[singular] 03/07: Imported Upstream version 4.0.1p2

Jerome Benoit calculus-guest at moszumanska.debian.org
Sun Feb 8 12:52:33 UTC 2015


This is an automated email from the git hooks/post-receive script.

calculus-guest pushed a commit to branch master
in repository singular.

commit 1e597ac9bb764d291d7eec9439e8152c93565b08
Author: Jerome Benoit <calculus at rezozer.net>
Date:   Sun Feb 8 12:35:05 2015 +0100

    Imported Upstream version 4.0.1p2
---
 .tarball-git-version                               |     1 +
 AUTHORS                                            |     0
 COPYING                                            |   117 +
 ChangeLog                                          |     0
 INSTALL                                            |    51 +
 IntegerProgramming/BigInt.cc                       |   373 +
 IntegerProgramming/BigInt.h                        |    83 +
 IntegerProgramming/Buchberger.cc                   |  3196 +++
 IntegerProgramming/IP_algorithms.cc                |  3991 +++
 IntegerProgramming/IP_algorithms.h                 |   296 +
 IntegerProgramming/LLL.cc                          |   590 +
 IntegerProgramming/LLL.h                           |    39 +
 IntegerProgramming/Makefile.am                     |    26 +
 IntegerProgramming/Makefile.in                     |   749 +
 IntegerProgramming/README                          |    11 +
 IntegerProgramming/binomial.cc                     |  1922 ++
 IntegerProgramming/binomial.h                      |   302 +
 IntegerProgramming/binomial__term_ordering.h       |    14 +
 IntegerProgramming/change_cost.cc                  |   212 +
 IntegerProgramming/change_cost.hlp                 |   141 +
 IntegerProgramming/gen_test.cc                     |    69 +
 IntegerProgramming/globals.h                       |   231 +
 IntegerProgramming/ideal.cc                        |  1092 +
 IntegerProgramming/ideal.h                         |   370 +
 IntegerProgramming/ideal_stuff.cc                  |   471 +
 IntegerProgramming/list.cc                         |  1166 +
 IntegerProgramming/list.h                          |   303 +
 IntegerProgramming/matrix.cc                       |   730 +
 IntegerProgramming/matrix.h                        |   169 +
 IntegerProgramming/solve_IP.cc                     |   299 +
 IntegerProgramming/solve_IP.hlp                    |   261 +
 IntegerProgramming/term_ordering.cc                |  1457 ++
 IntegerProgramming/term_ordering.h                 |   246 +
 IntegerProgramming/testdata.cc                     |   232 +
 IntegerProgramming/testdata.h                      |    53 +
 IntegerProgramming/toric_ideal.cc                  |   260 +
 IntegerProgramming/toric_ideal.hlp                 |   201 +
 Makefile.am                                        |    27 +
 Makefile.in                                        |  1067 +
 NEWS                                               |     0
 README                                             |    29 +
 README.md                                          |    29 +
 README.pkg                                         |    22 +
 Singular.pc.in                                     |    17 +
 Singular/COPYING                                   |    33 +
 Singular/ChangeLog                                 |     2 +
 Singular/LIB/JMBTest.lib                           |  1017 +
 Singular/LIB/JMSConst.lib                          |  1395 +
 Singular/LIB/absfact.lib                           |   959 +
 Singular/LIB/ainvar.lib                            |   726 +
 Singular/LIB/aksaka.lib                            |   419 +
 Singular/LIB/alexpoly.lib                          |  2496 ++
 Singular/LIB/algebra.lib                           |  1123 +
 Singular/LIB/algemodstd.lib                        |   484 +
 Singular/LIB/all.lib.tmpl                          |    12 +
 Singular/LIB/arcpoint.lib                          |   515 +
 Singular/LIB/assprimeszerodim.lib                  |   752 +
 Singular/LIB/atkins.lib                            |  1205 +
 Singular/LIB/bfun.lib                              |  1962 ++
 Singular/LIB/bimodules.lib                         |   774 +
 Singular/LIB/brnoeth.lib                           |  5022 ++++
 Singular/LIB/central.lib                           |  2169 ++
 Singular/LIB/cisimplicial.lib                      |  1836 ++
 Singular/LIB/classify.lib                          |  3039 +++
 Singular/LIB/classify_aeq.lib                      |  1639 ++
 Singular/LIB/classifyceq.lib                       |  2092 ++
 Singular/LIB/classifyci.lib                        |  1133 +
 Singular/LIB/compregb.lib                          |   276 +
 Singular/LIB/control.lib                           |  1638 ++
 Singular/LIB/crypto.lib                            |  2181 ++
 Singular/LIB/curvepar.lib                          |  1816 ++
 Singular/LIB/decodegb.lib                          |  2133 ++
 Singular/LIB/decomp.lib                            |  1655 ++
 Singular/LIB/deform.lib                            |   968 +
 Singular/LIB/derham.lib                            |  5979 +++++
 Singular/LIB/divisors.lib                          |   863 +
 Singular/LIB/dmod.lib                              |  6476 +++++
 Singular/LIB/dmodapp.lib                           |  3251 +++
 Singular/LIB/dmodloc.lib                           |  2650 ++
 Singular/LIB/dmodvar.lib                           |   816 +
 Singular/LIB/elim.lib                              |   993 +
 Singular/LIB/ellipticcovers.lib                    |   528 +
 Singular/LIB/equising.lib                          |  2147 ++
 Singular/LIB/ffsolve.lib                           |  1076 +
 Singular/LIB/findifs.lib                           |   778 +
 Singular/LIB/finitediff.lib                        |  1770 ++
 Singular/LIB/finvar.lib                            |  8485 ++++++
 Singular/LIB/fpadim.lib                            |  2186 ++
 Singular/LIB/freegb.lib                            |  3613 +++
 Singular/LIB/general.lib                           |  1274 +
 Singular/LIB/gitfan.lib                            |   577 +
 Singular/LIB/gkdim.lib                             |    99 +
 Singular/LIB/gmspoly.lib                           |   590 +
 Singular/LIB/gmssing.lib                           |  1741 ++
 Singular/LIB/graphics.lib                          |   360 +
 Singular/LIB/grobcov.lib                           |  4831 ++++
 Singular/LIB/groups.lib                            |  1123 +
 Singular/LIB/grwalk.lib                            |   545 +
 Singular/LIB/hdepth.lib                            |   195 +
 Singular/LIB/help.cnf                              |    57 +
 Singular/LIB/hnoether.lib                          |  4282 +++
 Singular/LIB/homolog.lib                           |  1948 ++
 Singular/LIB/hyperel.lib                           |   975 +
 Singular/LIB/inout.lib                             |   703 +
 Singular/LIB/integralbasis.lib                     |   570 +
 Singular/LIB/intprog.lib                           |   750 +
 Singular/LIB/involut.lib                           |   980 +
 Singular/LIB/jacobson.lib                          |  1215 +
 Singular/LIB/kskernel.lib                          |   534 +
 Singular/LIB/latex.lib                             |  3137 +++
 Singular/LIB/linalg.lib                            |  2044 ++
 Singular/LIB/locnormal.lib                         |   539 +
 Singular/LIB/makedbm.lib                           |   294 +
 Singular/LIB/matrix.lib                            |  1397 +
 Singular/LIB/modnormal.lib                         |   693 +
 Singular/LIB/modstd.lib                            |   778 +
 Singular/LIB/modular.lib                           |   347 +
 Singular/LIB/mondromy.lib                          |  1016 +
 Singular/LIB/monomialideal.lib                     |  3851 +++
 Singular/LIB/mprimdec.lib                          |  2352 ++
 Singular/LIB/mregular.lib                          |  1778 ++
 Singular/LIB/multigrading.lib                      |  5619 ++++
 Singular/LIB/ncalg.lib                             | 16288 ++++++++++++
 Singular/LIB/ncall.lib                             |    31 +
 Singular/LIB/ncdecomp.lib                          |   464 +
 Singular/LIB/ncfactor.lib                          |  9071 +++++++
 Singular/LIB/nchomolog.lib                         |   760 +
 Singular/LIB/ncpreim.lib                           |   796 +
 Singular/LIB/nctools.lib                           |  1905 ++
 Singular/LIB/noether.lib                           |   995 +
 Singular/LIB/normal.lib                            |  7428 ++++++
 Singular/LIB/normaliz.lib                          |  1684 ++
 Singular/LIB/ntsolve.lib                           |   364 +
 Singular/LIB/numerAlg.lib                          |   559 +
 Singular/LIB/numerDecom.lib                        |  2223 ++
 Singular/LIB/orbitparam.lib                        |   351 +
 Singular/LIB/parallel.lib                          |   305 +
 Singular/LIB/paraplanecurves.lib                   |  3070 +++
 Singular/LIB/perron.lib                            |   202 +
 Singular/LIB/phindex.lib                           |   642 +
 Singular/LIB/pointid.lib                           |   673 +
 Singular/LIB/poly.lib                              |  1165 +
 Singular/LIB/polybori.lib                          |  1432 ++
 Singular/LIB/polymake.lib                          |  2483 ++
 Singular/LIB/presolve.lib                          |  1538 ++
 Singular/LIB/primdec.lib                           |  9004 +++++++
 Singular/LIB/primdecint.lib                        |  1764 ++
 Singular/LIB/primitiv.lib                          |   402 +
 Singular/LIB/purityfiltration.lib                  |   961 +
 Singular/LIB/qhmoduli.lib                          |  1531 ++
 Singular/LIB/qmatrix.lib                           |   293 +
 Singular/LIB/random.lib                            |   455 +
 Singular/LIB/ratgb.lib                             |   493 +
 Singular/LIB/realclassify.lib                      |   817 +
 Singular/LIB/realizationMatroids.lib               |   772 +
 Singular/LIB/realrad.lib                           |  1211 +
 Singular/LIB/reesclos.lib                          |   465 +
 Singular/LIB/resbinomial.lib                       |  2802 ++
 Singular/LIB/resgraph.lib                          |   791 +
 Singular/LIB/resjung.lib                           |   820 +
 Singular/LIB/resolve.lib                           |  5070 ++++
 Singular/LIB/resources.lib                         |   161 +
 Singular/LIB/reszeta.lib                           |  5479 ++++
 Singular/LIB/ring.lib                              |  1127 +
 Singular/LIB/ringgb.lib                            |   343 +
 Singular/LIB/rinvar.lib                            |  1116 +
 Singular/LIB/rootsmr.lib                           |   709 +
 Singular/LIB/rootsur.lib                           |   958 +
 Singular/LIB/sagbi.lib                             |  1254 +
 Singular/LIB/schreyer.lib                          |  3597 +++
 Singular/LIB/schubert.lib                          |  2561 ++
 Singular/LIB/sheafcoh.lib                          |  1423 +
 Singular/LIB/signcond.lib                          |   437 +
 Singular/LIB/sing.lib                              |  1095 +
 Singular/LIB/sing4ti2.lib                          |   383 +
 Singular/LIB/solve.lib                             |  2237 ++
 Singular/LIB/spcurve.lib                           |  1065 +
 Singular/LIB/spectrum.lib                          |    62 +
 Singular/LIB/standard.lib                          |  2510 ++
 Singular/LIB/stratify.lib                          |  1070 +
 Singular/LIB/surf.lib                              |   382 +
 Singular/LIB/surfacesignature.lib                  |   522 +
 Singular/LIB/surfex.lib                            |  1464 ++
 Singular/LIB/symodstd.lib                          |  1580 ++
 Singular/LIB/tasks.lib                             |  1320 +
 Singular/LIB/teachstd.lib                          |   858 +
 Singular/LIB/template.lib                          |   116 +
 Singular/LIB/toric.lib                             |  1098 +
 Singular/LIB/triang.lib                            |  1195 +
 Singular/LIB/tropical.lib                          |  8545 ++++++
 Singular/LIB/tst.lib                               |  1109 +
 Singular/LIB/weierstr.lib                          |   241 +
 Singular/LIB/zeroset.lib                           |  1484 ++
 Singular/Makefile.am                               |   276 +
 Singular/Makefile.in                               |  2402 ++
 Singular/README                                    |    22 +
 Singular/all.lib                                   |   121 +
 Singular/attrib.cc                                 |   474 +
 Singular/attrib.h                                  |    50 +
 Singular/blackbox.cc                               |   206 +
 Singular/blackbox.h                                |    84 +
 Singular/calcSVD.cc                                |   118 +
 Singular/claptmpl.cc                               |   137 +
 Singular/cntrlc.cc                                 |   597 +
 Singular/cntrlc.h                                  |    26 +
 Singular/countedref.cc                             |   749 +
 Singular/countedref.h                              |   466 +
 Singular/denom_list.cc                             |    30 +
 Singular/distrib.h                                 |     1 +
 Singular/dyn_modules/Makefile.am                   |     5 +
 Singular/dyn_modules/Makefile.in                   |   676 +
 Singular/dyn_modules/Order/Makefile.am             |    37 +
 Singular/dyn_modules/Order/Makefile.in             |   823 +
 Singular/dyn_modules/Order/nforder.cpp             |   687 +
 Singular/dyn_modules/Order/nforder.h               |   137 +
 Singular/dyn_modules/Order/nforder_elt.cc          |   269 +
 Singular/dyn_modules/Order/nforder_elt.h           |    10 +
 Singular/dyn_modules/Order/nforder_ideal.cc        |   322 +
 Singular/dyn_modules/Order/nforder_ideal.h         |    71 +
 Singular/dyn_modules/Order/singular.cc             |   514 +
 Singular/dyn_modules/bigintm/Makefile.am           |    34 +
 Singular/dyn_modules/bigintm/Makefile.in           |   778 +
 Singular/dyn_modules/bigintm/bigintm.cc            |   317 +
 Singular/dyn_modules/bigintm/bigintm.h             |     6 +
 Singular/dyn_modules/bigintm/mod_main.cc           |    50 +
 Singular/dyn_modules/gfanlib/Makefile.am           |    44 +
 Singular/dyn_modules/gfanlib/Makefile.in           |   812 +
 Singular/dyn_modules/gfanlib/bbcone.cc             |  1969 ++
 Singular/dyn_modules/gfanlib/bbcone.h              |    42 +
 Singular/dyn_modules/gfanlib/bbfan.cc              |  1067 +
 Singular/dyn_modules/gfanlib/bbfan.h               |    24 +
 Singular/dyn_modules/gfanlib/bbpolytope.cc         |   493 +
 Singular/dyn_modules/gfanlib/bbpolytope.h          |    22 +
 Singular/dyn_modules/gfanlib/gfan.h                |   284 +
 Singular/dyn_modules/gfanlib/gfanlib.cc            |    28 +
 Singular/dyn_modules/gfanlib/gitfan.cc             |   377 +
 Singular/dyn_modules/gfanlib/gitfan.h              |    59 +
 Singular/dyn_modules/polymake/Makefile.am          |    38 +
 Singular/dyn_modules/polymake/Makefile.in          |   777 +
 .../dyn_modules/polymake/polymake_conversion.cc    |   525 +
 .../dyn_modules/polymake/polymake_documentation.cc |   227 +
 Singular/dyn_modules/polymake/polymake_wrapper.cc  |  1815 ++
 Singular/dyn_modules/pyobject/Makefile.am          |    27 +
 Singular/dyn_modules/pyobject/Makefile.in          |   745 +
 Singular/dyn_modules/pyobject/pyobject.cc          |   736 +
 Singular/dyn_modules/singmathic/Makefile.am        |    33 +
 Singular/dyn_modules/singmathic/Makefile.in        |   753 +
 Singular/dyn_modules/singmathic/singmathic.cc      |   564 +
 Singular/dyn_modules/staticdemo/Makefile.am        |    19 +
 Singular/dyn_modules/staticdemo/Makefile.in        |   671 +
 Singular/dyn_modules/staticdemo/staticdemo.cc      |    15 +
 Singular/dyn_modules/syzextra/DebugPrint.cc        |   106 +
 Singular/dyn_modules/syzextra/DebugPrint.h         |    41 +
 Singular/dyn_modules/syzextra/Makefile.am          |    36 +
 Singular/dyn_modules/syzextra/Makefile.in          |  1139 +
 Singular/dyn_modules/syzextra/mod_main.cc          |  2038 ++
 Singular/dyn_modules/syzextra/myNF.cc              |   339 +
 Singular/dyn_modules/syzextra/myNF.h               |    47 +
 Singular/dyn_modules/syzextra/singularxx_defs.h    |    74 +
 Singular/dyn_modules/syzextra/syzextra.cc          |  3099 +++
 Singular/dyn_modules/syzextra/syzextra.h           |   638 +
 Singular/dyn_modules/syzextra/test.sh              |     6 +
 Singular/dyn_modules/syzextra/test_release.sh      |     4 +
 Singular/eigenval_ip.cc                            |   285 +
 Singular/eigenval_ip.h                             |    21 +
 Singular/emacs.cc                                  |   341 +
 Singular/extra.cc                                  |  3721 +++
 Singular/feOpt.cc                                  |   397 +
 Singular/feOpt.h                                   |    82 +
 Singular/feOptES.inc                               |    34 +
 Singular/feOptGen.cc                               |    86 +
 Singular/feOptGen.h                                |    17 +
 Singular/feOptTS.inc                               |    33 +
 Singular/feOptTab.h                                |   159 +
 Singular/febase.cc                                 |    92 +
 Singular/fegetopt.c                                |   753 +
 Singular/fegetopt.h                                |   128 +
 Singular/fehelp.cc                                 |  1149 +
 Singular/fehelp.h                                  |    24 +
 Singular/fevoices.cc                               |   658 +
 Singular/fevoices.h                                |   105 +
 Singular/fglm.cc                                   |   499 +
 Singular/fglm.h                                    |    36 +
 Singular/gentable.cc                               |   948 +
 Singular/gms.cc                                    |   141 +
 Singular/gms.h                                     |    22 +
 Singular/grammar.cc                                |  4528 ++++
 Singular/grammar.h                                 |   184 +
 Singular/idrec.h                                   |    57 +
 Singular/iparith.cc                                |  9094 +++++++
 Singular/ipassign.cc                               |  2090 ++
 Singular/ipconv.cc                                 |   447 +
 Singular/ipconv.h                                  |    16 +
 Singular/ipid.cc                                   |   740 +
 Singular/ipid.h                                    |   151 +
 Singular/iplib.cc                                  |  1360 +
 Singular/ipprint.cc                                |   473 +
 Singular/ipprint.h                                 |    18 +
 Singular/ipshell.cc                                |  6087 +++++
 Singular/ipshell.h                                 |   297 +
 Singular/libparse.cc                               |  3535 +++
 Singular/libparse.h                                |   111 +
 Singular/libsingular.h                             |    35 +
 Singular/linearAlgebra_ip.cc                       |   105 +
 Singular/linearAlgebra_ip.h                        |    38 +
 Singular/links/asciiLink.cc                        |   503 +
 Singular/links/dbm_sl.h                            |    15 +
 Singular/links/ndbm.cc                             |   551 +
 Singular/links/ndbm.h                              |   103 +
 Singular/links/pipeLink.cc                         |   208 +
 Singular/links/pipeLink.h                          |    12 +
 Singular/links/semaphore.c                         |   139 +
 Singular/links/silink.cc                           |   450 +
 Singular/links/silink.h                            |   131 +
 Singular/links/simpleipc.h                         |    28 +
 Singular/links/sing_dbm.cc                         |   456 +
 Singular/links/sing_dbm.h                          |    14 +
 Singular/links/slInit.h                            |    20 +
 Singular/links/slInit_Dynamic.cc                   |    57 +
 Singular/links/slInit_Static.cc                    |    39 +
 Singular/links/ssiLink.cc                          |  2067 ++
 Singular/links/ssiLink.h                           |    23 +
 Singular/lists.cc                                  |   422 +
 Singular/lists.h                                   |    73 +
 Singular/locals.h                                  |    29 +
 Singular/make_alllib.sh                            |    16 +
 Singular/maps_ip.cc                                |   459 +
 Singular/maps_ip.h                                 |    33 +
 Singular/misc_ip.cc                                |  1317 +
 Singular/misc_ip.h                                 |    74 +
 Singular/mkinstalldirs                             |    32 +
 Singular/mmalloc.cc                                |    87 +
 Singular/mmalloc.h                                 |    24 +
 Singular/mmstd.c                                   |    56 +
 Singular/mod_lib.cc                                |   121 +
 Singular/mod_lib.h                                 |    35 +
 Singular/newstruct.cc                              |   877 +
 Singular/newstruct.h                               |    13 +
 Singular/number2.cc                                |   336 +
 Singular/number2.h                                 |    48 +
 Singular/omSingularConfig.h                        |    61 +
 Singular/pcv.cc                                    |   444 +
 Singular/pcv.h                                     |    37 +
 Singular/pyobject_setup.cc                         |    56 +
 Singular/pyobject_setup.h                          |    25 +
 Singular/run.h                                     |   100 +
 Singular/scanner.cc                                |  2331 ++
 Singular/sdb.cc                                    |   325 +
 Singular/sdb.h                                     |    25 +
 Singular/singular-libs                             |    63 +
 Singular/singularsurf                              |    11 +
 Singular/stype.h                                   |    24 +
 Singular/subexpr.cc                                |  1922 ++
 Singular/subexpr.h                                 |   180 +
 Singular/table.h                                   |  1264 +
 Singular/test.cc                                   |   385 +
 Singular/tesths.cc                                 |   234 +
 Singular/tok.h                                     |   172 +
 Singular/utils.cc                                  |   250 +
 Singular/utils.h                                   |    11 +
 Singular/walk.cc                                   |  8723 +++++++
 Singular/walk.h                                    |    85 +
 Singular/walk_ip.cc                                |   314 +
 Singular/wrapper.cc                                |   135 +
 _config.h.in                                       |   389 +
 aclocal.m4                                         |  1195 +
 autogen.sh                                         |     9 +
 build-aux/ar-lib                                   |   270 +
 build-aux/compile                                  |   347 +
 build-aux/config.guess                             |  1431 ++
 build-aux/config.sub                               |  1811 ++
 build-aux/depcomp                                  |   791 +
 build-aux/install-sh                               |   527 +
 build-aux/ltmain.sh                                |  9655 +++++++
 build-aux/missing                                  |   215 +
 build-aux/test-driver                              |   127 +
 build-aux/ylwrap                                   |   249 +
 configure                                          | 25721 +++++++++++++++++++
 configure.ac                                       |   269 +
 desktop/Makefile.am                                |    10 +
 desktop/Makefile.in                                |   583 +
 desktop/Singular-manual.desktop.in                 |    15 +
 desktop/Singular.desktop.in                        |    15 +
 desktop/Singular.png                               |   Bin 0 -> 4971 bytes
 doc/ESingular.man                                  |    43 +
 doc/Singular.man                                   |   101 +
 doc/TSingular.man                                  |    37 +
 dox/Doxyfile.in                                    |  2418 ++
 dox/DoxygenLayout.xml                              |   194 +
 dox/Makefile.am                                    |    41 +
 dox/Makefile.in                                    |   526 +
 dox/footer.html                                    |    19 +
 dox/header.html                                    |    55 +
 dox/logo.png                                       |   Bin 0 -> 10965 bytes
 dox/stylesheet.css                                 |  1442 ++
 doxy                                               |    92 +
 emacs/.emacs-general                               |   184 +
 emacs/.emacs-singular                              |   234 +
 emacs/COPYING                                      |    44 +
 emacs/ChangeLog                                    |  1001 +
 emacs/Makefile.am                                  |    24 +
 emacs/Makefile.in                                  |   570 +
 emacs/NEWS                                         |    34 +
 emacs/cmd-cmpl.el                                  |   241 +
 emacs/ex-cmpl.el                                   |  1681 ++
 emacs/hlp-cmpl.el                                  |  2869 +++
 emacs/lib-cmpl.el                                  |   180 +
 emacs/singular.el                                  |  4273 +++
 emacs/singular.xpm                                 |    39 +
 factory/AUTHORS                                    |     0
 factory/COPYING                                    |    51 +
 factory/ChangeLog                                  |  1829 ++
 factory/DegreePattern.cc                           |   148 +
 factory/DegreePattern.h                            |   180 +
 factory/ExtensionInfo.cc                           |    90 +
 factory/ExtensionInfo.h                            |   161 +
 factory/FLINTconvert.cc                            |   541 +
 factory/FLINTconvert.h                             |   253 +
 factory/Makefile.am                                |   293 +
 factory/Makefile.in                                |  1938 ++
 factory/NEWS                                       |   137 +
 factory/NTLconvert.cc                              |  1219 +
 factory/NTLconvert.h                               |    95 +
 factory/README                                     |   241 +
 factory/_config.h.in                               |   182 +
 factory/acinclude.m4                               |   321 +
 factory/aclocal.m4                                 |  1151 +
 factory/aminclude.am                               |   186 +
 factory/bin/fold-docu.el                           |    21 +
 factory/bin/folding.el                             |  1806 ++
 factory/bin/gen-readcf                             |    14 +
 factory/bin/makeheader                             |   145 +
 factory/canonicalform.cc                           |  1917 ++
 factory/canonicalform.h                            |   393 +
 factory/cfCharSets.cc                              |   694 +
 factory/cfCharSets.h                               |   103 +
 factory/cfCharSetsUtil.cc                          |   964 +
 factory/cfCharSetsUtil.h                           |   120 +
 factory/cfEzgcd.cc                                 |  1396 +
 factory/cfEzgcd.h                                  |    13 +
 factory/cfGcdAlgExt.cc                             |  1077 +
 factory/cfGcdAlgExt.h                              |    43 +
 factory/cfGcdUtil.cc                               |   281 +
 factory/cfGcdUtil.h                                |    17 +
 factory/cfModGcd.cc                                |  4202 +++
 factory/cfModGcd.h                                 |   133 +
 factory/cfModResultant.cc                          |   685 +
 factory/cfModResultant.h                           |    42 +
 factory/cfNTLzzpEXGCD.cc                           |   344 +
 factory/cfNTLzzpEXGCD.h                            |   115 +
 factory/cfNewtonPolygon.cc                         |  1375 +
 factory/cfNewtonPolygon.h                          |   136 +
 factory/cfSubResGcd.cc                             |   225 +
 factory/cfSubResGcd.h                              |    19 +
 factory/cfUnivarGcd.cc                             |   332 +
 factory/cfUnivarGcd.h                              |    38 +
 factory/cf_algorithm.cc                            |   574 +
 factory/cf_algorithm.h                             |   126 +
 factory/cf_assert.h                                |   139 +
 factory/cf_char.cc                                 |    66 +
 factory/cf_chinese.cc                              |   249 +
 factory/cf_cyclo.cc                                |   148 +
 factory/cf_cyclo.h                                 |    41 +
 factory/cf_defs.h                                  |    46 +
 factory/cf_eval.cc                                 |    82 +
 factory/cf_eval.h                                  |    56 +
 factory/cf_factor.cc                               |   781 +
 factory/cf_factory.cc                              |   260 +
 factory/cf_factory.h                               |    44 +
 factory/cf_gcd.cc                                  |   350 +
 factory/cf_generator.cc                            |   229 +
 factory/cf_generator.h                             |   125 +
 factory/cf_globals.cc                              |    39 +
 factory/cf_globals.h                               |    24 +
 factory/cf_hnf.cc                                  |    61 +
 factory/cf_hnf.h                                   |    52 +
 factory/cf_inline.cc                               |   570 +
 factory/cf_irred.cc                                |    56 +
 factory/cf_irred.h                                 |    27 +
 factory/cf_iter.cc                                 |   116 +
 factory/cf_iter.h                                  |    74 +
 factory/cf_iter_inline.cc                          |   153 +
 factory/cf_linsys.cc                               |   609 +
 factory/cf_map.cc                                  |   411 +
 factory/cf_map.h                                   |   110 +
 factory/cf_map_ext.cc                              |   469 +
 factory/cf_map_ext.h                               |   116 +
 factory/cf_ops.cc                                  |   695 +
 factory/cf_primes.cc                               |    48 +
 factory/cf_primes.h                                |    30 +
 factory/cf_primetab.h                              |  5342 ++++
 factory/cf_random.cc                               |   179 +
 factory/cf_random.h                                |   100 +
 factory/cf_resultant.cc                            |   240 +
 factory/cf_reval.cc                                |    71 +
 factory/cf_reval.h                                 |    41 +
 factory/cf_switches.cc                             |    39 +
 factory/cf_switches.h                              |    77 +
 factory/cf_util.cc                                 |    77 +
 factory/cf_util.h                                  |    18 +
 factory/configure                                  | 24421 ++++++++++++++++++
 factory/configure.ac                               |   403 +
 factory/cplusplus.cc                               |    37 +
 factory/debug.cc                                   |    34 +
 factory/debug.h                                    |    50 +
 factory/doxygen.cfg                                |  2305 ++
 factory/examples/application.cc                    |    55 +
 factory/examples/factorize.cc                      |    36 +
 factory/examples/gcd.cc                            |    45 +
 factory/facAbsBiFact.cc                            |   785 +
 factory/facAbsBiFact.h                             |    60 +
 factory/facAbsFact.cc                              |   946 +
 factory/facAbsFact.h                               |    50 +
 factory/facAlgExt.cc                               |   404 +
 factory/facAlgExt.h                                |    41 +
 factory/facAlgFunc.cc                              |  1076 +
 factory/facAlgFunc.h                               |    51 +
 factory/facAlgFuncUtil.cc                          |   722 +
 factory/facAlgFuncUtil.h                           |    76 +
 factory/facBivar.cc                                |   608 +
 factory/facBivar.h                                 |   306 +
 factory/facFactorize.cc                            |   832 +
 factory/facFactorize.h                             |   176 +
 factory/facFqBivar.cc                              |  9000 +++++++
 factory/facFqBivar.h                               |   767 +
 factory/facFqBivarUtil.cc                          |  1313 +
 factory/facFqBivarUtil.h                           |   345 +
 factory/facFqFactorize.cc                          |  3832 +++
 factory/facFqFactorize.h                           |   798 +
 factory/facFqFactorizeUtil.cc                      |   310 +
 factory/facFqFactorizeUtil.h                       |   194 +
 factory/facFqSquarefree.cc                         |   357 +
 factory/facFqSquarefree.h                          |   150 +
 factory/facHensel.cc                               |  2844 ++
 factory/facHensel.h                                |   245 +
 factory/facIrredTest.cc                            |   113 +
 factory/facIrredTest.h                             |    47 +
 factory/facMul.cc                                  |  3729 +++
 factory/facMul.h                                   |   181 +
 factory/facSparseHensel.cc                         |   405 +
 factory/facSparseHensel.h                          |   621 +
 factory/fac_sqrfree.cc                             |   151 +
 factory/fac_sqrfree.h                              |    24 +
 factory/fac_util.cc                                |   112 +
 factory/fac_util.h                                 |    51 +
 factory/factory.pc.in                              |    17 +
 factory/factory.template                           |   124 +
 factory/factoryconf.template                       |    27 +
 factory/ffops.cc                                   |   107 +
 factory/ffops.h                                    |   168 +
 factory/ftmpl_inst.cc                              |   164 +
 factory/gengftables-conway.cc                      |   373 +
 factory/gf_tabutil.cc                              |    56 +
 factory/gf_tabutil.h                               |    24 +
 factory/gfops.cc                                   |   290 +
 factory/gfops.h                                    |   256 +
 factory/gftables/10201                             |   342 +
 factory/gftables/1024                              |    37 +
 factory/gftables/10609                             |   356 +
 factory/gftables/11449                             |   384 +
 factory/gftables/11881                             |   398 +
 factory/gftables/121                               |     6 +
 factory/gftables/12167                             |   408 +
 factory/gftables/125                               |     7 +
 factory/gftables/12769                             |   428 +
 factory/gftables/128                               |     7 +
 factory/gftables/1331                              |    47 +
 factory/gftables/1369                              |    48 +
 factory/gftables/14641                             |   490 +
 factory/gftables/15625                             |   523 +
 factory/gftables/16                                |     3 +
 factory/gftables/16129                             |   540 +
 factory/gftables/16384                             |   549 +
 factory/gftables/16807                             |   563 +
 factory/gftables/1681                              |    58 +
 factory/gftables/169                               |     8 +
 factory/gftables/17161                             |   574 +
 factory/gftables/1849                              |    64 +
 factory/gftables/18769                             |   628 +
 factory/gftables/19321                             |   646 +
 factory/gftables/19683                             |   659 +
 factory/gftables/2048                              |    71 +
 factory/gftables/2187                              |    75 +
 factory/gftables/2197                              |    76 +
 factory/gftables/2209                              |    76 +
 factory/gftables/22201                             |   742 +
 factory/gftables/22801                             |   762 +
 factory/gftables/2401                              |    82 +
 factory/gftables/243                               |    11 +
 factory/gftables/24389                             |   815 +
 factory/gftables/24649                             |   824 +
 factory/gftables/25                                |     3 +
 factory/gftables/256                               |    11 +
 factory/gftables/26569                             |   888 +
 factory/gftables/27                                |     3 +
 factory/gftables/27889                             |   932 +
 factory/gftables/2809                              |    96 +
 factory/gftables/28561                             |   954 +
 factory/gftables/289                               |    12 +
 factory/gftables/29791                             |   995 +
 factory/gftables/29929                             |  1000 +
 factory/gftables/3125                              |   107 +
 factory/gftables/32                                |     4 +
 factory/gftables/32041                             |  1070 +
 factory/gftables/32761                             |  1094 +
 factory/gftables/32768                             |  1095 +
 factory/gftables/343                               |    14 +
 factory/gftables/3481                              |   118 +
 factory/gftables/361                               |    14 +
 factory/gftables/36481                             |  1218 +
 factory/gftables/3721                              |   126 +
 factory/gftables/37249                             |  1244 +
 factory/gftables/38809                             |  1296 +
 factory/gftables/39601                             |  1322 +
 factory/gftables/4                                 |     3 +
 factory/gftables/4096                              |   139 +
 factory/gftables/44521                             |  1486 ++
 factory/gftables/4489                              |   152 +
 factory/gftables/49                                |     4 +
 factory/gftables/4913                              |   166 +
 factory/gftables/49729                             |  1660 ++
 factory/gftables/5041                              |   170 +
 factory/gftables/50653                             |  1691 ++
 factory/gftables/512                               |    20 +
 factory/gftables/51529                             |  1720 ++
 factory/gftables/52441                             |  1750 ++
 factory/gftables/529                               |    20 +
 factory/gftables/5329                              |   180 +
 factory/gftables/54289                             |  1812 ++
 factory/gftables/57121                             |  1906 ++
 factory/gftables/58081                             |  1938 ++
 factory/gftables/59049                             |  1971 ++
 factory/gftables/6241                              |   210 +
 factory/gftables/625                               |    23 +
 factory/gftables/63001                             |  2102 ++
 factory/gftables/64                                |     5 +
 factory/gftables/6561                              |   221 +
 factory/gftables/6859                              |   231 +
 factory/gftables/6889                              |   232 +
 factory/gftables/729                               |    27 +
 factory/gftables/7921                              |   266 +
 factory/gftables/8                                 |     3 +
 factory/gftables/81                                |     5 +
 factory/gftables/8192                              |   276 +
 factory/gftables/841                               |    30 +
 factory/gftables/9                                 |     3 +
 factory/gftables/9409                              |   316 +
 factory/gftables/961                               |    34 +
 factory/gmpext.h                                   |    26 +
 factory/imm.cc                                     |    17 +
 factory/imm.h                                      |   489 +
 factory/include/factory/Makefile.am                |    12 +
 factory/include/factory/Makefile.in                |   623 +
 factory/include/factory/cf_gmp.h                   |    28 +
 factory/include/factory/templates/ftmpl_afactor.h  |    48 +
 factory/include/factory/templates/ftmpl_array.h    |    46 +
 factory/include/factory/templates/ftmpl_factor.h   |    51 +
 factory/include/factory/templates/ftmpl_list.h     |   145 +
 factory/include/factory/templates/ftmpl_matrix.h   |    95 +
 factory/int_cf.cc                                  |   225 +
 factory/int_cf.h                                   |   126 +
 factory/int_int.cc                                 |   580 +
 factory/int_int.h                                  |   240 +
 factory/int_intdiv.cc                              |   378 +
 factory/int_poly.cc                                |  2253 ++
 factory/int_poly.h                                 |   173 +
 factory/int_rat.cc                                 |   912 +
 factory/int_rat.h                                  |   130 +
 factory/make_factory_dist                          |     9 +
 factory/parseutil.cc                               |   160 +
 factory/parseutil.h                                |    34 +
 factory/readcf.cc                                  |  1801 ++
 factory/readcf.yy                                  |   219 +
 factory/singext.cc                                 |    81 +
 factory/singext.h                                  |    37 +
 factory/templates/ftmpl_afactor.cc                 |    39 +
 factory/templates/ftmpl_array.cc                   |   156 +
 factory/templates/ftmpl_factor.cc                  |    45 +
 factory/templates/ftmpl_functions.h                |    79 +
 factory/templates/ftmpl_list.cc                    |   726 +
 factory/templates/ftmpl_matrix.cc                  |   319 +
 factory/test.cc                                    |   132 +
 factory/test_install.cc                            |    20 +
 factory/timing.h                                   |    94 +
 factory/variable.cc                                |   314 +
 factory/variable.h                                 |   117 +
 gfanlib/Makefile.am                                |    19 +
 gfanlib/Makefile.in                                |   891 +
 gfanlib/_config.h.in                               |    95 +
 gfanlib/aclocal.m4                                 |  1148 +
 gfanlib/configure                                  | 20821 +++++++++++++++
 gfanlib/configure.ac                               |    53 +
 gfanlib/gfanlib.h                                  |    19 +
 gfanlib/gfanlib_matrix.h                           |   646 +
 gfanlib/gfanlib_polyhedralfan.cpp                  |   895 +
 gfanlib/gfanlib_polyhedralfan.h                    |   117 +
 gfanlib/gfanlib_polymakefile.cpp                   |   474 +
 gfanlib/gfanlib_polymakefile.h                     |    66 +
 gfanlib/gfanlib_q.h                                |   180 +
 gfanlib/gfanlib_symmetriccomplex.cpp               |   697 +
 gfanlib/gfanlib_symmetriccomplex.h                 |   122 +
 gfanlib/gfanlib_symmetry.cpp                       |   511 +
 gfanlib/gfanlib_symmetry.h                         |   154 +
 gfanlib/gfanlib_vector.h                           |   400 +
 gfanlib/gfanlib_z.h                                |   403 +
 gfanlib/gfanlib_zcone.cpp                          |  1276 +
 gfanlib/gfanlib_zcone.h                            |   362 +
 gfanlib/gfanlib_zfan.cpp                           |   401 +
 gfanlib/gfanlib_zfan.h                             |   172 +
 git-version-gen                                    |    24 +
 kernel/COPYING                                     |    30 +
 kernel/ChangeLog                                   |   856 +
 kernel/GBEngine/Makefile.am                        |    23 +
 kernel/GBEngine/Makefile.in                        |  1113 +
 kernel/GBEngine/f5c.cc                             |    32 +
 kernel/GBEngine/f5c.h                              |    20 +
 kernel/GBEngine/f5data.cc                          |    34 +
 kernel/GBEngine/f5data.h                           |   260 +
 kernel/GBEngine/f5gb.cc                            |  2146 ++
 kernel/GBEngine/f5gb.h                             |   177 +
 kernel/GBEngine/f5lists.cc                         |  1240 +
 kernel/GBEngine/f5lists.h                          |   378 +
 kernel/GBEngine/gr_kstd2.cc                        |  1325 +
 kernel/GBEngine/janet.cc                           |  1100 +
 kernel/GBEngine/janet.h                            |   101 +
 kernel/GBEngine/kInline.h                          |  1164 +
 kernel/GBEngine/khstd.cc                           |   208 +
 kernel/GBEngine/khstd.h                            |    18 +
 kernel/GBEngine/kpolys.cc                          |   129 +
 kernel/GBEngine/kspoly.cc                          |   853 +
 kernel/GBEngine/kstd1.cc                           |  3160 +++
 kernel/GBEngine/kstd1.h                            |    94 +
 kernel/GBEngine/kstd2.cc                           |  3415 +++
 kernel/GBEngine/kstdfac.cc                         |  1033 +
 kernel/GBEngine/kstdfac.h                          |    14 +
 kernel/GBEngine/kutil.cc                           |  9795 +++++++
 kernel/GBEngine/kutil.h                            |   799 +
 kernel/GBEngine/nc.cc                              |   419 +
 kernel/GBEngine/nc.h                               |    74 +
 kernel/GBEngine/ratgring.cc                        |   663 +
 kernel/GBEngine/ratgring.h                         |   117 +
 kernel/GBEngine/ringgb.cc                          |   304 +
 kernel/GBEngine/ringgb.h                           |    22 +
 kernel/GBEngine/sca.cc                             |  1237 +
 kernel/GBEngine/shiftgb.cc                         |   604 +
 kernel/GBEngine/shiftgb.h                          |    45 +
 kernel/GBEngine/syz.cc                             |  1186 +
 kernel/GBEngine/syz.h                              |   138 +
 kernel/GBEngine/syz0.cc                            |  1068 +
 kernel/GBEngine/syz1.cc                            |  2688 ++
 kernel/GBEngine/syz2.cc                            |  1095 +
 kernel/GBEngine/syz3.cc                            |  2046 ++
 kernel/GBEngine/test.cc                            |   508 +
 kernel/GBEngine/tgb.cc                             |  5198 ++++
 kernel/GBEngine/tgb.h                              |    21 +
 kernel/GBEngine/tgb_internal.h                     |  1960 ++
 kernel/GBEngine/tgbgauss.cc                        |   945 +
 kernel/GBEngine/tgbgauss.h                         |   102 +
 kernel/GBEngine/units.cc                           |    78 +
 kernel/GBEngine/units.h                            |    14 +
 kernel/Makefile.am                                 |    64 +
 kernel/Makefile.in                                 |  1278 +
 kernel/README                                      |    16 +
 kernel/combinatorics/Makefile.am                   |    22 +
 kernel/combinatorics/Makefile.in                   |  1085 +
 kernel/combinatorics/hdegree.cc                    |  1482 ++
 kernel/combinatorics/hilb.cc                       |  1405 +
 kernel/combinatorics/hilb.h                        |    27 +
 kernel/combinatorics/hutil.cc                      |  1068 +
 kernel/combinatorics/hutil.h                       |    90 +
 kernel/combinatorics/stairc.h                      |    37 +
 kernel/combinatorics/test.cc                       |   378 +
 kernel/digitech.cc                                 |    87 +
 kernel/digitech.h                                  |     7 +
 kernel/fast_mult.cc                                |   670 +
 kernel/fast_mult.h                                 |    10 +
 kernel/fglm/Makefile.am                            |    22 +
 kernel/fglm/Makefile.in                            |  1086 +
 kernel/fglm/fglm.h                                 |    85 +
 kernel/fglm/fglmcomb.cc                            |   557 +
 kernel/fglm/fglmgauss.cc                           |   212 +
 kernel/fglm/fglmgauss.h                            |    47 +
 kernel/fglm/fglmhom.cc                             |   454 +
 kernel/fglm/fglmvec.cc                             |   538 +
 kernel/fglm/fglmvec.h                              |    64 +
 kernel/fglm/fglmzero.cc                            |  1252 +
 kernel/fglm/test.cc                                |   376 +
 kernel/groebner_walk/Makefile.am                   |    22 +
 kernel/groebner_walk/Makefile.in                   |  1086 +
 kernel/groebner_walk/test.cc                       |   376 +
 kernel/groebner_walk/walkMain.cc                   |   662 +
 kernel/groebner_walk/walkMain.h                    |    61 +
 kernel/groebner_walk/walkProc.cc                   |   361 +
 kernel/groebner_walk/walkProc.h                    |     9 +
 kernel/groebner_walk/walkSupport.cc                |  1200 +
 kernel/groebner_walk/walkSupport.h                 |    51 +
 kernel/ideals.cc                                   |  2678 ++
 kernel/ideals.h                                    |   212 +
 kernel/linear_algebra/Cache.h                      |   329 +
 kernel/linear_algebra/CacheImplementation.h        |   436 +
 kernel/linear_algebra/Makefile.am                  |    28 +
 kernel/linear_algebra/Makefile.in                  |  1098 +
 kernel/linear_algebra/Minor.cc                     |  1170 +
 kernel/linear_algebra/Minor.h                      |   869 +
 kernel/linear_algebra/MinorInterface.cc            |   559 +
 kernel/linear_algebra/MinorInterface.h             |   110 +
 kernel/linear_algebra/MinorProcessor.cc            |  1549 ++
 kernel/linear_algebra/MinorProcessor.h             |   772 +
 kernel/linear_algebra/eigenval.cc                  |   125 +
 kernel/linear_algebra/eigenval.h                   |    18 +
 kernel/linear_algebra/interpolation.cc             |  1772 ++
 kernel/linear_algebra/interpolation.h              |    20 +
 kernel/linear_algebra/linearAlgebra.cc             |  1597 ++
 kernel/linear_algebra/linearAlgebra.h              |   582 +
 kernel/linear_algebra/minpoly.cc                   |   777 +
 kernel/linear_algebra/minpoly.h                    |   214 +
 kernel/linear_algebra/test.cc                      |   376 +
 kernel/maps/Makefile.am                            |    22 +
 kernel/maps/Makefile.in                            |  1081 +
 kernel/maps/fast_maps.cc                           |   741 +
 kernel/maps/fast_maps.h                            |   109 +
 kernel/maps/test.cc                                |   376 +
 kernel/mkinstalldirs                               |    32 +
 kernel/mod2.h                                      |   451 +
 kernel/numeric/Makefile.am                         |    23 +
 kernel/numeric/Makefile.in                         |  1085 +
 kernel/numeric/mpr_base.cc                         |  3229 +++
 kernel/numeric/mpr_base.h                          |   123 +
 kernel/numeric/mpr_inout.cc                        |   215 +
 kernel/numeric/mpr_inout.h                         |    74 +
 kernel/numeric/mpr_numeric.cc                      |  1381 +
 kernel/numeric/mpr_numeric.h                       |   236 +
 kernel/numeric/test.cc                             |   376 +
 kernel/oswrapper/Makefile.am                       |    22 +
 kernel/oswrapper/Makefile.in                       |  1127 +
 kernel/oswrapper/feread.cc                         |   422 +
 kernel/oswrapper/feread.h                          |    53 +
 kernel/oswrapper/fereadl.c                         |   852 +
 kernel/oswrapper/rlimit.c                          |    46 +
 kernel/oswrapper/rlimit.h                          |    23 +
 kernel/oswrapper/test.cc                           |   376 +
 kernel/oswrapper/timer.cc                          |   213 +
 kernel/oswrapper/timer.h                           |    28 +
 kernel/polys.cc                                    |    65 +
 kernel/polys.h                                     |   396 +
 kernel/preimage.cc                                 |   181 +
 kernel/preimage.h                                  |    10 +
 kernel/spectrum/GMPrat.cc                          |   548 +
 kernel/spectrum/GMPrat.h                           |    94 +
 kernel/spectrum/Makefile.am                        |    22 +
 kernel/spectrum/Makefile.in                        |  1088 +
 kernel/spectrum/kmatrix.h                          |   933 +
 kernel/spectrum/multicnt.cc                        |   248 +
 kernel/spectrum/multicnt.h                         |    83 +
 kernel/spectrum/npolygon.cc                        |   678 +
 kernel/spectrum/npolygon.h                         |   175 +
 kernel/spectrum/semic.cc                           |   493 +
 kernel/spectrum/semic.h                            |   148 +
 kernel/spectrum/spectrum.cc                        |   523 +
 kernel/spectrum/spectrum.h                         |    39 +
 kernel/spectrum/splist.cc                          |   386 +
 kernel/spectrum/splist.h                           |    89 +
 kernel/spectrum/test.cc                            |   376 +
 kernel/structs.h                                   |    95 +
 kernel/test.cc                                     |   619 +
 libpolys/AUTHORS                                   |     0
 libpolys/COPYING                                   |   103 +
 libpolys/ChangeLog                                 |     0
 libpolys/Makefile.am                               |    12 +
 libpolys/Makefile.in                               |   976 +
 libpolys/NEWS                                      |     0
 libpolys/README                                    |     9 +
 libpolys/_config.h.in                              |   242 +
 libpolys/aclocal.m4                                |  1185 +
 libpolys/coeffs/AE.cc                              |  1281 +
 libpolys/coeffs/AE.h                               |   112 +
 libpolys/coeffs/AEQ.cc                             |   921 +
 libpolys/coeffs/AEQ.h                              |   107 +
 libpolys/coeffs/AEp.cc                             |  1048 +
 libpolys/coeffs/AEp.h                              |   103 +
 libpolys/coeffs/Enumerator.h                       |   230 +
 libpolys/coeffs/Makefile.am                        |    40 +
 libpolys/coeffs/Makefile.in                        |  1104 +
 libpolys/coeffs/OPAE.cc                            |   397 +
 libpolys/coeffs/OPAE.h                             |    16 +
 libpolys/coeffs/OPAEQ.cc                           |   388 +
 libpolys/coeffs/OPAEQ.h                            |    15 +
 libpolys/coeffs/OPAEp.cc                           |   412 +
 libpolys/coeffs/OPAEp.h                            |    16 +
 libpolys/coeffs/bigintmat.cc                       |  2499 ++
 libpolys/coeffs/bigintmat.h                        |   333 +
 libpolys/coeffs/coeffs.h                           |   989 +
 libpolys/coeffs/ffields.cc                         |   996 +
 libpolys/coeffs/ffields.h                          |    21 +
 libpolys/coeffs/gnumpc.cc                          |   738 +
 libpolys/coeffs/gnumpc.h                           |    17 +
 libpolys/coeffs/gnumpfl.cc                         |   597 +
 libpolys/coeffs/gnumpfl.h                          |    21 +
 libpolys/coeffs/longrat.cc                         |  3277 +++
 libpolys/coeffs/longrat.h                          |   121 +
 libpolys/coeffs/longrat0.cc                        |   152 +
 libpolys/coeffs/modulop.cc                         |   930 +
 libpolys/coeffs/modulop.h                          |   135 +
 libpolys/coeffs/mpr_complex.cc                     |   826 +
 libpolys/coeffs/mpr_complex.h                      |   335 +
 libpolys/coeffs/mpr_global.h                       |    92 +
 libpolys/coeffs/numbers.cc                         |   556 +
 libpolys/coeffs/numbers.h                          |    98 +
 libpolys/coeffs/numstats.h                         |   148 +
 libpolys/coeffs/rintegers.cc                       |  1782 ++
 libpolys/coeffs/rintegers.h                        |    33 +
 libpolys/coeffs/rmodulo2m.cc                       |   877 +
 libpolys/coeffs/rmodulo2m.h                        |    21 +
 libpolys/coeffs/rmodulon.cc                        |   983 +
 libpolys/coeffs/rmodulon.h                         |    24 +
 libpolys/coeffs/shortfl.cc                         |   782 +
 libpolys/coeffs/shortfl.h                          |    22 +
 libpolys/coeffs/si_gmp.h                           |    17 +
 libpolys/coeffs/test.cc                            |   319 +
 libpolys/configure                                 | 24151 +++++++++++++++++
 libpolys/configure.ac                              |   150 +
 libpolys/libpolys-config.in                        |   108 +
 libpolys/libpolys.pc.in                            |    17 +
 libpolys/misc/Makefile.am                          |    22 +
 libpolys/misc/Makefile.in                          |   766 +
 libpolys/misc/auxiliary.h.in                       |   459 +
 libpolys/misc/int64vec.cc                          |   280 +
 libpolys/misc/int64vec.h                           |   101 +
 libpolys/misc/intvec.cc                            |   839 +
 libpolys/misc/intvec.h                             |   161 +
 libpolys/misc/mylimits.h                           |    16 +
 libpolys/misc/options.c                            |    12 +
 libpolys/misc/options.h                            |   140 +
 libpolys/misc/sirandom.c                           |    49 +
 libpolys/misc/sirandom.h                           |    20 +
 libpolys/polys/Makefile.am                         |   138 +
 libpolys/polys/Makefile.in                         |  1538 ++
 libpolys/polys/PolyEnumerator.cc                   |     9 +
 libpolys/polys/PolyEnumerator.h                    |   227 +
 libpolys/polys/clapconv.cc                         |   427 +
 libpolys/polys/clapconv.h                          |    34 +
 libpolys/polys/clapsing.cc                         |  1843 ++
 libpolys/polys/clapsing.h                          |    73 +
 libpolys/polys/coeffrings.h                        |    49 +
 libpolys/polys/ext_fields/algext.cc                |  1663 ++
 libpolys/polys/ext_fields/algext.h                 |    67 +
 libpolys/polys/ext_fields/transext.cc              |  2466 ++
 libpolys/polys/ext_fields/transext.h               |   137 +
 libpolys/polys/flintconv.cc                        |   184 +
 libpolys/polys/flintconv.h                         |    54 +
 libpolys/polys/kbuckets.cc                         |  1341 +
 libpolys/polys/kbuckets.h                          |   246 +
 libpolys/polys/matpol.cc                           |  1703 ++
 libpolys/polys/matpol.h                            |    95 +
 libpolys/polys/mod_raw.cc                          |   288 +
 libpolys/polys/mod_raw.h                           |    44 +
 libpolys/polys/monomials/maps.cc                   |   355 +
 libpolys/polys/monomials/maps.h                    |    32 +
 libpolys/polys/monomials/monomials.cc              |    34 +
 libpolys/polys/monomials/monomials.h               |   276 +
 libpolys/polys/monomials/p_polys.cc                |  4676 ++++
 libpolys/polys/monomials/p_polys.h                 |  1930 ++
 libpolys/polys/monomials/ring.cc                   |  5598 ++++
 libpolys/polys/monomials/ring.h                    |   824 +
 libpolys/polys/nc/gb_hack.h                        |    61 +
 libpolys/polys/nc/nc.h                             |   422 +
 libpolys/polys/nc/ncSACache.cc                     |    78 +
 libpolys/polys/nc/ncSACache.h                      |   131 +
 libpolys/polys/nc/ncSAFormula.cc                   |   759 +
 libpolys/polys/nc/ncSAFormula.h                    |   104 +
 libpolys/polys/nc/ncSAMult.cc                      |  1114 +
 libpolys/polys/nc/ncSAMult.h                       |   610 +
 libpolys/polys/nc/old.gring.cc                     |  3531 +++
 libpolys/polys/nc/sca.cc                           |  1592 ++
 libpolys/polys/nc/sca.h                            |   183 +
 libpolys/polys/nc/summator.cc                      |   204 +
 libpolys/polys/nc/summator.h                       |    72 +
 libpolys/polys/operations/pShallowCopyDelete.cc    |    53 +
 libpolys/polys/operations/pShallowCopyDelete.h     |    18 +
 libpolys/polys/operations/p_Mult_q.cc              |   302 +
 libpolys/polys/operations/p_Mult_q.h               |    32 +
 libpolys/polys/pDebug.cc                           |   422 +
 libpolys/polys/polys0.cc                           |   252 +
 libpolys/polys/prCopy.cc                           |   274 +
 libpolys/polys/prCopy.h                            |    51 +
 libpolys/polys/prCopy.pl                           |    38 +
 libpolys/polys/prCopyMacros.h                      |    52 +
 libpolys/polys/prCopyTemplate.cc                   |    37 +
 libpolys/polys/sbuckets.cc                         |   400 +
 libpolys/polys/sbuckets.h                          |   104 +
 libpolys/polys/simpleideals.cc                     |  1735 ++
 libpolys/polys/simpleideals.h                      |   154 +
 libpolys/polys/sparsmat.cc                         |  2958 +++
 libpolys/polys/sparsmat.h                          |    35 +
 libpolys/polys/templates/p_Add_q__T.cc             |    93 +
 libpolys/polys/templates/p_Copy__T.cc              |    37 +
 libpolys/polys/templates/p_Delete__T.cc            |    22 +
 libpolys/polys/templates/p_MemAdd.h                |   388 +
 libpolys/polys/templates/p_MemCmp.h                |   948 +
 libpolys/polys/templates/p_MemCopy.h               |    95 +
 libpolys/polys/templates/p_Merge_q__T.cc           |    59 +
 libpolys/polys/templates/p_Minus_mm_Mult_qq__T.cc  |   164 +
 libpolys/polys/templates/p_Mult_mm__T.cc           |    71 +
 libpolys/polys/templates/p_Mult_nn__T.cc           |    60 +
 libpolys/polys/templates/p_Neg__T.cc               |    28 +
 libpolys/polys/templates/p_Numbers.h               |   180 +
 libpolys/polys/templates/p_Procs.h                 |    74 +
 libpolys/polys/templates/p_Procs_Dynamic.cc        |   237 +
 libpolys/polys/templates/p_Procs_Dynamic.h         |    32 +
 libpolys/polys/templates/p_Procs_Generate.cc       |   328 +
 libpolys/polys/templates/p_Procs_Impl.h            |   704 +
 libpolys/polys/templates/p_Procs_Lib.cc            |    34 +
 libpolys/polys/templates/p_Procs_Set.h             |   211 +
 libpolys/polys/templates/p_Procs_Static.cc         |    70 +
 libpolys/polys/templates/p_Procs_Static.h          |    53 +
 libpolys/polys/templates/p_ShallowCopyDelete__T.cc |    38 +
 libpolys/polys/templates/p_kBucketSetLm__T.cc      |   183 +
 .../templates/pp_Mult_Coeff_mm_DivSelectMult__T.cc |    77 +
 .../templates/pp_Mult_Coeff_mm_DivSelect__T.cc     |    55 +
 libpolys/polys/templates/pp_Mult_mm_Noether__T.cc  |    86 +
 libpolys/polys/templates/pp_Mult_mm__T.cc          |    63 +
 libpolys/polys/templates/pp_Mult_nn__T.cc          |    60 +
 libpolys/polys/test.cc                             |   429 +
 libpolys/polys/weight.cc                           |   272 +
 libpolys/polys/weight.h                            |    33 +
 libpolys/polys/weight0.c                           |   487 +
 libpolys/reporter/Makefile.am                      |    15 +
 libpolys/reporter/Makefile.in                      |   681 +
 libpolys/reporter/dError.cc                        |   143 +
 libpolys/reporter/reporter.cc                      |   422 +
 libpolys/reporter/reporter.h                       |   141 +
 libpolys/reporter/s_buff.cc                        |   265 +
 libpolys/reporter/s_buff.h                         |    33 +
 libpolys/reporter/si_signals.h                     |   201 +
 libpolys/tests/Makefile.am                         |    66 +
 libpolys/tests/Makefile.in                         |  1112 +
 libpolys/tests/coeffs_test.h                       |   510 +
 libpolys/tests/common.h                            |   182 +
 libpolys/tests/cxxtest/Descriptions.cpp            |    58 +
 libpolys/tests/cxxtest/Descriptions.h              |    74 +
 libpolys/tests/cxxtest/DummyDescriptions.cpp       |    49 +
 libpolys/tests/cxxtest/DummyDescriptions.h         |    76 +
 libpolys/tests/cxxtest/ErrorFormatter.h            |   281 +
 libpolys/tests/cxxtest/ErrorPrinter.h              |    55 +
 libpolys/tests/cxxtest/Flags.h                     |   121 +
 libpolys/tests/cxxtest/GlobalFixture.cpp           |    23 +
 libpolys/tests/cxxtest/GlobalFixture.h             |    30 +
 libpolys/tests/cxxtest/Gui.h                       |   178 +
 libpolys/tests/cxxtest/LinkedList.cpp              |   172 +
 libpolys/tests/cxxtest/LinkedList.h                |    65 +
 libpolys/tests/cxxtest/Mock.h                      |   350 +
 libpolys/tests/cxxtest/ParenPrinter.h              |    21 +
 libpolys/tests/cxxtest/QtGui.h                     |   271 +
 libpolys/tests/cxxtest/RealDescriptions.cpp        |   311 +
 libpolys/tests/cxxtest/RealDescriptions.h          |   223 +
 libpolys/tests/cxxtest/Root.cpp                    |    27 +
 libpolys/tests/cxxtest/SelfTest.h                  |     7 +
 libpolys/tests/cxxtest/StdHeaders.h                |    25 +
 libpolys/tests/cxxtest/StdValueTraits.h            |   229 +
 libpolys/tests/cxxtest/StdioFilePrinter.h          |    41 +
 libpolys/tests/cxxtest/StdioPrinter.h              |    22 +
 libpolys/tests/cxxtest/TeeListener.h               |   182 +
 libpolys/tests/cxxtest/TestListener.h              |    70 +
 libpolys/tests/cxxtest/TestRunner.h                |   125 +
 libpolys/tests/cxxtest/TestSuite.cpp               |   138 +
 libpolys/tests/cxxtest/TestSuite.h                 |   512 +
 libpolys/tests/cxxtest/TestTracker.cpp             |   248 +
 libpolys/tests/cxxtest/TestTracker.h               |   114 +
 libpolys/tests/cxxtest/ValueTraits.cpp             |   140 +
 libpolys/tests/cxxtest/ValueTraits.h               |   377 +
 libpolys/tests/cxxtest/Win32Gui.h                  |   531 +
 libpolys/tests/cxxtest/X11Gui.h                    |   327 +
 libpolys/tests/cxxtest/YesNoRunner.h               |    29 +
 libpolys/tests/cxxtestgen.pl                       |   555 +
 libpolys/tests/polys_test.h                        |  2627 ++
 libpolys/tests/rings_test.h                        |   239 +
 libpolys/tests/simple_test.h                       |    21 +
 libsingular-config.in                              |   108 +
 m4/ax_append_compile_flags.m4                      |    65 +
 m4/ax_append_flag.m4                               |    69 +
 m4/ax_append_link_flags.m4                         |    63 +
 m4/ax_check_compile_flag.m4                        |    72 +
 m4/ax_check_link_flag.m4                           |    74 +
 m4/ax_compute_relative_paths.m4                    |   190 +
 m4/ax_cxx_gcc_abi_demangle.m4                      |    57 +
 m4/ax_normalize_path.m4                            |   115 +
 m4/ax_prefix_config_h.m4                           |   211 +
 m4/ax_pthread.m4                                   |   332 +
 m4/ax_python_embed.m4                              |   524 +
 m4/ax_python_with_version.m4                       |   128 +
 m4/cpu-check.m4                                    |    67 +
 m4/dbm-check.m4                                    |    17 +
 m4/flags.m4                                        |   155 +
 m4/flint-check.m4                                  |   128 +
 m4/gfanlib-check.m4                                |    76 +
 m4/gmp-check.m4                                    |   132 +
 m4/google-perftools.m4                             |   183 +
 m4/libtool.m4                                      |  7995 ++++++
 m4/ltoptions.m4                                    |   384 +
 m4/ltsugar.m4                                      |   123 +
 m4/ltversion.m4                                    |    23 +
 m4/lt~obsolete.m4                                  |    98 +
 m4/mathic-check.m4                                 |    31 +
 m4/ntl-check.m4                                    |   132 +
 m4/options.m4                                      |   383 +
 m4/p-procs.m4                                      |    90 +
 m4/polymake-check.m4                               |    82 +
 m4/readline-check.m4                               |   119 +
 omalloc/AUTHORS                                    |     0
 omalloc/COPYING                                    |    36 +
 omalloc/ChangeLog                                  |     0
 omalloc/Makefile.am                                |    80 +
 omalloc/Makefile.in                                |  1614 ++
 omalloc/NEWS                                       |     0
 omalloc/README                                     |     0
 omalloc/_config.h.in                               |   203 +
 omalloc/aclocal.m4                                 |  1173 +
 omalloc/configure                                  | 16582 ++++++++++++
 omalloc/configure.ac                               |   624 +
 omalloc/mylimits.h                                 |    14 +
 omalloc/omAllocDecl.h                              |   374 +
 omalloc/omAllocEmulate.c                           |    43 +
 omalloc/omAllocFunc.c                              |    21 +
 omalloc/omAllocFunc.h                              |    26 +
 omalloc/omAllocPrivate.h                           |   373 +
 omalloc/omAllocSystem.c                            |   356 +
 omalloc/omAllocSystem.h                            |    41 +
 omalloc/omBin.c                                    |   796 +
 omalloc/omBin.h                                    |    62 +
 omalloc/omBinPage.c                                |   606 +
 omalloc/omBinPage.h                                |    91 +
 omalloc/omDebug.c                                  |   644 +
 omalloc/omDebug.h                                  |   196 +
 omalloc/omDebugCheck.c                             |   578 +
 omalloc/omDebugTrack.c                             |   764 +
 omalloc/omDefaultConfig.h                          |   201 +
 omalloc/omDerivedConfig.h                          |   142 +
 omalloc/omError.c                                  |   136 +
 omalloc/omError.h                                  |    98 +
 omalloc/omGetBackTrace.c                           |    80 +
 omalloc/omGetBackTrace.h                           |    18 +
 omalloc/omGetPageSize.h                            |    46 +
 omalloc/omInline.h                                 |   262 +
 omalloc/omInlineDecl.h                             |    46 +
 omalloc/omList.c                                   |   259 +
 omalloc/omList.h                                   |   123 +
 omalloc/omMalloc.h                                 |    33 +
 omalloc/omMallocSystem.h                           |    19 +
 omalloc/omMemOps.h                                 |   177 +
 omalloc/omMmap.c                                   |    46 +
 omalloc/omOpts.c                                   |    24 +
 omalloc/omOpts.h                                   |    27 +
 omalloc/omPage.h                                   |   122 +
 omalloc/omRet2Info.c                               |   283 +
 omalloc/omRet2Info.h                               |    80 +
 omalloc/omReturn.h                                 |    60 +
 omalloc/omStats.c                                  |   143 +
 omalloc/omStats.h                                  |    51 +
 omalloc/omStructs.h                                |    36 +
 omalloc/omTables.c                                 |   219 +
 omalloc/om_Alloc.c                                 |   264 +
 omalloc/omalloc.c                                  |   128 +
 omalloc/omalloc.h                                  |    54 +
 omalloc/omalloc.pc.in                              |    17 +
 omalloc/omalloc_provide.c                          |    16 +
 omalloc/omtTest.c                                  |   495 +
 omalloc/omtTest.h                                  |   127 +
 omalloc/omtTestAlloc.c                             |   372 +
 omalloc/omtTestDebug.c                             |     2 +
 omalloc/omtTestError.c                             |   436 +
 omalloc/omtTestKeep.c                              |     2 +
 omalloc/omtTestReal.c                              |     1 +
 resources/Makefile.am                              |    24 +
 resources/Makefile.in                              |   987 +
 resources/_config.h.in                             |   141 +
 resources/aclocal.m4                               |  1180 +
 resources/configure                                | 21164 +++++++++++++++
 resources/configure.ac                             |    74 +
 resources/feFopen.cc                               |   210 +
 resources/feFopen.h                                |    37 +
 resources/feResource.cc                            |   717 +
 resources/feResource.h                             |    59 +
 resources/omFindExec.c                             |   284 +
 resources/omFindExec.h                             |    22 +
 resources/resources.pc.in                          |    17 +
 singular.spec.in                                   |    81 +
 xalloc/AUTHORS                                     |     0
 xalloc/ChangeLog                                   |     0
 xalloc/Makefile.am                                 |    19 +
 xalloc/Makefile.in                                 |   660 +
 xalloc/NEWS                                        |     0
 xalloc/README                                      |     0
 xalloc/dummy.c                                     |     6 +
 xalloc/omalloc.h                                   |   242 +
 1194 files changed, 906221 insertions(+)

diff --git a/.tarball-git-version b/.tarball-git-version
new file mode 100644
index 0000000..7413a75
--- /dev/null
+++ b/.tarball-git-version
@@ -0,0 +1 @@
+c60890b
\ No newline at end of file
diff --git a/AUTHORS b/AUTHORS
new file mode 100644
index 0000000..e69de29
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..18bc2b1
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,117 @@
+                        SINGULAR version 4-0
+                     University of Kaiserslautern
+      Department of Mathematics and  Centre for Computer Algebra
+     Authors: W. Decker, G.-M. Greuel, G. Pfister, H. Schoenemann
+
+                        Copyright (C) 1986-2014
+
+
+                               *NOTICE*
+
+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 (version 2 or version 3 of the License).
+
+Some single files have a copyright given within the file:
+Singular/links/ndbm.* (BSD)
+
+The following software modules shipped with SINGULAR have their own
+copyright: the omalloc library, the readline library, the GNU Multiple
+Precision Library (GMP), NTL: A Library for doing Number Theory (NTL),
+Flint: Fast Library for Number Theory, the Singular-Factory library, the
+Singular-libfac library, surfex, and, for the Windows distributions,
+the Cygwin DLL and the Cygwin tools (Cygwin), and the XEmacs editor
+(XEmacs).
+
+Their copyrights and licenses can be found in the accompanying files
+COPYING which are distributed along with these packages.  (Since
+version 3-0-3 of SINGULAR, all parts have GPL or LGPL as (one of) their
+licences.)
+
+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 (see GPL)
+
+Please send any comments or bug reports to
+<singular at mathematik.uni-kl.de>.
+
+If you want to be informed of new releases, please register as a
+SINGULAR user by sending an email to
+<singular at mathematik.uni-kl.de> with subject line `register' and body
+containing the following data:      your name, email address,
+organisation, country and platform(s).
+
+For information on how to cite SINGULAR see
+`http://www.singular.uni-kl.de/index.php/how-to-cite-singular'.
+
+You can also support SINGULAR by informing us about your result
+obtained by using SINGULAR.
+
+Availability
+============
+
+The latest information regarding the status of SINGULAR is always
+available from `http://www.singular.uni-kl.de'.
+
+Acknowledgements
+================
+
+The development of SINGULAR is directed and coordinated by Wolfram
+Decker, Gert-Martin Greuel, Gerhard Pfister, and Hans Scho"nemann.
+
+Current devteams: Abdus Salam School of Mathematical Sciences in Lahore,
+BTU Cottbus, Center for Advanced Security Research Darmstadt (CASED),
+FU Berlin, Isfahan University of Technology, Mathematisches
+Forschunginstitut Oberwolfach, Oklahoma State University, RWTH Aachen,
+Universidad de Buenos Aires, Universit� de Versailles
+Saint-Quentin-en-Yvelines, University of Go"ttingen, University of
+Hannover, University of La Laguna and University of Valladolid.
+
+Current SINGULAR developers: Wolfram Decker, Gert-Martin Greuel,
+Gerhard Pfister, Hans Scho"nemann,
+
+Shawki Al-Rashed, Daniel Andres, Mohamed Barakat, Isabel Bermejo,
+Muhammad Asan Binyamin, Rene' Birkner, Rocio Blanco, Xenia Bogomolec,
+Michael Brickenstein, Stanislav Bulygin, Antonio Campillo, Raza
+Choudery, Alexander Dreyer, Christian Eder, Santiago Encinas, Jose
+Ignacio Farran, Anne Fru"hbis-Kru"ger, Rosa de Frutos, Eva
+Garcia-Llorente, Ignacio Garcia-Marco, Christian Haase, Amir Hashemi,
+Fernando Hernando, Bradford Hovinen, Nazeran Idress, Anders Jensen,
+Lars Kastner, Junaid Alan Khan, Kai Kru"ger, Santiago Laplagne,
+Gr�goire Lecerf, Martin Lee, Viktor Levandovskyy, Benjamin Lorenz,
+Christoph Lossen, Thomas Markwig, Hannah Markwig, Irene Marquez, Bernd
+Martin, Edgar Martinez, Martin Monerjan, Francisco Monserrat, Oleksandr
+Motsak, Andreas Paffenholz, Maria Jesus Pisabarro, Diego Ruano, Afshan
+Sadiq, Kristina Schindelar, Mathias Schulze, Frank Seelisch, Andreas
+Steenpass, Stefan Steidel, Grischa Studzinski, Katharina Werner and Eva
+Zerz.
+
+Further contributions to SINGULAR have been made by: Martin Albrecht,
+Olaf Bachmann, Muhammad Ahsan Banyamin, Thomas Bauer, Thomas Bayer,
+Markus Becker, J. Boehm, Gergo Gyula Borus, Winfried Bruns, Fernando
+Hernando Carrillo, Victor Castellanos, Nadine Cremer, Michael Cuntz,
+Kai Dehmann, Christian Dingler, Marcin Dumnicki, Stephan Endrass,
+Vladimir Gerdt, Philippe Gimenez, Christian Gorzel, Hubert Grassmann,
+Jan Hackfeld, Agnes Heydtmann, Dietmar Hillebrand, Tobias Hirsch,
+Markus Hochstetter, N. Idrees, Manuel Kauers, Simon King, Sebastian
+Jambor, Oliver Labs, Anen Lakhal, Martin Lamm, Francisco Javier Lobillo,
+Christoph Mang, Michael Messollen, Andrea Mindnich, Antonio Montes,
+Jorge Martin Morales, Thomas Nu"ssler, Wolfgang Neumann, Markus Perling,
+Wilfried Pohl, Adrian Popescu, Tetyana Povalyaeva, Carlos Rabelo,
+Philipp Renner, J.-J.Salazar-Gonzalez, Alfredo Sanchez-Navarro, Ivor
+Saynisch, Jens Schmidt, Thomas Siebert, Christof Soeger, Silke Spang,
+William Stein, Ru"diger Stobbe, Henrik Strohmayer, Christian Stussak,
+Imade Sulandra, Akira Suzuki, Christine Theis, Enrique Tobis, Alberto
+Vigneron-Tenorio, Moritz Wenk, Eric Westenberger, Tim Wichmann, Oliver
+Wienand, Denis Yanovich and Oleksandr Yena.
+
+We should like to acknowledge the financial support given by the
+Volkswagen-Stiftung, the Deutsche Forschungsgemeinschaft and the
+Stiftung fu"r Innovation des Landes Rheinland-Pfalz to the SINGULAR
+project.
+
diff --git a/ChangeLog b/ChangeLog
new file mode 100644
index 0000000..e69de29
diff --git a/INSTALL b/INSTALL
new file mode 100644
index 0000000..ee9b755
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,51 @@
+windows (32bit):
+- get setup-x86.ex from www.cygwin.com
+- install cygwin from a nearby mirror
+- start "setup-x86.exe -X" (via cmd)
+  add repository: ftp://jim.mathematik.uni-kl.de/repo/cygwin
+  search for singular, select 4.0.1, install
+
+ubuntu-1204
+- add GPG key:
+  wget ftp://jim.mathematik.uni-kl.de/repo/extra/gpg
+  apt-key add gpg
+- add 
+  deb ftp://jim.mathematik.uni-kl.de/repo/ubuntu12 precise main
+  to /etc/apt/sources.list
+- apt-get update
+- apt-get install singular
+
+ubuntu-1404
+- add GPG key:
+  wget ftp://jim.mathematik.uni-kl.de/repo/extra/gpg
+  apt-key add gpg
+- add 
+  deb ftp://jim.mathematik.uni-kl.de/repo/ubuntu14 trusty main
+  to /etc/apt/sources.list
+- apt-get update
+- apt-get install singular
+
+fedora-20:
+- wget ftp://jim.mathematik.uni-kl.de/repo/extra/fedora/singular.repo -P /etc/yum.repos.d/
+- yum install singular
+
+generic ix86-Linux (32bit linux):
+- wget ftp;//www.mathematik.uni-kl.de/pub/Math/Singular/UNIX/Singular-4.0.1-ix86-Linux.tar.gz
+- tar zxf Singular-4.0.1-ix85-Linux.tar.gz
+- add $PWD/bin to your path (or add bin/Singular via a symbolic link to a
+  directory within your path)
+  
+generic x86_64 Linux (64bit linux):
+- wget ftp;//www.mathematik.uni-kl.de/pub/Math/Singular/UNIX/Singular-4.0.1-x86_64-Linux.tar.gz
+- tar zxf Singular-4.0.1-x86_64-Linux.tar.gz
+- add $PWD/bin to your path (or add bin/Singular via a symbolic link to a
+
+
+Mac OsX (intel):
+- ftp://www.mathematik.uni-kl.de/pub/Math/Singular/UNIX/Singular4-0-1_32.dmg
+  resp.
+  ftp://www.mathematik.uni-kl.de/pub/Math/Singular/UNIX/Singular4-0-1_64.dmg
+- install as usual
+
+sources:
+- wget  ftp;//www.mathematik.uni-kl.de/pub/Math/Singular/src/4-0-1/singular-4.0.1.tar.gz
diff --git a/IntegerProgramming/BigInt.cc b/IntegerProgramming/BigInt.cc
new file mode 100644
index 0000000..07c9698
--- /dev/null
+++ b/IntegerProgramming/BigInt.cc
@@ -0,0 +1,373 @@
+// BigInt.cc
+
+#ifndef BIG_INT_CC
+#define BIG_INT_CC
+
+#include "BigInt.h"
+
+//
+// Konstruktoren fuer die Klasse BigInt
+//
+
+// Default-Konstruktor
+
+BigInt::BigInt()
+{
+  mpz_init(value);
+}
+
+BigInt::BigInt(int a)
+{
+  mpz_init(value);
+  mpz_set_si(value,(long)a);
+}
+
+// Copy-Konstruktor
+
+BigInt::BigInt(const BigInt& a)
+{
+  mpz_init(value);
+  mpz_set(value,a.value);
+}
+
+// Destruktor
+BigInt::~BigInt()
+{
+  mpz_clear(value);
+}
+
+//
+// Zuweisungsoperatoren
+//
+
+BigInt& BigInt::operator=(int a)
+{
+  mpz_set_si(value,(long)a);
+  return *this;
+}
+
+BigInt& BigInt::operator=(const BigInt& a)
+{
+  mpz_set(value,a.value);
+  return *this;
+}
+
+//
+// Type-Conversion
+//
+
+BigInt::operator bool()
+{
+  if (mpz_sgn(value)) return true;
+  return false;
+}
+
+BigInt::operator int()
+{
+  long int ret_val;
+  ret_val=mpz_get_si(value);
+  return (int)ret_val;
+}
+
+BigInt::operator short()
+{
+  long int ret_val;
+  ret_val=mpz_get_si(value);
+  return (short)ret_val;
+}
+
+//
+// unary arithmetic operators
+//
+
+// unary Minus
+BigInt BigInt::operator-()
+{
+  BigInt erg;
+  mpz_neg(erg.value,value);
+  return erg;
+}
+
+// += Operator
+BigInt& BigInt::operator+=(const BigInt &a)
+{
+  BigInt aux;
+  mpz_set(aux.value,value);
+  mpz_add(value,aux.value,a.value);
+  return *this;
+}
+
+// -= Operator
+BigInt& BigInt::operator-=(const BigInt &a)
+{
+  BigInt aux;
+  mpz_set(aux.value,value);
+  mpz_sub(value,aux.value,a.value);
+  return *this;
+}
+
+// *= Operator
+BigInt& BigInt::operator*=(const BigInt &a)
+{
+  BigInt aux;
+  mpz_set(aux.value,value);
+  mpz_mul(value,aux.value,a.value);
+  return *this;
+}
+
+// /= Operator
+BigInt& BigInt::operator/=(const BigInt &a)
+{
+  BigInt aux;
+  mpz_set(aux.value,value);
+  mpz_fdiv_q(value,aux.value,a.value);
+  return *this;
+}
+
+// prefix ++
+BigInt& BigInt::operator++()
+{
+  BigInt aux;
+  mpz_set(aux.value,value);
+  mpz_add(value,aux.value,BigInt(1).value);
+  return *this;
+}
+
+// postfix ++
+BigInt BigInt::operator++(int)
+{
+  BigInt erg;
+  mpz_add(erg.value,value,BigInt(1).value);
+  return erg;
+}
+
+// prefix --
+BigInt& BigInt::operator--()
+{
+  BigInt aux;
+  mpz_set(aux.value,value);
+  mpz_sub(value,aux.value,BigInt(1).value);
+  return *this;
+}
+
+// postfix --
+BigInt BigInt::operator--(int)
+{
+  BigInt erg;
+  mpz_add(erg.value,value,BigInt(1).value);
+  return erg;
+}
+
+BigInt operator-(const BigInt& r)
+{
+  BigInt erg;
+  mpz_neg(erg.value,r.value);
+  return erg;
+}
+
+//
+// Vergleichsoperatorn
+//
+
+bool operator<(const BigInt& a,const BigInt& b)
+{
+  if (mpz_cmp(a.value,b.value)<0) return true;
+  return false;
+}
+
+bool operator<=(const BigInt& a,const BigInt& b)
+{
+  if (mpz_cmp(a.value,b.value)>0) return false;
+  return true;
+}
+
+bool operator>(const BigInt& a,const BigInt& b)
+{
+  if (mpz_cmp(a.value,b.value)>0) return true;
+  return false;
+}
+
+bool operator>=(const BigInt& a,const BigInt& b)
+{
+  if (mpz_cmp(a.value,b.value)<0) return false;
+  return true;
+}
+
+bool operator==(const BigInt& a,const BigInt& b)
+{
+  if (!mpz_cmp(a.value,b.value)) return true;
+  return false;
+}
+
+bool operator!=(const BigInt& a,const BigInt& b)
+{
+  if (!mpz_cmp(a.value,b.value)) return false;
+  return true;
+}
+
+bool operator<(const int& a,const BigInt& b)
+{
+  if (mpz_cmp(BigInt(a).value,b.value)<0) return true;
+  return false;
+}
+
+bool operator<=(const int& a,const BigInt& b)
+{
+  if (mpz_cmp(BigInt(a).value,b.value)>0) return false;
+  return true;
+}
+
+bool operator>(const int& a,const BigInt& b)
+{
+  if (mpz_cmp(BigInt(a).value,b.value)>0) return true;
+  return false;
+}
+
+bool operator>=(const int& a,const BigInt& b)
+{
+  if (mpz_cmp(BigInt(a).value,b.value)<0) return false;
+  return true;
+}
+
+bool operator==(const int& a,const BigInt& b)
+{
+  if (!mpz_cmp(BigInt(a).value,b.value)) return true;
+  return false;
+}
+
+bool operator!=(const int& a,const BigInt& b)
+{
+  if (!mpz_cmp(BigInt(a).value,b.value)) return false;
+  return true;
+}
+
+bool operator<(const BigInt& a,const int& b)
+{
+  if (mpz_cmp(a.value,BigInt(b).value)<0) return true;
+  return false;
+}
+
+bool operator<=(const BigInt& a,const int& b)
+{
+  if (mpz_cmp(a.value,BigInt(b).value)>0) return false;
+  return true;
+}
+
+bool operator>(const BigInt& a,const int& b)
+{
+  if (mpz_cmp(a.value,BigInt(b).value)>0) return true;
+  return false;
+}
+
+bool operator>=(const BigInt& a,const int& b)
+{
+  if (mpz_cmp(a.value,BigInt(b).value)<0) return false;
+  return true;
+}
+
+bool operator==(const BigInt& a,const int& b)
+{
+  if (!mpz_cmp(a.value,BigInt(b).value)) return true;
+  return false;
+}
+
+bool operator!=(const BigInt& a,const int& b)
+{
+  if (!mpz_cmp(a.value,BigInt(b).value)) return false;
+  return true;
+}
+
+//
+// die Grundoperationen
+//
+
+BigInt operator+(const BigInt& a,const BigInt &b)
+{
+  BigInt erg(a);
+  return erg+=b;
+}
+
+BigInt operator-(const BigInt& a,const BigInt &b)
+{
+  BigInt erg(a);
+  return erg-=b;
+}
+
+BigInt operator*(const BigInt& a,const BigInt &b)
+{
+  BigInt erg(a);
+  return erg*=b;
+}
+
+BigInt operator/(const BigInt& a,const BigInt &b)
+{
+  BigInt erg(a);
+  return erg/=b;
+}
+
+BigInt operator+(const int& a,const BigInt &b)
+{
+  BigInt erg(a);
+  return erg+=b;
+}
+
+BigInt operator-(const int& a,const BigInt &b)
+{
+  BigInt erg(a);
+  return erg-=b;
+}
+
+BigInt operator*(const int& a,const BigInt &b)
+{
+  BigInt erg(a);
+  return erg*=b;
+}
+
+BigInt operator/(const int& a,const BigInt &b)
+{
+  BigInt erg(a);
+  return erg/=b;
+}
+
+BigInt operator+(const BigInt& a,const int &b)
+{
+  BigInt erg(a);
+  return erg+=BigInt(b);
+}
+
+BigInt operator-(const BigInt& a,const int &b)
+{
+  BigInt erg(a);
+  return erg-=BigInt(b);
+}
+
+BigInt operator*(const BigInt& a,const int &b)
+{
+  BigInt erg(a);
+  return erg*=BigInt(b);
+}
+
+BigInt operator/(const BigInt& a,const int &b)
+{
+  BigInt erg(a);
+  return erg/=BigInt(b);
+}
+
+// liefert das Vorzeichen
+int sgn(const BigInt& a)
+{
+  return mpz_sgn(a.value);
+}
+
+// liefert den Absolutbetrag
+BigInt abs(const BigInt& a)
+{
+  BigInt erg;
+  if (mpz_sgn(a.value)<0)
+    mpz_neg(erg.value,a.value);
+  else
+    mpz_set(erg.value,a.value);
+  return erg;
+}
+
+#endif  // BIG_INT_CC
diff --git a/IntegerProgramming/BigInt.h b/IntegerProgramming/BigInt.h
new file mode 100644
index 0000000..4fd3ead
--- /dev/null
+++ b/IntegerProgramming/BigInt.h
@@ -0,0 +1,83 @@
+// BigInt.h
+
+// A BigInt-class with not much more functions than needed by the
+// LLL-algorithm. Wrapper class for the GNU MP library.
+
+#ifndef BIG_INT_H
+#define BIG_INT_H
+
+#include <stdlib.h>
+#include <float.h>
+#include <math.h>
+#include <ctype.h>
+#include <string.h>
+#include <stddef.h>
+#include <gmp.h>
+
+class BigInt
+{
+    mpz_t value;
+
+    public:
+
+    BigInt( );
+    BigInt( int );
+    BigInt( const BigInt& );
+    ~BigInt( );
+
+    BigInt& operator = ( int );
+    BigInt& operator = ( const BigInt& );
+
+    operator bool( );
+    operator int( );
+    operator short( );
+
+    BigInt  operator - ( );
+    BigInt& operator += ( const BigInt& );
+    BigInt& operator -= ( const BigInt& );
+    BigInt& operator *= ( const BigInt& );
+    BigInt& operator /= ( const BigInt& );
+    BigInt& operator ++ ( );
+    BigInt  operator ++ ( int );
+    BigInt& operator -- ( );
+    BigInt  operator -- ( int );
+
+    friend BigInt operator - ( const BigInt& );
+
+    friend bool operator <  ( const BigInt&, const BigInt& );
+    friend bool operator <= ( const BigInt&, const BigInt& );
+    friend bool operator >  ( const BigInt&, const BigInt& );
+    friend bool operator >= ( const BigInt&, const BigInt& );
+    friend bool operator == ( const BigInt&, const BigInt& );
+    friend bool operator != ( const BigInt&, const BigInt& );
+    friend bool operator <  ( const int&, const BigInt& );
+    friend bool operator <= ( const int&, const BigInt& );
+    friend bool operator >  ( const int&, const BigInt& );
+    friend bool operator >= ( const int&, const BigInt& );
+    friend bool operator == ( const int&, const BigInt& );
+    friend bool operator != ( const int&, const BigInt& );
+    friend bool operator <  ( const BigInt&, const int& );
+    friend bool operator <= ( const BigInt&, const int& );
+    friend bool operator >  ( const BigInt&, const int& );
+    friend bool operator >= ( const BigInt&, const int& );
+    friend bool operator == ( const BigInt&, const int& );
+    friend bool operator != ( const BigInt&, const int& );
+
+    friend int    sgn ( const BigInt& );
+    friend BigInt abs ( const BigInt& );
+};
+
+BigInt operator + ( const BigInt&, const BigInt& );
+BigInt operator - ( const BigInt&, const BigInt& );
+BigInt operator * ( const BigInt&, const BigInt& );
+BigInt operator / ( const BigInt&, const BigInt& );
+BigInt operator + ( const int&, const BigInt& );
+BigInt operator - ( const int&, const BigInt& );
+BigInt operator * ( const int&, const BigInt& );
+BigInt operator / ( const int&, const BigInt& );
+BigInt operator + ( const BigInt&, const int& );
+BigInt operator - ( const BigInt&, const int& );
+BigInt operator * ( const BigInt&, const int& );
+BigInt operator / ( const BigInt&, const int& );
+
+#endif  // BIG_INT_H
diff --git a/IntegerProgramming/Buchberger.cc b/IntegerProgramming/Buchberger.cc
new file mode 100644
index 0000000..ddb21d5
--- /dev/null
+++ b/IntegerProgramming/Buchberger.cc
@@ -0,0 +1,3196 @@
+// Buchberger.cc
+
+// implementation of Buchberger's Algorithm.
+
+#ifndef BUCHBERGER_CC
+#define BUCHBERGER_CC
+
+#include "ideal.h"
+
+/////////////////////////////////////////////////////////////////////////////
+/////////////// S-pair computation //////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+
+BOOLEAN ideal::unnecessary_S_pair(list_iterator& first_iter,
+                                  list_iterator& second_iter) const
+{
+// This function checks several criteria to discard th S-pair of the
+// binomials referenced by the iterators. The criteria depend on the
+// settings of the ideal�s S-pair flags.
+
+// The arguments are iterators instead of the referenced binomials
+// because we have to do some equality tests. These are more efficient on
+// iterators than on binomials.
+
+///////////// criterion of relatively prime leading terms ///////////////////
+
+  // An S-pair can discarded if the leading terms of the two binomials are
+  // relatively prime.
+
+  if(rel_primeness)
+    if(relatively_prime(first_iter.get_element(),second_iter.get_element())
+       ==TRUE)
+      return TRUE;
+
+//////////// criterion M ///////////////////////////////////////////////////
+
+  if(M_criterion)
+  {
+
+    list_iterator iter;
+    binomial& bin1=first_iter.get_element();
+    binomial& bin2=second_iter.get_element();
+
+    // The M-criterion of Gebauer/Moeller checks binomial triples as
+    // explained in binomial.h; these are built of the elements referenced
+    // by the argument iterators and a third element appearing before the
+    // element referenced by second_iter in the generator lists.
+
+
+#ifdef NO_SUPPORT_DRIVEN_METHODS_EXTENDED
+
+    iter.set_to_list(generators);
+
+#endif  // NO_SUPPORT_DRIVEN_METHODS_EXTENDED
+
+#ifdef SUPPORT_DRIVEN_METHODS_EXTENDED
+
+    // The support of the lcm of two monomials is the union of their supports.
+    // To test criterion M, we then only have to consider lists whose support
+    // is a subset of the union of (first_iter.get_element()).head_support and
+    // (second_iter.get_element()).head_support. As only elements before
+    // second_iter.get_element() are tested, we can stop iteraton as soon as
+    // we reach this element.
+
+    int supp2=bin2.head_support%Number_of_Lists;
+    int supp_union=(bin1.head_support%Number_of_Lists)|supp2;
+    // supp_union (read as binary vector) is the union of the supports of
+    // first_iter.get_element() and second_iter.get_element()
+    // (restricted to List_Support_Variables variables).
+
+    for(int i=0;i<S.number_of_subsets[supp_union];i++)
+      // Go through the lists that contain elements whose support is a
+      // subset of supp_union.
+    {
+      int actual_list=S.subsets_of_support[supp_union][i];
+      iter.set_to_list(generators[actual_list]);
+      // This is the i-th list among the generator list with elements
+      // whose support is a subset of supp_union.
+
+      if(actual_list==supp2)
+        break;
+      // The iteration has reached the list referenced by second_iter,
+      // this is handled alone to avoid unnecessary checks.
+      // Before breakin the loop, iter has to be set to this list.
+
+      while(iter.is_at_end()==FALSE)
+        // Iterate over the list with three iterators according to the
+        // description of criterion M.
+      {
+        if(M(iter.get_element(),bin1,bin2)==TRUE)
+          return TRUE;
+        iter.next();
+      }
+    }
+
+#endif  // SUPPORT_DRIVEN_METHODS_EXTENDED
+
+
+    // Now, iter references second_iter's list,
+    // if SUPPORT_DRIVEN_METHODS_EXTENDED are enabled or not.
+
+    while(iter!=second_iter)
+    {
+      if(M(iter.get_element(),bin1,bin2)==TRUE)
+        return TRUE;
+      iter.next();
+    }
+  }
+
+/////////////////////// criterion F ////////////////////////////////////////
+
+  if(F_criterion)
+  {
+
+    list_iterator iter;
+    binomial& bin1=first_iter.get_element();
+    binomial& bin2=second_iter.get_element();
+
+    // The F-criterion of Gebauer/Moeller checks binomial triples as
+    // explained in binomial.h; these are built of the elements referenced
+    // by the argument iterators and a third element appearing before the
+    // element referenced by first_iter in the generator lists.
+
+#ifdef NO_SUPPORT_DRIVEN_METHODS_EXTENDED
+
+    iter.set_to_list(generators);
+
+#endif  // NO_SUPPORT_DRIVEN_METHODS_EXTENDED
+
+
+#ifdef SUPPORT_DRIVEN_METHODS_EXTENDED
+
+    // Again, we only have to consider lists whose support is a subset of the
+    // union of (first_iter.get_element()).head_support and
+    // (second_iter.get_element()).head_support.
+    // Additionally,we can override lists whose support is to small.
+
+    int supp1=bin1.head_support%Number_of_Lists;
+    int supp2=bin2.head_support%Number_of_Lists;
+    int supp_union=supp1|supp2;
+    // supp_union (read as binary vector) is the union of the supports of
+    // first_iter.get_element() and second_iter.get_element()
+    // (restricted to List_Support_Variables variables).
+
+    for(int i=0;i<S.number_of_subsets[supp_union];i++)
+      // Go through the lists that contain elements whose support is a
+      // subset of supp_union.
+    {
+      int actual_list=S.subsets_of_support[supp_union][i];
+
+      if((actual_list|supp2) != supp_union)
+        continue;
+      // The support of the actual list is too small, so its elements cannot
+      // satisfie criterion F.
+
+      iter.set_to_list(generators[actual_list]);
+      // This is the i-th list among the generator list with elements
+      // whose support is a subset of supp_union.
+
+      if(actual_list==supp1)
+        break;
+      // The iteration has reached the list referenced by first_iter;
+      // this is handled alone to avoid unnecessary checks.
+      // iter has to be set to that list before breaking the loop.
+
+      while(iter.is_at_end()==FALSE)
+        // Iterate over the list with three iterators according to the
+        // description of criterion F.
+      {
+        if(F(iter.get_element(),bin1,bin2)==TRUE)
+          return TRUE;
+        iter.next();
+      }
+    }
+
+#endif  // SUPPORT_DRIVEN_METHODS_EXTENDED
+
+    // Now, iter references first_iter's list,
+    // if SUPPORT_DRIVEN_METHODS_EXTENDED are enabled or not.
+
+    while(iter!=first_iter)
+    {
+      if(F(iter.get_element(),bin1,bin2)==TRUE)
+        return TRUE;
+      iter.next();
+    }
+  }
+
+/////////////////////// criterion B /////////////////////////////////////////
+
+  if(B_criterion)
+  {
+
+    list_iterator iter;
+    binomial& bin1=first_iter.get_element();
+    binomial& bin2=second_iter.get_element();
+
+    // The B-criterion of Gebauer/Moeller checks binomial triples as
+    // explained in binomial.h; these are built of the elements referenced
+    // by the argument iterators and a third element appearing after the
+    // element referenced by second_iter in the generator lists.
+
+    iter=second_iter;
+    iter.next();
+
+    // First test second_iter's list.
+    // This is the only list if NO_SUPPORT_DRIVEN_METHODS are enabled.
+
+    while(iter.is_at_end()==FALSE)
+    {
+      if(B(iter.get_element(),bin1,bin2)==TRUE)
+        return(TRUE);
+      iter.next();
+    }
+
+#ifdef SUPPORT_DRIVEN_METHODS_EXTENDED
+
+    // Now consider the other lists.
+    // Again, we only have to consider lists whose support is a subset of the
+    // union of (first_iter.get_element()).head_support and
+    // (second_iter.get_element()).head_support.
+
+    int supp2=bin2.head_support%Number_of_Lists;
+    int supp_union=(bin1.head_support%Number_of_Lists)|supp2;
+    // supp_union (read as binary vector) is the union of the supports of
+    // first_iter.get_element() and second_iter.get_element()
+    // (restricted to List_Support_Variables variables).
+
+    for(int i=0;i<S.number_of_subsets[supp_union];i++)
+      // Go through the lists that contain elements whose support is a
+      // subset of supp_union.
+    {
+      int actual_list=S.subsets_of_support[supp_union][i];
+
+      if(actual_list<=supp2)
+        continue;
+      // Only lists after second_iter's list have to be considered.
+
+      iter.set_to_list(generators[actual_list]);
+      // This is the i-th list among the generator list with elements
+      // whose support is a subset of supp_union.
+
+      while(iter.is_at_end()==FALSE)
+      {
+        // Iterate over the list with three iterators according to the
+        // description of criterion B.
+        if(B(iter.get_element(),bin1,bin2)==TRUE)
+          return TRUE;
+        iter.next();
+      }
+    }
+
+#endif  // SUPPORT_DRIVEN_METHODS_EXTENDED
+  }
+
+////////////////////// Buchberger�s second criterion ////////////////////////
+
+  if(second_criterion)
+  {
+    list_iterator iter;
+    binomial& bin1=first_iter.get_element();
+    binomial& bin2=second_iter.get_element();
+
+    // The Buchberger�s second criterion checks binomial triples as
+    // explained in binomial.h; these are built of the elements referenced
+    // by the argument iterators and a third element appearing anywhere
+    // in the generator lists.
+
+#ifdef NO_SUPPORT_DRIVEN_METHODS_EXTENDED
+
+    iter.set_to_list(generators);
+
+    while(iter.is_at_end()==FALSE)
+      // Iterate over the list with three iterators according to the
+      // description of the second criterion.
+    {
+      if((iter!=first_iter) && (iter!=second_iter))
+        // Else the second criterion must not be applied
+        // (lcm(a,b) is, of course, divisible by a and by b).
+        if(second_crit(iter.get_element(),bin1,bin2)==TRUE)
+          return TRUE;
+      iter.next();
+    }
+
+#endif  // NO_SUPPORT_DRIVEN_METHODS_EXTENDED
+
+#ifdef SUPPORT_DRIVEN_METHODS_EXTENDED
+
+    // Again, we only have to consider lists whose support is a subset of
+    // the union of (first_iter.get_element()).head_support
+    // and (second_iter.get_element()).head_support.
+
+    int supp1=bin1.head_support%Number_of_Lists;
+    int supp2=bin2.head_support%Number_of_Lists;
+    int supp_union=supp1|supp2;
+    // supp_union (read as binary vector) is the union of the supports of
+    // first_iter.get_element() and second_iter.get_element()
+    // (restricted to List_Support_Variables variables)
+
+    for(int i=0;i<S.number_of_subsets[supp_union];i++)
+      // Go through the lists that contain elements whose support is a
+      // subset of supp_union.
+    {
+      int actual_list=S.subsets_of_support[supp_union][i];
+
+      if((actual_list==supp1) || (actual_list==supp2))
+        continue;
+      // The lists containing the elements referenced by the argument
+      // iterators are tested separately to avoid unnecessary checks for
+      // equality.
+
+      iter.set_to_list(generators[actual_list]);
+      // This is the i-th list among the generator list with elements
+      // whose support is a subset of supp_union.
+
+      while(iter.is_at_end()==FALSE)
+        // Iterate over the list with three iterators according to the
+        // description of the second criterion.
+      {
+        if(second_crit(iter.get_element(),bin1,bin2)==TRUE)
+          return TRUE;
+        iter.next();
+      }
+    }
+
+    if(supp1==supp2)
+      // The elements referenced by first_iter and second_iter appear in the
+      // same list.
+    {
+      iter.set_to_list(generators[supp1]);
+      while(iter.is_at_end()==FALSE)
+      {
+        if((iter!=first_iter) && (iter!=second_iter))
+          // Else the second criterion must not be applied
+          // (lcm(a,b) is, of course, divisible by a and by b).
+          if(second_crit(iter.get_element(),bin1,bin2)==TRUE)
+            return TRUE;
+        iter.next();
+      }
+    }
+    else
+      // The elements referenced by first_iter and second_iter appear in
+      // different lists.
+    {
+
+      // Test first_iter�s list.
+      iter.set_to_list(generators[supp1]);
+      while(iter.is_at_end()==FALSE)
+      {
+        if(iter!=first_iter)
+          // Else the second criterion must not be applied
+          // (lcm(a,b) is, of course, divisible by a and by b).
+          if(second_crit(iter.get_element(),bin1,bin2)==TRUE)
+            return TRUE;
+        iter.next();
+      }
+
+      // Test second_iter�s list.
+      iter.set_to_list(generators[supp2]);
+      while(iter.is_at_end()==FALSE)
+      {
+        if(iter!=second_iter)
+          // Else the second criterion must not be applied
+          // (lcm(a,b) is, of course, divisible by a and by b).
+          if(second_crit(iter.get_element(),bin1,bin2)==TRUE)
+            return TRUE;
+        iter.next();
+      }
+    }
+#endif  // SUPPORT_DRIVEN_METHODS_EXTENDED
+  }
+
+  // no criterion found to discard the S-Pair to compute
+  return FALSE;
+}
+
+ideal& ideal::compute_actual_S_pairs_1()
+{
+// This routine implements the simplest method for the S-pair computation
+// (and one of the most efficient methods). We simply iterate over the
+// generator list(s) with two pointers to look at each binomial pair.
+// The "done"-mark of each list element tells us if this element was
+// already considered in a previous S-pair computation; pairs of such
+// "old" binomials do not have to be computed anymore (but pairs of an old
+// and a new one have to be computed, of course). As the generator list are
+// ordered with respect to the "done"-flag (all undone elements preceed all
+// done elements), we can avoid unnecessary iteration steps by breaking
+// the iteration at the right point.
+
+// The computed S-pairs are stored in the aux_list for further computations.
+
+// For a better overview, the code for NO_SUPPORT_DRIVEN_METHODS_EXTENDED
+// and SUPPORT_DRIVEN_METHODS_EXTENDED is completetly separated in this
+// function.
+
+// Note that the "next()"-operations in the following routine do not reach a
+// NULL pointer because of the implementation of the "is_at_end()"-function
+// and because the "done"-component of the dummy element is set to zero.
+
+#ifdef NO_SUPPORT_DRIVEN_METHODS_EXTENDED
+
+  list_iterator first_iter(generators);
+
+  while(first_iter.element_is_marked_done()==FALSE)
+    // new generator, compute S-pairs with all following generators
+    // Notice that the new generators are always at the beginning,
+    // the old generators at the end of the generator list.
+  {
+    binomial& bin=first_iter.get_element();
+    first_iter.mark_element_done();
+
+    list_iterator second_iter(first_iter);
+    second_iter.next();
+    // This may be the dummy element.
+
+    while(second_iter.is_at_end()==FALSE)
+    {
+      if(unnecessary_S_pair(first_iter,second_iter)==FALSE)
+         aux_list._insert(S_binomial(bin,second_iter.get_element(),w));
+      second_iter.next();
+    }
+
+    first_iter.next();
+  }
+
+  // Now, first_iter references an old generator or the end of the generator
+  // list. As all following generators are old ones, we are done.
+
+#endif  // NO_SUPPORT_DRIVEN_METHODS_EXTENDED
+
+
+#ifdef SUPPORT_DRIVEN_METHODS_EXTENDED
+
+  list_iterator first_iter;
+
+  for(int i=0;i<Number_of_Lists;i++)
+  {
+    first_iter.set_to_list(generators[i]);
+
+    while(first_iter.element_is_marked_done()==FALSE)
+      // new generator, compute S-pairs with all following elements
+      // Notice that the new generators are always at the beginning,
+      // the old generators at the end of the generator lists.
+    {
+      binomial& bin=first_iter.get_element();
+      first_iter.mark_element_done();
+
+      // First search over the actual list with the second iterator.
+
+      list_iterator second_iter(first_iter);
+      second_iter.next();
+
+      while(second_iter.is_at_end()==FALSE)
+      {
+        if(unnecessary_S_pair(first_iter,second_iter)==FALSE)
+          aux_list._insert(S_binomial(bin,second_iter.get_element(),w));
+      second_iter.next();
+      }
+
+      // Then search over the remaining lists.
+
+      for(int j=i+1;j<Number_of_Lists;j++)
+      {
+        second_iter.set_to_list(generators[j]);
+
+        while(second_iter.is_at_end()==FALSE)
+        {
+          if(unnecessary_S_pair(first_iter,second_iter)==FALSE)
+            aux_list._insert(S_binomial(bin,second_iter.get_element(),w));
+          second_iter.next();
+        }
+      }
+      first_iter.next();
+    }
+
+    while(first_iter.is_at_end()==FALSE)
+      // old generator, compute only S-pairs with the following new generators
+      // (S-pairs with the following old generators were already computed
+      // before, first_iter.element_is_marked_done()==TRUE)
+      // As all generators in the actual list are old ones, we can
+      // start iteration with the next list.
+    {
+      binomial& bin=first_iter.get_element();
+
+      list_iterator second_iter;
+
+      for(int j=i+1;j<Number_of_Lists;j++)
+        // search over remaining lists
+      {
+        second_iter.set_to_list(generators[j]);
+
+        while(second_iter.element_is_marked_done()==FALSE)
+          // consider only new generators
+        {
+          if(unnecessary_S_pair(first_iter,second_iter)==FALSE)
+            aux_list._insert(S_binomial(bin,second_iter.get_element(),w));
+          second_iter.next();
+        }
+      }
+      first_iter.next();
+    }
+
+  }
+
+#endif  // SUPPORT_DRIVEN_METHODS_EXTENDED
+  return(*this);
+}
+
+ideal& ideal::compute_actual_S_pairs_1a()
+{
+// The only difference to the previous routine is that the aux_list is kept
+// ordered with respect to the ideal�s term ordering, i.e. the inserts are
+// replaced by ordered inserts.
+
+#ifdef NO_SUPPORT_DRIVEN_METHODS_EXTENDED
+
+  list_iterator first_iter(generators);
+
+  while(first_iter.element_is_marked_done()==FALSE)
+    // new generator, compute S-pairs with all following generators
+    // Notice that the new generators are always at the beginning,
+    // the old generators at the end of the generator list.
+  {
+    binomial& bin=first_iter.get_element();
+    first_iter.mark_element_done();
+
+    list_iterator second_iter(first_iter);
+    second_iter.next();
+    // This may be the dummy element.
+
+    while(second_iter.is_at_end()==FALSE)
+    {
+      if(unnecessary_S_pair(first_iter,second_iter)==FALSE)
+         aux_list._ordered_insert
+           (S_binomial(bin,second_iter.get_element(),w),w);
+      second_iter.next();
+    }
+    first_iter.next();
+  }
+
+  // Now, first_iter references an old generator or the end of the generator
+  // list. As all following generators are old ones, we are done.
+
+#endif  // NO_SUPPORT_DRIVEN_METHODS_EXTENDED
+
+#ifdef SUPPORT_DRIVEN_METHODS_EXTENDED
+
+  list_iterator first_iter;
+
+  for(int i=0;i<Number_of_Lists;i++)
+  {
+    first_iter.set_to_list(generators[i]);
+
+    while(first_iter.element_is_marked_done()==FALSE)
+      // new generator, compute S-pairs with all following elements
+      // Notice that the new generators are always at the beginning,
+      // the old generators at the end of the generator lists.
+    {
+      binomial& bin=first_iter.get_element();
+      first_iter.mark_element_done();
+
+      // First search over the actual list with the second iterator.
+
+      list_iterator second_iter(first_iter);
+      second_iter.next();
+
+      while(second_iter.is_at_end()==FALSE)
+      {
+        if(unnecessary_S_pair(first_iter,second_iter)==FALSE)
+          aux_list._ordered_insert
+            (S_binomial(bin,second_iter.get_element(),w),w);
+      second_iter.next();
+      }
+
+      // Then search over the remaining lists.
+
+      for(int j=i+1;j<Number_of_Lists;j++)
+      {
+        second_iter.set_to_list(generators[j]);
+
+        while(second_iter.is_at_end()==FALSE)
+        {
+          if(unnecessary_S_pair(first_iter,second_iter)==FALSE)
+            aux_list._ordered_insert
+              (S_binomial(bin,second_iter.get_element(),w),w);
+          second_iter.next();
+        }
+      }
+      first_iter.next();
+    }
+
+    while(first_iter.is_at_end()==FALSE)
+      // old generator, compute only S-pairs with the following new generators
+      // (S-pairs with the following old generators were already computed
+      // before, first_iter.element_is_marked_done()==TRUE)
+      // As all generators in the actual list are old ones, we can
+      // start iteration with the next list.
+    {
+      binomial& bin=first_iter.get_element();
+
+      list_iterator second_iter;
+
+      for(int j=i+1;j<Number_of_Lists;j++)
+        // search over remaining lists
+      {
+        second_iter.set_to_list(generators[j]);
+
+        while(second_iter.element_is_marked_done()==FALSE)
+          // consider only new generators
+        {
+          if(unnecessary_S_pair(first_iter,second_iter)==FALSE)
+            aux_list._ordered_insert
+              (S_binomial(bin,second_iter.get_element(),w),w);
+          second_iter.next();
+        }
+      }
+      first_iter.next();
+    }
+
+  }
+
+#endif  // SUPPORT_DRIVEN_METHODS_EXTENDED
+
+  return(*this);
+}
+
+ideal& ideal::compute_actual_S_pairs_2()
+{
+// This routine implements are mor dynamic S-pair-computation. As in the
+// previous routines, we iterate over the generator list(s) with two
+// iterators, forming pairs under the consideration of the "done"-flags.
+
+// But before inserting into the aux_list, these S-pairs are reduced by
+// the ideal generators. This seems to be clever, but shows to be a
+// disadvantage:
+// In the previous S-pair routines, the computed S-bionomials are not reduced
+// at all. This is done in the appropriate Groebner basis routine
+// (reduced_Groebner_basis_1 or ..._1a) when moving them from the aux_list
+// to the generator lists. This meens that S-binomials cannot only be reduced
+// by the generators known at the time of their computation, but also by
+// the S-pairs that where already treated.
+
+// The advantage of the current routine is that the immediately reduced
+// S-binomial can be used to reduce the ideal itself. This strategy keeps
+// the ideal almost reduced, so the minimalization will be faster.
+// Furthermore, the computation of S-pairs with unreduced generators is
+// avoided.
+// To provide a possibility to compensate the mentionned disadvantage,
+// I have written the routine minimalize_S_pairs() that interreduces the
+// binomials stored in aux_list.
+
+#ifdef NO_SUPPORT_DRIVEN_METHODS_EXTENDED
+
+  list_iterator first_iter(generators);
+
+  Integer first_reduced=0;
+  Integer second_reduced=0;
+  // When reducing the ideal immediately by newly found generators, it
+  // can happen that the binomials referenced by the iterators are
+  // reduced to zero and then deleted. We need to make sure that the
+  // iterators do not reference freed memory in such a case. These two
+  // flags help us with this task.
+
+  while(first_iter.element_is_marked_done()==FALSE)
+    // new generator, compute S-pairs with all following generators
+  {
+    binomial& bin1=first_iter.get_element();
+    first_iter.mark_element_done();
+
+    list_iterator second_iter(first_iter);
+    second_iter.next();
+    // This may be the dummy element.
+
+    while((second_iter.is_at_end()==FALSE) && (first_reduced<=0))
+    {
+      if(unnecessary_S_pair(first_iter,second_iter)==FALSE)
+      {
+        binomial& bin2=second_iter.get_element();
+
+        // compute S-binomial
+        binomial& S_bin=S_binomial(bin1,bin2,w);
+
+        // reduce S-binomial by the actual ideal generators
+        reduce(S_bin,FALSE);
+
+        if(S_bin!=0)
+        {
+          // reduce the ideal generators by the S-binomial
+          first_reduced=bin1.head_reductions_by(S_bin);
+          second_reduced=bin2.head_reductions_by(S_bin);
+          reduce_by(S_bin,first_iter,second_iter);
+          aux_list._insert(S_bin);
+        }
+        else
+          delete &S_bin;
+
+      }
+
+      // Move second_iter to the next element if its referenced binomial
+      // has not changed (if it has changed, the binomial was moved to the
+      // aux_list during the reduce_by(...)-procedure, and second_iter
+      // already references a new binomial).
+      if(second_reduced<=0)
+        second_iter.next();
+      else
+        second_reduced=0;
+
+    }
+
+    // same procedure for first_iter
+    if(first_reduced<=0)
+      first_iter.next();
+    else
+      first_reduced=0;
+  }
+
+#endif  // NO_SUPPORT_DRIVEN_METHODS_EXTENDED
+
+
+#ifdef SUPPORT_DRIVEN_METHODS_EXTENDED
+
+  list_iterator first_iter;
+
+  Integer first_reduced=0;
+  Integer second_reduced=0;
+  // When reducing the ideal immediately by newly found generators, it
+  // can happen that the binomials referenced by the iterators are
+  // changed (including their support!) or even reduced to zero and then
+  // deleted. We need to make sure that the iterators do not reference
+  // freed memory in such a case. These two flags help us with this task.
+
+
+  for(int i=0;i<Number_of_Lists;i++)
+  {
+    first_iter.set_to_list(generators[i]);
+
+    while(first_iter.element_is_marked_done()==FALSE)
+      // new generator, compute S-pairs with all following elements
+    {
+      binomial& bin1=first_iter.get_element();
+      first_iter.mark_element_done();
+
+      list_iterator second_iter(first_iter);
+      second_iter.next();
+
+      // First search over the actual list.
+
+      while((second_iter.is_at_end()==FALSE) && (first_reduced<=0))
+      {
+        if(unnecessary_S_pair(first_iter,second_iter)==FALSE)
+        {
+          binomial& bin2=second_iter.get_element();
+
+          // compute S-binomial
+          binomial& S_bin=S_binomial(bin1,bin2,w);
+
+          // reduce S-binomial by the actual ideal generators
+          reduce(S_bin,FALSE);
+
+          if((S_bin)!=0)
+          {
+            // reduce the ideal generators by the S-binomial
+            first_reduced=bin1.head_reductions_by(S_bin);
+            second_reduced=bin2.head_reductions_by(S_bin);
+            reduce_by(S_bin,first_iter,second_iter);
+            aux_list._insert(S_bin);
+          }
+          else
+            delete &S_bin;
+
+        }
+
+        // Move second_iter to the next element if its referenced binomial
+        // has not changed (if it has changed, the binomial was moved to the
+        // aux_list during the reduce_by(...)-procedure, and second_iter
+        // already references a new binomial).
+        if(second_reduced<=0)
+          second_iter.next();
+        else
+          second_reduced=0;
+
+      }
+
+      // Then search over the remaining lists.
+
+      for(int j=i+1;(j<Number_of_Lists) && (first_reduced<=0);j++)
+      {
+        second_iter.set_to_list(generators[j]);
+
+        while((second_iter.is_at_end()==FALSE) && (first_reduced<=0))
+        {
+          if(unnecessary_S_pair(first_iter,second_iter)==FALSE)
+          {
+            binomial& bin2=second_iter.get_element();
+
+            // compute S-binomial
+            binomial& S_bin=S_binomial(bin1,bin2,w);
+
+            // reduce S-binomial by the actual ideal generators
+            reduce(S_bin,FALSE);
+
+            if((S_bin)!=0)
+            {
+              // reduce the ideal generators by the S-binomial
+              first_reduced=bin1.head_reductions_by(S_bin);
+              second_reduced=bin2.head_reductions_by(S_bin);
+              reduce_by(S_bin,first_iter,second_iter);
+              aux_list._insert(S_bin);
+            }
+            else
+              delete& S_bin;
+
+          }
+
+          // Move second_iter to the next element if its referenced binomial
+          // has not changed.
+          if(second_reduced<=0)
+            second_iter.next();
+          else
+            second_reduced=0;
+        }
+      }
+
+      // same procedure for first_iter
+      if(first_reduced<=0)
+        first_iter.next();
+      else
+        first_reduced=0;
+
+    }
+
+
+    while(first_iter.is_at_end()==FALSE)
+      // old generator, compute only S-pairs with the following new generators
+      // As all generators in the actual list are old ones, we can
+      // start iteration with the next list.
+    {
+      binomial& bin1=first_iter.get_element();
+
+      list_iterator second_iter(first_iter);
+      second_iter.next();
+
+     for(int j=i+1;(j<Number_of_Lists) && (first_reduced<=0);j++)
+      {
+        second_iter.set_to_list(generators[j]);
+
+        while((second_iter.element_is_marked_done()==FALSE) &&
+              (first_reduced<=0))
+          // consider only new generators
+        {
+          if(unnecessary_S_pair(first_iter,second_iter)==FALSE)
+          {
+            binomial& bin2=second_iter.get_element();
+
+            // compute S-binomial
+            binomial& S_bin=S_binomial(bin1,bin2,w);
+
+            // reduce S-binomial by the actual ideal generators
+            reduce(S_bin,FALSE);
+
+            if((S_bin)!=0)
+            {
+              // reduce the ideal generators by the S-binomial
+              first_reduced=bin1.head_reductions_by(S_bin);
+              second_reduced=bin2.head_reductions_by(S_bin);
+              reduce_by(S_bin,first_iter,second_iter);
+              aux_list._insert(S_bin);
+            }
+            else
+              delete& S_bin;
+
+          }
+
+          // Move second_iter to the next element if its referenced binomial
+          // has not changed.
+          if(second_reduced<=0)
+            second_iter.next();
+          else
+            second_reduced=0;
+        }
+      }
+
+      // same procedure for first_iter
+      if(first_reduced<=0)
+        first_iter.next();
+      else
+        first_reduced=0;
+
+    }
+  }
+
+#endif  // SUPPORT_DRIVEN_METHODS_EXTENDED
+
+
+  return(*this);
+}
+
+
+
+
+
+ideal& ideal::compute_actual_S_pairs_3()
+{
+// This routine is quite similar to the preceeding.
+// The main difference is that the computed S-binomials are not stored in the
+// aux_list, but in new_generators. This makes a difference when minimalizing
+// the S-binomials in the appropriate Groebner basis routine
+// (reduced_Groebner_basis_3) with the help of the procedure
+// minimalize_new_generators(...).
+// If NO_SUPPORT_DRIVEN_METHODS_EXTENDED are enabled, only the organization
+// of the minimalization is different.
+// If SUPPORT_DRIVEN_METHODS_EXTENDED are enabled, the minimalization can
+// use the support information.
+
+
+#ifdef NO_SUPPORT_DRIVEN_METHODS_EXTENDED
+
+  list_iterator first_iter(generators);
+
+  Integer first_reduced=0;
+  Integer second_reduced=0;
+  // When reducing the ideal immediately by newly found generators, it
+  // can happen that the binomials referenced by the iterators are
+  // reduced to zero and then deleted. We need to make sure that the
+  // iterators do not reference freed memory in such a case. These two
+  // flags help us with this task.
+
+  while(first_iter.element_is_marked_done()==FALSE)
+    // new generator, compute S-pairs with all following generators
+  {
+    binomial& bin1=first_iter.get_element();
+    first_iter.mark_element_done();
+
+    list_iterator second_iter(first_iter);
+    second_iter.next();
+    // This may be the dummy element.
+
+    while((second_iter.is_at_end()==FALSE) && (first_reduced<=0))
+    {
+      if(unnecessary_S_pair(first_iter,second_iter)==FALSE)
+      {
+        binomial& bin2=second_iter.get_element();
+
+        // compute S-binomial
+        binomial& S_bin=S_binomial(bin1,bin2,w);
+
+        // reduce S-binomial by the actual ideal generators
+        reduce(S_bin,FALSE);
+
+        if(S_bin!=0)
+        {
+          // reduce the ideal generators by the S-binomial
+          first_reduced=bin1.head_reductions_by(S_bin);
+          second_reduced=bin2.head_reductions_by(S_bin);
+          reduce_by(S_bin,first_iter,second_iter);
+          add_new_generator(S_bin);
+        }
+        else
+          delete &S_bin;
+
+      }
+
+      // Move second_iter to the next element if its referenced binomial
+      // has not changed (if it has changed, the binomial was moved to the
+      // aux_list during the reduce_by(...)-procedure, and second_iter
+      // already references a new binomial).
+      if(second_reduced<=0)
+        second_iter.next();
+      else
+        second_reduced=0;
+
+    }
+
+    // same procedure for first_iter
+    if(first_reduced<=0)
+      first_iter.next();
+    else
+      first_reduced=0;
+  }
+
+#endif  // NO_SUPPORT_DRIVEN_METHODS_EXTENDED
+
+
+#ifdef SUPPORT_DRIVEN_METHODS_EXTENDED
+
+  list_iterator first_iter;
+
+  Integer first_reduced=0;
+  Integer second_reduced=0;
+  // When reducing the ideal immediately by newly found generators, it
+  // can happen that the binomials referenced by the iterators are
+  // changed (including their support!) or even reduced to zero and then
+  // deleted. We need to make sure that the iterators do not reference
+  // freed memory in such a case. These two flags help us with this task.
+
+
+  for(int i=0;i<Number_of_Lists;i++)
+  {
+    first_iter.set_to_list(generators[i]);
+
+    while(first_iter.element_is_marked_done()==FALSE)
+      // new generator, compute S-pairs with all following elements
+    {
+      binomial& bin1=first_iter.get_element();
+      first_iter.mark_element_done();
+
+      list_iterator second_iter(first_iter);
+      second_iter.next();
+
+      // First search over the actual list.
+
+      while((second_iter.is_at_end()==FALSE) && (first_reduced<=0))
+      {
+        if(unnecessary_S_pair(first_iter,second_iter)==FALSE)
+        {
+          binomial& bin2=second_iter.get_element();
+
+          // compute S-binomial
+          binomial& S_bin=S_binomial(bin1,bin2,w);
+
+          // reduce S-binomial by the actual ideal generators
+          reduce(S_bin,FALSE);
+
+          if((S_bin)!=0)
+          {
+            // reduce the ideal generators by the S-binomial
+            first_reduced=bin1.head_reductions_by(S_bin);
+            second_reduced=bin2.head_reductions_by(S_bin);
+            reduce_by(S_bin,first_iter,second_iter);
+            add_new_generator(S_bin);
+          }
+          else
+            delete &S_bin;
+
+        }
+
+        // Move second_iter to the next element if its referenced binomial
+        // has not changed (if it has changed, the binomial was moved to the
+        // aux_list during the reduce_by(...)-procedure, and second_iter
+        // already references a new binomial).
+        if(second_reduced<=0)
+          second_iter.next();
+        else
+          second_reduced=0;
+
+      }
+
+      // Then search over the remaining lists.
+
+      for(int j=i+1;(j<Number_of_Lists) && (first_reduced<=0);j++)
+      {
+        second_iter.set_to_list(generators[j]);
+
+        while((second_iter.is_at_end()==FALSE) && (first_reduced<=0))
+        {
+          if(unnecessary_S_pair(first_iter,second_iter)==FALSE)
+          {
+            binomial& bin2=second_iter.get_element();
+
+            // compute S-binomial
+            binomial& S_bin=S_binomial(bin1,bin2,w);
+
+            // reduce S-binomial by the actual ideal generators
+            reduce(S_bin,FALSE);
+
+            if((S_bin)!=0)
+            {
+              // reduce the ideal generators by the S-binomial
+              first_reduced=bin1.head_reductions_by(S_bin);
+              second_reduced=bin2.head_reductions_by(S_bin);
+              reduce_by(S_bin,first_iter,second_iter);
+              add_new_generator(S_bin);
+            }
+            else
+              delete& S_bin;
+
+          }
+
+          // Move second_iter to the next element if its referenced binomial
+          // has not changed.
+          if(second_reduced<=0)
+            second_iter.next();
+          else
+            second_reduced=0;
+        }
+      }
+
+      // same procedure for first_iter
+      if(first_reduced<=0)
+        first_iter.next();
+      else
+        first_reduced=0;
+
+    }
+
+
+    while(first_iter.is_at_end()==FALSE)
+      // old generator, compute only S-pairs with the following new generators
+      // As all generators in the actual list are old ones, we can
+      // start iteration with the next list.
+    {
+      binomial& bin1=first_iter.get_element();
+
+      list_iterator second_iter(first_iter);
+      second_iter.next();
+
+     for(int j=i+1;(j<Number_of_Lists) && (first_reduced<=0);j++)
+      {
+        second_iter.set_to_list(generators[j]);
+
+        while((second_iter.element_is_marked_done()==FALSE) &&
+              (first_reduced<=0))
+          // consider only new generators
+        {
+          if(unnecessary_S_pair(first_iter,second_iter)==FALSE)
+          {
+            binomial& bin2=second_iter.get_element();
+
+            // compute S-binomial
+            binomial& S_bin=S_binomial(bin1,bin2,w);
+
+            // reduce S-binomial by the actual ideal generators
+            reduce(S_bin,FALSE);
+
+            if((S_bin)!=0)
+            {
+              // reduce the ideal generators by the S-binomial
+              first_reduced=bin1.head_reductions_by(S_bin);
+              second_reduced=bin2.head_reductions_by(S_bin);
+              reduce_by(S_bin,first_iter,second_iter);
+              add_new_generator(S_bin);
+            }
+            else
+              delete& S_bin;
+
+          }
+
+          // Move second_iter to the next element if its referenced binomial
+          // has not changed.
+          if(second_reduced<=0)
+            second_iter.next();
+          else
+            second_reduced=0;
+        }
+      }
+
+      // same procedure for first_iter
+      if(first_reduced<=0)
+        first_iter.next();
+      else
+        first_reduced=0;
+
+    }
+  }
+
+#endif  // SUPPORT_DRIVEN_METHODS_EXTENDED
+
+
+  // During the reduce_by(...)-routines, some reduced generators were
+  // perhaps moved to the aux_list. This list is emptied now: Like the
+  // computed S-pairs, its elements are moved to the list(s) new_generators.
+  // To avoid this construction, we would have to write a second version
+  // of the reduce_by(...)-procedure. The efficiency gains would however
+  // not be considerable.
+
+  list_iterator iter(aux_list);
+
+  while(iter.is_at_end()==FALSE)
+  {
+    add_new_generator(iter.get_element());
+    iter.extract_element();
+  }
+
+
+  return(*this);
+}
+
+
+
+
+
+//////////////////////////////////////////////////////////////////////////////
+//////////// minimalization / autoreduction //////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+
+
+
+
+
+ideal& ideal::reduce_by(const binomial& bin, list_iterator& first_iter,
+                        list_iterator& second_iter)
+{
+// This routine reduces the ideal by the argument binomial and takes
+// care that the argument list iterators are not corrupted.
+// Only head reductions are performed.
+
+
+#ifdef NO_SUPPORT_DRIVEN_METHODS_EXTENDED
+
+  list_iterator iter(generators);
+  Integer reduced;
+
+  while(iter.is_at_end()==FALSE)
+  {
+    binomial& actual=iter.get_element();
+
+    // reduce actual binomial by bin
+    reduced=actual.head_reductions_by(bin);
+
+    if(reduced<=0)
+      iter.next();
+
+    else
+      // the actual binomial has changed and will be removed or
+      // moved to the aux_list
+    {
+
+#ifdef SL_LIST
+
+      // If we use a simply linked list, we have to take care of the
+      // following binomial.
+      if(iter.next_is(first_iter)==TRUE)
+        first_iter=iter;
+      if(iter.next_is(second_iter)==TRUE)
+        second_iter=iter;
+
+#endif  // SL_LIST
+
+
+#ifdef DL_LIST
+
+      // If we use a doubly linked list, we have to take care of the
+      // binomial itself.
+      if(iter==first_iter)
+        first_iter.next();
+      if(iter==second_iter)
+        second_iter.next();
+
+#endif  // DL_LIST
+
+
+      // move changed generator to the aux_list or delete it
+      if(actual==0)
+        iter.delete_element();
+      else
+      {
+        aux_list._insert(actual);
+        iter.extract_element();
+      }
+
+      size--;
+    }
+  }
+
+#endif  // NO_SUPPORT_DRIVEN_METHOD_EXTENDED
+
+
+#ifdef SUPPORT_DRIVEN_METHODS_EXTENDED
+
+  int supp1=(first_iter.get_element()).head_support%Number_of_Lists;
+  int supp2=(second_iter.get_element()).head_support%Number_of_Lists;
+
+  // Determine the lists over which we have to iterate.
+  // These are the lists with elements whose support contains the support
+  // of bin.
+  // List i has to be checked iff the set of bits in i that are 1 contains
+  // the set of bits in supp that are 1.
+  // Equivalent: List i has to be checked iff the set of bits in i
+  // that are 0 is contained in the set of bits of supp that are 0.
+  // With this formulation, we can use the subset tree as follows:
+
+  int supp=bin.head_support%Number_of_Lists;
+  int inv_supp=Number_of_Lists-supp-1;
+  // This bit vector is the bitwise inverse of bin.head_support (restricted
+  // to the variables considered in the list indices.
+
+  list_iterator iter;
+  Integer reduced;
+
+
+  for(int i=0;i<S.number_of_subsets[inv_supp];i++)
+  {
+    int actual_list=Number_of_Lists-S.subsets_of_support[inv_supp][i]-1;
+    // the actual list for iteration
+    // The support of S.subsets_of_support[inv_supp][i] as a bit vector
+    // is contained in that of inv_supp.
+    // I.e. the support of
+    // Number_of_Lists-S.subsets_of_support[inv_supp][i]-1
+    // - which is the bitwise inverse of S.subsets_of_support[inv_supp][i] -
+    // contains the support of the bitwise inverse of inv_supp, hence the
+    // support of supp.
+
+    if((actual_list==supp1) || (actual_list==supp2))
+      // The lists referenced by first_iter and second_iter are tested
+      // separately to avoid unnecessary checks.
+      continue;
+
+    iter.set_to_list(generators[actual_list]);
+
+    while(iter.is_at_end()==FALSE)
+    {
+      binomial& actual=iter.get_element();
+
+      // reduce actual binomial by bin
+      reduced=actual.head_reductions_by(bin);
+
+      if(reduced<=0)
+        iter.next();
+
+      else
+        // the actual binomial has changed and will be removed or
+      {
+        if(actual==0)
+          iter.delete_element();
+
+        else
+        {
+          aux_list._insert(actual);
+          iter.extract_element();
+        }
+
+        size--;
+      }
+    }
+  }
+
+  // Now test the lists referenced by first_iter and second_iter.
+
+  if(supp1==supp2)
+    // first_iter and second_iter reference the same list
+  {
+    if((supp1|supp)==supp1)
+      // support of bin contained in that of the element referenced by
+      // first_iter, else this list has not to be tested
+    {
+      iter.set_to_list(generators[supp1]);
+
+      while(iter.is_at_end()==FALSE)
+      {
+        binomial& actual=iter.get_element();
+        reduced=actual.head_reductions_by(bin);
+        if(reduced<=0)
+          iter.next();
+        else
+        {
+
+#ifdef SL_LIST
+
+          if(iter.next_is(first_iter)==TRUE)
+            first_iter=iter;
+          if(iter.next_is(second_iter)==TRUE)
+            second_iter=iter;
+
+#endif  // SL_LIST
+
+#ifdef DL_LIST
+
+          if(iter==first_iter)
+            first_iter.next();
+          if(iter==second_iter)
+            second_iter.next();
+
+#endif  // DL_LIST
+
+          if(actual==0)
+            iter.delete_element();
+          else
+          {
+            aux_list._insert(actual);
+            iter.extract_element();
+          }
+
+          size--;
+        }
+      }
+    }
+  }
+
+  else
+    // first_iter and second_iter reference different lists
+  {
+    if((supp1|supp)==supp1)
+      // support of bin contained in that of the element referenced by
+      // first_iter, else this list has not to be tested
+    {
+      iter.set_to_list(generators[supp1]);
+
+      while(iter.is_at_end()==FALSE)
+      {
+        binomial& actual=iter.get_element();
+        reduced=actual.head_reductions_by(bin);
+        if(reduced<=0)
+          iter.next();
+        else
+        {
+
+#ifdef SL_LIST
+
+          if(iter.next_is(first_iter)==TRUE)
+            first_iter=iter;
+
+#endif  // SL_LIST
+
+#ifdef DL_LIST
+
+          if(iter==first_iter)
+            first_iter.next();
+
+#endif  // DL_LIST
+
+          if(actual==0)
+            iter.delete_element();
+          else
+          {
+            aux_list._insert(actual);
+            iter.extract_element();
+          }
+
+          size--;
+        }
+      }
+    }
+
+    if((supp2|supp)==supp2)
+      // support of bin contained in that of the element referenced by
+      // second_iter, else this list has not to be tested
+    {
+      iter.set_to_list(generators[supp2]);
+
+      while(iter.is_at_end()==FALSE)
+      {
+        binomial& actual=iter.get_element();
+        reduced=actual.head_reductions_by(bin);
+        if(reduced<=0)
+          iter.next();
+        else
+        {
+
+#ifdef SL_LIST
+
+          if(iter.next_is(second_iter)==TRUE)
+            second_iter=iter;
+
+#endif  // SL_LIST
+
+#ifdef DL_LIST
+
+          if(iter==second_iter)
+            second_iter.next();
+
+#endif  // DL_LIST
+
+          if(actual==0)
+            iter.delete_element();
+          else
+          {
+            aux_list._insert(actual);
+            iter.extract_element();
+          }
+
+          size--;
+        }
+      }
+    }
+  }
+
+#endif
+
+  return *this;
+
+}
+
+
+
+
+
+ideal& ideal::minimalize_S_pairs()
+{
+// This routine implements a very simple minimalization method. We iterate
+// over the S-pair lists with two iterators, interreducing the two referenced
+// binomials. Remember that the S-pair list does not use the "head_reduced"-
+// flags. The iteration is repeated as long as some interreduction is done.
+
+  list_iterator first_iter;
+  int found;
+  // to control if a reduction has occurred during the actual iteration
+
+  do
+  {
+
+    first_iter.set_to_list(aux_list);
+    found=0;
+    // no reduction occured yet
+
+    while(first_iter.is_at_end()==FALSE)
+    {
+
+      binomial& bin1=first_iter.get_element();
+      int first_changed=0;
+      // to control if the first element has been reduced
+
+      // look at all following binomials
+      list_iterator second_iter(first_iter);
+      second_iter.next();
+      // this may be the dummy element
+
+      while(second_iter.is_at_end()==FALSE)
+      {
+        binomial& bin2=second_iter.get_element();
+        int second_changed=0;
+
+        if(bin1.reduce_head_by(bin2,w)!=0)
+          // head of first binomial can be reduced by second
+        {
+
+          if(bin1!=0)
+            found=1;
+            // found has not to be set if a binomial is reduced to zero
+            // (then there are no new binomials)
+
+          else
+            // the binomial referenced by bin1 is zero
+          {
+
+#ifdef SL_LIST
+
+            if(first_iter.next_is(second_iter))
+              second_iter.next();
+
+#endif  // SL_LIST
+
+            first_iter.delete_element();
+            first_changed=1;
+          }
+
+          break;
+          // Breaks the while-loop.
+          // As the element referenced by first_iter has changed,
+          // the iteration with the second iterator can be restarted.
+          // (We try to reduce as many elements as possible in one iteration.)
+        }
+
+
+        if(bin2.reduce_head_by(bin1,w)!=0)
+           // head of second binomial can be reduced by first
+        {
+
+          if(bin2!=0)
+            found=1;
+            // found has not to be set if a binomial is reduced to zero
+            // (then there are no new binomials)
+
+          else
+            // binomial referenced by bin2 is zero
+          {
+            second_iter.delete_element();
+            second_changed=1;
+          }
+
+          // As the second iterator always references an element coming
+          // after first_iter's element in the generator list, we do not
+          // pay attention to the deletion...
+        }
+
+        if(second_changed==0)
+          second_iter.next();
+      }
+
+
+      // Now second_iter has reached the end of the generator list or the
+      // element referenced by first_iter has been reduced...The iteration
+      // is continued with a new (or changed) first binomial.
+
+      if(first_changed==0)
+        first_iter.next();
+    }
+
+ }
+  while(found==1);
+
+  // When leaving the loop, no generators have been interreduced during
+  // the last iteration.
+
+  return *this;
+}
+
+
+
+
+
+ideal& ideal::minimalize_new_generators()
+{
+// This routine is very similar to the following one, minimalize().
+// The only difference is that we interreduce the elements stored in
+// new_generators instead of those stored in generators.
+// The size of the ideal has not to be manipulated hereby.
+
+
+#ifdef NO_SUPPORT_DRIVEN_METHODS_EXTENDED
+
+  list_iterator first_iter;
+  int found;
+  // to control if a reduction has occurred during the actual iteration
+
+  do
+  {
+    first_iter.set_to_list(new_generators);
+    found=0;
+    // no reduction occured yet
+
+    while(first_iter.element_is_marked_head_reduced()==FALSE)
+      // only the first element is tested for this flag
+      // the second may be an old one
+    {
+      binomial& bin1=first_iter.get_element();
+      int first_changed=0;
+      // to control if the first element has been reduced
+
+      // look at all following binomials
+      list_iterator second_iter(first_iter);
+      second_iter.next();
+      // this may be the dummy element
+
+      while(second_iter.is_at_end()==FALSE)
+      {
+        binomial& bin2=second_iter.get_element();
+
+        if(bin1.reduce_head_by(bin2,w)!=0)
+          // head of first binomial can be reduced by second
+        {
+
+#ifdef SL_LIST
+
+          // The binomial referenced by first_iter will be deleted or
+          // extracted. When using a simply linked list, this also affects
+          // the following element. We need to assure that this element does
+          // not reference freed memory.
+          if(first_iter.next_is(second_iter))
+              second_iter.next();
+
+#endif  // SL_LIST
+
+          if(bin1!=0)
+          {
+            found=1;
+            // found has not to be set if a binomial is reduced to zero
+            // (then there are no new binomials to insert)
+
+            aux_list._insert(bin1);
+            first_iter.extract_element();
+            // moved changed binomial to aux_list
+          }
+
+          else
+            first_iter.delete_element();
+
+
+          first_changed=1;
+          break;
+          // As the binomial referenced by first_iter has changed,
+          // the iteration with the second iterator can be restarted.
+          // (We try to reduce as many elements as possible in one iteration.)
+        }
+
+
+        if(bin2.reduce_head_by(bin1,w)!=0)
+           // head of second binomial can be reduced by first
+        {
+          // Here we do not have to pay attention to the deletion or the
+          // extraction of the element referenced by second_iter because
+          // the element referenced by second_iter always comes after the
+          // element referenced by first_iter in new_generators.
+
+          if(bin2!=0)
+          {
+            found=1;
+            // found has not to be set if a binomial is reduced to zero
+            // (then there are no new binomials to insert)
+
+            aux_list._insert(bin2);
+            second_iter.extract_element();
+            // move the element referenced by second_iter to aux_list
+          }
+
+          else
+            second_iter.delete_element();
+
+          // Here it makes not sense to restart iteration because the
+          // deletion sets the pointers as desired.
+        }
+
+        else
+          // no reduction possible
+          second_iter.next();
+
+      }
+
+      // Now second_iter has reached the end of the list new_generators or the
+      // binomial referenced first_iter has been reduced...The iteration
+      // is continued with a new (or changed) first binomial.
+
+      if(first_changed==0)
+        first_iter.next();
+    }
+
+
+    // Now we have found all currently possible reductions.
+    // The elements remaining in new_generators cannot be interreduced
+    // and are marked head_reduced.
+
+    first_iter.set_to_list(new_generators);
+    //   if(first_iter.is_at_end()==FALSE)
+      while(first_iter.element_is_marked_head_reduced()==FALSE)
+      {
+        first_iter.mark_element_head_reduced();
+        first_iter.next();
+      }
+
+
+    // Now reinsert reduced elements.
+
+    first_iter.set_to_list(aux_list);
+
+    while(first_iter.is_at_end()==FALSE)
+    {
+      binomial& bin=first_iter.get_element();
+
+      reduce(bin,FALSE);
+      // The binomial was only reduced by one other binomial before it was
+      // moved to aux_list. To reduce it by all other binomials now can
+      // diminish the number of iterations (do-while-loop).
+
+      if(bin==0)
+        first_iter.delete_element();
+      else
+      {
+        add_new_generator(bin);
+        first_iter.extract_element();
+      }
+
+    }
+
+  }
+  while(found==1);
+
+  // When leaving the loop, no generators have been interreduced during
+  // the last iteration; we are done.
+
+#endif  // NO_SUPPORT_DRIVEN_METHODS_EXTENDED
+
+
+#ifdef SUPPORT_DRIVEN_METHODS_EXTENDED
+
+  list_iterator first_iter;
+  list_iterator second_iter;
+  int found;
+  // to control if a reduction has occurred during the actual iteration
+
+  do
+  {
+    found=0;
+    // no reduction occurred yet
+
+    for(int i=0;i<Number_of_Lists;i++)
+    {
+      first_iter.set_to_list(new_generators[i]);
+
+// First try to reduce the binomials that are marked unreduced.
+
+      while(first_iter.element_is_marked_head_reduced()==FALSE)
+        // all other elements have to be tested for interreduction
+      {
+
+        binomial& bin=first_iter.get_element();
+        Integer changed=0;
+        // binomial referenced by bin not yet reduced
+
+// Look for head reductions:
+// Iterate over the lists that could contain reducers for the head of bin.
+// The list containing bin is tested separately to avoid an interreduction
+// of a binomial by itself respectively unnecessary checks for this when the
+// two iterators reference different lists.
+
+        for(int j=0;(j<S.number_of_subsets[i]-1)&&(changed==0);j++)
+        {
+          second_iter.set_to_list(new_generators[S.subsets_of_support[i][j]]);
+          // This is the j-th list among the new_generator lists with elements
+          // whose support is a subset of that of i.
+          // The support of i is just the head support of bin (restricted
+          // to the corresponding variables).
+
+          while((second_iter.is_at_end()==FALSE)&&(changed==0))
+          {
+            changed=bin.reduce_head_by(second_iter.get_element(),w);
+
+            if(changed!=0)
+              // bin has been reduced
+            {
+              if(bin!=0)
+              {
+                found=1;
+                // found has only to be set if the binomial has not been
+                // reduced to zero (else there are no new binomials)
+
+                aux_list._insert(bin);
+                first_iter.extract_element();
+              }
+              else
+                first_iter.delete_element();
+            }
+            second_iter.next();
+          }
+        }
+
+        // The list new_generators[i]
+        // =new_generators[S.subsets_of_support[i][S.number_of_subsets[i]-1]]
+        // has to be tested separately to avoid a reduction of the actual
+        // binomial by itself.
+
+        if(changed==0)
+          // binomial referenced by first_iter has not yet been reduced
+        {
+          second_iter.set_to_list(new_generators[i]);
+
+          while((second_iter.is_at_end()==FALSE) && (changed==0))
+          {
+            if(second_iter!=first_iter)
+              // the two iterators do not reference the same element
+              changed=bin.reduce_head_by(second_iter.get_element(),w);
+
+            if(changed!=0)
+              // bin has been reduced
+            {
+
+#ifdef SL_LIST
+
+              // bin will be deleted ar extracted - maybe dangerous for
+              // second_iter
+              if(first_iter.next_is(second_iter))
+                second_iter.next();
+
+#endif  // SL_LIST
+
+              if(bin!=0)
+              {
+                found=1;
+                aux_list._insert(bin);
+                first_iter.extract_element();
+              }
+              else
+                first_iter.delete_element();
+            }
+
+            else
+              // bin has not been reduced
+              second_iter.next();
+          }
+        }
+
+      if(changed==0)
+        first_iter.next();
+      // Else first_iter has already been set to the next element by deletion
+      // or extraction.
+      }
+
+
+//  Now try to reduce the binomials that are marked reduced.
+
+      while(first_iter.is_at_end()==FALSE)
+        // only unreduced elements have to be tested for interreduction
+      {
+        binomial& bin=first_iter.get_element();
+        Integer changed=0;
+        // binomial referenced by bin not yet reduced
+
+// Look for head reductions:
+// Iterate over the lists that could contain reducers for the head of bin.
+// The list containing bin is tested separately to avoid an interreduction
+// of a binomial by itself respectively unnecessary checks for this when the
+// two iterators reference different lists.
+
+        for(int j=0;(j<S.number_of_subsets[i]-1)&&(changed==0);j++)
+        {
+          second_iter.set_to_list(new_generators[S.subsets_of_support[i][j]]);
+          // This is the j-th list among the new_generators lists with elements
+          // whose support is a subset of that of i.
+          // The support of i is just the head support of bin (restricted
+          // to the corresponding variables).
+
+          while((second_iter.element_is_marked_head_reduced()==FALSE) &&
+                (changed==0))
+          {
+            changed=bin.reduce_head_by(second_iter.get_element(),w);
+
+            if(changed!=0)
+              // bin has been reduced
+            {
+              if(bin!=0)
+              {
+                found=1;
+                // found has only to be set if the binomial has not been
+                // reduced to zero (else there are no new binomials)
+                aux_list._insert(bin);
+                first_iter.extract_element();
+              }
+              else
+                first_iter.delete_element();
+            }
+            second_iter.next();
+          }
+        }
+
+        // The list new_generators[i]
+        // =new_generators[S.subsets_of_support[i][S.number_of_subsets[i]-1]]
+        // has to be tested separately to avoid a reduction of the actual
+        // binomial by itself.
+
+        if(changed==0)
+          // binomial referenced by first_iter has not yet been reduced
+        {
+          second_iter.set_to_list(new_generators[i]);
+
+          while((second_iter.element_is_marked_head_reduced()==FALSE) &&
+                (changed==0))
+          {
+            if(second_iter!=first_iter)
+              // the two iterators do not reference the same element
+              changed=bin.reduce_head_by(second_iter.get_element(),w);
+
+            if(changed!=0)
+              // bin has been reduced
+            {
+
+#ifdef SL_LIST
+
+              // bin will be deleted ar extracted - maybe dangerous for
+              // second_iter
+              if(first_iter.next_is(second_iter))
+                second_iter.next();
+
+#endif  // SL_LIST
+
+              if(bin!=0)
+              {
+                found=1;
+                aux_list._insert(bin);
+                first_iter.extract_element();
+              }
+              else
+                first_iter.delete_element();
+            }
+
+            else
+              // bin has not been reduced
+              second_iter.next();
+          }
+        }
+
+      if(changed==0)
+        first_iter.next();
+      // Else first_iter has already been set to the next element by deletion
+      // or extraction.
+      }
+
+    }
+
+
+    // Now we have found all currently possible reductions.
+    // The elements remaining in the new_generator lists cannot be interreduced
+    // and are marked reduced.
+
+    for(int i=0;i<Number_of_Lists;i++)
+    {
+      first_iter.set_to_list(new_generators[i]);
+      if(first_iter.is_at_end()==FALSE)
+        while(first_iter.element_is_marked_head_reduced()==FALSE)
+        {
+          first_iter.mark_element_head_reduced();
+          first_iter.next();
+        }
+    }
+
+
+    // Now reinsert reduced elements
+    // It seems to be quite unimportant for the performance if an element is
+    // completely reduced before reinsertion or not.
+
+    first_iter.set_to_list(aux_list);
+    while(first_iter.is_at_end()==FALSE)
+    {
+      binomial& bin=first_iter.get_element();
+      reduce(bin,FALSE);
+
+      if(bin==0)
+        first_iter.delete_element();
+      else
+      {
+        add_new_generator(bin);
+        first_iter.extract_element();
+      }
+    }
+
+  }
+  while(found==1);
+
+  // When leaving the loop, no generators have been interreduced during
+  // the last iteration; we are done.
+
+#endif  // SUPPORT_DRIVEN_METHODS_EXTENDED
+
+
+  return(*this);
+
+}
+
+
+
+
+
+ideal& ideal::minimalize()
+{
+// For a better overview, the code for NO_SUPPORT_DRIVEN_METHODS_EXTENDED
+// and SUPPORT_DRIVEN_METHODS_EXTENDED is completetly separated in this
+// function. Note that th iteration methods are quite different for those
+// two possibilities.
+
+
+#ifdef NO_SUPPORT_DRIVEN_METHODS_EXTENDED
+
+// For technical simplicity, the interreduction is done as follows:
+// We iterate over the generators with two iterators.
+// For each binomial pair, we examine if one binomial�s head can be
+// reduced by the other. If this is the case, the reducible binomial is
+// reduced and moved to the aux_list if it is not 0, else deleted.
+// After one iteration, the elements of the aux_list are reinserted;
+// then the interreduction is restarted until no new elements are found.
+
+// The above method of deleting and inserting is chosen for the following
+// reasons:
+// - The order undone elements - done elements in the generator lists
+//   is not destroyed. Newly found elements are automatically marked
+//   undone when they are reinserted.
+//   The S-pair computation can as usually make use of this fact.
+// - In analogy, the order head_unreduced elements - head_reduced elements
+//   is not destroyed. Remark that an undone element can never be reduced, as
+//   reduction is only done after an S-pair computation. Newly found
+//   elements are automatically marked unreduced. With the "head_reduced"-
+//   flag we make sure that any binomial pair is tested only once for
+//   interreduction during the whole algorithm.
+
+  list_iterator first_iter;
+  int found;
+  // to control if a reduction has occurred during the actual iteration
+
+  do
+  {
+    first_iter.set_to_list(generators);
+    found=0;
+    // no reduction occured yet
+
+    while(first_iter.element_is_marked_head_reduced()==FALSE)
+      // only the first element is tested for this flag
+      // the second may be an old one
+    {
+      binomial& bin1=first_iter.get_element();
+      int first_changed=0;
+      // to control if the first element has been reduced
+
+      // look at all following binomials
+      list_iterator second_iter(first_iter);
+      second_iter.next();
+      // this may be the dummy element
+
+      while(second_iter.is_at_end()==FALSE)
+      {
+        binomial& bin2=second_iter.get_element();
+
+        if(bin1.reduce_head_by(bin2,w)!=0)
+          // head of first binomial can be reduced by second
+        {
+
+#ifdef SL_LIST
+
+          // The binomial referenced by first_iter will be deleted or
+          // extracted. When using a simply linked list, this also affects
+          // the following element. We need to assure that this element does
+          // not reference freed memory.
+          if(first_iter.next_is(second_iter))
+              second_iter.next();
+
+#endif  // SL_LIST
+
+          if(bin1!=0)
+          {
+            found=1;
+            // found has not to be set if a binomial is reduced to zero
+            // (then there are no new binomials to insert)
+
+            aux_list._insert(bin1);
+            first_iter.extract_element();
+            // moved changed binomial to aux_list
+          }
+
+          else
+            first_iter.delete_element();
+
+
+          first_changed=1;
+          size--;
+          break;
+          // As the binomial referenced by first_iter has changed,
+          // the iteration with the second iterator can be restarted.
+          // (We try to reduce as many elements as possible in one iteration.)
+        }
+
+
+        if(bin2.reduce_head_by(bin1,w)!=0)
+           // head of second binomial can be reduced by first
+        {
+          // Here we do not have to pay attention to the deletion or the
+          // extraction of the element referenced by second_iter because
+          // the element referenced by second_iter always comes after the
+          // element referenced by first_iter in the generator list.
+
+          if(bin2!=0)
+          {
+            found=1;
+            // found has not to be set if a binomial is reduced to zero
+            // (then there are no new binomials to insert)
+
+            aux_list._insert(bin2);
+            second_iter.extract_element();
+            // move the element referenced by second_iter to aux_list
+          }
+
+          else
+            second_iter.delete_element();
+
+          size--;
+          // Here it makes not sense to restart iteration because the
+          // deletion sets the pointers as desired.
+        }
+
+        else
+          // no reduction possible
+          second_iter.next();
+
+      }
+
+      // Now second_iter has reached the end of the generator list or the
+      // binomial referenced first_iter has been reduced...The iteration
+      // is continued with a new (or changed) first binomial.
+
+      if(first_changed==0)
+        first_iter.next();
+    }
+
+
+    // Now we have found all currently possible reductions.
+    // The elements remaining in the generator list cannot be interreduced
+    // and are marked head_reduced.
+
+    first_iter.set_to_list(generators);
+    //   if(first_iter.is_at_end()==FALSE)
+      while(first_iter.element_is_marked_head_reduced()==FALSE)
+      {
+        first_iter.mark_element_head_reduced();
+        first_iter.next();
+      }
+
+
+    // Now reinsert reduced elements.
+
+    first_iter.set_to_list(aux_list);
+
+    while(first_iter.is_at_end()==FALSE)
+    {
+      binomial& bin=first_iter.get_element();
+
+      reduce(bin,FALSE);
+      // The binomial was only reduced by one other generator before it was
+      // moved to aux_list. To reduce it by all other generators now can
+      // diminish the number of iterations (do-while-loop).
+
+      if(bin==0)
+        first_iter.delete_element();
+      else
+      {
+        generators.insert(bin);
+        // We do not call the add_generator(...)-routine because we do not
+        // want number_of_new_binomials to be incremented.
+        size++;
+        first_iter.extract_element();
+      }
+
+    }
+
+  }
+  while(found==1);
+
+  // When leaving the loop, no generators have been interreduced during
+  // the last iteration; we are done.
+
+#endif  // NO_SUPPORT_DRIVEN_METHODS_EXTENDED
+
+
+#ifdef SUPPORT_DRIVEN_METHODS_EXTENDED
+
+// In this case, the reduction has to be organized in a different way to
+// use the support information to its full extend. Without the support
+// methods, we test interreduction symmetrically: if we have a pair of
+// generators, we test if generator 1 can be reduced by generator 2 AND
+// if generator 2 can be reduced by generator 1. So each unordered pair is
+// considered only once.
+// If we would implement the same for the support methods, the second head
+// reduction could not use the support information.
+// For this reason, we test ordered pairs: For a given generator, we
+// try to reduce his head by all other generators, considering its head
+// support vector.
+
+// The method of moving changed binomials to aux_list and later reinserting
+// them is kept. When using SUPPORT_DRIVEN_METHODS_EXTENDED, it is even
+// necessary to choose such a method because the head support of some
+// binomials may change, too, a fact that requires the list structure to be
+// rebuilt.
+
+  list_iterator first_iter;
+  list_iterator second_iter;
+  int found;
+  // to control if a reduction has occurred during the actual iteration
+
+  do
+  {
+    found=0;
+    // no reduction occurred yet
+
+    for(int i=0;i<Number_of_Lists;i++)
+    {
+      first_iter.set_to_list(generators[i]);
+
+// First try to reduce the binomials that are marked unreduced.
+
+      while(first_iter.element_is_marked_head_reduced()==FALSE)
+        // all other elements have to be tested for interreduction
+      {
+
+        binomial& bin=first_iter.get_element();
+        Integer changed=0;
+        // binomial referenced by bin not yet reduced
+
+// Look for head reductions:
+// Iterate over the lists that could contain reducers for the head of bin.
+// The list containing bin is tested separately to avoid an interreduction
+// of a binomial by itself respectively unnecessary checks for this when the
+// two iterators reference different lists.
+
+        for(int j=0;(j<S.number_of_subsets[i]-1)&&(changed==0);j++)
+        {
+          second_iter.set_to_list(generators[S.subsets_of_support[i][j]]);
+          // This is the j-th list among the generator lists with elements
+          // whose support is a subset of that of i.
+          // The support of i is just the head support of bin (restricted
+          // to the corresponding variables).
+
+          while((second_iter.is_at_end()==FALSE)&&(changed==0))
+          {
+            changed=bin.reduce_head_by(second_iter.get_element(),w);
+
+            if(changed!=0)
+              // bin has been reduced
+            {
+              if(bin!=0)
+              {
+                found=1;
+                // found has only to be set if the binomial has not been
+                // reduced to zero (else there are no new binomials)
+
+                aux_list._insert(bin);
+                first_iter.extract_element();
+              }
+              else
+                first_iter.delete_element();
+
+              size--;
+            }
+            second_iter.next();
+          }
+        }
+
+        // The list generators[i]
+        // =generators[S.subsets_of_support[i][S.number_of_subsets[i]-1]]
+        // has to be tested separately to avoid a reduction of the actual
+        // binomial by itself.
+
+        if(changed==0)
+          // binomial referenced by first_iter has not yet been reduced
+        {
+          second_iter.set_to_list(generators[i]);
+
+          while((second_iter.is_at_end()==FALSE) && (changed==0))
+          {
+            if(second_iter!=first_iter)
+              // the two iterators do not reference the same element
+              changed=bin.reduce_head_by(second_iter.get_element(),w);
+
+            if(changed!=0)
+              // bin has been reduced
+            {
+
+#ifdef SL_LIST
+
+              // bin will be deleted ar extracted - maybe dangerous for
+              // second_iter
+              if(first_iter.next_is(second_iter))
+                second_iter.next();
+
+#endif  // SL_LIST
+
+              if(bin!=0)
+              {
+                found=1;
+                aux_list._insert(bin);
+                first_iter.extract_element();
+              }
+              else
+                first_iter.delete_element();
+
+              size--;
+            }
+
+            else
+              // bin has not been reduced
+              second_iter.next();
+          }
+        }
+
+      if(changed==0)
+        first_iter.next();
+      // Else first_iter has already been set to the next element by deletion
+      // or extraction.
+      }
+
+
+//  Now try to reduce the binomials that are marked reduced.
+
+      while(first_iter.is_at_end()==FALSE)
+        // only unreduced elements have to be tested for interreduction
+      {
+        binomial& bin=first_iter.get_element();
+        Integer changed=0;
+        // binomial referenced by bin not yet reduced
+
+// Look for head reductions:
+// Iterate over the lists that could contain reducers for the head of bin.
+// The list containing bin is tested separately to avoid an interreduction
+// of a binomial by itself respectively unnecessary checks for this when the
+// two iterators reference different lists.
+
+        for(int j=0;(j<S.number_of_subsets[i]-1)&&(changed==0);j++)
+        {
+          second_iter.set_to_list(generators[S.subsets_of_support[i][j]]);
+          // This is the j-th list among the generator lists with elements
+          // whose support is a subset of that of i.
+          // The support of i is just the head support of bin (restricted
+          // to the corresponding variables).
+
+          while((second_iter.element_is_marked_head_reduced()==FALSE) &&
+                (changed==0))
+          {
+            changed=bin.reduce_head_by(second_iter.get_element(),w);
+
+            if(changed!=0)
+              // bin has been reduced
+            {
+              if(bin!=0)
+              {
+                found=1;
+                // found has only to be set if the binomial has not been
+                // reduced to zero (else there are no new binomials)
+                aux_list._insert(bin);
+                first_iter.extract_element();
+              }
+              else
+                first_iter.delete_element();
+
+              size--;
+            }
+            second_iter.next();
+          }
+        }
+
+        // The list generators[i]
+        // =generators[S.subsets_of_support[i][S.number_of_subsets[i]-1]]
+        // has to be tested separately to avoid a reduction of the actual
+        // binomial by itself.
+
+        if(changed==0)
+          // binomial referenced by first_iter has not yet been reduced
+        {
+          second_iter.set_to_list(generators[i]);
+
+          while((second_iter.element_is_marked_head_reduced()==FALSE) &&
+                (changed==0))
+          {
+            if(second_iter!=first_iter)
+              // the two iterators do not reference the same element
+              changed=bin.reduce_head_by(second_iter.get_element(),w);
+
+            if(changed!=0)
+              // bin has been reduced
+            {
+
+#ifdef SL_LIST
+
+              // bin will be deleted ar extracted - maybe dangerous for
+              // second_iter
+              if(first_iter.next_is(second_iter))
+                second_iter.next();
+
+#endif  // SL_LIST
+
+              if(bin!=0)
+              {
+                found=1;
+                aux_list._insert(bin);
+                first_iter.extract_element();
+              }
+              else
+                first_iter.delete_element();
+
+              size--;
+            }
+
+            else
+              // bin has not been reduced
+              second_iter.next();
+          }
+        }
+
+      if(changed==0)
+        first_iter.next();
+      // Else first_iter has already been set to the next element by deletion
+      // or extraction.
+      }
+
+    }
+
+
+    // Now we have found all currently possible reductions.
+    // The elements remaining in the generator lists cannot be interreduced
+    // and are marked reduced.
+
+    for(int i=0;i<Number_of_Lists;i++)
+    {
+      first_iter.set_to_list(generators[i]);
+      if(first_iter.is_at_end()==FALSE)
+        while(first_iter.element_is_marked_head_reduced()==FALSE)
+        {
+          first_iter.mark_element_head_reduced();
+          first_iter.next();
+        }
+    }
+
+
+    // Now reinsert reduced elements
+    // It seems to be quite unimportant for the performance if an element is
+    // completely reduced before reinsertion or not.
+
+    first_iter.set_to_list(aux_list);
+    while(first_iter.is_at_end()==FALSE)
+    {
+      binomial& bin=first_iter.get_element();
+      reduce(bin,FALSE);
+
+      if(bin==0)
+        first_iter.delete_element();
+      else
+      {
+        generators[bin.head_support%Number_of_Lists].insert(bin);
+        size++;
+        // We do not call the add_generator(...)-routine because we do not
+        // want number_of_new_binomials to be incremented.
+        first_iter.extract_element();
+      }
+    }
+
+  }
+  while(found==1);
+
+  // When leaving the loop, no generators have been interreduced during
+  // the last iteration; we are done.
+
+#endif  // SUPPORT_DRIVEN_METHODS_EXTENDED
+
+
+  return(*this);
+}
+
+
+
+
+
+ideal& ideal::final_reduce()
+{
+// During Buchberger�s algorithm, we perform only head reductions
+// (minimalizations). This strategy showed to be a little more efficient
+// than the strategy to do reduce the ideal always completely.
+// This method leads to a minimal, but in general not to the reduced Groebner
+// basis. The actual procedure reduces such a minimal basis at the end of
+// Buchberger�s algorithm. It will probably cause problems when called
+// in the course of the algorithm. For an explaination of this fact, see
+// the following comment.
+
+  minimalize();
+
+// Now there remain only tail reductions. They are quite simple: Each
+// binomial's tail is reduced as long as possible. As no binomial can be
+// reduced to zero by that and a binomial cannot reduce its own tail,
+// we do not have to pay special attention to that (under the assumption
+// that a real term ordering (i.e. a well-ordering) is used and that
+// the head and the tail of the binomial are coorect with respect to this
+// ordering).
+
+// Notice that the head can change because of a tail reduction due to the
+// trivial factors elimination (the new head will always divide the
+// old one). This change is especially dangerous if
+// SUPPORT_DRIVEN_METHODS_EXTENDED are enabled: It may happen that the
+// binomial is in the wrong list after a tail reduction.
+// Furthermore, if a head change occurs, it may happen that the generating
+// set is no more minimalized after this. So the reduction has to be restarted
+// after such a head change (and the respective binomial has to be marked
+// head_unreduced before).
+// This does not seem to be very efficient.
+
+// For this reason, the reduction routine is only written for a final
+// reduction (having already computed a Groebner basis of the ideal).
+// This Groebner basis is first minimalized. After that, a head change during
+// tail reduction is impossible because the head is already a minimal
+// generator of the initial ideal (and the new head would divide the old).
+
+// However, this argumentation is only valid if the input ideal is saturated.
+// In some algorithms (Hosten_Sturmfels...) this is not the case in
+// intermediate steps. The final reduction may cause inconsistencies here.
+// But as the list structure is rebuild after each intermediate Groebner
+// basis calculation (change of the term ordering) and as the last Groebner
+// basis calculation deals with a saturated ideal, the final result will be
+// correct.
+// (For non-saturated input ideals, the computed Groebner basis is in general
+// not a Groebner basis of the input ideal, but one for an ideal "between"
+// the input ideal and its saturation.)
+
+
+#ifdef NO_SUPPORT_DRIVEN_METHODS_EXTENDED
+
+  list_iterator first_iter;
+
+  first_iter.set_to_list(generators);
+
+  while(first_iter.is_at_end()==FALSE)
+  {
+    binomial& bin=first_iter.get_element();
+    int changed;
+    // to control if bin has been reduced
+
+    do
+    {
+      changed=0;
+      list_iterator second_iter;
+      second_iter.set_to_list(generators);
+
+      while(second_iter.is_at_end()==FALSE)
+      {
+        changed+=bin.reduce_tail_by(second_iter.get_element(),w);
+        // As soon as a reduction occurs, changed is set to a value !=0.
+        second_iter.next();
+      }
+
+    }
+    while(changed>0);
+
+    first_iter.next();
+  }
+
+#endif  // NO_SUPPORT_DRIVEN_METHODS_EXTENDED
+
+
+#ifdef SUPPORT_DRIVEN_METHODS_EXTENDED
+
+// In this case, the reduction has to be organized in a slightly different
+// way to use the support information to its full extend.
+// As soon as an reduction has taken place, the iteration over the reducer
+// lists is restarted using the new tail support information.
+
+  list_iterator first_iter;
+
+  for(int i=0;i<Number_of_Lists;i++)
+  {
+    first_iter.set_to_list(generators[i]);
+
+    while(first_iter.is_at_end()==FALSE)
+    {
+      binomial& bin=first_iter.get_element();
+      int changed;
+      // to control if bin has been reduced
+
+      do
+      {
+        changed=0;
+        list_iterator second_iter;
+
+        int supp=bin.tail_support%Number_of_Lists;
+        // determine the lists over which we have to iterate
+
+        for(int j=0;(j<S.number_of_subsets[supp]) && (changed==0);j++)
+        {
+          second_iter.set_to_list(generators[S.subsets_of_support[supp][j]]);
+          // This is the j-th list among the generator lists with elements
+          // whose support is a subset of supp.
+
+          while((second_iter.is_at_end()==FALSE) && (changed==0))
+          {
+            changed=bin.reduce_tail_by(second_iter.get_element(),w);
+            // Here we can do a simple assignment; as the iteration is stopped
+            // as soon as some reduction is done, reduced cannot be reset to
+            // zero in this assignment.
+            second_iter.next();
+          }
+        }
+
+      }
+      while(changed>0);
+
+      first_iter.next();
+    }
+  }
+
+#endif  // SUPPORT_DRIVEN_METHODS_EXTENDED
+
+  return(*this);
+}
+
+
+
+
+
+//////////////////////////////////////////////////////////////////////////////
+////////////////////// auxiliary stuff ///////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+
+
+
+
+
+int ideal::add_new_generators()
+{
+// Reduces the binomials in the "new_generators" list(s) by the generators
+// and moves them to the "generators" list(s).
+
+
+#ifdef NO_SUPPORT_DRIVEN_METHODS_EXTENDED
+
+  int result=0;
+  // element inserted?
+
+  list_iterator iter(new_generators);
+
+  while(iter.is_at_end()==FALSE)
+  {
+    binomial& bin=iter.get_element();
+    reduce(bin,FALSE);
+
+    if(bin==0)
+      iter.delete_element();
+    else
+    {
+      add_generator(bin);
+      iter.extract_element();
+      result=1;
+    }
+  }
+
+
+#endif  // NO_SUPPORT_DRIVEN_METHODS_EXTENDED
+
+
+#ifdef SUPPORT_DRIVEN_METHODS_EXTENDED
+
+  int result=0;
+  // element inserted?
+
+  list_iterator iter;
+
+  for(int i=0;i<Number_of_Lists;i++)
+  {
+    iter.set_to_list(new_generators[i]);
+
+    while(iter.is_at_end()==FALSE)
+    {
+      binomial& bin=iter.get_element();
+      reduce(bin,FALSE);
+
+      if(bin==0)
+        iter.delete_element();
+      else
+      {
+        add_generator(bin);
+        iter.extract_element();
+        result=1;
+      }
+    }
+  }
+
+
+#endif  // SUPPORT_DRIVEN_METHODS_EXTENDED
+
+
+  return result;
+}
+
+
+
+
+
+/////////////////////////////////////////////////////////////////////////////
+///////////////////// binomial reduction ////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+
+
+binomial& ideal::reduce(binomial& bin, BOOLEAN complete) const
+{
+// As bin is reduced by a fixed set of binomials, it is sufficient to do
+// head reductions first, then tail reductions (cf. Pottier).
+
+  list_iterator iter;
+  Integer reduced;
+  // to control if the binomial has been reduced during the actual iteration
+
+
+#ifdef NO_SUPPORT_DRIVEN_METHODS_EXTENDED
+
+  do
+  {
+    iter.set_to_list(generators);
+    reduced=0;
+    // not yet reduced
+
+    while(iter.is_at_end()==FALSE)
+    {
+      reduced+=bin.reduce_head_by(iter.get_element(),w);
+      // reduced is incremented (and so set to a value >0) as soon as bin
+      // is really reduced
+      iter.next();
+    }
+  }
+  while((reduced>0) && (bin!=0));
+
+  if(complete==TRUE)
+    do
+    {
+      iter.set_to_list(generators);
+      reduced=0;
+      // not yet reduced
+
+      while(iter.is_at_end()==FALSE)
+      {
+        reduced+=bin.reduce_tail_by(iter.get_element(),w);
+        // reduced is incremented (and so set to a value >0) as soon as bin
+        // is really reduced
+        iter.next();
+      }
+    }
+    while((reduced>0) && (bin!=0));
+
+#endif  // NO_SUPPORT_DRIVEN_METHODS_EXTENDED
+
+
+#ifdef SUPPORT_DRIVEN_METHODS_EXTENDED
+
+  do
+  {
+    reduced=0;
+    // not yet reduced
+
+    int supp=bin.head_support%Number_of_Lists;
+    // determine the lists over which we have to iterate
+
+    // As soon as some reduction is done, the iteration is started with
+    // the new support information; so we do not finish iterations over lists
+    // that cannot contain reducers any more.
+
+    for(int i=0;(i<S.number_of_subsets[supp]) && (reduced==0);i++)
+    {
+      iter.set_to_list(generators[S.subsets_of_support[supp][i]]);
+      // This is the i-th list among the generator lists with elements
+      // whose support is a subset of that of supp.
+
+      while((iter.is_at_end()==FALSE)&&(reduced==0))
+      {
+        reduced=bin.reduce_head_by(iter.get_element(),w);
+        // Here we can do a simple assignment; as the iteration is stopped
+        // as soon as some reduction is done, reduced cannot be reset to zero
+        // in this assignment.
+        iter.next();
+      }
+    }
+  }
+  while((reduced>0) && (bin!=0));
+
+  if(complete==TRUE)
+    do
+    {
+      reduced=0;
+      // not yet reduced
+
+      int supp=bin.tail_support%Number_of_Lists;
+      // determine the lists over which we have to iterate
+
+      // As soon as some reduction is done, the iteration is started with
+      // the new support information; so we do not finish iterations over
+      // lists that cannot contain reducers any more.
+
+      for(int i=0;(i<S.number_of_subsets[supp]) && (reduced==0);i++)
+      {
+        iter.set_to_list(generators[S.subsets_of_support[supp][i]]);
+        // This is the i-th list among the generator lists with elements
+        // whose support is a subset of that of supp.
+
+        while((iter.is_at_end()==FALSE)&&(reduced==0))
+        {
+          reduced=bin.reduce_tail_by(iter.get_element(),w);
+          // Here we can do a simple assignment; as the iteration is stopped
+          // as soon as some reduction is done, reduced cannot be reset to
+          // zero in this assignment
+        iter.next();
+      }
+    }
+  }
+  while(reduced>0);
+  // bin cannot be reduced to zero by a tail reduction
+
+#endif  // SUPPORT_DRIVEN_METHODS_EXTENDED
+
+  return(bin);
+}
+
+
+
+
+
+//////////////////////////////////////////////////////////////////////////////
+/////////// variants of Buchberger�s algorithm ///////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+
+
+
+
+
+ideal& ideal::reduced_Groebner_basis_1(const int& S_pair_criteria,
+                                       const float& interred_percentage)
+{
+  // set flags for the use of the S-pair criteria
+  // for an explaination see in globals.h
+  rel_primeness=(S_pair_criteria & 1);
+  M_criterion=(S_pair_criteria & 2);
+  F_criterion=(S_pair_criteria & 4);
+  B_criterion=(S_pair_criteria & 8);
+  second_criterion=(S_pair_criteria & 16);
+
+  interreduction_percentage=interred_percentage;
+
+  int done;
+  // control variable for recognizing when Buchberger's algorithm has reached
+  // his end
+
+  // first minimalize the initial generating system
+  minimalize();
+
+  do
+  {
+    done=1;
+    // no new generators found yet
+
+    compute_actual_S_pairs_1();
+    // compute the S-pairs of the actual generators
+    // These are stored in a unreduced form in aux_list.
+
+    list_iterator S_pair_iter(aux_list);
+    // now reduce and insert the computed S-pairs
+
+    while(S_pair_iter.is_at_end()==FALSE)
+    {
+      binomial& S_bin=S_pair_iter.get_element();
+      reduce(S_bin,FALSE);
+
+      if(S_bin!=0)
+        // new generator found
+      {
+        add_generator(S_bin);
+        S_pair_iter.extract_element();
+        done=0;
+        // algorithm does not terminate when a new generator is found
+      }
+      else
+        S_pair_iter.delete_element();
+    }
+
+    // now all computed S-pairs are inserted as generators
+    // enough for a minimalization?
+
+    if(interreduction_percentage>=0)
+      // intermediate interreductions allowed
+    {
+      if(number_of_new_binomials>=size*interreduction_percentage/100)
+        // enough new generators since last minimalization
+      {
+        minimalize();
+        number_of_new_binomials=0;
+      }
+    }
+
+    // now we restart the algorithm with the new generating system
+    // if the generating system has changed during the last iteration
+
+  }
+  while(done==0);
+  // if done==1, all computed S-pairs reduced to zero
+
+  // compute reduced from minimal Groebner basis
+  final_reduce();
+
+  return(*this);
+}
+
+
+
+
+
+
+ideal& ideal::reduced_Groebner_basis_1a(const int& S_pair_criteria,
+                                        const float& interred_percentage)
+{
+  // set flags for the use of the S-pair criteria
+  // for an explaination see in globals.h
+  rel_primeness=(S_pair_criteria & 1);
+  M_criterion=(S_pair_criteria & 2);
+  F_criterion=(S_pair_criteria & 4);
+  B_criterion=(S_pair_criteria & 8);
+  second_criterion=(S_pair_criteria & 16);
+
+  interreduction_percentage=interred_percentage;
+
+  int done;
+  // control variable for recognizing when Buchberger's algorithm has reached
+  // his end
+
+  // first minimalize the initial generating system
+  minimalize();
+
+  do
+  {
+    done=1;
+    // no new generators found yet
+
+    compute_actual_S_pairs_1a();
+    // compute the S-pairs of the actual generators
+    // These are stored in a unreduced form in aux_list.
+    // aux_list is ordered according to the ideal�s term ordering.
+
+    list_iterator S_pair_iter(aux_list);
+    // now reduce and insert the computed S-pairs
+
+    while(S_pair_iter.is_at_end()==FALSE)
+    {
+      binomial& S_bin=S_pair_iter.get_element();
+      reduce(S_bin,FALSE);
+
+      if(S_pair_iter.get_element()!=0)
+        // new generator found
+      {
+        add_generator(S_bin);
+        S_pair_iter.extract_element();
+        done=0;
+        // algorithm does not terminate when a new generator is found
+      }
+      else
+        S_pair_iter.delete_element();
+    }
+
+    // now all computed S-pairs are inserted as generators
+    // enough for a minimalization?
+
+    if(interreduction_percentage>=0)
+      // intermediate interreductions allowed
+    {
+      if(number_of_new_binomials>=size*interreduction_percentage/100)
+        // enough new generators since last minimalization
+      {
+        minimalize();
+        number_of_new_binomials=0;
+      }
+    }
+
+    // now we restart the algorithm with the new generating system
+    // if the generating system has changed during the last iteration
+
+  }
+  while(done==0);
+  // if done==1, all computed S-pairs reduced to zero
+
+  // compute reduced from minimal Groebner basis
+  final_reduce();
+
+  return(*this);
+}
+
+
+
+
+
+ideal& ideal::reduced_Groebner_basis_2(const int& S_pair_criteria,
+                                       const float& interred_percentage)
+{
+  // set flags for the use of the S-pair criteria
+  // for an explaination see in globals.h
+  rel_primeness=(S_pair_criteria & 1);
+  M_criterion=(S_pair_criteria & 2);
+  F_criterion=(S_pair_criteria & 4);
+  B_criterion=(S_pair_criteria & 8);
+  second_criterion=(S_pair_criteria & 16);
+
+  interreduction_percentage=interred_percentage;
+
+  int done;
+  // control variable for recognizing when Buchberger's algorithm has reached
+  // his end
+
+  // first minimalize the initial generating system
+  minimalize();
+
+  do
+  {
+    done=1;
+    // no new generators found yet
+
+    compute_actual_S_pairs_2();
+    // compute the S-pairs of the actual generators
+    // These are stored in a reduced version in aux_list.
+
+    minimalize_S_pairs();
+    // minimalize the binomials in aux_list
+    // These are not only S-pairs, but also ideal generators that were
+    // reduced by an S-pair during the S-pair computation.
+
+    list_iterator S_pair_iter(aux_list);
+
+    if(S_pair_iter.is_at_end()==FALSE)
+      // Zero binomials are not inserted in aux_list during the S-pair
+      // computation; i.e. if aux_list is not empty, a further iteration step
+      // has to be done.
+      done=0;
+
+    // now insert the computed S-pairs
+    while(S_pair_iter.is_at_end()==FALSE)
+      // S_pairs remaining
+    {
+      add_generator(S_pair_iter.get_element());
+      S_pair_iter.extract_element();
+    }
+
+    // now all computed S-pairs are inserted as generators
+    // enough for a minimalization?
+
+    if(interreduction_percentage>=0)
+      // intermediate interreductions allowed
+    {
+      if(number_of_new_binomials>=size*interreduction_percentage/100)
+        // enough new generators since last minimalization
+      {
+        minimalize();
+        number_of_new_binomials=0;
+      }
+    }
+
+    // now we restart the algorithm with the new generating system
+    // if the generating system has changed during the last iteration
+
+  }
+  while(done==0);
+  // if done==1, all computed S-pairs reduced to zero
+
+  // compute reduced from minimal Groebner basis
+  final_reduce();
+
+  return(*this);
+}
+
+
+
+
+
+ideal& ideal::reduced_Groebner_basis_3(const int& S_pair_criteria,
+                                       const float& interred_percentage)
+{
+  // set flags for the use of the S-pair criteria
+  // for an explaination see in globals.h
+  rel_primeness=(S_pair_criteria & 1);
+  M_criterion=(S_pair_criteria & 2);
+  F_criterion=(S_pair_criteria & 4);
+  B_criterion=(S_pair_criteria & 8);
+  second_criterion=(S_pair_criteria & 16);
+
+  interreduction_percentage=interred_percentage;
+
+  int not_done;
+  // control variable for recognizing when Buchberger's algorithm has reached
+  // his end
+
+  // first minimalize the initial generating system
+  minimalize();
+
+  do
+  {
+
+    compute_actual_S_pairs_3();
+    // compute the S-pairs of the actual generators
+    // These are stored in areduced version in the list(s) new_generators.
+
+    minimalize_new_generators();
+    // minimalize the binomials in aux_list
+    // These are not only S-pairs, but also ideal generators that were
+    // reduced by an S-pair during the S-pair computation.
+
+    not_done=add_new_generators();
+    // move binomials from new_generators to generators
+
+    // now all computed S-pairs are inserted as generators
+    // enough for a minimalization?
+
+    if(interreduction_percentage>=0)
+      // intermediate interreductions allowed
+    {
+      if(number_of_new_binomials>=size*interreduction_percentage/100)
+        // enough new generators since last reduction
+      {
+        minimalize();
+        number_of_new_binomials=0;
+      }
+    }
+
+    // now we restart the algorithm with the new generating system
+    // if the generating system has changed during the last iteration
+
+  }
+  while(not_done==1);
+  // if not_done==0, all computed S-pairs reduced to zero
+
+  // compute reduced from minimal Groebner basis
+  final_reduce();
+
+  return(*this);
+}
+
+
+
+
+
+ideal& ideal::reduced_Groebner_basis(const int& version,
+                                     const int& S_pair_criteria,
+                                     const float& interred_percentage)
+{
+  switch(version)
+  {
+      case 0:
+        return reduced_Groebner_basis_1a(S_pair_criteria, interred_percentage);
+      case 1:
+        return reduced_Groebner_basis_1(S_pair_criteria, interred_percentage);
+      case 2:
+        return reduced_Groebner_basis_2(S_pair_criteria, interred_percentage);
+      case 3:
+        return reduced_Groebner_basis_3(S_pair_criteria, interred_percentage);
+      default:
+        cerr<<"WARNING: ideal& ideal::reduced_Groebner_basis(const int&, "
+          "const int&, const float&):\n"
+          "version argument out of range, nothing done"<<endl;
+        return*this;
+  }
+}
+
+
+
+
+
+#endif  // BUCHBERGER_CC
diff --git a/IntegerProgramming/IP_algorithms.cc b/IntegerProgramming/IP_algorithms.cc
new file mode 100644
index 0000000..9a1e5fc
--- /dev/null
+++ b/IntegerProgramming/IP_algorithms.cc
@@ -0,0 +1,3991 @@
+// IP_algorithms.cc
+
+#ifndef IP_ALGORITHMS_CC
+#define IP_ALGORITHMS_CC
+
+#include "IP_algorithms.h"
+#include <time.h>
+#include <unistd.h>
+
+/////////////// method for printing compilation settings ////////////////////
+
+void print_flags(ofstream& output)
+{
+  output<<"compiler settings:"<<endl;
+
+#ifdef NO_SUPPORT_DRIVEN_METHODS
+  output<<"NO_SUPPORT_DRIVEN_METHODS"<<endl;
+#endif
+
+#ifdef SUPPORT_DRIVEN_METHODS
+
+#ifdef NO_SUPPORT_DRIVEN_METHODS_EXTENDED
+  output<<"SUPPORT_DRIVEN_METHODS"<<endl;
+#endif
+
+#ifdef SUPPORT_DRIVEN_METHODS_EXTENDED
+  output<<"SUPPORT_DRIVEN_METHODS_EXTENDED"<<endl;
+  output<<"List Support Variables:  "<<endl;
+  output<<List_Support_Variables<<endl;
+#endif
+
+#ifdef SUPPORT_VARIABLES_FIRST
+  output<<"SUPPORT_VARIABLES_FIRST"<<endl;
+#endif
+
+#ifdef SUPPORT_VARIABLES_LAST
+  output<<"SUPPORT_VARIABLES_LAST"<<endl;
+#endif
+
+#endif  // SUPPORT_DRIVEN_METHODS
+
+#ifdef DL_LIST
+  output<<"doubly linked lists"<<endl<<endl;
+#endif
+
+#ifdef SL_LIST
+  output<<"simply linked lists"<<endl<<endl;
+#endif
+
+}
+
+
+
+
+////////////////////////////////////////////////////////////////////////////
+///////////////////// IP algorithms ////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////
+
+
+
+
+int Conti_Traverso(INPUT_FILE MATRIX,
+                   const int& version,
+                   const int& S_pair_criteria,
+                   const float& interred_percentage,
+                   const BOOLEAN& verbose)
+{
+
+
+/////////////////////////// input /////////////////////////////////////////
+
+  char format_string[128]; // to verifie file format
+  int constraints;       // number of equality constraints
+  int variables;         // number of variables (without auxiliary variables)
+
+  ifstream input(MATRIX);
+
+  // verfifie existence of file
+
+  if(!input)
+  {
+    cerr<<"ERROR: int Conti_Traverso(INPUT_FILE, const BOOLEAN&):\n"
+      "cannot read from input file, possibly not found"<<endl;
+    return 0;
+  }
+
+  // read format specification
+
+  input>>format_string;
+
+  if(!input)
+  {
+    cerr<<"ERROR: int Conti_Traverso(INPUT_FILE, const BOOLEAN&):\n"
+      "input failure when reading format specification,\n"
+      "input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"MATRIX"))
+    cerr<<"Warning: int Conti_Traverso(INPUT_FILE, const BOOLEAN&):\n"
+      "input file has suspicious format"<<endl;
+
+  // read number of variables
+
+  input>>format_string;
+
+  if(!input)
+  {
+    cerr<<"ERROR: int Conti_Traverso(INPUT_FILE, const BOOLEAN&):\n"
+      "input failure before reading number of variables / matrix columns,\n"
+      "input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"columns:"))
+    cerr<<"WARNING: int Conti_Traverso(INPUT_FILE, const BOOLEAN&):\n"
+      "input file has suspicious format"<<endl;
+
+  input>>variables;
+
+  if(!input)
+  {
+    cerr<<"ERROR: int Conti_Traverso(INPUT_FILE, const BOOLEAN&):\n"
+      "input failure when reading number of variables / matrix columns,\n"
+      "input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(variables<=0)
+  {
+    cerr<<"ERROR: int Conti_Traverso(INPUT_FILE, const BOOLEAN&):\n"
+      "number of variables / matrix columns must be positve"<<endl;
+    return 0;
+  }
+
+  // read term ordering
+
+  input>>format_string;
+
+  if(!input)
+  {
+    cerr<<"ERROR: int Conti_Traverso(INPUT_FILE, const BOOLEAN&):\n"
+      "input failure before reading cost vector,\n"
+      "input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"cost"))
+    cerr<<"WARNING: int Conti_Traverso(INPUT_FILE, const BOOLEAN&):\n"
+      "input file has suspicious format"<<endl;
+
+  input>>format_string;
+
+  if(!input)
+  {
+    cerr<<"ERROR: int Conti_Traverso(INPUT_FILE, const BOOLEAN&):\n"
+      "input failure before reading cost vector,\n"
+      "input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"vector:"))
+    cerr<<"WARNING: int Conti_Traverso(INPUT_FILE, const BOOLEAN&):\n"
+      "input file has suspicious format"<<endl;
+
+  term_ordering w(variables,input,W_LEX);
+
+  if(w.error_status()<0)
+  {
+    cerr<<"ERROR: int Conti_Traverso(INPUT_FILE, const BOOLEAN&):\n"
+      "input failure when reading cost vector, input format not accepted"
+        <<endl;
+    return 0;
+  }
+
+  if(w.is_nonnegative()==FALSE)
+  {
+    cerr<<"ERROR: int Conti_Traverso(INPUT_FILE, const BOOLEAN&):\n"
+      "cost vectors with negative components are not supported"<<endl;
+    return 0;
+  }
+
+  // read number of constraints
+
+  input>>format_string;
+
+  if(!input)
+  {
+    cerr<<"ERROR: int Conti_Traverso(INPUT_FILE, const BOOLEAN&):\n"
+      "input failure before reading number of constraints / matrix rows,\n"
+      "input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"rows:"))
+    cerr<<"WARNING: int Conti_Traverso(INPUT_FILE, const BOOLEAN&):\n"
+      "input file has suspicious format"<<endl;
+
+  input>>constraints;
+
+  if(!input)
+  {
+    cerr<<"ERROR: int Conti_Traverso(INPUT_FILE, const BOOLEAN&):\n"
+      "input failure when reading number of constraints / matrix rows,\n"
+      "input format not accepted"
+        <<endl;
+    return 0;
+  }
+
+  if(constraints<=0)
+  {
+    cerr<<"ERROR: int Conti_Traverso(INPUT_FILE, const BOOLEAN&):\n"
+      "number of constraints / matrix rows must be positve"<<endl;
+    // Solving problems without constraints is possible, but not very
+    // interesting (because trivial). To avoid the problems and the overhead
+    // incurred by an "empty" matrix, such problems are refused.
+    return 0;
+  }
+
+  // read matrix
+
+  input>>format_string;
+
+  if(!input)
+  {
+    cerr<<"ERROR: int Conti_Traverso(INPUT_FILE, const BOOLEAN&):\n"
+      "input failure before reading matrix,\n"
+      "input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"matrix:"))
+    cerr<<"WARNING: int Conti_Traverso(INPUT_FILE, const BOOLEAN&):\n"
+      "input file has suspicious format"<<endl;
+
+  matrix A(constraints,variables,input);
+  if(A.error_status()<0)
+  {
+    cerr<<"ERROR: int Conti_Traverso(INPUT_FILE, const BOOLEAN&):\n"
+      "input failure when reading matrix, input format not accepted"<<endl;
+    return 0;
+  }
+
+
+///////////////////////// computation ////////////////////////////////////////
+
+  // prepare time measurement
+  clock_t start, end;
+
+  // create toric ideal
+  ideal I(A,w,CONTI_TRAVERSO);
+
+  // compute the standard basis
+  start=clock();
+  I.reduced_Groebner_basis(version,S_pair_criteria,interred_percentage);
+  end=clock();
+
+  // time measurement
+  float elapsed=((float) (end-start))/CLOCKS_PER_SEC;
+
+
+///////////////////////// output ////////////////////////////////////////////
+
+  // create output file
+
+  char GROEBNER[128];
+  int i=0;
+  while(MATRIX[i]!='\0' && MATRIX[i]!='.')
+  {
+    GROEBNER[i]=MATRIX[i];
+    i++;
+  }
+  GROEBNER[i]='\0';
+  strcat(GROEBNER,".GB.ct");
+
+  ofstream output(GROEBNER);
+
+  // format output file
+
+  output.flags(output.flags()|ios::fixed);
+  // output of fixed point numbers
+
+  output<<"GROEBNER"<<endl<<endl;
+
+  output<<"computed with algorithm:"<<endl;
+  output<<"ct"<<endl;
+  output<<"from file(s):"<<endl;
+  output<<MATRIX<<endl;
+  output<<"computation time"<<endl;
+  output<<setw(6)<<setprecision(2)<<elapsed<<" sec"<<endl<<endl;
+
+  output<<"term ordering:"<<endl;
+  output<<"elimination block"<<endl;
+  // elimination variables (>0)
+  output<<constraints+1<<endl;
+  output<<"LEX"<<endl;
+  output<<"weighted block"<<endl;
+  // weighted variables (>0)
+  output<<variables<<endl;
+  output<<"W_LEX"<<endl;
+  w.format_print_weight_vector(output);
+
+  output<<"size:"<<endl;
+  output<<I.number_of_generators()<<endl<<endl;
+
+  output<<"Groebner basis:"<<endl;
+  I.format_print(output);
+  output<<endl;
+
+  if(verbose==TRUE)
+  {
+    output<<"settings for the Buchberger algorithm:"<<endl;
+
+    output<<"version:"<<endl;
+    if(version==0)
+      output<<"1a"<<endl;
+    else
+      output<<version<<endl;
+
+    output<<"S-pair criteria:"<<endl;
+    if(S_pair_criteria & REL_PRIMENESS)
+      output<<"relatively prime leading terms"<<endl;
+    if(S_pair_criteria & M_CRITERION)
+      output<<"criterion M"<<endl;
+    if(S_pair_criteria & F_CRITERION)
+      output<<"criterion F"<<endl;
+    if(S_pair_criteria & B_CRITERION)
+      output<<"criterion B"<<endl;
+    if(S_pair_criteria & SECOND_CRITERION)
+      output<<"second criterion"<<endl;
+    output<<endl;
+
+    print_flags(output);
+    output<<endl;
+  }
+
+  return 1;
+}
+
+
+
+
+////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////
+
+
+
+
+int Positive_Conti_Traverso(INPUT_FILE MATRIX,
+                            const int& version,
+                            const int& S_pair_criteria,
+                            const float& interred_percentage,
+                            const BOOLEAN& verbose)
+{
+
+
+/////////////////////////// input /////////////////////////////////////////
+
+  char format_string[128]; // to verifie file format
+  int constraints;       // number of equality constraints
+  int variables;         // number of variables (without auxiliary variables)
+
+  ifstream input(MATRIX);
+
+  // verfifie existence of file
+
+  if(!input)
+  {
+    cerr<<"ERROR: int Positive_Conti_Traverso(INPUT_FILE, const BOOLEAN&):\n"
+      "cannot read from input file, possibly not found"<<endl;
+    return 0;
+  }
+
+  // read format specification
+
+  input>>format_string;
+
+  if(!input)
+  {
+    cerr<<"ERROR: int Positive_Conti_Traverso(INPUT_FILE, const BOOLEAN&):\n"
+      "input failure when reading format specification,\n"
+      "input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"MATRIX"))
+    cerr<<"Warning: int Positive_Conti_Traverso(INPUT_FILE, const BOOLEAN&):\n"
+      "input file has suspicious format"<<endl;
+
+  // read number of variables
+
+  input>>format_string;
+
+  if(!input)
+  {
+    cerr<<"ERROR: int Positive_Conti_Traverso(INPUT_FILE, const BOOLEAN&):\n"
+      "input failure before reading number of variables / matrix columns,\n"
+      "input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"columns:"))
+    cerr<<"WARNING: int Positive_Conti_Traverso(INPUT_FILE, const BOOLEAN&):\n"
+      "input file has suspicious format"<<endl;
+
+  input>>variables;
+
+  if(!input)
+  {
+    cerr<<"ERROR: int Positive_Conti_Traverso(INPUT_FILE, const BOOLEAN&):\n"
+      "input failure when reading number of variables / matrix columns,\n"
+      "input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(variables<=0)
+  {
+    cerr<<"ERROR: int Positive_Conti_Traverso(INPUT_FILE, const BOOLEAN&):\n"
+      "number of variables / matrix columns must be positve"<<endl;
+    return 0;
+  }
+
+  // read term ordering
+
+  input>>format_string;
+
+  if(!input)
+  {
+    cerr<<"ERROR: int Positive_Conti_Traverso(INPUT_FILE, const BOOLEAN&):\n"
+      "input failure before reading cost vector,\n"
+      " input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"cost"))
+    cerr<<"WARNING: int Positive_Conti_Traverso(INPUT_FILE, const BOOLEAN&):\n"
+      "input file has suspicious format"<<endl;
+
+  input>>format_string;
+
+  if(!input)
+  {
+    cerr<<"ERROR: int Positive_Conti_Traverso(INPUT_FILE, const BOOLEAN&):\n"
+      "input failure before reading cost vector,\n"
+      "input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"vector:"))
+    cerr<<"WARNING: int Positive_Conti_Traverso(INPUT_FILE, const BOOLEAN&):\n"
+      "input file has suspicious format"<<endl;
+
+  term_ordering w(variables,input,W_LEX);
+
+  if(w.error_status()<0)
+  {
+    cerr<<"ERROR: int Positive_Conti_Traverso(INPUT_FILE, const BOOLEAN&):\n"
+      "input failure when reading cost vector, input format not accepted"
+        <<endl;
+    return 0;
+  }
+
+  if(w.is_nonnegative()==FALSE)
+  {
+    cerr<<"ERROR: int Positive_Conti_Traverso(INPUT_FILE, const BOOLEAN&):\n"
+      "cost vectors with negative components are not supported"<<endl;
+    return 0;
+  }
+
+  // read number of constraints
+
+  input>>format_string;
+
+  if(!input)
+  {
+    cerr<<"ERROR: int Positive_Conti_Traverso(INPUT_FILE, const BOOLEAN&):\n"
+      "input failure before reading number of constraints / matrix rows,\n"
+      "input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"rows:"))
+    cerr<<"WARNING: int Positive_Conti_Traverso(INPUT_FILE, const BOOLEAN&):\n"
+      "input file has suspicious format"<<endl;
+
+  input>>constraints;
+
+  if(!input)
+  {
+    cerr<<"ERROR: int Positive_Conti_Traverso(INPUT_FILE, const BOOLEAN&):\n"
+      "input failure when reading number of constraints / matrix rows,\n"
+      "input format not accepted"
+        <<endl;
+    return 0;
+  }
+
+  if(constraints<=0)
+  {
+    cerr<<"ERROR: int Positive_Conti_Traverso(INPUT_FILE, const BOOLEAN&):\n"
+      "number of constraints / matrix rows must be positve"<<endl;
+    // Solving problems without constraints is possible, but not very
+    // interesting (because trivial). To avoid the problems and the overhead
+    // incurred by an "empty" matrix, such problems are refused.
+    return 0;
+  }
+
+  // read matrix
+
+  input>>format_string;
+
+  if(!input)
+  {
+    cerr<<"ERROR: int Positive_Conti_Traverso(INPUT_FILE, const BOOLEAN&):\n"
+      "input failure before reading matrix,\n"
+      "input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"matrix:"))
+    cerr<<"WARNING: int Positive_Conti_Traverso(INPUT_FILE, const BOOLEAN&):\n"
+      "input file has suspicious format"<<endl;
+
+  matrix A(constraints,variables,input);
+  if(A.error_status()<0)
+  {
+    cerr<<"ERROR: int Positive_Conti_Traverso(INPUT_FILE, const BOOLEAN&):\n"
+      "input failure when reading matrix, input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(A.is_nonnegative()==FALSE)
+  {
+    cerr<<"ERROR: int Positive_Conti_Traverso(INPUT_FILE, const BOOLEAN&):\n"
+      "input matrix has negative coefficients,\n"
+      "please use the general Conti-Traverso algorithm"<<endl;
+    return 0;
+  }
+
+
+///////////////////////// computation ////////////////////////////////////////
+
+  // prepare time measurement
+  clock_t start, end;
+
+  // create toric ideal
+  ideal I(A,w,POSITIVE_CONTI_TRAVERSO);
+
+  // compute the standard basis
+  start=clock();
+  I.reduced_Groebner_basis(version,S_pair_criteria,interred_percentage);
+  end=clock();
+
+  // time measurement
+  float elapsed=((float) (end-start))/CLOCKS_PER_SEC;
+
+
+///////////////////////// output ////////////////////////////////////////////
+
+  // create output file
+
+  char GROEBNER[128];
+  int i=0;
+  while(MATRIX[i]!='\0' && MATRIX[i]!='.')
+  {
+    GROEBNER[i]=MATRIX[i];
+    i++;
+  }
+  GROEBNER[i]='\0';
+  strcat(GROEBNER,".GB.pct");
+
+  ofstream output(GROEBNER);
+
+  // format output file
+
+  output.flags(output.flags()|ios::fixed);
+  // output of fixed point numbers
+
+  output<<"GROEBNER"<<endl<<endl;
+
+  output<<"computed with algorithm:"<<endl;
+  output<<"pct"<<endl;
+  output<<"from file(s):"<<endl;
+  output<<MATRIX<<endl;
+  output<<"computation time"<<endl;
+  output<<setw(6)<<setprecision(2)<<elapsed<<" sec"<<endl<<endl;
+
+  output<<"term ordering:"<<endl;
+  output<<"elimination block"<<endl;
+  // elimination variables (>0)
+  output<<constraints<<endl;
+  output<<"LEX"<<endl;
+  output<<"weighted block"<<endl;
+  // weighted variables (>0)
+  output<<variables<<endl;
+  output<<"W_LEX"<<endl;
+  w.format_print_weight_vector(output);
+  output<<endl;
+
+  output<<"size:"<<endl;
+  output<<I.number_of_generators()<<endl<<endl;
+
+  output<<"Groebner basis:"<<endl;
+  I.format_print(output);
+  output<<endl;
+
+  if(verbose==TRUE)
+  {
+    output<<"settings for the Buchberger algorithm:"<<endl;
+
+    output<<"version:"<<endl;
+    if(version==0)
+      output<<"1a"<<endl;
+    else
+      output<<version<<endl;
+
+    output<<"S-pair criteria:"<<endl;
+    if(S_pair_criteria & REL_PRIMENESS)
+      output<<"relatively prime leading terms"<<endl;
+    if(S_pair_criteria & M_CRITERION)
+      output<<"criterion M"<<endl;
+    if(S_pair_criteria & F_CRITERION)
+      output<<"criterion F"<<endl;
+    if(S_pair_criteria & B_CRITERION)
+      output<<"criterion B"<<endl;
+    if(S_pair_criteria & SECOND_CRITERION)
+      output<<"second criterion"<<endl;
+    output<<endl;
+
+    print_flags(output);
+    output<<endl;
+  }
+
+  return 1;
+}
+
+
+
+
+////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////
+
+
+
+
+int Elim_Conti_Traverso(INPUT_FILE MATRIX,
+                        const int& version,
+                        const int& S_pair_criteria,
+                        const float& interred_percentage,
+                        const BOOLEAN& verbose)
+{
+
+
+/////////////////////////// input /////////////////////////////////////////
+
+  char format_string[128]; // to verifie file format
+  int constraints;       // number of equality constraints
+  int variables;         // number of variables (without auxiliary variables)
+
+  ifstream input(MATRIX);
+
+  // verfifie existence of file
+
+  if(!input)
+  {
+    cerr<<"ERROR: int Elim_Conti_Traverso(INPUT_FILE, const BOOLEAN&):\n"
+      "cannot read from input file, possibly not found"<<endl;
+    return 0;
+  }
+
+  // read format specification
+
+  input>>format_string;
+
+  if(!input)
+  {
+    cerr<<"ERROR: int Elim_Conti_Traverso(INPUT_FILE, const BOOLEAN&):\n"
+      "input failure when reading format specification,\n"
+      "input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"MATRIX"))
+    cerr<<"Warning: int Elim_Conti_Traverso(INPUT_FILE, const BOOLEAN&):\n"
+      "input file has suspicious format"<<endl;
+
+  // read number of variables
+
+  input>>format_string;
+
+  if(!input)
+  {
+    cerr<<"ERROR: int Elim_Conti_Traverso(INPUT_FILE, const BOOLEAN&):\n"
+      "input failure before reading number of variables / matrix columns,\n"
+      "input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"columns:"))
+    cerr<<"WARNING: int Elim_Conti_Traverso(INPUT_FILE, const BOOLEAN&):\n"
+      "input file has suspicious format"<<endl;
+
+  input>>variables;
+
+  if(!input)
+  {
+    cerr<<"ERROR: int Elim_Conti_Traverso(INPUT_FILE, const BOOLEAN&):\n"
+      "input failure when reading number of variables / matrix columns,\n"
+      "input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(variables<=0)
+  {
+    cerr<<"ERROR: int Elim_Conti_Traverso(INPUT_FILE, const BOOLEAN&):\n"
+      "number of variables / matrix columns must be positve"<<endl;
+    return 0;
+  }
+
+  // read term ordering
+
+  input>>format_string;
+
+  if(!input)
+  {
+    cerr<<"ERROR: int Elim_Conti_Traverso(INPUT_FILE, const BOOLEAN&):\n"
+      "input failure before reading cost vector,\n"
+      "input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"cost"))
+    cerr<<"WARNING: int Elim_Conti_Traverso(INPUT_FILE, const BOOLEAN&):\n"
+      "input file has suspicious format"<<endl;
+
+  input>>format_string;
+
+  if(!input)
+  {
+    cerr<<"ERROR: int Elim_Conti_Traverso(INPUT_FILE, const BOOLEAN&):\n"
+      "input failure before reading cost vector,\n"
+      "input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"vector:"))
+    cerr<<"WARNING: int Elim_Conti_Traverso(INPUT_FILE, const BOOLEAN&):\n"
+      "input file has suspicious format"<<endl;
+
+  term_ordering w(variables,input,W_LEX);
+
+  if(w.error_status()<0)
+  {
+    cerr<<"ERROR: int Elim_Conti_Traverso(INPUT_FILE, const BOOLEAN&):\n"
+      "input failure when reading cost vector, input format not accepted"
+        <<endl;
+    return 0;
+  }
+
+  if(w.is_nonnegative()==FALSE)
+  {
+    cerr<<"ERROR: int Elim_Conti_Traverso(INPUT_FILE, const BOOLEAN&):\n"
+      "cost vectors with negative components are not supported"<<endl;
+    return 0;
+  }
+
+  // read number of constraints
+
+  input>>format_string;
+
+  if(!input)
+  {
+    cerr<<"ERROR: int Elim_Conti_Traverso(INPUT_FILE, const BOOLEAN&):\n"
+      "input failure before reading number of constraints / matrix rows,\n"
+      "input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"rows:"))
+    cerr<<"WARNING: int Elim_Conti_Traverso(INPUT_FILE, const BOOLEAN&):\n"
+      "input file has suspicious format"<<endl;
+
+  input>>constraints;
+
+  if(!input)
+  {
+    cerr<<"ERROR: int Elim_Conti_Traverso(INPUT_FILE, const BOOLEAN&):\n"
+      "input failure when reading number of constraints / matrix rows,\n"
+      "input format not accepted"
+        <<endl;
+    return 0;
+  }
+
+  if(constraints<=0)
+  {
+    cerr<<"ERROR: int Elim_Conti_Traverso(INPUT_FILE, const BOOLEAN&):\n"
+      "number of constraints / matrix rows must be positve"<<endl;
+    // Solving problems without constraints is possible, but not very
+    // interesting (because trivial). To avoid the problems and the overhead
+    // incurred by an "empty" matrix, such problems are refused.
+    return 0;
+  }
+
+  // read matrix
+
+  input>>format_string;
+
+  if(!input)
+  {
+    cerr<<"ERROR: int Elim_Conti_Traverso(INPUT_FILE, const BOOLEAN&):\n"
+      "input failure before reading matrix,\n"
+      "input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"matrix:"))
+    cerr<<"WARNING: int Elim_Conti_Traverso(INPUT_FILE, const BOOLEAN&):\n"
+      "input file has suspicious format"<<endl;
+
+  matrix A(constraints,variables,input);
+  if(A.error_status()<0)
+  {
+    cerr<<"ERROR: int Elim_Conti_Traverso(INPUT_FILE, const BOOLEAN&):\n"
+      "input failure when reading matrix, input format not accepted"<<endl;
+    return 0;
+  }
+
+
+///////////////////////// computation ////////////////////////////////////////
+
+  // prepare time measurement
+  clock_t start, end;
+
+  // create toric ideal: this is done with the CONTI_TRAVERSO constructor;
+  // some elimination has to be done later
+  ideal I(A,w,CONTI_TRAVERSO);
+
+  // compute the standard basis and eliminate auxiliary variables
+  start=clock();
+  I.reduced_Groebner_basis(version,S_pair_criteria,interred_percentage);
+  I.eliminate();
+  end=clock();
+
+  // time measurement
+  float elapsed=((float) (end-start))/CLOCKS_PER_SEC;
+
+
+///////////////////////// output ////////////////////////////////////////////
+
+  // create output file
+
+  char GROEBNER[128];
+  int i=0;
+  while(MATRIX[i]!='\0' && MATRIX[i]!='.')
+  {
+    GROEBNER[i]=MATRIX[i];
+    i++;
+  }
+  GROEBNER[i]='\0';
+  strcat(GROEBNER,".GB.ect");
+
+  ofstream output(GROEBNER);
+
+  // format output file
+
+  output.flags(output.flags()|ios::fixed);
+  // output of fixed point numbers
+
+  output<<"GROEBNER"<<endl<<endl;
+
+  output<<"computed with algorithm:"<<endl;
+  output<<"ect"<<endl;
+  output<<"from file(s):"<<endl;
+  output<<MATRIX<<endl;
+  output<<"computation time"<<endl;
+  output<<setw(6)<<setprecision(2)<<elapsed<<" sec"<<endl<<endl;
+
+  output<<"term ordering:"<<endl;
+  output<<"elimination block"<<endl;
+  // elimination variables (=0)
+  output<<0<<endl;
+  output<<"weighted block"<<endl;
+  // weighted variables (>0)
+  output<<variables<<endl;
+  output<<"W_LEX"<<endl;
+  w.format_print_weight_vector(output);
+
+  output<<"size:"<<endl;
+  output<<I.number_of_generators()<<endl<<endl;
+
+  output<<"Groebner basis:"<<endl;
+  I.format_print(output);
+  output<<endl;
+
+  if(verbose==TRUE)
+  {
+    output<<"settings for the Buchberger algorithm:"<<endl;
+
+    output<<"version:"<<endl;
+    if(version==0)
+      output<<"1a"<<endl;
+    else
+      output<<version<<endl;
+
+    output<<"S-pair criteria:"<<endl;
+    if(S_pair_criteria & REL_PRIMENESS)
+      output<<"relatively prime leading terms"<<endl;
+    if(S_pair_criteria & M_CRITERION)
+      output<<"criterion M"<<endl;
+    if(S_pair_criteria & F_CRITERION)
+      output<<"criterion F"<<endl;
+    if(S_pair_criteria & B_CRITERION)
+      output<<"criterion B"<<endl;
+    if(S_pair_criteria & SECOND_CRITERION)
+      output<<"second criterion"<<endl;
+    output<<endl;
+
+    print_flags(output);
+    output<<endl;
+  }
+
+  return 1;
+}
+
+
+
+
+////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////
+
+
+
+
+int Pottier(INPUT_FILE MATRIX,
+            const int& version,
+            const int& S_pair_criteria,
+            const float& interred_percentage,
+            const BOOLEAN& verbose)
+{
+
+
+/////////////////////////// input /////////////////////////////////////////
+
+  char format_string[128]; // to verifie file format
+  int constraints;       // number of equality constraints
+  int variables;         // number of variables (without auxiliary variables)
+
+  ifstream input(MATRIX);
+
+  // verfifie existence of file
+
+  if(!input)
+  {
+    cerr<<"ERROR: int Pottier(INPUT_FILE, const BOOLEAN&):\n"
+      "cannot read from input file, possibly not found"<<endl;
+    return 0;
+  }
+
+  // read format specification
+
+  input>>format_string;
+
+  if(!input)
+  {
+    cerr<<"ERROR: int Pottier(INPUT_FILE, const BOOLEAN&):\n"
+      "input failure when reading format specification,\n"
+      "input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"MATRIX"))
+    cerr<<"Warning: int Pottier(INPUT_FILE, const BOOLEAN&):\n"
+      "input file has suspicious format"<<endl;
+
+  // read number of variables
+
+  input>>format_string;
+
+  if(!input)
+  {
+    cerr<<"ERROR: int Pottier(INPUT_FILE, const BOOLEAN&):\n"
+      "input failure before reading number of variables / matrix columns,\n"
+      "input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"columns:"))
+    cerr<<"WARNING: int Pottier(INPUT_FILE, const BOOLEAN&):\n"
+      "input file has suspicious format"<<endl;
+
+  input>>variables;
+
+  if(!input)
+  {
+    cerr<<"ERROR: int Pottier(INPUT_FILE, const BOOLEAN&):\n"
+      "input failure when reading number of variables / matrix columns,\n"
+      "input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(variables<=0)
+  {
+    cerr<<"ERROR: int Pottier(INPUT_FILE, const BOOLEAN&):\n"
+      "number of variables / matrix columns must be positve"<<endl;
+    return 0;
+  }
+
+  // read term ordering
+
+  input>>format_string;
+
+  if(!input)
+  {
+    cerr<<"ERROR: int Pottier(INPUT_FILE, const BOOLEAN&):\n"
+      "input failure before reading cost vector,\n"
+      "input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"cost"))
+    cerr<<"WARNING: int Pottier(INPUT_FILE, const BOOLEAN&):\n"
+      "input file has suspicious format"<<endl;
+
+  input>>format_string;
+
+  if(!input)
+  {
+    cerr<<"ERROR: int Pottier(INPUT_FILE, const BOOLEAN&):\n"
+      "input failure before reading cost vector,\n"
+      "input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"vector:"))
+    cerr<<"WARNING: int Pottier(INPUT_FILE, const BOOLEAN&):\n"
+      "input file has suspicious format"<<endl;
+
+  term_ordering w(variables,input,W_LEX);
+
+  if(w.error_status()<0)
+  {
+    cerr<<"ERROR: int Pottier(INPUT_FILE, const BOOLEAN&):\n"
+      "input failure when reading cost vector, input format not accepted"
+        <<endl;
+    return 0;
+  }
+
+  if(w.is_nonnegative()==FALSE)
+  {
+    cerr<<"ERROR: int Pottier(INPUT_FILE, const BOOLEAN&):\n"
+      "cost vectors with negative components are not supported"<<endl;
+    return 0;
+  }
+
+  // read number of constraints
+
+  input>>format_string;
+
+  if(!input)
+  {
+    cerr<<"ERROR: int Pottier(INPUT_FILE, const BOOLEAN&):\n"
+      "input failure before reading number of constraints / matrix rows,\n"
+      " input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"rows:"))
+    cerr<<"WARNING: int Pottier(INPUT_FILE, const BOOLEAN&):\n"
+      "input file has suspicious format"<<endl;
+
+  input>>constraints;
+
+  if(!input)
+  {
+    cerr<<"ERROR: int Pottier(INPUT_FILE, const BOOLEAN&):\n"
+      "input failure when reading number of constraints / matrix rows,\n "
+      "input format not accepted"
+        <<endl;
+    return 0;
+  }
+
+  if(constraints<=0)
+  {
+    cerr<<"ERROR: int Pottier(INPUT_FILE, const BOOLEAN&):\n"
+      "number of constraints / matrix rows must be positve"<<endl;
+    // Solving problems without constraints is possible, but not very
+    // interesting (because trivial). To avoid the problems and the overhead
+    // incurred by an "empty" matrix, such problems are refused.
+    return 0;
+  }
+
+  // read matrix
+
+  input>>format_string;
+
+  if(!input)
+  {
+    cerr<<"ERROR: int Pottier(INPUT_FILE, const BOOLEAN&):\n"
+      "input failure before reading matrix,\n"
+      "input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"matrix:"))
+    cerr<<"WARNING: int Pottier(INPUT_FILE, const BOOLEAN&):\n"
+      "input file has suspicious format"<<endl;
+
+  matrix A(constraints,variables,input);
+  if(A.error_status()<0)
+  {
+    cerr<<"ERROR: int Pottier(INPUT_FILE, const BOOLEAN&):\n"
+      "input failure when reading matrix, input format not accepted"<<endl;
+    return 0;
+  }
+
+
+///////////////////////// computation ////////////////////////////////////////
+
+  // prepare time measurement
+  clock_t start, end;
+
+  // create toric ideal
+  ideal I(A,w,POTTIER);
+
+  // compute the standard basis and eliminate auxiliary variable
+  start=clock();
+  I.reduced_Groebner_basis(version,S_pair_criteria,interred_percentage);
+  I.eliminate();
+  end=clock();
+
+  // time measurement
+  float elapsed=((float) (end-start))/CLOCKS_PER_SEC;
+
+
+///////////////////////// output ////////////////////////////////////////////
+
+  // create output file
+
+  char GROEBNER[128];
+  int i=0;
+  while(MATRIX[i]!='\0' && MATRIX[i]!='.')
+  {
+    GROEBNER[i]=MATRIX[i];
+    i++;
+  }
+  GROEBNER[i]='\0';
+  strcat(GROEBNER,".GB.pt");
+
+  ofstream output(GROEBNER);
+
+  // format output file
+
+  output.flags(output.flags()|ios::fixed);
+  // output of fixed point numbers
+
+  output<<"GROEBNER"<<endl<<endl;
+
+  output<<"computed with algorithm:"<<endl;
+  output<<"pt"<<endl;
+  output<<"from file(s):"<<endl;
+  output<<MATRIX<<endl;
+  output<<"computation time"<<endl;
+  output<<setw(6)<<setprecision(2)<<elapsed<<" sec"<<endl<<endl;
+
+  output<<"term ordering:"<<endl;
+  output<<"elimination block"<<endl;
+  // elimination variables (=0)
+  output<<0<<endl;
+  output<<"weighted block"<<endl;
+  // weighted variables (>0)
+  output<<variables<<endl;
+  output<<"W_LEX"<<endl;
+  w.format_print_weight_vector(output);
+
+  output<<"size:"<<endl;
+  output<<I.number_of_generators()<<endl<<endl;
+
+  output<<"Groebner basis:"<<endl;
+  I.format_print(output);
+  output<<endl;
+
+  if(verbose==TRUE)
+  {
+    output<<"settings for the Buchberger algorithm:"<<endl;
+
+    output<<"version:"<<endl;
+    if(version==0)
+      output<<"1a"<<endl;
+    else
+      output<<version<<endl;
+
+    output<<"S-pair criteria:"<<endl;
+    if(S_pair_criteria & REL_PRIMENESS)
+      output<<"relatively prime leading terms"<<endl;
+    if(S_pair_criteria & M_CRITERION)
+      output<<"criterion M"<<endl;
+    if(S_pair_criteria & F_CRITERION)
+      output<<"criterion F"<<endl;
+    if(S_pair_criteria & B_CRITERION)
+      output<<"criterion B"<<endl;
+    if(S_pair_criteria & SECOND_CRITERION)
+      output<<"second criterion"<<endl;
+    output<<endl;
+
+    print_flags(output);
+    output<<endl;
+  }
+
+  return 1;
+}
+
+
+
+
+////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////
+
+
+
+
+int Hosten_Sturmfels(INPUT_FILE MATRIX,
+                     const int& version,
+                     const int& S_pair_criteria,
+                     const float& interred_percentage,
+                     const BOOLEAN& verbose)
+{
+
+
+/////////////////////////// input /////////////////////////////////////////
+
+  char format_string[128]; // to verifie file format
+  int constraints;       // number of equality constraints
+  int variables;         // number of variables
+
+  ifstream input(MATRIX);
+
+  // verfifie existence of file
+
+  if(!input)
+  {
+    cerr<<"ERROR: int Hosten_Sturmfels(INPUT_FILE, const BOOLEAN&):\n"
+      "cannot read from input file, possibly not found"<<endl;
+    return 0;
+  }
+
+  // read format specification
+
+  input>>format_string;
+
+  if(!input)
+  {
+    cerr<<"ERROR: int Hosten_Sturmfels(INPUT_FILE, const BOOLEAN&):\n"
+      "input failure when reading format specification,\n"
+      "input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"MATRIX"))
+    cerr<<"Warning: int Hosten_Sturmfels(INPUT_FILE, const BOOLEAN&):\n"
+      "input file has suspicious format"<<endl;
+
+  // read number of variables
+
+  input>>format_string;
+
+  if(!input)
+  {
+    cerr<<"ERROR: int Hosten_Sturmfels(INPUT_FILE, const BOOLEAN&):\n"
+      "input failure before reading number of variables / matrix columns,\n"
+      "input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"columns:"))
+    cerr<<"WARNING: int Hosten_Sturmfels(INPUT_FILE, const BOOLEAN&):\n"
+      "input file has suspicious format"<<endl;
+
+  input>>variables;
+
+  if(!input)
+  {
+    cerr<<"ERROR: int Hosten_Sturmfels(INPUT_FILE, const BOOLEAN&):\n"
+      "input failure when reading number of variables / matrix columns,\n"
+      "input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(variables<=0)
+  {
+    cerr<<"ERROR: int Hosten_Sturmfels(INPUT_FILE, const BOOLEAN&):\n"
+      "number of variables / matrix columns must be positve"<<endl;
+    return 0;
+  }
+
+  // read term ordering
+
+  input>>format_string;
+
+  if(!input)
+  {
+    cerr<<"ERROR: int Hosten_Sturmfels(INPUT_FILE, const BOOLEAN&):\n"
+      "input failure before reading cost vector,\n"
+      "input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"cost"))
+    cerr<<"WARNING: int Hosten_Sturmfels(INPUT_FILE, const BOOLEAN&):\n"
+      "input file has suspicious format"<<endl;
+
+  input>>format_string;
+
+  if(!input)
+  {
+    cerr<<"ERROR: int Hosten_Sturmfels(INPUT_FILE, const BOOLEAN&):\n"
+      "input failure before reading cost vector,\n"
+      "input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"vector:"))
+    cerr<<"WARNING: int Hosten_Sturmfels(INPUT_FILE, const BOOLEAN&):\n"
+      "input file has suspicious format"<<endl;
+
+  term_ordering c(variables,input,W_LEX);
+
+  if(c.error_status()<0)
+  {
+    cerr<<"ERROR: int Hosten_Sturmfels(INPUT_FILE, const BOOLEAN&):\n"
+      "input failure when reading cost vector, input format not accepted"
+        <<endl;
+    return 0;
+  }
+
+  if(c.is_nonnegative()==FALSE)
+  {
+    cerr<<"ERROR: int Hosten_Sturmfels(INPUT_FILE, const BOOLEAN&):\n"
+      "cost vectors with negative components are not supported"<<endl;
+    return 0;
+  }
+
+  // read number of constraints
+
+  input>>format_string;
+
+  if(!input)
+  {
+    cerr<<"ERROR: int Hosten_Sturmfels(INPUT_FILE, const BOOLEAN&):\n"
+      "input failure before reading number of constraints / matrix rows,\n"
+      "input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"rows:"))
+    cerr<<"WARNING: int Hosten_Sturmfels(INPUT_FILE, const BOOLEAN&):\n"
+      "input file has suspicious format"<<endl;
+
+  input>>constraints;
+
+  if(!input)
+  {
+    cerr<<"ERROR: int Hosten_Sturmfels(INPUT_FILE, const BOOLEAN&):\n"
+      "input failure when reading number of constraints / matrix rows,\n"
+      "input format not accepted"
+        <<endl;
+    return 0;
+  }
+
+  if(constraints<=0)
+  {
+    cerr<<"ERROR: int Hosten_Sturmfels(INPUT_FILE, const BOOLEAN&):\n"
+      "number of constraints / matrix rows must be positve"<<endl;
+    // Solving problems without constraints is possible, but not very
+    // interesting (because trivial). To avoid the problems and the overhead
+    // incurred by an "empty" matrix, such problems are refused.
+    return 0;
+  }
+
+  // read matrix
+
+  input>>format_string;
+
+  if(!input)
+  {
+    cerr<<"ERROR: int Hosten_Sturmfels(INPUT_FILE, const BOOLEAN&):\n"
+      "input failure before reading matrix,\n"
+      "input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"matrix:"))
+    cerr<<"WARNING: int Hosten_Sturmfels(INPUT_FILE, const BOOLEAN&):\n"
+      "input file has suspicious format"<<endl;
+
+  matrix A(constraints,variables,input);
+  if(A.error_status()<0)
+  {
+    cerr<<"ERROR: int Hosten_Sturmfels(INPUT_FILE, const BOOLEAN&):\n"
+      "input failure when reading matrix, input format not accepted"<<endl;
+    return 0;
+  }
+
+  // read positive vector in the row space of the matrix
+  // such a vector induces a homogenous grading on the ideal
+
+  input>>format_string;
+
+  if(!input)
+  {
+    cerr<<"ERROR: int Hosten_Sturmfels(INPUT_FILE, const BOOLEAN&):\n"
+      "input failure before reading positive row space vector,\n"
+      "input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"positive"))
+    cerr<<"WARNING: int Hosten_Sturmfels(INPUT_FILE, const BOOLEAN&):\n"
+      "input file has suspicious format"<<endl;
+
+  input>>format_string;
+
+  if(!input)
+  {
+    cerr<<"ERROR: int Hosten_Sturmfels(INPUT_FILE, const BOOLEAN&):\n"
+      "input failure before reading positive row space vector,\n"
+      "input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"row"))
+    cerr<<"WARNING: int Hosten_Sturmfels(INPUT_FILE, const BOOLEAN&):\n"
+      "input file has suspicious format"<<endl;
+
+  input>>format_string;
+
+  if(!input)
+  {
+    cerr<<"ERROR: int Hosten_Sturmfels(INPUT_FILE, const BOOLEAN&):\n"
+      "input failure before reading positive row space vector,\n"
+      " input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"space"))
+    cerr<<"WARNING: int Hosten_Sturmfels(INPUT_FILE, const BOOLEAN&):\n"
+      "input file has suspicious format"<<endl;
+
+  input>>format_string;
+
+  if(!input)
+  {
+    cerr<<"ERROR: int Hosten_Sturmfels(INPUT_FILE, const BOOLEAN&):\n"
+      "input failure before reading positive row space vector,\n"
+      "input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"vector:"))
+    cerr<<"WARNING: int Hosten_Sturmfels(INPUT_FILE, const BOOLEAN&):\n"
+      "input file has suspicious format"<<endl;
+
+  float *hom_grad=new float[variables];
+
+  for(int i=0;i<variables;i++)
+  {
+    input>>hom_grad[i];
+
+    if(!input)
+    {
+      cerr<<"ERROR: int Hosten_Sturmfels(INPUT_FILE, const BOOLEAN&):\n"
+        "input failure when reading positive grading / row space vector,\n"
+        "input format not accepted"<<endl;
+      delete[] hom_grad;
+      return 0;
+    }
+
+    if(hom_grad[i]<=0)
+    {
+      cerr<<"ERROR: int Hosten_Sturmfels(INPUT_FILE, const BOOLEAN&):\n"
+        "row space vector / grading must be positive"<<endl;
+      delete[] hom_grad;
+      return 0;
+    }
+  }
+
+
+///////////////////////// computation ////////////////////////////////////////
+
+  // prepare time measurement
+  clock_t start, end;
+
+  // construct homogenous term ordering
+  term_ordering w(variables, hom_grad, W_REV_LEX, HOMOGENEOUS);
+
+  delete[] hom_grad;
+
+  // create toric ideal
+  ideal I(A,w,HOSTEN_STURMFELS);
+
+  // compute the standard basis of the saturation:
+
+  start=clock();
+
+  // determine saturation variables
+  int *sat_var;
+  int number_of_sat_var=A.hosten_shapiro(sat_var);
+  // memory for sat_var is allocated in the hosten_shapiro procedure
+
+  // saturate the ideal
+  for(int i=0;i<number_of_sat_var;i++)
+  {
+    I.swap_variables(sat_var[i],variables-1);
+    // This operation simply makes the i-th saturation variable the cheapest.
+    // This involves swapping the weights in the ideal's term ordering,
+    // the variables in the generating binomials and rebuilding the
+    // list structure if SUPPORT_DRIVEN_METHODS_EXTENDED are used.
+
+    I.reduced_Groebner_basis(version,S_pair_criteria,interred_percentage);
+    // This calculation saturates the ideal with respect to the i-th
+    // variable.
+
+    I.swap_variables_unsafe(sat_var[i],variables-1);
+    // This operation does the same as ideal::swap_variables(...) except
+    // from rebuilding the list structure. It may cause an inconsistent
+    // structure, but is more efficient then the safe method. Before
+    // performing a Groebner basis computation, however, the ideal structure
+    // has to be rebuild. Procedures like ideal::swap_variables(...) and
+    // ideal::change_term_ordering_to(...) do this. But these are exactly
+    // the operations that follow.
+  }
+
+  delete[] sat_var;
+
+  // Now the ideal is saturated. The last Groebner basis computation is done
+  // with respect to the term ordering induced by the objective function.
+  I.change_term_ordering_to(c);
+  I.reduced_Groebner_basis(version,S_pair_criteria,interred_percentage);
+
+  end=clock();
+
+  // time measurement
+  float elapsed=((float) (end-start))/CLOCKS_PER_SEC;
+
+
+///////////////////////// output ////////////////////////////////////////////
+
+  // create output file
+
+  char GROEBNER[128];
+  int i=0;
+  while(MATRIX[i]!='\0' && MATRIX[i]!='.')
+  {
+    GROEBNER[i]=MATRIX[i];
+    i++;
+  }
+  GROEBNER[i]='\0';
+  strcat(GROEBNER,".GB.hs");
+
+  ofstream output(GROEBNER);
+
+  // format output file
+
+  output.flags(output.flags()|ios::fixed);
+  // output of fixed point numbers
+
+  output<<"GROEBNER"<<endl<<endl;
+
+  output<<"computed with algorithm:"<<endl;
+  output<<"hs"<<endl;
+  output<<"from file(s):"<<endl;
+  output<<MATRIX<<endl;
+  output<<"computation time"<<endl;
+  output<<setw(6)<<setprecision(2)<<elapsed<<" sec"<<endl<<endl;
+
+  output<<"term ordering:"<<endl;
+  output<<"elimination block"<<endl;
+  // elimination variables (=0)
+  output<<0<<endl;
+  output<<"weighted block"<<endl;
+  // weighted variables (>0)
+  output<<variables<<endl;
+  output<<"W_LEX"<<endl;
+  c.format_print_weight_vector(output);
+
+  output<<"size:"<<endl;
+  output<<I.number_of_generators()<<endl<<endl;
+
+  output<<"Groebner basis:"<<endl;
+  I.format_print(output);
+  output<<endl;
+
+  if(verbose==TRUE)
+  {
+    output<<"settings for the Buchberger algorithm:"<<endl;
+
+    output<<"version:"<<endl;
+    if(version==0)
+      output<<"1a"<<endl;
+    else
+      output<<version<<endl;
+
+    output<<"S-pair criteria:"<<endl;
+    if(S_pair_criteria & REL_PRIMENESS)
+      output<<"relatively prime leading terms"<<endl;
+    if(S_pair_criteria & M_CRITERION)
+      output<<"criterion M"<<endl;
+    if(S_pair_criteria & F_CRITERION)
+      output<<"criterion F"<<endl;
+    if(S_pair_criteria & B_CRITERION)
+      output<<"criterion B"<<endl;
+    if(S_pair_criteria & SECOND_CRITERION)
+      output<<"second criterion"<<endl;
+    output<<endl;
+
+    print_flags(output);
+    output<<endl;
+  }
+
+  return 1;
+}
+
+
+
+
+////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////
+
+
+
+
+int DiBiase_Urbanke(INPUT_FILE MATRIX,
+                    const int& version,
+                    const int& S_pair_criteria,
+                    const float& interred_percentage,
+                    const BOOLEAN& verbose)
+{
+
+
+/////////////////////////// input /////////////////////////////////////////
+
+  char format_string[128]; // to verify file format
+  int constraints;       // number of equality constraints
+  int variables;         // number of variables
+
+  ifstream input(MATRIX);
+
+  // verfifie existence of file
+
+  if(!input)
+  {
+    cerr<<"ERROR: int DiBiase_Urbanke(INPUT_FILE, const BOOLEAN&):\n"
+      "cannot read from input file, possibly not found"<<endl;
+    return 0;
+  }
+
+  // read format specification
+
+  input>>format_string;
+
+  if(!input)
+  {
+    cerr<<"ERROR: int DiBiase_Urbanke(INPUT_FILE, const BOOLEAN&):\n"
+      "input failure when reading format specification,\n"
+      "input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"MATRIX"))
+    cerr<<"Warning: int DiBiase_Urbanke(INPUT_FILE, const BOOLEAN&):\n"
+      "input file has suspicious format"<<endl;
+
+  // read number of variables
+
+  input>>format_string;
+
+  if(!input)
+  {
+    cerr<<"ERROR: int DiBiase_Urbanke(INPUT_FILE, const BOOLEAN&):\n"
+      "input failure before reading number of variables / matrix columns,\n"
+      "input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"columns:"))
+    cerr<<"WARNING: int DiBiase_Urbanke(INPUT_FILE, const BOOLEAN&):\n"
+      "input file has suspicious format"<<endl;
+
+  input>>variables;
+
+  if(!input)
+  {
+    cerr<<"ERROR: int DiBiase_Urbanke(INPUT_FILE, const BOOLEAN&):\n"
+      "input failure when reading number of variables / matrix columns,\n"
+      "input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(variables<=0)
+  {
+    cerr<<"ERROR: int DiBiase_Urbanke(INPUT_FILE, const BOOLEAN&):\n"
+      "number of variables / matrix columns must be positve"<<endl;
+    return 0;
+  }
+
+  // read term ordering
+
+  input>>format_string;
+
+  if(!input)
+  {
+    cerr<<"ERROR: int DiBiase_Urbanke(INPUT_FILE, const BOOLEAN&):\n"
+      "input failure before reading cost vector,\n"
+      "input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"cost"))
+    cerr<<"WARNING: int DiBiase_Urbanke(INPUT_FILE, const BOOLEAN&):\n"
+      "input file has suspicious format"<<endl;
+
+  input>>format_string;
+
+  if(!input)
+  {
+    cerr<<"ERROR: int DiBiase_Urbanke(INPUT_FILE, const BOOLEAN&):\n"
+      "input failure before reading cost vector,\n"
+      " input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"vector:"))
+    cerr<<"WARNING: int DiBiase_Urbanke(INPUT_FILE, const BOOLEAN&):\n"
+      "input file has suspicious format"<<endl;
+
+  term_ordering c(variables,input,W_LEX);
+
+  if(c.error_status()<0)
+  {
+    cerr<<"ERROR: int DiBiase_Urbanke(INPUT_FILE, const BOOLEAN&):\n"
+      "input failure when reading cost vector, input format not accepted"
+        <<endl;
+    return 0;
+  }
+
+  if(c.is_nonnegative()==FALSE)
+  {
+    cerr<<"ERROR: int DiBiase_Urbanke(INPUT_FILE, const BOOLEAN&):\n"
+      "cost vectors with negative components are not supported"<<endl;
+    return 0;
+  }
+
+  // read number of constraints
+
+  input>>format_string;
+
+  if(!input)
+  {
+    cerr<<"ERROR: int DiBiase_Urbanke(INPUT_FILE, const BOOLEAN&):\n"
+      "input failure before reading number of constraints / matrix rows,\n"
+      " input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"rows:"))
+    cerr<<"WARNING: int DiBiase_Urbanke(INPUT_FILE, const BOOLEAN&):\n"
+      "input file has suspicious format"<<endl;
+
+  input>>constraints;
+
+  if(!input)
+  {
+    cerr<<"ERROR: int DiBiase_Urbanke(INPUT_FILE, const BOOLEAN&):\n"
+      "input failure when reading number of constraints / matrix rows,\n"
+      "input format not accepted"
+        <<endl;
+    return 0;
+  }
+
+  if(constraints<=0)
+  {
+    cerr<<"ERROR: int DiBiase_Urbanke(INPUT_FILE, const BOOLEAN&):\n"
+      "number of constraints / matrix rows must be positve"<<endl;
+    // Solving problems without constraints is possible, but not very
+    // interesting (because trivial). To avoid the problems and the overhead
+    // incurred by an "empty" matrix, such problems are refused.
+    return 0;
+  }
+
+  // read matrix
+
+  input>>format_string;
+
+  if(!input)
+  {
+    cerr<<"ERROR: int DiBiase_Urbanke(INPUT_FILE, const BOOLEAN&):\n"
+      "input failure before reading matrix,\n"
+      "input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"matrix:"))
+    cerr<<"WARNING: int DiBiase_Urbanke(INPUT_FILE, const BOOLEAN&):\n"
+      "input file has suspicious format"<<endl;
+
+  matrix A(constraints,variables,input);
+  if(A.error_status()<0)
+  {
+    cerr<<"ERROR: int DiBiase_Urbanke(INPUT_FILE, const BOOLEAN&):\n"
+      "input failure when reading matrix, input format not accepted"<<endl;
+    return 0;
+  }
+
+
+///////////////////////// computation ////////////////////////////////////////
+
+  // prepare time measurement
+  clock_t start, end;
+
+  // compute flip variables (also to check the suitability of the algorithm)
+  int* F;
+  int r=A.compute_flip_variables(F);
+
+  if(r<0)
+    // algorithm not suitable
+  {
+    cout<<"ERROR: DiBiase_Urbanke(INPUT_FILE, const BOOLEAN&):\n"
+      "Kernel of the input matrix contains no vector with nonzero "
+      "components,\ninstance cannot be solved with this algorithm.\n"
+      "No output file created. Please use another algorithm."<<endl;
+    return 0;
+  }
+
+  ideal *I;
+  // We use a pointer here because we need to distinguish two cases
+  // for the ideal construction.
+
+  start=clock();
+
+  if(r==0)
+    // no variable flip needed
+    // create toric ideal from the lattice basis already with respect to the
+    // objective function
+  {
+    I=new ideal(A,c,DIBIASE_URBANKE);
+    I->reduced_Groebner_basis(version,S_pair_criteria,interred_percentage);
+  }
+
+  else
+  {
+    // construct term ordering to start with
+    // Here we have much freedom: The term ordering must only be an
+    // elimination ordering for the actual flip variable.
+    // To avoid supplementary functions to manipulate term orderings, we
+    // simply realize this as follows: The weight of the actual
+    // flip variable is set to 1, all other weights are set to zero. This
+    // still allows the use of different term orderings (by setting the
+    // refining ordering).
+
+    float* weights=new float[variables];
+    for(int j=0;j<variables;j++)
+      weights[j]=0;
+    weights[F[0]]=1;
+
+    term_ordering w(variables, weights, W_LEX);
+    // Which term ordering is the best here?
+
+    delete[] weights;
+
+    // create toric ideal
+    I=new ideal(A,w,DIBIASE_URBANKE);
+
+    I->reduced_Groebner_basis(version,S_pair_criteria,interred_percentage);
+    I->flip_variable_unsafe(F[0]);
+    // "unsafe" means that head and tail can be exchanged (cf. the routine
+    // ideal::swap_variables_unsafe(...) )
+    // But the following change of the term ordering will correct this.
+
+    for(int l=1;l<r;l++)
+    {
+      w.swap_weights(F[l-1],F[l]);
+      // This means concretely:
+      // The weight of x_F[l-1] is set to zero, that of x_F[l] to one.
+      // Now, x_F[l] is the elimination variable.
+
+      I->change_term_ordering_to(w);
+      I->reduced_Groebner_basis(version,S_pair_criteria,interred_percentage);
+      I->flip_variable_unsafe(F[l]);
+    }
+
+    // Now we have a generating system of the saturated ideal.
+    // Compute Groebner basis with respect to the objective function.
+    I->change_term_ordering_to(c);
+    I->reduced_Groebner_basis(version,S_pair_criteria,interred_percentage);
+
+  }
+
+  end=clock();
+
+  // time measurement
+  float elapsed=((float) (end-start))/CLOCKS_PER_SEC;
+
+
+///////////////////////// output ////////////////////////////////////////////
+
+  // create output file
+
+  char GROEBNER[128];
+  int i=0;
+  while(MATRIX[i]!='\0' && MATRIX[i]!='.')
+  {
+    GROEBNER[i]=MATRIX[i];
+    i++;
+  }
+  GROEBNER[i]='\0';
+  strcat(GROEBNER,".GB.du");
+
+  ofstream output(GROEBNER);
+
+  // format output file
+
+  output.flags(output.flags()|ios::fixed);
+  // output of fixed point numbers
+
+  output<<"GROEBNER"<<endl<<endl;
+
+  output<<"computed with algorithm:"<<endl;
+  output<<"du"<<endl;
+  output<<"from file(s):"<<endl;
+  output<<MATRIX<<endl;
+  output<<"computation time"<<endl;
+  output<<setw(6)<<setprecision(2)<<elapsed<<" sec"<<endl<<endl;
+
+  output<<"term ordering:"<<endl;
+  output<<"elimination block"<<endl;
+  // elimination variables (=0)
+  output<<0<<endl;
+  output<<"weighted block"<<endl;
+  // weighted variables (>0)
+  output<<variables<<endl;
+  output<<"W_LEX"<<endl;
+  c.format_print_weight_vector(output);
+
+  output<<"size:"<<endl;
+  output<<I->number_of_generators()<<endl<<endl;
+
+  output<<"Groebner basis:"<<endl;
+  I->format_print(output);
+  output<<endl;
+
+  if(verbose==TRUE)
+  {
+    output<<"settings for the Buchberger algorithm:"<<endl;
+
+    output<<"version:"<<endl;
+    if(version==0)
+      output<<"1a"<<endl;
+    else
+      output<<version<<endl;
+
+    output<<"S-pair criteria:"<<endl;
+    if(S_pair_criteria & REL_PRIMENESS)
+      output<<"relatively prime leading terms"<<endl;
+    if(S_pair_criteria & M_CRITERION)
+      output<<"criterion M"<<endl;
+    if(S_pair_criteria & F_CRITERION)
+      output<<"criterion F"<<endl;
+    if(S_pair_criteria & B_CRITERION)
+      output<<"criterion B"<<endl;
+    if(S_pair_criteria & SECOND_CRITERION)
+      output<<"second criterion"<<endl;
+    output<<endl;
+
+    print_flags(output);
+    output<<endl;
+  }
+
+
+////////////////////////////// memory cleanup ////////////////////////////////
+
+  if(r>0)
+    delete[] F;
+  delete I;
+
+  return 1;
+}
+
+
+
+
+////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////
+
+
+
+
+int Bigatti_LaScala_Robbiano(INPUT_FILE MATRIX,
+                             const int& version,
+                             const int& S_pair_criteria,
+                             const float& interred_percentage,
+                             const BOOLEAN& verbose)
+{
+
+
+/////////////////////////// input /////////////////////////////////////////
+
+  char format_string[128];     // to verifie file format
+  int constraints;       // number of equality constraints
+  int variables;         // number of variables
+
+  ifstream input(MATRIX);
+
+  // verfifie existence of file
+
+  if(!input)
+  {
+    cerr<<"ERROR: int Bigatti_LaScala_Robbiano(INPUT_FILE, const BOOLEAN&):\n"
+      "cannot read from input file, possibly not found"<<endl;
+    return 0;
+  }
+
+  // read format specification
+
+  input>>format_string;
+
+  if(!input)
+  {
+    cerr<<"ERROR: int Bigatti_LaScala_Robbiano(INPUT_FILE, const BOOLEAN&):\n"
+      "input failure when reading format specification,\n"
+      "input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"MATRIX"))
+    cerr<<"Warning: int Bigatti_LaScala_Robbiano(INPUT_FILE, const BOOLEAN&):"
+      "\n"
+      "input file has suspicious format"<<endl;
+
+  // read number of variables
+
+  input>>format_string;
+
+  if(!input)
+  {
+    cerr<<"ERROR: int Bigatti_LaScala_Robbiano(INPUT_FILE, const BOOLEAN&):\n"
+      "input failure before reading number of variables / matrix columns,\n"
+      "input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"columns:"))
+    cerr<<"WARNING: int Bigatti_LaScala_Robbiano(INPUT_FILE, const BOOLEAN&):"
+      "\n"
+      "input file has suspicious format"<<endl;
+
+  input>>variables;
+
+  if(!input)
+  {
+    cerr<<"ERROR: int Bigatti_LaScala_Robbiano(INPUT_FILE, const BOOLEAN&):\n"
+      "input failure when reading number of variables / matrix columns,\n"
+      "input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(variables<=0)
+  {
+    cerr<<"ERROR: int Bigatti_LaScala_Robbiano(INPUT_FILE, const BOOLEAN&):\n"
+      "number of variables / matrix columns must be positve"<<endl;
+    return 0;
+  }
+
+  // read term ordering
+
+  input>>format_string;
+
+  if(!input)
+  {
+    cerr<<"ERROR: int Bigatti_LaScala_Robbiano(INPUT_FILE, const BOOLEAN&):\n"
+      "input failure before reading cost vector,\n"
+      "input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"cost"))
+    cerr<<"WARNING: int Bigatti_LaScala_Robbiano(INPUT_FILE, const BOOLEAN&):"
+      "\n"
+      "input file has suspicious format"<<endl;
+
+  input>>format_string;
+
+  if(!input)
+  {
+    cerr<<"ERROR: int Bigatti_LaScala_Robbiano(INPUT_FILE, const BOOLEAN&):\n"
+      "input failure before reading cost vector,\n"
+      "input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"vector:"))
+    cerr<<"WARNING: int Bigatti_LaScala_Robbiano(INPUT_FILE, const BOOLEAN&):"
+      "\n"
+      "input file has suspicious format"<<endl;
+
+  term_ordering c(variables,input,W_LEX);
+
+  if(c.error_status()<0)
+  {
+    cerr<<"ERROR: int Bigatti_LaScala_Robbiano(INPUT_FILE, const BOOLEAN&):\n"
+      "input failure when reading cost vector, input format not accepted"
+        <<endl;
+    return 0;
+  }
+
+  if(c.is_nonnegative()==FALSE)
+  {
+    cerr<<"ERROR: int Bigatti_LaScala_Robbiano(INPUT_FILE, const BOOLEAN&):\n"
+      "cost vectors with negative components are not supported"<<endl;
+    return 0;
+  }
+
+  // read number of constraints
+
+  input>>format_string;
+
+  if(!input)
+  {
+    cerr<<"ERROR: int Bigatti_LaScala_Robbiano(INPUT_FILE, const BOOLEAN&):\n"
+      "input failure before reading number of constraints / matrix rows,\n"
+      "input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"rows:"))
+    cerr<<"WARNING: int Bigatti_LaScala_Robbiano(INPUT_FILE, const BOOLEAN&):"
+      "\n"
+      "input file has suspicious format"<<endl;
+
+  input>>constraints;
+
+  if(!input)
+  {
+    cerr<<"ERROR: int Bigatti_LaScala_Robbiano(INPUT_FILE, const BOOLEAN&):\n"
+      "input failure when reading number of constraints / matrix rows,\n"
+      "input format not accepted"
+        <<endl;
+    return 0;
+  }
+
+  if(constraints<=0)
+  {
+    cerr<<"ERROR: int Bigatti_LaScala_Robbiano(INPUT_FILE, const BOOLEAN&):\n"
+      "number of constraints / matrix rows must be positve"<<endl;
+    // Solving problems without constraints is possible, but not very
+    // interesting (because trivial). To avoid the problems and the overhead
+    // incurred by an "empty" matrix, such problems are refused.
+    return 0;
+  }
+
+  // read matrix
+
+  input>>format_string;
+
+  if(!input)
+  {
+    cerr<<"ERROR: int Bigatti_LaScala_Robbiano(INPUT_FILE, const BOOLEAN&):\n"
+      "input failure before reading matrix,\n"
+      "input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"matrix:"))
+    cerr<<"WARNING: int Bigatti_LaScala_Robbiano(INPUT_FILE, const BOOLEAN&):"
+      "\n"
+      "input file has suspicious format"<<endl;
+
+  matrix A(constraints,variables,input);
+  if(A.error_status()<0)
+  {
+    cerr<<"ERROR: int Bigatti_LaScala_Robbiano(INPUT_FILE, const BOOLEAN&):\n"
+      "input failure when reading matrix, input format not accepted"<<endl;
+    return 0;
+  }
+
+  // read positive vector in the row space of the matrix
+  // such a vector induces a grading with respect to which the ideal is
+  // homogenous
+
+  input>>format_string;
+
+  if(!input)
+  {
+    cerr<<"ERROR: int Bigatti_LaScala_Robbiano(INPUT_FILE, const BOOLEAN&):\n"
+      "input failure before reading positive row space vector,\n"
+      "input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"positive"))
+    cerr<<"WARNING: int Bigatti_LaScala_Robbiano(INPUT_FILE, const BOOLEAN&):"
+      "\n"
+      "input file has suspicious format"<<endl;
+
+  input>>format_string;
+
+  if(!input)
+  {
+    cerr<<"ERROR: int Bigatti_LaScala_Robbiano(INPUT_FILE, const BOOLEAN&):\n"
+      "input failure before reading positive row space vector,\n"
+      "input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"row"))
+    cerr<<"WARNING: int Bigatti_LaScala_Robbiano(INPUT_FILE, const BOOLEAN&):"
+      "\n"
+      "input file has suspicious format"<<endl;
+
+  input>>format_string;
+
+  if(!input)
+  {
+    cerr<<"ERROR: int Bigatti_LaScala_Robbiano(INPUT_FILE, const BOOLEAN&):\n"
+      "input failure before reading positive row space vector,\n"
+      " input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"space"))
+    cerr<<"WARNING: int Bigatti_LaScala_Robbiano(INPUT_FILE, const BOOLEAN&):"
+      "\n"
+      "input file has suspicious format"<<endl;
+
+  input>>format_string;
+
+  if(!input)
+  {
+    cerr<<"ERROR: int Bigatti_LaScala_Robbiano(INPUT_FILE, const BOOLEAN&):\n"
+      "input failure before reading positive row space vector,\n"
+      "input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"vector:"))
+    cerr<<"WARNING: int Bigatti_LaScala_Robbiano(INPUT_FILE, const BOOLEAN&):"
+      "\n"
+      "input file has suspicious format"<<endl;
+
+  float *hom_grad=new float[variables];
+
+  for(int _i=0;_i<variables;_i++)
+  {
+    input>>hom_grad[_i];
+
+    if(!input)
+    {
+      cerr<<"ERROR: int Bigatti_LaScala_Robbiano(INPUT_FILE, const BOOLEAN&):"
+        "\n"
+        "input failure when reading positive grading / row space vector,\n"
+        "input format not accepted"<<endl;
+      delete[] hom_grad;
+      return 0;
+    }
+
+    if(hom_grad[_i]<=0)
+    {
+      cerr<<"ERROR: int Bigatti_LaScala_Robbiano(INPUT_FILE, const BOOLEAN&):"
+        "\n"
+        "row space vector / grading must be positive"<<endl;
+      delete[] hom_grad;
+      return 0;
+    }
+  }
+
+
+
+///////////////////////// computation ////////////////////////////////////////
+
+  // prepare time measurement
+  clock_t start, end;
+
+  // construct homogenous term ordering
+  term_ordering w(variables, hom_grad, W_REV_LEX, HOMOGENEOUS);
+
+  delete[] hom_grad;
+
+  // create toric ideal
+  ideal I(A,w,BIGATTI_LASCALA_ROBBIANO);
+
+  // compute the standard basis
+  start=clock();
+  I.reduced_Groebner_basis(version,S_pair_criteria,interred_percentage);
+
+  // now we have a generating system
+  // to perform the substitution of the auxiliary variable U by the saturation
+  // variables:
+  // make U the revlex most expensive variable by swapping with the first,
+  // recompute the Groebner basis, undo the swap
+  I.swap_variables(0,variables);
+  I.reduced_Groebner_basis(version,S_pair_criteria,interred_percentage);
+  I.swap_variables(0,variables);
+
+  I.pseudo_eliminate();
+  // eliminate the auxiliary variable
+
+  // Now the ideal is saturated. Compute the Groebner basis
+  // with respect to the term ordering induced by the objective function.
+  I.change_term_ordering_to(c);
+  I.reduced_Groebner_basis(version,S_pair_criteria,interred_percentage);
+
+  end=clock();
+
+  // time measurement
+  float elapsed=((float) (end-start))/CLOCKS_PER_SEC;
+
+
+///////////////////////// output ////////////////////////////////////////////
+
+  // create output file
+
+  char GROEBNER[128];
+  int i=0;
+  while(MATRIX[i]!='\0' && MATRIX[i]!='.')
+  {
+    GROEBNER[i]=MATRIX[i];
+    i++;
+  }
+  GROEBNER[i]='\0';
+  strcat(GROEBNER,".GB.blr");
+
+  ofstream output(GROEBNER);
+
+  // format output file
+
+  output.flags(output.flags()|ios::fixed);
+  // output of fixed point numbers
+
+  output<<"GROEBNER"<<endl<<endl;
+
+  output<<"computed with algorithm:"<<endl;
+  output<<"blr"<<endl;
+  output<<"from file(s):"<<endl;
+  output<<MATRIX<<endl;
+  output<<"computation time"<<endl;
+  output<<setw(6)<<setprecision(2)<<elapsed<<" sec"<<endl<<endl;
+
+  output<<"term ordering:"<<endl;
+  output<<"elimination block"<<endl;
+  // elimination variables (00)
+  output<<0<<endl;
+  output<<"weighted block"<<endl;
+  // weighted variables (>0)
+  output<<variables<<endl;
+  output<<"W_LEX"<<endl;
+  c.format_print_weight_vector(output);
+
+  output<<"size:"<<endl;
+  output<<I.number_of_generators()<<endl<<endl;
+
+  output<<"Groebner basis:"<<endl;
+  I.format_print(output);
+  output<<endl;
+
+  if(verbose==TRUE)
+  {
+    output<<"settings for the Buchberger algorithm:"<<endl;
+
+    output<<"version:"<<endl;
+    if(version==0)
+      output<<"1a"<<endl;
+    else
+      output<<version<<endl;
+
+    output<<"S-pair criteria:"<<endl;
+    if(S_pair_criteria & REL_PRIMENESS)
+      output<<"relatively prime leading terms"<<endl;
+    if(S_pair_criteria & M_CRITERION)
+      output<<"criterion M"<<endl;
+    if(S_pair_criteria & F_CRITERION)
+      output<<"criterion F"<<endl;
+    if(S_pair_criteria & B_CRITERION)
+      output<<"criterion B"<<endl;
+    if(S_pair_criteria & SECOND_CRITERION)
+      output<<"second criterion"<<endl;
+    output<<endl;
+
+    print_flags(output);
+    output<<endl;
+  }
+
+  return 1;
+}
+
+
+
+
+////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////
+
+
+
+
+int solve(INPUT_FILE PROBLEM, INPUT_FILE GROEBNER)
+{
+
+  char format_string[128];
+  int problem_variables;
+  int elimination_variables;
+  int weighted_variables;
+  char elimination_refinement[128];
+  char weighted_refinement[128];
+  char algorithm[128];
+  long size;
+  long instances;
+
+  ifstream problem(PROBLEM);
+  ifstream groebner(GROEBNER);
+
+  // verfifie existence of files
+
+  if(!problem)
+  {
+    cerr<<"ERROR: int solve(INPUT_FILE, INPUT_FILE):\n"
+      "cannot read from first input file "<< PROBLEM <<", possibly not found"<<endl;
+    return 0;
+  }
+
+  if(!groebner)
+  {
+    cerr<<"ERROR: int solve(INPUT_FILE, INPUT_FILE):\n"
+      "cannot read from second input file "<< GROEBNER <<", possibly not found"<<endl;
+    return 0;
+  }
+
+// read GROEBNER file
+
+  // read format specification
+
+  groebner>>format_string;
+
+  if(!groebner)
+  {
+    cerr<<"ERROR: int solve(INPUT_FILE, INPUT_FILE):\n"
+      "input failure when reading format specification of second input file,\n"
+      "input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"GROEBNER"))
+    cerr<<"WARNING: int solve(INPUT_FILE, INPUT_FILE):\n"
+      "second input file has suspicious format"<<endl;
+
+  // read algorithm
+
+  groebner>>format_string;
+
+  if(!groebner)
+  {
+    cerr<<"ERROR: int solve(INPUT_FILE, INPUT_FILE):\n"
+      "input failure before reading algorithm from second input file,\n"
+      "input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"computed"))
+    cerr<<"WARNING: int solve(INPUT_FILE, INPUT_FILE):\n"
+      "second input file has suspicious format"<<endl;
+
+  groebner>>format_string;
+
+  if(!groebner)
+  {
+    cerr<<"ERROR: int solve(INPUT_FILE, INPUT_FILE):\n"
+      "input failure before reading algorithm from second input file,\n"
+      "input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"with"))
+    cerr<<"WARNING: int solve(INPUT_FILE, INPUT_FILE):\n"
+      "second input file has suspicious format"<<endl;
+
+  groebner>>format_string;
+
+  if(!groebner)
+  {
+    cerr<<"ERROR: int solve(INPUT_FILE, INPUT_FILE):\n"
+      "input failure before reading algorithm from second input file,\n"
+      "input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"algorithm:"))
+    cerr<<"WARNING: int solve(INPUT_FILE, INPUT_FILE):\n"
+      "second input file has suspicious format"<<endl;
+
+  groebner>>algorithm;
+
+  if(!groebner)
+  {
+    cerr<<"ERROR: int solve(INPUT_FILE, INPUT_FILE):\n"
+      "input failure when reading algorithm from second input file,\n"
+      "input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(algorithm,"ct") && strcmp(algorithm,"pct") &&
+     strcmp(algorithm,"ect") && strcmp(algorithm,"pt") &&
+     strcmp(algorithm,"hs") && strcmp(algorithm,"du")
+     && strcmp(algorithm,"blr"))
+    cerr<<"WARNING: int solve(INPUT_FILE, INPUT_FILE):\n"
+      "second input file computed with unknown algorithm"<<endl;
+
+  // override optional lines
+
+  do
+  {
+    groebner>>format_string;
+
+    if(!groebner)
+    {
+      cerr<<"ERROR: int solve(INPUT_FILE, INPUT_FILE):\n"
+        "input failure before reading term ordering from second \n"
+        "input file, input format not accepted"<<endl;
+      return 0;
+    }
+  }
+  while(strcmp(format_string,"term"));
+
+  // read term ordering
+
+  groebner>>format_string;
+
+  if(!groebner)
+  {
+    cerr<<"ERROR: int solve(INPUT_FILE, INPUT_FILE):\n"
+      "input failure before reading term ordering \n"
+      "from second input file, input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"ordering:"))
+    cerr<<"WARNING: int solve(INPUT_FILE, INPUT_FILE):\n"
+      "second input file has suspicious format"<<endl;
+
+  groebner>>format_string;
+
+  if(!groebner)
+  {
+    cerr<<"ERROR: int solve(INPUT_FILE, INPUT_FILE):\n"
+      "input failure when reading term ordering \n"
+      "from second input file, input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"elimination"))
+    cerr<<"WARNING: int solve(INPUT_FILE, INPUT_FILE):\n"
+      "second input file has suspicious format"<<endl;
+
+  groebner>>format_string;
+
+  if(!groebner)
+  {
+    cerr<<"ERROR: int solve(INPUT_FILE, INPUT_FILE):\n"
+      "input failure when reading term ordering \n"
+      "from second input file, input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"block"))
+    cerr<<"WARNING: int solve(INPUT_FILE, INPUT_FILE):\n"
+      "second input file has suspicious format"<<endl;
+
+  groebner>>elimination_variables;
+
+  if(!groebner)
+  {
+    cerr<<"ERROR: int solve(INPUT_FILE, INPUT_FILE):\n"
+      "input failure when reading term ordering \n"
+      "from second input file, input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(elimination_variables<0)
+  {
+    cerr<<"ERROR: int solve(INPUT_FILE, INPUT_FILE):\n"
+      "number of elimination variables in second input file must be "
+      "nonnegative"<<endl;
+    return 0;
+  }
+
+  if(elimination_variables>0)
+  {
+    groebner>>elimination_refinement;
+
+    if(!groebner)
+    {
+      cerr<<"ERROR: int solve(INPUT_FILE, INPUT_FILE):\n"
+        "input failure when reading term ordering \n"
+        "from second input file, input format not accepted"<<endl;
+      return 0;
+    }
+
+    if(strcmp(elimination_refinement,"LEX") &&
+       strcmp(elimination_refinement,"DEG_LEX") &&
+       strcmp(elimination_refinement,"DEG_REV_LEX"))
+    {
+      cerr<<"ERROR: int solve(INPUT_FILE, INPUT_FILE):\n"
+        "unknown elimination ordering in second input file"<<endl;
+      return 0;
+    }
+  }
+
+  groebner>>format_string;
+
+  if(!groebner)
+  {
+    cerr<<"ERROR: int solve(INPUT_FILE, INPUT_FILE):\n"
+      "input failure when reading term ordering \n"
+      "from second input file, input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"weighted"))
+    cerr<<"WARNING: int solve(INPUT_FILE, INPUT_FILE):\n"
+      "second input file has suspicious format"<<endl;
+
+  groebner>>format_string;
+
+  if(!groebner)
+  {
+    cerr<<"ERROR: int solve(INPUT_FILE, INPUT_FILE):\n"
+      "input failure when reading term ordering \n"
+      "from second input file, input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"block"))
+    cerr<<"WARNING: int solve(INPUT_FILE, INPUT_FILE):\n"
+      "second input file has suspicious format"<<endl;
+
+  groebner>>weighted_variables;
+
+  if(!groebner)
+  {
+    cerr<<"ERROR: int solve(INPUT_FILE, INPUT_FILE):\n"
+      "input failure when reading term ordering \n"
+      "from second input file, input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(weighted_variables<=0)
+  {
+    cerr<<"ERROR: int solve(INPUT_FILE, INPUT_FILE):\n"
+      "number of weighted variables in second input file must be "
+      "positive"<<endl;
+    return 0;
+  }
+
+  groebner>>weighted_refinement;
+
+  if(!groebner)
+  {
+    cerr<<"ERROR: int solve(INPUT_FILE, INPUT_FILE):\n"
+      "input failure when reading term ordering \n"
+      "from second input file, input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(weighted_refinement,"W_LEX") &&
+     strcmp(weighted_refinement,"W_REV_LEX") &&
+     strcmp(weighted_refinement,"W_DEG_LEX") &&
+     strcmp(weighted_refinement,"W_DEG_REV_LEX"))
+  {
+    cerr<<"ERROR: int solve(INPUT_FILE, INPUT_FILE):\n"
+      "unknown weighted ordering in second input file"<<endl;
+    return 0;
+  }
+
+  int weighted_ref;
+  if(!strcmp(weighted_refinement,"W_LEX"))
+    weighted_ref=W_LEX;
+  if(!strcmp(weighted_refinement,"W_REV_LEX"))
+    weighted_ref=W_REV_LEX;
+  if(!strcmp(weighted_refinement,"W_DEG_LEX"))
+    weighted_ref=W_DEG_LEX;
+  if(!strcmp(weighted_refinement,"W_DEG_REV_LEX"))
+    weighted_ref=W_DEG_REV_LEX;
+
+  term_ordering w(weighted_variables,groebner,weighted_ref);
+
+  if(w.error_status()<0)
+  {
+    cerr<<"ERROR: int solve(INPUT_FILE, INPUT_FILE):\n"
+      "input failure when reading new cost vector from second input file,\n"
+      "input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(w.is_nonnegative()==FALSE)
+  {
+    cerr<<"ERROR: int solve(INPUT_FILE, INPUT_FILE):\n"
+      "cost vectors with negative components are not supported"<<endl;
+    return 0;
+  }
+
+  if(elimination_variables>0)
+  {
+    int elimination_ref;
+    if(!strcmp(elimination_refinement,"LEX"))
+      elimination_ref=LEX;
+    if(!strcmp(elimination_refinement,"DEG_LEX"))
+      elimination_ref=DEG_LEX;
+    if(!strcmp(elimination_refinement,"DEG_REV_LEX"))
+      elimination_ref=DEG_REV_LEX;
+
+    w.convert_to_elimination_ordering(elimination_variables,elimination_ref);
+
+    if(w.error_status()<0)
+    {
+      cerr<<"ERROR: int solve(INPUT_FILE, INPUT_FILE):\n"
+        "input failure when reading new cost vector from second input file,\n"
+        "input format not accepted"<<endl;
+      return 0;
+    }
+  }
+
+  // read ideal
+
+  groebner>>format_string;
+
+  if(!groebner)
+  {
+    cerr<<"ERROR: int solve(INPUT_FILE, INPUT_FILE):\n"
+      "input failure before reading number of ideal generators \n"
+      "from second input file, input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"size:"))
+    cerr<<"WARNING: int solve(INPUT_FILE, INPUT_FILE):\n"
+      "second input file has suspicious format"<<endl;
+
+  groebner>>size;
+
+  if(!groebner)
+  {
+    cerr<<"ERROR: int solve(INPUT_FILE, INPUT_FILE):\n"
+      "input failure when reading number of ideal generators \n"
+      "from second input file, input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(size<0)
+  {
+    cerr<<"ERROR: int solve(INPUT_FILE, INPUT_FILE):\n"
+      "ideal in second input file is corrupt"<<endl;
+    return 0;
+  }
+
+  groebner>>format_string;
+
+  if(!groebner)
+  {
+    cerr<<"ERROR: int solve(INPUT_FILE, INPUT_FILE):\n"
+      "input failure before reading ideal generators \n"
+      "from second input file, input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"Groebner"))
+    cerr<<"WARNING: int solve(INPUT_FILE, INPUT_FILE):\n"
+      "second input file has suspicious format"<<endl;
+
+  groebner>>format_string;
+
+  if(!groebner)
+  {
+    cerr<<"ERROR: int solve(INPUT_FILE, INPUT_FILE):\n"
+      "input failure before reading ideal generators \n"
+      "from second input file, input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"basis:"))
+    cerr<<"WARNING: int solve(INPUT_FILE, INPUT_FILE):\n"
+      "second input file has suspicious format"<<endl;
+
+  ideal I(groebner,w,size);
+
+  if(!groebner)
+  {
+    cerr<<"ERROR: int solve(INPUT_FILE, INPUT_FILE):\n"
+      "input failure when reading ideal generators from second input file,\n"
+      "input format not accepted."<<endl;
+    return 0;
+  }
+
+  if(I.error_status()<0)
+  {
+    cerr<<"ERROR: int solve(INPUT_FILE, INPUT_FILE):\n"
+      "cannot compute with corrupt ideal\n"<<endl;
+    return 0;
+  }
+
+// read PROBLEM file
+
+  // read format specification
+
+  problem>>format_string;
+
+  if(!problem)
+  {
+    cerr<<"ERROR: int solve(INPUT_FILE, INPUT_FILE):\n"
+      "input failure when reading format specification of first input file,\n"
+      "input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"PROBLEM"))
+    cerr<<"WARNING: int solve(INPUT_FILE, INPUT_FILE):\n"
+      "first input file has suspicious format"<<endl;
+
+  // read vector dimension
+
+  problem>>format_string;
+
+  if(!problem)
+  {
+    cerr<<"ERROR: int solve(INPUT_FILE, INPUT_FILE):\n"
+      "input failure before reading vector dimension from first input file,\n"
+      "input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"vector"))
+    cerr<<"WARNING: int solve(INPUT_FILE, INPUT_FILE):\n"
+      "first input file has suspicious format"<<endl;
+
+  problem>>format_string;
+
+  if(!problem)
+  {
+    cerr<<"ERROR: int solve(INPUT_FILE, INPUT_FILE):\n"
+      "input failure before reading vector dimension from first input file,\n"
+      "input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"size:"))
+    cerr<<"WARNING: int solve(INPUT_FILE, INPUT_FILE):\n"
+      "first input file has suspicious format"<<endl;
+
+  problem>>problem_variables;
+
+  if(!problem)
+  {
+    cerr<<"ERROR: int solve(INPUT_FILE, INPUT_FILE):\n"
+      "input failure when reading vector dimension from first input file,\n"
+      "input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(problem_variables<=0)
+  {
+    cerr<<"ERROR: int solve(INPUT_FILE, INPUT_FILE):\n"
+      "vector dimension in first input file must be positive"<<endl;
+    return 0;
+  }
+
+  // consistency with respect to the number of variables is checked later
+
+  // read number of instances
+
+  problem>>format_string;
+
+  if(!problem)
+  {
+    cerr<<"ERROR: int solve(INPUT_FILE, INPUT_FILE):\n"
+      "input failure before reading number of instances from first input file,"
+      "\n"
+      "input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"number"))
+    cerr<<"WARNING: int solve(INPUT_FILE, INPUT_FILE):\n"
+      "first input file has suspicious format"<<endl;
+
+  problem>>format_string;
+
+  if(!problem)
+  {
+    cerr<<"ERROR: int solve(INPUT_FILE, INPUT_FILE):\n"
+      "input failure before reading number of instances from first input file,"
+      "\n"
+      "input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"of"))
+    cerr<<"WARNING: int solve(INPUT_FILE, INPUT_FILE):\n"
+      "first input file has suspicious format"<<endl;
+
+  problem>>format_string;
+
+  if(!problem)
+  {
+    cerr<<"ERROR: int solve(INPUT_FILE, INPUT_FILE):\n"
+      "input failure before reading number of instances from first input file,"
+      "\n"
+      "input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"instances:"))
+    cerr<<"WARNING: int solve(INPUT_FILE, INPUT_FILE):\n"
+      "first input file has suspicious format"<<endl;
+
+  problem>>instances;
+
+  if(!problem)
+  {
+    cerr<<"ERROR: int solve(INPUT_FILE, INPUT_FILE):\n"
+      "input failure when reading number of instances from first input file,\n"
+      "input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(instances<=0)
+  {
+    cerr<<"WARNING: int solve(INPUT_FILE, INPUT_FILE):\n"
+      "number of instances is <1, no output file created"<<endl;
+    return 1;
+    // no error
+  }
+
+  // read problem vectors (first part)
+
+  problem>>format_string;
+
+  if(!problem)
+  {
+    cerr<<"ERROR: int solve(INPUT_FILE, INPUT_FILE):\n"
+      "input failure before reading right hand / initial solution vectors \n"
+      "from first input file, input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"right"))
+    cerr<<"WARNING: int solve(INPUT_FILE, INPUT_FILE):\n"
+      "first input file has suspicious format"<<endl;
+
+  problem>>format_string;
+
+  if(!problem)
+  {
+    cerr<<"ERROR: int solve(INPUT_FILE, INPUT_FILE):\n"
+      "input failure before reading right hand / initial solution vectors \n"
+      "from first input file, input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"hand"))
+    cerr<<"WARNING: int solve(INPUT_FILE, INPUT_FILE):\n"
+      "first input file has suspicious format"<<endl;
+
+  problem>>format_string;
+
+  if(!problem)
+  {
+    cerr<<"ERROR: int solve(INPUT_FILE, INPUT_FILE):\n"
+      "input failure before reading right hand / initial solution vectors \n"
+      "from first input file, input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"or"))
+    cerr<<"WARNING: int solve(INPUT_FILE, INPUT_FILE):\n"
+      "first input file has suspicious format"<<endl;
+
+  problem>>format_string;
+
+  if(!problem)
+  {
+    cerr<<"ERROR: int solve(INPUT_FILE, INPUT_FILE):\n"
+      "input failure before reading right hand / initial solution vectors \n"
+      "from first input file, input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"initial"))
+    cerr<<"WARNING: int solve(INPUT_FILE, INPUT_FILE):\n"
+      "first input file has suspicious format"<<endl;
+
+  problem>>format_string;
+
+  if(!problem)
+  {
+    cerr<<"ERROR: int solve(INPUT_FILE, INPUT_FILE):\n"
+      "input failure before reading right hand / initial solution vectors \n"
+      "from first input file, input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"solution"))
+    cerr<<"WARNING: int solve(INPUT_FILE, INPUT_FILE):\n"
+      "first input file has suspicious format"<<endl;
+
+  problem>>format_string;
+
+  if(!problem)
+  {
+    cerr<<"ERROR: int solve(INPUT_FILE, INPUT_FILE):\n"
+      "input failure before reading right hand / initial solution vectors \n"
+      "from first input file, input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"vectors:"))
+    cerr<<"WARNING: int solve(INPUT_FILE, INPUT_FILE):\n"
+      "first input file has suspicious format"<<endl;
+
+  // the vectors are read in the section "computation" because we need to
+  // distinguish between the different algorithms
+
+
+//////////////////// output (first part) ///////////////////////////////////
+
+  // open output file (append mode)
+
+  char SOLUTION[128];
+
+  int i=0;
+  while(GROEBNER[i]!='\0' && GROEBNER[i]!='.')
+  {
+    SOLUTION[i]=GROEBNER[i];
+    i++;
+  }
+  SOLUTION[i]='\0';
+  strcat(SOLUTION,".sol.");
+  strcat(SOLUTION,algorithm);
+
+  ofstream output(SOLUTION,ios::app);
+
+  // format output file
+
+  output.flags(output.flags()|ios::fixed);
+  // output of fixed point numbers
+
+  output<<"SOLUTION"<<endl<<endl;
+
+  output<<"computed with algorithm:"<<endl;
+  output<<algorithm<<endl;
+  output<<"from file:"<<endl;
+  output<<GROEBNER<<endl;
+
+
+/////////// computation and output (second part) //////////////////////////
+
+  // distinguish 3 cases to verifie the consistency of the vector dimension
+  // and the number of variables
+
+  // Conti-Traverso: vectors are read as right hand vectors
+  // vector dimension = number of elimination variables without inversion
+  // variable
+  if(!strcmp(algorithm,"ct"))
+  {
+    if(problem_variables!=elimination_variables-1)
+    {
+      cerr<<"ERROR: int solve(INPUT_FILE, INPUT_FILE):\n"
+        "vector dimension in first input file and number of variables in\n"
+        "second input file do not match with respect to the\n"
+        "Conti-Traverso-algorithm"<<endl;
+      return 0;
+    }
+
+    Integer right_hand[weighted_variables+elimination_variables];
+
+    for(int k=0;k<instances;k++)
+    {
+      // at the beginning, the variables of interest are zero
+      for(i=0;i<weighted_variables;i++)
+        right_hand[i]=0;
+
+      // right hand vector is read from the input stream into the
+      // elimination variables
+      for(i=weighted_variables;
+          i<weighted_variables+elimination_variables-1;i++)
+      {
+        problem>>right_hand[i];
+
+        if(!problem)
+        {
+          cerr<<"ERROR: int solve(INPUT_FILE, INPUT_FILE):\n"
+            "input failure when reading right hand vector "<<k+1<<" from "
+            "first input \nfile, "
+            "this and all following right hand vectors will be ignored"<<endl;
+          return 0;
+        }
+      }
+
+      // determine the exponent of the inversion variable, i.e.
+      // - min{negative components of right_hand}.
+      Integer min=0;
+      for(i=weighted_variables;
+          i<weighted_variables+elimination_variables-1;i++)
+        if(right_hand[i]<min)
+          min=right_hand[i];
+
+      // transform right_hand so that all components are nonnegative
+      if(min<0)
+        for(i=weighted_variables;
+            i<weighted_variables+elimination_variables-1;i++)
+          right_hand[i]-=min;
+
+      // set exponent of the inversion variable
+      right_hand[weighted_variables+elimination_variables-1]=-min;
+
+      // construct binomial to reduce
+      binomial to_reduce(weighted_variables+elimination_variables,right_hand);
+
+      // prepare time measurement
+      clock_t start, end;
+
+      // reduce binomial
+      start=clock();
+      I.reduce(to_reduce,TRUE);
+      end=clock();
+
+      // time measurement
+      float elapsed=((float) (end-start))/CLOCKS_PER_SEC;
+
+      // output
+
+      output<<"right hand vector:"<<endl;
+      for(i=weighted_variables;
+          i<weighted_variables+elimination_variables-1;i++)
+        output<<setw(6)<<right_hand[i]+min;
+        // original vector
+      output<<endl;
+
+      output<<"solvable:"<<endl;
+
+      BOOLEAN solvable=TRUE;
+      for(i=weighted_variables;
+          i<=weighted_variables+elimination_variables-1;i++)
+        if(to_reduce[i]!=0)
+        {
+          solvable=FALSE;
+          break;
+        }
+
+      if(solvable==TRUE)
+      {
+        output<<"YES"<<endl;
+        output<<"optimal solution:"<<endl;
+        for(i=0;i<weighted_variables;i++)
+          output<<setw(6)<<to_reduce[i];
+        output<<endl;
+      }
+      else
+        output<<"NO"<<endl;
+
+      output<<"computation time"<<endl;
+      output<<setw(6)<<setprecision(2)<<elapsed<<" sec"<<endl<<endl;
+    }
+  }
+
+  else
+    // Positive Conti-Traverso: vectors are read as right hand vectors
+    // vector dimension = number of elimination variables
+    if(!strcmp(algorithm,"pct"))
+    {
+      if(problem_variables!=elimination_variables)
+      {
+        cerr<<"ERROR: int solve(INPUT_FILE, INPUT_FILE):\n"
+          "vector dimension in first input file and number of variables in\n"
+          "second input file do not match with respect to the\n"
+          "Positive Conti-Traverso algorithm"<<endl;
+        return 0;
+      }
+
+      Integer right_hand[weighted_variables+elimination_variables];
+      BOOLEAN error=FALSE;    // to test legality of right hand vectors
+
+      for(int k=0;k<instances;k++)
+      {
+        // at the beginning, the variables of interest are zero
+        for(i=0;i<weighted_variables;i++)
+          right_hand[i]=0;
+
+        // right hand vector is read from the input stream into the
+        // elimination variables
+        for(i=weighted_variables;
+            i<weighted_variables+elimination_variables;i++)
+        {
+          problem>>right_hand[i];
+
+          if(!problem)
+          {
+            cerr<<"ERROR: int solve(INPUT_FILE, INPUT_FILE):\n"
+              "input failure when reading right hand vector "<<k+1<<" from "
+              "first input \nfile, this and all following right hand vectors "
+              "will be ignored"<<endl;
+            return 0;
+          }
+
+          if(right_hand[i]<0)
+          {
+            cerr<<"ERROR: int solve(INPUT_FILE, INPUT_FILE):\n"
+              "right hand vectors with negative components cannot be handled\n"
+              "by the Positive Conti-Traverso algorithm,\n"
+              "right hand vector "<<k+1<<" will be ignored"<<endl;
+            error=TRUE;
+          }
+        }
+
+        if(error==TRUE)
+        {
+          error=FALSE;
+          continue;
+          // for-loop
+        }
+
+        // construct binomial to reduce
+        binomial to_reduce(weighted_variables+elimination_variables,
+                           right_hand);
+
+        // prepare time measurement
+        clock_t start, end;
+
+        // reduce binomial
+        start=clock();
+        I.reduce(to_reduce,TRUE);
+        end=clock();
+
+        // time measurement
+        float elapsed=((float) (end-start))/CLOCKS_PER_SEC;
+
+        // output
+
+        output<<"right hand vector:"<<endl;
+        for(i=weighted_variables;
+            i<weighted_variables+elimination_variables;i++)
+          output<<setw(6)<<right_hand[i];
+        // original vector
+        output<<endl;
+
+        output<<"solvable:"<<endl;
+
+        BOOLEAN solvable=TRUE;
+        for(i=weighted_variables;
+            i<weighted_variables+elimination_variables;i++)
+          if(to_reduce[i]!=0)
+          {
+            solvable=FALSE;
+            break;
+          }
+
+        if(solvable==TRUE)
+        {
+          output<<"YES"<<endl;
+          output<<"optimal solution:"<<endl;
+          for(i=0;i<weighted_variables;i++)
+            output<<setw(6)<<to_reduce[i];
+          output<<endl;
+        }
+        else
+          output<<"NO"<<endl;
+
+        output<<"computation time"<<endl;
+        output<<setw(6)<<setprecision(2)<<elapsed<<" sec"<<endl<<endl;
+      }
+    }
+
+    else
+      // other algorithms: vectors are read as initial solutions
+      // vector dimension = number of weighted variables
+    {
+      if(problem_variables!=weighted_variables)
+      {
+        cerr<<"ERROR: int solve(INPUT_FILE, INPUT_FILE):\n"
+          "vector dimension in first input file and number of variables in\n"
+          "second input file do not match with respect to the\n"
+          "chosen algorithm"<<endl;
+        return 0;
+      }
+
+      Integer initial_solution[weighted_variables];
+
+      for(int k=0;k<instances;k++)
+      {
+        // initial solution vector is read from the input stream into the
+        // elimination variables
+        for(i=0;i<weighted_variables;i++)
+        {
+          problem>>initial_solution[i];
+
+          if(!problem)
+          {
+            cerr<<"ERROR: int solve(INPUT_FILE, INPUT_FILE):\n"
+              "input failure when reading right hand vector "<<k+1<<" from "
+              "first input \nfile, this and all following right hand vectors "
+              "will be ignored"<<endl;
+            return 0;
+          }
+
+          if(initial_solution[i]<0)
+            cerr<<"WARNING: int solve(INPUT_FILE, INPUT_FILE):\n"
+              "initial solution vectors should be nonnegative"<<endl;
+        }
+
+        // construct binomial to reduce
+        binomial to_reduce(weighted_variables,initial_solution);
+
+        // prepare time measurement
+        clock_t start, end;
+
+        // reduce binomial
+        start=clock();
+        I.reduce(to_reduce,TRUE);
+        end=clock();
+
+        // time measurement
+        float elapsed=((float) (end-start))/CLOCKS_PER_SEC;
+
+        // output
+
+        output<<"initial solution vector:"<<endl;
+        for(i=0;i<weighted_variables;i++)
+          output<<setw(6)<<initial_solution[i];
+        // original vector
+        output<<endl;
+
+        output<<"optimal solution:"<<endl;
+        for(i=0;i<weighted_variables;i++)
+          output<<setw(6)<<to_reduce[i];
+        output<<endl;
+
+        output<<"computation time"<<endl;
+        output<<setw(6)<<setprecision(2)<<elapsed<<" sec"<<endl<<endl;
+      }
+    }
+
+  return 1;
+
+}
+
+
+
+////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////
+
+
+
+
+int change_cost(INPUT_FILE GROEBNER, INPUT_FILE NEW_COST,
+                const int& version,
+                const int& S_pair_criteria,
+                const float& interred_percentage,
+                const BOOLEAN& verbose)
+{
+
+  char format_string[128];
+  int elimination_variables;
+  int weighted_variables;
+  char elimination_refinement[128];
+  char weighted_refinement[128];
+  int new_variables;
+  char algorithm[128];
+  long old_size;
+
+  ifstream old(GROEBNER);
+  ifstream _new(NEW_COST);
+
+  // verifie existence of files
+
+  if(!old)
+  {
+    cerr<<"ERROR: int change_cost(INPUT_FILE, INPUT_FILE):\n"
+      "cannot read from first input file, possibly not found"<<endl;
+    return 0;
+  }
+
+  if(!_new)
+  {
+    cerr<<"ERROR: int change_cost(INPUT_FILE, INPUT_FILE):\n"
+      "cannot read from second input file, possibly not found"<<endl;
+    return 0;
+  }
+
+
+// read first part of GROEBNER file (until term ordering reached)
+
+  // read format specification
+
+  old>>format_string;
+
+  if(!old)
+  {
+    cerr<<"ERROR: int change_cost(INPUT_FILE, INPUT_FILE):\n"
+      "input failure when reading format specification of first input file,\n"
+      "input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"GROEBNER"))
+  {
+    cerr<<"WARNING: int change_cost(INPUT_FILE, INPUT_FILE):\n"
+      "first input file has suspicious format"<<endl;
+  }
+
+  // read algorithm
+
+  old>>format_string;
+
+  if(!old)
+  {
+    cerr<<"ERROR: int change_cost(INPUT_FILE, INPUT_FILE):\n"
+      "input failure before reading algorithm from first input file,\n"
+      "input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"computed"))
+  {
+    cerr<<"WARNING: int change_cost(INPUT_FILE, INPUT_FILE):\n"
+      "first input file has suspicious format"<<endl;
+  }
+
+  old>>format_string;
+
+  if(!old)
+  {
+    cerr<<"ERROR: int change_cost(INPUT_FILE, INPUT_FILE):\n"
+      "input failure before reading algorithm from first input file,\n"
+      "input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"with"))
+  {
+    cerr<<"WARNING: int change_cost(INPUT_FILE, INPUT_FILE):\n"
+      "first input file has suspicious format"<<endl;
+  }
+
+  old>>format_string;
+
+  if(!old)
+  {
+    cerr<<"ERROR: int change_cost(INPUT_FILE, INPUT_FILE):\n"
+      "input failure before reading algorithm from first input file,\n"
+      "input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"algorithm:"))
+  {
+    cerr<<"WARNING: int change_cost(INPUT_FILE, INPUT_FILE):\n"
+      "first input file has suspicious format"<<endl;
+  }
+
+  old>>algorithm;
+
+  if(!old)
+  {
+    cerr<<"ERROR: int change_cost(INPUT_FILE, INPUT_FILE):\n"
+      "input failure when reading algorithm from first input file,\n"
+      "input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(algorithm,"ct") && strcmp(algorithm,"pct") &&
+     strcmp(algorithm,"ect") && strcmp(algorithm,"pt") &&
+     strcmp(algorithm,"hs") && strcmp(algorithm,"du")
+     && strcmp(algorithm,"blr"))
+  {
+    cerr<<"WARNING: int change_cost(INPUT_FILE, INPUT_FILE):\n"
+      "first input file computed with unknown algorithm"<<endl;
+  }
+
+  // override optional lines
+
+  do
+  {
+    old>>format_string;
+
+    if(!old)
+    {
+      cerr<<"ERROR: int change_cost(INPUT_FILE, INPUT_FILE):\n"
+        "input failure before reading term ordering from first \n"
+        "input file, input format not accepted"<<endl;
+      return 0;
+    }
+  }
+  while(strcmp(format_string,"term"));
+
+  // read term ordering
+
+  old>>format_string;
+
+  if(!old)
+  {
+    cerr<<"ERROR: int change_cost(INPUT_FILE, INPUT_FILE):\n"
+      "input failure before reading term ordering \n"
+      "from first input file, input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"ordering:"))
+  {
+    cerr<<"WARNING: int change_cost(INPUT_FILE, INPUT_FILE):\n"
+      "first input file has suspicious format"<<endl;
+  }
+
+  old>>format_string;
+
+  if(!old)
+  {
+    cerr<<"ERROR: int change_cost(INPUT_FILE, INPUT_FILE):\n"
+      "input failure when reading term ordering \n"
+      "from first input file, input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"elimination"))
+  {
+    cerr<<"WARNING: int change_cost(INPUT_FILE, INPUT_FILE):\n"
+      "first input file has suspicious format"<<endl;
+  }
+
+  old>>format_string;
+
+  if(!old)
+  {
+    cerr<<"ERROR: int change_cost(INPUT_FILE, INPUT_FILE):\n"
+      "input failure when reading term ordering \n"
+      "from first input file, input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"block"))
+  {
+    cerr<<"WARNING: int change_cost(INPUT_FILE, INPUT_FILE):\n"
+      "first input file has suspicious format"<<endl;
+  }
+
+  old>>elimination_variables;
+
+  if(!old)
+  {
+    cerr<<"ERROR: int change_cost(INPUT_FILE, INPUT_FILE):\n"
+      "input failure when reading term ordering \n"
+      "from first input file, input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(elimination_variables<0)
+  {
+    cerr<<"ERROR: int change_cost(INPUT_FILE, INPUT_FILE):\n"
+      "number of elimination variables in first input file must be "
+      "nonnegative"<<endl;
+    return 0;
+  }
+
+  if(elimination_variables>0)
+  {
+    old>>elimination_refinement;
+
+    if(!old)
+    {
+      cerr<<"ERROR: int change_cost(INPUT_FILE, INPUT_FILE):\n"
+        "input failure when reading term ordering \n"
+        "from first input file, input format not accepted"<<endl;
+      return 0;
+    }
+
+    if(strcmp(elimination_refinement,"LEX") &&
+       strcmp(elimination_refinement,"DEG_LEX") &&
+       strcmp(elimination_refinement,"DEG_REV_LEX"))
+    {
+      cerr<<"ERROR: int change_cost(INPUT_FILE, INPUT_FILE):\n"
+        "unknown elimination ordering in first input file"<<endl;
+      return 0;
+    }
+  }
+
+  old>>format_string;
+
+  if(!old)
+  {
+    cerr<<"ERROR: int change_cost(INPUT_FILE, INPUT_FILE):\n"
+      "input failure when reading term ordering \n"
+      "from first input file, input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"weighted"))
+  {
+    cerr<<"WARNING: int change_cost(INPUT_FILE, INPUT_FILE):\n"
+      "first input file has suspicious format"<<endl;
+  }
+
+  old>>format_string;
+
+  if(!old)
+  {
+    cerr<<"ERROR: int change_cost(INPUT_FILE, INPUT_FILE):\n"
+      "input failure when reading term ordering \n"
+      "from first input file, input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"block"))
+  {
+    cerr<<"WARNING: int change_cost(INPUT_FILE, INPUT_FILE):\n"
+      "first input file has suspicious format"<<endl;
+  }
+
+  old>>weighted_variables;
+
+  if(!old)
+  {
+    cerr<<"ERROR: int change_cost(INPUT_FILE, INPUT_FILE):\n"
+      "input failure when reading term ordering \n"
+      "from first input file, input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(weighted_variables<=0)
+  {
+    cerr<<"ERROR: int change_cost(INPUT_FILE, INPUT_FILE):\n"
+      "number of weighted variables in first input file must be "
+      "positive"<<endl;
+    return 0;
+  }
+
+  old>>weighted_refinement;
+
+  if(!old)
+  {
+    cerr<<"ERROR: int change_cost(INPUT_FILE, INPUT_FILE):\n"
+      "input failure when reading term ordering \n"
+      "from first input file, input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(weighted_refinement,"W_LEX") &&
+     strcmp(weighted_refinement,"W_REV_LEX") &&
+     strcmp(weighted_refinement,"W_DEG_LEX") &&
+     strcmp(weighted_refinement,"W_DEG_REV_LEX"))
+  {
+    cerr<<"ERROR: int change_cost(INPUT_FILE, INPUT_FILE):\n"
+      "unknown weighted ordering in first input file"<<endl;
+    return 0;
+  }
+
+// read NEW_COST file
+
+  // read format specification
+
+  _new>>format_string;
+
+  if(!_new)
+  {
+    cerr<<"ERROR: int change_cost(INPUT_FILE, INPUT_FILE):\n"
+      "input failure when reading format specification\n"
+      "from second input file, input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"MATRIX") && strcmp(format_string,"NEW_COST"))
+  {
+    cerr<<"WARNING: int change_cost(INPUT_FILE, INPUT_FILE):\n"
+      "second input file has suspicious format"<<endl;
+  }
+
+  // read number of variables
+
+  _new>>format_string;
+
+  if(!_new)
+  {
+    cerr<<"ERROR: int change_cost(INPUT_FILE, INPUT_FILE):\n"
+      "input failure before reading number of variables \n"
+      "from second input file, input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"columns:") && strcmp(format_string,"variables:"))
+    cerr<<"WARNING: int change_cost(INPUT_FILE, INPUT_FILE):\n"
+      "second input file has suspicious format"<<endl;
+
+  _new>>new_variables;
+
+  if(!_new)
+  {
+    cerr<<"ERROR: int change_cost(INPUT_FILE, INPUT_FILE):\n"
+      "input failure when reading number of variables \n"
+      "from second input file, input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(new_variables<=0)
+  {
+    cerr<<"ERROR: int change_cost(INPUT_FILE, INPUT_FILE):\n"
+      "number of variables in second input file must be positve"<<endl;
+    return 0;
+  }
+
+  // Now we can verifie consistency of both files with respect to the number
+  // of weighted variables:
+
+  if(weighted_variables!=new_variables)
+  {
+    cerr<<"ERROR: int change_cost(INPUT_FILE, INPUT_FILE):\n"
+      "number of variables in first and second input file do not match"<<endl;
+    return 0;
+  }
+
+  // read term ordering
+
+  _new>>format_string;
+
+  if(!_new)
+  {
+    cerr<<"ERROR: int change_cost(INPUT_FILE, INPUT_FILE):\n"
+      "input failure before reading new cost vector from second input file,\n"
+      "input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"cost"))
+    cerr<<"WARNING: int change_cost(INPUT_FILE, INPUT_FILE):\n"
+      "second input file has suspicious format"<<endl;
+
+  _new>>format_string;
+
+  if(!_new)
+  {
+    cerr<<"ERROR: int change_cost(INPUT_FILE, INPUT_FILE):\n"
+      "input failure before reading new cost vector from second input file,\n"
+      "input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"vector:"))
+    cerr<<"WARNING: int change_cost(INPUT_FILE, INPUT_FILE):\n"
+      "second input file has suspicious format"<<endl;
+
+  // the term ordering to refine the weight is taken to be the same as that
+  // for the old Groebner basis
+  int weighted_ref;
+  if(!strcmp(weighted_refinement,"W_LEX"))
+    weighted_ref=W_LEX;
+  if(!strcmp(weighted_refinement,"W_REV_LEX"))
+    weighted_ref=W_REV_LEX;
+  if(!strcmp(weighted_refinement,"W_DEG_LEX"))
+    weighted_ref=W_DEG_LEX;
+  if(!strcmp(weighted_refinement,"W_DEG_REV_LEX"))
+    weighted_ref=W_DEG_REV_LEX;
+
+  term_ordering w(weighted_variables,_new,weighted_ref);
+
+  if(w.error_status()<0)
+  {
+    cerr<<"ERROR: int change_cost(INPUT_FILE, INPUT_FILE):\n"
+      "input failure when reading new cost vector from second input file,\n"
+      "input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(w.is_nonnegative()==FALSE)
+  {
+    cerr<<"ERROR: int change_cost(INPUT_FILE, INPUT_FILE):\n"
+      "cost vectors with negative components are not supported"<<endl;
+    return 0;
+  }
+
+  if(elimination_variables>0)
+  {
+    int elimination_ref;
+    if(!strcmp(elimination_refinement,"LEX"))
+      elimination_ref=LEX;
+    if(!strcmp(elimination_refinement,"DEG_LEX"))
+      elimination_ref=DEG_LEX;
+    if(!strcmp(elimination_refinement,"DEG_REV_LEX"))
+      elimination_ref=DEG_REV_LEX;
+    w.convert_to_elimination_ordering(elimination_variables,elimination_ref);
+
+    if(w.error_status()<0)
+    {
+      cerr<<"ERROR: int change_cost(INPUT_FILE, INPUT_FILE):\n"
+        "input failure when reading new cost vector from second input file,\n"
+        "input format not accepted"<<endl;
+      return 0;
+    }
+  }
+
+// read second part of the GROEBNER file
+
+  // override old weight vector
+
+  do
+  {
+    old>>format_string;
+
+    if(!old)
+    {
+      cerr<<"ERROR: int change_cost(INPUT_FILE, INPUT_FILE):\n"
+        "input failure before reading number of ideal generators \n"
+        "from first input file, input format not accepted"<<endl;
+      return 0;
+    }
+  }
+  while(strcmp(format_string,"size:"));
+
+  // read old Groebner basis
+
+  old>>old_size;
+
+  if(!old)
+  {
+    cerr<<"ERROR: int change_cost(INPUT_FILE, INPUT_FILE):\n"
+      "input failure when reading number of ideal generators \n"
+      "from first input file, input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(old_size<=0)
+  {
+    cerr<<"ERROR: int change_cost(INPUT_FILE, INPUT_FILE):\n"
+      "ideal in first input file is corrupt"<<endl;
+    return 0;
+  }
+
+  old>>format_string;
+
+  if(!old)
+  {
+    cerr<<"ERROR: int change_cost(INPUT_FILE, INPUT_FILE):\n"
+      "input failure before reading ideal generators \n"
+      "from first input file, input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"Groebner"))
+  {
+    cerr<<"WARNING: int change_cost(INPUT_FILE, INPUT_FILE):\n"
+      "first input file has suspicious format"<<endl;
+  }
+
+  old>>format_string;
+
+  if(!old)
+  {
+    cerr<<"ERROR: int change_cost(INPUT_FILE, INPUT_FILE):\n"
+      "input failure before reading ideal generators \n"
+      "from first input file, input format not accepted"<<endl;
+    return 0;
+  }
+
+  if(strcmp(format_string,"basis:"))
+  {
+    cerr<<"WARNING: int change_cost(INPUT_FILE, INPUT_FILE):\n"
+      "first input file has suspicious format"<<endl;
+  }
+
+  // read ideal generators from first input file, already with respect to
+  // the new term ordering
+  ideal I(old,w,old_size);
+
+  if(!old)
+  {
+    cerr<<"ERROR: int change_cost(INPUT_FILE, INPUT_FILE):\n"
+      "input failure when reading ideal generators from first input file,\n"
+      "input format not accepted."<<endl;
+    return 0;
+  }
+
+  if(I.error_status()<0)
+  {
+    cerr<<"ERROR: int change_cost(INPUT_FILE, INPUT_FILE):\n"
+      "cannot compute with corrupt ideal\n"<<endl;
+    return 0;
+  }
+
+
+///////////////////////// computation ////////////////////////////////////////
+
+  // prepare time measurement
+  clock_t start, end;
+
+  // compute new Groebner basis
+  start=clock();
+  I.reduced_Groebner_basis(version,S_pair_criteria,interred_percentage);
+  end=clock();
+
+  // time measurement
+  float elapsed=((float) (end-start))/CLOCKS_PER_SEC;
+
+
+///////////////////////// output ////////////////////////////////////////////
+
+  // create output file
+
+  char NEW_GROEBNER[128];
+
+  int i=0;
+  while(NEW_COST[i]!='\0' && NEW_COST[i]!='.')
+  {
+    NEW_GROEBNER[i]=NEW_COST[i];
+    i++;
+  }
+  NEW_GROEBNER[i]='\0';
+  strcat(NEW_GROEBNER,".GB.");
+  strcat(NEW_GROEBNER,algorithm);
+
+  ofstream output(NEW_GROEBNER);
+
+  // format output file
+
+  output.flags(output.flags()|ios::fixed);
+  // output of fixed point numbers
+
+  output<<"GROEBNER"<<endl<<endl;
+
+  output<<"computed with algorithm:"<<endl;
+  output<<algorithm<<endl;
+  output<<"from file(s):"<<endl;
+  output<<GROEBNER<<", "<<NEW_COST<<endl;
+  output<<"computation time"<<endl;
+  output<<setw(6)<<setprecision(2)<<elapsed<<" sec"<<endl<<endl;
+
+  output<<"term ordering:"<<endl;
+  output<<"elimination block"<<endl;
+  // elimination variables
+  output<<elimination_variables<<endl;
+  if(elimination_variables>0)
+    output<<elimination_refinement<<endl;
+  output<<"weighted block"<<endl;
+  // weighted variables (>0)
+  output<<weighted_variables<<endl;
+  output<<weighted_refinement<<endl;
+  w.format_print_weight_vector(output);
+
+  output<<"size:"<<endl;
+  output<<I.number_of_generators()<<endl<<endl;
+
+  output<<"Groebner basis:"<<endl;
+  I.format_print(output);
+  output<<endl;
+
+  if(verbose==TRUE)
+  {
+    output<<"settings for the Buchberger algorithm:"<<endl;
+
+    output<<"version:"<<endl;
+    if(version==0)
+      output<<"1a"<<endl;
+    else
+      output<<version<<endl;
+
+    output<<"S-pair criteria:"<<endl;
+    if(S_pair_criteria & REL_PRIMENESS)
+      output<<"relatively prime leading terms"<<endl;
+    if(S_pair_criteria & M_CRITERION)
+      output<<"criterion M"<<endl;
+    if(S_pair_criteria & F_CRITERION)
+      output<<"criterion F"<<endl;
+    if(S_pair_criteria & B_CRITERION)
+      output<<"criterion B"<<endl;
+    if(S_pair_criteria & SECOND_CRITERION)
+      output<<"second criterion"<<endl;
+    output<<endl;
+
+    print_flags(output);
+    output<<endl;
+  }
+
+  return 1;
+}
+
+#endif // IP_ALGORITHMS_CC
diff --git a/IntegerProgramming/IP_algorithms.h b/IntegerProgramming/IP_algorithms.h
new file mode 100644
index 0000000..70db8e4
--- /dev/null
+++ b/IntegerProgramming/IP_algorithms.h
@@ -0,0 +1,296 @@
+// IP_algorithms.h
+
+#ifndef IP_ALGORITHMS_H
+#define IP_ALGORITHMS_H
+
+#include "ideal.h"
+
+typedef char* INPUT_FILE;
+typedef char* OUTPUT_FILE;
+
+// This file contains the declaration of all implemented IP-algorithms.
+// They only solve problems for nonnegative weight vectors.
+
+// Let A an integral (mxn)-matrix, b a vector with m integral
+// coefficients and c a vector with n nonnegative real coefficients.
+// The solution of the IP-problem
+//
+//    minimize cx
+//    under the conditions
+//             Ax=b and all components of x are nonnegative integers
+//
+// proceeds in two steps:
+
+// First, we have to compute the toric ideal of A and its Groebner basis
+// with respect to a term ordering refining the cost function c. This can
+// be done by the following procedures. They check the format of their input
+// file (which should be a MATRIX file as described below) and return 1 if
+// they were successfull, 0 else.
+//  They take as arguments:
+// - their input file
+// - the arguments for Buchberger�s algorithm (see the comments in ideal.h)
+// - the output mode (verbose or not, default: not verbose; verbose mode
+//   prints compiler settings and options for Buchberger�s algorithm)
+// The last four arguments have default values and do not have to be
+// specified.
+
+// In the case of a successful computation, they write the computed Groebner
+// basis into a GROEBNER file which is named as the input file with extension
+// replaced by
+//      .GB.<alg>
+// where <alg> is an abbreviation for the used algorithm:
+//         ct     for Conti_Traverso(...)
+//        pct     for Positive_Conti_Traverso(...)
+//        ect     for Elim_Conti_Traverso(...)
+//         pt     for Pottier(...)
+//         hs     for Hosten_Sturmfels(...)
+//         du     for DiBiase_Urbanke(...)
+//        blr     for Bigatti_LaScala_Robbiano(...)
+
+extern int Conti_Traverso(INPUT_FILE MATRIX,
+                          const int& version=1,
+                          const int& S_pair_criteria=11,
+                          const float& interred_percentage=12.0,
+                          const BOOLEAN& verbose=FALSE);
+// The complete algorithm of Conti and Traverso which computes the toric
+// ideal of an extended matrix and which can be used for solving
+// integer programs without initial solution.
+
+extern int Positive_Conti_Traverso(INPUT_FILE MATRIX,
+                                   const int& version=1,
+                                   const int& S_pair_criteria=11,
+                                   const float& interred_percentage=12.0,
+                                   const BOOLEAN& verbose=FALSE);
+// The variant of the above algorithm for matrices and right hand vector
+// with only nonnegative entries using one elimination variable less.
+
+extern int Elim_Conti_Traverso(INPUT_FILE MATRIX,
+                               const int& version=1,
+                               const int& S_pair_criteria=11,
+                               const float& interred_percentage=12.0,
+                               const BOOLEAN& verbose=FALSE);
+// A version of the Conti-Traverso-algorithm which really computes the toric
+// ideal of A. Used for test purposes (correctness and performance of the
+// other algorithms). Nonnegativity is ignored.
+
+extern int Pottier(INPUT_FILE MATRIX,
+                   const int& version=1,
+                   const int& S_pair_criteria=11,
+                   const float& interred_percentage=12.0,
+                   const BOOLEAN& verbose=FALSE);
+// The algorithm proposed by Pottier using one elimination variable and
+// a lattice basis of the matrix kernel to compute the toric ideal A.
+
+extern int Hosten_Sturmfels(INPUT_FILE MATRIX,
+                            const int& version=1,
+                            const int& S_pair_criteria=11,
+                            const float& interred_percentage=12.0,
+                            const BOOLEAN& verbose=FALSE);
+// The algorithm proposed by Hosten and Sturmfels which computes the toric
+// ideal of A from its kernel lattice basis without supplementary
+// variables, but with various Groebner basis calculations.
+
+extern int DiBiase_Urbanke(INPUT_FILE MATRIX,
+                           const int& version=1,
+                           const int& S_pair_criteria=11,
+                           const float& interred_percentage=12.0,
+                           const BOOLEAN& verbose=FALSE);
+// The algorithm proposed by DiBiase and Urbanke which computes the toric
+// ideal of A from its kernel lattice basis using "variable flips".
+
+extern int Bigatti_LaScala_Robbiano(INPUT_FILE MATRIX,
+                                    const int& version=1,
+                                    const int& S_pair_criteria=11,
+                                    const float& interred_percentage=12.0,
+                                    const BOOLEAN& verbose=FALSE);
+// A modified version of the algorithm called EATI using "pseudo-elimination".
+// This algorithm is quite similar to Pottier's algorithm, but deals with
+// homogenous binomials.
+
+// The second step of the IP-solution is to reduce one or more given
+// initial solutions (which also define right-hand vectors b) with respect
+// to the computed Groebner basis. In the case that the Groebner basis
+// was computed via the algorithm of Conti and Traverso, it is sufficient
+// to give the right-hand vectors. In all other cases we need explicit
+// initial solutions. The routine
+
+extern int solve(INPUT_FILE PROBLEM, INPUT_FILE GROEBNER);
+
+// solves the IP-problems given by the vectors in PROBLEM with respect
+// to GROEBNER which should contain a Groebner basis as computed above. The
+// output is appended to a (eventually newly created) file named as GROEBNER
+// with extensions replaced by:
+//      .sol.<alg>
+// where <alg> is an abbreviation of the algorithm used to compute GROEBNER.
+
+// We also provide functionality to recompute toric ideals with respect to
+// another cost function:
+
+extern int change_cost(INPUT_FILE GROEBNER, INPUT_FILE NEW_COST,
+                       const int& version=1,
+                       const int& S_pair_criteria=11,
+                       const float& interred_percentage=12.0,
+                       const BOOLEAN& verbose=FALSE);
+
+// recomputes the Groebner basis in GROEBNER with respect to the cost given
+// in NEW_COST and writes the result into the file named as NEW_COST with
+// extension replaced by
+//      .GB.<alg>
+// where <alg> is an abbreviation of the algorithm used to compute GROEBNER.
+
+//////////////////////////////////////////////////////////////////////////////
+////////////      FORMAT OF INPUT AND OUTPUT FILES     ///////////////////////
+//////////////////////////////////////////////////////////////////////////////
+
+// The files appearing under the name MATRIX in the above declarations should
+// look as follows to be accepted by the algorithms:
+
+//      MATRIX                                  (* specifie format *)
+//
+//      columns:
+//      <number of columns>
+//
+//      cost vector:
+//      <coefficients of the cost vector>
+//
+//      rows:
+//      <number of rows>
+//
+//      matrix:
+//      <matrix coefficients>
+//
+//      positive row space vector:              (* optional, see below *)
+//      <coefficients of row space vector>
+
+// For example:
+
+//      MATRIX
+//
+//      columns:
+//      3
+//
+//      cost vector:
+//      1 1 1
+//
+//      rows:
+//      2
+//
+//      matrix:
+//      1 2 3
+//      4 5 6
+//
+//      positive row space vector:
+//      1 2 3
+
+// The positive row space vector is only needed by the algorithms of
+// Hosten/Sturmfels and Bigatti/LaScala/Robbiano. It is ignored by the other
+// algorithms, as well as further lines in the input file. This allows us to
+// use the same input format for all algorithms. The comments (as the word
+// "rows:") are only written into the file to make it easy to read.
+
+
+// The file named NEW_COST in the change_cost procedure should have the
+// following format:
+
+//      NEW_COST
+//
+//      variables:                          (* only weighted variables *)
+//      <number of weighted variables>
+//
+//      cost vector:
+//      <coefficients o the weight vector>
+
+// For convenience, the MATRIX format is also accepted by the change_cost
+// procedure. The lines following the cost vector are then ignored.
+
+// The files appearing under the name GROEBNER in the above declarations
+// are created in the following form by the algorithms for computing toric
+// ideals. This form is accepted by the solve(...) and the
+// change_cost(...) procedures:
+
+//      GROEBNER                            (* specifie format *)
+//
+//      computed with algorithm:
+//      <algorithm name abbreviation>       (* abbreviations as above *)
+//      from file(s):                       (* the following four lines are
+//      <name of respective MATRIX file>       optional *)
+//      computation time:
+//      <computation time in seconds>
+//
+//      term ordering:
+//      elimination block
+//      <number of elimination variables>
+//      <LEX / DEG_LEX                      (* only if number of elimination
+//      / DEG_REV_LEX>                         variables >0 *)
+//      weighted block
+//      <number of weighted variables>
+//      <W_LEX / W_REV_LEX                  (* number of weighted variables
+//      / W_DEG_LEX / W_DEG_REV_LEX>           should always >0 *)
+//      <weight_vector>
+//
+//      size:
+//      <number of elements>
+//
+//      Groebner basis:
+//      <basis elements>                    (* one basis element in each row,
+//                                             given by the coefficients of
+//                                             its vector representation *)
+//      settings for the                    (* all following lines are
+//      Buchberger algorithm:                  optional, verbose mode *)
+//      version:                            (* as explained in ideal.h,
+//      <version number>                       between 0 and 3 *)
+//      S-pair criteria:
+//      <{relatively prime leading terms,   (* a subset of these criteria *)
+//        criterion M, criterion F,
+//        criterion B, second criterion}>
+//      interreduction percentage:
+//      <interreduction percentage>
+//
+//      compiler settings:                  (* see the procedure
+//      ...                                    print_flags(...) in
+//      ...                                    IP_algorithms.cc *)
+
+// If the GROEBNER file is created by change_cost(...), the algorithm name
+// and MATRIX file are chosen as those of the original GROEBNER file; the
+// new_cost file is specified as a second MATRIX file.
+
+
+// The files appearing under the name PROBLEM in the above declarations should
+// look as follows to be accepted by the procedure solve(...):
+
+//      PROBLEM                                     (* specifie format *)
+//
+//      vector size:
+//      <vector dimension>
+//
+//      number of instances:
+//      <number of vectors>
+//
+//      right hand or initial solution vectors:
+//      <vector coefficients>                       (* one vector per row *)
+
+
+// solve(...) verifies if the vector size given in the PROBLEM file and
+// the number of variables given in the GROEBNER file match the respective
+// algorithm. In the matching case, it creates a SOLUTION file of the
+// following format (not used as an input file for any procedure):
+
+//      SOLUTION                                    (* specifie format *)
+//
+//      computed with algorithm:                    (* from the respective
+//      <algorithm name abbreviation>                  GROEBNER file *)
+//      from file:                                  (* the GROEBNER file *)
+//      <file name>
+//
+//      <right hand/initial solution> vector:
+//      <vector as in the problem file>
+//      solvable:                                   (* only if right-hand
+//      <YES/NO>                                       vector is given *)
+//      optimal solution:                           (* only in the case of
+//      <optimal solution vector>                      existence *)
+//      computation time:                           (* only reduction time *)
+//      <reduction time in seconds>
+//
+//      ...                                         (* further vectors *)
+
+#endif
diff --git a/IntegerProgramming/LLL.cc b/IntegerProgramming/LLL.cc
new file mode 100644
index 0000000..45af745
--- /dev/null
+++ b/IntegerProgramming/LLL.cc
@@ -0,0 +1,590 @@
+#ifndef LLL_CC
+#define LLL_CC
+
+#include "LLL.h"
+
+// subroutines for the LLL-algorithms
+
+void REDI_KB(const short& k, const short& l, BigInt** b,
+             const short& number_of_vectors, const short& vector_dimension,
+             BigInt** H, BigInt* d, BigInt** lambda)
+// the REDI procedure for relations(...) (to compute the Kernel Basis,
+// algorithm 2.7.2 in Cohen's book)
+{
+#ifdef GMP
+  if(abs(BigInt(2)*lambda[k][l])<=d[l+1])
+#else   // GMP
+  if(labs(2*lambda[k][l])<=d[l+1])
+    // labs is the abs-function for long ints
+#endif  // GMP
+    return;
+
+#ifdef GMP
+  BigInt q=(BigInt(2)*lambda[k][l]+d[l+1])/(BigInt(2)*d[l+1]);
+#else   // GMP
+  long q=(long int) floor(((float)(2*lambda[k][l]+d[l+1]))/(2*d[l+1]));
+#endif  // GMP
+
+  // q is the integer quotient of the division
+  // (2*lambda[k][l]+d[l+1])/(2*d[l+1]).
+  // Because of the rounding mode (always towards zero) of GNU C++,
+  // we cannot use the built-in integer division
+  // here; it causes errors when dealing with negative numbers. Therefore
+  // the complicated casts: The divident is first casted to a float which
+  // causes the division result to be a float. This result is explicitly
+  // rounded downwards. As the floor-function returns a double (for range
+  // reasons), this has to be casted to an integer again.
+
+  for(short n=0;n<number_of_vectors;n++)
+    H[k][n]-=q*H[l][n];
+  // H[k]=H[k]-q*H[l]
+
+  for(short m=0;m<vector_dimension;m++)
+    b[k][m]-=q*b[l][m];
+  // b[k]=b[k]-q*b[l]
+
+  lambda[k][l]-=q*d[l+1];
+
+  for(short i=0;i<=l-1;i++)
+    lambda[k][i]-=q*lambda[l][i];
+}
+
+
+
+
+void REDI_IL(const short& k, const short& l, BigInt** b,
+             const short& vector_dimension, BigInt* d, BigInt** lambda)
+// the REDI procedure for the integer LLL algorithm (algorithm 2.6.7 in
+// Cohen's book)
+{
+#ifdef GMP
+  if(abs(BigInt(2)*lambda[k][l])<=d[l+1])
+#else   // GMP
+  if(labs(2*lambda[k][l])<=d[l+1])
+    // labs is the abs-function for long ints
+#endif  // GMP
+    return;
+
+#ifdef GMP
+  BigInt q=(BigInt(2)*lambda[k][l]+d[l+1])/(BigInt(2)*d[l+1]);
+#else   // GMP
+  long q=(long int) floor(((float)(2*lambda[k][l]+d[l+1]))/(2*d[l+1]));
+#endif  // GMP
+
+  // q is the integer quotient of the division
+  // (2*lambda[k][l]+d[l+1])/(2*d[l+1]).
+  // Because of the rounding mode (always towards zero) of GNU C++,
+  // we cannot use the built-in integer division
+  // here; it causes errors when dealing with negative numbers. Therefore
+  // the complicated casts: The divident is first casted to a float which
+  // causes the division result to be a float. This result is explicitly
+  // rounded downwards. As the floor-function returns a double (for range
+  // reasons), this has to be casted to an integer again.
+
+  for(short m=0;m<vector_dimension;m++)
+    b[k][m]-=q*b[l][m];
+  // b[k]=b[k]-q*b[l]
+
+  lambda[k][l]-=q*d[l+1];
+
+  for(short i=0;i<=l-1;i++)
+    lambda[k][i]-=q*lambda[l][i];
+}
+
+
+
+
+void SWAPI(const short& k, const short& k_max, BigInt** b, BigInt* d,
+           BigInt** lambda)
+// the SWAPI procedure of algorithm 2.6.7
+{
+
+  // exchange b[k] and b[k-1]
+  // This can be done efficiently by swapping pointers (not entries).
+  BigInt* swap=b[k];
+  b[k]=b[k-1];
+  b[k-1]=swap;
+
+  if(k>1)
+    for(short j=0;j<=k-2;j++)
+    {
+      // exchange lambda[k][j] and lambda[k-1][j]
+      BigInt swap=lambda[k][j];
+      lambda[k][j]=lambda[k-1][j];
+      lambda[k-1][j]=swap;
+    }
+
+  BigInt _lambda=lambda[k][k-1];
+
+  BigInt B=(d[k-1]*d[k+1] + _lambda*_lambda)/d[k];
+  // It might be better to choose another evaluation order for this formula,
+  // see below.
+
+  for(short i=k+1;i<=k_max;i++)
+  {
+    BigInt t=lambda[i][k];
+    lambda[i][k]=(d[k+1]*lambda[i][k-1] - _lambda*t)/d[k];
+    lambda[i][k-1]=(B*t + _lambda*lambda[i][k])/d[k+1];
+  }
+
+  d[k]=B;
+}
+
+
+
+
+void SWAPK(const short& k, const short& k_max, BigInt** b, BigInt** H,
+           char *f, BigInt* d, BigInt** lambda)
+// the SWAPK procedure of algorithm 2.7.2
+{
+  // exchange H[k] and H[k-1]
+  // This can be done efficiently by swapping pointers (not entries).
+  BigInt *swap=H[k];
+  H[k]=H[k-1];
+  H[k-1]=swap;
+
+  // exchange b[k] and b[k-1] by the same method
+  swap=b[k];
+  b[k]=b[k-1];
+  b[k-1]=swap;
+
+  if(k>1)
+    for(short j=0;j<=k-2;j++)
+    {
+      // exchange lambda[k][j] and lambda[k-1][j]
+      BigInt swap=lambda[k][j];
+      lambda[k][j]=lambda[k-1][j];
+      lambda[k-1][j]=swap;
+    }
+
+  BigInt _lambda=lambda[k][k-1];
+
+  if(_lambda==BigInt(0))
+  {
+    d[k]=d[k-1];
+    f[k-1]=0;
+    f[k]=1;
+    lambda[k][k-1]=0;
+    for(short i=k+1;i<=k_max;i++)
+    {
+      lambda[i][k]=lambda[i][k-1];
+      lambda[i][k-1]=0;
+    }
+  }
+  else
+    // lambda!=0
+  {
+    for(short i=k+1;i<=k_max;i++)
+      lambda[i][k-1]=(_lambda*lambda[i][k-1])/d[k];
+
+    // Multiplie lambda[i][k-1] by _lambda/d[k].
+    // One could also write
+    //   lambda[i][k-1]*=(lambda/d[k]);   (*)
+    // Without a BigInt class, this can prevent overflows when computing
+    // _lambda*lambda[i][k-1].
+    // But examples show that lambda/d[k] is in general not an integer.
+    // So (*) could lead to problems due to the inexact floating point
+    // arithmetic...
+    // Therefore, we chose the secure evaluation order in all such cases.
+
+    BigInt t=d[k+1];
+    d[k]=(_lambda*_lambda)/d[k];
+    d[k+1]=d[k];
+
+    for(short j=k+1;j<=k_max-1;j++)
+      for(short i=j+1;i<=k_max;i++)
+        lambda[i][j]=(lambda[i][j]*d[k])/t;
+
+    for(short j=k+1;j<=k_max;j++)
+      d[j+1]=(d[j+1]*d[k])/t;
+  }
+
+}
+
+typedef BigInt* BigIntP;
+
+
+short relations(BigInt **b, const short& number_of_vectors,
+                const short& vector_dimension, BigInt**& H)
+{
+
+// first check arguments
+
+  if(number_of_vectors<0)
+  {
+    cerr<<"\nWARNING: short relations(BigInt**, const short&, const short&, "
+      "BigInt**):\nargument number_of_vectors out of range"<<endl;
+    return -1;
+  }
+
+  if(vector_dimension<=0)
+  {
+    cerr<<"\nWARNING: short relations(BigInt**, const short&, const short&, "
+      "BigInt**):\nargument vector_dimension out of range"<<endl;
+    return -1;
+  }
+
+
+// consider special case
+
+  if(number_of_vectors==1)
+    // Only one vector which has no relations if it is not zero,
+    // else relation 1.
+  {
+    short r=1;    // Suppose the only column of the matrix is zero.
+
+    for(short m=0;m<vector_dimension;m++)
+      if(b[0][m]!=BigInt(0))
+        // nonzero entry detected
+        r=0;
+
+    if(r==1)
+    {
+      H=new BigIntP[1];
+      H[0]=new BigInt[1];
+      H[0][0]=1;
+      // This is the lattice basis of the relations...
+    }
+
+    return r;
+  }
+
+
+// memory allocation
+
+// The names are chosen (as far as possible) according to Cohen's book.
+// However, for technical reasons, the indices do not run from 1 to
+// (e.g.) number_of_vectors, but from 0 to number_of_vectors-1.
+// Therefore all indices are shifted by -1 in comparison with this book,
+// except from the indices of the array d which has size
+// number_of_vectors+1.
+
+  H=new BigIntP[number_of_vectors];
+  for(short n=0;n<number_of_vectors;n++)
+    H[n]=new BigInt[number_of_vectors];
+
+  char* f=new char[number_of_vectors];
+
+  BigInt* d=new BigInt[number_of_vectors+1];
+
+  BigInt** lambda=new BigIntP[number_of_vectors];
+  for(short n=1;n<number_of_vectors;n++)
+    lambda[n]=new BigInt[n];
+  // We only need lambda[n][k] for n>k.
+
+
+
+// Step 1: Initialization
+
+  short k=1;
+  short k_max=0;
+  // for iteration
+
+  d[0]=1;
+
+  BigInt t=0;
+  for(short m=0;m<vector_dimension;m++)
+    t+=b[0][m]*b[0][m];
+  // Now, t is the scalar product of b[0] with itself.
+
+  for(short n=0;n<number_of_vectors;n++)
+    for(short l=0;l<number_of_vectors;l++)
+      if(n==l)
+        H[n][l]=1;
+      else
+        H[n][l]=0;
+  // Now, H equals the matrix I_(number_of_vectors).
+
+  if(t!=BigInt(0))
+  {
+    d[1]=t;
+    f[0]=1;
+  }
+  else
+  {
+    d[1]=1;
+    f[0]=0;
+  }
+
+
+
+// The other steps are not programmed with "goto" as in Cohen's book.
+// Instead, we enter a do-while-loop which terminates iff
+// k>=number_of_vectors.
+
+  do
+  {
+
+
+// Step 2: Incremental Gram-Schmidt
+
+    if(k>k_max)
+      // else we can immediately go to step 3.
+    {
+      k_max=k;
+
+      for(short j=0;j<=k;j++)
+        if((f[j]==0) && (j<k))
+          lambda[k][j]=0;
+        else
+        {
+          BigInt u=0;
+
+          // compute scalar product of b[k] and b[j]
+          for(short m=0;m<vector_dimension;m++)
+            u+=b[k][m]*b[j][m];
+
+          for(short i=0;i<=j-1;i++)
+            if(f[i]!=0)
+              u=(d[i+1]*u-lambda[k][i]*lambda[j][i])/d[i];
+
+          if(j<k)
+            lambda[k][j]=u;
+          else
+            // j==k
+            if(u!=BigInt(0))
+            {
+              d[k+1]=u;
+              f[k]=1;
+            }
+            else
+              // u==0
+            {
+              d[k+1]=d[k];
+              f[k]=0;
+            }
+        }
+    }
+
+
+// Step 3: Test f[k]==0 and f[k-1]!=0
+
+    do
+    {
+      if(f[k-1]!=0)
+        REDI_KB(k,k-1,b,number_of_vectors,vector_dimension,H,d,lambda);
+
+      if((f[k-1]!=0) && (f[k]==0))
+      {
+        SWAPK(k,k_max,b,H,f,d,lambda);
+
+        if(k>1)
+          k--;
+        else
+          k=1;
+        // k=max(1,k-1)
+      }
+
+      else
+        break;
+    }
+    while(1);
+
+    // Now the conditions above are no longer satisfied.
+
+    for(short l=k-2;l>=0;l--)
+      if(f[l]!=0)
+        REDI_KB(k,l,b,number_of_vectors,vector_dimension,H,d,lambda);
+    k++;
+
+
+// Step 4: Finished?
+
+  }
+  while(k<number_of_vectors);
+
+
+
+// Now we have computed a lattice basis of the relations of the b[i].
+// Prepare the LLL-reduction.
+
+  // Compute the dimension r of the relations.
+  short r=0;
+  for(short n=0;n<number_of_vectors;n++)
+    if(f[n]==0) // n==r!!
+      r++;
+    else
+      break;
+
+  // Delete the part of H that is no longer needed (especially the vectors
+  // H[r],...,H[number_of_vectors-1]).
+  BigInt **aux=H;
+  if(r>0)
+    H=new BigIntP[r];
+  for(short i=0;i<r;i++)
+    H[i]=aux[i];
+
+  for(short i=r;i<number_of_vectors;i++)
+    delete[] aux[i];
+  delete[] aux;
+
+  delete[] f;
+
+  delete[] d;
+
+  for(short i=1;i<number_of_vectors;i++)
+    delete[] lambda[i];
+  delete[] lambda;
+
+  integral_LLL(H,r,number_of_vectors);
+
+  return r;
+
+}
+
+
+
+
+short integral_LLL(BigInt** b, const short& number_of_vectors,
+                  const short& vector_dimension)
+{
+
+// first check arguments
+
+  if(number_of_vectors<0)
+  {
+    cerr<<"\nWARNING: short integral_LL(BigInt**, const short&, const short&):"
+      "\nargument number_of_vectors out of range"<<endl;
+    return -1;
+  }
+
+  if(vector_dimension<=0)
+  {
+    cerr<<"\nWARNING: short integral_LLL(BigInt**, const short&, const "
+      "short&):\nargument vector_dimension out of range"<<endl;
+    return -1;
+  }
+
+
+// consider special case
+
+  if(number_of_vectors<=1)
+    // 0 or 1 input vector, nothing to be done
+    return 0;
+
+
+// memory allocation
+
+// The names are chosen (as far as possible) according to Cohen's book.
+// However, for technical reasons, the indices do not run from 1 to
+// (e.g.) number_of_vectors, but from 0 to number_of_vectors-1.
+// Therefore all indices are shifted by -1 in comparison with this book,
+// except from the indices of the array d which has size
+// number_of_vectors+1.
+
+  BigInt* d=new BigInt[number_of_vectors+1];
+
+  BigInt** lambda=new BigIntP[number_of_vectors];
+  for(short s=1;s<number_of_vectors;s++)
+    lambda[s]=new BigInt[s];
+  // We only need lambda[n][k] for n>k.
+
+
+
+// Step 1: Initialization
+
+  short k=1;
+  short k_max=0;
+  // for iteration
+  d[0]=1;
+
+  d[1]=0;
+  for(short n=0;n<vector_dimension;n++)
+    d[1]+=b[0][n]*b[0][n];
+  // Now, d[1] is the scalar product of b[0] with itself.
+
+
+// The other steps are not programmed with "goto" as in Cohen's book.
+// Instead, we enter a do-while-loop which terminates iff k>r.
+
+  do
+  {
+
+
+// Step 2: Incremental Gram-Schmidt
+
+    if(k>k_max)
+      // else we can immediately go to step 3.
+    {
+      k_max=k;
+
+      for(short j=0;j<=k;j++)
+      {
+        BigInt u=0;
+        // compute scalar product of b[k] and b[j]
+        for(short n=0;n<vector_dimension;n++)
+          u+=b[k][n]*b[j][n];
+
+        for(short i=0;i<=j-1;i++)
+        {
+          u*=d[i+1];
+          u-=lambda[k][i]*lambda[j][i];
+          u/=d[i];
+
+          //u=(d[i+1]*u-lambda[k][i]*lambda[j][i])/d[i];
+        }
+
+        if(j<k)
+          lambda[k][j]=u;
+        else
+          // j==k
+          d[k+1]=u;
+      }
+
+      if(d[k+1]==BigInt(0))
+      {
+        cerr<<"\nERROR: void integral_LLL(BigInt**, const short&, const "
+          "short&):\ninput vectors must be linearly independent"<<endl;
+        return -1;
+      }
+    }
+
+
+// Step 3: Test LLL-condition
+
+    do
+    {
+      REDI_IL(k,k-1,b,vector_dimension,d,lambda);
+
+      //if(4*d[k+1]*d[k-1] < 3*d[k]*d[k] - lambda[k][k-1]*lambda[k][k-1])
+      if((BigInt(4))*d[k+1]*d[k-1]
+          < (BigInt(3))*d[k]*d[k] - lambda[k][k-1]*lambda[k][k-1])
+      {
+        SWAPI(k,k_max,b,d,lambda);
+        if(k>1)
+          k--;
+        // k=max(1,k-1)
+      }
+      else
+        break;
+
+    }
+    while(1);
+
+    // Now the condition above is no longer satisfied.
+
+    for(short l=k-2;l>=0;l--)
+      REDI_IL(k,l,b,vector_dimension,d,lambda);
+    k++;
+
+
+
+// Step 4: Finished?
+
+  }
+  while(k<number_of_vectors);
+
+
+// Now, b contains the LLL-reduced lattice basis.
+// Memory cleanup.
+
+  delete[] d;
+
+  for(short i=1;i<number_of_vectors;i++)
+    delete[] lambda[i];
+  delete[] lambda;
+
+  return 0;
+
+}
+#endif  // LLL_CC
diff --git a/IntegerProgramming/LLL.h b/IntegerProgramming/LLL.h
new file mode 100644
index 0000000..b48ef32
--- /dev/null
+++ b/IntegerProgramming/LLL.h
@@ -0,0 +1,39 @@
+// LLL.h
+
+// This file contains the implementation of two special variants of the
+// LLL-algorithm.
+// For further explainations see the book of Henri Cohen, A Course in
+// Computational Algebraic Number Theory.
+
+// When performing the LLL-algorithm, some coefficients grow very fast.
+// Therefore one should use a  data type for arbitrary long integers
+// (called "BigInt" in the code).
+// If no such data type is specified, BigInt is defined to be a long
+// (cf. globals.h).
+
+#ifndef LLL_H
+#define LLL_H
+
+#include "globals.h"
+
+extern short relations(BigInt** b, const short& number_of_vectors,
+                       const short& vector_dimension, BigInt**& H);
+// Computes the relations of the input vectors stored in b and returns the
+// dimension r of the lattice spanned by these relations.
+// The return value -1 indicates that an error has occurred.
+// A LLL-reduced basis of the relations is written into the two-dimensional
+// array H. Memory allocation for this array is done in the routine;
+// when leaving the routine, the dimension will be vector_columns x r.
+// This routine corresponds to algorithm 2.7.2 in Cohen's book.
+
+extern short integral_LLL(BigInt **b, const short& number_of_vectors,
+                          const short& vector_dimension);
+// Reduces the input vectors stored in b (in the sense of an LLL-reduction).
+// The input vectors have to be linearly independent.
+// ATTENTION: The input vectors are modified during this algorithm. For
+// efficiency reasons in our application, we do NOT store a transformation
+// matrix!
+// The return value is -1 if an error has occurred, 0 else.
+// This routine corresponds to algorithm 2.6.7 in Cohen's book.
+
+#endif  // LLL_H
diff --git a/IntegerProgramming/Makefile.am b/IntegerProgramming/Makefile.am
new file mode 100644
index 0000000..2b67c3a
--- /dev/null
+++ b/IntegerProgramming/Makefile.am
@@ -0,0 +1,26 @@
+ACLOCAL_AMFLAGS = -I ../m4
+
+AM_CPPFLAGS = $(GMP_CFLAGS)
+AM_LDFLAGS = $(GMP_LIBS)
+
+noinst_HEADERS = list.h binomial__term_ordering.h BigInt.h LLL.h matrix.h ideal.h binomial__term_ordering.h ideal.h \
+		term_ordering.h globals.h IP_algorithms.h binomial.h testdata.h
+# Ikernel_to_send.c  # never used?
+
+bindir=$(libexecdir)/singular/MOD
+
+bin_PROGRAMS = toric_ideal solve_IP change_cost gen_test
+
+COMMON_SOURCES = term_ordering.cc binomial.cc \
+        list.cc BigInt.cc LLL.cc matrix.cc ideal.cc Buchberger.cc \
+	ideal_stuff.cc IP_algorithms.cc testdata.cc
+
+toric_ideal_SOURCES = $(COMMON_SOURCES) toric_ideal.cc
+solve_IP_SOURCES = $(COMMON_SOURCES) solve_IP.cc
+change_cost_SOURCES = $(COMMON_SOURCES) change_cost.cc
+gen_test_SOURCES = $(COMMON_SOURCES) gen_test.cc
+
+# for now we don't install any additional help files...
+EXTRA_DIST = README change_cost.hlp solve_IP.hlp toric_ideal.hlp
+
+
diff --git a/IntegerProgramming/Makefile.in b/IntegerProgramming/Makefile.in
new file mode 100644
index 0000000..46215fa
--- /dev/null
+++ b/IntegerProgramming/Makefile.in
@@ -0,0 +1,749 @@
+# Makefile.in generated by automake 1.13.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 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@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+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 = toric_ideal$(EXEEXT) solve_IP$(EXEEXT) \
+	change_cost$(EXEEXT) gen_test$(EXEEXT)
+subdir = IntegerProgramming
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/build-aux/depcomp $(noinst_HEADERS) README
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_append_compile_flags.m4 \
+	$(top_srcdir)/m4/ax_append_flag.m4 \
+	$(top_srcdir)/m4/ax_append_link_flags.m4 \
+	$(top_srcdir)/m4/ax_check_compile_flag.m4 \
+	$(top_srcdir)/m4/ax_check_link_flag.m4 \
+	$(top_srcdir)/m4/ax_compute_relative_paths.m4 \
+	$(top_srcdir)/m4/ax_normalize_path.m4 \
+	$(top_srcdir)/m4/ax_prefix_config_h.m4 \
+	$(top_srcdir)/m4/ax_pthread.m4 \
+	$(top_srcdir)/m4/ax_python_embed.m4 \
+	$(top_srcdir)/m4/ax_python_with_version.m4 \
+	$(top_srcdir)/m4/cpu-check.m4 $(top_srcdir)/m4/dbm-check.m4 \
+	$(top_srcdir)/m4/flags.m4 $(top_srcdir)/m4/flint-check.m4 \
+	$(top_srcdir)/m4/gfanlib-check.m4 \
+	$(top_srcdir)/m4/gmp-check.m4 \
+	$(top_srcdir)/m4/google-perftools.m4 \
+	$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+	$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+	$(top_srcdir)/m4/lt~obsolete.m4 \
+	$(top_srcdir)/m4/mathic-check.m4 $(top_srcdir)/m4/ntl-check.m4 \
+	$(top_srcdir)/m4/options.m4 $(top_srcdir)/m4/p-procs.m4 \
+	$(top_srcdir)/m4/polymake-check.m4 \
+	$(top_srcdir)/m4/readline-check.m4 $(top_srcdir)/configure.ac
+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)"
+PROGRAMS = $(bin_PROGRAMS)
+am__objects_1 = term_ordering.$(OBJEXT) binomial.$(OBJEXT) \
+	list.$(OBJEXT) BigInt.$(OBJEXT) LLL.$(OBJEXT) matrix.$(OBJEXT) \
+	ideal.$(OBJEXT) Buchberger.$(OBJEXT) ideal_stuff.$(OBJEXT) \
+	IP_algorithms.$(OBJEXT) testdata.$(OBJEXT)
+am_change_cost_OBJECTS = $(am__objects_1) change_cost.$(OBJEXT)
+change_cost_OBJECTS = $(am_change_cost_OBJECTS)
+change_cost_LDADD = $(LDADD)
+AM_V_lt = $(am__v_lt_ at AM_V@)
+am__v_lt_ = $(am__v_lt_ at AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 = 
+am_gen_test_OBJECTS = $(am__objects_1) gen_test.$(OBJEXT)
+gen_test_OBJECTS = $(am_gen_test_OBJECTS)
+gen_test_LDADD = $(LDADD)
+am_solve_IP_OBJECTS = $(am__objects_1) solve_IP.$(OBJEXT)
+solve_IP_OBJECTS = $(am_solve_IP_OBJECTS)
+solve_IP_LDADD = $(LDADD)
+am_toric_ideal_OBJECTS = $(am__objects_1) toric_ideal.$(OBJEXT)
+toric_ideal_OBJECTS = $(am_toric_ideal_OBJECTS)
+toric_ideal_LDADD = $(LDADD)
+AM_V_P = $(am__v_P_ at AM_V@)
+am__v_P_ = $(am__v_P_ at AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_ at AM_V@)
+am__v_GEN_ = $(am__v_GEN_ at AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_ at AM_V@)
+am__v_at_ = $(am__v_at_ at AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+DEFAULT_INCLUDES = -I. at am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \
+	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+	$(AM_CXXFLAGS) $(CXXFLAGS)
+AM_V_CXX = $(am__v_CXX_ at AM_V@)
+am__v_CXX_ = $(am__v_CXX_ at AM_DEFAULT_V@)
+am__v_CXX_0 = @echo "  CXX     " $@;
+am__v_CXX_1 = 
+CXXLD = $(CXX)
+CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+	$(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CXXLD = $(am__v_CXXLD_ at AM_V@)
+am__v_CXXLD_ = $(am__v_CXXLD_ at AM_DEFAULT_V@)
+am__v_CXXLD_0 = @echo "  CXXLD   " $@;
+am__v_CXXLD_1 = 
+SOURCES = $(change_cost_SOURCES) $(gen_test_SOURCES) \
+	$(solve_IP_SOURCES) $(toric_ideal_SOURCES)
+DIST_SOURCES = $(change_cost_SOURCES) $(gen_test_SOURCES) \
+	$(solve_IP_SOURCES) $(toric_ideal_SOURCES)
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+HEADERS = $(noinst_HEADERS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BUILTIN_LIBS = @BUILTIN_LIBS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CDDGMPCPPFLAGS = @CDDGMPCPPFLAGS@
+CDDGMPLDFLAGS = @CDDGMPLDFLAGS@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATA_DIR = @DATA_DIR@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DOC_DIR = @DOC_DIR@
+DOXYGEN = @DOXYGEN@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FACTORY_INCLUDES = @FACTORY_INCLUDES@
+FACTORY_LIBS = @FACTORY_LIBS@
+FGREP = @FGREP@
+FLINT_CFLAGS = @FLINT_CFLAGS@
+FLINT_HOME = @FLINT_HOME@
+FLINT_LIBS = @FLINT_LIBS@
+GMP_CFLAGS = @GMP_CFLAGS@
+GMP_HOME = @GMP_HOME@
+GMP_LIBS = @GMP_LIBS@
+GMP_VERSION = @GMP_VERSION@
+GREP = @GREP@
+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@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NTL_CFLAGS = @NTL_CFLAGS@
+NTL_LIBS = @NTL_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OMALLOC_INCLUDES = @OMALLOC_INCLUDES@
+OMALLOC_LIBS = @OMALLOC_LIBS@
+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@
+PKG_REQUIRE = @PKG_REQUIRE@
+PMCONFIG = @PMCONFIG@
+PM_CFLAGS = @PM_CFLAGS@
+PM_INC = @PM_INC@
+PM_LDFLAGS = @PM_LDFLAGS@
+PM_LIBS = @PM_LIBS@
+POLYMAKE_CXXFLAGS = @POLYMAKE_CXXFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LDFLAGS = @PTHREAD_LDFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
+PYTHON = @PYTHON@
+PYTHON_CSPEC = @PYTHON_CSPEC@
+PYTHON_EXECPREFIX = @PYTHON_EXECPREFIX@
+PYTHON_LSPEC = @PYTHON_LSPEC@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+RANLIB = @RANLIB@
+RESOURCES_INCLUDES = @RESOURCES_INCLUDES@
+RESOURCES_LIBS = @RESOURCES_LIBS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SINGULAR_CFLAGS = @SINGULAR_CFLAGS@
+SI_COUNTEDREF_AUTOLOAD = @SI_COUNTEDREF_AUTOLOAD@
+SI_CPU_I386 = @SI_CPU_I386@
+SI_CPU_IA64 = @SI_CPU_IA64@
+SI_CPU_PPC = @SI_CPU_PPC@
+SI_CPU_SPARC = @SI_CPU_SPARC@
+SI_CPU_X86_64 = @SI_CPU_X86_64@
+STRIP = @STRIP@
+USEPPROCSDYNAMICLD = @USEPPROCSDYNAMICLD@
+USEPPROCSDYNAMICLDFLAGS = @USEPPROCSDYNAMICLDFLAGS@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
+# Ikernel_to_send.c  # never used?
+bindir = $(libexecdir)/singular/MOD
+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@
+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@
+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@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+ACLOCAL_AMFLAGS = -I ../m4
+AM_CPPFLAGS = $(GMP_CFLAGS)
+AM_LDFLAGS = $(GMP_LIBS)
+noinst_HEADERS = list.h binomial__term_ordering.h BigInt.h LLL.h matrix.h ideal.h binomial__term_ordering.h ideal.h \
+		term_ordering.h globals.h IP_algorithms.h binomial.h testdata.h
+
+COMMON_SOURCES = term_ordering.cc binomial.cc \
+        list.cc BigInt.cc LLL.cc matrix.cc ideal.cc Buchberger.cc \
+	ideal_stuff.cc IP_algorithms.cc testdata.cc
+
+toric_ideal_SOURCES = $(COMMON_SOURCES) toric_ideal.cc
+solve_IP_SOURCES = $(COMMON_SOURCES) solve_IP.cc
+change_cost_SOURCES = $(COMMON_SOURCES) change_cost.cc
+gen_test_SOURCES = $(COMMON_SOURCES) gen_test.cc
+
+# for now we don't install any additional help files...
+EXTRA_DIST = README change_cost.hlp solve_IP.hlp toric_ideal.hlp
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .cc .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) --foreign IntegerProgramming/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign IntegerProgramming/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)
+	@list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \
+	fi; \
+	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
+
+change_cost$(EXEEXT): $(change_cost_OBJECTS) $(change_cost_DEPENDENCIES) $(EXTRA_change_cost_DEPENDENCIES) 
+	@rm -f change_cost$(EXEEXT)
+	$(AM_V_CXXLD)$(CXXLINK) $(change_cost_OBJECTS) $(change_cost_LDADD) $(LIBS)
+
+gen_test$(EXEEXT): $(gen_test_OBJECTS) $(gen_test_DEPENDENCIES) $(EXTRA_gen_test_DEPENDENCIES) 
+	@rm -f gen_test$(EXEEXT)
+	$(AM_V_CXXLD)$(CXXLINK) $(gen_test_OBJECTS) $(gen_test_LDADD) $(LIBS)
+
+solve_IP$(EXEEXT): $(solve_IP_OBJECTS) $(solve_IP_DEPENDENCIES) $(EXTRA_solve_IP_DEPENDENCIES) 
+	@rm -f solve_IP$(EXEEXT)
+	$(AM_V_CXXLD)$(CXXLINK) $(solve_IP_OBJECTS) $(solve_IP_LDADD) $(LIBS)
+
+toric_ideal$(EXEEXT): $(toric_ideal_OBJECTS) $(toric_ideal_DEPENDENCIES) $(EXTRA_toric_ideal_DEPENDENCIES) 
+	@rm -f toric_ideal$(EXEEXT)
+	$(AM_V_CXXLD)$(CXXLINK) $(toric_ideal_OBJECTS) $(toric_ideal_LDADD) $(LIBS)
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/BigInt.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/Buchberger.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/IP_algorithms.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/LLL.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/binomial.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/change_cost.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/gen_test.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ideal.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ideal_stuff.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/list.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/matrix.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/solve_IP.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/term_ordering.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/testdata.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/toric_ideal.Po at am__quote@
+
+.cc.o:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+ at am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXXCOMPILE) -c -o $@ $<
+
+.cc.obj:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+ at am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.cc.lo:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+ at am__fastdepCXX_TRUE@	$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LTCXXCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	$(am__define_uniq_tagged_files); \
+	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-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	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"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+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) $(HEADERS)
+installdirs:
+	for dir in "$(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:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+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-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
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \
+	clean-binPROGRAMS clean-generic clean-libtool cscopelist-am \
+	ctags ctags-am 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-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 tags-am uninstall uninstall-am uninstall-binPROGRAMS
+
+
+# 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/IntegerProgramming/README b/IntegerProgramming/README
new file mode 100644
index 0000000..c95a10d
--- /dev/null
+++ b/IntegerProgramming/README
@@ -0,0 +1,11 @@
+//
+// author : Christine Theis
+//
+Procedures for Toric ideals/Integer Programming using Groebner basis methods
+Interface to Singular: intprog.lib, toric.lib
+Mathematical background: see math.doc
+
+install several stand alone programs into the $bindir
+
+
+Mon Apr 14 10:17:23 CEST 2003: Stefan Wolf <wolfs at in.tum.de>: gcc 3.2.2 port
diff --git a/IntegerProgramming/binomial.cc b/IntegerProgramming/binomial.cc
new file mode 100644
index 0000000..e1e97d9
--- /dev/null
+++ b/IntegerProgramming/binomial.cc
@@ -0,0 +1,1922 @@
+// binomial.cc
+
+// implementation of class binomial
+
+#ifndef BINOMIAL_CC
+#define BINOMIAL_CC
+
+#include <climits>
+#include "binomial__term_ordering.h"
+
+///////////////////////// constructors and destructor //////////////////////
+
+// For a better overview, the constructor code is separated for
+// NO_SUPPORT_DRIVEN_METHODS and SUPPORT_DRIVEN_METHODS.
+
+#ifdef NO_SUPPORT_DRIVEN_METHODS
+
+binomial::binomial(const short& number_of_variables)
+    :_number_of_variables(number_of_variables)
+{
+  exponent_vector=new Integer[_number_of_variables];
+}
+
+
+
+
+binomial::binomial(const short& number_of_variables,const Integer* exponents)
+    :_number_of_variables(number_of_variables)
+{
+
+  // range check for rarely used constructors
+  if(_number_of_variables<=0)
+  {
+    cerr<<"\nWARNING: binomial::binomial(const short&, const Integer*):\n"
+      "argument out of range"<<endl;
+    exponent_vector=NULL;
+    // to avoid problems when deleting
+    return;
+  }
+
+  // initialization
+  exponent_vector=new Integer[_number_of_variables];
+  for(short i=0;i<_number_of_variables;i++)
+    exponent_vector[i]=exponents[i];
+}
+
+
+
+
+binomial::binomial(const short& number_of_variables,const Integer* exponents,
+                   const term_ordering& w)
+    :_number_of_variables(number_of_variables)
+{
+
+  // range check for rarely used constructors
+  if(_number_of_variables<=0)
+  {
+    cerr<<"\nWARNING: binomial::binomial(const short&, const Integer*):\n"
+      "argument out of range"<<endl;
+    exponent_vector=NULL;
+    // to avoid problems when deleting
+    return;
+  }
+
+  exponent_vector=new Integer[_number_of_variables];
+
+  // determine head and tail
+  if(w.compare_to_zero(exponents)>=0)
+    for(short i=0;i<_number_of_variables;i++)
+      exponent_vector[i]=exponents[i];
+  else
+    for(short i=0;i<_number_of_variables;i++)
+      exponent_vector[i]=-exponents[i];
+
+}
+
+
+
+
+binomial::binomial(const binomial& b)
+    :_number_of_variables(b._number_of_variables)
+{
+  exponent_vector=new Integer[_number_of_variables];
+  for(short i=0;i<_number_of_variables;i++)
+    exponent_vector[i]=b.exponent_vector[i];
+}
+
+
+
+
+#endif  // NO_SUPPORT_DRIVEN_METHODS
+
+
+
+
+#ifdef SUPPORT_DRIVEN_METHODS
+
+
+
+
+binomial::binomial(const short& number_of_variables)
+    :_number_of_variables(number_of_variables),head_support(0),tail_support(0)
+{
+  exponent_vector=new Integer[_number_of_variables];
+}
+
+
+
+
+binomial::binomial(const short& number_of_variables, const Integer* exponents)
+    :_number_of_variables(number_of_variables),head_support(0),tail_support(0)
+{
+
+  // range check for rarely used constructors
+  if(_number_of_variables<=0)
+  {
+    exponent_vector=NULL;
+    // to avoid problems when deleting
+    cerr<<"\nWARNING: binomial::binomial(const short&, const Integer*):\n"
+      "argument out of range"<<endl;
+    return;
+  }
+
+  exponent_vector=new Integer[_number_of_variables];
+
+  short size_of_support_vectors=CHAR_BIT*sizeof(unsigned long);
+  // number of bits of a long int
+
+
+  for(short i=0;i<_number_of_variables;i++)
+  {
+
+#ifdef SUPPORT_VARIABLES_FIRST
+
+    Integer actual_entry=exponents[i];
+    exponent_vector[i]=actual_entry;
+
+#endif  // SUPPORT_VARIABLES_FIRST
+
+#ifdef SUPPORT_VARIABLES_LAST
+
+    short j=_number_of_variables-1-i;
+    Integer actual_entry=exponents[j];
+    exponent_vector[j]=actual_entry;
+
+#endif  // SUPPORT_VARIABLES_LAST
+
+    if(i<size_of_support_vectors)
+    {
+      // variable i is considered in the support vectors
+      if(actual_entry>0)
+        head_support|=(1<<i);
+        // bit i of head_support is set to 1 (counting from 0)
+      else if(actual_entry<0)
+        tail_support|=(1<<i);
+        // bit i of tail_support is set to 1
+    }
+  }
+
+}
+
+
+
+
+binomial::binomial(const short& number_of_variables, const Integer* exponents,
+                   const term_ordering& w)
+    :_number_of_variables(number_of_variables),head_support(0),tail_support(0)
+{
+  // range check for rarely used constructors
+  if(_number_of_variables<=0)
+  {
+    cerr<<"\nWARNING: binomial::binomial(const short&, const Integer*):\n"
+      "argument out of range"<<endl;
+    exponent_vector=NULL;
+    // to avoid problems when deleting
+    return;
+  }
+
+
+  exponent_vector=new Integer[_number_of_variables];
+
+  short size_of_support_vectors=CHAR_BIT*sizeof(unsigned long);
+  // number of bits of a long int
+
+  // determine head and tail
+  short sign;
+  if(w.compare_to_zero(exponents)>=0)
+    sign=1;
+  else
+    sign=-1;
+
+
+  for(short i=0;i<_number_of_variables;i++)
+  {
+
+#ifdef SUPPORT_VARIABLES_FIRST
+
+    Integer actual_entry=sign*exponents[i];
+    exponent_vector[i]=actual_entry;
+
+#endif  // SUPPORT_VARIABLES_FIRST
+
+#ifdef SUPPORT_VARIABLES_LAST
+
+    short j=_number_of_variables-1-i;
+    Integer actual_entry=sign*exponents[j];
+    exponent_vector[j]=actual_entry;
+
+#endif  // SUPPORT_VARIABLES_LAST
+
+    if(i<size_of_support_vectors)
+    {
+      // variable i is considered in the support vectors
+      if(actual_entry>0)
+        head_support|=(1<<i);
+        // bit i of head_support is set to 1 (counting from 0)
+      else if(actual_entry<0)
+        tail_support|=(1<<i);
+        // bit i of tail_support is set to 1
+    }
+  }
+
+}
+
+
+
+
+binomial::binomial(const binomial& b)
+    :_number_of_variables(b._number_of_variables),
+     head_support(b.head_support),tail_support(b.tail_support)
+{
+  exponent_vector=new Integer[_number_of_variables];
+  for(short i=0;i<_number_of_variables;i++)
+    exponent_vector[i]=b.exponent_vector[i];
+}
+
+
+
+
+#endif  // SUPPORT_DRIVEN_METHODS
+
+
+
+
+binomial::~binomial()
+{
+  delete[] exponent_vector;
+}
+
+
+
+
+/////////////////// object information /////////////////////////////////////
+
+
+
+
+short binomial::number_of_variables() const
+{
+  return _number_of_variables;
+}
+
+
+
+
+short binomial::error_status() const
+{
+  if(_number_of_variables<0)
+    return _number_of_variables;
+  return 0;
+}
+
+
+
+
+//////////////////// assignment and access operators ////////////////////////
+
+
+
+
+binomial& binomial::operator=(const binomial& b)
+{
+
+  if(&b==this)
+    return *this;
+
+
+#ifdef SUPPORT_DRIVEN_METHODS
+
+  head_support=b.head_support;
+  tail_support=b.tail_support;
+
+#endif  // SUPPORT_DRIVEN_METHODS
+
+  if(_number_of_variables!=b._number_of_variables)
+  {
+    delete[] exponent_vector;
+    _number_of_variables=b._number_of_variables;
+
+    if(_number_of_variables<=0)
+    {
+      cerr<<"\nWARNING: binomial& binomial::operator=(const binomial&):\n"
+        "assigment from corrupt binomial"<<endl;
+      exponent_vector=NULL;
+      return (*this);
+    }
+
+    exponent_vector=new Integer[_number_of_variables];
+  }
+
+  for(short i=0;i<_number_of_variables;i++)
+    exponent_vector[i]=b.exponent_vector[i];
+
+  return(*this);
+}
+
+
+
+
+Integer binomial::operator[](const short& i) const
+{
+  return exponent_vector[i];
+}
+
+
+
+
+//////////////////// comparison operators ///////////////////////////////////
+
+
+
+
+BOOLEAN binomial::operator==(const binomial& b) const
+{
+  if(this == &b)
+    return(TRUE);
+
+#ifdef SUPPORT_DRIVEN_METHODS
+
+  if(head_support!=b.head_support)
+    return(FALSE);
+  if(tail_support!=b.tail_support)
+    return(FALSE);
+
+#endif  // SUPPORT_DRIVEN_METHODS
+
+  for(short i=0;i<_number_of_variables;i++)
+    if(exponent_vector[i]!=b.exponent_vector[i])
+      return(FALSE);
+  return(TRUE);
+}
+
+
+
+
+BOOLEAN binomial::operator!=(const binomial& b) const
+{
+  if(this == &b)
+    return(FALSE);
+
+#ifdef SUPPORT_DRIVEN_METHODS
+
+  if(head_support!=b.head_support)
+    return(TRUE);
+  if(tail_support!=b.tail_support)
+    return(TRUE);
+
+#endif  // SUPPORT_DRIVEN_METHODS
+
+  for(short i=0;i<_number_of_variables;i++)
+    if(exponent_vector[i]!=b.exponent_vector[i])
+      return(TRUE);
+  return(FALSE);
+}
+
+
+
+
+// operators for efficient comparisons with the zero binomial (comp_value=0)
+
+BOOLEAN binomial::operator==(const Integer comp_value) const
+{
+
+#ifdef SUPPORT_DRIVEN_METHODS
+
+  if(comp_value==0)
+  {
+    if(head_support!=0)
+      return(FALSE);
+    if(tail_support!=0)
+      return(FALSE);
+  }
+
+#endif  // SUPPORT_DRIVEN_METHODS
+
+  for(short i=0;i<_number_of_variables;i++)
+    if(exponent_vector[i]!=comp_value)
+      return(FALSE);
+  return(TRUE);
+}
+
+
+
+
+BOOLEAN binomial::operator!=(const Integer comp_value) const
+{
+
+#ifdef SUPPORT_DRIVEN_METHODS
+
+  if(comp_value==0)
+  {
+    if(head_support!=0)
+      return(TRUE);
+    if(tail_support!=0)
+      return(TRUE);
+  }
+
+#endif  // SUPPORT_DRIVEN_METHODS
+
+  for(short i=0;i<_number_of_variables;i++)
+    if(exponent_vector[i]!=comp_value)
+      return(TRUE);
+  return(FALSE);
+}
+
+
+
+
+BOOLEAN binomial::operator<=(const Integer comp_value) const
+{
+
+#ifdef SUPPORT_DRIVEN_METHODS
+
+  if(comp_value==0)
+    if(head_support!=0)
+      return(FALSE);
+
+#endif  // SUPPORT_DRIVEN_METHODS
+
+  for(short i=0;i<_number_of_variables;i++)
+    if(exponent_vector[i]>comp_value)
+      return(FALSE);
+  return(TRUE);
+}
+
+
+
+
+BOOLEAN binomial::operator>=(const Integer comp_value) const
+{
+
+#ifdef SUPPORT_DRIVEN_METHODS
+
+  if(comp_value==0)
+    if(tail_support!=0)
+      return(FALSE);
+
+#endif
+
+  for(short i=0;i<_number_of_variables;i++)
+    if(exponent_vector[i]<comp_value)
+      return(FALSE);
+  return(TRUE);
+}
+
+
+
+
+////////////// basic routines for Buchbergers's algorithm //////////////////
+
+
+
+
+Integer binomial::head_reductions_by(const binomial& b) const
+// Returns the number of possible reductions of the actual binomial�s head
+// by the binomial b. This is the minimum of the quotients
+// exponent_vector[i]/b.exponent_vector[i]
+// where exponent_vector[i]>0 and b.exponent_vector[i]>0
+// (0 if there are no such quotients).
+// A negative return value means b=0 or head(b)=1.
+{
+
+
+#ifdef NO_SUPPORT_DRIVEN_METHODS
+
+  Integer result=-1;
+  Integer new_result=-1;
+  // -1 stands for infinitely many reductions
+
+  for(short i=0;i<_number_of_variables;i++)
+    // explicit sign tests for all components
+  {
+    Integer actual_b_component=b.exponent_vector[i];
+
+    if(actual_b_component>0)
+      // else variable i is not involved in the head of b
+    {
+      Integer actual_component=exponent_vector[i];
+
+      if(actual_component<actual_b_component)
+        return 0;
+
+      new_result=(Integer) (actual_component/actual_b_component);
+
+      // new_result>=1
+      if((new_result<result) || (result==-1))
+        // new (or first) minimum
+        result=new_result;
+    }
+ }
+
+#endif  // NO_SUPPORT_DRIVEN_METHODS
+
+
+#ifdef SUPPORT_DRIVEN_METHODS
+
+  if((head_support&b.head_support)!=b.head_support)
+    // head support of b not contained in head support, no reduction possible
+    return 0;
+
+
+  Integer result=-1;
+  Integer new_result=-1;
+  // -1 stands for infinitely many reductions
+
+
+  short size_of_support_vectors=CHAR_BIT*sizeof(long);
+  // number of bits of a long int
+  if(size_of_support_vectors>_number_of_variables)
+    size_of_support_vectors=_number_of_variables;
+    // number of components of the support vectors
+
+
+#ifdef SUPPORT_VARIABLES_FIRST
+
+  for(short i=0;i<size_of_support_vectors;i++)
+    // test support variables
+
+    if(b.head_support&(1<<i))
+      // bit i of b.head_support is 1
+    {
+      new_result=(Integer) (exponent_vector[i]/b.exponent_vector[i]);
+      // remember that exponent_vector[i]>0 !
+      // (head support contains that of b)
+
+      if(new_result==0)
+        // exponent_vector[i]<b.exponent_vector[i]
+        return 0;
+
+      // new_result>=1
+      if((new_result<result) || (result==-1))
+        // new (or first) minimum
+        result=new_result;
+    }
+
+
+  for(short i=size_of_support_vectors;i<_number_of_variables;i++)
+    // test non-support variables
+    // from now on we need explicit sign tests
+  {
+    Integer actual_b_component=b.exponent_vector[i];
+
+    if(actual_b_component>0)
+      // else variable i is not involved in the head of b
+    {
+      Integer actual_component=exponent_vector[i];
+
+      if(actual_component<actual_b_component)
+        return 0;
+
+      new_result=(Integer) (actual_component/actual_b_component);
+
+      // new_result>=1
+      if((new_result<result) || (result==-1))
+        // new (or first) minimum
+        result=new_result;
+    }
+  }
+
+#endif  // SUPPORT_VARIABLES_FIRST
+
+
+#ifdef SUPPORT_VARIABLES_LAST
+
+  for(short i=0;i<size_of_support_vectors;i++)
+    // test support variables
+
+    if(b.head_support&(1<<i))
+      // bit i of b.head_support is 1
+    {
+      short j=_number_of_variables-1-i;
+      new_result=(Integer) (exponent_vector[j]/ b.exponent_vector[j]);
+      // remember that exponent_vector[_number_of_variables-1-i]>0 !
+      // (head support contains that of b)
+
+      if(new_result==0)
+        // exponent_vector[_number_of_variables-1-i]
+        // <b.exponent_vector[_number_of_variables-1-i]
+        return 0;
+
+      // new_result>=1
+      if((new_result<result) || (result==-1))
+        // new (or first) minimum
+        result=new_result;
+    }
+
+
+  for(short i=size_of_support_vectors;i<_number_of_variables;i++)
+    // test non-support variables
+    // from now on we need explicit sign tests
+  {
+    short j=_number_of_variables-1-i;
+    Integer actual_b_component=b.exponent_vector[j];
+
+    if(actual_b_component>0)
+      // else variable number_of_variables-1-i is not involved in the head of b
+    {
+      Integer actual_component=exponent_vector[j];
+
+      if(actual_component<actual_b_component)
+        return 0;
+
+      new_result=(Integer) (actual_component/actual_b_component);
+
+      // new_result>=1
+      if((new_result<result) || (result==-1))
+        // new (or first) minimum
+        result=new_result;
+    }
+  }
+
+#endif  // SUPPORT_VARIABLES_LAST
+
+
+#endif  // SUPPORT_DRIVEN_METHODS
+
+
+  return(result);
+}
+
+
+
+
+Integer binomial::tail_reductions_by(const binomial& b) const
+// Returns the number of possible reductions of the actual binomial�s tail
+// by the binomial b. This is the minimum of the quotients
+// - exponent_vector[i]/b.exponent_vector[i]
+// where exponent_vector[i]<0 and b.exponent_vector[i]>0
+// (0 if there are no such quotients).
+// A negative return value means b=0 or head(b)=1.
+{
+
+
+#ifdef NO_SUPPORT_DRIVEN_METHODS
+
+  Integer result=-1;
+  Integer new_result=-1;
+  // -1 stands for infinitely many reductions
+
+  for(short i=0;i<_number_of_variables;i++)
+    // explicit sign tests for all components
+  {
+    Integer actual_b_component=b.exponent_vector[i];
+
+    if(actual_b_component>0)
+      // else variable i is not involved in the head of b
+    {
+      Integer actual_component=-exponent_vector[i];
+
+      if(actual_component<actual_b_component)
+        return 0;
+
+      new_result=(Integer) (actual_component/actual_b_component);
+
+      // new_result>=1
+      if((new_result<result) || (result==-1))
+        // new (or first) minimum
+        result=new_result;
+    }
+ }
+
+#endif  // NO_SUPPORT_DRIVEN_METHODS
+
+
+#ifdef SUPPORT_DRIVEN_METHODS
+
+  if((tail_support&b.head_support)!=b.head_support)
+    // head support of b not contained in tail support, no reduction possible
+    return 0;
+
+
+  Integer result=-1;
+  Integer new_result=-1;
+  // -1 stands for infinitely many reductions
+
+
+  short size_of_support_vectors=CHAR_BIT*sizeof(long);
+  // number of bits of a long int
+  if(size_of_support_vectors>_number_of_variables)
+    size_of_support_vectors=_number_of_variables;
+    // number of components of the support vectors
+
+
+#ifdef SUPPORT_VARIABLES_FIRST
+
+  for(short i=0;i<size_of_support_vectors;i++)
+    // test support variables
+
+    if(b.head_support&(1<<i))
+      // bit i of b.head_support is 1
+    {
+      new_result=(Integer) (-exponent_vector[i]/b.exponent_vector[i]);
+      // remember that exponent_vector[i]<0 !
+      // (tail support contains the head support of b)
+
+      if(new_result==0)
+        // -exponent_vector[i]<b.exponent_vector[i]
+        return 0;
+
+      // new_result>=1
+      if((new_result<result) || (result==-1))
+        // new (or first) minimum
+        result=new_result;
+    }
+
+
+  for(short i=size_of_support_vectors;i<_number_of_variables;i++)
+    // test non-support variables
+    // from now on we need explicit sign tests
+  {
+    Integer actual_b_component=b.exponent_vector[i];
+
+    if(actual_b_component>0)
+      // else variable i is not involved in the head of b
+    {
+      Integer actual_component=-exponent_vector[i];
+
+      if(actual_component<actual_b_component)
+        return 0;
+
+      new_result=(Integer) (actual_component/actual_b_component);
+
+      // new_result>=1
+      if((new_result<result) || (result==-1))
+        // new (or first) minimum
+        result=new_result;
+    }
+  }
+
+#endif  // SUPPORT_VARIABLES_FIRST
+
+
+#ifdef SUPPORT_VARIABLES_LAST
+
+  for(short i=0;i<size_of_support_vectors;i++)
+    // test support variables
+
+    if(b.head_support&(1<<i))
+      // bit i of b.head_support is 1
+    {
+      short j=_number_of_variables-1-i;
+      new_result=(Integer) (-exponent_vector[j] / b.exponent_vector[j]);
+      // remember that exponent_vector[_number_of_variables-1-i]<0 !
+      // (tail support contains the head support of b)
+
+      if(new_result==0)
+        // -exponent_vector[_number_of_variables-1-i]
+        // <b.exponent_vector[_number_of_variables-1-i]
+        return 0;
+
+      // new_result>=1
+      if((new_result<result) || (result==-1))
+        // new (or first) minimum
+        result=new_result;
+    }
+
+
+  for(short i=size_of_support_vectors;i<_number_of_variables;i++)
+    // test non-support variables
+    // from now on we need explicit sign tests
+  {
+    short j=_number_of_variables-1-i;
+    Integer actual_b_component=b.exponent_vector[j];
+
+    if(actual_b_component>0)
+      // else variable number_of_variables-1-i is not involved in the head of b
+    {
+      Integer actual_component=-exponent_vector[j];
+
+      if(actual_component<actual_b_component)
+        return 0;
+
+      new_result=(Integer) (actual_component/actual_b_component);
+
+      // new_result>=1
+      if((new_result<result) || (result==-1))
+        // new (or first) minimum
+        result=new_result;
+    }
+  }
+
+#endif  // SUPPORT_VARIABLES_LAST
+
+
+#endif  // SUPPORT_DRIVEN_METHODS
+
+
+  return(result);
+}
+
+
+
+
+int binomial::reduce_head_by(const binomial& b, const term_ordering& w)
+{
+  Integer reduction_number=head_reductions_by(b);
+  if(reduction_number<=0)
+    return 0;
+
+  for(short i=0;i<_number_of_variables;i++)
+    exponent_vector[i]-=(reduction_number * b.exponent_vector[i]);
+  // multiple reduction
+  // reduction corresponds to subtraction of vectors
+
+  short sign=w.compare_to_zero(exponent_vector);
+
+
+#ifdef NO_SUPPORT_DRIVEN_METHODS
+
+  if(sign==0)
+    // binomial reduced to zero
+    return 2;
+
+  for(short i=0;i<_number_of_variables;i++)
+    exponent_vector[i]*=sign;
+
+#endif  // NO_SUPPORT_DRIVEN_METHODS
+
+
+#ifdef SUPPORT_DRIVEN_METHODS
+
+  head_support=0;
+  tail_support=0;
+
+  if(sign==0)
+    // binomial reduced to zero
+    return 2;
+
+  short size_of_support_vectors=CHAR_BIT*sizeof(unsigned long);
+
+
+  // recompute the support vectors
+
+#ifdef SUPPORT_VARIABLES_FIRST
+
+  for(short i=0;i<_number_of_variables;i++)
+  {
+
+    Integer& actual_entry=exponent_vector[i];
+    // to avoid unnecessary pointer arithmetic
+
+    actual_entry*=sign;
+
+    if(i<size_of_support_vectors)
+      if(actual_entry>0)
+        head_support|=(1<<i);
+      else
+        if(actual_entry<0)
+          tail_support|=(1<<i);
+  }
+
+#endif  // SUPPORT_VARIABLES_FIRST
+
+
+#ifdef SUPPORT_VARIABLES_LAST
+
+  for(short i=0;i<_number_of_variables;i++)
+  {
+    Integer& actual_entry=exponent_vector[_number_of_variables-1-i];
+    // to avoid unneccessary pointer arithmetic
+
+    actual_entry*=sign;
+
+    if(i<size_of_support_vectors)
+    {
+      if(actual_entry>0)
+        head_support|=(1<<i);
+      else if(actual_entry<0)
+        tail_support|=(1<<i);
+    }
+  }
+
+#endif  // SUPPORT_VARIABLES_LAST
+
+
+#endif  // SUPPORT_DRIVEN_METHODS
+
+  return 1;
+}
+
+
+
+
+int binomial::reduce_tail_by(const binomial& b, const term_ordering& w)
+{
+  Integer reduction_number=tail_reductions_by(b);
+  if(reduction_number<=0)
+    return 0;
+
+  for(short i=0;i<_number_of_variables;i++)
+    exponent_vector[i]+=(reduction_number * b.exponent_vector[i]);
+  // multiple reduction
+  // reduction corresponds to addition of vectors
+
+  // a tail reduction does not require a sign check
+
+
+#ifdef SUPPORT_DRIVEN_METHODS
+
+  head_support=0;
+  tail_support=0;
+
+  short size_of_support_vectors=CHAR_BIT*sizeof(unsigned long);
+
+
+  // recompute the support vectors
+
+#ifdef SUPPORT_VARIABLES_FIRST
+
+  for(short i=0;i<_number_of_variables;i++)
+  {
+
+    Integer& actual_entry=exponent_vector[i];
+    // to avoid unnecessary pointer arithmetic
+
+    if(i<size_of_support_vectors)
+    {
+      if(actual_entry>0)
+        head_support|=(1<<i);
+      else if(actual_entry<0)
+        tail_support|=(1<<i);
+    }
+  }
+
+#endif  // SUPPORT_VARIABLES_FIRST
+
+
+#ifdef SUPPORT_VARIABLES_LAST
+
+  for(short i=0;i<_number_of_variables;i++)
+  {
+    Integer& actual_entry=exponent_vector[_number_of_variables-1-i];
+    // to avoid unneccessary pointer arithmetic
+
+    if(i<size_of_support_vectors)
+    {
+      if(actual_entry>0)
+        head_support|=(1<<i);
+      else if(actual_entry<0)
+        tail_support|=(1<<i);
+    }
+  }
+
+#endif  // SUPPORT_VARIABLES_LAST
+
+
+#endif  // SUPPORT_DRIVEN_METHODS
+
+  return 1;
+}
+
+
+
+
+binomial& S_binomial(const binomial& a, const binomial& b,
+                     const term_ordering& w)
+{
+  binomial* S_bin=new binomial(a._number_of_variables);
+  binomial& result=*S_bin;
+  // Note that we allocate memory for the result binomial. We often use
+  // pointers or references as argument and return types because the
+  // generating binomials of an ideal are kept in lists. For the performance
+  // of Buchberger's algorithm it it very important to avoid local copies
+  // of binomials, so a lot of attention is paid on the choice of argument
+  // and return types. As this choice is done in order to improve performance,
+  // it might be a bad choice with respect to code reuse (there are some
+  // dangerous constructions).
+
+  for(short i=0;i<result._number_of_variables;i++)
+    result.exponent_vector[i]=a.exponent_vector[i]-b.exponent_vector[i];
+  // The S-binomial corresponds to the vector difference.
+
+  // compute head and tail
+  short sign=w.compare_to_zero(result.exponent_vector);
+
+
+#ifdef NO_SUPPORT_DRIVEN_METHODS
+
+  if(sign==0)
+    // binomial reduced to zero
+    return result;
+
+  for(short i=0;i<result._number_of_variables;i++)
+    result.exponent_vector[i]*=sign;
+
+#endif  // NO_SUPPORT_DRIVEN_METHODS
+
+
+#ifdef SUPPORT_DRIVEN_METHODS
+
+  result.head_support=0;
+  result.tail_support=0;
+
+  if(sign==0)
+    // binomial reduced to zero
+    return result;
+
+  short size_of_support_vectors=CHAR_BIT*sizeof(unsigned long);
+
+
+  // recompute the support vectors
+
+#ifdef SUPPORT_VARIABLES_FIRST
+
+  for(short i=0;i<result._number_of_variables;i++)
+  {
+
+    Integer& actual_entry=result.exponent_vector[i];
+    // to avoid unnecessary pointer arithmetic
+
+    actual_entry*=sign;
+
+    if(i<size_of_support_vectors)
+    {
+      if(actual_entry>0)
+        result.head_support|=(1<<i);
+      else if(actual_entry<0)
+        result.tail_support|=(1<<i);
+    }
+  }
+
+#endif  // SUPPORT_VARIABLES_FIRST
+
+
+#ifdef SUPPORT_VARIABLES_LAST
+
+  for(short i=0;i<result._number_of_variables;i++)
+  {
+    Integer& actual_entry=result.exponent_vector
+      [result._number_of_variables-1-i];
+    // to avoid unneccessary pointer arithmetic
+
+    actual_entry*=sign;
+
+    if(i<size_of_support_vectors)
+    {
+      if(actual_entry>0)
+        result.head_support|=(1<<i);
+      else if(actual_entry<0)
+          result.tail_support|=(1<<i);
+    }
+  }
+
+#endif  // SUPPORT_VARIABLES_LAST
+
+
+#endif  // SUPPORT_DRIVEN_METHODS
+
+
+  return result;
+}
+
+
+
+
+///////////// criteria for unnecessary S-pairs ///////////////////////////////
+
+// The criteria are programmed in a way that tries to minimize pointer
+// arithmetic. Therefore the code may appear a little bit inflated.
+
+
+
+
+BOOLEAN relatively_prime(const binomial& a, const binomial& b)
+{
+
+#ifdef NO_SUPPORT_DRIVEN_METHODS
+
+  // look at all variables
+  for(short i=0;i<a._number_of_variables;i++)
+    if((a.exponent_vector[i]>0) && (b.exponent_vector[i]>0))
+      return FALSE;
+
+  return TRUE;
+
+#endif  // NO_SUPPORT_DRIVEN_METHODS
+
+
+#ifdef SUPPORT_DRIVEN_METHODS
+
+  if((a.head_support & b.head_support)!=0)
+  // common support variable in the heads
+    return FALSE;
+
+  // no common support variable in the heads, look at remaining variables
+  short size_of_support_vectors=CHAR_BIT*sizeof(unsigned long);
+
+
+#ifdef SUPPORT_VARIABLES_FIRST
+
+  for(short i=size_of_support_vectors;i<a._number_of_variables;i++)
+    if((a.exponent_vector[i]>0) && (b.exponent_vector[i]>0))
+      return FALSE;
+
+  return TRUE;
+
+#endif  // SUPPORT_VARIABLES_FIRST
+
+
+#ifdef SUPPORT_VARIABLES_LAST
+
+  for(short i=a._number_of_variables-1-size_of_support_vectors;i>=0;i--)
+    if((a.exponent_vector[i]>0) && (b.exponent_vector[i]>0))
+      return FALSE;
+
+  return TRUE;
+
+#endif  // SUPPORT_VARIABLES_LAST
+
+
+#endif  // SUPPORT_DRIVEN_METHODS
+
+}
+
+
+
+
+BOOLEAN M(const binomial& a, const binomial& b, const binomial& c)
+// Returns TRUE iff lcm(head(a),head(c)) divides properly lcm(head(b),head(c)).
+// This is checked by comparing the positive components of the exponent
+// vectors.
+{
+
+
+#ifdef SUPPORT_DRIVEN_METHODS
+
+  long b_or_c=b.head_support|c.head_support;
+
+  if((a.head_support|b_or_c) != b_or_c)
+    return FALSE;
+  // The support of lcm(head(a),head(c)) equals the union of the head supports
+  // of a and c. The above condition verifies if the support of
+  // lcm(head(a),head(c)) is contained in the support of lcm(head(b),head(c))
+  // by checking if head a involves a variable that is not involved in
+  // head(b) or head(c).
+
+#endif  // SUPPORT_DRIVEN_METHODS
+
+
+  BOOLEAN properly=FALSE;
+
+  for(short i=0;i<a._number_of_variables;i++)
+  {
+    Integer a_exponent=a.exponent_vector[i];
+    Integer b_exponent=b.exponent_vector[i];
+    Integer c_exponent=c.exponent_vector[i];
+    Integer m1=MAXIMUM(a_exponent,c_exponent);
+    Integer m2=MAXIMUM(b_exponent,c_exponent);
+
+    if(m1>0)
+    {
+      if(m1>m2)
+        return FALSE;
+      if(m1<m2)
+        properly=TRUE;
+    }
+  }
+
+  return properly;
+}
+
+
+
+
+BOOLEAN F(const binomial& a, const binomial& b, const binomial& c)
+// verifies if lcm(head(a),head(c))=lcm(head(b),head(c))
+{
+
+#ifdef SUPPORT_DRIVEN_METHODS
+
+  if((a.head_support|c.head_support)!=(b.head_support|c.head_support))
+    return FALSE;
+  // The above condition verifies if the support of lcm(head(a),head(c))
+  // equals the support of lcm(head(b),head(c)).
+
+#endif  // SUPPORT_DRIVEN_METHODS
+
+  for(short i=0;i<a._number_of_variables;i++)
+  {
+    Integer a_exponent=a.exponent_vector[i];
+    Integer b_exponent=b.exponent_vector[i];
+    Integer c_exponent=c.exponent_vector[i];
+    Integer m1=MAXIMUM(a_exponent,c_exponent);
+    Integer m2=MAXIMUM(b_exponent,c_exponent);
+
+    if((m1!=m2) && (m1>0 || m2>0))
+      return FALSE;
+  }
+
+  return TRUE;
+}
+
+
+
+
+BOOLEAN B(const binomial& a, const binomial& b, const binomial& c)
+// verifies if head(a) divides lcm(head(b),head(c)) and
+// lcm(head(a),head(b))!=lcm(head(b),head(c))!=lcm(head(a),head(c))
+{
+
+#ifdef SUPPORT_DRIVEN_METHODS
+
+  long a_or_b=a.head_support|b.head_support;
+  long a_or_c=a.head_support|c.head_support;
+  long b_or_c=b.head_support|c.head_support;
+
+  if((a.head_support & b_or_c)!=a.head_support)
+    return FALSE;
+  // The above condition verifies if the support of head(a) is contained in
+  // the support of lcm(head(b),head(c)).
+
+  if( (a_or_c != b_or_c) && (a_or_b != b_or_c))
+    // Then the inequality conditions are guaranteed...
+  {
+    for(short i=0;i<a._number_of_variables;i++)
+    {
+      Integer b_exponent=b.exponent_vector[i];
+      Integer c_exponent=c.exponent_vector[i];
+
+      if(a.exponent_vector[i]>MAXIMUM(b_exponent,c_exponent))
+        return FALSE;
+    }
+
+    return (TRUE);
+  }
+
+
+  if(a_or_b != b_or_c)
+    // Then the first inequality conditions is guaranteed...
+    // Verifie only the second.
+  {
+    BOOLEAN not_equal=FALSE;
+
+    for(short i=0;i<a._number_of_variables;i++)
+    {
+      Integer a_exponent=a.exponent_vector[i];
+      Integer b_exponent=b.exponent_vector[i];
+      Integer c_exponent=c.exponent_vector[i];
+      Integer m=MAXIMUM(b_exponent, c_exponent);
+
+      if(a_exponent>m)
+        return FALSE;
+
+      if(MAXIMUM(a_exponent,c_exponent) != m)
+         not_equal=TRUE;
+    }
+    return(not_equal);
+  }
+
+
+  if( a_or_c != b_or_c )
+    // Then the second inequality conditions is guaranteed...
+    // Verifie only the first.
+  {
+    BOOLEAN not_equal=FALSE;
+
+    for(short i=0;i<a._number_of_variables;i++)
+    {
+      Integer a_exponent=a.exponent_vector[i];
+      Integer b_exponent=b.exponent_vector[i];
+      Integer c_exponent=c.exponent_vector[i];
+      Integer m=MAXIMUM(b_exponent, c_exponent);
+
+      if(a_exponent > m)
+        return FALSE;
+
+      if(MAXIMUM(a_exponent,b_exponent) != m)
+        not_equal=TRUE;
+    }
+    return(not_equal);
+  }
+
+#endif  // SUPPORT_DRIVEN_METHODS
+
+
+  BOOLEAN not_equal_1=FALSE;
+  BOOLEAN not_equal_2=FALSE;
+
+  for(short i=0;i<a._number_of_variables;i++)
+  {
+    Integer a_exponent=a.exponent_vector[i];
+    Integer b_exponent=b.exponent_vector[i];
+    Integer c_exponent=c.exponent_vector[i];
+    Integer m=MAXIMUM(b_exponent, c_exponent);
+
+    if(a_exponent > m)
+      return FALSE;
+
+    if(MAXIMUM(a_exponent,b_exponent) != m)
+      not_equal_1=TRUE;
+    if(MAXIMUM(a_exponent,c_exponent) != m)
+      not_equal_2=TRUE;
+  }
+
+  return (not_equal_1 && not_equal_2);
+
+}
+
+
+
+
+BOOLEAN second_crit(const binomial& a, const binomial& b,
+                    const binomial& c)
+// verifies if head(a) divides lcm(head(b),head(c))
+{
+
+#ifdef SUPPORT_DRIVEN_METHODS
+
+  if((a.head_support & (b.head_support|c.head_support))!=a.head_support)
+    return FALSE;
+  // The above condition verifies if the support of head(a) is contained in
+  // the support of lcm(head(b),head(c))
+
+#endif  // SUPPORT_DRIVEN_METHODS.
+
+  for(short i=0;i<a._number_of_variables;i++)
+  {
+    Integer b_exponent=b.exponent_vector[i];
+    Integer c_exponent=c.exponent_vector[i];
+
+    if(a.exponent_vector[i]>MAXIMUM(b_exponent,c_exponent))
+      return FALSE;
+  }
+
+  return (TRUE);
+}
+
+
+
+
+//////// special routines needed by the IP-algorithms ///////////////////////
+
+
+
+
+BOOLEAN binomial::involves_elimination_variables(const term_ordering& w)
+{
+// The use of support information would require the distinction of various
+// cases here (relation between the number of variables to eliminate
+// and the number of support variables) and be quite difficult.
+// It is doubtful if this would improve performance.
+// As this function is not used in Buchberger�s algorithm (and therefore
+// rather rarely), I renounce to implement this.
+
+  for(short i=0;i<w.number_of_elimination_variables();i++)
+    // elimination variables are always the last ones
+    if(exponent_vector[_number_of_variables-1-i]!=0)
+      return TRUE;
+
+  return FALSE;
+}
+
+
+
+
+BOOLEAN binomial::drop_elimination_variables(const term_ordering& w)
+{
+  _number_of_variables-=w.number_of_elimination_variables();
+  // dangerous (no compatibility check)!!
+
+  // copy components of interest to save memory
+  // the leading term has to be recomputed!!
+
+  Integer *aux=exponent_vector;
+  exponent_vector=new Integer[_number_of_variables];
+
+  if(w.weight(aux)>=0)
+    for(short i=0;i<_number_of_variables;i++)
+      exponent_vector[i]=aux[i];
+  else
+    for(short i=0;i<_number_of_variables;i++)
+      exponent_vector[i]=-aux[i];
+
+  delete[] aux;
+
+
+#ifdef SUPPORT_DRIVEN_METHODS
+
+  // Recompute head and tail.
+  // Normally, this routine is only called for binomials that do not involve
+  // the variables to eliminate. But if SUPPORT_VARIABLES_LAST is enabled,
+  // the support changes in spite of this. Therefore, the support is
+  // recomputed... For the same reasons as mentionned in the preceeding
+  // routine, the existing support information is not used.
+
+  head_support=0;
+  tail_support=0;
+  short size_of_support_vectors=CHAR_BIT*sizeof(unsigned long);
+  if(size_of_support_vectors>_number_of_variables)
+    size_of_support_vectors=_number_of_variables;
+
+
+#ifdef SUPPORT_VARIABLES_FIRST
+
+  for(short i=0;i<size_of_support_vectors;i++)
+  {
+    Integer actual_entry=exponent_vector[i];
+    if(actual_entry>0)
+      head_support|=(1<<i);
+    else if(actual_entry[i]<0)
+      tail_support|=(1<<i);
+  }
+
+#endif  // SUPPORT_VARIABLES_FIRST
+
+
+#ifdef SUPPORT_VARIABLES_LAST
+
+  for(short i=0;i<size_of_support_vectors;i++)
+  {
+    Integer actual_entry=exponent_vector[_number_of_variables-1-i];
+    if(actual_entry>0)
+      head_support|=(1<<i);
+    else if(actual_entry<0)
+      tail_support|=(1<<i);
+  }
+
+#endif  // SUPPORT_VARIABLES_LAST
+
+
+#endif  // SUPPORT_DRIVEN_METHODS
+  return TRUE;
+
+}
+
+
+
+
+BOOLEAN binomial::drop_last_weighted_variable(const term_ordering& w)
+{
+  _number_of_variables--;
+  // dangerous!!
+
+  // copy components of interest to save memory
+  // the leading term has to be recomputed!!
+
+  Integer *aux=exponent_vector;
+  exponent_vector=new Integer[_number_of_variables];
+
+  short last_weighted_variable=w.number_of_weighted_variables()-1;
+  aux[last_weighted_variable]=0;
+  // set last component to zero, so it cannot influence the weight
+
+  if(w.weight(aux)>=0)
+  {
+    for(short i=0;i<last_weighted_variable;i++)
+      exponent_vector[i]=aux[i];
+    for(short i=last_weighted_variable;i<_number_of_variables;i++)
+      exponent_vector[i]=aux[i+1];
+  }
+  else
+  {
+    for(short i=0;i<last_weighted_variable;i++)
+      exponent_vector[i]=-aux[i];
+     for(short i=last_weighted_variable;i<_number_of_variables;i++)
+      exponent_vector[i]=-aux[i+1];
+  }
+
+  delete[] aux;
+
+
+#ifdef SUPPORT_DRIVEN_METHODS
+
+  // Recompute head and tail.
+  // Normally, this routine is only called for binomials that do not involve
+  // the variable to be dropped. But if SUPPORT_VARIABLES_LAST is enabled,
+  // the support changes in spite of this. Therefore, the support is
+  // recomputed... For the same reasons as mentionned in the preceeding
+  // routines, the existing support information is not used.
+
+  head_support=0;
+  tail_support=0;
+  short size_of_support_vectors=CHAR_BIT*sizeof(unsigned long);
+  if(size_of_support_vectors>_number_of_variables)
+    size_of_support_vectors=_number_of_variables;
+
+
+#ifdef SUPPORT_VARIABLES_FIRST
+
+  for(short i=0;i<size_of_support_vectors;i++)
+  {
+    Integer actual_entry=exponent_vector[i];
+    if(actual_entry>0)
+      head_support|=(1<<i);
+    else if(actual_entry<0)
+      tail_support|=(1<<i);
+  }
+
+#endif  // SUPPORT_VARIABLES_FIRST
+
+
+#ifdef SUPPORT_VARIABLES_LAST
+
+  for(short i=0;i<size_of_support_vectors;i++)
+  {
+    Integer actual_entry=exponent_vector[_number_of_variables-1-i];
+    if(actual_entry>0)
+      head_support|=(1<<i);
+    else if(actual_entry<0)
+      tail_support|=(1<<i);
+  }
+
+#endif  // SUPPORT_VARIABLES_LAST
+
+#endif  // SUPPORT_DRIVEN_METHODS
+  return TRUE;
+}
+
+
+
+
+int binomial::adapt_to_term_ordering(const term_ordering& w)
+{
+
+  if(w.compare_to_zero(exponent_vector)<0)
+  {
+    // then exchange head and tail
+    for(short i=0;i<_number_of_variables;i++)
+      exponent_vector[i]*=(-1);
+
+
+#ifdef SUPPORT_DRIVEN_METHODS
+
+    unsigned long swap=head_support;
+    head_support=tail_support;
+    tail_support=swap;
+
+#endif
+
+
+    return -1;
+    // binomial changed
+  }
+
+  else
+    return 1;
+    // binomial unchanged
+}
+
+
+
+
+binomial& binomial::swap_variables(const short& i, const short& j)
+{
+
+
+#ifdef SUPPORT_DRIVEN_METHODS
+
+  // First adjust head_support and tail_support.
+
+  short size_of_support_vectors=CHAR_BIT*sizeof(unsigned long);
+  if(size_of_support_vectors>_number_of_variables)
+    size_of_support_vectors=_number_of_variables;
+
+
+#ifdef SUPPORT_VARIABLES_FIRST
+
+  if(i<size_of_support_vectors)
+    // else i is no support variable
+  {
+    if(exponent_vector[j]>0)
+    // bit i will be 1 in the new head_support, 0 in the new tail_support
+    {
+      head_support|=(1<<i);
+      // bit i is set to 1
+
+      tail_support&=~(1<<i);
+      // bit i is set to 0
+      // (in the complement ~(1<<i) all bits are 1 except from bit i)
+    }
+
+    if(exponent_vector[j]==0)
+    // bit i will be 0 in the new head_support, 0 in the new tail_support
+    {
+      head_support&=~(1<<i);
+      // bit i is set to 0
+
+      tail_support&=~(1<<i);
+      // bit i is set to 0
+    }
+
+    if(exponent_vector[j]<0)
+    // bit i will be 0 in the new head_support, 1 in the new tail_support
+    {
+      head_support&=~(1<<i);
+      // bit i is set to 0
+
+      tail_support|=(1<<i);
+      // bit i is set to 1
+    }
+  }
+
+
+  if(j<size_of_support_vectors)
+    // else j is no support variable
+  {
+    if(exponent_vector[i]>0)
+    // bit j will be 1 in the new head_support, 0 in the new tail_support
+    {
+      head_support|=(1<<j);
+      // bit j is set to 1
+
+      tail_support&=~(1<<j);
+      // bit j is set to 0
+      // (in the complement ~(1<<j) all bits are 1 except from bit j)
+    }
+
+    if(exponent_vector[i]==0)
+    // bit j will be 0 in the new head_support, 0 in the new tail_support
+    {
+      head_support&=~(1<<j);
+      // bit j is set to 0
+
+      tail_support&=~(1<<j);
+      // bit j is set to 0
+    }
+
+    if(exponent_vector[i]<0)
+    // bit j will be 0 in the new head_support, 1 in the new tail_support
+    {
+      head_support&=~(1<<j);
+      // bit j is set to 0
+
+      tail_support|=(1<<j);
+      // bit j is set to 1
+    }
+  }
+
+#endif  // SUPPORT_VARIABLES_FIRST
+
+
+#ifdef SUPPORT_VARIABLES_LAST
+
+  // Using SUPPORT_VARIABLES_LAST, bit k of the support vectors
+  // corresponds to exponent_vector[_number_of_variables-1-k],
+  // hence bit _number_of_variables-1-i to exponent_vector[i].
+
+  if(i>=_number_of_variables-size_of_support_vectors)
+    // else i is no support variable
+  {
+    if(exponent_vector[j]>0)
+    // bit _number_of_variables-1-i will be 1 in the new head_support,
+    // 0 in the new tail_support
+    {
+      short k=_number_of_variables-1-i;
+
+      head_support|=(1<<k);
+      // bit _number_of_variables-1-i is set to 1
+
+      tail_support&=~(1<<k);
+      // bit _number_of_variables-1-i is set to 0
+      // (in the complement ~(1<<(_number_of_variables-1-i)) all bits are 1
+      // except from bit _number_of_variables-1-i)
+    }
+
+    if(exponent_vector[j]==0)
+    // bit _number_of_variables-1-i will be 0 in the new head_support,
+    // 0 in the new tail_support
+    {
+      short k=_number_of_variables-1-i;
+
+      head_support&=~(1<<k);
+      // bit _number_of_variables-1-i is set to 0
+
+      tail_support&=~(1<<k);
+      // bit _number_of_variables-1-i is set to 0
+    }
+
+    if(exponent_vector[j]<0)
+    // bit _number_of_variables-1-i will be 0 in the new head_support,
+     // 1 in the new tail_support
+    {
+      short k=_number_of_variables-1-i;
+
+      head_support&=~(1<<k);
+      // bit _number_of_variables-1-i is set to 0
+
+      tail_support|=(1<<k);
+      // bit _number_of_variables-1-i is set to 1
+    }
+  }
+
+
+  if(j>=_number_of_variables-size_of_support_vectors)
+      // else j is no support variable
+  {
+   if(exponent_vector[i]>0)
+    // bit _number_of_variables-1-j will be 1 in the new head_support,
+    // 0 in the new tail_support
+    {
+      short k=_number_of_variables-1-j;
+
+      head_support|=(1<<k);
+      // bit _number_of_variables-1-j is set to 1
+
+      tail_support&=~(1<<k);
+      // bit _number_of_variables-1-j is set to 0
+      // (in the complement ~(1<<(_number_of_variables-1-j)) all bits are 1
+      // except from bit _number_of_variables-1-j)
+    }
+
+    if(exponent_vector[i]==0)
+    // bit _number_of_variables-1-j will be 0 in the new head_support,
+    // 0 in the new tail_support
+    {
+      short k=_number_of_variables-1-j;
+
+      head_support&=~(1<<k);
+      // bit _number_of_variables-1-j is set to 0
+
+      tail_support&=~(1<<k);
+      // bit _number_of_variables-1-j is set to 0
+    }
+
+    if(exponent_vector[i]<0)
+    // bit _number_of_variables-1-j will be 0 in the new head_support,
+     // 1 in the new tail_support
+    {
+      short k=_number_of_variables-1-j;
+
+      head_support&=~(1<<k);
+      // bit _number_of_variables-1-j is set to 0
+
+      tail_support|=(1<<k);
+      // bit _number_of_variables-1-j is set to 1
+    }
+  }
+
+#endif  // SUPPORT_VARIABLES_LAST
+
+#endif  // SUPPORT_DRIVEN_METHODS
+
+
+// Now swap the components.
+
+  Integer swap=exponent_vector[j];
+  exponent_vector[j]=exponent_vector[i];
+  exponent_vector[i]=swap;
+
+  return *this;
+
+}
+
+binomial& binomial::flip_variable(const short& i)
+{
+
+  if(exponent_vector[i]==0)
+    // binomial does not involve variable to flip
+    return *this;
+
+
+#ifdef SUPPORT_DRIVEN_METHODS
+
+// First adjust head_support and tail_support.
+
+  short size_of_support_vectors=CHAR_BIT*sizeof(unsigned long);
+  if(size_of_support_vectors>_number_of_variables)
+    size_of_support_vectors=_number_of_variables;
+
+
+#ifdef SUPPORT_VARIABLES_FIRST
+
+  if(i<size_of_support_vectors)
+    // else i is no support variable
+  {
+    if(exponent_vector[i]>0)
+      // variable i will be moved from head to tail
+    {
+      head_support&=~(1<<i);
+      // bit i is set to 0
+
+      tail_support|=(1<<i);
+      // bit i is set to 1
+    }
+
+    else
+      // variable i will be moved from tail to head
+      // remember that exponent_vector[i]!=0
+    {
+      tail_support&=~(1<<i);
+      // bit i is set to 0
+
+      head_support|=(1<<i);
+      // bit i is set to 1
+    }
+  }
+#endif  // SUPPORT_VARIABLES_FIRST
+
+#ifdef SUPPORT_VARIABLES_LAST
+
+  // Using SUPPORT_VARIABLES_LAST, bit k of the support vectors
+  // corresponds to exponent_vector[_number_of_variables-1-k],
+  // hence bit _number_of_variables-1-i to exponent_vector[i].
+
+  if(i>=_number_of_variables-size_of_support_vectors)
+    // else i is no support variable
+  {
+    if(exponent_vector[i]>0)
+    // variable i will be moved from head to tail
+    {
+      short k=_number_of_variables-1-i;
+
+      head_support&=~(1<<k);
+      // bit _number_of_variables-1-i is set to 0
+
+      tail_support|=(1<<k);
+      // bit _number_of_variables-1-i is set to 1
+
+     }
+
+    else
+    // variable i will be moved from tail to head
+    {
+      short k=_number_of_variables-1-i;
+
+      tail_support&=~(1<<k);
+      // bit _number_of_variables-1-i is set to 0
+
+      head_support|=(1<<k);
+      // bit _number_of_variables-1-i is set to 1
+
+    }
+  }
+#endif  // SUPPORT_VARIABLES_LAST
+
+
+#endif  // SUPPORT_DRIVEN_METHODS
+
+  // Now flip the variable.
+
+  exponent_vector[i]*=-1;
+  return *this;
+}
+
+////////////////////////// output /////////////////////////////////////////
+
+void binomial::print() const
+{
+  printf("(");
+  for(short i=0;i<_number_of_variables-1;i++)
+    printf("%6d,",exponent_vector[i]);
+  printf("%6d)\n",exponent_vector[_number_of_variables-1]);
+}
+
+void binomial::print_all() const
+{
+  print();
+
+#ifdef SUPPORT_DRIVEN_METHODS
+
+  printf("head: %ld, tail %ld\n",head_support,tail_support);
+
+#endif  // SUPPORT_DRIVEN_METHODS
+}
+
+void binomial::print(FILE* output) const
+{
+  fprintf(output,"(");
+  for(short i=0;i<_number_of_variables-1;i++)
+    fprintf(output,"%6d,",exponent_vector[i]);
+  fprintf(output,"%6d)\n",exponent_vector[_number_of_variables-1]);
+}
+
+void binomial::print_all(FILE* output) const
+{
+  print(output);
+
+#ifdef SUPPORT_DRIVEN_METHODS
+
+  fprintf(output,"head: %ld, tail %ld\n",head_support,tail_support);
+
+#endif  // SUPPORT_DRIVEN_METHODS
+}
+
+void binomial::print(ofstream& output) const
+{
+  output<<"(";
+  for(short i=0;i<_number_of_variables-1;i++)
+    output<<setw(6)<<exponent_vector[i]<<",";
+  output<<setw(6)<<exponent_vector[_number_of_variables-1]<<")"<<endl;
+}
+
+void binomial::print_all(ofstream& output) const
+{
+  print(output);
+
+#ifdef SUPPORT_DRIVEN_METHODS
+
+  output<<"head: "<<setw(16)<<head_support<<", tail: "<<setw(16)
+        <<tail_support<<endl;
+
+#endif  // SUPPORT_DRIVEN_METHODS
+}
+
+void binomial::format_print(ofstream& output) const
+{
+  for(short i=0;i<_number_of_variables;i++)
+    output<<setw(6)<<exponent_vector[i];
+  output<<endl;
+}
+
+#endif  // BINOMIAL_CC
diff --git a/IntegerProgramming/binomial.h b/IntegerProgramming/binomial.h
new file mode 100644
index 0000000..e3f031c
--- /dev/null
+++ b/IntegerProgramming/binomial.h
@@ -0,0 +1,302 @@
+// binomial.h
+
+// The binomials considered here are differences of power-products of a
+// special kind. The initial monomial or head (with respect to a given
+// term ordering as described in term_ordering.h) has coefficient 1, the other
+// monomial (the tail) has coefficient -1. The head and the tail of a
+// binomial are always relatively prime, i.e., they do not involve common
+// variables.
+
+// Such a binomial in n variables is represented as an Integer vector of
+// size n: If the i-th variable is involved in the head with exponent k,
+// the i-th component of the vector is set to k. If the i-th variable is
+// involved in the tail with exponent k, the i-th component of the vector
+// is set to -k.
+
+// The members head_support and tail_support of type unsigned long have to be
+// understood as bit-vectors with m components, where m is the number of
+// bits in a long integer. The i-th bit of head_support tells us if the i-th
+// variable is involved in the head of the binomial (for i<=m): it is 1
+// iff this variable appears in the head. Analogously for tail_support.
+// Using these vectors, the question if a binomial can be reduced by another
+// can often be answered by performing a simple bitwise operation.
+
+// To avoid global variables, the number of variables is taken by the
+// constructors. But as it is the same for all appearing binomials during
+// the run of our algorithms (unless some elimination is done), the member
+// functions do not perform any range checks. This makes the algorithms
+// more efficient.
+
+// Most of the constructors do not perform sign checks on their arguments.
+// The reason is simple: Unlike the matrix or term ordering constructors, some
+// binomial constructors are frequently called during computation. As the
+// new binomials are build from the input binomials, it is sufficient to do
+// these checks on the input.
+
+
+
+#ifndef BINOMIAL_H
+#define BINOMIAL_H
+
+
+
+class term_ordering;
+
+
+
+class binomial
+{
+
+
+
+private:
+
+  Integer* exponent_vector;
+
+  short _number_of_variables;
+
+
+#ifdef SUPPORT_DRIVEN_METHODS
+
+  unsigned long head_support;
+  unsigned long tail_support;
+
+#endif  // SUPPORT_DRIVEN_METHODS
+
+
+
+public:
+
+
+
+// constructors and destructor
+
+  binomial(const short& number_of_variables);
+  // Allocates memory for a binomial of size number_of_variables
+  // without initialization.
+  // No range check on the argument!
+
+  binomial(const short& number_of_variables, const Integer* exponents);
+  binomial(const short& number_of_variables, const Integer* exponents,
+           const term_ordering&);
+  // These constructors build a binomial from its exponent vector/array.
+  // The first one takes the positive components as its head, the negative
+  // ones as its tail; the second one determines its head and tail with
+  // respect to the given term ordering.
+  // The array "exponents" is always copied. It would be faster to set
+  // only pointers on it. However, this is very dangerous, and as these
+  // constructors are only used at the beginning of the algorithm, it would
+  // not really improve performance.
+  // The Integer pointer exponents is declared as "const" to suggest that
+  // the referenced array is not changed (although the "const"-declaration
+  // does not assert this).
+  // These constructor check the range (sign) of their argument
+  // number_of_variables because it is not frequently called, but at a
+  // critical point (ideal constructors).
+
+  binomial(const binomial&);
+  // copy-constructor
+  // No check if the copied binomial is corrupt!
+
+  ~binomial();
+  // destructor
+
+
+
+// object information
+
+  short number_of_variables() const;
+  // Returns the number of variables.
+
+  short error_status() const;
+  // Returns _number_of_variables iff _number_of_variables<0
+  // (this is the "errror flag").
+
+
+
+// assigment and access operators
+
+  binomial& operator=(const binomial&);
+  // assignment operator with memory control
+
+  Integer operator[](const short& i) const;
+  // Access operator for reading exponent_vector[i]
+  // (cannot be used to overwrite exponent_vector[i]);
+  // no range chack on i!
+
+
+
+// comparison operators
+
+  BOOLEAN operator==(const binomial& v) const;
+  BOOLEAN operator!=(const binomial& v) const;
+  // comparison of binomials
+
+  BOOLEAN operator==(const Integer comp_value) const;
+  BOOLEAN operator!=(const Integer comp_value) const;
+  BOOLEAN operator<=(const Integer comp_value) const;
+  BOOLEAN operator>=(const Integer comp_value) const;
+  // operators for an efficient comparison with the zero binomial
+  // (comp_value=0)
+
+
+
+// basic routines for Buchbergers's algorithm
+
+  Integer head_reductions_by(const binomial& b) const;
+  // Returns the number of possible reductions of the actual binomial's head
+  // by the binomial b.
+  // The return value -1 means that b==0 or head(b)==1; one should not try
+  // reduce by such a binomial (reduction is undefined or does not terminate).
+  // The procedure reduce_tail_by(...) returns the unchanged binomial in such
+  // a case without a warning. This is done in view of the application:
+  // If a generator of an ideal is reduced to zero during a Groebner basis
+  // calculation and one forgets to delete it, this generator is ignored
+  // (else it would probably cause a fatal error).
+
+  Integer tail_reductions_by(const binomial& b) const;
+  // Returns the number of possible reductions of the actual binomial's tail
+  // by the binomial b.
+  // For the return value -1 see above.
+
+  int reduce_head_by(const binomial& b, const term_ordering& w);
+  // Performs a multiple reduction of the actual binomial's head by the
+  // binomial b and computes the new head and tail with respect to the term
+  // ordering w.
+  // The return value is 1 if the binomial has really been reduced, 2 if
+  // the binomial has been reduced to zero, 0 if the binomial has not been
+  // changed.
+
+  int reduce_tail_by(const binomial& b, const term_ordering& w);
+  // Performs a multiple reduction of the actual binomial's tail by the
+  // binomial b and computes the new head and tail with respect to the term
+  // ordering w.
+  // The return value is 1 if the binomial has really been reduced, else 0.
+  // (By a tail reduction, the binomial cannot be reduced to zero if the
+  // binomial itself and b are consistent with w, i.e. if head and tail are
+  // correct.)
+
+  friend binomial& S_binomial(const binomial& a, const binomial& b,
+                              const term_ordering& w);
+  // Computes the S-binomial of a and b with respect to the term ordering w
+  // and returns a reference on it (the necessary memory is allocated during
+  // the computation).
+
+
+
+// criteria for unnecessary S-Pairs
+
+  friend BOOLEAN relatively_prime(const binomial& a, const binomial& b);
+  // Returns TRUE iff the leading terms of a and b are relatively prime.
+
+  friend BOOLEAN M(const binomial& a,const binomial& b,const binomial& c);
+  // Verifies if lcm(head(a),head(c)) divides properly lcm(head(b),head(c)).
+
+  friend BOOLEAN F(const binomial& a, const binomial& b, const binomial& c);
+  // Verifies if lcm(head(a),head(c))=lcm(head(b),head(c)).
+
+  friend BOOLEAN B(const binomial& a, const binomial& b, const binomial& c);
+  // Verifies if head(a) divides lcm(head(b),head(c)) and
+  // lcm(head(a),head(b))!=lcm(head(b),head(c))!=lcm(head(a),head(c)).
+
+  friend BOOLEAN second_crit(const binomial& a, const binomial& b,
+                             const binomial& c);
+  // Verifies if head(a) divides lcm(head(b),head(c)).
+
+
+
+// special routines needed by the IP-algorithms
+
+// All this routines are not very frequently used (especially not in
+// Buchberger's algorithm), so I haven't spent much time in optimization.
+// None of them performs range checks on their arguments.
+
+  BOOLEAN involves_elimination_variables(const term_ordering& w);
+  // Verifies if the binomial involves elimination variables with respect
+  // to w.
+  // UNCHECKED PRECONDITION: w and the binomial are compatible, i.e.
+  // involve the same number of variables.
+
+  BOOLEAN drop_elimination_variables(const term_ordering& w);
+  // Cuts the elimination variables (with respect to w) from the binomial
+  // and adapts the member _number_of_variables as well as the head and the
+  // tail.
+  // UNCHECKED PRECONDITION: w and the binomial are compatible.
+  // The interesting part of the binomial (ot its additive inverse) is copied
+  // hereby to be able to free the memory needed by the dropped components.
+
+  BOOLEAN drop_last_weighted_variable(const term_ordering& w);
+  // Cuts the last variable from the binomial and adapts the member
+  // _number_of_variables as well as head and tail (the last two to the given
+  // term_ordering)
+  // UNCHECKED PRECONDITION: w is a weighted termordering (without elimination
+  // variables) that is compatible to the actual binomial.
+  // The interesting part of the binomial (ot its additive inverse) is copied
+  // hereby to be able to free the memory needed by the dropped components.
+
+  int adapt_to_term_ordering(const term_ordering&);
+  // Determines head and tail of the binomial with respect to the given term
+  // ordering; i.e. multiplies the exponent vector with -1 and exchanges
+  // head_support and tail_support, if necessary.
+  // Returns -1 if head and tail were exchanged, 1 else.
+  // UNCHECKED PRECONDITION: w and the binomial are compatible.
+
+  binomial& swap_variables(const short& i,const short& j);
+  // Swaps the components i and j of the exponent vector and actualizes
+  // head_support and tail_support.
+  // No range check on the arguments!
+
+  binomial& flip_variable(const short& i);
+  // Inverts component i of the exponent vector and actualizes head_support
+  // and tail_support.
+  // No range check on i!
+
+
+
+// output
+
+  void print() const;
+  void print_all() const;
+  // Writes the actual binomial to the standard output medium.
+  // The first routine only prints the exponent vector, the second prints
+  // the head and tail support, too (if SUPPORT_DRIVEN_METHODS are used).
+
+  void print(FILE* output) const;
+  void print_all(FILE* output) const;
+  // Writes the actual binomial to the referenced file which must have
+  // been opened for writing before.
+
+  void print(ofstream&) const;
+  void print_all(ofstream&) const;
+  // Writes the actual binomial to the given ofstream.
+
+  void format_print(ofstream&) const;
+  // Writes the given binomial to the actual ofstream in the format needed
+  // by the IP-algorithms.
+
+  friend class ideal;
+  // The class ideal is declared as a friend for efficiency reasons:
+  // This avoids many unnecessary function calls for inspecting members
+  // like head_support and tail_support.
+  // The class ideal does not change any members of the binomial class.
+
+  friend short term_ordering::compare(const binomial&, const binomial&) const;
+
+
+};
+
+
+#endif  // BINOMIAL_H
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/IntegerProgramming/binomial__term_ordering.h b/IntegerProgramming/binomial__term_ordering.h
new file mode 100644
index 0000000..8d1f4e7
--- /dev/null
+++ b/IntegerProgramming/binomial__term_ordering.h
@@ -0,0 +1,14 @@
+// binomial__term_ordering.h
+
+// The class binomial needs to know the class term_ordering and vice versa.
+// But for a  beautiful design, I did not want to write this declarations
+// into the same file. The file binter.h simply puts the two corresponding
+// header files together.
+
+#ifndef BINOMIAL__TERM_ORDERING_H
+#define BINOMIAL__TERM_ORDERING_H
+
+#include "term_ordering.h"
+#include "binomial.h"
+
+#endif  // BINOMIAL__TERM_ORDERING_H
diff --git a/IntegerProgramming/change_cost.cc b/IntegerProgramming/change_cost.cc
new file mode 100644
index 0000000..456e61d
--- /dev/null
+++ b/IntegerProgramming/change_cost.cc
@@ -0,0 +1,212 @@
+// change_cost.cc
+
+// This file provides an interface for changing the cost vector in IP-problems
+// and for recomputing Groebner basis of toric ideals.
+
+#ifndef CHANGE_COST_CC
+#define CHANGE_COST_CC
+
+#include "IP_algorithms.h"
+
+int main(int argc, char *argv[])
+{
+
+  // initialize arguments for the IP-algorithms (Buchberger)
+  // with default settings
+  BOOLEAN verbose=FALSE;
+  short version=1;
+  short S_pair_criteria=11;
+  double interreduction_percentage=12.0;
+
+
+///////////////////////// parse options /////////////////////////////////////
+
+
+  if(argc>=3)
+    // argc has to be at least 3 (except when help is required, see below):
+    // program name, GROEBNER file, NEW_COST file
+  {
+
+    for(short i=1;i<argc-2;i++)
+      // these are the input options
+    {
+
+      if(!strcmp(argv[i],"-v") || !strcmp(argv[i],"--verbose"))
+      {
+        verbose=TRUE;
+        continue;
+        // read next argument
+      }
+
+      if(!strcmp(argv[i],"-V") || !strcmp(argv[i],"-version"))
+      {
+        // check if next argument is a valid version number
+        i++;
+
+        if(!strcmp(argv[i],"1"))
+        {
+          version=1;
+          continue;
+        }
+        if(!strcmp(argv[i],"1a"))
+        {
+          version=0;
+          continue;
+        }
+        if(!strcmp(argv[i],"2"))
+        {
+          version=2;
+          continue;
+        }
+        if(!strcmp(argv[i],"3"))
+        {
+          version=3;
+          continue;
+        }
+
+        // When reaching this line, the version argument was invalid.
+        cerr<<"ERROR: invalid version argument"<<endl
+            <<"Type `change_cost --help' for help on options."<<endl;
+        return 1;
+      }
+
+      if(!strcmp(argv[i],"-S"))
+      {
+        // initialize argument to the use of no criteria
+        S_pair_criteria=0;
+
+        do
+        {
+          // Check what S-pair criterion the next argument indicates.
+          // If none: The algorithm is called without S-pair criteria.
+          i++;
+
+          if(i>=argc-2)
+            // file arguments reached
+            break;
+
+          if(!strcmp(argv[i],"RP"))
+          {
+            S_pair_criteria|=1;
+            continue;
+          }
+          if(!strcmp(argv[i],"M"))
+          {
+            S_pair_criteria|=2;
+            continue;
+          }
+          if(!strcmp(argv[i],"F"))
+          {
+            S_pair_criteria|=4;
+            continue;
+          }
+          if(!strcmp(argv[i],"B"))
+          {
+            S_pair_criteria|=8;
+            continue;
+          }
+          if(!strcmp(argv[i],"2"))
+          {
+            S_pair_criteria|=16;
+            continue;
+          }
+
+          // option does not belong to an S-pair criterion
+          break;
+
+        }
+        while(1);
+
+        i--;        // reset counter so that the outer loop
+        continue;   // continues with the just considered argument
+      }
+
+      if(!strcmp(argv[i],"-p"))
+      {
+        // read interreduction percentage
+        i++;
+
+        char** rest;
+        interreduction_percentage=strtod(argv[i],rest);
+        // The function strtod converts a string into a double. As the
+        // specification is not correct, it may cause trouble...
+        // For example, if the argument can be read as a float, the value
+        // of rest should be NULL. This is not the case. Therefore, we can
+        // only check by the following string comparison if a float has been
+        // built. An argument as 15xy is thereby considered as valid
+        // (with interreduction_percentage==15.0).
+
+        if(!(strcmp(argv[i],*rest)))
+          // argument was no float
+        {
+          cerr<<"ERROR: invalid argument for interreduction percentage"<<endl
+              <<"Type `change_cost --help' for help on options."<<endl;
+          return 1;
+        }
+
+        continue;
+      }
+
+      // When reaching this line, the argument is no legal option.
+      cerr<<"ERROR: invalid option "<<argv[i]<<endl
+          <<"Type `change_cost --help' for help on options."<<endl;
+      return 1;
+    }
+
+
+///////////////////// call IP-algorithms ////////////////////////////////////
+
+    // open first input stream (GROEBNER file)
+    ifstream first_input(argv[argc-2]);
+
+    if(!first_input)
+    {
+      cerr<<"ERROR: cannot open first input file, possibly not found"<<endl;
+      return 1;
+    }
+
+    // open second input stream (NEW_COST file)
+    ifstream second_input(argv[argc-1]);
+
+    if(!second_input)
+    {
+      cerr<<"ERROR: cannot open second input file, possibly not found"<<endl;
+      return 1;
+    }
+
+    // change term ordering
+    int success=change_cost(argv[argc-2], argv[argc-1], version,
+                            S_pair_criteria, interreduction_percentage,
+                            verbose);
+    if(!success)
+    {
+      cerr<<"ERROR: could not change cost vector,\n"
+        "no new GROEBNER file created"<<endl;
+      return 1;
+    }
+
+    // Groebner basis successfully changed
+    return 0;
+  }
+
+
+/////////////////////// provide help text ///////////////////////////////////
+
+  // handle the case of "missing" arguments
+
+  if((argc==2) && !strcmp(argv[1],"--help"))
+    // help required
+  {
+    system("less change_cost.hlp");
+    return 0;
+  }
+
+  else
+    // invalid arguments
+    cerr<<"USAGE: change_cost [options] groebner_file new_cost_file"<<endl
+        <<"Type `change_cost --help' for help on options."<<endl;
+
+  return 1;
+
+}
+#endif  // CHANGE_COST_CC
diff --git a/IntegerProgramming/change_cost.hlp b/IntegerProgramming/change_cost.hlp
new file mode 100644
index 0000000..55c715a
--- /dev/null
+++ b/IntegerProgramming/change_cost.hlp
@@ -0,0 +1,141 @@
+USAGE: change_cost [options] groebner_file new_cost_file
+
+
+
+DESCRIPTION:
+
+change_cost is a program for recomputing the reduced Groebner basis of
+a toric ideal with respect to a term ordering with modified
+weights. This can be used for varying the cost function in integer
+programming (see the help for solve_IP for more information).
+The program simply restarts Buchberger�s algorithm on an already
+computed toric ideal using the modified term ordering.
+
+
+
+FILE FORMAT:
+
+The first input file has to be a GROEBNER file; the second input file
+should to be a NEW_COST file. For convenience, also MATRIX files are
+accepted as second input files. For their format see the help for the
+solve_IP or the toric_ideal program.
+
+change_cost writes the new Groebner basis into a GROEBNER file named
+like the second input file with extensions replaced by
+
+	.GB.<alg>
+
+where GB stands for GROEBNER and <alg> is the abbreviation of the
+algorithm used for computing the input GROEBNER file (see the help for
+solve_IP or toric_ideal for an explaination).
+
+A GROEBNER file looks as follows:
+
+
+  GROEBNER
+
+  computed with algorithm:
+  <algorithm name abbreviation>       (* abbreviations as above *)
+  from file(s):                       (* the following four lines are
+  <name of respective MATRIX file>       optional *)
+  computation time:
+  <computation time in seconds>
+
+  term ordering:
+  elimination block
+  <number of elimination variables>
+  <LEX / DEG_LEX                      (* only if number of elimination
+  / DEG_REV_LEX>                         variables >0 *)
+  weighted block
+  <number of weighted variables>
+  <W_LEX / W_REV_LEX                  (* number of weighted variables
+  / W_DEG_LEX / W_DEG_REV_LEX>           should always be >0 *)
+  <weight_vector>
+
+  size:
+  <number of elements>
+
+  Groebner basis:
+  <basis elements>
+
+  <settings for the Buchberger
+   algorithm and compiler settings>  (* optional *)
+
+
+The Groebner basis consists always of binomials of the form x^a - x^b
+where x^a and x^b are relatively prime. Such a binomial can be
+represented by the vector a-b. The basis elements in the GROEBNER file
+are given by the coefficients of this vector representation.
+The settings for Buchberger�s algorithm and the compiler flags are
+produced when the GROEBNER file is generated by a call of solve_IP
+with the verbose output option
+
+	-v, --verbose
+
+Example:
+
+
+  GROEBNER
+
+  computed with algorithm:
+  du
+
+  term ordering:
+  elimination block:
+  0
+  weighted block:
+  3
+  W_LEX
+  1 2 3
+
+  size:
+  1
+
+  Groebner basis:
+  2 3 -2			    (*  x^2 * y^3 - z^2  *)
+
+
+A NEW_COST file should look as follows:
+
+
+  NEW_COST
+
+  variables:
+  <number of weighted variables>
+
+  cost vector:
+  <coefficients of the new weight vector>
+
+
+
+OPTIONS:
+
+ -p         <number>      percentage of new generators to cause an
+                          autoreduction during Buchberger�s algorithm;
+                          <number> may be an arbitrary float, a
+                          negative value allows no intermediate
+                          autoreductions
+			  default is
+                          -p 12.0
+
+ -S [RP] [M] [B] [M] [2]  criteria to use in Buchberger�s algorithm
+                          for discarding unneccessary S-pairs
+             RP           relatively prime leading terms
+             M            Gebauer-Moeller criterion M
+             F            Gebauer-Moeller criterion F
+             B            Gebauer-Moeller criterion B
+             2            Buchberger�s second criterion
+			  default is
+                          -S RP M B
+
+ -v,
+--verbose                 verbose output mode; writes the settings for
+                          Buchberger�s algorithm and the compiler
+                          flags into the output GROEBNER file
+
+-V <number>,
+--version <number>        version of Buchberger�s algorithm to use;
+                          <number> may be 1, 1a, 2 or 3
+			  default is
+                          -V 1
+
diff --git a/IntegerProgramming/gen_test.cc b/IntegerProgramming/gen_test.cc
new file mode 100644
index 0000000..eb011d3
--- /dev/null
+++ b/IntegerProgramming/gen_test.cc
@@ -0,0 +1,69 @@
+// gentest.cc
+
+// a program that generates some test data
+
+
+#ifndef GEN_TEST_CC
+#define GEN_TEST_CC
+
+#include "testdata.h"
+
+int main(void)
+{
+  ofstream output1("IP/testmatrix1");
+  random_matrix(3,4,0,5,output1);
+  ofstream output2("IP/testmatrix2");
+  random_matrix(4,6,0,5,output2);
+  ofstream output3("IP/testmatrix3");
+  random_matrix(3,4,-5,5,output3);
+  ofstream output4("IP/testmatrix4");
+  random_matrix(5,8,0,1,output4);
+  ofstream output5("IP/testmatrix5");
+  transportation_problem(3,4,5,output5);
+  ofstream output6("IP/testmatrix6");
+  transportation_problem(3,5,5,output6);
+
+  ofstream output1a("IP/testproblem1a");
+  random_problems(3,5,-5,5,output1a);
+  ofstream output1b("IP/testproblem1b");
+  random_problems(3,5,0,5,output1b);
+  ofstream output1c("IP/testproblem1c");
+  random_problems(4,5,0,5,output1c);
+
+  ofstream output2a("IP/testproblem2a");
+  random_problems(4,5,-5,5,output2a);
+  ofstream output2b("IP/testproblem2b");
+  random_problems(4,5,0,5,output2b);
+  ofstream output2c("IP/testproblem2c");
+  random_problems(6,5,0,5,output2c);
+
+  ofstream output3a("IP/testproblem3a");
+  random_problems(3,5,-5,5,output3a);
+  ofstream output3b("IP/testproblem3b");
+  random_problems(3,5,0,5,output3b);
+  ofstream output3c("IP/testproblem3c");
+  random_problems(4,5,0,5,output3c);
+
+  ofstream output4a("IP/testproblem4a");
+  random_problems(5,5,-5,5,output4a);
+  ofstream output4b("IP/testproblem4b");
+  random_problems(5,5,0,5,output4b);
+  ofstream output4c("IP/testproblem4c");
+  random_problems(8,5,0,5,output4c);
+
+  ofstream output5a("IP/testproblem5a");
+  random_problems(3+4,5,-5,5,output5a);
+  ofstream output5b("IP/testproblem5b");
+  random_problems(3+4,5,0,5,output5b);
+  ofstream output5c("IP/testproblem5c");
+  random_problems(3*4,5,0,5,output5c);
+
+  ofstream output6a("IP/testproblem6a");
+  random_problems(3+5,5,-5,5,output6a);
+  ofstream output6b("IP/testproblem6b");
+  random_problems(3+5,5,0,5,output6b);
+  ofstream output6c("IP/testproblem6c");
+  random_problems(3*5,5,0,5,output6c);
+  return 0;
+}
+#endif
diff --git a/IntegerProgramming/globals.h b/IntegerProgramming/globals.h
new file mode 100644
index 0000000..9ab4d6a
--- /dev/null
+++ b/IntegerProgramming/globals.h
@@ -0,0 +1,231 @@
+// globals.h
+
+// In this file
+// - some facilities as the g++ input/output routines are included,
+// - the general data type can be chosen (the people of Singular do not like
+//   templates),
+// - some makros are defined for an easier handling of the program,
+// - some flags and constants can be set to observe the behaviour of the
+//   algorithms when using different strategies.
+
+#ifndef GLOBALS_H
+#define GLOBALS_H
+// Include facilities needed by several files:
+
+// the following is not good! TODO: move to all including sources...
+
+#include <singularconfig.h>
+
+
+#include <stdio.h>
+#ifndef HAVE_IOSTREAM_H
+#include <iostream>
+#include <fstream>
+#include <iomanip>
+#include <limits>
+#else
+#include <iostream.h>
+#include <fstream.h>
+#include <iomanip.h>
+#include <limits.h>
+#endif
+#include <stddef.h>
+#include <stdlib.h>
+#include <math.h>
+#include <string.h>
+
+using namespace std;
+
+// Include a BigInt class from a foreign library:
+// This is needed by the LLL algorithm. If no such class is included,
+// it computes with long ints; this results in overflows and unexpected
+// behaviour even when computing with relatively small instances.
+
+#define GMP
+
+#ifdef GMP
+
+#include "BigInt.h"
+
+#else   // GMP
+
+typedef long BigInt;
+
+#endif // GMP
+
+// Define the general data type:
+// short seems to be sufficient for most practicable instances.
+
+typedef short Integer;
+// The general data type to deal with can be short, long or int...
+
+//#define _SHORT_
+// For an overflow control for thE result of the LLL algorithm, we have to
+// know the data type used.
+
+
+
+// Define a BOOLEAN data type etc. for an easy-to-read code:
+
+typedef char BOOLEAN;
+#define TRUE  1
+#define FALSE 0
+
+#define MAXIMUM(a,b) (a>b? a:b)
+
+#define INHOMOGENEOUS 0
+#define HOMOGENEOUS   1
+// For a more comfortable call of the term_ordering constructors.
+
+
+
+
+// Enumerate the algorithms:
+// The ideal constructor (builds an ideal from the input matrix) depends on
+// the algorithm. The constants are defined to make constructor calls easier
+// (you do not need to remember a number).
+
+#define CONTI_TRAVERSO           1
+#define POSITIVE_CONTI_TRAVERSO  2
+#define POTTIER                  3
+#define HOSTEN_STURMFELS         4
+#define DIBIASE_URBANKE          5
+#define BIGATTI_LASCALA_ROBBIANO 6
+
+
+
+
+// Enumerate the criteria to discard unnecessary S-pairs:
+// The constants are defined to allow an easier call of Buchberger�s algorithm
+// with different criteria. This algorithm takes as an argument a short int
+// which represents the combination of criteria to be used (with a default
+// combination if no argument is given).
+// The method to compute the argument for a certain combination is simple:
+// Simply add the constants that belong to criteria you want to use. As the
+// constants are chosen to be different powers of 2, each short int (in the
+// range of 0 to 31) gives a unique combination (cf. the read-write-execute
+// rights for files in UNIX systems).
+// EXAMPLE:
+// If you want to call Buchberger�s algorithm with the criterion "relatively
+// prime leading terms" and the second criterion for the ideal I, write:
+//
+//      I.reduced_Groebner_basis_1(REL_PRIMENESS + SECOND_CRITERION);
+// or
+//      I.reduced_Groebner_basis_1(17);
+//
+// The argument 0 means that no criteria are used, the argument 31 leads to
+// the use of all criteria.
+
+#define REL_PRIMENESS      1
+#define M_CRITERION        2
+#define F_CRITERION        4
+#define B_CRITERION        8
+#define SECOND_CRITERION  16
+
+// The names of tehse criteria are chosen according to the criteria
+// described in Gebauer/Moeller (except from the last).
+// The first one (relatively prime leading terms) is a local criterion
+// and the most effective.
+// The last four criteria are global ones involving searches over the
+// generator lists. But although the lcm-computations performed by these
+// checks are not much cheaper than a reduction, most of the criteria seem to
+// accelerate the computations.
+// REL_PRIMENESS should always be used.
+// The Gebauer/Moeller-criteria (M,F,B) seem to improve computation time in
+// the general case; Buchberger's second criterion seems to improve it in
+// more special cases (for example the transportation problem). They should
+// be switched on and off according to these results, but never be enabled
+// together; the overhead of too many criteria leads to a rather bad
+// performance in all cases.
+// The relatively primeness criterion is tested first because it
+// is very easy to check. The order of the Gebauer/Moeller-criteria does not
+// really affect computation. The relative order of the Gebauer/Moeller
+// criteria and the second criterion (if they are enabled together) has almost
+// the same effect as switching off the last criterion in this order.
+// There is no possibility to change the order in which the criteria are
+// tested without changing the program!
+
+
+
+
+// Enumerate the term orderings that can be used to refine the weight:
+// W_REV_LEX will give a term ordering in the classical sense if and only if
+// all weights are positive. It has been implemented because several
+// algorithms need a reverse lexicographical refinement. (Of course, these
+// algorithms control if they have a positive grading.)
+// A warning will be output when using W_REV_LEX in an insecure case.
+
+#define W_LEX          4
+#define W_REV_LEX      5
+#define W_DEG_LEX      6
+#define W_DEG_REV_LEX  7
+
+
+
+// Enumerate the term ordering used for the block of elimination variables:
+
+#define LEX          1
+#define DEG_LEX      2
+#define DEG_REV_LEX  3
+
+//////////////////////////////////////////////////////////////////////////////
+///////////////     TEST PARAMETER SECTION    ////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+
+// Set flags concerning the basic operations and the course of Buchberger's
+// algorithm:
+
+#define SUPPORT_DRIVEN_METHODS
+// possibilities:
+// SUPPORT_DRIVEN_METHODS
+// NO_SUPPORT_DRIVEN_METHODS
+
+// This flag allows to switch of and on the use of the support vectors in
+// the binomial class; these are used to speed up tests for reducibility of
+// binomials, relative primeness etc.
+
+#define SUPPORT_DRIVEN_METHODS_EXTENDED
+// possibilities:
+// SUPPORT_DRIVEN_METHODS_EXTENDED
+// NO_SUPPORT_DRIVEN_METHODS_EXTENDED
+
+// This flag allows to switch of and on the extended use of the support
+// information. This includes the splitting of the ideal generators into
+// several lists according to their head support. This discards many
+// unnecessary tests for divisibility etc.
+// SUPPORT_DRIVEN_METHODS_EXTENDED should only be enabled when
+// SUPPORT_DRIVEN_METHODS is set, too! The combination
+// NO_SUPPORT_DRIVEN_METHODS and  SUPPORT_DRIVEN_METHODS_EXTENDED is quite
+// senseless and will only work if your compiler automatically initializes
+// integers to zero.
+
+const unsigned short List_Support_Variables=8;
+
+// This is the number of variables considered to create and maintain the
+// generator lists of an ideal if SUPPORT_DRIVEN_METHODS_EXTENDED is
+// enabled. As there are 2^List_Support_Variables lists, this number
+// should not be too big (to avoid the overhead of many empty lists).
+// The best number may depend on the problem size and structure...
+
+#define SUPPORT_VARIABLES_LAST
+// possibilities:
+// SUPPORT_VARIABLES_LAST
+// SUPPORT_VARIABLES_FIRST
+
+// This flag determines whether the first or the last variables are considered
+// by the support methods. So this setting will only affect the computation if
+// such methods are enabled.
+// The reason for the introduction of this flag is the following:
+// The Conti-Traverso algorithm for solving an integer program works in two
+// phases: Given an artificial solution in auxiliary variables, these
+// variables are first eliminated to get a feasible solution. The elimination
+// variables are for technical reasons always the last. In a second phase,
+// this solution is reduced to a minimal solution with respect to a given
+// term ordering.
+// If SUPPORT_VARIABLES_LAST is set, the first phase will probably take
+// less time as if SUPPORT_VARIABLES_FIRST is set. If one is only interested
+// in finding a feasible solution (not necessary  minimal),
+// SUPPORT_VARIABLES_LAST might be the better choice.
+
+#endif  // GLOBALS_H
+
diff --git a/IntegerProgramming/ideal.cc b/IntegerProgramming/ideal.cc
new file mode 100644
index 0000000..ee28733
--- /dev/null
+++ b/IntegerProgramming/ideal.cc
@@ -0,0 +1,1092 @@
+// ideal.cc
+
+// implementation of some general ideal functions
+
+#ifndef IDEAL_CC
+#define IDEAL_CC
+
+#include <climits>
+#include "ideal.h"
+
+/////////////////////////////////////////////////////////////////////////////
+////////////////// private member functions /////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+
+///////////// subset_tree data structure ////////////////////////////////////
+
+#ifdef SUPPORT_DRIVEN_METHODS_EXTENDED
+
+void ideal::create_subset_tree()
+{
+  for(int i=0;i<Number_of_Lists;i++)
+  {
+
+// First determine the number of binary vectors whose support is a subset
+// of the support of i (i read as binary vector).
+// The support of i is a set of cardinality s, where s is the number of
+// bits in i that are 1. Hence the desired number is 2^s.
+
+    int s=0;
+
+    for(int k=0;k<List_Support_Variables;k++)
+      if( (i&(1<<k)) == (1<<k) )
+        // bit k of i is 1
+        s++;
+
+    S.number_of_subsets[i]=(1<<s);
+    // (1<<s) == 2^s
+
+// Now determine the concrete binary vectors whose support is a subset
+// of that of i. This is done in a very simple manner by comparing
+// the support of each number between 0 and i (read as binary vector)
+// with that of i. (Efficiency considerations are absolutely unimportant
+// in this function.)
+
+    S.subsets_of_support[i]=new int[S.number_of_subsets[i]];
+    // memory allocation for subsets_of_support[i]
+
+    int index=0;
+    for(int j=0;j<Number_of_Lists;j++)
+      if((i&j)==j)
+        // If the support of j as a bit vector is contained in the support of
+        // i as a bit vector, j is saved in the list subsets_of_support[i].
+          {
+            S.subsets_of_support[i][index]=j;
+            index++;
+          }
+  }
+}
+
+void ideal::destroy_subset_tree()
+{
+  for(int i=0;i<Number_of_Lists;i++)
+    delete[] S.subsets_of_support[i];
+  // The arrays number_of_subsets and subsets_of_support (the (int*)-array)
+  // are not dynamically allocated and do not have to be deleted.
+}
+#endif  // SUPPORT_DRIVEN_METHODS_EXTENDED
+
+/////////// subroutines for Buchberger�s algorithm //////////////////////////
+
+ideal& ideal::add_new_generator(binomial& bin)
+{
+#ifdef SUPPORT_DRIVEN_METHODS_EXTENDED
+
+  new_generators[(bin.head_support)%Number_of_Lists].insert(bin);
+  // insert the bin according to its support,
+  // considering only the first List_Support_Variables variables.
+
+#endif  // SUPPORT_DRIVEN_METHODS_EXTENDED
+
+#ifdef NO_SUPPORT_DRIVEN_METHODS_EXTENDED
+
+  new_generators.insert(bin);
+
+#endif  // NO_SUPPORT_DRIVEN_METHODS_EXTENDED
+
+  return(*this);
+}
+
+ideal& ideal::add_generator(binomial& bin)
+{
+// Beside its function as a auxiliary routine for a shorter code, this routine
+// offers a good way to hide if SUPPORT_DRIVEN_METHODS_EXTENDED are used or
+// not. So the constructors do not have to care about this.
+
+#ifdef SUPPORT_DRIVEN_METHODS_EXTENDED
+
+  generators[(bin.head_support)%Number_of_Lists].insert(bin);
+  // insert the bin according to its support,
+  // considering only the first List_Support_Variables variables.
+
+#endif  // SUPPORT_DRIVEN_METHODS_EXTENDED
+
+#ifdef NO_SUPPORT_DRIVEN_METHODS_EXTENDED
+
+  generators.insert(bin);
+
+#endif  // NO_SUPPORT_DRIVEN_METHODS_EXTENDED
+
+  size++;
+  number_of_new_binomials++;
+
+  return(*this);
+}
+
+//////////////////// constructor subroutines ////////////////////////////////
+
+ideal& ideal::Conti_Traverso_ideal(matrix& A,const term_ordering& _w)
+{
+
+  // A may have negative entries; to model this with binomials, we need an
+  // inversion variable.
+
+  w=_w;
+  // The argument term ordering should be given by the objective function.
+
+  w.convert_to_elimination_ordering(A.rows+1,LEX);
+  // extend term ordering into an elimination ordering of the appropriate
+  // size
+
+  Integer *generator=new Integer[A.columns+A.rows+1];
+  // A.columns + A.rows +1 is the number of variables for the Conti-Traverso
+  // algorithm with "inversion variable".
+
+  // build initial ideal generators
+  for(int j=0;j<A.columns;j++)
+  {
+    for(int k=0;k<A.columns;k++)
+      // original variables
+      if(j==k)
+        generator[k]=-1;
+      else
+        generator[k]=0;
+
+    for(int i=0;i<A.rows;i++)
+      // elimination variables
+      generator[A.columns+i]=A.coefficients[i][j];
+
+    generator[A.columns+A.rows]=0;
+    // inversion variable
+
+    // Note that the relative order of the variables is important:
+    // If the elimination variables do not follow the other variables,
+    // the conversion of the term ordering has not the desired effect.
+
+    binomial* bin=new binomial(A.rows+1+A.columns,generator,w);
+    add_generator(*bin);
+  }
+
+  // now add the "inversion generator"
+  for(int j=0;j<A.columns;j++)
+    generator[j]=0;
+  for(int i=0;i<A.rows+1;i++)
+    generator[A.columns+i]=1;
+  binomial* bin=new binomial(A.rows+1+A.columns,generator,w);
+  add_generator(*bin);
+
+  delete[] generator;
+  return *this;
+}
+
+ideal& ideal::Positive_Conti_Traverso_ideal(matrix& A,const term_ordering& _w)
+{
+
+  // A is assumed to have only nonnegative entries;then we need no
+  // "inversion variable".
+
+  w=_w;
+  // The argument term ordering should be given by the objective function.
+
+  w.convert_to_elimination_ordering(A.rows, LEX);
+  // extend term ordering into an elimination ordering of the appropriate
+  // size
+
+  Integer *generator=new Integer[A.columns+A.rows];
+  // A.columns + A.rows is the number of variables for the Conti-Traverso
+  // algorithm without "inversion variable".
+
+  // build the initial ideal generators
+  for(int j=0;j<A.columns;j++)
+  {
+    for(int k=0;k<A.columns;k++)
+      // original variables
+      if(j==k)
+        generator[k]=-1;
+      else
+        generator[k]=0;
+
+    for(int i=0;i<A.rows;i++)
+      // elimination variables
+      generator[A.columns+i]=A.coefficients[i][j];
+
+    // Note that the relative order of the variables is important:
+    // If the elimination variables do not follow the other variables,
+    // the conversion of the term ordering has not the desired effect.
+
+    binomial* bin=new binomial(A.rows+A.columns,generator,w);
+    add_generator(*bin);
+  }
+  delete[] generator;
+  return *this;
+}
+
+ideal& ideal::Pottier_ideal(matrix& A, const term_ordering& _w)
+{
+
+  w=_w;
+  // The argument term_ordering should be given by the objective function.
+
+  w.convert_to_elimination_ordering(1,LEX);
+  // add one elimination variable used to saturate the ideal
+
+  if(A._kernel_dimension==-2)
+    // kernel of A not yet computed, do this now
+    A.LLL_kernel_basis();
+
+  if((A._kernel_dimension==-1) &&  (A.columns<0))
+    // error occurred in kernel computation or matrix corrupt
+  {
+    cout<<"\nWARNING: ideal& ideal::Pottier_ideal(matrix&, const "
+      "term_ordering&):\ncannot build ideal from a corrupt input matrix"<<endl;
+    size=-1;
+    return *this;
+  }
+
+  Integer *generator=new Integer[A.columns+1];
+  // This is the number of variables needed for Pottier's algorithm.
+
+
+  // compute initial generating system from the kernel of A
+  for(int j=0;j<A._kernel_dimension;j++)
+  {
+
+    for(int k=0;k<A.columns;k++)
+    {
+
+      // We should first verifie if the components of the LLL-reduced lattice
+      // basis fit into the basic data type (Integer as defined in globals.h).
+      // This overflow control does of course not detect overflows in the
+      // course of the LLL-algorithm!
+
+#ifdef _SHORT_
+
+      if(((A.H)[j][k]>(const BigInt &)SHRT_MAX) || ((A.H)[j][k]<(const BigInt &)SHRT_MIN))
+      {
+        cerr<<"\nWARNING: ideal& ideal::Pottier_ideal(matrix&, const "
+          "term_ordering&):\n"
+          "LLL-reduced kernel basis does not fit into the used "
+          "basic data type int."<<endl;
+        size=-3;
+        delete[] generator;
+        return *this;
+      }
+
+#endif // _SHORT_
+
+#ifdef _INT_
+
+      if(((A.H)[j][k]>(const BigInt&)INT_MAX) || ((A.H)[j][k]<(const BigInt&)INT_MIN))
+      {
+        cerr<<"\nWARNING: ideal& ideal::Pottier_ideal(matrix&, const "
+          "term_ordering&):\n"
+          "LLL-reduced kernel basis does not fit into the used "
+          "basic data type int."<<endl;
+        size=-3;
+        delete[] generator;
+        return *this;
+      }
+
+#endif  // _INT_
+
+#ifdef _LONG_
+
+      if(((A.H)[j][k]>(const BigInt&)LONG_MAX) || ((A.H)[j][k]<(const BigInt&)LONG_MIN))
+      {
+        cerr<<"\nWARNING: ideal& ideal::Pottier_ideal(matrix&, const "
+          "term_ordering&):\n"
+          "LLL-reduced kernel basis does not fit into the used "
+          "basic data type long."<<endl;
+        size=-3;
+        delete[] generator;
+        return *this;
+      }
+
+#endif  // _LONG_
+
+      generator[k]=(A.H)[j][k];
+    }
+
+    generator[A.columns]=0;
+    // elimination variable
+
+    // Note that the relative order of the variables is important:
+    // If the elimination variable does not follow the other variables,
+    // the conversion of the term ordering has not the desired effect.
+
+    binomial* bin=new binomial(A.columns+1,generator,w);
+    add_generator(*bin);
+  }
+
+  // build "saturation generator"
+
+
+  // The use of the hosten_shapiro procedure is useful here because the head
+  // of the computed saturation generator is smaller if less variables are
+  // involved.
+  int* sat_var = NULL;
+  int number_of_sat_var = A.hosten_shapiro(sat_var);
+  if( (number_of_sat_var == 0) || (sat_var == NULL) )
+  {
+    delete[] generator;
+    return *this;
+  }
+
+  for(int j=0;j<A.columns;j++)
+    generator[j]=0;
+
+  for(int k=0;k<number_of_sat_var;k++)
+    generator[sat_var[k]]=1;
+
+  generator[A.columns]=1;
+
+  binomial* bin=new binomial(A.columns+1,generator,w);
+  add_generator(*bin);
+  // The "saturation generator" seems to be a monomial, but is interpreted
+  // as a binomial with tail 1 by the designed data structures.
+
+  delete[] sat_var;
+  delete[] generator;
+
+  return *this;
+}
+
+ideal& ideal::Hosten_Sturmfels_ideal(matrix& A, const term_ordering& _w)
+{
+
+  // check term ordering
+  if((_w.weight_refinement()!=W_REV_LEX) && (_w.is_positive()==FALSE))
+    cerr<<"\nWARNING: ideal& ideal::Hosten_Sturmfels_ideal(matrix&, const "
+      "term_ordering&):\nargument term ordering should be a weighted reverse"
+      "lexicographical \nwith positive weights"<<endl;
+
+  w=_w;
+  // The argument term_ordering should be given by a homogenous grading.
+
+  if(A._kernel_dimension==-2)
+    // kernel of A not yet computed, do this now
+    A.LLL_kernel_basis();
+
+  if((A._kernel_dimension==-1) &&  (A.columns<0))
+    // error occurred in kernel computation or matrix corrupt
+  {
+    cout<<"\nWARNING: ideal& ideal::Hosten_Sturmfels_ideal(matrix&, const "
+      "term_ordering&):\ncannot build ideal from a corrupt input matrix"<<endl;
+    size=-1;
+    return *this;
+  }
+
+  Integer * generator=new Integer[A.columns];
+  // The algorithm of Hosten and Sturmfels does not need supplementary
+  // variables.
+
+
+  // compute initial generating system from the kernel of A
+  for(int j=0;j<A._kernel_dimension;j++)
+  {
+
+    for(int k=0;k<A.columns;k++)
+    {
+
+      // We should first verifie if the components of the LLL-reduced lattice
+      // basis fit into the basic data type (Integer as defined in globals.h).
+      // This overflow control does of course not detect overflows in the
+      // course of the LLL-algorithm!
+
+#ifdef _SHORT_
+
+      if(((A.H)[j][k]>(const BigInt &)SHRT_MAX) || ((A.H)[j][k]<(const BigInt &)SHRT_MIN))
+      {
+        cerr<<"\nWARNING: ideal& ideal::Hosten_Sturmfels_ideal(matrix&, const "
+          "term_ordering&):\nLLL-reduced kernel basis does not fit "
+          "into the used basic data type int."<<endl;
+        size=-3;
+        delete[] generator;
+        return *this;
+      }
+
+#endif // _SHORT_
+
+#ifdef _INT_
+
+      if(((A.H)[j][k]>(const BigInt&)INT_MAX) || ((A.H)[j][k]<(const BigInt&)INT_MIN))
+      {
+        cerr<<"\nWARNING: ideal& ideal::Hosten_Sturmfels_ideal(matrix&, const "
+          "term_ordering&):\nLLL-reduced kernel basis does not fit "
+          "into the used basic data type int."<<endl;
+        size=-3;
+        delete[] generator;
+        return *this;
+      }
+
+#endif  // _INT_
+
+#ifdef _LONG_
+
+      if(((A.H)[j][k]>(const BigInt&)LONG_MAX) || ((A.H)[j][k]<(const BigInt&)LONG_MIN))
+      {
+        cerr<<"\nWARNING: ideal& ideal::Hosten_Sturmfels_ideal(matrix&, const "
+          "term_ordering&):\nLLL-reduced kernel basis does not fit "
+          "into the used basic data type long."<<endl;
+        size=-3;
+        delete[] generator;
+        return *this;
+      }
+
+#endif  // _LONG_
+
+      generator[k]=(A.H)[j][k];
+    }
+
+    // verifie term ordering
+    if(w.weight(generator)!=0)
+      cerr<<"\nWARNING: ideal& ideal::Hosten_Sturmfels_ideal(matrix&, "
+        "const term_ordering&):\nInvalid row space vector does not induce "
+        "homogenous grading."<<endl;
+
+    binomial* bin=new binomial(A.columns,generator,w);
+    add_generator(*bin);
+  }
+
+  delete[] generator;
+  return *this;
+}
+
+ideal& ideal::DiBiase_Urbanke_ideal(matrix& A, const term_ordering& _w)
+{
+  w=_w;
+
+  if(A._kernel_dimension==-2)
+    // kernel of A not yet computed, do this now
+    A.LLL_kernel_basis();
+
+  if((A._kernel_dimension==-1) &&  (A.columns<0))
+    // error occurred in kernel computation or matrix corrupt
+  {
+    cout<<"\nWARNING: ideal& ideal::DiBiase_Urbanke_ideal(matrix&, const "
+      "term_ordering&):\ncannot build ideal from a corrupt input matrix"<<endl;
+    size=-1;
+    return *this;
+  }
+
+  // now compute flip variables
+
+  int* F;
+  // set of flip variables
+  // If F[i]==j, x_j will be flipped.
+
+  int r=A.compute_flip_variables(F);
+  // number of flip variables
+
+  if(r<0)
+  {
+    cout<<"Kernel of the input matrix contains no vector with nonzero "
+      "components.\nPlease use another algorithm."<<endl;
+    size=-1;
+    return *this;
+  }
+
+  // check term ordering (as far as possible)
+  BOOLEAN ordering_okay=TRUE;
+
+  if(_w.weight_refinement()!=W_LEX)
+    ordering_okay=FALSE;
+
+  if(r>0)
+  {
+    for(int i=0;i<_w.number_of_weighted_variables();i++)
+      if((_w[i]!=0) && (i!=F[0]))
+        ordering_okay=FALSE;
+  }
+
+  if(ordering_okay==FALSE)
+    cerr<<"\nWARNING: ideal& ideal::DiBiase_Urbanke_ideal(matrix&, const "
+      "term_ordering&):\nargument term ordering might be inappropriate"<<endl;
+
+  Integer *generator=new Integer[A.columns];
+  // The algorithm of DiBiase and Urbanke does not need supplementary
+  // variables.
+
+  // compute initial generating system from the kernel of A
+  for(int j=0;j<A._kernel_dimension;j++)
+  {
+
+    for(int k=0;k<A.columns;k++)
+    {
+
+      // We should first verifie if the components of the LLL-reduced lattice
+      // basis fit into the basic data type (Integer as defined in globals.h).
+      // This overflow control does of course not detect overflows in the
+      // course of the LLL-algorithm!
+
+#ifdef _SHORT_
+
+      if(((A.H)[j][k]>(const BigInt &)SHRT_MAX) || ((A.H)[j][k]<(const BigInt &)SHRT_MIN))
+      {
+        cerr<<"\nWARNING: ideal& ideal::DiBiase_Urbanke_ideal(matrix&, const "
+          "term_ordering&):\nLLL-reduced kernel basis does not fit "
+          "into the used basic data type int."<<endl;
+        size=-3;
+        delete[] generator;
+        return *this;
+      }
+
+#endif // _SHORT_
+
+#ifdef _INT_
+
+      if(((A.H)[j][k]>(const BigInt&)INT_MAX) || ((A.H)[j][k]<(const BigInt&)INT_MIN))
+      {
+        cerr<<"\nWARNING: ideal& ideal::DiBiase_Urbanke_ideal(matrix&, const "
+          "term_ordering&):\nLLL-reduced kernel basis does not fit "
+          "into the used basic data type int."<<endl;
+        size=-3;
+        delete[] generator;
+        return *this;
+      }
+
+#endif  // _INT_
+
+#ifdef _LONG_
+
+      if(((A.H)[j][k]>(const BigInt&)LONG_MAX) || ((A.H)[j][k]<(const BigInt&)LONG_MIN))
+      {
+        cerr<<"\nWARNING: ideal& ideal::DiBiase_Urbanke_ideal(matrix&, const "
+          "term_ordering&):\nLLL-reduced kernel basis does not fit "
+          "into the used basic data type long."<<endl;
+        size=-3;
+        delete[] generator;
+        return *this;
+      }
+
+#endif  // _LONG_
+      generator[k]=(A.H)[j][k];
+    }
+
+    // flip variables
+    for(int l=0;l<r;l++)
+      generator[F[l]]*=-1;
+
+    binomial* bin=new binomial(A.columns,generator,w);
+    add_generator(*bin);
+  }
+  delete[] F;
+  delete[] generator;
+  return *this;
+}
+
+ideal& ideal::Bigatti_LaScala_Robbiano_ideal(matrix& A,const term_ordering& _w)
+{
+
+  // check term ordering
+  if((_w.weight_refinement()!=W_REV_LEX) && (_w.is_positive()==FALSE))
+    cerr<<"\nWARNING: ideal& ideal::Bigatti_LaScala_Robbiano_ideal(matrix&, "
+      "const term_ordering&):\nargument term ordering should be a weighted  "
+      "reverse lexicographical \nwith positive weights"<<endl;
+
+  w=_w;
+  // The argument term_ordering should be given by a homogenous grading.
+
+  if(A._kernel_dimension==-2)
+    // kernel of A not yet computed, do this now
+    A.LLL_kernel_basis();
+
+  if((A._kernel_dimension==-1) &&  (A.columns<0))
+    // error occurred in kernel computation or matrix corrupt
+  {
+    cout<<"\nWARNING: ideal& ideal::Bigatti_LaScala_Robbiano_ideal(matrix&, "
+      "const term_ordering&):\n"
+      "cannot build ideal from a corrupt input matrix"<<endl;
+    size=-1;
+    return *this;
+  }
+
+  // now compute saturation variables
+
+  // The techniques for computing a small set of saturation variables are
+  // useful here for the following two reasons:
+  // - The head of the saturation generator involves less variables, is
+  //   smaller in term ordering.
+  // - The weight of the pseudo-elimination variable is smaller.
+  int* sat_var;
+  int number_of_sat_var=A.hosten_shapiro(sat_var);
+
+  float weight=0;
+  for(int i=0;i<number_of_sat_var;i++)
+    weight+=w[sat_var[i]];
+
+  w.append_weighted_variable(weight);
+  // one supplementary variable used to saturate the ideal
+
+  Integer *generator=new Integer[A.columns+1];
+  // The algorithm of Bigatti, LaScala and Robbiano needs one supplementary
+  // weighted variable.
+
+  // first build "saturation generator"
+  for(int k=0;k<A.columns;k++)
+    generator[k]=0;
+  for(int i=0;i<number_of_sat_var;i++)
+    generator[sat_var[i]]=1;
+  generator[A.columns]=-1;
+
+  delete[] sat_var;
+
+  binomial* bin=new binomial(A.columns+1,generator,w);
+  add_generator(*bin);
+
+  // compute initial generating system from the kernel of A
+  for(int j=0;j<A._kernel_dimension;j++)
+  {
+    for(int k=0;k<A.columns;k++)
+    {
+      // We should first verifie if the components of the LLL-reduced lattice
+      // basis fit into the basic data type (Integer as defined in globals.h).
+      // This overflow control does of course not detect overflows in the
+      // course of the LLL-algorithm!
+
+#ifdef _SHORT_
+
+      if(((A.H)[j][k]>(const BigInt &)SHRT_MAX) || ((A.H)[j][k]<(const BigInt &)SHRT_MIN))
+      {
+        cerr<<"\nWARNING: ideal& ideal::Bigatti_LaScala_Robbiano_ideal"
+          "(matrix&, const term_ordering&):\nLLL-reduced kernel basis does "
+          "not fit into the used basic data type int."<<endl;
+        size=-3;
+        delete[] generator;
+        return *this;
+      }
+
+#endif // _SHORT_
+
+#ifdef _INT_
+
+      if(((A.H)[j][k]>(const BigInt&)INT_MAX) || ((A.H)[j][k]<(const BigInt&)INT_MIN))
+      {
+        cerr<<"\nWARNING: ideal& ideal::Bigatti_LaScala_Robbiano_ideal"
+          "(matrix&, const term_ordering&):\nLLL-reduced kernel basis does "
+          "not fit into the used basic data type int."<<endl;
+        size=-3;
+        delete[] generator;
+        return *this;
+      }
+
+#endif  // _INT_
+
+#ifdef _LONG_
+
+      if(((A.H)[j][k]>(const BigInt&)LONG_MAX) || ((A.H)[j][k]<(const BigInt&)LONG_MIN))
+      {
+        cerr<<"\nWARNING: ideal& ideal::Bigatti_LaScala_Robbiano_ideal"
+          "(matrix&, const term_ordering&):\nLLL-reduced kernel basis does "
+          "not fit into the used basic data type long."<<endl;
+        size=-3;
+        return *this;
+      }
+
+#endif  // _LONG_
+      generator[k]=(A.H)[j][k];
+    }
+    generator[A.columns]=0;
+    // saturation variable
+    // Note that the relative order of the variables is important (because
+    // of the reverse lexicographical refinement of the weight).
+
+    if(w.weight(generator)!=0)
+      cerr<<"\nWARNING: ideal& ideal::Bigatti_LaScala_Robbiano_ideal(matrix&, "
+        "const term_ordering&):\nInvalid row space vector does not induce "
+        "homogenous grading."<<endl;
+
+    binomial* bin=new binomial(A.columns+1,generator,w);
+    add_generator(*bin);
+    // insert generator
+  }
+  delete[] generator;
+  return *this;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+//////////////// public member functions ////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////// constructors and destructor /////////////////////////////
+
+ideal::ideal(matrix& A, const term_ordering& _w, const int& algorithm)
+{
+
+  // check arguments as far as possible
+
+  if(A.error_status()<0)
+  {
+    cerr<<"\nWARNING: ideal::ideal(matrix&, const term_ordering&, const "
+      "int&):\ncannot create ideal from a corrupt input matrix"<<endl;
+    size=-1;
+    return;
+  }
+
+  if(_w.error_status()<0)
+  {
+    cerr<<"\nWARNING: ideal::ideal(matrix&, const term_ordering&, const "
+      "int&):\ncannot create ideal with a corrupt input ordering"<<endl;
+    size=-1;
+    return;
+  }
+
+  if((_w.number_of_elimination_variables()!=0) &&
+     (_w.number_of_weighted_variables()!=A.columns))
+    cerr<<"\nWARNING: ideal& ideal::ideal(matrix&, const term_ordering&):\n"
+      "argument term ordering might be inappropriate"<<endl;
+
+#ifdef SUPPORT_DRIVEN_METHODS_EXTENDED
+
+  create_subset_tree();
+
+#endif  // SUPPORT_DRIVEN_METHODS_EXTENDED
+
+  size=0;
+
+  // initialize the S-pair flags with the default value
+  // (this is not really necessray, but looks nicer when outputting the
+  // ideal without having computed a Groebner basis)
+  rel_primeness=1;
+  M_criterion=2;
+  F_criterion=0;
+  B_criterion=8;
+  second_criterion=0;
+
+  interreduction_percentage=12.0;
+
+  // construct the ideal according to the algorithm
+  switch(algorithm)
+  {
+      case CONTI_TRAVERSO:
+        Conti_Traverso_ideal(A,_w);
+        break;
+      case POSITIVE_CONTI_TRAVERSO:
+        Positive_Conti_Traverso_ideal(A,_w);
+        break;
+      case POTTIER:
+        Pottier_ideal(A,_w);
+        break;
+      case HOSTEN_STURMFELS:
+        Hosten_Sturmfels_ideal(A,_w);
+        break;
+      case DIBIASE_URBANKE:
+        DiBiase_Urbanke_ideal(A,_w);
+        break;
+      case BIGATTI_LASCALA_ROBBIANO:
+        Bigatti_LaScala_Robbiano_ideal(A,_w);
+        break;
+      default:
+        cerr<<"\nWARNING: ideal::ideal(matrix&, const term_ordering&, const "
+          "int&):\nunknown algorithm for ideal construction"<<endl;
+        size=-1;
+        return;
+  }
+  number_of_new_binomials=size;
+}
+
+ideal::ideal(const ideal& I)
+{
+
+  if(I.error_status()<0)
+    cerr<<"\nWARNING: ideal::ideal(const ideal&):\n"
+      "trying to create ideal from a corrupt one"<<endl;
+
+  size=0;
+  // the size is automatically incremented when copying the generators
+
+  w=I.w;
+
+  rel_primeness=I.rel_primeness;
+  M_criterion=I.M_criterion;
+  F_criterion=I.F_criterion;
+  B_criterion=I.B_criterion;
+  second_criterion=I.second_criterion;
+
+  interreduction_percentage=I.interreduction_percentage;
+
+  // copy generators
+  // To be sure to get a real copy of the argument ideal, the lists
+  // aux_list and new_generators are also copied.
+  list_iterator iter;
+
+
+#ifdef NO_SUPPORT_DRIVEN_METHODS_EXTENDED
+
+  iter.set_to_list(I.generators);
+
+  while(iter.is_at_end()==FALSE)
+  {
+    binomial* bin=new binomial(iter.get_element());
+    add_generator(*bin);
+    iter.next();
+  }
+
+  iter.set_to_list(I.new_generators);
+
+  while(iter.is_at_end()==FALSE)
+  {
+    binomial* bin=new binomial(iter.get_element());
+    add_new_generator(*bin);
+    iter.next();
+  }
+
+#endif  // NO_SUPPORT_DRIVEN_METHODS_EXTENDED
+
+#ifdef SUPPORT_DRIVEN_METHODS_EXTENDED
+
+  create_subset_tree();
+
+  for(int i=0;i<Number_of_Lists;i++)
+  {
+    iter.set_to_list(I.generators[i]);
+
+    while(iter.is_at_end()==FALSE)
+    {
+      binomial* bin=new binomial(iter.get_element());
+      add_generator(*bin);
+      iter.next();
+    }
+  }
+
+  for(int i=0;i<Number_of_Lists;i++)
+  {
+    iter.set_to_list(I.new_generators[i]);
+
+    while(iter.is_at_end()==FALSE)
+    {
+      binomial* bin=new binomial(iter.get_element());
+      add_new_generator(*bin);
+      iter.next();
+    }
+  }
+
+#endif  // SUPPORT_DRIVEN_METHODS_EXTENDED
+
+  iter.set_to_list(I.aux_list);
+
+  while(iter.is_at_end()==FALSE)
+  {
+    binomial* bin=new binomial(iter.get_element());
+    aux_list._insert(*bin);
+    iter.next();
+  }
+  number_of_new_binomials=size;
+}
+
+ideal::ideal(ifstream& input, const term_ordering& _w, const int&
+             number_of_generators)
+{
+  if(_w.error_status()<0)
+  {
+    cerr<<"\nWARNING: ideal::ideal(ifstream&, const term_ordering&, const "
+      "int&):\ncannot create ideal with a corrupt input ordering"<<endl;
+    size=-1;
+    return;
+  }
+
+  w=_w;
+
+  // initialize the S-pair flags with the default value
+  // (this is not really necessray, but looks nicer when outputting the
+  // ideal without having computed a Groebner basis)
+  rel_primeness=1;
+  M_criterion=2;
+  F_criterion=0;
+  B_criterion=8;
+  second_criterion=0;
+
+  interreduction_percentage=12.0;
+
+#ifdef SUPPORT_DRIVEN_METHODS_EXTENDED
+
+  create_subset_tree();
+
+#endif  // SUPPORT_DRIVEN_METHODS_EXTENDED
+
+  int number_of_variables=
+    w.number_of_elimination_variables()+w.number_of_weighted_variables();
+  Integer* generator=new Integer[number_of_variables];
+
+  for(long i=0;i<number_of_generators;i++)
+  {
+    for(int j=0;j<number_of_variables;j++)
+    {
+      input>>generator[j];
+
+      if(!input)
+        // input failure, set "error flag"
+      {
+        cerr<<"\nWARNING: ideal::ideal(ifstream&, const term_ordering&, "
+          "const int&): \ninput failure when reading generator "<<i<<endl;
+        size=-2;
+        delete[] generator;
+        return;
+      }
+    }
+    binomial* bin=new binomial(number_of_variables,generator,w);
+    add_generator(*bin);
+  }
+  size=number_of_generators;
+  number_of_new_binomials=size;
+  delete[] generator;
+}
+
+ideal::~ideal()
+{
+
+#ifdef SUPPORT_DRIVEN_METHODS_EXTENDED
+
+  destroy_subset_tree();
+
+#endif  // SUPPORT_DRIVEN_METHODS_EXTENDED
+
+  // The destructor of the lists is automatically called.
+}
+
+///////////////////// object information ////////////////////////////////////
+
+long ideal::number_of_generators() const
+{
+  return size;
+}
+
+int ideal::error_status() const
+{
+  if(size<0)
+    return -1;
+  else
+    return 0;
+}
+
+//////////////////////////// output /////////////////////////////////////////
+
+void ideal::print() const
+{
+  printf("\nterm ordering:\n");
+  w.print();
+
+  printf("\ngenerators:\n");
+
+#ifdef SUPPORT_DRIVEN_METHODS_EXTENDED
+
+  for(int i=0;i<Number_of_Lists;i++)
+    generators[i].ordered_print(w);
+
+#endif  // SUPPORT_DRIVEN_METHODS_EXTENDED
+
+#ifdef NO_SUPPORT_DRIVEN_METHODS_EXTENDED
+
+    generators.ordered_print(w);
+
+#endif  // NO_SUPPORT_DRIVEN_METHODS_EXTENDED
+
+  printf("\nnumber of generators: %ld\n",size);
+}
+
+void ideal::print_all() const
+{
+  print();
+  cout<<"\nCurrently used S-pair criteria:"<<endl;
+  if(rel_primeness)
+    cout<<"relatively prime leading terms"<<endl;
+  if(M_criterion)
+    cout<<"criterion M"<<endl;
+  if(F_criterion)
+    cout<<"criterion F"<<endl;
+  if(B_criterion)
+    cout<<"criterion B"<<endl;
+  if(second_criterion)
+    cout<<"second criterion"<<endl;
+  cout<<"\nInterreduction frequency:  "<<setprecision(1)
+      <<interreduction_percentage<<" %"<<endl;
+}
+
+void ideal::print(FILE *output) const
+{
+  fprintf(output,"\nterm ordering:\n");
+  w.print(output);
+
+  fprintf(output,"\ngenerators:\n");
+
+#ifdef SUPPORT_DRIVEN_METHODS_EXTENDED
+
+  for(int i=0;i<Number_of_Lists;i++)
+    generators[i].ordered_print(output,w);
+
+#endif  // SUPPORT_DRIVEN_METHODS_EXTENDED
+
+#ifdef NO_SUPPORT_DRIVEN_METHODS_EXTENDED
+
+    generators.ordered_print(output,w);
+
+#endif  // NO_SUPPORT_DRIVEN_METHODS_EXTENDED
+
+  fprintf(output,"\nnumber of generators: %ld\n",size);
+
+  fprintf(output,"\nInterreduction frequency:  %.1f %% \n", interreduction_percentage);
+}
+
+void ideal::print_all(FILE* output) const
+{
+  print(output);
+  fprintf(output,"\nCurrently used S-pair criteria:\n");
+  if(rel_primeness)
+    fprintf(output,"relatively prime leading terms\n");
+  if(M_criterion)
+    fprintf(output,"criterion M\n");
+  if(F_criterion)
+    fprintf(output,"criterion F\n");
+  if(B_criterion)
+    fprintf(output,"criterion B\n");
+  if(second_criterion)
+    fprintf(output,"second criterion\n");
+}
+
+void ideal::print(ofstream& output) const
+{
+  output<<"\nterm ordering:\n"<<endl;
+  w.print(output);
+
+  output<<"\ngenerators:\n"<<endl;
+
+#ifdef SUPPORT_DRIVEN_METHODS_EXTENDED
+
+  for(int i=0;i<Number_of_Lists;i++)
+    generators[i].ordered_print(output,w);
+
+#endif  // SUPPORT_DRIVEN_METHODS_EXTENDED
+
+#ifdef NO_SUPPORT_DRIVEN_METHODS_EXTENDED
+
+    generators.ordered_print(output,w);
+
+#endif  // NO_SUPPORT_DRIVEN_METHODS_EXTENDED
+
+    output<<"\nnumber of generators: "<<size<<endl;
+}
+
+void ideal::print_all(ofstream& output) const
+{
+  print(output);
+  output<<"\nCurrently used S-pair criteria:"<<endl;
+  if(rel_primeness)
+    output<<"relatively prime leading terms"<<endl;
+  if(M_criterion)
+    output<<"criterion M"<<endl;
+  if(F_criterion)
+    output<<"criterion F"<<endl;
+  if(B_criterion)
+    output<<"criterion B"<<endl;
+  if(second_criterion)
+    output<<"second_criterion"<<endl;
+  output<<"\nInterreduction frequency:  "<<setprecision(1)
+        <<interreduction_percentage<<" %"<<endl;
+}
+
+void ideal::format_print(ofstream& output) const
+{
+#ifdef SUPPORT_DRIVEN_METHODS_EXTENDED
+
+  for(int i=0;i<Number_of_Lists;i++)
+    generators[i].ordered_format_print(output,w);
+
+#endif  // SUPPORT_DRIVEN_METHODS_EXTENDED
+
+#ifdef NO_SUPPORT_DRIVEN_METHODS_EXTENDED
+
+    generators.ordered_format_print(output,w);
+
+#endif  // NO_SUPPORT_DRIVEN_METHODS_EXTENDED
+}
+#endif  // IDEAL_CC
diff --git a/IntegerProgramming/ideal.h b/IntegerProgramming/ideal.h
new file mode 100644
index 0000000..a526146
--- /dev/null
+++ b/IntegerProgramming/ideal.h
@@ -0,0 +1,370 @@
+// ideal.h
+
+// This class implements a saturated binomial ideal. Such an ideal is
+// given by its generators.
+// If SUPPORT_DRIVEN_METHODS_EXTENDED are enabled, the generators are not
+// stored in a single list, but classified according to their support. This
+// representation, together with the subset_tree data structure, allows a
+// faster search for reducers.
+
+// The entries of the two-dimensional array "subsets_of_support" are to be
+// read as bit vectors with List_Support_Variables components (the constant
+// List_Support_Variables is defined in globals.h). So all entries
+// are in the range between 0 and 2^List_Support_Variables -1.
+// subsets_of_support[i] is an array that contains all binary vectors whose
+// support is a subset of that of i, i read as a binary vector.
+// number_of_subsets[i] is the number of these subsets, i.e. the length of
+// the array subsets_of_support[i].
+
+// If, for example, List_Support_Variables=8, the datastructure subset_tree
+// has 6561=8^3 entries.
+
+
+
+#ifndef IDEAL_H
+#define IDEAL_H
+
+
+
+#include "list.h"
+#include "matrix.h"
+
+
+
+
+const int Number_of_Lists=1<<List_Support_Variables;
+
+
+
+
+////////////////////// struct subset_tree ////////////////////////////////////
+
+typedef struct
+{
+  int* subsets_of_support[Number_of_Lists];
+  int number_of_subsets[Number_of_Lists];
+} subset_tree;
+
+//////////////////////// class ideal /////////////////////////////////////////
+
+class ideal
+{
+
+private:
+
+// generator lists
+
+#ifdef SUPPORT_DRIVEN_METHODS_EXTENDED
+
+  subset_tree S;
+
+  list generators[Number_of_Lists];
+
+  list new_generators[Number_of_Lists];
+  // Only needed in some special versions of Buchberger�s algorithm to
+  // store newly found generators.
+
+#endif  // SUPPORT_DRIVEN_METHODS_EXTENDED
+
+
+#ifdef NO_SUPPORT_DRIVEN_METHODS_EXTENDED
+
+  list generators;
+
+  list new_generators;
+  // Only needed in some special versions of Buchberger�s algorithm to
+  // store newly found generators.
+
+#endif  // NO_SUPPORT_DRIVEN_METHODS_EXTENDED
+
+// flags for the use of the S-pair criteria and the autoreduction
+
+  int rel_primeness;
+  int M_criterion;
+  int F_criterion;
+  int B_criterion;
+  int second_criterion;
+  // When Buchberger�s algorithm is called, we only use one argument which
+  // describes the combination of the criteria to be used (see in globals.h).
+  // But we use five flags instead of one here because this is a little more
+  // efficient.
+  // The standard setting enables the relative primeness criterion, the M- and
+  // the B-criterion.
+
+  float interreduction_percentage;
+  // To  determine the autoreduction frequency, i.e. the percentage of new
+  // generators (i.e. generators found since the last autoreduction) with
+  // respect to the total size of an ideal that must be reached to cause an
+  // interreduction.
+  // If Interreduction_Percentage==0, interreduction is done after each
+  // S-Pair computation. If Interreduction_Percentage<0, interreduction is
+  // only done once at the end of the algorithm.
+  // The standard setting is 12 (=12%).
+
+// further members
+
+  term_ordering w;
+  // For technical reasons, the term ordering is taken as a member.
+  // So we do not need to pass it as an argument to each ideal function,
+  // and the management of the generator lists is easier and safer when
+  // using SUPPORT_DRIVEN_METHODS_EXTENDED.
+
+  list aux_list;
+  // an auxiliary list for keeping (for example) S-pairs
+
+  long size;
+  // the actual number of generators of the ideal
+  // Also used as an "error flag"; a negative size means that an error has
+  // occurred:
+  // -1 indicates a "semantic" error (which occurs e.g. if some constructor
+  //    argument is out of range)
+  // -2 indicates an error occured when reading from a file
+  // -3 indicates an overflow of an integer type variable
+
+
+  long number_of_new_binomials;
+  // the number of newly found generators
+
+// private member functions
+
+// subroutines for building and deleting the subset_tree data structure
+// (implemented in ideal.cc)
+
+#ifdef SUPPORT_DRIVEN_METHODS_EXTENDED
+
+  void create_subset_tree();
+  void destroy_subset_tree();
+
+#endif  // SUPPORT_DRIVEN_METHODS_EXTENDED
+
+// subroutines for Buchberger�s algorithm (implemented in Buchberger.cc except
+// from the first two implemeted in ideal.cc)
+
+// Some of these procedures do not interact with all versions of Buchberger�s
+// algorithm. Generally, they cannot be combined as one likes. This header
+// file only gives a brief overview of their features. For more detailed
+// comments see the implementation.
+
+  ideal& add_new_generator(binomial& bin);
+  ideal& add_generator(binomial& bin);
+  // Inserts a (new) generator in the appropriate list.
+
+  int add_new_generators();
+  // Moves the new generators to the generator lists.
+
+// S-pair computation
+
+  BOOLEAN unnecessary_S_pair(list_iterator&, list_iterator&) const;
+  // Checks if the S_Pair of the binomials referenced by the iterators can be
+  // discarded (by the criteria chosen in globals.h).
+
+  ideal& compute_actual_S_pairs_1();
+  ideal& compute_actual_S_pairs_1a();
+  ideal& compute_actual_S_pairs_2();
+  ideal& compute_actual_S_pairs_3();
+  // different versions for computing the S-binomials of the actual generators
+  // They differ for example in the following points:
+  // - They insert the S-binomials in the order in which they are computed, in
+  //   the order given by the term ordering w or according to their support.
+  // - Some reduce an S-binomial directly after its computation by the ideal
+  //   generators, others reduce it later (after having computed more
+  //   S-binomials, hence more possible reducers).
+  // - Some reduce the ideal generators immediately by a newly computed
+  //   S-binomial, others don�t.
+  // In each case, the use of the list flag "done" guarantees that we perform
+  // the S-pair computation only once for each binomial pair.
+
+// minimalization / autoreduction
+
+  ideal& reduce_by(const binomial&, list_iterator&, list_iterator&);
+  // Reduces the heads of the ideal generators by the given binomial
+  // (used by some versions of the S-pair computation).
+
+  ideal& minimalize_S_pairs();
+  ideal& minimalize_new_generators();
+  ideal& minimalize();
+  // Performs an autoreduction of the binomials stored in aux_list
+  // respectively in the list(s) new_generators respectively in the
+  // generators.
+  // The respective list(s) is (are) reduced to a minimal set (not
+  // necessarily to a reduced set); this means that only the heads of the
+  // binomials are reduced, not their tails. This strategy showed to be
+  // a little more efficient than a complete autoreduction.
+  // The last two procedures use the "head_reduced" flag of the list class
+  // to avoid unnecessary tests for interreduction.
+
+  ideal& final_reduce();
+  // final interreduction of the ideal generators
+  // It seems to be slightly more efficient to perform a complete
+  // interreduction only at the end of Buchberger's algorithm and
+  // to replace the intermediate interreductions by minimalizations.
+  // For efficiency reasons, this routine is designed for reducing a
+  // Groebner basis of an saturated ideal. Reducing another generating
+  // set with it may cause inconsistencies (cf. comment in the implementation).
+
+// constructor subroutines for the handling of the different algorithms
+// (implemented in ideal.cc)
+// The "Conti-Traverso constructors" create a toric ideal directly from the
+// input matrix and the term ordering given by the input weight vector.
+// The other constructors create a toric ideal from a lattice basis of
+// the kernel of the input matrix.
+
+  ideal& Conti_Traverso_ideal(matrix&, const term_ordering&);
+  ideal& Positive_Conti_Traverso_ideal(matrix&, const term_ordering&);
+  ideal& Pottier_ideal(matrix&, const term_ordering&);
+  ideal& Hosten_Sturmfels_ideal(matrix&, const term_ordering&);
+  ideal& DiBiase_Urbanke_ideal(matrix&, const term_ordering&);
+  ideal& Bigatti_LaScala_Robbiano_ideal(matrix&, const term_ordering&);
+
+public:
+
+// constructors and destructor (implemented in ideal.cc)
+
+  ideal(matrix&, const term_ordering&, const int& algorithm);
+  // Creates a binomial ideal from the given matrix using the given algorithm
+  // (see in globals.h).
+  // The arguments are checked for consistency as far as possible.
+  // The term ordering is needed to determine the leading terms of the
+  // binomials in the resulting generating set. Neither is the generated ideal
+  // saturated nor is it given in form of a Groebner basis.
+  // Such computations must be explicitely demanded.
+  // The argument matrix cannot be declared as const because the constructor
+  // may call the LLL-algorithm to compute the matrix kernel (if this hasn�t
+  // been done yet). This algorithm changes some matrix members. But the
+  // real matrix remains, of course, unchanged.
+
+  ideal(const ideal&);
+  // copy-constructor
+  // It might be useful to keep several Groebner bases of the same ideal
+  // (or of an ideal and its elimination ideal).
+
+  ideal(ifstream&, const term_ordering&, const int& number_of_generators);
+  // Reads an ideal from a given ifstream in the following way:
+  // A block of integers is converted into a binomial
+  // that is stored in the generator list(s) with respect to the given
+  // term ordering. The size of such a block is the size of the given
+  // term_ordering, i.e. the number of variables for which it was constructed.
+  // This is done number_of_generators times.
+
+   ~ideal();
+  // destructor
+
+// object information (implemented in ideal.cc)
+
+  long number_of_generators() const;
+  // Returns the actual number of generators.
+
+  int error_status() const;
+  // Returns -1 if an error has occurred (i.e. size<0), else 0.
+
+// Buchberger stuff (implemented in Buchberger.cc)
+
+  ideal& reduced_Groebner_basis_1(const int& S_pair_criteria=11,
+                                  const float& interred_percentage=12.0);
+  ideal& reduced_Groebner_basis_1a(const int& S_pair_criteria=11,
+                                   const float& interred_percentage=12.0);
+  ideal& reduced_Groebner_basis_2(const int& S_pair_criteria=11,
+                                  const float& interred_percentage=12.0);
+  ideal& reduced_Groebner_basis_3(const int& S_pair_criteria=11,
+                                  const float& interred_percentage=12.0);
+  // Several different versions of Buchberger�s algorithm for computing
+  // the reduced Groebner basis of the actual ideal. They differ in the
+  // steering of the algorithm (i.e. in the way in which the S-pair
+  // computation and reduction is organized). Further variants can be
+  // obtained by setting the flags in globals.h (autoreduction frequency,
+  // use of the S-pair criteria and the support information).
+  // Except from the variant 1a (which orders the S-pairs with respect to w
+  // and which showed to be quite slow), the efficiency of these algorithms
+  // does not differ too much.
+  // The first argument indicates which criteria will be used to discard
+  // unnecessary S-pairs. For an explaination of how this works, see in
+  // globals.h. The default value 11 means that we use the criterion of
+  // relatively prime leading terms as well as the M- and the B-criterion.
+  // The second argument specifies the interreduction frequency; see the
+  // comment for the member interreduction_percentage above. The standard
+  // value is 12%.
+  // ATTENTION: In spite of the different argument type you should never
+  // try to use these functions with one default argument (either two or
+  // none). When writing
+  //    reduced_Groebner_basis_1(10.5),
+  // the GNU C++ compiler casts 10.5 into an integer and takes it as the
+  // argument S_pair_criteria!
+  // ATTENTION: If the input ideal is not saturated, the computed reduced
+  // Groebner basis is not that of the input ideal, but that of an ideal
+  // "between" the input ideal and its saturation.
+
+  ideal& reduced_Groebner_basis(const int& version=1,
+                                const int& S_pair_criteria=11,
+                                const float& interred_percentage=12.0);
+  // Takes the version of Buchberger�s algorithm as above as an argument
+  // (to allow a call of different versions of our IP-algorithms from the
+  // command line). To call version 1a, the first argument has to be zero.
+
+  binomial& reduce(binomial& bin, BOOLEAN complete=TRUE) const;
+  // Reduces a binomial by the actual generators.
+  // To reduce a binomial by the ideal (outside of Buchberger�s algorithm),
+  // be sure to have computed the reduced Groebner basis before.
+  // The flag "complete" indicates if the binomial is reduced completely
+  // (head and tail); if it is set to FALSE, only the tail will be reduced.
+  // Using this flag in a clever manner allows to improve the performance
+  // of Buchberger's algorithm by up to three percent.
+
+// special features needed by our IP-algorithms
+// (implemented in ideal_stuff.cc)
+
+  ideal& eliminate();
+  // Eliminates the generators involving elimination variables
+  // (with respect to the term ordering w).
+  // The reduced Groebner basis with respect to w should have been computed
+  // before calling this routine.
+
+  ideal& pseudo_eliminate();
+  // Eliminates the generators involving the last weighted variable -
+  // a special routine needed by the algorithm of Bigatti, La Scala and
+  // Robbiano.
+
+  ideal& change_term_ordering_to(const term_ordering& _w);
+  // Replaces the actual term ordering by the argument ordering.
+  // Their "compatibility" (number of variables) is checked, head and tail
+  // of the generators are adapted to the new ordering.
+  // This may especially involve a rebuilding of the list structure if
+  // SUPPORT_DRIVEN_METHODS_EXTENDED are enabled.
+
+  ideal& swap_variables(const int& i, const int& j);
+  // Swaps the i-th and the j-th variable in all generators as well as the
+  // corresponding components of the term ordering's weight vector.
+  // If SUPPORT_DRIVEN_METHODS are enabled, the list structure is rebuilt
+  // according to the new order on the variables.
+
+  ideal& swap_variables_unsafe(const int& i, const int& j);
+  // Swaps the i-th and the j-th variable in all generators as well as the
+  // corresponding components of the term ordering's weight vector.
+  // DANGER: The head/tail structure is not rebuilt!
+
+  ideal& flip_variable_unsafe(const int& i);
+  // Inverts the sign of the i-th variable in all generators.
+  // DANGER: The list structure is not rebuilt!
+
+// output (implemented in ideal.cc)
+
+  void print() const;
+  void print_all() const;
+  // Writes the ideal to the standard output medium.
+  // The second routine also prints the S-pair flags.
+
+  void print(FILE*) const;
+  void print_all(FILE*) const;
+  // Writes the ideal to the referenced file which has to be opened
+  // for writing before.
+
+  void print(ofstream&) const;
+  void print_all(ofstream &) const;
+  // Writes the ideal to the given ofstream.
+
+  void format_print(ofstream&) const;
+  // Writes the ideal generators to the given ofstream in a format
+  // that allows them to be reread by the ideal constructor from an ifstream.
+
+};
+
+#endif  // IDEAL_H
diff --git a/IntegerProgramming/ideal_stuff.cc b/IntegerProgramming/ideal_stuff.cc
new file mode 100644
index 0000000..f30efe1
--- /dev/null
+++ b/IntegerProgramming/ideal_stuff.cc
@@ -0,0 +1,471 @@
+// ideal_stuff.cc
+
+// implementation of the special ideal features needed by the IP-algorithms
+
+#ifndef IDEAL_STUFF_CC
+#define IDEAL_STUFF_CC
+
+#include "ideal.h"
+
+////////////////////// elimination stuff ///////////////////////////////////
+
+ideal& ideal::eliminate()
+{
+// eliminates the generators of the ideal involving elimination variables
+// with respect to w
+
+  if(w.number_of_elimination_variables()<=0)
+    // elimination unnecessary
+    return *this;
+
+  list_iterator iter;
+
+#ifdef NO_SUPPORT_DRIVEN_METHODS_EXTENDED
+
+// Simply iterate over the generator list and delete the elements involving
+// elimination variables.
+// There is no need to change the done/undone or the reduced/unreduced mark of
+// an element.
+
+  iter.set_to_list(generators);
+
+  while((iter.is_at_end())==FALSE)
+  {
+    binomial& bin=iter.get_element();
+
+    if(bin.involves_elimination_variables(w)==TRUE)
+    {
+      iter.delete_element();
+      size--;
+    }
+    else
+    {
+      bin.drop_elimination_variables(w);
+      iter.next();
+    }
+  }
+
+#endif  // NO_SUPPORT_DRIVEN_METHODS_EXTENDED
+
+
+#ifdef SUPPORT_DRIVEN_METHODS_EXTENDED
+
+// Iterate over the generator lists and check whether the elements involve
+// elimination variables.
+// As the set of support variables can be changed by the elimination, the
+// elements that are not deleted are first moved to the aux_list and then
+// reinserted according to their new support.
+// The elimination variables are droppd while reinserting.
+// In general, elimination is done only once. The time needed for this is
+// linear in the number of generators (in the Groebner basis). The elimination
+// itself is therefore very fast in comparison to the Groebner basis
+// computation needed for it... So we renounce to a complicated optimization
+// of this procedure (the support information is not used). In fact, tests
+// show that elimination time is really negligible.
+
+  // elimination
+  for(int i=0;i<Number_of_Lists;i++)
+  {
+    iter.set_to_list(generators[i]);
+
+    while((iter.is_at_end())==FALSE)
+    {
+      binomial& bin=iter.get_element();
+
+      if(bin.involves_elimination_variables(w)==TRUE)
+      {
+        iter.delete_element();
+        size--;
+      }
+      else
+      {
+        aux_list._insert(bin);
+        iter.extract_element();
+        // As the generators are reinserted later, we do not decrement the
+        // size (and so do not need to increment it during reinsertion).
+      }
+    }
+  }
+
+  // reinsertion
+  iter.set_to_list(aux_list);
+
+  while(iter.is_at_end()==FALSE)
+  {
+    binomial& bin=iter.get_element();
+    bin.drop_elimination_variables(w);
+    generators[bin.head_support%Number_of_Lists].insert(bin);
+    // size is not incremented, see above...
+    iter.extract_element();
+  }
+
+#endif  // SUPPORT_DRIVEN_METHODS_EXTENDED
+
+
+  // finally adapt term ordering
+  w.convert_to_weighted_ordering();
+
+  return *this;
+}
+
+
+
+
+ideal& ideal::pseudo_eliminate()
+{
+
+  if(w.number_of_weighted_variables()<=0)
+  {
+    cerr<<"WARNING: ideal& ideal::pseudo_eliminate():\n"
+      "cannot be performed without weighted variables"<<endl;
+    return *this;
+  }
+
+
+  list_iterator iter;
+
+  int last_weighted_variable=w.number_of_weighted_variables()-1;
+
+
+#ifdef NO_SUPPORT_DRIVEN_METHODS_EXTENDED
+
+// Simply iterate over the generator list and delete the elements involving
+// the last weighted variable.
+// There is no need to change the done/undone or the reduced/unreduced mark of
+// an element.
+
+  iter.set_to_list(generators);
+
+  while(iter.is_at_end()==FALSE)
+  {
+    binomial& bin=iter.get_element();
+
+    if(bin[last_weighted_variable]!=0)
+      // weighted variable to drop is involved in bin
+    {
+      iter.delete_element();
+      size--;
+    }
+    else
+    {
+      bin.drop_last_weighted_variable(w);
+      iter.next();
+    }
+  }
+
+#endif  // NO_SUPPORT_DRIVEN_METHODS_EXTENDED
+
+
+#ifdef SUPPORT_DRIVEN_METHODS_EXTENDED
+
+// Iterate over the generator lists and check whether the elements involve
+// the last weighted variable.
+// As the set of support variables can be changed by the pseudo-elimination,
+// the elements that are not deleted are first moved to the aux_list and then
+// reinserted according to their new support.
+// The last weight variable is dropped while reinserting.
+// For the time needed by this function see the remarks for ideal::eliminate().
+
+  for(int i=0;i<Number_of_Lists;i++)
+  {
+    iter.set_to_list(generators[i]);
+
+    while((iter.is_at_end())==FALSE)
+    {
+      binomial& bin=iter.get_element();
+
+      if(bin[last_weighted_variable]!=0)
+      {
+        iter.delete_element();
+        size--;
+      }
+      else
+      {
+        aux_list._insert(bin);
+        iter.extract_element();
+        // As the generators are reinserted later, we do not decrement the
+        // size (and so do not need to increment it during reinsertion).
+      }
+    }
+  }
+
+
+  iter.set_to_list(aux_list);
+
+  while(iter.is_at_end()==FALSE)
+  {
+    binomial& bin=iter.get_element();
+    bin.drop_last_weighted_variable(w);
+    generators[bin.head_support%Number_of_Lists].insert(bin);
+    // size is not incremented, see above...
+    iter.extract_element();
+  }
+
+#endif  // SUPPORT_DRIVEN_METHODS_EXTENDED
+
+  // finally adapt term ordering
+  w.delete_last_weighted_variable();
+
+  return *this;
+}
+
+
+
+
+/////////////////// management of the term ordering /////////////////////////
+
+
+
+
+ideal& ideal::change_term_ordering_to(const term_ordering& _w)
+{
+
+  // first check compatibility
+  if((w.number_of_weighted_variables()+w.number_of_elimination_variables())!=
+     (_w.number_of_weighted_variables()+_w.number_of_elimination_variables()))
+  {
+    cerr<<"WARNING: ideal& ideal::change_term_ordering_to"
+      "(const term_ordering&):\nincompatibility detected, term ordering not"
+      "changed."<<endl;
+    return *this;
+  }
+
+  // change term ordering
+  w=_w;
+
+  list_iterator iter;
+
+
+#ifdef NO_SUPPORT_DRIVEN_METHODS_EXTENDED
+
+// Simply iterate over the generator list. Because the change of the term
+// ordering, the "done" and "reduced" marks of the elements have to be deleted.
+
+  iter.set_to_list(generators);
+
+  while((iter.is_at_end())==FALSE)
+  {
+    (iter.get_element()).adapt_to_term_ordering(w);
+    iter.mark_element_undone();
+    iter.mark_element_head_unreduced();
+    iter.next();
+  }
+
+#endif  // NO_SUPPORT_DRIVEN_METHODS_EXTENDED
+
+
+#ifdef SUPPORT_DRIVEN_METHODS_EXTENDED
+
+// As head and tail might have to be exchanged, the elements are first moved to
+// the aux_list and then reinserted according to their new head.
+
+  for(int i=0;i<Number_of_Lists;i++)
+  {
+    iter.set_to_list(generators[i]);
+
+    while((iter.is_at_end())==FALSE)
+    {
+      binomial& bin=iter.get_element();
+
+      if(bin.adapt_to_term_ordering(w)==-1)
+        // head and tail exchanged
+      {
+        aux_list._insert(bin);
+        iter.extract_element();
+        // As the generators are reinserted later, we do not decrement the
+        // size (and so do not need to increment it during reinsertion).
+      }
+      else
+      {
+        // Although the S-pairs of the remaining elements have already been
+        // computed once, the "done" marks have to be deleted: With a new
+        // term ordering, the results of the S-pair reduction can change -
+        // as well as the interreduction results.
+        iter.mark_element_undone();
+        iter.mark_element_head_unreduced();
+        iter.next();
+      }
+    }
+  }
+
+  // reinsertion
+  iter.set_to_list(aux_list);
+
+  while(iter.is_at_end()==FALSE)
+  {
+    binomial& bin=iter.get_element();
+    generators[bin.head_support%Number_of_Lists].insert(bin);
+    // size is not incremented, see above...
+    iter.extract_element();
+  }
+
+#endif  // SUPPORT_DRIVEN_METHODS_EXTENDED
+
+
+  return *this;
+}
+
+
+
+
+/////////// manipulation of the variables ///////////////////////////////////
+
+
+
+
+ideal& ideal::swap_variables_unsafe(const int& i, const int& j)
+{
+  // first check arguments
+  if((i<0) || (i>=w.number_of_weighted_variables())
+     || (j<0) || (j>=w.number_of_weighted_variables()))
+  {
+    cout<<"WARNING: ideal::swap_variables(const int&, const int&)\n "
+      "or ideal::swap_variables_unsafe(const int&, const int&):\n"
+      "index out of range"<<endl;
+    return *this;
+  }
+
+  if(i==j)
+    return(*this);
+  // special case to avoid unnecessary overhead
+
+
+  list_iterator iter;
+
+
+#ifdef NO_SUPPORT_DRIVEN_METHODS_EXTENDED
+
+  iter.set_to_list(generators);
+
+  while((iter.is_at_end())==FALSE)
+  {
+    (iter.get_element()).swap_variables(i,j);
+    iter.next();
+  }
+
+#endif  // NO_SUPPORT_DRIVEN_METHODS_EXTENDED
+
+
+#ifdef SUPPORT_DRIVEN_METHODS_EXTENDED
+
+// As head_support and tail_support are manipulated, the elements are first
+// moved to the aux_list and then reinserted according to their new head.
+// But head and tail are not adapted to the new term ordering induced by
+// the change of the variable order - this is only done in the "safe"
+// routine swap_variables(const int&, const int&).
+
+  for(int l=0;l<Number_of_Lists;l++)
+  {
+    iter.set_to_list(generators[l]);
+
+    while((iter.is_at_end())==FALSE)
+    {
+      binomial& bin=iter.get_element();
+      bin.swap_variables(i,j);
+      aux_list._insert(bin);
+      iter.extract_element();
+      // As the generators are reinserted later, we do not decrement the
+      // size (and so do not need to increment it during reinsertion).
+    }
+  }
+
+  // reinsertion
+  iter.set_to_list(aux_list);
+
+  while(iter.is_at_end()==FALSE)
+  {
+    binomial& bin=iter.get_element();
+    generators[bin.head_support%Number_of_Lists].insert(bin);
+    // size is not incremented, see above...
+    iter.extract_element();
+  }
+
+#endif  // SUPPORT_DRIVEN_METHODS_EXTENDED
+
+
+  // finally adapt term ordering
+  w.swap_weights(i,j);
+
+  return *this;
+}
+
+
+
+
+ideal& ideal::swap_variables(const int& i, const int& j)
+{
+
+  swap_variables_unsafe(i,j);
+
+  change_term_ordering_to(w);
+  // This rebuilds the list structure...
+
+  return *this;
+}
+
+
+
+
+ideal& ideal::flip_variable_unsafe(const int& i)
+{
+  // first check argument
+  if((i<0) || (i>=w.number_of_weighted_variables()))
+  {
+    cout<<"WARNING: ideal::flip_variables(const int&):\n"
+      "argument out of range, nothing done"<<endl;
+    return *this;
+  }
+
+
+  list_iterator iter;
+
+
+#ifdef NO_SUPPORT_DRIVEN_METHODS_EXTENDED
+
+  iter.set_to_list(generators);
+
+  while((iter.is_at_end())==FALSE)
+  {
+    (iter.get_element()).flip_variable(i);
+    iter.next();
+  }
+
+#endif  // NO_SUPPORT_DRIVEN_METHODS_EXTENDED
+
+
+#ifdef SUPPORT_DRIVEN_METHODS_EXTENDED
+
+// As head_support and tail_support can change, the elements are first moved
+// to the aux_list and then reinserted according to their new head.
+
+  for(int l=0;l<Number_of_Lists;l++)
+  {
+    iter.set_to_list(generators[l]);
+
+    while((iter.is_at_end())==FALSE)
+    {
+      binomial& bin=iter.get_element();
+      bin.flip_variable(i);
+      aux_list._insert(bin);
+      iter.extract_element();
+      // As the generators are reinserted later, we do not decrement the
+      // size (and so do not need to increment it during reinsertion).
+    }
+  }
+
+  // reinsertion
+  iter.set_to_list(aux_list);
+
+  while(iter.is_at_end()==FALSE)
+  {
+    binomial& bin=iter.get_element();
+    generators[bin.head_support%Number_of_Lists].insert(bin);
+    iter.extract_element();
+    // size is not incremented, see above...
+  }
+
+#endif  // SUPPORT_DRIVEN_METHODS_EXTENDED
+
+  return *this;
+}
+#endif  // IDEAL_STUFF_CC
diff --git a/IntegerProgramming/list.cc b/IntegerProgramming/list.cc
new file mode 100644
index 0000000..9b68962
--- /dev/null
+++ b/IntegerProgramming/list.cc
@@ -0,0 +1,1166 @@
+// list.cc
+
+// implementation of class list and class list iterator
+
+#ifndef LIST_CC
+#define LIST_CC
+
+#include "list.h"
+
+/////////////////////////////////////////////////////////////////////////////
+///////////////////////// class list ////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////// constructors and destructor /////////////////////////////
+
+list::list()
+{
+
+#ifdef DL_LIST
+
+  element* begin_dummy=new element;
+
+#endif  // DL_LIST
+
+  element* end_dummy=new element;
+
+#ifdef DL_LIST
+
+  begin_dummy->previous=NULL;
+  begin_dummy->next=end_dummy;
+  begin_dummy->entry=NULL;
+  begin_dummy->done=FALSE;
+  begin_dummy->head_reduced=FALSE;
+  end_dummy->previous=begin_dummy;
+
+#endif  // DL_LIST
+
+  end_dummy->next=NULL;
+  end_dummy->entry=NULL;
+  end_dummy->done=TRUE;
+  end_dummy->head_reduced=TRUE;
+
+#ifdef DL_LIST
+
+  start=begin_dummy;
+
+#endif  // DL_LIST
+
+#ifdef SL_LIST
+
+  start=end_dummy;
+
+#endif  // SL_LIST
+
+}
+
+// The dummy elements have the following functions:
+// - The end_dummy guarantees that the deletion method of the simply linked
+//   list works: Deletion is done by copying the next element to the actual
+//   position and then deleting the original, see below for an explaination.
+//   This would cause problems when deleting the last element; then the
+//   next-pointer of the preceeding element would reference freed memory
+//   (it cannot be manipulated, is unknown). So the end_dummy as an
+//   artificial last element avoids this problem.
+// - With the described deletion method for a simply linked list, the start
+//   pointer of a list has never to be changed by the list_iterator class
+//   (as long as the list is not empty; but with the end_dummy, the list
+//   never becomes empty). So a list iterator must never know on which list
+//   he operates on.
+//   Doubly linked lists use another, more secure deletion method (which
+//   really deletes the actual element). Therefore, the comfort of a start
+//   pointer which has never to be manipulated by the iterators must be
+//   reached in another way: This is the purpose of the begin_dummy, an
+//   artificial first element which is referenced by the start pointer and
+//   never changed.
+// - With the dummy elements, we do need to distinguish the cases of inserting
+//   or deleting at the beginning or the end of a list.
+// - Furthermore, the end_dummy is a stopper for Buchberger's algorithm:
+//   By setting all flags to TRUE, we can eliminate many calls of the
+//   is_at_end()-function of the list iterator class.
+// The dummy elements should never be deleted (the dletion method is not
+// secure)!
+
+
+
+
+list::list(const list& l)
+{
+
+#ifdef DL_LIST
+
+  element* begin_dummy=new element;
+
+#endif  // DL_LIST
+
+  element* end_dummy=new element;
+
+#ifdef DL_LIST
+
+  begin_dummy->previous=NULL;
+  begin_dummy->next=end_dummy;
+  begin_dummy->entry=NULL;
+  begin_dummy->done=FALSE;
+  begin_dummy->head_reduced=FALSE;
+
+  end_dummy->previous=NULL;
+
+#endif  // DL_LIST
+
+  end_dummy->next=NULL;
+  end_dummy->entry=NULL;
+  end_dummy->done=TRUE;
+  end_dummy->head_reduced=TRUE;
+
+#ifdef DL_LIST
+
+  start=begin_dummy;
+  element *iter=(l.start)->next;
+
+#endif  // DL_LIST
+
+#ifdef SL_LIST
+
+  element* iter=l.start;
+
+#endif  // SL_LIST
+
+  if(iter==NULL)
+  {
+    cerr<<"\nWARNING: list::list(const list&):\ntry to construct a list from"
+      " a corrupt one; empty list created"<<endl;
+    return;
+  }
+
+  while((iter->next)!=NULL)
+    // end_dummy not reached
+  {
+    copy_insert(*(iter->entry));
+    iter=iter->next;
+  }
+
+}
+
+
+
+
+list::~list()
+{
+
+#ifdef DL_LIST
+
+  element *iter=start->next;
+
+#endif  // DL_LIST
+
+#ifdef SL_LIST
+
+  element *iter=start;
+
+#endif  // SL_LIST
+
+  while(iter->next!=NULL)
+    // delete non-dummy elements
+  {
+    element* aux=iter;
+    iter=iter->next;
+    delete aux->entry;
+    delete aux;
+  }
+
+  // end_dummy reached, delete it
+  delete iter;
+
+#ifdef DL_LIST
+
+  // delete begin_dummy
+  delete start;
+
+#endif  // DL_LIST
+
+}
+
+
+
+
+///////////////////// inserting ////////////////////////////////////////////
+
+// For a better overview, the code for the simply and for the doubly linked
+// list is separated (except from the "copy-insert"-routines).
+
+
+
+
+#ifdef DL_LIST
+
+
+
+
+list& list::insert(binomial& bin)
+{
+  // insert at the beginning (after the begin_dummy)
+
+  // initialize element
+  element* aux=new element;
+  aux->entry=&bin;
+  aux->done=FALSE;
+  aux->head_reduced=FALSE;
+
+  // set pointers
+  aux->next=start->next;
+  aux->next->previous=aux;
+  aux->previous=start;
+  start->next=aux;
+
+  return(*this);
+}
+
+
+
+
+list& list::_insert(binomial& bin)
+{
+  // insert at the beginning
+
+  // initialize element
+  element* aux=new element;
+  aux->entry=&bin;
+
+  // set pointers
+  aux->next=start->next;
+  aux->next->previous=aux;
+  aux->previous=start;
+  start->next=aux;
+
+  return(*this);
+}
+
+
+
+
+list& list::ordered_insert(binomial& bin, const term_ordering& w)
+{
+
+  // search for the place to insert
+  element* iter=start->next;
+  while(iter->entry!=NULL)
+    // end_dummy not reached
+  {
+    if(w.compare(*(iter->entry),bin)<=0)
+      // bin is bigger in term ordering then the referenced binomial
+      iter=iter->next;
+    else
+      break;
+  }
+
+  // now bin is smaller in term ordering then the referenced binomial
+  // or the referenced binomial is the end_dummy
+
+  // initialize element
+  element*aux=new element;
+  aux->entry=&bin;
+  aux->done=FALSE;
+  aux->head_reduced=FALSE;
+
+  // set pointers
+  aux->previous=iter->previous;
+  aux->previous->next=aux;
+  aux->next=iter;
+  iter->previous=aux;
+
+  return *this;
+}
+
+
+
+
+list& list::_ordered_insert(binomial& bin, const term_ordering& w)
+{
+  // search for the place to insert
+  element* iter=start->next;
+  while(iter->entry!=NULL)
+    // end_dummy not reached
+  {
+    if(w.compare(*(iter->entry),bin)<=0)
+      // bin is bigger in term ordering then the referenced binomial
+      iter=iter->next;
+    else
+      break;
+  }
+
+  // now bin is smaller in term ordering then the referenced binomial
+  // or the referenced binomial is the end_dummy
+
+  // initialize element
+  element*aux=new element;
+  aux->entry=&bin;
+
+  // set pointers
+  aux->previous=iter->previous;
+  aux->previous->next=aux;
+  aux->next=iter;
+  iter->previous=aux;
+
+  return *this;
+}
+
+
+
+
+#endif  // DL_LIST
+
+
+
+
+#ifdef SL_LIST
+
+
+
+
+list& list::insert(binomial& bin)
+{
+  // insert at the beginning
+
+  // initialize element
+  element* aux=new element;
+  aux->entry=&bin;
+  aux->done=FALSE;
+  aux->head_reduced=FALSE;
+
+  // set pointers
+  aux->next=start;
+  start=aux;
+
+  return(*this);
+}
+
+
+
+
+list& list::_insert(binomial& bin)
+{
+  // insert at the beginning
+
+  // initialize element
+  element* aux=new element;
+  aux->entry=&bin;
+
+  // set pointers
+  aux->next=start;
+  start=aux;
+
+  return(*this);
+}
+
+
+
+
+list& list::ordered_insert(binomial& bin, const term_ordering& w)
+{
+  // search for the place to insert
+  element* iter=start;
+  while(iter->entry!=NULL)
+    // end_dummy not reached
+  {
+    if(w.compare(*(iter->entry),bin)<=0)
+      // bin is bigger in term ordering then the referenced binomial
+      iter=iter->next;
+    else
+      break;
+  }
+
+  // now bin is smaller in term ordering then the referenced binomial
+  // or the referenced binomial is the end_dummy
+
+  // here we have to consider a special case
+  if(iter==start)
+    return insert(bin);
+
+  // insert new element by first allocating a new list place behind the
+  // referenced element, then moving the referenced element to that
+  // new place...
+  element*aux=new element;
+  aux->entry=iter->entry;
+  aux->done=iter->done;
+  aux->head_reduced=iter->head_reduced;
+  aux->next=iter->next;
+
+  // .. and finally inserting bin at the old place
+  // Remember that we cannot insert a new element between the referenced
+  // element and its preceeding (we do not know the preceeding element)
+  iter->entry=&bin;
+  iter->done=FALSE;
+  iter->head_reduced=FALSE;
+  iter->next=aux;
+
+  return *this;
+}
+
+
+
+
+list& list::_ordered_insert(binomial& bin, const term_ordering& w)
+{
+  // search for the place to insert
+  element* iter=start;
+  while(iter->entry!=NULL)
+    // end_dummy not reached
+  {
+    if(w.compare(*(iter->entry),bin)<=0)
+      // bin is bigger in term ordering then the referenced binomial
+      iter=iter->next;
+    else
+      break;
+  }
+
+  // now bin is smaller in term ordering then the referenced binomial
+  // or the referenced binomial is the end_dummy
+
+  // here we have to consider a special case
+  if(iter==start)
+    return _insert(bin);
+
+  // insert new element by first allocating a new list place behind the
+  // referenced element, then moving the referenced element to that
+  // new place...
+  element*aux=new element;
+  aux->entry=iter->entry;
+  aux->next=iter->next;
+
+  // .. and finally inserting bin at the old place
+  // Remember that we cannot insert a new element between the referenced
+  // element and its preceeding (we do not know the preceeding element)
+  iter->entry=&bin;
+  iter->next=aux;
+
+  return *this;
+}
+
+
+
+
+#endif  // SL_LIST
+
+
+
+
+// copy-insert routines
+
+list& list::copy_insert(const binomial& bin)
+{
+  binomial* _bin=new binomial(bin);
+  return insert(*_bin);
+}
+
+
+list& list::_copy_insert(const binomial& bin)
+{
+  binomial *_bin=new binomial(bin);
+  return _insert(*_bin);
+}
+
+
+list& list::ordered_copy_insert(const binomial& bin, const term_ordering& w)
+{
+  binomial *_bin=new binomial(bin);
+  return ordered_insert(*_bin,w);
+}
+
+
+list& list::_ordered_copy_insert(const binomial& bin, const term_ordering& w)
+{
+  binomial *_bin=new binomial(bin);
+  return _ordered_insert(*_bin,w);
+}
+
+
+
+
+/////////////////////////// output //////////////////////////////////////////
+
+
+
+
+void list::print() const
+{
+
+#ifdef DL_LIST
+
+  element* iter=start->next;
+
+#endif  // DL_LIST
+
+#ifdef SL_LIST
+
+  element *iter=start;
+
+#endif  // SL_LIST
+
+  if(iter==NULL)
+  {
+    cerr<<"\nWARNING: void list::print() const:\ncannot print corrupt list"
+        <<endl;
+    return;
+  }
+
+  while(iter->next!=NULL)
+  {
+    iter->entry->print();
+    iter=iter->next;
+  }
+}
+
+
+
+
+void list::ordered_print(const term_ordering& w) const
+{
+
+#ifdef DL_LIST
+
+  element* iter=start->next;
+
+#endif  // DL_LIST
+
+#ifdef SL_LIST
+
+  element *iter=start;
+
+#endif  // SL_LIST
+
+  if(iter==NULL)
+  {
+    cerr<<"\nWARNING: void list::print(const term_ordering&) const:\n"
+      "cannot print corrupt list"<<endl;
+    return;
+  }
+
+  list aux;
+
+  while(iter->next!=NULL)
+  {
+    aux._ordered_insert(*(iter->entry),w);
+    iter=iter->next;
+  }
+
+  aux.print();
+
+  // delete aux, but only the element structs, not the binomials
+  // (these are still stored in the actual list!)
+
+#ifdef DL_LIST
+
+  iter=aux.start->next;
+
+#endif  // DL_LIST
+
+#ifdef SL_LIST
+
+  iter=aux.start;
+
+#endif
+
+  while(iter->next!=NULL)
+    // end_dummy not reached
+  {
+    element* aux2=iter->next;
+    iter->next=iter->next->next;
+    delete aux2;
+  }
+
+  // the dummy elements are deleted by the destructor
+
+}
+
+
+
+
+void list::print(FILE* output) const
+{
+
+#ifdef DL_LIST
+
+  element* iter=start->next;
+
+#endif  // DL_LIST
+
+#ifdef SL_LIST
+
+  element *iter=start;
+
+#endif  // SL_LIST
+
+  if(iter==NULL)
+  {
+    cerr<<"\nWARNING: void list::print(FILE*) const:\ncannot print corrupt "
+      "list"<<endl;
+    fprintf(output,"\nWARNING: void list::print(FILE*) const:\ncannot print "
+            "corrupt list\n");
+    return;
+  }
+
+  while(iter->next!=NULL)
+  {
+    iter->entry->print(output);
+    iter=iter->next;
+  }
+}
+
+
+
+
+void list::ordered_print(FILE* output, const term_ordering& w) const
+{
+
+#ifdef DL_LIST
+
+  element* iter=start->next;
+
+#endif  // DL_LIST
+
+#ifdef SL_LIST
+
+  element *iter=start;
+
+#endif  // SL_LIST
+
+  if(iter==NULL)
+  {
+    cerr<<"\nWARNING: void list::print(const term_ordering&) const:\n"
+      "cannot print corrupt list"<<endl;
+    fprintf(output,"\nWARNING: void list::print(const term_ordering&) const:\n"
+      "cannot print corrupt list\n");
+    return;
+  }
+
+  list aux;
+
+  while(iter->next!=NULL)
+  {
+    aux._ordered_insert(*(iter->entry),w);
+    iter=iter->next;
+  }
+
+  aux.print(output);
+
+  // delete aux, but only the element structs, not the binomials
+  // (these are still stored in the actual list!)
+
+#ifdef DL_LIST
+
+  iter=aux.start->next;
+
+#endif  // DL_LIST
+
+#ifdef SL_LIST
+
+  iter=aux.start;
+
+#endif
+
+  while(iter->next!=NULL)
+    // end_dummy not reached
+  {
+    element* aux2=iter->next;
+    iter->next=iter->next->next;
+    delete aux2;
+  }
+
+  // the dummy elements are deleted by the destructor
+}
+
+
+
+
+void list::print(ofstream& output) const
+{
+
+#ifdef DL_LIST
+
+  element* iter=start->next;
+
+#endif  // DL_LIST
+
+#ifdef SL_LIST
+
+  element *iter=start;
+
+#endif  // SL_LIST
+
+  if(iter==NULL)
+  {
+    cerr<<"\nWARNING: void list::print(ofstream&) const:\n"
+      "cannot print corrupt list"<<endl;
+    output<<"\nWARNING: void list::print(oftream&) const:\ncannot print "
+      "corrupt list"<<endl;
+    return;
+  }
+
+  while(iter->next!=NULL)
+  {
+    iter->entry->print(output);
+    iter=iter->next;
+  }
+}
+
+
+
+
+void list::ordered_print(ofstream& output, const term_ordering& w) const
+{
+
+#ifdef DL_LIST
+
+  element* iter=start->next;
+
+#endif  // DL_LIST
+
+#ifdef SL_LIST
+
+  element *iter=start;
+
+#endif  // SL_LIST
+
+  if(iter==NULL)
+  {
+    cerr<<"\nWARNING: void list::ordered_print(const term_ordering&) const:\n"
+      "cannot print corrupt list"<<endl;
+    output<<"\nWARNING: void list::ordered_print(const term_ordering&) const:"
+      "\n"
+      "cannot print corrupt list\n"<<endl;
+    return;
+  }
+
+  list aux;
+
+  while(iter->next!=NULL)
+  {
+    aux._ordered_insert(*(iter->entry),w);
+    iter=iter->next;
+  }
+
+  aux.print(output);
+
+  // delete aux, but only the element structs, not the binomials
+  // (these are still stored in the actual list!)
+
+#ifdef DL_LIST
+
+  iter=(aux.start)->next;
+
+#endif  // DL_LIST
+
+#ifdef SL_LIST
+
+
+  iter=aux.start;
+
+#endif
+
+
+  while((iter->next)!=NULL)
+  {
+    element* aux1=iter->next;
+    iter->next=iter->next->next;
+    delete aux1;
+  }
+
+  // the dummy elements are deleted by the destructor
+}
+
+
+
+
+void list::format_print(ofstream& output) const
+{
+
+#ifdef DL_LIST
+
+  element* iter=start->next;
+
+#endif  // DL_LIST
+
+#ifdef SL_LIST
+
+  element *iter=start;
+
+#endif  // SL_LIST
+
+  if(iter==NULL)
+  {
+    cerr<<"\nWARNING: void list::print(ofstream&) const:\n"
+      "cannot print corrupt list"<<endl;
+    output<<"\nWARNING: void list::print(oftream&) const:\ncannot print "
+      "corrupt list"<<endl;
+    return;
+  }
+
+  while(iter->next!=NULL)
+  {
+    iter->entry->format_print(output);
+    iter=iter->next;
+  }
+}
+
+
+
+
+void list::ordered_format_print(ofstream& output, const term_ordering& w) const
+{
+
+#ifdef DL_LIST
+
+  element* iter=start->next;
+
+#endif  // DL_LIST
+
+#ifdef SL_LIST
+
+  element *iter=start;
+
+#endif  // SL_LIST
+
+  if(iter==NULL)
+  {
+    cerr<<"\nWARNING: void list::ordered_format_print(const term_ordering&) "
+      "const:\n"
+      "cannot print corrupt list"<<endl;
+    output<<"\nWARNING: void list::ordered_format_print(const term_ordering&) "
+      "const:\n"
+      "cannot print corrupt list\n"<<endl;
+    return;
+  }
+
+  list aux;
+
+  while(iter->next!=NULL)
+  {
+    aux._ordered_insert(*(iter->entry),w);
+    iter=iter->next;
+  }
+
+  aux.format_print(output);
+
+  // delete aux, but only the element structs, not the binomials
+  // (these are still stored in the actual list!)
+
+#ifdef DL_LIST
+
+  iter=(aux.start)->next;
+
+#endif  // DL_LIST
+
+#ifdef SL_LIST
+
+
+  iter=aux.start;
+
+#endif
+
+
+  while((iter->next)!=NULL)
+  {
+    element* aux1=iter->next;
+    iter->next=iter->next->next;
+    delete aux1;
+  }
+
+  // the dummy elements are deleted by the destructor
+}
+
+
+
+
+
+/////////////////////////////////////////////////////////////////////////////
+////////////////////// class list_iterator //////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+
+// implementation of class list_iterator
+// Most of these function can be inlined. I have tried this and not improved
+// the performance. Perhaps the compiler does this automatically...
+
+
+
+
+///////////////////////// constructors and destructor ///////////////////////
+
+
+
+
+list_iterator::list_iterator()
+{
+  actual=NULL;
+}
+
+
+
+list_iterator::list_iterator(list& l)
+{
+
+#ifdef DL_LIST
+
+  actual=(l.start)->next;
+
+#endif // DL_LIST
+
+#ifdef SL_LIST
+
+  actual=l.start;
+
+#endif // SL_LIST
+
+}
+
+
+
+list_iterator::list_iterator(list_iterator& iter)
+{
+  actual=iter.actual;
+}
+
+
+
+list_iterator::~list_iterator()
+{
+}
+
+
+
+
+/////////////////// object information /////////////////////////////////////
+
+
+
+
+BOOLEAN list_iterator::element_is_marked_done() const
+{
+  return(actual->done);
+}
+
+
+BOOLEAN list_iterator::element_is_marked_head_reduced() const
+{
+  return(actual->head_reduced);
+}
+
+
+BOOLEAN list_iterator::is_at_end() const
+{
+  if(actual==NULL)
+  // actual references no list
+    return(TRUE);
+
+  if(actual->next==NULL)
+  // actual references dummy element
+    return(TRUE);
+
+  // actual references a real element
+  return(FALSE);
+}
+
+
+
+
+////////////////////////// assigment ///////////////////////////////////////
+
+
+
+
+list_iterator& list_iterator::set_to_list(const list& l)
+{
+
+#ifdef DL_LIST
+
+  actual=(l.start)->next;
+
+#endif  // DL_LIST
+
+#ifdef SL_LIST
+
+  actual=l.start;
+
+#endif  // SL_LIST
+
+  return *this;
+}
+
+
+
+list_iterator& list_iterator::operator=(const list_iterator& iter)
+{
+  if((&iter)!=this)
+    actual=iter.actual;
+  return *this;
+}
+
+
+
+list_iterator& list_iterator::next()
+{
+  actual=actual->next;
+  return *this;
+}
+
+
+
+
+/////////////////// comparison ////////////////////////////////////////////
+
+
+
+
+int list_iterator::operator==(const list_iterator& iter) const
+{
+  return(actual==iter.actual);
+}
+
+
+int list_iterator::operator!=(const list_iterator& iter) const
+{
+  return(!(actual==iter.actual));
+}
+
+
+int list_iterator::next_is(const list_iterator& iter) const
+{
+  return ((actual->next)==iter.actual);
+}
+
+
+
+
+////////////// manipulation of list elements //////////////////////////////
+
+// For a better overview, the code of the delete- and extract-routine is
+// separated for simply and doubly linked lists.
+
+
+
+
+binomial& list_iterator::get_element()
+{
+  return(*(actual->entry));
+}
+
+
+
+
+#ifdef DL_LIST
+
+
+
+
+list_iterator& list_iterator::delete_element()
+{
+  binomial* aux1=actual->entry;
+  element*  aux2=actual;
+
+  actual->previous->next=actual->next;
+  actual->next->previous=actual->previous;
+
+  actual=actual->next;
+
+  delete aux1;
+  delete aux2;
+  return *this;
+}
+
+
+
+
+list_iterator& list_iterator::extract_element()
+{
+  element* aux=actual;
+
+  actual->previous->next=actual->next;
+  actual->next->previous=actual->previous;
+
+  actual=actual->next;
+
+  delete aux;
+  return *this;
+}
+
+
+
+
+#endif  // DL_LIST
+
+
+
+
+#ifdef SL_LIST
+
+// When deleting or extracting an element of a simply linked list, the
+// next-pointer of the previous element cannot be manipulated (is unkonwn!).
+// So deletion must be done by copying the next element to the actual position
+// and then deleting the original. Notice that only pointers are copies, never
+// binomials.
+
+
+
+
+list_iterator& list_iterator::delete_element()
+{
+  binomial* aux1=actual->entry;
+  element* aux2=actual->next;
+
+  actual->done=actual->next->done;
+  actual->head_reduced=actual->next->head_reduced;
+  actual->entry=actual->next->entry;
+  actual->next=actual->next->next;
+
+  delete aux1;
+  delete aux2;
+
+  return *this;
+}
+
+
+
+
+list_iterator& list_iterator::extract_element()
+{
+  element* aux=actual->next;
+
+  actual->done=actual->next->done;
+  actual->head_reduced=actual->next->head_reduced;
+  actual->entry=actual->next->entry;
+  actual->next=actual->next->next;
+
+  delete aux;
+  return *this;
+}
+#endif  // SL_LIST
+
+list_iterator& list_iterator::mark_element_done()
+{
+  actual->done=TRUE;
+  return *this;
+}
+
+
+
+list_iterator& list_iterator::mark_element_undone()
+{
+  actual->done=FALSE;
+  return *this;
+}
+
+
+
+list_iterator& list_iterator::mark_element_head_reduced()
+{
+  actual->head_reduced=TRUE;
+  return *this;
+}
+
+
+
+list_iterator& list_iterator::mark_element_head_unreduced()
+{
+  actual->head_reduced=FALSE;
+  return *this;
+}
+#endif  // LIST_CC
diff --git a/IntegerProgramming/list.h b/IntegerProgramming/list.h
new file mode 100644
index 0000000..d92caec
--- /dev/null
+++ b/IntegerProgramming/list.h
@@ -0,0 +1,303 @@
+// list.h
+
+
+// The classes "list" and "list_iterator" are designed for the special needs
+// of Buchberger's algorithm; it is not recommendable to use them for
+// more general purposes.
+// "list" implements a simply linked list of binomials (or, more exactly,
+// pointers on binomials).
+// A list_iterator is not much more than a pointer to a list element, but using
+// iterators instead of pointers makes the code of Buchberger's algorithm much
+// easier to read.
+
+// The delegation of tasks to this classes and the realization of some
+// functions are quite special.
+// So is the insertion of list elements the task of the class list, while the
+// deletion is delegated to the iterator class. The reason is the simple:
+// Elements are almost always inserted at the beginning of a list (except
+// from the case of an ordered list), but can be deleted from an arbitrary
+// place (this is necessary e.g. if a binomial is reduced to zero during
+// Buchberger's algorithm).
+
+// For efficiency reasons, the iterator operations are not secure. They do
+// not check if the iterator really references a list element or if it has
+// reached the end of the list. To assert this, use the is_at_end()-test.
+
+// I have designed an own iterator class instead of taking pointers for
+// iteration as lists members for flexibility reasons:
+// Buchberger's algorithm requires to form pairs of binomials (or, for
+// testing criteria to discard S-Pairs, even triples). So we need up to
+// three pointers to iterate over the generator lists. The advantage of the
+// iterator class is simply that the programmer does not have to keep
+// in mind the lists over which he is actually iterating.
+// This was very helpful for me during the implementation of Buchberger's
+// algorithm (especially for the implementation of
+// SUPPORT_DRIVEN_METHODS_EXTENDED where many lists have to be considered).
+
+
+// There are two different implementations of the class list:
+// - If SL_LIST is set, we use a simply linked list.
+//   The insert operations are very efficient because we have to set very
+//   few pointers. But the deletion of an element is a dangerous operation
+//   because it moves the following element (not the binomial, but the struct)
+//   to another storage place.
+// - If DL_LIST is set, we use a doubly linked list.
+//   This shows to be considerably slower, but it is easier to use
+
+
+
+#ifndef LIST_H
+#define LIST_H
+
+
+
+#define DL_LIST
+// possibilities:
+// SL_LIST
+// DL_LIST
+
+
+
+#include "binomial__term_ordering.h"
+
+
+
+
+////////////////////////////// struct element ///////////////////////////////
+
+
+
+
+typedef struct Element
+{
+  binomial *entry;
+  struct Element *next;
+
+
+#ifdef DL_LIST
+
+  struct Element *previous;
+
+#endif  // DL_LIST
+
+
+  // flags needed by the ideal implementation to speed up Buchberger's
+  // algorithm
+  BOOLEAN done;
+  BOOLEAN head_reduced;
+
+} element;
+
+
+
+
+/////////////////////////// class list ////////////////////////////////////
+
+
+
+
+class list
+{
+
+
+
+private:
+
+
+  element *start;
+  // pointer to the beginning
+
+
+
+public:
+
+
+// constructors and destructor
+
+  list();
+  // Creates an "empty" list (with a dummy element for a user friendly
+  // iterator class, see the comments in list.cc).
+
+  list(const list&);
+  // copy-constructor
+
+  ~list();
+  // destructor
+
+
+
+// inserting
+
+  list& insert(binomial&);
+  list& copy_insert(const binomial&);
+  // These operations insert a binomial at the beginning of the list:
+  // insert does this by placing pointers on it, copy_insert by copying the
+  // binomial.
+  // The first operation is dangerous; but the consequent use of the
+  // combination insert - extract_element (cf. class list_iterator) instead of
+  // copy_insert - delete_element is very important for the performance of
+  // Buchberger's algorithm.
+
+  list& _insert(binomial&);
+  list& _copy_insert(const binomial&);
+  // A little more efficient insert function for list that do not use
+  // the 3 flags - these are not set.
+  // It is not more efficient to implement these simpler lists as an own class.
+
+  list& ordered_insert(binomial&, const term_ordering&);
+  list& ordered_copy_insert(const binomial&, const term_ordering&);
+  // These operations insert a binomial according to the given term ordering
+  // into a list. (The list should be ordered by the same term ordering.)
+  // To insert elements, we use a simple linear search.
+
+  list& _ordered_insert(binomial&, const term_ordering&);
+  list& _ordered_copy_insert(const binomial&, const term_ordering&);
+  // A little more efficient ordered_insert function for list that do not use
+  // the 3 flags - these are not set.
+
+
+
+// output
+
+  void print() const;
+  void ordered_print(const term_ordering&) const;
+  // Writes the list to the standard output medium.
+  // The first routine writes the list elements as they are oredred in
+  // the list.
+  // The second one writes them in increasing order with respect to the
+  // argument term ordering; the list has not to be ordered before and
+  // will not be ordered after. This routine is essentially written to
+  // compare Gr�bner bases.
+
+  void print(FILE* output) const;
+  void ordered_print(FILE* output, const term_ordering&) const;
+  // Writes the list to the referenced file which has to be opened for
+  // writing before.
+
+  void print(ofstream&) const;
+  void ordered_print(ofstream&, const term_ordering&) const;
+  // Writes the list to the given ofstream.
+
+  void format_print(ofstream&) const;
+  void ordered_format_print(ofstream&, const term_ordering&) const;
+  // Writes the list to the given ofstream in the format needed by the
+  // IP-algorithms.
+
+  friend class list_iterator;
+
+};
+
+
+
+
+///////////////////// class list_iterator ////////////////////////////////
+
+
+
+
+class list_iterator
+{
+
+
+
+private:
+
+  element* actual;
+
+
+
+public:
+
+
+
+// constructors and destructor
+
+  list_iterator();
+  // Sets actual to NULL.
+
+  list_iterator(list& l);
+  // Sets a list_iterator to the beginning of l.
+
+  list_iterator(list_iterator& iter);
+  // Sets a list iterator to the same position as iter.
+
+  ~list_iterator();
+  // destructor
+
+
+
+// object information
+
+  BOOLEAN element_is_marked_done() const;
+  // Returns the "done"-component of the referenced element.
+
+  BOOLEAN element_is_marked_head_reduced() const;
+  // Returns the "head_reduced"-component of the referenced element.
+
+  BOOLEAN is_at_end() const;
+  // Returns TRUE iff the iterator is at the end of "its" list
+  // (especially if the iterator references no list).
+
+
+
+// assignment
+
+  list_iterator& set_to_list(const list& l);
+  // Sets the iterator to the beginning of l.
+
+  list_iterator& operator=(const list_iterator& iter);
+  // Sets the iterator to the same element as iter.
+
+  list_iterator& next();
+  // Sets the iterator to the next entry.
+
+
+
+// comparison
+
+  int operator==(const list_iterator& iter) const;
+  int operator!=(const list_iterator& iter) const;
+  // These operators verifie if actual references the same element
+  // as iter.actual.
+
+  int next_is(const list_iterator& iter) const;
+  // Checks if actual->next references the same element as iter.actual.
+  // This check is needed in very special situations (two iterators reference
+  // subsequent elements of a list, and the first is deleted; then the
+  // iterator referencing the second before deletion references freed memory
+  // after deletion, cf. the implementation of delete and extract).
+
+
+
+// manipulation of list elements
+
+  // All this operations could be declared as const because they do not
+  // change the "actual" pointer. For suggestive reasons, this is not done
+  // because they change the referenced list element.
+
+  binomial& get_element();
+  // Returns the referenced binomial.
+
+  list_iterator& delete_element();
+  // Deletes the referenced binomial.
+
+  list_iterator& extract_element();
+  // Only resets pointers so that the refenced binomial is no longer found
+  // when iterating over the list.
+
+  list_iterator& mark_element_done();
+  // Sets the "done"-component of the referenced element to TRUE.
+
+  list_iterator& mark_element_undone();
+  // Sets the "done"-component of the referenced element to FALSE.
+
+  list_iterator& mark_element_head_reduced();
+  // Sets the "head_reduced"-component of the referenced element to TRUE.
+
+  list_iterator& mark_element_head_unreduced();
+  // Sets the "head_reduced"-component of the referenced element to FALSE.
+
+};
+
+
+#endif  // list.h
diff --git a/IntegerProgramming/matrix.cc b/IntegerProgramming/matrix.cc
new file mode 100644
index 0000000..bc8b121
--- /dev/null
+++ b/IntegerProgramming/matrix.cc
@@ -0,0 +1,730 @@
+// matrix.cc
+
+// implementation of class matrix
+
+#ifndef MATRIX_CC
+#define MATRIX_CC
+
+#include "matrix.h"
+
+////////////// constructors and destructor //////////////////////////////////
+typedef Integer* IntegerP;
+typedef BigInt* BigIntP;
+
+matrix::matrix(const int& row_number, const int& column_number)
+    :rows(row_number),columns(column_number)
+{
+  _kernel_dimension=-2;
+  // LLL-algorithm not yet performed
+
+  // argument check
+  if((rows<=0)||(columns<=0))
+    // bad input, set "error flag"
+  {
+    cerr<<"\nWARNING: matrix::matrix(const int&, const int&):\n"
+      "argument out of range"<<endl;
+    columns=-1;
+    return;
+  }
+
+  // memory allocation and initialization
+
+  coefficients=new IntegerP[rows];
+  for(int i=0;i<rows;i++)
+    coefficients[i]=new Integer[columns];
+  for(int i=0;i<rows;i++)
+    for(int j=0;j<columns;j++)
+      coefficients[i][j]=0;
+}
+
+matrix::matrix(const int& row_number, const int& column_number,
+               Integer** entries)
+    :rows(row_number),columns(column_number)
+{
+  _kernel_dimension=-2;
+  // LLL-algorithm not yet performed
+
+  // argument check
+  if((rows<=0)||(columns<=0))
+    // bad input, set "error flag"
+  {
+    cerr<<"\nWARNING: matrix::matrix(const int&, const int&, Integr**):\n"
+      "argument out of range"<<endl;
+    columns=-1;
+    return;
+  }
+
+  // memory allocation and initialization
+
+  coefficients=new IntegerP[rows];
+  for(int i=0;i<rows;i++)
+    coefficients[i]=new Integer[columns];
+  for(int i=0;i<rows;i++)
+    for(int j=0;j<columns;j++)
+      coefficients[i][j]=entries[i][j];
+  // coefficients[i] is the i-th row vector
+}
+
+
+
+
+matrix::matrix(ifstream& input)
+{
+  _kernel_dimension=-2;
+  // LLL-algorithm not yet performed
+
+  input>>rows;
+  if(!input)
+    // input failure, set "error flag"
+  {
+    cerr<<"\nWARNING: matrix::matrix(ifstream&): input failure"<<endl;
+    columns=-2;
+    return;
+  }
+
+  input>>columns;
+  if(!input)
+    // input failure, set "error flag"
+  {
+    cerr<<"\nWARNING: matrix::matrix(ifstream&): input failure"<<endl;
+    columns=-2;
+    return;
+  }
+
+  if((rows<=0)||(columns<=0))
+    // bad input, set "error flag"
+  {
+    cerr<<"\nWARNING: matrix::matrix(ifstream&): bad input"<<endl;
+    columns=-1;
+    return;
+  }
+
+  coefficients=new IntegerP[rows];
+  for(int i=0;i<rows;i++)
+    coefficients[i]=new Integer[columns];
+  for(int i=0;i<rows;i++)
+    for(int j=0;j<columns;j++)
+    {
+      input>>coefficients[i][j];
+      if(!input)
+        // bad input, set error flag
+      {
+        cerr<<"\nWARNING: matrix::matrix(ifstream&): input failure"<<endl;
+        columns=-2;
+        return;
+      }
+    }
+}
+
+
+
+
+matrix::matrix(const int& m, const int& n, ifstream& input)
+{
+  _kernel_dimension=-2;
+  // LLL-algorithm not yet performed
+
+  // argument check
+  if((m<=0) || (n<=0))
+    // bad input, set "error flag"
+  {
+    cerr<<"\nWARNING: matrix::matrix(const int&, const int&, ifstream&):\n"
+      "argument out of range"<<endl;
+    columns=-1;
+    return;
+  }
+
+  rows=m;
+  columns=n;
+
+  // memory allocation and initialization
+
+  coefficients=new IntegerP[rows];
+  for(int i=0;i<rows;i++)
+    coefficients[i]=new Integer[columns];
+  for(int i=0;i<rows;i++)
+    for(int j=0;j<columns;j++)
+    {
+      input>>coefficients[i][j];
+      if(!input)
+        // bad input, set error flag
+      {
+        columns=-2;
+        return;
+      }
+    }
+}
+
+
+
+
+matrix::matrix(const matrix& A)
+    :rows(A.rows),columns(A.columns),_kernel_dimension(A._kernel_dimension)
+{
+
+  if(columns<0)
+  {
+    cerr<<"\nWARNING: matrix::matrix(const matrix&):\n"
+      "Building a matrix from a corrupt one"<<endl;
+    return;
+  }
+
+  // memory allocation and initialization (also for H)
+
+  coefficients=new IntegerP[rows];
+  for(int i=0;i<rows;i++)
+    coefficients[i]=new Integer[columns];
+  for(int i=0;i<rows;i++)
+    for(int j=0;j<columns;j++)
+      coefficients[i][j]=A.coefficients[i][j];
+
+  if(_kernel_dimension>0)
+  {
+    H=new BigIntP[_kernel_dimension];
+    for(int k=0;k<_kernel_dimension;k++)
+      H[k]=new BigInt[columns];
+    for(int k=0;k<_kernel_dimension;k++)
+      for(int j=0;j<columns;j++)
+        H[k][j]=(A.H)[k][j];
+  }
+}
+
+
+
+
+matrix::~matrix()
+{
+  for(int i=0;i<rows;i++)
+    delete[] coefficients[i];
+  delete[] coefficients;
+
+  if(_kernel_dimension>0)
+    // LLL-algorithm performed
+  {
+    for(int i=0;i<_kernel_dimension;i++)
+      delete[] H[i];
+    delete[] H;
+  }
+}
+
+
+
+
+//////////////////// object properties //////////////////////////////////////
+
+
+
+
+BOOLEAN matrix::is_nonnegative() const
+{
+  for(int i=0;i<rows;i++)
+    for(int j=0;j<columns;j++)
+      if(coefficients[i][j]<0)
+        return FALSE;
+  return TRUE;
+}
+
+
+
+int matrix::error_status() const
+{
+  if(columns<0)
+    return columns;
+  else
+    return 0;
+}
+
+
+
+int matrix::row_number() const
+{
+  return rows;
+}
+
+
+
+int matrix::column_number() const
+{
+  return columns;
+}
+
+
+
+
+////////// special routines for the IP-algorithms /////////////////////////
+
+
+
+
+int matrix::LLL_kernel_basis()
+{
+
+  // copy the column vectors of the actual matrix
+  // (They are modified by the LLL-algorithm!)
+  BigInt** b=new BigIntP[columns];
+  for(int n=0;n<columns;n++)
+    b[n]=new BigInt[rows];
+  for(int n=0;n<columns;n++)
+    for(int m=0;m<rows;m++)
+      b[n][m]=coefficients[m][n];
+
+  // compute a LLL-reduced basis of the relations of b[0],...,b[columns-1]
+  _kernel_dimension=relations(b,columns,rows,H);
+
+  // The kernel lattice basis is now stored in the member H (vectors
+  // H[0],...,H[_kernel_dimension-1]).
+
+  // delete auxiliary vectors
+  for(int n=0;n<columns;n++)
+    delete[] b[n];
+  delete[] b;
+
+  return _kernel_dimension;
+}
+
+
+
+
+int matrix::compute_nonzero_kernel_vector()
+{
+
+  if(_kernel_dimension==-2)
+    // lattice basis not yet computed
+    LLL_kernel_basis();
+
+  if(_kernel_dimension==-1)
+  {
+    cerr<<"\nWARNING: int matrix::compute_non_zero_kernel_vector(BigInt*&):"
+      "\nerror in kernel basis, cannot compute the desired vector"<<endl;
+    return 0;
+  }
+
+  if(_kernel_dimension==0)
+  {
+    cerr<<"\nWARNING: int matrix::compute_non_zero_kernel_vector(BigInt*&): "
+      "\nkernel dimension is zero"<<endl;
+    return 0;
+  }
+
+  // Now, the kernel dimension is positive.
+
+  BigInt *M=new BigInt[_kernel_dimension];
+  // M stores a number by which the algorithm decides which vector to
+  // take next.
+
+
+// STEP 1: Determine the vector with the least zero components (if it is not
+// unique, choose the smallest).
+
+  // determine number of zero components
+  for(int i=0;i<_kernel_dimension;i++)
+  {
+    M[i]=0;
+    for(int j=0;j<columns;j++)
+      if(H[i][j]==BigInt(0))
+        M[i]++;
+  }
+
+  // determine minimal number of zero components
+  BigInt min=columns;
+  // columns is an upper bound (not reached because the kernel basis cannot
+  // contain the zero vector)
+  for(int i=0;i<_kernel_dimension;i++)
+    if(M[i]<min)
+      min=M[i];
+
+  // add the square of the norm to the vectors with the least zero components
+  // and discard the others (the norm computation is why we have chosen the
+  // M[i] to be BigInts)
+  for(int i=0;i<_kernel_dimension;i++)
+    if(M[i]!=min)
+      M[i]=-1;
+    else
+      for(int j=0;j<columns;j++)
+        M[i]+=H[i][j]*H[i][j];
+  // As the lattice basis does not contain the zero vector, at least one M[i]
+  // is positive!
+
+  // determine the start vector, i.e. the one with least zero components, but
+  // smallest possible (euclidian) norm
+  int min_index=-1;
+  for(int i=0;i<_kernel_dimension;i++)
+    if(M[i]>BigInt(0))
+    {
+      if(min_index==-1)
+        min_index=i;
+      else if(M[i]<M[min_index])
+        min_index=i;
+    }
+
+  // Now, H[min_index] is the vector to be transformed into a nonnegative one.
+  // For a better overview, it is swapped with the first vector
+  // (only pointers).
+
+  if(min_index!=0)
+  {
+    BigInt* swap=H[min_index];
+    H[min_index]=H[0];
+    H[0]=swap;
+  }
+
+
+// Now construct the desired vector.
+// This is done by adding a linear combination of
+// H[1],...,H[_kernel_dimension-1] to H[0]. It is important that the final
+// result, written as a linear combination of
+// H[0],...,H[_kernel_dimension-1], has coefficient 1 or -1 at H[0]
+// (to make sure that it is together with H[1],...,H[_kernel_dimension]
+// still a  l a t t i c e   basis).
+
+  for(int current_position=1;current_position<columns;current_position++)
+    // in fact, this loop will terminate before the condition in the
+    // for-statement is satisfied...
+  {
+
+
+// STEP 2: Nonnegative vector already found?
+
+    BOOLEAN found=TRUE;
+    for(int j=0;j<columns;j++)
+      if(H[0][j]==BigInt(0))
+        found=FALSE;
+
+    if(found==TRUE)
+      // H[0] has only positive entries,
+      return 1;
+    // else there are further zero components
+
+
+// STEP 3: Can a furhter zero component be "eliminated"?
+// If this is the case, find a basis vector that can do this.
+
+    // determine number of components in each remaining vector that are zero
+    // in the vector itself as well as in the already constructed vector
+    for(int i=current_position;i<_kernel_dimension;i++)
+      M[i]=0;
+
+    int remaining_zero_components=0;
+
+    for(int j=0;j<columns;j++)
+      if(H[0][j]==BigInt(0))
+      {
+        remaining_zero_components++;
+        for(int i=current_position;i<_kernel_dimension;i++)
+          if(H[i][j]==BigInt(0))
+            M[i]++;
+      }
+
+    // determine minimal number of such components
+    min=remaining_zero_components;
+    // this is the number of zero components in H[0] and an upper bound
+    // for the M[i]
+    for(int i=current_position;i<_kernel_dimension;i++)
+      if(M[i]<min)
+        min=M[i];
+
+    if(min==(const BigInt&)remaining_zero_components)
+      // all zero components in H[0] are zero in each remaining vector
+      // => desired vector does not exist
+      return 0;
+
+    // add the square of the norm to the vectors with the least common zero
+    // components
+    // discard the others
+    for(int i=current_position;i<_kernel_dimension;i++)
+      if(M[i]!=min)
+        M[i]=-1;
+      else
+        for(int j=0;j<columns;j++)
+          M[i]+=H[i][j]*H[i][j];
+    //  Again, at least one M[i] is positive!
+
+    // determine vector to proceed with
+    // This is the vector with the least common zero components with respect
+    // to H[0], but the smallest possible norm.
+    int min_index=0;
+    for(int i=current_position;i<_kernel_dimension;i++)
+      if(M[i]>BigInt(0))
+      {
+        if(min_index==0)
+          min_index=i;
+        else if(M[i]<M[min_index])
+          min_index=i;
+      }
+
+    // Now, a multiple of H[min_index] will be added to the already constructed
+    // vector H[0].
+    // For a better handling, it is swapped with the vector at current_position
+    // (only pointers).
+
+    if(min_index!=current_position)
+    {
+      BigInt* swap=H[min_index];
+      H[min_index]=H[current_position];
+      H[current_position]=swap;
+    }
+
+
+// STEP 4: Choose a convenient multiple of H[current_position] to add to H[0].
+// The number of factors "mult" that have to be tested is bounded by the
+// number of nonzero components in H[0] (for each such components, there is at
+// most one such factor that will eliminate it in the linear combination
+// H[0] + mult*H[current_position].
+
+    found=FALSE;
+
+    for(int mult=1;found==FALSE;mult++)
+    {
+      found=TRUE;
+
+      // check if any component !=0 of H[0] becomes zero by adding
+      // mult*H[current_position]
+      for(int j=0;j<columns;j++)
+        if(H[0][j]!=BigInt(0))
+          if(H[0][j]+(const BigInt&)mult*H[current_position][j]
+            ==BigInt(0))
+            found=FALSE;
+
+      if(found==TRUE)
+        for(int j=0;j<columns;j++)
+          H[0][j]+=(const BigInt&)mult*H[current_position][j];
+      else
+        // try -mult
+      {
+
+        found=TRUE;
+
+        // check if any component !=0 of H[0] becomes zero by subtracting
+        // mult*H[current_position]
+        for(int j=0;j<columns;j++)
+          if(H[0][j]!=BigInt(0))
+            if(H[0][j]-(const BigInt&)mult*H[current_position][j]
+              ==BigInt(0))
+              found=FALSE;
+
+        if(found==TRUE)
+          for(int j=0;j<columns;j++)
+            H[0][j]-=(const BigInt&)mult*H[current_position][j];
+      }
+    }
+  }
+
+// When reaching this line, an error must have occurred.
+  cerr<<"FATAL ERROR in int matrix::compute_nonnegative_vector()"<<endl;
+  abort();
+}
+
+int matrix::compute_flip_variables(int*& F)
+{
+  // first compute nonzero vector
+  int okay=compute_nonzero_kernel_vector();
+
+  if(!okay)
+  {
+    cout<<"\nWARNING: int matrix::compute_flip_variables(int*&):\n"
+      "kernel of the matrix contains no vector with nonzero components,\n"
+      "no flip variables computed"<<endl;
+    return -1;
+  }
+
+  // compute variables to flip; these might either be those corresponding
+  // to the positive components of the kernel vector without zero components
+  // or those corresponding to the negative ones
+
+  int r=0;
+  // number of flip variables
+
+  for(int j=0;j<columns;j++)
+    if(H[0][j]<BigInt(0))
+      r++;
+  // remember that all components of H[0] are !=0
+
+  if(r==0)
+    // no flip variables
+    return 0;
+
+  if(2*r>columns)
+    // more negative than positive components in H[0]
+    // all variables corresponding to positive components will be flipped
+  {
+    r=columns-r;
+    F=new int[r];
+    memset(F,0,r*sizeof(int));
+    int counter=0;
+    for(int j=0;j<columns;j++)
+      if(H[0][j]> BigInt(0))
+      {
+        F[counter]=j;
+        counter++;
+      }
+  }
+  else
+    // more (or as many) positive than negative components in v
+    // all variables corresponding to negative components will be flipped
+  {
+    F=new int[r];
+    memset(F,0,r*sizeof(int));
+    int counter=0;
+    for(int j=0;j<columns;j++)
+      if(H[0][j]< BigInt(0))
+      {
+        F[counter]=j;
+        counter++;
+      }
+  }
+
+  return r;
+}
+
+
+
+
+int matrix::hosten_shapiro(int*& sat_var)
+{
+
+  if(_kernel_dimension==-2)
+    // lattice basis not yet computed
+    LLL_kernel_basis();
+
+  if(_kernel_dimension==-1)
+  {
+    cerr<<"\nWARNING: int matrix::hosten_shapiro(int*&):\n"
+      "error in kernel basis, cannot compute the saturation variables"<<endl;
+    return 0;
+  }
+
+  if(_kernel_dimension==0)
+    // the toric ideal corresponding to the kernel lattice is the zero ideal,
+    // no saturation variables necessary
+    return 0;
+
+  // Now, the kernel dimension is positive.
+
+  if(columns==1)
+    // matrix consists of one zero column, kernel is generated by the vector
+    // (1) corresponding to the toric ideal <x-1> which is already staurated
+    return 0;
+
+  int number_of_sat_var=0;
+  sat_var=new int[columns/2];
+  memset(sat_var,0,sizeof(int)*(columns/2));
+
+  BOOLEAN* ideal_saturated_by_var=new BOOLEAN[columns];
+  // auxiliary array used to remember by which variables the ideal has still to
+  // be saturated
+  for(int j=0;j<columns;j++)
+    ideal_saturated_by_var[j]=FALSE;
+
+  for(int k=0;k<_kernel_dimension;k++)
+  {
+    // determine number of positive and negative components in H[k]
+    // corresponding to variables by which the ideal has still to be saturated
+    int pos_sat_var=0;
+    int neg_sat_var=0;
+
+    for(int j=0;j<columns;j++)
+    {
+      if(ideal_saturated_by_var[j]==FALSE)
+      {
+        if(H[k][j]> BigInt(0))
+          pos_sat_var++;
+        else
+          if(H[k][j]< BigInt(0))
+            neg_sat_var++;
+      }
+    }
+
+
+    // now add the smaller set to the saturation variables
+    if(pos_sat_var<=neg_sat_var)
+    {
+      for(int j=0;j<columns;j++)
+        if(ideal_saturated_by_var[j]==FALSE)
+        {
+          if(H[k][j]> BigInt(0))
+            // ideal has to be saturated by the variables corresponding
+            // to positive components
+          {
+            sat_var[number_of_sat_var]=j;
+            ideal_saturated_by_var[j]=TRUE;
+            number_of_sat_var++;
+          }
+          else if(H[k][j]< BigInt(0))
+              // then the ideal is automatically saturated by the variables
+              // corresponding to negative components
+              ideal_saturated_by_var[j]=TRUE;
+        }
+    }
+    else
+    {
+      for(int j=0;j<columns;j++)
+        if(ideal_saturated_by_var[j]==FALSE)
+        {
+          if(H[k][j]< BigInt(0))
+            // ideal has to be saturated by the variables corresponding
+            // to negative components
+          {
+            sat_var[number_of_sat_var]=j;
+            ideal_saturated_by_var[j]=TRUE;
+            number_of_sat_var++;
+          }
+          else if(H[k][j]> BigInt(0))
+              // then the ideal is automatically saturated by the variables
+              // corresponding to positive components
+              ideal_saturated_by_var[j]=TRUE;
+        }
+    }
+  }
+
+  // clean up memory
+  delete[] ideal_saturated_by_var;
+
+  return number_of_sat_var;
+}
+
+
+
+
+//////////////////// output ///////////////////////////////////////////////
+
+
+
+
+void matrix::print() const
+{
+  printf("\n%3d x %3d\n",rows,columns);
+
+  for(int i=0;i<rows;i++)
+  {
+    for(int j=0;j<columns;j++)
+      printf("%6d",coefficients[i][j]);
+    printf("\n");
+  }
+}
+
+
+void matrix::print(FILE *output) const
+{
+  fprintf(output,"\n%3d x %3d\n",rows,columns);
+
+  for(int i=0;i<rows;i++)
+  {
+    for(int j=0;j<columns;j++)
+      fprintf(output,"%6d",coefficients[i][j]);
+    fprintf(output,"\n");
+  }
+}
+
+
+void matrix::print(ofstream& output) const
+{
+  output<<endl<<setw(3)<<rows<<" x "<<setw(3)<<columns<<endl;
+
+  for(int i=0;i<rows;i++)
+  {
+    for(int j=0;j<columns;j++)
+      output<<setw(6)<<coefficients[i][j];
+    output<<endl;
+  }
+}
+#endif  // matrix.cc
diff --git a/IntegerProgramming/matrix.h b/IntegerProgramming/matrix.h
new file mode 100644
index 0000000..d0a8327
--- /dev/null
+++ b/IntegerProgramming/matrix.h
@@ -0,0 +1,169 @@
+// matrix.h
+
+
+// This class is designed to handle the input of the integer programming
+// problem. It offers facilities to convert a two-dimensional integer array
+// into a matrix and to read a matrix from an input file.
+// Furhermore, some special routines needed by the IP-algorithms are
+// implemented:
+// - the computation of a lattice basis for the integer kernel via the LLL
+//   algorithm;
+// - the computation of a kernel vector which has no zero components (if
+//   such a vector exists) and is a basis vector for the kernel lattice;
+// - the procedure of Hosten and Shapiro computing a small set of saturation
+//   variables for the toric ideal given by the matrix kernel.
+
+
+
+#ifndef MATRIX_H
+#define MATRIX_H
+
+
+
+#include "LLL.h"
+
+
+
+class matrix
+{
+
+
+
+private:
+
+  int rows;
+
+  int columns;
+  // Also used as error flag (values <0):
+  // -1 indicates a "semantic" error (which occurs e.g. if some constructor
+  //    argument is out of range)
+  // -2 indicates an error occured when reading from a file
+
+  Integer **coefficients;
+  // the matrix entries
+
+  BigInt **H;
+  // This array is used to store the LLL-reduced lattice basis of the kernel.
+  // Memory allocation is done in the LLL-routines, so the array is only
+  // allocated if such a basis is really computed.
+
+  int _kernel_dimension;
+  // the number of vectors stored in H (the size of these vectors is columns)
+  // If _kernel_dimension==-2, no kernel basis has been computed yet.
+  // If _kernel_dimension==-1, an error has occured during the kernel basis
+  // computation.
+
+
+
+public:
+
+
+
+// constructors and destructor
+
+  matrix(const int& row_number, const int& column_number);
+  // Creates a zero matrix of the specified size.
+
+  matrix(const int& row_number, const int& column_number,
+         Integer** entries);
+  // Builds a matrix from its coefficient array.
+
+  matrix(ifstream& input);
+  // Reads a matrix from the given ifstream.
+  // The input stream must have the following format:
+  //
+  //    m=number of rows
+  //    n=number of columns
+  //    coefficients 0..n-1 of row 1
+  //    coefficients 0..n-1 of row 2
+  //            ...
+  //    coefficients 0..n-1 of row m
+
+  matrix(const int& m, const int& n, ifstream& input);
+  // Reads a (m x n)-matrix from the given ifstream.
+  // The input stream must have the following format:
+  //
+  //    coefficients 0..n-1 of row 1;
+  //    coefficients 0..n-1 of row 2;
+  //            ...
+  //    coefficients 0..n-1 of row m.
+
+  matrix(const matrix&);
+  // copy-constructor (also copies H)
+
+  ~matrix();
+  // destructor
+
+
+
+// object properties
+
+  BOOLEAN is_nonnegative() const;
+  // Returns TRUE, if all entries of the matrix are >=0, else FALSE.
+
+  int error_status() const;
+  // Returns columns iff columns<0 (this is the "error flag"), else 0.
+
+  int row_number() const;
+  // Retuns the row number.
+
+  int column_number() const;
+  // Returns the column number.
+
+  int kernel_dimension() const;
+  // Returns the kernel dimension.
+
+
+
+// special routines for the IP-algorithms
+
+  int LLL_kernel_basis();
+  // Computes a LLL-reduced integer basis of the matrix kernel and returns
+  // the kernel dimension (-1 if an error has occurred).
+  // This dimension is also stored in the member kernel_dimension.
+
+  int compute_nonzero_kernel_vector();
+  // Transforms the kernel lattice basis stored in H so that it contains
+  // a vector whose components are all !=0;
+  // returns 0 if no such vector exists, else 1.
+  // If no such basis has been computed before, this is done now.
+
+  int compute_flip_variables(int*&);
+  // Computes a set of flip variables for the algorithm of DiBiase and
+  // Urbanke from a kernel vector with no zero components.
+  // Returns the size of that set if such a kernel vector exists, else -1.
+  // If necessary, such a vector is computed.
+  // The computed set is copied to the argument pointer (memory allocation
+  // is done in the routine) to be accessible for the calling function.
+
+  int hosten_shapiro(int*& sat_var);
+  // Computes a set of saturation variables for the ideal defined by the
+  // kernel lattice and returns the size of that set.
+  // If no lattice basis has been computed before, this is done now.
+  // The computed set is stored in the argument pointer (memory allocation
+  // is done in the routine) to be accessible for the calling function.
+  // This routine implements the most simple strategy for computing this set:
+  // The kernel vectors are examined in their actual. A "greedy" strategy
+  // choosing "clever" kernel vectors to begin with could give better results
+  // in many cases, but this is not guaranteed...
+  // (And what is a clever choice?)
+
+// output
+
+  void print() const;
+  // Writes the matrix to the standard output medium.
+
+  void print(FILE*) const;
+  // Writes the matrix to the referenced file which has to be opened
+  // for writing before.
+
+  void print(ofstream&) const;
+  // Writes the matrix to the given ofstream.
+
+  friend class ideal;
+  // Our toric ideals are all constructed from matrices, and the matrix class
+  // is designed only for the needs of these constructors. So it would be
+  // unnecessary overhead to hide the matrix members from these constructors.
+
+};
+#endif
diff --git a/IntegerProgramming/solve_IP.cc b/IntegerProgramming/solve_IP.cc
new file mode 100644
index 0000000..4deaf13
--- /dev/null
+++ b/IntegerProgramming/solve_IP.cc
@@ -0,0 +1,299 @@
+// solve_IP.cc
+
+// This file provides the interface to call the implemented IP-algorithms.
+// This includes a short help text on the choice of algorithms and their
+// arguments and the required formats of the input file.
+
+#ifndef SOLVE_IP_CC
+#define SOLVE_IP_CC
+
+#include "IP_algorithms.h"
+
+int main(int argc, char *argv[])
+{
+
+  // initialize arguments for the IP-algorithms (Buchberger)
+  // with default settings
+  BOOLEAN verbose=FALSE;
+  int version=1;
+  int S_pair_criteria=11;
+  double interreduction_percentage=12.0;
+
+///////////////////////// parse options /////////////////////////////////////
+
+  int alg_option=0;
+  // no algorithm specified yet
+
+  if(argc>=3)
+    // argc has to be at least 3 (except when help is required, see below):
+    // program name, (MATRIX or) GROEBNER file, PROBLEM file
+  {
+
+    for(int i=1;i<argc-2;i++)
+      // these are the input options
+    {
+
+      if(!strcmp(argv[i],"-v") || !strcmp(argv[i],"--verbose"))
+      {
+        verbose=TRUE;
+        continue;
+        // read next argument
+      }
+
+      if(!strcmp(argv[i],"-V") || !strcmp(argv[i],"-version"))
+      {
+        // check if next argument is a valid version number
+        i++;
+
+        if(!strcmp(argv[i],"1"))
+        {
+          version=1;
+          continue;
+        }
+        if(!strcmp(argv[i],"1a"))
+        {
+          version=0;
+          continue;
+        }
+        if(!strcmp(argv[i],"2"))
+        {
+          version=2;
+          continue;
+        }
+        if(!strcmp(argv[i],"3"))
+        {
+          version=3;
+          continue;
+        }
+
+        // When reaching this line, the version argument was invalid.
+        cerr<<"ERROR: invalid version argument\n"
+            <<"Type `solve_IP --help' for help on options.\n";
+        return 1;
+      }
+
+      if(!strcmp(argv[i],"-S"))
+      {
+        // initialize argument to the use of no criteria
+        S_pair_criteria=0;
+
+        do
+        {
+          // Check what S-pair criterion the next argument indicates.
+          // If none: The algorithm is called without S-pair criteria.
+          i++;
+
+          if(i>=argc-2)
+            // file arguments reached
+            break;
+
+          if(!strcmp(argv[i],"RP"))
+          {
+            S_pair_criteria|=1;
+            continue;
+          }
+          if(!strcmp(argv[i],"M"))
+          {
+            S_pair_criteria|=2;
+            continue;
+          }
+          if(!strcmp(argv[i],"F"))
+          {
+            S_pair_criteria|=4;
+            continue;
+          }
+          if(!strcmp(argv[i],"B"))
+          {
+            S_pair_criteria|=8;
+            continue;
+          }
+          if(!strcmp(argv[i],"2"))
+          {
+            S_pair_criteria|=16;
+            continue;
+          }
+
+          // option does not belong to an S-pair criterion
+          break;
+
+        }
+        while(1);
+
+        i--;        // reset counter so that the outer loop
+        continue;   // continues with the just considered argument
+      }
+
+      if(!strcmp(argv[i],"-p"))
+      {
+        // read interreduction percentage
+        i++;
+
+        char** rest;
+        interreduction_percentage=strtod(argv[i],rest);
+        // The function strtod converts a string into a double. As the
+        // specification is not correct, it may cause trouble...
+        // For example, if the argument can be read as a float, the value
+        // of rest should be NULL. This is not the case. Therefore, we can
+        // only check by the following string comparison if a float has been
+        // built. An argument as 15xy is thereby considered as valid
+        // (with interreduction_percentage==15.0).
+
+        if(!(strcmp(argv[i],*rest)))
+          // argument was no float
+        {
+          cerr<<"ERROR: invalid argument for interreduction percentage\n"
+              <<"Type `solve_IP --help' for help on options.\n";
+          return 1;
+        }
+
+        continue;
+      }
+
+      if(!strcmp(argv[i],"-alg") || !strcmp(argv[i],"--algorithm"))
+      {
+        // check if next argument is a valid algorithm specification
+        i++;
+
+        if(!strcmp(argv[i],"ct") || !strcmp(argv[i],"pct") ||
+           !strcmp(argv[i],"ect") || !strcmp(argv[i],"pt") ||
+           !strcmp(argv[i],"hs") || !strcmp(argv[i],"du") ||
+           !strcmp(argv[i],"blr"))
+        {
+          alg_option=i;
+          continue;
+        }
+
+        // When reaching this line, the algorithm argument was invalid.
+        cerr<<"ERROR: unkwon algorithm\n"
+            <<"Type `solve_IP --help' for help on options.\n";
+        return 1;
+      }
+
+      // When reaching this line, the argument is no legal option.
+      cerr<<"ERROR: invalid option "<<argv[i]
+          <<"\nType `solve_IP --help' for help on options.\n";
+      return 1;
+    }
+
+
+///////////////////// call IP-algorithms ////////////////////////////////////
+
+    // open first input stream (MATRIX or GROEBNER file)
+    ifstream first_input(argv[argc-2]);
+
+    if(!first_input)
+    {
+      cerr<<"ERROR: cannot open first input file, possibly not found\n";
+      return 1;
+    }
+
+    // open second input stream (PROBLEM file)
+    ifstream second_input(argv[argc-1]);
+
+    if(!second_input)
+    {
+      cerr<<"ERROR: cannot open second input file, possibly not found\n";
+      return 1;
+    }
+
+    // check if the first input file is a MATRIX file; in that case,
+    // we have to compute a Groebner basis first
+    char format_string[128];
+    first_input>>format_string;
+
+    if(!strcmp(format_string,"MATRIX"))
+    {
+      if(alg_option==0)
+      {
+        cerr<<"ERROR: first input file is a MATRIX file;\n"
+          "algorithm has to be specified\n";
+        return 1;
+      }
+
+      // perform specified algorithm to compute a Groebner basis of the
+      // toric ideal defined by the input matrix
+
+      int success;
+      if(!strcmp(argv[alg_option],"ct"))
+        success=Conti_Traverso(argv[argc-2], version, S_pair_criteria,
+                               interreduction_percentage, verbose);
+      if(!strcmp(argv[alg_option],"pct"))
+        success=Positive_Conti_Traverso(argv[argc-2], version,
+                                        S_pair_criteria,
+                                        interreduction_percentage, verbose);
+      if(!strcmp(argv[alg_option],"ect"))
+        success=Elim_Conti_Traverso(argv[argc-2], version, S_pair_criteria,
+                                    interreduction_percentage, verbose);
+      if(!strcmp(argv[alg_option],"pt"))
+        success=Pottier(argv[argc-2], version, S_pair_criteria,
+                        interreduction_percentage, verbose);
+      if(!strcmp(argv[alg_option],"hs"))
+        success=Hosten_Sturmfels(argv[argc-2], version, S_pair_criteria,
+                                 interreduction_percentage, verbose);
+      if(!strcmp(argv[alg_option],"du"))
+        success=DiBiase_Urbanke(argv[argc-2], version, S_pair_criteria,
+                                interreduction_percentage, verbose);
+      if(!strcmp(argv[alg_option],"blr"))
+        success=Bigatti_LaScala_Robbiano(argv[argc-2], version,
+                                         S_pair_criteria,
+                                         interreduction_percentage, verbose);
+      if(!success)
+      {
+        cerr<<"ERROR: could not perform required IP-algorithm,\n"
+          "no GROEBNER file created\n";
+        return 1;
+      }
+
+      // Groebner basis successfully computed
+      // now solve problems
+
+      char* GROEBNER=new char[128];
+      memset(GROEBNER,0,128);
+      int i=0;
+      while(argv[argc-2][i]!='\0' && argv[argc-2][i]!='.' && argv[argc-2][i]>' ')
+      {
+        GROEBNER[i]=argv[argc-2][i];
+        i++;
+      }
+      strcat(GROEBNER,".GB.");
+      strcat(GROEBNER,argv[alg_option]);
+
+      success=solve(argv[argc-1],GROEBNER);
+      delete[] GROEBNER;
+      return(!success);
+      // ! because 0 indicates in general a regular program termination
+    }
+
+    else
+      // first input file is no MATRIX file, GROEBNER file assumed
+    {
+      if(argc>3)
+        // input options are ignored when program is called with a
+        // GROEBNER file
+        cerr<<"WARNING: program called with a GROEBNER file,\n"
+          "specified options will not have any effect\n";
+          return(!solve(argv[argc-1],argv[argc-2]));
+    }
+  }
+
+
+/////////////////////// provide help text ///////////////////////////////////
+
+  // handle the case of "missing" arguments
+
+  if((argc==2) && !strcmp(argv[1],"--help"))
+    // help required
+  {
+    system("less solve_IP.hlp");
+    return 0;
+  }
+
+  else
+    // invalid arguments
+    cerr<<"USAGE: solve_IP [options] toric_file problem_file\n"
+        <<"Type `solve_IP --help' for help on options.\n";
+
+  return 1;
+
+}
+#endif  // SOLVE_IP_CC
diff --git a/IntegerProgramming/solve_IP.hlp b/IntegerProgramming/solve_IP.hlp
new file mode 100644
index 0000000..e6fea38
--- /dev/null
+++ b/IntegerProgramming/solve_IP.hlp
@@ -0,0 +1,261 @@
+USAGE: solve_IP [options] toric_file problem_file
+
+
+
+DESCRIPTION:
+
+solve_IP is a program for solving integer programming problems with
+the Buchberger algorithm:
+
+Let A an integral (mxn)-matrix, b a vector with m integral
+coefficients and c a vector with n nonnegative real coefficients. The
+solution of the IP-problem
+
+    minimize{ cx | Ax=b, all components of x are nonnegative integers }
+
+proceeds in two steps:
+
+1. We compute the toric ideal of A and its Groebner basis with respect
+   to a term ordering refining the cost function c.
+
+2. We reduce the right hand vector b or an initial solution of the
+   problem modulo this ideal.
+
+For these purposes, we can use seven different algorithms:
+The algorithm of Conti/Traverso (ct) can compute an optimal solution
+of the IP-problem directly from the right hand vector b. The same is
+true for its "positive" variant (pct) which can only be applied if A
+and b have nonnegative entries, but should be faster in that case.
+All other algorithms need initial solutions of the IP-problem. Except
+from the elimination version of the Conti-Traverso algorithm (ect),
+they should be more efficient than the algorithm mentionned before.
+These are the algorithms of Pottier (pt), Bigatti/La Scala/Robbiano
+(blr), Hosten/Sturmfels (hs) and Di Biase/Urbanke (du). The last two
+seem to be the fastest in the actual implementation.
+
+
+
+FILE FORMAT:
+
+The first input file may be a MATRIX or a GROEBNER file; these two
+types are called "toric files". The second input file has to be a
+PROBLEM file.
+
+If the PROBLEM file contains a positive number of problems ,i.e. right
+hand vectors or initial solutions, solve_IP appends its solutions to a
+SOLUTION file named like the first input file with extensions replaced
+by
+
+	.sol.<alg>
+
+where sol stands for solution and <alg> is the abbreviation of the
+used algorithm as above. When called with a MATRIX file, solve_IP
+produces a GROEBNER file named like the MATRIX file with extensions
+replaced by
+
+	.GB.<alg>
+
+where GB stands for GROEBNER.
+
+A MATRIX file should look as follows:
+
+
+  MATRIX
+
+  columns:
+  <number of columns>
+
+  cost vector:
+  <coefficients of the cost vector>
+
+  rows:
+  <number of rows>
+
+  matrix:
+  <matrix coefficients>
+
+  positive row space vector:
+  <coefficients of row space vector>
+
+
+The last two lines are only needed when solve_IP is called with the
+algorithms of Hosten/Sturmfels or Bigatti/La Scala/Robbiano, i.e. the
+options
+
+	-alg hs
+or
+	-alg blr
+
+The other algorithms ignore these lines.
+
+Example:
+
+
+  MATRIX
+
+  columns:
+  3
+
+  cost vector:
+  1 1 1
+
+  rows:
+  2
+
+  matrix:
+  1 2 3
+  4 5 6
+
+  positive row space vector:
+  1 2 3
+
+
+A GROEBNER file looks as follows:
+
+
+  GROEBNER
+
+  computed with algorithm:
+  <algorithm name abbreviation>       (* abbreviations as above *)
+  from file(s):                       (* the following four lines are
+  <name of respective MATRIX file>       optional *)
+  computation time:
+  <computation time in seconds>
+
+  term ordering:
+  elimination block
+  <number of elimination variables>
+  <LEX / DEG_LEX                      (* only if number of elimination
+  / DEG_REV_LEX>                         variables >0 *)
+  weighted block
+  <number of weighted variables>
+  <W_LEX / W_REV_LEX                  (* number of weighted variables
+  / W_DEG_LEX / W_DEG_REV_LEX>           should always be >0 *)
+  <weight_vector>
+
+  size:
+  <number of elements>
+
+  Groebner basis:
+  <basis elements>
+
+  <settings for the Buchberger
+   algorithm and compiler settings>  (* optional *)
+
+
+The Groebner basis consists always of binomials of the form x^a - x^b
+where x^a and x^b are relatively prime. Such a binomial can be
+represented by the vector a-b. The basis elements in the GROEBNER file
+are given by the coefficients of this vector representation.
+The settings for Buchberger�s algorithm and the compiler flags are
+produced when the GROEBNER file is generated by a call of solve_IP
+with the verbose output option
+
+	-v, --verbose
+
+Example (not belonging to the example above):
+
+
+  GROEBNER
+
+  computed with algorithm:
+  du
+
+  term ordering:
+  elimination block:
+  0
+  weighted block:
+  3
+  W_LEX
+  1 2 3
+
+  size:
+  1
+
+  Groebner basis:
+  2 3 -2			    (*  x^2 * y^3 - z^2  *)
+
+
+A PROBLEM file should look as follows:
+
+
+  PROBLEM
+
+  vector size:
+  <vector dimension>
+
+  number of instances:
+  <number of vectors>
+
+  right-hand or initial solution vectors:
+  <vector coefficients>
+
+
+A SOLUTION file looks as follows:
+
+  SOLUTION
+
+  computed with algorithm:
+  <algorithm name abbreviation>
+  from file:                                  (* the GROEBNER file *)
+  <file name>
+
+  <right hand/initial solution> vector:
+  <vector as in the problem file>
+  solvable:                                   (* only if right-hand
+  <YES/NO>                                       vector is given *)
+  optimal solution:                           (* only in the case of
+  <optimal solution vector>		         existence *)
+  computation time:                           (* only for reduction *)
+  <reduction time in seconds>
+
+  ...                                         (* further vectors,
+                                                 same format *)
+
+
+
+OPTIONS:
+
+ -alg       <alg>,
+--algorithm <alg>         algorithm to use for solving the given IP
+                          instances; <alg> may be
+             ct           for Conti/Traverso,
+             pct          for the positive Conti/Traverso,
+             ect          for Conti/Traverso with elimination,
+             pt           for Pottier,
+             hs           for Hosten/Sturmfels,
+             du           for Di Biase/Urbanke,
+             blr          for Bigatti-LaScal-Robbiano.
+
+ -p         <number>      percentage of new generators to cause an
+                          autoreduction during Buchberger�s algorithm;
+                          <number> may be an arbitrary float, a
+                          negative value allows no intermediate
+                          autoreductions
+			  default is
+                          -p 12.0
+
+ -S [RP] [M] [B] [M] [2]  criteria to use in Buchberger�s algorithm
+                          for discarding unneccessary S-pairs
+             RP           relatively prime leading terms
+             M            Gebauer-Moeller criterion M
+             F            Gebauer-Moeller criterion F
+             B            Gebauer-Moeller criterion B
+             2            Buchberger�s second criterion
+			  default is
+                          -S RP M B
+
+ -v,
+--verbose                 verbose output mode; writes the settings for
+                          Buchberger�s algorithm and the compiler
+                          flags into the output GROEBNER file
+
+-V <number>,
+--version <number>        version of Buchberger�s algorithm to use;
+                          <number> may be 1, 1a, 2 or 3
+			  default is
+                          -V 1
+
+
+When called with a GROEBNER file, these options do not affect
+computation and are ignored by solve_IP.
\ No newline at end of file
diff --git a/IntegerProgramming/term_ordering.cc b/IntegerProgramming/term_ordering.cc
new file mode 100644
index 0000000..7090274
--- /dev/null
+++ b/IntegerProgramming/term_ordering.cc
@@ -0,0 +1,1457 @@
+// term_ordering.cc
+
+// implementation of class term ordering
+
+#ifndef TERM_ORDERING_CC
+#define TERM_ORDERING_CC
+
+#include "binomial__term_ordering.h"
+
+/////////////// constructors and destructor ///////////////////////////////////
+
+term_ordering::term_ordering(const BOOLEAN& _homogeneous)
+    :homogeneous(_homogeneous)
+{
+  weight_vector=NULL;
+  weighted_block_size=0;
+  elimination_block_size=0;
+}
+
+
+
+
+term_ordering::term_ordering(const short& number_of_weighted_variables,
+                             const float* weights,
+                             const short& _weighted_ordering,
+                             const BOOLEAN& _homogeneous)
+    :weighted_block_size(number_of_weighted_variables),
+     homogeneous(_homogeneous)
+{
+  if((_weighted_ordering<4) || (_weighted_ordering>7))
+    // unknown ordering refining the weight, set "error flag"
+    weighted_block_size=-1;
+  else
+    weighted_ordering=_weighted_ordering;
+
+  if(weighted_block_size<0)
+    // argument out of range, set "error flag"
+    weighted_block_size=-1;
+
+  if(weighted_block_size>0)
+  {
+    weight_vector=new float[weighted_block_size];
+
+    BOOLEAN negative_weight=FALSE;
+    BOOLEAN zero_weight=FALSE;
+    // for checking the input
+
+    for(short i=0;i<weighted_block_size;i++)
+    {
+      weight_vector[i]=weights[i];
+      // initialize weight vector with weights
+
+      if(weight_vector[i]<0)
+        negative_weight=TRUE;
+      if(weight_vector[i]==0)
+        zero_weight=TRUE;
+    }
+
+    if(negative_weight==TRUE)
+      cerr<<"\nWARNING: term_ordering::term_ordering(const short&, "
+        "const float*, const short&):\nWeight vector with negative components"
+        " does not define a well ordering"<<endl;
+
+    if((weighted_ordering==W_REV_LEX) && (zero_weight==TRUE))
+      cerr<<"\nWARNING: term_ordering::term_ordering(const short&, "
+        "const float*, const short&):\nZero weights refined by a reverse "
+        "lexicographical ordering do not define a well ordering"<<endl;
+
+  }
+  else
+    if(weighted_block_size<0)
+      cerr<<"\nWARNING:term_ordering::term_ordering(const short&, "
+        "const float*, const short&):\nBad input in term ordering "
+        "constructor"<<endl;
+
+  elimination_block_size=0;
+
+}
+
+
+
+
+term_ordering::term_ordering(const short& number_of_weighted_variables,
+                             const float* weights,
+                             const short& _weighted_ordering,
+                             const short& number_of_elimination_variables,
+                             const short& _elimination_ordering,
+                             const BOOLEAN& _homogeneous)
+    :weighted_block_size(number_of_weighted_variables),
+     elimination_block_size(number_of_elimination_variables),
+     homogeneous(_homogeneous)
+{
+  if((_weighted_ordering<4) || (_weighted_ordering>7))
+    // unknown ordering refining the weight, set "error flag"
+    weighted_block_size=-1;
+  else
+    weighted_ordering=_weighted_ordering;
+
+  if((_elimination_ordering<1) || (_elimination_ordering>3))
+    // unknown ordering on the elimination variables, set "error flag"
+    weighted_block_size=-1;
+  else
+    elimination_ordering=_elimination_ordering;
+
+  if((weighted_block_size<0)||(elimination_block_size<0))
+    // argument out of range, set "error flag"
+    weighted_block_size=-1;
+
+  if(weighted_block_size>0)
+  {
+    weight_vector=new float[weighted_block_size];
+
+    BOOLEAN negative_weight=FALSE;
+    BOOLEAN zero_weight=FALSE;
+    // for checking the input
+
+    for(short i=0;i<weighted_block_size;i++)
+    {
+      weight_vector[i]=weights[i];
+      // initialize weight vector with weights
+
+      if(weight_vector[i]<0)
+        negative_weight=TRUE;
+      if(weight_vector[i]==0)
+        zero_weight=TRUE;
+    }
+
+    if(negative_weight==TRUE)
+      cerr<<"\nWARNING:term_ordering::term_ordering(const short&, "
+        "const float*, const short&, const short&, const short&):\n"
+        "Weight vector with negative components does not define "
+        "a well ordering"<<endl;
+
+    if((weighted_ordering==W_REV_LEX) && (zero_weight==TRUE))
+      cerr<<"\nWARNING:term_ordering::term_ordering(const short&, "
+        "const float*, const short&, const short&, const short&):\n"
+        "Zero weights refined by a reverse lexicographical "
+        "ordering do not define a well ordering"<<endl;
+
+  }
+  else
+    if(weighted_block_size<0)
+      cerr<<"\nWARNING:term_ordering::term_ordering(const short&, "
+        "const float*, const short&, const short&, const short&):\n"
+        "Bad input in term ordering constructor"<<endl;
+}
+
+
+
+
+term_ordering::term_ordering(ifstream& input, const short& _weighted_ordering,
+                             const BOOLEAN& _homogeneous)
+    :homogeneous(_homogeneous)
+{
+
+  if((_weighted_ordering<4) || (_weighted_ordering>7))
+    // unknown ordering refining the weight, set "error flag"
+    weighted_block_size=-1;
+  else
+    weighted_ordering=_weighted_ordering;
+
+
+  input>>weighted_block_size;
+  if(!input)
+    // input failure, set "error flag"
+    weighted_block_size=-2;
+  if(weighted_block_size<0)
+    // input out of range, set error flag
+    weighted_block_size=-1;
+
+  if(weighted_block_size>0)
+  {
+    weight_vector=new float[weighted_block_size];
+
+    BOOLEAN negative_weight=FALSE;
+    BOOLEAN zero_weight=FALSE;
+    // for checking the input
+
+    for(short i=0;i<weighted_block_size;i++)
+    {
+      input>>weight_vector[i];
+
+      if(!input)
+      // input failure, set "error flag"
+      {
+        weighted_block_size=-2;
+        cerr<<"\nWARNING: term_ordering::term_ordering(ifstream&, const "
+          "short&):\nInput failed reading term ordering from ofstream"<<endl;
+        break;
+      }
+
+      if(weight_vector[i]<0)
+        negative_weight=TRUE;
+      if(weight_vector[i]==0)
+        zero_weight=TRUE;
+    }
+
+    if(negative_weight==TRUE)
+      cerr<<"\nWARNING: term_ordering::term_ordering(ifstream&, const short&)"
+        ":\nWeight vector with negative components does not define "
+        "a well ordering"<<endl;
+
+    if((weighted_ordering==W_REV_LEX) && (zero_weight==TRUE))
+      cerr<<"\nWARNING: term_ordering::term_ordering(ifstream&, const short&)"
+        ":\nZero weights refined by a reverse lexicographical "
+        "ordering do not define a well ordering"<<endl;
+  }
+  else
+    if(weighted_block_size<0)
+      cerr<<"\nWARNING: term_ordering::term_ordering(ifstream&, const short&)"
+        ":\nBuilding a term ordering from a corrupt one"<<endl;
+
+  elimination_block_size=0;
+}
+
+
+
+
+term_ordering::term_ordering(const short& n, ifstream& input,
+                             const short& _weighted_ordering,
+                             const BOOLEAN& _homogeneous)
+    :homogeneous(_homogeneous)
+{
+  if((_weighted_ordering<4) || (_weighted_ordering>7))
+    // unknown ordering refining the weight, set "error flag"
+    weighted_block_size=-1;
+  else
+    weighted_ordering=_weighted_ordering;
+
+  if(n<0)
+    // input out of range, set error flag
+    weighted_block_size=-1;
+  else
+    weighted_block_size=n;
+
+  if(weighted_block_size>0)
+  {
+    weight_vector=new float[weighted_block_size];
+
+    BOOLEAN negative_weight=FALSE;
+    BOOLEAN zero_weight=FALSE;
+    // for checking the input
+
+    for(short i=0;i<weighted_block_size;i++)
+    {
+      input>>weight_vector[i];
+
+      if(!input)
+      // input failure, set "error flag"
+      {
+        weighted_block_size=-2;
+        cerr<<"\nWARNING: term_ordering::term_ordering(const short&, "
+          "ifstream&, const short&):\nInput failed reading term ordering "
+          "from ofstream"<<endl;
+        break;
+      }
+
+      if(weight_vector[i]<0)
+      {
+        cout << "neg found at i="<<i<<":" <<weight_vector[i] <<"\n";
+        negative_weight=TRUE;
+      }
+      if(weight_vector[i]==0)
+        zero_weight=TRUE;
+    }
+
+    if(negative_weight==TRUE)
+      cerr<<"\nWARNING: term_ordering::term_ordering(const short&, ifstream&, "
+        "const short&):\nWeight vector with negative components does not "
+        "define a well ordering"<<endl;
+
+    if((weighted_ordering==W_REV_LEX) && (zero_weight==TRUE))
+      cerr<<"\nWARNING: term_ordering::term_ordering(const short&, ifstream&, "
+        "const short&):\nZero weights refined by a reverse lexicographical "
+        "ordering do not define a well ordering"<<endl;
+  }
+  else
+    if(weighted_block_size<0)
+      cerr<<"\nWARNING: term_ordering::term_ordering(const short&, ifstream&, "
+        "const short&):\n Building a term ordering from a corrupt one"<<endl;
+
+  elimination_block_size=0;
+}
+
+
+
+
+term_ordering::term_ordering(const term_ordering& w)
+    :weighted_block_size(w.weighted_block_size),
+     weighted_ordering(w.weighted_ordering),
+     elimination_block_size(w.elimination_block_size),
+     elimination_ordering(w.elimination_ordering),
+     homogeneous(w.homogeneous)
+{
+  if(weighted_block_size>0)
+  {
+    weight_vector=new float[weighted_block_size];
+    for(short i=0;i<weighted_block_size;i++)
+      weight_vector[i]=w.weight_vector[i];
+  }
+  else
+    if(weighted_block_size<0)
+      cerr<<"\nWARNING: term_ordering::term_ordering(const term_ordering&):\n"
+        "Building a term ordering from a corrupt one"<<endl;
+
+}
+
+
+
+
+term_ordering::~term_ordering()
+{
+  if(weighted_block_size>0)
+    delete[] weight_vector;
+}
+
+
+
+
+/////////////// object properties /////////////////////////////////////////
+
+
+
+
+short term_ordering::number_of_weighted_variables() const
+{
+  return weighted_block_size;
+}
+
+
+
+short term_ordering::weight_refinement() const
+{
+  return weighted_ordering;
+}
+
+
+
+short term_ordering::number_of_elimination_variables() const
+{
+  return elimination_block_size;
+}
+
+
+
+short term_ordering::elimination_refinement() const
+{
+  return elimination_ordering;
+}
+
+
+
+BOOLEAN term_ordering::is_homogeneous() const
+{
+  return homogeneous;
+}
+
+
+
+short term_ordering::error_status() const
+{
+  if(weighted_block_size<0)
+    return weighted_block_size;
+  return 0;
+}
+
+
+
+BOOLEAN term_ordering::is_nonnegative() const
+{
+  for(int i=0;i<weighted_block_size;i++)
+    if(weight_vector[i]<0)
+      return FALSE;
+  return TRUE;
+}
+
+
+
+BOOLEAN term_ordering::is_positive() const
+{
+  for(int i=0;i<weighted_block_size;i++)
+    if(weight_vector[i]<=0)
+      return FALSE;
+  return TRUE;
+}
+
+
+
+
+/////////////// frequently used comparison functions //////////////////////
+
+
+
+
+double term_ordering::weight(const Integer* v) const
+{
+  double result=0;
+  for(short i=0;i<weighted_block_size;i++)
+    result+=(weight_vector[i]*v[i]);
+  return(result);
+}
+
+
+
+
+short term_ordering::compare_to_zero(const Integer* v) const
+{
+  unsigned short last_index=weighted_block_size+elimination_block_size;
+  double w=0;
+
+  // First check the elimination variables.
+
+  if(elimination_block_size>0)
+    switch(elimination_ordering)
+    {
+        case LEX:
+
+          for(short i=weighted_block_size;i<last_index;i++)
+          {
+            Integer actual_component=v[i];
+            if(actual_component>0)
+              return 1;
+            if(actual_component<0)
+              return -1;
+          }
+
+        break;
+
+        case DEG_LEX:
+
+          // compute the degree
+          for(short i=weighted_block_size;i<last_index;i++)
+            w+=v[i];
+
+          if(w>0)
+            return 1;
+          if(w<0)
+            return -1;
+
+          // if the degree is zero:
+          // tie breaking with the lexicographical ordering
+          for(short i=weighted_block_size;i<last_index;i++)
+          {
+            Integer actual_component=v[i];
+            if(actual_component>0)
+              return 1;
+            if(actual_component<0)
+              return -1;
+          }
+
+          break;
+
+        case DEG_REV_LEX:
+
+          //compute the degree
+          for(short i=weighted_block_size;i<last_index;i++)
+            w+=v[i];
+
+          if(w>0)
+            return 1;
+          if(w<0)
+            return -1;
+          // if the degree is zero:
+          // tie breaking with the reverse lexicographical ordering
+          for(short i=last_index-1;i>=weighted_block_size;i--)
+          {
+            Integer actual_component=v[i];
+            if(actual_component<0)
+              return 1;
+            if(actual_component>0)
+              return -1;
+          }
+    }
+
+
+  // When reaching this line, the vector components corresponding to
+  // elimination variables are all zero.
+  // Compute the weight.
+  // If the term ordering is a homogeneous one, this is superfluous.
+
+  if(!homogeneous)
+  {
+    w=weight(v);
+    if(w>0)
+      return 1;
+    if(w<0)
+      return -1;
+  }
+
+
+  // When reaching this line, the weight of the vector components corresponding
+  // to weighted variables is zero.
+  // Tie breaking with the term ordering refining the weight.
+
+  switch(weighted_ordering)
+  {
+      case W_LEX:
+
+        for(short i=0;i<weighted_block_size;i++)
+        {
+          Integer actual_component=v[i];
+          if(actual_component>0)
+            return 1;
+          if(actual_component<0)
+            return -1;
+        }
+
+        break;
+
+      case W_REV_LEX:
+
+        for(short i=weighted_block_size-1;i>=0;i--)
+        {
+          Integer actual_component=v[i];
+          if(actual_component<0)
+            return 1;
+          if(actual_component>0)
+            return -1;
+        }
+
+        break;
+
+      case W_DEG_LEX:
+
+        for(short i=0;i<weighted_block_size;i++)
+          w+=v[i];
+
+        if(w>0)
+          return 1;
+        if(w<0)
+          return -1;
+
+        for(short i=0;i<weighted_block_size;i++)
+        {
+          Integer actual_component=v[i];
+          if(actual_component>0)
+            return 1;
+          if(actual_component<0)
+            return -1;
+        }
+
+        break;
+
+      case W_DEG_REV_LEX:
+
+        for(short i=0;i<weighted_block_size;i++)
+          w+=v[i];
+
+        if(w>0)
+          return 1;
+        if(w<0)
+          return -1;
+
+        for(short i=weighted_block_size-1;i>=0;i--)
+        {
+          Integer actual_component=v[i];
+          if(actual_component<0)
+            return 1;
+          if(actual_component>0)
+            return -1;
+        }
+
+  }
+
+  // When reaching this line, the argument vector is the zero vector.
+
+  return 0;
+
+}
+
+
+
+
+short term_ordering::compare(const binomial& bin1, const binomial& bin2) const
+{
+  unsigned short last_index=weighted_block_size+elimination_block_size;
+  double w1=0;
+  double w2=0;
+
+  Integer* v1=bin1.exponent_vector;
+  Integer* v2=bin2.exponent_vector;
+
+  // First compare the heads of the input binomials.
+  // The code is analogous to the routine compare_to_zero(...), except
+  // from the fact that we must consider the sign of the vector components.
+
+  // First check the elimination variables.
+
+  if(elimination_block_size>0)
+    switch(elimination_ordering)
+    {
+        case LEX:
+
+          for(short i=weighted_block_size;i<last_index;i++)
+          {
+            Integer comp1=v1[i];
+            Integer comp2=v2[i];
+
+            if(comp1>0 || comp2>0)
+            {
+              if(comp1>comp2)
+                return 1;
+              if(comp1<comp2)
+                return -1;
+            }
+          }
+
+        break;
+
+        case DEG_LEX:
+
+          // compute the degree of the heads in the elimination variables
+          for(short i=weighted_block_size;i<last_index;i++)
+          {
+            Integer comp1=v1[i];
+            Integer comp2=v2[i];
+
+            if(comp1>0)
+              w1+=comp1;
+            if(comp2>0)
+              w2+=comp2;
+          }
+
+          if(w1>w2)
+            return 1;
+          if(w1<w2)
+            return -1;
+
+          // if the degree is equal:
+          // tie breaking with the lexicographical ordering
+          for(short i=weighted_block_size;i<last_index;i++)
+          {
+            Integer comp1=v1[i];
+            Integer comp2=v2[i];
+
+            if(comp1>0 || comp2>0)
+            {
+              if(comp1>comp2)
+                return 1;
+              if(comp1<comp2)
+                return -1;
+            }
+          }
+
+          break;
+
+        case DEG_REV_LEX:
+
+          //compute the degree of the heads in the elimination variables
+          for(short i=weighted_block_size;i<last_index;i++)
+          {
+            Integer comp1=v1[i];
+            Integer comp2=v2[i];
+
+            if(comp1>0)
+              w1+=comp1;
+            if(comp2>0)
+              w2+=comp2;
+          }
+
+          if(w1>w2)
+            return 1;
+          if(w1<w2)
+            return -1;
+          // if the degree is equal:
+          // tie breaking with the reverse lexicographical ordering
+          for(short i=last_index-1;i>=weighted_block_size;i--)
+          {
+            Integer comp1=v1[i];
+            Integer comp2=v2[i];
+
+            if(comp1>0 || comp2>0)
+            {
+              if(comp1<comp2)
+                return 1;
+              if(comp1>comp2)
+                return -1;
+            }
+          }
+    }
+
+
+  // When reaching this line, the heads are equal in the elimination
+  // variables.
+  // Compute the weight of the heads.
+
+  w1=0;
+  for(short i=0;i<weighted_block_size;i++)
+  {
+    Integer actual_component=v1[i];
+    if(actual_component>0)
+      w1+=actual_component*weight_vector[i];
+  }
+
+  w2=0;
+  for(short i=0;i<weighted_block_size;i++)
+  {
+    Integer actual_component=v2[i];
+    if(actual_component>0)
+      w2+=actual_component*weight_vector[i];
+  }
+
+  if(w1>w2)
+    return 1;
+  if(w1<w2)
+    return -1;
+
+
+  // When reaching this line, the weight of the heads in the weighted
+  // variables are equal.
+  // Tie breaking with the term ordering refining the weight.
+
+  switch(weighted_ordering)
+  {
+      case W_LEX:
+
+        for(short i=0;i<weighted_block_size;i++)
+        {
+          Integer comp1=v1[i];
+          Integer comp2=v2[i];
+
+          if(comp1>0 || comp2>0)
+          {
+            if(comp1>comp2)
+              return 1;
+            if(comp1<comp2)
+              return -1;
+          }
+        }
+
+        break;
+
+      case W_REV_LEX:
+
+        for(short i=weighted_block_size-1;i>=0;i--)
+        {
+          Integer comp1=v1[i];
+          Integer comp2=v2[i];
+
+          if(comp1>0 || comp2>0)
+          {
+            if(comp1<comp2)
+              return 1;
+            if(comp1>comp2)
+              return -1;
+          }
+        }
+
+        break;
+
+      case W_DEG_LEX:
+
+        for(short i=0;i<weighted_block_size;i++)
+        {
+          Integer comp1=v1[i];
+          Integer comp2=v2[i];
+
+          if(comp1>0)
+            w1+=comp1;
+          if(comp2>0)
+            w2+=comp2;
+        }
+
+        if(w1>w2)
+          return 1;
+        if(w1<w2)
+          return -1;
+
+        for(short i=0;i<weighted_block_size;i++)
+        {
+          Integer comp1=v1[i];
+          Integer comp2=v2[i];
+
+          if(comp1>0 || comp2>0)
+          {
+            if(comp1>comp2)
+              return 1;
+            if(comp1<comp2)
+              return -1;
+          }
+        }
+
+        break;
+
+      case W_DEG_REV_LEX:
+
+        for(short i=0;i<weighted_block_size;i++)
+        {
+          Integer comp1=v1[i];
+          Integer comp2=v2[i];
+
+          if(comp1>0)
+            w1+=comp1;
+          if(comp2>0)
+            w2+=comp2;
+        }
+
+        if(w1>w2)
+          return 1;
+        if(w1<w2)
+          return -1;
+
+        for(short i=weighted_block_size-1;i>=0;i--)
+        {
+          Integer comp1=v1[i];
+          Integer comp2=v2[i];
+
+          if(comp1>0 || comp2>0)
+          {
+            if(comp1<comp2)
+              return 1;
+            if(comp1>comp2)
+              return -1;
+          }
+        }
+  }
+
+
+  // When reaching this line, the heads of the binomials are equal.
+  // Now we decide by the tails.
+  // This part of the code could also be omitted in the current context:
+  // The compare(...)-function is only called when dealing with ordered
+  // lists. This is done in two cases:
+  // - When computing with ordered S-pair lists, it doesn't really matter
+  //   if such similar binomials are in the right order.
+  // - When outputting a reduced Groebner basis, it cannot happen that two
+  //   heads are equal.
+
+  w1=0;
+  w2=0;
+
+  // First check the elimination variables.
+
+  if(elimination_block_size>0)
+    switch(elimination_ordering)
+    {
+        case LEX:
+
+          for(short i=weighted_block_size;i<last_index;i++)
+          {
+            Integer comp1=-v1[i];
+            Integer comp2=-v2[i];
+
+            if(comp1>0 || comp2>0)
+            {
+              if(comp1>comp2)
+                return 1;
+              if(comp1<comp2)
+                return -1;
+            }
+          }
+
+        break;
+
+        case DEG_LEX:
+
+          // compute the degree of the tails in the elimination variables
+          for(short i=weighted_block_size;i<last_index;i++)
+          {
+            Integer comp1=-v1[i];
+            Integer comp2=-v2[i];
+
+            if(comp1>0)
+              w1+=comp1;
+            if(comp2>0)
+              w2+=comp2;
+          }
+
+          if(w1>w2)
+            return 1;
+          if(w1<w2)
+            return -1;
+
+          // if the degree is equal:
+          // tie breaking with the lexicographical ordering
+          for(short i=weighted_block_size;i<last_index;i++)
+          {
+            Integer comp1=-v1[i];
+            Integer comp2=-v2[i];
+
+            if(comp1>0 || comp2>0)
+            {
+              if(comp1>comp2)
+                return 1;
+              if(comp1<comp2)
+                return -1;
+            }
+          }
+
+          break;
+
+        case DEG_REV_LEX:
+
+          // compute the degree of the tails in the elimination variables
+          for(short i=weighted_block_size;i<last_index;i++)
+          {
+            Integer comp1=-v1[i];
+            Integer comp2=-v2[i];
+
+            if(comp1>0)
+              w1+=comp1;
+            if(comp2>0)
+              w2+=comp2;
+          }
+
+          if(w1>w2)
+            return 1;
+          if(w1<w2)
+            return -1;
+          // if the degree is equal:
+          // tie breaking with the reverse lexicographical ordering
+          for(short i=last_index-1;i>=weighted_block_size;i--)
+          {
+            Integer comp1=-v1[i];
+            Integer comp2=-v2[i];
+
+            if(comp1>0 || comp2>0)
+            {
+              if(comp1<comp2)
+                return 1;
+              if(comp1>comp2)
+                return -1;
+            }
+          }
+    }
+
+
+  // When reaching this line, the tails are equal in the elimination
+  // variables.
+  // Compute the weight of the tails.
+
+  w1=0;
+  for(short i=0;i<weighted_block_size;i++)
+  {
+    Integer actual_component=-v1[i];
+    if(actual_component>0)
+      w1+=actual_component*weight_vector[i];
+  }
+
+  w2=0;
+  for(short i=0;i<weighted_block_size;i++)
+  {
+    Integer actual_component=-v2[i];
+    if(actual_component>0)
+      w2+=actual_component*weight_vector[i];
+  }
+
+  if(w1>w2)
+    return 1;
+  if(w1<w2)
+    return -1;
+
+
+  // When reaching this line, the weight of the tails in the weighted
+  // variables are equal.
+  // Tie breaking with the term ordering refining the weight.
+
+  switch(weighted_ordering)
+  {
+      case W_LEX:
+
+        for(short i=0;i<weighted_block_size;i++)
+        {
+          Integer comp1=-v1[i];
+          Integer comp2=-v2[i];
+
+          if(comp1>0 || comp2>0)
+          {
+            if(comp1>comp2)
+              return 1;
+            if(comp1<comp2)
+              return -1;
+          }
+        }
+
+        break;
+
+      case W_REV_LEX:
+
+        for(short i=weighted_block_size-1;i>=0;i--)
+        {
+          Integer comp1=-v1[i];
+          Integer comp2=-v2[i];
+
+          if(comp1>0 || comp2>0)
+          {
+            if(comp1<comp2)
+              return 1;
+            if(comp1>comp2)
+              return -1;
+          }
+        }
+
+        break;
+
+      case W_DEG_LEX:
+
+        for(short i=0;i<weighted_block_size;i++)
+        {
+          Integer comp1=-v1[i];
+          Integer comp2=-v2[i];
+
+          if(comp1>0)
+            w1+=comp1;
+          if(comp2>0)
+            w2+=comp2;
+        }
+
+        if(w1>w2)
+          return 1;
+        if(w1<w2)
+          return -1;
+
+        for(short i=0;i<weighted_block_size;i++)
+        {
+          Integer comp1=-v1[i];
+          Integer comp2=-v2[i];
+
+          if(comp1>0 || comp2>0)
+          {
+            if(comp1>comp2)
+              return 1;
+            if(comp1<comp2)
+              return -1;
+          }
+        }
+
+        break;
+
+      case W_DEG_REV_LEX:
+
+        for(short i=0;i<weighted_block_size;i++)
+        {
+          Integer comp1=-v1[i];
+          Integer comp2=-v2[i];
+
+          if(comp1>0)
+            w1+=comp1;
+          if(comp2>0)
+            w2+=comp2;
+        }
+
+        if(w1>w2)
+          return 1;
+        if(w1<w2)
+          return -1;
+
+        for(short i=weighted_block_size-1;i>=0;i--)
+        {
+          Integer comp1=-v1[i];
+          Integer comp2=-v2[i];
+
+          if(comp1>0 || comp2>0)
+          {
+            if(comp1<comp2)
+              return 1;
+            if(comp1>comp2)
+              return -1;
+          }
+        }
+  }
+
+  return 0;
+
+}
+
+
+
+
+///////// operators and routines needed by the IP-algorithms ////////////////
+///////// to manipulate the term ordering ////////////////////////////////
+
+
+
+
+term_ordering& term_ordering::operator=(const term_ordering& w)
+{
+  if(&w==this)
+    return *this;
+
+  if(weighted_block_size>0)
+    delete[] weight_vector;
+
+  weighted_block_size=w.weighted_block_size;
+  weighted_ordering=w.weighted_ordering;
+  elimination_block_size=w.elimination_block_size;
+  elimination_ordering=w.elimination_ordering;
+  homogeneous=w.homogeneous;
+
+  if(weighted_block_size>0)
+  {
+    weight_vector=new float[weighted_block_size];
+    for(short i=0;i<weighted_block_size;i++)
+      weight_vector[i]=w.weight_vector[i];
+  }
+  else
+    if(weighted_block_size<0)
+      cerr<<"\nWARNING: term_ordering& term_ordering::"
+        "operator=(const term_ordering&):\n"
+        "assignment from corrupt term ordering"<<endl;
+
+  return(*this);
+}
+
+
+
+
+float term_ordering::operator[](const short& i) const
+{
+  if((i<0) || (i>=weighted_block_size))
+  {
+    cerr<<"\nWARNING: float term_ordering::operator[](const short& i):\n"
+      "access to invalid weight vector component"<<endl;
+    return FLT_MAX;
+  }
+  else
+    return weight_vector[i];
+}
+
+
+
+
+term_ordering& term_ordering::convert_to_weighted_ordering()
+{
+  elimination_block_size=0;
+  return(*this);
+}
+
+
+
+
+term_ordering& term_ordering::convert_to_elimination_ordering
+(const short& number_of_elimination_variables,
+ const short& _elimination_ordering)
+{
+  if((_elimination_ordering<1) || (_elimination_ordering>3))
+    // unknown ordering on the elimination variables, set "error flag"
+    weighted_block_size=-1;
+  else
+    elimination_ordering=_elimination_ordering;
+
+  if(number_of_elimination_variables<0)
+    // argument out of range, set error flag
+    weighted_block_size=-1;
+  else
+    elimination_block_size=number_of_elimination_variables;
+
+  if(weighted_block_size<0)
+    cerr<<"\nWARNING: term_ordering& term_ordering::"
+      "convert_to_elimination_ordering(const short&, const short&):\n"
+      "argument out of range"<<endl;
+
+  return(*this);
+}
+
+
+
+
+term_ordering& term_ordering::append_weighted_variable(const float& weight)
+{
+  if(weighted_block_size>=0)
+  {
+    float *aux=weight_vector;
+    weight_vector=new float[weighted_block_size+1];
+
+    for(short i=0;i<weighted_block_size;i++)
+      weight_vector[i]=aux[i];
+    weight_vector[weighted_block_size]=weight;
+
+    if(weighted_block_size>0)
+      delete[] aux;
+
+    weighted_block_size++;
+  }
+  else
+    cerr<<"\nWARNING: term_ordering& term_ordering::append_weighted_variable"
+      "(const float&):\n"
+      "called for a corrupt term ordering, term ordering not changed"
+        <<endl;
+
+  return(*this);
+}
+
+
+
+
+term_ordering& term_ordering::delete_last_weighted_variable()
+{
+  if(weighted_block_size>0)
+  {
+    float *aux=weight_vector;
+
+    if(weighted_block_size>1)
+      weight_vector=new float[weighted_block_size-1];
+
+    for(short i=0;i<weighted_block_size-1;i++)
+      weight_vector[i]=aux[i];
+    weighted_block_size--;
+
+    delete[] aux;
+  }
+  else
+    cerr<<"\nWARNING: term_ordering& term_ordering::"
+      "delete_last_weighted_variable():\n"
+      "called for a maybe corrupt term ordering without weighted variables,\n"
+      "term ordering not changed"<<endl;
+
+  return(*this);
+}
+
+
+
+
+term_ordering& term_ordering::swap_weights(const short& i, const short& j)
+{
+  if((i<0) || (i>=weighted_block_size) || (j<0) || (j>=weighted_block_size))
+  {
+    cout<<"\nWARNING: term_ordering& termordering::swap_weights"
+      "(const short, const short):\nindex out of range"<<endl;
+    return *this;
+  }
+
+  float swap=weight_vector[j];
+  weight_vector[j]=weight_vector[i];
+  weight_vector[i]=swap;
+
+  return *this;
+}
+
+
+
+
+/////////////////// output ///////////////////////////////////////////////
+
+
+
+
+void term_ordering::print_weight_vector() const
+{
+  if(weighted_block_size<0)
+  {
+    printf("\nWARNING: void term_ordering::print_weight_vector():\n"
+           "cannot print corrupt term ordering\n");
+    return;
+  }
+
+  printf("(");
+  for(short i=0;i<weighted_block_size-1;i++)
+    printf("%6.2f,",weight_vector[i]);
+  printf("%6.2f)\n",weight_vector[weighted_block_size-1]);
+}
+
+
+
+
+void term_ordering::print() const
+{
+  if(weighted_block_size<0)
+  {
+    printf("\n\nWARNING: void term_ordering::print():\n"
+           "cannot print corrupt term ordering\n");
+    return;
+  }
+
+  printf("\nelimination variables:%4d\n",elimination_block_size);
+  printf("weighted variables:   %4d\n",weighted_block_size);
+
+  printf("weight vector:\n");
+  print_weight_vector();
+
+  if(elimination_block_size>0)
+  {
+    printf("ordering on elimination variables: ");
+    switch(elimination_ordering)
+    {
+        case LEX:
+          printf("LEX\n");
+          break;
+        case DEG_LEX:
+          printf("DEG_LEX\n");
+          break;
+        case DEG_REV_LEX:
+          printf("DEG_REV_LEX\n");
+          break;
+    }
+  }
+
+  printf("ordering refining the weight:      ");
+  switch(weighted_ordering)
+  {
+      case W_LEX:
+        printf("W_LEX\n\n");
+        break;
+      case W_REV_LEX:
+        printf("W_REV_LEX\n\n");
+        break;
+      case W_DEG_LEX:
+        printf("W_DEG_LEX\n\n");
+        break;
+      case W_DEG_REV_LEX:
+        printf("W_DEG_REV_LEX\n\n");
+        break;
+  }
+
+}
+
+
+
+
+void term_ordering::print_weight_vector(FILE* output) const
+{
+  if(weighted_block_size<0)
+  {
+    fprintf(output,"\nWARNING: void term_ordering::print_weight_vector(FILE*)"
+            ":\ncannot print corrupt term ordering\n");
+    return;
+  }
+
+  fprintf(output,"(");
+  for(short i=0;i<weighted_block_size-1;i++)
+    fprintf(output,"%6.2f,",weight_vector[i]);
+  fprintf(output,"%6.2f)\n",weight_vector[weighted_block_size-1]);
+}
+
+
+
+
+void term_ordering::print(FILE* output) const
+{
+  if(weighted_block_size<0)
+  {
+    fprintf(output,"\n\nWARNING: void term_ordering::print(FILE*):\n"
+           "cannot print corrupt term ordering\n");
+
+    return;
+  }
+
+  fprintf(output,"\nelimination variables:%4d\n",elimination_block_size);
+  fprintf(output,"weighted variables:   %4d\n",weighted_block_size);
+
+  fprintf(output,"weight_vector:\n");
+  print_weight_vector(output);
+
+  if(elimination_block_size>0)
+  {
+    fprintf(output,"ordering on elimination variables: ");
+    switch(elimination_ordering)
+    {
+        case LEX:
+          fprintf(output,"LEX\n");
+          break;
+        case DEG_LEX:
+          fprintf(output,"DEG_LEX\n");
+          break;
+        case DEG_REV_LEX:
+          fprintf(output,"DEG_REV_LEX\n");
+          break;
+    }
+  }
+
+  fprintf(output,"ordering refining the weight:      ");
+  switch(weighted_ordering)
+  {
+      case W_LEX:
+        fprintf(output,"W_LEX\n\n");
+        break;
+      case W_REV_LEX:
+        fprintf(output,"W_REV_LEX\n\n");
+        break;
+      case W_DEG_LEX:
+        fprintf(output,"W_DEG_LEX\n\n");
+        break;
+      case W_DEG_REV_LEX:
+        fprintf(output,"W_DEG_REV_LEX\n\n");
+        break;
+  }
+}
+
+
+
+
+void term_ordering::print_weight_vector(ofstream& output) const
+{
+  if(weighted_block_size<0)
+  {
+    output<<"\nWARNING: void term_ordering::print_weight_vector(ofstream&):\n"
+      "cannot print corrupt term ordering"<<endl;
+    return;
+  }
+
+  output<<"(";
+  for(short i=0;i<weighted_block_size-1;i++)
+    output<<setw(6)<<setprecision(2)<<weight_vector[i]<<",";
+  output<<setw(6)<<setprecision(2)<<weight_vector[weighted_block_size-1]
+        <<")"<<endl<<endl;
+}
+
+
+
+
+void term_ordering::print(ofstream& output) const
+{
+  if(weighted_block_size<0)
+  {
+    output<<"\nWARNING: void term_ordering::print(ofstream&):\n"
+      "cannot print corrupt term ordering"<<endl;
+    return;
+  }
+
+  output<<"\nelimination variables:"<<setw(4)<<elimination_block_size<<endl
+        <<"weighted variables:   "<<setw(4)<<weighted_block_size<<endl;
+
+  output<<"weight_vector:"<<endl;
+  print_weight_vector(output);
+
+  if(elimination_block_size>0)
+  {
+    output<<"ordering on elimination variables: ";
+    switch(elimination_ordering)
+    {
+        case LEX:
+          output<<"LEX\n"<<endl;
+          break;
+        case DEG_LEX:
+          output<<"DEG_LEX\n"<<endl;
+          break;
+        case DEG_REV_LEX:
+          output<<"DEG_REV_LEX\n"<<endl;
+          break;
+    }
+  }
+
+  output<<"ordering refining the weight:      ";
+  switch(weighted_ordering)
+  {
+      case W_LEX:
+        output<<"W_LEX\n"<<endl;
+        break;
+      case W_REV_LEX:
+        output<<"W_REV_LEX\n"<<endl;
+        break;
+      case W_DEG_LEX:
+        output<<"W_DEG_LEX\n"<<endl;
+        break;
+      case W_DEG_REV_LEX:
+        output<<"W_DEG_REV_LEX\n"<<endl;
+        break;
+  }
+}
+
+void term_ordering::format_print_weight_vector(ofstream& output) const
+{
+  for(short i=0;i<weighted_block_size;i++)
+    output<<setw(6)<<setprecision(2)<<weight_vector[i];
+  output<<endl;
+}
+#endif  // TERM_ORDERING_CC
diff --git a/IntegerProgramming/term_ordering.h b/IntegerProgramming/term_ordering.h
new file mode 100644
index 0000000..d4108a1
--- /dev/null
+++ b/IntegerProgramming/term_ordering.h
@@ -0,0 +1,246 @@
+// term_ordering.h
+
+
+// Our IP-algorithms need two kinds of term orderings: a weighted term ordering
+// and a block ordering that eliminates some auxiliary variables. Both
+// are constructed from the input or for the specific requirements of the
+// algorithms. To allow an easy and flexible handling, the term ordering is
+// realized as a class.
+
+// Weight vectors for term orderings have to be nonnegative in most contexts.
+// But input vectors with negative components are not refused by the
+// constructors. This has the following two reasons:
+// - There is a more general notion of term ordering who does not claim
+//   the monomial 1 to be a (unique) minimal monomial. This allows negative
+//   weights.
+// - This class is written for the final purpose of integer programming.
+//   The linear objective function induces the term ordering and might also
+//   have negative components. Although the program actually cannot treat
+//   this case, there are ways to tackle it. In view of a possible later
+//   expansion of the program, the nonnegativity check is delegated to a
+//   separate function instead of doing it in the constructors.
+
+// For the same reasons as mentionned in the binomial class, frequently
+// used operations on Integer vectors do not perform range checks. Nor do
+// they check if an error has occurred (i.e. control the "error flag", see
+// below).
+// These are concretely the functions weight(...), compare_to_zero(...) and
+// compare(...).
+// All other routines perform argument checks (range, file format...).
+// This is only really important when reading from a file (as most other range
+// checks are already made by the routines calling these functions). But as
+// all these operations are executed only a few times in the course of our
+// algorithms, the checks do not slow down computation.
+
+#ifndef TERM_ORDERING_H
+#define TERM_ORDERING_H
+
+#include "globals.h"
+
+class binomial;
+
+class term_ordering
+{
+protected:
+
+  float *weight_vector;
+
+  short weighted_block_size;
+  // the number of weighted variables
+  // Also the "error flag", i.e. values <0 indicate an error:
+  // -1 indicates a "semantic" error (arguments out of range, for example a
+  //    negative number of variables);
+  // -2 indicates an error occured when reading from a file.
+
+  short weighted_ordering;
+  // the term ordering refining the weight on the weighted variables
+  // possibilities: see in globals.h
+
+  short elimination_block_size;
+  // the number of elimination variables
+
+  short elimination_ordering;
+  // the term ordering on the elimination variables
+
+  BOOLEAN homogeneous;
+  // This flag is set to TRUE if the term ordering is thought of as a
+  // homogeneous one (i.e. the weighted part), else to FALSE. The standard
+  // setting is FALSE.
+  // The routine compare_to_zero is faster if the term ordering is homogenous.
+  // It would be safer and more natural to take this flag as a member of
+  // the ideal class; this would, however, require many supplementary
+  // functions (homogeneous versions of existing functions) in the ideal and
+  // even in the binomial class.
+
+public:
+// constructors and destructor
+
+  term_ordering(const BOOLEAN& homogeneous=FALSE);
+  // Sets weighted_block_size and elimination_block_size to zero.
+  // With this default contructor, the term ordering can be taken as a member
+  // of another class (the ideal class in our case).
+
+  term_ordering(const short& number_of_weighted_variables,
+                const float* weights,
+                const short& _weighted_ordering,
+                const BOOLEAN& _homogeneous=FALSE);
+  // Initializes weight vector with weights,
+  // weighted_block_size with number_of_weighted_variables,
+  // the refining ordering as given in the argument
+  // and elimination_block_size with 0.
+
+  term_ordering(const short& number_of_weighted_variables,
+                const float* weights,
+                const short& _weighted_ordering,
+                const short& number_of_elimination_variables,
+                const short& _elimination_ordering,
+                const BOOLEAN& _homogeneous=FALSE);
+  // Initializes weight vector with weights,
+  // weighted_block_size with number_of_weighted_variables,
+  // the orderings as given in the arguments
+  // and elimination_block_size with _number_of_elimination_variables.
+
+  term_ordering(ifstream& input, const short& _weighted_ordering,
+                const BOOLEAN& _homogeneous=FALSE);
+  // Reads a weight vector from the input stream and converts it into a
+  // weighted term ordering (with the refining ordering given by the second
+  // argument).
+  // The input stream must have the following format:
+  //
+  //    size n of the weight vector (=weighted_block_size)
+  //    components 0..n-1 of the weight vector
+  //
+
+  term_ordering(const short& n, ifstream& input,
+                const short& _weighted_ordering,
+                const BOOLEAN& _homogeneous=FALSE);
+  // Reads a weight vector of size n from the input stream and converts it
+  // into a weighted term ordering (with the refining ordering given by the
+  // second argument).
+  // The input stream has the following format:
+  //
+  //    components 0..n-1 of the weight vector
+  //
+
+  term_ordering(const term_ordering&);
+  // copy-constructor
+
+
+  ~term_ordering();
+  // destructor
+
+// object properties
+
+  short number_of_weighted_variables() const;
+  // Returns weighted_block_size.
+
+  short weight_refinement() const;
+  // Returns weighted_ordering.
+
+  short number_of_elimination_variables() const;
+  // Returns elimination_block_size.
+
+  short elimination_refinement() const;
+  // Returns elimination_ordering.
+
+  BOOLEAN is_homogeneous() const;
+  // Returns homogeneous.
+
+  short error_status() const;
+  // Returns weighted_block_size if weighted_block_size<0, else 0
+  // (this is the "error flag").
+
+  BOOLEAN is_nonnegative() const;
+  // Returns TRUE iff all components of the weight vector are >=0.
+  // If this is not the case, Buchberger's algorithm will perhaps not
+  // terminate using the actual ordering, i.e. the ordering is no
+  // well ordering.
+
+  BOOLEAN is_positive() const;
+  // Returns TRUE ifs all components of the weight vector are >0.
+  // If this is not the case, this may lead to problems even if all weights
+  // are nonnegative: Zero weights do not give a well ordering in combination
+  // with a reverse lexicographical refinement.
+
+// frequently used comparison functions
+
+  double weight(const Integer* v) const;
+  // Returns the weight of an Integer vector v with respect to weight_vector,
+  // i.e. the scalar product of the two vectors.
+  // UNCHECKED PRECONDITION: v has weighted_block_size components.
+  // The return type is double to avoid overflows.
+
+  short compare_to_zero(const Integer* v) const;
+  // This function is used to determine a binomials's head with respect to the
+  // actual term ordering. The comparison of its two monomials is done
+  // according to the binomial data structure:
+  // Instead of comparing explicitely two monomials, the Integer vector
+  // corresponding to their difference is compared to the zero vector.
+  // The function returns
+  //          1, if v>0,
+  //             -1, if v<0,
+  //              0, if v=0
+  // UNCHECKED PRECONDITION:
+  // v has weighted_block_size + elimination_block_size components
+
+  short compare(const binomial& bin1, const binomial& bin2) const;
+  // Compares the given binomials by first comparing the heads, then in the
+  // case of equality the tails.
+  // UNCHECKED PRECONDITION: The exponent vectors of the binomials have
+  // already the correct sign, i.e. the positive part of a vector is really
+  // its head and not its tail.
+  // The function returns
+  //        -1 if bin1<bin2
+  //         0 if bin1=bin2
+  //         1 if bin1>bin2
+
+// operators and routines needed by the algorithms to manipulate the term
+// ordering
+
+  term_ordering& operator=(const term_ordering&);
+  // assignment operator with memory control
+
+  float operator[](const short& i) const;
+  // Returns weight_vector[i] (FLT_MAX if i is out of range).
+
+  term_ordering& convert_to_weighted_ordering();
+  // Sets elimination_block_size to 0.
+
+  term_ordering& convert_to_elimination_ordering
+  (const short& number_of_elimination_variables,
+   const short& _elimination_ordering);
+  // Sets elimination_block_size to number_of_elimination_variables
+  // and the ordering on the elimination variables as given in the argument.
+
+  term_ordering& append_weighted_variable(const float& weight);
+  // Appends the given weight to the weight vector (with memory control).
+
+  term_ordering& delete_last_weighted_variable();
+  // Deletes the last weighted variable (with memory control).
+
+  term_ordering& swap_weights(const short& i, const short& j);
+  // This function is used if two weighted variables must change their
+  // position (order) with respect to the refining ordering.
+
+// output
+
+  void print_weight_vector() const;
+  void print() const;
+  // Writes the term ordering to the standard output medium
+  // (only the weight vector or with supplementary information).
+
+  void print_weight_vector(FILE*) const;
+  void print(FILE*) const;
+  // Writes the term ordering to the referenced file
+  // which has to be opened for writing before.
+
+  void print_weight_vector(ofstream&) const;
+  void print(ofstream&) const;
+  // Writes the term ordering to the given ofstream.
+
+  void format_print_weight_vector(ofstream&) const;
+  // Writes the term ordering to the given ofstream in the format required
+  // by the IP-algorithms.
+
+};
+#endif  // TERM_ORDERING_H
diff --git a/IntegerProgramming/testdata.cc b/IntegerProgramming/testdata.cc
new file mode 100644
index 0000000..c330444
--- /dev/null
+++ b/IntegerProgramming/testdata.cc
@@ -0,0 +1,232 @@
+// testdata.cc
+
+// Implements the data generation routines declared in testdata.h.
+
+#ifndef TESTDATA_CC
+#define TESTDATA_CC
+
+
+
+#include "testdata.h"
+
+
+
+
+int random_matrix(const short& rows, const short& columns,
+                  const Integer& lower_bound, const Integer& upper_bound,
+                  ofstream& MATRIX)
+{
+  // check arguments
+
+  if(rows<=0)
+  {
+    cerr<<"ERROR: int random_matrix(const short&, const short&, \n"
+      "                         const Integer&, const Integer&, ofstream&):\n"
+      "first argument out of range: number of matrix rows must be positive"
+        <<endl;
+    return 0;
+  }
+
+  if(columns<=0)
+  {
+    cerr<<"ERROR: int random_matrix(const short&, const short&, \n"
+      "                         const Integer&, const Integer&, ofstream&):\n"
+      "second argument out of range: number of matrix columns must be positive"
+        <<endl;
+    return 0;
+  }
+
+  if(upper_bound<0)
+  {
+    cerr<<"ERROR: int random_matrix(const short&, const short&, \n"
+      "                         const Integer&, const Integer&, ofstream&):\n"
+      "fourth argument (upper bound for random cost vector entries) must be\n"
+      "nonnegative\n"<<endl;
+    return 0;
+  }
+
+  if(upper_bound<lower_bound)
+  {
+    cerr<<"ERROR: int random_matrix(const short&, const short&, \n"
+      "                         const Integer&, const Integer&, ofstream&):\n"
+      "third argument (lower bound for random entries) must be less\n"
+      "or equal the fourth argument (upper bound)"<<endl;
+    return 0;
+  }
+
+  // create test file
+
+  MATRIX<<"MATRIX"<<endl<<endl;
+
+  MATRIX<<"columns:"<<endl;
+  MATRIX<<columns<<endl<<endl;
+
+  // random cost vector
+  MATRIX<<"cost vector:"<<endl;
+  for(short j=0;j<columns;j++)
+    MATRIX<<setw(4)<<rand()%(upper_bound+1);
+  // random entries between 0 and upper_bound
+  MATRIX<<endl;
+
+  MATRIX<<"rows:"<<endl;
+  MATRIX<<rows<<endl<<endl;
+
+  // random matrix
+  MATRIX<<"matrix:"<<endl;
+  for(short i=0;i<rows;i++)
+  {
+    for(short j=0;j<columns;j++)
+      MATRIX<<setw(4)<<rand()%(upper_bound-lower_bound+1)+lower_bound;
+    // random entries between lower_bound and upper_bound
+    MATRIX<<endl;
+  }
+  MATRIX<<endl;
+
+  MATRIX<<"positive row space vector:"<<endl;
+
+  return 1;
+
+}
+
+
+
+
+int transportation_problem(const short& sources, const short& targets,
+                           const Integer& upper_bound, ofstream& MATRIX)
+{
+  // check arguments
+
+  if(sources<=0)
+  {
+    cerr<<"ERROR: int transportation_problem(const short&, const short&, \n"
+      "                         const Integer&, ofstream&):\n"
+      "first argument out of range: number of sources must be positive"
+        <<endl;
+    return 0;
+  }
+
+  if(targets<=0)
+  {
+    cerr<<"ERROR: int transportation_problem(const short&, const short&, \n"
+      "                         const Integer&, ofstream&):\n"
+      "second argument out of range: number of targets must be positive"
+        <<endl;
+    return 0;
+  }
+
+  if(upper_bound<0)
+  {
+    cerr<<"ERROR: int transportation_problem(const short&, const short&, \n"
+      "                         const Integer&, const Integer&, ofstream&):\n"
+      "third argument (upper bound for random cost vector entries) must be\n"
+      "nonnegative\n"<<endl;
+    return 0;
+  }
+
+  // create test file
+
+  MATRIX<<"MATRIX"<<endl<<endl;
+
+  MATRIX<<"columns:"<<endl;
+  MATRIX<<sources*targets<<endl<<endl;
+
+  // random cost vector
+  MATRIX<<"cost vector:"<<endl;
+  for(short j=0;j<sources*targets;j++)
+    MATRIX<<setw(4)<<rand()%(upper_bound+1);
+  // random entries between 0 and upper_bound
+  MATRIX<<endl;
+
+  MATRIX<<"rows:"<<endl;
+  MATRIX<<sources+targets<<endl<<endl;
+
+  // constraint matrix in the usual formulation of the transportation problem
+  // as an IP problem
+  MATRIX<<"matrix:"<<endl;
+
+  for(int i=0;i<targets;i++)
+    // generate matrix
+  {
+    for(int k=0;k<targets;k++)
+      for(int j=0;j<sources;j++)
+        MATRIX<<setw(2)<<(int)(i==k);
+    MATRIX<<endl;
+  }
+
+  for(int j=0;j<sources;j++)
+  {
+    for(int i=0;i<targets;i++)
+      for(int k=0;k<sources;k++)
+        MATRIX<<setw(2)<<(int)(j==k);
+    MATRIX<<endl;
+  }
+
+  MATRIX<<endl;
+
+  MATRIX<<"positive row space vector:"<<endl;
+  for(short j=0;j<sources*targets;j++)
+    MATRIX<<setw(2)<<1<<endl;
+  MATRIX<<endl;
+
+  return 1;
+}
+
+
+
+int random_problems(const short& vector_dimension,
+                    const long& number_of_instances,
+                    const Integer& lower_bound, const Integer& upper_bound,
+                    ofstream& PROBLEM)
+{
+  // check arguments
+
+  if(vector_dimension<=0)
+  {
+    cerr<<"ERROR: int random_problems(const short&, const long&, \n"
+      "                         const Integer&, const Integer&, ofstream&):\n"
+      "first argument out of range: vector dimension must be positive"
+        <<endl;
+    return 0;
+  }
+
+  if(number_of_instances<0)
+  {
+    cerr<<"ERROR: int random_problems(const short&, const long&, \n"
+      "                         const Integer&, const Integer&, ofstream&):\n"
+      "second argument out of range: number of instances must be nonnegative"
+        <<endl;
+    return 0;
+  }
+
+  if(upper_bound<lower_bound)
+  {
+    cerr<<"ERROR: int random_problems(const short&, const long&, \n"
+      "                         const Integer&, const Integer&, ofstream&):\n"
+      "third argument (lower bound for random entries) must be less\n"
+      "or equal the fourth argument (upper bound)"<<endl;
+    return 0;
+  }
+
+  // create random problems
+
+  PROBLEM<<"PROBLEM"<<endl<<endl;
+
+  PROBLEM<<"vector size:"<<endl;
+  PROBLEM<<vector_dimension<<endl<<endl;
+
+  PROBLEM<<"number of instances:"<<endl;
+  PROBLEM<<number_of_instances<<endl<<endl;
+
+  PROBLEM<<"right hand or initial solution vectors:"<<endl;
+  for(short i=0;i<number_of_instances;i++)
+  {
+    for(short j=0;j<vector_dimension;j++)
+      PROBLEM<<setw(4)<<rand()%(upper_bound+1);
+    // random entries between 0 and upper_bound
+    PROBLEM<<endl;
+  }
+  PROBLEM<<endl;
+
+  return 1;
+}
+#endif  // TESTDATA_CC
diff --git a/IntegerProgramming/testdata.h b/IntegerProgramming/testdata.h
new file mode 100644
index 0000000..ad66c54
--- /dev/null
+++ b/IntegerProgramming/testdata.h
@@ -0,0 +1,53 @@
+// testdata.h
+
+// This file provides an interface for generating test data.
+
+#ifndef TESTDATA_H
+#define TESTDATA_H
+
+#include "globals.h"
+
+extern int random_matrix(const short& rows, const short& columns,
+                         const Integer& lower_bound,
+                         const Integer& upper_bound,
+                         ofstream& MATRIX);
+
+// Creates a random matrix of size rows x columns with entries between
+// lower_bound and upper_bound. This matrix is written in the MATRIX file
+// in the format explained in IP_algorithms.h, together with a randomly
+// generated (integer) cost vector with entries between 0 and upper_bound.
+
+// The positive row space vector needed by the algorithms of Hosten/Sturmfels
+// and Bigatti/LaScala/Robbiano has to be entered by hand. It can be computed
+// (or its existence can be verified) with the Simplex algorithm that is not
+// included in this package.
+
+extern int transportation_problem(const short& sources, const short& targets,
+                                  const Integer& upper_bound,
+                                  ofstream& MATRIX);
+
+// Creates a transportation problem with the given number of sources and
+// targets. This involves creating the (fixed) constraint matrix of size
+// (sources + targets) x (sources * targets) and a randomly chosen cost vector
+// (the "transportation matrix") of size targets*sources with entries between
+// 0 and upper_bound.
+
+// In the case of the transportation problem, a positive row space vector
+// is given e.g. by the vector where all entries are 1, so it is printed
+// automatically.
+
+extern int random_problems (const short& vector_dimension,
+                            const long& number_of_instances,
+                            const Integer& lower_bound,
+                            const Integer& upper_bound,
+                            ofstream& PROBLEM);
+
+// Creates number_of_instances random vectors of size vector_dimension
+// with entries beteewn lower_bound and upper_bound. These vectors are
+// written in the PROBLEM file in the format explained in IP_algorithms.h.
+
+// For the (Positive) Conti-Traverso algorithm it might be more useful to
+// generate some problems by hand (randomly created instances show to be
+// unsolvable in many cases).
+
+#endif  // TESTDATA_H
diff --git a/IntegerProgramming/toric_ideal.cc b/IntegerProgramming/toric_ideal.cc
new file mode 100644
index 0000000..fdd0a1f
--- /dev/null
+++ b/IntegerProgramming/toric_ideal.cc
@@ -0,0 +1,260 @@
+// toric_ideal.cc
+
+// This file provides an interface to compute toric ideals from a matrix
+// without solving IP-problems.
+
+
+
+#ifndef TORIC_IDEAL_CC
+#define TORIC_IDEAL_CC
+
+
+
+#include "IP_algorithms.h"
+
+
+
+int main(int argc, char *argv[])
+{
+
+  // initialize arguments for the Buchberger algorithm
+  // with default settings
+  BOOLEAN verbose=FALSE;
+  short version=1;
+  short S_pair_criteria=11;
+  double interreduction_percentage=12.0;
+
+
+///////////////////////// parse options /////////////////////////////////////
+
+  short alg_option=0;
+  // no algorithm specified yet
+
+  if(argc>=2 && strcmp(argv[1],"--help"))
+    // argc has to be at least 2
+    // program name, MATRIX file
+  {
+
+    for(short i=1;i<argc-1;i++)
+      // these are the input options
+    {
+
+      if(!strcmp(argv[i],"-v") || !strcmp(argv[i],"--verbose"))
+      {
+        verbose=TRUE;
+        continue;
+        // read next argument
+      }
+
+      if(!strcmp(argv[i],"-V") || !strcmp(argv[i],"-version"))
+      {
+        // check if next argument is a valid version number
+        i++;
+
+        if(!strcmp(argv[i],"1"))
+        {
+          version=1;
+          continue;
+        }
+        if(!strcmp(argv[i],"1a"))
+        {
+          version=0;
+          continue;
+        }
+        if(!strcmp(argv[i],"2"))
+        {
+          version=2;
+          continue;
+        }
+        if(!strcmp(argv[i],"3"))
+        {
+          version=3;
+          continue;
+        }
+
+        // When reaching this line, the version argument was invalid.
+        cerr<<"ERROR: invalid version argument"<<endl
+            <<"Type `toric_ideal --help' for help on options."<<endl;
+        return 1;
+      }
+
+      if(!strcmp(argv[i],"-S"))
+      {
+        // initialize argument to the use of no criteria
+        S_pair_criteria=0;
+
+        do
+        {
+          // Check what S-pair criterion the next argument indicates.
+          // If none: The algorithm is called without S-pair criteria.
+          i++;
+
+          if(i>=argc-2)
+            // file arguments reached
+            break;
+
+          if(!strcmp(argv[i],"RP"))
+          {
+            S_pair_criteria|=1;
+            continue;
+          }
+          if(!strcmp(argv[i],"M"))
+          {
+            S_pair_criteria|=2;
+            continue;
+          }
+          if(!strcmp(argv[i],"F"))
+          {
+            S_pair_criteria|=4;
+            continue;
+          }
+          if(!strcmp(argv[i],"B"))
+          {
+            S_pair_criteria|=8;
+            continue;
+          }
+          if(!strcmp(argv[i],"2"))
+          {
+            S_pair_criteria|=16;
+            continue;
+          }
+
+          // option does not belong to an S-pair criterion
+          break;
+
+        }
+        while(1);
+
+        i--;        // reset counter so that the outer loop
+        continue;   // continues with the just considered argument
+      }
+
+      if(!strcmp(argv[i],"-p"))
+      {
+        // read interreduction percentage
+        i++;
+
+        char** rest;
+        interreduction_percentage=strtod(argv[i],rest);
+        // The function strtod converts a string into a double. As the
+        // specification is not correct, it may cause trouble...
+        // For example, if the argument can be read as a float, the value
+        // of rest should be NULL. This is not the case. Therefore, we can
+        // only check by the following string comparison if a float has been
+        // built. An argument as 15xy is thereby considered as valid
+        // (with interreduction_percentage==15.0).
+
+        if(!(strcmp(argv[i],*rest)))
+          // argument was no float
+        {
+          cerr<<"ERROR: invalid argument for interreduction percentage"<<endl
+              <<"Type `toric_ideal --help' for help on options."<<endl;
+          return 1;
+        }
+
+        continue;
+      }
+
+      if(!strcmp(argv[i],"-alg") || !strcmp(argv[i],"--algorithm"))
+      {
+        // check if next argument is a valid algorithm specification
+        i++;
+
+        if(!strcmp(argv[i],"ct") || !strcmp(argv[i],"pct") ||
+           !strcmp(argv[i],"ect") || !strcmp(argv[i],"pt") ||
+           !strcmp(argv[i],"hs") || !strcmp(argv[i],"du") ||
+           !strcmp(argv[i],"blr"))
+        {
+          alg_option=i;
+          continue;
+        }
+
+        // When reaching this line, the algorithm argument was invalid.
+        cerr<<"ERROR: unkwon algorithm"<<endl
+            <<"Type `toric_ideal --help' for help on options."<<endl;
+        return 1;
+      }
+
+      // When reaching this line, the argument is no legal option.
+      cerr<<"ERROR: invalid option "<<argv[i]<<endl
+          <<"Type `toric_ideal --help' for help on options."<<endl;
+      return 1;
+    }
+
+
+////////////// call algorithms for computing toric ideals /////////////////////
+
+    // open input stream (MATRIX file)
+    ifstream input(argv[argc-1]);
+
+    if(!input)
+    {
+      cerr<<"ERROR: cannot open input file, possibly not found"<<endl;
+      return 1;
+    }
+
+    if(alg_option==0)
+    {
+      cerr<<"ERROR: no valid algorithm specified"<<endl;
+      return 1;
+    }
+
+    // perform specified algorithm to compute a Groebner basis of the
+    // toric ideal defined by the input matrix
+
+    int success;
+    if(!strcmp(argv[alg_option],"ct"))
+      success=Conti_Traverso(argv[argc-1], version, S_pair_criteria,
+                             interreduction_percentage, verbose);
+    if(!strcmp(argv[alg_option],"pct"))
+      success=Positive_Conti_Traverso(argv[argc-1], version,
+                                      S_pair_criteria,
+                                      interreduction_percentage, verbose);
+    if(!strcmp(argv[alg_option],"ect"))
+      success=Elim_Conti_Traverso(argv[argc-1], version, S_pair_criteria,
+                                  interreduction_percentage, verbose);
+    if(!strcmp(argv[alg_option],"pt"))
+      success=Pottier(argv[argc-1], version, S_pair_criteria,
+                      interreduction_percentage, verbose);
+    if(!strcmp(argv[alg_option],"hs"))
+      success=Hosten_Sturmfels(argv[argc-1], version, S_pair_criteria,
+                               interreduction_percentage, verbose);
+    if(!strcmp(argv[alg_option],"du"))
+      success=DiBiase_Urbanke(argv[argc-1], version, S_pair_criteria,
+                              interreduction_percentage, verbose);
+    if(!strcmp(argv[alg_option],"blr"))
+      success=Bigatti_LaScala_Robbiano(argv[argc-1], version,
+                                       S_pair_criteria,
+                                       interreduction_percentage, verbose);
+    if(!success)
+    {
+      cerr<<"ERROR: could not perform required IP-algorithm,\n"
+        "no GROEBNER file created"<<endl;
+      return 1;
+    }
+
+    // Groebner basis successfully computed
+    return 0;
+  }
+
+
+/////////////////////// provide help text ///////////////////////////////////
+
+  // handle the case of "missing" arguments
+
+  if((argc==2) && !strcmp(argv[1],"--help"))
+    // help required
+  {
+    system("less toric_ideal.hlp");
+    return 0;
+  }
+
+  else
+    // invalid arguments
+    cerr<<"USAGE: toric_ideal [options] matrix_file"<<endl
+        <<"Type `toric_ideal --help' for help on options."<<endl;
+
+  return 1;
+
+}
+#endif  // TORIC_IDEAL_CC
diff --git a/IntegerProgramming/toric_ideal.hlp b/IntegerProgramming/toric_ideal.hlp
new file mode 100644
index 0000000..86f69d5
--- /dev/null
+++ b/IntegerProgramming/toric_ideal.hlp
@@ -0,0 +1,201 @@
+USAGE: toric_ideal [options] matrix_file
+
+
+
+DESCRIPTION:
+
+toric_ideal is a program for computing the toric ideal of a matrix A.
+This ideal is always given by the reduced Groebner basis with respect
+to a given term ordering which is computed via Buchberger�s
+algorithm.
+For this purpose, we can use six different algorithms:
+The algorithm of Conti/Traverso (ct) computes the toric ideal of an
+extended matrix. This ideal can be used later for solving integer
+programming problems for given right hand vectors. By eliminating
+auxiliary variables, we can get the toric ideal of the original matrix
+from it. The same is true for the "positive" variant of the
+Conti-Traverso-algorithm (pct) which can only be applied if A has
+nonnegative entries, but should be faster in that case (it computes
+the toric ideal of a smaller extended matrix).
+All other algorithms compute the toric ideal of A itself. Except from
+the elimination version of the Conti-Traverso algorithm (ect), they
+should be more efficient than the algorithm mentionned before. These
+are the algorithms of Pottier (pt), Bigatti/La Scala/Robbiano (blr),
+Hosten/Sturmfels (hs) and Di Biase/Urbanke (du). The last two seem to
+be the fastest in the actual implementation.
+
+
+
+FILE FORMAT:
+
+The input file has to be a MATRIX file. toric_ideal produces a
+GROEBNER file named like the MATRIX file with extensions replaced by
+
+	.GB.<alg>
+
+where GB stands for GROEBNER and <alg> is the abbreviation for the
+used algorithm as above.
+
+A MATRIX file should look as follows:
+
+
+  MATRIX
+
+  columns:
+  <number of columns>
+
+  cost vector:
+  <coefficients of the cost vector>
+
+  rows:
+  <number of rows>
+
+  matrix:
+  <matrix coefficients>
+
+  positive row space vector:
+  <coefficients of row space vector>
+
+
+The last two lines are only needed when toric_ideal is called with the
+algorithms of Hosten/Sturmfels or Bigatti/La Scala/Robbiano, i.e. the
+options
+
+	-alg hs
+or
+	-alg blr
+
+The other algorithms ignore these lines.
+
+Example:
+
+
+  MATRIX
+
+  columns:
+  3
+
+  cost vector:
+  1 1 1
+
+  rows:
+  2
+
+  matrix:
+  1 2 3
+  4 5 6
+
+  positive row space vector:
+  1 2 3
+
+
+A GROEBNER file looks as follows:
+
+
+  GROEBNER
+
+  computed with algorithm:
+  <algorithm name abbreviation>       (* abbreviations as above *)
+  from file(s):                       (* the following four lines are
+  <name of respective MATRIX file>       optional *)
+  computation time:
+  <computation time in seconds>
+
+  term ordering:
+  elimination block
+  <number of elimination variables>
+  <LEX / DEG_LEX                      (* only if number of elimination
+  / DEG_REV_LEX>                         variables >0 *)
+  weighted block
+  <number of weighted variables>
+  <W_LEX / W_REV_LEX                  (* number of weighted variables
+  / W_DEG_LEX / W_DEG_REV_LEX>           should always be >0 *)
+  <weight_vector>
+
+  size:
+  <number of elements>
+
+  Groebner basis:
+  <basis elements>
+
+  <settings for the Buchberger
+   algorithm and compiler settings>  (* optional *)
+
+
+The Groebner basis consists always of binomials of the form x^a - x^b
+where x^a and x^b are relatively prime. Such a binomial can be
+represented by the vector a-b. The basis elements in the GROEBNER file
+are given by the coefficients of this vector representation.
+The settings for Buchberger�s algorithm and the compiler flags are
+produced when the GROEBNER file is generated by a call of toric_ideal
+with the verbose output option
+
+	-v, --verbose
+
+Example (not belonging to the example above):
+
+
+  GROEBNER
+
+  computed with algorithm:
+  du
+
+  term ordering:
+  elimination block:
+  0
+  weighted block:
+  3
+  W_LEX
+  1 2 3
+
+  size:
+  1
+
+  Groebner basis:
+  2 3 -2			    (*  x^2 * y^3 - z^2  *)
+
+
+
+OPTIONS:
+
+ -alg       <alg>,
+--algorithm <alg>         algorithm to use for computing the toric
+                          ideal; <alg> may be
+             ct           for Conti/Traverso,
+             pct          for the positive Conti/Traverso,
+             ect          for Conti/Traverso with elimination,
+             pt           for Pottier,
+             hs           for Hosten/Sturmfels,
+             du           for Di Biase/Urbanke,
+             blr          for Bigatti-LaScal-Robbiano.
+
+ -p         <number>      percentage of new generators to cause an
+                          autoreduction during Buchberger�s algorithm;
+                          <number> may be an arbitrary float, a
+                          negative value allows no intermediate
+                          autoreductions
+			  default is
+                          -p 12.0
+
+ -S [RP] [M] [B] [M] [2]  criteria to use in Buchberger�s algorithm
+                          for discarding unneccessary S-pairs
+             RP           relatively prime leading terms
+             M            Gebauer-Moeller criterion M
+             F            Gebauer-Moeller criterion F
+             B            Gebauer-Moeller criterion B
+             2            Buchberger�s second criterion
+			  default is
+                          -S RP M B
+
+ -v,
+--verbose                 verbose output mode; writes the settings for
+                          Buchberger�s algorithm and the compiler
+                          flags into the output GROEBNER file
+
+-V <number>,
+--version <number>        version of Buchberger�s algorithm to use;
+                          <number> may be 1, 1a, 2 or 3
+			  default is
+                          -V 1
+
+
diff --git a/Makefile.am b/Makefile.am
new file mode 100644
index 0000000..a1841c4
--- /dev/null
+++ b/Makefile.am
@@ -0,0 +1,27 @@
+ACLOCAL_AMFLAGS = -I m4
+
+if ENABLE_FACTORY
+  USE_FACTORY = factory
+endif
+
+SUBDIRS = resources omalloc xalloc $(USE_FACTORY) \
+libpolys gfanlib IntegerProgramming \
+kernel Singular \
+dox emacs desktop
+
+EXTRA_DIST = README README.md README.pkg autogen.sh git-version-gen doxy singular.spec.in
+
+bin_SCRIPTS = libsingular-config
+
+dist-hook:
+	$(srcdir)/git-version-gen $(srcdir)/.tarball-git-version > $(distdir)/.tarball-git-version
+
+
+configheaderdir = ${includedir}/singular
+nodist_configheader_HEADERS = singularconfig.h
+DISTCLEANFILES = $(nodist_configheader_HEADERS)
+
+dist_man1_MANS = doc/Singular.man doc/ESingular.man doc/TSingular.man
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = Singular.pc
diff --git a/Makefile.in b/Makefile.in
new file mode 100644
index 0000000..f15ad4f
--- /dev/null
+++ b/Makefile.in
@@ -0,0 +1,1067 @@
+# Makefile.in generated by automake 1.13.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 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@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+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 = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/configure $(am__configure_deps) \
+	$(srcdir)/_config.h.in $(srcdir)/libsingular-config.in \
+	$(srcdir)/Singular.pc.in $(srcdir)/singular.spec.in \
+	$(dist_man1_MANS) AUTHORS COPYING ChangeLog INSTALL NEWS \
+	README build-aux/ar-lib build-aux/compile \
+	build-aux/config.guess build-aux/config.sub build-aux/depcomp \
+	build-aux/install-sh build-aux/missing build-aux/ylwrap \
+	build-aux/ltmain.sh $(top_srcdir)/build-aux/ar-lib \
+	$(top_srcdir)/build-aux/compile \
+	$(top_srcdir)/build-aux/config.guess \
+	$(top_srcdir)/build-aux/config.sub \
+	$(top_srcdir)/build-aux/install-sh \
+	$(top_srcdir)/build-aux/ltmain.sh \
+	$(top_srcdir)/build-aux/missing
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_append_compile_flags.m4 \
+	$(top_srcdir)/m4/ax_append_flag.m4 \
+	$(top_srcdir)/m4/ax_append_link_flags.m4 \
+	$(top_srcdir)/m4/ax_check_compile_flag.m4 \
+	$(top_srcdir)/m4/ax_check_link_flag.m4 \
+	$(top_srcdir)/m4/ax_compute_relative_paths.m4 \
+	$(top_srcdir)/m4/ax_normalize_path.m4 \
+	$(top_srcdir)/m4/ax_prefix_config_h.m4 \
+	$(top_srcdir)/m4/ax_pthread.m4 \
+	$(top_srcdir)/m4/ax_python_embed.m4 \
+	$(top_srcdir)/m4/ax_python_with_version.m4 \
+	$(top_srcdir)/m4/cpu-check.m4 $(top_srcdir)/m4/dbm-check.m4 \
+	$(top_srcdir)/m4/flags.m4 $(top_srcdir)/m4/flint-check.m4 \
+	$(top_srcdir)/m4/gfanlib-check.m4 \
+	$(top_srcdir)/m4/gmp-check.m4 \
+	$(top_srcdir)/m4/google-perftools.m4 \
+	$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+	$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+	$(top_srcdir)/m4/lt~obsolete.m4 \
+	$(top_srcdir)/m4/mathic-check.m4 $(top_srcdir)/m4/ntl-check.m4 \
+	$(top_srcdir)/m4/options.m4 $(top_srcdir)/m4/p-procs.m4 \
+	$(top_srcdir)/m4/polymake-check.m4 \
+	$(top_srcdir)/m4/readline-check.m4 $(top_srcdir)/configure.ac
+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 = libsingular-config Singular.pc singular.spec
+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__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
+am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" \
+	"$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(configheaderdir)"
+SCRIPTS = $(bin_SCRIPTS)
+AM_V_P = $(am__v_P_ at AM_V@)
+am__v_P_ = $(am__v_P_ at AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_ at AM_V@)
+am__v_GEN_ = $(am__v_GEN_ at AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_ at AM_V@)
+am__v_at_ = $(am__v_at_ at AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+SOURCES =
+DIST_SOURCES =
+RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
+	ctags-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 \
+	tags-recursive uninstall-recursive
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+man1dir = $(mandir)/man1
+NROFF = nroff
+MANS = $(dist_man1_MANS)
+DATA = $(pkgconfig_DATA)
+HEADERS = $(nodist_configheader_HEADERS)
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive	\
+  distclean-recursive maintainer-clean-recursive
+am__recursive_targets = \
+  $(RECURSIVE_TARGETS) \
+  $(RECURSIVE_CLEAN_TARGETS) \
+  $(am__extra_recursive_targets)
+AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
+	cscope distdir dist dist-all distcheck
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \
+	$(LISP)_config.h.in
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+CSCOPE = cscope
+DIST_SUBDIRS = resources omalloc xalloc factory libpolys gfanlib \
+	IntegerProgramming kernel Singular dox emacs desktop
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+distdir = $(PACKAGE)-$(VERSION)
+top_distdir = $(distdir)
+am__remove_distdir = \
+  if test -d "$(distdir)"; then \
+    find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \
+      && rm -rf "$(distdir)" \
+      || { sleep 5 && rm -rf "$(distdir)"; }; \
+  else :; fi
+am__post_remove_distdir = $(am__remove_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
+DIST_TARGETS = dist-gzip
+distuninstallcheck_listfiles = find . -type f -print
+am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \
+  | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$'
+distcleancheck_listfiles = find . -type f -print
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BUILTIN_LIBS = @BUILTIN_LIBS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CDDGMPCPPFLAGS = @CDDGMPCPPFLAGS@
+CDDGMPLDFLAGS = @CDDGMPLDFLAGS@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATA_DIR = @DATA_DIR@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DOC_DIR = @DOC_DIR@
+DOXYGEN = @DOXYGEN@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FACTORY_INCLUDES = @FACTORY_INCLUDES@
+FACTORY_LIBS = @FACTORY_LIBS@
+FGREP = @FGREP@
+FLINT_CFLAGS = @FLINT_CFLAGS@
+FLINT_HOME = @FLINT_HOME@
+FLINT_LIBS = @FLINT_LIBS@
+GMP_CFLAGS = @GMP_CFLAGS@
+GMP_HOME = @GMP_HOME@
+GMP_LIBS = @GMP_LIBS@
+GMP_VERSION = @GMP_VERSION@
+GREP = @GREP@
+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@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NTL_CFLAGS = @NTL_CFLAGS@
+NTL_LIBS = @NTL_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OMALLOC_INCLUDES = @OMALLOC_INCLUDES@
+OMALLOC_LIBS = @OMALLOC_LIBS@
+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@
+PKG_REQUIRE = @PKG_REQUIRE@
+PMCONFIG = @PMCONFIG@
+PM_CFLAGS = @PM_CFLAGS@
+PM_INC = @PM_INC@
+PM_LDFLAGS = @PM_LDFLAGS@
+PM_LIBS = @PM_LIBS@
+POLYMAKE_CXXFLAGS = @POLYMAKE_CXXFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LDFLAGS = @PTHREAD_LDFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
+PYTHON = @PYTHON@
+PYTHON_CSPEC = @PYTHON_CSPEC@
+PYTHON_EXECPREFIX = @PYTHON_EXECPREFIX@
+PYTHON_LSPEC = @PYTHON_LSPEC@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+RANLIB = @RANLIB@
+RESOURCES_INCLUDES = @RESOURCES_INCLUDES@
+RESOURCES_LIBS = @RESOURCES_LIBS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SINGULAR_CFLAGS = @SINGULAR_CFLAGS@
+SI_COUNTEDREF_AUTOLOAD = @SI_COUNTEDREF_AUTOLOAD@
+SI_CPU_I386 = @SI_CPU_I386@
+SI_CPU_IA64 = @SI_CPU_IA64@
+SI_CPU_PPC = @SI_CPU_PPC@
+SI_CPU_SPARC = @SI_CPU_SPARC@
+SI_CPU_X86_64 = @SI_CPU_X86_64@
+STRIP = @STRIP@
+USEPPROCSDYNAMICLD = @USEPPROCSDYNAMICLD@
+USEPPROCSDYNAMICLDFLAGS = @USEPPROCSDYNAMICLDFLAGS@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
+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@
+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@
+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@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+ACLOCAL_AMFLAGS = -I m4
+ at ENABLE_FACTORY_TRUE@USE_FACTORY = factory
+SUBDIRS = resources omalloc xalloc $(USE_FACTORY) \
+libpolys gfanlib IntegerProgramming \
+kernel Singular \
+dox emacs desktop
+
+EXTRA_DIST = README README.md README.pkg autogen.sh git-version-gen doxy singular.spec.in
+bin_SCRIPTS = libsingular-config
+configheaderdir = ${includedir}/singular
+nodist_configheader_HEADERS = singularconfig.h
+DISTCLEANFILES = $(nodist_configheader_HEADERS)
+dist_man1_MANS = doc/Singular.man doc/ESingular.man doc/TSingular.man
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = Singular.pc
+all: _config.h
+	$(MAKE) $(AM_MAKEFLAGS) all-recursive
+
+.SUFFIXES:
+am--refresh: Makefile
+	@:
+$(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) --foreign'; \
+	      $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \
+		&& exit 0; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign 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; else :; fi
+	@if test ! -f $@; then $(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
+libsingular-config: $(top_builddir)/config.status $(srcdir)/libsingular-config.in
+	cd $(top_builddir) && $(SHELL) ./config.status $@
+Singular.pc: $(top_builddir)/config.status $(srcdir)/Singular.pc.in
+	cd $(top_builddir) && $(SHELL) ./config.status $@
+singular.spec: $(top_builddir)/config.status $(srcdir)/singular.spec.in
+	cd $(top_builddir) && $(SHELL) ./config.status $@
+install-binSCRIPTS: $(bin_SCRIPTS)
+	@$(NORMAL_INSTALL)
+	@list='$(bin_SCRIPTS)'; test -n "$(bindir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \
+	fi; \
+	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)'`; \
+	dir='$(DESTDIR)$(bindir)'; $(am__uninstall_files_from_dir)
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+
+distclean-libtool:
+	-rm -f libtool config.lt
+install-man1: $(dist_man1_MANS)
+	@$(NORMAL_INSTALL)
+	@list1='$(dist_man1_MANS)'; \
+	list2=''; \
+	test -n "$(man1dir)" \
+	  && test -n "`echo $$list1$$list2`" \
+	  || exit 0; \
+	echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \
+	$(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \
+	{ for i in $$list1; do echo "$$i"; done;  \
+	if test -n "$$list2"; then \
+	  for i in $$list2; do echo "$$i"; done \
+	    | sed -n '/\.1[a-z]*$$/p'; \
+	fi; \
+	} | 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='$(dist_man1_MANS)'; test -n "$(man1dir)" || exit 0; \
+	files=`{ for i in $$list; do echo "$$i"; done; \
+	} | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \
+	      -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+	dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir)
+install-pkgconfigDATA: $(pkgconfig_DATA)
+	@$(NORMAL_INSTALL)
+	@list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(pkgconfigdir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" || exit 1; \
+	fi; \
+	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|^.*/||'`; \
+	dir='$(DESTDIR)$(pkgconfigdir)'; $(am__uninstall_files_from_dir)
+install-nodist_configheaderHEADERS: $(nodist_configheader_HEADERS)
+	@$(NORMAL_INSTALL)
+	@list='$(nodist_configheader_HEADERS)'; test -n "$(configheaderdir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(configheaderdir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(configheaderdir)" || exit 1; \
+	fi; \
+	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)$(configheaderdir)'"; \
+	  $(INSTALL_HEADER) $$files "$(DESTDIR)$(configheaderdir)" || exit $$?; \
+	done
+
+uninstall-nodist_configheaderHEADERS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(nodist_configheader_HEADERS)'; test -n "$(configheaderdir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	dir='$(DESTDIR)$(configheaderdir)'; $(am__uninstall_files_from_dir)
+
+# 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.
+$(am__recursive_targets):
+	@fail=; \
+	if $(am__make_keepgoing); then \
+	  failcom='fail=yes'; \
+	else \
+	  failcom='exit 1'; \
+	fi; \
+	dot_seen=no; \
+	target=`echo $@ | sed s/-recursive//`; \
+	case "$@" in \
+	  distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+	  *) list='$(SUBDIRS)' ;; \
+	esac; \
+	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"
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-recursive
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	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; \
+	$(am__define_uniq_tagged_files); \
+	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-recursive
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	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"
+cscope: cscope.files
+	test ! -s cscope.files \
+	  || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS)
+clean-cscope:
+	-rm -f cscope.files
+cscope.files: clean-cscope cscopelist
+cscopelist: cscopelist-recursive
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+	-rm -f cscope.out cscope.in.out cscope.po.out cscope.files
+
+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 \
+	    $(am__make_dryrun) \
+	      || test -d "$(distdir)/$$subdir" \
+	      || $(MKDIR_P) "$(distdir)/$$subdir" \
+	      || exit 1; \
+	    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
+	-test -n "$(am__skip_mode_fix)" \
+	|| find "$(distdir)" -type d ! -perm -755 \
+		-exec chmod u+rwx,go+rx {} \; -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__post_remove_distdir)
+
+dist-bzip2: distdir
+	tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2
+	$(am__post_remove_distdir)
+
+dist-lzip: distdir
+	tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz
+	$(am__post_remove_distdir)
+
+dist-xz: distdir
+	tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz
+	$(am__post_remove_distdir)
+
+dist-tarZ: distdir
+	tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
+	$(am__post_remove_distdir)
+
+dist-shar: distdir
+	shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
+	$(am__post_remove_distdir)
+
+dist-zip: distdir
+	-rm -f $(distdir).zip
+	zip -rq $(distdir).zip $(distdir)
+	$(am__post_remove_distdir)
+
+dist dist-all:
+	$(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:'
+	$(am__post_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) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\
+	*.tar.bz2*) \
+	  bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
+	*.tar.lz*) \
+	  lzip -dc $(distdir).tar.lz | $(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) gzip -dc $(distdir).shar.gz | unshar ;;\
+	*.zip*) \
+	  unzip $(distdir).zip ;;\
+	esac
+	chmod -R a-w $(distdir)
+	chmod u+w $(distdir)
+	mkdir $(distdir)/_build $(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" \
+	    $(AM_DISTCHECK_CONFIGURE_FLAGS) \
+	    $(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__post_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:
+	@test -n '$(distuninstallcheck_dir)' || { \
+	  echo 'ERROR: trying to run $@ with an empty' \
+	       '$$(distuninstallcheck_dir)' >&2; \
+	  exit 1; \
+	}; \
+	$(am__cd) '$(distuninstallcheck_dir)' || { \
+	  echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \
+	  exit 1; \
+	}; \
+	test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \
+	   || { 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 $(SCRIPTS) $(MANS) $(DATA) $(HEADERS) _config.h
+installdirs: installdirs-recursive
+installdirs-am:
+	for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(configheaderdir)"; do \
+	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+	done
+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:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+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)
+	-test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
+
+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-man install-nodist_configheaderHEADERS \
+	install-pkgconfigDATA
+
+install-dvi: install-dvi-recursive
+
+install-dvi-am:
+
+install-exec-am: install-binSCRIPTS
+
+install-html: install-html-recursive
+
+install-html-am:
+
+install-info: install-info-recursive
+
+install-info-am:
+
+install-man: install-man1
+
+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: uninstall-binSCRIPTS uninstall-man \
+	uninstall-nodist_configheaderHEADERS uninstall-pkgconfigDATA
+
+uninstall-man: uninstall-man1
+
+.MAKE: $(am__recursive_targets) all install-am install-strip
+
+.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \
+	am--refresh check check-am clean clean-cscope clean-generic \
+	clean-libtool cscope cscopelist-am ctags ctags-am dist \
+	dist-all dist-bzip2 dist-gzip dist-hook dist-lzip 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-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-man1 install-nodist_configheaderHEADERS install-pdf \
+	install-pdf-am install-pkgconfigDATA 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-am uninstall uninstall-am \
+	uninstall-binSCRIPTS uninstall-man uninstall-man1 \
+	uninstall-nodist_configheaderHEADERS uninstall-pkgconfigDATA
+
+
+dist-hook:
+	$(srcdir)/git-version-gen $(srcdir)/.tarball-git-version > $(distdir)/.tarball-git-version
+
+# 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..e69de29
diff --git a/README b/README
new file mode 100644
index 0000000..9448c9d
--- /dev/null
+++ b/README
@@ -0,0 +1,29 @@
+CAS Singular
+============
+
+Singular is a computer algebra system for polynomial computations, with
+special emphasis on commutative and non-commutative algebra, algebraic
+geometry, and singularity theory. It is free and open-source under the
+GNU General Public Licence (See [COPYING]).
+
+* Installation instructions from source code:
+    <https://github.com/Singular/Sources/wiki/Step-by-Step-Installation-Instructions-for-Singular>
+
+* Homepage:
+    <http://www.singular.uni-kl.de/>
+
+* Source code:
+    <https://github.com/Singular/Sources>
+
+* User Manual:
+    <http://www.singular.uni-kl.de/Manual/latest>
+
+* Bug/Issue-Tracker:
+    <http://www.singular.uni-kl.de:8002/trac>
+
+* Singular Wiki:
+    <https://github.com/Singular/Sources/wiki/>
+
+* [Developer and Reference Manual:](@ref main_page)
+   <http://www.mathematik.uni-kl.de/~motsak/dox/html>
+
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..1064bed
--- /dev/null
+++ b/README.md
@@ -0,0 +1,29 @@
+CAS Singular    {#mainpage}
+============
+
+Singular is a computer algebra system for polynomial computations, with
+special emphasis on commutative and non-commutative algebra, algebraic
+geometry, and singularity theory. It is free and open-source under the
+GNU General Public Licence (See [COPYING](@ref copying_page)).
+
+* Installation instructions from source code:
+    <https://github.com/Singular/Sources/wiki/Step-by-Step-Installation-Instructions-for-Singular>
+
+* Homepage:
+    <http://www.singular.uni-kl.de/>
+
+* Source code:
+    <https://github.com/Singular/Sources>
+
+* User Manual:
+    <http://www.singular.uni-kl.de/Manual/latest>
+
+* Bug/Issue-Tracker:
+    <http://www.singular.uni-kl.de:8002/trac>
+
+* Singular Wiki:
+    <https://github.com/Singular/Sources/wiki/>
+
+* [Developer and Reference Manual:](@ref main_page)
+   <http://www.mathematik.uni-kl.de/~motsak/dox/html>
+
diff --git a/README.pkg b/README.pkg
new file mode 100644
index 0000000..d5bf82f
--- /dev/null
+++ b/README.pkg
@@ -0,0 +1,22 @@
+Debian (and Debian based Operating Systems)
+===========================================
+
+The Debian [1] package for Singular is currently maintained by the Debian Science Team [2,3]:
+the git repository for the singular Debian package is at Alioth [4].
+
+[1] https://www.debian.org/
+[2] https://wiki.debian.org/DebianScience
+[3] https://qa.debian.org/developer.php?login=debian-science-maintainers@lists.alioth.debian.org
+[4] http://anonscm.debian.org/cgit/debian-science/packages/singular.git/
+
+
+SINGULAR rpm packages
+=====================
+
+To build Singular rpm packages run (with 4.0.0 replaced by the respective Singular version):
+$ rpmbuild -tb singular-4.0.0.tar.gz
+
+To install the newly created packages run (as superuser, with x86_64 replaced by your architecture
+and 4.0.0 by the respective Singular version):
+$ cd `rpm --eval '%{_topdir}'`/RPMS
+$ rpm -i x86_64/singular-4.0.0-1.x86_64.rpm noarch/singular-common-4.0.0-1.noarch.rpm
diff --git a/Singular.pc.in b/Singular.pc.in
new file mode 100644
index 0000000..944b167
--- /dev/null
+++ b/Singular.pc.in
@@ -0,0 +1,17 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: libSingular
+Description: The Singular high level functionality
+Version: @PACKAGE_VERSION@
+URL: https://github.com/Singular/Sources/
+
+Requires: @PKG_REQUIRE@ libpolys
+Conflicts:
+
+Cflags: -I${includedir} -I${includedir}/singular @SINGULAR_CFLAGS@
+Libs: -L${libdir} -lSingular @USEPPROCSDYNAMICLD@
+Libs.private:
+
diff --git a/Singular/COPYING b/Singular/COPYING
new file mode 100644
index 0000000..7aeaa76
--- /dev/null
+++ b/Singular/COPYING
@@ -0,0 +1,33 @@
+                        SINGULAR version 4-0
+
+                     University of Kaiserslautern
+
+      Department of Mathematics and  Centre for Computer Algebra
+
+           Authors: G.-M. Greuel, G. Pfister, H. Schoenemann
+
+                        Copyright (C) 1986-2014
+
+
+
+                               *NOTICE*
+
+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 ( version 2 or version 3 of the License ).
+
+Some single files have a copyright given within the file:
+Singular/ndbm.* (BSD).
+
+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 (see GPL)
+
+Please send any comments or bug reports to
+<singular at mathematik.uni-kl.de>.
+
diff --git a/Singular/ChangeLog b/Singular/ChangeLog
new file mode 100644
index 0000000..139597f
--- /dev/null
+++ b/Singular/ChangeLog
@@ -0,0 +1,2 @@
+
+
diff --git a/Singular/LIB/JMBTest.lib b/Singular/LIB/JMBTest.lib
new file mode 100644
index 0000000..7da3579
--- /dev/null
+++ b/Singular/LIB/JMBTest.lib
@@ -0,0 +1,1017 @@
+//////////////////////////////////////////////////////////////////////
+version="version JMBTest.lib 4.0.0.0 Jun_2013 "; // $Id: aba2de11ed1e911bbf56c65b39cfd2621b578a49 $
+category="Algebraic Geometry";
+// summary description of the library
+info="
+LIBRARY:   JMBTest.lib  A library for Singular which performs JM basis test.
+AUTHOR:    Michela Ceria, email: michela.ceria at unito.it
+
+SEE ALSO:  JMSConst_lib
+KEYWORDS:  J-marked schemes
+
+OVERVIEW:
+The library performs the J-marked basis test, as described in [CR], [BCLR].
+Such a test is performed via the criterion explained in [BCLR],
+concerning Eliahou-Kervaire polynomials (EK from now on).
+We point out that all the polynomials are homogeneous
+and they must be arranged by degree.
+The fundamental steps are the following:@*
+-construct the Vm polynomials, via the algorithm VConstructor
+explained in [CR];@*
+-construct the Eliahou-Kervaire polynomials defined in [BCLR];@*
+-reduce the  Eliahou-Kervaire polynomials using the Vm's;@*
+-if it exist an Eliahou-Kervaire polynomial such that its reduction
+mod Vm is different from zero, the given one is not a J-Marked basis.
+
+The algorithm terminates only if the ordering is rp.
+Anyway, the number of reduction steps is bounded.
+
+REFERENCES:
+[CR] Francesca Cioffi, Margherita Roggero,Flat Families by Strongly
+Stable Ideals and a Generalization of Groebner Bases,
+J. Symbolic Comput. 46,  1070-1084, (2011).@*
+[BCLR] Cristina Bertone, Francesca Cioffi, Paolo Lella,
+Margherita Roggero, Upgraded methods for the effective
+computation of marked schemes on a strongly stable ideal,
+Journal of Symbolic Computation
+(2012), http://dx.doi.org/10.1016/j.jsc.2012.07.006 @*
+
+PROCEDURES:
+  Minimus(ideal)            minimal variable in an ideal
+  Maximus(ideal)               maximal variable in an ideal
+  StartOrderingV(list,list)     ordering of polynomials as in [BCLR]
+  TestJMark(list)           tests whether we have a J-marked basis
+";
+LIB "qhmoduli.lib";
+LIB "monomialideal.lib";
+LIB "ring.lib";
+////////////////////////////////////////////////////////////////////
+proc mod_init()
+"USAGE:     mod_init();
+RETURN:   struct: jmp
+EXAMPLE:  example  mod_init; shows an example"
+{
+newstruct("jmp", "poly h, poly t");
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  mod_init();
+}
+////////////////////////////////////////////////////////////////////
+proc Terns(list G, int c)
+"USAGE:    Terns(G,c); G list, c int
+RETURN:   list: T
+NOTE:     Input is a list of J-marked  polynomials
+(arranged by degree) and an integer.
+EXAMPLE:  example Terns; shows an example"
+{
+list T=list();
+int z;
+ for(int k=1; k<=size(G[c]);k=k+1)
+    {
+//Loop on G[c] making positions of polynomials in G[c]
+      z=size(T);
+      T=insert(T,list(1,c,k) ,size(T));
+    }
+return(T);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+ring r=0, (x,y,z), rp;
+jmp r1;
+r1.h=z^3;
+r1.t=poly(0);
+jmp r2;
+r2.h=z^2*y;
+r2.t=poly(0);
+jmp r3;
+r3.h=z*y^2 ;
+r3.t=-x^2*y;
+jmp r4;
+r4.h=y^5;
+r4.t=poly(0);
+list G2F=list(list(r1,r2,r3),list(r4));
+Terns(G2F, 1);
+Terns(G2F, 2);
+}
+////////////////////////////////////////////////////////////////////
+proc VConst(list G, int c)
+"USAGE:    VConst(G, c); G list, c int
+RETURN:   list: V
+NOTES: this procedure computes the Vm polynomials following the
+algorithm in [CR],but it only keeps in memory the monomials by
+which the G's must be multplied and their positions.
+EXAMPLE:  example VConst; shows an example"
+{
+jmp f=G[1][1];
+int aJ=deg(f.h);
+// minimal degree of polynomials in G
+//print(aJ);
+list V=list();
+V[1]=Terns(G,1);
+// V[1]=G[1] (keeping in memory only [head, position])
+//print(c-aJ+1);
+int i;
+int j;
+int m;
+list OO;
+jmp p;
+  for(m=2; m<=c-aJ+1; m=m+1)
+  {
+     //print("entro nel form");
+     if(m>size(G))
+        {V[m]=list();
+//If we have not G[m] we insert a list()
+        //print("vuota prima");
+        }
+     else
+        {V[m]=Terns(G,m);
+        //print("piena prima");
+        }
+     for(i=1; i<nvars(basering)+1; i=i+1)
+        {
+          //print("entrata fori");
+          //print(i);
+          for(j=1; j<=size(V[m-1]); j=j+1)
+             {
+                   p=G[V[m-1][j][2]][V[m-1][j][3]];
+                  //print(p.h);
+                  //print(p.t);
+                  //print(var(i));
+                  //print(Minimus(V[m-1][j][1]*p.h));
+               if(var(i)<=Minimus(variables(V[m-1][j][1]*p.h)))
+                  {
+//Can I multiply by the current variable?
+                    //print("minoremin");
+                    //print("fin qui ci sono");
+                     //print(V[m-1][j][1]);
+                     OO=list(var(i)*V[m-1][j][1],V[m-1][j][2],V[m-1][j][3]);
+                    V[m]=insert(V[m], OO ,size(V[m]));
+                  }
+             }
+        }
+  }
+return (V);}
+example
+{ "EXAMPLE:"; echo = 2;
+ ring r=0, (x,y,z), rp;
+jmp r1;
+r1.h=z^3;
+r1.t=poly(0);
+jmp r2;
+r2.h=z^2*y;
+r2.t=poly(0);
+jmp r3;
+r3.h=z*y^2 ;
+r3.t=-x^2*y;
+jmp r4;
+r4.h=y^5;
+r4.t=poly(0);
+list G2F=list(list(r1,r2,r3),list(r4));
+VConst(G2F,4,basering);}
+////////////////////////////////////////////////////////////////////
+proc Minimus(ideal L)
+"USAGE:    Minimus(L); G list, c int
+RETURN:   list: V
+NOTES: it returns the minimal variable generating the ideal L.@*
+The input must be an ideal generated by variables.
+EXAMPLE:  example Minimus; shows an example"
+{
+poly min=L[1];
+int i;
+for(i=2;i<=size(L); i++)
+  {
+    if(L[i]<min){min=L[i];}
+  }
+return(min);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+ ring r=0, (x,y,z), rp;
+ideal I=y,x,z;
+Minimus(I);
+}
+////////////////////////////////////////////////////////////////////
+proc Maximus(ideal L)
+"USAGE:    Maximus(L); G list, c int
+RETURN:   list: V
+NOTES: it returns the maximal variable generating the ideal L.@*
+The input must be an ideal generated by variables.
+EXAMPLE:  example Maximus; shows an example"
+{
+poly max=L[1];
+int i;
+for(i=2;i<=size(L); i++)
+  {
+    if(L[i]>max){max=L[i];}
+  }
+return(max);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+ ring r=0, (x,y,z), rp;
+ideal I=y,x,z;
+Maximus(I);
+}
+////////////////////////////////////////////////////////////////////
+proc GJmpMins(jmp P, jmp Q)
+"USAGE:    GJmpMins(P,Q); P jmp, Q jmp
+RETURN:   int: d
+EXAMPLE:  example GJmpMins; shows an example"
+{
+  int d=1;
+//-1=lower, 0=equal, 1=higher
+//At the beginning suppose Q is higher
+  if(deg(P.h)<deg(Q.h))
+     {
+//Compare degrees;
+      d=-1;
+      //print("Per Grado");
+     }
+  if(deg(P.h)==deg(Q.h))
+     {
+      if(P.h==Q.h)
+         {
+          if(P.t==Q.t)
+              {
+//head=tail
+               d=0;
+               //print("Uguali");
+              }
+         }
+     else
+        {
+//print(Minimus(variables(P.h/gcdMon(P.h,Q.h))));
+//print(Minimus(variables(Q.h/gcdMon(P.h,Q.h))));
+          if(Minimus(variables(P.h/gcdMon(P.h,Q.h)))<Minimus(variables(Q.h/gcdMon(P.h,Q.h))))
+             {
+             d=-1;
+            //print("Per Indice");
+             }
+        }
+     }
+ return(d);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+ ring r=0, (x,y,z), rp;
+jmp p1;
+p1.h=poly(1);
+p1.t=poly(1);
+jmp p2;
+p2.h=x^2;
+p2.t=poly(0);
+jmp p3;
+p3.h=x;
+p3.t=poly(0);
+ GJmpMins(p1, p2);
+ GJmpMins(p2, p3);
+GJmpMins(p1,p1);
+}
+////////////////////////////////////////////////////////////////////
+proc TernCompare(list A, list B, list G)
+"USAGE:    TernCompare(A,B,C); A list, B list, G list
+RETURN:   int: d
+NOTE:     A and B are terns, while G is the given list of
+J-marked polynomials.
+EXAMPLE:  example TernCompare; shows an example"
+{
+int d=-1;
+//Start: A<B
+if(A[1]==B[1])
+  {
+   if(A[2]==B[2]&& A[3]==B[3])
+     {
+      //print("Uguali");
+      d=0;
+     }
+   else
+     {
+jmp g1=G[A[2]][A[3]];
+jmp g2=G[B[2]][B[3]];
+       if(GJmpMins(g1, g2)==1)
+          {
+            //print("Maggiore per il G");
+            d=1;
+          }
+     }
+  }
+else
+  {
+    if(A[1]>B[1])
+      {
+//the ordering MUST be rp
+        //print("Maggiore per Lex");
+        d=1;
+      }
+  }
+return(d);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+ ring r=0, (x,y,z), rp;
+jmp r1;
+r1.h=z^3;
+r1.t=poly(0);
+jmp r2;
+r2.h=z^2*y;
+r2.t=poly(0);
+jmp r3;
+r3.h=z*y^2 ;
+r3.t=-x^2*y;
+jmp r4;
+r4.h=y^5;
+r4.t=poly(0);
+list G2F=list(list(r1,r2,r3),list(r4));
+TernCompare([1,1,1],[x,1,1],G2F);
+}
+////////////////////////////////////////////////////////////////////
+proc MinOfV(list V, list G)
+"USAGE:    Minimal(V,G); V list, G list
+RETURN:   int: R
+NOTE:     Input=lista(terne), G.
+EXAMPLE:  example Minimal; shows an example"
+{
+//Minimal element for a given degree
+list R=list();
+list MIN=V[1];
+int h=1;
+int i;
+for(i=2; i<=size(V); i++)
+    {
+//I consider the first as minimum
+//If I find something smaller I change minimum
+     if(TernCompare(V[i],MIN,G)<=0)
+       {
+        MIN=V[i];
+        h=i;
+       }
+    }
+//Return: [minimum,position of the minimum]
+R=MIN,h;
+return(R);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+ ring r=0, (x,y,z), rp;
+jmp r1;
+r1.h=z^3;
+r1.t=poly(0);
+jmp r2;
+r2.h=z^2*y;
+r2.t=poly(0);
+jmp r3;
+r3.h=z*y^2 ;
+r3.t=-x^2*y;
+jmp r4;
+r4.h=y^5;
+r4.t=poly(0);
+list G2F=list(list(r1,r2,r3),list(r4));
+MinOfV(VConst(G2F,4,basering)[1],G2F);
+}
+////////////////////////////////////////////////////////////////////
+proc OrderingV(list V,list G,list R)
+"USAGE:   OrderingV(V,G,R); V list, G list, R list
+RETURN:   list: R
+NOTE:     Input: Vm,G,emptylist
+EXAMPLE:  example OrderingV; shows an example"
+{
+//Order V[m]
+//R  will contain results but at the beginning it is empty
+list M=list();
+if(size(V)==1)
+  {
+    R=insert(R,V[1],size(R));
+  }
+else
+  {
+   M=MinOfV(V,G);
+   R=insert(R,M[1],size(R));
+   V=delete(V,M[2]);
+//recursive call
+   R=OrderingV(V,G,R);
+  }
+return(R);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+ ring r=0, (x,y,z), rp;
+jmp r1;
+r1.h=z^3;
+r1.t=poly(0);
+jmp r2;
+r2.h=z^2*y;
+r2.t=poly(0);
+jmp r3;
+r3.h=z*y^2;
+r3.t=-x^2*y;
+jmp r4;
+r4.h=y^5;
+r4.t=poly(0);
+list G2F=list(list(r1,r2,r3),list(r4));
+OrderingV(VConst(G2F,4,basering)[1],G2F,list());
+}
+////////////////////////////////////////////////////////////////////
+proc StartOrderingV(list V,list G)
+"USAGE:   StartOrdina(V,G); V list, G list
+RETURN:   list: R
+NOTE:     Input Vm,G. This procedure uses OrderingV to get
+the ordered polynomials as in [BCLR].
+EXAMPLE:  example StartOrderingV; shows an example"
+{
+ return(OrderingV(V,G, list()));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+ ring r=0, (x,y,z), rp;
+jmp r1;
+r1.h=z^3;
+r1.t=poly(0);
+jmp r2;
+r2.h=z^2*y;
+r2.t=poly(0);
+jmp r3;
+r3.h=z*y^2;
+r3.t=-x^2*y;
+jmp r4;
+r4.h=y^5;
+r4.t=poly(0);
+list G2F=list(list(r1,r2,r3),list(r4));
+StartOrderingV(VConst(G2F,4,basering)[1],G2F);
+}
+////////////////////////////////////////////////////////////////////
+proc Multiply(list L, list G)
+"USAGE:    moltiplica(L,G); L list, G list
+RETURN:   jmp: K
+NOTE:     Input: a 3-ple,G. It performs the product associated
+to the 3-uple.
+EXAMPLE:  example Multiply; shows an example"
+{
+jmp g=G[L[2]][L[3]];
+jmp K;
+K.h=L[1]*g.h;
+K.t=L[1]*g.t;
+ return(K);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+ ring r=0, (x,y,z), rp;
+ list P=x^2,1,1;
+jmp r1;
+r1.h=z^3;
+r1.t=poly(0);
+jmp r2;
+r2.h=z^2*y;
+r2.t=poly(0);
+jmp r3;
+r3.h=z*y^2 ;
+r3.t=-x^2*y;
+jmp r4;
+r4.h=y^5;
+r4.t=poly(0);
+list G2F=list(list(r1,r2,r3),list(r4));
+Multiply(P,G2F);
+}
+////////////////////////////////////////////////////////////////////
+proc IdealOfV(list V)
+"USAGE:    IdealOfV(V); V list
+RETURN:   ideal: I
+NOTES: this procedure takes a list of Vm's of a certain degree
+and construct their ideal, multiplying the head by the weighted
+variable t.
+EXAMPLE:  example IdealOfV; shows an example"
+{
+ideal I=0;
+int i;
+if (size(V)!=0)
+  {
+   list M=list();
+jmp g;
+   for(i=1; i<= size(V); i++)
+       {
+         g=V[i];
+         g.h=t*g.h;
+         M[i]=g.h+g.t;
+       }
+   I=M[1..size(M)];
+//print("IdealOfV");
+  //I=std(I);
+  }
+return(I);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+ ring r=0, (x,y,z,t), rp;
+jmp r1;
+r1.h=z^3;
+r1.t=poly(0);
+jmp r2;
+r2.h=z^2*y;
+r2.t=poly(0);
+jmp r3;
+r3.h=z*y^2 ;
+r3.t=-x^2*y;
+jmp r4;
+r4.h=y^5;
+r4.t=poly(0);
+list G2F=list(list(r1,r2,r3),list(r4));
+IdealOfV(G2F[1]);
+}
+////////////////////////////////////////////////////////////////////
+proc NewWeight(int n)
+"USAGE:    NewWeight(n); n int
+RETURN:   intvec: u
+EXAMPLE:  example NewWeight; shows an example"
+{
+intvec u=0;
+u[n]=1;
+return(u);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+ NewWeight(3);
+}
+////////////////////////////////////////////////////////////////////
+proc FinalVm(list V1 , list G1 ,def r)
+"USAGE:     FinalVm(V1, G1, r);  V1 list,  G1 list , r
+RETURN:   intvec: u
+EXAMPLE:  example NewWeight; shows an example"
+{
+//multiply and reduce, degree by degree
+intvec u=NewWeight(nvars(r)+1);
+list L=ringlist(r);
+L[2]=insert(L[2],"t",size(L[2]));
+//print(L[2]);
+list ordlist="a",u;
+L[3]=insert(L[3],ordlist,0);
+def H=ring(L);
+//print(V1);
+//print(G1);
+list M=list();
+jmp p;
+list N;
+poly q;
+poly s;
+int i;
+int j;
+for(i=1; i<=size(G1); i++)
+   {
+           N=list();
+           for(j=1; j<=size(G1[i]); j++)
+              {
+                p=G1[i][j];
+                q=p.h;
+                s=p.t;
+                N[j]=list(q,s);
+               }
+           M[i]=N;
+    }
+p.h=poly(0);
+p.t=poly(0);
+setring H;
+list R=list();
+list S=list();
+//print("anello definito");
+def V=imap(r,V1);
+//def G=imap(r,G1);
+//print(V);
+def MM=imap(r,M);
+list G=list();
+list N=list();
+for(i=1; i<=size(MM); i++)
+   {
+           for(j=1; j<=size(MM[i]); j++)
+              {
+                p.h=MM[i][j][1];
+                p.t=MM[i][j][2];
+                N[j]=p;
+               }
+           G[i]=N;
+    }
+ideal I=0;
+jmp LL;
+jmp UU;
+ for(i=1; i<=size(V);i++)
+    {
+       R[i]=list();
+       S[i]=list();
+       I=0;
+       for(j=1;j<=size(V[i]); j++)
+          {
+            LL=Multiply(V[i][j],G);
+            LL.t=reduce(t*LL.t,I);
+//I only reduce the tail
+              LL.t=subst(LL.t,t,1);
+              S[i]=insert(S[i],LL,size(S[i]));
+              LL.h=t*LL.h;
+            R[i]=insert(R[i],LL,size(R[i]));
+             UU=R[i][j];
+              I=I+ideal(UU.h+UU.t);
+              attrib(I,"isSB",1);
+          }
+    }
+list M=list();
+poly q;
+poly s;
+for(i=1; i<=size(S); i++)
+   {
+           N=list();
+           for(j=1; j<=size(S[i]); j++)
+              {
+                p=S[i][j];
+                q=p.h;
+                s=p.t;
+                N[j]=list(q,s);
+               }
+           M[i]=N;
+    }
+p.h=poly(0);
+p.t=poly(0);
+setring r;
+def MM=imap(H,M);
+list MMM=list();
+for(i=1; i<=size(MM); i++)
+   {
+           N=list();
+           for(j=1; j<=size(MM[i]); j++)
+              {
+                p.h=MM[i][j][1];
+                p.t=MM[i][j][2];
+                N[j]=p;
+               }
+           MMM[i]=N;
+    }
+return(MMM);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+ ring r=0, (x,y,z), rp;
+jmp r1;
+r1.h=z^3;
+r1.t=poly(0);
+jmp r2;
+r2.h=z^2*y;
+r2.t=poly(0);
+jmp r3;
+r3.h=z*y^2 ;
+r3.t=-x^2*y;
+jmp r4;
+r4.h=y^5;
+r4.t=poly(0);
+list G2F=list(list(r1,r2,r3),list(r4));
+ FinalVm(VConst(G2F,6,r) , G2F, r);
+}
+////////////////////////////////////////////////////////////////////
+proc ConstructorMain(list G, int c,def r)
+"USAGE:    Costruttore(G,c); G list, c int
+RETURN:   list: R
+NOTE:     At the end separated by degree.
+EXAMPLE:  example Costruttore; shows an example"
+{
+list V=list();
+V= VConst(G,c);
+//print("VConst");
+//V non ordered
+list L=list();
+list R=list();
+int i;
+// head, position
+//order the different degrees
+for(i=1; i<=size(V); i++)
+   {
+    L[i]=StartOrderingV(V[i], G);
+   }
+//multiply and reduce
+//print("Ordinare");
+R=FinalVm(L, G, r);
+//print("FinalVm");
+return(R);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+ ring r=0, (x,y,z), rp;
+jmp r1;
+r1.h=z^3;
+r1.t=poly(0);
+jmp r2;
+r2.h=z^2*y;
+r2.t=poly(0);
+jmp r3;
+r3.h=z*y^2 ;
+r3.t=-x^2*y;
+jmp r4;
+r4.h=y^5;
+r4.t=poly(0);
+list G2F=list(list(r1,r2,r3),list(r4));
+ConstructorMain(G2F,6,r);
+}
+////////////////////////////////////////////////////////////////////
+proc EKCouples(jmp A, jmp B)
+"USAGE:    CoppiaEK(A,B); A list, B list
+RETURN:   list: L
+NOTE:     At the end the monomials involved by EK.
+EXAMPLE:  example EKCouples; shows an example"
+{
+poly E;
+list L=0,0;
+string s=varstr(basering);
+list VVV=varstr(basering);
+//L will contain results
+poly h=Minimus(variables(A.h));
+//print(h);
+int l=findvars(h,1)[2][1];
+if(l!=nvars(basering))
+ {
+//print("vero");
+//print(l);
+  for(int j=l+1;j<=nvars(basering); j++)
+   {
+    //print("entrata");
+    //print(var(j));
+    E=var(j)*A.h/B.h;
+//Candidate for * product
+    //print(E);
+    if(E!=0)
+      {
+        //print("primo if passato");
+        if(Minimus(variables(B.h))>=Maximus(variables(E)))
+           {
+//Does it work with * ?
+            //print("secondo if passato");
+            L[1]=j;
+            L[2]=E;
+            break;
+           }
+      }
+   }
+  }
+return (L);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+ ring r=0, (x,y,z), rp;
+jmp A;
+A.h=y*z^2;
+A.t=poly(0);
+jmp B;
+B.h=y^2*z;
+B.t=poly(0);
+EKCouples(A,B);
+EKCouples(B,A);
+}
+////////////////////////////////////////////////////////////////////
+proc EKPolys(list G)
+"USAGE:    PolysEK(G); G list
+RETURN:   list: EK, list: D
+NOTE:     At the end EK polynomials and their degrees
+
+EXAMPLE:  example PolysEK; shows an example"
+{
+list D=list();
+list C=list();
+list N=0,0;
+list EK=list();
+int i;
+int j;
+int k;
+int l;
+jmp p;
+for(i=1; i<=size(G); i++)
+   {
+     for(j=1; j<=size(G[i]); j++)
+        {
+         for(k=1; k<=size(G); k++)
+             {
+               for(l=1; l<=size(G[k]); l++)
+                  {
+                     if(i!=k||j!=l)
+                       {
+//Loop on polynomials
+                        C=EKCouples(G[i][j], G[k][l]);
+//print("coppia");
+                        if(C[2]!=0)
+                          {
+                           C=insert(C,list(i,j,k,l),size(C));
+                           EK=insert(EK,C,size(EK));
+                           p=G[k][l];
+                           D=insert(D,deg(C[2]*p.h),size(D));
+                          }
+                       }
+                  }
+             }
+        }
+   }
+//Double Return
+return(EK, D);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring r=0, (x,y,z), rp;
+jmp r1;
+r1.h=z^3;
+r1.t=poly(0);
+jmp r2;
+r2.h=z^2*y;
+r2.t=poly(0);
+jmp r3;
+r3.h=z*y^2;
+r3.t=-x^2*y;
+jmp r4;
+r4.h=y^5;
+r4.t=poly(0);
+list G2F=list(list(r1,r2,r3),list(r4));
+EKPolys(G2F);
+}
+////////////////////////////////////////////////////////////////////
+proc EKPolynomials(list EK, list G)
+"USAGE:     EKPolynomials(EK,G); EK list, G list
+RETURN:   list: p
+NOTE:     At the end I obtain the EK polynomials and
+their degrees.
+EXAMPLE:  example SpolyEK; shows an example"
+{
+jmp u=G[EK[3][1]][EK[3][2]];
+jmp q=G[EK[3][3]][EK[3][4]];
+return(var(EK[1])*(u.h+u.t)-EK[2]*(q.h+q.t));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+ ring r=0, (x,y,z), rp;
+jmp r1;
+r1.h=z^3;
+r1.t=poly(0);
+jmp r2;
+r2.h=z^2*y;
+r2.t=poly(0);
+jmp r3;
+r3.h=z*y^2;
+r3.t=-x^2*y;
+jmp r4;
+r4.h=y^5;
+r4.t=poly(0);
+list G2F=list(list(r1,r2,r3),list(r4));
+list EK,D=EKPolys(G2F);
+EKPolynomials(EK[1],G2F);
+}
+////////////////////////////////////////////////////////////////////
+proc TestJMark(list G1,def r)
+"USAGE:    TestJMark(G);  G list
+RETURN:    int: i
+NOTE:
+This procedure performs J-marked basis test.@*
+The input is a list of J-marked polynomials (jmp) arranged
+by degree, so G1 is a list of list.@*
+The output is a boolean evaluation:
+True=1/False=0
+EXAMPLE:  example TestJMark; shows an example"
+{int flag=1;
+if(size(G1)==1 && size(G1[1])==1)
+ {
+  //Hypersurface
+  print("Only One Polynomial");
+  flag=1;
+ }
+else
+  {
+   int d=0;
+   list EK,D=EKPolys(G1);
+//print("PolysEK");
+   //I found EK couples
+   int massimo=Max(D);
+   list V1=ConstructorMain(G1,massimo,r);
+//print("Costruttore");
+//print(V1);
+   jmp mi=V1[1][1];
+   int minimo=Min(deg(mi.h));
+   intvec u=NewWeight(nvars(r)+1);
+list L=ringlist(r);
+L[2]=insert(L[2],"t",size(L[2]));
+//print(L[2]);
+list ordlist="a",u;
+L[3]=insert(L[3],ordlist,0);
+def H=ring(L);
+list JJ=list();
+jmp pp;
+jmp qq;
+int i;
+int j;
+list NN;
+for(i=size(V1);i>0;i--)
+    {
+     NN=list();
+     for(j=size(V1[i]);j>0;j--)
+         {
+          //print(j);
+          pp=V1[i][j];
+          NN[j]=list(pp.h,pp.t);
+          }
+//print(NN);
+JJ[i]=NN;
+//print(JJ[i]);
+//print(i);
+    }
+//print(JJ);
+list KK=list();
+list UU=list();
+//jmp qq;
+for(i=size(G1);i>0;i--)
+    {
+     for(j=size(G1[i]);j>0;j--)
+         {
+          //print(j);
+          qq=G1[i][j];
+          UU[j]=list(qq.h,qq.t);
+          }
+//print(UU);
+KK[i]=UU;
+    }
+setring H;
+//I defined the new ring with the weighted
+//variable t
+poly p;
+//print("anello definito");
+def JJJ=imap(r,JJ);
+def EK=imap(r,EK);
+//print(flag);
+//imap(r,D);
+list V=list();
+jmp fp;
+//int i;
+//int j;
+list N;
+for(i=size(JJJ); i>0; i--)
+   {
+           N=list();
+           for(j=size(JJJ[i]); j>0; j--)
+              {
+                fp.h=JJJ[i][j][1];
+                fp.t=JJJ[i][j][2];
+                N[j]=fp;
+               }
+           V[i]=N;
+            }
+//print(V);
+def KKJ=imap(r,KK);
+list G=list();
+list U=list();
+for(i=1; i<=size(KKJ); i++)
+   {
+           for(j=1; j<=size(KKJ[i]); j++)
+              {
+                fp.h=KKJ[i][j][1];
+                fp.t=KKJ[i][j][2];
+                U[j]=fp;
+               }
+           G[i]=U;
+    }
+// print(V);
+//print(G);
+//I imported in H everithing I need
+poly q;
+ideal I;
+   for(j=1; j<=size(EK);j++)
+      {
+       d=D[j];
+       p=EKPolynomials(EK[j],G);
+       //print("arrivo");
+       I=IdealOfV(V[d-minimo+1]);
+attrib(I,"isSB",1);
+//print(I);
+q=reduce(t*p,I);
+//print(I[1]);
+//print(t*p);
+q=subst(q,t,1);
+//I reduce all the EK polynomials
+//       q=RiduzPoly(V[d-minimo+1], p);
+       if(q!=0)
+         {
+//check whether reduction is 0
+          print("NOT A BASIS");
+         flag=0;
+          break;
+         }
+     }
+  }
+//print(flag);
+setring r;
+//typeof(flag);
+return(flag);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+ ring r=0, (x,y,z), rp;
+jmp r1;
+r1.h=z^3;
+r1.t=poly(0);
+jmp r2;
+r2.h=z^2*y;
+r2.t=poly(0);
+jmp r3;
+r3.h=z*y^2 ;
+r3.t=-x^2*y;
+jmp r4;
+r4.h=y^5;
+r4.t=poly(0);
+list G2F=list(list(r1,r2,r3),list(r4));
+TestJMark(G2F,r);
+}
diff --git a/Singular/LIB/JMSConst.lib b/Singular/LIB/JMSConst.lib
new file mode 100644
index 0000000..9abf212
--- /dev/null
+++ b/Singular/LIB/JMSConst.lib
@@ -0,0 +1,1395 @@
+//////////////////////////////////////////////////////////////////////
+version="version JMSConst.lib 4.0.0.0 Jun_2013 "; // $Id: 20df0a1f767abd611fe1c4b9afd9654a8af4556b $
+category="Algebraic Geometry";
+// summary description of the library
+info="
+LIBRARY:   JMSConst.lib  A library for Singular which constructs J-Marked Schemes.
+AUTHOR:    Michela Ceria, email: michela.ceria at unito.it
+
+SEE ALSO:  JMBTest_lib
+
+KEYWORDS:  J-marked schemes, Borel ideals
+
+OVERVIEW:
+The library performs the J-marked computation, as described in [BCLR].
+As in JMBTest.lib we construct the V polynomials and we reduce the EK
+polynomials w.r.t. them, putting the coefficients as results.
+
+
+The algorithm terminates only if the ordering is rp.
+Anyway, the number of reduction steps is bounded.
+
+REFERENCES:
+[CR] Francesca Cioffi, Margherita Roggero,Flat Families by Strongly
+Stable Ideals and a Generalization of Groebner Bases,
+J. Symbolic Comput. 46,  1070-1084, (2011).@*
+[BCLR] Cristina Bertone, Francesca Cioffi, Paolo Lella,
+Margherita Roggero, Upgraded methods for the effective
+computation of marked schemes on a strongly stable ideal,
+Journal of Symbolic Computation
+(2012), http://dx.doi.org/10.1016/j.jsc.2012.07.006 @*
+
+
+
+SEE ALSO: JMSConst_lib
+PROCEDURES:
+BorelCheck(ideal,r)       checks whether the given ideal is Borel
+JMarkedScheme(list, list, list, int)  computes authomatically all the J-marked scheme
+";
+LIB "presolve.lib";
+LIB "qhmoduli.lib";
+LIB "monomialideal.lib";
+////////////////////////////////////////////////////////////////////
+proc BorelCheck(ideal Borid,def r)
+"USAGE:    BorelCheck(Borid,r); Borid ideal, r ring
+RETURN:   int: d
+NOTE:     Input must be a monomial ideal.
+The procedure checks whether the Borel moves produce elements belonging to Borid.
+EXAMPLE:  example QuanteC; shows an example"
+{
+int n= nvars(r);
+int b=1;
+int i=1;
+int k;
+intvec v;
+int j;
+int u;
+//b =bool. b=1 true; b=0 false
+//we suppose true!
+//i=counter on the elements of Borid
+int s= size(Borid);
+while(b && i<=s)
+      {
+        v=leadexp(Borid[i]);
+        j=1;
+        u=size(v);
+        while(b && j<=u)
+             {
+               if(v[j]!=0)
+                 {
+                   k=j+1;
+                  while(b && k<=n)
+                       {
+                         b=(reduce(Borid[i]*var(k)/var(j),std(Borid))==0);
+                         k++;
+                        }
+                 }
+              j++;
+             }
+      i++;
+      }
+return(b);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+ ring r=0, (x,y,z),rp;
+ ideal Borid=y^2*z,y*z^2,z^3,y^5;
+BorelCheck(Borid,r);
+}
+////////////////////////////////////////////////////////////////////
+proc ArrangeBorel(ideal Borid)
+"USAGE:    ArrangeBorel(Borid); Borid ideal
+RETURN:   list: Input
+NOTE:     Input must be a monomial ideal, increasingly ordered by degree.
+The procedure groups the monomials in a list of lists as needed to compute J-marked scheme.
+// It also returns a list containing the size of every sublist generated.
+EXAMPLE:  example ArrangeBorel; shows an example"
+{
+list Input;
+int j=1;
+//list numero=1;
+Input[1]=list(Borid[1]);
+for(int i=2; i<=size(Borid); i++)
+   {
+     if(deg(Borid[i])!=deg(Borid[i-1]))
+        {
+         j++;
+         Input[j]=list();
+        // numero[j]=0;
+        }
+Input[j]=insert(Input[j],Borid[i],size(Input[j]));
+//numero[j]=numero[j]+1;
+   }
+return(Input);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+ ring r=0, (x,y,z),rp;
+ ideal Borid=y^2*z,y*z^2,z^3,y^5;
+ArrangeBorel(Borid);
+}
+////////////////////////////////////////////////////////////////////
+proc NumNewVar(list B, list NumN)
+"USAGE:    NumNewVar(B,NumN); B list, NumN list
+RETURN:   int: d
+NOTE: B is the grouped Borel, while NumN is a list containing the cardinalities of the obtained groups.
+EXAMPLE:  example NumNewVar; shows an example"
+{
+int d;
+int j;
+int i;
+for(i=1; i<=size(B); i++)
+   {
+     d=d+size(B[i])*NumN[i];
+    }
+return(d);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+ ring r=0, (x,y,z),rp;
+ ideal Borid=y^2*z,y*z^2,z^3,y^5;
+list B= ArrangeBorel(Borid);
+list NumN=7,8;
+NumNewVar(B,NumN);
+}
+////////////////////////////////////////////////////////////////////
+proc NewTails(ideal NI, int s)
+"USAGE:    NewTails(NI,s); NI ideal, s int
+RETURN:   list: M
+NOTE:     The procedure construct the tails of the required unknown J-marked polynomials.
+EXAMPLE:  example NewTails; shows an example"
+{
+ poly p=0;
+for(int i=1; i<=size(NI); i++)//Loop on the Groebner escalier
+   {
+    p=p+NI[i]*c(i+s); //multiply by c's
+   }
+int u=size(NI);
+list M=p,u;
+return(M);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+ ring r=(0,c(1..7)), (x,y,z),rp;
+ ideal NI=x^2,x*y,y^2,z^2;
+ NewTails(NI,3);
+}
+////////////////////////////////////////////////////////////////////
+proc ArrangeTails(list Q)
+"USAGE:    ArrangeTails(Q); Q list
+RETURN:   list: Q
+NOTE:     Constructs the final list of J-marked polynomials.
+EXAMPLE:  example FormaInput; shows an example"
+{
+jmp m=Q[1][1];
+jmp M=Q[size(Q)][1];
+int minimo=deg(m.h);
+int massimo=deg(M.h);
+//print(minimo);
+//print(massimo);
+int i=2;
+jmp qi;
+while(i<=size(Q))
+     {
+       //print("entro nel ciclo");
+       //print(i);
+       qi=Q[i][1];
+       if(deg(qi.h)!=minimo+1)
+         {
+          //print("qui riempire");
+          //print(i);
+          Q=insert(Q,list(),i-1);//Insert empty list for all intermediate degree between the minimum and the maximum, not having polynomials.
+          //print(Q);
+         }
+       minimo=minimo+1;
+       i=i+1;
+       //print("ora ho");
+       //print(minimo);
+       //print(i);
+     }
+return(Q);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+ring r=0, (x,y,z),rp;
+ ideal Borid=y^2*z,y*z^2,z^3,y^5;
+attrib(Borid,"isSB",1);
+    list B=ArrangeBorel(Borid);
+    list NumN;
+    list N;
+    int i;
+    int d;
+    for(i=1;i<=size(B);i++)
+       {
+        d=deg(B[i][1]);
+        N[i]=kbase(Borid,d);
+        NumN[i]=size(N[i]);
+       }
+int qc=NumNewVar(B, NumN);
+//Now I must define the NEW RING, putting the c parameters inside.
+list L=ringlist(r);
+list L2;
+L2[1]=L[1];
+L2[2]=list();
+for(i=qc;i>=1;i--)
+    {
+     L2[2][i]="c("+string(i)+")";
+    }
+L2[3]=list(list("rp",qc));
+L2[4]=L[4];
+L[1]=L2;
+def K=ring(L);
+setring(K);
+ideal Borid=imap(r,Borid);
+list N=imap(r,N);
+list B=imap(r,B);
+//NumN contains only scalars so I do not imap it
+int j;
+list Q;
+int s;
+list M;
+jmp pp;
+for(i=1;i<=size(B);i++)
+    {
+      Q[i]=list();
+     for(j=1;j<=size(B[i]);j++)
+        {
+          M=NewTails(N[i],s);
+          pp.h=B[i][j];
+          pp.t=M[1];
+          Q[i][j]=pp;
+          s=s+M[2];
+          //print(s);
+        }
+    }
+list P=ArrangeTails(Q);
+int ll;
+int uu;
+jmp Pp;
+for(ll=1; ll<=size(P);ll++)
+   {
+    for(uu=1;uu<=size(P[ll]);uu++)
+       {Pp=P[ll][uu]; Pp.h; Pp.t;}
+   }
+}
+////////////////////////////////////////////////////////////////////
+proc mod_init()
+"USAGE:     mod_init();
+RETURN:   struct: jmp
+EXAMPLE:  example  mod_init; shows an example"
+{
+newstruct("jmp", "poly h, poly t");
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  mod_init();
+}
+////////////////////////////////////////////////////////////////////
+proc Terns(list G, int c)
+"USAGE:    Terns(G,c); G list, c int
+RETURN:   list: T
+NOTE:     Input is a list of J-marked  polynomials
+(arranged by degree) and an integer.
+EXAMPLE:  example Terns; shows an example"
+{
+list T=list();
+int z;
+ for(int k=1; k<=size(G[c]);k=k+1)
+    {
+//Loop on G[c] making positions of polynomials in G[c]
+      z=size(T);
+      T=insert(T,list(1,c,k) ,size(T));
+    }
+return(T);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+ring r=0, (x,y,z), rp;
+jmp r1;
+r1.h=z^3;
+r1.t=poly(0);
+jmp r2;
+r2.h=z^2*y;
+r2.t=poly(0);
+jmp r3;
+r3.h=z*y^2 ;
+r3.t=-x^2*y;
+jmp r4;
+r4.h=y^5;
+r4.t=poly(0);
+list G2F=list(list(r1,r2,r3),list(r4));
+Terns(G2F, 1);
+Terns(G2F, 2);
+}
+////////////////////////////////////////////////////////////////////
+proc VConst(list G, int c)
+"USAGE:    VConst(G, c); G list, c int
+RETURN:   list: V
+NOTES: this procedure computes the Vm polynomials following the
+algorithm in [CR],but it only keeps in memory the monomials by
+which the G's must be multplied and their positions.
+EXAMPLE:  example VConst; shows an example"
+{
+jmp f=G[1][1];
+int aJ=deg(f.h);
+// minimal degree of polynomials in G
+//print(aJ);
+list V=list();
+V[1]=Terns(G,1);
+// V[1]=G[1] (keeping in memory only [head, position])
+//print(c-aJ+1);
+int i;
+int j;
+int m;
+list OO;
+jmp p;
+  for(m=2; m<=c-aJ+1; m=m+1)
+  {
+     //print("entro nel form");
+     if(m>size(G))
+        {V[m]=list();
+//If we have not G[m] we insert a list()
+        //print("vuota prima");
+        }
+     else
+        {V[m]=Terns(G,m);
+        //print("piena prima");
+        }
+     for(i=1; i<nvars(basering)+1; i=i+1)
+        {
+          //print("entrata fori");
+          //print(i);
+          for(j=1; j<=size(V[m-1]); j=j+1)
+             {
+                   p=G[V[m-1][j][2]][V[m-1][j][3]];
+                  //print(p.h);
+                  //print(p.t);
+                  //print(var(i));
+                  //print(Minimus(V[m-1][j][1]*p.h));
+               if(var(i)<=Minimus(variables(V[m-1][j][1]*p.h)))
+                  {
+//Can I multiply by the current variable?
+                    //print("minoremin");
+                    //print("fin qui ci sono");
+                     //print(V[m-1][j][1]);
+                     OO=list(var(i)*V[m-1][j][1],V[m-1][j][2],V[m-1][j][3]);
+                    V[m]=insert(V[m], OO ,size(V[m]));
+                  }
+             }
+        }
+  }
+return (V);}
+example
+{ "EXAMPLE:"; echo = 2;
+ ring r=0, (x,y,z), rp;
+jmp r1;
+r1.h=z^3;
+r1.t=poly(0);
+jmp r2;
+r2.h=z^2*y;
+r2.t=poly(0);
+jmp r3;
+r3.h=z*y^2 ;
+r3.t=-x^2*y;
+jmp r4;
+r4.h=y^5;
+r4.t=poly(0);
+list G2F=list(list(r1,r2,r3),list(r4));
+VConst(G2F,4,basering);}
+////////////////////////////////////////////////////////////////////
+proc Minimus(ideal L)
+"USAGE:    Minimus(L); G list, c int
+RETURN:   list: V
+NOTES: it returns the minimal variable generating the ideal L;
+input must be an ideal generated by variables.
+EXAMPLE:  example Minimus; shows an example"
+{
+poly min=L[1];
+int i;
+for(i=2;i<=size(L); i++)
+  {
+    if(L[i]<min){min=L[i];}
+  }
+return(min);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+ ring r=0, (x,y,z), rp;
+ideal I=y,x,z;
+Minimus(I);
+}
+////////////////////////////////////////////////////////////////////
+proc Maximus(ideal L)
+"USAGE:    Maximus(L); G list, c int
+RETURN:   list: V
+NOTES: it returns the maximal variable generating the ideal L
+input must be an ideal generated by variables.
+EXAMPLE:  example Maximus; shows an example"
+{
+poly max=L[1];
+int i;
+for(i=2;i<=size(L); i++)
+  {
+    if(L[i]>max){max=L[i];}
+  }
+return(max);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+ ring r=0, (x,y,z), rp;
+ideal I=y,x,z;
+Maximus(I);
+}
+////////////////////////////////////////////////////////////////////
+proc GPolyMin(jmp P, jmp Q)
+"USAGE:    GPolyMin(P,Q); P jmp, Q jmp
+RETURN:   int: d
+EXAMPLE:  example GPolyMin; shows an example"
+{
+  int d=1;
+//-1=lower, 0=equal, 1=higher
+//At the beginning suppose Q is higher
+  if(deg(P.h)<deg(Q.h))
+     {
+//Compare degrees;
+      d=-1;
+      //print("Per Grado");
+     }
+  if(deg(P.h)==deg(Q.h))
+     {
+      if(P.h==Q.h)
+         {
+          if(P.t==Q.t)
+              {
+//head=tail
+               d=0;
+               //print("Uguali");
+              }
+         }
+     else
+        {
+//print(Minimus(variables(P.h/gcdMon(P.h,Q.h))));
+//print(Minimus(variables(Q.h/gcdMon(P.h,Q.h))));
+          if(Minimus(variables(P.h/gcdMon(P.h,Q.h)))<Minimus(variables(Q.h/gcdMon(P.h,Q.h))))
+             {
+             d=-1;
+            //print("Per Indice");
+             }
+        }
+     }
+ return(d);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+ ring r=0, (x,y,z), rp;
+ jmp p1;
+p1.h=poly(1);
+p1.t=poly(1);
+jmp p2;
+p2.h=x^2;
+p2.t=poly(0);
+jmp p3;
+p3.h=x;
+p3.t=poly(0);
+ GPolyMin(p1,p2);
+ GPolyMin(p2, p3);
+GPolyMin(p2,p2);
+}
+////////////////////////////////////////////////////////////////////
+proc TernComparer(list A, list B, list G)
+"USAGE:    TernComparer(A,B,C); A list, B list, G list
+RETURN:   int: d
+NOTE:     A and B are terns, while G is the given list of
+J-marked polynomials.
+EXAMPLE:  example TernComparer; shows an example"
+{
+int d=-1;
+//Start: A<B
+if(A[1]==B[1])
+  {
+   if(A[2]==B[2]&& A[3]==B[3])
+     {
+      //print("Uguali");
+      d=0;
+     }
+   else
+     {
+jmp g1=G[A[2]][A[3]];
+jmp g2=G[B[2]][B[3]];
+       if(GPolyMin(g1, g2)==1)
+          {
+            //print("Maggiore per il G");
+            d=1;
+          }
+     }
+  }
+else
+  {
+    if(A[1]>B[1])
+      {
+//the ordering MUST be rp
+        //print("Maggiore per Lex");
+        d=1;
+      }
+  }
+return(d);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+ ring r=0, (x,y,z), rp;
+jmp r1;
+r1.h=z^3;
+r1.t=poly(0);
+jmp r2;
+r2.h=z^2*y;
+r2.t=poly(0);
+jmp r3;
+r3.h=z*y^2 ;
+r3.t=-x^2*y;
+jmp r4;
+r4.h=y^5;
+r4.t=poly(0);
+list G2F=list(list(r1,r2,r3),list(r4));
+TernComparer([1,1,1],[x,1,1],G2F);
+}
+////////////////////////////////////////////////////////////////////
+proc MinimalV(list V, list G)
+"USAGE:    Minimal(V,G); V list, G list
+RETURN:   int: R
+NOTE:     Input=list(terns), G.
+EXAMPLE:  example MinimalV; shows an example"
+{
+//Minimal element for a given degree
+list R=list();
+list MIN=V[1];
+int h=1;
+int i;
+for(i=2; i<=size(V); i++)
+    {
+//I consider the first as minimum
+//If I find something smaller I change minimum
+     if(TernComparer(V[i],MIN,G)<=0)
+       {
+        MIN=V[i];
+        h=i;
+       }
+    }
+//Return: [minimum,position of the minimum]
+R=MIN,h;
+return(R);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+ ring r=0, (x,y,z), rp;
+jmp r1;
+r1.h=z^3;
+r1.t=poly(0);
+jmp r2;
+r2.h=z^2*y;
+r2.t=poly(0);
+jmp r3;
+r3.h=z*y^2 ;
+r3.t=-x^2*y;
+jmp r4;
+r4.h=y^5;
+r4.t=poly(0);
+list G2F=list(list(r1,r2,r3),list(r4));
+MinimalV(VConst(G2F,4,basering)[1],G2F);
+}
+////////////////////////////////////////////////////////////////////
+proc OrderV(list V,list G,list R)
+"USAGE:   Ordinare(V,G,R); V list, G list, R list
+RETURN:   list: R
+NOTE:     Input: Vm,G,emptylist
+EXAMPLE:  example Ordinare; shows an example"
+{
+//Order V[m]
+//R  will contain results but at the beginning it is empty
+list M=list();
+if(size(V)==1)
+  {
+    R=insert(R,V[1],size(R));
+  }
+else
+  {
+   M=MinimalV(V,G);
+   R=insert(R,M[1],size(R));
+   V=delete(V,M[2]);
+//recursive call
+   R=OrderV(V,G,R);
+  }
+return(R);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+ ring r=0, (x,y,z), rp;
+jmp r1;
+r1.h=z^3;
+r1.t=poly(0);
+jmp r2;
+r2.h=z^2*y;
+r2.t=poly(0);
+jmp r3;
+r3.h=z*y^2;
+r3.t=-x^2*y;
+jmp r4;
+r4.h=y^5;
+r4.t=poly(0);
+list G2F=list(list(r1,r2,r3),list(r4));
+OrderV(VConst(G2F,4,r)[1],G2F,list());
+}
+////////////////////////////////////////////////////////////////////
+proc StartOrderingV(list V,list G)
+"USAGE:   StartOrderingV(V,G); V list, G list
+RETURN:   list: R
+NOTE:     Input Vm,G. This procedure uses OrderV to get
+the ordered polynomials as in [BCLR].
+EXAMPLE:  example StartOrderingV; shows an example"
+{
+ return(OrderV(V,G, list()));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+ ring r=0, (x,y,z), rp;
+jmp r1;
+r1.h=z^3;
+r1.t=poly(0);
+jmp r2;
+r2.h=z^2*y;
+r2.t=poly(0);
+jmp r3;
+r3.h=z*y^2;
+r3.t=-x^2*y;
+jmp r4;
+r4.h=y^5;
+r4.t=poly(0);
+list G2F=list(list(r1,r2,r3),list(r4));
+StartOrderingV(VConst(G2F,4,basering)[1],G2F);
+}
+////////////////////////////////////////////////////////////////////
+proc MultiplyJmP(list L, list G)
+"USAGE:    MultiplyJmP(L,G); L list, G list
+RETURN:   jmp: K
+NOTE:     Input: a 3-ple,G. It performs the product associated
+to the 3-uple.
+EXAMPLE:  example MultiplyJmP; shows an example"
+{
+jmp g=G[L[2]][L[3]];
+jmp K;
+K.h=L[1]*g.h;
+K.t=L[1]*g.t;
+ return(K);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+ ring r=0, (x,y,z), rp;
+ list P=x^2,1,1;
+jmp r1;
+r1.h=z^3;
+r1.t=poly(0);
+jmp r2;
+r2.h=z^2*y;
+r2.t=poly(0);
+jmp r3;
+r3.h=z*y^2 ;
+r3.t=-x^2*y;
+jmp r4;
+r4.h=y^5;
+r4.t=poly(0);
+list G2F=list(list(r1,r2,r3),list(r4));
+MultiplyJmP(P,G2F);
+}
+////////////////////////////////////////////////////////////////////
+//proc JmpIdeal(list V,r)
+//"USAGE:    JmpIdeal(V); V list
+//RETURN:   ideal: I
+//NOTES: this procedure takes a list of Vm's of a certain degree
+//and construct their ideal, multiplying the head by the weighted
+//variable t.
+//EXAMPLE:  example JmpIdeal; shows an example"
+//{
+//ideal I=0;
+//int i;
+//if (size(V)!=0)
+ // {
+//   list M=list();
+//jmp g;
+//   for(i=1; i<= size(V); i++)
+//       {
+//         g=V[i];
+//         g.h=(g.h)*t;
+//         M[i]=g.h+g.t;
+//       }
+//   I=M[1..size(M)];
+//attrib(I,"isSB",1);
+//  }
+//return(I);
+//}
+//example
+//{ "EXAMPLE:"; echo = 2;
+// ring r=0, (x,y,z,t), rp;
+//jmp r1;
+//r1.h=z^3;
+//r1.t=poly(0);
+//jmp r2;
+//r2.h=z^2*y;
+//r2.t=poly(0);
+//jmp r3;
+//r3.h=z*y^2 ;
+//r3.t=-x^2*y;
+//jmp r4;
+//r4.h=y^5;
+//r4.t=poly(0);
+//list G2F=list(list(r1,r2,r3),list(r4));
+//JmpIdeal(VConst(G2F,6,r)[1],r);
+//}
+////////////////////////////////////////////////////////////////////
+proc NewWeight(int n)
+"USAGE:    NewWeight(n); n int
+RETURN:   intvec: u
+EXAMPLE:  example NewWeight; shows an example"
+{
+intvec u=0;
+u[n]=1;
+return(u);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+ NewWeight(3);
+}
+////////////////////////////////////////////////////////////////////
+proc FinalVm(list V1 , list G1 , def r)
+"USAGE:     FinalVm(V1, G1, r);  V1 list,  G1 list , r
+RETURN:   intvec: u
+EXAMPLE:  example FinalVm; shows an example"
+{
+//multiply and reduce, degree by degree
+intvec u=NewWeight(nvars(r)+1);
+list L=ringlist(r);
+L[2]=insert(L[2],"t",size(L[2]));
+//print(L[2]);
+list ordlist="a",u;
+L[3]=insert(L[3],ordlist,0);
+def H=ring(L);
+//print(V1);
+//print(G1);
+list M=list();
+jmp p;
+list N;
+poly q;
+poly s;
+int i;
+int j;
+for(i=1; i<=size(G1); i++)
+   {
+           N=list();
+           for(j=1; j<=size(G1[i]); j++)
+              {
+                p=G1[i][j];
+                q=p.h;
+                s=p.t;
+                N[j]=list(q,s);
+               }
+           M[i]=N;
+    }
+//print("M is");
+//print(M);
+p.h=poly(0);
+p.t=poly(0);
+setring H;
+list R=list();
+list S=list();
+//print("anello definito");
+list V=imap(r,V1);
+//def G=imap(r,G1);
+//print(V);
+list MM=imap(r,M);
+list G=list();
+list N=list();
+for(i=1; i<=size(MM); i++)
+   {
+           for(j=1; j<=size(MM[i]); j++)
+              {
+                p.h=MM[i][j][1];
+                p.t=MM[i][j][2];
+                N[j]=p;
+               }
+           G[i]=N;
+    }
+ideal I=0;
+jmp LL;
+jmp UU;
+//print("pronta x ridurre");
+ for(i=1; i<=size(V);i++)
+    {
+//print("sono a V di");
+//print(i);
+       R[i]=list();
+       S[i]=list();
+       I=0;
+              attrib(I,"isSB",1);
+       for(j=1;j<=size(V[i]); j++)
+          {
+//print(j);
+//print("esimo elem");
+            LL=MultiplyJmP(V[i][j],G);
+              LL.t=reduce(t*LL.t,I);
+//I only reduce the tail
+//print(LL.t);
+              LL.t=subst(LL.t,t,1);
+              S[i]=insert(S[i],LL,size(S[i]));
+              LL.h=t*LL.h;
+            R[i]=insert(R[i],LL,size(R[i]));
+             UU=R[i][j];
+              I=I+ideal(UU.h+UU.t);
+              attrib(I,"isSB",1);
+          }
+    }
+//print("ho ridotto");
+list M=list();
+poly q;
+poly s;
+for(i=1; i<=size(S); i++)
+   {
+           N=list();
+           for(j=1; j<=size(S[i]); j++)
+              {
+                p=S[i][j];
+                q=p.h;
+                s=p.t;
+                N[j]=list(q,s);
+               }
+           M[i]=N;
+    }
+p.h=poly(0);
+p.t=poly(0);
+setring r;
+def MM=imap(H,M);
+list MMM=list();
+for(i=1; i<=size(MM); i++)
+   {
+           N=list();
+           for(j=1; j<=size(MM[i]); j++)
+              {
+                p.h=MM[i][j][1];
+                p.t=MM[i][j][2];
+                N[j]=p;
+               }
+           MMM[i]=N;
+    }
+return(MMM);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+ ring r=0, (x,y,z), rp;
+jmp r1;
+r1.h=z^3;
+r1.t=poly(0);
+jmp r2;
+r2.h=z^2*y;
+r2.t=poly(0);
+jmp r3;
+r3.h=z*y^2 ;
+r3.t=-x^2*y;
+jmp r4;
+r4.h=y^5;
+r4.t=poly(0);
+list G2F=list(list(r1,r2,r3),list(r4));
+ FinalVm(VConst(G2F,6,r) , G2F, r);
+}
+////////////////////////////////////////////////////////////////////
+proc VmConstructor(list G, int c,def r)
+"USAGE:     VmConstructor(G,c); G list, c int
+RETURN:   list: R
+NOTE:     At the end separated by degree.
+EXAMPLE:  example VmConstructor; shows an example"
+{
+list V=list();
+V= VConst(G,c);
+//print("VConst");
+//V non ordered
+list L=list();
+list R=list();
+int i;
+// head, position
+//order the different degrees
+for(i=1; i<=size(V); i++)
+   {
+    L[i]=StartOrderingV(V[i], G);
+   }
+//print("finito ordine");
+//multiply and reduce
+//print("Ordinare");
+//R=FinalVm(L, G, r);
+//print("FinalVm");
+return(L);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+ ring r=0, (x,y,z), rp;
+jmp r1;
+r1.h=z^3;
+r1.t=poly(0);
+jmp r2;
+r2.h=z^2*y;
+r2.t=poly(0);
+jmp r3;
+r3.h=z*y^2 ;
+r3.t=-x^2*y;
+jmp r4;
+r4.h=y^5;
+r4.t=poly(0);
+list G2F=list(list(r1,r2,r3),list(r4));
+ VmConstructor(G2F,6,r);
+}
+////////////////////////////////////////////////////////////////////
+proc EKCouples(jmp A, jmp B)
+"USAGE:    CoppiaEK(A,B); A list, B list
+RETURN:   list: L
+NOTE:     At the end the monomials involved by EK.
+EXAMPLE:  example EKCouples; shows an example"
+{
+poly E;
+list L=0,0;
+string s=varstr(basering);
+list VVV=varstr(basering);
+//L will contain results
+poly h=Minimus(variables(A.h));
+//print(h);
+int l=findvars(h,1)[2][1];
+if(l!=nvars(basering))
+ {
+//print("vero");
+//print(l);
+  for(int j=l+1;j<=nvars(basering); j++)
+   {
+    //print("entrata");
+    //print(var(j));
+    E=var(j)*A.h/B.h;
+//Candidate for * product
+    //print(E);
+    if(E!=0)
+      {
+        //print("primo if passato");
+        if(Minimus(variables(B.h))>=Maximus(variables(E)))
+           {
+//Does it work with * ?
+            //print("secondo if passato");
+            L[1]=j;
+            L[2]=E;
+            break;
+           }
+      }
+   }
+  }
+return (L);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+ ring r=0, (x,y,z), rp;
+jmp A;
+A.h=y*z^2;
+A.t=poly(0);
+jmp B;
+B.h=y^2*z;
+B.t=poly(0);
+EKCouples(A,B);
+EKCouples(B,A);
+}
+////////////////////////////////////////////////////////////////////
+proc EKPolynomials(list G)
+"USAGE:    EKPolynomials(G); G list
+RETURN:   list: EK, list: D
+NOTE:     At the end EK polynomials and their degrees
+
+EXAMPLE:  example EKPolynomials; shows an example"
+{
+list D=list();
+list C=list();
+list N=0,0;
+list EK=list();
+int i;
+int j;
+int k;
+int l;
+jmp p;
+for(i=1; i<=size(G); i++)
+   {
+     for(j=1; j<=size(G[i]); j++)
+        {
+         for(k=1; k<=size(G); k++)
+             {
+               for(l=1; l<=size(G[k]); l++)
+                  {
+                     if(i!=k||j!=l)
+                       {
+//Loop on polynomials
+                        C=EKCouples(G[i][j], G[k][l]);
+//print("coppia");
+                        if(C[2]!=0)
+                          {
+                           C=insert(C,list(i,j,k,l),size(C));
+                           EK=insert(EK,C,size(EK));
+                           p=G[k][l];
+                           D=insert(D,deg(C[2]*p.h),size(D));
+                          }
+                       }
+                  }
+             }
+        }
+   }
+//Double Return
+return(EK, D);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring r=0, (x,y,z), rp;
+jmp r1;
+r1.h=z^3;
+r1.t=poly(0);
+jmp r2;
+r2.h=z^2*y;
+r2.t=poly(0);
+jmp r3;
+r3.h=z*y^2;
+r3.t=-x^2*y;
+jmp r4;
+r4.h=y^5;
+r4.t=poly(0);
+list G2F=list(list(r1,r2,r3),list(r4));
+EKPolynomials(G2F);
+}
+////////////////////////////////////////////////////////////////////
+proc MultEKPolys(list EK, list G)
+"USAGE:    MultEKPolys(G); G list
+RETURN:   list: p
+NOTE:     At the end I obtain the EK polynomials and
+their degrees.
+EXAMPLE:  example MultEKPolys; shows an example"
+{
+jmp u;
+u=G[EK[3][1]][EK[3][2]];
+//print("u");
+jmp q;
+q=G[EK[3][3]][EK[3][4]];
+return(var(EK[1])*(u.h+u.t)-EK[2]*(q.h+q.t));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+ ring r=0, (x,y,z), rp;
+jmp r1;
+r1.h=z^3;
+r1.t=poly(0);
+jmp r2;
+r2.h=z^2*y;
+r2.t=poly(0);
+jmp r3;
+r3.h=z*y^2;
+r3.t=-x^2*y;
+jmp r4;
+r4.h=y^5;
+r4.t=poly(0);
+list G2F=list(list(r1,r2,r3),list(r4));
+list EK,D=EKPolynomials(G2F);
+MultEKPolys(EK[2],G2F);
+}
+////////////////////////////////////////////////////////////////////
+proc SchemeEq(list W, list EK,list D,list Q,def r)
+"USAGE:    SchemeEq(W,EK,D,Q,r);  W list, EK list, D list, Q list, r ring
+RETURN:    int: i
+NOTE:
+This procedure performs the reduction of EK-polynomials, obtaining
+the J-marked scheme.
+EXAMPLE:  example SchemeEq; shows an example"
+{
+list Jms=list();
+//ideal I;
+list M=list();
+jmp mini;
+mini=W[1][1];
+int minimo=deg(mini.h);
+//multiply variables
+poly pd=poly(1);
+for(int i=1;i<=nvars(r);i++)
+{pd=pd*var(i);}
+//CHANGE RING
+intvec u=NewWeight(nvars(r)+1);
+list L=ringlist(r);
+L[2]=insert(L[2],"t",size(L[2]));
+//print(L[2]);
+list ordlist="a",u;
+L[3]=insert(L[3],ordlist,0);
+def H=ring(L);
+//list
+M=list();
+jmp pu;
+list N;
+poly q;
+poly s;
+i=0;
+int j;
+for(i=1; i<=size(Q); i++)
+   {
+           N=list();
+           for(j=1; j<=size(Q[i]); j++)
+              {
+                pu=Q[i][j];
+                q=pu.h;
+                s=pu.t;
+                N[j]=list(q,s);
+               }
+           M[i]=N;
+    }
+list O;
+pu.h=poly(0);
+pu.t=poly(0);
+for(i=1; i<=size(W); i++)
+   {
+           N=list();
+           for(j=1; j<=size(W[i]); j++)
+              {
+                pu=W[i][j];
+                q=pu.h;
+                s=pu.t;
+                N[j]=list(q,s);
+               }
+           O[i]=N;
+    }
+pu.h=poly(0);
+pu.t=poly(0);
+setring H;
+list R=list();
+list S=list();
+//print("anello definito");
+def EK=imap(r,EK);
+def MM=imap(r,M);
+def OO=imap(r,O);
+def pd=imap(r,pd);
+list G=list();
+list N=list();
+for(i=1; i<=size(MM); i++)
+   {
+           for(j=1; j<=size(MM[i]); j++)
+              {
+                pu.h=MM[i][j][1];
+                pu.t=MM[i][j][2];
+                N[j]=pu;
+               }
+           G[i]=N;
+    }
+list V;
+for(i=1; i<=size(OO); i++)
+   {
+           for(j=1; j<=size(OO[i]); j++)
+              {
+                pu.h=OO[i][j][1];
+                pu.t=OO[i][j][2];
+                N[j]=pu;
+               }
+           V[i]=N;
+    }
+//print(V);
+//print(G);
+matrix C;
+list COEFF;
+poly p=0;
+poly q=0;
+ideal I;
+list M;
+i=0;
+jmp g;
+int k;
+for(j=1; j<=size(EK);j++)
+      {
+       //print("arrivo");
+       //print(j);
+       p=MultEKPolys(EK[j],G);
+       //ideal
+        I=0;
+       if (size(V[D[j]-minimo+1])!=0)
+           {
+            M=list();
+          //  jmp g;
+       for(i=1; i<= size(V[D[j]-minimo+1]); i++)
+           {
+            g=V[D[j]-minimo+1][i];
+            g.h=(g.h)*t;
+            M[i]=g.h+g.t;
+          }
+      I=M[1..size(M)];
+     attrib(I,"isSB",1);
+//print(I);
+  }
+//print(I);
+q=reduce(t*p,I);
+q=subst(q,t,1);
+       C=coef(q,pd);
+       COEFF=C[2,1..ncols(C)];
+       for(k=1;k<=size(COEFF);k++)
+          {
+            if(COEFF[k]!=0)
+           { Jms=insert(Jms,COEFF[k],size(Jms));}
+          }
+      }
+setring r;
+def Jms=imap(H,Jms);
+return(Jms);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+ ring r=0, (x,y,z),rp;
+ ideal Borid=y^2*z,y*z^2,z^3,y^5;
+attrib(Borid,"isSB",1);
+    list B=ArrangeBorel(Borid);
+    list NumN;
+    list N;
+    int i;
+    int d;
+    for(i=1;i<=size(B);i++)
+       {
+        d=deg(B[i][1]);
+        N[i]=kbase(Borid,d);
+        NumN[i]=size(N[i]);
+       }
+int qc=NumNewVar(B, NumN);
+//Now I must define the NEW RING,
+//putting the c parameters inside.
+list L=ringlist(r);
+list L2;
+L2[1]=L[1];
+L2[2]=list();
+for(i=qc;i>=1;i--)
+    {
+     L2[2][i]="c("+string(i)+")";
+    }
+L2[3]=list(list("rp",qc));
+L2[4]=L[4];
+L[1]=L2;
+if(defined(K)){kill K;}
+def K=ring(L);
+export K;
+setring(K);
+def Borid=imap(r,Borid);
+def N=imap(r,N);
+def B=imap(r,B);
+//NumN contains only scalars so I do not imap it
+int j;
+list Q;
+int s;
+list M;
+jmp pp;
+for(i=1;i<=size(B);i++)
+    {
+      Q[i]=list();
+     for(j=1;j<=size(B[i]);j++)
+        {
+          M=NewTails(N[i],s);
+          pp.h=B[i][j];
+          pp.t=M[1];
+          Q[i][j]=pp;
+          s=s+M[2];
+          //print(s);
+        }
+    }
+list P=ArrangeTails(Q);
+list EK,D= EKPolynomials(P);
+     int massimo=Max(D);
+//list V=VConst(P, massimo);
+//pause();
+list V=VmConstructor(P,massimo,r);
+list W=FinalVm(V,P,K);
+//print("I V ridotti in ordine sono");
+//print(W);
+list Jms=SchemeEq(W,EK,D,P,K);
+Jms;}
+
+//////////////////////////////////////////////////////////////////////
+proc JMarkedScheme(ideal Borid,def r)
+"USAGE:    JMarkedScheme(Borid, r);  Borid ideal, r ring
+RETURN:    list: Jms
+NOTE:
+This procedure performs automatically the whole construction
+of the J-marked scheme.
+EXAMPLE:  example JMarkedScheme; shows an example"
+{
+list Jms;
+if(BorelCheck(Borid,r))
+  {
+   if(size(Borid)==1)
+     { Jms=list();}
+  else{
+    //print("Input is OK");
+    attrib(Borid,"isSB",1);
+    list B=ArrangeBorel(Borid);
+    list NumN;
+    list N;
+    int i;
+    int d;
+    for(i=1;i<=size(B);i++)
+       {
+        d=deg(B[i][1]);
+        N[i]=kbase(Borid,d);
+        NumN[i]=size(N[i]);
+       }
+int qc=NumNewVar(B, NumN);
+if(qc==0)
+{Jms=list(0);}
+else
+ {
+//Now I must define the NEW RING,
+//putting the c parameters inside.
+list L=ringlist(r);
+list L2;
+L2[1]=L[1];
+L2[2]=list();
+for(i=qc;i>=1;i--)
+    {
+     L2[2][i]="c("+string(i)+")";
+    }
+L2[3]=list(list("rp",qc));
+L2[4]=L[4];
+L[1]=L2;
+if(defined(K)){kill K;}
+def K=ring(L);
+export K;
+setring(K);
+def Borid=imap(r,Borid);
+def N=imap(r,N);
+def B=imap(r,B);
+//NumN contains only scalars so I do not imap it
+int j;
+list Q;
+int s;
+list M;
+jmp pp;
+for(i=1;i<=size(B);i++)
+    {
+      Q[i]=list();
+     for(j=1;j<=size(B[i]);j++)
+        {
+          M=NewTails(N[i],s);
+          pp.h=B[i][j];
+          pp.t=M[1];
+          Q[i][j]=pp;
+          s=s+M[2];
+          //print(s);
+        }
+    }
+list P=ArrangeTails(Q);
+list EK,D= EKPolynomials(P);
+     int massimo=Max(D);
+//list V=VConst(P, massimo);
+//pause();
+list V=VmConstructor(P,massimo,r);
+list W=FinalVm(V,P,K);
+//print("I V ridotti in ordine sono");
+//print(W);
+//list
+Jms=SchemeEq(W,EK,D,P,K);
+keepring K;}
+}
+  }
+else
+   {
+    print("WRONG IDEAL IN INPUT");
+    print("It is NOT BOREL");
+   }
+return(Jms);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+ ring r=0, (x,y,z),rp;
+ ideal Borid=y^2*z,y*z^2,z^3,y^5;
+JMarkedScheme(Borid,r);
+}
+////////////////////////////////////////////////////////////////////
diff --git a/Singular/LIB/absfact.lib b/Singular/LIB/absfact.lib
new file mode 100644
index 0000000..1483c16
--- /dev/null
+++ b/Singular/LIB/absfact.lib
@@ -0,0 +1,959 @@
+////
+version="version absfact.lib 4.0.0.0 Jun_2013 "; // $Id: 16f65d70800ea54737b5628579e58c191cd32a8c $
+category="Factorization";
+info="
+LIBRARY: absfact.lib   Absolute factorization for characteristic 0
+AUTHORS: Wolfram Decker,       decker at math.uni-sb.de
+         Gregoire Lecerf,      lecerf at math.uvsq.fr
+         Gerhard Pfister,      pfister at mathematik.uni-kl.de
+         Martin Lee,           mlee at mathematik.uni-kl.de
+
+OVERVIEW:
+A library for computing the absolute factorization of multivariate
+polynomials f with coefficients in a field K of characteristic zero.
+Using Trager's idea, the implemented algorithm computes an absolutely
+irreducible factor by factorizing over some finite extension field L
+(which is chosen such that V(f) has a smooth point with coordinates in L).
+Then a minimal extension field is determined making use of the
+Rothstein-Trager partial fraction decomposition algorithm.
+absFactorizeBCG uses the algorithm of Bertone, Cheze and Galligo for bivariate
+polynomials and similar ideas as above to reduce to this case.
+
+REFERENCES:
+G. Cheze, G. Lecerf: Lifting and recombination techniques for absolute
+                  factorization. Journal of Complexity, 23(3):380-420, 2007.
+C. Bertone, G. Cheze, and A. Galligo: Modular las vegas algorithms for
+                  polynomial absolute factorization. J. Symb. Comput.,
+                  45(12):1280-1295, December 2010
+
+KEYWORDS: factorization; absolute factorization.
+SEE ALSO: factorize
+
+PROCEDURES:
+  absFactorize();        absolute factorization of poly
+  absFactorizeBCG();     absolute factorization of poly
+";
+
+////////////////////////////////////////////////////////////////////
+static proc partialDegree(poly p, int i)
+"USAGE:  partialDegree(p,i);   p poly, i int
+RETURN: int, the degree of p in the i-th variable
+"
+{
+  int n = nvars(basering);
+  intvec tmp;
+  tmp[n] = 0;
+  tmp[i] = 1;
+  return(deg(p,tmp));
+}
+////////////////////////////////////////////////////////////////////
+static proc belongTo(string s, list l)
+"USAGE:  belongTo(s,l);   s string, l list
+RETURN: 1 if s belongs to l, 0 otherwise
+"
+{
+  string tmp;
+  for(int i = 1; i <= size(l); i++) {
+    tmp = l[i];
+    if (tmp == s) {
+      return(1);
+    }
+  }
+  return(0);
+}
+////////////////////////////////////////////////////////////////////
+static proc variableWithSmallestPositiveDegree(poly p)
+"USAGE:  variableWithSmallestPositiveDegree(p);  p poly
+RETURN: int;  0 if p is constant. Otherwise, the index of the
+        variable which has the smallest positive degree in p.
+"
+{
+  int n = nvars(basering);
+  int v = 0;
+  int d = deg(p);
+  int d_loc;
+  for(int i = 1; i <= n; i++) {
+    d_loc = partialDegree(p, i);
+    if (d_loc >= 1 and d_loc <= d) {
+      v = i;
+      d = d_loc;
+    }
+  }
+  return(v);
+}
+////////////////////////////////////////////////////////////////////
+static proc smallestProperSimpleFactor(poly p)
+"USAGE:  smallestProperSimpleFactor(p);   p poly
+RETURN: poly:  a proper irreducible simple factor of p of smallest
+        degree. If no such factor exists, 0 is returned.
+"
+{
+  list p_facts = factorize(p);
+  int s = size(p_facts[1]);
+  int d = deg(p)+1;
+  poly q = 0;
+  poly f;
+  int e;
+  for(int i = 1; i <= s; i++)
+  {
+    f = p_facts[1][i];
+    e = deg(f);
+    if (e >= 1 and e < d and p_facts[2][i] == 1)
+    {
+      q = f / leadcoef(f);
+      d = e;
+    }
+  }
+  return(q);
+}
+////////////////////////////////////////////////////////////////////
+static proc smallestProperFactor(poly p)
+"USAGE:  smallestProperFactor(p);   p poly
+RETURN: poly:  a proper irreducible factor of p of smallest degree.
+        If p is constant, 0 is returned.
+"
+{
+  list p_facts = factorize(p);
+  int s = size(p_facts[1]);
+  int d = deg(p)+1;
+  poly q = 0;
+  poly f;
+  int e;
+  for(int i = 1; i <= s; i++)
+  {
+    f = p_facts[1][i];
+    e = deg(f);
+    if (e >= 1 and e < d)
+    {
+      q = f / leadcoef(f);
+      d = e;
+    }
+  }
+  return(q);
+}
+////////////////////////////////////////////////////////////////////
+static proc extensionContainingSmoothPoint(poly p, int m)
+"USAGE:  extensionContainingSmoothPoint(p,m);  p poly, m int
+RETURN: poly:  an irreducible univariate polynomial that defines an
+        algebraic extension of the current ground field that contains
+        a smooth point of the hypersurface defined by p=0.
+"
+{
+  int n = nvars(basering) - 1;
+  poly q = 0;
+  int i;
+  list a;
+  for(i=1;i<=n+1;i++){a[i] = 0;}
+  a[m] = var(n+1);
+  // The list a is to be taken with random entries in [-e, e].
+  // Every 10 * n trial, e is incremented by 1.
+  int e = 1;
+  int nbtrial = 0;
+  map h;
+  while (q == 0)
+  {
+    h = basering, a[1..n+1];
+    q = smallestProperSimpleFactor(h(p));
+    for(i = 1; i  <= n ; i = i + 1)
+    {
+      if (i != m)
+      {
+        a[i] = random(-e, e);
+      }
+    }
+    nbtrial++;
+    if (nbtrial >= 10 * n)
+    {
+      e = e + 1;
+      nbtrial = 0;
+    }
+  }
+  return(q);
+}
+////////////////////////////////////////////////////////////////////
+static proc RothsteinTragerResultant(poly g, poly f, int m)
+"USAGE:  RothsteinTragerResultant(g,f,m);  g,f poly, m int
+RETURN: poly
+NOTE:   To be called by the RothsteinTrager procedure only.
+"
+{
+  def MPz = basering;
+  int n = nvars(MPz) - 1;
+  int d = partialDegree(f, m);
+  poly df = diff(f, var(m));
+  list a;
+  int i;
+  for(i=1;i<=n+1;i++){ a[i] = 0; }
+  a[m] = var(m);
+  poly q = 0;
+  int e = 1;
+  int nbtrial = 0;
+  map h;
+  while (q == 0)
+  {
+    h = MPz, a[1..n+1];
+    q = resultant(h(f), h(df) * var(n+1) - h(g), var(m));
+    if (deg(q) == d)
+    {
+      return(q/leadcoef(q));
+    }
+    q = 0;
+    for(i = 1; i  <= n ; i++)
+    {
+      if (i != m)
+      {
+        a[i] = random(-e, e);
+      }
+    }
+    nbtrial++;
+    if (nbtrial >= 10 * n)
+    {
+      e++;
+      nbtrial = 0;
+    }
+  }
+}
+////////////////////////////////////////////////////////////////////
+static proc RothsteinTrager(list g, poly p, int m, int expectedDegQ)
+"USAGE:  RothsteinTrager(g,p,m,d);  g list, p poly, m,d int
+RETURN: list L consisting of two entries of type poly
+NOTE:   the return value is the Rothstein-Trager partial fraction
+        decomposition of the quotient s/p, where s is a generic linear
+        combination of the elements of g. The genericity via d
+        (the expected degree of L[1]).
+"
+{
+  def MPz = basering;
+  int n = nvars(MPz) - 1;
+  poly dp = diff(p, var(m));
+  int r = size(g);
+  list a;
+  int i;
+  for(i=1;i<=r;i++){a[i] = 0;}
+  a[r] = 1;
+  int nbtrial = 0;
+  int e = 1;
+  poly s;
+  poly q;
+  while (1)
+  {
+    s = 0;
+    for(i = 1; i <= r; i++){s = s + a[i] * g[i];}
+    q = RothsteinTragerResultant(s, p, m);
+    q = smallestProperFactor(q);
+    if (deg(q) == expectedDegQ)
+    {
+      // Go into the quotient by q(z)=0
+      ring MP_z = (0,var(n+1)), (x(1..n)), dp;
+      list lMP_z = ringlist(MP_z);
+      lMP_z[1][4] = ideal(imap(MPz,q));
+      list tmp = ringlist(MPz)[2];
+      lMP_z[2] = list(tmp[1..n]);
+      def MPq = ring(lMP_z);
+      setring(MPq);
+      poly f = gcd(imap(MPz, p), par(1) * imap(MPz, dp) - imap(MPz, s));
+      f = f / leadcoef(f);
+      setring(MPz);
+      return(list(q, imap(MPq, f)));
+    }
+    for(i = 1; i  <= r ; i++)
+    {
+      a[i] = random(-e, e);
+    }
+    nbtrial++;
+    if (nbtrial >= 10 * r)
+    {
+      e++;
+      nbtrial = 0;
+    }
+  }
+}
+////////////////////////////////////////////////////////////////////
+static proc absFactorizeIrreducible(poly p)
+"USAGE:   absFactorizeIrreducible(p);   p poly
+ASSUME:  p is an irreducible polynomial that does not depend on the last
+         variable @z of the basering.
+RETURN:  list L of two polynomials: q=L[1] is an irreducible polynomial of
+         minimal degree in @z such that p has an absolute factor
+         over K[@z]/<q>, and f represents such an absolute factor.
+"
+{
+  int dblevel = printlevel - voice + 2;
+  dbprint(dblevel,"Entering absfact.lib::absFactorizeIrreducible with ",p);
+  def MPz = basering;
+  int d = deg(p);
+  int n = nvars(MPz) - 1;
+
+  if (d < 1)
+  {
+    return(list(var(n+1), p));
+  }
+  int m = variableWithSmallestPositiveDegree(p);
+  // var(m) is now considered as the main variable.
+
+  poly q = extensionContainingSmoothPoint(p, m);
+  int r = deg(q);
+  if (r == 1)
+  {
+    return(list(var(n+1), p));
+  }
+
+  list tmp = ringlist(MPz)[2];
+  // Go into the quotient by q(z)=0
+  ring MP_z = (0,var(n+1)), (x(1..n)), dp;
+  list lMP_z = ringlist(MP_z);
+  lMP_z[1][4] = ideal(imap(MPz,q));
+  lMP_z[2] = list(tmp[1..n]);
+  def MPq = ring(lMP_z);
+  setring(MPq);
+  dbprint(dblevel-1,"Factoring in algebraic extension");
+  // "Factoring p in the algebraic extension...";
+  poly p_loc = imap(MPz, p);
+  poly f = smallestProperSimpleFactor(p_loc);
+  int degf = deg(f);
+
+  if (degf == d)
+  {
+    setring(MPz);
+    return(list(var(n+1), p));
+  }
+
+  if (degf * r == d)
+  {
+    setring(MPz);
+    return(list(q, imap(MPq, f)));
+  }
+  dbprint(dblevel-1,"Absolutely irreducible factor found");
+  dbprint(dblevel,"Minimizing field extension");
+  // "Need to find a minimal extension";
+  poly co_f = p_loc / f;
+  poly e = diff(f, var(m)) * co_f;
+  setring(MPz);
+  poly e = imap(MPq, e);
+  list g;
+  int i;
+  for(i = 1; i <= r; i++)
+  {
+    g[i] = subst(e, var(n+1), 0);
+    e = diff(e, var(n+1));
+  }
+  return(RothsteinTrager(g, p, m, d div degf));
+}
+
+////////////////////////////////////////////////////////////////////
+proc absFactorize(poly p, list #)
+"USAGE:  absFactorize(p [,s]);   p poly, s string
+ASSUME: coefficient field is the field of rational numbers or a
+        transcendental extension thereof
+RETURN: ring @code{R} which is obtained from the current basering
+        by adding a new parameter (if a string @code{s} is given as a
+        second input, the new parameter gets this string as name). The ring
+        @code{R} comes with a list @code{absolute_factors} with the
+        following entries:
+ at format
+    absolute_factors[1]: ideal   (the absolute factors)
+    absolute_factors[2]: intvec  (the multiplicities)
+    absolute_factors[3]: ideal   (the minimal polynomials)
+    absolute_factors[4]: int     (total number of nontriv. absolute factors)
+ at end format
+        The entry @code{absolute_factors[1][1]} is a constant, the
+        entry @code{absolute_factors[3][1]} is the parameter added to the
+        current ring.@*
+        Each of the remaining entries @code{absolute_factors[1][j]} stands for
+        a class of conjugated absolute factors. The corresponding entry
+        @code{absolute_factors[3][j]} is the minimal polynomial of the
+        field extension over which the factor is minimally defined (its degree
+        is the number of conjugates in the class). If the entry
+        @code{absolute_factors[3][j]} coincides with @code{absolute_factors[3][1]},
+        no field extension was necessary for the @code{j}th (class of)
+        absolute factor(s).
+NOTE:   All factors are presented denominator- and content-free. The constant
+        factor (first entry) is chosen such that the product of all (!) the
+        (denominator- and content-free) absolute factors of @code{p} equals
+        @code{p / absolute_factors[1][1]}.
+SEE ALSO: factorize, absPrimdecGTZ
+EXAMPLE: example absFactorize; shows an example
+"
+{
+  int dblevel = printlevel - voice + 2;
+  dbprint(dblevel,"Entering absfact.lib::absFactorize with ",p);
+  def MP = basering;
+  int i;
+  if (char(MP) != 0)
+  {
+    ERROR("// absfact.lib::absFactorize is only implemented for "+
+          "characteristic 0");
+  }
+  if(minpoly!=0)
+  {
+    ERROR("// absfact.lib::absFactorize is not implemented for algebraic "
+          +"extensions");
+  }
+
+  int n = nvars(MP);
+  int pa=npars(MP);
+  list lMP= ringlist(MP);
+  list buflMP= lMP;
+  intvec vv,vk;
+  for(i=1;i<=n;i++){vv[i]=1;}
+  vk=vv,1;
+
+  //if the basering has parameters, add the parameters to the variables
+  //takes care about coefficients and possible denominators
+  if(pa>0)
+  {
+    poly qh=cleardenom(p);
+    if (p==0)
+    {
+      number cok=0;
+    }
+    else
+    {
+      number cok=leadcoef(p)/leadcoef(qh);
+    }
+    p=qh;
+    string sp;
+    for(i=1;i<=npars(basering);i++)
+    {
+      sp=string(par(i));
+      sp=sp[2..size(sp)-1];
+      lMP[2][n+i]=sp;
+      vv=vv,1;
+    }
+    lMP[1]=0;
+    n=n+npars(MP);
+  }
+
+  // MPz is obtained by adding the new variable @z to MP
+  // ordering is wp(1...1)
+  // All the above subroutines work in MPz
+  string newvar;
+  if(size(#)>0)
+  {
+    if(typeof(#[1])=="string")
+    {
+      newvar=#[1];
+    }
+    else
+    {
+      newvar = "a";
+    }
+  }
+  else
+  {
+    newvar = "a";
+  }
+  if (newvar=="a")
+  {
+    if(belongTo(newvar, lMP[2])||defined(a)){newvar = "b";}
+    if(belongTo(newvar, lMP[2])||defined(b)){newvar = "c";}
+    if(belongTo(newvar, lMP[2])||defined(c)){newvar = "@c";}
+    while(belongTo(newvar, lMP[2]))
+    {
+       newvar = "@" + newvar;
+    }
+  }
+  lMP[2][n+1] = newvar;
+
+  // new ordering
+  vv=vv,1;
+  list orst;
+  orst[1]=list("wp",vv);
+  orst[2]=list("C",0);
+  lMP[3]=orst;
+
+  def MPz = ring(lMP);
+  setring(MPz);
+  poly p=imap(MP,p);
+
+  // special treatment in the homogeneous case, dropping one variable
+  // by substituting the first variable by 1
+  int ho=homog(p);
+  if(ho)
+  {
+    int dh=deg(p);
+    p=subst(p,var(1),1);
+    int di=deg(p);
+  }
+  list rat_facts = factorize(p);
+  int s = size(rat_facts[1]);
+  list tmpf; // absolute factors
+  intvec tmpm; // respective multiplicities
+  tmpf[1] = list(var(n+1), leadcoef(imap(MP,p)));
+  tmpm[1] = 1;
+  poly tmp;
+  for(i = 2; i <= s; i++)
+  {
+    tmp = rat_facts[1][i];
+    tmp = tmp / leadcoef(tmp);
+    tmpf[i] = absFactorizeIrreducible(tmp);
+    tmpm[i] = rat_facts[2][i];
+  }
+  // the homogeneous case, homogenizing the result
+  // the new variable has to have degree 0
+  // need to change the ring
+  if(ho)
+  {
+    list ll=ringlist(MPz);
+    vv[size(vv)]=0;
+    ll[3][1][2]=vv;
+    def MPhelp=ring(ll);
+    setring(MPhelp);
+    list tmpf=imap(MPz,tmpf);
+    for(i=2;i<=size(tmpf);i++)
+    {
+      tmpf[i][2]=homog(tmpf[i][2],var(1));
+    }
+    if(dh>di)
+    {
+      tmpf[size(tmpf)+1]=list(var(n+1),var(1));
+      tmpm[size(tmpm)+1]=dh-di;
+    }
+    setring(MPz);
+    tmpf=imap(MPhelp,tmpf);
+  }
+  // in case of parameters we have to go back to the old ring
+  // taking care about constant factors
+  if(pa)
+  {
+    setring(MP);
+    n=nvars(MP);
+    list lM=ringlist(MP);
+    orst[1]=list("wp",vk);
+    orst[2]=list("C",0);
+    lM[2][n+1] = newvar;
+    lM[3]=orst;
+    def MPout=ring(lM);
+    setring(MPout);
+    list tmpf=imap(MPz,tmpf);
+    number cok=imap(MP,cok);
+    tmpf[1][2]=cok*tmpf[1][2];
+  }
+  else
+  {
+    def MPout=MPz;
+  }
+  // if we want the output as string
+  if(size(#)>0)
+  {
+    if(typeof(#[1])=="int")
+    {
+      if(#[1]==77)
+      {  // undocumented feature for Gerhard's absPrimdecGTZ
+        if (size(tmpf)<2){ list abs_fac = list(var(n+1),poly(1)); }
+        else { list abs_fac=tmpf[2..size(tmpf)]; }
+        abs_fac=abs_fac,newvar;
+        string result = string(abs_fac);
+        setring(MP);
+        return(result);
+      }
+    }
+  }
+  // preparing the output for SINGULAR standard
+  // a list: factors(ideal),multiplicities(intvec),minpolys(ideal),
+  // number of factors in the absolute factorization
+  // the output(except the coefficient) should have no denominators
+  // and no content
+  ideal facts,minpols;
+  intvec mults;
+  int nfacts;
+  number co=1;
+  minpols[1]=tmpf[1][1];
+  facts[1]=tmpf[1][2];     //the coefficient
+  for(i=2;i<=size(tmpf);i++)
+  {
+    minpols[i]=cleardenom(tmpf[i][1]);
+    facts[i]=cleardenom(tmpf[i][2]);
+    co=co*(leadcoef(tmpf[i][2])/leadcoef(facts[i]))^(deg(minpols[i])*tmpm[i]);
+  }
+  facts[1]=facts[1]*co;
+  for(i=1;i<=size(tmpm);i++)
+  {
+    mults[i]=tmpm[i];
+  }
+  for(i=2;i<=size(mults);i++)
+  {
+    nfacts=nfacts+mults[i]*deg(minpols[i]);
+  }
+  list absolute_factors=facts,mults,minpols,nfacts;
+
+  // create ring with extra parameter `newvar` for output:
+  setring(MP);
+  list Lout=ringlist(MP);
+  if(!pa)
+  {
+    list Lpar=list(char(MP),list(newvar),list(list("lp",intvec(1))),ideal(0));
+  }
+  else
+  {
+    list Lpar=Lout[1];
+    Lpar[2][size(Lpar[2])+1]=newvar;
+    vv=Lpar[3][1][2];
+    vv=vv,1;
+    Lpar[3][1][2]=vv;
+  }
+  Lout[1]=Lpar;
+  def MPo=ring(Lout);
+  setring(MPo);
+  list absolute_factors=imap(MPout,absolute_factors);
+  export absolute_factors;
+  setring(MP);
+
+  dbprint( printlevel-voice+3,"
+// 'absFactorize' created a ring, in which a list absolute_factors (the
+// absolute factors) is stored.
+// To access the list of absolute factors, type (if the name S was assigned
+// to the return value):
+//        setring(S); absolute_factors;
+  ");
+  return(MPo);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring R = (0), (x,y), lp;
+  poly p = (-7*x^2 + 2*x*y^2 + 6*x + y^4 + 14*y^2 + 47)*(5x2+y2)^3*(x-y)^4;
+  def S = absFactorize(p) ;
+  setring(S);
+  absolute_factors;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+proc absFactorizeBCG(poly p, list #)
+"USAGE:  absFactorizeBCG(p [,s]);   p poly, s string
+ASSUME: coefficient field is the field of rational numbers or a
+        transcendental extension thereof
+RETURN: ring @code{R} which is obtained from the current basering
+        by adding a new parameter (if a string @code{s} is given as a
+        second input, the new parameter gets this string as name). The ring
+        @code{R} comes with a list @code{absolute_factors} with the
+        following entries:
+ at format
+    absolute_factors[1]: ideal   (the absolute factors)
+    absolute_factors[2]: intvec  (the multiplicities)
+    absolute_factors[3]: ideal   (the minimal polynomials)
+    absolute_factors[4]: int     (total number of nontriv. absolute factors)
+ at end format
+        The entry @code{absolute_factors[1][1]} is a constant, the
+        entry @code{absolute_factors[3][1]} is the parameter added to the
+        current ring.@*
+        Each of the remaining entries @code{absolute_factors[1][j]} stands for
+        a class of conjugated absolute factors. The corresponding entry
+        @code{absolute_factors[3][j]} is the minimal polynomial of the
+        field extension over which the factor is minimally defined (its degree
+        is the number of conjugates in the class). If the entry
+        @code{absolute_factors[3][j]} coincides with @code{absolute_factors[3][1]},
+        no field extension was necessary for the @code{j}th (class of)
+        absolute factor(s).
+NOTE:   All factors are presented denominator- and content-free. The constant
+        factor (first entry) is chosen such that the product of all (!) the
+        (denominator- and content-free) absolute factors of @code{p} equals
+        @code{p / absolute_factors[1][1]}.
+SEE ALSO: factorize, absPrimdecGTZ, absFactorize
+EXAMPLE: example absFactorizeBCG; shows an example
+"
+{
+  int dblevel = printlevel - voice + 2;
+  dbprint(dblevel,"Entering absfact.lib::absFactorizeBCG with ",p);
+  def MP = basering;
+  int i;
+  if (char(MP) != 0)
+  {
+    ERROR("// absfact.lib::absFactorizeBCG is only implemented for "+
+          "characteristic 0");
+  }
+  if(minpoly!=0)
+  {
+    ERROR("// absfact.lib::absFactorizeBCG is not implemented for algebraic "
+          +"extensions");
+  }
+
+  int n = nvars(MP);
+  int pa=npars(MP);
+  list lMP= ringlist(MP);
+  intvec vv,vk;
+  for(i=1;i<=n;i++){vv[i]=1;}
+  vk=vv,1;
+
+  //if the basering has parameters, add the parameters to the variables
+  //takes care about coefficients and possible denominators
+  if(pa>0)
+  {
+    poly qh=cleardenom(p);
+    if (p==0)
+    {
+      number cok=0;
+    }
+    else
+    {
+      number cok=leadcoef(p)/leadcoef(qh);
+    }
+    p=qh;
+    string sp;
+    for(i=1;i<=npars(basering);i++)
+    {
+      sp=string(par(i));
+      sp=sp[2..size(sp)-1];
+      lMP[2][n+i]=sp;
+      vv=vv,1;
+    }
+    lMP[1]=0;
+    n=n+npars(MP);
+  }
+
+  // MPz is obtained by adding the new variable @z to MP
+  // ordering is wp(1...1)
+  // All the above subroutines work in MPz
+  string newvar;
+  if(size(#)>0)
+  {
+    if(typeof(#[1])=="string")
+    {
+      newvar=#[1];
+    }
+    else
+    {
+      newvar = "a";
+    }
+  }
+  else
+  {
+    newvar = "a";
+  }
+  if (newvar=="a")
+  {
+    if(belongTo(newvar, lMP[2])||defined(a)){newvar = "b";}
+    if(belongTo(newvar, lMP[2])||defined(b)){newvar = "c";}
+    if(belongTo(newvar, lMP[2])||defined(c)){newvar = "@c";}
+    while(belongTo(newvar, lMP[2]))
+    {
+       newvar = "@" + newvar;
+    }
+  }
+
+  // create ring with extra parameter `newvar` for output:
+  setring(MP);
+  list Lout=ringlist(MP);
+  if(!pa)
+  {
+    list Lpar=list(char(MP),list(newvar),list(list("lp",intvec(1))),ideal(0));
+  }
+  else
+  {
+    list Lpar=Lout[1];
+    Lpar[2][size(Lpar[2])+1]=newvar;
+    vv=Lpar[3][1][2];
+    vv=vv,1;
+    Lpar[3][1][2]=vv;
+  }
+  Lout[1]=Lpar;
+  def MPo=ring(Lout);
+  setring(MPo);
+
+  poly p=imap(MP,p);
+
+  // special treatment in the homogeneous case, dropping one variable
+  // by substituting the first variable by 1
+  int ho=homog(p);
+  if(ho)
+  {
+    int dh=deg(p);
+    p=subst(p,var(1),1);
+    int di=deg(p);
+  }
+
+  list tmpf=system ("absFact", p);
+
+  // the homogeneous case, homogenizing the result
+  // the new variable has to have degree 0
+  // need to change the ring
+  if(ho)
+  {
+    list ll=ringlist(MPo);
+    vv[size(vv)]=0;
+    ll[3][1][2]=vv;
+    def MPhelp=ring(ll);
+    setring(MPhelp);
+    list tmpf=imap(MPo,tmpf);
+    for(i=2;i<=size(tmpf[1]);i++)
+    {
+      tmpf[1][i]=homog(tmpf[1][i],var(1));
+    }
+    if(dh>di)
+    {
+      tmpf[1][size(tmpf[1])+1]=var(1);
+      tmpf[2][size(tmpf[2])+1]=dh-di;
+      tmpf[3][size(tmpf[3])+1]=par(npars(MPo));
+      tmpf[4]= tmpf[4]+dh-di;
+    }
+    setring(MPo);
+    tmpf=imap(MPhelp,tmpf);
+  }
+
+  if (pa)
+  {
+    number cok=imap(MP,cok);
+    tmpf[1][1]=cok*tmpf[1][1];
+  }
+
+  // if we want the output as string
+  if(size(#)>0)
+  {
+    if(typeof(#[1])=="int")
+    {
+      if(#[1]==77)
+      {  // undocumented feature for Gerhard's absPrimdecGTZ
+        if (size(tmpf[1])<2){ list abs_fac = list(var(n+1),poly(1)); }
+        else
+        {
+          list abs_fac= tmpf[3][2];
+          abs_fac= abs_fac, tmpf[1][2];
+          for (i= 3; i <= size(tmpf[1]); i++)
+          {
+            abs_fac=abs_fac,tmpf[3][i];
+            abs_fac=abs_fac,tmpf[1][i];
+          }
+        }
+        abs_fac=abs_fac,newvar;
+        string result = string(abs_fac);
+        setring(MP);
+        return(result);
+      }
+    }
+  }
+
+  list absolute_factors= tmpf;
+  export absolute_factors;
+  setring(MP);
+
+  dbprint( printlevel-voice+3,"
+// 'absFactorizeBCG' created a ring, in which a list absolute_factors (the
+// absolute factors) is stored.
+// To access the list of absolute factors, type (if the name S was assigned
+// to the return value):
+//        setring(S); absolute_factors;
+  ");
+  return(MPo);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring R = (0), (x,y), lp;
+  poly p = (-7*x^2 + 2*x*y^2 + 6*x + y^4 + 14*y^2 + 47)*(5x2+y2)^3*(x-y)^4;
+  def S = absFactorizeBCG(p) ;
+  setring(S);
+  absolute_factors;
+}
+
+
+/*
+  ring r=0,(x,t),dp;
+  poly p=x^4+(t^3-2t^2-2t)*x^3-(t^5-2t^4-t^2-2t-1)*x^2
+         -(t^6-4t^5+t^4+6t^3+2t^2)*x+(t^6-4t^5+2t^4+4t^3+t^2);
+  def S = absFactorize(p,"s");
+  setring(S);
+  absolute_factors;
+
+  ring r1=(0,a,b),(x,y),dp;
+  poly p=(a3-a2b+27ab3-27b4)/(a+b5)*x2+(a2+27b3)*y;
+  def S = absFactorize(p);
+  setring(S);
+  absolute_factors;
+
+  ring r2=0,(x,y,z,w),dp;
+  poly f=(x2+y2+z2)^2+w4;
+  def S =absFactorize(f);
+  setring(S);
+  absolute_factors;
+
+ring r=0,(x),dp;
+poly p=0;
+def S = absFactorize(p);
+setring(S);
+absolute_factors;
+
+ring r=0,(x),dp;
+poly p=7/11;
+def S = absFactorize(p);
+setring(S);
+absolute_factors;
+
+ring r=(0,a,b),(x,y),dp;
+poly p=0;
+def S = absFactorize(p);
+setring(S);
+absolute_factors;
+
+ring r=(0,a,b),(x,y),dp;
+poly p=(a+1)/b;
+def S = absFactorize(p);
+setring(S);
+absolute_factors;
+
+ring r=(0,a,b),(x,y),dp;
+poly p=(a+1)/b*x;
+def S = absFactorize(p,"s");
+setring(S);
+absolute_factors;
+
+ring r=(0,a,b),(x,y),dp;
+poly p=(a+1)/b*x + 1;
+def S = absFactorize(p,"s");
+setring(S);
+absolute_factors;
+
+ring r=(0,a,b),(x,y),dp;
+poly p=(a+1)/b*x + y;
+def S = absFactorize(p,"s");
+setring(S);
+absolute_factors;
+
+ring r=0,(x,t),dp;
+poly p=x^4+(t^3-2t^2-2t)*x^3-(t^5-2t^4-t^2-2t-1)*x^2
+       -(t^6-4t^5+t^4+6t^3+2t^2)*x+(t^6-4t^5+2t^4+4t^3+t^2);
+def S = absFactorize(p,"s");
+setring(S);
+absolute_factors;
+
+ring r1=(0,a,b),(x,y),dp;
+poly p=(a3-a2b+27ab3-27b4)/(a+b5)*x2+(a2+27b3)*y;
+def S = absFactorize(p);
+setring(S);
+absolute_factors;
+
+ring r2=0,(x,y,z,w),dp;
+poly f=(x2+y2+z2)^2+w4;
+def S =absFactorize(f);
+setring(S);
+absolute_factors;
+
+ring r3=0,(x,y,z,w),dp;
+poly f=(x2+y2+z2)^4+w8;
+def S =absFactorize(f);
+setring(S);
+absolute_factors;
+
+ring r4=0,(x,y),dp;
+poly f=y6-(2x2-2x-14)*y4-(4x3+35x2-6x-47)*y2+14x4-12x3-94x2;
+def S=absFactorize(f);
+setring(S);
+absolute_factors;
+
+ring R1 = 0, x, dp;
+def S1 = absFactorize(x4-2);
+setring(S1);
+absolute_factors;
+
+ring R3 = 0, (x,y), dp;
+poly f = x2y4+y6+2x3y2+2xy4-7x4+7x2y2+14y4+6x3+6xy2+47x2+47y2;
+def S3 = absFactorize(f);
+setring(S3);
+absolute_factors;
+
+ring R4 = 0, (x,y), dp;
+poly f = y4+2*xy2-7*x2+14*y2+6*x+47;
+def S4 = absFactorize(f);
+setring(S4);
+absolute_factors;
+
+*/
diff --git a/Singular/LIB/ainvar.lib b/Singular/LIB/ainvar.lib
new file mode 100644
index 0000000..08aa2f9
--- /dev/null
+++ b/Singular/LIB/ainvar.lib
@@ -0,0 +1,726 @@
+//////////////////////////////////////////////////////////////////////////////
+version="version ainvar.lib 4.0.0.0 Jun_2013 "; // $Id: 43bf74d54af86b68f5f318ff2719221f2488449a $
+category="Invariant theory";
+info="
+LIBRARY: ainvar.lib    Invariant Rings of the Additive Group
+AUTHORS: Gerhard Pfister (email: pfister at mathematik.uni-kl.de),
+         Gert-Martin Greuel (email: greuel at mathematik.uni-kl.de)
+
+PROCEDURES:
+  invariantRing(m..);  compute ring of invariants of (K,+)-action given by m
+  derivate(m,f);       derivation of f with respect to the vector field m
+  actionIsProper(m);   tests whether action defined by m is proper
+  reduction(p,I);      SAGBI reduction of p in the subring generated by I
+  completeReduction(); complete SAGBI reduction
+  localInvar(m,p..);   invariant polynomial under m computed from p,...
+  furtherInvar(m..);   compute further invariants of m from the given ones
+  sortier(id);         sorts generators of id by increasing leading terms
+";
+
+LIB "inout.lib";
+LIB "general.lib";
+LIB "algebra.lib";
+///////////////////////////////////////////////////////////////////////////////
+
+proc sortier(def id)
+"USAGE:   sortier(id);  id ideal/module
+RETURN:  the same ideal/module but with generators ordered by their
+         leading terms, starting with the smallest
+EXAMPLE: example sortier; shows an example
+"
+{
+  if(size(id)==0)
+  {return(id); }
+  intvec i=sortvec(id);
+  int j;
+  if( typeof(id)=="ideal")
+  { ideal m; }
+  if( typeof(id)=="module")
+  { module m; }
+  if( typeof(id)!="ideal" and  typeof(id)!="module")
+  { ERROR("input must be of type ideal or module"); }
+  for (j=1;j<=size(i);j++)
+  {
+    m[j] = id[i[j]];
+  }
+  return(m);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring q=0,(x,y,z,u,v,w),dp;
+   ideal i=w,x,z,y,v;
+   sortier(i);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc derivate (matrix m, def id)
+"USAGE:  derivate(m,id);  m matrix, id poly/vector/ideal
+ASSUME:  m is an nx1 matrix, where n = number of variables of the basering
+RETURN:  poly/vector/ideal (same type as input), result of applying the
+         vector field by the matrix m componentwise to id;
+NOTE:    the vector field is m[1,1]*d/dx(1) +...+ m[1,n]*d/dx(n)
+EXAMPLE: example derivate; shows an example
+"
+{
+  execute (typeof(id)+ " j;");
+  ideal I = ideal(id);
+  matrix mh=matrix(jacob(I))*m;
+  if(typeof(j)=="poly")
+  { j = mh[1,1];
+  }
+  else
+  { j = mh[1];
+  }
+  return(j);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring q=0,(x,y,z,u,v,w),dp;
+   poly f=2xz-y2;
+   matrix m[6][1] =x,y,0,u,v;
+   derivate(m,f);
+   vector v = [2xz-y2,u6-3];
+   derivate(m,v);
+   derivate(m,ideal(2xz-y2,u6-3));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc actionIsProper(matrix m)
+"USAGE:  actionIsProper(m); m matrix
+ASSUME:  m is a nx1 matrix, where n = number of variables of the basering
+RETURN:  int = 1, if the action defined by m is proper, 0 if not
+NOTE:    m defines a group action which is the exponential of the vector
+         field  m[1,1]*d/dx(1) +...+ m[1,n]*d/dx(n)
+EXAMPLE: example actionIsProper; shows an example
+"
+{
+  int i;
+  ideal id=maxideal(1);
+  def bsr=basering;
+
+  //changes the basering bsr to bsr[@t]
+  execute("ring s="+charstr(basering)+",("+varstr(basering)+", at t),dp;");
+  poly inv,delta,tee,j;
+  ideal id=imap(bsr,id);
+  matrix @m[size(id)+1][1];
+  @m=imap(bsr,m),0;
+  int auxv;
+
+  //computes the exp(@t*m)(var(i)) for all i
+  for(i=1;i<=nvars(basering)-1;i++)
+  {
+     inv=var(i);
+     delta=derivate(@m,inv);
+     j=1;
+     auxv=1;
+     tee=@t;
+     while(delta!=0)
+     {
+        inv=inv+1/j*delta*tee;
+        auxv=auxv+1;
+        j=j*auxv;
+        tee=tee*@t;
+        delta=derivate(@m,delta);
+     }
+     id=id+ideal(inv);
+  }
+  i=inSubring(@t,id)[1];
+  setring(bsr);
+  return(i);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+
+  ring rf=0,x(1..7),dp;
+  matrix m[7][1];
+  m[4,1]=x(1)^3;
+  m[5,1]=x(2)^3;
+  m[6,1]=x(3)^3;
+  m[7,1]=(x(1)*x(2)*x(3))^2;
+  actionIsProper(m);
+
+  ring rd=0,x(1..5),dp;
+  matrix m[5][1];
+  m[3,1]=x(1);
+  m[4,1]=x(2);
+  m[5,1]=1+x(1)*x(4)^2;
+  actionIsProper(m);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc reduction(poly p, ideal dom, list #)
+"USAGE:   reduction(p,I[,q,n]); p poly, I ideal, [q monomial, n int (optional)]
+RETURN:  a polynomial equal to  p-H(f1,...,fr), in case the leading
+         term LT(p) of p is of the form H(LT(f1),...,LT(fr)) for some
+         polynomial H in r variables over the base field, I=f1,...,fr;
+         if q is given, a maximal power a is computed such that q^a divides
+         p-H(f1,...,fr), and then (p-H(f1,...,fr))/q^a is returned;
+         return p if no H is found
+         if n=1, a different algorithm is chosen which is sometimes faster
+         (default: n=0; q and n can be given (or not) in any order)
+NOTE:    this is a kind of SAGBI reduction in the subalgebra K[f1,...,fr] of
+         the basering
+EXAMPLE: example reduction; shows an example
+"
+{
+  int i,choose;
+  int z=ncols(dom);
+  def bsr=basering;
+  if( size(#) >0 )
+  { if( typeof(#[1]) == "int")
+    { choose = #[1];
+    }
+    if( typeof(#[1]) == "poly")
+    { poly q = #[1];
+    }
+    if( size(#)>1 )
+    {  if( typeof(#[2]) == "poly")
+       { poly q = #[2];
+       }
+       if( typeof(#[2]) == "int")
+      { choose = #[2];
+      }
+    }
+  }
+
+  // -------------------- first algorithm (default) -----------------------
+  if ( choose == 0 )
+  {
+     list L = algebra_containment(lead(p),lead(dom),1);
+     if( L[1]==1 )
+     {
+  // the ring L[2] = char(bsr),(x(1..nvars(bsr)),y(1..z)),(dp(n),dp(m)),
+  // contains polynomial check s.t. LT(p) is of the form check(LT(f1),...,LT(fr))
+       def s1 = L[2];
+       map psi = s1,maxideal(1),dom;
+       poly re = p - psi(check);
+       // divide by the maximal power of #[1]
+          if ( defined(q) == voice )
+          {  while ((re!=0) && (re!=#[1]) &&(subst(re,#[1],0)==0))
+             {  re=re/#[1];
+             }
+          }
+          return(re);
+     }
+  return(p);
+  }
+  // ------------------------- second algorithm ---------------------------
+  else
+  {
+  //----------------- arranges the monomial v for elimination -------------
+     poly v=product(maxideal(1));
+
+  //------------- changes the basering bsr to bsr[@(0),...,@(z)] ----------
+  execute("ring s="+charstr(basering)+",("+varstr(basering)+",@(0..z)),dp;");
+// Ev hier die Reihenfolge der Vars aendern. Dazu muss unten aber entsprechend
+// geaendert werden:
+//  execute("ring s="+charstr(basering)+",(@(0..z),"+varstr(basering)+"),dp;");
+
+  //constructs the leading ideal of dom=(p-@(0),dom[1]-@(1),...,dom[z]-@(z))
+     ideal dom=imap(bsr,dom);
+     for (i=1;i<=z;i++)
+     {
+        dom[i]=lead(dom[i])-var(nvars(bsr)+i+1);
+     }
+     dom=lead(imap(bsr,p))-@(0),dom;
+
+  //---------- eliminates the variables of the basering bsr --------------
+  //i.e. computes dom intersected with K[@(0),...,@(z)] (this is hard)
+  //### hier Variante analog zu algebra_containment einbauen!
+     ideal kern=eliminate(dom,imap(bsr,v));
+
+  //---------  test wether @(0)-h(@(1),...,@(z)) is in ker ---------------
+  // for some polynomial h and divide by maximal power of q=#[1]
+     poly h;
+     z=size(kern);
+     for (i=1;i<=z;i++)
+     {
+        h=kern[i]/@(0);
+        if (deg(h)==0)
+        {  h=(1/h)*kern[i];
+        // define the map psi : s ---> bsr defined by @(i) ---> p,dom[i]
+           setring bsr;
+           map psi=s,maxideal(1),p,dom;
+           poly re=psi(h);
+           // divide by the maximal power of #[1]
+           if (size(#)>0)
+           {  while ((re!=0) && (re!=#[1]) &&(subst(re,#[1],0)==0))
+              {  re=re/#[1];
+              }
+           }
+           return(re);
+        }
+     }
+     setring bsr;
+     return(p);
+  }
+}
+
+example
+{ "EXAMPLE:"; echo = 2;
+   ring q=0,(x,y,z,u,v,w),dp;
+   poly p=x2yz-x2v;
+   ideal dom =x-w,u2w+1,yz-v;
+   reduction(p,dom);
+   reduction(p,dom,w);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc completeReduction(poly p, ideal dom, list #)
+"USAGE:   completeReduction(p,I[,q,n]); p poly, I ideal, [q monomial, n int]
+RETURN:  a polynomial, the SAGBI reduction of the polynomial p with respect to I
+         via the procedure 'reduction' as long as possible
+         if n=1, a different algorithm is chosen which is sometimes faster
+         (default: n=0; q and n can be given (or not) in any order)
+NOTE:    help reduction; shows an explanation of SAGBI reduction
+EXAMPLE: example completeReduction; shows an example
+"
+{
+  poly p1=p;
+  poly p2=reduction(p,dom,#);
+  while (p1!=p2)
+  {
+    p1=p2;
+    p2=reduction(p1,dom,#);
+  }
+  return(p2);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring q=0,(x,y,z,u,v,w),dp;
+   poly p=x2yz-x2v;
+   ideal dom =x-w,u2w+1,yz-v;
+   completeReduction(p,dom);
+   completeReduction(p,dom,w);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc completeReductionnew(poly p, ideal dom, list #)
+"USAGE:   completeReduction(p,I[,q,n]); p poly, I ideal, [q monomial, n int]
+RETURN:  a polynomial, the SAGBI reduction of the polynomial p with I
+         via the procedure 'reduction' as long as possible
+         if n=1, a different algorithm is chosen which is sometimes faster
+         (default: n=0; q and n can be given (or not) in any order)
+NOTE:    help reduction; shows an explanation of SAGBI reduction
+EXAMPLE: example completeReduction; shows an example
+"
+{
+  if(p==0)
+  {
+     return(p);
+  }
+  poly p1=p;
+  poly p2=reduction(p,dom,#);
+  while (p1!=p2)
+  {
+    p1=p2;
+    p2=reduction(p1,dom,#);
+  }
+  poly re=lead(p2)+completeReduction(p2-lead(p2),dom,#);
+  return(re);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc localInvar(matrix m, poly p, poly q, poly h)
+"USAGE:   localInvar(m,p,q,h); m matrix, p,q,h polynomials
+ASSUME:  m(q) and h are invariant under the vector field m, i.e. m(m(q))=m(h)=0
+         h must be a ring variable
+RETURN:  a polynomial, the invariant polynomial of the vector field
+ at format
+         m = m[1,1]*d/dx(1) +...+ m[n,1]*d/dx(n)
+ at end format
+         with respect to p,q,h. It is defined as follows: set inv = p if p is
+         invariant, and else set
+         inv = m(q)^N * sum_i=1..N-1{ (-1)^i*(1/i!)*m^i(p)*(q/m(q))^i }
+         where m^N(p) = 0,  m^(N-1)(p) != 0; the result is inv divided by h
+         as often as possible
+EXAMPLE: example localInvar; shows an example
+"
+{
+  if ((derivate(m,h) !=0) || (derivate(m,derivate(m,q)) !=0))
+  {
+    "//the last two polynomials of the input must be invariant functions";
+    return(q);
+  }
+  int ii,k;
+  for ( k=1; k <= nvars(basering); k++  )
+  {  if (h == var(k))
+     { ii=1;
+     }
+  }
+  if( ii==0 )
+  {  "// the last argument must be a ring variable";
+     return(q);
+  }
+
+  poly inv=p;
+  poly dif= derivate(m,inv);
+  poly a=derivate(m,q);
+  poly sgn=-1;
+  poly coeff=sgn*q;
+  k=1;
+  if (dif==0)
+  {
+    return(inv);
+  }
+  while (dif!=0)
+  {
+    inv=(a*inv)+(coeff*dif);
+    dif=derivate(m,dif);
+    k=k+1;
+    coeff=q*coeff*sgn/k;
+  }
+  while ((inv!=0) && (inv!=h) &&(subst(inv,h,0)==0))
+ {
+   inv=inv/h;
+  }
+  return(inv);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring q=0,(x,y,z),dp;
+   matrix m[3][1];
+   m[2,1]=x;
+   m[3,1]=y;
+   poly in=localInvar(m,z,y,x);
+   in;
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc furtherInvar(matrix m, ideal id, ideal karl, poly q, list #)
+"USAGE:   furtherInvar(m,id,karl,q); m matrix, id,karl ideals, q poly, n int
+ASSUME:  karl,id,q are invariant under the vector field m,
+         moreover, q must be a variable
+RETURN:  list of two ideals, the first ideal contains further invariants of
+         the vector field
+ at format
+         m = sum m[i,1]*d/dx(i) with respect to id,p,q,
+ at end format
+         i.e. we compute elements in the (invariant) subring generated by id
+         which are divisible by q and divide them by q as often as possible.
+         The second ideal contains all invariants given before.
+         If n=1, a different algorithm is chosen which is sometimes faster
+         (default: n=0)
+EXAMPLE: example furtherInvar; shows an example
+"
+{
+  list ll = q;
+  if ( size(#)>0 )
+  {  ll = ll+list(#[1]);
+  }
+  int i;
+  ideal null,eins;
+  int z=ncols(id);
+  intvec v;
+  def br=basering;
+  ideal su;
+  for (i=1; i<=z; i++)
+  {
+    su[i]=subst(id[i],q,0);
+  }
+  // -- define the map phi : r1 ---> br defined by y(i) ---> id[i](q=0) --
+  execute ("ring r1="+charstr(basering)+",(y(1..z)),dp;");
+  setring br;
+  map phi=r1,su;
+  setring r1;
+  // --------------- compute the kernel of phi ---------------------------
+  ideal ker=preimage(br,phi,null);
+  ker=mstd(ker)[2];
+  // ---- define the map psi : r1 ---> br defined by y(i) ---> id[i] -----
+  setring br;
+  map psi=r1,id;
+  // -------------------  compute psi(ker(phi)) --------------------------
+  ideal rel=psi(ker);
+  // divide by maximal power of q, test wether we really obtain invariants
+  for (i=1;i<=size(rel);i++)
+  {
+    while ((rel[i]!=0) && (rel[i]!=q) &&(subst(rel[i],q,0)==0))
+    {
+      rel[i]=rel[i]/q;
+      if (derivate(m,rel[i])!=0)
+      {
+         "// error in furtherInvar, function not invariant:";
+         rel[i];
+      }
+    }
+    rel[i]=simplify(rel[i],1);
+  }
+  // ---------------------------------------------------------------------
+  // test whether some variables occur linearly and then delete the
+  // corresponding invariant function
+  setring r1;
+  int j;
+  for (i=1;i<=size(ker);i=i+1)
+  {
+     for (j=1;j<=z;j++)
+     {
+        if (deg(ker[i]/y(j))==0)
+        {
+           setring br;
+           rel[i]= completeReduction(rel[i],karl,ll);
+           if(rel[i]!=0)
+           {
+              karl[j+1]=rel[i];
+              rel[i]=0;
+              eins=1;
+           }
+           setring r1;
+        }
+     }
+
+  }
+  setring br;
+  rel=rel+null;
+  if(size(rel)==0){rel=eins;}
+  list l=rel,karl;
+  return(l);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r=0,(x,y,z,u),dp;
+   matrix m[4][1];
+   m[2,1]=x;
+   m[3,1]=y;
+   m[4,1]=z;
+   ideal id=localInvar(m,z,y,x),localInvar(m,u,y,x);
+   ideal karl=id,x;
+   list in=furtherInvar(m,id,karl,x);
+   in;
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc invariantRing(matrix m, poly p, poly q, int b, list #)
+"USAGE:   invariantRing(m,p,q,b[,r,pa]); m matrix, p,q poly, b,r int, pa string
+ASSUME:  p,q variables with m(p)=q and q invariant under m
+         i.e. if p=x(i) and q=x(j) then m[j,1]=0 and m[i,1]=x(j)
+RETURN:  ideal, containing generators of the ring of invariants of the
+         additive group (K,+) given by the vector field
+ at format
+         m = m[1,1]*d/dx(1) +...+ m[n,1]*d/dx(n).
+ at end format
+         If b>0 the computation stops after all invariants of degree <= b
+         (and at least one of higher degree) are found or when all invariants
+         are computed.
+         If b<=0, the computation continues until all generators
+         of the ring of invariants are computed (should be used only if the
+         ring of invariants is known to be finitely generated, otherwise the
+         algorithm might not stop).
+         If r=1 a different reduction is used which is sometimes faster
+         (default r=0).
+DISPLAY: if pa is given (any string as 5th or 6th argument), the computation
+         pauses whenever new invariants are found and displays them
+THEORY:  The algorithm for computing the ring of invariants works in char 0
+         or suffiently large characteristic.
+         (K,+) acts as the exponential of the vector field defined by the
+         matrix m.
+         For background see G.-M. Greuel, G. Pfister,
+         Geometric quotients of unipotent group actions, Proc.
+         London Math. Soc. (3) 67, 75-105 (1993).
+EXAMPLE: example invariantRing; shows an example
+"
+{
+  ideal j;
+  int i,it;
+  list ll=q;
+  int bou=b;
+  if( size(#) >0 )
+  { if( typeof(#[1]) == "int")
+    { ll=ll+list(#[1]);
+    }
+    if( typeof(#[1]) == "string")
+    { string pau=#[1];
+    }
+    if( size(#)>1 )
+    {
+      if( typeof(#[2]) == "string")
+      { string pau=#[2];
+      }
+      if( typeof(#[2]) == "int")
+      { ll=ll+list(#[2]);
+      }
+    }
+  }
+  int z;
+  ideal karl;
+  ideal k1=1;
+  list k2;
+  //------------------ computation of local invariants ------------------
+  for (i=1;i<=nvars(basering);i++)
+  {
+    karl=karl+localInvar(m,var(i),p,q);
+  }
+  if( defined(pau) )
+  {  "";
+     "// local invariants computed:";
+     "";
+     karl;
+     "";
+     pause("// hit return key to continue!");
+     "";
+  }
+  //------------------ computation of further invariants ----------------
+  it=0;
+  while (size(k1)!=0)
+  {
+    // test if the new invariants are already in the ring generated
+    // by the invariants we constructed so far
+    it++;
+    karl=sortier(karl);
+    j=q;
+    for (i=1;i<=size(karl);i++)
+    {
+       j=j + simplify(completeReduction(karl[i],j,ll),1);
+    }
+    karl=j;
+    j[1]=0;
+    j=simplify(j,2);
+    k2=furtherInvar(m,j,karl,q);
+    k1=k2[1];
+    karl=k2[2];
+    if(k1[1]!=1)
+    {
+       k1=sortier(k1);
+       z=size(k1);
+       for (i=1;i<=z;i++)
+       {
+          k1[i]= completeReduction(k1[i],karl,ll);
+          if (k1[i]!=0)
+          {
+            karl=karl+simplify(k1[i],1);
+          }
+       }
+       if( defined(pau) == voice)
+       {
+       "// the invariants after",it,"iteration(s):"; "";
+       karl;"";
+       pause("// hit return key to continue!");
+       "";
+       }
+       if( (bou>0) && (size(k1)>0) )
+       {
+         if( deg(k1[size(k1)])>bou )
+        {
+            return(karl);
+        }
+      }
+    }
+  }
+  return(karl);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+
+  //Winkelmann: free action but Spec(k[x(1),...,x(5)]) --> Spec(invariant ring)
+  //is not surjective
+
+  ring rw=0,(x(1..5)),dp;
+  matrix m[5][1];
+  m[3,1]=x(1);
+  m[4,1]=x(2);
+  m[5,1]=1+x(1)*x(4)+x(2)*x(3);
+  ideal in=invariantRing(m,x(3),x(1),0);      //compute full invarint ring
+  in;
+
+  //Deveney/Finston: The ring of invariants is not finitely generated
+
+  ring rf=0,(x(1..7)),dp;
+  matrix m[7][1];
+  m[4,1]=x(1)^3;
+  m[5,1]=x(2)^3;
+  m[6,1]=x(3)^3;
+  m[7,1]=(x(1)*x(2)*x(3))^2;
+  ideal in=invariantRing(m,x(4),x(1),6);      //all invariants up to degree 6
+  in;
+}
+///////////////////////////////////////////////////////////////////////////////
+/*             Further examplex
+
+  //Deveney/Finston: Proper Ga-action which is not locally trivial
+  //r[x(1),...,x(5)] is not flat over the ring of invariants
+  LIB "invar.lib";
+  ring rd=0,(x(1..5)),dp;
+  matrix m[5][1];
+  m[3,1]=x(1);
+  m[4,1]=x(2);
+  m[5,1]=1+x(1)*x(4)^2;
+  ideal in=invariantRing(m,x(3),x(1),0,1);
+  in;
+
+  actionIsProper(m);
+
+  //compute the algebraic relations between the invariants
+  int z=size(in);
+  ideal null;
+  ring r1=0,(y(1..z)),dp;
+  setring rd;
+  map phi=r1,in;
+  setring r1;
+  ideal ker=preimage(rd,phi,null);
+  ker;
+
+  //the discriminant
+
+  ring r=0,(x(1..2),y(1..2),z,t),dp;
+  poly p=z+(1+x(1)*y(2)^2)*t+x(1)*y(1)*y(2)*t^2+(1/3)*x(1)*y(1)^2*t^3;
+
+  matrix m[5][5];
+  m[1,1]=z;
+  m[1,2]=x(1)*y(2)^2+1;
+  m[1,3]=x(1)*y(1)*y(2);
+  m[1,4]=1/3*x(1)*y(1)^2;
+  m[1,5]=0;
+  m[2,1]=0;
+  m[2,2]=z;
+  m[2,3]=x(1)*y(2)^2+1;
+  m[2,4]=x(1)*y(1)*y(2);
+  m[2,5]=1/3*x(1)*y(1)^2;
+  m[3,1]=x(1)*y(2)^2+1;
+  m[3,2]=2*x(1)*y(1)*y(2);
+  m[3,3]=x(1)*y(1)^2;
+  m[3,4]=0;
+  m[3,5]=0;
+  m[4,1]=0;
+  m[4,2]=x(1)*y(2)^2+1;
+  m[4,3]=2*x(1)*y(1)*y(2);
+  m[4,4]=x(1)*y(1)^2;
+  m[4,5]=0;
+  m[5,1]=0;
+  m[5,2]=0;
+  m[5,3]=x(1)*y(2)^2+1;
+  m[5,4]=2*x(1)*y(1)*y(2);
+  m[5,5]=x(1)*y(1)^2;
+
+  poly disc=9*det(m)/(x(1)^2*y(1)^4);
+
+  LIB "invar.lib";
+  matrix n[6][1];
+  n[2,1]=x(1);
+  n[4,1]=y(1);
+  n[5,1]=1+x(1)*y(2)^2;
+
+  derivate(n,disc);
+
+//x(1)^3*y(2)^6-6*x(1)^2*y(1)*y(2)^3*z+6*x(1)^2*y(2)^4+9*x(1)*y(1)^2*z^2-18*x(1)*y(1)*y(2)*z+9*x(1)*y(2)^2+4
+
+//////////////////////////////////////////////////////////////////////////////
+//constructive approach to Weizenboecks theorem
+
+  int n=5;
+  // int n=6;  //limit
+  ring w=32003,(x(1..n)),wp(1..n);
+
+  // definition of the vector field m=sum m[i]*d/dx(i)
+  matrix m[n][1];
+  int i;
+  for (i=1;i<=n-1;i=i+1)
+  {
+    m[i+1,1]=x(i);
+  }
+  ideal in=invariantRing(m,x(2),x(1),0,"");
+
+  in;
+*/
diff --git a/Singular/LIB/aksaka.lib b/Singular/LIB/aksaka.lib
new file mode 100644
index 0000000..7ff75df
--- /dev/null
+++ b/Singular/LIB/aksaka.lib
@@ -0,0 +1,419 @@
+////////////////////////////////////////////////////////////////////////////////
+version="version aksaka.lib 4.0.0.1 Jun_2014 "; // $Id: bc74504c42ff955c330251e3f092f84d4c6c8a0d $
+category="Teaching";
+info="
+LIBRARY: aksaka.lib     Procedures for primality testing after Agrawal, Saxena, Kayal
+AUTHORS: Christoph Mang
+
+OVERVIEW:
+ Algorithms for primality testing in polynomial time
+ based on the ideas of Agrawal, Saxena and  Kayal.
+
+PROCEDURES:
+
+fastExpt(a,m,n)         a^m for numbers a,m; if a^k>n n+1 is returned
+log2(n)                    logarithm to basis 2 of n
+PerfectPowerTest(n)        checks if there are a,b>1, so that a^b=n
+wurzel(r)                  square root of number r
+euler(r)                   phi-function of Euler
+coeffmod(f,n)              polynomial f modulo number n (coefficients mod n)
+powerpolyX(q,n,a,r)        (polynomial a)^q modulo (poly r,number n)
+ask(n)                     ASK-Algorithm; deterministic Primality test
+";
+
+LIB "crypto.lib";
+LIB "ntsolve.lib";
+
+///////////////////////////////////////////////////////////////
+//                                                           //
+//   FAST (MODULAR) EXPONENTIATION                           //
+//                                                           //
+///////////////////////////////////////////////////////////////
+proc fastExpt(bigint a,bigint m,bigint n)
+"USAGE: fastExpt(a,m,n); a, m, n = number;
+RETURN: the m-th power of a; if a^m>n the procedure returns n+1
+NOTE:   uses fast exponentiation
+EXAMPLE:example fastExpt; shows an example
+"
+{
+  bigint b,c,d;
+  c=m;
+  b=a;
+  d=1;
+  while(c>=1)
+  {
+    if(b>n)
+    {
+      return(n+1);
+    }
+    if((c mod 2)==1)
+    {
+      d=d*b;
+      if(d>n)
+      {
+        return(n+1);
+      }
+    }
+    b=b^2;
+    c=c div 2;
+  }
+  return(d)
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   fastExpt(2,10,1022);
+}
+////////////////////////////////////////////////////////////////////////////
+proc coeffmod(poly f,bigint n)
+"USAGE: coeffmod(f,n);
+ASSUME: poly f depends on at most var(1) of the basering
+RETURN: poly f modulo number n
+NOTE:   at first the coefficients of the monomials of the polynomial f are
+        determined, then their remainder modulo n is calculated,
+        after that the polynomial 'is put together' again
+EXAMPLE:example coeffmod; shows an example
+"
+{
+  matrix M=coeffs(f,var(1));         //Bestimmung der Polynomkoeffizienten
+  int i=1;
+  poly g;
+  int o=nrows(M);
+
+  while(i<=o)
+  {
+    g=g+(bigint(leadcoef(M[i,1])) mod n)*var(1)^(i-1) ;
+                   // umwandeln der Koeffizienten in bigint,
+                   // Berechnung der Reste dieser bigint modulo n,
+                   // Polynom mit neuen Koeffizienten wieder zusammensetzen
+    i++;
+  }
+  return(g);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring R = 0,x,dp;
+   poly f=2457*x4+52345*x3-98*x2+5;
+   bigint n=3;
+   coeffmod(f,n);
+}
+//////////////////////////////////////////////////////////////////////////
+proc powerpolyX(bigint q,bigint n,poly a,poly r)
+"USAGE: powerpolyX(q,n,a,r);
+RETURN: the q-th power of poly a modulo poly r and number n
+EXAMPLE:example powerpolyX; shows an example
+"
+{
+  ideal I=r;
+
+  if(q==1){return(coeffmod(reduce(a,I),n));}
+  if((q mod 5)==0){return(coeffmod(reduce(powerpolyX(q div 5,n,a,r)^5,I),n));}
+  if((q mod 4)==0){return(coeffmod(reduce(powerpolyX(q div 4,n,a,r)^4,I),n));}
+  if((q mod 3)==0){return(coeffmod(reduce(powerpolyX(q div 3,n,a,r)^3,I),n));}
+  if((q mod 2)==0){return(coeffmod(reduce(powerpolyX(q div 2,n,a,r)^2,I),n));}
+
+  return(coeffmod(reduce(a*powerpolyX(q-1,n,a,r),I),n));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring R=0,x,dp;
+   poly a=3*x3-x2+5;
+   poly r=x7-1;
+   bigint q=123;
+   bigint n=5;
+   powerpolyX(q,n,a,r);
+}
+///////////////////////////////////////////////////////////////
+//                                                           //
+//   GENERAL PROCEDURES                                      //
+//                                                           //
+///////////////////////////////////////////////////////////////
+proc log2(bigint xx)
+"USAGE:  log2(x);
+RETURN:  logarithm to basis 2 of x
+NOTE:    calculates the natural logarithm of x with a power-series
+         of the ln, then the basis is changed to 2
+EXAMPLE: example log2; shows an example
+"
+{
+  ring r=0, at x,dp;
+  number b,c,d,t,l,x;
+  x=number(xx);
+  int k;
+                                         // log2=logarithmus zur basis 2,
+                                         // log=natuerlicher logarithmus
+  b=100000000000000000000000000000000000000000000000000;
+  c=141421356237309504880168872420969807856967187537695;    // c/b=sqrt(2)
+  d=69314718055994530941723212145817656807550013436026;     // d/b=log(2)
+
+  //bringen x zunaechst zwischen 1/sqrt(2) und sqrt(2), so dass Reihe schnell
+  //konvergiert, berechnen dann Reihe bis 30. Summanden und letztendlich
+  //log2(x)=log(x)/log(2)=(log(x/2^j)+j*log(2))/log(2)  fuer grosse x
+  //log2(x)=log(x)/log(2)=(log(x*2^j)-j*log(2))/log(2)  fuer kleine x
+
+  number j=0;
+  if(x<(b/c))
+  {
+    while(x<(b/c))
+    {
+      x=x*2;
+      j=j+1;
+    }
+    t=(x-1)/(x+1);
+    k=0;
+    l=0;
+    while(k<30)       //fuer  x*2^j wird Reihe bis k-tem Summanden berechnet
+    {
+      l=l+2*(t^(2*k+1))/(2*k+1);      //l=log(x*2^j) nach k Summanden
+      k=k+1;
+    }
+    return (intPart((l*b/d)-j));         //log2(x)=log(x*2^j)/log(2)-j wird ausgegeben
+  }
+  while(x>(c/b))
+  {
+    x=x/2;
+    j=j+1;
+  }
+  t=(x-1)/(x+1);
+  k=0;
+  l=0;
+  while(k<30)         //fuer  x/2^j wird Reihe bis k-tem Summanden berechnet
+  {
+    l=l+2*(t^(2*k+1))/(2*k+1);       //l=log(x/2^j) nach k Summanden
+    k=k+1;
+  }
+  return(intPart(((l*b/d)+j)));     //hier wird log2(x)=log(x/2^j)/log(2)+j  ausgegeben
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   log2(1024);
+}
+//////////////////////////////////////////////////////////////////////////
+proc wurzel(number r)
+"USAGE: wurzel(r);
+ASSUME: characteristic of basering is 0, r>=0
+RETURN: number, square root of r
+EXAMPLE:example wurzel; shows an example
+"
+{
+  poly f=var(1)^2-r;             //Wurzel wird als Nullstelle eines Polys
+                                 //mit proc nt_solve genaehert
+  def B=basering;
+  ring R=(real,40),var(1),dp;
+  poly g=imap(B,f);
+  list l=nt_solve(g,1.1);
+  number m=leadcoef(l[1][1]);
+  setring B;
+  return(imap(R,m));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring R = 0,x,dp;
+   wurzel(7629412809180100);
+}
+//////////////////////////////////////////////////////////////////////////
+proc euler(bigint r)
+"USAGE: euler(r);
+RETURN: bigint phi(r), where phi is Eulers phi-function
+NOTE:   first r is factorized with proc PollardRho, then phi(r) is
+        calculated with the help of phi(p) of every factor p;
+EXAMPLE:example euler; shows an example
+"
+{
+  list l=PollardRho(r,5000,1);           //bestimmen der Primfaktoren von r
+  int k;
+  bigint phi=r;
+  for(k=1;k<=size(l);k++)
+  {
+    phi=phi-phi div l[k];       //berechnen phi(r) mit Hilfe der
+  }                         //Primfaktoren und Eigenschaften der phi-Fktn
+  return(phi);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   euler(99991);
+}
+///////////////////////////////////////////////////////////////
+//                                                           //
+//   PERFECT POWER TEST                                      //
+//                                                           //
+///////////////////////////////////////////////////////////////
+proc PerfectPowerTest(bigint n)
+"USAGE: PerfectPowerTest(n);
+RETURN: 0 if there are numbers a,b>1 with a^b=n;
+        1 if there are no numbers a,b>1 with a^b=n;
+        if printlevel>=1 and there are a,b>1 with a^b=n,
+        then a,b are printed
+EXAMPLE:example PerfectPowerTest; shows an example
+"
+{
+  bigint a,b,c,e,f,m,l,p;
+  b=2;
+  l=log2(n);
+  e=0;
+  f=1;
+
+  while(b<=l)
+  {
+    a=1;
+    c=n;
+
+    while(c-a>=2)
+    {
+      m=(a+c) div 2;
+      p=fastExpt(m,b,n);
+
+      if(p==n)
+      {
+        if(printlevel>=1){"es existieren Zahlen a,b>1 mit a^b=n";
+                      "a=";m;"b=";b;pause();}
+        return(e);
+      }
+
+      if(p<n)
+      {
+        a=m;
+      }
+      else
+      {
+        c=m;
+      }
+    }
+    b=b+1;
+  }
+  if(printlevel>=1){"es existieren keine Zahlen a,b>1  mit a^b=n";pause();}
+  return(f);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   PerfectPowerTest(887503681);
+}
+///////////////////////////////////////////////////////////////
+//                                                           //
+//   ASK PRIMALITY TEST                                      //
+//                                                           //
+///////////////////////////////////////////////////////////////
+proc ask(bigint n)
+"USAGE: ask(n);
+ASSUME: n>1
+RETURN: 0 if n is composite;
+        1 if n is prime;
+        if printlevel>=1, you are informed what the procedure will do
+        or has calculated
+NOTE:   ASK-algorithm; uses proc powerpolyX for step 5
+EXAMPLE:example ask; shows an example
+"
+{
+  bigint c,p;
+  c=0;
+  p=1;
+
+  if(n==2) { return(p); }
+  if(printlevel>=1){"Beginn: Test ob a^b=n fuer a,b>1";pause();}
+  if(0==PerfectPowerTest(n))             // Schritt1 des ASK-Alg.
+  { return(c); }
+  if(printlevel>=1)
+  {
+    "Beginn: Berechnung von r, so dass ord(n) in Z/rZ groesser log2(n)^2 ";
+    pause();
+  }
+  bigint k,M,M2,b;
+  int r;                          // Zeile 526-542: Schritt 2
+  M=log2(n);                      // darin sind die Schritte
+  M2=M^2;                         // 3 und 4 integriert
+  r=2;
+
+  if(gcd(n,r)!=1)   //falls ggt ungleich eins, Teiler von n gefunden,
+                    // Schritt 3 des ASK-Alg.
+  {
+    if(printlevel>=1){"Zahl r gefunden mit r|n";"r=";r;pause();}
+    return(c);
+  }
+  if(r==n-1)              // falls diese Bedingung erfuellt ist, ist
+                         // ggT(a,n)=1 fuer 0<a<=r, schritt 4 des ASK-Alg.
+  {
+    if(printlevel>=1){"ggt(r,n)=1 fuer alle 1<r<n";pause();}
+    return(p);
+  }
+  k=1;
+  b=1;
+
+  while(k<=M2)         //Beginn des Ordnungstests fuer aktuelles r
+  {
+    b=((b*n) mod r);
+    if(b==1)   //tritt Bedingung ein so gilt fuer aktuelles r,k:
+               //n^k=1 mod r
+               //tritt Bedingung ein, wird wegen k<=M2=intPart(log2(n)^2)
+               //r erhoeht,k=0 gesetzt und Ordnung erneut untersucht
+               //tritt diese Bedingung beim groessten k=intPart(log2(n)^2)
+               //nicht ein, so ist ord_r_(n)>log2(n)^2 und Schleife
+               //wird nicht mehr ausgefuehrt
+    {
+      if(r==2147483647)
+      {
+        string e="error: r ueberschreitet integer Bereich und darf
+                  nicht als Grad eines Polynoms verwendet werden";
+        return(e);
+      }
+      r=r+1;
+      if(gcd(n,r)!=1)   //falls ggt ungleich eins, Teiler von n gefunden,
+                         //wird aufgrund von Schritt 3 des ASK-Alg. fuer
+                         //jeden Kandidaten r getestet
+      {
+        if(printlevel>=1){"Zahl r gefunden mit r|n";"r=";r;pause();}
+        return(c);
+      }
+      if(r==n-1)         //falls diese Bedingung erfuellt ist,
+                         //ist n wegen Zeile 571 prim
+                         //wird aufgrund von Schritt 4 des ASK-Alg. fuer
+                         //jeden Kandidaten r getestet
+      {
+        if(printlevel>=1){"ggt(r,n)=1 fuer alle 1<r<n";pause();}
+        return(p);
+      }
+
+      k=0;               //fuer neuen Kandidaten r, muss k fuer den
+                         //Ordnungstest zurueckgesetzt werden
+    }
+    k=k+1;
+  }
+  if(printlevel>=1)
+  {
+    "Zahl r gefunden, so dass ord(n) in Z/rZ groesser log2(n)^2 ";
+    "r=";r;pause();
+  }
+  ring @R=0, at x,dp;
+  bigint l=1;                         // Zeile 603-628: Schritt 5
+  poly f,g;                           // Zeile 618 ueberprueft Gleichungen fuer
+                                      // das jeweilige a
+  g=var(1)^r-1;
+  bigint grenze=intPart(wurzel(euler(r))*M);
+
+  if(printlevel>=1)
+  {"Beginn: Ueberpruefung ob (x+a)^n kongruent x^n+a mod (x^r-1,n)
+        fuer 0<a<=intPart(wurzel(phi(r))*log2(n))=";grenze;pause();
+  }
+  while(l<=grenze)          //
+  {
+    if(printlevel>=1){"a=";l;}
+    f=var(1)+l;
+    if(powerpolyX(bigint(n),bigint(n),f,g)!=(var(1)^(int((n mod r)))+l))
+    {
+      if(printlevel>=1)
+      {"Fuer a=";l;"ist (x+a)^n nicht kongruent x^n+a mod (x^r-1,n)";
+        pause();
+      }
+      return(c);
+    }
+    l=l+1;
+  }
+  if(printlevel>=1)
+  {"(x+a)^n kongruent x^n+a mod (x^r-1,n) fuer 0<a<wurzel(phi(r))*log2(n)";
+    pause();
+  }
+  return(p);       // Schritt 6
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   //ask(100003);
+   ask(32003);
+}
diff --git a/Singular/LIB/alexpoly.lib b/Singular/LIB/alexpoly.lib
new file mode 100644
index 0000000..8588906
--- /dev/null
+++ b/Singular/LIB/alexpoly.lib
@@ -0,0 +1,2496 @@
+////
+version="version alexpoly.lib 4.0.0.0 Jun_2013 "; // $Id: 618e58dbd3c8aa362df31c396d982cdb691407c0 $
+category="Singularities";
+info="
+LIBRARY:  alexpoly.lib   Resolution Graph and Alexander Polynomial
+AUTHOR:   Fernando Hernando Carrillo, hernando at agt.uva.es
+          Thomas Keilen,   keilen at mathematik.uni-kl.de
+
+OVERVIEW:
+ A library for computing the resolution graph of a plane curve singularity f,
+ the total multiplicities of the total transforms of the branches of f along
+ the exceptional divisors of a minimal good resolution of f, the Alexander
+ polynomial of f, and the zeta function of its monodromy operator.
+
+PROCEDURES:
+ resolutiongraph(f);        resolution graph f
+ totalmultiplicities(f);    resolution graph, total multiplicities and strict multiplicities of f
+ alexanderpolynomial(f);    Alexander polynomial of f
+ semigroup(f);              calculates generators for the semigroup of f
+ proximitymatrix(f);        calculates the proximity matrix of f
+ multseq2charexp(v);        converts multiplicity sequence to characteristic exponents
+ charexp2multseq(v);        converts characteristic exponents to multiplicity sequence
+ charexp2generators(v);     converts characteristic exponents to generators of the semigroup
+ charexp2inter(c,e);        converts contact matrix and charact. exp. to intersection matrix
+ charexp2conductor(v);      converts characteristic exponents to conductor
+ charexp2poly(v,a);         calculates a polynomial f with characteristic exponents v
+ tau_es2(f);                equisingular Tjurina number of f
+
+KEYWORDS: Hamburger-Noether expansion; Puiseux expansion; curve singularities;
+          topological invariants; Alexander polynomial; resolution graph;
+          total multiplicities; equisingular Tjurina number
+";
+
+///////////////////////////////////////////////////////////////////////////////////////////
+LIB "hnoether.lib";
+///////////////////////////////////////////////////////////////////////////////////////////
+
+proc resolutiongraph (def INPUT,list #)
+"USAGE:  resolutiongraph(INPUT); INPUT poly or list
+ASSUME:  INPUT is either a REDUCED bivariate polynomial defining a plane curve singularity,
+         or the output of @code{hnexpansion(f[,\"ess\"])}, or the list @code{hne} in
+         the ring created by @code{hnexpansion(f[,\"ess\"])}, or the output of
+         @code{develop(f)} resp. of @code{extdevelop(f,n)}, or a list containing
+         the contact matrix and a list of integer vectors with the characteristic exponents
+         of the branches of a plane curve singularity, or an integer vector containing the
+         characteristic exponents of an irreducible plane curve singularity.
+RETURN:  intmat, the incidence matrix of the resolution graph of the plane curve
+         defined by INPUT, where the entries on the diagonal are the weights of the
+         vertices of the graph and a negative entry corresponds to the strict transform
+         of a branch of the curve.
+NOTE:    In case the Hamburger-Noether expansion of the curve f is needed
+         for other purposes as well it is better to calculate this first
+         with the aid of @code{hnexpansion} and use it as input instead of
+         the polynomial itself.
+         @*
+         If you are not sure whether the INPUT polynomial is reduced or not, use
+         @code{squarefree(INPUT)} as input instead.
+SEE ALSO: develop, hnexpansion, totalmultiplicities, alexanderpolynomial
+EXAMPLE: example resolutiongraph;  shows an example
+"
+{
+  return(totalmultiplicities(INPUT,#)[1]);
+}
+example
+{
+  "EXAMPLE:";
+  echo=2;
+  ring r=0,(x,y),ls;
+  poly f1=(y2-x3)^2-4x5y-x7;
+  poly f2=y2-x3;
+  poly f3=y3-x2;
+  resolutiongraph(f1*f2*f3);
+}
+
+proc totalmultiplicities (def INPUT, list #)
+"USAGE:  totalmultiplicities(INPUT); INPUT poly or list
+ASSUME:  INPUT is either a REDUCED bivariate polynomial defining a plane curve singularity,
+         or the output of @code{hnexpansion(f[,\"ess\"])}, or the list @code{hne} in
+         the ring created by @code{hnexpansion(f[,\"ess\"])}, or the output of
+         @code{develop(f)} resp. of @code{extdevelop(f,n)}, or a list containing
+         the contact matrix and a list of integer vectors with the characteristic exponents
+         of the branches of a plane curve singularity, or an integer vector containing the
+         characteristic exponents of an irreducible plane curve singularity.
+RETURN:  list @code{L} of three integer matrices. @code{L[1]} is the incidence matrix of
+         the resolution graph of the plane curve defined by INPUT, where the entries on the
+         diagonal are the weights of the vertices of the graph and a negative entry corresponds
+         to the strict transform of a branch of the curve. @code{L[2]} is an integer matrix,
+         which has for each vertex in the graph a row and for each branch of the curve a column.
+         The entry in position [i,j] contains the total multiplicity of the j-th branch (i.e. the
+         branch with weight -j in @code{L[1]}) along the exceptional divisor corresponding
+         to the i-th row in @code{L[1]}. In particular, the i-th row contains
+         the total multiplicities of the branches of the plane curve (defined by INPUT) along
+         the exceptional divisor which corresponds to the i-th row in the incidence matrix
+         @code{L[1]}. @code{L[3]} is an integer matrix which contains the (strict) multiplicities
+         of the branches of the curve along the exceptional divisors in the same way as @code{L[2]}
+         contains the total multiplicities.
+NOTE:    The total multiplicty of a branch along an exceptional divisor is the multiplicity
+         with which this exceptional divisor occurs in the total transform of this branch
+         under the resolution corresponding to the resolution graph.
+         @*
+         In case the Hamburger-Noether expansion of the curve f is needed
+         for other purposes as well it is better to calculate this first
+         with the aid of @code{hnexpansion} and use it as input instead of
+         the polynomial itself.
+         @*
+         If you are not sure whether the INPUT polynomial is reduced or not, use
+         @code{squarefree(INPUT)} as input instead.
+SEE ALSO: develop, hnexpansion, alexanderpolynomial, resolutiongraph
+EXAMPLE: example totalmultiplicities;  shows an example
+"
+{
+  ///////////////////////////////////////////////////////////////////////////////////////////////
+  /// The algorithm described in [JP] DeJong, Pfister, Local Analytic Geometry, Vieweg 2000,
+  /// is used for the implementation -- the missing case is included by appropriate sorting.
+  ///////////////////////////////////////////////////////////////////////////////////////////////
+  /// If # is empty, then an additional sorting of the branches will be made, so that
+  /// the branches can be split with split_graph in order to get the graphs of the curves
+  /// separated on the first exceptional divisor. Otherwise split_graph should not be applied!
+  ///////////////////////////////////////////////////////////////////////////////////////////////
+  /// If #[1]="tau", then totalmultiplicities is called for the use in tau_es2 - thus it returns
+  /// the prolonged resolutiongraphs of the branches, their multiplicity sequences and their
+  /// contact matrix - sorted appropriately.
+  ///////////////////////////////////////////////////////////////////////////////////////////////
+  int i,j,s,e,ii;
+  intmat helpmati,helpmatii;
+  intvec helpvec;
+  /////////////////////////////////////////////////////////////////////////////////
+  // Decide, which kind of input we have, and define the contact matrix
+  /////////////////////////////////////////////////////////////////////////////////
+  // Input: a polynomial defining a plane curve singularity.
+  //////////////////////////////////////////////////////////////////////////////
+  if (typeof(INPUT)=="poly")
+  {
+    /*
+    poly f=squarefree(INPUT);
+    if ( deg(f)!=deg(INPUT) )
+    {
+      dbprint(printlevel-voice+4,"// input polynomial was not reduced");
+      dbprint(printlevel-voice+4,"// we continue with its reduction");
+    }
+    list I at N@V=invariants(f);
+    */
+    list I at N@V=invariants(INPUT);
+  }
+  else
+  {
+    ///////////////////////////////////////////////////////////////////////////////////
+    // Input: the vector of characteristic exponents of an irreducible plane curve
+    ///////////////////////////////////////////////////////////////////////////////////
+    if (typeof(INPUT)=="intvec")
+    {
+      list charexp;
+      charexp[1]=INPUT;
+      intmat contact[1][1]=0;
+    }
+    else
+    {
+      if (typeof(INPUT)=="list")
+      {
+        /////////////////////////////////////////////////////////////////////////////////
+        // Input: intersection-matrix and characteristic exponents.
+        //////////////////////////////////////////////////////////////////////////////
+        if (typeof(INPUT[1])=="intmat")
+        {
+          intmat contact=INPUT[1];
+          list charexp=INPUT[2];
+        }
+        else
+        {
+          /////////////////////////////////////////////////////////////////////////////////
+          // Input: output of hnexpansion or hne in the ring created by hnexpansion
+          //////////////////////////////////////////////////////////////////////////////
+          if ((typeof(INPUT[1])=="ring") or (typeof(INPUT[1])=="list"))
+          {
+            list I at N@V=invariants(INPUT);
+          }
+          else
+          {
+            ////////////////////////////////////////////////////////////////////////////////////
+            // Input: output of reddevelop or extdevelop -- irreducible plane curve singularity
+            ////////////////////////////////////////////////////////////////////////////////////
+            if (typeof(INPUT[1])=="matrix")
+            {
+              list charexp=invariants(INPUT)[1];
+              intmat contact[1][1]=0;
+            }
+            else
+            {
+              ERROR("The input is invalid!");
+            }
+          }
+        }
+      }
+      else
+      {
+        ERROR("The input is invalid!");
+      }
+    }
+  }
+  ///////////////////////////////////////////////////////////////////////////////////////////////////
+  // If the input was a polynomial or a HN-Expansion, then calculate the contact matrix and char.exponents.
+  ///////////////////////////////////////////////////////////////////////////////////////////////////
+  if (defined(I at N@V))
+  {
+    intmat contact=I at N@V[size(I at N@V)][1];   // contact numbers
+    list charexp;                       // characteristic exponents
+    for (i=1;i<=size(I at N@V)-1;i++)
+    {
+      charexp[i]=I at N@V[i][1];
+    }
+  }
+  //////////////////////////////////////////////////////////////////////////////
+  // Find the maximal contact numbers of the branches
+  //////////////////////////////////////////////////////////////////////////////
+  int r=ncols(contact);   // number of branches
+  intvec maxcontact;      // maximal contactnumber of branch i with other branches
+  for (i=1;i<=r;i++)
+  {
+    maxcontact[i]=max_in_intvec(intvec(contact[i,1..r]));
+  }
+  ///////////////////////////////////////////////////////////////////////////////
+  // Define the graphs of the branches and prolong them if necessary.
+  ///////////////////////////////////////////////////////////////////////////////
+  intmat gr,gr_red,grp;      // a subgraph, a reduced subgraph, a prolonged subgraph
+  int omega;              // point of highest weight in subgraph
+  list graphs;            // contains the subgraphs of the C_i
+  list totmult;           // contains the total multiplicities of the subgraphs
+  list multipl;           // contains the multiplicities of the subgraphs
+  list gr_tm;             // takes a single subgraph and tot.mult.
+  intvec tm,mt;           // total multiplicities and multiplicities
+  for (i=1;i<=r;i++)
+  {
+    gr_tm=irred_resgraph_totmult(charexp[i]); // graph, total multipl. and multipl. of the ith branch
+    gr=gr_tm[1];  // the graph of the ith branch
+    tm=gr_tm[2];  // the total multiplicities of the ith branch
+    mt=gr_tm[3];  // the multiplicities of the ith branch
+    omega=nrows(gr)-1;  // maximal weight in the graph of the ith branch
+    // If the maximal contact of the ith branch with some other branch is larger
+    // than the maximal weight omega, then the graph has to be polonged.
+    if (omega<maxcontact[i])
+    {
+      grp=intmat(intvec(0),maxcontact[i]+1,maxcontact[i]+1);
+      // save the graph without the point of the strict transform
+      if (omega>=1) // otherwise the graph consists only of the strict transform
+      {
+        grp[1..omega,1..omega]=gr[1..omega,1..omega];
+      }
+      // add the points of multiplicity 1 up to weight maxcontact[i] and the strict transform
+      // and connect them
+      for (j=omega+1;j<=maxcontact[i]+1;j++)
+      {
+        // adding the vertex to the graph and adding the total multiplicities
+        if (j<=maxcontact[i])
+        {
+          grp[j,j]=j;
+          if (j>1)
+          {
+            tm[j]=tm[j-1]+1;
+            mt[j]=1;
+          }
+          else  // then there is no previous point in the graph
+          {
+            tm[j]=1;
+            mt[j]=1;
+          }
+        }
+        // connecting the vertex with the previous part of the graph
+        if (j>1)  // otherwise there is nothing to connect to
+        {
+          grp[j-1,j]=1;
+          grp[j,j-1]=1;
+        }
+      }
+      gr=grp;  // replace the subgraph by the prolonged subgraph
+    }
+    gr[nrows(gr),ncols(gr)]=-i;  // give the strict transform in the ith branch weight -i
+    graphs[i]=gr;
+    totmult[i]=tm;
+    multipl[i]=mt;
+  }
+  ///////////////////////////////////////////////////////////////////////////////
+  // Check, if the procedure is called from inside tau_es2.
+  int check_tau;
+  if (size(#)==1)
+  {
+    if (#[1]=="tau")
+    {
+      check_tau=1;
+    }
+  }
+  /////////////////////////////////////////////////////////////////////////////////
+  // The procedure tau_es2 expects the branches to be ordered according to their
+  // contact during the resolution process.
+  /////////////////////////////////////////////////////////////////////////////////
+  if ((size(#)==0) or (check_tau==1))
+  {
+    list SORT;
+    for (i=1;i<=ncols(contact)-2;i++)
+    {
+      SORT=sort_branches(contact,graphs,totmult,multipl,i,ncols(contact));
+      contact=SORT[1];
+      graphs=SORT[2];
+      totmult=SORT[3];
+      multipl=SORT[4];
+    }
+  }
+  ///////////////////////////////////////////////////////////////////////////////////
+  /// If the procedure is called from inside tau_es2, the output will be the prolonged
+  /// resolutiongraphs of the branches, their multiplicity sequences and their contact matrix.
+  if (check_tau==1)
+  {
+    return(list(graphs,multipl,contact));
+  }
+  /////////////////////////////////////////////////////////////////////////////////////
+  // Sort the branches in such a way, that in the blowing up procedure whenever to branches
+  // C_i and C_j have contact k (i.e. after k steps they are separated) and one of the following
+  // situations occurs:
+  // A) some exceptional divisor E_l (l<k) still intersects C_i after k steps of blowing up
+  //    and no such E_l intersects C_j
+  // OR
+  // B) some exceptional divisor E_l (l<k-1) still intersects C_i after k steps of blowing up
+  //    and another one (necessarily E_k-1) intersects C_j,
+  // THEN: i<j!
+  /////////////////////////////////////////////////////////////////////////////////////////
+  // This means in the algorithm for glueing graphs together described in [JP] p.217-19
+  // the Case 3 never occurs -- and Case 1 only occurs, if it is unavoidable, that is when
+  // C_1 there meets an E_l with l<k.
+  // (Otherwise we say that (C_i,C_j) has "bad contact".)
+  ////////////////////////////////////////////////////////////////////////////////////////
+  // We can detect this by looking at the graphs of C_i and C_j. If E_l stays together with
+  // C_i and not with C_j in the k-th step of blowing up, then in the graph of C_i
+  // k and l are NOT connected, while in the graph of C_j they are!
+  //////////////////////////////////////////////////////////////////////////////////////////
+  // Note also, that for a fixed pair (i,j) this situation can only occur for ONE l (in Case A: l<k
+  // and possibly l=k-1;  in Case B: l<k-1).
+  //////////////////////////////////////////////////////////////////////////////////////////
+  // Our algorithm now works as follows. Start with i=1 and j=2.
+  // While (i<r=number of branches) do as follows: Check C_i with C_j.
+  // If a bad contact (C_i,C_j) occurs, then MOVE C_j to the position of C_i (and move all C_t
+  // with t>=i, t!=j  one position further). Else do nothing particular.
+  // Then, if j<r set j=j+1. Else set j=i+2 and i=i+1.  End of While.
+  // To see that this works we note that if (C_i,C_j) has bad contact for some j>i, then
+  // (C_j,C_t) does NOT have bad contact for t=i+1,...,j-1. For this we consider the 3 cases:
+  // 1)  contact(C_t,C_j)=contact(C_i,C_j)=k:  E_l stays with C_j in k-th step and C_t and C_j
+  //                                           separate there, so (C_t,C_j) has bad contact
+  //                                           and hence (C_j,C_t) does NOT have bad contact
+  // 2)  contact(C_t,C_j)>contact(C_i,C_j)=k:  CANNOT HAPPEN - C_i had no bad contact with C_t,
+  //                                           hence E_l did not stay with C_t in the k-th step;
+  //                                           however, E_l stays with C_j there, so C_t and C_j
+  //                                           cannot have a contact higher than k
+  // 3)  contact(C_t,C_j)<contact(C_i,C_j)=k:  when C_t and C_j separate, C_j and C_i are still
+  //                                           together; and since (C_i,C_t) did not have bad
+  //                                           contact also (C_j,C_t) cannot have bad contact.
+  // This ensures that when we do the moving of the graphs, we do NOT create any new bad contacts.
+  //////////////////////////////////////////////////////////////////////////////
+  i=1;
+  j=2;
+  intvec connections_i,connections_j;
+  int n_i,n_j;
+  int bad_contact;
+  while (i<r)
+  {
+    // Test graphs[i] with graphs[j] for bad contact.
+    connections_i=find_lower_connection_points(graphs[i],contact[i,j]);
+    if (connections_i[1]==0) // no connection point of lower weight there
+    {
+      n_i=0;
+    }
+    else
+    {
+      n_i=size(connections_i);
+    }
+    connections_j=find_lower_connection_points(graphs[j],contact[i,j]);
+    if (connections_j[1]==0) // no connection point of lower weight there
+    {
+      n_j=0;
+    }
+    else
+    {
+      n_j=size(connections_j);
+    }
+    bad_contact=0;
+    ii=1;
+    // The points of weight k=contact(C_i,C_j) in C_i and C_j are connectd to n_i respectively
+    // n_j points of weight less than k, where n_i and n_j might take values among 0, 1 and 2.
+    // n_j=2:        Then E_k is intersected by E_k-1 and E_l (l<k-1) in the k-th step, however
+    //               C_j does not stay with anyone of those, so (C_i,C_j) does not have bad contact.
+    // n_i=0:        Then C_i stays with E_k-1 and there is no E_l with l<k-1 in the k-th step,
+    //               hence (C_i,C_j) does not have bad contact.
+    // n_i=1, n_j=0: Analogously, then C_j stays with E_k-1 and there is no E_l (l<k-1). This means
+    //               (C_i,C_j) has bad contact.
+    // n_i=1, n_j=1: EITHER there is no E_l (l<k-1) and C_i and C_j both separate from E_k-1
+    //               in the k-th step of blowing up (hence (C_i,C_j) does not have bad contact).
+    //               OR there is an E_l (l<k-1) with which one stays and the other one stays
+    //               with E_k-1 (bad contact, if E_l stays with C_j; good contact otherwise).
+    // n_i=2,        E_k is intersected by E_k-1 and E_l in the k-th step and C_i does not
+    //               stay together with any of those.
+    //        n_j=0: This CANNOT occur, since then C_j would have to stay together with E_l
+    //               and E_k-1, which is impossible.
+    //        n_j=1: Then C_j stays together with either E_l or with E_k-1, however both cases
+    //               imply that (C_i,C_j) has bad contact
+    // ALTERNATIVE CONSIDERATION FOR DISTINGUISHING THE CASES:
+    // n_i<n_j   : C_i stays with "more" E's than C_j does (only one is possible of course!),
+    //             hence (C_i,C_j) does not have bad contact.
+    // n_i>n_j   : C_i stays with "less" E's than C_j does (i.e. with none) hence (C_i,C_j) has bad contact.
+    // n_i=n_j=0 : Not possible, since then both would stay with E_k-1.
+    // n_i=n_j=2 : Both separate from E_k-1 as well as from some E_l (l<k) - hence NO bad contact.
+    // n_i=n_j=1 : One stays with E_k-1 and one with E_l (l<k). Bad contact, if C_j stays with E_l,
+    //             i.e. if in the graph of C_i the point k is connected to l, and no bad contact otherwise.
+    if ((n_i>n_j) or ((n_i==1) and (n_j==1) and (connections_i[1]<contact[i,j]-1)))
+    {
+      bad_contact=1;
+      // Move the graph (etc.) of C_j into the position i.
+      graphs=insert(graphs,graphs[j],i-1);
+      graphs=delete(graphs,j+1);
+      totmult=insert(totmult,totmult[j],i-1);
+      totmult=delete(totmult,j+1);
+      multipl=insert(multipl,multipl[j],i-1);
+      multipl=delete(multipl,j+1);
+      contact=move_row_col(contact,i,j);
+    }
+    if (j<r)  // There are still some C_j against which C_i has to be tested.
+    {
+      j++;
+    }
+    else      // Now C_i has been tested against all C_j, and we may continue with C_i+1.
+    {
+      j=i+2;
+      i=i+1;
+    }
+  }
+  /////////////////////////////////////////////////////////////////////////////////////
+  // Glue the graphs together.
+  //////////////////////////////////////////////////////////////////////////////
+  ///////////////////////////////////////////////////////////////////////////////////
+  intmat rgraph=graphs[1];                 // keeps the resolution graph
+  intmat rtm=intmat(totmult[1],nrows(rgraph),1); // keeps the tot.mult. at the vertices of the graph as rows
+  intmat rmt=intmat(multipl[1],nrows(rgraph),1); // keeps the mult. at the vertices of the graph as rows
+  intvec stricttransforms=0,ncols(rgraph);   // keeps the position of the ith strict
+                                             // transform in rgraph at position i+1 !!!
+  intvec k,kp,p,q,o;   // highest contact numbers, num. of branch with hgt contact, separation points
+  int maxc,maxcp;
+  for (i=2;i<=r;i++)
+  {
+    //////////////////////////////////////////////////////////////////////////////////
+    // Find j<i minimal s.t. contact[i,j] is maximal.
+    maxcp=i;
+    for (j=1;j<i;j++)
+    {
+      if (contact[i,j]>contact[i,maxcp]){maxcp=j;}
+    }
+    kp[i]=maxcp;            // the j such that C_i has its maximal contact to C_j
+    k[i]=contact[i,maxcp];  // the maximal contact of C_i with C_1,...,C_i-1
+    ///////////////////////////////////////////////////////////////////////////////////
+    // Find in the graph of C_1,...,C_i-1 the points p of wgt k and q of wgt k-1
+    // connected to C_maxcp.
+    // Since non of C_j for j<maxcp has contact k with C_i, the point p lies in
+    // the remaining part of the graph of C_maxcp.
+    s=rgraph[stricttransforms[maxcp]+1,stricttransforms[maxcp]+1];
+    p[i]=stricttransforms[maxcp]+1+k[i]-s; // pt. to which reduced subgraph of C_i is glued
+    // If s<k[i], then q also lies in this part, otherwise it lies in the remaining part
+    // of the graph of the C_j to which C_maxcp is connected, i.e. j=kp[maxcp], since
+    // the contact of C_i and of C_maxcp to this C_j is strictly less than k.
+    // If s=k[i]=1, then p=1 and there is no q! We may thus set q=0.
+    if ((s<k[i]) or ((s==k[i]) and (s==1)))  // i.e. q is on the same subgraph as p, or q does not exist
+    {
+      q[i]=p[i]-1;
+    }
+    else               // i.e. q is on the subgraph to which the subgraph of p has been glued
+    {
+      s=rgraph[stricttransforms[kp[maxcp]]+1,stricttransforms[kp[maxcp]]+1];
+      q[i]=stricttransforms[kp[maxcp]]+k[i]-s;
+    }
+    //////////////////////////////////////////////////////////////////////////////////////
+    // Reduce the graph of C_i and add it to the graph of C_1,...,C_i-1.
+    gr=graphs[i];
+    s=nrows(rgraph);
+    // Delete in the graph of C_i everything of weight <=k.
+    gr_red=intmat(intvec(gr[k[i]+1..nrows(gr),k[i]+1..ncols(gr)]),nrows(gr)-k[i],ncols(gr)-k[i]);
+    // Add this part to the graph of C_1,...,C_i-1.
+    rgraph=addmat(rgraph,gr_red);
+    /////////////////////////////////////////////////////////////////////////////////////
+    // Connect the two parts of the graph.
+    /////////////////////////////////////////////////////////////////////////////////////
+    // Connect the points connected to the point of wgt k in the graph of C_i to p[i].
+    for (j=k[i]+1;j<=ncols(gr);j++)
+    {
+      if(gr[k[i],j]==1)
+      {
+        rgraph[s+j-k[i],p[i]]=1;
+        rgraph[p[i],s+j-k[i]]=1;
+      }
+    }
+    // If pt. of wgt k is not connected to pt of wgt k-1 in graph of C_i, then points
+    // connected to the one of wgt k-1 have to be connected to q[i].
+    if (k[i]>1)
+    {
+      if (gr[k[i],k[i]-1]!=1)
+      {
+        for (j=k[i]+1;j<=ncols(gr);j++)
+        {
+          if(gr[k[i]-1,j]==1)
+          {
+            rgraph[s+j-k[i],q[i]]=1;
+            rgraph[q[i],s+j-k[i]]=1;
+          }
+        }
+        // Cut the connection from p[i] to q[i].
+        rgraph[p[i],q[i]]=0;
+        rgraph[q[i],p[i]]=0;
+      }
+    }
+    stricttransforms[i+1]=ncols(rgraph);
+    ////////////////////////////////////////////////////////////////////////////////
+    // Adjust the total multiplicities
+    ////////////////////////////////////////////////////////////////////////////////
+    // Add the total multiplicities for the added subgraph to rtm
+    tm=totmult[i];
+    mt=multipl[i];
+    if (k[i]<size(tm)) // if the reduced subgraph of C_i has more than one point
+    {
+      rtm=addmat(rtm,intmat(intvec(tm[k[i]+1..size(tm)]),nrows(gr_red),1));
+      rmt=addmat(rmt,intmat(intvec(mt[k[i]+1..size(mt)]),nrows(gr_red),1));
+    }
+    else // if the reduced subgraph of C_i consists only of the strict transform
+    {
+      rtm=addmat(rtm,0);
+      rmt=addmat(rmt,0);
+    }
+    // Adjust the total multiplicities at the places where the subgraph has been glued.
+    e=k[i];    // the highest weight of a point that has not yet been assigned its tot. mult.
+    while(e>=1)
+    {
+      s=stricttransforms[maxcp]+1;  // Line in the graph of the start. pt. of the subgraph of C_maxcp.
+      for (j=rgraph[s,s];j<=e;j++)  // Adjust the multiplicities.
+      {
+        rtm[s+j-rgraph[s,s],i]=tm[j];
+        rmt[s+j-rgraph[s,s],i]=mt[j];
+      }
+      maxcp=kp[maxcp];  // To which subgraph has the subgraph of C_maxcp been glued?
+      e=rgraph[s,s]-1;  // What is the highest weight of a pt. that has not yet been assigned its tot.mult.?
+    }
+    e=nrows(rtm);  // Number of rows in the matrix of totalmultiplicities.
+    // The total multiplicities of the C_s for s=1,...,i-1 along the exceptional divisors
+    // which are introduced after the strict transform of C_s has separated (i.e. the entries
+    // in rows stricttransform[i]+1,...,stricttransform[i+1]-1 in the s-th column of the matrix
+    // of total multiplicities still have to be calculated.
+    for (s=1;s<i;s++)
+    {
+      rtm[1..e,s]=adjust_tot_mult(intvec(rtm[1..e,i]),intvec(rtm[1..e,s]),intvec(rmt[1..e,i]),intvec(rmt[1..e,s]),p,q,stricttransforms,i);
+    }
+    // The total multiplicities of the C_i along the exceptional divisors
+    // which are introduced for the sake of C_s, s=1,...,i-1, after the strict transform
+    // of C_i has separated (i.e. the entries in rows stricttransform[s]+1,...,stricttransform[s+1]-1
+    // in the i-th column of the matrix of total multiplicities still have to be calculated.
+    for (s=1;s<i;s++)
+    {
+      rtm[1..e,i]=adjust_tot_mult(intvec(rtm[1..e,s]),intvec(rtm[1..e,i]),intvec(rmt[1..e,s]),intvec(rmt[1..e,i]),p,q,stricttransforms,s);
+    }
+  }
+  list result=rgraph,rtm,rmt;
+  return(result);
+}
+example
+{
+  "EXAMPLE:";
+  echo=2;
+  ring r=0,(x,y),ls;
+  poly f1=(y2-x3)^2-4x5y-x7;
+  poly f2=y2-x3;
+  poly f3=y3-x2;
+  totalmultiplicities(f1*f2*f3);
+}
+
+
+
+proc alexanderpolynomial (def INPUT)
+"USAGE:  alexanderpolynomial(INPUT); INPUT poly or list
+ASSUME:  INPUT is either a REDUCED bivariate polynomial defining a plane curve singularity,
+         or the output of @code{hnexpansion(f[,\"ess\"])}, or the list @code{hne} in
+         the ring created by @code{hnexpansion(f[,\"ess\"])}, or the output of
+         @code{develop(f)} resp. of @code{extdevelop(f,n)}, or a list containing
+         the contact matrix and a list of integer vectors with the characteristic exponents
+         of the branches of a plane curve singularity, or an integer vector containing the
+         characteristic exponents of an irreducible plane curve singularity.
+CREATE:  a ring with variables t, t(1), ..., t(r) (where r is the number of branches of
+         the plane curve singularity f defined by INPUT) and ordering ls over the
+         ground field of the basering. @*
+         Moreover, the ring contains the Alexander polynomial of f in variables t(1), ..., t(r)
+         (@code{alexpoly}), the zeta function of the monodromy operator of f in the variable t
+         (@code{zeta_monodromy}), and a list containing the factors of the Alexander
+         polynomial with multiplicities (@code{alexfactors}).
+RETURN:  a list, say @code{ALEX}, where @code{ALEX[1]} is the created ring
+NOTE:    to use the ring type: @code{def ALEXring=ALEX[i]; setring ALEXring;}.
+         @*
+         Alternatively you may use the procedure sethnering and type: sethnering(ALEX,\"ALEXring\");
+         @*
+         To access the Alexander polynomial resp. the zeta function resp. the
+         factors of the Alexander polynomial type: @code{alexpoly} resp. @code{zeta_monodromy}
+         resp. @code{alexfactors}.@*
+         In case the Hamburger-Noether expansion of the curve f is needed
+         for other purposes as well it is better to calculate this first
+         with the aid of @code{hnexpansion} and use it as input instead of
+         the polynomial itself.
+         @*
+         If you are not sure whether the INPUT polynomial is reduced or not, use
+         @code{squarefree(INPUT)} as input instead.
+SEE ALSO: resolutiongraph, totalmultiplicities
+EXAMPLE: example alexanderpolynomial;  shows an example
+"
+{
+  // Get the resolution graph and the total multiplicities.
+  list gr_tm=totalmultiplicities(INPUT);
+  intmat gr=gr_tm[1];
+  intmat tm=gr_tm[2];
+  int r=ncols(tm);
+  int e=ncols(gr);
+  // Define the Ring for the Alexander Polynomial and the Zeta Function of the Monodromy.
+  execute("ring ALEXring=("+charstr(basering)+"),(t,t(1..r)),dp;");
+  poly hilfspoly=1;
+  poly alexnumerator=1;    // numerator of the Alexander polynomial
+  poly alexdenominator=1;  // denominator of the Alexander polynomial
+  list alexfactors;        // the factors of the Alexanderpolynomial with multiplicities
+  list alexfactor;
+  int chi=2;
+  int i,j,k;
+  int s=1;
+  // Consider every vertex of the resolution graph.
+  for (i=1;i<=e;i++)
+  {
+    if (gr[i,i]>0)  // If it belongs to an exceptional curve.
+    {
+      for (j=1;j<=e;j++)  // Calculate the Euler charateristik of the smooth locus of the exc. curve.
+      {
+        if ((gr[i,j]==1) and (i!=j))
+        {
+          chi=chi-1;
+        }
+      }
+      if (chi!=0)         // If the Euler characteristik is not zero, then it gives a factor in the AP.
+      {
+        for (k=1;k<=r;k++)
+        {
+          hilfspoly=hilfspoly*t(k)^tm[i,k];
+        }
+        hilfspoly=1-hilfspoly;
+        if (chi<0)       // ... either in the numerator ...
+        {
+          alexnumerator=alexnumerator * hilfspoly^-chi;
+        }
+        else             // ... or in the denominator.
+        {
+          alexdenominator=alexdenominator * hilfspoly^chi;
+        }
+        alexfactor=hilfspoly,-chi;
+        alexfactors[s]=alexfactor;
+        s++;
+      }
+      chi=2;
+      hilfspoly=1;
+    }
+  }
+  // Calculate the Alexander Polynomial.
+  if (ncols(tm)==1)  // If we have only one branch, then the numerator has to be multiplied by 1-t.
+  {
+    alexnumerator=alexnumerator*(1-t(1));
+    alexfactor=1-t(1),1;
+    alexfactors[size(alexfactors)+1]=alexfactor;
+  }
+  poly alexpoly=alexnumerator / alexdenominator;
+  // Calculate the Zeta Function of the Monodromy Operator.
+  poly zeta_monodromy=alexpoly;
+  for (i=1;i<=r;i++)
+  {
+    zeta_monodromy=subst(zeta_monodromy,t(i),t);
+  }
+  export zeta_monodromy;
+  export alexnumerator;
+  export alexdenominator;
+  export alexfactors;
+  export alexpoly;
+  list ALEX=ALEXring;
+  return(ALEX);
+}
+example
+{
+  "EXAMPLE:";
+  echo=2;
+  ring r=0,(x,y),ls;
+  poly f1=(y2-x3)^2-4x5y-x7;
+  poly f2=y2-x3;
+  poly f3=y3-x2;
+  list ALEX=alexanderpolynomial(f1*f2*f3);
+  def ALEXring=ALEX[1];
+  setring ALEXring;
+  alexfactors;
+  alexpoly;
+  zeta_monodromy;
+}
+
+proc semigroup (def INPUT)
+"USAGE:    semigroup(INPUT); INPUT poly or list
+ASSUME:   INPUT is either a REDUCED bivariate polynomial defining a plane curve singularity,
+          or the output of @code{hnexpansion(f[,\"ess\"])}, or the list @code{hne} in
+          the ring created by @code{hnexpansion(f[,\"ess\"])}, or the output of
+          @code{develop(f)} resp. of @code{extdevelop(f,n)}, or a list containing
+          the contact matrix and a list of integer vectors with the characteristic exponents
+          of the branches of a plane curve singularity, or an integer vector containing
+          the characteristic exponents of an irreducible plane curve singularity.
+RETURN:   a list with three entries. The first and the second are lists @code{v_1,...,v_s}
+          and @code{w_1,...,w_r} respectively of integer vectors such that the semigroup
+          of the plane curve defined by the INPUT is generated by the vectors
+          @code{v_1,...,v_s,w_1+k*e_1,...,w_r+k*e_r}, where e_i denotes the i-th standard
+          basis vector and k runs through all non-negative integers. The thrid entry is the conductor
+          of the plane curve singularity. Note that r is the number of branches of the plane curve
+          singularity and integer vectors thus have size r.
+NOTE:     If the output is zero this means that the curve has one branch and is regular.
+          In the reducible case the set of generators may not be minimal.
+          @*
+          If you are not sure whether the INPUT polynomial is reduced or not, use
+          @code{squarefree(INPUT)} as input instead.
+SEE ALSO: resolutiongraph, totalmultiplicities
+EXAMPLE:  example semigroup;  shows an example
+"
+{
+  ////////////////////////////////////////////////////////////////////////////////////////
+  // Uses the algorithm in [CDG99] A. Campillo, F. Delgado, S.M. Gusein-Zade, On the
+  // generators of the semigroup of a plane curve singularity,
+  // J. London Math. Soc. (2) 60 (1999), 420-430.
+  ////////////////////////////////////////////////////////////////////////////////////////
+  intvec conductor; // conductor of the singularity
+  list charexp;     // characteristic exponents of the singularity
+  int i,j;
+  /////////////////////////////////////////////////////////////////////////////////
+  // Decide, which kind of input we have, and define the contact matrix
+  /////////////////////////////////////////////////////////////////////////////////
+  // Input: a polynomial defining a plane curve singularity.
+  //////////////////////////////////////////////////////////////////////////////
+  if (typeof(INPUT)=="poly")
+  {
+    /*
+    poly FFF=squarefree(INPUT);
+    if ( deg(FFF)!=deg(INPUT) )
+    {
+      dbprint(printlevel-voice+3,"// input polynomial was not reduced");
+      dbprint(printlevel-voice+3,"// we continue with its reduction");
+    }
+    list I at N@V=invariants(FFF);
+    */
+    list I at N@V=invariants(INPUT);
+  }
+  else
+  {
+    ///////////////////////////////////////////////////////////////////////////////////
+    // Input: the vector of characteristic exponents of an irreducible plane curve
+    ///////////////////////////////////////////////////////////////////////////////////
+    if (typeof(INPUT)=="intvec")
+    {
+      // Calculate the semigroup and the conductor directly.
+      conductor[1]=charexp2conductor(INPUT);
+      intvec gener=charexp2generators(INPUT);
+      list genera;
+      for (i=1;i<=size(gener);i++)
+      {
+        genera[i]=gener[i];
+      }
+      return(list(genera,list(),conductor));
+    }
+    else
+    {
+      if (typeof(INPUT)=="list")
+      {
+        /////////////////////////////////////////////////////////////////////////////////
+        // Input: intersection-matrix and characteristic exponents.
+        //////////////////////////////////////////////////////////////////////////////
+        if (typeof(INPUT[1])=="intmat")
+        {
+          intmat contact=INPUT[1];
+          charexp=INPUT[2];
+          int n=ncols(contact); // to know how many branches we have
+          if (n==1) // Only one branch!
+          {
+            return(semigroup(charexp[1]));
+          }
+          intmat intersecmult=charexp2inter(contact,charexp);
+          for(i=1;i<=ncols(contact);i++)
+          {
+            conductor[i]=charexp2conductor(charexp[i]);//list with the characteristic exponents
+          }
+        }
+        else
+        {
+          /////////////////////////////////////////////////////////////////////////////////
+          // Input: output of hnexpansion or hne in the ring created by hnexpansion
+          //////////////////////////////////////////////////////////////////////////////
+          if ((typeof(INPUT[1])=="ring") or (typeof(INPUT[1])=="list"))
+          {
+            list I at N@V=invariants(INPUT);
+          }
+          else
+          {
+            ////////////////////////////////////////////////////////////////////////////////////
+            // Input: output of develop or extdevelop -- irreducible plane curve singularity
+            ////////////////////////////////////////////////////////////////////////////////////
+            if (typeof(INPUT[1])=="matrix")
+            {
+              return(semigroup(invariants(INPUT)[1]));
+            }
+            else
+            {
+              ERROR("The input is invalid!");
+            }
+          }
+        }
+      }
+      else
+      {
+        ERROR("The input is invalid!");
+      }
+    }
+  }
+  ///////////////////////////////////////////////////////////////////////////////////////////////////
+  // If the input was a poly or an HN-Expansion, then calculate the contact matrix and char.exponents.
+  ///////////////////////////////////////////////////////////////////////////////////////////////////
+  if (defined(I at N@V))
+  {
+    int n =size(I at N@V)-1;// number of branches
+    // If the singularity is irreducible, then we calculate the semigroup directly.
+    if (n==1)
+    {
+      return(semigroup(I at N@V[1][1]));
+    }
+    // If the singularity is not irreducible, then we go on.
+    intmat contact=I at N@V[size(I at N@V)][1];        // contact matrix
+    intmat intersecmult=I at N@V[size(I at N@V)][2];   // intersection multiplicities
+    for(i=1;i<=n;i++)
+        {
+          conductor[i]=I at N@V[i][5];
+      charexp[i]=I at N@V[i][1];
+        }
+  }
+  /////////////////////////////////////////////////////////////////////////////////////
+  // If we have come so far, the curve is reducible!
+  /////////////////////////////////////////////////////////////////////////////////////
+  // Compute the conductor of the curve.
+  /////////////////////////////////////////////////////////////////////////////////////
+  for(i=1;i<=size(conductor);i++)
+  {
+    for(j=1;j<=size(conductor);j++)
+        {
+          conductor[i]=conductor[i]+intersecmult[i,j];
+        }
+  }
+  /////////////////////////////////////////////////////////////////////////////////////
+  /// The total multiplicity vectors of the exceptional divisors generate the semigroup,
+  /// however, this system of generators is not minimal. Theorem 2 in [CDG99] leads
+  /// to the following algorithm for minimizing the set of generators.
+  /////////////////////////////////////////////////////////////////////////////////////
+  list resgr_totmult=totalmultiplicities(list(contact,charexp)); // resolution graph and tot. mult.
+  intmat resgr=resgr_totmult[1];    // resolution graph
+  intmat totmult=resgr_totmult[2];  // total multiplicities
+  list conpts;                      // ith entry = points to which i is connected and their weights
+  intvec series;                    // ith entry = row in totmult which corresponds to w_i
+  intvec deadarc;                   // Star point and the point connected to the star point of a dead arc.
+  list deadarcs;                    // Saves deadarc for all dead arcs.
+  int stop,ctp,ctpstop;
+  list ordinary_generators, series_generators; // the v_i and the w_i from the description
+  // Find for each branch of the curve all the points in the graph to which it is connected
+  // and save the numbers of the corresponding rows in the graph as well as the weight of the point.
+  for (i=1;i<=ncols(resgr);i++)
+  {
+    conpts[i]=find_connection_points(resgr,i);
+  }
+  //////////////////////////////////////////////////////////////////////////////////
+  // Check for each point in the graph, whether it contributes to the semigroup.
+  // If it does not contribute to the semigroup, then set the weight of the point
+  // to zero, i.e. resgr[i,i]=0. Note that the vertex 1 always contributes!
+  //////////////////////////////////////////////////////////////////////////////////
+  // Find first all the points corresponding to the branches and the end points of dead arcs.
+  // The points to which the branch k is connected contributes to w_k. The end points of
+  // dead arcs contribute to the v_i, while the remaining points of the dead arcs are to be removed.
+  j=1;      // Counter for dead arcs - the star points of dead arcs have to be saved for future use.
+  for (i=2;i<=ncols(resgr);i++)
+  {
+    // The end points of dead arcs and the end points corresponding to the branches are
+    // recognized by the fact that they are only connected to one other point.
+    if (size(conpts[i][1])==1)  // row i in the graph corresponds to  an end point
+    {
+      // For an end point corresponding to a branch k the last point E_alpha(k), to which it is
+      // connected, contributes to the generator w_k.
+      if (resgr[i,i]<0)
+      {
+        series[-resgr[i,i]]=conpts[i][1][1];  // Find E_alpha(k), where k=-resgr[i,i]
+        ctp=conpts[i][1][1];
+        resgr[ctp,ctp]=0;                     // So E_alph(k) does not contribute to the v_i.
+      }
+      // For an end point of a dead arc the end point contributes, but all the other points
+      // of the dead arc - including the star point = separation pt of the dead arc - do not contribute.
+      if (resgr[i,i]>0)
+      {
+        stop=0;  // Stop checks whether the star point of the dead arc has been reached.
+        ctp=conpts[i][1][1]; // The point to which the end point is connected.
+        // Set the weights of all the other points in the dead arc to zero.
+        while ((stop==0) and (ctp!=1)) // If the star point or the vertex 1 has been reached, stop.
+        {
+          deadarc[2]=i;          // i might be the point connected to the star point of the dead arc.
+          resgr[ctp,ctp]=0;
+          if (size(conpts[ctp][1])==2)  // If ctp was an ordinary vertex, we go on.
+          {
+            deadarc[2]=ctp; // ctp might be the point connectd to the star point of the dead arc.
+            ctp=conpts[ctp][1][2];  // This is the second point (of higher weight) to which ctp is connected.
+          }
+          else  // If ctp is the star point, we stop.
+          {
+            deadarc[1]=ctp;       // Star point of this dead arc.
+            deadarcs[j]=deadarc;  // Save the j-th dead arc.
+            j++;
+            stop=1;
+          }
+        }
+      }
+    }
+  }
+  //////////////////////////////////////////////////////////////////////////////////
+  // Points (!=1) which are on the geodesics of every branch don't contribute.
+  // (The geodesic of a branch is the shortest connection of the strict transform to 1 in the graph.)
+  stop=0;              // Checks whether the points on all geodesics have been found.
+  ctp=1;               // Point (=row in resgr) to be considered.
+  int prev_ctp;        // Previous point in the graph, to which ctp was connected.
+  int dead_arc_ctp;    // If ctp is the star pt of a dead arc, this is the connection pt of ctp in the d.a.
+  int dastarptcheck;   // Checks whether a point is a star point of a dead arc.
+  if (size(conpts[1][1])>=2) // The graphs separate already at point 1.
+  {
+    stop=1;
+  }
+  else  // The graphs do not separate at point 1.
+  {
+    prev_ctp=1;
+    ctp=conpts[1][1][1];  // Next point to be considered.
+  }
+  // Pass on along the graph until we reach the first point where some branches separate.
+  while (stop==0)
+  {
+    if (size(conpts[ctp][1])==2)  // Point ctp is connected to 2 other points, hence is a normal vertex.
+    {
+      resgr[ctp,ctp]=0;       // Point ctp is a normal vertex.
+      prev_ctp=ctp;           // Save the position of ctp for future use.
+      ctp=conpts[ctp][1][2];  // Next point to which ctp is connected.
+    }
+    if (size(conpts[ctp][1])>3)  // More than three points are connected to ctp.
+    {
+      resgr[ctp,ctp]=0;
+      stop=1;                    // The graphs separate at point ctp.
+    }
+    if (size(conpts[ctp][1])==3)  // At ctp a dead arc might depart or some branch(es)!
+    {                             // If a dead arc departs, then the branches stay together.
+      resgr[ctp,ctp]=0;
+      // Check if a dead arc departs at point ctp (i.e. if ctp is the star point of a dead arc),
+      // then the branches do not separate at ctp.
+      dastarptcheck=0;
+      i=1;
+      while ((i<=size(deadarcs)) and (dastarptcheck==0))
+      {
+        if (ctp==deadarcs[i][1])  // ctp is the star point of a dead arc.
+        {
+          dastarptcheck=1;
+          dead_arc_ctp=deadarcs[i][2];  // The point in the dead arc to which ctp is connected.
+        }
+        i++;
+      }
+      if (dastarptcheck==0)  // ctp is not the star point of a dead arc, hence the graphs separate at ctp.
+      {
+        stop=1;
+      }
+      else
+      {
+        // Set ctp to the point connected to ctp which is not in the dead arc and is not prev_ctp.
+        i=1;
+        ctpstop=0;
+        while ((i<=3) and (ctpstop==0))
+        {
+          if ((conpts[ctp][1][i]!=prev_ctp) and (conpts[ctp][1][i]!=dead_arc_ctp))
+          {
+            prev_ctp=ctp;
+            ctp=conpts[ctp][1][i];
+            ctpstop=1;
+          }
+          i++;
+        }
+      }
+    }
+  }
+  /////////////////////////////////////////////////////////////////////////////////////////////
+  // Collect the generators v_j by checking which points in the graph still have
+  // a positive weight! These points contribute their total multiplicity vector as
+  // generator v_j.
+  j=1;
+  for (i=1;i<=ncols(resgr);i++)
+  {
+    if (resgr[i,i]>0)
+    {
+      ordinary_generators[j]=intvec(totmult[i,1..ncols(totmult)]);
+      j++;
+    }
+  }
+  // The "exceptional" generators w_i, for which we have to include w_i+ke_i (for all k)
+  // are the total multiplicity vectors of the points saved in series.
+  for (i=1;i<=ncols(totmult);i++)
+  {
+    series_generators[i]=intvec(totmult[series[i],1..ncols(totmult)]);
+  }
+  return(list(ordinary_generators,series_generators,conductor));
+}
+example
+{
+  "EXAMPLE:";
+  echo=2;
+  ring r=0,(x,y),ls;
+  // Irreducible Case
+  semigroup((x2-y3)^2-4x5y-x7);
+  // In the irreducible case, invariants() also calculates a minimal set of
+  // generators of the semigroup.
+  invariants((x2-y3)^2-4x5y-x7)[1][2];
+  // Reducible Case
+  poly f=(y2-x3)*(y2+x3)*(y4-2x3y2-4x5y+x6-x7);
+  semigroup(f);
+}
+
+
+
+proc charexp2generators (intvec charexp)
+"USAGE:      charexp2generators(v),  v intvec
+ASSUME:      v contains the characteristic exponents of an irreducible plane
+             curve singularity
+RETURN:      intvec, the minimal set of generators of the semigroup of the plane curve singularity
+SEE ALSO:    invariants, resolutiongraph, totalmultiplicities, alexanderpolynomial
+KEYWORDS:    generators; semigroup; characteristic exponents; topological invariants
+EXAMPLE:     example charexp2generators;   shows an example"
+{
+  int end=size(charexp);
+  // If the singularity is smooth!
+  if (end==1)
+  {
+    return(1);
+  }
+  int i,j;
+  intvec gener;
+  intvec GGT;
+  for (i=1;i<=end;i++)
+  {
+    // Calculate the sequence of gcd's of the characteristic exponents.
+    if (i==1)
+    {
+      GGT[1]=charexp[1];
+    }
+    else
+    {
+      GGT[i]=gcd(GGT[i-1],charexp[i]);
+    }
+    // Calculate the generators.
+    gener[i]=charexp[i];
+    for (j=2;j<=i-1;j++)
+    {
+      gener[i]=gener[i]+((GGT[j-1]-GGT[j]) div GGT[i-1])*charexp[j];
+    }
+  }
+  return(gener);
+}
+example
+{
+  "EXAMPLE:";
+  echo=2;
+  charexp2generators(intvec(28,64,66,77));
+}
+
+
+proc charexp2multseq (intvec charexp)
+"USAGE:      charexp2multseq(v),  v intvec
+ASSUME:      v contains the characteristic exponents of an irreducible plane
+             curve singularity
+RETURN:      intvec, the multiplicity sequence of the plane curve singularity
+NOTE:        If the curve singularity is smooth, then the multiplicity sequence is empty.
+             This is expressed by returning zero.
+SEE ALSO:    invariants, resolutiongraph, totalmultiplicities, alexanderpolynomial
+KEYWORDS:    characteristic exponents; multiplicity sequence; topological invariants
+EXAMPLE:     example charexp2multseq;   shows an example"
+{
+  int end=size(charexp);
+  // If the singularity is smooth!
+  if (end==1)
+  {
+    return(1); // ERROR: Should be 0, but for the time being, Singular returns 1.
+  }
+  intvec multseq=euclidseq(charexp[2],charexp[1]);
+  for (int i=3;i<=end;i++)
+  {
+    multseq=multseq,euclidseq(charexp[i]-charexp[i-1],multseq[size(multseq)]);
+  }
+  return(multseq);
+}
+example
+{
+  "EXAMPLE:";
+  echo=2;
+  charexp2multseq(intvec(28,64,66,77));
+}
+
+proc multseq2charexp(def v)   // Procedure written by Fernando.
+"USAGE:  multseq2charexp(v), v intvec
+ASSUME:  The input is an intvec, which contains the mutiplicity sequence
+         of an irreducible plane curve singularity .
+RETURN:  An intvec, which contains the sequence of characteristic
+         exponents of the irreducible plane curve singularity defined by v.
+EXAMPLE: example multseq2charexp; shows an example.
+"
+{
+  ///////  Preamble which reduces the input of an intvec to  /////////////
+  ///////  the originally assumed input of a list of intvecs /////////////
+  ///////  and tests the input.                              /////////////
+  if (typeof(v)=="intvec")
+  {
+    list RESULT=multseq2charexp(list(v));
+    return(RESULT[1]);
+  }
+  if (typeof(v)!="list")
+  {
+    ERROR("Invalid Input!");
+  }
+  if (typeof(v)=="list")
+  {
+    int TESTV;
+    for (int III=1;III<=size(v);III++)
+    {
+      if (typeof(v[III])!="intvec")
+      {
+        TESTV=1;
+      }
+    }
+    if (TESTV==1)
+    {
+      ERROR("Invalid Input!");
+    }
+  }
+  ///////////////////////////////////////////////////////////
+  list L=v;
+  int n =size(L);
+  // ///////////////////////////////////////////////////////
+  // we look the size of each vector
+  intvec mm;
+  for(int j=1;j<=n;j++)
+  {
+    mm[j]=size(L[j]);
+  }
+  // ///////////////////////////////////////////////////////
+  // we define some variables
+  list LL;
+  int temp, temp1,temp2;
+  int ind,r,l,boolean;
+  int old,new;
+  int contador;
+  list EUCLI,EUCLI1;
+  intvec exponent,exponentes1;
+  int new1,old1;
+  int contador1;
+  int a,b,f;
+  //with the for we round each branch.
+  for(int k=1;k<=n;k++)
+  {
+    l=1;
+    old=L[k][l];
+    //if the vertor has more than one element
+    if(mm[k]<>1)
+    {
+      // ///////////////////////////////////////////////////////////////////////////////
+      // the first step is special because is easy to know the two first characteristic exponents
+      new=L[k][l+1];
+      contador=1;
+      while(old==new)//we check how many consecutives elements are equal, starting in the first.
+      {
+        contador=contador+1;
+        old=new;
+        new=L[k][contador+1];
+      }
+      exponent=L[k][l],contador*L[k][l]+L[k][l+contador];// those are the first two characteristic exponents.
+      LL[k]=exponent;// we insert them in the final matrix
+      EUCLI=euclides(LL[k][2],LL[k][1]);// compute the euclides algorithm for the two first characteristic exponents.
+      temp=size(EUCLI[1]);
+      // measure how many elements of the multiplicity sequence belong to the first euclidean algorithm.
+      for(ind=1;ind<=temp;ind=ind+1)
+      {
+        l=l+EUCLI[1][ind];
+      }
+      l=l-1;//this is the number we are looking for.
+      ///////////////////////////////////////////////////////////////
+      r=1;
+      //repeat the same process until the end of the multiplicity sequence.
+      if(mm[k]-1>l)
+      {
+        while( l<mm[k]-1)
+        {
+          r=r+1;
+          old1=L[k][l];
+          new1=L[k][l+1];
+          contador1=0;
+          boolean=1;
+          if(old1==new1)
+          {
+            while(old1==new1 and boolean==1)
+            {
+              contador1=contador1+1;
+              old1=new1;
+              new1=L[k][l+contador1+1];
+              if(size(L[k])<=l+contador1+1)
+              {
+                boolean =0;
+              }
+            }
+          }
+          temp1=size(LL[k]);
+          exponentes1=LL[k],LL[k][temp1]+(contador1*L[k][l])+L[k][contador1+l+1];
+          LL[k]=exponentes1;
+          EUCLI1=euclides(LL[k][temp1+1]-LL[k][temp1],L[k][l]);
+          temp2=size(EUCLI1[1]);
+          for(ind=1;ind<=temp2;ind=ind+1)
+          {
+            l=l+EUCLI1[1][ind];
+          }
+        }
+      }
+    }
+    // if the vector has only one element then the charexp is only 1.
+    else
+    {
+      LL[k]=1;
+    }
+  }
+  return(LL);
+}
+example
+{
+  "EXAMPLE:";echo=2;
+  intvec v=2,1,1;
+  multseq2charexp(v);
+  intvec v1=4,2,2,1,1;
+  multseq2charexp(v1);
+}
+
+proc charexp2inter (intmat contact, list charexp)
+"USAGE:      charexp2inter(contact,charexp),  contact matrix, charexp list
+ASSUME:      charexp contains the integer vectors of characteristic exponents
+             of the branches of a plane curve singularity, and contact is their
+             contact matrix
+RETURN:      intmat, the matrix intersection multiplicities of the branches
+SEE ALSO:    invariants, resolutiongraph, totalmultiplicities, semigroup
+KEYWORDS:    contact matrix; characteristic exponents; intersection multiplicity; topological invariants
+EXAMPLE:     example charexp2inter;   shows an example"
+{
+  int n=ncols(contact);
+  int i,j,k;
+  list multpl;
+  int max=0;
+  intvec helpvect;
+  intmat inters[n][n];
+  // Calculate the multiplicity sequences of the branches.
+  for (i=1;i<=n;i++)
+  {
+    multpl[i]=charexp2multseq(charexp[i]);
+    // Find the maximal length of a multiplicity sequence.
+    if (max<size(multpl[i]))
+    {
+      max=size(multpl[i]);
+    }
+  }
+  // If the contact of certain branches is higher than the maximal length of the
+  // multiplicity sequence, then max should be the maximal contact!
+  helpvect=max,intvec(contact);
+  max=max_in_intvec(helpvect)[1];
+  // Prolong them by 1s, in order to take care of higher contact.
+  for (i=1;i<=n;i++)
+  {
+    helpvect=multpl[i];
+    for (j=size(multpl[i]+1);j<=max;j++)
+    {
+      helpvect[j]=1;
+    }
+    multpl[i]=helpvect;
+  }
+  // Calculate the intersection numbers of the branches: for two branches f_i and f_j
+  // this is the sum over mult_k(f_i)*mult_k(f_j), where k runs over all infinitely
+  // near points which f_i and f_j share, i.e. from 1 to contact[i,j].
+  for (i=1;i<=n;i++)
+  {
+    for (j=i+1;j<=n;j++)
+    {
+      for (k=1;k<=contact[i,j];k++)
+      {
+        inters[i,j]=inters[i,j]+multpl[i][k]*multpl[j][k];
+      }
+      inters[j,i]=inters[i,j];
+    }
+  }
+  return(inters);
+}
+example
+{
+  "EXAMPLE:";echo=2;
+  ring r=0,(x,y),ds;
+  list INV=invariants((x2-y3)*(x3-y2)*((x2-y3)^2-4x5y-x7));
+  intmat contact=INV[4][1];
+  list charexp=INV[1][1],INV[2][1],INV[3][1];
+  // The intersection matrix is INV[4][2].
+  print(INV[4][2]);
+  // And it is calulated as ...
+  print(charexp2inter(contact,charexp));
+}
+
+
+proc charexp2conductor(intvec B)  // Procedure written by Fernando
+"USAGE:      charexp2conductor(v),  v intvec
+ASSUME:      v contains the characteristic exponents of an irreducible plane
+             curve singularity
+RETURN:      int, the conductor of the plane curve singularity
+NOTE:        If the curve singularity is smooth, the conductor is zero.
+SEE ALSO:    invariants, resolutiongraph, totalmultiplicities, semigroup
+KEYWORDS:    conductor; characteristic exponents; multiplicity sequence; topological invariants
+EXAMPLE:     example charexp2conductor;   shows an example"
+{
+  intvec E;
+  int i,conductor;
+  E[1]=B[1];
+  for(i=2;i<=size(B);i++)
+    {
+      E[i]=gcd(E[i-1],B[i]);
+    }
+  conductor=1-E[1];
+  for(i=2;i<=size(B);i++)
+    {
+      conductor=conductor+(B[i]*(E[i-1]-E[i]));
+    }
+  return(conductor);
+}
+example
+{
+  "EXAMPLE:";
+  echo=2;
+  charexp2conductor(intvec(2,3));  // A1-Singularity
+  charexp2conductor(intvec(28,64,66,77));
+}
+
+
+proc charexp2poly(intvec v, vector a)  // Procedure written by Fernando.
+"USAGE:  charexp2poly(v,a); intvec v, vector a.
+ASSUME:  v an intvec containing the characterictic exponents of an irreducible plane curve singularity.
+         a a vector containing the coefficients of a parametrization given by x(t)=x^v[1],
+         y(t)=a(1)t^v[2]+...+a[n-1]t^v[n], i.e. the entries of a are of type number.
+RETURN:  A polynomial f in the first two variables of the basering, such that f defines an
+         irreducible plane curve singularity with characteristic exponents v.
+NOTE:    The entries in a should be of type number and the vector v should be the sequence of
+         characteristic exponents of an irreducible plane curve singularity in order to
+         get a sensible result,
+SEE ALSO: charexp2multseq, multseq2charexp.
+EXAMPLE: example charexp2poly;  shows an example
+"
+{
+  int n=size(v);
+  vector expo;
+  int i,j,s;
+  for(i=1;i<=v[1];i++)
+  {
+    expo[i]=0;//initialize to 0.
+  }
+  for(i=2;i<=n;i++)
+  {
+    s=v[i] mod v[1];//calculate the position.
+    expo=expo-a[i-1]*var(1)^((v[i]-s) div v[1])*gen(s+1);//save in expo -var(1) to the power the corresponding
+                                                     //but only in the right positions
+  }
+  matrix M[v[1]][v[1]];
+  //construct the matrix that generates the polynomial
+  for(i=1;i<=v[1];i++)
+  {
+    M[i,i]=var(2)+expo[1];//The  diagonal
+    for(j=1;j<=v[1]-i;j++)
+         {
+           M[j,j+i]=expo[i+1];//over diagonal
+         }
+    for(j=1;j<=v[1]-i;j++)
+         {
+           M[j+i,j]=var(1)*expo[1+v[1]-i];//under diagonal
+         }
+  }
+  //the poynomial is the determinant of the matrix
+  poly irredpoly=det(M);
+  return(irredpoly)
+}
+example
+{
+  "EXAMPLE:";echo=2;
+  ring r=0,(x,y),dp;
+  intvec v=8,12,14,17;
+  vector a=[1,1,1];
+  poly f=charexp2poly(v,a);
+  f;
+  invariants(f)[1][1];  // The characteristic exponents of f.
+}
+
+proc tau_es2 (def INPUT, list #)
+"USAGE:  tau_es2(INPUT); INPUT poly or list
+ASSUME:  INPUT is either a REDUCED bivariate polynomial defining a plane curve singularity,
+         or the output of @code{hnexpansion(f[,\"ess\"])}, or the list @code{hne} in
+         the ring created by @code{hnexpansion(f[,\"ess\"])}, or the output of
+         @code{develop(f)} resp. of @code{extdevelop(f,n)}, or a list containing
+         the contact matrix and a list of integer vectors with the characteristic exponents
+         of the branches of a plane curve singularity, or an integer vector containing the
+         characteristic exponents of an irreducible plane curve singularity.
+RETURN:  int, the equisingular Tjurina number of f, i. e. the codimension of the mu-constant
+         stratum in the semiuniversal deformation of f, where mu is the Milnor number of f.
+NOTE:    The equisingular Tjurina number is calculated with the aid of a Hamburger-Noether
+         expansion, which is the hard part of the calculation.
+         In case the Hamburger-Noether expansion of the curve f is needed
+         for other purposes as well it is better to calculate this first
+         with the aid of @code{hnexpansion} and use it as input instead of
+         the polynomial itself.
+         @*
+         If you are not sure whether the INPUT polynomial is reduced or not, use
+         @code{squarefree(INPUT)} as input instead.
+SEE ALSO: tau_es, develop, hnexpansion, totalmultiplicities, equising_lib
+EXAMPLE: example tau_es2;  shows an example
+"
+{
+  // If the input is a weighted homogeneous polynomial, then use a direct algorithm to
+  // calculate the equisingular Tjurina number, by caluclating a K-basis of the
+  // Tjurina algebra and omitting those elements with weighted degree at least the
+  // weighted degree of the polynomial. -- If an additional input # is given (which is
+  // not just the number 1 !!!), the procedure always uses the recursive algorithm.
+  if ((typeof(INPUT)=="poly") and (size(#)==0))
+  {
+    if (qhweight(INPUT)[1]!=0)
+    {
+      /*
+      poly f=squarefree(INPUT);
+      if ( deg(f)!=deg(INPUT) )
+      {
+        dbprint(printlevel-voice+3,"// input polynomial was not reduced");
+        dbprint(printlevel-voice+3,"// we continue with its reduction");
+      }
+      return(tau_es_qh(f));
+      */
+      return(tau_es_qh(INPUT));
+    }
+  }
+  // Else apply the recursive algorithm from Eugenii Shustin, On Manifolds of Singular
+  // Algebraic Curves, Selecta Math. Sov. Vol 10, No. 1 (1991), p. 31.
+  int i,j,k;                  // Laufvariablen
+  int tau,tau_i;              // Variable for es-Tjurina no., multiplicitiy, and es-Tjurina at blow ups
+  intmat contact;             // contact matrix
+  list graphs, multipl;       // resolution graphs and multiplicity sequences
+  list graphs_ed, multipl_ed; // res.graphs and mult.seq. of one curve on 1st ex. div.
+  intmat contact_ed;          // contact matrix of one curve on 1st exceptional divisor
+  int d_i;                    // correction term
+  intvec connections;
+  intmat graph;
+  intvec multseq;
+  int s,e;
+  int multi;                  // multiplicity of the curve defined by the input.
+  /////////////////////////////////////////////////////////
+  // Check what type the input is, and act accordingly.
+  if (typeof(INPUT)=="list")
+  {
+    if (size(INPUT)==3)
+    {
+      // If the INPUT is the output of totalmultiplicities(INPUT,"tau")
+      if ((typeof(INPUT[1])=="list") and (typeof(INPUT[2])=="list") and (typeof(INPUT[3])=="intmat"))
+      {
+        graphs=INPUT[1];
+        multipl=INPUT[2];
+        contact=INPUT[3];
+      }
+      // Otherwise call the procedure with the output of totalmultiplicities(INPUT,"tau").
+      else
+      {
+        return(tau_es2(totalmultiplicities(INPUT,"tau")));
+      }
+    }
+    else
+    {
+      return(tau_es2(totalmultiplicities(INPUT,"tau")));
+    }
+  }
+  // Otherwise call the procedure with the output of totalmultiplicities(INPUT,"tau").
+  else
+  {
+    return(tau_es2(totalmultiplicities(INPUT,"tau")));
+  }
+  /// End of checking the input
+  ///////////////////////////////////////////////////////
+  // If the singularity is smooth, the equisingular Tjurina number is zero.
+  if ((ncols(contact)==1) and (multipl[1][1]<=1))
+  {
+    return(0);
+  }
+  // Otherwise calculate the multiplicity of the singularity.
+  for (i=1;i<=size(multipl);i++)
+  {
+    multi=multi+multipl[i][1];
+  }
+  // Find the branches which stay together after blowing up once, and group them together.
+  k=0;
+  intvec curves_on_first_ex_div=k;  // If this is 0=i_0,i_1,...i_s=ncols(contact), then the branches
+  while (k<ncols(contact))          // (i_j)+1,...,i_(j+1) stay together after the first blowing up,
+  {                                 // and s is the number of infinitely near points of first order.
+    k=find_last_non_one(intvec(contact[k+1,1..ncols(contact)]),k+2);
+    curves_on_first_ex_div=curves_on_first_ex_div,k;
+  }
+  // And then calculate the equisingular Tjurina numbers in the infinitely near points of
+  // first order plus some correction term (= the number of blow ups needed to separate the
+  // strict transform from the exceptional divisor in the corresponding infinitely near point)
+  // and add them.
+  for (i=1;i<=size(curves_on_first_ex_div)-1;i++)
+  {
+    s=curves_on_first_ex_div[i]+1;
+    e=curves_on_first_ex_div[i+1];
+    graphs_ed=list(graphs[s..e]);
+    multipl_ed=list(multipl[s..e]);
+    contact_ed=intmat_minus_one(intmat(intvec(contact[s..e,s..e]),e-s+1,e-s+1));
+    connections=0;
+    // Adjust the graphs and multiplicity sequences by cutting the first level.
+    // And find in each graph the point to which the point 1 is connected = 1 + number of
+    // blow ups needed to separate the strict transform from the first exceptional divisor.
+    for (j=1;j<=size(graphs_ed);j++)
+    {
+      // Adjust the graphs and find the connection points.
+      graph=graphs_ed[j];
+      connections[j]=find_connection_point(intvec(graph[1,1..ncols(graph)]),1);
+      graph=delete_row(delete_col(graph,1),1);
+      graphs_ed[j]=graph;
+      // Adjust the multiplicity sequences.
+      multseq=multipl_ed[j];
+      if (size(multseq)==1)  // If multseq has only one entry, then their is only
+      {                      // one branch left and it is smooth! So set multipl_ed[j]=1.
+        multipl_ed[j]=intvec(1);
+      }
+      else  // Otherwise just cut the first entry.
+      {
+        multipl_ed[j]=intvec(multseq[2..size(multseq)]);
+      }
+    }
+    // Calculate the equisingular Tjurina number of the strict transform at the i-th
+    // intersection point with the first exceptional divisor.
+    tau_i=tau_es2(list(graphs_ed,multipl_ed,contact_ed));
+    // Calculate the number no. of blow ups needed to separate the strict transform of
+    // the curve defined by the input from the first exceptional divisor at their i-th
+    // intersection point.
+    d_i=max_in_intvec(connections)-1;
+    // If d_i is negative, then there was only one branch left and it was smooth, so d_i should be 1.
+    if (d_i<0)
+    {
+      d_i=1;
+    }
+    // If the curve defined by graphs_ed was smooth, then the summand has to be reduced by 1.
+    if (tau_i==0)
+    {
+      tau_i=-1;
+    }
+    tau=tau+tau_i+d_i;
+  }
+  // The equisingular Tjurina number is then calculated by adding the following term.
+  tau=tau+((multi*(multi+1)) div 2)-2;
+  return(tau);
+}
+example
+{
+  "EXAMPLE:";
+  echo=2;
+  ring r=0,(x,y),ls;
+  poly f1=y2-x3;
+  poly f2=(y2-x3)^2-4x5y-x7;
+  poly f3=y3-x2;
+  tau_es2(f1);
+  tau_es2(f2);
+  tau_es2(f1*f2*f3);
+}
+
+
+///////////////////////////////////////////////////////////////////////////////////////////
+// Static procedures.
+///////////////////////////////////////////////////////////////////////////////////////////
+
+static proc euclidseq(int a,int b)
+"USAGE:      euclidseq(a,b),  a,b integers
+RETURN:      intvec,  the divisors in the euclidean alogrithm with multiplicities
+KEYWORDS:    Euclidean algorithm; multiplicity sequence
+NOTE :       This procedure is for internal use only; it is called by charexp2multseq.
+"
+{
+  int i;
+  // multseq saves in each step of the Euclidean algorithm q-times the divisor b
+  intvec multseq;
+  int q=a div b;
+  int r=a mod b;
+  for (i=1;i<=q;i++)
+  {
+    multseq[i]=b;
+  }
+  int s=q;        // size of multseq
+  a=b;
+  b=r;
+  while(r<>0)
+  {
+        q=a div b;
+        r=a mod b;
+    for (i=1;i<=q;i++)
+    {
+      multseq[s+i]=b;
+    }
+    s=s+q;        // size of multseq
+        a=b;
+        b=r;
+  }
+  return(multseq);
+}
+
+static proc puiseuxchainpart (int piij, int muij, intvec multpl, int initial_tm, int end_tm, int j)
+"USAGE:   puiseuxchainpart(piij,muiij,multpl,initial_tm,end_tm,j);
+RETURN:   list L, L[1] incidence matrix of a part of the Puiseux chain, L[2] the total
+          multiplicities of this part of the Puiseux chain.
+NOTE:     This procedure is only for internal use; it is called by puiseuxchain.
+"
+{
+  int delta=1;
+  if (j==1){delta=0;}                 // Delta measures whether j is 1 or not.
+  intvec totalmultiplicity;           // Keeps the total multiplicities.
+  intmat pcp[muij][muij];             // Keeps the incidence matrix of the Puiseuxchainpart S_i,j.
+  // Calculate the total multiplicities and the Puiseuxchainpart S_i,j.
+  totalmultiplicity[1]=initial_tm+end_tm+multpl[1];
+  pcp[1,1]=piij+1;
+  for (int k=2;k<=muij;k++)
+  {
+    pcp[k,k]=piij+k;
+    pcp[k-1,k]=1;
+    pcp[k,k-1]=1;
+    totalmultiplicity[k]=totalmultiplicity[k-1]+delta*initial_tm+multpl[k];
+  }
+  list result=pcp,totalmultiplicity;
+  return(result);
+}
+
+static proc puiseuxchain (int initial, intvec divseq, intvec multpl, int initial_tm)
+"USAGE:   puiseuxchain(initial,divseq,multpl,initial_tm); int initial, initial_tm, intvec divseq, multpl
+RETURN:   list L, L[1] incidence matrix of a Puiseux chain, L[2] the weight of the point to which the
+          previous Puiseux chain has to be connected, L[3] the sequence of total multiplicities of
+          the points in this Puiseux chain.
+NOTE:     This procedure is only for internal use; it is called by irred_resgraph_totmult.
+"
+{
+  int j,k,l,connectpoint;
+  intvec multpli;
+  int pc_tm=initial_tm;       // Keeps the total multipl. of the endpoint of P_i-1.
+  int end_tm=0;
+  int start=1;
+  int omega=size(divseq);
+  // Keep the endpoints of the puiseuxchainparts (minus initial)  s_i,j in divseq_sum.
+  intvec divseq_sum=divseq[1];
+  for (j=2;j<=omega;j++)
+    {
+      divseq_sum[j]=divseq_sum[j-1]+divseq[j];
+    }
+  // Define the connecting point of the Puiseuxchain P_i-1 with P_i.
+  if (divseq[1]==0)
+  {
+    // If divseq[1]=mu_i,1=0, then the Puiseuxchainpart S_i,1 is empty.
+    // We may start building the Puiseuxchain with part 2, i.e. set start=2.
+    start=2;
+    if (omega>=3)
+    {
+      connectpoint=initial+divseq_sum[2]+1;  // startpoint of s_i+1,3
+    }
+    else
+    {
+      connectpoint=initial+divseq_sum[2];    // endpoint of s_i+1,2
+    }
+  }
+  else
+  {
+    connectpoint=initial+1;
+  }
+  // Build the Puiseuxchainparts s_i,j and put them as blocks into pc=P_i.
+  multpli=multpl[initial+1..initial+divseq_sum[start]];
+  list pcp=puiseuxchainpart(initial,divseq[start],multpli,initial_tm,end_tm,start);
+  intmat pc=pcp[1];
+  intvec tm=pcp[2];
+  for (j=start+1;j<=omega;j++)
+    {
+      // Keep the final total multipl. of the puiseuxchainpart S_i,j-2 resp. P_i-1, if S_i,1 empty.
+      if (j>2){end_tm=initial_tm;}
+      // Calculate the endpoint of S_i,j-1.
+      initial=initial+divseq[j-1];
+      // Keep the total multiplicity of the endpoint of S_i,j-1
+      initial_tm=pcp[2][size(pcp[2])];
+      // Build the new puiseuxchainpart S_i,j
+      multpli=multpl[initial+1..initial+divseq[j]];
+      pcp=puiseuxchainpart(initial,divseq[j],multpli,initial_tm,end_tm,j);
+      pc=addmat(pc,pcp[1]);
+      tm=tm,pcp[2];
+    }
+  // Connect the Puiseuxchainparts s_i,j.
+  for (j=start;j<=omega-2;j++)
+    {
+      k=divseq_sum[j];          // endpoint of s_i,j
+      l=divseq_sum[j+1]+1;      // startpoint of s_i,j+2
+      pc[k,l]=1;            // connecting these
+      pc[l,k]=1;
+    }
+  if (omega>=start+1)   // If there are at least two non-empty s_i,j.
+    {
+      k=divseq_sum[omega-1];    // endpoint of s_i,omega-1
+      l=divseq_sum[omega];      // endpoint of s_i,omega
+      pc[k,l]=1;            // connecting these
+      pc[l,k]=1;
+    }
+  list ergebnis=pc,connectpoint,tm;
+  return(ergebnis);
+}
+
+static proc irred_resgraph_totmult (intvec charexp)
+"USAGE:   irred_resgraph_totmult(charexp); charexp intvec
+ASSUME:   charexp is an integer vector containg the characteristic exponents of
+          an irreducible plane curve singularity
+RETURN:   list L, L[1] is the incidence matrix of the resolution graph of the plane curve
+          singularity defined by INPUT, and L[2] is its sequence of total multiplicities
+NOTE:     This procedure is only for internal use; it is called by resgraph.
+"
+{
+  int k,l;
+  intvec multpl=charexp2multseq(charexp);  // multiplicity sequence of the singularity
+  // Do first the case where the singularity is actually smooth.
+  if (size(charexp)==1)
+  {
+    intmat resgraph[1][1]=0;
+    intvec tm=1;   // there is no exceptional divisor in the resolution - ERROR: should be 0,
+                   // but for the time being, Singular returns 1 as multiplicity of smooth curves
+    list result=resgraph,tm,multpl;
+    return(result);
+  }
+  // End of the smooth case
+  int initial_tm=0;                  // total multipl. of the endpoint of Puiseux chain P_i-1
+  int g=size(charexp);
+  list es=divsequence(charexp[2],charexp[1]);   // keeps the lengths of the Puiseuxchainparts s_i,j
+  intvec divseq=es[1];
+  int r=es[2];
+  int initial=0;
+  // Build the Puiseuxchains P_i and put them as blocks into a matrix.
+  list pc=puiseuxchain(initial,divseq,multpl,initial_tm);
+  intmat resgraph=pc[1];
+  intvec endpoints=resgraph[nrows(resgraph),ncols(resgraph)];
+  intvec connectpoints=pc[2];
+  intvec tm=pc[3];
+  for (int i=3;i<=g;i++)
+    {
+      initial_tm=tm[size(tm)];
+      es=divsequence(charexp[i]-charexp[i-1],r);
+      divseq=es[1];
+      r=es[2];
+      initial=endpoints[size(endpoints)];
+      pc=puiseuxchain(initial,divseq,multpl,initial_tm);
+      resgraph=addmat(resgraph,pc[1]);
+      endpoints=endpoints,resgraph[nrows(resgraph),ncols(resgraph)];
+      connectpoints=connectpoints,pc[2];
+      tm=tm,pc[3];
+    }
+  // Adding the * for the strict transform to the Graph.
+  resgraph=addmat(resgraph,0);
+  // The connecting point of the * with the graph.
+  connectpoints=connectpoints,nrows(resgraph);
+  // Connect the P_i with each other and with *.
+  for (i=2;i<=g;i++)
+  {
+    k=endpoints[i-1];          // endpoint of P_i-1
+    l=connectpoints[i];        // conncting point of P_i resp. of *
+    resgraph[k,l]=1;          // connecting these
+    resgraph[l,k]=1;
+  }
+  list result=resgraph,tm,multpl; //HIER GEAENDERT!!!!
+  return(result);
+}
+
+
+static proc max_in_intvec (intvec v, list #)
+"USAGE:   max_in_intvec(v); v intvec
+RETURN:   int m, maximum of the integers in v
+USAGE:    max_in_intvec(v,1); v intvec
+RETURN:   intvec m, m[1] maximum of the integers in v, m[2] position of the
+          last occurence of the maximum in v
+NOTE:     This procedure is only for internal use; this procedure is called by
+          totalmultiplicities and semigroup.
+"
+{
+  int max=v[1];
+  int maxpos=1;
+  for (int i=2;i<=size(v);i++)
+  {
+    if (v[i]>max)
+    {
+      max=v[i];
+      maxpos=i;
+    }
+  }
+  if (size(#)==0)
+  {
+    return(max);
+  }
+  else
+  {
+    return(intvec(max,maxpos));
+  }
+}
+
+static proc addmat (intmat A,intmat B)
+"USAGE:   max_in_intvec(A,B); A, B integer matrices
+RETURN:   intmat C, block matrix with left-upper block A, right-lower block B
+NOTE:     This procedure is only for internal use; this procedure is called several times.
+"
+{
+  int nc=ncols(A);
+  int nr=nrows(A);
+  int mc=ncols(B);
+  int mr=nrows(B);
+  int i,j;
+  intmat AB[nr+mr][nc+mc];
+  for (i=1;i<=nr;i++)
+    {
+      for (j=1;j<=nc;j++)
+        {
+          AB[i,j]=A[i,j];
+        }
+    }
+  for (i=1;i<=mr;i++)
+    {
+      for (j=1;j<=mc;j++)
+        {
+          AB[i+nr,j+nc]=B[i,j];
+        }
+    }
+  return(AB);
+}
+
+static proc divsequence(int a,int b)
+"USAGE:   divsequence(a,b); a,b integers
+RETURN:   list l, l[1] the multiplicities of the divisors in the Euclidean algorithm
+          and l[2] the last non-zero remainder in the Euclidean algorithm
+NOTE:     This procedure is only for internal use; it is called in irred_res_graph.
+"
+{
+  int q=a div b;
+  int r=a mod b;
+  intvec divseq=q;
+  while(r<>0)
+  {
+    a=b;
+    b=r;
+    q=a div b;
+    r=a mod b;
+    divseq = divseq,q;
+  }
+  list result=divseq,b;
+  return(result);
+}
+
+
+
+static proc adjust_tot_mult (intvec rtm_fix, intvec rtm_var, intvec rmt_fix, intvec rmt_var, def p, def q, def stricttransforms, int k)
+"USAGE:   adjust_tot_mult(v1,v2,v3,v4,p,q,st,k); v1,...,st intvecs and k an integer
+RETURN:   intvec rtm_var, adjusted total multiplicities
+NOTE:     This procedure is only for internal use; it is called in totalmultiplicities.
+"
+{
+  int j,l,store;  // Help variables.
+  // Recalculate the entries in rtm_var from stricttransforms[k]+1,...,stricttransforms[k+1]-1.
+  for (j=stricttransforms[k]+1;j<stricttransforms[k+1];j++)
+  {
+    if (rtm_var[j]==0) // If the entry is non-zero, we know that it is already correct.
+    {
+      // Check if the vertex in the fixed part is connected to one or to two vertices of lower weight.
+      if (j==stricttransforms[k]+1)  // The vertex of weight 1 less is p[k], to which the subgraph is glued.
+      {
+        store=rtm_fix[j]-rmt_fix[j]-rtm_fix[p[k]];
+      }
+      else                           // The vertex of weight 1 less belongs to the subgraph.
+      {
+        store=rtm_fix[j]-rmt_fix[j]-rtm_fix[j-1];
+      }
+      // It is connected to two vertices V (which has weight one less) and W.
+      if (store>0)
+      {
+        if (j==stricttransforms[k]+1)  // V is p[k] (to which the subgraph was glued) and W is q[k], the
+        {                              // vertex of weight one less, to which p[k] is connected.
+          rtm_var[j]=rtm_var[p[k]]+rtm_var[q[k]];  // In this case the subgraph separates p[k] and q[k]!
+        }
+        if (j==stricttransforms[k]+2)  // V belongs to the subgraph (it is the vertex considerd in the
+        {  // previous case!), and W is p[k] or q[k]. In this case the subgraph separates p[k] and q[k].
+          if (store==rtm_fix[p[k]])  // If W=p[k], ...
+          {
+            rtm_var[j]=rtm_var[j-1]+rtm_var[p[k]];
+          }
+          else                       // else W=q[k] ... .
+          {
+            rtm_var[j]=rtm_var[j-1]+rtm_var[q[k]];  // separates p[k] and q[k].
+          }
+        }
+        if (j>stricttransforms[k]+2)  // V belongs to the subgraph and W either does as well or is p[k].
+        {
+          l=j-2;
+          while (store<rtm_fix[l]) // Find the second vertex W which is connected to which it is
+          {                        // connected. It has total multipl. = store!
+            if (l>stricttransforms[k]+1) // If l-1 belongs to the graph, then reduce l.
+            {
+              l=l-1;
+            }
+            else // If l-1 is stricttransform[k], hence isn't in the graph, then reducing l gives p[k].
+            {    // If l=p[k] and still store<rtm_fix[l], then j must be connected to q[k]!
+              if (l==stricttransforms[k]+1)
+              {
+                l=p[k];
+              }
+              else
+              {
+                l=q[k];
+              }
+            }
+          }
+          rtm_var[j]=rtm_var[j-1]+rtm_var[l];
+        }
+      }
+      // It is only connected to one vertex V, which then must be the one of weight one less.
+      else
+      {
+        if (j==stricttransforms[k]+1) // V is p[k], the vertex, to which the subgraph was glued.
+        {
+          rtm_var[j]=rtm_var[p[k]];
+        }
+        else
+        {
+          rtm_var[j]=rtm_var[j-1];  // V is belongs already to the subgraph.
+        }
+      }
+    }
+  }
+  return(rtm_var);
+}
+
+
+static proc find_connection_point (intvec v, int k)
+"USAGE:   find_connection_point(v,c); where v is an intvec, and k is an integer
+RETURN:   The largest integer i>k, such that v[i]=1, or 0 if no such i exists.
+NOTE:     This procedure is only for internal use; it is called in totalmultiplicities.
+"
+{
+  for (int i=size(v)-1;i>=k+1;i--)
+  {
+    if (v[i]==1)
+    {
+      return(i);
+    }
+  }
+  return(0);
+}
+
+static proc find_connection_points (intmat resgr, int k)
+"USAGE:   find_connection_points(resgr,k); where resgr is an intmat, and k is an integer
+RETURN:   list of two intvecs ctps and ctpswts, where ctps contains all integers i!=k, such
+          that resgr[k,i]=1, and ctpswts contains for each such i the weight resgr[i,i].
+NOTE:     This procedure is only for internal use; it is called in totalmultiplicities.
+"
+{
+  intvec ctps;
+  intvec ctpswts;
+  int j=1;
+  for (int i=1;i<=ncols(resgr);i++)
+  {
+    if ((resgr[k,i]==1) and (i!=k))
+    {
+      ctps[j]=i;
+      ctpswts[j]=resgr[i,i];
+      j++;
+    }
+  }
+  return(list(ctps,ctpswts));
+}
+
+static proc find_lower_connection_points (intmat resgr, int k)
+"USAGE:   find_lower_connection_points(resgr,k); where resgr is an intmat, and k is an integer
+ASSUME:   resgr is the resolutiongraph of an IRREDUCIBLE curve singularity and k<ncols(resgr).
+RETURN:   intvec, which contains the weights of points of lower weight than k, to which
+          the point of weight k in resgr is connected, and 0 if no such point exists.
+NOTE:     This procedure is only for internal use; it is called in totalmultiplicities.
+"
+{
+  intvec ctps=find_connection_points(resgr,k)[2];
+  intvec lower_ctps;
+  int i=1;
+  while ((ctps[i]<k) and (ctps[i]>0))
+  {
+    lower_ctps[i]=ctps[i];
+    i++;
+  }
+  return(lower_ctps);
+}
+
+
+static proc euclides(int a,int b)  // Procedure of Fernando.
+"USAGE:   euclides(m,n);where m,n are integers.
+RETURN:   The divisor, the quotients and the remainders of the euclidean algorithm performing for m and n.
+NOTE:     This procedure is only for internal use; it is called in multseq2charexp.
+"
+{
+ int c=a div b;//we compute in c the integer division between a and b.
+ int r=a mod b;//in r the remainer of the division between a and b
+ intvec dividendo=c;// we define the intvec of the dividens and we initialize it to c
+ intvec remain=r;// we define the intvec of the remainders and we initialize it to r
+ a=b;//change a to b
+ b=r;// and b to r
+
+ while(r<>0)// while the current remainder is diferent to 0 we make the same af before
+  {
+    c=a div b;
+    r=a mod b;
+    dividendo =dividendo,c;
+    if(r<>0)
+      {
+        remain=remain,r;
+      }
+       a=b;
+       b=r;
+     }
+   list L=dividendo,remain;//we put in a list all the dividens and all the remainders
+   return(L);// and return the list
+}
+
+
+
+static proc tau_es_qh (poly f)
+"USAGE:    tau_es_qh(f), poly f
+RETURN:   int, equisingular Tjurina number
+NOTE:     This procedure is only for internal use; it is called in Tau_es.
+"
+{
+  intvec qh=qhweight(f);
+  if (qh[1]==0)
+  {
+    ERROR("Input is not quasi-homogenous.");
+  }
+  else
+  {
+    int d_f = deg(f,qh);
+    list Tj=Tjurina(f,1);
+    ideal tj=Tj[2];
+    int Taues=size(tj);
+    for (int i=1;i<=size(tj);i++)
+    {
+      if (deg(tj[i],qh)>=d_f)
+      {
+        Taues--;
+      }
+    }
+  }
+  return(Taues);
+}
+
+
+static proc move_row (intmat M, int i,int j)
+"USAGE:    move_row(M,i,j), intmat M, int i,j
+RETURN:   intmat, the matrix M with j-th row now i-th row and the remaining rows moved accordingly.
+NOTE:     This procedure is only for internal use; it is called in move_row_col.
+"
+{
+  if ((i>nrows(M)) or (j>nrows(M)))
+  {
+    ERROR("The matrix has not enough rows.");
+  }
+  if (i==j)
+  {
+    return(M);
+  }
+  if (i>1)
+  {
+    intmat N[nrows(M)+1][ncols(M)]=intvec(M[1..i-1,1..ncols(M)]),intvec(M[j,1..ncols(M)]),intvec(M[i..nrows(M),1..ncols(M)]);
+  }
+  if (i==1)
+  {
+    intmat N[nrows(M)+1][ncols(M)]=intvec(M[j,1..ncols(M)]),intvec(M[i..nrows(M),1..ncols(M)]);
+  }
+  if (i<j)
+  {
+    N=delete_row(N,j+1);
+  }
+  if (i>j)
+  {
+    N=delete_row(N,j);
+  }
+  return(N);
+}
+
+static proc move_col (intmat M, int i,int j)
+"USAGE:    move_col(M,i,j), intmat M, int i,j
+RETURN:   intmat, the matrix M with j-th column now i-th column and the remaining columns moved accordingly.
+NOTE:     This procedure is only for internal use; it is called in move_row_col.
+"
+{
+  return(transpose(move_row(transpose(M),i,j)));
+}
+
+static proc move_row_col (intmat M,int i,int j)
+"USAGE:    move_row(M,i,j), intmat M, int i,j
+RETURN:   intmat, the matrix M with j-th row/column now i-th row/column and the remaining
+          rows and columns moved accordingly.
+NOTE:     This procedure is only for internal use; it is called in totalmultiplicities.
+"
+{
+  return(move_col(move_row(M,i,j),i,j));
+}
+
+
+static proc delete_row (intmat M,int i)
+"USAGE:    delete_row(M,i); M intmat, i int
+RETURN:   intmat, which is derived from M by removing the ith row
+NOTE:     This procedure is only for internal use; it is called in move_row and tau_es2.
+"
+{
+  if ((i!=1) and (i!=nrows(M)))
+  {
+    return(intmat(intvec(M[1..i-1,1..ncols(M)],M[i+1..nrows(M),1..ncols(M)]),nrows(M)-1,ncols(M)));
+  }
+  if (i==1)
+  {
+    return(intmat(intvec(M[2..nrows(M),1..ncols(M)]),nrows(M)-1,ncols(M)));
+  }
+  else
+  {
+    return(intmat(intvec(M[1..nrows(M)-1,1..ncols(M)]),nrows(M)-1,ncols(M)));
+  }
+}
+
+static proc delete_col (intmat M, int i)
+"USAGE:    delete_col(M,i); M intmat, i int
+RETURN:   intmat, which is derived from M by removing the ith column
+NOTE:     This procedure is only for internal use; it is called in tau_es.
+"
+{
+  return(transpose(delete_row(transpose(M),i)));
+}
+
+
+
+static proc sort_branches (intmat contact, list graphs, list totmult, list multpl, int k,int l)
+"USAGE:    sort_branches(K,L,M,N,k,l); K intmat, L,M,N lists, k,l integers
+ASSUME:   K = contact matrix of the branches of a curve, L = their resolutiongraphs,
+          M = their totalmultiplicities, N = their multiplicities
+RETURN:   list LL, LL[1] transformed K, LL[2..4] transformed L,M,N.
+          The procedure sorts the branches from k+1 to l according to descending contact with
+          with the branch k.
+NOTE:     This procedure is only for internal use; it is called in totalmultiplicities.
+"
+{
+  intvec max;
+  for (int i=k+1;i<=l;i++)
+  {
+    // Find the last graph max between i and l which has maximal contact with k.
+    max=max_in_intvec(intvec(contact[k,i..l]),1);
+    max[2]=max[2]+i-1;
+    if (i!=max[2])  // If max is not i, then move max to position i!
+    {
+      graphs=insert(graphs,graphs[max[2]],i-1);
+      graphs=delete(graphs,max[2]+1);
+      totmult=insert(totmult,totmult[max[2]],i-1);
+      totmult=delete(totmult,max[2]+1);
+      multpl=insert(multpl,multpl[max[2]],i-1);
+      multpl=delete(multpl,max[2]+1);
+      contact=move_row_col(contact,i,max[2]);
+    }
+  }
+  return(list(contact,graphs,totmult,multpl));
+}
+
+
+static proc find_last_non_one (intvec v,int k)
+"USAGE:    find_last_non_one (v,k); intvec v, int k
+RETURN:   int i, the last index i>=k such that v[i]!=1, or k-1 if no such i exists.
+NOTE:     This procedure is only for internal use; it is called in tau_es2.
+"
+{
+  int i=size(v);
+  while (i>=k)
+  {
+    if (v[i]!=1)
+    {
+      return(i);
+    }
+    else
+    {
+      i--;
+    }
+  }
+  return(i);
+}
+
+static proc intmat_minus_one (intmat M)
+"USAGE:    intmat_minus_one(M);  intmat M
+RETURN:   intmat, all non-zero entries of M deminuished by 1.
+NOTE:     This procedure is only for internal use; it is called in tau_es2.
+"
+{
+  int i,j;
+  for (i=1;i<=nrows(M);i++)
+  {
+    for (j=1;j<=ncols(M);j++)
+    {
+      if (M[i,j]!=0)
+      {
+        M[i,j]=M[i,j]-1;
+      }
+    }
+  }
+  return(M);
+}
+
+proc proximitymatrix (def INPUT)
+"USAGE:  proximitymatrix(INPUT); INPUT poly or list or intmat
+ASSUME:  INPUT is either a REDUCED bivariate polynomial defining a plane curve singularity,
+         or the output of @code{hnexpansion(f[,\"ess\"])}, or the list @code{hne} in
+         the ring created by @code{hnexpansion(f[,\"ess\"])}, or the output of
+         @code{develop(f)} resp. of @code{extdevelop(f,n)}, or a list containing
+         the contact matrix and a list of integer vectors with the characteristic exponents
+         of the branches of a plane curve singularity, or an integer vector containing the
+         characteristic exponents of an irreducible plane curve singularity, or the resolution
+         graph of a plane curve singularity (i.e. the output of resolutiongraph or
+         the first entry in the output of totalmultiplicities).
+RETURN:  list, of three integer matrices. The first one is the proximity matrix of
+         the plane curve defined by the INPUT, i.e. the entry i,j is 1 if the
+         infinitely near point corresponding to row i is proximate to the infinitely
+         near point corresponding to row j. The second integer matrix is the incidence matrix of the
+         resolution graph of the plane curve. The entry on the diagonal in row i is -s-1
+         if s is the number of points proximate to the infinitely near point corresponding
+         to the ith row in the matrix. The third integer matrix is the incidence matrix of
+         the Enriques diagram of the plane curve singularity, i.e. each row corresponds to
+         an infinitely near point in the minimal standard resolution, including the
+         strict transforms of the branches, the diagonal element gives
+         the level of the point, and the entry i,j is -1 if row i is proximate to row j.
+NOTE:    In case the Hamburger-Noether expansion of the curve f is needed
+         for other purposes as well it is better to calculate this first
+         with the aid of @code{hnexpansion} and use it as input instead of
+         the polynomial itself.
+         @*
+         If you are not sure whether the INPUT polynomial is reduced or not, use
+         @code{squarefree(INPUT)} as input instead.
+         @*
+         If the input is a smooth curve, then the output will consist of
+         three one-by-one zero matrices.
+         @*
+         For the definitions of the computed objects see e.g. the book
+         Eduardo Casas-Alvero, Singularities of Plane Curves.
+SEE ALSO: develop, hnexpansion, totalmultiplicities, alexanderpolynomial
+EXAMPLE: example proximitymatrix;  shows an example
+"
+{
+  ///////// Decide on the type of input. //////////
+  if (typeof(INPUT)=="intmat")
+  {
+    intmat resgr=INPUT;
+  }
+  else
+  {
+    intmat resgr=totalmultiplicities(INPUT)[1];
+  }
+  ////////  Deal with the case of a smooth curve ////////////////
+  if (size(resgr)==1)
+  {
+    return(list(intmat(intvec(1),1,1),intmat(intvec(-1),1,1),intmat(intvec(0),1,1)));
+  }
+  ////////  Calculate the proximity resolution graph ////////////
+  int i,j;
+  int n=nrows(resgr);
+  intvec diag; // Diagonal of the Enriques diagram.
+  int si; // number of points proximate to the point corresponding to the ith row
+  // Adjust the weights of the nodes corresponding to strict transforms so
+  // as if there had been one additional blow up.
+  for (i=1;i<=n;i++)
+  {
+    // Check if the row corresponds to an exceptional divisor ...
+    if (resgr[i,i]<0)
+    {
+      j=1;
+      while ((resgr[i,j]==0) or (i==j))
+      {
+        j++;
+      }
+      resgr[i,i]=resgr[j,j]+1;
+    }
+  }
+  // Set the weights in the resolution graph to the blowing up level in the resolution.
+  for (i=1;i<=n;i++)
+  {
+    resgr[i,i]=resgr[i,i]-1;
+    diag[i]=resgr[i,i]; // The level of the corresponding infinitely near point.
+  }
+  // Replace the weights in the resolution graph by
+  // -s-1, where s is the number of points which are proximate to the point.
+  for (i=1;i<=n;i++)
+  {
+    si=-1;
+    // Find the points of higher weight which are connected to the ith row.
+    for (j=i+1;j<=n;j++)
+    {
+      // If the point in row j is connected to the ith row, then all the points of
+      // weight resgr[i,i]+1 to weight resgr[j,j] in the corresponding subgraph
+      // are proximate to the point of the ith row. This number is just resgr[j,j]-resgr[i,i].
+      if ((resgr[i,j]!=0) and (resgr[j,j]>0))
+      {
+        si=si-(resgr[j,j]-resgr[i,i]);
+      }
+    }
+    resgr[i,i]=si;
+  }
+  ///////////////  Calculate the proximity matrix  ///////////////////
+  intmat proximity=proxgauss(resgr);
+  intmat enriques=proximity;
+  for (i=1;i<=nrows(enriques);i++)
+  {
+    enriques[i,i]=diag[i];
+  }
+  return(list(proximity,resgr,enriques));
+}
+example
+{
+  "EXAMPLE:";
+  echo=2;
+  ring r=0,(x,y),ls;
+  poly f1=(y2-x3)^2-4x5y-x7;
+  poly f2=y2-x3;
+  poly f3=y3-x2;
+  list proximity=proximitymatrix(f1*f2*f3);
+  /// The proximity matrix P ///
+  print(proximity[1]);
+  /// The proximity resolution graph N ///
+  print(proximity[2]);
+  /// They satisfy N=-transpose(P)*P ///
+  print(-transpose(proximity[1])*proximity[1]);
+  /// The incidence matrix of the Enriques diagram ///
+  print(proximity[3]);
+  /// If M is the matrix of multiplicities and TM the matrix of total
+  /// multiplicities of the singularity, then  M=P*TM.
+  /// We therefore calculate the (total) multiplicities. Note that
+  /// they have to be slightly extended.
+  list MULT=extend_multiplicities(totalmultiplicities(f1*f2*f3));
+  intmat TM=MULT[1];  // Total multiplicites.
+  intmat M=MULT[2];   // Multiplicities.
+  /// Check: M-P*TM=0.
+  M-proximity[1]*TM;
+  /// Check: inverse(P)*M-TM=0.
+  intmat_inverse(proximity[1])*M-TM;
+}
+
+static proc addmultiplrows (intmat M, int i, int j, int ki, int kj)
+"USAGE:   addmultiplrows(M,i,j,ki,kj);  intmat M, int i,j,ki,kj
+RETURN:   intmat, replaces the j-th row in M by ki-times the i-th row plus
+                  kj times the j-th
+NOTE:     This procedure is only for internal use; it is called in intmat_inverse
+          and proxgauss.
+"
+{
+  int k=ncols(M);
+  M[j,1..k]=kj*M[j,1..k]+ki*M[i,1..k];
+  return(M);
+}
+
+
+static proc proxgauss (intmat M)
+"USAGE:   proxgauss(M);  intmat M
+ASSUME:   M is the output of proximity_resgr
+RETURN:   intmat, replaces the j-th row in M by ki-times the i-th row plus
+                  kj times the j-th
+NOTE:     This procedure is only for internal use; it is called in intmat_inverse.
+"
+{
+  int i;
+  int n=nrows(M);
+  if (n==1)
+  {
+    M[1,1]=1;
+    return(M);
+  }
+  else
+  {
+    if (M[n,n]<0)
+    {
+      M=addmultiplrows(M,n,n,-1,0);
+    }
+    for (i=n-1;i>=1;i--)
+    {
+      if (M[i,n]!=0)
+      {
+        M=addmultiplrows(M,n,i,-M[i,n],M[n,n]);
+      }
+    }
+    intmat N[n-1][n-1]=M[1..n-1,1..n-1];
+    N=proxgauss(N);
+    M[1..n-1,1..n-1]=N[1..n-1,1..n-1];
+    return(M);
+  }
+}
+
+proc extend_multiplicities (list rg)
+"USAGE:      extend_multiplicities(rg); list rg
+ASSUME:      rg is the output of the procedure totalmultiplicities
+RETURN:      list, the first entry is an integer matrix containing the total
+             multiplicities and the second entry is an integer matrix containing
+             the multiplicies of the resolution given by rg, where the zeros
+             corresponding to the strict transforms of the branches of the curve
+             have been replaced by the (total) multiplicities of the infinitely near
+             point corresponding to one further blow up for each branch.
+KEYWORDS:    total multiplicities; multiplicity sequence; resolution graph
+EXAMPLE:     example extend_multiplicities;   shows an example
+"
+{
+  intmat resgr,tm,mt=rg[1],rg[2],rg[3];
+  int i,j;
+  for (i=1;i<=nrows(resgr);i++)
+  {
+    if (resgr[i,i]<0)
+    {
+      j=1;
+      while ((resgr[i,j]==0) or (i==j))
+      {
+        j++;
+      }
+      tm[i,1..ncols(tm)]=tm[j,1..ncols(tm)];
+      tm[i,-resgr[i,i]]=tm[i,-resgr[i,i]]+1;
+      mt[i,-resgr[i,i]]=1;
+    }
+  }
+  return(list(tm,mt));
+}
+example
+{
+  "EXAMPLE:";
+  echo=2;
+  ring r=0,(x,y),ls;
+  poly f1=(y2-x3)^2-4x5y-x7;
+  poly f2=y2-x3;
+  poly f3=y3-x2;
+  // Calculate the resolution graph and the (total) multiplicities of f1*f2*f3.
+  list RESGR=totalmultiplicities(f1*f2*f3);
+  // Extend the (total) multiplicities.
+  list MULT=extend_multiplicities(RESGR);
+  // Compare the total multiplicities.
+  RESGR[2];
+  MULT[1];
+  // Compare the multiplicities.
+  RESGR[3];
+  MULT[2];
+}
+
+proc intmat_inverse (intmat M)
+"USAGE:      intmat_inverse(M); intmat M
+ASSUME:      M is a lower triangular integer matrix with diagonal entries 1 or -1
+RETURN:      intmat, the inverse of M
+KEYWORDS:    integer matrix, inverse
+EXAMPLE:     example intmat_inverse;   shows an example
+"
+{
+  int i,j,k;
+  int n=nrows(M);
+  intmat U[n][n];
+  U=U+1;
+  for (i=1;i<=n;i++)
+  {
+    if (M[i,i]==-1)
+    {
+      M=addmultiplrows(M,i,i,-1,0);
+      U=addmultiplrows(U,i,i,-1,0);
+    }
+    for (j=i+1;j<=n;j++)
+    {
+      U=addmultiplrows(U,i,j,-M[j,i],M[i,i]);
+      M=addmultiplrows(M,i,j,-M[j,i],M[i,i]);
+    }
+  }
+  return(U);
+}
+example
+{
+  "EXAMPLE:";echo=2;
+  intmat M[5][5]=1,0,0,0,0,1,1,0,0,0,2,1,1,0,0,3,1,1,1,0,4,1,1,1,1 ;
+  intmat U=intmat_inverse(M);
+  print(U);
+  print(U*M);
+}
diff --git a/Singular/LIB/algebra.lib b/Singular/LIB/algebra.lib
new file mode 100644
index 0000000..2074f2c
--- /dev/null
+++ b/Singular/LIB/algebra.lib
@@ -0,0 +1,1123 @@
+///////////////////////////////////////////////////////////////////////////////
+version="version algebra.lib 4.0.1.1 Dec_2014 "; // $Id: 2bb3191198fbd2218ed724a0340d9b6d804e14b8 $
+category="Commutative Algebra";
+info="
+LIBRARY:  algebra.lib   Compute with Algbras and Algebra Maps
+AUTHORS:  Gert-Martin Greuel,     greuel at mathematik.uni-kl.de,
+@*        Agnes Eileen Heydtmann, agnes at math.uni-sb.de,
+@*        Gerhard Pfister,        pfister at mathematik.uni-kl.de
+
+PROCEDURES:
+ algebra_containment(); query of algebra containment
+ module_containment();  query of module containment over a subalgebra
+ inSubring(p,I);        test whether polynomial p is in subring generated by I
+ algDependent(I);       computes algebraic relations between generators of I
+ alg_kernel(phi);       computes the kernel of the ringmap phi
+ is_injective(phi);     test for injectivity of ringmap phi
+ is_surjective(phi);    test for surjectivity of ringmap phi
+ is_bijective(phi);     test for bijectivity of ring map phi
+ noetherNormal(id);     noether normalization of ideal id
+ mapIsFinite(R,phi,I);  query for finiteness of map phi:R --> basering/I
+
+ finitenessTest(i,z);   find variables which occur as pure power in lead(i)
+ nonZeroEntry(id);      list describing non-zero entries of an identifier
+";
+
+ LIB "inout.lib";
+ LIB "elim.lib";
+ LIB "ring.lib";
+ LIB "matrix.lib";
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc algebra_containment (poly p, ideal A, list #)
+"USAGE:   algebra_containment(p,A[,k]); p poly, A ideal, k integer.
+@*       A = A[1],...,A[m] generators of subalgebra of the basering
+RETURN:
+ at format
+         - k=0 (or if k is not given) an integer:
+           1  : if p is contained in the subalgebra K[A[1],...,A[m]]
+           0  : if p is not contained in K[A[1],...,A[m]]
+         - k=1 : a list, say l, of size 2, l[1] integer, l[2] ring, satisfying
+           l[1]=1 if p is in the subalgebra K[A[1],...,A[m]] and then the ring
+           l[2]: ring, contains poly check = h(y(1),...,y(m)) if p=h(A[1],...,A[m])
+           l[1]=0 if p is not in the subalgebra K[A[1],...,A[m]] and then
+           l[2] contains the poly check = h(x,y(1),...,y(m)) if p satisfies
+           the nonlinear relation p = h(x,A[1],...,A[m]) where
+           x = x(1),...,x(n) denote the variables of the basering
+ at end format
+DISPLAY: if k=0 and printlevel >= voice+1 (default) display the polynomial check
+NOTE:    The proc inSubring uses a different algorithm which is sometimes
+         faster.
+THEORY:  The ideal of algebraic relations of the algebra generators A[1],...,
+         A[m] is computed introducing new variables y(i) and the product
+         order with x(i) >> y(i).
+         p reduces to a polynomial only in the y(i) <=> p is contained in the
+         subring generated by the polynomials A[1],...,A[m].
+EXAMPLE: example algebra_containment; shows an example
+"
+{ int DEGB = degBound;
+  degBound = 0;
+    if (size(#)==0)
+    { #[1] = 0;
+    }
+    def br=basering;
+    int n = nvars(br);
+    int m = ncols(A);
+    int i;
+    string mp=string(minpoly);
+    //-----------------
+    // neu CL 10/05:
+    int is_qring;
+    if (size(ideal(br))>0) {
+      is_qring=1;
+      ideal IdQ = ideal(br);
+    }
+    //-----------------
+    // ---------- create new ring with extra variables --------------------
+    execute ("ring R=("+charstr(br)+"),(x(1..n),y(1..m)),(dp(n),dp(m));");
+    if (mp!="0")
+    { execute ("minpoly=number("+mp+");"); }
+    ideal vars=x(1..n);
+    map emb=br,vars;
+    ideal A=ideal(emb(A));
+    poly check=emb(p);
+    for (i=1;i<=m;i=i+1)
+    { A[i]=A[i]-y(i);
+    }
+    //-----------------
+    // neu CL 10/05:
+    if (is_qring) { A = A,emb(IdQ); }
+    //-----------------
+    A=std(A);
+    check=reduce(check,A);
+    /*alternatively we could use reduce(check,A,1) which is a little faster
+      but result is bigger since it is not tail-reduced
+    */
+  //--- checking whether all variables from old ring have disappeared ------
+  // if so, then the sum of the first n leading exponents is 0, hence i=1
+  // use i also to control the display
+    i = (sum(leadexp(check),1..n)==0);
+  degBound = DEGB;
+    if( #[1] == 0 )
+    { dbprint(printlevel-voice+3,"// "+string(check));
+      return(i);
+    }
+    else
+    { list l = i,R;
+      kill A,vars,emb;
+      export check;
+      dbprint(printlevel-voice+3,"
+// 'algebra_containment' created a ring as 2nd element of the list.
+// The ring contains the polynomial check which defines the algebraic relation.
+// To access to the ring and see check you must give the ring a name,
+// e.g.:
+               def S = l[2]; setring S; check;
+        ");
+     setring br;
+     return(l);
+    }
+}
+example
+{ "EXAMPLE: Sturmfels: Algorithms in Invariant Theory 2.3.7:"; echo=2;
+   int p = printlevel; printlevel = 1;
+   ring R = 0,(x,y,z),dp;
+   ideal A=x2+y2,z2,x4+y4,1,x2z-1y2z,xyz,x3y-1xy3;
+   poly p1=z;
+   poly p2=
+   x10z3-x8y2z3+2x6y4z3-2x4y6z3+x2y8z3-y10z3+x6z4+3x4y2z4+3x2y4z4+y6z4;
+   algebra_containment(p1,A);
+   algebra_containment(p2,A);
+   list L = algebra_containment(p2,A,1);
+   L[1];
+   def S = L[2]; setring S;
+   check;
+   printlevel = p;
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc module_containment(poly p, ideal P, ideal S, list #)
+"USAGE:   module_containment(p,P,M[,k]); p poly, P ideal, M ideal, k int
+@*       P = P[1],...,P[n] generators of a subalgebra of the basering,
+@*       M = M[1],...,M[m] generators of a module over the subalgebra K[P]
+ASSUME:  ncols(P) = nvars(basering), the P[i] are algebraically independent
+RETURN:
+ at format
+         - k=0 (or if k is not given), an integer:
+           1    : if p is contained in the module <M[1],...,M[m]> over K[P]
+           0    : if p is not contained in <M[1],...,M[m]>
+         - k=1, a list, say l, of size 2, l[1] integer, l[2] ring:
+           l[1]=1 : if p is in <M[1],...,M[m]> and then the ring l[2] contains
+             the polynomial check = h(y(1),...,y(m),z(1),...,z(n)) if
+             p = h(M[1],...,M[m],P[1],...,P[n])
+           l[1]=0 : if p is in not in <M[1],...,M[m]>, then l[2] contains the
+             poly check = h(x,y(1),...,y(m),z(1),...,z(n)) if p satisfies
+             the nonlinear relation p = h(x,M[1],...,M[m],P[1],...,P[n]) where
+             x = x(1),...,x(n) denote the variables of the basering
+ at end format
+DISPLAY: the polynomial h(y(1),...,y(m),z(1),...,z(n)) if k=0, resp.
+         a comment how to access the relation check if k=1, provided
+         printlevel >= voice+1 (default).
+THEORY:  The ideal of algebraic relations of all the generators p1,...,pn,
+         s1,...,st given by P and S is computed introducing new variables y(j),
+         z(i) and the product order: x^a*y^b*z^c > x^d*y^e*z^f if x^a > x^d
+         with respect to the lp ordering or else if z^c > z^f with respect to
+         the dp ordering or else if y^b > y^e with respect to the lp ordering
+         again. p reduces to a polynomial only in the y(j) and z(i), linear in
+         the z(i) <=> p is contained in the module.
+EXAMPLE: example module_containment; shows an example
+"
+{ def br=basering;
+  int DEGB = degBound;
+  degBound=0;
+  if (size(#)==0)
+  { #[1] = 0;
+  }
+  int n=nvars(br);
+  if ( ncols(P)==n )
+  { int m=ncols(S);
+    string mp=string(minpoly);
+  // ---------- create new ring with extra variables --------------------
+    execute
+   ("ring R=("+charstr(br)+"),(x(1..n),y(1..m),z(1..n)),(lp(n),dp(m),lp(n));");
+    if (mp!="0")
+    { execute ("minpoly=number("+mp+");"); }
+    ideal vars = x(1..n);
+    map emb = br,vars;
+    ideal P = emb(P);
+    ideal S  = emb(S);
+    poly check = emb(p);
+    ideal I;
+    for (int i=1;i<=m;i=i+1)
+    { I[i]=S[i]-y(i);
+    }
+    for (i=1;i<=n;i=i+1)
+    { I[m+i]=P[i]-z(i);
+    }
+    I=std(I);
+    check = reduce(check,I);
+  //--- checking whether all variables from old ring have disappeared ------
+  // if so, then the sum of the first n leading exponents is 0
+    i = (sum(leadexp(check),1..n)==0);
+    if( #[1] == 0 )
+    { dbprint(i*(printlevel-voice+3),"// "+string(check));
+      setring br;
+      return(i);
+    }
+    else
+    { list l = i,R;
+      kill I,vars,emb,P,S;
+      export check;
+      dbprint(printlevel-voice+3,"
+// 'module_containment' created a ring as 2nd element of the list. The
+// ring contains the polynomial check which defines the algebraic relation
+// for p. To access to the ring and see check you must give the ring
+// a name, e.g.:
+     def S = l[2]; setring S; check;
+      ");
+      setring br;
+      return(l);
+    }
+  }
+  else
+  {
+      setring br;
+    "ERROR: the first ideal must have nvars(basering) entries";
+    return();
+  }
+}
+example
+{ "EXAMPLE: Sturmfels: Algorithms in Invariant Theory 2.3.7:"; echo=2;
+   int p = printlevel; printlevel = 1;
+   ring R=0,(x,y,z),dp;
+   ideal P = x2+y2,z2,x4+y4;           //algebra generators
+   ideal M = 1,x2z-1y2z,xyz,x3y-1xy3;  //module generators
+   poly p1=
+   x10z3-x8y2z3+2x6y4z3-2x4y6z3+x2y8z3-y10z3+x6z4+3x4y2z4+3x2y4z4+y6z4;
+   module_containment(p1,P,M);
+   poly p2=z;
+   list l = module_containment(p2,P,M,1);
+   l[1];
+   def S = l[2]; setring S; check;
+   printlevel=p;
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc inSubring(poly p, ideal I)
+"USAGE:   inSubring(p,i); p poly, i ideal
+RETURN:
+ at format
+         a list l of size 2, l[1] integer, l[2] string
+         l[1]=1 if and only if p is in the subring generated by i=i[1],...,i[k],
+                and then l[2] = y(0)-h(y(1),...,y(k)) if p = h(i[1],...,i[k])
+         l[1]=0 if and only if p is in not the subring generated by i,
+                and then l[2] = h(y(0),y(1),...,y(k)) where p satisfies the
+                nonlinear relation h(p,i[1],...,i[k])=0.
+ at end format
+NOTE:    the proc algebra_containment tests the same using a different
+         algorithm, which is often faster
+         if l[1] == 0 then l[2] may contain more than one relation h(y(0),y(1),...,y(k)),
+         separated by comma
+EXAMPLE: example inSubring; shows an example
+"
+{int z=ncols(I);
+  int i;
+  def gnir=basering;
+  int n = nvars(gnir);
+  string mp=string(minpoly);
+  list l;
+  // neu CL 10/05:
+  int is_qring;
+  if (size(ideal(gnir))>0)
+  {
+    is_qring=1;
+    ideal IdQ = ideal(gnir);
+  }
+  // ---------- create new ring with extra variables --------------------
+  //the intersection of ideal nett=(p-y(0),I[1]-y(1),...)
+  //with the ring k[y(0),...,y(n)] is computed, the result is ker
+   execute ("ring r1= ("+charstr(basering)+"),(x(1..n),y(0..z)),lp;");
+ //  execute ("ring r1= ("+charstr(basering)+"),(y(0..z),x(1..n)),dp;");
+  if (mp!="0")
+  { execute ("minpoly=number("+mp+");"); }
+  ideal va = x(1..n);
+  map emb = gnir,va;
+  ideal nett = emb(I);
+  for (i=1;i<=z;i++)
+  { nett[i]=nett[i]-y(i);
+  }
+  nett=emb(p)-y(0),nett;
+  // neu CL 10/05:
+  if (is_qring) { nett = nett,emb(IdQ); }
+  //-----------------
+  ideal ker=eliminate(nett,product(va));
+  ker=std(ker);
+  //---------- test wether y(0)-h(y(1),...,y(z)) is in ker --------------
+  l[1]=0;
+  l[2]="";
+  for (i=1;i<=size(ker);i++)
+  { if (deg(ker[i]/y(0))==0)
+     { string str=string(ker[i]);
+        setring gnir;
+        l[1]=1;
+        l[2]=str;
+        return(l);
+     }
+     if (deg(ker[i]/y(0))>0)
+     { if( l[2] != "" ){ l[2] = l[2] + ","; }
+       l[2] = l[2] + string(ker[i]);
+     }
+  }
+  setring gnir;
+  return(l);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring q=0,(x,y,z,u,v,w),dp;
+   poly p=xyzu2w-1yzu2w2+u4w2-1xu2vw+u2vw2+xyz-1yzw+2u2w-1xv+vw+2;
+   ideal I =x-w,u2w+1,yz-v;
+   inSubring(p,I);
+}
+//////////////////////////////////////////////////////////////////////////////
+
+proc algDependent( ideal A, list # )
+"USAGE:   algDependent(f[,c]); f ideal (say, f = f1,...,fm), c integer
+RETURN:
+ at format
+         a list l  of size 2, l[1] integer, l[2] ring:
+         - l[1] = 1 if f1,...,fm are algebraic dependent, 0 if not
+         - l[2] is a ring with variables x(1),...,x(n),y(1),...,y(m) if the
+           basering has n variables. It contains the ideal 'ker', depending
+           only on the y(i) and generating the algebraic relations between the
+           f[i], i.e. substituting y(i) by fi yields 0. Of course, ker is
+           nothing but the kernel of the ring map
+              K[y(1),...,y(m)] ---> basering,  y(i) --> fi.
+ at end format
+NOTE:    Three different algorithms are used depending on c = 1,2,3.
+         If c is not given or c=0, a heuristically best method is chosen.
+         The basering may be a quotient ring.
+         To access to the ring l[2] and see ker you must give the ring a name,
+         e.g. def S=l[2]; setring S; ker;
+DISPLAY: The above comment is displayed if printlevel >= 0 (default).
+EXAMPLE: example algDependent; shows an example
+"
+{
+    int bestoption = 3;
+    // bestoption is the default algorithm, it may be set to 1,2 or 3;
+    // it should be changed, if another algorithm turns out to be faster
+    // in general. Is perhaps dependent on the input (# vars, size ...)
+    int tt;
+    if( size(#) > 0 )
+    { if( typeof(#[1]) == "int" )
+      { tt = #[1];
+      }
+    }
+    if( size(#) == 0 or tt == 0 )
+    { tt = bestoption;
+    }
+    def br=basering;
+    int n = nvars(br);
+    ideal B = ideal(br);
+    int m = ncols(A);
+    int s = size(B);
+    int i;
+    string mp = string(minpoly);
+ // --------------------- 1st variant of algorithm ----------------------
+ // use internal preimage command (should be equivalent to 2nd variant)
+    if ( tt == 1 )
+    {
+      execute ("ring R1=("+charstr(br)+"),y(1..m),dp;");
+      if (mp!="0")
+      { execute ("minpoly=number("+mp+");"); }
+      setring br;
+      map phi = R1,A;
+      setring R1;
+      ideal ker = preimage(br,phi,B);
+    }
+ // ---------- create new ring with extra variables --------------------
+    execute ("ring R2=("+charstr(br)+"),(x(1..n),y(1..m)),(dp);");
+    if (mp!="0")
+    { execute ("minpoly=number("+mp+");"); }
+    if( tt == 1 )
+    {
+      ideal ker = imap(R1,ker);
+    }
+    else
+    {
+      ideal vars = x(1..n);
+      map emb = br,vars;
+      ideal A = emb(A);
+      for (i=1; i<=m; i=i+1)
+      { A[i] = A[i]-y(i);
+      }
+ // --------------------- 2nd variant of algorithm ----------------------
+ // use internal eliminate for eliminating m variables x(i) from
+ // ideal A[i] - y(i) (uses extra eliminating 'first row', a-order)
+      if ( s == 0 and  tt == 2  )
+      { ideal ker = eliminate(A,product(vars));
+      }
+      else
+ // eliminate does not work in qrings
+ // --------------------- 3rd variant of algorithm ----------------------
+ // eliminate m variables x(i) from ideal A[i] - y(i) by choosing product
+ // order
+       {execute ("ring R3=("+charstr(br)+"),(x(1..n),y(1..m)),(dp(n),dp(m));");
+        if (mp!="0")
+        { execute ("minpoly=number("+mp+");"); }
+        if ( s != 0 )
+        { ideal vars = x(1..n);
+          map emb = br,vars;
+          ideal B = emb(B);
+          attrib(B,"isSB",1);
+          qring Q = B;
+        }
+        ideal A = imap(R2,A);
+        A = std(A);
+        ideal ker = nselect(A,1..n);
+        setring R2;
+        if ( defined(Q)==voice )
+        { ideal ker = imap(Q,ker);
+        }
+        else
+        { ideal ker = imap(R3,ker);
+        }
+        kill A,emb,vars;
+      }
+    }
+ // --------------------------- return ----------------------------------
+    s = size(ker);
+    list L = (s!=0), R2;
+    export(ker);
+    dbprint(printlevel-voice+3,"
+// The 2nd element of the list l is a ring with variables x(1),...,x(n),
+// and y(1),...,y(m) if the basering has n variables and if the ideal
+// is f[1],...,f[m]. The ring contains the ideal ker which depends only
+// on the y(i) and generates the relations between the f[i].
+// I.e. substituting y(i) by f[i] yields 0.
+// To access to the ring and see ker you must give the ring a name,
+// e.g.:
+             def S = l[2]; setring S; ker;
+        ");
+    setring br;
+    return (L);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   int p = printlevel; printlevel = 1;
+   ring R = 0,(x,y,z,u,v,w),dp;
+   ideal I = xyzu2w-1yzu2w2+u4w2-1xu2vw+u2vw2+xyz-1yzw+2u2w-1xv+vw+2,
+             x-w, u2w+1, yz-v;
+   list l = algDependent(I);
+   l[1];
+   def S = l[2]; setring S;
+   ker;
+   printlevel = p;
+}
+//////////////////////////////////////////////////////////////////////////////
+proc alg_kernel( map phi, def pr, list #)
+"USAGE:   alg_kernel(phi,pr[,s,c]); phi map to basering, pr preimage ring,
+         s string (name of kernel in pr), c integer.
+RETURN:  a string, the kernel of phi as string.
+         If, moreover, a string s is given, the algorithm creates, in the
+         preimage ring pr the kernel of phi with name s.
+         Three different algorithms are used depending on c = 1,2,3.
+         If c is not given or c=0, a heuristically best method is chosen.
+         (algorithm 1 uses the preimage command)
+NOTE:    Since the kernel of phi lives in pr, it cannot be returned to the
+         basering. If s is given, the user has access to it in pr via s.
+         The basering may be a quotient ring.
+EXAMPLE: example alg_kernel; shows an example
+"
+{   int tt;
+   def BAS = basering;
+   if( size(#) >0 )
+   { if( typeof(#[1]) == "int")
+     { tt = #[1];
+     }
+     if( typeof(#[1]) == "string")
+     { string nker=#[1];
+     }
+     if( size(#)>1 )
+     {  if( typeof(#[2]) == "string")
+        { string nker=#[2];
+        }
+        if( typeof(#[2]) == "int")
+       {  tt = #[2];
+       }
+     }
+   }
+    int n = nvars(basering);
+    string mp = string(minpoly);
+    ideal A = ideal(phi);
+    //def pr = preimage(phi);
+    //folgendes Auffuellen oder Stutzen ist ev nicht mehr noetig
+    //falls map das richtig macht
+    int m = nvars(pr);
+    ideal j;
+    j[m]=0;
+    A=A,j;
+    A=A[1..m];
+    list L = algDependent(A,tt);
+    // algDependent is called with "bestoption" if tt = 0
+    def S = L[2];
+    execute ("ring R=("+charstr(basering)+"),(@(1..n),"+varstr(pr)+"),(dp);");
+    if (mp!="0")
+    { execute ("minpoly=number("+mp+");"); }
+    ideal ker = fetch(S,ker);       //in order to have variable names correct
+    string sker = string(ker);
+    if (defined(nker) == voice)
+    { setring pr;
+      execute("ideal "+nker+"="+sker+";");
+      execute("export("+nker+");");
+     }
+    setring BAS;
+    return(sker);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r = 0,(a,b,c),ds;
+   ring s = 0,(x,y,z,u,v,w),dp;
+   ideal I = x-w,u2w+1,yz-v;
+   map phi = r,I;                // a map from r to s:
+   alg_kernel(phi,r);            // a,b,c ---> x-w,u2w+1,yz-v
+
+   ring S = 0,(a,b,c),ds;
+   ring R = 0,(x,y,z),dp;
+   qring Q = std(x-y);
+   ideal i = x, y, x2-y3;
+   map phi = S,i;                 // a map to a quotient ring
+   alg_kernel(phi,S,"ker",3);     // uses algorithm 3
+   setring S;                     // you have access to kernel in preimage
+   ker;
+}
+//////////////////////////////////////////////////////////////////////////////
+
+proc is_injective( map phi,def pr,list #)
+"USAGE:   is_injective(phi,pr[,c,s]); phi map, pr preimage ring, c int, s string
+RETURN:
+ at format
+         - 1 (type int) if phi is injective, 0 if not (if s is not given).
+         - If s is given, return a list l of size 2, l[1] int, l[2] ring:
+           l[1] is 1 if phi is injective, 0 if not
+           l[2] is a ring with variables x(1),...,x(n),y(1),...,y(m) if the
+           basering has n variables and the map m components, it contains the
+           ideal 'ker', depending only on the y(i), the kernel of the given map
+ at end format
+NOTE:    Three differnt algorithms are used depending on c = 1,2,3.
+         If c is not given or c=0, a heuristically best method is chosen.
+         The basering may be a quotient ring. However, if the preimage ring is
+         a quotient ring, say pr = P/I, consider phi as a map from P and then
+         the algorithm returns 1 if the kernel of phi is 0 mod I.
+         To access to the ring l[2] and see ker you must give the ring a name,
+         e.g. def S=l[2]; setring S; ker;
+DISPLAY: The above comment is displayed if printlevel >= 0 (default).
+EXAMPLE: example is_injective; shows an example
+"
+{  def bsr = basering;
+   int tt;
+   if( size(#) >0 )
+   { if( typeof(#[1]) == "int")
+     { tt = #[1];
+     }
+     if( typeof(#[1]) == "string")
+     { string pau=#[1];
+     }
+     if( size(#)>1 )
+     {  if( typeof(#[2]) == "string")
+        { string pau=#[2];
+        }
+        if( typeof(#[2]) == "int")
+       {  tt = #[2];
+       }
+     }
+   }
+    int n = nvars(basering);
+    string mp = string(minpoly);
+    ideal A = ideal(phi);
+    //def pr = preimage(phi);
+    //folgendes Auffuellen oder Stutzen ist ev nicht mehr noetig
+    //falls map das richtig macht
+    int m = nvars(pr);
+    ideal j;
+    j[m]=0;
+    A=A,j;
+    A=A[1..m];
+    list L = algDependent(A,tt);
+    L[1] = L[1]==0;
+// the preimage ring may be a quotient ring, we still have to check whether
+// the kernel is 0 mod ideal of the quotient ring
+    setring pr;
+    if ( size(ideal(pr)) != 0 )
+    { def S = L[2];
+      ideal proj;
+      proj [n+1..n+m] = maxideal(1);
+      map psi = S,proj;
+      L[1] = size(NF(psi(ker),std(0))) == 0;
+    }
+    setring bsr;
+    if ( defined(pau) != voice )
+    {  return (L[1]);
+    }
+    else
+    {
+      dbprint(printlevel-voice+3,"
+// The 2nd element of the list is a ring with variables x(1),...,x(n),
+// y(1),...,y(m) if the basering has n variables and the map is
+// F[1],...,F[m].
+// It contains the ideal ker, the kernel of the given map y(i) --> F[i].
+// To access to the ring and see ker you must give the ring a name,
+// e.g.:
+     def S = l[2]; setring S; ker;
+        ");
+      return(L);
+    }
+ }
+example
+{ "EXAMPLE:"; echo = 2;
+   int p = printlevel;
+   ring r = 0,(a,b,c),ds;
+   ring s = 0,(x,y,z,u,v,w),dp;
+   ideal I = x-w,u2w+1,yz-v;
+   map phi = r,I;                    // a map from r to s:
+   is_injective(phi,r);              // a,b,c ---> x-w,u2w+1,yz-v
+   ring R = 0,(x,y,z),dp;
+   ideal i = x, y, x2-y3;
+   map phi = R,i;                    // a map from R to itself, z --> x2-y3
+   list l = is_injective(phi,R,"");
+   l[1];
+   def S = l[2]; setring S;
+   ker;
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc is_surjective( map phi )
+"USAGE:   is_surjective(phi); phi map to basering, or ideal defining it
+RETURN:  an integer,  1 if phi is surjective, 0 if not
+NOTE:    The algorithm returns 1 if and only if all the variables of the basering are
+         contained in the polynomial subalgebra generated by the polynomials
+         defining phi. Hence, it tests surjectivity in the case of a global odering.
+         If the basering has local or mixed ordering or if the preimage ring is a
+         quotient ring (in which case the map may not be well defined) then the return
+         value 1 needs to be interpreted with care.
+EXAMPLE: example is_surjective; shows an example
+"
+{
+  def br=basering;
+    ideal B = ideal(br);
+    int s = size(B);
+    int n = nvars(br);
+    ideal A = ideal(phi);
+    int m = ncols(A);
+    int ii,t=1,1;
+    string mp=string(minpoly);
+  // ------------ create new ring with extra variables ---------------------
+    execute ("ring R=("+charstr(br)+"),(x(1..n),y(1..m)),(dp(n),dp(m));");
+    if (mp!="0")
+    { execute ("minpoly=number("+mp+");"); }
+    ideal vars = x(1..n);
+    map emb = br,vars;
+    if ( s != 0 )
+    {  ideal B = emb(B);
+       attrib(B,"isSB",1);
+       qring Q = B;
+       ideal vars = x(1..n);
+       map emb = br,vars;
+    }
+    ideal A = emb(A);
+    for ( ii=1; ii<=m; ii++ )
+    { A[ii] = A [ii]-y(ii);
+    }
+    A=std(A);
+  // ------------- check whether the x(i) are in the image -----------------
+    poly check;
+    for (ii=1; ii<=n; ii++ )
+    {  check=reduce(x(ii),A,1);
+  // --- checking whether all variables from old ring have disappeared -----
+  // if so, then the sum of the first n leading exponents is 0
+       if( sum(leadexp(check),1..n)!=0 )
+       { t=0;
+         break;
+       }
+    }
+   setring br;
+   return(t);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring R = 0,(x,y,z),dp;
+   ideal i = x, y, x2-y3;
+   map phi = R,i;                    // a map from R to itself, z->x2-y3
+   is_surjective(phi);
+   qring Q = std(ideal(z-x37));
+   map psi = R, x,y,x2-y3;           // the same map to the quotient ring
+   is_surjective(psi);
+
+   ring S = 0,(a,b,c),dp;
+   map psi = R,ideal(a,a+b,c-a2+b3); // a map from R to S,
+   is_surjective(psi);               // x->a, y->a+b, z->c-a2+b3
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc is_bijective ( map phi,def pr )
+"USAGE:   is_bijective(phi,pr); phi map to basering, pr preimage ring
+RETURN:  an integer,  1 if phi is bijective, 0 if not
+NOTE:    The algorithm checks first injectivity and then surjectivity.
+         To interprete this for local/mixed orderings, or for quotient rings
+         type help is_surjective; and help is_injective;
+DISPLAY: A comment if printlevel >= voice-1 (default)
+EXAMPLE: example is_bijective; shows an example
+"
+{
+  def br = basering;
+    int n = nvars(br);
+    ideal B = ideal(br);
+    int s = size(B);
+    ideal A = ideal(phi);
+    //folgendes Auffuellen oder Stutzen ist ev nicht mehr noetig
+    //falls map das richtig macht
+    int m = nvars(pr);
+    ideal j;
+    j[m]=0;
+    A=A,j;
+    A=A[1..m];
+    int ii,t = 1,1;
+    string mp=string(minpoly);
+  // ------------ create new ring with extra variables ---------------------
+    execute ("ring R=("+charstr(br)+"),(x(1..n),y(1..m)),(dp(n),dp(m));");
+    if (mp!="0")
+    { execute ("minpoly=number("+mp+");"); }
+    ideal vars = x(1..n);
+    map emb = br,vars;
+    if ( s != 0 )
+    {  ideal B = emb(B);
+       attrib(B,"isSB",1);
+       qring Q = B;
+       ideal vars = x(1..n);
+       map emb = br,vars;
+    }
+    ideal A = emb(A);
+    for ( ii=1; ii<=m; ii++ )
+    { A[ii] = A[ii]-y(ii);
+    }
+    A=std(A);
+    def bsr = basering;
+ // ------- checking whether phi is injective by computing the kernel -------
+    ideal ker = nselect(A,1..n);
+    t = size(ker);
+    setring pr;
+    if ( size(ideal(pr)) != 0 )
+    {
+      ideal proj;
+      proj[n+1..n+m] = maxideal(1);
+      map psi = bsr,proj;
+      t = size(NF(psi(ker),std(0)));
+    }
+    if ( t != 0 )
+    {  dbprint(printlevel-voice+3,"// map not injective" );
+      setring br;
+      return(0);
+    }
+   else
+ // -------------- checking whether phi is surjective ----------------------
+   { t = 1;
+     setring bsr;
+     poly check;
+     for (ii=1; ii<=n; ii++ )
+     {  check=reduce(x(ii),A,1);
+  // --- checking whether all variables from old ring have disappeared -----
+  // if so, then the sum of the first n leading exponents is 0
+        if( sum(leadexp(check),1..n)!=0 )
+        { t=0;
+          break;
+        }
+     }
+     if ( t == 0 )
+     {  dbprint(printlevel-voice+3,"// map injective, but not surjective" );
+     }
+     setring br;
+     return(t);
+   }
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   int p = printlevel;  printlevel = 1;
+   ring R = 0,(x,y,z),dp;
+   ideal i = x, y, x2-y3;
+   map phi = R,i;                      // a map from R to itself, z->x2-y3
+   is_bijective(phi,R);
+   qring Q = std(z-x2+y3);
+   is_bijective(ideal(x,y,x2-y3),Q);
+
+   ring S = 0,(a,b,c,d),dp;
+   map psi = R,ideal(a,a+b,c-a2+b3,0); // a map from R to S,
+   is_bijective(psi,R);                // x->a, y->a+b, z->c-a2+b3
+   qring T = std(d,c-a2+b3);
+   map chi = Q,a,b,a2-b3;              // amap between two quotient rings
+   is_bijective(chi,Q);
+
+   printlevel = p;
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc noetherNormal(ideal i, list #)
+"USAGE:   noetherNormal(id[,p]);  id ideal, p integer
+RETURN:
+ at format
+         a list l of two ideals, say I,J:
+         - I defines a map (coordinate change in the basering), such that:
+         - J is generated by a subset of the variables with size(J) = dim(id)
+           if we define  map phi=basering,I;
+           then k[var(1),...,var(n)]/phi(id) is finite over k[J].
+         If p is given, 0<=p<=100, a sparse coordinate change with p percent
+         of the matrix entries being 0 (default: p=0 i.e. dense)
+ at end format
+NOTE:    Designed for characteristic 0.It works also in char k > 0 if it
+         terminates,but may result in an infinite loop in small characteristic.
+EXAMPLE: example noetherNormal; shows an example
+"
+{
+   i=simplify(i,2);
+   if ( i== 0)
+   {
+     list l = maxideal(1),maxideal(1);
+     return( l );
+   }
+   int p;
+   if( size(#) != 0 )
+   {
+     p = #[1];
+   }
+   def r = basering;
+   int n = nvars(r);
+   list good;
+   // ------------------------ change of ordering ---------------------------
+   //a procedure from ring.lib changing the order to dp creating a new
+   //basering @R in order to compute the dimension d of i
+   def @R=changeord(list(list("dp",1:nvars(basering))));
+   setring @R;
+   ideal i = imap(r,i);
+   list j = mstd(i);
+   i = j[2];
+   int d = dim(j[1]);
+   if ( d <= 0)
+   {
+     setring r;
+     list l = maxideal(1),ideal(0);
+     return( l );
+   }
+   // ------------------------ change of ordering ---------------------------
+   //Now change the order to (dp(n-d),lp) creating a new basering @S
+   def @S=changeord(list(list("dp",1:(n-d)),list("lp",1:d)));
+   setring @S;
+   ideal m;
+
+   // ----------------- sparse-random coordinate change  --------------------
+   //creating lower triangular random generators for the maximal ideal
+   //a procedure from random.lib, as sparse as possible
+   if(  char(@S) >  0 )
+   {
+      m=ideal(sparsetriag(n,n,p,char(@S)+1)*transpose(maxideal(1)));
+   }
+   if(  char(@S) == 0 )
+   {
+      if ( voice <= 6 )
+      {
+        m=ideal(sparsetriag(n,n,p,10)*transpose(maxideal(1)));
+      }
+     if( voice > 6 and voice <= 11)
+     {
+        m=ideal(sparsetriag(n,n,p,100)*transpose(maxideal(1)));
+      }
+      if ( voice > 11 )
+      {
+        m=ideal(sparsetriag(n,n,p,30000)*transpose(maxideal(1)));
+      }
+   }
+
+   map phi=r,m;
+   //map phi=@R,m;
+   ideal i=std(phi(i));
+
+   // ----------------------- test for finiteness ---------------------------
+   //We need a test whether the coordinate change was random enough, if yes
+   //we are ready, else call noetherNormal again
+   list l=finitenessTest(i);
+
+   setring r;
+   list l=imap(@S,l);
+
+   if(size(l[3]) == d)                    //the generic case
+   {
+      good = fetch(@S,m),l[3];
+      kill @S, at R;
+      return(good);
+   }
+   else                                   //the bad case
+   { kill @S, at R;
+      if ( voice >= 21 )
+      {
+       "// WARNING: In case of a finite ground field";
+       "// the characteristic may be too small.";
+       "// This could result in an infinte loop.";
+       "// Loop in noetherNormal, voice:";, voice;"";
+      }
+     if ( voice >= 16 )
+     {
+       "// Switch to dense coordinate change";"";
+       return(noetherNormal(i));
+     }
+     return(noetherNormal(i,p));
+   }
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r=0,(x,y,z),dp;
+   ideal i= xy,xz;
+   noetherNormal(i);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc finitenessTest(ideal i, list #)
+"USAGE:   finitenessTest(J[,v]); J ideal, v intvec (say v1,...,vr with vi>0)
+RETURN:
+ at format
+         a list l with l[1] integer, l[2], l[3], l[4] ideals
+         - l[1] = 1 if var(v1),...,var(vr) are in l[2] and 0 else
+         - l[2] (resp. l[3]) contains those variables which occur,
+           (resp. do not occur) as pure power in the leading term of one of the
+           generators of J,
+         - l[4] contains those J[i] for which the leading term is a pure power
+           of a variable (which is then in l[2])
+         (default: v = [1,2,..,nvars(basering)])
+ at end format
+THEORY:  If J is a standard basis of an ideal generated by x_1 - f_1(y),...,
+         x_n - f_n with y_j ordered lexicographically and y_j >> x_i, then,
+         if y_i appears as pure power in the leading term of J[k], J[k] defines
+         an integral relation for y_i over the y_(i+1),... and the f's.
+         Moreover, in this situation, if l[2] = y_1,...,y_r, then K[y_1,...y_r]
+         is finite over K[f_1..f_n]. If J contains furthermore polynomials
+         h_j(y), then K[y_1,...y_z]/<h_j> is finite over K[f_1..f_n].
+         For a proof cf. Prop. 3.1.5, p. 214. in [G.-M. Greuel, G. Pfister:
+         A SINGULAR Introduction to Commutative Algebra, 2nd Edition,
+         Springer Verlag (2007)]
+EXAMPLE: example finitenessTest; shows an example
+"
+{  int n = nvars(basering);
+   intvec v,w;
+   int j,z,ii;
+   v[n]=0;                             //v should have size n
+   intvec V = 1..n;
+   list nze;                           //the non-zero entries of a leadexp
+   if (size(#) != 0 )
+   {
+     V = #[1];
+   }
+   intmat W[1][n];                     //create intmat with 1 row, having 1 at
+                                       //position V[j], i = 1..size(V), 0 else
+   for( j=1; j<=size(V); j++ )
+   {
+     W[1,V[j]] = 1;
+   }
+   ideal relation,zero,nonzero;
+   // ---------------------- check leading exponents -------------------------
+
+   for(j=1;j<=ncols(i);j++)
+   {
+      w = leadexp(i[j]);
+      nze = nonZeroEntry(w);
+      if( nze[1] == 1 )               //the leading term of i[j] is a
+      {                               //pure power of some variable
+        if( W*w != 0 )                //case: variable has index appearing in V
+        {
+          relation[size(relation)+1] = i[j];
+          v=v+w;
+        }
+      }
+   }
+   // ----------------- pick the corresponding variables ---------------------
+   //the nonzero entries of v correspond to variables which occur as
+   //pure power in the leading term of some polynomial in i
+
+   for(j=1; j<=size(v); j++)
+   {
+      if(v[j]==0)
+      {
+         zero[size(zero)+1]=var(j);
+      }
+      else
+      {
+        nonzero[size(nonzero)+1]=var(j);
+      }
+   }
+   // ---------------- do we have all pure powers we want? -------------------
+   // test this by dividing the product of corresponding variables
+   ideal max = maxideal(1);
+   max = max[V];
+   z = (product(nonzero)/product(max) != 0);
+   return(list(z,nonzero,zero,relation));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring s = 0,(x,y,z,a,b,c),(lp(3),dp);
+   ideal i= a -(xy)^3+x2-z, b -y2-1, c -z3;
+   ideal j = a -(xy)^3+x2-z, b -y2-1, c -z3, xy;
+   finitenessTest(std(i),1..3);
+   finitenessTest(std(j),1..3);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc mapIsFinite(map phi,def R, list #)
+"USAGE:   mapIsFinite(phi,R[,J]); R the preimage ring of the map
+         phi: R ---> basering
+         J an ideal in the basering, J = 0 if not given
+RETURN:  1 if R ---> basering/J is finite and 0 else
+NOTE:    R may be a quotient ring (this will be ignored since a map R/I-->S/J
+         is finite if and only if the induced map R-->S/J is finite).
+SEE ALSO: finitenessTest
+EXAMPLE: example mapIsFinite; shows an example
+"
+{
+  def bsr = basering;
+  ideal J;
+  if( size(#) != 0 )
+  {
+    J = #[1];
+  }
+  string os = ordstr(bsr);
+  int m = nvars(bsr);
+  int n = nvars(R);
+  ideal PHI = ideal(phi);
+  if ( ncols(PHI) < n )
+  { PHI[n]=0;
+  }
+  // --------------------- change of variable names -------------------------
+  execute("ring @bsr = ("+charstr(bsr)+"),y(1..m),("+os+");");
+  ideal J = fetch(bsr,J);
+  ideal PHI = fetch(bsr,PHI);
+
+  // --------------------------- enlarging ring -----------------------------
+  execute("ring @rr = ("+charstr(bsr)+"),(y(1..m),x(1..n)),(lp(m),dp);");
+  ideal J = imap(@bsr,J);
+  ideal PHI = imap(@bsr,PHI);
+  ideal M;
+  int i;
+
+  for(i=1;i<=n;i++)
+  {
+    M[i]=x(i)-PHI[i];
+  }
+  M = std(M+J);
+  // ----------------------- test for finiteness ---------------------------
+  list l = finitenessTest(M,1..m);
+  int result = l[1];
+  setring bsr;
+  return( result );
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r = 0,(a,b,c),dp;
+   ring s = 0,(x,y,z),dp;
+   ideal i= xy;
+   map phi= r,(xy)^3+x2+z,y2-1,z3;
+   mapIsFinite(phi,r,i);
+}
+//////////////////////////////////////////////////////////////////////////////
+
+proc nonZeroEntry(def id)
+"USAGE:  nonZeroEntry(id); id=object for which the test 'id[i]!=0', i=1,..,N,
+         N=size(id) (resp. ncols(id) for id of type ideal or module)
+         is defined (e.g. ideal, vector, list of polynomials, intvec,...)
+RETURN:  @format
+         a list, say l, with l[1] an integer, l[2], l[3] integer vectors:
+         - l[1] number of non-zero entries of id
+         - l[2] intvec of size l[1] with l[2][i]=i if id[i] != 0
+           in case l[1]!=0 (and l[2]=0 if l[1]=0)
+         - l[3] intvec with l[3][i]=1 if id[i]!=0 and l[3][i]=0 else
+ at end format
+NOTE:
+EXAMPLE: example nonZeroEntry; shows an example
+"
+{
+   int ii,jj,N,n;
+   intvec v,V;
+
+   if ( typeof(id) == "ideal" || typeof(id) == "module" )
+   {
+      N = ncols(id);
+   }
+   else
+   {
+     N = size(id);
+   }
+   for ( ii=1; ii<=N; ii++ )
+   {
+      V[ii] = 0;
+      if ( id[ii] != 0 )
+      {
+         n++;
+         v=v,ii;      //the first entry of v is always 0
+         V[ii] = 1;
+      }
+   }
+   if ( size(v) > 1 ) //if id[ii] != 0 for at least one ii delete the first 0
+   {
+      v = v[2..size(v)];
+   }
+
+   list l = n,v,V;
+   return(l);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r = 0,(a,b,c),dp;
+   poly f = a3c+b3+c2+a;
+   intvec v = leadexp(f);
+   nonZeroEntry(v);
+
+   intvec w;
+   list L = 37,0,f,v,w;
+   nonZeroEntry(L);
+}
+//////////////////////////////////////////////////////////////////////////////
+
diff --git a/Singular/LIB/algemodstd.lib b/Singular/LIB/algemodstd.lib
new file mode 100644
index 0000000..9be0832
--- /dev/null
+++ b/Singular/LIB/algemodstd.lib
@@ -0,0 +1,484 @@
+////////////////////////////////////////////////////////////////////////////////
+version="version algemodstd.lib 4.0.1.0 Sep_2014 ";  // $Id: 71d2d34587126e65afaad9bea15879724ea1b326 $
+category="Commutative Algebra";
+info="
+
+LIBRARY:   algemodstd.lib  Groebner bases of ideals in polynomial rings
+                           over algebraic number fields
+AUTHORS:   D.K. Boku       boku at mathematik.uni-kl.de
+@*         W. Decker       decker at mathematik.uni-kl.de
+@*         C. Fieker       fieker at mathematik.uni-kl.de
+
+OVERVIEW:
+  A library for computing the Groebner basis of an ideal in the polynomial
+  ring over an algebraic number field Q(t) using the modular methods, where t is
+  algebraic over the field of rational numbers Q. For the case Q(t) = Q, the procedure
+  is inspired by Arnold [1]. This idea is then extended
+  to the case t not in Q using factorization as follows:
+  Let f be the minimal polynomial of t.
+  For I, I' ideals in Q(t)[X], Q[X,t]/<f> respectively, we map I to I' via the map sending
+  t to t + <f>.
+  We first choose a prime p such that f has at least two factors in characteristic p and
+  add each factor f_i to I' to obtain the ideal J'_i = I' + <f_i>.
+  We then compute a standard basis G'_i of J'_i for each i and combine the G'_i to G_p
+  (a standard basis of I'_p) using chinese remaindering for polynomials. The procedure is
+  repeated for many primes p, where we compute the G_p in parallel until the
+  number of primes is sufficiently large to recover the correct standard basis G' of I'.
+  Finally, by mapping G' back to Q(t)[X], a standard basis G of I is obtained.
+
+REFERENCES:
+  [1] E. A. Arnold: Modular algorithms for computing Groebner bases.
+      J. Symb. Comp. 35, 403-419 (2003).
+
+PROCEDURES:
+  chinrempoly(l,m);       chinese remaindering for polynomials
+  algemodStd(I);          standard basis of I over algebraic number field using modular methods
+";
+
+LIB "modstd.lib";
+
+////////////////////////////////////////////////////////////////////////////////
+
+static proc testPrime(int p, ideal I)
+{
+    /*
+     * test whether a prime p divides the denominator(s)
+     * and leading coefficients of generating set of ideal
+     */
+    int i,j;
+    poly f;
+    number num;
+    bigint d1,d2,d3;
+    for(i = 1; i <= size(I); i++)
+    {
+        f = cleardenom(I[i]);
+        if(f == 0)
+        {
+            return(0);
+        }
+        num = leadcoef(I[i])/leadcoef(f);
+        d1 = bigint(numerator(num));
+        d2 = bigint(denominator(num));
+        if( (d1 mod p) == 0)
+        {
+            return(0);
+        }
+        if((d2 mod p) == 0)
+        {
+            return(0);
+        }
+        for(j = size(f); j > 0; j--)
+        {
+            d3 = bigint(leadcoef(f[j]));
+            if( (d3 mod p) == 0)
+            {
+                return(0);
+            }
+        }
+    }
+    return(1);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/* return 1 if the number of factors are in the required bound , 0 else */
+
+static proc minpolyTask(poly f,int p)
+{
+    /*
+     * bound for irreducible factor(s) of (f mod p)
+     * see testfact()
+     */
+    int nr,k,ur;
+    ur=deg(f);
+    list L=factmodp(f,p);
+    if(degtest(L[2])==1)
+    {
+        // now each factor is squarefree
+        if(ur<=3)
+        {
+            return(1);
+        }
+        else
+        {
+            nr = testfact(ur);
+            k=ncols(L[1]);
+            if(nr < k && k < (ur-nr))// set bound for k
+            {
+                return(1);
+            }
+        }
+    }
+    return(0);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/* return 1 if both testPrime(p,J) and minpolyTask(f,p) is true, 0 else */
+
+static proc PrimeTestTask(int p, list L)
+{
+    /* L=list(I), I=J,f; J ideal , f minpoly */
+    int sz,nr,dg;
+    ideal J=L[1];
+    sz=ncols(J);
+    poly f=J[sz];
+    dg=deg(f);
+    if(!testPrime(p,J) or !minpolyTask(f,p))
+    {
+        return(0);
+    }
+    return(1);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/* compute factors of f mod p with multiplicity */
+
+static proc factmodp(poly f, int p)
+{
+    def R=basering;
+    list l=ringlist(R);
+    l[1]=p;
+    def S=ring(l);
+    setring S;
+    list L=factorize(imap(R,f),2);
+    ideal J=L[1];
+    intvec v=L[2];
+    list scx=J,v;
+    setring R;
+    return(imap(S,scx));
+    kill S;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/* set a bound for number of factors w.r.t degree nr*/
+
+static proc testfact(int nr)
+{
+    // nr must be greater than 3
+    int i;
+    if(nr>3 and nr<=5)
+    {
+        i=1;
+    }
+    if(nr>5 and nr<=10)
+    {
+        i=2;
+    }
+    if(nr>10 and nr<=15)
+    {
+        i=3;
+    }
+    if(nr>15 and nr<=20)
+    {
+        i=4;
+    }
+    if(nr>20 and nr<=25)
+    {
+        i=5;
+    }
+    if(nr>25 and nr<=30)
+    {
+        i=6;
+    }
+    if(nr>30)
+    {
+        i=10;
+    }
+    return(i);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// return 1 if v[i]>1 , 0 else
+
+static proc degtest(intvec v)
+{
+    for(int j=1;j<=nrows(v);j++)
+    {
+        if(v[j]>1)
+        {
+            return(0);
+        }
+    }
+    return(1);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+static proc chinRm(list m, list ll, list lk,list l1,int uz)
+{
+    poly ff,c;
+
+    for(int i=1;i<=uz;i++)
+    {
+        c = division(l1[i]*ll[i],m[i])[2][1];
+        ff = ff + c*lk[i];
+    }
+    return(ff);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+proc chinrempoly(list l,list m)
+"USAGE:  chinrempoly(l, m); l list, m list
+RETURN:  a polynomial (resp. ideal) which is congruent to l[i] modulo m[i] for all i
+NOTE: The procedure applies chinese remaindering to the first argument w.r.t. the
+      moduli given in the second. The elements in the first list must be of same type
+      which can be polynomial or ideal. The moduli must be of type polynomial. Elements
+      in the second list must be distinct and co-prime.
+SEE ALSO: chinrem
+EXAMPLE: example chinrempoly; shows an example
+"
+{
+    int i,j,sz,uz;
+    uz = size(l);
+    sz = ncols(ideal(l[1]));
+    poly f=1;
+    for(i=1;i<=uz;i++)
+    {
+        f=f*m[i];
+    }
+
+    ideal I,J;
+    list l1,ll,lk,l2;
+    poly c,ff;
+    for(j=1;j<=uz;j++)
+    {
+        lk[j]=f/m[j];
+        ll[j]=extgcd(lk[j],m[j])[2];
+    }
+
+    for(i=1;i<=sz;i++)
+    {
+        for(j=1;j<=uz;j++)
+        {
+            I = l[j];
+            l1[j] = I[i];
+        }
+        J[i] = chinRm(m,ll,lk,l1,uz);
+    }
+    return(J);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+    ring rr=97,x,dp;
+    poly f=x^7-7*x + 3;
+    ideal J=factorize(f,1);
+    J;
+    list m=J[1..ncols(J)];
+    list l= x^2+2*x+3, x^2+5, x^2+7;
+    ideal I=chinrempoly(l,m);
+    I;
+    ring s=0,x,dp;
+    list m= x^2+2*x+3, x^3+5, x^4+x^3+7;
+    list l=x^3 + 2, x^4 + 7, x^5 + 11;
+    ideal I=chinrempoly(l,m);
+    I;
+    int p=prime(536546513);
+    ring r = p, (x,y,a), (dp(2),dp(1));
+    poly minpolynomial = a^2+1;
+    ideal kf=factorize(minpolynomial,1);//return factors without multiplicity
+    kf;
+    ideal k=(a+1)*x2+y, 3x-ay+ a+2;
+    option(redSB);
+    ideal k1=k,kf[1];
+    ideal k2 =k,kf[2];
+    k1=std(k1);
+    k2=std(k2);
+    list l=k1,k2;
+    list m=kf[1..ncols(kf)];
+    ideal I=chinrempoly(l,m);
+    I=simplify(I,2);
+    I;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+static proc LiftPolyCRT(ideal I)
+{
+    /*
+     * compute std for each factor and combine this result
+     * to modulo minpoly via CRT for poly over char p>0
+     */
+    int u,in,j;
+    list LL,Lk;
+    ideal J,K,II;
+    poly f;
+    u=ncols(I);
+    J=I[1..u-1];
+    f=I[u];
+    K=factorize(f,1);
+    in=ncols(K);
+    for(j=1;j<=in;j++)
+    {
+        LL[j]=K[j];
+        ideal I(j)=J,K[j];
+        I(j)=std(I(j));
+        if(size(I(j))==1)
+        {
+            Lk[j]=I(j);
+        }
+        else
+        {
+            I(j)[1]=0;
+            I(j)=simplify(I(j), 2);
+            Lk[j]=I(j);
+        }
+    }
+    // apply CRT for polynomials
+    II =chinrempoly(Lk,LL),f;
+    return(II);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+static proc PtestStd(string command, list args, ideal result, int p)
+{
+    /*
+     * let G be std of I which is not yet known whether it is the correct
+     *  standard basis or not. So this procedure does the first test
+     */
+    def br = basering;
+    list lbr = ringlist(br);
+    if (typeof(lbr[1]) == "int")
+    {
+        lbr[1] = p;
+    }
+    else
+    {
+        lbr[1][1] = p;
+    }
+    def rp = ring(lbr);
+    setring(rp);
+    ideal Ip = fetch(br, args)[1];
+    ideal Gp = fetch(br, result);
+    attrib(Gp, "isSB", 1);
+    int i;
+    for (i = ncols(Ip); i > 0; i--)
+    {
+        if (reduce(Ip[i], Gp, 1) != 0)
+        {
+            setring(br);
+            return(0);
+        }
+    }
+    Ip = LiftPolyCRT(Ip);
+    attrib(Ip,"isSB",1);
+    for (i = ncols(Gp); i > 0; i--)
+    {
+        if (reduce(Gp[i], Ip, 1) != 0)
+        {
+            setring(br);
+            return(0);
+        }
+    }
+    setring(br);
+    return(1);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+static proc cleardenomIdeal(ideal I)
+{
+    int t=ncols(I);
+    if(size(I)==0)
+    {
+        return(I);
+    }
+    else
+    {
+        for(int i=1;i<=t;i++)
+        {
+            I[i]=cleardenom(I[i]);
+        }
+    }
+    return(I);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+static proc modStdparallelized(ideal I)
+{
+    // apply modular.lib
+    /* save options */
+    intvec opt = option(get);
+    option(redSB);
+    I = modular("Algemodstd::LiftPolyCRT", list(I), PrimeTestTask, Modstd::deleteUnluckyPrimes_std,
+              PtestStd, Modstd::finalTest_std,536870909);
+    attrib(I, "isSB", 1);
+    option(set,opt);
+    return(I);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/* main procedure */
+proc algemodStd(ideal I, list #)
+"USAGE:  algemodStd(I, #); I ideal, # optional parameters
+RETURN:  standard basis of I over algebraic number field
+NOTE: The procedure passes to @ref{modStd} if the ground field has no
+      parameter. In this case, the optional parameters # (if given)
+      are directly passed to @ref{modStd}.
+SEE ALSO: modStd
+EXAMPLE: example algemodStd; shows an example
+"
+{
+    list L=#;
+    def Rbs=basering;
+    poly f;
+    ideal J;
+    int n=nvars(Rbs);
+    if(size(I)==0)
+    {
+        return(ideal(0));
+    }
+    if(npars(Rbs)==0)
+    {
+        J=modStd(I,L);//if algebraic number is in Q
+        if(size(#)>0)
+        {
+            return(cleardenomIdeal(J));
+        }
+        return(J);
+    }
+    list rl=ringlist(Rbs);
+    f=rl[1][4][1];
+    rl[2][n+1]=rl[1][2][1];
+    rl[1]=rl[1][1];
+    rl[3][size(rl[3])+1]=rl[3][size(rl[3])];
+    rl[3][size(rl[3])-1]=list("dp",1);
+    def S=ring(rl);
+    setring S;
+    poly f=imap(Rbs,f);
+    ideal I=imap(Rbs,I);
+    I = simplify(I,2);// eraze the zero generatos
+    ideal J;
+    if(f==0)
+    {
+        ERROR("minpoly must be non-zero");
+    }
+    I=I,f;
+    J=modStdparallelized(I);
+    setring Rbs;
+    J=imap(S,J);
+    J=simplify(J,2);
+    if(size(#)>0)
+    {
+        return(cleardenomIdeal(J));
+    }
+    return(J);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+    ring r1 =(0,a),(x,y),dp;
+    minpoly =a^2+1;
+    ideal k=(a/2+1)*x^2+2/3y, 3*x-a*y+ a/7+2;
+    ideal I=algemodStd(k);
+    I;
+    ring r2 =(0,a),(x,y,z),dp;
+    minpoly =a^3 +2;
+    ideal k=(a^2+a/2)*x^2+(a^2 -2/3*a)*yz, (3*a^2+1)*zx-(a+4/7)*y+ a+2/5;
+    ideal IJ=algemodStd(k);
+    IJ;
+    ring r3=0,(x,y),dp;// ring without parameter
+    ideal I = x2 + y, xy - 7y + 2x;
+    I=algemodStd(I);
+    I;
+}
diff --git a/Singular/LIB/all.lib.tmpl b/Singular/LIB/all.lib.tmpl
new file mode 100644
index 0000000..51b800d
--- /dev/null
+++ b/Singular/LIB/all.lib.tmpl
@@ -0,0 +1,12 @@
+///////////////////////////////////////////////////////////////////////////////
+version="version all.lib 4.0.1.1 Nov_2014 ";
+category = "General purpose";
+info="
+LIBRARY:  all.lib   Load all libraries (commutative case)
+AUTHORS:  Singular team (automatically generated, do not edit)
+
+use: help Singular libraries; for a list of the libraries
+";
+
+///////////////////////////////////////////////////////////////////////////////
+
diff --git a/Singular/LIB/arcpoint.lib b/Singular/LIB/arcpoint.lib
new file mode 100644
index 0000000..cad2526
--- /dev/null
+++ b/Singular/LIB/arcpoint.lib
@@ -0,0 +1,515 @@
+//////////////////////////////////////////////////////////////////////////////
+version="version arcpoint.lib 4.0.0.0 Jun_2013 "; // $Id: 14a93d330540dc1bfea332ae44d5ca619952e74a $
+//-*- mode:C++;-*-
+
+category="Singularities";
+info="
+LIBRARY:  arcpoint.lib          Truncations of arcs at a singular point
+AUTHOR:   Nadine Cremer         cremer at mathematik.uni-kl.de
+
+OVERVIEW: An arc is given by a power series in one variable, say t, and
+          truncating it at a positive integer i means cutting
+          the t-powers > i. The set of arcs truncated at order
+          <bound> is denoted Tr(i). An algorithm for computing
+          these sets (which happen to be constructible) is given in
+          [Lejeune-Jalabert, M.: Courbes trac\'ees sur un germe
+          d'hypersurface, American Journal of Mathematics, 112 (1990)].
+          Our procedures for computing the locally closed sets contributing
+          to the set of truncations rely on this algorithm.
+
+PROCEDURES:
+    nashmult(f,bound);         determines locally closed sets relevant
+                               for computing truncations of arcs over a
+                               hypersurface with isolated singularity
+                               defined by f. The sets are given by two
+                               ideals specifying relations between
+                               coefficients of power series in t. One
+                               of the ideals defines an open set, the
+                               other one the complement of a closed
+                               set within the open one.
+                               We consider only coefficients up to
+                               t^<bound>.
+                               Moreover, the sequence of Nash
+                               Multiplicities of each set is
+                               displayed
+    removepower(I);            modifies the ideal I such that the
+                               algebraic set defined by it remains
+                               the same: removes powers of variables
+    idealsimplify(I,maxiter);  further simplification of I in the
+                               above sense: reduction with other
+                               elements of I. The positive integer
+                               <maxiter> gives a bound to the number of
+                               repetition steps
+    equalJinI(I,J);            tests if two ideals I and J are equal
+                               under the assumption that J is
+                               contained in I. Returns 1 if this is
+                               true and 0 otherwise
+    ";
+
+LIB "ring.lib";
+LIB "general.lib";
+LIB "standard.lib";
+LIB "sing.lib";
+
+
+//////////////////////////////////////////////////////////////////////
+//                                                                  //
+//                  RELEVANT LOCALLY CLOSED SETS                    //
+//                                                                  //
+//////////////////////////////////////////////////////////////////////
+
+
+proc nashmult (poly f, int bound)
+"USAGE:   nashmult(f,bound); f polynomial, bound positive integer
+CREATE:  allsteps:
+ at format
+         a list containing all relevant locally closed sets
+         up to order <bound> and their sequences of
+         Nash Multiplicities
+ at end format
+         setstep:
+ at format
+         list of relevant locally closed sets
+         obtained from sequences of length bound+1
+ at end format
+RETURN:  ring, original basering with additional
+         variables t and coefficients up to t^<bound>
+EXAMPLE: example nashmult; shows an example"
+
+{
+ // Make sure that only admissible  parameters are entered
+
+ if (bound<1)
+ {
+   ERROR("Integer parameter must be positive!");
+ }
+
+ // General setup, declarations and initialization...
+
+ int k,s,step,loop;                   // loop variables
+ int pos;                             // position parameter
+ int countall;                        // position parameter
+ list allsteps;                       // saves results from all
+                                      // steps
+ def r=basering;
+ int startvar=nvars(basering);
+ intvec control=order(f);             // initialize
+ def R=ringchange(bound+1);           // ring in which result lies
+
+
+ setring R;                           // make it basering
+ ideal I0;
+ list init=control,I0,I0;
+ list setstep=insert(setstep,init);   // stores Nash multiplicities
+ kill I0;                             // and underlying sets (given
+ kill init;                           // that the sets are not
+                                       // empty),will be a list of
+                                      // lists, each of which
+                                      // containing an intvec and
+                                      // two ideals
+
+
+  // consider all possible sequences of multiplicities<=<bound>:
+
+ for(step=2;step<=bound+1;step++)
+ {
+   list setsteptmp;                    // temporary variable, local
+                                       // to this loop
+   int count;                          // position parameter
+   int setsize=size(setstep);
+
+   setring r;
+   def rplug=pluginCoeffs(f,step);     // substitute variables in f
+                                       // by polynomials in t of
+                                       // degree <step>
+   setring R;
+   ideal coe=imap(rplug,resultcoe);    // gives the t-coefficients
+   kill rplug;
+
+
+   // consider all sequences of length <step-1> giving rise to a
+   // family...
+
+   for(loop=1;loop<=setsize;loop++)
+   {
+     control=setstep[loop][1];       // initialization. <control>
+     int sizecontrol=size(control);  // describes Nash mutiplicities
+     ideal gprev=setstep[loop][3];   // in this step, <fprev> and
+     ideal fprev=setstep[loop][2];   // <gprev> the already obtained
+                                     // relations
+
+     ideal actcoe=reduce(coe,slimgb(fprev));  // take into account
+                                              // existing relations
+
+     pos=1;                          // determine first nonzero
+     while(actcoe[pos]==0)           // t-coefficient
+     {
+       pos++;
+     }
+
+     ideal fset;                     // will store relations
+     ideal gset;                     // defining the
+                                     // constructible sets
+
+     int m0=control[sizecontrol];    // bounds the computations
+
+     // consider all possible sequences arising from <control>...
+
+     control=control,0;
+     for (s=1;s<=m0;s++)
+     {
+       control[step]=control[step]+1;  // the next possible sequence
+                                       // of multiplicities
+
+       fset=fset,actcoe[pos+s-1],gset; // add new condition
+       gset=gset,fset;
+
+       for(k=0;k<startvar;k++)         // additional conditions for
+       {                               // <gset>:
+         ideal coevar=coeffs(actcoe[pos+s],
+         var(startvar+1+step+k*(bound+1)));
+         int coesize=ncols(coevar);
+         if (coesize>=2)               // add coeff. of nonconstant
+         {                             // terms in "highest"
+           gset=gset,coevar[2..coesize]; // variables
+         }
+         kill coevar;
+         kill coesize;
+       }
+       fset=fprev,fset;                // add obtained conditions
+       gset=fprev,gset;                // to the existing ones...
+       gset=idealsimplify(gset,1000);  // ...and simplify
+       fset=idealsimplify(fset,1000);
+
+
+        // if we have found a nontrivial component...
+
+       if (control[step-1]==1)
+       {
+         list comp=control,fset,gset;              // ...add it and
+         setsteptmp=insert(setsteptmp,comp,count); // multiplicity
+         count++;
+         kill comp;
+       }
+       else
+       {
+         if (equalJinI(gset,fset)==0)
+         {
+           list comp=control,fset,gset;             // ...add it and
+           setsteptmp=insert(setsteptmp,comp,count);// multiplicity
+           count++;
+           kill comp;
+         }
+       }
+     }
+     kill fset,gset,actcoe,sizecontrol,fprev,gprev,m0;
+  }
+  setstep=setsteptmp;
+
+  allsteps=insert(allsteps,setstep,countall);   // add results from
+  countall++;                                   // this step
+
+  kill setsteptmp,count,coe,setsize;
+ }
+ export(setstep);
+ export(allsteps);
+ return(R);
+}
+example
+{
+  "EXAMPLE:"; echo=2;
+  ring r=0,(x,y,z),dp;
+  poly f=z4+y3-x2;
+  def R=nashmult(f,2);
+  setring R;
+  allsteps;
+}
+
+
+
+//////////////////////////////////////////////////////////////////////
+//                                                                  //
+//               SUBSTITUE VARIABLES BY POLYNOMIALS                 //
+//                                                                  //
+//////////////////////////////////////////////////////////////////////
+
+
+static proc pluginCoeffs (poly f,int i)
+"USAGE:   pluginCoeffs(f,i); f polynomial, i integer
+CREATE:  matrix, the t-coefficients obtained by replacing each
+         variable of f by a polynomial in t
+RETURN:  ring, corresponds to f and i in the sense that it is
+         the original ring with added variables t and
+         t-coefficients up to t^<bound> "
+{
+  int startvar=nvars(basering);
+  def r=basering;
+  def R=ringchange(i);              // changes the ring
+  setring R;                        // makes it new basering;
+  ideal I=tpolys(i,startvar);
+  map h=r,I;                        // define map
+  ideal resultplug=h(f);
+  matrix resultcoe=coeffs(resultplug[1],t);
+  export(resultcoe);                // keep accessible
+  export(resultplug);
+  return(R);                        //
+}
+
+//////////////////////////////////////////////////////////////////////
+static proc tpolys (int i,int k)
+"USAGE:   tpolys(i,k); i,k integer
+RETURN:  ideal, generated by k polynomials in t of degree i
+         of the form a(1)*t+..+a(i)*t^i
+NOTE:    called from pluginCoeffs"
+{
+  int s,t;
+  int v;
+  poly sum;
+  ideal I;
+  for(t=1;t<=k;t++)
+  {
+    v=(t-1)*i;
+    for(s=1;s<=i;s++)
+    {
+      sum=sum+var(1+k+v+s)*var(k+1)^s;
+    }
+    I[t]=sum;
+    sum=0;
+  }
+  return(I);
+}
+
+
+//////////////////////////////////////////////////////////////////////
+//                                                                  //
+//                  CONSTRUCTING THE RESULT RING                    //
+//                                                                  //
+//////////////////////////////////////////////////////////////////////
+
+
+static proc ringchange (int i)
+"USAGE:   ringchange(i); i integer
+RETURN:  ring, extends basering by variables t and
+          #(variables of basering)*i new variables"
+{
+  def R=changevar(""+varstr(basering)+",t,"
+  +variables_str(nvars(basering),i)+"");
+  return(R);
+}
+
+/////////////////////////////////////////////////////////////////////
+static proc variables_str (int k,int i)
+"USAGE:   variables_str(k,i); k,i integer
+ASSUME:  1<=k<=26, i>=1
+RETURN:  string of names of variables added in ringchange
+NOTE:    called from ringchange, we use this procedure to
+          obtain a nice shape of the ring created "
+{
+  list l;
+  int s,u;
+  string str;
+  for (u=1;u<=k;u++)
+  {
+    for (s=1;s<=i;s++)
+    {
+      str=""+atoz(u)+"("+string(s)+")"; // creates new variables
+      l[(u-1)*i+s]=str;                 // saves them in a list
+    }
+  }
+  string str1=string(l);               // makes a string of the
+  return(str1);                        // list (needed for change
+}                                      // of ring)
+
+//////////////////////////////////////////////////////////////////////
+static proc atoz (int n)
+"USAGE:   atoz(n); n integer
+ASSUME:  1<=n<=26
+RETURN:  string, the nth letter of the alphabet"
+{
+ string s="ring r=0,("+A_Z("a",n)+"),ds;";
+ execute(s);
+ return (string(var(n)));
+}
+
+
+//////////////////////////////////////////////////////////////////////
+//                                                                  //
+//                  AUXILIARY PROCEDURES                            //
+//                                                                  //
+//////////////////////////////////////////////////////////////////////
+
+
+static proc order (poly f)
+"USAGE:   order(f); f polynomial
+RETURN:  int i, such that f_i is the smallest (in terms of degree)
+         non-zero homogeneous part
+NOTE:    is designed for ordering dp"
+{
+ int k=deg(f);
+ int i;
+ for(i=1;i<=k;i++)
+ {
+  if(jet(f,i)!=0)
+  {
+    return(i);
+  }
+ }
+}
+
+//////////////////////////////////////////////////////////////////////
+static proc modd (poly f, poly g)
+"USAGE:   modd(f,g); f,g polynomials
+RETURN:  poly, f mod g division with remainder
+NOTE:    called from idealsimplify where it is used to modify
+          the generating set of an ideal"
+{
+  poly result=f-(f/g)*g;
+  return(result);
+}
+
+//////////////////////////////////////////////////////////////////////
+proc removepower (ideal I)
+"USAGE:   removepower(I); I ideal
+SEE ALSO:idealsimplify
+RETURN:  ideal defining the same zeroset as I: if any  generator
+         of I is a power of one single variable, replace it by the
+         respective variable
+EXAMPLE: example removepower; shows an example"
+{
+  int i,j;
+  int divisornumber=0;
+  int pos;
+  I=simplify(I,6);            // remove 0 and multiple generators
+  for(j=1;j<=ncols(I);j++)
+  {
+    if(size(I[j])==1)         // test if generators are powers
+    {                         // of variables...
+      for(i=1;i<=nvars(basering);i++)
+      {
+        if(modd(I[j],var(i))==0)
+        {
+          divisornumber++;
+          pos=i;
+        }
+      }
+    }
+    if(divisornumber==1)      // ...if so, replace by variable
+    {
+      I[j]=var(pos);
+    }
+    divisornumber=0;
+  }
+  return(I);
+}
+example
+{
+  "EXAMPLE:"; echo=2;
+   ring r=0,(x,y,z),dp;
+   ideal I = x3,y+z2-x2;
+   I;
+
+   removepower(I);
+}
+
+//////////////////////////////////////////////////////////////////////
+proc idealsimplify (ideal I, int maxiter)
+"USAGE:   idealsimplify(I,m); I ideal, m int
+ASSUME:  procedure is stable for sufficiently large m
+RETURN:  ideal defining the same zeroset as I: replace   generators
+         of I by the generator modulo other generating elements
+EXAMPLE: example idealsimplify; shows an example "
+{
+  if(maxiter<1)
+    {ERROR("The integer argument has to be positive!")}
+  ideal comp;
+  int iteration;
+  int changed=0;
+  int i,j,ci,n,cols;
+  for(iteration=0;iteration<maxiter;iteration++)
+  {
+    comp=I;
+    n=ncols(I);
+    for(j=2;j<=n;j++)         // reduce with lower elements
+    {
+      for(i=1;i<j;i++)
+      {
+        if(I[i]!=0)
+        {
+          I[j]=modd(I[j],I[i]);
+        }
+      }
+    }
+    I=simplify(removepower(I),7);
+
+    kill n;
+    int n=ncols(I);
+    for(j=n-1;j>=1;j--)       // reduce with higher elements
+    {
+      for(i=n;i>j;i--)
+      {
+        if(I[i]!=0)
+        {
+          I[j]=modd(I[j],I[i]);
+        }
+      }
+     }
+    I=simplify(removepower(I),7);
+
+    if (ncols(I)==ncols(comp))      //check if I has changed
+    {
+      cols=ncols(I);
+      changed=0;
+      for(ci=1;ci<=cols;ci++)
+      {
+        if (I[ci]!=comp[ci])
+        {
+          changed=1;
+          break;
+        }
+      }
+      if (changed==0)
+       break;
+    }
+  }
+  return(I);
+}
+example
+{
+  "EXAMPLE:"; echo=2;
+  ring r=0,(x,y,z),dp;
+  ideal I = x3,y+z2-x2;
+  I;
+
+  idealsimplify(I,10);
+}
+
+//////////////////////////////////////////////////////////////////////
+proc equalJinI (ideal I, ideal J)
+"USAGE:   equalJinI(I,J); (I,J ideals)
+ASSUME:  J contained in I and both I and J have been processed
+         with idealsimplify before
+SEE ALSO: idealsimplify
+RETURN:  1, if I=J, 0 otherwise
+EXAMPLE: example equalJinI; shows an example"
+{
+  int col=ncols(I);
+  J=slimgb(J);
+  int k;
+  for(k=1;k<=col;k++)
+  {
+    if(reduce(I[k],J)!=0)
+    { return(0);}
+  }
+  return(1);
+}
+example
+{
+  "EXAMPLE:"; echo=2;
+  ring r=0,(x,y,z),dp;
+  ideal I = x,y+z2;
+  ideal J1= x;
+  ideal J2= x,y+z2;
+
+  equalJinI(I,J1);
+  equalJinI(I,J2);
+}
diff --git a/Singular/LIB/assprimeszerodim.lib b/Singular/LIB/assprimeszerodim.lib
new file mode 100644
index 0000000..c8192ae
--- /dev/null
+++ b/Singular/LIB/assprimeszerodim.lib
@@ -0,0 +1,752 @@
+///////////////////////////////////////////////////////////////////////////////
+version="version assprimeszerodim.lib 4.0.0.0 Jun_2014 "; // $Id: 4c9703d9d449016b92ecb5f8786539f6d04d29ed $
+category="Commutative Algebra";
+info="
+LIBRARY:  assprimeszerodim.lib   associated primes of a zero-dimensional ideal
+
+AUTHORS:  N. Idrees       nazeranjawwad at gmail.com
+          G. Pfister      pfister at mathematik.uni-kl.de
+          A. Steenpass    steenpass at mathematik.uni-kl.de
+          S. Steidel      steidel at mathematik.uni-kl.de
+
+OVERVIEW:
+
+  A library for computing the associated primes and the radical of a
+  zero-dimensional ideal in the polynomial ring over the rational numbers,
+  Q[x_1,...,x_n], using modular computations.
+
+SEE ALSO: primdec_lib
+
+PROCEDURES:
+ zeroRadical(I);       computes the radical of I
+ assPrimes(I);         computes the associated primes of I
+";
+
+LIB "primdec.lib";
+LIB "modstd.lib";
+
+////////////////////////////////////////////////////////////////////////////////
+
+proc zeroRadical(ideal I, list #)
+"USAGE:  zeroRadical(I[, exactness]); I ideal, exactness int
+ASSUME:  I is zero-dimensional in Q[variables]
+RETURN:  the radical of I
+NOTE:    A final test is applied to the result if exactness != 0 (default),
+         otherwise no final test is done.
+EXAMPLE: example zeroRadical; shows an example
+"
+{
+   /* read optional parameter */
+   int exactness = 1;
+   if(size(#) > 0)
+   {
+      if(size(#) > 1 || typeof(#[1]) != "int")
+      {
+         ERROR("wrong optional parameter");
+      }
+      exactness = #[1];
+   }
+
+   /* compute a standard basis if necessary */
+   if (!attrib(I, "isSB"))
+   {
+      I = modStd(I, exactness);
+   }
+
+   /* call modular() */
+   // TODO: write deleteUnluckyPrimes_zeroRadical()
+   if(exactness)
+   {
+      ideal F = modular("Assprimeszerodim::zeroRadP", list(I),
+         Modstd::primeTest_std, Modular::deleteUnluckyPrimes_default,
+         pTest_zeroRadical, finalTest_zeroRadical);
+   }
+   else
+   {
+      ideal F = modular("Assprimeszerodim::zeroRadP", list(I),
+         Modstd::primeTest_std, Modular::deleteUnluckyPrimes_default,
+         pTest_zeroRadical);
+   }
+
+   /* compute the squarefree parts */
+   poly f;
+   int k;
+   int i;
+   for(i = nvars(basering); i > 0; i--)
+   {
+      f = gcd(F[i], diff(F[i], var(i)));
+      k = k + deg(f);
+      F[i] = F[i]/f;
+   }
+
+   /* return the result */
+   if(k == 0)
+   {
+      return(I);
+   }
+   else
+   {
+      return(modStd(I + F, exactness));
+   }
+}
+example
+{ "EXAMPLE:";  echo = 2;
+   ring R = 0, (x,y), dp;
+   ideal I = xy4-2xy2+x, x2-x, y4-2y2+1;
+   zeroRadical(I);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+/* The pTest for zeroRadical(), to be used in modular(). */
+static proc pTest_zeroRadical(string command, list args, ideal result, int p)
+{
+   /* change to characteristic p */
+   def br = basering;
+   list lbr = ringlist(br);
+   if(typeof(lbr[1]) == "int")
+   {
+      lbr[1] = p;
+   }
+   else
+   {
+      lbr[1][1] = p;
+   }
+   def rp = ring(lbr);
+   setring(rp);
+   ideal Ip = fetch(br, args)[1];
+   ideal Fp_result = fetch(br, result);
+
+   /* run the command and compare with given result */
+   execute("ideal Fp = "+command+"(Ip);");
+   int i;
+   for(i = nvars(br); i > 0; i--)
+   {
+      if(Fp[i] != Fp_result[i])
+      {
+         setring(br);
+         return(0);
+      }
+   }
+   setring(br);
+   return(1);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+/* The finalTest for zeroRadical, to be used in modular(). */
+static proc finalTest_zeroRadical(string command, list args, ideal F)
+{
+   int i;
+   for(i = nvars(basering); i > 0; i--)
+   {
+      if(reduce(F[i], args[1]) != 0) { return(0); }
+   }
+   return(1);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+proc assPrimes(def I, list #)
+"USAGE:  assPrimes(I[, alg, exactness]); I ideal or module,
+         alg string (optional), exactness int (optional)
+         - alg = "GTZ":    method of Gianni/Trager/Zacharias (default)
+         - alg = "EHV":    method of Eisenbud/Hunecke/Vasconcelos
+         - alg = "Monico": method of Monico
+ASSUME:  I is zero-dimensional over Q[variables]
+RETURN:  a list of the associated primes of I
+NOTE:    A final test is applied to the result if exactness != 0 (default),
+         otherwise no final test is done.
+EXAMPLE: example assPrimes; shows an example
+"
+{
+   /* read input */
+   if(typeof(I) != "ideal")
+   {
+      if(typeof(I) != "module")
+      {
+         ERROR("The first argument must be of type 'ideal' or 'module'.");
+      }
+      module M = I;
+      kill I;
+      ideal I = Ann(M);
+      kill M;
+   }
+
+   /* read optional parameters */
+   list defaults = list("GTZ", 1);
+   int i;
+   for(i = 1; i <= size(defaults); i++)
+   {
+      if(typeof(#[i]) != typeof(defaults[i]))
+      {
+         # = insert(#, defaults[i], i-1);
+      }
+   }
+   if(size(#) != size(defaults))
+   {
+      ERROR("wrong optional parameters");
+   }
+   string alg = #[1];
+   int exactness = #[2];
+   int a;
+   if(alg == "GTZ")
+   {
+      a = 1;
+   }
+   if(alg == "EHV")
+   {
+      a = 2;
+   }
+   if(alg == "Monico")
+   {
+      a = 3;
+   }
+   if(a == 0)   // alg != "GTZ" && alg != "EHV" && alg != "Monico"
+   {
+      ERROR("unknown method");
+   }
+
+   /* compute a standard basis if necessary */
+   if(printlevel >= 10) { "========== Start modStd =========="; }
+   if (!attrib(I, "isSB")) {
+       I = modStd(I, exactness);
+   }
+   if(printlevel >= 10) { "=========== End modStd ==========="; }
+   int d = vdim(I);
+   if(d == -1) { ERROR("Ideal is not zero-dimensional."); }
+   if(homog(I) == 1) { return(list(maxideal(1))); }
+
+   /* compute the radical if necessary */
+   ideal J = I;
+   int isRad;
+   poly f;
+   isRad, f = pTestRad(I, d);
+   while(!isRad)
+   {
+      J = zeroRadical(I, exactness);
+      J = modStd(J, exactness);
+      d = vdim(J);
+      isRad, f = pTestRad(J, d);
+   }
+   I = J;
+   kill J;
+
+   /* call modular() */
+   if(exactness)
+   {
+      ideal F = modular("Assprimeszerodim::modpSpecialAlgDep",
+         list(I, f, d, a),
+         Modstd::primeTest_std, Modular::deleteUnluckyPrimes_default,
+         pTest_assPrimes, finalTest_assPrimes);
+   }
+   else
+   {
+      ideal F = modular("Assprimeszerodim::modpSpecialAlgDep",
+         list(I, f, d, a),
+         Modstd::primeTest_std, Modular::deleteUnluckyPrimes_default,
+         pTest_assPrimes);
+   }
+
+   /* compute the components */
+   list result;
+   list H = factorize(F[1]);
+   for(i = size(H[1])-1; i > 0; i--)
+   {
+      result[i] = I + ideal(quickSubst(H[1][i+1], f, I));
+   }
+
+   /* return the result */
+   return(result);
+}
+example
+{ "EXAMPLE:";  echo = 2;
+   ring R = 0,(a,b,c,d,e,f),dp;
+   ideal I =
+   2fb+2ec+d2+a2+a,
+   2fc+2ed+2ba+b,
+   2fd+e2+2ca+c+b2,
+   2fe+2da+d+2cb,
+   f2+2ea+e+2db+c2,
+   2fa+f+2eb+2dc;
+   assPrimes(I);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+/* Computes a poly F in Q[T] such that
+ * <F> = kernel(Q[T] --> basering, T |-> f),
+ * T := last variable in the basering.
+ */
+static proc specialAlgDepEHV(ideal I, poly f)
+{
+   def R = basering;
+   execute("ring QT = ("+charstr(R)+"), "+varstr(R, nvars(R))+", dp;");
+   setring(R);
+   map phi = QT, f;
+   setring QT;
+   ideal F = preimage(R, phi, I); // corresponds to std(I, f-T) in dp(n),dp(1)
+   setring(R);
+   ideal F = imap(QT, F);
+   return(F);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+/* Assume I is zero-dimensional.
+ * Computes a poly F in Q[T] such that
+ * <F> = kernel(Q[T] --> basering, T |-> f),
+ * T := last variable in the basering.
+ */
+static proc specialAlgDepGTZ(ideal I, poly f)
+{
+   def R = basering;
+   if(nvars(R) > 1)
+   {
+      def Rlp = changeord(list(list("dp", 1:(nvars(R)-1)), list("dp", 1:1)));
+      setring(Rlp);
+      poly f = imap(R, f);
+      ideal I;
+   }
+   ideal K = maxideal(1);
+   K[nvars(R)] = 2*var(nvars(R))-f;
+   map phi = R, K;
+   I = phi(I);
+   I = std(I);
+   ideal F = I[1];
+   if(nvars(R) > 1)
+   {
+      setring(R);
+      ideal F = imap(Rlp, F);
+   }
+   return(F);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+/* Assume I is zero-dimensional.
+ * Computes a poly F in Q[T], the characteristic polynomial of the map
+ * basering/I ---> basering/I  defined by the multiplication with f,
+ * T := last variable in the basering.
+ * In case I is radical, it is the same polynomial as in specialAlgDepEHV.
+ */
+static proc specialAlgDepMonico(ideal I, poly f, int d)
+{
+   def R = basering;
+   int j;
+   matrix M[d][d];
+   ideal J = std(I);
+   ideal basis = kbase(J);
+   poly vars = var(nvars(R));
+   for(j = nvars(R)-1; j > 0; j--)
+   {
+     vars = var(j)*vars;
+   }
+   for(j = 1; j <= d; j++)
+   {
+     M[1..d, j] = coeffs(reduce(f*basis[j], J), basis, vars);
+   }
+   execute("ring QT = ("+charstr(R)+"), "+varstr(R, nvars(R))+", dp;");
+   matrix M = imap(R, M);
+   ideal F = det(M-var(1)*freemodule(d));
+   setring(R);
+   ideal F = imap(QT, F);
+   return(F);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+static proc specialTest(int d, poly p, ideal I)
+{
+//=== computes a poly F in Q[T] such that <F>=kernel(Q[T]--->basering)
+//=== mapping T to p and test if d=deg(F)
+   def R = basering;
+   execute("ring Rhelp = ("+charstr(R)+"), T, dp;");
+   setring R;
+   map phi = Rhelp,p;
+   setring Rhelp;
+   ideal F = preimage(R,phi,I);
+   int e=deg(F[1]);
+   setring R;
+   return((e==d), fetch(Rhelp, F)[1]);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+/* Assume d = vector space dim(basering/J).
+ * Tries to find a (sparse) linear form r such that d = deg(F), where
+ * F is a poly in Q[T] such that <F> = kernel(Q[T]-->basering) mapping T to r.
+ * If found, returns (1, r, F). If not found, returns (0, 0, 0).
+ */
+static proc findGen(ideal J, int d)
+{
+   def R = basering;
+   int n = nvars(R);
+   int okay;
+   poly F;
+
+   /* try trivial transformation */
+   poly r = var(n);
+   okay, F = specialTest(d, r, J);
+   if(okay)
+   {
+      return(1, r, F);
+   }
+
+   /* try transformations of the form var(n) + var(i) */
+   int i;
+   for(i = 1; i < n; i++)
+   {
+      okay, F = specialTest(d, r+var(i), J);
+      if(okay)
+      {
+         return(1, r+var(i), F);
+      }
+   }
+
+   /* try transformations of the form var(n) + \sum var(i) */
+   if(n > 2)
+   {
+      for(i = 1; i < n; i++)
+      {
+         r = r + var(i);
+         okay, F = specialTest(d, r, J);
+         if(okay)
+         {
+            return(1, r, F);
+         }
+      }
+   }
+
+   /* try random transformations */
+   int N = 2;   // arbitrarily chosen
+   for(i = N; i > 0; i--)
+   {
+      r = randomLast(100)[n];
+      okay, F = specialTest(d, r, J);
+      if(okay)
+      {
+         return(1, r, F);
+      }
+   }
+
+   /* not found */
+   return(0, 0, 0);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+/* Assume d = vector space dim(basering/I).
+ * Tests if I is radical over F_p, where p is some randomly chosen prime.
+ * If yes, chooses a linear form r such that d = deg(squarefreepart(F)), where
+ * F is a poly in Z/p[T] such that <F> = kernel(Z/p[T]-->Z/p[vars(basering)])
+ * mapping T to r.
+ * Returns (1, r), if I is radical over F_p, and (0, 0) otherwise.
+ */
+static proc pTestRad(ideal I, int d)
+{
+   int N = 2;   // Try N random primes. Value of N can be chosen arbitrarily.
+   def R = basering;
+   list rl = ringlist(R);
+   int p;
+   int okay;
+   int i;
+   for(i = N; i > 0; i--)
+   {
+      p = prime(random(100000000,536870912));
+
+      // change to characteristic p
+      if(typeof(rl[1]) == "int")
+      {
+         rl[1] = p;
+      }
+      else
+      {
+         rl[1][1] = p;
+      }
+      def Rp(i) = ring(rl);
+      setring Rp(i);
+      ideal I = imap(R, I);
+
+      // find and test transformation
+      poly r;
+      poly F;
+      okay, r, F = findGen(I, d);
+      if(okay)
+      {
+         poly f = gcd(F, diff(F, var(1)));
+         if(d == deg(F/f))   // F squarefree?
+         {
+            setring(R);
+            return(1, imap(Rp(i), r));
+         }
+      }
+      setring(R);
+   }
+   return(0, 0);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+/* Computes an ideal F such that ncols(F) = nvars(basering),
+ * < F[i] > = (I intersected with K[var(i)]), and F[i] is monic.
+ */
+static proc zeroRadP(ideal I)
+{
+   intvec opt = option(get);
+   option(redSB);
+   I = std(I);
+   ideal F = finduni(I);   // F[i] generates I intersected with K[var(i)]
+   F = simplify(F, 1);
+   option(set, opt);
+   return(F);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+static proc quickSubst(poly h, poly r, ideal I)
+{
+//=== assume h is in Q[x_n], r is in Q[x_1,...,x_n], computes h(r) mod I
+   attrib(I,"isSB",1);
+   int n = nvars(basering);
+   poly q = 1;
+   int i,j,d;
+   intvec v;
+   list L;
+   for(i = 1; i <= size(h); i++)
+   {
+      L[i] = list(leadcoef(h[i]),leadexp(h[i])[n]);
+   }
+   d = L[1][2];
+   i = 0;
+   h = 0;
+
+   while(i <= d)
+   {
+      if(L[size(L)-j][2] == i)
+      {
+         h = reduce(h+L[size(L)-j][1]*q,I);
+         j++;
+      }
+      q = reduce(q*r,I);
+      i++;
+   }
+   return(h);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+/* Simple switch for specialAlgDepEHV, specialAlgDepGTZ, and
+ * specialAlgDepMonico.
+ */
+static proc modpSpecialAlgDep(ideal I, poly f, int d, int alg)
+{
+   ideal F;
+   if(alg == 1) { F = specialAlgDepEHV(I, f); }
+   if(alg == 2) { F = specialAlgDepGTZ(I, f); }
+   if(alg == 3) { F = specialAlgDepMonico(I, f, d); }
+   F = simplify(F, 1);
+   return(F);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+/* The pTest for assPrimes(), to be used in modular(). */
+static proc pTest_assPrimes(string command, list args, ideal F, int p)
+{
+   def br = basering;
+   list lbr = ringlist(br);
+   if(typeof(lbr[1]) == "int")
+   {
+      lbr[1] = p;
+   }
+   else
+   {
+      lbr[1][1] = p;
+   }
+   def rp = ring(lbr);
+   setring(rp);
+   list args_p = fetch(br, args);
+   ideal F = fetch(br, F);
+   execute("ideal Fp = "+command+"("
+      +Tasks::argsToString("args_p", size(args_p))+");");
+   int k = (Fp[1] == F[1]);
+   setring br;
+   return(k);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+/* The finalTest for assPrimes(), to be used in modular(). */
+static proc finalTest_assPrimes(string command, alias list args, ideal F)
+{
+   F = cleardenom(F[1]);
+   if(deg(F[1]) != args[3]) { return(0); }
+   if(gcd(F[1], diff(F[1], var(nvars(basering)))) != 1) { return(0); };
+   if(quickSubst(F[1], args[2], args[1]) != 0) { return(0); }
+   return(1);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+/*
+Examples:
+=========
+
+//=== Test for zeroR
+ring R = 0,(x,y),dp;
+ideal I = xy4-2xy2+x, x2-x, y4-2y2+1;
+
+//=== Cyclic_6
+ring R = 0,x(1..6),dp;
+ideal I = cyclic(6);
+
+//=== Amrhein
+ring R = 0,(a,b,c,d,e,f),dp;
+ideal I = 2fb+2ec+d2+a2+a,
+          2fc+2ed+2ba+b,
+          2fd+e2+2ca+c+b2,
+          2fe+2da+d+2cb,
+          f2+2ea+e+2db+c2,
+          2fa+f+2eb+2dc;
+
+//=== Becker-Niermann
+ring R = 0,(x,y,z),dp;
+ideal I = x2+xy2z-2xy+y4+y2+z2,
+          -x3y2+xy2z+xyz3-2xy+y4,
+          -2x2y+xy4+yz4-3;
+
+//=== Roczen
+ring R = 0,(a,b,c,d,e,f,g,h,k,o),dp;
+ideal I = o+1, k4+k, hk, h4+h, gk, gh, g3+h3+k3+1,
+          fk, f4+f, eh, ef, f3h3+e3k3+e3+f3+h3+k3+1,
+          e3g+f3g+g, e4+e, dh3+dk3+d, dg, df, de,
+          d3+e3+f3+1, e2g2+d2h2+c, f2g2+d2k2+b,
+          f2h2+e2k2+a;
+
+//=== FourBodyProblem
+//=== 4 bodies with equal masses, before symmetrisation.
+//=== We are looking for the real positive solutions
+ring R = 0,(B,b,D,d,F,f),dp;
+ideal I = (b-d)*(B-D)-2*F+2,
+          (b-d)*(B+D-2*F)+2*(B-D),
+          (b-d)^2-2*(b+d)+f+1,
+          B^2*b^3-1,D^2*d^3-1,F^2*f^3-1;
+
+//=== Reimer_5
+ring R = 0,(x,y,z,t,u),dp;
+ideal I = 2x2-2y2+2z2-2t2+2u2-1,
+          2x3-2y3+2z3-2t3+2u3-1,
+          2x4-2y4+2z4-2t4+2u4-1,
+          2x5-2y5+2z5-2t5+2u5-1,
+          2x6-2y6+2z6-2t6+2u6-1;
+
+//=== ZeroDim.example_12
+ring R = 0, (x, y, z), lp;
+ideal I = 7xy+x+3yz+4y+2z+10,
+          x3+x2y+3xyz+5xy+3x+2y3+6y2z+yz+1,
+          3x4+2x2y2+3x2y+4x2z2+xyz+xz2+6y2z+5z4;
+
+//=== ZeroDim.example_27
+ring R = 0, (w, x, y, z), lp;
+ideal I = -2w2+9wx+9wy-7wz-4w+8x2+9xy-3xz+8x+6y2-7yz+4y-6z2+8z+2,
+          3w2-5wx-3wy-6wz+9w+4x2+2xy-2xz+7x+9y2+6yz+5y+7z2+7z+5,
+          7w2+5wx+3wy-5wz-5w+2x2+9xy-7xz+4x-4y2-5yz+6y-4z2-9z+2,
+          8w2+5wx-4wy+2wz+3w+5x2+2xy-7xz-7x+7y2-8yz-7y+7z2-8z+8;
+
+//=== Cassou_1
+ring R = 0, (b,c,d,e), dp;
+ideal I = 6b4c3+21b4c2d+15b4cd2+9b4d3+36b4c2+84b4cd+30b4d2+72b4c+84b4d-8b2c2e
+          -28b2cde+36b2d2e+48b4-32b2ce-56b2de-144b2c-648b2d-32b2e-288b2-120,
+          9b4c4+30b4c3d+39b4c2d2+18b4cd3+72b4c3+180b4c2d+156b4cd2+36b4d3+216b4c2
+          +360b4cd+156b4d2-24b2c3e-16b2c2de+16b2cd2e+24b2d3e+288b4c+240b4d
+          -144b2c2e+32b2d2e+144b4-432b2c2-720b2cd-432b2d2-288b2ce+16c2e2-32cde2
+          +16d2e2-1728b2c-1440b2d-192b2e+64ce2-64de2-1728b2+576ce-576de+64e2
+          -240c+1152e+4704,
+          -15b2c3e+15b2c2de-90b2c2e+60b2cde-81b2c2+216b2cd-162b2d2-180b2ce
+          +60b2de+40c2e2-80cde2+40d2e2-324b2c+432b2d-120b2e+160ce2-160de2-324b2
+          +1008ce-1008de+160e2+2016e+5184,
+          -4b2c2+4b2cd-3b2d2-16b2c+8b2d-16b2+22ce-22de+44e+261;
+
+================================================================================
+
+The following timings are conducted on an Intel Xeon X5460 with 4 CPUs, 3.16 GHz
+each, 64 GB RAM under the Gentoo Linux operating system by using the 32-bit
+version of Singular 3-1-1.
+The results of the timinings are summarized in the following table where
+assPrimes* denotes the parallelized version of the algorithm on 4 CPUs and
+ (1) approach of Eisenbud, Hunecke, Vasconcelos (cf. specialAlgDepEHV),
+ (2) approach of Gianni, Trager, Zacharias      (cf. specialAlgDepGTZ),
+ (3) approach of Monico                         (cf. specialAlgDepMonico).
+
+Example             | minAssGTZ |     assPrimes         assPrimes*
+                    |           |  (1)   (2)   (3)   (1)   (2)   (3)
+--------------------------------------------------------------------
+Cyclic_6            |      5    |    5    10     7     4     7     6
+Amrhein             |      1    |    3     3     5     1     2    21
+Becker-Niermann     |      -    |    0     0     1     0     0     0
+Roczen              |      0    |    3     2     0     2     4     1
+FourBodyProblem     |      -    |  139   139   148    96    83    96
+Reimer_5            |      -    |  132   128   175    97    70   103
+ZeroDim.example_12  |    170    |  125   125   125    67    68    63
+ZeroDim.example_27  |     27    |  215   226   215   113   117   108
+Cassou_1            |    525    |  112   112   112    56    56    57
+
+minAssGTZ (cf. primdec_lib) runs out of memory for Becker-Niermann,
+FourBodyProblem and Reimer_5.
+
+================================================================================
+
+//=== One component at the origin
+
+ring R = 0, (x,y), dp;
+poly f1 = (y5 + y4x7 + 2x8);
+poly f2 = (y3 + 7x4);
+poly f3 = (y7 + 2x12);
+poly f = f1*f2*f3 + y19;
+ideal I = f, diff(f, x), diff(f, y);
+
+ring R = 0, (x,y), dp;
+poly f1 = (y5 + y4x7 + 2x8);
+poly f2 = (y3 + 7x4);
+poly f3 = (y7 + 2x12);
+poly f4 = (y11 + 2x18);
+poly f = f1*f2*f3*f4 + y30;
+ideal I = f, diff(f, x), diff(f, y);
+
+ring R = 0, (x,y), dp;
+poly f1 = (y15 + y14x7 + 2x18);
+poly f2 = (y13 + 7x14);
+poly f3 = (y17 + 2x22);
+poly f = f1*f2*f3 + y49;
+ideal I = f, diff(f, x), diff(f, y);
+
+ring R = 0, (x,y), dp;
+poly f1 = (y15 + y14x20 + 2x38);
+poly f2 = (y19 + 3y17x50 + 7x52);
+poly f = f1*f2 + y36;
+ideal I = f, diff(f, x), diff(f, y);
+
+//=== Several components
+
+ring R = 0, (x,y), dp;
+poly f1 = (y5 + y4x7 + 2x8);
+poly f2 = (y13 + 7x14);
+poly f = f1*subst(f2, x, x-3, y, y+5);
+ideal I = f, diff(f, x), diff(f, y);
+
+ring R = 0, (x,y), dp;
+poly f1 = (y5  + y4x7 + 2x8);
+poly f2 = (y3 + 7x4);
+poly f3 = (y7 + 2x12);
+poly f = f1*f2*subst(f3, y, y+5);
+ideal I = f, diff(f, x), diff(f, y);
+
+ring R = 0, (x,y), dp;
+poly f1 = (y5  + 2x8);
+poly f2 = (y3 + 7x4);
+poly f3 = (y7 + 2x12);
+poly f = f1*subst(f2,x,x-1)*subst(f3, y, y+5);
+ideal I = f, diff(f, x), diff(f, y);
+*/
+
diff --git a/Singular/LIB/atkins.lib b/Singular/LIB/atkins.lib
new file mode 100644
index 0000000..a6b14f4
--- /dev/null
+++ b/Singular/LIB/atkins.lib
@@ -0,0 +1,1205 @@
+///////////////////////////////////////////////////////////////////////////////
+version="version atkins.lib 4.0.0.1 Jun_2014 ";
+category="Teaching";
+info="
+LIBRARY:  atkins.lib     Procedures for teaching cryptography
+AUTHOR:                  Stefan Steidel, steidel at mathematik.uni-kl.de
+
+NOTE: The library contains auxiliary procedures to compute the elliptic
+      curve primality test of Atkin and the Atkin's Test itself.
+      The library is intended to be used for teaching purposes but not
+      for serious computations. Sufficiently high printlevel allows to
+      control each step, thus illustrating the algorithms at work.
+
+
+PROCEDURES:
+  newTest(L,D)              checks if number D already exists in list L
+  bubblesort(L)             sorts elements of the list L
+  disc(N,k)                 generates a list of negative discriminants
+  Cornacchia(d,p)           computes solution (x,y) for x^2+d*y^2=p
+  CornacchiaModified(D,p)   computes solution (x,y) for x^2+|D|*y^2=4p
+  maximum(L)                computes the maximal number contained in L
+  sqr(w,k)                  computes the square root of w w.r.t. accuracy k
+  expo(z,k)                 computes exp(z)
+  jOft(t,k)                 computes the j-invariant of t
+  round(r)                  rounds r to the nearest number out of Z
+  HilbertClassPoly(D,k)     computes the Hilbert Class Polynomial
+  rootsModp(p,P)            computes roots of the polynomial P modulo p
+  wUnit(D)                  computes the number of units in Q(sqr(D))
+  Atkin(N,K,B)              tries to prove that N is prime
+
+";
+
+LIB "crypto.lib";
+LIB "general.lib";
+LIB "ntsolve.lib";
+LIB "inout.lib";
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc newTest(list L, def D)
+"USAGE: newTest(L,D);
+RETURN:  1, if D does not already exist in L,
+        -1, if D does already exist in L
+EXAMPLE:example new; shows an example
+"
+{
+  int a=1;                // a=1 means: D does not already exist in L
+  int i;
+  for(i=1;i<=size(L);i++)
+  {
+    if(D==L[i])
+    {
+      a=-1;                 // a=-1 means: D does already exist in L
+      break;
+    }
+  }
+ return(a);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+    ring r = 0,x,dp;
+    list L=8976,-223456,556,-778,3,-55603,45,766677;
+    number D=-55603;
+    newTest(L,D);
+}
+
+
+proc bubblesort(list L)
+"USAGE: bubblesort(L);
+RETURN: list L, sort in decreasing order
+EXAMPLE:example bubblesort; shows an example
+"
+{
+  def b;
+  int n,i,j;
+  while(j==0)
+  {
+    i=i+1;
+    j=1;
+    for(n=1;n<=size(L)-i;n++)
+    {
+      if(L[n]<L[n+1])
+      {
+        b=L[n];
+        L[n]=L[n+1];
+        L[n+1]=b;
+        j=0;
+      }
+    }
+  }
+  return(L);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+    ring r = 0,x,dp;
+    list L=-567,-233,446,12,-34,8907;
+    bubblesort(L);
+}
+
+
+proc disc(bigint N, int k)
+"USAGE: disc(N,k);
+RETURN: list L of negative discriminants D, sorted in decreasing order
+ASSUME: D<0, D kongruent 0 or 1 modulo 4 and |D|<4N
+NOTE:   D=b^2-4*a, where 0<=b<=k and intPart((b^2)/4)+1<=a<=k for each b
+EXAMPLE:example disc; shows an example
+"
+{
+  list L=-3,-4,-7;
+  bigint D;
+  bigint B;
+  int a,b;
+  for(b=0;b<=k;b++)
+  {
+    B=b^2;
+    for(a=int(B div 4)+1;a<=k;a++)
+    {
+      D=-4*a+B;
+      if((D<0)&&((D mod 4)!=-2)&&((D mod 4)!=-1)&&(absValue(D)<4*N)&&(newTest(L,D)==1))
+      {
+        L[size(L)+1]=D;
+      }
+    }
+  }
+  L=bubblesort(L);
+  return(L);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+    disc(2003,50);
+}
+
+proc Cornacchia(bigint d, bigint p)
+"USAGE: Cornacchia(d,p);
+RETURN: x,y such that x^2+d*y^2=p with p prime,
+        -1, if the Diophantine equation has no solution,
+         0, if the parameters are wrong selected
+ASSUME: 0<d<p
+EXAMPLE:example Cornacchia; shows an example
+"
+{
+  if((d<0)||(p<d))              // (0)[Test if assumptions well-defined]
+  {
+    return(0);
+    // ERROR("Parameters wrong selected! It has to be 0<d<p!");
+  }
+  else
+  {
+    bigint k,x(0),a,b,l,r,c,i;
+
+    k=Jacobi(-d,p);             // (1)[Test if residue]
+    if(k==-1)
+    {
+      return(-1);
+      // ERROR("The Diophantine equation has no solution!");
+    }
+    else
+    {
+       x(0)=squareRoot(-d,p);   // (2)[Compute square root]
+       if((p div 2>=x(0))||(p<=x(0)))
+       {
+           x(0)=-x(0) mod p+p;
+       }
+       a=p;
+       b=x(0);
+       l=intRoot(p);
+       while(b>l)               // (3)[Euclidean algorithm]
+       {
+          r=a mod b;
+          a=b;
+          b=r;
+       }
+       c=(p-b^2) div d;             // (4)[Test solution]
+       i=intRoot(c);
+       if((((p-b^2) mod d)!=0)||(c!=i^2))
+       {
+          return(-1);
+       }
+       else
+       {
+          list L=b,i;
+          return(L);
+       }
+    }
+  }
+}
+example
+{ "EXAMPLE:"; echo = 2;
+    Cornacchia(55,9551);
+}
+
+
+proc CornacchiaModified(bigint D, bigint p)
+"USAGE: CornacchiaModified(D,p);
+RETURN: x,y such that x^2+|D|*y^2=p with p prime,
+        -1, if the Diophantine equation has no solution,
+         0, if the parameters are wrong selected
+ASSUME: D<0, D kongruent 0 or 1 modulo 4 and |D|<4p
+EXAMPLE:example CornacchiaModified; shows an example
+"
+{
+  if((D>=0)||((D mod 4)==-2)||((D mod 4)==-1)||(absValue(D)>=4*p))
+  {                                  // (0)[Test if assumptions well-defined]
+    return(0);
+    // ERROR("Parameters wrong selected!");
+  }
+  else
+  {
+    if(p==2)                         // (1)[Case p=2]
+    {
+      if((D+8)==intRoot(D+8)^2)
+      {
+        return(intRoot(D+8),1);
+      }
+      else
+      {
+        return(-1);
+        // ERROR("The Diophantine equation has no solution!");
+      }
+    }
+    else
+    {
+      bigint k,x(0),a,b,l,r,c;
+      k=Jacobi(D,p);                 // (2)[Test if residue]
+      if(k==-1)
+      {
+        return(-1);
+        // ERROR("The Diophantine equation has no solution!");
+      }
+      else
+      {
+        x(0)=squareRoot(D,p);        // (3)[Compute square root]
+        if((x(0) mod 2)!=(-(D mod 2))) // D is <0
+        {
+          x(0)=p-x(0);
+        }
+        a=2*p;
+        b=x(0);
+        l=intRoot(4*p);
+        while(b>l)                   // (4)[Euclidean algorithm]
+        {
+          r=a mod b;
+          a=b;
+          b=r;
+        }
+        c=(4*p-b^2) div absValue(D);     // (5)[Test solution]
+        bigint root_c=intRoot(c);
+        if((((4*p-b^2) mod absValue(D))!=0)||(c!=root_c^2))
+        {
+          return(-1);
+          // ERROR("The Diophantine equation has no solution!");
+        }
+        else
+        {
+          list L=b,root_c;
+          return(L);
+        }
+      }
+    }
+  }
+}
+example
+{ "EXAMPLE:"; echo = 2;
+    CornacchiaModified(-107,1319);
+}
+
+
+static proc pFactor1(number n,int B, list P)
+"USAGE: pFactor1(n,B,P); n to be factorized, B a bound , P a list of primes
+RETURN: a list of factors of n or the message: no factor found
+NOTE:   Pollard's p-factorization
+        creates the product k of powers of primes (bounded by B)  from
+        the list P with the idea that for a prime divisor p of n p-1|k
+        then p devides gcd(a^k-1,n) for some random a
+EXAMPLE:example pFactor1; shows an example
+"
+{
+  int i;
+  number k=1;
+  number w;
+  while(i<size(P))
+  {
+    i++;
+    w=P[i];
+    if(w>B) {break;}
+    while(w*P[i]<=B)
+    {
+      w=w*P[i];
+    }
+    k=k*w;
+  }
+  number a=random(2,2147483629);
+  number d=gcd(powerN(a,k,n)-1,n);
+  if((d>1)&&(d<n)){return(d);}
+  return(n);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring R = 0,z,dp;
+   list L=primList(1000);
+   pFactor1(1241143,13,L);
+   number h=10;
+   h=h^30+25;
+   pFactor1(h,20,L);
+}
+
+
+proc maximum(list L)
+"USAGE: maximum(list L);
+RETURN: the maximal number contained in list L
+EXAMPLE:example maximum; shows an example
+"
+{
+  number max=L[1];
+  int i;
+  for(i=2;i<=size(L);i++)
+  {
+    if(L[i]>max)
+    {
+      max=L[i];
+    }
+  }
+  return(max);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+    ring r = 0,x,dp;
+    list L=465,867,1233,4567,776544,233445,2334,556;
+    maximum(L);
+}
+
+
+static proc cmod(number x, number y)
+"USAGE: cmod(x,y);
+RETURN: x mod y
+ASSUME: x,y out of Z and x,y<=2147483647
+NOTE:   this algorithm is a helping procedure to be able to calculate
+        x mod y with x,y out of Z while working in the complex field
+EXAMPLE:example cmod; shows an example
+"
+{
+  int rest=int(x-y*int(x/y));
+  if(rest<0)
+  {
+    rest=rest+int(y);
+  }
+  return(rest);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+    ring r = (complex,30,i),x,dp;
+    number x=-1004456;
+    number y=1233;
+    cmod(x,y);
+}
+
+
+proc sqr(number w, int k)
+"USAGE: sqr(w,k);
+RETURN: the square root of w
+ASSUME: w>=0
+NOTE:   k describes the number of decimals being calculated in the real numbers,
+        k, intPart(k/5) are inputs for the procedure "nt_solve"
+EXAMPLE:example sqr; shows an example
+"
+{
+  poly f=var(1)^2-w;
+  def S=basering;
+  ring R=(real,k),var(1),dp;
+  poly f=imap(S,f);
+  ideal I=nt_solve(f,1.1,list(k,k div 5));
+  number c=leadcoef(I[1]);
+  setring S;
+  number c=imap(R,c);
+  return(c);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+    ring R = (real,60),x,dp;
+    number ww=288469650108669535726081;
+    sqr(ww,60);
+}
+
+
+proc expo(number z, int k)
+"USAGE: expo(z,k);
+RETURN: e^z to the order k
+NOTE:   k describes the number of summands being calculated in the exponential power series
+EXAMPLE:example expo; shows an example
+"
+{
+  number q=1;
+  number e=1;
+  int n;
+  for(n=1;n<=k;n++)
+  {
+    q=q*z/n;
+    e=e+q;
+  }
+  return(e);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+    ring r = (real,30),x,dp;
+    number z=40.35;
+    expo(z,1000);
+}
+
+
+proc jOft(number t, int k)
+"USAGE: jOft(t,k);
+RETURN: the j-invariant of t
+ASSUME: t is a complex number with positive imaginary part
+NOTE:   k describes the number of summands being calculated in the power series,
+        10*k is input for the procedure @code{expo}
+EXAMPLE:example jOft; shows an example
+"
+{
+  number q1,q2,qr1,qi1,tr,ti,m1,m2,f,j;
+
+  number pi=3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094330572703657595919530921861173819326117931051185480744623799627495673518857527 [...]
+
+  tr=repart(t);
+  ti=impart(t);
+  if(tr==-1/2){qr1=-1;}
+  else
+  {
+    if(tr==0){qr1=1;}
+    else
+    {
+      tr=tr-round(tr);
+      qr1=expo(2*i*pi*tr,10*k);
+    }
+  }
+
+  qi1=expo(-pi*ti,10*k);
+  q1=qr1*qi1^2;
+  q2=q1^2;
+
+  int n=1;
+  while(n<=k)
+  {
+    m1=m1+(-1)^n*(q1^(n*(3*n-1) div 2)+q1^(n*(3*n+1) div 2));
+    m2=m2+(-1)^n*(q2^(n*(3*n-1) div 2)+q2^(n*(3*n+1) div 2));
+    n++;
+  }
+
+  f=q1*((1+m2)/(1+m1))^24;
+
+  j=(256*f+1)^3/f;
+  return(j);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+    ring r = (complex,30,i),x,dp;
+    number t=(-7+i*sqr(7,250))/2;
+    jOft(t,50);
+}
+
+
+proc round(number r)
+"USAGE: round(r);
+RETURN: the nearest number to r out of Z
+ASSUME: r should be a rational or a real number
+EXAMPLE:example round; shows an example
+"
+{
+  number a=absValue(r);
+  number v=r/a;
+
+  number d=10;
+  int e;
+  while(1)
+  {
+    e=e+1;
+    if(a-d^e<0)
+    {
+      e=e-1;
+      break;
+    }
+  }
+
+  number b=a;
+  int k;
+  for(k=0;k<=e;k++)
+  {
+    while(1)
+    {
+      b=b-d^(e-k);
+      if(b<0)
+      {
+        b=b+d^(e-k);
+        break;
+      }
+    }
+  }
+
+  if(b<1/2)
+  {
+    return(v*(a-b));
+  }
+  else
+  {
+    return(v*(a+1-b));
+  }
+}
+example
+{ "EXAMPLE:"; echo = 2;
+    ring R = (real,50),x,dp;
+    number r=7357683445788723456321.6788643224;
+    round(r);
+}
+
+
+proc HilbertClassPoly(bigint D, int k)
+"USAGE: HilbertClassPoly(D,k);
+RETURN: the monic polynomial of degree h(D) in Z[X] of which jOft((D+sqr(D))/2) is a root
+ASSUME: D is a negative discriminant
+NOTE:   k is input for the procedure "jOft",
+        5*k is input for the procedure "sqr",
+        10*k describes the number of decimals being calculated in the complex numbers
+EXAMPLE:example HilbertClassPoly; shows an example
+"
+{
+  if(D>=0)                     // (0)[Test if assumptions well-defined]
+  {
+    ERROR("Parameter wrong selected!");
+  }
+  else
+  {
+    def S=basering;
+
+    string s1,s2,s3;
+    bigint B=intRoot(absValue(D) div 3);
+
+    ring C=(complex,10*k,i),x,dp;
+    number DD=D;
+
+    poly P=1;                  // (1)[Initialize]
+    number b=cmod(DD,2);
+
+    number t,a,g,tau,j;
+    list L;
+
+    bigint a1,b1,t1,g1;
+    int step=2;
+    while(1)
+    {
+      if(step==2)              // (2)[Initialize a]
+      {
+        t=(b^2-DD)/4;
+        L=b,1;
+        a=maximum(L);
+        step=3;
+      }
+
+      if(step==3)              // (3)[Test]
+      {
+        if((cmod(t,a)!=0))
+        {
+          step=4;
+        }
+        else
+        {
+          s1=string(a);
+          s2=string(b);
+          s3=string(t);
+
+          execute("a1="+s1+";");
+          execute("b1="+s2+";");
+          execute("t1="+s3+";");
+          g1=gcd(gcd(a1,b1),t1 div a1);
+          setring C;
+          g=g1;
+
+          if(g!=1)
+          {
+            step=4;
+          }
+          else
+          {
+            tau=(-b+i*sqr(absValue(DD),5*k))/(2*a);
+            j=jOft(tau,k);
+            if((a==b)||(a^2==t)||(b==0))
+            {
+              P=P*(var(1)-repart(j));
+              step=4;
+            }
+            else
+            {
+              P=P*(var(1)^2-2*repart(j)*var(1)+repart(j)^2+impart(j)^2);
+              step=4;
+            }
+          }
+        }
+      }
+
+      if(step==4)              // (4)[Loop on a]
+      {
+        a=a+1;
+        if(a^2<=t)
+        {
+          step=3;
+          continue;
+        }
+        else
+        {
+          step=5;
+        }
+      }
+
+      if(step==5)              // (5)[Loop on b]
+      {
+        b=b+2;
+        if(b<=B)
+        {
+          step=2;
+        }
+        else
+        {
+          break;
+        }
+      }
+    }
+
+    matrix M=coeffs(P,var(1));
+
+    list liste;
+    int n;
+    for(n=1;n<=nrows(M);n++)
+    {
+      liste[n]=round(repart(number(M[n,1])));
+    }
+
+    poly Q;
+    int m;
+    for(m=1;m<=size(liste);m++)
+    {
+      Q=Q+liste[m]*var(1)^(m-1);
+    }
+
+    string s=string(Q);
+    setring S;
+    execute("poly Q="+s+";");
+    return(Q);
+  }
+}
+example
+{ "EXAMPLE:"; echo = 2;
+    ring r = 0,x,dp;
+    bigint D=-23;
+    HilbertClassPoly(D,50);
+}
+
+
+proc rootsModp(int p, poly P)
+"USAGE: rootsModp(p,P);
+RETURN: list of roots of the polynomial P modulo p with p prime
+ASSUME: p>=3
+NOTE:   this algorithm will be called recursively, and it is understood
+        that all the operations are done in Z/pZ (excepting squareRoot(d,p))
+EXAMPLE:example rootsModp; shows an example
+"
+{
+  if(p<3)                                 // (0)[Test if assumptions well-defined]
+  {
+    ERROR("Parameter wrong selected, since p<3!");
+  }
+  else
+  {
+    def S=basering;
+    ring R=p,var(1),dp;
+
+    poly P=imap(S,P);
+    number d;
+    int a;
+    list L;
+
+    poly A=gcd(var(1)^p-var(1),P);        // (1)[Isolate roots in Z/pZ]
+    if(subst(A,var(1),0)==0)
+    {
+      L[1]=0;
+      A=A/var(1);
+    }
+
+    if(deg(A)==0)                         // (2)[Small degree?]
+    {
+      return(L);
+    }
+
+    if(deg(A)==1)
+    {
+      matrix M=coeffs(A,var(1));
+      L[size(L)+1]=-leadcoef(M[1,1])/leadcoef(M[2,1]);
+      setring S;
+      list L=imap(R,L);
+      return(L);
+    }
+
+    if(deg(A)==2)
+    {
+      matrix M=coeffs(A,var(1));
+      d=leadcoef(M[2,1])^2-4*leadcoef(M[1,1])*leadcoef(M[3,1]);
+
+      ring T=0,var(1),dp;
+      number d=imap(R,d);
+      number e=squareRoot(bigint(d),bigint(p));
+      setring R;
+      number e=imap(T,e);
+
+      L[size(L)+1]=(-leadcoef(M[2,1])+e)/(2*leadcoef(M[3,1]));
+      L[size(L)+1]=(-leadcoef(M[2,1])-e)/(2*leadcoef(M[3,1]));
+      setring S;
+      list L=imap(R,L);
+      return(L);
+    }
+
+    poly B=1;                             // (3)[Random splitting]
+    poly C;
+    while((deg(B)==0)||(deg(B)==deg(A)))
+    {
+      a=random(0,p-1);
+      B=gcd((var(1)+a)^((p-1) div 2)-1,A);
+      C=A/B;
+    }
+
+    setring S;                            // (4)[Recurse]
+    poly B=imap(R,B);
+    poly C=imap(R,C);
+    list l=L+rootsModp(p,B)+rootsModp(p,C);
+    return(l);
+  }
+}
+example
+{ "EXAMPLE:"; echo = 2;
+    ring r = 0,x,dp;
+    poly f=x4+2x3-5x2+x;
+    rootsModp(7,f);
+    poly g=x5+112x4+655x3+551x2+1129x+831;
+    rootsModp(1223,g);
+}
+
+
+proc wUnit(bigint D)
+"USAGE: wUnit(D);
+RETURN: the number of roots of unity in the quadratic order of discriminant D
+ASSUME: D<0 a discriminant kongruent to 0 or 1 modulo 4
+EXAMPLE:example w; shows an example
+"
+{
+  if((D>=0)||((D mod 4)==2)||((D mod 4)==3))
+  {
+    ERROR("Parameter wrong selected!");
+  }
+  else
+  {
+    if(D<-4) {return(2);}
+    if(D==-4){return(4);}
+    if(D==-3){return(6);}
+  }
+}
+example
+{ "EXAMPLE:"; echo = 2;
+    bigint D=-3;
+    wUnit(D);
+}
+
+
+proc Atkin(number N, int K, int B)
+"USAGE: Atkin(N,K,B);
+RETURN:  1, if N is prime,
+        -1, if N is not prime,
+         0, if the algorithm is not applicable, since there are too few discriminants
+ASSUME: N is coprime to 6 and different from 1
+NOTE:   K/2 is input for the procedure "disc",@*
+        K is input for the procedure "HilbertClassPoly",@*
+        B describes the number of recursions being calculated.@*
+        The basis of the algorithm is the following theorem:
+          Let N be an integer coprime to 6 and different from 1 and E be an
+          ellipic curve modulo N.@* Assume that we know an integer m and a
+          point P of E(Z/NZ) satisfying the following conditions.@*
+           (1) There exists a prime divisor q of m such that q > (4-th root(N)+1)^2.@*
+           (2) m*P = O(E) = (0:1:0).@*
+           (3) (m/q)*P = (x:y:t) with t element of (Z/NZ)*.@*
+          Then N is prime.
+EXAMPLE:example Atkin; shows an example
+"
+{
+  if(N==1)           {return(-1);} // (0)[Test if assumptions well-defined]
+  if((N==2)||(N==3)) {return(1);}
+  if(gcd(N,6)!=1)
+  {
+    if(printlevel>=1) {"gcd(N,6) = "+string(gcd(N,6));pause();"";}
+    return(-1);
+  }
+  else
+  {
+    int i;                         // (1)[Initialize]
+    int n(i);
+    number N(i)=N;
+    if(printlevel>=1) {"Set i = 0, n = 0 and N(i) = N(0)= "+string(N(i))+".";pause();"";}
+
+    // declarations:
+    int j(0),j(1),j(2),j(3),j(4),k;    // running indices
+    list L;                            // all primes smaller than 1000
+    list H;                            // sequence of negative discriminants
+    number D;                          // discriminant out of H
+    list L1,L2,S,S1,S2,R;              // lists of relevant elements
+    list P,P1,P2;                      // elliptic points on E(Z/N(i)Z)
+    number m,q;                        // m=|E(Z/N(i)Z)| and q|m
+    number a,b,j,c;                    // characterize E(Z/N(i)Z)
+    number g,u;                        // g out of Z/N(i)Z, u=Jacobi(g,N(i))
+    poly T;                            // T=HilbertClassPoly(D,K)
+    matrix M;                          // M contains the coefficients of T
+
+    if(printlevel>=1) {"List H of possibly suitable discriminants will be calculated.";}
+    H=disc(bigint(N),K div 2);
+    if(printlevel>=1) {"H = "+string(H);pause();"";}
+
+    int step=2;
+    while(1)
+    {
+      if(step==2)                  // (2)[Is N(i) small??]
+      {
+        L=5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509,521,523,541,547,557,563,569,571,577,587,593,599,601,607,613,617,619,631,641,643,647,653,659,661,673,677,683,691,701,709,719,727 [...]
+        for(j(0)=1;j(0)<=size(L);j(0)++)
+        {
+          if(N(i)==L[j(0)]){return(1);}
+          if(((N(i) mod L[j(0)])==0)&&(N(i)!=L[j(0)]))
+          {
+            if(printlevel>=1) {"N("+string(i)+") = "+string(N(i))+" is divisible by "+string(L[j(0)])+".";pause();"";}
+            step=14;
+            break;
+          }
+        }
+        if(step==2)
+        {
+          step=3;
+        }
+      }
+
+      if(step==3)                  // (3)[Choose next discriminant]
+      {
+        n(i)=n(i)+1;
+        if(n(i)==size(H)+1)
+        {
+          if(printlevel>=1) {"Algorithm is not applicable, since there are not enough suitable discriminants.";
+                             "Increase the parameter of accuracy K and start the algorithm again.";pause();"";}
+          return(0);
+        }
+        D=H[n(i)];
+        if(printlevel>=1) {"Next discriminant D will be chosen. D = "+string(D)+".";pause();"";}
+        if(Jacobi(D,N(i))!=1)
+        {
+          if(printlevel>=1) {"Jacobi(D,N("+string(i)+")) = "+string(Jacobi(D,N(i)));pause();"";}
+          continue;
+        }
+        else
+        {
+          L1=CornacchiaModified(D,N(i));
+          if(size(L1)>1)
+          {
+            if(printlevel>=1) {"The solution (x,y) of the equation x^2+|D|y^2 = 4N("+string(i)+") is";L1;pause();"";}
+            step=4;
+          }
+          else
+          {
+            if(L1[1]==-1)
+            {
+              if(printlevel>=1) {"The equation x^2+|D|y^2 = 4N("+string(i)+") has no solution.";pause();"";}
+              continue;
+            }
+            if(L1[1]==0)
+            {
+              if(printLevel>=1) {"Algorithm is not applicable for N("+string(i)+") = "+string(N(i))+",";
+                                 "since there are not enough suitable discriminants.";pause();"";}
+              step=14;
+            }
+          }
+        }
+      }
+
+      if(step==4)                  // (4)[Factor m]
+      {
+        if(printlevel>=1) {"List L2 of possible m = |E(Z/N("+string(i)+")Z)| will be calculated.";}
+        if(absValue(L1[1])^2<=4*N(i)) {L2=N(i)+1+L1[1],N(i)+1-L1[1];}
+        if(D==-4)
+        {
+          if(absValue(2*L1[2])^2<=4*N(i)) {L2[size(L2)+1]=N(i)+1+2*L1[2];
+                                           L2[size(L2)+1]=N(i)+1-2*L1[2];}
+        }
+// At this point "<=4*N(i)" has been replaced by "<=16*N(i)".
+        if(D==-3)
+        {
+          if(absValue(L1[1]+3*L1[2])^2<=16*N(i)) {L2[size(L2)+1]=N(i)+1+(L1[1]+3*L1[2])/2;
+                                                  L2[size(L2)+1]=N(i)+1-(L1[1]+3*L1[2])/2;}
+          if(absValue(L1[1]-3*L1[2])^2<=16*N(i)) {L2[size(L2)+1]=N(i)+1+(L1[1]-3*L1[2])/2;
+                                                  L2[size(L2)+1]=N(i)+1-(L1[1]-3*L1[2])/2;}
+        }
+///////////////////////////////////////////////////////////////
+        if(size(L2)==0)
+        {
+          if(printlevel>=1) {"Due to the theorem of Hasse there were no possible m = |E(Z/N("+string(i)+")Z)|";
+                             "found for D = "+string(D)+".";}
+          step=3;
+          continue;
+        }
+        else
+        {
+          if(printlevel>=1) {"L2 = ";L2;pause();"";}
+        }
+
+        if(printlevel>=1) {"List S of factors of all possible m will be calculated.";}
+        S=list();
+        for(j(1)=1;j(1)<=size(L2);j(1)++)
+        {
+          m=L2[j(1)];
+          if(m!=0)
+          {
+            S1=PollardRho(m,10000,1,L);
+            S2=pFactor(m,100,L);
+            S[size(S)+1]=list(m,S1+S2);
+          }
+        }
+        if(printlevel>=1) {"S=";S;pause();"";}
+        step=5;
+      }
+
+      if(step==5)                  // (5)[Does a suitable m exist??]
+      {
+        for(j(2)=1;j(2)<=size(S);j(2)++)
+        {
+          m=L2[j(2)];
+          for(j(3)=1;j(3)<=size(S[j(2)][2]);j(3)++)
+          {
+            q=S[j(2)][2][j(3)];
+// sqr(sqr(N(i),50),50) replaces intRoot(intRoot(N(i)))
+            if((q>(sqr(sqr(N(i),50),50)+1)^2) && (MillerRabin(q,5)==1))
+            {
+              step=6;
+              break;
+            }
+//////////////////////////////////////////////////////
+          }
+          if(step==6)
+          {
+            if(printlevel>=1) {"Suitable pair (m,q) has been found such that q|m,";
+                               "q > (4-th root(N("+string(i)+"))+1)^2 and q passes the Miller-Rabin-Test.";
+                               "m = "+string(m)+",";"q = "+string(q);pause();"";}
+            break;
+          }
+          else
+          {
+            step=3;
+          }
+        }
+        if(step==3)
+        {
+          if(printlevel>=1) {"No suitable pair (m,q) has been found such that q|m,";
+                             "q > (4-th root(N("+string(i)+"))+1)^2 and q passes the Miller-Rabin-Test.";
+                              pause();"";}
+          continue;
+        }
+      }
+
+      if(step==6)                  // (6)[Compute elliptic curve]
+      {
+        if(D==-4)
+        {
+          a=-1;
+          b=0;
+          if(printlevel>=1) {"Since D = -4, set a = -1 and b = 0.";pause();"";}
+        }
+        if(D==-3)
+        {
+          a=0;
+          b=-1;
+          if(printlevel>=1) {"Since D = -3, set a = 0 and b = -1.";pause();"";}
+        }
+        if(D<-4)
+        {
+          if(printlevel>=1) {"The minimal polynomial T of j((D+sqr(D))/2) in Z[X] will be calculated for D="+string(D)+".";}
+          T=HilbertClassPoly(D,K);
+          if(printlevel>=1) {"T = "+string(T);pause();"";}
+
+          M=coeffs(T,var(1));
+          T=0;
+
+          for(j(4)=1;j(4)<=nrows(M);j(4)++)
+          {
+            M[j(4),1]=leadcoef(M[j(4),1]) mod N(i);
+            T=T+M[j(4),1]*var(1)^(j(4)-1);
+          }
+          if(printlevel>=1) {"Set T = T mod N("+string(i)+").";"T = "+string(T);pause();"";}
+
+          R=rootsModp(int(N(i)),T);
+          if(deg(T)>size(R))
+          {
+            ERROR("The polynomial T does not completely split into linear factors modulo N("+string(i)+")."
+                  "Increase the parameter of accuracy K and start the algorithm again.");
+          }
+          if(printlevel>=1) {if(deg(T)>1) {"The "+string(deg(T))+" zeroes of T modulo N("+string(i)+") are";
+                                           R;pause();"";}
+                             if(deg(T)==1){"The zero of T modulo N("+string(i)+") is";R;pause();"";}}
+
+          j=R[1];
+          c=j*exgcdN(j-1728,N(i))[1];
+          a=-3*c mod N(i);
+          b=2*c mod N(i);
+          if(printlevel>=1) {"Choose the zero j = "+string(j)+" and set"; "c = j/(j-1728) mod N("+string(i)+"), a = -3c mod N("+string(i)+"), b = 2c mod N("+string(i)+").";
+                             "a = "+string(a)+",";"b = "+string(b);pause();"";}
+        }
+        step=7;
+      }
+
+      if(step==7)                  // (7)[Find g]
+      {
+        if(D==-3)
+        {
+          while(1)
+          {
+            g=random(1,2147483647) mod N(i);
+            u=Jacobi(g,N(i));
+            if((u==-1)&&(powerN(g,(N(i)-1)/3,N(i))!=1))
+            {
+              if(printlevel>=1) {"g = "+string(g);pause();"";}
+              break;
+            }
+          }
+        }
+        else
+        {
+          while(1)
+          {
+            g=random(1,2147483647) mod N(i);
+            u=Jacobi(g,N(i));
+            if(u==-1)
+            {
+              if(printlevel>=1) {"g = "+string(g);pause();"";}
+              break;
+            }
+          }
+        }
+        step=8;
+      }
+
+      if(step==8)                  // (8)[Find P]
+      {
+        if(printlevel>=1) {"A random point P on the elliptic curve corresponding";
+                           "to the equation y^2 = x^3+ax+b for";"N("+string(i)+") = "+string(N(i))+",";
+                           "   a = "+string(a)+",";"   b = "+string(b);"will be chosen.";}
+        P=ellipticRandomPoint(N(i),a,b);
+        if(printlevel>=1) {"P = ("+string(P)+")";pause();"";}
+
+        if(size(P)==1)
+        {
+          step=14;
+        }
+        else
+        {
+          step=9;
+        }
+      }
+
+      if(step==9)                  // (9)[Find right curve]
+      {
+        if(printlevel>=1) {"The points P2 = (m/q)*P and P1 = q*P2 on the curve will be calculated.";}
+        P2=ellipticMult(N(i),a,b,P,m/q);
+        P1=ellipticMult(N(i),a,b,P2,q);
+        if(printlevel>=1) {"P1 = ("+string(P1)+"),";"P2 = ("+string(P2)+")";pause();"";}
+
+        if((P1[1]==0)&&(P1[2]==1)&&(P1[3]==0))
+        {
+          step=12;
+        }
+        else
+        {
+          if(printlevel>=1) {"Since P1 != (0:1:0), it holds m != |E(Z/N("+string(i)+")Z)| for the coefficients a = "+string(a)+" and b = "+string(b)+".";
+                             "Therefore choose new coefficients a and b.";pause();"";}
+          step=10;
+        }
+      }
+
+      if(step==10)                 // (10)[Change coefficients]
+      {
+        k=k+1;
+        if(k>=wUnit(bigint(D)))
+        {
+          if(printlevel>=1) {"Since k = wUnit(D) = "+string(k)+", it holds that N("+string(i)+") = "+string(N(i))+" is not prime.";pause();"";}
+          step=14;
+        }
+        else
+        {
+          if(D<-4) {a=a*g^2 mod N(i); b=b*g^3 mod N(i);
+                    if(printlevel>=1) {"Since D < -4, set a = a*g^2 mod N("+string(i)+") and b = b*g^3 mod N("+string(i)+").";
+                                       "a = "+string(a)+",";"b = "+string(b)+",";"k = "+string(k);pause();"";}}
+          if(D==-4){a=a*g mod N(i);
+                    if(printlevel>=1) {"Since D = -4, set a = a*g mod N("+string(i)+").";"a = "+string(a)+",";
+                                       "b = "+string(b)+",";"k = "+string(k);pause();"";}}
+          if(D==-3){b=b*g mod N(i);
+                    if(printlevel>=1) {"Since D = -3, set b = b*g mod N("+string(i)+").";"a = "+string(a)+",";
+                                       "b = "+string(b)+",";"k = "+string(k);pause();"";}}
+          step=8;
+          continue;
+        }
+      }
+
+      if(step==11)                 // (11)[Find a new P]
+      {
+        if(printlevel>=1) {"A new random point P on the elliptic curve will be chosen,";
+                           "since also P2 = (0:1:0).";}
+        P=ellipticRandomPoint(N(i),a,b);
+        if(printlevel>=1) {"P = ("+string(P)+")";pause();"";}
+
+        if(size(P)==1)
+        {
+          step=14;
+        }
+        else
+        {
+          if(printlevel>=1) {"The points P2 = (m/q)*P and P1 = q*P2 on the curve will be calculated.";}
+          P2=ellipticMult(N(i),a,b,P,m/q);
+          P1=ellipticMult(N(i),a,b,P2,q);
+          if(printlevel>=1) {"P1 = ("+string(P1)+"),";"P2 = ("+string(P2)+")";pause();"";}
+
+          if((P1[1]!=0)||(P1[2]!=1)||(P1[3]!=0))
+          {
+            if(printlevel>=1) {"Since P1 != (0:1:0), it holds m != |E(Z/N("+string(i)+")Z)| for the coefficients a = "+string(a)+" and b = "+string(b)+".";
+                               "Therefore choose new coefficients a and b.";pause();"";}
+            step=10;
+            continue;
+          }
+          else
+          {
+            step=12;
+          }
+        }
+      }
+
+      if(step==12)                 // (12)[Check P]
+      {
+        if((P2[1]==0)&&(P2[2]==1)&&(P2[3]==0))
+        {
+          step=11;
+          continue;
+        }
+        else
+        {
+          step=13;
+        }
+      }
+
+      if(step==13)                 // (13)[Recurse]
+      {
+        if(i<B)
+        {
+          if(printlevel>=1) {string(i+1)+". Recursion:";"";
+                             "N("+string(i)+") = "+string(N(i))+" suffices the conditions of the underlying theorem,";
+                             "since P1 = (0:1:0) and P2[3] in (Z/N("+string(i)+")Z)*.";"";
+                             "Now check if also the found factor q="+string(q)+" suffices these assumptions.";
+                             "Therefore set i = i+1, N("+string(i+1)+") = q = "+string(q)+" and restart the algorithm.";pause();"";}
+          i=i+1;
+          int n(i);
+          number N(i)=q;
+          k=0;
+          step=2;
+          continue;
+        }
+        else
+        {
+          if(printlevel>=1) {"N(B) = N("+string(i)+") = "+string(N(i))+" suffices the conditions of the underlying theorem,";
+                             "since P1 = (0:1:0) and P2[3] in (Z/N("+string(i)+")Z)*.";
+                             "In particular N = "+string(N)+" is prime.";pause();"";}
+          return(1);
+        }
+      }
+
+      if(step==14)                 // (14)[Backtrack]
+      {
+        if(i>0)
+        {
+          if(printlevel>=1) {"Set i = i-1 and restart the algorithm for N("+string(i-1)+") = "+string(N(i-1))+" with";
+                             "a new discriminant.";pause();"";}
+          i=i-1;
+          k=0;
+          step=3;
+        }
+        else
+        {
+          if(printlevel>=1) {"N(0) = N = "+string(N)+" and therefore N is not prime.";pause();"";}
+          return(-1);
+        }
+      }
+    }
+  }
+}
+example
+{ "EXAMPLE:"; echo = 2;
+    ring R = 0,x,dp;
+    Atkin(7691,100,5);
+    Atkin(3473,10,2);
+    printlevel=1;
+    Atkin(10000079,100,2);
+}
+
diff --git a/Singular/LIB/bfun.lib b/Singular/LIB/bfun.lib
new file mode 100644
index 0000000..520cdcb
--- /dev/null
+++ b/Singular/LIB/bfun.lib
@@ -0,0 +1,1962 @@
+/////////////////////////////////////////////////////////////////////////////
+version="version bfun.lib 4.0.0.0 Jun_2013 "; // $Id: ec07870569d6828b6cb89ea4e65c85db66e7e604 $
+category="Noncommutative";
+info="
+LIBRARY: bfun.lib     Algorithms for b-functions and Bernstein-Sato polynomial
+AUTHORS: Daniel Andres, daniel.andres at math.rwth-aachen.de
+@* Viktor Levandovskyy,      levandov at math.rwth-aachen.de
+
+OVERVIEW:
+Given a polynomial ring R = K[x_1,...,x_n] and a polynomial F in R,
+one is interested in the global b-function (also known as Bernstein-Sato
+polynomial) b(s) in K[s], defined to be the non-zero monic polynomial of minimal
+degree, satisfying a functional identity L * F^{s+1} = b(s) F^s,
+for some operator L in D[s] (* stands for the action of differential operator)@*
+By D one denotes the n-th Weyl algebra
+K<x_1,...,x_n,d_1,...,d_n | d_j x_j = x_j d_j +1>.
+One is interested in the following data:@*
+  - Bernstein-Sato polynomial b(s) in K[s],@*
+  - the list of its roots, which are known to be rational@*
+  - the multiplicities of the roots.@*
+
+There is a constructive definition of a b-function of a holonomic ideal I in D
+(that is, an ideal I in a Weyl algebra D, such that D/I is holonomic module)
+with respect to the given weight vector w: For a polynomial p in D, its initial
+form w.r.t. (-w,w) is defined as the sum of all terms of p which have
+maximal weighted total degree where the weight of x_i is -w_i and the weight
+of d_i is w_i. Let J be the initial ideal of I w.r.t. (-w,w), i.e. the
+K-vector space generated by all initial forms w.r.t (-w,w) of elements of I.
+Put s = w_1 x_1 d_1 + ... + w_n x_n d_n. Then the monic generator b_w(s) of
+the intersection of J with the PID K[s] is called the b-function of I w.r.t.  w.
+Unlike Bernstein-Sato polynomial, general b-function with respect to
+arbitrary weights need not have rational roots at all. However, b-function
+of a holonomic ideal is known to be non-zero as well.
+
+REFERENCES: [SST] Saito, Sturmfels, Takayama: Groebner Deformations of
+Hypergeometric Differential Equations (2000),@*
+Noro: An Efficient Modular Algorithm for Computing the Global b-function,
+(2002).
+
+
+PROCEDURES:
+bfct(f[,s,t,v]);            compute the BS polynomial of f with linear reductions
+bfctSyz(f[,r,s,t,u,v]);     compute the BS polynomial of f with syzygy-solver
+bfctAnn(f[,s]);             compute the BS polynomial of f via Ann f^s + f
+bfctOneGB(f[,s,t]);         compute the BS polynomial of f by just one GB computation
+bfctIdeal(I,w[,s,t]);       compute the b-function of ideal w.r.t. weight
+pIntersect(f,I[,s]);        intersection of ideal with subalgebra K[f] for a polynomial f
+pIntersectSyz(f,I[,p,s,t]); intersection of ideal with subalgebra K[f] with syz-solver
+linReduce(f,I[,s]);         reduce a polynomial by linear reductions w.r.t. ideal
+linReduceIdeal(I,[s,t]);    interreduce generators of ideal by linear reductions
+linSyzSolve(I[,s]);         compute a linear dependency of elements of ideal I
+
+allPositive(v);             checks whether all entries of an intvec are positive
+scalarProd(v,w);            computes the standard scalar product of two intvecs
+vec2poly(v[,i]);            constructs an univariate polynomial with given coefficients
+
+
+SEE ALSO: dmod_lib, dmodapp_lib, dmodvar_lib, gmssing_lib
+
+KEYWORDS: D-module; global Bernstein-Sato polynomial; Bernstein-Sato polynomial; b-function;
+graded Weyl algebra; initial ideal; initial form; principal intersection; linear interreduction;
+initial ideal approach
+";
+
+
+
+/*
+CHANGELOG
+
+03.03.11:
+- simplified scalarProd
+- fixed bug in bfct when user used vars t,Dt
+- now bFactor is used by bfct, bfctAnn, i.e. the static procs
+  addRoot, listofroots are superfluous
+- fixed printlevel/debug message issue in bfct, bfctAnn
+- fixed small issue for zero ideal input in linReduceIdeal
+
+16.03.11
+- fixed bug in linReduceIdeal when ideal contained unlucky constellation
+  of zeros
+- fixed printlevel/debug message issue in linReduceIdeal
+*/
+
+
+
+LIB "qhmoduli.lib"; // for Max
+LIB "dmod.lib";     // for SannfsBFCT etc
+LIB "dmodapp.lib";  // for initialIdealW etc
+LIB "nctools.lib";  // for isWeyl etc
+LIB "presolve.lib"; // for valvars
+
+//--------------- auxiliary procedures ----------------------------------------
+
+/*
+static proc gradedWeyl (intvec u,intvec v)
+"USAGE:  gradedWeyl(u,v); u,v intvecs
+RETURN:  a ring, the associated graded ring of the basering w.r.t. u and v
+PURPOSE: compute the associated graded ring of the basering w.r.t. u and v
+ASSUME: basering is a Weyl algebra
+EXAMPLE: example gradedWeyl; shows examples
+NOTE:    u[i] is the weight of x(i), v[i] the weight of D(i).
+@*       u+v has to be a non-negative intvec.
+"
+{
+  // todo check assumption
+  int i;
+  def save = basering;
+  int n = nvars(save) div 2;
+  if (nrows(u)<>n || nrows(v)<>n)
+  {
+    ERROR("weight vectors have wrong dimension");
+  }
+  intvec uv,gr;
+  uv = u+v;
+  for (i=1; i<=n; i++)
+  {
+    if (uv[i]>=0)
+    {
+      if (uv[i]==0)
+      {
+        gr[i] = 0;
+      }
+      else
+      {
+        gr[i] = 1;
+      }
+    }
+    else
+    {
+      ERROR("the sum of the weight vectors has to be a non-negative intvec");
+    }
+  }
+  list l = ringlist(save);
+  list l2 = l[2];
+  matrix l6 = l[6];
+  for (i=1; i<=n; i++)
+  {
+    if (gr[i] == 1)
+    {
+       l2[n+i] = "xi("+string(i)+")";
+       l6[i,n+i] = 0;
+    }
+  }
+  l[2] = l2;
+  l[6] = l6;
+  def G = ring(l);
+  return(G);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring @D = 0,(x,y,z,Dx,Dy,Dz),dp;
+  def D = Weyl();
+  setring D;
+  intvec u = -1,-1,1; intvec v = 2,1,1;
+  def G = gradedWeyl(u,v);
+  setring G; G;
+}
+*/
+
+static proc safeVarName (string s)
+{
+  string S = "," + charstr(basering) + "," + varstr(basering) + ",";
+  s = "," + s + ",";
+  while (find(S,s) <> 0)
+  {
+    s[1] = "@";
+    s = "," + s;
+  }
+  s = s[2..size(s)-1];
+  return(s)
+}
+
+proc allPositive (intvec v)
+"USAGE:  allPositive(v);  v an intvec
+RETURN:  int, 1 if all components of v are positive, or 0 otherwise
+PURPOSE: check whether all components of an intvec are positive
+EXAMPLE: example allPositive; shows an example
+"
+{
+  int i;
+  for (i=1; i<=size(v); i++)
+  {
+    if (v[i]<=0)
+    {
+      return(0);
+      break;
+    }
+  }
+  return(1);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  intvec v = 1,2,3;
+  allPositive(v);
+  intvec w = 1,-2,3;
+  allPositive(w);
+}
+
+static proc findFirst (list l, def i)
+"USAGE:  findFirst(l,i);  l a list, i an argument of any type
+RETURN:  int, the position of the first appearance of i in l,
+@*       or 0 if i is not a member of l
+PURPOSE: check whether the second argument is a member of a list
+EXAMPLE: example findFirst; shows an example
+"
+{
+  int j;
+  for (j=1; j<=size(l); j++)
+  {
+    if (l[j]==i)
+    {
+      return(j);
+      break;
+    }
+  }
+  return(0);
+}
+//   findFirst(list(1, 2, list(1)),2);       // seems to be a bit buggy,
+//   findFirst(list(1, 2, list(1)),3);       // but works for the purposes
+//   findFirst(list(1, 2, list(1)),list(1)); // of this library
+//   findFirst(l,list(2));
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,x,dp;
+  list l = 1,2,3;
+  findFirst(l,4);
+  findFirst(l,2);
+}
+
+proc scalarProd (intvec v, intvec w)
+"USAGE:  scalarProd(v,w);  v,w intvecs
+RETURN:  int, the standard scalar product of v and w
+PURPOSE: computes the scalar product of two intvecs
+ASSUME:  the arguments are of the same size
+EXAMPLE: example scalarProd; shows examples
+"
+{
+  if (size(v)!=size(w))
+  {
+    ERROR("non-matching dimensions");
+  }
+  else
+  {
+    intvec u = transpose(v)*w;
+  }
+  return(u[1]);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  intvec v = 1,2,3;
+  intvec w = 4,5,6;
+  scalarProd(v,w);
+}
+
+//-------------- main procedures -------------------------------------------------------
+
+proc linReduceIdeal(ideal I, list #)
+"USAGE:  linReduceIdeal(I [,s,t,u]); I an ideal, s,t,u optional ints
+RETURN:  ideal or list, linear reductum (over field) of I by its elements
+PURPOSE: reduces a list of polys only by linear reductions (no monomial
+@*        multiplications)
+NOTE:    If s<>0, a list consisting of the reduced ideal and the coefficient
+@*       vectors of the used reductions given as module is returned.
+@*       Otherwise (and by default), only the reduced ideal is returned.
+@*       If t<>0 (and by default) all monomials are reduced (if possible),
+@*       otherwise, only leading monomials are reduced.
+@*       If u<>0 (and by default), the ideal is first sorted in increasing order.
+@*       If u is set to 0 and the given ideal is not sorted in the way described,
+@*       the result might not be as expected.
+DISPLAY: If @code{printlevel}=1, progress debug messages will be printed,
+@*       if printlevel>=2, all the debug messages will be printed.
+EXAMPLE: example linReduceIdeal; shows examples
+"
+{
+  // #[1] = remembercoeffs
+  // #[2] = redtail
+  // #[3] = sortideal
+  int ppl = printlevel - voice + 2;
+  int remembercoeffs = 0; // default
+  int redtail        = 1; // default
+  int sortideal      = 1; // default
+  if (size(#)>0)
+  {
+    if (typeof(#[1])=="int" || typeof(#[1])=="number")
+    {
+      remembercoeffs = #[1];
+    }
+    if (size(#)>1)
+    {
+      if (typeof(#[2])=="int" || typeof(#[2])=="number")
+      {
+        redtail = #[2];
+      }
+      if (size(#)>2)
+      {
+        if (typeof(#[3])=="int" || typeof(#[3])=="number")
+        {
+          sortideal = #[3];
+        }
+      }
+    }
+  }
+  int sI = ncols(I);
+  int sZeros = sI - size(I);
+  int i,j,k;
+  ideal J,lmJ,ordJ;
+  list lJ = sort(I);
+  intvec iv,iv2; //todo
+  module M; // for the coefficients
+  // step 1: prepare, e.g. sort I
+  if (sortideal <> 0)
+  {
+    if (sZeros > 0) // I contains zeros
+    {
+      if (remembercoeffs <> 0)
+      {
+        j = 0;
+        k = 0;
+        intvec posNonZero;
+        for (i=1; i<=sI; i++)
+        {
+          if (I[i] == 0)
+          {
+            j++;
+            J[j] = 0;
+            ordJ[j] = -1;
+            M[j] = gen(i);
+          }
+          else
+          {
+            k++;
+            M[k+sZeros] = gen(lJ[2][k]);
+             posNonZero = posNonZero,i;
+          }
+        }
+         posNonZero = posNonZero[2..nrows(posNonZero)];
+         posNonZero = posNonZero[lJ[2]];
+         for (i=1; i<=size(lJ[1]); i++)
+         {
+           M[i+sZeros] = gen(posNonZero[i]);
+         }
+        kill posNonZero;
+      }
+      else
+      {
+        for (i=1; i<=sZeros; i++)
+        {
+          J[i] = 0;
+          ordJ[i] = -1;
+        }
+      }
+      I = J,lJ[1];
+    }
+    else // I contains no zeros
+    {
+      I = lJ[1];
+      if (remembercoeffs <> 0)
+      {
+        for (i=1; i<=size(lJ[1]); i++) { M[i] = gen(lJ[2][i]); }
+      }
+    }
+  }
+  else // assume I is already sorted
+  {
+    if (remembercoeffs <> 0)
+    {
+      for (i=1; i<=ncols(I); i++) { M[i] = gen(i);  }
+    }
+  }
+  dbprint(ppl,"// initially sorted ideal:", I);
+  if (remembercoeffs <> 0) { dbprint(ppl,"// used permutations:", M); }
+  // step 2: reduce leading monomials by linear reductions
+  poly lm,c,redpoly,maxlmJ;
+  J[sZeros+1] = I[sZeros+1];
+  lm = I[sZeros+1];
+  maxlmJ = leadmonom(lm);
+  lmJ[sZeros+1] = maxlmJ;
+  int ordlm,reduction;
+  ordJ[sZeros+1] = ord(lm);
+  vector v;
+  int noRedPast;
+  for (i=sZeros+2; i<=sI; i++)
+  {
+    redpoly = I[i];
+    lm = leadmonom(redpoly);
+    ordlm = ord(lm);
+    if (remembercoeffs <> 0) { v = M[i]; }
+    reduction = 1;
+    while (reduction == 1) // while there was a reduction
+    {
+      noRedPast = i;
+      reduction = 0;
+      for (j=sZeros+1; j<noRedPast; j++)
+      {
+        if (lm == 0) { break; } // nothing more to reduce
+        if (lm > maxlmJ) { break; } //lm is bigger than maximal monomial to reduce with
+        if (ordlm == ordJ[j])
+        {
+          if (lm == lmJ[j])
+          {
+            dbprint(ppl-1,"// reducing " + string(redpoly));
+            dbprint(ppl-1,"//  with " + string(J[j]));
+            c = leadcoef(redpoly)/leadcoef(J[j]);
+            redpoly = redpoly - c*J[j];
+            dbprint(ppl-1,"//  to " + string(redpoly));
+            lm = leadmonom(redpoly);
+            ordlm = ord(lm);
+            if (remembercoeffs <> 0) { M[i] = M[i] - c * M[j]; }
+            noRedPast = j;
+            reduction = 1;
+          }
+        }
+      }
+    }
+    for (j=sZeros+1; j<i; j++)
+    {
+      if (redpoly < J[j]) { break; }
+    }
+    J = insertGenerator(J,redpoly,j);
+    lmJ = insertGenerator(lmJ,lm,j);
+    ordJ = insertGenerator(ordJ,poly(ordlm),j);
+    if (remembercoeffs <> 0)
+    {
+      v = M[i];
+      M = deleteGenerator(M,i);
+      M = insertGenerator(M,v,j);
+    }
+    maxlmJ = lmJ[i];
+  }
+  // step 3: reduce tails by linear reductions as well
+  if (redtail <> 0)
+  {
+    dbprint(ppl,"// finished reducing leading monomials");
+    dbprint(ppl-1,string(J));
+    if (remembercoeffs <> 0) { dbprint(ppl-1,"// used reductions:" + string(M)); }
+    for (i=sZeros+1; i<=sI; i++)
+    {
+      lm = lmJ[i];
+      for (j=i+1; j<=sI; j++)
+      {
+        for (k=2; k<=size(J[j]); k++) // run over all terms in J[j]
+        {
+          if (ordJ[i] == ord(J[j][k]))
+          {
+            if (lm == normalize(J[j][k]))
+            {
+              c = leadcoef(J[j][k])/leadcoef(J[i]);
+              dbprint(ppl-1,"// reducing " + string(J[j]));
+              dbprint(ppl-1,"//  with " + string(J[i]));
+              J[j] = J[j] - c*J[i];
+              dbprint(ppl-1,"//  to " + string(J[j]));
+              if (remembercoeffs <> 0) { M[j] = M[j] - c * M[i]; }
+            }
+          }
+        }
+      }
+    }
+  }
+  if (sI == sZeros) // if I=0,0,...,0, we now have one too much by construction due to sort
+  {
+    J = J[1..sZeros];
+  }
+  if (remembercoeffs <> 0) { return(list(J,M)); }
+  else { return(J); }
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y),dp;
+  ideal I = 3,x+9,y4+5x,2y4+7x+2;
+  linReduceIdeal(I);     // reduces tails
+  linReduceIdeal(I,0,0); // no reductions of tails
+  list l = linReduceIdeal(I,1); // reduces tails and shows reductions used
+  l;
+  module M = I;
+  matrix(l[1]) - M*l[2];
+}
+
+proc linReduce(poly f, ideal I, list #)
+"USAGE:  linReduce(f, I [,s,t,u]); f a poly, I an ideal, s,t,u optional ints
+RETURN:  poly or list, linear reductum (over field) of f by elements from I
+PURPOSE: reduce a polynomial only by linear reductions (no monomial multiplications)
+NOTE:    If s<>0, a list consisting of the reduced polynomial and the coefficient
+@*       vector of the used reductions is returned, otherwise (and by default)
+@*       only reduced polynomial is returned.
+@*       If t<>0 (and by default) all monomials are reduced (if possible),
+@*       otherwise, only leading monomials are reduced.
+@*       If u<>0 (and by default), the ideal is linearly pre-reduced, i.e.
+@*       instead of the given ideal, the output of @code{linReduceIdeal} is used.
+@*       If u is set to 0 and the given ideal does not equal the output of
+@*       @code{linReduceIdeal}, the result might not be as expected.
+DISPLAY: If @code{printlevel}=1, progress debug messages will be printed,
+@*       if printlevel>=2, all the debug messages will be printed.
+EXAMPLE: example linReduce; shows examples
+"
+{
+  int ppl = printlevel - voice + 2;
+  int remembercoeffs = 0; // default
+  int redtail        = 1; // default
+  int prepareideal   = 1; // default
+  if (size(#)>0)
+  {
+    if (typeof(#[1])=="int" || typeof(#[1])=="number")
+    {
+      remembercoeffs = #[1];
+    }
+    if (size(#)>1)
+    {
+      if (typeof(#[2])=="int" || typeof(#[2])=="number")
+      {
+        redtail = #[2];
+      }
+      if (size(#)>2)
+      {
+        if (typeof(#[3])=="int" || typeof(#[3])=="number")
+        {
+          prepareideal = #[3];
+        }
+      }
+    }
+  }
+  int i,j,k;
+  int sI = ncols(I);
+  // pre-reduce I:
+  module M;
+  if (prepareideal <> 0)
+  {
+    if (remembercoeffs <> 0)
+    {
+      list sortedI = linReduceIdeal(I,1,redtail);
+      I = sortedI[1];
+      M = sortedI[2];
+      dbprint(ppl-1,"// prepared ideal:" +string(I));
+      dbprint(ppl-1,"//  with operations:" +string(M));
+    }
+    else { I = linReduceIdeal(I,0,redtail); }
+  }
+  else
+  {
+    if (remembercoeffs <> 0)
+    {
+      for (i=1; i<=sI; i++) { M[i] = gen(i); }
+    }
+  }
+  ideal lmI,lcI,ordI;
+  for (i=1; i<=sI; i++)
+  {
+    lmI[i] = leadmonom(I[i]);
+    lcI[i] = leadcoef(I[i]);
+    ordI[i] = ord(lmI[i]);
+  }
+  vector v;
+  poly c;
+  // === reduce leading monomials ===
+  poly lm = leadmonom(f);
+  int ordf = ord(lm);
+  for (i=sI; i>=1; i--)  // I is sorted: smallest lm's on top
+  {
+    if (lm == 0) { break; }
+    else
+    {
+      if (ordf == ordI[i])
+      {
+        if (lm == lmI[i])
+        {
+          c = leadcoef(f)/lcI[i];
+          f = f - c*I[i];
+          lm = leadmonom(f);
+          ordf = ord(lm);
+          if (remembercoeffs <> 0) { v = v - c * M[i]; }
+        }
+      }
+    }
+  }
+  // === reduce tails as well ===
+  if (redtail <> 0)
+  {
+    dbprint(ppl,"// finished reducing leading monomials");
+    dbprint(ppl-1,string(f));
+    if (remembercoeffs <> 0) { dbprint(ppl-1,"// used reductions:" + string(v)); }
+    for (i=1; i<=sI; i++)
+    {
+      dbprint(ppl,"// testing ideal entry "+string(i));
+      for (j=1; j<=size(f); j++)
+      {
+        if (ord(f[j]) == ordI[i])
+        {
+          if (normalize(f[j]) == lmI[i])
+          {
+            c = leadcoef(f[j])/lcI[i];
+            f = f - c*I[i];
+            dbprint(ppl-1,"// reducing with " + string(I[i]));
+            dbprint(ppl-1,"//  to " + string(f));
+            if (remembercoeffs <> 0) { v = v - c * M[i]; }
+          }
+        }
+      }
+    }
+  }
+  if (remembercoeffs <> 0)
+  {
+    list l = f,v;
+    return(l);
+  }
+  else { return(f); }
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y),dp;
+  ideal I = 1,y,xy;
+  poly f = 5xy+7y+3;
+  poly g = 7x+5y+3;
+  linReduce(g,I);     // reduces tails
+  linReduce(g,I,0,0); // no reductions of tails
+  linReduce(f,I,1);   // reduces tails and shows reductions used
+  f = x3+y2+x2+y+x;
+  I = x3-y3, y3-x2,x3-y2,x2-y,y2-x;
+  list l = linReduce(f,I,1);
+  l;
+  module M = I;
+  f - (l[1]-(M*l[2])[1,1]);
+}
+
+proc linSyzSolve (ideal I, list #)
+"USAGE:  linSyzSolve(I[,s]);  I an ideal, s an optional int
+RETURN:  vector, coefficient vector of linear combination of 0 in elements of I
+PURPOSE: compute a linear dependency between the elements of an ideal
+@*       if such one exists
+NOTE:    If s<>0, @code{std} is used for Groebner basis computations,
+@*       otherwise, @code{slimgb} is used.
+@*       By default, @code{slimgb} is used in char 0 and @code{std} in char >0.
+DISPLAY: If printlevel=1, progress debug messages will be printed,
+@*       if printlevel>=2, all the debug messages will be printed.
+EXAMPLE: example linSyzSolve; shows examples
+"
+{
+  int whichengine     = 0; // default
+  int enginespecified = 0; // default
+  if (size(#)>0)
+  {
+    if (typeof(#[1])=="int" || typeof(#[1])=="number")
+    {
+      whichengine = int( #[1]);
+      enginespecified = 1;
+    }
+  }
+  int ppl = printlevel - voice +2;
+  int sI = ncols(I);
+  // check if we are done
+  if (I[sI]==0)
+  {
+    vector v = gen(sI);
+  }
+  else
+  {
+    // ------- 1. introduce undefined coeffs ------------------
+    def save = basering;
+    list RL = ringlist(save);
+    int nv = nvars(save);
+    int np = npars(save);
+    int p = char(save);
+    string cs = "(" + charstr(save) + ")";
+    if (enginespecified == 0)
+    {
+      if (p <> 0)
+      {
+        whichengine = 1;
+      }
+    }
+    int i;
+    list Lvar;
+    for (i=1; i<=sI; i++)
+    {
+      Lvar[i] = safeVarName("@a(" + string(i) + ")");
+    }
+    list L at A = RL[1..4];
+    L at A[2] = Lvar;
+    L at A[3] = list(list("lp",intvec(1:sI)),list("C",intvec(0)));
+    def @A = ring(L at A);
+    L at A[2] = list(safeVarName("@z"));
+    L at A[3][1] = list("dp",intvec(1));
+    if (size(L at A[1])>1)
+    {
+      L at A[1][2] = L at A[1][2] + Lvar;
+      L at A[1][3][size(L at A[1][3])+1] = list("lp",intvec(1:sI));
+    }
+    else
+    {
+      L at A[1] = list(p,Lvar,list(list("lp",intvec(1:sI))),ideal(0));
+    }
+    def @aA = ring(L at A);
+    def @B = save + @aA;
+    setring @B;
+    ideal I = imap(save,I);
+    // ------- 2. form the linear system for the undef coeffs ---
+     poly W;  ideal QQ;
+    for (i=1; i<=sI; i++)
+    {
+      W = W + par(np+i)*I[i];
+    }
+    while (W!=0)
+    {
+      QQ = QQ,leadcoef(W);
+      W = W - lead(W);
+    }
+    // QQ consists of polynomial expressions in @a(i) of type number
+    setring @A;
+    ideal QQ = imap(@B,QQ);
+    // ------- 3. this QQ is a polynomial ideal, so "solve" the system -----
+    dbprint(ppl, "// linSyzSolve: starting Groebner basis computation with engine:", whichengine);
+    QQ = engine(QQ,whichengine);
+    dbprint(ppl, "// QQ after engine:", QQ);
+    if (dim(QQ) == -1)
+    {
+      dbprint(ppl+1, "// no solutions by linSyzSolve");
+      // output zeroes
+      setring save;
+      kill @A, at aA, at B;
+      return(v);
+    }
+    // ------- 4. in order to get the numeric values -------
+    matrix AA = matrix(maxideal(1));
+    module MQQ = std(module(QQ));
+    AA = NF(AA,MQQ); // todo: we still receive NF warnings
+    dbprint(ppl, "// AA after NF:",AA);
+    //    "AA after NF:"; print(AA);
+    for(i=1; i<=sI; i++)
+    {
+      AA = subst(AA,var(i),1);
+    }
+    dbprint(ppl, "// AA after subst:",AA);
+    //    "AA after subst: "; print(AA);
+    vector v = (module(transpose(AA)))[1];
+    setring save;
+    vector v = imap(@A,v);
+    kill @A, at aA, at B;
+  }
+  return(v);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,x,dp;
+  ideal I = x,2x;
+  linSyzSolve(I);
+  ideal J = x,x2;
+  linSyzSolve(J);
+}
+
+proc pIntersect (poly s, ideal I, list #)
+"USAGE:  pIntersect(f, I [,s]);  f a poly, I an ideal, s an optional int
+RETURN:  vector, coefficient vector of the monic polynomial
+PURPOSE: compute the intersection of ideal I with the subalgebra K[f]
+ASSUME:  I is given as Groebner basis, basering is not a qring.
+NOTE:    If the intersection is zero, this proc might not terminate.
+@*       If s>0 is given, it is searched for the generator of the intersection
+@*       only up to degree s. Otherwise (and by default), no bound is assumed.
+DISPLAY: If printlevel=1, progress debug messages will be printed,
+@*       if printlevel>=2, all the debug messages will be printed.
+EXAMPLE: example pIntersect; shows examples
+"
+{
+  def save = basering;
+  int n = nvars(save);
+  list RL = ringlist(save);
+  int i,j,k;
+  if (RL[4]<>0)
+  {
+    ERROR ("basering must not be a qring");
+  }
+  // assume I is given in Groebner basis
+  if (attrib(I,"isSB") <> 1)
+  {
+    print("// WARNING: The input has no SB attribute!");
+    print("// Treating it as if it were a Groebner basis and proceeding...");
+    attrib(I,"isSB",1); // set attribute for suppressing NF messages
+  }
+  int bound = 0; // default
+  if (size(#)>0)
+  {
+    if (typeof(#[1])=="int" || typeof(#[1])=="number")
+    {
+      bound = #[1];
+    }
+  }
+  int ppl = printlevel-voice+2;
+  // ---case 1: I = basering---
+  if (size(I) == 1)
+  {
+    if (simplify(I,2)[1] == 1)
+    {
+      return(gen(1)); // = 1
+    }
+  }
+  // ---case 2: intersection is zero---
+  intvec degs = leadexp(s);
+  intvec possdegbounds;
+  list degI;
+  i = 1;
+  while (i <= ncols(I))
+  {
+    if (i == ncols(I)+1) { break; }
+    degI[i] = leadexp(I[i]);
+    for (j=1; j<=n; j++)
+    {
+      if (degs[j] == 0)
+      {
+        if (degI[i][j] <> 0) { break; }
+      }
+      if (j == n)
+      {
+        k++;
+        possdegbounds[k] = Max(degI[i]);
+      }
+    }
+    i++;
+  }
+  int degbound = Min(possdegbounds);
+  if (bound>0 && bound<degbound) // given bound is too small
+  {
+    print("// Try a bound of at least " + string(degbound));
+    return(vector(0));
+  }
+  dbprint(ppl,"// lower bound for the degree of the insection is " +string(degbound));
+  if (degbound == 0) // lm(s) does not appear in lm(I)
+  {
+    print("// Intersection is zero");
+    return(vector(0));
+  }
+  // ---case 3: intersection is non-trivial---
+  ideal redNI = 1;
+  vector v;
+  list l,ll;
+  l[1] = vector(0);
+  poly toNF,tobracket,newNF,rednewNF,oldNF,secNF;
+  i = 1;
+  while (1)
+  {
+    if (bound>0 && i>bound) { return(vector(0)); }
+    dbprint(ppl,"// Testing degree "+string(i));
+    if (i>1)
+    {
+      oldNF = newNF;
+      tobracket = s^(i-1) - oldNF;
+      if (tobracket==0) // todo bug in bracket?
+      {
+        toNF = 0;
+      }
+      else
+      {
+        toNF = bracket(tobracket,secNF);
+      }
+      newNF = NF(toNF+oldNF*secNF,I);  // = NF(s^i,I)
+    }
+    else
+    {
+      newNF = NF(s,I);
+      secNF = newNF;
+    }
+    ll = linReduce(newNF,redNI,1);
+    rednewNF = ll[1];
+    l[i+1] = ll[2];
+    dbprint(ppl-1,"// newNF is: "+string(newNF));
+    dbprint(ppl-1,"// rednewNF is: "+string(rednewNF));
+    if (rednewNF != 0) // no linear dependency
+    {
+      redNI[i+1] = rednewNF;
+      i++;
+    }
+    else // there is a linear dependency, hence we are done
+    {
+      dbprint(ppl,"// degree of the generator of the intersection is: "+string(i));
+      break;
+    }
+  }
+  dbprint(ppl-1,"// used linear reductions:", l);
+  // we obtain the coefficients of the generator by the used reductions:
+  list Lvar;
+  for (j=1; j<=i+1; j++)
+  {
+    Lvar[j] = safeVarName("a("+string(j)+")");
+  }
+  list Lord = list("dp",intvec(1:(i+1))),list("C",intvec(0));
+  list L at R = RL[1..4];
+  L at R[2] = Lvar; L at R[3] = Lord;
+  def @R = ring(L at R); setring @R;
+  list l = imap(save,l);
+  ideal C;
+  for (j=1;j<=i+1;j++)
+  {
+    C[j] = 0;
+    for (k=1;k<=j;k++)
+    {
+      C[j] = C[j]+l[j][k]*var(k);
+    }
+  }
+  for (j=i;j>=1;j--)
+  {
+    C[i+1]= subst(C[i+1],var(j),var(j)+C[j]);
+  }
+  matrix m = coeffs(C[i+1],maxideal(1));
+  vector v = gen(i+1);
+  for (j=1;j<=i+1;j++)
+  {
+    v = v + m[j,1]*gen(j);
+  }
+  setring save;
+  v = imap(@R,v);
+  kill @R;
+  return(v);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y),dp;
+  poly f = x^2+y^3+x*y^2;
+  def D = initialMalgrange(f);
+  setring D;
+  inF;
+  pIntersect(t*Dt,inF);
+  pIntersect(t*Dt,inF,1);
+}
+
+proc pIntersectSyz (poly s, ideal I, list #)
+"USAGE:  pIntersectSyz(f, I [,p,s,t]);  f poly, I ideal, p,t optial ints, p prime
+RETURN:  vector, coefficient vector of the monic polynomial
+PURPOSE: compute the intersection of an ideal I with the subalgebra K[f]
+ASSUME:  I is given as Groebner basis.
+NOTE:    If the intersection is zero, this procedure might not terminate.
+@*       If p>0 is given, this proc computes the generator of the intersection in
+@*       char p first and then only searches for a generator of the obtained
+@*       degree in the basering. Otherwise, it searches for all degrees by
+@*       computing syzygies.
+@*       If s<>0, @code{std} is used for Groebner basis computations in char 0,
+@*       otherwise, and by default, @code{slimgb} is used.
+@*       If t<>0 and by default, @code{std} is used for Groebner basis
+@*       computations in char >0, otherwise, @code{slimgb} is used.
+DISPLAY: If printlevel=1, progress debug messages will be printed,
+@*       if printlevel>=2, all the debug messages will be printed.
+EXAMPLE: example pIntersectSyz; shows examples
+"
+{
+  // assume I is given as Groebner basis
+  if (attrib(I,"isSB") <> 1)
+  {
+    print("// WARNING: The input has no SB attribute!");
+    print("//  Treating it as if it were a Groebner basis and proceeding...");
+    attrib(I,"isSB",1); // set attribute for suppressing NF messages
+  }
+  int ppl = printlevel-voice+2;
+  int whichengine  = 0; // default
+  int modengine    = 1; // default
+  int solveincharp = 0; // default
+  def save = basering;
+  int n = nvars(save);
+  if (size(#)>0)
+  {
+    if (typeof(#[1])=="int" || typeof(#[1])=="number")
+    {
+      solveincharp = int(#[1]);
+    }
+    if (size(#)>1)
+    {
+      if (typeof(#[2])=="int" || typeof(#[2])=="number")
+      {
+        whichengine = int(#[2]);
+      }
+      if (size(#)>2)
+      {
+        if (typeof(#[3])=="int" || typeof(#[3])=="number")
+        {
+          modengine = int(#[3]);
+        }
+      }
+    }
+  }
+  int i,j;
+  vector v;
+  poly tobracket,toNF,newNF,p;
+  ideal NI = 1;
+  newNF = NF(s,I);
+  NI[2] = newNF;
+  list RL = ringlist(save);
+  if (solveincharp)
+  {
+    int psolveincharp = prime(solveincharp);
+    if (solveincharp <> psolveincharp)
+    {
+      print("// " + string(solveincharp) + " is invalid characteristic of ground field.");
+      print("// " + string(psolveincharp) + " is used.");
+      solveincharp = psolveincharp;
+      kill psolveincharp;
+    }
+    list RLp = RL[1..4];
+    if (typeof(RL[1]) == "int") { RLp[1] = solveincharp; }
+    else { RLp[1][1] = solveincharp; } // parameters
+    def @Rp = ring(RLp);
+    setring @Rp;
+    number c;
+    setring save;
+    int shortSave = short; // workaround for maps Q(a_i) -> Z/p(a_i)
+    short = 0;
+    string str;
+    int badprime;
+    i=1;
+    while (badprime == 0 && i<=size(s)) // detect bad primes
+    {
+      str = string(denominator(leadcoef(s[i])));
+      str = "c = " + str + ";";
+      setring @Rp;
+      execute(str);
+      if (c == 0) { badprime = 1; }
+      setring save;
+      i++;
+    }
+    str = "poly s = " + string(s) + ";";
+    if (size(RL) > 4) // basering is NC-algebra
+    {
+      string RL5 = "@C = " + string(RL[5]) + ";";
+      string RL6 = "@D = " + string(RL[6]) + ";";
+      setring @Rp;
+      matrix @C[n][n]; matrix @D[n][n];
+      execute(RL5); execute(RL6);
+      def Rp = nc_algebra(@C, at D);
+    }
+    else { def Rp = @Rp; }
+    setring Rp;
+    kill @Rp;
+    dbprint(ppl-1,"// solving in ring ", Rp);
+    execute(str);
+    vector v;
+    number c;
+    ideal NI = 1;
+    setring save;
+    i=1;
+    while (badprime == 0 && i<=size(I)) // detect bad primes
+    {
+      str = string(leadcoef(cleardenom(I[i])));
+      str = "c = " + str + ";";
+      setring Rp;
+      execute(str);
+      if (c == 0) { badprime = 1; }
+      setring save;
+      i++;
+    }
+    if (badprime == 1)
+    {
+      print("// WARNING: bad prime");
+      short = shortSave;
+      return(vector(0));
+    }
+  }
+  i = 1;
+  dbprint(ppl,"// pIntersectSyz starts...");
+  dbprint(ppl-1,"// with ideal I=", I);
+  while (1)
+  {
+    dbprint(ppl,"// testing degree: "+string(i));
+    if (i>1)
+    {
+      tobracket = s^(i-1)-NI[i];
+      if (tobracket!=0)
+      {
+        toNF = bracket(tobracket,NI[2]) + NI[i]*NI[2];
+      }
+      else
+      {
+        toNF = NI[i]*NI[2];
+      }
+      newNF =  NF(toNF,I);
+      NI[i+1] = newNF;
+    }
+    // look for a solution
+    dbprint(ppl-1,"// linSyzSolve starts with: "+string(matrix(NI)));
+    if (solveincharp) // modular method
+    {
+      for (j=1; j<=size(newNF); j++)
+      {
+        str = string(denominator(leadcoef(s[i])));
+        str = "c = " + str + ";";
+        setring Rp;
+        execute(str);
+        if (c == 0)
+        {
+          print("// WARNING: bad prime");
+          setring save;
+          short = shortSave;
+          return(vector(0));
+        }
+        setring save;
+      }
+      str = "NI[" + string(i) + "+1] = " + string(newNF) + ";";
+      setring Rp;
+      execute(str); // NI[i+1] = [newNF]_{solveincharp}
+      v = linSyzSolve(NI,modengine);
+      if (v!=0) // there is a modular solution
+      {
+        dbprint(ppl,"// got solution in char "+string(solveincharp)+" of degree "+string(i));
+        setring save;
+        v = linSyzSolve(NI,whichengine);
+        if (v==0)
+        {
+          break;
+        }
+      }
+      else // no modular solution
+      {
+        setring save;
+        v = 0;
+      }
+    }
+    else // non-modular method
+    {
+      v = linSyzSolve(NI,whichengine);
+    }
+    matrix MM[1][nrows(v)] = matrix(v);
+    dbprint(ppl-1,"// linSyzSolve ready  with: "+string(MM));
+    kill MM;
+    //  "linSyzSolve ready with"; print(v);
+    if (v!=0)
+    {
+      // a solution:
+      //check for the reality of the solution
+      p = 0;
+      for (j=1; j<=i+1; j++)
+      {
+        p = p + v[j]*NI[j];
+      }
+      if (p!=0)
+      {
+        dbprint(ppl,"// linSyzSolve: bad solution!");
+      }
+      else
+      {
+        dbprint(ppl,"// linSyzSolve: got solution!");
+        // "got solution!";
+        break;
+      }
+    }
+    // no solution:
+    i++;
+  }
+  dbprint(ppl,"// pIntersectSyz finished");
+  if (solveincharp) { short = shortSave; }
+  return(v);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y),dp;
+  poly f = x^2+y^3+x*y^2;
+  def D = initialMalgrange(f);
+  setring D;
+  inF;
+  poly s = t*Dt;
+  pIntersectSyz(s,inF);
+  int p = prime(20000);
+  pIntersectSyz(s,inF,p,0,0);
+}
+
+proc vec2poly (list #)
+"USAGE:  vec2poly(v [,i]);  v a vector or an intvec, i an optional int
+RETURN:  poly, an univariate polynomial in i-th variable with coefficients given by v
+PURPOSE: constructs an univariate polynomial in K[var(i)] with given coefficients,
+@*       such that the coefficient at var(i)^{j-1} is v[j].
+NOTE:    The optional argument i must be positive, by default i is 1.
+EXAMPLE: example vec2poly; shows examples
+"
+{
+  def save = basering;
+  int i,ringvar;
+  ringvar = 1; // default
+  if (size(#) > 0)
+  {
+    if (typeof(#[1])=="vector" || typeof(#[1])=="intvec")
+    {
+      def v = #[1];
+    }
+    else
+    {
+      ERROR("wrong input: expected vector/intvec expression");
+    }
+    if (size(#) > 1)
+    {
+      if (typeof(#[2])=="int" || typeof(#[2])=="number")
+      {
+        ringvar = int(#[2]);
+      }
+    }
+  }
+  if (ringvar > nvars(save))
+  {
+    ERROR("var out of range");
+  }
+  poly p;
+  for (i=1; i<=nrows(v); i++)
+  {
+    p = p + v[i]*(var(ringvar))^(i-1);
+  }
+  return(p);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y),dp;
+  vector v = gen(1) + 3*gen(3) + 22/9*gen(4);
+  intvec iv = 3,2,1;
+  vec2poly(v,2);
+  vec2poly(iv);
+}
+
+/*
+// // listofroots and addRoots aren't needed anymore due to some modifications
+//
+// static proc listofroots (list #)
+// {
+//   def save = basering;
+//   int n = nvars(save);
+//   int i;
+//   poly p;
+//   if (typeof(#[1])=="vector")
+//   {
+//     vector b = #[1];
+//     for (i=1; i<=nrows(b); i++)
+//     {
+//       p = p + b[i]*(var(1))^(i-1);
+//     }
+//   }
+//   else
+//   {
+//     p = #[1];
+//   }
+//   int substitution = int(#[2]);
+//   string s = safeVarName("s");
+//   list RL = ringlist(save); RL = RL[1..4];
+//   RL[2] = list(s); RL[3] = list(list("dp",intvec(1)),list("C",0));
+//   def S = ring(RL); setring S;
+//   ideal J;
+//   for (i=1; i<=n; i++)
+//   {
+//     J[i] = var(1);
+//   }
+//   map @m = save,J;
+//   poly p = @m(p);
+//   if (substitution == 1)
+//   {
+//     p = subst(p,var(1),-var(1)-1);
+//   }
+//   // the rest of this proc is nicked from bernsteinBM from dmod.lib
+//   list P = factorize(p);//with constants and multiplicities
+//   ideal bs; intvec m;   //the BS polynomial is monic, so we are not interested in constants
+//   for (i=2; i<= size(P[1]); i++)  //we delete P[1][1] and P[2][1]
+//   {
+//     bs[i-1] = P[1][i];
+//     m[i-1]  = P[2][i];
+//   }
+//   bs =  normalize(bs);
+//   bs = -subst(bs,var(1),0);
+//   setring save;
+//   ideal bs = imap(S,bs);
+//   kill S;
+//   list BS = bs,m;
+//   return(BS);
+// }
+//
+//
+// static proc addRoot(number q, list L)
+// {
+//   // add root to list in bFactor format
+//   int i,qInL;
+//   ideal I = L[1];
+//   intvec v = L[2];
+//   list LL;
+//   if (v == 0)
+//   {
+//     I = poly(q);
+//     v = 1;
+//     LL = I,v;
+//   }
+//   else
+//   {
+//     for (i=1; i<=ncols(I); i++)
+//     {
+//       if (I[i] == q)
+//       {
+//         qInL = i;
+//         break;
+//       }
+//     }
+//     if (qInL)
+//     {
+//       v[qInL] = v[qInL] + 1;
+//     }
+//     else
+//     {
+//       I = q,I;
+//       v = 1,v;
+//     }
+//   }
+//   LL = I,v;
+//   if (size(L) == 3) // irreducible factor
+//   {
+//     if (L[3] <> "0" && L[3] <> "1")
+//     {
+//       LL = LL + list(L[3]);
+//     }
+//   }
+//   return(LL);
+// }
+*/
+
+static proc bfctengine (poly f, int inorann, int whichengine, int addPD, int stdsum, int methodord, int methodpIntersect, int pIntersectchar, int modengine, intvec u0)
+{
+  int printlevelsave = printlevel;
+  printlevel = printlevel + 1;
+  int ppl = printlevel - voice + 2;
+  int i;
+  def save = basering;
+  int n = nvars(save);
+  if (isCommutative() == 0) { ERROR("basering must be commutative"); }
+  if (char(save) <> 0) { ERROR("characteristic of basering has to be 0"); }
+  list L = ringlist(save);
+  int qr;
+  if (L[4] <> 0) // qring
+  {
+    print("// basering is qring:");
+    print("// discarding the quotient and proceeding...");
+    L[4] = ideal(0);
+    qr = 1;
+    def save2 = ring(L); setring save2;
+    poly f = imap(save,f);
+  }
+  if (inorann == 0) // bfct using initial ideal
+  {
+    // list L = ringlist(basering);
+    intvec iv = valvars(f)[1]; // heuristacally better ordering for initialMalgrange
+    list varL = L[2];
+    varL = varL[iv];
+    L[2] = varL;
+    if (u0 <> 0)
+    {
+      u0 = u0[iv];
+    }
+    def newr = ring(L);
+    kill varL,iv,L;
+    setring newr;
+    poly f = imap(save,f);
+    dbprint(ppl,"// starting computation of the initial ideal of the Malgrange ideal...");
+    def D = initialMalgrange(f,whichengine,methodord,u0);
+    dbprint(ppl,"// ...done");
+    setring D;
+    ideal J = inF;
+    kill inF;
+    poly s = var(1)*var(n+2);
+  }
+  else // bfct using Ann(f^s)
+  {
+    dbprint(ppl,"// starting computation of the s-parametric annihilator...");
+    def D = SannfsBFCT(f,addPD,whichengine,stdsum);
+    dbprint(ppl,"// ...done");
+    setring D;
+    ideal J = LD;
+    kill LD;
+    poly s = var(1);
+  }
+  vector b;
+  dbprint(ppl,"// starting to intersect with subalgebra...");
+  // try it modular
+  if (methodpIntersect <> 0) // pIntersectSyz
+  {
+    if (pIntersectchar == 0) // pIntersectSyz::modular
+    {
+      list L = ringlist(D);
+      int lb = 10000; int ub = 536870909; // bounds for random primes
+      list usedprimes;
+      int sJ = size(J);
+      int sLJq;
+      ideal LJ;
+      for (i=1; i<=sJ; i++)
+      {
+        LJ[i] = leadcoef(cleardenom(J[i]));
+      }
+      int short_save = short; // workaround for map Q(a_i) -> Z/q(a_i)
+      short = 0;
+      string strLJq = "ideal LJq = " + string(LJ) + ";";
+      int nD = nvars(D);
+      string L5 = "matrix @C[nD][nD]; @C = " + string(L[5]) + ";";
+      string L6 = "matrix @D[nD][nD]; @D = " + string(L[6]) + ";";
+      L = L[1..4];
+      i = 1;
+      while (b == 0)
+      {
+        dbprint(ppl,"// number of run in the loop: "+string(i));
+        int q = prime(random(lb,ub));
+        if (findFirst(usedprimes,q)==0) // if q has not been used already
+        {
+          usedprimes = usedprimes,q;
+          dbprint(ppl,"// using prime: "+string(q));
+          if (typeof(L[1]) == "int") { L[1] = q; }
+          else { L[1][1] = q; } // parameters
+          def @Rq = ring(L); setring @Rq;
+          execute(L5); execute(L6);
+          def Rq = nc_algebra(@C, at D); // def Rq = nc_algebra(1, at D);
+          setring Rq; kill @Rq;
+          execute(strLJq);
+          sLJq = size(LJq);
+          setring D; kill Rq;
+          if (sLJq <> sJ ) // detect unlucky prime
+          {
+            dbprint(ppl,"// " +string(q) + " is unlucky");
+            b = 0;
+          }
+          else
+          {
+            b = pIntersectSyz(s,J,q,whichengine,modengine);
+          }
+        }
+        i++;
+      }
+      short = short_save;
+    }
+    else // pIntersectSyz::non-modular
+    {
+      b = pIntersectSyz(s,J,0,whichengine);
+    }
+  }
+  else // pIntersect: linReduce
+  {
+    b = pIntersect(s,J);
+  }
+  dbprint(ppl,"// ...done"); // with the intersection
+  poly pb = vec2poly(b);
+  if (inorann == 0)
+  {
+    pb = subst(pb,var(1),-var(1)-1);
+  }
+  else // bfctAnn
+  {
+    if (addPD)
+    {
+      pb = pb*(var(1)+1);
+    }
+  }
+  list l = bFactor(pb);
+  setring save;
+  list l = imap(D,l);
+  printlevel = printlevelsave;
+  return(l);
+}
+
+proc bfct (poly f, list #)
+"USAGE:  bfct(f [,s,t,v]);  f a poly, s,t optional ints, v an optional intvec
+RETURN:  list of ideal and intvec
+PURPOSE: computes the roots of the Bernstein-Sato polynomial b(s)
+@*       for the hypersurface defined by f.
+ASSUME:  The basering is commutative and of characteristic 0.
+BACKGROUND: In this proc, the initial Malgrange ideal is computed according to
+@*       the algorithm by Masayuki Noro and then a system of linear equations is
+@*       solved by linear reductions.
+NOTE:    In the output list, the ideal contains all the roots
+@*       and the intvec their multiplicities.
+@*       If s<>0, @code{std} is used for GB computations,
+@*       otherwise, and by default, @code{slimgb} is used.
+@*       If t<>0, a matrix ordering is used for Groebner basis computations,
+@*       otherwise, and by default, a block ordering is used.
+@*       If v is a positive weight vector, v is used for homogenization
+@*       computations, otherwise and by default, no weights are used.
+DISPLAY: If printlevel=1, progress debug messages will be printed,
+@*       if printlevel>=2, all the debug messages will be printed.
+EXAMPLE: example bfct; shows examples
+"
+{
+  int ppl = printlevel - voice +2;
+  int i;
+  int n = nvars(basering);
+  // in # we have two switches:
+  // one for the engine used for Groebner basis computations,
+  // one for  M() ordering or its realization
+  // in # can also be the optional weight vector
+  int whichengine  = 0; // default
+  int methodord    = 0; // default
+  intvec u0        = 0; // default
+  if (size(#)>0)
+  {
+    if (typeof(#[1])=="int" || typeof(#[1])=="number")
+    {
+      whichengine = int(#[1]);
+    }
+    if (size(#)>1)
+    {
+      if (typeof(#[2])=="int" || typeof(#[2])=="number")
+      {
+        methodord = int(#[2]);
+      }
+      if (size(#)>2)
+      {
+        if (typeof(#[3])=="intvec" && size(#[3])==n && allPositive(#[3])==1)
+        {
+          u0 = #[3];
+        }
+      }
+    }
+  }
+  list b = bfctengine(f,0,whichengine,0,0,methodord,0,0,0,u0);
+  return(b);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y),dp;
+  poly f = x^2+y^3+x*y^2;
+  bfct(f);
+  intvec v = 3,2;
+  bfct(f,1,0,v);
+}
+
+proc bfctSyz (poly f, list #)
+"USAGE:  bfctSyz(f [,r,s,t,u,v]);  f poly, r,s,t,u optional ints, v opt. intvec
+RETURN:  list of ideal and intvec
+PURPOSE: computes the roots of the Bernstein-Sato polynomial b(s)
+@*       for the hypersurface defined by f
+ASSUME:  The basering is commutative and of characteristic 0.
+BACKGROUND: In this proc, the initial Malgrange ideal is computed according to
+@*       the algorithm by Masayuki Noro and then a system of linear equations is
+@*       solved by computing syzygies.
+NOTE:    In the output list, the ideal contains all the roots and the intvec
+@*       their multiplicities.
+@*       If r<>0, @code{std} is used for GB computations in characteristic 0,
+@*       otherwise, and by default, @code{slimgb} is used.
+@*       If s<>0, a matrix ordering is used for GB computations, otherwise,
+@*       and by default, a block ordering is used.
+@*       If t<>0, the computation of the intersection is solely performed over
+@*       charasteristic 0, otherwise and by default, a modular method is used.
+@*       If u<>0 and by default, @code{std} is used for GB computations in
+@*       characteristic >0, otherwise, @code{slimgb} is used.
+@*       If v is a positive weight vector, v is used for homogenization
+@*       computations, otherwise and by default, no weights are used.
+DISPLAY: If printlevel=1, progress debug messages will be printed,
+@*       if printlevel>=2, all the debug messages will be printed.
+EXAMPLE: example bfctSyz; shows examples
+"
+{
+  int ppl = printlevel - voice +2;
+  int i;
+  // in # we have four switches:
+  // one for the engine used for Groebner basis computations in char 0,
+  // one for  M() ordering or its realization
+  // one for a modular method when computing the intersection
+  // and one for the engine used for Groebner basis computations in char >0
+  // in # can also be the optional weight vector
+  int n = nvars(basering);
+  int whichengine = 0; // default
+  int methodord   = 0; // default
+  int pIntersectchar = 0; // default
+  int modengine   = 1; // default
+  intvec u0       = 0; // default
+  if (size(#)>0)
+  {
+    if (typeof(#[1])=="int" || typeof(#[1])=="number")
+    {
+      whichengine = int(#[1]);
+    }
+    if (size(#)>1)
+    {
+      if (typeof(#[2])=="int" || typeof(#[2])=="number")
+      {
+        methodord = int(#[2]);
+      }
+      if (size(#)>2)
+      {
+        if (typeof(#[3])=="int" || typeof(#[3])=="number")
+        {
+          pIntersectchar = int(#[3]);
+        }
+        if (size(#)>3)
+        {
+          if (typeof(#[4])=="int" || typeof(#[4])=="number")
+          {
+            modengine = int(#[4]);
+          }
+          if (size(#)>4)
+          {
+            if (typeof(#[5])=="intvec" && size(#[5])==n && allPositive(#[5])==1)
+            {
+              u0 = #[5];
+            }
+          }
+        }
+      }
+    }
+  }
+  list b = bfctengine(f,0,whichengine,0,0,methodord,1,pIntersectchar,modengine,u0);
+  return(b);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y),dp;
+  poly f = x^2+y^3+x*y^2;
+  bfctSyz(f);
+  intvec v = 3,2;
+  bfctSyz(f,0,1,1,0,v);
+}
+
+proc bfctIdeal (ideal I, intvec w, list #)
+"USAGE:  bfctIdeal(I,w[,s,t]);  I an ideal, w an intvec, s,t optional ints
+RETURN:  list of ideal and intvec
+PURPOSE: computes the roots of the global b-function of I w.r.t. the weight (-w,w).
+ASSUME:  The basering is the n-th Weyl algebra in characteristic 0 and for all
+@*       1<=i<=n the identity var(i+n)*var(i)=var(i)*var(i+1)+1 holds, i.e. the
+@*       sequence of variables is given by x(1),...,x(n),D(1),...,D(n),
+@*       where D(i) is the differential operator belonging to x(i).
+@*       Further we assume that I is holonomic.
+BACKGROUND:  In this proc, the initial ideal of I is computed according to the
+@*       algorithm by Masayuki Noro and then a system of linear equations is
+@*       solved by linear reductions.
+NOTE:    In the output list, say L,
+@*  - L[1] of type ideal contains all the rational roots of a b-function,
+@*  - L[2] of type intvec contains the multiplicities of above roots,
+@*  - optional L[3] of type string is the part of b-function without rational roots.
+@*  Note, that a b-function of degree 0 is encoded via L[1][1]=0, L[2]=0 and
+@*  L[3] is 1 (for nonzero constant) or 0 (for zero b-function).
+@*       If s<>0, @code{std} is used for GB computations in characteristic 0,
+@*       otherwise, and by default, @code{slimgb} is used.
+@*       If t<>0, a matrix ordering is used for GB computations, otherwise,
+@*       and by default, a block ordering is used.
+DISPLAY: If printlevel=1, progress debug messages will be printed,
+@*       if printlevel>=2, all the debug messages will be printed.
+EXAMPLE: example bfctIdeal; shows examples
+"
+{
+  int ppl = printlevel - voice +2;
+  int i;
+  def save = basering;
+  int n = nvars(save) div 2;
+  int whichengine = 0; // default
+  int methodord   = 0; // default
+  if (size(#)>0)
+  {
+    if (typeof(#[1])=="int" || typeof(#[1])=="number")
+    {
+      whichengine = int(#[1]);
+    }
+    if (size(#)>1)
+    {
+      if (typeof(#[2])=="int" || typeof(#[2])=="number")
+      {
+        methodord = int(#[2]);
+      }
+    }
+  }
+  if (isWeyl()==0) { ERROR("basering is not a Weyl algebra"); }
+  for (i=1; i<=n; i++)
+  {
+    if (bracket(var(i+n),var(i))<>1)
+    {
+      ERROR(string(var(i+n))+" is not a differential operator for " +string(var(i)));
+    }
+  }
+  int isH = isHolonomic(I);
+  if (isH<>1)
+  {
+    print("WARNING: given ideal is not holonomic");
+    print("... setting bound for degree of b-function to 10 and proceeding");
+    isH = 10;
+  }
+  else { isH = 0; } // no degree bound for pIntersect
+  ideal J = initialIdealW(I,-w,w,whichengine,methodord);
+  poly s;
+  for (i=1; i<=n; i++)
+  {
+    s = s + w[i]*var(i)*var(n+i);
+  }
+  vector b = pIntersect(s,J,isH);
+  list RL = ringlist(save); RL = RL[1..4];
+  RL[2] = list(safeVarName("s"));
+  RL[3] = list(list("dp",intvec(1)),list("C",intvec(0)));
+  def @S = ring(RL); setring @S;
+  vector b = imap(save,b);
+  poly bs = vec2poly(b);
+  list l = bFactor(bs);
+  setring save;
+  list l = imap(@S,l);
+  return(l);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring @D = 0,(x,y,Dx,Dy),dp;
+  def D = Weyl();
+  setring D;
+  ideal I = 3*x^2*Dy+2*y*Dx,2*x*Dx+3*y*Dy+6; I = std(I);
+  intvec w1 = 0,1;
+  intvec w2 = 2,3;
+  bfctIdeal(I,w1);
+  bfctIdeal(I,w2,0,1);
+  ideal J = I[size(I)]; // J is not holonomic by construction
+  bfctIdeal(J,w1); //  b-function of D/J w.r.t. w1 is non-zero
+  bfctIdeal(J,w2); //  b-function of D/J w.r.t. w2 is zero
+}
+
+proc bfctOneGB (poly f,list #)
+"USAGE:  bfctOneGB(f [,s,t]);  f a poly, s,t optional ints
+RETURN:  list of ideal and intvec
+PURPOSE: computes the roots of the Bernstein-Sato polynomial b(s) for the
+@*       hypersurface defined by f, using only one GB computation
+ASSUME:  The basering is commutative and of characteristic 0.
+BACKGROUND: In this proc, the initial Malgrange ideal is computed based on the
+@*       algorithm by Masayuki Noro and combined with an elimination ordering.
+NOTE:    In the output list, the ideal contains all the roots and the intvec
+@*       their multiplicities.
+@*       If s<>0, @code{std} is used for the GB computation, otherwise,
+@*       and by default, @code{slimgb} is used.
+@*       If t<>0, a matrix ordering is used for GB computations,
+@*       otherwise, and by default, a block ordering is used.
+DISPLAY: If printlevel=1, progress debug messages will be printed,
+@*       if printlevel>=2, all the debug messages will be printed.
+EXAMPLE: example bfctOneGB; shows examples
+"
+{
+  int ppl = printlevel - voice +2;
+  if (!isCommutative()) { ERROR("Basering must be commutative"); }
+  def save = basering;
+  int n = nvars(save);
+  if (char(save) <> 0)
+  {
+    ERROR("characteristic of basering has to be 0");
+  }
+  list L = ringlist(save);
+  int qr;
+  if (L[4] <> 0) // qring?
+  {
+    print("// basering is qring:");
+    print("// discarding the quotient and proceeding...");
+    L[4] = ideal(0);
+    qr = 1;
+    def save2 = ring(L);
+    setring save2;
+    poly f = imap(save,f);
+  }
+  int N = 2*n+4;
+  int i;
+  int whichengine = 0; // default
+  int methodord   = 0; // default
+  if (size(#)>0)
+  {
+    if (typeof(#[1])=="int" || typeof(#[1])=="number")
+    {
+      whichengine = int(#[1]);
+    }
+    if (size(#)>1)
+    {
+      if (typeof(#[2])=="int" || typeof(#[2])=="number")
+      {
+        methodord = int(#[2]);
+      }
+    }
+  }
+  // creating the homogenized extended Weyl algebra
+  // create names for vars
+  list Lvar;
+  Lvar[1]   = safeVarName("t");
+  Lvar[2]   = safeVarName("s");
+  Lvar[n+3] = safeVarName("D"+Lvar[1]);
+  Lvar[N]   = safeVarName("h");
+  for (i=1; i<=n; i++)
+  {
+    Lvar[i+2]   = string(var(i));
+    Lvar[i+n+3] = safeVarName("D" + string(var(i)));
+  }
+  // create ordering
+  intvec uv = -1; uv[n+3] = 1; uv[N] = 0;
+  intvec @a = 1:N; @a[2] = 2;
+  intvec @a2 = @a; @a2[2] = 0; @a2[2*n+4] = 0;
+  list Lord;
+  Lord[1] = list("a", at a); Lord[2] = list("a", at a2);
+  if (methodord == 0) // default: block ordering
+  {
+    //ring @Dh = 0,(t,s,x(n..1),Dt,D(n..1),h),(a(@a),a(@a2),a(uv),dp(N-1),lp(1));
+    Lord[3] = list("a",uv);
+    Lord[4] = list("dp",intvec(1:(N-1)));
+    Lord[5] = list("lp",intvec(1));
+    Lord[6] = list("C",intvec(0));
+  }
+  else // M() ordering
+  {
+    intmat @Ord[N][N];
+    @Ord[1,1..N] = uv; @Ord[2,1..N] = 1:(N-1);
+    for (i=1; i<=N-2; i++) { @Ord[2+i,N - i] = -1; }
+    dbprint(ppl,"// weights for ordering: "+string(transpose(@a)));
+    dbprint(ppl,"// the ordering matrix:", at Ord);
+    //ring @Dh = 0,(t,s,x(n..1),Dt,D(n..1),h),(a(@a),a(@a2),M(@Ord));
+    Lord[3] = list("M",intvec(@Ord));
+    Lord[4] = list("C",intvec(0));
+  }
+  // create commutative ring
+  list L at Dh = ringlist(basering);
+  L at Dh = L at Dh[1..4]; // if basering is commutative nc_algebra
+  L at Dh[2] = Lvar; L at Dh[3] = Lord;
+  def @Dh = ring(L at Dh); setring @Dh;
+  dbprint(ppl,"// the ring @Dh:", at Dh);
+  // create non-commutative relations
+  matrix @relD[N][N];
+  @relD[1,2] = var(1)*var(N)^2;     //  s*t = t*s + t*h^2
+  @relD[2,n+3] = var(n+3)*var(N)^2; // Dt*s = s*Dt+Dt*h^2
+  @relD[1,n+3] = var(N)^2;
+  for (i=1; i<=n; i++)
+  {
+    @relD[i+2,n+3+i] = var(N)^2;
+  }
+  dbprint(ppl,"// nc relations:", at relD);
+  def Dh = nc_algebra(1, at relD);
+  setring Dh; kill @Dh;
+  dbprint(ppl,"// computing in ring",Dh);
+  poly f = imap(save,f);
+  f = homog(f,h);
+  // create the Malgrange ideal
+  ideal I = var(1) - f, var(1)*var(n+3) - var(2);
+  for (i=1; i<=n; i++)
+  {
+    I[3+i] = var(i+n+3)+diff(f,var(i+2))*var(n+3);
+  }
+  dbprint(ppl-1, "// the Malgrange ideal: " +string(I));
+  // the hard part: Groebner basis computation
+  dbprint(ppl, "// starting Groebner basis computation with engine: "+string(whichengine));
+  I = engine(I, whichengine);
+  dbprint(ppl, "// finished Groebner basis computation");
+  I = subst(I,h,1); // dehomogenization
+  dbprint(ppl-1,string(I));
+  // 3.3 the initial form
+  I = inForm(I,uv);
+  dbprint(ppl, "// the initial ideal:", string(matrix(I)));
+  // read off the solution
+  intvec tonselect = 1;
+  for (i=3; i<=2*n+4; i++) { tonselect = tonselect,i; }
+  I = nselect(I,tonselect);
+  dbprint(ppl, "// generators containing only s:", string(matrix(I)));
+  I = engine(I, whichengine); // is now a principal ideal;
+  if (qr == 1) { setring save2; }
+  else { setring save; }
+  ideal J; J[2] = var(1);
+  map @m = Dh,J;
+  ideal I = @m(I);
+  poly p = I[1];
+  p = subst(p,var(1),-var(1)-1);
+  list l = bFactor(p);
+  if (qr == 1)
+  {
+    setring save;
+    list l = imap(save2,l);
+  }
+  return(l);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y),dp;
+  poly f = x^2+y^3+x*y^2;
+  bfctOneGB(f);
+  bfctOneGB(f,1,1);
+}
+
+
+
+proc bfctAnn (poly f, list #)
+"USAGE:  bfctAnn(f [,a,b,c]);  f a poly, a, b, c optional ints
+RETURN:  list of ideal and intvec
+PURPOSE: computes the roots of the Bernstein-Sato polynomial b(s) for the
+@*       hypersurface defined by f.
+ASSUME:  The basering is commutative and of characteristic 0.
+BACKGROUND: In this proc, Ann(f^s) is computed and then a system of linear
+@*       equations is solved by linear reductions.
+NOTE:    In the output list, the ideal contains all the roots and the intvec
+@*  their multiplicities.
+@*  If a<>0, only f is appended to Ann(f^s), otherwise, and by default,
+@*  f and all its partial derivatives are appended.
+@*  If b<>0, @code{std} is used for GB computations, otherwise, and by
+@*  default, @code{slimgb} is used.
+@*  If c<>0, @code{std} is used for Groebner basis computations of ideals
+@*  <I+J> when I is already a Groebner basis of <I>.
+@*  Otherwise, and by default the engine determined by the switch b is used.
+@*  Note that in the case c<>0, the choice for b will be overwritten only
+@*  for the types of ideals mentioned above.
+@*  This means that if b<>0, specifying c has no effect.
+DISPLAY: If printlevel=1, progress debug messages will be printed,
+@*       if printlevel>=2, all the debug messages will be printed.
+EXAMPLE: example bfctAnn; shows examples
+"
+{
+  def save = basering;
+  int ppl = printlevel - voice + 2;
+  int addPD       = 1; // default
+  int whichengine = 0; // default
+  int stdsum      = 0; // default
+  if (size(#)>0)
+  {
+    if (typeof(#[1])=="int" || typeof(#[1])=="number")
+    {
+      addPD = int(#[1]);
+    }
+    if (size(#)>1)
+    {
+      if (typeof(#[2])=="int" || typeof(#[2])=="number")
+      {
+        whichengine = int(#[2]);
+      }
+      if (size(#)>2)
+      {
+        if (typeof(#[3])=="int" || typeof(#[3])=="number")
+        {
+          stdsum = int(#[3]);
+        }
+      }
+    }
+  }
+  list b = bfctengine(f,1,whichengine,addPD,stdsum,0,0,0,0,0);
+  return(b);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y),dp;
+  poly f = x^2+y^3+x*y^2;
+  bfctAnn(f);
+  def R = reiffen(4,5); setring R;
+  RC; // the Reiffen curve in 4,5
+  bfctAnn(RC,0,1);
+}
+
+/*
+static proc hardexamples ()
+{
+  //  some hard examples
+  ring r1 = 0,(x,y,z,w),dp;
+  // ab34
+  poly ab34 = (z3+w4)*(3z2x+4w3y);
+  bfct(ab34);
+  // ha3
+  poly ha3 = xyzw*(x+y)*(x+z)*(x+w)*(y+z+w);
+  bfct(ha3);
+  // ha4
+  poly ha4 = xyzw*(x+y)*(x+z)*(x+w)*(y+z)*(y+w);
+  bfct(ha4);
+  // chal4: reiffen(4,5)*reiffen(5,4)
+  ring r2 = 0,(x,y),dp;
+  poly chal4 = (x4+xy4+y5)*(x5+x4y+y4);
+  bfct(chal4);
+  // (xy+z)*reiffen(4,5)
+  ring r3 = 0,(x,y,z),dp;
+  poly xyzreiffen45 = (xy+z)*(y4+yz4+z5);
+  bfct(xyzreiffen45);
+
+// sparse ideal as suggested by Alex; gives 1 as std
+ideal I1 = 28191*y^2+14628*x*Dy, 24865*x^2+24072*x*Dx+17756*Dy^2;
+std(I1);
+}
+*/
diff --git a/Singular/LIB/bimodules.lib b/Singular/LIB/bimodules.lib
new file mode 100644
index 0000000..bc33ec6
--- /dev/null
+++ b/Singular/LIB/bimodules.lib
@@ -0,0 +1,774 @@
+/////////////////////////////////////////////////////////////////////////////
+version="version bimodules.lib 4.0.0.0 Jun_2013 "; // $Id: 5055ee4e20bdafb2cc63a931cbca6d46c27b86dd $
+category="Noncommutative";
+info="
+LIBRARY: bimodules.lib     Tools for handling bimodules
+AUTHORS: Ann Christina Foldenauer,    Christina.Foldenauer at rwth-aachen.de
+@*       Viktor Levandovskyy,     levandov at math.rwth-aachen.de
+
+OVERVIEW:
+@* The main purpose of this library is the handling of bimodules
+@* which will help e.g. to determine weak normal forms of representation matrices
+@* and total divisors within non-commutative, non-simple G-algebras.
+@* We will use modules homomorphisms between a G-algebra and its enveloping algebra
+@* in order to work left Groebner basis theory on bimodules.
+@* Assume we have defined a (non-commutative) G-algebra A over the field K, and an (A,A)-bimodule M.
+@* Instead of working with M over A, we define the enveloping algebra A^{env} = A otimes_K A^{opp}
+@* (this can be done with command envelope(A)) and embed M into A^{env} via imap().
+@* Thus we obtain the left A^{env}-module M otimes 1 in A^{env}.
+@* This has a lot of advantages, because left module theory has much more commands
+@* that are already implemented in SINGULAR:PLURAL. Two important procedures that we can use are std()
+@* which computes the left Groebner basis, and NF() which computes the left normal form.
+@* With the help of this method we are also able to determine the set of bisyzygies of a bimodule.
+@*
+@* A built-in command @code{twostd} in PLURAL computes the two-sided Groebner basis of an ideal
+@* by using the right completion algorithm of [2]. @code{bistd} from this library uses very different
+@* approach, which is often superior to the right completion.
+
+REFERENCES:
+@* The procedure bistd() is the implementation of an algorithm M. del Socorro Garcia Roman presented in [1](page 66-78).
+@* [1] Maria del Socorro Garcia Roman, Effective methods in Algebras with PBW bases:
+@* G-algebras and Yang-Baxter Algebras, Ph.D. thesis, Universidad de La Laguna, 2005.
+@* [2] Viktor Levandovskyy, Non-commutative Computer Algebra for polynomial Algebras:
+@* Groebner Bases, Applications and Implementations, Ph.D. thesis, Kaiserlautern, 2005.
+@* [3] N. Jacobson, The theory of rings, AMS, 1943.
+@* [4] P. M. Cohn, Free Rings and their Relations, Academic Press Inc. (London) Ltd., 1971.
+
+PROCEDURES:
+bistd(M);      computes the two-sided Groebner bases of an ideal or module
+bitrinity(M);  computes the trinity of M: Groebner basis, lift matrix and bisyzygies
+liftenvelope(M,g); computes the coefficients of an element g concerning the generators of a bimodule M in the enveloping algebra
+CompDecomp(p); returns an ideal which contains the component decomposition of a polynomial p in the enveloping algebra regarding the right side of the tensors
+isPureTensor(p); checks whether an element p in A^{env} is a pure tensor
+isTwoSidedGB(I);   checks whether an ideal I is two-sided Groebner basis
+
+SEE ALSO: ncalg_lib; nctools_lib
+
+KEYWORDS: bimodules; bisyzygies; lift; enveloping algebra; pure tensor; total divisors; two-sided; two-sided Groebner basis; tensor
+
+";
+
+LIB "ncalg.lib";
+LIB "nctools.lib";
+
+proc testbimoduleslib()
+{
+  /* tests all procs for consistency */
+  "MAIN PROCEDURES:";
+  example bistd;
+  example bitrinity;
+  example liftenvelope;
+  example isPureTensor;
+  example isTwoSidedGB;
+  "SECONDARY BIMODULES PROCEDURES:";
+  example enveltrinity;
+  example CompDecomp;
+}
+
+proc bistdIdeal (ideal M)
+"does bistd directly for ideals
+"
+{
+  intvec optionsave = option(get);
+  option(redSB);
+  option(redTail);
+  def save = basering ;
+  def saveenv = envelope(save);
+  setring saveenv;
+  ideal M = imap(save, M);
+  int i; int n = nvars(save);
+  ideal K;
+  for (i=1; i <= n; i++)
+  {
+    K[i] = var(i)-var(2*n-i+1);
+  }
+  M = M+K;
+  M = std(M);
+  option(set,optionsave);
+  setring save;
+  list L = ringlist(save);
+  if (size(ringlist(save)) > 4)
+  {
+    L = delete(L,6);
+    L = delete(L,5);}
+  def Scom = ring(L);
+  setring Scom;
+  ideal P;
+  for (i= 1; i <= n; i++)
+  {
+    P[i] = var(i);
+    P[2*n-i+1] = var(i);
+  }
+  map Pi = saveenv, P;
+  ideal N = Pi(M) ;
+  setring save;
+  ideal MM = fetch(Scom,N);
+  return(MM);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring w = 0,(x,s),Dp;
+  def W=nc_algebra(1,s); // 1st shift algebra
+  setring W;
+  ideal I1 = s^3-x^2*s;
+  print(matrix(bistd(I1))); // compare with twostd:
+  print(matrix(twostd(I1)));
+  ideal I2 = I1, x*s;
+  print(matrix(bistd(I2))); // compare with twostd:
+  print(matrix(twostd(I2)));
+}
+
+proc bistd (module M)
+"USAGE: bistd(M); M is (two-sided) ideal/module
+RETURN: ideal or module (same type as the argument)
+PURPOSE: Computes the two-sided Groebner basis of an ideal/module with the help the enveloping algebra of the basering, alternative to twostd() for ideals.
+EXAMPLE: example bistd; shows examples
+"
+{
+  // VL: added simplify
+  // commented out: Additionally you should use simplify(N,2+4+8) on the output N = bistd(M), where M denotes to the ideal/module in the argument.
+  // NOTE: option(redSB), option(redTail) are used by the procedure.
+  //    intvec optionsave = option(get);
+  //      option(redSB);
+  //      option(redTail);
+  int ROW = nrows(M);
+  def save = basering ;
+  def saveenv = envelope(save);
+  setring saveenv;
+  module M = imap(save, M);
+  int i; int n = nvars(save);
+  module B;
+  for (i=1; i <= n; i++)
+  {
+    B[i] = var(i) - var(2*n-i+1);
+  }
+  module K ; int j;int m = 1;
+  for (i=1; i <= n; i++)
+  {
+    for(j=1;j<=ROW;j++)
+    {
+      K[m]= B[i][1,1]*gen(j);m++;
+    }
+  }
+  M = M+K;
+  M = std(M);
+  //   option(set,optionsave);
+  setring save;
+  list L = ringlist(save);
+  if (size(ringlist(save)) > 4)
+  {L = delete(L,6);L = delete(L,5);}
+  def Scom = ring(L);
+  setring Scom;
+  ideal P;
+  for (i= 1; i <= n; i++)
+  {
+    P[i] = var(i) ;
+    P[2*n-i+1] = var(i);
+  }
+  map Pi = saveenv, P;
+  module N = Pi(M) ;
+  setring save;
+  module MM = fetch(Scom,N);
+  if (nrows(MM)==1)
+  {
+    //i.e. MM is an ideal indeed
+    ideal @M = ideal(MM);
+    kill MM;
+    ideal MM = @M;
+  }
+  MM = simplify(MM,2+4+8);
+  return(MM);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring w = 0,(x,s),Dp;
+  def W=nc_algebra(1,s); // 1st shift algebra
+  setring W;
+  matrix m[3][3]=[s^2,s+1,0],[s+1,0,s^3-x^2*s],[2*s+1, s^3+s^2, s^2];
+  print(m);
+  module L = m; module M2 = bistd(L);
+  print(M2);
+}
+
+proc enveltrinityIdeal(ideal f)
+" enveltrinity for an ideal directly"
+{
+  // AUXILIARY PROCEDURES: Uses Zersubcols(matrix N, int l).
+  intvec optionsave = option(get);
+  def save = basering ;
+  option(redSB);
+  int i; int n = nvars(save);
+  def saveenv = envelope(save);
+  setring saveenv;
+  def R = makeModElimRing(saveenv); setring R;
+  ideal K;
+  for (i=1; i <= n; i++)
+  { K[i] = var(i)-var(2*n-i+1);}
+  K = std(K);
+  ideal f = imap(save, f);
+  // now we compute the trinity (GB,Liftmatrix,Syzygy)
+  // can do it with f but F=NF(f,kr), so the ideals are the same in R env
+  ideal I = f, K;   // ideal I = F, K;
+  int l = ncols(I);
+  int j = ncols(f);
+  matrix M[j+1][l];
+  for (i = 1; i<= l;i++)
+  {
+    M[1,i] = I[i];
+  }
+  for (i=1; i <= j;i++)
+  {
+    M[i+1,i] = 1;
+  }
+  matrix N = std(M);
+  option(set,optionsave);
+  int m = ncols(N);
+  intvec sypos;
+  for (i=1; i <= m; i++)
+  {
+    if (N[1,i] == 0)
+    {
+      sypos = sypos,i;
+    }
+  }
+  intvec Nrows = 2..(j+1);
+  matrix BS = submat(N,Nrows,sypos); // e.g. for each column (b_1,...,b_j) you get 0 = sum_i (b_i*f_i)
+  module BSy = BS;
+  setring saveenv;
+  ideal K = imap(R,K);
+  module BS = imap(R,BSy);
+  matrix N = imap(R,N);
+  kill R;
+  export K; export BS; export N;
+  return(saveenv);
+}
+
+static proc Zersubcols(matrix N, int l)
+{
+  if (nrows(N) <= l)
+  {
+    string f = "Inputinteger ist zu gross. Muss kleiner sein als die Anzahl der Zeilen von der Inputmatrix."; return(f);
+  }
+  else
+  {
+    matrix O[l][1]; int m = ncols(N);
+    matrix H = submat(N,1..l,1..m);
+    int i;
+    intvec s;
+    intvec c;
+    for(i=1; i<= m;i++)
+    {
+      if(H[i] != O[1]) {c = c,i;}
+      else {s = s,i;}
+    }
+    list L = s,c;
+    return(L);
+  }
+}
+
+proc enveltrinity(module M)
+"USAGE: enveltrinity(M); M is (two-sided) ideal/module
+RETURN: ring, the enveloping algebra of the basering with objects K, N, BS in it.
+PURPOSE: compute two-sided Groebner basis, module of bisyzygies and the bitransformation matrix of M.
+THEORY: Assume R is a G-algebra generated by x_1, \dots x_k. Let psi_s be the epimorphism of left R (X) R^{opp} modules:
+@*  psi_s (s (X)_K t) = smt := (s_1 m t_1, ... , s_s m t_s) = (\psi(s_1 (X) t_1) , ... , psi(s_s (X) t_s)) in R^s
+@* additionally we define for a given bimodule M = < f_1, ... , f_r > the matrix M' := [F, I_r], [K, 0]
+@* where I_r refers to the identity matrix in Mat(r,R), K is a matrix which columns are the generators of the kernel of psi_s.
+@* These have the form (x_i-X_i)e_j for j in {1,...,s}, i in {1,...,k}.
+@* The matrix F = (f_1 ... f_r), where the f_i's are the generators of M and 0 is the matrix with only entries that are zero.
+@* Enveltrinity() calculates the kernel K of psi_s and left normal form N of the matrix M' which also yields the bisyzygies of M
+@* and a coefficient matrix as submatrix of N which we need in the procedures bitrinity() and liftenevelope().
+
+NOTE: In the output,
+@* ideal/module K is the kernel of psi_s above
+@* matrix N is the left Groebner basis of the matrix M'
+@* module BS corresponds to the set of bisyzygies of M.
+@* To get K,N or BS, use @code{def G = enveltrinity(M); setring G; K; N; BS;}.
+EXAMPLE: example enveltrinity; shows examples
+"
+{
+  def save = basering ;
+  intvec optionsave = option(get);
+  option(redSB);
+  int ROW = nrows(M);
+  int i; int n = nvars(save);
+  def saveenv = envelope(save);
+  setring saveenv;
+  def R = makeModElimRing(saveenv); setring R;
+  module B;
+  for (i=1; i <= n; i++)
+  { B[i] = var(i) - var(2*n-i+1);}
+  module K ; int t;int g = 1;
+  for (i=1; i <= n; i++)
+  {
+    for(t=1;t<=ROW;t++)
+    {
+      K[g]= B[i][1,1]*gen(t);g++;
+    }
+  }
+  K = std(K);
+  module M = imap(save,M);
+  module I = M,K;
+  int l = ncols(I);
+  int j = ncols(M);
+
+  matrix NN[j+ROW][l];
+  for (t=1; t <= ROW; t++)
+  {
+    for (i = 1; i<= l;i++)
+    { NN[t,i] = I[t,i];}
+  }
+  for (i=ROW+1; i <= j+ROW;i++)
+  { NN[i,i-ROW] = 1;}
+  // now we compute the trinity (GB,Liftmatrix,Syzygy)
+  // can do it with f but F=NF(f,kr), so the ideals are the same in R env
+  matrix N = std(NN);
+  option(set,optionsave);
+  intvec sypos = Zersubcols(N,ROW)[1];
+  sypos = sypos[2..nrows(sypos)];
+  intvec Nrows = (ROW+1)..(j+ROW);
+  matrix BS = submat(N,Nrows,sypos);  // e.g. for each column (b_1,...,b_j) you get 0 = sum_i (b_i*f_i)
+  module BSy = BS;
+  setring saveenv;
+  matrix N = imap(R,N); module BS = imap(R,BSy);
+  module K = imap(R,K);
+  if (nrows(K)==1)
+  {
+    // i.e. K is an ideal
+    ideal @K = ideal(K);
+    kill K;
+    ideal K = @K;
+  }
+  kill R;
+  export K;
+  export BS;
+  export N;
+  return(saveenv);
+}
+example
+{"EXAMPLE"; echo = 2;
+  ring r = 0,(x,s),dp;
+  def R = nc_algebra(1,s); setring R;
+  poly f = x*s + s^2;
+  ideal I = f;
+  def G = enveltrinity(I);
+  setring G;
+  print(matrix(K)); // kernel of psi_s
+  print(BS); // module of bisyzygies
+  print(N); // bitransformation matrix
+}
+
+proc bitrinityIdeal(ideal f)
+"direct appl of bitrinity to ideal"
+{
+  intvec optionsave = option(get);
+  option(redSB);
+  option(redTail);
+  int j = ncols(f);
+  def A = enveltrinity(f);
+  setring A; // A = envelope(basering)
+  int i;
+  def R = makeModElimRing(A); setring R;
+  ideal K = imap(A,K); K = std(K);
+  option(set,optionsave);
+  matrix N = imap(A,N);
+  int m = ncols(N);
+  //decomposition of N: Liftmatrix, Bisyzygymatrix:
+  intvec cfpos;
+  for (i=1; i <= m; i++)
+  { if (N[1,i] != 0)
+    {cfpos = cfpos,i;}
+  }
+  cfpos = cfpos[2..nrows(cfpos)];
+  matrix C = submat(N,1..(j+1),cfpos);
+  module Coef;
+  for(i=1;i<=ncols(C);i++)
+  {
+    poly p = NF(C[1,i],K);
+    if( (p != 0) && (p == C[1,i]))
+    {  Coef = Coef,C[i];}
+  }
+  matrix Co = Coef;
+  matrix Coe = submat(Co,1..nrows(Co),2..ncols(Co));
+  module CC = Coe;      //e.g. i-th column is (a_i1,...,a_ij) (see top)
+  setring A;
+  matrix Coeff = imap(R,CC); matrix Bisyz = BS;// e.g. for each column (b_1,...,b_j) you get 0 = sum_i (b_i*f_i)
+  kill R;
+  list L = Coeff,Bisyz;
+  // output is a Coefficient-Matrix Co and a Bisyzygy-Matriy BS such that (g1,...,gk) = (f1,...,fj)*Submat(Coeff,2..nrows(Coeff),1..ncols(Coeff)) and (0,...,0) = (f1,...,fj)*BiSyz
+  export L;
+  return(A);
+}
+
+proc bitrinity(module M)
+"USAGE: bitrinity(M); M is (two-sided) ideal/module
+RETURN: ring, the enveloping algebra of the basering, with objects in it.
+additionally it exports a list L = Coeff, Bisyz.
+THEORY:
+Let  psi_s be the epimorphism of left R (X) R^{opp} modules:
+@*  psi_s(s (X)_K t) = smt := (s_1 m t_1, ... , s_s m t_s) = (\psi(s_1 (X) t_1) , \dots , psi(s_s (X) t_s)) in R^s.
+@* Then psi_s(A) := (psi_s(a_{ij})) for every matrix A in Mat(n x m, R)$.
+@* For a two-sided ideal I = < f_1, ... , f_j> with Groebner basis G = {g_1, ... , g_k} in R, Coeff is the Coefficient-Matrix and
+BiSyz a bisyzygy matrix.
+@* Let C be the submatrix of Coeff, where C is Coeff without the first row. Then
+(g_1,...,g_k) = psi_s(C^T * (f_1 ... f_j)^T) and (0,...,0) = psi_s(BiSyz^T * (f_1 ... f_j)^T).
+@* The first row of Coeff (G_1 ... G_n)$ corresponds to the image of the Groebner basis of I:
+psi_s((G_1 ... G_n)) = G = {g_1 ... g_k }.
+@* For a (R,R)-bimodule M with Groebner basis G = {g_1, ... , g_k} in R^r, Coeff is the coefficient matrix and
+BiSyz a bisyzygy matrix.
+@* Let C be the submatrix of Coeff, where C is Coeff without the first r rows. Then
+(g_1 ... g_k) = psi_s(C^T * (f_1 ... f_j)^T) and (0 ... 0) = psi_s(BiSyz^T * (f_1 ... f_j)^T).
+@* The first r rows of Coeff = (G_1 ... G_n) (Here G_i denotes to the i-th column of the first r rows) corresponds to the image of the
+Groebner basis of M: psi_s((G_1 ... G_n)) = G = {g_1 ... g_k}.
+PURPOSE: This procedure returns a coefficient matrix in the enveloping algebra of the basering R, that gives implicitly the two-sided Groebner basis of a (R,R)-bimodule M
+and the coefficients that produce the Groebner basis with the help of the originally used generators of M. Additionally it calculates the bisyzygies of M as left-module of the enveloping algebra of R.
+AUXILIARY PROCEDURES: Uses the procedure enveltrinity().
+NOTE: To get list L = Coeff, BiSyz, we set: def G = bitrinity(); setring G; L; or $L[1]; L[2];.
+EXAMPLE: example bitrinity; shows examples
+"
+{
+  intvec optionsave = option(get);
+  option(redSB);
+  option(redTail);
+  int ROW = nrows(M); int j = ncols(M);
+  def A = enveltrinity(M);
+  setring A; // A = envelope(basering)
+  int i;
+  def R = makeModElimRing(A); setring R;
+  module K = imap(A,K); K = std(K);
+  option(set,optionsave);
+  matrix N = imap(A,N);
+  int m = ncols(N);
+  //decomposition of N: Liftmatrix, Bisyzygymatrix:
+  intvec cfpos = Zersubcols(N,ROW)[2];
+  cfpos = cfpos[2..nrows(cfpos)];
+  matrix C1 = submat(N,1..nrows(N),cfpos);
+  matrix C2 = submat(N,1..ROW,cfpos);
+  module Coef; matrix O[ROW][1];
+  module p;
+  for(i=1;i<=ncols(C2);i++)
+  {
+    p = NF(C2[i],K);
+    if( (p[1] != O[1]) && (p[1] == C2[i]))
+    {  Coef = Coef,C1[i];}
+  }
+  matrix Co = Coef;
+  matrix Coe = submat(Co,1..nrows(Co),2..ncols(Co));
+  module CC = Coe;
+  setring A;
+  matrix Coeff = imap(R,CC); matrix Bisyz = BS;
+  kill R;
+  list L = Coeff,Bisyz;
+  export L;
+  return(A);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,s),dp;
+  def R = nc_algebra(1,s); setring R; // 1st shift algebra
+  poly f = x*s + s^2; // only one generator
+  ideal I = f; // note, two sided Groebner basis of I is xs, s^2
+  def G = bitrinity(I);
+  setring G;
+  print(L[1]); // Coeff
+//the first row shows the Groebnerbasis of I consists of
+// psi_s(SX) = xs , phi(S^2) = s^2:
+// remember phi(a (X) b - c (X) d) = psi_s(a (X) b) - phi(c (X) d) := ab - cd in R.
+// psi_s((-s+S+1)*(x*s + s^2)) = psi_s(-xs2-s3+xsS+xs+s2S)
+// = -xs^2-s^3+xs^2+xs+s^3 = xs
+// psi_s((s-S)*(x*s + s^2)) = psi_s(xs2+s3-xsS-s2S+s2) = s^2
+  print(L[2]);  //Bisyzygies
+// e.g. psi_s((x2-2sS+s-X2+2S2+2X+S-1)(x*s + s^2))
+// = psi_s(x3s+x2s2-2xs2S+xs2-2s3S+s3-xsX2+2xsS2+2xsX+xsS-xs-s2X2+2s2S2+2s2X-s2S)
+// = x^3s+x^2s^2-2xs^3+xs^2-2s^4+s^3-xsx^2+2xs^3+2xsx+xs^2-xs-s^2x^2+2s^4+2s^2x-s^3
+// = 0 in R
+}
+
+proc liftenvelope(module I,poly g)
+"USAGE: liftenvelope(M,g); M ideal/module, g poly
+RETURN: ring, the enveloping algebra of the basering R.
+Given a two-sided ideal M in R and a polynomial g in R this procedure returns the enveloping algebra of R.
+Additionally it exports a list l = C, B; where B is the left Groebner basis of the left-syzygies of M \otimes 1 and C is a vector of coefficients in the enveloping algebra
+of R such that psi_s(C^T *(f_1 \dots f_n)) = g.
+@* psi_s is an epimorphism of left R (X) R^{opp} modules:
+@*  psi_s (s (X)_K t) = smt := (s_1 m t_1, ... , s_s m t_s) = (\psi(s_1 (X) t_1) , \dots , psi(s_s (X) t_s)) in R^s.
+@* Then psi_s(A) := (psi_s(a_{ij})) for every matrix A in Mat(n x m, R)$.
+ASSUME: The second component has to be an element of the first component.
+PURPOSE: This procedure is used for computing total divisors. Let {f_1, ..., f_n} be the generators of the first component and let the second component be called g. Then
+the returned list l = C, B = (b_1, ..., b_n); defines an affine set A = C + sum_i a_i b_i with (a_1,..,a_n) in the enveloping algebra of the basering R such that
+psi_s(a^T * (f_1 ... f_n)) = g for all a in A. For certain rings R, we csn find pure tensors within this set A,
+and if we do, liftenvelope() helps us to decide whether f is a total divisor of g.
+NOTE: To get list l = C, B. we set: def G = liftenvelope(); setring G; l; or l[1]; l[2];.
+EXAMPLE: example liftenvelope; shows examples
+"
+{
+    def save = basering;
+    int m = ncols(I);
+    intvec optionsave = option(get);
+    option(redSB);
+    option(redTail);
+    def A = enveltrinity(I);
+    setring A; // A = envelope(basering)
+    int i;
+    def R = makeModElimRing(A); setring R;
+    module N = imap(A,N); N = std(N);
+    //intvec Nrows = 2..(j+1);
+    module g = imap(save,g);
+    matrix G[nrows(N)][1];
+    for (i=2;i<=m;i++)
+    {
+      G[1,1] = g;
+      G[i,1]=0;
+    }
+    module NFG = (-1)*NF(G,N);
+    module C = submat(NFG,2..nrows(N),1);
+
+    setring A;
+    module C = imap(R,C);
+    kill R;
+    module B = std(BS);
+    option(set,optionsave);
+    list l = C,B; // transpose(C)*(f1,...,fn) = g
+    export l;
+    return(A);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,s),dp;
+  def R = nc_algebra(1,s); setring R;
+  ideal I = x*s;
+  poly p = s*x*s*x;  // = (s (x) x) * x*s = (sX) * x*s
+  p;
+  def J = liftenvelope(I,p);
+  setring J;
+  print(l[1]);
+  //2s+SX = (2s (x) 1) + (1 (x) sx)
+  print(l[2]);
+  // Groebnerbasis of BiSyz(I) as LeftSyz in R^{env}
+  // We get : 2s+SX + ( sX - 2s -SX) = sX  - a pure tensor!!!!
+}
+
+static proc twoComp(poly q)
+"USAGE: twoComp(g); g poly
+NOTE: This procedure only works if the basering is an enveloping algebra A^{env} of a (non-commutative) ring A. Thus also the polynomial in the argument has to be in A^{env}.
+RETURN: Returns the second half of the leading exponent of a polynomial p in A^{env}:
+@* lm(p) = c x1^a1 x2^a2 ... xn^an (X) xn^bn * x(n-1)^b(n-1) * ... * x1^b1
+such that lex(p) = [a1,..,an,bn,...,b1]. Then the procedure returns [bn,...,b1] (of lex(p)!).
+"
+{
+      if (q == 0) {return(q);}
+      def saveenv = basering;
+      int n = nvars(saveenv); int k = n div 2;
+      intvec v = leadexp(q);
+      intvec w = v[k+1..2*k];
+      return(w);
+}
+
+static proc firstComp(poly q)
+"USAGE: firstComp(g); g poly
+NOTE: This procedure only works if the basering is an enveloping algebra A^{env} of a (non-commutative) ring A. Thus also the polynomial in the argument has to be in A^{env}.
+RETURN: Returns the first half of the leading exponent of a polynomial p in A^{env}:
+@* lm(p) = c x1^a1 x2^a2 ... xn^an (X) xn^bn * x(n-1)^b(n-1) * ... * x1^b1
+such that lex(p) = [a1,..,an,bn,...,b1]. Then the procedure returns [a1,...,an] (of lex(p)!).
+"
+{
+      if (q == 0) {return(q);}
+      def saveenv = basering;
+      int n = nvars(saveenv); int k = n div 2;
+      intvec v = leadexp(q);
+      intvec w = v[1..k];
+      return(w);
+}
+
+
+proc CompDecomp(poly p)
+"USAGE: CompDecomp(p); p poly
+NOTE: This procedure only works if the basering is an enveloping algebra A^{env} of a (non-commutative) ring A. Thus also the polynomial in the argument has to be in A^{env}.
+RETURN: Returns an ideal I in A^{env}, where the sum of all terms of the argument with the same right side (of the tensor summands) are stored as a generator of I.
+@* Let b != c, then for p = (a (X) b) + (c (X) b) + (a (X) c) the ideal I := CompDecomp(p) is given by: I[1] = (a (X) b) + (c (X) b); I[2] = a (X) c.
+PURPOSE: By decomposing the polynomial we can easily check whether the given polynomial is a pure tensor.
+EXAMPLE: example CompDecomp; shows examples
+"
+{
+      poly s = p;
+      ideal Q;
+      int j = 0; poly t; poly w;
+      while (s!= 0)
+      {
+        t = lead(s);
+        w = s-t;
+        s = s-t;
+        j++;
+        Q[j] = t;
+        while(w !=0)
+        {
+          if (twoComp(w) == twoComp(t))
+          {
+            Q[j] = Q[j]+lead(w);
+            s = s-lead(w);
+          }
+          w = w-lead(w);
+        }
+      }
+      return(Q);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,s),dp;
+  def R = nc_algebra(1,s); setring R; //1st shift algebra
+  def Re = envelope(R); setring Re; //basering is now R^{env} = R (X) R^{opp}
+  poly f = X*S*x^2+5*x*S*X+S*X; f;
+  ideal I = CompDecomp(f);
+  print(matrix(I)); // what means that f = (x2+5x+1)*SX + x2*S
+  poly p = x*S+X^2*S+2*s+x*X^2*s+5*x*s; p;
+  ideal Q = CompDecomp(p);
+  print(matrix(Q));
+}
+
+proc getOneComp(poly p)
+"USAGE: getOneComp(p); p poly
+NOTE: This procedure only works if the basering is an enveloping algebra A^{env} of a (non-commutative) ring A. Thus also the polynomial in the argument has to be in A^{env}.
+ASSUME: The given polynomial has to be of the form sum_i a_i \otimes b = (sum_i a_i) (X) b.
+RETURN: Returns a polynomial in A^{env}, which is the sum of the left-side (of the tensor summands) of all terms of the argument.
+@* Let A be a G-algebra. For a given polynomial p in A^{env} of the form p = sum_i a_i (X) b = (sum_i a_i) (X) b this procedure returns
+g = (\sum_i a_i) (X) 1  written sum_i a_i in A^{env}.
+PURPOSE: This is an auxiliary procedure for isPureTensor().
+EXAMPLE: example getOneComp; shows examples
+"
+{
+    ideal I;
+    int i; int m = size(p);poly f;
+    if (size(p) == 0) {f = 1; return(f);}
+    for(i=1;i<=m;i++)
+         { I[i] = leadcoef(p[i])*monomial(firstComp(p[i]));}
+    f = sum(I);
+    return(f);
+ }
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,s),dp;
+  def R = nc_algebra(1,s); setring R; //1st shift algebra
+  def Re = envelope(R); setring Re; //basering is now R^{env} = R (X) R^{opp}
+  poly f = 5*x*s*S+x^2*S+s*S+3*x*S;  // f = (x2+5xs+3x+s)*S
+  getOneComp(f);
+}
+
+proc isPureTensor(poly g)
+"USAGE: isPureTensor(g); g poly
+NOTE: This procedure only works if the basering is an enveloping algebra A^{env} of a (non-commutative) ring A. Thus also the polynomial in the argument has to be in A^{env}.
+RETURN: Returns 0 if g is not a pure tensor and if g is a pure tensor then isPureTensor() returns a vector v with v = a*gen(1)+b*gen(2) = (a,b)^T with a (X) b = g.
+PURPOSE: Checks whether a given polynomial in $\A^{env}$ is a pure tensor. This is also an auxiliary procedure for checking total divisibility.
+EXAMPLE: example isPureTensor; shows examples
+"
+{
+  ideal I = CompDecomp(g);
+  ideal U;int i; int k = ncols(I);
+  for (i = 1 ; i <= k; i++)
+  {
+    U[i] = getOneComp(I[i]);
+  }
+  poly q = normalize(U[1]);
+  for (i=2; i<= k;i++)
+  {
+    if ( U[i] != leadcoef(U[i])*q)
+    {
+      return(0);
+    }
+  }
+  def saveenv = basering;
+  int n = nvars(saveenv); int l = n div 2;
+  ideal P; intvec d = 0:l;
+  intvec vv;
+  for (i=1;i<=k;i++)
+  {
+    vv= d,twoComp(I[i]);
+    P[i] = leadcoef(U[i])*monomial(vv);
+  }
+  poly w = sum(P);
+  vector v = [q, w];
+  return(v);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,s),dp;
+  def R = nc_algebra(1,s); setring R; //1st shift algebra
+  def Re = envelope(R); setring Re; //basering is now R^{env} = R (X) R^{opp}
+  poly p = x*(x*s)*x + s^2*x; p;
+  // p is of the form q(X)1, a pure tensor indeed:
+  isPureTensor(p);
+  // v = transpose( x3s+x2s+xs2+2s2  1 ) i.e. p = x3s+x2s+xs2+2s2 (X) 1
+  poly g = S*X+ x*s*X+ S^2*x;
+  g;
+  isPureTensor(g); // indeed g is not a pure tensor
+  poly d = x*X+s*X+x*S*X+s*S*X;d;
+  isPureTensor(d); // d is a pure tensor indeed
+  // v = transpose( x+s  S*X+X ) i.e. d = x+s (X) s*x+x
+  // remember that * denotes to the opposite mulitiplication s*x = xs in R.
+}
+
+proc isTwoSidedGB(ideal I)
+"USAGE: isTwoSidedGB(I); I ideal
+RETURN: Returns 0 if the generators of a given ideal are not two-sided, 1 if they are.\\
+NOTE: This procedure should only be used for non-commutative rings, as every element is two-sided in a commutative ring.
+PURPOSE: Auxiliary procedure for diagonal forms. Let R be a non-commutative ring (e.g. G-algebra), and p in R, this program checks whether p is two-sided i.e. Rp = pR.
+EXAMPLE: example isTwoSidedGB; shows examples
+"
+{
+  int i; int n = nvars(basering);
+  ideal J;
+  // determine whether I is a left Groebner basis
+  if (attrib(I,"isSB") == 1)
+  {
+    J = I;
+    J = simplify(J,1+2+4+8);
+    attrib(J,"isSB",1);
+  }
+  else
+  {
+    intvec optionsave = option(get);
+    option(redSB);
+    option(redTail);
+    J = std(I);
+    J = simplify(J,1+2+4+8);
+    attrib(J,"isSB",1);
+    I = interred(I);
+    I = simplify(I,1+2+4+8);
+    if ( size(J) != size(I))
+    {
+      option(set,optionsave);
+      return(int(0));
+    }
+    for(i = 1; i <= size(I); i++)
+    {
+      if (I[i] != J[i])
+      {
+        option(set,optionsave);
+        return(int(0));
+      }
+    }
+  }
+  //  I = simplify(I,1+2+4+8);
+  // now, we check whether J is right complete
+  for(i = 1; i <= n; i++)
+  {
+    if ( simplify( NF(J*var(i),J), 2) != 0 )
+    {
+      return(int(0));
+    }
+  }
+  return(int(1));
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,s),dp;
+  def R = nc_algebra(1,s); setring R; //1st shift algebra
+  ideal I = s^2, x*s, s^2 + 3*x*s;
+  isTwoSidedGB(I); // I is two-sided
+  ideal J = s^2+x;
+  isTwoSidedGB(J); // J is not two-sided; twostd(J) = s,x;
+}
diff --git a/Singular/LIB/brnoeth.lib b/Singular/LIB/brnoeth.lib
new file mode 100644
index 0000000..2c448ca
--- /dev/null
+++ b/Singular/LIB/brnoeth.lib
@@ -0,0 +1,5022 @@
+////////////////////////////////////////////////////////////////
+version="version brnoeth.lib 4.0.0.0 Jun_2013 "; // $Id: 77922abdbed7c92461109f27aa8b002186839899 $
+category="Coding theory";
+info="
+LIBRARY:   brnoeth.lib  Brill-Noether Algorithm, Weierstrass-SG and AG-codes
+AUTHORS:   Jose Ignacio Farran Martin, ignfar at eis.uva.es
+           Christoph Lossen,           lossen at mathematik.uni-kl.de
+
+OVERVIEW:
+ Implementation of the Brill-Noether algorithm for solving the
+ Riemann-Roch problem and applications to Algebraic Geometry codes.
+ The computation of Weierstrass semigroups is also implemented.@*
+ The procedures are intended only for plane (singular) curves defined over
+ a prime field of positive characteristic.@*
+ For more information about the library see the end of the file brnoeth.lib.
+
+PROCEDURES:
+ Adj_div(f)            computes the conductor of a curve
+ NSplaces(h,A)         computes non-singular places with given degrees
+ BrillNoether(D,C)     computes a vector space basis of the linear system L(D)
+ Weierstrass(P,m,C)    computes the Weierstrass semigroup of C at P up to m
+ extcurve(d,C)         extends the curve C to an extension of degree d
+ AGcode_L(G,D,E)       computes the evaluation AG code with divisors G and D
+ AGcode_Omega(G,D,E)   computes the residual AG code with divisors G and D
+ prepSV(G,D,F,E)       preprocessing for the basic decoding algorithm
+ decodeSV(y,K)         decoding of a word with the basic decoding algorithm
+ closed_points(I)      computes the zero-set of a zero-dim. ideal in 2 vars
+ dual_code(C)          computes the dual code
+ sys_code(C)           computes an equivalent systematic code
+ permute_L(L,P)        applies a permutation to a list
+
+KEYWORDS:  Weierstrass semigroup; Algebraic Geometry codes;
+           Brill-Noether algorithm
+";
+
+LIB "matrix.lib";
+LIB "triang.lib";
+LIB "hnoether.lib";
+LIB "inout.lib";
+
+///////////////////////////////////////////////////////////////////////////////
+
+// **********************************************************
+// * POINTS, PLACES AND DIVISORS OF (SINGULAR) PLANE CURVES *
+// **********************************************************
+
+proc closed_points (ideal I)
+"USAGE:     closed_points(I); I an ideal
+RETURN:     list of prime ideals (each a Groebner basis), corresponding to
+            the (distinct affine closed) points of V(I)
+NOTE:       The ideal must have dimension 0, the basering must have 2
+            variables, the ordering must be lp, and the base field must
+            be finite and prime.@*
+            It might be convenient to set the option(redSB) in advance.
+SEE ALSO:   triang_lib
+EXAMPLE:    example closed_points; shows an example
+"
+{
+  ideal II=std(I);
+  if (II==1)
+  {
+    return(list());
+  }
+  list TL=triangMH(II);
+  int s=size(TL);
+  list L=list();
+  int i,j,k;
+  ideal Facts;
+  poly G2;
+  for (i=1;i<=s;i=i+1)
+  {
+    Facts=factorize(TL[i][1],1);
+    k=size(Facts);
+    G2=TL[i][2];
+    for (j=1;j<=k;j=j+1)
+    {
+      L=L+pd2(Facts[j],G2);
+    }
+  }
+  // eliminate possible repetitions
+  s=size(L);
+  list LP=list();
+  LP[1]=std(L[1]);
+  int counter=1;
+  for (i=2;i<=s;i=i+1)
+  {
+    if (isPinL(L[i],LP)==0)
+    {
+      counter=counter+1;
+      LP[counter]=std(L[i]);
+    }
+  }
+  return(LP);
+}
+example
+{
+  "EXAMPLE:";  echo = 2;
+  ring s=2,(x,y),lp;
+  // this is just the affine plane over F_4 :
+  ideal I=x4+x,y4+y;
+  list L=closed_points(I);
+  // and here you have all the points :
+  L;
+}
+///////////////////////////////////////////////////////////////////////////////
+
+static proc pd2 (poly g1,poly g2)
+{
+  // If g1,g2 is a std. resp. lex. in (x,y) then the procedure
+  //    factorizes g2 in the "extension given by g1"
+  //    (then g1 must be irreducible) and returns a list of
+  //    ideals with always g1 as first component and the
+  //    distinct factors of g2 as second components
+  list L=list();
+  ideal J=g1;
+  int i,s;
+  if (deg(g1)==1)
+  {
+    poly A=-subst(g1,var(2),0);
+    poly B=subst(g2,var(2),A);
+    ideal facts=factorize(B,1);
+    s=size(facts);
+    for (i=1;i<=s;i=i+1)
+    {
+      J[2]=facts[i];
+      L[i]=J;
+    }
+  }
+  else
+  {
+    def BR=basering;
+    poly A=g1;
+    poly B=g2;
+    ring raux1=char(basering),(x,y, at a),lp;
+    poly G;
+    ring raux2=(char(basering), at a),(x,y),lp;
+    map psi=BR,x, at a; minpoly=number(psi(A)); if(!defined(psi)){ map psi=BR,x, at a; }
+    poly f=psi(B);
+    ideal facts=factorize(f,1);
+    s=size(facts);
+    poly g;
+    string sg;
+    for (i=1;i<=s;i=i+1)
+    {
+      g=facts[i];
+      sg=string(g);
+      setring raux1;
+      execute("G="+sg+";");
+      G=subst(G, at a,y);
+      setring BR;
+      map ppssii=raux1,var(1),var(2),0;
+      J[2]=ppssii(G);
+      L[i]=J;
+      kill ppssii;
+      setring raux2;
+    }
+    setring BR;
+    kill raux1,raux2;
+  }
+  return(L);
+}
+///////////////////////////////////////////////////////////////////////////////
+static proc isPinL (ideal P,list L)
+{
+  // checks if a (plane) point P is in a list of (plane) points L
+  //    by just comparing generators
+  // it works only if all (prime) ideals are given in a "canonical way",
+  // namely:
+  //    the first generator is monic and irreducible,
+  //        and depends only on the second variable,
+  //    and the second one is monic in the first variable
+  //        and irreducible over the field extension determined by
+  //        the second variable and the first generator as minpoly
+  int s=size(L);
+  int i;
+  for (i=1;i<=s;i=i+1)
+  {
+    if ( P[1]==L[i][1] && P[2]==L[i][2] )
+    {
+      return(1);
+    }
+  }
+  return(0);
+}
+///////////////////////////////////////////////////////////////////////////////
+static proc s_locus (poly f)
+{
+  // computes : ideal of affine singular locus
+  // the equation f must be affine
+  // warning : if there is an error message then the output is "none"
+  // option(redSB) is convenient to be set in advance
+  ideal I=f,jacob(f);
+  I=std(I);
+  if (dim(I)>0)
+  {
+    // dimension check (has to be 0)
+    ERROR("something was wrong; possibly non-reduced curve");
+  }
+  else
+  {
+    return(I);
+  }
+}
+///////////////////////////////////////////////////////////////////////////////
+static proc curve (poly f)
+"USAGE:      curve(f), where f is a polynomial (affine or projective)
+CREATE:     poly CHI in both rings aff_r=p,(x,y),lp and Proj_R=p,(x,y,z),lp
+            also ideal (std) Aff_SLocus of affine singular locus in the ring
+            aff_r
+RETURN:     list (size 3) with two rings aff_r,Proj_R and an integer deg(f)
+NOTE:       f must be absolutely irreducible, but this is not checked
+            it is not implemented yet for extensions of prime fields
+"
+{
+  def base_r=basering;
+  ring aff_r=char(basering),(x,y),lp;
+  ring Proj_R=char(basering),(x,y,z),lp;
+  setring base_r;
+  int degX=deg(f);
+  if (nvars(basering)==2)
+  {
+    setring aff_r;
+    map embpol=base_r,x,y;
+    poly CHI=embpol(f);
+    export(CHI);
+    kill embpol;
+    ideal Aff_SLocus=s_locus(CHI);
+    export(Aff_SLocus);
+    setring Proj_R;
+    poly CHI=homog(imap(aff_r,CHI),z);
+    export(CHI);
+    setring base_r;
+    list L=list();
+    L[1]=aff_r;
+    L[2]=Proj_R;
+    L[3]=degX;
+    kill aff_r,Proj_R;
+    return(L);
+  }
+  if (nvars(basering)==3)
+  {
+    setring Proj_R;
+    map embpol=base_r,x,y,z;
+    poly CHI=embpol(f);
+    export(CHI);
+    kill embpol;
+    string s=string(subst(CHI,z,1));
+    setring aff_r;
+    execute("poly CHI="+s+";");
+    export(CHI);
+    ideal Aff_SLocus=s_locus(CHI);
+    export(Aff_SLocus);
+    setring base_r;
+    list L=list();
+    L[1]=aff_r;
+    L[2]=Proj_R;
+    L[3]=degX;
+    kill aff_r,Proj_R;
+    return(L);
+  }
+  ERROR("basering must have 2 or 3 variables");
+}
+///////////////////////////////////////////////////////////////////////////////
+static proc Aff_SL (ideal ISL)
+{
+  // computes : affine singular (closed) points as a list of lists of
+  //     prime ideals and intvec (for storing the places over each point)
+  // the ideal ISL=s_locus(CHI) is assumed to be computed in advance for
+  //     a plane curve CHI, and it must be given by a standard basis
+  // for our purpose the function must called with the "global" ideal
+  //     "Aff_SLocus"
+  list SL=list();
+  ideal I=ISL;
+  if ( I[1] != 1 )
+  {
+    list L=list();
+    ideal aux;
+    intvec iv;
+    int i,s;
+    L=closed_points(I);
+    s=size(L);
+    for (i=1;i<=s;i=i+1)
+    {
+      aux=std(L[i]);
+      SL[i]=list(aux,iv);
+    }
+  }
+  return(SL);
+}
+///////////////////////////////////////////////////////////////////////////////
+static proc inf_P (poly f)
+{
+  // computes : all (closed) points at infinity as homogeneous polynomials
+  // output : two lists with respectively singular and non-singular points
+  intvec iv;
+  def base_r=basering;
+  ring r_auxz=char(basering),(x,y,z),lp;
+  poly f=imap(base_r,f);
+  poly F=homog(f,z);                    // equation of projective curve
+  poly f_inf=subst(F,z,0);
+  setring base_r;
+  poly f_inf=imap(r_auxz,f_inf);
+  ideal I=factorize(f_inf,1);           // points at infinity as homogeneous
+                                        // polynomials
+  int s=size(I);
+  int i;
+  list IP_S=list();                     // for singular points at infinity
+  list IP_NS=list();                    // for non-singular points at infinity
+  int counter_S;
+  int counter_NS;
+  poly aux;
+  for (i=1;i<=s;i=i+1)
+  {
+    aux=subst(I[i],y,1);
+    if (aux==1)
+    {
+      // the point is (1:0:0)
+      setring r_auxz;
+      poly f_yz=subst(F,x,1);
+      if ( subst(subst(diff(f_yz,y),y,0),z,0)==0 &&
+           subst(subst(diff(f_yz,z),y,0),z,0)==0 )
+      {
+        // the point is singular
+        counter_S=counter_S+1;
+        kill f_yz;
+        setring base_r;
+        IP_S[counter_S]=list(I[i],iv);
+      }
+      else
+      {
+        // the point is non-singular
+        counter_NS=counter_NS+1;
+        kill f_yz;
+        setring base_r;
+        IP_NS[counter_NS]=list(I[i],iv);
+      }
+    }
+    else
+    {
+      // the point is (a:1:0) | a is root of aux
+      if (deg(aux)==1)
+      {
+        // the point is rational and no field extension is needed
+        setring r_auxz;
+        poly f_xz=subst(F,y,1);
+        poly aux=imap(base_r,aux);
+        number A=-number(subst(aux,x,0));
+        map phi=r_auxz,x+A,0,z;
+        poly f_origin=phi(f_xz);
+        if ( subst(subst(diff(f_origin,x),x,0),z,0)==0 &&
+             subst(subst(diff(f_origin,z),x,0),z,0)==0 )
+        {
+          // the point is singular
+          counter_S=counter_S+1;
+          kill f_xz,aux,A,phi,f_origin;
+          setring base_r;
+          IP_S[counter_S]=list(I[i],iv);
+        }
+        else
+        {
+          // the point is non-singular
+          counter_NS=counter_NS+1;
+          kill f_xz,aux,A,phi,f_origin;
+          setring base_r;
+          IP_NS[counter_NS]=list(I[i],iv);
+        }
+      }
+      else
+      {
+        // the point is non-rational and a field extension with minpoly=aux
+        // is needed
+        ring r_ext=(char(basering), at a),(x,y,z),lp;
+        poly F=imap(r_auxz,F);
+        poly f_xz=subst(F,y,1);
+        poly aux=imap(base_r,aux);
+        minpoly=number(subst(aux,x, at a));
+        map phi=r_ext,x+ at a,0,z;
+        poly f_origin=phi(f_xz);
+        if ( subst(subst(diff(f_origin,x),x,0),z,0)==0 &&
+             subst(subst(diff(f_origin,z),x,0),z,0)==0 )
+        {
+          // the point is singular
+          counter_S=counter_S+1;
+          setring base_r;
+          kill r_ext;
+          IP_S[counter_S]=list(I[i],iv);
+        }
+        else
+        {
+          // the point is non-singular
+          counter_NS=counter_NS+1;
+          setring base_r;
+          kill r_ext;
+          IP_NS[counter_NS]=list(I[i],iv);
+        }
+      }
+    }
+  }
+  kill r_auxz;
+  return(list(IP_S,IP_NS));
+}
+///////////////////////////////////////////////////////////////////////////////
+static proc closed_points_ext (poly f,int d,ideal SL)
+{
+  // computes : (closed affine non-singular) points over an extension of
+  //            degree d
+  // remark(1) : singular points are supposed to be listed appart
+  // remark(2) : std SL=s_locus(f) is supposed to be computed in advance
+  // remark(3) : ideal SL is used to remove those points which are singular
+  // output : list of list of prime ideals with an intvec for storing the
+  //          places
+  int Q=char(basering)^d;             // cardinality of the extension field
+  ideal I=f,x^Q-x,y^Q-y;              // ideal of the searched points
+  I=std(I);
+  if (I==1)
+  {
+    return(list());
+  }
+  list LP=list();
+  int m=size(SL);
+  list L=list();
+  ideal aux;
+  intvec iv;
+  int i,s,j,counter;
+  L=closed_points(I);
+  s=size(L);
+  for (i=1;i<=s;i=i+1)
+  {
+    aux=std(L[i]);
+    for (j=1;j<=m;j=j+1)
+    {
+      // check if singular i.e. if SL is contained in aux
+      if ( NF(SL[j],aux) != 0 )
+      {
+        counter=counter+1;
+        LP[counter]=list(aux,iv);
+        break;
+      }
+    }
+  }
+  return(LP);
+}
+///////////////////////////////////////////////////////////////////////////////
+static proc degree_P (list P)
+"USAGE:      degree_P(P), where P is either a polynomial or an ideal
+RETURN:     integer with the degree of the closed point given by P
+SEE ALSO:   closed_points
+NOTE:       If P is a (homogeneous irreducible) polynomial the point is at
+            infinity, and if P is a (prime) ideal the points is affine, and
+            the ideal must be given by 2 generators: the first one irreducible
+            and depending only on y, and the second one irreducible over the
+            extension given by y with the first generator as minimal polynomial
+"
+{
+  // computes : the degree of a given point
+  // remark(1) : if the input is (irreducible homogeneous) polynomial => the point
+  //             is at infinity
+  // remark(2) : it the input is (std. resp. lp. prime) ideal => the point is
+  //             affine
+  if (typeof(P[1])=="ideal")
+  {
+    if (size(P[1])==2)
+    {
+      int d=deg(P[1][1]);
+      poly aux=subst(P[1][2],y,1);
+      d=d*deg(aux);
+      return(d);
+    }
+    else
+    {
+      // this should not happen in principle
+      ERROR("non-valid parameter");
+    }
+  }
+  else
+  {
+    if (typeof(P[1])=="poly")
+    {
+      return(deg(P[1]));
+    }
+    else
+    {
+      ERROR("parameter must have a polynomial or ideal in the first component");
+    }
+  }
+}
+///////////////////////////////////////////////////////////////////////////////
+static proc closed_points_deg (poly f,int d,ideal SL)
+{
+  // computes : (closed affine non-singular) points of degree d
+  // remark(1) : singular points are supposed to be listed appart
+  // remark(2) : std SL=s_locus(f) is supposed to be computed in advance
+  list L=closed_points_ext(f,d,SL);
+  int s=size(L);
+  int i,counter;
+  list LP=list();
+  for (i=1;i<=s;i=i+1)
+  {
+    if (degree_P(L[i])==d)
+    {
+      counter=counter+1;
+      LP[counter]=L[i];
+    }
+  }
+  return(LP);
+}
+///////////////////////////////////////////////////////////////////////////////
+static proc idealSubset (ideal I,ideal J)
+{
+  // checks wether I is contained in J and returns a boolean
+  // remark : J is assumed to be given by a standard basis
+  int s=ncols(I);
+  int i;
+  for (i=1;i<=s;i=i+1)
+  {
+    if ( NF(I[i],std(J)) != 0 )
+    {
+      return(0);
+    }
+  }
+  return(1);
+}
+///////////////////////////////////////////////////////////////////////////////
+static proc belongs (list P,ideal I)
+{
+  // checks if affine point P is contained in V(I) and returns a boolean
+  // remark : P[1] is assumed to be an ideal given by a standard basis
+  if (typeof(P[1])=="ideal")
+  {
+    return(idealSubset(I,P[1]));
+  }
+  else
+  {
+    ERROR("first argument must be an affine point");
+  }
+}
+///////////////////////////////////////////////////////////////////////////////
+static proc equals (ideal I,ideal J)
+{
+  // checks if I is equal to J and returns a boolean
+  // remark : I and J are assumed to be given by a standard basis
+  int answer=0;
+  if (idealSubset(I,J)==1)
+  {
+    if (idealSubset(J,I)==1)
+    {
+      answer=1;
+    }
+  }
+  return(answer);
+}
+///////////////////////////////////////////////////////////////////////////////
+static proc isInLP (ideal P,list LP)
+{
+  // checks if affine point P is a list LP and returns either its position or
+  //   zero
+  // remark : all points in LP and P itself are assumed to be given by a
+  //   standard basis
+  // warning : the procedure does not check whether the points are affine or
+  //   not
+  int s=size(LP);
+  if (s==0)
+  {
+    return(0);
+  }
+  int i;
+  for (i=1;i<=s;i=i+1)
+  {
+    if (equals(P,LP[i][1])==1)
+    {
+      return(i);
+    }
+  }
+  return(0);
+}
+///////////////////////////////////////////////////////////////////////////////
+static proc res_deg ()
+{
+  // computes the residual degree of the basering with respect to its prime
+  //   field
+  // warning : minpoly must depend on a parameter called "a"
+  int ext;
+  string s_m=string(minpoly);
+  if (s_m=="0")
+  {
+    ext=1;
+  }
+  else
+  {
+    ring auxr=char(basering),a,lp;
+    execute("poly minp="+s_m+";");
+    ext=deg(minp);
+  }
+  return(ext);
+}
+///////////////////////////////////////////////////////////////////////////////
+static proc Frobenius (def etwas,int r)
+{
+  // applies the Frobenius map over F_{p^r} to an object defined over an
+  //   extension of such field
+  // usually it is called with r=1, i.e. the Frobenius map over the prime
+  //   field F_p
+  // returns always an object of the same type, and works correctly on
+  // numbers, polynomials, ideals, matrices or lists of the above types
+  // maybe : types vector and module should be added in the future, but they
+  //   are not needed now
+  int q=char(basering)^r;
+  if (typeof(etwas)=="number")
+  {
+    return(etwas^q);
+  }
+  if (typeof(etwas)=="poly")
+  {
+    int s=size(etwas);
+    poly f;
+    int i;
+    for (i=1;i<=s;i=i+1)
+    {
+      f=f+(leadcoef(etwas[i])^q)*leadmonom(etwas[i]);
+    }
+    return(f);
+  }
+  if (typeof(etwas)=="ideal")
+  {
+    int s=ncols(etwas);
+    ideal I;
+    int i;
+    for (i=1;i<=s;i=i+1)
+    {
+      I[i]=Frobenius(etwas[i],r);
+    }
+    return(I);
+  }
+  if (typeof(etwas)=="matrix")
+  {
+    int m=nrows(etwas);
+    int n=ncols(etwas);
+    matrix A[m][n];
+    int i,j;
+    for (i=1;i<=m;i=i+1)
+    {
+      for (j=1;j<=n;j=j+1)
+      {
+        A[i,j]=Frobenius(etwas[i,j],r);
+      }
+    }
+    return(A);
+  }
+  if (typeof(etwas)=="list")
+  {
+    int s=size(etwas);
+    list L=list();
+    int i;
+    for (i=1;i<=s;i=i+1)
+    {
+      if (typeof(etwas[i])<>"none")
+      {
+        L[i]=Frobenius(etwas[i],r);
+      }
+    }
+    return(L);
+  }
+  return(etwas);
+}
+///////////////////////////////////////////////////////////////////////////////
+static proc conj_b (list L,int r)
+{
+  // applies the Frobenius map over F_{p^r} to a list of type HNE defined over
+  //   a larger extension
+  // when r=1 it turns to be the Frobenius map over the prime field F_{p}
+  // returns : a list of type HNE which is either conjugate of the input or
+  //     the same list in case of L being actually defined over the base field
+  //     F_{p^r}
+  int p=char(basering);
+  int Q=p^r;
+  list LL=list();
+  int m=nrows(L[1]);
+  int n=ncols(L[1]);
+  matrix A[m][n];
+  poly f;
+  poly aux;
+  int i,j;
+  for (i=1;i<=m;i=i+1)
+  {
+    for (j=1;j<=n;j=j+1)
+    {
+      aux=L[1][i,j];
+      if (aux<>x)
+      {
+        A[i,j]=aux^Q;
+      }
+      else
+      {
+        A[i,j]=aux;
+        break;
+      }
+    }
+  }
+  m=size(L[4]);
+  for (i=1;i<=m;i=i+1)
+  {
+    f=f+(leadcoef(L[4][i])^Q)*leadmonom(L[4][i]);
+  }
+  LL[1]=A;
+  LL[2]=L[2];
+  LL[3]=L[3];
+  LL[4]=f;
+  return(LL);
+}
+///////////////////////////////////////////////////////////////////////////////
+static proc grad_b (list L,int r)
+{
+  // computes the degree of a list of type HNE which is actually defined over
+  //    F_{p^r} eventhough it is given in an extension of such field
+  int gr=1;
+  int rd=res_deg() div r;
+  list LL=L;
+  int i;
+  for (i=1;i<=rd;i=i+1)
+  {
+    LL=conj_b(LL,r);
+    if ( LL[1]==L[1] && LL[4]==L[4] )
+    {
+      break;
+    }
+    else
+    {
+      gr=gr+1;
+    }
+  }
+  return(gr);
+}
+///////////////////////////////////////////////////////////////////////////////
+static proc conj_bs (list L,int r)
+{
+  // computes all the conjugates over F_{p^r} of a list of type HNE defined
+  //   over an extension
+  // returns : a list of lists of type HNE, where the first one is the input
+  //   list
+  // remark : notice that the degree of the branch is then the size of the
+  //   output
+  list branches=list();
+  int gr=1;
+  branches[1]=L;
+  int rd=res_deg() div r;
+  list LL=L;
+  int i;
+  for (i=1;i<=rd;i=i+1)
+  {
+    LL=conj_b(LL,r);
+    if ( LL[1]==L[1] && LL[4]==L[4] )
+    {
+      break;
+    }
+    else
+    {
+      gr=gr+1;
+      branches[gr]=LL;
+    }
+  }
+  return(branches);
+}
+///////////////////////////////////////////////////////////////////////////////
+static proc subfield (def sf)
+{
+  // writes the generator "a" of a subfield of the coefficients field of
+  //   basering in terms of the current generator (also called "a") as a
+  //   string sf is an existing ring whose coefficient field is such a subfield
+  // warning : in basering there must be a variable called "x" and subfield
+  //   must not be prime
+  def base_r=basering;
+  string new_m=string(minpoly);
+  setring sf;
+  string old_m=string(minpoly);
+  if (old_m==new_m)
+  {
+    setring base_r;
+    return("a");
+  }
+  else
+  {
+    if (old_m<>string(0))
+    {
+      ring auxring=char(basering),(a,x),lp;
+      execute("poly mpol="+old_m+";");
+      mpol=subst(mpol,a,x);
+      setring base_r;
+      poly mpol=imap(auxring,mpol);
+      kill auxring;
+      string answer="? error : non-primitive element";
+      int r=res_deg();
+      int q=char(basering)^r;
+      int i;
+      number b;
+      for (i=1;i<=q-2;i=i+1)
+      {
+        b=a^i;
+        if (subst(mpol,x,b)==0)
+        {
+          answer=string(b);
+          break;
+        }
+      }
+      if (answer<>"? error : non-primitive element")
+      {
+        return(answer);
+      }
+      else
+      {
+        // list all the elements of the finite field F_q
+        int p=char(basering);
+        list FF1,FF2;
+        for (i=0;i<p;i=i+1)
+        {
+          FF1[i+1]=number(i);
+        }
+        int s,j,k;
+        for (i=1;i<r;i=i+1)
+        {
+          s=size(FF1);
+          for (j=1;j<=s;j=j+1)
+          {
+            FF1[j]=FF1[j]*a;
+          }
+          FF2=FF1;
+          for (k=1;k<p;k=k+1)
+          {
+            for (j=1;j<=s;j=j+1)
+            {
+              FF1[j]=FF1[j]+number(1);
+            }
+            FF2=FF2+FF1;
+          }
+          FF1=FF2;
+          FF2=list();
+        }
+        kill FF2;
+        for (i=1;i<=q-1;i=i+1)
+        {
+          b=FF1[i];
+          if (subst(mpol,x,b)==0)
+          {
+            answer=string(b);
+            break;
+          }
+        }
+      }
+      kill FF1;
+      return(answer);
+    }
+    else
+    {
+      dbprint(printlevel+1,"warning : minpoly=0 in the subfield;
+                              you should check that nothing is wrong");
+      return(string(1));
+    }
+  }
+}
+///////////////////////////////////////////////////////////////////////////////
+static proc importdatum (def sf,string datum,string rel)
+{
+  // fetchs a poly with name "datum" to the current basering from the ring sf
+  //   such that the generator is given by string "rel"
+  // warning : ring sf must have only variables (x,y) and basering must have
+  //   at least (x,y)
+  // warning : the case of minpoly=0 is not regarded; there you can use "imap"
+  //   instead
+  def base_r=basering;
+  if (rel=="a")
+  {
+    setring sf;
+    execute("poly pdatum="+datum+";");
+    setring base_r;
+    poly pdatum=imap(sf,pdatum);
+    return(pdatum);
+  }
+  else
+  {
+    setring sf;
+    execute("string sdatum=string("+datum+");");
+    ring auxring=char(basering),(a,x,y),lp;
+    execute("poly pdatum="+sdatum+";");
+    execute("map phi=basering,"+rel+",x,y;");
+    pdatum=phi(pdatum);
+    string snewdatum=string(pdatum);
+    setring base_r;
+    execute("poly pdatum="+snewdatum+";");
+    kill auxring;
+    return(pdatum);
+  }
+}
+///////////////////////////////////////////////////////////////////////////////
+static proc rationalize (def lf,string datum,string rel)
+{
+  // fetchs a poly with name "datum" to the current basering from the ring lf
+  //   and larger coefficients field, where the generator of current ring is
+  //   given by string "rel" and "datum" is actually defined over the small
+  //   field
+  // warning : ring lf must have only variables (x,y) and basering must have
+  //           at least (x,y)
+  // warning : the case of minpoly=0 is supposed unnecessary, since then
+  //           "datum" should be already written in the right way, i.e. in
+  //           terms of the prime field
+  def base_r=basering;
+  if (rel=="a")
+  {
+    setring lf;
+    execute("poly pdatum="+datum+";");
+    setring base_r;
+    poly pdatum=imap(lf,pdatum);
+    return(pdatum);
+  }
+  else
+  {
+    setring lf;
+    execute("string sdatum=string("+datum+");");
+    ring auxring=char(basering),(a,b,x,y,t),lp;
+//  execute("poly pdatum="+datum+";");
+    execute("poly pdatum="+sdatum+";");
+    execute("poly prel=b-("+rel+");");
+// was before:
+//    ideal I=pdatum,prel;
+//    I=eliminate(I,a);
+//    if (size(I)<=1){ poly newdatum=I[1]; }
+//    else { ERROR("Elimination error"); }
+// CL 09/05 new:
+    poly newdatum=reduce(pdatum,std(prel));
+newdatum;
+//
+    newdatum=subst(newdatum,b,a);
+    string snewdatum=string(newdatum);
+    setring base_r;
+    execute("poly newdatum="+snewdatum+";");
+    kill auxring;
+    return(newdatum);
+  }
+}
+///////////////////////////////////////////////////////////////////////////////
+static proc place (intvec Pp,int sing,list CURVE)
+{
+  // computes the "rational" places which are defined over a (closed) point
+  // Pp points to an appropriate point of the given curve
+  // creates : local rings (if they do not exist yet) and then add the
+  //   places to a list
+  //   each place is given basically by the coordinates of the point and a
+  //   list HNdevelop
+  // returns : list with all updated data of the curve
+  // if the places already exist they are not computed again
+  // if sing==1 the point is assumed singular and computes the local conductor
+  //   for all places using the local invariants of the branches
+  // if sing==2 the point is assumed singular and computes the local conductor
+  //   for all places using the Dedekind formula and local parametrizations
+  //   of the branches
+  // if sing<>1&2 the point is assumed non-singular and the local conductor
+  //   should be zero
+  list PP=list();
+  if (Pp[1]==0)
+  {
+    if (Pp[2]==0)
+    {
+      PP=Aff_SPoints[Pp[3]];
+    }
+    if (Pp[2]==1)
+    {
+      PP=Inf_Points[1][Pp[3]];
+    }
+    if (Pp[2]==2)
+    {
+      PP=Inf_Points[2][Pp[3]];
+    }
+  }
+  else
+  {
+    PP=Aff_Points(Pp[2])[Pp[3]];
+  }
+  if (PP[2]<>0)
+  {
+    return(CURVE);
+  }
+  intvec PtoPl;
+  def base_r=basering;
+  int ext1;
+  list Places=CURVE[3];
+  intvec Conductor=CURVE[4];
+  list update_CURVE=CURVE;
+  if (typeof(PP[1])=="ideal")
+  {
+    ideal P=PP[1];
+    if (size(P)==2)
+    {
+      int d=deg(P[1]);
+      poly aux=subst(P[2],y,1);
+      d=d*deg(aux);
+      ext1=d;
+      // the point is (A:B:1) but one must distinguish several cases
+      // P is assumed to be a std. resp. "(x,y),lp" and thus P[1] depends
+      // only on "y"
+      if (d==1)
+      {
+        // the point is rational
+        number B=-number(subst(P[1],y,0));
+        poly aux2=subst(P[2],y,B);
+        number A=-number(subst(aux2,x,0));
+        // the point is (A:B:1)
+        ring local_aux=char(basering),(x,y),ls;
+        number coord at 1=imap(base_r,A);
+        number coord at 2=imap(base_r,B);
+        number coord at 3=number(1);
+        map phi=base_r,x+coord at 1,y+coord at 2;
+        poly CHI=phi(CHI);
+      }
+      else
+      {
+        if (deg(P[1])==1)
+        {
+          // the point is non-rational but the second component needs no
+          // field extension
+          number B=-number(subst(P[1],y,0));
+          poly aux2=subst(P[2],y,B);
+          // the point has degree d>1
+          // careful : the parameter will be called "a" anyway
+          ring local_aux=(char(basering),a),(x,y),ls;
+          map psi=base_r,a,0;
+          minpoly=number(psi(aux2));
+          number coord at 1=a;
+          number coord at 2=imap(base_r,B);
+          number coord at 3=number(1);
+          // the point is (a:B:1)
+          map phi=base_r,x+a,y+coord at 2;
+          poly CHI=phi(CHI);
+        }
+        else
+        {
+          if (deg(subst(P[2],y,1))==1)
+          {
+            // the point is non-rational but the needed minpoly is just P[1]
+            // careful : the parameter will be called "a" anyway
+            poly P1=P[1];
+            poly P2=P[2];
+            ring local_aux=(char(basering),a),(x,y),ls;
+            map psi=base_r,0,a;
+            minpoly=number(psi(P1));
+            // the point looks like (A:a:1)
+            // A is computed by substituting y=a in P[2]
+            poly aux1=imap(base_r,P2);
+            poly aux2=subst(aux1,y,a);
+            number coord at 1=-number(subst(aux2,x,0));
+            number coord at 2=a;
+            number coord at 3=number(1);
+            map phi=base_r,x+coord at 1,y+a;
+            poly CHI=phi(CHI);
+          }
+          else
+          {
+            // this is the most complicated case of non-rational point
+            // firstly : construct an extension of degree d and guess the
+            //           minpoly
+            poly P1=P[1];
+            poly P2=P[2];
+            int p=char(basering);
+            int Q=p^d;
+            ring aux_r=(Q,a),(x,y,t),ls;
+            string minpoly_string=string(minpoly);
+            ring local_aux=(char(basering),a),(x,y),ls;
+            execute("minpoly="+minpoly_string+";");
+            // secondly : compute one root of P[1]
+            poly P_1=imap(base_r,P1);
+            poly P_2=imap(base_r,P2);
+            ideal factors1=factorize(P_1,1);       // hopefully this works !!!!
+            number coord at 2=-number(subst(factors1[1],y,0));
+            // thirdly : compute one of the first components for the above root
+            poly P_0=subst(P_2,y,coord at 2);
+            ideal factors2=factorize(P_0,1);       // hopefully this works !!!!
+            number coord at 1=-number(subst(factors2[1],x,0));
+            number coord at 3=number(1);
+            map phi=base_r,x+coord at 1,y+coord at 2;
+            poly CHI=phi(CHI);
+            kill aux_r;
+          }
+        }
+      }
+    }
+    else
+    {
+      // this should not happen in principle
+      ERROR("non-valid parameter");
+    }
+  }
+  else
+  {
+    if (typeof(PP[1])=="poly")
+    {
+      poly P=PP[1];
+      ring r_auxz=char(basering),(x,y,z),lp;
+      poly CHI=imap(base_r,CHI);
+      CHI=homog(CHI,z);
+      setring base_r;
+      poly aux=subst(P,y,1);
+      if (aux==1)
+      {
+        // the point is (1:0:0)
+        ring local_aux=char(basering),(x,y),ls;
+        number coord at 1=number(1);
+        number coord at 2=number(0);
+        number coord at 3=number(0);
+        map Phi=r_auxz,1,x,y;
+        poly CHI=Phi(CHI);
+        ext1=1;
+      }
+      else
+      {
+        // the point is (A:1:0) where A is a root of aux
+        int d=deg(aux);
+        ext1=d;
+        if (d==1)
+        {
+          // the point is rational
+          number A=-number(subst(aux,x,0));
+          ring local_aux=char(basering),(x,y),ls;
+          number coord at 1=imap(base_r,A);
+          number coord at 2=number(1);
+          number coord at 3=number(0);
+          map Phi=r_auxz,x+coord at 1,1,y;
+          poly CHI=Phi(CHI);
+        }
+        else
+        {
+          // the point has degree d>1
+          // careful : the parameter will be called "a" anyway
+          ring local_aux=(char(basering),a),(x,y),ls;
+          map psi=base_r,a,1;
+          minpoly=number(psi(P));
+          number coord at 1=a;
+          number coord at 2=number(1);
+          number coord at 3=number(0);
+          map Phi=r_auxz,x+a,1,y;
+          poly CHI=Phi(CHI);
+        }
+      }
+      kill r_auxz;
+    }
+    else
+    {
+      ERROR("a point must have a polynomial or ideal in the first component");
+    }
+  }
+  export(coord at 1);
+  export(coord at 2);
+  export(coord at 3);
+  export(CHI);
+  int i,j,k;
+  int m,n;
+  list LLL=ratdevelop(CHI);
+//  list LLL=hnexpansion(CHI,"ess");
+  if (typeof(LLL[1])=="ring") {
+    def altring=basering;
+    def HNEring = LLL[1]; setring HNEring;
+    def L at HNE = HND;
+    kill HND;
+//    def L at HNE = hne;
+//    kill hne;
+
+  }
+  else {
+    def L at HNE=LLL;
+//    def L at HNE=LLL[1];
+    def HNEring=basering;
+    setring HNEring;
+  }
+  kill LLL;
+  export(L at HNE);
+  int n_branches=size(L at HNE);
+  list Li_aux=list();
+  int N_branches;
+  int N=size(Places);
+  if (sing==1)
+  {
+    list delta2=list();
+    for (i=1;i<=n_branches;i=i+1)
+    {
+      delta2[i]=invariants(L at HNE[i])[5];
+    }
+    int dq;
+  }
+  int ext2=res_deg();
+  list dgs=list();
+  int ext_0;
+  int check;
+  string sss,olda,newa;
+  if (defined(Q)==0)
+  {
+    int Q;
+  }
+  if (ext1==1)
+  {
+    if (ext2==1)
+    {
+      if (sing==1)
+      {
+        intmat I_mult[n_branches][n_branches];
+        if (n_branches>1)
+        {
+          for (i=1;i<=n_branches-1;i=i+1)
+          {
+            for (j=i+1;j<=n_branches;j=j+1)
+            {
+              I_mult[i,j]=intersection(L at HNE[i],L at HNE[j]);
+              I_mult[j,i]=I_mult[i,j];
+            }
+          }
+        }
+      }
+////////
+check=0;
+////////
+      if (size(update_CURVE[5])>0)
+      {
+        if (typeof(update_CURVE[5][1])=="list")
+        {
+          check=1;
+        }
+      }
+      if (check==0)
+      {
+        intvec dgs_points(1);
+        ring S(1)=char(basering),(x,y,t),ls;
+        list BRANCHES=list();
+        list POINTS=list();
+        list LOC_EQS=list();
+        list PARAMETRIZATIONS=list();
+        export(BRANCHES);
+        export(POINTS);
+        export(LOC_EQS);
+        export(PARAMETRIZATIONS);
+      }
+      else
+      {
+        intvec dgs_points(1)=update_CURVE[5][1][2];
+        def S1=update_CURVE[5][1][1];
+        execute("ring S(1)="+string(update_CURVE[5][1][1])+";");
+        fetchall(S1);
+        kill S1;
+      }
+      N_branches=size(BRANCHES);
+      for (i=1;i<=n_branches;i=i+1)
+      {
+        dgs_points(1)[N_branches+i]=1;
+        POINTS[N_branches+i]=list();
+        POINTS[N_branches+i][1]=imap(local_aux,coord at 1);
+        POINTS[N_branches+i][2]=imap(local_aux,coord at 2);
+        POINTS[N_branches+i][3]=imap(local_aux,coord at 3);
+        LOC_EQS[N_branches+i]=imap(local_aux,CHI);
+        setring HNEring;
+        Li_aux=L at HNE[i];
+        setring S(1);
+        BRANCHES=insert(BRANCHES,imap(HNEring,Li_aux),N_branches+i-1);
+        PARAMETRIZATIONS[N_branches+i]=param(BRANCHES[N_branches+i],0);
+        N=N+1;
+        intvec iw=1,N_branches+i;
+        Places[N]=iw;
+        if (sing==1)
+        {
+          dq=delta2[i];
+          for (j=1;j<=n_branches;j=j+1)
+          {
+            dq=dq+I_mult[i,j];
+          }
+          Conductor[N]=dq;
+        }
+        if (sing==2)
+        {
+          Conductor[N]=local_conductor(iw[2],S(1));
+        }
+        kill iw;
+        PtoPl[i]=N;
+      }
+      setring base_r;
+      update_CURVE[5][1]=list();
+      update_CURVE[5][1][1]=S(1);
+      update_CURVE[5][1][2]=dgs_points(1);
+    }
+    else
+    {
+      // we start with a rational point but we get non-rational branches
+      // they may have different degrees and then we may need to reduce the
+      // field extensions for each one, and finally check if the minpoly
+      // fetches with S(i) or not
+      // if one of the branches is rational, we may trust that it is written
+      // correctly
+      if (sing==1)
+      {
+        int n_geobrs;
+        int counter_c;
+        list auxgb=list();
+        list geobrs=list();
+        for (i=1;i<=n_branches;i=i+1)
+        {
+          auxgb=conj_bs(L at HNE[i],1);
+          dgs[i]=size(auxgb);
+          n_geobrs=n_geobrs+dgs[i];
+          for (j=1;j<=dgs[i];j=j+1)
+          {
+            counter_c=counter_c+1;
+            geobrs[counter_c]=auxgb[j];
+          }
+        }
+        intmat I_mult[n_geobrs][n_geobrs];
+        for (i=1;i<n_geobrs;i=i+1)
+        {
+          for (j=i+1;j<=n_geobrs;j=j+1)
+          {
+            I_mult[i,j]=intersection(geobrs[i],geobrs[j]);
+            I_mult[j,i]=I_mult[i,j];
+          }
+        }
+        kill auxgb,geobrs;
+      }
+      else
+      {
+        for (i=1;i<=n_branches;i=i+1)
+        {
+          dgs[i]=grad_b(L[i],1);
+        }
+      }
+      // the actual degree of each branch is computed and now check if the
+      // local ring exists
+      for (i=1;i<=n_branches;i=i+1)
+      {
+        ext_0=dgs[i];
+////////
+check=0;
+////////
+        if (size(update_CURVE[5])>=ext_0)
+        {
+          if (typeof(update_CURVE[5][ext_0])=="list")
+          {
+            check=1;
+          }
+        }
+        if (check==0)
+        {
+          if (ext_0>1)
+          {
+            if (ext_0==ext2)
+            {
+              sss=string(minpoly);
+            }
+            else
+            {
+              Q=char(basering)^ext_0;
+              ring auxxx=(Q,a),z,lp;
+              sss=string(minpoly);
+              setring base_r;
+              kill auxxx;
+            }
+            ring S(ext_0)=(char(basering),a),(x,y,t),ls;
+            execute("minpoly="+sss+";");
+          }
+          else
+          {
+            ring S(ext_0)=char(basering),(x,y,t),ls;
+          }
+          intvec dgs_points(ext_0);
+          list BRANCHES=list();
+          list POINTS=list();
+          list LOC_EQS=list();
+          list PARAMETRIZATIONS=list();
+          export(BRANCHES);
+          export(POINTS);
+          export(LOC_EQS);
+          export(PARAMETRIZATIONS);
+        }
+        else
+        {
+          intvec dgs_points(ext_0)=update_CURVE[5][ext_0][2];
+          def Sext_0=update_CURVE[5][ext_0][1];
+          setring Sext_0;
+          string SM=string(minpoly);
+          string SR=string(update_CURVE[5][ext_0][1]);
+          execute("ring S("+string(ext_0)+")="+SR+";");
+          execute("minpoly="+SM+";");
+          kill SM,SR;
+          fetchall(Sext_0);
+          kill Sext_0;
+        }
+        N_branches=size(BRANCHES);
+        dgs_points(ext_0)[N_branches+1]=1;
+        POINTS[N_branches+1]=list();
+        POINTS[N_branches+1][1]=imap(local_aux,coord at 1);
+        POINTS[N_branches+1][2]=imap(local_aux,coord at 2);
+        POINTS[N_branches+1][3]=imap(local_aux,coord at 3);
+        LOC_EQS[N_branches+1]=imap(local_aux,CHI);
+        // now fetch the branches into the new local ring
+        if (ext_0==1)
+        {
+          setring HNEring;
+          Li_aux=L at HNE[i];
+          setring S(1);
+          BRANCHES=insert(BRANCHES,imap(HNEring,Li_aux),N_branches);
+        }
+        else
+        {
+          // rationalize branch
+          setring HNEring;
+          newa=subfield(S(ext_0));
+          m=nrows(L at HNE[i][1]);
+          n=ncols(L at HNE[i][1]);
+          setring S(ext_0);
+          list Laux=list();
+          poly paux=rationalize(HNEring,"L at HNE["+string(i)+"][4]",newa);
+          matrix Maux[m][n];
+          for (j=1;j<=m;j=j+1)
+          {
+            for (k=1;k<=n;k=k+1)
+            {
+              Maux[j,k]=rationalize(HNEring,"L at HNE["+string(i)+"][1]["+
+                           string(j)+","+string(k)+"]",newa);
+            }
+          }
+          setring HNEring;
+          intvec Li2=L at HNE[i][2];
+          int Li3=L at HNE[i][3];
+          setring S(ext_0);
+          Laux[1]=Maux;
+          Laux[2]=Li2;
+          Laux[3]=Li3;
+          Laux[4]=paux;
+          BRANCHES=insert(BRANCHES,Laux,N_branches);
+          kill Laux,Maux,paux,Li2,Li3;
+        }
+        PARAMETRIZATIONS[N_branches+1]=param(BRANCHES[N_branches+1],0);
+        N=N+1;
+        intvec iw=ext_0,N_branches+1;
+        Places[N]=iw;
+        if (sing==2)
+        {
+          Conductor[N]=local_conductor(iw[2],S(ext_0));
+        }
+        kill iw;
+        PtoPl[i]=N;
+        setring HNEring;
+        update_CURVE[5][ext_0]=list();
+        update_CURVE[5][ext_0][1]=S(ext_0);
+        update_CURVE[5][ext_0][2]=dgs_points(ext_0);
+      }
+      if (sing==1)
+      {
+        int N_ini=N-n_branches;
+        counter_c=1;
+        for (i=1;i<=n_branches;i=i+1)
+        {
+          dq=delta2[i];
+          for (j=1;j<=n_geobrs;j=j+1)
+          {
+            dq=dq+I_mult[counter_c,j];
+          }
+          Conductor[N_ini+i]=dq;
+          counter_c=counter_c+dgs[i];
+        }
+      }
+      setring base_r;
+    }
+  }
+  else
+  {
+    if (ext1==ext2)
+    {
+      // the degree of the point equals to the degree of all branches
+      // one must just fetch the minpoly's of local_aux, HNEring and S(ext2)
+      if (sing==1)
+      {
+        intmat I_mult[n_branches][n_branches];
+        if (n_branches>1)
+        {
+          for (i=1;i<=n_branches-1;i=i+1)
+          {
+            for (j=i+1;j<=n_branches;j=j+1)
+            {
+              I_mult[i,j]=intersection(L at HNE[i],L at HNE[j]);
+              I_mult[j,i]=I_mult[i,j];
+            }
+          }
+        }
+      }
+////////
+check=0;
+////////
+      if (size(update_CURVE[5])>=ext2)
+      {
+        if (typeof(update_CURVE[5][ext2])=="list")
+        {
+          check=1;
+        }
+      }
+      if (check==0)
+      {
+        sss=string(minpoly);
+        ring S(ext2)=(char(basering),a),(x,y,t),ls;
+        execute("minpoly="+sss+";");
+        intvec dgs_points(ext2);
+        list BRANCHES=list();
+        list POINTS=list();
+        list LOC_EQS=list();
+        list PARAMETRIZATIONS=list();
+        export(BRANCHES);
+        export(POINTS);
+        export(LOC_EQS);
+        export(PARAMETRIZATIONS);
+      }
+      else
+      {
+        intvec dgs_points(ext2)=update_CURVE[5][ext2][2];
+        def Sext2=update_CURVE[5][ext2][1];
+        setring Sext2;
+        string SM=string(minpoly);
+        string SR=string(update_CURVE[5][ext2][1]);
+        execute("ring S("+string(ext2)+")="+SR+";");
+        execute("minpoly="+SM+";");
+        kill SM,SR;
+        fetchall(Sext2);
+        kill Sext2;
+      }
+      N_branches=size(BRANCHES);
+      for (i=1;i<=n_branches;i=i+1)
+      {
+        // fetch all the data into the new local ring
+        olda=subfield(local_aux);
+        dgs_points(ext2)[N_branches+i]=ext1;
+        POINTS[N_branches+i]=list();
+        POINTS[N_branches+i][1]=number(importdatum(local_aux,"coord at 1",olda));
+        POINTS[N_branches+i][2]=number(importdatum(local_aux,"coord at 2",olda));
+        POINTS[N_branches+i][3]=number(importdatum(local_aux,"coord at 3",olda));
+        LOC_EQS[N_branches+i]=importdatum(local_aux,"CHI",olda);
+        newa=subfield(HNEring);
+        setring HNEring;
+        m=nrows(L at HNE[i][1]);
+        n=ncols(L at HNE[i][1]);
+        setring S(ext2);
+        list Laux=list();
+        poly paux=importdatum(HNEring,"L at HNE["+string(i)+"][4]",newa);
+        matrix Maux[m][n];
+        for (j=1;j<=m;j=j+1)
+        {
+          for (k=1;k<=n;k=k+1)
+          {
+            Maux[j,k]=importdatum(HNEring,"L at HNE["+string(i)+"][1]["+
+                                   string(j)+","+string(k)+"]",newa);
+          }
+        }
+        setring HNEring;
+        intvec Li2=L at HNE[i][2];
+        int Li3=L at HNE[i][3];
+        setring S(ext2);
+        Laux[1]=Maux;
+        Laux[2]=Li2;
+        Laux[3]=Li3;
+        Laux[4]=paux;
+        BRANCHES=insert(BRANCHES,Laux,N_branches+i-1);
+        kill Laux,Maux,paux,Li2,Li3;
+        PARAMETRIZATIONS[N_branches+i]=param(BRANCHES[N_branches+i],0);
+        N=N+1;
+        intvec iw=ext2,N_branches+i;
+        Places[N]=iw;
+        if (sing==1)
+        {
+          dq=delta2[i];
+          for (j=1;j<=n_branches;j=j+1)
+          {
+            dq=dq+I_mult[i,j];
+          }
+          Conductor[N]=dq;
+        }
+        if (sing==2)
+        {
+          Conductor[N]=local_conductor(iw[2],S(ext2));
+        }
+        kill iw;
+        PtoPl[i]=N;
+      }
+      setring base_r;
+      update_CURVE[5][ext2]=list();
+      update_CURVE[5][ext2][1]=S(ext2);
+      update_CURVE[5][ext2][2]=dgs_points(ext2);
+    }
+    else
+    {
+      // this is the most complicated case
+      if (sing==1)
+      {
+        int n_geobrs;
+        int counter_c;
+        list auxgb=list();
+        list geobrs=list();
+        for (i=1;i<=n_branches;i=i+1)
+        {
+          auxgb=conj_bs(L at HNE[i],ext1);
+          dgs[i]=size(auxgb);
+          n_geobrs=n_geobrs+dgs[i];
+          for (j=1;j<=dgs[i];j=j+1)
+          {
+            counter_c=counter_c+1;
+            geobrs[counter_c]=auxgb[j];
+          }
+        }
+        intmat I_mult[n_geobrs][n_geobrs];
+        for (i=1;i<n_geobrs;i=i+1)
+        {
+          for (j=i+1;j<=n_geobrs;j=j+1)
+          {
+            I_mult[i,j]=intersection(geobrs[i],geobrs[j]);
+            I_mult[j,i]=I_mult[i,j];
+          }
+        }
+        kill auxgb,geobrs;
+      }
+      else
+      {
+        for (i=1;i<=n_branches;i=i+1)
+        {
+          dgs[i]=grad_b(L at HNE[i],ext1);
+        }
+      }
+      for (i=1;i<=n_branches;i=i+1)
+      {
+        // first compute the actual degree of each branch and check if the
+        // local ring exists
+        ext_0=ext1*dgs[i];
+////////
+check=0;
+////////
+        if (size(update_CURVE[5])>=ext_0)
+        {
+          if (typeof(update_CURVE[5][ext_0])=="list")
+          {
+            check=1;
+          }
+        }
+        if (check==0)
+        {
+          if (ext_0>ext1)
+          {
+            if (ext_0==ext2)
+            {
+              sss=string(minpoly);
+            }
+            else
+            {
+              Q=char(basering)^ext_0;
+              ring auxxx=(Q,a),z,lp;
+              sss=string(minpoly);
+              setring base_r;
+              kill auxxx;
+            }
+          }
+          else
+          {
+            setring local_aux;
+            sss=string(minpoly);
+          }
+          ring S(ext_0)=(char(basering),a),(x,y,t),ls;
+          execute("minpoly="+sss+";");
+          intvec dgs_points(ext_0);
+          list BRANCHES=list();
+          list POINTS=list();
+          list LOC_EQS=list();
+          list PARAMETRIZATIONS=list();
+          export(BRANCHES);
+          export(POINTS);
+          export(LOC_EQS);
+          export(PARAMETRIZATIONS);
+        }
+        else
+        {
+          intvec dgs_points(ext_0)=update_CURVE[5][ext_0][2];
+          def Sext_0=update_CURVE[5][ext_0][1];
+          setring Sext_0;
+          string SM=string(minpoly);
+          string SR=string(update_CURVE[5][ext_0][1]);
+          execute("ring S("+string(ext_0)+")="+SR+";");
+          execute("minpoly="+SM+";");
+          kill SM,SR;
+          fetchall(badring);
+          kill badring;
+        }
+        N_branches=size(BRANCHES);
+        // now fetch all the data into the new local ring
+        olda=subfield(local_aux);
+        dgs_points(ext_0)[N_branches+1]=ext1;
+        POINTS[N_branches+1]=list();
+        POINTS[N_branches+1][1]=number(importdatum(local_aux,"coord at 1",olda));
+        POINTS[N_branches+1][2]=number(importdatum(local_aux,"coord at 2",olda));
+        POINTS[N_branches+1][3]=number(importdatum(local_aux,"coord at 3",olda));
+        LOC_EQS[N_branches+1]=importdatum(local_aux,"CHI",olda);
+        setring HNEring;
+        newa=subfield(S(ext_0));
+        m=nrows(L at HNE[i][1]);
+        n=ncols(L at HNE[i][1]);
+        setring S(ext_0);
+        list Laux=list();
+        poly paux=rationalize(HNEring,"L at HNE["+string(i)+"][4]",newa);
+        matrix Maux[m][n];
+        for (j=1;j<=m;j=j+1)
+        {
+          for (k=1;k<=n;k=k+1)
+          {
+            Maux[j,k]=rationalize(HNEring,"L at HNE["+string(i)+"][1]["+
+               string(j)+","+string(k)+"]",newa);
+          }
+        }
+        setring HNEring;
+        intvec Li2=L at HNE[i][2];
+        int Li3=L at HNE[i][3];
+        setring S(ext_0);
+        Laux[1]=Maux;
+        Laux[2]=Li2;
+        Laux[3]=Li3;
+        Laux[4]=paux;
+        BRANCHES=insert(BRANCHES,Laux,N_branches);
+        kill Laux,Maux,paux,Li2,Li3;
+        PARAMETRIZATIONS[N_branches+1]=param(BRANCHES[N_branches+1],0);
+        N=N+1;
+        intvec iw=ext_0,N_branches+1;
+        Places[N]=iw;
+        if (sing==2)
+        {
+          Conductor[N]=local_conductor(iw[2],S(ext_0));
+        }
+        kill iw;
+        PtoPl[i]=N;
+        setring HNEring;
+        update_CURVE[5][ext_0]=list();
+        update_CURVE[5][ext_0][1]=S(ext_0);
+        update_CURVE[5][ext_0][2]=dgs_points(ext_0);
+      }
+      if (sing==1)
+      {
+        int N_ini=N-n_branches;
+        counter_c=1;
+        for (i=1;i<=n_branches;i=i+1)
+        {
+          dq=delta2[i];
+          for (j=1;j<=n_geobrs;j=j+1)
+          {
+            dq=dq+I_mult[counter_c,j];
+          }
+          Conductor[N_ini+i]=dq;
+          counter_c=counter_c+dgs[i];
+        }
+      }
+      setring base_r;
+    }
+  }
+  update_CURVE[3]=Places;
+  update_CURVE[4]=Conductor;
+  PP[2]=PtoPl;
+  if (Pp[1]==0)
+  {
+    if (Pp[2]==0)
+    {
+      Aff_SPoints[Pp[3]]=PP;
+    }
+    if (Pp[2]==1)
+    {
+      Inf_Points[1][Pp[3]]=PP;
+    }
+    if (Pp[2]==2)
+    {
+      Inf_Points[2][Pp[3]]=PP;
+    }
+  }
+  else
+  {
+    Aff_Points(Pp[2])[Pp[3]]=PP;
+  }
+  update_CURVE[1][1]=base_r;
+  kill HNEring;
+  kill local_aux;
+  return(update_CURVE);
+}
+///////////////////////////////////////////////////////////////////////////////
+static proc local_conductor (int k,def SS)
+{
+  // computes the degree of the local conductor at a place of a plane curve
+  // if the point is non-singular the result will be zero
+  // the computation is carried out with the "Dedekind formula" via
+  // parametrizations
+  int a,b,Cq;
+  def b_ring=basering;
+  setring SS;
+  poly fx=diff(LOC_EQS[k],x);
+  poly fy=diff(LOC_EQS[k],y);
+  int nr=ncols(BRANCHES[k][1]);
+  poly xt=PARAMETRIZATIONS[k][1][1];
+  poly yt=PARAMETRIZATIONS[k][1][2];
+  int ordx=PARAMETRIZATIONS[k][2][1];
+  int ordy=PARAMETRIZATIONS[k][2][2];
+  map phi_t=basering,xt,yt,1;
+  poly derf;
+  if (fx<>0)
+  {
+    derf=fx;
+    poly tt=diff(yt,t);
+    b=mindeg(tt);
+    if (ordy>-1)
+    {
+      while (b>=ordy)
+      {
+        BRANCHES[k]=extdevelop(BRANCHES[k],2*nr);
+        nr=ncols(BRANCHES[k][1]);
+        PARAMETRIZATIONS[k]=param(BRANCHES[k],0);
+        ordy=PARAMETRIZATIONS[k][2][2];
+        yt=PARAMETRIZATIONS[k][1][2];
+        tt=diff(yt,t);
+        b=mindeg(tt);
+      }
+      xt=PARAMETRIZATIONS[k][1][1];
+      ordx=PARAMETRIZATIONS[k][2][1];
+    }
+    poly ft=phi_t(derf);
+  }
+  else
+  {
+    derf=fy;
+    poly tt=diff(xt,t);
+    b=mindeg(tt);
+    if (ordx>-1)
+    {
+      while (b>=ordx)
+      {
+        BRANCHES[k]=extdevelop(BRANCHES[k],2*nr);
+        nr=ncols(BRANCHES[k][1]);
+        PARAMETRIZATIONS[k]=param(BRANCHES[k],0);
+        ordx=PARAMETRIZATIONS[k][2][1];
+        xt=PARAMETRIZATIONS[k][1][1];
+        tt=diff(xt,t);
+        b=mindeg(tt);
+      }
+      yt=PARAMETRIZATIONS[k][1][2];
+      ordy=PARAMETRIZATIONS[k][2][2];
+    }
+    poly ft=phi_t(derf);
+  }
+  a=mindeg(ft);
+  if ( ordx>-1 || ordy>-1 )
+  {
+    if (ordy==-1)
+    {
+      while (a>ordx)
+      {
+        BRANCHES[k]=extdevelop(BRANCHES[k],2*nr);
+        nr=ncols(BRANCHES[k][1]);
+        PARAMETRIZATIONS[k]=param(BRANCHES[k],0);
+        ordx=PARAMETRIZATIONS[k][2][1];
+        xt=PARAMETRIZATIONS[k][1][1];
+        ft=phi_t(derf);
+        a=mindeg(ft);
+      }
+    }
+    else
+    {
+      if (ordx==-1)
+      {
+        while (a>ordy)
+        {
+          BRANCHES[k]=extdevelop(BRANCHES[k],2*nr);
+          nr=ncols(BRANCHES[k][1]);
+          PARAMETRIZATIONS[k]=param(BRANCHES[k],0);
+          ordy=PARAMETRIZATIONS[k][2][2];
+          yt=PARAMETRIZATIONS[k][1][2];
+          ft=phi_t(derf);
+          a=mindeg(ft);
+        }
+      }
+      else
+      {
+        int ordf=ordx;
+        if (ordx>ordy)
+        {
+          ordf=ordy;
+        }
+        while (a>ordf)
+        {
+          BRANCHES[k]=extdevelop(BRANCHES[k],2*nr);
+          nr=ncols(BRANCHES[k][1]);
+          PARAMETRIZATIONS[k]=param(BRANCHES[k],0);
+          ordx=PARAMETRIZATIONS[k][2][1];
+          ordy=PARAMETRIZATIONS[k][2][2];
+          ordf=ordx;
+          if (ordx>ordy)
+          {
+            ordf=ordy;
+          }
+          xt=PARAMETRIZATIONS[k][1][1];
+          yt=PARAMETRIZATIONS[k][1][2];
+          ft=phi_t(derf);
+          a=mindeg(ft);
+        }
+      }
+    }
+  }
+  Cq=a-b;
+  setring b_ring;
+  return(Cq);
+}
+///////////////////////////////////////////////////////////////////////////////
+static proc max_D (intvec D1,intvec D2)
+{
+  // computes the maximum of two divisors (intvec)
+  int s1=size(D1);
+  int s2=size(D2);
+  int i;
+  if (s1>s2)
+  {
+    for (i=1;i<=s2;i=i+1)
+    {
+      if (D2[i]>D1[i])
+      {
+        D1[i]=D2[i];
+      }
+    }
+    for (i=s2+1;i<=s1;i=i+1)
+    {
+      if (D1[i]<0)
+      {
+        D1[i]=0;
+      }
+    }
+    return(D1);
+  }
+  else
+  {
+    for (i=1;i<=s1;i=i+1)
+    {
+      if (D1[i]>D2[i])
+      {
+        D2[i]=D1[i];
+      }
+    }
+    for (i=s1+1;i<=s2;i=i+1)
+    {
+      if (D2[i]<0)
+      {
+        D2[i]=0;
+      }
+    }
+    return(D2);
+  }
+}
+///////////////////////////////////////////////////////////////////////////////
+static proc deg_D (intvec D,list PP)
+{
+  // computes the degree of a divisor (intvec or list of integers)
+  int i;
+  int d=0;
+  int s=size(D);
+  for (i=1;i<=s;i=i+1)
+  {
+    d=d+D[i]*PP[i][1];
+  }
+  return(d);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+// ============================================================================
+// *******  MAIN PROCEDURES for the "preprocessing" of Brill-Noether   ********
+// ============================================================================
+
+proc Adj_div (poly f,list #)
+"USAGE:    Adj_div( f [,l] ); f a poly, [l a list]
+RETURN:   list L with the computed data:
+  @format
+  L[1] a list of rings: L[1][1]=aff_r (affine), L[1][2]=Proj_R (projective),
+  L[2] an intvec with 2 entries (degree, genus),
+  L[3] a list of intvec (closed places),
+  L[4] an intvec (conductor),
+  L[5] a list of lists:
+     L[5][d][1] a (local) ring over an extension of degree d,
+     L[5][d][2] an intvec (degrees of base points of places of degree d)
+  @end format
+NOTE:     @code{Adj_div(f);} computes and stores the fundamental data of the
+          plane curve defined by f as needed for AG codes.
+          In the affine ring you can find the following data:
+   @format
+   poly CHI:  affine equation of the curve,
+   ideal Aff_SLocus:  affine singular locus (std),
+   list Inf_Points:  points at infinity
+            Inf_Points[1]:  singular points
+            Inf_Points[2]:  non-singular points,
+   list Aff_SPoints:  affine singular points (if not empty).
+   @end format
+          In the projective ring you can find the projective equation
+          CHI of the curve (poly).
+          In the local rings L[5][d][1] you find:
+   @format
+   list POINTS:  base points of the places of degree d,
+   list LOC_EQS:  local equations of the curve at the base points,
+   list BRANCHES:  Hamburger-Noether developments of the places,
+   list PARAMETRIZATIONS:  local parametrizations of the places,
+   @end format
+          Each entry of the list L[3] corresponds to one closed place (i.e.,
+          a place and all its conjugates) which is represented by an intvec
+          of size two, the first entry is the degree of the place (in
+          particular, it tells the local ring where to find the data
+          describing one representative of the closed place), and the
+          second one is the position of those data in the lists POINTS, etc.,
+          inside this local ring.@*
+          In the intvec L[4] (conductor) the i-th entry corresponds to the
+          i-th entry in the list of places L[3].
+
+          With no optional arguments, the conductor is computed by
+          local invariants of the singularities; otherwise it is computed
+          by the Dedekind formula. @*
+          An affine point is represented by a list P where P[1] is std
+          of a prime ideal and P[2] is an intvec containing the position
+          of the places above P in the list of closed places L[3]. @*
+          If the point is at infinity, P[1] is a homogeneous irreducible
+          polynomial in two variables.
+
+          If @code{printlevel>=0} additional comments are displayed (default:
+          @code{printlevel=0}).
+WARNING:  The parameter of the needed field extensions is called 'a'. Thus,
+          there should be no global object named 'a' when executing Adj_div.
+KEYWORDS: Hamburger-Noether expansions; adjunction divisor
+SEE ALSO: closed_points, NSplaces
+EXAMPLE:  example Adj_div; shows an example
+"
+{
+  // computes the adjunction divisor and the genus of a (singular) plane curve
+  // as a byproduct, it computes all the singular points with the corresponding
+  //      places and the genus of the curve
+  // the adjunction divisor is stored in an intvec
+  // also the non-singular places at infinity are computed
+  // returns a list with all the computed data
+  if (char(basering)==0)
+  {
+    ERROR("Base field not implemented");
+  }
+  if (npars(basering)>0)
+  {
+    ERROR("Base field not implemented");
+  }
+  if (defined(a)==1)
+  {
+    if ((typeof(a)=="int") or (typeof(a)=="intvec") or (typeof(a)=="intmat") or
+        (typeof(a)=="string") or (typeof(a)=="proc") or (typeof(a)=="list"))
+    {
+      print("WARNING: There is an object named 'a' of the global type "
+             + typeof(a)+".");
+      print("This will cause problems when "
+             + "executing Adj_div, as 'a' is used for "
+             + "the name of the parameter of the field extensions needed.");
+      ERROR("Please rename or kill the object named 'a'");
+    }
+  }
+  intvec opgt=option(get);
+  option(redSB);
+  def Base_R=basering;
+  list CURVE=curve(f);
+  def aff_r=CURVE[1];
+  def Proj_R=CURVE[2];
+  int degX=CURVE[3];
+  int genusX=(degX-1)*(degX-2);
+  genusX = genusX div 2;
+  intvec iivv=degX,genusX;
+  intvec Conductor;
+  setring aff_r;
+  dbprint(printlevel+1,"Computing affine singular points ... ");
+  list Aff_SPoints=Aff_SL(Aff_SLocus);
+  int s=size(Aff_SPoints);
+  if (s>0)
+  {
+    export(Aff_SPoints);
+  }
+  dbprint(printlevel+1,"Computing all points at infinity ... ");
+  list Inf_Points=inf_P(CHI);
+  export(Inf_Points);
+  list update_CURVE=list();
+  update_CURVE[1]=list();
+  update_CURVE[1][1]=aff_r;
+  update_CURVE[1][2]=Proj_R;
+  update_CURVE[2]=iivv;
+  update_CURVE[3]=list();
+  update_CURVE[4]=Conductor;
+  update_CURVE[5]=list();
+  int i;
+  intvec pP=0,0,0;
+  if (size(#)==0)
+  {
+    dbprint(printlevel+1,"Computing affine singular places ... ");
+    if (s>0)
+    {
+      for (i=1;i<=s;i=i+1)
+      {
+        pP[3]=i;
+        update_CURVE=place(pP,1,update_CURVE);
+      }
+    }
+    dbprint(printlevel+1,"Computing singular places at infinity ... ");
+    s=size(Inf_Points[1]);
+    if (s>0)
+    {
+      pP[2]=1;
+      for (i=1;i<=s;i=i+1)
+      {
+        pP[3]=i;
+        update_CURVE=place(pP,1,update_CURVE);
+      }
+    }
+  }
+  else
+  {
+    dbprint(printlevel+1,"Computing affine singular places ... ");
+    s=size(Aff_SPoints);
+    if (s>0)
+    {
+      for (i=1;i<=s;i=i+1)
+      {
+        pP[3]=i;
+        update_CURVE=place(pP,2,update_CURVE);
+      }
+    }
+    dbprint(printlevel+1,"Computing singular places at infinity ... ");
+    s=size(Inf_Points[1]);
+    if (s>0)
+    {
+      pP[2]=1;
+      for (i=1;i<=s;i=i+1)
+      {
+        pP[3]=i;
+        update_CURVE=place(pP,2,update_CURVE);
+      }
+    }
+  }
+  dbprint(printlevel+1,"Computing non-singular places at infinity ... ");
+  s=size(Inf_Points[2]);
+  if (s>0)
+  {
+    pP[2]=2;
+    for (i=1;i<=s;i=i+1)
+    {
+      pP[3]=i;
+      update_CURVE=place(pP,0,update_CURVE);
+    }
+  }
+  dbprint(printlevel+1,"Adjunction divisor computed successfully");
+  list Places=update_CURVE[3];
+  Conductor=update_CURVE[4];
+  genusX = genusX - (deg_D(Conductor,Places) div 2);
+  update_CURVE[2][2]=genusX;
+  setring Base_R;
+  dbprint(printlevel+1," ");
+  dbprint(printlevel+2,"The genus of the curve is "+string(genusX));
+  option(set,opgt);
+  return(update_CURVE);
+}
+example
+{
+  "EXAMPLE:";  echo = 2;
+  int plevel=printlevel;
+  printlevel=-1;
+  ring s=2,(x,y),lp;
+  list C=Adj_div(y9+y8+xy6+x2y3+y2+x3);
+  def aff_R=C[1][1];      // the affine ring
+  setring aff_R;
+  listvar(aff_R);         // data in the affine ring
+  CHI;                    // affine equation of the curve
+  Aff_SLocus;             // ideal of the affine singular locus
+  Aff_SPoints[1];         // 1st affine singular point: (1:1:1), no.1
+  Inf_Points[1];          // singular point(s) at infinity: (1:0:0), no.4
+  Inf_Points[2];          // list of non-singular points at infinity
+  //
+  pause("press RETURN");
+  def proj_R=C[1][2];     // the projective ring
+  setring proj_R;
+  CHI;                    // projective equation of the curve
+  C[2][1];                // degree of the curve
+  C[2][2];                // genus of the curve
+  C[3];                   // list of computed places
+  C[4];                   // adjunction divisor (all points are singular!)
+  //
+  pause("press RETURN");
+  // we look at the place(s) of degree 2 by changing to the ring
+  C[5][2][1];
+  def S(2)=C[5][2][1];
+  setring S(2);
+  POINTS;                // base point(s) of place(s) of degree 2: (1:a:1)
+  LOC_EQS;               // local equation(s)
+  PARAMETRIZATIONS;      // parametrization(s) and exactness
+  BRANCHES;              // Hamburger-Noether development
+  printlevel=plevel;
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc NSplaces (intvec h,list CURVE)
+"USAGE:   NSplaces( h, CURVE ), where h is an intvec and CURVE is a list
+RETURN:   list L with updated data of CURVE after computing all non-singular
+          affine closed places whose degrees are in the intvec h: @*
+   @format
+   in L[1][1]: (affine ring) lists Aff_Points(d) with affine non-singular
+               (closed) points of degree d (if non-empty),
+   in L[3]:    the newly computed closed places are added,
+   in L[5]:    local rings created/updated to store (repres. of) new places.
+   @end format
+          See @ref{Adj_div} for a description of the entries in L.
+NOTE:     The list_expression should be the output of the procedure Adj_div.@*
+          Raising @code{printlevel}, additional comments are displayed
+          (default: @code{printlevel=0}).
+WARNING:  The parameter of the needed field extensions is called 'a'. Thus,
+          there should be no global object named 'a' when executing NSplaces.
+SEE ALSO: closed_points, Adj_div
+EXAMPLE:  example NSplaces; shows an example
+"
+{
+  // computes all the non-singular affine (closed) places with fixed degrees
+  // creates lists of points and the corresponding places
+  // list CURVE must be the output of the procedure "Adj_div"
+  // notice : if h==0 then nothing is done
+  // warning : non-positive entries are forgotten
+  if (defined(a)==1)
+  {
+    if ((typeof(a)=="int") or (typeof(a)=="intvec") or (typeof(a)=="intmat") or
+        (typeof(a)=="string") or (typeof(a)=="proc") or (typeof(a)=="list"))
+    {
+      print("WARNING: There is an object named 'a' of the global type "
+             + typeof(a)+".");
+      print("This will cause problems when "
+             + "executing Adj_div, as 'a' is used for "
+             + "the name of the parameter of the field extensions needed.");
+      ERROR("Please rename or kill the object named 'a'");
+    }
+  }
+  if (h==0)
+  {
+    return(CURVE);
+  }
+  intvec opgt=option(get);
+  option(redSB);
+  def Base_R=basering;
+  def aff_r=CURVE[1][1];
+  int M=size(h);
+  list update_CURVE=CURVE;
+  int i,j,l,s;
+  setring aff_r;
+  intvec pP=1,0,0;
+  for (i=1;i<=M;i=i+1)
+  {
+    l=h[i];
+    if (l>0)
+    {
+      dbprint(printlevel+1,"Computing non-singular affine places of degree "
+                             +string(l)+" ... ");
+      if (defined(Aff_Points(l))==0)
+      {
+        list Aff_Points(l)=closed_points_deg(CHI,l,Aff_SLocus);
+        s=size(Aff_Points(l));
+        if (s>0)
+        {
+          export(Aff_Points(l));
+          pP[2]=l;
+          for (j=1;j<=s;j=j+1)
+          {
+            dbprint(printlevel-voice-2,"Place No.\ "+string(j));
+            pP[3]=j;
+            update_CURVE=place(pP,0,update_CURVE);
+          }
+        }
+      }
+    }
+  }
+  setring Base_R;
+  option(set,opgt);
+  return(update_CURVE);
+}
+example
+{
+  "EXAMPLE:";  echo = 2;
+  int plevel=printlevel;
+  printlevel=-1;
+  ring s=2,(x,y),lp;
+  list C=Adj_div(x3y+y3+x);
+  // The list of computed places:
+  C[3];
+  // create places up to degree 4
+  list L=NSplaces(1..4,C);
+  // The list of computed places is now:
+  L[3];
+  // e.g., affine non-singular points of degree 4 :
+  def aff_r=L[1][1];
+  setring aff_r;
+  Aff_Points(4);
+  // e.g., base point of the 1st place of degree 4 :
+  def S(4)=L[5][4][1];
+  setring S(4);
+  POINTS[1];
+  printlevel=plevel;
+}
+///////////////////////////////////////////////////////////////////////////////
+
+// ** SPECIAL PROCEDURES FOR LINEAR ALGEBRA **
+
+static proc Ker (matrix A)
+{
+  // warning : "lp" ordering is necessary
+  intvec opgt=option(get);
+  option(redSB);
+  matrix M=transpose(syz(A));
+  option(set,opgt);
+  return(M);
+}
+///////////////////////////////////////////////////////////////////////////////
+static proc get_NZsol (matrix A)
+{
+  matrix sol=Ker(A);
+  return(submat(sol,1..1,1..ncols(sol)));
+}
+///////////////////////////////////////////////////////////////////////////////
+static proc supplement (matrix W,matrix V)
+"USAGE:     supplement(W,V), where W,V are matrices of numbers such that the
+            vector space generated by the rows of W is contained in that
+            generated by the rows of V
+RETURN:     matrix whose rows generate a supplementary vector space of W in V,
+            or a zero row-matrix if <W>==<V>
+NOTE:       W,V must be given with maximal rank
+"
+{
+  // W and V represent independent sets of vectors and <W> is assumed to be
+  // contained in <V>
+  // computes matrix S whose rows are l.i. vectors s.t. <W> union <S> is a
+  // basis of <V>
+  // careful : the size of all vectors is assumed to be the same but it is
+  //  not checked and neither the linear independence of the vectors is checked
+  // the trivial case W=0 is not covered by this procedure (and thus V<>0)
+  // if <W>=<V> then a zero row-matrix is returned
+  // warning : option(redSB) must be set in advance
+  int n1=nrows(W);
+  int n2=nrows(V);
+  int s=n2-n1;
+  if (s==0)
+  {
+    int n=ncols(W);
+    matrix HH[1][n];
+    return(HH);
+  }
+  matrix H=transpose(lift(transpose(V),transpose(W)));
+  H=supplem(H);
+  return(H*V);
+}
+///////////////////////////////////////////////////////////////////////////////
+static proc supplem (matrix M)
+"USAGE:      supplem(M), where M is a matrix of numbers with maximal rank
+RETURN:     matrix whose rows generate a supplementary vector space of <M> in
+            k^n, where k is the base field and n is the number of columns
+SEE ALSO:   supplement
+NOTE:       The rank r is assumed to be 1<r<n.
+"
+{
+  // warning : the linear independence of the rows is not checked
+  int r=nrows(M);
+  int n=ncols(M);
+  int s=n-r;
+  matrix A=M;
+  matrix supl[s][n];
+  int counter=0;
+  int h=r+1;
+  int i;
+  for (i=1;i<=n;i=i+1)
+  {
+    matrix TT[1][n];
+    TT[1,i]=1;
+    A=transpose(concat(transpose(A),transpose(TT)));
+    r=mat_rank(A);
+    if (r==h)
+    {
+      h=h+1;
+      counter=counter+1;
+      supl=transpose(concat(transpose(supl),transpose(TT)));
+      if (counter==s)
+      {
+        break;
+      }
+    }
+    kill TT;
+  }
+  supl=transpose(compress(transpose(supl)));
+  return(supl);
+}
+///////////////////////////////////////////////////////////////////////////////
+static proc mat_rank (matrix A)
+{
+  // warning : "lp" ordering is necessary
+  intvec opgt=option(get);
+  option(redSB);
+  int r=size(std(module(transpose(A))));
+  option(set,opgt);
+  return(r);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+// ***************************************************************
+// * PROCEDURES FOR INTERPOLATION, INTERSECTION AND EXTRA PLACES *
+// ***************************************************************
+
+static proc estim_n (intvec Dplus,int dgX,list PL)
+{
+  // computes an estimate for the degree n in the Brill-Noether algorithm
+  int estim=2*deg_D(Dplus,PL)+dgX*(dgX-3);
+  estim=estim div (2*dgX);
+  estim=estim+1;
+  if (estim<dgX)
+  {
+    estim=dgX;
+  }
+  return(estim);
+}
+///////////////////////////////////////////////////////////////////////////////
+static proc nforms (int n)
+{
+  // computes the list of all homogeneous monomials of degree n>=0
+  // exports ideal nFORMS(n) whose generators are ranged with lp order
+  //   in Proj_R and returns size(nFORMS(n))
+  // warning : it is supposed to be called inside Proj_R
+  // if n<=0 then nFORMS(0) is "computed fast"
+  ideal nFORMS(n);
+  int N;
+  if (n>0)
+  {
+    N=(n+1)*(n+2);
+    N=N div 2;
+    N=N+1;
+    int i,j,k;
+    for (i=0;i<=n;i=i+1)
+    {
+      for (j=0;j<=n-i;j=j+1)
+      {
+        k=k+1;
+        nFORMS(n)[N-k]=x^i*y^j*z^(n-i-j);
+      }
+    }
+    export(nFORMS(n));
+  }
+  else
+  {
+    N=2;
+    nFORMS(0)=1;
+    export(nFORMS(0));
+  }
+  return(N-1);
+}
+///////////////////////////////////////////////////////////////////////////////
+static proc nmultiples (int n,int dgX,poly f)
+{
+  // computes a basis of the space of forms of degree n which are multiple of
+  //     CHI
+  // returns a matrix whose rows are the coordinates (related to nFORMS(n))
+  //     of such a basis
+  // warning : it is supposed to be called inside Proj_R
+  // warning : nFORMS(n) is created in the way, together with nFORMS(n-degX)
+  // warning : n must be greater or equal than the degree of the curve
+  if (defined(nFORMS(n))==0)
+  {
+    dbprint(printlevel+1,string(nforms(n)));
+  }
+  int m=n-dgX;
+  if (defined(nFORMS(m))==0)
+  {
+    int k=nforms(m);
+  }
+  else
+  {
+    int k=size(nFORMS(m));
+  }
+  ideal nmults;
+  int i;
+  for (i=1;i<=k;i=i+1)
+  {
+    nmults[i]=f*nFORMS(m)[i];
+  }
+  return(transpose(lift(nFORMS(n),nmults)));
+}
+///////////////////////////////////////////////////////////////////////////////
+static proc interpolating_forms (intvec D,int n,list CURVE)
+{
+  // computes a vector basis of the space of forms of degree n whose
+  //     intersection divisor with the curve is greater or equal than D>=0
+  // the procedure is supposed to be called inside the ring Proj_R and
+  //     assumes that the forms nFORMS(n) are previously computed
+  // the output is a matrix whose rows are the coordinates in nFORMS(n) of
+  //     such a basis
+  // remark : the support of D may contain "extra" places
+  def BR=basering;
+  def aff_r=CURVE[1][1];
+  int N=size(nFORMS(n));
+  matrix totalM[1][N];
+  int s=size(D);
+  list Places=CURVE[3];
+  int NPls=size(Places);
+  int i,j,k,kk,id,ip,RR,ordx,ordy,nr,NR;
+  if (s<=NPls)
+  {
+    for (i=1;i<=s;i=i+1)
+    {
+      if (D[i]>0)
+      {
+        id=Places[i][1];
+        ip=Places[i][2];
+        RR=D[i];
+        def SS=CURVE[5][id][1];
+        setring SS;
+        poly xt=PARAMETRIZATIONS[ip][1][1];
+        poly yt=PARAMETRIZATIONS[ip][1][2];
+        ordx=PARAMETRIZATIONS[ip][2][1];
+        ordy=PARAMETRIZATIONS[ip][2][2];
+        nr=ncols(BRANCHES[ip][1]);
+        if ( ordx>-1 || ordy>-1 )
+        {
+          while ( ( RR>=ordx && ordx>-1 ) || ( RR>=ordy && ordy>-1 ) )
+          {
+            BRANCHES[ip]=extdevelop(BRANCHES[ip],2*nr);
+            nr=ncols(BRANCHES[ip][1]);
+            PARAMETRIZATIONS[ip]=param(BRANCHES[ip],0);
+            xt=PARAMETRIZATIONS[ip][1][1];
+            yt=PARAMETRIZATIONS[ip][1][2];
+            ordx=PARAMETRIZATIONS[ip][2][1];
+            ordy=PARAMETRIZATIONS[ip][2][2];
+          }
+        }
+        if (POINTS[ip][3]==number(1))
+        {
+          number A=POINTS[ip][1];
+          number B=POINTS[ip][2];
+          map Mt=BR,A+xt,B+yt,1;
+          kill A,B;
+        }
+        else
+        {
+          if (POINTS[ip][2]==number(1))
+          {
+            number A=POINTS[ip][1];
+            map Mt=BR,A+xt,1,yt;
+            kill A;
+          }
+          else
+          {
+            map Mt=BR,1,xt,yt;
+          }
+        }
+        ideal nFORMS(n)=Mt(nFORMS(n));
+        // rewrite properly the above conditions to obtain the local equations
+        matrix partM[RR][N];
+        matrix auxMC=coeffs(nFORMS(n),t);
+        NR=nrows(auxMC);
+        if (RR<=NR)
+        {
+          for (j=1;j<=RR;j=j+1)
+          {
+            for (k=1;k<=N;k=k+1)
+            {
+              partM[j,k]=number(auxMC[j,k]);
+            }
+          }
+        }
+        else
+        {
+          for (j=1;j<=NR;j=j+1)
+          {
+            for (k=1;k<=N;k=k+1)
+            {
+              partM[j,k]=number(auxMC[j,k]);
+            }
+          }
+          for (j=NR+1;j<=RR;j=j+1)
+          {
+            for (k=1;k<=N;k=k+1)
+            {
+              partM[j,k]=number(0);
+            }
+          }
+        }
+        matrix localM=partM;
+        matrix conjM=partM;
+        for (j=2;j<=id;j=j+1)
+        {
+          conjM=Frobenius(conjM,1);
+          localM=transpose(concat(transpose(localM),transpose(conjM)));
+        }
+        localM=gauss_row(localM);
+        setring BR;
+        totalM=transpose(concat(transpose(totalM),transpose(imap(SS,localM))));
+        totalM=transpose(compress(transpose(totalM)));
+        setring SS;
+        kill xt,yt,Mt,nFORMS(n),partM,auxMC,conjM,localM;
+        setring BR;
+        kill SS;
+      }
+    }
+  }
+  else
+  {
+    // distinguish between "standard" places and "extra" places
+    for (i=1;i<=NPls;i=i+1)
+    {
+      if (D[i]>0)
+      {
+        id=Places[i][1];
+        ip=Places[i][2];
+        RR=D[i];
+        def SS=CURVE[5][id][1];
+        setring SS;
+        poly xt=PARAMETRIZATIONS[ip][1][1];
+        poly yt=PARAMETRIZATIONS[ip][1][2];
+        ordx=PARAMETRIZATIONS[ip][2][1];
+        ordy=PARAMETRIZATIONS[ip][2][2];
+        nr=ncols(BRANCHES[ip][1]);
+        if ( ordx>-1 || ordy>-1 )
+        {
+          while ( ( RR>=ordx && ordx>-1 ) || ( RR>=ordy && ordy>-1 ) )
+          {
+            BRANCHES[ip]=extdevelop(BRANCHES[ip],2*nr);
+            nr=ncols(BRANCHES[ip][1]);
+            PARAMETRIZATIONS[ip]=param(BRANCHES[ip],0);
+            xt=PARAMETRIZATIONS[ip][1][1];
+            yt=PARAMETRIZATIONS[ip][1][2];
+            ordx=PARAMETRIZATIONS[ip][2][1];
+            ordy=PARAMETRIZATIONS[ip][2][2];
+          }
+        }
+        if (POINTS[ip][3]==number(1))
+        {
+          number A=POINTS[ip][1];
+          number B=POINTS[ip][2];
+          map Mt=BR,A+xt,B+yt,1;
+          kill A,B;
+        }
+        else
+        {
+          if (POINTS[ip][2]==number(1))
+          {
+            number A=POINTS[ip][1];
+            map Mt=BR,A+xt,1,yt;
+            kill A;
+          }
+          else
+          {
+            map Mt=BR,1,xt,yt;
+          }
+        }
+        ideal nFORMS(n)=Mt(nFORMS(n));
+        // rewrite properly the above conditions to obtain the local equations
+        matrix partM[RR][N];
+        matrix auxMC=coeffs(nFORMS(n),t);
+        NR=nrows(auxMC);
+        if (RR<=NR)
+        {
+          for (j=1;j<=RR;j=j+1)
+          {
+            for (k=1;k<=N;k=k+1)
+            {
+              partM[j,k]=number(auxMC[j,k]);
+            }
+          }
+        }
+        else
+        {
+          for (j=1;j<=NR;j=j+1)
+          {
+            for (k=1;k<=N;k=k+1)
+            {
+              partM[j,k]=number(auxMC[j,k]);
+            }
+          }
+          for (j=NR+1;j<=RR;j=j+1)
+          {
+            for (k=1;k<=N;k=k+1)
+            {
+              partM[j,k]=number(0);
+            }
+          }
+        }
+        matrix localM=partM;
+        matrix conjM=partM;
+        for (j=2;j<=id;j=j+1)
+        {
+          conjM=Frobenius(conjM,1);
+          localM=transpose(concat(transpose(localM),transpose(conjM)));
+        }
+        localM=gauss_row(localM);
+        setring BR;
+        totalM=transpose(concat(transpose(totalM),transpose(imap(SS,localM))));
+        totalM=transpose(compress(transpose(totalM)));
+        setring SS;
+        kill xt,yt,Mt,nFORMS(n),partM,auxMC,conjM,localM;
+        setring BR;
+        kill SS;
+      }
+    }
+    k=s-NPls;
+    int l;
+    for (i=1;i<=k;i=i+1)
+    {
+      // in this case D[NPls+i]>0 is assumed to be true during the
+      // Brill-Noether algorithm
+      RR=D[NPls+i];
+      setring aff_r;
+      def SS=@EXTRA@[2][i];
+      def extra_dgs=@EXTRA@[3];
+      setring SS;
+      poly xt=PARAMETRIZATION[1][1];
+      poly yt=PARAMETRIZATION[1][2];
+      ordx=PARAMETRIZATION[2][1];
+      ordy=PARAMETRIZATION[2][2];
+      nr=ncols(BRANCH[1]);
+      if ( ordx>-1 || ordy>-1 )
+      {
+        while ( ( RR>=ordx && ordx>-1 ) || ( RR>=ordy && ordy>-1 ) )
+        {
+          BRANCH=extdevelop(BRANCH,2*nr);
+          nr=ncols(BRANCH[1]);
+          PARAMETRIZATION=param(BRANCH,0);
+          xt=PARAMETRIZATION[1][1];
+          yt=PARAMETRIZATION[1][2];
+          ordx=PARAMETRIZATION[2][1];
+          ordy=PARAMETRIZATION[2][2];
+        }
+      }
+      number A=POINT[1];
+      number B=POINT[2];
+      map Mt=BR,A+xt,B+yt,1;
+      kill A,B;
+      ideal nFORMS(n)=Mt(nFORMS(n));
+      // rewrite properly the above conditions to obtain the local equations
+      matrix partM[RR][N];
+      matrix auxMC=coeffs(nFORMS(n),t);
+      NR=nrows(auxMC);
+      if (RR<=NR)
+      {
+        for (j=1;j<=RR;j=j+1)
+        {
+          for (kk=1;kk<=N;kk=kk+1)
+          {
+            partM[j,kk]=number(auxMC[j,kk]);
+          }
+        }
+      }
+      else
+      {
+        for (j=1;j<=NR;j=j+1)
+        {
+          for (kk=1;kk<=N;kk=kk+1)
+          {
+            partM[j,kk]=number(auxMC[j,kk]);
+          }
+        }
+        for (j=NR+1;j<=RR;j=j+1)
+        {
+          for (kk=1;kk<=N;kk=kk+1)
+          {
+            partM[j,kk]=number(0);
+          }
+        }
+      }
+      matrix localM=partM;
+      matrix conjM=partM;
+      l=extra_dgs[i];
+      for (j=2;j<=l;j=j+1)
+      {
+        conjM=Frobenius(conjM,1);
+        localM=transpose(concat(transpose(localM),transpose(conjM)));
+      }
+      localM=gauss_row(localM);
+      setring BR;
+      totalM=transpose(concat(transpose(totalM),transpose(imap(SS,localM))));
+      totalM=transpose(compress(transpose(totalM)));
+      setring SS;
+      kill xt,yt,Mt,nFORMS(n),partM,auxMC,conjM,localM;
+      setring BR;
+      kill SS;
+    }
+  }
+  return(Ker(totalM));
+}
+///////////////////////////////////////////////////////////////////////////////
+static proc local_IN (poly h,int m)
+{
+  // computes the intersection number of h and the curve CHI at a certain place
+  // returns a list with the intersection number and the "leading coefficient"
+  // the procedure must be called inside a local ring, h must be a local
+  //     equation with respect to the desired place, and m indicates the
+  //     number of place inside that local ring, containing lists
+  //     POINT(S)/BRANCH(ES)/PARAMETRIZATION(S) when m=0 an "extra place" is
+  //     considered
+  def BR=basering;
+  if (m>0)
+  {
+    int nr=ncols(BRANCHES[m][1]);
+    poly xt=PARAMETRIZATIONS[m][1][1];
+    poly yt=PARAMETRIZATIONS[m][1][2];
+    int ordx=PARAMETRIZATIONS[m][2][1];
+    int ordy=PARAMETRIZATIONS[m][2][2];
+    map phi=BR,xt,yt,1;
+    poly ht=phi(h);
+    int inum=mindeg(ht);
+    if ( ordx>-1 || ordy>-1 )
+    {
+      while (((inum>ordx||inum==-1) && ordx>-1) || ((inum>ordy||inum==-1) && ordy>-1))
+      {
+        BRANCHES[m]=extdevelop(BRANCHES[m],2*nr);
+        nr=ncols(BRANCHES[m][1]);
+        PARAMETRIZATIONS[m]=param(BRANCHES[m],0);
+        xt=PARAMETRIZATIONS[m][1][1];
+        yt=PARAMETRIZATIONS[m][1][2];
+        ordx=PARAMETRIZATIONS[m][2][1];
+        ordy=PARAMETRIZATIONS[m][2][2];
+        phi=BR,xt,yt,1;
+        ht=phi(h);
+        inum=mindeg(ht);
+      }
+    }
+  }
+  else
+  {
+    int nr=ncols(BRANCH[1]);
+    poly xt=PARAMETRIZATION[1][1];
+    poly yt=PARAMETRIZATION[1][2];
+    int ordx=PARAMETRIZATION[2][1];
+    int ordy=PARAMETRIZATION[2][2];
+    map phi=basering,xt,yt,1;
+    poly ht=phi(h);
+    int inum=mindeg(ht);
+    if ( ordx>-1 || ordy>-1 )
+    {
+      while (((inum>ordx||inum==-1) && ordx>-1) || ((inum>ordy||inum==-1) && ordy>-1))
+      {
+        BRANCH=extdevelop(BRANCH,2*nr);
+        nr=ncols(BRANCH[1]);
+        PARAMETRIZATION=param(BRANCH,0);
+        xt=PARAMETRIZATION[1][1];
+        yt=PARAMETRIZATION[1][2];
+        ordx=PARAMETRIZATION[2][1];
+        ordy=PARAMETRIZATION[2][2];
+        phi=BR,xt,yt,1;
+        ht=phi(h);
+        inum=mindeg(ht);
+      }
+    }
+  }
+  list answer=list();
+  answer[1]=inum;
+  number AA=number(coeffs(ht,t)[inum+1,1]);
+  answer[2]=AA;
+  return(answer);
+}
+///////////////////////////////////////////////////////////////////////////////
+static proc extra_place (ideal P)
+{
+  // computes the "rational" place which is defined over a (closed) "extra"
+  //     point
+  // an "extra" point will be necessarily affine, non-singular and non-rational
+  // creates : a specific local ring to deal with the (unique) place above it
+  // returns : list with the above local ring and the degree of the point/place
+  // warning : the procedure must be called inside the affine ring aff_r
+  def base_r=basering;
+  int ext=deg(P[1]);
+  poly aux=subst(P[2],y,1);
+  ext=ext*deg(aux);
+  // P is assumed to be a std. resp. "(x,y),lp" and thus P[1] depends only
+  // on "y"
+  if (deg(P[1])==1)
+  {
+    // the point is non-rational but the second component needs no field
+    // extension
+    number B=-number(subst(P[1],y,0));
+    poly aux2=subst(P[2],y,B);
+    // careful : the parameter will be called "a" anyway
+    ring ES=(char(basering),a),(x,y,t),ls;
+    map psi=base_r,a,0;
+    minpoly=number(psi(aux2));
+    if (defined (psi))
+    {
+      kill psi;
+    }
+    number A=a;
+    number B=imap(base_r,B);
+  }
+  else
+  {
+    if (deg(subst(P[2],y,1))==1)
+    {
+      // the point is non-rational but the needed minpoly is just P[1]
+      // careful : the parameter will be called "a" anyway
+      poly P1=P[1];
+      poly P2=P[2];
+      ring ES=(char(basering),a),(x,y,t),ls;
+      map psi=base_r,0,a;
+      minpoly=number(psi(P1));
+      if (defined (psi))
+      {
+        kill psi;
+      }
+      poly aux1=imap(base_r,P2);
+      poly aux2=subst(aux1,y,a);
+      number A=-number(subst(aux2,x,0));
+      number B=a;
+    }
+    else
+    {
+      // this is the most complicated case of non-rational point
+      poly P1=P[1];
+      poly P2=P[2];
+      int p=char(basering);
+      int Q=p^ext;
+      ring aux_r=(Q,a),(x,y,t),ls;
+      string minpoly_string=string(minpoly);
+      ring ES=(char(basering),a),(x,y,t),ls;
+      execute("minpoly="+minpoly_string+";");
+      poly P_1=imap(base_r,P1);
+      poly P_2=imap(base_r,P2);
+      ideal factors1=factorize(P_1,1);
+      number B=-number(subst(factors1[1],y,0));
+      poly P_0=subst(P_2,y,B);
+      ideal factors2=factorize(P_0,1);
+      number A=-number(subst(factors2[1],x,0));
+      kill aux_r;
+    }
+  }
+  list POINT=list();
+  POINT[1]=A;
+  POINT[2]=B;
+  export(POINT);
+  map phi=base_r,x+A,y+B;
+  poly LOC_EQ=phi(CHI);
+  kill A,B,phi;
+  list LLL=hnexpansion(LOC_EQ,"ess");
+  if (typeof(LLL[1])=="ring") {
+    def altring=basering;
+    def HNEring = LLL[1];
+    setring HNEring;
+    def L at HNE = hne[1];
+    kill hne;
+    export(L at HNE);
+    int m=nrows(L at HNE[1]);
+    int n=ncols(L at HNE[1]);
+    intvec Li2=L at HNE[2];
+    int Li3=L at HNE[3];
+    setring ES;
+    string newa=subfield(HNEring);
+    poly paux=importdatum(HNEring,"L at HNE[4]",newa);
+    matrix Maux[m][n];
+    int i,j;
+    for (i=1;i<=m;i=i+1)
+    {
+      for (j=1;j<=n;j=j+1)
+      {
+        Maux[i,j]=importdatum(HNEring,"L at HNE[1]["+string(i)+","+
+                                                  string(j)+"]",newa);
+      }
+    }
+  }
+  else {
+    def L at HNE=LLL[1][1];
+    matrix Maux=L at HNE[1];
+    intvec Li2=L at HNE[2];
+    int Li3=L at HNE[3];
+    poly paux=L at HNE[4];
+    def HNEring=basering;
+    setring HNEring;
+  }
+  kill LLL;
+
+  list BRANCH=list();
+  BRANCH[1]=Maux;
+  BRANCH[2]=Li2;
+  BRANCH[3]=Li3;
+  BRANCH[4]=paux;
+  export(BRANCH);
+  list PARAMETRIZATION=param(BRANCH,0);
+  export(PARAMETRIZATION);
+  kill HNEring;
+  setring base_r;
+  list answer=list();
+  answer[1]=ES;
+  answer[2]=ext;
+  kill ES;
+  return(answer);
+}
+///////////////////////////////////////////////////////////////////////////////
+static proc intersection_div (poly H,list CURVE)
+"USAGE:     intersection_div(H,CURVE), where H is a homogeneous polynomial
+            in ring Proj_R=p,(x,y,z),lp and CURVE is the list of data for
+            the given curve
+CREATE:     new places which had not been computed in advance if necessary
+            those places are stored each one in a local ring where you find
+            lists POINT,BRANCH,PARAMETRIZATION for the place living in that
+            ring; the degree of the point/place in such a ring is stored in
+            an intvec, and the base points in the remaining list
+            Everything is exported in a list @EXTRA@ inside the ring
+            aff_r=CURVE[1][1] and returned with the updated CURVE
+RETURN:     list with the intersection divisor (intvec) between the underlying
+            curve and H=0, and the list CURVE updated
+SEE ALSO:   Adj_div, NSplaces, closed_points
+NOTE:       The procedure must be called from the ring Proj_R=CURVE[1][2]
+            (projective).
+            If @EXTRA@ already exists, the new places are added to the
+            previous data.
+"
+{
+  // computes the intersection divisor of H and the curve CHI
+  // returns a list with (possibly) "extra places" and it must be called
+  //     inside Proj_R
+  // in case of extra places, some local rings ES(1) ... ES(m) are created
+  //     together with an integer list "extra_dgs" containing the degrees of
+  //     those places
+  intvec opgt=option(get);
+  option(redSB);
+  intvec interdiv;
+  def BRing=basering;
+  int Tz1=deg(H);
+  list Places=CURVE[3];
+  int N=size(Places);
+  def aff_r=CURVE[1][1];
+  setring aff_r;
+  if (defined(@EXTRA@)==0)
+  {
+    list @EXTRA@=list();
+    list EP=list();
+    list ES=list();
+    list extra_dgs=list();
+  }
+  else
+  {
+    list EP=@EXTRA@[1];
+    list ES=@EXTRA@[2];
+    list extra_dgs=@EXTRA@[3];
+  }
+  int NN=size(extra_dgs);
+  int counterEPl=0;
+  setring BRing;
+  poly h=subst(H,z,1);
+  int Tz2=deg(h);
+  int Tz3=Tz1-Tz2;
+  int i,j,k,l,m,n,s,np,NP,I_N;
+  if (Tz3==0)
+  {
+    // if this still does not work -> try always with ALL points in
+    // Inf_Points !!!!
+    poly Hinf=subst(H,z,0);
+    setring aff_r;
+    // compute the points at infinity of H and see which of them are in
+    // Inf_Points
+    poly h=imap(BRing,h);
+    poly hinf=imap(BRing,Hinf);
+    ideal pinf=factorize(hinf,1);
+    list TIP=Inf_Points[1]+Inf_Points[2];
+    s=size(TIP);
+    NP=size(pinf);
+    for (i=1;i<=NP;i=i+1)
+    {
+      for (j=1;j<=s;j=j+1)
+      {
+        if (pinf[i]==TIP[j][1])
+        {
+          np=size(TIP[j][2]);
+          for (k=1;k<=np;k=k+1)
+          {
+            n=TIP[j][2][k];
+            l=Places[n][1];
+            m=Places[n][2];
+            def SS=CURVE[5][l][1];
+            setring SS;
+            // local equation h of H
+            if (POINTS[m][2]==number(1))
+            {
+              number A=POINTS[m][1];
+              map psi=BRing,x+A,1,y;
+              kill A;
+            }
+            else
+            {
+              map psi=BRing,1,x,y;
+            }
+            poly h=psi(H);
+            I_N=local_IN(h,m)[1];
+            interdiv[n]=I_N;
+            kill h,psi;
+            setring aff_r;
+            kill SS;
+          }
+          break;
+        }
+      }
+    }
+    kill hinf,pinf;
+  }
+  else
+  {
+    // H is a multiple of z and hence all the points in Inf_Points intersect
+    // with H
+    setring aff_r;
+    poly h=imap(BRing,h);
+    list TIP=Inf_Points[1]+Inf_Points[2];
+    s=size(TIP);
+    for (j=1;j<=s;j=j+1)
+    {
+      np=size(TIP[j][2]);
+      for (k=1;k<=np;k=k+1)
+      {
+        n=TIP[j][2][k];
+        l=Places[n][1];
+        m=Places[n][2];
+        def SS=CURVE[5][l][1];
+        setring SS;
+        // local equation h of H
+        if (POINTS[m][2]==number(1))
+        {
+          number A=POINTS[m][1];
+          map psi=BRing,x+A,1,y;
+          kill A;
+        }
+        else
+        {
+          map psi=BRing,1,x,y;
+        }
+        poly h=psi(H);
+        I_N=local_IN(h,m)[1];
+        interdiv[n]=I_N;
+        kill h,psi;
+        setring aff_r;
+        kill SS;
+      }
+    }
+  }
+  // compute common affine points of H and CHI
+  ideal CAL=h,CHI;
+  CAL=std(CAL);
+  if (CAL<>1)
+  {
+    list TAP=list();
+    TAP=closed_points(CAL);
+    NP=size(TAP);
+    list auxP=list();
+    int dP;
+    for (i=1;i<=NP;i=i+1)
+    {
+      if (belongs(TAP[i],Aff_SLocus)==1)
+      {
+        // search the point in the list Aff_SPoints
+        j=isInLP(TAP[i],Aff_SPoints);
+        np=size(Aff_SPoints[j][2]);
+        for (k=1;k<=np;k=k+1)
+        {
+          n=Aff_SPoints[j][2][k];
+          l=Places[n][1];
+          m=Places[n][2];
+          def SS=CURVE[5][l][1];
+          setring SS;
+          // local equation h of H
+          number A=POINTS[m][1];
+          number B=POINTS[m][2];
+          map psi=BRing,x+A,y+B,1;
+          poly h=psi(H);
+          I_N=local_IN(h,m)[1];
+          interdiv[n]=I_N;
+          kill A,B,h,psi;
+          setring aff_r;
+          kill SS;
+        }
+      }
+      else
+      {
+        auxP=list();
+        auxP[1]=TAP[i];
+        dP=degree_P(auxP);
+        if (defined(Aff_Points(dP))<>0)
+        {
+          // search the point in the list Aff_Points(dP)
+          j=isInLP(TAP[i],Aff_Points(dP));
+          n=Aff_Points(dP)[j][2][1];
+          l=Places[n][1];
+          m=Places[n][2];
+          def SS=CURVE[5][l][1];
+          setring SS;
+          // local equation h of H
+          number A=POINTS[m][1];
+          number B=POINTS[m][2];
+          map psi=BRing,x+A,y+B,1;
+          poly h=psi(H);
+          I_N=local_IN(h,m)[1];
+          interdiv[n]=I_N;
+          kill A,B,h,psi;
+          setring aff_r;
+          kill SS;
+        }
+        else
+        {
+          // previously check if it is an existing "extra place"
+          j=isInLP(TAP[i],EP);
+          if (j>0)
+          {
+            def SS=ES[j];
+            setring SS;
+            // local equation h of H
+            number A=POINT[1];
+            number B=POINT[2];
+            map psi=BRing,x+A,y+B,1;
+            poly h=psi(H);
+            I_N=local_IN(h,0)[1];
+            interdiv[N+j]=I_N;
+            setring aff_r;
+            kill SS;
+          }
+          else
+          {
+            // then we must create a new "extra place"
+            counterEPl=counterEPl+1;
+            list EXTRA_PLACE=extra_place(TAP[i]);
+            def SS=EXTRA_PLACE[1];
+            ES[NN+counterEPl]=SS;
+            extra_dgs[NN+counterEPl]=EXTRA_PLACE[2];
+            EP[NN+counterEPl]=list();
+            EP[NN+counterEPl][1]=TAP[i];
+            EP[NN+counterEPl][2]=0;
+            setring SS;
+            // local equation h of H
+            number A=POINT[1];
+            number B=POINT[2];
+            map psi=BRing,x+A,y+B,1;
+            poly h=psi(H);
+            I_N=local_IN(h,0)[1];
+            kill A,B,h,psi;
+            interdiv[N+NN+counterEPl]=I_N;
+            setring aff_r;
+            kill SS;
+          }
+        }
+      }
+    }
+    kill TAP,auxP;
+  }
+  kill h,CAL,TIP;
+  @EXTRA@[1]=EP;
+  @EXTRA@[2]=ES;
+  @EXTRA@[3]=extra_dgs;
+  kill EP;
+  list update_CURVE=CURVE;
+  if (size(extra_dgs)>0)
+  {
+    export(@EXTRA@);
+    update_CURVE[1][1]=basering;
+  }
+  else
+  {
+    kill @EXTRA@;
+  }
+  setring BRing;
+  kill h;
+  kill aff_r;
+  list answer=list();
+  answer[1]=interdiv;
+  answer[2]=update_CURVE;
+  option(set,opgt);
+  return(answer);
+}
+///////////////////////////////////////////////////////////////////////////////
+static proc local_eq (poly H,def SS,int m)
+{
+  // computes a local equation of polynomial H in the ring SS related to the place
+  //     "m"
+  // list POINT/POINTS is searched depending on wether m=0 or m>0 respectively
+  // warning : the procedure must be called from ring "Proj_R" and returns a
+  //     string
+  def BRing=basering;
+  setring SS;
+  if (m>0)
+  {
+    if (POINTS[m][3]==number(1))
+    {
+      number A=POINTS[m][1];
+      number B=POINTS[m][2];
+      map psi=BRing,x+A,y+B,1;
+    }
+    else
+    {
+      if (POINTS[m][2]==number(1))
+      {
+        number A=POINTS[m][1];
+        map psi=BRing,x+A,1,y;
+      }
+      else
+      {
+        map psi=BRing,1,x,y;
+      }
+    }
+  }
+  else
+  {
+    number A=POINT[1];
+    number B=POINT[2];
+    map psi=BRing,x+A,y+B,1;
+  }
+  poly h=psi(H);
+  string str_h=string(h);
+  setring BRing;
+  return(str_h);
+}
+///////////////////////////////////////////////////////////////////////////////
+static proc min_wt_rmat (matrix M)
+{
+  // finds the row of M with minimum non-zero entries, i.e. minimum
+  // "Hamming-weight"
+  int m=nrows(M);
+  int n=ncols(M);
+  int i,j;
+  int Hwt=0;
+  for (j=1;j<=n;j=j+1)
+  {
+    if (M[1,j]<>0)
+    {
+      Hwt=Hwt+1;
+    }
+  }
+  int minHwt=Hwt;
+  int k=1;
+  for (i=2;i<=m;i=i+1)
+  {
+    Hwt=0;
+    for (j=1;j<=n;j=j+1)
+    {
+      if (M[i,j]<>0)
+      {
+        Hwt=Hwt+1;
+      }
+    }
+    if (Hwt<minHwt)
+    {
+      minHwt=Hwt;
+      k=i;
+    }
+  }
+  return(k);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+// ============================================================================
+// *******    MAIN PROCEDURE : the Brill-Noether algorithm             ********
+// ============================================================================
+
+proc BrillNoether (intvec G,list CURVE)
+"USAGE:    BrillNoether(G,CURVE); G an intvec, CURVE a list
+RETURN:   list of ideals (each of them with two homogeneous generators,
+          which represent the numerator, resp. denominator, of a rational
+          function).@*
+          The corresponding rational functions form a vector space basis of the
+          linear system L(G), G a rational divisor over a non-singular curve.
+NOTE:     The procedure must be called from the ring CURVE[1][2], where
+          CURVE is the output of the procedure @code{NSplaces}. @*
+          The intvec G represents a rational divisor supported on the closed
+          places of CURVE[3] (e.g. @code{G=2,0,-1;} means 2 times the closed
+          place 1 minus 1 times the closed place 3).
+SEE ALSO: Adj_div, NSplaces, Weierstrass
+EXAMPLE:  example BrillNoether; shows an example
+"
+{
+  // computes a vector basis for the space L(G),
+  //     where G is a given rational divisor over the non-singular curve
+  // returns : list of ideals in R each with 2 elements H,Ho such that
+  //           the set of functions {H/Ho} is the searched basis
+  // warning : the conductor and sufficiently many points of the plane
+  //           curve should be computed in advance, in list CURVE
+  // the algorithm of Brill-Noether is carried out in the procedure
+  def BRing=basering;
+  int degX=CURVE[2][1];
+  list Places=CURVE[3];
+  intvec Conductor=CURVE[4];
+  if (deg_D(G,Places)<0)
+  {
+    return(list());
+  }
+  intvec nuldiv;
+  if (G==nuldiv)
+  {
+    list quickL=list();
+    ideal quickId;
+    quickId[1]=1;
+    quickId[2]=1;
+    quickL[1]=quickId;
+    return(quickL);
+  }
+  intvec J=max_D(G,nuldiv)+Conductor;
+  int n=estim_n(J,degX,Places);
+  dbprint(printlevel+1,"Forms of degree "+string(n)+" : ");
+  matrix W=nmultiples(n,degX,CHI);
+  kill nFORMS(n-degX);
+  list update_CURVE=CURVE;
+  matrix V=interpolating_forms(J,n,update_CURVE);
+  matrix VmW=supplement(W,V);
+  int k=min_wt_rmat(VmW);
+  int N=size(nFORMS(n));
+  matrix H0[1][N];
+  int i,j;
+  for (i=1;i<=N;i=i+1) { H0[1,i]=VmW[k,i]; }
+  poly Ho;
+  for (i=1;i<=N;i=i+1) { Ho=Ho+(H0[1,i]*nFORMS(n)[i]); }
+  list INTERD=intersection_div(Ho,update_CURVE);
+  intvec NHo=INTERD[1];
+  update_CURVE=INTERD[2];
+  intvec AR=NHo-G;
+  matrix V2=interpolating_forms(AR,n,update_CURVE);
+  def aux_RING=update_CURVE[1][1];
+  setring aux_RING;
+  if (defined(@EXTRA@)<>0)
+  {
+    kill @EXTRA@;
+  }
+  setring BRing;
+  update_CURVE[1][1]=aux_RING;
+  kill aux_RING;
+  matrix B0=supplement(W,V2);
+  if (Hamming_wt(B0)==0)
+  {
+    return(list());
+  }
+  int ld=nrows(B0);
+  list Bres=list();
+  ideal HH;
+  poly H;
+  for (j=1;j<=ld;j=j+1)
+  {
+    H=0;
+    for (i=1;i<=N;i=i+1)
+    {
+      H=H+(B0[j,i]*nFORMS(n)[i]);
+    }
+    HH=H,Ho;
+    Bres[j]=simplifyRF(HH);
+  }
+  kill nFORMS(n);
+  dbprint(printlevel+1," ");
+  dbprint(printlevel+2,"Vector basis successfully computed ");
+  dbprint(printlevel+1," ");
+  return(Bres);
+}
+example
+{
+  "EXAMPLE:";  echo = 2;
+  int plevel=printlevel;
+  printlevel=-1;
+  ring s=2,(x,y),lp;
+  list C=Adj_div(x3y+y3+x);
+  C=NSplaces(1..4,C);
+  // the first 3 Places in C[3] are of degree 1.
+  // we define the rational divisor G = 4*C[3][1]+4*C[3][3] (of degree 8):
+  intvec G=4,0,4;
+  def R=C[1][2];
+  setring R;
+  list LG=BrillNoether(G,C);
+  // here is the vector basis of L(G):
+  LG;
+  printlevel=plevel;
+}
+///////////////////////////////////////////////////////////////////////////////
+
+// *** procedures for dealing with "RATIONAL FUNCTIONS" over a plane curve ***
+// a rational function F may be given by (homogeneous) ideal or (affine) poly
+// (or number)
+
+static proc polytoRF (F)
+{
+  // converts a polynomial (or number) into a "rational function" of type "ideal"
+  // warning : it must be called inside "R" and the polynomial is expected to be affine
+  ideal RF;
+  RF[1]=homog(F,z);
+  RF[2]=z^(deg(F));
+  return(RF);
+}
+///////////////////////////////////////////////////////////////////////////////
+static proc simplifyRF (ideal F)
+{
+  // simplifies a rational function f/g extracting the gcd(f,g)
+  // maybe add a "restriction" to the curve "CHI" but it is not easy to
+  // programm
+  poly auxp=gcd(F[1],F[2]);
+  return(ideal(division(F,auxp)[1]));
+}
+///////////////////////////////////////////////////////////////////////////////
+static proc sumRF (def F,def G)
+{
+  // sum of two "rational functions" F,G given by either a pair
+  // numerator/denominator or a poly
+  if ( typeof(F)=="ideal" && typeof(G)=="ideal" )
+  {
+    ideal FG;
+    FG[1]=F[1]*G[2]+F[2]*G[1];
+    FG[2]=F[2]*G[2];
+    return(simplifyRF(FG));
+  }
+  else
+  {
+    if (typeof(F)=="ideal")
+    {
+      ideal GG=polytoRF(G);
+      ideal FG;
+      FG[1]=F[1]*GG[2]+F[2]*GG[1];
+      FG[2]=F[2]*GG[2];
+      return(simplifyRF(FG));
+    }
+    else
+    {
+      if (typeof(G)=="ideal")
+      {
+        ideal FF=polytoRF(F);
+        ideal FG;
+        FG[1]=FF[1]*G[2]+FF[2]*G[1];
+        FG[2]=FF[2]*G[2];
+        return(simplifyRF(FG));
+      }
+      else
+      {
+        return(F+G);
+      }
+    }
+  }
+}
+///////////////////////////////////////////////////////////////////////////////
+static proc negRF (def F)
+{
+  // returns -F as rational function
+  if (typeof(F)=="ideal")
+  {
+    ideal FF=F;
+    FF[1]=-F[1];
+    return(FF);
+  }
+  else
+  {
+    return(-F);
+  }
+}
+///////////////////////////////////////////////////////////////////////////////
+static proc escprodRF (def l,def F)
+{
+  // computes l*F as rational function
+  // l should be either a number or a polynomial of degree zero
+  if (typeof(F)=="ideal")
+  {
+    ideal lF=F;
+    lF[1]=l*F[1];
+    return(lF);
+  }
+  else
+  {
+    return(l*F);
+  }
+}
+///////////////////////////////////////////////////////////////////////////////
+
+// ******** procedures to compute Weierstrass semigroups ********
+
+static proc orderRF (ideal F,def SS,int m)
+"USAGE:  orderRF(F,SS,m); F an ideal, SS a ring and m an integer
+RETURN: list with the order (int) and the leading coefficient (number)
+NOTE:   F represents a rational function, thus the procedure must be
+        called from global ring R or R(d).
+        SS contains the name of a local ring where rational places are
+        stored, and then we take that which is in position m in the
+        corresponding lists of data.
+        The order of F at the place given by SS,m is returned together
+        with the coefficient of minimum degree in the corresponding power
+        series.
+"
+{
+  // computes the order of a rational function F at a RATIONAL place given by
+  //     a local ring SS and a position "m" inside SS
+  // warning : the procedure must be called from global projective ring "R" or
+  //     "R(i)"
+  // returns a list with the order (int) and the "leading coefficient" (number)
+  def BR=basering;
+  poly f=F[1];
+  string sf=local_eq(f,SS,m);
+  poly g=F[2];
+  string sg=local_eq(g,SS,m);
+  setring SS;
+  execute("poly ff="+sf+";");
+  execute("poly gg="+sg+";");
+  list o1=local_IN(ff,m);
+  list o2=local_IN(gg,m);
+  int oo=o1[1]-o2[1];
+  number lc=o1[2]/o2[2];
+  setring BR;
+  number LC=number(imap(SS,lc));
+  return(list(oo,LC));
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc Weierstrass (int P,int m,list CURVE)
+"USAGE:    Weierstrass( i, m, CURVE );  i,m integers and CURVE a list
+RETURN:   list WS of two lists:
+  @format
+  WS[1] list of integers (Weierstr. semigroup of the curve at place i up to m)
+  WS[2] list of ideals (the associated rational functions)
+  @end format
+NOTE:     The procedure must be called from the ring CURVE[1][2],
+          where CURVE is the output of the procedure @code{NSplaces}.
+@*        i represents the place CURVE[3][i].
+@*        Rational functions are represented by numerator/denominator
+          in form of ideals with two homogeneous generators.
+WARNING:  The place must be rational, i.e., necessarily CURVE[3][i][1]=1. @*
+SEE ALSO: Adj_div, NSplaces, BrillNoether
+EXAMPLE:  example Weierstrass; shows an example
+"
+{
+  // computes the Weierstrass semigroup at a RATIONAL place P up to a bound "m"
+  //   together with the functions achieving each value up to m, via
+  //   Brill-Noether
+  // returns 2 lists : the first consists of all the poles up to m in
+  //   increasing order and the second consists of the corresponging rational
+  //   functions
+  list Places=CURVE[3];
+  intvec pl=Places[P];
+  int dP=pl[1];
+  int nP=pl[2];
+  if (dP<>1)
+  {
+    ERROR("the given place is not defined over the prime field");
+  }
+  if (m<=0)
+  {
+    if (m==0)
+    {
+      list semig=list();
+      int auxint=0;
+      semig[1]=auxint;
+      list funcs=list();
+      ideal auxF;
+      auxF[1]=1;
+      auxF[2]=1;
+      funcs[1]=auxF;
+      return(list(semig,funcs));
+    }
+    else
+    {
+      ERROR("second argument must be non-negative");
+    }
+  }
+  int auxint=0;
+  ideal auxF;
+  auxF[1]=1;
+  auxF[2]=1;
+  // Brill-Noether algorithm
+  intvec mP;
+  mP[P]=m;
+  list LmP=BrillNoether(mP,CURVE);
+  int lmP=size(LmP);
+  if (lmP==1)
+  {
+    list semig=list();
+    semig[1]=auxint;
+    list funcs=list();
+    funcs[1]=auxF;
+    return(list(semig,funcs));
+  }
+  def SS=CURVE[5][dP][1];
+  list ordLmP=list();
+  list polLmP=list();
+  list sortpol=list();
+  int maxpol;
+  int i,j,k;
+  for (i=1;i<=lmP-1;i=i+1)
+  {
+    for (j=1;j<=lmP-i+1;j=j+1)
+    {
+      ordLmP[j]=orderRF(LmP[j],SS,nP);
+      polLmP[j]=-ordLmP[j][1];
+    }
+    sortpol=sort(polLmP);
+    polLmP=sortpol[1];
+    maxpol=polLmP[lmP-i+1];
+    LmP=permute_L(LmP,sortpol[2]);
+    ordLmP=permute_L(ordLmP,sortpol[2]);
+    // triangulate LmP
+    for (k=1;k<=lmP-i;k=k+1)
+    {
+      if (polLmP[lmP-i+1-k]==maxpol)
+      {
+        LmP[lmP-i+1-k]=sumRF(LmP[lmP-i+1-k],negRF(escprodRF(
+                       ordLmP[lmP-i+1-k][2]/ordLmP[lmP-i+1][2],LmP[lmP-i+1])));
+      }
+      else
+      {
+        break;
+      }
+    }
+  }
+  polLmP[1]=auxint;
+  LmP[1]=auxF;
+  return(list(polLmP,LmP));
+}
+example
+{
+  "EXAMPLE:";  echo = 2;
+  int plevel=printlevel;
+  printlevel=-1;
+  ring s=2,(x,y),lp;
+  list C=Adj_div(x3y+y3+x);
+  C=NSplaces(1..4,C);
+  def R=C[1][2];
+  setring R;
+  // Place C[3][1] has degree 1 (i.e it is rational);
+  list WS=Weierstrass(1,7,C);
+  // the first part of the list is the Weierstrass semigroup up to 7 :
+  WS[1];
+  // and the second part are the corresponding functions :
+  WS[2];
+  printlevel=plevel;
+}
+///////////////////////////////////////////////////////////////////////////////
+
+// axiliary procedure for permuting a list or intvec
+
+proc permute_L (def L,def P)
+"USAGE:    permute_L( L, P ); L,P either intvecs or lists
+RETURN:   list obtained from L by applying the permutation given by P.
+NOTE:     If P is a list, all entries must be integers.
+SEE ALSO: sys_code, AGcode_Omega, prepSV
+EXAMPLE:  example permute_L; shows an example
+"
+{
+  // permutes the list L according to the permutation P (both intvecs or
+  //  lists of integers)
+  int s=size(L);
+  int n=size(P);
+  int i;
+  if (s<n)
+  {
+    for (i=s+1;i<=n;i=i+1)
+    {
+      L[i]=0;
+    }
+    s=size(L);
+  }
+  list auxL=L;
+  for (i=1;i<=n;i=i+1)
+  {
+    auxL[i]=L[P[i]];
+  }
+  return(auxL);
+}
+example
+{
+  "EXAMPLE:";  echo = 2;
+  list L=list();
+  L[1]="a";
+  L[2]="b";
+  L[3]="c";
+  L[4]="d";
+  intvec P=1,3,4,2;
+  // the list L is permuted according to P :
+  permute_L(L,P);
+}
+///////////////////////////////////////////////////////////////////////////////
+static proc evalRF (ideal F,def SS,int m)
+"USAGE:     evalRF(F,SS,m), where F is an ideal, SS is a ring and m is an
+            integer
+RETURN:     the evaluation (number) of F at the place given by SS,m if it is
+            well-defined
+NOTE:       F represents a rational function, thus the procedure must be
+            called from R or R(d).
+            SS contains the name of a local ring where rational places are
+            stored, and then we take that which is in position m in the
+            corresponding lists of data.
+"
+{
+  // evaluates a rational function F at a RATIONAL place given by
+  //     a local ring SS and a position "m" inside SS
+  list olc=orderRF(F,SS,m);
+  int oo=olc[1];
+  if (oo==0)
+  {
+    return(olc[2]);
+  }
+  else
+  {
+    if (oo>0)
+    {
+      return(number(0));
+    }
+    else
+    {
+      ERROR("the function is not well-defined at the given place");
+    }
+  }
+}
+///////////////////////////////////////////////////////////////////////////////
+//
+// ******** procedures for constructing AG codes ********
+//
+///////////////////////////////////////////////////////////////////////////////
+
+static proc gen_mat (list LF,intvec LP,def RP)
+"USAGE:      gen_mat(LF,LP,RP); LF list of rational functions,
+            LP intvec of rational places and RP a local ring
+RETURN:     a generator matrix of the evaluation code given by LF and LP
+SEE ALSO:   extcurve
+KEYWORDS:   evaluation codes
+NOTE:       Rational places are searched in local ring RP
+            The procedure must be called from R or R(d) fromlist CURVE
+            after having executed extcurve(d,CURVE)
+"
+{
+  // computes a generator matrix (with numbers) of the evaluation code given
+  //    by a list of rational functions LF and a list of RATIONAL places LP
+  int m=size(LF);
+  int n=size(LP);
+  matrix GM[m][n];
+  int i,j;
+  for (i=1;i<=m;i=i+1)
+  {
+    for (j=1;j<=n;j=j+1)
+    {
+      GM[i,j]=evalRF(LF[i],RP,LP[j]);
+    }
+  }
+  return(GM);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc dual_code (matrix G)
+"USAGE:   dual_code(G); G a matrix of numbers
+RETURN:   a generator matrix of the dual code generated by G
+NOTE:     The input should be a matrix G of numbers. @*
+          The output is also a parity check matrix for the code defined by G
+KEYWORDS: linear code, dual
+EXAMPLE:  example dual_code; shows an example
+"
+{
+  // computes the dual code of C given by a generator matrix G
+  //     i.e. computes a parity-check matrix H of C
+  // conversely : computes also G if H is given
+  return(Ker(G));
+}
+example
+{
+  "EXAMPLE:";  echo = 2;
+  ring s=2,T,lp;
+  // here is the Hamming code of length 7 and dimension 3
+  matrix G[3][7]=1,0,1,0,1,0,1,0,1,1,0,0,1,1,0,0,0,1,1,1,1;
+  print(G);
+  matrix H=dual_code(G);
+  print(H);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+// ======================================================================
+// *********** initial test for disjointness ***************
+// ======================================================================
+
+static proc disj_divs (intvec H,intvec P,list EC)
+{
+  int s1=size(H);
+  int s2=size(P);
+  list PLACES=EC[3];
+  def BRing=basering;
+  def auxR=EC[1][5];
+  setring auxR;
+  int s=res_deg();
+  setring BRing;
+  kill auxR;
+  int i,j,k,d,l,N,M;
+  intvec auxIV,iw;
+  for (i=1;i<=s;i=i+1)
+  {
+    if ( (s mod i) == 0 )
+    {
+      if (typeof(EC[5][i])=="list")
+      {
+        def auxR=EC[5][i][1];
+        setring auxR;
+        auxIV[i]=size(POINTS);
+        setring BRing;
+        kill auxR;
+      }
+      else
+      {
+        auxIV[i]=0;
+      }
+    }
+    else
+    {
+      auxIV[i]=0;
+    }
+  }
+  for (i=1;i<=s1;i=i+1)
+  {
+    if (H[i]<>0)
+    {
+      iw=PLACES[i];
+      d=iw[1];
+      if ( (s mod d) == 0 )
+      {
+        l=iw[2];
+        // check that this place(s) is/are not in sup(D)
+        if (d==1)
+        {
+          for (j=1;j<=s2;j=j+1)
+          {
+            if (l==P[j])
+            {
+              return(0);
+            }
+          }
+        }
+        else
+        {
+          N=0;
+          for (j=1;j<d;j=j+1)
+          {
+            N=N+j*auxIV[j];
+          }
+          N=N+d*(l-1);
+          M=N+d;
+          for (k=N+1;k<=M;k=k+1)
+          {
+            for (j=1;j<=s2;j=j+1)
+            {
+              if (k==P[j])
+              {
+                return(0);
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  kill auxIV,iw;
+  return(1);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc AGcode_L (intvec G,intvec D,list EC)
+"USAGE:    AGcode_L( G, D, EC );  G,D intvec, EC a list
+RETURN:   a generator matrix for the evaluation AG code defined by the
+          divisors G and D.
+NOTE:     The procedure must be called within the ring EC[1][4],
+          where EC is the output of @code{extcurve(d)} (or within
+          the ring EC[1][2] if d=1). @*
+          The entry i in the intvec D refers to the i-th rational
+          place in EC[1][5] (i.e., to POINTS[i], etc., see @ref{extcurve}).@*
+          The intvec G represents a rational divisor (see @ref{BrillNoether}
+          for more details).@*
+          The code evaluates the vector space basis of L(G) at the rational
+          places given by D.
+WARNINGS: G should satisfy @math{ 2*genus-2 < deg(G) < size(D) }, which is
+          not checked by the algorithm.
+          G and D should have disjoint supports (checked by the algorithm).
+SEE ALSO: Adj_div, BrillNoether, extcurve, AGcode_Omega
+EXAMPLE:  example AGcode_L; shows an example
+"
+{
+  // returns a generator matrix for the evaluation AG code given by G and D
+  // G must be a divisor defined over the prime field and D an intvec of
+  // "rational places"
+  // it must be called inside R or R(d) and requires previously "extcurve(d)"
+  def BR=basering;
+  if (disj_divs(G,D,EC)==0)
+  {
+    dbprint(printlevel+3,"? the divisors do not have disjoint supports,
+                                 0-matrix returned ?");
+    matrix answer;
+    return(answer);
+  }
+  if (res_deg()>1)
+  {
+    def R=EC[1][2];
+    setring R;
+    list LG=BrillNoether(G,EC);
+    setring BR;
+    list LG=imap(R,LG);
+    setring R;
+    kill LG;
+    setring BR;
+    kill R;
+  }
+  else
+  {
+    list LG=BrillNoether(G,EC);
+  }
+  def RP=EC[1][5];
+  matrix M=gen_mat(LG,D,RP);
+  kill LG;
+  return(M);
+}
+example
+{
+  "EXAMPLE:";  echo = 2;
+  int plevel=printlevel;
+  printlevel=-1;
+  ring s=2,(x,y),lp;
+  list HC=Adj_div(x3+y2+y);
+  HC=NSplaces(1..2,HC);
+  HC=extcurve(2,HC);
+  def ER=HC[1][4];
+  setring ER;
+  intvec G=5;      // the rational divisor G = 5*HC[3][1]
+  intvec D=2..9;   // D = sum of the rational places no. 2..9 over F_4
+  // let us construct the corresponding evaluation AG code :
+  matrix C=AGcode_L(G,D,HC);
+  // here is a linear code of type [8,5,>=3] over F_4
+  print(C);
+  printlevel=plevel;
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc AGcode_Omega (intvec G,intvec D,list EC)
+"USAGE:    AGcode_Omega( G, D, EC ); G,D intvec, EC a list
+RETURN:   a generator matrix for the residual AG code defined by the
+          divisors G and D.
+NOTE:     The procedure must be called within the ring EC[1][4],
+          where EC is the output of @code{extcurve(d)} (or within
+          the ring EC[1][2] if d=1). @*
+          The entry i in the intvec D refers to the i-th rational
+          place in EC[1][5] (i.e., to POINTS[i], etc., see @ref{extcurve}).@*
+          The intvec G represents a rational divisor (see @ref{BrillNoether}
+          for more details).@*
+          The code computes the residues of a vector space basis of
+          @math{\Omega(G-D)} at the rational places given by D.
+WARNINGS: G should satisfy @math{ 2*genus-2 < deg(G) < size(D) }, which is
+          not checked by the algorithm.
+          G and D should have disjoint supports (checked by the algorithm).
+SEE ALSO: Adj_div, BrillNoether, extcurve, AGcode_L
+EXAMPLE:  example AGcode_Omega; shows an example
+"
+{
+  // returns a generator matrix for the residual AG code given by G and D
+  // G must be a divisor defined over the prime field and D an intvec or
+  // "rational places"
+  // it must be called inside R or R(d) and requires previously "extcurve(d)"
+  return(dual_code(AGcode_L(G,D,EC)));
+}
+example
+{
+  "EXAMPLE:";  echo = 2;
+  int plevel=printlevel;
+  printlevel=-1;
+  ring s=2,(x,y),lp;
+  list HC=Adj_div(x3+y2+y);
+  HC=NSplaces(1..2,HC);
+  HC=extcurve(2,HC);
+  def ER=HC[1][4];
+  setring ER;
+  intvec G=5;      // the rational divisor G = 5*HC[3][1]
+  intvec D=2..9;   // D = sum of the rational places no. 2..9 over F_4
+  // let us construct the corresponding residual AG code :
+  matrix C=AGcode_Omega(G,D,HC);
+  // here is a linear code of type [8,3,>=5] over F_4
+  print(C);
+  printlevel=plevel;
+}
+///////////////////////////////////////////////////////////////////////////////
+
+// ============================================================================
+// *******   auxiliary procedure to define AG codes over extensions    ********
+// ============================================================================
+
+proc extcurve (int d,list CURVE)
+"USAGE:    extcurve( d, CURVE ); d an integer, CURVE a list
+RETURN:   list L which is the update of the list CURVE with additional entries
+   @format
+   L[1][3]: ring (p,a),(x,y),lp (affine),
+   L[1][4]: ring (p,a),(x,y,z),lp (projective),
+   L[1][5]: ring (p,a),(x,y,t),ls (local),
+   L[2][3]: int  (the number of rational places),
+   @end format
+          the rings being defined over a field extension of degree d. @*
+          If d<2 then @code{extcurve(d,CURVE);} creates a list L which
+          is the update of the list CURVE with additional entries
+   @format
+   L[1][5]: ring p,(x,y,t),ls,
+   L[2][3]: int  (the number of computed places over the base field).
+   @end format
+          In both cases, in the ring L[1][5] lists with the data for all the
+          computed rational places (after a field extension of degree d) are
+          created (see @ref{Adj_div}):
+   @format
+   lists POINTS, LOC_EQS, BRANCHES, PARAMETRIZATIONS.
+   @end format
+NOTE:     The list CURVE should be the output of @code{NSplaces},
+          and must contain (at least) one place of degree d. @*
+          You actually need all the places with degree dividing d.
+          Otherwise, not all the places are computed, but only part of them. @*
+          This procedure must be executed before constructing AG codes,
+          even if no extension is needed. The ring L[1][4] must be active
+          when constructing codes over the field extension.@*
+SEE ALSO: closed_points, Adj_div, NSplaces, AGcode_L, AGcode_Omega
+EXAMPLE:  example extcurve; shows an example
+"
+{
+  // extends the underlying curve and all its associated objects to a larger
+  //     base field in order to evaluate points over such a extension
+  // if d<2 then the only change is that a local ring "RatPl" (which is a
+  //     copy of "S(1)") is created in order to store the rational places
+  //     where we can do evaluations
+  // otherwise, such a ring contains all places which are rational over the
+  //     extension
+  // warning : list Places does not change so that only divisors which are
+  //     "rational over the prime field" are allowed; this probably will
+  //     change in the future
+  // warning : the places in RatPl are ranged in increasing degree, respecting
+  //     the order from list Places and placing the conjugate branches all
+  //     together
+  def BR=basering;
+  list ext_CURVE=CURVE;
+  if (d<2)
+  {
+    def SS=CURVE[5][1][1];
+    ring RatPl=char(basering),(x,y,t),ls;
+    list POINTS=imap(SS,POINTS);
+    list LOC_EQS=imap(SS,LOC_EQS);
+    list BRANCHES=imap(SS,BRANCHES);
+    list PARAMETRIZATIONS=imap(SS,PARAMETRIZATIONS);
+    export(POINTS);
+    export(LOC_EQS);
+    export(BRANCHES);
+    export(PARAMETRIZATIONS);
+    int NrRatPl=size(POINTS);
+    ext_CURVE[2][3]=NrRatPl;
+    setring BR;
+    ext_CURVE[1][5]=RatPl;
+    dbprint(printlevel+1,"");
+    dbprint(printlevel+2,"Total number of rational places : "+string(NrRatPl));
+    dbprint(printlevel+1,"");
+    kill RatPl;
+    return(ext_CURVE);
+  }
+  else
+  {
+    // exclude the case when no place of degree d was previously computed/found
+    int dd=size(CURVE[5]);
+    if (dd<d)
+    {
+      ERROR("you did not compute/find any place of degree "+string(d));
+    }
+    if (typeof(CURVE[5][d])<>"list")
+    {
+      ERROR("you did not compute/find any place of degree "+string(d));
+    }
+
+    // Define the ring "RatPl" :
+    def S(d)=CURVE[5][d][1];
+    setring S(d);
+    string smin=string(minpoly);
+    setring BR;
+    ring RatPl=(char(basering),a),(x,y,t),ls;
+    execute("minpoly="+smin+";");
+
+    // import data from local ring S(d)
+    list POINTS=imap(S(d),POINTS);
+    list LOC_EQS=imap(S(d),LOC_EQS);
+    list BRANCHES=imap(S(d),BRANCHES);
+    list PARAMETRIZATIONS=imap(S(d),PARAMETRIZATIONS);
+    kill S(d);
+
+    // conjugate data from S(d)
+    int s=size(POINTS);
+    int counter=0;
+    int piv=0;
+    int i,j,k;
+    for (j=1;j<=s;j=j+1)
+    {
+      counter=counter+1;
+      piv=counter;
+      for (k=1;k<d;k=k+1)
+      {
+        POINTS=insert(POINTS,Frobenius(POINTS[piv],1),counter);
+        LOC_EQS=insert(LOC_EQS,Frobenius(LOC_EQS[piv],1),counter);
+        BRANCHES=insert(BRANCHES,conj_b(BRANCHES[piv],1),counter);
+        PARAMETRIZATIONS=insert(PARAMETRIZATIONS,Frobenius(
+                                  PARAMETRIZATIONS[piv],1),counter);
+        counter=counter+1;
+        piv=counter;
+      }
+    }
+
+    // now the same thing for smaller base fields
+    string olda;
+    poly paux;
+    intvec iv,iw;
+    int ii,jj,kk,m,n;
+    for (i=d-1;i>=2;i=i-1)
+    {
+      if ( (d mod i)==0 )
+      {
+        if (typeof(CURVE[5][i])=="list")
+        {
+          def S(i)=CURVE[5][i][1];
+          // embedd S(i) inside basering == RatPl " ==S(d) "
+          olda=subfield(S(i));
+          setring S(i);
+          s=size(POINTS);
+          setring RatPl;
+          // import data from S(i)
+          for (j=s;j>=1;j=j-1)
+          {
+            counter=0;
+            POINTS=insert(POINTS,list(),0);
+            POINTS[1][1]=number(importdatum(S(i),"POINTS["+string(j)
+                                                          +"][1]",olda));
+            POINTS[1][2]=number(importdatum(S(i),"POINTS["+string(j)
+                                                          +"][2]",olda));
+            POINTS[1][3]=number(importdatum(S(i),"POINTS["+string(j)
+                                                          +"][3]",olda));
+            LOC_EQS=insert(LOC_EQS,importdatum(S(i),"LOC_EQS["+string(j)
+                                                          +"]",olda),0);
+            BRANCHES=insert(BRANCHES,list(),0);
+            setring S(i);
+            m=nrows(BRANCHES[j][1]);
+            n=ncols(BRANCHES[j][1]);
+            iv=BRANCHES[j][2];
+            kk=BRANCHES[j][3];
+            poly par at 1=subst(PARAMETRIZATIONS[j][1][1],t,x);
+            poly par at 2=subst(PARAMETRIZATIONS[j][1][2],t,x);
+            export(par at 1);
+            export(par at 2);
+            iw=PARAMETRIZATIONS[j][2];
+            setring RatPl;
+            paux=importdatum(S(i),"BRANCHES["+string(j)+"][4]",olda);
+            matrix Maux[m][n];
+            for (ii=1;ii<=m;ii=ii+1)
+            {
+              for (jj=1;jj<=n;jj=jj+1)
+              {
+                Maux[ii,jj]=importdatum(S(i),"BRANCHES["+string(j)
+                               +"][1]["+string(ii)+","+string(jj)+"]",olda);
+              }
+            }
+            BRANCHES[1][1]=Maux;
+            BRANCHES[1][2]=iv;
+            BRANCHES[1][3]=kk;
+            BRANCHES[1][4]=paux;
+            kill Maux;
+            PARAMETRIZATIONS=insert(PARAMETRIZATIONS,list(),0);
+            PARAMETRIZATIONS[1][1]=ideal(0);
+            PARAMETRIZATIONS[1][1][1]=importdatum(S(i),"par at 1",olda);
+            PARAMETRIZATIONS[1][1][2]=importdatum(S(i),"par at 2",olda);
+            PARAMETRIZATIONS[1][1][1]=subst(PARAMETRIZATIONS[1][1][1],x,t);
+            PARAMETRIZATIONS[1][1][2]=subst(PARAMETRIZATIONS[1][1][2],x,t);
+            PARAMETRIZATIONS[1][2]=iw;
+            for (k=1;k<i;k=k+1)
+            {
+              counter=counter+1;
+              piv=counter;
+              POINTS=insert(POINTS,Frobenius(POINTS[piv],1),counter);
+              LOC_EQS=insert(LOC_EQS,Frobenius(LOC_EQS[piv],1),counter);
+              BRANCHES=insert(BRANCHES,conj_b(BRANCHES[piv],1),counter);
+              PARAMETRIZATIONS=insert(PARAMETRIZATIONS,Frobenius(
+                                        PARAMETRIZATIONS[piv],1),counter);
+            }
+            setring S(i);
+            kill par at 1,par at 2;
+            setring RatPl;
+          }
+          kill S(i);
+        }
+      }
+    }
+    kill iw;
+    kill paux;
+
+    // finally add points from S(1)
+    if (typeof(CURVE[5][1])=="list")
+    {
+      def S(1)=CURVE[5][1][1];
+      POINTS=imap(S(1),POINTS)+POINTS;
+      LOC_EQS=imap(S(1),LOC_EQS)+LOC_EQS;
+      BRANCHES=imap(S(1),BRANCHES)+BRANCHES;
+      PARAMETRIZATIONS=imap(S(1),PARAMETRIZATIONS)+PARAMETRIZATIONS;
+    }
+
+    // prepare data for output
+    export(POINTS);
+    export(LOC_EQS);
+    export(BRANCHES);
+    export(PARAMETRIZATIONS);
+    int NrRatPl=size(POINTS);
+    ext_CURVE[2][3]=NrRatPl;
+    setring BR;
+    ext_CURVE[1][5]=RatPl;
+    ring r(d)=(char(basering),a),(x,y),lp;
+    execute("minpoly="+smin+";");
+    setring BR;
+    ext_CURVE[1][3]=r(d);
+    ring R(d)=(char(basering),a),(x,y,z),lp;
+    execute("minpoly="+smin+";");
+    setring BR;
+    ext_CURVE[1][4]=R(d);
+    dbprint(printlevel+1,"");
+    dbprint(printlevel+2,"Total number of rational places : NrRatPl = "
+                                   +string(NrRatPl));
+    dbprint(printlevel+1,"");
+    kill S(1);
+    kill R(d);
+    kill RatPl;
+    return(ext_CURVE);
+  }
+}
+example
+{
+  "EXAMPLE:";  echo = 2;
+  int plevel=printlevel;
+  printlevel=-1;
+  ring s=2,(x,y),lp;
+  list C=Adj_div(x5+y2+y);
+  C=NSplaces(1..4,C);
+  // since we have all points up to degree 4, we can extend the curve
+  // to that extension, in order to get rational points over F_16;
+  C=extcurve(4,C);
+  // e.g., display the basepoint of place no. 32:
+  def R=C[1][5];
+  setring R;
+  POINTS[32];
+  printlevel=plevel;
+}
+///////////////////////////////////////////////////////////////////////////////
+
+// specific procedures for linear/AG codes
+
+static proc Hamming_wt (matrix A)
+"USAGE:     Hamming_wt(A), where A is any matrix
+RETURN:     the Hamming weight (number of non-zero entries) of the matrix A
+"
+{
+  // computes the Hamming weight (number of non-zero entries) of any matrix
+  // notice that "words" are represented by matrices of size 1xn
+  // computing the Hamming distance between two matrices can be done by
+  // Hamming_wt(A-B)
+  int m=nrows(A);
+  int n=ncols(A);
+  int i,j;
+  int w=0;
+  for (i=1;i<=m;i=i+1)
+  {
+    for (j=1;j<=n;j=j+1)
+    {
+      if (A[i,j]<>0)
+      {
+        w=w+1;
+      }
+    }
+  }
+  return(w);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+// Basic Algorithm of Skorobogatov and Vladut for decoding AG codes
+// warning : the user must choose carefully the parameters for the code and
+//     the decoding since they will never be checked by the procedures
+
+proc prepSV (intvec G,intvec D,intvec F,list EC)
+"USAGE:    prepSV( G, D, F, EC ); G,D,F intvecs and EC a list
+RETURN:   list E of size n+3, where n=size(D). All its entries but E[n+3]
+          are matrices:
+   @format
+   E[1]:  parity check matrix for the current AG code
+   E[2] ... E[n+2]:  matrices used in the procedure decodeSV
+   E[n+3]:  intvec with
+       E[n+3][1]: correction capacity @math{epsilon} of the algorithm
+       E[n+3][2]: designed Goppa distance @math{delta} of the current AG code
+   @end format
+NOTE:     Computes the preprocessing for the basic (Skorobogatov-Vladut)
+          decoding algorithm.@*
+          The procedure must be called within the ring EC[1][4], where EC is
+          the output of @code{extcurve(d)} (or in the ring EC[1][2] if d=1) @*
+          The intvec G and F represent rational divisors (see
+          @ref{BrillNoether} for more details).@*
+          The intvec D refers to rational places (see @ref{AGcode_Omega}
+          for more details.).
+          The current AG code is @code{AGcode_Omega(G,D,EC)}.@*
+          If you know the exact minimum distance d and you want to use it in
+          @code{decodeSV} instead of @math{delta}, you can change the value
+          of E[n+3][2] to d before applying decodeSV.
+          If you have a systematic encoding for the current code and want to
+          keep it during the decoding, you must previously permute D (using
+          @code{permute_L(D,P);}), e.g., according to the permutation
+          P=L[3], L being the output of @code{sys_code}.
+WARNINGS: F must be a divisor with support disjoint from the support of D and
+          with degree @math{epsilon + genus}, where
+          @math{epsilon:=[(deg(G)-3*genus+1)/2]}.@*
+          G should satisfy @math{ 2*genus-2 < deg(G) < size(D) }, which is
+          not checked by the algorithm.
+          G and D should also have disjoint supports (checked by the
+          algorithm).
+KEYWORDS: SV-decoding algorithm, preprocessing
+SEE ALSO: extcurve, AGcode_Omega, decodeSV, sys_code, permute_L
+EXAMPLE:  example prepSV; shows an example
+"
+{
+  if (disj_divs(F,D,EC)==0)
+  {
+    dbprint(printlevel+3,"? the divisors do not have disjoint supports,
+                            empty list returned ?");
+    return(list());
+  }
+  list E=list();
+  list Places=EC[3];
+  int m=deg_D(G,Places);
+  int genusX=EC[2][2];
+  int e=(m+1-3*genusX) div 2;
+  if (e<1)
+  {
+    dbprint(printlevel+3,"? the correction capacity of the basic algorithm
+                            is zero, empty list returned ?");
+    return(list());
+  }
+  // deg(F)==e+genusX should be satisfied, and sup(D),sup(F) should be
+  // disjoint !!!!
+  int n=size(D);
+  // 2*genusX-2<m<n should also be satisfied !!!!
+  matrix EE=AGcode_L(G,D,EC);
+  int l=nrows(EE);
+  E[1]=EE;
+  matrix GP=AGcode_L(F,D,EC);
+  int r=nrows(GP);
+  intvec H=G-F;
+  matrix HP=AGcode_L(H,D,EC);
+  int s=nrows(HP);
+  int i,j,k;
+  kill EE;
+  for (k=1;k<=n;k=k+1)
+  {
+    E[k+1]=GP[1,k]*submat(HP,1..s,k..k);
+    for (i=2;i<=r;i=i+1)
+    {
+      E[k+1]=concat(E[k+1],GP[i,k]*submat(HP,1..s,k..k));
+    }
+  }
+  E[n+2]=GP;
+  intvec IW=e,m+2-2*genusX;
+  E[n+3]=IW;
+  kill IW;
+  return(E);
+}
+example
+{
+  "EXAMPLE:";  echo = 2;
+  int plevel=printlevel;
+  printlevel=-1;
+  ring s=2,(x,y),lp;
+  list HC=Adj_div(x3+y2+y);
+  HC=NSplaces(1..2,HC);
+  HC=extcurve(2,HC);
+  def ER=HC[1][4];
+  setring ER;
+  intvec G=5;      // the rational divisor G = 5*HC[3][1]
+  intvec D=2..9;   // D = sum of the rational places no. 2..9 over F_4
+  // construct the corresp. residual AG code of type [8,3,>=5] over F_4:
+  matrix C=AGcode_Omega(G,D,HC);
+  // we can correct 1 error and the genus is 1, thus F must have degree 2
+  // and support disjoint from that of D;
+  intvec F=2;
+  list SV=prepSV(G,D,F,HC);
+  // now everything is prepared to decode with the basic algorithm;
+  // for example, here is a parity check matrix to compute the syndrome :
+  print(SV[1]);
+  // and here you have the correction capacity of the algorithm :
+  int epsilon=SV[size(D)+3][1];
+  epsilon;
+  printlevel=plevel;
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc decodeSV (matrix y,list K)
+"USAGE:     decodeSV( y, K ); y a row-matrix and K a list
+RETURN:     a codeword (row-matrix) if possible, resp. the 0-matrix (of size
+            1) if decoding is impossible.
+            For decoding the basic (Skorobogatov-Vladut) decoding algorithm
+            is applied.
+NOTE:       The list_expression should be the output K of the procedure
+            @code{prepSV}.@*
+            The matrix_expression should be a (1 x n)-matrix,  where
+            n = ncols(K[1]).@*
+            The decoding may fail if the number of errors is greater than
+            the correction capacity of the algorithm.
+KEYWORDS:   SV-decoding algorithm
+SEE ALSO:   extcurve, AGcode_Omega, prepSV
+EXAMPLE:    example decodeSV; shows an example
+"
+{
+  // decodes y with the "basic decoding algorithm", if possible
+  // requires the preprocessing done by the procedure "prepSV"
+  // the procedure must be called from ring R or R(d)
+  // returns either a codeword (matrix) of none (in case of too many errors)
+  matrix syndr=K[1]*transpose(y);
+  if (Hamming_wt(syndr)==0)
+  {
+    return(y);
+  }
+  matrix Ey=y[1,1]*K[2];
+  int n=ncols(y);
+  int i;
+  for (i=2;i<=n;i=i+1)
+  {
+    Ey=Ey+y[1,i]*K[i+1];
+  }
+  matrix Ky=get_NZsol(Ey);
+  if (Hamming_wt(Ky)==0)
+  {
+    dbprint(printlevel+3,"? no error-locator found ?");
+    dbprint(printlevel+3,"? too many errors occur, 0-matrix returned ?");
+    matrix answer;
+    return(answer);
+  }
+  int r=nrows(K[n+2]);
+  matrix ErrLoc[1][n];
+  list Z=list();
+  list NZ=list();
+  int j;
+  for (j=1;j<=n;j=j+1)
+  {
+    for (i=1;i<=r;i=i+1)
+    {
+      ErrLoc[1,j]=ErrLoc[1,j]+K[n+2][i,j]*Ky[1,i];
+    }
+    if (ErrLoc[1,j]==0)
+    {
+      Z=insert(Z,j,size(Z));
+    }
+    else
+    {
+      NZ=insert(NZ,j,size(NZ));
+    }
+  }
+  int k=size(NZ);
+  int l=nrows(K[1]);
+  int s=l+k;
+  matrix A[s][n];
+  matrix b[s][1];
+  for (i=1;i<=l;i=i+1)
+  {
+    for (j=1;j<=n;j=j+1)
+    {
+      A[i,j]=K[1][i,j];
+    }
+    b[i,1]=syndr[i,1];
+  }
+  for (i=1;i<=k;i=i+1)
+  {
+    A[l+i,NZ[i]]=number(1);
+  }
+  intvec opgt=option(get);
+  option(redSB);
+  matrix L=transpose(syz(concat(A,-b)));
+  if (nrows(L)==1)
+  {
+    if (L[1,n+1]<>0)
+    {
+      poly pivote=L[1,n+1];
+      matrix sol=submat(L,1..1,1..n);
+      if (pivote<>1)
+      {
+        sol=(number(1)/number(pivote))*sol;
+      }
+      // check at least that the number of comitted errors is less than half
+      //     the Goppa distance
+      // imposing Hamming_wt(sol)<=K[n+3][1] would be more correct, but maybe
+      //     is too strong
+      // on the other hand, if Hamming_wt(sol) is too large the decoding may
+      //     not be acceptable
+      if ( Hamming_wt(sol) <= (K[n+3][2]-1) div 2 )
+      {
+        option(set,opgt);
+        return(y-sol);
+      }
+      else
+      {
+        dbprint(printlevel+3,"? non-acceptable decoding ?");
+      }
+    }
+    else
+    {
+      dbprint(printlevel+3,"? no solution found ?");
+    }
+  }
+  else
+  {
+    dbprint(printlevel+3,"? non-unique solution ?");
+  }
+  option(set,opgt);
+  dbprint(printlevel+3,"? too many errors occur, 0-matrix returned ?");
+  matrix answer;
+  return(answer);
+}
+example
+{
+  "EXAMPLE:";  echo = 2;
+  int plevel=printlevel;
+  printlevel=-1;
+  ring s=2,(x,y),lp;
+  list HC=Adj_div(x3+y2+y);
+  HC=NSplaces(1..2,HC);
+  HC=extcurve(2,HC);
+  def ER=HC[1][4];
+  setring ER;
+  intvec G=5;      // the rational divisor G = 5*HC[3][1]
+  intvec D=2..9;   // D = sum of the rational places no. 2..9 over F_4
+  // construct the corresp. residual AG code of type [8,3,>=5] over F_4:
+  matrix C=AGcode_Omega(G,D,HC);
+  // we can correct 1 error and the genus is 1, thus F must have degree 2
+  // and support disjoint from that of D
+  intvec F=2;
+  list SV=prepSV(G,D,F,HC);
+  // now we produce 1 error on the zero-codeword :
+  matrix y[1][8];
+  y[1,3]=a;
+  // and then we decode :
+  print(decodeSV(y,SV));
+  printlevel=plevel;
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc sys_code (matrix C)
+"USAGE:    sys_code(C); C is a matrix of constants
+RETURN:   list L with:
+   @format
+   L[1] is the generator matrix in standard form of an equivalent code,
+   L[2] is the parity check matrix in standard form of such code,
+   L[3] is an intvec which represents the needed permutation.
+   @end format
+NOTE:     Computes a systematic code which is equivalent to the given one.@*
+          The input should be a matrix of numbers.@*
+          The output has to be interpreted as follows: if the input was
+          the generator matrix of an AG code then one should apply the
+          permutation L[3] to the divisor D of rational points by means
+          of @code{permute_L(D,L[3]);} before continuing to work with the
+          code (for instance, if you want to use the systematic encoding
+          together with a decoding algorithm).
+KEYWORDS: linear code, systematic
+SEE ALSO: permute_L, AGcode_Omega, prepSV
+EXAMPLE:  example sys_code; shows an example
+"
+{
+  // computes a systematic code which is equivalent to that given by C
+  int i,j,k,l,h,r;
+  int m=nrows(C);
+  int n=ncols(C);
+  int mr=m;
+  matrix A[m][n]=C;
+  poly c,p;
+  list corners=list();
+  if(m>n)
+  {
+    mr=n;
+  }
+  // first the matrix A will be reduced with elementary operations by rows
+  for(i=1;i<=mr;i=i+1)
+  {
+    if((i+l)>n)
+    {
+      // the process is finished
+      break;
+    }
+    // look for a non-zero element
+    if(A[i,i+l]==0)
+    {
+      h=i;
+      p=0;
+      for (j=i+1;j<=m;j=j+1)
+      {
+        c=A[j,i+l];
+        if (c!=0)
+        {
+          p=c;
+          h=j;
+          break;
+        }
+      }
+      if (h!=i)
+      {
+        // permutation of rows i and h
+        for (j=1;j<=n;j=j+1)
+        {
+          c=A[i,j];
+          A[i,j]=A[h,j];
+          A[h,j]=c;
+        }
+      }
+      if(p==0)
+      {
+        // non-zero element not found in the current column
+        l=l+1;
+        continue;
+      }
+    }
+    // non-zero element was found in "strategic" position
+    corners[i]=i+l;
+    // make zeros below that position
+    for(j=i+1;j<=m;j=j+1)
+    {
+      c=A[j,i+l]/A[i,i+l];
+      for(k=i+l+1;k<=n;k=k+1)
+      {
+        A[j,k]=A[j,k]-A[i,k]*c;
+      }
+      A[j,i+l]=0;
+      A[j,i]=0;
+    }
+    // the rank is at least r
+    // when the process stops the last r is actually the true rank of A=a
+    r=i;
+  }
+  if (r<m)
+  {
+    ERROR("the given matrix does not have maximum rank");
+  }
+  // set the corners to the beginning and construct the permutation
+  intvec PCols=1..n;
+  for (j=1;j<=m;j=j+1)
+  {
+    if (corners[j]>j)
+    {
+      // interchange columns j and corners[j]
+      for (i=1;i<=m;i=i+1)
+      {
+        c=A[i,j];
+        A[i,j]=A[i,corners[j]];
+        A[i,corners[j]]=c;
+      }
+      k=PCols[j];
+      PCols[j]=PCols[corners[j]];
+      PCols[corners[j]]=k;
+    }
+  }
+  // convert the diagonal into ones
+  for (i=1;i<=m;i=i+1)
+  {
+    for (j=i+1;j<=n;j=j+1)
+    {
+      A[i,j]=A[i,j]/A[i,i];
+    }
+    A[i,i]=1;
+  }
+  // complete a block with the identity matrix
+  for (k=1;k<m;k=k+1)
+  {
+    for (i=k+1;i<=m;i=i+1)
+    {
+      for (j=i+1;j<=n;j=j+1)
+      {
+        A[k,j]=A[k,j]-A[i,j]*A[k,i];
+      }
+      A[k,i]=0;
+    }
+  }
+  // compute a parity-check matrix in standard form
+  matrix B=concat(-transpose(submat(A,1..m,m+1..n)),diag(1,n-m));
+  list L=list();
+  L[1]=A;
+  L[2]=B;
+  L[3]=PCols;
+  return(L);
+}
+example
+{
+  "EXAMPLE:";  echo = 2;
+  ring s=3,T,lp;
+  matrix C[2][5]=0,1,0,1,1,0,1,0,0,1;
+  print(C);
+  list L=sys_code(C);
+  L[3];
+  // here is the generator matrix in standard form
+  print(L[1]);
+  // here is the control matrix in standard form
+  print(L[2]);
+  // we can check that both codes are dual to each other
+  print(L[1]*transpose(L[2]));
+}
+
+////////////// this procedure should be moved to hnoether.lib /////////
+static proc ratdevelop (poly chi)
+{
+  int ring_is_changed;
+  int k1=res_deg();
+  list L=hnexpansion(chi,"ess");
+  if (typeof(L[1])=="ring") {
+    def altring=basering;
+    def HNring = L[1]; setring HNring;
+    def HND = hne;
+    kill hne;
+    ring_is_changed=1;
+  }
+  else {
+    def HND=L[1];
+  }
+  int k2=res_deg();
+  if (k1<k2)
+  {
+    int N=size(HND);
+    list CB=list();
+    int i,j,k,d;
+    intvec dgs;
+    list auxL=list();
+    intvec auxiv;
+    for (i=1;i<=N;i++)
+    {
+      CB[i]=conj_bs(HND[i],k1);
+      dgs[i]=size(CB[i]);
+    }
+    for (i=1;i<N;i++)
+    {
+      for (j=i+1;j<=N;j++)
+      {
+        if (dgs[i]==dgs[j])
+        {
+          d=dgs[i];
+          for (k=1;k<=d;k++)
+          {
+            if (intersection(CB[i][1],CB[j][k])==-1)
+            {
+              HND=delete(HND,j);
+              CB=delete(CB,j);
+//              dgs=delete(dgs,j);
+              execute("auxL="+string(dgs)+";");
+              auxL=delete(auxL,j);
+              execute("dgs="+string(auxL)+";");
+              N=N-1;
+              j=j-1;
+              break;
+            }
+          }
+        }
+      }
+    }
+  }
+  if (ring_is_changed==0) { return(HND); }
+  else { export HND; setring altring; return(HNring); }
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+
+/*
+// ============================================================================
+// *******       ADDITIONAL INFORMATION ABOUT THE LIBRARY              ********
+// ============================================================================
+
+A SINGULAR library for plane curves, Weierstrass semigroups and AG codes
+Also available via http://wmatem.eis.uva.es/~ignfar/singular/
+
+PREVIOUS WARNINGS :
+
+   (1) The procedures will work only in positive characteristic
+   (2) The base field must be prime (this may change in the future)
+           This limitation is not too serious, since in coding theory
+           the used curves are usually (if not always) defined over a
+           prime field, and extensions are only considered for
+           evaluating functions in a field with many points;
+           by the same reason, auxiliary divisors are usually defined
+           over the prime field,
+           with the exception of that consisting of "rational points"
+   (3) The curve must be absolutely irreducible (but it is not checked)
+   (4) Only (algebraic projective) plane curves are considered
+
+GENERAL CONCEPTS :
+
+   (1) An affine point P is represented by a std of a prime ideal,
+       and an intvec containing the position of the places above P
+       in the list of Places; if the point is at infinity, the ideal is
+       changed by a homogeneous irreducible polynomial in two variables
+   (2) A place is represented by :
+       a base point (list of homogeneous coordinates),
+       a local equation for the curve at the base point,
+       a Hamburger-Noether expansion of the corresponding branch,
+       and a local parametrization (in "t") of such branch; everything is
+       stored in a local ring "_[5][d][1]", d being the degree of the place,
+       by means of lists "POINTS,LOC_EQS,BRANCHES,PARAMETRIZATIONS", and
+       the degrees of the base points corresponding to the places in the
+       ring "_[5][d][1]" are stored in an intvec "_[5][d][2]"
+   (3) A divisor is represented by an intvec, where the integer at the
+       position i means the coefficient of the i-th place in the divisor
+   (4) Rational functions are represented by numerator/denominator
+       in form of ideals with two homogeneous generators
+
+OUTLINE/EXAMPLE OF THE USE OF THE LIBRARY :
+
+Plane curves :
+
+      (1.0) ring s=p,(x,y[,z]),lp;
+
+            Notice that if you use 3 variables, then the equation
+            of the curve is assumed to be a homogeneous polynomial.
+
+      (1.1) list CURVE=Adj_div(equation);
+
+            In CURVE[3] are listed all the (singular closed) places
+            with their corresponding degrees; thus, you can now decide
+            how many other points you want to compute with NSplaces.
+
+      (1.2) CURVE=NSplaces(degrees,CURVE);
+
+            "degrees" is an intvec with the degrees we want to compute
+
+      (1.3) CURVE=extcurve(extension,CURVE);
+
+            The rational places over the extension are ranged in
+            the ring CURVE[1][5] with the following rules:
+
+                (i)    all the representatives of the same closed point
+                       are listed in consecutive positions;
+                (ii)   if deg(P)<deg(Q), then the representatives of P
+                       are listed before those of Q;
+                (iii)  if two closed points P,Q have the same degree,
+                       then the representatives of P are listed before
+                       if P appears before in the list CURVE[3].
+
+Rational functions :
+
+      (2.0) def R=CURVE[1][2];
+            setring R;
+      (2.1) list LG=BrillNoether(intvec divisor,CURVE);
+      (2.2) list WS=Weierstrass(int place,int bound,CURVE);
+
+Algebraic Geometry codes :
+
+      (3.0) def ER=CURVE[1][4];    // if extension>1; else use R instead
+            setring ER;
+
+            Now you have to decide the divisor G and the sequence of
+            rational points D to use for constructing the codes;
+            first notice that the syntax for G and D is different:
+
+                (a) G is a divisor supported on the closed places of
+                    CURVE[3], and you must say just the coefficient
+                    of each such a point; for example, G=2,0,-1 means
+                    2 times the place 1 minus 1 times the place 3.
+
+                (b) D is a sequence of rational points (all different
+                    and counted 1 time each one), whose data are read
+                    from the lists inside CURVE[1][5] and now you must
+                    say just the order how you range the chosen point;
+                    for example, D=2,4,1 means that you choose the
+                    rational places 1,2,4 and you range them as 2,4,1.
+
+      (3.1) matrix C=AGcode_L(divisor,places,CURVE);
+
+      (3.2) AGcode_Omega(divisor,places,CURVE);
+
+            In the same way as for defining the codes, the auxiliary
+            divisor F must have disjoint support to that of D, and
+            its degree has to be given by a formula (see help prepSV).
+
+      (3.3) list SV=prepSV(divisor,places,auxiliary_divisor,CURVE);
+
+      (3.4) decodeSV(word,SV);
+
+Special Issues :
+
+      (I)  AG codes with systematic encoding :
+
+              matrix C=AGcode_Omega(G,D,CURVE);
+              list CODE=sys_code(G);
+              C=CODE[1];               // generator matrix in standard form
+              D=permute_L(D,CODE[3]);  // suitable permutation of coordinates
+              list SV=prepSV(G,D,F,CURVE);
+              SV[1]=CODE[2];           // parity-check matrix in standard form
+
+      (II) Using the true minimum distance d for decoding :
+
+              matrix C=AGcode_Omega(G,D,CURVE);
+              int n=size(D);
+              list SV=prepSV(G,D,F,CURVE);
+              SV[n+3][2]=d;            // then use decodeSV(y,SV);
+
+
+// ============================================================================
+// ***   Some "macros" with typical examples of curves in Coding Theory    ****
+// ============================================================================
+
+
+proc Klein ()
+{
+  list KLEIN=Adj_div(x3y+y3+x);
+  KLEIN=NSplaces(1..3,KLEIN);
+  KLEIN=extcurve(3,KLEIN);
+  dbprint(printlevel+1,"Klein quartic over F_8 successfully constructed");
+  return(KLEIN);
+}
+
+proc Hermite (int m)
+{
+  int p=char(basering);
+  int r=p^m;
+  list HERMITE=Adj_div(y^r+y-x^(r+1));
+  HERMITE=NSplaces(1..2*m,HERMITE);
+  HERMITE=extcurve(2*m,HERMITE);
+  dbprint(printlevel+1,"Hermitian curve over F_("+string(r)+"^2)
+                          successfully constructed");
+  return(HERMITE);
+}
+
+proc Suzuki ()
+{
+  list SUZUKI=Adj_div(x10+x3+y8+y);
+  SUZUKI=NSplaces(1..3,SUZUKI);
+  SUZUKI=extcurve(3,SUZUKI);
+  dbprint(printlevel+1,"Suzuki curve over F_8 successfully constructed");
+  return(SUZUKI);
+}
+
+// **** Other interesting examples :
+
+// A hyperelliptic curve with 33 rational points over F_16
+
+list CURVE=Adj_div(x5+y2+y);
+CURVE=NSplaces(1..4,CURVE);
+CURVE=extcurve(4,CURVE);
+
+// A nice curve with 113 rational points over F_64
+
+list CURVE=Adj_div(y9+y8+xy6+x2y3+y2+x3);
+intvec ww=1,2,3,6;
+CURVE=NSplaces(ww,CURVE);
+CURVE=extcurve(6,CURVE);
+
+*/
diff --git a/Singular/LIB/central.lib b/Singular/LIB/central.lib
new file mode 100644
index 0000000..3b7da18
--- /dev/null
+++ b/Singular/LIB/central.lib
@@ -0,0 +1,2169 @@
+//////////////////////////////////////////////////////////////////////////////
+version="version central.lib 4.0.0.0 Jun_2013 "; // $Id: 02406432764d31ead77ae891aeb5ea152ccd3e1a $
+category="Noncommutative";
+info="
+LIBRARY:  central.lib      Computation of central elements of GR-algebras
+
+AUTHOR:  Oleksandr Motsak,    U at D, where U={motsak}, D={mathematik.uni-kl.de}
+
+OVERVIEW: A library for computing elements of the center and centralizers of sets of elements in GR-algebras.
+
+KEYWORDS:  center; centralizer; reduce; centralize; PBW
+
+PROCEDURES:
+  centralizeSet(F, V)          v.s. basis of the centralizer of F within V
+  centralizerVS(F, D)          v.s. basis of the centralizer of F
+  centralizerRed(F, D[, N])    reduced basis of the centralizer of F
+  centerVS(D)                  v.s. basis of the center
+  centerRed(D[, k])            reduced basis of the center
+  center(D[, k])               reduced basis of the center
+  centralizer(F, D[, k])       reduced bais of the centralizer of F
+  sa_reduce(V)              's.a. reduction' of pairwise commuting elements
+  sa_poly_reduce(p, V)      's.a. reduction' of p by pairwise commuting elements
+  inCenter(T)                  checks the centrality of list/ideal/poly T
+  inCentralizer(T, S)          checks whether list/ideal/poly T commute with S
+  isCartan(p)                  checks whether polynomial p is a Cartan element
+  applyAdF(Basis, f)           images of elements under the k-linear map Ad_f
+  linearMapKernel(Images)      kernel of a linear map given by images
+  linearCombinations(Basis, C)  k-linear combinations of elements
+  variablesStandard()          set of algebra generators in their natural order
+  variablesSorted()            heuristically sorted set of algebra generators
+  PBW_eqDeg(Deg)               PBW monomials of given degree
+  PBW_maxDeg(MaxDeg)           PBW monomials up to given degree
+  PBW_maxMonom(MaxMonom)       PBW monomials up to given maximal monomial
+";
+
+LIB "general.lib" // for "sort"
+LIB "poly.lib" // for "maxdeg"
+
+
+/******************************************************/
+// ::DefaultStuff:: Shortcuts to useful short functions. Just to avoid if( if( if( ... ))).
+/******************************************************/
+
+
+/******************************************************/
+static proc DefaultValue ( def s, list # ) // Process general variable parameters list
+  "
+RETURN: s or (typeof(s))(#)
+"
+{
+  def @p = s;
+  if ( size(#) > 0 )
+  {
+    if ( typeof(#[1]) == typeof(s) )
+      {
+        @p = #[1];
+      }
+  }
+  return( @p );
+}
+
+/******************************************************/
+static proc DefaultInt( list # ) // Process variable parameters list with 'int' default value
+  "
+RETURN: 0 or int(#)
+"
+{
+  int @p = 0;
+  return( DefaultValue( @p, # ) );
+}
+
+/******************************************************/
+static proc DefaultIdeal ( list # ) // Process variable parameters list with 'ideal' default value
+  "
+RETURN: 0 or ideal(#)
+"
+{
+  ideal @p = 0;
+  return( DefaultValue( @p, # ) );
+}
+
+
+
+/******************************************************/
+// ::Debug:: Shortcuts to used debugging functions.
+/******************************************************/
+
+
+/******************************************************/
+static proc toprint( int pl ) // To print or not to print?!? The answer is here!
+  "
+RETURN: 1 means to print, otherwise 0.
+"
+{
+  return( printlevel >= ( 3 -  pl) ); // voice + ?
+}
+
+/******************************************************/
+static proc DBPrint( int pl, list # ) // My 'dbprint' which uses toprint(i).
+  "
+    USAGE:
+"
+{
+  if( toprint(pl) )
+    {
+      dbprint(1, #);
+    }
+}
+
+/******************************************************/
+static proc BCall( string Name, list # ) // This function must be called at the beginning of every 'mathematical' function.
+  "
+USAGE: Name is a name of a mathematical function to trace. # means parameters into the function.
+"
+{
+  if( toprint(0) )
+    {
+      "CALL: ", Name, "( ";
+      dbprint(1, #);
+      "     )";
+    }
+}
+
+/******************************************************/
+static proc ECall(string Name, list #) // This function must be called at the end of every 'mathematical' function.
+  "
+USAGE: Name is a name of a mathematical function to trace. # means result of the function.
+"
+{
+  if( toprint(0) )
+    {
+      "RET : ", Name, " => Result: {";
+      dbprint(1, #);
+      "    }";
+    }
+}
+
+
+
+/******************************************************/
+// ::Helpers:: Small functions used in this library.
+/******************************************************/
+
+/******************************************************/
+static proc makeNice( def l )
+  "
+RETURN: the same as input
+PURPOSE: make 'nice' polynomials, kill scalars
+"
+{
+  /*4DEBUG*/    if( defined( @@@DEBUG ) ){ BCall( "makeNice", l ); } /*4DEBUG*/
+
+  poly p;
+
+  if( typeof(l) == "poly" )
+    {
+      // "normal" polynomial form == no denominators, gcd of coeffs is a unit
+      l = cleardenom( l );
+      if ( maxdegInt(l) > 0 )
+        {
+          l = cleardenom( l / leadcoef(l) );
+        }
+    } else
+      {
+        if( typeof(l) == "ideal" )
+          {
+            for( int i = 1; i <= size(l); i++ )
+              {
+                p = l[i];
+                   p = cleardenom( p );
+
+                // Now make polynomials look nice:
+                if ( maxdegInt(p) > 0 ) // throw away scalars!
+                  {
+                        // "normal" polynomial form == no denominators, gcd of coeffs is a unit
+                        p = cleardenom( p / leadcoef(p) );
+                  } else
+                    {
+                      p = 0; // no constants
+                    }
+                l[i] = p;
+
+              }
+
+            l = simplify(l, 2 + 8);
+          }
+      }
+
+  /*4DEBUG*/    if( defined( @@@DEBUG ) ){ ECall( "makeNice", l ); } /*4DEBUG*/
+  return( l );
+}
+
+
+
+/******************************************************/
+static proc monomialForm( def p )
+  "
+: p is either poly or ideal
+RETURN: polynomial with all monomials from p but without coefficients.
+"
+{
+  /*4DEBUG*/    if( defined( @@@DEBUG ) ){ BCall( "monomialForm", p ); } /*4DEBUG*/
+
+  poly result = 0; int k, j; poly m;
+
+  if( typeof(p) == "ideal" ) //
+    {
+      if( ncols(p) > 0 )
+        {
+          result = uni_poly( p[1] );
+
+          for ( k = ncols(p); k > 1; k -- )
+            {
+              for( j = size(p[k]); j > 0; j-- )
+                {
+                  m = leadmonom( p[k][j] );
+
+                  if( size(result + m) > size(result) ) // trick!
+                    {
+                      result = result + m;
+                    }
+                }
+
+            }
+        }
+    }
+  else
+    {
+      if( typeof(p) == "poly" ) //
+        {
+          result = uni_poly(p);
+        } else
+          {
+            ERROR( "ERROR: Wrong input! Expected polynomial or ideal!" );
+          }
+    }
+
+  /*4DEBUG*/    if( defined( @@@DEBUG ) ){ ECall( "monomialForm", result ); } /*4DEBUG*/
+  return( result );
+}
+
+/******************************************************/
+static proc uni_poly( poly p )
+  "
+    returns polynomial with the same monomials but without coefficients.
+"
+{
+  /*4DEBUG*/    if( defined( @@@DEBUG ) ){ BCall( "uni_poly", p ); } /*4DEBUG*/
+
+  poly result = 0;
+
+  for ( int k = size(p); k > 0; k -- )
+    {
+      result = result + leadmonom( p[k] );
+    }
+
+  /*4DEBUG*/    if( defined( @@@DEBUG ) ){ ECall( "uni_poly", result ); } /*4DEBUG*/
+  return( result );
+}
+
+
+
+
+
+/******************************************************/
+static proc smoothQideal( ideal I, list #)
+  "
+PURPOSE: smooths the ideal in a current QUOTIENT(!) ring.
+"
+{
+  /*4DEBUG*/    if( defined( @@@DEBUG ) ){ BCall( "smoothQideal", I ); } /*4DEBUG*/
+
+  ideal A = matrix(I) - matrix(NF( I, twostd(DefaultIdeal(#)), 1 )); // component wise
+
+  if( size(A) > 0 ) // Were there any changes (any non-zero component)?
+    {
+      ideal T;
+
+      int j = 1;
+
+      for( int i = 1; i <= ncols(I); i++ )
+        {
+          if( size(A[i]) == 0 ) // keep only unchanged elements
+            {
+              T[ j ] = I[i]; j++;
+            }
+        }
+      I = T;
+    }
+
+  /*4DEBUG*/    if( defined( @@@DEBUG ) ){ ECall( "smoothQideal", I ); } /*4DEBUG*/
+
+  return( I );
+}
+
+
+
+
+/******************************************************/
+// ::PBW:: PBW basis construction.
+/******************************************************/
+
+
+
+
+/******************************************************/
+proc PBW_maxDeg( int MaxDeg )
+"
+USAGE: PBW_maxDeg(MaxDeg); MaxDeg int
+PURPOSE: Compute PBW elements up to a given maximal degree.
+RETURN: ideal consisting of found elements.
+NOTE: unit is omitted. Weights are ignored!
+"
+{
+  /*4DEBUG*/    if( defined( @@@DEBUG ) ){ BCall( "PBW_maxDeg", MaxDeg ); } /*4DEBUG*/
+
+  ideal Basis = 0;
+
+  for (int k = 1; k <= MaxDeg; k ++ )
+    {
+      Basis = Basis + maxideal(k);
+    }
+
+  Basis = smoothQideal( Basis );
+
+  /*4DEBUG*/    if( defined( @@@DEBUG ) ){ ECall( "PBW_maxDeg", Basis ); } /*4DEBUG*/
+  return( Basis );
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring AA = 0,(e,f,h),dp;
+  matrix D[3][3]=0;
+  D[1,2]=-h;  D[1,3]=2*e;  D[2,3]=-2*f;
+  def A = nc_algebra(1,D); // this algebra is U(sl_2)
+  setring A;
+
+  // PBW Basis of A_2 - monomials of degree <= 2, without unit:
+  PBW_maxDeg( 2 );
+}
+
+
+/******************************************************/
+proc PBW_eqDeg( int Deg )
+"
+USAGE: PBW_eqDeg(Deg); Deg int
+PURPOSE: Compute PBW elements of a given degree.
+RETURN: ideal consisting of found elements.
+NOTE: Unit is omitted. Weights are ignored!
+"
+{
+  /*4DEBUG*/    if( defined( @@@DEBUG ) ){ BCall( "PBW_eqDeg", Deg ); } /*4DEBUG*/
+
+  ideal Basis = smoothQideal( maxideal( Deg ) );
+
+  /*4DEBUG*/    if( defined( @@@DEBUG ) ){ ECall( "PBW_eqDeg", Basis ); } /*4DEBUG*/
+  return( Basis );
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring AA = 0,(e,f,h),dp;
+  matrix D[3][3]=0;
+  D[1,2]=-h;  D[1,3]=2*e;  D[2,3]=-2*f;
+  def A = nc_algebra(1,D); setring A; // this algebra is U(sl_2)
+
+  // PBW Basis of A_2 \ A_1 - monomials of degree == 2:
+  PBW_eqDeg( 2 );
+}
+
+
+/******************************************************/
+proc PBW_maxMonom( poly MaxMonom )
+"
+USAGE: PBW_maxMonom(m); m poly
+PURPOSE: Compute PBW elements up to a given maximal one.
+RETURN: ideal consisting of found elements.
+NOTE: Unit is omitted. Weights are ignored!
+"
+{
+  /*4DEBUG*/    if( defined( @@@DEBUG ) ){ BCall( "PBW_maxMonom", MaxMonom ); } /*4DEBUG*/
+
+  ideal K = 0;
+
+  intvec exp = leadexp( MaxMonom );
+
+  for ( int k = 1; k <= size(exp); k ++ )
+    {
+      K[ 1 + size(K) ] = var(k)^( 1 + exp[k] );
+    }
+
+  attrib(K, "isSB", 1);
+
+  K = kbase(K);
+
+  K = K[ (ncols(K)-1)..1]; // reverse, kill last 1
+
+  K = smoothQideal( K );
+
+  /*4DEBUG*/    if( defined( @@@DEBUG ) ){ ECall( "PBW_maxMonom", K ); } /*4DEBUG*/
+
+  return( K );
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring AA = 0,(e,f,h),dp;
+  matrix D[3][3]=0;
+  D[1,2]=-h;  D[1,3]=2*e;  D[2,3]=-2*f;
+  def A = nc_algebra(1,D); // this algebra is U(sl_2)
+  setring A;
+
+  // At most 1st degree in e, h and at most 2nd degree in f, unit is omitted:
+  PBW_maxMonom( e*(f^2)* h );
+}
+
+
+
+
+/******************************************************/
+// ::CORE:: Core procedures...
+/******************************************************/
+
+
+
+/******************************************************/
+proc applyAdF( ideal I, poly p )
+  "
+USAGE: applyAdF(B, f); B ideal, f poly
+PURPOSE: Apply Ad_f to every element of B
+RETURN: ideal, generated by Ad_f(B[i]), 1<=i<=size(B)
+NOTE:  Ad_f(v) := [f, v] = f*v - v*f
+SEE ALSO:   linearMapKernel; linearMapKernel
+"
+{
+  /*4DEBUG*/    if( defined( @@@DEBUG ) ){ BCall( "applyAdF", I, p ); } /*4DEBUG*/
+
+  poly t; ideal II = 0;
+
+  for ( int k = ncols(I); k > 0; k --)
+    {
+      t = I[k];
+      II[k] = p * t - t * p; // we have to reduce smooth images in Qrings...
+    }
+
+  II = NF( II, twostd(0) ); // ... now!
+
+  /*4DEBUG*/    if( defined( @@@DEBUG ) ){ ECall( "applyAdF", II ); } /*4DEBUG*/
+  return( II );
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring AA = 0,(e,f,h),dp;
+  matrix D[3][3]=0;
+  D[1,2]=-h;  D[1,3]=2*e;  D[2,3]=-2*f;
+  def A = nc_algebra(1,D); setring A; // this algebra is U(sl_2)
+
+  // Let us consider the linear map Ad_{e} from A_2 into A.
+
+  // Compute the PBW basis of A_2:
+  ideal Basis = PBW_maxDeg( 2 ); Basis;
+
+  // Compute images of basis elements under the linear map Ad_e:
+  ideal Image = applyAdF( Basis, e ); Image;
+
+  // Now we have a linear map given by: Basis_i --> Image_i
+  // Let's compute its kernel K:
+
+  // 1. compute syzygy module C:
+  module C = linearMapKernel( Image ); C;
+
+  // 2. compute corresponding combinations of basis vectors:
+  ideal K = linearCombinations(Basis, C); K;
+
+  // Let's check that Ad_e(K) is zero:
+  applyAdF( K, e );
+}
+
+
+
+/******************************************************/
+proc linearMapKernel( ideal Images )
+"
+USAGE: linearMapKernel( Images ); Images ideal
+PURPOSE: Computes the syzygy module of the linear map given by Images.
+RETURN: syzygy module, or int(0) if all images are zeroes
+SEE ALSO:   applyAdF; linearMapKernel
+"
+{
+  /*4DEBUG*/    if( defined( @@@DEBUG ) ){ BCall( "linearMapKernel", Images ); } /*4DEBUG*/
+
+  // This must be a list of monomials in a form of polynomial (sum with coeffs == 1)
+  poly Monomials = monomialForm( Images );
+
+  int N = size( Monomials ); // number of different monomials
+
+  if ( N == 0 ) // & ncols( Images ) > 0 => all Images == 0
+    {
+      int result = 0;
+
+      /*4DEBUG*/        if( defined( @@@DEBUG ) ){ ECall( "linearMapKernel", result ); } /*4DEBUG*/
+      return( result );
+    }
+
+  // Compute matrix MD
+  module MD; // zero
+
+  int x, y;
+
+  vector w;
+
+  poly p, m;
+
+  int V = ncols(Images); // must be equal to ncols(Basis) and size(Basis)!
+
+  // We take monomials as vector space basis of <Image>_k...
+
+  // TODO: Is there any other way to compute a basis of it and represent images as
+  // linear combination of them???
+
+  // Maybe some 'free resolution' stuff??? But we need linear maps only!!!
+
+  for ( x = 1; x <= V; x++ ) // For every Image vector
+    {
+      w = 0;
+
+      p = Images[x];
+
+      y = 1; // from 1st monomial in Monomials...
+
+      while( size(p) > 0 )
+        {
+          m = leadmonom(p);
+
+          // y < N!
+          while( Monomials[y] != m )
+            // There MUST be this monomial because of the construction of Monomials polynomial!
+            {
+              y++; // to size()
+            }
+
+          // found monomial m at position y.
+
+          w = w + leadcoef(p) * gen(y); // leadcoef(p) MUST be nonzero!
+          p = p - lead(p); // kill lead term
+        }
+
+      MD[x] = w;
+    }
+
+  /*******************************************/
+
+  // save options
+  intvec v = option( get );
+
+  // set right options
+  option( redSB );
+  option( redTail );
+
+  // compute everything in a right form
+  MD = simplify( groebner( syz(MD) ), 1 + 2 + 8 );
+  // note that MD is a matrix of numbers - no polynomials...
+
+  // restore options
+  option( set, v );
+
+  /*4DEBUG*/    if( defined( @@@DEBUG ) ){ ECall( "linearMapKernel", MD ); } /*4DEBUG*/
+
+  return( MD );
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring AA = 0,(e,f,h),dp;
+  matrix D[3][3]=0;
+  D[1,2]=-h;  D[1,3]=2*e;  D[2,3]=-2*f;
+  def A = nc_algebra(1,D); // this algebra is U(sl_2)
+  setring A;
+
+  // Let us consider the linear map Ad_{e} from A_2 into A.
+
+  // Compute the PBW basis of A_2:
+  ideal Basis = PBW_maxDeg( 2 ); Basis;
+
+  // Compute images of basis elements under the linear map Ad_e:
+  ideal Image = applyAdF( Basis, e ); Image;
+
+  // Now we have a linear map given by: Basis_i --> Image_i
+  // Let's compute its kernel K:
+
+  // 1. compute syzygy module C:
+  module C = linearMapKernel( Image ); C;
+
+  // 2. compute corresponding combinations of basis vectors:
+  ideal K = linearCombinations(Basis, C); K;
+
+  // Let's check that Ad_e(K) is zero:
+  ideal Z = applyAdF( K, e ); Z;
+
+  // Now linearMapKernel will return a single integer 0:
+  def CC  = linearMapKernel(Z); typeof(CC); CC;
+}
+
+
+/******************************************************/
+proc linearCombinations( ideal Basis, module KER )
+  "
+USAGE:  linearCombinations( Basis, C ); Basis ideal, C module
+PURPOSE: forms linear combinations of elements from Basis by replacing gen(i) by Basis[i] in C
+RETURN: ideal generated by computed linear combinations
+SEE ALSO:   linearMapKernel; applyAdF
+"
+{
+
+  /*4DEBUG*/    if( defined( @@@DEBUG ) ){ BCall( "linearCombinations", Basis, KER ); } /*4DEBUG*/
+
+
+  number c;
+
+  int x, y;
+
+  vector w;
+
+  poly p;
+
+  ideal result = 0;
+
+  // Kernel' basis translation
+  for ( x = 1; x <= ncols(KER); x++ )
+    {
+      p = 0;
+      w = KER[x];
+
+      for ( y = 1; y <= nrows(w); y++ )
+        {
+          c = leadcoef( w[y] );
+
+          if ( c != 0 )
+            {
+              p = p + c * Basis[y]; // linear combination of base vectors { Basis[y] }
+            }
+        }
+      result[ x ]  = p;
+    }
+
+
+  // no reduction in quotient algebras is needed. No multiplications were done!
+
+
+  /*4DEBUG*/    if( defined( @@@DEBUG ) ){ ECall( "linearCombinations", result ); } /*4DEBUG*/
+
+  return( result );
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring AA = 0,(e,f,h),dp;
+  matrix D[3][3]=0;
+  D[1,2]=-h;  D[1,3]=2*e;  D[2,3]=-2*f;
+  def A = nc_algebra(1,D); setring A; // this algebra is U(sl_2)
+
+  // Let us consider the linear map Ad_{e} from A_2 into A.
+
+  // Compute the PBW basis of A_2:
+  ideal Basis = PBW_maxDeg( 2 ); Basis;
+
+  // Compute images of basis elements under the linear map Ad_e:
+  ideal Image = applyAdF( Basis, e ); Image;
+
+  // Now we have a linear map given by: Basis_i --> Image_i
+  // Let's compute its kernel K:
+
+  // 1. compute syzygy module C:
+  module C = linearMapKernel( Image ); C;
+
+  // 2. compute corresponding combinations of basis vectors:
+  ideal K = linearCombinations(Basis, C); K;
+
+  // Let's check that Ad_e(K) is zero:
+  applyAdF( K, e );
+}
+
+
+
+/******************************************************/
+static proc LINEAR_MAP_KERNEL(ideal Basis, ideal Images ) // Ker of the linear map given by its values on basis vectors
+  "
+PURPOSE: Computation of the kernel basis of the linear map given by the list @given
+"
+{
+  /*4DEBUG*/    if( defined( @@@DEBUG ) ){ BCall( "LINEAR_MAP_KERNEL", Basis, Images ); } /*4DEBUG*/
+
+  ideal result = 0;
+
+  if ( size( Basis ) == 0 )
+    {
+      /*4DEBUG*/        if( defined( @@@DEBUG ) ){ ECall( "LINEAR_MAP_KERNEL", result ); } /*4DEBUG*/
+      return( result );
+    }
+
+  // compute fundamental solutions system
+  def T = linearMapKernel( Images );
+
+
+  // check result of linearMapKernel
+  if( typeof(T) == "int" )
+  {
+    if( T == 0 )
+    {
+      // All zeroes! Return Basis:
+      /*4DEBUG*/        if( defined( @@@DEBUG ) ){ ECall( "LINEAR_MAP_KERNEL", Basis ); } /*4DEBUG*/
+      return( Basis );
+    }
+  }
+  else
+  {
+    if( typeof(T) != "module" )
+    {
+       ERROR( "Wrong output from the 'linearMapKernel' function!" );
+    }
+  }
+
+  result = linearCombinations( Basis, T );
+
+  /*4DEBUG*/    if( defined( @@@DEBUG ) ){ ECall( "LINEAR_MAP_KERNEL", result ); } /*4DEBUG*/
+  return( result );
+}
+
+
+
+
+/******************************************************/
+static proc ZeroKer( ideal Basis, ideal Images ) // VS Basis of a Kernel of the linear map AD_h, h is a Cartan element
+"
+PURPOSE: Computes VS Basis of a Kernel of the linear map AD_h, when h is a Cartan element
+NOTE: the result is a set of all basis vectors having a zero image
+"
+{
+  /*4DEBUG*/    if( defined( @@@DEBUG ) ){ BCall( "ZeroKer", Basis, Images ); } /*4DEBUG*/
+
+  ideal result = 0;
+
+  for( int i = 1; i <= ncols( Basis ); i++ )
+    {
+      if( size( Images[i] ) == 0 ) // zero image?
+        {
+          result[ 1 + size(result) ] = Basis[i]; // take this basis vector!
+        }
+    }
+
+  /*4DEBUG*/    if( defined( @@@DEBUG ) ){ ECall( "ZeroKer", result ); } /*4DEBUG*/
+  return( result );
+}
+
+
+
+
+/******************************************************/
+// ::Variables:: Computes a set of variables
+/******************************************************/
+
+
+
+/******************************************************/
+// Returns an ideal of variables in a current base ring.
+proc variablesStandard()
+"
+USAGE:      variablesStandard();
+RETURN:     ideal, generated by algebra variables
+PURPOSE:    computes the set of algebra variables taken in their natural order
+SEE ALSO:   variablesSorted
+EXAMPLE:    example variablesStandard; shows an example
+"
+{
+  /*4DEBUG*/    if( defined( @@@DEBUG ) ){ BCall( "variablesStandard" ); } /*4DEBUG*/
+
+  ideal result = maxideal(1);
+
+  /*4DEBUG*/    if( defined( @@@DEBUG ) ){ ECall( "variablesStandard", result ); } /*4DEBUG*/
+  return( result );
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring AA = 0,(x,y,z),dp;
+  matrix D[3][3]=0;
+  D[1,2]=-z;  D[1,3]=2*x;  D[2,3]=-2*y;
+  def A = nc_algebra(1,D); setring A; // this algebra is U(sl_2)
+  // Variables in their natural order:
+  variablesStandard();
+}
+
+/******************************************************/
+// Sorts variables into an ideal. This is a kind of heuristics!
+proc variablesSorted()
+"
+USAGE:      variablesSorted();
+RETURN:     ideal, generated by sorted algebra variables
+PURPOSE:    computes the set of algebra variables sorted so that
+@* Cartan variables go first
+NOTE:       This is a heuristics for the computation of the center:
+@* it is better to compute centralizers of Cartan variables first since in this
+@* case we can omit solving the system of equations.
+SEE ALSO:   variablesStandard
+EXAMPLE:    example variablesSorted; shows an example
+"{
+  /*4DEBUG*/    if( defined( @@@DEBUG ) ){ BCall( "variablesSorted" ); } /*4DEBUG*/
+
+  ideal V   = variablesStandard();
+  int  N    = size( V ); // == nvars( basering )
+
+  ideal result = 0;
+
+  int  r_begin = 1;
+  int  r_end   = N;
+
+  poly v;
+
+  for( int k = 1; k <= N; k++ )
+    {
+      v = V[k];
+
+      if( isCartan(v) == 1 ) // Cartan elements go 1st
+        {
+          result[r_begin] = v;
+          r_begin++;
+        } else // Other - in the end...
+          {
+            result[r_end] = v;
+            r_end--;
+          }
+    }
+
+  /*4DEBUG*/    if( defined( @@@DEBUG ) ){ ECall( "variablesSorted", result ); } /*4DEBUG*/
+  return( result );
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring AA = 0,(x,y,z),dp;
+  matrix D[3][3]=0;
+  D[1,2]=-z;  D[1,3]=2*x;  D[2,3]=-2*y;
+  def A = nc_algebra(1,D); setring A; // this algebra is U(sl_2)
+  // There is only one Cartan variable - z in U(sl_2),
+  // it must go 1st:
+  variablesSorted();
+}
+
+
+
+
+
+/******************************************************/
+/******************************************************/
+// ::BasicCentralizerComputation:: Basic functions for centralize' computation.
+/******************************************************/
+/******************************************************/
+
+
+
+
+
+/******************************************************/
+// HL 'core' function
+proc centralizeSet( ideal F, ideal V )
+"
+USAGE:      centralizeSet( F, V ); F, V ideals
+INPUT:      F, V finite sets of elements of the base algebra
+RETURN:     ideal, generated by computed elements
+PURPOSE:    computes a vector space basis of the centralizer of the set F in the vector space generated by V over the ground field
+SEE ALSO:   centralizerVS; centralizer; inCentralizer
+EXAMPLE:    example centralizeSet; shows an example
+"
+{
+  /*4DEBUG*/    if( defined( @@@DEBUG ) ){ BCall( "centralizeSet", F, V ); } /*4DEBUG*/
+
+  int  N = size(F);
+
+  if( N == 0)
+    {
+      ERROR( "F MUST be non empty!!!" );
+    }
+
+  DBPrint(1, "BasisSize: " + string(size(V)) );
+
+  ideal Images;
+
+  for( int v = 1; (v <= N) and (size(V) > 0); v++ )
+    {
+      DBPrint(1, "Centralizing " + string(F[v]) );
+
+      Images = applyAdF( V, F[v] );
+
+      if( (isCartan(F[v]) == 1) or (size(V) == 1) )
+        {
+          V = ZeroKer( V, Images );
+        } else
+          {
+            V = LINEAR_MAP_KERNEL( V, Images );
+          }
+
+      // Printing...
+      DBPrint(1, "Progress: [ " + string(v) + " / " + string(N) + " ]"+
+              " => BasisSize: " + string(size(V)) );
+    }
+
+  V = makeNice(V);
+
+  /*4DEBUG*/    if( defined( @@@DEBUG ) ){ ECall( "centralizeSet", V ); } /*4DEBUG*/
+
+  return( V );
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring A = 0,(e(1..4)),dp;
+  matrix D[4][4]=0;
+  D[2,4] = -e(1);
+  D[3,4] = -e(2);
+  // This is A_4_1 - the first real Lie algebra of dimension 4.
+  def A_4_1 = nc_algebra(1,D); setring A_4_1;
+
+  ideal F = variablesSorted(); F;
+
+  // the center of A_4_1 is generated by
+  // e(1) and -1/2*e(2)^2+e(1)*e(3)
+  // therefore one may consider computing it in the following way:
+
+  // 1. Compute a PBW basis consisting of
+  //    monomials with exponent <= (1,2,1,0)
+  ideal V = PBW_maxMonom( e(1) * e(2)^ 2 * e(3) );
+
+  // 2. Compute the centralizer of F within the vector space
+  //    spanned by these monomials:
+  ideal C = centralizeSet( F, V ); C;
+
+  inCenter(C); // check the result
+}
+
+
+
+/******************************************************/
+proc centralizerVS( ideal F, int d )
+  "
+USAGE:      centralizerVS( F, D ); F ideal, D int
+RETURN:     ideal, generated by computed elements
+PURPOSE:    computes a vector space basis of centralizer(F) up to degree D
+NOTE:       D must be non-negative
+SEE ALSO:   centerVS; centralizer; inCentralizer
+EXAMPLE:    example centralizerVS; shows an example
+"
+{
+  /*4DEBUG*/    if( defined( @@@DEBUG ) ){ BCall( "centralizerVS", F, d ); } /*4DEBUG*/
+
+  if( size(F) == 0)
+    {
+      ERROR( "F MUST be non-empty!!!" );
+    }
+
+  ideal V = centralizeSet( F, PBW_maxDeg( d ) ); // basis of the Centralizer of S in PBW basis
+
+  /*4DEBUG*/    if( defined( @@@DEBUG ) ){ ECall( "centralizerVS", V ); } /*4DEBUG*/
+
+  return( V );
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring AA = 0,(x,y,z),dp;
+  matrix D[3][3]=0;
+  D[1,2]=-z;  D[1,3]=2*x;  D[2,3]=-2*y;
+  def A = nc_algebra(1,D); setring A; // this algebra is U(sl_2)
+  ideal F = x, y;
+  // find generators of the vector space of elements
+  // of degree <= 4 commuting with x and y:
+  ideal C = centralizerVS(F, 4);
+  C;
+  inCentralizer(C, F); // check the result
+}
+
+
+
+
+/******************************************************/
+// ::CenterAliases:: Basic functions/aliases for center' computation.
+/******************************************************/
+
+
+
+
+/******************************************************/
+proc centerVS( int D )
+"
+USAGE:      centerVS( D ); D int
+RETURN:     ideal, generated by computed elements
+PURPOSE:    computes a vector space basis of the center up to degree D
+NOTE:       D must be non-negative
+SEE ALSO:   centralizerVS; center; inCenter
+EXAMPLE:    example centerVS; shows an example
+"
+{
+  /*4DEBUG*/    if( defined( @@@DEBUG ) ){ BCall( "centerVS", D ); } /*4DEBUG*/
+
+
+  if( nameof( basering ) == "basering" )
+    {
+      //        ERROR( "No current ring!" );
+    }
+
+  if( D < 0 )
+    {
+      ERROR( "Degree D must be non-negative!" );
+    }
+
+  ideal result = centralizerVS( variablesSorted(), D );
+
+  /*4DEBUG*/    if( defined( @@@DEBUG ) ){ ECall( "centerVS", result ); } /*4DEBUG*/
+
+  return( result );
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring AA = 0,(x,y,z),dp;
+  matrix D[3][3]=0;
+  D[1,2]=-z;  D[1,3]=2*x;  D[2,3]=-2*y;
+  def A = nc_algebra(1,D); setring A; // this algebra is U(sl_2)
+  // find a basis of the vector space of all
+  // central elements of degree <= 4:
+  ideal Z = centerVS(4);
+  Z;
+  // note that the second element is the square of the first
+  // plus a multiple of the first:
+  Z[2] - Z[1]^2 + 8*Z[1];
+  inCenter(Z); // check the result
+}
+
+
+/******************************************************/
+proc centralizerRed( ideal F, int D, list # )
+"
+USAGE:      centralizerRed( F, D[, N] ); F ideal, D int, N optional int
+RETURN:     ideal, generated by computed elements
+PURPOSE:    computes subalgebra generators of centralizer(F) up to degree D.
+NOTE:       In general, one cannot compute the whole centralizer(F).
+@* Hence, one has to specify a termination condition via arguments D and/or N.
+@* If D is positive, only centralizing elements up to degree D are computed.
+@* If D is negative, the termination is determined by N only.
+@* If N is given, the computation stops if at least N elements have been found.
+@* Warning: if N is given and bigger than the actual number of generators,
+@* the procedure may not terminate.
+@* Current ordering must be a degree compatible well-ordering.
+SEE ALSO:   centralizerVS; centerRed; centralizer; inCentralizer
+EXAMPLE:    example centralizerRed; shows an example
+"
+{
+  /*4DEBUG*/    if( defined( @@@DEBUG ) ){ BCall( "centralizerRed", F, D, # ); } /*4DEBUG*/
+
+  if( nameof( basering ) == "basering" )
+    {
+      //        ERROR( "No current ring!" );
+    }
+
+  if( size(F) == 0)
+    {
+      ERROR( "F MUST be non-empty!!!" );
+    }
+
+  /////////////////////////////////////////////////////////////////////////////
+
+  int i, j, l, d;
+
+  /////////////////////////////////////////////////////////////////////////////
+
+  int k = DefaultInt(#);
+
+  int m = (k > 0);
+
+  int @MinDeg = 6; // starting guess for Maximal Bounding Degree, 6
+  int @Delta  = 4; // increment of it, 4
+
+  if( m and (D <= 0) )
+    {
+      // minimal guess
+      D = @MinDeg;
+    }
+
+  if( !m and D < 0)
+    {
+      ERROR("Wrong bounding condition!");
+    }
+
+  /////////////////////////////////////////////////////////////////////////////
+
+  def NCRING = basering; // Non-commutative ring
+  list L = ringlist( NCRING );
+  def L1, L2, L3, L4 = L[1..4]; // General components
+
+  def COMMRING = ring( list( L1, L2, L3, L4 ) ); // Underlying commutative ring
+
+
+  /////////////////////////////////////////////////////////////////////////////
+
+  // we keep the list of found leading monomials in the commutative ring!
+  setring COMMRING;
+
+  // Init
+  list FOUND_LEADING_MONOMIALS = list();
+
+  for( i = 1; i <= D; i++ )
+    {
+      FOUND_LEADING_MONOMIALS[i] = ideal();
+    }
+
+  ideal FLM, NEW, T; // in COMMRING
+
+  /////////////////////////////////////////////////////////////////////////////
+
+  setring NCRING;
+
+  ideal result, FLM, PBW, NEW, T, P; // in NCRING
+
+  // Main loop:
+  i = 1;
+
+  while( i <= D )
+    {
+      DBPrint( 1, "Current degree is " + string(i) );
+
+      /////////////////////////////////////////////////////////////////////////////
+
+      // Compute current "reduced" PBW basis...
+
+      // Prepare current found leading monomials
+      setring COMMRING;
+      FLM = FOUND_LEADING_MONOMIALS[i];
+
+      // And back to NCRing
+      setring NCRING;
+
+      FLM = imap(COMMRING, FLM); // We cannot write imap(COMMRING, FOUND_LEADING_MONOMIALS[i]) :(((
+
+      attrib(FLM, "isSB", 1); // just to avoid "no standard basis" warning.
+
+      // degrees should not change,
+      // no monomials should be multiplied here
+      T = reduce( PBW_eqDeg( i ), FLM, 1 );
+
+      // we simply kill in T monomials occurring in FOUND_LEADING_MONOMIALS[i]
+      P = PBW + T; // + simplifies
+
+      // Compute current centralizer
+      NEW = centralizeSet( F, P );
+
+      if( size(NEW) > 0 )
+        {
+          // In order to speedup multiplications we are going into a commutative ring:
+          setring COMMRING;
+
+          // we can perform commutative interreduction
+          // since no monomials should be multiplied!
+          // degrees should not change
+          NEW = interred( imap( NCRING, NEW ) );
+
+          // Go back!
+          setring NCRING;
+
+          NEW = imap( COMMRING, NEW );
+
+          DBPrint( 1, "Found: ", NEW );
+
+          // Add them to result...
+          result = result + NEW;
+        }
+
+      // Did we find needed number of generators? Or reached the bound?
+      if( (m and (size(result) >= k)) or (!m and (i == D)) )
+        {
+          break; // Get out of here!!!
+        }
+
+      // otherwise we must update FOUND_LEADING_MONOMIALS
+      if( size(NEW) > 0 )
+        {
+          setring COMMRING;
+
+          FLM = 0;
+
+          // We must update FOUND_LEADING_MONOMIALS!!!
+          for( j = 1; j <= size(NEW); j++ )
+            {
+              FLM[j] = leadmonom( NEW[j] ); // we are interested in leading monomials only!
+            }
+
+          FOUND_LEADING_MONOMIALS[i] = FOUND_LEADING_MONOMIALS[i] + FLM;
+
+          for( j = 1; j <= D; j = j + i ) // For every degree (j*i) of LNEW, do:
+            {
+              for( l = j; (l+i) <= D; l++ )
+                {
+                  FOUND_LEADING_MONOMIALS[l+i] =
+                    FOUND_LEADING_MONOMIALS[l+i] + FOUND_LEADING_MONOMIALS[l] * FLM;
+                }
+            }
+
+          // Return to NCRING
+          setring NCRING;
+
+          FLM = imap(COMMRING, FLM);
+          attrib(FLM, "isSB", 1);// just to avoid "no standard basis" warning.
+
+          // we simply kill in T monomials occurring in FOUND_LEADING_MONOMIALS[i]
+          T = reduce( T, FLM, 1 );
+
+          PBW = PBW + T;
+        } else
+          {
+            PBW = P;
+          }
+
+
+      if( m and (i == D) ) // Was the previous estimation too small???
+        {
+          // We must update FOUND_LEADING_MONOMIALS in their Commutative world:
+          setring COMMRING;
+
+          // Init new grades:
+          for( j = D + 1; j <= (D + @Delta); j++ )
+            {
+              FOUND_LEADING_MONOMIALS[j] = ideal();
+            }
+
+          FLM = 0;
+
+          // All previously computed elements in their order!
+          NEW = imap( NCRING, result );
+
+          for( j = 1; j <= size(NEW); j++ )
+            {
+              FLM[j] = leadmonom( NEW[j] ); // we are interested in leading monomials only!
+            }
+
+          while( size(FLM) > 0 )
+            {
+              // minimal degree:
+              d = mindegInt(FLM);  /// ### ///
+
+              // take all of minimal degree:
+              T = jet( FLM, d );
+
+              // there are size(T) elements of smallest degree (deg(FLM[1])) in FLM!
+
+              // Add them in the same way:
+              for( j = 1; j <= (D + @Delta); j = j + d ) // For every degree (j*d) of T, do:
+                {
+                  for( l = j; (l + d) <= (D + @Delta); l++ )
+                    {
+                      if( (l + d) > D ) // Only new should be updated!
+                        {
+                          FOUND_LEADING_MONOMIALS[l+d] =
+                            FOUND_LEADING_MONOMIALS[l+d] + FOUND_LEADING_MONOMIALS[l] * T;
+                        }
+                    }
+                }
+
+              // Kill them from FLM:
+              if( size(T) < size(FLM) )
+                {
+                  FLM = FLM[ (size(T)+1) .. size(FLM) ];
+                } else
+                  {
+                    FLM = 0; // break;
+                  }
+
+            }
+
+          // Go back...
+          setring NCRING;
+
+/*
+    if(toprint())
+    {
+      typeof(@Delta); @Delta;
+      typeof(D); D;
+    }
+*/
+          // And set new Bound
+          D = D + @Delta;
+        }
+
+      i++;
+    }
+
+  result = makeNice(result);
+
+  /*4DEBUG*/    if( defined( @@@DEBUG ) ){ ECall( "centralizerRed", result ); } /*4DEBUG*/
+
+  return( result );
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring AA = 0,(x,y,z),dp;
+  matrix D[3][3]=0;
+  D[1,2]=-z;  D[1,3]=2*x;  D[2,3]=-2*y;
+  def A = nc_algebra(1,D); setring A; // this algebra is U(sl_2)
+  ideal F = x, y;
+  // find subalgebra generators of degree <= 4 of the subalgebra of
+  // all elements commuting with x and y:
+  ideal C = centralizerRed(F, 4);
+  C;
+  inCentralizer(C, F); // check the result
+}
+
+
+/******************************************************/
+proc centerRed( int D, list # )
+"
+USAGE:      centerRed( D[, N] ); D int, N optional int
+RETURN:     ideal, generated by computed elements
+PURPOSE:    computes subalgebra generators of the center up to degree D
+NOTE:       In general, one cannot compute the whole center.
+@* Hence, one has to specify a termination condition via arguments D and/or N.
+@* If D is positive, only central elements up to degree D will be found.
+@* If D is negative, the termination is determined by N only.
+@* If N is given, the computation stops if at least N elements have been found.
+@* Warning: if N is given and bigger than the actual number of generators,
+@* the procedure may not terminate.
+@* Current ordering must be a degree compatible well-ordering.
+SEE ALSO:   centralizerRed; centerVS; center; inCenter
+EXAMPLE:    example centerRed; shows an example
+"
+{
+  /*4DEBUG*/    if( defined( @@@DEBUG ) ){ BCall( "centerRed", D, # ); } /*4DEBUG*/
+
+  if( nameof( basering ) == "basering" )
+    {
+      //        ERROR( "No current ring!" );
+    }
+
+  ideal result = centralizerRed( variablesSorted(), D, # );
+
+  /*4DEBUG*/    if( defined( @@@DEBUG ) ){ ECall( "centerRed", result ); } /*4DEBUG*/
+
+  return( result );
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring AA = 0,(x,y,z),dp;
+  matrix D[3][3]=0;
+  D[1,2]=z;
+  def A = nc_algebra(1,D); setring A; // it is a Heisenberg algebra
+  // find a basis of the vector space of
+  // central elements of degree <= 3:
+  ideal VSZ = centerVS(3);
+  // There should be 3 degrees of z.
+  VSZ;
+  inCenter(VSZ); // check the result
+  // find "minimal" central elements of degree <= 3
+  ideal SAZ = centerRed(3);
+  // Only 'z' must be computed
+  SAZ;
+  inCenter(SAZ); // check the result
+}
+
+
+/******************************************************/
+/******************************************************/
+// ::SubAlgebraReduction:: A kind of subalgebra reduction...
+/******************************************************/
+/******************************************************/
+
+/******************************************************/
+static proc INTERRED( ideal S )
+  "
+USAGE:      INTERRED( S ); S ideal
+RETURN:      ideal, interreduced S
+PURPOSE:     interreduction without monomial multiplication,
+    just make every leading monomial occur in a single polynomial
+"
+{
+  /*4DEBUG*/    if( defined( @@@DEBUG ) ){ BCall( "INTERRED", S ); } /*4DEBUG*/
+
+  ideal result = S;
+
+  int flag = 1;
+
+  int i, j, N;
+
+  poly p, lm;
+
+  while( flag == 1 )
+    {
+      flag = 0;
+
+      result = sort( simplify( result, 1 + 2 + 8) )[1];
+      // sorting w.r.t. actual monomial ordering
+      // generators with SMALLER(!) leading term come FIRST
+
+      N = size(result);
+
+      // kill leading monomials:
+
+      i = 1;
+      while( i < N )
+        {
+          p = result[i];
+          lm = leadmonom(p);
+
+          j = i + 1;
+          while( leadmonom(result[j]) == lm )
+            {
+              result[j] = result[j] - p; // leadcoefs are 1 because of simplify.
+              flag = 1; // we have changed something => we do still need to care about it...
+              j++;
+
+              if( j > N )
+                {
+                  break;
+                }
+            }
+
+          i = j;
+        }
+    }
+
+  // We are done! No common leading monomials!
+  // The result is sorted
+
+  /*4DEBUG*/    if( defined( @@@DEBUG ) ){ ECall( "INTERRED", result ); } /*4DEBUG*/
+
+  return( result );
+}
+
+
+/******************************************************/
+static proc SANF( poly p, list FOUND_LEADING_MONOMIALS )
+  "
+    reduce p w.r.t. found multiples without ANY polynomial multiplications!
+"
+{
+  /*4DEBUG*/    if( defined( @@@DEBUG ) ){ BCall( "SANF", p, FOUND_LEADING_MONOMIALS); } /*4DEBUG*/
+
+  poly q = p;
+  poly head = 0;
+
+  int d; int N = size(FOUND_LEADING_MONOMIALS);
+
+  while( size(q) > 0 )
+    {
+      d = maxdegInt(p); /// ### ///
+
+      if( (0 < d) and (d <= N) )
+        {
+          if( size(FOUND_LEADING_MONOMIALS[d]) > 0 )
+            {
+              attrib( FOUND_LEADING_MONOMIALS[d], "isSB", 1);
+              q = reduce( p, FOUND_LEADING_MONOMIALS[d] );
+            }
+
+          DBPrint(1, string(p) + " --> " + string(q) );
+        }
+
+      if( q == p )
+        {
+          p = lead(q);
+
+          if( d > 0 )
+            {
+              // No scalars!
+              head = head + p;
+            }
+
+          q = q - p;
+        }
+
+      p = q;
+    }
+
+
+
+  /*4DEBUG*/    if( defined( @@@DEBUG ) ){ ECall( "SANF", head ); } /*4DEBUG*/
+
+  return( head );
+}
+
+
+/******************************************************/
+static proc maxdegInt( ideal I )
+{
+  /*4DEBUG*/    if( defined( @@@DEBUG ) ){ BCall( "maxdegInt", I ); } /*4DEBUG*/
+
+  intmat D = maxdeg(I);
+
+  int max = D[1, 1]; int m;
+
+  for( int c = 2; c <= ncols(D); c++ )
+    {
+      m = D[1, c];
+
+      if( m > max )
+        {
+          max = m;
+        }
+    }
+
+  /*4DEBUG*/    if( defined( @@@DEBUG ) ){ ECall( "maxdegInt", max ); } /*4DEBUG*/
+
+  return( max );
+}
+
+
+/******************************************************/
+static proc mindegInt( ideal I )
+{
+  /*4DEBUG*/    if( defined( @@@DEBUG ) ){ BCall( "mindegInt", I ); } /*4DEBUG*/
+
+  intmat D = mindeg(I);
+
+  int min = D[1, 1]; int m;
+
+  for( int c = 2; c <= ncols(D); c++ )
+    {
+      m = D[1, c];
+
+      if( m < min )
+        {
+          min = m;
+        }
+    }
+
+  /*4DEBUG*/    if( defined( @@@DEBUG ) ){ ECall( "mindegInt", min ); } /*4DEBUG*/
+
+  return( min );
+}
+
+/******************************************************/
+// 'subalgebra basis' computation
+proc sa_reduce( ideal V )
+"
+USAGE:     sa_reduce(V); V ideal
+RETURN:     ideal, generated by computed elements
+PURPOSE:    compute a subalgebra basis of an algebra generated by the elements of V
+NOTE:       At the moment the usage of this procedure is limited to G-algebras
+SEE ALSO:   sa_poly_reduce
+EXAMPLE:    example sa_reduce; shows an example
+"
+{
+  /*4DEBUG*/    if( defined( @@@DEBUG ) ){ BCall( "sa_reduce", V ); } /*4DEBUG*/
+
+  ideal result = ideal();
+
+  ideal FLM = INTERRED( V ); // The output is sorted "[1]<[2]<[3]<..."
+
+  // We are bounded by maximal degree!!!
+  int D = maxdegInt( FLM );
+
+  // Init
+  list FOUND_LEADING_MONOMIALS = list();
+
+  int i;
+
+  for( i = 1; i <= D; i++ )
+    {
+      FOUND_LEADING_MONOMIALS[i] = ideal();
+    }
+
+  int d, j, l;
+
+  poly p, q; ideal T;
+
+
+  int c = 1;  // polynomials in FLM commute pairwise
+
+  for( j = 1; (j < size(FLM)) and (c == 1); j++ )
+    {
+      p = FLM[j];
+
+      for( l = j+1; (l <= size(FLM)) and (c == 1); l++ )
+        {
+          q = FLM[l];
+
+          if( NF(p*q - q*p, twostd(0)) != 0  )
+            {
+              c = 0; // There exists non-commuting pair
+            }
+        }
+    }
+
+  while( size(FLM) > 0 )
+    {
+//    FLM;
+
+      // Take the 1st element of FLM...
+      p = FLM[1]; // SANF( FLM[1], FOUND_LEADING_MONOMIALS );
+
+      FLM[1] = 0; // ...and kill it from FLM
+
+      d = maxdegInt( p );
+      T = ideal(p);
+
+//      d; size(FOUND_LEADING_MONOMIALS);
+
+    if( d > 0 )
+    {
+
+      FOUND_LEADING_MONOMIALS[d] = FOUND_LEADING_MONOMIALS[d] + T;
+
+      for( j = 1; j <= D; j = j + d ) // For every degree (j*d) of T, do:
+        {
+          for( l = j; (l + d) <= D; l++ )
+            {
+              FOUND_LEADING_MONOMIALS[l+d] =
+                FOUND_LEADING_MONOMIALS[l+d] + FOUND_LEADING_MONOMIALS[l] * T;
+
+              if( c != 1 )
+                {
+                  FOUND_LEADING_MONOMIALS[l+d] =
+                    FOUND_LEADING_MONOMIALS[l+d] + T * FOUND_LEADING_MONOMIALS[l];
+                }
+            }
+        }
+    }
+
+      if( size(FLM) > 0 )
+        {
+          for( i = 2; i <= ncols(FLM); i++ )
+            {
+              FLM[i] = SANF( FLM[i], FOUND_LEADING_MONOMIALS );
+            }
+          FLM = INTERRED( FLM );
+        }
+
+        if( size(T) > 0 )
+        {
+          DBPrint(1, "Found: " + string(T) );
+          result = result + T;
+        }
+
+    }
+
+  result = makeNice(result);
+
+  /*4DEBUG*/    if( defined( @@@DEBUG ) ){ ECall( "sa_reduce", result ); } /*4DEBUG*/
+
+  return( result );
+}
+example
+{ "EXAMPLE:"; echo = 2;
+ ring AA = 0,(x,y,z),dp;
+ matrix D[3][3]=0;
+ D[1,2]=-z; D[1,3]=2*x; D[2,3]=-2*y;
+ def A = nc_algebra(1,D); setring A; // this algebra is U(sl_2)
+ poly f = 4*x*y+z^2-2*z; // a central polynomial
+ ideal I = f, f*f, f*f*f - 10*f*f, f+3*z^3; I;
+ sa_reduce(I); // should be just f and z^3
+}
+
+
+
+/******************************************************/
+// subalgebra reduction of a polynomial
+proc sa_poly_reduce( poly p, ideal V )
+"
+USAGE:      sa_poly_reduce(p, V); p poly, V ideal
+RETURN:     polynomial, a reduction of p w.r.t. V
+PURPOSE:    computes a reduction of the polynomial p w.r.t. the subalgebra generated by elements of V
+NOTE:       At the moment the usage of this procedure is limited to G-algebras
+SEE ALSO:   sa_reduce
+EXAMPLE:    example sa_poly_reduce; shows an example
+"
+{
+  /*4DEBUG*/    if( defined( @@@DEBUG ) ){ ECall( "sa_poly_reduce", p, V ); } /*4DEBUG*/
+  // As previous...
+
+  ideal FLM = INTERRED( V ); // The output is sorted "[1]<[2]<[3]<..."
+
+  // We are bounded by maximal degree!!!
+  int D = maxdegInt( FLM + ideal(p)  );
+
+  // Init
+  list FOUND_LEADING_MONOMIALS = list();
+
+  int i;
+
+  for( i = 1; i <= D; i++ )
+    {
+      FOUND_LEADING_MONOMIALS[i] = ideal();
+    }
+
+  int d, j, l;
+
+  poly f, q; ideal T;
+
+
+  int c = 1;  // polynomials in FLM commute pairwise
+
+  for( j = 1; (j < size(FLM)) and (c == 1); j++ )
+    {
+      f = FLM[j];
+
+      for( l = j+1; (l <= size(FLM)) and (c == 1); l++ )
+        {
+          q = FLM[l];
+
+          if( NF(f*q - q*f, twostd(0)) != 0 )
+            {
+              c = 0;
+            }
+        }
+    }
+
+
+  while( size(FLM) > 0 )
+    {
+      // Take the 1st element of FLM...
+      q = SANF( FLM[1], FOUND_LEADING_MONOMIALS );
+
+      FLM[1] = 0; // ...and kill it from FLM
+
+      d = maxdegInt(q);
+      T = ideal(q);
+
+      FOUND_LEADING_MONOMIALS[d] = FOUND_LEADING_MONOMIALS[d] + T;
+
+      for( j = 1; j <= D; j = j + d ) // For every degree (j*d) of T, do:
+        {
+          for( l = j; (l + d) <= D; l++ )
+            {
+              FOUND_LEADING_MONOMIALS[l+d] =
+                FOUND_LEADING_MONOMIALS[l+d] + FOUND_LEADING_MONOMIALS[l] * T;
+
+              if( c != 1 )
+                {
+                  FOUND_LEADING_MONOMIALS[l+d] =
+                    FOUND_LEADING_MONOMIALS[l+d] + T * FOUND_LEADING_MONOMIALS[l];
+                }
+            }
+        }
+
+      if( size(FLM) > 0 )
+        {
+          for( i = 2; i <= ncols(FLM); i++ )
+            {
+              FLM[i] = SANF( FLM[i], FOUND_LEADING_MONOMIALS );
+            }
+          FLM = INTERRED( FLM );
+        }
+    }
+
+  poly result = SANF(p, FOUND_LEADING_MONOMIALS);
+
+  result = makeNice( result );
+
+
+  /*4DEBUG*/    if( defined( @@@DEBUG ) ){ ECall( "sa_poly_reduce", result ); } /*4DEBUG*/
+
+  return( result );
+}
+example
+{ "EXAMPLE:"; echo = 2;
+ ring AA = 0,(x,y,z),dp;
+ matrix D[3][3]=0;
+ D[1,2]=-z; D[1,3]=2*x; D[2,3]=-2*y;
+ def A = nc_algebra(1,D); setring A; // this algebra is U(sl_2)
+ poly f = 4*x*y+z^2-2*z; // a central polynomial
+ sa_poly_reduce(f + 3*f*f + x, ideal(f) ); // should be just 'x'
+}
+
+
+
+
+
+
+
+/******************************************************/
+// ::inStuff:: inCentralizer, inCenter, isCartan helpers
+/******************************************************/
+
+
+/******************************************************/
+static proc inCentralizer_poly( poly p, ideal S )
+  "
+    if p in centralizer(S) => return 1, otherwise return 0
+"
+{
+  poly f;
+
+  for( int k = 1; k <= size(S); k++ )
+    {
+      f = S[k];
+
+      if( NF( f * p - p * f, twostd(0) ) != 0 )
+        {
+          DBPrint( 1, "POLY: " + string (p) +
+                   " is NOT in the centralizer of polynomial {" + string(f) + "}" );
+          return (0);
+        }
+    }
+
+  return( 1 );
+}
+
+/******************************************************/
+static proc inCentralizer_list( def l, ideal S )
+{
+  for( int @i = 1; @i <= size(l); @i++ )
+    {
+      if( (typeof(l[@i])=="poly") or (typeof(l[@i]) == "int") or (typeof(l[@i]) == "number") )
+        {
+          if(! inCentralizer_poly(l[@i], S) )
+            {
+              return(0);
+            }
+
+        } else
+          {
+            if( (typeof(l[@i])=="list") or (typeof(l[@i])=="ideal") )
+              {
+                if(! inCentralizer_list(l[@i], S) )
+                  {
+                    return(0);
+                  }
+              }
+          }
+    }
+  return(1);
+}
+
+
+/******************************************************************************/
+// Checks the commutativity of polynomials of a with the polynomials in S
+proc inCentralizer( def a, ideal S )
+"
+USAGE:   inCentralizer(E, S); E poly/list/ideal, S poly/ideal
+RETURN:  integer, 1 if E is in the centralizer(S), 0 otherwise
+PURPOSE: check whether the elements of E are in the centralizer(S)
+EXAMPLE: example inCentralizer; shows examples
+"
+{
+  /*4DEBUG*/    if( defined( @@@DEBUG ) ){ BCall( "inCentralizer", a, S ); } /*4DEBUG*/
+
+  if( nameof( basering ) == "basering" )
+    {
+      //        ERROR( "No current ring!" );
+    }
+
+
+  int res;
+
+  if( (typeof(a) == "poly") or (typeof(a) == "int") or (typeof(a) == "number") )
+    {
+      res = inCentralizer_poly(a, S);
+    } else
+      {
+        if( (typeof(a)=="list") or (typeof(a)=="ideal") )
+          {
+            res = inCentralizer_list(a, S);
+          } else
+            {
+              res = -1;
+            }
+      }
+
+  if( res == -1 )
+    {
+      ERROR( "Wrong argument!" );
+    }
+
+  /*4DEBUG*/    if( defined( @@@DEBUG ) ){ ECall( "inCentralizer", res ); } /*4DEBUG*/
+
+  return (res);
+}
+example
+{
+  "EXAMPLE:";echo=2;
+  ring R = 0,(x,y,z),dp;
+  matrix D[3][3]=0;
+  D[1,2]=-z;
+  def r = nc_algebra(1,D); setring r; // the Heisenberg algebra
+  poly f = x^2;
+  poly a = z; // 'z' is central => it lies in every centralizer!
+  poly b = y^2;
+  inCentralizer(a, f);
+  inCentralizer(b, f);
+  list  l = list(1, a);
+  inCentralizer(l, f);
+  ideal I = a, b;
+  inCentralizer(I, f);
+  printlevel = 2;
+  inCentralizer(a, f); // yes
+  inCentralizer(b, f); // no
+}
+
+/******************************************************/
+// Checks the centrality of a
+proc inCenter( def a )
+  "
+USAGE:   inCenter(E); E poly/list/ideal
+RETURN:  integer, 1 if E is in the center, 0 otherwise
+PURPOSE: check whether the elements of E are central
+EXAMPLE: example inCenter; shows examples
+"
+{
+  /*4DEBUG*/    if( defined( @@@DEBUG ) ){ BCall( "inCenter", a ); } /*4DEBUG*/
+
+  if( nameof( basering ) == "basering" )
+    {
+      //        ERROR( "No current ring!" );
+    }
+
+  int result = inCentralizer( a, variablesStandard() );
+
+  /*4DEBUG*/    if( defined( @@@DEBUG ) ){ ECall( "inCenter", result ); } /*4DEBUG*/
+
+  return( result );
+}
+example
+{
+  "EXAMPLE:";echo=2;
+  ring R=0,(x,y,z),dp;
+  matrix D[3][3]=0;
+  D[1,2]=-z;
+  D[1,3]=2*x;
+  D[2,3]=-2*y;
+  def r = nc_algebra(1,D); setring r; // this is U(sl_2)
+  poly p=4*x*y+z^2-2*z;
+  inCenter(p);
+  poly f=4*x*y;
+  inCenter(f);
+  list l= list( 1, p, p^2, p^3);
+  inCenter(l);
+  ideal I= p, f;
+  inCenter(I);
+}
+
+
+/******************************************************/
+// Checks whether f is a Cartan element.
+proc isCartan( poly f )
+"
+USAGE:       isCartan(f); f poly
+PURPOSE:     check whether f is a Cartan element.
+RETURN:      integer, 1 if f is a Cartan element and 0 otherwise.
+NOTE:        f is a Cartan element of the algebra A
+@* if and only if for all g in A there exists C in K such that [f, g] = C * g
+@* if and only if for all variables v_i there exist C in K such that [f, v_i] = C * v_i.
+"
+{
+  /*4DEBUG*/    if( defined( @@@DEBUG ) ){ BCall( "isCartan", f ); } /*4DEBUG*/
+
+  if( nameof( basering ) == "basering" )
+    {
+      //        ERROR( "No current ring!" );
+    }
+
+
+  ideal V = variablesStandard();
+
+  int r = 1; poly v, g;
+
+  for( int i = size(V); i > 0; i-- )
+    {
+      v = leadmonom(V[i]); // V[i] must be just a variable, but...
+
+      g = NF( f*v - v*f, twostd(0) ); // [f, V[i]]
+
+      if( size(g) > 0 )
+        {
+          if( size(g) > 1 ) // it is not just \alpha * v_i.
+            {
+              r = 0;
+              break;
+            }
+
+          if( leadmonom(g) != v ) // g = \alpha * v_j, j != i.
+            {
+              r = 0;
+              break;
+            }
+
+        } // else \alpha = 0
+    }
+
+  /*4DEBUG*/    if( defined( @@@DEBUG ) ){ ECall( "isCartan", r ); } /*4DEBUG*/
+  return( r );
+}
+example
+{
+  "EXAMPLE:";echo=2;
+  ring R=0,(x,y,z),dp;
+  matrix D[3][3]=0;
+  D[1,2]=-z;
+  D[1,3]=2*x;
+  D[2,3]=-2*y;
+  def r = nc_algebra(1,D); setring r; // this is U(sl_2) with cartan - z
+  isCartan(z); // yes!
+  poly p=4*x*y+z^2-2*z;
+  isCartan(p); // central elements are Cartan elements!
+  poly f=4*x*y;
+  isCartan(f); // no way!
+  isCartan( 10 + p + z ); // scalar + central + cartan
+}
+
+
+
+
+/******************************************************/
+/******************************************************/
+// ::MainAliases:: The main non-static functions, visible to user are here. They are wrappers around basic functions.
+/******************************************************/
+/******************************************************/
+
+
+
+
+/******************************************************/
+// Computes the generators of the center of a basering
+proc center( int D, list # )
+"
+USAGE:      center(D[, N]); D int, N optional int
+RETURN:     ideal, generated by computed elements
+PURPOSE:    computes subalgebra generators of the center up to degree D
+NOTE:       In general, one cannot compute the whole center.
+@* Hence, one has to specify a termination condition via arguments D and/or N.
+@* If D is positive, only central elements up to degree D will be found.
+@* If D is negative, the termination is determined by N only.
+@* If N is given, the computation stops if at least N elements have been found.
+@* Warning: if N is given and bigger than the actual number of generators,
+@* the procedure may not terminate.
+@* Current ordering must be a degree compatible well-ordering.
+SEE ALSO:   centralizer; inCenter
+EXAMPLE:    example center; shows an example
+"
+{
+  if( nameof( basering ) == "basering" )
+    {
+      //        ERROR( "No current ring!" );
+    }
+
+  if( DefaultInt( # ) > 0 )
+    {
+      return( centerRed( D, # ) );
+    }
+
+  if( D >= 0 )
+    {
+      return( sa_reduce( centerVS(D) ) ); // Experimental! May be wrong!!!
+    }
+
+  ERROR( "Wrong arguments!" );
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring AA = 0,(x,y,z,t),dp;
+  matrix D[4][4]=0;
+  D[1,2]=-z;  D[1,3]=2*x;  D[2,3]=-2*y;
+  def A = nc_algebra(1,D); setring A; // this algebra is U(sl_2) tensored with K[t]
+  // find generators of the center of degree <= 3:
+  ideal Z = center(3);
+  Z;
+  inCenter(Z); // check the result
+  // find at least one generator of the center:
+  ideal Z2 = center(-1, 1);
+  Z2;
+  inCenter(Z2); // check the result
+}
+
+/******************************************************/
+// Computes the generators of the centralizer of S in a basering
+proc centralizer( ideal S, int D, list # )
+"
+USAGE:      centralizer(F, D[, N]); F poly/ideal, D int, N optional int
+RETURN:     ideal, generated by computed elements
+PURPOSE:    computes subalgebra generators of centralizer(F) up to degree D
+NOTE:       In general, one cannot compute the whole centralizer(F).
+@* Hence, one has to specify a termination condition via arguments D and/or N.
+@* If D is positive, only centralizing elements up to degree D will be found.
+@* If D is negative, the termination is determined by N only.
+@* If N is given, the computation stops if at least N elements have been found.
+@* Warning: if N is given and bigger than the actual number of generators,
+@* the procedure may not terminate.
+@* Current ordering must be a degree compatible well-ordering.
+SEE ALSO:   center; inCentralizer
+EXAMPLE:    example centralizer; shows an example
+"
+{
+  if( nameof( basering ) == "basering" )
+    {
+      //        ERROR( "No current ring!" );
+    }
+
+  if( DefaultInt( # ) > 0 )
+    {
+      return( centralizerRed( S, D, # ) );
+    }
+
+  if( D >= 0 )
+    {
+      return( sa_reduce( centralizerVS(S, D) ) ); // Experimental! May be wrong!!!
+    }
+
+  ERROR( "Wrong arguments!" );
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring AA = 0,(x,y,z),dp;
+  matrix D[3][3]=0;
+  D[1,2]=-z; D[1,3]=2*x; D[2,3]=-2*y;
+  def A = nc_algebra(1,D); setring A; // this algebra is U(sl_2)
+  poly f = 4*x*y+z^2-2*z; // a central polynomial
+  f;
+  // find generators of the centralizer of f of degree <= 2:
+  ideal c = centralizer(f, 2);
+  c;  // since f is central, the answer consists of generators of A
+  inCentralizer(c, f); // check the result
+  // find at least two generators of the centralizer of f:
+  ideal cc = centralizer(f,-1,2);
+  cc;
+  inCentralizer(cc, f); // check the result
+  poly g = z^2-2*z; // some non-central polynomial
+  // find generators of the centralizer of g of degree <= 2:
+  c = centralizer(g, 2);
+  c;
+  inCentralizer(c, g); // check the result
+  // find at least one generator of the centralizer of g:
+  centralizer(g,-1,1);
+  // find at least two generators of the centralizer of g:
+  cc = centralizer(g,-1,2);
+  cc;
+  inCentralizer(cc, g); // check the result
+}
+
+
+/*******************************************************
+ // normally one should use this library together with ncalg.lib in the following way:
+
+LIB "ncalg.lib";
+def Usl3 = makeUsl(3); // U(sl_3)
+setring Usl3;
+
+// show current ring:
+basering;
+
+LIB "central.lib";
+
+// easy example(few seconds), must compute two polynomials of degrees 2 and 3.
+center(3);
+
+kill Usl3;
+
+def Ug2 = makeUg2(); // U(g_2)
+setring Ug2;
+
+// show current ring:
+basering;
+
+// easy example(few seconds), must compute one polynomial of degree 2.
+center(2);
+
+// hard example (~hours), must compute two polynomials of degrees 2 and 6.
+center(6);
+
+quit;
+*******************************************************/
diff --git a/Singular/LIB/cisimplicial.lib b/Singular/LIB/cisimplicial.lib
new file mode 100644
index 0000000..d7cc6db
--- /dev/null
+++ b/Singular/LIB/cisimplicial.lib
@@ -0,0 +1,1836 @@
+//////////////////////////////////////////////////////////////////////
+
+category= "Commutative Algebra";
+version="version cisimplicial.lib 4.0.0.0 Jun_2013 "; // $Id: b1e4c69c3130d49927f6191ddfb5770d163f2c3c $
+info="
+LIBRARY: cisimplicial.lib. Determines if the toric ideal of
+a simplicial toric variety is a complete intersection
+
+AUTHORS: I.Bermejo,               ibermejo at ull.es
+@*       I.Garcia-Marco,          iggarcia at ull.es
+
+OVERVIEW:
+  A library for determining if a simplicial toric ideal is a complete
+  intersection with NO NEED of computing explicitly a system of generators
+  of such ideal. The procedures are based on two papers:
+  I. Bermejo, I. Garcia-Marco and J.J. Salazar-Gonzalez: 'An algorithm for
+  checking whether the toric ideal of an affine monomial curve is a complete
+  intersection', J. Symbolic Computation 42 (2007) pags: 971--991 and
+  I.Bermejo and I. Garcia-Marco: 'Complete  intersections in simplicial toric
+  varieties', Preprint (2010)
+
+PROCEDURES:
+ minMult(a,b);        computes the minimum multiple of a that belongs to the
+                semigroup generated by b
+ belongSemigroup(v,A[,n]);     checks whether A*x = v has a nonnegative
+                               integral solution
+ oneDimBelongSemigroup(n,v[,m]);      checks whether v*x = n has a
+                                      nonnegative integral solution
+ cardGroup(A);           computes the cardinal of Z^m / ZA
+ isCI(A);     checks wether I(A) is a complete intersection
+";
+
+LIB "general.lib";
+
+
+/////////////////////////////////////////////////////////////////////
+
+
+static proc Multiple(intvec v, intmat A, list #)
+"
+USAGE:   Multiple(v,A[,n]); v is an integral vector, A is an integral matrix, n is an integer.
+RETURN:  0 if none of the [n first] columns of A divides the vector v or an intvec otherwise.
+         In this case v = answer[2] * (answer[1]-th column of A).
+ASSUME:  nrows(v) = nrows(A) [and n <= nrows(A)].
+"
+{
+
+   intvec answer;
+   if (v == 0)
+   {
+      answer[1] = 1;
+      answer[2] = 0;
+      return (answer);
+   }
+
+   int last;
+   int e = size(#);
+   if  (e > 0)
+   {
+      last = #[1];
+   }
+   else
+   {
+      last = ncols(A);
+   }
+
+   int i,j,s;
+   for (j = 1; j <= last; j++)
+   {
+      s = 0;
+      for (i = 1; i <= nrows(A); i++)
+      {
+          if ((v[i] == 0)&&(A[i,j] != 0))
+          {
+             // it is not multiple of A_j
+            break;
+          }
+          if (v[i] != 0)
+          {
+            if (A[i,j] == 0)
+            {
+              // it is not multiple of A_j
+              break;
+            }
+            if (s == 0)
+            {
+              s = v[i] div A[i,j];
+            }
+            if (v[i] != s * A[i,j])
+            {
+              break;
+            }
+      }
+      if (i == nrows(A))
+      {
+        answer[1] = j;
+        answer[2] = s;
+        // v = s * A_j
+        return (answer);
+      }
+    }
+   }
+
+   // None of the columns of A divides v
+   return (0);
+
+}
+
+/////////////////////////////////////////////////////////////////////
+
+
+proc oneDimBelongSemigroup(int n, intvec v, list #)
+"
+USAGE:   oneDimBelongSemigroup(n,v[,m]); v is an integral vector,
+         n is a positive integer[, m is a positive integer].
+RETURN:  counters, a vector with nonnegative entries such that
+         v*counters = n. If it does not exist such a vector, it returns 0.
+         If a third parameter m is introduced, it will only consider the
+         first m entries of v.
+ASSUME:  v is an integral vector with positive entries.
+EXAMPLE: example oneDimBelongSemigroup; shows some examples.
+"
+{
+//--------------------------- initialisation ---------------------------------
+
+
+   int i, j;
+   int PartialSum;
+   int num;
+   int e = size(#);
+
+   if  (e > 0)
+   {
+      num = #[1];
+   }
+   else
+   {
+      num = nrows(v);
+   }
+
+   intvec v2 = v[1..num];
+   intvec counter, belong;
+   belong[num] = 0;
+   counter[num] = 0;
+   for (i = 1; i <= num; i++)
+   {
+      if (n % v[i] == 0)
+      {
+         // ---- n is multiple of v[i]
+         belong[i] = n div v[i];
+         return (belong);
+      }
+   }
+
+   if (num == 1)
+   {
+      // ---- num = 1 and n is not multiple of v[1] --> FALSE
+      return(0);
+   }
+
+   PartialSum = 0;
+
+   intvec w = sort(v2)[1];
+   intvec cambio = sort(v2)[2];
+
+   // ---- Iterative procedure to determine if n is in the semigroup generated by v
+   while (1)
+   {
+      if (n  >= PartialSum)
+      {
+         if (((n - PartialSum) % w[1]) == 0)
+         {
+            // ---- n belongs to the semigroup generated by v,
+            belong[cambio[1]] = (n - PartialSum) div w[1];
+            for (j = 2; j <= num; j++)
+            {
+               belong[cambio[j]] = counter[j];
+            }
+            return(belong);
+         }
+      }
+      i = num;
+      while (!defined(end))
+      {
+         if (i == 1)
+         {
+            // ---- Stop, n is not in the semigroup
+            return(0);
+         }
+         if (i > 1)
+         {
+            // counters control
+            if (w[i] > n - PartialSum)
+            {
+               PartialSum = PartialSum - (counter[i]*w[i]);
+               counter[i] = 0;
+               i--;
+            }
+            else
+            {
+               counter[i] = counter[i] + 1;
+               PartialSum = PartialSum + w[i];
+               int end;
+            }
+         }
+      }
+      kill end;
+   }
+}
+example
+{ "EXAMPLE:";echo=2;
+   int a = 95;
+   intvec v = 18,51,13;
+   oneDimBelongSemigroup(a,v);
+   "// 95 = 1*18 + 1*25 + 2*13";
+   oneDimBelongSemigroup(a,v,2);
+   "// 95 is not a combination of 18 and 52;";
+}
+
+
+
+/////////////////////////////////////////////////////////////////////
+
+
+proc SBelongSemigroup (intvec v, intmat A, list #)
+"
+USAGE:  SBelongSemigroup(v,A[,k]); v is an integral vector, A is an
+        integral matrix, n is a positive integer.
+RETURN: counters, a vector with nonnegative entries such that
+        A*counters = v. If it does not exist such vector, it returns 0.
+        If a third parameter k is introduced, it will only consider the
+        first k columns of A.
+ASSUME: A is an m x n matrix with nonnegative entries, n >= m, for every
+        i,j <= m, i != j then A[i,j] = 0, v has nonnegative entries and
+        nrows(v) = nrows(A);
+"
+{
+
+   int last;
+   int e = size(#);
+   if  (e > 0)
+   {
+      last = #[1];
+   }
+   else
+   {
+      last = ncols(A);
+   }
+
+   intvec counters;
+   counters[last] = 0;
+
+   int i, j, k, l;
+   intvec d;
+   for (i = 1; i <= nrows(A); i++)
+   {
+      d[i] = A[i,i];
+   }
+
+   i = 1;
+   while ((i < nrows(v)) && (v[i] % d[i] == 0))
+   {
+      i++;
+   }
+   if (v[i] % d[i] == 0)
+   {
+      // v is a combination of the first nrows(A) columns
+      for (j = 1; j <= nrows(v); j++)
+      {
+         counters[j] = v[j] div d[j];
+      }
+      return(counters);
+   }
+
+   int gcdrow;
+   for (i = 1; i <= nrows(A); i++)
+   {
+      gcdrow = d[i];
+      for (j = nrows(A)+1; j <= last; j++)
+      {
+         if (A[i,j] != 0)
+         {
+            gcdrow = gcd(gcdrow,A[i,j]);
+         }
+      }
+      if (v[i] % gcdrow != 0)
+      {
+         return (0);
+      }
+   }
+
+   intvec swap;
+   for (i = 1; i <= last; i++)
+   {
+      swap[i] = i;
+   }
+   for (i = nrows(A) + 1; i <= last; i++)
+   {
+      for (j = 1; j <= nrows(v); j++)
+      {
+         if (A[j,i] > v[j])
+         {
+            swap[i] = 0;
+            for (k = 1; k <= nrows(A); k++)
+            {
+               A[k,i] = A[k,last];
+            }
+            swap[i] = swap[last];
+            last--;
+            i--;
+            break;
+         }
+      }
+   }
+   if (nrows(A) == last)
+   {
+      return (0);
+   }
+
+
+   intvec order;
+   order[last] = 0;
+   for (i = nrows(A) + 1; i <= last; i++)
+   {
+      order[i] = 1;
+      for (j = 1; j <= nrows(A); j++)
+      {
+         if (A[j,i] > 0)
+         {
+            order[i] = lcm(order[i], d[j] div gcd(A[j,i],d[j]));
+         }
+      }
+   }
+
+   intvec counters2;
+   counters2[last] = 0;
+
+   // A full enumeration is performed
+   while(1)
+   {
+      i = nrows(counters2);
+      while (1)
+      {
+         j = 1;
+         if (counters2[i] < order[i] - 1)
+         {
+            while ((j < nrows(A)) and (v[j] >= A[j,i]))
+            {
+               j++;
+            }
+         }
+         if ((v[j] < A[j,i])||(counters2[i] == order[i] - 1))
+         {
+            // A_j is not < v componentwise or counters2 = order[i]
+            // we cannot increase counters2[i]
+            if (counters2[i] != 0)
+            {
+               for (k = 1; k <= nrows(v); k++)
+               {
+                  v[k] = v[k] + counters2[i] * A[k,i];
+               }
+               counters2[i] = 0;
+            }
+            i--;
+            if (i <= nrows(A))
+            {
+               // A*x = v has not nonnegative integral solution
+               return(0);
+            }
+         }
+         else
+         {
+            // j = nrows(A), then A_j < v (componentwise)
+            // we add one unit to counters2[i]
+            for (k = 1; k <= nrows(v); k++)
+            {
+               v[k] = v[k] - A[k,i];
+            }
+            counters2[i] = counters2[i] + 1;
+
+            l = 1;
+            while ((l < nrows(v)) and (v[l] % d[l] == 0))
+            {
+               l++;
+            }
+            if (v[l] % d[l] == 0)
+            {
+               // v is a combination of the first nrows(A) columns
+               for (k = 1; k <= nrows(v); k++)
+               {
+                  counters[k] = v[k] div d[k];
+               }
+               for (k = nrows(v) + 1; k <= nrows(counters2); k++)
+               {
+                  counters[swap[k]] = counters2[k];
+               }
+               // A*counters = v
+               return(counters);
+            }
+
+            break;
+         }
+      }
+   }
+}
+
+
+/////////////////////////////////////////////////////////////////////
+
+
+
+proc belongSemigroup (intvec v, intmat A, list #)
+"
+USAGE:   belongSemigroup(v,A[,k]); v is an integral vector, A is an
+         integral matrix, n is a positive integer.
+RETURN:  counters, a vector with nonnegative entries such that
+         A*counters = v. If it does not exist such a vector, it returns 0.
+         If a third parameter k is introduced, it will only consider the
+         first k columns of A.
+ASSUME:  A is a matrix with nonnegative entries, nonzero colums,
+         v is a nonnegative vector and nrows(v) = nrows(A).
+EXAMPLE: example belongSemigroup; shows some examples.
+"
+{
+   int inputlast;
+   int e = size(#);
+   if  (e > 0)
+   {
+      inputlast = #[1];
+   }
+   else
+   {
+      inputlast = ncols(A);
+   }
+
+   int i, j, k;
+   intvec counters;
+   int last = inputlast;
+
+   if (last == 0)
+   {
+      return (counters);
+   }
+
+   intvec swap;
+   for (i = 1; i <= last; i++)
+   {
+      swap[i] = i;
+   }
+   for (i = 1; i <= last; i++)
+   {
+      for (j = 1; j <= nrows(v); j++)
+      {
+         if (A[j,i] > v[j])
+         {
+            swap[i] = 0;
+            for (k = 1; k <= nrows(A); k++)
+            {
+               A[k,i] = A[k,last];
+            }
+            swap[i] = swap[last];
+            last--;
+            i--;
+            break;
+         }
+      }
+   }
+
+   if (last == 0)
+   {
+      return (0);
+   }
+
+   intvec multip = Multiple(v, A, last);
+
+   if (multip != 0)
+   {
+      intvec counters2;
+      counters2[inputlast] = 0;
+      // v = mult.value * ((mult.column)-th column of A)
+      counters2[swap[multip[1]]] = multip[2];
+      return (counters2);
+   }
+
+   counters[last] = 0;
+   // A full enumeration is performed
+   // Example: si v = (3,2,6), a1 = (1,0,0), a2 = (0,1,1), a3 = (0,0,1), then counters will take the
+   // following values:
+   // 000, 001, 002, 003, 004, 005, 006, 010, 011, 012, 013, 014, 015, 020, 021, 022, 023, 024 ---> 324
+   while(1)
+   {
+      i = nrows(counters);
+      while (1)
+      {
+         j = 1;
+         while (j <= nrows(A))
+         {
+            if (v[j] < A[j,i])
+            {
+               break;
+            }
+            j++;
+         }
+         if (j <= nrows(A))
+         {
+            if (counters[i] != 0)
+            {
+               for (k = 1; k <= nrows(A); k++)
+               {
+                  v[k] = v[k] + counters[i] * A[k,i];
+               }
+               counters[i] = 0;
+            }
+            i--;
+            if (i < 2)
+            {
+               // Does not belong
+               return (0);
+            }
+         }
+         else
+         {
+            for (k = 1; k <= nrows(A); k++)
+            {
+               v[k] = v[k] - A[k,i];
+            }
+            counters[i] = counters[i] + 1;
+            multip = Multiple(v, A, i);
+            if (multip != 0)
+            {
+               // v belongs, we return the solution counters so that A * counters = v
+               counters[multip[1]] = multip[2];
+               intvec counters2;
+               counters2[inputlast] = 0;
+               for (i = 1; i <= last; i++)
+               {
+                  counters2[swap[i]] = counters[i];
+               }
+               return (counters2);
+            }
+
+            break;
+         }
+      }
+   }
+}
+example
+{ "EXAMPLE:"; echo=2;
+   intmat A[3][4] = 10,3,2,1,2,1,1,3,5,0,1,2;
+   print(A);
+   intvec v = 23,12,10;
+   belongSemigroup(v,A);
+   "// A * (1,3,1,2) = v";
+   belongSemigroup(v,A,3);
+   "// v is not a combination of the first 3 columns of A";
+   intvec w = 12,4,1;
+   belongSemigroup(w,A);
+   "// w is not a combination of the columns of A";
+}
+
+/////////////////////////////////////////////////////////////////////
+
+
+
+proc cardGroup(intmat A, list #)
+"
+USAGE:   cardGroup(A[,n]); A is a matrix with integral coefficients.
+RETURN:         It returns a bigint. If we denote by ZA the group generated
+         by the columns of the matrix A, then it returns the number of
+         elements of the group of Z^m / ZA, where m = number of rows of A.
+         If a second parameter n is introduced, it will
+         only consider the first n columns of A. It returns 0 if Z^m / ZA
+         is infinite; this is, when rank ZA < m.
+EXAMPLE: example cardGroup; shows an example.
+"
+{
+   int i, j, k, l;
+   int coef1, coef2, aux;
+   bigint aux2, aux3;
+   list gcdiv;
+
+   int last;
+   int e = size(#);
+   if  (e > 0)
+   {
+      last = #[1];
+   }
+   else
+   {
+      last = ncols(A);
+   }
+
+   // First we put the matrix A in diagonal form.
+   for (i = 1; i <= nrows(A); i++)
+   {
+      j = i;
+      while (A[i,j] == 0)
+      {
+         j++;
+         if (j > last)
+         {
+            return (0);
+            // Group is infinite
+         }
+      }
+      if (j > i)
+      {
+         for (k = i; k <= nrows(A); k++)
+         {
+            // swap columns to have a nonzero pivot
+            aux = A[k,i];
+            A[k,i] = A[k,j];
+            A[k,j] = aux;
+         }
+      }
+      for (k = j+1; k <= last; k++)
+      {
+         if (A[i,k] != 0)
+         {
+            gcdiv = extgcd(A[i,i],A[i,k]);
+            coef1 = A[i,k] div gcdiv[1];
+            coef2 = A[i,i] div gcdiv[1];
+            for (l = i; l <= nrows(A); l++)
+            {
+               // Perform elemental operations in the matrix
+               // to put A in diagonal form
+               aux2 = bigint(gcdiv[2]) * bigint(A[l,i]) + bigint(gcdiv[3]) * bigint(A[l,k]);
+               aux3 = bigint(coef1) * bigint(A[l,i]) - bigint(coef2) * bigint(A[l,k]);
+               A[l,k] = int(aux3);
+               A[l,i] = int(aux2);
+            }
+         }
+      }
+   }
+
+   // Once the matrix is in diagonal form, we only have to multiply
+   // the diagonal elements
+
+   bigint determinant = bigint(A[1,1]);
+   bigint entry;
+   for (i = 2; i <= nrows(A); i++)
+   {
+      entry = bigint(A[i,i]);
+      determinant = determinant * entry;
+   }
+   determinant = absValue(determinant);
+   return(determinant);
+
+}
+example
+{ "EXAMPLE:"; echo=2;
+   intmat A[3][5] = 24,  0,  0,  8, 3,
+                     0, 24,  0, 10, 6,
+                     0,  0, 24,  5, 9;
+   cardGroup(A);
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+proc minMult(int a, intvec b)
+"
+USAGE:   minMult (a, b); a integer, b integer vector.
+RETURN:  an integer k, the minimum positive integer such that k*a belongs to the
+         semigroup generated by the integers in b.
+ASSUME:  a is a positive integer, b is a vector of positive integers.
+EXAMPLE: example minMult; shows an example.
+"
+{
+//--------------------------- initialisation ---------------------------------
+   int i, j, min, max;
+   int n = nrows(b);
+
+   if (n == 1)
+   {
+      // ---- trivial case
+      return(b[1]/gcd(a,b[1]));
+   }
+
+   max = b[1];
+   for (i = 2; i <= n; i++)
+   {
+      if (b[i] > max)
+      {
+         max = b[i];
+      }
+   }
+   int NumNodes = a + max; //----Number of nodes in the graph
+
+   int dist = 1;
+   // ---- Auxiliary structures to obtain the shortest path between the nodes 1 and a+1 of this graph
+   intvec queue = 1;
+   intvec queue2;
+
+   // ---- Control vector:
+   //      control[i] = 0 -> node not reached yet
+   //      control[i] = 1 -> node in queue1
+   //      control[i] = 2 -> node in queue2
+   //      control[i] = 3 -> node already processed
+   intvec control;
+   control[1] = 3;         // Starting node
+   control[a + max] = 0;   // Ending node
+   int current = 1;        // Current node
+   int next;               // Node connected to corrent by arc (current, next)
+
+   int ElemQueue, ElemQueue2;
+   int PosQueue = 1;
+
+   // Algoritmo de Dijkstra
+   while (1)
+   {
+      if (current <= a)
+      {
+         // ---- current <= a, arcs are (current, current + b[i])
+         for (i = 1; i <= n; i++)
+         {
+            next = current + b[i];
+            if (next == a+1)
+            {
+               kill control;
+               kill queue;
+               kill queue2;
+               return (dist);
+            }
+            if ((control[next] == 0)||(control[next] == 2))
+            {
+               control[next] = 1;
+               queue = queue, next;
+            }
+         }
+      }
+      if (current > a)
+      {
+         // ---- current > a, the only possible ars is (current, current - a)
+         next = current - a;
+         if (control[next] == 0)
+         {
+            control[next] = 2;
+            queue2[nrows(queue2) + 1] = next;
+         }
+      }
+      PosQueue++;
+      if (PosQueue <= nrows(queue))
+      {
+         current = queue[PosQueue];
+      }
+      else
+      {
+         dist++;
+         if (control[a+1] == 2)
+         {
+            return(dist);
+         }
+         queue = queue2[2..nrows(queue2)];
+         current = queue[1];
+         PosQueue = 1;
+         queue2 = 0;
+      }
+      control[current] = 3;
+   }
+}
+example
+{ "EXAMPLE:";echo=2;
+   int a = 46;
+   intvec b = 13,17,59;
+   minMult(a,b);
+   "// 3*a = 8*b[1] + 2*b[2]"
+}
+
+
+/////////////////////////////////////////////////////////////////////
+
+
+static proc CheckMin (int posiblemin, intmat A, int column, list #)
+"
+USAGE:  CheckMin(posiblemin,A,column[,n]); posiblemin is an integer,
+        A is an integral matrix and column and last are integers.
+RETURN: 1 if posiblemin is the minimum value x such that x * (column-th colum of A)
+        belongs to the semigroup generated by all the columns of A except
+        A_column. It returns 0 otherwise. If an extra parameter n is
+        introduced then it will only consider the first n columns of A.
+ASSUME: 1 <= column <= ncols(A), A does not have negative entries or zero columns
+"
+{
+
+   // If one can write (posiblemin-1)*A_column as a non-trivial combination of the
+   // colums of A, then posiblemin is > to the real minimum
+   intvec counters, multip;
+   counters[ncols(A)] = 0;
+
+   int i,j,k;
+   int last;
+
+   int e = size(#);
+   if  (e > 0)
+   {
+      last = #[1];
+   }
+   else
+   {
+      last = ncols(A);
+   }
+
+   intvec v, aux;
+   for (i = 1; i <= nrows(A); i++)
+   {
+      v[i] = (posiblemin-1)*A[i,column];
+      // We swap A_column with A_1
+      aux[i] = A[i,1];
+      A[i,1] = A[i,column];
+      A[i,column] = aux[i];
+   }
+
+   for (i = 2; i <= last; i++)
+   {
+      for (j = 1; j <= nrows(v); j++)
+      {
+         if (A[j,i] > v[j])
+         {
+            for (k = 1; k <= nrows(A); k++)
+            {
+               A[k,i] = A[k,last];
+            }
+            last--;
+            i--;
+            break;
+         }
+      }
+   }
+
+   // A full enumeration is performed
+   while(1)
+   {
+      i = last;
+      while (1)
+      {
+         j = 1;
+         while (j <= nrows(A))
+         {
+            if (v[j] < A[j,i])
+            {
+               break;
+            }
+            j++;
+         }
+         if (j <= nrows(A))
+         {
+            if (counters[i] != 0)
+            {
+               for (k = 1; k <= nrows(A); k++)
+               {
+                  v[k] = v[k] + counters[i] * A[k,i];
+               }
+               counters[i] = 0;
+            }
+            i--;
+            if (i == 1)
+            {
+               // The only solution is that v = (posiblemin-1)*A.col[1]
+               return (1);
+            }
+         }
+         else
+         {
+            for (k = 1; k <= nrows(A); k++)
+            {
+               v[k] = v[k] - A[k,i];
+            }
+            counters[i] = counters[i]+1;
+            multip = Multiple(v, A, i);
+            if (multip != 0)
+            {
+               return (0);
+            }
+            break;
+         }
+      }
+   }
+}
+
+/////////////////////////////////////////////////////////////////////
+
+
+static proc SimplicialCheckMin (int posiblemin, intmat A, int column, list #)
+"
+USAGE:  SimplicialCheckMin(posiblemin,A,column[,last]); posiblemin is an integer,
+        A is an integral matrix and column and last are integers.
+RETURN: 1 if posiblemin is less or equal to the minimum value x such that
+        x * A_column belongs to the semigroup generated by all the columns of A
+        except A_column. It returns 0 otherwise. If an extra parameter last is
+        introduced then it will only consider the first n columns of A.
+ASSUME: 1 <= column <= ncols(A), A does not have negative entries or zero columns
+        A[i,j] = 0 for all 1 <= i,j <= nrows(A) where i != j
+"
+{
+   // If one can write (posiblemin-1)*A_column as a non-trivial combination of the
+   // colums of A, then posiblemin is > than the real minimum
+
+   int last;
+   int e = size(#);
+   if  (e > 0)
+   {
+      last = #[1];
+   }
+   else
+   {
+      last = ncols(A);
+   }
+
+   int i, j, k, l;
+   intvec d, v;
+   for (i = 1; i <= nrows(A); i++)
+   {
+      d[i] = A[i,i];
+   }
+
+   for (i = 1; i <= nrows(A); i++)
+   {
+      v[i] = A[i,column] * (posiblemin-1);
+   }
+
+   i = 1;
+   while ((i < nrows(v)) && (v[i] % d[i] == 0))
+   {
+      i++;
+   }
+   if (v[i] % d[i] == 0)
+   {
+      // v is a combination of the first nrows(A) columns
+      return(0);
+   }
+
+   int aux;
+   for (i = 1; i <= nrows(A); i++)
+   {
+      aux = A[i,nrows(A)+1];
+      A[i,nrows(A)+1] = A[i,column];
+      A[i,column] = aux;
+   }
+
+   for (i = nrows(A) + 2; i <= last; i++)
+   {
+       for (j = 1; j <= nrows(v); j++)
+       {
+          if (A[j,i] > v[j])
+          {
+             for (k = 1; k <= nrows(A); k++)
+             {
+                A[k,i] = A[k,last];
+             }
+             last--;
+             i--;
+             break;
+          }
+       }
+    }
+
+    intvec order;
+    order[last] = 0;
+    for (i = nrows(A) + 1; i <= last; i++)
+    {
+       order[i] = 1;
+       for (j = 1; j <= nrows(A); j++)
+       {
+          if (A[j,i] > 0)
+          {
+             order[i] = lcm(order[i], d[j] div gcd(A[j,i],d[j]));
+          }
+       }
+    }
+
+
+    if (order[nrows(A)+1] < posiblemin-1)
+    {
+       return (0);
+    }
+
+    order[nrows(A)+1] = posiblemin-1;
+
+    intvec counters;
+    counters[last] = 0;
+
+    // A full enumeration is performed
+    while(1)
+    {
+       i = last;
+       while (1)
+       {
+          j = 1;
+          if (counters[i] < order[i] - 1)
+          {
+             while ((j < nrows(A)) and (v[j] >= A[j,i]))
+             {
+                j++;
+             }
+          }
+          if ((v[j] < A[j,i])||(counters[i] == order[i] - 1))
+          {
+             // A_j is not < v componentwise or counters = order[i]-1
+             // we cannot increase counters[i]
+             if (counters[i] != 0)
+             {
+                for (k = 1; k <= nrows(v); k++)
+                {
+                   v[k] = v[k] + counters[i] * A[k,i];
+                }
+                counters[i] = 0;
+             }
+             i--;
+            if (i <= nrows(A))
+            {
+               // A*x = v has not nonnegative integral solution different
+               // from the trivial one
+               return(1);
+            }
+         }
+         else
+         {
+            // j = nrows(A), then A_j < v (componentwise)
+            // we add one unit to counters[i]
+            for (k = 1; k <= nrows(v); k++)
+            {
+               v[k] = v[k] - A[k,i];
+            }
+            counters[i] = counters[i] + 1;
+
+            l = 1;
+            while ((l < nrows(v)) and (v[l] % d[l] == 0))
+            {
+               l++;
+            }
+            if (v[l] % d[l] == 0)
+            {
+               // v is a combination of the first nrows(A) columns
+               return(0);
+            }
+
+            break;
+         }
+      }
+   }
+}
+
+
+
+/////////////////////////////////////////////////////////////////////
+
+
+static proc Proportional(intvec a, intvec b)
+"
+USAGE:  Proportional(a,b); a,b integral vectors
+RETURN: 1 if nrows(a) = nrows(b) and the vectors a and b are proportional;
+        this is, there exist a rational number k such that k*a = b, and
+        0 otherwise
+ASSUME: a, b are nonzero vectors
+"
+{
+
+   if (nrows(a) != nrows(b))
+   {
+      return (0)
+   }
+
+   int i, pivot;
+   pivot = 1;
+   while (a[pivot] == 0)
+   {
+      if (b[pivot] != 0)
+      {
+         // Not proportional
+         return (0);
+      }
+      pivot++;
+   }
+
+   if (b[pivot] == 0)
+   {
+      // Not proportional
+      return (0);
+   }
+
+   for (i = pivot + 1; i <= nrows(a); i++)
+   {
+      if (a[i] * b[pivot] != a[pivot] * b[i])
+      {
+         // Not proportional
+         return (0);
+      }
+   }
+   return (1);
+
+}
+
+/////////////////////////////////////////////////////////////////////
+
+
+static proc StimatesMin(intmat A, int column, intvec line, list #)
+"
+USAGE:  StimatesMin(A,column,line[,n]); A is an integral matrix, column is
+        an integer, line is an integral vector and n is an integer.
+RETURN: The minimum integer k such that k * A_column belongs to the
+        semigroup generated by all the columns of A except A_column. It
+        returns 0 if it is not necessary to compute for the main program.
+        If an extra parameter n is introuduced it considers the first n
+        colums of A.
+ASSUME: 1 <= column [<= n] <= ncols(A), A has nonnegative entries, line is
+        a vector such that line[i] = line[j] if and only if the i-th and
+        j-th columns of A are proportional
+"
+{
+
+   int last;
+   int e = size(#);
+   if  (e > 0)
+   {
+      last = #[1];
+   }
+   else
+   {
+      last = nrows(line);
+   }
+
+   intvec current;
+   int i,j,k;
+   for (i = 1; i <= nrows(A); i++)
+   {
+      current[i] = A[i,column];
+   }
+
+   int nonzero = 1;
+   while (current[nonzero] == 0)
+   {
+      nonzero++;
+   }
+
+   // We will only consider those colums A_j such that line[j] = line[column]
+   intvec prop, jthcolumn;
+   for (j = 1; j <= last; j++)
+   {
+      if (j != column)
+      {
+         if (line[column] == line[j])
+         {
+            prop[nrows(prop)+1] = A[nonzero,j];
+         }
+      }
+   }
+   int posiblemin = 0;
+   if (prop[nrows(prop)] > 0)
+   {
+      // 1-dim minimum
+      posiblemin = minMult(current[nonzero],prop);
+   }
+
+   if (line[column] <= nrows(A))
+   {
+      // It is not necessary to do CheckMin
+      return(posiblemin);
+   }
+
+
+   if (posiblemin > 0)
+   {
+      if (SimplicialCheckMin(posiblemin, A, column, last))
+      {
+         // It is the real minimum, otherwise minimum < posiblemin
+         return (posiblemin);
+      }
+   }
+   // Not necessary to compute the minimum explicitly
+   return (0);
+}
+
+/////////////////////////////////////////////////////////////////////
+
+
+proc isCI(intmat A)
+"
+USAGE:   isCI(A); A is an integral matrix
+RETURN:  1 if the simplicial toric ideal I(A) is a complete intersection
+         and 0 otherwise. If printlevel > 0 and I(A) is a complete
+         intersection it also shows a minimal set of generators of I(A)
+ASSUME:  A is an m x n integral matrix with nonnegative entries and for
+         every 1 <= i <= m, there exist a column in A whose i-th coordinate
+         is not null and the rest are 0.
+EXAMPLE: example isCI; shows some examples
+"
+{
+//--------------------------- initialisation ---------------------------------
+
+   intvec d;
+   intvec minimum;
+   intvec swap;                // swap[i] = j if and only if the i-th column of B equals the j-th column of A
+   intvec line;                // line[i] = line[j] if and only if the i-th and the j-th column of B are proportional
+
+
+   int n, m;           // Size of the input
+   int i,j,k,l,t;
+
+   n = ncols(A);
+   m = nrows(A);
+   intmat B[m][n];                                // auxiliary matrix
+   intmat support[2*n-m][n];        // support[i,j] = 1 if and only if a_j belongs to V_i
+   if (printlevel > 0)
+   {
+      ring r = 0,x(1..n),dp;
+      ideal toric;                        // In case I(A) is a complete intersection, we obtain a
+                                        // minimal set of generators
+   }
+
+   for (i = 1; i <= n; i++)
+   {
+      int zero = 0;
+      swap[i] = i;
+      for (j = 1; j <= m; j++)
+      {
+         B[j,i] = A[j,i];
+         if (B[j,i] > 0)
+         {
+            zero++;
+         }
+         if (B[j,i] < 0)
+         {
+            print("// There are negative entries in the matrix");
+            return (0);
+         }
+      }
+      if (zero == 0)
+      {
+         print ("// There is a zero column in the matrix");
+         return (0);
+      }
+   kill zero;
+   }
+
+//--------------------------- preprocessing the input ---------------------------------
+
+
+   int aux, found;
+
+   // We write B in a standard form; this is, for 1 <= i,j <= m, j != i then B[i,j] = 0
+   for (i = 1; i <= m; i++)
+   {
+      j = i;
+      found = 0;
+      while (j <= n)
+      {
+         if (B[i,j] != 0)
+         {
+            k = 1;
+            while ((k == i)||(B[k,j] == 0))
+            {
+               k++;
+               if (k == m+1)
+               {
+                  for (l = 1; l <= m; l++)
+                  {
+                     aux = B[l,j];
+                     B[l,j] = B[l,i];
+                     B[l,i] = aux;
+                  }
+                  aux = swap[j];
+                  swap[j] = swap[i];
+                  swap[i] = aux;
+                  found = 1;
+                  break;
+               }
+            }
+         }
+         if (found == 1)
+         {
+            break;
+         }
+         j++;
+      }
+      if (j == n+1)
+      {
+         print("// There exists an i such that no column in A has the i-th coordinate positive and the rest are 0.");
+            // It is not simplicial
+         return (0);
+      }
+   }
+
+   // Initialisation of variables
+   int numgens = 0;                // number of generators built
+
+   for (i = 1; i <= n; i++)
+   {
+      support[i,i] = 1;
+   }
+
+   intvec ithcolumn, jthcolumn, belong;
+   int numcols = ncols(B);
+   line[numcols] = 0;
+
+   // line[i] = line[j] if and only if B_i and B_j are proportional.
+   // Moreover for i = 1,...,nrows(B) we have that line[i]= i
+   for (i = 1; i <= numcols; i++)
+   {
+      if (line[i] == 0)
+      {
+         for (j = 1; j <= nrows(B); j++)
+         {
+            ithcolumn[j] = B[j,i];
+         }
+         line[i] = i;
+         for (j = i+1; j <= numcols; j++)
+         {
+            for (k = 1; k <= nrows(B); k++)
+            {
+               jthcolumn[k] = B[k,j];
+            }
+            if (Proportional(ithcolumn, jthcolumn))
+            {
+               line[j] = i;
+            }
+         }
+      }
+   }
+
+//----------------- We apply reduction ---------------
+
+   bigint det1, det2;
+   int minim, swapiold, lineiold;
+   int change = 1;
+
+   det1 = cardGroup(B,numcols);
+   while (change == 1)
+   {
+      change = 0;
+      for (i = 1; i <= numcols; i++)
+      {
+         for (j = 1; j <= m; j++)
+         {
+            ithcolumn[j] = B[j,i];
+            B[j,i] = B[j,numcols];
+         }
+         swapiold = swap[i];
+         swap[i] = swap[numcols];
+         lineiold = line[i];
+         line[i] = line[numcols];
+         det2 = cardGroup(B,numcols-1);
+         minim = int(det2/det1);
+         if (lineiold > m)
+         {
+            belong = SBelongSemigroup(minim*ithcolumn,B,numcols-1);
+            if (belong != 0)
+            {
+               // It belongs, we remove the ith column
+               if (printlevel > 0)
+               {
+                  // Create a generator
+                  poly mon1 = x(swapiold)^(minim);
+                  poly mon2 = 1;
+                  for (j = 1; j <= nrows(belong); j++)
+                  {
+                     mon2 = mon2 * x(swap[j])^(belong[j]);
+                  }
+                  toric = toric, mon1-mon2;
+                  kill mon1;
+                  kill mon2;
+               }
+               det1 = det2;
+               change = 1;
+               numgens++;
+               numcols--;
+               i--;
+            }
+         }
+         else
+         {
+            // line[i] <= m
+            intvec semigroup, supportmon;
+            int position;
+            for (j = 1; j <= numcols-1; j++)
+            {
+               if (line[j] == lineiold)
+               {
+                  position = j;
+                  semigroup = semigroup, B[lineiold,j];
+                  supportmon = supportmon, swap[j];
+               }
+            }
+            if (semigroup == 0)
+            {
+               belong = 0;
+            }
+            else
+            {
+               semigroup = semigroup[2..nrows(semigroup)];
+               supportmon = supportmon[2..nrows(supportmon)];
+               belong = oneDimBelongSemigroup(minim*ithcolumn[lineiold],semigroup);
+            }
+            if (belong != 0)
+            {
+               // It belongs, we remove the ith column
+               if (printlevel > 0)
+               {
+                  // We create a generator
+                  poly mon1,mon2;
+                  mon1 = x(swapiold)^(minim);
+                  mon2 = 1;
+                  for (j = 1; j <= nrows(supportmon); j++)
+                  {
+                     mon2 = mon2 * x(supportmon[j])^(belong[j]);
+                  }
+                  toric = toric, mon1-mon2;
+                  kill mon1, mon2;
+               }
+               det1 = det2;
+               numcols--;
+               numgens++;
+               change = 1;
+               if (i <= m)
+               {
+                  // We put again B in standard form
+                  if (position != i)
+                  {
+                     for (j = 1; j <= m; j++)
+                     {
+                        aux = B[j,position];
+                        B[j,position] = B[j,i];
+                        B[j,i] = aux;
+                     }
+                     aux = swap[i];
+                     swap[i] = swap[position];
+                     swap[position] = aux;
+                     aux = line[i];
+                     line[i] = line[position];
+                     line[position] = aux;
+                  }
+               }
+               i--;
+            }
+            kill position;
+            kill semigroup;
+            kill supportmon;
+         }
+         if (belong == 0)
+         {
+            for (j = 1; j <= m; j++)
+            {
+               B[j,i] = ithcolumn[j];
+            }
+            swap[i] = swapiold;
+            line[i] = lineiold;
+         }
+      }
+   }
+
+    // Initialisation of variables
+    minimum[numcols] = 0;
+
+//----------------- We run the first part of the algorithm ---------------
+
+   // Estimation of m_i with i = 1,...,n
+   for (i = 1; i <= numcols; i++)
+   {
+      minimum[i] = StimatesMin(B,i,line,numcols);
+   }
+
+   int nonzero;
+   int stagenumber = 0;
+   change = 1;
+   while (change == 1)
+   {
+      // If for every i,j we have that m_i*B_i != m_j*B_j we leave the while loop
+      change = 0;
+      for (i = 1; (i <= numcols) && (change == 0); i++)
+      {
+         if (minimum[i] != 0)
+         {
+            for (j = i+1; (j <= numcols) && (change == 0); j++)
+            {
+               if ((minimum[j] != 0)&&(line[i] == line[j]))
+               {
+                  // We look for a nonzero entry in B_i
+                  nonzero = 1;
+                  while (B[nonzero,i] == 0)
+                  {
+                     nonzero++;
+                  }
+                  if (minimum[i]*B[nonzero,i] == minimum[j]*B[nonzero,j])
+                  {
+                     // m_i b_i = m_j b_j
+                     numgens++;
+                     stagenumber++;
+                     if (swap[i] <= n)
+                     {
+                        // For k = swap[i], we have that V_k = {b_i}, so m_i b_i belongs to V_k
+                              if (printlevel > 0)
+                        {
+                           poly mon1 = x(swap[i])^(minimum[i]);
+                        }
+                     }
+                     else
+                     {
+                        // We check wether m_i b_i belongs to the semigroup generated by V_k
+                        // where k = swap[i]. All vectors in V_k are proportional to b_i
+                        intvec checkbelong;
+                        int miai;
+                        intvec supporti;
+                        miai = minimum[i]*B[nonzero,i];
+                        for (k = 1; k <= n; k++)
+                        {
+                           if (support[swap[i],k])
+                           {
+                              supporti = supporti, k;
+                              checkbelong[nrows(supporti)-1] = A[nonzero,k];
+                           }
+                        }
+                        // 1-dim belong semigroup
+                        belong = oneDimBelongSemigroup(miai,checkbelong);
+                        if (belong == 0)
+                        {
+                           // It does not belong
+                           print ("// It is NOT a complete intersection");
+                           return (0);
+                        }
+                        if (printlevel > 0)
+                        {
+                           poly mon1 = 1;
+                           // It belongs, we construct a monomial of the new generator
+                           for (k = 1; k < nrows(supporti); k++)
+                           {
+                              mon1 = mon1 * x(supporti[k+1])^(belong[k]);
+                           }
+                        }
+                        kill miai;
+                        kill checkbelong;
+                        kill supporti;
+                     }
+                     if (swap[j] <= n)
+                     {
+                        // For k = swap[j], we have that V_k = {b_j}, so m_j b_j belongs to V_k
+                        if (printlevel > 0)
+                        {
+                           poly mon2 = x(swap[j])^(minimum[j]);
+                           toric = toric, mon1-mon2;
+                           kill mon1;
+                           kill mon2;
+                        }
+                     }
+                     else
+                     {
+                        // We check wether m_j b_j belongs to the semigroup generated by V_k
+                        // where k = swap[j]. All vectors in V_k are proportional to b_j
+                        intvec checkbelong;
+                        int mjaj;
+                        intvec supportj;
+                        nonzero = 1;
+                        while (B[nonzero,j] == 0)
+                        {
+                           nonzero++;
+                        }
+                        mjaj = minimum[j]*B[nonzero,j];
+                        for (k = 1; k <= n; k++)
+                        {
+                           if (support[swap[j],k])
+                           {
+                              supportj = supportj, k;
+                              checkbelong[nrows(supportj)-1] = A[nonzero,k];
+                           }
+                        }
+                        // 1-dim belong semigroup
+                        belong = oneDimBelongSemigroup(mjaj,checkbelong);
+                        if (belong == 0)
+                        {
+                           // It does not belong
+                           print ("// It is NOT a complete intersection");
+                           return (0);
+                        }
+                        if (printlevel > 0)
+                        {
+                           poly mon2 = 1;
+                           // It belongs, we construct the second monomial of the generator
+                           for (k = 1; k < nrows(supportj); k++)
+                           {
+                              mon2 = mon2 * x(supportj[k+1])^(belong[k]);
+                           }
+                           toric = toric,mon1-mon2;
+                           kill mon1;
+                           kill mon2;
+                        }
+                        kill checkbelong;
+                        kill mjaj;
+                        kill supportj;
+                     }
+
+                     // Now we remove b_i, b_j from B and we add gcd(b_i,b_j)
+                     change = 1;
+                     for (k = 1; k <= n; k++)
+                     {
+                        // V_{support.nrows} = V_i + V_j
+                        support[n+stagenumber,k] = support[swap[i],k] + support[swap[j],k];
+                     }
+                     // line[i] does not change
+                     line[j] = line[numcols];
+                     swap[i] = n+stagenumber;
+                     swap[j] = swap[numcols];
+                     k = 1;
+                     while (B[k,i] == 0)
+                     {
+                        k++;
+                     }
+                     int dp;
+                     dp = gcd(B[k,i], B[k,j]);
+                     int factor = B[k,i] div dp;
+                     B[k,i] = dp;
+                     k++;
+                     kill dp;
+                     while (k <= nrows(B))
+                     {
+                        B[k,i] = B[k,i] / factor;
+                        k++;
+                     }
+                     kill factor;
+                     for (k = 1; k <= nrows(B); k++)
+                     {
+                        B[k,j] = B[k,numcols];
+                     }
+                     minimum[j] = minimum[numcols];
+                     numcols--;
+                     // We compute a new m_i
+                     minimum[i] = StimatesMin(B,i,line,numcols);
+                  }
+               }
+            }
+         }
+      }
+   }
+
+//--------------------------- We apply reduction ---------------------------------
+
+   intvec minZ;
+   for (i = 1; i <= n+stagenumber; i++)
+   {
+      minZ[i] = 1;
+   }
+   det1 = cardGroup(B,numcols);
+   int posaux;
+   intvec counters1,counters2;
+
+   while (numgens < n - m)
+   {
+      change = 0;
+      i = nrows(B) + 1;
+      while ((i <= numcols)&&(numgens < n-m))
+      {
+         // The vector we are going to study
+         for (j = 1; j <= nrows(B); j++)
+         {
+            ithcolumn[j] = B[j,i];
+            B[j,i] = B[j,numcols];
+         }
+         posaux = swap[i];
+         swap[i] = swap[numcols];
+
+         numcols--;
+
+         det2 = cardGroup(B,numcols);
+         minim = int(det2/det1);
+
+         if (minim != 1)
+         {
+            // If minimum = 1, we have previously checked that current does not belong to
+            // the semigroup generated by the columns of B.
+
+            for (j = 1; j <= nrows(B); j++)
+            {
+               ithcolumn[j] = ithcolumn[j]*minim;
+            }
+            minZ[posaux] = minim * minZ[posaux];
+            det1 = det2;  // det1 *= minimum
+
+            intvec support1, support2;
+            nonzero = 1;
+            while (ithcolumn[nonzero] == 0)
+            {
+               nonzero++;
+               if (nonzero > nrows(ithcolumn))
+               {
+                  print("// ERROR");
+                  return (0);
+               }
+            }
+            int currentnonzero = ithcolumn[nonzero];
+            intvec B1;
+            for (j = 1; j <= n; j++)
+            {
+               if (support[posaux,j])
+               {
+                  // a_j is proportional to b_i = a_posaux
+                  support1 = support1, j;
+                  B1[nrows(support1)-1] = A[nonzero,j];
+               }
+            }
+            // 1-dim belongsemigroup
+            counters1 = oneDimBelongSemigroup(currentnonzero, B1);
+            kill currentnonzero;
+            kill B1;
+            if (counters1 != 0)
+            {
+               intmat B2[m][n];
+               // It belongs, now we have to check if current belongs to the semigroup
+               // generated by the columns of B2
+               for (j = 1; j <= numcols; j++)
+               {
+                  for (k = 1; k <= n; k++)
+                  {
+                     if (support[swap[j],k])
+                     {
+                        // a_k may not be proportional to b_i = a_posaux
+                        support2 = support2, k;
+                        for (l = 1; l <= m; l++)
+                        {
+                           B2[l,nrows(support2)-1] = A[l,k];
+                        }
+                     }
+                  }
+               }
+               // We write B2 in standard form
+               for (l = 1; l <= m; l++)
+               {
+                  j = l;
+                  found = 0;
+                  while (found == 0)
+                  {
+                     if (B2[l,j] != 0)
+                     {
+                        k = 1;
+                        while ((k == l)||(B2[k,j] == 0))
+                        {
+                           k++;
+                           if (k == m + 1)
+                           {
+                              for (t = 1; t <= m; t++)
+                              {
+                                 jthcolumn[t] = B2[t,j];
+                                 B2[t,j] = B2[t,l];
+                                 B2[t,l] = jthcolumn[t];
+                              }
+                              aux = support2[j+1];
+                              support2[j+1] = support2[l+1];
+                              support2[l+1] = aux;
+                              found = 1;
+                              break;
+                           }
+                        }
+                     }
+                     j++;
+                  }
+               }
+
+               // m-dim belong semigroup
+               counters2 = SBelongSemigroup(ithcolumn, B2, nrows(support2)-1);
+               kill B2;
+
+               if (counters2 != 0)
+               {
+                  // current belongs, we construct the new generator
+                  numgens++;
+                  if (printlevel > 0)
+                  {
+                     poly mon1, mon2;
+                     mon1 = 1;
+                     mon2 = 1;
+                     for (j = 1; j < nrows(support1); j++)
+                     {
+                        mon1 = mon1 * x(support1[j+1])^(counters1[j]);
+                     }
+                     for (j = 1; j < nrows(support2); j++)
+                     {
+                        mon2 = mon2 * x(support2[j+1])^(counters2[j]);
+                     }
+                     toric = toric, mon1-mon2;
+                     kill mon1;
+                     kill mon2;
+                  }
+
+                  if (i != numcols)
+                  {
+                     i--;
+                  }
+                  change = 1; // We have removed a column of B
+
+               }
+            }
+            kill support1,support2;
+         }
+
+         if ((counters1 == 0)||(counters2 == 0)||(minim == 1))
+         {
+            // We swap again the columns in B
+            for (j = 1; j <= m; j++)
+            {
+               B[j,i] = ithcolumn[j];
+            }
+            numcols++;
+            swap[numcols] = swap[i];
+            swap[i] = posaux;
+         }
+
+         if ((i == numcols)&&(change == 0))
+         {
+            print(" // It is NOT a Complete Intersection.");
+            return (0);
+         }
+         i++;
+      }
+   }
+
+   // We have removed all possible columns
+   if (printlevel > 0)
+   {
+      print("// Generators of the toric ideal");
+      toric = simplify(toric,2);
+      toric;
+   }
+   print("// It is a complete intersection");
+   return(1);
+}
+example
+{ "EXAMPLE:"; echo=2;
+   intmat A[2][5] = 60,0,140,150,21,0,60,140,150,21;
+   print(A);
+   printlevel = 0;
+   isCI(A);
+   printlevel = 1;
+   isCI(A);
+   intmat B[3][5] = 12,0,0,1,2,0,10,0,3,2,0,0,8,3,3;
+   print(B);
+   isCI(B);
+   printlevel=0;
+}
+
+
diff --git a/Singular/LIB/classify.lib b/Singular/LIB/classify.lib
new file mode 100644
index 0000000..b3fcf15
--- /dev/null
+++ b/Singular/LIB/classify.lib
@@ -0,0 +1,3039 @@
+///////////////////////////////////////////////////////////////////////////////
+version="version classify.lib 4.0.0.0 Jun_2013 "; // $Id: 95a7d7350e18e7530be8e91119c4c9a1422aa56b $
+category="Singularities";
+info="
+LIBRARY:  classify.lib  Arnold Classifier of Singularities
+AUTHOR:   Kai Krueger, krueger at mathematik.uni-kl.de
+
+OVERVIEW:
+   A library for classifying isolated hypersurface singularities w.r.t. right
+   equivalence, based on the determinator of singularities by V.I. Arnold.
+
+SEE ALSO:  realclassify_lib
+
+PROCEDURES:
+ basicinvariants(f); computes Milnor number, determinacy-bound and corank of
+ classify(f);        normal form of polynomial f determined with Arnold's method
+ corank(f);          computes the corank of f (i.e. of the Hessian of f)
+ Hcode(v);           coding of intvec v acoording to the number repetitions
+ init_debug([n]);    print trace and debugging information depending on int n
+ internalfunctions();display names of internal procedures of this library
+ milnorcode(f[,e]);  Hilbert polynomial of [e-th] Milnor algebra coded with Hcode
+ morsesplit(f);      residual part of f after applying the splitting lemma
+ quickclass(f)       normal form of f determined by invariants (milnorcode)
+ singularity(s,[]);  normal form of singularity given by its name s and index
+ A_L(s/f);           shortcut for quickclass(f) or normalform(s)
+ normalform(s);      normal form of singularity given by its name s
+ debug_log(lev,[]);  print trace and debugging information w.r.t level>@DeBug
+ swap(a,b);          swaps the arguments
+ modality(f);        modality of the singularity
+ complexSingType(f); complex type of the singularity as a string
+ prepRealclassify(f);
+                     the modality and the complex type of the singularity at
+                     once
+           (parameters in square brackets [] are optional)
+";
+
+LIB "inout.lib";
+LIB "elim.lib";
+LIB "sing.lib";
+LIB "makedbm.lib";
+
+///////////////////////////////////////////////////////////////////////////////
+proc classify_init
+{
+  string s;
+  link l="DBM:r NFlist";
+  s = read(l,"VERSION");
+  if (s == "" ) {
+    if (printlevel > 0)
+    {
+      "(classify.lib): Need to create database...";
+    }
+    create_sing_dbm();
+  }
+  close(l);
+  l="DBM:r NFlist";
+  s = read(l,"VERSION");
+  //"(classify.lib): Creation done. Current version:", s;
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc classify (poly f_in)
+"USAGE:    classify(f);  f=poly
+COMPUTE:  normal form and singularity type of f with respect to right
+          equivalence, as given in the book \"Singularities of differentiable
+          maps, Volume I\" by V.I. Arnold, S.M. Gusein-Zade, A.N. Varchenko
+RETURN:   normal form of f, of type poly
+REMARK:   This version of classify is only beta. Please send bugs and
+          comments to: \"Kai Krueger\" <krueger at mathematik.uni-kl.de> @*
+          Be sure to have at least @sc{Singular} version 1.0.1. Updates can be
+          found at: @*
+          URL=http://www.mathematik.uni-kl.de/~krueger/Singular/
+NOTE:     type init_debug(n); (0 <= n <= 10) in order to get intermediate
+          information, higher values of n give more information.
+          The proc creates several global objects with names all starting
+          with @, hence there should be no name conflicts.
+EXAMPLE:  example classify; shows an example"
+{
+//---------------------------- initialisation ---------------------------------
+  poly   f_out;
+  int    n, i, corank, show_nf;
+  string s2;
+  list   v;
+  def ring_ext = basering;
+
+  // Namespaces:
+  if(defined(A_Z)==0) { proc A_Z = general_lib::A_Z; export A_Z; }
+  init_debug();                    // initialize trace/debug mode
+  if(checkring()) { return(f_in); }
+  n = nvars(basering);
+  show_nf  = 1;                // return normal form if set to '1'
+
+  // define new ring
+  ring ring_top=char(basering),(x(1..n)),(c,ds);
+
+  map conv_ext2top=ring_ext,maxideal(1);
+
+  if(defined(@ringdisplay)!=0) { kill @ringdisplay; }
+  string @ringdisplay = "ring_ext";
+  export @ringdisplay;
+
+  v = Klassifiziere(conv_ext2top(f_in));
+  if(typeof(v[1])=="poly") {
+     poly f_out = v[1];
+     s2 = v[2];          // s2: Typ des Polynoms f z.b: E[18]
+     corank = v[3];
+  }
+  else {
+     s2="NoClass";
+  }
+
+//---------------- collect results and create return-value --------------------
+  if( s2=="error!" || s2=="NoClass") {
+      setring ring_ext;
+      return(f_in);
+  }
+
+  if(show_nf==1) {
+    poly f_nf = normalform(s2);
+    for(i=corank+1;i<=n;i=i+1) { f_nf = f_nf + x(i)^2; }
+    debug_log(2, "Normal form NF(f)=", f_nf);
+  }
+  if(corank>1) { for(i=corank+1;i<=n;i=i+1) { f_out = f_out + x(i)^2; } }
+  setring ring_ext;
+  map conv_top2ext=ring_top,maxideal(1);
+
+  if(show_nf == 1) { return(conv_top2ext(f_nf)); }
+  else { return(conv_top2ext(f_out)); }
+}
+example
+{"EXAMPLE"; echo=2;
+   ring r=0,(x,y,z),ds;
+   poly f=(x2+3y-2z)^2+xyz-(x-y3+x2*z3)^3;
+   classify(f);
+   init_debug(3);
+   classify(f);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static proc Klassifiziere (poly f)
+{
+//--------------------------- initialisation ----------------------------------
+  string s1;
+  int    n, cnt, corank_f, K, Mu;
+  list   v, cstn;
+  map    PhiG;
+  def ring_top = basering;
+
+  n = nvars(basering);    // Zahl der Variablen des aktuellen Rings.
+  PhiG = ring_top, maxideal(1);
+  cstn[4] = PhiG;
+  if( defined(@ringdisplay) == 0)
+  {
+    string @ringdisplay;               // Define always 'ringdisplay' to be
+    export @ringdisplay;               // able to run 'Show(f)'
+  }
+  @ringdisplay = "setring RingB;";
+  if(defined(RingB)!=0) { kill RingB; }
+  execute ("ring RingB="+charstr(basering)+",("+A_Z("x", n)+"),(c,ds);");
+  export RingB;
+  setring ring_top;
+
+//---------------------- compute basciinvariants ------------------------------
+  if(jet(f,0) != 0 )
+  {
+    cstn[1] = corank(f); cstn[2]=-1; cstn[3]=1;
+    return(printresult(1, f, "a unit", cstn, -1));
+  }
+
+  debug_log(1, "Computing Basicinvariants of f ...");
+  K, Mu, corank_f = basicinvariants(f);
+  debug_log(0, "About the singularity :");
+  debug_log(0, "          Milnor number(f)   = "+string(Mu));
+  debug_log(0, "          Corank(f)          = "+string(corank_f));
+  debug_log(0, "          Determinacy       <= "+string(K));
+  cstn[1] = corank_f;
+  cstn[2] = Mu;
+  cstn[3] = K;
+
+  if( Mu == 0)
+  {
+    cstn[1]=1; cstn[3]=1;
+    return(printresult(1, f, "A[0]", cstn, 0));
+  }
+
+  if(Mu<0)
+  {
+    debug_log(0, "The Milnor number of the function is infinite.");
+    debug_log(0, "The singularity is not in Arnolds list.");
+    return(printresult(1, 1, "error!", cstn, -1));
+  }
+
+  f = jet(f, K);
+  v = HKclass(milnorcode(f));
+  if(v[2]>0) { debug_log(0, "Guessing type via Milnorcode: ", v[1]);}
+  else
+  {
+    debug_log(0, "Hilbert polynomial not recognised. Milnor code = ",
+              milnorcode(f));
+  }
+  debug_log(0, "");
+  debug_log(0, "Computing normal form ...");
+
+//------------ step 1, classification according to corank(f) ------------------
+  if(corank_f == 0)
+  {
+    return(printresult(2, f, "A["+string(Mu)+"]", cstn, 0));
+  }
+  if(corank_f == 1)
+  {
+    return(printresult(2, f, "A["+string(Mu)+"]", cstn, 0));
+  }
+  cstn[4] = 0;
+  if(corank_f == 2) { return(Funktion1bis(f, cstn)); }
+  if(corank_f == 3) { return(Funktion1bis(f, cstn)); }
+  return(printresult(105, f, "NoClass", cstn, -1));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static proc Funktion1bis (poly f, list cstn)
+{
+//---------------------------- initialisation ---------------------------------
+   def ring_top=basering;
+   poly   g;
+   int    n, corank, K;
+   map    conv, PhiG;
+   string s1;
+   list   v_res, v_class, v, iv;
+
+   corank = cstn[1];
+   K = cstn[3];
+   n = nvars(basering);
+
+//-------------------- apply morsesplit if n>corank ---------------------------
+   if( n > corank) {
+     debug_log(0,
+      "I have to apply the splitting lemma. This will take some time....:-)");
+     v_res = Morse(f, K, corank, 0);
+     g = v_res[1];
+     PhiG = v_res[2];
+
+     conv = ReOrder(g);
+     g = conv(g);
+     PhiG = conv(PhiG);
+
+     if(defined(RingB) != 0 ) { kill RingB; }
+     ring ring_rest=char(basering),(x(1..corank)),(c,ds);
+
+     map MapReduce=ring_top,maxideal(1);
+     poly G = MapReduce(g);
+     map PhiG=ring_top,maxideal(1);// Konstruiere Id auf r
+     PhiG = MapReduce(PhiG);
+
+     execute("ring RingB="+charstr(basering)+",("+A_Z("x",corank)+"),(c,ds);");
+     export RingB;
+     setring ring_rest;
+   }
+   else {
+     ring ring_rest=char(basering),(x(1..corank)),(c,ds);
+     map  PhiG=ring_top,maxideal(1);
+     poly G = PhiG(f);
+   }
+
+//--------------------- step 1 of Arnold now finished -------------------------
+    map phi = ring_rest,maxideal(1);
+    cstn[4] = phi;
+    if(corank == 2) { v_class = Funktion3(G, cstn); }
+    else {
+      if(corank == 3) { v_class = Funktion50(G, cstn); }
+      else { v_class = printresult(1, f, "error!", cstn, -1); }
+    }
+//-------------------------- classification done ------------------------------
+    if(typeof(v_class[1])!="poly") {
+       return(v);
+    }
+    poly f_result = v_class[1];
+    v[2] = v_class[2];
+    v[3] = v_class[3];
+    map Phi = v_class[4];
+    PhiG = Phi(PhiG);
+    setring ring_top;
+    if(defined(conv)!=0) { kill conv; }
+    map conv=ring_rest,maxideal(1);
+    v[1] = conv(f_result);
+    return(v);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static proc Funktion3 (poly f, list cstn)
+{
+//---------------------------- initialisation ---------------------------------
+    poly f3 = jet(f, 3);
+    ideal Jf;
+    int Dim, Mult, Mu;
+    debug_log(1, "Step 3");
+
+    if( f3 == 0 ) { return(Funktion13(f, cstn)); }
+
+    // f3 ~ x3 , x2y+y3 , x2y
+    Jf = std(jacob(f3));
+    Dim = dim(Jf);
+    if(Dim == 0) { return(printresult(4, f, "D[4]", cstn, 0)); }
+
+    Mult = mult(Jf);
+    Mu = cstn[2];
+    if(Dim == 1) {
+      if( Mult == 1) { return(printresult(5,f,"D["+string(Mu)+"]", cstn, 0)); }
+      if( Mult == 2) { return(Funktion6(f, cstn));}         // series E,J
+      debug_log(0, "dimension 1 und deg != 1, 2 => error, ",
+                        "this should never occur");
+      return(printresult(3, f, "error!", cstn, -1));
+      // Should never reach this line
+    }
+    // Should never reach this line
+    return(printresult(3, f, "error!", cstn, -1));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static proc Funktion6 (poly f, list cstn)
+{ // Arnold's steps 6-12
+//---------------------------- initialisation ---------------------------------
+    poly   f3, fk;
+    ideal  JetId, Jf;
+    int    k, Dim, Mult, n, Mu;
+    map    PhiG, Phi;
+    intvec RFlg;
+    list   v;
+
+    def ring_top=basering;
+    f3   = jet(f, 3);            // 3-Jet von f
+    n    = nvars(basering);
+    Mu   = cstn[2];
+    PhiG = cstn[4];
+    k    = 1;
+    debug_log(1, "   Step 6");
+
+    RFlg = GetRf(f, n);
+    v    = Faktorisiere(f, f3, 3, 1, RFlg);
+    f    = v[1];
+    Phi  = v[2];
+    PhiG = Phi(PhiG);
+    cstn[4] = PhiG;
+
+//---------------------------- begin of loop ----------------------------------
+    while( (6*k) <= Mu ) {
+      JetId = x(1)^3+x(2)^(3*k);
+      fk    = jet(f, 3*k, weight(JetId));
+      //--------------------------- step 6(k) ---------------------------------
+      if( fk == Coeff(fk,x(1), x(1)^3)*x(1)^3 ) {
+        JetId = x(1)^3+x(2)^(3*k+1);           // check jet x3,y3k+1  : E[6k]
+        fk    = jet(f, 3*(3*k+1), weight(JetId));
+        if( Coeff(fk,x(2),x(2)^(3*k+1)) != 0 ) {
+          return(printresult(7, f, "E["+string(6*k)+"]", cstn, k-1));
+        }
+
+        JetId = x(1)^3+x(1)*x(2)^(2*k+1);      // check jet x3,xy2k+1 : E[6k+1]
+        fk    = jet(f, 3*(2*k+1), weight(JetId));
+        if( Coeff(fk, x(1)*x(2), x(1)*x(2)^(2*k+1)) != 0 ) {
+          return(printresult(8, f,"E["+string(6*k+1)+"]", cstn, k-1));
+        }
+
+        JetId = x(1)^3+x(2)^(3*k+2);           // check jet x3,y3k+1  : E[6k+2]
+        fk    = jet(f, 3*(3*k+2), weight(JetId));
+        if( Coeff(fk,x(2),x(2)^(3*k+2)) != 0 ) {
+          return(printresult(9, f,"E["+string(6*k+2)+"]", cstn, k-1));
+        }
+
+        //------------------------- step 10(k) --------------------------------
+        k++;
+        JetId = x(1)^3+x(2)^(3*k);
+        fk    = jet(f, 3*k, weight(JetId));
+        Jf    = std(jacob(fk));
+        Dim   = dim(Jf);
+
+        if(Dim==0) { return(printresult(11,f,"J["+string(k)+",0]",cstn,k-1)); }
+        Mult = mult(Jf);
+        if( Dim ==1  && Mult==1) {
+          return(printresult(12,f,"J["+string(k)+","+string(Mu - 6*k +2)+"]",
+                 cstn, k-1));
+        }
+        if( Dim == 1  && Mult == 2) {
+          if(Coeff(fk, x(2), x(2)^(3*k)) != 0) {
+            v    = Faktorisiere(f, fk, 3, k, RFlg);
+            f    = v[1];
+            Phi  = v[2];
+            PhiG = Phi(PhiG);
+            cstn[4] = PhiG;
+          }
+        }
+      }
+    }
+    // Should never reach this line
+    return(printresult(6, f, "error!", cstn, -1));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static proc Funktion13 (poly f, list cstn)
+{
+//---------------------------- initialisation ---------------------------------
+    poly f4;
+    ideal Jf;
+    int Dim, Mult, Mu;
+
+    debug_log(1, "   Step 13");
+    Mu = cstn[2];
+    f4 = jet(f, 4);
+    if( f4 == 0 ) { return(Funktion47(f, cstn)); }
+
+    // f4 ~ x4+ax2y2+y4, x4+x2y2, x2y2, x3y, x4
+    Jf  = std(jacob(f4));
+    Dim = dim(Jf);
+
+    if(Dim==0) { return(printresult(14,f,"X[9] = X[1,0] = T[2,4,4]",cstn,1)); }
+    Mult = mult(Jf);
+    if( Dim == 1) {
+      if( Mult == 1 ) {
+        return(printresult(15, f,
+              "X[1,"+string(Mu-9)+"] = T[2,4,"+string(Mu-5)+"]", cstn, 1));
+      }
+      if( Mult == 2 ) {
+        Jf = Jf, jacob(Jf);
+        Jf = std(Jf);
+        Dim = dim(Jf);
+        if(Dim==0){return(printresult(16,f,"Y[1,p,q] = T[2,4+p,4+q]",cstn,1));}
+        if( Dim == 1 ) { return(Funktion17(f, cstn)); }
+      }
+      if( Mult == 3 ) { return(Funktion25(f, cstn)); }
+    }
+    // Should never reach this line
+    return(printresult(13, f, "error!", cstn, -1));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static proc Funktion17 (poly f, list cstn)
+{ // Analog zu Fumktion 6, Kombination 17-24
+//---------------------------- initialisation ---------------------------------
+    poly  fk, ft;
+    ideal JetId, Jf;
+    int   p, Dim, Mult, Mu;
+    list  v;
+    map   PhiG, Phi;
+
+    def ring_top=basering;
+    debug_log(1, "      Step 17");
+    Mu   = cstn[2];
+    PhiG = cstn[4];
+    fk   = jet(f, 4);
+    p    = 1;
+
+//---------------------------- begin of loop ----------------------------------
+    while( 3*p<= Mu) {
+      debug_log(1, "         Step 18("+string(p)+")");
+      v   = Isomorphie_s17(f, fk, p, 1);
+      f, Phi  = v[1..2];
+      PhiG    = Phi(PhiG);
+      cstn[4] = PhiG;
+
+      if ( p>1) {
+        JetId = x(1)^3*x(2) + x(2)^(3*p);
+        fk = jet(f, 3*p, weight(JetId));
+      }
+      //--------------------------- step 18(p) --------------------------------
+      JetId = x(1)^3*x(2) + x(2)^(3*p+2);     // check jet x3y,y3k+2  : Z[6p+5]
+      fk = jet(f, 3*(3*p+2), weight(JetId));
+      if( Coeff(fk, x(2), x(2)^(3*p+2)) != 0) {
+        return(printresult(19,f, "Z["+string(6*p+5)+"]", cstn, p));
+      }
+
+      JetId = x(1)^3*x(2)+x(1)*x(2)^(2*p+2);  // check jet x3y,xy2k+2 : Z[6p+6]
+      fk = jet(f, 2*(3*p+2)+1, weight(JetId));
+      if( Coeff(fk, x(1)*x(2), x(1)*x(2)^(2*p+2)) != 0) {
+        return(printresult(20, f, "Z["+string(6*p+6)+"]", cstn, p));
+      }
+
+      JetId = x(1)^3*x(2) + x(2)^(3*p+3);     // check jet x3y,y3k+3  : Z[6p+7]
+      fk = jet(f, 3*(3*p+3), weight(JetId));
+      if( Coeff(fk, x(2), x(2)^(3*p+3)) != 0) {
+        return(printresult(21, f, "Z["+string(6*p+7)+"]", cstn, p));
+      }
+
+      //---------------------------- step 22 ----------------------------------
+      p = p+1;
+      JetId = x(1)^3*x(2) + x(2)^(3*p+1);
+      fk   = jet(f, 3*p+1, weight(JetId));
+      ft   = Teile(fk, x(2));
+      Jf   = std(jacob(ft));
+      Dim  = dim(Jf);
+      Mult = mult(Jf);
+      if(Dim==0) { return(printresult(23,f,"Z["+string(p-1)+",0]", cstn, p)); }
+      if( Mult == 1 ) {
+         return(printresult(24, f, "Z["+string(p-1)+","+string(Mu-3-6*p)+"]",
+                cstn, p));
+      }
+    }
+    // Should never reach this line
+    return(printresult(17, f, "error!", cstn, -1));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static proc Funktion25 (poly f, list cstn)
+{ // Analog zu Fumktion 6, Kombination 25-46
+//---------------------------- initialisation ---------------------------------
+    poly   fk, ft;
+    ideal  JetId, Jf;
+    int    k, Dim, Mult, Mu;
+    map    PhiG, Phi;
+    intvec RFlg;
+    list   v;
+    def ring_top=basering;
+
+    debug_log(1, "      Step 25");
+    Mu   = cstn[2];
+    PhiG = cstn[4];
+    fk   = jet(f, 4);
+    k    = 1;
+    RFlg = GetRf(f, 2);
+
+//---------------------------- begin of loop ----------------------------------
+    while (k<Mu) {
+      v    =  Faktorisiere(f, fk, 4 , k, RFlg);
+      f, Phi  = v[1..2];
+      PhiG    = Phi(PhiG);
+      cstn[4] = PhiG;
+
+      //--------------------------- step 26(k) --------------------------------
+      JetId = x(1)^4 + x(2)^(4*k+1);          // check jet x4,y4k+1  : W[12k]
+      fk    = jet(f, 4*(4*k+1), weight(JetId));
+      if( Coeff(fk, x(2), x(2)^(4*k+1)) != 0) {
+        return(printresult(27, f, "W["+string(12*k)+"]", cstn, 3*k-2));
+      }
+
+      JetId = x(1)^4 + x(1)*x(2)^(3*k+1);     // check jet x4,xy3k+1 : W[12k+1]
+      fk    = jet(f, 4*(3*k+1), weight(JetId));
+      if( Coeff(fk, x(1)*x(2), x(1)*x(2)^(3*k+1)) != 0) {
+        return(printresult(28, f, "W["+string(12*k+1)+"]", cstn, 3*k-2));
+      }
+
+      //--------------------------- step 29(k) --------------------------------
+      JetId = x(1)^4 + x(2)^(4*k+2);
+      fk    = jet(f, 2*(4*k+2), weight(JetId));
+      if( Coeff(fk, x(2), x(2)^(4*k+2)) != 0) {
+        Jf  = std(jacob(fk));
+        Dim = dim(Jf);
+        if(Dim==0) {return(printresult(30,f,"W["+string(k)+",0]",cstn,3*k-1));}
+        if(Dim==1) {
+           return(printresult(32, f,
+                  "W#["+string(k)+","+string(Mu-12*k-3)+"]", cstn, 3*k-1));
+        }
+        return(printresult(29, f, "error!", cstn, -1));
+      }
+      else {
+        // x^4 oder x^2(x^2+x(2)^2k+1)
+        ft  = Teile(fk, x(1)^2);
+        Jf  = std(jacob(ft));
+        Dim = dim(Jf);
+        if( Dim == 0 ) {
+           return(printresult(31, f, "W["+string(k)+","+string(Mu-12*k-3)+"]",
+                  cstn, 3*k-1));
+        }
+        if( Dim != 1 ) { return(printresult(29, f, "error!", cstn, -1)); }
+
+        //-------------------------- step 33(k) -------------------------------
+        JetId = x(1)^4 + x(1)*x(2)^(3*k+2);   // check jet x4,xy3k+2 : W[12k+5]
+        fk    = jet(f, 4*(3*k+2), weight(JetId));
+        if( Coeff(fk, x(1)*x(2), x(1)*x(2)^(3*k+2)) != 0) {
+          return(printresult(34, f,"W["+string(12*k+5)+"]", cstn, 3*k-1));
+        }
+
+        JetId = x(1)^4 + x(2)^(4*k+3);        // check jet x4,y4k+3  : W[12k+6]
+        fk    = jet(f, 4*(4*k+3), weight(JetId));
+        if( Coeff(fk, x(2), x(2)^(4*k+3)) != 0){
+          return(printresult(35, f,"W["+string(12*k+6)+"]", cstn, 3*k-1));
+        }
+
+        //-------------------------- step 36(k) -------------------------------
+        k = k+1;
+        JetId = x(1)^4 + x(2)^(4*k);
+        fk    = jet(f, (4*k), weight(JetId));
+        Jf    = std(jacob(fk));
+        Dim   = dim(Jf);
+        Mult  = mult(Jf);
+        if(Dim==0) {return(printresult(37,f,"X["+string(k)+",0]",cstn,3*k-1));}
+        if(Dim==1) {
+          if(Mult==1) {
+             return(printresult(38, f,"X["+string(k)+","+string(Mu-12*k+3)+"]",
+                    cstn, 3*k-1));
+          }
+          if(Mult==2) {
+            ft  = Teile(fk, x(1)^2);
+            Jf  = std(jacob(ft));
+            Dim = dim(Jf);
+            if( Dim == 0) { return(Funktion40(f, cstn, k)); }
+            if( Dim == 1) {
+               return(printresult(39, f, "Y["+string(k)+",r,s]", cstn,3*k-1));
+            }
+          }
+          if(Mult!=3) {
+            return(printresult(36, f, "error!", cstn, -1)); }
+        }
+        else { return(printresult(36, f, "error!", cstn, -1)); }
+      }
+    }  // Ende der While-Schleife
+    // Should never reach this line
+    return(printresult(25, f, "error!", cstn, -1));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static proc Funktion40 (poly f, list cstn, int k)
+{
+//---------------------------- initialisation ---------------------------------
+    int    r, kr, rr, sr, oldDebug;
+    poly   fk, f2, a, b, c;
+    ideal  JetId, Jfsyz;
+    string Typ, RestRing, s1;
+    list   v1, v2;
+    def ring_top=basering;
+
+    debug_log(1, "         Step 40" );
+
+//------------------------------ compute f2 -----------------------------------
+    JetId = x(1)^4 + x(2)^(4*k);
+    fk  = jet(f, (4*k), weight(JetId));
+    f2  = -fk / x(1)^3;
+    Jfsyz = f - fk, x(1)^3, f2;
+    matrix Mat = matrix(syz(Jfsyz));
+    a = Mat[2,1] / Mat[1,1] - Mat[2,2];
+    b = - Mat[3,1] / Mat[1,1] + Mat[3,2];
+    ring tmp_ring=char(basering), (x(1),x(2)),(c,ds);
+    map map_top2tmp=ring_top,maxideal(1);
+    oldDebug = @DeBug;
+    init_debug(-1);
+//------------------------------ classify f2 ----------------------------------
+    v1=Klassifiziere(map_top2tmp(b));
+    init_debug(oldDebug);
+    Typ = v1[2];
+    v2 = DecodeNormalFormString(Typ);
+    Typ, kr, rr, sr = v2[1..4];
+    r   = kr-k;
+    setring ring_top;
+    if( Typ == "E[6k]" ) {
+       return(printresult(42, f, "Z["+string(k)+","+string(12*k+6*r-1)+"]",
+              cstn, 3*k+r-2));
+    }
+    if( Typ == "E[6k+1]" ) {
+       return(printresult(43, f, "Z["+string(k)+","+string(12*k+6*r)+"]",
+              cstn, 3*k+r-2));
+    }
+    if( Typ == "E[6k+2]" ) {
+       return(printresult(44, f, "Z["+string(k)+","+string(12*k+6*r+1)+"]",
+              cstn, 3*k+r-2));
+    }
+    if( Typ == "J[k,0]" ) {
+       return(printresult(45, f, "Z["+string(k)+","+string(r)+",0]",
+              cstn, 3*k+r-2));
+    }
+    if( Typ == "J[k,r]" ) {
+       return(printresult(46,f,"Z["+string(k)+","+string(r)+","+string(rr)+"]",
+              cstn, 3*k+r-2));
+    }
+    // Should never reach this line
+    return(printresult(40, f, "error!", cstn, -1));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static proc Funktion50 (poly f, list cstn)
+{
+//---------------------------- initialisation ---------------------------------
+    poly  f3;
+    ideal Jf, Jf1, Jf2;
+    int   Dim, Mult, Mu;
+    debug_log(1, "Step 50");
+
+    f3 = jet(f, 3);
+    if( f3 == 0 ) { return(printresult(104, f, "NoClass", cstn, -1)); }
+
+    // f3 ~
+    Jf1  = jacob(f3);
+    Jf   = std(Jf1);
+    Dim  = dim(Jf);
+    Mult = mult(Jf);
+    Mu   = cstn[2];
+
+    if(Dim == 0) {
+       return(printresult(51, f, "P[8] = T[3,3,3]", cstn, 1));
+    } // x3 + y3 + z3 + axyz
+    if(Dim == 1) {
+      if (Mult == 1) {
+        return(printresult(52, f,"P["+string(Mu)+"] = T[3,3,"+string(Mu-5)+"]",
+               cstn, 1));
+      } // x3 + y3 + xyz
+      if(Mult == 2) {
+        Jf2 = wedge(jacob(Jf1),3-Dim), Jf1;
+        Jf2 = std(Jf2);
+        Dim = dim(Jf2);
+        if (Dim==0) { return(printresult(54,f,"R[p,q] = T[3,p,q]", cstn, 1)); }
+        if (Dim==1) { return(Funktion58(f, cstn)); }  // x3 + yz2
+      }
+      if(Mult == 3) {
+        Jf2 = wedge(jacob(Jf1),3-Dim), Jf1;
+        Jf2 = std(Jf2);
+        Dim = dim(Jf2);
+        if(Dim == 0) { return(printresult(56, f, "T[p,q,r]", cstn, 1)); }
+        if(Dim == 1) { return(Funktion66(f, cstn)); }   // x2z + yz2
+      }
+      if(Mult == 4) { return(Funktion82(f, cstn)); }    // x3 + xz2
+    }
+    if(Dim == 2) {
+      if(Mult == 1) { return(Funktion97(f, cstn)); }    // x2y
+      if(Mult == 2) { return(printresult(103,f,"NoClass", cstn, -1));}
+    }
+
+    // Should never reach this line
+    return(printresult(50, f, "error!", cstn, -1));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static proc Funktion58 (poly fin, list cstn)
+{
+//---------------------------- initialisation ---------------------------------
+    poly  f, f3, a, b, phi, b1, b2, b3, fa, fb, fc;
+    ideal B, Jf3, J1, J2, S, Jfsyz;
+    int   kx, ky, kz;
+    string tp;
+    matrix M[2][3];
+    matrix C[2][3], D;
+    list v;
+    map  PhiG, VERT;
+    def ring_top=basering;
+    debug_log(1, "   Step 58");
+
+    f    = fin;
+    f3   = jet(f, 3);
+    PhiG = cstn[4];
+    tp   = "Nix";
+    kx   = 1;     // Koordinate x
+    ky   = 2;     // Koordinate y
+    kz   = 3;     // Koordinate z
+    B    = maxideal(1);     // ideal fuer Abbildungen
+    Jf3  = jacob(f3);
+    S    = sat(Jf3, maxideal(1))[1];
+    J1   = diff(S[1], x(kx)), diff(S[1], x(ky)), diff(S[1], x(kz)),
+           diff(S[2], x(kx)), diff(S[2], x(ky)), diff(S[2], x(kz));
+    M    = J1;
+    J2   = minor(M, 2), S;
+
+    //------------------ determine coordinate named 'x' -----------------------
+    S  = sat(J2, maxideal(1))[1];
+    J1 = Coeff(S[1], x(1), x(1)), Coeff(S[1], x(2), x(2)),
+          Coeff(S[1], x(3), x(3)), Coeff(S[2], x(1), x(1)),
+          Coeff(S[2], x(2), x(2)), Coeff(S[2], x(3), x(3));
+    C  = J1;
+    D  = syz(C);
+    kill C;
+
+    b1 = D[1,1];
+    b2 = D[2,1];
+    b3 = D[3,1];
+
+    debug_log(6, "f3,s1=", Show(f3));
+    if( b1 != 0) {
+      VERT=ring_top,-1*b1*x(1), -1*b2*x(1)+x(2), -1*b3*x(1) + x(3);
+      kx=1; ky=2; kz=3;
+    }
+    else {
+      if( b2 != 0) {
+        VERT=ring_top, x(1) + -1*b1*x(2), -1*b2*x(2), -1*b3*x(2) + x(3);
+        kx=2; ky=1; kz=3;
+      }
+      else {
+        if( b3 != 0) {
+          VERT=ring_top,x(1) + -1*b1*x(3), x(2) + -1*b2*x(3), -1*b3*x(3);
+          kx=3; ky=1; kz=2;
+        }
+      }
+    }
+    f       = VERT(f);
+    PhiG    = VERT(PhiG);
+    cstn[4] = PhiG;
+    debug_log(6, VERT);
+    f3 = jet(f,3);
+    debug_log(6, "f3,s2=", Show(f3));
+
+    //---------------- compute f_2 such that j3f = xf_2+f_3 -------------------
+    debug_log(6, "1) x=", kx, "  y=", ky, "  z=", kz );
+    matrix C = Coeffs(f3, x(kx));
+    fb=C[2,1];  // Coeff von x^1
+    fc=C[1,1];  // Coeff von x^0
+    if(diff(fb, x(ky)) != 0) {
+      Jfsyz = fb, diff(fb, x(ky));
+      matrix Mat = matrix(syz(Jfsyz));
+      B = maxideal(1);     // setze Abbildungs-ideal
+      if( nrows(Mat) == 2) {
+        poly Relation = -2 * Mat[2,1] / Mat[1,1];
+        b = Coeff(Relation, x(kz), x(kz));
+        B[rvar(x(ky))] = x(ky)-b*x(kz);
+      }
+      else {
+        Jfsyz = fb, diff(fb, x(kz));
+        Mat = matrix(syz(Jfsyz));
+        poly Relation = -2 * Mat[2,1];
+        a = Coeff(Relation, x(ky), x(ky));
+        B[rvar(x(kz))] = x(kz)-a*x(kz);
+        ky, kz = swap(ky, kz);
+      }
+      VERT = ring_top, B;
+      f    = VERT(f);
+      PhiG = VERT(PhiG);
+      cstn[4] = PhiG;
+      f3 = jet(f,3);
+      kill Mat;
+    }
+    else { ky,kz = swap(ky,kz); }
+
+    //------- compute tschirnhaus for 'z' and get f3=f_1(x,y,z)y^2+z^3 --------
+    C    = Coeffs(f3, x(kx));
+    fb   = C[2,1];  // Coeff von x^1
+    fc   = C[1,1];  // Coeff von x^0
+    v    = tschirnhaus(fc, x(kz));
+    fc, VERT = v[1..2];
+    f    = VERT(f);
+    PhiG = VERT(PhiG);
+    cstn[4] = PhiG;
+    f3 = jet(f,3);
+
+    //------------------- compute f_1 and get f3=xy^2+z^3 ---------------------
+    fb = (f3 - 1*(Coeffs(f3, x(kz))[4,1])*x(kz)^3)/(x(ky)^2);
+    fc=(x(kx)-1*(Coeffs(fb,x(ky))[2,1])*x(ky)-1*(Coeffs(fb,x(kz))[2,1])*x(kz));
+    fa = Coeffs(fb, x(kx))[2,1];
+    if ( fa != 0 ) {
+      B = maxideal(1);
+      B[rvar(x(kx))] = fc / fa;
+      VERT = ring_top, B;
+      f    = VERT(f);
+      PhiG = VERT(PhiG);
+      cstn[4] = PhiG;
+      f3   = jet(f,3);
+    }
+
+    //--------------------- permutation of x,y,z  -----------------------------
+    if(Coeffs(f3, x(1))[4,1]!=0) {
+      kx=1;
+      if(Coeffs(f3, x(2))[3,1]==0) { ky=2; kz=3; }
+      else { ky=3; kz=2; }
+    }
+    else {
+      if(Coeffs(f3, x(2))[4,1]!=0) {
+        kx=2;
+        if(Coeffs(f3, x(3))[3,1]==0) { ky=3; kz=1; }
+        else { ky=1; kz=3; }
+      }
+      else {
+        kx=3;
+        if(Coeffs(f3, x(1))[3,1]==0) { ky=1; kz=2; }
+        else { ky=2; kz=1; }
+      }
+    }
+    VERT = ring_top, x(kx), x(ky), x(kz);
+    f    = VERT(f);
+    PhiG = VERT(PhiG);
+    cstn[4] = PhiG;
+    f3   = jet(f,3);
+    return(Funktion59(f, cstn));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static proc Funktion59 (poly f, list cstn)
+{
+//---------------------------- initialisation ---------------------------------
+    poly   phi, fr, fk, alpha, beta, f_tmp;
+    ideal JetId;
+    int    p, Dim, Mult, Mu;
+    string tp;
+    list   v;
+    map    PhiG, Phi;
+    intvec w, RFlg;
+    def ring_top=basering;
+    debug_log(1, "      Step 59");
+
+    Mu   = cstn[2];
+    PhiG = cstn[4];
+    tp   = "Nix";
+    p    = 1;
+    phi  = jet(f,3);
+    fr   = f - phi;
+    RFlg = 1,2,3;
+    alpha = coeffs(fr, x(1))[1,1];
+    beta = (fr - alpha) / x(1);
+    debug_log(3, "f    = ", Show(f));
+    debug_log(3, "fr   = ", Show(fr));
+    debug_log(3, "alpha= ", Show(alpha));
+    debug_log(3, "beta = ", Show(beta));
+
+//---------------------------- begin of loop ----------------------------------
+    while(6*p<Mu) {
+      JetId = x(2)^(3*p+1);
+      JetId = phi + x(2)^(3*p+1);
+      //--------------------------- step 59(k) --------------------------------
+      w     = weight(JetId);
+      fk    = jet(fr, 3*w[1], w);
+      if(fk!=0) { return(printresult(60,f, "Q["+string(6*p+4)+"]", cstn, p)); }
+
+      JetId = phi + x(1)*x(2)^(2*p+1);
+      w     = weight(JetId);
+      fk    = jet(fr, 3*w[1], w);
+      if(fk!=0) { return(printresult(61,f, "Q["+string(6*p+5)+"]", cstn, p)); }
+
+      JetId = phi + x(2)^(3*p+2);
+      w     = weight(JetId);
+      fk    = jet(fr, 3*w[1], w);
+      if(fk!=0) { return(printresult(62,f, "Q["+string(6*p+6)+"]", cstn, p)); }
+
+      //--------------------------- step 63(k) --------------------------------
+      p++;
+      JetId = phi + x(2)^(3*p);
+      w     = weight(JetId);
+      fk    = jet(f, 3*w[1], w);
+      JetId = std(jacob(fk));
+      Dim   = dim(JetId);
+      Mult  = mult(JetId);
+      if(Dim==0) { return(printresult(64, f, "Q["+string(p)+",0]", cstn, p)); }
+      if(Dim==1) {
+        if(Mult == 1) {
+           return(printresult(65, f, "Q["+string(p)+","+string(Mu-(6*p+2))+"]",
+                  cstn, p));
+        }
+        if(Mult == 2) {
+          fk    = jet(fr, 3*w[1], w);
+          f_tmp = Coeffs(phi, x(1))[4,1] *x(1)^3+fk;
+          v    = Faktorisiere(f, f_tmp, 3 , p, RFlg);
+          f    = v[1];
+          Phi  = v[2];
+          PhiG = Phi(PhiG);
+          cstn[4] = PhiG;
+          fr = f - phi;
+        }
+      }
+    }
+    // Should never reach this line
+    return(printresult(59, f, "error!", cstn, -1));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static proc Funktion66 (poly f, list cstn)
+{
+//---------------------------- initialisation ---------------------------------
+    int kx = 1; // Koordinate x
+    int ky = 2; // Koordinate y
+    int kz = 3; // Koordinate z
+    poly f3 = jet(f, 3);
+    ideal JetId;
+
+    debug_log(1, "   Step 66");
+    debug_log(2, "F3=", Show(f3));
+    poly fx = diff(f3, x(kx));
+    JetId = jacob(fx);
+    JetId = std(JetId);
+    "nach x:",Show(fx), "  Id=", JetId, "  Dim=", dim(JetId);
+
+    poly fy = diff(f3, x(ky));
+    JetId = jacob(fx);
+    JetId = std(JetId);
+    "nach y:",Show(fy), "  Id=", JetId, "  Dim=", dim(JetId);
+
+    poly fz = diff(f3, x(kz));
+    JetId = jacob(fx);
+    JetId = std(JetId);
+    "nach z:",Show(fz), "  Id=", JetId, "  Dim=", dim(JetId);
+    return(printresult(1, 66, "error!", cstn, -1));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static proc Funktion82 (poly f, list cstn)
+{
+//---------------------------- initialisation ---------------------------------
+    poly   f3, b1, b2, b3;
+    int    i, kx, ky, kz, Fall;
+    ideal  Jfsyz, B;
+    intvec kv = 1,2,3;
+    matrix Mat;
+    map    PhiG, VERT;
+    list   v;
+    def ring_top=basering;
+    debug_log(1, "   Step 82");
+
+    f3 = jet(f,3);
+    kx = 1;     // Koordinate x
+    ky = 2;     // Koordinate y
+    kz = 3;     // Koordinate z
+    B  = maxideal(1);
+    Jfsyz = jacob(f3);
+    PhiG  = cstn[4];
+    Fall  = 2;
+
+//------------------ find coordinatechange that f3 ~ g(x,z) -------------------
+    if (diff(f3, x(1)) == 0) { kx, ky = swap(kx, ky); }
+    if (diff(f3, x(2)) == 0) {  }
+    if (diff(f3, x(3)) == 0) { kz, ky = swap(kz, ky); }
+    if ( (diff(f3, x(1)) != 0) && (diff(f3, x(2)) != 0) &&
+          (diff(f3, x(3)) != 0) ) {
+      Mat = matrix(syz(Jfsyz));
+      b1  = Mat[1,1];
+      b2  = Mat[2,1];
+      b3  = Mat[3,1];
+
+      if( b1 != 0) {
+        VERT = ring_top,b1*x(kx), b2*x(kx)+x(ky), b3*x(kx) + x(kz);
+        kx, ky = swap(kx, ky);
+      }
+      else {
+        if(b2!=0) { VERT = ring_top,x(kx)+b1*x(ky),b2*x(ky),b3*x(ky)+x(kz); }
+        else {
+          if(b3!=0) { VERT = ring_top,x(kx)+b1*x(kz),x(ky)+b2*x(kz),b3*x(kz); }
+          else { VERT = ring_top,B; }
+        }
+      }
+      f    = VERT(f);
+      PhiG = VERT(PhiG);
+      cstn[4] = PhiG;
+    }
+    VERT = ring_top,x(kx),x(ky),x(kz);
+    f    = VERT(f);
+    PhiG = VERT(PhiG);
+    cstn[4] = PhiG;
+    f3   = jet(f,3);
+
+    if( (f3-subst(f3, x(kx), 0)) == 0) { kx, ky = swap(kx, ky); }
+    if( (f3-subst(f3, x(kz), 0)) == 0) { kz, ky = swap(kz, ky); }
+
+//------------ find coordinatechange for f3 ~ x3+xz2, if possible  ------------
+    matrix C = coeffs(f3, x(kx));
+    if(size(C) == 3) { C = coeffs(f3, x(kz)); kx,kz=swap(kx, kz); }
+    if(C[1,1] == 0 && C[3,1] == 0) { Fall = 1; }
+    if(C[1,1] != 0 && C[3,1] != 0 ) { Fall = 3; }
+    if(C[1,1] == 0 && C[3,1] != 0 ) { Fall = 2; }
+    if(C[1,1] != 0 && C[3,1] == 0 ) { Fall = 2; kx,kz=swap(kx, kz); }
+
+    if(Fall == 1) {
+      VERT=ring_top,x(kx),x(ky),x(kz);
+    }
+    if(Fall == 2) {
+       v = tschirnhaus(f3/x(kz), x(kx));
+       b1, VERT = v[1..2];
+    }
+    if(Fall == 3) {
+      v = tschirnhaus(f3/x(kx), x(kx));
+      b1, VERT = [1..2];
+      debug_log(2, "B1=", Show(jet(VERT(f),3)));
+      v = tschirnhaus(f3/x(kz), x(kz));
+      b2, VERT = [1..2];
+      debug_log(2, "B2=", Show(jet(VERT(f),3)));
+    }
+    f    = VERT(f);
+    PhiG = VERT(PhiG);
+    cstn[4] = PhiG;
+    f3   = jet(f,3);
+
+//------------- if f3 ~ x3+xz2 then continue with classification  -------------
+    C = coeffs(f3, x(1));
+    if( C[1,1] == 0 && C[2,1] != 0 && C[3,1] == 0 && C[4,1] != 0 ) {
+      return(Funktion83(f, cstn));
+    }
+    return(printresult(82, f, "error!", cstn, -1));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static proc Isomorphie_s82_z (poly f, poly fk, int p)
+{
+//---------------------------- initialisation ---------------------------------
+    poly   Relation, a, b;
+    ideal  Jfsyz, B;
+    matrix Mat;
+    map    VERT;
+    list   v;
+    def ring_top=basering;
+
+    debug_log(1, "      Isomorphie 82/90 z");
+    debug_log(2, "tt=", Show(fk));
+    Jfsyz = fk, diff(fk, x(3));
+    Mat   = matrix(syz(Jfsyz));
+    Relation = -2 * Mat[2,1] / Mat[1,1];
+    a = Coeff(Relation, x(3), x(3));
+    b = Coeff(Relation, x(2), x(2)^p);
+    B = maxideal(1);
+    B[rvar(x(3))] = x(3)-b*x(2)^p;
+    VERT = ring_top,B;
+    v    = VERT(f), VERT;
+    debug_log(2, VERT);
+    debug_log(2, "      z res=", Show(VERT(fk)));
+    return(v);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static proc Isomorphie_s82_x (poly f, poly fk, int p)
+{
+//---------------------------- initialisation ---------------------------------
+    matrix Mat;
+    poly   Relation, a, b;
+    ideal  Jfsyz, B;
+    map    VERT;
+    list   v;
+    def ring_top=basering;
+
+    debug_log(1, "      Isomorphie 82/90 x");
+    debug_log(2, "tt=", Show(fk));
+    Jfsyz = fk, diff(fk, x(1));
+    Mat   = matrix(syz(Jfsyz));
+    Relation = -3 * Mat[2,1] / Mat[1,1];
+    a = Coeff(Relation, x(1), x(1));
+    b = Coeff(Relation, x(2), x(2)^p);
+    B = maxideal(1);
+    B[rvar(x(1))] = x(1)-b*x(2)^p;
+    VERT = ring_top,B;
+    v    = VERT(f), VERT;
+    debug_log(2, VERT);
+    debug_log(2, "      x res=", Show(VERT(fk)));
+
+    return(v);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static proc Funktion83 (poly f, list cstn)
+{
+//---------------------------- initialisation ---------------------------------
+    poly   fk, phi, a, b;
+    ideal  JetId, Jf, B;
+    int    k, Dim, Mult;
+    intvec w;
+    map    PhiG, Phi;
+    list   v;
+    matrix Mat;
+    def ring_top=basering;
+    debug_log(1, "      Step 83");
+
+    k    = 1;
+    PhiG = cstn[4];
+//---------------------------- begin of loop ----------------------------------
+    while(k<10) {
+      phi   = jet(f, 3);
+      //--------------------------- step 83(k) --------------------------------
+      JetId = x(1)^3 + x(3)^3 + x(2)^(3*k+1);
+      fk    = jet(f- phi, 3*w[1], weight(JetId)) ;
+      if(fk!=0) { return(printresult(84,f,"U["+string(12*k)+"]",cstn,4*k-3)); }
+
+      JetId = x(1)^3 + x(3)^3 + x(1)*x(2)^(2*k+1);
+      fk    = jet(f, 3*w[1], weight(JetId)) ;
+      //--------------------------- step 85(k) --------------------------------
+      if ( fk != phi ) {
+        Jf   = std(jacob(fk));
+        Dim  = dim(Jf);
+        if(Dim==0) {return(printresult(86,f,"U["+string(k)+",0]",cstn,4*k-2));}
+        if(Dim==1) {return(printresult(87,f,"U["+string(k)+",p]",cstn,4*k-2));}
+      }
+
+      //--------------------------- step 88(k) --------------------------------
+      JetId = x(1)^3 + x(3)^3 + x(2)^(3*k+2);
+      fk    = jet(f- phi, 3*w[1], weight(JetId)) ;
+      if(fk!=0) {return(printresult(89,f,"U["+string(12*k+4)+"]",cstn,4*k-2));}
+
+      //--------------------------- step 90(k) --------------------------------
+      k++;
+      JetId = x(1)^3 + x(3)^3 + x(2)^(3*k);
+      fk    = jet(f, 3*w[1], weight(JetId)) ;
+      Jf    = std(jacob(fk));
+      Dim   = dim(Jf);
+      Mult  = mult(Jf);
+      if ( Dim == 0 ) { return(printresult(83, f, "NoClass", cstn, -1)); }
+      if ( Dim == 1 ) {
+        if ( Mult == 4 ) {
+          if( fk - phi != 0) { // b!=0  und/oder b'!=0
+            if( Coeff(fk,x(1)*x(2), x(1)^2*x(2)^k) == 0 ) { // b=0 und b'!=0
+              a    = (fk - Coeff(fk, x(1), x(1)^3)*x(1)^3) / x(1);
+              v    = Isomorphie_s82_z(f, a, k);
+            }
+            else {
+              if( Coeff(fk,x(1)*x(2)*x(3), x(1)*x(2)^k*x(3)) == 0 ){
+                        // b!=0 und b'=0
+                a    = subst(fk, x(3), 0);
+                v    = Isomorphie_s82_x(f, a, k);
+              }
+              else {
+                a = Coeff(fk,x(1)*x(2)*x(3), x(1)*x(2)^k*x(3));
+                b = Coeff(fk,x(2)*x(3), x(2)^(2*k)*x(3));
+                B = maxideal(1);
+                B[rvar(x(1))] = x(1)-b/a*x(2)^k;
+                Phi  = ring_top,B;
+                f    = Phi(f);
+                PhiG = Phi(PhiG);
+                cstn[4] = PhiG;
+                fk   = jet(f, 3*w[1], w) ;
+                a    = (fk - Coeff(fk, x(1), x(1)^3)*x(1)^3) / x(1);
+                v    = Isomorphie_s82_z(f, a, k);
+              } // ende else b!=0 und b'=0
+            } // ende else b=0 und b'!=0
+            f, Phi  = v[1..2];
+            PhiG    = Phi(PhiG);
+            cstn[4] = PhiG;
+          } //ende fk-phi!=0
+        } // ende mult=4
+        else { return(printresult(83, f, "NoClass", cstn, -1)); }
+      } // ende dim=1
+      else { return(printresult(83, f, "NoClass", cstn, -1)); }
+    } // ENDE While
+    return(printresult(83, f, "error!", cstn, -1));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static proc Funktion97 (poly f, list cstn)
+{
+//---------------------------- initialisation ---------------------------------
+    poly   f3, l1, l2, a, b, c, prod;
+    ideal  Jfsyz, Jf, B;
+    int    k, i, pt, kx, ky, kz, Dim, Mult, Mu;
+    matrix Mat;
+    map    PhiG, VERT;
+    def ring_top=basering;
+    debug_log(1, "   Step 97");
+
+    Mu   = cstn[2];
+    PhiG = cstn[4];
+    kx   = 1;   // Koordinate x
+    ky   = 2;   // Koordinate y
+    kz   = 3;   // Koordinate z
+    B    = maxideal(1); // Abbildungs-ideal
+    pt   = 2;
+    f3   = jet(f, 3);
+    k    = 1;
+
+//--------------------------- compute f3 ~ x2y --------------------------------
+    // vertausche 2 Koordinaten sodass d2f/dx2 <>0 ist.
+    for(i=1;i<4;i=i+1) {
+      if(diff(diff(f3, x(i)), x(i)) != 0) { kx = i; i=4; }
+    }
+    if(kx == 2) { ky = 1; kz = 3; }
+    if(kx == 3) { ky = 2; kz = 1; }
+    //-------------------------- compute -l1*l2 -------------------------------
+    f3    = jet(f, 3);
+    Jfsyz = f3, diff(f3, x(kx));
+    Mat   = matrix(syz(Jfsyz));
+    if(deg(Mat[2,1])>1) {
+      Jfsyz = f3, Mat[2,1];
+      Mat   = matrix(syz(Jfsyz));
+
+      // berechen Abb. sodass f=x2*l2
+      l1 = Mat[2,1];
+      a  = Coeff(l1, x(kx), x(kx));
+      l1 =  l1 / number(a);
+      b  = Coeff(l1, x(ky), x(ky));
+      c  = Coeff(l1, x(kz), x(kz));
+      B[rvar(x(kx))] = x(kx) - b * x(ky) - c * x(kz);
+      VERT = ring_top, B;
+      f    = VERT(f);
+      PhiG = VERT(PhiG);
+      cstn[4] = PhiG;
+
+      f3 = jet(f, 3);
+      l2 = f3 / x(kx)^2;
+
+      // sorge dafuer, dass b<>0 ist.
+      b = Coeff(l2, x(ky), x(ky));
+      if( b== 0) { ky, kz = swap(ky, kz); }
+
+      // Koordinaten-Transf. s.d. f=x2y
+      b  = Coeff(l2, x(ky), x(ky));
+      l2 =  l2 / number(b);
+      a  = Coeff(l2, x(kx), x(kx));
+      c  = Coeff(l2, x(kz), x(kz));
+      B  = maxideal(1);
+      B[rvar(x(ky))] = -a * x(kx) + x(ky) - c * x(kz);
+      VERT = ring_top, B;
+      f    = VERT(f);
+      PhiG = VERT(PhiG);
+      cstn[4] = PhiG;
+    }
+
+//------------------------------- step 98 ---------------------------------
+    Jfsyz = x(kx)^2*x(ky) + x(ky)^4 + x(kz)^4;
+    a     = jet(f, 8, weight(Jfsyz));
+    Jf    = std(jacob(a));
+    Dim   = dim(Jf);
+    Mult  = mult(Jf);
+    if( Dim == 0) { return(printresult(99, f, "V[1,0]", cstn, 3)); }
+    if( Dim == 1) {
+      if(Mult==1) {return(printresult(100,f,"V[1,"+string(Mu-15)+"]",cstn,3));}
+      if(Mult==2){return(printresult(101,f,"V#[1,"+string(Mu-15)+"]",cstn,3));}
+    }
+    " Dim=",Dim," Mult=",Mult;
+    return(printresult(102, f, "NoClass", cstn, -1));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+proc tschirnhaus (poly f, poly x)
+"USAGE:    tschirnhaus();"
+{
+//---------------------------- initialisation ---------------------------------
+    poly   b;
+    ideal  B;
+    int    n, j, hc;
+    matrix cf;
+    intvec z;
+    string s;
+    list   v;
+    map    Phi, EH;
+    def ring_top=basering;
+
+    n    = nvars(basering);
+    cf   = coeffs(f, x);
+    hc   = nrows(cf) - 1; // hoechster exponent von x_i
+    b    = cf[hc+1,1];    // koeffizient von x_i^hc
+    B    = maxideal(1);
+    z[n] = 0;
+    EH   = ring_top, z;
+    Phi  = ring_top, B;
+    v[1] = f;
+    if ( EH(b) != 0)    // pruefe ob der Koeff von x_i^hc
+    { B[rvar(x)] = x -1*(cf[hc,1]/(hc*b));
+      v[1] = Phi(f);
+    }
+    v[2] = Phi;
+    return(v);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static proc Isomorphie_s17 (poly f, poly fk, int k, int ct, list #)
+{
+//---------------------------- initialisation ---------------------------------
+    ideal  Jfsyz, JetId, bb;
+    poly   a, b, c, d, Relation, an, bn;
+    int    B,C, alpha, beta, gamma, g;
+    matrix Matx, Maty;
+    map    PhiG, VERT;
+    list   v;
+    def ring_top=basering;
+
+    if(size(#)==1) { PhiG = #[1]; }
+    else { PhiG = ring_top,maxideal(1); }
+    bb = maxideal(1);
+
+    // Ziel: bestimme a,b,c,d sodass  fk = (ax+by^k)^3(cx+dy) gilt.
+    debug_log(2, "Isomorphie_s17:");
+    debug_log(2, "Faktor: f=",Show(f)," Jet=",Show(fk)," k=",k, "cnt=", ct);
+
+    if( k == 1) {
+      Jfsyz = fk, diff(fk, x(1));
+      Matx  = matrix(syz(Jfsyz));
+      Jfsyz = fk, diff(fk, x(2));
+      Maty  = matrix(syz(Jfsyz));
+
+      a = Coeff(fk, x(1), x(1)^4);
+      b = Coeff(fk, x(2), x(2)^4);
+      c = Coeff(fk, x(1)*x(2), x(1)^3*x(2));
+      d = Coeff(fk, x(1)*x(2), x(1)*x(2)^3);
+
+      if( (a != 0) && (b != 0) ) {
+        B = -int(Coeff(Matx[1,1], x(2), x(2)));
+        C = -int(Coeff(Maty[1,1], x(1), x(1)));
+        alpha = int(Coeff(Matx[2,1], x(1), x(1)^2));
+        beta  = int(Coeff(Matx[2,1], x(1)*x(2), x(1)*x(2)));
+        gamma = int(Coeff(Matx[2,1], x(2), x(2)^2));
+
+        bb[rvar(x(1))] = x(1) - (2*gamma / (B - beta))*x(2);
+        bb[rvar(x(2))] = x(2) - ((C - beta) / (2*gamma))*x(1);
+        VERT     = ring_top,bb;
+        Relation = VERT(f);
+        fk       = jet(Relation, 4);
+
+        an = Coeff(fk, x(1), x(1)^4);
+        bn = Coeff(fk, x(2), x(2)^4);
+        if( (an != 0) & (bn != 0) ) { VERT=ring_top,x(1),(x(2) + a*x(1))/ b; }
+        f    = VERT(f);
+        fk   = jet(f, 4);
+        PhiG = VERT(PhiG);
+
+        a = Coeff(fk, x(1), x(1)^4);
+        b = Coeff(fk, x(2), x(2)^4);
+        c = Coeff(fk, x(1)*x(2), x(1)^3*x(2));
+        d = Coeff(fk, x(1)*x(2), x(1)*x(2)^3);
+        Jfsyz = fk, diff(fk, x(1));
+        Matx  = matrix(syz(Jfsyz));
+        Jfsyz = fk, diff(fk, x(2));
+        Maty  = matrix(syz(Jfsyz));
+      }
+
+      if( (a == 0) || (b == 0) ) {
+        if( a == 0) {
+          if( c == 0) { // y3(ax+by)
+            Relation = - Matx[2,1] / Matx[1,1];
+            a = Coeff(Relation, x(1), x(1));
+            b = Coeff(Relation, x(2), x(2));
+            VERT=ring_top,a*x(2)^k - b*x(1), x(1);
+          }
+          else { // (ax+by)^3y
+            Relation = - 3*Matx[2,1] / Matx[1,1];
+            a = Coeff(Relation, x(1), x(1));
+            b = Coeff(Relation, x(2), x(2));
+            VERT=ring_top,a*x(1) - b*x(2), x(2);
+          }
+        }
+        else {
+          if( d == 0) { // x3(ax+by)
+            Relation = - Maty[2,1] / Maty[1,1];
+            a = Coeff(Relation, x(1), x(1));
+            b = Coeff(Relation, x(2), x(2));
+            VERT=ring_top,x(1), b*x(2)^k - a*x(1);
+          }
+          else { // x(ax+by)^3
+            Relation = - 3*Maty[2,1] / Maty[1,1];
+            a = Coeff(Relation, x(1), x(1));
+            b = Coeff(Relation, x(2), x(2));
+            VERT=ring_top,x(2), b*x(1) - a*x(2);
+          }
+        }
+        f    = VERT(f);
+        PhiG = VERT(PhiG);
+      }
+      else {  //      "Weder b noch a sind 0";
+        if(ct > 5) { v[1]=f; v[2]=PhiG; return(v); }
+        fk = jet(f, 4);
+        return(Isomorphie_s17(f, fk, k, ct+1, PhiG));
+      }
+    }
+    else {  // k >1
+      a     = fk/x(2);
+      Jfsyz = a, diff(a, x(1));
+      Matx  = matrix(syz(Jfsyz));
+      Relation = -3 * Matx[2,1] / Matx[1,1];
+      a    = Coeff(Relation, x(1), x(1));
+      b    = Coeff(Relation, x(2), x(2)^k);
+      VERT = basering,x(1)-b*x(2)^k,x(2);
+      f    = VERT(f);
+      PhiG = VERT(PhiG);
+      JetId = x(1)^3*x(2) + x(2)^(3*k+1);
+      fk = jet(f, 3*k+1, weight(JetId));
+    }
+    v = f, PhiG;
+    debug_log(2, "Isomorphie_s17: done");
+    debug_log(2, "Faktor: f=",Show(f)," Jet=",Show(fk)," k=",k);
+
+    return(v);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static proc printresult (int step, poly f, string typ, list cstn, int m)
+{
+  if(defined(onlyreturninvariants))
+  {
+    if(onlyreturninvariants == 1)
+    {
+      Modality = m;
+      Type = typ;
+    }
+  }
+//---------------------------- initialisation ---------------------------------
+  int corank, Mu, K;
+  list v;
+
+  corank, Mu, K = cstn[1..3];
+  debug_log(0,"   Arnold step number "+string(step));
+  if( @DeBug >= 0 )
+  {
+    "The singularity";
+    "   "+Show(jet(f, K))+"";
+    if( typ != "error!" && typ != "NoClass" )
+    {
+      "is R-equivalent to "+typ+".";
+    }
+    if ( typ == "NoClass" )
+    {
+      "is not in Arnolds list.";
+    }
+//    if(K>=0)  { "  det = "+string(K); }
+    if(Mu>=0) { "   Milnor number = "+string(Mu); }
+    if(m>=0)  { "   modality      = "+string(m); }
+  }
+  v = f, typ, corank, cstn[4];
+  return(v);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static proc Funktion47 (poly f, list cstn)
+{
+  int corank = cstn[1];
+  int Mu = cstn[2];
+  int K  = cstn[3];
+  string s = "The Singularity "+Show(jet(f, K));
+  string tp="";
+//  return(printresult(47, f, tp, cstn, -1));
+
+  s = s +" has 4-jet equal to zero. (F47), mu="+string(Mu);
+
+  s; // +"  ("+SG_Typ+")";
+  s = "No further classification available.";
+  s;
+  return(Show(f), tp, corank);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static proc Funktion91 (poly f, list cstn, int k)
+{
+  string tp  = "U*[k,0]";
+  return(printresult(91, f, tp, cstn, -1));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static proc Funktion92 (poly f, list cstn, int k)
+{
+  string tp  = "UP[k]";
+  return(printresult(92, f, tp, cstn, -1));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static proc Funktion93 (poly f, list cstn, int k)
+{
+  string tp  = "UQ[k]";
+  return(printresult(93, f, tp, cstn, -1));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static proc Funktion94 (poly f, list cstn, int k)
+{
+  string tp  = "UR[k]";
+  return(printresult(94, f, tp, cstn, -1));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static proc Funktion95 (poly f, list cstn, int k)
+{
+  string tp  = "US[k]";
+  return(printresult(95, f, tp, cstn, -1));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static proc Funktion96 (poly f, list cstn, int k)
+{
+  string tp  = "UT[k]";
+  return(printresult(96, f, tp, cstn, -1));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+proc morsesplit(poly f)
+"
+USAGE:    morsesplit(f);        f=poly
+RETURN:   Normal form of f in M^3 after application of the splitting lemma
+COMPUTE:  apply the splitting lemma (generalized Morse lemma) to f
+EXAMPLE:  example morsesplit; shows an example"
+{
+//---------------------------- initialisation ---------------------------------
+  poly f_out;
+  int  n, K, Mu, corank;
+  list v;
+
+  if(defined(@ringdisplay) != 0 ) { kill @ringdisplay; }
+  string @ringdisplay = "setring "+nameof(basering);
+  export @ringdisplay;
+
+  def ring_ext=basering;
+
+  n = nvars(basering);
+
+  // if trace/debug mode not set, do it!
+  init_debug();
+  K, Mu, corank = basicinvariants(f);
+  ring ring_top=char(basering),(x(1..n)),(c,ds);
+
+  map Conv=ring_ext,maxideal(1);
+  setring ring_top;
+  v = Morse(jet(Conv(f),K), K, corank, 0);
+  poly f_out = v[1];
+  setring ring_ext;
+  map ConvUp = ring_top, maxideal(1);
+  return(ConvUp(f_out));
+}
+example
+{ "EXAMPLE"; echo=2;
+   ring r=0,(x,y,z),ds;
+   export r;
+   init_debug(1);
+   poly f=(x2+3y-2z)^2+xyz-(x-y3+x2*z3)^3;
+   poly g=morsesplit(f);
+   g;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static proc Coeffs (list #)
+{
+  matrix m=matrix(coeffs(#[1],#[2]), deg(#[1])+1, 1);
+  return(m);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static proc Morse(poly f, int K, int corank, int ShowPhi)
+{
+//---------------------------- initialisation ---------------------------------
+  poly   fc, f2, a, P, Beta, fi;
+  ideal  Jfx, B;
+  int    n, i, j, k, Rang, Done;
+  matrix Mat;
+  map    Id, Psi, Phi, PhiG;
+  intvec Abb, RFlg;
+  list   v;
+
+  fi = f;
+  n = nvars(basering);
+  init_debug();
+
+  def ring_top=basering;
+
+  debug_log(3, "Split the polynomial below using determinacy: ", string(K));
+  debug_log(3, Show(fi));
+
+  for( j=1; j<=n ; j++) { Abb[j] = 0; }
+
+  RFlg = GetRf(fi, n);
+  debug_log(2, "Permutations:", RFlg );
+  PhiG=ring_top,maxideal(1);
+
+//----------------- find quadratic term, if there is only one -----------------
+  B = maxideal(1);
+  if(corank == (n-1))
+  {
+    Done = 0;
+    f2   = jet(fi, 2);
+    j    = 1;
+    Jfx  = f2, diff(f2, x(j));
+    while(j<=n && (diff(f2, x(j))==0))
+    {
+      j++;
+      Jfx = f2, diff(f2, x(j));
+    }
+    Mat  = matrix(syz(Jfx));
+    Beta = 2*Mat[2,1]/Mat[1,1];
+    for( j=1; j<=n ; j++)
+    {
+      f2 = Coeff(Beta, x(RFlg[j]), x(RFlg[j]));
+      if(f2!=0)
+      {
+        k = RFlg[j];
+        break;
+      }
+    }
+    for( j=1; j<=n ; j=j+1)
+    {
+      f2 = Coeff(Beta, x(j), x(j));
+      if(j == k) { B[rvar(x(j))] = (2*f2*x(j)-Beta) / number(f2); }
+    }
+    Phi  =ring_top,B;
+    fi   = Phi(fi);
+    PhiG = Phi(PhiG);
+  }
+  if( ShowPhi > 1) { PhiG; }
+
+//------------------------ compute spliting lemma -----------------------------
+  fc = fi;
+  i  = 1;              // Index fuer Variablen wird bearbeitet
+  while( i <= n)
+  {
+    Phi=ring_top,maxideal(1);
+    debug_log(6, "Pruefe Variable x(" +string(RFlg[i]) + ")");
+    debug_log(6, "--------------------");
+    j  = i + 1;        // setze j fuer evtle Verschiebung
+    f2 = jet(fc,2);
+    debug_log(6, "Rechne 2-Jet =" , string(f2));
+    if( (f2 - subst(f2, x(RFlg[i]), 0)) == 0 ) { Abb[RFlg[i]] = 1; }
+    if( (f2 - subst(f2, x(RFlg[i]), 0)) != 0 )
+    {
+      while( (j<=n) || (i==n) )
+      {
+        debug_log(6, "Pruefe 2-Jet mit Wert : " + string(jet(fc,2)));
+        a = Coeff(jet(fc,2), x(RFlg[i]), x(RFlg[i])^2);
+        debug_log(6,"Koeffizient von x(" + string(RFlg[i]) + ")^2 ist:", a);
+        if( (a != 0) || (i==n) )
+        {
+          debug_log(6, "BREAK!!!!!!!!!!!!!!");
+          break;
+        }
+        debug_log(6,"Verschiebe evtl Variable x(",string(RFlg[j]),") um x(",
+                     string(RFlg[i]), ")");
+        B = maxideal(1);
+        for( k=1; k<=n ; k=k+1)
+        {
+          if(k==RFlg[j]) { B[rvar(x(k))] = x(k) + x(RFlg[i]); }
+        }
+        Phi = ring_top,B;
+        fc  = Phi(fi);
+        j++;
+      }               // Ende while( (j<=n) || (i==n) )
+
+      debug_log(6, "Moegliche Verschiebung fertig!");
+      PhiG = Phi(PhiG);
+      if( ShowPhi > 1) { "NachVersch.:"; Phi; }
+
+      if( (j<=n) || (i==n))
+      {
+        P = Coeff(fc, x(RFlg[i]), x(RFlg[i]));
+        debug_log(6, "Koeffizient von x("+string(RFlg[i])+") ist: ",
+                      string(P));
+        if(P != 0)
+        {
+          debug_log(6, "1 Koeffizient von x("+string(RFlg[i])+") ist: ",
+                       string(P));
+          debug_log(6, "a=" + string(a));
+          P = P / number (2 * a);
+          debug_log(6, "2 Koeffizient von x("+string(RFlg[i])+") ist: ",
+                       string(P));
+          B = maxideal(1);
+          for( k=1; k<=n ; k=k+1) {if(k==RFlg[i]) {B[rvar(x(k))]=x(k)-P;}}
+          Phi =ring_top,B;
+          debug_log(6, "Quadratische-Ergaenzung durch:", Phi);
+          fi   = Phi(fc);
+          PhiG = Phi(PhiG);
+          fc   = jet(fi,K);
+          P    = Coeff(fc, x(RFlg[i]), x(RFlg[i]));
+          if( P != 0)
+          {
+            fi = fc;
+            continue;
+          }
+        }     // Ende if(P != 0)
+              // Fertig mit Quadratischer-Ergaenzung
+      }               // Ende if( (j<=n) || (i==n))
+    }                 // Ende if( (f2 - subst(f2, x(RFlg[i]), 0)) != 0 )
+
+    fi = fc;
+    i++;
+    debug_log(6, "++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
+  }
+  debug_log(6, "Ende  ---------------------------------------------------");
+
+//--------------------------- collect results ---------------------------------
+  if( ShowPhi > 0 )
+  {
+    "Abbildung innerhalb des Morse-Lemmas:";
+    PhiG;
+    "Vergleich:";
+    "PhiG(f)= " + Show(jet(PhiG(f), K));
+    "fi     = " + Show(fi);
+  }
+
+  Rang = 0;
+  B    = maxideal(1);
+  for( i=1; i<=n ; i++) { if(Abb[i] != 1) { Rang ++; B[rvar(x(i))] = 0; } }
+  Phi  = ring_top,B;
+  PhiG = Phi(PhiG);
+  fi   = Phi(fi);
+  v    = fi, PhiG;
+  debug_log(2, "rank determined with Morse rg=", Rang);
+  debug_log(1, "Residual singularity f=",Show(fi));
+  return(v);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static proc Coeff(poly f, list #)
+{
+//---------------------------- initialisation ---------------------------------
+  poly   a, term;
+  int    n, i;
+  matrix K;
+
+  n     = nvars(basering);
+  i     = 1;
+  term  = #[2];
+  K     = coef(f, #[1]);
+
+  while( (i<=ncols(K)) && (K[1,i] != term) )
+  { i++;
+    if(i>ncols(K)) { break; }
+  }
+  if(i<=ncols(K)) { a = K[2,i]; }
+  if(i>ncols(K)) { a = 0; }
+
+  return(a);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static proc ReOrder(poly f)
+{
+//---------------------------- initialisation ---------------------------------
+  poly  result;
+  ideal B = maxideal(1);
+  int   i, n, Ctn, Ctv;
+  map   conv;
+
+  n = nvars(basering);
+  Ctv = 1;              // Zahl der Vorhandenen Variablen
+  Ctn = n;              // Zahl der Nicht-Vorhandenen Variablen
+  def ring_top=basering;
+
+  for( i=1; i<=n; i=i+1)
+  { result = subst(f,x(i), 0) - f;
+    if( result != 0 ) { B[rvar(x(i))] = x(Ctv); Ctv++; }
+    else { B[rvar(x(i))] = x(Ctn); Ctn--; }
+  }
+
+  conv = ring_top,B;
+  return(conv);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+proc quickclass(poly f)
+"
+USAGE:    quickclass(f);         f=poly
+RETURN:   Normal form of f in Arnold's list
+REMARK:   try to determine the normal form of f by invariants, mainly by
+          computing the Hilbert function of the Milnor algebra,
+          no coordinate change is needed (see also proc 'milnorcode').
+EXAMPLE:  example quickclass; shows an example"
+{
+//---------------------------- initialisation ---------------------------------
+  string Typ;
+  int    cnt, K, Mu, corank;
+  list   v;
+  def ring_top=basering;
+  // check basic condition on the basering.
+  if(checkring()) { return(f); }
+  if( f==0 ) {
+    "Normal form : 0";
+    return(f);
+  }
+  if( jet(f,0)!=0 ) {
+    "Normal form : 1";
+    return(f);
+  }
+  K, Mu, corank = basicinvariants(f);
+  if(Mu<0) {
+    debug_log(0, "The Milnor number of the function is infinite.");
+    return(f);
+  }
+
+  // Do the classification of f
+  // typ: list of types matching the milnorcode
+  // cnt: number of matches found
+  v = HKclass(milnorcode(f));
+  Typ, cnt = v[1..2];
+  "Singularity R-equivalent to :",Typ;
+  if(cnt==0) {
+    "Hilbert polynomial not recognised. Milnor code = ", milnorcode(f);
+    return();
+  }
+  if(cnt==1) {
+    debug_log(1,"Getting normal form from database.");
+    "normal form :",A_L(Typ);
+    return(A_L(Typ));
+  }
+  // Hier nun der Fall cnt>1
+  "Hilbert-Code of Jf^2";
+  "We have ", cnt, "cases to test";
+  Cubic(f);
+  return(v);
+}
+example
+{ "EXAMPLE:"; echo=2;
+   ring r=0,(x,y,z),ds;
+   poly f=(x2+3y-2z)^2+xyz-(x-y3+x2*z3)^3;
+   quickclass(f);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+proc milnorcode (poly f, list #)
+"USAGE:    milnorcode(f[,e]); f=poly, e=int
+RETURN:   intvec, coding the Hilbert function of the e-th Milnor algebra
+          of f, i.e. of basering/(jacob(f)^e) (default e=1), according
+          to proc Hcode
+EXAMPLE:  example milnorcode; shows an example"
+{
+  int  e=1;
+  if(size(#)==1) { e=#[1]; }
+  ideal jf=std(jacob(f)^e);
+  intvec v=hilb(jf,2);
+
+  return(Hcode(v));
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring r=0,(x,y,z),ds;
+  poly f=x2y+y3+z2;
+  milnorcode(f);
+  milnorcode(f,2);  // a big second argument may result in memory overflow
+}
+
+///////////////////////////////////////////////////////////////////////////////
+proc Hcode (intvec v)
+"USAGE:    Hcode(v); v=intvec
+RETURN:   intvec, coding v according to the number of successive
+          repetitions of an entry
+EXAMPLE:  example Hcode; shows an example."
+{
+  int    col, len, i, cur, cnt, maxcoef, nlen;
+  intvec hil1, hil2;
+
+  col      = 1;
+  len      = size(v);
+  v[len+1] = 0;
+
+  init_debug();
+  debug_log(1, "Hcode:", v );
+
+  for(i=1; i<=len; i++) { if( v[i] > maxcoef) { maxcoef = v[i]; } }
+
+  nlen       = 2*maxcoef - 1;
+  hil1[nlen] = 0;
+  hil2[nlen] = 0;
+
+  for(i=1; i<=nlen; i++)
+  { if( i > maxcoef) { hil2[i] = 2*maxcoef-i; }
+    else { hil2[i] = i; }
+  }
+
+  for(i=1; i<=nlen; i++)
+  { cnt=0;
+    while( (col<=len) && (v[col] == hil2[i]) )
+    { cnt++; col++; }
+    hil1[i] = cnt;
+  }
+  return(hil1);
+}
+example
+{ "EXAMPLE:"; echo=2;
+  intvec v1 = 1,3,5,5,2;
+  Hcode(v1);
+  intvec v2 = 1,2,3,4,4,4,4,4,4,4,3,2,1;
+  Hcode(v2);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static proc Cubic (poly f)
+{
+//---------------------------- initialisation ---------------------------------
+  poly  f3;
+  ideal Jf, Jf1, Jf2;
+  int   Dim, Mult;
+
+  f3 = jet(f, 3);
+  if( jet(f,2) != 0) { return("2-jet non zero"); }
+  if( f3 == 0 ) { return("null form"); }
+
+  Jf1  = jacob(f3);
+  Jf   = std(Jf1);
+  Dim  = dim(Jf);
+  Mult = mult(Jf);
+
+  if(Dim == 0) { return("P[8]:smooth cubic"); } // x3 + y3 + z3 + axyz
+  if(Dim == 1) {
+    if(Mult == 2) {
+      Jf2  = wedge(jacob(Jf1),3-Dim), Jf1;
+      Jf2  = std(Jf2);
+      Dim  = dim(Jf2);
+      if (Dim == 0) { return("R:conic + line"); }       // x3 + xyz
+      if (Dim == 1) { return("Q:cuspidal cubic"); }  // x3 + yz2
+    }
+    if(Mult == 3) {
+      Jf2 = wedge(jacob(Jf1),3-Dim), Jf1;
+      Jf2 = std(Jf2);
+      Dim = dim(Jf2);
+      if(Dim == 0) { return("T:three lines"); } // xyz
+      if(Dim == 1) { return("S:conic + tangent"); }     // x2z + yz2
+    }
+    if(Mult == 4) { return("U:three concurrent lines"); }       // x3 + xz2
+  }
+  if(Dim == 2) {
+    if(Mult == 1) { return("V:doubleline + line"); }    // x2y
+    if(Mult == 2) { return("V': tripple line"); }       // x3
+  }
+  if(Dim == 3) { return("P[9]:nodal cubic"); }  // x3 + y3 + xyz
+
+  return("");
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static proc parity  (int e)
+"USAGE:    parity()"
+{
+  int r = e div 2;
+  if( 2*r == e ) { return(0); }
+  return(1);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static proc HKclass (intvec sg)
+{
+//---------------------------- initialisation ---------------------------------
+  int    cnt = 0;
+  string SG_Typ = "";
+  list   v;
+
+  // if trace/debug mode not set, do it!
+  init_debug();
+  debug_log(1, "Milnor code : ", sg );
+  if(size(sg) == 1) { v ="A["+string(sg[1])+"]", 1; return(v); }
+  if(size(sg) == 3) { return(HKclass3(sg, SG_Typ, cnt)); }
+  if(size(sg) == 5) { return(HKclass5(sg, SG_Typ, cnt)); }
+  if(size(sg) == 7) { return(HKclass7(sg, SG_Typ, cnt)); }
+  debug_log(1, "No solution found." );
+  v = "", 0;
+  return(v);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static proc HKclass3 (intvec sg, string SG_Typ, int cnt)
+{
+  list v;
+
+  if(sg[1] == 1) { v = HKclass3_teil_1(sg, SG_Typ, cnt); }
+  debug_log(6, "HKclass3: ", v[1], " cnt=", v[2]);
+  return(v);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static proc HKclass3_teil_1 (intvec sg, string SG_Typ, int cnt)
+{
+  int  k, r, s;
+  list v;
+
+  debug_log(2, "entering HKclass3_teil_1", sg);
+  if(sg[2]==1) { SG_Typ=SG_Typ+" D[k]=D["+string(sg[3]+3)+"]";cnt++;} // D[k]
+  if(sg[2]>=1) {
+    if( parity(sg[2])) { // sg[2] ist ungerade
+      if(sg[2]<=sg[3]) {
+        k = (sg[2]+1) div 2;
+        if(k>1) {
+          cnt++;
+          SG_Typ=SG_Typ+" J[k,r]=J["+string(k)+","+string(sg[3]+1-2*k)+"]";
+        }// J[k,r]
+      }
+      if(sg[2]==sg[3]+2) {                              // E[6k+2]
+        k = (sg[2]-1) div 2;
+        if(k>0) {cnt++; SG_Typ=SG_Typ+" E[6k+2]=E[" + string(6*k+2) + "]"; }
+      }
+    }
+    else {              // sg[2] ist gerade
+      if( sg[2] == sg[3]+1) {                           // E[6k]
+        k = sg[2] div 2; cnt++; SG_Typ=SG_Typ + " E[6k]=E[" + string(6*k) + "]"; }
+      if( sg[2] == sg[3]) {                             // E[6k+1]
+        k=sg[2] div 2; cnt++; SG_Typ=SG_Typ+" E[6k+1]=E["+string(6*k+1)+"]"; }
+    }
+  }
+
+  debug_log(2, "finishing HKclass3_teil_1");
+  debug_log(6, "HKclass3: ", SG_Typ, " cnt=", cnt);
+  v = SG_Typ, cnt;
+  return(v);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static proc HKclass5 (intvec sg, string SG_Typ, int cnt)
+{
+  list v;
+
+  if(sg[1] == 1 && sg[2] == 1) { v = HKclass5_teil_1(sg, SG_Typ,cnt); }
+  if(sg[1] == 1 && sg[2] == 0) { v = HKclass5_teil_2(sg, SG_Typ,cnt); }
+  debug_log(6, "HKclass5: ", v[1], " cnt=", v[2]);
+  return(v);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static proc HKclass5_teil_1 (intvec sg, string SG_Typ, int cnt)
+{
+  int  k, r, s;
+  list v;
+
+  debug_log(2, "entering HKclass5_teil_1", sg);
+  if(parity(sg[3])) {  // Dritte Stelle soll ungerade sein
+    k = (sg[3]+1) div 2;
+    if(sg[3] > sg[4]) {
+      k--;
+      if( (sg[4]==sg[5]) && (sg[3] == sg[4]+1) && k>0 ) { // W[12k+6]
+        SG_Typ = SG_Typ + " W[12k+6]=W["+string(12*k+6)+"]"; cnt++;
+      }
+      if( (sg[3]==sg[5]) && (sg[3] == sg[4]+2) && k>0 ) { // W[12k+5]
+        SG_Typ = SG_Typ + " W[12k+5]=W["+string(12*k+5)+"]"; cnt++;
+      }
+    }
+    else {  // sg[3] <= sg[4]
+      if( (sg[3]==sg[4]) && (sg[5] >= sg[3]) ) {
+        r = sg[5] - sg[4];
+        SG_Typ=SG_Typ +" X[k,r]=X["+string(k)+","+string(r)+"]"; cnt++;
+      }
+      if( (sg[3]==1) && (sg[4]==3) && (sg[5]>=sg[4])){    // Z[1,r]
+        r = sg[5] - sg[4];
+        SG_Typ = SG_Typ + " Z[1,r]=Z[1,"+string(r)+"]"; cnt++;
+      }
+
+      if( sg[4] == sg[5]) {
+        if(parity(sg[4])) {                                  // Z[k,r,0]
+          r = (sg[4] - sg[3]) div 2;
+          if( r>0 ) { cnt++;
+            SG_Typ = SG_Typ + " Z[k,r,0]=Z["+string(k)+","+string(r)+",0]";
+          }
+        }
+        else {                                                // Z[k,12k+6r]
+          r = (sg[4] - 2*k) div 2; cnt++;
+          SG_Typ = SG_Typ+" Z[k,12k+6r]=Z["+string(k)+","+string(12*k+6*r)+"]";
+        }
+      }
+
+      if( parity(sg[4]) ) {  // 4. Stelle ist ungerade
+        if(sg[4] == sg[5]+2) {                              // Z[k,12k+6r+1]
+          r = (sg[4]-2*k-1) div 2; cnt++;
+          SG_Typ=SG_Typ+" Z[k,12k+6r+1]=Z["+string(k)+",";
+          SG_Typ=SG_Typ+string(12*k+6*r+1)+"]";
+       }
+       if( (sg[5]>sg[4]) && (sg[4]>sg[3]) ) {           // Z[k,r,s]
+          r = (sg[4] - sg[3]) div 2; cnt++;
+          s = sg[5] - sg[4];
+          SG_Typ = SG_Typ + " Z[k,r,s]=";
+          SG_Typ = SG_Typ + "Z["+string(k)+","+string(r)+","+string(s)+"]";
+        }
+      }
+      else {  // 4. Stelle ist gerade
+        if( sg[4] == sg[5]+1) {                             // Z[k,12k+6r-1]
+          r = (sg[4] - 2*k) div 2; cnt++;
+          SG_Typ=SG_Typ+" Z[k,12k+6r-1]=Z["+string(k)+",";
+          SG_Typ=SG_Typ+string(12*k+6*r-1)+"]";
+        }
+      }
+
+      if(sg[4]>sg[3]) {                                     // Y[k,r,s]
+        r = sg[4] - sg[3];
+        s = sg[5] - sg[3] + r;
+        if( s<0 ) { s = -s; }
+        SG_Typ = SG_Typ + " Y[k,r,s]="; cnt++;
+        SG_Typ = SG_Typ + "Y["+string(k)+","+string(r)+","+string(s)+"]";
+      }
+    }
+  }
+  else {  // Dritte Stelle soll gerade sein
+    k = sg[3] div 2;
+    // sortiere verschiedene W's
+    if(k>0) {
+      if( (sg[4]==2*k-1) && (sg[4]==sg[5]) ) {  // W[12k]
+        SG_Typ = SG_Typ + " W[12k]=W["+string(12*k)+"]"; cnt++;
+      }
+      if( (sg[4]==2*k-1) && (sg[3]==sg[5]) ) {  // W[12k+1]
+        SG_Typ = SG_Typ + " W[12k+1]=W["+string(12*k+1)+"]"; cnt++;
+      }
+      if( (sg[4]==2*k) && (sg[5]>=sg[4]) ) {    // W[k,r]
+        r = sg[5] - sg[4];
+        SG_Typ=SG_Typ+" W[k,r]=W["+string(k)+","+string(r)+"]"; cnt++;
+      }
+      if( (sg[5]==2*k-1) && (sg[4]>sg[3]) ) {  // W#[k,2r-1]
+        r = sg[4] - sg[3]; cnt++;
+        SG_Typ = SG_Typ + " W#[k,2r-1]=W["+string(k)+","+string(2*r-1)+"]";
+      }
+      if( (sg[5]==2*k) && (sg[4]>sg[3]) ) {  // W#[k,2r]
+        r = sg[4] - sg[3]; cnt++;
+        SG_Typ = SG_Typ + " W#[k,2r]=W["+string(k)+","+string(2*r)+"]";
+      }
+    }   // ENDIF k>0
+  }
+  debug_log(2, "finishing HKclass5_teil_1");
+  debug_log(6, "HKclass5_teil_1: ", SG_Typ, " cnt=", cnt);
+  v = SG_Typ, cnt;
+  return(v);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static proc HKclass5_teil_2 (intvec sg, string SG_Typ, int cnt)
+{
+  int k, r, s;
+  list v;
+
+  debug_log(2, "entering HKclass5_teil_2", sg);
+  // finde T[p,q,r]
+  k = sg[3] + 1;
+  r = sg[4] + k;
+  s = sg[5] + r - 1;
+  if(k>2 && r>2 && s>2) {                               // T[k,r,s]
+    cnt++;
+    SG_Typ = SG_Typ + " T[k,r,s]=T["+string(k)+","+string(r)+","+string(s)+"]";
+  }
+
+  // finde weitere Moeglicjkeiten.
+  if(sg[3]==2) {  // Q[...]
+    if(parity(sg[4])) { // 4. Stelle ist ungerade.
+      if(sg[4]==sg[5]) {                                // Q[6k+4]
+        k=(sg[4]+1) div 2; cnt++; SG_Typ=SG_Typ+" Q[6k+4]=Q["+string(6*k+4)+"]";
+      }
+      if(sg[4]+1==sg[5]) {                      // Q[6k+5]
+        k=sg[5] div 2; cnt++; SG_Typ=SG_Typ+" Q[6k+5]=Q["+string(6*k+5)+"]";
+      }
+    }
+    else { // 4. Stelle ist gerade.
+      if(sg[4]==sg[5]+1) {                      // Q[6k+6]
+        k=sg[4] div 2; cnt++; SG_Typ=SG_Typ+" Q[6k+6]=Q["+string(6*k+6)+"]";
+      }
+      if(sg[4]<sg[5]) {                 // Q[k,r]
+        k = (sg[4]+2) div 2;
+        if(k>=2) {
+          r=sg[5]+1-2*k; cnt++;
+          SG_Typ=SG_Typ+" Q[k,r]=Q["+string(k)+","+string(r)+"]";
+        }
+      }
+    }
+  }
+  else {           // S[...]
+    if(parity(sg[3])) {  // 3. Stelle ist ungerade.
+      k = (sg[3]-1) div 2;
+      if(sg[3]==sg[4]+3 && sg[3]==sg[5]+2) {    // S[12k-1]
+        cnt++; SG_Typ = SG_Typ + " S[12k-1]=S["+string(12*k-1)+"]";
+      }
+      if(sg[3]==sg[4]+3 && sg[3]==sg[5]+1) {    // s[12k]
+        cnt++; SG_Typ = SG_Typ + " S[12k]=S["+string(12*k)+"]";
+      }
+      if(sg[3]==sg[4]+2 && sg[5]>=sg[4]+1) {    // S[k,r]
+        r = sg[5] - 2*k; cnt++;
+        SG_Typ = SG_Typ + " S[k,r]=S["+string(k)+","+string(r)+"]";
+      }
+      if(sg[3]==sg[5]+2 && sg[4]>=sg[5]) {              // S#[k,2r-1]
+        r = sg[4] - 2*k + 1; cnt++;
+        SG_Typ = SG_Typ + " S#[k,2r-1]=S#["+string(k)+","+string(2*r-1)+"]";
+      }
+      if(sg[3]==sg[5]+1 && sg[4]>=sg[5]) {              // S#[k,2r]
+        r = sg[4] - 2*k + 1; cnt++;
+        SG_Typ = SG_Typ + " S#[k,2r]=S#["+string(k)+","+string(2*r)+"]";
+      }
+    }
+    else { // 3. Stelle ist gerade.
+      if(sg[3]==sg[5]+1 && sg[5]==sg[4]+3) {    // S[12k+4]
+        k = (sg[3]-2) div 2; cnt++;
+        SG_Typ = SG_Typ + " S[12k+4]=S["+string(12*k+4)+"]";
+      }
+      if(sg[3]==sg[5]+2 && sg[5]==sg[4]+1) {    // S[12k+5]
+        k = (sg[3]-2) div 2; cnt++;
+        SG_Typ = SG_Typ + " S[12k+5]=S["+string(12*k+5)+"]";
+      }
+    }
+  }
+  debug_log(2, "finishing HKclass5_teil_2");
+  debug_log(6, "HKclass5_teil_2: ", SG_Typ, " cnt=", cnt);
+  v = SG_Typ, cnt;
+  return(v);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static proc HKclass7 (intvec sg, string SG_Typ, int cnt)
+{
+  list v;
+
+  if(sg[1]==1 && sg[2]==0 && sg[3]==1) {
+      v=HKclass7_teil_1(sg, SG_Typ, cnt);
+  }
+  else {
+      v[1]="not in list";
+      v[2]=0;
+  }
+  debug_log(6, "HKclass7: ", v[1], " cnt=", v[2]);
+  return(v);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static proc HKclass7_teil_1 (intvec sg, string SG_Typ, int cnt)
+{
+  int k, r, s;
+  list v;
+
+  debug_log(2, "entering HKclass7_teil_1", sg);
+  if(sg[4] == 2) {                                      // V[...]
+    if(sg[5] == 0 && sg[6] == 1 && sg[7]>0) {   // V[1,r]
+      r = sg[7] - 1; cnt++; SG_Typ = SG_Typ + " V[1,r]=V[1,"+string(r)+"]";
+    }
+    if(sg[5] == 1 && sg[7] == 1) {                      // V#[1,2r-1]
+      r=sg[6]+1; cnt++; SG_Typ=SG_Typ+" V#[1,2r-1]=V#[1,"+string(2*r-1)+"]";
+    }
+    if(sg[5] == 1 && sg[7] == 2) {                      // V#[1,2r]
+      r=sg[6]+1; cnt++; SG_Typ=SG_Typ+" V#[1,2r]=V#[1,"+string(2*r)+"]";
+    }
+  }
+  //            Moegliche U[...]'s
+  k = sg[4];
+  if(sg[5]==2*k-1 && sg[6]==0 && sg[7]==sg[5]) {        // U[12k]
+    cnt++;SG_Typ = SG_Typ + " U[12k]=U["+string(12*k)+"]";
+  }
+  if(sg[5]==2*k && sg[6]==0 && sg[7]==sg[5]) {  // U[12k+4]
+    cnt++;SG_Typ = SG_Typ + " U[12k+4]=U["+string(12*k+4)+"]";
+  }
+  if(sg[5]==2*k-1 && sg[6]>0 && sg[7]==sg[5]) { // U[k,2r-1]
+    r=sg[6]-1; cnt++;
+    SG_Typ=SG_Typ+" U[k,2r-1]=U["+string(k)+","+string(2*r-1)+"]";
+  }
+  if(sg[5]==2*k-1 && sg[6]>0 && sg[7]==2*k) {   // U[k,2r]
+    r = sg[6]; cnt++;
+    SG_Typ = SG_Typ + " U[k,2r]=U["+string(k)+","+string(2*r)+"]";
+  }
+  debug_log(2, "finishing HKclass7_teil_1");
+  debug_log(6, "HKclass7_teil_1: ", SG_Typ, " cnt=", cnt);
+  v = SG_Typ, cnt;
+  return(v);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+proc singularity(string typ, list #)
+"USAGE:    singularity(t, l); t=string (name of singularity),
+          l=list of integers/polynomials (indices/parmeters of singularity)
+COMPUTE:  get the singularity named by type t from the database.
+          list l is as follows: @*
+          l= k [,r [,s [,a [,b [,c [,d]..]: k,r,s=int   a,b,c,d=poly. @*
+          The name of the dbm-databasefile is: NFlist.[dir,pag].
+          The file is found in the current directory. If it does not
+          exist, please run the script MakeDBM first.
+RETURN:   Normal form and corank of the singularity named by type t and its
+          index (indices) l.
+EXAMPLE:  example singularity; shows an example"
+{
+  poly a1, a2, a3, a4, f;
+  int k, r, s;
+  int len = size(#);
+  list v, ret;
+
+  classify_init();
+  ret = 0, 0;
+  k = #[1];
+  if(len>=2) { r = #[2]; }
+  else { r = 0; }
+  if(len>=3) { s = #[3]; }
+  else { s = 0; }
+  if( k<0 || r<0 || s<0) {
+    "Initial condition failed: k>=0; r>=0; s>=0";
+    "k="+string(k)+" r="+string(r)+"   s="+string(s);
+    return(ret);
+  }
+  int crk;
+
+  init_debug();
+  def ring_top=basering;
+
+  if(len>=4) { a1 = #[4]; }
+  else { a1=1; }
+  if(len>=5) { a2 = #[5]; }
+  else { a2=1; }
+  if(len>=6) { a3 = #[6]; }
+  else { a3=1; }
+  if(len>=7) { a4 = #[7]; }
+  else { a4=1; }
+
+  debug_log(4, "Values: len=", string(len), " k=", string(k), " r=",
+        string(r));
+  if(defined(RingNF) != 0 ) { kill RingNF; }
+  ring RingNF=char(basering),(x,y,z),(c,ds);
+  poly f;
+  map Conv=ring_top,maxideal(1);
+  v = Singularitaet(typ, k, r, s, Conv(a1), Conv(a2), Conv(a4), Conv(a4));
+  f, crk = v[1..2];
+  debug_log(2, "Info=", f );
+  setring ring_top;
+  if(defined(Phi) != 0 ) { kill Phi; }
+  map Phi=RingNF,maxideal(1);
+
+  ret = Phi(f), crk;
+  return(ret);
+}
+example
+{ "EXAMPLE"; echo=2;
+  ring r=0,(x,y,z),(c,ds);
+  init_debug(0);
+  singularity("E[6k]",6);
+  singularity("T[k,r,s]", 3, 7, 5);
+  poly f=y;
+  singularity("J[k,r]", 4, 0, 0, f);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static proc Singularitaet (string typ,int k,int r,int s,poly a,poly b,poly c,poly d)
+{
+  list   v;
+  string DBMPATH=system("getenv","DBMPATH");
+  string DatabasePath, Database, S, Text, Tp;
+  poly   f, f1;
+  int    crk, Mu, ret;
+  intvec MlnCd;
+
+  if( DBMPATH != "" ) { DatabasePath = DBMPATH+"/NFlist"; }
+  else { DatabasePath = "NFlist"; }
+  Database="DBM: ",DatabasePath;
+
+  link dbmLink=Database;
+  debug_log(2, "Opening Singalarity-database: ", newline, Database);
+  Tp = read(dbmLink, typ);
+  debug_log(2,"DBMread(", typ, ")=", Tp, ".");
+  if( Tp != "(null)" && Tp !="" ) {
+    string Key = "I_", typ;
+    S = "f = ", Tp, ";";
+    debug_log(2,"S=", S, " Tp=", Tp, "Key=", Key);
+    execute(S);
+    execute(read(dbmLink, Key)+";");
+    debug_log(1, "Polynom f=", f,  "  crk=", crk, "  Mu=", Mu,
+                " MlnCd=", MlnCd);
+    v = f, crk, Mu, MlnCd;
+  }
+  else {
+    v = 0, 0, 0, 0;
+  }
+  close(dbmLink);
+  return(v);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+proc RandomPolyK (int M, string Typ)
+"USAGE:    RandomPolyK(M, Typ)"
+{
+//---------------------------- initialisation ---------------------------------
+  int    n, b, i, k, r, s, crk;
+  ideal  B;
+  map    Phi;
+  string txt, Tp;
+  list   v;
+
+  def ring_ext=basering;
+  n=4;
+  if(M<5) { M = 5; }
+
+  k = random(1, M);
+  r = random(-5, 2*M);
+  s = random(-5, 2*M);
+  if(r<0) { r = 0; }
+  if(s<0) { s = 0; }
+
+  ring RgAnf=char(basering),(x,y,z,t),(c,ds);
+  poly f;
+
+  v = singularity(Typ, k, r, s);
+  f, crk = v[1..2];
+//  f = f +t2;
+  if(crk==1) { f = f + y2 + z2; }
+  if(crk==2) { f = f + z2; }
+  txt="RandomPoly-Series: gewaehlt fall "+Typ+" mit";
+  txt=txt+" f="+string(f);
+  txt;
+  setring ring_ext;
+  B = maxideal(1);
+
+  r=1;
+  for(i=n; i>0; i--,r++) {
+//  for(i=1; i<=n; i=i+1)
+    B[rvar(x(r))] = x(i);
+    if(i>2 && random(1,10)<3) { B[rvar(x(r))] = B[rvar(x(r))] + x(i-1); }
+//    if(i==1 && random(1,10)<4) { B[rvar(x(r))] = B[rvar(x(r))]- x(n); }
+    if(i>0) {
+      for(b=3; b<5; b=b+1) {
+        // B[rvar(x(r))] = B[rvar(x(r))] + random(0,9) * x(i)^(b+2);
+        if(random(1,20)<3) {
+          B[rvar(x(r))] = B[rvar(x(r))] - random(-2,2)*x(b)^2;
+        }
+      }
+    }
+  }
+  Phi=RgAnf, B;
+  Phi;
+  poly fr=Phi(f);
+  fr = fr+(x(1)+x(2))^2;
+//  return(Phi(f));
+  return(fr);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+proc debug_log (int level, list #)
+"USAGE:    debug_log(level,li); level=int, li=comma separated \"message\" list
+COMPUTE:  print \"messages\" if level>=@DeBug.
+          useful for user-defined trace messages.
+EXAMPLE:  example debug_log; shows an example
+SEE ALSO: init_debug
+"
+{
+   int len = size(#);
+//   int printresult = printlevel - level +1;
+//   if(level>1) {
+//     dbprint(printresult, "Debug:("+ string(level)+ "): ", #[2..len]);
+//   }
+//   else { dbprint(printresult, #[1..len]); }
+   if( defined(@DeBug) == 0 ) { init_debug(); }
+   if(@DeBug>=level) {
+      if(level>1) { "Debug:("+ string(level)+ "): ", #[1..len]; }
+      else { #[1..len]; }
+   }
+}
+example
+{ "EXAMPLE:"; echo=2;
+  example init_debug;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+proc init_debug(list #)
+"USAGE:    init_debug([level]);  level=int
+COMPUTE:  Set the global variable @DeBug to level. The variable @DeBug is
+          used by the function debug_log(level, list of strings) to know
+          when to print the list of strings. init_debug() reports only
+          changes of @DeBug.
+NOTE:     The procedure init_debug(n); is usefull as trace-mode. n may
+          range from 0 to 10, higher values of n give more information.
+EXAMPLE:  example init_debug; shows an example"
+{
+  int newDebug=0;
+  if( defined(@DeBug) != 0 ) { newDebug = @DeBug; }
+
+  if( size(#) > 0 ) {
+    newDebug=#[1];
+  }
+  else {
+    string s=system("getenv", "SG_DEBUG");
+    if( s != "" && defined(@DeBug)==0) {
+      s="newDebug="+s;
+      execute(s);
+    }
+  }
+  if( defined(@DeBug) == 0) {
+    int @DeBug = newDebug;
+    export @DeBug;
+    if(@DeBug>0) { "Debugging level is set to ", @DeBug; }
+  }
+  else {
+    if( (size(#) == 0) && (newDebug < @DeBug) ) { return(); }
+    if( @DeBug != newDebug) {
+      int oldDebug = @DeBug;
+      @DeBug = newDebug;
+      if(@DeBug>0) { "Debugging level change from ", oldDebug, " to ", at DeBug; }
+      else {
+        if( @DeBug==0 && oldDebug>0 ) { "Debugging switched off."; }
+      }
+    }
+  }
+  printlevel = @DeBug;
+}
+example
+{ "EXAMPLE:"; echo=2;
+  init_debug();
+  debug_log(1,"no trace information printed");
+  init_debug(1);
+  debug_log(1,"some trace information");
+  init_debug(2);
+  debug_log(2,"nice for debugging scripts");
+  init_debug(0);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+proc basicinvariants(poly f)
+"USAGE:    basicinvariants(f);   f = poly
+COMPUTE:  Compute basic invariants of f: an upper bound d for the
+          determinacy, the milnor number mu and the corank c of f
+RETURN:   intvec: d, mu, c
+EXAMPLE:  example basicinvariants; shows an example"
+{
+  intvec v;
+  ideal Jfs = std(jacob(f));
+  v[1] = system("HC")+1;
+  v[2] = vdim(Jfs);
+  v[3] = corank(f);
+  if( v[2]<v[1] ) { v[1] = v[2]+1; }
+  return(v);
+}
+example
+{ "EXAMPLE:"; echo=2;
+   ring r=0,(x,y,z),ds;
+   basicinvariants((x2+3y-2z)^2+xyz-(x-y3+x2*z3)^3);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+proc corank(poly f)
+"USAGE:    corank(f);   f=poly
+RETURN:   the corank of the Hessian matrix of f, of type int
+REMARK:   corank(f) is the number of variables occuring in the residual
+          singularity after applying 'morsesplit' to f
+EXAMPLE:  example corank; shows an example"
+{
+  matrix M = jacob(jacob(jet(f,2)));
+  list lba = bareiss(M);
+  int cr = nvars(basering) - size(module(lba[1]));
+  return(cr);
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring r=0,(x,y,z),ds;
+  poly f=(x2+3y-2z)^2+xyz-(x-y3+x2*z3)^3;
+  corank(f);
+}
+///////////////////////////////////////////////////////////////////////////////
+static proc Faktorisiere(poly f, poly fk, int pt, int k, intvec RFlg)
+{
+//---------------------------- initialisation ---------------------------------
+  poly   a, b, Relation;
+  ideal  B, Jfsyz;
+  map    PhiG, VERT;
+  matrix Mat;
+  list   v;
+  def    ring_top=basering;
+
+  // Ziel: bestimme a,b sodass  fk = (ax+by^k)^pt gilt.
+  B    = maxideal(1);
+  PhiG = ring_top,B;
+  debug_log(2, "Faktor: f=",Show(f)," Jet=",Show(fk)," k=",k," exp=",pt);
+
+//----------------------- compute role of x and y -----------------------------
+  Jfsyz = fk, diff(fk, x(1));
+  Mat   = matrix(syz(Jfsyz));
+  if( (fk-subst(fk,x(1),0)) != 0  &&  (fk-subst(fk,x(2),0)) != 0 ) {
+    // Wenn k>0 ist die Wahl fuer x & y bereits getroffen
+    // sonst bestimmen x und y
+    Jfsyz    = fk, diff(fk, x(1));
+    Mat      = matrix(syz(Jfsyz));
+    Relation = -pt * Mat[2,1] / Mat[1,1];
+    a = Coeff(Relation, x(1), x(1));
+    b = Coeff(Relation, x(2), x(2)^k);
+    B = maxideal(1);
+    if( (RFlg[1]==1 && k==1) || k>1) { B[rvar(x(1))] = x(1)-b*x(2)^k; }
+    else { B[rvar(x(2))] = x(2)-b*x(1)^k; }
+    VERT = basering,B;
+    f    = VERT(f);
+    PhiG = VERT(PhiG);
+  }
+
+//------------------- permutation of x and y, if needed -----------------------
+  if( k==1 ) {
+    debug_log(2, "Fak-7:",Show(f)," jet=",Show(fk));
+    if(Coeff(jet(f, pt), x(1), x(1)^pt) == 0) {
+      VERT = basering,x(2),x(1);
+      f    = VERT(f);
+      PhiG = VERT(PhiG);
+    }
+  }
+  debug_log(2, "Fak-8:",Show(f)," jet=",Show(fk));
+  debug_log(6, "Faktorisiere liefert: f=", Show(f));
+  v[1] = f;
+  v[2] = PhiG;
+  return(v);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static proc Teile(poly f, poly fk)
+{
+  ideal  Jfsyz = f, fk;
+  poly   Relation;
+  matrix Mat = matrix(syz(Jfsyz));
+  Relation   = -1 * Mat[2,1]/Mat[1,1];
+  return(Relation);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static proc GetRf (poly fi, int n)
+"USAGE:    GetRf();"
+{
+//---------------------------- initialisation ---------------------------------
+  int    j, k, l1, l1w;
+  matrix Koef;
+  intvec RFlg;
+
+  RFlg[n] = 0;
+  intvec Haeufigkeit = RFlg;
+
+  for( j=1; j<=n ; j=j+1) {
+    Koef = coef(fi, x(j));
+    Haeufigkeit[j] = ncols(Koef);
+    if(Coeff(fi, x(j),0) == 0) { Haeufigkeit[j] = Haeufigkeit[j] + 1;}
+  }
+  for( j=n; j>0 ; j=j-1) {
+    l1  = 0;
+    l1w = 0;
+    for(k=1;k<=n;k=k+1) { if(Haeufigkeit[k]>l1w) { l1=k; l1w=Haeufigkeit[k];}}
+    RFlg[j]        = l1;
+    Haeufigkeit[l1] = 0;
+  }
+  debug_log(2, "Permutations:", RFlg);
+  return(RFlg);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static proc Show(poly g)
+{
+  string s;
+  def ring_save=basering;
+
+  execute(@ringdisplay);
+  map showpoly=ring_save,maxideal(1);
+  s = string(showpoly(g));
+  setring ring_save;
+  return (s);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static proc checkring
+{
+  int CH = char(basering);
+  if(CH >= 2 && CH<=13) {
+    "Ring has characteristic ",CH;
+    "Characteristic other than 0 or 0<char<13 is not yet implemented";
+    return(1);
+  }
+  return(0);  // characteristic of ring is OK, return (0)
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static proc DecodeNormalFormString (string S_in)
+"USAGE:    DecodeNormalFormString"
+{
+//---------------------------- initialisation ---------------------------------
+  int    C_eq, a, b, i, t, k, r, s;
+  string s1, s2, s3, s4, s_in, Typ;
+  list v = "Error", 0, 0, 0;
+
+  C_eq = find(S_in, "=")+1;
+  s_in = S_in[C_eq,30];
+  debug_log(2, "Decode:");
+
+  debug_log(2, "S_in=", S_in,"  s_in=",s_in );
+  a = find(s_in, "[")+1;
+  b = find(s_in, "]")-1;
+  t = 1;
+  k = 0;
+  r = 0;
+  s = 0;
+
+  if(a<0 || b<0) { return(v); }
+  Typ = s_in[1..a-1];
+  s1  = s_in[a..b];
+  debug_log(6, "Suche Type:", Typ);
+  //---------------------- decode between brackets ----------------------------
+  if( find(s1, ",") == 0) {
+    debug_log(8, "  Number of columns: 0");
+    s2 = "k = "+s1+";";
+    execute(s2);
+    if( (Typ=="A[") || (Typ=="D[") ) { s3 = "k"; }
+    if( Typ == "E[") { t = 6; }
+    if( Typ == "W[") { t = 12; }
+    if( Typ == "Q[") { t = 6; }
+    if( Typ == "Z[") { t = 6; }
+    if( Typ == "U[") { t = 12; }
+    if( t > 1 ) {
+      i = k;
+      k = k div t;
+      b = i - t*k;
+      if( (s1 == "Q[") && (b==0) ) { k=k-1; b=6; }
+      if(Typ == "Z[") {
+        if(b==0) { k=k-1; b=6; }
+        if(b==1) { k=k-1; b=7; }
+      }
+      if( b == 0 ) { s3 = string(t)+"k"; }
+      else { s3 = string(t)+"k+"+string(b); }
+    }
+    if( Typ == "S[") {
+      i = k+1;
+      k = i/12;
+      b = i - 12*k;
+      if( b == 1 ) { s3 = "k"; }
+      else {
+        if(b==0) { s3 = "12k"+string(b-1); }
+        else { s3 = "12k+"+string(b-1); }
+      }
+    }
+    s2 = Typ + s3 +"]";
+  }  // es kommt mindestens ein komma vor...
+  //----------------------- more than 1 parameter -----------------------------
+  else {
+    b  = find(s1, ",");
+    s2 = "k = ",s1[1..b-1],";";
+    execute(s2);
+    s1 = s1[b+1..size(s1)];
+    if(find(s1, ",") == 0) {
+      debug_log(8, "  Number of columns 1");
+      s2 = "r = "+s1+";";
+      execute(s2);
+      s4 = "r";
+      s3 = "k";
+      if(r==0) { s4 = string(0); }
+      if(k==0 && Typ=="Z[") { s3 = string(1); }
+      if(Typ[2] == "#") {
+        i = r+1;
+        r = i div 2;
+        b = i - 2*r;
+        if( b == 1 ) { s4 = "2r"; }
+        else { s4 = "2r-1"; }
+      }
+      s2 = Typ + s3 + "," + s4 +"]";
+    }  // es kommt mindestens zwei komma vor...
+    //----------------------- get third parameter -----------------------------
+    else {
+      debug_log(8, "  Number of columns >=2");
+      debug_log(2, "Y[k,r,s] / Z[k,r,s] / T[k,r,s]");
+      b  = find(s1, ",");
+      s2 = "r = ",s1[1..b-1],";";
+      execute(s2);
+      s2 = "s = ",s1[b+1..size(s1)],";";
+      execute(s2);
+      if(Typ=="Y[") { s2 = "Y[k,r,s]"; }
+      if(Typ=="Z[") { s2 = "Z[k,r,s]"; }
+      if(Typ=="T[") { s2 = "T[k,r,s]"; }
+    }
+  }
+  debug_log(2, "Looking for Normalform of ",s2,"with (k,r,s) = (",
+        k,",",r,",", s, ")" );
+  v = s2, k, r, s;
+  return(v);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+proc A_L
+"USAGE:    A_L(f);  f poly
+          A_L(s);  s string, the name of the singularity
+COMPUTE:  the normal form of f in Arnold's list of singularities in case 1,
+          in case 2 nothing has to be computed.
+RETURN:   A_L(f): compute via 'milnorcode' the class of f and return the normal
+          form of f found in the database.
+          A_L(\"name\"): get the normal form from the database for the
+          singularity given by its name.
+EXAMPLE:  example A_L; shows an example"
+{
+  // if trace/debug mode not set, do it!
+  init_debug();
+
+  if( typeof(#[1]) == "string" ) {
+    if(checkring()) { return(#[1]); }
+    return(normalform(#[1]));
+  }
+  if( typeof(#[1]) == "poly" ) {
+    if(checkring()) { return(#[1]); }
+    return(quickclass(#[1]));
+  }
+
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring r=0,(a,b,c),ds;
+  poly f=A_L("E[13]");
+  f;
+  A_L(f);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+proc normalform(string s_in)
+"USAGE:    normalform(s);  s=string
+RETURN:   Arnold's normal form of singularity with name s
+EXAMPLE:  example normalform; shows an example."
+{
+  string Typ;
+  int    k, r, s, crk;
+  int    n, i;
+  poly   f;
+  list   v;
+  def ring_ext = basering;
+  n = nvars(basering);
+  ring ring_top=char(basering),(x(1..n)),(c,ds);
+
+  if(checkring()) { return(s_in); }
+  if(nvars(basering)<=1) {
+    "We need at least 2 variables in basering, you have",nvars(basering),".";
+    return();
+  }
+  // if trace/debug mode not set, do it!
+  init_debug();
+
+  v = DecodeNormalFormString(s_in);
+  Typ, k, r, s = v[1..4];
+  if(Typ=="Error") { return(0); }
+  v = singularity(Typ, k, r, s);
+  poly f_out;
+  f_out, crk = v[1..2];
+  if(crk>1) { for(i=crk+1;i<=n;i=i+1) { f_out = f_out + x(i)^2; } }
+  setring ring_ext;
+  map conv_top2ext=ring_top,maxideal(1);
+  f = conv_top2ext(f_out);
+//  f, crk = v[1..2];
+  return(f);
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring r=0,(a,b,c),ds;
+  normalform("E[13]");
+}
+
+///////////////////////////////////////////////////////////////////////////////
+proc swap
+"USAGE:    swap(a,b);
+RETURN:   b,a if a,b is the input (any type)"
+{
+  return(#[2],#[1]);
+}
+example
+{ "EXAMPLE:"; echo=2;
+  swap("variable1","variable2");
+}
+
+///////////////////////////////////////////////////////////////////////////////
+proc Setring(int c, string name)
+"USAGE:    "
+{
+  string s="ring "+name+"=0,(x(1.."+ string(c) +")),(c,ds);";
+  return(s);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+proc internalfunctions()
+"USAGE:   internalfunctions();
+RETURN:  nothing, display names of internal procedures of classify.lib
+EXAMPLE: no example"
+{ "   Internal functions for the classification using Arnold's method,";
+ "   the function numbers correspond to numbers in Arnold's classifier:";
+ "Klassifiziere(poly f);      //determine the type of the singularity f
+  Funktion1bis (poly f, list cstn)
+  Funktion3 (poly f, list cstn)
+  Funktion6 (poly f, list cstn)
+  Funktion13 (poly f, list cstn)
+  Funktion17 (poly f, list cstn)
+  Funktion25 (poly f, list cstn)
+  Funktion40 (poly f, list cstn, int k)
+  Funktion47 (poly f, list cstn)
+  Funktion50 (poly f, list cstn)
+  Funktion58 (poly fin, list cstn)
+  Funktion59 (poly f, list cstn)
+  Funktion66 (poly f, list cstn)
+  Funktion82 (poly f, list cstn)
+  Funktion83 (poly f, list cstn)
+  Funktion91 (poly f, list cstn, int k)
+  Funktion92 (poly f, list cstn, int k)
+  Funktion93 (poly f, list cstn, int k)
+  Funktion94 (poly f, list cstn, int k)
+  Funktion95 (poly f, list cstn, int k)
+  Funktion96 (poly f, list cstn, int k)
+  Funktion97 (poly f, list cstn)
+  Isomorphie_s82_x (poly f, poly fk, int k)
+  Isomorphie_s82_z (poly f, poly fk, int k)
+  Isomorphie_s17 (poly f, poly fk, int k, int ct)
+  printresult (string f,string typ,int Mu,int m,int corank,int K)
+  ";
+  "   Internal functions for the classifcation by invariants:
+  Cubic (poly f)
+  parity (int e)             //return the parity of e
+  HKclass (intvec i)
+  HKclass3( intvec i, string SG_Typ, int cnt)
+  HKclass3_teil_1 (intvec i, string SG_Typ, int cnt)
+  HKclass5 (intvec i, string SG_Typ, int cnt)
+  HKclass5_teil_1 (intvec i, string SG_Typ, int cnt)
+  HKclass5_teil_2 (intvec i, string SG_Typ, int cnt)
+  HKclass7 (intvec i, string SG_Typ, int cnt)
+  HKclass7_teil_1 (intvec i, string SG_Typ, int cnt)
+  ";
+  "   Internal functions for the Morse-splitting lemma:
+  Morse(poly fi, int K, int corank)  //splitting lemma itself
+  Coeffs (list #)
+  Coeff
+  ";
+  "   Internal functions providing tools:
+  ReOrder(poly f)
+  Singularitaet(string typ,int k,int r,int s,poly a,poly b,poly c,poly d)
+  RandomPolyK
+  Faktorisiere(poly f, poly g, int p, int k)   compute g = (ax+by^k)^p
+  Teile(poly f, poly g);             //divides f by g
+  GetRf(poly f, int n);
+  Show(poly f);
+  checkring();
+  DecodeNormalFormString(string s);
+  Setring(int n, string ringname);
+  ";
+}
+example
+{
+  "EXAMPLE"; echo=2;
+  internalfunctions();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+proc prepRealclassify(poly f)
+"
+USAGE:    prepRealclassify(f); f poly
+RETURN:   a list, containing the modality of the singularity and the type of
+          the singularity as a string
+          @* This procedure is needed in realclassify.lib in order to avoid
+          classify() being called more than once.
+EXAMPLE:  example prepRealclassify; shows an example"
+{
+  exportinvariants(f);
+  return(list(Modality, Type));
+}
+example
+{
+  "EXAMPLE"; echo = 2;
+  ring r = 0, (x,y,z), ds;
+  poly f = (x2+3y-2z)^2+xyz-(x-y3+x2z3)^3;
+  prepRealclassify(f);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+proc modality(poly f)
+"
+USAGE:    modality(f); f poly
+RETURN:   the modality of the singularity
+EXAMPLE:  example modality; shows an example"
+{
+  exportinvariants(f);
+  return(Modality);
+}
+example
+{
+  "EXAMPLE"; echo = 2;
+  ring r = 0, (x,y,z), ds;
+  poly f = (x2+3y-2z)^2+xyz-(x-y3+x2z3)^3;
+  modality(f);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+proc complexSingType(poly f)
+"
+USAGE:    complexSingType(f); f poly
+RETURN:   the type of the singularity as a string
+EXAMPLE:  example complexSingType; shows an example"
+{
+  exportinvariants(f);
+  return(Type);
+}
+example
+{
+  "EXAMPLE"; echo = 2;
+  ring r = 0, (x,y,z), ds;
+  poly f = (x2+3y-2z)^2+xyz-(x-y3+x2z3)^3;
+  complexSingType(f);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/* some of the invariants will be exported during the computation of
+ * classify(f) such that they are accessible at for all procs in the library
+ */
+static proc exportinvariants(poly f)
+{
+  init_debug(-1);
+  if(!defined(onlyreturninvariants))
+  {
+    int onlyreturninvariants;
+    export(onlyreturninvariants);
+  }
+  onlyreturninvariants = 1;
+  if(!defined(Modality))
+  {
+    int Modality;
+    export(Modality);
+  }
+  if(!defined(Type))
+  {
+    string Type;
+    export(Type);
+  }
+  f = classify(f);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// E n d   O f   F i l e
+
diff --git a/Singular/LIB/classify_aeq.lib b/Singular/LIB/classify_aeq.lib
new file mode 100644
index 0000000..a0f4cca
--- /dev/null
+++ b/Singular/LIB/classify_aeq.lib
@@ -0,0 +1,1639 @@
+///////////////////////////////////////////////////////////////////////////////
+version="version classify_aeq.lib 4.0.0.0 Jun_2013 "; // $Id: 5c407338a0e9d6d03fda1ca89cbf7411cb1c53d3 $
+category="Singularities";
+info="
+LIBRARY: classifyAeq.lib         Simple Space Curve singularities in characteristic 0
+
+AUTHORS: Faira Kanwal Janjua     fairakanwaljanjua at gmail.com
+         Gerhard Pfister         pfister at mathematik.uni-kl.de
+
+OVERVIEW: A library for classifying the simple singularities
+          with respect to A equivalence in characteristic 0.
+  Simple Surface singularities in characteristic O have been classified by Bruce and Gaffney [4] resp.
+  Gibson and Hobbs [1] with respect to A equivalence. If the input is one of the simple singularities in
+  [1] it returns a normal form otherwise a zero ideal(i.e not simple).
+
+REFERENCES:
+  [1] Gibson,C.G; Hobbs,C.A.:Simple SIngularities of Space Curves.
+  Math.Proc. Comb.Phil.Soc.(1993),113,297.
+  [2] Hefez,A;Hernandes,M.E.:Standard bases for local rings of branches and their modules of differentials.
+  Journal of Symbolic Computation 42(2007) 178-191.
+  [3] Hefez,A;Hernandes,M.E.:The Analytic Classification Of Plane Branches. Bull.Lond Math Soc.43.(2011) 2,289-298.
+  [4] Bruce, J.W.,Gaffney, T.J.: Simple singularities of mappings (C, 0) ->(C2,0).
+  J. London Math. Soc. (2) 26 (1982), 465-474.
+
+PROCEDURES:
+          sagbiAlg(G);    Compute the Sagbi-basis of the Algebra.
+          sagbiMod(I,A);  Compute the Sagbi- basis of the Module.
+          semiGroup(G);   Compute the Semi-Group of the Algebra provided the input is Sagbi Bases of the Algebra.
+          semiMod(I,A);   Compute the Semi-Module provided that the input are the Sagbi Bases of the Algebra resp.Module.
+          planeCur(I);    Compute the type of the Simple Plane Curve singularity.
+          spaceCur(I);    Compute the type of the simple Space Curve singularity.
+";
+LIB "algebra.lib";
+LIB "curvepar.lib";
+///////////////////////////////////////////////////////////////////////////////
+proc planeCur(ideal I)
+"USAGE":  planeCur(I);  I ideal
+RETURN: An ideal.Ideal is one of the singularity in the list of Bruce and Gaffney [4]
+EXAMPLE: example planeCur;  shows an example
+"
+{
+   def R=basering;
+   I=sortMOD(I);
+   list M;
+   list K;
+   if(I==0)
+   {return(I);}
+   ideal G=sagbiAlg(I);
+   list L=semiGroup(G);
+   ideal J=diff(G,var(1));
+   J=sagbiMod(J,G);
+   M=semiMod(J,G);
+   int C=L[2];
+   ideal Z=0,0;
+   if(L[1][1]>4)
+   {
+      return(Z);
+   }
+   if(L[1][1]==1)
+   {
+        ideal A=var(1);
+        K=Guess(A);
+        if(CompareList(M,K,6)!=0)
+        {
+              return(A);
+        }
+        else
+        {
+            return(Z);
+        }
+    }
+    if(L[1][1]==2)
+    {
+         ideal A=var(1)^2,var(1)^(L[2]+1);
+         K=Guess(A);
+         if(CompareList(M,K,6)!=0)
+         {
+            return(A);
+         }
+         else
+         {
+            return(Z);
+         }
+    }
+    if(L[1][1]==4)
+    {
+          if(L[1][2]==5)
+          {
+                intvec q=4,5;
+                if((L[1]==q)&&(L[2]==12)&&(size(L[3])==7))
+                {
+                   intvec q1=3,4; intvec q2=3,4,10;
+                   if((M[4]==q1)&&(M[5]==11)&&(size(M[6])==6))
+                   {
+                       ideal A=var(1)^4,var(1)^5;
+                        K=Guess(A);
+                       if(CompareList(M,K,6)!=0)
+                       {
+                           return(A);
+                       }
+                   }
+                   if((M[4]==q2)&&(M[5]==7)&&(size(M[6])==3))
+                   {
+                       ideal A=var(1)^4,var(1)^5+var(1)^7;
+                       K=Guess(A);
+                       if(CompareList(M,K,6)!=0)
+                       {
+                         return(A);
+                       }
+                   }
+                   else
+                   {
+                      return(Z);
+                   }
+                }
+                else
+                {
+                   return(Z);
+                }
+          }
+          if(L[1][2]==6)
+          {
+                ideal A=var(1)^4,var(1)^6+var(1)^(L[1][3]-6);
+                K=Guess(A);
+                if(L[1][3] mod 2 !=0)
+                {
+                   ideal S=t4,t6+t^(M[2]-9);
+                   if(CompareList(M,K,6)!=0)
+                   {
+                      return(S);
+                   }
+                   if(CompareList(M,K,6)==0)
+                   {
+                      int m=size(K[4])+1;
+                      if(size(M[4])==m)
+                      {
+                        return(S);
+                      }
+                      else{return(Z);}
+                   }
+                }
+                else
+                {
+                   return(Z);
+                }
+          }
+          if(L[1][2]==7)
+          {
+                intvec q=4,7;list K;
+                ideal A=var(1)^4,var(1)^7;
+                ideal B=var(1)^4,var(1)^7+var(1)^9;
+                ideal T=var(1)^4,var(1)^7+var(1)^10;
+                list Q=A,B,T;
+                for(int i=1;i<=3;i++)
+                {    K=Guess(Q[i]);
+                     if(CompareList(M,K,6)!=0)
+                     {
+                        if(i==1)
+                        {
+                            return(A);
+                            break;
+                        }
+                        if(i==2)
+                        {
+                          return(B);
+                          break;
+                        }
+                        if(i==3)
+                        {
+                           return(T);
+                           break;
+                        }
+                     }
+                }
+                else
+                {
+                     return(Z);
+                }
+        }
+        else
+        {
+             return(Z);
+        }
+   }
+   if(L[1][1]==3)
+   {
+          int k=L[1][2]-1;
+          int p=L[1][2]-2;
+          if(k mod 3 ==0)
+          {
+              if(size(M[4])==2)
+              {
+                  ideal A=var(1)^3,var(1)^L[1][2];
+                  ideal B=var(1)^3,var(1)^L[1][2]+var(1)^M[5];
+                  list Q=A,B;
+                  for(int i=1;i<=2;i++)
+                  {  K=Guess(Q[i]);
+                     if(CompareList(M,K,6)!=0)
+                     {
+                        return(Q[i]);
+                     }
+                  }
+              }
+              if(size(M[4])==3)
+              {
+                  ideal A=var(1)^3,var(1)^L[1][2];
+                  ideal B=var(1)^3,var(1)^L[1][2]+var(1)^M[5];
+                  list Q=A,B;
+                  for(int i=1;i<=2;i++)
+                  {  K=Guess(Q[i]);
+                     if(CompareList(M,K,6)!=0)
+                     {
+                          return(Q[i]);
+                     }
+                  }
+              }
+              else
+              {
+                  return(Z);
+              }
+          }
+          if(p mod 3 ==0)
+          {
+               if(size(M[4])==2)
+               {
+                    ideal A=var(1)^3,var(1)^L[1][2];
+                    ideal B=var(1)^3,var(1)^L[1][2]+var(1)^M[5];
+                    list Q=A,B;
+                    for(int i=1;i<=2;i++)
+                    {    K=Guess(Q[i]);
+                         if(CompareList(M,K,6)!=0)
+                         {
+                            return(Q[i]);
+                         }
+                     }
+                }
+                if(size(M[4])==3)
+                {
+                     ideal A=var(1)^3,var(1)^L[1][2];
+                     ideal B=var(1)^3,var(1)^L[1][2]+var(1)^M[5];
+                     list Q=A,B;
+                     for(int i=1;i<=2;i++)
+                     {    K=Guess(Q[i]);
+                          if(CompareList(M,K,6)!=0)
+                          {
+                              return(Q[i]);
+                          }
+                     }
+                }
+                else
+                {
+                      return(Z);
+                }
+           }
+           else
+           {
+                 return(Z)
+           }
+   }
+}
+example
+{
+"EXAMPLE:"; echo=2;
+  ring R=0,t,Ds;
+  ideal I=t4+4t5+6t6+8t7+13t8+12t9+10t10+12t11+6t12+4t13+4t14+t16,t7+7t8+22t9+51t10+113t11+219t12+366t13+589t14+876t15+1170t16+1514t17
++1828t18+2011t19+2165t20+2163t21+1982t22+1806t23+1491t24+1141t25+889t26+588t27+379t28+252t29+120t30+72t31+36t32+9t33+9t34+t36;
+  planeCur(I);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+proc spaceCur(ideal I)
+"USAGE":  spaceCur(I);  I ideal
+RETURN: an ideal. Ideal is one of the singularity  in the list of C.G.Gibson and C.A.Hobbs.
+EXAMPLE: example spaceCur;  shows an example
+"
+{
+   def R=basering;
+   I=sortMOD(I);
+   list M;
+   list K;
+   if(I==0)
+   {return(I);}
+   ideal G=sagbiAlg(I);
+   if(size(G)<=2){return(planeCur(G));}
+   list L=semiGroup(G);
+   ideal J=diff(G,var(1));
+   J=sagbiMod(J,G);
+   M=semiMod(J,G);
+   int C=L[2];
+   ideal Z=0,0,0;
+   if(L[1][1]>5)
+   {
+      return(Z);
+   }
+   if(L[1][1]==3)
+   {
+          int k=L[1][2]-1;
+          int p=L[1][2]-2;
+          if(k mod 3 ==0)
+          {
+               poly q=var(1)*(J[2])-G[2];
+               if(leadexp(q)!=leadexp(J[3]))
+               {
+                  if(size(M[4])!=3)
+                  {
+                     ideal B=var(1)^3,var(1)^L[1][2]+var(1)^M[5],var(1)^L[1][3];
+                     return(B);
+                  }
+                  if(size(M[4])==3)
+                  {
+                     ideal I1=G[1],G[2];
+                     I1=sortMOD(I1);
+                     ideal T=sagbiAlg(I1);
+                     ideal J1=diff(T,var(1));
+                     J1=sagbiMod(J1,T);
+                     K=semiMod(J1,T);
+                     if(size(K[4])!=2)
+                     {
+                           ideal B=var(1)^3,var(1)^L[1][2]+var(1)^M[5],var(1)^L[1][3];
+                          return(B);
+                     }
+                     if(size(K[4])==2)
+                     {
+                         ideal A=var(1)^3,var(1)^L[1][2],var(1)^L[1][3];
+                          return(A);
+                     }
+                  }
+               }
+               if(leadexp(q)==leadexp(J[3]))
+               {
+                  if(size(M[4])!=3)
+                  {
+                      ideal B=var(1)^3,var(1)^L[1][2]+var(1)^M[5],var(1)^L[1][3];
+                      return(B);
+                  }
+                  if(size(M[4])==3)
+                  {
+                      ideal I1=G[1],G[2];
+                      I1=sortMOD(I1);
+                      ideal T=sagbiAlg(I1);
+                      ideal J1=diff(T,var(1));
+                      J1=sagbiMod(J1,T);
+                      K=semiMod(J1,T);
+                      if(size(K[4])!=2)
+                      {
+                            ideal B=var(1)^3,var(1)^L[1][2]+var(1)^M[5],var(1)^L[1][3];
+                            return(B);
+                      }
+                      if(size(K[4])==2)
+                      {
+                           ideal A=var(1)^3,var(1)^L[1][2],var(1)^L[1][3];
+                           return(A);
+                      }
+                  }
+               }
+          }
+          if(p mod 3 ==0)
+          {
+                poly q=var(1)^3*(J[2])-var(1)^2*(G[2]);
+               if(leadexp(q)!=leadexp(J[3]))
+               {
+                  if(size(M[4])!=3)
+                  {
+                     ideal B=var(1)^3,var(1)^L[1][2]+var(1)^M[5],var(1)^L[1][3];
+                     return(B);
+                  }
+                  if(size(M[4])==3)
+                  {
+                       ideal I1=G[1],G[2];
+                       I1=sortMOD(I1);
+                       ideal T=sagbiAlg(I1);
+                       ideal J1=diff(T,var(1));
+                       J1=sagbiMod(J1,T);
+                       K=semiMod(J1,T);
+                       if(size(K[4])!=2)
+                       {
+                           ideal B=var(1)^3,var(1)^L[1][2]+var(1)^M[5],var(1)^L[1][3];
+                           return(B);
+                       }
+                       if(size(K[4])==2)
+                       {
+                           ideal A=var(1)^3,var(1)^L[1][2],var(1)^L[1][3];
+                           return(A);
+                       }
+                 }
+              }
+              if(leadexp(q)==leadexp(J[3]))
+              {
+                  if(size(M[4])!=3)
+                  {
+                        ideal B=var(1)^3,var(1)^L[1][2]+var(1)^M[5],var(1)^L[1][3];
+                        return(B);
+                  }
+                  if(size(M[4])==3)
+                  {
+                       ideal I1=G[1],G[2];
+                       ideal T=sagbiAlg(I1);
+                       ideal J1=diff(T,var(1));
+                       J1=sagbiMod(J1,T);
+                       K=semiMod(J1,T);
+                       if(size(K[4])!=2)
+                       {
+                           ideal B=var(1)^3,var(1)^L[1][2]+var(1)^M[5],var(1)^L[1][3];
+                           return(B);
+                       }
+                       if(size(K[4])==2)
+                       {
+                           ideal A=var(1)^3,var(1)^L[1][2],var(1)^L[1][3];
+                           return(A);
+                       }
+                  }
+             }
+           }
+           else
+           {
+                 return(Z);
+           }
+   }
+   if(L[1][1]==4)
+   {
+      if(L[1][2]==5)
+      {
+         if(L[1][3]==11)
+         {
+             ideal A=var(1)^4,var(1)^5,var(1)^11;
+             ideal B=var(1)^4,var(1)^5+var(1)^7,var(1)^11;
+             list Q=A,B;
+             ideal Ij=jet(I,10);
+             Ij=simplify(Ij,2);
+             ideal Gj=sagbiAlg(Ij);
+             list Lj=semiGroup(Gj);
+             ideal Jj=diff(Gj,var(1));
+             Jj=sagbiMod(Jj,Gj);
+             list Mj=semiMod(Jj,Gj);
+             if(size(Mj[4])==2)
+             {
+                 K=Guess(Q[1]);
+                 if(CompareList(M,K,6)!=0)
+                 {
+                    return(Q[1]);
+                 }
+             }
+             if(size(Mj[4])==3)
+             {
+                 K=Guess(Q[2]);
+                 if(CompareList(M,K,6)!=0)
+                 {
+                    return(Q[2]);
+                 }
+             }
+         }
+         if(L[1][3]!=11)
+         {
+              ideal A=var(1)^4,var(1)^5,var(1)^6;
+              ideal B=var(1)^4,var(1)^5,var(1)^7;
+              list Q=A,B;
+              for(int i=1;i<=2;i++)
+              {
+                 K=Guess(Q[i]);
+                 if(CompareList(M,K,6)!=0)
+                 {
+                    return(Q[i]);
+                    break;
+                 }
+              }
+         }
+         else
+         {return(Z);
+         }
+      }
+      if(L[1][2]==6)
+      {
+          if(size(L[1])==3)
+          {
+               if(size(M[4])==3)
+               {
+                   ideal A=var(1)^4,var(1)^6,var(1)^L[1][3];
+                   K=Guess(A);
+                   if(CompareList(M,K,6)!=0)
+                   {
+                       return(A);
+                   }
+                   else
+                   {
+                       return(Z);
+                   }
+               }
+               if(size(M[4])==4)
+               {
+                   ideal A=var(1)^4,var(1)^6+var(1)^(L[1][3]-2),var(1)^L[1][3];
+                   K=Guess(A);
+                   if(CompareList(M,K,6)!=0)
+                   {
+                          return(A);
+                   }
+                   else
+                   {
+                       return(Z);
+                   }
+               }
+          }
+          if(size(L[1])==4)
+          {
+               if(size(M[4])==4)
+               {
+                   ideal A=var(1)^4,var(1)^6+var(1)^(L[1][3]-4),var(1)^L[1][3];
+                   K=Guess(A);
+                   if(CompareList(M,K,6)!=0)
+                   {
+                       return(A);
+                   }
+                   else
+                   {
+                       return(Z);
+                   }
+               }
+               if(size(M[4])==5)
+               {
+                   ideal A=var(1)^4,var(1)^6+var(1)^(L[1][4]-8),var(1)^L[1][4];
+                   K=Guess(A);
+                   if(CompareList(M,K,6)!=0)
+                   {
+                          return(A);
+                   }
+                   else
+                   {
+                       return(Z);
+                   }
+               }
+          }
+          else
+          {
+              return(Z);
+          }
+      }
+      if(L[1][2]==7)
+      {
+          if(L[1][3]==9)
+          {
+               ideal A=var(1)^4,var(1)^7,var(1)^9+var(1)^10;
+               ideal B=var(1)^4,var(1)^7,var(1)^9;
+               list Q=A,B;
+               for(int i=1;i<=2;i++)
+               {
+                  K=Guess(Q[i]);
+                  if(CompareList(M,K,6)!=0)
+                  {
+                     return(Q[i]);
+                     break;
+                  }
+               }
+          }
+          if(L[1][3]==10)
+          {
+               ideal A=var(1)^4,var(1)^7,var(1)^10;
+               ideal B=var(1)^4,var(1)^7+var(1)^9,var(1)^10;
+               list Q=A,B;
+               for(int i=1;i<=2;i++)
+               {
+                    K=Guess(Q[i]);
+                   if(CompareList(M,K,6)!=0)
+                   {
+                      return(Q[i]);
+                      break;
+                   }
+               }
+          }
+          if(L[1][3]==13)
+          {
+               ideal A=var(1)^4,var(1)^7,var(1)^13;
+               ideal B=var(1)^4,var(1)^7+var(1)^9,var(1)^13;
+               list Q=A,B;
+               ideal Ij=jet(I,12);
+               Ij=simplify(Ij,2);
+               ideal Gj=sagbiAlg(Ij);
+               list Lj=semiGroup(Gj);
+               ideal Jj=diff(Gj,var(1));
+               Jj=sagbiMod(Jj,Gj);
+               Jj=jet(Jj,12);
+               Jj=simplify(Jj,2);
+               list Mj=semiMod(Jj,Gj);
+               if(size(Jj)==2)
+               {
+                    K=Guess(Q[1]);
+                    if(CompareList(M,K,6)!=0)
+                    {
+                       return(A);
+                       break;
+                    }
+               }
+               if(size(Jj)==3)
+               {
+                    K=Guess(Q[2]);
+                    if(CompareList(M,K,6)!=0)
+                    {
+                       return(B);
+                       break;
+                    }
+                }
+          }
+          if(L[1][3]==17)
+          {
+                ideal A=var(1)^4,var(1)^7,var(1)^17;
+                ideal B=var(1)^4,var(1)^7+var(1)^9,var(1)^17;
+                ideal T=var(1)^4,var(1)^7+var(1)^10,var(1)^17;
+                list Q=A,B,T;
+                for(int i=1;i<=3;i++)
+                {
+                    K=Guess(Q[i]);
+                    if(CompareList(M,K,6)!=0)
+                    {
+                        if(i==2)
+                        {
+                           return(Q[i]);
+                           break;
+                        }
+                        else
+                        {
+                             ideal Ij=jet(I,16);
+                             Ij=simplify(Ij,2);
+                             ideal Gj=sagbiAlg(Ij);
+                             list Lj=semiGroup(Gj);
+                             ideal Jj=diff(Gj,var(1));
+                             Jj=sagbiMod(Jj,Gj);
+                             Jj=jet(Jj,16);
+                             Jj=simplify(Jj,2);
+                             list Mj=semiMod(Jj,Gj);
+                             if(size(Jj)==2)
+                             {
+                                 if(CompareList(M,K,6)!=0)
+                                 {
+                                    return(A);
+                                    break;
+                                 }
+                             }
+                             if(size(Jj)==3)
+                             {
+                                 if(CompareList(M,K,6)!=0)
+                                 {
+                                    return(T);
+                                    break;
+                                 }
+                             }
+                        }
+                    }
+                }
+          }
+          else
+          {
+              return(Z);
+          }
+      }
+   }
+}
+example
+{
+  "EXAMPLE:"; echo=2;
+   ring R=0,t,Ds;
+ideal I=t3+3t4+3t5+t6,t13+14t14+92t15+377t16+1079t17+2288t18+3718t19+4719t20+4719t21+3718t22+2288t23+1079t24+377t25+92t26+14t27+t28,t17+17t18+136t19+680t20+2380t21+6188t22+12376t23+19448t24+24310t25+24310t26+19448t27+12376t28+6188t29+2380t30+680t31+136t32+17t33+t34;
+  spaceCur(I);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+proc sagbiAlg(ideal I)
+"USAGE":  sagbiAlg(I);  I ideal
+RETURN: An ideal.The sagbi bases of I.
+EXAMPLE: example sagbiAlg;  shows an example
+{
+    def R=basering;
+    def O=changeord(list(list("Ds",nvars(R))));
+    setring O;
+    ideal I=imap(R,I);
+    ideal L;
+    poly h;
+    int z,n;
+
+    if(size(I)==0){return(I);}
+    int b=ConductorBound(I);
+
+  // int b=200;
+  //   b=correctBound(I,b);
+   ideal S=interReduceSagbi(I,b) ;
+  // b=correctBound(S,b);
+   while(size(S)!=n)
+   {
+       n=size(S);
+       L=sagbiSP(S);
+       for (z=1;z<=size(L);z++)
+       {
+             h=sagbiNF(L[z],S,b);
+             if(h!=0)
+             {
+                  S=insertOne(h,S,b);
+             }
+        }
+   }
+   setring R;
+   ideal S=imap(O,S);
+   return(S);
+}
+
+example
+{
+  "EXAMPLE:"; echo=2;
+ring R=0,t,ds;
+ideal I=t8,t10+t13,t12+t15;
+sagbiAlg(I);
+I=t8,t10+t13,t12+2t15;
+sagbiAlg(I);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+proc sagbiMod(ideal I,ideal G)
+"USAGE":  sagbiMod(I,G);  I an ideal module and ideal G being the sagbi bases of the Algebra
+RETURN: An ideal. the sagbi bases for the differential module.
+EXAMPLE: example sagbiMod;  shows an example
+{
+  def R=basering;//up till now the ordering of the base ring is ds
+  def O=changeord(list(list("Ds",nvars(R))));
+  setring O;
+  ideal I=imap(R,I);
+  ideal G=imap(R,G);
+  int n=ncols(G);poly h;
+  if(I==0)
+  { return(I);}
+  ideal S,J,M;
+  I=sortMOD(I);
+  if(deg(lead(I[1]))<=1)
+  { setring R;
+    return(imap(O,I));}
+  int b=ConductorBound(lead(G))+deg(lead(I[1]));
+  list P;int i;
+  P=createP(I);
+  while(size(P)!=0)
+  {
+      J=P[1][1],P[1][2];
+      P=delete(P,1);
+      S=SpolyMOD(J,G);
+      for(i=1;i<=size(S);i++)
+      {
+         h=sagbiNFMOD(S[i],G,I,b);
+         if(h!=0)
+         {
+             h=simplify(h,1);
+             P=enlargeP(h,P,I);
+             I[size(I)+1]=h;
+         }
+      }
+  }
+  I=sortMOD(I);
+  setring R;
+  ideal K=imap(O,I);
+  return(K);
+}
+example
+{
+  "EXAMPLE:"; echo=2;
+  ring r=0,t,Ds;
+  ideal G=t8,t10+t13,t12+t15,t23-t29,t27;
+  ideal I=diff(G,t);
+  sagbiMod(I,G);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+proc semiGroup(ideal I)
+"USAGE": semiGroup(I);  I ideal the sagbi bases of Algebra.
+RETURN: list L; list with three entries associated to the algebra generated by
+   the sagbi basis:
+   generators of the semigroup
+   the conductor
+    the semigroup
+EXAMPLE: example planeCur;  shows an example
+{
+   list M;
+   if(deg(I[1])<=1)
+   {
+      M[1]=intvec(1);
+      M[2]=1;
+      M[3]=intvec(0,1);
+   }
+   else
+   {
+      ideal J=lead(I);
+      int b=ConductorBound(J);
+      int i;
+      list L=J[1];
+      for(i=2;i<=size(J);i++)
+      {
+         L[i]=J[i];
+      }
+      M=WSemigroup(L,b);
+      intvec v=0,M[3];
+      M[3]=cutAfterConductor(v);
+      M[2]=findConductor(M[3]);
+   }
+   return(M);
+}
+
+example
+{
+ "EXAMPLE:"; echo=2;
+ring R=0,t,ds;
+ideal I=t8,t10+t13,t12+t15,t23-t29,t27;
+semiGroup(I);
+I=t8,t10+t13,t12+2t15,t27-3t33,t29;
+semiGroup(I);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+proc semiMod(ideal I,ideal G)
+"USAGE":  semiMod(I,G);  I ideal,G ideal;I and G are the sagbi bases of the differential module resp.Algebra.
+RETURN: list K;
+      K[1]min generators of the semialgebra.
+      K[2]conductor of the algebra.
+      K[3]genrators for the semialgebra.
+      K[4]min generators of the module.
+      K[5]conductor of the module.
+      K[6]semigroup of the module.
+EXAMPLE: example semiMod;  shows an example
+{
+     list L=semiGroup(G);
+     intvec M;
+     list C;intvec S;
+     int j; int k; int b;
+     for(int i=1;i<=size(I);i++)
+     {
+         M[size(M)+1]=ord(I[i]);
+     }
+     M=M[2..size(M)];
+     for(i=1;i<=size(M);i++)
+     {
+         C[size(C)+1]=M[i]+L[3];
+     }
+     int a=M[1]+L[2];
+     for(j=1;j<=size(M);j++)
+     {
+        for(i=0;i<=a;i++)
+        {
+           for(k=1;k<=size(L[3]);k++)
+           {
+               if(i==C[j][k])
+               {
+                  S[size(S)+1]=i;
+               }
+           }
+        }
+      }
+      S=S[2..size(S)];
+      list K;
+      K[1]=L[1];//generators of the semialgebra.
+      K[2]=L[2];//conductor of the algebra.
+      K[3]=L[3];//semi group of the algebra.
+      K[4]=M;// generators of the semimodule.
+      K[5]=findConductor(sortIntvec(S)); //conductor of the module.
+      K[6]=cutAfterConductor(sortIntvec(S));//semigroup of the module.
+      return(K);
+}
+example
+{
+  "EXAMPLE:"; echo=2;
+  ring r=0,t,Ds;
+  ideal G=t4,t7+t10;
+  ideal I=diff(G,t);
+  ideal k=sagbiMod(I,G);
+  semiMod(k,G);
+}
+////////////////////////////////////////////////////////////////////////////////
+static proc sagbiNF(poly f,ideal I,int b)
+{
+//computes the Sagbi normal form
+   list L=1;
+   map psi;
+   f=jet(f,b);
+   if(f==0){return(f);}
+   while((f!=0) && (L[1]!=0))
+   {
+     L= algebra_containment(lead(f),lead(I),1);
+     if (L[1]==1)
+     {
+        def S= L[2];
+        psi= S,maxideal(1),I;
+        f=jet(f-psi(check),b);
+        kill S;
+     }
+   }
+   return (lead(f)+sagbiNF(f-lead(f),I,b));
+}
+
+/*
+ring R=0,t,ds;
+
+ideal I=t5+t7,t4;
+
+sagbiNF(t7+2t9+3t11+t14+t13+6t15+t17,I,20);
+
+*/
+////////////////////////////////////////////////////////////////////////////////
+static proc sagbiSP(ideal I)
+{
+//computes the set of Sagbi-s-polys
+   if(I==0){ return(I); }
+   list L=algDependent(lead(I));
+
+   def S= L[2];
+   map phi= S,maxideal(1),I;
+   return(simplify(phi(ker),2));
+}
+
+/*
+
+ring R=0,t,ds;
+
+ideal I=t4+t5,t7+t11,t9+t20;
+
+sagbiSP(I);
+
+*/
+
+////////////////////////////////////////////////////////////////////////////////
+static proc sortSagbi(ideal I)
+{
+    //sorts, makes input monic and removes zeros
+    I=simplify(I,2+1);
+    int i;
+    int n=1;
+    poly p;
+    while(n)
+    {
+       n=0;
+       for(i=1;i<size(I);i++)
+       {
+           if(deg(lead(I[i]))>deg(lead(I[i+1])))
+           {
+                n=1;
+                p=I[i];
+                I[i]=I[i+1];
+               I[i+1]=p;
+               break;
+            }
+       }
+    }
+   return(I);
+}
+
+/*
+
+ring R=0,t,ds;
+
+ideal I=3t5,7t2+t7,6t3+t8,3t+t7;
+
+sortSagbi(I);
+
+*/
+
+////////////////////////////////////////////////////////////////////////////////
+static proc insertOne(poly p, ideal I, int b)
+{
+   //assume I is sorted, inserts p at the correct place
+     int i,j;
+     poly q;
+     for(i=1;i<=size(I);i++)
+     {
+              if(deg(lead(p))<deg(lead(I[i])))
+              {
+                  break;
+              }
+     }
+     if(i==size(I)+1)
+     {
+        I=I,simplify(p,1);
+     }
+     else
+     {
+         for(j=size(I)+1;j>i;j--)
+         {
+              I[j]=I[j-1];
+         }
+         I[i]=simplify(p,1);
+     }
+     if(i<size(I))
+     {
+           I=interReduceSagbi(I,b);
+     }
+     return(I);
+}
+
+/*
+
+ring R=0,t,ds;
+
+ideal I=t8,t10+t13,t12+t15;
+
+insertOne(t17,I,20);
+
+I=t8,t10+t13,t12+t15,t23-t29;
+
+insertOne(-2t27,I,40);
+
+*/
+
+////////////////////////////////////////////////////////////////////////////////
+static proc interReduceSagbi(ideal I, int b)
+{
+// reduces the elements of the dial against each other
+     I=sortSagbi(I);
+     ideal J;
+     int n=1;
+   int i;
+     poly h;
+     while(n)
+     {
+          n=0;
+          i=1;
+          while(i<size(I))
+          {
+              i++;
+              J=I[1..i-1];
+              h=sagbiNF(I[i],J,b);
+              h=simplify(h,1);
+              if(h!=I[i])
+              {
+                   n=1;
+                   I[i]=h;
+                   I=sortSagbi(I);
+                   break;
+              }
+           }
+      }
+      return(I);
+}
+
+/*
+
+    ring R=0,t,ds;
+
+    ideal I=t8,t8+t10+t13,t8+t12+t15;
+
+    interReduceSagbi(I,20);
+
+*/
+////////////////////////////////////////////////////////////////////////////////
+
+static proc correctBound(ideal I, int b)
+{
+  //computes the conductor c of the semigroup associated to K[I]
+  //if b>=c
+   list L;
+   int i;
+   for(i=1;i<=size(I);i++)
+   {
+       L[i]=I[i];
+   }
+   list M=WSemigroup(L,b);
+   if(b>M[2])
+   {b=M[2]+1;}
+   return(b);
+}
+
+/*
+
+ring R=0,t,ds;
+
+ideal I=t8,t10+t13,t12+t15;
+
+correctBound(I,40);
+
+I=t8,t10+t13,t12+2t15;
+
+correctBound(I,40);
+
+*/
+////////////////////////////////////////////////////////////////////////////////
+static proc sortMinord(ideal I)
+{
+    //input an ideal
+    //output a list L[1]=minimal order,
+    //              L[2]=poly having the minimal order,
+    //              L[3]=the k suchthat I[k] has the minimal order,
+    //              L[4]=ideal I sorted in a way that minimal degree polynomial
+
+    //appears as the last polynomial of the ideal.ie I[size(I)]=I[k].
+    int i;
+    int n=1;
+    list L;
+    poly p;
+    while(n)
+    {
+       n=0;
+       for(i=1;i<size(I);i++)
+       {
+           if(ord(I[i])<ord(I[i+1]))
+           {
+                n=1;
+                p=I[i];
+                I[i]=I[i+1];
+                I[i+1]=p;
+                break;
+            }
+       }
+    }
+    L[1]=ord(I[size(I)]);
+    L[2]=I[size(I)];
+    L[3]=size(I);
+    L[4]=I;
+    return(L);
+}
+/*
+ring r=0,t,Ds;
+ideal I=t3,t6,t8,t4,t5,t9,t11,t3;
+sortMinord(I);
+*/
+
+////////////////////////////////////////////////////////////////////////////////
+static proc inversP(poly p,int b)
+{
+  //computes the inverse of p upto the bound b
+  if(size(p)==1)
+  {
+   return(p);
+  }
+  number c=leadcoef(p);
+  p=p/c;
+  poly q=1;
+  poly s=1;
+  while(deg(lead(q))<b)
+  {
+      q=q*(1-p);
+      s=s+q;
+  }
+  s=1/c*jet(s,b);
+  return(s);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+static proc ConductorBound(ideal I)
+{
+    //input an ideal
+    // output an integer which gives the bound of the semigroup conductor
+    list M,L;
+    int c,i,b;
+    ideal J;
+    poly p;
+    if(size(I)<=1)
+    {return(2);}
+    while(1)
+    {
+        b=b+5;
+        J=I;
+        L=sortMinord(J);
+        M[size(M)+1]=L[1];
+        while((M[size(M)]!=1)&&(size(L[4])>1))
+        {
+             p=L[2]/var(1)^L[1];
+             J=L[4];
+             for(i=1;i<=L[3]-1;i++)
+             {
+               J[i]=J[i]/var(1)^L[1]*inversP(p,b);
+               if(deg(lead(J[i]))==0){J[i]=J[i]-lead(J[i]);}
+             }
+             J=simplify(J,2);
+             L=sortMinord(J);
+             M[size(M)+1]=L[1];
+        }
+        if(M[size(M)]==1){break;}
+    }
+    for(i=1;i<=size(M)-1;i++)
+    {
+       c=c+M[i]*(M[i]-1);
+    }
+    return(c+1);
+}
+/*
+ring r=0,t,Ds;
+ideal I=t3+3t7,t8+5t9;
+ConductorBound(I);
+*/
+////////////////////////////////////////////////////////////////////////////////
+static proc sortMOD(ideal I)
+{
+    //sorts, makes input monic and removes zeros
+    I=simplify(I,2);
+    I=simplify(I,1);
+    int i;
+    int n=1;
+    poly p;
+    while(n)
+    {
+       n=0;
+       for(i=1;i<size(I);i++)
+       {
+           if(deg(lead(I[i]))>deg(lead(I[i+1])))
+           {
+                n=1;
+                p=I[i];
+                I[i]=I[i+1];
+                I[i+1]=p;
+                break;
+            }
+       }
+    }
+   return(I);
+}
+////////////////////////////////////////////////////////////////////////////////
+static proc SpolyMOD(ideal S,ideal P)
+{
+     //Assume that the basering is a ring in one variable.
+    //input two ideals ideal S=<s_1,s_2> generators of the module and ideal P=<p_1,p_2,..,p_n> the sagbi basis of the algebra
+    //output is an ideal generated by Q[p_1,p_2,...p_n]s_1-R[p_1,p_2,...p_n]s_2 for generators of
+    //Q[lead(p_1),lead(p_2),.,lead(p_n)]lead(s_1)-R[lead(p_1),lead(p_2),.,lead(p_n)]lead(s_2)=0 .
+   def br=basering;
+   int n=ncols(P);
+   ideal P1=lead(P);
+   ideal S1=lead(S);
+   execute
+    ("ring T=("+charstr(br)+",x(1),z(1..n)),(y(1..2)),dp;");
+    poly q;
+    execute
+   ("ring R=("+charstr(br)+"),(x(1),y(1..2),z(1..n)),(lp(3),dp(n));");
+   map phi=br,x(1);
+   ideal G=phi(P1);
+   ideal I=phi(S1);
+   ideal K,J;
+   int d,o,s,j;
+   poly q=I[1];
+   if(deg(I[1])>deg(I[2]))
+   {
+       o=1;
+       q=I[2];
+   }
+   I=I/q;
+   for(int i=1;i<=2;i++)
+   {
+     K[i]=I[i]-y(i);
+   }
+   for(i=1;i<=n;i++)
+   {
+     K[2+i]=G[i]-z(i);
+   }
+   option(redSB);
+   K=std(K);
+   for(i=1;i<=size(K);i++)
+   {
+         if((K[i]/x(1)==0)&&((diff(K[i],y(1))!=0)||(diff(K[i],y(2))!=0)))
+         {
+                q=K[i];
+                for(j=1;j<=2;j++)
+                {
+                    q=subst(q,y(j),0);
+                }
+                K[i]=K[i]-q+q*y(o+1);
+                q=K[i];
+                setring T;
+                q=imap(R,q);
+                s=deg(q);
+                setring R;
+                if(s==1){J[size(J)+1]=simplify(q,1);}
+         }
+   }
+   setring br;
+   map phi=R,maxideal(1),S,P;
+   return(phi(J));
+}
+/*
+ring r=0,t,dp;
+ideal I=4t3,7t6+10t9;
+ideal J=t4,t7+t10;
+sortSagbi(SpolyMOD(I,J));
+*/
+////////////////////////////////////////////////////////////////////////////////
+static proc sagbiNFMODO(poly p, ideal G, ideal I,int b)
+{
+    //input a poly ideal G ideal I int b is a bound
+    //output an ideal K such that in each K[i] generators of I appear in linear.
+    def br=basering;
+    p=jet(p,b);
+    if(p==0){return(p);}
+    int n=ncols(G);
+    int m=ncols(I);
+    ideal G1=lead(G);
+    ideal I1=lead(I);
+     poly p1=lead(p);
+    //create new ring with extra variables -
+    execute
+    ("ring T=("+charstr(br)+",x(1),z(1..n)),(x(2),y(1..m)),dp;");
+    execute
+    ("ring R=("+charstr(br)+"),(x(1..2),y(1..m),z(1..n)),(lp(m+2),dp(n));");
+     map phi = br,x(1);
+     ideal P = phi(G1);
+     ideal S = phi(I1);
+     poly check = phi(p1);
+     poly keep=S[1];
+     S=S/keep;
+
+     check=check/keep;
+     ideal M;
+     poly q;
+     for (int i=1;i<=m;i=i+1)
+     {
+         M[i]=S[i]-y(i);
+     }
+     for (i=1;i<=n;i=i+1)
+     {
+        M[m+i]=P[i]-z(i);
+     }
+     M[size(M)+1]=check-x(2);
+     check=check*keep;
+     option(redSB);
+     M=std(M);
+     int j,s;
+     for(i=1;i<=size(M);i++)
+     {
+         if((deg(M[i]/x(2))==0)&&(M[i]/x(1)==0))
+         {
+               q=subst(M[i],x(2),0);
+               for(j=1;j<=m;j++)
+               {
+                  q=subst(q,y(j),0);
+               }
+               M[i]=M[i]-q+q*y(1);
+             q=M[i];
+               setring T;
+               poly q=imap(R,q);
+             s=deg(q);
+               setring R;
+               if(s==1){check=simplify(q,1);break;}
+         }
+     }
+     setring br;
+     map psi=R,maxideal(1),p,I,G;
+     return(psi(check));
+}
+////////////////////////////////////////////////////////////////////////////////
+
+static proc sagbiNFMOD(poly p, ideal G, ideal I, int b)
+{
+    poly f=jet(p,b);
+    if(f==0){return(f);}
+    poly h;
+    while(f!=h)
+    {
+         h=f;
+         f=sagbiNFMODO(f,G,I,b);
+    }
+    if(f==0){return(f);}
+    return(lead(f)+sagbiNFMOD(f-lead(f),G,I,b));
+}
+////////////////////////////////////////////////////////////////////////////////
+static proc createP(ideal I)
+{
+   list P;
+   int i=1;
+   int j;
+   while(i<=size(I)-1)
+   {
+      j=i+1;
+      while(j<=size(I))
+      {
+          P[size(P)+1]=list(I[i],I[j]);
+          j++;
+      }
+      i++;
+   }
+   return(P);
+}
+////////////////////////////////////////////////////////////////////////////////
+static proc enlargeP(poly h,list P,ideal I)
+{
+    int i;
+    for(i=1;i<=size(I);i++)
+    {
+         P[size(P)+1]=list(I[i],h);
+    }
+    return(P);
+}
+/*
+ring r=0,t,Ds;
+ideal I=4t3,7t6+10t9;
+ideal G=t4,t7+t10;
+sagbiMod(I,G,18);
+*/
+
+////////////////////////////////////////////////////////////////////////////////
+static proc sortIntvec(intvec L)
+{
+    //input: intvec L.
+    //output: L sorted, multiple elements canceled.
+    int i;
+    int j;
+    int n=1;
+    intvec M;
+    while(n)
+    {
+        for(i=1;i<=size(L);i++)
+        {
+            for(j=i+1;j<=size(L);j++)
+            {
+                 if(L[i]==L[j])
+                 {
+                    L[j]=0;
+                 }
+             }
+         }
+         n=0;
+     }
+     for(i=1;i<=size(L);i++)
+     {
+         if((L[i]!=0)||(i==1))
+         {
+            M[size(M)+1]=L[i];
+         }
+     }
+     int m=1;int p;
+     while(m)
+     {
+        m=0;
+        for(i=1;i<size(M);i++)
+        {
+           if(M[i]>M[i+1])
+           {
+                m=1;
+                p=M[i];
+                M[i]=M[i+1];
+               M[i+1]=p;
+               break;
+            }
+         }
+      }
+     M=M[2..size(M)];
+     return(M);
+}
+////////////////////////////////////////////////////////////////////////////////
+static proc findConductor(intvec L)
+{
+     //input a intvec L
+     //output is an integer which came before the gap from right to left.
+     int i;int j; list K;
+     int c;
+     for(i=size(L);i>=2;i--)
+     {
+        if(L[i]!=L[i-1]+1)
+        {
+            c=L[i];
+            break;
+        }
+     }
+     if(c==0){c=1;}
+     return(c);
+}
+////////////////////////////////////////////////////////////////////////////////
+static proc cutAfterConductor(intvec L)
+{
+     //input an integer vector
+     //output cut all the integers in the intvec which came after the conductor
+     int i;int j; intvec K;
+     int c=findConductor(L);
+     for(i=1;i<=size(L);i++)
+     {
+         if(L[i]==c)
+         {
+            K[1..i]=L[1..i];
+         }
+     }
+     return(K);
+}
+////////////////////////////////////////////////////////////////////////////////
+static proc CompareList(list L,list M,int n)
+{
+      //input two list L,M with the same size n
+      //out put 0 if not equal 1 if equal.
+      for(int i=1;i<=n;i++)
+      {
+           if(L[i]!=M[i])
+           {
+               i=0;
+               break;
+           }
+      }
+      return(i);
+}
+////////////////////////////////////////////////////////////////////////////////
+static proc Guess(ideal I)
+{
+  // comput the sagbi basis of the module
+  //which we guess .
+   I=sagbiAlg(I);
+   ideal H=diff(I,var(1));
+   H=sagbiMod(H,I);
+   list K=semiMod(H,I);
+   return(K);
+}
+////////////////////////////////////////////////////////////////////////////////
+/*
+===============================   Examples==========================================
+ideal I=t4+4t5+6t6+8t7+13t8+12t9+10t10+12t11+6t12+4t13+4t14+t16,t7+7t8+22t9+51t10+113t11+219t12+366t13+589t14+876t15+1170t16+1514t17+1828t1
+8+2011t19+2165t20+2163t21+1982t22+1806t23+1491t24+1141t25+889t26+588t27+379t28+2
+52t29+120t30+72t31+36t32+9t33+9t34+t36;
+planeCur(I);
+//=============================
+ideal I=t4+4t5+6t6+8t7+13t8+12t9+10t10+12t11+6t12+4t13+4t14+t16,t7+7t8+21t9+42t10+77t11+126t12+168t13+211t14+252t15+252t16+245t17+231t18+17
+5t19+140t20+105t21+56t22+42t23+21t24+7t25+7t26+t28
+planeCur(I);
+//===============================
+ideal I=t4+4t5+6t6+8t7+13t8+12t9+10t10+12t11+6t12+4t13+4t14+t16,t5+5t6+11t7+22t8+46t9+73t10+107t11+161t12+198t13+231t14+272t15+262t16+250t1
+7+236t18+175t19+141t20+105t21+56t22+42t23+21t24+7t25+7t26+t28
+planeCur(I);
+//===============================
+ideal I=t4+4t5+6t6+8t7+13t8+12t9+10t10+12t11+6t12+4t13+4t14+t16,t6+7t7+22t8+47t9+87t10+143t11+202t12+258t13+307t14+332t15+327t16+305t17+266
+t18+205t19+155t20+111t21+62t22+42t23+22t24+7t25+7t26+t28
+planeCur(I);
+//===============================
+ideal I=t2+2t3+t4+2t5+2t6+t8,t+t2+t4;
+planeCur(I);
+//===============================
+ideal I=t2+2t3+t4+2t5+2t6+t8,t3+3t4+3t5+4t6+6t7+3t8+3t9+3t10+t12;
+planeCur(I);
+//===============================
+ideal I=t2+2t3+t4+2t5+2t6+t8,t5+5t6+10t7+15t8+25t9+31t10+30t11+35t12+30t13+20t14+20t15+10t16+5t17+5t18+t
+20;
+planeCur(I);
+//================================================================
+ideal I=t2+2t3+t4+2t5+2t6+t8,t11+11t12+55t13+176t14+440t15+957t16+1837t17+3135t18+4917t19+7150t20+9581t2
+1+12046t22+14300t23+15851t24+16665t25+16687t26+15642t27+14025t28+12012t29+9570t3
+0+7392t31+5412t32+3630t33+2442t34+1485t35+825t36+495t37+220t38+110t39+55t40+11t4
+1+11t42+t44
+planeCur(I);
+//===============================
+ideal I=t2+2t3+t4+2t5+2t6+t8,t45+45t46+990t47+14235t48+150975t49+1264329t50+8742030t51+51530985t52+26531
+7525t53+1216052255t54+5037384726t55+19091253735t56+66860434260t57+218159032410t5
+8+667743178590t59+1928258130018t60+5278946615910t61+13758022145340t62+3425642198
+1760t63+81743054778990t64+187438301870193t65+413998043743845t66+882643063827960t
+67+1819834573178925t68+3634672399863945t69+7042671464388093t70+13256726980146210
+t71+24271349963247255t72+43270648586469315t73+75192560924341905t74+1274795590273
+39134t75+211037186585880765t76+341404127193205395t77+540109313678250885t78+83615
+2328502076770t79+1267494306126371433t80+1882391473790147350t81+27403488768330021
+60t82+3912426884928977910t83+5480608823069934180t84+7535946071701345419t85+10175
+247273088233765t86+13496177050168252770t87+17590776929351920305t88+2253760903474
+9950330t89+28392934993342165732t90+35181553858703840610t91+42888103580926417860t
+92+51449748796644626670t93+60751205041524651720t94+70622965899108523296t95+80843
+398349265488310t96+91145062374529367655t97+101225220090613564275t98+110760068529
+877638960t99+119421810187582522995t100+126897320456330125725t101+132906930278955
+392505t102+137221752614812709130t103+139678059865381605315t104+14018746206071963
+5683t105+138742016728357115865t106+135413875517988518550t107+1303495836626693311
+25t108+123759636437037165840t109+115904304930914703126t110+107077029168089360280
+t111+97586814544772570280t112+87741050370279892245t113+77830012377996062865t114+
+68114044171037561004t115+58814074232856531765t116+50105762317964865600t117+42117
+223130580686220t118+34929979773602146200t119+28582581501297657240t120+2307618932
+9698326690t121+18381388272325750530t122+14445518786710710480t123+111999120315284
+53530t124+8566543884036576384t125+6463772035817658320t126+4810966835075093880t12
+7+3531977599087147320t128+2557482632962404180t129+1826346112628778972t130+128615
+1054039308160t131+893096793855988260t132+611445912380539110t133+4126879484894709
+90t134+274559737461674588t135+180030436220988810t136+116328756134241090t137+7406
+1684381355110t138+46450833440621940t139+28695217633493598t140+17456561066064945t
+141+10455665532950385t142+6164429567615550t143+3576677924170795t144+204174682346
+8917t145+1146414046643415t146+632953124099190t147+343522434444255t148+1832093883
+47205t149+95981896978935t150+49375510221510t151+24930700142535t152+1234956944936
+0t153+5998779092790t154+2855797655022t155+1331635383390t156+607860009900t157+271
+401068250t158+118455934740t159+50498441136t160+20999419155t161+8518084355t162+33
+61582620t163+1290701115t164+481780299t165+173664315t166+61087950t167+20511645t16
+8+6704775t169+2115729t170+610170t171+191565t172+42570t173+15180t174+1980t175+990
+t176+45t177+45t178+t180
+planeCur(I);
+//===============================
+ideal I=t3+3t4+3t5+4t6+6t7+3t8+3t9+3t10+t12,t2+2t3+t4+2t5+2t6+t8
+planeCur(I);
+//===============================
+ ideal I=t3+3t4+3t5+4t6+6t7+3t8+3t9+3t10+t12,t5+5t6+10t7+15t8+25t9+31t10+30t11+35t12+30t13+20t14+20t15+10t16+5t17+5t18+t20
+ planeCur(I);
+//===============================
+ideal I=t3+3t4+3t5+4t6+6t7+3t8+3t9+3t10+t12,t4+4t5+6t6+8t7+13t8+12t9+10t10+12t11+6t12+4t13+4t14+t16
+ planeCur(I);
+//==========================================================================
+ ring r=0,t,Ds;
+ ideal I=t3,t10+t14;
+ planeCur(I);
+//===============================
+ideal I=t3+3t4+3t5+t6,t10+10t11+45t12+120t13+211t14+266t15+301t16+484t17+1046t18+2012t19+3004t20+
+3432t21+3003t22+2002t23+1001t24+364t25+91t26+14t27+t28
+planeCur(I);
+//=======================================
+ideal I=t3+3t4+3t5+t6,t10+10t11+45t12+120t13+210t14+252t15+210t16+120t17+45t18+10t19+t20
+ planeCur(I);
+//===============================
+ring r=0,t,Ds;
+ideal I=t3+3t4+3t5+t6,t13+14t14+92t15+377t16+1079t17+2288t18+3718t19+4719t20+4719t21+3718t22+2288
+t23+1079t24+377t25+92t26+14t27+t28,t20+20t21+190t22+1140t23+4845t24+15504t25+38760t26+77520t27+125970t28+16796
+0t29+184756t30+167960t31+125970t32+77520t33+38760t34+15504t35+4845t36+1140t37+19
+0t38+20t39+t40
+spaceCur(I);
+//=====================================================
+ideal I=t3+3t4+3t5+t6,t13+14t14+92t15+377t16+1079t17+2288t18+3718t19+4719t20+4719t21+3718t22+2288
+t23+1079t24+377t25+92t26+14t27+t28,t17+17t18+136t19+680t20+2380t21+6188t22+12376t23+19448t24+24310t25+24310t26
++19448t27+12376t28+6188t29+2380t30+680t31+136t32+17t33+t34
+spaceCur(I);
+//========================================================
+ideal I=t3,t16,t14;
+spaceCur(I);
+//=============================================
+ideal I=t3,t19,t14;
+spaceCur(I);
+//==============================================
+ideal I=t3,t14+t16,t19;
+spaceCur(I);
+//===============================================
+ideal I=t3,t14+t16,t25;
+spaceCur(I);
+//=======================================
+ideal I=t3+3t4+3t5+t6,t14+14t15+91t16+364t17+1001t18+2002t19+3003t20+3432t21+3004t22+2024t23+1232
+t24+1904t25+7406t26+26348t27+74614t28+170544t29+319770t30+497420t31+646646t32+70
+5432t33+646646t34+497420t35+319770t36+170544t37+74613t38+26334t39+7315t40+1540t4
+1+231t42+22t43+t44,t25+25t26+300t27+2300t28+12650t29+53130t30+177100t31+480700t32+1081575t33+2
+042975t34+3268760t35+4457400t36+5200300t37+5200300t38+4457400t39+3268760t40+2042
+975t41+1081575t42+480700t43+177100t44+53130t45+12650t46+2300t47+300t48+25t49+t50
+spaceCur(I);
+//=========================================================
+ideal I=t3+3t4+3t5+t6,t14+14t15+91t16+364t17+1001t18+2003t19+3022t20+3603t21+3972t22+5878t23+1262
+9t24+27496t25+50479t26+75596t27+92379t28+92378t29+75582t30+50388t31+27132t32+116
+28t33+3876t34+969t35+171t36+19t37+t38,t25+25t26+300t27+2300t28+12650t29+53130t30+177100t31+480700t32+1081575t33+2
+042975t34+3268760t35+4457400t36+5200300t37+5200300t38+4457400t39+3268760t40+2042
+975t41+1081575t42+480700t43+177100t44+53130t45+12650t46+2300t47+300t48+25t49+t50
+spaceCur(I);
+//==============================================================
+ideal I=t3+3t4+3t5+t6,t14+14t15+92t16+380t17+1121t18+2562t19+4823t20+7800t21+11011t22+13442t23+13
+871t24+11804t25+8099t26+4382t27+1821t28+560t29+120t30+16t31+t32,t19+19t20+171t21+969t22+3876t23+11628t24+27132t25+50388t26+75582t27+92378t2
+8+92378t29+75582t30+50388t31+27132t32+11628t33+3876t34+969t35+171t36+19t37+t38
+spaceCur(I);
+//======================================================================
+ideal I=t3+3t4+3t5+t6,t14+14t15+92t16+380t17+1121t18+2562t19+4823t20+7800t21+11011t22+13442t23+13
+871t24+11804t25+8099t26+4382t27+1821t28+560t29+120t30+16t31+t32,t25+25t26+300t27+2300t28+12650t29+53130t30+177100t31+480700t32+1081575t33+2
+042975t34+3268760t35+4457400t36+5200300t37+5200300t38+4457400t39+3268760t40+2042
+975t41+1081575t42+480700t43+177100t44+53130t45+12650t46+2300t47+300t48+25t49+t50
+spaceCur(I);
+//================================================================
+ideal I=t3+3t4+3t5+t6,t16+16t17+120t18+560t19+1820t20+4368t21+8008t22+11440t23+12870t24+11440t25+
+8008t26+4368t27+1820t28+560t29+120t30+16t31+t32
+,t14+14t15+91t16+364t17+1001t18+2002t19+3003t20+3432t21+3003t22+2002t23+1001
+t24+364t25+91t26+14t27+t28
+spaceCur(I);
+//===========================================================================================
+*/
diff --git a/Singular/LIB/classifyceq.lib b/Singular/LIB/classifyceq.lib
new file mode 100644
index 0000000..a0c6c13
--- /dev/null
+++ b/Singular/LIB/classifyceq.lib
@@ -0,0 +1,2092 @@
+/////////////////////////////////////////////////////////////////////////////////
+version="version classifyceq.lib 4.0.0.0 Jun_2013 "; // $Id: f5489b4e3f68ada1e8639d108b4560159de83dc6 $
+category="Singularities";
+
+info="
+LIBRARY:  classifyCeq.lib       simple hypersurface singularities in characteristic p > 0
+AUTHORS:  Deeba Afzal           deebafzal at gmail.com
+          Faira Kanwal Janjua   fairakanwaljanjua at gmail.com
+
+OVERVIEW:
+   A library for classifying the simple singularities with respect to contact equivalence in charateristic p > 0 .
+   Simple hypersurface singularities in charateristic p > 0 were classified by Greuel and
+   Kroening [1] with respect to contact equivalence. The classifier we use has been proposed in [2].
+
+REFERENCES:
+[1] Greuel, G.-M.; Kroening, H.: Simple singularities in positive characteristic.
+    Math.Z. 203, 339-354 (1990).
+[2] Afzal,D.;Binyamin,M.A.;Janjua,F.K.: On the classification of simple singularities in positive characteristic.
+
+PROCEDURES:
+  classifyCeq(f);     simple hypersurface singularities in charateristic p > 0
+";
+LIB "sing.lib";
+LIB "classify.lib";
+LIB "primdec.lib";
+LIB "ring.lib";
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+proc classifyCeq(poly f)
+"USAGE:  classifyCeq(f);  f poly
+RETURN: string including the Tjurina number of f and its type in the classification of Greuel and Kroening
+EXAMPLE: example classifyCeq;  shows an example
+"
+{
+   def R=basering;
+   def S=changeord(list(list("ds",1:nvars(basering))));
+   setring S;
+   poly f=imap(R,f);
+   string re;
+   if(char(basering)==0)
+   {
+     re=(string(classify(f)));
+   }
+   if(char(basering)!=2)
+   {
+     re=classifyCeq1(f);
+   }
+   if(char(basering)==2)
+   {
+     re=classifyCeq2(f);
+   }
+   setring R;
+   return(re);
+}
+example
+{
+  "EXAMPLE:"; echo=2;
+   ring R=3,(x,y,z,u,v,w),ds;
+   classifyCeq(-x2+xy+y2+xz-yz-z2+w2+u3+v4);
+}
+///////////////////////////////////////////////////////////  char p > 2 //////////////////////////////////////////
+static proc blowupone(poly f)
+{
+   //=== input f smooth or isolated simple singularity at zero
+   //=== output var(1) or poly with isolated singularity at zero
+   def R=basering;
+   def S=changeord(list(list("ds",1:nvars(basering))));
+   setring S;
+   int n=nvars(basering);
+   int i;
+   poly f=imap(R,f);
+   if(deg(lead(f))<=1){setring R;return(var(1));}
+   def T=changeord(list(list("lp",1:nvars(basering))));
+   setring T;
+   map phi;
+   ideal mphi, sing;
+   poly p,q;
+   //===========  blow up =======================================================
+   for(i=1;i<=n;i++)
+   {
+      mphi=var(i)*maxideal(1);
+      mphi[i]=var(i);
+      phi=S,mphi;
+       p=phi(f);
+      q=p/var(i);
+      while(size(p)==size(q))
+      {
+         p=q;
+         q=q/var(i);
+      }
+      //===============  p is the strict transform var(i) exceptional divisor ====
+       //=============== analysis of singularities ================================
+      sing=jacob(p),p,var(i);
+      sing=radical(sing);
+      option(redSB);
+      sing=std(sing);
+      sing=simplify(sing,1);
+       if(size(sing)>1)
+      {
+         if(size(sing)!=n){ERROR("not simple");}
+         ideal mpsi=std(maxideal(1));
+         for(i=1;i<=n;i++){mpsi[i]=var(i)-sing[n-i+1][2];}
+         map psi=T,mpsi;
+         p=psi(p);
+         setring R;
+         poly p=imap(T,p);
+         return(p);
+      }
+    }
+   setring R;
+   return(var(1));
+}
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ static proc classifyCeq1(poly f)
+//====Classify Simple hypersurface singularities when charateristic p!=2
+{
+      // char!=2
+      //====input poly f
+      //====output  The function defines ......not an isolated singularity or  not a simple singularity  and tjurina
+      //          of the singularity or a simple singularity ,tjurina of the singularity and type of the singularity.
+      def R=basering;
+      int d;
+      int m=tjurina(f);
+
+           if(m==-1)
+           {
+                 return("The given function defines not an isolated singularity" );
+
+           }
+           poly g;
+           int c;
+           c=corank(f);
+           if(c<=1)
+           {
+
+               if(c==0)
+               {
+                  return("The given function defines a simple singularity.
+The tjurina number is "+string(m)+".
+A[1]:"+string(var(1))+"^2+"+string(var(2))+"^2");
+               }
+
+               if(c==1)
+
+              {
+                  poly w=blowupone(f);
+                  int n=tjurina(w);
+
+                 int b=m-n;
+                 if(b<=2)
+                 {
+                   return( "The given function defines a simple singularity.
+The tjurina number is "+string(m)+".
+A["+string(m)+"]:"+string(var(1))+"^2+"+string(var(2))+"^"+string(m+1)+"");
+                 }
+                 else
+                 {
+
+                    return("The given function defines a simple singularity.
+The tjurina number is "+string(m)+".
+A["+string(m-1)+"]:"+string(var(1))+"^2+"+string(var(2))+"^"+string(m)+"");
+                 }
+
+   }
+}
+           if(c==2)
+           {
+                 g=jet(f,3);
+                 if(g==0)
+                 {
+                    return( "The given function defines not a simple singularity.
+The tjurina number is "+string(m)+".");
+                 }
+                 if(g!=0)
+                 {
+
+                       def S=GDsplitting(f);
+                       setring S;
+
+
+                      poly g=jet(f,3);
+                         if(g==0)
+                         {
+                             setring(R);
+                            return("The given function defines not a simple singularity.
+The tjurina number is "+string(m)+".");
+                          }
+                      list L=factorize(g);
+                      if(size(L[1])==2)
+                      {
+                              ideal M=var(1),var(2)^2;
+                              ideal N=std(M^3);
+                               poly h=reduce(f,N);
+                                if(h==0)
+                                {
+                                   return(" The given function defines not a simple singularity
+The tjurina number is "+string(m)+".");
+                                }
+                                if(h!=0)
+                                {
+                                       if((char(R)!=3)&&(char(R)!=5))
+                                        {
+                                             setring R;
+                                             if(m==6)
+                                             {
+                                                 return("The given function defines a simple singularity.
+The tjurina number is "+string(m)+".
+E^0[6]:"+string(var(1))+"^3+"+string(var(2))+"^4");
+                                             }
+                                             if(m==7)
+                                             {
+                                                 return("The given function defines a simple singularity.
+The tjurina number is "+string(m)+".
+E^0[7]:"+string(var(1))+"^3+"+string(var(1))+"*"+string(var(2))+"^3");
+                                             }
+                                             if(m==8)
+                                             {
+                                                 return("The given function defines a simple singularity.
+The tjurina number is "+string(m)+".
+E^0[8]:"+string(var(1))+"^3+"+string(var(2))+"^5");
+                                             }
+                                        }
+                                        if(char(R)==5)
+                                        {
+                                            setring R;
+                                            if(m==6)
+                                            {
+                                               return("The given function defines a simple singularity.
+The tjurina number is "+string(m)+".
+E^0[6]:"+string(var(1))+"^3+"+string(var(2))+"^4");
+                                            }
+                                            if(m==7)
+                                            {
+                                               return("The given function defines a simple singularity.
+The tjurina number is "+string(m)+".
+E^0[7]:"+string(var(1))+"^3+"+string(var(1))+"*"+string(var(2))+"^3");
+                                            }
+                                            if(m==10)
+                                            {
+                                                 return("The given function defines a simple singularity.
+The tjurina number is "+string(m)+".
+E^0[8]:"+string(var(1))+"^3+"+string(var(2))+"^5");
+                                             }
+                                             if(m==8)
+                                             {
+                                                return("The given function defines a simple singularity.
+The tjurina number is "+string(m)+".
+E^1[8]:"+string(var(1))+"^3+"+string(var(2))+"^5+"+string(var(1))+"*"+string(var(2))+"^4");
+                                             }
+                                        }
+                                        if(char(R)==3)
+                                        {
+                                             poly p=blowupone(f);
+                                             int e=(std(jacob(p)+ideal(p))==1);
+                                             setring R;
+                                             if((m==7)&&e)
+                                             {
+                                                 return("The given function defines a simple singularity.
+The tjurina number is "+string(m)+".
+E^1[6]:"+string(var(1))+"^3+"+string(var(2))+"^4+"+string(var(1))+"^2*"+string(var(2))+"^2");
+                                             }
+                                             if((m==7)&&!e)
+                                             {
+                                                 return("The given function defines a simple singularity.
+The tjurina number is "+string(m)+".
+E^1[7]:"+string(var(1))+"^3+"+string(var(1))+"*"+string(var(2))+"^3+"+string(var(1))+"^2*"+string(var(2))+"^2");
+                                             }
+                                             if(m==8)
+                                             {
+
+                                                return("The given function defines a simple singularity.
+The tjurina number is "+string(m)+".
+E^2[8]:"+string(var(1))+"^3+"+string(var(2))+"^5+"+string(var(1))+"^2*"+string(var(2))+"^2");
+                                             }
+                                             if(m==10)
+                                             {
+                                                 return("The given function defines a simple singularity.
+The tjurina number is "+string(m)+".
+E^1[8]:"+string(var(1))+"^3+"+string(var(2))+"^5+"+string(var(1))+"^2*"+string(var(2))+"^3");
+                                             }
+                                            if((m==9)&&e)
+                                            {
+
+                                                return("The given function defines a simple singularity.
+The tjurina number is "+string(m)+".
+E^0[6]:"+string(var(1))+"^3+"+string(var(2))+"^4");
+                                            }
+                                            if((m==9)&&!e)
+                                            {
+
+                                                 return("The given function defines a simple singularity.
+The tjurina number is "+string(m)+".
+E^0[7]:"+string(var(1))+"^3+"+string(var(1))+"*"+string(var(2))+"^3");
+                                            }
+                                           if(m==12)
+                                           {
+
+                                                return("The given function defines a simple singularity.
+The tjurina number is "+string(m)+".
+E^0[8]:"+string(var(1))+"^3+"+string(var(2))+"^5");
+                                           }
+
+                                       }
+                                       else
+                                       {
+                                             return( "The given function defines not a simple singularity");
+                                       }
+
+                                   }
+
+                   }
+
+                   if(size(L[1])==3)
+                   {
+                           setring R;
+                           return("The given function defines a simple singularity.
+The tjurina number is "+string(m)+".
+D["+string(m)+"]:"+string(var(1))+"^2*"+string(var(2))+"+"+string(var(2))+"^"+string(m-1)+"");
+                   }
+                    if(size(L[1])==4)
+                   {
+                                         setring R;
+                                        return("The given function defines a simple singularity.
+The tjurina number is "+string(m)+".
+D[4]:"+string(var(1))+"^2*"+string(var(2))+"+"+string(var(1))+"^3");
+                   }
+          }
+     }
+  if(c>=3)
+  {
+     return( "The given function defines not a simple singularity.
+The tjurina number is "+string(m)+".");
+  }
+
+}                    // ends classifyCeq1
+ example
+{
+"EXAMPLE:"; echo=2;
+  ring R=5,(x,y),ds;
+  classifyCeq1(x2y+y22);
+}
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+static proc GDsplitting(poly f)
+{      // the result of the splitting lemma (myMorsesplitting) in a special ring of 2 variables
+       // input a poly f of order >=2
+       // output  ring S=char(basering),(x,y),ds;  and a poly f in <x,y>^3 in S with the following properties:
+       // f + a sum of squares of further variables is contact equivalentt to the input polynomial
+       def R=basering;
+       intvec t;
+       int b,i;
+       b=tjurina(f);
+       f=myMorsesplitting(f,b);
+       t=forv(findVar(f));
+       ring S=char(basering),(x,y),ds;
+       ideal M;
+       M[t[1]]=var(1);
+       M[t[2]]=var(2);
+       i=1;
+       if((i!=t[1])&&(i!=t[2]))
+       {
+         M[i]=0;
+       }
+       map phi=R,M;
+       poly f=phi(f);
+       export(f);
+       setring(R);
+       return(S);
+}
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+static proc myMorsesplitting(poly f,int b)
+{
+   // splitting lemma
+   // input  poly f=f(x(1),...,x(n))      jet(f,2)!=0
+   // output a polynomial in 2 variables of order >=3 such that a sum of squares of the remaining variables plus this
+   // polynomial is contact equivalent to the input polynomial
+   intvec w;
+   f=simplify(jet(f,b),1);
+   while(jet(f,2)!=0)
+   {
+      w=findlead(f);
+      if(w[1]==w[2])
+      {
+             f=splitting_one(f,w[1],b);
+      }
+      else
+      {
+             f=splitting_two(f,w[1],w[2],b);
+      }
+    }
+    return(f);
+}
+example
+{
+ "EXAMPLE:"; echo=2;
+  ring R=3,(x,y,z,u,v),ds;
+  poly f=x2+x3z+u2+v2+z3+y11;
+  myMorsesplitting(f,30);
+}
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+static proc findlead(poly f)
+
+{
+  //  input poly f=x(i)^2+h      or   poly f=x(i)*x(j)+h  , h of order >=2
+  //  output intvec w   w[1]=i,w[2]=i   or  w[1]=i ,w[2]=j
+  intvec v=leadexp(f);
+  int i,k,n;
+  intvec w;
+  n=nvars(basering);
+  for(i=1;i<=n;i++)
+  {
+      if(v[i]==2)
+      {
+          w[1]=i;
+          w[2]=i;
+          break;
+      }
+     if(v[i]==1)
+      {
+          k++;
+          w[k]=i;
+      }
+  }
+  return(w);
+}
+example
+{
+ "EXAMPLE:"; echo=2;
+  ring R=3,(x,y,z,u,v),ds;
+  poly f=x2+x3z+u2+v2+z3+y11;
+  findlead(f);
+}
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+static proc splitting_one(poly p, int i, int b)
+{
+// assumes that p=x_i^2+h, no x_i^2 in h, h of order >=2
+// returns q(x_1,??x_i-1,x_i+1,...,x_n) such that x_i^2 +q is right equivalent to p mod
+// <x_1,??,x_n>^b
+
+   if(b<2){b=2;}
+   def R=basering;
+   ideal M=maxideal(1);
+   map phi;
+   poly q=jet((p-var(i)^2)/var(i),b);
+   while(q!=0)
+   {
+      p=quickSubst(p,var(i)-1/2*q,i,b);
+      q=jet((p-var(i)^2)/var(i),b);
+   }
+   return(simplify(jet(p,b)-var(i)^2,1));                           //make the leading coefficient 1
+}
+example
+{
+ "EXAMPLE:"; echo=2;
+ ring R=3,(x,y,z,u,v),ds;
+ poly f=x2+y3+z4+xy3+u2+v2;
+ splitting_one(f,1,18);
+}
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+static proc splitting_two(poly p, int i, int j, int b)
+{
+// assumes that p=x_i*x_j+h, no x_i^2 in h, h of order >=2
+// returns q(x_1,???,x_i-1,x_i+1,...,x_j-1,x_j+1,...,x_n) such that x_i*x_j +q is right equivalent to p mod
+// <x_1,??,x_n>^b
+
+   if(b<2){b=2;}
+   def R=basering;
+   ideal M=maxideal(1);
+   map phi;
+   poly q=jet((p-var(i)*var(j))/var(i),b);
+   while(q!=0)
+   {
+      p=quickSubst(p,var(j)-q,j,b);
+      q=jet((p-var(i)*var(j))/var(i),b);
+   }
+   return(simplify(substitute(jet(p,b),var(j),0),1));              //make the leading coefficient 1
+}
+example
+{
+ "EXAMPLE:"; echo=2;
+ring R=5,(u,v,w,s,t),ds;
+poly f=uv+t2+u4s+u11+v7+s9+w8;
+ splitting_two(f,1,2,128);
+}
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+static proc quickSubst(poly h, poly r, int i, int b)
+{
+   //=== assume h, r is in Q[x_1,...,x_n], computes jet(h(x_i=r),b)
+   h=jet(h,b);
+   r=jet(r,b);
+   matrix M=coef(h,var(i));
+   poly q = 1;
+   int j,k,d;
+   intvec v;
+   d=deg(M[1,1]);
+   v[d+1]=1;
+   for(k = 2; k <= ncols(M); k++)
+   {
+        v[deg(M[1,k])+1]=1;
+   }
+   h=0;
+   for(k=1;k<=d+1;k++)
+   {
+      if(v[k]==1)
+      {
+         h=h+jet(q*M[2,ncols(M)-j],b);
+         j++;
+      }
+      q=jet(q*r,b);
+   }
+   return(h);
+}
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+static proc findVar(poly p)
+{
+   //  input poly f
+   //  output intvec v   v[i]=0 if f is not depending on var(i) and v[j]=1 if f is depending on var(j)
+    intvec v;
+    int i,n;
+     n=nvars(basering);
+    for(i=1;i<=n;i++)
+    {
+           if(subst(p,var(i),0)==p)
+           {
+               v[i]=0;
+           }
+           else
+           {
+                v[i]=1;
+           }
+    }
+    return(v);
+}
+example
+{
+ "EXAMPLE:"; echo=2;
+  ring R=3,(x,y,z,u,v),ds;
+  poly f=y3+u5;
+  findlead(f);
+}
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+static proc forv(intvec v)
+{
+       //returns the places of v which are different from zero
+       intvec w;
+       int i,j;
+       j=1;
+       for(i=1;i<=nvars(basering);i++)
+       {
+            if(v[i]!=0)
+            {
+               w[j]=i;
+                j++;
+            }
+        }
+        return(w);
+}
+
+/////////////////////////////////////////// char p=2 ////////////////////////////////////////////////////////////////////////////
+static proc classifyCeq2(poly p)
+//====Classification of hypersurface singularities in Characteristic p=2.
+{
+       //    input    poly p
+       //    output   The normal form to which f is contact equvalent or the function is not simple.
+       def R=basering;
+       int t=tjurina(p);
+       list T;
+       if(t==-1)
+       {
+          return("The given function defines not an isolated singularity");
+       }
+        int b=t+1;
+       p=SPILPRO(p,b);
+       list L=findVAR(p);
+       if(L[2]>=4)
+       {
+
+           return("The given function defines not a simple singularity.
+The Tjurina Number is "+string(t)+". ");
+       }
+       if(L[2]==1)
+       {
+          def S=redvar2(p);
+           setring S;
+
+          string a="The given function defines an isolated Singularity.
+The Tjurina number is "+string(t)+".
+A_"+string(leadexp(p)[1]-1)+":xy+z"+string(leadexp(p)[1])+".";
+          setring R;
+          return(a);
+       }
+
+       if(jet(p,2)==0)
+       {
+           if(L[2]==3)
+           {
+              return("The given function defines not a simple singularity.
+The Tjurina Number is "+string(t)+". ");
+
+           }
+           def S=redvar2(p);
+           setring S;
+           string a=curCeq2(p);
+           setring R;
+           return(a);
+       }
+       else
+       {
+         if(L[2]==3)
+         {
+             int B=t div 2+1;
+             p=splitting_SQUA(p,B);
+             def S=redvar2(p);
+             setring S;
+             string a=surCeq2(p);
+             setring R;
+             return(a);
+         }
+           p=splitting_SQUA(p,b);
+           def S=redvar2(p);
+           setring S;
+           string a=curCeq2(p);
+           setring R;
+           return(a);
+      }
+}
+example
+{
+   "EXAMPLE:"; echo=2;
+    ring r=2,(x,y,z,w,t,v),ds;
+    poly f=xy+zw+t5+v3;
+    classifyCeq2(f);
+}
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+static proc SPILPRO(poly p,int B)
+{
+    //Splitting lemma in characteristic 2
+    //input a polynomial f and a bound B
+    //output a polynomial q, the result of the splitting lemma applied to f up to the order B
+  int i,j;
+  def R=basering;
+  int n=nvars(R);
+  poly q=splittingLchar2(p);
+  list T=FindPRO(q);
+
+  while(size(T)!=0)
+  {
+     i=T[1]; j=T[2];
+     q=splitting_two2(q,i,j,B);
+
+     T=FindPRO(q);
+  }
+  return(q);
+}
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+static proc surCeq2(poly f)
+//====Classification of Surface Singularaties in case when p=2
+{
+        //===input a funation defined in the ring whose Characteristic is 2.
+        //===output is a Normal Form to which Given function is contact equivalent or function is not simple.
+        def R=basering;
+        int n=nvars(R);
+        list L;
+        int k=tjurina(f);
+        if(k==-1)
+        {
+           return("The given function defines not an isolated singularity.");
+        }
+        return(surEsing(f));
+}
+example
+{
+  "EXAMPLE:"; echo=2;
+   ring R=2,(x,y,z),Ds;
+   surCeq(xy+y2+yz+x2y+xy2+xyz+z21+xz21);
+
+}
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+static proc surEsing(poly f)
+//====Classifcation of Ek singularities.
+{
+     //===input: A function which is an isolated singularity.
+     //===output: Normal form to which given function is contact equivalent.
+     list M;
+     def R=basering;
+     f=formf(f);
+     poly p=jet(f,2);
+     int k=tjurina(f);
+
+     list L=factorize(p);
+     poly g=subst(f,leadmonom(L[1][2]),0);
+     poly j=jet(g,3)-jet(g,2);
+     poly C=f-g;
+     C=C/leadmonom(L[1][2]);
+     poly h=subst(C,leadmonom(L[1][2]),0);
+     h=jet(h,2);
+     poly h1=j+h*leadmonom(L[1][2]);
+
+     if(h!=0)
+     {
+            list P=factorize(h1);
+            list N=factorize(j);
+
+            if((size(P[1])==2)&&(size(P[2])==2)&&(P[2][2]==1)&&(N[2][2]==3))
+            {
+                if(k==6)
+                {
+
+                   return(" The given function defines an isolated Singularity.
+The Tjurina number is "+string(tjurina(f))+".
+E^1[6]:z2+x3+y2z+xyz.");
+
+                }
+                if(k==8)
+                 {
+                    return("The given function defines an isolated Singularity.
+The Tjurina number is "+string(tjurina(f))+".
+E^0[6]:z2+x3+y2z.");
+
+                }
+            }
+            if(((size(P[1])==4)&&(size(P[2])==4))||((size(N[1])==4)&&(size(N[2])==4)))
+            {
+                if(k==8)
+                {
+                   return("The given function defines an isolated Singularity.
+The Tjurina number is "+string(tjurina(f))+".
+D[4]:z2+x2y+xy2.");
+                }
+                if(k==6)
+                {
+                   return("The given function defines an isolated Singularity.
+The Tjurina number is "+string(tjurina(f))+".
+D^1[4]:z2+x2y+xy2+xyz.");
+
+                 }
+            }
+            if((size(P[1])<=3)&&(size(P[2])<=3))
+            {
+
+                    if(k==6)
+                    {
+                        return("The given function defines an isolated Singularity.
+The Tjurina number is "+string(tjurina(f))+".
+D^1[5]:z2+x2y+y2z+xyz.");
+                    }
+                    if(k==8)
+                    {
+
+                           if(size(lengthBL(f))==4)
+                           {
+                                 return("The given function defines an isolated Singularity.
+The Tjurina number is "+string(tjurina(f))+".
+E^3[7]:z2+x3+xy3+xyz.");
+
+                           }
+                            else
+                           {
+                                if(size(lengthBL(f))==5)
+                                {
+
+                                    return("The given function defines an isolated Singularity.
+The Tjurina number is "+string(tjurina(f))+".
+E^4[8]:z2+x3+y5+xyz.");
+                                }
+                                else
+                                {
+                                    return("The given function defines an isolated Singularity.
+The Tjurina number is "+string(tjurina(f))+".
+D^0[5]:z2+x2y+y2z.");
+
+                                 }
+                            }
+
+                       }
+
+               }
+               list Q=factorize(j);
+               if((size(Q[1])==3)&&(size(Q[2])==3))
+               {
+
+                      return(surDsing(f));
+               }
+               else
+               {
+                        if(k==10)
+                        {
+                             if(size(lengthBL(f))==4)
+                             {
+                                return("The given function defines an isolated Singularity.
+The Tjurina number is "+string(tjurina(f))+".
+E^2[7]:z2+x3+xy3+y3z.");
+
+                             }
+                             if(size(lengthBL(f))==5)
+                             {
+                                return("The given function defines an isolated Singularity.
+The Tjurina number is "+string(tjurina(f))+".
+E^3[8]:z2+x3+y5+y3z.");
+
+                             }
+                        }
+                        if(k==12)
+                        {
+
+                             if(size(lengthBL(f))==4)
+                             {
+                                   return("The given function defines an isolated Singularity.
+The Tjurina number is "+string(tjurina(f))+".
+E^1[7]:z2+x3+xy3+xy3z.");
+
+                              }
+                              if(size(lengthBL(f))==5)
+                              {
+                                   return("The given function defines an isolated Singularity.
+The Tjurina number is "+string(tjurina(f))+".
+E^2[8]:z2+x3+y5+xy2z.");
+
+                              }
+                         }
+                         if(k==14)
+                         {
+
+                              if(size(lengthBL(f))==4)
+                              {
+                                     retrun("The given function defines an isolated Singularity.
+The Tjurina number is "+string(tjurina(f))+".
+E^0[7]:z2+x3+xy3.");
+
+                              }
+                              if(size(lengthBL(f))==5)
+                              {
+                                    return("The given function defines an isolated Singularity.
+The Tjurina number is "+string(tjurina(f))+".
+E^1[8]:z2+x3+y5+xy3z.");
+                              }
+                          }
+                          if(k==16)
+                          {
+                               return("The given function defines an isolated Singularity.
+The Tjurina number is "+string(tjurina(f))+".
+E^0[8]:z2+x3+y5.");
+                          }
+                  }
+     }
+     if(h==0)
+     {
+            list P=factorize(j);
+            if((size(P[1])==2)&&(size(P[2])==2)&&((P[2][2])==1))
+            {
+               if(k==6)
+               {
+                    return("The given function defines an isolated Singularity.
+The Tjurina number is "+string(tjurina(f))+".
+E^1[6]:z2+x3+y2z+xyz.");
+               }
+               if(k==8)
+               {
+                    return("The given function defines an isolated Singularity.
+The Tjurina number is "+string(tjurina(f))+".
+E^0[6]:z2+x3+y2z.");
+
+               }
+            }
+            if((size(P[1])==4)&&(size(P[2])==4))
+            {
+               if(k==8)
+               {
+                   return("The given function defines an isolated Singularity.
+The Tjurina number is "+string(tjurina(f))+".
+D^0[4]:z2+x2y+xy2.");
+
+               }
+               if(k==6)
+               {
+                   return("The given function defines an isolated Singularity.
+The Tjurina number is "+string(tjurina(f))+".
+D^1[4]:z2+x2y+xy2+xyz.");
+
+               }
+            }
+
+            if((size(P[1])==3)&&(size(P[2])==3))
+            {
+                if(((P[2][2])==1)&&((P[2][3])==1))
+                {
+                      if(k==6)
+                      {
+                           return("The given function defines an isolated Singularity.
+The Tjurina number is "+string(tjurina(f))+".
+D^1[5]:z2+x2y+y2z+xyz.");
+                      }
+                      if(k==8)
+                      {
+                          if(size(lengthBL(f))==4)
+                          {
+                              return("The given function defines an isolated Singularity.
+The Tjurina number is "+string(tjurina(f))+".
+E^3[7]:z2+x3+xy3+xyz.");
+                          }
+                          else
+                          {
+                                if(size(lengthBL(f))==5)
+                                {
+                                    return("The given function defines an isolated Singularity.
+The Tjurina number is "+string(tjurina(f))+".
+E^4[8]:z2+x3+y5+xyz.");
+
+                                 }
+                                 else
+                                 {
+                                     return("The given function defines an isolated Singularity.
+The Tjurina number is "+string(tjurina(f))+".
+D^0[5]:z2+x2y+y2z.");
+
+                                 }
+                            }
+                        }
+                   }
+
+              }
+
+              if((size(P[1])==2)&&((P[2][2])==3))
+              {
+                         if(k==10)
+                         {
+                              if(size(lengthBL(f))==4)
+                              {
+                                     return("The given function defines an isolated Singularity.
+The Tjurina number is "+string(tjurina(f))+".
+E^2[7]:z2+x3+xy3+y3z.");
+
+                              }
+                              if(size(lengthBL(f))==5)
+                              {
+                                     return("The given function defines an isolated Singularity.
+The Tjurina number is "+string(tjurina(f))+".
+E^3[8]:z2+x3+y5+y3z.");
+
+                               }
+                          }
+                          if(k==12)
+                          {
+
+                               if(size(lengthBL(f))==4)
+                               {
+                                     return("The given function defines an isolated Singularity.
+The Tjurina number is "+string(tjurina(f))+".
+E^1[7]:z2+x3+xy3+xy3z.");
+
+                                }
+                                if(size(lengthBL(f))==5)
+                                {
+                                     return("The given function defines an isolated Singularity.
+The Tjurina number is "+string(tjurina(f))+".
+E^2[8]:z2+x3+y5+xy2z.");
+
+                                 }
+                           }
+                           if(k==14)
+                           {
+
+                                if(size(lengthBL(f))==4)
+                                {
+                                     return("The given function defines an isolated Singularity.
+The Tjurina number is "+string(tjurina(f))+".
+E^0[7]:z2+x3+xy3.");
+
+                                }
+                                if(size(lengthBL(f))==5)
+                                {
+                                     return("The given function defines an isolated Singularity.
+The Tjurina number is "+string(tjurina(f))+".
+E^1[8]:z2+x3+y5+xy3z.");
+
+                                }
+                           }
+                           if(k==16)
+                           {
+                                return("The given function defines an isolated Singularity.
+The Tjurina number is "+string(tjurina(f))+".
+E^0[8]:z2+x3+y5.");
+
+                           }
+               }
+               return(surDsing(f));
+      }
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+static proc surDsing(poly f)
+//====Classification of Dk singularaties========================
+
+{
+      //===input: A function which is an isolated singularity.
+      //===output: Normal form to which given function is contact equivalent.
+
+     def R=basering;
+     int n=nvars(R);
+     f=formf(f);
+     int k=tjurina(f);
+
+     list M=factorize(jet(f,2));
+
+     poly g=subst(f,leadmonom(M[1][2]),0);
+     poly j=jet(g,3);
+     if(j==0)
+     {
+
+       return("The given function defines not a simple singularity.
+The Tjurina Number is "+string(k)+".");
+
+     }
+     list P=factorize(j);
+     if((size(P[1])==4)&&(size(P[2])==4))
+     {
+           if(k==8)
+           {
+
+              return("The given function defines an isolated Singularity.
+The Tjurina number is "+string(tjurina(f))+".
+D^0 [4]:z2+x2y+xy2.");
+
+           }
+           if(k==6)
+           {
+               return("The given function defines an isolated Singularity.
+The Tjurina number is "+string(tjurina(f))+".
+D^1 [4]:z2+x2y+xy2+xyz.");
+
+           }
+     }
+     if((size(P[1])==3)&&(size(P[2])==3))
+     {
+
+         poly q=BlowUpO(f);
+
+         if((tjurina(f)-tjurina(q))==4)
+         {
+               list Q=whichSUR(f);
+
+               j=subst(Q[2],leadmonom(M[1][2]),0);
+               poly j1=jet(j,3);
+               list L=factorize(j1);
+
+               if((size(L[1])==4)&&(size(L[2])==4))
+               {
+                     return("The given function defines an isolated Singularity.
+The Tjurina number is "+string(tjurina(f))+".
+D^0 ["+string(tjurina(f) div 2)+"]:z2+x2y+xy"+string(tjurina(f) div 4)+". ");
+
+               }
+               if((size(L[1])==3)&&(size(L[2])==3))
+               {
+                    return("The given function defines an isolated Singularity.
+The Tjurina number is "+string(tjurina(f))+".
+D^0 ["+string((tjurina(f) div 2)+1)+"]:z2+x2y+y"+string(tjurina(f) div 4)+"z.");
+
+               }
+          }
+          if((tjurina(f)-tjurina(q))==2)
+          {
+
+               list Q=whichSUR(f);
+               if(Q[1]==8){Q[2]=BlowUpO(Q[2]);}
+               j=subst(Q[2],leadmonom(M[1][2]),0);
+               poly j1=jet(j,3);
+
+               list L=factorize(j1);
+               if((size(L[1])==4)&&(size(L[2])==4))
+               {
+                  return("The given function defines an isolated Singularity.
+The Tjurina number is "+string(tjurina(f))+".
+D^"+string(findSUR(f))+" ["+string((tjurina(f)+2*findSUR(f)) div 2)+"]:z2+x2y+xy^"+string((tjurina(f)+2*findSUR(f)) div 4)+"+ xy"+string(((tjurina(f)+2*findSUR(f)) div 4)-findSUR(f))+" z.");
+
+               }
+               if((size(L[1])==3)&&(size(L[2])==3))
+               {
+               return("The given function defines an isolated Singularity.
+The Tjurina number is "+string(tjurina(f))+".
+D^"+string(findRSUR(f))+" ["+string(((tjurina(f)+2*findRSUR(f)) div 2)+1)+"]:z2+x2y+y"+string((tjurina(f)+2*findRSUR(f)) div 4)+"z+xy"+string(((tjurina(f)+2*findRSUR(f)) div 4)-findRSUR(f))+"z.");
+
+               }
+          }
+     }
+}
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+static proc formf(poly f)
+//=====Transform jet(f,2) in to the polynomial var(3)^2.
+//=====This is the case when We are in Dk and Ek surface singularaties.
+{
+
+        poly j=jet(f,2);
+        list L=factorize(j);
+        def r=basering;
+        if(leadmonom(L[1][2])==var(1))
+        {
+            f=subst(f,var(1),L[1][2]);
+            map phi=r,var(3),var(2),var(1);
+            return(phi(f));
+
+        }
+        if(leadmonom(L[1][2])==var(2))
+        {
+            f=subst(f,var(2),L[1][2]);
+             map phi=r,var(1),var(3),var(2);
+                return(phi(f));
+
+        }
+        if(leadmonom(L[1][2])==var(3))
+        {
+             return(f);
+        }
+}
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+static proc whichSUR(poly f)
+//====This procedure is required to separate the Surface Case D_2m from D_2m+1 as discribes in [2].
+{
+   int d=tjurina(f);
+   list L;
+   while(1)
+   {
+       f=BlowUpO(f);
+       d=tjurina(f);
+
+       if((d==6)||(d==8))
+       {
+         L[1]=d;
+         L[2]=f;
+
+         return(L);
+       }
+   }
+   return(d);
+}
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+static proc findSUR(poly f)//D2m,r
+//====Number of blowup required in order either to get the difference equal to 4 or the Tjurina number is less than 6.
+{
+
+     int a, r,b;
+     while(1)
+     {
+         r++;
+         a=tjurina(f);
+         if(a<=1)
+         {
+            return(r);
+         }
+         f=BlowUpO(f);
+         b=tjurina(f);
+         if((a-b)==4)
+         {
+              if(b==2)
+              {
+                return(r);
+              }
+              return(r-1);
+         }
+         if(b<6)
+         {
+             return(r-1);
+         }
+
+      }
+}
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+static proc findRSUR(poly f)//D2m+1,r
+//====Calculate the number of blow ups required by a polynomial in order to get the difference 4.
+{
+
+    int a, r,b;
+    while(1)
+    {
+       r++;
+       a=tjurina(f);
+
+       if(a==2)
+       {
+           return(r);
+       }
+
+       f=BlowUpO(f);
+       b=tjurina(f);
+
+       if((a-b)==4)
+       {
+           return(r-1);
+       }
+       if(b<6)
+       {
+            return(r);
+       }
+    }
+}
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+static proc BlowUpO(poly f)
+//====Gives the procedure of Blowing up ingeneral
+{
+   //=== input f smooth or isolated singularity at zero
+   //=== output var(1) or poly with isolated singularity at zero, the transformation
+   //=== of the singularity of the blowing up to zero
+    def R=basering;
+   def S=changeord(list(list("ds",1:nvars(basering))));
+   setring S;
+   int n=nvars(basering);
+   int i,t,c,d,e,j,k;
+   poly f=imap(R,f);
+   if(deg(lead(f))<=1){setring R;return(var(1));}
+   poly p;
+   def T=changeord(list(list("lp",1:nvars(basering))));
+   setring T;
+   list L;
+   map phi,psi;
+   ideal mphi, mpsi,sing;
+   poly p,q,m,l;
+   poly h=var(1);
+   //===========  blow up=======================================================
+   for(i=1;i<=n;i++)
+   {
+      mphi=var(i)*maxideal(1);
+      mphi[i]=var(i);
+      phi=S,mphi;
+       p=phi(f);
+      q=p/var(i);
+      while(size(p)==size(q))
+      {
+         p=q;
+         q=q/var(i);
+      }
+      //===============  p is the strict transform var(i) exceptional divisor ====
+       //=============== analysis of singularities ================================
+      sing=jacob(p),p,var(i);
+      sing=radical(sing);
+      option(redSB);
+      sing=std(sing);
+      if(dim(sing)>0){ERROR("not simple");}
+      sing=std(simplify(sing,1));
+      if(dim(sing)==0)
+      {
+        if(vdim(sing)==1)
+            {
+                  mpsi=std(maxideal(1));
+                  for(k=1;k<=n;k++){mpsi[k]=var(k)-sing[n-k+1][2];}
+                  psi=T,mpsi;
+                  p=psi(p);
+            }
+            else
+            {     //this can only happen in case of a D-singularity
+                   L=minAssGTZ(sing);
+                   d=0;
+                   for(j=1;j<=size(L);j++)
+                   {
+                       sing=std(L[j]);
+                       sing=std(simplify(sing,1));
+                       if(vdim(sing)!=1){ERROR("something is wrong in blowUpO");}
+                       mpsi=std(maxideal(1));
+                       for(k=1;k<=n;k++){mpsi[k]=var(k)-sing[n-k+1][2];}
+                       psi=T,mpsi;
+                       m=psi(p);
+                       setring S;
+                       p=imap(T,m);
+                       e=tjurina(p);
+                       setring T;
+                       if(e>d)
+                       {
+                            d=e;
+                            l=m;
+                       }
+                    }
+                   p=l;
+            }
+            setring S;
+            p=imap(T,p);
+            c=tjurina(p);
+            setring T;
+            if(c>t)
+            {
+                 t=c;
+                 h=p;
+            }
+         }
+       }
+     setring R;
+     poly h=imap(T,h);
+     return(h);
+}
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+static proc lengthBL(poly f)
+//====Return the list of Tjurina numbers of each blowing up in the resolution before it becomes smooth.
+{
+    list L;
+    int i=1;
+    int d=tjurina(f);
+    while(d>=2)
+    {
+        f=BlowUpO(f);
+         L[i]=d;
+        d=tjurina(f);
+
+         i=i+1;
+    }
+    return(L);
+}
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+static proc curCeq2(poly f)
+//====Classification of Curves in Case when p=2.
+{
+
+     int c;
+     int k;
+     number m,a,b;
+     ideal I;
+     int d;
+     k=tjurina(f);
+     if(k==-1)
+     {
+           return("The given function defines not an isolated singularity");
+
+     }
+     if(deg(lead(f))==2)
+     {
+          poly f1=jet(f,2);
+          list T=factorize(f1);
+          if(size(T[1])==3)
+          {
+              return("The given function defines an isolated Singularity.
+The Tjurina number is "+string(tjurina(f))+".
+A1:x2+xy.");
+
+          }
+          if(size(T[1])==2)
+          {
+                poly g=BlowUpO(f);
+                if((tjurina(f)-tjurina(g))==4)
+                {
+                      return("The given function defines an isolated Singularity.
+The Tjurina number is "+string(tjurina(f))+".
+A["+string(k div 2)+"]:x2+y "+string(tjurina(f) div 2+1)+". where r=0. ");
+                }
+                else
+                {
+                     d=whichtru(f);
+                    if(d==1)
+                    {
+                         if((k mod 4)==0)
+                         {
+
+                            return("The given function defines an isolated Singularity.
+The Tjurina number is "+string(tjurina(f))+".
+A["+string(2*(tjurina(f) div 2)-1)+"]:x2+xy"+string(tjurina(f) div 2)+".");
+                         }
+                         else
+                         {
+                            return("The given function defines an isolated Singularity.
+The Tjurina number is "+string(tjurina(f))+".
+A["+string((2*(tjurina(f)+1) div 2)-1)+"]:x2+xy"+string((tjurina(f)+1) div 2)+".");
+
+                         }
+                    }
+                    if(d==0)
+                    {
+                        if((findR(f) mod 2)==0)
+                        {
+                           return("The given function defines an isolated Singularity.
+The Tjurina number is "+string(tjurina(f))+".
+A^"+string(findR(f))+" ["+string(2*((tjurina(f)+2*findR(f)) div 4))+"]:x2+y"+string(((tjurina(f)+2*findR(f)) div 2)+1)+"+xy"+string(((tjurina(f)+2*findR(f)) div 2)-findR(f))+".");
+                        }
+                        if((findR(f) mod 2)!=0)
+                        {
+                           return("The given function defines an isolated Singularity.
+The Tjurina number is "+string(tjurina(f))+".
+A^"+string(findR(f))+" ["+string(2*(((tjurina(f)+1)+2*findR(f)) div 4))+"]:x2+y"+string((((tjurina(f)+1)+2*findR(f)) div 2)+1)+"+xy"+string((((tjurina(f)+1)+2*findR(f)) div 2)-findR(f))+".");
+
+                        }
+                     }
+
+                 }
+
+           }
+
+       }
+       if(deg(lead(f))==3)
+       {
+           if(jet(f,3)==0)
+           {return("The given function defines not a simple Singularity.
+             The Tjurina number is "+string(tjurina(f))+".")}
+           poly f1=jet(f,3);
+           list L=factorize(f1);
+           if(size(L[1])==4)
+           {
+              return("The given function defines an isolated Singularity.
+The Tjurina number is "+string(tjurina(f))+".
+D[4]:x2y+xy2.");
+
+            }
+            if(size(L[1])==3)
+            {
+                poly g=BlowUpO(f);
+                if((tjurina(f)-tjurina(g))==8)
+                {
+                     return("The given function defines an isolated Singularity.
+The Tjurina number is "+string(tjurina(f))+".
+D^0["+string((tjurina(f) div 2)+1)+"]:x2y+y"+string(tjurina(f) div 2)+". where m="+string(tjurina(f)/4)+".");
+
+                 }
+                 else
+                 {
+                      if(whichtru(f)==1)
+                      {
+                         return("The given function defines an isolated Singularity.
+The Tjurina number is "+string(tjurina(f))+".
+D["+string(tjurina(f))+"]:x2y+xy"+string(tjurina(f) div 2)+". ");
+                       }
+                       if(whichtru(f)==0)
+                       {
+                             if((findRD(f) mod 2)==0)
+                             {
+                            return("The given function defines an isolated Singularity.
+The Tjurina number is "+string(tjurina(f))+".
+D^"+string(findRD(f))+"["+string(2*((tjurina(f) div 2+findRD(f)) div 2)+1)+"]:x2y+y"+string((tjurina(f) div 2+findRD(f)))+"+xy"+string((tjurina(f) div 2+findRD(f))-findRD(f))+" where even r="+string(findRD(f))+".");
+                              }
+                              else
+                              {
+                               return("The given function defines an isolated Singularity.
+The Tjurina number is "+string(tjurina(f))+".
+D^"+string(findRD(f))+"["+string(2*(((tjurina(f)+1) div 2+findRD(f)) div 2)+1)+"]:x2y+y"+string(((tjurina(f)+1) div 2+findRD(f)))+"+xy"+string(((tjurina(f)+1) div 2+findRD(f))-findRD(f))+",odd r="+string(findRD(f))+".");
+                               }
+                         }
+                 }
+             }
+             a=leadcoef(f);
+             b=leadcoef(f-lead(f));
+             f=subst(f,var(1),1/a*(var(1)-a*b*var(2)));
+             I=var(1),var(2)^2;
+             I=std(I^3);
+             if(reduce(f,I)!=0)
+             {
+                if(k==6)
+                 {
+                     return("The given function defines an isolated Singularity.
+The Tjurina number is "+string(tjurina(f))+".
+E^1[6]:x3+y4+xy3.");
+
+                 }
+                 if(k==7)
+                 {
+                      return("The given function defines an isolated Singularity.
+The Tjurina number is "+string(tjurina(f))+".
+E[7]:x3+xy3.");
+                  }
+                  if(k==8)
+                  {
+                       poly t=BlowUpO(f);
+                       if(tjurina(t)==0)
+                       {
+                           return("The given function defines an isolated Singularity.
+The Tjurina number is "+string(tjurina(f))+".
+E^0[6]:x3+y4.");
+                       }
+                        else
+                       {
+                           return("The given function defines an isolated Singularity.
+The Tjurina number is "+string(tjurina(f))+".
+E[8]:x3+y5.");
+                        }
+                   }
+               }
+               else
+               {return("The given function defines not a simple singularity.
+                        The Tjurina number is "+string(tjurina(f))+".");}
+      }
+
+      if(deg(lead(f))>3)
+      {
+
+          return("The given function defines not a simple singularity.
+                  The Tjurina number is "+string(tjurina(f))+".");
+
+      }
+}
+example
+{
+   "EXAMPLE:"; echo=2;
+   ring R=2,(x,y),Ds;
+   curCeq2(x3+x2y+xy2+y3+xy3+y4);
+
+}
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+static proc whichtru(poly f)
+//====Gives the information that we do successive blowups and the last singularaty before becoming smmoth has Tjurina
+//====number 1 if not than returns 0.(returns either a singularaty or smooth surve)============
+{
+   int d=tjurina(f);
+   while(1)
+   {
+       f=BlowUpO(f);
+       d=tjurina(f);
+       if(d==1)
+       {
+         return(d);
+       }
+       if(d==0)
+       {
+          return(d);
+       }
+   }
+  return(d);
+}
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+static proc findR(poly f)
+//====Find the number of blowups required by polynomial such that
+//====difference between two consecutive blowups become 4
+//====this procedure find the value of r in case of Ak singularaties as in [1].
+{
+    int a, r,b;
+    while(1)
+    {
+        r++;
+        a=tjurina(f);
+        if(a<=1)
+        {
+            return(-1);
+        }
+        f=BlowUpO(f);
+
+        b=tjurina(f);
+
+        if((a-b)==4)
+        {
+            return(r-1);
+        }
+     }
+}
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+static proc findRD(poly p)
+//=====Find the number of blowups required by polynomial such
+//=====that difference between two consecutive blowups become 4
+//=====this procedure find the value of r in case of Dk singularaties as in [1].
+{
+
+   int k=tjurina(p);
+   poly q=BlowUpO(p);
+   int t=tjurina(q);
+   int r;
+
+   if((k mod 4)==0)
+   {
+      r=findR(BlowUpO(p))+2;
+      return(r);
+   }
+   if((k mod 4 !=0)&&(t mod 4==0))
+   {
+     if(t!=0)
+     {
+        r=findR(BlowUpO(p))+1;
+       return(r);
+     }
+   }
+   if((k mod 2)==0)
+   {
+      r=findR(BlowUpO(p))+2;
+      return(r);
+   }
+
+}
+//////////////////////////////////////////////////////////////////////////////////////////////////////////
+static proc splitting_SQUA(poly p, int b)
+ {
+         // assumes that p=x_i^2+h, h of order >=3
+         // returns q(x_1,??,x_n) such that x_i^2 +q is right equivalent to p mod
+          // <x_1,??,x_n>^b and x_i is only linear in q
+            def R=basering; int n=nvars(R);
+            ideal M=maxideal(1);
+            int j;
+             map phi;
+             p=jet(p,b);
+             p=simplify(p,1);
+             list T=FindSQUA(p);
+             int i=T[1];
+             poly q=p/var(i)^2;
+             while(q!=1)
+             {
+                for(j=1;j<=n;j++)
+                {
+                   M[j]=var(j)*q;
+                }
+                phi=R,M;
+                p=phi(p);
+                p=p*inverseUnit(q,b);
+                p=jet(p,b);
+                q=p/var(i)^2;
+             }
+             return(p);
+ }
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////
+static proc splitting_two2(poly p, int i, int j, int b)
+{
+     // assumes that p=x_i*x_j+h, no x_i^2, no in h, h of order >=2
+     // returns q(x_1,??x_i-1,x_i+1,...,x_j-1,x_j+1,...,x_n) such that x_i*x_j +q is right equivalent to p mod
+     // <x_1,??,x_n>^b
+      if(b<2){b=2;}
+      def R=basering;
+      poly q=jet((p-var(i)*var(j))/var(i),b);
+      while(q!=0)
+      {
+         p=quickSubst2(p,var(j)-q,j,b);
+         q=jet((p-var(i)*var(j))/var(i),b);
+      }
+      return(simplify(substitute(jet(p,b),var(j),0),1));              //make the leading coefficient 1
+
+}
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+static proc quickSubst2(poly h, poly r, int i, int b)
+{
+    //=== assume h, r is in Q[x_1,...,x_n], computes jet(h(x_i=r),b)
+     h=jet(h,b);
+     r=jet(r,b);
+     matrix M=coef(h,var(i));
+     poly q = 1;
+     int j,k,d;
+     intvec v;
+     d=deg(M[1,1]);
+     v[d+1]=1;
+     for(k = 2; k <= ncols(M); k++)
+     {
+         v[deg(M[1,k])+1]=1;
+     }
+     h=0;
+     for(k=1;k<=d+1;k++)
+     {
+        if(v[k]==1)
+        {
+            h=h+jet(q*M[2,ncols(M)-j],b);
+            j++;
+        }
+        q=jet(q*r,b);
+      }
+   return(h);
+}
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+static proc FindPRO(poly f)
+{
+        //input the polynomial
+      // output is a list T where T[1]=the first variable which appear as product in the quadraic form.
+      //                          T[2]=the second variable which appear as product with the var(T[1]) in the quadraic form.
+  def R=basering;
+  int n=nvars(R);
+  int i,j,k;
+  list T;
+  for(i=1;i<=n;i++)
+  {
+     for(k=i+1;k<=n;k++)
+     {
+         for(j=1;j<=size(f);j++)
+         {
+             if(leadmonom(f[j])==var(i)*var(k))
+             {
+
+                T[1]=i;
+                T[2]=k;
+                return(T);
+             }
+         }
+     }
+
+  }
+   return(T);
+}
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+static proc FindSQUA(poly f)
+{
+      //input the polynomial
+      // output is a list T where T[1]=the first variable which appears as a square in the quadraic part of f.
+      //                          T[2]= the number of squares appearing in the quadraic part of f.
+  def R=basering;
+  int n=nvars(R);
+  int i,j,k;
+  list T;
+  for(i=1;i<=n;i++)
+  {
+       for(j=1;j<=size(f);j++)
+       {
+           if(leadmonom(f[j])==var(i)^2)
+           {
+                k++;
+                T[1]=i;
+                T[2]=k;
+                return(T);
+            }
+       }
+   }
+   return(T);
+}
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+static proc findVAR(poly f)
+{
+     //input: a poly f
+     //output a list L=v,k v an intvec, v[i]=0, if depends on var(i), v[i]=1 else
+     //k is the number of variables occurring in f
+     intvec v;
+     int i,k;int n=nvars(basering);
+     list L;
+     for(i=1;i<=n;i++)
+     {
+        if(f==subst(f,var(i),0))
+        {
+           v[i]=1;
+        }
+        else
+        {
+           v[i]=0;
+           k++;
+        }
+     }
+     L=v,k;
+     return(L);
+}
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+static proc redvar2(poly p)
+{
+       //input  a polynomial depending on x_i_1,...,x_i_k
+       //output a new ring with k variables containing the polynomial
+   def R=basering;
+   int n=nvars(R);
+   list N=findVAR(p);
+   int m=N[2];
+   intvec v=N[1];
+   int l;
+   int i;
+   if(n==m)
+   {
+
+        def S=R;
+        if(defined(h))
+        {
+           kill h;
+        }
+        poly h;
+        export h;
+
+   }
+   else
+   {
+      def S=defring("2",m,"u","ds");
+      setring S;
+      ideal M;
+      for(i=1;i<=n;i++)
+      {
+           if(v[i]==1)
+           {
+              M[i]=0;
+           }
+           else
+           {
+              l++;
+              M[i]=var(l);
+           }
+       }
+       map phi=R,M;
+       poly p=phi(p);
+       export p;
+       setring R;
+    }
+    return(S);
+}
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+static proc inverseUnit(poly q,int b)
+{
+   //input a polynomial q with non-zero constant part
+   //output the inverse of q up to order b as a power series
+   number c=leadcoef(q);
+   q=q/c;
+   int i;
+   poly u=1;
+   poly a=q-1;
+   poly s=-a;
+   for(i=1;i<=b;i++)
+   {
+      u=u+s;
+      s=s*a;
+   }
+   return(u/c);
+}
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+static proc splittingLchar2(poly f)
+{
+   //the quadratic part of the splitting lemma in characteristic 2
+   //input: poly f
+   //output: a polynomial right equivalent to the input polynomial such that the quadratic part is in normal form
+   poly p=jet(f,2);
+   if(p==0){return(f);}
+   if(!homog(p)){return(jet(f,1));}
+   def R=basering;
+   def S=changeord(list(list("lp",1:nvars(basering))));
+   setring S;
+   ideal ma=maxideal(1);
+   number a;
+   int c=ringlist(S)[1][1];
+   poly f=imap(R,f);
+   poly p=imap(R,p);
+   poly h,q;
+   intvec v=leadexp(p);
+   int i,j,k;
+   intvec w;
+   for(k=1;k<=size(v);k++)
+   {
+      if(v[k]!=0){w[size(w)+1]=k;}
+   }
+   i=w[2];
+   if(size(w)==3){j=w[3];}
+   if(j>0)
+   {
+      a=1/leadcoef(p);
+      ma[j]=a*(var(j)+(p-lead(p))/var(i));
+      map phi=S,ma;
+      p=phi(p);
+      f=phi(f);
+      q=(p-lead(p))/var(j);
+      ma=maxideal(1);
+      ma[i]=var(i)+q;
+      phi=S,ma;
+      f=phi(f);
+      h=splittingLchar2(f-var(i)*var(j));
+      if(jet(h,2)==0)
+     {
+         setring R;
+         f=imap(S,f);
+         return(f);
+      }
+      v=leadexp(h);
+      for(k=1;k<=size(v);k++)
+      {
+         if(v[k]!=0){break;}
+      }
+      if(v[k]==2)
+      {
+         ma=maxideal(1);
+         ma[i]=var(j);
+         ma[j]=var(k);
+         ma[k]=var(i);
+         phi=S,ma;
+         h=phi(h);
+         f=h+var(j)*var(k);
+      }
+      else
+      {
+         f=h+var(i)*var(j);
+      }
+      setring R;
+      f=imap(S,f);
+      return(f);
+   }
+
+   a= leadcoef(p)^(c div 2);
+   ma[i]=1/a*var(i);
+   map phi=S,ma;
+   p=phi(p);
+   f=phi(f);
+   q=p/var(i);
+   if(size(q)==1)
+  {
+      if(p==var(i)^2)
+      {
+         setring R;
+         f=imap(S,f);
+         return(f);
+      }
+      h=splittingLchar2(f-var(i)^2);
+      p=jet(h,2);
+      v=leadexp(p);
+      h=h+var(i)^2;
+
+      for(k=1;k<=size(v);k++)
+      {
+         if(v[k]!=0){j=k;break;}
+      }
+      if(v[j]==2)
+      {
+         ma=maxideal(1);
+         ma[i]=var(i)+var(j);
+         phi=S,ma;
+         h=phi(h);
+         h=splittingLchar2(h);
+      }
+      setring R;
+      f=imap(S,h);
+      return(f);
+   }
+   else
+   {
+      q=q-lead(q);
+      v=leadexp(q);
+      for(k=1;k<=size(v);k++)
+      {
+         if(v[k]!=0){j=k;break;}
+      }
+      ma=maxideal(1);
+      ma[j]=1/leadcoef(q)*(var(j)+q-lead(q));
+      phi=S,ma;
+      f=phi(f);
+      ma=maxideal(1);
+      ma[j]=var(i);
+      ma[i]=var(j);
+      phi=S,ma;
+      f=phi(f);
+      p=jet(f,2);
+      if(leadmonom(p)==var(i)^2)
+      {
+                                            f=phi(f);
+         p=jet(f,2);
+         ma=maxideal(1);
+         ma[i]=p/var(j)-var(j);
+         phi=S,ma;
+         f=phi(f);
+         h=splittingLchar2(f-var(i)^2-var(i)*var(j)-var(j)^2);
+         p=jet(h,2);
+
+         f=var(i)^2+var(i)*var(j)+var(j)^2+h;
+         if(p!=0)
+         {
+            v=leadexp(p);
+            for(k=1;k<=size(v);k++)
+            {
+               if(v[k]!=0){break;}
+            }
+            if(v[k]==2)
+            {
+               ma=maxideal(1);
+               ma[k]=var(i)+var(k);
+               phi=S,ma;
+               f=phi(f);
+               setring R;
+               f=imap(S,f);
+               return(splittingLchar2(f));
+            }
+            setring R;
+            f=imap(S,f);
+            return(f);
+         }
+         else                     //we return (x_i)^2+x_i*x_j+(x_j)^2 since we need a field extension
+         {                        //to transform it to x_i*x_j
+            setring R;
+            f=imap(S,f);
+            return(f);
+         }
+      }
+      setring R;
+      f=imap(S,f);
+      return(splittingLchar2(f));
+   }
+}
+///////////////////////////////////////////////////////////////////////////////////////////////////////////
+/*
+===============================   Examples for characteristic 2 ==========================================
+ring r=2,(x,y,z,w,t,v),ds;
+poly p=xy+zw+t5+v3;
+classifyCeq(p);
+
+map phi=r,v,t,w,z,y,x;
+poly c=1+x+y+z;
+poly q=c*p;
+q=phi(q);
+q=zw+tv+x3+zw2+zwt+zwv+wtv+t2v+tv2+x3w+x3t+x3v+y5+y5w+y5t+y5v;
+classifyCeq(q);
+
+poly p=ztv+x3+zw2+zwt+zwv+wtv+tv2+tv2+x3w+x3t+x3v+xy3+xy3w+xy3v;
+classifyCeq(p);
+
+poly p=zw+tv+x3+zw2+zwt+wtv+t2v+tv2+x3w+x3t+x3v+y4+y4w+y4t+y4v;
+classifyCeq(p);//E^0[6]
+
+poly p=zw+tv+x3+zw2+zwt+zwv+wtv+t2v+tv2+x3w+x3t+x3v+xy3+y4+xy3w+xy3t+xy3v+y4w+y4t+y4v;
+classifyCeq(p);//E^1[6]
+
+poly p=y2+zw+tv+y2w+y2t+y2v+zw2+zwt+zwv+wtv+t2v+tv2+x11+x11w+x11t+x11v;
+classifyCeq(p);//A[10] r=0;
+
+poly p=zw+tv+xy2+zw2+zwv+zwt+wtv+t2v+tv2+xy2w+xy2t+xy2v+x14y+x14yw+x14yt+x14yv+x26+x26w+x26t+x26v;
+classifyCeq(p);
+
+ring r=2,(x,y,z,t,w,u,v),Ds;
+ideal I=z+t,x+t+w,v,y,u,t,w+z;
+det(jacob(I));
+map phi=r,I;
+poly a=1+x+u+v;
+poly p=xy+zt+wu+v19;
+poly q=a*p;
+poly j=phi(q);
+classifyCeq(j);
+classifyCeq(p);
+
+poly p=x2+yz+tw+u3+v2x;
+classifyCeq(p);
+
+poly q=a*p;
+poly j=phi(q);
+classifyCeq(j);
+
+poly p=xy+zw+t2+u2v+v19u;
+classifyCeq(p);
+
+poly q=a*p;
+poly j=phi(q);
+classifyCeq(j);
+
+poly p=xy+zw+t2+u2v+v5t+uvt;
+classifyCeq(p);
+
+poly q=a*p;
+poly j=phi(q);
+classifyCeq(j);
+
+poly p=xy+zw+t2+u2v+v5u+uvt;
+classifyCeq(p);
+
+poly q=a*p;
+poly j=phi(q);
+classifyCeq(j);
+
+ring r=2,(x,y,z,t,w,u,v,e),Ds;
+ideal I=x+y+z+t+w,y+z+t+w,e,v,u,t,w,z;
+map si=r,I;
+
+poly p=xy+zt+wu+v2+e81;
+poly j=si(p);
+classifyCeq(j);
+
+poly p=xy+zt+wu+v2+e81+e^(80-12)*v;
+classifyCeq(p);
+poly j=si(p);
+classifyCeq(j);
+
+poly p=xy+zt+wu+v2e+e60+e31v;
+classifyCeq(p);
+
+poly p=xy+zt+wu+v2e+e60+e59v;
+poly j=si(p);
+classifyCeq(j);
+===============================   Examples for characteristic > 2 ========================================
+ring R=3,(x,y,z,u,v,w,s,t),ds;
+ideal M=maxideal(1);
+M[3]=x-y+z+u+w-s+t;
+poly f=u3+v4+u2v2+x2+y2+z2+s2+t2+w2;
+classifyCeq(f);
+
+map phi=R,M;
+f=phi(f);
+classifyCeq(f);
+
+f=u2+y32+s2+t2+v2+x2+z2+w2;
+classifyCeq(f);
+
+map phi=R,M;
+f=phi(f);
+classifyCeq(f);
+
+
+f=v2w+w61+x2+y2+z2+t2+z2+s2+u2;
+classifyCeq(f);
+
+f=phi(f);
+classifyCeq(f);
+
+f=u2+v2+w2+s2+t2-x2y+xy2+z6+y11+xy11+x14+z53;  // f is of corank=3
+classifyCeq(f);
+
+f=x3+y4+xy5+s2+t2;
+classifyCeq(f);
+
+f=u3+v5+u2v2+x2+y2+z2+t2+s2+w2;
+classifyCeq(f);
+
+ideal M=maxideal(1);
+M[2]=x+y+2s+t;
+map phi=R,M;
+f=phi(f);
+classifyCeq(f);
+
+ring R=3,(u,v,w,s,t),ds;
+poly f=w2s+s21+u2+v2+t2;
+classifyCeq(f);
+
+ideal M=maxideal(1);
+M[3]=u+2v+w+2t+2s;
+map phi=R,M;
+f=phi(f);
+classifyCeq(f);
+
+ring R=5,(x,y,z,u,v,w,s,t),dp;
+poly f=v2w+w61+x2+y2+z2+t2+z2+s2+u2;
+classifyCeq(f);
+
+*/
diff --git a/Singular/LIB/classifyci.lib b/Singular/LIB/classifyci.lib
new file mode 100644
index 0000000..4453613
--- /dev/null
+++ b/Singular/LIB/classifyci.lib
@@ -0,0 +1,1133 @@
+////////////////////////////////////////////////////////////////////////////////
+version=="version classifyci.lib 4.0.0.0 Jun_2013 "; // $Id: 3490b4512206c608167dc0874d4c2066225031b8 $
+category="Singularities";
+
+info="
+LIBRARY:  classifyci.lib     Isolated complete intersection singularities in characteristic  0
+AUTHORS:  Gerhard Pfister     pfister at mathematik.uni-kl.de
+          Deeba Afzal         deebafzal at gmail.com
+
+
+OVERVIEW:
+   A library for classifying isolated complete intersection singularities for the base field of characteristic  0
+   and for computing weierstrass semigroup of the space curve.Isolated complete intersection singularities were
+   classified by M.Giusti [1] for the base field of characteristic 0. Algorithm for the semigroup of a space
+   curve singularity is given in [2].
+
+REFERENCES:
+[1] Giusti,M:Classification des singularities isolees simples d'intersections completes,
+             C,R.Acad.Sci.Paris Ser.A-B 284(1977),167-169.
+[2] Castellanos,A.,Castellanos,J.,2005:Algorithm for the semigroup of a space curve singularity.
+             Semigroup Forum 70,44-66.
+PROCEDURES:
+ classifyicis(I);  Isolated simple complete intersection singularities for the base field of charateristic  0
+ Semigroup(I);     Weierstrass semigroup of the space curve given by equations
+";
+LIB "classify.lib";
+LIB "classify_aeq.lib";
+LIB "poly.lib";
+LIB "curvepar.lib";
+LIB "algebra.lib";
+
+////////////////////////////////////////////////////////////////////////////////
+proc classifyicis(ideal I)
+"USAGE: classifyicis(I);  I ideal
+ASSUME: I is given by two generators
+PURPOSE:Check whether the ideal defines a complete intersection singularity or not
+RETURN: String  type in the classification of Giusti,M
+@*           or The given singularity is not simple
+EXAMPLE: example classifyicis;  shows an example
+"
+{
+   def R=basering;
+   def SS=changeord(list(list("ds",nvars(R))),R);
+   setring SS;
+   ideal I=imap(R,I);
+   string re;
+   if(char(basering)==0)
+   {
+       re=ICIS12(I);
+   }
+    if(char(basering)!=0)
+   {
+          re="The characteristic of basering should be 0";
+   }
+   setring R;
+   return(re);
+}
+example
+{
+  "EXAMPLE:"; echo=2;
+   ring R=0,(x,y,z),ds;
+   ideal I=x2+yz,xy+z4;
+   classifyicis(I);
+}
+////////////////////////////////////////////////////////////////////////////////
+static proc ICIS12(ideal I)
+{
+  int n=nvars(basering);
+  if(n==2)
+  {
+     return(zerodim_ICIS(I));
+  }
+  if(n==3)
+  {
+     return(onedim_ICIS(I));
+  }
+  if(n>=4)
+  {
+     return("The given singularity is not simple");
+  }
+}
+////////////////////////////////////////////////////////////////////////////////
+static proc zerodim_ICIS(ideal I)
+"USAGE: zerodim_ICIS(l);  I is an ideal
+ASSUME: I is given by two generators
+PURPOSE: Check whether the ideal defines a complete intersection singularity of dimension zero or not
+RETURN: String  type in the classification of Giusti,M, of the 0-dimensional complete inetersection
+@*       or The given singularity is not simple
+EXAMPLE: example zerodim_ICIS; shows an example
+"
+{
+  def R=basering;
+  poly g,h,r;
+  ideal J;
+  int a,b,c,d;
+  map phi;
+  list L;
+  string re;
+  // g=g[0]+g[1]   where ord(g[1])>=3   ,g[0] can be zero
+  // h=h[0]+h[1]    where ord(h[1])>=3    ,h[0] can be zero
+  d=vdim(std(I));
+  if(d==-1)
+  {
+    return("The given singularity is not simple");
+  }
+  a=ord(I[1]);
+  b=ord(I[2]);
+  if((a>=3)&&(b>=3))
+  {                                             //start case1
+    return("The given singularity is not simple");
+  }                                           // end case 1
+  if((a==2&&b>=3)||(a>=3&&b==2))                // start case 2
+  {
+    if(a==2)
+    {
+      g=I[1];
+      h=I[2];
+    }
+    if(b==2)
+    {
+      g=I[2];
+      h=I[1];
+    }
+    L=factorize(jet(g,2));
+    if(size(L[1])==3)
+    {
+      re=findwhichF(g,h,L);
+      return(re);
+    }                                     // end size(L[1]=3)
+    if((size(L[1])==2)&&(L[2][2]==2))
+    {                                     // start (size(L[1])==2)&&(L[2][2]==2)
+      // case (x2,h);
+      r=L[1][2];
+      if(size(r)==2)                //  ax+by  goes to x
+      {
+        matrix M3=coef(r,var(1));
+        M3=subst(M3,var(2),1);
+        matrix A[2][2]=M3[2,1],M3[2,2],0,1;
+        matrix B=inverse(A);
+        phi=R,B[1,1]*var(1)+B[1,2]*var(2),B[2,1]*var(1)+B[2,2]*var(2);
+        g=phi(g);
+        h=phi(h);
+        J=(g,h);
+      }            // end size(r)=2
+      if(size(r)==1)                 // jet(g,2)=ax2 or  by2   goes to x2
+      {
+        if(leadmonom(r)==var(1))
+        {
+          phi=R,var(1)/leadcoef(r),var(2);
+          g=phi(g);
+          h=phi(h);
+        }
+        if(leadmonom(r)==var(2))
+        {
+          phi=R,var(2)/leadcoef(r),var(1);
+          g=phi(g);
+          h=phi(h);
+        }
+        J=(g,h);
+      }                // end size(r)=1
+      c=milnor(g);
+      if((d>=7)&&(c==2))
+      {
+        //"I-series";
+        if(d mod(2)==0)
+        {
+          return("I_"+string(d-1)+":(x2+y3,y"+string(d div 2)+")");
+        }
+        if(d mod(2)!=0)
+        {
+          return("I_"+string(d-1)+":(x2+y3,xy"+string((d-3) div 2)+")");
+        }
+      }
+      if(d==6)
+      {
+        return("G_5:(x2,y3)");
+      }
+      ring R1=0,(var(2),var(1)),ds;
+      setring R1;
+      ideal J=imap(R,J);
+      poly h1=reduce(J[2],std(J[1]),d);
+      poly h2=leadmonom(h1);
+      int ss=deg(h2)-1;
+      if((h2==var(1)^4)&&((c>=3)||(c==-1)))
+      {
+        setring R;
+        return("G_7:(x2,y4)");
+      }
+      if((h2==var(2)*var(1)^2)&&((c>=3)||(c==-1)))
+      {
+        setring R;
+        return("H_"+string(d-1)+":(x2+y"+string(d-4)+",xy2)");
+      }
+      setring R;
+      return("The given singularity is not simple");
+    }                                          // end (size(L[1])==2)&&(L[2][2]==2)
+    if((size(L[1])==2)&&(L[2][2]==1))
+    {
+      def S=factorExt(g);
+      setring S;
+      poly h=imap(R,h);                     // poly g=imap(R,g);  we need not S has already g
+      re= findwhichF(g,h,L);
+      setring R;
+      return(re);
+    }
+  }                                            // end case 2
+  if((a==2)&&(b==2))                  // start case 3
+  {
+    g=I[1];
+    h=I[2];
+    poly Q=testDiv(jet(h,2),jet(g,2));
+    if(Q!=0)
+    {
+      I=(g,h-Q*g);
+      return(zerodim_ICIS(I));
+    }
+    if(Q==0)
+    {
+      L=factorize(jet(g,2));
+      if(size(L[1])==3)
+      {
+        re=findwhichF(g,h,L);
+        return(re);
+      }
+      if((size(L[1])==2)&&(L[2][2]==1))
+      {
+        def S=factorExt(g);
+        setring S;
+        poly h=imap(R,h);
+        re=findwhichF(g,h,L);
+        setring R;
+        return(re);
+      }
+      L=factorize(jet(h,2));
+      if(size(L[1])==3)
+      {
+        re=findwhichF(h,g,L);
+        return(re);
+      }
+      if((size(L[1])==2)&&(L[2][2]==1))
+      {
+        def S=factorExt(h);
+        setring S;
+        poly g=imap(R,g);
+        re=findwhichF(h,g,L);
+        setring R;
+        return(re);
+      }
+      else
+      {    // there exist a s.t g[0]+ah[0] has two different factors.
+        int e=Finda(g,h);
+        I=(g+e*h,h);
+        re=zerodim_ICIS(I);
+        return(re);
+      }
+    }
+  }                                              // end case 3
+}                                                //  proc
+example
+{
+  "EXAMPLE:"; echo=2;
+   ring R=0,(x,y),ds;
+   ideal I=x2+8xy+16y2+y3,xy7+4y8;
+   zerodim_ICIS(I);
+}
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+static proc Finda(poly g,poly h)
+"USAGE:  Finda(g,h);  g,h are polynomials
+PURPOSE: Find a such that jet(g,2)+a*jet(h,2) has two different factors
+RETURN: integer a
+{
+  // find  a s.t jet(g,2)+a*jet(h,2) has two different factors.
+  int o;
+  list L=factorize(jet(h,2));
+  if(L[2][2]==1){return(0);}
+  poly r= jet(g,2);
+  list T=factorize(r);
+  while(T[2][2]!=1)
+  {
+    o++;
+    r= r+jet(h,2);
+    T=factorize(r);
+  }
+  return(o);
+}
+/*
+ring R=0,(x,y),ds;
+poly g=x2+xy3;
+poly h=y2+x3+y7;
+finda(g,h);
+*/
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+static proc testDiv(poly f,poly g)
+"USAGE:  testDiv(f,g);  f,g are polynomials
+ASSUME: I is given by two generators
+PURPOSE: Check whether  f divides g or not.
+RETURN: poly h(quotient)  if f divides g
+ @*              0 if f does not divide g
+{
+  poly h=f/g;
+  if(f-h*g==0)
+  {
+    return(h);
+  }
+  return(0);
+}
+/*
+   ring R=0,(x,y,ds;
+   poly f=x2+y2;
+   poly g=3x2+3y2
+   testDiv(f,g);
+*/
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ static proc findwhichF(poly g,poly h,list L)
+"USAGE:  findwhichF(g,h,L);  g,h are polynomials,L list of factors of jet(g,2)
+RETURN: string  type F^n,p_n+p-1 in the classification of Giusti,M
+{
+  // return("F^n,p_n+p-1")
+  def R=basering;
+  matrix M,N;
+  ideal J;
+  map si;
+  list T;
+  string rem;
+  //  in each case we want to transform jet(g,2) which has two factors to xy
+// and then find std and know about the type of  "F^n,p_n+p-1"
+  if((size(L[1][2])==2)&&(size(L[1][3])==2))
+  {
+    M=coef(L[1][2],var(1));
+    N=coef(L[1][3],var(1));
+    matrix A[2][2]=M[2,1],M[2,2],N[2,1],N[2,2];
+    A=subst(A,var(1),1,var(2),1);
+    matrix B=inverse(A);
+    si=R,B[1,1]*var(1)+B[1,2]*var(2),B[2,1]*var(1)+B[2,2]*var(2);
+    g=si(g);
+    h=si(h);
+    J=(g,h);
+    J=std(J);
+    // if g and h both of order 2 no problem in that case because deg(J[2])=2 so lead(J[2])=x2,y2,xy does not matter
+    T[1]=deg(lead(J[2]));
+    T[2]=deg(lead(J[3]))-1;
+    rem="F^"+string(T[1])+","+string(T[2])+"_"+string(T[1]+T[2]-1)+":(xy,x"+string(T[1])+"+y"+string(T[2])+")";
+    return(rem);
+  }
+  if((size(L[1][2])==2)&&(size(L[1][3])==1))
+  {
+    // two cases 1- jet(g,2)=(ax+by)*cx,  2-  jet(g,2)=(ax+by)*cy
+    if(leadmonom(L[1][3])==var(1))
+    {
+      M=coef(L[1][2],var(1));
+      M=subst(M,var(2),1);
+      si=R,var(1),-M[2,1]/M[2,2]*var(1)+var(2);
+      g=si(g);
+      h=si(h);
+      J=(g,h);
+      J=std(J);
+      T[1]=deg(lead(J[2]));
+      T[2]=deg(lead(J[3]))-1;
+      rem="F^"+string(T[1])+","+string(T[2])+"_"+string(T[1]+T[2]-1)+":(xy,x"+string(T[1])+"+y"+string(T[2])+")";
+      return(rem);
+    }
+    if(leadmonom(L[1][3])==var(2))
+    {
+      M=coef(L[1][2],var(1));
+      M=subst(M,var(2),1);
+      matrix A[2][2]=M[2,1],M[2,2],0,1;
+      matrix  B=inverse(A);
+      si=R,B[1,1]*var(1)+B[1,2]*var(2),B[2,1]*var(1)+B[2,2]*var(2);
+      g=si(g);
+      h=si(h);
+      J=(g,h);
+      J=std(J);
+      T[1]=deg(lead(J[2]));
+      T[2]=deg(lead(J[3]))-1;
+      rem="F^"+string(T[1])+","+string(T[2])+"_"+string(T[1]+T[2]-1)+":(xy,x"+string(T[1])+"+y"+string(T[2])+")";
+      return(rem);
+    }
+  }
+  else
+  {
+    J=(g,h);
+    J=std(J);
+    T[1]=deg(lead(J[2]));
+    T[2]=deg(lead(J[3]))-1;
+    rem="F^"+string(T[1])+","+string(T[2])+"_"+string(T[1]+T[2]-1)+":(xy,x"+string(T[1])+"+y"+string(T[2])+")";
+    return(rem);
+  }
+}
+/*
+ ring R=0,(x,y),ds;
+poly g=xy+y2+y4;
+poly h=x4+4x3y+6x2y2+4xy3+y4+y7+xy7;
+L=factorize(jet(g,2),2);
+findwhichF(g,h,L);
+*/
+////////////////////////////////////////////////////////////////////////////////
+static proc factorExt(poly g)
+"USAGE:  procExt(g); jet(g,2) is an irreducible polynomial
+PURPOSE: Find the field extension in which jet(g,2) has two different factors
+RETURN: ring S in which jet(g,2) has factors
+{
+  def R=basering;
+  g=simplify(g,1);
+  poly f=jet(g,2);
+  list L=factorize(f);
+  if(L[2][2]==1)
+  {
+    ring S=(0,t),(var(1),var(2)),ds;
+    poly f=fetch(R,f);
+    poly g=fetch(R,g);
+    minpoly=t2+leadcoef(f/(var(1)*var(2)))*t+leadcoef(f/var(2)^2);
+    list L=factorize(f);
+    export L;
+    export g;
+  }
+  else
+  {
+    def S=R;
+    export L;
+  }
+  setring R;
+  return(S);
+}
+/*
+ring R=0,(x,y),ds;
+poly g=x2=y2+x4+xy11;
+factorExt(g);
+*/
+////////////////////////////////////////////////////////////////////////////////
+static proc onedim_ICIS(ideal I)
+"USAGE:  onedim_ICIS(l);  I is an ideal
+ASSUME: I is given by two generators
+PURPOSE: Check whether the ideal defines a complete intersection singularity of dimension 1 or not
+RETURN: String  type in the classification of Giusti,M, of 1-dimesnional complete inetersection singualrity
+@*       or The given singularity is not simple
+EXAMPLE: example onedim_ICIS; shows an example
+"
+{
+  int m,t,r;
+  poly g1,g2,f1,f2;
+  string rem;
+  list A,B;
+  f1=I[1];
+  f2=I[2];
+  // I=nf_icis(I);
+  m=genericmilnor(I);
+  t=tjurina(I);
+  if(m==-1)
+  {
+    return("The given singularity is not simple");
+  }
+  if(m!=t)                // in ICIS milnor=tjurina
+  {
+    return("The given singularity is not simple");
+  }
+  g1=jet(f1,2);
+  g2=jet(f2,2);
+  if((ord(g1)==1)||(ord(g2)==1)){return(arnoldsimple(I,m));}
+  if(g1==0)
+  {
+    return("The given singularity is not simple");
+  }
+  if(g2==0)
+  {
+    return("The given singularity is not simple");
+  }
+  rem=typejet2(g1,g2);
+  if(rem=="type1")
+  {
+    return("S_5:(x2+y2+z2,yz)");
+  }
+  if(rem=="type2")
+  {
+    return("S_"+string(m)+":(x2+y2+z"+string(m-3)+",yz)");
+  }
+  if(rem=="type3")
+  {
+    if(m==7)
+    {
+      return("T_7:(x2+y3+z3,yz)");
+    }
+    if(m==8)
+    {
+      return("T_8:(x2+y3+z4,yz)");
+    }
+    if(m==9)
+    {
+      B=Semigroup(I);
+      B=changeType(B);
+      A=list(list(2,5),list(2,3));
+      if(compLL(A,B))
+      {
+        return("T_9:(x2+y3+z5,yz)");
+      }
+    }
+    return("The given singularity is not simple");
+  }
+  if(rem=="type4")
+  {
+    if(m==7)
+    {
+      return("U_7:(x2+yz,xy+z3)");
+    }
+    if(m==8)
+    {
+      return("U_8:(x2+yz+z3,xy)");
+    }
+    if(m==9)
+    {
+      return("U_9:(x2+yz,xy+z4)");
+    }
+    return("The given singularity is not simple");
+  }
+  if(rem=="type5")
+  {
+    if(m==8)
+    {
+      return("W_8:(x2+z3,y2+xz)");
+    }
+    if(m==9)
+    {
+      return("W_9:(x2+yz2,y2+xz)");
+    }
+    return("The given singularity is not simple");
+  }
+  if(rem=="type6")
+  {
+    if(m==9)
+    {
+      return("Z_9:(x2+z3,y2+z3)");
+    }
+    if(m==10)
+    {
+      return("Z_10:(x2+yz2,y2+z3)");
+    }
+    return("The given singularity is not simple");
+  }
+  if(rem=="not simple")
+  {
+    return("The given singularity is not simple");
+  }
+}
+example
+{
+  "EXAMPLE:"; echo=2;
+   ring R=0,(x,y,z),ds;
+   ideal I=x2+8xy+16y2+2xz+8yz+z2+yz2+9z3,y2+xz+22yz+82z2;
+   onedim_ICIS(I);
+}
+////////////////////////////////////////////////////////////////////////////////
+static proc arnoldsimple(ideal I,int m)
+"USAGE:  arnoldsimple(I,m);  I is an ideal, m is an integer greater or equal to milnor number of the ideal I
+ASSUME: I is given by two generators and one of the generator of the ideal I is of order 1
+PURPOSE: check whether the ideal defines a  hypersurface simple complete intersection singularity or not
+RETURN: string  type in the classification of Arnold,
+@*       or The given singularity is not simple
+EXAMPLE: example arnoldsimple; shows an example
+"
+{
+ //if one generator is of order 1 we reduce case to hypersurface case
+  def R=basering;
+  if(ord(I[1])==1)
+  {
+    poly g=specialNF(I[2],I[1],m);
+    ring S=0,(var(2),var(3)),ds;
+    setring S;
+    poly g=imap(R,g);
+    string dd=complexSingType(g);
+    int e=modality(g);
+    setring R;
+    if(e==0)
+    {
+      return(dd);
+    }
+    if(e!=0)
+    {
+      return( "The given singularity is not simple");
+    }
+  }
+  if(ord(I[2])==1)
+  {
+    I=I[2],I[1];
+    return(arnoldsimple(I,m));
+  }
+}
+example
+{
+  "EXAMPLE:"; echo=2;
+   ring R=0,(x,y,z),ds;
+   ideal I=x+y2,y3+z4+xy11;
+   arnoldsimple(I,6);
+}
+////////////////////////////////////////////////////////////////////////////////
+static proc specialNF(poly g,poly f,int m)
+"USAGE:  specialNF(g,f);  g,f are polynomials, m is an integer greater or equal to milnor number of the ideal I=(g,h)
+ASSUME: f is of order 1 and f=x+higher
+RETURN: poly g not involving x (Using implicit fn thm)
+{
+  poly k;
+  list T=linearpart(g,f);
+  f=T[1];
+  g=T[2];
+  poly h=var(1)-f;
+  while(1)
+  {
+    g=subst(g,var(1),h);
+    k=jet(g,m);
+    if(diff(k,var(1))==0)
+    {
+      break;
+    }
+  }
+  return(k);
+}
+/*
+ring R=0,(x,y,z),ds;
+poly f=x+y2;
+poly g=y3+z4+xy11;
+speciaNF(g,f,6);
+*/
+////////////////////////////////////////////////////////////////////////////////
+static proc linearpart(poly g,poly f)          //   f=linear part+higher,g   output list T,T[1]=x+higher term,T[2]=g
+"USAGE:  specialNF(g,f);  g,f are polynomials
+ASSUME: f=lineat part+higher that is f is of order 1
+RETURN: list T, T[1]=x+higher and T[2]=g'
+{
+  def R=basering;
+  poly i,j,k;
+  list T;
+  i=diff(jet(f,1),var(1));
+  j=diff(jet(f,1),var(2));
+  k=diff(jet(f,1),var(3));
+  if(i!=0)
+  {
+    ideal M=maxideal(1);
+    M[1]=(var(1)-((j*var(2)+k*var(3))/leadcoef(f)))/leadcoef(f);
+    map phi=R,M;
+    f=phi(f);
+    g=phi(g);
+  }
+  if(i==0)
+  {
+    if(j!=0)
+    {
+      map phi=R,var(2),var(1),var(3);
+      f=phi(f);
+      g=phi(g);
+      return(linearpart(g,f));
+    }
+    if(k!=0)
+    {
+      map phi=R,var(3),var(2),var(1);
+      f=phi(f);
+      g=phi(g);
+      return(linearpart(g,f));
+    }
+  }
+  T[1]=f;
+  T[2]=g;
+  return(T);
+}
+/*
+ring R=0,(x,y,z),ds;
+poly f=x+2y+y2;
+poly g=y3+z4+zy11;
+lineatpart(g,f);
+*/
+////////////////////////////////////////////////////////////////////////////////
+static  proc typejet2(poly g1,poly g2)
+"USAGE:  typejet2(g1,g2);  g1,g2 are polynomials
+ASSUME: g1,g2 are homogenous polynomials of degree 2
+PURPOSE: Check whether (g1,g2) is a quadratic form in the list of Guisti or not
+RETURN: string  type for the quadratic forms appearing in Guist's list
+@*       or not simple
+{
+  def R=basering;
+  ideal I=(g1,g2);
+  def S=absPrimdecGTZ(I);
+  setring S;
+  list L,T;
+  int e,i,j;
+  intvec a,a1;
+  L=primary_decomp;
+  for(j=1;j<=size(L);j++)
+  {
+    if(dim(std(L[j][1]))!=2)
+    {
+      return("not simple");
+    }
+  }
+  T=absolute_primes;
+  for(i=1;i<=size(T);i++)
+  {
+    e=e+T[i][2];
+  }
+  if(e==4)
+  {
+    setring R;
+    return("type1");
+  }
+  if(e==3)
+  {
+    setring R;
+    return("type2");
+  }
+  if(e==2)
+  {
+    ideal J=std(L[1][1]);
+    ideal J1=std(L[2][1]);
+    a=hilbPoly(J);
+    a1=hilbPoly(J1);
+    if((a[2]==2)&&(a1[2]==2))
+    {
+      setring R;
+      return("type3");
+    }
+    if(((a[2]==3)&&(a1[2]==1))||((a[2]==1)&&(a1[2]==3)))                      //||(a[2]==1)&&(a1[2]==3))
+    {
+      setring R;
+      return("type4");
+    }
+  }
+  if(e==1)
+  {
+    setring R;             // I lies in R and zero in S1
+    ideal JJ=radical(I);
+    JJ=JJ^3;
+    ideal JJJ=reduce(JJ,std(I));
+    if(size(JJJ)==0)
+    {
+      return("type6");
+    }
+    if(size(JJJ)!=0)
+    {
+      return("type5");
+    }
+  }
+  setring R;
+  return("not simple");
+}
+/*
+ring R=0,(x,y,z),ds;
+poly g1=x2+yz;
+poly g2=xy;
+typejet2(g1,g2);
+*/
+////////////////////////////////////////////////////////////////////////////////
+static proc compL(list L,list M)
+{
+  int l,m,i,j;
+  l=size(L);
+  m=size(M);
+  if(l!=m)
+  {return(0);}
+  for(i=1;i<=m;i++)
+  {
+    if(L[i]!=M[i])
+    {return(0);}
+  }
+  return(1);
+}
+////////////////////////////////////////////////////////////////////////////////
+static proc compLL(list L,list M)
+"USAGE:  compLL(L,M);  L, M are lists
+PURPOSE: Check whether the lists are equal or not
+RETURN: 1 if both lists are equal upto a permutation
+ @*              0 if both are not equal
+{
+  int l,m,i,j,s;
+  l=size(L);
+  m=size(M);
+  if(l!=m)
+  {return(0);}
+  for(i=1;i<=m;i++)
+  {
+    for(j=1;j<=m;j++)
+    {
+      if(compL(L[i],M[j]))
+      {
+        s++;
+        break;
+      }
+    }
+  }
+  if(s==m)
+  {return(1);}
+  if(s!=m)
+  {
+    return(0);
+  }
+}
+/*
+ring R=0,(x,y,z),ds;
+list L=(1),(2,3),(2,5);
+list T=(2,3),(1),(2,5);
+compLL(L,T);
+*/
+////////////////////////////////////////////////////////////////////////////////
+static proc changeType(list L)
+"USAGE:  changeType(L);  L is a list of intvectors
+PURPOSE: Change the list of intvectors to the list of lists
+RETURN: List of lists
+{
+  int i,j;
+  list T;
+  for(i=1;i<=size(L);i++)
+  {
+    list S;
+    for(j=1;j<=size(L[i]);j++)
+    {
+      S[j]=L[i][j];
+    }
+    T[size(T)+1]=S;
+    kill S;
+  }
+  return(T);
+}
+/*
+ring R=0,(x,y,z),ds;
+list B=(4,6,7);
+changeType(B);
+*/
+////////////////////////////////////////////////////////////////////////////////
+static proc genericmilnor(ideal I)
+"USAGE:  genericmilnor(l);  I is an ideal
+PURPOSE: Computes the milnor number of generic linear combination of the ideal I
+RETURN: Milnor number of I if it is finite
+@*       or -1 if it is not finite
+{
+  int m=milnor(I);
+  int i,a,b;
+  if(m>=0)
+  {
+    return(m);
+  }
+  def R=basering;
+  def R1=changechar(32003,R);
+  setring R1;
+  ideal I;
+  while(i<10)
+  {
+    i++;
+    a=random(-100,100);
+    b=random(-100,100);
+    while(a==0)
+    {
+      a=random(-100,100);
+    }
+    while(b==0)
+    {
+      b=random(-100,100);
+    }
+    I=imap(R,I);
+    I[1]=a*I[1]+b*I[2];
+    m=milnor(I);
+    if(m>=0)
+    {
+      setring R;
+      return(m);
+    }
+  }
+  setring R;
+  return(-1);
+}
+/*
+   ring R=0,(x,y,z),ds;
+   ideal I=x2+z3,y2+z3;
+   genericmilnor(I);
+*/
+////////////////////////////////////////////////////////////////////////////////
+proc Semigroup(ideal I)
+"USAGE:  Semigroup(l);  I is an ideal
+PURPOSE: Computes the semigroup of the ideal I corresponding to each branch
+RETURN: list of semigroup of ideal I corresponding to each branch
+EXAMPLE: Semigroup; shows an example
+"
+{
+  list L=facstd(I);
+  list RE,JE,PE;
+  if(size(L)==1)
+  {
+     RE=CurveRes(L[1]);
+     RE=semi_group(RE);
+     return(RE);
+  }
+  ideal J,K;
+  list T,T1,T2,T3,T4,T5,H;
+  int i,j,l;
+  for(i=1;i<=size(L);i++)
+  {
+    RE=CurveRes(radical(L[i])) ;
+    T1[i]=semi_group(RE);
+    for(j=i+1;j<=size(L);j++)
+    {
+      JE=CurveRes(radical(L[j]));
+      T2[j]=semi_group(JE);
+      J=L[i]+L[j];
+      if(dim(std(J))!=1)
+      {
+        break;
+      }
+      K=slocus(J);
+      if(K[1]==1)
+      { T3=1;}
+      else
+      {
+        PE=CurveRes(radical(J));
+        T3=semi_group(PE);
+      }
+      T4=commonpartlists(T1[i],T3);
+      T5=commonpartlists(T2[j],T3);
+      if(compLL(T4,T5))
+      {
+        T1[i]=del(T1[i],T4);
+      }
+    }
+    for(l=1;l<=size(T1[i]);l++)
+    {
+      H[size(H)+1]=T1[i][l];
+    }
+  }
+  return(H);
+}
+example
+{
+  "EXAMPLE:"; echo=2;
+   ring R=0,(x,y,z),ds;
+   ideal I=x2+y3+z5,yz;
+   Semigroup(I);
+}
+////////////////////////////////////////////////////////////////////////////////
+static proc del(list L,list M)
+"USAGE:  del(L,M);  L and M are two lists
+PURPOSE: Delete common part of list M from List L
+RETURN: list L
+{
+  int i,j;
+  for(i=1;i<=size(M);i++)
+  {
+    for(j=1;j<=size(L);j++)
+    {
+      if(compL(L[j],M[i]))
+      {L=delete(L,j);}
+    }
+  }
+  return(L);
+}
+////////////////////////////////////////////////////////////////////////////////
+static proc commonpartlists(list L,list M)
+"USAGE:  commonpart(L,M);  L and M are two lists
+PURPOSE: Computes the intersetion of two list
+RETURN: list T
+{
+   list T;
+   int i,m,l,j,k;
+   m=size(M);
+   l=size(L);
+   if(l>=m)
+   {
+     for(i=1;i<=m;i++)
+     {
+       for(j=1;j<=l;j++)
+       {
+         if(compLL(M[i],L[j]))
+         {
+           T[k+1]=M[i];
+           k++;
+         }
+       }
+     }
+   }
+   return(T);
+}
+////////////////////////////////////////////////////////////////////////////////
+static proc semi_group(list H)
+"USAGE:  semi_group(H);  H list
+COMPUTE:Weierstrass semigroup of space curve C,which is given by an ideal
+RETURN: list A  , which gives generators set of the Weierstrass semigroup corresponding to each irreducible component of C
+{
+   int i,d,u,v,w,k;
+   int j=1;
+   int e=1;
+   def R=basering;
+
+   list A;
+   string mpo;
+   list LL;
+   for(k=1;k<=size(H);k++)
+   {
+     LL=CurveParam(H[k]);
+     def S=LL[1];
+     setring S;
+     list TT;
+     for(i=1;i<=size(Param);i++)
+     {
+       d=deg(Param[i][2]);
+       TT=Param[i];
+       mpo=string(Param[i][2]);
+       ring S1=(0,a),(t),ds;
+       setring S1;
+       execute("minpoly="+mpo+";");
+       list TT=imap(S,TT);
+       list T;
+       ideal J1;
+       for(u=1;u<=size(TT[1]);u++)
+       {
+         J1[u]=TT[1][u];
+       }
+       J1=simplify(J1,2);
+       J1=sagbiAlg(J1);
+       w=Classify_aeq::ConductorBound(J1);
+       J1=lead(J1);
+       list TTT;
+       for(v=1;v<=size(J1);v++)
+       {
+         TTT[v]=J1[v];
+       }
+       for(j=1;j<=d;j++)
+       {
+         T=WSemigroup(TTT,w);
+         A[e]=T[1];       //  intersted only in semigroup
+         e++;
+       }
+       setring S;
+       kill S1;
+       kill T;
+     }
+     setring R;
+     kill S;
+   }
+   return(A);
+}
+//==============================Examples======================================
+/*
+//=========Examples of Isolated simple complete intersection singularities======
+ring R=0,(x,y),ds;
+ideal M=maxideal(1);
+//======================
+ideal I=x2+y3,xy11;
+M[1]=x;
+M[2]=x+3y+xy;
+map phi=R,M;
+I=phi(I);
+classifyicis(I);
+//======================
+ideal I=xy,x5+y4;
+M[1]=x+4y;
+M[2]=y;
+map phi=R,M;
+I=phi(I);
+classifyicis(I);
+//======================
+ideal I=x2,y4;
+M[1]=x+xy2;
+M[2]=x+y+x2+y2;
+map phi=R,M;
+I=phi(I);
+classifyicis(I)
+//===========================================
+ideal I=x2+y11,x2y3+xy4;
+classifyicis(I);
+//======================
+ring S=0,(u,v),dp;
+ideal N=maxideal(1);
+//======================
+ideal J=u2+v7,uv2;
+N[1]=u+3v+uv+u3v;
+N[2]=v;
+map si=S,N;
+J=si(J);
+classifyicis(J);
+//======================
+ideal J=u2+v2+uv5+v11,uv4+v5;
+classifyicis(I);
+//===========================================
+ring R=0,(x,y,z),ds;
+ideal M=maxideal(1);
+//======================
+ideal I=x2+y3+z5,yz;
+classifyicis(I);
+//======================
+ideal I=x2+z3,y2+z3;
+classificis(I);
+//======================
+ideal I=x2+yz+z3,xy;
+M[3]=x+4y+3z+x2y;
+map phi=R,M;
+I=phi(I);
+classifyicis(I);
+//======================
+ideal I=x2+y3+z6,yz+xy3;
+classifyicis(I);
+//============================================
+ideal I=x2+z3,y2+xz;
+M[2]=x+3y;
+map phi=R,M;
+I=phi(I);
+classifyicis(I);
+//============================================
+ring S=0,(u,v,w),ds;
+ideal M=maxideal(1);
+ideal I=u2+vw+w3,uv;
+M[1]=u+3v+3vw+w2;
+ map phi=S,M;
+ I=phi(I);
+classifyicis(I);
+//==========Examples of Semigroup of the space curves====================
+ring R=0,(x,y,z),ds;
+ideal I=xy+z3,xz+z2y2+y6;
+Semigroup(I);
+//======================
+ideal I=xy,xz+z3+z2y3+y11;
+Semigroup(I);
+//======================
+ideal I=xy+z4,xz+y6+yz2;
+Semigroup(I);
+//======================
+ideal I=xy+z2,x2+z2y+5y4;
+Semigroup(I);
+//======================
+ideal I=x2+yz2,y2+z3;
+Semigroup(I);
+//======================
+ideal I=x2+yz,xy+z4;
+Semigroup(I);
+//======================
+ideal I=xy,xz+z3+z2y5+2y15;
+Semigroup(I);
+//======================
+ideal I=xy,xz+z3+zy9;
+Semigroup(I);
+//======================
+*/
diff --git a/Singular/LIB/compregb.lib b/Singular/LIB/compregb.lib
new file mode 100644
index 0000000..25a5224
--- /dev/null
+++ b/Singular/LIB/compregb.lib
@@ -0,0 +1,276 @@
+//////////////////////////////////////////////////////////////////////////////
+version="version compregb.lib 4.0.0.0 Jun_2013 "; // $Id: 95e4c7dacb9b13daa2efb154f66ace0d4fef37dc $
+category="General purpose";
+info="
+LIBRARY:  compregb.lib      experimental implementation for comprehensive Groebner systems
+AUTHOR:  Akira Suzuki (http://kurt.scitec.kobe-u.ac.jp/~sakira/CGBusingGB/)
+                      (<sakira at kobe-u.ac.jp>)
+OVERVIEW:
+see \"A Simple Algorithm to compute Comprehensive Groebner Bases using Groebner
+Bases\" by Akira Suzuki and Yosuke Sato for details.
+
+PROCEDURES:
+  cgs(polys,vars,pars,R1,R2);     comprehensive Groebner systems
+  base2str(G);                    pretty print of the result G
+
+KEYWORDS: comprehensive Groebner system
+";
+///////////////////////////////////////////////////////////////////////////////
+// global variables are the followings:
+// Parameters, Variables, VMinDPoly,
+// RingAll, RingVar;
+
+///////////////////////////////////////////////////////////////////////////////
+static proc setup_special_dpolys()
+{
+  poly VMinDPoly = Variables[size(Variables)];
+  export(VMinDPoly);
+}
+
+static proc newcasebasis(poly Case, ideal Basis)
+{
+  list CB = Case, Basis;
+  return(CB);
+}
+
+static proc contains(poly Vari, list Varis)
+{
+  int l = size(Varis);
+  for (int i = 1; i <= l; i ++)
+  {
+    if (Vari == Varis[i])
+    {
+      return(1);
+    }
+  }
+
+  return(0);
+}
+
+static proc polys_heads(list PolyL)
+{
+  int i, j;
+  int length = size(PolyL);
+  if (!length)
+  {
+    return(PolyL);
+  }
+
+  setring(RingVar);
+  list PolyL = imap(RingAll, PolyL);
+  list HCoefs = list();
+  length = size(PolyL);
+  for (i = 1; i <= length; i ++)
+  {
+    HCoefs = insert(HCoefs, leadcoef(PolyL[i]));
+  }
+  setring(RingAll);
+  list HCoefs = imap(RingVar, HCoefs);
+
+  list CoefL;
+  ideal CoefLsub;
+  poly Coef;
+  for (i = 1; i <= length; i ++)
+  {
+    Coef = HCoefs[i];
+    if (typeof(Coef) == "poly")
+    {
+      CoefLsub = factorize(Coef, 1);
+      for (j = 1; j <= size(CoefLsub); j ++)
+      {
+        if (CoefLsub[j] > 1)
+        {
+          CoefL = insert(CoefL, CoefLsub[j]);
+        }
+      }
+    }
+  }
+
+  for (i = 1; i <= size(CoefL); i ++)
+  {
+    Coef = CoefL[i];
+    for (j = i + 1; j <= size(CoefL); j ++)
+    {
+      if (Coef == CoefL[j])
+      {
+        CoefL = delete(CoefL, j);
+        j --;
+      }
+    }
+  }
+
+  return(CoefL);
+}
+
+static proc polys_restrict_v(ideal Polys)
+{
+  return(polys_separate_v_p(Polys)[0]);
+}
+
+static proc polys_restrict_p(ideal Polys)
+{
+  return(polys_separate_v_p(Polys)[1]);
+}
+
+static proc polys_separate_v_p(ideal Polys)
+{
+  list R_v, R_p;
+  poly P;
+  int length = size(Polys);
+
+  for (int i = 1; i <= length; i ++)
+  {
+    P = Polys[i];
+    if (P < VMinDPoly)
+    {
+      R_p = insert(R_p, P);
+    }
+    else
+    {
+      R_v = insert(R_v, P);
+    }
+  }
+
+  return(R_v, R_p);
+}
+
+static proc cgs_main(ideal Polys)
+{
+  ideal F;
+  list FP, FV, HFact, Bases;
+  poly H;
+  int i;
+
+//    F = groebner(Polys);
+  F = slimgb(Polys);
+
+  if (F[1] == 1)
+  {
+    return(list());
+  }
+
+  FV, FP = polys_separate_v_p(F);
+
+  HFact = polys_heads(FV);
+  int HFL = size(HFact);
+
+  H = 1;
+  for (i = 1; i <= HFL; i ++)
+  {
+    H = H * HFact[i];
+  }
+
+  Bases = insert(Bases, list(H, F));
+
+  for (i = 1; i <= HFL; i ++)
+  {
+    //    print("paras:" + string(FP));
+    //    print("ideal:" + string(HFact[i]));
+    Bases = cgs_main(F + ideal(HFact[i])) + Bases;
+  }
+
+  return(Bases);
+}
+
+proc cgs(ideal Polys, list Vars, list Paras,def RingVar,def RingAll)
+"USAGE: cgs(Polys,Vars,Paras,RingVar,RingAll); Polys an ideal, Vars, the list
+        of variables, Paras the list of parameters, RingVar the ring with
+        Paras as parameters, RingAll the ring with Paras as variables
+        (RingAll should be the current ring)
+RETURN: a list L of lists L[i] of a polynomial and an ideal:
+        L[i][1] the polynomial giving the condition on the parameters
+        L[i][2] the Groebner basis for this case
+EXAMPLE: example cgs; shows an example
+"
+{
+  option(redSB);
+  list Parameters = Paras;
+  list Variables = Vars;
+  poly VMinDPoly = Vars[size(Vars)];
+  export(Parameters, Variables, VMinDPoly);
+
+  export(RingVar, RingAll);
+  setring(RingAll);
+
+  list G = cgs_main(Polys);
+
+  keepring(RingAll);
+  return(G);
+}
+example
+{ "EXAMPLE:";echo=2;
+  ring RingVar=(0,a,b),(x,y,t),lp;
+  ring RingAll=0,(x,y,t,a,b),(lp(3),dp);
+  ideal polys=x^3-a,y^4-b,x+y-t;
+  list vars=x,y,t;
+  list paras=a,b;
+  list G = cgs(polys,vars,paras,RingVar,RingAll);
+  G;
+}
+proc basis2str(list B)
+{
+  string Str;
+  ideal Factors;
+  int i;
+
+  Str = "(";
+  Factors = factorize(B[1], 1);
+  for (i = 1; i <= size(Factors); i ++)
+  {
+    Str = Str + "(" + string(Factors[i]) + ")";
+  }
+  Str = Str + "!=0,";
+
+  list FV, FP;
+  FV, FP = polys_separate_v_p(B[2]);
+  for (i = 1; i <= size(FP); i ++)
+  {
+    Str = Str + string(FP[i]) + "=0,";
+  }
+
+  if (size(Str) > 1)
+  {
+    Str = Str[1, size(Str) - 1] + ")[";
+  }
+  else
+  {
+    Str = "()[";
+  }
+
+  if (size(FV))
+  {
+    for (i = 1; i <= size(FV); i ++)
+    {
+      Str = Str + string(FV[i]) + ",";
+    }
+
+    Str = Str[1, size(Str) - 1] + "]";
+  }
+  else
+  {
+    Str += "]";
+  }
+
+  return(Str);
+}
+
+proc bases2str(list Bases)
+{
+  string Str;
+  int i;
+
+  Str = "";
+  for (i = 1; i <= size(Bases); i ++)
+  {
+    Str = Str + basis2str(Bases[i]) + newline;
+  }
+
+  return(Str);
+}
+
+/*
+ring RingVar=(0,a,b),(x,y,t),lp; ring RingAll=0,(x,y,t,a,b),(lp(3),dp);
+ideal polys=x^3-a,y^4-b,x+y-t; list vars=x,y,t; list paras=a,b;
+list G = cgs(polys,vars,paras,RingVar,RingAll);
+bases2str(G);
+*/
diff --git a/Singular/LIB/control.lib b/Singular/LIB/control.lib
new file mode 100644
index 0000000..fb2c782
--- /dev/null
+++ b/Singular/LIB/control.lib
@@ -0,0 +1,1638 @@
+/////////////////////////////////////////////////////////////////////////
+version="version control.lib 4.0.0.0 Jun_2013 "; // $Id: 018a6cff8b41a26f7eb46724ad9d483956bfb9aa $
+category="System and Control Theory";
+info="
+LIBRARY:  control.lib     Algebraic analysis tools for System and Control Theory
+
+AUTHORS:  Oleksandr Iena,       yena at mathematik.uni-kl.de
+@*        Markus Becker,        mbecker at mathematik.uni-kl.de
+@*        Viktor Levandovskyy,  levandov at mathematik.uni-kl.de
+
+SUPPORT: Forschungsschwerpunkt 'Mathematik und Praxis' (Project of Dr. E. Zerz
+and V. Levandovskyy), University of Kaiserslautern
+
+PROCEDURES:
+  control(R);     analysis of controllability-related properties of R (using Ext modules)
+  controlDim(R);  analysis of controllability-related properties of R (using dimension)
+  autonom(R);     analysis of autonomy-related properties of R (using Ext modules)
+  autonomDim(R);  analysis of autonomy-related properties of R (using dimension)
+
+  leftKernel(R);       a left kernel of R
+  rightKernel(R);      a right kernel of R
+  leftInverse(R);      a left inverse of R
+  rightInverse(R);     a right inverse of R
+  colrank(M);          a column rank of M as of matrix
+  genericity(M);       analysis of the genericity of parameters
+  canonize(L);         Groebnerification for modules in the output of control or autonomy procs
+  iostruct(R);         computes an IO-structure of behavior given by a module R
+  findTorsion(R, I);   generators of the submodule of a module R, annihilated by the ideal I
+
+  controlExample(s);   set up an example from the mini database inside of the library
+  view();              well-formatted output of lists, modules and matrices
+";
+
+LIB "homolog.lib";
+LIB "poly.lib";
+LIB "primdec.lib";
+LIB "matrix.lib";
+
+//---------------------------------------------------------------
+static proc Opt_Our()
+"USAGE: Opt_Our();
+RETURN: intvec, where previous options are stored
+PURPOSE: save previous options and set customized options
+"
+{
+  intvec v;
+  v=option(get);
+  option(redSB);
+  option(redTail);
+  return (v);
+}
+
+//-------------------------------------------------------------------------
+
+static proc space(int n)
+"USAGE:spase(n); n is an integer (number of needed spaces)
+RETURN:  string consisting of n spaces
+NOTE:  the procedure is used in the procedure 'view' to have a better formatted output
+"{
+  int i;
+  string s="";
+  for(i=1;i<=n;i++)
+  {
+    s=s+" ";
+  }
+  return(s);
+}
+//-----------------------------------------------------------------------------
+proc view(def M)
+"USAGE:  view(M);   M is of any type
+RETURN:  no return value
+PURPOSE:  procedure for (well-) formatted output of modules, matrices, lists of modules, matrices; shows everything even if entries are long
+NOTE:  in case of other types( not 'module', 'matrix', 'list') works just as standard 'print' procedure
+EXAMPLE:  example view; shows an example
+"
+{
+  // to be replaced with something more feasible
+  if ( (typeof(M)=="module")||(typeof(M)=="matrix") )
+  {
+    int @R=nrows(M);
+    int @C=ncols(M);
+    int i;
+    int j;
+    list MaxLength=list();
+    int Size=0;
+    int max;
+    string s;
+
+    for(i=1;i<=@C;i++)
+    {
+      max=0;
+      for(j=1;j<=@R;j++)
+      {
+        Size=size( string( M[j,i] ) );
+        if( Size>max )
+        {
+          max=Size;
+        }
+      }
+      MaxLength[i] = max;
+    }
+    for(i=1;i<=@R;i++)
+    {
+      s="";
+      for(j=1;j<@C;j++)
+      {
+        s=s+string(M[i,j])+space( MaxLength[j]-size( string( M[i,j] ) ) ) +",";
+      }
+      s=s+string(M[i,j])+space( MaxLength[j]-size( string( M[i,j] ) ) );
+      if (i!=@R)
+      {
+        s=s+",";
+      }
+      print(s);
+    }
+    return();
+  }
+  if(typeof(M)=="list")
+  {
+    int sz=size(M);
+    int i;
+    for(i=1;i<=sz;i++)
+    {
+      view(M[i]);
+      print("");
+    }
+    return();
+  }
+  print(M);
+  return();
+}
+example
+{"EXAMPLE:";echo = 2;
+  ring r;
+  list L;
+  matrix M[1][3] = x2+x,y3-y,z5-4z+7;
+  L[1] = "a matrix:";
+  L[2] = M;
+  L[3] = "an ideal:";
+  L[4] = ideal(M);
+  view(L);
+}
+//--------------------------------------------------------------------------
+proc rightKernel(matrix M)
+"USAGE:  rightKernel(M);   M a matrix
+RETURN:  module
+PURPOSE: computes the right kernel of matrix M (a module of all elements v such that Mv=0)
+EXAMPLE: example rightKernel; shows an example
+"{
+  return(modulo(M,std(0)));
+}
+example
+{"EXAMPLE:";echo = 2;
+  ring r = 0,(x,y,z),dp;
+  matrix M[1][3] = x,y,z;
+  print(M);
+  matrix R = rightKernel(M);
+  print(R);
+  // check:
+  print(M*R);
+}
+//-------------------------------------------------------------------------
+proc leftKernel(matrix M)
+"USAGE:  leftKernel(M);   M a matrix
+RETURN:  module
+PURPOSE: computes left kernel of matrix M (a module of all elements v such that vM=0)
+EXAMPLE:  example leftKernel; shows an example
+"
+{
+  return( transpose( modulo( transpose(M),std(0) ) ) );
+}
+example
+{"EXAMPLE:";echo = 2;
+  ring r= 0,(x,y,z),dp;
+  matrix M[3][1] = x,y,z;
+  print(M);
+  matrix L = leftKernel(M);
+  print(L);
+  // check:
+  print(L*M);
+}
+//------------------------------------------------------------------------
+proc leftInverse(module M)
+"USAGE:  leftInverse(M);  M a module
+RETURN:  module
+PURPOSE: computes such a matrix L, that LM = Id;
+EXAMPLE: example leftInverse; shows an example
+NOTE: exists only in the case when M is free submodule
+"
+{
+  // it works also for the NC case;
+  int NCols = ncols(M);
+  module Id = freemodule(NCols);
+  module N  = transpose(M);
+  intvec old_opt=Opt_Our();
+  Id = std(Id);
+  matrix T;
+  // check the correctness (Id \subseteq M)
+  // via dimension: dim (M) = -1!
+  int d = dim_Our(N);
+  if (d != -1)
+  {
+    // No left inverse exists
+    return(matrix(0));
+  }
+  matrix T2 = lift(N, Id);
+  T2 =  transpose(T2);
+  option(set,old_opt);  // set the options back
+  return(T2);
+}
+example
+{
+  "EXAMPLE:";echo =2;
+  // a trivial example:
+  ring r = 0,(x,z),dp;
+  matrix M[2][1] = 1,x2z;
+  print(M);
+  print( leftInverse(M) );
+  kill r;
+  // derived from the example TwoPendula:
+  ring r=(0,m1,m2,M,g,L1,L2),Dt,dp;
+  matrix U[3][1];
+  U[1,1]=(-L2)*Dt^4+(g)*Dt^2;
+  U[2,1]=(-L1)*Dt^4+(g)*Dt^2;
+  U[3,1]=(L1*L2)*Dt^4+(-g*L1-g*L2)*Dt^2+(g^2);
+  module M = module(U);
+  module L = leftInverse(M);
+  print(L);
+  // check
+  print(L*M);
+}
+//-----------------------------------------------------------------------
+proc rightInverse(module R)
+"USAGE:  rightInverse(M);  M a module
+RETURN:  module
+PURPOSE: computes such a matrix L, that ML = Id
+EXAMPLE: example rightInverse; shows an example
+NOTE: exists only in the case when M is free submodule
+"
+{
+  // for comm case it suffices
+  if (isCommutative())
+  {
+    return(transpose(leftInverse(transpose(R))));
+  }
+  // for noncomm
+  def save = basering; def sop = opposite(save);
+  setring sop; module Mop = oppose(save,R);
+  Mop = transpose(Mop);
+  module L = leftInverse(Mop);
+  setring save; module L = oppose(sop,L);
+  L = transpose(L);
+  return(matrix(L));
+}
+example
+{ "EXAMPLE:";echo =2;
+  // a trivial example:
+  ring r = 0,(x,z),dp;
+  matrix M[1][2] = 1,x2+z;
+  print(M);
+  print( rightInverse(M) );
+  kill r;
+  // derived from the TwoPendula example:
+  ring r=(0,m1,m2,M,g,L1,L2),Dt,dp;
+  matrix U[1][3];
+  U[1,1]=(-L2)*Dt^4+(g)*Dt^2;
+  U[1,2]=(-L1)*Dt^4+(g)*Dt^2;
+  U[1,3]=(L1*L2)*Dt^4+(-g*L1-g*L2)*Dt^2+(g^2);
+  module M = module(U);
+  module L = rightInverse(M);
+  print(L);
+  // check
+  print(M*L);
+}
+//-----------------------------------------------------------------------
+static proc dim_Our(module R)
+{
+  int d;
+  if (attrib(R,"isSB")<>1)
+  {
+    R = std(R);
+  }
+  d = dim(R);
+  return(d);
+}
+//-----------------------------------------------------------------------
+static proc Ann_Our(module R)
+{
+  return(Ann(R));
+}
+//-----------------------------------------------------------------------
+static proc Ext_Our(int i, module R, list #)
+{
+  // mimicking 'Ext_R' from homolog.lib
+  int ExtraArg = ( size(#)>0 );
+  if (ExtraArg)
+  {
+    return( Ext_R(i,R,#[1]) );
+  }
+  else
+  {
+    return( Ext_R(i,R) );
+  }
+}
+//------------------------------------------------------------------------
+static proc is_zero_Our
+{
+  //just a copy of 'is_zero' from "poly.lib" patched with GKdim
+  int d = dim_Our(std(#[1]));
+  int a = ( d==-1 );
+  if( size(#) >1 ) { list L=a,d; return(L); }
+  return(a);
+  //  return( is_zero(R) ) ;
+}
+//------------------------------------------------------------------------
+static proc control_output(int i, int NVars, module R, module Ext_1, list Gen)
+"USAGE:  control_output(i, NVars, R, Ext_1),
+PURPOSE: where
+@*         i is integer (number of first nonzero Ext or a number of variables in a basering + 1 in case that all the Exts are zero),
+@*           NVars:  integer, number of variables in a base ring,
+@*           R:  module R (cokernel representation),
+@*           Ext_1:  module, the first Ext(its cokernel representation)
+RETURN:  list with all the contollability properties of the system which is to be returned in 'control' procedure
+NOTE:  this procedure is used in 'control' procedure
+"{
+  // TODO: NVars to be replaced with the global hom. dimension of basering!!!
+  // Is not clear what to do with gl.dim of qrings
+  string DofS = "dimension of the system:";
+  string Fn   = "number of first nonzero Ext:";
+  string Gen_mes = "Parameter constellations which might lead to a non-controllable system:";
+
+  module RK = rightKernel(R);
+  int d=dim_Our(std(transpose(R)));
+
+  if (i==1)
+  {
+    return(
+            list ( Fn,
+                   i,
+                  "not controllable , image representation for controllable part:",
+                    RK,
+                  "kernel representation for controllable part:",
+                   leftKernel( RK ),
+                  "obstruction to controllability",
+                   Ext_1,
+                  "annihilator of torsion module (of obstruction to controllability)",
+                   Ann_Our(Ext_1),
+                   DofS,
+                   d
+                 )
+          );
+  }
+
+  if(i>NVars)
+  {
+    return( list(  Fn,
+                   -1,
+                  "strongly controllable(flat), image representation:",
+                   RK,
+                  "left inverse to image representation:",
+                   leftInverse(RK),
+                   DofS,
+                   d,
+                   Gen_mes,
+                   Gen)
+          );
+  }
+
+  //
+  //now i<=NVars
+  //
+
+  if( (i==2) )
+  {
+    return( list( Fn,
+                  i,
+                 "controllable, not reflexive, image representation:",
+                  RK,
+                  DofS,
+                  d,
+                  Gen_mes,
+                  Gen)
+          );
+  }
+
+  if( (i>=3) )
+  {
+    return( list ( Fn,
+                   i,
+                  "reflexive, not strongly controllable, image representation:",
+                   RK,
+                   DofS,
+                   d,
+                      Gen_mes,
+                   Gen)
+          );
+  }
+}
+//-------------------------------------------------------------------------
+
+proc control(module R)
+"USAGE:  control(R);  R a module (R is the matrix of the system of equations to be investigated)
+RETURN:  list
+PURPOSE: compute the list of all the properties concerning controllability of the system (behavior), represented by the matrix R
+NOTE: the properties and corresponding data like controllability, flatness, dimension of the system, degree of controllability, kernel and image representations, genericity of parameters, obstructions to controllability, annihilator of torsion submodule and left inverse are investigated
+EXAMPLE:  example control; shows an example
+"
+{
+  int i;
+  int NVars=nvars(basering);
+  // TODO: NVars to be replaced with the global hom. dimension of basering!!!
+  int ExtIsZero;
+  intvec v=Opt_Our();
+  module R_std=std(R);
+  module Ext_1 = std(Ext_Our(1,R_std));
+
+  ExtIsZero=is_zero_Our(Ext_1);
+  i=1;
+  while( (ExtIsZero) && (i<=NVars) )
+  {
+    i++;
+    ExtIsZero = is_zero_Our( Ext_Our(i,R_std) );
+  }
+  matrix T=lift(R,R_std);
+  list l=genericity(T);
+  option(set,v);
+
+  return( control_output( i, NVars, R, Ext_1, l ) );
+}
+example
+{"EXAMPLE:";echo = 2;
+  // a WindTunnel example
+  ring A = (0,a, omega, zeta, k),(D1, delta),dp;
+  module R;
+  R = [D1+a, -k*a*delta, 0, 0],
+      [0, D1, -1, 0],
+      [0, omega^2, D1+2*zeta*omega, -omega^2];
+  R=transpose(R);
+  view(R);
+  view(control(R));
+}
+//--------------------------------------------------------------------------
+proc controlDim(module R)
+"USAGE:  controlDim(R); R a module (R is the matrix of the system of equations to be investigated)
+RETURN: list
+PURPOSE: computes list of all the properties concerning controllability of the system (behavior), represented by the  matrix R
+EXAMPLE:  example controlDim; shows an example
+NOTE: the properties and corresponding data like controllability, flatness, dimension of the system, degree of controllability, kernel and image representations, genericity of parameters, obstructions to controllability, annihilator of torsion submodule and left inverse are investigated.
+@* This procedure is analogous to 'control' but uses dimension calculations.
+@* The implemented approach works for full row rank matrices only (the check is done automatically).
+"
+{
+  if( nrows(R) != colrank(transpose(R)) )
+  {
+    return ("controlDim cannot be applied, since R does not have full row rank");
+  }
+  intvec     v = Opt_Our();
+  module R_std = std(R);
+  int        d = dim_Our(R_std);
+  int    NVars = nvars(basering);
+  int        i = NVars-d;
+  module Ext_1 = std(Ext_Our(1,R_std));
+  matrix     T = lift(R,R_std);
+  list       l = genericity(T);
+  option(set, v);
+  return( control_output( i, NVars, R, Ext_1, l));
+}
+example
+{"EXAMPLE:";echo = 2;
+  //a WindTunnel example
+  ring A = (0,a, omega, zeta, k),(D1, delta),dp;
+  module R;
+  R = [D1+a, -k*a*delta, 0, 0],
+      [0, D1, -1, 0],
+      [0, omega^2, D1+2*zeta*omega, -omega^2];
+  R=transpose(R);
+  view(R);
+  view(controlDim(R));
+}
+//------------------------------------------------------------------------
+proc colrank(module M)
+"USAGE: colrank(M); M a matrix/module
+RETURN: int
+PURPOSE: compute the column rank of M as of matrix
+NOTE: this procedure uses Bareiss algorithm
+"{
+  // NOte continued:
+  // which might not terminate in some cases
+  module M_red  = bareiss(M)[1];
+  int NCols_red = ncols(M_red);
+  return (NCols_red);
+}
+example
+{"EXAMPLE: ";echo = 2;
+  // de Rham complex
+  ring r=0,(D(1..3)),dp;
+  module R;
+  R=[0,-D(3),D(2)],
+    [D(3),0,-D(1)],
+    [-D(2),D(1),0];
+  R=transpose(R);
+  colrank(R);
+}
+
+//------------------------------------------------------------------------
+static proc autonom_output( int i, int NVars, module RC, int R_rank )
+"USAGE:  proc autonom_output(i, NVars, RC, R_rank)
+           i:  integer, number of first nonzero Ext or
+               just number of variables in a base ring + 1 in case that all the Exts are zero
+           NVars:  integer, number of variables in a base ring
+           RC: module, kernel-representation of controllable part of the system
+           R_rank: integer, column rank of the representation matrix
+PURPOSE: compute all the autonomy properties of the system which is to be returned in 'autonom' procedure
+RETURN:  list
+NOTE:  this procedure is used in 'autonom' procedure
+"
+{
+  int d=NVars-i;//that is the dimension of the system
+  string DofS="dimension of the system:";
+  string Fn = "number of first nonzero Ext:";
+  if(i==0)
+  {
+    return( list(  Fn,
+                   i,
+                  "not autonomous",
+                   "kernel representation for controllable part",
+                   RC,
+                   "column rank of the matrix",
+                   R_rank,
+                   DofS,
+                   d )
+          );
+  }
+
+  if( i>NVars )
+  {
+    return( list( Fn,
+                  -1,
+                  "trivial",
+                  DofS,
+                  d )
+          );
+  }
+
+  //
+  //now i<=NVars
+  //
+
+
+  if( i==1 )
+  // in case that NVars==1 there is no sense to consider the notion
+  // of strongly autonomous behavior, because it does not imply
+  // that system is overdetermined in this case
+  {
+    return( list ( Fn,
+                   i,
+                  "autonomous, not overdetermined",
+                   DofS,
+                   d )
+          );
+  }
+
+  if( i==NVars )
+  {
+    return( list(  Fn,
+                   i,
+                  "strongly autonomous(fin. dimensional),in particular overdetermined",
+                   DofS,
+                   d)
+          );
+  }
+
+  if( i<NVars )
+  {
+    return( list ( Fn,
+                   i,
+                  "overdetermined, not strongly autonomous",
+                   DofS,
+                   d)
+          );
+  }
+}
+//--------------------------------------------------------------------------
+proc autonomDim(module R)
+"USAGE:  autonomDim(R);   R a module (R is a matrix of the system of equations which is to be investigated)
+RETURN: list
+PURPOSE: computes the list of all the properties concerning autonomy of the system (behavior), represented by the matrix R
+NOTE: the properties and corresponding data like autonomy resp. strong autonomy, dimension of the system, autonomy degree, kernel representation and (over)determinacy are investigated.
+@* This procedure is analogous to 'autonom' but uses dimension calculations
+EXAMPLE:  example autonomDim; shows an example
+"
+{
+  int d;
+  int NVars  = nvars(basering);
+  module RT  = transpose(R);
+  module RC;  //for computation of controllable part if if exists
+  int R_rank = ncols(R);
+  d          = dim_Our( std(RT) );  //this is the dimension of the system
+  int      i = NVars-d;  //First non-zero Ext
+  if( d==0 )
+    {
+      RC = leftKernel(rightKernel(R));
+      R_rank=colrank(R);
+    }
+  return( autonom_output(i,NVars,RC,R_rank) );
+}
+example
+{"EXAMPLE:"; echo = 2;
+  // Cauchy1 example
+  ring r=0,(s1,s2,s3,s4),dp;
+  module R= [s1,-s2],
+            [s2, s1],
+            [s3,-s4],
+            [s4, s3];
+  R=transpose(R);
+  view( R );
+  view( autonomDim(R) );
+}
+//----------------------------------------------------------
+proc autonom(module R)
+"USAGE:  autonom(R);   R a module (R is a matrix of the system of equations which is to be investigated)
+RETURN:  list
+PURPOSE: find all the properties concerning autonomy of the system (behavior) represented by the  matrix R
+NOTE: the properties and corresponding data like autonomy resp. strong autonomy, dimension of the system, autonomy degree, kernel representation and (over)determinacy are investigated
+EXAMPLE: example autonom; shows an example
+"
+{
+  int NVars=nvars(basering);
+  int ExtIsZero;
+  module RT=transpose(R);
+  module RC;
+  int R_rank=ncols(R);
+  ExtIsZero=is_zero_Our(Ext_Our(0,RT));
+  int i=0;
+  while( (ExtIsZero)&&(i<=NVars) )
+  {
+    i++;
+    ExtIsZero = is_zero_Our(Ext_Our(i,RT));
+  }
+  if (i==0)
+  {
+    RC = leftKernel(rightKernel(R));
+    R_rank=colrank(R);
+  }
+  return(autonom_output(i,NVars,RC,R_rank));
+}
+example
+{"EXAMPLE:"; echo = 2;
+  // Cauchy
+  ring r=0,(s1,s2,s3,s4),dp;
+  module R= [s1,-s2],
+            [s2, s1],
+            [s3,-s4],
+            [s4, s3];
+  R=transpose(R);
+  view( R );
+  view( autonom(R) );
+}
+
+
+//----------------------------------------------------------
+proc genericity(matrix M)
+"USAGE:  genericity(M); M is a matrix/module
+RETURN:  list (of strings)
+PURPOSE: determine parametric expressions which have been assumed to be non-zero in the process of computing the Groebner basis
+NOTE: the output list consists of strings. The first string contains the variables only, whereas each further string contains
+      a single polynomial in parameters.
+@* We strongly recommend to switch on the redSB and redTail options.
+@* The procedure is effective with the lift procedure for modules with parameters
+EXAMPLE:  example genericity; shows an example
+"
+{
+  // returns "-", if there are no parameters!
+  if (npars(basering)==0)
+  {
+    return("-");
+  }
+  list RT = evas_genericity(M); // list of strings
+  if ((size(RT)==1) && (RT[1] == ""))
+  {
+    return("-");
+  }
+  return(RT);
+}
+example
+{  // TwoPendula
+  "EXAMPLE:"; echo = 2;
+  ring r=(0,m1,m2,M,g,L1,L2),Dt,dp;
+  module RR =
+    [m1*L1*Dt^2, m2*L2*Dt^2, -1, (M+m1+m2)*Dt^2],
+    [m1*L1^2*Dt^2-m1*L1*g, 0, 0, m1*L1*Dt^2],
+    [0, m2*L2^2*Dt^2-m2*L2*g, 0, m2*L2*Dt^2];
+  module R = transpose(RR);
+  module SR = std(R);
+  matrix T = lift(R,SR);
+  genericity(T);
+  //-- The result might be different when computing reduced bases:
+  matrix T2;
+  option(redSB);
+  option(redTail);
+  module SR2 = std(R);
+  T2 =  lift(R,SR2);
+  genericity(T2);
+}
+//---------------------------------------------------------------
+static proc victors_genericity(matrix M)
+{
+  // returns "-", if there are no parameters!
+  if (npars(basering)==0)
+  {
+    return("-");
+  }
+  int plevel = printlevel-voice+2;
+  // M is a matrix over a ring with params and vars;
+  ideal I = ideal(M); // a list of entries
+  I = simplify(I,2); // delete 0's
+  // decompose every coeff in every poly
+  int i;
+  int s = size(I);
+  ideal NM;
+  poly p;
+  number num;
+  int  cl=1;
+  intvec ZeroVec; ZeroVec[nvars(basering)] = 0;
+  intvec W;
+  ideal Numero, Denomiro;
+  int cNu=0; int cDe=0;
+  for (i=1; i<=s; i++)
+  {
+    // remove contents and add them as polys
+    p   = I[i];
+    W   = leadexp(p);
+    if (W == ZeroVec) // i.e. just a coef
+    {
+      num    = denominator(leadcoef(p)); // from poly.lib
+      NM[cl] = numerator(leadcoef(p));
+      dbprint(p,"numerator:");
+      dbprint(p, string(NM[cl]));
+      cNu++; Numero[cNu]= NM[cl];
+      cl++;
+      NM[cl] = num; // denominator
+      dbprint(p,"denominator:");
+      dbprint(p, string(NM[cl]));
+      cDe++; Denomiro[cDe]= NM[cl];
+      cl++;
+      p = p - lead(p); // for the next cycle
+    }
+    if ( p!= 0)
+    {
+      num = content(p);
+      p   = p/num;
+      NM[cl] = denominator(num);
+      dbprint(p,"content denominator:");
+      dbprint(p, string(NM[cl]));
+      cNu++; Numero[cNu]= NM[cl];
+      cl++;
+      NM[cl] = numerator(num);
+      dbprint(p,"content numerator:");
+      dbprint(p, string(NM[cl]));
+      cDe++; Denomiro[cDe]= NM[cl];
+      cl++;
+    }
+    // it seems that the next elements will not have real influence
+    while( p != 0)
+    {
+      NM[cl] = leadcoef(p); // should be all integer, i.e. non-rational
+      dbprint(p,"coef:");
+      dbprint(p, string(NM[cl]));
+      cl++;
+      p = p - lead(p);
+    }
+  }
+  NM = simplify(NM,4); // delete identical
+  string newvars = parstr(basering);
+  def save = basering;
+  string NewRing = "ring @NR =" +string(char(basering))+",("+newvars+"),Dp;";
+  execute(NewRing);
+  // get params as variables
+  // create a list of non-monomials
+  ideal @L;
+  ideal F;
+  ideal NM = imap(save,NM);
+  NM = simplify(NM,8); //delete multiples
+  poly p,q;
+  cl = 1;
+  int j, cf;
+  for(i=1; i<=size(NM);i++)
+  {
+    p = NM[i] - lead(NM[i]);
+    if (p!=0)
+    {
+      //      L[cl] = p;
+      F  = factorize(NM[i],1); //non-constant factors only
+      cf = 1;
+      // factorize every polynomial
+      // throw away every monomial from factorization (also constants from above ring)
+      for (j=1; j<=size(F);j++)
+      {
+        q = F[j]-lead(F[j]);
+        if (q!=0)
+        {
+          @L[cl] = F[j];
+          cl++;
+        }
+      }
+    }
+  }
+  // return the result [in string-format]
+  @L = simplify(@L,2+4+8); // skip zeroes, doubled and entries, diff. by a constant
+  list SL;
+  for (j=1; j<=size(@L);j++)
+  {
+    SL[j] = string(@L[j]);
+  }
+  setring save;
+  return(SL);
+}
+//---------------------------------------------------------------
+static proc evas_genericity(matrix M)
+{
+  // called from the main genericity proc
+  ideal I = ideal(M);
+  I = simplify(I,2+4);
+  int s = ncols(I);
+  ideal Den;
+  poly p;
+  int i;
+  for (i=1; i<=s; i++)
+  {
+    p = I[i];
+    while (p !=0)
+    {
+      Den = Den, denominator(leadcoef(p));
+      p   = p-lead(p);
+    }
+  }
+  Den = simplify(Den,2+4);
+  string newvars = parstr(basering);
+  def save = basering;
+  string NewRing = "ring @NR =(" +string(char(basering))+"),("+newvars+"),Dp;";
+  execute(NewRing);
+  ideal F;
+  ideal Den = imap(save,Den);
+  Den = simplify(Den,2);
+  int s1 = ncols(Den);
+  for (i=1; i<=s1; i++)
+  {
+    Den[i] = normalize(Den[i]);
+    if ( Den[i] !=1)
+    {
+      F= F, factorize(Den[i],1);
+    }
+  }
+  F = simplify(F, 2+4+8);
+  ideal @L = F;
+  @L = simplify(@L,2);
+  list SL;
+  int c,j;
+  string Mono;
+  c = 1;
+  for (j=1; j<= ncols(@L);j++)
+  {
+    if (leadcoef(@L[j]) <0)
+    {
+      @L[j] = -1*@L[j];
+    }
+    if (((@L[j] - lead(@L[j]))==0 ) && (@L[j]!=0) ) //@L[j] is a monomial
+    {
+      Mono = Mono + string(@L[j])+ ","; // concatenation
+    }
+    else
+    {
+      c++;
+      SL[c] = string(@L[j]);
+    }
+  }
+  if (Mono!="")
+  {
+    Mono = Mono[1..size(Mono)-1]; // delete the last colon
+  }
+  SL[1] = Mono;
+  setring save;
+  return(SL);
+}
+
+//---------------------------------------------------------------
+proc canonize(list L)
+"USAGE:  canonize(L); L a list
+RETURN:  list
+PURPOSE: modules in the list are canonized by computing their reduced minimal (= unique up to constant factor w.r.t. the given ordering) Groebner bases
+ASSUME:  L is the output of control/autonomy procedures
+EXAMPLE:  example canonize; shows an example
+"
+{
+  list M = L;
+  intvec v=Opt_Our();
+  int s = size(L);
+  int i;
+  for (i=2; i<=s; i=i+2)
+  {
+    if (typeof(M[i])=="module")
+    {
+      M[i] = std(M[i]);
+      //      M[i] = prune(M[i]); // mimimal embedding: no need yet
+      //      M[i] = std(M[i]);
+    }
+  }
+  option(set, v); //set old values back
+  return(M);
+}
+example
+{  // TwoPendula with L1=L2=L
+  "EXAMPLE:"; echo = 2;
+  ring r=(0,m1,m2,M,g,L),Dt,dp;
+  module RR =
+    [m1*L*Dt^2, m2*L*Dt^2, -1, (M+m1+m2)*Dt^2],
+    [m1*L^2*Dt^2-m1*L*g, 0, 0, m1*L*Dt^2],
+    [0, m2*L^2*Dt^2-m2*L*g, 0, m2*L*Dt^2];
+  module R = transpose(RR);
+  list C = control(R);
+  list CC = canonize(C);
+  view(CC);
+}
+
+//----------------------------------------------------------------
+
+static proc elementof (int i, intvec v)
+{
+  int b=0;
+  for(int j=1;j<=nrows(v);j++)
+    {
+      if(v[j]==i)
+        {
+          b=1;
+          return (b);
+        }
+    }
+  return (b);
+}
+//-----------------------------------------------------------------
+proc iostruct(module R)
+"USAGE: iostruct( R ); R a module
+RETURN:  list L with entries: string s, intvec v, module P and module Q
+PURPOSE:  if R is the kernel-representation-matrix of some system, then we output a input-ouput representation Py=Qu of the system, the components that have been chosen as outputs(intvec v) and a comment s
+NOTE:  the procedure uses Bareiss algorithm
+EXAMPLE:  example iostruct; shows an example
+"
+{
+  // NOTE cont'd
+  //which might not terminate in some cases
+  list L = bareiss(R);
+  int R_rank = ncols(L[1]);
+  int NCols=ncols(R);
+  intvec v=L[2];
+  int temp;
+  int NRows=nrows(v);
+  int i,j;
+  int b=1;
+  module P;
+  module Q;
+  int n=0;
+
+  while(b==1)               //sort v through bubblesort
+    {
+      b=0;
+      for(i=1;i<NRows;i++)
+        {
+          if(v[i]>v[i+1])
+          {
+            temp=v[i];
+            v[i]=v[i+1];
+            v[i+1]=temp;
+            b=1;
+          }
+        }
+    }
+  P=R[v];                     //generate P
+  for(i=1;i<=NCols;i++)       //generate Q
+    {
+      if(elementof(i,v)==1)
+        {
+          i++;
+          continue;
+        }
+      Q=Q,R[i];
+    }
+  Q=simplify(Q,2);
+  string s="The following components have been chosen as outputs: ";
+  return (list(s,v,P,Q));
+}
+example
+{"EXAMPLE:";echo = 2;
+ //Example Antenna
+ ring r = (0, K1, K2, Te, Kp, Kc),(Dt, delta), (c,dp);
+ module RR;
+ RR =
+   [Dt, -K1, 0, 0, 0, 0, 0, 0, 0],
+   [0, Dt+K2/Te, 0, 0, 0, 0, -Kp/Te*delta, -Kc/Te*delta, -Kc/Te*delta],
+   [0, 0, Dt, -K1, 0, 0, 0, 0, 0],
+   [0, 0, 0, Dt+K2/Te, 0, 0, -Kc/Te*delta, -Kp/Te*delta, -Kc/Te*delta],
+   [0, 0, 0, 0, Dt, -K1, 0, 0, 0],
+   [0, 0, 0, 0, 0, Dt+K2/Te, -Kc/Te*delta, -Kc/Te*delta, -Kp/Te*delta];
+ module R = transpose(RR);
+ view(iostruct(R));
+}
+
+//---------------------------------------------------------------
+static proc smdeg(matrix N)
+"USAGE: smdeg( N ); N a matrix
+RETURN:  intvec
+PURPOSE: returns an intvec of length 2 with the index of an element of N with smallest degree
+"
+{
+  int n = nrows(N);
+  int m = ncols(N);
+  int d,d_temp;
+  intvec v;
+  int i,j;            // counter
+
+  if (N==0)
+  {
+    v = 1,1;
+    return(v);
+  }
+
+  for (i=1; i<=n; i++)
+// hier wird ein Element ausgewaehlt(!=0) und mit dessen Grad gestartet
+  {
+    for (j=1; j<=m; j++)
+    {
+      if( deg(N[i,j])!=-1 )
+      {
+        d=deg(N[i,j]);
+        break;
+      }
+    }
+    if (d != -1)
+    {
+      break;
+    }
+  }
+  for(i=1; i<=n; i++)
+  {
+    for(j=1; j<=m; j++)
+    {
+      d_temp = deg(N[i,j]);
+      if ( (d_temp < d) && (N[i,j]!=0) )
+      {
+        d=d_temp;
+      }
+    }
+  }
+  for (i=1; i<=n; i++)
+  {
+    for (j=1; j<=m;j++)
+    {
+      if ( (deg(N[i,j]) == d) && (N[i,j]!=0) )
+      {
+        v = i,j;
+        return(v);
+      }
+    }
+  }
+}
+//---------------------------------------------------------------
+static proc NoNon0Pol(vector v)
+"USAGE: NoNon0Pol(v), v a vector
+RETURN:  int
+PURPOSE: returns 1, if there is only one non-zero element in v and 0 else
+"{
+  int i,j;
+  int n = nrows(v);
+  for( j=1; j<=n; j++)
+  {
+    if (v[j] != 0)
+    {
+      i++;
+    }
+  }
+  if ( i!=1 )
+  {
+    i=0;
+  }
+  return(i);
+}
+//---------------------------------------------------------------
+static proc extgcd_Our(poly p, poly q)
+{
+  ideal J;   //for extgcd-computations
+  matrix T; //----------"------------
+  list L;
+  // the extgcd-command has a bug in versions before 2-0-7
+  if ( system("version")<=2006 )
+  {
+    J = p,q; // J = N[k-1,k-1],N[k,k]; //J is of type ideal
+    L[1] = liftstd(J,T);  //T is of type matrix
+    if(J[1]==p) //this is just for the case the SINGULAR swaps the
+    //      two elements due to ordering
+    {
+      L[2] = T[1,1];
+      L[3] = T[2,1];
+    }
+    else
+    {
+      L[2] = T[2,1];
+      L[3] = T[1,1];
+    }
+  }
+  else
+  {
+    L=extgcd(p,q);
+    //    L=extgcd(N[k-1,k-1],N[k,k]);
+    //one can use this line if extgcd-bug is fixed
+  }
+  return(L);
+}
+static proc normalize_Our(matrix N, matrix Q)
+"USAGE: normalize_Our(N,Q), N, Q are two matrices
+PURPOSE: normalizes N and divides the columns of Q through the leading coefficients of the columns of N
+RETURN: normalized matrix N and altered Q(according to the scheme mentioned in purpose). If number of columns of N and Q do not coincide, N and Q are returned unchanged
+NOTE: number of columns of N and Q must coincide.
+"
+{
+  if(ncols(N) != ncols(Q))
+    {
+      return (N,Q);
+    }
+  module M = module(N);
+  module S = module(Q);
+  int NCols = ncols(N);
+  number n;
+  for(int i=1;i<=NCols;i++)
+    {
+      n = leadcoef(M[i]);
+      if( n != 0 )
+        {
+          M[i]=M[i]/n;
+          S[i]=S[i]/n;
+        }
+     }
+   N = matrix(M);
+   Q = matrix(S);
+   return (N,Q);
+}
+
+//---------------------------------------------------------------
+proc oldsmith( module M )
+"USAGE: oldsmith(M); M a module/matrix
+PURPOSE: computes the Smith normal form of a matrix
+RETURN: a list of length 4 with the following entries:
+@*      [1]: the Smith normal form S of M,
+@*      [2]: the rank of M,
+@*      [3]: a unimodular matrix U,
+@*      [4]: a unimodular matrix V,
+such that U*M*V=S. An warning is returned when no Smith form exists.
+NOTE: Older experimental implementation. The Smith form only exists over PIDs (principal ideal domains). Use global ordering for computations!
+"
+{
+  if (nvars(basering)>1) //if more than one variable, return empty list
+  {
+    string s="The Smith-Form only exists for principal ideal domains";
+    return (s);
+  }
+  matrix N = matrix(M);         //Typecasting
+  int n = nrows(N);
+  int m = ncols(N);
+  matrix P = unitmat(n);       //left transformation matrix
+  matrix Q = unitmat(m);       //right transformation matrix
+  int k, i, j, deg_temp;
+  poly tmp;
+  vector v;
+  list L;                      //for extgcd-computation
+  intmat f[1][n];              //to save degrees
+  matrix lambda[1][n];         //to save leadcoefficients
+  intmat g[1][m];              //to save degrees
+  matrix mu[1][m];             //to save leadcoefficients
+  int ii;                       //counter
+
+  while ((k!=n) && (k!=m) )
+  {
+    k++;
+    while ((k<=n) && (k<=m))  //outer while-loop for column-operations
+    {
+      while(k<=m )        //inner while-loop for row-operations
+      {
+        if( (n>m) && (k < n) && (k<m))
+        {
+          if( simplify((ideal(submat(N,k+1..n,k+1..m))),2)== 0)
+          {
+            return(N,k-1,P,Q);
+          }
+        }
+        i,j = smdeg(submat(N,k..n,k..m)); //choose smallest degree in the remaining submatrix
+        i=i+(k-1);                        //indices adjusted to the whole matrix
+        j=j+(k-1);
+        if(i!=k)                    //take the element with smallest degree in the first position
+        {
+          N=permrow(N,i,k);
+          P=permrow(P,i,k);
+        }
+        if(j!=k)
+        {
+          N=permcol(N,j,k);
+          Q=permcol(Q,j,k);
+        }
+        if(NoNon0Pol(N[k])==1)
+        {
+          break;
+        }
+        tmp=leadcoef(N[k,k]);
+        deg_temp=ord(N[k,k]);             //ord outputs the leading degree of N[k,k]
+        for(ii=k+1;ii<=n;ii++)
+        {
+          lambda[1,ii]=leadcoef(N[ii,k])/tmp;
+          f[1,ii]=deg(N[ii,k])-deg_temp;
+        }
+        for(ii=k+1;ii<=n;ii++)
+        {
+          N = addrow(N,k,-lambda[1,ii]*var(1)^f[1,ii],ii);
+          P = addrow(P,k,-lambda[1,ii]*var(1)^f[1,ii],ii);
+          N,Q=normalize_Our(N,Q);
+        }
+      }
+      if (k>n)
+      {
+        break;
+      }
+      if(NoNon0Pol(transpose(N)[k])==1)
+      {
+        break;
+      }
+      tmp=leadcoef(N[k,k]);
+      deg_temp=ord(N[k,k]); //ord outputs the leading degree of N[k][k]
+
+      for(ii=k+1;ii<=m;ii++)
+      {
+        mu[1,ii]=leadcoef(N[k,ii])/tmp;
+        g[1,ii]=deg(N[k,ii])-deg_temp;
+      }
+      for(ii=k+1;ii<=m;ii++)
+      {
+        N=addcol(N,k,-mu[1,ii]*var(1)^g[1,ii],ii);
+        Q=addcol(Q,k,-mu[1,ii]*var(1)^g[1,ii],ii);
+        N,Q=normalize_Our(N,Q);
+      }
+    }
+    if( (k!=1) && (k<n) && (k<m) )
+    {
+      L = extgcd_Our(N[k-1,k-1],N[k,k]);
+      if ( N[k-1,k-1]!=L[1] )  //means that N[k-1,k-1] is not a divisor of N[k,k]
+      {
+        N=addrow(N,k-1,L[2],k);
+        P=addrow(P,k-1,L[2],k);
+        N,Q=normalize_Our(N,Q);
+
+        N=addcol(N,k,-L[3],k-1);
+        Q=addcol(Q,k,-L[3],k-1);
+        N,Q=normalize_Our(N,Q);
+        k=k-2;
+      }
+    }
+  }
+  if( (k<=n) && (k<=m) )
+  {
+    if( N[k,k]==0)
+    {
+      return(N,k-1,P,Q);
+    }
+  }
+  return(N,k,P,Q);
+}
+example
+{
+  "EXAMPLE:";echo = 2;
+  option(redSB);
+  option(redTail);
+  ring r   = 0,x,dp;
+  module M = [x2,x,3x3-4], [2x2-1,4x,5x2], [2x5,3x,4x];
+  print(M);
+  list P = oldsmith(M);
+  print(P[1]);
+  matrix N = matrix(M);
+  matrix B = P[3]*N*P[4];
+  print(B);
+}
+// see what happens when the matrix is already in Smith-Form
+//  module M = [x,0,0],[0,x2,0],[0,0,x3];
+//  list L = oldsmith(M);
+// print(L[1]);
+//matrix N=matrix(M);
+//matrix B=L[3]*N*L[4];
+//print(B);
+//---------------------------------------------------------------
+static proc list_tex(L, string name,link l,int nr_loop)
+"USAGE: list_tex(L,name,l), where L is a list, name a string, l a link
+         writes the content of list L in a tex-file 'name'
+RETURN: nothing
+"
+{
+  if(typeof(L)!="list")  //in case L is not a list
+  {
+    texobj(name,L);
+  }
+  if(size(L)==0)
+  {
+  }
+  else
+  {
+    string t;
+    for (int i=1;i<=size(L);i++)
+    {
+      while(1)
+      {
+        if(typeof(L[i])=="string")  //Fehler hier fuer normalen output->nur wenn string in liste dann verbatim
+        {
+          t=L[i];
+          if(nr_loop==1)
+          {
+            write(l,"\\begin\{center\}");
+            write(l,"\\begin\{verbatim\}");
+          }
+          write(l,t);
+          if(nr_loop==0)
+          {
+            write(l,"\\par");
+          }
+          if(nr_loop==1)
+          {
+            write(l,"\\end\{verbatim\}");
+            write(l,"\\end\{center\}");
+          }
+          break;
+        }
+        if(typeof(L[i])=="module")
+        {
+          texobj(name,matrix(L[i]));
+          break;
+        }
+        if(typeof(L[i])=="list")
+        {
+          list_tex(L[i],name,l,1);
+          break;
+        }
+        write(l,"\\begin\{center\}");
+        texobj(name,L[i]);
+        write(l,"\\end\{center\}");
+        write(l,"\\par");
+        break;
+      }
+    }
+  }
+}
+example
+{
+  "EXAMPLE:";echo = 2;
+}
+//---------------------------------------------------------------
+proc verbatim_tex(string s, link l)
+"USAGE: verbatim_tex(s,l), where s is a string and l a link
+PURPOSE: writes the content of s in verbatim-environment in the file
+         specified by link
+RETURN: nothing
+"
+{
+  write(l,"\\begin{verbatim}");
+  write(l,s);
+  write(l,"\\end{verbatim}");
+  write(l,"\\par");
+}
+example
+{
+  "EXAMPLE:";echo = 2;
+}
+//---------------------------------------------------------------
+proc findTorsion(module R, ideal TAnn)
+"USAGE:  findTorsion(R, I);   R an ideal/matrix/module, I an ideal
+RETURN:  module
+PURPOSE: computes the Groebner basis of the submodule of R, annihilated by I
+NOTE: especially helpful, when I is the annihilator of the t(R) - the torsion submodule of R. In this case, the result is the explicit presentation of t(R) as
+the submodule of R
+EXAMPLE: example findTorsion; shows an example
+"
+{
+  // motivation: let R be a module,
+  // TAnn is the annihilator of t(R)\subset R
+  // compute the generators of t(R) explicitly
+  ideal AS = TAnn;
+  module S = R;
+  if (attrib(S,"isSB")<>1)
+  {
+    S = std(S);
+  }
+  if (attrib(AS,"isSB")<>1)
+  {
+    AS = std(AS);
+  }
+  int nc  = ncols(S);
+  module To = quotient(S,AS);
+  To = std(NF(To,S));
+  return(To);
+}
+example
+{
+  "EXAMPLE:";echo = 2;
+  // Flexible Rod
+  ring A = 0,(D1, D2), (c,dp);
+  module R= [D1, -D1*D2, -1], [2*D1*D2, -D1-D1*D2^2, 0];
+  module RR = transpose(R);
+  list L = control(RR);
+  // here, we have the annihilator:
+  ideal LAnn = D1; // = L[10]
+  module Tr  = findTorsion(RR,LAnn);
+  print(RR);  // the module itself
+  print(Tr); // generators of the torsion submodule
+}
+
+
+proc controlExample(string s)
+"USAGE:  controlExample(s);   s a string
+RETURN:  ring
+PURPOSE: set up an example from the mini database by initalizing a ring and a module in a ring
+NOTE: in order to see the list of available examples, execute @code{controlExample(\"show\");}
+@* To use an example, one has to do the following. Suppose one calls the ring, where the example will be activated, A. Then, by executing
+@*  @code{def A = controlExample(\"Antenna\");} and @code{setring A;},
+@* A will become a basering from the example \"Antenna\" with
+the predefined system module R (transposed).
+After that one can just execute @code{control(R);} respectively
+ at code{autonom(R);} to perform the control resp. autonomy analysis of R.
+EXAMPLE: example controlExample; shows an example
+"{
+  list E, S, D; // E=official name, S=synonym, D=description
+  E[1] = "Cauchy1";  S[1] = "cauchy1";  D[1] = "1-dimensional Cauchy equation";
+  E[2] = "Cauchy2";  S[2] = "cauchy2";  D[2] = "2-dimensional Cauchy equation";
+  E[3] = "Control1"; S[3] = "control1"; D[3] = "example of a simple noncontrollable system";
+  E[4] = "Control2"; S[4] = "control2"; D[4] = "example of a simple controllable system";
+  E[5] = "Antenna";  S[5] = "antenna";  D[5] = "antenna";
+  E[6] = "Einstein"; S[6] = "einstein"; D[6] = "Einstein equations in vacuum";
+  E[7] = "FlexibleRod"; S[7] = "flexible rod"; D[7] = "flexible rod";
+  E[8] = "TwoPendula";  S[8] = "two pendula";  D[8] = "two pendula mounted on a cart";
+  E[9] = "WindTunnel";  S[9] = "wind tunnel";D[9] = "wind tunnel";
+  E[10] = "Zerz1";      S[10] = "zerz1"; D[10] = "example from the lecture of Eva Zerz";
+  // all the examples so far
+  int i;
+  if ( (s=="show") || (s=="Show") )
+  {
+    print("The list of examples:");
+    for (i=1; i<=size(E); i++)
+    {
+      printf("name: %s,  desc: %s", E[i],D[i]);
+    }
+    return();
+  }
+  string t;
+  for (i=1; i<=size(E); i++)
+  {
+    if ( (s==E[i]) || (s==S[i]) )
+    {
+      t = "def @A = ex"+E[i]+"();";
+      execute(t);
+      return(@A);
+    }
+  }
+  "No example found";
+  return();
+}
+example
+{
+  "EXAMPLE:";echo = 2;
+  controlExample("show");   // let us see all available examples:
+  def B = controlExample("TwoPendula"); // let us set up a particular example
+  setring B;
+  print(R);
+}
+
+//----------------------------------------------------------
+//
+//Some example rings with defined systems
+//----------------------------------------------------------
+//autonomy:
+//
+//----------------------------------------------------------
+static proc exCauchy1()
+{
+  ring @r=0,(s1,s2),dp;
+  module R= [s1,-s2],
+            [s2, s1];
+  R=transpose(R);
+  export R;
+  return(@r);
+}
+//----------------------------------------------------------
+static proc exCauchy2()
+{
+  ring @r=0,(s1,s2,s3,s4),dp;
+  module R= [s1,-s2],
+            [s2, s1],
+            [s3,-s4],
+            [s4, s3];
+  R=transpose(R);
+  export R;
+  return(@r);
+}
+//----------------------------------------------------------
+static proc exZerz1()
+{
+  ring @r=0,(d1,d2),dp;
+  module R=[d1^2-d2],
+           [d2^2-1];
+  R=transpose(R);
+  export R;
+  return(@r);
+}
+//----------------------------------------------------------
+//control
+//----------------------------------------------------------
+static proc exControl1()
+{
+  ring @r=0,(s1,s2,s3),dp;
+  module R=[0,-s3,s2],
+           [s3,0,-s1];
+  R=transpose(R);
+  export R;
+  return(@r);
+}
+//----------------------------------------------------------
+static proc exControl2()
+{
+  ring @r=0,(s1,s2,s3),dp;
+  module R=[0,-s3,s2],
+           [s3,0,-s1],
+           [-s2,s1,0];
+  R=transpose(R);
+  export R;
+  return(@r);
+}
+//----------------------------------------------------------
+static proc exAntenna()
+{
+  ring @r = (0, K1, K2, Te, Kp, Kc),(Dt, delta), dp;
+  module R;
+  R = [Dt, -K1, 0, 0, 0, 0, 0, 0, 0],
+      [0, Dt+K2/Te, 0, 0, 0, 0, -Kp/Te*delta, -Kc/Te*delta, -Kc/Te*delta],
+      [0, 0, Dt, -K1, 0, 0, 0, 0, 0],
+      [0, 0, 0, Dt+K2/Te, 0, 0, -Kc/Te*delta, -Kp/Te*delta, -Kc/Te*delta],
+      [0, 0, 0, 0, Dt, -K1, 0, 0, 0],
+      [0, 0, 0, 0, 0, Dt+K2/Te, -Kc/Te*delta, -Kc/Te*delta, -Kp/Te*delta];
+
+  R=transpose(R);
+  export R;
+  return(@r);
+}
+
+//----------------------------------------------------------
+
+static proc exEinstein()
+{
+  ring @r = 0,(D(1..4)),dp;
+  module R =
+  [D(2)^2+D(3)^2-D(4)^2, D(1)^2, D(1)^2, -D(1)^2, -2*D(1)*D(2), 0, 0, -2*D(1)*D(3), 0, 2*D(1)*D(4)],
+  [D(2)^2, D(1)^2+D(3)^2-D(4)^2, D(2)^2, -D(2)^2, -2*D(1)*D(2), -2*D(2)*D(3), 0, 0, 2*D(2)*D(4), 0],
+  [D(3)^2, D(3)^2, D(1)^2+D(2)^2-D(4)^2, -D(3)^2, 0, -2*D(2)*D(3), 2*D(3)*D(4), -2*D(1)*D(3), 0, 0],
+  [D(4)^2, D(4)^2, D(4)^2, D(1)^2+D(2)^2+D(3)^2, 0, 0, -2*D(3)*D(4), 0, -2*D(2)*D(4), -2*D(1)*D(4)],
+  [0, 0, D(1)*D(2), -D(1)*D(2), D(3)^2-D(4)^2, -D(1)*D(3), 0, -D(2)*D(3), D(1)*D(4), D(2)*D(4)],
+  [D(2)*D(3), 0, 0, -D(2)*D(3),-D(1)*D(3), D(1)^2-D(4)^2, D(2)*D(4), -D(1)*D(2), D(3)*D(4), 0],
+  [D(3)*D(4), D(3)*D(4), 0, 0, 0, -D(2)*D(4), D(1)^2+D(2)^2, -D(1)*D(4), -D(2)*D(3), -D(1)*D(3)],
+  [0, D(1)*D(3), 0, -D(1)*D(3), -D(2)*D(3), -D(1)*D(2), D(1)*D(4), D(2)^2-D(4)^2, 0, D(3)*D(4)],
+  [D(2)*D(4), 0, D(2)*D(4), 0, -D(1)*D(4), -D(3)*D(4), -D(2)*D(3), 0, D(1)^2+D(3)^2, -D(1)*D(2)],
+  [0, D(1)*D(4), D(1)*D(4), 0, -D(2)*D(4), 0, -D(1)*D(3), -D(3)*D(4), -D(1)*D(2), D(2)^2+D(3)^2];
+
+  R=transpose(R);
+  export R;
+  return(@r);
+}
+
+//----------------------------------------------------------
+static proc exFlexibleRod()
+{
+  ring @r = 0,(D1, delta), dp;
+  module R;
+  R = [D1, -D1*delta, -1], [2*D1*delta, -D1-D1*delta^2, 0];
+
+  R=transpose(R);
+  export R;
+  return(@r);
+}
+
+//----------------------------------------------------------
+static proc exTwoPendula()
+{
+  ring @r=(0,m1,m2,M,g,L1,L2),Dt,dp;
+  module R = [m1*L1*Dt^2, m2*L2*Dt^2, -1, (M+m1+m2)*Dt^2],
+             [m1*L1^2*Dt^2-m1*L1*g, 0, 0, m1*L1*Dt^2],
+             [0, m2*L2^2*Dt^2-m2*L2*g, 0, m2*L2*Dt^2];
+
+  R=transpose(R);
+  export R;
+  return(@r);
+}
+//----------------------------------------------------------
+static proc exWindTunnel()
+{
+  ring @r = (0,a, omega, zeta, k),(D1, delta),dp;
+  module R = [D1+a, -k*a*delta, 0, 0],
+             [0, D1, -1, 0],
+             [0, omega^2, D1+2*zeta*omega, -omega^2];
+
+  R=transpose(R);
+  export R;
+  return(@r);
+}
+
+/* noncomm examples for leftInverse/rightInverse:
+
+LIB "jacobson.lib";
+    ring w = 0,(x,d),Dp;
+    def W=nc_algebra(1,1);
+    setring W;
+    matrix m[3][3]=[d2,d+1,0],[d+1,0,d3-x2*d],[2d+1, d3+d2, d2];
+    list J=jacobson(m,0);
+
+leftInverse(J[3]); // exist
+rightInverse(J[3]);
+
+leftInverse(J[1]); // zero
+rightInverse(J[1]);
+
+list JJ = jacobson(J[1],0);
+
+leftInverse(JJ[3]); // exist
+rightInverse(JJ[3]);
+
+leftInverse(JJ[1]); // exist
+rightInverse(JJ[1]);
+
+leftInverse(JJ[2]); // zero
+rightInverse(JJ[2]);
+
+*/
diff --git a/Singular/LIB/crypto.lib b/Singular/LIB/crypto.lib
new file mode 100644
index 0000000..4bf99e2
--- /dev/null
+++ b/Singular/LIB/crypto.lib
@@ -0,0 +1,2181 @@
+//////////////////////////////////////////////////////////////////////////////
+version="version crypto.lib 4.0.0.1 Aug_2014 "; // $Id: 763cdcfc31ba974ab1e4ac359172f585844f5b0a $
+category="Teaching";
+info="
+LIBRARY:  crypto.lib     Procedures for teaching cryptography
+AUTHOR:                  Gerhard Pfister, pfister at mathematik.uni-kl.de
+
+OVERVIEW:
+     The library contains procedures to compute the discrete logarithm,
+      primality-tests, factorization included elliptic curves.
+      The library is intended to be used for teaching purposes but not
+      for serious computations. Sufficiently high printlevel allows to
+      control each step, thus illustrating the algorithms at work.
+
+
+PROCEDURES:
+ decimal(s);                number corresponding to the hexadecimal number s
+ eexgcdN(L)                 T with sum_i L[i]*T[i]=T[n+1]=gcd(L[1],...,L[n])
+ lcmN(a,b)                  compute lcm(a,b)
+ powerN(m,d,n)              compute m^d mod n
+ chineseRem(T,L)            compute x such that x = T[i] mod L[i]
+ Jacobi(a,n)                the generalized Legendre symbol of a and n
+ primList(n)                the list of all primes <=n
+ primL(q)                   first primes p_1,...,p_r such that q<p_1*...*p_r
+ intPart(x)                 the integral part of a rational number
+ intRoot(m)                 the integral part of the square root of m
+ squareRoot(a,p)            the square root of a in Z/p, p prime
+ solutionsMod2(M)           basis solutions of Mx=0 over Z/2
+ powerX(q,i,I)              q-th power of the i-th variable modulo I
+ babyGiant(b,y,p)           discrete logarithm x: b^x=y mod p
+ rho(b,y,p)                 discrete logarithm x: b^x=y mod p
+ MillerRabin(n,k)           probabilistic primaly-test of Miller-Rabin
+ SolowayStrassen(n,k)       probabilistic primaly-test of Soloway-Strassen
+ PocklingtonLehmer(N,[])    primaly-test of Pocklington-Lehmer
+ PollardRho(n,k,a,[])       Pollard's rho factorization
+ pFactor(n,B,P)             Pollard's p-factorization
+ quadraticSieve(n,c,B,k)    quadratic sieve factorization
+ isOnCurve(N,a,b,P)         P is on the curve y^2z=x^3+a*xz^2+b*z^3  over Z/N
+ ellipticAdd(N,a,b,P,Q)     P+Q, addition on elliptic curves
+ ellipticMult(N,a,b,P,k)    k*P on elliptic curves
+ ellipticRandomCurve(N)     generates y^2z=x^3+a*xz^2+b*z^3  over Z/N randomly
+ ellipticRandomPoint(N,a,b) random point on y^2z=x^3+a*xz^2+b*z^3  over Z/N
+ countPoints(N,a,b)         number of points of y^2=x^3+a*x+b  over Z/N
+ ellipticAllPoints(N,a,b)   points of y^2=x^3+a*x+b  over Z/N
+ ShanksMestre(q,a,b,[])     number of points of y^2=x^3+a*x+b  over Z/N
+ Schoof(N,a,b)              number of points of y^2=x^3+a*x+b  over Z/N
+ generateG(a,b,m)           m-th division polynomial of y^2=x^3+a*x+b  over Z/N
+ factorLenstraECM(N,S,B,[]) Lenstra's factorization
+ ECPP(N)                    primaly-test of Goldwasser-Kilian
+
+              [parameters in square brackets are optional]
+";
+
+LIB "poly.lib";
+
+///////////////////////////////////////////////////////////////////////////////
+
+
+//=============================================================================
+//=========================== basic prozedures ================================
+//=============================================================================
+
+proc decimal(string s)
+"USAGE:  decimal(s); s = string
+RETURN: the (decimal) number corresponding to the hexadecimal number s
+EXAMPLE:example decimal; shows an example
+"
+{
+   int n=size(s);
+   int i;
+   bigint k;
+   bigint t=16;
+   bigint m=0;
+   for(i=1;i<=n;i++)
+   {
+      k=0;
+      if(s[i]=="1"){k=1;}
+      if(s[i]=="2"){k=2;}
+      if(s[i]=="3"){k=3;}
+      if(s[i]=="4"){k=4;}
+      if(s[i]=="5"){k=5;}
+      if(s[i]=="6"){k=6;}
+      if(s[i]=="7"){k=7;}
+      if(s[i]=="8"){k=8;}
+      if(s[i]=="9"){k=9;}
+      if(s[i]=="a"){k=10;}
+      if(s[i]=="b"){k=11;}
+      if(s[i]=="c"){k=12;}
+      if(s[i]=="d"){k=13;}
+      if(s[i]=="e"){k=14;}
+      if(s[i]=="f"){k=15;}
+      m=m*t+k;
+   }
+   return(m);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   string s  ="8edfe37dae96cfd2466d77d3884d4196";
+   decimal(s);
+}
+
+proc eexgcdN(list L)
+"USAGE:  eexgcdN(L);
+RETURN: list T such that sum_i L[i]*T[i]=T[n+1]=gcd(L[1],...,L[n])
+EXAMPLE:example eexgcdN; shows an example
+"
+{
+   if(size(L)==2)
+   {
+     list LL=extgcd(L[1],L[2]);return(list(LL[2],LL[3],LL[1]));
+   }
+   bigint p=L[size(L)];
+   L=delete(L,size(L));
+   list T=eexgcdN(L);
+   list S=extgcd(T[size(T)],p);
+   int i;
+   for(i=1;i<=size(T)-1;i++)
+   {
+      T[i]=T[i]*S[2];
+   }
+   p=T[size(T)];
+   T[size(T)]=S[3];
+   T[size(T)+1]=S[1];
+   return(T);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   eexgcdN(list(24,15,21));
+}
+
+proc lcmN(bigint a, bigint b)
+"USAGE:  lcmN(a,b);
+RETURN: lcm(a,b);
+EXAMPLE:example lcmN; shows an example
+"
+{
+   return (a*b/gcd(a,b));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   lcmN(24,15);
+}
+
+proc powerN(bigint m, bigint d, bigint n)
+"USAGE:  powerN(m,d,n);
+RETURN: m^d mod n
+EXAMPLE:example powerN; shows an example
+"
+{
+   if(d==0){return(bigint(1));}
+   int i;
+   if(n==0)
+   {
+      for(i=12;i>=2;i--)
+      {
+         if((d mod i)==0){return(powerN(m,d div i,n)^i);}
+      }
+      return(m*powerN(m,d-1,n));
+   }
+   for(i=12;i>=2;i--)
+   {
+      if((d mod i)==0)
+      {
+        bigint rr=powerN(m,d div i,n)^i mod n;
+        if (rr<0) { rr=rr+n;}
+        return(rr);
+      }
+   }
+   return(m*powerN(m,d-1,n) mod n);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   powerN(24,15,7);
+}
+
+proc chineseRem(list T,list L)
+"USAGE:  chineseRem(T,L);
+RETURN: x such that x = T[i] mod L[i]
+NOTE:   chinese remainder theorem
+EXAMPLE:example chineseRem; shows an example
+"
+{
+   int i;
+   int n=size(L);
+   bigint N=1;
+   for(i=1;i<=n;i++)
+   {
+      N=N*L[i];
+   }
+   list M;
+   for(i=1;i<=n;i++)
+   {
+      M[i]=N div L[i];
+   }
+   list S=eexgcdN(M);
+   bigint x;
+   for(i=1;i<=n;i++)
+   {
+      x=x+S[i]*M[i]*T[i];
+   }
+   x=x mod N;
+   return(x);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   chineseRem(list(24,15,7),list(2,3,5));
+}
+
+proc Jacobi(bigint a, bigint n)
+"USAGE:  Jacobi(a,n);
+RETURN: the generalized Legendre symbol
+NOTE: if n is an odd prime then Jacobi(a,n)=0,1,-1 if n|a, a=x^2 mod n,else
+EXAMPLE:example Jacobi; shows an example
+"
+{
+   int i;
+   int z=1;
+   bigint t=1;
+   bigint k;
+
+   if((((n-1) div 2) mod 2)!=0){z=-1;}
+   if(a<0){return(z*Jacobi(-a,n));}
+   a=a mod n;
+   if(n==1){return(1);}
+   if(a==0){return(0);}
+
+   while(a!=0)
+   {
+      while((a mod 2)==0)
+      {
+         a=a div 2;
+         if(((n mod 8)==3)||((n mod 8)==5)){t=-t;}
+      }
+      k=a;a=n;n=k;
+      if(((a mod 4)==3)&&((n mod 4)==3)){t=-t;}
+      a=a mod n;
+   }
+   if (n==1){return(t);}
+   return(0);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   Jacobi(13580555397810650806,5792543);
+}
+
+proc primList(int n)
+"USAGE:  primList(n);
+RETURN: the list of all primes <=n
+EXAMPLE:example primList; shows an example
+"
+{
+   int i,j;
+   list re;
+   re[1]=2;
+   re[2]=3;
+   for(i=5;i<=n;i=i+2)
+   {
+     j=1;
+     while(j<=size(re))
+     {
+        if((i mod re[j])==0){break;}
+        j++;
+     }
+     if(j==size(re)+1){re[size(re)+1]=i;}
+   }
+   return(re);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   list L=primList(100);
+   size(L);
+   L[size(L)];
+}
+
+proc primL(bigint q)
+"USAGE:  primL(q);
+RETURN: list of the first primes p_1,...,p_r such that q>p_1*...*p_(r-1)
+        and q<p_1*...*p_r
+EXAMPLE:example primL; shows an example
+"
+{
+   int i,j;
+   list re;
+   re[1]=2;
+   re[2]=3;
+   bigint s=6;
+   i=3;
+   while(s<=q)
+   {
+     i=i+2;
+     j=1;
+     while(j<=size(re))
+     {
+        if((i mod re[j])==0){break;}
+        j++;
+     }
+     if(j==size(re)+1)
+     {
+        re[size(re)+1]=i;
+        s=s*i;
+     }
+   }
+   return(re);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   primL(20);
+}
+
+proc intPart(number x)
+"USAGE:  intPart(x);
+RETURN: the integral part of a rational number
+EXAMPLE:example intPart; shows an example
+"
+{
+  if (x>=0)
+  {
+    return(bigint((numerator(x)-(bigint(numerator(x)) mod bigint(denominator(x)))))
+         div bigint(denominator(x)));
+  }
+  else
+  {
+    return(bigint((numerator(x)-(bigint(numerator(x)) mod bigint(denominator(x)+denominator(x)))))
+         div bigint(denominator(x)));
+  }
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r=0,x,dp;
+   intPart(7/3);
+}
+
+proc intRoot(bigint mm)
+"USAGE:  intRoot(m);
+RETURN: the integral part of the square root of m
+EXAMPLE:example intRoot; shows an example
+"
+{
+   ring R = 0, at x,dp;
+   number m=mm;
+   number x=1;
+   number t=x^2;
+   number s=(x+1)^2;
+   while(((m>t)&&(m>s))||((m<t)&&(m<s)))
+   {
+      if (x==0) { t=0; }
+      else
+      {
+        x=intPart(x/2+m/(2*x));  //Newton step
+        t=x^2;
+      }
+      if(t>m)
+      {
+         s=(x-1)^2;
+      }
+      else
+      {
+         s=(x+1)^2;
+      }
+   }
+   if(t>m){return(bigint(x-1));}
+   if(s==m){return(bigint(x+1));}
+   return(bigint(x));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   intRoot(20);
+}
+
+proc squareRoot(bigint a, bigint p)
+"USAGE:  squareRoot(a,p);
+RETURN: the square root of a in Z/p, p prime
+NOTE:   assumes the Jacobi symbol is 1 or p=2.
+EXAMPLE:example squareRoot; shows an example
+"
+{
+   if(p==2){return(a);}
+   if((a mod p)==0){return(0);}
+   if (a<0) { a=a+p; }
+   if(powerN(a,p-1,p)!=1)
+   {
+      "p is not prime";
+      return(bigint(-5));
+   }
+   bigint n=random(1,2147483647) mod p;
+   if(n==0){n=n+1;}
+   bigint j=Jacobi(n,p);
+   if(j==0)
+   {
+      "p is not prime";
+      return(bigint(-5));
+   }
+   if(j==1)
+   {
+      return(squareRoot(a,p));
+   }
+   bigint q=p-1;
+   bigint e=0;
+   bigint two=2;
+   bigint z,m,t;
+   while((q mod 2)==0)
+   {
+      e=e+1;
+      q=q div 2;
+   }
+   bigint y=powerN(n,q,p);
+   bigint r=e;
+   bigint x=powerN(a,(q-1) div 2,p);
+   bigint b=a*x^2 mod p;
+   x=a*x mod p;
+
+   while(((b-1) mod p)!=0)
+   {
+      m=0;z=b;
+      while(((z-1) mod p)!=0)
+      {
+         z=z^2 mod p;
+         m=m+1;
+      }
+      t=powerN(y,powerN(two,r-m-1,p),p);
+      y=t^2 mod p;
+      r=m;
+      x=x*t mod p;
+      b=b*y mod p;
+   }
+   return(x);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   squareRoot(8315890421938608,32003);
+}
+
+
+proc solutionsMod2(bigintmat MM)
+"USAGE:  solutionsMod2(M);
+RETURN: an intmat containing a basis of the vector space of solutions of the
+        linear system of equations defined by M over the prime field of
+        characteristic 2
+EXAMPLE:example solutionsMod2; shows an example
+"
+{
+   ring Rhelp=2,z,(c,dp);
+   int i,j;
+   matrix M[nrows(MM)][ncols(MM)];
+   for(i=1;i<=nrows(MM);i++)
+   {
+      for(j=1;j<=ncols(MM);j++)
+      {
+         M[i,j]=MM[i,j];
+      }
+   }
+   matrix S=syz(M);
+   intmat v[nrows(S)][ncols(S)];
+   for(i=1;i<=nrows(S);i++)
+   {
+      for(j=1;j<=ncols(S);j++)
+      {
+         if(S[i,j]==1){v[i,j]=1;}
+      }
+   }
+   return(v);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   bigintmat M[3][3]=1,2,3,4,5,6,7,6,5;
+   solutionsMod2(M);
+}
+
+proc powerX(int q, int i, ideal I)
+"USAGE:  powerX(q,i,I);
+RETURN: the q-th power of the i-th variable modulo I
+ASSUME: I is a standard basis
+EXAMPLE:example powerX; shows an example
+"
+{
+   if(q<=181){return(reduce(var(i)^int(q),I));}
+   if((q mod 5)==0){return(reduce(powerX(q div 5,i,I)^5,I));}
+   if((q mod 4)==0){return(reduce(powerX(q div 4,i,I)^4,I));}
+   if((q mod 3)==0){return(reduce(powerX(q div 3,i,I)^3,I));}
+   if((q mod 2)==0){return(reduce(powerX(q div 2,i,I)^2,I));}
+   return(reduce(var(i)*powerX(q-1,i,I),I));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring R = 0,(x,y),dp;
+   powerX(100,2,std(ideal(x3-1,y2-x)));
+}
+
+//======================================================================
+//=========================== Discrete Logarithm =======================
+//======================================================================
+
+//============== Shank's baby step - giant step ========================
+
+proc babyGiant(bigint b, bigint y, bigint p)
+"USAGE:  babyGiant(b,y,p);
+RETURN: the discrete logarithm x: b^x=y mod p
+NOTE:   This procedure works based on Shank's baby step - giant step method.
+EXAMPLE:example babyGiant; shows an example
+"
+{
+   int i,j,m;
+   list l;
+   bigint h=1;
+   bigint x;
+
+//choose m minimal such that m^2>p
+   for(i=1;i<=p;i++){if(i^2>p) break;}
+   m=i;
+
+//baby-step:  compute the table y*b^i for 1<=i<=m
+   for(i=1;i<=m;i++){l[i]=y*b^i mod p;}
+
+//giant-step: compute b^(m+j), 1<=j<=m and search in the baby-step table
+//for an i with y*b^i=b^(m*j). If found then x=m*j-i
+   bigint g=b^m mod p;
+   while(j<m)
+   {
+      j++;
+      h=h*g mod p;
+      for(i=1;i<=m;i++)
+      {
+         if(h==l[i])
+         {
+            x=m*j-i;
+            j=m;
+            break;
+         }
+     }
+   }
+   return(x);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   bigint b=2;
+   bigint y=10;
+   bigint p=101;
+   babyGiant(b,y,p);
+}
+
+//==============  Pollards rho  =================================
+
+proc rho(bigint b, bigint y, bigint p)
+"USAGE:  rho(b,y,p);
+RETURN: the discrete logarithm x=log_b(y): b^x=y mod p
+NOTE: Pollard's rho:
+       choose random f_0 in 0,...,p-2 ,e_0=0, define x_0=b^f_0, define
+       x_i=y^e_i*b^f_i as below. For i large enough there is i with
+       x_(i/2)=x_i. Let s:=e_(i/2)-e_i mod p-1 and t:=f_i-f_(i/2) mod p-1,
+       d=gcd(s,p-1)=u*s+v*(p-1) then x=tu/d +j*(p-1)/d for some j (to be
+       found by trying)
+EXAMPLE:example rho; shows an example
+"
+{
+   int i=1;
+   int j;
+   bigint s,t;
+   list e,f,x;
+
+   e[1]=0;
+   f[1]=random(0,2147483629) mod (p-1);
+   x[1]=powerN(b,f[1],p);
+   while(i)
+   {
+      if((x[i] mod 3)==1)
+      {
+         x[i+1]=y*x[i] mod p;
+         e[i+1]=e[i]+1 mod (p-1);
+         f[i+1]=f[i];
+      }
+      if((x[i] mod 3)==2)
+      {
+         x[i+1]=x[i]^2 mod p;
+         e[i+1]=e[i]*2 mod (p-1);
+         f[i+1]=f[i]*2 mod (p-1);
+      }
+      if((x[i] mod 3)==0)
+      {
+         x[i+1]=x[i]*b mod p;
+         e[i+1]=e[i];
+         f[i+1]=f[i]+1 mod (p-1);
+      }
+      i++;
+      for(j=i-1;j>=1;j--)
+      {
+         if(x[i]==x[j])
+         {
+            s=(e[j]-e[i]) mod (p-1);
+            t=(f[i]-f[j]) mod (p-1);
+            if(s!=0)
+            {
+               i=0;
+            }
+            else
+            {
+               e[1]=0;
+               f[1]=random(0,2147483629) mod (p-1);
+               x[1]=powerN(b,f[1],p);
+               i=1;
+            }
+            break;
+         }
+      }
+   }
+
+   list w=extgcd(s,p-1);
+   bigint u=w[2];
+   bigint d=w[1];
+
+   bigint a=(t*u div d) mod (p-1);
+
+   bigint pn=powerN(b,a,p);
+   if (pn<0) { pn=pn+p;}
+   while(powerN(b,a,p)!=y)
+   {
+      a=(a+(p-1) div d) mod (p-1);
+      if (a<0) { a=a+p-1; }
+   }
+   return(a);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   bigint b=2;
+   bigint y=10;
+   bigint p=101;
+   rho(b,y,p);
+}
+//====================================================================
+//====================== Primality Tests =============================
+//====================================================================
+
+//================================= Miller-Rabin =====================
+
+proc MillerRabin(bigint n, int k)
+"USAGE:  MillerRabin(n,k);
+RETURN: 1 if n is prime, 0 else
+NOTE: probabilistic test of Miller-Rabin with k loops to test if n is prime.
+       Using the theorem: If n is prime, n-1=2^s*r, r odd, then
+       powerN(a,r,n)=1 or powerN(a,r*2^i,n)=-1 for some i
+EXAMPLE:example MillerRabin; shows an example
+"
+{
+   if(n<0){n=-n;}
+   if((n==2)||(n==3)){return(1);}
+   if((n mod 2)==0){return(0);}
+
+   int i;
+   bigint a,b,j,r,s;
+   r=n-1;
+   s=0;
+   while((r mod 2)==0)
+   {
+      s=s+1;
+      r=r div 2;
+   }
+   while(i<k)
+   {
+      i++;
+      a=random(2,2147483629) mod n; if(a==0){a=3;}
+      if(gcd(a,n)!=1){return(0);}
+      b=powerN(a,r,n);
+      if(b!=1)
+      {
+         j=0;
+         while(j<s)
+         {
+           if(((b+1) mod n)==0) break;
+           b=powerN(b,2,n);
+           j=j+1;
+         }
+         if(j==s){return(0);}
+      }
+   }
+   return(1);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   bigint x=2;
+   x=x^787-1;
+   MillerRabin(x,3);
+}
+
+//======================= Soloway-Strassen  ==========================
+
+proc SolowayStrassen(bigint n, int k)
+"USAGE:  SolowayStrassen(n,k);
+RETURN: 1 if n is prime, 0 else
+NOTE: probabilistic test of Soloway-Strassen with k loops to test if n is
+       prime using the theorem: If n is prime then
+       powerN(a,(n-1)/2,n)=Jacobi(a,n) mod n
+EXAMPLE:example SolowayStrassen; shows an example
+"
+{
+   if(n<0){n=-n;}
+   if((n==2)||(n==3)){return(1);}
+   if((n mod 2)==0){return(0);}
+
+   bigint a,pn,jn;
+   int i;
+   while(i<k)
+   {
+      i++;
+      a=random(2,2147483629) mod n; if(a==0){a=3;}
+      if(gcd(a,n)!=1){return(0);}
+      pn=powerN(a,(n-1) div 2,n);
+      if (pn<0) { pn=pn+n;}
+      jn=Jacobi(a,n) mod n;
+      if (jn<0) { jn=jn+n;}
+      if(pn!=jn){return(0);}
+   }
+   return(1);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   bigint h=10;
+   bigint p=h^100+267;
+   //p=h^100+43723;
+   //p=h^200+632347;
+   SolowayStrassen(h,3);
+}
+
+
+/*
+ring R=0,z,dp;
+number p=398075086424064937397125500550386491199064362342526708406385189575946388957261768583317;
+number q=472772146107435302536223071973048224632914695302097116459852171130520711256363590397527;
+number n=p*q;
+SolowayStrassen(n,3);
+*/
+
+//===================== Pocklington-Lehmer ==============================
+
+proc PocklingtonLehmer(bigint N, list #)
+"USAGE: PocklingtonLehmer(N); optional: PocklingtonLehmer(N,L);
+        L a list of the first k primes
+RETURN:message N is not prime or {A,{p},{a_p}} as certificate for N being prime
+NOTE:assumes that it is possible to factorize N-1=A*B such that gcd(A,B)=1,
+      the factorization of A is completely known and A^2>N .
+      N is prime if and only if for each prime factor p of A we can find
+      a_p such that a_p^(N-1)=1 mod N and gcd(a_p^((N-1)/p)-1,N)=1
+EXAMPLE:example PocklingtonLehmer; shows an example
+"
+{
+   bigint m=intRoot(N);
+   if(size(#)>0)
+   {
+      list S=PollardRho(N-1,10000,1,#);
+   }
+   else
+   {
+      list S=PollardRho(N-1,10000,1);
+   }
+   int i,j;
+   bigint A=1;
+   bigint p,a,g;
+   list PA;
+   list re;
+
+   while(i<size(S))
+   {
+      p=S[i+1];
+      A=A*p;
+      PA[i+1]=p;
+      if(A>m){break;}
+
+      while(1)
+      {
+        p=p*S[i+1];
+        if(((N-1) mod p)==0)
+        {
+           A=A*p;
+        }
+        else
+        {
+           break;
+        }
+      }
+      i++;
+   }
+   if(A<=m)
+   {
+     A=N div A;
+     PA=list(S[size(S)]);
+   }
+   for(i=1;i<=size(PA);i++)
+   {
+      a=1;
+      while(a<N-1)
+      {
+         a=a+1;
+         if(powerN(a,N-1,N)!=1){return("not prime");}
+         g=gcd(powerN(a,(N-1) div PA[i],N),N);
+         if(g==1)
+         {
+           re[size(re)+1]=list(PA[i],a);
+           break;
+         }
+         if(g<N){"not prime";return(g);}
+      }
+   }
+   return(list(A,re));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   bigint N=105554676553297;
+   PocklingtonLehmer(N);
+   list L=primList(1000);
+   PocklingtonLehmer(N,L);
+}
+
+//=======================================================================
+//======================= Factorization =================================
+//=======================================================================
+
+//======================= Pollards rho  =================================
+
+proc PollardRho(bigint n, int k, int allFactors, list #)
+"USAGE:  PollardRho(n,k,allFactors); optional: PollardRho(n,k,allFactors,L);
+         L a list of the first k primes
+RETURN: a list of factors of n (which could be just n),if allFactors=0@*
+        a list of all factors of n ,if allFactors=1
+NOTE: probabilistic rho-algorithm of Pollard to find a factor of n in k loops.
+      Creates a sequence x_i such that (x_i)^2=(x_2i)^2 mod n for some i,
+      computes gcd(x_i-x_2i,n) to find a divisor. To define the sequence
+      choose x,a and define x_n+1=x_n^2+a mod n, x_1=x.
+      If allFactors is 1, it tries to find recursively all prime factors
+      using the Soloway-Strassen test.
+SEE ALSO: primefactors
+EXAMPLE:example PollardRho; shows an example
+"
+{
+    int i,j;
+    list L=primList(100);
+    list re,se;
+    if(n<0){n=-n;}
+    if(n==1){return(re);}
+
+//this is optional: test whether a prime of the list # devides n
+    if(size(#)>0)
+    {
+       L=#;
+    }
+    for(i=1;i<=size(L);i++)
+    {
+       if((n mod L[i])==0)
+       {
+          re[size(re)+1]=L[i];
+          while((n mod L[i])==0)
+          {
+             n=n div L[i];
+          }
+       }
+       if(n==1){return(re);}
+    }
+    int e=size(re);
+//here the rho-algorithm starts
+    bigint a,d,x,y;
+    while(n>1)
+    {
+       a=random(2,2147483629);
+       x=random(2,2147483629);
+       y=x;
+       d=1;
+       i=0;
+       while(i<k)
+       {
+          i++;
+          x=powerN(x,2,n); x=(x+a) mod n;
+          y=powerN(y,2,n); y=(y+a) mod n;
+          y=powerN(y,2,n); y=(y+a) mod n;
+          d=gcd(x-y,n);
+          if(d>1)
+          {
+             re[size(re)+1]=d;
+             while((n mod d)==0)
+             {
+               n=n div d;
+             }
+             break;
+          }
+          if(i==k)
+          {
+             re[size(re)+1]=n;
+             n=1;
+          }
+       }
+    }
+    if(allFactors)      //want to obtain all prime factors
+    {
+       i=e;
+       while(i<size(re))
+       {
+          i++;
+
+          if(!SolowayStrassen(re[i],5))
+          {
+             se=PollardRho(re[i],2*k,1);
+             re[i]=se[size(se)];
+             for(j=1;j<=size(se)-1;j++)
+             {
+                re[size(re)+1]=se[j];
+             }
+             i--;
+          }
+       }
+    }
+    return(re);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   bigint h=10;
+   bigint p=h^30+4;
+   PollardRho(p,5000,0);
+}
+
+//======================== Pollards p-factorization ================
+proc pFactor(bigint n,int B, list P)
+"USAGE:  pFactor(n,B,P); n to be factorized, B a bound , P a list of primes
+RETURN: a list of factors of n or n if no factor found
+NOTE: Pollard's p-factorization
+       creates the product k of powers of primes (bounded by B)  from
+       the list P with the idea that for a prime divisor p of n we have
+       p-1|k, and then p divides gcd(a^k-1,n) for some random a
+EXAMPLE:example pFactor; shows an example
+"
+{
+   int i;
+   bigint k=1;
+   bigint w;
+   while(i<size(P))
+   {
+      i++;
+      w=P[i];
+      if(w>B) break;
+      while(w*P[i]<=B)
+      {
+         w=w*P[i];
+      }
+      k=k*w;
+   }
+   bigint a=random(2,2147483629);
+   bigint d=gcd(powerN(a,k,n)-1,n);
+   if((d>1)&&(d<n)){return(d);}
+   return(n);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   list L=primList(1000);
+   pFactor(1241143,13,L);
+   bigint h=10;
+   h=h^30+25;
+   pFactor(h,20,L);
+}
+
+//==================== quadratic sieve ==============================
+
+proc quadraticSieve(bigint n, int c, list B, int k)
+"USAGE:  quadraticSieve(n,c,B,k); n to be factorized, [-c,c] the
+         sieve-intervall, B a list of primes,
+         k for using the first k elements in B
+RETURN: a list of factors of n or the message: no divisor found
+NOTE: The idea being used is to find x,y such that x^2=y^2 mod n then
+      gcd(x-y,n) can be a proper divisor of n
+EXAMPLE:example quadraticSieve; shows an example
+"
+{
+   bigint f,d;
+   int i,j,l,s,p;
+   list S,tmp;
+   intvec v;
+   v[k]=0;
+
+//compute the integral part of the square root of n
+   bigint m=intRoot(n);
+
+//consider the function f(X)=(X+m)^2-n and compute for s in [-c,c] the values
+   while(i<=2*c)
+   {
+      f=(i-c+m)^2-n;
+      tmp[1]=i-c+m;
+      tmp[2]=f;
+      tmp[3]=v;
+      S[i+1]=tmp;
+      i++;
+   }
+
+//the sieve with p in B
+//find all s in [-c,c] such that f(s) has all prime divisors in the first
+//k elements of B and the decomposition of f(s). They are characterized
+//by 1 or -1 at the second place of S[j]:
+//S[j]=j-c+m,f(j-c)/p_1^v_1*...*p_k^v_k, v_1,...,v_k maximal
+   for(i=1;i<=k;i++)
+   {
+      p=B[i];
+      if((p>2)&&(Jacobi(n,p)==-1)){i++;continue;}//n is no quadratic rest mod p
+      j=1;
+      while(j<=p)
+      {
+         if(j>2*c+1) break;
+         f=S[j][2];
+         v=S[j][3];
+         s=0;
+         while((f mod p)==0)
+         {
+            s++;
+            f=f div p;
+         }
+         if(s)
+         {
+           S[j][2]=f;
+           v[i]=s;
+           S[j][3]=v;
+           l=j;
+           while(l+p<=2*c+1)
+           {
+              l=l+p;
+              f=S[l][2];
+              v=S[l][3];
+              s=0;
+              while((f mod p)==0)
+              {
+                s++;
+                f=f div p;
+              }
+              S[l][2]=f;
+              v[i]=s;
+              S[l][3]=v;
+           }
+         }
+         j++;
+      }
+   }
+   list T;
+   for(j=1;j<=2*c+1;j++)
+   {
+      if((S[j][2]==1)||(S[j][2]==-1))
+      {
+         T[size(T)+1]=S[j];
+      }
+   }
+
+//the system of equations for the exponents {l_s} for the f(s) such
+//product f(s)^l_s is a square (l_s are 1 or 0)
+   bigintmat M[k+1][size(T)];
+   for(j=1;j<=size(T);j++)
+   {
+      if(T[j][2]==-1){M[1,j]=1;}
+      for(i=1;i<=k;i++)
+      {
+         M[i+1,j]=T[j][3][i];
+      }
+   }
+   intmat G=solutionsMod2(M);
+
+//construction of x and y such that x^2=y^2 mod n and d=gcd(x-y,n)
+//y=square root of product f(s)^l_s
+//x=product s+m
+   bigint x=1;
+   bigint y=1;
+
+   for(i=1;i<=ncols(G);i++)
+   {
+      kill v;
+      intvec v;
+      v[k]=0;
+      for(j=1;j<=size(T);j++)
+      {
+         x=x*T[j][1]^G[j,i] mod n;
+         if((T[j][2]==-1)&&(G[j,i]==1)){y=-y;}
+         v=v+G[j,i]*T[j][3];
+
+      }
+      for(l=1;l<=k;l++)
+      {
+         y=y*B[l]^(v[l] div 2) mod n;
+      }
+      d=gcd(x-y,n);
+      if((d>1)&&(d<n)){return(d);}
+   }
+   return("no divisor found");
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   list L=primList(5000);
+   quadraticSieve(7429,3,L,4);
+   quadraticSieve(1241143,100,L,50);
+}
+
+//======================================================================
+//==================== elliptic curves  ================================
+//======================================================================
+
+//================= elementary operations ==============================
+
+proc isOnCurve(bigint N, bigint a, bigint b, list P)
+"USAGE:  isOnCurve(N,a,b,P);
+RETURN: 1 or 0 (depending on whether P is on the curve or not)
+NOTE: checks whether P=(P[1]:P[2]:P[3]) is a point on the elliptic
+      curve defined by y^2z=x^3+a*xz^2+b*z^3  over Z/N
+EXAMPLE:example isOnCurve; shows an example
+"
+{
+   if(((P[2]^2*P[3]-P[1]^3-a*P[1]*P[3]^2-b*P[3]^3) mod N)!=0){return(0);}
+   return(1);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   isOnCurve(32003,5,7,list(10,16,1));
+}
+
+proc ellipticAdd(bigint N, bigint a, bigint b, list P, list Q)
+"USAGE:  ellipticAdd(N,a,b,P,Q);
+RETURN: list L, representing the point P+Q
+NOTE: P=(P[1]:P[2]:P[3]), Q=(Q[1]:Q[2]:Q[3]) points on the elliptic curve
+      defined by y^2z=x^3+a*xz^2+b*z^3  over Z/N
+EXAMPLE:example ellipticAdd; shows an example
+"
+{
+   if(N==2){ERROR("not implemented for 2");}
+   int i;
+   for(i=1;i<=3;i++)
+   {
+      P[i]=P[i] mod N; if (P[i]<0) { P[i]=P[i]+N:}
+      Q[i]=Q[i] mod N; if (Q[i]<0) { Q[i]=Q[i]+N;}
+   }
+   list Resu;
+   Resu[1]=bigint(0);
+   Resu[2]=bigint(1);
+   Resu[3]=bigint(0);
+   list Error;
+   Error[1]=0;
+   //test for ellictic curve
+   bigint D=4*a^3+27*b^2;
+   bigint g=gcd(D,N);
+   if(g==N){return(Error);}
+   if(g!=1)
+   {
+      P[4]=g;
+      return(P);
+   }
+   if(((P[1]==0)&&(P[2]==0)&&(P[3]==0))||((Q[1]==0)&&(Q[2]==0)&&(Q[3]==0)))
+   {
+      Error[1]=-2;
+      return(Error);
+   }
+   if(!isOnCurve(N,a,b,P)||!isOnCurve(N,a,b,Q))
+   {
+      Error[1]=-1;
+      return(Error);
+   }
+   if(P[3]==0){return(Q);}
+   if(Q[3]==0){return(P);}
+   list I=extgcd(P[3],N);
+   if(I[1]!=1)
+   {
+      P[4]=I[1];
+      return(P);
+   }
+   P[1]=P[1]*I[2] mod N;
+   P[2]=P[2]*I[2] mod N;
+   I=extgcd(Q[3],N);
+   if(I[1]!=1)
+   {
+      P[4]=I[1];
+      return(P);
+   }
+   Q[1]=Q[1]*I[2] mod N;
+   Q[2]=Q[2]*I[2] mod N;
+   if((P[1]==Q[1])&&(((P[2]+Q[2]) mod N)==0)){return(Resu);}
+   bigint L;
+   if((P[1]==Q[1])&&(P[2]==Q[2]))
+   {
+      I=extgcd(2*Q[2],N);
+      if(I[1]!=1)
+      {
+         P[4]=I[1];
+         return(P);
+      }
+      L=I[2]*(3*Q[1]^2+a) mod N;
+   }
+   else
+   {
+      I=extgcd(Q[1]-P[1],N);
+      if(I[1]!=1)
+      {
+         P[4]=I[1];
+         return(P);
+      }
+      L=(Q[2]-P[2])*I[2] mod N;
+   }
+   Resu[1]=(L^2-P[1]-Q[1]) mod N;
+   if (Resu[1]<0) { Resu[1]=Resu[1]+N; }
+   Resu[2]=(L*(P[1]-Resu[1])-P[2]) mod N;
+   if (Resu[2]<0) { Resu[2]=Resu[2]+N; }
+   Resu[3]=bigint(1);
+   return(Resu);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   bigint N=11;
+   bigint a=1;
+   bigint b=6;
+   list P,Q;
+   P[1]=2;
+   P[2]=4;
+   P[3]=1;
+   Q[1]=3;
+   Q[2]=5;
+   Q[3]=1;
+   ellipticAdd(N,a,b,P,Q);
+}
+
+proc ellipticMult(bigint N, bigint a, bigint b, list P, bigint k)
+"USAGE:  ellipticMult(N,a,b,P,k);
+RETURN: a list L representing the point k*P
+NOTE:  P=(P[1]:P[2]:P[3]) a point on the elliptic curve defined by
+       y^2z=x^3+a*xz^2+b*z^3  over Z/N
+EXAMPLE:example ellipticMult; shows an example
+"
+{
+   if(P[3]==0){return(P);}
+   list resu;
+   resu[1]=bigint(0);
+   resu[2]=bigint(1);
+   resu[3]=bigint(0);
+
+   if(k==0){return(resu);}
+   if(k==1){return(P);}
+   if(k==2){return(ellipticAdd(N,a,b,P,P));}
+   if(k==-1)
+   {
+      resu=P;
+      resu[2]=N-P[2];
+      return(resu);
+   }
+   if(k<0)
+   {
+      resu=ellipticMult(N,a,b,P,-k);
+      return(ellipticMult(N,a,b,resu,-1));
+   }
+   if((k mod 2)==0)
+   {
+      resu=ellipticMult(N,a,b,P,k/2);
+      return(ellipticAdd(N,a,b,resu,resu));
+   }
+   resu=ellipticMult(N,a,b,P,k-1);
+   return(ellipticAdd(N,a,b,resu,P));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   bigint N=11;
+   bigint a=1;
+   bigint b=6;
+   list P;
+   P[1]=2;
+   P[2]=4;
+   P[3]=1;
+   ellipticMult(N,a,b,P,3);
+}
+
+//================== Random for elliptic curves =====================
+
+proc ellipticRandomCurve(bigint N)
+"USAGE:  ellipticRandomCurve(N);
+RETURN: a list of two random numbers a,b and 4a^3+27b^2 mod N
+NOTE:   y^2z=x^3+a*xz^2+b^2*z^3 defines an elliptic curve over Z/N
+EXAMPLE:example ellipticRandomCurve; shows an example
+"
+{
+   int k;
+   while(k<=10)
+   {
+     k++;
+     bigint a=random(1,2147483647) mod N;
+     bigint b=random(1,2147483647) mod N;
+     //test for ellictic curve
+     bigint D=4*a^3+27*b^4; //the constant term is b^2
+     bigint g=gcd(D,N);
+     if(g<N){return(list(a,b,g));}
+   }
+   ERROR("no random curve found");
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ellipticRandomCurve(32003);
+}
+
+proc ellipticRandomPoint(bigint N, bigint a, bigint b)
+"USAGE:  ellipticRandomPoint(N,a,b);
+RETURN: a list representing  a random point (x:y:z) of the elliptic curve
+        defined by y^2z=x^3+a*xz^2+b*z^3  over Z/N
+EXAMPLE:example ellipticRandomPoint; shows an example
+"
+{
+   bigint x=random(1,2147483647) mod N;
+   bigint h=x^3+a*x+b;
+   h=h mod N;
+   list resu;
+   resu[1]=x;
+   resu[2]=0;
+   resu[3]=1;
+   if(h==0){return(resu);}
+
+   bigint n=Jacobi(h,N);
+   if(n==0)
+   {
+      resu=-5;
+      "N is not prime";
+      return(resu);
+   }
+   if(n==1)
+   {
+      resu[2]=squareRoot(h,N);
+      return(resu);
+   }
+   return(ellipticRandomPoint(N,a,b));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ellipticRandomPoint(32003,3,181);
+}
+
+
+
+//====================================================================
+//======== counting the points of an elliptic curve  =================
+//====================================================================
+
+//==================   the trivial approaches  =======================
+proc countPoints(bigint N, bigint a, bigint b)
+"USAGE:  countPoints(N,a,b);
+RETURN: the number of points of the elliptic curve defined by
+        y^2=x^3+a*x+b  over Z/N
+NOTE: trivial approach
+EXAMPLE:example countPoints; shows an example
+"
+{
+  bigint x;
+  bigint r=N+1;
+  while(x<N)
+  {
+     r=r+Jacobi((x^3+a*x+b) mod N,N);
+     x=x+1;
+  }
+  return(r);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   countPoints(181,71,150);
+}
+
+proc ellipticAllPoints(bigint N, bigint a, bigint b)
+"USAGE:  ellipticAllPoints(N,a,b);
+RETURN: list of points (x:y:z) of the elliptic curve defined by
+        y^2z=x^3+a*xz^2+b*z^3  over Z/N
+EXAMPLE:example ellipticAllPoints; shows an example
+"
+{
+   list resu,point;
+   point[1]=0;
+   point[2]=1;
+   point[3]=0;
+   resu[1]=point;
+   point[3]=1;
+   bigint x,h,n;
+   while(x<N)
+   {
+      h=(x^3+a*x+b) mod N;
+      if(h==0)
+      {
+         point[1]=x;
+         point[2]=0;
+         resu[size(resu)+1]=point;
+      }
+      else
+      {
+         n=Jacobi(h,N);
+         if(n==1)
+         {
+            n=squareRoot(h,N);
+            point[1]=x;
+            point[2]=n;
+            resu[size(resu)+1]=point;
+            point[2]=N-n;
+            resu[size(resu)+1]=point;
+         }
+      }
+      x=x+1;
+   }
+   return(resu);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   list L=ellipticAllPoints(181,71,150);
+   size(L);
+   L[size(L)];
+}
+
+//================ the algorithm of Shanks and Mestre =================
+
+proc ShanksMestre(bigint q, bigint a, bigint b, list #)
+"USAGE:  ShanksMestre(q,a,b); optional: ShanksMestre(q,a,b,s); s the number
+         of loops in the algorithm (default s=1)
+RETURN: the number of points of the elliptic curve defined by
+         y^2=x^3+a*x+b  over Z/N
+NOTE: algorithm of Shanks and Mestre (baby-step-giant-step)
+EXAMPLE:example ShanksMestre; shows an example
+"
+{
+   bigint n=intRoot(4*q);
+   bigint m=intRoot(intRoot(16*q))+1;
+   bigint d;
+   int i,j,k,s;
+   list B,K,T,P,Q,R,mP;
+   B[1]=list(0,1,0);
+   if(size(#)>0)
+   {
+      s=#[1];
+   }
+   else
+   {
+      s=1;
+   }
+   while(k<s)
+   {
+      P =ellipticRandomPoint(q,a,b);
+      Q =ellipticMult(q,a,b,P,n+q+1);
+
+      while(j<m)
+      {
+         j++;
+         B[j+1]=ellipticAdd(q,a,b,P,B[j]);  //baby-step list
+      }
+      mP=ellipticAdd(q,a,b,P,B[j]);
+      mP[2]=q-mP[2];
+      while(i<m)                            //giant-step
+      {
+         j=0;
+         while(j<m)
+         {
+            j++;
+            if((Q[1]==B[j][1])&&(Q[2]==B[j][2])&&(Q[3]==B[j][3]))
+            {
+               T[1]=P;
+               T[2]=q+1+n-(i*m+j-1);
+               K[size(K)+1]=T;
+               if(size(K)>1)
+               {
+                  if(K[size(K)][2]!=K[size(K)-1][2])
+                  {
+                     d=gcd(K[size(K)][2],K[size(K)-1][2]);
+                     if(ellipticMult(q,a,b,K[size(K)],d)[3]==0)
+                     {
+                       K[size(K)][2]=K[size(K)-1][2];
+                     }
+                  }
+               }
+               i=int(m);
+               break;
+            }
+         }
+         i=i+1;
+         Q=ellipticAdd(q,a,b,mP,Q);
+      }
+      k++;
+   }
+   if(size(K)>0)
+   {
+      int te=1;
+      for(i=1;i<=size(K)-1;i++)
+      {
+         if(K[size(K)][2]!=K[i][2])
+         {
+           if(ellipticMult(q,a,b,K[i],K[size(K)][2])[3]!=0)
+           {
+             te=0;
+             break;
+           }
+         }
+      }
+      if(te)
+      {
+         return(K[size(K)][2]);
+      }
+   }
+   return(ShanksMestre(q,a,b,s));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ShanksMestre(32003,71,602);
+}
+
+//==================== Schoof's algorithm =============================
+
+proc Schoof(bigint N,bigint a, bigint b)
+"USAGE:  Schoof(N,a,b);
+RETURN: the number of points of the elliptic curve defined by
+        y^2=x^3+a*x+b  over Z/N
+NOTE:  algorithm of Schoof
+EXAMPLE:example Schoof; shows an example
+"
+{
+   int pr=printlevel;
+//test for ellictic curve
+   bigint D=4*a^3+27*b^2;
+   bigint G=gcd(D,N);
+   if(G==N){ERROR("not an elliptic curve");}
+   if(G!=1){ERROR("not a prime");}
+
+//=== small N
+  // if((N<=500)&&(pr<5)){return(countPoints(int(N),a,b));}
+
+//=== the general case
+   bigint q=intRoot(4*N);
+   list L=primL(2*q);
+   int r=size(L);
+   list T;
+   int i,j;
+   for(j=1;j<=r;j++)
+   {
+      T[j]=(testElliptic(int(N),a,b,L[j])+int(q)) mod L[j];
+   }
+   if(pr>=5)
+   {
+      "===================================================================";
+      "Chinese remainder :";
+      for(i=1;i<=size(T);i++)
+      {
+         " x =",T[i]," mod ",L[i];
+      }
+      "gives t+ integral part of the square root of q (to be positive)";
+      chineseRem(T,L);
+      "we obtain t = ",chineseRem(T,L)-q;
+      "===================================================================";
+   }
+   bigint t=chineseRem(T,L)-q;
+   return(N+1-t);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   Schoof(32003,71,602);
+}
+
+/*
+needs 518 sec
+Schoof(2147483629,17,3567);
+2147168895
+*/
+
+
+proc generateG(number a,number b, int m)
+"USAGE:  generateG(a,b,m);
+RETURN: m-th division polynomial
+NOTE: generate the so-called division polynomials, i.e., the recursively defined
+polynomials p_m=generateG(a,b,m) in Z[x, y] such that, for a point (x:y:1) on the
+elliptic curve defined by y^2=x^3+a*x+b  over Z/N the point@*
+m*P=(x-(p_(m-1)*p_(m+1))/p_m^2 :(p_(m+2)*p_(m-1)^2-p_(m-2)*p_(m+1)^2)/4y*p_m^3 :1)
+and m*P=0 if and only if p_m(P)=0
+EXAMPLE:example generateG; shows an example
+"
+{
+   if(m==0){return(poly(0));}
+   if(m==1){return(poly(1));}
+   if(m==2){return(2*var(1));}
+   if(m==3){return(3*var(2)^4+6*a*var(2)^2+12*b*var(2)-a^2);}
+   if(m==4)
+   {
+      return(4*var(1)*(var(2)^6+5*a*var(2)^4+20*b*var(2)^3-5*a^2*var(2)^2
+        -4*a*b*var(2)-8*b^2-a^3));
+   }
+   if((m mod 2)==0)
+   {
+      return((generateG(a,b,m div 2+2)*generateG(a,b,m div 2-1)^2
+        -generateG(a,b,m div 2-2)*generateG(a,b,m div 2+1)^2)
+        *generateG(a,b,m div 2)/(2*var(1)));
+   }
+   return(generateG(a,b,(m-1) div 2+2)*generateG(a,b,(m-1) div 2)^3
+     -generateG(a,b,(m-1) div 2-1)*generateG(a,b,(m-1) div 2+1)^3);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring R = 0,(x,y),dp;
+   generateG(7,15,4);
+}
+
+
+static proc testElliptic(int q,bigint aa,bigint bb,int l)
+"USAGE:  testElliptic(q,a,b,l);
+RETURN: an integer t, the trace of the Frobenius
+NOTE: the kernel for the Schoof algorithm: looks for the t such that for all
+      points (x:y:1) in C[l]={P in C | l*P=0},C the elliptic curve defined by
+      y^2=x^3+a*x+b  over Z/q with group structure induced by 0=(0:1:0),
+      (x:y:1)^(q^2)-t*(x:y:1)^q -ql*(x:y:1)=(0:1:0), ql= q mod l, trace of
+      Frobenius.
+EXAMPLE:example testElliptic; shows an example
+"
+{
+   int pr=printlevel;
+   ring S=q,(y,x),(L(100000),lp);
+   number a=aa;
+   number b=bb;
+   poly F=y2-x3-a*x-b;       // the curve C
+   poly G=generateG(a,b,l);
+   ideal I=std(ideal(F,G));  // the points C[l]
+   poly xq=powerX(q,2,I);
+   poly yq=powerX(q,1,I);
+   poly xq2=reduce(subst(xq,x,xq,y,yq),I);
+   poly yq2=reduce(subst(yq,x,xq,y,yq),I);
+   ideal J;
+   int ql=q mod l;
+   if(ql==0){ERROR("q is not prime");}
+   int t;
+   poly F1,F2,G1,G2,P1,P2,Q1,Q2,H1,H2,L1,L2;
+
+   if(pr>=5)
+   {
+      "===================================================================";
+      "q=",q;
+      "l=",l;
+      "q mod l=",ql;
+      "the Groebner basis for C[l]:";I;
+      "x^q mod I = ",xq;
+      "x^(q^2) mod I = ",xq2;
+      "y^q mod I = ",yq;
+      "y^(q^2) mod I = ",yq2;
+      pause();
+   }
+   //==== l=2 =============================================================
+   if(l==2)
+   {
+      xq=powerX(q,2,std(x3+a*x+b));
+      J=std(ideal(xq-x,x3+a*x+b));
+      if(deg(J[1])==0){t=1;}
+      if(pr>=5)
+      {
+         "===================================================================";
+         "the case l=2";
+         "the gcd(x^q-x,x^3+ax+b)=",J[1];
+         pause();
+      }
+      return(t);
+   }
+   //=== (F1/G1,F2/G2)=[ql](x,y) ==========================================
+   if(ql==1)
+   {
+      F1=x;G1=1;F2=y;G2=1;
+   }
+   else
+   {
+      G1=reduce(generateG(a,b,ql)^2,I);
+      F1=reduce(x*G1-generateG(a,b,ql-1)*generateG(a,b,ql+1),I);
+      G2=reduce(4*y*generateG(a,b,ql)^3,I);
+      F2=reduce(generateG(a,b,ql+2)*generateG(a,b,ql-1)^2
+               -generateG(a,b,ql-2)*generateG(a,b,ql+1)^2,I);
+
+   }
+   if(pr>=5)
+   {
+      "===================================================================";
+      "the point ql*(x,y)=(F1/G1,F2/G2)";
+      "F1=",F1;
+      "G1=",G1;
+      "F2=",F2;
+      "G2=",G2;
+      pause();
+   }
+   //==== the case t=0 :  the equations for (x,y)^(q^2)=-[ql](x,y) ===
+   J[1]=xq2*G1-F1;
+   J[2]=yq2*G2+F2;
+   if(pr>=5)
+   {
+      "===================================================================";
+      "the case t=0 mod l";
+      "the equations for (x,y)^(q^2)=-[ql](x,y) :";
+      J;
+      "the test, if they vanish for all points in C[l]:";
+      reduce(J,I);
+      pause();
+   }
+   //=== test if all points of C[l] satisfy  (x,y)^(q^2)=-[ql](x,y)
+   //=== if so: t mod l =0 is returned
+   if(size(reduce(J,I))==0){return(0);}
+
+   //==== test for (x,y)^(q^2)=[ql](x,y) for some point
+
+   J=xq2*G1-F1,yq2*G2-F2;
+   J=std(J+I);
+   if(pr>=5)
+   {
+      "===================================================================";
+      "test if (x,y)^(q^2)=[ql](x,y) for one point";
+      "if so, the Frobenius has an eigenvalue 2ql/t: (x,y)^q=(2ql/t)*(x,y)";
+      "it follows that t^2=4q mod l";
+      "if w is one square root of q mod l";
+      "t =2w mod l or -2w mod l ";
+      "-------------------------------------------------------------------";
+      "the equations for (x,y)^(q^2)=[ql](x,y) :";
+      xq2*G1-F1,yq2*G2-F2;
+      "the test if one point satisfies them";
+      J;
+      pause();
+   }
+   if(deg(J[1])>0)
+   {
+      int w=int(squareRoot(q,l));
+      //=== +/-2w mod l zurueckgeben, wenn (x,y)^q=+/-[w](x,y)
+      //==== the case t>0 :  (Q1/P1,Q2/P2)=[w](x,y) ==============
+      if(w==1)
+      {
+         Q1=x;P1=1;Q2=y;P2=1;
+      }
+      else
+      {
+         P1=reduce(generateG(a,b,w)^2,I);
+         Q1=reduce(x*G1-generateG(a,b,w-1)*generateG(a,b,w+1),I);
+         P2=reduce(4*y*generateG(a,b,w)^3,I);
+         Q2=reduce(generateG(a,b,w+2)*generateG(a,b,w-1)^2
+               -generateG(a,b,w-2)*generateG(a,b,w+1)^2,I);
+      }
+      J=xq*P1-Q1,yq*P2-Q2;
+      J=std(I+J);
+      if(pr>=5)
+      {
+      "===================================================================";
+      "the Frobenius has an eigenvalue, one of the roots of  w^2=q mod l:";
+      "one root is:";w;
+      "test, if it is the eigenvalue (if not it must be -w):";
+      "the equations for (x,y)^q=w*(x,y)";I;xq*P1-Q1,yq*P2-Q2;
+      "the Groebner basis";
+       J;
+         pause();
+      }
+      if(deg(J[1])>0){return(2*w mod l);}
+      return(-2*w mod l);
+   }
+
+   //==== the case t>0 :  (Q1/P1,Q2/P2)=(x,y)^(q^2)+[ql](x,y) =====
+   P1=reduce(G1*G2^2*(F1-xq2*G1)^2,I);
+   Q1=reduce((F2-yq2*G2)^2*G1^3-F1*G2^2*(F1-xq2*G1)^2-xq2*P1,I);
+   P2=reduce(P1*G2*(F1-xq2*G1),I);
+   Q2=reduce((xq2*P1-Q1)*(F2-yq2*G2)*G1-yq2*P2,I);
+
+   if(pr>=5)
+   {
+      "we are in the general case:";
+      "(x,y)^(q^2)!=ql*(x,y) and (x,y)^(q^2)!=-ql*(x,y) ";
+      "the point (Q1/P1,Q2/P2)=(x,y)^(q^2)+[ql](x,y)";
+      "Q1=",Q1;
+      "P1=",P1;
+      "Q2=",Q2;
+      "P2=",P2;
+      pause();
+   }
+   while(t<(l-1) div 2)
+   {
+      t++;
+      //====  (H1/L1,H2/L2)=[t](x,y)^q ===============================
+      if(t==1)
+      {
+         H1=xq;L1=1;
+         H2=yq;L2=1;
+      }
+      else
+      {
+         H1=x*generateG(a,b,t)^2-generateG(a,b,t-1)*generateG(a,b,t+1);
+         H1=subst(H1,x,xq,y,yq);
+         H1=reduce(H1,I);
+         L1=generateG(a,b,t)^2;
+         L1=subst(L1,x,xq,y,yq);
+         L1=reduce(L1,I);
+         H2=generateG(a,b,t+2)*generateG(a,b,t-1)^2
+           -generateG(a,b,t-2)*generateG(a,b,t+1)^2;
+         H2=subst(H2,x,xq,y,yq);
+         H2=reduce(H2,I);
+         L2=4*y*generateG(a,b,t)^3;
+         L2=subst(L2,x,xq,y,yq);
+         L2=reduce(L2,I);
+      }
+      J=Q1*L1-P1*H1,Q2*L2-P2*H2;
+      if(pr>=5)
+      {
+      "we test now the different t, 0<t<=(l-1)/2:";
+      "the point (H1/L1,H2/L2)=[t](x,y)^q :";
+      "H1=",H1;
+      "L1=",L1;
+      "H2=",H2;
+      "L2=",L2;
+      "the equations for (x,y)^(q^2)+[ql](x,y)=[t](x,y)^q :";J;
+      "the test";reduce(J,I);
+      "the test for l-t (the x-cordinate is the same):";
+       Q1*L1-P1*H1,Q2*L2+P2*H2;
+       reduce(ideal(Q1*L1-P1*H1,Q2*L2+P2*H2),I);
+         pause();
+      }
+      if(size(reduce(J,I))==0){return(t);}
+      J=Q1*L1-P1*H1,Q2*L2+P2*H2;
+      if(size(reduce(J,I))==0){return(l-t);}
+   }
+   ERROR("something is wrong in testElliptic");
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   testElliptic(1267985441,338474977,64740730,3);
+}
+
+//============================================================================
+//================== Factorization and Primality Test ========================
+//============================================================================
+
+//============= Lenstra's ECM Factorization ==================================
+
+proc factorLenstraECM(bigint N, list S, int B, list #)
+"USAGE:  factorLenstraECM(N,S,B); optional: factorLenstraECM(N,S,B,d);
+         d+1 the number of loops in the algorithm (default d=0)
+RETURN: a factor of N or the message no factor found
+NOTE: - computes a factor of N using Lenstra's ECM factorization@*
+      - the idea is that the fact that N is not prime is dedected using
+        the operations on the elliptic curve
+      - is similarly to Pollard's p-1-factorization
+EXAMPLE:example factorLenstraECM; shows an example
+"
+{
+   list L,P;
+   bigint g,M,w;
+   int i,j,k,d;
+   int l=size(S);
+   if(size(#)>0)
+   {
+      d=#[1];
+   }
+
+   while(i<=d)
+   {
+      L=ellipticRandomCurve(N);
+      if(L[3]>1){return(L[3]);} //the discriminant was not invertible
+      P=list(0,L[2],1);
+      j=0;
+      M=1;
+      while(j<l)
+      {
+         j++;
+         w=S[j];
+         if(w>B) break;
+         while(w*S[j]<B)
+         {
+           w=w*S[j];
+         }
+         M=M*w;
+         P=ellipticMult(N,L[1],L[2]^2,P,w);
+         if(size(P)==4){return(P[4]);}  //some inverse did not exsist
+         if(P[3]==0){break;}            //the case M*P=0
+      }
+      i++;
+   }
+   return("no factor found");
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   list L=primList(1000);
+   factorLenstraECM(181*32003,L,10,5);
+   bigint h=10;
+   h=h^30+25;
+   factorLenstraECM(h,L,4,3);
+}
+
+//================= ECPP (Goldwasser-Kilian) a primaly-test =============
+
+proc ECPP(bigint N)
+"USAGE:  ECPP(N);
+RETURN: message:N is not prime or {L,P,m,q} as certificate for N being prime@*
+         L a list (y^2=x^3+L[1]*x+L[2] defines an elliptic curve C)@*
+         P a list ((P[1]:P[2]:P[3]) is a point of C)@*
+         m,q integers
+ASSUME: gcd(N,6)=1
+NOTE:   The basis of the algorithm is the following theorem:
+         Given C, an elliptic curve over Z/N, P a point of C(Z/N),
+         m an integer, q a prime with the following properties:
+         - q|m
+         - q>(4-th root(N) +1)^2
+         - m*P=0=(0:1:0)
+         - (m/q)*P=(x:y:z) and z a unit in Z/N
+         Then N is prime.
+EXAMPLE:example ECPP; shows an example
+"
+{
+   list L,S,P;
+   bigint m,q;
+   int i;
+
+   bigint n=intRoot(intRoot(N));
+   n=(n+1)^2;                         //lower bound for q
+   while(1)
+   {
+      L=ellipticRandomCurve(N);       //a random elliptic curve C
+      m=ShanksMestre(N,L[1],L[2],3);  //number of points of the curve C
+      S=PollardRho(m,10000,1);        //factorization of m
+      for(i=1;i<=size(S);i++)         //search for q between the primes
+      {
+         q=S[i];
+         if(n<q){break;}
+      }
+      if(n<q){break;}
+   }
+   bigint u=m/q;
+   while(1)
+   {
+      P=ellipticRandomPoint(N,L[1],L[2]);  //a random point on C
+      "P=",P;
+      if(ellipticMult(N,L[1],L[2],P,m)[3]!=0){"N is not prime";return(-5);}
+      if(ellipticMult(N,L[1],L[2],P,u)[3]!=0)
+      {
+         L=delete(L,3);
+         return(list(L,P,m,q));
+      }
+   }
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   bigint N=1267985441;
+   ECPP(N);
+}
+
+static proc wordToNumber(string s)
+{
+   int i;
+   intvec v;
+   bigint n;
+   bigint t=27;
+   for(i=size(s);i>0;i--)
+   {
+      if(s[i]=="a"){v[i]=0;}
+      if(s[i]=="b"){v[i]=1;}
+      if(s[i]=="c"){v[i]=2;}
+      if(s[i]=="d"){v[i]=3;}
+      if(s[i]=="e"){v[i]=4;}
+      if(s[i]=="f"){v[i]=5;}
+      if(s[i]=="g"){v[i]=6;}
+      if(s[i]=="h"){v[i]=7;}
+      if(s[i]=="i"){v[i]=8;}
+      if(s[i]=="j"){v[i]=9;}
+      if(s[i]=="k"){v[i]=10;}
+      if(s[i]=="l"){v[i]=11;}
+      if(s[i]=="m"){v[i]=12;}
+      if(s[i]=="n"){v[i]=13;}
+      if(s[i]=="o"){v[i]=14;}
+      if(s[i]=="p"){v[i]=15;}
+      if(s[i]=="q"){v[i]=16;}
+      if(s[i]=="r"){v[i]=17;}
+      if(s[i]=="s"){v[i]=18;}
+      if(s[i]=="t"){v[i]=19;}
+      if(s[i]=="u"){v[i]=20;}
+      if(s[i]=="v"){v[i]=21;}
+      if(s[i]=="w"){v[i]=22;}
+      if(s[i]=="x"){v[i]=23;}
+      if(s[i]=="y"){v[i]=24;}
+      if(s[i]=="z"){v[i]=25;}
+      if(s[i]==" "){v[i]=26;}
+   }
+   for(i=1;i<=size(s);i++)
+   {
+      n=n+v[i]*t^(i-1);
+   }
+   return(n);
+}
+
+static proc numberToWord(bigint n)
+{
+   int i,j;
+   string v;
+   list s;
+   bigint t=27;
+   bigint mm;
+   bigint nn=n;
+   while(nn>t)
+   {
+      j++;
+      mm=nn mod t;
+      s[j]=mm;
+      nn=(nn-mm) div t;
+   }
+   j++;
+   s[j]=nn;
+   for(i=1;i<=j;i++)
+   {
+      if(s[i]==0){v=v+"a";}
+      if(s[i]==1){v=v+"b";}
+      if(s[i]==2){v=v+"c";}
+      if(s[i]==3){v=v+"d";}
+      if(s[i]==4){v=v+"e";}
+      if(s[i]==5){v=v+"f";}
+      if(s[i]==6){v=v+"g";}
+      if(s[i]==7){v=v+"h";}
+      if(s[i]==8){v=v+"i";}
+      if(s[i]==9){v=v+"j";}
+      if(s[i]==10){v=v+"k";}
+      if(s[i]==11){v=v+"l";}
+      if(s[i]==12){v=v+"m";}
+      if(s[i]==13){v=v+"n";}
+      if(s[i]==14){v=v+"o";}
+      if(s[i]==15){v=v+"p";}
+      if(s[i]==16){v=v+"q";}
+      if(s[i]==17){v=v+"r";}
+      if(s[i]==18){v=v+"s";}
+      if(s[i]==19){v=v+"t";}
+      if(s[i]==20){v=v+"u";}
+      if(s[i]==21){v=v+"v";}
+      if(s[i]==22){v=v+"w";}
+      if(s[i]==23){v=v+"x";}
+      if(s[i]==24){v=v+"y";}
+      if(s[i]==25){v=v+"z";}
+      if(s[i]==26){v=v+" ";}
+   }
+   return(v);
+}
+
+proc code(string s)
+"USAGE:  code(s); s a string
+ASSUME:  s contains only small letters and space
+COMPUTE: a bigint, RSA-coding of the string s
+RETURN:  return RSA-coding of the string s as string
+EXAMPLE: code;  shows an example
+"
+{
+   ring r=0,x,dp;
+   bigint
+p=398075086424064937397125500550386491199064362342526708406385189575946388957261768583317;
+   bigint
+q=472772146107435302536223071973048224632914695302097116459852171130520711256363590397527;
+   bigint n=p*q;
+   bigint phi=(p-1)*(q-1);
+   bigint e=1234567891;
+   //bigint d=extgcd(e,phi)[2];
+   bigint m=wordToNumber(s);
+   bigint c=powerN(m,e,n);
+   string cc=string(c);
+   return(cc);
+}
+example
+{"EXAMPLE:";  echo = 2;
+  string s="i go to school";
+  code(s);
+}
+
+proc decodeString(string g)
+"USAGE:  decodeString(s); s a string
+ASSUME:  s is a string of a bigint, the output of code
+COMPUTE: a string, RSA-decoding of the string s
+RETURN:  return RSA-decoding of the string s as string
+EXAMPLE: decodeString;  shows an example
+"
+{
+   bigint
+p=398075086424064937397125500550386491199064362342526708406385189575946388957261768583317;
+   bigint
+q=472772146107435302536223071973048224632914695302097116459852171130520711256363590397527;
+   bigint n=p*q;
+   bigint phi=(p-1)*(q-1);
+   bigint e=1234567891;
+   bigint d=extgcd(e,phi)[2];
+   execute("bigint c="+g+";");
+   bigint f=powerN(c,d,n);
+   string s=numberToWord(f);
+   return(s);
+}
+example
+{"EXAMPLE:";  echo = 2;
+  string
+s="78638618599886548153321853785991541374544958648147340831959482696082179852616053583234149080198937632782579537867262780982185252913122030800897193851413140758915381848932565";
+  string t=decodeString(s);
+  t;
+}
+
+/*
+//===============================================================
+//=======  Example for DSA  =====================================
+//===============================================================
+Suppose a file test is given.It contains "Oscar".
+
+//Hash-function MD5 under Linux
+
+md5sum test           8edfe37dae96cfd2466d77d3884d4196
+
+//================================================================
+
+ring R=0,x,dp;
+
+number q=2^19+21;          //524309
+number o=2*3*23*number(7883)*number(16170811);
+
+number p=o*q+1;            //9223372036869000547
+number b=2;
+number g=power(2,o,p);     //8308467587808723131
+
+number a=111111;
+number A=power(g,a,p);     //8566038811843553785
+
+number h =decimal("8edfe37dae96cfd2466d77d3884d4196");
+
+                           //189912871665444375716340628395668619670
+h= h mod q;                //259847
+
+number k=123456;
+
+number ki=exgcd(k,q)[1];    //50804
+                            //inverse von k mod q
+
+number r= power(g,k,p) mod q;    //76646
+
+number s=ki*(h+a*r) mod q;       //2065
+
+//========== signatur is (r,s)=(76646,2065) =====================
+//==================== verification  ============================
+
+number si=exgcd(s,q)[1];  //inverse von s mod q
+number e1=si*h mod q;
+number e2=si*r mod q;
+number rr=((power(g,e1,p)*power(A,e2,p)) mod p) mod q;    //76646
+
+//===============================================================
+//=======  Example for knapsack  ================================
+//===============================================================
+ring R=(5^5,t),x,dp;
+R;
+//   # ground field : 3125
+//   primitive element : t
+//   minpoly        : 1*t^5+4*t^1+2*t^0
+//   number of vars : 1
+//        block   1 : ordering dp
+//                  : names    x
+//        block   2 : ordering C
+
+proc findEx(number n, number g)
+{
+   int i;
+   for(i=0;i<=size(basering)-1;i++)
+   {
+      if(g^i==n){return(i);}
+   }
+}
+
+number g=t^3;                       //choice of the primitive root
+
+findEx(t+1,g);
+//2091
+findEx(t+2,g);
+//2291
+findEx(t+3,g);
+//1043
+
+intvec b=1,2091,2291,1043;          // k=4
+int z=199;
+intvec v=1043+z,1+z,2091+z,2291+z;  //permutation   pi=(0123)
+v;
+1242,200,2290,2490
+
+//(1101)=(e_3,e_2,e_1,e_0)
+//encoding 2490+2290+1242=6022 und 1+1+0+1=3
+
+//(6022,3) decoding: c-z*c'=6022-199*3=5425
+
+ring S=5,x,dp;
+poly F=x5+4x+2;
+poly G=reduce((x^3)^5425,std(F));
+G;
+//x3+x2+x+1
+
+factorize(G);
+//[1]:
+//   _[1]=1
+//   _[2]=x+1
+//   _[3]=x-2
+//   _[4]=x+2
+//[2]:
+//   1,1,1,1
+
+//factors x+1,x+2,x+3, i.e.  (1110)=(e_pi(3),e_pi(2),e_pi(1),e_pi(0))
+
+//pi(0)=1,pi(1)=2,pi(2)=3,pi(3)=0 gives:  (1101)
+
+*/
+
diff --git a/Singular/LIB/curvepar.lib b/Singular/LIB/curvepar.lib
new file mode 100644
index 0000000..588ea74
--- /dev/null
+++ b/Singular/LIB/curvepar.lib
@@ -0,0 +1,1816 @@
+////////////////////////////////////////////////////////////////////////////////
+version="version curvepar.lib 4.0.0.0 Jun_2013 "; // $Id: 6132b803aac5fe11ce68c0a516c601f9ce70e756 $
+category="Singularity Theory";
+info="
+LIBRARY:  curvepar.lib  Resolution of space curve singularities, semi-group
+
+AUTHOR:     Gerhard Pfister    email: pfister at mathematik.uni-kl.de
+            Nil Sahin          email: e150916 at metu.edu.tr
+            Maryna Viazovska   email: viazovsk at mathematik.uni-kl.de
+
+SEE ALSO: spcurve_lib
+
+PROCEDURES:
+BlowingUp(f,I,l);             BlowingUp of V(I) at the point 0;
+CurveRes(I);                  Resolution of V(I)
+CurveParam(I);                Parametrization of algebraic branches of V(I)
+WSemigroup(X,b);              Weierstrass semigroup of the curve
+primparam(x,y,c);             HN matrix of parametrization(x(t),y(t))
+MultiplicitySequence(I);      Multiplicity sequences of the branches of plane curve V(I)
+CharacteristicExponents(I);   Characteristic exponents of the branches of plane curve V(I)
+IntersectionMatrix(I);        Intersection Matrix of the branches of plane curve V(I)
+ContactMatrix(I);             Contact Matrix of the branches of plane curve V(I)
+plainInvariants(I);           Invariants of the branches of plane curve V(I)
+";
+
+LIB "sing.lib";
+LIB "primdec.lib";
+LIB "linalg.lib";
+LIB "ring.lib";
+LIB "alexpoly.lib";
+LIB "matrix.lib";
+
+//////////////////////////////////////////////////////////////
+//----------Resolution of singular curve--------------------//
+//////////////////////////////////////////////////////////////
+
+proc BlowingUp(poly f,ideal I,list l,list #)
+"USAGE:   BlowingUp(f,I,l);
+          f=poly
+          b=ideal
+          l=list
+
+ASSUME:   The basering is r=0,(x(1..n),a),dp
+          f is an irrreducible polynomial in k[a],
+          I is an ideal of a curve(if we consider a as a parameter)
+
+COMPUTE:  Blowing-up of the curve at point 0.
+
+RETURN:   list C of charts.
+          Each chart C[i] is a list of size 5 (reps. 6 in case of plane curves)
+          C[i][1] is an integer j. It shows, which standard chart do we consider.
+          C[i][2] is an irreducible poly g in k[a]. It is a minimal polynomial
+                  for the new parameter.
+          C[i][3] is an ideal H in k[a].
+                  c_i=F_i(a_new) for i=1..n,
+                  a_old=H[n+1](a_new).
+          C[i][4] is a map teta:k[x(1)..x(n),a]-->k[x(1)..x(n),a] from the new
+                  curve to the old one.
+                  x(1)-->x(j)*x(1)
+                  . . .
+                  x(j)-->x(j)
+                  . . .
+                  x(n)-->x(j)*(c_n+x(n))
+          C[i][5] is an ideal J of a new curve. J=teta(I).
+          C[i][6] is the list of exceptional divisors in the chart
+
+EXAMPLE: example BlowingUp; shows an example"
+{
+  def r=basering;
+  int n=nvars(r)-1;
+  ring r1=(0,a),(x(1..n)),ds;
+  number f=leadcoef(imap(r,f));
+  minpoly=f;
+  ideal I=imap(r,I);
+  ideal locI=std(I);
+  ideal J=tangentcone(I);
+  setring r;
+  ideal J=imap(r1,J);
+  ideal locI=imap(r1,locI);
+  int j;
+  int i;
+  list C,E;
+  list C1;
+  ideal B;
+  poly g;
+  ideal F;
+  poly b,p;
+  list Z;
+  list Z1;
+  ideal D;
+  map teta;
+  ideal D1;
+  map teta1;
+  int k,e;
+  ideal I1;
+  ideal I2;
+  int ind;
+  list w=mlist(l,n);
+  for(j=1;j<=n;j++)
+  {
+    B=J;
+    for(i=1;i<j;i++) {B=B+x(w[i]);}
+    B=B+(x(w[j])-1);
+    B=B+f;
+    Z=Z1;
+    if(dim(std(B))==0)
+    {
+      Z=ZeroIdeal(B);
+      for(i=1;i<j;i++)
+      {
+        D[w[i]]=x(w[j])*x(w[i]);
+      }
+      D[w[j]]=x(w[j]);
+      for(i=j+1;i<=n;i++)
+      {
+        D[w[i]]=x(w[j])*x(w[i]);
+      }
+      D[n+1]=a;
+      teta=r,D;
+      I1=teta(locI);
+      I1=reduce(I1,std(f));
+      ind=1;
+      for(i=1;i<=size(I1);i++)
+      {
+        ind=1;
+        while(ind==1)
+        {
+          if(gcd(x(w[j]),I1[i])==x(w[j])){I1[i]=I1[i]/x(w[j]);}
+          else{ind=0;}
+        }
+      }
+    }
+    for(k=1;k<=size(Z);k++)
+    {
+      g=Z[k][1];
+      for(i=1;i<=n;i++){F[i]=Z[k][2][i];}
+      b=Z[k][3];
+      C1[1]=w[j];
+      C1[2]=g;
+      C1[3]=F;
+      for(i=1;i<j;i++)
+      {D[w[i]]=x(w[j])*x(w[i]);}
+      D[w[j]]=x(w[j]);
+      for(i=j+1;i<=n;i++)
+      {D[w[i]]=x(w[j])*(F[w[i]]+x(w[i]));}
+      D[n+1]=Z[k][2][n+1];
+      teta=r,D;
+      C1[4]=D;
+      for(i=1;i<=j;i++)
+      {D1[w[i]]=x(w[i]);}
+      for(i=j+1;i<=n;i++)
+      {D1[w[i]]=F[w[i]]+x(w[i]);}
+      D1[n+1]=a;
+      teta1=r,D1;
+      if(nvars(basering)==3)
+      {
+        I2=quickSubst(I1[1],teta1[1],teta1[2],std(g));
+      }
+      else
+      {
+        I2=teta1(I1);
+        I2=reduce(I2,std(g));
+      }
+      C1[5]=I2;
+      if(nvars(basering)==3)
+      {
+        if(size(#)>0)
+        {
+          E=#;
+          E=teta(E);
+          for(e=1;e<=size(E);e++)
+          {
+            p=E[e];
+            while(subst(p,x(w[j]),0)==0)
+            {
+              p=p/x(w[j]);
+            }
+            if((deg(E[e])>0)&&(deg(p)==0))
+            {
+              E[e]=size(E);
+            }
+            else
+            {
+              E[e]=p;
+            }
+          }
+          E[size(E)+1]=x(w[j]);
+          C1[6]=E;
+        }
+        else
+        {
+          C1[6]=list(x(w[j]));
+        }
+      }
+      C=insert(C,C1);
+    }
+  }
+  return(C);
+}
+example
+{
+  "EXAMPLE:";echo = 2;
+  ring r=0,(x(1..3),a),dp;
+  poly f=a2+1;
+  ideal i=x(1)^2+a*x(2)^3,x(3)^2-x(2);
+  list l=1,3,2;
+  list B=BlowingUp(f,i,l);
+  B;
+}
+//============= ACHTUNG ZeroIdeal ueberarbeiten / minAssGTZ rein  ========================
+//////////////////////////////////////////////////////////////////////////////////////////
+static proc ZeroIdeal(ideal J)
+
+"USAGE:   ZeroIdeal(J);
+          J=ideal
+
+ASSUME:   J is a zero-dimensional ideal in k[x(1),...,x(n)].
+
+COMPUTE:  Primary decomposition of radical(J). Each prime ideal J[i] has the form:
+          x(1)-f[1](b),...,x(n)-f[n](b),
+          f(b)=0, f irreducible
+          for some b=x(1)*a(1)+...+x(n)*a(n), a(i) in k.
+
+RETURN:   list Z of lists.
+          Each list Z[k] is a list of size 3
+          Z[k][1] is a poly f(b)
+          Z[k][2] is an ideal H, H[n]=f[n],
+          Z[k][3] is a poly x(1)*a(1)+...+x(n)*a(n)
+
+EXAMPLE:"
+{
+  intvec opt = option(get);
+  def r=basering;
+  int n=nvars(r);
+  if(dim(std(J))!=0){return(0);}
+  ring s=0,(x(1..n)),lp;
+  ideal A; ideal S; int i; int j;
+  for(i=1;i<=n;i++) {A[i]=x(i);}
+  map phi=r,A;
+  ideal J=phi(J);
+  ideal I=radical(J);
+  list D=zerodec(I);
+  list Z; ideal H; intvec w; intvec v; int ind; ideal T; map tau; int q; list u;
+  ideal Di; poly h;
+  for(i=1;i<=size(D);i++)
+  {
+    option(redSB);
+    ind=0;q=n;
+    while(ind==0 and q>0)
+    {
+      for(j=1;j<=n;j++){T[j]=x(j);}
+      T[q]=x(n);
+      T[n]=x(q);
+      tau=s,T;
+      Di=D[i];
+      S=std(tau(Di));
+      ind=1;
+      v=leadexp(S[1]);
+      if(leadmonom(S[1])!=x(n)^v[n]){ind=0;}
+      for(j=2;j<=n;j++)
+      {
+        if(leadmonom(S[j])!=x(n-j+1)){ind=0;}
+        H[n-j+1]= -S[j]/leadcoef(S[j])+x(n-j+1);
+        v=leadexp(H[n-j+1]);
+        if(leadcoef(H[n-j+1])*leadmonom(H[n-j+1])!=leadcoef(H[n-j+1])*x(n)^v[n])
+        {ind=0;}
+      }
+      if(ind==1)
+      {
+        u[1]=S[1];
+        H[n]=x(n);
+        H[n]=H[q];
+        H[q]=x(n);
+        u[2]=H;
+        u[3]=x(q);
+        Z[i]=u;
+      }
+      q--;
+    }
+    if(ind==0)
+    {
+      vector a;
+      while(ind==0)
+      {
+        h=x(n);
+        for(j=1;j<=n-1;j++){a=a+random(-10,10)*gen(j);h=h+a[j]*x(j);}
+        T=subst(S,x(n),h);
+        option(redSB);
+        T=std(T);
+        ind=1;
+        w=leadexp(T[1]);
+        if(leadmonom(T[1])!=x(n)^w[n]){ind=0;}
+        for(j=2;j<=n;j++)
+        {
+          if(leadmonom(T[j])!=x(n-j+1)){ind=0;}
+          H[n-j+1]= -T[j]/leadcoef(T[j])+x(n-j+1);
+          w=leadexp(H[n-j+1]);
+          if(leadmonom(H[n-j+1])*leadcoef(H[n-j+1])!=leadcoef(H[n-j+1])*x(n)^w[n])
+          {ind=0;}
+        }
+        if(ind==1)
+        {
+          list l;
+          l[1]=T[1];
+          H[n]=x(n);h=x(n);
+          for(j=1;j<=n-1;j++){H[n]=H[n]+a[j]*H[j];h=h-a[j]*x(j);}
+          l[2]=H;
+          l[3]=h;
+          Z[i]=l;
+        }
+      }
+    }
+  }
+  setring r;
+  ideal A;
+  list Z;
+  for(i=1;i<=n;i++)
+  {A[i]=var(i);}
+  map psi=s,A;
+  Z=psi(Z);
+  option(set, opt);
+  return(Z);
+}
+/////////////////////////////////////////////////////////////////////////////////////////////
+//assume that the basering is k[x(1),...,x(n),a]
+
+static proc main(ideal I,ideal Psi,poly f,list m,list l,list HN,intvec v,list HI,list #)
+{
+  def s=basering;
+  int i,z;
+  int j;
+  list C,E,resTree;
+  list C1;
+  list C2;
+  list C3;
+  list l1;
+  C2[8]=HI;
+  list m1;
+  list HN1;
+  ideal J;
+  map psi;
+  intvec w;
+  z=(SmoothTest(I,f)==1);
+  if((nvars(basering)==3)&&z&&(size(#)>0))
+  {
+    z=transversalTest(I,f,#);
+  }
+  if(z)
+  {
+    C2[1]=I;
+    C2[2]=Psi;
+    C2[3]=f;
+    C2[4]=m;
+    C2[5]=l;
+    C2[6]=HN;
+    if(nvars(basering)==3)
+    {
+      if(size(#)>0)
+      {
+        C2[9]=#;
+      }
+      C2[7]=v;
+    }
+    //C2[8][size(C2[8])+1]=list(C2[7],C2[9]);
+    C[1]=C2;
+  }
+  if(!z)
+  {
+    int mm=mmult(I,f);
+    m1=insert(m,mm,size(m));
+    if(nvars(basering)==3)
+    {
+      if(size(#)>0)
+      {
+        E=#;
+        C1=BlowingUp(f,I,l,E);
+      }
+      else
+      {
+        C1=BlowingUp(f,I,l);
+      }
+    }
+    else
+    {
+      C1=BlowingUp(f,I,l);
+    }
+    for(j=1;j<=size(C1);j++)
+    {
+      C2[1]=C1[j][5];
+      J=C1[j][4];
+      psi=s,J;
+      C2[2]=psi(Psi);
+      C2[3]=C1[j][2];
+      C2[4]=m1;
+      l1=insert(l,C1[j][1],size(l));
+      C2[5]=l1;
+      HN1=psi(HN);
+      HN1=insert(HN1,C1[j][3],size(HN1)-1);
+      C2[6]=HN1;
+      if(deg(C2[3])>1)
+      {
+        w=v,-j;
+      }
+      else
+      {
+        w=v,j;
+      }
+      C2[7]=w;
+      if(nvars(basering)==3)
+      {
+        C2[9]=C1[j][6];
+        C2[8][size(C2[8])+1]=list(C2[7],C2[9]);
+        C3=main(C2[1],C2[2],C2[3],C2[4],C2[5],C2[6],C2[7],C2[8],C2[9]);
+        C=C+C3;
+      }
+      else
+      {
+        C3=main(C2[1],C2[2],C2[3],C2[4],C2[5],C2[6],C2[7],C2[8]);
+        C=C+C3;
+      }
+    }
+  }
+  return(C);
+}
+////////////////////////////////////////////////////////////////////////////////////////////////
+
+static proc transversalTest(ideal I,poly f,list L)
+{
+  def r=basering;
+  int n=nvars(r)-1;
+  int i;
+  ring r1=(0,a),(x(1..n)),ds;
+  number f=leadcoef(imap(r,f));
+  minpoly=f;
+  ideal I=imap(r,I);
+  list L=imap(r,L);
+  ideal K=jet(L[size(L)],deg(lead(L[size(L)])));
+  ideal T=1;
+  if(size(L)>1)
+  {
+    for(i=1;i<=size(L)-1;i++)
+    {
+      if(subst(L[i],x(1),0,x(2),0)==0) break;
+    }
+    if(i<=size(L)-1)
+    {
+      T=jet(L[i],deg(lead(L[i])));
+    }
+  }
+  ideal J=jet(I[1],deg(lead(I[1])));
+  setring r;
+  ideal J=imap(r1,J);
+  ideal K=imap(r1,K);
+  ideal T=imap(r1,T);
+  int m=size(reduce(J,std(K)))+size(reduce(K,std(J)));
+  if(m)
+  {
+    m=size(reduce(J+K+T,std(ideal(x(1),x(2)))));
+  }
+  return(m);
+}
+////////////////////////////////////////////////////////////////////////////////////////////////
+static proc SmoothTest(ideal I,poly f)
+//Assume I is a radical ideal of dimension 1 in a ring k[x(1..n),a]
+//Returns 1 if a curve V(I) is smooth at point 0 and returns 0 otherwise
+{
+  int ind;
+  int l;
+  def t=basering;
+  int n=nvars(t)-1;
+  ring r1=(0,a),(x(1..n)),dp;
+  number f=leadcoef(imap(t,f));
+  minpoly=f;
+  ideal I=imap(t,I);
+  matrix M=jacob(I);
+  for(l=1;l<=n;l++){M=subst(M,x(l),0);}
+  if(mat_rk(M)==(n-1)){ind=1;}
+  return(ind);
+}
+////////////////////////////////////////////////////////////////////////////////////////////////
+proc CurveRes(ideal I)
+"USAGE:   CurveRes(I);
+          I ideal
+ASSUME:   The basering is r=0,(x(1..n))
+          V(I) is a curve with a singular point 0.
+COMPUTE:  Resolution of the curve V(I).
+RETURN:   a ring R=basering+k[a]
+          Ring R contains a list Resolve
+          Resolve is a list of charts
+          Each Resolve[i] is a list of size 6
+          Resolve[i][1] is an ideal J of a new curve. J=teta(I).
+          Resolve[i][2] ideal which represents the map
+                        teta:k[x(1)..x(n),a]-->k[x(1)..x(n),a] from the
+                        new curve to the old one.
+          Resolve[i][3] is an irreducible poly g in k[a]. It is a minimal polynomial for the
+                        new parameter a. deg(g) gives the number of branches in Resolve[i]
+          Resolve[i][4] sequence of multiplicities (sum over all branches in Resolve as long as
+                        they intersect each other !)
+          Resolve[i][5] is a list of integers l. It shows, which standard charts we considered.
+          Resolve[i][6] HN matrix
+          Resolve[i][7] (only for plane curves) the development of exceptional divisors
+                        the entries correspond to the i-th blowing up. The first entry is an
+                        intvec. The first negative entry gives the splitting of the (over Q
+                        irreducible) branches. The second entry is a list of the exceptional
+                        divisors. If the entry is an integer i, it says that the divisor is not
+                        visible in this chart after the i-th blowing up.
+
+EXAMPLE: example CurveRes; shows an example"
+{
+  def r=basering;
+  int n=nvars(r);
+  ring s=0,(x(1..n),a),dp;
+  ideal A;
+  int i;
+  int j;
+  for(i=1;i<=n;i++){A[i]=x(i);}
+  map phi=r,A;
+  ideal I=phi(I);
+  poly f=a;
+  list l;
+  list m;
+  list HN=x(1);
+  ideal psi;
+  for(i=1;i<=n;i++){psi[i]=x(i);}
+  psi[n+1]=a;
+  intvec v;
+  list L,Resolve;
+  if(n==2)
+  {
+    ideal J=factorize(I[1],1);
+    list resolve;
+    for(int k=1;k<=size(J);k++)
+    {
+      I=J[k];
+      resolve=main(I,psi,f,m,l,HN,v,L);
+      for(i=1;i<=size(resolve);i++)
+      {
+        resolve[i][6]=delete(resolve[i][6],size(resolve[i][6]));
+        if(size(resolve[i])>=9){resolve[i]=delete(resolve[i],9);}
+        resolve[i]=delete(resolve[i],7);
+      }
+      if(k==1){Resolve=resolve;}
+      else{Resolve=Resolve+resolve;}
+    }
+  }
+  else
+  {
+    Resolve=main(I,psi,f,m,l,HN,v,L);
+    for(i=1;i<=size(Resolve);i++)
+    {
+      Resolve[i][6]=delete(Resolve[i][6],size(Resolve[i][6]));
+      Resolve[i]=delete(Resolve[i],8);
+    }
+  }
+  export(Resolve);
+  return(s);
+}
+example
+{
+  "EXAMPLE:"; echo=2;
+  ring r=0,(x,y,z),dp;
+  ideal i=x2-y3,z2-y5;
+  def s=CurveRes(i);
+  setring s;
+  Resolve;
+}
+//////////////////////////////////////////////////////////////////
+static proc mlist(list l,int n)
+{
+  list N;
+  list M;
+  int i;
+  int j;
+  for(i=1;i<=n;i++) {M[i]=i;}
+  N=l+M;
+  for(i=1;i<=size(N)-1;i++)
+  {
+    j=i+1;
+    while(j<=size(N))
+    {
+      if(N[i]==N[j]){N=delete(N,j);}
+      else
+      {j++;}
+    }
+  }
+  return(N);
+}
+/////////////////////////////////////////////////////////////////////
+//Assume that the basering is k[x(1..n),a]
+
+static proc mmult(ideal I,poly f)
+{
+  def r=basering;
+  int n=nvars(r)-1;
+  ring r1=(0,a),(x(1..n)),ds;
+  number f=leadcoef(imap(r,f));
+  minpoly=f;
+  ideal I=imap(r,I);
+  int m=mult(std(I));
+  return(m);
+}
+//////////////////////////////////////////////////////////////
+//--------Parametrization of smooth curve-------------------//
+//////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+//computes jacobian matrix, considering x(1..n) as variables and a(1..m) as parameters
+
+static proc mjacob(ideal I)
+{
+  def r=basering;
+  int n=nvars(r);
+  int k=size(I);
+  matrix M[k][n];
+  int i;
+  int j;
+  int l;
+  for(i=1;i<=k;i++)
+  {
+    for(j=1;j<=n;j++)
+    {
+      M[i,j]=diff(I[i],x(j));
+      for(l=1;l<=n;l++){M[i,j]=subst(M[i,j],x(l),0);}
+    }
+  }
+  return(M);
+}
+//////////////////////////////////////////////////////////
+static proc mmi(matrix M,int n)
+{
+  ideal l;
+  int k=nrows(M);
+  int i;
+  int j;
+  for(i=1;i<=k;i++)
+  {
+    l[i]=0;
+    for(j=1;j<=n;j++)
+    {
+      l[i]=l[i]+x(j)*M[i,j];
+    }
+  }
+  l=std(l);
+  int t=size(l);
+  i=1;
+  int mi=0;
+  while( mi==0 and i<=n-1)
+  {
+    if(diff(l[i],x(n-i))!=0){mi=n-i+1;}
+    else{i++;}
+  }
+  if(mi==0){mi=1;}
+  matrix Mi[k][n-1];
+  for(i=1;i<=k;i++)
+  {
+    for(j=1;j<=mi-1;j++)
+    {
+      Mi[i,j]=M[i,j];
+    }
+    for(j=mi;j<=n-1;j++)
+    {
+      Mi[i,j]=M[i,j+1];
+    }
+  }
+  list lmi=mi,Mi;
+  return(lmi);
+}
+//////////////////////////////////////////////////////////
+static proc mC(matrix Mi,int n)
+{
+  int k=nrows(Mi);
+  ideal c;
+  int i,j;
+  for(i=1;i<=n-1;i++)
+  {
+    c[i]=0;
+    for(j=1;j<=k;j++)
+    {
+      c[i]=c[i]+y(j)*Mi[j,i];
+    }
+  }
+  c=std(c);
+  return(c);
+}
+//////////////////////////////////////////////////////////
+static proc mmF(ideal C, matrix Mi,int n,int k)
+{
+  int s=size(C);
+  intvec mf;
+  int p=0;
+  int t=0;
+  int i;
+  int j;
+  int v=0;
+  for(i=s;i>0;i--)
+  {
+    p=t;
+    j=1;
+    while(t==p and p+j<=k)
+    {
+      if(diff(C[i],y(p+j))==0){j++;}
+      if(diff(C[i],y(p+j))!=0){t=p+j;v++;mf[v]=t;}
+    }
+  }
+  matrix B[n-1][n-1];
+  for(i=1;i<=n-1;i++)
+  {
+    for(j=1;j<=n-1;j++)
+    {
+      B[i,j]=Mi[ mf[i],j];
+    }
+  }
+  list mmf=mf,B;
+  return(mmf);
+}
+/////////////////////////////////////////////////////
+static proc cparam(ideal I,poly f,int n,int m,int N)
+{
+  def r=basering;
+  ring s=(0,a),(x(1..n)),lp;
+  number f=leadcoef(imap(r,f));
+  minpoly=f;
+  ideal I=imap(r,I);
+  matrix M=mjacob(I);
+  list l0=mmi(M,n);
+  int mi=l0[1];
+  matrix Mi=l0[2];
+  int k=nrows(Mi);
+  ring q=(0,a),(y(1..k)),lp;
+  number f=leadcoef(imap(r,f));
+  minpoly=f;
+  matrix Mi=imap(s,Mi);
+  ideal D=mC(Mi,n);
+  list l1=mmF(D,Mi,n,k);
+  intvec mf=l1[1];
+  matrix B=l1[2];
+  setring s;
+  matrix B=imap(q,B);
+  matrix C=inverse(B);
+  int i;
+  int j;
+  ideal P;
+  for(i=1;i<mi;i++){P[i]=x(i);}
+  P[mi]=x(n);
+  for(i=1;i<=n-mi;i++){P[mi+i]=x(mi+i-1);}
+  map phi=s,P;
+  ideal I1=phi(I);
+  if(nvars(basering)==2)
+  {
+    setring r;
+    ideal I1=imap(s,I1);
+    matrix C=imap(s,C);
+    list X;
+    matrix d[n-1][1];
+    matrix b[n-1][1];
+    ideal Q;
+    map psi;
+    int l;
+    for(i=1;i<=N;i++)
+    {
+      for(j=1;j<=n-1;j++)
+      {
+        d[j,1]=diff(I1[mf[j]],x(n));
+        for(l=1;l<=n;l++)
+        {
+          d[j,1]=subst(d[j,1],x(l),0);
+        }
+      }
+      b=-C*d;
+      I1=jet(I1,N-i+2);
+      X[i]=b;
+      for(j=1;j<=n-1;j++){Q[j]=x(n)*(b[j,1]+x(j));}
+      Q[n]=x(n);
+      I1[1]=quickSubst(I1[1],Q[1],Q[2],std(f));
+      I1=I1/x(n);
+    }
+    list Y=X,mi;
+    return(Y);
+  }
+  list X;
+  matrix d[n-1][1];
+  matrix b[n-1][1];
+  ideal Q;
+  map psi;
+  int l;
+  for(i=1;i<=N;i++)
+  {
+    for(j=1;j<=n-1;j++)
+    {
+      d[j,1]=diff(I1[mf[j]],x(n));
+      for(l=1;l<=n;l++){d[j,1]=subst(d[j,1],x(l),0);}
+    }
+    b=-C*d;
+    I1=jet(I1,N-i+2);
+    X[i]=b;
+    for(j=1;j<=n-1;j++){Q[j]=x(n)*(b[j,1]+x(j));}
+    Q[n]=x(n);
+    psi=s,Q;
+    I1=psi(I1);
+    I1=I1/x(n);
+  }
+  list Y=X,mi,var(1);
+  setring r;
+  list Y=imap(s,Y);
+  Y=delete(Y,3);
+  return(Y);
+}
+//////////////////////////////////////////////////////////////
+//--------Parametrization of singular curve-----------------//
+//////////////////////////////////////////////////////////////
+proc CurveParam (list #)
+"USAGE:   CurveParam(I);
+          I ideal
+ASSUME:   I is an ideal of a curve C with a singular point 0.
+COMPUTE:  Parametrization for algebraic branches of the curve C.
+RETURN:   list L of size 1.
+          L[1] is a ring ring rt=0,(t,a),ds;
+          Ring R contains a list Param
+          Param is a list of algebraic branches
+          Each Param[i] is a list of size 3
+          Param[i][1] is a list of polynomials
+          Param[i][2] is an irredusible polynomial f\in k[a].It is a minimal polynomial for
+                      the parameter a.
+          Param[i][3] is an integer b--upper bound for the conductor of Weierstrass semigroup
+
+EXAMPLE: example curveparam; shows an example"
+{
+  int i;
+  int j;
+  if(typeof(#[1])=="ideal")
+  {
+    int d=deg(#[1][1]);
+    def s=CurveRes(#[1]);
+  }
+  else
+  {
+    def s=#[1];
+  }
+  setring s;
+  int n=nvars(s)-1;
+  list Param;
+  list l;
+  ideal D,P,Q,T;
+  poly f;
+  map tau;
+  list Z;
+  list Y;
+  list X;
+  int mi;
+  int b;
+  int k;
+  int dd;
+  for(j=1;j<=size(Resolve);j++)
+  {
+    b=0;
+    for(k=1;k<=size(Resolve[j][4]);k++)
+    {
+      b=b+Resolve[j][4][k]*(Resolve[j][4][k]+1);
+    }
+    if((n==2)&&(size(Resolve[j][4])==0))
+    {b=d;}
+    Y=cparam(Resolve[j][1],Resolve[j][3],n,1,b);
+    X=Y[1];
+    mi=Y[2];
+    f=Resolve[j][3];
+    for(i=1;i<mi;i++)
+    {
+      P[i]=0;
+      for(k=1;k<=b;k++){P[i]=P[i]+X[k][i,1]*(x(1)^k);}
+    }
+    P[mi]=x(1);
+    for(i=mi+1;i<=n;i++)
+    {
+      P[i]=0;
+      for(k=1;k<=b;k++){P[i]=P[i]+X[k][i-1,1]*(x(1)^k);}
+    }
+    P[n+1]=a;
+    tau=s,P;
+    T=Resolve[j][2];
+//HERE A TEST FOR dd
+    if(nvars(basering)==3)
+    {
+      dd=boundparam(P[2]);
+      if(dd==1){dd=boundparam(P[1]);}
+      P[1]=jet(P[1],dd);
+      P[2]=jet(P[2],dd);
+      Q[1]=quickSubst(T[1],P[1],P[2],std(f));
+      Q[2]=quickSubst(T[2],P[1],P[2],std(f));
+      Q[3]=a;
+    }
+    else
+    {
+      Q=tau(T);
+    }
+    for(i=1;i<=n;i++){Z[i]=jet(reduce(Q[i],std(f)),b+1);}
+    l[1]=Z;
+    l[2]=f;
+    l[3]=b;
+    Param[j]=l;
+  }
+  ring rt=0,(t,a),ds;
+  ideal D;
+  D[1]=t;
+  D[n+1]=a;
+  map delta=s,D;
+  list Param=delta(Param);
+  export(Param);
+  return(rt);
+}
+example
+{
+  "EXAMPLE:";echo=2;
+  ring r=0,(x,y,z),dp;
+  ideal i=x2-y3,z2-y5;
+  def s=CurveParam(i);
+  setring s;
+  Param;
+}
+///////////////////////////////////////////////////////////////////////////////////////////
+//----------Computation of Weierstrass Semigroup from parametrization--------------------//
+///////////////////////////////////////////////////////////////////////////////////////////
+static proc Semi(intvec G,int b)
+"USAGE:   Semi(G,b);
+          G=intvec
+          b=int
+ASSUME:   G[1]<=G[2]<=...<=G[k],
+COMPUTE:  elements of semigroup S generated by the enteries of G till the bound b.
+          For each element i of S computes the list of integer vectors v of dimension
+          k=size(G), such that g[1]*v[1]+g[2]*v[2]+...+g[k]*v[k]=i. If there exists
+          conductor  of semigroup S  c<b-n, where n is minimal element of G, then
+          computes also c+n.
+RETURN:   list M of size 2.
+          L=M[1] is a list  of size min(b,c+n).
+          L[i] is a list of integer vectors.
+          If i is not in a semigroup S than L[i] is empty.
+          M[2] is an integer =min(b,c+n)
+          M[3] minimal generators of S
+EXAMPLE:"
+{
+  list L;
+  list l;
+  int i;
+  for(i=1;i<=b;i++){L[i]=l;}
+  int k=size(G);
+  int n=G[1];
+  int j;
+  int t;
+  int q;
+  int c=0;
+  intvec w;
+  intvec v;
+  for(i=1;i<=k;i++)
+  {
+    for(j=1;j<=k;j++)
+    {
+      if(j==i){w[j]=1;}
+      else{w[j]=0;}
+    }
+    L[G[i]]=insert(L[G[i]],w);
+  }
+  list L1=L;
+  int s=0;
+  int s1=0;
+  i=1;
+  int p;
+  while(i<=b and s<n)
+  {
+    for(j=1;j<=k;j++)
+    {
+      if(i-G[j]>0)
+      {
+        if(size(L[i-G[j]])>0)
+        {
+          for(t=1;t<=size(L[i-G[j]]);t++)
+          {
+            v=L[i-G[j]][t];
+            p=1;
+            for(q=1;q<j;q++)
+            {
+              if(v[q]>0){p=0;}
+            }
+            if(p==1){v[j]=v[j]+1;L[i]=insert(L[i],v);}
+          }
+        }
+      }
+    }
+    if(size(L[i])>0){s1=1;}
+    s=s1*(s+1);
+    s1=0;
+    i++;
+  }
+  intvec Gmin;
+  int jmin=1;
+  for(j=1;j<=k;j++)
+  {
+    if(size(L[G[j]])==size(L1[G[j]]) && G[j]<i)
+    {
+      Gmin[jmin]=G[j];
+      L1[G[j]]=insert(L1[G[j]],0);
+      jmin++;
+    }
+  }
+  list M=L,i-1,Gmin;
+  return(M);
+}
+///////////////////////////////////////////////////////////////////////////////////////////
+static proc AddElem(list L,int b,int k,int g,int n)
+"ASSUME:  L list of size b. L[i] list of integer vectors of dimension k.
+          b=int
+          k=int as above
+          g=int new generator
+          n=int. minimal generator
+RETURN: list M
+        M[1]=new L;
+        M[2]=new b;"
+{
+  int i,j;
+  intvec v;
+  for(i=1;i<=b;i++)
+  {
+    if(size(L[i])>0)
+    {
+      for(j=1;j<=size(L[i]);j++)
+      {
+        v=L[i][j];
+        v[k+1]=0;
+        L[i][j]=v;
+      }
+    }
+  }
+  intvec w;
+  w[k+1]=1;
+  L[g]=insert(L[g],w);
+  int s=0;
+  int s1=0;
+  i=1;
+  while(i<=b and s<n)
+  {
+    if(i-g>0)
+    {
+      if(size(L[i-g])>0)
+      {
+        for(j=1;j<=size(L[i-g]);j++)
+        {
+          v=L[i-g][j];
+          v[k+1]=v[k+1]+1;
+          L[i]=insert(L[i],v);
+        }
+      }
+    }
+    if(size(L[i])>0){s1=1;}
+    s=s1*(s+1);
+    s1=0;
+    i++;
+  }
+  int b1=i-1;
+  list M=L,b1;
+  return(M);
+}
+///////////////////////////////////////////////////////////////////////////////////////////
+proc WSemigroup(list X,int b0)
+"USAGE:    WSemigroup(X,b0);
+           X a list of polinomials in one vaiable, say t.
+           b0 an integer
+COMPUTE:   Weierstrass semigroup of space curve C,which is given by a parametrization
+           X[1](t),...,X[k](t), till the bound b0.
+
+ASSUME:    b0 is greater then conductor
+RETURN:    list M of size 5.
+           M[1]= list of integers, which are minimal generators set of the Weierstrass semigroup.
+           M[2]=integer, conductor of the Weierstrass semigroup.
+           M[3]=intvec, all elements of the Weierstrass semigroup till some bound b,
+           which is greather than conductor.
+WARNING:   works only over the ring with one variable with ordering ds
+EXAMPLE: example WSemigroup; shows an example"
+
+{
+  int k=size(X);
+  intvec G;
+  int i,i2;
+  poly t=var(1);
+  poly h;
+  int g;
+  for(i=1;i<=k;i++)
+  {G[i]=ord(X[i]);}
+  for(i=1;i<k;i++)
+  {
+    for(i2=i;i2<=k;i2++)
+    {
+      if(G[i]>G[i2])
+      {
+        g=G[i];G[i]=G[i2];G[i2]=g;
+        h=X[i];X[i]=X[i2];X[i2]=h;
+      }
+    }
+  }
+  list U=Semi(G,b0);
+  list L=U[1];
+  int b=U[2];
+  G=U[3];
+  int k1=size(G);
+  list N;
+  list l;
+  for(i=1;i<=b;i++){N[i]=l;}
+  int j;
+  for(j=b0;j>b;j--){L=delete(L,j);}
+  poly p;
+  int s;
+  int e;
+  for(i=1;i<=b;i++)
+  {
+    for(j=1;j<=size(L[i]);j++)
+    {
+      p=1;
+      for(s=1;s<=k;s++)
+      {
+        for(e=1;e<=L[i][j][s];e++)
+        {
+          p=p*X[s];
+          p=jet(p,b);
+        }
+      }
+      N[i]=insert(N[i],p);
+    }
+  }
+  int j1;
+  int j2;
+  list M;
+  poly c1;
+  poly c2;
+  poly f;
+  int m;
+  int b1;
+  ideal I;
+  matrix C;
+  matrix C1;
+  int q;
+  int i1;
+  i=1;
+  while(i<=b)
+  {
+    for(j1=2;j1<=size(N[i]);j1++)
+    {
+      for(j2=1;j2<j1;j2++)
+      {
+        c1=coeffs(N[i][j1],t)[i+1,1];
+        c2=coeffs(N[i][j2],t)[i+1,1];
+        f=c2*N[i][j1]-c1*N[i][j2];
+        m=ord(f);
+        if(m>=0)
+        {
+          if(size(N[m])==0)
+          {
+            N[m]=insert(N[m],f);
+            if(size(L[m])==0)
+            {
+              M=AddElem(L,b,k,m,G[1]);
+              L=M[1];
+              b1=M[2];
+              G[k1+1]=m;
+              X[k+1]=f;
+              N[m]=insert(N[m],f);
+              k=k+1;
+              k1=k1+1;
+              if(b1<b)
+              {
+                for(i1=1;i1<=b1;i1++)
+                {
+                  for(s=1;s<=size(N[i1]);s++){N[i1][s]=jet(N[i1][s],b1);}
+                }
+                for(s=size(N);s>b1;s--){N=delete(N,s);}
+                for(s=size(L);s>b1;s--){L=delete(L,s);}
+              }
+              b=b1;
+            }
+          }
+          else
+          {
+            for(q=1;q<=size(N[m]);q++){I[q]=N[m][q];}
+            I[size(N[m])+1]=f;
+            C=coeffs(I,t);
+            C1=gauss_col(C);
+            if(C1[size(N[m])+1]!=0){N[m]=insert(N[m],f);}
+          }
+        }
+      }
+    }
+    i++;
+  }
+  intvec S;
+  j=1;
+  for(i=1;i<=b;i++)
+  {
+    if(size(L[i])>0){S[j]=i;j++;}
+  }
+  U=Semi(G,b);
+  G=U[3];
+  list Q=G,b-G[1]+1,S;
+  return(Q);
+}
+example
+{
+  "EXAMPLE:";echo=2;
+  ring r=0,(t),ds;
+  list X=t4,t5+t11,t9+2*t7;
+  list L=WSemigroup(X,30);
+  L;
+}
+////////////////////////////////////////////////////////////////////////////////////////////
+
+static proc quickSubst(poly h, poly r, poly s,ideal I)
+{
+//=== computes h(r,s) mod I for h in Q[x(1),x(2),a]
+  attrib(I,"isSB",1);
+  if((r==x(1))&&(s==x(2))){return(reduce(h,I));}
+  poly q1 = 1;
+  poly q2 = 1;
+  poly q3 = 1;
+  int i,j,e1,e2,e3;
+  list L,L1,L2,L3;
+  if(r==x(1))
+  {
+    matrix M=coeffs(h,x(2));
+    L[1]=1;
+    for(i=2;i<=nrows(M);i++)
+    {
+      q2 = reduce(q2*s,I);
+      L[i]=q2;
+    }
+    i=1;
+    h=0;
+    while(i <= nrows(M))
+    {
+      if(M[i,1]!=0)
+      {
+         h=h+M[i,1]*L[i];
+      }
+      i++;
+    }
+    h=reduce(h,I);
+    return(h);
+  }
+  if(s==x(2))
+  {
+    matrix M=coeffs(h,x(1));
+    L[1]=1;
+    for(i=2;i<=nrows(M);i++)
+    {
+      q1 = reduce(q1*r,I);
+      L[i]=q1;
+    }
+    i=1;
+    h=0;
+    while(i <= nrows(M))
+    {
+      if(M[i,1]!=0)
+      {
+        h=h+M[i,1]*L[i];
+      }
+      i++;
+    }
+    h=reduce(h,I);
+    return(h);
+  }
+  for(i=1;i<=size(h);i++)
+  {
+    if(leadexp(h[i])[1]>e1){e1=leadexp(h[i])[1];}
+    if(leadexp(h[i])[2]>e2){e2=leadexp(h[i])[2];}
+    if(leadexp(h[i])[3]>e3){e3=leadexp(h[i])[3];}
+  }
+  for(i = 1; i <= size(h); i++)
+  {
+    L[i] = list(leadcoef(h[i]),leadexp(h[i]));
+  }
+  L1[1]=1;
+  L2[1]=1;
+  L3[1]=1;
+  for(i=1;i<=e1;i++)
+  {
+    q1 = reduce(q1*r,I);
+    L1[i+1]=q1;
+  }
+  for(i=1;i<=e2;i++)
+  {
+    q2 = reduce(q2*s,I);
+    L2[i+1]=q2;
+  }
+  for(i=1;i<=e3;i++)
+  {
+    q3 = reduce(q3*var(3),I);
+    L3[i+1]=q3;
+  }
+  int m=size(L);
+  i = 1;
+  h = 0;
+  while(i <= m)
+  {
+    h=h+L[i][1]*L1[L[i][2][1]+1]*L2[L[i][2][2]+1]*L3[L[i][2][3]+1];
+    i++;
+  }
+  h=reduce(h,I);
+  return(h);
+}
+
+static proc semi2char(intvec v)
+{
+  intvec k=v[1..2];
+  intvec w=v[1];
+  int i,j,p,q;
+  for(i=2;i<size(v);i++)
+  {
+    w[i]=gcd(w[i-1],v[i]);
+  }
+  for(i=3;i<=size(v);i++)
+  {
+    k[i]=v[i];
+    for(j=2;j<i;j++)
+    {
+      k[i]=k[i]-(w[j-1] div w[j]-1)*v[j];
+    }
+  }
+  return(k);
+}
+/////////////////////////////////////////////////////////////////////////////////////////////////
+proc primparam(poly x,poly y,int c)
+"USAGE:  MultiplicitySequence(x,y,c);  x poly, y poly, c integer
+ASSUME:  x and y are polynomials in k(a)[t] such that (x,y) is a primitive parametrization of
+         a plane curve branch and ord(x)<ord(y).
+RETURN:  Hamburger-Noether Matrix of the curve branch given parametrically by (x,y).
+EXAMPLE: example primparam;  shows an example
+"
+{
+  int i,h;
+  poly F,z;
+  list L;
+  while(ord(x)>1)
+  {
+    list v;
+    while(ord(y)>=ord(x))
+    {
+      F=divide(y,x,c);
+      if(ord(F)==0)
+      {
+        v=insert(v,subst(F,t,0),size(v));
+        y=F-subst(F,t,0);
+      }
+      else
+      {
+        v=insert(v,0,size(v));
+        y=F;
+      }
+    }
+    v=insert(v,t,size(v));
+    L=insert(L,transform(v),size(L));
+    z=x;
+    x=y;
+    y=z;
+    kill v;
+  }
+  if(ord(x)==1)
+  {
+    list v;
+    while(i<c)
+    {
+      F=divide(y,x,c);
+      if(ord(F)==0)
+      {
+        v=insert(v,subst(F,t,0),size(v));
+        y=F-subst(F,t,0);
+      }
+      else
+      {
+        v=insert(v,0,size(v));
+        y=F;
+      }
+      if(y==0)
+      {
+        v=insert(v,t,size(v));
+        break;
+      }
+      i++;
+    }
+    L=insert(L,transform(v),size(L));
+  }
+  return(compose(L));
+}
+example
+{
+  "EXAMPLE:"; echo=2;
+  ring r=(0,a),t,ds;
+  poly x=t6;
+  poly y=t8+t11;
+  int c=15;
+  primparam(x,y,c);
+}
+
+//////////////////////////////////////
+//L is a list of polynomials
+//////////////////////////////////////
+static proc transform(list L)
+{
+  matrix m2;
+  matrix m1=matrix(L[1]);
+  for(int i=2;i<=size(L);i++)
+  {
+    m2=matrix(L[i]);
+    m1=concat(m1,m2);
+  }
+  return(m1);
+}
+/////////////////////////////////////////////////////////////////
+//L is a list of matrices
+///////////////////////////////////////
+static proc compose(list L)
+{
+  matrix M[ncols(L[1])][1]=transpose(L[1]);
+  for(int i=2;i<=size(L);i++)
+  {
+    M=concat(M,transpose(L[i]));
+  }
+  return(transpose(M));
+}
+//////////////////////////////////////////////////////////
+static proc rduce(poly p)
+{
+  int n=ord(p);
+  poly q=p/(t^n);
+  return(q);
+}
+////////////////////////////////////////////////////
+static proc divide(poly p,poly q,int c)i
+{
+  int n=ord(p);
+  int m=ord(q);
+  poly p'=rduce(p);
+  poly q'=rduce(q);
+  poly r=t^(n-m)*p'*jet(1,q',c);
+  return(jet(r,c));
+}
+/////////////////////////////////////////////////////
+static proc contact(list L)
+{
+  def M=L[1];
+  intvec v=L[2];
+  int s,j,i;
+  for(i=1;i<=size(v);i++)
+  {
+    if(v[i]<0){v[i]=-1-v[i];}
+    for(j=1;j<=v[i];j++)
+    {
+      s=s+1;
+      if(find(string(M[i,j]),"a")!=0){return(s);}
+    }
+  }
+}
+///////////////////////////////////////////////////////////
+static proc converter(list L)
+{
+def s=basering;
+list D;
+int i,c;
+for(i=1;i<=size(L);i++)
+   {D=insert(D,deg(L[i][2]),size(D));}
+ring r=(0,a),(t),ds;
+list L=imap(s,L);
+poly x,y,z;
+list A,B;
+for(i=1;i<=size(L);i++)
+   {A[5]=D[i];
+   x=L[i][1][1];
+   y=L[i][1][2];
+   if(ord(x)<=ord(y)){A[3]=0;}
+   else{A[3]=1;
+       z=x;
+       x=y;
+       y=z;
+       }
+   c=bound(x,y);
+   if(c==-1){ERROR("Bound is not enough");}
+   A[1]=primparam(x,y,c);
+   A[2]=lengths(A[1]);
+   A[4]=0;
+   B=insert(B,A,size(B));
+   A=list();
+   }
+ring r1=(0,a),(x,y),ds;
+list hne=fetch(r,B);
+export(hne);
+return(r1);
+}
+//////////////////////////////////////////////////////////
+static proc intermat(list L)
+{
+    int s=size(L);
+    intvec v=L[1][5];
+    intvec w1;
+    int i,j,d,b,l,k,c,o,p;
+    for(i=2;i<=s;i++)
+    {v=v,L[i][5];}
+    intvec u=v[1];
+    for(i=2;i<=s;i++)
+    {
+      l=u[size(u)]+v[i];
+      u=u,l;
+    }
+    int m=u[size(u)];
+    intmat M[m][m];
+    for(i=1;i<=m;i++)
+    {
+      for(j=i+1;j<=m;j++)
+      {
+        d=sorting(u,i);
+        b=sorting(u,j);
+        if(d==b){k=contact(L[d]);
+        w1=multsequence(L[d]);
+        if(size(w1)<k){for(p=size(w1)+1;p<=k;p++)
+        {w1=w1,1;} }
+        for(o=1;o<=k;o++){c=c+w1[o]*w1[o];}
+        M[i,j]=c;
+        c=0;
+      }
+      else
+      {M[i,j]=intersection(L[d],L[b]);}
+    }
+  }
+  return(M);
+}
+/////////////////////////////////////////////////////////////////
+static proc lengths(matrix M)
+{
+  intvec v;
+  int s,i,j;
+  for(i=1;i<=nrows(M);i++)
+  {
+    for(j=1;j<=ncols(M);j++)
+    {
+      if(M[i,j]==t)
+      {
+        v[i]=j-1;
+        if(i==nrows(M)){s=1;}
+        break;
+      }
+    }
+  }
+  if(s==0){v[nrows(M)]=-j;}
+  return(v);
+}
+//////////////////////////////////////////////////////////////////////
+static proc sorting(intvec u,int k)
+{
+  int s=size(u);
+  int i;
+  for(i=1;i<=s;i++)
+  {
+    if(u[i]>=k){break;}
+  }
+  return(i);
+}
+//////////////////////////////////////////////////////////////////////
+proc MultiplicitySequence(ideal i)
+"USAGE:  MultiplicitySequence(i); i ideal
+ASSUME:  i is the defining ideal of a (reducible) plane curve singularity.
+RETURN:  list X of charts. Each chart contains the multiplicity sequence of
+         the corresponding branch.
+EXAMPLE: example MultiplicitySequence;  shows an example
+"
+{
+  def s=CurveParam(i);
+  setring s;
+  int j,k;
+  def r1=converter(Param);
+  setring r1;
+  list Y=hne;
+  list X;
+  for(j=1;j<=size(Y);j++)
+  {
+    for(k=1;k<=Y[j][5];k++)
+    {
+      X=insert(X,multsequence(Y[j]),size(X));
+    }
+  }
+  return(X);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r=0,(x,y),ds;
+  ideal i=x14-x4y7-y11;
+  MultiplicitySequence(i);
+}
+/////////////////////////////////////////////////////////////////////////
+proc IntersectionMatrix(ideal i)
+"USAGE:  IntersectionMatrix(i); i ideal
+ASSUME:  i is the defining ideal of a (reducible) plane curve singularity.
+RETURN:  intmat of the intersection multiplicities of the branches.
+EXAMPLE: example IntersectionMatrix;  shows an example
+"
+{
+  def s=CurveParam(i);
+  setring s;
+  int j,k;
+  def r1=converter(Param);
+  setring r1;
+  list Y=hne;
+  return(intermat(Y));
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r=0,(x,y),ds;
+  ideal i=x14-x4y7-y11;
+  IntersectionMatrix(i);
+}
+///////////////////////////////////////////////////////////////////////////
+proc CharacteristicExponents(ideal i)
+"USAGE:  CharacteristicExponents(i); i ideal
+ASSUME:  i is the defining ideal of a (reducible) plane curve singularity.
+RETURN:  list X of charts. Each chart contains the characteristic exponents
+         of the corresponding branch.
+EXAMPLE: example CharacteristicExponents;  shows an example
+"
+{
+  def s=CurveParam(i);
+  setring s;
+  int j,k;
+  def r1=converter(Param);
+  setring r1;
+  list X;
+  list Y=hne;
+  for(j=1;j<=size(Y);j++)
+  {
+    for(k=1;k<=Y[j][5];k++)
+    {
+      X=insert(X,invariants(Y[j])[1],size(X));
+    }
+  }
+  return(X);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r=0,(x,y),ds;
+  ideal i=x14-x4y7-y11;
+  CharacteristicExponents(i);
+}
+/////////////////////////////////////////////////////////////////////////////
+static proc contactNumber(int a,intvec v1,intvec v2)
+{
+//====  a is the intersection multiplicity of the branches
+//====  v1,v2 are the multiplicity sequences
+  int i,c,d;
+  if(size(v1)>size(v2))
+  {
+    for(i=size(v2)+1;i<=size(v1);i++)
+    {
+      v2[i]=1;
+    }
+  }
+  if(size(v1)<size(v2))
+  {
+    for(i=size(v1)+1;i<=size(v2);i++)
+    {
+      v1[i]=1;
+    }
+  }
+  while((c<a)&&(d<size(v1)))
+  {
+    d++;
+    c=c+v1[d]*v2[d];
+  }
+  if(c<a)
+  {
+    d=d+a-c;
+  }
+   return(d);
+}
+////////////////////////////////////////////////////////////////////////////
+proc ContactMatrix(ideal I)
+"USAGE:  ContactMatrix(I); I ideal
+ASSUME:  i is the defining ideal of a (reducible) plane curve singularity.
+RETURN:  intmat N of the contact matrix of the braches of the curve.
+EXAMPLE: example ContactMatrix;  shows an example
+"
+{
+  def s=CurveParam(I);
+  setring s;
+  int j,k,i;
+  def r1=converter(Param);
+  setring r1;
+  list Y=hne;
+  list L;
+  for(j=1;j<=size(Y);j++)
+  {
+    for(k=1;k<=Y[j][5];k++)
+    {
+      L=insert(L,multsequence(Y[j]),size(L));
+     }
+  }
+  intmat M=intermat(Y);
+  intmat N[nrows(M)][ncols(M)];
+  for(i=1;i<=nrows(M);i++)
+  {
+  for(j=i+1;j<=ncols(M);j++)
+  {
+    N[i,j]=contactNumber(M[i,j],L[i],L[j]);
+    N[j,i]=N[i,j];}
+  }
+  return(N);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r=0,(x,y),ds;
+  ideal i=x14-x4y7-y11;
+  ContactMatrix(i);
+}
+///////////////////////////////////////////////////////////////////////////
+proc plainInvariants(ideal i)
+"USAGE:  plainInvariants(i); i ideal
+ASSUME:  i is the defining ideal of a (reducible) plane curve singularity.
+RETURN:  list L of charts. L[j] is the invariants of the jth branch and the last entry
+         of L is a list containing the intersection matrix,contact matrix,resolution
+         graph of the curve.
+         L[j][1]:     intvec (characteristic exponents of the jth branch)
+         L[j][2]:    intvec (generators of the semigroup of the jth branch)
+         L[j][3]:    intvec (first components of the puiseux pairs of the jth branch)
+         L[j][4]:    intvec (second components of the puiseux pairs of the jth branch)
+         L[j][5]:    int    (degree of conductor of the jth branch)
+         L[j][6]:    intvec (multiplicity sequence of the jth branch.
+         L[last][1]: intmat (intersection matrix of the branches)
+         L[last][2]: intmat (contact matrix of the branches)
+         L[last][3]: intmat (resolution graph of the curve)
+SEE ALSO: MultiplicitySequence, CharacteristicExponents, IntersectionMatrix,
+          ContactMatrix
+EXAMPLE: example plainInvariants;  shows an example
+"
+{
+  def s=CurveParam(i);
+  setring s;
+  int j,k;
+  def r1=converter(Param);
+  setring r1;
+  list Y=hne;
+  list L,X,Q;
+  for(j=1;j<=size(Y);j++)
+  {
+    for(k=1;k<=Y[j][5];k++)
+    {
+      L=insert(L,invariants(Y[j]),size(L));   //computes the same thing again
+      X=insert(X,invariants(Y[j])[1],size(X));
+    }
+  }
+  L=insert(L,list(),size(L));
+  L[size(L)]=insert(L[size(L)],intermat(Y),size(L[size(L)]));
+  intmat N[nrows(intermat(Y))][ncols(intermat(Y))];
+  for(k=1;k<=nrows(intermat(Y));k++)
+  {
+    for(j=k+1;j<=ncols(intermat(Y));j++)
+    {
+      N[k,j]=contactNumber(intermat(Y)[k,j],L[k][6],L[j][6]);
+      N[j,k]=N[k,j];
+    }
+  }
+  L[size(L)]=insert(L[size(L)],N,size(L[size(L)]));
+  Q=L[size(L)][2],X;
+  L[size(L)]=insert(L[size(L)],resolutiongraph(Q),size(L[size(L)]));
+  return(L);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r=0,(x,y),ds;
+  ideal i=x14-x4y7-y11;
+  plainInvariants(i);
+}
+////////////////////////////////////////////////////////////////////////////////////
+static proc bound(poly x,poly y)
+{
+  poly z=x+y;
+  int m=ord(z);
+  int i;
+  int c=-1;
+  for(i=2;i<=size(z);i++)
+  {
+    if(gcd(m,leadexp(z[i])[1])==1)
+    {
+      c=2*leadexp(z[i])[1];
+      break;
+    }
+    else
+    {
+      m=gcd(m,leadexp(z[i])[1]);
+    }
+  }
+  return(c);
+}
+/////////////////////////////////////////////////////////////////////////////////////
+static proc boundparam(poly f)
+{
+  int i;
+  int l=size(f);
+  int m=leadexp(f[l])[1];
+  for(i=l-1;i>=1;i--)
+  {
+    if(gcd(m,leadexp(f[i])[1])==1)
+    {
+      i=i-1;
+      break;
+    }
+    else
+    {
+      m=gcd(m,leadexp(f[i])[1]);
+    }
+  }
+  return(2*leadexp(f[i+1])[1]);
+}
diff --git a/Singular/LIB/decodegb.lib b/Singular/LIB/decodegb.lib
new file mode 100644
index 0000000..e30218b
--- /dev/null
+++ b/Singular/LIB/decodegb.lib
@@ -0,0 +1,2133 @@
+//////////////////////////////////////////////////////////////////////////////
+version="version decodegb.lib 4.0.0.0 Jun_2013 "; // $Id: 65580650b0b9cd5f5208f7859d9969fdca6afa18 $
+category="Coding theory";
+info="
+LIBRARY: decodegb.lib         Decoding and min distance of linear codes with GB
+AUTHOR:  Stanislav Bulygin,   bulygin at mathematik.uni-kl.de
+
+OVERVIEW:
+ In this library we generate several systems used for decoding cyclic codes and
+ finding their minimum distance. Namely, we work with the Cooper's philosophy
+ and generalized Newton identities. The origindeal method of quadratic equations
+ is worked out here as well. We also (for comparison) enable to work with the
+ system of Fitzgerald-Lax. We provide some auxiliary functions for further
+ manipulations and decoding. For an overview of the methods mentioned above @ref{Decoding codes with Groebner bases}.
+ For the vanishing ideal computation the algorithm of Farr and Gao is
+ implemented.
+
+PROCEDURES:
+ sysCRHT(..);        generates the CRHT-ideal as in Cooper's philosophy
+ sysCRHTMindist(..); CRHT-ideal to find the minimum distance in the binary case
+ sysNewton(..);      generates the ideal with the generalized Newton identities
+ sysBin(..);         generates Bin system using Waring function
+ encode(x,g);        encodes given message x with the given generator matrix g
+ syndrome(h,c);      computes a syndrome w.r.t. the given check matrix
+ sysQE(..);          generates the system of quadratic equations for decoding
+ errorInsert(..);    inserts errors in a word
+ errorRand(y,num,e); inserts random errors in a word
+ randomCheck(m,n,e); generates a random check matrix
+ genMDSMat(n,a);     generates an MDS (actually an RS) matrix
+ mindist(check);     computes the minimum distance of a code
+ decode(rec);        decoding of a word using the system of quadratic equations
+ decodeRandom(..); a procedure for manipulation with random codes
+ decodeCode(..);   a procedure for manipulation with the given code
+ vanishId(points);   computes the vanishing ideal for the given set of points
+ sysFL(..);          generates the Fitzgerald-Lax system
+ decodeRandomFL(..); manipulation with random codes via Fitzgerald-Lax
+
+
+KEYWORDS:  Cyclic code; Linear code; Decoding;
+           Minimum distance; Groebner bases, decodeGB
+";
+
+LIB "linalg.lib";
+LIB "brnoeth.lib";
+
+///////////////////////////////////////////////////////////////////////////////
+// creates a list result, where result[i]=i, 1<=i<=n
+static proc lis (int n)
+{
+ list result;
+ if (n<=0) {print("ERRORlis");}
+ for (int i=1; i<=n; i++)
+ {
+  result=result+list(i);
+ }
+ return(result);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// creates a list of all combinations without repititions of m objects out of n
+static proc combinations (int m, int n)
+{
+ list result;
+ if (m>n) {print("ERRORcombinations");}
+ if (m==n) {result[size(result)+1]=lis(m);return(result);}
+ if (m==0) {result[size(result)+1]=list();return(result);}
+ list temp=combinations(m-1,n-1);
+ for (int i=1; i<=size(temp); i++)
+ {
+  temp[i]=temp[i]+list(n);
+ }
+ result=combinations(m,n-1)+temp;
+ return(result);
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+// the polynomial for Sala's restrictions
+static proc p_poly(int n, int a, int b)
+{
+  poly f;
+  for (int i=0; i<=n-1; i++)
+  {
+    f=f+Z(a)^i*Z(b)^(n-1-i);
+  }
+  return(f);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc sysCRHT (int n, list defset, int e, int q, int m, list #)
+"USAGE:   sysCRHT(n,defset,e,q,m,[k]); n,e,q,m,k are int, defset list of int's
+ at format
+         - n length of the cyclic code,
+         - defset is a list representing the defining set,
+         - e the error-correcting capacity,
+         - q field size
+         - m degree extension of the splitting field,
+         - if k>0 additional equations representing the fact that every two
+         error positions are either different or at least one of them is zero
+ at end format
+RETURN: the ring to work with the CRHT-ideal (with Sala's additions),
+        containig an ideal with name 'crht'
+THEORY:  Based on 'defset' of the given cyclic code, the procedure constructs
+         the corresponding Cooper-Reed-Heleseth-Truong ideal 'crht'. With its
+         help one can solve the decoding problem. For basics of the method @ref{Cooper philosophy}.
+SEE ALSO: sysNewton, sysBin
+EXAMPLE: example sysCRHT; shows an example
+"
+{
+  int r=size(defset);
+  ring @crht=(q,a),(Y(e..1),Z(1..e),X(r..1)),lp;
+  ideal crht;
+  int i,j;
+  poly sum;
+  int k;
+  if ( size(#) > 0)
+  {
+    k = #[1];
+  }
+
+  //---------------------- add check equations --------------------------
+  for (i=1; i<=r; i++)
+  {
+    sum=0;
+    for (j=1; j<=e; j++)
+    {
+      sum=sum+Y(j)*Z(j)^defset[i];
+    }
+    crht[i]=sum-X(i);
+  }
+
+  //--------------------- field equations on syndromes ------------------
+  for (i=1; i<=r; i++)
+  {
+    crht=crht,X(i)^(q^m)-X(i);
+  }
+
+  //------ restrictions on error-locations: n-th roots of unity ----------
+  for (i=1; i<=e; i++)
+  {
+    crht=crht,Z(i)^(n+1)-Z(i);
+  }
+
+  for (i=1; i<=e; i++)
+  {
+    crht=crht,Y(i)^(q-1)-1;
+  }
+
+  //--------- add Sala's additional conditions if necessary --------------
+  if ( k > 0 )
+
+  {
+    for (i=1; i<=e; i++)
+    {
+      for (j=i+1; j<=e; j++)
+      {
+        crht=crht,Z(i)*Z(j)*p_poly(n,i,j);
+      }
+    }
+  }
+  export crht;
+  return(@crht);
+}
+example
+{ "EXAMPLE:"; echo=2;
+  // binary cyclic [15,7,5] code with defining set (1,3)
+  intvec v = option(get);
+
+  list defset=1,3;           // defining set
+  int n=15;                  // length
+  int e=2;                   // error-correcting capacity
+  int q=2;                   // basefield size
+  int m=4;                   // degree extension of the splitting field
+  int sala=1;                // indicator to add additional equations
+
+  def A=sysCRHT(n,defset,e,q,m);
+  setring A;
+  A;                         // shows the ring we are working in
+  print(crht);               // the CRHT-ideal
+  option(redSB);
+  ideal red_crht=std(crht);  // reduced Groebner basis
+  print(red_crht);
+
+  //============================
+  A=sysCRHT(n,defset,e,q,m,sala);
+  setring A;
+  print(crht);                // CRHT-ideal with additional equations from Sala
+  option(redSB);
+  ideal red_crht=std(crht);   // reduced Groebner basis
+  print(red_crht);
+  red_crht[5];                // general error-locator polynomial for this code
+  option(set,v);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+
+proc sysCRHTMindist (int n, list defset, int w)
+"USAGE:  sysCRHTMindist(n,defset,w);  n,w are int, defset is list of int's
+ at format
+        - n length of the cyclic code,
+        - defset is a list representing the defining set,
+        - w is a candidate for the minimum distance
+ at end format
+RETURN:  the ring to work with the Sala's ideal for the minimum distance
+         containing the ideal with name 'crht_md'
+THEORY:  Based on 'defset' of the given cyclic code, the procedure constructs
+         the corresponding Cooper-Reed-Heleseth-Truong ideal 'crht_md'. With
+         its help one can find minimum distance of the code in the binary
+         case. For basics of the method @ref{Cooper philosophy}.
+EXAMPLE: example sysCRHTMindist; shows an example
+"
+{
+  int r=size(defset);
+  ring @crht_md=2,Z(1..w),lp;
+  ideal crht_md;
+  int i,j;
+  poly sum;
+
+  //------------ add check equations --------------
+  for (i=1; i<=r; i++)
+  {
+    sum=0;
+    for (j=1; j<=w; j++)
+    {
+      sum=sum+Z(j)^defset[i];
+    }
+    crht_md[i]=sum;
+  }
+
+
+  //----------- locations are n-th roots of unity ------------
+  for (i=1; i<=w; i++)
+  {
+    crht_md=crht_md,Z(i)^n-1;
+  }
+
+  //------------ adding conditions on locations being different ------------
+  for (i=1; i<=w; i++)
+  {
+    for (j=i+1; j<=w; j++)
+    {
+      crht_md=crht_md,Z(i)*Z(j)*p_poly(n,i,j);
+    }
+  }
+
+  export crht_md;
+  return(@crht_md);
+}
+example
+{
+  "EXAMPLE:"; echo=2;
+  intvec v = option(get);
+  // binary cyclic [15,7,5] code with defining set (1,3)
+
+  list defset=1,3;             // defining set
+  int n=15;                    // length
+  int d=5;                     // candidate for the minimum distance
+
+  def A=sysCRHTMindist(n,defset,d);
+  setring A;
+  A;                           // shows the ring we are working in
+  print(crht_md);              // the Sala's ideal for mindist
+  option(redSB);
+  ideal red_crht_md=std(crht_md);
+  print(red_crht_md);          // reduced Groebner basis
+
+  option(set,v);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// slightly modified mod function
+static proc mod_ (int n, int m)
+{
+  n=n mod m;
+  if (n<=0){ return(n+m);}
+  return(n);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc sysNewton (int n, list defset, int t, int q, int m, list #)
+"USAGE:   sysNewton (n,defset,t,q,m,[tr]); n,t,q,m,tr int, defset is list int's
+ at format
+         - n is length,
+         - defset is the defining set,
+         - t is the number of errors,
+         - q is basefield size,
+         - m is degree extension of the splitting field,
+         - if tr>0 it indicates that Newton identities in triangular
+           form should be constructed
+ at end format
+RETURN:  the ring to work with the generalized Newton identities (in
+         triangular form if applicable) containing the ideal with name 'newton'
+THEORY:  Based on 'defset' of the given cyclic code, the procedure constructs
+         the corresponding ideal 'newton' with the generalized Newton
+         identities. With its help one can solve the decoding problem. For
+         basics of the method @ref{Generalized Newton identities}.
+SEE ALSO: sysCRHT, sysBin
+EXAMPLE:  example sysNewton; shows an example
+"
+{
+ string s="ring @newton=("+string(q)+",a),(";
+ int i,j;
+ int flag;
+ int tr;
+
+ if (size(#)>0)
+ {
+  tr=#[1];
+ }
+
+ for (i=n; i>=1; i--)
+ {
+  for (j=1; j<=size(defset); j++)
+  {
+    flag=1;
+    if (i==defset[j])
+    {
+      flag=0;
+      break;
+    }
+  }
+  if (flag)
+  {
+    s=s+"S("+string(i)+"),";
+  }
+ }
+ s=s+"sigma(1.."+string(t)+"),";
+ for (i=size(defset); i>=2; i--)
+ {
+  s=s+"S("+string(defset[i])+"),";
+ }
+ s=s+"S("+string(defset[1])+")),lp;";
+
+ execute(s);
+
+ ideal newton;
+ poly sum;
+
+
+ //------------ generate generalized Newton identities ----------
+ if (tr)
+ {
+  for (i=1; i<=t; i++)
+  {
+    sum=0;
+    for (j=1; j<=i-1; j++)
+    {
+      sum=sum+sigma(j)*S(i-j);
+    }
+    newton=newton,S(i)+sum+number(i)*sigma(i);
+  }
+ } else
+ {
+  for (i=1; i<=t; i++)
+  {
+    sum=0;
+    for (j=1; j<=t; j++)
+    {
+      sum=sum+sigma(j)*S(mod_(i-j,n));
+    }
+    newton=newton,S(i)+sum;
+  }
+ }
+ for (i=1; i<=n-t; i++)
+ {
+  sum=0;
+  for (j=1; j<=t; j++)
+  {
+    sum=sum+sigma(j)*S(t+i-j);
+  }
+  newton=newton,S(t+i)+sum;
+ }
+
+ //----------- add field equations on sigma's --------------
+ for (i=1; i<=t; i++)
+ {
+  newton=newton,sigma(i)^(q^m)-sigma(i);
+ }
+
+ //----------- add conjugacy relations ------------------
+ for (i=1; i<=n; i++)
+ {
+  newton=newton,S(i)^q-S(mod_(q*i,n));
+ }
+ newton=simplify(newton,2);
+ export newton;
+ return(@newton);
+}
+example
+{
+     "EXAMPLE:";  echo = 2;
+     // Newton identities for a binary 3-error-correcting cyclic code of
+     //length 31 with defining set (1,5,7)
+
+     int n=31;          // length
+     list defset=1,5,7; //defining set
+     int t=3;           // number of errors
+     int q=2;           // basefield size
+     int m=5;           // degree extension of the splitting field
+     int tr=1;          // indicator of triangular form of Newton identities
+
+
+     def A=sysNewton(n,defset,t,q,m);
+     setring A;
+     A;                 // shows the ring we are working in
+     print(newton);     // generalized Newton identities
+
+     //===============================
+     A=sysNewton(n,defset,t,q,m,tr);
+     setring A;
+     print(newton);     // generalized Newton identities in triangular form
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// forms a list of special combinations needed for computation of Waring's
+//function
+static proc combinations_sum (int m, int n)
+{
+ list result;
+ list comb=combinations(m-1,n+m-1);
+ int i,j,flag,count;
+ list interm=comb;
+ for (i=1; i<=size(comb); i++)
+ {
+  interm[i][1]=comb[i][1]-1;
+  for (j=2; j<=m-1; j++)
+  {
+   interm[i][j]=comb[i][j]-comb[i][j-1]-1;
+  }
+  interm[i][m]=n+m-comb[i][m-1]-1;
+  flag=1;
+  count=2;
+  while ((flag)&&(count<=m))
+  {
+   if (interm[i][count] mod count != 0) {flag=0;}
+   count++;
+  }
+  if (flag)
+  {
+   for (j=2; j<=m; j++)
+   {
+    interm[i][j]=interm[i][j] div j;
+   }
+   result[size(result)+1]=interm[i];
+  }
+ }
+ return(result);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//if n=q^e*m, m and n are coprime, then return e
+static proc exp_count (int n, int q)
+{
+ int flag=1;
+ int result=0;
+ while(flag)
+ {
+  if (n mod q != 0) {flag=0;}
+   else {n=n div q; result++;}
+ }
+ return(result);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+
+proc sysBin (int v, list Q, int n, list #)
+"USAGE:    sysBin (v,Q,n,[odd]);  v,n,odd are int, Q is list of int's
+ at format
+          - v a number if errors,
+          - Q is a defining set of the code,
+          - n the length,
+          - odd is an additional parameter: if
+           set to 1, then the defining set is enlarged by odd elements,
+           which are 2^(some power)*(some elment in the def.set) mod n
+ at end format
+RETURN:    the ring with the resulting system called 'bin'
+THEORY:  Based on Q of the given cyclic code, the procedure constructs
+         the corresponding ideal 'bin' with the use of the Waring function.
+         With its help one can solve the decoding problem.
+         For basics of the method @ref{Generalized Newton identities}.
+SEE ALSO: sysNewton, sysCRHT
+EXAMPLE:   example sysBin; shows an example
+"
+{
+ int odd;
+ if (size(#)>0)
+ {
+  odd=#[1];
+ }
+
+ //ring r=2,(sigma(1..v),S(1..n)),(lp(v),dp(n));
+ ring r=2,(S(1..n),sigma(1..v)),lp;
+ list cyclot;
+ ideal result;
+ int i,j,k,s;
+ list comb;
+ poly sum_, mon;
+ int count1, count2, upper, coef_, flag, gener;
+ list Q_update;
+ if (odd==1)
+ {
+  for (i=1; i<=n; i++)
+  {
+   cyclot[i]=0;
+  }
+  for (i=1; i<=size(Q); i++)
+  {
+   flag=1;
+   gener=Q[i];
+   while(flag)
+   {
+    cyclot[gener]=1;
+    gener=2*gener mod n;
+    if (gener == Q[i]) {flag=0;}
+   }
+  }
+  for (i=1; i<=n; i++)
+  {
+   if ((cyclot[i] == 1)&&(i mod 2 == 1)) {Q_update[size(Q_update)+1]=i;}
+  }
+ }
+ else
+ {
+  Q_update=Q;
+ }
+
+ //---- form polynomials for the Bin system via Waring's function ---------
+ for (i=1; i<=size(Q_update); i++)
+ {
+  comb=combinations_sum(v,Q_update[i]);
+  sum_=0;
+  for (k=1; k<=size(comb); k++)
+  {
+   upper=0;
+   for (j=1; j<=v; j++)
+   {
+    upper=upper+comb[k][j];
+   }
+   count1=0;
+   for (j=2; j<=upper-1; j++)
+   {
+    count1=count1+exp_count(j,2);
+   }
+   count1=count1+exp_count(Q_update[i],2);
+   count2=0;
+   for (j=1; j<=v; j++)
+   {
+    for (s=2; s<=comb[k][j]; s++)
+    {
+     count2=count2+exp_count(s,2);
+    }
+   }
+   if (count1<count2) {print("ERRORsysBin");}
+   if (count1>count2) {coef_=0;}
+   if (count1 == count2) {coef_=1;}
+   mon=1;
+   for (j=1; j<=v; j++)
+   {
+    mon=mon*sigma(j)^(comb[k][j]);
+   }
+   sum_=sum_+coef_*mon;
+  }
+  result=result,S(Q_update[i])-sum_;
+ }
+ ideal bin=simplify(result,2);
+ export bin;
+ return(r);
+}
+example
+{
+     "EXAMPLE:";  echo = 2;
+     // [31,16,7] quadratic residue code
+     list l=1,5,7,9,19,25;
+     // we do not need even synromes here
+     def A=sysBin(3,l,31);
+     setring A;
+     print(bin);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc encode (matrix x, matrix g)
+"USAGE:  encode (x, g);  x a row vector (message), and g a generator matrix
+RETURN:  corresponding codeword
+EXAMPLE: example encode; shows an example
+"
+{
+ if (nrows(x)>1) {print("ERRORencode1!");}
+ if (ncols(x)!=nrows(g)) {print("ERRORencode2!");}
+ return(x*g);
+}
+example
+{
+     "EXAMPLE:";  echo = 2;
+     ring r=2,x,dp;
+     matrix x[1][4]=1,0,1,0;
+     matrix g[4][7]=1,0,0,0,0,1,1,
+                    0,1,0,0,1,0,1,
+                    0,0,1,0,1,1,1,
+                    0,0,0,1,1,1,0;
+     //encode x with the generator matrix g
+     print(encode(x,g));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc syndrome (matrix h, matrix c)
+"USAGE:  syndrome (h, c);  h a check matrix, c a row vector (codeword)
+RETURN:  corresponding syndrome
+EXAMPLE: example syndrome; shows an example
+"
+{
+ if (nrows(c)>1) {print("ERRORsyndrome1!");}
+ if (ncols(c)!=ncols(h)) {print("ERRORsyndrome2!");}
+ return(h*transpose(c));
+}
+example
+{
+     "EXAMPLE:";  echo = 2;
+     ring r=2,x,dp;
+     matrix x[1][4]=1,0,1,0;
+     matrix g[4][7]=1,0,0,0,0,1,1,
+                    0,1,0,0,1,0,1,
+                    0,0,1,0,1,1,1,
+                    0,0,0,1,1,1,0;
+     //encode x with the generator matrix g
+     matrix c=encode(x,g);
+     // disturb
+     c[1,3]=0;
+     //compute syndrome
+     //corresponding check matrix
+     matrix check[3][7]=1,0,0,1,1,0,1,0,1,0,1,0,1,1,0,0,1,0,1,1,1;
+     print(syndrome(check,c));
+     c[1,3]=1;
+     //now c is a codeword
+     print(syndrome(check,c));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// (coordinatewise) star product of two vectors
+static proc star(matrix m, int i, int j)
+{
+ matrix result[ncols(m)][1];
+ for (int k=1; k<=ncols(m); k++)
+ {
+  result[k,1]=m[i,k]*m[j,k];
+ }
+ return(result);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc sysQE(matrix check, matrix y, int t, list #)
+"USAGE:   sysQE(check,y,t,[fieldeq,formal]);check,y matrix;t,fieldeq,formal int
+ at format
+        - check is a parity check matrix of the code
+        - y is a received word,
+        - t the number of errors to be corrected,
+        - if fieldeq=1, then field equations are added,
+        - if formal=0, field equations on (known) syndrome variables
+          are not added, in order to add them (note that the exponent should
+          be equal to the number of elements in the INITIAL alphabet) one
+          needs to set formal>0 for the exponent
+ at end format
+RETURN:   the ring to work with together with the resulting system called 'qe'
+THEORY:  Based on 'check' of the given linear code, the procedure constructs
+         the corresponding ideal that gives an opportunity to compute
+         unknown syndrome of the received word y. After computing the unknown
+         syndromes one is able to solve the decoding problem.
+         For basics of the method @ref{Decoding method based on quadratic equations}.
+SEE ALSO: sysFL
+EXAMPLE:  example sysQE; shows an example
+"
+{
+ int fieldeq;
+ int formal;
+ if (size(#)>0)
+ {
+  fieldeq=#[1];
+ }
+ if (size(#)>1)
+ {
+  formal=#[2];
+ }
+
+ def br=basering;
+ list rl=ringlist(br);
+
+ int red=nrows(check);
+ int n=ncols(check);
+ int q=rl[1][1];
+
+ if (formal==0)
+ {
+  ring work=(q,a),(V(1..t),U(1..n)),dp;
+ } else
+ {
+  ring work=(q,a),(V(1..t),U(1..n),s(1..red)),(dp(t),lp(n),dp(red));
+ }
+
+ matrix check=imap(br,check);
+ matrix y=imap(br,y);
+
+ matrix h_full=genMDSMat(n,a);
+ matrix h=submat(h_full,1..red,1..n);
+ if (nrows(y)!=1) {print("ERROR1Pell");}
+ if (ncols(y)!=n) {print("ERROR2Pell");}
+
+ ideal result;
+
+ list c;
+ list a;
+ list tmp,tmp2;
+ int i,j,l,k;
+ number sum,prod,sig;
+        poly sum1,sum2,sum3;
+ for (i=1; i<=n; i++)
+ {
+  c[i]=tmp;
+ }
+
+ matrix transf=inverse(transpose(h_full));
+
+ //------ expression matrix of check vectors w.r.t. the MDS basis -----------
+ for (i=1; i<=red ; i++)
+ {
+  a[i]=transpose(submat(check,i..i,1..n));
+  a[i]=transf*a[i];
+ }
+
+ //----------- compute the structure constants ------------------------
+ matrix te[n][1];
+ for (i=1; i<=n; i++)
+ {
+  for (j=1; j<=t+1; j++)
+  {
+   if ((j<i)&&(i<=t+1)) {c[i][j]=c[j][i];}
+   else
+   {
+    if (i+j<=n+1)
+    {
+     c[i][j]=te;
+     c[i][j][i+j-1,1]=1;
+    }
+    else
+    {
+     c[i][j]=star(h_full,i,j);
+     c[i][j]=transf*c[i][j];
+    }
+   }
+  }
+ }
+
+
+ if (formal==0)
+ {
+  matrix s[red][1]=syndrome(check,y);
+  for (j=1; j<=red; j++)
+  {
+   sum1=0;
+   for (l=1; l<=n; l++)
+   {
+    sum1=sum1+a[j][l,1]*U(l);
+   }
+   result=result,sum1-s[j,1];
+  }
+ } else
+ {
+  for (j=1; j<=red; j++)
+  {
+   sum1=0;
+   for (l=1; l<=n; l++)
+   {
+    sum1=sum1+a[j][l,1]*U(l);
+   }
+   result=result,sum1-s(j);
+  }
+  for (j=1; j<=red; j++)
+  {
+     result=result,s(j)^(formal)-s(j);
+  }
+ }
+ if (fieldeq)
+ {
+  for (i=1; i<=n; i++)
+  {
+   result=result,U(i)^q-U(i);
+  }
+  for (j=1; j<=t; j++)
+  {
+     result=result,V(j)^q-V(j);
+  }
+ }
+
+ //----- form the quadratic equations according to the theory -----------
+ for (i=1; i<=n; i++)
+ {
+  sum1=0;
+  for (j=1; j<=t; j++)
+  {
+   sum2=0;
+   for (l=1; l<=n; l++)
+   {
+    sum2=sum2+c[i][j][l,1]*U(l);
+   }
+   sum1=sum1+sum2*V(j);
+  }
+  sum3=0;
+  for (l=1; l<=n; l++)
+  {
+   sum3=sum3+c[i][t+1][l,1]*U(l);
+  }
+  result=result,sum1-sum3;
+ }
+
+ result=simplify(result,2);
+
+ ideal qe=result;
+ export qe;
+ return(work);
+}
+example
+{
+     "EXAMPLE:";  echo = 2;
+     intvec v = option(get);
+
+     //correct 2 errors in [7,3] 8-ary code RS code
+     int t=2; int q=8; int n=7; int redun=4;
+     ring r=(q,a),x,dp;
+     matrix h_full=genMDSMat(n,a);
+     matrix h=submat(h_full,1..redun,1..n);
+     matrix g=dual_code(h);
+     matrix x[1][3]=0,0,1,0;
+     matrix y[1][7]=encode(x,g);
+
+     //disturb with 2 errors
+     matrix rec[1][7]=errorInsert(y,list(2,4),list(1,a));
+
+     //generate the system
+     def A=sysQE(h,rec,t);
+     setring A;
+     print(qe);
+
+     //let us decode
+     option(redSB);
+     ideal sys_qe=std(qe);
+     print(sys_qe);
+
+     option(set,v);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc errorInsert(matrix y, list pos, list val)
+"USAGE:  errorInsert(y,pos,val); y is matrix, pos,val are list of int's
+ at format
+        - y is a (code) word,
+        - pos = positions where errors occured,
+        - val = their corresponding values
+ at end format
+RETURN:  corresponding received word
+EXAMPLE: example errorInsert; shows an example
+"
+{
+ matrix result[1][ncols(y)]=y;
+ if (size(pos)!=size(val)) {print("ERRORerror");}
+ for (int i=1; i<=size(pos); i++)
+ {
+  result[1,pos[i]]=y[1,pos[i]]+val[i];
+ }
+ return(result);
+}
+example
+{
+     "EXAMPLE:";  echo = 2;
+     //correct 2 errors in [7,3] 8-ary code RS code
+     int t=2; int q=8; int n=7; int redun=4;
+     ring r=(q,a),x,dp;
+     matrix h_full=genMDSMat(n,a);
+     matrix h=submat(h_full,1..redun,1..n);
+     matrix g=dual_code(h);
+     matrix x[1][3]=0,0,1,0;
+     matrix y[1][7]=encode(x,g);
+     print(y);
+
+     //disturb with 2 errors
+     matrix rec[1][7]=errorInsert(y,list(2,4),list(1,a));
+     print(rec);
+     print(rec-y);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc errorRand(matrix y, int num, int e)
+"USAGE:    errorRand(y, num, e); y is matrix, num,e are int
+ at format
+          - y is a (code) word,
+          - num is the number of errors,
+          - e is an extension degree (if one wants values to be from GF(p^e))
+ at end format
+RETURN:    corresponding received word
+EXAMPLE:   example errorRand; shows an example
+"
+{
+ matrix result[1][ncols(y)]=y;
+ int i,j, flag, temp;
+ list pos, val;
+ matrix tempnum;
+
+ for (i=1; i<=num; i++)
+ {
+  while(1)
+  {
+   temp=random(1,ncols(y));
+   flag=1;
+   for (j=1; j<=size(pos); j++)
+   {
+    if (temp==pos[j]) {flag=0;}
+   }
+   if (flag) {pos[i]=temp;break;}
+  }
+ }
+
+ for (i=1; i<=num; i++)
+ {
+  flag=1;
+  while(flag)
+  {
+   tempnum=randomvector(1,e);
+   if (tempnum!=0) {flag=0;}
+  }
+  val[i]=tempnum;
+ }
+
+ for (i=1; i<=size(pos); i++)
+ {
+  result[1,pos[i]]=y[1,pos[i]]+val[i];
+ }
+ return(result);
+}
+example
+{
+  "EXAMPLE:";  echo = 2;
+     //correct 2 errors in [7,3] 8-ary code RS code
+     int t=2; int q=8; int n=7; int redun=4;
+     ring r=(q,a),x,dp;
+     matrix h_full=genMDSMat(n,a);
+     matrix h=submat(h_full,1..redun,1..n);
+     matrix g=dual_code(h);
+     matrix x[1][3]=0,0,1,0;
+     matrix y[1][7]=encode(x,g);
+
+     //disturb with 2 random errors
+     matrix rec[1][7]=errorRand(y,2,3);
+     print(rec);
+     print(rec-y);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc randomCheck(int m, int n, int e)
+"USAGE:    randomCheck(m, n, e); m,n,e are int
+ at format
+          - m x n are dimensions of the matrix,
+          - e is an extension degree (if one wants values to be from GF(p^e))
+ at end format
+RETURN:    random check matrix
+EXAMPLE:   example randomCheck; shows an example
+"
+{
+ matrix result[m][n];
+ matrix rand[m][n-m];
+ int i,j;
+ matrix temp;
+ for (i=1; i<=m; i++)
+ {
+  temp=randomvector(n-m,e);
+  for (j=1; j<=n-m; j++)
+  {
+   rand[i,j]=temp[j,1];
+  }
+ }
+ result=concat(rand,unitmat(m));
+ return(result);
+}
+example
+{
+  "EXAMPLE:";  echo = 2;
+     int redun=5; int n=15;
+     ring r=2,x,dp;
+
+     //generate random check matrix for a [15,5] binary code
+     matrix h=randomCheck(redun,n,1);
+     print(h);
+
+     //corresponding generator matrix
+     matrix g=dual_code(h);
+     print(g);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc genMDSMat(int n, number a)
+"USAGE:   genMDSMat(n, a); n is int, a is number
+ at format
+        - n x n are dimensions of the MDS matrix,
+        - a is a primitive element of the field.
+ at end format
+NOTE:   An MDS matrix is constructed in the following way. We take 'a' to be a
+        generator of the multiplicative group of the field. Then we construct
+        the Vandermonde matrix with this 'a'.
+ASSUME:   extension field should already be defined
+RETURN:   a matrix with the MDS property.
+SEE ALSO: Decoding method based on quadratic equations
+EXAMPLE:  example genMDSMat; shows an example
+"
+{
+ int i,j;
+ matrix result[n][n];
+ for (i=0; i<=n-1; i++)
+ {
+  for (j=0; j<=n-1; j++)
+  {
+   result[j+1,i+1]=(a^i)^j;
+  }
+ }
+ return(result);
+}
+example
+{
+     "EXAMPLE:";  echo = 2;
+     int q=16; int n=15;
+     ring r=(q,a),x,dp;
+
+     //generate an MDS (Vandermonde) matrix
+     matrix h_full=genMDSMat(n,a);
+     print(h_full);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+
+proc mindist (matrix check)
+"USAGE:  mindist (check, q); check matrix, q int
+ at format
+        - check is a check matrix,
+        - q is the field size
+ at end format
+RETURN:  minimum distance of the code
+EXAMPLE: example mindist; shows an example
+"
+{
+ intvec vopt = option(get);
+
+ int n=ncols(check); int redun=nrows(check); int t=redun+1;
+
+ def br=basering;
+ list rl=ringlist(br);
+ int q=rl[1][1];
+
+ ring work=(q,a),(V(1..t),U(1..n)),dp;
+ matrix check=imap(br,check);
+
+ ideal temp;
+ int count=1;
+ int flag=1;
+ int flag2;
+ int i;
+ matrix z[1][n];
+ option(redSB);
+ def A=sysQE(check,z,count);
+
+ //proceed with solving the system w.r.t zero vector until some solutions
+ //are found
+ while (flag)
+ {
+    A=sysQE(check,z,count);
+    setring A;
+    ideal temp=qe;
+    temp=std(temp);
+    flag2=1;
+    setring work;
+    temp=imap(A,temp);
+    for (i=1; i<=n; i++)
+    {
+      if
+        (temp[i]!=U(n-i+1))
+        {
+          flag2=0;
+        }
+    }
+    if (!flag2)
+    {
+      flag=0;
+    }
+    else
+    {
+      count++;
+    }
+ }
+ int result=count;
+
+ option(set,vopt);
+ return(result);
+}
+example
+{
+     "EXAMPLE:";  echo = 2;
+     //determine a minimum distance for a [7,3] binary code
+     int q=8; int n=7; int redun=4; int t=redun+1;
+     ring r=(q,a),x,dp;
+
+     //generate random check matrix
+     matrix h=randomCheck(redun,n,1);
+     print(h);
+     int l=mindist(h);
+     l;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc decode(matrix check, matrix rec)
+"USAGE:    decode(check, rec, t); check, rec matrix, t int
+ at format
+          - check is the check matrix of the code,
+          - rec is a received word,
+          - t is an upper bound for the number of errors one wants to correct
+ at end format
+NOTE:     The method described in @ref{Decoding method based on quadratic equations}
+          is used for decoding.
+ASSUME:   Errors in rec should be correctable, otherwise the output is
+          unpredictable
+RETURN:   a codeword that is closest to rec
+EXAMPLE:  example decode; shows an example
+"
+{
+ intvec vopt = option(get);
+
+ def br=basering;
+ int n=ncols(check);
+
+ int count=1;
+ def A=sysQE(check,rec,count);
+ while(1)
+ {
+  A=sysQE(check,rec,count);
+  setring A;
+  matrix h_full=genMDSMat(n,a);
+  matrix rec=imap(br,rec);
+  option(redSB);
+  ideal qe_red=std(qe);
+  if (qe_red[1]!=1)
+  {
+    break;
+  }
+  else
+  {
+    count++;
+  }
+  setring br;
+ }
+
+ setring A;
+
+ //obtain a codeword
+ //this works only if our code is indeed can correct these errors
+ matrix syn[n][1];
+ for (int i=1; i<=n; i++)
+ {
+  syn[i,1]=-qe_red[n-i+1]+lead(qe_red[n-i+1]);
+ }
+
+ matrix real_syn=inverse(h_full)*syn;
+ setring br;
+ matrix real_syn=imap(A,real_syn);
+
+ option(set,vopt);
+ return(rec-transpose(real_syn));
+}
+example
+{
+     "EXAMPLE:";  echo = 2;
+     //correct 1 error in [15,7] binary code
+     int t=1; int q=16; int n=15; int redun=10;
+     ring r=(q,a),x,dp;
+
+     //generate random check matrix
+     matrix h=randomCheck(redun,n,1);
+     matrix g=dual_code(h);
+     matrix x[1][n-redun]=0,0,1,0,1,0,1;
+     matrix y[1][n]=encode(x,g);
+     print(y);
+
+     // find out the minimum distance of the code
+     list l=mindist(h);
+
+     //disturb with errors
+     "Correct ",(l[1]-1) div 2," errors";
+     matrix rec[1][n]=errorRand(y,(l[1]-1) div 2,1);
+     print(rec);
+
+     //let us decode
+     matrix dec_word=decode(h,rec);
+     print(dec_word);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+
+proc decodeRandom(int n, int redun, int ncodes, int ntrials, list #)
+"USAGE:    decodeRandom(redun,q,ncodes,ntrials,[e]); all parameters int
+ at format
+          - redun is a redundabcy of a (random) code,
+          - q is the field size,
+          - ncodes is the number of random codes to be processed,
+          - ntrials is the number of received vectors per code to be corrected
+          - If e is given it sets the correction capacity explicitly. It
+          should be used in case one expects some lower bound,
+          otherwise the procedure tries to compute the real minimum distance
+          to find out the error-correction capacity
+ at end format
+RETURN:    nothing;
+EXAMPLE:   example decodeRandom; shows an example
+"
+{
+ intvec vopt = option(get);
+
+ int i,j;
+ matrix h;
+ int dist, t;
+ ideal sys;
+ int tmp;
+ int e;
+ if (size(#)>0)
+ {
+  e=#[1];
+ }
+
+ option(redSB);
+ def br=basering;
+ matrix h_full=genMDSMat(n,a);
+ matrix z[1][ncols(h_full)];
+
+ //------------------ determine error-correction capacity -------------------
+ for (i=1; i<=ncodes; i++)
+ {
+  setring br;
+  h=randomCheck(redun,n,1);
+  "check matrix:";
+  print(h);
+  if (e>0)
+  {
+     t=e;
+  } else {
+     tmp=mindist(h);
+     dist=tmp;
+     printf("d= %p",dist);
+     t=(dist-1) div 2;
+  }
+
+  //------------- generate the template system ----------------------
+  def A=sysQE(h,z,t);
+  setring A;
+  matrix word,y,rec;
+  ideal sys2,sys3;
+  matrix h=imap(br,h);
+  matrix g=dual_code(h);
+  ideal sys=qe;
+  print("The system is generated");
+
+  //------ modify the template according to every received word --------------
+  for (j=1; j<=ntrials; j++)
+  {
+   word=randomvector(n-redun,1);
+   y=encode(transpose(word),g);
+   print("Codeword:");
+   print(y);
+   rec=errorRand(y,t,1);
+   print("Received word:");
+   print(rec);
+   sys2=add_synd(rec,h,redun,sys);
+   option(redSB);
+   sys3=std(sys2);
+   print("The Groebenr basis of the QE system:");
+   print(sys3);
+  }
+  kill A;
+  option(set,vopt);
+ }
+}
+example
+{
+     "EXAMPLE:";  echo = 2;
+     int q=32; int n=25; int redun=n-11; int t=redun+1;
+     ring r=(q,a),x,dp;
+
+     // correct 2 errors in 2 random binary codes, 3 trials each
+     decodeRandom(n,redun,2,3,2);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+
+proc decodeCode(matrix check, int ntrials, list #)
+"USAGE:     decodeCode(check, ntrials, [e]); check matrix, ntrials,e int
+ at format
+           - check is a parity check matrix for the code,
+           - ntrials is the number of received vectors per code to be
+           corrected.
+           - If e is given it sets the correction capacity explicitly. It
+           should be used in case one expects some lower bound,
+           otherwise the procedure tries to compute the real minimum distance
+           to find out the error-correction capacity
+ at end format
+RETURN:     nothing;
+EXAMPLE:    example decodeCode; shows an example
+"
+{
+ intvec vopt = option(get);
+
+ int n=ncols(check);
+ int redun=nrows(check);
+ int i,j;
+ matrix h;
+ int dist, t;
+ ideal sys;
+ int tmp;
+ int e;
+ if (size(#)>0)
+ {
+  e=#[1];
+ }
+
+ option(redSB);
+ def br=basering;
+ matrix h_full=genMDSMat(n,a);
+ matrix z[1][ncols(h_full)];
+ setring br;
+ h=check;
+ "check matrix:";
+ print(h);
+
+ //------------------ determine error-correction capacity -------------------
+ if (e>0)
+ {
+    t=e;
+ } else {
+   tmp=mindist(h);
+   dist=tmp;
+   printf("d= %p",dist);
+   t=(dist-1) div 2;
+ }
+
+ //------------- generate the template system ----------------------
+ def A=sysQE(h,z,t);
+ setring A;
+ matrix word,y,rec;
+ ideal sys2,sys3;
+ matrix h=imap(br,h);
+ matrix g=dual_code(h);
+ ideal sys=qe;
+ print("The system is generated");
+
+ //--- modify the template according to every received word ---------------
+ for (j=1; j<=ntrials; j++)
+ {
+   word=randomvector(n-redun,1);
+   y=encode(transpose(word),g);
+   print("Codeword:");
+   print(y);
+   rec=errorRand(y,t,1);
+   print("Received word:");
+   print(rec);
+   sys2=add_synd(rec,h,redun,sys);
+   option(redSB);
+   sys3=std(sys2);
+   print("Groebner basis of the QE system:");
+   print(sys3);
+ }
+
+ option(set,vopt);
+}
+example
+{
+     "EXAMPLE:";  echo = 2;
+     int q=32; int n=25; int redun=n-11; int t=redun+1;
+     ring r=(q,a),x,dp;
+     matrix check=randomCheck(redun,n,1);
+
+     // correct 2 errors in using the code above, 3 trials
+     decodeCode(check,3,2);
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+// adding syndrome values to the template system
+static proc add_synd (matrix rec, matrix check, int redun, ideal sys)
+{
+     ideal result=sys;
+     matrix s[redun][1]=syndrome(check,rec);
+     for (int i=1; i<=redun; i++)
+
+     {
+          result[i]=result[i]-s[i,1];
+     }
+     return(result);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// evaluate a polynomial at a given point
+static proc ev (poly f, matrix p)
+{
+     if (ncols(p)>1) {ERROR("not a column vector");};
+     int m=size(p);
+     poly temp=f;
+     for (int i=1; i<=m; i++)
+     {
+          temp=subst(temp,var(i),p[i,1]);
+     }
+     return(number(temp));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// return index of an element in the ideal where it does not vanish at the
+//given point
+static proc find_index (ideal G, matrix p)
+{
+     if (ncols(p)>1) {ERROR("not a column vector");};
+     int i=1;
+     int n=size(G);
+     while(i<=n)
+     {
+          if (ev(G[i],p)!=0) {return(i);}
+          i++;
+     }
+     return(-1);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// convert ideal to list
+static proc ideal2list (ideal id)
+{
+     list l;
+     for (int i=1; i<=size(id); i++)
+     {
+          l[i]=id[i];
+     }
+     return(l);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// convert list to ideal
+static proc list2ideal (list l)
+{
+     ideal id;
+     for (int i=1; i<=size(l); i++)
+     {
+          id[i]=l[i];
+     }
+     return(id);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// check whether given polynomial is divisible by some leading monomial of the
+//ideal
+static proc divisible (poly m, ideal G)
+{
+     for (int i=1; i<=size(G); i++)
+     {
+          if (m/leadmonom(G[i])!=0) {return(1);}
+     }
+     return(0);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc vanishId (list points)
+"USAGE:  vanishId (points); point is a list of matrices
+        'points' is a list of points for which the vanishing ideal is to be
+        constructed
+RETURN:  Vanishing ideal corresponding to the given set of points
+EXAMPLE: example vanishId; shows an example
+"
+{
+     int m=size(points[1]);
+     int n=size(points);
+
+     ideal G=1;
+     int i,k,j;
+     list temp;
+     poly h,cur;
+
+     //------------- proceed according to Farr-Gao algorithm ----------------
+     for (k=1; k<=n; k++)
+     {
+          i=find_index(G,points[k]);
+          cur=G[i];
+          for(j=i+1; j<=size(G); j++)
+          {
+               G[j]=G[j]-ev(G[j],points[k])/ev(G[i],points[k])*G[i];
+          }
+          G=simplify(G,2);
+          temp=ideal2list(G);
+          temp=delete(temp,i);
+          G=list2ideal(temp);
+          for (j=1; j<=m; j++)
+          {
+               if (!divisible(var(j)*leadmonom(cur),G))
+               {
+                    attrib(G,"isSB",1);
+                    h=NF((var(j)-points[k][j,1])*cur,G);
+                    temp=ideal2list(G);
+                    temp=insert(temp,h);
+                    G=list2ideal(temp);
+                    G=sort(G)[1];
+               }
+          }
+     }
+     attrib(G,"isSB",1);
+     return(G);
+}
+example
+{
+     "EXAMPLE:";  echo = 2;
+      ring r=3,(x(1..3)),dp;
+
+     //generate all 3-vectors over GF(3)
+     list points=pointsGen(3,1);
+
+     list points2=convPoints(points);
+
+     //grasps the first 11 points
+     list p=graspList(points2,1,11);
+     print(p);
+
+     //construct the vanishing ideal
+     ideal id=vanishId(p);
+     print(id);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// construct the list of all vectors of length m with elements in p^e, where p
+// is theharacteristic
+proc pointsGen (int m, int e)
+{
+     if (e>1)
+     {
+     list result;
+     int count=1;
+     int i,j;
+     list l=ringlist(basering);
+     int charac=l[1][1];
+     number a=par(1);
+     list tmp;
+     for (i=1; i<=charac^(e*m); i++)
+     {
+          result[i]=tmp;
+     }
+     if (m==1)
+     {
+          result[count][m]=0;
+          count++;
+          for (j=1; j<=charac^(e)-1; j++)
+          {
+               result[count][m]=a^j;
+               count++;
+          }
+          return(result);
+     }
+     list prev=pointsGen(m-1,e);
+     for (i=1; i<=size(prev); i++)
+     {
+          result[count]=prev[i];
+          result[count][m]=0;
+          count++;
+          for (j=1; j<=charac^(e)-1; j++)
+          {
+               result[count]=prev[i];
+               result[count][m]=a^j;
+               count++;
+          }
+     }
+     return(result);
+     }
+
+     if (e==1)
+     {
+     list result;
+     int count=1;
+     int i,j;
+     list l=ringlist(basering);
+     int charac=l[1][1];
+     list tmp;
+     for (i=1; i<=charac^m; i++)
+     {
+          result[i]=tmp;
+     }
+     if (m==1)
+     {
+          for (j=0; j<=charac-1; j++)
+          {
+               result[count][m]=number(j);
+               count++;
+          }
+          return(result);
+     }
+     list prev=pointsGen(m-1,e);
+     for (i=1; i<=size(prev); i++)
+     {
+          for (j=0; j<=charac-1; j++)
+          {
+               result[count]=prev[i];
+               result[count][m]=number(j);
+               count++;
+          }
+     }
+     return(result);
+     }
+
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// convert list to a column vector
+static proc list2vec (list l)
+{
+     matrix m[size(l)][1];
+     for (int i=1; i<=size(l); i++)
+     {
+          m[i,1]=l[i];
+     }
+     return(m);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// convert all the point in the list with list2vec
+proc convPoints (list points)
+{
+     for (int i=1; i<=size(points); i++)
+     {
+          points[i]=list2vec(points[i]);
+     }
+     return(points);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// extracts elements from l in the range m..n
+proc graspList (list l, int m, int n)
+{
+     list result;
+     int count=1;
+     for (int i=m; i<=n; i++)
+     {
+          result[count]=l[i];
+          count++;
+     }
+     return(result);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// "characteristic" polynomial
+static proc xi_gen (matrix p, int e, int s)
+{
+     poly prod=1;
+     list rl=ringlist(basering);
+     int charac=rl[1][1];
+     int l;
+     for (l=1; l<=s; l++)
+     {
+          prod=prod*(1-(var(l)-p[l,1])^(charac^e-1));
+     }
+     return(prod);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// generating polynomials in Fitzgerald-Lax construction
+static proc gener_funcs (matrix check, list points, int e, ideal id, int s)
+{
+     int n=ncols(check);
+     if (n!=size(points)) {ERROR("Incompatible sizes of check and points");}
+     ideal xi;
+     int i,j;
+     for (i=1; i<=n; i++)
+     {
+          xi[i]=xi_gen(points[i],e,s);
+     }
+     ideal result;
+     int m=nrows(check);
+     poly sum;
+     for (i=1; i<=m; i++)
+     {
+          sum=0;
+          for (j=1; j<=n; j++)
+          {
+               sum=sum+check[i,j]*xi[j];
+          }
+          result[i]=NF(sum,id);
+     }
+     return(result);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc sysFL (matrix check, matrix y, int t, int e, int s)
+"USAGE:    sysFL (check,y,t,e,s); check,y matrix, t,e,s int
+ at format
+          - check is a parity check matrix of the code,
+          - y is a received word,
+          - t the number of errors to correct,
+          - e is the extension degree,
+          - s is the dimension of the point for the vanishing ideal
+ at end format
+RETURN:  the system of Fitzgerald-Lax for the given decoding problem
+THEORY:  Based on 'check' of the given linear code, the procedure constructs
+         the corresponding ideal constructed with a generalization of
+         Cooper's philosophy. For basics of the method @ref{Fitzgerald-Lax method}.
+SEE ALSO: sysQE
+EXAMPLE:   example sysFL; shows an example
+"
+{
+     list rl=ringlist(basering);
+     int charac=rl[1][1];
+     int n=ncols(check);
+     int m=nrows(check);
+     list points=pointsGen(s,e);
+     list points2=convPoints(points);
+     list p=graspList(points2,1,n);
+     ideal id=vanishId(p,e);
+     ideal funcs=gener_funcs(check,p,e,id,s);
+
+     ideal result;
+     poly temp;
+     int i,j,k;
+
+     //--------------- add vanishing realtions ---------------------
+     for (i=1; i<=t; i++)
+     {
+          for (j=1; j<=size(id); j++)
+          {
+               temp=id[j];
+               for (k=1; k<=s; k++)
+               {
+                    temp=subst(temp,var(k),x_var(i,k,s));
+               }
+               result=result,temp;
+          }
+     }
+
+     //--------------- add field equations --------------------
+     for (i=1; i<=t; i++)
+     {
+          for (k=1; k<=s; k++)
+          {
+               result=result,x_var(i,k,s)^(charac^e)-x_var(i,k,s);
+          }
+     }
+     for (i=1; i<=t; i++)
+     {
+          result=result,e(i)^(charac^e-1)-1;
+     }
+
+     result=simplify(result,8);
+
+     //--------------- add check realtions --------------------
+     poly sum;
+     matrix syn[m][1]=syndrome(check,y);
+     for (i=1; i<=size(funcs); i++)
+     {
+          sum=0;
+          for (j=1; j<=t; j++)
+          {
+               temp=funcs[i];
+               for (k=1; k<=s; k++)
+               {
+                    temp=subst(temp,var(k),x_var(j,k,s));
+               }
+               sum=sum+temp*e(j);
+          }
+          result=result,sum-syn[i,1];
+     }
+
+     result=simplify(result,2);
+
+     points=points2;
+     export points;
+     return(result);
+}
+example
+{
+     "EXAMPLE:";  echo = 2;
+     intvec vopt = option(get);
+
+     list l=FLpreprocess(3,1,11,2,"");
+     def r=l[1];
+     setring r;
+     int s_work=l[2];
+
+     //the check matrix of [11,6,5] ternary code
+     matrix h[5][11]=1,0,0,0,0,1,1,1,-1,-1,0,
+          0,1,0,0,0,1,1,-1,1,0,-1,
+          0,0,1,0,0,1,-1,1,0,1,-1,
+          0,0,0,1,0,1,-1,0,1,-1,1,
+          0,0,0,0,1,1,0,-1,-1,1,1;
+     matrix g=dual_code(h);
+     matrix x[1][6];
+     matrix y[1][11]=encode(x,g);
+     //disturb with 2 errors
+     matrix rec[1][11]=errorInsert(y,list(2,4),list(1,-1));
+
+     //the Fitzgerald-Lax system
+     ideal sys=sysFL(h,rec,2,1,s_work);
+     print(sys);
+     option(redSB);
+     ideal red_sys=std(sys);
+     red_sys;
+     // read the solutions from this redGB
+     // the points are (0,0,1) and (0,1,0) with error values 1 and -1 resp.
+     // use list points to find error positions;
+     points;
+
+     option(set,vopt);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// preprocessing steps for the Fitzgerald-Lax scheme
+proc FLpreprocess (int p, int e, int n, int t, string minp)
+{
+     ring r1=p,x,dp;
+     int s=1;
+     while(p^(s*e)<n)
+     {
+          s++;
+     }
+     list var_ord;
+     int i,j;
+     int count=1;
+     for (i=s; i>=1; i--)
+     {
+          var_ord[count]=string("x("+string(i)+")");
+          count++;
+     }
+     for (i=t; i>=1; i--)
+     {
+          var_ord[count]=string("e("+string(i)+")");
+          count++;
+          for (j=s; j>=1; j--)
+          {
+               var_ord[count]=string("x1("+string(s*(i-1)+j)+")");
+               count++;
+          }
+     }
+
+     list rl;
+     list tmp;
+
+     if (e>1)
+     {
+          rl[1]=tmp;
+          rl[1][1]=p;
+          rl[1][2]=tmp;
+          rl[1][2][1]=string("a");
+          rl[1][3]=tmp;
+          rl[1][3][1]=tmp;
+          rl[1][3][1][1]=string("lp");
+          rl[1][3][1][2]=1;
+          rl[1][4]=ideal(0);
+     } else {
+          rl[1]=p;
+     }
+
+     rl[2]=var_ord;
+
+     rl[3]=tmp;
+     rl[3][1]=tmp;
+     rl[3][1][1]=string("lp");
+     intvec v=1;
+     for (i=1; i<=size(var_ord)-1; i++)
+     {
+          v=v,1;
+     }
+     rl[3][1][2]=v;
+     rl[3][2]=tmp;
+     rl[3][2][1]=string("C");
+     rl[3][2][2]=intvec(0);
+
+     rl[4]=ideal(0);
+
+     def r2=ring(rl);
+     setring r2;
+     list l=ringlist(r2);
+     if (e>1)
+     {
+          execute(string("poly f="+minp));
+          ideal id=f;
+          l[1][4]=id;
+     }
+
+     def r=ring(l);
+     setring r;
+
+     return(list(r,s));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// imitating two indeces
+static proc x_var (int i, int j, int s)
+{
+     return(x1(s*(i-1)+j));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// random vector of length n with entries from p^e, p the characteristic
+static proc randomvector(int n, int e)
+{
+    int i;
+    matrix result[n][1];
+    for (i=1; i<=n; i++)
+    {
+        result[i,1]=asElement(random_prime_vector(e));
+    }
+    return(result);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// "convert" representation of an element from the field extension from vector
+//to an elelemnt
+static proc asElement(list l)
+{
+  number s;
+  int i;
+  number w=1;
+  if (size(l)>1) {w=par(1);}
+  for (i=0; i<=size(l)-1; i++)
+  {
+    s=s+w^i*l[i+1];
+  }
+  return(s);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// random vector of length n with entries from p, p the characteristic
+static proc random_prime_vector (int n)
+{
+  list rl=ringlist(basering);
+  int i, charac;
+  for (i=2; i<=rl[1][1]; i++)
+  {
+    if (rl[1][1] mod i ==0)
+    {
+      break;
+    }
+  }
+  charac=i;
+
+  list l;
+
+  for (i=1; i<=n; i++)
+  {
+    l=l+list(random(0,charac-1));
+  }
+  return(l);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc decodeRandomFL(int n, int redun, int p, int e, int t, int ncodes, int ntrials, string minpol)
+"USAGE:    decodeRandomFL(redun,p,e,n,t,ncodes,ntrials,minpol);
+ at format
+          - n is length of codes generated,
+          - redun = redundancy of codes generated,
+          - p is the characteristic,
+          - e is the extension degree,
+          - t is the number of errors to correct,
+          - ncodes is the number of random codes to be processed,
+          - ntrials is the number of received vectors per code to be corrected,
+          - minpol: due to some pecularities of SINGULAR one needs to provide
+          minimal polynomial for the extension explicitly
+ at end format
+RETURN:    nothing
+EXAMPLE:   example decodeRandomFL; shows an example
+"
+{
+ intvec vopt = option(get);
+
+ list l=FLpreprocess(p,e,n,t,minpol);
+
+ def r=l[1];
+ int s_work=l[2];
+ export(s_work);
+ setring r;
+
+ int i,j;
+ matrix h, g, word, y, rec;
+ ideal sys, sys2, sys3;
+
+
+ option(redSB);
+ matrix z[1][n];
+
+ for (i=1; i<=ncodes; i++)
+ {
+     h=randomCheck(redun,n,e);
+     g=dual_code(h);
+
+     //---------------- generate the template system -----------------------
+     sys=sysFL(h,z,t,e,s_work);
+
+     //------ modifying the template according to the received word ---------
+     for (j=1; j<=ntrials; j++)
+     {
+          word=randomvector(n-redun,1);
+          y=encode(transpose(word),g);
+          print("Codeword:");
+          print(y);
+          rec=errorRand(y,t,e);
+          print("Received word");
+          print(rec);
+          sys2=LF_add_synd(rec,h,sys);
+          sys3=std(sys2);
+          print("Groebner basis of the FL system:");
+          print(sys3);
+     }
+ }
+
+ option(set,vopt);
+}
+example
+{
+     "EXAMPLE:";  echo = 2;
+
+     // correcting one error for one random binary code of length 25,
+     // redundancy 14; 10 words are processed
+     decodeRandomFL(25,14,2,1,1,1,10,"");
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// add syndrome values to the template system in FL
+static proc LF_add_synd (matrix rec, matrix check, ideal sys)
+{
+     int redun=nrows(check);
+     ideal result=sys;
+     matrix s[redun][1]=syndrome(check,rec);
+     for (int i=size(sys)-redun+1; i<=size(sys); i++)
+     {
+          result[i]=result[i]-s[i-size(sys)+redun,1];
+     }
+     return(result);
+}
+
+
+/*
+//////////////     SOME RELATIVELY EASY EXAMPLES    //////////////
+///////////////////  THAT RUN AROUND ONE MINUTE  ////////////////
+
+"EXAMPLE:";  echo = 2;
+int q=128; int n=120; int redun=n-30;
+ring r=(q,a),x,dp;
+decodeRandom(n,redun,1,1,6);
+
+int q=128; int n=120; int redun=n-20;
+ring r=(q,a),x,dp;
+decodeRandom(n,redun,1,1,9);
+
+int q=128; int n=120; int redun=n-10;
+ring r=(q,a),x,dp;
+decodeRandom(n,redun,1,1,19);
+
+int q=256; int n=150; int redun=n-10;
+ring r=(q,a),x,dp;
+decodeRandom(n,redun,1,1,22);
+
+//////////////     SOME HARD EXAMPLES    //////////////////////
+//////      THAT MAYBE WILL BE DOABLE LATER     ///////////////
+
+1.) These random instances are not doable in <=1000 sec.
+
+"EXAMPLE:";  echo = 2;
+int q=128; int n=120; int redun=n-40;
+ring r=(q,a),x,dp;
+decodeRandom(n,redun,1,1,6);
+
+redun=n-30;
+decodeRandom(n,redun,1,1,8);
+
+redun=n-20;
+decodeRandom(n,redun,1,1,12);
+
+redun=n-10;
+decodeRandom(n,redun,1,1,24);
+
+int q=256; int n=150; int redun=n-10;
+ring r=(q,a),x,dp;
+decodeRandom(n,redun,1,1,26);
+
+
+2.) Generic decoding is hard!
+
+int q=32; int n=31; int redun=n-16; int t=3;
+ring r=(q,a),(V(1..n),U(n..1),s(redun..1)),(dp(n),lp(n),dp(redun));
+matrix check[redun][n]= 1,1,0,1,1,0,0,0,1,0,1,0,0,1,0,0,1,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,1,1,0,1,1,0,0,0,1,
+0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,1,1,0,1,1,0,0,0,1,0,1,0,0,1,0,0,1,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,1,1,0,0,
+0,1,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,1,1,0,1,1,0,0,0,1,0,1,0,0,1,0,0,1,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,1,1,
+0,0,0,1,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,1,1,0,1,1,0,0,0,1,0,1,0,0,1,0,
+0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,
+1,1,0,0,0,1,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,1,1,0,1,1,0,0,0,1,0,1,0,0,
+1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
+1,0,1,1,0,0,0,1,0,1,0,0,1,0,0,1,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,1,1,0,1,1,0,0,0,1,0,1,
+0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,1,1,0,1,1,0,0,0,1,0,1,0,0,1,0,0,1,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,1,1,0,0,0,1,
+0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,1,1,0,1,1,0,0,0,1,0,1,0,0,1,0,0,1,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,1,1,0,0,
+0,1,0,1,0,0,1,0,0,1;
+matrix rec[1][n];
+
+def A=sysQE(check,rec,t,1,2);
+setring A;
+print(qe);
+ideal red_qe=stdfglm(qe);
+
+*/
diff --git a/Singular/LIB/decomp.lib b/Singular/LIB/decomp.lib
new file mode 100644
index 0000000..3ffb020
--- /dev/null
+++ b/Singular/LIB/decomp.lib
@@ -0,0 +1,1655 @@
+///////////////////////////////////////////////////////////////////////
+version="version decomp.lib 4.0.0.0 Jun_2013 "; // $Id: 6bfa7a1841ebda249c7957bf6dba5c0da562ab52 $
+
+// last changed  21.5.12 C.G. reversal wieder eingefuegt (standalone)
+category = "general";
+info =
+"
+LIBRARY: decomp.lib  Functional Decomposition of Polynomials
+AUTHOR:  Christian Gorzel, University of Muenster
+email: gorzelc at math.uni-muenster.de
+
+
+OVERVIEW:
+ at texinfo
+ This library implements functional uni-multivariate decomposition
+ of multivariate polynomials.
+
+    A (multivariate) polynomial f is a composite if it can be written as
+    @math{g \\circ h} where g is univariate and h is multivariate,
+    where @math{\\deg(g), \\deg(h)>1}.
+
+    Uniqueness for monic polynomials is up to linear coordinate change
+ at tex
+     $g\\circ h  = g(x/c -d) \\circ c(h(x)+d)$.
+ at end tex
+
+    If f is a composite, then @code{decompose(f);} returns an ideal (g,h);
+    such that @math{\\deg(g) < \\deg(f)} is maximal, (@math{\\deg(h)\\geq 2}).
+    The polynomial h is, by the maximality of @math{\\deg(g)}, not a composite.
+
+    The polynomial g is univariate in the (first) variable vvar of f,
+    such that deg_vvar(f) is maximal.
+
+    @code{decompose(f,1);} computes a full decomposition, i.e. if f is a
+    composite, then an ideal @math{(g_1,\\dots ,g_m,h)} is returned, where
+    @math{g_i} are univariate and each entry is primitive such that
+    @math{f=g_1\\circ \\dots \\circ g_m\\circ h}.
+
+    If f is not a composite, for instance if @math{\\deg(f)} is prime,
+    then @code{decompose(f);} returns f.
+
+    The command @code{decompose} is the inverse: @code{compose(decompose(f,1))==f}.
+
+    Recall, that Chebyshev polynomials of the first kind commute by composition. @*
+
+    The decomposition algorithms work in the tame case, that is if
+    char(basering)=0 or p:=char(basering) > 0 but deg(g) is not divisible by
+    p.
+    Additionally, it works for monic polynomials over @math{Z} and in some
+    cases for monic polyomials over coefficient rings. @* See
+    @code{is_composite} for examples.  (It also works over the reals but
+    there it seems not be numerical stable.) @*
+
+    More information on the univariate resp. multivariate case. @*
+
+    Univariate decomposition is created, with the additional assumption
+    @math{\\deg(g), \\deg(h)>1}. @*
+
+    A multivariate polynomial f is a composite, if f can be written as
+    @math{g \\circ h}, where @math{g} is a univariate polynomial and @math{h}
+    is multivariate.  Note, that unlike in the univariate case, the polynomial
+    @math{h} may be of degree @math{1}. @*
+    E.g. @math{f = (x+y)^2+ 2(x+y) +1} is the composite of
+    @math{g = x^2+2x+1} and @math{h = x+y}. @*
+
+    If @code{nvars(basering)>1}, then, by default, a single-variable
+    multivariate polynomial is not considered to be the same as in the
+    one-variable polynomial ring; it will always be decomposed. That is: @*
+   @code{> ring r1=0,x,dp;} @*
+   @code{> decompose(x3+2x+1);} @*
+   @code{x3+2x+1} @*
+    but: @*
+   @code{> ring r2=0,(x,y),dp;} @*
+   @code{> decompose(x3+2x+1);} @*
+   @code{_[1]=x3+2x+1} @*
+   @code{_[2]=x} @*
+
+    In particular: @*
+    @code{is_composite(x3+2x+1)==1;}  in @code{ring r1} but  @*
+    @code{is_composite(x3+2x+1)==0;}  in @code{ring r2}. @*
+
+   This is justified by interpreting the polynomial decomposition as an
+   affine Stein factorization of the mapping @math{f:k^n \\to k, n\\geq 2}.
+
+      The behaviour can changed by the some global variables.
+
+    @code{int DECMETH;} choose von zur Gathen's or Kozen-Landau's method.
+@*    @code{int MINS;} compute f = g o h, such that h(0) = 0. @*
+    @code{int IMPROVE;} simplify the coefficients of g and h if f is
+    not monic. @*
+    @code{int DEGONE;} single-variable multivariate are
+    considered uni-variate. @*
+
+    See @code{decompopts;} for more information.
+
+    Additional information is displayed if @code{printlevel > 0}.
+ at end texinfo
+REFERENCES:
+ at texinfo
+ at tex
+D. Kozen, S. Landau: Polynomial Decomposition Algorithms, \\par
+  \\quad \\qquad          J. Symb. Comp. (1989), 7, 445-456. \\par
+J. von zu Gathen: Functional Decomposition of Polynomials: the Tame Case,\\par
+  \\quad \\qquad          J. Symb. Comp. (1990), 9, 281-299. \\par
+ J. von zur Gathen, J. Gerhard:  Modern computer algebra,  \\par
+  \\quad \\qquad          Cambridge University Press, Cambridge, 2003.
+ at end tex
+ at end texinfo
+PROCEDURES:
+// decompunivmonic(f,r);
+// decompmultivmonic(f,var,s);
+ decompopts([\"reset\"]);    displays resp. resets global options
+ decompose(f[,1]);           [complete] functional decomposition of poly f
+ is_composite(f);            predicate, is f a composite polynomial?
+ chebyshev(n[,1]);           the nth Chebyshev polynomial of the first kind
+ compose(f1,..,fn);          compose f1 (f2 (...(fn))), f_i polys of ideal
+
+AUXILIARY PROCEDURES:
+ makedistinguished(f,var);   transforms f to a var-distinguished polynomial
+// divisors(n[,1]);            intvec [increasing] of the divisors d of n
+// gcdv(v);                    the gcd of the entries in intvec v
+// maxdegs(f);                 maximal degree for each variable of the poly f
+// randomintvec(n,a,b[,1]);    random intvec size n, [non-zero] entries in {a,b}
+KEYWORDS: Functional decomposition
+";
+
+/*
+ decompunivpoly(poly f,list #)  // f = goh; r = deg g, s = deg h;
+
+ Ablauf ist:
+
+decompose(f)
+| check whether f is the composite by a monomial
+| check whether f is univariate
+| transformation to a distinguished polynomial
+     decompmultivmonic(f,vvar,r)
+         decompunivmonic(f,r)   // detect vvar by maxdegs
+     |lift univariate decomposition
+| back-transformation
+| fulldecompose, iterate
+   | decompuniv for g
+
+*/
+///////////////////////////////////////////////////////////////////////////////
+
+
+proc decompopts(list #)
+"USAGE:  decompopts(); or decompopts(\"reset\");
+RETURN: nothing
+NOTE:
+ at texinfo
+        in the first case, it shows the setting of the control parameters;@*
+        in the second case, it kills the user-defined control parameters and@*
+                            resets to the default setting which will then
+                            be diplayed. @* @*
+        int DECMETH; Method for computing the univariate decomposition@*
+                 0 : (default) Kozen-Landau @*
+                 1 : von zur Gathen @*
+
+        int IMPROVE Choice of coefficients for the decomposition @*
+         @math{(g_1,\ldots,g_l,h)} of a non-monic polynomials f. @*
+         0 : leadcoef(@math{g_1}) = leadcoef(@math{f})
+              and @math{g_2,\ldots,g_l,h} are monic @*
+         1 : (default), content(@math{g_i}) = 1 @*
+
+        int MINS @*
+         @math{f=g\circ h, (g_1,\ldots,g_m,h)} of a non-monic polynomials f.@*
+               0 : g(0) = f(0), h(0) = 0   [ueberlegen fuer complete] @*
+               1 : (default),  g(0)=0, h(0) = f(0) @*
+               2 : Tschirnhaus @*
+
+        int DECORD; The order in which the decomposition will be computed@*
+               0 : minfirst @*
+               1 : (default) maxfirst @*
+
+      int DEGONE; decompose also polynomials built on linear ones @*
+               0 : (default) @*
+               1 :
+ at end texinfo
+EXAMPLE: example decompopts; shows an example
+"
+{
+/*
+  siehe Erlaeuterungen, globale Variablen wie im Header angegeben,
+  suchen mit CTRL-S Top::
+  diese eintragen
+*/
+  if (size(#))
+  {
+    if (string(#[1]) == "reset")
+    {
+      if (defined(DECMETH)) {kill DECMETH;}
+      //   if (defined(DECORD)) {kill DECORD;}
+      if (defined(MINS)) {kill MINS;}
+      if (defined(IMPROVE)) {kill IMPROVE;}
+    }
+  }
+
+ if (voice==2)
+ {
+  "";
+  "  === Global variables for decomp.lib === ";
+  "";
+
+  if (!defined(DECMETH)) {" -- DECMETH (int) not defined, implicitly 1";}
+  else
+  {
+    if (DECMETH!=0 and DECMETH!=1) { DECMETH=1; }
+   " -- DECMETH =", DECMETH;
+  }
+/*
+  if (!defined(DECORD)) {" -- DECORD (int) not defined, implicitly 1";}
+  else
+  {
+    if (DECORD!=0 and DECORD!=1) { DECORD=1; }
+   " -- (int) DECORD =", DECORD;
+  }
+*/
+  if (!defined(MINS)) {" -- MINS (int) not defined, implicitly 0";}
+  else
+  {
+    if (MINS!=0 and MINS!=1) { MINS = 0; }
+   " -- (int) MINS =", MINS;
+  }
+
+  if (!defined(IMPROVE)) {" -- IMPROVE (int) not defined, implicitly 1";}
+  else
+  {
+   if (IMPROVE!=0 and IMPROVE!=1) { IMPROVE=1; }
+   " -- (int) IMPROVE =", IMPROVE;
+  }
+ }
+}
+example;
+{ "EXAMPLE:"; echo =2;
+   decompopts();
+}
+///////////////////////////////////////////////////////////////////////////////
+
+//static
+proc decompmonom(poly f, list #)
+"USAGE: decompmonom(f[,vvar]); f poly, vvar poly
+PURPOSE: compute a maximal decomposition in case that
+         f = g o h, where g is univariate and h is a single monomial
+RETURN: ideal, (g,h); g univariate, h monomial if such a decomposition exist,
+        poly, the input, otherwise
+ASSUME: f is non-constant
+EXAMPLE: example decompmonom; shows an example
+"
+{
+  int i,k;
+  poly g;
+
+  poly vvar = var(1);
+  if (size(#)) { vvar = var(rvar(#[1])); }
+
+  //poly vvar = maxdeg(f);
+  poly zeropart = jet(f,0);
+  poly ff = f - zeropart;
+  int mindeg = -deg(ff,-1:nvars(basering));
+  poly minff = jet(ff,mindeg);
+  if (size(minff)>1) { return(f); }
+  intvec minv = leadexp(minff);
+  minv = minv/gcdv(minv);
+  for (i=1;i<=size(ff);i++)
+  {
+    k = divintvecs(leadexp(ff[i]),minv);
+    if (k==0)  { return(f); }
+    else { g = g + leadcoef(ff[i])*vvar^k; }
+  }
+  g = g + zeropart;
+  dbprint("* Sucessfully multivariate decomposed by a monomial"+newline);
+  return(ideal(g,monomial(minv)));
+}
+example
+{ "EXAMPLE:"; echo =2;
+   ring r = 0,(x,y),dp;
+   poly f = subst((x2+x3)^150,x,x2y3);
+   decompmonom(f);
+
+   ring rxyz = 0,(x,y,z),dp;
+   poly g = 1+x2+x3+x5;
+   poly G = subst(g,x,x7y5z3);
+   ideal I = decompmonom(G^50);
+   I[2];
+}
+///////////////////////////////////////////////////////////////////////////////
+
+static proc divintvecs(intvec v,intvec w)
+"USAGE: divintvecs(v,w); v,w intvec, w!=0
+RETURN: int, k if  v = k*w,
+             0 otherwise
+NOTE: if w==0, then an Error message occurs
+EXAMPLE: example divintevcs; shows an example
+"
+{
+  if (w==0) {
+    ERROR("// Error: proc divintvecs: the second argument has to be non-zero.");
+    return(0);
+  }
+  int i=1;
+  while (w[i]==0) { i++; }
+  int k = v[i] div w[i];
+  if (v == k*w) { return(k); }
+  else { return(0); }
+}
+example
+{ "EXAMPLE:"; echo =2;
+  intvec v = 1,2,3;
+  intvec w = 2,4,6;
+  divintvecs(w,v);
+  divintvecs(intvec(3,2,9),v);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+static proc gcdv(intvec v)
+"USAGE: gcdv(v); intvec v
+RETURN: int, the gcd of the entries in v
+NOTE:   if v=0, then gcdv(v)=1 @*
+        this is different from Singular's builtin gcd, where gcd(0,0)==0
+EXAMPLE: example gcdv; shows an example
+"
+{
+  int ggt;
+  int i,n;
+
+  ggt = v[1];
+  for (i=2;i<=size(v);i++)
+  {
+    ggt = gcd(ggt,v[i]);
+  }
+  if (ggt==0)
+  {
+    ggt = 1;
+  }
+  return(ggt);
+}
+example
+{ "EXAMPLE:"; echo =2;
+  intvec v = 6,15,21;
+  gcdv(v);
+  gcdv(0:3);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+static proc divisors(int n,list #)
+"USAGE:  divisors(n); n int
+         divisors(n,1); n int
+RETURN: intvec, the positive divisors of n  @*
+           in decreasing order (default) @*
+           in increasing order in the second case
+EXAMPLE: example divisors; shows an example
+"
+{
+  int i,j;
+  intvec v = 1;
+
+  list l = primefactors(n);
+  list primesl = l[1];
+  list multl = l[2];
+
+  for (i=1;i<=size(primesl);i++)
+  {
+   for (j=1;j<=multl[i];j++)
+     { v = v,primesl[i]*v;}
+  }
+
+  ring rhelp =0,x,dp;        // sort the intvec
+  poly h;
+  for(i=1;i<=size(v);i++)
+  {
+    h = h+x^v[i];
+  }
+  v=0;
+  for(i=1;i<=size(h);i++)
+  {
+   v[i]=leadexp(h[i])[1];
+  }
+  if (size(#)) {
+    return(intvec(v[size(v)..1]));
+  }
+
+  return(v);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  divisors(30);
+  divisors(-24,1);
+}
+///////////////////////////////////////////////////////////////////////////////
+//
+// Dies wirkt sich nur aus wenn Brueche vorhanden sind?!
+// Laeuft dann so statt cleardenom usw. problemlos ueber Z,Z_m
+// ansehen.
+//
+static proc improvecoef(poly g0,poly h0,number lc)
+"USAGE: improvecoef(g0,h0,lc); g0, h0 poly; lc number
+RETURN: poly, poly, number
+ASSUME: global ordering
+EXAMPLE: example improvecoef; shows an example
+"
+{
+  int Zcoefs = find(charstr(basering),"integer");
+  poly vvar = var(univariate(g0));
+  number lch0 = leadcoef(h0);
+  number denom;
+
+  if (Zcoefs and lch0<0)  // da cleardenom fuer integer buggy ist.
+  {
+    h0 = h0/(-1);
+    denom = -1;
+  }
+  else
+  {
+   h0 = cleardenom(h0);
+   denom = leadcoef(h0)/lch0;
+  }
+  g0 = subst(g0,vvar,1/denom*vvar);
+  g0 = lc*g0;
+  lc = leadcoef(g0);
+  g0= 1/lc*g0;
+  return(g0,h0,lc);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r = 0,x,dp;
+
+   poly g = 3x2+5x;
+   poly h = 4x3+2/3x;
+   number lc = 7;
+
+   improvecoef(g,h,lc);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc compose(list #)
+"USAGE: compose(f1,...,fn); f1,...,fn poly
+        compose(I); I ideal,  @*
+ASSUME: the ideal consists of n=ncols(I) >= 1 entries, @*
+          where I[1],...,I[n-1] are univariate in the same variable @*
+          but I[n] may be multivariate.
+RETURN: poly, the composition  I[1](I[2](...I[n]))
+NOTE:   this procedure is the inverse of decompose
+EXAMPLE: example compose; shows some examples
+SEE: decompose
+"
+{
+  def d = basering;   // Ohne dies kommt es zu Fehler, wenn auf Toplevel
+                      // ring r definiert ist.
+
+  ideal I = ideal(#[1..size(#)]);
+  int n=ncols(I);
+  poly f=I[1];
+  map phisubst;
+  ideal phiid = maxideal(1);
+
+  int varnum = univariate(f);
+
+  if (varnum<0) {
+    " // the first polynomial is a constant";
+    return(f);
+  }
+  if (varnum==0 and n>1) {
+    " // the first polynomial is not univariate";
+    return(f);
+  }
+  // Hier noch einen Test ergaenzen
+
+  poly vvar = var(varnum);
+
+  for(int i=2;i<=n;i++)
+  {
+    phiid[varnum]=I[i];
+    // phisubst=d,phiid;
+    phisubst=basering,phiid;
+    f = phisubst(f);
+  }
+  return(f);
+}
+example
+{ "EXAMPLE:"; echo =2;
+   ring r = 0,(x,y),dp;
+   compose(x3+1,x2,y3+x);
+   // or the input as one ideal
+   compose(ideal(x3+1,x2,x3+y));
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc is_composite(poly f)
+"USAGE: is_composite(f); f poly
+RETURN: int @*
+     1, if f is decomposable @*
+     0, if f is not decomposable @*
+ -1, if char(basering)>0 and deg(f) is  divisible by char(basering) but no
+      decomposition has been found.
+NOTE:  The last case means that it could exist a decomposition f=g o h  with
+char(basering)|deg(g), but this wild case cannot be decided by the algorithm.@*
+       Some additional information will be displayed when called by the user.
+EXAMPLE: example is_composite; shows some examples
+"
+{
+  int d = deg(f,nvars(basering));
+  int cb = char(basering);
+
+  if (d<1)
+  {
+    " The polynomial is constant ";
+    return(0);
+  }
+  if (d==1)
+  {
+    " The polynomial is linear ";
+    return(0);
+  }
+
+  if (nvars(basering)==1 and d==prime(d))
+  {
+    " The degree is prime.";
+    return(0);
+  }
+
+  if (nvars(basering)>1 and univariate(f))  // and not(defined(DEGONE))
+  {
+    return(1);
+  }
+
+  // else try to decompose
+  int nc = ncols(ideal(decompose(f)));
+
+  if (cb > 0)   // check the not covered wild case
+  {
+    if ((d mod cb == 0) and (nc == 1))
+    {
+      if (voice==2)
+      {
+        "// -- Warning: wild case, cannot decide whether the polynomial has a";
+        "// -- decomposition goh with deg(g) divisible by char(basering) = "
+          + string(cb) + ".";
+       }
+      return(-1);
+    }
+  }
+  // in the tame case, decompose gives the correct result
+  return(nc>1);
+}
+example
+{ "EXAMPLE:"; echo =2;
+
+   ring r0 = 0,x,dp;
+   is_composite(x4+5x2+6);    // biquadratic polynomial
+
+   is_composite(2x2+x+1);     // prime degree
+   // -----------------------------------------------------------------------
+   // polynomial ring with several variables
+   ring R = 0,(x,y),dp;
+   // -----------------------------------------------------------------------
+   // single-variable multivariate polynomials
+   is_composite(2x+1);
+   is_composite(2x2+x+1);
+   // -----------------------------------------------------------------------
+   // prime characteristic
+   ring r7 = 7,x,dp;
+   is_composite(compose(ideal(x2+x,x14)));     // is_composite(x14+x7);
+   is_composite(compose(ideal(x14+x,x2)));     // is_composite(x14+x2);
+
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc decompose(poly f,list #)
+"USAGE:  decompose(f); f poly
+        decompose(f,1); f poly
+RETURN: poly, the input, if f is not a composite
+        ideal, if the input is a composite
+NOTE: computes a full decomposition if called by the second variant
+EXAMPLE: example decompose; shows some examples
+SEE: compose
+"
+{
+ if (!defined(IMPROVE)){ int IMPROVE = 1; }
+ if (!defined(MINFIRST)){ int MINFIRST = 0; }
+ int fulldecompose;
+
+ if (size(#)) {        // cf. ERROR-msg in randomintvec
+   if (typeof(#[1])=="int") {
+       fulldecompose = (#[1]==1);
+   }
+ }
+
+ int m,iscomposed;
+ int globalord = 1;
+ ideal I;
+
+// --- preparatory stuff ----------------------------------------------------
+  // The degree is not independent of the term order
+ int n = deg(f,1:nvars(basering));
+ int varnum = univariate(f);  // to avoid transformation if f is univariate
+
+ // if (deg(f)<=1) {return(f);} //steigt automatisch bei der for-schleife aus m = 2
+ if (n==prime(n) and nvars(basering)==1
+     //  or (varnum>0 and nvars(basering))
+  ) {return(f);}
+
+ if (varnum<0)
+ {
+   ERROR("// -- Error proc decompoly: the polynomial is constant.");
+ }
+ //--------------------------------------------------------------------------
+
+ int minfirst = MINFIRST!=0;
+ list mdeg;
+ intvec maxdegv,degcand;
+
+ // -- switch to global order, necessary for division -- // Weiter nach oben
+ if (typeof(attrib(basering,"global"))!="int") {
+   globalord = 0;
+ }
+ else {
+   globalord = attrib(basering,"global");
+ }
+
+ if (!globalord) {
+   def d = basering;
+   list ll = ringlist(basering);
+   ll[3] = list(list("dp",1:nvars(basering)),list("C",0));
+   def rneu = ring(ll);
+   setring rneu;
+   poly f = fetch(d,f);
+   ideal I;
+ }
+ // -----------------------------------------------------------------------
+
+ map phiback;
+ poly f0,g0,h0,vvar;
+ number lc;
+ ideal J;   // wird erst in fulldecompose benoetigt
+
+ // --- Determine the candidates for deg(g) a decreasing sequence of divisors
+ poly lf = jet(f,n)-jet(f,n-1);
+ //"lf = ",lf;
+ if (size(lf)==1)         // the leading homogeneous part is a monomial
+ {
+     degcand = divisors(gcdv(leadexp(lf)));
+ }
+ else
+ {
+   degcand = divisors(n);            // Das ist absteigend
+ }
+
+ if(printlevel>0) {degcand;}
+
+ // --- preparatory steps for the multivariate case -------------------------
+
+ if (varnum>0)            // -- univariate polynomial
+ {
+  vvar = var(varnum);
+  f0 = f;   // save f
+ }
+ else  // i.e. multivariate (varnum==0),the case varnum < 0 is excluded above
+ {
+  // -- find variable with  maximal degree
+  mdeg = maxdegs(f);
+  maxdegv = mdeg[2];
+  varnum = maxdegv[2];
+  vvar = var(varnum);
+  phiback = maxideal(1);
+
+// special case, the polynomial is  a composite of a single monomial //20.6.10
+   if (qhweight(f)!=0) { I = decompmonom(f,vvar); }
+   iscomposed = size(I)>1;
+   if (iscomposed)          // 3.6.11 - dies decompmonom
+   { //I;
+      ideal J = decompunivmonic(I[1],deg(I[1]));
+      I[2]= subst(J[2],vvar,I[2]);
+      I[1] = J[1];
+      //I;
+   }
+
+   if (!iscomposed) // -- transform into a distinguished polynomial
+   {
+     f0,phiback = makedistinguished(f,vvar);
+   }
+ }
+ // ------ Start computation ------------------------------------------------
+ // -- normalize and  save the leading coefficient
+ lc = 1;
+ //f0;
+ //"vvar = ",vvar;
+
+ // --- 11.4.11 hier auch noch gewichteten Grad beruecksichtigen ? --
+
+  if (!iscomposed) { lc = leadcoef(coeffs(f0,vvar)[deg(f0)+1,1]); } // 20.6.10
+
+  // if Z, Z_m, and f is not monic (and  content !=1) // if (f0/lc*lc!=f0)
+  if (find(charstr(basering),"integer") and not(lc==1 or lc==-1)) // 6.4.11
+  {
+    ERROR("// -- Error proc decompose: Can not decompose non-monic polynomial over Z!");
+  }
+
+  if (lc!=1){ f0 = 1/number(lc)*f0;}      // --- normalize the polynomial
+
+  // -- Now the input is prepared to be monic and vvar-distinguished
+  //----------------------------------------------------------------
+  m = 1;
+
+  // --- Special case: a multivariate can be composite of a linear polynom
+  if (univariate(f) and nvars(basering)==1) // 11.8.09 d.h.
+  {    // --- if univariate ----------------------------------------
+    if(minfirst) {degcand = divisors(n,1);} // dies ist aufsteigend
+    m = 2;                                  // skip first entry
+  }
+  // if decomposed as the decomposition with a monomial
+  // then skip the multivariate process // 20.6.10 detected as decompmonomial
+  if (iscomposed) { degcand = 1; }
+
+  if (printlevel>0 and !iscomposed) { "* Degree candidates are", degcand; }
+
+  // -- check succesively for each candidate
+  // whether f is decomposable with deg g = r
+
+  for(;m<size(degcand);m++)   // decreasing
+  { //r = degcand[m];
+    I =  decompmultivmonic(f0,vvar,degcand[m]);
+    if (size(I)>1)
+    {
+     iscomposed = 1;
+     break;
+    }
+  }
+ // -- all candidates have be checked but f is primitive
+ if(!iscomposed) {
+   if (!globalord) { setring d; }   // restore old ring
+   dbprint("** not decomposable: linear / not tame / prime degree --");
+   return(f);
+ }
+
+ // -- the monic vvar-distinguished polynomial f0 is decomposed -------
+ // -- retransformation for the multivariate case ---------------------
+  g0,h0 = I;
+
+  if (!univariate(f)) { h0 = phiback(h0);}
+
+  if (IMPROVE) { g0,h0,lc=improvecoef(g0,h0,lc);}  //  ueber switch
+  I = h0;
+
+ // -- Full decomposition: try to decompose g further ------------------
+  if (fulldecompose) {
+    dbprint(newline+"** Compute a complete decomposition");
+    while (iscomposed) {
+     iscomposed=0;
+     degcand=divisors(deg(g0,1:nvars(basering)));  // absteigend
+     if (printlevel> 0) { "** Degree candidates are now: ", degcand; }
+     for (m=2;m<size(degcand);m++) //OK, ergibt lexicographically ..
+     {
+       J =decompunivmonic(g0,degcand[m]); /*      J =decompuniv(g0);*/
+       g0 = J[1];
+       h0=J[2];
+       iscomposed = deg(h0,1:nvars(basering))>1;
+       if (iscomposed) {
+         if (IMPROVE) { g0,h0,lc=improvecoef(g0,h0,lc); }  //  ueber switch
+         I = h0,I;
+         break;
+       }
+      }
+    }
+  dbprint("** completely decomposed"+newline);
+  }
+  I = lc*g0,I;
+  if (!globalord) {
+   setring d;
+   I = fetch(rneu,I);
+  }
+  return(I);
+}
+example
+{ "EXAMPLE:"; echo =2;
+   ring r2 = 0,(x,y),dp;
+
+   decompose(((x3+2y)^6+x3+2y)^4);
+
+   // complete decomposition
+   decompose(((x3+2y)^6+x3+2y)^4,1);
+   // -----------------------------------------------------------------------
+   // decompose over the integers
+   ring rZ = integer,x,dp;
+   decompose(compose(ideal(x3,x2+2x,x3+2)),1);
+   // -----------------------------------------------------------------------
+   // prime characteristic
+   ring r7 = 7,x,dp;
+   decompose(compose(ideal(x2+x,x7)));   // tame case
+   // -----------------------------------------------------------------------
+   decompose(compose(ideal(x7+x,x2)));   // wild case
+   // -----------------------------------------------------------------------
+   ring ry = (0,y),x,dp;     // y is now a parameter
+   compose(x2+yx+5,x5-2yx3+x);
+   decompose(_);
+
+  // Usage of variable IMPROVE
+  ideal J = x2+10x, 64x7-112x5+56x3-7x, 4x3-3x;
+  decompose(compose(J),1);
+  int IMPROVE=0;
+  exportto(Decomp,IMPROVE);
+  decompose(compose(J),1);
+}
+///////////////////////////////////////////////////////////////////////////////
+/*   ring rt =(0,t),x,dp;
+   poly f = 36*x6+12*x4+15*x3+x2+5/2*x+(-t);
+   decompose(f);
+*/
+
+
+// Dies gibt stets ein ideal zurueck, wenn f composite ist
+// gibt das polynom zurueck, wenn es primitiv ist
+// static
+proc decompmultivmonic(poly f,poly vvar,int r)
+"USAGE:  decompmultivmonic(f,vvar,r); f,vvar poly; r int
+RETURN:  ideal, I = ideal(g,h) if f = g o h with deg(g) = r@*
+           poly f, if  f is not a composite or char(basering) divides r
+ASSUME:  f is monic and distinguished w.r.t. vvar,
+         1<=r<=deg(f) is a divisor of deg(f)
+         and char(basering) does not divide r.
+EXAMPLE: example decompmultivmonic; shows an example
+"
+{
+  def d = basering;
+ int i,isprimitive;
+ int m = nvars(basering);
+ int n = deg(f);
+ int varnum = rvar(vvar);
+ intvec v = 1:m;   // weight-vector for jet
+   v[varnum]=0;
+ int s = n div r;
+ // r = deg g; s = deg h;
+
+ poly f0 = f;
+ poly h,h0,g,gp,fgp,k,t,u;
+ ideal I,rem,phiid;
+ list l;
+ map phisubst;
+
+// -- entscheidet intern, abhaengig von der Anzahl der Ringvariablen,
+// -- ob f0 primitive ist.
+// " r = ",r;
+
+ if (s*r!=n)
+ {
+   ERROR("// -- Error proc decompmultivmonic: r = "+string(r)+
+             " does not divide deg(f) = "+string(n)+".");
+ }
+
+ int cb = char(basering);  // oder dies in decompunivmonic
+ if (cb>0)
+ {
+     if (r mod cb == 0)
+     {
+       if (voice == 2)
+       {
+        "// Warning: wild case in characteristic " + string(cb) +
+         ". We cannot decide";
+         "// whether a decomposition goh with deg(g) = " + string(r)+
+         " exists.";"";
+       }
+       return(f);
+     }
+ }
+//---------------------------------------------------------------------------
+
+ for (i=1;i<=m;i++)
+ {
+  if (i!=varnum) {f0 = subst(f0,var(i),0);}
+ }
+ //" f0 = ",f0;
+ // f0 ist nun das univariate
+
+ // 24.3.09   // 11.8.09  nochmals ansehen
+ if (r==deg(f0)) // the case of a linear multivarcomposite
+ {
+   dbprint("** try to decompose in linear h, deg g = "+string(r));
+  I = f0,vvar;   // Das ist hier wichtig
+ }
+ else   // find decomposition of the univariate f0
+ {
+  I = decompunivmonic(f0,r);
+  // dbprint(" ** monic decomposed");//" I = ";I;
+
+  isprimitive=(deg(I[2])==1);
+  if (isprimitive) {return(f);}
+ }
+
+//---- proceed in the multivariate case
+//---- lift the univariate decomposition
+ if (!univariate(f))
+ {
+   dbprint("* Lift the univariate decomposition");
+   g,h0 = I;
+   k = h0;
+   gp = diff(g,vvar);
+
+   // -- This is substitution ----
+   // t = substitute(gp,vvar,h0);
+   phiid = maxideal(1);
+   phiid[varnum]=h0;
+   phisubst=basering,phiid;
+    t = phisubst(gp);
+   // -- substitution ende
+   fgp = 1;
+   i = 0;
+   while(fgp!=0)
+   {
+     i++;
+     // -- This  is substitution ----
+     //gp = substitute(g,vvar,k);
+     phiid[varnum]=k;
+     phisubst=basering,phiid;
+     gp = phisubst(g);
+     // --  substitution ende
+
+     fgp = f - gp;
+     u = jet(fgp,i,v) - jet(fgp,i-1,v);    // oder mit reduce(maxideal(x))
+     l = division(u,t);                    // die kleineren Terme abschneiden
+     rem = l[2];
+     u = l[1][1,1];    // the factor
+     if (rem!=0)
+     {
+       isprimitive = 1;
+       break;
+     }
+     k = k + u;
+   }
+   h = k;
+   I = g,h;
+   //"decomposed as =";
+   //I;
+ }
+ if (isprimitive) {
+   dbprint(">>> not multivariate decomposed"+newline);
+  return(f);
+ }
+ else {
+   dbprint("* Sucessfully multivariate decomposed"+newline);
+  return(I);
+ }
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r = 0,(x,y),lp;
+   poly f = 3xy4 + 2xy2 + x5y3 + x + y6;
+   decompmultivmonic(f,y,2);
+
+   ring rx = 0,x,lp;
+   decompmultivmonic(x8,x,4);
+}
+///////////////////////////////////////////////////////////////////////////////
+//static
+proc decompunivmonic(poly f,int r)
+"USAGE: decompunivmonic(f,r); f poly, r int
+RETURN:  ideal,  (g,h) such that f = goh and deg(g) = r
+         poly f, if such a decomposition does not exist.
+ASSUME:  f is univariate, r is a divisor of deg(f)      @*
+         and char(basering) does not divide r in case that char(basering) > 0.
+         global order of the basering is assumed.
+EXAMPLE: example decompunivmonic; shows an example
+"
+{
+ int d = deg(f);
+ int s;    // r = deg g; s = deg h;
+ int minf,mins;
+ int iscomposed = 1;
+
+ if (!defined(MINS)) { int MINS = 0; }
+ if (!defined(DECMETH)) { int DECMETH = 1; }
+ int savedecmeth = DECMETH;
+ int Zcoefs =charstr(basering)=="integer";//find(charstr(basering),"integer");
+
+ number cf;
+ poly h,g;
+ ideal I;
+ matrix cc;
+
+ // --- Check input and create the results for the simple cases
+
+ if (deg(f)<1){return(ideal(f,var(1)));}  // wird dies aufgerufen?
+ //-------------------------
+
+ int varnum = univariate(f);
+
+ if (varnum==0)
+ {
+   "// -- The polynomial is not univariate";
+   return(f);
+ }
+
+ poly vvar = var(varnum);
+ I = f,vvar;
+
+ if (leadcoef(f)!=1)
+ {
+     "// -- Error proc decompunivmonic: the polynomial is not monic.";
+     return(f);
+ }
+ /* Dies einklammern, wenn (x+1)^2 zerlegt werden sollte
+  // aus decompose heraus, wird dies gar nicht aufgerufen!
+ if (deg(f)==1 or deg(f)==prime(deg(f)))
+ {
+   "// -- The polynomial is not a composite.";
+  return(I);
+ }
+ */
+ /* ---------------------------------------------------- */
+ s = d div r;
+
+ if (d!=s*r)
+ {
+   ERROR("// -- Error proc decompunivmonic: the second argument does not divide deg f.");
+ }
+ int cb = char(basering);
+ if (cb>0)
+ {
+     if (r mod cb ==0)
+     {
+         "wild case: cannot determine a decomposition";
+         return(I);
+     }
+ }
+// -------------------------------------------------------------------------
+ // The Newton iteration only works over coefficient *fields*
+ // Therefore use in this case the Kozen-Landau method i.e. set DECMETH = 1;
+ if (savedecmeth==0 and Zcoefs) { DECMETH=1; }
+
+// -- Start the computation ----------------------------------------------
+
+  dbprint("* STEP 1: Determine h");
+  dbprint(" d = deg f = " +string(n) + " f = goh"," r = deg g = "+string(r),
+          " s = deg h = " +string(s));
+  int tt = timer;
+
+  if(DECMETH==1) {  // Kozen-Landau
+    dbprint("* Kozen-Landau method");
+
+   // Determine ord(f);
+   //cc  = coef(f,vvar);  // extract coefficents of f
+   //print(cc); read("");
+
+   // dbprint("time: "+string(timer-tt)); tt = timer;
+   // minf = deg(cc[1,ncols(cc)]);   // 11.8.09 Doch OK.
+   minf = -deg(f,-1:nvars(basering));  // this is local ord 15.3.10
+
+   // oder: mins = 1;  if (minf) { .. dies .. }
+   mins = (minf div r) + (minf mod r) > 0;  // i.e. ceil(minf/r)
+
+   if (mins==0 and MINS) { mins=1; } // omit the constant term i.e. h(0) = 0
+
+   dbprint("** min f = "+string(minf) + " | min s = "+string(mins) +
+           " | s-mins = "+ string(s-mins));
+
+   // Dies wird wohl nicht benoetigt.
+   //  int minr=  (minf div s) + ((minf mod s)>0); // ceil
+   dbprint("** extract the coeffs ");
+   cc  = coeffs(f,vvar);
+
+   dbprint("time: "+ string(timer -tt));
+
+   h = vvar^s;
+   for (int j=1;j<=s-mins;j++)
+   {
+/*
+     timer = 1;H = Power(h,r);  "Power H"; timer;
+     timer = 1;G = h^r;  "h^r"; timer;
+*/
+    cf = (number(cc[d-j+1,1])-number(coeffs(h^r,vvar)[d-j+1,1]));
+
+//    d-j+1,"cf =",cf, " r= ",r;
+// dbprint("*** "+ string(d-j+1) + " cf = "+string(cf) + " r= "+string(r));
+
+    if (Zcoefs) { if (bigint(cf) mod r != 0) { iscomposed = 0; break; }}
+    cf = cf/r;
+
+    //else { cf = cf/r; }
+    h = h + cf*vvar^(s-j);
+//    " h = ",h;
+   }
+  } else {
+   dbprint("* von zur Gathen-method");
+   //  "f=",f;
+   h = reversal(newtonrroot(reversal(f,d),r,s+!MINS),s,vvar);  // verdreht OK
+   //   " h = ",h;
+   dbprint("* END STEP 1: time: "+string(timer -tt));
+  }
+  DECMETH=savedecmeth;   // restore the original method
+
+  if (iscomposed == 0) {
+    dbprint("** Failed in STEP 1: not decomposed with deg h = "+string(s)+newline);
+    return(I);
+  }
+
+  // -- Step 2: try to rewrite f as a sum of powers of h ---
+  dbprint("* STEP 2: Determine g");
+  poly H = h^r;
+  int dalt = r;
+  int ds;
+  number c;
+  while (d >= 0)   // i.e. f!=0
+  {
+    //dbprint("d = ",d);
+    ds = d div s;
+    if (ds * s !=d)   // d mod s != 0, i.e. remaining f is a power of h
+    {
+      iscomposed = 0;
+      break;
+    }
+    c = leadcoef(f);
+    g = g + c*vvar^ds;
+    H = division(H,h^(dalt - ds))[1][1,1];   // 10.3.10
+    // H = H / h^(dalt - ds);
+    f = f - c*H;
+    //"f = ",f;
+
+    dalt = ds;
+    d = deg(f);
+  }
+  dbprint("* END STEP 2: time: "+string(timer -tt));
+  if (iscomposed)
+  {
+   dbprint("** Sucessfully univariate decomposed with deg g = "+string(r)+newline);
+    I = g,h;
+  } else {
+   dbprint("** Failed in STEP 2: not decomposed with deg g = "+string(r)+newline);
+  }
+
+ return(I);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring r=0,(x,y),dp;
+  decompunivmonic((x2+x+1)^3,3);
+  decompunivmonic((x2+x)^3,3);
+
+  decompunivmonic((y2+y+1)^3,3);
+}
+///////////////////////////////////////////////////////////////////////////////
+// aus polyaux.lib
+proc reversal(poly f,list #)
+"USAGE: reversal(f); f poly
+         reversal(f,k); f poly, k int
+         reversal(f,k,vvar); f poly, k int, vvar poly (a ring variable)
+RETURN: poly, the reversal x^k*f(1/x) of the input f
+ASSUME: f is univariate and that  k>=deg(f)
+@*      since no negative exponents are possible in Singular
+@*      if k<deg(f) then k = deg(f) is used
+NOTE: reversal(f); is by default reversal(f,deg(f));
+      the third variant is needed if f is a non-zero constant and k>0 @*
+@*    reversal is only idempotent,
+@*    if called twice with the deg(f) as second argument
+EXAMPLE: example reversal; shows an example
+"
+{
+  int k = 0;
+  poly vvar = var(1);
+
+  if (size(#)) {
+    k  = #[1] - deg(f) ;
+    if (k<0) { k=0; }
+    if (size(#)==2){            // check whether second optional argument
+      vvar = var(univariate(#[2]));     // is a ring variable
+    }
+  }
+
+  int varnum = univariate(f);
+
+  if (varnum==0) {
+    ERROR("// -- the input is not univariate.");
+  }
+  if (varnum<0) {  // the polynomial is  constant
+    return(f*vvar^k);
+  }
+
+  def d = basering;
+  list l = ringlist(d);
+  list varl = l[2];
+  varl = insert(varl,"@z",size(varl));
+  l[2] = varl;
+  def rnew = ring(l);
+  setring rnew;
+  poly f = fetch(d,f);
+  f = subst(homog(f, at z),var(varnum),1, at z,var(varnum))*var(varnum)^k;
+
+  setring d;
+  f = fetch(rnew,f);
+  return(f);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r = 0,x,dp;
+   poly f = x3+2x+5;
+   reversal(f);
+   // the same as
+   reversal(f,3);
+   reversal(f,5);
+
+   poly g  = x3+2x;
+   reversal(g);
+
+   // Not idempotent
+   reversal(reversal(g));
+
+   // idempotent
+   reversal(reversal(g,deg(g)),deg(g));
+   // or for short
+   // reversal(reversal(g),deg(g));
+}
+///////////////////////////////////////////////////////////////////////////////
+// aus polyaux.lib
+proc newtonrroot(poly f,int r,int l)
+"USAGE: newtonrroot(f,r,l); f poly; r int; l int
+RETURN:  poly h, the solution of h^r = f modulo vvar^l
+ASSUME: f(0) = 1
+NOTE: this uses p-adic Newton iteration. It is the adaption of Algorithm 9.22@*
+        of von zur Gathen & Gerhard p. 264 for the special case: phi = Y^r - f
+EXAMPLE: example newtonrroot; shows some examples
+"
+{
+ // phi = Y^r - f
+
+ poly g = 1;  // start polynomial
+
+ poly s =  1/number(r); // initial solution
+ int i = 2;
+ //"s initial",s;
+
+ while(i<l) {
+   // "iteration i",i;
+
+  //  g = (g -(g^r-f)*s) mod x^i;
+  g = jet((g -(g^r-f)*s), i-1);
+  //  s = 2*s - (r*g^(r-1)*s^2) mod x^i;
+  s = jet(2*s - (r*g^(r-1)*s^2),i-1);
+  // "s is now ",s;
+
+  i = 2*i;
+ }
+ //"return newtonrroot";
+ //jet((g -(g^r-f)*s),l-1);
+
+ return(jet((g -(g^r-f)*s),l-1));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r = 0,x,dp;
+
+   ring r3 = 3,x,dp;
+   poly f = x+1;
+   // determine square root of f modulo x^4
+   poly g = newtonrroot(f,2,4);
+   g;
+   g^2;
+   ring R = (0,b,c,d),x,ds;
+//   poly f = 1 + bx +cx2+dx3;
+   poly f = 1 + 5bx +5cx2+5dx3;
+   poly g2 = newtonrroot(f,2,4);
+   g2;
+   f-g2^2;
+   poly f5 = 1 +5*(bx+cx2+dx3);
+   poly g5 = newtonrroot(f5,5,4);
+   g5;
+   f5-g5^5;
+   // Multivariate polynomials
+   ring r = 0,(x,y,z),ds;
+   ring r2 =(0,a,b,c,d,e),(x,y),ds;
+//   poly f = 1 +ax+by+cx2+dxy+ey2;
+   poly f3 = 1 +9*(ax+by+cx2+dxy+ey2);
+   poly g3 = newtonrroot(f3,3,4);
+   jet(g3^3-f3,5);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+static proc randomintvec(int n,int a,int b,list #)
+"USAGE: randomintvec(n,a,b); n,a,b int;
+        randomintvec(n,a,b,1); n,a,b int;
+RETURN: intvec, say v, of length n
+        with entries a<=v[i]<=b, in the first case, resp.
+        with entries a<=v[i]<=b, where v[i]!=0, in the second case
+NOTE:   a<=b should be satisfied, otherwise always v[i]=b (due to random).
+EXAMPLE: example randomintvec; shows some examples
+"
+{
+  int i,randint,nozeroes;
+  intvec v;
+
+  if (size(#)) {
+   if (typeof(#[1])!="int") {
+     ERROR("4th argument can only be an integer, assumed 1.");
+   }
+    nozeroes = #[1]==1;
+  }
+
+  for (i=1;i<=n;i++)
+  {
+    randint = random(a,b);
+    while (nozeroes and randint==0) { randint = random(a,b); }
+    v[i] = randint;
+  }
+  return(v);
+}
+example
+{ "EXAMPLE:"; echo = 1;
+  int randval = system("--random");  // store initial value
+  system("--random",0815);
+  echo = 2;
+  randomintvec(7,-1,1);   // 7 entries in {-1,0,1}
+  randomintvec(7,-1,1,1); // 7 entries either -1 or 1
+  randomintvec(3,-10,10);
+  echo = 1;
+  system("--random",randval);      // reset random generator
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc makedistinguished(poly f,poly vvar)
+"USAGE:  makedistinguished(f,vvar); f, vvar poly; where vvar is a ring variable
+RETURN:  (poly, ideal): the transformed polynomial and an ideal defining
+                       the map which reverses the transformation.
+PURPOSE: let vvar = var(1). Then  f is transformed by a random linear
+         coordinate change
+         phi = (var(1), var(2)+c_2*vvar,...,var(n)+c_n*vvar)  @*
+         such that phi(f) = f o phi becomes distinguished with respect
+         to vvar. That is, the new polynomial contains the monomial vvar^d,
+         where d is the degree of f. @*
+         If already f is distinguished w.r.t. vvar, then f is left unchanged
+         and the re-transformation is the identity.
+NOTE 1:  (this proc correctly works independent of the term ordering.)
+         to apply the reverse transformation, either define a map
+         or use substitute (to be loaded from poly.lib).
+NOTE 2:  If p=char(basering) > 0, then there exist polynomials of degree d>=p,
+         e.g. @math{(p-1)x^p y + xy^p}, that cannot be transformed to a
+         vvar-distinguished polynomial. @*
+         In this case, *p random trials will be made and the proc
+         may leave with an ERROR message.
+EXAMPLE: example makedistinguished; shows some examples
+"
+{
+  def d = basering;   // eigentlich ueberfluessig // wg Bug mit example part
+  map phi;            // erforderlich
+  ideal Db= maxideal(1);
+  int n,b = nvars(basering),1;
+  intvec v= 0:n;
+  intvec w =v;
+  int varnum = rvar(vvar);
+  w[varnum]=1;   // weight vector for deg
+
+  poly g = f;
+  int degg = deg(g);
+
+  int count = 1; // limit the number of trials in char(p) > 0
+  //int count =2*char(basering);
+
+  while(deg(g,w)!=degg and (count-2*char(basering)))  // do a transformation
+  {
+    v = randomintvec(n,-b,b,1);  // n non-zero entries
+    v[varnum] = 0;
+    phi = d,ideal(matrix(maxideal(1),n,1) + var(varnum)*v);  // transformation;
+    g = phi(f);
+    b++;    // increase the range for the random values
+    // count--;
+    count++;
+  }
+  if (deg(g,w)!=degg) {
+   ERROR("it could not be transform to a "+string(vvar)+"-distinguished polynomial.");
+  }
+  Db = ideal(matrix(maxideal(1),n,1) - var(varnum)*v); // back transformation
+  return(g,Db);
+}
+example
+{ "EXAMPLE:";
+  int randval = system("--random");  // store initial value
+  system("--random",0815);
+  echo = 2;
+
+   ring r = 0,(x,y),dp;
+   poly g;
+   map phi;
+   // -----------------------------------------------------------------------
+   // Example 1:
+   poly f = 3xy4 + 2xy2 + x5y3 + x + y6;    // degree 8
+   // make the polynomial y-distinguished
+   g, phi = makedistinguished(f,y);
+   g;
+   phi;
+
+   // to reverse the transformation apply the map
+   f == phi(g);
+
+   //  -----------------------------------------------------------------------
+   // Example 2:
+   // The following polynomial is already x-distinguished
+   f = x6+y4+xy;
+   g,phi = makedistinguished(f,x);
+   g;                         // f is left unchanged
+   phi;                       // the transformation is the identity.
+   echo = 1;
+
+   system("--random",randval);      // reset random generator
+   // -----------------------------------------------------------------------
+   echo = 2;
+   // Example 3:    // polynomials which cannot be transformed
+   // If p=char(basering)>0, then (p-1)*x^p*y + x*y^p factorizes completely
+   // in linear factors, since (p-1)*x^p+x equiv 0 on F_p. Hence,
+   // such polynomials cannot be transformed to a distinguished polynomial.
+
+   ring r3 = 3,(x,y),dp;
+   makedistinguished(2x3y+xy3,y);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+static proc maxdegs(poly f)
+"USAGE: maxdegs(f); f poly
+RETURN:  list of two intvecs
+         _[1] intvec: degree for variable i, 1<=i<=nvars(basering) @*
+         _[2] intvec: max of _[1], index of first variable with this max degree
+EXAMPLE: example maxdegs; shows an example
+"
+{
+  int i,n;
+  intvec degs,maxdeg;
+  list l;
+
+  n = nvars(basering);
+
+  for (i=1;i<=n;i++)
+  {
+   degs[i] = nrows(coeffs(f,var(i)))-1;
+   if (degs[i] > maxdeg)
+   {
+    maxdeg[1] = degs[i];
+    maxdeg[2] = i;
+   }
+  }
+  return(list(degs,maxdeg));
+}
+example
+{ "EXAMPLE:"; echo =2;
+   ring r = 0,(x,y,z),lp;
+   poly f = 3xy4 + 2xy2 + x5y3 + xz6 + y6;
+   maxdegs(f);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc chebyshev(int n,list #)
+"USAGE:   chebyshev(n); n int, n >= 0
+         chebyshev(n,c); n int, n >= 0, c number, c!=0
+RETURN:  poly, the [monic] nth Chebyshev polynomial of the first kind. @*
+         The polynomials are defined in the first variable, say x, of the
+         basering.
+NOTE:   @texinfo
+ The (generalized) Chebyshev polynomials of the first kind  can be
+         defined by the recursion:
+ at tex
+$C_0 = c,\ C_1 = x,\ C_n = 2/c\cdot x\cdot C_{n-1}-C_{n-2},\ n \geq 2,c\neq 0$.
+ at end tex
+ at end texinfo
+        These polynomials commute by composition:
+        @math{C_m \circ C_n = C_n\circ C_m}. @*
+        For c=1, we obtain the standard (non monic) Chebyshev polynomials
+        @math{T_n} which satisfy @math{T_n(x)  = \cos(n \cdot \arccos(x))}. @*
+        For c=2 (default), we obtain the monic Chebyshev polynomials @math{P_n}
+        which satisfy the relation @math{P_n(x+ 1/x) = x^n+ 1/x^n}. @*
+        By default the monic Chebyshev polynomials are returned:
+        @math{P_n =}@code{chebyshev(n)} and @math{T_n=}@code{chebyshev(n,1)}.@*
+        It holds @math{P_n(x) = 2\cdot T_n(x/2)} and more generally
+        @math{C_n(c\cdot x) = c\cdot T_n(x)} @*
+        That is @code{subst(chebyshev(n,c),var(1),c*var(1))= c*chebyshev(n,1)}.
+
+        If @code{char(basering) = 2}, then
+        @math{C_0 = 1, C_1 = x, C_2 = 1, C_3 = x}, and so on.
+EXAMPLE: example chebyshev; shows some examples
+"
+{
+ number startv = 2;
+
+ if (size(#)){ startv = #[1]; }
+ if (startv == 0) { startv = 1; }
+
+ poly f0,f1 = startv,var(1);
+ poly fneu,falt = f1,f0;
+ poly fh;
+
+ if (n<=0) {return(f0);}
+ if (n==1) {return(f1);}
+
+ for(int i=2;i<=n;i++)
+ {
+   fh = 2/startv*var(1)*fneu - falt;
+  // fh = 2*var(1)*fneu - falt;
+  falt = fneu;
+  fneu = fh;
+ }
+ return(fh);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r = 0,x,lp;
+
+   // The monic Chebyshev polynomials
+   chebyshev(0);
+   chebyshev(1);
+   chebyshev(2);
+   chebyshev(3);
+
+   // These polynomials commute
+   compose(chebyshev(2),chebyshev(6)) ==
+   compose(chebyshev(6),chebyshev(2));
+
+   // The standard Chebyshev polynomials
+   chebyshev(0,1);
+   chebyshev(1,1);
+   chebyshev(2,1);
+   chebyshev(3,1);
+   // -----------------------------------------------------------------------
+   // The relation for the various Chebyshev polynomials
+   5*chebyshev(3,1)==subst(chebyshev(3,5),x,5x);
+   // -----------------------------------------------------------------------
+   // char 2 case
+   ring r2 = 2,x,dp;
+   chebyshev(2);
+   chebyshev(3);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+/*
+
+// Examples for decomp.lib
+
+ring r02 = 0,(x,y),dp;
+
+decompose(compose(x6,chebyshev(4),x2+y3+x5y7),1);
+
+int  MINS = 0;
+decompose((xy+1)^7);
+//_[1]=x7
+//_[2]=xy+1
+
+decompose((x2y3+1)^7);
+//_[1]=y7
+//_[2]=x2y3+1
+
+MINS = 1;
+ring r01 = 0,x,dp;
+decompose((x+1)^7);
+//x7+7x6+21x5+35x4+35x3+21x2+7x+1
+
+decompunivmonic((x+1)^7,7);
+//_[1]=x7
+//_[2]=x+1
+
+int MINS =1;
+ decompunivmonic((x+1)^7,7);
+//_[1]=x7+7x6+21x5+35x4+35x3+21x2+7x+1
+//_[2]=x
+
+ // --  Example -------------
+
+//  Comparision Kozen-Landau vs. von zur Gathen
+
+ ring r02 = 0,(x,y),dp;
+
+  // printlevel = 5;
+
+ decompopts("reset");
+
+ poly F = compose(x6,chebyshev(4)+3,8x2+y3+7x5y7+2);
+ deg(F);
+
+ timer = 1;decompose(F,1);timer;
+
+ int MINS = 1;
+ timer = 1;decompose(F,1);timer;
+ int IMPROVE  =0;
+ timer = 1;decompose(F,1);timer;
+
+ decompopts("reset");
+ int DECMETH = 0;  // von zur Gathen
+
+ timer = 1;decompose(F,1);timer;
+
+decompopts("reset");
+
+ // -- Example -------------
+
+ring rZ10 = (integer,10),x,dp;
+chebyshev(2);
+//x2+8
+chebyshev(3);
+//x3+7x
+
+compose(chebyshev(2),chebyshev(3));
+//x6+4x4+9x2+8
+decompose(_);
+int MINS =1;
+decompose(compose(chebyshev(2),chebyshev(3)));
+compose(_);
+
+decompopts("reset");
+
+// --  Example -------------
+
+ring rT =(0,y),x,dp;
+compose(x2,x3+y,(y+1)*x2);
+//(y6+6y5+15y4+20y3+15y2+6y+1)*x12+(2y4+6y3+6y2+2y)*x6+(y2)
+
+ decompose(_,1);
+//_[1]=(y6+6y5+15y4+20y3+15y2+6y+1)*x2
+//_[2]=x3+(y)/(y3+3y2+3y+1)
+//_[3]=x2
+
+int MINS =1;
+compose(x2,x3+y,(y+1)*x2);
+//(y6+6y5+15y4+20y3+15y2+6y+1)*x12+(2y4+6y3+6y2+2y)*x6+(y2)
+
+decompose(_,1);
+//_[1]=(y6+6y5+15y4+20y3+15y2+6y+1)*x2+(2y4+6y3+6y2+2y)*x+(y2)
+//_[2]=x3
+//_[3]=x2
+
+//ring rt =(0,t),x,dp;
+//compose(x2+tx+5,x5-2tx3+x);
+//x10+(-4t)*x8+(4t2+2)*x6+(t)*x5+(-4t)*x4+(-2t2)*x3+x2+(t)*x+5
+
+decompose(_);
+//_[1]=x2+(-1/4t2+5)
+//_[2]=x5+(-2t)*x3+x+(1/2t)
+
+int IMPROVE = 1;
+compose(x2+tx+5,x5-2tx3+x);
+//x10+(-4t)*x8+(4t2+2)*x6+(t)*x5+(-4t)*x4+(-2t2)*x3+x2+(t)*x+5
+
+decompose(_);
+//_[1]=x2+(-1/4t2+5)
+//_[2]=x5+(-2t)*x3+x+(1/2t)
+
+int IMPROVE = 0;
+compose(x2+tx+5,x5-2tx3+x);
+//x10+(-4t)*x8+(4t2+2)*x6+(t)*x5+(-4t)*x4+(-2t2)*x3+x2+(t)*x+5
+decompose(_);
+//_[1]=x2+(-1/4t2+5)
+//_[2]=x5+(-2t)*x3+x+(1/2t)
+
+int MINS = 1;
+compose(x2+tx+5,x5-2tx3+x);
+//x10+(-4t)*x8+(4t2+2)*x6+(t)*x5+(-4t)*x4+(-2t2)*x3+x2+(t)*x+5
+
+decompose(_);
+//_[1]=x2+(t)*x+5
+//_[2]=x5+(-2t)*x3+x
+
+*/
+///////////////////////////////////////////////////////////////////////////////
+// --- End of decomp.lib --------------------------------------------------- //
+///////////////////////////////////////////////////////////////////////////////
diff --git a/Singular/LIB/deform.lib b/Singular/LIB/deform.lib
new file mode 100644
index 0000000..4c548ed
--- /dev/null
+++ b/Singular/LIB/deform.lib
@@ -0,0 +1,968 @@
+//////////////////////////////////////////////////////////////////////////////
+version="version deform.lib 4.0.0.0 Jun_2013 "; // $Id: ee339cdeaa126e4730b57eed609001d8214797a8 $
+category="Singularities";
+info="
+LIBRARY:  deform.lib    Miniversal Deformation of Singularities and Modules
+AUTHOR:   Bernd Martin, email: martin at math.tu-cottbus.de
+
+PROCEDURES:
+ versal(Fo[,d,any])        miniversal deformation of isolated singularity Fo
+ mod_versal(Mo,I,[,d,any]) miniversal deformation of module Mo modulo ideal I
+ lift_kbase(N,M);          lifting N into standard kbase of M
+ lift_rel_kb(N,M[,kbM,p])  relative lifting N into a kbase of M
+";
+
+LIB "inout.lib";
+LIB "general.lib";
+LIB "matrix.lib";
+LIB "homolog.lib";
+LIB "sing.lib";
+///////////////////////////////////////////////////////////////////////////////
+
+proc versal (ideal Fo,list #)
+"USAGE:   versal(Fo[,d,any]); Fo=ideal, d=int, any=list
+COMPUTE: miniversal deformation of Fo up to degree d (default d=100),
+RETURN: list L of 4 rings:
+         L[1] extending the basering Po by new variables given by
+          \"A,B,..\" (deformation parameters); the new variables precede
+         the old ones, the ordering is the product of \"ls\" and \"ord(Po)\" @*
+         L[2] = L[1]/Fo extending Qo=Po/Fo, @*
+         L[3] = the embedding ring of the versal base space, @*
+         L[4] = L[1]/Js extending L[3]/Js. @*
+      In the ring L[1] the following matrices are stored:
+         @*Js  = giving the versal base space (obstructions),
+         @*Fs  = giving the versal family of Fo,
+         @*Rs  = giving the lifting of Ro=syz(Fo).
+
+      If d is defined (!=0), it computes up to degree d.
+      @*If 'any' is defined and any[1] is no string, interactive version.
+      @*Otherwise 'any' is interpreted as a list of predefined strings:
+      \"my\",\"param\",\"order\",\"out\": @*
+      (\"my\" internal prefix, \"param\" is a letter (e.g. \"A\") for the
+      name of the first parameter or (e.g. \"A(\") for index parameter
+      variables, \"order\" ordering string for ring extension), \"out\" name
+      of output file).
+NOTE:   printlevel < 0        no additional output,
+        printlevel >=0,1,2,.. informs you, what is going on;
+        this proc uses 'execute'.
+EXAMPLE:example versal; shows an example
+"
+{
+//------- prepare -------------------------------------------------------------
+  string str, at param, at order, at my, at out, at degrees;
+  int @d,d_max, at t1,t1', at t2, at colR,ok_ann, at smooth, at noObstr, at size, at j;
+  int p    = printlevel-voice+3;
+  int time = timer;
+  intvec @iv, at jv, at is_qh, at degr;
+  d_max    = 100;
+  @my = ""; @param="A"; @order="ds"; @out="no";
+  @size    = size(#);
+  if( @size>0 ) { if (#[1]>0) { d_max = #[1];} }
+  if( @size>1 )
+  { if(typeof(#[2])!="string")
+    { string @active;
+      @my, at param, at order, at out = interact1();
+    }
+    else
+    { @my = #[2];
+      if (@size>2) {@param = #[3];}
+      if (@size>3) {@order = #[4];}
+      if (@size>4) {@out   = #[5];}
+    }
+  }
+  string myPx = @my+"Px";
+  string myQx = @my+"Qx";
+  string myOx = @my+"Ox";
+  string mySo = @my+"So";
+         Fo   = simplify(Fo,10);
+  @is_qh      = qhweight(Fo);
+  int    @rowR= size(Fo);
+  def    Po   = basering;
+setring  Po;
+  poly   X_s  = product(maxideal(1));
+//-------  reproduce T_12 -----------------------------------------------------
+  list   Ls   = T_12(Fo,1);
+  matrix Ro   = Ls[6];                         // syz(i)
+  matrix InfD = Ls[5];                         // matrix of inf. deformations
+  matrix PreO = Ls[7];                         // representation of (Syz/Kos)*
+  module PreO'= std(PreO);
+  module PreT = Ls[2];                         // representation of modT_2 (sb)
+  if(dim(PreT)==0)
+  {
+    matrix kbT_2 = kbase(PreT);                 // kbase of T_2
+  }
+  else
+  {
+    matrix kbT_2 ;                              // kbase of T_2 : empty
+  }
+  @t1 = Ls[3];                                 // vdim of T_1
+  @t2 = Ls[4];                                 // vdim of T_2
+  kill Ls;
+  t1' = @t1;
+  if( @t1==0) { dbprint(p,"// rigid!"); return(list());}
+  if( @t2==0) { @smooth=1; dbprint(p,"// smooth base space");}
+  dbprint(p,"// ready: T_1 and T_2");
+  @colR = ncols(Ro);
+//-----  test: quasi-homogeneous, choice of inf. def.--------------------------
+  @degrees = homog_test(@is_qh,matrix(Fo),InfD);
+  @jv = 1.. at t1;
+  if (@degrees!="")
+  { dbprint(p-1,"// T_1 is quasi-homogeneous represented with weight-vector",
+    @degrees);
+  }
+  if (defined(@active))
+  { "// matrix of infinitesimal deformations:";print(InfD);
+    "// weights of infinitesimal deformations (  empty ='not qhomog'):";
+     @degrees;
+     matrix dummy;
+     InfD,dummy,t1' = interact2(InfD, at jv);kill dummy;
+  }
+ //---- create new rings and objects ------------------------------------------
+  list list_of_rings=get_rings(Fo,t1',1, at order, at param);
+  def `myPx`= list_of_rings[1];
+  def `myQx`= list_of_rings[2];
+  def `myOx`= list_of_rings[3];
+  def `mySo`= list_of_rings[4];
+  kill list_of_rings;
+  setring `myPx`;
+  @jv=0; @jv[t1']=0; @jv=@jv+1; @jv[nvars(basering)]=0;
+                                               //weight-vector for calculating
+                                               //rel-jet with resp to def-para
+  ideal  Io   = imap(Po,Fo);
+  ideal  J,m_J,tid;     attrib(J,"isSB",1);
+  matrix Fo   = matrix(Io);                   //initial equations
+  matrix homF = kohom(Fo, at colR);
+  matrix Ro   = imap(Po,Ro);
+  matrix homR = transpose(Ro);
+  matrix homFR= concat(homR,homF);
+  module hom' = std(homFR);
+  matrix Js[1][@t2];
+  matrix F_R,Fs,Rs,Fn,Rn;
+  export Js,Fs,Rs;
+  matrix Mon[t1'][1]=maxideal(1);
+  Fn  = transpose(imap(Po,InfD)*Mon);         //infinitesimal deformations
+  Fs  = Fo + Fn;
+  dbprint(p-1,"// infinitesimal deformation: Fs: ",Fs);
+  Rn  = (-1)*lift(Fo,Fs*Ro);                  //infinit. relations
+  Rs  = Ro + Rn;
+  F_R = Fs*Rs;
+  tid = 0 + ideal(F_R);
+  if (tid[1]==0) {d_max=1;}                   //finished ?
+ setring `myOx`;
+  matrix Fs,Rs,Cup,Cup',F_R,homFR,New,Rn,Fn;
+  module hom';
+  ideal  null,tid;  attrib(null,"isSB",1);
+ setring `myQx`;
+  poly X_s = imap(Po,X_s);
+  matrix Cup,Cup',MASS;
+  ideal  tid,null;               attrib(null,"isSB",1);
+  ideal  J,m_J;                  attrib(J,"isSB",1);
+                                 attrib(m_J,"isSB",1);
+  matrix PreO = imap(Po,PreO);
+  module PreO'= imap(Po,PreO');  attrib(PreO',"isSB",1);
+  module PreT = imap(Po,PreT);   attrib(PreT,"isSB",1);
+  matrix kbT_2 = imap(Po,kbT_2);
+  matrix Mon  = fetch(`myPx`,Mon);
+  matrix F_R  = fetch(`myPx`,F_R);
+  matrix Js[1][@t2];
+//------- start the loop ------------------------------------------------------
+   for (@d=2;@d<=d_max;@d=@d+1)
+   {
+     if( @t1==0) {break};
+     dbprint(p,"// start computation in degree "+string(@d)+".");
+     dbprint(p-3,">>> TIME = "+string(timer-time));
+     dbprint(p-3,"==> memory = "+string(kmemory())+"k");
+//------- compute obstruction-vector  -----------------------------------------
+     if (@smooth) { @noObstr=1;}
+     else
+     { Cup = jet(F_R, at d, at jv);
+       Cup = matrix(reduce(ideal(Cup),m_J), at colR,1);
+       Cup = jet(Cup, at d, at jv);
+     }
+//------- express obstructions in kbase of T_2  -------------------------------
+     if ( @noObstr==0 )
+     {  Cup' = reduce(Cup,PreO');
+        tid  = simplify(ideal(Cup'),10);
+        if(tid[1]!=0)
+        {  dbprint(p-4,"// *");
+           Cup=Cup-Cup';
+        }
+        Cup   = lift(PreO,Cup);
+        MASS  = lift_rel_kb(Cup,PreT,kbT_2,X_s);
+        dbprint(p-3,"// next MASSEY-products:",MASS-jet(MASS, at d-1, at jv));
+        if    (MASS==transpose(Js))
+              { @noObstr=1;dbprint(p-1,"// no obstruction"); }
+         else { @noObstr=0; }
+      }
+//------- obtain equations of base space --------------------------------------
+      if ( @noObstr==0 )
+      { Js = transpose(MASS);
+        dbprint(p-2,"// next equation of base space:",
+        simplify(ideal(Js),10));
+ setring `myPx`;
+        Js   = imap(`myQx`,Js);
+      degBound = @d+1;
+        J    = std(ideal(Js));
+        m_J  = std(J*ideal(Mon));
+      degBound = 0;
+//--------------- obtain new base-ring ----------------------------------------
+        if(defined(`myOx`)) {kill `myOx`;}
+  qring `myOx` = J;
+        matrix Fs,Rs,F_R,Cup,Cup',homFR,New,Rn,Fn;
+        module hom';
+        ideal  null,tid;  attrib(null,"isSB",1);
+      }
+//---------------- lift equations F and relations R ---------------------------
+ setring `myOx`;
+      Fs    = fetch(`myPx`,Fs);
+      Rs    = fetch(`myPx`,Rs);
+      F_R   = Fs*Rs;
+      F_R   = matrix(reduce(ideal(F_R),null));
+      tid   = 0 + ideal(F_R);
+      if (tid[1]==0) { dbprint(p-1,"// finished"); break;}
+      Cup   = (-1)*transpose(jet(F_R, at d, at jv));
+      homFR = fetch(`myPx`,homFR);
+      hom'  = fetch(`myPx`,hom');  attrib(hom',"isSB",1);
+      Cup'  = simplify(reduce(Cup,hom'),10);
+      tid   = simplify(ideal(Cup'),10);
+      if (tid[1]!=0)
+      {  dbprint(p-4,"// #");
+         Cup=Cup-Cup';
+      }
+      New   = lift(homFR,Cup);
+      Rn    = matrix(ideal(New[1+ at rowR..nrows(New),1]), at rowR, at colR);
+      Fn    = matrix(ideal(New[1.. at rowR,1]),1, at rowR);
+      Fs    = Fs+Fn;
+      Rs    = Rs+Rn;
+      F_R   = Fs*Rs;
+      tid   = 0+reduce(ideal(F_R),null);
+//---------------- fetch results into other rings -----------------------------
+  setring `myPx`;
+      Fs    = fetch(`myOx`,Fs);
+      Rs    = fetch(`myOx`,Rs);
+      F_R   = Fs*Rs;
+  setring `myQx`;
+      F_R = fetch(`myPx`,F_R);
+      m_J = fetch(`myPx`,m_J);  attrib(m_J,"isSB",1);
+      J   = fetch(`myPx`,J);    attrib(J,"isSB",1);
+      Js  = fetch(`myPx`,Js);
+      tid = fetch(`myOx`,tid);
+      if (tid[1]==0) { dbprint(p-1,"// finished");break;}
+   }
+//---------  end loop and final output ----------------------------------------
+  setring `myPx`;
+   if (@out!="no")
+   {  string out = @out+"_"+string(@d);
+      "// writing file "+out+" with matrix Js, matrix Fs, matrix Rs ready
+      for reading in rings "+myPx+" or "+myQx;
+      write(out,"matrix Js[1][", at t2,"]=",Js,";matrix Fs[1][", at rowR,"]=",Fs,
+      ";matrix Rs[", at rowR,"][", at colR,"]=",Rs,";");
+   }
+   dbprint(p-3,">>> TIME = "+string(timer-time));
+   if (@is_qh != 0)
+   { @degr = qhweight(ideal(Js));
+     @degr = @degr[1..t1'];
+     dbprint(p-1,"// quasi-homogeneous weights of miniversal base", at degr);
+   }
+   dbprint(p-1,
+   "// ___ Equations of miniversal base space ___",Js,
+   "// ___ Equations of miniversal total space ___",Fs);
+   dbprint(p,"","
+// 'versal' returned a list, say L, of four rings. In L[1] are stored:
+//   as matrix Fs: Equations of total space of the miniversal deformation,
+//   as matrix Js: Equations of miniversal base space,
+//   as matrix Rs: syzygies of Fs mod Js.
+// To access these data, type
+     def Px=L[1]; setring Px; print(Fs); print(Js); print(Rs);
+
+// L[2] = L[1]/Fo extending Qo=Po/Fo,
+// L[3] = the embedding ring of the versal base space,
+// L[4] = L[1]/Js extending L[3]/Js.
+");
+   return(list(`myPx`,`myQx`,`mySo`,`myOx`));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   int p          = printlevel;
+   printlevel     = 0;
+   ring r1        = 0,(x,y,z,u,v),ds;
+   matrix m[2][4] = x,y,z,u,y,z,u,v;
+   ideal Fo       = minor(m,2);
+                    // cone over rational normal curve of degree 4
+   list L=versal(Fo);
+   L;
+   def Px=L[1];
+   setring Px;
+   // ___ Equations of miniversal base space ___:
+   Js;"";
+   // ___ Equations of miniversal total space ___:
+   Fs;"";
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc mod_versal(matrix Mo, ideal I, list #)
+"USAGE:   mod_versal(Mo,Io[,d,any]); Io=ideal, Mo=module, d=int, any =list
+COMPUTE: miniversal deformation of coker(Mo) over Qo=Po/Io, Po=basering;
+RETURN:  list L of 4 rings:
+         L[1] extending the basering Po by new variables given by
+          \"A,B,..\" (deformation parameters); the new variables precede
+         the old ones, the ordering is the product of \"ls\" and \"ord(Po)\" @*
+         L[2] = L[1]/Io extending Qo, @*
+         L[3] = the embedding ring of the versal base space, @*
+         L[4] = L[1]/(Io+Js) ring of the versal deformation of coker(Ms). @*
+      In the ring L[1] the following matrices are stored:
+         @*Js  = giving the versal base space (obstructions),
+         @*Fs  = giving the versal family of Mo,
+         @*Rs  = giving the lifting of syzygies Lo=syz(Mo).
+      If d is defined (!=0), it computes up to degree d.
+      @*If 'any' is defined and any[1] is no string, interactive version.
+      @*Otherwise 'any' is interpreted as a list of predefined strings:
+      \"my\",\"param\",\"order\",\"out\": @*
+      (\"my\" internal prefix, \"param\" is a letter (e.g. \"A\") for the
+      name of the first parameter or (e.g. \"A(\") for index parameter
+      variables, \"order\" ordering string for ring extension), \"out\" name
+      of output file).
+NOTE:   printlevel < 0        no additional output,
+        printlevel >=0,1,2,.. informs you, what is going on,
+        this proc uses 'execute'.
+EXAMPLE:example mod_versal; shows an example
+"
+{
+//------- prepare -------------------------------------------------------------
+  intvec save_opt=option(get);
+  option(cancelunit);
+  string str, at param, at order, at my, at out, at degrees;
+  int @d,d_max,f0,f1,f2,e1,e1',e2,ok_ann, at smooth, at noObstr, at size, at j;
+  int p    = printlevel-voice+3;
+  int time = timer;
+  intvec @iv, at jv, at is_qh, at degr;
+  d_max    = 100;
+  @my = ""; @param="A"; @order="ds"; @out="no";
+  @size = size(#);
+  if( @size>0 ) { d_max = #[1]; }
+  if( @size>1 )
+  { if(typeof(#[2])!="string")
+    { string @active;
+      @my, at param, at order, at out = interact1();
+    }
+    else
+    { @my = #[2];
+      if (@size>2) {@param = #[3];}
+      if (@size>3) {@order = #[4];}
+      if (@size>4) {@out   = #[5];}
+    }
+  }
+  string myPx = @my+"Px";
+  string myQx = @my+"Qx";
+  string myOx = @my+"Ox";
+  string mySo = @my+"So";
+  @is_qh      = qhweight(I);
+  def    Po   = basering;
+ setring Po;
+  poly   X_s = product(maxideal(1));
+//-------- compute Ext's ------------------------------------------------------
+         I   = std(I);
+ qring   Qo  = I;
+  matrix Mo  = fetch(Po,Mo);
+  list   Lo  = compute_ext(Mo,p);
+         f0,f1,f2,e1,e2,ok_ann=Lo[1];
+  matrix Ls,kb1,lift1 = Lo[2],Lo[3],Lo[4];
+  matrix kb2,C',D' = Lo[5][2],Lo[5][3],Lo[5][5];
+  module ex2,Co,Do = Lo[5][1],Lo[5][4],Lo[5][6];
+  kill Lo;
+  dbprint(p,"// ready: Ext1 and Ext2");
+//-----  test: quasi-homogeneous, choice of inf. def.--------------------------
+  @degrees = homog_test(@is_qh,Mo,kb1);
+  e1' = e1;  @jv = 1..e1;
+  if (@degrees != "")
+  { dbprint(p-1,"// Ext1 is quasi-homogeneous represented: "+ at degrees);
+  }
+  if (defined(@active))
+  { "// kbase of Ext1:";
+    print(kb1);
+    "// weights of kbase of Ext1 ( empty = 'not qhomog')";@degrees;
+    kb1,lift1,e1' = interact2(kb1, at jv,lift1);
+  }
+//-------- get new rings and objects ------------------------------------------
+ setring Po;
+  list list_of_rings=get_rings(I,e1',0, at order, at param);
+  def `myPx`= list_of_rings[1];
+  def `myQx`= list_of_rings[2];
+  def `myOx`= list_of_rings[3];
+  def `mySo`= list_of_rings[4];
+  kill list_of_rings;
+ setring `myPx`;
+  ideal  J,m_J;
+  ideal  I_J  = imap(Po,I);
+  ideal  Io   = I_J;
+  matrix Mon[e1'][1] = maxideal(1);
+  matrix Ms   = imap(Qo,Mo);
+  matrix Ls   = imap(Qo,Ls);
+  matrix Js[1][e2];
+ setring `myQx`;
+  ideal  J,I_J,tet,null;              attrib(null,"isSB",1);
+  ideal  m_J  = fetch(`myPx`,m_J);   attrib(m_J,"isSB",1);
+  @jv=0;  @jv[e1] = 0; @jv = @jv+1;   @jv[nvars(`myPx`)] = 0;
+  matrix Ms   = imap(Qo,Mo);          export(Ms);
+  matrix Ls   = imap(Qo,Ls);          export(Ls);
+  matrix Js[e2][1];                   export(Js);
+  matrix MASS;
+  matrix Mon  = fetch(`myPx`,Mon);
+  matrix Mn,Ln,ML,Cup,Cup',Lift;
+  matrix C'   = imap(Qo,C');
+  module Co   = imap(Qo,Co);          attrib(Co,"isSB",1);
+  module ex2  = imap(Qo,ex2);         attrib(ex2,"isSB",1);
+  matrix D'   = imap(Qo,D');
+  module Do   = imap(Qo,Do);          attrib(Do,"isSB",1);
+  matrix kb2  = imap(Qo,kb2);
+  matrix kb1  = imap(Qo,kb1);
+  matrix lift1= imap(Qo,lift1);
+  poly   X_s  = imap(Po,X_s);
+  intvec intv = e1',e1,f0,f1,f2;
+         Ms,Ls= get_inf_def(Ms,Ls,kb1,lift1,X_s);
+  kill   kb1,lift1;
+  dbprint(p-1,"// infinitesimal extension",Ms);
+//----------- start the loop --------------------------------------------------
+  for (@d=2;@d<=d_max;@d=@d+1)
+  {
+    dbprint(p-3,">>> time = "+string(timer-time));
+    dbprint(p-3,"==> memory = "+string(memory(0)/1000)+
+                ",  allocated = "+string(memory(1)/1000));
+    dbprint(p,"// start deg = "+string(@d));
+//-------- get obstruction ----------------------------------------------------
+    Cup  = matrix(ideal(Ms*Ls),f0*f2,1);
+    Cup  = jet(Cup, at d, at jv);
+    Cup  = reduce(ideal(Cup),m_J);
+    Cup  = jet(Cup, at d, at jv);
+//-------- express obstruction in kbase ---------------------------------------
+    Cup' = reduce(Cup,Do);
+    tet  = simplify(ideal(Cup'),10);
+    if (tet[1]!=0)
+    { dbprint(p-4,"// *");
+      Cup = Cup-Cup';
+    }
+    Cup  = lift(D',Cup);
+    if (ok_ann)
+    { MASS = lift_rel_kb(Cup,ex2,kb2,X_s);}
+    else
+    { MASS = reduce(Cup,ex2);}
+    dbprint(p-3,"// next MATRIC-MASSEY-products",
+    MASS-jet(MASS, at d-1, at jv));
+    if   ( MASS==transpose(Js))
+         { @noObstr = 1;dbprint(p-1,"//no obstruction"); }
+    else { @noObstr = 0; }
+//-------- obtain equations of base space -------------------------------------
+    if (@noObstr == 0)
+    { Js = MASS;
+      dbprint(p-2,"// next equation of base space:",simplify(ideal(Js),10));
+ setring `myPx`;
+      Js = imap(`myQx`,Js);
+     degBound=@d+1;
+      J   = std(ideal(Js));
+      m_J = std(ideal(Mon)*J);
+     degBound=0;
+      I_J = Io,J;                attrib(I_J,"isSB",1);
+//-------- obtain new base ring -----------------------------------------------
+      if (defined(`myOx`)) {kill `myOx`;}
+ qring `myOx` = I_J;
+      ideal null,tet;            attrib(null,"isSB",1);
+      matrix Ms  = imap(`myQx`,Ms);
+      matrix Ls  = imap(`myQx`,Ls);
+      matrix Mn,Ln,ML,Cup,Cup',Lift;
+      matrix C'  = imap(Qo,C');
+      module Co  = imap(Qo,Co);   attrib(Co,"isSB",1);
+      module ex2 = imap(Qo,ex2);  attrib(ex2,"isSB",1);
+      matrix kb2 = imap(Qo,kb2);
+      poly   X_s = imap(Po,X_s);
+    }
+//-------- get lifts ----------------------------------------------------------
+   setring `myOx`;
+    ML  = matrix(reduce(ideal(Ms*Ls),null),f0,f2);
+    Cup = matrix(ideal(ML),f0*f2,1);
+    Cup = jet(Cup, at d, at jv);
+    Cup'= reduce(Cup,Co);
+    tet = simplify(ideal(Cup'),10);
+    if (tet[1]!=0)
+    { dbprint(p-4,"// #");
+     Cup = Cup-Cup';
+    }
+    Lift = lift(C',Cup);
+    Mn   = matrix(ideal(Lift),f0,f1);
+    Ln   = matrix(ideal(Lift[f0*f1+1..nrows(Lift),1]),f1,f2);
+    Ms   = Ms-Mn;
+    Ls   = Ls-Ln;
+    dbprint(p-3,"// next extension of Mo",Mn);
+    dbprint(p-3,"// next extension of syz(Mo)",Ln);
+    ML   = reduce(ideal(Ms*Ls),null);
+//--------- test: finished ----------------------------------------------------
+    tet  = simplify(ideal(ML),10);
+    if (tet[1]==0) { dbprint(p-1,"// finished in degree ", at d);}
+//---------fetch results into Qx and Px ---------------------------------------
+   setring `myPx`;
+    Ms   = fetch(`myOx`,Ms);
+    Ls   = fetch(`myOx`,Ls);
+   setring `myQx`;
+    Ms   = fetch(`myOx`,Ms);
+    Ls   = fetch(`myOx`,Ls);
+    ML   = Ms*Ls;
+    ML   = matrix(reduce(ideal(ML),null),f0,f2);
+    tet  = imap(`myOx`,tet);
+    if (tet[1]==0) { break;}
+  }
+//------- end of loop, final output -------------------------------------------
+  if (@out != "no")
+  { string out = @out+"_"+string(@d);
+    "// writing file '"+out+"' with matrix Js, matrix Ms, matrix Ls
+    ready for reading in rings "+myPx+" or "+myQx;
+    write(out,"matrix Js[1][",e2,"]=",Js,";matrix Ms[",f0,"][",f1,"]=",Ms,
+    ";matrix Ls[",f1,"][",f2,"]=",Ls,";");
+  }
+  dbprint(p-3,">>> TIME = "+string(timer-time));
+  if (@is_qh != 0)
+  { @degr = qhweight(ideal(Js));
+    @degr = @degr[1..e1'];
+    dbprint(p-1,"// quasi-homogeneous weights of miniversal base", at degr);
+  }
+  dbprint(p,"
+// 'mod_versal' returned a list, say L, of four rings. In L[2] are stored:
+//   as matrix Ms: presentation matrix of the deformed module,
+//   as matrix Ls: lifted syzygies,
+//   as matrix Js:  Equations of total space of miniversal deformation
+// To access these data, type
+     def Qx=L[2]; setring Qx; print(Ms); print(Ls); print(Js);
+");
+  option(set,save_opt);
+  return(list(`myPx`,`myQx`,`mySo`,`myOx`));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  int p = printlevel;
+  printlevel = 1;
+  ring  Ro = 0,(x,y),wp(3,4);
+  ideal Io = x4+y3;
+  matrix Mo[2][2] = x2,y,-y2,x2;
+  list L = mod_versal(Mo,Io);
+  def Qx=L[2]; setring Qx;
+  print(Ms);
+  print(Ls);
+  print(Js);
+  printlevel = p;
+  if (defined(Px)) {kill Px,Qx,So;}
+}
+///////////////////////////////////////////////////////////////////////////////
+proc kill_rings(list #)
+"USAGE: kill_rings([string]);
+RETURN: nothing, but kills exported rings generated by procedures
+        'versal' and 'mod_versal' with optional prefix 'string'
+NOTE: obsolete
+"
+{
+  string my,br;
+  if (size(#)>0)     { my = #[1];}
+  string na=nameof(basering);
+  br = my+"Qx";
+  if (defined(`br`)) { kill `br`;}
+  br = my+"Px";
+  if (defined(`br`)) { kill `br`;}
+  br = my+"So";
+  if (defined(`br`)) { kill `br`;}
+  br = my+"Ox";
+  if (defined(`br`)) { kill `br`;}
+  br = my+"Sx";
+  if (defined(`br`)) { kill `br`}
+  //Namespaces:
+  br = my+"Qx";
+  if (defined(Top::`br`)) { kill Top::`br`;}
+  br = my+"Ox";
+  if (defined(Top::`br`)) { kill Top::`br`;}
+  br = my+"Px";
+  if (defined(Ring::`br`)) { kill Ring::`br`;}
+  br = my+"So";
+  if (defined(Ring::`br`)) { kill Ring::`br`;}
+  if (defined(basering)==0)
+  { "// choose new basering?";
+    listvar(Top,ring);
+  }
+  return();
+}
+///////////////////////////////////////////////////////////////////////////////
+proc compute_ext(matrix Mo,int p)
+"
+Sub-procedure: obtain Ext1 and Ext2 and other objects used by mod_versal
+"
+{
+   int    l,f0,f1,f2,f3,e1,e2,ok_ann;
+   module Co,Do,ima,ex1,ex2;
+   matrix M0,M1,M2,ker,kb1,lift1,kb2,A,B,C,D;
+//------- resM ---------------------------------------------------------------
+   list resM = nres(Mo,3);
+   M0 = resM[1];
+   M1 = resM[2];
+   M2 = resM[3];   kill resM;
+   f0 = nrows(M0);
+   f1 = ncols(M0);
+   f2 = ncols(M1);
+   f3 = ncols(M2);
+//------ compute Ext^2  ------------------------------------------------------
+   B    = kohom(M0,f3);
+   A    = kontrahom(M2,f0);
+   D    = modulo(A,B);
+   Do   = std(D);
+   ima  = kohom(M0,f2),kontrahom(M1,f0);
+   ex2  = modulo(D,ima);
+   ex2  = std(ex2);
+   e2   = vdim(ex2);
+   kb2  = kbase(ex2);
+      dbprint(p,"// vdim (Ext^2) = "+string(e2));
+//------ test: max = Ann(Ext2) -----------------------------------------------
+   for (l=1;l<=e2;l=l+1)
+   { ok_ann = ok_ann+ord(kb2[l]);
+   }
+   if (ok_ann==0)
+   {  e2 =nrows(ex2);
+      dbprint(p,"// Ann(Ext2) is maximal");
+   }
+//------ compute Ext^1 -------------------------------------------------------
+   B     = kohom(M0,f2);
+   A     = kontrahom(M1,f0);
+   ker   = modulo(A,B);
+   ima   = kohom(M0,f1),kontrahom(M0,f0);
+   ex1   = modulo(ker,ima);
+   ex1   = std(ex1);
+   e1    = vdim(ex1);
+      dbprint(p,"// vdim (Ext^1) = "+string(e1));
+   kb1   = kbase(ex1);
+   kb1   = ker*kb1;
+   C     = concat(A,B);
+   Co    = std(C);
+//------ compute the liftings of Ext^1 ---------------------------------------
+   lift1 = A*kb1;
+   lift1 = lift(B,lift1);
+   intvec iv = f0,f1,f2,e1,e2,ok_ann;
+   list   L' = ex2,kb2,C,Co,D,Do;
+   return(iv,M1,kb1,lift1,L');
+}
+///////////////////////////////////////////////////////////////////////////////
+static proc get_rings(ideal Io,int e1,int switch, list #)
+"
+Sub-procedure: creating ring-extensions, returned as a list of 4 rings
+"
+{
+   def Po = basering;
+   string my;
+   string my_ord = "ds";
+   string my_var = "A";
+   if (size(#)>1)
+   {
+     my_ord = #[1];
+     my_var = #[2];
+   }
+   def my_Px=extendring(e1,my_var,my_ord);
+   setring my_Px;
+   ideal Io  = imap(Po,Io);
+   attrib(Io,"isSB",1);
+   qring my_Qx = Io;
+   if (switch)
+   {
+     setring my_Px;
+     qring my_Ox = std(ideal(0));
+   }
+   else
+   {
+     def my_Ox = my_Qx;
+   }
+   def my_So=defring(charstr(Po),e1,my_var,my_ord);
+   setring my_So;
+   list erg=list(my_Px,my_Qx,my_Ox,my_So);
+   return(erg);
+}
+///////////////////////////////////////////////////////////////////////////////
+proc get_inf_def(list #)
+"
+Sub-procedure: compute infinitesimal family of a module and its syzygies
+               from a kbase of Ext1 and its lifts
+"
+{
+  matrix Ms  = #[1];
+  matrix Ls  = #[2];
+  matrix kb1 = #[3];
+  matrix li1 = #[4];
+  int   e1,f0,f1,f2;
+  poly X_s     = #[5];
+  e1 = ncols(kb1);
+  f0 = nrows(Ms);
+  f1 = nrows(Ls);
+  f2 = ncols(Ls);
+  int  l;
+  for (l=1;l<=e1;l=l+1)
+  {
+     Ms = Ms + var(l)*matrix(ideal(kb1[l]),f0,f1);
+     Ls = Ls - var(l)*matrix(ideal(li1[l]),f1,f2);
+  }
+  return(Ms,Ls);
+}
+//////////////////////////////////////////////////////////////////////////////
+proc lift_rel_kb (module N, module M, list #)
+"USAGE:   lift_rel_kb(N,M[,kbaseM,p]);
+ASSUME:  [p a monomial ] or the product of all variables
+         N, M modules of same rank, M depending only on variables not in p
+         and vdim(M) is finite in this ring,
+         [ kbaseM the kbase of M in the subring given by variables not in p ] @*
+         warning: these assumptions are not checked by the procedure
+RETURN:  matrix A, whose j-th columns present the coeff's of N[j] in kbaseM,
+         i.e. kbaseM*A = reduce(N,std(M))
+EXAMPLE: example lift_rel_kb;  shows examples
+"
+{
+  poly p = product(maxideal(1));
+       M = std(M);
+  matrix A;
+  if (size(#)>0) { p=#[2]; module kbaseM=#[1];}
+  else
+  { if (vdim(M)<=0) { "// vdim(M) not finite";return(A);}
+    module kbaseM = kbase(M);
+  }
+  N = reduce(N,M);
+  if (simplify(N,10)[1]==[0]) {return(A);}
+  A = coeffs(N,kbaseM,p);
+  return(A);
+}
+example
+{
+  "EXAMPLE:"; echo=2;
+  ring r=0,(A,B,x,y),dp;
+  module M      = [x2,xy],[xy,y3],[y2],[0,x];
+  module kbaseM = [1],[x],[xy],[y],[0,1],[0,y],[0,y2];
+  poly f=xy;
+  module N = [AB,BBy],[A3xy+x4,AB*(1+y2)];
+  matrix A = lift_rel_kb(N,M,kbaseM,f);
+  print(A);
+  "TEST:";
+  print(matrix(kbaseM)*A-matrix(reduce(N,std(M))));
+}
+///////////////////////////////////////////////////////////////////////////////
+proc lift_kbase (def N,def M)
+"USAGE:   lift_kbase(N,M); N,M=poly/ideal/vector/module
+RETURN:  matrix A, coefficient matrix expressing N as linear combination of
+         k-basis of M. Let the k-basis have k elements and size(N)=c columns.
+         Then A satisfies:
+             matrix(reduce(N,std(M)),k,c) = matrix(kbase(std(M)))*A
+ASSUME:  dim(M)=0 and the monomial ordering is a well ordering or the last
+         block of the ordering is c or C
+EXAMPLE: example lift_kbase; shows an example
+"
+{
+  return(lift_rel_kb(N,M));
+}
+example
+{"EXAMPLE:";     echo=2;
+  ring R=0,(x,y),ds;
+  module M=[x2,xy],[y2,xy],[0,xx],[0,yy];
+  module N=[x3+xy,x],[x,x+y2];
+  print(M);
+  module kb=kbase(std(M));
+  print(kb);
+  print(N);
+  matrix A=lift_kbase(N,M);
+  print(A);
+  matrix(reduce(N,std(M)),nrows(kb),ncols(A)) - matrix(kbase(std(M)))*A;
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+proc interact1 ()
+"
+Sub_procedure: asking for and reading your input-strings
+"
+{
+ string my = "@";
+ string str,out,my_ord,my_var;
+ my_ord = "ds";
+ my_var = "A";
+ "INPUT: name of output-file (ENTER = no output, do not use \"my\"!)";
+   str = read("");
+   if (size(str)>1)
+   { out = str[1..size(str)-1];}
+   else
+   { out = "no";}
+ "INPUT: prefix-string of ring-extension (ENTER = '@')";
+   str = read("");
+   if ( size(str) > 1 )
+   { my = str[1..size(str)-1]; }
+ "INPUT:parameter-string
+   (give a letter corresponding to first new variable followed by the next letters,
+   or 'T('       - a letter + '('  - getting a string of indexed variables)
+   (ENTER = A) :";
+   str = read("");
+   if (size(str)>1) { my_var=str[1..size(str)-1]; }
+ "INPUT:order-string (local or weighted!) (ENTER = ds) :";
+   str = read("");
+   if (size(str)>1) { my_ord=str[1..size(str)-1]; }
+   if( find(my_ord,"s")+find(my_ord,"w") == 0 )
+   { "// ordering must be an local! changed into 'ds'";
+     my_ord = "ds";
+   }
+   return(my,my_var,my_ord,out);
+}
+///////////////////////////////////////////////////////////////////////////////
+proc interact2 (matrix A, intvec col_vec, list #)
+"
+Sub-procedure: asking for and reading your input
+"
+{
+  module B,C;
+  matrix D;
+  int flag;
+  if (size(#)>0) { D=#[1];flag=1;}
+  int t1 = ncols(A);
+  ">>Do you want all deformations? (ENTER=yes)";
+  string str = read("");
+  if ((size(str)>1) and (str<>"yes"))
+  { ">> Choose columns of the matrix";
+    ">> (Enter = all columns)";
+    "INPUT (number of columns to use as integer-list 'i_1,i_2,.. ,i_t' ):";
+    string columnes = read("");
+
+// improved: CL
+// ==========================================================
+// old:   if (size(columnes)<2) {columnes=string(col_vec);}
+//        t1 = size(columnes)/2;
+// new:
+    if (columnes=="")
+    {
+      intvec vvvv=1..ncols(A);
+    }
+    else
+    {
+      execute("intvec vvvv="+columnes);
+    }
+    t1=size(vvvv);
+// ==========================================================
+
+    int l,l1;
+    for (l=1;l<=t1;l=l+1)
+    {
+// old:   execute("l1= "+columnes[2*l-1]+";");
+      l1=vvvv[l];
+      B[l] = A[l1];
+      if(flag) { C[l]=D[l1];}
+    }
+    A = matrix(B,nrows(A),size(B));
+    D = matrix(C,nrows(D),size(C));
+  }
+  return(A,D,t1);
+}
+///////////////////////////////////////////////////////////////////////////////
+proc negative_part(intvec iv)
+"
+RETURNS intvec of indices of jv having negative entries (or iv, if non)
+"
+{
+   intvec jv;
+   int    l,k;
+   for (l=1;l<=size(iv);l=l+1)
+   { if (iv[l]<0)
+     {  k = k+1;
+        jv[k]=l;
+     }
+   }
+   if (jv==0) {jv=1; dbprint(printlevel-1,"// empty negative part, return all ");}
+   return(jv);
+}
+///////////////////////////////////////////////////////////////////////////////
+proc find_ord(matrix A, intvec w_vec)
+"
+Sub-proc: return martix ord(a_ij) with respect to weight_vec, or
+          0 if A non-qh
+"
+{
+  int @r = nrows(A);
+  int @c = ncols(A);
+  int i,j;
+  def br = basering;
+  def nr=changeord(list(list("wp",w_vec)));
+  setring nr;
+  matrix A    = imap(br,A);
+  intmat degA[@r][@c];
+  if (homog(ideal(A)))
+  { for (i=1;i<=@r;i=i+1)
+    { for(j=1;j<=@c;j=j+1)
+      {  degA[i,j]=ord(A[i,j]); }
+    }
+  }
+  setring br;
+  if (defined(nr)) { kill nr; }
+  return(degA);
+}
+///////////////////////////////////////////////////////////////////////////////
+proc homog_test(intvec w_vec, matrix Mo, matrix A)
+"
+Sub proc: return relative weight string of columns of A with respect
+          to the given w_vec and to Mo, or \"\" if not qh
+    NOTE: * means weight is not determined
+"
+{
+  int k,l;
+  intvec tv;
+  string @nv;
+  int @r = nrows(A);
+  int @c = ncols(A);
+  A = concat(matrix(ideal(Mo), at r,1),A);
+  intmat a = find_ord(A,w_vec);
+  intmat b[@r][@c];
+  for (l=1;l<=@c;l=l+1)
+  {
+    for (k=1;k<=@r;k=k+1)
+    {  if (A[k,l+1]!=0)
+       { b[k,l] = a[k,l+1]-a[k,1];}
+    }
+    tv = 0;
+    for (k=1;k<=@r;k=k+1)
+    {  if (A[k,l+1]*A[k,1]!=0)
+       {tv = tv,b[k,l];}
+    }
+    if (size(tv)>1)
+    { k = tv[2];
+      tv = tv[2..size(tv)];
+      tv = tv -k;
+      if (tv==0) { @nv = @nv+string(-k)+",";}
+      else {return("");}
+    }
+    else { @nv = @nv+"*,";}
+  }
+  @nv = @nv[1..size(@nv)-1];
+  return(@nv);
+}
+///////////////////////////////////////////////////////////////////////////////
+proc homog_t(intvec d_vec, matrix Fo, matrix A)
+"
+Sub-procedure: Computing relative (with respect to flatten(Fo)) weight_vec
+               of columns of A (return zero if Fo or A not qh)
+"
+{
+   Fo = matrix(Fo,nrows(A),1);
+   A  = concat(Fo,A);
+   A  = transpose(A);
+   def br = basering;
+   def nr=changeord(list(list("wp",d_vec)));
+   setring nr;
+   module A = fetch(br,A);
+   intvec dv;
+   int l = homog(A) ;
+   if (l==0)
+   {
+     setring br;
+     kill Top::nr;
+     if (defined(nr)) { kill nr; }
+     return(l);
+   }
+   dv = attrib(A,"isHomog");
+   l  = dv[1];
+   dv = dv[2..size(dv)];
+   dv = dv-l;
+ setring br;
+   kill Top::nr;
+   if (defined(nr)) { kill nr; }
+   return(dv);
+}
+///////////////////////////////////////////////////////////////////////////////
diff --git a/Singular/LIB/derham.lib b/Singular/LIB/derham.lib
new file mode 100644
index 0000000..8a4d5a7
--- /dev/null
+++ b/Singular/LIB/derham.lib
@@ -0,0 +1,5979 @@
+///////////////////////////////////////////////////////////////////////////////
+version="version derham.lib 4.0.0.0 Jun_2013 ";
+category="Noncommutative";
+info="
+LIBRARY:  derham.lib      Computation of deRham cohomology
+
+AUTHORS:  Cornelia Rottner, rottner at mathematik.uni-kl.de
+
+OVERVIEW:
+A library for computing the de Rham cohomology of complements of complex affine
+varieties.
+
+
+REFERENCES:
+[OT] Oaku, T.; Takayama, N.: Algorithms of D-modules - restriction, tensor product,
+     localzation, and local cohomology groups}, J. Pure Appl. Algebra 156, 267-308
+     (2001)
+[R]  Rottner, C.: Computing de Rham Cohomology,diploma thesis (2012)
+[W1] Walther, U.: Algorithmic computation of local cohomology modules and the local
+     cohomological dimension of algebraic varieties}, J. Pure Appl. Algebra 139,
+     303-321 (1999)
+[W2] Walther, U.: Algorithmic computation of de Rham Cohomology of Complements of
+     Complex Affine Varieties}, J. Symbolic Computation 29, 796-839 (2000)
+[W3] Walther, U.: Computing the cup product structure for complements of complex
+     affine varieties, J. Pure Appl. Algebra 164, 247-273 (2001)
+
+
+PROCEDURES:
+
+deRhamCohomology(list[,opt]); computes the de Rham cohomology
+MVComplex(list);              computes the Mayer-Vietoris complex
+";
+
+LIB "nctools.lib";
+LIB "matrix.lib";
+LIB "qhmoduli.lib";
+LIB "general.lib";
+//LIB "dmod.lib";
+LIB "bfun.lib";
+LIB "dmodapp.lib";
+LIB "poly.lib";
+LIB "schreyer.lib";
+LIB "dmodloc.lib";
+
+
+////////////////////////////////////////////////////////////////////////////////////
+
+proc deRhamCohomology(list L,list #)
+"USAGE: deRhamCohomology(L[,choices]); L a list consisting of polynomials, choices
+        optional list consisting of one up to three strings @*
+        The optional strings may be one of the strings@*
+        -'noCE': compute quasi-isomorphic complexes without using Cartan-Eilenberg
+         resolutionsq@*
+        -'Vdres': compute quasi-isomorphic complexes using Cartan-Eilenberg
+         resolutions; the CE resolutions are computed via V__d-homogenization
+         and without using Schreyer's method @*
+        -'Sres': compute quasi-isomorphic complexes using Cartan-Eilenberg
+         resolutions in the homogenized Weyl algebra via Schreyer's method@*
+        one of the strings@*
+        -'iterativeloc': compute localizations by factorizing the polynomials and
+         sucessive localization of the factors @*
+        -'no iterativeloc': compute localizations by directly localizing the
+         product@*
+        and one of the strings
+        -'onlybounds': computes bounds for the minimal and maximal interger roots
+         of the global b-function
+        -'exactroots' computes the minimal and maximal integer root of the global
+         b-function
+        The default is 'noCE', 'iterativeloc' and 'onlybounds'.
+ASSUME: -The basering must be a polynomial ring over the field of rational numbers@*
+RETURN: list, where the ith entry is the (i-1)st de Rham cohomology group of the
+        complement of the complex affine variety given by the polynomials in L
+EXAMPLE:example deRhamCohomology; shows an example
+"
+{
+  intvec saveoptions=option(get);
+  intvec i1,i2;
+  option(none);
+  int recursiveloc=1;
+  int i,j,nr,nc;
+  def R=basering;
+  poly islcm, forlcm;
+  int n=nvars(R);
+  int le=size(L)+n;
+  string Syzstring="noCE";
+  int onlybounds=1;
+  int diffforms;
+  for (i=1; i<=size(#); i++)
+    {
+      if (#[i]=="Sres")
+        {
+          Syzstring="Sres";
+        }
+      if (#[i]=="Vdres")
+        {
+          Syzstring="Vdres";
+        }
+      if (#[i]=="noiterativeloc")
+        {
+          recursiveloc=0;
+        }
+      if (#[i]=="exactroots")
+        {
+          onlybounds=0;
+        }
+      if (#[i]=="diffforms")
+        {
+          diffforms=1;
+        }
+    }
+  for (i=1; i<=size(L); i++)
+    {
+      if (L[i]==0)
+        {
+          L=delete(L,i);
+          i=i-1;
+        }
+    }
+  if (size(L)==0)
+    {
+      return (list(0));//////////////////////////////////////////////////////////////////stimmt das jetzt?!??????????????????????????????????
+    }
+  for (i=1; i<= size(L); i++)
+    {
+      if (leadcoef(L[i])-L[i]==0)
+        {
+          return(list(1));    ///////////////////////////////////////////////////////////////stimmt das jetzt?!????????????????????????????????????
+        }
+    }
+  if (size(L)==0)
+    {
+      /*the complement of the variety given by the input is the whole space*/
+      return(list(1));
+    }
+  for (i=1; i<=size(L); i++)
+    {
+      if (typeof(L[i])!="poly")
+        {
+          print("The input list must consist of polynomials");
+          return();
+        }
+    }
+  if (size(L)==1 and Syzstring=="noCE")
+    {
+      Syzstring="Sres";
+    }
+  /* 1st step: compute the Mayer-Vietoris Complex and its Fourier transform*/
+  def W=MVComplex(L,recursiveloc);//new ring that contains the MV complex
+  setring W;
+  list fortoVdstrict=MV;
+  if (diffforms==0)
+    {
+      ideal IFourier=var(n+1);
+      for (i=2;i<=n;i++)
+        {
+          IFourier=IFourier,var(n+i);
+        }
+      for (i=1; i<=n;i++)
+        {
+          IFourier=IFourier,-var(i);
+        }
+      map cFourier=W,IFourier;
+      matrix sup;
+      for (i=1; i<=size(MV); i++)
+        {
+          sup=fortoVdstrict[i];
+          /*takes the Fourier transform of the MV complex*/
+          fortoVdstrict[i]=cFourier(sup);
+        }
+    }
+  /* 2nd step: Compute a V_d-strict free complex that is quasi-isomorphic to the
+     complex fortoVdstrict
+     The 1st entry of the list rem will be the quasi-isomorphic complex, the 2nd
+     entry contains the cohomology modules and is needed for the computation of the
+     global b-function*/
+  if (Syzstring=="noCE")
+    {
+      list rem=quasiisomorphicVdComplex(fortoVdstrict,diffforms);
+      list quasiiso=rem[3];
+    }
+  else
+    {
+      list rem=toVdStrictFreeComplex(fortoVdstrict,Syzstring,diffforms);
+      if (diffforms==1)
+        {
+          list quasiiso=list(matrix(1,1,1));
+        }
+    }
+  list newcomplex=rem[1];
+////////////////////////////////////////////////////////////////////////////////////
+  /* 3rd step: Compute the  bounds for the minimal and maximal integer root of the
+     global b-function of newcomplex(i.e. compute the lcm of the b-functions of its
+     cohomology modules)(if onlybouns=1). Else we compute the minimal and maximal
+     integer root.
+
+     If we compute only the bounds, we omit additional Groebner basis computations.
+     However this leads to a higher-dimensional truncated complex.
+
+     Note that the  cohomology modules are already contained in rem[2].
+     minmaxk[1] and minmaxk[2] will contain the bounds resp exact roots.*/
+  if (diffforms==1)
+    {
+      list minmaxk=exactGlobalBFunIntegration(rem[2]);
+    }
+  else
+    {
+      if (onlybounds==1)
+        {
+          list minmaxk=globalBFun(rem[2],Syzstring);
+        }
+      else
+        {
+          list minmaxk=exactGlobalBFun(rem[2],Syzstring);
+        }
+    }
+  if (size(minmaxk)==0)
+    {
+      return (0);
+    }
+  ///////////////////////////////////////////////////////////////////////////Bis hierhin angepasst
+  /*4th step: Truncate the complex D_n/(x_1,...,x_n)\otimes C, (where
+    C=(C^i[m^i],d^i) is given by newcomplex, i.e. C^i=D_n^newcomplex[3*i-2],
+    m^i=newcomplex[3*i-1], d^i=newcomplex[3*i]), using Thm 5.7 in [W1]:
+    The truncated module D_n/(x_1,..,x_n)\otimes C[i] is generated by the set
+    (0,...,P_(i_j),0,...), where P_(i_j) is a monomial in C[D(1),...,D(n)] and
+    if it is placed in component k it holds that
+    minmaxk[1]-m^i[k]<=deg(P_(i_j))<=minmaxk[2]-m^i[k]*/
+  int k,l;
+  list truncatedcomplex,shorten,upto;
+  for (i=1; i<=size(newcomplex) div 3; i++)
+    {
+      shorten[3*i-1]=list();
+      for (j=1; j<=size(newcomplex[3*i-1]); j++)
+        {
+          /*shorten[3*i-1][j][k]=minmaxk[k]-m^i[j]+1 (for k=1,2) if this value is
+            positive otherwise we will set it to be list();
+.-            we added +1, because we will use a list, where we put in position l
+            polys of degree l+1*/
+          shorten[3*i-1][j]=list(minmaxk[1]-newcomplex[3*i-1][j]+1);
+          if (diffforms==1)
+            {
+              shorten[3*i-1][j][1]=1;
+            }
+          shorten[3*i-1][j][2]=minmaxk[2]-newcomplex[3*i-1][j]+1;
+          upto[size(upto)+1]=shorten[3*i-1][j][2];
+          if (shorten[3*i-1][j][2]<=0)
+            {
+              shorten[3*i-1][j]=list();
+            }
+          else
+            {
+              if (shorten[3*i-1][j][1]<=0)
+                {
+                  shorten[3*i-1][j][1]=1;
+                }
+            }
+        }
+    }
+  int iupto=Max(upto);//maximal degree +1 of the polynomials we have to consider
+  if (iupto<=0)
+    {
+      return(list(0));
+    }
+  list allpolys;
+  /*allpolys[i] will consist list of all monomials in D(1),...,D(n) of degree i-1*/
+  allpolys[1]=list(1);
+  list minvar;
+  list keepv;
+  minvar[1]=list(1);
+  for (i=1; i<=iupto-1; i++)
+    {
+      allpolys[i+1]=list();
+      minvar[i+1]=list();
+      for (k=1; k<=size(allpolys[i]); k++)
+        {
+          for (j=minvar[i][k]; j<=nvars(W) div 2; j++)
+            {
+              if (diffforms==0)
+                {
+                  allpolys[i+1][size(allpolys[i+1])+1]=allpolys[i][k]*D(j);
+                }
+              else
+                {
+                  allpolys[i+1][size(allpolys[i+1])+1]=allpolys[i][k]*x(j);
+                }
+              minvar[i+1][size(minvar[i+1])+1]=j;
+            }
+        }
+    }
+  list keepformatrix,sizetruncom,fortrun,fst;
+  int count,stc;
+  intvec v,forin;
+  matrix subm;
+  list keepcount;
+  list passendespoly;
+  /*now we compute the truncation*/
+  for (i=1; i<=size(newcomplex) div 3; i++)
+    {
+      /*truncatedcomplex[2*i-1] will contain all the generators for the truncation
+        of D_n/(x(1),..,x(n))\otimes C[i]*/
+      truncatedcomplex[2*i-1]=list();
+      sizetruncom[2*i-1]=list();
+      sizetruncom[2*i]=list();
+      passendespoly[i]=list();
+      /*truncatedcomplex[2*i] will be the map trunc(D_n/(x(1),..,x(n))\otimes C[i])
+        ->trunc(D_n/(x(1),..,x(n))\otimes C[i+1])*/
+      truncatedcomplex[2*i]=newcomplex[3*i];
+      v=0;count=0;
+      sizetruncom[2*i][1]=0;
+      for (j=1; j<=newcomplex[3*i-2]; j++)
+        {
+          if (size(shorten[3*i-1][j])!=0)
+            {
+              fortrun=sublist(allpolys,shorten[3*i-1][j][1],shorten[3*i-1][j][2]);
+              truncatedcomplex[2*i-1][size(truncatedcomplex[2*i-1])+1]=fortrun[1];
+              for (k=1; k<=size(fortrun[1]); k++)
+                {
+                  for (l=1; l<=size(fortrun[1][k]); l++)
+                    {
+                      passendespoly[i][size(passendespoly[i])+1]=list(fortrun[1][k][l][1],j);
+                    }
+                }
+              count=count+fortrun[2];
+              fst=list(int(shorten[3*i-1][j][1])-1,int(shorten[3*i-1][j][2])-1);
+              sizetruncom[2*i-1][size(sizetruncom[2*i-1])+1]=fst;
+              sizetruncom[2*i][size(sizetruncom[2*i])+1]=count;
+              if (v!=0)
+                {
+                  v[size(v)+1]=j;
+                }
+              else
+                {
+                  v[1]=j;
+                }
+            }
+        }
+      if (v!=0)
+        {
+          keepv[i]=v;
+          subm=submat(truncatedcomplex[2*i],v,1..ncols(truncatedcomplex[2*i]));
+          truncatedcomplex[2*i]=subm;
+          if (i!=1)
+            {
+              i1=1..nrows(truncatedcomplex[2*(i-1)]);
+              subm=submat(truncatedcomplex[2*(i-1)],i1,v);
+              truncatedcomplex[2*(i-1)]=subm;
+            }
+        }
+      else
+        {
+          keepv[i]=list();
+          truncatedcomplex[2*i]=matrix(0,1,ncols(truncatedcomplex[2*i]));
+          if (i!=1)
+            {
+              nr=nrows(truncatedcomplex[2*(i-1)]);
+              truncatedcomplex[2*(i-1)]=matrix(0,nr,1);
+            }
+        }
+    }
+  list keeptruncatedcomplex=truncatedcomplex;
+  matrix M;
+  int st,pi,pj;
+  poly ptc;
+  int b,d,ideg,kplus,lplus;
+  int z;
+  poly form,lform,nform;
+  /*computation of the maps*/
+  if (diffforms==1)
+    {
+      def ConvWeyl=makeConverseWeyl(nvars(basering) div 2);
+      setring ConvWeyl;
+      poly form,lform,nform;
+      poly ptc;
+      list truncatedcomplex;
+      matrix M;
+      ideal I=x(1);
+      for (i=2; i<=nvars(basering) div 2; i++)
+        {
+          I=I,var(nvars(basering) div 2 + i);
+        }
+      for (i=1; i<=nvars(basering) div 2; i++)
+        {
+          I=I,var(i);
+        }
+      map transtc=W,I;
+      truncatedcomplex=transtc(truncatedcomplex);
+    }
+  for (i=1; i<size(truncatedcomplex) div 2; i++)
+    {
+      nr=max(1,sizetruncom[2*i][size(sizetruncom[2*i])]);
+      nc=max(1,sizetruncom[2*i+2][size(sizetruncom[2*i+2])]);
+      M=matrix(0,nr,nc);
+      for (k=1; k<=size(truncatedcomplex[2*i-1]);k++)
+        {
+          for (l=1; l<=size(truncatedcomplex[2*(i+1)-1]); l++)
+            {
+              if (size(sizetruncom[2*i])!=1)
+                {
+                  for (j=1; j<=size(truncatedcomplex[2*i-1][k]); j++)
+                    {
+                      for (b=1; b<=size(truncatedcomplex[2*i-1][k][j]); b++)
+                        {
+                          form=truncatedcomplex[2*i-1][k][j][b][1];
+                          form=form*truncatedcomplex[2*i][k,l];
+
+
+                          for (z=1; z<=nvars(basering) div 2; z++)//neu
+                            {//
+                              form=subst(form,var(z),0);//
+                            }//
+
+                          while (form!=0)
+                            {
+                              lform=lead(form);
+                              v=leadexp(lform);
+                              v=v[1..n];
+                              // if (v==(0:n))
+                              //{
+                                  ideg=deg(lform)-sizetruncom[2*(i+1)-1][l][1];
+                                  if (ideg>=0)
+                                    {
+                                      nr=ideg+1;
+                                      st=size(truncatedcomplex[2*(i+1)-1][l][nr]);
+                                      for (d=1; d<=st;d++)
+                                        {
+                                          nc=2*(i+1)-1;
+                                          ptc=truncatedcomplex[nc][l][ideg+1][d][1];
+                                          if (leadmonom(lform)==ptc)
+                                            {
+                                              nr=2*i-1;
+                                              pi=truncatedcomplex[nr][k][j][b][2];
+                                              pi=pi+sizetruncom[2*i][k];
+                                              nc=2*(i+1)-1;
+                                              nr=ideg+1;
+                                              pj=truncatedcomplex[nc][l][nr][d][2];
+                                              pj=pj+sizetruncom[2*(i+1)][l];
+                                              M[pi,pj]=leadcoef(lform);
+                                              break;
+                                            }
+                                        }
+                                    }
+                                  //        }
+
+                              form=form-lform;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+      truncatedcomplex[2*i]=M;
+      truncatedcomplex[2*i-1]=sizetruncom[2*i][size(sizetruncom[2*i])];
+    }
+  truncatedcomplex[2*i-1]=sizetruncom[2*i][size(sizetruncom[2*i])];
+  if (truncatedcomplex[2*i-1]!=0)
+    {
+      truncatedcomplex[2*i]=matrix(0,truncatedcomplex[2*i-1],1);
+    }
+  if (diffforms==1)
+    {
+      setring W;
+    truncatedcomplex=imap(ConvWeyl,truncatedcomplex);
+  }
+  setring R;
+ list truncatedcomplex=imap(W,truncatedcomplex);
+/*computes the cohomology of the complex (D^i,d^i) given by truncatedcomplex,
+  i.e. D^i=C^truncatedcomplex[2*i-1] and d^i=truncatedcomplex[2*i]*/
+ if (diffforms==0)
+   {
+     list derhamhom=findCohomology(truncatedcomplex,le);
+     option(set,saveoptions);
+     return (derhamhom);
+   }
+ list outall=findCohomologyDiffForms(truncatedcomplex,le);
+ setring W;
+ list dimanddiff=imap(R,outall);
+ list alldiffforms=dimanddiff[2];
+ while(size(alldiffforms)<size(passendespoly))
+   {
+     passendespoly=delete(passendespoly,1);
+   }
+ list newdiffforms;
+ matrix Diff;
+ for (i=1; i<=size(alldiffforms); i++)
+   {
+     newdiffforms[i]=list();
+     for (j=1; j<=size(alldiffforms[i]); j++)
+       {
+         Diff=matrix(0,1,newcomplex[3*(i+size(newcomplex) div 3 - size(alldiffforms))-2]);
+         for (k=1; k<=ncols(alldiffforms[i][j]); k++)
+           {
+             if (alldiffforms[i][j][1,k]!=0)
+               {
+                 Diff[1,passendespoly[i][k][2]]=Diff[1,passendespoly[i][k][2]]+alldiffforms[i][j][1,k]*passendespoly[i][k][1];
+               }
+           }
+         newdiffforms[i][j]=Diff;
+       }
+   }
+ list omegacomplex=makeOmega(nvars(W) div 2);
+ list newcomplexmod;
+ for (i=1; i<=size(newcomplex) div 3; i++)
+   {
+     newcomplexmod[2*i-1]=newcomplex[3*i-2];
+     newcomplexmod[2*i]=newcomplex[3*i];
+   }
+ while (size(dimanddiff[1])<size(newcomplexmod) div 2)
+   {
+     newcomplexmod=delete(newcomplexmod,1);
+     newcomplexmod=delete(newcomplexmod,1);
+   }
+ while (size(dimanddiff[1])<size(quasiiso))
+   {
+     quasiiso=delete(quasiiso,1);
+   }
+ while (size(dimanddiff[1])>size(generators))
+   {
+     generators=insert(generators,list());
+   }
+ while (size(dimanddiff[1])>size(quasiiso))
+   {
+     quasiiso=insert(quasiiso,list());
+   }
+ int keepsign;
+ list derhamdiff;
+ list doublecom=makeDoubleComplex(newcomplexmod,omegacomplex,quasiiso,generators);
+ matrix diffform;
+ int stopping;
+ int p;
+ matrix convert;
+ list interim;
+ list correspondingposition;
+ list allforms=list();
+ for (i=1; i<=size(newdiffforms); i++)
+   {
+     derhamdiff[i]=list();
+     allforms[i]=list();
+     for (j=1; j<=size(newdiffforms[i]); j++)
+       {
+         allforms[i][j]=list();
+         keepsign=1;
+         derhamdiff[i][j]=0;
+         diffform=newdiffforms[i][j];//Zeilenform
+         correspondingposition=doublecom[i][1];//needed fpr transformation process
+         interim=transferDiffforms(diffform,correspondingposition);
+         if (size(interim)!=0)
+           {
+             allforms[i][j][size(allforms[i][j])+1]=interim;
+           }
+         stopping=0;
+         p=1;
+         for (k=i; k<=size(newdiffforms); k++)
+           {
+             keepsign=(-1)*keepsign;
+             if (stopping==0)
+               {
+                 if (size(doublecom[k][p][2])==0)
+                   {
+                     stopping=1;
+                   }
+                 else
+                   {
+                     if (size(doublecom[k+1][p][3])!=0)
+                       {
+                         diffform=diffform*doublecom[k][p][2];//Spaltenform
+                         if (diffform!=matrix(0,nrows(diffform),ncols(diffform)))
+                           {
+                              diffform=findPreimage(doublecom[k+1][p][3],transpose(diffform));//Zeilenform
+                             correspondingposition=doublecom[k+1][p+1];//needed for transformation process
+                             interim=transferDiffforms(keepsign*diffform,correspondingposition);
+                             if (size(interim)!=0)
+                               {
+                                 allforms[i][j][size(allforms[i][j])+1]=interim;
+                               }
+                             p=p+1;
+                           }
+                         else
+                           {
+                             stopping=1;
+                           }
+                       }
+                     else
+                       {
+                         stopping=1;
+                       }
+                   }
+               }
+           }
+       }
+   }
+ setring R;
+ list allforms=fetch(W,allforms);
+ option(set,saveoptions);
+ return (allforms);
+}
+
+example
+{ "EXAMPLE:";
+  ring r = 0,(x,y,z),dp;
+  list L=(xy,xz);
+  deRhamCohomology(L);
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+//COMPUTATION OF THE MAYER-VIETORIS COMPLEX
+////////////////////////////////////////////////////////////////////////////////////
+
+proc MVComplex(list L,list #)
+"USAGE:MVComplex(L); L a list of  polynomials
+ASSUME: -Basering is a polynomial ring with n vwariables and rational coefficients
+        -L is a list of non-constant polynomials
+RETURN: ring W: the nth Weyl algebra @*
+        W contains a list MV, which represents the Mayer-Vietrois complex (C^i,d^i) of the
+        polynomials contained in L as follows:@*
+        the C^i are given  by D_n^ncols(C[2*i-1])/im(C[2*i-1]) and the differentials
+        d^i are given by C[2*i]
+EXAMPLE:example MVComplex; shows an example
+"
+{
+  /* We follow algorithm 3.2.5 in [R],if #!=0 we use also  Remark 3.2.6 in [R] for
+     an additional iterative localization*/
+  def R=basering;
+  int i;
+  int iterative=1;
+  if (size(#)!=0)
+    {
+      iterative=#[1];
+    }
+  for (i=1; i<=size(L); i++)
+    {
+      if (L[i]==0)
+        {
+          print("localization with respect to 0 not possible");
+          return();
+        }
+      if (leadcoef(L[i])-L[i]==0)
+        {
+          print("polynomials must be non-constant");
+          return();
+        }
+    }
+  if (iterative==1)
+    {
+      /*compute the localizations by factorizing the polynomials and iterative
+        localization of the factors */
+      for (i=1; i<=size(L); i++)
+        {
+          L[i]=factorize(L[i],1);
+        }
+    }
+  int r=size(L);
+  int n=nvars(basering);
+  int le=size(L)+n;
+  /*construct the ring Ws*/
+  def W=makeWeyl(n);
+  setring W;
+  list man=ringlist(W);
+  if (n==1)
+    {
+      man[2][1]="x(1)";
+      man[2][2]="D(1)";
+      def Wi=ring(man);
+      setring Wi;
+      kill W;
+      def W=Wi;
+      setring W;
+      list man=ringlist(W);
+    }
+  man[2][size(man[2])+1]="s";;
+  man[3][3]=man[3][2];
+  man[3][2]=list("dp",intvec(1));
+  matrix N=UpOneMatrix(size(man[2]));
+  man[5]=N;
+  matrix M[1][1];
+  man[6]=transpose(concat(transpose(concat(man[6],M)),M));
+  def Ws=ring(man);
+  setring Ws;
+  int j,k,l,c;
+  list L=fetch(R,L);
+  list Cech;
+  ideal J=var(1+n);
+  for (i=2; i<=n; i++)
+    {
+      J=J,var(i+n);
+    }
+  Cech[1]=list(J);
+  list Theta, remminroots;
+  Theta[1]=list(list(list(),1,1));
+  list rem,findminintroot,diffmaps;
+  int minroot,st,sk;
+  intvec k1;
+  poly fred,forfetch;
+  matrix subm;
+  int rmr;
+  if (iterative==0)
+    {/*computation of the modules of the MV complex*/
+      for (i=1; i<=r; i++)
+        {
+          findminintroot=list();
+          Cech[i+1]=list();
+          Theta[i+1]=list();
+          k1=1;
+          for (j=1; j<=i; j++)
+            {
+              k1[size(k1)+1]=size(Theta[j+1]);
+              for (k=1; k<=k1[j]; k++)
+                {
+                  Theta[j+1][size(Theta[j+1])+1]=list(Theta[j][k][1]+list(i));
+                  Theta[j+1][size(Theta[j+1])][2]=Theta[j][k][2]*L[i];
+                  /*We compute the s-parametric annihilator J(s)  and the b-function
+                    of the polynomial L[i] and Cech[i][k] to localize the module
+                    D_n/(D(1),...,D(n))[L[i]^(-1)]\otimes D_n^c/im(Cech[i][k]),
+                    where c=ncols(Cech[i][k]) and the im(Cech[i][k]) is generated by
+                    the rows of the matrix.
+                    If we plug the minimal integer root r(or a smaller integer
+                    value)in J(s), then D_n^ncols(J(s))/im(J(r)) is isomorphic to
+                    the above localization*/
+                  rem=SannfsIBM(L[i],Cech[j][k]);
+                  Cech[j+1][size(Cech[j+1])+1]=rem[1];
+                  findminintroot[size(findminintroot)+1]=rem[2];
+                }
+            }
+          /* we compute the minimal root of all b-functions of L[i] computed above,
+             because we want to plug in the same root r in all s-parametric
+             annihilators we computed for L[i]  ->this will ensure  we can compute
+             the maps of the MV complex*/
+          minroot=minIntRootD(findminintroot);
+          for (j=1; j<=i; j++)
+            {
+              for (k=1; k<=k1[j]; k++)
+                {
+                  sk=size(Cech[j+1])+1-k;
+                  Cech[j+1][size(Cech[j+1])+1-k]=subst(Cech[j+1][sk],s,minroot);
+                }
+            }
+          remminroots[i]=minroot;
+        }
+      Cech=delete(Cech,1);
+      Theta=delete(Theta,1);
+      list zw;
+      poly reme;
+      /*computation of the maps of the MV complex*/
+      for (i=1; i<r; i++)
+        {
+          diffmaps[i]=matrix(0,size(Cech[i]),size(Cech[i+1]));
+          for (j=1; j<=size(Cech[i]); j++)
+            {
+              for (k=1; k<=size(Cech[i+1]); k++)
+                {
+                  zw=LMSubset(Theta[i][j][1],Theta[i+1][k][1]);
+                  if (zw[2]!=0)
+                    {
+                      rmr=-remminroots[zw[1]];
+                      reme=zw[2]*(Theta[i+1][k][2]/Theta[i][j][2])^(rmr);
+                      zw[2]=zw[2]*(Theta[i+1][k][2]/Theta[i][j][2])^(rmr);
+                      diffmaps[i][j,k]=zw[2];
+                    }
+                }
+            }
+        }
+      diffmaps[r]=matrix(0,1,1);
+    }
+  list generators;
+  if (iterative==1)
+    {
+      for (i=1; i<=r;i++)
+        {
+          generators[i]=list();////////////////////////////////////////////////////////////////////
+          Cech[i+1]=list();
+          Theta[i+1]=list();
+          k1=1;
+          for (c=1; c<=size(L[i]); c++)
+            {
+              findminintroot=list();
+              for (j=1; j<=i; j++)
+                {
+                  if (c==1)
+                    {
+                      k1[size(k1)+1]=size(Theta[j+1]);
+                    }
+                  for (k=1; k<=k1[j]; k++)
+                    {
+                      /*We compute the s-parametric annihilator J(s)  und the b-
+                        function of the polynomial L[i][c] and Cech[i][k] to
+                        localize the module D_n/(D(1),...,D(n))[L[i][c]^(-1)]\otimes
+                        D_n^c/im(Cech[i][k]), where c=ncols(Cech[i][k]).
+                        If we plug the minimal integer root r(or a smaller integer
+                        value)in J(s), then D_n^ncols(J(s))/im(J(r)) is isomorphic
+                        to the above localization*/
+                      if (c==1)
+                        {
+                          rmr=size(Theta[j+1])+1;
+                          Theta[j+1][rmr]=list(Theta[j][k][1]+list(i));
+                          Theta[j+1][size(Theta[j+1])][2]=Theta[j][k][2]*L[i][c];
+                          rem=SannfsIBM(L[i][c],Cech[j][k]);
+                          Cech[j+1][size(Cech[j+1])+1]=rem[1];
+                          findminintroot[size(findminintroot)+1]=rem[2];
+                        }
+                      else
+                        {
+                          st=size(Theta[j+1])-k1[j]+k;
+                          Theta[j+1][st][2]=Theta[j+1][st][2]*L[i][c];
+                          rem=SannfsIBM(L[i][c],Cech[j+1][size(Cech[j+1])-k1[j]+k]);
+                          Cech[j+1][size(Cech[j+1])-k1[j]+k]=rem[1];
+                          findminintroot[size(findminintroot)+1]=rem[2];
+                        }
+                    }
+                }
+                /* we compute the minimal root of all b-functions of L[i][c]
+                   computed above,because we want to plug in the same root r in all
+                   s-parametric annihilators we computed for L[i]  ->this will
+                   ensure  we can compute the maps of the MV complex*/
+              minroot=minIntRootD(findminintroot);
+              for (j=1; j<=i; j++)
+                {
+                  for (k=1; k<=k1[j]; k++)
+                    {
+                      st=size(Cech[j+1])+1-k;
+                      Cech[j+1][st]=subst(Cech[j+1][st],s,minroot);
+                    }
+                }
+              if (c==1)
+                {
+                  remminroots[i]=list();
+                }
+              remminroots[i][c]=minroot;
+            }
+        }
+      Cech=delete(Cech,1);
+      Theta=delete(Theta,1);
+      list zw;
+      poly reme;
+      /*maps of the MV Complex*/
+      for (i=1; i<r; i++)
+        {
+          diffmaps[i]=matrix(0,size(Cech[i]),size(Cech[i+1]));
+          for (j=1; j<=size(Cech[i]); j++)
+            {
+              for (k=1; k<=size(Cech[i+1]); k++)
+                {
+                  zw=LMSubset(Theta[i][j][1],Theta[i+1][k][1]);
+                  if (zw[2]!=0)
+                    {
+                      reme=1;
+                      for (c=1; c<=size(L[zw[1]]);c++)
+                        {
+                          reme=reme*L[zw[1]][c]^(-remminroots[zw[1]][c]);
+                        }
+                      diffmaps[i][j,k]=zw[2]*reme;
+                    }
+                }
+            }
+        }
+      diffmaps[r]=matrix(0,1,1);
+      for (i=1; i<=r; i++)
+        {
+          for (j=1; j<=size(Theta[i]); j++)
+            {
+              generators[i][j]=1;
+              for (c=1; c<=size(Theta[i][j][1]); c++)
+                {
+                  for (k=1; k<=size(L[Theta[i][j][1][c]]); k++)
+                    {
+                      generators[i][j]=generators[i][j]*L[Theta[i][j][1][c]][k]^((-1)*remminroots[Theta[i][j][1][c]][k]);
+                    }
+                }
+            }
+        }
+    }
+  setring W;
+  /*map the modules and maps to the Weyl algebra*/
+  list diffmaps=imap(Ws,diffmaps);
+  list Cechmodules=imap(Ws,Cech);
+  if (iterative==1)
+    {
+      list Theta=imap(Ws,Theta);
+      list generators=imap(Ws,generators);
+    }
+  list Cech;
+  matrix sup;
+  for (i=1; i<=r; i++)
+    {
+      sup=transpose(matrix(Cechmodules[i][1]));
+      Cech[2*i-1]=sup;
+      for (j=2; j<=size(Cechmodules[i]); j++)
+        {
+          sup=transpose(matrix(Cechmodules[i][j]));
+          Cech[2*i-1]=dsum(Cech[2*i-1],sup);
+        }
+      sup=matrix(diffmaps[i]);
+      Cech[2*i]=sup;
+    }
+  list MV=Cech;
+  if (iterative==1)
+    {
+      export Theta;
+      export generators;
+    }
+  export MV;
+
+  return (W);
+}
+
+example
+{ "EXAMPLE:";
+  ring r = 0,(x,y,z),dp;
+  list L=xy,xz;
+  def C=MVComplex(L);
+  setring C;
+  MV;
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+
+static proc SannfsIBM(poly F,ideal myJ)
+"USAGE: SannfsIBM(f,J), F poly, J ideal
+ASSUME: basering is D_n[s], where D_n is the Weyl algebra and s and extra
+        commutative variable@*
+        f is a polynomial in the variables x(1),...,x(n) with rational coefficients
+        @*
+        J is holonomic and f-saturated
+RETURN  AlList of the form (K,g), where K is an ideal and g a univariant polynomial
+        in  the variable s. K is the s-parametric annihilator of F and J and g is
+        the b-function of F and J.
+"
+{
+  /*modified version of the procedure SannfsBM from the library dmod.lib: SannfsBM
+    computes the s-parametric annihilator for J=(x_1,...,x_n)*/
+  /* We use Algorithm 3.1.12 in[R] to compute the s-parametric
+     annihilator. Then we use the s-parametric annihilator to compute the b-function
+     via Algorithm 4.7 in [W1].*/
+  /* We assume that the basering the the nth Weyl algebra D_n. We create the ring
+     D_n[s,t], where t*s=s*t-t*/
+  def save = basering;
+  int N = nvars(basering)-1;
+  int Nnew = N+2;
+  int i,j;
+  string s;
+  list RL = ringlist(basering);
+  list L, Lord;
+  list tmp;
+  intvec iv;
+  L[1] = RL[1];
+  L[4] = RL[4];
+  list Name  = RL[2];
+  Name=delete(Name,size(Name));
+  list RName;
+  RName[1] = "t";
+  RName[2] = "s";
+  list DName;
+ for(i=1;i<=N div 2;i++)
+  {
+    DName[i] = var(N div 2+i);
+    Name=delete(Name,N div 2+1);
+  }
+  tmp[1] = "t";
+  tmp[2] = "s";
+  list NName = tmp +Name+DName;
+  L[2]   = NName;
+  kill NName;
+  tmp[1]  = "lp";
+  iv      = 1,1;
+  tmp[2]  = iv;
+  Lord[1] = tmp;
+  tmp[1]  = "dp";
+  s       = "iv=";
+  for(i=1;i<=Nnew;i++)
+  {
+    s = s+"1,";
+  }
+  s[size(s)]= ";";
+  execute(s);
+  kill s;
+  tmp[2]    = iv;
+  Lord[2]   = tmp;
+  tmp[1]    = "C";
+  iv        = 0;
+  tmp[2]    = iv;
+  Lord[3]   = tmp;
+  tmp       = 0;
+  L[3]      = Lord;
+  def @R@ = ring(L);
+  setring @R@;
+  matrix @D[Nnew][Nnew];
+  @D[1,2]=t;
+  for(i=1; i<=N div 2; i++)
+  {
+    @D[2+i, N div 2+2+i]=1;
+  }
+  def @R = nc_algebra(1, at D);
+  setring @R;
+  kill @R@;
+  /*we start with the computation of the s-parametric annihilator*/
+  poly  F = imap(save,F);
+  ideal myJ=imap(save,myJ);
+  for (i=1; i<=N div 2; i++)
+    {
+      myJ=subst(myJ,D(i),D(i)+diff(F,x(i))*t);
+    }
+  ideal I = t*F+s;
+  I=I,myJ;//the s-parametric annihilator in D_n[s,t]
+  /*we compute the intersection of I and D_n[s]*/
+  ideal J = slimgb(I);
+  ideal K = nselect(J,1);
+  K = slimgb(K);//the s-parametric annihilator
+  /*we use K to compute the b-function*/
+  ideal B=K,F;
+  B=slimgb(B);
+  vector p=pIntersect(s,B);
+  poly f=vec2poly(p,2);
+  setring save;
+  poly f=imap(@R,f);
+  ideal K=imap(@R,K);
+  return (list(K,f));
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+//COMPUTATION OF A QUASI-ISOMORPHIC V_D-STRICT FREE COMPLEX
+////////////////////////////////////////////////////////////////////////////////////
+
+static proc quasiisomorphicVdComplex(list L,list #)
+"USAGE: quasiisomorphicVdComplex(L[,df]); L a list of the form (M_1,f_1,...,M_s,f_s),
+        where the M_i and f_i are matrices
+ASSUME: Basering is the Weyl algebra D_n @*
+        (M_1,f_1,...,M_s,f_s) represents a complex 0->D_n^(r_1)/im(M_1)->
+        D_n^(r_2)/im(M_2)->...->D_n^(r_s)->0 with differentials f_i, where im(M_i)
+        is generated by the rows of M_i. In particular it hold:@*
+        - The M_i are m_i x r_i-matrices and the f_iare r_i x r_(i+1)-matrices @*
+        -the image of M_1*f_i is contained in the image of M_(i+1) @*
+        d is an integer between 1 and n. If no value for d is given, it is assumed
+        to be n @*
+        df is an optional int, if df equals 1 a \tilde(V_d)-strict complex
+        will be computed (instead of a V_d-strict one) (for a definition see [W3])
+RETURN: list of the form (L_1,L_2), were L_1 and L_2 are lists @*
+        L_1 is of the form (i_(-n-1),g_(-n-1),m_(-n-1),...,i_s,g_s,m_s) such that:@*
+        -the i_j are integers, the g_j are i_j x i_(j+1)-matrices, the m_j intvecs
+         of size i_j@*
+        -D_n^(i_(-n-1))[m_(-n-1)]->...->D_n^(i_s)[m_s]->0  is a V_d-strict complex
+         with differentials m_i that is quasi-isomorphic to the complex given by L@*
+        L_2 is of the form (H_1,n_1,...,H_s,n_s), where the H_i are matrices and
+        the n_i are shift vectors such that:@*
+        -coker(H_i) is the ith cohomology group of the complex given by L_1@*
+        -the n_i are the shift vectors of the coker(H_i)
+THEORY: We follow Proposition 3.2 and Corollary 3.3 in [W3]
+"
+{
+  int tilde;
+  if (size(#)!=0)
+    {
+      tilde=#[1];
+    }
+  def B=basering;
+  int n=nvars(B) div 2 + 1;//+1 muesste stimmen! bitte kontrollieren!
+  int d=nvars(B) div 2;
+  int r=size(L) div 2;
+  int lonc=n+r;
+  int Kiold=0;
+  matrix kerold;
+  // matrix kernew=out[r][2][2];
+  matrix kernew=diag(1,ncols(L[size(L)-1]));
+  module mL;
+  int i;
+  int k;
+  matrix testm;
+  int Kinew=nrows(kernew);
+  int Jiold=0;
+  int Jinew=0;
+  matrix Niold;
+  matrix Ninew;
+  list newcomplex;
+  int Aiold=Kinew;
+  matrix savediv;
+  newcomplex[3*lonc-2]=Kinew;
+  newcomplex[3*lonc-1]=intvec(0:Kinew);
+  newcomplex[3*lonc]=matrix(0,Kinew,1);
+  list quasiiso;
+  quasiiso[lonc]=diag(1,Kinew);
+  matrix invimage;
+  matrix keralpha;
+  intvec v;
+  int j;
+  matrix sc;
+  matrix fnc;
+  int indk;
+  int indj;
+  int Aiold;
+  list saveres;
+  matrix Liplus;
+  for (i=r-1; i>=0; i--)
+    {
+      indk=0;
+      indj=0;
+      Kiold=Kinew;
+      kerold=kernew;
+      if (i!=0)
+        {
+          // kernew=divdr(L[2*i],L[2*i+1],1);
+          kernew=divdr(L[2*i],L[2*i+1]);
+          mL=slimgb(transpose(L[2*i-1]));
+          for (k=1; k<=nrows(kernew); k++)
+            {
+              testm=reduce(transpose(submat(kernew,k,intvec(1..ncols(kernew)))),mL);
+              if (testm==matrix(0,nrows(testm),ncols(testm)))
+                {
+                  kernew=transpose(deletecol(transpose(kernew),k));
+                  k=k-1;
+                }
+            }
+          Kinew=nrows(kernew);
+          if (kernew==matrix(0,nrows(kernew),ncols(kernew)))
+            {
+              Kinew=0;
+              indk=1;
+            }
+        }
+      else
+        {
+          Kinew=0;
+          indk=1;
+        }
+      Jiold=Jinew;
+      Niold=Ninew;
+      keralpha=transpose(syz(transpose(newcomplex[3*(i+n)+3])));
+      if (i!=0)
+        {
+          invimage=divdr(quasiiso[n+i+1],transpose(concat(transpose(L[2*i]),transpose(L[2*i+1]))));
+          Ninew=vdStrictIntersect(keralpha,invimage,newcomplex[3*(n+i+1)-1],tilde);//////////////
+        }
+      else
+        {
+          invimage=divdr(quasiiso[n+i+1],L[2*i+1]);
+          saveres=vdStrictIntersectPlus(keralpha,invimage,newcomplex[3*(n+i+1)-1],tilde);////////////////////////
+
+          ///////////////////BIS HIERHIN VERALLGEMEINERT////////////////////////////////////////////////////////////////////
+
+
+          Ninew=saveres[1];
+        }
+      Jinew=nrows(Ninew);
+      if (Ninew==matrix(0,nrows(Ninew),ncols(Ninew)))
+        {
+          Jinew=0;
+          indk=1;
+        }
+      newcomplex[3*(n+i)-2]=Kinew+Jinew;
+      v=0;
+      if (indk==0)
+        {
+          v=(0:Kinew);
+          if (indj==0)
+            {
+              fnc=transpose(concat(transpose(matrix(0,Kinew,Kiold+Jiold)),transpose(Ninew)));
+            }
+          else
+            {
+              fnc=matrix(0,Kinew,Kiold+Jiold);
+            }
+        }
+      else
+        {
+          if (indj==0)
+            {
+              fnc=Ninew;
+            }
+          else
+            {
+              fnc=matrix(0,1,Kiold+Jiold);
+              newcomplex[3*(n+i)-2]=1;
+            }
+        }
+      Aiold=Jinew+Kinew;
+      if (Aiold==0)
+        {
+          Aiold=1;
+        }
+      newcomplex[3*(n+i)]=fnc;
+      for (j=1; j<=Jinew; j++)
+        {
+          if (tilde==0)
+            {
+              v[Kinew+j]=VdDeg(submat(Ninew,j,(1..ncols(Ninew))),nvars(B) div 2,newcomplex[3*(n+i)+2]);
+            }
+          else
+            {
+              v[Kinew+j]=VdDegTilde(submat(Ninew,j,(1..ncols(Ninew))),nvars(B) div 2,newcomplex[3*(n+i)+2]);
+            }
+        }
+      newcomplex[3*(n+i)-1]=v;
+      if (i==0)
+        {
+          quasiiso[n+i]=matrix(0,Jinew,1);
+        }
+      else
+        {
+          if (indj==0)
+            {
+              sc=submat(fnc,intvec(Kinew+1..nrows(fnc)),intvec(1..ncols(fnc)))*quasiiso[n+i+1];
+              Liplus=transpose(concat(transpose(L[2*i]),transpose(L[2*i+1])));
+              sc=matrixLift(Liplus,sc);//stimmt das jetzt
+              sc=submat(sc,intvec(1..nrows(sc)),intvec(1..nrows(L[2*i])));
+              if (indk==0)
+                {
+                  //pi=kernew
+                  quasiiso[n+i]=transpose(concat(transpose(kernew),transpose(sc)));
+                }
+              else
+                {
+                  quasiiso[n+i]=sc;
+                }
+            }
+          else
+            {
+              if (indk==0)
+                {
+                  quasiiso[n+i]=kernew;
+                }
+              else
+                {
+                  quasiiso[n+i]=matrix(0,1,ncols(kernew));
+                }
+            }
+        }
+    }
+  for (i=1; i<=n-1; i++)
+    {
+      quasiiso[n-i]=list();
+      if (size(saveres[2][i])!=0)
+        {
+          newcomplex[3*(n-i)]=saveres[2][i];
+          newcomplex[3*(n-i)-2]=nrows(saveres[2][i]);
+          v=0;
+          for (j=1; j<=newcomplex[3*(n-i)-2]; j++)
+            {
+              if (tilde==0)
+                {
+                  v[j]=VdDeg(submat(saveres[2][i],j,(1..ncols(saveres[2][i]))),nvars(B) div 2, newcomplex[3*(n-i)+2]);
+                }
+              else
+                {
+                  v[j]=VdDegTilde(submat(saveres[2][i],j,(1..ncols(saveres[2][i]))),nvars(B) div 2, newcomplex[3*(n-i)+2]);
+                }
+            }
+          newcomplex[3*(n-i)-1]=v;
+        }
+      else
+        {
+          newcomplex[3*(n-i)]=matrix(0,1,1);
+          if (newcomplex[3*(n-i)+1]!=0)
+            {
+              newcomplex[3*(n-i)]=matrix(0,1,newcomplex[3*(n-i)+1]);
+            }
+          newcomplex[3*(n-i)-2]=int(0);
+          newcomplex[3*(n-i)-1]=intvec(0);
+        }
+    }
+  list result;
+  result[1]=newcomplex;
+  result[2]=list();
+  list forsep;
+  for (i=1; i<=size(L) div 2+1; i++)
+    {
+      forsep[2*i]=newcomplex[3*(n+i-1)];
+      forsep[2*i-1]=matrix(0,1,nrows(forsep[2*i]));
+    }
+  forsep=shortExactPieces(forsep);
+  list listofHis;
+  matrix forVd;
+  for (i=1; i<=size(L) div 2; i++)
+    {
+      v=0;
+      listofHis[i]=list(forsep[i+1][1][5]);
+      forVd=forsep[i+1][2][2];
+      for (j=1; j<=nrows(forVd); j++)
+        {
+          if (tilde==0)
+            {
+              v[j]=VdDeg(submat(forVd,j,intvec(1..ncols(forVd))),nvars(B) div 2, newcomplex[3*(n+i)-1]);
+            }
+          else
+            {
+              v[j]=VdDegTilde(submat(forVd,j,intvec(1..ncols(forVd))),nvars(B) div 2, newcomplex[3*(n+i)-1]);
+            }
+        }
+      listofHis[i][2]=v;
+    }
+  result[2]=listofHis;
+  result[3]=quasiiso;
+  return(result);
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+
+static proc vdStrictIntersect(matrix M, matrix N, intvec v, int tilde)
+{
+  def B=basering;
+  option(returnSB);//                    alternative:erst intersect und dann SB-Berechung mit slimgb
+  if (tilde==0)
+    {
+      def HomWeyl=makeHomogenizedWeyl(nvars(B) div 2,v);
+    }
+  else
+    {
+      def HomWeyl=makeHomogenizedWeylTilde(nvars(B) div 2,v);
+    }
+  setring HomWeyl;
+  matrix M=fetch(B,M);
+  matrix N=fetch(B,N);
+  M=nHomogenize(M);
+  N=nHomogenize(N);
+  matrix vdintersection=transpose(intersect(transpose(M),transpose(N)));
+  vdintersection=subst(vdintersection,h,1);
+  setring B;
+  matrix vdintersection=fetch(HomWeyl,vdintersection);
+  option(noreturnSB);
+  return(vdintersection);
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+
+static proc vdStrictIntersectPlus(matrix M, matrix N, intvec v, int tilde)
+{
+  def B=basering;
+  int n=nvars(B) div 2;
+  matrix vdint=transpose(intersect(transpose(M),transpose(N)));
+  if (tilde==0)
+    {
+      def HomWeyl=makeHomogenizedWeyl(nvars(B) div 2,v);
+    }
+  else
+    {
+      def HomWeyl=makeHomogenizedWeylTilde(nvars(B) div 2,v);
+    }
+  setring HomWeyl;
+  matrix vdint=fetch(B,vdint);
+  matrix N=fetch(B,N);
+  vdint=nHomogenize(vdint);
+  intvec i1;
+  intvec i2;
+  int i;
+  int nr;
+  int nc;
+  def ringofSyz=Sres(transpose(vdint),n);////////////////////////////////////////////////////////////////
+  setring ringofSyz;
+  matrix vdint=transpose(matrix(RES[2]));
+  vdint=subst(vdint,h,1);
+  int logens=ncols(vdint)+1;
+  int omitemptylist;
+  matrix zerom;
+  list rofA;
+  for (i=3; i<=n+3; i++)////////////////////////////////////////////////////////////////////////////n und si muessen noch definiert werden
+    {
+      if (size(RES)>=i)
+        {
+          zerom=matrix(0,nrows(matrix(RES[i])),ncols(matrix(RES[i])));
+          if (RES[i]!=zerom)
+            {
+              rofA[i-2]=(matrix(RES[i]));
+              if (i==3)
+                {
+                  if (nrows(rofA[i-2])-logens+1!=nrows(vdint))
+                    {
+                      //build the resolution
+                      nr=nrows(vdint)+logens-1;
+                      nc=ncols(rofA[i-2]);
+                      rofA[i-2]=matrix(rofA[i-2],nr,nc);
+                    }
+
+                }
+              if (i!=3)
+                {
+                  if (nrows(rofA[i-2])-logens+1!=nrows(rofA[i-3]))
+                    {
+                      nr=nrows(rofA[i-3])+logens-1;
+                      nc=ncols(rofA[i-2]);
+                      rofA[i-2]=matrix(rofA[i-2],nr,nc);
+                    }
+                }
+              i1=intvec(logens..nrows(rofA[i-2]));
+              i2=intvec(1..ncols(rofA[i-2]));
+              rofA[i-2]=transpose(submat(rofA[i-2],i1,i2));
+              logens=logens+ncols(rofA[i-2]);
+              rofA[i-2]=subst(rofA[i-2],h,1);
+            }
+          else
+            {
+              rofA[i-2]=list();
+            }
+        }
+      else
+        {
+          rofA[i-2]=list();
+        }
+    }
+  if(size(rofA[1])==0)
+    {
+      omitemptylist=1;
+    }
+  setring B;
+  vdint=fetch(ringofSyz,vdint);
+  if (omitemptylist!=1)
+    {
+      list rofA=fetch(ringofSyz,rofA);
+    }
+  kill HomWeyl;
+  kill ringofSyz;
+  return(list(vdint,rofA));
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+
+static proc toVdStrictFreeComplex(list L,string Syzstring,list #)
+"USAGE: toVdStrictFreeComplex(L, Syzstring [,d]); L a list of the form
+        (M_1,f_1,...,M_s,f_s), where the M_i and f_i are matrices, Syzstring a
+        string, d an optional integer
+ASSUME: Basering is the Weyl algebra D_n @*
+        (M_1,f_1,...,M_s,f_s) represents a complex 0->D_n^(r_1)/im(M_1)->
+        D_n^(r_2)/im(M_2)->...->D_n^(r_s)->0 with differentials f_i, where im(M_i)
+        is generated by the rows of M_i. In particular it hold:@*
+        - The M_i are m_i x r_i-matrices and the f_iare r_i x r_(i+1)-matrices @*
+        -the image of M_1*f_i is contained in the image of M_(i+1) @*
+        d is an optional integer which indices in the case size(L)=2, whether a
+        V_d-strict or \tilde(V_d)-strict will be computed@*
+        Syzstring is either: @*
+        -'Sres' (computes the resolutions and Groebner bases in the homogenized
+         Weyl algebra using Schreyer's method)@*
+        or @*
+        -'Vdres' (computes the resolutions via V_d-homogenization and without
+         Schreyer's method)@*
+RETURN: list of the form (L_1,L_2), were L_1 and L_2 are lists @*
+        L_1 is of the form (i_(-n-1),g_(-n-1),m_(-n-1),...,i_s,g_s,m_s) such that:@*
+        -the i_j are integers, the g_j are i_j x i_(j+1)-matrices, the m_j intvecs
+         of size i_j@*
+        -D_n^(i_(-n-1))[m_(-n-1)]->...->D_n^(i_s)[m_s]->0  is a V_d-strict complex
+         with differentials m_i that is quasi-isomorphic to the complex given by L@*
+        L_2 is of the form (H_1,n_1,...,H_s,n_s), where the H_i are matrices and
+        the n_i are shift vectors such that:@*
+        -coker(H_i) is the ith cohomology group of the complex given by L_1@*
+        -the n_i are the shift vectors of the coker(H_i)
+THEORY: We follow Algorithm 3.8 in [W2]
+"
+{
+  def B=basering;
+  int n=nvars(B) div 2+2;
+  int d=nvars(B) div 2;
+  intvec v;
+  list out, outall;
+  int i,j,k,indi,nc,nr;
+  matrix mem;
+  intvec i1,i2;
+  int tilde;
+  if (size(#)!=0)
+    {
+      for (i=1; i<=size(#); i++)
+        {
+          if (typeof(#[i])=="int")
+            {
+              tilde=#[i];
+            }
+        }
+    }
+  /* If size(L)=2, our complex consists for only one non-trivial module.
+     Therefore, we just have to compute a V_d-strict resolution of this module.*/
+  if (size(L)==2)
+    {
+      v=(0:ncols(L[1]));
+      out[3*n-1]=v;
+      out[3*n-2]=ncols(L[1]);
+      out[3*n]=L[2];
+      if (Syzstring=="Vdres")
+        {
+          /*if Syzstring="Vdres", we compute a V_d-strict Groebner basis of L[1]
+            using F-homogenization (Prop. 3.9 in [OT]); then we compute the syzygies
+            and make them V_d-strict using Prop  3.9[OT] and so on*/
+          out[3*n-3]=VdStrictGB(L[1],d,v);
+          for (i=n-1; i>=1; i--)
+            {
+              out[3*i-2]=nrows(out[3*i]);
+              v=0;
+              for (j=1; j<=out[3*i-2]; j++)
+                {
+                  mem=submat(out[3*i],j,intvec(1..ncols(out[3*i])));
+                  v[j]=VdDeg(mem,d, out[3*i+2]);//next shift vector
+                }
+              out[3*i-1]=v;
+              if (i!=1)
+                {
+                  /*next step in the resolution*/
+                  out[3*i-3]=transpose(syz(transpose(out[3*i])));
+                  if (out[3*i-3]!=matrix(0,nrows(out[3*i-3]),ncols(out[3*i-3])))
+                    {
+                      /*makes the resolution V_d-strict*/
+                      out[3*i-3]=VdStrictGB(out[3*i-3],d,out[3*i-1]);
+                    }
+                  else
+                    {
+                      /*resolution is already computed*/
+                      out[3*i-3]=matrix(0,1,ncols(out[3*i-3]));
+                      out[3*i-4]=intvec(0);
+                      out[3*i-5]=int(0);
+                      for (j=i-2; j>=1; j--)
+                        {
+                          out[3*j]=matrix(0,1,1);
+                          out[3*j-1]=intvec(0);
+                          out[3*j-2]=int(0);
+                        }
+                      break;
+                    }
+                }
+            }
+        }
+      else
+        {
+          /*in the case Syzstring!="Vdres" we compute the resolution in the
+            homogenized Weyl algebra using Thm 9.10 in[OT]*/
+          if (tilde==0)
+            {
+              def HomWeyl=makeHomogenizedWeyl(d);
+            }
+          else
+            {
+              def HomWeyl=makeHomogenizedWeylTilde(d);
+            }
+          setring HomWeyl;
+          list L=fetch(B,L);
+          L[1]=nHomogenize(L[1]);
+          list out=fetch(B,out);
+          out[3*n-3]=L[1];
+          /*computes a ring with a list RES; RES is a V_d-strict resolution of
+            L[1]*/
+          def ringofSyz=Sres(transpose(L[1]),d);
+          setring ringofSyz;
+          int logens=2;
+          matrix mem;
+          list out=fetch(HomWeyl,out);
+          out[3*n-3]=transpose(matrix(RES[2]));
+          out[3*n-3]=subst(out[3*n-3],h,1);
+          for (i=n-1; i>=1; i--)
+            {
+              out[3*i-2]=nrows(out[3*i]);
+              v=0;
+              for (j=1; j<=out[3*i-2]; j++)
+                {
+                  mem=submat(out[3*i],j,intvec(1..ncols(out[3*i])));
+                  if (tilde==0)
+                    {
+                      v[j]=VdDeg(mem,d, out[3*i+2]);
+                    }
+                  else
+                    {
+                      v[j]=VdDegTilde(mem,d, out[3*i+2]);
+                    }
+                }
+              out[3*i-1]=v;//shift vector such that the resolution RES is V_d-strict
+              if (i!=1)
+                {
+                  indi=0;
+                  if (size(RES)>=n-i+2)
+                    {
+                      nr=nrows(matrix(RES[n-i+2]));
+                      mem=matrix(0,nr,ncols(matrix(RES[n-i+2])));
+                      if (matrix(RES[n-i+2])!=mem)
+                        {
+                          indi=1;
+                          out[3*i-3]=(matrix(RES[n-i+2]));
+                          if (nrows(out[3*i-3])-logens+1!=nrows(out[3*i]))
+                            {
+                              mem=out[3*i-3];
+                              out[3*i-3]=matrix(mem,nrows(mem)+logens-1,ncols(mem));
+                            }
+                          mem=out[3*i-3];
+                          i1=intvec(logens..nrows(mem));
+                          mem=submat(mem,i1,intvec(1..ncols(mem)));
+                          out[3*i-3]=transpose(mem);
+                          out[3*i-3]=subst(out[3*i-3],h,1);
+                          logens=logens+ncols(out[3*i-3]);
+                        }
+                    }
+                  if(indi==0)
+                    {
+                      out[3*i-3]=matrix(0,1,nrows(out[3*i]));
+                      out[3*i-4]=intvec(0);
+                      out[3*i-5]=int(0);
+                      for (j=i-2; j>=1; j--)
+                        {
+                          out[3*j]=matrix(0,1,1);
+                          out[3*j-1]=intvec(0);
+                          out[3*j-2]=int(0);
+                        }
+                      break;
+                    }
+                }
+            }
+          setring B;
+          out=fetch(ringofSyz,out);//contains the V_d-strict resolution
+          kill ringofSyz;
+        }
+      outall[1]=out;
+      outall[2]=list(list(out[3*n-3],out[3*n-1]));
+      return(outall);
+    }
+  /*case size(L)>2: We compute a quasi-isomorphic free complex following Alg 3.8 in
+    [W2]*/
+  /* We denote the complex given by L as (C^i,d^i).
+     We start by computing in the proc shortExaxtPieces representations for the
+     short exact sequences B^i->Z^i->H^i and Z^i->C^i->B^(i+1), where the B^i, Z^i
+     and H^i are coboundaries, cocycles and cohomology groups, respectively.*/
+  out=shortExactPieces(L);
+  list rem;
+  /* shortExactpiecesToVdStrict makes the sequences B^i->Z^i->H^i and
+     Z^i->C^i->B^(i+1) V_d-strict*/
+  rem=shortExactPiecesToVdStrict(out,d,Syzstring);
+  /*VdStrictDoubleComplexes computes V_d-strict resolutions over the seqeunces from
+    proc shortExactPiecesToVdstrict*/
+  out=VdStrictDoubleComplexes(rem[1],d,Syzstring);
+  for (i=1;i<=size(out); i++)
+    {
+      rem[2][i][1]=out[i][1][5][1];
+      rem[2][i][2]=out[i][1][8][1];
+    }
+  /* AssemblingDoubleComplexes puts the resolution of the C^i (from the sequences
+     Z^i->C^i->B^(i+1)) together to obtain a Cartan-Eilenberg resolution of
+     (C^i,d^i)*/
+  out=assemblingDoubleComplexes(out);
+  /*the proc totalComplex takes the total complex of the double complex from the
+    proc assemblingDoubleComplexes*/
+  out=totalComplex(out);
+  outall[1]=out;
+  outall[2]=rem[2];//contains the cohomology groups and their shift vectors
+  return (outall);
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+
+
+static proc sublist(list L,int m,int n)
+{
+  list out;
+  int i; int j;
+  int count;
+  for (i=m; i<=n; i++)
+    {
+      out[size(out)+1]=list();
+      for (j=1; j<=size(L[i]); j++)
+        {
+          count=count+1;
+          out[size(out)][j]=list(L[i][j],count);
+        }
+    }
+  list o=list(out,count);
+  return(o);
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+
+static proc LMSubset(list L,list M, list #)
+{
+  int i;
+  int j=1;
+  if (size(#)==0)
+    {
+      list position=(M[size(M)],(-1)^(size(L)));
+    }
+  else
+    {
+      list position=(M[size(M)],1);
+    }
+  for (i=1; i<=size(L); i++)
+    {
+      if (L[i]!=M[j])
+        {
+          if (L[i]!=M[i+1] or j!=i)
+            {
+              return (L[i],0);
+            }
+          else
+            {
+              if (size(#)==0)
+                {
+                  position=(M[i],(-1)^(i-1));
+                }
+              else
+                {
+                  position=(M[i],(-1)^(size(L)+1-i));
+                }
+              j=j+1;
+            }
+        }
+      j=j+1;
+
+    }
+  return (position);
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+
+static proc shortExactPieces(list L)
+{
+  /*we follow Section 3.3 in [W2]*/
+  /* we assume that L=(M_1,f_1,...,M_s,f_s) defines the complex  C=(C^i,d^i)
+     as in the procedure toVdstrictcomplex*/
+  matrix  Bnew= divdr(L[2],L[3]);
+  matrix Bold=Bnew;
+  matrix Z=divdr(Bnew,L[1]);
+  list bzh,zcb;
+  bzh=list(list(),list(),Z,unitmat(ncols(Z)),Z);
+  zcb=(Z, Bnew, L[1], unitmat(ncols(L[1])), Bnew);
+  list sep;
+  /* the list sep will be of size s such that
+     -sep[i]=(sep[i][1],sep[i][2]) is a list of two lists
+     -sep[i][1]=(B^i,f^(BZi),Z^i,f_^(ZHi),H^i) such that coker(B^i)->coker(Z^i)
+      ->coker(H^i) represents the short exact seqeuence B^i(C)->Z^i(C)->H^i(C)
+     -sep[i][2]=(Z^i,f^(ZCi),C^i,f^(CBi),B^(i+1)) such that coker(Z^i)->coker(C^i)->
+      coker(B^(i+1)) represents the short exact seqeuence Z^i(C)->C^i->B^(i+1)(C)*/
+  sep[1]=list(bzh,zcb);
+  int i;
+  list out;
+  for (i=3; i<=size(L)-2; i=i+2)
+    {
+      /*the proc bzhzcb computes representations for the short exact seqeunces */
+      out=bzhzcb(Bold, L[i-1] , L[i], L[i+1], L[i+2]);
+      sep[size(sep)+1]=out[1];
+      Bold=out[2];
+    }
+  bzh=(divdr(L[size(L)-2], L[size(L)-1]),L[size(L)-2], L[size(L)-1]);
+  bzh[4]=unitmat(ncols(L[size(L)-1]));
+  bzh[5]=transpose(concat(transpose(L[size(L)-2]),transpose(L[size(L)-1])));
+  zcb=(L[size(L)-1], unitmat(ncols(L[size(L)-1])), L[size(L)-1],list(),list());
+  sep[size(sep)+1]=list(bzh,zcb);
+  return(sep);
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+
+static proc bzhzcb (matrix Bold,matrix f0,matrix C1,matrix f1,matrix C2)
+{
+  matrix Bnew=divdr(f1,C2);
+  matrix Z= divdr(Bnew,C1);
+  matrix lift1= matrixLift(Bnew,f0);
+  matrix H=transpose(concat(transpose(lift1),transpose(Z)));
+  list bzh=(Bold, lift1, Z, unitmat(ncols(Z)),H);
+  list zcb=(Z, Bnew, C1, unitmat(ncols(C1)),Bnew);
+  list out=(list(bzh, zcb), Bnew);
+  return(out);
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+
+static proc shortExactPiecesToVdStrict(list C,int d,list #)
+{/* We transform the short exact pieces from procedure shortExactPieces to V_d-
+    strict short exact sequences. For this, we use Algorithm 3.11 and Lemma 4.2 in
+    [W2].*/
+  /* If we compute our Groebner bases in the homogenized Weyl algebra, we already
+     compute some resolutions it omit additional Groebner basis computations later
+     on.*/
+  int s =size(C);int i; int j;
+  string Syzstring="Sres";
+  intvec v=0:ncols(C[s][1][5]);
+  if (size(#)!=0)
+    {
+      for (i=1; i<=size(#); i++)
+        {
+          if (typeof(#[i])=="string")
+            {
+              Syzstring=#[i];
+            }
+          if (typeof(#[i])=="intvec")
+            {
+               v=#[i];
+            }
+        }
+    }
+  list out;
+  list forout;
+  if (Syzstring=="Vdres")
+    {
+      out[s]=list(toVdStrictSequence(C[s][1],d,v, Syzstring,s));
+    }
+  else
+    {
+      forout=toVdStrictSequence(C[s][1],d,v, Syzstring,s);
+      list resolutionofA=forout[9];
+      list resolutionofC=forout[10];
+      forout=delete(forout,10);
+      forout=delete(forout,9);
+      out[s]=list(forout);
+      for (i=1; i<=size(resolutionofC); i++)
+        {
+          out[s][1][5][i+1]=resolutionofC[i];//save the resolutions
+          out[s][1][1][i+1]=resolutionofA[i];
+        }
+    }
+  out[s][2]=list(list(out[s][1][3][1]));
+  out[s][2][2]=list(unitmat(ncols(out[s][1][3][1])));
+  out[s][2][3]=list(out[s][1][3][1]);
+  out[s][2][4]=list(list());
+  out[s][2][5]=list(list());
+  out[s][2][6]=list(out[s][1][7][1]);
+  out[s][2][7]=list(out[s][2][6][1]);
+  out[s][2][8]=list(list());
+  list resolutionofD;
+  list resolutionofF;
+  for (i=s-1; i>=2; i--)
+    {
+      C[i][2][5]=out[i+1][1][1][1];
+      forout=toVdStrictSequences(C[i],d,out[i+1][1][6][1],Syzstring,s);
+      if (Syzstring=="Sres")
+        {
+          resolutionofD=forout[3];//save the resolutions
+          resolutionofF=forout[4];
+          forout=delete(forout,4);
+          forout=delete(forout,3);
+        }
+      out[i]=forout;
+      if(Syzstring=="Sres")
+        {
+          for (j=2; j<=size(out[i+1][1][1]); j++)
+            {
+              out[i][2][5][j]=out[i+1][1][1][j];
+            }
+          for (j=1; j<=size(resolutionofD);j++)
+            {
+              out[i][1][1][j+1]=resolutionofD[j];
+              out[i][1][5][j+1]=resolutionofF[j];
+            }
+        }
+    }
+  out[1]=list(list());//initalize our list
+  C[1][2][5]=out[2][1][1][1];
+  /*Compute the last V_d-strict seqeunce*/
+  if (Syzstring=="Vdres")
+    {
+      out[1][2]=toVdStrictSequence(C[1][2],d,out[2][1][6][1],Syzstring,s,"J_Agiv");
+    }
+  else
+    {
+      forout=toVdStrictSequence(C[1][2],d,out[2][1][6][1],Syzstring,s,"J_Agiv");
+      out[1][2]=delete(forout,9);
+      list resolutionofA2=forout[9];
+      for (i=1; i<=size(out[2][1][1]); i++)
+        {
+          /*put the modules for the resolutions in the right spot*/
+          out[1][2][5][i]=out[2][1][1][i];
+        }
+      for (i=1; i<=size(resolutionofA2); i++)
+        {
+          out[1][2][1][i+1]=resolutionofA2[i];
+        }
+    }
+  out[1][1][3]=list(out[1][2][1][1]);
+  out[1][1][5]=list(out[1][2][1][1]);
+  out[1][1][4]=list(unitmat(ncols(out[1][1][3][1])));
+  out[1][1][7]=list(out[1][2][6][1]);
+  out[1][1][8]=list(out[1][2][6][1]);
+  out[1][1][1]=list(list());
+  out[1][1][2]=list(list());
+  out[1][1][6]=list(list());
+  if (Syzstring=="Sres")
+    {
+      for (i=1; i<=size(out[1][2][1]); i++)
+        {
+          out[1][1][3][i]=out[1][2][1][i];
+          out[1][1][5][i]=out[1][2][1][i];
+        }
+    }
+  list Hi;
+  for (i=1; i<=size(out); i++)
+    {
+      Hi[i]=list(out[i][1][5][1],out[i][1][8][1]);
+    }
+  list outall;
+  outall[1]=out;
+  outall[2]=Hi;
+  return(outall);
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+
+static proc toVdStrictSequence(list C,int n,intvec v,string Syzstring,int si,list #)
+{
+  /*this is the Algorithm 3.11 in [W2]*/
+  int omitemptylist;
+  int lengthofres=si+n-1;
+  int i,j,logens;
+  def B=basering;
+  matrix bi=slimgb(transpose(C[5]));
+  /* Computation of a V_d-strict Groebner basis of C[5]:
+     -if Syzstring=="Vdres" this is done using the method of weighted homogenization
+     (Prop. 3.9 [OT])
+     -else we use the homogenized Weyl algebra for Groebner basis computations
+     (Prop 9.9 [OT]),
+     in this case we already compute someresolutions (Thm. 9.10 [OT]) to omit
+     extra Groebner basis computations later on*/
+  int nr,nc;
+  intvec i1,i2;
+  if (Syzstring=="Vdres")
+    {
+      if(size(#)==0)
+        {
+          matrix J_C=VdStrictGB(C[5],n,list(v));
+        }
+      else
+        {
+          matrix J_C=C[5];//C[5] is already a V_d-strict Groebner basis
+        }
+    }
+  else
+    {
+      if (size(#)==0)
+        {
+          matrix MC=C[5];
+          def HomWeyl=makeHomogenizedWeyl(nvars(B) div 2, v);
+          setring HomWeyl;
+          matrix J_C=fetch(B,MC);
+          J_C=nHomogenize(J_C);
+          /*computation of V_d-strict resolution of C[5]->needed for proc
+            VdstrictDoubleComplexes*/
+          def ringofSyz=Sres(transpose(J_C),lengthofres);
+          setring ringofSyz;
+          matrix J_C=transpose(matrix(RES[2]));
+          J_C=subst(J_C,h,1);
+          logens=ncols(J_C)+1;
+          matrix zerom;
+          list rofC;//will contain resolution of C
+          for (i=3; i<=n+si+1; i++)
+            {
+              if (size(RES)>=i)
+                {
+                  zerom=matrix(0,nrows(matrix(RES[i])),ncols(matrix(RES[i])));
+                  if (RES[i]!=zerom)
+                    {
+                      rofC[i-2]=(matrix(RES[i]));
+
+                      if (i==3)
+                        {
+                          if (nrows(rofC[i-2])-logens+1!=nrows(J_C))
+                            {
+                              //build the resolution
+                              nr=nrows(J_C)+logens-1;
+                              nc=ncols(rofC[i-2]);
+                              rofC[i-2]=matrix(rofC[i-2],nr,nc);
+                            }
+
+                        }
+                      if (i!=3)
+                        {
+                          if (nrows(rofC[i-2])-logens+1!=nrows(rofC[i-3]))
+                            {
+                              nr=nrows(rofC[i-3])+logens-1;
+                              nc=ncols(rofC[i-2]);
+                              rofC[i-2]=matrix(rofC[i-2],nr,nc);
+                            }
+                        }
+                      i1=intvec(logens..nrows(rofC[i-2]));
+                      i2=intvec(1..ncols(rofC[i-2]));
+                      rofC[i-2]=transpose(submat(rofC[i-2],i1,i2));
+                      logens=logens+ncols(rofC[i-2]);
+                      rofC[i-2]=subst(rofC[i-2],h,1);
+                    }
+                  else
+                    {
+                      rofC[i-2]=list();
+                    }
+                }
+              else
+                {
+                  rofC[i-2]=list();
+                }
+            }
+          if(size(rofC[1])==0)
+            {
+              omitemptylist=1;
+            }
+          setring B;
+          matrix  J_C=fetch(ringofSyz,J_C);
+          if (omitemptylist!=1)
+            {
+              list rofC=fetch(ringofSyz,rofC);
+            }
+          omitemptylist=0;
+          kill HomWeyl;
+          kill ringofSyz;
+        }
+      else
+        {
+          matrix J_C=C[5];//C[5] is already a V_d-strict Groebner basis
+        }
+    }
+  /* we compute a V_d-strict Groebner basis for C[3]*/
+  matrix J_A=C[1];
+  matrix f_CB=C[4];
+  matrix f_ACB=transpose(concat(transpose(C[2]),transpose(f_CB)));
+  matrix J_AC=divdr(f_ACB,C[3]);
+  matrix P=matrixLift(J_AC * prodr(ncols(C[1]),ncols(C[5])) ,J_C);
+  list storePi;
+  matrix Pi[1][ncols(J_AC)];
+  for (i=1; i<=nrows(J_C); i++)
+    {
+      for (j=1; j<=nrows(J_AC);j++)
+        {
+          Pi=Pi+P[i,j]*submat(J_AC,j,intvec(1..ncols(J_AC)));
+        }
+      storePi[i]=Pi;
+      Pi=0;
+    }
+  /*we compute the shift vector for C[1]*/
+  intvec m_a;
+  list findMin;
+  int comMin;
+  for (i=1; i<=ncols(J_A); i++)
+    {
+      for (j=1; j<=size(storePi);j++)
+        {
+          if (storePi[j][1,i]!=0)
+            {
+              comMin=VdDeg(storePi[j]*prodr(ncols(J_A),ncols(C[5])),n,v);
+              comMin=comMin-VdDeg(storePi[j][1,i],n,intvec(0));
+              findMin[size(findMin)+1]=comMin;
+            }
+        }
+      if (size(findMin)!=0)
+        {
+          m_a[i]=Min(findMin);
+          findMin=list();
+        }
+      else
+        {
+          m_a[i]=0;
+        }
+    }
+  matrix zero[ncols(J_A)][ncols(J_C)];
+  matrix g_AB=concat(unitmat(ncols(J_A)),zero);
+  matrix g_BC= transpose(concat(transpose(zero),transpose(unitmat(ncols(J_C)))));
+  intvec m_b=m_a,v;
+  /* computation of a V_d-strict Groebner basis of C[1] (and resolution if
+     Syzstring=='Vdres') */
+  if (Syzstring=="Vdres")
+    {
+      J_A=VdStrictGB(J_A,n,m_a);
+    }
+  else
+    {
+      def HomWeyl=makeHomogenizedWeyl(nvars(B) div 2, m_a);
+      setring HomWeyl;
+      matrix J_A=fetch(B,J_A);
+      J_A=nHomogenize(J_A);
+      def ringofSyz=Sres(transpose(J_A),lengthofres);
+      setring ringofSyz;
+      matrix J_A=transpose(matrix(RES[2]));
+      matrix zerom;
+      J_A=subst(J_A,h,1);
+      logens=ncols(J_A)+1;
+      list rofA;
+      for (i=3; i<=n+si+1; i++)
+        {
+          if (size(RES)>=i)
+            {
+              zerom=matrix(0,nrows(matrix(RES[i])),ncols(matrix(RES[i])));
+              if (RES[i]!=zerom)
+                {
+                  rofA[i-2]=matrix(RES[i]);// resolution for C[1]
+                  if (i==3)
+                    {
+                      if (nrows(rofA[i-2])-logens+1!=nrows(J_A))
+                        {
+                          nr=nrows(J_A)+logens-1;
+                          nc=ncols(rofA[i-2]);
+                          rofA[i-2]=matrix(rofA[i-2],nr,nc);
+                        }
+                    }
+                  if (i!=3)
+                    {
+                      if (nrows(rofA[i-2])-logens+1!=nrows(rofA[i-3]))
+                        {
+                          nr=nrows(rofA[i-3])+logens-1;
+                          nc=ncols(rofA[i-2]);
+                          rofA[i-2]=matrix(rofA[i-2],nr,nc);
+                        }
+                    }
+                  i1=intvec(logens..nrows(rofA[i-2]));
+                  i2=intvec(1..ncols(rofA[i-2]));
+                  rofA[i-2]=transpose(submat(rofA[i-2],i1,i2));
+                  logens=logens+ncols(rofA[i-2]);
+                  rofA[i-2]=subst(rofA[i-2],h,1);
+                }
+              else
+                {
+                  rofA[i-2]=list();
+                }
+            }
+          else
+            {
+              rofA[i-2]=list();
+            }
+        }
+      if(size(rofA[1])==0)
+        {
+          omitemptylist=1;
+        }
+      setring B;
+      J_A=fetch(ringofSyz,J_A);
+      if (omitemptylist!=1)
+        {
+          list rofA=fetch(ringofSyz,rofA);
+        }
+      omitemptylist=0;
+      kill HomWeyl;
+      kill ringofSyz;
+    }
+  J_AC=transpose(storePi[1]);
+  for (i=2; i<= size(storePi); i++)
+    {
+      J_AC=concat(J_AC, transpose(storePi[i]));
+    }
+  J_AC=transpose(concat(transpose(matrix(J_A,nrows(J_A),nrows(J_AC))),J_AC));
+  list Vdstrict=(list(J_A),list(g_AB),list(J_AC),list(g_BC),list(J_C),list(m_a));
+  Vdstrict[7]=list(m_b);
+  Vdstrict[8]=list(v);
+  if(Syzstring=="Sres")
+    {
+      Vdstrict[9]=rofA;
+      if(size(#)==0)
+        {
+          Vdstrict[10]=rofC;
+        }
+    }
+  return (Vdstrict);
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+
+static proc toVdStrictSequences (list L,int d,intvec v,string Syzstring,int sizeL)
+{
+  /* this is Argorithm 3.11 combined with Lemma 4.2 in [W2] for two short exact
+     pieces.
+     We asume that we are given two sequences of the form coker(L[i][1])->
+     coker(L[i][3])->coker(L[i][5]) with differentials L[i][2] and L[i][4] such
+     that L[1][3]=L[2][1].We are going to transform them to V_d-strict sequences
+     J_D->J_A->J_F and J_A->J_B->J_C*/
+  int omitemptylist;
+  int lengthofres=sizeL+d-1;
+  int logens;
+  def B=basering;
+  matrix J_F=L[1][5];
+  matrix J_D=L[1][1];
+  matrix f_FA=L[1][4];
+  /*We find new presentations coker(J_DF) and coker(J_DFC)  for L[1][4]=L[2][1]
+     and L[2][4],resp. such that ncols(L[i][1])+ncols(L[i][5])=ncols(L[i][3]) */
+  matrix f_DFA=transpose(concat(transpose(L[1][2]),transpose(f_FA)));
+  matrix J_DF=divdr(f_DFA,L[1][3]);//coker(J_DF) is isomorphic to coker(L[2][1]);
+  matrix J_C=L[2][5];
+  matrix f_CB=L[2][4];
+  matrix f_DFCB=transpose(concat(transpose(f_DFA*L[2][2]),transpose(f_CB)));
+  matrix J_DFC=divdr(f_DFCB,L[2][3]);//coker(J_DFC) are coker(L[2][3)]) isomorphic
+  /* find a shift vector on the range of J_F such that the first sequence is
+     exact*/
+  matrix P=matrixLift(J_DFC*prodr(ncols(J_DF),ncols(L[2][5])),J_C);
+  list storePi;
+  matrix Pi[1][ncols(J_DFC)];
+  int i; int j;
+  for (i=1; i<=nrows(J_C); i++)
+    {
+      for (j=1; j<=nrows(J_DFC);j++)
+        {
+          Pi=Pi+P[i,j]*submat(J_DFC,j,intvec(1..ncols(J_DFC)));
+        }
+      storePi[i]=Pi;
+      Pi=0;
+    }
+  intvec m_a;
+  list findMin;
+  list noMin;
+  int comMin;
+  int nr,nc;
+  intvec i1,i2;
+  for (i=1; i<=ncols(J_DF); i++)
+    {
+      for (j=1; j<=size(storePi);j++)
+        {
+          if (storePi[j][1,i]!=0)
+            {
+              comMin=VdDeg(storePi[j]*prodr(ncols(J_DF),ncols(J_C)),d,v);
+              comMin=comMin-VdDeg(storePi[j][1,i],d,intvec(0));
+              findMin[size(findMin)+1]=comMin;
+            }
+        }
+      if (size(findMin)!=0)
+        {
+          m_a[i]=Min(findMin);// shift vector for L[2][1]
+          findMin=list();
+          noMin[i]=0;
+        }
+      else
+        {
+          noMin[i]=1;
+        }
+    }
+  if (size(m_a) < ncols(J_DF))
+    {
+      m_a[ncols(J_DF)]=0;
+    }
+  intvec m_f=m_a[ncols(J_D)+1..size(m_a)];
+  /* Computation of a V_d-strict Groebner basis of J_F=L[1][5]:
+     if Syzstring=="Vdres" this is done using the method of weighted homogenization
+     (Prop. 3.9 [OT])
+     else we use the homogenized Weyl algerba for Groebner basis computations
+     (Prop 9.9 [OT]), in this case we already compute resolutions
+     (Thm. 9.10 in [OT]) to omit extra Groebner basis  computations later on*/
+  if (Syzstring=="Vdres")
+    {
+      J_F=VdStrictGB(J_F,d,m_f);
+    }
+  else
+    {
+      def HomWeyl=makeHomogenizedWeyl(nvars(B) div 2, m_f);
+      setring HomWeyl;
+      matrix J_F=fetch(B,J_F);
+      J_F=nHomogenize(J_F);
+      def ringofSyz=Sres(transpose(J_F),lengthofres);
+      setring ringofSyz;
+      matrix J_F=transpose(matrix(RES[2]));
+      J_F=subst(J_F,h,1);
+      logens=ncols(J_F)+1;
+      list rofF;
+      for (i=3; i<=d+sizeL+1; i++)
+        {
+          if (size(RES)>=i)
+            {
+              if (RES[i]!=matrix(0,nrows(matrix(RES[i])),ncols(matrix(RES[i]))))
+                {
+                  rofF[i-2]=(matrix(RES[i]));// resolution for J_F
+                  if (i==3)
+                    {
+                      if (nrows(rofF[i-2])-logens+1!=nrows(J_F))
+                        {
+                          nr=nrows(J_F)+logens-1;
+                          nc=ncols(rofF[i-2]);
+                          rofF[i-2]=matrix(rofF[i-2],nr,nc);
+                        }
+                    }
+                  if (i!=3)
+                    {
+                      if (nrows(rofF[i-2])-logens+1!=nrows(rofF[i-3]))
+                        {
+                          nr=nrows(rofF[i-3])+logens-1;
+                          rofF[i-2]=matrix(rofF[i-2],nr,ncols(rofF[i-2]));
+                        }
+                    }
+                  i1=intvec(logens..nrows(rofF[i-2]));
+                  i2=intvec(1..ncols(rofF[i-2]));
+                  rofF[i-2]=transpose(submat(rofF[i-2],i1,i2));
+                  logens=logens+ncols(rofF[i-2]);
+                  rofF[i-2]=subst(rofF[i-2],h,1);
+                }
+              else
+                {
+                  rofF[i-2]=list();
+                }
+            }
+          else
+            {
+              rofF[i-2]=list();
+            }
+        }
+      if(size(rofF[1])==0)
+        {
+          omitemptylist=1;
+        }
+      setring B;
+      J_F=fetch(ringofSyz,J_F);
+      if (omitemptylist!=1)
+        {
+          list rofF=fetch(ringofSyz,rofF);
+        }
+      omitemptylist=0;
+      kill HomWeyl;
+      kill ringofSyz;
+    }
+  /*find shift vectors on the range of J_D*/
+  P=matrixLift(J_DF * prodr(ncols(L[1][1]),ncols(L[1][5])) ,J_F);
+  list storePinew;
+  matrix Pidf[1][ncols(J_DF)];
+  for (i=1; i<=nrows(J_F); i++)
+    {
+      for (j=1; j<=nrows(J_DF);j++)
+        {
+          Pidf=Pidf+P[i,j]*submat(J_DF,j,intvec(1..ncols(J_DF)));
+        }
+      storePinew[i]=Pidf;
+      Pidf=0;
+    }
+  intvec m_d;
+  for (i=1; i<=ncols(J_D); i++)
+    {
+      for (j=1; j<=size(storePinew);j++)
+        {
+          if (storePinew[j][1,i]!=0)
+            {
+              comMin=VdDeg(storePinew[j]*prodr(ncols(J_D),ncols(L[1][5])),d,m_f);
+              comMin=comMin-VdDeg(storePinew[j][1,i],d,intvec(0));
+              findMin[size(findMin)+1]=comMin;
+            }
+        }
+      if (size(findMin)!=0)
+        {
+          if (noMin[i]==0)
+            {
+              m_d[i]=Min(insert(findMin,m_a[i]));
+              m_a[i]=m_d[i];
+            }
+          else
+            {
+              m_d[i]=Min(findMin);
+              m_a[i]=m_d[i];
+            }
+        }
+      else
+        {
+          m_d[i]=m_a[i];
+        }
+      findMin=list();
+    }
+  /* compute a V_d-strict Groebner basis (and resolution of J_D if
+     Syzstring!='Vdres') for J_D*/
+  if (Syzstring=="Vdres")
+    {
+      J_D=VdStrictGB(J_D,d,m_d);
+    }
+  else
+    {
+      def HomWeyl=makeHomogenizedWeyl(nvars(B) div 2, m_d);
+      setring HomWeyl;
+      matrix J_D=fetch(B,J_D);
+      J_D=nHomogenize(J_D);
+      def ringofSyz=Sres(transpose(J_D),lengthofres);
+      setring ringofSyz;
+      matrix J_D=transpose(matrix(RES[2]));
+      J_D=subst(J_D,h,1);
+      logens=ncols(J_D)+1;
+      list rofD;
+      for (i=3; i<=d+sizeL+1; i++)
+        {
+          if (size(RES)>=i)
+            {
+              if (RES[i]!=matrix(0,nrows(matrix(RES[i])),ncols(matrix(RES[i]))))
+                {
+                  rofD[i-2]=(matrix(RES[i]));// resolution for J_D
+                  if (i==3)
+                    {
+                      if (nrows(rofD[i-2])-logens+1!=nrows(J_D))
+                        {
+                          nr=nrows(J_D)+logens-1;
+                          rofD[i-2]=matrix(rofD[i-2],nr,ncols(rofD[i-2]));
+                        }
+                    }
+                  if (i!=3)
+                    {
+                      if (nrows(rofD[i-2])-logens+1!=nrows(rofD[i-3]))
+                        {
+                          nr=nrows(rofD[i-3])+logens-1;
+                          rofD[i-2]=matrix(rofD[i-2],nr,ncols(rofD[i-2]));
+                        }
+                    }
+                  i1=intvec(logens..nrows(rofD[i-2]));
+                  i2=intvec(1..ncols(rofD[i-2]));
+                  rofD[i-2]=transpose(submat(rofD[i-2],i1,i2));
+                  logens=logens+ncols(rofD[i-2]);
+                  rofD[i-2]=subst(rofD[i-2],h,1);
+                }
+              else
+                {
+                  rofD[i-2]=list();
+                }
+            }
+          else
+            {
+              rofD[i-2]=list();
+            }
+        }
+      if(size(rofD[1])==0)
+        {
+          omitemptylist=1;
+        }
+      setring B;
+      J_D=fetch(ringofSyz,J_D);
+      if (omitemptylist!=1)
+        {
+          list rofD=fetch(ringofSyz,rofD);
+        }
+      omitemptylist=0;
+      kill HomWeyl;
+      kill ringofSyz;
+    }
+  /* compute new matrices for J_A and J_B  such that their rows form a V_d-strict
+     Groebner basis and nrows(J_A)=nrows(J_D)+nrows(J_F) and
+     nrows(J_B)=nrows(J_A)+nrows(J_C)*/
+  J_DF=transpose(storePinew[1]);
+  for (i=2; i<=nrows(J_F); i++)
+    {
+      J_DF=concat(J_DF,transpose(storePinew[i]));
+    }
+  J_DF=transpose(concat(transpose(matrix(J_D,nrows(J_D),nrows(J_DF))),J_DF));
+  J_DFC=transpose(storePi[1]);
+  for (i=2; i<=nrows(J_C); i++)
+    {
+      J_DFC=concat(J_DFC,transpose(storePi[i]));
+    }
+  J_DFC=transpose(concat(transpose(matrix(J_DF,nrows(J_DF),nrows(J_DFC))),J_DFC));
+  intvec m_b=m_a,v;
+  matrix zero[ncols(J_D)][ncols(J_F)];
+  matrix g_DA=concat(unitmat(ncols(J_D)),zero);
+  matrix g_AF=transpose(concat(transpose(zero),unitmat(ncols(J_F))));
+  matrix zero1[ncols(J_DF)][ncols(J_C)];
+  matrix g_AB=concat(unitmat(ncols(J_DF)),zero1);
+  matrix g_BC=transpose(concat(transpose(zero1),unitmat(ncols(J_C))));
+  list out;
+  out[1]=list(list(J_D),list(g_DA),list(J_DF),list(g_AF),list(J_F));
+  out[1]=out[1]+list(list(m_d),list(m_a),list(m_f));
+  out[2]=list(list(J_DF),list(g_AB),list(J_DFC),list(g_BC),list(J_C));
+  out[2]=out[2]+list(list(m_a),list(m_b),list(v));
+  if (Syzstring=="Sres")
+    {
+      out[3]=rofD;
+      out[4]=rofF;
+    }
+  return(out);
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+
+static proc VdStrictDoubleComplexes(list L,int d,string Syzstring)
+{
+  /* We compute  V_d-strict resolutions over the V_d-strict short exact pieces from
+     the procedure shortExactPiecesToVdStrict.
+     We use Algorithms 3.14 and 3.15 in [W2]*/
+  int i,k,c,j,l,totaldeg,comparedegs,SBcom,verk;
+  intvec fordegs;
+  intvec n_b,i1,i2;
+  matrix rem,forML,subm,zerom,unitm,subm2;
+  matrix J_B;
+  list store;
+  int t=size(L)+d;
+  int vd1,vd2,nr,nc;
+  def B=basering;
+  int n=nvars(B) div 2;
+  intvec v;
+  list forhW;
+  if (Syzstring=="Sres")
+    {
+    /*we already computed some of the resolutions in the procedure
+      shortExactPiecesToVdStrict*/
+      matrix Pold,Pnew,Picombined; intvec containsndeg; matrix Pinew;
+      for (k=1; k<=(size(L)+d-1); k++)
+        {
+          L[1][1][1][k+1]=list();
+          L[1][1][2][k+1]=list();
+          L[1][1][6][k+1]=list();
+        }
+      L[1][1][6][size(L)+d+1]=list();
+      matrix mem;
+      for (i=2; i<=d+size(L)+1; i++)
+        {;
+          v=0;
+          if(size(L[1][1][3][i-1])!=0)
+            {
+              if(i!=d+size(L)+1)
+                {
+                  /*horizontal differential*/
+                  L[1][1][4][i-1]=unitmat(nrows(L[1][1][3][i-1]));
+                }
+              for (j=1; j<=nrows(L[1][1][3][i-1]); j++)
+                {
+                  mem=submat(L[1][1][3][i-1],j,intvec(1..ncols(L[1][1][3][i-1])));
+                  v[j]=VdDeg(mem,d,L[1][1][7][i-1]);
+                }
+              L[1][1][7][i]=v;//new shift vector
+              L[1][1][8][i]=v;
+              L[1][2][6][i]=v;
+            }
+          else
+            {
+              if (i!=d+size(L)+1)
+                {
+                  L[1][1][4][i-1]=list();
+                }
+              L[1][1][7][i]=list();
+              L[1][1][8][i]=list();
+              L[1][2][6][i]=list();
+            }
+        }
+      if (size(L[1][1][3][d+size(L)])!=0)
+        {
+          /*horizontal differential*/
+          L[1][1][4][d+size(L)]=unitmat(nrows(L[1][1][3][d+size(L)]));
+        }
+      else
+        {
+          L[1][1][4][d+size(L)]=list();
+        }
+      for (k=1; k<size(L); k++)
+        {
+          /* We build a V_d-strict resolution for coker(L[k][2][1][1])->
+             coker(L[k][2][3][1])->coker(L[k][2][5][1]) using the resolution
+             obtained for coker(L[k][1][3][1]).
+             L[k][2][i][j] will be the jth module in the resolution of L[k][2][i][1]
+             for i=1,3,5.
+             L[k][2][i+5][j] will be the jth  shift vector in the resolution of
+             L[k][2][i][1](this holds also for the case Syzstring=="Vdres")*/
+          for (i=2; i<=d+size(L); i++)
+            {
+              v=0;
+              if (size(L[k][2][5][i-1])!=0)
+                {
+                  for (j=1; j<=nrows(L[k][2][5][i-1]); j++)
+                    {
+                      i1=intvec(1..ncols(L[k][2][5][i-1]));
+                      mem=submat(L[k][2][5][i-1],j,i1);
+                      v[j]=VdDeg(mem,d,L[k][2][8][i-1]);
+                    }
+                  /*next shift vector in th resolution of coker(L[k][2][5][1])*/
+                  L[k][2][8][i]=v;
+                }
+              else
+                {
+                  L[k][2][8][i]=list();
+                }
+              /* we build step by step a resolution for coker(L[k][2][5][1]) using
+                 the resolutions of coker(L[k][2][1][1]) and coker(L[k][2][5][1])*/
+              if (size(L[k][2][5][i])!=0)
+                {
+                  if (size(L[k][2][1][i])!=0 or size(L[k][2][1][i-1])!=0)
+                    {
+                      L[k][2][3][i]=transpose(syz(transpose(L[k][2][3][i-1])));
+                      nr= nrows(L[k][2][1][i-1]);
+                      nc=ncols(L[k][2][5][i]);
+                      Pold=matrixLift(L[k][2][3][i]*prodr(nr,nc), L[k][2][5][i]);
+                      matrix Pi[1][ncols(L[k][2][3][i])];
+                       for (l=1; l<=nrows(L[k][2][5][i]); l++)
+                        {
+                          for (j=1; j<=nrows(L[k][2][3][i]); j++)
+                            {
+                              i2=intvec(1..ncols(L[k][2][3][i]));
+                              Pi=Pi+Pold[l,j]*submat(L[k][2][3][i],j,i2);
+                            }
+                          if (l==1)
+                            {
+                              Picombined=transpose(Pi);
+                            }
+                          else
+                            {
+                              Picombined=concat(Picombined,transpose(Pi));
+                            }
+                          Pi=0;
+                        }
+                       kill Pi;
+                       Picombined=transpose(Picombined);
+                       if (size(L[k][2][1][i])!=0)
+                        {
+                          if (i==2)
+                            {
+                              containsndeg=(0:ncols(L[k][2][1][1]));
+                            }
+                          containsndeg=nDeg(L[k][2][1][i-1],containsndeg);
+                          forhW=list(L[k][2][6][i],containsndeg);
+                          def HomWeyl=makeHomogenizedWeyl(n,forhW);
+                          setring HomWeyl;
+                          list L=fetch(B,L);
+                          matrix M=L[k][2][1][i];
+                          module Mmod;
+                          list forM=nHomogenize(M,containsndeg,1);
+                          M=forM[1];
+                          totaldeg=forM[2];
+                          kill forM;
+                          matrix Maorig=fetch(B,Picombined);
+                          matrix Ma=submat(Maorig,(1..nrows(Maorig)),(1..ncols(M)));
+                          matrix mem,subm,zerom;
+                          matrix Pinew;
+                          M=transpose(M);
+                          SBcom=0;
+                          for (l=1; l<=nrows(Ma); l++)
+                            {
+                              zerom=matrix(0,1,(ncols(Maorig)-ncols(Ma)));
+                              i1=(ncols(Ma)+1..ncols(Maorig));
+                              if (submat(Maorig,l,i1)==zerom)
+                                {
+                                  for (cc=1; cc<=ncols(Ma); cc++)
+                                    {
+                                      Maorig[l,cc]=0;
+                                    }
+                                }
+                              i2=(ncols(Ma)+1..ncols(Maorig));
+                              i1=(1..ncols(Ma));
+                              if (VdDeg(submat(Maorig,l,i1),d,L[k][2][6][i])>
+                                  VdDeg(submat(Maorig,l,i2),d,L[k][2][8][i]) and
+                                  submat(Maorig,l,i1)!=matrix(0,1,ncols(Ma)))
+                                {
+                                  /*V_d-Grad is to big--> we make it smaller using
+                                    Vdnormal form computations*/
+                                  if (SBcom==0)
+                                  {
+                                    Mmod=slimgb(M);
+                                    M=Mmod;
+                                    SBcom=1;
+                                  }
+                                  //print("Reduzierung des V_d-Grades(Stelle1)");
+                                  i2=(ncols(Ma)+1..ncols(Maorig));
+                                  vd1=VdDeg(submat(Maorig,l,i2),d,L[k][2][8][i]);
+                                  mem=submat(Ma,l,(1..ncols(Ma)));
+                                  mem=nHomogenize(mem,containsndeg);
+                                  mem=h^totaldeg*mem;
+                                  mem=transpose(mem);
+                                  mem=reduce(mem,Mod);//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+                                  matrix jt=transpose(subst(mem,h,1));
+                                  setring B;
+                                  matrix jt=fetch(HomWeyl,jt);
+                                  matrix need=fetch(HomWeyl,Maorig);
+                                  need=submat(need,l,(1..ncols(need)));
+                                  i1=L[k][2][6][i];
+                                  i2=L[k][2][8][i];
+                                  jt=VdNormalForm(need,L[k][2][1][i],d,i1,i2);
+                                  setring HomWeyl;
+                                  mem=fetch(B,jt);
+                                  mem=transpose(mem);
+                                  if (l==1)
+                                    {
+                                      Pinew=mem;
+                                    }
+                                  else
+                                    {
+                                      Pinew=concat(Pinew,mem);
+                                    }
+                                  vd2=VdDeg(transpose(mem),d,L[k][2][6][i]);
+                                  if (vd2>vd1 and mem!=matrix(0,nrows(mem),ncols(mem)))
+                                    {//should not happen!!
+                                      //print("Reduzierung fehlgeschlagen!!(Stelle1)");
+                                    }
+                                }
+                              else
+                                {
+                                  if (l==1)
+                                    {
+                                      Pinew=transpose(submat(Ma,l,(1..ncols(Ma))));
+                                    }
+                                  else
+                                    {
+                                      subm=transpose(submat(Ma,l,(1..ncols(Ma))));
+                                      Pinew=concat(Pinew,subm);
+                                    }
+                                }
+                            }
+                          Pinew=subst(Pinew,h,1);
+                          Pinew=transpose(Pinew);
+                          setring B;
+                          Pinew=fetch(HomWeyl,Pinew);
+                          kill HomWeyl;
+                          L[k][2][3][i]=concat(Pinew,L[k][2][5][i]);
+                          subm=transpose(L[k][2][3][i]);
+                          subm=concat(transpose(L[k][2][1][i]),subm);
+                          L[k][2][3][i]=transpose(subm);
+                        }
+                      else
+                        {
+                          L[k][2][3][i]=Picombined;
+                        }
+                      L[k+1][1][1][i]=L[k][2][5][i];
+                      nr=nrows(L[k][2][1][i-1]);
+                      nc=ncols(L[k][2][5][i]);
+                      L[k][2][2][i]=concat(unitmat(nr),matrix(0,nr,nc));
+                      L[k][2][4][i]=prodr(nrows(L[k][2][1][i-1]),nc);
+                      v=L[k][2][6][i],L[k][2][8][i];
+                      L[k][2][7][i]=v;
+                      L[k+1][1][6][i]=L[k][2][8][i];
+                    }
+                  else
+                    {
+                      L[k][2][3][i]=L[k][2][5][i];
+                      L[k][2][2][i]=list();
+                      L[k][2][7][i]=L[k][2][8][i];
+                      L[k][2][4][i]=unitmat(nrows(L[k][2][5][i-1]));
+                      L[k+1][1][6][i]=L[k][2][8][i];
+                      L[k+1][1][1][i]=L[k][2][5][i];
+                    }
+                }
+              else
+                {
+                  if (size(L[k][2][1][i])!=0)
+                    {
+                      if (size(L[k][2][5][i-1])!=0)
+                        {
+                          nr=nrows(L[k][2][5][i-1]);
+                          L[k][2][3][i]=concat(L[k][2][1][i],matrix(0,1,nr));
+                          v=L[k][2][6][i],L[k][2][8][i];
+                          L[k][2][7][i]=v;
+                          nc=nrows(L[k][2][1][i-1]);
+                          L[k][2][2][i]=concat(unitmat(nc),matrix(0,nc,nr));
+                          L[k][2][4][i]=prodr(nrows(L[k][2][1][i-1]),nr);
+                        }
+                      else
+                        {
+                          L[k][2][3][i]=L[k][2][1][i];
+                          L[k][2][7][i]=L[k][2][6][i];
+                          L[k][2][2][i]=unitmat(nrows(L[k][2][1][i-1]));
+                          L[k][2][4][i]=list();
+                        }
+                      L[k+1][1][1][i]=L[k][2][5][i];
+                      L[k+1][1][6][i]=L[k][2][8][i];
+                    }
+                  else
+                    {
+                      L[k][2][3][i]=list();
+                      if (size(L[k][2][6][i])!=0)
+                        {
+                          if (size(L[k][2][8][i])!=0)
+                            {
+                              v=L[k][2][6][i],L[k][2][8][i];
+                              L[k][2][7][i]=v;
+                              nr=nrows(L[k][2][1][i-1]);
+                              nc=nrows(L[k][2][5][i-1]);
+                              L[k][2][2][i]=concat(unitmat(nc),matrix(0,nr,nc));
+                              L[k][2][4][i]=prodr(nr,nrows(L[k][2][5][i-1]));
+                            }
+                          else
+                            {
+                              L[k][2][7][i]=L[k][2][6][i];
+                              L[k][2][2][i]=unitmat(nrows(L[k][2][1][i-1]));
+                              L[k][2][4][i]=list();
+                            }
+                        }
+                      else
+                        {
+                          if (size(L[k][2][8][i])!=0)
+                            {
+                              L[k][2][7][i]=L[k][2][8][i];
+                              L[k][2][2][i]=list();
+                              L[k][2][4][i]=unitmat(nrows(L[k][2][5][i-1]));
+                            }
+                          else
+                            {
+                              L[k][2][7][i]=list();
+                              L[k][2][2][i]=list();
+                              L[k][2][4][i]=list();
+                            }
+                        }
+                      L[k+1][1][1][i]=L[k][2][5][i];
+                      L[k+1][1][6][i]=L[k][2][8][i];
+                    }
+                }
+            }
+          i=d+size(L)+1;
+          v=0;
+          if (size(L[k][2][5][i-1])!=0)
+            {
+              for (j=1; j<=nrows(L[k][2][5][i-1]); j++)
+                {
+                  mem=submat(L[k][2][5][i-1],j,intvec(1..ncols(L[k][2][5][i-1])));
+                  v[j]=VdDeg(mem,d,L[k][2][8][i-1]);
+                }
+              L[k][2][8][i]=v;
+              if (size(L[k][2][6][i])!=0)
+                {
+                  v=L[k][2][6][i],L[k][2][8][i];
+                  L[k][2][7][i]=v;
+                }
+              else
+                {
+                  L[k][2][7][i]=L[k][2][8][i];
+                }
+            }
+          else
+            {
+              L[k][2][8][i]=list();
+              L[k][2][7][i]=L[k][2][6][i];
+            }
+          L[k+1][1][6][i]=L[k][2][8][i];
+          /* now we build V_d-strict resolutions for the sequences
+             coker(L[k+1][1][1][1])->coker(L[k+1][1][3][1])->coker(L[k+1][1][5][i])
+             using the resolutions  for coker(L[k][2][5][1]) we just obtained
+             (works exactly the same as above)*/
+          for (i=2; i<=d+size(L); i++)
+            {
+              v=0;
+              if (size(L[k+1][1][5][i-1])!=0)
+                {
+                  for (j=1; j<=nrows(L[k+1][1][5][i-1]); j++)
+                    {
+                      i1=intvec(1..ncols(L[k+1][1][5][i-1]));
+                      mem=submat(L[k+1][1][5][i-1],j,i1);
+                      v[j]=VdDeg(mem,d,L[k+1][1][8][i-1]);
+                    }
+                  L[k+1][1][8][i]=v;
+                }
+              else
+                {
+                  L[k+1][1][8][i]=list();
+                }
+              if (size(L[k+1][1][5][i])!=0)
+                {
+                  if (size(L[k+1][1][1][i])!=0 or size(L[k+1][1][1][i-1])!=0)
+                    {
+                      L[k+1][1][3][i]=transpose(syz(transpose(L[k+1][1][3][i-1])));
+                      nr=nrows(L[k+1][1][1][i-1]);
+                      nc=ncols(L[k+1][1][5][i]);
+                      Pold=matrixLift(L[k+1][1][3][i]*prodr(nr,nc),L[k+1][1][5][i]);
+                      matrix Pi[1][ncols(L[k+1][1][3][i])];
+                      for (l=1; l<=nrows(L[k+1][1][5][i]); l++)
+                        {
+                          for (j=1; j<=nrows(L[k+1][1][3][i]); j++)
+                            {
+                              i2=intvec(1..ncols(L[k+1][1][3][i]));
+                              Pi=Pi+Pold[l,j]*submat(L[k+1][1][3][i],j,i2);
+                            }
+                          if (l==1)
+                            {
+                              Picombined=transpose(Pi);
+                            }
+                          else
+                            {
+                              Picombined=concat(Picombined,transpose(Pi));
+                            }
+                          Pi=0;
+                        }
+                      kill Pi;
+                      Picombined=transpose(Picombined);
+                      if(size(L[k+1][1][1][i])!=0)
+                        {
+                          if (i==2)
+                            {
+                              containsndeg=(0:ncols(L[k+1][1][1][i-1]));
+                            }
+                          containsndeg=nDeg(L[k+1][1][1][i-1],containsndeg);
+                          forhW=list(L[k+1][1][6][i], containsndeg);
+                          def HomWeyl=makeHomogenizedWeyl(n,forhW);
+                          setring HomWeyl;
+                          list L=fetch(B,L);
+                          matrix M=L[k+1][1][1][i];
+                          module Mmod;
+                          list forM=nHomogenize(M,containsndeg,1);
+                          M=forM[1];
+                          totaldeg=forM[2];
+                          kill forM;
+                          matrix Maorig=fetch(B,Picombined);
+                          matrix Ma=submat(Maorig,(1..nrows(Maorig)),(1..ncols(M)));
+                          Ma=nHomogenize(Ma,containsndeg);
+                          matrix mem,subm,zerom,subm2;
+                          matrix Pinew;
+                          M=transpose(M);
+                          SBcom=0;
+                          for (l=1; l<=nrows(Ma); l++)
+                            {
+                              i2=(ncols(Ma)+1..ncols(Maorig));
+                              nc=ncols(Maorig)-ncols(Ma);
+                              if (submat(Maorig,l,i2)==matrix(0,1,nc))
+                                {
+                                  for (cc=1; cc<=ncols(Ma); cc++)
+                                    {
+                                      Maorig[l,cc]=0;
+                                    }
+                                }
+                              i1=(1..ncols(Ma));
+                              i2=L[k+1][1][8][i];
+                              subm=submat(Maorig,l,i1);
+                              subm2=submat(Maorig,l,(ncols(Ma)+1..ncols(Maorig)));
+                              if (VdDeg(subm,d,L[k+1][1][6][i])>VdDeg(subm2,d,i2)
+                                  and subm!=matrix(0,1,ncols(Ma)))
+                                {
+                                  //print("Reduzierung des Vd-Grades (Stelle2)");
+                                  if (SBcom==0)
+                                    {
+                                      Mmod=slimgb(M);
+                                      M=Mmod;
+                                      SBcom=1;
+                                    }
+                                  vd1=VdDeg(subm2,d,L[k+1][1][8][i]);
+                                  mem=submat(Ma,l,(1..ncols(Ma)));
+                                  mem=nHomogenize(mem,containsndeg);
+                                  mem=h^totaldeg*mem;
+                                  mem=transpose(mem);
+                                  mem=reduce(mem,Mmod);
+                                  if (l==1)
+                                    {
+                                      Pinew=mem;
+                                    }
+                                  else
+                                    {
+                                      Pinew=concat(Pinew,mem);
+                                    }
+                                  vd2=VdDeg(transpose(mem),d,L[k+1][1][6][i]);
+                                  if (vd2>vd1 and mem!=matrix(0,nrows(mem),ncols(mem)))
+                                    {//should not happen
+                                      //print("Reduzierung fehlgeschlagen!!!!(Stelle2)");
+                                    }
+                                }
+                              else
+                                {
+                                  if (l==1)
+                                    {
+                                      Pinew=transpose(submat(Ma,l,(1..ncols(Ma))));
+                                    }
+                                  else
+                                    {
+                                      subm=transpose(submat(Ma,l,(1..ncols(Ma))));
+                                      Pinew=concat(Pinew,subm);
+                                    }
+                                }
+                            }
+                          Pinew=subst(Pinew,h,1);
+                          Pinew=transpose(Pinew);
+                          setring B;
+                          Pinew=fetch(HomWeyl,Pinew);
+                          kill HomWeyl;
+                          L[k+1][1][3][i]=concat(Pinew,L[k+1][1][5][i]);
+                          subm=transpose(L[k+1][1][1][i]);
+                          subm2=transpose(L[k+1][1][3][i]);
+                          L[k+1][1][3][i]=transpose(concat(subm,subm2));
+                        }
+                      else
+                        {
+                          L[k+1][1][3][i]=Picombined;
+                        }
+                      L[k+1][2][1][i]=L[k+1][1][3][i];
+                      nr=nrows(L[k+1][1][1][i-1]);
+                      nc=ncols(L[k+1][1][5][i]);
+                      L[k+1][1][2][i]=concat(unitmat(nr),matrix(0,nr,nc));
+                      L[k+1][1][4][i]=prodr(nr,nc);
+                      v=L[k+1][1][6][i],L[k+1][1][8][i];
+                      L[k+1][1][7][i]=v;
+                      L[k+1][2][6][i]=L[k+1][1][7][i];
+                    }
+                  else
+                    {
+                      L[k+1][1][3][i]=L[k+1][1][5][i];
+                      L[k+1][1][2][i]=list();
+                      L[k+1][1][4][i]=unitmat(nrows(L[k+1][1][5][i-1]));
+                      L[k+1][1][7][i]=L[k+1][1][8][i];
+                      L[k+1][2][6][i]=L[k+1][1][7][i];
+                      L[k+1][2][1][i]=L[k+1][1][3][i];
+                    }
+                }
+              else
+                {
+                  if (size(L[k+1][1][1][i])!=0)
+                    {
+                      if (size(L[k+1][1][5][i-1])!=0)
+                        {
+                          zerom=matrix(0,1,nrows(L[k+1][1][5][i-1]));
+                          L[k+1][1][3][i]=concat(L[k+1][1][1][i],zerom);
+                          v=L[k+1][1][6][i],L[k+1][1][8][i];
+                          L[k+1][1][7][i]=v;
+                          nr=nrows(L[k+1][1][1][i-1]);
+                          nc=nrows(L[k+1][1][5][i-1]);
+                          L[k+1][1][2][i]=concat(unitmat(nr),matrix(0,nr,nc));
+                          L[k+1][1][4][i]=prodr(nr,nc);
+                        }
+                      else
+                        {
+                          L[k+1][1][3][i]=L[k+1][1][1][i];
+                          L[k+1][1][7][i]=L[k+1][1][6][i];
+                          L[k+1][1][2][i]=unitmat(nrows(L[k+1][1][1][i-1]));
+                          L[k+1][1][4][i]=list();
+                        }
+                      L[k+1][2][1][i]=L[k+1][1][3][i];
+                      L[k+1][2][6][i]=L[k+1][1][7][i];
+                    }
+                  else
+                    {
+                      L[k+1][1][3][i]=list();
+                      if (size(L[k+1][1][6][i])!=0)
+                        {
+                          if (size(L[k+1][1][8][i])!=0)
+                            {
+                              v=L[k+1][1][6][i],L[k+1][1][8][i];
+                              L[k+1][1][7][i]=v;
+                              nr=nrows(L[k+1][1][1][i-1]);
+                              nc=nrows(L[k+1][1][5][i-1]);
+                              L[k+1][1][2][i]=concat(unitmat(nr),matrix(0,nr,nc));
+                              L[k+1][1][4][i]=prodr(nr,nrows(L[k+1][1][5][i-1]));
+                            }
+                          else
+                            {
+                              L[k+1][1][7][i]=L[k+1][1][6][i];
+                              L[k+1][1][2][i]=unitmat(nrows(L[k+1][1][1][i-1]));
+                              L[k+1][1][4][i]=list();
+                            }
+                        }
+                      else
+                        {
+                          if (size(L[k+1][1][8][i])!=0)
+                            {
+                              L[k+1][1][7][i]=L[k+1][1][8][i];
+                              L[k+1][1][2][i]=list();
+                              L[k+1][1][4][i]=unitmat(nrows(L[k+1][1][5][i-1]));
+                            }
+                          else
+                            {
+                              L[k+1][1][7][i]=list();
+                              L[k+1][1][2][i]=list();
+                              L[k+1][1][4][i]=list();
+                            }
+                        }
+
+                      L[k+1][2][1][i]=L[k+1][1][3][i];
+                      L[k+1][2][6][i]=L[k+1][1][7][i];
+                    }
+                }
+            }
+          i=size(L)+d+1;
+          v=0;
+          if (size(L[k+1][1][5][i-1])!=0)
+            {
+              for (j=1; j<=nrows(L[k+1][1][5][i-1]); j++)
+                {
+                  i1=intvec(1..ncols(L[k+1][1][5][i-1]));
+                  mem=submat(L[k+1][1][5][i-1],j,i1);
+                  v[j]=VdDeg(mem,d,L[k+1][1][8][i-1]);
+                }
+              L[k+1][1][8][i]=v;
+              if (size(L[k+1][1][6][i])!=0)
+                {
+                  v=L[k+1][1][6][i],L[k+1][1][8][i];
+                  L[k+1][1][7][i]=v;
+                }
+              else
+                {
+                  L[k+1][1][7][i]=L[k+1][1][8][i];
+                }
+            }
+          else
+            {
+              L[k+1][1][8][i]=list();
+              L[k+1][1][7][i]=L[k+1][1][8][i];
+            }
+          L[k+1][2][6][i]=L[k+1][1][7][i];
+        }
+      for (k=1; k<=(size(L)+d); k++)
+        {
+          L[size(L)][2][5][k]=list();
+          L[size(L)][2][4][k]=list();
+          L[size(L)][2][8][k]=list();
+          L[size(L)][2][3][k]=L[size(L)][2][1][k];
+          L[size(L)][2][7][k]=L[size(L)][2][6][k];
+        }
+      L[size(L)][2][7][size(L)+d+1]=L[size(L)][2][6][size(L)+d+1];
+      L[size(L)][2][8][size(L)+d+1]=list();
+      /* building the resolution of the last short exact piece*/
+      for (i=2; i<=d+size(L); i++)
+        {
+          v=0;
+          if(size(L[size(L)][2][1][i-1])!=0)
+            {
+              L[size(L)][2][2][i]=unitmat(nrows(L[size(L)][2][1][i-1]));
+            }
+          else
+            {
+              L[size(L)][2][2][i-1]=list();
+            }
+        }
+      return(L);
+    }
+  /*case Syzstring=="Vdres"*/
+  list forVd;
+  for (k=1; k<=(size(L)+d); k++)//?????
+    {
+      /* we compute a V_d-strict resolution for the first short exact piece*/
+      L[1][1][1][k+1]=list();
+      L[1][1][2][k+1]=list();
+      L[1][1][6][k+1]=list();
+      if (size(L[1][1][3][k])!=0)
+        {
+          for (i=1; i<=nrows(L[1][1][3][k]); i++)
+            {
+              rem=submat(L[1][1][3][k],i,(1..ncols(L[1][1][3][k])));
+              n_b[i]=VdDeg(rem,d,L[1][1][7][k]);
+            }
+          J_B=transpose(syz(transpose(L[1][1][3][k])));
+          L[1][1][7][k+1]=n_b;
+          L[1][1][8][k+1]=n_b;
+          L[1][1][4][k+1]=unitmat(nrows(L[1][1][3][k]));
+          if (J_B!=matrix(0,nrows(J_B),ncols(J_B)))
+            {
+              J_B=VdStrictGB(J_B,d,n_b);
+              L[1][1][3][k+1]=J_B;
+              L[1][1][5][k+1]=J_B;
+            }
+          else
+            {
+              L[1][1][3][k+1]=list();
+              L[1][1][5][k+1]=list();
+            }
+          n_b=0;
+        }
+      else
+        {
+          L[1][1][3][k+1]=list();
+          L[1][1][5][k+1]=list();
+          L[1][1][7][k+1]=list();
+          L[1][1][8][k+1]=list();
+          L[1][1][4][k+1]=list();
+        }
+      /* we compute step by step V_d-strict resolutions over
+         coker(L[i][2][1][1])->coker(L[i][2][3][1])->coker(L[i][2][1][5])
+         and coker(L[i+1][1][1][1])->coker(L[i+1][1][3][1])->coker(L[i+1][1][1][5])
+         using the already computed resolutions for coker(L[i][2][1][1])=
+         coker(L[i][1][3][1]) and coker(L[i+1][1][1][1])=coker(L[i][2][5][1])*/
+      for (i=1; i<size(L); i++)
+        {
+          forVd[1]=L[i][2][1][k];
+          forVd[2]=L[i][2][2][k];
+          forVd[3]=L[i][2][3][k];
+          forVd[4]=L[i][2][4][k];
+          forVd[5]=L[i][2][5][k];
+          forVd[6]=L[i][2][6][k];
+          forVd[7]=L[i][2][7][k];
+          forVd[8]=L[i][2][8][k];
+          store=toVdStrict2x3Complex(forVd,d,L[i][1][3][k+1],L[i][1][7][k+1]);
+          for (j=1; j<=8; j++)
+            {
+              L[i][2][j][k+1]=store[j];
+            }
+          forVd[1]=L[i+1][1][1][k];
+          forVd[2]=L[i+1][1][2][k];
+          forVd[3]=L[i+1][1][3][k];
+          forVd[4]=L[i+1][1][4][k];
+          forVd[5]=L[i+1][1][5][k];
+          forVd[6]=L[i+1][1][6][k];
+          forVd[7]=L[i+1][1][7][k];
+          forVd[8]=L[i+1][1][8][k];
+          store=toVdStrict2x3Complex(forVd,d,L[i][2][5][k+1],L[i][2][8][k+1]);
+          for (j=1; j<=8; j++)
+            {
+              L[i+1][1][j][k+1]=store[j];
+            }
+        }
+      if (size(L[size(L)][1][7][k+1])!=0)
+        {
+          L[size(L)][2][4][k+1]=list();
+          L[size(L)][2][5][k+1]=list();
+          L[size(L)][2][6][k+1]=L[size(L)][1][7][k+1];
+          L[size(L)][2][7][k+1]=L[size(L)][1][7][k+1];
+          L[size(L)][2][8][k+1]=list();
+          L[size(L)][2][2][k+1]=unitmat(size(L[size(L)][1][7][k+1]));
+          if (size(L[size(L)][1][3][k+1])!=0)
+            {
+              L[size(L)][2][1][k+1]=L[size(L)][1][3][k+1];
+              L[size(L)][2][3][k+1]=L[size(L)][1][3][k+1];
+            }
+          else
+            {
+              L[size(L)][2][1][k+1]=list();
+              L[size(L)][2][3][k+1]=list();
+            }
+        }
+      else
+        {
+          for (j=1; j<=8; j++)
+            {
+              L[size(L)][2][j][k+1]=list();
+            }
+        }
+    }
+  k=t;
+  intvec n_c;
+  intvec vn_b;
+  list N_b;
+  int n;
+  /*computation of the shift vectors*/
+  for (i=1; i<=size(L); i++)
+    {
+      for (n=1; n<=2; n++)
+        {
+          if (i==1 and n==1)
+            {
+              L[i][n][6][k+1]=list();
+            }
+          else
+            {
+              if (n==1)
+                {
+                  L[i][1][6][k+1]=L[i-1][2][8][k+1];
+                }
+              else
+                {
+                  L[i][2][6][k+1]=L[i][1][7][k+1];
+                }
+            }
+          N_b[1]=L[i][n][6][k+1];
+          if (size(L[i][n][5][k])!=0)
+            {
+              for (j=1; j<=nrows(L[i][n][5][k]); j++)
+                {
+                  rem=submat(L[i][n][5][k],j,(1..ncols(L[i][n][5][k])));
+                  n_c[j]=VdDeg(rem,d,L[i][n][8][k]);
+                }
+              L[i][n][8][k+1]=n_c;
+            }
+          else
+            {
+              L[i][n][8][k+1]=list();
+            }
+          N_b[2]=L[i][n][8][k+1];
+          n_c=0;
+          if (size(N_b[1])!=0)
+            {
+              vn_b=N_b[1];
+              if (size(N_b[2])!=0)
+                {
+                  vn_b=vn_b,N_b[2];
+                }
+              L[i][n][7][k+1]=vn_b;
+            }
+          else
+            {
+              if (size(N_b[2])!=0)
+                {
+                  L[i][n][7][k+1]=N_b[2];
+                }
+              else
+                {
+                  L[i][n][7][k+1]=list();
+                }
+            }
+        }
+    }
+  return(L);
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+
+static proc toVdStrict2x3Complex(list L,int d,list #)
+{
+  /* We build a one-step free resolution over a V_d-strict short exact piece
+     (Algorithm 3.14 in [W2]).
+     This procedure is called from the procedure VdStrictDoubleComplexes
+     if Syzstring=='Vdres'*/
+  matrix rem;
+  int i,j,cc;
+  int nr;
+  list J_A=list(list());
+  list J_B=list(list());
+  list J_C=list(list());
+  list g_AB=list(list());
+  list g_BC=list(list());
+  list n_a=list(list());
+  list n_b=list(list());
+  list n_c=list(list());
+  intvec n_b1;
+  matrix fromnf;
+  intvec i1,i2;
+  /* compute a one step V_d-strict resolution for L[5]*/
+  if (size(L[5])!=0)
+    {
+      intvec n_c1;
+      for (i=1; i<=nrows(L[5]); i++)
+        {
+          rem=submat(L[5],i,intvec(1..ncols(L[5])));
+          n_c1[i]=VdDeg(rem,d, L[8]);//new shift vector
+        }
+      n_c[1]=n_c1;
+      J_C[1]=transpose(syz(transpose(L[5])));
+      if (J_C[1]!=matrix(0,nrows(J_C[1]),ncols(J_C[1])))
+        {
+          J_C[1]=VdStrictGB(J_C[1],d,n_c1);
+          if (size(#[2])!=0)// new shift vector for the resolution of L[1]
+            {
+              n_a[1]=#[2];
+              n_b1=n_a[1],n_c[1];
+              n_b[1]=n_b1;
+              matrix zero[nrows(L[1])][nrows(L[5])];
+              g_AB=concat(unitmat(nrows(L[1])),matrix(0,nrows(L[1]),nrows(L[5])));
+              if (size(#[1])!=0)
+                {
+                  J_A=#[1];// one step V_d-strict resolution for L[1]
+                  /* use resolutions of L[1] and L[5] to build a resolution for
+                     L[3]*/
+                  J_B[1]=transpose(matrix(syz(transpose(L[3]))));
+                  matrix P=matrixLift(J_B[1]*prodr(nrows(L[1]),nrows(L[5])),J_C[1]);
+                  matrix Pi[1][ncols(J_B[1])];
+                  matrix Picombined;
+                  for (i=1; i<=nrows(J_C[1]); i++)
+                    {
+                      for (j=1; j<=nrows(J_B[1]);j++)
+                        {
+                          Pi=Pi+P[i,j]*submat(J_B[1],j,intvec(1..ncols(J_B[1])));
+                        }
+                      if (i==1)
+                        {
+                          Picombined=transpose(Pi);
+                        }
+                      else
+                        {
+                          Picombined=concat(Picombined,transpose(Pi));
+                        }
+                      Pi=0;
+                    }
+                  Picombined=transpose(Picombined);
+                  fromnf=VdNormalForm(Picombined,J_A[1],d,n_a[1],n_c[1]);
+                  i1=intvec(1..nrows(Picombined));
+                  i2=intvec((ncols(J_A[1])+1)..ncols(Picombined));
+                  Picombined=concat(fromnf,submat(Picombined,i1,i2));
+                  J_B[1]=transpose(matrix(J_A[1],nrows(J_A[1]),ncols(J_B[1])));
+                  J_B[1]=transpose(concat(J_B[1],transpose(Picombined)));
+                  g_BC=transpose(concat(transpose(zero),unitmat(nrows(L[5]))));
+                }
+              else//L[1] is already a resolution
+                {
+                  //compute a resolution for L[3]
+                  J_B=transpose(matrix(syz(transpose(L[3]))));
+                  matrix P=matrixLift(J_B[1]*prodr(nrows(L[1]),nrows(L[5])),J_C[1]);
+                  matrix Pi[1][ncols(J_B[1])];
+                  matrix Picombined;
+                  for (i=1; i<=nrows(J_C[1]); i++)
+                    {
+                      for (j=1; j<=nrows(J_B[1]);j++)
+                        {
+                          Pi=Pi+P[i,j]*submat(J_B[1],j,intvec(1..ncols(J_B[1])));
+                        }
+                      if (i==1)
+                        {
+                          Picombined=transpose(Pi);
+                        }
+                      else
+                        {
+                          Picombined=concat(Picombined,transpose(Pi));
+                        }
+                      Pi=0;
+                    }
+                  Picombined=transpose(Picombined);
+                  J_B[1]=Picombined;
+                  g_BC=transpose(concat(transpose(zero),unitmat(nrows(L[5]))));
+                }
+            }
+          else
+            {
+              n_b=n_c[1];
+              J_B[1]=J_C[1];
+              g_BC=unitmat(ncols(J_C[1]));
+            }
+        }
+      else
+        {
+          J_C=list(list());// L[5] is already a resolution
+          if (size(#[2])!=0)
+            {
+              matrix zero[nrows(L[1])][nrows(L[5])];
+              g_BC=transpose(concat(transpose(zero),unitmat(nrows(L[5]))));
+              n_a[1]=#[2];
+              n_b1=n_a[1],n_c[1];
+              n_b[1]=n_b1;
+              g_AB=concat(unitmat(nrows(L[1])),matrix(0,nrows(L[1]),nrows(L[5])));
+              if (size(#[1])!=0)
+                {
+                  J_A=#[1];
+                  /*resolution of L[3]*/
+                  nr=nrows(J_A[1]);
+                  J_B=concat(J_A[1],matrix(0,nr,nrows(L[3])-nrows(L[1])));
+                }
+            }
+          else
+            {
+              n_b=n_c[1];
+              g_BC=unitmat(ncols(L[5]));
+            }
+        }
+    }
+  else// L[5]=list();
+    {
+      if (size(#[2])!=0)
+        {
+          n_a[1]=#[2];
+          n_b=n_a[1];
+          g_AB=unitmat(size(n_b[1]));
+          if (size(#[1])!=0)
+            {
+              J_A=#[1];
+              J_B[1]=J_A[1];// resolution of L[3] equals that of L[1]
+            }
+        }
+    }
+  list out=(J_A[1],g_AB[1],J_B[1],g_BC[1],J_C[1],n_a[1],n_b[1],n_c[1]);
+  return (out);
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+
+static proc assemblingDoubleComplexes(list L)
+{
+  /* The input is the output of VdStrictDoubleComplexes, we assemble the
+     resolutions of the L[i][2][3][1] to obtain a V_d-strict free Cartan-Eilenberg
+     resolution with modules P^i_j (1<=i<=size(L), j>=0) for the seqeunce
+     coker(L[1][2][3][1])->...->coker(L[size(L)][2][3][1])*/
+  list out;
+  int i,j,k,l,oldj,newj,nr,nc;
+  for (i=1; i<=size(L); i++)
+    {
+      out[i]=list(list());
+      out[i][1][1]=ncols(L[i][2][3][1]);//rank of module P^i_0
+      if (size(L[i][2][5][1])!=0)
+        {
+          /*horizontal differential P^i_0->P^(i+1)_0*/
+          nc=ncols(L[i][2][5][1]);
+          out[i][1][4]=prodr(ncols(L[i][2][3][1])-ncols(L[i][2][5][1]),nc);
+        }
+      else
+        {
+          /*horizontal differential P^i_0->0*/
+          out[i][1][4]=matrix(0,ncols(L[i][2][3][1]),1);
+        }
+      oldj=newj;
+      for (j=1; j<=size(L[i][2][3]);j++)
+        {
+          out[i][j][2]=L[i][2][7][j];//shift vector of P^i_{j-1}
+          if (size(L[i][2][3][j])==0)
+            {
+              newj =j;
+              break;
+            }
+          out[i][j+1]=list();
+          out[i][j+1][1]=nrows(L[i][2][3][j]);//rank of the module P^i_j
+          out[i][j+1][3]=L[i][2][3][j];//vertical differential P^i_j->P^(i+1)_j
+          if (size(L[i][2][5][j])!=0)
+            {
+              //horizonal differential P^i_j->P^(i-1)_j
+              nr=nrows(L[i][2][3][j])-nrows(L[i][2][5][j]);
+              out[i][j+1][4]=(-1)^j*prodr(nr,nrows(L[i][2][5][j]));
+            }
+          else
+            {
+              /*horizontal differential P^i_j->P^(i-1)_j*/
+              out[i][j+1][4]=matrix(0,nrows(L[i][2][3][j]),1);
+            }
+          if(j==size(L[i][2][3]))
+            {
+              out[i][j+1][2]=L[i][2][7][j+1];//shift vector of P^i_j
+              newj=j+1;
+            }
+        }
+      if (i>1)
+        {
+
+          for (k=1; k<=Min(list(oldj,newj)); k++)
+            {
+              /*horizonal differential P^(i-1)_(k-1)->P^i_(k-1)*/
+              nr=nrows(out[i-1][k][4]);
+              out[i-1][k][4]=matrix(out[i-1][k][4],nr,out[i][k][1]);
+            }
+          for (k=newj+1; k<=oldj; k++)
+            {
+              /*no differential needed*/
+              out[i-1][k]=delete(out[i-1][k],4);
+            }
+        }
+    }
+  return (out);
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+
+static proc totalComplex(list L);
+{
+  /* Input is the output of assemblingDoubleComplexes.
+     We obtain a complex C^1[m^1]->...->C^(r)[m^r]  with differentials d^i and
+     shift  vectors m^i (where C^r is placed in degree size(L)-1).
+     This complex is dercribed in the list out as follows:
+     rank(C^i)=out[3*i-2]; m_i=out[3*i-1] and d^i=out[3*i]*/
+  list out;intvec rem1;intvec v; list remsize; int emp;
+  int i; int j; int c; int d; matrix M; int k; int l;
+  int n=nvars(basering) div 2;
+  list K;
+  for (i=1; i<=n+1; i++)
+    {
+      K[i]=list();
+    }
+  L=K+L;
+  for (i=1; i<=size(L); i++)
+    {
+      emp=0;
+      if (size(L[i])!=0)
+        {
+          out[3*i-2]=L[i][1][1];
+          v=L[i][1][1];
+          rem1=L[i][1][2];
+          emp=1;
+        }
+      else
+        {
+          out[3*i-2]=0;
+          v=0;
+        }
+      for (j=i+1; j<=size(L); j++)
+        {
+          if (size(L[j])>=j-i+1)
+            {
+              out[3*i-2]=out[3*i-2]+L[j][j-i+1][1];
+              if (emp==0)
+                {
+                  rem1=L[j][j-i+1][2];
+                  emp=1;
+                }
+              else
+                {
+                  rem1=rem1,L[j][j-i+1][2];
+                }
+              v[size(v)+1]=L[j][j-i+1][1];
+            }
+          else
+            {
+              v[size(v)+1]=0;
+            }
+        }
+      out[3*i-1]=rem1;
+      v[size(v)+1]=0;
+      remsize[i]=v;
+    }
+  int o1;
+  int o2;
+  for (i=1; i<=size(L)-1; i++)
+    {
+      o1=1;
+      o2=1;
+      if (size(out[3*i-2])!=0)
+        {
+          o1=out[3*i-2];
+        }
+      if (size(out[3*i+1])!=0)
+        {
+          o2=out[3*i+1];
+        }
+      M=matrix(0,o1,o2);
+      if (size(L[i])!=0)
+        {
+          if (size(L[i][1][4])!=0)
+            {
+              M=matrix(L[i][1][4],o1,o2);
+            }
+        }
+      c=remsize[i][1];
+      for (j=i+1; j<=size(L); j++)
+        {
+          if (remsize[i][j-i+1]!=0)
+            {
+              for (k=c+1; k<=c+remsize[i][j-i+1]; k++)
+                {
+                  for (l=d+1; l<=d+remsize[i+1][j-i];l++)
+                    {
+                      M[k,l]=L[j][j-i+1][3][(k-c),(l-d)];
+                    }
+                }
+              d=d+remsize[i+1][j-i];
+              if (remsize[i+1][j-i+1]!=0)
+                {
+                  for (k=c+1; k<=c+remsize[i][j-i+1]; k++)
+                    {
+                      for (l=d+1; l<=d+remsize[i+1][j-i+1];l++)
+                        {
+                          M[k,l]=L[j][j-i+1][4][k-c,l-d];
+                        }
+                    }
+                  c=c+remsize[i][j-i+1];
+                }
+            }
+          else
+            {
+              d=d+remsize[i+1][j-i];
+            }
+        }
+      out[3*i]=M;
+      d=0; c=0;
+    }
+  out[3*size(L)]=matrix(0,out[3*size(L)-2],1);
+  return (out);
+
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+//COMPUTATION OF THE BLOBAL B-FUNCTION
+////////////////////////////////////////////////////////////////////////////////////
+
+static proc globalBFun(list L,list #)
+{
+  /*We assume that the basering is the nth Weyl algebra and that L=(L[1],...,L[s]),
+    where L[i]=(L[i][1],L[i][2]) and L[i][1] is a m_i x n_i-matrix and L[i][2] an
+    intvec of size n_i.
+    We compute bounds for the minimal and maximal integer roots of the b-functions
+    of coker(L[i][1])[L[i][2]], where L[i][2] is the shift vector (cf. Def.
+    6.1.1 in [R]) by combining Algorithm 6.1.6 in [R] and the method of principal
+    intersection (cf. Remark 6.1.7 in [R] 2012).
+    This works ONLY IF ALL B-FUNCTIONS ARE NON-ZERO, but this is the case since this
+    proc is only called from the procedure deRhamCohomology and the input comes
+    originally from the procedure toVdstrictFreeComplex*/
+  if (size(#)==0)//# may contain the Syzstring
+    {
+      string Syzstring="Sres";
+    }
+  else
+    {
+      string Syzstring=#[1];
+    }
+  int i,j;
+  def W=basering;
+  int n=nvars(W) div 2;
+  list G0;
+  ideal I;
+  for (j=1; j<=size(L); j++)
+    {
+      G0[j]=list();
+      for (i=1; i<=ncols(L[j][1]); i++)
+        {
+          G0[j][i]=I;
+        }
+    }
+  list out;
+  ideal I; poly f;
+  intvec i1;
+  for (j=1; j<=size(L); j++)
+    {
+      /*if the shift vector L[j][2] is non-zero we have to compute a V_d-strict
+        Groebner basis of L[j][1] with respect to the zero shift; otherwise L[i][1]
+        is already a V_d-strict Groebner basis, because it was obtained by the
+        procedure toVdStrictFreeComplex*/
+      if (L[j][2]!=intvec(0:size(L[j][2])) or Syzstring=="noCE")
+              {
+          if (Syzstring=="Vdres")
+            {
+              L[j][1]=VdStrictGB(L[j][1],n);
+            }
+          else
+            {
+              def HomWeyl=makeHomogenizedWeyl(n);
+              setring HomWeyl;
+              list L=fetch(W,L);
+              L[j][1]=nHomogenize(L[j][1]);
+              L[j][1]=transpose(matrix(slimgb(transpose(L[j][1]))));
+              L[j][1]=subst(L[j][1],h,1);
+              setring W;
+              L=fetch(HomWeyl,L);
+              kill HomWeyl;
+            }
+        }
+      for (i=1; i<=ncols(L[j][1]); i++)
+        {
+          G0[j][i]=I;
+        }
+      for (i=1; i<=nrows(L[j][1]); i++)
+        {
+          /*computes the terms of maximal V_d-degree of the biggest non-zero
+            component of submat(L[j][1],i,(1..ncols(L[j][1])))*/
+          i1=(1..ncols(L[j][1]));
+          out=VdDeg(submat(L[j][1],i,i1),n,intvec(0:size(L[j][2])),1);
+          // f=L[j][1][i,out[2]];
+          G0[j][out[2]]=G0[j][out[2]],out[1];
+          G0[j][out[2]]=compress(G0[j][out[2]]);
+        }
+    }
+  list save;
+  int l;
+  list weights;
+  /*bFctIdealModified computes the intersection of G0[j][i] and
+    x(1)D(1)+...+x(n)D(n) using the method of principal intersection*/
+  for (j=1; j<=size(G0); j++)
+    {
+      for (i=1; i<=size(G0[j]); i++)
+        {
+          G0[j][i]=bFctIdealModified(G0[j][i]);
+        }
+      for (i=1; i<=size(G0[j]); i++)
+        {
+          weights=list();
+          if (size(G0[j][i])!=0)
+            {
+              for (l=i; l<=size(G0[j]); l++)
+                {
+                  weights[size(weights)+1]=L[j][2][l];
+                }
+              G0[j][i]=list(G0[j][i][1]+Min(weights),G0[j][i][2]+Max(weights));
+            }
+        }
+    }
+  list allmin;
+  list allmax;
+  for (j=1; j<=size(G0); j++)
+    {
+      for (i=1; i<=size(G0[j]); i++)
+        {
+          if (size(G0[j][i])!=0)
+            {
+              allmin[size(allmin)+1]=G0[j][i][1];
+              allmax[size(allmax)+1]=G0[j][i][2];
+            }
+        }
+    }
+  list minmax=list(Min(allmin),Max(allmax));
+  return(minmax);
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+
+static proc exactGlobalBFun(list L,list #)
+{
+  /*We assume that the basering is the nth Weyl algebra and that L=(L[1],...,L[s]),
+    where L[i]=(L[i][1],L[i][2]) and L[i][1] is a m_i x n_i-matrix and L[i][2] an
+    intvec of size n_i.
+    We compute bounds for the minimal and maximal integer roots of the b-functions
+    of coker(L[i][1])[L[i][2]], where L[i][2] is the shift vector (cf. Def.
+    6.1.1 in [R]) by combining Algorithm 6.1.6 in [R] and the method of principal
+    intersection (cf. Remark 6.1.7 in [R] 2012).
+    This works ONLY IF ALL B-FUNCTIONS ARE NON-ZERO, but this is the case since this
+    proc is only called from the procedure deRhamCohomology and the input comes
+    originally from the procedure toVdstrictFreeComplex*/
+  if (size(#)==0)//# may contain the Syzstring
+    {
+      string Syzstring="Sres";
+    }
+  else
+    {
+      string Syzstring=#[1];
+    }
+  int i,j,k;
+  def W=basering;
+  int n=nvars(W) div 2;
+  list G0;
+  ideal I;
+  for (j=1; j<=size(L); j++)
+    {
+      G0[j]=list();
+      for (i=1; i<=ncols(L[j][1]); i++)
+        {
+          G0[j][i]=I;
+        }
+    }
+  list out;
+  matrix M;
+  ideal I; poly f;
+  intvec i1;
+  for (j=1; j<=size(L); j++)
+    {
+      M=L[j][1];
+      /*if the shift vector L[j][2] is non-zero we have to compute a V_d-strict
+        Groebner basis of L[j][1] with respect to the zero shift; otherwise L[i][1]
+        is already a V_d-strict Groebner basis, because it was obtained by the
+        procedure toVdStrictFreeComplex*/
+      for (k=1; k<=ncols(L[j][1]); k++)
+        {
+          L[j][1]=permcol(M,1,k);
+          if (Syzstring=="Vdres")
+            {
+              L[j][1]=VdStrictGB(L[j][1],n);
+            }
+          else
+            {
+              def HomWeyl=makeHomogenizedWeyl(n);
+              setring HomWeyl;
+              list L=fetch(W,L);
+              L[j][1]=nHomogenize(L[j][1]);
+              L[j][1]=transpose(matrix(slimgb(transpose(L[j][1]))));
+              L[j][1]=subst(L[j][1],h,1);
+              setring W;
+              L=fetch(HomWeyl,L);
+              kill HomWeyl;
+            }
+          for (i=1; i<=nrows(L[j][1]); i++)
+            {
+              /*computes the terms of maximal V_d-degree of the biggest non-zero
+                component of submat(L[j][1],i,(1..ncols(L[j][1])))*/
+              i1=(1..ncols(L[j][1]));
+              out=VdDeg(submat(L[j][1],i,i1),n,intvec(0:size(L[j][2])),1);
+              if (out[2]==1)
+                {
+                  G0[j][k]=G0[j][k],out[1];
+                  G0[j][k]=compress(G0[j][k]);
+                }
+            }
+        }
+    }
+  list save;
+  int l;
+  list weights;
+  /*bFctIdealModified computes the intersection of G0[j][i] and
+    x(1)D(1)+...+x(n)D(n) using the method of principal intersection*/
+  for (j=1; j<=size(G0); j++)
+    {
+      for (i=1; i<=size(G0[j]); i++)
+        {
+          G0[j][i]=bFctIdealModified(G0[j][i]);
+        }
+      for (i=1; i<=size(G0[j]); i++)
+        {
+          if (size(G0[j][i])!=0)
+            {
+              G0[j][i]=list(G0[j][i][1]+L[j][2][i],G0[j][i][2]+L[j][2][i]);
+            }
+        }
+    }
+  list allmin;
+  list allmax;
+  for (j=1; j<=size(G0); j++)
+    {
+      for (i=1; i<=size(G0[j]); i++)
+        {
+          if (size(G0[j][i])!=0)
+            {
+              allmin[size(allmin)+1]=G0[j][i][1];
+              allmax[size(allmax)+1]=G0[j][i][2];
+            }
+        }
+    }
+  list minmax=list(Min(allmin),Max(allmax));
+  return(minmax);
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////////////////
+
+static proc exactGlobalBFunIntegration(list L,list #)
+{
+  /*We assume that the basering is the nth Weyl algebra and that L=(L[1],...,L[s]),
+    where L[i]=(L[i][1],L[i][2]) and L[i][1] is a m_i x n_i-matrix and L[i][2] an
+    intvec of size n_i.
+    We compute bounds for the minimal and maximal integer roots of the b-functions
+    of coker(L[i][1])[L[i][2]], where L[i][2] is the shift vector (cf. Def.
+    6.1.1 in [R]) by combining Algorithm 6.1.6 in [R] and the method of principal
+    intersection (cf. Remark 6.1.7 in [R] 2012).
+    This works ONLY IF ALL B-FUNCTIONS ARE NON-ZERO, but this is the case since this
+    proc is only called from the procedure deRhamCohomology and the input comes
+    originally from the procedure toVdstrictFreeComplex*/
+  string Syzstring="Sres";
+  int i,j,k;
+  def W=basering;
+  int n=nvars(W) div 2;
+//   def C=makeConverseWeyl(n);
+//   setring C;
+//   ideal Jn=x(1);
+//   for (i=2; i<=nvars(basering) div 2; i++)
+//     {
+//       Jn=Jn,var(nvars(basering) div 2 + i);
+//     }
+//   for (i=1; i<=nvars(basering) div 2; i++)
+//     {
+//       Jn=Jn,var(i);
+//     }
+//   map transtc=W,Jn;
+//   list L=transtc(L);
+  list G0;
+  ideal I;
+  for (j=1; j<=size(L); j++)
+    {
+      G0[j]=list();
+      for (i=1; i<=ncols(L[j][1]); i++)
+        {
+          G0[j][i]=I;
+        }
+    }
+  list out;
+  matrix M;
+  ideal I;
+  poly f;
+  intvec i1;
+  for (j=1; j<=size(L); j++)
+    {
+      M=L[j][1];
+      /*if the shift vector L[j][2] is non-zero we have to compute a V_d-strict
+        Groebner basis of L[j][1] with respect to the zero shift; otherwise L[i][1]
+        is already a V_d-strict Groebner basis, because it was obtained by the
+        procedure toVdStrictFreeComplex*/
+      for (k=1; k<=ncols(L[j][1]); k++)
+        {
+          L[j][1]=permcol(M,1,k);
+          def HomWeyl=makeHomogenizedWeylTilde(n);
+          setring HomWeyl;
+          list L=fetch(W,L);
+          L[j][1]=nHomogenize(L[j][1]);
+          L[j][1]=transpose(matrix(slimgb(transpose(L[j][1]))));
+          L[j][1]=subst(L[j][1],h,1);
+          setring W;
+          L=fetch(HomWeyl,L);
+          kill HomWeyl;
+          for (i=1; i<=nrows(L[j][1]); i++)
+            {
+              /*computes the terms of maximal V_d-degree of the biggest non-zero
+                component of submat(L[j][1],i,(1..ncols(L[j][1])))*/
+              i1=(1..ncols(L[j][1]));
+              out=VdDegTilde(submat(L[j][1],i,i1),n,intvec(0:size(L[j][2])),1);//hier koennte es evtl noch einen Fehler geben!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+              f=L[j][1][i,out[2]];
+              if (out[2]==1)
+                {
+                  G0[j][k]=G0[j][k],out[1];
+                  G0[j][k]=compress(G0[j][k]);
+                }
+            }
+        }
+    }
+  list save;
+  int l;
+  list weights;
+  /*bFctIdealModified computes the intersection of G0[j][i] and
+    x(1)D(1)+...+x(n)D(n) using the method of principal intersection*/
+  for (j=1; j<=size(G0); j++)
+    {
+      for (i=1; i<=size(G0[j]); i++)
+        {
+          G0[j][i]=bFctIdealModified(G0[j][i],1);
+        }
+      for (i=1; i<=size(G0[j]); i++)
+        {
+          if (size(G0[j][i])!=0)
+            {
+              G0[j][i]=list(G0[j][i][1]+L[j][2][i],G0[j][i][2]+L[j][2][i]);
+            }
+        }
+    }
+  list allmin;
+  list allmax;
+  for (j=1; j<=size(G0); j++)
+    {
+      for (i=1; i<=size(G0[j]); i++)
+        {
+          if (size(G0[j][i])!=0)
+            {
+              allmin[size(allmin)+1]=G0[j][i][1];
+              allmax[size(allmax)+1]=G0[j][i][2];
+            }
+        }
+    }
+  list minmax=list(Min(allmin),Max(allmax));
+  return(minmax);
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+
+static proc bFctIdealModified (ideal I, list #)
+{/*modified version of the procedure bfunIdeal from bfun.lib*/
+  int tilde;
+  if (size(#)!=0)
+    {
+      tilde=#[1];
+    }
+  def B= basering;
+  int n = nvars(B) div 2;
+  intvec w=(1:n);
+  //  if (tilde==0)
+  // {
+      I= initialIdealW(I,-w,w);
+      //    }
+//   else
+//     {
+//       I= initialIdealW(I,w,-w);
+//     }
+  poly s; int i;
+  if (tilde==0)
+    {
+      for (i=1; i<=n; i++)
+        {
+          s=s+x(i)*D(i);
+        }
+    }
+  else
+    {
+      for (i=1; i<=n; i++)
+        {
+          s=s-D(i)*x(i);
+        }
+    }
+  /*pIntersect computes the intersection on s and I*/
+  vector b = pIntersect(s,I);
+  list RL = ringlist(B); RL = RL[1..4];
+  RL[2] = list(safeVarName("s"));
+  RL[3] = list(list("dp",intvec(1)),list("C",intvec(0)));
+  def @S = ring(RL); setring @S;
+  vector b = imap(B,b);
+  poly bs = vec2poly(b);
+  ring r=0,s,dp;
+  poly bs=imap(@S,bs);
+  /*find minimal and maximal integer root*/
+  ideal allfac=factorize(bs,1);
+  list allfacs;
+  for (i=1; i<=ncols(allfac); i++)
+    {
+      allfacs[i]=allfac[i];
+    }
+  number testzero;
+  list zeros;
+  for (i=1; i<=size(allfacs); i++)
+    {
+      if (deg(allfacs[i])==1)
+        {
+          testzero=number(subst(allfacs[i],s,0))/leadcoef(allfacs[i]);
+          if (testzero-int(testzero)==0)
+            {
+              zeros[size(zeros)+1]=int(-1)*int(testzero);
+            }
+        }
+    }
+  if (size(zeros)!=0)
+    {
+      list minmax=(Min(zeros),Max(zeros));
+    }
+  else
+    {
+      list minmax=list();
+    }
+  setring B;
+  return(minmax);
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+
+static proc safeVarName (string s)
+{/* from the library "bfun.lib"*/
+  string S = "," + charstr(basering) + "," + varstr(basering) + ",";
+  s = "," + s + ",";
+  while (find(S,s) <> 0)
+  {
+    s[1] = "@";
+    s = "," + s;
+  }
+  s = s[2..size(s)-1];
+  return(s)
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+
+static proc globalBFunOT(list L,list #)
+{
+  /*this proc is currently not used since globalBFun computes the same output and is
+    faster, however globalBFun works only for non-zero b-functions!*/
+  /*We assume that the basering is the nth Weyl algebra and that L=(L[1],...,L[s]),
+    where L[i]=(L[i][1],L[i][2]) and L[i][1] is a m_i x n_i-matrix and L[i][2] an
+    intvec of size n_i.
+    We compute bounds for the minimal and maximal integer roots of the b-functions
+    of coker(L[i][1])[L[i][2]], where L[i][2] is the shift vector (cf. Def.
+    6.1.1 in [R]) using Algorithm 6.1.6 in [R].*/
+  if (size(#)==0)
+    {
+      string Syzstring="Sres";
+    }
+  else
+    {
+      string Syzstring=#[1];
+    }
+  int i; int j;
+  def W=basering;
+  int n=nvars(W) div 2;
+  list G0;
+  ideal I;
+  intvec i1;
+  for (j=1; j<=size(L); j++)
+    {
+      G0[j]=list();
+      for (i=1; i<=ncols(L[j][1]); i++)
+        {
+          G0[j][i]=I;
+        }
+    }
+  list out;
+  for (j=1; j<=size(L); j++)
+    {
+      if (L[j][2]!=intvec(0:size(L[j][2])))
+              {
+          if (Syzstring=="Vdres")
+            {
+              L[j][1]=VdStrictGB(L[j][1],n);
+            }
+          else
+            {
+              def HomWeyl=makeHomogenizedWeyl(n);
+              setring HomWeyl;
+              list L=fetch(W,L);
+              L[j][1]=nHomogenize(L[j][1]);
+              L[j][1]=transpose(matrix(slimgb(transpose(L[j][1]))));
+              L[j][1]=subst(L[j][1],h,1);
+              setring W;
+              L=fetch(HomWeyl,L);
+              kill HomWeyl;
+            }
+        }
+      for (i=1; i<=nrows(L[j][1]); i++)
+        {
+          i1=(1..ncols(L[j][1]));
+          out=VdDeg(submat(L[j][1],i,i1),n,intvec(0:size(L[j][2])),1);
+          G0[j][out[2]][size(G0[j][out[2]])+1]=(out[1]);
+        }
+    }
+  list Data=ringlist(W);
+  for (i=1; i<=n; i++)
+    {
+      Data[2][2*n+i]=Data[2][i];
+      Data[2][3*n+i]=Data[2][n+i];
+      Data[2][i]="v("+string(i)+")";
+      Data[2][n+i]="w("+string(i)+")";
+    }
+  Data[3][1][1]="M";
+  intvec mord=(0:16*n^2);
+  mord[1..2*n]=(1:2*n);
+  mord[6*n+1..8*n]=(1:2*n);
+  for (i=0; i<=2*n-2; i++)
+    {
+      mord[(3+i)*4*n-i]=-1;
+      mord[(2*n+2+i)*4*n-2*n-i]=-1;
+    }
+  Data[3][1][2]=mord;
+  matrix Ones=UpOneMatrix(4*n);
+  Data[5]=Ones;
+  matrix con[2*n][2*n];
+  Data[6]=transpose(concat(con,transpose(concat(con,Data[6]))));
+  def Wuv=ring(Data);
+  setring Wuv;
+  list G0=imap(W,G0); list G3; poly lterm;intvec lexp;
+  list G1,G2,LL;
+  intvec e,f;
+  int  kapp,k,l;
+  poly h;
+  ideal I;
+  for (l=1; l<=size(G0); l++)
+    {
+      G1[l]=list();  G2[l]=list(); G3[l]=list();
+      for (i=1; i<=size(G0[l]); i++)
+        {
+          for (j=1; j<=ncols(G0[l][i]);j++)
+            {
+                    G0[l][i][j]=mHom(G0[l][i][j]);
+            }
+          for (j=1; j<=nvars(Wuv) div 4; j++)
+            {
+              G0[l][i][size(G0[l][i])+1]=1-v(j)*w(j);
+            }
+          G1[l][i]=slimgb(G0[l][i]);
+          G2[l][i]=I;
+          G3[l][i]=list();
+          for (j=1; j<=ncols(G1[l][i]); j++)
+            {
+              e=leadexp(G1[l][i][j]);
+              f=e[1..2*n];
+              if (f==intvec(0:(2*n)))
+                {
+                  for (k=1; k<=n; k++)
+                    {
+                      kapp=-e[2*n+k]+e[3*n+k];
+                      if (kapp>0)
+                        {
+                          G1[l][i][j]=(x(k)^kapp)*G1[l][i][j];
+                        }
+                      if (kapp<0)
+                        {
+                          G1[l][i][j]=(D(k)^(-kapp))*G1[l][i][j];
+                        }
+                    }
+                  G2[l][i][size(G2[l][i])+1]=G1[l][i][j];
+                  G3[l][i][size(G3[l][i])+1]=list();
+                  while (G1[l][i][j]!=0)
+                    {
+                      lterm=lead(G1[l][i][j]);
+                      G1[l][i][j]=G1[l][i][j]-lterm;
+                      lexp=leadexp(lterm);
+                      lexp=lexp[2*n+1..3*n];
+                      LL=list(lexp,leadcoef(lterm));
+                      G3[l][i][size(G3[l][i])][size(G3[l][i][size(G3[l][i])])+1]=LL;
+                    }
+                }
+            }
+        }
+    }
+  ring r=0,(s(1..n)),dp;
+  ideal I;
+  map G3forr=Wuv,I;
+  list G3=G3forr(G3);
+  poly fs,gs;
+  int a;
+  list G4;
+  for (l=1; l<=size(G3); l++)
+    {
+      G4[l]=list();
+      for (i=1; i<=size(G3[l]);i++)
+        {
+          G4[l][i]=I;
+
+          for (j=1; j<=size(G3[l][i]); j++)
+            {
+              fs=0;
+              for (k=1; k<=size(G3[l][i][j]); k++)
+                {
+                  gs=1;
+                  for (a=1; a<=n; a++)
+                    {
+                      if (G3[l][i][j][k][1][a]!=0)
+                        {
+                          gs=gs*permuteVar(list(G3[l][i][j][k][1][a]),a);
+                        }
+                    }
+                  gs=gs*G3[l][i][j][k][2];
+                  fs=fs+gs;
+                }
+              G4[l][i]=G4[l][i],fs;
+            }
+        }
+    }
+  if (n==1)
+    {
+      ring rnew=0,t,dp;
+    }
+  else
+    {
+      ring rnew=0,(t,s(2..n)),dp;
+    }
+  ideal Iformap;
+  Iformap[1]=t;
+   poly forel=1;
+   for (i=2; i<=n; i++)
+     {
+       Iformap[1]=Iformap[1]-s(i);
+       Iformap[i]=s(i);
+       forel=forel*s(i);
+     }
+   map rtornew=r,Iformap;
+   list G4=rtornew(G4);
+   list getintvecs=fetch(W,L);
+   ideal J;
+   option(redSB);
+   for (l=1; l<=size(G4); l++)
+     {
+       J=1;
+       for (i=1; i<=size(G4[l]); i++)
+         {
+           G4[l][i]=eliminate(G4[l][i],forel);
+           J=intersect(J,G4[l][i]);
+         }
+       G4[l]=poly(std(J)[1]);
+     }
+   list minmax;
+   list mini=list();
+   list maxi=list();
+   list L=fetch(W,L);
+   for (i=1; i<=size(G4); i++)
+     {
+       minmax[i]=minIntRootD(G4[i],1);
+       if (size(minmax[i])!=0)
+         {
+           mini=insert(mini,minmax[i][1]+Min(L[i][2]));
+           maxi=insert(maxi,minmax[i][2]+Max(L[i][2]));
+         }
+     }
+   mini=Min(mini);
+   maxi=Max(maxi);
+   minmax=list(mini[1],maxi[1]);
+   option(none);
+  return(minmax);
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+//COMPUTATION OF THE COHOMOLOGY
+////////////////////////////////////////////////////////////////////////////////////
+
+static proc findCohomology(list L,int le)
+{
+/*computes the cohomology of the complex (D^i,d^i) given by D^i=C^L[2*i-1] and
+  d^i=L[2*i]*/
+  def R=basering;
+  ring r=0,(x),dp;
+  list L=imap(R,L);
+  list out;
+  int i, ker, im;
+  matrix S;
+  option(returnSB);
+  option(redSB);
+  for (i=2; i<=size(L); i=i+2)
+    {
+      if (L[i-1]==0)
+        {
+          out[i div 2]=0;
+          im=0;
+        }
+      else
+        {
+          S=matrix(syz(transpose(L[i])));
+          if (S!=matrix(0,nrows(S),ncols(S)))
+            {
+              ker=ncols(S);
+              out[i div 2]=ker-im;
+              im=L[i-1]-ker;
+            }
+          else
+            {
+              out[i div 2]=0;////achtung geaendert??????????????????????????????????????????????????!!!!!!!!!!!!!!!!!!!!!!!!!war mal out[i-1]
+              im=L[i-1];
+            }
+        }
+    }
+  option(none);
+  while (size(out)>le)
+    {
+      out=delete(out,1);
+    }
+  setring R;
+  return(out);
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+
+
+static proc findCohomologyDiffForms(list L,int le)
+{
+  /*computes the cohomology of the complex (D^i,d^i) given by D^i=C^L[2*i-1] and
+    d^i=L[2*i]*/
+  def R=basering;
+  list outdiffforms=list(var(1));
+  ring r=0,(x),dp;
+  list L=imap(R,L);
+  list out;
+  list outdiffforms;
+  int i, ker, im, j;
+  matrix S;
+  matrix concreteimage=matrix(0);
+  module concreteimagemod=concreteimage;
+  option(returnSB);
+  option(redSB);
+  matrix redS;
+  for (i=2; i<=size(L); i=i+2)
+    {
+      if (L[i-1]==0)
+        {
+          out[i div 2]=0;
+          im=0;
+          concreteimage=matrix(0);
+          concreteimagemod=concreteimage;
+          outdiffforms[i div 2]=list();
+        }
+      else
+        {
+          S=matrix(transpose(syz(transpose(L[i]))));
+          if (S!=matrix(0,nrows(S),ncols(S)))
+            {
+              ker=nrows(S);
+              out[i div 2]=ker-im;
+              if(out[i div 2]==0)
+                {
+                  outdiffforms[i div 2]=list();
+                }
+              else
+                {
+                  outdiffforms[i div 2]=list();
+                  if (concreteimage==matrix(0))
+                    {
+                      for (j=1; j<=nrows(S); j++)
+                        {
+                          outdiffforms[ i div 2][j]=submat(S,j,intvec(1..ncols(S)));
+                        }
+                    }
+                  else
+                    {
+                      redS=transpose(std(reduce(transpose(S),concreteimagemod)));
+                      for (j=1; j<=nrows(redS); j++)
+                        {
+                          if (submat(redS,j, intvec(1..ncols(redS)))!=matrix(0,1,ncols(redS)))
+                            {
+                              outdiffforms[i div 2][size(outdiffforms[i div 2])+1]=submat(redS,j, intvec(1..ncols(redS)));
+                            }
+                        }
+                    }
+                }
+              im=L[i-1]-ker;
+              concreteimagemod=std(transpose(L[i]));
+              concreteimage=concreteimagemod;
+              concreteimage=transpose(concreteimage);
+
+
+              //concreteimage=transpose(std(transpose(L[i])));//Achtung:hier wieder das Problem mit no Standard basis!!!!!!!!!!!!!
+            }
+          else
+            {
+              out[i div 2]=0;
+              outdiffforms[i div 2]=0;
+              im=L[i-1];
+              concreteimagemod=std(transpose(L[i]));
+              concreteimage=concreteimagemod;
+              concreteimage=transpose(concreteimage);
+              //concreteimage=transpose(std(transpose(L[i])));
+            }
+        }
+    }
+  option(none);
+  while (size(out)>le)
+    {
+      out=delete(out,1);
+      outdiffforms=delete(outdiffforms,1);
+    }
+  setring R;
+  outdiffforms=imap(r,outdiffforms);
+  list outall=list(out,outdiffforms);
+  option(noredSB);
+  option(noreturnSB);
+  return(outall);
+}
+
+
+
+////////////////////////////////////////////////////////////////////////////////////
+//AUXILIARY PROCEDURES
+////////////////////////////////////////////////////////////////////////////////////
+
+static proc findPreimage(matrix m, matrix n)
+{
+  def W=basering;//input wird in spaltenform angenommen, output in zeilenform
+  list rl=ringlist(W);
+  list rlnew=rl;
+  rlnew[3][1]=rl[3][2];
+  rlnew[3][2]=rl[3][1];
+  def Wnew=ring(rlnew);
+  setring Wnew;
+  matrix m=imap(W,m);
+  matrix n=imap(W,n);
+  def Opp=opposite(Wnew);
+  setring Opp;
+  matrix m=oppose(Wnew,m);
+  matrix n=oppose(Wnew,n);
+  option(redSB);
+  //matrix m=imap(W,m);
+  //  matrix n=imap(W,n);
+  int i;
+  matrix preim;
+  if (n!=matrix(0,nrows(n),ncols(n)))
+    {
+      matrix con=concat(m,n);
+      matrix s=syz(con);
+      for (i=1; i<=ncols(s); i++)
+        {
+          if (s[nrows(s),i]==1)
+            {
+              preim=(-1)*submat(s,1..ncols(m),i);
+              break;
+            }
+        }
+    }
+  else
+    {
+      matrix s=syz(m);
+      preim=submat(s,1..ncols(m),1);
+    }
+  option(noredSB);
+  setring Wnew;
+  matrix preim=oppose(Opp,preim);
+  setring W;
+  matrix preim=imap(Wnew,preim);
+  return(transpose(preim));
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+
+static proc divdr(matrix m,matrix n, list #)
+{
+  if (n!=matrix(0,nrows(n),ncols(n)))
+    {
+      m=transpose(m);
+      n=transpose(n);
+      matrix con=concat(m,n);
+      matrix s=syz(con);
+      s=submat(s,1..ncols(m),1..ncols(s));
+      s=transpose(compress(s));
+    }
+  else
+    {
+      matrix s=transpose(syz(transpose(m)));
+    }
+  int i;
+  matrix g;
+  matrix sm;
+  if (size(#)!=0)
+    {
+      for (i=1; i<=nrows(s); i++)
+        {
+          g=deletecol(transpose(s),i);
+          sm=transpose(submat(s,i,intvec(1..ncols(s))));
+          sm=reduce(sm,slimgb(g));
+          if (sm==matrix(0,nrows(sm),ncols(sm)))
+            {
+              s=g;
+              s=transpose(s);
+              i=i-1;
+            }
+        }
+    }
+  return(s);
+}
+////////////////////////////////////////////////////////////////////////////////////
+
+static proc matrixLift(matrix M,matrix N)
+{
+  intvec v=option(get);
+  option(none);
+  matrix l=transpose(lift(transpose(M),transpose(N)));
+  option(set,v);
+  return(l);
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+
+static proc VdStrictGB (matrix M,int d,list #)
+"USAGE:VdStrictGB(M,d[,v]); M a matrix, d an integer, v an optional intvec
+ASSUME:-basering is the nth Weyl algebra D_n @*
+       -1<=d<=n @*
+       -v (if given) is the shift vector on the range of M (in particular,
+        size(v)=ncols(M)); otherwise v is assumed to be the zero shift vector
+RETURN:matrix N; the rows of N form a V_d-strict Groebner basis with respect to v
+       for the module generated by the rows of M
+"
+{
+  if (M==matrix(0,nrows(M),ncols(M)))
+    {
+      return (matrix(0,1,ncols(M)));
+    }
+  intvec op=option(get);
+  def W =basering;
+  int ncM=ncols(M);
+  list Data=ringlist(W);
+  Data[2]=list("nhv")+Data[2];
+  Data[3][3]=Data[3][1];
+  Data[3][1]=list("dp",intvec(1));
+  matrix re[size(Data[2])][size(Data[2])]=UpOneMatrix(size(Data[2]));
+  Data[5]=re;
+  int k,l;
+  Data[6]=transpose(concat(matrix(0,1,1),transpose(concat(matrix(0,1,1),Data[6]))));
+  def Whom=ring(Data);// D_n[nhv] with the new commuative variable nhv
+  setring Whom;
+  matrix Mnew=imap(W,M);
+  intvec v;
+  if (size(#)!=0)
+    {
+      v=#[1];
+    }
+  if (size(v) < ncM)
+    {
+      v=v,0:(ncM-size(v));
+    }
+  Mnew=homogenize(Mnew, d, v);//homogenization of M with respect to the new variable
+  Mnew=transpose(Mnew);
+  Mnew=slimgb(Mnew);// computes a Groebner basis of the homogenzition of M
+  Mnew=subst(Mnew,nhv,1);// substitution of 1 gives V_d-strict Groebner basis  of M
+  Mnew=compress(Mnew);
+  Mnew=transpose(Mnew);
+  setring W;
+  M=imap(Whom,Mnew);
+  option(set,op);
+  return(M);
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+
+static proc VdNormalForm(matrix F,matrix M,int d,intvec v,list #)
+"USAGE:VdNormalForm(F,M,d,v[,w]); F and M matrices, d int, v intvec, w an optional
+       intvec
+ASSUME:-basering is the nth Weyl algebra D_n @*
+       -F a n_1 x n_2-matrix and M a m_1 x m_2-matrix with m_2<=n_2 @*
+       -d is an integer between 1 and n @*
+       -v is a shift vector for D_n^(m_2) and hence size(v)=m_2 @*
+       -w is a shift vector for D_n^(m_1-m_2) and hence size(v)=m_1-m_2 @*
+RETURN:a n_1 x n_2-matrix N such that:@*
+       -If no optional intvec w is given:(N[i,1],..,N[i,m_2]) is a V_d-strict normal
+        form of (F[i,1],...,F[i,m_2]) with respect to a V_d-strict Groebner basis of
+        the rows of M and the shift vector v
+       -If w is given:(N[i,1],..,N[i,m_2]) is chosen such that
+        Vddeg((N[i,1],...,N[i,m_2])[v])<=Vddeg((F[i,m_2+1],...,F[i,m_1])[v]);
+       -N[i,j]=F[i,j] for j>m_2
+"
+{
+  int SBcom;
+  def W =basering;
+  int c=ncols(M);
+  matrix keepF=F;
+  if (size(#)!=0)
+    {
+      intvec w=#[1];
+    }
+  F=submat(F,intvec(1..nrows(F)),intvec(1..c));
+  list Data=ringlist(W);
+  Data[2]=list("nhv")+Data[2];
+  Data[3][3]=Data[3][1];
+  Data[3][1]=list("dp",intvec(1));
+  matrix re[size(Data[2])][size(Data[2])]=UpOneMatrix(size(Data[2]));
+  Data[5]=re;
+  int k,l,nr,nc;
+  matrix rep[size(Data[2])][size(Data[2])];
+  for (l=size(Data[2])-1;l>=1; l--)
+    {
+      for (k=l-1; k>=1;k--)
+        {
+          rep[k+1,l+1]=Data[6][k,l];
+        }
+    }
+  Data[6]=rep;
+  def Whom=ring(Data);//new ring D_n[nvh] this new commuative variable nhv
+  setring Whom;
+  matrix Mnew=imap(W,M);
+  list forMnew=homogenize(Mnew,d,v,1);//commputes homogenization of M;
+  Mnew=forMnew[1];
+  int rightexp=forMnew[2];
+  matrix Fnew=imap(W,F);
+  matrix keepF=imap(W,keepF);
+  matrix Fb;
+  int cc;
+  intvec i1,i2;
+  matrix zeromat,subm1,subm2,zeromat2;
+  for (l=1; l<=nrows(Fnew); l++)
+    {
+      if (size(#)!=0)
+        {
+          subm2=submat(keepF,l,((ncols(Fnew)+1)..ncols(keepF)));
+          zeromat2=matrix(0,1,ncols(subm2));
+          if (submat(keepF,l,((ncols(Fnew)+1)..ncols(keepF)))==zeromat2)
+            {
+              for (cc=1; cc<=ncols(Fnew); c++)
+                {
+                  Fnew[l,cc]=0;
+                }
+            }
+          i1=intvec(1..ncols(Fnew));
+          subm1=submat(Fnew,l,i1);
+          subm2=submat(keepF,l,(ncols(Fnew)+1)..ncols(keepF));
+          zeromat=matrix(0,1,ncols(Fnew));
+          if (VdDegnhv(subm1,d,v)>VdDegnhv(subm2,d,w)
+              and submat(Fnew,l,intvec(1..ncols(Fnew)))!=zeromat)
+            {
+              //print("Reduzierung des V_d-Grades noetig");
+              /*We need to reduce the V_d-degree. First we homogenize the
+                lth row of Fnew*/
+              Fb=homogenize(subm1,d,v)*(nhv^rightexp);
+              if (SBcom==0)
+                {
+                  /*computes a V_d-strict standard basis*/
+                  Mnew=slimgb(transpose(Mnew));//
+                  SBcom=1;
+                }
+              /*computes a V_d-strict normal form for FB*/
+              Fb=transpose(reduce(transpose(Fb),Mnew));
+              if (VdDegnhv(Fb,d,v)> VdDegnhv(subm2,d,w)
+                  and Fb!=matrix(0,nrows(Fb),ncols(Fb)))//should not happen
+                {
+                  //print("Reduzierung fehlgeschlagen!!!!!!!!!!!!!!!!");
+                }
+            }
+          else
+            {
+              /*condition on V_ddeg already satisfied -> no normal form
+                computation is needed*/
+              Fb=submat(Fnew,l,intvec(1..ncols(Fnew)));
+            }
+        }
+      else
+        {
+          Fb=homogenize(submat(Fnew,l,intvec(1..ncols(Fnew))),d,v);
+          if (SBcom==0)
+            {
+              Mnew=slimgb(transpose(Mnew));// computes a V_d-strict Groebner basis
+              SBcom=1;
+            }
+          Fb=transpose(reduce(transpose(Fb),Mnew));//normal form
+        }
+      for (k=1; k<=ncols(Fnew);k++)
+        {
+          Fnew[l,k]=Fb[1,k];
+        }
+    }
+  Fnew=subst(Fnew,nhv,1);//obtain normal form in D_n
+  setring W;
+  F=imap(Whom,Fnew);
+  return(F);
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+
+static proc homogenize (matrix M,int d,intvec v,list #)
+{
+  /* we compute the F[v]-homogenization of each row of M (cf. Def. 3.4 in [OT])*/
+  if (M==matrix(0,nrows(M),ncols(M)))
+    {
+      return(M);
+    }
+  int i,l,s, kmin, nhvexp;
+  poly f;
+  intvec vnm;
+  list findmin,maxnhv,rempoly,remk,rem1,rem2;
+  int n=(nvars(basering)-1) div 2;
+  for (int k=1; k<=nrows(M); k++)
+    {
+      for (l=1; l<=ncols (M); l++)
+        {
+          f=M[k,l];
+          s=size(f);
+          for (i=1; i<=s; i++)
+            {
+              vnm=leadexp(f);
+              vnm=vnm[n+2..n+d+1]-vnm[2..d+1];
+              kmin=sum(vnm)+v[l];
+              rem1[size(rem1)+1]=lead(f);
+              rem2[size(rem2)+1]=kmin;
+              findmin=insert(findmin,kmin);
+              f=f-lead(f);
+            }
+          rempoly[l]=rem1;
+          remk[l]=rem2;
+          rem1=list();
+          rem2=list();
+        }
+      if (size(findmin)!=0)
+        {
+          kmin=Min(findmin);
+        }
+      for (l=1; l<=ncols(M); l++)
+        {
+          if (M[k,l]!=0)
+            {
+              M[k,l]=0;
+              for (i=1; i<=size(rempoly[l]);i++)
+                {
+                  nhvexp=remk[l][i]-kmin;
+                  M[k,l]=M[k,l]+nhv^(nhvexp)*rempoly[l][i];
+                  maxnhv[size(maxnhv)+1]=nhvexp;
+                }
+            }
+        }
+      rempoly=list();
+      remk=list();
+      findmin=list();
+    }
+  maxnhv=Max(maxnhv);
+  nhvexp=maxnhv[1];
+  if (size(#)!=0)
+    {
+      return(list(M,nhvexp));//only needed for normal form computations
+    }
+  return(M);
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+
+static proc soldr (matrix M,matrix N)
+{
+  /* We compute a ncols(M) x nrows(M)-matrix C such that
+     C[i,1]M_1+...+C[i,nrows(M)]M_(nrows(M))= e_i mod im(N),
+     where e_i is the ith basis element on the range of M, M_j denotes the jth row
+     of M and im(N) is generated by the rows of N */
+  int n=nrows(M);
+  int q=ncols(M);
+  matrix S=concat(transpose(M),transpose(N));
+  def W=basering;
+  list Data=ringlist(W);
+  list Save=Data[3];
+  Data[3]=list(list("c",0),list("dp",intvec(1..nvars(W))));
+  def Wmod=ring(Data);
+  setring Wmod;
+  matrix Smod=imap(W,S);
+  matrix E[q][1];
+  matrix Smod2,Smodnew;
+  option(returnSB);
+  int i,j;
+  for (i=1;i<=q;i++)
+    {
+      E[i,1]=1;
+      Smod2=concat(E,Smod);
+      Smod2=syz(Smod2);
+      E[i,1]=0;
+      for (j=1;j<=ncols(Smod2);j++)
+        {
+          if (Smod2[1,j]==1)
+            {
+              Smodnew=concat(Smodnew,(-1)*(submat(Smod2,intvec(2..n+1),j)));
+              break;
+            }
+        }
+    }
+  Smodnew=transpose(submat(Smodnew,intvec(1..n),intvec(2..q+1)));
+  setring W;
+  matrix  Snew=imap(Wmod,Smodnew);
+  option(none);
+  return (Snew);
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+
+static proc prodr (int k,int l)
+{
+  if (k==0)
+    {
+      matrix P=unitmat(l);
+      return (P);
+    }
+  matrix O[l][k];
+  matrix P=transpose(concat(O,unitmat(l)));
+  return (P);
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+
+static proc VdDeg(matrix M,int d,intvec v,list #)
+{
+  /* We assume that the basering it the nth Weyl algebra and that  M is a 1 x r-
+     matrix.
+     We compute the V_d-deg of M with respect to the shift vector v,
+     i.e V_ddeg(M)=max (V_ddeg(M_i)+v[i]), where k=V_ddeg(M_i) if k is the minimal
+     integer, such that M_i can be expressed as a sum of operators
+     x(1)^(a_1)*...*x(n)^(a_n)*D(1)^(b_1)*...*D(n)^(b_n) with
+     a_1+..+a_d+k>=b_1+..+b_d*/
+  int i, j, etoint;
+  int n=nvars(basering) div 2;
+  intvec  e;
+  list findmax;
+  int c=ncols(M);
+  poly l;
+  list positionpoly,positionVd;
+  for (i=1; i<=c; i++)
+    {
+      positionpoly[i]=list();
+      positionVd[i]=list();
+      while (M[1,i]!=0)
+        {
+          l=lead(M[1,i]);
+          positionpoly[i][size(positionpoly[i])+1]=l;
+          e=leadexp(l);
+          e=-e[1..d]+e[n+1..n+d];
+          e=sum(e)+v[i];
+          etoint=e[1];
+          positionVd[i][size(positionVd[i])+1]=etoint;
+          findmax[size(findmax)+1]=etoint;
+          M[1,i]=M[1,i]-l;
+        }
+    }
+  if (size(findmax)!=0)
+    {
+      int maxVd=Max(findmax);
+      if (size(#)==0)
+        {
+          return (maxVd);
+        }
+    }
+  else // M is 0-modul
+    {
+      return(int(0));
+    }
+  l=0;
+  for (i=c; i>=1; i--)
+    {
+      for (j=1; j<=size(positionVd[i]); j++)
+        {
+          if (positionVd[i][j]==maxVd)
+            {
+              l=l+positionpoly[i][j];
+            }
+        }
+      if (l!=0)
+        {
+          /*returns the largest component that has maximal V_d-degree
+            and its terms of maximal V_d-deg (needed for globalBFun)*/
+          return (list(l,i));
+        }
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+
+static proc VdDegTilde(matrix M,int d,intvec v,list #)
+{
+  /* We assume that the basering it the nth Weyl algebra and that  M is a 1 x r-
+     matrix.
+     We compute the \tilde(V_d)-deg of M with respect to the shift vector v,
+     i.e \tilde(V_d)deg(M)=max (\tilde(V_d)deg(M_i)+v[i]), where k=\tilde(V_d)deg(M_i) if k is the minimal
+     integer, such that M_i can be expressed as a sum of operators
+     x(1)^(a_1)*...*x(n)^(a_n)*D(1)^(b_1)*...*D(n)^(b_n) with
+     a_1+..+a_d<=b_1+..+b_d+k*/
+  int i, j, etoint;
+  int n=nvars(basering) div 2;
+  intvec  e;
+  list findmax;
+  int c=ncols(M);
+  poly l;
+  list positionpoly,positionVd;
+  for (i=1; i<=c; i++)
+    {
+      positionpoly[i]=list();
+      positionVd[i]=list();
+      while (M[1,i]!=0)
+        {
+          l=lead(M[1,i]);
+          positionpoly[i][size(positionpoly[i])+1]=l;
+          e=leadexp(l);
+          e=e[1..d]-e[n+1..n+d];
+          e=sum(e)+v[i];
+          etoint=e[1];
+          positionVd[i][size(positionVd[i])+1]=etoint;
+          findmax[size(findmax)+1]=etoint;
+          M[1,i]=M[1,i]-l;
+        }
+    }
+  if (size(findmax)!=0)
+    {
+      int maxVd=Max(findmax);
+      if (size(#)==0)
+        {
+          return (maxVd);
+        }
+    }
+  else // M is 0-modul
+    {
+      return(int(0));
+    }
+  l=0;
+  for (i=c; i>=1; i--)
+    {
+      for (j=1; j<=size(positionVd[i]); j++)
+        {
+          if (positionVd[i][j]==maxVd)
+            {
+              l=l+positionpoly[i][j];
+            }
+        }
+      if (l!=0)
+        {
+          /*returns the largest component that has maximal V_d-degree
+            and its terms of maximal V_d-deg (needed for globalBFun)*/
+          return (list(l,i));
+        }
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+
+static proc VdDegnhv(matrix M,int d,intvec v,list #)
+{
+  /* As the procedure VdDeg, but the basering is the nth Weyl algebra
+     with a commutative variable nhv*/
+  int i,j,etoint;
+  int n=nvars(basering) div 2;
+  intvec  e;
+  int etoint;
+  list findmax;
+  int c=ncols(M);
+  poly l;
+  list positionpoly;
+  list positionVd;
+  for (i=1; i<=c; i++)
+    {
+      positionpoly[i]=list();
+      positionVd[i]=list();
+      while (M[1,i]!=0)
+        {
+          l=lead(M[1,i]);
+          positionpoly[i][size(positionpoly[i])+1]=l;
+          e=leadexp(l);
+          e=-e[2..d+1]+e[n+2..n+d+1];
+          e=sum(e)+v[i];
+          etoint=e[1];
+          positionVd[i][size(positionVd[i])+1]=etoint;
+          findmax[size(findmax)+1]=etoint;
+          M[1,i]=M[1,i]-l;
+        }
+    }
+  if (size(findmax)!=0)
+    {
+      int maxVd=Max(findmax);
+      if (size(#)==0)
+        {
+          return (maxVd);
+        }
+    }
+  else // M is 0-modul
+    {
+      return(int(0));
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+
+static proc deletecol(matrix M,int l)
+{
+  if (ncols(M)==1)
+    {
+      return(M);
+    }
+  int s=ncols(M);
+  if (l==1)
+    {
+      M=submat(M,(1..nrows(M)),(2..ncols(M)));
+      return(M);
+    }
+  if (l==s)
+    {
+      M=submat(M,(1..nrows(M)),(1..(ncols(M)-1)));
+      return(M);
+    }
+  intvec v=(1..(l-1)),((l+1)..s);
+  M=submat(M,(1..nrows(M)),v);
+  return(M);
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+
+static proc mHom(poly f)
+{/*for globalBFunOT*/
+  poly g;
+  poly l;
+  poly add;
+  intvec e;
+  list minint;
+  list remf;
+  int i;
+  int j;
+  int n=nvars(basering) div 4;
+  if (f==0)
+    {
+      return(f);
+    }
+  while (f!=0)
+    {
+      l=lead(f);
+      e=leadexp(l);
+      remf[size(remf)+1]=list();
+      remf[size(remf)][1]=l;
+      for (i=1; i<=n; i++)
+        {
+          remf[size(remf)][i+1]=-e[2*n+i]+e[3*n+i];
+          if (size(minint)<i)
+            {
+              minint[i]=list();
+            }
+          minint[i][size(minint[i])+1]=-e[2*n+i]+e[3*n+i];
+        }
+      f=f-l;
+    }
+  for (i=1; i<=n; i++)
+    {
+      minint[i]=Min(minint[i]);
+    }
+  for (i=1; i<=size(remf); i++)
+    {
+      add=remf[i][1];
+      for (j=1; j<=n; j++)
+        {
+          add=v(j)^(remf[i][j+1]-minint[j])*add;
+        }
+      g=g+add;
+    }
+  return (g);
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+
+static proc permuteVar(list L,int n)
+{/*for globalBFunOT*/
+  if (typeof(L[1])=="intvec")
+    {
+      intvec v=L[1];
+    }
+  else
+    {
+      intvec v=(1:L[1]),(0:L[1]);
+    }
+  int i;int k; int indi=0;
+  int j;
+  int s=size(v);
+  poly e;
+  intvec fore;
+  for (i=2; i<=size(v); i=i+2)
+    {
+
+      if (v[i]!=0)
+        {
+           j=i+1;
+          while (v[j]!=0)
+            {
+              j=j+1;
+            }
+          v[i]=0;
+          v[j]=1;
+          fore=0;
+          indi=0;
+          for (k=1; k<=size(v); k++)
+            {
+              if (k!=i and k!=j)
+                {
+                  if (indi==0)
+                    {
+                      indi=1;
+                      fore[1]=v[k];
+                    }
+                  else
+                    {
+                      fore[size(fore)+1]=v[k];
+                    }
+                }
+            }
+          e=e-(j-i)*permutevar(list(fore),n);
+        }
+    }
+  e=e+s(n)^(size(v) div 2);
+  return (e);
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+
+static proc makeHomogenizedWeyl(int n,list #)
+{
+  /*modified version of the procedure makeWeyl() from the library nctools.lib*/
+  /*Creates the nth homogenized Weyl algebra with variables x(1),..,x(n),D(1),..,
+    D(n) and homogenization variable h, i.e. it holds x(i)*D(i)=D(i)*x(1)+h^2.
+    If # contains on intvec v, we assign weight v[i] to the ith module component.*/
+  if (n<1)
+    {
+      print*("Incorrect input");
+      return();
+    }
+  if (n ==1)
+    {
+      ring @rr = 0,(x(1),D(1),h),dp;
+    }
+  else
+    {
+      ring @rr = 0,(x(1..n),D(1..n),h),dp;
+    }
+  setring @rr;
+  int i=0;
+  if (size(#)==0)
+    {
+      def @rrr = homogenizedWeyl(i);
+    }
+  else
+    {
+      def @rrr=homogenizedWeyl(i,#);
+    }
+  return(@rrr);
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+
+static proc makeHomogenizedWeylTilde(int n,list #)
+{
+  /*modified version of the procedure makeWeyl() from the library nctools.lib*/
+  /*Creates the nth homogenized Weyl algebra with variables x(1),..,x(n),D(1),..,
+    D(n) and homogenization variable h, i.e. it holds x(i)*D(i)=D(i)*x(1)+h^2.
+    If # contains on intvec v, we assign weight v[i] to the ith module component.*/
+  if (n<1)
+    {
+      print*("Incorrect input");
+      return();
+    }
+  if (n ==1)
+    {
+      ring @rr = 0,(x(1),D(1),h),dp;
+    }
+  else
+    {
+      ring @rr = 0,(x(1..n),D(1..n),h),dp;
+    }
+  setring @rr;
+  int i=1;
+  if (size(#)==0)
+    {
+      def @rrr = homogenizedWeyl(i);
+    }
+  else
+    {
+      def @rrr=homogenizedWeyl(i,#);
+    }
+  return(@rrr);
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+
+static proc makeConverseHomogenizedWeylTilde(int n,list #)
+{
+  /*modified version of the procedure makeWeyl() from the library nctools.lib*/
+  /*Creates the nth homogenized Weyl algebra with variables x(1),..,x(n),D(1),..,
+    D(n) and homogenization variable h, i.e. it holds x(i)*D(i)=D(i)*x(1)+h^2.
+    If # contains on intvec v, we assign weight v[i] to the ith module component.*/
+  if (n<1)
+    {
+      print*("Incorrect input");
+      return();
+    }
+  if (n ==1)
+    {
+      ring @rr = 0,(D(1),x(1),h),dp;
+    }
+  else
+    {
+      ring @rr = 0,(D(1..n),x(1..n),h),dp;
+    }
+  setring @rr;
+  int i=1;
+  if (size(#)==0)
+    {
+      def @rrr = converseHomogenizedWeyl(i);
+    }
+  else
+    {
+      def @rrr=converseHomogenizedWeyl(i,#);
+    }
+  return(@rrr);
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+
+static proc converseHomogenizedWeyl (int tilde,list #)
+{
+  /*modified version of the procedure Weyl() from the library nctools.lib*/
+  /*Creates a homogenized Weyl algebra structure on the basering. We assume
+    n=nvars(basering) is odd. The first (n-1)/2 variables will be treated as the
+    x(i), the next (n-1)/2 as the corresponding differentials D(i) and the last as
+    the homogenization variable h, i.e. it holds x(i)*D(i)=D(i)*x(1)+h^2.
+    If # contains on intvec v, we assign weight v[i] to the ith module component.*/
+  string rname=nameof(basering);
+  if ( rname == "basering") // i.e. no ring has been set yet
+    {
+      "You have to call the procedure from the ring";
+      return();
+    }
+  int nv = nvars(basering);
+  int N = (nv-1) div 2;
+  if (((nv-1) % 2) != 0)
+    {
+      "Cannot create homogenized Weyl structure for an even number of generators";
+      return();
+    }
+  matrix @D[nv][nv];
+  int i;
+  for ( i=1; i<=N; i++ )
+    {
+      @D[i,N+i]=-h^2;
+    }
+  def @R = nc_algebra(1, at D);
+  setring @R;
+  list RL=ringlist(@R);
+  intvec v;
+  /*we need this ordering for Groebner basis computations*/
+  if (tilde==0)
+    {
+      for (i=1; i<=N; i++)
+        {
+          v[i]=-1;
+          v[N+i]=1;
+        }
+    }
+  else
+    {
+      for (i=1; i<=N; i++)
+        {
+          v[i]=1;
+          v[N+i]=-1;
+        }
+    }
+  v[nv]=0;
+  /* we assign weights to module components*/
+  if (size(#)!=0)
+    {
+      if (typeof(#[1])=="intvec")
+        {
+          intvec m=#[1];
+          for (i=1; i<=size(m); i++)
+            {
+              v[size(v)+1]=m[i];//assigns weight m[i] to the ith module component
+            }
+          RL[3]=insert(RL[3],list("am",v));
+        }
+      else
+        {
+          RL[3]=insert(RL[3],list("a",v));
+        }
+    }
+  else
+    {
+      RL[3]=insert(RL[3],list("a",v));
+    }
+  intvec w=(1:nv);
+  if (size(#)>=2)
+    {
+      if (typeof(#[2])=="intvec")
+        {
+          intvec n=#[2];
+          for (i=1; i<=size(n); i++)
+            {
+              w[size(w)+1]=n[i];
+            }
+          RL[3]=insert(RL[3],list("am",w));
+        }
+      else
+        {
+          RL[3]=insert(RL[3],list("a",w));
+        }
+    }
+  else
+    {
+      RL[3]=insert(RL[3],list("a",w));
+    }
+  /*this ordering is needed for globalBFun and globalBFunOT*/
+  list saveord=RL[3][3];
+  RL[3][3]=RL[3][4];
+  RL[3][4]=saveord;
+  intvec notforh=(1:(size(RL[3][4][2])-1));
+  RL[3][4][2]=notforh;
+  RL[3][5]=list("dp",1);
+  def @@R=ring(RL);
+  return(@@R);
+}
+///////////////////////////////////////////////////////////////////////////////////
+
+static proc homogenizedWeyl (int tilde,list #)
+{
+  /*modified version of the procedure Weyl() from the library nctools.lib*/
+  /*Creates a homogenized Weyl algebra structure on the basering. We assume
+    n=nvars(basering) is odd. The first (n-1)/2 variables will be treated as the
+    x(i), the next (n-1)/2 as the corresponding differentials D(i) and the last as
+    the homogenization variable h, i.e. it holds x(i)*D(i)=D(i)*x(1)+h^2.
+    If # contains on intvec v, we assign weight v[i] to the ith module component.*/
+  string rname=nameof(basering);
+  if ( rname == "basering") // i.e. no ring has been set yet
+    {
+      "You have to call the procedure from the ring";
+      return();
+    }
+  int nv = nvars(basering);
+  int N = (nv-1) div 2;
+  if (((nv-1) % 2) != 0)
+    {
+      "Cannot create homogenized Weyl structure for an even number of generators";
+      return();
+    }
+  matrix @D[nv][nv];
+  int i;
+  for ( i=1; i<=N; i++ )
+    {
+      @D[i,N+i]=h^2;
+    }
+  def @R = nc_algebra(1, at D);
+  setring @R;
+  list RL=ringlist(@R);
+  intvec v;
+  /*we need this ordering for Groebner basis computations*/
+  if (tilde==0)
+    {
+      for (i=1; i<=N; i++)
+        {
+          v[i]=-1;
+          v[N+i]=1;
+        }
+    }
+  else
+    {
+      for (i=1; i<=N; i++)
+        {
+          v[i]=1;
+          v[N+i]=-1;
+        }
+    }
+  v[nv]=0;
+  /* we assign weights to module components*/
+  if (size(#)!=0)
+    {
+      if (typeof(#[1])=="intvec")
+        {
+          intvec m=#[1];
+          for (i=1; i<=size(m); i++)
+            {
+              v[size(v)+1]=m[i];//assigns weight m[i] to the ith module component
+            }
+          RL[3]=insert(RL[3],list("am",v));
+        }
+      else
+        {
+          RL[3]=insert(RL[3],list("a",v));
+        }
+    }
+  else
+    {
+      RL[3]=insert(RL[3],list("a",v));
+    }
+  intvec w=(1:nv);
+  if (size(#)>=2)
+    {
+      if (typeof(#[2])=="intvec")
+        {
+          intvec n=#[2];
+          for (i=1; i<=size(n); i++)
+            {
+              w[size(w)+1]=n[i];
+            }
+          RL[3]=insert(RL[3],list("am",w));
+        }
+      else
+        {
+          RL[3]=insert(RL[3],list("a",w));
+        }
+    }
+  else
+    {
+      RL[3]=insert(RL[3],list("a",w));
+    }
+  /*this ordering is needed for globalBFun and globalBFunOT*/
+  list saveord=RL[3][3];
+  RL[3][3]=RL[3][4];
+  RL[3][4]=saveord;
+  intvec notforh=(1:(size(RL[3][4][2])-1));
+  RL[3][4][2]=notforh;
+  RL[3][5]=list("dp",1);
+  def @@R=ring(RL);
+  return(@@R);
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+
+static proc nHomogenize (matrix M,list #)
+{
+  /* # may contain an intvec v, if no intvec is given, we assume that v=(0:ncols(M))
+     We compute the h[v]-homogenization of the rows of M as in Definition 9.2 [OT]*/
+  int l; poly f; int s; int i; intvec vnm;int kmin; list findmax;
+  int n=(nvars(basering)-1) div 2;
+  list rempoly;
+  list remk;
+  list rem1;
+  list rem2;
+  list maxhexp;
+  int hexp;
+  intvec v=(0:ncols(M));
+  if (size(#)!=0)
+    {
+      if (typeof(#[1])=="intvec")
+        {
+          v=#[1];
+        }
+    }
+  if (size(v)<ncols(M))
+    {
+      for (i=size(v)+1; i<=ncols(M); i++)
+        {
+          v[i]=0;
+        }
+    }
+  for (int k=1; k<=nrows(M); k++)
+    {
+      for (l=1; l<=ncols (M); l++)
+        {
+          f=M[k,l];
+          s=size(f);
+          for (i=1; i<=s; i++)
+            {
+              vnm=leadexp(f);
+              kmin=sum(vnm)+v[l];
+              rem1[size(rem1)+1]=lead(f);
+              rem2[size(rem2)+1]=kmin;
+              findmax=insert(findmax,kmin);
+              f=f-lead(f);
+            }
+          rempoly[l]=rem1;
+          remk[l]=rem2;
+          rem1=list();
+          rem2=list();
+        }
+      if (size(findmax)!=0)
+        {
+          kmin=Max(findmax);
+        }
+      else
+        {
+          kmin=0;
+        }
+      for (l=1; l<=ncols(M); l++)
+        {
+          if (M[k,l]!=0)
+            {
+              M[k,l]=0;
+              for (i=1; i<=size(rempoly[l]);i++)
+                {
+                  hexp=kmin-remk[l][i];
+                  maxhexp[size(maxhexp)+1]=hexp;
+                  M[k,l]=M[k,l]+h^hexp*rempoly[l][i];
+                }
+            }
+        }
+      rempoly=list();
+      remk=list();
+      findmax=list();
+    }
+  if (size(maxhexp)!=0)
+    {
+      maxhexp=Max(maxhexp);
+      hexp=maxhexp[1];
+    }
+  else
+    {
+      hexp=0;
+    }
+  if (size(#)>1)
+    {
+      list forreturn=M,hexp;
+
+      return(forreturn);
+    }
+  return(M);
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+
+static proc nDeg (matrix M,intvec m)
+{/*we compute an intvec n such that n[i]=max(deg(M[i,j])+m[j]|M[i,j]!=0) (where deg
+   stands for the total degree) if (M[i,j]!=0 for some j) and n[i]=0 else*/
+  int i; int j;
+  intvec n;
+  list L;
+  for (i=1; i<=nrows(M); i++)
+    {
+      L=list();
+      for (j=1; j<=ncols(M); j++)
+        {
+          if (M[i,j]!=0)
+            {
+              L=insert(L,deg(M[i,j])+m[j]);
+            }
+        }
+      if (size(L)==0)
+        {
+          n[i]=0;
+        }
+      else
+        {
+          n[i]=Max(L);
+        }
+    }
+  return(n);
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+
+static proc minIntRootD(list L,list #)
+"USAGE:minIntRootD(L [,M]); L list, M optinonal list
+ASSUME:L a list of univariate polynomials with rational coefficients @*
+       the variable of the polynomial is s if size(#)==0 (needed for proc
+       MVComplex) and t else (needed for globalBFun)
+RETURN:-if size(#)==0: int i, where i is an integer root of one of the polynomials
+        and it is minimal with respect to that property@*
+       -if size(#)!=0: list L=(i,j), where i is as above and j is an integer root
+        of one of the polynomials and is maximal with respect to that property (if
+        an integer root exists) or L=list() else
+"
+{
+  def B=basering;
+  if (size(#)==0)
+    {
+      ring rnew=0,s,dp;
+    }
+  else
+    {
+      ring rnew=0,t,dp;
+    }
+  list L=imap(B,L);
+
+  int i;
+  int j;
+  number isint;
+  list possmin;
+  ideal allfac;
+  list allfacs;
+  for (i=1; i<=size(L); i++)
+    {
+      allfac=factorize(L[i],1);
+      for (j=1; j<=ncols(allfac); j++)
+        {
+          allfacs[j]=allfac[j];
+        }
+      for (j=1; j<=size(allfacs); j++)
+        {
+          if (deg(allfacs[j])==1)
+            {
+              isint=number(subst(allfacs[j],var(1),0)/leadcoef(allfacs[j]));
+              if (isint-int(isint)==0)
+                {
+                  possmin[size(possmin)+1]=int(isint);
+                }
+            }
+        }
+      allfacs=list();
+    }
+  int zerolist;
+  if (size(possmin)!=0)
+    {
+      int miniroot=(-1)*Max(possmin);
+      int maxiroot=(-1)*Min(possmin);
+    }
+  else
+    {
+      zerolist=1;
+    }
+  setring B;
+  if (size(#)==0)
+    {
+      return(miniroot);
+    }
+  else
+    {
+      if (zerolist==0)
+        {
+          return(list(miniroot,maxiroot));
+        }
+      else
+        {
+          return(list());
+        }
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+
+proc converseWeyl(list #)
+{
+  string rname=nameof(basering);
+  int @chr = 0;
+  int nv = nvars(basering);
+  int N = nv div 2;
+  matrix @D[nv][nv];
+  int i;
+  for ( i=1; i<=N; i++)
+  {
+      @D[i,N+i]=-1;
+  }
+  def @R = nc_algebra(1, at D);
+  return(@R);
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+
+proc makeConverseWeyl(int n, list #)
+{
+  if (n==1)
+    {
+      ring @rr = 0,(D(1),x(1)),dp;
+    }
+  else
+  {
+    ring @rr = 0,(D(1..n),x(1..n)),dp;
+  }
+  setring @rr;
+  def @rrr = converseWeyl();
+  return(@rrr);
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+
+proc makeOmega(int n)
+{
+  def R=basering;
+  int i;
+  int j,k,l;
+  list omega;
+  omega[1]=list(list(list()));
+  omega[2]=list();
+  for (i=1; i<=n; i++)
+    {
+      omega[2][i]=list(i);
+    }
+  for (i=2; i<=n; i++)
+    {
+      omega[i+1]=list();
+      for (j=1; j<=size(omega[i]); j++)
+        {
+          if (omega[i][j][size(omega[i][j])]<n)
+            {
+              for (k=omega[i][j][size(omega[i][j])]+1; k<=n; k++)
+                {
+                  omega[i+1][size(omega[i+1])+1]=omega[i][j];
+                  omega[i+1][size(omega[i+1])][size( omega[i+1][size(omega[i+1])])+1]=k;
+                }
+            }
+        }
+    }
+  list omegamaps;
+  matrix om;
+  list lms;
+  omegamaps[1]=matrix(0,n,1);
+  for (i=1; i<=n; i++)
+    {
+      omegamaps[1][i,1]=var(n+i);
+    }
+  for (i=2; i<=n; i++)
+    {
+      om=matrix(0,size(omega[i+1]),size(omega[i]));
+      for (k=1; k<=size(omega[i]); k++)
+        {
+          for (l=1; l<=size(omega[i+1]); l++)
+            {
+              lms=LMSubset(omega[i][k],omega[i+1][l],1);
+              om[l,k]=lms[2]*var(n+lms[1]);
+            }
+        }
+      omegamaps[i]=om;
+    }
+  omegamaps[n+1]=matrix(0,1,1);
+  list allomega;
+  for (i=1; i<=n+1; i++)
+    {
+      allomega[2*i]=omega[n+2-i];
+      allomega[2*i-1]=omegamaps[n+2-i];
+    }
+  return(allomega);
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+
+static proc makeDoubleComplex(list L, list M, list Q, list G)
+{
+  list doublecomplex;
+  int i,j,k,l;
+  int s1;
+  int s2;
+  int c;
+  int d;
+  list gens=list();
+  for (i=1; i<=size(L) div 2; i++)
+    {
+      doublecomplex[i]=list();
+      for (j=1; j<=size(M) div 2; j++)
+        {
+          doublecomplex[i][j]=list();
+          doublecomplex[i][j]=list(M[2*j]+list(L[2*i-1]));
+          gens=list();
+          doublecomplex[i][j][6]=G[i];
+          if (size(Q[i])!=0)
+            {
+              doublecomplex[i][j][4]=tensor(unitmat(size(M[2*j])),Q[i]);
+              for (c=1; c<=size(M[2*j]); c++)
+                {
+                  for (d=1; d<=ncols(Q[i]); d++)
+                    {
+                      gens[size(gens)+1]=list(M[2*j][c],d);
+                    }
+                }
+              doublecomplex[i][j][5]=gens;
+            }
+          else
+            {
+              doublecomplex[i][j][4]=list();
+              doublecomplex[i][j][5]=list();
+            }
+          if (size(Q[i])!=0)
+            {
+              if (Q[i]==matrix(0,nrows(Q[i]),ncols(Q[i])))
+                {
+                  doublecomplex[i][j][4]=list();
+                }
+            }
+          if (j!=1)
+            {
+              s1=(size(doublecomplex[i][j-1][1])-1)*doublecomplex[i][j-1][1][size(doublecomplex[i][j-1][1])];
+              s2=(size(doublecomplex[i][j][1])-1)*doublecomplex[i][j][1][size(doublecomplex[i][j][1])];
+              if (s1==0 or s2==0)
+                {
+                  doublecomplex[i][j-1][3]=list();
+                }
+              else
+                {
+                  doublecomplex[i][j-1][3]=tensor(M[2*j-1],unitmat(L[2*i-1]));
+                }
+
+            }
+          if (j==size(M) div 2)
+            {
+              doublecomplex[i][j][3]=list();
+            }
+          if (i!=1)
+            {
+              s1=(size(doublecomplex[i-1][j][1])-1)*doublecomplex[i-1][j][1][size(doublecomplex[i-1][j][1])];
+              s2=(size(doublecomplex[i][j][1])-1)*doublecomplex[i][j][1][size(doublecomplex[i][j][1])];
+              if (s1==0 or s2==0)
+                {
+                  doublecomplex[i-1][j][2]=list();
+                }
+              else
+                {
+                  doublecomplex[i-1][j][2]=tensor(unitmat(size(M[2*j])),L[2*(i-1)]);
+                }
+            }
+          if (i==size(L) div 2)
+            {
+              doublecomplex[i][j][2]=list();
+            }
+        }
+    }
+  return(doublecomplex);
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+
+static proc transferDiffforms(matrix m, list L)
+{
+  int i;
+  list transfered;
+  if (size(L[4])==0)
+    {
+      return(list());
+    }
+  if (size(L[5])==0)
+    {
+      return(list());
+    }
+  m=m*L[4];
+  list transferedm=list();
+  int si=L[5][size(L[5])][2];//Anzahl der direkten Summanden in \oplus R_F_I
+  matrix fortrans=matrix(0,1,si);
+  list omegagen=list();
+  list save=list();
+  int t;
+  int c;
+  int j;
+  list converteddiff;
+  vector w;
+  poly p=1;
+  for (i=1; i<=ncols(m); i++)
+    {
+      if (m[1,i]!=0)
+        {
+          if (size(omegagen)==0)
+            {
+              omegagen=L[5][i][1];
+              fortrans[1,L[5][i][2]]= fortrans[1,L[5][i][2]]+m[1,i];
+            }
+          else
+            {
+              t=0;
+              for (j=1; j<=size(omegagen);j++)
+                {
+                  if (size(omegagen[j])!=0)
+                    {
+                      if (omegagen[j]!=L[5][i][1][j])
+                        {
+                          t=1;
+                        }
+                    }
+                }
+              if (t==0)
+                {
+                  fortrans[1,L[5][i][2]]= fortrans[1,L[5][i][2]]+m[1,i];
+                }
+              else
+                {
+                  converteddiff=list();
+                  for (j=1; j<=ncols(fortrans); j++)
+                    {
+                      if (fortrans[1,j]!=0)
+                        {
+                          w=[p,L[6][j]];
+                          converteddiff[j]=dmodActionRat(fortrans[1,j],w);
+                        }
+                      else
+                        {
+                          converteddiff[j]=0;
+                        }
+
+                    }
+                  save[size(save)+1]=list(converteddiff,omegagen);
+                  omegagen=L[5][i][1];
+                  fortrans=matrix(0,1,si);
+                  fortrans[1,L[5][i][2]]= fortrans[1,L[5][i][2]]+m[1,i];
+                }
+            }
+        }
+    }
+  if (fortrans==matrix(0,1,si))
+    {
+      return(list());
+    }
+  converteddiff=list();
+  for (j=1; j<=ncols(fortrans); j++)
+    {
+      if (fortrans[1,j]!=0)
+        {
+          w=[p,L[6][j]];
+          converteddiff[j]=dmodActionRat(fortrans[1,j],w);
+        }
+      else
+        {
+          converteddiff[j]=0;
+        }
+    }
+  save[size(save)+1]=list(converteddiff,omegagen);
+  return(save);
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////
+/*
+////////////////////////////////////////////////////////////////////////////////////
+FURTHER EXAMPLES FOR TESTING THE PROCEDURES
+////////////////////////////////////////////////////////////////////////////////////
+LIB "derham.lib";
+
+//----------------------------------------
+//EXAMPLE 1
+//----------------------------------------
+ring r=0,(x,y),dp;
+poly f=y2-x3-2x+3;
+list L=deRhamCohomology(f);
+L;
+kill r;
+
+//----------------------------------------
+//EXAMPLE 2
+//----------------------------------------
+ring r=0,(x,y),dp;
+poly f=y2-x3-x;
+list L=deRhamCohomology(f);
+L;
+kill r;
+
+//----------------------------------------
+//EXAMPLE 3
+//----------------------------------------
+ring r=0,(x,y),dp;
+list C=list(x2-1,(x+1)*y,y*(y2+2x+1));
+list L=deRhamCohomology(C);
+L;
+kill r;
+
+//----------------------------------------
+//EXAMPLE 4
+//----------------------------------------
+ring r=0,(x,y,z),dp;
+list C=list(x*(x-1),y,z*(z-1),z*(x-1));
+list L=deRhamCohomology(C);
+L;
+kill r;
+
+//----------------------------------------
+//EXAMPLE 5
+//----------------------------------------
+ring r=0,(x,y,z),dp;
+list C=list(x*y,y*z);
+list L=deRhamCohomology(C,"Vdres");
+L;
+kill r;
+
+//----------------------------------------
+//EXAMPLE 6
+//----------------------------------------
+ring r=0,(x,y,z,u),dp;
+list C=list(x,y,z,u);
+list L=deRhamCohomology(C);
+L;
+kill r;
+
+//----------------------------------------
+//EXAMPLE 7
+//----------------------------------------
+ring r=0,(x,y,z),dp;
+poly f=x3+y3+z3;
+list L=deRhamCohomology(f);
+L;
+kill r;
+
+//----------------------------------------
+//EXAMPLE 8
+//----------------------------------------
+ring r=0,(x,y,z),dp;
+poly f=x2+y2+z2;
+list L=deRhamCohomology(f,"Vdres");
+L;
+kill r;
+
+//----------------------------------------
+//EXAMPLE 9
+//----------------------------------------
+ring r=0,(x,y,z,u),dp;
+list C=list(x2+y2+z2,u);
+list L=deRhamCohomology(C);
+L;
+kill r;
+
+
+//----------------------------------------
+//EXAMPLE 10
+//----------------------------------------
+ring r=0,(x,y,z),dp;
+list C=list((x*(y-1),y2-1));
+list L=deRhamCohomology(C);
+L;
+kill r;
+
+
+*/
diff --git a/Singular/LIB/divisors.lib b/Singular/LIB/divisors.lib
new file mode 100644
index 0000000..bcefb1d
--- /dev/null
+++ b/Singular/LIB/divisors.lib
@@ -0,0 +1,863 @@
+///////////////////////////////////////////////////////////////////////////////
+version="version divisors.lib 4.0.0.0 Jun_2013 "; // $Id: 8ead4ff58e5d5010e160616239d1c259e7f041d3 $
+category = "Commutative Algebra";
+info="
+LIBRARY:  divisors.lib      Divisors and P-Divisors
+
+AUTHORS:  Janko Boehm       boehm at mathematik.uni-kl.de
+@*        Lars Kastner      kastner at math.fu-berlin.de
+@*        Benjamin Lorenz   blorenz at math.uni-frankfurt.de
+@*        Hans Schoenemann  hannes at mathematik.uni-kl.de
+@*        Yue Ren           ren at mathematik.uni-kl.de
+
+OVERVIEW:
+
+We implement a class divisor on an algebraic variety and methods
+for computing with them. Divisors are represented by tuples of ideals
+defining the positive and the negative part. In particular, we implement the group
+structure on divisors, computing global sections and testing linear
+equivalence.
+
+In addition to this we provide a class formaldivisor which implements
+integer formal sums of divisors (not necessarily prime). A formal divisor
+can be evaluated to a divisor, and a divisor can be decomposed into
+a formal sum.
+
+Finally we provide a class pdivisor which implements polyhedral formal sums of
+divisors (P-divisors) where the coefficients are assumed to be polyhedra with fixed tail cone.
+There is a function to evaluate a P-divisor on a vector in the dual of the tail cone. The
+result will be a formal divisor.
+
+
+REFERENCES:
+
+For the class divisor we closely follow Macaulay2's tutorial on divisors.
+
+
+PROCEDURES:
+
+makeDivisor(ideal,ideal)                        create a divisor
+divisorplus(divisor,divisor)                    add two divisors
+multdivisor(int,divisor)                        multiply a divisor by an interger
+negativedivisor(divisor)                        compute the negative of the divisor
+normalForm(divisor)                             normal form of a divisor
+isEqualDivisor(divisor,divisor)                 test whether two divisors are equal
+globalSections(divisor)                         compute the global sections of a divisor
+degreeDivisor(divisor)                          degree of a divisor
+linearlyEquivalent(divisor,divisor)             test whether two divisors a linearly equivalent
+effective(divisor)                              compute an effective divisor
+                                                linearly equivalent to a divisor
+
+makeFormalDivisor(list)                         make a formal integer sum of divisors
+evaluateFormalDivisor(formaldivisor)            evalutate a formal sum of divisors to a divisor
+formaldivisorplus(formaldivisor,formaldivisor)  add two formal divisors
+negativeformaldivisor(formaldivisor)            compute the negative of the formal divisor
+multformaldivisor(int,formaldivisor)            multiply a formal divisor by an interger
+degreeFormalDivisor(formaldivisor)              degree of a formal divisor
+
+makePDivisor(List)                              make a formal polyhedral sum of divisors
+evaluatePDivisor(pdivisor,intvec)               evaluate a polyhedral divisor
+                                                to an integer formal divisor
+pdivisorplus(pdivisor,pdivisor)                 add two polyhedral divisors
+
+
+";
+
+
+////////////////////////////////////////////////////////////////////////////////
+
+LIB "primdec.lib";
+
+proc mod_init()
+{
+LIB"gfanlib.so";
+newstruct("divisor","ideal den,ideal num");
+newstruct("formaldivisor","list summands");
+newstruct("pdivisor","list summands, cone tail");
+
+system("install","divisor","print",divisor_print,1);
+system("install","divisor","+",divisorplus,2);
+system("install","divisor","*",proxymultdivisor,2);
+system("install","formaldivisor","print",formaldivisor_print,1);
+system("install","formaldivisor","+",formaldivisorplus,2);
+system("install","formaldivisor","*",proxymultformaldivisor,2);
+system("install","pdivisor","+",pdivisorplus,2);
+}
+
+
+
+proc divisor_print(divisor D)
+"USAGE:  divisor_print(D); D; D = divisor. @*
+ASSUME:  D is a divisor.
+RETURN:  Will print D.
+KEYWORDS: divisors
+EXAMPLE: example divisor_print; shows an example
+"
+{
+"("+string(D.num)+") - ("+string(D.den)+")";
+}
+example
+{ "EXAMPLE:";
+ring r=31991,(x,y,z),dp;
+ideal I = y^2*z - x*(x-z)*(x+3*z);
+qring Q = std(I);
+divisor P = makeDivisor(ideal(x,z),ideal(1));
+P;
+}
+
+
+proc formaldivisor_print(formaldivisor fD)
+"USAGE:  formaldivisor_print(D); D; D = formaldivisor. @*
+ASSUME:  fD is a formaldivisor.
+RETURN:  Will print fD.
+KEYWORDS: divisors
+EXAMPLE: example formaldivisor_print; shows an example
+"
+{
+  int i; string s; list L=fD.summands;
+  list cd; int c; divisor d;
+  string linebreak =
+"
+";
+  for (i=1; i<=size(L); i++)
+  {
+    cd=L[i]; c=cd[1]; d=cd[2];
+    if (i>1 && c>=0) { s = s + "+"; }
+    s = s + string(c)+"*( ("+string(d.num)+") - ("+string(d.den)+") )";
+    if (i!=size(L)) { s = s + linebreak; }
+  }
+  s;
+}
+example
+{ "EXAMPLE:";
+ring r=31991,(x,y,z),dp;
+ideal I = y^2*z - x*(x-z)*(x+3*z);
+qring Q = std(I);
+divisor P = makeDivisor(ideal(x,z),ideal(1));
+P;
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+// divisors as numerator and denomiator ideals
+
+proc makeDivisor(ideal I, ideal J)
+"USAGE:  makeDivisor(I ,J); I = ideal, J = ideal. @*
+ASSUME:  I and J are ideals in a qring Q of a smooth irreducible variety X
+         such that any ideal in Q satisfies the S2 condition.
+RETURN:  a divisor on X
+THEORY:  The procedure will eliminate all components which are not of codimension 1.
+         The S2 condition requires that every proper nonzero principal ideal
+         has pure codimension 1.
+KEYWORDS: divisors
+EXAMPLE: example makeDivisor; shows an example
+"
+{
+divisor C;
+C.num = purify1(I);
+C.den = purify1(J);
+return(C);
+}
+
+example
+{ "EXAMPLE:";
+ring r=31991,(x,y,z),dp;
+ideal I = y^2*z - x*(x-z)*(x+3*z);
+qring Q = std(I);
+divisor P = makeDivisor(ideal(x,z),ideal(1));
+}
+
+
+proc divisorplus(divisor A, divisor B)
+"USAGE:  divisorplus(A ,B); A + B; A = divisor, B = divisor. @*
+ASSUME:  A and B are divisors on X.
+RETURN:  a divisor on X
+THEORY:  The procedure will compute the product of the numerator
+         and denominator ideals, respectively.
+KEYWORDS: divisors
+EXAMPLE: example divisorplus; shows an example
+"
+{
+return(makeDivisor(interred(A.num*B.num),interred(A.den*B.den)));
+}
+example
+{ "EXAMPLE:";
+ring r=31991,(x,y,z),dp;
+ideal I = y^2*z - x*(x-z)*(x+3*z);
+qring Q = std(I);
+divisor A = makeDivisor(ideal(x,z),ideal(1));
+divisor B = makeDivisor(ideal(x,y),ideal(1));
+A+B;
+}
+
+
+proc multdivisor(int n, divisor A)
+"USAGE:  multdivisor(n ,A); A*n; n = integer, A = divisor.@*
+ASSUME:  n is an integer and A is a divisor on X.
+RETURN:  a divisor on X
+THEORY:  The procedure will compute the n-th power of the numerator
+         and denominator ideals, respectively.
+KEYWORDS: divisors
+EXAMPLE: example multdivisor; shows an example
+"
+{
+if (n<0) {return(multdivisor(-n,negativedivisor(A)));}
+return(makeDivisor(interred((A.num)^n),interred((A.den)^n)));
+}
+example
+{ "EXAMPLE:";
+ring r=31991,(x,y,z),dp;
+ideal I = y^2*z - x*(x-z)*(x+3*z);
+qring Q = std(I);
+divisor A = makeDivisor(ideal(x,z),ideal(1));
+A;
+divisor D = multdivisor(4,A);
+D;
+A*4;
+}
+
+
+/***
+ * For operator overloading, which needs a procedure which takes a divisor first
+ * and integer second.
+ **/
+proc proxymultdivisor(divisor A, int n)
+{
+if (n<0) {return(multdivisor(-n,negativedivisor(A)));}
+return(makeDivisor(interred((A.num)^n),interred((A.den)^n)));
+}
+
+
+proc negativedivisor(divisor A)
+"USAGE:  negativedivisor(A); A*(-1); A = divisor.@*
+ASSUME:  A is a divisor on X.
+RETURN:  a divisor on X
+THEORY:  The procedure will interchange the numerator and denominator ideals.
+KEYWORDS: divisors
+EXAMPLE: example negativedivisor; shows an example
+"
+{
+divisor B;
+B.num=A.den;
+B.den=A.num;
+return(B);
+}
+example
+{ "EXAMPLE:";
+ring r=31991,(x,y,z),dp;
+ideal I = y^2*z - x*(x-z)*(x+3*z);
+qring Q = std(I);
+divisor A = makeDivisor(ideal(x,z),ideal(1));
+A;
+divisor D = negativedivisor(A);
+D;
+}
+
+
+proc normalForm(divisor A)
+"USAGE:  normalForm(A); A = divisor.@*
+ASSUME:  A is a divisor on X.
+RETURN:  different representative of the same divisor on X
+THEORY:  The procedure will cancel common components of numerator and denominator.
+KEYWORDS: divisors
+EXAMPLE: example normalForm; shows an example
+"
+{
+divisor B;
+B.num=quotient(A.num,A.den);
+B.den=quotient(A.den,A.num);
+return(B);
+}
+example
+{ "EXAMPLE:";
+ring r=31991,(x,y,z),dp;
+ideal I = y^2*z - x*(x-z)*(x+3*z);
+qring Q = std(I);
+divisor A = makeDivisor(ideal(x,z),ideal(1));
+divisor B = makeDivisor(ideal(x,y),ideal(1));
+divisor D = (A+B)+multdivisor(-1,B);
+D;
+normalForm(D);
+}
+
+
+
+
+static proc isEqualIdeal(ideal A,ideal B){
+return((size(NF(A,std(B)))==0) && (size(NF(B,std(A)))==0));
+}
+
+
+proc isEqualDivisor(divisor A,divisor B)
+"USAGE:  isEqualDivisor(A,B); A = divisor, B = divisor.@*
+ASSUME:  A and B are divisors on X.
+RETURN:  int 0 or 1, checks equality of A and B.
+THEORY:  The procedure will compute the normal forms of A and B and compare.
+KEYWORDS: divisors
+EXAMPLE: example isEqualDivisor; shows an example
+"
+{
+A=normalForm(A);
+B=normalForm(B);
+return((isEqualIdeal(A.num,B.num)) && (isEqualIdeal(A.den,B.den)));
+}
+example
+{ "EXAMPLE:";
+ring r=31991,(x,y,z),dp;
+ideal I = y^2*z - x*(x-z)*(x+3*z);
+qring Q = std(I);
+divisor A = makeDivisor(ideal(x,z),ideal(1));
+divisor B = makeDivisor(ideal(x,y),ideal(1));
+divisor D = (A+B)+multdivisor(-1,B);
+isEqualDivisor(A,D);
+}
+
+
+static proc purify1(ideal I)
+{
+I = simplify(I,2);
+if (I[1]==0){ERROR("expected a non-zero ideal");}
+ideal f = I[1];
+return(minbase(quotient(f,quotient(f,I))));
+}
+
+
+static proc basis(ideal I,int d)
+{
+I=simplify(jet(intersect(I,maxideal(d)),d),2);
+return(I)}
+
+//basis(ideal(x,y^3),2);
+
+
+proc globalSections(divisor D)
+"USAGE:  globalSections(A); A = divisor.@*
+ASSUME:  A is a divisor on X.
+RETURN:  a list with a basis of the space of global sections of D.
+THEORY:  We assume that the qring of X satisfies the S2-condition and that X is smooth. We compute sat((f*J) : I) /f
+         where D = (I)-(J).
+KEYWORDS: divisors
+EXAMPLE: example globalSections; shows an example
+"
+{
+poly f =(simplify(D.num,2))[1];
+ideal LD = basis(purify1(quotient(f*D.den,D.num)),deg(f));
+list L = simplify(LD,2),f;
+return(L);
+}
+example
+{ "EXAMPLE:";
+ring r=31991,(x,y,z),dp;
+ideal I = y^2*z - x*(x-z)*(x+3*z);
+qring Q = std(I);
+divisor P = makeDivisor(ideal(x,z),ideal(1));
+divisor D = multdivisor(4,P);
+globalSections(D);
+}
+
+
+static proc sectionIdeal(poly f, poly g, divisor D){
+return(purify1(quotient(quotient(f*D.num,g), D.den)));
+}
+
+proc degreeDivisor(divisor A)
+"USAGE:  degreeDivisor(A); A = divisor.@*
+ASSUME:  A is a divisor on X.
+RETURN:  The degree of A.
+THEORY:  We compute difference of the degrees of the numerator and denominator ideals.
+KEYWORDS: divisors
+EXAMPLE: example degreeDivisor; shows an example
+"
+{
+  return( mult(std(A.num))-mult(std(A.den)));
+}
+example
+{ "EXAMPLE:";
+ring r=31991,(x,y,z),dp;
+ideal I = y^2*z - x*(x-z)*(x+3*z);
+qring Q = std(I);
+divisor P = makeDivisor(ideal(x,z),ideal(1));
+degreeDivisor(P);
+}
+
+proc linearlyEquivalent(divisor A, divisor B)
+"USAGE:  linearlyEquivalent(A,B); A = divisor, B = divisor.@*
+ASSUME:  A and B are divisors on X.
+RETURN:  list if A and B a linearly equivalent and int 0 otherwise.
+THEORY:  Checks whether A-B is principle. If yes, returns a list L=(f,g) where
+         A - B = (f/g).
+KEYWORDS: divisors
+EXAMPLE: example linearlyEquivalent; shows an example
+"
+{
+divisor F = normalForm(divisorplus(A,negativedivisor(B)));
+list LB = globalSections(F);
+if (size(LB[1])!=1) {return(0);}
+ideal V = sectionIdeal(LB[1][1,1],LB[2],F);
+if (isEqualIdeal(V,ideal(1))==1) {return(list(LB[1][1,1],LB[2]));}
+return(0);
+}
+example
+{ "EXAMPLE:";
+ring r=31991,(x,y,z),dp;
+ideal I = y^2*z - x*(x-z)*(x+3*z);
+qring Q = std(I);
+divisor A = makeDivisor(ideal(x,z),ideal(1));
+divisor B = makeDivisor(ideal(x,y),ideal(1));
+linearlyEquivalent(A,B);
+linearlyEquivalent(multdivisor(2,A),multdivisor(2,B));
+}
+
+
+proc effective(divisor A)
+"USAGE:  effective(A); A = divisor.@*
+ASSUME:  A is a divisor on X which is linearly equivalent to an effective divisor.
+RETURN:  divisor on X.
+THEORY:  We compute an effective divisor linearly equivalent to A.
+KEYWORDS: divisors
+EXAMPLE: example effective; shows an example
+"
+{
+list LB = globalSections(A);
+if (size(LB[1])==0) {ERROR("the divisor is not linearly equivalent to an effective divisor");}
+ideal V = sectionIdeal(LB[1][1,1],LB[2],A);
+return(makeDivisor(V,ideal(1)));
+}
+example
+{ "EXAMPLE:";
+ring r=31991,(x,y,z),dp;
+ideal I = y^2*z - x*(x-z)*(x+3*z);
+qring Q = std(I);
+divisor A = makeDivisor(ideal(x,z),ideal(1));
+divisor B = makeDivisor(ideal(x,y),ideal(1));
+divisor D = divisorplus(multdivisor(2,B),negativedivisor(A));
+effective(D);
+}
+
+
+
+////////////////////////////////////////////////////////////////////////////////
+// formal sums of divisors
+
+proc makeFormalDivisor(list L)
+"USAGE:  makeFormalDivisor(L); L = list.@*
+ASSUME:  L is a list of tuples of an integer and a divisor.
+RETURN:  a formal divisor on X
+THEORY:  Represents an integer formal sum of divisors.
+KEYWORDS: divisors
+EXAMPLE: example makeFormalDivisor; shows an example
+"
+{
+formaldivisor C;
+C.summands = L;
+return(C);
+}
+example
+{ "EXAMPLE:";
+ring r=31991,(x,y,z),dp;
+ideal I = y^2*z - x*(x-z)*(x+3*z);
+qring Q = std(I);
+divisor A = makeDivisor(ideal(x,z),ideal(1));
+divisor B = makeDivisor(ideal(x,y),ideal(1));
+makeFormalDivisor(list(list(-5,A),list(2,B)));
+}
+
+
+proc evaluateFormalDivisor(formaldivisor D)
+"USAGE:  evaluateFormalDivisor(D); D = formal divisor.@*
+ASSUME:  D is a formal divisor on X.
+RETURN:  a divisor on X
+THEORY:  Will evaluate the formal sum.
+KEYWORDS: divisors
+EXAMPLE: example evaluateFormalDivisor; shows an example
+"
+{
+list L = D.summands;
+if (size(L)==0) {return(makeDivisor(ideal(1),ideal(1)));}
+int i;
+divisor E = multdivisor(L[1][1],L[1][2]);
+  for ( i=2; i <= size(L); i++ )
+  {
+    E = divisorplus(E, multdivisor(L[i][1],L[i][2]));
+  }
+return(E);
+}
+example
+{ "EXAMPLE:";
+ring r=31991,(x,y,z),dp;
+ideal I = y^2*z - x*(x-z)*(x+3*z);
+qring Q = std(I);
+divisor A = makeDivisor(ideal(x,z),ideal(1));
+divisor B = makeDivisor(ideal(x,y),ideal(1));
+formaldivisor fE= makeFormalDivisor(list(list(-5,A),list(2,B)));
+evaluateFormalDivisor(fE);
+}
+
+
+
+static proc position(divisor I,list L){
+int i;
+for (i=1; i <=size(L); i++){
+   if (isEqualDivisor(I,L[i][2])==1) {return(i);}
+}
+return(0);}
+
+
+proc formaldivisorplus(formaldivisor A, formaldivisor B)
+"USAGE:  formaldivisorplus(A ,B); A + B; A = formaldivisor, B = formaldivisor. @*
+ASSUME:  A and B are formal divisors on X.
+RETURN:  a formal divisor on X
+THEORY:  The procedure will add the formal sums.
+KEYWORDS: divisors
+EXAMPLE: example formaldivisorplus; shows an example
+"
+{
+formaldivisor C;
+int i,p;
+int j=1;
+list L;
+list LA=A.summands;
+list LB=B.summands;
+for (i=1; i<=size(LA);i++){
+   p=position(LA[i][2],L);
+   if (p==0) {
+        L[j]=list();
+        L[j][2]=LA[i][2];
+        L[j][1]=LA[i][1];
+        j=j+1;
+   } else {
+        L[p][1]=L[p][1]+LA[i][1];
+   };
+}
+for (i=1; i<=size(LB);i++){
+   p=position(LB[i][2],L);
+   if (p==0) {
+        L[j]=list();
+        L[j][2]=LB[i][2];
+        L[j][1]=LB[i][1];
+        j=j+1;
+   } else {
+        L[p][1]=L[p][1]+LB[i][1];
+   };
+}
+//C.summands = (A.summands)+(B.summands);
+return(L);
+}
+example
+{ "EXAMPLE:";
+ring r=31991,(x,y,z),dp;
+ideal I = y^2*z - x*(x-z)*(x+3*z);
+qring Q = std(I);
+divisor A = makeDivisor(ideal(x,z),ideal(1));
+divisor B = makeDivisor(ideal(x,y),ideal(1));
+divisor C = makeDivisor(ideal(x-z,y),ideal(1));
+formaldivisor fE= makeFormalDivisor(list(list(-5,A),list(2,B)));
+formaldivisor fE2= makeFormalDivisor(list(list(-5,A),list(2,C)));
+formaldivisorplus(fE,fE2);
+}
+
+
+proc degreeFormalDivisor(formaldivisor A)
+"USAGE:  degreeFormalDivisor(A); A = formaldivisor.@*
+ASSUME:  A is a formaldivisor on X.
+RETURN:  The degree of A.
+THEORY:  We compute degrees of the summands and return the weighted sum.
+KEYWORDS: divisors
+EXAMPLE: example degreeFormalDivisor; shows an example
+"
+{
+int i,s;
+list L = A.summands;
+for (i=1;i<=size(L);i++){
+    s=s+L[i][1]*degreeDivisor(L[i][2]);
+}
+return(s);
+}
+example
+{ "EXAMPLE:";
+ring r=31991,(x,y,z),dp;
+ideal I = y^2*z - x*(x-z)*(x+3*z);
+qring Q = std(I);
+divisor A = makeDivisor(ideal(x,z),ideal(1));
+divisor B = makeDivisor(ideal(x,y),ideal(1));
+formaldivisor fE= makeFormalDivisor(list(list(-5,A),list(2,B)));
+degreeFormalDivisor(fE);
+}
+
+
+proc multformaldivisor(int n,formaldivisor A)
+"USAGE:  multformaldivisor(n ,A); A*n; n = integer, A = formaldivisor.@*
+ASSUME:  n is an integer and A is a formal divisor on X.
+RETURN:  a formal divisor on X
+THEORY:  The procedure will multiply the formal sum with n.
+KEYWORDS: divisors
+EXAMPLE: example multformaldivisor; shows an example
+"
+{
+formaldivisor B;
+list L=A.summands;
+int i;
+for (i=1;i<=size(L);i++){
+  L[i][1]=n*L[i][1];
+}
+B.summands=L;
+return(B);
+}
+example
+{ "EXAMPLE:";
+ring r=31991,(x,y,z),dp;
+ideal I = y^2*z - x*(x-z)*(x+3*z);
+qring Q = std(I);
+divisor A = makeDivisor(ideal(x,z),ideal(1));
+divisor B = makeDivisor(ideal(x,y),ideal(1));
+formaldivisor fE= makeFormalDivisor(list(list(-5,A),list(2,B)));
+fE*2;
+}
+
+
+/***
+ * For operator overloading, which needs a procedure which takes a divisor first
+ * and integer second.
+ **/
+proc proxymultformaldivisor(formaldivisor A, int n)
+{
+formaldivisor B;
+list L=A.summands;
+int i;
+for (i=1;i<=size(L);i++){
+  L[i][1]=n*L[i][1];
+}
+B.summands=L;
+return(B);
+}
+
+
+
+proc negativeformaldivisor(formaldivisor A)
+"USAGE:  negativeformaldivisor(A); A = formaldivisor.@*
+ASSUME:  A is a formaldivisor on X.
+RETURN:  a formal divisor on X
+THEORY:  The procedure will change the signs of the coefficients.
+KEYWORDS: divisors
+EXAMPLE: example negativeformaldivisor; shows an example
+"
+{
+formaldivisor B;
+list L=A.summands;
+int i;
+for (i=1;i<=size(L);i++){
+  L[i][1]=-L[i][1];
+}
+B.summands=L;
+return(B);
+}
+example
+{ "EXAMPLE:";
+ring r=31991,(x,y,z),dp;
+ideal I = y^2*z - x*(x-z)*(x+3*z);
+qring Q = std(I);
+divisor A = makeDivisor(ideal(x,z),ideal(1));
+divisor B = makeDivisor(ideal(x,y),ideal(1));
+formaldivisor fE= makeFormalDivisor(list(list(-5,A),list(2,B)));
+negativeformaldivisor(fE);
+}
+
+
+static proc primDecDivisor(divisor D)
+"decompose a divisor into a formal divisor of primary divisors"
+{
+formaldivisor E;
+ideal I = D.num;
+ideal J = D.den;
+list L;
+int i;
+int j = 1;
+list LI = primdecGTZ(I);
+for (i=1;i<=size(LI);i++){
+   LI[i][2];
+   L[j]=list(1,makeDivisor(LI[i][1],ideal(1)));
+   j=j+1;
+};
+list LJ = primdecGTZ(J);
+for (i=1;i<=size(LJ);i++){
+   LJ[i][2];
+   L[j]=list(-1,makeDivisor(LJ[i][1],ideal(1)));
+   j=j+1;
+};
+E.summands=L;
+return(E);}
+
+
+
+
+////////////////////////////////////////////////////////////////////////////////
+// P-divisors
+
+proc makePDivisor(list L)
+"USAGE:  makePDivisor(L); L = list.@*
+ASSUME:  L is a list of tuples of a integral polyhedron and a divisor such that
+         all polyhedra have the same tail cone.
+RETURN:  a pdivisor on X
+THEORY:  Represents an polyhedral formal sum of divisors.
+KEYWORDS: divisors, polyhedra
+EXAMPLE: example makePDivisor; shows an example
+"
+{
+pdivisor P;
+list CP = decomposePolyhedron(L[1][1]);
+P.tail = CP[1];
+list LP;
+LP[1]=list(CP[2],L[1][2]);
+int i;
+for (i=2; i<=size(L);i++){
+   CP = decomposePolyhedron(L[i][1]);
+   if (!(CP[1]==P.tail)) {ERROR("All P-coefficients should have the same tail cone");}
+   LP[i]=list(CP[2],L[i][2]);
+}
+P.summands = LP;
+return(P);
+}
+example
+{ "EXAMPLE:";
+ring r=31991,(x,y,z),dp;
+ideal I = y^2*z - x*(x-z)*(x+3*z);
+qring Q = std(I);
+divisor A = makeDivisor(ideal(x,z),ideal(1));
+divisor B = makeDivisor(ideal(x,y),ideal(1));
+intmat M[4][4]= 1,4,0,0,
+                1,0,3,0,
+                0,0,0,2,
+                1,1,1,1;
+polytope PP = polytopeViaPoints(M);
+makePDivisor(list(list(PP,A),list(PP,B)));
+}
+
+static proc decomposePolyhedron(polytope P){
+intmat rays = vertices(P);
+intmat rays2 = rays;
+int i,j;
+for (i=1; i<=nrows(rays);i++){
+   if (rays[i,1]==1) {
+      for (j=1; j<=ncols(rays);j++){
+         rays[i,j]=0;
+      }
+   } else {
+      for (j=1; j<=ncols(rays);j++){
+         rays2[i,j]=0;
+      }
+   }
+}
+cone C = coneViaPoints(rays);
+polytope C2 = polytopeViaPoints(rays2);
+return(list(C,C2));
+}
+
+
+proc evaluatePDivisor(pdivisor D,intvec v)
+"USAGE:  evaluatePDivisor(D,v); D = pdivisor, v = intvec.@*
+ASSUME:  D is a polyhedral divisor on X and v is a point in the dual of the
+         tailcone of the coefficients.
+RETURN:  a formal divisor on X
+THEORY:  Will evaluate the polyhedral sum to an integer formal sum.
+KEYWORDS: divisors, polyhedra
+EXAMPLE: example evaluatePDivisor; shows an example
+"
+{
+formaldivisor vD;
+list L = D.summands;
+cone C = D.tail;
+cone dC = dualCone(C);
+list vL;
+int i;
+intvec vv = 0,v;
+if (!(containsInSupport(dC,vv)))
+  {ERROR("the linear form given should be in the dual tail cone");}
+for (i=1; i<=size(L);i++){
+        vL[i]=list();
+        vL[i][2]=L[i][2];
+  vL[i][1]=Polymake::minimalValue(L[i][1],vv);
+}
+vD.summands = vL;
+return(vD);}
+example
+{ "EXAMPLE:";
+LIB("polymake.so");
+ring r=31991,(x,y,z),dp;
+ideal I = y^2*z - x*(x-z)*(x+3*z);
+qring Q = std(I);
+divisor A = makeDivisor(ideal(x,z),ideal(1));
+divisor B = makeDivisor(ideal(x,y),ideal(1));
+intmat M[4][4]= 1,4,0,0,
+                1,0,3,0,
+                0,0,0,2,
+                1,1,1,1;
+polytope PP = polytopeViaPoints(M);
+pdivisor pD = makePDivisor(list(list(PP,A),list(PP,B)));
+intvec v=1,1,1;
+evaluatePDivisor(pD,v);
+}
+
+
+
+
+
+proc pdivisorplus(pdivisor A, pdivisor B)
+"USAGE:  pdivisorplus(A ,B); A + B; A = pdivisor, B = pdivisor. @*
+ASSUME:  A and B are polyhedral divisors on X.
+RETURN:  a pdivisor on X
+THEORY:  The procedure will add the polyhedral formal sums by doing Minkowski sums.
+KEYWORDS: divisors, polyhedra
+EXAMPLE: example pdivisorplus; shows an example
+"
+{
+pdivisor C;
+int i,p;
+int j=1;
+if (!(A.tail==B.tail)) {ERROR("tail cones should be equal");}
+list L;
+list LA=A.summands;
+list LB=B.summands;
+for (i=1; i<=size(LA);i++){
+   p=position(LA[i][2],L);
+   if (p==0) {
+        L[j]=list();
+        L[j][2]=LA[i][2];
+        L[j][1]=LA[i][1];
+        j=j+1;
+   } else {
+        L[p][1]=Polymake::minkowskiSum(L[p][1],LA[i][1]);
+   };
+}
+for (i=1; i<=size(LB);i++){
+   p=position(LB[i][2],L);
+   if (p==0) {
+        L[j]=list();
+        L[j][2]=LB[i][2];
+        L[j][1]=LB[i][1];
+        j=j+1;
+   } else {
+        L[p][1]=Polymake::minkowskiSum(L[p][1],LB[i][1]);
+   };
+}
+C.summands = L;
+C.tail = A.tail;
+return(C);
+}
+example
+{ "EXAMPLE:";
+LIB("polymake.so");
+ring r=31991,(x,y,z),dp;
+ideal I = y^2*z - x*(x-z)*(x+3*z);
+qring Q = std(I);
+divisor A = makeDivisor(ideal(x,z),ideal(1));
+divisor B = makeDivisor(ideal(x,y),ideal(1));
+intmat M[4][4]= 1,4,0,0,
+                1,0,3,0,
+                0,0,0,2,
+                1,1,1,1;
+polytope PP = polytopeViaPoints(M);
+pdivisor pD = makePDivisor(list(list(PP,A),list(PP,B)));
+pdivisorplus(pD,pD);
+}
+
+
diff --git a/Singular/LIB/dmod.lib b/Singular/LIB/dmod.lib
new file mode 100644
index 0000000..89523d3
--- /dev/null
+++ b/Singular/LIB/dmod.lib
@@ -0,0 +1,6476 @@
+/////////////////////////////////////////////////////////////////////////////
+version="version dmod.lib 4.0.0.0 Jun_2013 "; // $Id: 77a454bc5614e1b8403142a06d7521b497e3c544 $
+category="Noncommutative";
+info="
+LIBRARY: dmod.lib     Algorithms for algebraic D-modules
+AUTHORS: Viktor Levandovskyy,     levandov at math.rwth-aachen.de
+@*             Jorge Martin Morales,    jorge at unizar.es
+
+OVERVIEW:
+Let K be a field of characteristic 0. Given a polynomial ring
+@*      R = K[x_1,...,x_n] and a polynomial F in R,
+@*      one is interested in the R[1/F]-module of rank one, generated by
+@*      the symbol F^s for a symbolic discrete variable s.
+@* In fact, the module R[1/F]*F^s has a structure of a D(R)[s]-module, where D(R)
+@* is an n-th Weyl algebra K<x_1,...,x_n,d_1,...,d_n | d_j x_j = x_j d_j +1> and
+@* D(R)[s] = D(R) tensored with K[s] over K.
+@* Constructively, one needs to find a left ideal I = I(F^s) in D(R), such
+@* that K[x_1,...,x_n,1/F]*F^s is isomorphic to D(R)/I as a D(R)-module.
+@* We often write just D for D(R) and D[s] for D(R)[s].
+@* One is interested in the following data:
+@* - Ann F^s = I = I(F^s) in D(R)[s], denoted by LD in the output
+@* - global Bernstein polynomial in K[s], denoted by bs,
+@* - its minimal integer root s0, the list of all roots of bs, which are known
+@*   to be rational, with their multiplicities, which is denoted by BS
+@* - Ann F^s0 = I(F^s0) in D(R), denoted by LD0 in the output
+@*   (LD0 is a holonomic ideal in D(R))
+@* - Ann^(1) F^s in D(R)[s], denoted by LD1 (logarithmic derivations)
+@* - an operator in D(R)[s], denoted by PS, such that the functional equality
+@*     PS*F^(s+1) = bs*F^s holds in K[x_1,...,x_n,1/F]*F^s.
+
+REFERENCES:
+@* We provide the following implementations of algorithms:
+@* (OT) the classical Ann F^s algorithm from Oaku and Takayama (Journal of
+@* Pure and Applied Math., 1999),
+@* (LOT) Levandovskyy's modification of the Oaku-Takayama algorithm (ISSAC 2007)
+@* (BM) the Ann F^s algorithm by Briancon and Maisonobe (Remarques sur
+@*        l'ideal de Bernstein associe a des polynomes, preprint, 2002)
+@* (LM08) V. Levandovskyy and J. Martin-Morales, ISSAC 2008
+@* (C) Countinho, A Primer of Algebraic D-Modules,
+@* (SST) Saito, Sturmfels, Takayama 'Groebner Deformations of Hypergeometric
+@*         Differential Equations', Springer, 2000
+
+
+Guide:
+@* - Ann F^s = I(F^s) = LD in D(R)[s] can be computed by Sannfs [BM, OT, LOT]
+@* - Ann^(1) F^s in D(R)[s] can be computed by Sannfslog
+@* - global Bernstein polynomial bs in K[s] can be computed by bernsteinBM
+@* - Ann F^s0 = I(F^s0) = LD0 in D(R) can be computed by annfs0, annfs, annfsBM,
+@*    annfsOT, annfsLOT, annfs2, annfsRB etc.
+@* - all the relevant data to F^s (LD, LD0, bs, PS) are computed by operatorBM
+@* - operator PS can be computed via operatorModulo or operatorBM
+@*
+@* - annihilator of F^{s1} for a number s1 is computed with annfspecial
+@* - annihilator of F_1^s_1 * ... * F_p^s_p is computed with annfsBMI
+@* - computing the multiplicity of a rational number r in the Bernstein poly
+@*   of a given ideal goes with checkRoot
+@* - check, whether a given univariate polynomial divides the Bernstein poly
+@*   goes with checkFactor
+
+
+PROCEDURES:
+
+annfs(F[,S,eng]);       compute Ann F^s0 in D and Bernstein polynomial for a poly F
+annfspecial(I, F, m, n);  compute Ann F^n from Ann F^s for a polynomial F and a number n
+Sannfs(F[,S,eng]);      compute Ann F^s in D[s] for a polynomial F
+Sannfslog(F[,eng]);     compute Ann^(1) F^s in D[s] for a polynomial F
+bernsteinBM(F[,eng]);   compute global Bernstein polynomial for a polynomial F (algorithm of Briancon-Maisonobe)
+bernsteinLift(I,F [,eng]);  compute a possible multiple of Bernstein polynomial via lift-like procedure
+operatorBM(F[,eng]);    compute Ann F^s, Ann F^s0, BS and PS for a polynomial F (algorithm of Briancon-Maisonobe)
+operatorModulo(F, I, b); compute PS via the modulo approach
+annfsParamBM(F[,eng]);  compute the generic Ann F^s (algorithm by Briancon and Maisonobe) and exceptional parametric constellations for a polynomial F with parametric coefficients
+annfsBMI(F[,eng]);      compute Ann F^s and Bernstein ideal for a polynomial F=f1*..*fP (multivariate algorithm of Briancon-Maisonobe)
+checkRoot(F,a[,S,eng]); check if a given rational is a root of the global Bernstein polynomial of F and compute its multiplicity
+SannfsBFCT(F[,eng]);      compute Ann F^s in D[s] for a polynomial F (algorithm of Briancon-Maisonobe, other output ordering)
+annfs0(I,F [,eng]);          compute Ann F^s0 in D and Bernstein polynomial from the known Ann F^s in D[s]
+annfs2(I,F [,eng]);           compute Ann F^s0 in D and Bernstein polynomial from the known Ann F^s in D[s] by using a trick of Noro
+annfsRB(I,F [,eng]);          compute Ann F^s0 in D and Bernstein polynomial from the known Ann F^s in D[s] by using Jacobian ideal
+checkFactor(I,F,q[,eng]); check whether a polynomial q in K[s] is a factor of the global Bernstein polynomial of F from the known Ann F^s in D[s]
+
+
+arrange(p);           create a poly, describing a full hyperplane arrangement
+reiffen(p,q);         create a poly, describing a Reiffen curve
+isHolonomic(M);   check whether a module is holonomic
+convloc(L);         replace global orderings with local in the ringlist L
+minIntRoot(P,fact); minimal integer root among the roots of a maximal ideal P
+isRational(n);  check whether n is a rational number
+
+SEE ALSO: bfun_lib, dmodapp_lib, dmodvar_lib, gmssing_lib
+
+KEYWORDS: D-module; D-module structure; left annihilator ideal; Bernstein-Sato polynomial; global Bernstein-Sato polynomial;
+Weyl algebra; Bernstein operator; logarithmic annihilator ideal; parametric annihilator; root of Bernstein-Sato polynomial;
+hyperplane arrangement; Oaku-Takayama algorithm; Briancon-Maisonobe algorithm; LOT algorithm
+";
+
+// reworked by JM+VL on 9.3.2010: Sannfslog
+// added by VL on 2.3.2010: bernsteinLift
+// ****** commented out for better readability by VL on 2.3.2010
+// annfsBM(F[,eng]);          compute Ann F^s0 in D and Bernstein polynomial for a polynomial F (algorithm of Briancon-Maisonobe)
+// annfsLOT(F[,eng]);         compute Ann F^s0 in D and Bernstein polynomial for a polynomial F (Levandovskyy modification of the Oaku-Takayama algorithm)
+// annfsOT(F[,eng]);          compute Ann F^s0 in D and Bernstein polynomial for a polynomial F (algorithm of Oaku-Takayama)
+// SannfsBM(F[,eng]);         compute Ann F^s in D[s] for a polynomial F (algorithm of Briancon-Maisonobe)
+// SannfsLOT(F[,eng]);        compute Ann F^s in D[s] for a polynomial F (Levandovskyy modification of the Oaku-Takayama algorithm)
+// SannfsOT(F[,eng]);         compute Ann F^s in D[s] for a polynomial F (algorithm of Oaku-Takayama)
+// checkRoot1(I,F,a[,eng]);   check whether a rational is a root of the global Bernstein polynomial of F from the known Ann F^s in D[s]
+// checkRoot2(I,F,a[,eng]);   check whether a rational is a root of the global Bernstein polynomial of F and compute its multiplicity from the known Ann F^s in D[s]
+
+LIB "matrix.lib"; // for submat
+LIB "nctools.lib"; // makeModElimRing etc.
+LIB "elim.lib"; // for nselect
+LIB "qhmoduli.lib"; // for Max
+LIB "gkdim.lib";
+LIB "gmssing.lib";
+LIB "control.lib";  // for genericity
+LIB "dmodapp.lib"; // for e.g. engine
+LIB "poly.lib";
+
+proc testdmodlib()
+{
+  /* tests all procs for consistency */
+  /* adding the new proc, add it here */
+
+  "MAIN PROCEDURES:";
+  example annfs;
+  example Sannfs;
+  example Sannfslog;
+  example bernsteinBM;
+  example operatorBM;
+  example annfspecial;
+  example annfsParamBM;
+  example annfsBMI;
+  example checkRoot;
+  example annfs0;
+  example annfs2;
+  example annfsRB;
+  example annfs2;
+  example operatorModulo;
+  "SECONDARY D-MOD PROCEDURES:";
+  example annfsBM;
+  example annfsLOT;
+  example annfsOT;
+  example SannfsBM;
+  example SannfsLOT;
+  example SannfsOT;
+  example SannfsBFCT;
+  example checkRoot1;
+  example checkRoot2;
+  example checkFactor;
+}
+
+
+
+// new top-level procedures
+proc annfs(poly F, list #)
+"USAGE:  annfs(f [,S,eng]);  f a poly, S a string, eng an optional int
+RETURN:  ring
+PURPOSE: compute the D-module structure of basering[1/f]*f^s with the algorithm
+@*  given in S and with the Groebner basis engine given in ''eng''
+NOTE:  activate the output ring with the @code{setring} command.
+@*    String S; S can be one of the following:
+@*    'bm' (default) - for the algorithm of Briancon and Maisonobe,
+@*    'ot'  - for the algorithm of Oaku and Takayama,
+@*    'lot' - for the Levandovskyy's modification of the algorithm of OT.
+@*  If eng <>0, @code{std} is used for Groebner basis computations,
+@*  otherwise and by default @code{slimgb} is used.
+@*  In the output ring:
+@*  - the ideal LD (which is a Groebner basis) is the needed D-module structure,
+@*  - the list  BS contains roots and multiplicities of a BS-polynomial of f.
+DISPLAY: If @code{printlevel}=1, progress debug messages will be printed,
+@*          if @code{printlevel}>=2, all the debug messages will be printed.
+EXAMPLE: example annfs; shows examples
+"
+{
+  int eng = 0;
+  int chs = 0; // choice
+  string algo = "bm";
+  string st;
+  if ( size(#)>0 )
+  {
+   if ( typeof(#[1]) == "string" )
+   {
+     st = string(#[1]);
+     if ( (st == "BM") || (st == "Bm") || (st == "bM") ||(st == "bm"))
+     {
+       algo = "bm";
+       chs  = 1;
+     }
+     if ( (st == "OT") || (st == "Ot") || (st == "oT") || (st == "ot"))
+     {
+       algo = "ot";
+       chs  = 1;
+     }
+     if ( (st == "LOT") || (st == "lOT") || (st == "Lot") || (st == "lot"))
+     {
+       algo = "lot";
+       chs  = 1;
+     }
+     if (chs != 1)
+     {
+       // incorrect value of S
+       print("Incorrect algorithm given, proceed with the default BM");
+       algo = "bm";
+     }
+     // second arg
+     if (size(#)>1)
+     {
+       // exists 2nd arg
+       if ( typeof(#[2]) == "int" )
+       {
+         // the case: given alg, given engine
+         eng = int(#[2]);
+       }
+       else
+       {
+         eng = 0;
+       }
+     }
+     else
+     {
+       // no second arg
+       eng = 0;
+     }
+   }
+   else
+   {
+     if ( typeof(#[1]) == "int" )
+     {
+     // the case: default alg, engine
+     eng = int(#[1]);
+     //      algo = "bm";  //is already set
+     }
+     else
+     {
+       // incorr. 1st arg
+       algo = "bm";
+     }
+   }
+  }
+
+   // size(#)=0, i.e. there is no algorithm and no engine given
+   //  eng = 0; algo = "bm";  //are already set
+   // int ppl = printlevel-voice+2;
+
+  int old_printlevel = printlevel;
+  printlevel=printlevel+1;
+  def save = basering;
+  if ( algo=="ot")
+  {
+    def @A = annfsOT(F,eng);
+  }
+  else
+  {
+    if ( algo=="lot")
+    {
+      def @A = annfsLOT(F,eng);
+    }
+    else
+    {
+      // bm = default
+      def @A = annfsBM(F,eng);
+    }
+  }
+  printlevel = old_printlevel;
+  return(@A);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y,z),Dp;
+  poly F = z*x^2+y^3;
+  def A  = annfs(F); // here, the default BM algorithm will be used
+  setring A; // the Weyl algebra in (x,y,z,Dx,Dy,Dz)
+  LD; //the annihilator of F^{-1} over A
+  BS; // roots with multiplicities of BS polynomial
+}
+
+
+proc Sannfs(poly F, list #)
+"USAGE:  Sannfs(f [,S,eng]);  f a poly, S a string, eng an optional int
+RETURN:  ring
+PURPOSE: compute the D-module structure of basering[f^s] with the algorithm
+@*  given in S and with the Groebner basis engine given in eng
+NOTE:    activate the output ring with the @code{setring} command.
+@*       The value of a string S can be
+@*       'bm' (default) - for the algorithm of  Briancon and Maisonobe,
+@*       'lot' - for the Levandovskyy's modification of the algorithm of OT,
+@*       'ot'  - for the algorithm of Oaku and Takayama.
+@*       If eng <>0, @code{std} is used for Groebner basis computations,
+@*       otherwise, and by default @code{slimgb} is used.
+@*       In the output ring:
+@*       - the ideal LD is the needed D-module structure.
+DISPLAY: If @code{printlevel}=1, progress debug messages will be printed,
+@*          if @code{printlevel}>=2, all the debug messages will be printed.
+EXAMPLE: example Sannfs; shows examples
+"
+{
+  int eng = 0;
+  int chs = 0; // choice
+  string algo = "bm";
+  string st;
+  if ( size(#)>0 )
+  {
+   if ( typeof(#[1]) == "string" )
+   {
+     st = string(#[1]);
+     if ( (st == "BM") || (st == "Bm") || (st == "bM") ||(st == "bm"))
+     {
+       algo = "bm";
+       chs  = 1;
+     }
+     if ( (st == "OT") || (st == "Ot") || (st == "oT") || (st == "ot"))
+     {
+       algo = "ot";
+       chs  = 1;
+     }
+     if ( (st == "LOT") || (st == "lOT") || (st == "Lot") || (st == "lot"))
+     {
+       algo = "lot";
+       chs  = 1;
+     }
+     if (chs != 1)
+     {
+       // incorrect value of S
+       print("Incorrect algorithm given, proceed with the default BM");
+       algo = "bm";
+     }
+     // second arg
+     if (size(#)>1)
+     {
+       // exists 2nd arg
+       if ( typeof(#[2]) == "int" )
+       {
+         // the case: given alg, given engine
+         eng = int(#[2]);
+       }
+       else
+       {
+         eng = 0;
+       }
+     }
+     else
+     {
+       // no second arg
+       eng = 0;
+     }
+   }
+   else
+   {
+     if ( typeof(#[1]) == "int" )
+     {
+     // the case: default alg, engine
+     eng = int(#[1]);
+     //      algo = "bm";  //is already set
+     }
+     else
+     {
+       // incorr. 1st arg
+       algo = "bm";
+     }
+   }
+  }
+  // size(#)=0, i.e. there is no algorithm and no engine given
+  //  eng = 0; algo = "bm";  //are already set
+  // int ppl = printlevel-voice+2;
+  printlevel=printlevel+1;
+  def save = basering;
+  if ( algo=="ot")
+  {
+    def @A = SannfsOT(F,eng);
+  }
+  else
+  {
+    if ( algo=="lot")
+    {
+      def @A = SannfsLOT(F,eng);
+    }
+    else
+    {
+      // bm = default
+      def @A = SannfsBM(F,eng);
+    }
+  }
+  printlevel=printlevel-1;
+  return(@A);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y,z),Dp;
+  poly F = x^3+y^3+z^3;
+  printlevel = 0;
+  def A  = Sannfs(F); // here, the default BM algorithm will be used
+  setring A;
+  LD;
+}
+
+proc Sannfslog (poly F, list #)
+"USAGE:  Sannfslog(f [,eng]);  f a poly, eng an optional int
+RETURN:  ring
+PURPOSE: compute the D-module structure of basering[1/f]*f^s
+NOTE:    activate the output ring with the @code{setring} command.
+@*   In the output ring D[s], the ideal LD1 is generated by the elements
+@*   in Ann F^s in D[s], coming from logarithmic derivations.
+@*       If eng <>0, @code{std} is used for Groebner basis computations,
+@*       otherwise, and by default @code{slimgb} is used.
+DISPLAY: If @code{printlevel}=1, progress debug messages will be printed,
+@*          if @code{printlevel}>=2, all the debug messages will be printed.
+EXAMPLE: example Sannfslog; shows examples
+"
+{
+  int eng = 0;
+  if ( size(#)>0 )
+  {
+    if ( typeof(#[1]) == "int" )
+    {
+      eng = int(#[1]);
+    }
+  }
+  int ppl = printlevel-voice+2;
+  def save = basering;
+  int N = nvars(basering);
+  int Nnew = 2*N+1;
+  int i;
+  string s;
+  list RL = ringlist(basering);
+  list L, Lord;
+  list tmp;
+  intvec iv;
+  L[1] = RL[1]; // char
+  L[4] = RL[4]; // char, minpoly
+  // check whether vars have admissible names
+  list Name = RL[2];
+  for (i=1; i<=N; i++)
+  {
+    if (Name[i] == "s")
+    {
+      ERROR("Variable names should not include s");
+    }
+  }
+  // the ideal I
+  ideal I = -F, jacob(F);
+  dbprint(ppl,"// -1-1- starting the computation of syz(-F,_Dx(F))");
+  dbprint(ppl-1, I);
+  matrix M = syz(I);
+  M = transpose(M);  // it is more usefull working with columns
+  dbprint(ppl,"// -1-2- the module syz(-F,_Dx(F)) has been computed");
+  dbprint(ppl-1, M);
+  // ------------ the ring @R ------------
+  // _x, _Dx, s;  elim.ord for _x,_Dx.
+  // now, create the names for new vars
+  list DName;
+  for (i=1; i<=N; i++)
+  {
+    DName[i] = "D"+Name[i]; // concat
+  }
+  tmp[1] = "s";
+  list NName;
+  NName = Name + DName + tmp;
+  L[2] = NName;
+  tmp = 0;
+  // block ord (dp(N),dp);
+  s = "iv=";
+  for (i=1; i<=Nnew-1; i++)
+  {
+    s = s+"1,";
+  }
+  s[size(s)]=";";
+  execute(s);
+  tmp[1] = "dp";  // string
+  tmp[2] = iv;   // intvec
+  Lord[1] = tmp;
+  // continue with dp 1,1,1,1...
+  tmp[1] = "dp";  // string
+  s[size(s)] = ",";
+  s = s+"1;";
+  execute(s);
+  kill s;
+  kill NName;
+  tmp[2]      = iv;
+  Lord[2]     = tmp;
+  tmp[1]      = "C";  iv  = 0;  tmp[2]=iv;
+  Lord[3]     = tmp;  tmp = 0;
+  L[3]        = Lord;
+  // we are done with the list. Now add a Plural part
+  def @R@ = ring(L);
+  setring @R@;
+  matrix @D[Nnew][Nnew];
+  for (i=1; i<=N; i++)
+  {
+    @D[i,N+i]=1;
+  }
+  def @R = nc_algebra(1, at D);
+  setring @R;
+  kill @R@;
+  dbprint(ppl,"// -2-1- the ring @R(_x,_Dx,s) is ready");
+  dbprint(ppl-1, @R);
+  matrix M = imap(save,M);
+  // now, create the vector [-s,_Dx]
+  vector v = [-s];  // now s is a variable
+  for (i=1; i<=N; i++)
+  {
+    v = v + var(i+N)*gen(i+1);
+  }
+  ideal J = ideal(M*v);
+  // make leadcoeffs positive
+  for (i=1; i<= ncols(J); i++)
+  {
+    if ( leadcoef(J[i])<0 )
+    {
+      J[i] = -J[i];
+    }
+  }
+  ideal LD1 = J;
+  kill J;
+  export LD1;
+  return(@R);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y),Dp;
+  poly F = x4+y5+x*y4;
+  printlevel = 0;
+  def A  = Sannfslog(F);
+  setring A;
+  LD1;
+}
+
+// JM+VL: output ring restructured into "normal"
+
+// proc Sannfslog (poly F, list #)
+// "USAGE:  Sannfslog(f [,eng]);  f a poly, eng an optional int
+// RETURN:  ring
+// PURPOSE: compute the D-module structure of basering[1/f]*f^s
+// NOTE:    activate the output ring with the @code{setring} command.
+// @*   In the output ring D[s], the ideal LD1 is generated by the elements
+// @*   in Ann F^s in D[s], coming from logarithmic derivations.
+// @*       If eng <>0, @code{std} is used for Groebner basis computations,
+// @*       otherwise, and by default @code{slimgb} is used.
+// DISPLAY: If @code{printlevel}=1, progress debug messages will be printed,
+// @*          if @code{printlevel}>=2, all the debug messages will be printed.
+// EXAMPLE: example Sannfslog; shows examples
+// "
+// {
+//   int eng = 0;
+//   if ( size(#)>0 )
+//   {
+//     if ( typeof(#[1]) == "int" )
+//     {
+//       eng = int(#[1]);
+//     }
+//   }
+//   int ppl = printlevel-voice+2;
+//   def save = basering;
+//   int N = nvars(basering);
+//   int Nnew = 2*N+1;
+//   int i;
+//   string s;
+//   list RL = ringlist(basering);
+//   list L, Lord;
+//   list tmp;
+//   intvec iv;
+//   L[1] = RL[1]; // char
+//   L[4] = RL[4]; // char, minpoly
+//   // check whether vars have admissible names
+//   list Name = RL[2];
+//   for (i=1; i<=N; i++)
+//   {
+//     if (Name[i] == "s")
+//     {
+//       ERROR("Variable names should not include s");
+//     }
+//   }
+//   // the ideal I
+//   ideal I = -F, jacob(F);
+//   dbprint(ppl,"// -1-1- starting the computation of syz(-F,_Dx(F))");
+//   dbprint(ppl-1, I);
+//   matrix M = syz(I);
+//   M = transpose(M);  // it is more usefull working with columns
+//   dbprint(ppl,"// -1-2- the module syz(-F,_Dx(F)) has been computed");
+//   dbprint(ppl-1, M);
+//   // ------------ the ring @R ------------
+//   // _x, _Dx, s;  elim.ord for _x,_Dx.
+//   // now, create the names for new vars
+//   list DName;
+//   for (i=1; i<=N; i++)
+//   {
+//     DName[i] = "D"+Name[i]; // concat
+//   }
+//   tmp[1] = "s";
+//   list NName;
+//   for (i=1; i<=N; i++)
+//   {
+//     NName[2*i-1] = Name[i];
+//     NName[2*i] = DName[i];
+//     //NName[2*i-1] = DName[i];
+//     //NName[2*i] = Name[i];
+//   }
+//   NName[Nnew] = tmp[1];
+//   L[2] = NName;
+//   tmp = 0;
+//   // block ord (a(1,1),a(0,0,1,1),...,dp);
+//   //list("a",intvec(1,1)), list("a",intvec(0,0,1,1)), ...
+//   tmp[1] = "a";  // string
+//   for (i=1; i<=N; i++)
+//   {
+//     iv[2*i-1] = 1;
+//     iv[2*i]   = 1;
+//     tmp[2]    = iv;  iv = 0;  // intvec
+//     Lord[i]   = tmp;
+//   }
+//   //list("dp",intvec(1,1,1,1,1,...))
+//   s = "iv=";
+//   for (i=1; i<=Nnew; i++)
+//   {
+//     s = s+"1,";
+//   }
+//   s[size(s)]=";";
+//   execute(s);
+//   kill s;
+//   tmp[1] = "dp";  // string
+//   tmp[2] = iv;    // intvec
+//   Lord[N+1] = tmp;
+//   //list("C",intvec(0))
+//   tmp[1] = "C";  // string
+//   iv = 0;
+//   tmp[2] = iv;   // intvec
+//   Lord[N+2] = tmp;
+//   tmp = 0;
+//   L[3]    = Lord;
+//   // we are done with the list. Now add a Plural part
+//   def @R@ = ring(L);
+//   setring @R@;
+//   matrix @D[Nnew][Nnew];
+//   for (i=1; i<=N; i++)
+//   {
+//     @D[2*i-1,2*i]=1;
+//     //@D[2*i-1,2*i]=-1;
+//   }
+//   def @R = nc_algebra(1, at D);
+//   setring @R;
+//   kill @R@;
+//   dbprint(ppl,"// -2-1- the ring @R(_x,_Dx,s) is ready");
+//   dbprint(ppl-1, @R);
+//   matrix M = imap(save,M);
+//   // now, create the vector [-s,_Dx]
+//   vector v = [-s];  // now s is a variable
+//   for (i=1; i<=N; i++)
+//   {
+//     v = v + var(2*i)*gen(i+1);
+//     //v = v + var(2*i-1)*gen(i+1);
+//   }
+//   ideal J = ideal(M*v);
+//   // make leadcoeffs positive
+//   for (i=1; i<= ncols(J); i++)
+//   {
+//     if ( leadcoef(J[i])<0 )
+//     {
+//       J[i] = -J[i];
+//     }
+//   }
+//   ideal LD1 = J;
+//   kill J;
+//   export LD1;
+//   return(@R);
+// }
+// example
+// {
+//   "EXAMPLE:"; echo = 2;
+//   ring r = 0,(x,y),Dp;
+//   poly F = x^4+y^5+x*y^4;
+//   printlevel = 0;
+//   def A  = Sannfslog(F);
+//   setring A;
+//   LD1;
+// }
+
+
+// alternative code for SannfsBM, renamed from annfsBM to ALTannfsBM
+// is superfluos - will not be included in the official documentation
+static proc ALTannfsBM (poly F, list #)
+"USAGE:  ALTannfsBM(f [,eng]);  f a poly, eng an optional int
+RETURN:  ring
+PURPOSE: compute the annihilator ideal of f^s in D[s], where D is the Weyl
+@*   algebra, according to the algorithm by Briancon and Maisonobe
+NOTE:  activate the output ring with the @code{setring} command. In this ring,
+@*       - the ideal LD is the annihilator of f^s.
+@*       If eng <>0, @code{std} is used for Groebner basis computations,
+@*       otherwise, and by default @code{slimgb} is used.
+DISPLAY: If @code{printlevel}=1, progress debug messages will be printed,
+@*          if @code{printlevel}>=2, all the debug messages will be printed.
+EXAMPLE: example ALTannfsBM; shows examples
+"
+{
+  int eng = 0;
+  if ( size(#)>0 )
+  {
+    if ( typeof(#[1]) == "int" )
+    {
+      eng = int(#[1]);
+    }
+  }
+  // returns a list with a ring and an ideal LD in it
+  int ppl = printlevel-voice+2;
+  //  printf("plevel :%s, voice: %s",printlevel,voice);
+  def save = basering;
+  int N = nvars(basering);
+  int Nnew = 2*N+2;
+  int i,j;
+  string s;
+  list RL = ringlist(basering);
+  list L, Lord;
+  list tmp;
+  intvec iv;
+  L[1] = RL[1];  //char
+  L[4] = RL[4];  //char, minpoly
+  // check whether vars have admissible names
+  list Name  = RL[2];
+  list RName;
+  RName[1] = "t";
+  RName[2] = "s";
+  for (i=1; i<=N; i++)
+  {
+    for(j=1; j<=size(RName); j++)
+    {
+      if (Name[i] == RName[j])
+      {
+        ERROR("Variable names should not include t,s");
+      }
+    }
+  }
+  // now, create the names for new vars
+  list DName;
+  for (i=1; i<=N; i++)
+  {
+    DName[i] = "D"+Name[i];  //concat
+  }
+  tmp[1] = "t";
+  tmp[2] = "s";
+  list NName = tmp + Name + DName;
+  L[2]   = NName;
+  // Name, Dname will be used further
+  kill NName;
+  // block ord (lp(2),dp);
+  tmp[1]  = "lp"; // string
+  iv      = 1,1;
+  tmp[2]  = iv; //intvec
+  Lord[1] = tmp;
+  // continue with dp 1,1,1,1...
+  tmp[1]  = "dp"; // string
+  s       = "iv=";
+  for (i=1; i<=Nnew; i++)
+  {
+    s = s+"1,";
+  }
+  s[size(s)]= ";";
+  execute(s);
+  kill s;
+  tmp[2]    = iv;
+  Lord[2]   = tmp;
+  tmp[1]    = "C";
+  iv        = 0;
+  tmp[2]    = iv;
+  Lord[3]   = tmp;
+  tmp       = 0;
+  L[3]      = Lord;
+  // we are done with the list
+  def @R@ = ring(L);
+  setring @R@;
+  matrix @D[Nnew][Nnew];
+  @D[1,2]=t;
+  for(i=1; i<=N; i++)
+  {
+    @D[2+i,N+2+i]=1;
+  }
+  // L[5] = matrix(UpOneMatrix(Nnew));
+  // L[6] = @D;
+  def @R = nc_algebra(1, at D);
+  setring @R;
+  kill @R@;
+  dbprint(ppl,"// -1-1- the ring @R(t,s,_x,_Dx) is ready");
+  dbprint(ppl-1, @R);
+  // create the ideal I
+  poly  F = imap(save,F);
+  ideal I = t*F+s;
+  poly p;
+  for(i=1; i<=N; i++)
+  {
+    p = t;  //t
+    p = diff(F,var(2+i))*p;
+    I = I, var(N+2+i) + p;
+  }
+  // -------- the ideal I is ready ----------
+  dbprint(ppl,"// -1-2- starting the elimination of t in @R");
+  dbprint(ppl-1, I);
+  ideal J = engine(I,eng);
+  ideal K = nselect(J,1);
+  kill I,J;
+  dbprint(ppl,"// -1-3- t is eliminated");
+  dbprint(ppl-1, K);  //K is without t
+  // create Dn[s], where Dn is the ordinary Weyl Algebra, and put the result into it,
+  // thus creating the ring @R2
+  // keep: N, i,j,s, tmp, RL
+  setring save;
+  Nnew = 2*N+1;
+  // list RL = ringlist(save);  //is defined earlier
+  kill Lord, tmp, iv;
+  L = 0;
+  list Lord, tmp;
+  intvec iv;
+  L[1] = RL[1];
+  L[4] = RL[4];  //char, minpoly
+  // check whether vars have admissible names -> done earlier
+  // list Name = RL[2]
+  // DName is defined earlier
+  tmp[1] = "s";
+  list NName = Name + DName + tmp;
+  L[2] = NName;
+  // dp ordering;
+  string s = "iv=";
+  for (i=1; i<=Nnew; i++)
+  {
+    s = s+"1,";
+  }
+  s[size(s)] = ";";
+  execute(s);
+  kill s;
+  tmp     = 0;
+  tmp[1]  = "dp";  //string
+  tmp[2]  = iv;    //intvec
+  Lord[1] = tmp;
+  tmp[1]  = "C";
+  iv      = 0;
+  tmp[2]  = iv;
+  Lord[2] = tmp;
+  tmp     = 0;
+  L[3]    = Lord;
+  // we are done with the list
+  // Add: Plural part
+  def @R2@ = ring(L);
+  setring @R2@;
+  matrix @D[Nnew][Nnew];
+  for (i=1; i<=N; i++)
+  {
+    @D[i,N+i]=1;
+  }
+  def @R2 = nc_algebra(1, at D);
+  setring @R2;
+  kill @R2@;
+  dbprint(ppl,"// -2-1- the ring @R2(_x,_Dx,s) is ready");
+  dbprint(ppl-1, @R2);
+  ideal K = imap(@R,K);
+  option(redSB);
+  //dbprint(ppl,"// -2-2- the final cosmetic std");
+  //K = engine(K,eng);  //std does the job too
+  // total cleanup
+  kill @R;
+  ideal LD = K;
+  export LD;
+  return(@R2);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y,z,w),Dp;
+  poly F = x^3+y^3+z^2*w;
+  printlevel = 0;
+  def A = ALTannfsBM(F);
+  setring A;
+  LD;
+}
+
+proc bernsteinBM(poly F, list #)
+"USAGE:  bernsteinBM(f [,eng]);  f a poly, eng an optional int
+RETURN:  list (of roots of the Bernstein polynomial b and their multiplicies)
+PURPOSE: compute the global Bernstein-Sato polynomial for a hypersurface,
+@* defined by f, according to the algorithm by Briancon and Maisonobe
+NOTE:    If eng <>0, @code{std} is used for Groebner basis computations,
+@*       otherwise, and by default @code{slimgb} is used.
+DISPLAY: If @code{printlevel}=1, progress debug messages will be printed,
+@*          if @code{printlevel}>=2, all the debug messages will be printed.
+EXAMPLE: example bernsteinBM; shows examples
+"
+{
+  int eng = 0;
+  if ( size(#)>0 )
+  {
+    if ( typeof(#[1]) == "int" )
+    {
+      eng = int(#[1]);
+    }
+  }
+  // returns a list with a ring and an ideal LD in it
+  int ppl = printlevel-voice+2;
+  //  printf("plevel :%s, voice: %s",printlevel,voice);
+  def save = basering;
+  int N = nvars(basering);
+  int Nnew = 2*N+2;
+  int i,j;
+  string s;
+  list RL = ringlist(basering);
+  list L, Lord;
+  list tmp;
+  intvec iv;
+  L[1] = RL[1];  //char
+  L[4] = RL[4];  //char, minpoly
+  // check whether vars have admissible names
+  list Name  = RL[2];
+  list RName;
+  RName[1] = "t";
+  RName[2] = "s";
+  for (i=1; i<=N; i++)
+  {
+    for(j=1; j<=size(RName); j++)
+    {
+      if (Name[i] == RName[j])
+      {
+        ERROR("Variable names should not include t,s");
+      }
+    }
+  }
+  // now, create the names for new vars
+  list DName;
+  for (i=1; i<=N; i++)
+  {
+    DName[i] = "D"+Name[i];  //concat
+  }
+  tmp[1] = "t";
+  tmp[2] = "s";
+  list NName = tmp + Name + DName;
+  L[2]   = NName;
+  // Name, Dname will be used further
+  kill NName;
+  // block ord (lp(2),dp);
+  tmp[1]  = "lp"; // string
+  iv      = 1,1;
+  tmp[2]  = iv; //intvec
+  Lord[1] = tmp;
+  // continue with dp 1,1,1,1...
+  tmp[1]  = "dp"; // string
+  s       = "iv=";
+  for (i=1; i<=Nnew; i++)
+  {
+    s = s+"1,";
+  }
+  s[size(s)]= ";";
+  execute(s);
+  kill s;
+  tmp[2]    = iv;
+  Lord[2]   = tmp;
+  tmp[1]    = "C";
+  iv        = 0;
+  tmp[2]    = iv;
+  Lord[3]   = tmp;
+  tmp       = 0;
+  L[3]      = Lord;
+  // we are done with the list
+  def @R@ = ring(L);
+  setring @R@;
+  matrix @D[Nnew][Nnew];
+  @D[1,2]=t;
+  for(i=1; i<=N; i++)
+  {
+    @D[2+i,N+2+i]=1;
+  }
+  // L[5] = matrix(UpOneMatrix(Nnew));
+  // L[6] = @D;
+  def @R = nc_algebra(1, at D);
+  setring @R;
+  kill @R@;
+  dbprint(ppl,"// -1-1- the ring @R(t,s,_x,_Dx) is ready");
+  dbprint(ppl-1, @R);
+  // create the ideal I
+  poly  F = imap(save,F);
+  ideal I = t*F+s;
+  poly p;
+  for(i=1; i<=N; i++)
+  {
+    p = t;  //t
+    p = diff(F,var(2+i))*p;
+    I = I, var(N+2+i) + p;
+  }
+  // -------- the ideal I is ready ----------
+  dbprint(ppl,"// -1-2- starting the elimination of t in @R");
+  dbprint(ppl-1, I);
+  ideal J = engine(I,eng);
+  ideal K = nselect(J,1);
+  kill I,J;
+  dbprint(ppl,"// -1-3- t is eliminated");
+  dbprint(ppl-1, K);  //K is without t
+  // ----------- the ring @R2 ------------
+  // _x, _Dx,s;  elim.ord for _x,_Dx.
+  // keep: N, i,j,s, tmp, RL
+  setring save;
+  Nnew = 2*N+1;
+  kill Lord, tmp, iv, RName;
+  list Lord, tmp;
+  intvec iv;
+  L[1] = RL[1];
+  L[4] = RL[4];  //char, minpoly
+  // check whether vars hava admissible names -> done earlier
+  // now, create the names for new var
+  tmp[1] = "s";
+  // DName is defined earlier
+  list NName = Name + DName + tmp;
+  L[2] = NName;
+  tmp = 0;
+  // block ord (dp(N),dp);
+  string s = "iv=";
+  for (i=1; i<=Nnew-1; i++)
+  {
+    s = s+"1,";
+  }
+  s[size(s)]=";";
+  execute(s);
+  tmp[1] = "dp";  //string
+  tmp[2] = iv;    //intvec
+  Lord[1] = tmp;
+  // continue with dp 1,1,1,1...
+  tmp[1] = "dp";  //string
+  s[size(s)] = ",";
+  s = s+"1;";
+  execute(s);
+  kill s;
+  kill NName;
+  tmp[2]  = iv;
+  Lord[2] = tmp;
+  tmp[1]  = "C";
+  iv      = 0;
+  tmp[2]  = iv;
+  Lord[3] = tmp;
+  tmp     = 0;
+  L[3]    = Lord;
+  // we are done with the list. Now add a Plural part
+  def @R2@ = ring(L);
+  setring @R2@;
+  matrix @D[Nnew][Nnew];
+  for (i=1; i<=N; i++)
+  {
+    @D[i,N+i]=1;
+  }
+  def @R2 = nc_algebra(1, at D);
+  setring @R2;
+  kill @R2@;
+  dbprint(ppl,"// -2-1- the ring @R2(_x,_Dx,s) is ready");
+  dbprint(ppl-1, @R2);
+  ideal MM = maxideal(1);
+  MM = 0,s,MM;
+  map R01 = @R, MM;
+  ideal K = R01(K);
+  kill @R, R01;
+  poly F = imap(save,F);
+  K = K,F;
+  dbprint(ppl,"// -2-2- starting the elimination of _x,_Dx in @R2");
+  dbprint(ppl-1, K);
+  ideal M = engine(K,eng);
+  ideal K2 = nselect(M,1..Nnew-1);
+  kill K,M;
+  dbprint(ppl,"// -2-3- _x,_Dx are eliminated in @R2");
+  dbprint(ppl-1, K2);
+  // the ring @R3 and the search for minimal negative int s
+  ring @R3 = 0,s,dp;
+  dbprint(ppl,"// -3-1- the ring @R3(s) is ready");
+  ideal K3 = imap(@R2,K2);
+  kill @R2;
+  poly p = K3[1];
+  dbprint(ppl,"// -3-2- factorization");
+  list P = factorize(p);          //with constants and multiplicities
+  ideal bs; intvec m;             //the Bernstein polynomial is monic, so we are not interested in constants
+  for (i=2; i<= size(P[1]); i++)  //we delete P[1][1] and P[2][1]
+  {
+    bs[i-1] = P[1][i];
+    m[i-1]  = P[2][i];
+  }
+  // "--------- b-function factorizes into ---------";  P;
+  //int sP = minIntRoot(bs,1);
+  //dbprint(ppl,"// -3-3- minimal integer root found");
+  //dbprint(ppl-1, sP);
+  // convert factors to a list of their roots and multiplicities
+  bs =  normalize(bs);
+  bs = -subst(bs,s,0);
+  setring save;
+  ideal bs = imap(@R3,bs);
+  kill @R3;
+  list BS = bs,m;
+  return(BS);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y,z,w),Dp;
+  poly F = x^3+y^3+z^2*w;
+  printlevel = 0;
+  bernsteinBM(F);
+}
+
+// some changes
+proc annfsBM (poly F, list #)
+"USAGE:  annfsBM(f [,eng]);  f a poly, eng an optional int
+RETURN:  ring
+PURPOSE: compute the D-module structure of basering[1/f]*f^s, according
+@* to the algorithm by Briancon and Maisonobe
+NOTE:    activate the output ring with the @code{setring} command. In this ring,
+@*       - the ideal LD (which is a Groebner basis) is the needed D-module structure,
+@*         which is obtained by substituting the minimal integer root of a Bernstein
+@*         polynomial into the s-parametric ideal;
+@*       - the list BS is the list of roots and multiplicities of a Bernstein polynomial of f.
+@*       If eng <>0, @code{std} is used for Groebner basis computations,
+@*       otherwise, and by default @code{slimgb} is used.
+DISPLAY: If @code{printlevel}=1, progress debug messages will be printed,
+@*          if @code{printlevel}>=2, all the debug messages will be printed.
+EXAMPLE: example annfsBM; shows examples
+"
+{
+  int eng = 0;
+  if ( size(#)>0 )
+  {
+    if ( typeof(#[1]) == "int" )
+    {
+      eng = int(#[1]);
+    }
+  }
+  // returns a list with a ring and an ideal LD in it
+  int ppl = printlevel-voice+2;
+  //  printf("plevel :%s, voice: %s",printlevel,voice);
+  def save = basering;
+  int N = nvars(basering);
+  int Nnew = 2*N+2;
+  int i,j;
+  string s;
+  list RL = ringlist(basering);
+  list L, Lord;
+  list tmp;
+  intvec iv;
+  L[1] = RL[1];  //char
+  L[4] = RL[4];  //char, minpoly
+  // check whether vars have admissible names
+  list Name  = RL[2];
+  list RName;
+  RName[1] = "t";
+  RName[2] = "s";
+  for (i=1; i<=N; i++)
+  {
+    for(j=1; j<=size(RName); j++)
+    {
+      if (Name[i] == RName[j])
+      {
+        ERROR("Variable names should not include t,s");
+      }
+    }
+  }
+  // now, create the names for new vars
+  list DName;
+  for (i=1; i<=N; i++)
+  {
+    DName[i] = "D"+Name[i];  //concat
+  }
+  tmp[1] = "t";
+  tmp[2] = "s";
+  list NName = tmp + Name + DName;
+  L[2]   = NName;
+  // Name, Dname will be used further
+  kill NName;
+  // block ord (lp(2),dp);
+  tmp[1]  = "lp"; // string
+  iv      = 1,1;
+  tmp[2]  = iv; //intvec
+  Lord[1] = tmp;
+  // continue with dp 1,1,1,1...
+  tmp[1]  = "dp"; // string
+  s       = "iv=";
+  for (i=1; i<=Nnew; i++)
+  {
+    s = s+"1,";
+  }
+  s[size(s)]= ";";
+  execute(s);
+  kill s;
+  tmp[2]    = iv;
+  Lord[2]   = tmp;
+  tmp[1]    = "C";
+  iv        = 0;
+  tmp[2]    = iv;
+  Lord[3]   = tmp;
+  tmp       = 0;
+  L[3]      = Lord;
+  // we are done with the list
+  def @R@ = ring(L);
+  setring @R@;
+  matrix @D[Nnew][Nnew];
+  @D[1,2]=t;
+  for(i=1; i<=N; i++)
+  {
+    @D[2+i,N+2+i]=1;
+  }
+  // L[5] = matrix(UpOneMatrix(Nnew));
+  // L[6] = @D;
+  def @R = nc_algebra(1, at D);
+  setring @R;
+  kill @R@;
+  dbprint(ppl,"// -1-1- the ring @R(t,s,_x,_Dx) is ready");
+  dbprint(ppl-1, @R);
+  // create the ideal I
+  poly  F = imap(save,F);
+  ideal I = t*F+s;
+  poly p;
+  for(i=1; i<=N; i++)
+  {
+    p = t;  //t
+    p = diff(F,var(2+i))*p;
+    I = I, var(N+2+i) + p;
+  }
+  // -------- the ideal I is ready ----------
+  dbprint(ppl,"// -1-2- starting the elimination of t in @R");
+  dbprint(ppl-1, I);
+  ideal J = engine(I,eng);
+  ideal K = nselect(J,1);
+  kill I,J;
+  dbprint(ppl,"// -1-3- t is eliminated");
+  dbprint(ppl-1, K);  //K is without t
+  setring save;
+  // ----------- the ring @R2 ------------
+  // _x, _Dx,s;  elim.ord for _x,_Dx.
+  // keep: N, i,j,s, tmp, RL
+  Nnew = 2*N+1;
+  kill Lord, tmp, iv, RName;
+  list Lord, tmp;
+  intvec iv;
+  L[1] = RL[1];
+  L[4] = RL[4];  //char, minpoly
+  // check whether vars hava admissible names -> done earlier
+  // now, create the names for new var
+  tmp[1] = "s";
+  // DName is defined earlier
+  list NName = Name + DName + tmp;
+  L[2] = NName;
+  tmp = 0;
+  // block ord (dp(N),dp);
+  string s = "iv=";
+  for (i=1; i<=Nnew-1; i++)
+  {
+    s = s+"1,";
+  }
+  s[size(s)]=";";
+  execute(s);
+  tmp[1] = "dp";  //string
+  tmp[2] = iv;    //intvec
+  Lord[1] = tmp;
+  // continue with dp 1,1,1,1...
+  tmp[1] = "dp";  //string
+  s[size(s)] = ",";
+  s = s+"1;";
+  execute(s);
+  kill s;
+  kill NName;
+  tmp[2]  = iv;
+  Lord[2] = tmp;
+  tmp[1]  = "C";
+  iv      = 0;
+  tmp[2]  = iv;
+  Lord[3] = tmp;
+  tmp     = 0;
+  L[3]    = Lord;
+  // we are done with the list. Now add a Plural part
+  def @R2@ = ring(L);
+  setring @R2@;
+  matrix @D[Nnew][Nnew];
+  for (i=1; i<=N; i++)
+  {
+    @D[i,N+i]=1;
+  }
+  def @R2 = nc_algebra(1, at D);
+  setring @R2;
+  kill @R2@;
+  dbprint(ppl,"// -2-1- the ring @R2(_x,_Dx,s) is ready");
+  dbprint(ppl-1, @R2);
+  ideal MM = maxideal(1);
+  MM = 0,s,MM;
+  map R01 = @R, MM;
+  ideal K = R01(K);
+  poly F = imap(save,F);
+  K = K,F;
+  dbprint(ppl,"// -2-2- starting the elimination of _x,_Dx in @R2");
+  dbprint(ppl-1, K);
+  ideal M = engine(K,eng);
+  ideal K2 = nselect(M,1..Nnew-1);
+  kill K,M;
+  dbprint(ppl,"// -2-3- _x,_Dx are eliminated in @R2");
+  dbprint(ppl-1, K2);
+  // the ring @R3 and the search for minimal negative int s
+  ring @R3 = 0,s,dp;
+  dbprint(ppl,"// -3-1- the ring @R3(s) is ready");
+  ideal K3 = imap(@R2,K2);
+  poly p = K3[1];
+  dbprint(ppl,"// -3-2- factorization");
+  list P = factorize(p);          //with constants and multiplicities
+  ideal bs; intvec m;             //the Bernstein polynomial is monic, so we are not interested in constants
+  for (i=2; i<= size(P[1]); i++)  //we ignore P[1][1] (constant) and P[2][1] (its mult.)
+  {
+    bs[i-1] = P[1][i];
+    m[i-1]  = P[2][i];
+  }
+  // "--------- b-function factorizes into ---------";  P;
+  int sP = minIntRoot(bs,1);
+  dbprint(ppl,"// -3-3- minimal integer root found");
+  dbprint(ppl-1, sP);
+  // convert factors to a list of their roots
+  bs = normalize(bs);
+  bs = -subst(bs,s,0);
+  list BS = bs,m;
+  //TODO: sort BS!
+  // --------- substitute s found in the ideal ---------
+  // --------- going back to @R and substitute ---------
+  setring @R;
+  ideal K2 = subst(K,s,sP);
+  kill K;
+  // create the ordinary Weyl algebra and put the result into it,
+  // thus creating the ring @R4
+  // keep: N, i,j,s, tmp, RL
+  setring save;
+  Nnew = 2*N;
+  // list RL = ringlist(save);  //is defined earlier
+  kill Lord, tmp, iv;
+  L = 0;
+  list Lord, tmp;
+  intvec iv;
+  L[1] = RL[1];
+  L[4] = RL[4];  //char, minpoly
+  // check whether vars have admissible names -> done earlier
+  // list Name = RL[2]M
+  // DName is defined earlier
+  list NName = Name + DName;
+  L[2] = NName;
+  // dp ordering;
+  string s = "iv=";
+  for (i=1; i<=Nnew; i++)
+  {
+    s = s+"1,";
+  }
+  s[size(s)] = ";";
+  execute(s);
+  kill s;
+  tmp     = 0;
+  tmp[1]  = "dp";  //string
+  tmp[2]  = iv;    //intvec
+  Lord[1] = tmp;
+  tmp[1]  = "C";
+  iv      = 0;
+  tmp[2]  = iv;
+  Lord[2] = tmp;
+  tmp     = 0;
+  L[3]    = Lord;
+  // we are done with the list
+  // Add: Plural part
+  def @R4@ = ring(L);
+  setring @R4@;
+  matrix @D[Nnew][Nnew];
+  for (i=1; i<=N; i++)
+  {
+    @D[i,N+i]=1;
+  }
+  def @R4 = nc_algebra(1, at D);
+  setring @R4;
+  kill @R4@;
+  dbprint(ppl,"// -4-1- the ring @R4(_x,_Dx) is ready");
+  dbprint(ppl-1, @R4);
+  ideal K4 = imap(@R,K2);
+  intvec saveopt=option(get);
+  option(redSB);
+  dbprint(ppl,"// -4-2- the final cosmetic std");
+  K4 = engine(K4,eng);  //std does the job too
+  // total cleanup
+  kill @R;
+  kill @R2;
+  list BS = imap(@R3,BS);
+  export BS;
+  kill @R3;
+  ideal LD = K4;
+  export LD;
+  option(set,saveopt);
+  return(@R4);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y,z),Dp;
+  poly F = z*x^2+y^3;
+  printlevel = 0;
+  def A = annfsBM(F);
+  setring A;
+  LD;
+  BS;
+}
+
+
+// replacing s with -s-1 => data is shorter
+// analogue of annfs0
+proc annfs2(ideal I, poly F, list #)
+"USAGE:  annfs2(I, F [,eng]);  I an ideal, F a poly, eng an optional int
+RETURN:  ring
+PURPOSE: compute the annihilator ideal of f^s in the Weyl Algebra,
+@*       based on the output of Sannfs-like procedure
+@*       annfs2 uses shorter expressions in the variable s (the idea of Noro).
+NOTE: activate the output ring with the @code{setring} command. In this ring,
+@*      - the ideal LD (which is a Groebner basis) is the annihilator of f^s,
+@*      - the list BS contains the roots with multiplicities of the BS polynomial.
+@*    If eng <>0, @code{std} is used for Groebner basis computations,
+@*    otherwise and by default @code{slimgb} is used.
+DISPLAY: If @code{printlevel}=1, progress debug messages will be printed,
+@*       if @code{printlevel}>=2, all the debug messages will be printed.
+EXAMPLE: example annfs2; shows examples
+"
+{
+  int eng = 0;
+  if ( size(#)>0 )
+  {
+    if ( typeof(#[1]) == "int" )
+    {
+      eng = int(#[1]);
+    }
+  }
+  def @R2 = basering;
+  // we're in D_n[s], where the elim ord for s is set
+  ideal J = NF(I,std(F));
+  // make leadcoeffs positive
+  int i;
+  J = subst(J,s,-s-1);
+  for (i=1; i<= ncols(J); i++)
+  {
+    if (leadcoef(J[i]) <0 )
+    {
+      J[i] = -J[i];
+    }
+  }
+  J = J,F;
+  ideal M = engine(J,eng);
+  int Nnew = nvars(@R2);
+  ideal K2 = nselect(M,1..Nnew-1);
+  int ppl = printlevel-voice+2;
+  dbprint(ppl,"// -1-1- _x,_Dx are eliminated in basering");
+  dbprint(ppl-1, K2);
+  // the ring @R3 and the search for minimal negative int s
+  ring @R3 = 0,s,dp;
+  dbprint(ppl,"// -2-1- the ring @R3 i.e. K[s] is ready");
+  ideal K3 = imap(@R2,K2);
+  poly p = K3[1];
+  dbprint(ppl,"// -2-2- factorization");
+  //  ideal P = factorize(p,1);  //without constants and multiplicities
+  //  "--------- b-function factorizes into ---------";   P;
+  // convert factors to the list of their roots with mults
+  // assume all factors are linear
+  //  ideal BS = normalize(P);
+  //  BS = subst(BS,s,0);
+  //  BS = -BS;
+  list P = factorize(p);          //with constants and multiplicities
+  ideal bs; intvec m;             //the Bernstein polynomial is monic, so we are not interested in constants
+  for (i=2; i<= size(P[1]); i++)  //we delete P[1][1] and P[2][1]
+  {
+    bs[i-1] = P[1][i]; bs[i-1] = subst(bs[i-1],s,-s-1);
+    m[i-1]  = P[2][i];
+  }
+  int sP = minIntRoot(bs,1);
+  bs =  normalize(bs);
+  bs = -subst(bs,s,0);
+  dbprint(ppl,"// -2-3- minimal integer root found");
+  dbprint(ppl-1, sP);
+ //TODO: sort BS!
+  // --------- substitute s found in the ideal ---------
+  // --------- going back to @R and substitute ---------
+  setring @R2;
+  K2 = subst(I,s,sP);
+  // create the ordinary Weyl algebra and put the result into it,
+  // thus creating the ring @R5
+  // keep: N, i,j,s, tmp, RL
+  Nnew = Nnew - 1; // former 2*N;
+  // list RL = ringlist(save);  // is defined earlier
+  //  kill Lord, tmp, iv;
+  list L = 0;
+  list Lord, tmp;
+  intvec iv;
+  list RL = ringlist(basering);
+  L[1] = RL[1];
+  L[4] = RL[4];  //char, minpoly
+  // check whether vars have admissible names -> done earlier
+  // list Name = RL[2]M
+  // DName is defined earlier
+  list NName; // = RL[2]; // skip the last var 's'
+  for (i=1; i<=Nnew; i++)
+  {
+    NName[i] =  RL[2][i];
+  }
+  L[2] = NName;
+  // dp ordering;
+  string s = "iv=";
+  for (i=1; i<=Nnew; i++)
+  {
+    s = s+"1,";
+  }
+  s[size(s)] = ";";
+  execute(s);
+  tmp     = 0;
+  tmp[1]  = "dp";  // string
+  tmp[2]  = iv;  // intvec
+  Lord[1] = tmp;
+  kill s;
+  tmp[1]  = "C";
+  iv = 0;
+  tmp[2]  = iv;
+  Lord[2] = tmp;
+  tmp     = 0;
+  L[3]    = Lord;
+  // we are done with the list
+  // Add: Plural part
+  def @R4@ = ring(L);
+  setring @R4@;
+  int N = Nnew div 2;
+  matrix @D[Nnew][Nnew];
+  for (i=1; i<=N; i++)
+  {
+    @D[i,N+i]=1;
+  }
+  def @R4 = nc_algebra(1, at D);
+  setring @R4;
+  kill @R4@;
+  dbprint(ppl,"// -3-1- the ring @R4 is ready");
+  dbprint(ppl-1, @R4);
+  ideal K4 = imap(@R2,K2);
+  option(redSB);
+  dbprint(ppl,"// -3-2- the final cosmetic std");
+  K4 = engine(K4,eng);  // std does the job too
+  // total cleanup
+  ideal bs = imap(@R3,bs);
+  kill @R3;
+  list BS = bs,m;
+  export BS;
+  ideal LD = K4;
+  export LD;
+  return(@R4);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y,z),Dp;
+  poly F = x^3+y^3+z^3;
+  printlevel = 0;
+  def A = SannfsBM(F);
+  setring A;
+  LD;
+  poly F = imap(r,F);
+  def B  = annfs2(LD,F);
+  setring B;
+  LD;
+  BS;
+}
+
+// try to replace s with -s-1 => data is shorter as in annfs2
+// and use what Macaulay2 people call reduceB strategy, that is add
+// not F but Tjurina ideal <F,dF/dx1,...,dF/dxN>; the resulting B-function
+// has to be multiplied with (s+1) at the very end
+proc annfsRB(ideal I, poly F, list #)
+"USAGE:  annfsRB(I, F [,eng]);  I an ideal, F a poly, eng an optional int
+RETURN:  ring
+PURPOSE: compute the annihilator ideal of f^s in the Weyl Algebra,
+@* based on the output of Sannfs like procedure
+NOTE:    activate the output ring with the @code{setring} command. In this ring,
+@*       - the ideal LD (which is a Groebner basis) is the annihilator of f^s,
+@*       - the list BS contains the roots with multiplicities of a Bernstein polynomial of f.
+@*       If eng <>0, @code{std} is used for Groebner basis computations,
+@*       otherwise and by default @code{slimgb} is used.
+@*       This procedure uses in addition to F its Jacobian ideal.
+DISPLAY: If @code{printlevel}=1, progress debug messages will be printed,
+@*       if @code{printlevel}>=2, all the debug messages will be printed.
+EXAMPLE: example annfsRB; shows examples
+"
+{
+  int eng = 0;
+  if ( size(#)>0 )
+  {
+    if ( typeof(#[1]) == "int" )
+    {
+      eng = int(#[1]);
+    }
+  }
+  def @R2 = basering;
+  int ppl = printlevel-voice+2;
+  // we're in D_n[s], where the elim ord for s is set
+  // switch to comm. ring in X's and compute the GB of Tjurina ideal
+  dbprint(ppl,"// -1-0- creating K[x] and Tjurina ideal");
+  list nL = ringlist(@R2);
+  list temp,t2;
+  temp[1] = nL[1];
+  temp[4] = nL[4];
+  int @n = int((nvars(@R2)-1) div 2); // # of x's
+  int i;
+  for (i=1; i<=@n; i++)
+  {
+    t2[i] = nL[2][i];
+  }
+  temp[2] = t2;
+  t2 = 0;
+  t2[1] = nL[3][1]; // more weights than vars?
+  t2[2] = nL[3][3];
+  temp[3] = t2;
+  def @R22 = ring(temp);
+  setring @R22;
+  poly F = imap(@R2,F);
+  ideal J = F;
+  for (i=1; i<=@n; i++)
+  {
+    J = J, diff(F,var(i));
+  }
+  J = engine(J,eng);
+  dbprint(ppl,"// -1-1- finished computing the GB of Tjurina ideal");
+  dbprint(ppl-1, J);
+  setring @R2;
+  ideal JF = imap(@R22,J);
+  kill @R22;
+  attrib(JF,"isSB",1); // embedded comm ring is used
+  ideal J = NF(I,JF);
+  dbprint(ppl,"// -1-2- finished computing the NF of I w.r.t. Tjurina ideal");
+  dbprint(ppl-1, J2);
+  // make leadcoeffs positive
+  J = subst(J,s,-s-1);
+  for (i=1; i<= ncols(J); i++)
+  {
+    if (leadcoef(J[i]) <0 )
+    {
+      J[i] = -J[i];
+    }
+  }
+  J = J,JF;
+  ideal M = engine(J,eng);
+  int Nnew = nvars(@R2);
+  ideal K2 = nselect(M,1..Nnew-1);
+  dbprint(ppl,"// -2-0- _x,_Dx are eliminated in basering");
+  dbprint(ppl-1, K2);
+  // the ring @R3 and the search for minimal negative int s
+  ring @R3 = 0,s,dp;
+  dbprint(ppl,"// -2-1- the ring @R3 i.e. K[s] is ready");
+  ideal K3 = imap(@R2,K2);
+  poly p = K3[1];
+  p = s*p; // mult with the lost (s+1) factor
+  dbprint(ppl,"// -2-2- factorization");
+  //  ideal P = factorize(p,1);  //without constants and multiplicities
+  //  "--------- b-function factorizes into ---------";   P;
+  // convert factors to the list of their roots with mults
+  // assume all factors are linear
+  //  ideal BS = normalize(P);
+  //  BS = subst(BS,s,0);
+  //  BS = -BS;
+  list P = factorize(p);          //with constants and multiplicities
+  ideal bs; intvec m;             //the Bernstein polynomial is monic, so we are not interested in constants
+  for (i=2; i<= size(P[1]); i++)  //we delete P[1][1] and P[2][1]
+  {
+    bs[i-1] = P[1][i]; bs[i-1] = subst(bs[i-1],s,-s-1);
+    m[i-1]  = P[2][i];
+  }
+  int sP = minIntRoot(bs,1);
+  bs =  normalize(bs);
+  bs = -subst(bs,s,0);
+  dbprint(ppl,"// -2-3- minimal integer root found");
+  dbprint(ppl-1, sP);
+ //TODO: sort BS!
+  // --------- substitute s found in the ideal ---------
+  // --------- going back to @R and substitute ---------
+  setring @R2;
+  K2 = subst(I,s,sP);
+  // create the ordinary Weyl algebra and put the result into it,
+  // thus creating the ring @R5
+  // keep: N, i,j,s, tmp, RL
+  Nnew = Nnew - 1; // former 2*N;
+  // list RL = ringlist(save);  // is defined earlier
+  //  kill Lord, tmp, iv;
+  list L = 0;
+  list Lord, tmp;
+  intvec iv;
+  list RL = ringlist(basering);
+  L[1] = RL[1];
+  L[4] = RL[4];  //char, minpoly
+  // check whether vars have admissible names -> done earlier
+  // list Name = RL[2]M
+  // DName is defined earlier
+  list NName; // = RL[2]; // skip the last var 's'
+  for (i=1; i<=Nnew; i++)
+  {
+    NName[i] =  RL[2][i];
+  }
+  L[2] = NName;
+  // dp ordering;
+  string s = "iv=";
+  for (i=1; i<=Nnew; i++)
+  {
+    s = s+"1,";
+  }
+  s[size(s)] = ";";
+  execute(s);
+  tmp     = 0;
+  tmp[1]  = "dp";  // string
+  tmp[2]  = iv;  // intvec
+  Lord[1] = tmp;
+  kill s;
+  tmp[1]  = "C";
+  iv = 0;
+  tmp[2]  = iv;
+  Lord[2] = tmp;
+  tmp     = 0;
+  L[3]    = Lord;
+  // we are done with the list
+  // Add: Plural part
+  def @R4@ = ring(L);
+  setring @R4@;
+  int N = Nnew div 2;
+  matrix @D[Nnew][Nnew];
+  for (i=1; i<=N; i++)
+  {
+    @D[i,N+i]=1;
+  }
+  def @R4 = nc_algebra(1, at D);
+  setring @R4;
+  kill @R4@;
+  dbprint(ppl,"// -3-1- the ring @R4 is ready");
+  dbprint(ppl-1, @R4);
+  ideal K4 = imap(@R2,K2);
+  intvec saveopt=option(get);
+  option(redSB);
+  dbprint(ppl,"// -3-2- the final cosmetic std");
+  K4 = engine(K4,eng);  // std does the job too
+  // total cleanup
+  ideal bs = imap(@R3,bs);
+  kill @R3;
+  list BS = bs,m;
+  export BS;
+  ideal LD = K4;
+  export LD;
+  option(set,saveopt);
+  return(@R4);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y,z),Dp;
+  poly F = x^3+y^3+z^3;
+  printlevel = 0;
+  def A = SannfsBM(F); setring A;
+  LD; // s-parametric ahhinilator
+  poly F = imap(r,F);
+  def B  = annfsRB(LD,F); setring B;
+  LD;
+  BS;
+}
+
+proc operatorBM(poly F, list #)
+"USAGE:  operatorBM(f [,eng]);  f a poly, eng an optional int
+RETURN:  ring
+PURPOSE: compute the B-operator and other relevant data for Ann F^s,
+@*  using e.g. algorithm by Briancon and Maisonobe for Ann F^s and BS.
+NOTE:    activate the output ring with the @code{setring} command. In the output ring D[s]
+@*       - the polynomial F is the same as the input,
+@*       - the ideal LD is the annihilator of f^s in Dn[s],
+@*       - the ideal LD0 is the needed D-mod structure, where LD0 = LD|s=s0,
+@*       - the polynomial bs is the global Bernstein polynomial of f in the variable s,
+@*       - the list BS contains all the roots with multiplicities of the global Bernstein polynomial of f,
+@*       - the polynomial PS is an operator in Dn[s] such that PS*f^(s+1) = bs*f^s.
+@*       If eng <>0, @code{std} is used for Groebner basis computations,
+@*       otherwise and by default @code{slimgb} is used.
+DISPLAY: If @code{printlevel}=1, progress debug messages will be printed,
+@*       if @code{printlevel}>=2, all the debug messages will be printed.
+EXAMPLE: example operatorBM; shows examples
+"
+{
+  int eng = 0;
+  if ( size(#)>0 )
+  {
+    if ( typeof(#[1]) == "int" )
+    {
+      eng = int(#[1]);
+    }
+  }
+  // returns a list with a ring and an ideal LD in it
+  int ppl = printlevel-voice+2;
+  //  printf("plevel :%s, voice: %s",printlevel,voice);
+  def save = basering;
+  int N = nvars(basering);
+  int Nnew = 2*N+2;
+  int i,j;
+  string s;
+  list RL = ringlist(basering);
+  list L, Lord;
+  list tmp;
+  intvec iv;
+  L[1] = RL[1];  //char
+  L[4] = RL[4];  //char, minpoly
+  // check whether vars have admissible names
+  list Name  = RL[2];
+  list RName;
+  RName[1] = "t";
+  RName[2] = "s";
+  for (i=1; i<=N; i++)
+  {
+    for(j=1; j<=size(RName); j++)
+    {
+      if (Name[i] == RName[j])
+      {
+        ERROR("Variable names should not include t,s");
+      }
+    }
+  }
+  // now, create the names for new vars
+  list DName;
+  for (i=1; i<=N; i++)
+  {
+    DName[i] = "D"+Name[i];  //concat
+  }
+  tmp[1] = "t";
+  tmp[2] = "s";
+  list NName = tmp + Name + DName;
+  L[2]   = NName;
+  // Name, Dname will be used further
+  kill NName;
+  // block ord (lp(2),dp);
+  tmp[1]  = "lp"; // string
+  iv      = 1,1;
+  tmp[2]  = iv; //intvec
+  Lord[1] = tmp;
+  // continue with dp 1,1,1,1...
+  tmp[1]  = "dp"; // string
+  s       = "iv=";
+  for (i=1; i<=Nnew; i++)
+  {
+    s = s+"1,";
+  }
+  s[size(s)]= ";";
+  execute(s);
+  kill s;
+  tmp[2]    = iv;
+  Lord[2]   = tmp;
+  tmp[1]    = "C";
+  iv        = 0;
+  tmp[2]    = iv;
+  Lord[3]   = tmp;
+  tmp       = 0;
+  L[3]      = Lord;
+  // we are done with the list
+  def @R@ = ring(L);
+  setring @R@;
+  matrix @D[Nnew][Nnew];
+  @D[1,2]=t;
+  for(i=1; i<=N; i++)
+  {
+    @D[2+i,N+2+i]=1;
+  }
+  // L[5] = matrix(UpOneMatrix(Nnew));
+  // L[6] = @D;
+  def @R = nc_algebra(1, at D);
+  setring @R;
+  kill @R@;
+  dbprint(ppl,"// -1-1- the ring @R(t,s,_x,_Dx) is ready");
+  dbprint(ppl-1, @R);
+  // create the ideal I
+  poly  F = imap(save,F);
+  ideal I = t*F+s;
+  poly p;
+  for(i=1; i<=N; i++)
+  {
+    p = t;  //t
+    p = diff(F,var(2+i))*p;
+    I = I, var(N+2+i) + p;
+  }
+  // -------- the ideal I is ready ----------
+  dbprint(ppl,"// -1-2- starting the elimination of t in @R");
+  dbprint(ppl-1, I);
+  ideal J = engine(I,eng);
+  ideal K = nselect(J,1);
+  kill I,J;
+  dbprint(ppl,"// -1-3- t is eliminated");
+  dbprint(ppl-1, K);  //K is without t
+  setring save;
+  // ----------- the ring @R2 ------------
+  // _x, _Dx,s;  elim.ord for _x,_Dx.
+  // keep: N, i,j,s, tmp, RL
+  Nnew = 2*N+1;
+  kill Lord, tmp, iv, RName;
+  list Lord, tmp;
+  intvec iv;
+  L[1] = RL[1];
+  L[4] = RL[4];  //char, minpoly
+  // check whether vars hava admissible names -> done earlier
+  // now, create the names for new var
+  tmp[1] = "s";
+  // DName is defined earlier
+  list NName = Name + DName + tmp;
+  L[2] = NName;
+  tmp = 0;
+  // block ord (dp(N),dp);
+  string s = "iv=";
+  for (i=1; i<=Nnew-1; i++)
+  {
+    s = s+"1,";
+  }
+  s[size(s)]=";";
+  execute(s);
+  tmp[1] = "dp";  //string
+  tmp[2] = iv;    //intvec
+  Lord[1] = tmp;
+  // continue with dp 1,1,1,1...
+  tmp[1] = "dp";  //string
+  s[size(s)] = ",";
+  s = s+"1;";
+  execute(s);
+  kill s;
+  kill NName;
+  tmp[2]  = iv;
+  Lord[2] = tmp;
+  tmp[1]  = "C";
+  iv      = 0;
+  tmp[2]  = iv;
+  Lord[3] = tmp;
+  tmp     = 0;
+  L[3]    = Lord;
+  // we are done with the list. Now add a Plural part
+  def @R2@ = ring(L);
+  setring @R2@;
+  matrix @D[Nnew][Nnew];
+  for (i=1; i<=N; i++)
+  {
+    @D[i,N+i]=1;
+  }
+  def @R2 = nc_algebra(1, at D);
+  setring @R2;
+  kill @R2@;
+  dbprint(ppl,"// -2-1- the ring @R2(_x,_Dx,s) is ready");
+  dbprint(ppl-1, @R2);
+  ideal MM = maxideal(1);
+  MM = 0,s,MM;
+  map R01 = @R, MM;
+  ideal K = R01(K);
+  poly F = imap(save,F);
+  K = K,F;
+  dbprint(ppl,"// -2-2- starting the elimination of _x,_Dx in @R2");
+  dbprint(ppl-1, K);
+  ideal M = engine(K,eng);
+  ideal K2 = nselect(M,1..Nnew-1);
+  kill K,M;
+  dbprint(ppl,"// -2-3- _x,_Dx are eliminated in @R2");
+  dbprint(ppl-1, K2);
+  // the ring @R3 and the search for minimal negative int s
+  ring @R3 = 0,s,dp;
+  dbprint(ppl,"// -3-1- the ring @R3(s) is ready");
+  ideal K3 = imap(@R2,K2);
+  kill @R2;
+  poly p = K3[1];
+  dbprint(ppl,"// -3-2- factorization");
+  list P = factorize(p);          //with constants and multiplicities
+  ideal bs; intvec m;             //the Bernstein polynomial is monic, so we are not interested in constants
+  for (i=2; i<= size(P[1]); i++)  //we delete P[1][1] and P[2][1]
+  {
+    bs[i-1] = P[1][i];
+    m[i-1]  = P[2][i];
+  }
+  // "--------- b-function factorizes into ---------";  P;
+  int sP = minIntRoot(bs,1);
+  dbprint(ppl,"// -3-3- minimal integer root found");
+  dbprint(ppl-1, sP);
+  // convert factors to a list of their roots with multiplicities
+  bs = normalize(bs);
+  bs = -subst(bs,s,0);
+  list BS = bs,m;
+  //TODO: sort BS!
+  // --------- substitute s found in the ideal ---------
+  // --------- going back to @R and substitute ---------
+  setring @R;
+  ideal K2 = subst(K,s,sP);
+  // create Dn[s], where Dn is the ordinary Weyl algebra, and put the result into it,
+  // thus creating the ring @R4
+  // keep: N, i,j,s, tmp, RL
+  setring save;
+  Nnew = 2*N+1;
+  // list RL = ringlist(save);  //is defined earlier
+  kill Lord, tmp, iv;
+  L = 0;
+  list Lord, tmp;
+  intvec iv;
+  L[1] = RL[1];
+  L[4] = RL[4];  //char, minpoly
+  // check whether vars have admissible names -> done earlier
+  // list Name = RL[2]
+  // DName is defined earlier
+  tmp[1] = "s";
+  list NName = Name + DName + tmp;
+  L[2] = NName;
+  // dp ordering;
+  string s = "iv=";
+  for (i=1; i<=Nnew; i++)
+  {
+    s = s+"1,";
+  }
+  s[size(s)] = ";";
+  execute(s);
+  kill s;
+  tmp     = 0;
+  tmp[1]  = "dp";  //string
+  tmp[2]  = iv;    //intvec
+  Lord[1] = tmp;
+  tmp[1]  = "C";
+  iv      = 0;
+  tmp[2]  = iv;
+  Lord[2] = tmp;
+  tmp     = 0;
+  L[3]    = Lord;
+  // we are done with the list
+  // Add: Plural part
+  def @R4@ = ring(L);
+  setring @R4@;
+  matrix @D[Nnew][Nnew];
+  for (i=1; i<=N; i++)
+  {
+    @D[i,N+i]=1;
+  }
+  def @R4 = nc_algebra(1, at D);
+  setring @R4;
+  kill @R4@;
+  dbprint(ppl,"// -4-1- the ring @R4(_x,_Dx,s) is ready");
+  dbprint(ppl-1, @R4);
+  ideal LD0 = imap(@R,K2);
+  ideal LD  = imap(@R,K);
+  kill @R;
+  poly bs = imap(@R3,p);
+  list BS = imap(@R3,BS);
+  kill @R3;
+  bs = normalize(bs);
+  poly F = imap(save,F);
+  dbprint(ppl,"// -4-2- starting the computation of PS via lift");
+//better liftstd, I didn't knot it works also for Plural, liftslimgb?
+// liftstd may give extra coeffs in the resulting ideal
+  matrix T = lift(F+LD,bs);
+  poly PS = T[1,1];
+  dbprint(ppl,"// -4-3- an operator PS found, PS*f^(s+1) = b(s)*f^s");
+  dbprint(ppl-1,PS);
+  intvec saveopt=option(get);
+  option(redSB);
+  dbprint(ppl,"// -4-4- the final cosmetic std");
+  LD0 = engine(LD0,eng);  //std does the job too
+  LD  = engine(LD,eng);
+  export F,LD,LD0,bs,BS,PS;
+  option(set,saveopt);
+  return(@R4);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y,z),Dp;
+  poly F = x^3+y^3+z^3;
+  printlevel = 0;
+  def A = operatorBM(F);
+  setring A;
+  F; // the original polynomial itself
+  LD; // generic annihilator
+  LD0; // annihilator
+  bs; // normalized Bernstein poly
+  BS; // roots and multiplicities of the Bernstein poly
+  PS; // the operator, s.t. PS*F^{s+1} = bs*F^s mod LD
+  reduce(PS*F-bs,LD); // check the property of PS
+}
+
+// more interesting:
+//  ring r = 0,(x,y,z,w),Dp;
+//  poly F = x^3+y^3+z^2*w;
+
+// need: (c,<) ordering for such comp's
+
+proc operatorModulo(poly F, ideal I, poly b)
+"USAGE:  operatorModulo(f,I,b);  f a poly, I an ideal, b a poly
+RETURN:  poly
+PURPOSE: compute the B-operator from the polynomial f,
+@*           ideal I = Ann f^s and Bernstein-Sato polynomial b
+@*           using modulo i.e. kernel of module homomorphism
+NOTE:  The computations take place in the ring, similar to the one
+@*       returned by Sannfs procedure.
+@*     Note, that operator is not completely reduced wrt Ann f^{s+1}.
+@*     If printlevel=1, progress debug messages will be printed,
+@*     if printlevel>=2, all the debug messages will be printed.
+EXAMPLE: example operatorModulo; shows examples
+"
+{
+  int ppl = printlevel-voice+2;
+  def save = basering;
+  // change the ordering on the currRing
+  def mering = makeModElimRing(save);
+  setring mering;
+  poly b = imap(save, b);
+  poly F = imap(save, F);
+  ideal I = imap(save, I);
+  matrix N = matrix(I); // ann f^s
+  //  matrix K = hom_kernel(AA,M,N);
+  // option(noreturnSB)?
+  /// matrix K = modulo(AA,N); // too slow: do it with slim!
+    module M = b,-F;
+    dbprint(ppl,"starting modulo computation");
+    module K = moduloSlim(M,N);
+    dbprint(ppl,"finished modulo computation");
+    //    K = transpose(K);
+//     matrix M[3][s+2] = F,-b,I[1..s], 1,0:(s+1),0,1,0:(s);
+//     module GM = slimgb(M);
+//     module GMT = transpose(G);
+//     GMT = GMT[2],GMT[3]; // modulo matrix
+//     module K = GMT[2];
+//     GMT = transpose(GMT);
+//     K = transpose(K);
+//     matrix K = GMT;
+//////////////////////////////////////////////////
+//  now select those elts whose 0's entry is nonzero
+// if there is constant => done
+// if not => compute GB and get it
+    module L;
+    ideal J;
+    int i;
+    poly t; number n;
+    for(i=1; i<=ncols(K); i++)
+    {
+      if (K[1,i]!=0)
+      {
+        L = L,K[i];
+        if ( leadmonom(K[1,i]) == 1)
+        {
+          t = K[2,i];
+          n = leadcoef(K[1,i]);
+          t = t/n;
+          break;
+          //          return(t);
+        }
+      }
+    }
+    if (n!=0)
+    {
+      // constant found
+      setring save; poly t = imap(mering,t); kill mering;
+      return(t);
+    }
+    dbprint(ppl,"no explicit constant. Start one more GB computation");
+    // else: compute GB and do the same
+    L = L[2..ncols(L)];
+    K  = slimgb(L);
+    dbprint(ppl,"finished GB computation");
+    for(i=1; i<=ncols(K); i++)
+    {
+      if (K[1,i]!=0)
+      {
+        if ( leadmonom(K[1,i]) == 1)
+        {
+          t = K[2,i];
+          n = leadcoef(K[1,i]);
+          t = t/n;
+//          break;
+          setring save; poly t = imap(mering,t); kill mering;
+          return(t);
+        }
+      }
+    }
+
+    // we are here if no constant found
+    "ERROR: must never get here!";
+    return(0);
+//     for(i=1; i<=nrows(K); i++)
+//     {
+//       if (K[i,2]!=0)
+//       {
+//         if ( leadmonom(K[i,2]) == 1)
+//         {
+//           t = K[i,1];
+//           n = leadcoef(K[i,2]);
+//           t = t/n;
+// //        J = J, K[i][2];
+//           break;
+//         }
+//      }
+//   }
+//   ideal J = groebner(subst(I,s,s+1)); // for NF
+//   t = NF(t,J);
+//   "candidate:"; t;
+//   J = subst(J,s,s-1);
+//   // test:
+//   if ( NF(t*F-b,J) !=0)
+//   {
+//     "Problem: PS does not work on F";
+//   }
+//   return(t);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  //  LIB "dmod.lib"; option(prot); option(mem);
+  ring r = 0,(x,y),Dp;
+  poly F = x^3+y^3+x*y^3;
+  def A = Sannfs(F); // here we get LD = ann f^s
+  setring A;
+  poly F = imap(r,F);
+  def B = annfs0(LD,F); // to obtain BS polynomial
+  list BS = imap(B,BS);   poly bs = fl2poly(BS,"s");
+  poly PS = operatorModulo(F,LD,bs);
+  LD = groebner(LD);
+  PS = NF(PS,subst(LD,s,s+1));; // reduction modulo Ann s^{s+1}
+  size(PS);
+  lead(PS);
+  reduce(PS*F-bs,LD); // check the defining property of PS
+}
+
+proc annfsParamBM (poly F, list #)
+"USAGE:  annfsParamBM(f [,eng]);  f a poly, eng an optional int
+RETURN:  ring
+PURPOSE: compute the generic Ann F^s and exceptional parametric constellations
+@* of a polynomial with parametric coefficients with the BM algorithm
+NOTE:    activate the output ring with the @code{setring} command. In this ring,
+@*       - the ideal LD is the D-module structure oa Ann F^s
+@*       - the ideal Param contains special parameters as entries
+@*       If eng <>0, @code{std} is used for Groebner basis computations,
+@*       otherwise, and by default @code{slimgb} is used.
+DISPLAY: If @code{printlevel}=1, progress debug messages will be printed,
+@*          if @code{printlevel}>=2, all the debug messages will be printed.
+EXAMPLE: example annfsParamBM; shows examples
+"
+{
+  //PURPOSE: compute the list of all possible Bernstein-Sato polynomials for a polynomial with parametric coefficients, according to the algorithm by Briancon and Maisonobe
+  // @*       - the list BS is the list of roots and multiplicities of a Bernstein polynomial of f.
+  // ***** not implented yet ****
+  int eng = 0;
+  if ( size(#)>0 )
+  {
+    if ( typeof(#[1]) == "int" )
+    {
+      eng = int(#[1]);
+    }
+  }
+  // returns a list with a ring and an ideal LD in it
+  int ppl = printlevel-voice+2;
+  //  printf("plevel :%s, voice: %s",printlevel,voice);
+  def save = basering;
+  int N = nvars(basering);
+  int Nnew = 2*N+2;
+  int i,j;
+  string s;
+  list RL = ringlist(basering);
+  list L, Lord;
+  list tmp;
+  intvec iv;
+  L[1] = RL[1];  //char
+  L[4] = RL[4];  //char, minpoly
+  // check whether vars have admissible names
+  list Name  = RL[2];
+  list RName;
+  RName[1] = "t";
+  RName[2] = "s";
+  for (i=1; i<=N; i++)
+  {
+    for(j=1; j<=size(RName); j++)
+    {
+      if (Name[i] == RName[j])
+      {
+        ERROR("Variable names should not include t,s");
+      }
+    }
+  }
+  // now, create the names for new vars
+  list DName;
+  for (i=1; i<=N; i++)
+  {
+    DName[i] = "D"+Name[i];  //concat
+  }
+  tmp[1] = "t";
+  tmp[2] = "s";
+  list NName = tmp + Name + DName;
+  L[2]   = NName;
+  // Name, Dname will be used further
+  kill NName;
+  // block ord (lp(2),dp);
+  tmp[1]  = "lp"; // string
+  iv      = 1,1;
+  tmp[2]  = iv; //intvec
+  Lord[1] = tmp;
+  // continue with dp 1,1,1,1...
+  tmp[1]  = "dp"; // string
+  s       = "iv=";
+  for (i=1; i<=Nnew; i++)
+  {
+    s = s+"1,";
+  }
+  s[size(s)]= ";";
+  execute(s);
+  kill s;
+  tmp[2]    = iv;
+  Lord[2]   = tmp;
+  tmp[1]    = "C";
+  iv        = 0;
+  tmp[2]    = iv;
+  Lord[3]   = tmp;
+  tmp       = 0;
+  L[3]      = Lord;
+  // we are done with the list
+  def @R@ = ring(L);
+  setring @R@;
+  matrix @D[Nnew][Nnew];
+  @D[1,2]=t;
+  for(i=1; i<=N; i++)
+  {
+    @D[2+i,N+2+i]=1;
+  }
+  // L[5] = matrix(UpOneMatrix(Nnew));
+  // L[6] = @D;
+  def @R = nc_algebra(1, at D);
+  setring @R;
+  kill @R@;
+  dbprint(ppl,"// -1-1- the ring @R(t,s,_x,_Dx) is ready");
+  dbprint(ppl-1, @R);
+  // create the ideal I
+  poly  F = imap(save,F);
+  ideal I = t*F+s;
+  poly p;
+  for(i=1; i<=N; i++)
+  {
+    p = t;  //t
+    p = diff(F,var(2+i))*p;
+    I = I, var(N+2+i) + p;
+  }
+  // -------- the ideal I is ready ----------
+  dbprint(ppl,"// -1-2- starting the elimination of t in @R");
+  dbprint(ppl-1, I);
+  ideal J = engine(I,eng);
+  ideal K = nselect(J,1);
+  dbprint(ppl,"// -1-3- t is eliminated");
+  dbprint(ppl-1, K);  //K is without t
+  // ----- looking for special parameters -----
+  dbprint(ppl,"// -2-1- starting the computation of the transformation matrix (via lift)");
+  J = normalize(J);
+  matrix T = lift(I,J);  //try also with liftstd
+  kill I,J;
+  dbprint(ppl,"// -2-2- the transformation matrix has been computed");
+  dbprint(ppl-1, T);  //T is the transformation matrix
+  dbprint(ppl,"// -2-3- genericity does the job");
+  list lParam = genericity(T);
+  int ip = size(lParam);
+  int cip;
+  string sParam;
+  if (sParam[1]=="-") { sParam=""; } //genericity returns "-"
+  // if no parameters exist in a basering
+  for (cip=1; cip <= ip; cip++)
+  {
+    sParam = sParam + "," +lParam[cip];
+  }
+  if (size(sParam) >=2)
+  {
+    sParam = sParam[2..size(sParam)]; // removes the 1st colon
+  }
+  export sParam;
+  kill T;
+  dbprint(ppl,"// -2-4- the special parameters has been computed");
+  dbprint(ppl, sParam);
+  // create Dn[s], where Dn is the ordinary Weyl Algebra, and put the result into it,
+  // thus creating the ring @R2
+  // keep: N, i,j,s, tmp, RL
+  setring save;
+  Nnew = 2*N+1;
+  // list RL = ringlist(save);  //is defined earlier
+  kill Lord, tmp, iv;
+  L = 0;
+  list Lord, tmp;
+  intvec iv;
+  L[1] = RL[1];
+  L[4] = RL[4];  //char, minpoly
+  // check whether vars have admissible names -> done earlier
+  // list Name = RL[2]M
+  // DName is defined earlier
+  tmp[1] = "s";
+  list NName = Name + DName + tmp;
+  L[2] = NName;
+  // dp ordering;
+  string s = "iv=";
+  for (i=1; i<=Nnew; i++)
+  {
+    s = s+"1,";
+  }
+  s[size(s)] = ";";
+  execute(s);
+  kill s;
+  tmp     = 0;
+  tmp[1]  = "dp";  //string
+  tmp[2]  = iv;    //intvec
+  Lord[1] = tmp;
+  tmp[1]  = "C";
+  iv      = 0;
+  tmp[2]  = iv;
+  Lord[2] = tmp;
+  tmp     = 0;
+  L[3]    = Lord;
+  // we are done with the list
+  // Add: Plural part
+  def @R2@ = ring(L);
+  setring @R2@;
+  matrix @D[Nnew][Nnew];
+  for (i=1; i<=N; i++)
+  {
+    @D[i,N+i]=1;
+  }
+  def @R2 = nc_algebra(1, at D);
+  setring @R2;
+  kill @R2@;
+  dbprint(ppl,"// -3-1- the ring @R2(_x,_Dx,s) is ready");
+  dbprint(ppl-1, @R2);
+  ideal K = imap(@R,K);
+  kill @R;
+  intvec saveopt=option(get);
+  option(redSB);
+  dbprint(ppl,"// -3-2- the final cosmetic std");
+  K = engine(K,eng);  //std does the job too
+  ideal LD = K;
+  export LD;
+  if (sParam[1] == ",")
+  {
+    sParam = sParam[2..size(sParam)];
+  }
+  //  || ((sParam[1] == " ") && (sParam[2] == ",")))
+  execute("ideal Param ="+sParam+";");
+  export Param;
+  kill sParam;
+  option(set,saveopt);
+  return(@R2);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = (0,a,b),(x,y),Dp;
+  poly F = x^2 - (y-a)*(y-b);
+  printlevel = 0;
+  def A = annfsParamBM(F);  setring A;
+  LD;
+  Param;
+  setring r;
+  poly G = x2-(y-a)^2; // try the exceptional value b=a of parameters
+  def B = annfsParamBM(G); setring B;
+  LD;
+  Param;
+}
+
+// *** the following example is nice, but too complicated for the documentation ***
+//   ring r = (0,a),(x,y,z),Dp;
+//   poly F = x^4+y^4+z^2+a*x*y*z;
+//   printlevel = 2; //0
+//   def A = annfsParamBM(F);
+//   setring A;
+//   LD;
+//   Param;
+
+
+proc annfsBMI(ideal F, list #)
+"USAGE:  annfsBMI(F [,eng,met,us]);  F an ideal, eng, met, us optional ints
+RETURN:  ring
+PURPOSE: compute two kinds of Bernstein-Sato ideals, associated to
+@* f = F[1]*..*F[P], with the multivariate algorithm by Briancon and Maisonobe.
+NOTE:    activate the output ring with the @code{setring} command. In this ring,
+@*       - the ideal LD is the annihilator of F[1]^s_1*..*F[P]^s_p,
+@*       - the list or ideal BS is a Bernstein-Sato ideal of a polynomial f = F[1]*..*F[P].
+@*       If eng <>0, @code{std} is used for Groebner basis computations,
+@*       otherwise, and by default @code{slimgb} is used.
+@*       If met <0, the B-Sigma ideal (cf. Castro and Ucha,
+@*       'On the computation of Bernstein-Sato ideals', 2005) is computed.
+@*       If 0 < met < P, then the ideal B_P (cf. the paper) is computed.
+@*       Otherwise, and by default, the ideal B (cf. the paper) is computed.
+@*       If us<>0, then syzygies-driven method is used.
+@*       If the output ideal happens to be principal, the list of factors
+@*       with their multiplicities is returned instead of the ideal.
+@*       If printlevel=1, progress debug messages will be printed,
+@*       if printlevel>=2, all the debug messages will be printed.
+EXAMPLE: example annfsBMI; shows examples
+"
+{
+  int eng = 0;
+  int met = 0;
+  int usesyz = 0;
+  if ( size(#)>0 )
+  {
+    if ( typeof(#[1]) == "int" )
+    {
+      eng = int(#[1]);
+    }
+    if ( size(#)>1 )
+    {
+      if ( typeof(#[2]) == "int" )
+      {
+        met = int(#[2]);
+      }
+    }
+    if ( size(#)>2 )
+    {
+      if ( typeof(#[3]) == "int" )
+      {
+        usesyz = int(#[3]);
+      }
+    }
+
+  }
+  // returns a list with a ring and an ideal LD in it
+  int ppl = printlevel-voice+2;
+  //  printf("plevel :%s, voice: %s",printlevel,voice);
+  def save = basering;
+  int N = nvars(basering);
+  //if F has some generators which are zero, int P = ncols(I);
+  int P = size(F);
+  if (P < ncols(F))
+  {
+    F = simplify(F,2);
+  }
+  P = size(F);
+  if (P == 0)
+  {
+    ERROR("zero ideal in the input");
+  }
+  int Nnew = 2*N+2*P;
+  int i,j;
+  string s;
+  list RL = ringlist(basering);
+  list L, Lord;
+  list tmp;
+  intvec iv;
+  L[1] = RL[1];  //char
+  L[4] = RL[4];  //char, minpoly
+  // check whether vars have admissible names
+  list Name  = RL[2];
+  list RName;
+  for (j=1; j<=P; j++)
+  {
+    RName[j] = "t("+string(j)+")";
+    RName[j+P] = "s("+string(j)+")";
+  }
+  for(i=1; i<=N; i++)
+  {
+    for(j=1; j<=size(RName); j++)
+    {
+      if (Name[i] == RName[j])
+      { ERROR("Variable names should not include t(i),s(i)"); }
+    }
+  }
+  // now, create the names for new vars
+  list DName;
+  for(i=1; i<=N; i++)
+  {
+    DName[i] = "D"+Name[i];  //concat
+  }
+  list NName = RName + Name + DName;
+  L[2]   = NName;
+  // Name, Dname will be used further
+  kill NName;
+  // block ord (lp(P),dp);
+  tmp[1] = "lp";  //string
+  s      = "iv=";
+  for (i=1; i<=2*P; i++)
+  {
+    s = s+"1,";
+  }
+  s[size(s)]= ";";
+  execute(s);
+  tmp[2] = iv;  //intvec
+  Lord[1] = tmp;
+  // continue with dp 1,1,1,1...
+  tmp[1] = "dp";  //string
+  s      = "iv=";
+  for (i=1; i<=Nnew; i++)  //actually i<=2*N
+  {
+    s = s+"1,";
+  }
+  s[size(s)]= ";";
+  execute(s);
+  kill s;
+  tmp[2]  = iv;
+  Lord[2] = tmp;
+  tmp[1]  = "C";
+  iv      = 0;
+  tmp[2]  = iv;
+  Lord[3] = tmp;
+  tmp     = 0;
+  L[3]    = Lord;
+  // we are done with the list
+  def @R@ = ring(L);
+  setring @R@;
+  matrix @D[Nnew][Nnew];
+  for (i=1; i<=P; i++)
+  {
+    @D[i,i+P] = t(i);
+  }
+  for(i=1; i<=N; i++)
+  {
+    @D[2*P+i,2*P+N+i] = 1;
+  }
+  // L[5] = matrix(UpOneMatrix(Nnew));
+  // L[6] = @D;
+  def @R = nc_algebra(1, at D);
+  setring @R;
+  kill @R@;
+  dbprint(ppl,"// -1-1- the ring @R(_t,_s,_x,_Dx) is ready");
+  dbprint(ppl-1, @R);
+  // create the ideal I
+  ideal  F = imap(save,F);
+  ideal I = t(1)*F[1]+s(1);
+  for (j=2; j<=P; j++)
+  {
+    I = I, t(j)*F[j]+s(j);
+  }
+  poly p,q;
+  for (i=1; i<=N; i++)
+  {
+    p=0;
+    for (j=1; j<=P; j++)
+    {
+      q = t(j);
+      q = diff(F[j],var(2*P+i))*q;
+      p = p + q;
+    }
+    I = I, var(2*P+N+i) + p;
+  }
+  // -------- the ideal I is ready ----------
+  if (usesyz)
+  {
+    dbprint(ppl,"// -1-1-1 adding syzygy-driven elements to the ideal");
+    // -- form the extended Jacobian matrix; do the comps over K[x]
+    setring save;
+    module JC = module(transpose(jacob(F))); // NxP
+    for (j=1; j<=P; j++)
+    {
+      JC[j] = JC[j] + F[j]*gen(N+j);
+    }
+    //    matrix JAC[N+P][P];
+    dbprint(ppl,"// -1-1-2 computing syzygies of the extended Jacobian matrix over K[_x]");
+    dbprint(ppl-1, matrix(JC));
+    matrix SJ = transpose(syz(transpose(JC))); //or of std(syz)?
+    dbprint(ppl,"// -1-1-3 finished computing syzygies of the ext Jacobian matrix over K[_x]");
+    dbprint(ppl-1, matrix(SJ));
+    setring @R;
+    // add generators: first N comps d_i, then P comps s_j
+    matrix SJ = imap(save, SJ);
+    poly pi;
+    for (i=1; i<=nrows(SJ); i++)
+    {
+      pi = 0;
+      for (j=1; j<=N; j++)
+      {
+        pi = pi + SJ[i,j]*var(2*P+N+j);
+      }
+      for (j=1; j<=P; j++)
+      {
+        pi = pi + SJ[i,N+j]*s(j);
+      }
+      dbprint(ppl-1, "// -1-1-4 adding element:" + string(pi));
+      I = I, pi;
+    }
+  }
+  dbprint(ppl,"// -1-2- starting the elimination of "+string(t(1..P))+" in @R");
+  dbprint(ppl-1, I);
+  ideal J = engine(I,eng);
+  ideal K = nselect(J,1..P);
+  kill I,J;
+  dbprint(ppl,"// -1-3- all t(i) are eliminated");
+  dbprint(ppl-1, K);  //K is without t(i)
+  // ----------- the ring @R2 ------------
+  // _x, _Dx,s;  elim.ord for _x,_Dx.
+  // keep: N, i,j,s, tmp, RL
+  setring save;
+  Nnew = 2*N+P;
+  kill Lord, tmp, iv, RName;
+  list Lord, tmp;
+  intvec iv;
+  L[1] = RL[1];  //char
+  L[4] = RL[4];  //char, minpoly
+  // check whether vars hava admissible names -> done earlier
+  // now, create the names for new var
+  for (j=1; j<=P; j++)
+  {
+    tmp[j] = "s("+string(j)+")";
+  }
+  // DName is defined earlier
+  list NName = Name + DName + tmp;
+  L[2] = NName;
+  tmp = 0;
+  // block ord (dp(N),dp);
+  string s = "iv=";
+  for (i=1; i<=Nnew-P; i++)
+  {
+    s = s+"1,";
+  }
+  s[size(s)]=";";
+  execute(s);
+  tmp[1] = "dp";  //string
+  tmp[2] = iv;    //intvec
+  Lord[1] = tmp;
+  // continue with dp 1,1,1,1...
+  tmp[1] = "dp";  //string
+  s[size(s)] = ",";
+  for (j=1; j<=P; j++)
+  {
+    s = s+"1,";
+  }
+  s[size(s)]=";";
+  execute(s);
+  kill s;
+  kill NName;
+  tmp[2]  = iv;
+  Lord[2] = tmp;
+  tmp[1]  = "C";
+  iv      = 0;
+  tmp[2]  = iv;
+  Lord[3] = tmp;
+  tmp     = 0;
+  L[3]    = Lord;
+  // we are done with the list. Now add a Plural part
+  def @R2@ = ring(L);
+  setring @R2@;
+  matrix @D[Nnew][Nnew];
+  for (i=1; i<=N; i++)
+  {
+    @D[i,N+i]=1;
+  }
+  def @R2 = nc_algebra(1, at D);
+  setring @R2;
+  kill @R2@;
+  dbprint(ppl,"// -2-1- the ring @R2(_x,_Dx,_s) is ready");
+  dbprint(ppl-1, @R2);
+//  ideal MM = maxideal(1);
+//  MM = 0,s,MM;
+//  map R01 = @R, MM;
+//  ideal K = R01(K);
+  ideal F = imap(save,F);  // maybe ideal F = R01(I); ?
+  ideal K = imap(@R,K);    // maybe ideal K = R01(I); ?
+
+  if (met <0)
+  {
+  //K = K,F;     // to compute Bsigma (see "On the computation of Bernstein-Sato ideals"; Castro, Ucha)
+    K = K,F;
+    dbprint(ppl,"// -2-1-1 computing the ideal B-Sigma from Castro-Ucha");
+  }
+  if ( (met>0) && (met<=ncols(F) ) )
+  {
+  /* compute the ideal B_met */
+  //j=2;         // for example
+  //K = K,F[j];  // to compute Bj (see "On the computation of Bernstein-Sato ideals"; Castro, Ucha)
+    dbprint(ppl,"// -2-1-1 computing the ideal B_i from Castro-Ucha");
+    K = K, F[met];
+  }
+  if ( ( met == 0) || (met > ncols(F) ) )
+  {
+    // that is met ==0 or met> ncols(F)
+    /* compute the ideal B */
+    poly f=1;
+    for (j=1; j<=P; j++)
+    {
+      f = f*F[j];
+    }
+    K = K,f;       // to compute B (Bernstein-Sato ideal)
+    dbprint(ppl,"// -2-1-1 computing the ideal B from Castro-Ucha");
+  }
+  dbprint(ppl,"// -2-2- starting the elimination of _x,_Dx in @R2");
+  dbprint(ppl-1, K);
+  ideal M = engine(K,eng);
+  ideal K2 = nselect(M,1..Nnew-P);
+  kill K,M;
+  dbprint(ppl,"// -2-3- _x,_Dx are eliminated in @R2");
+  dbprint(ppl-1, K2);
+  // the ring @R3 and factorize
+  ring @R3 = 0,s(1..P),dp;
+  dbprint(ppl,"// -3-1- the ring @R3(_s) is ready");
+  ideal K3 = imap(@R2,K2);
+  if (ncols(K3)==1)
+  {
+    poly p = K3[1];
+    dbprint(ppl,"// -3-2- the Bernstein ideal is principal");
+    dbprint(ppl,"// -3-2-1- factorization");
+    // Warning: now P is an integer
+    list Q = factorize(p);         //with constants and multiplicities
+    ideal bs; intvec m;
+    for (i=2; i<=size(Q[1]); i++)  //we delete Q[1][1] and Q[2][1]
+    {
+      bs[i-1] = Q[1][i];
+      m[i-1]  = Q[2][i];
+    }
+    //  "--------- Q-ideal factorizes into ---------";  list(bs,m);
+    list BS = bs,m;
+  }
+  else
+  {
+    // conjecture for some ideals: the Bernstein ideal is principal
+    dbprint(ppl,"// -3-2- the Bernstein ideal is not principal");
+    ideal BS = K3;
+  }
+  // create the ring @R4(_x,_Dx,_s) and put the result into it,
+  // _x, _Dx,s;  ord "dp".
+  // keep: N, i,j,s, tmp, RL
+  setring save;
+  Nnew = 2*N+P;
+  // list RL = ringlist(save);  //is defined earlier
+  kill Lord, tmp, iv;
+  L = 0;
+  list Lord, tmp;
+  intvec iv;
+  L[1] = RL[1];  //char
+  L[4] = RL[4];  //char, minpoly
+  // check whether vars hava admissible names -> done earlier
+  // now, create the names for new var
+  for (j=1; j<=P; j++)
+  {
+    tmp[j] = "s("+string(j)+")";
+  }
+  // DName is defined earlier
+  list NName = Name + DName + tmp;
+  L[2] = NName;
+  tmp = 0;
+  // dp ordering;
+  string s = "iv=";
+  for (i=1; i<=Nnew; i++)
+  {
+    s = s+"1,";
+  }
+  s[size(s)]=";";
+  execute(s);
+  kill s;
+  kill NName;
+  tmp[1] = "dp";  //string
+  tmp[2] = iv;    //intvec
+  Lord[1] = tmp;
+  tmp[1]  = "C";
+  iv      = 0;
+  tmp[2]  = iv;
+  Lord[2] = tmp;
+  tmp     = 0;
+  L[3]    = Lord;
+  // we are done with the list. Now add a Plural part
+  def @R4@ = ring(L);
+  setring @R4@;
+  matrix @D[Nnew][Nnew];
+  for (i=1; i<=N; i++)
+  {
+    @D[i,N+i]=1;
+  }
+  def @R4 = nc_algebra(1, at D);
+  setring @R4;
+  kill @R4@;
+  dbprint(ppl,"// -4-1- the ring @R4i(_x,_Dx,_s) is ready");
+  dbprint(ppl-1, @R4);
+  ideal K4 = imap(@R,K);
+  intvec saveopt=option(get);
+  option(redSB);
+  dbprint(ppl,"// -4-2- the final cosmetic std");
+  K4 = engine(K4,eng);  //std does the job too
+  // total cleanup
+  kill @R;
+  kill @R2;
+  def BS = imap(@R3,BS);
+  export BS;
+  kill @R3;
+  ideal LD = K4;
+  export LD;
+  option(set,saveopt);
+  return(@R4);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y),Dp;
+  ideal F = x,y,x+y;
+  printlevel = 0;
+  // *1* let us compute the B ideal
+  def A = annfsBMI(F);    setring A;
+  LD; // annihilator
+  BS; // Bernstein-Sato ideal
+  // *2* now, let us compute B-Sigma ideal
+  setring r;
+  def Sigma = annfsBMI(F,0,-1); setring Sigma;
+  print(matrix(lead(LD))); // compact form of leading
+  //  monomials from the annihilator
+  BS; // Bernstein-Sato B-Sigma ideal: it is principal,
+  // so factors and multiplicities are returned
+  // *3* and now, let us compute B-i ideal
+  setring r;
+  def Bi = annfsBMI(F,0,3); // that is F[3]=x+y is taken
+  setring Bi;
+  print(matrix(lead(LD)));   // compact form of leading
+  //  monomials from the annihilator
+  BS; // the B_3 ideal: it is principal, so factors
+  // and multiplicities are returned
+}
+
+proc annfsOT(poly F, list #)
+"USAGE:  annfsOT(f [,eng]);  f a poly, eng an optional int
+RETURN:  ring
+PURPOSE: compute the D-module structure of basering[1/f]*f^s,
+@* according to the algorithm by Oaku and Takayama
+NOTE:    activate the output ring with the @code{setring} command. In this ring,
+@*       - the ideal LD (which is a Groebner basis) is the needed D-module structure,
+@*         which is obtained by substituting the minimal integer root of a Bernstein
+@*         polynomial into the s-parametric ideal;
+@*       - the list BS contains roots with multiplicities of a Bernstein polynomial of f.
+@*       If eng <>0, @code{std} is used for Groebner basis computations,
+@*       otherwise, and by default @code{slimgb} is used.
+@*       If printlevel=1, progress debug messages will be printed,
+@*       if printlevel>=2, all the debug messages will be printed.
+EXAMPLE: example annfsOT; shows examples
+"
+{
+  int eng = 0;
+  if ( size(#)>0 )
+  {
+    if ( typeof(#[1]) == "int" )
+    {
+      eng = int(#[1]);
+    }
+  }
+  // returns a list with a ring and an ideal LD in it
+  int ppl = printlevel-voice+2;
+  //  printf("plevel :%s, voice: %s",printlevel,voice);
+  def save = basering;
+  int N = nvars(basering);
+  int Nnew = 2*(N+2);
+  int i,j;
+  string s;
+  list RL = ringlist(basering);
+  list L, Lord;
+  list tmp;
+  intvec iv;
+  L[1] = RL[1]; // char
+  L[4] = RL[4]; // char, minpoly
+  // check whether vars have admissible names
+  list Name  = RL[2];
+  list RName;
+  RName[1] = "u";
+  RName[2] = "v";
+  RName[3] = "t";
+  RName[4] = "Dt";
+  for(i=1;i<=N;i++)
+  {
+    for(j=1; j<=size(RName);j++)
+    {
+      if (Name[i] == RName[j])
+      {
+        ERROR("Variable names should not include u,v,t,Dt");
+      }
+    }
+  }
+  // now, create the names for new vars
+  tmp[1]     = "u";
+  tmp[2]     = "v";
+  list UName = tmp;
+  list DName;
+  for(i=1;i<=N;i++)
+  {
+    DName[i] = "D"+Name[i]; // concat
+  }
+  tmp    =  0;
+  tmp[1] = "t";
+  tmp[2] = "Dt";
+  list NName = UName +  tmp + Name + DName;
+  L[2]   = NName;
+  tmp    = 0;
+  // Name, Dname will be used further
+  kill UName;
+  kill NName;
+  // block ord (a(1,1),dp);
+  tmp[1]  = "a"; // string
+  iv      = 1,1;
+  tmp[2]  = iv; //intvec
+  Lord[1] = tmp;
+  // continue with dp 1,1,1,1...
+  tmp[1]  = "dp"; // string
+  s       = "iv=";
+  for(i=1;i<=Nnew;i++)
+  {
+    s = s+"1,";
+  }
+  s[size(s)]= ";";
+  execute(s);
+  tmp[2]    = iv;
+  Lord[2]   = tmp;
+  tmp[1]    = "C";
+  iv        = 0;
+  tmp[2]    = iv;
+  Lord[3]   = tmp;
+  tmp       = 0;
+  L[3]      = Lord;
+  // we are done with the list
+  def @R@ = ring(L);
+  setring @R@;
+  matrix @D[Nnew][Nnew];
+  @D[3,4]=1;
+  for(i=1; i<=N; i++)
+  {
+    @D[4+i,N+4+i]=1;
+  }
+  //  @D[N+3,2*(N+2)]=1; old t,Dt stuff
+  //  L[5] = matrix(UpOneMatrix(Nnew));
+  //  L[6] = @D;
+  def @R = nc_algebra(1, at D);
+  setring @R;
+  kill @R@;
+  dbprint(ppl,"// -1-1- the ring @R(u,v,t,Dt,_x,_Dx) is ready");
+  dbprint(ppl-1, @R);
+  // create the ideal I
+  poly  F = imap(save,F);
+  ideal I = u*F-t,u*v-1;
+  poly p;
+  for(i=1; i<=N; i++)
+  {
+    p = u*Dt; // u*Dt
+    p = diff(F,var(4+i))*p;
+    I = I, var(N+4+i) + p;
+  }
+  // -------- the ideal I is ready ----------
+  dbprint(ppl,"// -1-2- starting the elimination of u,v in @R");
+  dbprint(ppl-1, I);
+  ideal J = engine(I,eng);
+  ideal K = nselect(J,1..2);
+  dbprint(ppl,"// -1-3- u,v are eliminated");
+  dbprint(ppl-1, K);  // K is without u,v
+  setring save;
+  // ------------ new ring @R2 ------------------
+  // without u,v and with the elim.ord for t,Dt
+  // tensored with the K[s]
+  // keep: N, i,j,s, tmp, RL
+  Nnew = 2*N+2+1;
+  //  list RL = ringlist(save); // is defined earlier
+  L = 0;  //  kill L;
+  kill Lord, tmp, iv, RName;
+  list Lord, tmp;
+  intvec iv;
+  L[1] = RL[1]; L[4] = RL[4]; // char, minpoly
+  // check whether vars have admissible names -> done earlier
+  //  list Name  = RL[2];
+  list RName;
+  RName[1] = "t";
+  RName[2] = "Dt";
+  // now, create the names for new var (here, s only)
+  tmp[1]     = "s";
+  // DName is defined earlier
+  list NName = RName + Name + DName + tmp;
+  L[2]   = NName;
+  tmp    = 0;
+  // block ord (a(1,1),dp);
+  tmp[1]  = "a";  iv = 1,1; tmp[2]  = iv; //intvec
+  Lord[1] = tmp;
+  // continue with a(1,1,1,1)...
+  tmp[1]  = "dp"; s  = "iv=";
+  for(i=1; i<= Nnew; i++)
+  {
+    s = s+"1,";
+  }
+  s[size(s)]= ";";  execute(s);
+  kill NName;
+  tmp[2]    = iv;
+  Lord[2]   = tmp;
+  // extra block for s
+  // tmp[1] = "dp"; iv = 1;
+  //  s[size(s)]= ",";  s = s + "1,1,1;";  execute(s);  tmp[2]    = iv;
+  //  Lord[3]   = tmp;
+  kill s;
+  tmp[1]    = "C";   iv  = 0; tmp[2] = iv;
+  Lord[3]   = tmp;   tmp = 0;
+  L[3]      = Lord;
+  // we are done with the list. Now, add a Plural part
+  def @R2@ = ring(L);
+  setring @R2@;
+  matrix @D[Nnew][Nnew];
+  @D[1,2] = 1;
+  for(i=1; i<=N; i++)
+  {
+    @D[2+i,2+N+i] = 1;
+  }
+  def @R2 = nc_algebra(1, at D);
+  setring @R2;
+  kill @R2@;
+  dbprint(ppl,"// -2-1- the ring @R2(t,Dt,_x,_Dx,s) is ready");
+  dbprint(ppl-1, @R2);
+  ideal MM = maxideal(1);
+  MM = 0,0,MM;
+  map R01 = @R, MM;
+  ideal K = R01(K);
+  //  ideal K = imap(@R,K); // names of vars are important!
+  poly G = t*Dt+s+1; // s is a variable here
+  K = NF(K,std(G)),G;
+  // -------- the ideal K_(@R2) is ready ----------
+  dbprint(ppl,"// -2-2- starting the elimination of t,Dt in @R2");
+  dbprint(ppl-1, K);
+  ideal M  = engine(K,eng);
+  ideal K2 = nselect(M,1..2);
+  dbprint(ppl,"// -2-3- t,Dt are eliminated");
+  dbprint(ppl-1, K2);
+  //  dbprint(ppl-1+1," -2-4- std of K2");
+  //  option(redSB);  option(redTail);  K2 = std(K2);
+  //  K2; // without t,Dt, and with s
+  // -------- the ring @R3 ----------
+  // _x, _Dx, s; elim.ord for _x,_Dx.
+  // keep: N, i,j,s, tmp, RL
+  setring save;
+  Nnew = 2*N+1;
+  //  list RL = ringlist(save); // is defined earlier
+  //  kill L;
+  kill Lord, tmp, iv, RName;
+  list Lord, tmp;
+  intvec iv;
+  L[1] = RL[1]; L[4] = RL[4]; // char, minpoly
+  // check whether vars have admissible names -> done earlier
+  //  list Name  = RL[2];
+  // now, create the names for new var (here, s only)
+  tmp[1]     = "s";
+  // DName is defined earlier
+  list NName = Name + DName + tmp;
+  L[2]   = NName;
+  tmp    = 0;
+  // block ord (a(1,1...),dp);
+  string  s = "iv=";
+  for(i=1; i<=Nnew-1; i++)
+  {
+    s = s+"1,";
+  }
+  s[size(s)]= ";";
+  execute(s);
+  tmp[1]  = "a"; // string
+  tmp[2]  = iv; //intvec
+  Lord[1] = tmp;
+  // continue with dp 1,1,1,1...
+  tmp[1]  = "dp"; // string
+  s[size(s)]=","; s= s+"1;";
+  execute(s);
+  kill s;
+  kill NName;
+  tmp[2]    = iv;
+  Lord[2]   = tmp;
+  tmp[1]    = "C";  iv  = 0;  tmp[2] = iv;
+  Lord[3]   = tmp;  tmp = 0;
+  L[3]      = Lord;
+  // we are done with the list. Now add a Plural part
+  def @R3@ = ring(L);
+  setring @R3@;
+  matrix @D[Nnew][Nnew];
+  for(i=1; i<=N; i++)
+  {
+    @D[i,N+i]=1;
+  }
+  def @R3 = nc_algebra(1, at D);
+  setring @R3;
+  kill @R3@;
+  dbprint(ppl,"// -3-1- the ring @R3(_x,_Dx,s) is ready");
+  dbprint(ppl-1, @R3);
+  ideal MM = maxideal(1);
+  MM = 0,0,MM;
+  map R12 = @R2, MM;
+  ideal K = R12(K2);
+  poly  F = imap(save,F);
+  K = K,F;
+  dbprint(ppl,"// -3-2- starting the elimination of _x,_Dx in @R3");
+  dbprint(ppl-1, K);
+  ideal M = engine(K,eng);
+  ideal K3 = nselect(M,1..Nnew-1);
+  dbprint(ppl,"// -3-3-  _x,_Dx are eliminated in @R3");
+  dbprint(ppl-1, K3);
+  // the ring @R4  and the search for minimal negative int s
+  ring @R4 = 0,(s),dp;
+  dbprint(ppl,"// -4-1- the ring @R4 is ready");
+  ideal K4 = imap(@R3,K3);
+  poly p = K4[1];
+  dbprint(ppl,"// -4-2- factorization");
+////  ideal P = factorize(p,1);  // without constants and multiplicities
+  list P = factorize(p);         // with constants and multiplicities
+  ideal bs; intvec m;            // the Bernstein polynomial is monic, so we are not interested in constants
+  for (i=2; i<=size(P[1]); i++)  // we delete P[1][1] and P[2][1]
+  {
+    bs[i-1] = P[1][i];
+    m[i-1]  = P[2][i];
+  }
+  //  "------ b-function factorizes into ----------";  P;
+////  int sP  = minIntRoot(P, 1);
+  int sP = minIntRoot(bs,1);
+  dbprint(ppl,"// -4-3- minimal integer root found");
+  dbprint(ppl-1, sP);
+  // convert factors to a list of their roots
+  // assume all factors are linear
+////  ideal BS = normalize(P);
+////  BS = subst(BS,s,0);
+////  BS = -BS;
+  bs = normalize(bs);
+  bs = subst(bs,s,0);
+  bs = -bs;
+  list BS = bs,m;
+  // TODO: sort BS!
+  // ------ substitute s found in the ideal ------
+  // ------- going back to @R2 and substitute --------
+  setring @R2;
+  ideal K3 = subst(K2,s,sP);
+  // create the ordinary Weyl algebra and put the result into it,
+  // thus creating the ring @R5
+  // keep: N, i,j,s, tmp, RL
+  setring save;
+  Nnew = 2*N;
+  //  list RL = ringlist(save); // is defined earlier
+  kill Lord, tmp, iv;
+  L = 0;
+  list Lord, tmp;
+  intvec iv;
+  L[1] = RL[1];   L[4] = RL[4]; // char, minpoly
+  // check whether vars have admissible names -> done earlier
+  //  list Name  = RL[2];
+  // DName is defined earlier
+  list NName = Name + DName;
+  L[2]   = NName;
+  // dp ordering;
+  string   s       = "iv=";
+  for(i=1;i<=Nnew;i++)
+  {
+    s = s+"1,";
+  }
+  s[size(s)]= ";";
+  execute(s);
+  tmp     = 0;
+  tmp[1]  = "dp"; // string
+  tmp[2]  = iv; //intvec
+  Lord[1] = tmp;
+  kill s;
+  tmp[1]    = "C";
+  iv        = 0;
+  tmp[2]    = iv;
+  Lord[2]   = tmp;
+  tmp       = 0;
+  L[3]      = Lord;
+  // we are done with the list
+  // Add: Plural part
+  def @R5@ = ring(L);
+  setring @R5@;
+  matrix @D[Nnew][Nnew];
+  for(i=1; i<=N; i++)
+  {
+    @D[i,N+i]=1;
+  }
+  def @R5 = nc_algebra(1, at D);
+  setring @R5;
+  kill @R5@;
+  dbprint(ppl,"// -5-1- the ring @R5 is ready");
+  dbprint(ppl-1, @R5);
+  ideal K5 = imap(@R2,K3);
+  intvec saveopt=option(get);
+  option(redSB);
+  dbprint(ppl,"// -5-2- the final cosmetic std");
+  K5 = engine(K5,eng); // std does the job too
+  // total cleanup
+  kill @R;
+  kill @R2;
+  kill @R3;
+////  ideal BS = imap(@R4,BS);
+  list BS = imap(@R4,BS);
+  export BS;
+  ideal LD = K5;
+  kill @R4;
+  export LD;
+  option(set,saveopt);
+  return(@R5);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y,z),Dp;
+  poly F = x^2+y^3+z^5;
+  printlevel = 0;
+  def A  = annfsOT(F);
+  setring A;
+  LD;
+  BS;
+}
+
+
+proc SannfsOT(poly F, list #)
+"USAGE:  SannfsOT(f [,eng]);  f a poly, eng an optional int
+RETURN:  ring
+PURPOSE: compute the D-module structure of basering[1/f]*f^s, according to the
+@* 1st step of the algorithm by Oaku and Takayama in the ring D[s]
+NOTE:    activate the output ring with the @code{setring} command.
+@*  In the output ring D[s], the ideal LD (which is NOT a Groebner basis)
+@*  is the needed D-module structure.
+@*  If eng <>0, @code{std} is used for Groebner basis computations,
+@*  otherwise, and by default @code{slimgb} is used.
+@*  If printlevel=1, progress debug messages will be printed,
+@*  if printlevel>=2, all the debug messages will be printed.
+EXAMPLE: example SannfsOT; shows examples
+"
+{
+  int eng = 0;
+  if ( size(#)>0 )
+  {
+    if ( typeof(#[1]) == "int" )
+    {
+      eng = int(#[1]);
+    }
+  }
+  // returns a list with a ring and an ideal LD in it
+  int ppl = printlevel-voice+2;
+  //  printf("plevel :%s, voice: %s",printlevel,voice);
+  def save = basering;
+  int N = nvars(basering);
+  int Nnew = 2*(N+2);
+  int i,j;
+  string s;
+  list RL = ringlist(basering);
+  list L, Lord;
+  list tmp;
+  intvec iv;
+  L[1] = RL[1]; // char
+  L[4] = RL[4]; // char, minpoly
+  // check whether vars have admissible names
+  list Name  = RL[2];
+  list RName;
+  RName[1] = "u";
+  RName[2] = "v";
+  RName[3] = "t";
+  RName[4] = "Dt";
+  for(i=1;i<=N;i++)
+  {
+    for(j=1; j<=size(RName);j++)
+    {
+      if (Name[i] == RName[j])
+      {
+        ERROR("Variable names should not include u,v,t,Dt");
+      }
+    }
+  }
+  // now, create the names for new vars
+  tmp[1]     = "u";
+  tmp[2]     = "v";
+  list UName = tmp;
+  list DName;
+  for(i=1;i<=N;i++)
+  {
+    DName[i] = "D"+Name[i]; // concat
+  }
+  tmp    =  0;
+  tmp[1] = "t";
+  tmp[2] = "Dt";
+  list NName = UName +  tmp + Name + DName;
+  L[2]   = NName;
+  tmp    = 0;
+  // Name, Dname will be used further
+  kill UName;
+  kill NName;
+  // block ord (a(1,1),dp);
+  tmp[1]  = "a"; // string
+  iv      = 1,1;
+  tmp[2]  = iv; //intvec
+  Lord[1] = tmp;
+  // continue with dp 1,1,1,1...
+  tmp[1]  = "dp"; // string
+  s       = "iv=";
+  for(i=1;i<=Nnew;i++)
+  {
+    s = s+"1,";
+  }
+  s[size(s)]= ";";
+  execute(s);
+  tmp[2]    = iv;
+  Lord[2]   = tmp;
+  tmp[1]    = "C";
+  iv        = 0;
+  tmp[2]    = iv;
+  Lord[3]   = tmp;
+  tmp       = 0;
+  L[3]      = Lord;
+  // we are done with the list
+  def @R@ = ring(L);
+  setring @R@;
+  matrix @D[Nnew][Nnew];
+  @D[3,4]=1;
+  for(i=1; i<=N; i++)
+  {
+    @D[4+i,N+4+i]=1;
+  }
+  //  @D[N+3,2*(N+2)]=1; old t,Dt stuff
+  //  L[5] = matrix(UpOneMatrix(Nnew));
+  //  L[6] = @D;
+  def @R =  nc_algebra(1, at D);
+  setring @R;
+  kill @R@;
+  dbprint(ppl,"// -1-1- the ring @R(u,v,t,Dt,_x,_Dx) is ready");
+  dbprint(ppl-1, @R);
+  // create the ideal I
+  poly  F = imap(save,F);
+  ideal I = u*F-t,u*v-1;
+  poly p;
+  for(i=1; i<=N; i++)
+  {
+    p = u*Dt; // u*Dt
+    p = diff(F,var(4+i))*p;
+    I = I, var(N+4+i) + p;
+  }
+  // -------- the ideal I is ready ----------
+  dbprint(ppl,"// -1-2- starting the elimination of u,v in @R");
+  dbprint(ppl-1, I);
+  ideal J = engine(I,eng);
+  ideal K = nselect(J,1..2);
+  dbprint(ppl,"// -1-3- u,v are eliminated");
+  dbprint(ppl-1, K);  // K is without u,v
+  setring save;
+  // ------------ new ring @R2 ------------------
+  // without u,v and with the elim.ord for t,Dt
+  // tensored with the K[s]
+  // keep: N, i,j,s, tmp, RL
+  Nnew = 2*N+2+1;
+  //  list RL = ringlist(save); // is defined earlier
+  L = 0;  //  kill L;
+  kill Lord, tmp, iv, RName;
+  list Lord, tmp;
+  intvec iv;
+  L[1] = RL[1]; L[4] = RL[4]; // char, minpoly
+  // check whether vars have admissible names -> done earlier
+  //  list Name  = RL[2];
+  list RName;
+  RName[1] = "t";
+  RName[2] = "Dt";
+  // now, create the names for new var (here, s only)
+  tmp[1]     = "s";
+  // DName is defined earlier
+  list NName = RName + Name + DName + tmp;
+  L[2]   = NName;
+  tmp    = 0;
+  // block ord (a(1,1),dp);
+  tmp[1]  = "a";  iv = 1,1; tmp[2]  = iv; //intvec
+  Lord[1] = tmp;
+  // continue with a(1,1,1,1)...
+  tmp[1]  = "dp"; s  = "iv=";
+  for(i=1; i<= Nnew; i++)
+  {
+    s = s+"1,";
+  }
+  s[size(s)]= ";";  execute(s);
+  kill NName;
+  tmp[2]    = iv;
+  Lord[2]   = tmp;
+  // extra block for s
+  // tmp[1] = "dp"; iv = 1;
+  //  s[size(s)]= ",";  s = s + "1,1,1;";  execute(s);  tmp[2]    = iv;
+  //  Lord[3]   = tmp;
+  kill s;
+  tmp[1]    = "C";   iv  = 0; tmp[2] = iv;
+  Lord[3]   = tmp;   tmp = 0;
+  L[3]      = Lord;
+  // we are done with the list. Now, add a Plural part
+  def @R2@ = ring(L);
+  setring @R2@;
+  matrix @D[Nnew][Nnew];
+  @D[1,2] = 1;
+  for(i=1; i<=N; i++)
+  {
+    @D[2+i,2+N+i] = 1;
+  }
+  def @R2 = nc_algebra(1, at D);
+  setring @R2;
+  kill @R2@;
+  dbprint(ppl,"// -2-1- the ring @R2(t,Dt,_x,_Dx,s) is ready");
+  dbprint(ppl-1, @R2);
+  ideal MM = maxideal(1);
+  MM = 0,0,MM;
+  map R01 = @R, MM;
+  ideal K = R01(K);
+  //  ideal K = imap(@R,K); // names of vars are important!
+  poly G = t*Dt+s+1; // s is a variable here
+  K = NF(K,std(G)),G;
+  // -------- the ideal K_(@R2) is ready ----------
+  dbprint(ppl,"// -2-2- starting the elimination of t,Dt in @R2");
+  dbprint(ppl-1, K);
+  ideal M  = engine(K,eng);
+  ideal K2 = nselect(M,1..2);
+  dbprint(ppl,"// -2-3- t,Dt are eliminated");
+  dbprint(ppl-1, K2);
+  K2 = engine(K2,eng);
+  setring save;
+  // ----------- the ring @R3 ------------
+  // _x, _Dx,s;  elim.ord for _x,_Dx.
+  // keep: N, i,j,s, tmp, RL
+  Nnew = 2*N+1;
+  kill Lord, tmp, iv, RName;
+  list Lord, tmp;
+  intvec iv;
+  L[1] = RL[1];
+  L[4] = RL[4];  // char, minpoly
+  // check whether vars hava admissible names -> done earlier
+  // now, create the names for new var
+  tmp[1] = "s";
+  // DName is defined earlier
+  list NName = Name + DName + tmp;
+  L[2] = NName;
+  tmp = 0;
+  // block ord (dp(N),dp);
+  string s = "iv=";
+  for (i=1; i<=Nnew-1; i++)
+  {
+    s = s+"1,";
+  }
+  s[size(s)]=";";
+  execute(s);
+  tmp[1] = "dp";  // string
+  tmp[2] = iv;   // intvec
+  Lord[1] = tmp;
+  // continue with dp 1,1,1,1...
+  tmp[1] = "dp";  // string
+  s[size(s)] = ",";
+  s = s+"1;";
+  execute(s);
+  kill s;
+  kill NName;
+  tmp[2]      = iv;
+  Lord[2]     = tmp;
+  tmp[1]      = "C";  iv  = 0;  tmp[2]=iv;
+  Lord[3]     = tmp;  tmp = 0;
+  L[3]        = Lord;
+  // we are done with the list. Now add a Plural part
+  def @R3@ = ring(L);
+  setring @R3@;
+  matrix @D[Nnew][Nnew];
+  for (i=1; i<=N; i++)
+  {
+    @D[i,N+i]=1;
+  }
+  def @R3 = nc_algebra(1, at D);
+  setring @R3;
+  kill @R3@;
+  dbprint(ppl,"// -3-1- the ring @R3(_x,_Dx,s) is ready");
+  dbprint(ppl-1, @R3);
+  ideal MM = maxideal(1);
+  MM = 0,s,MM;
+  map R01 = @R2, MM;
+  ideal K2 = R01(K2);
+  // total cleanup
+  ideal LD = K2;
+  // make leadcoeffs positive
+  for (i=1; i<= ncols(LD); i++)
+  {
+    if (leadcoef(LD[i]) <0 )
+    {
+      LD[i] = -LD[i];
+    }
+  }
+  export LD;
+  kill @R;
+  kill @R2;
+  return(@R3);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y,z),Dp;
+  poly F = x^3+y^3+z^3;
+  printlevel = 0;
+  def A  = SannfsOT(F);
+  setring A;
+  LD;
+}
+
+proc SannfsBM(poly F, list #)
+"USAGE:  SannfsBM(f [,eng]);  f a poly, eng an optional int
+RETURN:  ring
+PURPOSE: compute the D-module structure of basering[1/f]*f^s, according to the
+@* 1st step of the algorithm by Briancon and Maisonobe in the ring D[s].
+NOTE:  activate the output ring with the @code{setring} command.
+@*   In the output ring D[s], the ideal LD (which is NOT a Groebner basis) is
+@*   the needed D-module structure.
+@*   If eng <>0, @code{std} is used for Groebner basis computations,
+@*   otherwise, and by default @code{slimgb} is used.
+@*   If printlevel=1, progress debug messages will be printed,
+@*   if printlevel>=2, all the debug messages will be printed.
+EXAMPLE: example SannfsBM; shows examples
+"
+{
+  int eng = 0;
+  if ( size(#)>0 )
+  {
+    if ( typeof(#[1]) == "int" )
+    {
+      eng = int(#[1]);
+    }
+  }
+  // returns a list with a ring and an ideal LD in it
+  int ppl = printlevel-voice+2;
+  //  printf("plevel :%s, voice: %s",printlevel,voice);
+  def save = basering;
+  int N = nvars(basering);
+  int Nnew = 2*N+2;
+  int i,j;
+  string s;
+  list RL = ringlist(basering);
+  list L, Lord;
+  list tmp;
+  intvec iv;
+  L[1] = RL[1]; // char
+  L[4] = RL[4]; // char, minpoly
+  // check whether vars have admissible names
+  list Name  = RL[2];
+  list RName;
+  RName[1] = "t";
+  RName[2] = "s";
+  for(i=1;i<=N;i++)
+  {
+    for(j=1; j<=size(RName);j++)
+    {
+      if (Name[i] == RName[j])
+      {
+        ERROR("Variable names should not include t,s");
+      }
+    }
+  }
+  // now, create the names for new vars
+  list DName;
+  for(i=1;i<=N;i++)
+  {
+    DName[i] = "D"+Name[i]; // concat
+  }
+  tmp[1] = "t";
+  tmp[2] = "s";
+  list NName = tmp + Name + DName;
+  L[2]   = NName;
+  // Name, Dname will be used further
+  kill NName;
+  // block ord (lp(2),dp);
+  tmp[1]  = "lp"; // string
+  iv      = 1,1;
+  tmp[2]  = iv; //intvec
+  Lord[1] = tmp;
+  // continue with dp 1,1,1,1...
+  tmp[1]  = "dp"; // string
+  s       = "iv=";
+  for(i=1;i<=Nnew;i++)
+  {
+    s = s+"1,";
+  }
+  s[size(s)]= ";";
+  execute(s);
+  kill s;
+  tmp[2]    = iv;
+  Lord[2]   = tmp;
+  tmp[1]    = "C";
+  iv        = 0;
+  tmp[2]    = iv;
+  Lord[3]   = tmp;
+  tmp       = 0;
+  L[3]      = Lord;
+  // we are done with the list
+  def @R@ = ring(L);
+  setring @R@;
+  matrix @D[Nnew][Nnew];
+  @D[1,2]=t;
+  for(i=1; i<=N; i++)
+  {
+    @D[2+i,N+2+i]=1;
+  }
+  //  L[5] = matrix(UpOneMatrix(Nnew));
+  //  L[6] = @D;
+  def @R = nc_algebra(1, at D);
+  setring @R;
+  kill @R@;
+  dbprint(ppl,"// -1-1- the ring @R(t,s,_x,_Dx) is ready");
+  dbprint(ppl-1, @R);
+  // create the ideal I
+  poly  F = imap(save,F);
+  ideal I = t*F+s;
+  poly p;
+  for(i=1; i<=N; i++)
+  {
+    p = t; // t
+    p = diff(F,var(2+i))*p;
+    I = I, var(N+2+i) + p;
+  }
+  // -------- the ideal I is ready ----------
+  dbprint(ppl,"// -1-2- starting the elimination of t in @R");
+  dbprint(ppl-1, I);
+  ideal J = engine(I,eng);
+  ideal K = nselect(J,1);
+  dbprint(ppl,"// -1-3- t is eliminated");
+  dbprint(ppl-1, K);  // K is without t
+  K = engine(K,eng);  // std does the job too
+  // now, we must change the ordering
+  // and create a ring without t, Dt
+  //  setring S;
+  // ----------- the ring @R3 ------------
+  // _x, _Dx,s;  elim.ord for _x,_Dx.
+  // keep: N, i,j,s, tmp, RL
+  Nnew = 2*N+1;
+  kill Lord, tmp, iv, RName;
+  list Lord, tmp;
+  intvec iv;
+  list L=imap(save,L);
+  list RL=imap(save,RL);
+  L[1] = RL[1];
+  L[4] = RL[4];  // char, minpoly
+  // check whether vars hava admissible names -> done earlier
+  // now, create the names for new var
+  tmp[1] = "s";
+  // DName is defined earlier
+  list NName = Name + DName + tmp;
+  L[2] = NName;
+  tmp = 0;
+  // block ord (dp(N),dp);
+  string s = "iv=";
+  for (i=1; i<=Nnew-1; i++)
+  {
+    s = s+"1,";
+  }
+  s[size(s)]=";";
+  execute(s);
+  tmp[1] = "dp";  // string
+  tmp[2] = iv;   // intvec
+  Lord[1] = tmp;
+  // continue with dp 1,1,1,1...
+  tmp[1] = "dp";  // string
+  s[size(s)] = ",";
+  s = s+"1;";
+  execute(s);
+  kill s;
+  kill NName;
+  tmp[2]      = iv;
+  Lord[2]     = tmp;
+  tmp[1]      = "C";  iv  = 0;  tmp[2]=iv;
+  Lord[3]     = tmp;  tmp = 0;
+  L[3]        = Lord;
+  // we are done with the list. Now add a Plural part
+  def @R2@ = ring(L);
+  setring @R2@;
+  matrix @D[Nnew][Nnew];
+  for (i=1; i<=N; i++)
+  {
+    @D[i,N+i]=1;
+  }
+  def @R2 = nc_algebra(1, at D);
+  setring @R2;
+  kill @R2@;
+  dbprint(ppl,"//  -2-1- the ring @R2(_x,_Dx,s) is ready");
+  dbprint(ppl-1, @R2);
+  ideal MM = maxideal(1);
+  MM = 0,s,MM;
+  map R01 = @R, MM;
+  ideal K = R01(K);
+  // total cleanup
+  ideal LD = K;
+  // make leadcoeffs positive
+  for (i=1; i<= ncols(LD); i++)
+  {
+    if (leadcoef(LD[i]) <0 )
+    {
+      LD[i] = -LD[i];
+    }
+  }
+  export LD;
+  kill @R;
+  return(@R2);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y,z),Dp;
+  poly F = x^3+y^3+z^3;
+  printlevel = 0;
+  def A = SannfsBM(F);
+  setring A;
+  LD;
+}
+
+static proc safeVarName (string s, list #)
+{
+  string S;
+  int cv = 1;
+  if (size(#)>1)
+  {
+    if (#[1]=="v") { cv = 0; S = varstr(basering); }
+    if (#[1]=="c") { cv = 0; S = charstr(basering); }
+  }
+  if (cv) { S = charstr(basering) + "," + varstr(basering); }
+  S = "," + S + ",";
+  s = "," + s + ",";
+  while (find(S,s) <> 0)
+  {
+    s[1] = "@";
+    s = "," + s;
+  }
+  s = s[2..size(s)-1];
+  return(s)
+}
+
+proc SannfsBFCT(poly F, list #)
+"USAGE:  SannfsBFCT(f [,a,b,c]);  f a poly, a,b,c optional ints
+RETURN:  ring
+PURPOSE: compute a Groebner basis either of Ann(f^s)+<f> or of
+@*       Ann(f^s)+<f,f_1,...,f_n> in D[s]
+NOTE:    Activate the output ring with the @code{setring} command.
+@*  This procedure, unlike SannfsBM, returns the ring D[s] with an anti-
+@*  elimination ordering for s.
+@*  The output ring contains an ideal @code{LD}, being a Groebner basis
+@*  either of  Ann(f^s)+<f>, if a=0 (and by default), or of
+@*  Ann(f^s)+<f,f_1,...,f_n>, otherwise.
+@*  Here, f_i stands for the i-th  partial derivative of f.
+@*  If b<>0, @code{std} is used for Groebner basis computations,
+@*  otherwise, and by default @code{slimgb} is used.
+@*  If c<>0, @code{std} is used for Groebner basis computations of
+@*  ideals <I+J> when I is already a Groebner basis of <I>.
+@*  Otherwise, and by default the engine determined by the switch b is
+@*  used. Note that in the case c<>0, the choice for b will be
+@*  overwritten only for the types of ideals mentioned above.
+@*  This means that if b<>0, specifying c has no effect.
+DISPLAY: If printlevel=1, progress debug messages will be printed,
+@*       if printlevel>=2, all the debug messages will be printed.
+EXAMPLE: example SannfsBFCT; shows examples
+"
+{
+  int addPD,eng,stdsum;
+  if (size(#)>0)
+  {
+    if (typeof(#[1])=="int" || typeof(#[1])=="number")
+    {
+      addPD = int(#[1]);
+    }
+    if (size(#)>1)
+    {
+      if (typeof(#[2])=="int" || typeof(#[2])=="number")
+      {
+        eng = int(#[2]);
+      }
+      if (size(#)>2)
+      {
+        if (typeof(#[3])=="int" || typeof(#[3])=="number")
+        {
+          stdsum = int(#[3]);
+        }
+      }
+    }
+  }
+  int ppl = printlevel-voice+2;
+  def save = basering;
+  int N = nvars(save);
+  intvec optSave = option(get);
+  int i,j;
+  list RL = ringlist(save);
+  // ----- step 1: compute syzigies
+  intvec iv;
+  list L,Lord;
+  iv = 1:N; Lord[1] = list("dp",iv);
+  iv = 0;   Lord[2] = list("C",iv);
+  L = RL;
+  L[3] = Lord;
+  def @RM = ring(L);
+  kill L,Lord;
+  setring @RM;
+  option(redSB);
+  option(redTail);
+  def RM = makeModElimRing(@RM);
+  setring RM;
+  poly F = imap(save,F);
+  ideal J = jacob(F);
+  J = F,J;
+  dbprint(ppl,"// -1-1- Starting the computation of syz(F,_Dx(F))");
+  dbprint(ppl-1, J);
+  module M = syz(J);
+  dbprint(ppl,"// -1-2- The module syz(F,_Dx(F)) has been computed");
+  dbprint(ppl-1, M);
+  dbprint(ppl,"// -1-3- Starting GB computation of syz(F,_Dx(F))");
+  M = engine(M,eng);
+  dbprint(ppl,"// -1-4- GB computation finished");
+  dbprint(ppl-1, M);
+  // ----- step 2: compute part of Ann(F^s)
+  setring save;
+  option(set,optSave);
+  module M = imap(RM,M);
+  kill optSave,RM;
+  // ----- create D[s]
+  int Nnew = 2*N+1;
+  list L, Lord;
+  // ----- keep char, minpoly
+  L[1] = RL[1];
+  L[4] = RL[4];
+  // ----- create names for new vars
+  list Name  = RL[2];
+  string newVar at s = safeVarName("s");
+  if (newVar at s[1] == "@")
+  {
+    print("Name s already assigned to parameter/ringvar.");
+    print("Using " + newVar at s + " instead.")
+  }
+  list DName;
+  for (i=1; i<=N; i++)
+  {
+    DName[i] = safeVarName("D" + Name[i]);
+  }
+  L[2] = list(newVar at s) + Name + DName;
+  // ----- create ordering
+  // --- anti-elimination ordering for s
+  iv = 1;       Lord[1] = list("dp",iv);
+  iv = 1:(2*N); Lord[2] = list("dp",iv);
+  iv = 0;       Lord[3] = list("C",iv);
+  L[3] = Lord;
+  // ----- create commutative ring
+  def @Ds = ring(L);
+  kill L,Lord;
+  setring @Ds;
+  // ----- create nc relations
+   matrix Drel[Nnew][Nnew];
+  for (i=1; i<=N; i++)
+  {
+    Drel[i+1,N+1+i] = 1;
+  }
+  def Ds = nc_algebra(1,Drel);
+  setring Ds;
+  kill @Ds;
+  dbprint(ppl,"// -2-1- The ring D[s] is ready");
+  dbprint(ppl-1, Ds);
+  matrix M = imap(save,M);
+  vector v = var(1)*gen(1);
+  for (i=1; i<=N; i++)
+  {
+    v = v + var(i+1+N)*gen(i+1); //[s,_Dx]
+  }
+  ideal J = transpose(M)*v;
+  kill M,v;
+  dbprint(ppl,"// -2-2- Compute part of Ann(F^s)");
+  dbprint(ppl-1, J);
+  J = engine(J,eng);
+  dbprint(ppl,"// -2-3- GB computation finished");
+  dbprint(ppl-1, J);
+  // ----- step 3: the full annihilator
+  // ----- create D<t,s>
+  setring save;
+  Nnew = 2*N+2;
+  list L, Lord;
+  // ----- keep char, minpoly
+  L[1] = RL[1];
+  L[4] = RL[4];
+  // ----- create vars
+  string newVar at t = safeVarName("t");
+  L[2] = list(newVar at t,newVar at s) + DName + Name;
+  // ----- create ordering for elimination of t
+  // block ord (lp(2),dp);
+  iv = 1,1;    Lord[1] = list("lp",iv);
+  iv = 1:Nnew; Lord[2] = list("dp",iv);
+  iv = 0;      Lord[3] = list("C",iv);
+  L[3] = Lord;
+  def @Dts = ring(L);
+  kill RL,L,Lord,Name,DName,newVar at s,newVar at t;
+  setring @Dts;
+  // ----- create nc relations
+  matrix Drel[Nnew][Nnew];
+  Drel[1,2] = var(1);
+  for(i=1; i<=N; i++)
+  {
+    Drel[2+i,N+2+i]=-1;
+  }
+  def Dts = nc_algebra(1,Drel);
+  setring Dts;
+  kill @Dts;
+  dbprint(ppl,"// -3-1- The ring D<t,s> is ready");
+  dbprint(ppl-1, Dts);
+  // ----- create the ideal I following BM
+  poly  F = imap(save,F);
+  ideal I = var(1)*F + var(2); // = t*F + s
+  poly p;
+  for(i=1; i<=N; i++)
+  {
+    p = var(1)*diff(F,var(N+2+i)) + var(2+i); // = t*F_i + D_i
+    I[i+1] = p;
+  }
+  // ----- add already computed part to it
+  ideal MM = var(2);      // s
+  for (i=1; i<=N; i++)
+  {
+    MM[1+i] = var(2+N+i); // _x
+    MM[1+N+i] = var(2+i); // _Dx
+  }
+  map Ds2Dts = Ds,MM;
+  ideal J = Ds2Dts(J);
+  attrib(J,"isSB",1);
+  kill MM,Ds2Dts;
+  // ----- start the elimination
+  dbprint(ppl,"// -3-2- Starting the elimination of t in D<t,s>");
+  dbprint(ppl-1, I);
+  if (stdsum || eng <> 0)
+  {
+    I = std(J,I);
+  }
+  else
+  {
+    I = J,I;
+    I = engine(I,eng);
+  }
+  kill J;
+  I = nselect(I,1);
+  dbprint(ppl,"// -3-3- t is eliminated");
+  dbprint(ppl-1, I);  // I is without t
+  // ----- step 4: add F
+  // ----- back to D[s]
+  setring Ds;
+  ideal MM = 0,var(1);      // 0,s
+  for (i=1; i<=N; i++)
+  {
+    MM[2+i]   = var(1+N+i); // _Dx
+    MM[2+N+i] = var(1+i);   // _x
+  }
+  map Dts2Ds = Dts, MM;
+  ideal LD = Dts2Ds(I);
+  kill J,Dts,Dts2Ds,MM;
+  dbprint(ppl,"// -4-1- Starting cosmetic Groebner computation");
+  LD = engine(LD,eng);
+  dbprint(ppl,"// -4-2- Finished cosmetic Groebner computation");
+  dbprint(ppl-1, LD);
+  // ----- use reduction trick as Macaulay2 does: compute b(s)/(s+1) by adding all partial derivations also
+  ideal J;
+  if (addPD)
+  {
+    setring @RM;
+    poly F = imap(save,F);
+    ideal J = jacob(F);
+    J = F,J;
+    dbprint(ppl,"// -4-2-1- Start GB computation <f, f_i>");
+    J = engine(J,eng);
+    dbprint(ppl,"// -4-2-2- Finished GB computation <f, f_i>");
+    dbprint(ppl-1, J);
+    setring Ds;
+    J = imap(@RM,J);
+    attrib(J,"isSB",1);
+    dbprint(ppl,"// -4-3- Start GB computations for Ann f^s + <f, f_i>");
+  }
+  else
+  {
+    J = imap(save,F);
+    dbprint(ppl,"// -4-3- Start GB computations for Ann f^s + <f>");
+  }
+  kill @RM;
+  // ----- the really hard part
+  if (stdsum || eng <> 0)
+  {
+    LD = std(LD,J);
+  }
+  else
+  {
+    LD = LD,J;
+    LD = engine(LD,eng);
+  }
+  if (addPD) { dbprint(ppl,"// -4-4- Finished GB computations for Ann f^s + <f, f_i>"); }
+  else       { dbprint(ppl,"// -4-4- Finished GB computations for Ann f^s + <f>"); }
+  dbprint(ppl-1, LD);
+  export LD;
+  return(Ds);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y,z,w),Dp;
+  poly F = x^3+y^3+z^3*w;
+  // compute Ann(F^s)+<F> using slimgb only
+  def A = SannfsBFCT(F);
+  setring A; A;
+  LD;
+  // the Bernstein-Sato poly of F:
+  vec2poly(pIntersect(s,LD));
+  // a fancier example:
+  def R = reiffen(4,5); setring R;
+  RC; // the Reiffen curve in 4,5
+  // compute Ann(RC^s)+<RC,diff(RC,x),diff(RC,y)>
+  // using std for GB computations of ideals <I+J>
+  // where I is already a GB of <I>
+  // and slimgb for other ideals
+  def B = SannfsBFCT(RC,1,0,1);
+  setring B;
+  // the Bernstein-Sato poly of RC:
+  (s-1)*vec2poly(pIntersect(s,LD));
+}
+
+
+proc SannfsBFCTstd(poly F, list #)
+"USAGE:  SannfsBFCTstd(f [,eng]);  f a poly, eng an optional int
+RETURN:  ring
+PURPOSE: compute Ann f^s and Groebner basis of Ann f^s+f in D[s]
+NOTE:    activate the output ring with the @code{setring} command.
+@*    This procedure, unlike SannfsBM, returns a ring with the degrevlex
+@*    ordering in all variables.
+@*    In the ring D[s], the ideal LD (which IS a Groebner basis) is the needed ideal.
+@*    In this procedure @code{std} is used for Groebner basis computations.
+DISPLAY: If printlevel=1, progress debug messages will be printed,
+@*       if printlevel>=2, all the debug messages will be printed.
+EXAMPLE: example SannfsBFCTstd; shows examples
+"
+{
+  // DEBUG INFO: ordering on the output ring = dp,
+  // use std(K,F); for reusing the std property of K
+
+  int eng = 0;
+  if ( size(#)>0 )
+  {
+    if ( typeof(#[1]) == "int" )
+    {
+      eng = int(#[1]);
+    }
+  }
+  // returns a list with a ring and an ideal LD in it
+  int ppl = printlevel-voice+2;
+  //  printf("plevel :%s, voice: %s",printlevel,voice);
+  def save = basering;
+  int N = nvars(basering);
+  int Nnew = 2*N+2;
+  int i,j;
+  string s;
+  list RL = ringlist(basering);
+  list L, Lord;
+  list tmp;
+  intvec iv;
+  L[1] = RL[1]; // char
+  L[4] = RL[4]; // char, minpoly
+  // check whether vars have admissible names
+  list Name  = RL[2];
+  list RName;
+  RName[1] = "@t";
+  RName[2] = "@s";
+  for(i=1;i<=N;i++)
+  {
+    for(j=1; j<=size(RName);j++)
+    {
+      if (Name[i] == RName[j])
+      {
+        ERROR("Variable names should not include @t, at s");
+      }
+    }
+  }
+  // now, create the names for new vars
+  list DName;
+  for(i=1;i<=N;i++)
+  {
+    DName[i] = "D"+Name[i]; // concat
+  }
+  tmp[1] = "t";
+  tmp[2] = "s";
+  list NName = tmp + DName + Name ;
+  L[2]   = NName;
+  // Name, Dname will be used further
+  kill NName;
+  // block ord (lp(2),dp);
+  tmp[1]  = "lp"; // string
+  iv      = 1,1;
+  tmp[2]  = iv; //intvec
+  Lord[1] = tmp;
+  // continue with dp 1,1,1,1...
+  tmp[1]  = "dp"; // string
+  s       = "iv=";
+  for(i=1;i<=Nnew;i++)
+  {
+    s = s+"1,";
+  }
+  s[size(s)]= ";";
+  execute(s);
+  kill s;
+  tmp[2]    = iv;
+  Lord[2]   = tmp;
+  tmp[1]    = "C";
+  iv        = 0;
+  tmp[2]    = iv;
+  Lord[3]   = tmp;
+  tmp       = 0;
+  L[3]      = Lord;
+  // we are done with the list
+  def @R@ = ring(L);
+  setring @R@;
+  matrix @D[Nnew][Nnew];
+  @D[1,2]=t;
+  for(i=1; i<=N; i++)
+  {
+    @D[2+i,N+2+i]=-1;
+  }
+  //  L[5] = matrix(UpOneMatrix(Nnew));
+  //  L[6] = @D;
+  def @R = nc_algebra(1, at D);
+  setring @R;
+  kill @R@;
+  dbprint(ppl,"// -1-1- the ring @R(t,s,_Dx,_x) is ready");
+  dbprint(ppl-1, @R);
+  // create the ideal I
+  poly  F = imap(save,F);
+  ideal I = t*F+s;
+  poly p;
+  for(i=1; i<=N; i++)
+  {
+    p = t; // t
+    p = diff(F,var(N+2+i))*p;
+    I = I, var(2+i) + p;
+  }
+  // -------- the ideal I is ready ----------
+  dbprint(ppl,"// -1-2- starting the elimination of t in @R");
+  dbprint(ppl-1, I);
+  ideal J = engine(I,eng);
+  ideal K = nselect(J,1);
+  dbprint(ppl,"// -1-3- t is eliminated");
+  dbprint(ppl-1, K);  // K is without t
+  K = engine(K,eng);  // std does the job too
+  // now, we must change the ordering
+  // and create a ring without t
+  //  setring S;
+  // ----------- the ring @R3 ------------
+  // _Dx,_x,s;  +fast ord !
+  // keep: N, i,j,s, tmp, RL
+  Nnew = 2*N+1;
+  kill Lord, tmp, iv, RName;
+  list Lord, tmp;
+  intvec iv;
+  list L=imap(save,L);
+  list RL=imap(save,RL);
+  L[1] = RL[1];
+  L[4] = RL[4];  // char, minpoly
+  // check whether vars hava admissible names -> done earlier
+  // now, create the names for new var
+  tmp[1] = "s";
+  // DName is defined earlier
+  list NName = DName + Name + tmp;
+  L[2] = NName;
+  tmp = 0;
+  // just dp
+  // block ord (dp(N),dp);
+  string s = "iv=";
+  for (i=1; i<=Nnew; i++)
+  {
+    s = s+"1,";
+  }
+  s[size(s)]=";";
+  execute(s);
+  tmp[1] = "dp";  // string
+  tmp[2] = iv;   // intvec
+  Lord[1] = tmp;
+  kill s;
+  kill NName;
+  tmp[1]      = "C";
+  Lord[2]     = tmp;  tmp = 0;
+  L[3]        = Lord;
+  // we are done with the list. Now add a Plural part
+  def @R2@ = ring(L);
+  setring @R2@;
+  matrix @D[Nnew][Nnew];
+  for (i=1; i<=N; i++)
+  {
+    @D[i,N+i]=-1;
+  }
+  def @R2 = nc_algebra(1, at D);
+  setring @R2;
+  kill @R2@;
+  dbprint(ppl,"//  -2-1- the ring @R2(_Dx,_x,s) is ready");
+  dbprint(ppl-1, @R2);
+  ideal MM = maxideal(1);
+  MM = 0,s,MM;
+  map R01 = @R, MM;
+  ideal K = R01(K);
+  // total cleanup
+  poly F = imap(save, F);
+  //  ideal LD = K,F;
+  dbprint(ppl,"//  -2-2- start GB computations for Ann f^s + f");
+  //  dbprint(ppl-1, LD);
+  ideal LD = std(K,F);
+  //  LD = engine(LD,eng);
+  dbprint(ppl,"//  -2-3- finished GB computations for Ann f^s + f");
+  dbprint(ppl-1, LD);
+  // make leadcoeffs positive
+  for (i=1; i<= ncols(LD); i++)
+  {
+    if (leadcoef(LD[i]) <0 )
+    {
+      LD[i] = -LD[i];
+    }
+  }
+  export LD;
+  kill @R;
+  return(@R2);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y,z,w),Dp;
+  poly F = x^3+y^3+z^3*w;
+  printlevel = 0;
+  def A = SannfsBFCT(F); setring A;
+  intvec v = 1,2,3,4,5,6,7,8;
+  // are there polynomials, depending on s only?
+  nselect(LD,v);
+  // a fancier example:
+  def R = reiffen(4,5); setring R;
+  v = 1,2,3,4;
+  RC; // the Reiffen curve in 4,5
+  def B = SannfsBFCT(RC);
+  setring B;
+  // Are there polynomials, depending on s only?
+  nselect(LD,v);
+  // It is not the case. Are there leading monomials in s only?
+  nselect(lead(LD),v);
+}
+
+// use a finer ordering
+
+proc SannfsLOT(poly F, list #)
+"USAGE:  SannfsLOT(f [,eng]);  f a poly, eng an optional int
+RETURN:  ring
+PURPOSE: compute the D-module structure of basering[1/f]*f^s, according to the
+@* Levandovskyy's modification of the algorithm by Oaku and Takayama in D[s]
+NOTE:    activate the output ring with the @code{setring} command.
+@*    In the ring D[s], the ideal LD (which is NOT a Groebner basis) is
+@*    the needed D-module structure.
+@*    If eng <>0, @code{std} is used for Groebner basis computations,
+@*    otherwise, and by default @code{slimgb} is used.
+@*    If printlevel=1, progress debug messages will be printed,
+@*    if printlevel>=2, all the debug messages will be printed.
+EXAMPLE: example SannfsLOT; shows examples
+"
+{
+  int eng = 0;
+  if ( size(#)>0 )
+  {
+    if ( typeof(#[1]) == "int" )
+    {
+      eng = int(#[1]);
+    }
+  }
+  // returns a list with a ring and an ideal LD in it
+  int ppl = printlevel-voice+2;
+  //  printf("plevel :%s, voice: %s",printlevel,voice);
+  def save = basering;
+  int N = nvars(basering);
+  //  int Nnew = 2*(N+2);
+  int Nnew = 2*(N+1)+1; //removed u,v; added s
+  int i,j;
+  string s;
+  list RL = ringlist(basering);
+  list L, Lord;
+  list tmp;
+  intvec iv;
+  L[1] = RL[1]; // char
+  L[4] = RL[4]; // char, minpoly
+  // check whether vars have admissible names
+  list Name  = RL[2];
+  list RName;
+//   RName[1] = "u";
+//   RName[2] = "v";
+  RName[1] = "t";
+  RName[2] = "Dt";
+  for(i=1;i<=N;i++)
+  {
+    for(j=1; j<=size(RName);j++)
+    {
+      if (Name[i] == RName[j])
+      {
+        ERROR("Variable names should not include t,Dt");
+      }
+    }
+  }
+  // now, create the names for new vars
+//   tmp[1]     = "u";
+//   tmp[2]     = "v";
+//   list UName = tmp;
+  list DName;
+  for(i=1;i<=N;i++)
+  {
+    DName[i] = "D"+Name[i]; // concat
+  }
+  tmp    =  0;
+  tmp[1] = "t";
+  tmp[2] = "Dt";
+  list SName ; SName[1] = "s";
+  //  list NName = tmp + Name + DName + SName;
+  list NName = tmp + SName + Name + DName;
+  L[2]   = NName;
+  tmp    = 0;
+  // Name, Dname will be used further
+  //  kill UName;
+  kill NName;
+  // block ord (a(1,1),dp);
+  tmp[1]  = "a"; // string
+  iv      = 1,1;
+  tmp[2]  = iv; //intvec
+  Lord[1] = tmp;
+  // continue with a(0,0,1)
+  tmp[1]  = "a"; // string
+  iv      = 0,0,1;
+  tmp[2]  = iv; //intvec
+  Lord[2] = tmp;
+  // continue with dp 1,1,1,1...
+  tmp[1]  = "dp"; // string
+  s       = "iv=";
+  for(i=1;i<=Nnew;i++)
+  {
+    s = s+"1,";
+  }
+  s[size(s)]= ";";
+  execute(s);
+  tmp[2]    = iv;
+  Lord[3]   = tmp;
+  tmp[1]    = "C";
+  iv        = 0;
+  tmp[2]    = iv;
+  Lord[4]   = tmp;
+  tmp       = 0;
+  L[3]      = Lord;
+  // we are done with the list
+  def @R@ = ring(L);
+  setring @R@;
+  matrix @D[Nnew][Nnew];
+  @D[1,2]=1;
+  for(i=1; i<=N; i++)
+  {
+    @D[3+i,N+3+i]=1;
+  }
+  // ADD [s,t]=-t, [s,Dt]=Dt
+  @D[1,3] = -var(1);
+  @D[2,3] = var(2);
+  //  @D[N+3,2*(N+2)]=1; old t,Dt stuff
+  //  L[5] = matrix(UpOneMatrix(Nnew));
+  //  L[6] = @D;
+  def @R = nc_algebra(1, at D);
+  setring @R;
+  kill @R@;
+  dbprint(ppl,"// -1-1- the ring @R(t,Dt,s,_x,_Dx) is ready");
+  dbprint(ppl-1, @R);
+  // create the ideal I
+  poly  F = imap(save,F);
+  //  ideal I = u*F-t,u*v-1;
+  ideal I = F-t;
+  poly p;
+  for(i=1; i<=N; i++)
+  {
+    //    p = u*Dt; // u*Dt
+    p = Dt;
+    p = diff(F,var(3+i))*p;
+    I = I, var(N+3+i) + p;
+  }
+  //  I = I, var(1)*var(2) + var(Nnew) +1; // reduce it with t-f!!!
+  // t*Dt + s +1 reduced with t-f gives f*Dt + s
+  I = I, F*var(2) + var(3);
+  // -------- the ideal I is ready ----------
+  dbprint(ppl,"// -1-2- starting the elimination of t,Dt in @R");
+  dbprint(ppl-1, I);
+  ideal J = engine(I,eng);
+  ideal K = nselect(J,1..2);
+  dbprint(ppl,"// -1-3- t,Dt are eliminated");
+  dbprint(ppl-1, K);  // K is without t, Dt
+  K = engine(K,eng);  // std does the job too
+  // now, we must change the ordering
+  // and create a ring without t, Dt
+  setring save;
+  // ----------- the ring @R3 ------------
+  // _x, _Dx,s;  elim.ord for _x,_Dx.
+  // keep: N, i,j,s, tmp, RL
+  Nnew = 2*N+1;
+  kill Lord, tmp, iv, RName;
+  list Lord, tmp;
+  intvec iv;
+  L[1] = RL[1];
+  L[4] = RL[4];  // char, minpoly
+  // check whether vars hava admissible names -> done earlier
+  // now, create the names for new var
+  tmp[1] = "s";
+  // DName is defined earlier
+  list NName = Name + DName + tmp;
+  L[2] = NName;
+  tmp = 0;
+  // block ord (dp(N),dp);
+  // string s is already defined
+  s = "iv=";
+  for (i=1; i<=Nnew-1; i++)
+  {
+    s = s+"1,";
+  }
+  s[size(s)]=";";
+  execute(s);
+  tmp[1] = "dp";  // string
+  tmp[2] = iv;   // intvec
+  Lord[1] = tmp;
+  // continue with dp 1,1,1,1...
+  tmp[1] = "dp";  // string
+  s[size(s)] = ",";
+  s = s+"1;";
+  execute(s);
+  kill s;
+  kill NName;
+  tmp[2]      = iv;
+  Lord[2]     = tmp;
+  tmp[1]      = "C";  iv  = 0;  tmp[2]=iv;
+  Lord[3]     = tmp;  tmp = 0;
+  L[3]        = Lord;
+  // we are done with the list. Now add a Plural part
+  def @R2@ = ring(L);
+  setring @R2@;
+  matrix @D[Nnew][Nnew];
+  for (i=1; i<=N; i++)
+  {
+    @D[i,N+i]=1;
+  }
+  def @R2 = nc_algebra(1, at D);
+  setring @R2;
+  kill @R2@;
+  dbprint(ppl,"//  -2-1- the ring @R2(_x,_Dx,s) is ready");
+  dbprint(ppl-1, @R2);
+  ideal MM = maxideal(1);
+  //  MM = 0,s,MM;
+  MM = 0,0,s,MM[1..size(MM)-1];
+  map R01 = @R, MM;
+  ideal K = R01(K);
+  // total cleanup
+  ideal LD = K;
+  // make leadcoeffs positive
+  for (i=1; i<= ncols(LD); i++)
+  {
+    if (leadcoef(LD[i]) <0 )
+    {
+      LD[i] = -LD[i];
+    }
+  }
+  export LD;
+  kill @R;
+  return(@R2);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y,z),Dp;
+  poly F = x^3+y^3+z^3;
+  printlevel = 0;
+  def A  = SannfsLOT(F);
+  setring A;
+  LD;
+}
+
+/*
+proc SannfsLOTold(poly F, list #)
+"USAGE:  SannfsLOT(f [,eng]);  f a poly, eng an optional int
+RETURN:  ring
+PURPOSE: compute the D-module structure of basering[1/f]*f^s, according to the Levandovskyy's modification of the algorithm by Oaku and Takayama in the ring D[s], where D is the Weyl algebra
+NOTE:    activate the output ring with the @code{setring} command.
+@*       In the ring D[s], the ideal LD (which is NOT a Groebner basis) is the needed D-module structure.
+@*       If eng <>0, @code{std} is used for Groebner basis computations,
+@*       otherwise, and by default @code{slimgb} is used.
+@*       If printlevel=1, progress debug messages will be printed,
+@*       if printlevel>=2, all the debug messages will be printed.
+EXAMPLE: example SannfsLOT; shows examples
+"
+{
+  int eng = 0;
+  if ( size(#)>0 )
+  {
+    if ( typeof(#[1]) == "int" )
+    {
+      eng = int(#[1]);
+    }
+  }
+  // returns a list with a ring and an ideal LD in it
+  int ppl = printlevel-voice+2;
+  //  printf("plevel :%s, voice: %s",printlevel,voice);
+  def save = basering;
+  int N = nvars(basering);
+  //  int Nnew = 2*(N+2);
+  int Nnew = 2*(N+1)+1; //removed u,v; added s
+  int i,j;
+  string s;
+  list RL = ringlist(basering);
+  list L, Lord;
+  list tmp;
+  intvec iv;
+  L[1] = RL[1]; // char
+  L[4] = RL[4]; // char, minpoly
+  // check whether vars have admissible names
+  list Name  = RL[2];
+  list RName;
+//   RName[1] = "u";
+//   RName[2] = "v";
+  RName[1] = "t";
+  RName[2] = "Dt";
+  for(i=1;i<=N;i++)
+  {
+    for(j=1; j<=size(RName);j++)
+    {
+      if (Name[i] == RName[j])
+      {
+        ERROR("Variable names should not include t,Dt");
+      }
+    }
+  }
+  // now, create the names for new vars
+//   tmp[1]     = "u";
+//   tmp[2]     = "v";
+//   list UName = tmp;
+  list DName;
+  for(i=1;i<=N;i++)
+  {
+    DName[i] = "D"+Name[i]; // concat
+  }
+  tmp    =  0;
+  tmp[1] = "t";
+  tmp[2] = "Dt";
+  list SName ; SName[1] = "s";
+  //  list NName = UName +  tmp + Name + DName;
+  list NName = tmp + Name + DName + SName;
+  L[2]   = NName;
+  tmp    = 0;
+  // Name, Dname will be used further
+  //  kill UName;
+  kill NName;
+  // block ord (a(1,1),dp);
+  tmp[1]  = "a"; // string
+  iv      = 1,1;
+  tmp[2]  = iv; //intvec
+  Lord[1] = tmp;
+  // continue with dp 1,1,1,1...
+  tmp[1]  = "dp"; // string
+  s       = "iv=";
+  for(i=1;i<=Nnew;i++)
+  {
+    s = s+"1,";
+  }
+  s[size(s)]= ";";
+  execute(s);
+  tmp[2]    = iv;
+  Lord[2]   = tmp;
+  tmp[1]    = "C";
+  iv        = 0;
+  tmp[2]    = iv;
+  Lord[3]   = tmp;
+  tmp       = 0;
+  L[3]      = Lord;
+  // we are done with the list
+  def @R@ = ring(L);
+  setring @R@;
+  matrix @D[Nnew][Nnew];
+  @D[1,2]=1;
+  for(i=1; i<=N; i++)
+  {
+    @D[2+i,N+2+i]=1;
+  }
+  // ADD [s,t]=-t, [s,Dt]=Dt
+  @D[1,Nnew] = -var(1);
+  @D[2,Nnew] = var(2);
+  //  @D[N+3,2*(N+2)]=1; old t,Dt stuff
+  //  L[5] = matrix(UpOneMatrix(Nnew));
+  //  L[6] = @D;
+  def @R = nc_algebra(1, at D);
+  setring @R;
+  kill @R@;
+  dbprint(ppl,"// -1-1- the ring @R(t,Dt,_x,_Dx,s) is ready");
+  dbprint(ppl-1, @R);
+  // create the ideal I
+  poly  F = imap(save,F);
+  //  ideal I = u*F-t,u*v-1;
+  ideal I = F-t;
+  poly p;
+  for(i=1; i<=N; i++)
+  {
+    //    p = u*Dt; // u*Dt
+    p = Dt;
+    p = diff(F,var(2+i))*p;
+    I = I, var(N+2+i) + p;
+  }
+  //  I = I, var(1)*var(2) + var(Nnew) +1; // reduce it with t-f!!!
+  // t*Dt + s +1 reduced with t-f gives f*Dt + s
+  I = I, F*var(2) + var(Nnew);
+  // -------- the ideal I is ready ----------
+  dbprint(ppl,"// -1-2- starting the elimination of t,Dt in @R");
+  dbprint(ppl-1, I);
+  ideal J = engine(I,eng);
+  ideal K = nselect(J,1..2);
+  dbprint(ppl,"// -1-3- t,Dt are eliminated");
+  dbprint(ppl-1, K);  // K is without t, Dt
+  K = engine(K,eng);  // std does the job too
+  // now, we must change the ordering
+  // and create a ring without t, Dt
+  setring save;
+  // ----------- the ring @R3 ------------
+  // _x, _Dx,s;  elim.ord for _x,_Dx.
+  // keep: N, i,j,s, tmp, RL
+  Nnew = 2*N+1;
+  kill Lord, tmp, iv, RName;
+  list Lord, tmp;
+  intvec iv;
+  L[1] = RL[1];
+  L[4] = RL[4];  // char, minpoly
+  // check whether vars hava admissible names -> done earlier
+  // now, create the names for new var
+  tmp[1] = "s";
+  // DName is defined earlier
+  list NName = Name + DName + tmp;
+  L[2] = NName;
+  tmp = 0;
+  // block ord (dp(N),dp);
+  // string s is already defined
+  s = "iv=";
+  for (i=1; i<=Nnew-1; i++)
+  {
+    s = s+"1,";
+  }
+  s[size(s)]=";";
+  execute(s);
+  tmp[1] = "dp";  // string
+  tmp[2] = iv;   // intvec
+  Lord[1] = tmp;
+  // continue with dp 1,1,1,1...
+  tmp[1] = "dp";  // string
+  s[size(s)] = ",";
+  s = s+"1;";
+  execute(s);
+  kill s;
+  kill NName;
+  tmp[2]      = iv;
+  Lord[2]     = tmp;
+  tmp[1]      = "C";  iv  = 0;  tmp[2]=iv;
+  Lord[3]     = tmp;  tmp = 0;
+  L[3]        = Lord;
+  // we are done with the list. Now add a Plural part
+  def @R2@ = ring(L);
+  setring @R2@;
+  matrix @D[Nnew][Nnew];
+  for (i=1; i<=N; i++)
+  {
+    @D[i,N+i]=1;
+  }
+  def @R2 = nc_algebra(1, at D);
+  setring @R2;
+  kill @R2@;
+  dbprint(ppl,"//  -2-1- the ring @R2(_x,_Dx,s) is ready");
+  dbprint(ppl-1, @R2);
+  ideal MM = maxideal(1);
+  MM = 0,s,MM;
+  map R01 = @R, MM;
+  ideal K = R01(K);
+  // total cleanup
+  ideal LD = K;
+  // make leadcoeffs positive
+  for (i=1; i<= ncols(LD); i++)
+  {
+    if (leadcoef(LD[i]) <0 )
+    {
+      LD[i] = -LD[i];
+    }
+  }
+  export LD;
+  kill @R;
+  return(@R2);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y,z),Dp;
+  poly F = x^3+y^3+z^3;
+  printlevel = 0;
+  def A  = SannfsLOTold(F);
+  setring A;
+  LD;
+}
+
+*/
+
+proc annfsLOT(poly F, list #)
+"USAGE:  annfsLOT(F [,eng]);  F a poly, eng an optional int
+RETURN:  ring
+PURPOSE: compute the D-module structure of basering[1/f]*f^s, according to
+@* the Levandovskyy's modification of the algorithm by Oaku and Takayama
+NOTE:    activate the output ring with the @code{setring} command. In this ring,
+@*  - the ideal LD (which is a Groebner basis) is the needed D-module structure,
+@*    which is obtained by substituting the minimal integer root of a Bernstein
+@*    polynomial into the s-parametric ideal;
+@*  - the list BS contains the roots with multiplicities of BS polynomial of f.
+@*    If eng <>0, @code{std} is used for Groebner basis computations,
+@*    otherwise and by default @code{slimgb} is used.
+@*    If printlevel=1, progress debug messages will be printed,
+@*    if printlevel>=2, all the debug messages will be printed.
+EXAMPLE: example annfsLOT; shows examples
+"
+{
+  int eng = 0;
+  if ( size(#)>0 )
+  {
+    if ( typeof(#[1]) == "int" )
+    {
+      eng = int(#[1]);
+    }
+  }
+  printlevel=printlevel+1;
+  def save = basering;
+  def @A = SannfsLOT(F,eng);
+  setring @A;
+  poly F = imap(save,F);
+  def B  = annfs0(LD,F,eng);
+  return(B);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y,z),Dp;
+  poly F = z*x^2+y^3;
+  printlevel = 0;
+  def A  = annfsLOT(F);
+  setring A;
+  LD;
+  BS;
+}
+
+proc annfs0(ideal I, poly F, list #)
+"USAGE:  annfs0(I, F [,eng]);  I an ideal, F a poly, eng an optional int
+RETURN:  ring
+PURPOSE: compute the annihilator ideal of f^s in the Weyl Algebra, based
+@* on the output of Sannfs-like procedure
+NOTE:    activate the output ring with the @code{setring} command. In this ring,
+@* - the ideal LD (which is a Groebner basis) is the annihilator of f^s,
+@* - the list BS contains the roots with multiplicities of BS polynomial of f.
+@*  If eng <>0, @code{std} is used for Groebner basis computations,
+@*  otherwise and by default @code{slimgb} is used.
+@*  If printlevel=1, progress debug messages will be printed,
+@*  if printlevel>=2, all the debug messages will be printed.
+EXAMPLE: example annfs0; shows examples
+"
+{
+  int eng = 0;
+  if ( size(#)>0 )
+  {
+    if ( typeof(#[1]) == "int" )
+    {
+      eng = int(#[1]);
+    }
+  }
+  def @R2 = basering;
+  // we're in D_n[s], where the elim ord for s is set
+  ideal J = NF(I,std(F));
+  // make leadcoeffs positive
+  int i;
+  for (i=1; i<= ncols(J); i++)
+  {
+    if (leadcoef(J[i]) <0 )
+    {
+      J[i] = -J[i];
+    }
+  }
+  J = J,F;
+  ideal M = engine(J,eng);
+  int Nnew = nvars(@R2);
+  ideal K2 = nselect(M,1..Nnew-1);
+  int ppl = printlevel-voice+2;
+  dbprint(ppl,"// -1-1- _x,_Dx are eliminated in basering");
+  dbprint(ppl-1, K2);
+  // the ring @R3 and the search for minimal negative int s
+  ring @R3 = 0,s,dp;
+  dbprint(ppl,"// -2-1- the ring @R3 i.e. K[s] is ready");
+  ideal K3 = imap(@R2,K2);
+  poly p = K3[1];
+  dbprint(ppl,"// -2-2- factorization");
+  //  ideal P = factorize(p,1);  //without constants and multiplicities
+  //  "--------- b-function factorizes into ---------";   P;
+  // convert factors to the list of their roots with mults
+  // assume all factors are linear
+  //  ideal BS = normalize(P);
+  //  BS = subst(BS,s,0);
+  //  BS = -BS;
+  list P = factorize(p);          //with constants and multiplicities
+  ideal bs; intvec m;             //the Bernstein polynomial is monic, so we are not interested in constants
+  for (i=2; i<= size(P[1]); i++)  //we delete P[1][1] and P[2][1]
+  {
+    bs[i-1] = P[1][i];
+    m[i-1]  = P[2][i];
+  }
+  int sP = minIntRoot(bs,1);
+  bs =  normalize(bs);
+  bs = -subst(bs,s,0);
+  dbprint(ppl,"// -2-3- minimal integer root found");
+  dbprint(ppl-1, sP);
+ //TODO: sort BS!
+  // --------- substitute s found in the ideal ---------
+  // --------- going back to @R and substitute ---------
+  setring @R2;
+  K2 = subst(I,s,sP);
+  // create the ordinary Weyl algebra and put the result into it,
+  // thus creating the ring @R5
+  // keep: N, i,j,s, tmp, RL
+  Nnew = Nnew - 1; // former 2*N;
+  // list RL = ringlist(save);  // is defined earlier
+  //  kill Lord, tmp, iv;
+  list L = 0;
+  list Lord, tmp;
+  intvec iv;
+  list RL = ringlist(basering);
+  L[1] = RL[1];
+  L[4] = RL[4];  //char, minpoly
+  // check whether vars have admissible names -> done earlier
+  // list Name = RL[2]M
+  // DName is defined earlier
+  list NName; // = RL[2]; // skip the last var 's'
+  for (i=1; i<=Nnew; i++)
+  {
+    NName[i] =  RL[2][i];
+  }
+  L[2] = NName;
+  // dp ordering;
+  string s = "iv=";
+  for (i=1; i<=Nnew; i++)
+  {
+    s = s+"1,";
+  }
+  s[size(s)] = ";";
+  execute(s);
+  tmp     = 0;
+  tmp[1]  = "dp";  // string
+  tmp[2]  = iv;  // intvec
+  Lord[1] = tmp;
+  kill s;
+  tmp[1]  = "C";
+  iv = 0;
+  tmp[2]  = iv;
+  Lord[2] = tmp;
+  tmp     = 0;
+  L[3]    = Lord;
+  // we are done with the list
+  // Add: Plural part
+  def @R4@ = ring(L);
+  setring @R4@;
+  int N = Nnew div 2;
+  matrix @D[Nnew][Nnew];
+  for (i=1; i<=N; i++)
+  {
+    @D[i,N+i]=1;
+  }
+  def @R4 = nc_algebra(1, at D);
+  setring @R4;
+  kill @R4@;
+  dbprint(ppl,"// -3-1- the ring @R4 is ready");
+  dbprint(ppl-1, @R4);
+  ideal K4 = imap(@R2,K2);
+  intvec saveopt=option(get);
+  option(redSB);
+  dbprint(ppl,"// -3-2- the final cosmetic std");
+  K4 = engine(K4,eng);  // std does the job too
+  // total cleanup
+  ideal bs = imap(@R3,bs);
+  kill @R3;
+  list BS = bs,m;
+  export BS;
+  ideal LD = K4;
+  export LD;
+  option(set,saveopt);
+  return(@R4);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y,z),Dp;
+  poly F = x^3+y^3+z^3;
+  printlevel = 0;
+  def A = SannfsBM(F);   setring A;
+  // alternatively, one can use SannfsOT or SannfsLOT
+  LD;
+  poly F = imap(r,F);
+  def B  = annfs0(LD,F);  setring B;
+  LD;
+  BS;
+}
+
+// proc annfsgms(poly F, list #)
+// "USAGE:  annfsgms(f [,eng]);  f a poly, eng an optional int
+// ASSUME:  f has an isolated critical point at 0
+// RETURN:  ring
+// PURPOSE: compute the D-module structure of basering[1/f]*f^s
+// NOTE:    activate the output ring with the @code{setring} command. In this ring,
+// @*       - the ideal LD is the needed D-mod structure,
+// @*       - the ideal BS is the list of roots of a Bernstein polynomial of f.
+// @*       If eng <>0, @code{std} is used for Groebner basis computations,
+// @*       otherwise (and by default) @code{slimgb} is used.
+// @*       If printlevel=1, progress debug messages will be printed,
+// @*       if printlevel>=2, all the debug messages will be printed.
+// EXAMPLE: example annfsgms; shows examples
+// "
+// {
+//   LIB "gmssing.lib";
+//   int eng = 0;
+//   if ( size(#)>0 )
+//   {
+//     if ( typeof(#[1]) == "int" )
+//     {
+//       eng = int(#[1]);
+//     }
+//   }
+//   int ppl = printlevel-voice+2;
+//   // returns a ring with the ideal LD in it
+//   def save = basering;
+//   // compute the Bernstein polynomial from gmssing.lib
+//   list RL = ringlist(basering);
+//   // in the descr. of the ordering, replace "p" by "s"
+//   list NL = convloc(RL);
+//   // create a ring with the ordering, converted to local
+//   def @LR = ring(NL);
+//   setring @LR;
+//   poly F  = imap(save, F);
+//   ideal B = bernstein(F)[1];
+//   // since B may not contain (s+1) [following gmssing.lib]
+//   // add it!
+//   B = B,-1;
+//   B = simplify(B,2+4); // erase zero and repeated entries
+//   // find the minimal integer value
+//   int   S = minIntRoot(B,0);
+//   dbprint(ppl,"// -0- minimal integer root found");
+//   dbprint(ppl-1,S);
+//   setring save;
+//   int N = nvars(basering);
+//   int Nnew = 2*(N+2);
+//   int i,j;
+//   string s;
+//   //  list RL = ringlist(basering);
+//   list L, Lord;
+//   list tmp;
+//   intvec iv;
+//   L[1] = RL[1]; // char
+//   L[4] = RL[4]; // char, minpoly
+//   // check whether vars have admissible names
+//   list Name  = RL[2];
+//   list RName;
+//   RName[1] = "u";
+//   RName[2] = "v";
+//   RName[3] = "t";
+//   RName[4] = "Dt";
+//   for(i=1;i<=N;i++)
+//   {
+//     for(j=1; j<=size(RName);j++)
+//     {
+//       if (Name[i] == RName[j])
+//       {
+//         ERROR("Variable names should not include u,v,t,Dt");
+//       }
+//     }
+//   }
+//   // now, create the names for new vars
+//   //  tmp[1]     = "u";  tmp[2]     = "v";  tmp[3]     = "t";  tmp[4]     = "Dt";
+//   list UName = RName;
+//   list DName;
+//   for(i=1;i<=N;i++)
+//   {
+//     DName[i] = "D"+Name[i]; // concat
+//   }
+//   list NName = UName + Name + DName;
+//   L[2]       = NName;
+//   tmp        = 0;
+//   // Name, Dname will be used further
+//   kill UName;
+//   kill NName;
+//   // block ord (a(1,1),dp);
+//   tmp[1]  = "a"; // string
+//   iv      = 1,1;
+//   tmp[2]  = iv; //intvec
+//   Lord[1] = tmp;
+//   // continue with dp 1,1,1,1...
+//   tmp[1]  = "dp"; // string
+//   s       = "iv=";
+//   for(i=1; i<=Nnew; i++) // need really all vars!
+//   {
+//     s = s+"1,";
+//   }
+//   s[size(s)]= ";";
+//   execute(s);
+//   tmp[2]    = iv;
+//   Lord[2]   = tmp;
+//   tmp[1]    = "C";
+//   iv        = 0;
+//   tmp[2]    = iv;
+//   Lord[3]   = tmp;
+//   tmp       = 0;
+//   L[3]      = Lord;
+//   // we are done with the list
+//   def @R = ring(L);
+//   setring @R;
+//   matrix @D[Nnew][Nnew];
+//   @D[3,4] = 1; // t,Dt
+//   for(i=1; i<=N; i++)
+//   {
+//     @D[4+i,4+N+i]=1;
+//   }
+//   //  L[5] = matrix(UpOneMatrix(Nnew));
+//   //  L[6] = @D;
+//   nc_algebra(1, at D);
+//   dbprint(ppl,"// -1-1- the ring @R is ready");
+//   dbprint(ppl-1, at R);
+//   // create the ideal
+//   poly F  = imap(save,F);
+//   ideal I = u*F-t,u*v-1;
+//   poly p;
+//   for(i=1; i<=N; i++)
+//   {
+//     p = u*Dt; // u*Dt
+//     p = diff(F,var(4+i))*p;
+//     I = I, var(N+4+i) + p; // Dx, Dy
+//   }
+//   // add the relations between t,Dt and s
+//   //  I = I, t*Dt+1+S;
+//   // -------- the ideal I is ready ----------
+//   dbprint(ppl,"// -1-2- starting the elimination of u,v in @R");
+//   ideal J = engine(I,eng);
+//   ideal K = nselect(J,1..2);
+//   dbprint(ppl,"// -1-3- u,v are eliminated in @R");
+//   dbprint(ppl-1,K); // without u,v: not yet our answer
+//   //----- create a ring with elim.ord for t,Dt -------
+//   setring save;
+//   // ------------ new ring @R2 ------------------
+//   // without u,v and with the elim.ord for t,Dt
+//   // keep: N, i,j,s, tmp, RL
+//   Nnew = 2*N+2;
+//   //  list RL = ringlist(save); // is defined earlier
+//   kill Lord,tmp,iv, RName;
+//   L = 0;
+//   list Lord, tmp;
+//   intvec iv;
+//   L[1] = RL[1]; // char
+//   L[4] = RL[4]; // char, minpoly
+//   // check whether vars have admissible names -> done earlier
+//   //  list Name  = RL[2];
+//   list RName;
+//   RName[1] = "t";
+//   RName[2] = "Dt";
+//   // DName is defined earlier
+//   list NName = RName + Name + DName;
+//   L[2]   = NName;
+//   tmp    = 0;
+//   // block ord (a(1,1),dp);
+//   tmp[1]  = "a"; // string
+//   iv      = 1,1;
+//   tmp[2]  = iv; //intvec
+//   Lord[1] = tmp;
+//   // continue with dp 1,1,1,1...
+//   tmp[1]  = "dp"; // string
+//   s       = "iv=";
+//   for(i=1;i<=Nnew;i++)
+//   {
+//     s = s+"1,";
+//   }
+//   s[size(s)]= ";";
+//   execute(s);
+//   kill s;
+//   kill NName;
+//   tmp[2]    = iv;
+//   Lord[2]   = tmp;
+//   tmp[1]    = "C";
+//   iv        = 0;
+//   tmp[2]    = iv;
+//   Lord[3]   = tmp;
+//   tmp       = 0;
+//   L[3]      = Lord;
+//   // we are done with the list
+//   // Add: Plural part
+//   def @R2 = ring(L);
+//   setring @R2;
+//   matrix @D[Nnew][Nnew];
+//   @D[1,2]=1;
+//   for(i=1; i<=N; i++)
+//   {
+//     @D[2+i,2+N+i]=1;
+//   }
+//   nc_algebra(1, at D);
+//   dbprint(ppl,"// -2-1- the ring @R2 is ready");
+//   dbprint(ppl-1, at R2);
+//   ideal MM = maxideal(1);
+//   MM = 0,0,MM;
+//   map R01 = @R, MM;
+//   ideal K2 = R01(K);
+//   // add the relations between t,Dt and s
+//   //  K2       = K2, t*Dt+1+S;
+//   poly G = t*Dt+S+1;
+//   K2 = NF(K2,std(G)),G;
+//   dbprint(ppl,"// -2-2- starting elimination for t,Dt in @R2");
+//   ideal J  = engine(K2,eng);
+//   ideal K  = nselect(J,1..2);
+//   dbprint(ppl,"// -2-3- t,Dt are eliminated");
+//   dbprint(ppl-1,K);
+//   //  "------- produce a final result --------";
+//   // ----- create the ordinary Weyl algebra and put
+//   // ----- the result into it
+//   // ------ create the ring @R5
+//   // keep: N, i,j,s, tmp, RL
+//   setring save;
+//   Nnew = 2*N;
+//   //  list RL = ringlist(save); // is defined earlier
+//   kill Lord, tmp, iv;
+//   //  kill L;
+//   L = 0;
+//   list Lord, tmp;
+//   intvec iv;
+//   L[1] = RL[1]; // char
+//   L[4] = RL[4]; // char, minpoly
+//   // check whether vars have admissible names -> done earlier
+//   //  list Name  = RL[2];
+//   // DName is defined earlier
+//   list NName = Name + DName;
+//   L[2]   = NName;
+//   // dp ordering;
+//   string   s       = "iv=";
+//   for(i=1;i<=2*N;i++)
+//   {
+//     s = s+"1,";
+//   }
+//   s[size(s)]= ";";
+//   execute(s);
+//   tmp     = 0;
+//   tmp[1]  = "dp"; // string
+//   tmp[2]  = iv; //intvec
+//   Lord[1] = tmp;
+//   kill s;
+//   tmp[1]    = "C";
+//   iv        = 0;
+//   tmp[2]    = iv;
+//   Lord[2]   = tmp;
+//   tmp       = 0;
+//   L[3]      = Lord;
+//   // we are done with the list
+//   // Add: Plural part
+//   def @R5 = ring(L);
+//   setring @R5;
+//   matrix @D[Nnew][Nnew];
+//   for(i=1; i<=N; i++)
+//   {
+//     @D[i,N+i]=1;
+//   }
+//   nc_algebra(1, at D);
+//   dbprint(ppl,"// -3-1- the ring @R5 is ready");
+//   dbprint(ppl-1, at R5);
+//   ideal K5 = imap(@R2,K);
+//   option(redSB);
+//   dbprint(ppl,"// -3-2- the final cosmetic std");
+//   K5 = engine(K5,eng); // std does the job too
+//   // total cleanup
+//   kill @R;
+//   kill @R2;
+//   ideal LD = K5;
+//   ideal BS = imap(@LR,B);
+//   kill @LR;
+//   export BS;
+//   export LD;
+//   return(@R5);
+// }
+// example
+// {
+//   "EXAMPLE:"; echo = 2;
+//   ring r = 0,(x,y,z),Dp;
+//   poly F = x^2+y^3+z^5;
+//   def A = annfsgms(F);
+//   setring A;
+//   LD;
+//   print(matrix(BS));
+// }
+
+
+proc convloc(list @NL)
+"USAGE:  convloc(L); L a list
+RETURN:  list
+PURPOSE: convert a ringlist L into another ringlist,
+@* where all the 'p' orderings are replaced with the 's' orderings, e.g. @code{dp} by @code{ds}.
+ASSUME: L is a result of a ringlist command
+EXAMPLE: example convloc; shows examples
+"
+{
+  list NL = @NL;
+  // given a ringlist, returns a new ringlist,
+  // where all the p-orderings are replaced with s-ord's
+  int i,j,k,found;
+  int nblocks = size(NL[3]);
+  for(i=1; i<=nblocks; i++)
+  {
+    for(j=1; j<=size(NL[3][i]); j++)
+    {
+      if (typeof(NL[3][i][j]) == "string" )
+      {
+        found = 0;
+        for (k=1; k<=size(NL[3][i][j]); k++)
+        {
+          if (NL[3][i][j][k]=="p")
+          {
+            NL[3][i][j][k]="s";
+            found = 1;
+            //    printf("replaced at %s,%s,%s",i,j,k);
+          }
+        }
+      }
+    }
+  }
+  return(NL);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y,z),(Dp(2),dp(1));
+  list L = ringlist(r);
+  list N = convloc(L);
+  def rs = ring(N);
+  setring rs;
+  rs;
+}
+
+proc annfspecial(ideal I, poly F, int mir, number n)
+"USAGE:  annfspecial(I,F,mir,n);  I an ideal, F a poly, int mir, number n
+RETURN:  ideal
+PURPOSE: compute the annihilator ideal of F^n in the Weyl Algebra
+@*           for the given rational number n
+ASSUME:  The basering is D[s] and contains 's' explicitly as a variable,
+@*   the ideal I is the Ann F^s in D[s] (obtained with e.g. SannfsBM),
+@*   the integer 'mir' is the minimal integer root of the BS polynomial of F,
+@*   and the number n is rational.
+NOTE: We compute the real annihilator for any rational value of n (both
+@*       generic and exceptional). The implementation goes along the lines of
+@*       the Algorithm 5.3.15 from Saito-Sturmfels-Takayama.
+DISPLAY: If printlevel=1, progress debug messages will be printed,
+@*       if printlevel>=2, all the debug messages will be printed.
+EXAMPLE: example annfspecial; shows examples
+"
+{
+
+  if (!isRational(n))
+  {
+    "ERROR: n must be a rational number!";
+  }
+  int ppl = printlevel-voice+2;
+  //  int mir =  minIntRoot(L[1],0);
+  int ns   = rvar("s");
+  if (!ns)
+  {
+    ERROR("Variable s expected in the ideal AnnFs");
+  }
+  int d;
+  ideal P = subst(I,var(ns),n);
+  if (denominator(n) == 1)
+  {
+    // n is fraction-free
+    d = int(numerator(n));
+    if ( (!d) && (n!=0))
+    {
+      ERROR("no parametric special values are allowed");
+    }
+    d = d - mir;
+    if (d>0)
+    {
+      dbprint(ppl,"// -1-1- starting syzygy computations");
+      matrix J[1][1] = F^d;
+      dbprint(ppl-1,"// -1-1-1- of the polynomial ideal");
+      dbprint(ppl-1,J);
+      matrix K[1][size(I)] = subst(I,var(ns),mir);
+      dbprint(ppl-1,"// -1-1-2- modulo ideal:");
+      dbprint(ppl-1, K);
+      module M = modulo(J,K);
+      dbprint(ppl-1,"// -1-1-3- getting the result:");
+      dbprint(ppl-1, M);
+      P  = P, ideal(M);
+      dbprint(ppl,"// -1-2- finished syzygy computations");
+    }
+    else
+    {
+      dbprint(ppl,"// -1-1- d<=0, no syzygy computations needed");
+      dbprint(ppl-1,"// -1-2- for d =");
+      dbprint(ppl-1, d);
+    }
+  }
+  // also the else case: d<=0 or n is not an integer
+  dbprint(ppl,"// -2-1- starting final Groebner basis");
+  P = groebner(P);
+  dbprint(ppl,"// -2-2- finished final Groebner basis");
+  return(P);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y),dp;
+  poly F = x3-y2;
+  def  B = annfs(F);  setring B;
+  minIntRoot(BS[1],0);
+  // So, the minimal integer root is -1
+  setring r;
+  def  A = SannfsBM(F);
+  setring A;
+  poly F = x3-y2;
+  annfspecial(LD,F,-1,3/4); // generic root
+  annfspecial(LD,F,-1,-2);  // integer but still generic root
+  annfspecial(LD,F,-1,1);   // exceptional root
+}
+
+/*
+//static proc new_ex_annfspecial()
+{
+  //another example for annfspecial: x3+y3+z3
+  ring r = 0,(x,y,z),dp;
+  poly F =  x3+y3+z3;
+  def  B = annfs(F);  setring B;
+  minIntRoot(BS[1],0);
+  // So, the minimal integer root is -1
+  setring r;
+  def  A = SannfsBM(F);
+  setring A;
+  poly F =  x3+y3+z3;
+  annfspecial(LD,F,-1,3/4); // generic root
+  annfspecial(LD,F,-1,-2);  // integer but still generic root
+  annfspecial(LD,F,-1,1);   // exceptional root
+}
+*/
+
+proc minIntRoot(ideal P, int fact)
+"USAGE:  minIntRoot(P, fact); P an ideal, fact an int
+RETURN:  int
+PURPOSE: minimal integer root of a maximal ideal P
+NOTE:    if fact==1, P is the result of some 'factorize' call,
+@*       else P is treated as the result of bernstein::gmssing.lib
+@*       in both cases without constants and multiplicities
+EXAMPLE: example minIntRoot; shows examples
+"
+{
+  //    ideal P = factorize(p,1);
+  // or ideal P = bernstein(F)[1];
+  intvec vP;
+  number nP;
+  int i;
+  if ( fact )
+  {
+    // the result comes from "factorize"
+    P = normalize(P); // now leadcoef = 1
+    // TODO: hunt for units and kill then !!!
+    P = matrix(lead(P))-P;
+    // nP = leadcoef(P[i]-lead(P[i])); // for 1 var only, extract the coeff
+  }
+  else
+  {
+    // bernstein deletes -1 usually
+    P = P, -1;
+  }
+  // for both situations:
+  // now we have an ideal of fractions of type "number"
+  int sP = size(P);
+  for(i=1; i<=sP; i++)
+  {
+    nP = leadcoef(P[i]);
+    if ( (nP - int(nP)) == 0 )
+    {
+      vP = vP,int(nP);
+    }
+  }
+  if ( size(vP)>=2 )
+  {
+    vP = vP[2..size(vP)];
+  }
+  sP = -Max(-vP);
+  if (sP == 0)
+  {
+    "Warning: zero root present!";
+  }
+  return(sP);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r   = 0,(x,y),ds;
+  poly f1  = x*y*(x+y);
+  ideal I1 = bernstein(f1)[1]; // a local Bernstein poly
+  I1;
+  minIntRoot(I1,0);
+  poly  f2  = x2-y3;
+  ideal I2  = bernstein(f2)[1];
+  I2;
+  minIntRoot(I2,0);
+  // now we illustrate the behaviour of factorize
+  // together with a global ordering
+  ring r2  = 0,x,dp;
+  poly f3   = 9*(x+2/3)*(x+1)*(x+4/3); //global b-polynomial of f1=x*y*(x+y)
+  ideal I3 = factorize(f3,1);
+  I3;
+  minIntRoot(I3,1);
+  // and a more interesting situation
+  ring  s  = 0,(x,y,z),ds;
+  poly  f  = x3 + y3 + z3;
+  ideal I  = bernstein(f)[1];
+  I;
+  minIntRoot(I,0);
+}
+
+proc isHolonomic(def M)
+"USAGE:  isHolonomic(M); M an ideal/module/matrix
+RETURN:  int, 1 if M is holonomic over the base ring, and 0 otherwise
+ASSUME: basering is a Weyl algebra in characteristic 0
+PURPOSE: check whether M is holonomic over the base ring
+NOTE:    M is holonomic if 2*dim(M) = dim(R), where R is the
+base ring; dim stands for Gelfand-Kirillov dimension
+EXAMPLE: example isHolonomic; shows examples
+"
+{
+  // char>0 or qring
+  if (  (size(ideal(basering)) >0) || (char(basering) >0) )
+  {
+    ERROR("Basering is inappropriate: characteristic>0 or qring present");
+  }
+  if (!isWeyl(basering))
+  {
+    ERROR("Basering is not a Weyl algebra");
+  }
+
+  if ( (typeof(M) != "ideal") && (typeof(M) != "module") && (typeof(M) != "matrix") )
+  {
+  //  print(typeof(M));
+    ERROR("an argument of type ideal/module/matrix expected");
+  }
+  if (attrib(M,"isSB")!=1)
+  {
+    M = engine(M,0);
+  }
+  int dimR = gkdim(std(0));
+  int dimM = gkdim(M);
+  return( (dimR==2*dimM) );
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring R = 0,(x,y),dp;
+  poly F = x*y*(x+y);
+  def A = annfsBM(F,0);
+  setring A;
+  LD;
+  isHolonomic(LD);
+  ideal I = std(LD[1]);
+  I;
+  isHolonomic(I);
+}
+
+proc reiffen(int p, int q)
+"USAGE:  reiffen(p, q);  int p, int q
+RETURN:  ring
+PURPOSE: set up the polynomial, describing a Reiffen curve
+NOTE:  activate the output ring with the @code{setring} command and
+@*       find the curve as a polynomial RC.
+@*  A Reiffen curve is defined as RC = x^p + y^q + xy^{q-1}, q >= p+1 >= 5
+
+EXAMPLE: example reiffen; shows examples
+"
+{
+  // we allow also other numbers, p \geq 1, q\geq 1
+// a Reiffen curve is defined as
+// F = x^p + y^q +x*y^{q-1}, q \geq p+1 \geq 5
+
+// ASSUME: q >= p+1 >= 5. Otherwise an error message is returned
+
+//   if ( (p<4) || (q<5) || (q-p<1) )
+//   {
+//     ERROR("Some of conditions p>=4, q>=5 or q>=p+1 is not satisfied!");
+//   }
+  if ( (p<1) || (q<1) )
+  {
+    ERROR("Some of conditions p>=1, q>=1 is not satisfied!");
+  }
+  ring @r = 0,(x,y),dp;
+  poly RC = y^q +x^p + x*y^(q-1);
+  export RC;
+  return(@r);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  def r = reiffen(4,5);
+  setring r;
+  RC;
+}
+
+proc arrange(int p)
+"USAGE:  arrange(p);  int p
+RETURN:  ring
+PURPOSE: set up the polynomial, describing a hyperplane arrangement
+NOTE:  must be executed in a commutative ring
+ASSUME: basering is present and it is commutative
+EXAMPLE: example arrange; shows examples
+"
+{
+  int UseBasering = 0 ;
+  if (p<2)
+  {
+    ERROR("p>=2 is required!");
+  }
+  if ( nameof(basering)!="basering" )
+  {
+    if (p > nvars(basering))
+    {
+      ERROR("too big p");
+    }
+    else
+    {
+      def @r = basering;
+      UseBasering = 1;
+    }
+  }
+  else
+  {
+    // no basering found
+    ERROR("no basering found!");
+    //    ring @r = 0,(x(1..p)),dp;
+  }
+  int i,j,sI;
+  poly  q = 1;
+  list ar;
+  ideal tmp;
+  tmp = ideal(var(1));
+  ar[1] = tmp;
+  for (i = 2; i<=p; i++)
+  {
+    // add i-nary sums to the product
+    ar = indAR(ar,i);
+  }
+  for (i = 1; i<=p; i++)
+  {
+    tmp = ar[i]; sI = size(tmp);
+    for (j = 1; j<=sI; j++)
+    {
+      q = q*tmp[j];
+    }
+  }
+  if (UseBasering)
+  {
+    return(q);
+  }
+  //  poly AR = q; export AR;
+  //  return(@r);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring X = 0,(x,y,z,t),dp;
+  poly q = arrange(3);
+  factorize(q,1);
+}
+
+proc checkRoot(poly F, number a, list #)
+"USAGE:  checkRoot(f,alpha [,S,eng]);  poly f, number alpha, string S, int eng
+RETURN:  int
+ASSUME: Basering is a commutative ring, alpha is a positive rational number.
+PURPOSE: check whether a negative rational number -alpha is a root of the global
+@* Bernstein-Sato polynomial of f and compute its multiplicity,
+@* with the algorithm given by S and with the Groebner basis engine given by eng.
+NOTE:  The annihilator of f^s in D[s] is needed and hence it is computed with the
+@*       algorithm by Briancon and Maisonobe. The value of a string S can be
+@*       'alg1' (default) - for the algorithm 1 of [LM08]
+@*       'alg2' - for the algorithm 2 of [LM08]
+@*       Depending on the value of S, the output of type int is:
+@*       'alg1': 1 only if -alpha is a root of the global Bernstein-Sato polynomial
+@*       'alg2':  the multiplicity of -alpha as a root of the global Bernstein-Sato
+@*                  polynomial of f. If -alpha is not a root, the output is 0.
+@*       If eng <>0, @code{std} is used for Groebner basis computations,
+@*       otherwise (and by default) @code{slimgb} is used.
+DISPLAY: If printlevel=1, progress debug messages will be printed,
+@*          if printlevel>=2, all the debug messages will be printed.
+EXAMPLE: example checkRoot; shows examples
+"
+{
+  int eng = 0;
+  int chs = 0; // choice
+  string algo = "alg1";
+  string st;
+  if ( size(#)>0 )
+  {
+   if ( typeof(#[1]) == "string" )
+   {
+     st = string(#[1]);
+     if ( (st == "alg1") || (st == "ALG1") || (st == "Alg1") ||(st == "aLG1"))
+     {
+       algo = "alg1";
+       chs  = 1;
+     }
+     if ( (st == "alg2") || (st == "ALG2") || (st == "Alg2") || (st == "aLG2"))
+     {
+       algo = "alg2";
+       chs  = 1;
+     }
+     if (chs != 1)
+     {
+       // incorrect value of S
+       print("Incorrect algorithm given, proceed with the default alg1");
+       algo = "alg1";
+     }
+     // second arg
+     if (size(#)>1)
+     {
+       // exists 2nd arg
+       if ( typeof(#[2]) == "int" )
+       {
+         // the case: given alg, given engine
+         eng = int(#[2]);
+       }
+       else
+       {
+         eng = 0;
+       }
+     }
+     else
+     {
+       // no second arg
+       eng = 0;
+     }
+   }
+   else
+   {
+     if ( typeof(#[1]) == "int" )
+     {
+       // the case: default alg, engine
+       eng = int(#[1]);
+       // algo = "alg1";  //is already set
+     }
+     else
+     {
+       // incorr. 1st arg
+       algo = "alg1";
+     }
+   }
+  }
+  // size(#)=0, i.e. there is no algorithm and no engine given
+  //  eng = 0; algo = "alg1";  //are already set
+  // int ppl = printlevel-voice+2;
+// check assume: a is positive rational number
+  if (!isRational(a))
+  {
+    ERROR("rational root expected for checking");
+  }
+  if (numerator(a) < 0 )
+  {
+    ERROR("expected positive -alpha");
+    // the following is more user-friendly but less correct
+    //    print("proceeding with the negated root");
+    //    a = -a;
+  }
+  printlevel=printlevel+1;
+  def save = basering;
+  def @A = SannfsBM(F);
+  setring @A;
+  poly F = imap(save,F);
+  number a = imap(save,a);
+  if ( algo=="alg1")
+  {
+    int output = checkRoot1(LD,F,a,eng);
+  }
+  else
+  {
+    if ( algo=="alg2")
+    {
+      int output = checkRoot2(LD,F,a,eng);
+    }
+  }
+  printlevel=printlevel-1;
+  return(output);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  printlevel=0;
+  ring r = 0,(x,y),Dp;
+  poly F = x^4+y^5+x*y^4;
+  checkRoot(F,11/20);    // -11/20 is a root of bf
+  poly G = x*y;
+  checkRoot(G,1,"alg2"); // -1 is a root of bg with multiplicity 2
+}
+
+proc checkRoot1(ideal I, poly F, number a, list #)
+"USAGE:  checkRoot1(I,f,alpha [,eng]);  ideal I, poly f, number alpha, int eng
+ASSUME:  Basering is D[s], I is the annihilator of f^s in D[s],
+@* that is basering and I are the output of Sannfs-like procedure,
+@* f is a polynomial in K[x] and alpha is a rational number.
+RETURN:  int, 1 if -alpha is a root of the Bernstein-Sato polynomial of f
+PURPOSE: check, whether alpha is a root of the global Bernstein-Sato polynomial of f
+NOTE:  If eng <>0, @code{std} is used for Groebner basis computations,
+@*       otherwise (and by default) @code{slimgb} is used.
+DISPLAY: If printlevel=1, progress debug messages will be printed,
+@*          if printlevel>=2, all the debug messages will be printed.
+EXAMPLE: example checkRoot1; shows examples
+"
+{
+  // to check: alpha is rational (has char 0 check inside)
+  if (!isRational(a))
+  {
+    "ERROR: alpha must be a rational number!";
+  }
+  //  no qring
+  if ( size(ideal(basering)) >0 )
+  {
+    "ERROR: no qring is allowed";
+  }
+  int eng = 0;
+  if ( size(#)>0 )
+  {
+    if ( typeof(#[1]) == "int" )
+    {
+      eng = int(#[1]);
+    }
+  }
+  int ppl = printlevel-voice+2;
+  dbprint(ppl,"// -0-1- starting the procedure checkRoot1");
+  def save = basering;
+  int N = nvars(basering);
+  int Nnew = N-1;
+  int n = Nnew div 2;
+  int i;
+  string s;
+  list RL = ringlist(basering);
+  list L, Lord;
+  list tmp;
+  intvec iv;
+  L[1] = RL[1];  // char
+  L[4] = RL[4];  // char, minpoly
+  // check whether basering is D[s]=K(_x,_Dx,s)
+  list Name = RL[2];
+//   for (i=1; i<=n; i++)
+//   {
+//     if ( bracket(var(i+n),var(i))!=1 )
+//     {
+//       ERROR("basering should be D[s]=K(_x,_Dx,s)");
+//     }
+//   }
+  if ( Name[N]!="s" )
+  {
+    ERROR("the last variable of basering should be s");
+  }
+  // now, create the new vars
+  list NName;
+  for (i=1; i<=Nnew; i++)
+  {
+    NName[i] = Name[i];
+  }
+  L[2] = NName;
+  kill Name,NName;
+  // block ord (dp);
+  tmp[1] = "dp"; // string
+  s = "iv=";
+  for (i=1; i<=Nnew; i++)
+  {
+    s = s+"1,";
+  }
+  s[size(s)]=";";
+  execute(s);
+  kill s;
+  tmp[2]  = iv;
+  Lord[1] = tmp;
+  tmp[1]  = "C";
+  iv      = 0;
+  tmp[2]  = iv;
+  Lord[2] = tmp;
+  tmp     = 0;
+  L[3]    = Lord;
+  // we are done with the list
+  def @R@ = ring(L);
+  setring @R@;
+  matrix @D[Nnew][Nnew];
+  for (i=1; i<=n; i++)
+  {
+    @D[i,i+n]=1;
+  }
+  def @R = nc_algebra(1, at D);
+  setring @R;
+  kill @R@;
+  dbprint(ppl,"// -1-1- the ring @R(_x,_Dx) is ready");
+  dbprint(ppl-1, S);
+  // create the ideal K = ann_D[s](f^s)_{s=-alpha} + < f >
+  setring save;
+  ideal K = subst(I,s,-a);
+  dbprint(ppl,"// -1-2- the variable s has been substituted by "+string(-a));
+  dbprint(ppl-1, K);
+  K = NF(K,std(F));
+  // make leadcoeffs positive
+  for (i=1; i<=ncols(K); i++)
+  {
+    if ( leadcoef(K[i])<0 )
+    {
+      K[i] = -K[i];
+    }
+  }
+  K = K,F;
+  // ------------ the ideal K is ready ------------
+  setring @R;
+  ideal K = imap(save,K);
+  dbprint(ppl,"// -1-3- starting the computation of a Groebner basis of K in @R");
+  dbprint(ppl-1, K);
+  ideal G = engine(K,eng);
+  dbprint(ppl,"// -1-4- the Groebner basis has been computed");
+  dbprint(ppl-1, G);
+  return(G[1]!=1);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y),Dp;
+  poly F = x^4+y^5+x*y^4;
+  printlevel = 0;
+  def A = Sannfs(F);
+  setring A;
+  poly F = imap(r,F);
+  checkRoot1(LD,F,31/20);   // -31/20 is not a root of bs
+  checkRoot1(LD,F,11/20);   // -11/20 is a root of bs
+}
+
+proc checkRoot2 (ideal I, poly F, number a, list #)
+"USAGE:  checkRoot2(I,f,a [,eng]);  I an ideal, f a poly, alpha a number, eng an optional int
+ASSUME:  I is the annihilator of f^s in D[s], basering is D[s],
+@* that is basering and I are the output os Sannfs-like procedure,
+@* f is a polynomial in K[_x] and alpha is a rational number.
+RETURN:  int, the multiplicity of -alpha as a root of the BS polynomial of f.
+PURPOSE: check whether a rational number alpha is a root of the global Bernstein-
+@* Sato polynomial of f and compute its multiplicity from the known Ann F^s in D[s]
+NOTE:   If -alpha is not a root, the output is 0.
+@*       If eng <>0, @code{std} is used for Groebner basis computations,
+@*       otherwise (and by default) @code{slimgb} is used.
+DISPLAY: If printlevel=1, progress debug messages will be printed,
+@*          if printlevel>=2, all the debug messages will be printed.
+EXAMPLE: example checkRoot2; shows examples
+"
+{
+
+
+  // to check: alpha is rational (has char 0 check inside)
+  if (!isRational(a))
+  {
+    "ERROR: alpha must be a rational number!";
+  }
+  //  no qring
+  if ( size(ideal(basering)) >0 )
+  {
+    "ERROR: no qring is allowed";
+  }
+
+  int eng = 0;
+  if ( size(#)>0 )
+  {
+    if ( typeof(#[1]) == "int" )
+    {
+      eng = int(#[1]);
+    }
+  }
+  int ppl = printlevel-voice+2;
+  dbprint(ppl,"// -0-1- starting the procedure checkRoot2");
+  def save = basering;
+  int N = nvars(basering);
+  int n = (N-1) div 2;
+  int i;
+  string s;
+  list RL = ringlist(basering);
+  list L, Lord;
+  list tmp;
+  intvec iv;
+  L[1] = RL[1];  // char
+  L[4] = RL[4];  // char, minpoly
+  // check whether basering is D[s]=K(_x,_Dx,s)
+  list Name = RL[2];
+  for (i=1; i<=n; i++)
+  {
+    if ( bracket(var(i+n),var(i))!=1 )
+    {
+      ERROR("basering should be D[s]=K(_x,_Dx,s)");
+    }
+  }
+  if ( Name[N]!="s" )
+  {
+    ERROR("the last variable of basering should be s");
+  }
+  // now, create the new vars
+  L[2] = Name;
+  kill Name;
+  // block ord (dp);
+  tmp[1] = "dp"; // string
+  s = "iv=";
+  for (i=1; i<=N; i++)
+  {
+    s = s+"1,";
+  }
+  s[size(s)]=";";
+  execute(s);
+  kill s;
+  tmp[2]  = iv;
+  Lord[1] = tmp;
+  tmp[1]  = "C";
+  iv      = 0;
+  tmp[2]  = iv;
+  Lord[2] = tmp;
+  tmp     = 0;
+  L[3]    = Lord;
+  // we are done with the list
+  def @R@ = ring(L);
+  setring @R@;
+  matrix @D[N][N];
+  for (i=1; i<=n; i++)
+  {
+    @D[i,i+n]=1;
+  }
+  def @R = nc_algebra(1, at D);
+  setring @R;
+  kill @R@;
+  dbprint(ppl,"// -1-1- the ring @R(_x,_Dx,s) is ready");
+  dbprint(ppl-1, @R);
+  // now, continue with the algorithm
+  ideal I = imap(save,I);
+  poly F = imap(save,F);
+  number a = imap(save,a);
+  ideal II = NF(I,std(F));
+  // make leadcoeffs positive
+  for (i=1; i<=ncols(II); i++)
+  {
+    if ( leadcoef(II[i])<0 )
+    {
+      II[i] = -II[i];
+    }
+  }
+  ideal J,G;
+  int m;  // the output (multiplicity)
+  dbprint(ppl,"// -2- starting the bucle");
+  for (i=0; i<=n; i++)  // the multiplicity has to be <= n
+  {
+    // create the ideal Ji = ann_D[s](f^s) + < f, (s+alpha)^{i+1} >
+    // (s+alpha)^i in Ji <==> -alpha is a root with multiplicity >= i
+    J = II,F,(s+a)^(i+1);
+    // ------------ the ideal Ji is ready -----------
+    dbprint(ppl,"// -2-"+string(i+1)+"-1- starting the computation of a Groebner basis of J"+string(i)+" in @R");
+    dbprint(ppl-1, J);
+    G = engine(J,eng);
+    dbprint(ppl,"// -2-"+string(i+1)+"-2- the Groebner basis has been computed");
+    dbprint(ppl-1, G);
+    if ( NF((s+a)^i,G)==0 )
+    {
+      dbprint(ppl,"// -2-"+string(i+1)+"-3- the number "+string(-a)+" has not multiplicity "+string(i+1));
+      m = i;
+      break;
+    }
+    dbprint(ppl,"// -2-"+string(i+1)+"-3- the number "+string(-a)+" has multiplicity at least "+string(i+1));
+  }
+  dbprint(ppl,"// -3- the bucle has finished");
+  return(m);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y,z),Dp;
+  poly F = x*y*z;
+  printlevel = 0;
+  def A = Sannfs(F);
+  setring A;
+  poly F = imap(r,F);
+  checkRoot2(LD,F,1);    // -1 is a root of bs with multiplicity 3
+  checkRoot2(LD,F,1/3);  // -1/3 is not a root
+}
+
+proc checkFactor(ideal I, poly F, poly q, list #)
+"USAGE:  checkFactor(I,f,qs [,eng]);  I an ideal, f a poly, qs a poly, eng an optional int
+ASSUME:  checkFactor is called from the basering, created by Sannfs-like proc,
+@* that is, from the Weyl algebra in x1,..,xN,d1,..,dN tensored with K[s].
+@* The ideal I is the annihilator of f^s in D[s], that is the ideal, computed
+@* by Sannfs-like procedure (usually called LD there).
+@* Moreover, f is a polynomial in K[x1,..,xN] and qs is a polynomial in K[s].
+RETURN:  int, 1 if qs is a factor of the global Bernstein polynomial of f and 0 otherwise
+PURPOSE: check whether a univariate polynomial qs is a factor of the
+@*  Bernstein-Sato polynomial of f without explicit knowledge of the latter.
+NOTE:    If eng <>0, @code{std} is used for Groebner basis computations,
+@*       otherwise (and by default) @code{slimgb} is used.
+DISPLAY: If printlevel=1, progress debug messages will be printed,
+@*          if printlevel>=2, all the debug messages will be printed.
+EXAMPLE: example checkFactor; shows examples
+"
+{
+
+  // ASSUME too complicated, cannot check it.
+
+  int eng = 0;
+  if ( size(#)>0 )
+  {
+    if ( typeof(#[1]) == "int" )
+    {
+      eng = int(#[1]);
+    }
+  }
+  int ppl = printlevel-voice+2;
+  def @R2 = basering;
+  int N = nvars(@R2);
+  int i;
+  // we're in D_n[s], where the elim ord for s is set
+  dbprint(ppl,"// -0-1- starting the procedure checkFactor");
+  dbprint(ppl,"// -1-1- the ring @R2(_x,_Dx,s) is ready");
+  dbprint(ppl-1, @R2);
+  // create the ideal J = ann_D[s](f^s) + < f,q >
+  ideal J = NF(I,std(F));
+  // make leadcoeffs positive
+  for (i=1; i<=ncols(J); i++)
+  {
+    if ( leadcoef(J[i])<0 )
+    {
+      J[i] = -J[i];
+    }
+  }
+  J = J,F,q;
+  // ------------ the ideal J is ready -----------
+  dbprint(ppl,"// -1-2- starting the elimination of _x,_Dx in @R2");
+  dbprint(ppl-1, J);
+  ideal G = engine(J,eng);
+  ideal K = nselect(G,1..N-1);
+  kill J,G;
+  dbprint(ppl,"// -1-3- _x,_Dx are eliminated");
+  dbprint(ppl-1, K);
+  //q is a factor of bs if and only if K = < q >
+  //K = normalize(K);
+  //q = normalize(q);
+  //return( (K[1]==q) );
+  return( NF(K[1],std(q))==0 );
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y),Dp;
+  poly F = x^4+y^5+x*y^4;
+  printlevel = 0;
+  def A = Sannfs(F);
+  setring A;
+  poly F = imap(r,F);
+  checkFactor(LD,F,20*s+31);     // -31/20 is not a root of bs
+  checkFactor(LD,F,20*s+11);     // -11/20 is a root of bs
+  checkFactor(LD,F,(20*s+11)^2); // the multiplicity of -11/20 is 1
+}
+
+static proc indAR(list L, int n)
+"USAGE:  indAR(L,n);  list L, int n
+RETURN:  list
+PURPOSE: computes arrangement inductively, using L and
+@* var(n) as the next variable
+ASSUME: L has a structure of an arrangement
+EXAMPLE: example indAR; shows examples
+"
+{
+  if ( (n<2) || (n>nvars(basering)) )
+  {
+    ERROR("incorrect n");
+  }
+  int sl = size(L);
+  list K;
+  ideal tmp;
+  poly @t = L[sl][1] + var(n); //1 elt
+  K[sl+1] = ideal(@t);
+  tmp = L[1]+var(n);
+  K[1] = tmp; tmp = 0;
+  int i,j,sI;
+  ideal I;
+  for(i=sl; i>=2; i--)
+  {
+    I = L[i-1]; sI = size(I);
+    for(j=1; j<=sI; j++)
+    {
+      I[j] = I[j] + var(n);
+    }
+    tmp  = L[i],I;
+    K[i] = tmp;
+    I = 0; tmp = 0;
+  }
+  kill I; kill tmp;
+  return(K);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y,z,t,v),dp;
+  list L;
+  L[1] = ideal(x);
+  list K = indAR(L,2);
+  K;
+  list M = indAR(K,3);
+  M;
+  M = indAR(M,4);
+  M;
+}
+
+proc isRational(number n)
+"USAGE:  isRational(n); n number
+RETURN:  int
+PURPOSE: determine whether n is a rational number,
+@* that is it does not contain parameters.
+ASSUME: ground field is of characteristic 0
+EXAMPLE: example indAR; shows examples
+"
+{
+  if (char(basering) != 0)
+  {
+    ERROR("The ground field must be of characteristic 0!");
+  }
+  number dn = denominator(n);
+  number nn = numerator(n);
+  return( ((int(dn)==dn) && (int(nn)==nn)) );
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = (0,a),(x,y),dp;
+  number n1 = 11/73;
+  isRational(n1);
+  number n2 = (11*a+3)/72;
+  isRational(n2);
+}
+
+proc bernsteinLift(ideal I, poly F, list #)
+"USAGE:  bernsteinLift(I, F [,eng]);  I an ideal, F a poly, eng an optional int
+RETURN:  list
+PURPOSE: compute the (multiple of) Bernstein-Sato polynomial with lift-like method,
+@* based on the output of Sannfs-like procedure
+NOTE:  the output list contains the roots with multiplicities of the candidate
+@* for being Bernstein-Sato polynomial of f.
+@*  If eng <>0, @code{std} is used for Groebner basis computations,
+@*  otherwise and by default @code{slimgb} is used.
+@*  If printlevel=1, progress debug messages will be printed,
+@*  if printlevel>=2, all the debug messages will be printed.
+EXAMPLE: example bernsteinLift; shows examples
+"
+{
+  // assume: s is the last variable! check in the code
+  int eng = 0;
+  if ( size(#)>0 )
+  {
+    if ( typeof(#[1]) == "int" )
+    {
+      eng = int(#[1]);
+    }
+  }
+  def @R2 = basering;
+  int Nnew = nvars(@R2);
+  int N = Nnew div 2;
+  int ppl = printlevel-voice+2;
+  // we're in D_n[s], where the elim ord for s is set
+  // create D_n(s)
+  // create the ordinary Weyl algebra and put the result into it,
+  // keep: N, i,j,s, tmp, RL
+  Nnew = Nnew - 1; // former 2*N;
+  list L = 0;
+  list Lord, tmp;
+  intvec iv; int i;
+  list RL = ringlist(basering);
+  // if we work over alg. extension => problem!
+  if (size(RL[1]) > 1)
+  {
+    ERROR("cannot work over algebraic field extension");
+  }
+  tmp[1] = RL[1]; // char
+  tmp[2] = list("s");
+  tmp[3] = list(list("lp",int(1)));
+  tmp[4] = ideal(0);
+  L[1] = tmp; // field
+  tmp = 0;
+  L[4] = RL[4];  // factor ideal
+
+  // check whether vars have admissible names -> done earlier
+  // list Name = RL[2]M
+  // DName is defined earlier
+  list NName; // = RL[2]; // skip the last var 's'
+  for (i=1; i<=Nnew; i++)
+  {
+    NName[i] =  RL[2][i];
+  }
+  L[2] = NName;
+  // (c, ) ordering:
+  tmp[1]  = "c";
+  iv = 0;
+  tmp[2]  = iv;
+  Lord[1] = tmp;
+  tmp=0;
+  // dp ordering;
+  string s = "iv=";
+  for (i=1; i<=Nnew; i++)
+  {
+    s = s+"1,";
+  }
+  s[size(s)] = ";";
+  execute(s);
+  tmp     = 0;
+  tmp[1]  = "dp";  // string
+  tmp[2]  = iv;  // intvec
+  Lord[2] = tmp;
+  kill s;
+  tmp     = 0;
+  L[3]    = Lord;
+  // we are done with the list
+  // Add: Plural part
+  def @R4@ = ring(L);
+  setring @R4@;
+  matrix @D[Nnew][Nnew];
+  for (i=1; i<=N; i++)
+  {
+    @D[i,N+i]=1;
+  }
+  def @R4 = nc_algebra(1, at D);
+  setring @R4;
+  kill @R4@;
+  dbprint(ppl,"// -3-1- the ring K(s)<x,dx> is ready");
+  dbprint(ppl-1, @R4);
+  // map things correctly, using names
+  ideal J = imap(@R2, I), imap(@R2,F);
+  module M;
+  // make leadcoeffs positive
+  for (i=1; i<= ncols(J); i++)
+  {
+    if (J[i]!=0)
+    {
+      M[i] = J[i]*gen(1) + gen(1+i);
+    }
+  }
+  dbprint(ppl,"// -3-2- starting GB of the assoc. module M");
+  M = engine(M,eng);
+  dbprint(ppl,"// -3-3- finished GB of the assoc. module M");
+  dbprint(ppl-1, M);
+  // now look for (1) entry with 1st comp nonzero
+  // determine whether there are several 1st comps nonzero
+  module M2;
+  for (i=1; i<= ncols(M); i++)
+  {
+    if (M[1,i]!=0)
+    {
+      M2 = M2, M[i];
+    }
+  }
+  M2 = simplify(M2,2); // skip 0s
+  if (ncols(M2) > 1)
+  {
+    dbprint(ppl,"// -*- more than 1 element with nonzero leading component");
+    option(redSB);    option(redTail); // set them back?
+    M2 = interred(M2);
+    if (ncols(M2) > 1)
+    {
+      ERROR("more than one leading component after interred: assume violation!");
+    }
+    if (leadexp(M2[1]) != 0)
+    {
+      ERROR("nonconstant entry after interred: assume violation!");
+    }
+  }
+  // now there's only one el-t with leadcomp<>0
+  vector V = M2[1];
+  number bcand = leadcoef(V[1]); // 1st component
+  V[1]=0;
+  number ct = content(V); // content of the cofactors
+  poly CF = ct*V[ncols(J)]; // polynomial in K[s]<x,dx>, cofactor to F
+  dbprint(ppl,"// -3-4- the cofactor candidate found");
+  dbprint(ppl-1,CF);
+  dbprint(ppl,"// -3-5- the entry as it is");
+  dbprint(ppl-1,bcand);
+  bcand = bcand*ct; // a product of both
+  dbprint(ppl,"// -3-6- the content of the rest vector");
+  dbprint(ppl-1,ct);
+  ring @R3 = 0,s,dp;
+  dbprint(ppl,"// -4-1- the ring @R3 i.e. K[s] is ready");
+  poly bcand = imap(@R4,bcand);
+  dbprint(ppl,"// -4-2- factorization");
+  list P = factorize(bcand);          //with constants and multiplicities
+  ideal bs; intvec m;             //the Bernstein polynomial is monic, so we are not interested in constants
+  for (i=2; i<= size(P[1]); i++)  //we delete P[1][1] and P[2][1]
+  {
+    bs[i-1] = P[1][i];
+    m[i-1]  = P[2][i];
+  }
+  bs = normalize(bs); bs = -subst(bs,s,0); // to get roots only
+  setring @R2; // the ring the story started with
+  ideal bs = imap(@R3,bs); // intvec m is global
+  intvec mm = m; m = 0;
+  kill @R3; // kills m as well....
+  list @L = list(bs, mm);
+  // look for (2) return the GB of syzygies?
+  return(@L);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y,z),Dp;
+  poly F = x^3+y^3+z^3;
+  printlevel = 0;
+  def A = Sannfs(F);   setring A;
+  LD;
+  poly F = imap(r,F);
+  list L  = bernsteinLift(LD,F); L;
+  poly bs = fl2poly(L,"s"); bs; // the candidate for Bernstein-Sato polynomial
+}
+
+/// ****** EXAMPLES ************
+
+/*
+
+//static proc exCheckGenericity()
+{
+  LIB "control.lib";
+  ring r = (0,a,b,c),x,dp;
+  poly p = (x-a)*(x-b)*(x-c);
+  def A = annfsBM(p);
+  setring A;
+  ideal J = slimgb(LD);
+  matrix T = lift(LD,J);
+  T = normalize(T);
+  genericity(T);
+  // Ann =x^3*Dx+3*x^2*t*Dt+(-a-b-c)*x^2*Dx+(-2*a-2*b-2*c)*x*t*Dt+3*x^2+(a*b+a*c+b*c)*x*Dx+(a*b+a*c+b*c)*t*Dt+(-2*a-2*b-2*c)*x+(-a*b*c)*Dx+(a*b+a*c+b*c)
+  // genericity: g = a2-ab-ac+b2-bc+c2 =0
+  // g = (a -(b+c)/2)^2 + (3/4)*(b-c)^2;
+  // g ==0 <=> a=b=c
+  // indeed, Ann = (x-a)^2*(x*Dx+3*t*Dt+(-a)*Dx+3)
+  // --------------------------------------------
+  // BUT a direct computation shows
+  // when a=b=c,
+  // Ann = x*Dx+3*t*Dt+(-a)*Dx+3
+}
+
+//static proc exOT_17()
+{
+  // Oaku-Takayama, p.208
+  ring R = 0,(x,y),dp;
+  poly F = x^3-y^2; // x^2+x*y+y^2;
+  option(prot);
+  option(mem);
+  //  option(redSB);
+  def A = annfsOT(F,0);
+  setring A;
+  LD;
+  gkdim(LD); // a holonomic check
+  //  poly F = x^3-y^2; // = x^7 - y^5; // x^3-y^4; // x^5 - y^4;
+}
+
+//static proc exOT_16()
+{
+  // Oaku-Takayama, p.208
+  ring R = 0,(x),dp;
+  poly F = x*(1-x);
+  option(prot);
+  option(mem);
+  //  option(redSB);
+  def A = annfsOT(F,0);
+  setring A;
+  LD;
+  gkdim(LD); // a holonomic check
+}
+
+//static proc ex_bcheck()
+{
+  ring R = 0,(x,y),dp;
+  poly F = x*y*(x+y);
+  option(prot);
+  option(mem);
+  int eng = 0;
+  //  option(redSB);
+  def A = annfsOT(F,eng);
+  setring A;
+  LD;
+}
+
+//static proc ex_bcheck2()
+{
+  ring R = 0,(x,y),dp;
+  poly F = x*y*(x+y);
+  int eng = 0;
+  def A = annfsBM(F,eng);
+  setring A;
+  LD;
+}
+
+//static proc ex_BMI()
+{
+  // a hard example
+  ring r = 0,(x,y),Dp;
+  poly F1 = (x2-y3)*(x3-y2);
+  poly F2 = (x2-y3)*(xy4+y5+x4);
+  ideal F = F1,F2;
+  def A = annfsBMI(F);
+  setring A;
+  LD;
+  BS;
+}
+
+//static proc ex2_BMI()
+{
+  // this example was believed to be intractable in 2005 by Gago-Vargas, Castro and Ucha
+  ring r = 0,(x,y),Dp;
+  option(prot);
+  option(mem);
+  ideal F = x2+y3,x3+y2;
+  printlevel = 2;
+  def A = annfsBMI(F);
+  setring A;
+  LD;
+  BS;
+}
+
+//static proc ex_operatorBM()
+{
+  ring r = 0,(x,y,z,w),Dp;
+  poly F = x^3+y^3+z^2*w;
+  printlevel = 0;
+  def A = operatorBM(F);
+  setring A;
+  F; // the original polynomial itself
+  LD; // generic annihilator
+  LD0; // annihilator
+  bs; // normalized Bernstein poly
+  BS; // root and multiplicities of the Bernstein poly
+  PS; // the operator, s.t. PS*F^{s+1} = bs*F^s mod LD
+  reduce(PS*F-bs,LD); // check the property of PS
+}
+
+*/
diff --git a/Singular/LIB/dmodapp.lib b/Singular/LIB/dmodapp.lib
new file mode 100644
index 0000000..37ee592
--- /dev/null
+++ b/Singular/LIB/dmodapp.lib
@@ -0,0 +1,3251 @@
+/////////////////////////////////////////////////////////////////////////////
+version="version dmodapp.lib 4.0.0.0 Jun_2013 "; // $Id: 066f33b6a2c2657da872064d37f46ffaec7fcb6d $
+category="Noncommutative";
+info="
+LIBRARY: dmodapp.lib     Applications of algebraic D-modules
+AUTHORS: Viktor Levandovskyy,  levandov at math.rwth-aachen.de
+@*       Daniel Andres,   daniel.andres at math.rwth-aachen.de
+
+Support: DFG Graduiertenkolleg 1632 'Experimentelle und konstruktive Algebra'
+
+OVERVIEW:
+Let K be a field of characteristic 0, R = K[x1,...,xN] and
+D be the Weyl algebra in variables x1,...,xN,d1,...,dN.
+In this library there are the following procedures for algebraic D-modules:
+
+@* - given a cyclic representation D/I of a holonomic module and a polynomial
+ F in R, it is proved that the localization of D/I with respect to the mult.
+ closed set of all powers of F is a holonomic D-module. Thus we aim to compute
+ its cyclic representaion D/L for an ideal L in D. The procedures for the
+ localization are DLoc, SDLoc and DLoc0.
+
+@* - annihilator in D of a given polynomial F from R as well as
+ of a given rational function G/F from Quot(R). These can be computed via
+ procedures annPoly resp. annRat.
+
+@* - Groebner bases with respect to weights (according to (SST), given an
+ arbitrary integer vector containing weights for variables, one computes the
+ homogenization of a given ideal relative to this vector, then one computes a
+ Groebner basis and returns the dehomogenization of the result), initial
+ forms and initial ideals in Weyl algebras with respect to a given weight
+ vector can be computed with GBWeight, inForm, initialMalgrange and
+ initialIdealW.
+
+@* - restriction and integration of a holonomic module D/I. Suppose I
+ annihilates a function F(x1,...,xn). Our aim is to compute an ideal J
+ directly from I, which annihilates
+@*   - F(0,...,0,xk,...,xn) in case of restriction or
+@*   - the integral of F with respect to x1,...,xm in case of integration.
+ The corresponding procedures are restrictionModule, restrictionIdeal,
+ integralModule and integralIdeal.
+
+@* - characteristic varieties defined by ideals in Weyl algebras can be computed
+ with charVariety and charInfo.
+
+@* - appelF1, appelF2 and appelF4 return ideals in parametric Weyl algebras,
+ which annihilate corresponding Appel hypergeometric functions.
+
+
+REFERENCES:
+@* (SST) Saito, Sturmfels, Takayama 'Groebner Deformations of Hypergeometric
+         Differential Equations', Springer, 2000
+@* (OTW) Oaku, Takayama, Walther 'A Localization Algorithm for D-modules',
+         Journal of Symbolic Computation, 2000
+@* (OT)  Oaku, Takayama 'Algorithms for D-modules',
+         Journal of Pure and Applied Algebra, 1998
+
+
+PROCEDURES:
+
+annPoly(f);  computes annihilator of a polynomial f in the corr. Weyl algebra
+annRat(f,g); computes annihilator of rational function f/g in corr. Weyl algebra
+DLoc(I,f);   computes presentation of localization of D/I wrt symbolic power f^s
+SDLoc(I,f);  computes generic presentation of the localization of D/I wrt f^s
+DLoc0(I,f);  computes presentation of localization of D/I wrt f^s based on SDLoc
+
+GBWeight(I,u,v[,a,b]);       computes Groebner basis of I wrt a weight vector
+initialMalgrange(f[,s,t,v]); computes Groebner basis of initial Malgrange ideal
+initialIdealW(I,u,v[,s,t]);  computes initial ideal of  wrt a given weight
+inForm(f,w);                 computes initial form of poly/ideal wrt a weight
+
+restrictionIdeal(I,w[,eng,m,G]);  computes restriction ideal of I wrt w
+restrictionModule(I,w[,eng,m,G]); computes restriction module of I wrt w
+integralIdeal(I,w[,eng,m,G]);     computes integral ideal of I wrt w
+integralModule(I,w[,eng,m,G]);    computes integral module of I wrt w
+deRhamCohom(f[,eng,m]);           computes basis of n-th de Rham cohom. group
+deRhamCohomIdeal(I[,w,eng,m,G]);  computes basis of n-th de Rham cohom. group
+
+charVariety(I); computes characteristic variety of the ideal I
+charInfo(I);    computes char. variety, singular locus and primary decomp.
+isFsat(I,F);    checks whether the ideal I is F-saturated
+
+
+
+appelF1();     creates an ideal annihilating Appel F1 function
+appelF2();     creates an ideal annihilating Appel F2 function
+appelF4();     creates an ideal annihilating Appel F4 function
+
+fourier(I[,v]);        applies Fourier automorphism to ideal
+inverseFourier(I[,v]); applies inverse Fourier automorphism to ideal
+
+bFactor(F);    computes the roots of irreducible factors of an univariate poly
+intRoots(L);   dismisses non-integer roots from list in bFactor format
+poly2list(f);  decomposes the polynomial f into a list of terms and exponents
+fl2poly(L,s);  reconstructs a monic univariate polynomial from its factorization
+
+insertGenerator(id,p[,k]); inserts an element into an ideal/module
+deleteGenerator(id,k);     deletes the k-th element from an ideal/module
+
+engine(I,i);   computes a Groebner basis with the algorithm specified by i
+isInt(n);      checks whether number n is actually an int
+sortIntvec(v); sorts intvec
+
+KEYWORDS: D-module; annihilator of polynomial; annihilator of rational function;
+D-localization; localization of D-module; D-restriction; restriction of
+D-module; D-integration; integration of D-module; characteristic variety;
+Appel function; Appel hypergeometric function
+
+SEE ALSO: bfun_lib, dmod_lib, dmodvar_lib, gmssing_lib
+";
+
+/*
+  Changelog
+  21.09.10 by DA:
+  - restructured library for better readability
+  - new / improved procs:
+  - toolbox: isInt, intRoots, sortIntvec
+  - GB wrt weights: GBWeight, initialIdealW rewritten using GBWeight
+  - restriction/integration: restrictionX, integralX where X in {Module, Ideal},
+  fourier, inverseFourier, deRhamCohom, deRhamCohomIdeal
+  - characteristic variety: charVariety, charInfo
+  - added keywords for features
+  - reformated help strings and examples in existing procs
+  - added SUPPORT in header
+  - added reference (OT)
+
+  04.10.10 by DA:
+  - incorporated suggestions by Oleksandr Motsak, among other:
+  - bugfixes for fl2poly, sortIntvec, annPoly, GBWeight
+  - enhanced functionality for deleteGenerator, inForm
+
+  11.10.10 by DA:
+  - procedure bFactor now sorts the roots using new static procedure sortNumberIdeal
+
+  17.03.11 by DA:
+  - bugfixes for inForm with polynomial input, typo in restrictionIdealEngine
+
+  06.06.12 by DA:
+  - bugfix and documentation in deRhamCohomIdeal, output and
+  documentation in deRhamCohom
+  - changed charVariety: no homogenization is needed
+  - changed inForm: code is much simpler using jet
+
+*/
+
+
+LIB "bfun.lib";     // for pIntersect etc
+LIB "dmod.lib";     // for SannfsBM etc
+LIB "general.lib";  // for sort
+LIB "gkdim.lib";
+LIB "nctools.lib";  // for isWeyl etc
+LIB "poly.lib";
+LIB "primdec.lib";  // for primdecGKZ
+LIB "qhmoduli.lib"; // for Max
+LIB "sing.lib";     // for slocus
+
+
+///////////////////////////////////////////////////////////////////////////////
+// testing for consistency of the library:
+proc testdmodapp()
+{
+  example annPoly;
+  example annRat;
+  example DLoc;
+  example SDLoc;
+  example DLoc0;
+  example GBWeight;
+  example initialMalgrange;
+  example initialIdealW;
+  example inForm;
+  example restrictionIdeal;
+  example restrictionModule;
+  example integralIdeal;
+  example integralModule;
+  example deRhamCohom;
+  example deRhamCohomIdeal;
+  example charVariety;
+  example charInfo;
+  example isFsat;
+  example appelF1;
+  example appelF2;
+  example appelF4;
+  example fourier;
+  example inverseFourier;
+  example bFactor;
+  example intRoots;
+  example poly2list;
+  example fl2poly;
+  example insertGenerator;
+  example deleteGenerator;
+  example engine;
+  example isInt;
+  example sortIntvec;
+}
+
+
+// general assumptions ////////////////////////////////////////////////////////
+
+static proc dmodappAssumeViolation()
+{
+  // char K <> 0 or qring
+  if (  (size(ideal(basering)) >0) || (char(basering) >0) )
+  {
+    ERROR("Basering is inappropriate: characteristic>0 or qring present");
+  }
+  return();
+}
+
+static proc dmodappMoreAssumeViolation()
+{
+  // char K <> 0, qring
+  dmodappAssumeViolation();
+  // no Weyl algebra
+  if (isWeyl() == 0)
+  {
+    ERROR("Basering is not a Weyl algebra");
+  }
+  // wrong sequence of vars
+  int i,n;
+  n = nvars(basering) div 2;
+  for (i=1; i<=n; i++)
+  {
+    if (bracket(var(i+n),var(i))<>1)
+    {
+      ERROR(string(var(i+n))+" is not a differential operator for " +string(var(i)));
+    }
+  }
+  return();
+}
+
+static proc safeVarName (string s, string cv)
+// assumes 's' to be a valid variable name
+// returns valid var name string @@.. at s
+{
+  string S;
+  if (cv == "v")  { S = "," + "," + varstr(basering)  + ","; }
+  if (cv == "c")  { S = "," + "," + charstr(basering) + ","; }
+  if (cv == "cv") { S = "," + charstr(basering) + "," + varstr(basering) + ","; }
+  s = "," + s + ",";
+  while (find(S,s) <> 0)
+  {
+    s[1] = "@";
+    s = "," + s;
+  }
+  s = s[2..size(s)-1];
+  return(s)
+    }
+
+static proc intLike (def i)
+{
+  string str = typeof(i);
+  if (str == "int" || str == "number" || str == "bigint")
+  {
+    return(1);
+  }
+  else
+  {
+    return(0);
+  }
+}
+
+
+// toolbox ////////////////////////////////////////////////////////////////////
+
+proc engine(def I, int i)
+"USAGE:  engine(I,i);  I  ideal/module/matrix, i an int
+RETURN:  the same type as I
+PURPOSE: compute the Groebner basis of I with the algorithm, chosen via i
+NOTE:    By default and if i=0, slimgb is used; otherwise std does the job.
+EXAMPLE: example engine; shows examples
+"
+{
+  /* std - slimgb mix */
+  def J;
+  //  ideal J;
+  if (i==0)
+  {
+    J = slimgb(I);
+  }
+  else
+  {
+    // without options -> strange! (ringlist?)
+    intvec v = option(get);
+    option(redSB);
+    option(redTail);
+    J = std(I);
+    option(set, v);
+  }
+  return(J);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y),Dp;
+  ideal I  = y*(x3-y2),x*(x3-y2);
+  engine(I,0); // uses slimgb
+  engine(I,1); // uses std
+}
+
+proc poly2list (poly f)
+"USAGE:  poly2list(f); f a poly
+RETURN:  list of exponents and corresponding terms of f
+PURPOSE: converts a poly to a list of pairs consisting of intvecs (1st entry)
+@*       and polys (2nd entry), where the i-th pair contains the exponent of the
+@*       i-th term of f and the i-th term (with coefficient) itself.
+EXAMPLE: example poly2list; shows examples
+"
+{
+  list l;
+  int i = 1;
+  if (f == 0) // just for the zero polynomial
+  {
+    l[1] = list(leadexp(f), lead(f));
+  }
+  else
+  {
+    l[size(f)] = list(); // memory pre-allocation
+    while (f != 0)
+    {
+      l[i] = list(leadexp(f), lead(f));
+      f = f - lead(f);
+      i++;
+    }
+  }
+  return(l);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,x,dp;
+  poly F = x;
+  poly2list(F);
+  ring r2 = 0,(x,y),dp;
+  poly F = x2y+5xy2;
+  poly2list(F);
+  poly2list(0);
+}
+
+proc fl2poly(list L, string s)
+"USAGE:  fl2poly(L,s); L a list, s a string
+RETURN:  poly
+PURPOSE: reconstruct a monic polynomial in one variable from its factorization
+ASSUME:  s is a string with the name of some variable and
+@*       L is supposed to consist of two entries:
+@*        - L[1] of the type ideal with the roots of a polynomial
+@*        - L[2] of the type intvec with the multiplicities of corr. roots
+EXAMPLE: example fl2poly; shows examples
+"
+{
+  if (rvar(s)==0)
+  {
+    ERROR(s+ " is no variable in the basering");
+  }
+  poly x = var(rvar(s));
+  poly P = 1;
+  ideal RR = L[1];
+  int sl = ncols(RR);
+  intvec IV = L[2];
+  if (sl <> nrows(IV))
+  {
+    ERROR("number of roots doesn't match number of multiplicites");
+  }
+  for(int i=1; i<=sl; i++)
+  {
+    if (IV[i] > 0)
+    {
+      P = P*((x-RR[i])^IV[i]);
+    }
+    else
+    {
+      printf("Ignored the root with incorrect multiplicity %s",string(IV[i]));
+    }
+  }
+  return(P);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y,z,s),Dp;
+  ideal I = -1,-4/3,0,-5/3,-2;
+  intvec mI = 2,1,2,1,1;
+  list BS = I,mI;
+  poly p = fl2poly(BS,"s");
+  p;
+  factorize(p,2);
+}
+
+proc insertGenerator (list #)
+"USAGE:  insertGenerator(id,p[,k]);
+@*       id an ideal/module, p a poly/vector, k an optional int
+RETURN:  of the same type as id
+PURPOSE: inserts p into id at k-th position and returns the enlarged object
+NOTE:    If k is given, p is inserted at position k, otherwise (and by default),
+@*       p is inserted at the beginning (k=1).
+SEE ALSO: deleteGenerator
+EXAMPLE: example insertGenerator; shows examples
+"
+{
+  if (size(#) < 2)
+  {
+    ERROR("insertGenerator has to be called with at least 2 arguments (ideal/module,poly/vector)");
+  }
+  string inp1 = typeof(#[1]);
+  if (inp1 == "ideal" || inp1 == "module")
+  {
+    def id = #[1];
+  }
+  else { ERROR("first argument has to be of type ideal or module"); }
+  string inp2 = typeof(#[2]);
+  if (inp2 == "poly" || inp2 == "vector")
+  {
+    def f = #[2];
+  }
+  else { ERROR("second argument has to be of type poly/vector"); }
+  if (inp1 == "ideal" && inp2 == "vector")
+  {
+    ERROR("second argument has to be a polynomial if first argument is an ideal");
+  }
+  // don't check module/poly combination due to auto-conversion
+  //   if (inp1 == "module" && inp2 == "poly")
+  //   {
+  //     ERROR("second argument has to be a vector if first argument is a module");
+  //   }
+  int n = ncols(id);
+  int k = 1; // default
+  if (size(#)>=3)
+  {
+    if (intLike(#[3]))
+    {
+      k = int(#[3]);
+      if (k<=0)
+      {
+        ERROR("third argument has to be positive");
+      }
+    }
+    else { ERROR("third argument has to be of type int"); }
+  }
+  execute(inp1 +" J;");
+  if (k == 1) { J = f,id; }
+  else
+  {
+    if (k>n)
+    {
+      J = id;
+      J[k] = f;
+    }
+    else // 1<k<=n
+    {
+      J[n+1] = id[n]; // preinit
+      J[1..k-1] = id[1..k-1];
+      J[k] = f;
+      J[k+1..n+1] = id[k..n];
+    }
+  }
+  return(J);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y,z),dp;
+  ideal I = x^2,z^4;
+  insertGenerator(I,y^3);
+  insertGenerator(I,y^3,2);
+  module M = I*gen(3);
+  insertGenerator(M,[x^3,y^2,z],2);
+  insertGenerator(M,x+y+z,4);
+}
+
+proc deleteGenerator (def id, int k)
+"USAGE:   deleteGenerator(id,k);  id an ideal/module, k an int
+RETURN:   of the same type as id
+PURPOSE:  deletes the k-th generator from the first argument and returns
+@*        the altered object
+SEE ALSO: insertGenerator
+EXAMPLE:  example deleteGenerator; shows examples
+"
+{
+  string inp1 = typeof(id);
+  if (inp1 <> "ideal" && inp1 <> "module")
+  {
+    ERROR("first argument has to be of type ideal or module");
+  }
+  execute(inp1 +" J;");
+  int n = ncols(id);
+  if (n == 1 && k == 1) { return(J); }
+  if (k<=0 || k>n)
+  {
+    ERROR("second argument has to be in the range 1,...,"+string(n));
+  }
+  J[n-1] = 0; // preinit
+  if (k == 1) { J = id[2..n]; }
+  else
+  {
+    if (k == n) { J = id[1..n-1]; }
+    else
+    {
+      J[1..k-1] = id[1..k-1];
+      J[k..n-1] = id[k+1..n];
+    }
+  }
+  return(J);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y,z),dp;
+  ideal I = x^2,y^3,z^4;
+  deleteGenerator(I,2);
+  module M = [x,y,z],[x2,y2,z2],[x3,y3,z3];
+  print(deleteGenerator(M,2));
+  M = M[1];
+  deleteGenerator(M,1);
+}
+
+static proc sortNumberIdeal (ideal I)
+// sorts ideal of constant polys (ie numbers), returns according permutation
+{
+  int i;
+  int nI = ncols(I);
+  intvec dI;
+  for (i=nI; i>0; i--)
+  {
+    dI[i] = int(denominator(leadcoef(I[i])));
+  }
+  int lcmI = lcm(dI);
+  for (i=nI; i>0; i--)
+  {
+    dI[i] = int(lcmI*leadcoef(I[i]));
+  }
+  intvec perm = sortIntvec(dI)[2];
+  return(perm);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,s,dp;
+  ideal I = -9/20,-11/20,-23/20,-19/20,-1,-13/10,-27/20,-13/20,-21/20,-17/20,
+    -11/10,-9/10,-7/10; // roots of BS poly of reiffen(4,5)
+  intvec v = sortNumberIdeal(I); v;
+  I[v];
+}
+
+proc bFactor (poly F)
+"USAGE:  bFactor(f);  f poly
+RETURN:  list of ideal and intvec and possibly a string
+PURPOSE: tries to compute the roots of a univariate poly f
+NOTE:    The output list consists of two or three entries:
+@*       roots of f as an ideal, their multiplicities as intvec, and,
+@*       if present, a third one being the product of all irreducible factors
+@*       of degree greater than one, given as string.
+@*       If f is the zero polynomial or if f has no roots in the ground field,
+@*       this is encoded as root 0 with multiplicity 0.
+DISPLAY: If printlevel=1, progress debug messages will be printed,
+@*       if printlevel>=2, all the debug messages will be printed.
+EXAMPLE: example bFactor; shows examples
+"
+{
+  int ppl = printlevel - voice +2;
+  def save = basering;
+  ideal LI = variables(F);
+  list L;
+  int i = size(LI);
+  if (i>1) { ERROR("poly has to be univariate")}
+  if (i == 0)
+  {
+    dbprint(ppl,"// poly is constant");
+    L = list(ideal(0),intvec(0),string(F));
+    return(L);
+  }
+  poly v = LI[1];
+  L = ringlist(save); L = L[1..4];
+  L[2] = list(string(v));
+  L[3] = list(list("dp",intvec(1)),list("C",intvec(0)));
+  def @S = ring(L);
+  setring @S;
+  poly ir = 1; poly F = imap(save,F);
+  list L = factorize(F);
+  ideal I = L[1];
+  intvec m = L[2];
+  ideal II; intvec mm;
+  for (i=2; i<=ncols(I); i++)
+  {
+    if (deg(I[i]) > 1)
+    {
+      ir = ir * I[i]^m[i];
+    }
+    else
+    {
+      II[size(II)+1] = I[i];
+      mm[size(II)] = m[i];
+    }
+  }
+  II = normalize(II);
+  II = subst(II,var(1),0);
+  II = -II;
+  intvec perm = sortNumberIdeal(II);
+  II = II[perm];
+  mm = mm[perm];
+  if (size(II)>0)
+  {
+    dbprint(ppl,"// found roots");
+    dbprint(ppl-1,string(II));
+  }
+  else
+  {
+    dbprint(ppl,"// found no roots");
+  }
+  L = list(II,mm);
+  if (ir <> 1)
+  {
+    dbprint(ppl,"// found irreducible factors");
+    ir = cleardenom(ir);
+    dbprint(ppl-1,string(ir));
+    L = L + list(string(ir));
+  }
+  else
+  {
+    dbprint(ppl,"// no irreducible factors found");
+  }
+  setring save;
+  L = imap(@S,L);
+  return(L);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y),dp;
+  bFactor((x^2-1)^2);
+  bFactor((x^2+1)^2);
+  bFactor((y^2+1/2)*(y+9)*(y-7));
+  bFactor(1);
+  bFactor(0);
+}
+
+proc isInt (number n)
+"USAGE:  isInt(n); n a number
+RETURN:  int, 1 if n is an integer or 0 otherwise
+PURPOSE: check whether given object of type number is actually an int
+NOTE:    Parameters are treated as integers.
+EXAMPLE: example isInt; shows an example
+"
+{
+  number d = denominator(n);
+  if (d<>1)
+  {
+    return(0);
+  }
+  else
+  {
+    return(1);
+  }
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,x,dp;
+  number n = 4/3;
+  isInt(n);
+  n = 11;
+  isInt(n);
+}
+
+proc intRoots (list l)
+"USAGE:  isInt(L); L a list
+RETURN:  list
+PURPOSE: extracts integer roots from a list given in @code{bFactor} format
+ASSUME:  The input list must be given in the format of @code{bFactor}.
+NOTE:    Parameters are treated as integers.
+SEE ALSO: bFactor
+EXAMPLE: example intRoots; shows an example
+"
+{
+  int wronginput;
+  int sl = size(l);
+  if (sl>0)
+  {
+    if (typeof(l[1])<>"ideal"){wronginput = 1;}
+    if (sl>1)
+    {
+      if (typeof(l[2])<>"intvec"){wronginput = 1;}
+      if (sl>2)
+      {
+        if (typeof(l[3])<>"string"){wronginput = 1;}
+        if (sl>3){wronginput = 1;}
+      }
+    }
+  }
+  if (sl<2){wronginput = 1;}
+  if (wronginput)
+  {
+    ERROR("Given list has wrong format.");
+  }
+  int i,j;
+  ideal l1 = l[1];
+  int n = ncols(l1);
+  j = 1;
+  ideal I;
+  intvec v;
+  for (i=1; i<=n; i++)
+  {
+    if (size(l1[j])>1) // poly not number
+    {
+      ERROR("Ideal in list has wrong format.");
+    }
+    if (isInt(leadcoef(l1[i])))
+    {
+      I[j] = l1[i];
+      v[j] = l[2][i];
+      j++;
+    }
+  }
+  return(list(I,v));
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,x,dp;
+  list L = bFactor((x-4/3)*(x+3)^2*(x-5)^4); L;
+  intRoots(L);
+}
+
+proc sortIntvec (intvec v)
+"USAGE:  sortIntvec(v); v an intvec
+RETURN:  list of two intvecs
+PURPOSE: sorts an intvec
+NOTE:    In the output list L, the first entry consists of the entries of v
+@*       satisfying L[1][i] >= L[1][i+1]. The second entry is a permutation
+@*       such that v[L[2]] = L[1].
+@*       Unlike in the procedure @code{sort}, zeros are not dismissed.
+SEE ALSO: sort
+EXAMPLE: example sortIntvec; shows examples
+"
+{
+  int i;
+  intvec vpos,vzero,vneg,vv,sortv,permv;
+  list l;
+  for (i=1; i<=nrows(v); i++)
+  {
+    if (v[i]>0)
+    {
+      vpos = vpos,i;
+    }
+    else
+    {
+      if (v[i]==0)
+      {
+        vzero = vzero,i;
+      }
+      else // v[i]<0
+      {
+        vneg = vneg,i;
+      }
+    }
+  }
+  if (size(vpos)>1)
+  {
+    vpos = vpos[2..size(vpos)];
+    vv = v[vpos];
+    l = sort(vv);
+    vv = l[1];
+    vpos = vpos[l[2]];
+    sortv = vv[size(vv)..1];
+    permv = vpos[size(vv)..1];
+  }
+  if (size(vzero)>1)
+  {
+    vzero = vzero[2..size(vzero)];
+    permv = permv,vzero;
+    sortv = sortv,0:size(vzero);
+  }
+  if (size(vneg)>1)
+  {
+    vneg = vneg[2..size(vneg)];
+    vv = -v[vneg];
+    l = sort(vv);
+    vv = -l[1];
+    vneg = vneg[l[2]];
+    sortv = sortv,vv;
+    permv = permv,vneg;
+  }
+  if (permv[1]==0)
+  {
+    sortv = sortv[2..size(sortv)];
+    permv = permv[2..size(permv)];
+  }
+  return(list(sortv,permv));
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,x,dp;
+  intvec v = -1,0,1,-2,0,2;
+  list L = sortIntvec(v); L;
+  v[L[2]];
+  v = -3,0;
+  sortIntvec(v);
+  v = 0,-3;
+  sortIntvec(v);
+}
+
+
+// F-saturation ///////////////////////////////////////////////////////////////
+
+proc isFsat(ideal I, poly F)
+"USAGE:  isFsat(I, F);  I an ideal, F a poly
+RETURN:  int, 1  if I is F-saturated and 0 otherwise
+PURPOSE: checks whether the ideal I is F-saturated
+NOTE:    We check indeed that Ker(D--> F--> D/I) is 0, where D is the basering.
+EXAMPLE: example isFsat; shows examples
+"
+{
+  /* checks whether I is F-saturated, that is Ke  (D -F-> D/I) is 0 */
+  /* works in any algebra */
+  /*  for simplicity : later check attrib */
+  /* returns 1 if I is F-sat */
+  if (attrib(I,"isSB")!=1)
+  {
+    I = groebner(I);
+  }
+  matrix @M = matrix(I);
+  matrix @F[1][1] = F;
+  def S = modulo(module(@F),module(@M));
+  S = NF(S,I);
+  S = groebner(S);
+  return( (gkdim(S) == -1) );
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y),dp;
+  poly G = x*(x-y)*y;
+  def A = annfs(G);
+  setring A;
+  poly F = x3-y2;
+  isFsat(LD,F);
+  ideal J = LD*F;
+  isFsat(J,F);
+}
+
+
+// annihilators ///////////////////////////////////////////////////////////////
+
+proc annRat(poly g, poly f)
+"USAGE:   annRat(g,f);  f, g polynomials
+RETURN:   ring (a Weyl algebra) containing an ideal 'LD'
+PURPOSE:  compute the annihilator of the rational function g/f in the
+@*        corresponding Weyl algebra
+ASSUME:   basering is commutative and over a field of characteristic 0
+NOTE:     Activate the output ring with the @code{setring} command.
+@*        In the output ring, the ideal 'LD' (in Groebner basis) is the
+@*        annihilator of g/f.
+@*        The algorithm uses the computation of Ann(f^{-1}) via D-modules,
+@*        see (SST).
+DISPLAY:  If printlevel =1, progress debug messages will be printed,
+@*        if printlevel>=2, all the debug messages will be printed.
+SEE ALSO: annPoly
+EXAMPLE:  example annRat; shows examples
+"
+{
+  // assumption check
+  dmodappAssumeViolation();
+  if (!isCommutative())
+  {
+    ERROR("Basering must be commutative.");
+  }
+  // assumptions: f is not a constant
+  if (f==0) { ERROR("the denominator f cannot be zero"); }
+  if ((leadexp(f) == 0) && (size(f) < 2))
+  {
+    // f = const, so use annPoly
+    g = g/f;
+    def @R = annPoly(g);
+    return(@R);
+  }
+  // computes the annihilator of g/f
+  def save = basering;
+  int ppl = printlevel-voice+2;
+  dbprint(ppl,"// -1-[annRat] computing the ann f^s");
+  def  @R1 = SannfsBM(f);
+  setring @R1;
+  poly f = imap(save,f);
+  int i,mir;
+  int isr = 0; // checkRoot1(LD,f,1); // roots are negative, have to enter positive int
+  if (!isr)
+  {
+    // -1 is not the root
+    // find the m.i.r iteratively
+    mir = 0;
+    for(i=nvars(save)+1; i>=1; i--)
+    {
+      isr =  checkRoot1(LD,f,i);
+      if (isr) { mir =-i; break; }
+    }
+    if (mir ==0)
+    {
+      ERROR("No integer root found! Aborting computations, inform the authors!");
+    }
+    // now mir == i is m.i.r.
+  }
+  else
+  {
+    // -1 is the m.i.r
+    mir = -1;
+  }
+  dbprint(ppl,"// -2-[annRat] the minimal integer root is ");
+  dbprint(ppl-1, mir);
+  // use annfspecial
+  dbprint(ppl,"// -3-[annRat] running annfspecial ");
+  ideal AF = annfspecial(LD,f,mir,-1); // ann f^{-1}
+  //  LD = subst(LD,s,j);
+  //  LD = engine(LD,0);
+  // modify the ring: throw s away
+  // output ring comes from SannfsBM
+  list U = ringlist(@R1);
+  list tmp; // variables
+  for(i=1; i<=size(U[2])-1; i++)
+  {
+    tmp[i] = U[2][i];
+  }
+  U[2] = tmp;
+  tmp = 0;
+  tmp[1] = U[3][1]; // x,Dx block
+  tmp[2] = U[3][3]; // module block
+  U[3] = tmp;
+  tmp = 0;
+  tmp = U[1],U[2],U[3],U[4];
+  def @R2 = ring(tmp);
+  setring @R2;
+  // now supply with Weyl algebra relations
+  int N = nvars(@R2) div 2;
+  matrix @D[2*N][2*N];
+  for(i=1; i<=N; i++)
+  {
+    @D[i,N+i]=1;
+  }
+  def @R3 = nc_algebra(1, at D);
+  setring @R3;
+  dbprint(ppl,"// - -[annRat] ring without s is ready:");
+  dbprint(ppl-1, at R3);
+  poly g = imap(save,g);
+  matrix G[1][1] = g;
+  matrix LL = matrix(imap(@R1,AF));
+  kill @R1;   kill @R2;
+  dbprint(ppl,"// -4-[annRat] running modulo");
+  ideal LD  = modulo(G,LL);
+  dbprint(ppl,"// -4-[annRat] running GB on the final result");
+  LD  = engine(LD,0);
+  export LD;
+  return(@R3);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y),dp;
+  poly g = 2*x*y;  poly f = x^2 - y^3;
+  def B = annRat(g,f);
+  setring B;
+  LD;
+  // Now, compare with the output of Macaulay2:
+  ideal tst = 3*x*Dx + 2*y*Dy + 1, y^3*Dy^2 - x^2*Dy^2 + 6*y^2*Dy + 6*y,
+    9*y^2*Dx^2*Dy-4*y*Dy^3+27*y*Dx^2+2*Dy^2, 9*y^3*Dx^2-4*y^2*Dy^2+10*y*Dy -10;
+  option(redSB); option(redTail);
+  LD = groebner(LD);
+  tst = groebner(tst);
+  print(matrix(NF(LD,tst)));  print(matrix(NF(tst,LD)));
+  // So, these two answers are the same
+}
+
+proc annPoly(poly f)
+"USAGE:   annPoly(f);  f a poly
+RETURN:   ring (a Weyl algebra) containing an ideal 'LD'
+PURPOSE:  compute the complete annihilator ideal of f in the corresponding
+@*        Weyl algebra
+ASSUME:   basering is commutative and over a field of characteristic 0
+NOTE:     Activate the output ring with the @code{setring} command.
+@*        In the output ring, the ideal 'LD' (in Groebner basis) is the
+@*        annihilator.
+DISPLAY:  If printlevel =1, progress debug messages will be printed,
+@*        if printlevel>=2, all the debug messages will be printed.
+SEE ALSO: annRat
+EXAMPLE:  example annPoly; shows examples
+"
+{
+  // assumption check
+  dmodappAssumeViolation();
+  if (!isCommutative())
+  {
+    ERROR("Basering must be commutative.");
+  }
+  // computes a system of linear PDEs with polynomial coeffs for f
+  def save = basering;
+  list L = ringlist(save);
+  list Name = L[2];
+  int N = nvars(save);
+  int i;
+  for (i=1; i<=N; i++)
+  {
+    Name[N+i] = safeVarName("D"+Name[i],"cv"); // concat
+  }
+  L[2] = Name;
+  def @R = ring(L);
+  setring @R;
+  def @@R = Weyl();
+  setring @@R;
+  kill @R;
+  matrix M[1][N];
+  for (i=1; i<=N; i++)
+  {
+    M[1,i] = var(N+i);
+  }
+  matrix F[1][1] = imap(save,f);
+  def I = modulo(module(F),module(M));
+  ideal LD = I;
+  LD = groebner(LD);
+  export LD;
+  return(@@R);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y,z),dp;
+  poly f = x^2*z - y^3;
+  def A = annPoly(f);
+  setring A;    // A is the 3rd Weyl algebra in 6 variables
+  LD;           // the Groebner basis of annihilator
+  gkdim(LD);    // must be 3 = 6/2, since A/LD is holonomic module
+  NF(Dy^4, LD); // must be 0 since Dy^4 clearly annihilates f
+  poly f = imap(r,f);
+  NF(LD*f,std(ideal(Dx,Dy,Dz))); // must be zero if LD indeed annihilates f
+}
+
+
+
+// localizations //////////////////////////////////////////////////////////////
+
+proc DLoc(ideal I, poly F)
+"USAGE:  DLoc(I, f);  I an ideal, f a poly
+RETURN:  list of ideal and list
+ASSUME:  the basering is a Weyl algebra
+PURPOSE: compute the presentation of the localization of D/I w.r.t. f^s
+NOTE:    In the output list L,
+@*       - L[1] is an ideal (given as Groebner basis), the presentation of the
+@*       localization,
+@*       - L[2] is a list containing roots with multiplicities of Bernstein
+@*       polynomial of (D/I)_f.
+DISPLAY: If printlevel =1, progress debug messages will be printed,
+@*       if printlevel>=2, all the debug messages will be printed.
+EXAMPLE: example DLoc; shows examples
+"
+{
+  /* runs SDLoc and DLoc0 */
+  /* assume: run from Weyl algebra */
+  dmodappAssumeViolation();
+  if (!isWeyl())
+  {
+    ERROR("Basering is not a Weyl algebra");
+  }
+  int old_printlevel = printlevel;
+  printlevel=printlevel+1;
+  def @R = basering;
+  def @R2 = SDLoc(I,F);
+  setring @R2;
+  poly F = imap(@R,F);
+  def @R3 = DLoc0(LD,F);
+  setring @R3;
+  ideal bs = BS[1];
+  intvec m = BS[2];
+  setring @R;
+  ideal LD0 = imap(@R3,LD0);
+  ideal bs = imap(@R3,bs);
+  list BS; BS[1] = bs; BS[2] = m;
+  kill @R3;
+  printlevel = old_printlevel;
+  return(list(LD0,BS));
+}
+example;
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y,Dx,Dy),dp;
+  def R = Weyl();    setring R; // Weyl algebra in variables x,y,Dx,Dy
+  poly F = x2-y3;
+  ideal I = (y^3 - x^2)*Dx - 2*x, (y^3 - x^2)*Dy + 3*y^2; // I = Dx*F, Dy*F;
+  // I is not holonomic, since its dimension is not 4/2=2
+  gkdim(I);
+  list L = DLoc(I, x2-y3);
+  L[1]; // localized module (R/I)_f is isomorphic to R/LD0
+  L[2]; // description of b-function for localization
+}
+
+proc DLoc0(ideal I, poly F)
+"USAGE:  DLoc0(I, f);  I an ideal, f a poly
+RETURN:  ring (a Weyl algebra) containing an ideal 'LD0' and a list 'BS'
+PURPOSE: compute the presentation of the localization of D/I w.r.t. f^s,
+@*       where D is a Weyl Algebra, based on the output of procedure SDLoc
+ASSUME:  the basering is similar to the output ring of SDLoc procedure
+NOTE:    activate the output ring with the @code{setring} command. In this ring,
+@*       - the ideal LD0 (given as Groebner basis) is the presentation of the
+@*       localization,
+@*       - the list BS contains roots and multiplicities of Bernstein
+@*       polynomial of (D/I)_f.
+DISPLAY: If printlevel =1, progress debug messages will be printed,
+@*       if printlevel>=2, all the debug messages will be printed.
+EXAMPLE: example DLoc0; shows examples
+"
+{
+  dmodappAssumeViolation();
+  /* assume: to be run in the output ring of SDLoc */
+  /* doing: add F, eliminate vars*Dvars, factorize BS */
+  /* analogue to annfs0 */
+  def @R2 = basering;
+  // we're in D_n[s], where the elim ord for s is set
+  ideal J = NF(I,std(F));
+  // make leadcoeffs positive
+  int i;
+  for (i=1; i<= ncols(J); i++)
+  {
+    if (leadcoef(J[i]) <0 )
+    {
+      J[i] = -J[i];
+    }
+  }
+  J = J,F;
+  ideal M = groebner(J);
+  int Nnew = nvars(@R2);
+  ideal K2 = nselect(M,1..Nnew-1);
+  int ppl = printlevel-voice+2;
+  dbprint(ppl,"// -1-1- _x,_Dx are eliminated in basering");
+  dbprint(ppl-1, K2);
+  // the ring @R3 and the search for minimal negative int s
+  ring @R3 = 0,s,dp;
+  dbprint(ppl,"// -2-1- the ring @R3 = K[s] is ready");
+  ideal K3 = imap(@R2,K2);
+  poly p = K3[1];
+  dbprint(ppl,"// -2-2- attempt the factorization");
+  list PP = factorize(p);          //with constants and multiplicities
+  ideal bs; intvec m;             //the Bernstein polynomial is monic, so
+  // we are not interested in constants
+  for (i=2; i<= size(PP[1]); i++)  //we delete P[1][1] and P[2][1]
+  {
+    bs[i-1] = PP[1][i];
+    m[i-1]  = PP[2][i];
+  }
+  ideal bbs; int srat=0; int HasRatRoots = 0;
+  int sP;
+  for (i=1; i<= size(bs); i++)
+  {
+    if (deg(bs[i]) == 1)
+    {
+      bbs = bbs,bs[i];
+    }
+  }
+  if (size(bbs)==0)
+  {
+    dbprint(ppl-1,"// -2-3- factorization: no rational roots");
+    //    HasRatRoots = 0;
+    HasRatRoots = 1; // s0 = -1 then
+    sP = -1;
+    // todo: return ideal with no subst and a b-function unfactorized
+  }
+  else
+  {
+    // exist rational roots
+    dbprint(ppl-1,"// -2-3- factorization: rational roots found");
+    HasRatRoots = 1;
+    //    dbprint(ppl-1,bbs);
+    bbs = bbs[2..ncols(bbs)];
+    ideal P = bbs;
+    dbprint(ppl-1,P);
+    srat = size(bs) - size(bbs);
+    // define minIntRoot on linear factors or find out that it doesn't exist
+    intvec vP;
+    number nP;
+    P = normalize(P); // now leadcoef = 1
+    P = ideal(matrix(lead(P))-matrix(P));
+    sP = size(P);
+    int cnt = 0;
+    for (i=1; i<=sP; i++)
+    {
+      nP = leadcoef(P[i]);
+      if ( (nP - int(nP)) == 0 )
+      {
+        cnt++;
+        vP[cnt] = int(nP);
+      }
+    }
+    //     if ( size(vP)>=2 )
+    //     {
+    //       vP = vP[2..size(vP)];
+    //     }
+    if ( size(vP)==0 )
+    {
+      // no roots!
+      dbprint(ppl,"// -2-4- no integer root, setting s0 = -1");
+      sP = -1;
+      //      HasRatRoots = 0; // older stuff, here we do substitution
+      HasRatRoots = 1;
+    }
+    else
+    {
+      HasRatRoots = 1;
+      sP = -Max(-vP);
+      dbprint(ppl,"// -2-4- minimal integer root found");
+      dbprint(ppl-1, sP);
+      //    int sP = minIntRoot(bbs,1);
+      //       P =  normalize(P);
+      //       bs = -subst(bs,s,0);
+      if (sP >=0)
+      {
+        dbprint(ppl,"// -2-5- nonnegative root, setting s0 = -1");
+        sP = -1;
+      }
+      else
+      {
+        dbprint(ppl,"// -2-5- the root is negative");
+      }
+    }
+  }
+
+  if (HasRatRoots)
+  {
+    setring @R2;
+    K2 = subst(I,s,sP);
+    // IF min int root exists ->
+    // create the ordinary Weyl algebra and put the result into it,
+    // thus creating the ring @R5
+    // ELSE : return the same ring with new objects
+    // keep: N, i,j,s, tmp, RL
+    Nnew = Nnew - 1; // former 2*N;
+    // list RL = ringlist(save);  // is defined earlier
+    //  kill Lord, tmp, iv;
+    list L = 0;
+    list Lord, tmp;
+    intvec iv;
+    list RL = ringlist(basering);
+    L[1] = RL[1];
+    L[4] = RL[4];  //char, minpoly
+    // check whether vars have admissible names -> done earlier
+    // list Name = RL[2]M
+    // DName is defined earlier
+    list NName; // = RL[2]; // skip the last var 's'
+    for (i=1; i<=Nnew; i++)
+    {
+      NName[i] =  RL[2][i];
+    }
+    L[2] = NName;
+    // dp ordering;
+    string s = "iv=";
+    for (i=1; i<=Nnew; i++)
+    {
+      s = s+"1,";
+    }
+    s[size(s)] = ";";
+    execute(s);
+    tmp     = 0;
+    tmp[1]  = "dp";  // string
+    tmp[2]  = iv;  // intvec
+    Lord[1] = tmp;
+    kill s;
+    tmp[1]  = "C";
+    iv = 0;
+    tmp[2]  = iv;
+    Lord[2] = tmp;
+    tmp     = 0;
+    L[3]    = Lord;
+    // we are done with the list
+    // Add: Plural part
+    def @R4@ = ring(L);
+    setring @R4@;
+    int N = Nnew div 2;
+    matrix @D[Nnew][Nnew];
+    for (i=1; i<=N; i++)
+    {
+      @D[i,N+i]=1;
+    }
+    def @R4 = nc_algebra(1, at D);
+    setring @R4;
+    kill @R4@;
+    dbprint(ppl,"// -3-1- the ring @R4 is ready");
+    dbprint(ppl-1, @R4);
+    ideal K4 = imap(@R2,K2);
+    intvec vopt = option(get);
+    option(redSB);
+    dbprint(ppl,"// -3-2- the final cosmetic std");
+    K4 = groebner(K4);  // std does the job too
+    option(set,vopt);
+    // total cleanup
+    setring @R2;
+    ideal bs = imap(@R3,bs);
+    bs = -normalize(bs); // "-" for getting correct coeffs!
+    bs = subst(bs,s,0);
+    kill @R3;
+    setring @R4;
+    ideal bs = imap(@R2,bs); // only rationals are the entries
+    list BS; BS[1] = bs; BS[2] = m;
+    export BS;
+    //    list LBS = imap(@R3,LBS);
+    //    list BS; BS[1] = sbs; BS[2] = m;
+    //    BS;
+    //    export BS;
+    ideal LD0 = K4;
+    export LD0;
+    return(@R4);
+  }
+  else
+  {
+    /* SHOULD NEVER GET THERE */
+    /* no rational/integer roots */
+    /* return objects in the copy of current ring */
+    setring @R2;
+    ideal LD0 = I;
+    poly BS = normalize(K2[1]);
+    export LD0;
+    export BS;
+    return(@R2);
+  }
+}
+example;
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y,Dx,Dy),dp;
+  def R = Weyl();    setring R; // Weyl algebra in variables x,y,Dx,Dy
+  poly F = x2-y3;
+  ideal I = (y^3 - x^2)*Dx - 2*x, (y^3 - x^2)*Dy + 3*y^2; // I = Dx*F, Dy*F;
+  // moreover I is not holonomic, since its dimension is not 2 = 4/2
+  gkdim(I); // 3
+  def W = SDLoc(I,F);  setring W; // creates ideal LD in W = R[s]
+  def U = DLoc0(LD, x2-y3);  setring U; // compute in R
+  LD0; // Groebner basis of the presentation of localization
+  BS; // description of b-function for localization
+}
+
+proc SDLoc(ideal I, poly F)
+"USAGE:  SDLoc(I, f);  I an ideal, f a poly
+RETURN:  ring (basering extended by a new variable) containing an ideal 'LD'
+PURPOSE: compute a generic presentation of the localization of D/I w.r.t. f^s
+ASSUME:  the basering D is a Weyl algebra over a field of characteristic 0
+NOTE:    Activate this ring with the @code{setring} command. In this ring,
+@*       the ideal LD (given as Groebner basis) is the presentation of the
+@*       localization.
+DISPLAY: If printlevel =1, progress debug messages will be printed,
+@*       if printlevel>=2, all the debug messages will be printed.
+EXAMPLE: example SDLoc; shows examples
+"
+{
+  /* analogue to Sannfs */
+  /* printlevel >=4 gives debug info */
+  /* assume: we're in the Weyl algebra D  in x1,x2,...,d1,d2,... */
+
+  dmodappAssumeViolation();
+  if (!isWeyl())
+  {
+    ERROR("Basering is not a Weyl algebra");
+  }
+  def save = basering;
+  /* 1. create D <t, dt, s > as in LOT */
+  /* ordering: eliminate t,dt */
+  int ppl = printlevel-voice+2;
+  int N = nvars(save); N = N div 2;
+  int Nnew = 2*N + 3; // t,Dt,s
+  int i,j;
+  string s;
+  list RL = ringlist(save);
+  list L, Lord;
+  list tmp;
+  intvec iv;
+  L[1] = RL[1]; // char
+  L[4] = RL[4]; // char, minpoly
+  // check whether vars have admissible names
+  list Name  = RL[2];
+  list RName;
+  RName[1] = "@t";
+  RName[2] = "@Dt";
+  RName[3] = "@s";
+  for(i=1;i<=N;i++)
+  {
+    for(j=1; j<=size(RName);j++)
+    {
+      if (Name[i] == RName[j])
+      {
+        ERROR("Variable names should not include @t, at Dt, at s");
+      }
+    }
+  }
+  // now, create the names for new vars
+  tmp    =  0;
+  tmp[1] = "@t";
+  tmp[2] = "@Dt";
+  list SName ; SName[1] = "@s";
+  list NName = tmp + Name + SName;
+  L[2]   = NName;
+  tmp    = 0;
+  kill NName;
+  // block ord (a(1,1),dp);
+  tmp[1]  = "a"; // string
+  iv      = 1,1;
+  tmp[2]  = iv; //intvec
+  Lord[1] = tmp;
+  // continue with dp 1,1,1,1...
+  tmp[1]  = "dp"; // string
+  s       = "iv=";
+  for(i=1;i<=Nnew;i++)
+  {
+    s = s+"1,";
+  }
+  s[size(s)]= ";";
+  execute(s);
+  tmp[2]    = iv;
+  Lord[2]   = tmp;
+  tmp[1]    = "C";
+  iv        = 0;
+  tmp[2]    = iv;
+  Lord[3]   = tmp;
+  tmp       = 0;
+  L[3]      = Lord;
+  // we are done with the list
+  def @R@ = ring(L);
+  setring @R@;
+  matrix @D[Nnew][Nnew];
+  @D[1,2]=1;
+  for(i=1; i<=N; i++)
+  {
+    @D[2+i,N+2+i]=1;
+  }
+  // ADD [s,t]=-t, [s,Dt]=Dt
+  @D[1,Nnew] = -var(1);
+  @D[2,Nnew] = var(2);
+  def @R = nc_algebra(1, at D);
+  setring @R;
+  kill @R@;
+  dbprint(ppl,"// -1-1- the ring @R(@t, at Dt,_x,_Dx, at s) is ready");
+  dbprint(ppl-1, @R);
+  poly  F = imap(save,F);
+  ideal I = imap(save,I);
+  dbprint(ppl-1, "the ideal after map:");
+  dbprint(ppl-1, I);
+  poly p = 0;
+  for(i=1; i<=N; i++)
+  {
+    p = diff(F,var(2+i))*@Dt + var(2+N+i);
+    dbprint(ppl-1, p);
+    I = subst(I,var(2+N+i),p);
+    dbprint(ppl-1, var(2+N+i));
+    p = 0;
+  }
+  I = I, @t - F;
+  // t*Dt + s +1 reduced with t-f gives f*Dt + s
+  I = I, F*var(2) + var(Nnew); // @s
+  // -------- the ideal I is ready ----------
+  dbprint(ppl,"// -1-2- starting the elimination of @t, at Dt in @R");
+  dbprint(ppl-1, I);
+  //  ideal J = engine(I,eng);
+  ideal J = groebner(I);
+  dbprint(ppl-1,"// -1-2-1- result of the  elimination of @t, at Dt in @R");
+  dbprint(ppl-1, J);;
+  ideal K = nselect(J,1..2);
+  dbprint(ppl,"// -1-3- @t, at Dt are eliminated");
+  dbprint(ppl-1, K);  // K is without t, Dt
+  K = groebner(K);  // std does the job too
+  // now, we must change the ordering
+  // and create a ring without t, Dt
+  setring save;
+  // ----------- the ring @R3 ------------
+  // _x, _Dx,s;  elim.ord for _x,_Dx.
+  // keep: N, i,j,s, tmp, RL
+  Nnew = 2*N+1;
+  kill Lord, tmp, iv, RName;
+  list Lord, tmp;
+  intvec iv;
+  L[1] = RL[1];
+  L[4] = RL[4];  // char, minpoly
+  // check whether vars hava admissible names -> done earlier
+  // now, create the names for new var
+  tmp[1] = "s";
+  list NName = Name + tmp;
+  L[2] = NName;
+  tmp = 0;
+  // block ord (dp(N),dp);
+  // string s is already defined
+  s = "iv=";
+  for (i=1; i<=Nnew-1; i++)
+  {
+    s = s+"1,";
+  }
+  s[size(s)]=";";
+  execute(s);
+  tmp[1] = "dp";  // string
+  tmp[2] = iv;   // intvec
+  Lord[1] = tmp;
+  // continue with dp 1,1,1,1...
+  tmp[1] = "dp";  // string
+  s[size(s)] = ",";
+  s = s+"1;";
+  execute(s);
+  kill s;
+  kill NName;
+  tmp[2]      = iv;
+  Lord[2]     = tmp;
+  tmp[1]      = "C";  iv  = 0;  tmp[2]=iv;
+  Lord[3]     = tmp;  tmp = 0;
+  L[3]        = Lord;
+  // we are done with the list. Now add a Plural part
+  def @R2@ = ring(L);
+  setring @R2@;
+  matrix @D[Nnew][Nnew];
+  for (i=1; i<=N; i++)
+  {
+    @D[i,N+i]=1;
+  }
+  def @R2 = nc_algebra(1, at D);
+  setring @R2;
+  kill @R2@;
+  dbprint(ppl,"//  -2-1- the ring @R2(_x,_Dx,s) is ready");
+  dbprint(ppl-1, @R2);
+  ideal MM = maxideal(1);
+  MM = 0,s,MM;
+  map R01 = @R, MM;
+  ideal K = R01(K);
+  // total cleanup
+  ideal LD = K;
+  // make leadcoeffs positive
+  for (i=1; i<= ncols(LD); i++)
+  {
+    if (leadcoef(LD[i]) <0 )
+    {
+      LD[i] = -LD[i];
+    }
+  }
+  export LD;
+  kill @R;
+  return(@R2);
+}
+example;
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y,Dx,Dy),dp;
+  def R = Weyl(); // Weyl algebra on the variables x,y,Dx,Dy
+  setring R;
+  poly F = x2-y3;
+  ideal I = Dx*F, Dy*F;
+  // note, that I is not holonomic, since it's dimension is not 2
+  gkdim(I);  // 3, while dim R = 4
+  def W = SDLoc(I,F);
+  setring W; // = R[s], where s is a new variable
+  LD;        // Groebner basis of s-parametric presentation
+}
+
+
+// Groebner basis wrt weights and initial ideal business //////////////////////
+
+proc GBWeight (ideal I, intvec u, intvec v, list #)
+"USAGE:  GBWeight(I,u,v [,s,t,w]);
+@*       I ideal, u,v intvecs, s,t optional ints, w an optional intvec
+RETURN:  ideal, Groebner basis of I w.r.t. the weights u and v
+ASSUME:  The basering is the n-th Weyl algebra over a field of characteristic 0
+@*       and for all 1<=i<=n the identity var(i+n)*var(i)=var(i)*var(i+1)+1
+@*       holds, i.e. the sequence of variables is given by
+@*       x(1),...,x(n),D(1),...,D(n), where D(i) is the differential operator
+@*       belonging to x(i).
+PURPOSE: computes a Groebner basis with respect to given weights
+NOTE:    The weights u and v are understood as weight vectors for x(i) and D(i),
+@*       respectively. According to (SST), one computes the homogenization of a
+@*       given ideal relative to (u,v), then one computes a Groebner basis and
+@*       returns the dehomogenization of the result.
+@*       If s<>0, @code{std} is used for Groebner basis computations,
+@*       otherwise, and by default, @code{slimgb} is used.
+@*       If t<>0, a matrix ordering is used for Groebner basis computations,
+@*       otherwise, and by default, a block ordering is used.
+@*       If w is given and consists of exactly 2*n strictly positive entries,
+@*       w is used for constructing the weighted homogenized Weyl algebra,
+@*       see Noro (2002). Otherwise, and by default, the homogenization weight
+@*       (1,...,1) is used.
+DISPLAY: If printlevel=1, progress debug messages will be printed,
+@*       if printlevel>=2, all the debug messages will be printed.
+EXAMPLE: example GBWeight; shows examples
+"
+{
+  dmodappMoreAssumeViolation();
+  int ppl = printlevel - voice +2;
+  def save = basering;
+  int n = nvars(save) div 2;
+  int whichengine = 0;           // default
+  int methodord   = 0;           // default
+  intvec homogweights = 1:(2*n); // default
+  if (size(#)>0)
+  {
+    if (intLike(#[1]))
+    {
+      whichengine = int(#[1]);
+    }
+    if (size(#)>1)
+    {
+      if (intLike(#[2]))
+      {
+        methodord = int(#[2]);
+      }
+      if (size(#)>2)
+      {
+        if (typeof(#[3])=="intvec")
+        {
+          if (size(#[3])==2*n && allPositive(#[3])==1)
+          {
+            homogweights = #[3];
+          }
+          else
+          {
+            print("// Homogenization weight vector must consist of positive entries and be");
+            print("// of size " + string(n) + ". Using weight (1,...,1).");
+          }
+        }
+      }
+    }
+  }
+  // 1. create  homogenized Weyl algebra
+  // 1.1 create ordering
+  int i;
+  list RL = ringlist(save);
+  int N = 2*n+1;
+  intvec uv = u,v,0;
+  homogweights = homogweights,1;
+  list Lord = list(list("a",homogweights));
+  list C0 = list("C",intvec(0));
+  if (methodord == 0) // default: blockordering
+  {
+    Lord[5] = C0;
+    Lord[4] = list("lp",intvec(1));
+    Lord[3] = list("dp",intvec(1:(N-1)));
+    Lord[2] = list("a",uv);
+  }
+  else                // M() ordering
+  {
+    intmat @Ord[N][N];
+    @Ord[1,1..N] = uv; @Ord[2,1..N] = 1:(N-1);
+    for (i=1; i<=N-2; i++)
+    {
+      @Ord[2+i,N - i] = -1;
+    }
+    dbprint(ppl-1,"// the ordering matrix:", at Ord);
+    Lord[2] = list("M",intvec(@Ord));
+    Lord[3] = C0;
+  }
+  // 1.2 the homog var
+  list Lvar = RL[2]; Lvar[N] = safeVarName("h","cv");
+  // 1.3 create commutative ring
+  list L@@Dh = RL; L@@Dh = L@@Dh[1..4];
+  L@@Dh[2] = Lvar; L@@Dh[3] = Lord;
+  def @Dh = ring(L@@Dh); kill L@@Dh;
+  setring @Dh;
+  // 1.4 create non-commutative relations
+  matrix @relD[N][N];
+  for (i=1; i<=n; i++)
+  {
+    @relD[i,n+i] = var(N)^(homogweights[i]+homogweights[n+i]);
+  }
+  def Dh = nc_algebra(1, at relD);
+  setring Dh; kill @Dh;
+  dbprint(ppl-1,"// computing in ring",Dh);
+  // 2. Compute the initial ideal
+  ideal I = imap(save,I);
+  I = homog(I,var(N));
+  // 2.1 the hard part: Groebner basis computation
+  dbprint(ppl, "// starting Groebner basis computation with engine: "+string(whichengine));
+  I = engine(I, whichengine);
+  dbprint(ppl, "// finished Groebner basis computation");
+  dbprint(ppl-1, "// ideal before dehomogenization is " +string(I));
+  I = subst(I,var(N),1); // dehomogenization
+  setring save;
+  I = imap(Dh,I); kill Dh;
+  return(I);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y,Dx,Dy),dp;
+  def D2 = Weyl();
+  setring D2;
+  ideal I = 3*x^2*Dy+2*y*Dx,2*x*Dx+3*y*Dy+6;
+  intvec u = -2,-3;
+  intvec v = -u;
+  GBWeight(I,u,v);
+  ideal J = std(I);
+  GBWeight(J,u,v); // same as above
+  u = 0,1;
+  GBWeight(I,u,v);
+}
+
+proc inForm (def I, intvec w)
+"USAGE:  inForm(I,w);  I ideal or poly, w intvec
+RETURN:  ideal, generated by initial forms of generators of I w.r.t. w, or
+@*       poly, initial form of input poly w.r.t. w
+PURPOSE: computes the initial form of an ideal or a poly w.r.t. the weight w
+NOTE:    The size of the weight vector must be equal to the number of variables
+@*       of the basering.
+EXAMPLE: example inForm; shows examples
+"
+{
+  string inp1 = typeof(I);
+  if ((inp1 <> "ideal") && (inp1 <> "poly"))
+  {
+    ERROR("first argument has to be an ideal or a poly");
+  }
+  if (size(w) != nvars(basering))
+  {
+    ERROR("weight vector has wrong dimension");
+  }
+  ideal II = I;
+  int j;
+  poly g;
+  ideal J;
+  for (j=1; j<=ncols(II); j++)
+  {
+    g = II[j];
+    J[j] = g - jet(g,deg(g,w)-1,w);
+  }
+  if (inp1 == "ideal")
+  {
+    return(J);
+  }
+  else
+  {
+    return(J[1]);
+  }
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y,Dx,Dy),dp;
+  def D = Weyl(); setring D;
+  poly F = 3*x^2*Dy+2*y*Dx;
+  poly G = 2*x*Dx+3*y*Dy+6;
+  ideal I = F,G;
+  intvec w1 = -1,-1,1,1;
+  intvec w2 = -1,-2,1,2;
+  intvec w3 = -2,-3,2,3;
+  inForm(I,w1);
+  inForm(I,w2);
+  inForm(I,w3);
+  inForm(F,w1);
+}
+
+proc initialIdealW(ideal I, intvec u, intvec v, list #)
+"USAGE:  initialIdealW(I,u,v [,s,t,w]);
+@*       I ideal, u,v intvecs, s,t optional ints, w an optional intvec
+RETURN:  ideal, GB of initial ideal of the input ideal wrt the weights u and v
+ASSUME:  The basering is the n-th Weyl algebra in characteristic 0 and for all
+@*       1<=i<=n the identity var(i+n)*var(i)=var(i)*var(i+1)+1 holds, i.e. the
+@*       sequence of variables is given by x(1),...,x(n),D(1),...,D(n),
+@*       where D(i) is the differential operator belonging to x(i).
+PURPOSE: computes the initial ideal with respect to given weights.
+NOTE:    u and v are understood as weight vectors for x(1..n) and D(1..n)
+@*       respectively.
+@*       If s<>0, @code{std} is used for Groebner basis computations,
+@*       otherwise, and by default, @code{slimgb} is used.
+@*       If t<>0, a matrix ordering is used for Groebner basis computations,
+@*       otherwise, and by default, a block ordering is used.
+@*       If w is given and consists of exactly 2*n strictly positive entries,
+@*       w is used as homogenization weight.
+@*       Otherwise, and by default, the homogenization weight (1,...,1) is used.
+DISPLAY: If printlevel=1, progress debug messages will be printed,
+@*       if printlevel>=2, all the debug messages will be printed.
+EXAMPLE: example initialIdealW; shows examples
+"
+{
+  // assumption check in GBWeight
+  int ppl = printlevel - voice + 2;
+  printlevel = printlevel + 1;
+  I = GBWeight(I,u,v,#);
+  printlevel = printlevel - 1;
+  intvec uv = u,v;
+  I = inForm(I,uv);
+  int eng;
+  if (size(#)>0)
+  {
+    if(typeof(#[1])=="int" || typeof(#[1])=="number")
+    {
+      eng = int(#[1]);
+    }
+  }
+  dbprint(ppl,"// starting cosmetic Groebner basis computation");
+  I = engine(I,eng);
+  dbprint(ppl,"// finished cosmetic Groebner basis computation");
+  return(I);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y,Dx,Dy),dp;
+  def D2 = Weyl();
+  setring D2;
+  ideal I = 3*x^2*Dy+2*y*Dx,2*x*Dx+3*y*Dy+6;
+  intvec u = -2,-3;
+  intvec v = -u;
+  initialIdealW(I,u,v);
+  ideal J = std(I);
+  initialIdealW(J,u,v); // same as above
+  u = 0,1;
+  initialIdealW(I,u,v);
+}
+
+proc initialMalgrange (poly f,list #)
+"USAGE:  initialMalgrange(f,[,a,b,v]); f poly, a,b optional ints, v opt. intvec
+RETURN:  ring, Weyl algebra induced by basering, extended by two new vars t,Dt
+PURPOSE: computes the initial Malgrange ideal of a given polynomial w.r.t. the
+@*       weight vector (-1,0...,0,1,0,...,0) such that the weight of t is -1
+@*       and the weight of Dt is 1.
+ASSUME:  The basering is commutative and over a field of characteristic 0.
+NOTE:    Activate the output ring with the @code{setring} command.
+@*       The returned ring contains the ideal 'inF', being the initial ideal
+@*       of the Malgrange ideal of f.
+@*       Varnames of the basering should not include t and Dt.
+@*       If a<>0, @code{std} is used for Groebner basis computations,
+@*       otherwise, and by default, @code{slimgb} is used.
+@*       If b<>0, a matrix ordering is used for Groebner basis computations,
+@*       otherwise, and by default, a block ordering is used.
+@*       If a positive weight vector v is given, the weight
+@*       (d,v[1],...,v[n],1,d+1-v[1],...,d+1-v[n]) is used for homogenization
+@*       computations, where d denotes the weighted degree of f.
+@*       Otherwise and by default, v is set to (1,...,1). See Noro (2002).
+DISPLAY: If printlevel=1, progress debug messages will be printed,
+@*       if printlevel>=2, all the debug messages will be printed.
+EXAMPLE: example initialMalgrange; shows examples
+"
+{
+  dmodappAssumeViolation();
+  if (!isCommutative())
+  {
+    ERROR("Basering must be commutative.");
+  }
+  int ppl = printlevel - voice + 2;
+  def save = basering;
+  int n = nvars(save);
+  int i;
+  int whichengine = 0; // default
+  int methodord   = 0; // default
+  intvec u0 = 1:n;     // default
+  if (size(#)>0)
+  {
+    if (intLike(#[1]))
+    {
+      whichengine = int(#[1]);
+    }
+    if (size(#)>1)
+    {
+      if (intLike(#[2]))
+      {
+        methodord = int(#[2]);
+      }
+      if (size(#)>2)
+      {
+        if ((typeof(#[3])=="intvec") && (size(#[3])==n) && (allPositive(#[3])==1))
+        {
+          u0 = #[3];
+        }
+      }
+    }
+  }
+  list RL = ringlist(save);
+  RL = RL[1..4]; // if basering is commutative nc_algebra
+  list C0 = list("C",intvec(0));
+  // 1. create homogenization weights
+  // 1.1. get the weighted degree of f
+  list Lord = list(list("wp",u0),C0);
+  list L at r = RL;
+  L at r[3] = Lord;
+  def r = ring(L at r); kill L at r,Lord;
+  setring r;
+  poly f = imap(save,f);
+  int d = deg(f);
+  setring save; kill r;
+  // 1.2 the homogenization weights
+  intvec homogweights = d;
+  homogweights[n+2] = 1;
+  for (i=1; i<=n; i++)
+  {
+    homogweights[i+1]   = u0[i];
+    homogweights[n+2+i] = d+1-u0[i];
+  }
+  // 2. create extended Weyl algebra
+  int N = 2*n+2;
+  // 2.1 create names for vars
+  string vart  = safeVarName("t","cv");
+  string varDt = safeVarName("D"+vart,"cv");
+  while (varDt <> "D"+vart)
+  {
+    vart  = safeVarName("@"+vart,"cv");
+    varDt = safeVarName("D"+vart,"cv");
+  }
+  list Lvar;
+  Lvar[1] = vart; Lvar[n+2] = varDt;
+  for (i=1; i<=n; i++)
+  {
+    Lvar[i+1]   = string(var(i));
+    Lvar[i+n+2] = safeVarName("D" + string(var(i)),"cv");
+  }
+  //  2.2 create ordering
+  list Lord = list(list("dp",intvec(1:N)),C0);
+  // 2.3 create the (n+1)-th Weyl algebra
+  list L at D = RL; L at D[2] = Lvar; L at D[3] = Lord;
+  def @D = ring(L at D); kill L at D;
+  setring @D;
+  def D = Weyl();
+  setring D; kill @D;
+  dbprint(ppl,"// the (n+1)-th Weyl algebra :" ,D);
+  // 3. compute the initial ideal
+  // 3.1 create the Malgrange ideal
+  poly f = imap(save,f);
+  ideal I = var(1)-f;
+  for (i=1; i<=n; i++)
+  {
+    I = I, var(n+2+i)+diff(f,var(i+1))*var(n+2);
+  }
+  // I = engine(I,whichengine); // todo efficient to compute GB wrt dp first?
+  // 3.2 computie the initial ideal
+  intvec w = 1,0:n;
+  printlevel = printlevel + 1;
+  I = initialIdealW(I,-w,w,whichengine,methodord,homogweights);
+  printlevel = printlevel - 1;
+  ideal inF = I; attrib(inF,"isSB",1);
+  export(inF);
+  setring save;
+  return(D);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y),dp;
+  poly f = x^2+y^3+x*y^2;
+  def D = initialMalgrange(f);
+  setring D;
+  inF;
+  setring r;
+  intvec v = 3,2;
+  def D2 = initialMalgrange(f,1,1,v);
+  setring D2;
+  inF;
+}
+
+
+// restriction and integration ////////////////////////////////////////////////
+
+static proc restrictionModuleEngine (ideal I, intvec w, list #)
+// returns list L with 2 entries of type ideal
+// L[1]=basis of free module, L[2]=generating system of submodule
+// #=eng,m,G; eng=engine; m=min int root of bfctIdeal(I,w); G=GB of I wrt (-w,w)
+{
+  dmodappMoreAssumeViolation();
+  if (!isHolonomic(I))
+  {
+    ERROR("Given ideal is not holonomic");
+  }
+  int l0,l0set,Gset;
+  ideal G;
+  int whichengine = 0;         // default
+  if (size(#)>0)
+  {
+    if (intLike(#[1]))
+    {
+      whichengine = int(#[1]);
+    }
+    if (size(#)>1)
+    {
+      if (intLike(#[2]))
+      {
+        l0 = int(#[2]);
+        l0set = 1;
+      }
+      if (size(#)>2)
+      {
+        if (typeof(#[3])=="ideal")
+        {
+          G = #[3];
+          Gset = 1;
+        }
+      }
+    }
+  }
+  int ppl = printlevel;
+  int i,j,k;
+  int n = nvars(basering) div 2;
+  if (w == 0:size(w))
+  {
+    ERROR("weight vector must not be zero");
+  }
+  if (size(w)<>n)
+  {
+    ERROR("weight vector must have exactly " + string(n) + " entries");
+  }
+  for (i=1; i<=n; i++)
+  {
+    if (w[i]<0)
+    {
+      ERROR("weight vector must not have negative entries");
+    }
+  }
+  intvec ww = -w,w;
+  if (!Gset)
+  {
+    G = GBWeight(I,-w,w,whichengine);
+    dbprint(ppl,"// found GB wrt weight " +string(w));
+    dbprint(ppl-1,"// " + string(G));
+  }
+  if (!l0set)
+  {
+    ideal inG = inForm(G,ww);
+    inG = engine(inG,whichengine);
+    poly s = 0;
+    for (i=1; i<=n; i++)
+    {
+      s = s + w[i]*var(i)*var(i+n);
+    }
+    vector v = pIntersect(s,inG);
+    list L = bFactor(vec2poly(v));
+    dbprint(ppl,"// found b-function of given ideal wrt weight " + string(w));
+    dbprint(ppl-1,"// roots: "+string(L[1]));
+    dbprint(ppl-1,"// multiplicities: "+string(L[2]));
+    kill inG,v,s;
+    L = intRoots(L);           // integral roots of b-function
+    if (L[2]==0:size(L[2]))       // no integral roots
+    {
+      return(list(ideal(0),ideal(0)));
+    }
+    intvec v;
+    for (i=1; i<=ncols(L[1]); i++)
+    {
+      v[i] = int(L[1][i]);
+    }
+    l0 = Max(v);
+    dbprint(ppl,"// maximal integral root is " +string(l0));
+    kill L,v;
+  }
+  if (l0 < 0)                  // maximal integral root is < 0
+  {
+    return(list(ideal(0),ideal(0)));
+  }
+  intvec m;
+  for (i=ncols(G); i>0; i--)
+  {
+    m[i] = deg(G[i],ww);
+  }
+  dbprint(ppl,"// weighted degree of generators of GB is " +string(m));
+  def save = basering;
+  list RL = ringlist(save);
+  RL = RL[1..4];
+  list Lvar;
+  j = 1;
+  intvec neww;
+  for (i=1; i<=n; i++)
+  {
+    if (w[i]>0)
+    {
+      Lvar[j] = string(var(i+n));
+      neww[j] = w[i];
+      j++;
+    }
+  }
+  list Lord;
+  Lord[1] = list("dp",intvec(1:n));
+  Lord[2] = list("C", intvec(0));
+  RL[2] = Lvar;
+  RL[3] = Lord;
+  def r = ring(RL);
+  kill Lvar, Lord, RL;
+  setring r;
+  ideal B;
+  list Blist;
+  intvec mm = l0,-m+l0;
+  for (i=0; i<=Max(mm); i++)
+  {
+    B = weightKB(std(0),i,neww);
+    Blist[i+1] = B;
+  }
+  setring save;
+  list Blist = imap(r,Blist);
+  ideal ff = maxideal(1);
+  for (i=1; i<=n; i++)
+  {
+    if (w[i]<>0)
+    {
+      ff[i] = 0;
+    }
+  }
+  map f = save,ff;
+  ideal B,M;
+  poly p;
+  for (i=1; i<=size(G); i++)
+  {
+    for (j=1; j<=l0-m[i]+1; j++)
+    {
+      B = Blist[j];
+      for (k=1; k<=ncols(B); k++)
+      {
+        p = B[k]*G[i];
+        p = f(p);
+        M[size(M)+1] = p;
+      }
+    }
+  }
+  ideal Bl0 = Blist[1..(l0+1)];
+  dbprint(ppl,"// found basis of free module");
+  dbprint(ppl-1,"// " + string(Bl0));
+  dbprint(ppl,"// found generators of submodule");
+  dbprint(ppl-1,"// " + string(M));
+  return(list(Bl0,M));
+}
+
+static proc restrictionModuleOutput (ideal B, ideal N, intvec w, int eng, string str)
+// returns ring, which contains module "str"
+{
+  int n = nvars(basering) div 2;
+  int i,j;
+  def save = basering;
+  // 1: create new ring
+  list RL = ringlist(save);
+  RL = RL[1..4];
+  list V = RL[2];
+  poly prodvar = 1;
+  int zeropresent;
+  j = 0;
+  for (i=1; i<=n; i++)
+  {
+    if (w[i]<>0)
+    {
+      V = delete(V,i-j);
+      V = delete(V,i-2*j-1+n);
+      j = j+1;
+      prodvar = prodvar*var(i)*var(i+n);
+    }
+    else
+    {
+      zeropresent = 1;
+    }
+  }
+  if (!zeropresent) // restrict/integrate all vars, return input ring
+  {
+    def newR = save;
+  }
+  else
+  {
+    RL[2] = V;
+    V = list();
+    V[1] = list("C", intvec(0));
+    V[2] = list("dp",intvec(1:(2*size(ideal(w)))));
+    RL[3] = V;
+    def @D = ring(RL);
+    setring @D;
+    def newR = Weyl();
+    setring save;
+    kill @D;
+  }
+  // 2. get coker representation of module
+  module M = coeffs(N,B,prodvar);
+  if (zeropresent)
+  {
+    setring newR;
+    module M = imap(save,M);
+  }
+  M = engine(M,eng);
+  M = prune(M);
+  M = engine(M,eng);
+  execute("module " + str + " = M;");
+  execute("export(" + str + ");");
+  setring save;
+  return(newR);
+}
+
+proc restrictionModule (ideal I, intvec w, list #)
+"USAGE:  restrictionModule(I,w,[,eng,m,G]);
+@*       I ideal, w intvec, eng and m optional ints, G optional ideal
+RETURN:  ring (a Weyl algebra) containing a module 'resMod'
+ASSUME:  The basering is the n-th Weyl algebra over a field of characteristic 0
+@*       and for all 1<=i<=n the identity var(i+n)*var(i)=var(i)*var(i+1)+1
+@*       holds, i.e. the sequence of variables is given by
+@*       x(1),...,x(n),D(1),...,D(n), where D(i) is the differential operator
+@*       belonging to x(i).
+@*       Further, assume that I is holonomic and that w is n-dimensional with
+@*       non-negative entries.
+PURPOSE: computes the restriction module of a holonomic ideal to the subspace
+@*       defined by the variables corresponding to the non-zero entries of the
+@*       given intvec
+NOTE:    The output ring is the Weyl algebra defined by the zero entries of w.
+@*       It contains a module 'resMod' being the restriction module of I wrt w.
+@*       If there are no zero entries, the input ring is returned.
+@*       If eng<>0, @code{std} is used for Groebner basis computations,
+@*       otherwise, and by default, @code{slimgb} is used.
+@*       The minimal integer root of the b-function of I wrt the weight (-w,w)
+@*       can be specified via the optional argument m.
+@*       The optional argument G is used for specifying a Groebner Basis of I
+@*       wrt the weight (-w,w), that is, the initial form of G generates the
+@*       initial ideal of I wrt the weight (-w,w).
+@*       Further note, that the assumptions on m and G (if given) are not
+@*       checked.
+DISPLAY: If printlevel=1, progress debug messages will be printed,
+@*       if printlevel>=2, all the debug messages will be printed.
+EXAMPLE: example restrictionModule; shows examples
+"
+{
+  list L = restrictionModuleEngine(I,w,#);
+  int eng;
+  if (size(#)>0)
+  {
+    if (intLike(#[1]))
+    {
+      eng = int(#[1]);
+    }
+  }
+  def newR = restrictionModuleOutput(L[1],L[2],w,eng,"resMod");
+  return(newR);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(a,x,b,Da,Dx,Db),dp;
+  def D3 = Weyl();
+  setring D3;
+  ideal I = a*Db-Dx+2*Da, x*Db-Da, x*Da+a*Da+b*Db+1,
+    x*Dx-2*x*Da-a*Da, b*Db^2+Dx*Da-Da^2+Db,
+    a*Dx*Da+2*x*Da^2+a*Da^2+b*Dx*Db+Dx+2*Da;
+  intvec w = 1,0,0;
+  def rm = restrictionModule(I,w);
+  setring rm; rm;
+  print(resMod);
+}
+
+static proc restrictionIdealEngine (ideal I, intvec w, string cf, list #)
+{
+  int eng;
+  if (size(#)>0)
+  {
+    if(intLike(#[1]))
+    {
+      eng = int(#[1]);
+    }
+  }
+  def save = basering;
+  if (cf == "restriction")
+  {
+    def newR = restrictionModule(I,w,#);
+    setring newR;
+    matrix M = resMod;
+    kill resMod;
+  }
+  if (cf == "integral")
+  {
+    def newR = integralModule(I,w,#);
+    setring newR;
+    matrix M = intMod;
+    kill intMod;
+  }
+  int i,r,c;
+  r = nrows(M);
+  c = ncols(M);
+  ideal J;
+  if (r == 1) // nothing to do
+  {
+    J = M;
+  }
+  else
+  {
+    matrix zm[r-1][1]; // zero matrix
+    matrix v[r-1][1];
+    for (i=1; i<=c; i++)
+    {
+      if (M[1,i]<>0)
+      {
+        v = M[2..r,i];
+        if (v == zm)
+        {
+          J[size(J)+1] = M[1,i];
+        }
+      }
+    }
+  }
+  J = engine(J,eng);
+  if (cf == "restriction")
+  {
+    ideal resIdeal = J;
+    export(resIdeal);
+  }
+  if (cf == "integral")
+  {
+    ideal intIdeal = J;
+    export(intIdeal);
+  }
+  setring save;
+  return(newR);
+}
+
+proc restrictionIdeal (ideal I, intvec w, list #)
+"USAGE:  restrictionIdeal(I,w,[,eng,m,G]);
+@*       I ideal, w intvec, eng and m optional ints, G optional ideal
+RETURN:  ring (a Weyl algebra) containing an ideal 'resIdeal'
+ASSUME:  The basering is the n-th Weyl algebra over a field of characteristic 0
+@*       and for all 1<=i<=n the identity var(i+n)*var(i)=var(i)*var(i+1)+1
+@*       holds, i.e. the sequence of variables is given by
+@*       x(1),...,x(n),D(1),...,D(n), where D(i) is the differential operator
+@*       belonging to x(i).
+@*       Further, assume that I is holonomic and that w is n-dimensional with
+@*       non-negative entries.
+PURPOSE: computes the restriction ideal of a holonomic ideal to the subspace
+@*       defined by the variables corresponding to the non-zero entries of the
+@*       given intvec
+NOTE:    The output ring is the Weyl algebra defined by the zero entries of w.
+@*       It contains an ideal 'resIdeal' being the restriction ideal of I wrt w.
+@*       If there are no zero entries, the input ring is returned.
+@*       If eng<>0, @code{std} is used for Groebner basis computations,
+@*       otherwise, and by default, @code{slimgb} is used.
+@*       The minimal integer root of the b-function of I wrt the weight (-w,w)
+@*       can be specified via the optional argument m.
+@*       The optional argument G is used for specifying a Groebner basis of I
+@*       wrt the weight (-w,w), that is, the initial form of G generates the
+@*       initial ideal of I wrt the weight (-w,w).
+@*       Further note, that the assumptions on m and G (if given) are not
+@*       checked.
+DISPLAY: If printlevel=1, progress debug messages will be printed,
+@*       if printlevel>=2, all the debug messages will be printed.
+EXAMPLE: example restrictionIdeal; shows examples
+"
+{
+  def rm = restrictionIdealEngine(I,w,"restriction",#);
+  return(rm);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(a,x,b,Da,Dx,Db),dp;
+  def D3 = Weyl();
+  setring D3;
+  ideal I = a*Db-Dx+2*Da,
+    x*Db-Da,
+    x*Da+a*Da+b*Db+1,
+    x*Dx-2*x*Da-a*Da,
+    b*Db^2+Dx*Da-Da^2+Db,
+    a*Dx*Da+2*x*Da^2+a*Da^2+b*Dx*Db+Dx+2*Da;
+  intvec w = 1,0,0;
+  def D2 = restrictionIdeal(I,w);
+  setring D2; D2;
+  resIdeal;
+}
+
+proc fourier (ideal I, list #)
+"USAGE:  fourier(I[,v]); I an ideal, v an optional intvec
+RETURN:  ideal
+PURPOSE: computes the Fourier transform of an ideal in a Weyl algebra
+ASSUME:  The basering is the n-th Weyl algebra over a field of characteristic 0
+@*       and for all 1<=i<=n the identity var(i+n)*var(i)=var(i)*var(i+1)+1
+@*       holds, i.e. the sequence of variables is given by
+@*       x(1),...,x(n),D(1),...,D(n), where D(i) is the differential operator
+@*       belonging to x(i).
+NOTE:    The Fourier automorphism is defined by mapping x(i) to -D(i) and
+@*       D(i) to x(i).
+@*       If v is an intvec with entries ranging from 1 to n, the Fourier
+@*       transform of I restricted to the variables given by v is computed.
+SEE ALSO: inverseFourier
+EXAMPLE: example fourier; shows examples
+"
+{
+  dmodappMoreAssumeViolation();
+  intvec v;
+  if (size(#)>0)
+  {
+    if(typeof(#[1])=="intvec")
+    {
+      v = #[1];
+    }
+  }
+  int n = nvars(basering) div 2;
+  int i;
+  if(v <> 0:size(v))
+  {
+    v = sortIntvec(v)[1];
+    for (i=1; i<size(v); i++)
+    {
+      if (v[i] == v[i+1])
+      {
+        ERROR("No double entries allowed in intvec");
+      }
+    }
+  }
+  else
+  {
+    v = 1..n;
+  }
+  ideal m = maxideal(1);
+  for (i=1; i<=size(v); i++)
+  {
+    if (v[i]<0 || v[i]>n)
+    {
+      ERROR("Entries of intvec must range from 1 to "+string(n));
+    }
+    m[v[i]] = -var(v[i]+n);
+    m[v[i]+n] = var(v[i]);
+  }
+  map F = basering,m;
+  ideal FI = F(I);
+  return(FI);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y,Dx,Dy),dp;
+  def D2 = Weyl();
+  setring D2;
+  ideal I = x*Dx+2*y*Dy+2, x^2*Dx+y*Dx+2*x;
+  intvec v = 2;
+  fourier(I,v);
+  fourier(I);
+}
+
+proc inverseFourier (ideal I, list #)
+"USAGE:  inverseFourier(I[,v]); I an ideal, v an optional intvec
+RETURN:  ideal
+PURPOSE: computes the inverse Fourier transform of an ideal in a Weyl algebra
+ASSUME:  The basering is the n-th Weyl algebra over a field of characteristic 0
+@*       and for all 1<=i<=n the identity var(i+n)*var(i)=var(i)*var(i+1)+1
+@*       holds, i.e. the sequence of variables is given by
+@*       x(1),...,x(n),D(1),...,D(n), where D(i) is the differential operator
+@*       belonging to x(i).
+NOTE:    The Fourier automorphism is defined by mapping x(i) to -D(i) and
+@*       D(i) to x(i).
+@*       If v is an intvec with entries ranging from 1 to n, the inverse Fourier
+@*       transform of I restricted to the variables given by v is computed.
+SEE ALSO: fourier
+EXAMPLE: example inverseFourier; shows examples
+"
+{
+  dmodappMoreAssumeViolation();
+  intvec v;
+  if (size(#)>0)
+  {
+    if(typeof(#[1])=="intvec")
+    {
+      v = #[1];
+    }
+  }
+  int n = nvars(basering) div 2;
+  int i;
+  if(v <> 0:size(v))
+  {
+    v = sortIntvec(v)[1];
+    for (i=1; i<size(v); i++)
+    {
+      if (v[i] == v[i+1])
+      {
+        ERROR("No double entries allowed in intvec");
+      }
+    }
+  }
+  else
+  {
+    v = 1..n;
+  }
+  ideal m = maxideal(1);
+  for (i=1; i<=size(v); i++)
+  {
+    if (v[i]<0 || v[i]>n)
+    {
+      ERROR("Entries of intvec must range between 1 and "+string(n));
+    }
+    m[v[i]] = var(v[i]+n);
+    m[v[i]+n] = -var(v[i]);
+  }
+  map F = basering,m;
+  ideal FI = F(I);
+  return(FI);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y,Dx,Dy),dp;
+  def D2 = Weyl();
+  setring D2;
+  ideal I = x*Dx+2*y*Dy+2, x^2*Dx+y*Dx+2*x;
+  intvec v = 2;
+  ideal FI = fourier(I);
+  inverseFourier(FI);
+}
+
+proc integralModule (ideal I, intvec w, list #)
+"USAGE:  integralModule(I,w,[,eng,m,G]);
+@*       I ideal, w intvec, eng and m optional ints, G optional ideal
+RETURN:  ring (a Weyl algebra) containing a module 'intMod'
+ASSUME:  The basering is the n-th Weyl algebra over a field of characteristic 0
+@*       and for all 1<=i<=n the identity var(i+n)*var(i)=var(i)*var(i+1)+1
+@*       holds, i.e. the sequence of variables is given by
+@*       x(1),...,x(n),D(1),...,D(n), where D(i) is the differential operator
+@*       belonging to x(i).
+@*       Further, assume that I is holonomic and that w is n-dimensional with
+@*       non-negative entries.
+PURPOSE: computes the integral module of a holonomic ideal w.r.t. the subspace
+@*       defined by the variables corresponding to the non-zero entries of the
+@*       given intvec
+NOTE:    The output ring is the Weyl algebra defined by the zero entries of w.
+@*       It contains a module 'intMod' being the integral module of I wrt w.
+@*       If there are no zero entries, the input ring is returned.
+@*       If eng<>0, @code{std} is used for Groebner basis computations,
+@*       otherwise, and by default, @code{slimgb} is used.
+@*       Let F(I) denote the Fourier transform of I w.r.t. w.
+@*       The minimal integer root of the b-function of F(I) w.r.t. the weight
+@*       (-w,w) can be specified via the optional argument m.
+@*       The optional argument G is used for specifying a Groebner Basis of F(I)
+@*       wrt the weight (-w,w), that is, the initial form of G generates the
+@*       initial ideal of F(I) w.r.t. the weight (-w,w).
+@*       Further note, that the assumptions on m and G (if given) are not
+@*       checked.
+DISPLAY: If printlevel=1, progress debug messages will be printed,
+@*       if printlevel>=2, all the debug messages will be printed.
+EXAMPLE: example integralModule; shows examples
+"
+{
+  int l0,l0set,Gset;
+  ideal G;
+  int whichengine = 0;         // default
+  if (size(#)>0)
+  {
+    if (intLike(#[1]))
+    {
+      whichengine = int(#[1]);
+    }
+    if (size(#)>1)
+    {
+      if (intLike(#[2]))
+      {
+        l0 = int(#[2]);
+        l0set = 1;
+      }
+      if (size(#)>2)
+      {
+        if (typeof(#[3])=="ideal")
+        {
+          G = #[3];
+          Gset = 1;
+        }
+      }
+    }
+  }
+  int ppl = printlevel;
+  int i;
+  int n = nvars(basering) div 2;
+  intvec v;
+  for (i=1; i<=n; i++)
+  {
+    if (w[i]>0)
+    {
+      if (v == 0:size(v))
+      {
+        v[1] = i;
+      }
+      else
+      {
+        v[size(v)+1] = i;
+      }
+    }
+  }
+  ideal FI = fourier(I,v);
+  dbprint(ppl,"// computed Fourier transform of given ideal");
+  dbprint(ppl-1,"// " + string(FI));
+  list L;
+  if (l0set)
+  {
+    if (Gset) // l0 and G given
+    {
+      L = restrictionModuleEngine(FI,w,whichengine,l0,G);
+    }
+    else      // l0 given, G not
+    {
+      L = restrictionModuleEngine(FI,w,whichengine,l0);
+    }
+  }
+  else        // nothing given
+  {
+    L = restrictionModuleEngine(FI,w,whichengine);
+  }
+  ideal B,N;
+  B = inverseFourier(L[1],v);
+  N = inverseFourier(L[2],v);
+  def newR = restrictionModuleOutput(B,N,w,whichengine,"intMod");
+  return(newR);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,b,Dx,Db),dp;
+  def D2 = Weyl();
+  setring D2;
+  ideal I = x*Dx+2*b*Db+2, x^2*Dx+b*Dx+2*x;
+  intvec w = 1,0;
+  def im = integralModule(I,w);
+  setring im; im;
+  print(intMod);
+}
+
+proc integralIdeal (ideal I, intvec w, list #)
+"USAGE:  integralIdeal(I,w,[,eng,m,G]);
+@*       I ideal, w intvec, eng and m optional ints, G optional ideal
+RETURN:  ring (a Weyl algebra) containing an ideal 'intIdeal'
+ASSUME:  The basering is the n-th Weyl algebra over a field of characteristic 0
+@*       and for all 1<=i<=n the identity var(i+n)*var(i)=var(i)*var(i+1)+1
+@*       holds, i.e. the sequence of variables is given by
+@*       x(1),...,x(n),D(1),...,D(n), where D(i) is the differential operator
+@*       belonging to x(i).
+@*       Further, assume that I is holonomic and that w is n-dimensional with
+@*       non-negative entries.
+PURPOSE: computes the integral ideal of a holonomic ideal w.r.t. the subspace
+@*       defined by the variables corresponding to the non-zero entries of the
+@*       given intvec.
+NOTE:    The output ring is the Weyl algebra defined by the zero entries of w.
+@*       It contains ideal 'intIdeal' being the integral ideal of I w.r.t. w.
+@*       If there are no zero entries, the input ring is returned.
+@*       If eng<>0, @code{std} is used for Groebner basis computations,
+@*       otherwise, and by default, @code{slimgb} is used.
+@*       The minimal integer root of the b-function of I wrt the weight (-w,w)
+@*       can be specified via the optional argument m.
+@*       The optional argument G is used for specifying a Groebner basis of I
+@*       wrt the weight (-w,w), that is, the initial form of G generates the
+@*       initial ideal of I wrt the weight (-w,w).
+@*       Further note, that the assumptions on m and G (if given) are not
+@*       checked.
+DISPLAY: If printlevel=1, progress debug messages will be printed,
+@*       if printlevel>=2, all the debug messages will be printed.
+EXAMPLE: example integralIdeal; shows examples
+"
+{
+  def im = restrictionIdealEngine(I,w,"integral",#);
+  return(im);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,b,Dx,Db),dp;
+  def D2 = Weyl();
+  setring D2;
+  ideal I = x*Dx+2*b*Db+2, x^2*Dx+b*Dx+2*x;
+  intvec w = 1,0;
+  def D1 = integralIdeal(I,w);
+  setring D1; D1;
+  intIdeal;
+}
+
+proc deRhamCohomIdeal (ideal I, list #)
+"USAGE:  deRhamCohomIdeal (I[,w,eng,k,G]);
+@*       I ideal, w optional intvec, eng and k optional ints, G optional ideal
+RETURN:  ideal
+ASSUME:  The basering is the n-th Weyl algebra D over a field of characteristic
+@*       zero and for all 1<=i<=n the identity var(i+n)*var(i)=var(i)*var(i+1)+1
+@*       holds, i.e. the sequence of variables is given by
+@*       x(1),...,x(n),D(1),...,D(n), where D(i) is the differential operator
+@*       belonging to x(i).
+@*       Further, assume that I is of special kind, namely let f in K[x] and
+@*       consider the module K[x,1/f]f^m, where m is smaller than or equal to
+@*       the minimal integer root of the Bernstein-Sato polynomial of f.
+@*       Since this module is known to be a holonomic D-module, it has a cyclic
+@*       presentation D/I.
+PURPOSE: computes a basis of the n-th de Rham cohomology group of the complement
+@*       of the hypersurface defined by f
+NOTE:    The elements of the basis are of the form f^m*p, where p runs over the
+@*       entries of the returned ideal.
+@*       If I does not satisfy the assumptions described above, the result might
+@*       have no meaning. Note that I can be computed with @code{annfs}.
+@*       If w is an intvec with exactly n strictly positive entries, w is used
+@*       in the computation. Otherwise, and by default, w is set to (1,...,1).
+@*       If eng<>0, @code{std} is used for Groebner basis computations,
+@*       otherwise, and by default, @code{slimgb} is used.
+@*       Let F(I) denote the Fourier transform of I wrt w.
+@*       An integer smaller than or equal to the minimal integer root of the
+@*       b-function of F(I) wrt the weight (-w,w) can be specified via the
+@*       optional argument k.
+@*       The optional argument G is used for specifying a Groebner Basis of F(I)
+@*       wrt the weight (-w,w), that is, the initial form of G generates the
+@*       initial ideal of F(I) wrt the weight (-w,w).
+@*       Further note, that the assumptions on I, k and G (if given) are not
+@*       checked.
+THEORY:  (SST) pp. 232-235
+DISPLAY: If printlevel=1, progress debug messages will be printed,
+@*       if printlevel>=2, all the debug messages will be printed.
+SEE ALSO: deRhamCohom
+EXAMPLE: example deRhamCohomIdeal; shows examples
+"
+{
+  intvec w = 1:(nvars(basering) div 2);
+  int l0,l0set,Gset;
+  ideal G;
+  int whichengine = 0;         // default
+  if (size(#)>0)
+  {
+    if (typeof(#[1])=="intvec")
+    {
+      if (allPositive(#[1])==1)
+      {
+        w = #[1];
+      }
+      else
+      {
+        print("// Entries of intvec must be strictly positive");
+        print("// Using weight " + string(w));
+      }
+      if (size(#)>1)
+      {
+        if (intLike(#[2]))
+        {
+          whichengine = int(#[2]);
+        }
+        if (size(#)>2)
+        {
+          if (intLike(#[3]))
+          {
+            l0 = int(#[3]);
+            l0set = 1;
+          }
+          if (size(#)>3)
+          {
+            if (typeof(#[4])=="ideal")
+            {
+              G = #[4];
+              Gset = 1;
+            }
+          }
+        }
+      }
+    }
+  }
+  int ppl = printlevel;
+  int i,j;
+  int n = nvars(basering) div 2;
+  intvec v;
+  for (i=1; i<=n; i++)
+  {
+    if (w[i]>0)
+    {
+      if (v == 0:size(v))
+      {
+        v[1] = i;
+      }
+      else
+      {
+        v[size(v)+1] = i;
+      }
+    }
+  }
+  ideal FI = fourier(I,v);
+  dbprint(ppl,"// computed Fourier transform of given ideal");
+  dbprint(ppl-1,"// " + string(FI));
+  list L;
+  if (l0set)
+  {
+    if (Gset) // l0 and G given
+    {
+      L = restrictionModuleEngine(FI,w,whichengine,l0,G);
+    }
+    else      // l0 given, G not
+    {
+      L = restrictionModuleEngine(FI,w,whichengine,l0);
+    }
+  }
+  else        // nothing given
+  {
+    L = restrictionModuleEngine(FI,w,whichengine);
+  }
+  ideal B,N;
+  B = inverseFourier(L[1],v);
+  N = inverseFourier(L[2],v);
+  dbprint(ppl,"// computed integral module of given ideal");
+  dbprint(ppl-1,"// " + string(B));
+  dbprint(ppl-1,"// " + string(N));
+  ideal DR;
+  poly p;
+  poly Dt = 1;
+  for (i=1; i<=n; i++)
+  {
+    Dt = Dt*var(i+n);
+  }
+  N = simplify(N,2+8);
+  printlevel = printlevel-1;
+  N = linReduceIdeal(N);
+  N = simplify(N,2+8);
+  for (i=1; i<=size(B); i++)
+  {
+    p = linReduce(B[i],N);
+    if (p<>0)
+    {
+      DR[size(DR)+1] = B[i]*Dt;
+      j=1;
+      while ((j<size(N)) && (p<N[j]))
+      {
+        j++;
+      }
+      N = insertGenerator(N,p,j+1);
+    }
+  }
+  printlevel = printlevel + 1;
+  return(DR);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y,z),dp;
+  poly F = x^3+y^3+z^3;
+  bfctAnn(F);            // Bernstein-Sato poly of F has minimal integer root -2
+  def W = annRat(1,F^2); // so we compute the annihilator of 1/F^2
+  setring W; W;          // Weyl algebra, contains LD = Ann(1/F^2)
+  LD;                    // K[x,y,z,1/F]F^(-2) is isomorphic to W/LD as W-module
+  deRhamCohomIdeal(LD);  // we see that the K-dim is 2
+}
+
+proc deRhamCohom (poly f, list #)
+"USAGE:  deRhamCohom(f[,w,eng,m]);  f poly, w optional intvec,
+                                    eng and m optional ints
+RETURN:  ring (a Weyl Algebra) containing a list 'DR' of ideal and int
+ASSUME:  Basering is commutative and over a field of characteristic 0.
+PURPOSE: computes a basis of the n-th de Rham cohomology group of the complement
+@*       of the hypersurface defined by f, where n denotes the number of
+@*       variables of the basering
+NOTE:    The output ring is the n-th Weyl algebra. It contains a list 'DR' with
+@*       two entries (ideal J and int m) such that {f^m*J[i] : i=1..size(I)} is
+@*       a basis of the n-th de Rham cohomology group of the complement of the
+@*       hypersurface defined by f.
+@*       If w is an intvec with exactly n strictly positive entries, w is used
+@*       in the computation. Otherwise, and by default, w is set to (1,...,1).
+@*       If eng<>0, @code{std} is used for Groebner basis computations,
+@*       otherwise, and by default, @code{slimgb} is used.
+@*       If m is given, it is assumed to be less than or equal to the minimal
+@*       integer root of the Bernstein-Sato polynomial of f. This assumption is
+@*       not checked. If not specified, m is set to the minimal integer root of
+@*       the Bernstein-Sato polynomial of f.
+THEORY:  (SST) pp. 232-235
+DISPLAY: If printlevel=1, progress debug messages will be printed,
+@*       if printlevel>=2, all the debug messages will be printed.
+SEE ALSO: deRhamCohomIdeal
+EXAMPLE: example deRhamCohom; shows example
+"
+{
+  int ppl = printlevel - voice + 2;
+  def save = basering;
+  int n = nvars(save);
+  intvec w = 1:n;
+  int eng,l0,l0given;
+  if (size(#)>0)
+  {
+    if (typeof(#[1])=="intvec")
+    {
+      w = #[1];
+    }
+    if (size(#)>1)
+    {
+      if(intLike(#[2]))
+      {
+        eng = int(#[2]);
+      }
+      if (size(#)>2)
+      {
+        if(intLike(#[3]))
+        {
+          l0 = int(#[3]);
+          l0given = 1;
+        }
+      }
+    }
+  }
+  if (!isCommutative())
+  {
+    ERROR("Basering must be commutative.");
+  }
+  int i;
+  dbprint(ppl,"// Computing s-parametric annihilator Ann(f^s)...");
+  def A = Sannfs(f);
+  setring A;
+  dbprint(ppl,"// ...done");
+  dbprint(ppl-1,"//    Got: " + string(LD));
+  poly f = imap(save,f);
+  if (!l0given)
+  {
+    dbprint(ppl,"// Computing b-function of given poly...");
+    ideal LDf = LD,f;
+    LDf = engine(LDf,eng);
+    vector v = pIntersect(var(2*n+1),LDf);   // BS poly of f
+    list BS = bFactor(vec2poly(v));
+    dbprint(ppl,"// ...done");
+    dbprint(ppl-1,"// roots: " + string(BS[1]));
+    dbprint(ppl-1,"// multiplicities: " + string(BS[2]));
+    BS = intRoots(BS);
+    intvec iv;
+    for (i=1; i<=ncols(BS[1]); i++)
+    {
+      iv[i] = int(BS[1][i]);
+    }
+    l0 = Min(iv);
+    kill v,iv,BS,LDf;
+  }
+  dbprint(ppl,"// Computing Ann(f^" + string(l0) + ")...");
+  LD = annfspecial(LD,f,l0,l0); // Ann(f^l0)
+  // create new ring without s
+  list RL = ringlist(A);
+  RL = RL[1..4];
+  list Lt = RL[2];
+  Lt = delete(Lt,2*n+1);
+  RL[2] = Lt;
+  Lt = RL[3];
+  Lt = delete(Lt,2);
+  RL[3] = Lt;
+  def @B = ring(RL);
+  setring @B;
+  def B = Weyl();
+  setring B;
+  kill @B;
+  ideal LD = imap(A,LD);
+  LD = engine(LD,eng);
+  dbprint(ppl,"// ...done");
+  dbprint(ppl-1,"//    Got: " + string(LD));
+  kill A;
+  ideal DRJ = deRhamCohomIdeal(LD,w,eng);
+  list DR = DRJ,l0;
+  export(DR);
+  setring save;
+  return(B);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y,z),dp;
+  poly f = x^3+y^3+z^3;
+  def A = deRhamCohom(f); // we see that the K-dim is 2
+  setring A;
+  DR;
+}
+
+// Appel hypergeometric functions /////////////////////////////////////////////
+
+proc appelF1()
+"USAGE:  appelF1();
+RETURN:  ring (a parametric Weyl algebra) containing an ideal 'IAppel1'
+PURPOSE: defines the ideal in a parametric Weyl algebra,
+@*       which annihilates Appel F1 hypergeometric function
+NOTE:    The output ring is a parametric Weyl algebra. It contains an ideal
+@*       'IAappel1' annihilating Appel F1 hypergeometric function.
+@*       See (SST) p. 48.
+EXAMPLE: example appelF1; shows example
+"
+{
+  // Appel F1, d = b', SST p.48
+  ring @r = (0,a,b,c,d),(x,y,Dx,Dy),(a(0,0,1,1),a(0,0,1,0),dp);
+  def @S = Weyl();
+  setring @S;
+  ideal IAppel1 =
+    (x*Dx)*(x*Dx+y*Dy+c-1) - x*(x*Dx+y*Dy+a)*(x*Dx+b),
+    (y*Dy)*(x*Dx+y*Dy+c-1) - y*(x*Dx+y*Dy+a)*(y*Dy+d),
+    (x-y)*Dx*Dy - d*Dx + b*Dy;
+  export IAppel1;
+  kill @r;
+  return(@S);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  def A = appelF1();
+  setring A;
+  IAppel1;
+}
+
+proc appelF2()
+"USAGE:  appelF2();
+RETURN:  ring (a parametric Weyl algebra) containing an ideal 'IAppel2'
+PURPOSE: defines the ideal in a parametric Weyl algebra,
+@*       which annihilates Appel F2 hypergeometric function
+NOTE:    The output ring is a parametric Weyl algebra. It contains an ideal
+@*       'IAappel2' annihilating Appel F2 hypergeometric function.
+@*       See (SST) p. 85.
+EXAMPLE: example appelF2; shows example
+"
+{
+  // Appel F2, c = b', SST p.85
+  ring @r = (0,a,b,c),(x,y,Dx,Dy),(a(0,0,1,1),a(0,0,1,0),dp);
+  def @S = Weyl();
+  setring @S;
+  ideal IAppel2 =
+    (x*Dx)^2 - x*(x*Dx+y*Dy+a)*(x*Dx+b),
+    (y*Dy)^2 - y*(x*Dx+y*Dy+a)*(y*Dy+c);
+  export IAppel2;
+  kill @r;
+  return(@S);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  def A = appelF2();
+  setring A;
+  IAppel2;
+}
+
+proc appelF4()
+"USAGE:  appelF4();
+RETURN:  ring (a parametric Weyl algebra) containing an ideal 'IAppel4'
+PURPOSE: defines the ideal in a parametric Weyl algebra,
+@*       which annihilates Appel F4 hypergeometric function
+NOTE:    The output ring is a parametric Weyl algebra. It contains an ideal
+@*       'IAappel4' annihilating Appel F4 hypergeometric function.
+@*       See (SST) p. 39.
+EXAMPLE: example appelF4; shows example
+"
+{
+  // Appel F4, d = c', SST, p. 39
+  ring @r = (0,a,b,c,d),(x,y,Dx,Dy),(a(0,0,1,1),a(0,0,1,0),dp);
+  def @S = Weyl();
+  setring @S;
+  ideal IAppel4 =
+    Dx*(x*Dx+c-1) - (x*Dx+y*Dy+a)*(x*Dx+y*Dy+b),
+    Dy*(y*Dy+d-1) - (x*Dx+y*Dy+a)*(x*Dx+y*Dy+b);
+  export IAppel4;
+  kill @r;
+  return(@S);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  def A = appelF4();
+  setring A;
+  IAppel4;
+}
+
+
+// characteric variety ////////////////////////////////////////////////////////
+
+proc charVariety(ideal I, list #)
+"USAGE:  charVariety(I [,eng]); I an ideal, eng an optional int
+RETURN:  ring (commutative) containing an ideal 'charVar'
+PURPOSE: computes an ideal whose zero set is the characteristic variety of I in
+@*       the sense of D-module theory
+ASSUME:  The basering is the n-th Weyl algebra over a field of characteristic 0
+@*       and for all 1<=i<=n the identity var(i+n)*var(i)=var(i)*var(i+1)+1
+@*       holds, i.e. the sequence of variables is given by
+@*       x(1),...,x(n),D(1),...,D(n), where D(i) is the differential operator
+@*       belonging to x(i).
+NOTE:    The output ring is commutative. It contains an ideal 'charVar'.
+@*       If eng<>0, @code{std} is used for Groebner basis computations,
+@*       otherwise, and by default, @code{slimgb} is used.
+DISPLAY: If @code{printlevel}=1, progress debug messages will be printed,
+@*       if @code{printlevel}>=2, all the debug messages will be printed.
+SEE ALSO: charInfo
+EXAMPLE: example charVariety; shows examples
+"
+{
+  // assumption check is done in GBWeight
+  int eng;
+  if (size(#)>0)
+  {
+    if (intLike(#[1]))
+    {
+      eng = int(#[1]);
+    }
+  }
+  int ppl = printlevel - voice + 2;
+  def save = basering;
+  int n = nvars(save) div 2;
+  intvec uv = (0:n),(1:n);
+  list RL = ringlist(save);
+  list L = RL[3];
+  L = insert(L,list("a",uv));
+  RL[3] = L;
+  // TODO printlevel
+  def Ra = ring(RL);
+  setring Ra;
+  dbprint(ppl,"// Starting Groebner basis computation...");
+  ideal I = imap(save,I);
+  I = engine(I,eng);
+  dbprint(ppl,"// ... done.");
+  dbprint(ppl-1,"//    Got: " + string(I));
+  setring save;
+  RL = ringlist(save);
+  RL = RL[1..4];
+  def newR = ring(RL);
+  setring newR;
+  ideal charVar = imap(Ra,I);
+  charVar = inForm(charVar,uv);
+  // charVar = groebner(charVar);
+  export(charVar);
+  setring save;
+  return(newR);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y),Dp;
+  poly F = x3-y2;
+  printlevel = 0;
+  def A  = annfs(F);
+  setring A;      // Weyl algebra
+  LD;             // the annihilator of F
+  def CA = charVariety(LD);
+  setring CA; CA; // commutative ring
+  charVar;
+  dim(std(charVar));   // hence I is holonomic
+}
+
+proc charInfo(ideal I)
+"USAGE:  charInfo(I);  I an ideal
+RETURN:  ring (commut.) containing ideals 'charVar','singLoc' and list 'primDec'
+PURPOSE: computes characteristic variety of I (in the sense of D-module theory),
+@*       its singular locus and primary decomposition
+ASSUME:  The basering is the n-th Weyl algebra over a field of characteristic 0
+@*       and for all 1<=i<=n the identity var(i+n)*var(i)=var(i)*var(i+1)+1
+@*       holds, i.e. the sequence of variables is given by
+@*       x(1),...,x(n),D(1),...,D(n), where D(i) is the differential operator
+@*       belonging to x(i).
+NOTE:    In the output ring, which is commutative:
+@*       - the ideal 'charVar' is the characteristic variety char(I),
+@*       - the ideal 'SingLoc' is the singular locus of char(I),
+@*       - the list 'primDec' is the primary decomposition of char(I).
+DISPLAY: If @code{printlevel}=1, progress debug messages will be printed,
+@*       if @code{printlevel}>=2, all the debug messages will be printed.
+EXAMPLE: example charInfo; shows examples
+"
+{
+  int ppl = printlevel - voice + 2;
+  def save = basering;
+  dbprint(ppl,"// computing characteristic variety...");
+  def A = charVariety(I);
+  setring A;
+  dbprint(ppl,"// ...done");
+  dbprint(ppl-1,"//    Got: " + string(charVar));
+  dbprint(ppl,"// computing singular locus...");
+  ideal singLoc = slocus(charVar);
+  singLoc = groebner(singLoc);
+  dbprint(ppl,"// ...done");
+  dbprint(ppl-1,"//    Got: " + string(singLoc));
+  dbprint(ppl,"// computing primary decomposition...");
+  list primDec = primdecGTZ(charVar);
+  dbprint(ppl,"// ...done");
+  //export(charVar,singLoc,primDec);
+  export(singLoc,primDec);
+  setring save;
+  return(A);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y),Dp;
+  poly F = x3-y2;
+  printlevel = 0;
+  def A  = annfs(F);
+  setring A;      // Weyl algebra
+  LD;             // the annihilator of F
+  def CA = charInfo(LD);
+  setring CA; CA; // commutative ring
+  charVar;        // characteristic variety
+  singLoc;        // singular locus
+  primDec;        // primary decomposition
+}
+
+
+// examples ///////////////////////////////////////////////////////////////////
+
+/*
+  static proc exCusp()
+  {
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y,Dx,Dy),dp;
+  def R = Weyl();   setring R;
+  poly F = x2-y3;
+  ideal I = (y^3 - x^2)*Dx - 2*x, (y^3 - x^2)*Dy + 3*y^2; // I = Dx*F, Dy*F;
+  def W = SDLoc(I,F);
+  setring W;
+  LD;
+  def U = DLoc0(LD,x2-y3);
+  setring U;
+  LD0;
+  BS;
+  // the same with DLoc:
+  setring R;
+  DLoc(I,F);
+  }
+
+  static proc exWalther1()
+  {
+  // p.18 Rem 3.10
+  ring r = 0,(x,Dx),dp;
+  def R = nc_algebra(1,1);
+  setring R;
+  poly F = x;
+  ideal I = x*Dx+1;
+  def W = SDLoc(I,F);
+  setring W;
+  LD;
+  ideal J = LD, x;
+  eliminate(J,x*Dx); // must be [1]=s // agree!
+  // the same result with Dloc0:
+  def U = DLoc0(LD,x);
+  setring U;
+  LD0;
+  BS;
+  }
+
+  static proc exWalther2()
+  {
+  // p.19 Rem 3.10 cont'd
+  ring r = 0,(x,Dx),dp;
+  def R = nc_algebra(1,1);
+  setring R;
+  poly F = x;
+  ideal I = (x*Dx)^2+1;
+  def W = SDLoc(I,F);
+  setring W;
+  LD;
+  ideal J = LD, x;
+  eliminate(J,x*Dx); // must be [1]=s^2+2*s+2 // agree!
+  // the same result with Dloc0:
+  def U = DLoc0(LD,x);
+  setring U;
+  LD0;
+  BS;
+  // almost the same with DLoc
+  setring R;
+  DLoc(I,F);
+  }
+
+  static proc exWalther3()
+  {
+  // can check with annFs too :-)
+  // p.21 Ex 3.15
+  LIB "nctools.lib";
+  ring r = 0,(x,y,z,w,Dx,Dy,Dz,Dw),dp;
+  def R = Weyl();
+  setring R;
+  poly F = x2+y2+z2+w2;
+  ideal I = Dx,Dy,Dz,Dw;
+  def W = SDLoc(I,F);
+  setring W;
+  LD;
+  ideal J = LD, x2+y2+z2+w2;
+  eliminate(J,x*y*z*w*Dx*Dy*Dz*Dw); // must be [1]=s^2+3*s+2 // agree
+  ring r2 =  0,(x,y,z,w),dp;
+  poly F = x2+y2+z2+w2;
+  def Z = annfs(F);
+  setring Z;
+  LD;
+  BS;
+  // the same result with Dloc0:
+  setring W;
+  def U = DLoc0(LD,x2+y2+z2+w2);
+  setring U;
+  LD0;  BS;
+  // the same result with DLoc:
+  setring R;
+  DLoc(I,F);
+  }
+
+  static proc ex_annRat()
+  {
+  // more complicated example for annRat
+  ring r = 0,(x,y,z),dp;
+  poly f = x3+y3+z3; // mir = -2
+  poly g = x*y*z;
+  def A = annRat(g,f);
+  setring A;
+  }
+*/
diff --git a/Singular/LIB/dmodloc.lib b/Singular/LIB/dmodloc.lib
new file mode 100644
index 0000000..0bba2cf
--- /dev/null
+++ b/Singular/LIB/dmodloc.lib
@@ -0,0 +1,2650 @@
+/////////////////////////////////////////////////////////////////////
+version="version dmodloc.lib 4.0.0.0 Jun_2013 "; // $Id: 56e865161a0d398b43e7f628f4433a925efbc538 $
+category="Noncommutative";
+info="
+LIBRARY: dmodloc.lib     Localization of algebraic D-modules and applications
+AUTHOR:  Daniel Andres,  daniel.andres at math.rwth-aachen.de
+
+Support: DFG Graduiertenkolleg 1632 `Experimentelle und konstruktive Algebra'
+
+
+OVERVIEW:
+Let I be a left ideal in the n-th polynomial Weyl algebra D=K[x]<d> and
+let f be a polynomial in K[x].
+
+If D/I is a holonomic module over D, it is known that the localization of D/I
+at f is also holonomic. The procedure @code{Dlocalization} computes an ideal
+J in D such that this localization is isomorphic to D/J as D-modules.
+
+If one regards I as an ideal in the rational Weyl algebra as above, K(x)<d>*I,
+and intersects with K[x]<d>, the result is called the Weyl closure of I.
+The procedures @code{WeylClosure} (if I has finite holonomic rank) and
+ at code{WeylClosure1} (if I is in the first Weyl algebra) can be used for
+computations.
+
+As an application of the Weyl closure, the procedure @code{annRatSyz} computes
+a holonomic part of the annihilator of a rational function by computing certain
+syzygies. The full annihilator can be obtained by taking the Weyl closure of
+the result.
+
+If one regards the left ideal I as system of linear PDEs, one can find its
+polynomial solutions with @code{polSol} (if I is holonomic) or
+ at code{polSolFiniteRank} (if I is of finite holonomic rank). Rational solutions
+can be obtained with @code{ratSol}.
+
+The procedure @code{bfctBound} computes a possible multiple of the b-function
+for f^s*u at a generic root of f. Here, u stands for [1] in D/I.
+
+This library also offers the procedures @code{holonomicRank} and
+ at code{DsingularLocus} to compute the holonomic rank and the singular locus
+of the D-module D/I.
+
+
+REFERENCES:
+   (OT)  T. Oaku, N. Takayama: `Algorithms for D-modules',
+         Journal of Pure and Applied Algebra, 1998.
+@* (OTT) T. Oaku, N. Takayama, H. Tsai: `Polynomial and rational solutions
+         of holonomic systems', Journal of Pure and Applied Algebra, 2001.
+@* (OTW) T. Oaku, N. Takayama, U. Walther: `A Localization Algorithm for
+         D-modules', Journal of Symbolic Computation, 2000.
+@* (Tsa) H. Tsai: `Algorithms for algebraic analysis', PhD thesis, 2000.
+
+
+PROCEDURES:
+Dlocalization(I,f[,k,e]);  computes the localization of a D-module
+WeylClosure(I);    computes the Weyl closure of an ideal in the Weyl algebra
+WeylClosure1(L);   computes the Weyl closure of operator in first Weyl algebra
+holonomicRank(I);  computes the holonomic rank of I
+DsingularLocus(I); computes the singular locus of a D-module
+polSol(I[,w,m]);   computes basis of polynomial solutions to the given system
+polSolFiniteRank(I[,w]); computes basis of polynomial solutions to given system
+ratSol(I);         computes basis of rational solutions to the given system
+bfctBound(I,f[,primdec]); computes multiple of b-function for f^s*u
+annRatSyz(f,g[,db,eng]);  computes part of annihilator of rational function g/f
+
+dmodGeneralAssumptionCheck();   check general assumptions
+safeVarName(s);    finds a free name to use for a new variable
+extendWeyl(S);     extends basering (Weyl algebra) by given vars
+polyVars(f,v);     checks whether f contains only variables indexed by v
+monomialInIdeal(I);    computes all monomials appearing in generators of ideal
+vars2pars(v);      converts variables specified by v into parameters
+minIntRoot2(L);    finds minimal integer root in a list of roots
+maxIntRoot(L);     finds maximal integer root in a list of roots
+dmodAction(id,f[,v]);  computes the natural action of a D-module on K[x]
+dmodActionRat(id,w);   computes the natural action of a D-module on K(x)
+simplifyRat(v);    simplifies rational function
+addRat(v,w);       adds rational functions
+multRat(v,w);      multiplies rational functions
+diffRat(v,j);      derives rational function
+commRing();        deletes non-commutative relations from ring
+rightNFWeyl(id,k); computes right NF wrt right ideal (var(k)) in Weyl algebra
+
+
+KEYWORDS: D-module; holonomic rank; singular locus of D-module;
+D-localization; localization of D-module; characteristic variety;
+Weyl closure; polynomial solutions; rational solutions;
+annihilator of rational function
+
+
+SEE ALSO: bfun_lib, dmod_lib, dmodapp_lib, dmodvar_lib, gmssing_lib
+";
+
+
+/*
+CHANGELOG:
+12.11.12: bugfixes, updated docu
+17.12.12: updated docu, removed redundant procedure killTerms
+*/
+
+
+LIB "bfun.lib";    // for pIntersect etc
+LIB "dmodapp.lib"; // for GBWeight, charVariety etc
+LIB "nctools.lib"; // for Weyl, isWeyl etc
+// TODO uncomment this once chern.lib is ready
+// LIB "chern.lib";   // for orderedPartition
+
+
+// testing for consistency of the library /////////////////////////////////////
+
+static proc testdmodloc()
+{
+  example dmodGeneralAssumptionCheck;
+  example safeVarName;
+  example extendWeyl;
+  example polyVars;
+  example monomialInIdeal;
+  example vars2pars;
+  example minIntRoot2;
+  example maxIntRoot;
+  example dmodAction;
+  example dmodActionRat;
+  example simplifyRat;
+  example addRat;
+  example multRat;
+  example diffRat;
+  example commRing;
+  example holonomicRank;
+  example DsingularLocus;
+  example rightNFWeyl;
+  example Dlocalization;
+  example WeylClosure1;
+  example WeylClosure;
+  example polSol;
+  example polSolFiniteRank;
+  example ratSol;
+  example bfctBound;
+  example annRatSyz;
+}
+
+
+// tools //////////////////////////////////////////////////////////////////////
+
+proc dmodGeneralAssumptionCheck ()
+"
+USAGE:    dmodGeneralAssumptionCheck();
+RETURN:   nothing, but checks general assumptions on the basering
+NOTE:     This procedure checks the following conditions on the basering R
+          and prints an error message if any of them is violated:
+@*         - R is the n-th Weyl algebra over a field of characteristic 0,
+@*         - R is not a qring,
+@*         - for all 1<=i<=n the identity var(i+n)*var(i)=var(i)*var(i+1)+1
+             holds, i.e. the sequence of variables is given by
+             x(1),...,x(n),D(1),...,D(n), where D(i) is the differential
+             operator belonging to x(i).
+EXAMPLE:  example dmodGeneralAssumptionCheck; shows examples
+"
+{
+  // char K <> 0, qring
+  if (  (size(ideal(basering)) >0) || (char(basering) >0) )
+  {
+    ERROR("Basering is inappropriate: characteristic>0 or qring present");
+  }
+  // no Weyl algebra
+  if (isWeyl() == 0)
+  {
+    ERROR("Basering is not a Weyl algebra");
+  }
+  // wrong sequence of vars
+  int i,n;
+  n = nvars(basering) div 2;
+  for (i=1; i<=n; i++)
+  {
+    if (bracket(var(i+n),var(i))<>1)
+    {
+      ERROR(string(var(i+n))+" is not a differential operator for " +string(var(i)));
+    }
+  }
+  return();
+}
+example
+{
+  "EXAMPLE"; echo=2;
+  ring r = 0,(x,D),dp;
+  dmodGeneralAssumptionCheck(); // prints error message
+  def W = Weyl();
+  setring W;
+  dmodGeneralAssumptionCheck(); // returns nothing
+}
+
+
+proc safeVarName (string s)
+"
+USAGE:    safeVarName(s);  s string
+RETURN:   string, returns s if s is not the name of a par/var of basering
+          and `@' + s otherwise
+EXAMPLE:  example safeVarName; shows examples
+"
+{
+  string S = "," + charstr(basering) + "," + varstr(basering) + ",";
+  s = "," + s + ",";
+  while (find(S,s) <> 0)
+  {
+    s[1] = "@";
+    s = "," + s;
+  }
+  s = s[2..size(s)-1];
+  return(s);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = (0,a),(w, at w,x,y),dp;
+  safeVarName("a");
+  safeVarName("x");
+  safeVarName("z");
+  safeVarName("w");
+}
+
+
+proc extendWeyl (def newVars)
+"
+USAGE:    extendWeyl(S);  S string or list of strings
+ASSUME:   The basering is the n-th Weyl algebra over a field of
+          characteristic 0 and for all 1<=i<=n the identity
+          var(i+n)*var(i)=var(i)*var(i+1)+1 holds, i.e. the sequence of
+          variables is given by x(1),...,x(n),D(1),...,D(n), where D(i)
+          is the differential operator belonging to x(i).
+RETURN:   ring, Weyl algebra extended by vars given by S
+EXAMPLE:  example extendWeyl; shows examples
+"
+{
+  dmodGeneralAssumptionCheck();
+  int i,s;
+  string inpt = typeof(newVars);
+  list L;
+  if (inpt=="string")
+  {
+    s = 1;
+    L = newVars;
+  }
+  else
+  {
+    if (inpt=="list")
+    {
+      s = size(newVars);
+      if (s<1)
+      {
+        ERROR("No new variables specified.");
+      }
+      for (i=1; i<=s; i++)
+      {
+        if (typeof(newVars[i]) <> "string")
+        {
+          ERROR("Entries of input list must be of type string.");
+        }
+      }
+      L = newVars;
+    }
+    else
+    {
+      ERROR("Expected string or list of strings as input.");
+    }
+  }
+  def save = basering;
+  int n = nvars(save) div 2;
+  list RL = ringlist(save);
+  RL = RL[1..4];
+  list Ltemp = L;
+  for (i=s; i>0; i--)
+  {
+    Ltemp[n+s+i] = "D" + newVars[i];
+  }
+  for (i=n; i>0; i--)
+  {
+    Ltemp[s+i]     = RL[2][i];
+    Ltemp[n+2*s+i] = RL[2][n+i];
+  }
+  RL[2] = Ltemp;
+  Ltemp = list();
+  Ltemp[1] = list("dp",intvec(1:(2*n+2*s)));
+  Ltemp[2] = list("C",intvec(0));
+  RL[3] = Ltemp;
+  kill Ltemp;
+  def @Dv = ring(RL);
+  setring @Dv;
+  def Dv = Weyl();
+  setring save;
+  return(Dv);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring @D2 = 0,(x,y,Dx,Dy),dp;
+  def D2 = Weyl();
+  setring D2;
+  def D3 = extendWeyl("t");
+  setring D3; D3;
+  list L = "u","v";
+  def D5 = extendWeyl(L);
+  setring D5;
+  D5;
+}
+
+
+proc polyVars (poly f, intvec v)
+"
+USAGE:    polyVars(f,v);  f poly, v intvec
+RETURN:   int, 1 if f contains only variables indexed by v, 0 otherwise
+EXAMPLE:  example polyVars; shows examples
+"
+{
+  ideal varsf = variables(f); // vars contained in f
+  ideal V;
+  int i;
+  int n = nvars(basering);
+  for (i=1; i<=nrows(v); i++)
+  {
+    if ( (v[i]<0) || (v[i]>n) )
+    {
+      ERROR("var(" + string(v[i]) + ") out of range");
+    }
+    V[i] = var(v[i]);
+  }
+  attrib(V,"isSB",1);
+  ideal N = NF(varsf,V);
+  N = simplify(N,2);
+  if (N[1]==0)
+  {
+    return(1);
+  }
+  else
+  {
+    return(0);
+  }
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y,z),dp;
+  poly f = y^2+zy;
+  intvec v = 1,2;
+  polyVars(f,v); // does f depend only on x,y?
+  v = 2,3;
+  polyVars(f,v); // does f depend only on y,z?
+}
+
+
+proc monomialInIdeal (ideal I)
+"
+USAGE:    monomialInIdeal(I);  I ideal
+RETURN:   ideal consisting of all monomials appearing in generators of ideal
+EXAMLPE:  example monomialInIdeal; shows examples
+"
+{
+  // returns ideal consisting of all monomials appearing in generators of ideal
+  I = simplify(I,2+8);
+  int i;
+  poly p;
+  ideal M;
+  for (i=1; i<=size(I); i++)
+  {
+    p = I[i];
+    while (p<>0)
+    {
+      M[size(M)+1] = leadmonom(p);
+      p = p - lead(p);
+    }
+  }
+  M = simplify(M,4+2);
+  return(M);
+}
+example
+{
+  "EXAMPLE"; echo=2;
+  ring r = 0,(x,y),dp;
+  ideal I = x2+5x3y7, x-x2-6xy;
+  monomialInIdeal(I);
+}
+
+
+proc vars2pars (intvec v)
+"
+USAGE:    vars2pars(v);  v intvec
+ASSUME:   The basering is commutative.
+RETURN:   ring with variables specified by v converted into parameters
+EXAMPLE:  example vars2pars; shows examples
+"
+{
+  if (isCommutative() == 0)
+  {
+    ERROR("The basering must be commutative.");
+  }
+  v = sortIntvec(v)[1];
+  int sv = size(v);
+  if ( (v[1]<1) || (v[sv]<1) )
+  {
+    ERROR("Expected entries of intvec in the range 1.."+string(n));
+  }
+  def save = basering;
+  int i,j,n;
+  n = nvars(save);
+  list RL = ringlist(save);
+  list Lp,Lv,L1;
+  if (typeof(RL[1]) == "list")
+  {
+    L1 = RL[1];
+    Lp = L1[2];
+  }
+  else
+  {
+    L1[1] = RL[1];
+    L1[4] = ideal(0);
+  }
+  j = sv;
+  for (i=1; i<=n; i++)
+  {
+    if (j>0)
+    {
+      if (v[j]==i)
+      {
+        Lp[size(Lp)+1] = string(var(i));
+        j--;
+      }
+      else
+      {
+        Lv[size(Lv)+1] = string(var(i));
+      }
+    }
+    else
+    {
+      Lv[size(Lv)+1] = string(var(i));
+    }
+  }
+  RL[2] = Lv;
+  L1[2] = Lp;
+  L1[3] = list(list("lp",intvec(1:size(Lp))));
+  RL[1] = L1;
+  L1 = list();
+  L1[1] = list("dp",intvec(1:sv));
+  L1[2] = list("C",intvec(0));
+  RL[3] = L1;
+//   RL;
+  def R = ring(RL);
+  return(R);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y,z,a,b,c),dp;
+  intvec v = 4,5,6;
+  def R = vars2pars(v);
+  setring R;
+  R;
+  v = 1,2;
+  def RR = vars2pars(v);
+  setring RR;
+  RR;
+}
+
+
+static proc minMaxIntRoot (list L, string minmax)
+{
+  int win;
+  if (size(L)>1)
+  {
+    if ( (typeof(L[1])<>"ideal") || (typeof(L[2])<>"intvec") )
+    {
+      win = 1;
+    }
+  }
+  else
+  {
+    win = 1;
+  }
+  if (win)
+  {
+    ERROR("Expected list in the format of bFactor");
+  }
+  if (size(L)>2)
+  {
+    if ( (L[3]=="1") || (L[3]=="0") )
+    {
+      print("// Warning: Constant poly. Returning 0.");
+      return(int(0));
+    }
+  }
+  ideal I = L[1];
+  int i,k,b;
+  if (minmax=="min")
+  {
+    i = ncols(I);
+    k = -1;
+    b = 0;
+  }
+  else // minmax=="max"
+  {
+    i = 1;
+    k = 1;
+    b = ncols(I);
+  }
+  for (; k*i<k*b; i=i+k)
+  {
+    if (isInt(leadcoef(I[i])))
+    {
+      return(int(leadcoef(I[i])));
+    }
+  }
+  print("// Warning: No integer root found. Returning 0.");
+  return(int(0));
+}
+
+
+//TODO rename? minIntRoot is name of proc in dmod.lib
+proc minIntRoot2 (list L)
+"
+USAGE:    minIntRoot2(L);  L list
+ASSUME:   L is the output of bFactor.
+RETURN:   int, the minimal integer root in a list of roots
+SEE ALSO: minIntRoot, maxIntRoot, bFactor
+EXAMPLE:  example minIntRoot2; shows examples
+"
+{
+  return(minMaxIntRoot(L,"min"));
+}
+example
+{
+  "EXAMPLE"; echo=2;
+  ring r = 0,x,dp;
+  poly f = x*(x+1)*(x-2)*(x-5/2)*(x+5/2);
+  list L = bFactor(f);
+  minIntRoot2(L);
+}
+
+
+proc maxIntRoot (list L)
+"
+USAGE:    maxIntRoot(L);  L list
+ASSUME:   L is the output of bFactor.
+RETURN:   int, the maximal integer root in a list of roots
+SEE ALSO: minIntRoot2, bFactor
+EXAMPLE:  example maxIntRoot; shows examples
+"
+{
+  return(minMaxIntRoot(L,"max"));
+}
+example
+{
+  "EXAMPLE"; echo=2;
+  ring r = 0,x,dp;
+  poly f = x*(x+1)*(x-2)*(x-5/2)*(x+5/2);
+  list L = bFactor(f);
+  maxIntRoot(L);
+}
+
+
+proc dmodAction (def id, poly f, list #)
+"
+USAGE:    dmodAction(id,f[,v]);  id ideal or poly, f poly, v optional intvec
+ASSUME:   If v is not given, the basering is the n-th Weyl algebra W over a
+          field of characteristic 0 and for all 1<=i<=n the identity
+          var(i+n)*var(i)=var(i)*var(i+1)+1 holds, i.e. the sequence of
+          variables is given by x(1),...,x(n),D(1),...,D(n), where D(i) is the
+          differential operator belonging to x(i).
+          Otherwise, v is assumed to specify positions of variables, which form
+          a Weyl algebra as a subalgebra of the basering:
+          If size(v) equals 2*n, then bracket(var(v[i]),var(v[j])) must equal
+          1 if and only if j equals i+n, and 0 otherwise,  for all 1<=i,j<=n.
+@*        Further, assume that f does not contain any D(i).
+RETURN:   same type as id, the result of the natural D-module action of id on f
+NOTE:     The assumptions made are not checked.
+EXAMPLE:  example dmodAction; shows examples
+"
+{
+  string inp1 = typeof(id);
+  if ((inp1<>"poly") && (inp1<>"ideal"))
+  {
+    ERROR("Expected first argument to be poly or ideal but received "+inp1);
+  }
+  intvec posXD = 1..nvars(basering);
+  if (size(#)>0)
+  {
+    if (typeof(#[1])=="intvec")
+    {
+      posXD = #[1];
+    }
+  }
+  if ((size(posXD) mod 2)<>0)
+  {
+    ERROR("Even number of variables expected.")
+  }
+  int n = (size(posXD)) div 2;
+  int i,j,k,l;
+  ideal resI = id;
+  int sid = ncols(resI);
+  intvec v;
+  poly P,h;
+  for (l=1; l<=sid; l++)
+  {
+    P = resI[l];
+    resI[l] = 0;
+    for (i=1; i<=size(P); i++)
+    {
+      v = leadexp(P[i]);
+      h = f;
+      for (j=1; j<=n; j++)
+      {
+        for (k=1; k<=v[posXD[j+n]]; k++) // action of Dx
+        {
+          h = diff(h,var(posXD[j]));
+        }
+        h = h*var(posXD[j])^v[posXD[j]]; // action of x
+      }
+      h = leadcoef(P[i])*h;
+      resI[l] = resI[l] + h;
+    }
+  }
+  if (inp1 == "ideal")
+  {
+    return(resI);
+  }
+  else
+  {
+    return(resI[1]);
+  }
+}
+example
+{
+  ring r = 0,(x,y,z),dp;
+  poly f = x^2*z - y^3;
+  def A = annPoly(f);
+  setring A;
+  poly f = imap(r,f);
+  dmodAction(LD,f);
+  poly P = y*Dy+3*z*Dz-3;
+  dmodAction(P,f);
+  dmodAction(P[1],f);
+}
+
+
+static proc checkRatInput (vector I)
+{
+  // check for valid input
+  int wrginpt;
+  if (nrows(I)<>2)
+  {
+    wrginpt = 1;
+  }
+  else
+  {
+    if (I[2] == 0)
+    {
+      wrginpt = 1;
+    }
+  }
+  if (wrginpt)
+  {
+    ERROR("Vector must consist of exactly two components, second one not 0");
+  }
+  return();
+}
+
+
+proc dmodActionRat(def id, vector w)
+"
+USAGE:    dmodActionRat(id,w);  id ideal or poly, f vector
+ASSUME:   The basering is the n-th Weyl algebra W over a field of
+          characteristic 0 and for all 1<=i<=n the identity
+          var(i+n)*var(i)=var(i)*var(i+1)+1 holds, i.e. the sequence of
+          variables is given by x(1),...,x(n),D(1),...,D(n), where D(i) is the
+          differential operator belonging to x(i).
+@*        Further, assume that w has exactly two components, second one not 0,
+          and that w does not contain any D(i).
+RETURN:   same type as id, the result of the natural D-module action of id on
+          the rational function w[1]/w[2]
+EXAMPLE:  example dmodActionRat; shows examples
+"
+{
+  string inp1 = typeof(id);
+  if ( (inp1<>"poly") && (inp1<>"ideal") )
+  {
+    ERROR("Expected first argument to be poly or ideal but received " + inp1);
+  }
+  checkRatInput(w);
+  poly f = w[1];
+  finKx(f);
+  f = w[2];
+  finKx(f);
+  def save = basering;
+  def r = commRing();
+  setring r;
+  ideal I = imap(save,id);
+  vector w = imap(save,w);
+  int i,j,k,l;
+  int n = nvars(basering) div 2;
+  int sid = ncols(I);
+  intvec v;
+  poly P;
+  vector h,resT;
+  module resL;
+  for (l=1; l<=sid; l++)
+  {
+    P = I[l];
+    resT = [0,1];
+    for (i=1; i<=size(P); i++)
+    {
+      v = leadexp(P[i]);
+      h = w;
+      for (j=1; j<=n; j++)
+      {
+        for (k=1; k<=v[j+n]; k++) // action of Dx
+        {
+          h = diffRat(h,j);
+        }
+        h = h + h[1]*(var(j)^v[j]-1)*gen(1);  // action of x
+      }
+      h = h + (leadcoef(P[i])-1)*h[1]*gen(1);
+      resT = addRat(resT,h);
+    }
+    resL[l] = resT;
+  }
+  setring save;
+  module resL = imap(r,resL);
+  return(resL);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y),dp;
+  poly f = 2*x;  poly g = y;
+  def A = annRat(f,g); setring A;
+  poly f = imap(r,f); poly g = imap(r,g);
+  vector v = [f,g]; // represents f/g
+  // x and y act by multiplication
+  dmodActionRat(x,v);
+  dmodActionRat(y,v);
+  // Dx and Dy act by partial derivation
+  dmodActionRat(Dx,v);
+  dmodActionRat(Dy,v);
+  dmodActionRat(x*Dx+y*Dy,v);
+  setring r;
+  f = 2*x*y; g = x^2 - y^3;
+  def B = annRat(f,g); setring B;
+  poly f = imap(r,f); poly g = imap(r,g);
+  vector v = [f,g];
+  dmodActionRat(LD,v); // hence LD is indeed the annihilator of f/g
+}
+
+
+static proc arithmeticRat (vector I, vector J, string op, list #)
+{
+  // op = "+": return I+J
+  // op = "*": return I*J
+  // op = "s": return simplified I
+  // op = "d": return diff(I,var(#[1]))
+  int isComm = isCommutative();
+  if (!isComm)
+  {
+    def save = basering;
+    def r = commRing();
+    setring r;
+    ideal m = maxideal(1);
+    map f = save,m;
+    vector I = f(I);
+    vector J = f(J);
+  }
+  vector K;
+  poly p;
+  if (op == "s")
+  {
+    p = gcd(I[1],I[2]);
+    K = (I[1]/p)*gen(1) + (I[2]/p)*gen(2);
+  }
+  else
+  {
+    if (op == "+")
+    {
+      I = arithmeticRat(I,vector(0),"s");
+      J = arithmeticRat(J,vector(0),"s");
+      p = lcm(I[2],J[2]);
+      K = (I[1]*p/I[2] + J[1]*p/J[2])*gen(1) + p*gen(2);
+    }
+    else
+    {
+      if (op == "*")
+      {
+        K = (I[1]*J[1])*gen(1) + (I[2]*J[2])*gen(2);
+      }
+      else
+      {
+        if (op == "d")
+        {
+          int j = #[1];
+          K = (diff(I[1],var(j))*I[2] - I[1]*diff(I[2],var(j)))*gen(1)+ (I[2]^2)*gen(2);
+        }
+      }
+    }
+    K = arithmeticRat(K,vector(0),"s");
+  }
+  if (!isComm)
+  {
+    setring save;
+    vector K = imap(r,K);
+  }
+  return(K);
+}
+
+
+proc simplifyRat (vector J)
+"
+USAGE:    simplifyRat(v);  v vector
+ASSUME:   Assume that v has exactly two components, second one not 0.
+RETURN:   vector, representing simplified rational function v[1]/v[2]
+NOTE:     Possibly present non-commutative relations of the basering are
+          ignored.
+EXAMPLE:  example simplifyRat; shows examples
+"
+{
+  checkRatInput(J);
+  return(arithmeticRat(J,vector(0),"s"));
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+   ring r = 0,(x,y),dp;
+  vector v = [x2-1,x+1];
+  simplifyRat(v);
+  simplifyRat(v) - [x-1,1];
+}
+
+
+proc addRat (vector I, vector J)
+"
+USAGE:    addRat(v,w);  v,w vectors
+ASSUME:   Assume that v,w have exactly two components, second ones not 0.
+RETURN:   vector, representing rational function (v[1]/v[2])+(w[1]/w[2])
+NOTE:     Possibly present non-commutative relations of the basering are
+          ignored.
+EXAMPLE:  example addRat; shows examples
+"
+{
+  checkRatInput(I);
+  checkRatInput(J);
+  return(arithmeticRat(I,J,"+"));
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y),dp;
+  vector v = [x,y];
+  vector w = [y,x];
+  addRat(v,w);
+  addRat(v,w) - [x2+y2,xy];
+}
+
+
+proc multRat (vector I, vector J)
+"
+USAGE:    multRat(v,w);  v,w vectors
+ASSUME:   Assume that v,w have exactly two components, second ones not 0.
+RETURN:   vector, representing rational function (v[1]/v[2])*(w[1]/w[2])
+NOTE:     Possibly present non-commutative relations of the basering are
+          ignored.
+EXAMPLE:  example multRat; shows examples
+"
+{
+  checkRatInput(I);
+  checkRatInput(J);
+  return(arithmeticRat(I,J,"*"));
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y),dp;
+  vector v = [x,y];
+  vector w = [y,x];
+  multRat(v,w);
+  multRat(v,w) - [1,1];
+}
+
+
+proc diffRat (vector I, int j)
+"
+USAGE:    diffRat(v,j);  v vector, j int
+ASSUME:   Assume that v has exactly two components, second one not 0.
+RETURN:   vector, representing rational function derivative of rational
+          function (v[1]/v[2]) w.r.t. var(j)
+NOTE:     Possibly present non-commutative relations of the basering are
+          ignored.
+EXAMPLE:  example diffRat; shows examples
+"
+{
+  checkRatInput(I);
+  if ( (j<1) || (j>nvars(basering)) )
+  {
+    ERROR("Second argument must be in the range 1.."+string(nvars(basering)));
+  }
+  return(arithmeticRat(I,vector(0),"d",j));
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y),dp;
+  vector v = [x,y];
+  diffRat(v,1);
+  diffRat(v,1) - [1,y];
+  diffRat(v,2);
+  diffRat(v,2) - [-x,y2];
+}
+
+
+proc commRing ()
+"
+USAGE:    commRing();
+RETURN:   ring, basering without non-commutative relations
+EXAMPLE:  example commRing; shows examples
+"
+{
+  list RL = ringlist(basering);
+  if (size(RL)<=4)
+  {
+    return(basering);
+  }
+  RL = RL[1..4];
+  def r = ring(RL);
+  return(r);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  def W = makeWeyl(3);
+  setring W; W;
+  def W2 = commRing();
+  setring W2; W2;
+  ring r = 0,(x,y),dp;
+  def r2 = commRing(); // same as r
+  setring r2; r2;
+}
+
+
+// TODO remove this proc once chern.lib is ready
+static proc orderedPartition(int n, list #)
+"
+USUAGE:  orderedPartition(n,a); n,a positive ints
+         orderedPartition(n,w); n positive int, w positive intvec
+RETURN:  list of intvecs
+PURPOSE: Computes all partitions of n of length a, if the second
+         argument is an int, or computes all weighted partitions
+         w.r.t. w of n of length size(w) if the second argument
+         is an intvec.
+         In both cases, zero parts are included.
+EXAMPLE: example orderedPartition; shows an example
+"
+{
+  int a,wrongInpt,intInpt;
+  intvec w = 1;
+  if (size(#)>0)
+  {
+    if (typeof(#[1]) == "int")
+    {
+      a = #[1];
+      intInpt = 1;
+    }
+    else
+    {
+      if (typeof(#[1]) == "intvec")
+      {
+        w = #[1];
+        a = size(w);
+      }
+      else
+      {
+        wrongInpt = 1;
+      }
+    }
+  }
+  else
+  {
+    wrongInpt = 1;
+  }
+  if (wrongInpt)
+  {
+    ERROR("Expected second argument of type int or intvec.");
+  }
+  kill wrongInpt;
+  if (n==0 && a>0)
+  {
+    return(list(0:a));
+  }
+  if (n<=0 || a<=0 || allPositive(w)==0)
+  {
+    ERROR("Positive arguments expected.");
+  }
+  int baseringdef;
+  if (defined(basering)) // if a basering is defined, it should be saved for later use
+  {
+    def save = basering;
+    baseringdef = 1;
+  }
+  ring r = 0,(x(1..a)),dp; // all variables for partition of length a
+  ideal M;
+  if (intInpt)
+  {
+    M = maxideal(n);   // all monomials of total degree n
+  }
+  else
+  {
+    M = weightKB(ideal(0),n,w); // all monomials of total weighted degree n
+  }
+  list L;
+  int i;
+  for (i = 1; i <= ncols(M); i++) {L = insert(L,leadexp(M[i]));}
+  // the leadexp corresponds to a partition
+  if (baseringdef) // sets the old ring as basering again
+  {
+    setring save;
+  }
+  return(L); //returns the list of partitions
+}
+example
+{
+ "EXAMPLE"; echo = 2;
+ orderedPartition(4,2);
+ orderedPartition(5,3);
+ orderedPartition(2,4);
+ orderedPartition(8,intvec(2,3));
+ orderedPartition(7,intvec(2,2)); // no such partition
+}
+
+
+// applications of characteristic variety /////////////////////////////////////
+
+proc holonomicRank (ideal I, list #)
+"
+USAGE:    holonomicRank(I[,e]);   I ideal, e optional int
+ASSUME:   The basering is the n-th Weyl algebra over a field of
+          characteristic 0 and for all 1<=i<=n the identity
+          var(i+n)*var(i)=var(i)*var(i+1)+1 holds, i.e. the sequence of
+          variables is given by x(1),...,x(n),D(1),...,D(n), where D(i)
+          is the differential operator belonging to x(i).
+RETURN:   int, the holonomic rank of I
+REMARKS:  The holonomic rank of I is defined to be the K(x(1..n))-dimension of
+          the module W/WI, where W is the rational Weyl algebra
+          K(x(1..n))<D(1..n)>.
+          If this dimension is infinite, -1 is returned.
+NOTE:     If e<>0, @code{std} is used for Groebner basis computations,
+          otherwise (and by default) @code{slimgb} is used.
+@*        If printlevel=1, progress debug messages will be printed,
+          if printlevel>=2, all the debug messages will be printed.
+EXAMPLE:  example holonomicRank; shows examples
+"
+{
+  // assumption check is done by charVariety
+  int ppl = printlevel - voice + 2;
+  int eng;
+  if (size(#)>0)
+  {
+    if(typeof(#[1])=="int")
+    {
+      eng = #[1];
+    }
+  }
+  def save = basering;
+  dbprint(ppl  ,"// Computing characteristic variety...");
+  def grD = charVariety(I);
+  setring grD; // commutative ring
+  dbprint(ppl  ,"// ...done.");
+  dbprint(ppl-1,"// " + string(charVar));
+  int n = nvars(save) div 2;
+  intvec v = 1..n;
+  def R = vars2pars(v);
+  setring R;
+  ideal J = imap(grD,charVar);
+  dbprint(ppl  ,"// Starting GB computation...");
+  J = engine(J,0); // use slimgb
+  dbprint(ppl  ,"// ...done.");
+  dbprint(ppl-1,"// " + string(J));
+  int d = vdim(J);
+  setring save;
+  return(d);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  // (OTW), Example 8
+  ring r3 = 0,(x,y,z,Dx,Dy,Dz),dp;
+  def D3 = Weyl();
+  setring D3;
+  poly f = x^3-y^2*z^2;
+  ideal I = f^2*Dx+3*x^2, f^2*Dy-2*y*z^2, f^2*Dz-2*y^2*z;
+  // I annihilates exp(1/f)
+  holonomicRank(I);
+}
+
+
+proc DsingularLocus (ideal I)
+"
+USAGE:    DsingularLocus(I);  I ideal
+ASSUME:   The basering is the n-th Weyl algebra over a field of
+          characteristic 0 and for all 1<=i<=n the identity
+          var(i+n)*var(i)=var(i)*var(i+1)+1 holds, i.e. the sequence of
+          variables is given by x(1),...,x(n),D(1),...,D(n), where D(i)
+          is the differential operator belonging to x(i).
+RETURN:   ideal, describing the singular locus of the D-module D/I
+NOTE:     If printlevel>=1, progress debug messages will be printed,
+          if printlevel>=2, all the debug messages will be printed
+EXAMPLE:  example DsingularLocus; shows examples
+"
+{
+  // assumption check is done by charVariety
+  int ppl = printlevel - voice + 2;
+  def save = basering;
+  dbprint(ppl  ,"// Computing characteristic variety...");
+  def grD = charVariety(I);
+  setring grD;
+  dbprint(ppl  ,"// ...done");
+  dbprint(ppl-1,"// " + string(charVar));
+  poly pDD = 1;
+  ideal IDD;
+  int i;
+  int n = nvars(basering) div 2;
+  for (i=1; i<=n; i++)
+  {
+    pDD = pDD*var(i+n);
+    IDD[i] = var(i+n);
+  }
+  dbprint(ppl  ,"// Computing saturation...");
+  ideal S = sat(charVar,IDD)[1];
+  dbprint(ppl  ,"// ...done");
+  dbprint(ppl-1,"// " + string(S));
+  dbprint(ppl  ,"// Computing elimination...");
+  S = eliminate(S,pDD);
+  dbprint(ppl  ,"// ...done");
+  dbprint(ppl-1,"// " + string(S));
+  dbprint(ppl  ,"// Computing radical...");
+  S = radical(S);
+  dbprint(ppl  ,"// ...done");
+  dbprint(ppl-1,"// " + string(S));
+  setring save;
+  ideal S = imap(grD,S);
+  return(S);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  // (OTW), Example 8
+  ring @D3 = 0,(x,y,z,Dx,Dy,Dz),dp;
+  def D3 = Weyl();
+  setring D3;
+  poly f = x^3-y^2*z^2;
+  ideal I = f^2*Dx + 3*x^2, f^2*Dy-2*y*z^2, f^2*Dz-2*y^2*z;
+  // I annihilates exp(1/f)
+  DsingularLocus(I);
+}
+
+
+// localization ///////////////////////////////////////////////////////////////
+
+static proc finKx(poly f)
+{
+  int n = nvars(basering) div 2;
+  intvec iv = 1..n;
+  if (polyVars(f,iv) == 0)
+  {
+    ERROR("Given poly may not contain differential operators.");
+  }
+  return();
+}
+
+
+proc rightNFWeyl (def id, int k)
+"
+USAGE:    rightNFWeyl(id,k);  id ideal or poly, k int
+ASSUME:   The basering is the n-th Weyl algebra over a field of
+          characteristic 0 and for all 1<=i<=n the identity
+          var(i+n)*var(i)=var(i)*var(i+1)+1 holds, i.e. the sequence of
+          variables is given by x(1),...,x(n),D(1),...,D(n), where D(i)
+          is the differential operator belonging to x(i).
+RETURN:   same type as id, the right normal form of id with respect to the
+          principal right ideal generated by the k-th variable
+NOTE:     No Groebner basis computation is used.
+EXAMPLE:  example rightNFWeyl; shows examples.
+"
+{
+  dmodGeneralAssumptionCheck();
+  string inpt = typeof(id);
+  if (inpt=="ideal" || inpt=="poly")
+  {
+    ideal I = id;
+  }
+  else
+  {
+    ERROR("Expected first input to be of type ideal or poly.");
+  }
+  def save = basering;
+  int n = nvars(save) div 2;
+  if (0>k || k>2*n)
+  {
+    ERROR("Expected second input to be in the range 1.."+string(2*n)+".");
+  }
+  int i,j;
+  if (k>n) // var(k) = Dx(k-n)
+  {
+    // switch var(k),var(k-n)
+    list RL = ringlist(save);
+    matrix rel = RL[6];
+    rel[k-n,k] = -1;
+    RL = RL[1..4];
+    list L = RL[2];
+    string str = L[k-n];
+    L[k-n] = L[k];
+    L[k] = str;
+    RL[2] = L;
+    def @W = ring(RL);
+    kill L,RL,str;
+    ideal @mm = maxideal(1);
+    setring @W;
+    matrix rel = imap(save,rel);
+    def W = nc_algebra(1,rel);
+    setring W;
+    ideal @mm = imap(save, at mm);
+    map mm = save, at mm;
+    ideal I = mm(I);
+    i = k-n;
+  }
+  else  // var(k) = x(k)
+  {
+    def W = save;
+    i = k;
+  }
+  for (j=1; j<=ncols(I); j++)
+  {
+    I[j] = subst(I[j],var(i),0);
+  }
+  setring save;
+  I = imap(W,I);
+  if (inpt=="poly")
+  {
+    return(I[1]);
+  }
+  else
+  {
+    return(I);
+  }
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y,Dx,Dy),dp;
+  def W = Weyl();
+  setring W;
+  ideal I = x^3*Dx^3, y^2*Dy^2, x*Dy, y*Dx;
+  rightNFWeyl(I,1); // right NF wrt principal right ideal x*W
+  rightNFWeyl(I,3); // right NF wrt principal right ideal Dx*W
+  rightNFWeyl(I,2); // right NF wrt principal right ideal y*W
+  rightNFWeyl(I,4); // right NF wrt principal right ideal Dy*W
+  poly p = x*Dx+1;
+  rightNFWeyl(p,1); // right NF wrt principal right ideal x*W
+}
+
+
+// TODO check OTW for assumptions on holonomicity
+proc Dlocalization (ideal J, poly f, list #)
+"
+USAGE:    Dlocalization(I,f[,k,e]);  I ideal, f poly, k,e optional ints
+ASSUME:   The basering is the n-th Weyl algebra over a field of
+          characteristic 0 and for all 1<=i<=n the identity
+          var(i+n)*var(i)=var(i)*var(i+1)+1 holds, i.e. the sequence of
+          variables is given by x(1),...,x(n),D(1),...,D(n), where D(i)
+          is the differential operator belonging to x(i).
+@*        Further, assume that f does not contain any D(i) and that I is
+          holonomic on K^n\V(f).
+RETURN:   ideal or list, computes an ideal J such that D/J is isomorphic
+          to D/I localized at f as D-modules.
+          If k<>0, a list consisting of J and an integer m is returned,
+          such that f^m represents the natural map from D/I to D/J.
+          Otherwise (and by default), only the ideal J is returned.
+REMARKS:  It is known that a localization at f of a holonomic D-module is
+          again a holonomic D-module.
+@*        Reference: (OTW)
+NOTE:     If e<>0, @code{std} is used for Groebner basis computations,
+          otherwise (and by default) @code{slimgb} is used.
+@*        If printlevel=1, progress debug messages will be printed,
+          if printlevel>=2, all the debug messages will be printed.
+SEE ALSO: DLoc, SDLoc, DLoc0
+EXAMPLE: example Dlocalization; shows examples
+"
+{
+  dmodGeneralAssumptionCheck();
+  finKx(f);
+  int ppl = printlevel - voice + 2;
+  int outList,eng;
+  if (size(#)>0)
+  {
+    if (typeof(#[1])=="int" || typeof(#[1])=="number")
+    {
+      outList = int(#[1]);
+    }
+    if (size(#)>1)
+    {
+      if (typeof(#[2])=="int" || typeof(#[2])=="number")
+      {
+        eng = int(#[2]);
+      }
+    }
+  }
+  int i,j;
+  def save = basering;
+  int n = nvars(save) div 2;
+  def Dv = extendWeyl(safeVarName("v"));
+  setring Dv;
+  poly f = imap(save,f);
+  ideal phiI;
+  for (i=n; i>0; i--)
+  {
+    phiI[i+n] = var(i+n+2)-var(1)^2*bracket(var(i+n+2),f)*var(n+2);
+    phiI[i]   = var(i+1);
+  }
+  map phi = save,phiI;
+  ideal J = phi(J);
+  J = J, 1-f*var(1);
+  // TODO original J has to be holonomic only on K^n\V(f), not on all of K^n
+  // does is suffice to show that new J is holonomic on Dv??
+  if (isHolonomic(J) == 0)
+  {
+    ERROR("Module is not holonomic.");
+  }
+  intvec w = 1; w[n+1]=0;
+  ideal G = GBWeight(J,w,-w,eng);
+  dbprint(ppl  ,"// found GB wrt weight " +string(-w));
+  dbprint(ppl-1,"// " + string(G));
+  intvec ww = w,-w;
+  ideal inG = inForm(G,ww);
+  inG = engine(inG,eng);
+  poly s = var(1)*var(n+2); // s=v*Dv
+  vector intersecvec = pIntersect(s,inG);
+  s = vec2poly(intersecvec);
+  s = subst(s,var(1),-var(1)-1);
+  list L = bFactor(s);
+  dbprint(ppl  ,"// found b-function");
+  dbprint(ppl-1,"// roots: "+string(L[1]));
+  dbprint(ppl-1,"// multiplicities: "+string(L[2]));
+  kill inG,intersecvec,s;
+  // TODO: use maxIntRoot
+  L = intRoots(L);           // integral roots of b-function
+  if (L[2]==0:size(L[2]))    // no integral roots
+  {
+    setring save;
+    return(ideal(1));
+  }
+  intvec iv;
+  for (i=1; i<=ncols(L[1]); i++)
+  {
+    iv[i] = int(L[1][i]);
+  }
+  int l0 = Max(iv);
+  dbprint(ppl,"// maximal integral root is " +string(l0));
+  kill L,iv;
+  intvec degG;
+  ideal Gk;
+  for (j=1; j<=ncols(G); j++)
+  {
+    degG[j] = deg(G[j],ww);
+    for (i=0; i<=l0-degG[j]; i++)
+    {
+      Gk[ncols(Gk)+1] = var(1)^i*G[j];
+    }
+  }
+  Gk = rightNFWeyl(Gk,n+2);
+  dbprint(ppl,"// found right normalforms");
+  module M = coeffs(Gk,var(1));
+  setring save;
+  def mer = makeModElimRing(save);
+  setring mer;
+  module M = imap(Dv,M);
+  kill Dv;
+  M = engine(M,eng);
+  dbprint(ppl  ,"// found GB of free module of rank " + string(l0+1));
+  dbprint(ppl-1,"// " + string(M));
+  M = prune(M);
+  setring save;
+  matrix M = imap(mer,M);
+  kill mer;
+  int ro = nrows(M);
+  int co = ncols(M);
+  ideal I;
+  if (ro == 1) // nothing to do
+  {
+    I = M;
+  }
+  else
+  {
+    matrix zm[ro-1][1]; // zero matrix
+    matrix v[ro-1][1];
+    for (i=1; i<=co; i++)
+    {
+      v = M[1..ro-1,i];
+      if (v == zm)
+      {
+        I[size(I)+1] = M[ro,i];
+      }
+    }
+  }
+  if (outList<>0)
+  {
+    return(list(I,l0+2));
+  }
+  else
+  {
+    return(I);
+  }
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  // (OTW), Example 8
+  ring r = 0,(x,y,z,Dx,Dy,Dz),dp;
+  def W = Weyl();
+  setring W;
+  poly f = x^3-y^2*z^2;
+  ideal I = f^2*Dx+3*x^2, f^2*Dy-2*y*z^2, f^2*Dz-2*y^2*z;
+  // I annihilates exp(1/f)
+  ideal J = Dlocalization(I,f);
+  J;
+  Dlocalization(I,f,1); // The natural map D/I -> D/J is given by 1/f^2
+}
+
+
+
+// Weyl closure ///////////////////////////////////////////////////////////////
+
+static proc orderFiltrationD1 (poly f)
+{
+  // returns list of ideal and intvec
+  // ideal contains x-parts, intvec corresponding degree in Dx
+  poly g,h;
+  g = f;
+  ideal I;
+  intvec v,w,u;
+  w = 0,1;
+  int i,j;
+  i = 1;
+  while (g<>0)
+  {
+    h = inForm(g,w);
+    I[i] = 0;
+    for (j=1; j<=size(h); j++)
+    {
+      v = leadexp(h[j]);
+      u[i] = v[2];
+      v[2] = 0;
+      I[i] = I[i] + leadcoef(h[j])*monomial(v);
+    }
+    g = g-h;
+    i++;
+  }
+  return(list(I,u));
+}
+
+
+static proc kerLinMapD1 (ideal W, poly L, poly p)
+{
+  // computes kernel of right multiplication with L viewed
+  // as homomorphism of K-vector spaces span(W) -> D1/p*D1
+  // assume p in K[x], basering is K<x,Dx>
+  ideal G,K;
+  G = std(p);
+  list l;
+  int i,j;
+  // first, compute the image of span(W)
+  if (simplify(W,2)[1] == 0)
+  {
+    return(K); // = 0
+  }
+  for (i=1; i<=size(W); i++)
+  {
+    l = orderFiltrationD1(W[i]*L);
+    K[i] = 0;
+    for (j=1; j<=size(l[1]); j++)
+    {
+      K[i] = K[i] + NF(l[1][j],G)*var(2)^(l[2][j]);
+    }
+  }
+  // now, we get the kernel by linear algebra
+  l = linReduceIdeal(K,1);
+  i = ncols(l[1]) - size(l[1]);
+  if (i<>0)
+  {
+    K = module(W)*l[2];
+    K = K[1..i];
+  }
+  else
+  {
+    K = 0;
+  }
+  return(K);
+}
+
+
+static proc leftDivisionKxD1 (poly p, poly L)
+{
+  // basering is D1 = K<x,Dx>
+  // p in K[x]
+  // compute p^(-1)*L if p is a left divisor of L
+//   if (rightNF(L,ideal(p))<>0)
+//   {
+//     ERROR("First poly is not a right factor of second poly");
+//   }
+  def save = basering;
+  list l = orderFiltrationD1(L);
+  ideal l1 = l[1];
+  ring r = 0,x,dp;
+  ideal l1 = fetch(save,l1);
+  poly p = fetch(save,p);
+  int i;
+  for (i=1; i<=ncols(l1); i++)
+  {
+    l1[i] =  division(l1[i],p)[1][1,1];
+  }
+  setring save;
+  ideal I = fetch(r,l1);
+  poly f;
+  for (i=1; i<=ncols(I); i++)
+  {
+    f = f + I[i]*var(2)^(l[2][i]);
+  }
+  return(f);
+}
+
+
+proc WeylClosure1 (poly L)
+"
+USAGE:    WeylClosure1(L);  L a poly
+ASSUME:   The basering is the first Weyl algebra D=K<x,d|dx=xd+1> over a field
+          K of characteristic 0.
+RETURN:   ideal, the Weyl closure of the principal left ideal generated by L
+REMARKS:  The Weyl closure of a left ideal I in the Weyl algebra D is defined
+          to be the intersection of I regarded as left ideal in the rational
+          Weyl algebra K(x)<d> with the polynomial Weyl algebra D.
+@*        Reference: (Tsa), Algorithm 1.2.4
+NOTE:     If printlevel=1, progress debug messages will be printed,
+          if printlevel>=2, all the debug messages will be printed.
+SEE ALSO: WeylClosure
+EXAMPLE:  example WeylClosure1; shows examples
+"
+{
+  dmodGeneralAssumptionCheck(); // assumption check
+  int ppl = printlevel - voice + 2;
+  def save = basering;
+  intvec w = 0,1; // for order filtration
+  poly p = inForm(L,w);
+  ring @R = 0,var(1),dp;
+  ideal mm = var(1),1;
+  map m = save,mm;
+  ideal @p = m(p);
+  poly p = @p[1];
+  poly g = gcd(p,diff(p,var(1)));
+  if (g == 1)
+  {
+    g = p;
+  }
+  ideal facp = factorize(g,1); // g is squarefree, constants aren't interesting
+  dbprint(ppl-1,
+          "// squarefree part of highest coefficient w.r.t. order filtration:");
+  dbprint(ppl-1, "// " + string(facp));
+  setring save;
+  p = imap(@R,p);
+  // 1-1 extend basering by parameter and introduce new var t=x*d
+  list RL = ringlist(save);
+  RL = RL[1..4];
+  list l;
+  l[1] = int(0);
+  l[2] = list(safeVarName("a"));
+  l[3] = list(list("lp",intvec(1)));
+  l[4] = ideal(0);
+  RL[1] = l;
+  l = RL[2] + list(safeVarName("t"));
+  RL[2] = l;
+  l = list();
+  l[1] = list("dp",intvec(1,1));
+  l[2] = list("dp",intvec(1));
+  l[3] = list("C",intvec(0));
+  RL[3] = l;
+  def @Wat = ring(RL);
+  kill RL,l;
+  setring @Wat;
+  matrix relD[3][3];
+  relD[1,2] = 1;
+  relD[1,3] = var(1);
+  relD[2,3] = -var(2);
+  def Wat = nc_algebra(1,relD);
+  setring Wat;
+  kill @Wat;
+  // 1-2 rewrite L using Euler operators
+  ideal mm = var(1)+par(1),var(2);
+  map m = save,mm;
+  poly L = m(L);
+  w = -1,1,0; // for Bernstein filtration
+  int i = 1;
+  ideal Q;
+  poly p = L;
+  intvec d;
+  while (p<>0)
+  {
+    Q[i] = inForm(p,w);
+    p = p - Q[i];
+    d[i] = -deg(Q[i],w);
+    i++;
+  }
+  ideal S = std(var(1)*var(2)-var(3));
+  Q = NF(Q,S);
+  dbprint(ppl,  "// found Euler representation of operator");
+  dbprint(ppl-1,"// " + string(Q));
+  Q = subst(Q,var(1),1);
+  Q = subst(Q,var(2),1);
+  // 1-3 prepare for algebraic extensions with minpoly = facp[i]
+  list RL = ringlist(Wat);
+  RL = RL[1..4];
+  list l;
+  l = string(var(3));
+  RL[2] = l;
+  l = list();
+  l[1] = list("dp",intvec(1));
+  l[2] = list("C",intvec(0));
+  RL[3] = l;
+  mm = par(1);
+  m = @R,par(1);
+  ideal facp = m(facp);
+  kill @R,m,mm,l,S;
+  intvec maxroots,testroots;
+  int sq = size(Q);
+  string strQ = "ideal Q = " + string(Q) + ";";
+  // TODO do it without string workaround when issue with maps from
+  //   transcendental to algebraic extension fields is fixed
+  int j,maxr;
+  // 2-1 get max int root of lowest nonzero entry of Q in algebraic extension
+  for (i=1; i<=size(facp); i++)
+  {
+    testroots = 0;
+    def Ra = ring(RL);
+    setring Ra;
+    ideal mm = 1,1,var(1);
+    map m = Wat,mm;
+    ideal facp = m(facp);
+    minpoly = leadcoef(facp[i]);
+    execute(strQ);
+    if (simplify(Q,2)[1] == poly(0))
+    {
+      break;
+    }
+    j = 1;
+    while (j<sq)
+    {
+      if (Q[j]==0)
+      {
+        j++;
+      }
+      else
+      {
+        break;
+      }
+    }
+    maxroots[i] = d[j]; // d[j] = r_k
+    list LR = bFactor(Q[j]);
+    LR = intRoots(LR);
+    if (LR[2]<>0:size(LR[2])) // there are integral roots
+    {
+      for (j=1; j<=ncols(LR[1]); j++)
+      {
+        testroots[j] = int(LR[1][j]);
+      }
+      maxr = Max(testroots);
+      if(maxr<0)
+      {
+        maxr = 0;
+      }
+      maxroots[i] = maxroots[i] + maxr;
+    }
+    kill LR;
+    setring Wat;
+    kill Ra;
+  }
+  maxr = Max(maxroots);
+  // 3-1 build basis of vectorspace
+  setring save;
+  ideal KB;
+  for (i=0; i<deg(p); i++)  // it's really <, not <=
+  {
+    for (j=0; j<=maxr; j++) // it's really <=, not <
+    {
+      KB[size(KB)+1] = monomial(intvec(i,j));
+    }
+  }
+  dbprint(ppl,"// got vector space basis");
+  dbprint(ppl-1, "// " + string(KB));
+  // 3-2 get kernel of *L: span(KB)->D/pD
+  KB = kerLinMapD1(KB,L,p);
+  dbprint(ppl,"// got kernel");
+  dbprint(ppl-1, "// " + string(KB));
+  // 4-1 get (1/p)*f*L where f in KB
+  for (i=1; i<=ncols(KB); i++)
+  {
+    KB[i] = leftDivisionKxD1(p,KB[i]*L);
+  }
+  KB = L,KB;
+  // 4-2 done
+  return(KB);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,Dx),dp;
+  def W = Weyl();
+  setring W;
+  poly L = (x^3+2)*Dx-3*x^2;
+  WeylClosure1(L);
+  L = (x^4-4*x^3+3*x^2)*Dx^2+(-6*x^3+20*x^2-12*x)*Dx+(12*x^2-32*x+12);
+  WeylClosure1(L);
+}
+
+
+proc WeylClosure (ideal I)
+"
+USAGE:    WeylClosure(I);  I an ideal
+ASSUME:   The basering is the n-th Weyl algebra W over a field of
+          characteristic 0 and for all 1<=i<=n the identity
+          var(i+n)*var(i)=var(i)*var(i+1)+1 holds, i.e. the sequence of
+          variables is given by x(1),...,x(n),D(1),...,D(n), where D(i) is the
+          differential operator belonging to x(i).
+@*        Moreover, assume that the holonomic rank of W/I is finite.
+RETURN:   ideal, the Weyl closure of I
+REMARKS:  The Weyl closure of a left ideal I in the Weyl algebra W is defined to
+          be the intersection of I regarded as left ideal in the rational Weyl
+          algebra K(x(1..n))<D(1..n)> with the polynomial Weyl algebra W.
+@*        Reference: (Tsa), Algorithm 2.2.4
+NOTE:     If printlevel=1, progress debug messages will be printed,
+          if printlevel>=2, all the debug messages will be printed.
+SEE ALSO: WeylClosure1
+EXAMPLE:  example WeylClosure; shows examples
+"
+{
+  // assumption check
+  dmodGeneralAssumptionCheck();
+  if (holonomicRank(I)==-1)
+  {
+    ERROR("Input is not of finite holonomic rank.");
+  }
+  int ppl = printlevel - voice + 2;
+  int eng = 0; // engine
+  def save = basering;
+  dbprint(ppl  ,"// Starting to compute singular locus...");
+  ideal sl = DsingularLocus(I);
+  sl = simplify(sl,2);
+  dbprint(ppl  ,"// ...done.");
+  dbprint(ppl-1,"// " + string(sl));
+  if (sl[1] == 0) // can never get here
+  {
+    ERROR("Can't find polynomial in K[x] vanishing on singular locus.");
+  }
+  poly f = sl[1];
+  dbprint(ppl  ,"// Found poly vanishing on singular locus: " + string(f));
+  dbprint(ppl  ,"// Starting to compute localization...");
+  list L = Dlocalization(I,f,1);
+  ideal G = L[1];
+  dbprint(ppl  ,"// ...done.");
+  dbprint(ppl-1,"// " + string(G));
+  dbprint(ppl  ,"// Starting to compute kernel of localization map...");
+  if (eng == 0)
+  {
+    G = moduloSlim(f^L[2],G);
+  }
+  else
+  {
+    G = modulo(f^L[2],G);
+  }
+  dbprint(ppl  ,"// ...done.");
+  return(G);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  // (OTW), Example 8
+  ring r = 0,(x,y,z,Dx,Dy,Dz),dp;
+  def D3 = Weyl();
+  setring D3;
+  poly f = x^3-y^2*z^2;
+  ideal I = f^2*Dx + 3*x^2, f^2*Dy-2*y*z^2, f^2*Dz-2*y^2*z;
+  // I annihilates exp(1/f)
+  WeylClosure(I);
+}
+
+
+
+// solutions to systems of PDEs ///////////////////////////////////////////////
+
+proc polSol (ideal I, list #)
+"
+USAGE:    polSol(I[,w,m]);  I ideal, w optional intvec, m optional int
+ASSUME:   The basering is the n-th Weyl algebra W over a field of
+          characteristic 0 and for all 1<=i<=n the identity
+          var(i+n)*var(i)=var(i)*var(i+1)+1 holds, i.e. the sequence of
+          variables is given by x(1),...,x(n),D(1),...,D(n), where D(i) is the
+          differential operator belonging to x(i).
+@*        Moreover, assume that I is holonomic.
+RETURN:   ideal, a basis of the polynomial solutions to the given system of
+          linear PDEs with polynomial coefficients, encoded via I
+REMARKS:  If w is given, w should consist of n strictly negative entries.
+          Otherwise and by default, w is set to -1:n.
+          In this case, w is used as weight vector for the computation of a
+          b-function.
+@*        If m is given, m is assumed to be the minimal integer root of the
+          b-function of I w.r.t. w. Note that this assumption is not checked.
+@*        Reference: (OTT), Algorithm 2.4
+NOTE:     If printlevel=1, progress debug messages will be printed,
+          if printlevel>=2, all the debug messages will be printed.
+SEE ALSO: polSolFiniteRank, ratSol
+EXAMPLE:  example polSol; shows examples
+"
+{
+  dmodGeneralAssumptionCheck();
+  int ppl = printlevel - voice + 2;
+  int mr,mrgiven;
+  def save = basering;
+  int n = nvars(save);
+  intvec w = -1:(n div 2);
+  if (size(#)>0)
+  {
+    if (typeof(#[1])=="intvec")
+    {
+      if (allPositive(-#[1]))
+      {
+        w = #[1];
+      }
+    }
+    if (size(#)>1)
+    {
+      if (typeof(#[2])=="int")
+      {
+        mr = #[2];
+        mrgiven = 1;
+      }
+    }
+  }
+  // Step 1: the b-function
+  list L;
+  if (!mrgiven)
+  {
+    if (!isHolonomic(I))
+    {
+      ERROR("Ideal is not holonomic. Try polSolFiniteRank.");
+    }
+    dbprint(ppl,"// Computing b-function...");
+    L = bfctIdeal(I,w);
+    dbprint(ppl,"// ...done.");
+    dbprint(ppl-1,"//   Roots: " + string(L[1]));
+    dbprint(ppl-1,"//   Multiplicities: " + string(L[2]));
+    mr = minIntRoot2(L);
+    dbprint(ppl,"// Minimal integer root is " + string(mr) + ".");
+  }
+  if (mr>0)
+  {
+    return(ideal(0));
+  }
+  // Step 2: get the form of a solution f
+  int i;
+  L = list();
+  for (i=0; i<=-mr; i++)
+  {
+    L = L + orderedPartition(i,-w);
+  }
+  ideal mons;
+  for (i=1; i<=size(L); i++)
+  {
+    mons[i] = monomial(L[i]);
+  }
+  kill L;
+  mons = simplify(mons,2+4); // L might contain lots of 0s by construction
+  ring @C = (0, at c(1..size(mons))),dummyvar,dp;
+  def WC = save + @C;
+  setring WC;
+  ideal mons = imap(save,mons);
+  poly f;
+  for (i=1; i<=size(mons); i++)
+  {
+    f = f + par(i)*mons[i];
+  }
+  // Step 3: determine values of @c(i) by equating coefficients
+  ideal I = imap(save,I);
+  I = dmodAction(I,f,1..n);
+  ideal M = monomialInIdeal(I);
+  matrix CC = coeffs(I,M);
+  int j;
+  ideal C;
+  for (i=1; i<=nrows(CC); i++)
+  {
+    f = 0;
+    for (j=1; j<=ncols(CC); j++)
+    {
+      f = f + CC[i,j];
+    }
+    C[size(C)+1] = f;
+  }
+  // Step 3.1: solve a linear system
+  ring rC = 0,(@c(1..size(mons))),dp;
+  ideal C = imap(WC,C);
+  matrix M = coeffs(C,maxideal(1));
+  module MM = leftKernel(M);
+  setring WC;
+  module MM = imap(rC,MM);
+  // Step 3.2: return the solution
+  ideal F = ideal(MM*transpose(mons));
+  setring save;
+  ideal F = imap(WC,F);
+  return(F);
+}
+example
+{
+  "EXAMPLE:"; echo=2;
+  ring r = 0,(x,y,Dx,Dy),dp;
+  def W = Weyl();
+  setring W;
+  poly tx,ty = x*Dx, y*Dy;
+  ideal I =      // Appel F1 with parameters (2,-3,-2,5)
+    tx*(tx+ty+4)-x*(tx+ty+2)*(tx-3),
+    ty*(tx+ty+4)-y*(tx+ty+2)*(ty-2),
+    (x-y)*Dx*Dy+2*Dx-3*Dy;
+  intvec w = -1,-1;
+  polSol(I,w);
+}
+
+
+static proc ex_polSol()
+{  ring r = 0,(x,y,Dx,Dy),dp;
+  def W = Weyl();
+  setring W;
+  poly tx,ty = x*Dx, y*Dy;
+  ideal I =      // Appel F1 with parameters (2,-3,-2,5)
+    tx*(tx+ty+4)-x*(tx+ty+2)*(tx-3),
+    ty*(tx+ty+4)-y*(tx+ty+2)*(ty-2),
+    (x-y)*Dx*Dy+2*Dx-3*Dy;
+  intvec w = -5,-7;
+  // the following gives a bug
+  polSol(I,w);
+  // this is due to a bug in weightKB, see ticket #339
+  // http://www.singular.uni-kl.de:8002/trac/ticket/339
+}
+
+
+proc polSolFiniteRank (ideal I, list #)
+"
+USAGE:    polSolFiniteRank(I[,w]);  I ideal, w optional intvec
+ASSUME:   The basering is the n-th Weyl algebra W over a field of
+          characteristic 0 and for all 1<=i<=n the identity
+          var(i+n)*var(i)=var(i)*var(i+1)+1 holds, i.e. the sequence of
+          variables is given by x(1),...,x(n),D(1),...,D(n), where D(i) is the
+          differential operator belonging to x(i).
+@*        Moreover, assume that I is of finite holonomic rank.
+RETURN:   ideal, a basis of the polynomial solutions to the given system of
+          linear PDEs with polynomial coefficients, encoded via I
+REMARKS:  If w is given, w should consist of n strictly negative entries.
+          Otherwise and by default, w is set to -1:n.
+          In this case, w is used as weight vector for the computation of a
+          b-function.
+@*        Reference: (OTT), Algorithm 2.6
+NOTE:     If printlevel=1, progress debug messages will be printed,
+          if printlevel>=2, all the debug messages will be printed.
+SEE ALSO: polSol, ratSol
+EXAMPLE:  example polSolFiniteRank; shows examples
+"
+{
+  dmodGeneralAssumptionCheck();
+  if (holonomicRank(I)==-1)
+  {
+    ERROR("Ideal is not of finite holonomic rank.");
+  }
+  int ppl = printlevel - voice + 2;
+  int n = nvars(basering) div 2;
+  int eng;
+  intvec w = -1:(n div 2);
+  if (size(#)>0)
+  {
+    if (typeof(#[1])=="intvec")
+    {
+      if (allPositive(-#[1]))
+      {
+        w = #[1];
+      }
+    }
+  }
+  dbprint(ppl,"// Computing initial ideal...");
+  ideal J = initialIdealW(I,-w,w);
+  dbprint(ppl,"// ...done.");
+  dbprint(ppl,"// Computing Weyl closure...");
+  J = WeylClosure(J);
+  J = engine(J,eng);
+  dbprint(ppl,"// ...done.");
+  poly s;
+  int i;
+  for (i=1; i<=n; i++)
+  {
+    s = s + w[i]*var(i)*var(i+n);
+  }
+  dbprint(ppl,"// Computing intersection...");
+  vector v = pIntersect(s,J);
+  list L = bFactor(vec2poly(v));
+  dbprint(ppl-1,"//   roots: " + string(L[1]));
+  dbprint(ppl-1,"//   multiplicities: " + string(L[2]));
+  dbprint(ppl,"// ...done.");
+  int mr =  minIntRoot2(L);
+  int pl = printlevel;
+  printlevel = printlevel + 1;
+  ideal K = polSol(I,w,mr);
+  printlevel = printlevel - 1;
+  return(K);
+}
+example
+{
+  "EXAMPLE:"; echo=2;
+  ring r = 0,(x,y,Dx,Dy),dp;
+  def W = Weyl();
+  setring W;
+  poly tx,ty = x*Dx, y*Dy;
+  ideal I =      // Appel F1 with parameters (2,-3,-2,5)
+    tx*(tx+ty+4)-x*(tx+ty+2)*(tx-3),
+    ty*(tx+ty+4)-y*(tx+ty+2)*(ty-2),
+    (x-y)*Dx*Dy+2*Dx-3*Dy;
+  intvec w = -1,-1;
+  polSolFiniteRank(I,w);
+}
+
+
+static proc twistedIdeal(ideal I, poly f, intvec k, ideal F)
+{
+  // I subset D_n, f in K[x], F = factorize(f,1), size(k) = size(F), k[i]>0
+  def save = basering;
+  int n = nvars(save) div 2;
+  int i,j;
+  intvec a,v,w;
+  w = (0:n),(1:n);
+  for (i=1; i<=size(I); i++)
+  {
+    a[i] = deg(I[i],w);
+  }
+  ring FD = 0,(fd(1..n)),dp;
+  def @@WFD = save + FD;
+  setring @@WFD;
+  poly f = imap(save,f);
+  list RL = ringlist(basering);
+  RL = RL[1..4];
+  list L = RL[3];
+  v = (1:(2*n)),((deg(f)+1):n);
+  L = insert(L,list("a",v));
+  RL[3] = L;
+  def @WFD = ring(RL);
+  setring @WFD;
+  poly f = imap(save,f);
+  matrix Drel[3*n][3*n];
+  for (i=1; i<=n; i++)
+  {
+    Drel[i,i+n] = 1;     // [D,x]
+    Drel[i,i+2*n] = f;   // [fD,x]
+    for (j=1; j<=n; j++)
+    {
+      Drel[i+n,j+2*n] = -diff(f,var(i))*var(j+n);  // [fD,D]
+      Drel[j+2*n,i+2*n] = diff(f,var(i))*var(j+2*n) - diff(f,var(j))*var(i+2*n);
+      // [fD,fD]
+    }
+  }
+  def WFD = nc_algebra(1,Drel);
+  setring WFD;
+  kill @WFD,@@WFD;
+  ideal I = imap(save,I);
+  poly f = imap(save,f);
+  for (i=1; i<=size(I); i++)
+  {
+    I[i] = f^(a[i])*I[i];
+  }
+  ideal S;
+  for (i=1; i<=n; i++)
+  {
+    S[size(S)+1] = var(i+2*n) - f*var(i+n);
+  }
+  S = slimgb(S);
+  I = NF(I,S);
+  if (select1(I,intvec((n+1)..2*n))[1] <> 0)
+  {
+    // should never get here
+    ERROR("Something's wrong. Please inform the author.");
+  }
+  setring save;
+  ideal mm = maxideal(1);
+  poly s;
+  for (i=1; i<=n; i++)
+  {
+    s = f*var(i+n);
+    for (j=1; j<=size(F); j++)
+    {
+      s = s + k[j]*(f/F[j])*bracket(var(i+n),F[j]);
+    }
+    mm[i+2*n] = s;
+  }
+  map m = WFD,mm;
+  ideal J = m(I);
+  return(J);
+}
+example
+{
+  "EXAMPLE"; echo=2;
+  ring r = 0,(x,y,Dx,Dy),dp;
+  def W = Weyl();
+  setring W;
+  poly tx,ty = x*Dx, y*Dy;
+  ideal I =      // Appel F1 with parameters (3,-1,1,1) is a solution
+    tx*(tx+ty)-x*(tx+ty+3)*(tx-1),
+    ty*(tx+ty)-y*(tx+ty+3)*(ty+1);
+  kill tx,ty;
+  poly f = x^3*y^2-x^2*y^3-x^3*y+x*y^3+x^2*y-x*y^2;
+  ideal F = x-1,x,-x+y,y-1,y;
+  intvec k = -1,-1,-1,-3,-1;
+  ideal T = twistedIdeal(I,f,k,F);
+  // TODO change the ordering of WFD
+  // introduce new var f??
+  //paper:
+  poly fx = diff(f,x);
+  poly fy = diff(f,y);
+  poly fDx = f*Dx;
+  poly fDy = f*Dy;
+  poly fd(1) = fDx;
+  poly fd(2) = fDy;
+  ideal K=
+    (x^2-x^3)*(fDx)^2+x*((1-3*x)*f-(1-x)*y*fy-(1-x)*x*fx)*(fDx)
+    +x*(1-x)*y*(fDy)*(fDx)+x*y*f*(fDy)+3*x*f^2,
+    (y^2-y^3)*(fDy)^2+y*((1-5*y)*f-(1-y)*x*fx-(1-y)*y*fy)*(fDy)
+    +y*(1-y)*x*(fDx)*(fDy)-y*x*f*(fDx)-3*y*f^2;
+}
+
+
+proc ratSol (ideal I)
+"
+USAGE:    ratSol(I);  I ideal
+ASSUME:   The basering is the n-th Weyl algebra W over a field of
+          characteristic 0 and for all 1<=i<=n the identity
+          var(i+n)*var(i)=var(i)*var(i+1)+1 holds, i.e. the sequence of
+          variables is given by x(1),...,x(n),D(1),...,D(n), where D(i) is the
+          differential operator belonging to x(i).
+@*        Moreover, assume that I is holonomic.
+RETURN:   module, a basis of the rational solutions to the given system of
+          linear PDEs with polynomial coefficients, encoded via I
+          Note that each entry has two components, the first one standing for
+          the enumerator, the second one for the denominator.
+REMARKS:  Reference: (OTT), Algorithm 3.10
+NOTE:     If printlevel=1, progress debug messages will be printed,
+          if printlevel>=2, all the debug messages will be printed.
+SEE ALSO: polSol, polSolFiniteRank
+EXAMPLE:  example ratSol; shows examples
+"
+{
+  dmodGeneralAssumptionCheck();
+  if (!isHolonomic(I))
+  {
+    ERROR("Ideal is not holonomic.");
+  }
+  int ppl = printlevel - voice + 2;
+  def save = basering;
+  dbprint(ppl,"// computing singular locus...");
+  ideal S = DsingularLocus(I);
+  dbprint(ppl,"// ...done.");
+  poly f = S[1];
+  dbprint(ppl,"// considering poly " + string(f));
+  int n = nvars(save) div 2;
+  list RL = ringlist(save);
+  RL = RL[1..4];
+  list L = RL[2];
+  L = list(L[1..n]);
+  RL[2] = L;
+  L = list();
+  L[1] = list("dp",intvec(1:n));
+  L[2] = list("C",intvec(0));
+  RL[3] = L;
+  def rr = ring(RL);
+  setring rr;
+  poly f = imap(save,f);
+  ideal F = factorize(f,1); // not interested in multiplicities
+  dbprint(ppl,"// with irreducible factors " + string(F));
+  setring save;
+  ideal F = imap(rr,F);
+  kill rr,RL;
+  int i;
+  intvec k;
+  ideal FF = 1,1;
+  dbprint(ppl,"// computing b-functions of irreducible factors...");
+  for (i=1; i<=size(F); i++)
+  {
+    dbprint(ppl,"//   considering " + string(F[i]) + "...");
+    L = bfctBound(I,F[i]);
+    if (size(L) == 3) // bfct is constant
+    {
+      dbprint(ppl,"//   ...got " + string(L[3]));
+      if (L[3] == "1")
+      {
+        return(0); // TODO type // no rational solutions
+      }
+      else // should never get here
+      {
+        ERROR("Oops, something went wrong. Please inform the author.");
+      }
+    }
+    else
+    {
+      dbprint(ppl,"//   ...got roots " + string(L[1]));
+      dbprint(ppl,"//      with multiplicities " + string(L[2]));
+      k[i] = -maxIntRoot(L)-1;
+      if (k[i] < 0)
+      {
+        FF[2] = FF[2]*F[i]^(-k[i]);
+      }
+      else
+      {
+        FF[1] = FF[1]*F[i]^(k[i]);
+      }
+    }
+  }
+  vector v = FF[1]*gen(1) + FF[2]*gen(2);
+  kill FF;
+  dbprint(ppl,"// ...done");
+  ideal twI = twistedIdeal(I,f,k,F);
+  intvec w = -1:n;
+  dbprint(ppl,"// computing polynomial solutions of twisted system...");
+  if (isHolonomic(twI))
+  {
+    ideal P = polSol(twI,w);
+  }
+  else
+  {
+    ideal P = polSolFiniteRank(twI,w);
+  }
+  module M;
+  vector vv;
+  for (i=1; i<=ncols(P); i++)
+  {
+    vv = P[i]*gen(1) + 1*gen(2);
+    M[i] = multRat(v,vv);
+  }
+  dbprint(ppl,"// ...done");
+  return (M);
+}
+example
+{
+  "EXAMPLE"; echo=2;
+  ring r = 0,(x,y,Dx,Dy),dp;
+  def W = Weyl();
+  setring W;
+  poly tx,ty = x*Dx, y*Dy;
+  ideal I =      // Appel F1 with parameters (3,-1,1,1) is a solution
+    tx*(tx+ty)-x*(tx+ty+3)*(tx-1),
+    ty*(tx+ty)-y*(tx+ty+3)*(ty+1);
+  module M = ratSol(I);
+  // We obtain a basis of the rational solutions to I represented by a
+  // module / matrix with two rows.
+  // Each column of the matrix represents a rational function, where
+  // the first row correspond to the enumerator and the second row to
+  // the denominator.
+  print(M);
+}
+
+
+proc bfctBound (ideal I, poly f, list #)
+"
+USAGE:    bfctBound (I,f[,primdec]);  I ideal, f poly, primdec optional string
+ASSUME:   The basering is the n-th Weyl algebra W over a field of
+          characteristic 0 and for all 1<=i<=n the identity
+          var(i+n)*var(i)=var(i)*var(i+1)+1 holds, i.e. the sequence of
+          variables is given by x(1),...,x(n),D(1),...,D(n), where D(i) is the
+          differential operator belonging to x(i).
+@*        Moreover, assume that I is holonomic.
+RETURN:   list of roots (of type ideal) and multiplicities (of type intvec) of
+          a multiple of the b-function for f^s*u at a generic root of f.
+          Here, u stands for [1] in D/I.
+REMARKS:  Reference: (OTT), Algorithm 3.4
+NOTE:     This procedure requires to compute a primary decomposition in a
+          commutative ring. The optional string primdec can be used to specify
+          the algorithm to do so. It may either be `GTZ' (Gianni, Trager,
+          Zacharias) or `SY' (Shimoyama, Yokoyama). By default, `GTZ' is used.
+@*        If printlevel=1, progress debug messages will be printed,
+          if printlevel>=2, all the debug messages will be printed.
+SEE ALSO: bernstein, bfct, bfctAnn
+EXAMPLE:  example bfctBound; shows examples
+"
+{
+  dmodGeneralAssumptionCheck();
+  finKx(f);
+  if (!isHolonomic(I))
+  {
+    ERROR("Ideal is not holonomic.");
+  }
+  int ppl = printlevel - voice + 2;
+  string primdec = "GTZ";
+  if (size(#)>1)
+  {
+    if (typeof(#[1])=="string")
+    {
+      if ( (#[1]=="SY") || (#[1]=="sy") || (#[1]=="Sy") )
+      {
+        primdec = "SY";
+      }
+      else
+      {
+        if ( (#[1]<>"GTZ") && (#[1]<>"gtz") && (#[1]<>"Gtz") )
+        {
+          print("// Warning: optional string may either be `GTZ' or `SY',");
+          print("//          proceeding with `GTZ'.");
+          primdec = "GTZ";
+        }
+      }
+    }
+  }
+  def save = basering;
+  int n = nvars(save) div 2;
+  // step 1
+  ideal mm = maxideal(1);
+  def Wt = extendWeyl(safeVarName("t"));
+  setring Wt;
+  poly f = imap(save,f);
+  ideal mm = imap(save,mm);
+  int i;
+  for (i=1; i<=n; i++)
+  {
+    mm[i+n] = var(i+n+2) + bracket(var(i+n+2),f)*var(n+2);
+  }
+  map m = save,mm;
+  ideal I = m(I);
+  I = I, var(1)-f;
+  // step 2
+  intvec w = 1,(0:n);
+  dbprint(ppl  ,"// Computing initial ideal...");
+  I = initialIdealW(I,-w,w);
+  dbprint(ppl  ,"// ...done.");
+  dbprint(ppl-1,"// " + string(I));
+  // step 3: rewrite I using Euler operator t*Dt
+  list RL = ringlist(Wt);
+  RL = RL[1..4];
+  list L = RL[2] + list(safeVarName("s")); // s=t*Dt
+  RL[2] = L;
+  L = list();
+  L[1] = list("dp",intvec(1:(2*n+2)));
+  L[2] = list("dp",intvec(1));
+  L[3] = list("C",intvec(0));
+  RL[3] = L;
+  def @Wts = ring(RL);
+  kill L,RL;
+  setring @Wts;
+  matrix relD[2*n+3][2*n+3];
+  relD[1,2*n+3] = var(1);
+  relD[n+2,2*n+3] = -var(n+2);
+  for (i=1; i<=n+1; i++)
+  {
+    relD[i,n+i+1] = 1;
+  }
+  def Wts = nc_algebra(1,relD);
+  setring Wts;
+  ideal I = imap(Wt,I);
+  kill Wt, at Wts;
+  ideal S = var(1)*var(n+2)-var(2*n+3);
+  attrib(S,"isSB",1);
+  dbprint(ppl  ,"// Computing Euler representation...");
+  // I = NF(I,S);
+  int d;
+  intvec ww = 0:(2*2+2); ww[1] = -1; ww[n+2] = 1;
+  for (i=1; i<=size(I); i++)
+  {
+    d = deg(I[i],ww);
+    if (d>0)
+    {
+      I[i] = var(1)^d*I[i];
+    }
+    if (d<0)
+    {
+      d = -d;
+      I[i] = var(n+2)^d*I[i];
+    }
+  }
+  I = NF(I,S); // now there are no t,Dt in I, only s
+  dbprint(ppl  ,"// ...done.");
+  I = subst(I,var(2*n+3),-var(2*n+3)-1);
+  ring Ks = 0,s,dp;
+  def Ws = save + Ks;
+  setring Ws;
+  ideal I = imap(Wts,I);
+  kill Wts;
+  poly DD = 1;
+  for (i=1; i<=n; i++)
+  {
+    DD = DD * var(n+i);
+  }
+  dbprint(ppl  ,"// Eliminating differential operators...");
+  ideal J = eliminate(I,DD); // J subset K[x,s]
+  dbprint(ppl  ,"// ...done.");
+  dbprint(ppl-1,"// " + string(J));
+  list RL = ringlist(Ws);
+  RL = RL[1..4];
+  list L = RL[2];
+  L = list(L[1..n]) + list(L[2*n+1]);
+  RL[2] = L;
+  L = list();
+  L[1] = list("dp",intvec(1:(n+1)));
+  L[2] = list("C",intvec(0));
+  RL[3] = L;
+  def Kxs = ring(RL);
+  setring Kxs;
+  ideal J = imap(Ws,J);
+  dbprint(ppl  ,"// Computing primary decomposition with engine "
+          + primdec + "...");
+  if (primdec == "GTZ")
+  {
+    list P = primdecGTZ(J);
+  }
+  else
+  {
+    list P = primdecSY(J);
+  }
+  dbprint(ppl  ,"// ...done.");
+  dbprint(ppl-1,"// " + string(P));
+  ideal GP,Qix,rad,B;
+  poly f = imap(save,f);
+  vector v;
+  for (i=1; i<=size(P); i++)
+  {
+    dbprint(ppl  ,"// Considering primary component " + string(i)
+            + " of " + string(size(P)) + "...");
+    dbprint(ppl  ,"//   Intersecting with K[x] and computing radical...");
+    GP = std(P[i][1]);
+    Qix = eliminate(GP,var(n+1)); // subset K[x]
+    rad = radical(Qix);
+    rad = std(rad);
+    dbprint(ppl  ,"//   ...done.");
+    dbprint(ppl-1,"// " + string(rad));
+    if (rad[1]==0 || NF(f,rad)==0)
+    {
+      dbprint(ppl  ,"//   Intersecting with K[s]...");
+      v = pIntersect(var(n+1),GP);
+      B[size(B)+1] = vec2poly(v,n+1);
+      dbprint(ppl  ,"//   ...done.");
+      dbprint(ppl-1,"// " + string(B[size(B)]));
+    }
+    dbprint(ppl  ,"// ...done.");
+  }
+  f = lcm(B); // =lcm(B[1],...,B[size(B)])
+  list bb = bFactor(f);
+  setring save;
+  list bb = imap(Kxs,bb);
+  return(bb);
+}
+example
+{
+  "EXAMPLE"; echo=2;
+  ring r = 0,(x,y,Dx,Dy),dp;
+  def W = Weyl();
+  setring W;
+  poly tx,ty = x*Dx, y*Dy;
+  ideal I =      // Appel F1 with parameters (2,-3,-2,5)
+    tx*(tx+ty+4)-x*(tx+ty+2)*(tx-3),
+    ty*(tx+ty+4)-y*(tx+ty+2)*(ty-2),
+    (x-y)*Dx*Dy+2*Dx-3*Dy;
+  kill tx,ty;
+  poly f = x-1;
+  bfctBound(I,f);
+}
+
+
+//TODO check f/g or g/f, check Weyl closure of result
+proc annRatSyz (poly f, poly g, list #)
+"
+USAGE:    annRatSyz(f,g[,db,eng]);  f, g polynomials, db,eng optional integers
+ASSUME:   The basering is commutative and over a field of characteristic 0.
+RETURN:   ring (a Weyl algebra) containing an ideal `LD', which is (part of)
+          the annihilator of the rational function g/f in the corresponding
+          Weyl algebra
+REMARKS:  This procedure uses the computation of certain syzygies.
+          One can obtain the full annihilator by computing the Weyl closure of
+          the ideal LD.
+NOTE:     Activate the output ring with the @code{setring} command.
+          In the output ring, the ideal `LD' (in Groebner basis) is (part of)
+          the annihilator of g/f.
+@*        If db>0 is given, operators of order up to db are considered,
+          otherwise, and by default, a minimal holonomic solution is computed.
+@*        If eng<>0, @code{std} is used for Groebner basis computations,
+          otherwise, and by default, @code{slimgb} is used.
+@*        If printlevel =1, progress debug messages will be printed,
+          if printlevel>=2, all the debug messages will be printed.
+SEE ALSO: annRat, annPoly
+EXAMPLE:  example annRatSyz; shows examples
+"
+{
+  // check assumptions
+  if (!isCommutative())
+  {
+    ERROR("Basering must be commutative.");
+  }
+  if (  (size(ideal(basering)) >0) || (char(basering) >0) )
+  {
+    ERROR("Basering is inappropriate: characteristic>0 or qring present.");
+  }
+  if (g == 0)
+  {
+    ERROR("Second polynomial must not be zero.");
+  }
+  int db,eng;
+  if (size(#)>0)
+  {
+    if (typeof(#[1]) == "int")
+    {
+      db = int(#[1]);
+    }
+    if (size(#)>1)
+    {
+      if (typeof(#[2]) == "int")
+      {
+        eng = int(#[1]);
+      }
+    }
+  }
+  int ppl = printlevel - voice + 2;
+  vector I = f*gen(1)+g*gen(2);
+  checkRatInput(I);
+  int i,j;
+  def R = basering;
+  int n = nvars(R);
+  list RL = ringlist(R);
+  RL = RL[1..4];
+  list Ltmp = RL[2];
+  for (i=1; i<=n; i++)
+  {
+    Ltmp[i+n] = safeVarName("D" + Ltmp[i]);
+  }
+  RL[2] = Ltmp;
+  Ltmp = list();
+  Ltmp[1] = list("dp",intvec(1:2*n));
+  Ltmp[2] = list("C",intvec(0));
+  RL[3] = Ltmp;
+  kill Ltmp;
+  def @D = ring(RL);
+  setring @D;
+  def D = Weyl();
+  setring D;
+  ideal DD = 1;
+  ideal Dcd,Dnd,LD,tmp;
+  Dnd = 1;
+  module DS;
+  poly DJ;
+  kill @D;
+  setring R;
+  module Rnd,Rcd;
+  Rnd[1] = I;
+  vector RJ;
+  ideal L = I[1];
+  module RS;
+  poly p,pnew;
+  pnew = I[2];
+  int k,c;
+  while(1)
+  {
+    k++;
+    setring R;
+    dbprint(ppl,"// Testing order: " + string(k));
+    Rcd = Rnd;
+    Rnd = 0;
+    setring D;
+    Dcd = Dnd;
+    Dnd = 0;
+    dbprint(ppl-1,"// Current members of the annihilator: " + string(LD));
+    setring R;
+    c = size(Rcd);
+    p = pnew;
+    for (i=1; i<=c; i++)
+    {
+      for (j=1; j<=n; j++)
+      {
+        RJ = diffRat(Rcd[i],j);
+        setring D;
+        DJ = Dcd[i]*var(n+j);
+        tmp = Dnd,DJ;
+        if (size(Dnd) <> size(simplify(tmp,4))) // new element
+        {
+          Dnd[size(Dnd)+1] = DJ;
+          setring R;
+          Rnd[size(Rnd)+1] = RJ;
+          pnew = lcm(pnew,RJ[2]);
+        }
+        else // already have DJ in Dnd
+        {
+          setring R;
+        }
+      }
+    }
+    p = pnew/p;
+    for (i=1; i<=size(L); i++)
+    {
+      L[i] = p*L[i];
+    }
+    for (i=1; i<=size(Rnd); i++)
+    {
+      L[size(L)+1] = pnew/Rnd[i][2]*Rnd[i][1];
+    }
+    RS = syz(L);
+    setring D;
+    DD = DD,Dnd;
+    setring R;
+    if (RS <> 0)
+    {
+      setring D;
+      DS = imap(R,RS);
+      LD = ideal(transpose(DS)*transpose(DD));
+    }
+    else
+    {
+      setring D;
+    }
+    LD = engine(LD,eng);
+    // test if we're done
+    if (db<=0)
+    {
+      if (isHolonomic(LD)) { break; }
+    }
+    else
+    {
+      if (k==db) { break; }
+    }
+  }
+  export(LD);
+  setring R;
+  return(D);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  // printlevel = 3;
+  ring r = 0,(x,y),dp;
+  poly f = 2*x*y; poly g = x^2 - y^3;
+  def A = annRatSyz(f,g);   // compute a holonomic solution
+  setring A; A;
+  LD;
+  setring r;
+  def B = annRatSyz(f,g,5); // compute a solution up to degree 5
+  setring B;
+  LD; // this is the full annihilator as we will check below
+  setring r;
+  def C = annRat(f,g); setring C;
+  LD; // the full annihilator
+  ideal BLD = imap(B,LD);
+  NF(LD,std(BLD));
+}
+
diff --git a/Singular/LIB/dmodvar.lib b/Singular/LIB/dmodvar.lib
new file mode 100644
index 0000000..71dbfbd
--- /dev/null
+++ b/Singular/LIB/dmodvar.lib
@@ -0,0 +1,816 @@
+///////////////////////////////////////////////////////////////////////
+version="version dmodvar.lib 4.0.0.0 Jun_2013 "; // $Id: 8be884926175b47ee3b742934e34b0701133cc34 $
+category="Noncommutative";
+info="
+LIBRARY: dmodvar.lib     Algebraic D-modules for varieties
+
+AUTHORS: Daniel Andres,        daniel.andres at math.rwth-aachen.de
+@*       Viktor Levandovskyy,  levandov at math.rwth-aachen.de
+@*       Jorge Martin-Morales, jorge at unizar.es
+
+Support: DFG Graduiertenkolleg 1632 'Experimentelle und konstruktive Algebra'
+
+OVERVIEW: Let K be a field of characteristic 0. Given a polynomial ring R = K[x_1,...,x_n]
+and polynomials f_1,...,f_r in R, define F = f_1*...*f_r and F^s = f_1^s_1*...*f_r^s_r
+for symbolic discrete (that is shiftable) variables s_1,..., s_r.
+The module R[1/F]*F^s has the structure of a D<S>-module, where D<S> = D(R)
+tensored with S over K, where
+@* - D(R) is the n-th Weyl algebra K<x_1,...,x_n,d_1,...,d_n | d_j x_j = x_j d_j + 1>
+@* - S is the universal enveloping algebra of gl_r, generated by s_i = s_{ii}.
+@* One is interested in the following data:
+@* - the left ideal Ann F^s in D<S>, usually denoted by LD in the output
+@* - global Bernstein polynomial in one variable s = s_1+...+s_r, denoted by bs,
+@* - its minimal integer root s0, the list of all roots of bs, which are known to be
+     negative rational numbers, with their multiplicities, which is denoted by BS
+@* - an r-tuple of operators in D<S>, denoted by PS, such that the functional equality
+     sum(k=1 to k=r) P_k*f_k*F^s = bs*F^s holds in R[1/F]*F^s.
+
+REFERENCES:
+   (BMS06) Budur, Mustata, Saito: Bernstein-Sato polynomials of arbitrary varieties (2006).
+@* (ALM09) Andres, Levandovskyy, Martin-Morales: Principal Intersection and Bernstein-Sato
+Polynomial of an Affine Variety (2009).
+
+
+PROCEDURES:
+bfctVarIn(F[,L]);       computes the roots of the Bernstein-Sato polynomial b(s) of the variety V(F) using initial ideal approach
+bfctVarAnn(F[,L]);      computes the roots of the Bernstein-Sato polynomial b(s) of the variety V(F) using Sannfs approach
+SannfsVar(F[,O,e]);     computes the annihilator of F^s in the ring D<S>
+makeMalgrange(F[,ORD]); creates the Malgrange ideal, associated with F = F[1],..,F[P]
+
+SEE ALSO: bfun_lib, dmod_lib, dmodapp_lib, gmssing_lib
+
+KEYWORDS: D-module; D-module structure; Bernstein-Sato polynomial for variety; global Bernstein-Sato polynomial for variety;
+Weyl algebra; parametric annihilator for variety; Budur-Mustata-Saito approach; initial ideal approach
+";
+
+/*
+// Static procs:
+// coDim(I);           compute the codimension of the leading ideal of I
+// dmodvarAssumeViolation()
+// ORDstr2list (ORD, NN)
+// smallGenCoDim(I,k)
+*/
+
+/*
+  CHANGELOG
+  11.10.10 by DA:
+  - reformated help strings
+  - simplified code
+  - add and use of safeVarName
+  - renamed makeIF to makeMalgrange
+*/
+
+
+LIB "bfun.lib";    // for pIntersect
+LIB "dmodapp.lib"; // for isCommutative etc.
+
+
+///////////////////////////////////////////////////////////////////////////////
+
+// testing for consistency of the library:
+proc testdmodvarlib ()
+{
+  example makeMalgrange;
+  example bfctVarIn;
+  example bfctVarAnn;
+  example SannfsVar;
+}
+//   example coDim;
+
+///////////////////////////////////////////////////////////////////////////////
+
+static proc dmodvarAssumeViolation()
+{
+  // char K = 0, no qring
+  if (  (size(ideal(basering)) >0) || (char(basering) >0) )
+  {
+    ERROR("Basering is inappropriate: characteristic>0 or qring present");
+  }
+  return();
+}
+
+static proc safeVarName (string s, string cv)
+// assumes 's' to be a valid variable name
+// returns valid var name string @@.. at s
+{
+  string S;
+  if (cv == "v")  { S = "," + "," + varstr(basering)  + ","; }
+  if (cv == "c")  { S = "," + "," + charstr(basering) + ","; }
+  if (cv == "cv") { S = "," + charstr(basering) + "," + varstr(basering) + ","; }
+  s = "," + s + ",";
+  while (find(S,s) <> 0)
+  {
+    s[1] = "@";
+    s = "," + s;
+  }
+  s = s[2..size(s)-1];
+  return(s)
+    }
+
+// da: in smallGenCoDim(), rewritten using mstd business
+static proc coDim (ideal I)
+  "USAGE:  coDim (I);  I an ideal
+RETURN:  int
+PURPOSE: computes the codimension of the ideal generated by the leading monomials
+   of the given generators of the ideal. This is also the codimension of
+   the ideal if it is represented by a standard basis.
+NOTE:    The codimension of an ideal I means the number of variables minus the
+   Krull dimension of the basering modulo I.
+EXAMPLE: example coDim; shows examples
+"
+{
+  int n = nvars(basering);
+  int d = dim(I); // to insert: check whether I is in GB
+  return(n-d);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring R = 0,(x,y,z),Dp;
+  ideal I = x^2+y^3, z;
+  coDim(std(I));
+}
+
+static proc ORDstr2list (string ORD, int NN)
+{
+  /* convert an ordering defined in NN variables in the  */
+  /* string form into the same ordering in the list form */
+  string st;
+  st = "ring @Z = 0,z(1.." + string(NN) + "),";
+  st = st + ORD + ";";
+  execute(st); kill st;
+  list L = ringlist(@Z)[3];
+  kill @Z;
+  return(L);
+}
+
+proc SannfsVar (ideal F, list #)
+  "USAGE:  SannfsVar(F [,ORD,eng]);  F an ideal, ORD an optional string, eng an optional int
+RETURN:  ring (Weyl algebra tensored with U(gl_P)), containing an ideal LD
+PURPOSE: compute the D<S>-module structure of D<S>*f^s where f = F[1]*...*F[P]
+   and D<S> is the Weyl algebra D tensored with K<S>=U(gl_P), according to the
+   generalized algorithm by Briancon and Maisonobe for affine varieties
+ASSUME:  The basering is commutative and over a field of characteristic 0.
+NOTE:    Activate the output ring D<S> with the @code{setring} command.
+   In the ring D<S>, the ideal LD is the needed D<S>-module structure.
+@* The value of ORD must be an elimination ordering in D<Dt,S> for Dt
+   written in the string form, otherwise the result may have no meaning.
+   By default ORD = '(a(1..(P)..1),a(1..(P+P^2)..1),dp)'.
+@* If eng<>0, @code{std} is used for Groebner basis computations,
+   otherwise, and by default @code{slimgb} is used.
+DISPLAY: If printlevel=1, progress debug messages will be printed,
+@* if printlevel>=2, all the debug messages will be printed.
+EXAMPLE: example SannfsVar; shows examples
+"
+{
+  dmodvarAssumeViolation();
+  if (!isCommutative())
+  {
+    ERROR("Basering must be commutative");
+  }
+  def save = basering;
+  int N = nvars(basering);
+  int P = ncols(F);  //ncols better than size, since F[i] could be zero
+  // P is needed for default ORD
+  int i,j,k,l;
+  // st = "(a(1..(P)..1),a(1..(P+P^2)..1),dp)";
+  string st = "(a(" + string(1:P);
+  st = st + "),a(" + string(1:(P+P^2));
+  st = st + "),dp)";
+  // default values
+  string ORD = st;
+  int eng = 0;
+  if ( size(#)>0 )
+  {
+    if ( typeof(#[1]) == "string" )
+    {
+      ORD = string(#[1]);
+      // second arg
+      if (size(#)>1)
+      {
+        // exists 2nd arg
+        if ( typeof(#[2]) == "int" )
+        {
+          // the case: given ORD, given engine
+          eng = int(#[2]);
+        }
+      }
+    }
+    else
+    {
+      if ( typeof(#[1]) == "int" )
+      {
+        // the case: default ORD, engine given
+        eng = int(#[1]);
+        // ORD = "(a(1..(P)..1),a(1..(P+P^2)..1),dp)";  //is already set
+      }
+      else
+      {
+        // incorr. 1st arg
+        ORD = string(st);
+      }
+    }
+  }
+  // size(#)=0, i.e. there is no elimination ordering and no engine given
+  // eng = 0; ORD = "(a(1..(P)..1),a(1..(P^2)..1),dp)";  //are already set
+  int ppl = printlevel-voice+2;
+  // returns a list with a ring and an ideal LD in it
+  // save, N, P and the indices are already defined
+  int Nnew = 2*N+P+P^2;
+  list RL = ringlist(basering);
+  list L;
+  L[1] = RL[1];  //char
+  L[4] = RL[4];  //char, minpoly
+  // check whether vars have admissible names
+  list Name  = RL[2];
+  list RName;
+  // (i,j) <--> (i-1)*p+j
+  for (i=1; i<=P; i++)
+  {
+    RName[i] = safeVarName("Dt("+string(i)+")","cv");
+    for (j=1; j<=P; j++)
+    {
+      RName[P+(i-1)*P+j] = safeVarName("s("+string(i)+")("+string(j)+")","cv");
+    }
+  }
+  // now, create the names for new vars
+  list DName;
+  for(i=1; i<=N; i++)
+  {
+    DName[i] = safeVarName("D"+Name[i],"cv");  //concat
+  }
+  list NName = RName + Name + DName;
+  L[2] = NName;
+  // Name, Dname will be used further
+  kill NName;
+  //block ord (a(1..(P)..1),a(1..(P+P^2)..1),dp);
+  //export Nnew;
+  L[3] = ORDstr2list(ORD,Nnew);
+  // we are done with the list
+  def @R@ = ring(L);
+  setring @R@;
+  matrix @D[Nnew][Nnew];
+  // kronecker(i,j) equals (i==j)
+  // (i,j) <--> (i-1)*p+j
+  for (i=1; i<=P; i++)
+  {
+    for (j=1; j<=P; j++)
+    {
+      for (k=1; k<=P; k++)
+      {
+        //[sij,Dtk] = djk*Dti
+        //         @D[k,P+(i-1)*P+j] = (j==k)*Dt(i);
+        @D[k,P+(i-1)*P+j] = (j==k)*var(i);
+        for (l=1; l<=P; l++)
+        {
+          if ( (i-k)*P < l-j )
+          {
+            //[sij,skl] = djk*sil - dil*skj
+            //             @D[P+(i-1)*P+j,P+(k-1)*P+l] = -(j==k)*s(i)(l) + (i==l)*s(k)(j);
+            @D[P+(i-1)*P+j,P+(k-1)*P+l] = -(j==k)*var(i*P+l) + (i==l)*var(k*P+j);
+          }
+        }
+      }
+    }
+  }
+  for (i=1; i<=N; i++)
+  {
+    //[Dx,x]=1
+    @D[P+P^2+i,P+P^2+N+i] = 1;
+  }
+  def @R = nc_algebra(1, at D);
+  setring @R;
+  //@R@ will be used further
+  dbprint(ppl,"// -1-1- the ring @R(_Dt,_s,_x,_Dx) is ready");
+  dbprint(ppl-1, @R);
+  // create the ideal I
+  // (i,j) <--> (i-1)*p+j
+  ideal  F = imap(save,F);
+  ideal I;
+  for (i=1; i<=P; i++)
+  {
+    for (j=1; j<=P; j++)
+    {
+      //       I[(i-1)*P+j] = Dt(i)*F[j] + s(i)(j);
+      I[(i-1)*P+j] = var(i)*F[j] + var(i*P+j);
+    }
+  }
+  poly p,q;
+  for (i=1; i<=N; i++)
+  {
+    p=0;
+    for (j=1; j<=P; j++)
+    {
+      //       q = Dt(j);
+      q = var(j);
+      q = q*diff(F[j],var(P+P^2+i));
+      p = p + q;
+    }
+    I = I, p + var(P+P^2+N+i);
+  }
+  // -------- the ideal I is ready ----------
+  dbprint(ppl,"// -1-2- starting the elimination of Dt(i) in @R");
+  dbprint(ppl-1, I);
+  ideal J = engine(I,eng);
+  ideal K = nselect(J,1..P);
+  kill I,J;
+  dbprint(ppl,"// -1-3- all Dt(i) are eliminated");
+  dbprint(ppl-1, K);  //K is without Dt(i)
+  // ----------- the ring @R2(_s,_x,_Dx) ------------
+  //come back to the ring save, recover L and remove all Dt(i)
+  //L[1],L[4] do not change
+  setring save;
+  list Lord, tmp;
+  // variables
+  tmp = L[2];
+  Lord = tmp[P+1..Nnew];
+  L[2] = Lord;
+  // ordering
+  // st = "(a(1..(P^2)..1),dp)";
+  st = "(a(" + string(1:P^2);
+  st = st + "),dp)";
+  tmp = ORDstr2list(st,Nnew-P);
+  L[3] = tmp;
+  def @R2@ = ring(L);
+  kill L;
+  // we are done with the list
+  setring @R2@;
+  matrix tmpM,LordM;
+  // non-commutative relations
+  intvec iv = P+1..Nnew;
+  tmpM = imap(@R@, at D);
+  kill @R@;
+  LordM = submat(tmpM,iv,iv);
+  matrix @D2 = LordM;
+  def @R2 = nc_algebra(1, at D2);
+  setring @R2;
+  kill @R2@;
+  dbprint(ppl,"// -2-1- the ring @R(_s,_x,_Dx) is ready");
+  dbprint(ppl-1, @R2);
+  ideal K = imap(@R,K);
+  kill @R;
+  dbprint(ppl,"// -2-2- starting cosmetic Groebner basis computation");
+  dbprint(ppl-1, K);
+  K = engine(K,eng);
+  dbprint(ppl,"// -2-3- the cosmetic Groebner basis has been computed");
+  dbprint(ppl-1,K);
+  ideal LD = K;
+  attrib(LD,"isSB",1);
+  export LD;
+  return(@R2);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring R = 0,(x,y),Dp;
+  ideal F = x^3, y^5;
+  //ORD = "(a(1,1),a(1,1,1,1,1,1),dp)";
+  //eng = 0;
+  def A = SannfsVar(F);
+  setring A;
+  A;
+  LD;
+}
+
+proc bfctVarAnn (ideal F, list #)
+  "USAGE:  bfctVarAnn(F[,gid,eng]); F an ideal, gid,eng optional ints
+RETURN:  list of an ideal and an intvec
+PURPOSE: computes the roots of the Bernstein-Sato polynomial and their multiplicities
+   for an affine algebraic variety defined by F = F[1],..,F[r].
+ASSUME:  The basering is commutative and over a field in char 0.
+NOTE:    In the output list, the ideal contains all the roots and
+   the intvec their multiplicities.
+@* If gid<>0, the ideal is used as given. Otherwise, and by default, a
+   heuristically better suited generating set is used.
+@* If eng<>0, @code{std} is used for GB computations,
+   otherwise, and by default, @code{slimgb} is used.
+@* Computational remark: The time of computation can be very different depending
+   on the chosen generators of F, although the result is always the same.
+@* Further note that in this proc, the annihilator of f^s in D[s] is computed and
+   then a system of linear equations is solved by linear reductions in order to
+   find the minimal polynomial of S = s(1)(1) + ... + s(P)(P).
+   The resulted is shifted by 1-codim(Var(F)) following (BMS06).
+DISPLAY: If printlevel=1, progress debug messages will be printed,
+@* if printlevel=2, all the debug messages will be printed.
+EXAMPLE: example bfctVarAnn; shows examples
+"
+{
+  dmodvarAssumeViolation();
+  if (!isCommutative())
+  {
+    ERROR("Basering must be commutative");
+  }
+  int gid = 0; // default
+  int eng = 0; // default
+  if (size(#)>0)
+  {
+    if (typeof(#[1])=="int" || typeof(#[1])=="number")
+    {
+      gid = int(#[1]);
+    }
+    if (size(#)>1)
+    {
+      if (typeof(#[2])=="int" || typeof(#[2])=="number")
+      {
+        eng = int(#[2]);
+      }
+    }
+  }
+  def save = basering;
+  int ppl = printlevel - voice + 2;
+  printlevel = printlevel+1;
+  list L = smallGenCoDim(F,gid);
+  F = L[1];
+  int cd = L[2];
+  kill L;
+  def @R2 = SannfsVar(F,eng);
+  printlevel = printlevel-1;
+  int sF = size(F); // no 0 in F
+  setring @R2;
+  // we are in D[s] and LD is a std of SannfsVar(F)
+  ideal F = imap(save,F);
+  ideal GF = std(F);
+  ideal J = NF(LD,GF);
+  J = J, F;
+  dbprint(ppl,"// -3-1- starting Groebner basis of ann F^s + F ");
+  dbprint(ppl-1,J);
+  ideal K = engine(J,eng);
+  dbprint(ppl,"// -3-2- finished Groebner basis of ann F^s + F ");
+  dbprint(ppl-1,K);
+  poly S;
+  int i;
+  for (i=1; i<=sF; i++)
+  {
+    //     S = S + s(i)(i);
+    S = S + var((i-1)*sF+i);
+  }
+  dbprint(ppl,"// -4-1- computing the minimal polynomial of S");
+  dbprint(ppl-1,"S = "+string(S));
+  vector M = pIntersect(S,K);
+  dbprint(ppl,"// -4-2- the minimal polynomial has been computed");
+  ring @R3 = 0,s,dp;
+  vector M = imap(@R2,M);
+  poly p = vec2poly(M);
+  dbprint(ppl-1,p);
+  dbprint(ppl,"// -5-1- codimension of the variety");
+  dbprint(ppl-1,cd);
+  dbprint(ppl,"// -5-2- shifting BS(s)=minpoly(s-codim+1)");
+  p = subst(p,var(1),var(1)-cd+1);
+  dbprint(ppl-1,p);
+  dbprint(ppl,"// -5-3- factorization of the minimal polynomial");
+  list BS = bFactor(p);
+  setring save;
+  list BS = imap(@R3,BS);
+  kill @R2, at R3;
+  return(BS);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring R = 0,(x,y,z),Dp;
+  ideal F = x^2+y^3, z;
+  bfctVarAnn(F);
+}
+
+proc makeMalgrange (ideal F, list #)
+  "USAGE:  makeMalgrange(F [,ORD]);  F an ideal, ORD an optional string
+RETURN:  ring (Weyl algebra) containing an ideal IF
+PURPOSE: create the ideal by Malgrange associated with F = F[1],...,F[P].
+NOTE:    Activate the output ring with the @code{setring} command. In this ring,
+   the ideal IF is the ideal by Malgrange corresponding to F.
+@* The value of ORD must be an arbitrary ordering in K<_t,_x,_Dt,_Dx>
+   written in the string form. By default ORD = 'dp'.
+DISPLAY: If printlevel=1, progress debug messages will be printed,
+@* if printlevel>=2, all the debug messages will be printed.
+EXAMPLE: example makeMalgrange; shows examples
+"
+{
+  string ORD = "dp";
+  if ( size(#)>0 )
+  {
+    if ( typeof(#[1]) == "string" )
+    {
+      ORD = string(#[1]);
+    }
+  }
+  int ppl = printlevel-voice+2;
+  def save = basering;
+  int N = nvars(save);
+  int P = ncols(F);
+  int Nnew = 2*P+2*N;
+  int i,j;
+  string st;
+  list RL = ringlist(save);
+  list L,Lord;
+  list tmp;
+  intvec iv;
+  L[1] = RL[1];
+  L[4] = RL[4];
+  //check whether vars have admissible names
+  list Name = RL[2];
+  list TName, DTName;
+  for (i=1; i<=P; i++)
+  {
+    TName[i] = safeVarName("t("+string(i)+")","cv");
+    DTName[i] = safeVarName("Dt("+string(i)+")","cv");
+  }
+  //now, create the names for new vars
+  list DName;
+  for (i=1; i<=N; i++)
+  {
+    DName[i] = safeVarName("D"+Name[i],"cv");  //concat
+  }
+  list NName = TName + Name + DTName + DName;
+  L[2]   = NName;
+  // Name, Dname will be used further
+  kill NName, TName, Name, DTName, DName;
+  // ORD already set, default ord dp;
+  L[3] = ORDstr2list(ORD,Nnew);
+  // we are done with the list
+  def @R@ = ring(L);
+  setring @R@;
+  def @R = Weyl();
+  setring @R;
+  kill @R@;
+  //dbprint(ppl,"// -1-1- the ring @R(_t,_x,_Dt,_Dx) is ready");
+  //dbprint(ppl-1, @R);
+  // create the ideal I
+  ideal  F = imap(save,F);
+  ideal I;
+  for (j=1; j<=P; j++)
+  {
+    //     I[j] = t(j) - F[j];
+    I[j] = var(j) - F[j];
+  }
+  poly p,q;
+  for (i=1; i<=N; i++)
+  {
+    p=0;
+    for (j=1; j<=P; j++)
+    {
+      //       q = Dt(j);
+      q = var(P+N+j);
+      q = diff(F[j],var(P+i))*q;
+      p = p + q;
+    }
+    I = I, p + var(2*P+N+i);
+  }
+  // -------- the ideal I is ready ----------
+  ideal IF = I;
+  export IF;
+  return(@R);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring R = 0,(x,y,z),Dp;
+  ideal I = x^2+y^3, z;
+  def W = makeMalgrange(I);
+  setring W;
+  W;
+  IF;
+}
+
+proc bfctVarIn (ideal I, list #)
+  "USAGE:  bfctVarIn(I [,a,b,c]);  I an ideal, a,b,c optional ints
+RETURN:  list of ideal and intvec
+PURPOSE: computes the roots of the Bernstein-Sato polynomial and their
+   multiplicities for an affine algebraic variety defined by I.
+ASSUME:  The basering is commutative and over a field of characteristic 0.
+@* Varnames of the basering do not include t(1),...,t(r) and
+   Dt(1),...,Dt(r), where r is the number of entries of the input ideal.
+NOTE:    In the output list, say L,
+@* - L[1] of type ideal contains all the rational roots of a b-function,
+@* - L[2] of type intvec contains the multiplicities of above roots,
+@* - optional L[3] of type string is the part of b-function without rational roots.
+@* Note, that a b-function of degree 0 is encoded via L[1][1]=0, L[2]=0 and
+   L[3] is 1 (for nonzero constant) or 0 (for zero b-function).
+@* If a<>0, the ideal is used as given. Otherwise, and by default, a
+   heuristically better suited generating set is used to reduce computation time.
+@* If b<>0, @code{std} is used for GB computations in characteristic 0,
+   otherwise, and by default, @code{slimgb} is used.
+@* If c<>0, a matrix ordering is used for GB computations, otherwise,
+   and by default, a block ordering is used.
+@* Further note, that in this proc, the initial ideal of the multivariate Malgrange
+   ideal defined by I is computed and then a system of linear equations is solved
+   by linear reductions following the ideas by Noro.
+   The result is shifted by 1-codim(Var(F)) following (BMS06).
+DISPLAY: If printlevel=1, progress debug messages will be printed,
+@* if printlevel>=2, all the debug messages will be printed.
+EXAMPLE: example bfctVarIn; shows examples
+"
+{
+  dmodvarAssumeViolation();
+  if (!isCommutative())
+  {
+    ERROR("Basering must be commutative");
+  }
+  int ppl = printlevel - voice + 2;
+  int idealasgiven  = 0; // default
+  int whicheng      = 0; // default
+  int whichord      = 0; // default
+  if (size(#)>0)
+  {
+    if (typeof(#[1])=="int" || typeof(#[1])=="number")
+    {
+      idealasgiven = int(#[1]);
+    }
+    if (size(#)>1)
+    {
+      if (typeof(#[2])=="int" || typeof(#[2])=="number")
+      {
+        whicheng = int(#[2]);
+      }
+      if (size(#)>2)
+      {
+        if (typeof(#[3])=="int" || typeof(#[3])=="number")
+        {
+          whichord = int(#[3]);
+        }
+      }
+    }
+  }
+  def save = basering;
+  int i;
+  int n = nvars(basering);
+  // step 0: get small generating set
+  I = simplify(I,2);
+  list L = smallGenCoDim(I,idealasgiven);
+  I = L[1];
+  int c = L[2];
+  kill L;
+  // step 1: setting up the multivariate Malgrange ideal
+  int r = size(I);
+  def D = makeMalgrange(I);
+  setring D;
+  dbprint(ppl-1,"// Computing in " + string(n+r) + "-th Weyl algebra:", D);
+  dbprint(ppl-1,"// The Malgrange ideal: ", IF);
+  // step 2: compute the b-function of the Malgrange ideal w.r.t. approriate weights
+  intvec w = 1:r;
+  w[r+n] = 0;
+  dbprint(ppl,"// Computing the b-function of the Malgrange ideal...");
+  list L = bfctIdeal(IF,w,whicheng,whichord);
+  dbprint(ppl,"// ... done.");
+  dbprint(ppl-1,"// The b-function: ",L);
+  // step 3: shift the result
+  ring S = 0,s,dp;
+  list L = imap(D,L);
+  kill D;
+  if (size(L)==2)
+  {
+    ideal B = L[1];
+    ideal BB;
+    int nB = ncols(B);
+    for (i=nB; i>0; i--)
+    {
+      BB[i] = -B[nB-i+1]+c-r-1;
+    }
+    L[1] = BB;
+  }
+  else // should never get here: BS poly has non-rational roots
+  {
+    string str = L[3];
+    L = delete(L,3);
+    str = "poly @b = (" + str + ")*(" + string(fl2poly(L,"s")) + ");";
+    execute(str);
+    poly b = subst(@b,s,-s+c-r-1);
+    L = bFactor(b);
+  }
+  setring save;
+  list L = imap(S,L);
+  return(L);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring R = 0,(x,y,z),dp;
+  ideal F = x^2+y^3, z;
+  list L = bfctVarIn(F);
+  L;
+}
+
+static proc smallGenCoDim (ideal I, int Iasgiven)
+{
+  // call from K[x], returns list L
+  // L[1]=I or L[1]=smaller generating set of I
+  // L[2]=codimension(I)
+  int ppl = printlevel - voice + 2;
+  int n = nvars(basering);
+  int c;
+  if (attrib(I,"isSB") == 1)
+  {
+    c = n - dim(I);
+    if (!Iasgiven)
+    {
+      list L = mstd(I);
+    }
+  }
+  else
+  {
+    def save = basering;
+    list RL = ringlist(save);
+    list @ord;
+    @ord[1] = list("dp", intvec(1:n));
+    @ord[2] = list("C", intvec(0));
+    RL[3] = @ord;
+    kill @ord;
+    if (size(RL)>4) // commutative G-algebra present
+    {
+      RL = RL[1..4];
+    }
+    def R = ring(RL);
+    kill RL;
+    setring R;
+    ideal I = imap(save,I);
+    if (!Iasgiven)
+    {
+      list L = mstd(I);
+      c = n - dim(L[1]);
+      setring save;
+      list L = imap(R,L);
+    }
+    else
+    {
+      I = std(I);
+      c = n - dim(I);
+      setring save;
+    }
+    kill R;
+  }
+  if (!Iasgiven)
+  {
+    if (size(L[2]) < size(I))
+    {
+      I = L[2];
+      dbprint(ppl,"// Found smaller generating set of the given variety: ", I);
+    }
+    else
+    {
+      dbprint(ppl,"// Have not found smaller generating set of the given variety.");
+    }
+  }
+  dbprint(ppl-1,"// The codim of the given variety is " + string(c) + ".");
+  if (!defined(L))
+  {
+    list L;
+  }
+  L[1] = I;
+  L[2] = c;
+  return(L);
+}
+
+/*
+// Some more examples
+
+static proc TXcups()
+{
+"EXAMPLE:"; echo = 2;
+//TX tangent space of X=V(x^2+y^3)
+ring R = 0,(x0,x1,y0,y1),Dp;
+ideal F = x0^2+y0^3, 2*x0*x1+3*y0^2*y1;
+printlevel = 0;
+//ORD = "(a(1,1),a(1,1,1,1,1,1),dp)";
+//eng = 0;
+def A = SannfsVar(F);
+setring A;
+LD;
+}
+
+static proc ex47()
+{
+ring r7 = 0,(x0,x1,y0,y1),dp;
+ideal I = x0^2+y0^3, 2*x0*x1+3*y0^2*y1;
+bfctVarIn(I);
+// second ex - too big
+ideal J = x0^4+y0^5, 4*x0^3*x1+5*y0^4*y1;
+bfctVarIn(J);
+}
+
+static proc ex48()
+{
+ring r8 = 0,(x1,x2,x3),dp;
+ideal I = x1^3-x2*x3, x2^2-x1*x3, x3^2-x1^2*x2;
+bfctVarIn(I);
+}
+
+static proc ex49 ()
+{
+ring r9 = 0,(z1,z2,z3,z4),dp;
+ideal I = z3^2-z2*z4, z2^2*z3-z1*z4, z2^3-z1*z3;
+bfctVarIn(I);
+}
+
+static proc ex410()
+{
+LIB "toric.lib";
+ring r = 0,(z(1..7)),dp;
+intmat A[3][7];
+A = 6,4,2,0,3,1,0,0,1,2,3,0,1,0,0,0,0,0,1,1,2;
+ideal I = toric_ideal(A,"pt");
+I = std(I);
+//ideal I = z(6)^2-z(3)*z(7), z(5)*z(6)-z(2)*z(7), z(5)^2-z(1)*z(7),
+//  z(4)*z(5)-z(3)*z(6), z(3)*z(5)-z(2)*z(6), z(2)*z(5)-z(1)*z(6),
+//  z(3)^2-z(2)*z(4), z(2)*z(3)-z(1)*z(4), z(2)^2-z(1)*z(3);
+bfctVarIn(I,1); // no result yet
+}
+*/
diff --git a/Singular/LIB/elim.lib b/Singular/LIB/elim.lib
new file mode 100644
index 0000000..5889c14
--- /dev/null
+++ b/Singular/LIB/elim.lib
@@ -0,0 +1,993 @@
+///////////////////////////////////////////////////////////////////////////////
+version="version elim.lib 4.0.0.1 Jan_2014 "; // $Id: a6da1d3bce92babf2df6bbdb98cac0228cf05c77 $
+category="Commutative Algebra";
+info="
+LIBRARY:  elim.lib      Elimination, Saturation and Blowing up
+
+PROCEDURES:
+ blowup0(j[,s1,s2])   create presentation of blownup ring of ideal j
+ elimRing(p)          create ring with block ordering for elimating vars in p
+ elim(id,..)          variables .. eliminated from id (ideal/module)
+ elim1(id,p)          variables .. eliminated from id (different algorithm)
+ elim2(id,..)         variables .. eliminated from id (different algorithm)
+ nselect(id,v)        select generators not containing variables given by v
+ sat(id,j)            saturated quotient of ideal/module id by ideal j
+ select(id,v)         select generators containing all variables given by v
+ select1(id,v)        select generators containing one variable given by v
+           (parameters in square brackets [] are optional)
+";
+
+LIB "inout.lib";
+LIB "general.lib";
+LIB "poly.lib";
+LIB "ring.lib";
+///////////////////////////////////////////////////////////////////////////////
+
+proc blowup0 (ideal J,ideal C, list #)
+"USAGE:   blowup0(J,C [,W]); J,C,W ideals
+@*       C = ideal of center of blowup, J = ideal to be blown up,
+         W = ideal of ambient space
+ASSUME:  inclusion of ideals : W in J, J in C.
+         If not, the procedure replaces J by J+W and C by C+J+W
+RETURN:  a ring, say B, containing the ideals C,J,W and the ideals
+@*         - bR (ideal defining the blown up basering)
+@*         - aS (ideal of blown up ambient space)
+@*         - eD (ideal of exceptional divisor)
+@*         - tT (ideal of total transform)
+@*         - sT (ideal of strict transform)
+@*         - bM (ideal of the blowup map from basering to B)
+@*       such that B/bR is isomorphic to the blowup ring BC.
+PURPOSE: compute the projective blowup of the basering in the center C, the
+         exceptional locus, the total and strict tranform of J,
+         and the blowup map.
+         The projective blowup is a presentation of the blowup ring
+         BC = R[C] = R + t*C + t^2*C^2 + ... (also called Rees ring) of the
+         ideal C in the ring basering R.
+THEORY:  If basering = K[x1,...,xn] and C = <f1,...,fk> then let
+         B = K[x1,...,xn,y1,...,yk] and aS the preimage in B of W
+         under the map B -> K[x1,...,xn,t], xi -> xi, yi -> t*fi.
+         aS is homogeneous in the variables yi and defines a variety
+         Z=V(aS) in  A^n x P^(k-1), the ambient space of the blowup of V(W).
+         The projection Z -> A^n is an isomorphism outside the preimage
+         of the center V(C) in A^n and is called the blowup of the center.
+         The preimage of V(C) is called the exceptional set, the preimage of
+         V(J) is called the total transform of V(J). The strict transform
+         is the closure of (total transform minus the exceptional set).
+@*       If C = <x1,...,xn> then aS = <yi*xj - yj*xi | i,j=1,...,n>
+         and Z is the blowup of A^n in 0, the exceptional set is P^(k-1).
+NOTE:    The procedure creates a new ring with variables y(1..k) and x(1..n)
+         where n=nvars(basering) and k=ncols(C). The ordering is a block
+         ordering where the x-block has the ordering of the basering and
+         the y-block has ordering dp if C is not homogeneous
+         resp. the weighted ordering wp(b1,...bk) if C is homogeneous
+         with deg(C[i])=bi.
+SEE ALSO:blowUp, blowUp2
+EXAMPLE: example blowup0; shows examples
+"{
+   def br = basering;
+   list l = ringlist(br);
+   int n,k,i = nvars(br),ncols(C),0;
+   ideal W;
+   if (size(#) !=0)
+   { W = #[1];}
+   J = J,W;
+   //J = interred(J+W);
+//------------------------- create rings for blowup ------------------------
+//Create rings tr = K[x(1),...,x(n),t] and nr = K[x(1),...,x(n),y(1),...,y(k)]
+//and map Bl: nr --> tr, x(i)->x(i), y(i)->t*fi.
+//Let ord be the ordering of the basering.
+//We change the ringlist l by changing l[2] and l[3]
+//For K[t,x(1),...,x(n),t]
+// - l[2]: the variables to x(1),...,x(n),t
+// - l[3]: the ordering to a block ordering (ord,dp(1))
+//For K[x(1),...,x(n),y(1),...,y(k)]
+// - l[2]: the variables to x(1),...,x(n),y(1),...,y(k),
+// - l[3]: the ordering to a block ordering (ord,dp) if C is
+//         not homogeneous or to (ord,wp(b1,...bk),ord) if C is
+//         homogeneous with deg(C[i])=bi;
+
+//--------------- create tr = K[x(1),...,x(n),t] ---------------------------
+   int s = size(l[3]);
+   for ( i=n; i>=1; i--)
+   {
+      l[2][i]="x("+string(i)+")";
+   }
+   l[2]=insert(l[2],"t",n);
+   l[3]=insert(l[3],list("dp",1),s-1);
+   def tr = ring(l);
+
+//--------------- create nr = K[x(1),...,x(n),y(1),...,y(k)] ---------------
+   l[2]=delete(l[2],n+1);
+   l[3]=delete(l[3],s);
+   for ( i=k; i>=1; i--)
+   {
+      l[2][n+i]="y("+string(i)+")";
+   }
+
+   //---- change l[3]:
+   l[3][s+1] = l[3][s];         // save the module ordering of the basering
+   intvec w=1:k;
+   intvec v;                    // containing the weights for the varibale
+   if( homog(C) )
+   {
+      for( i=k; i>=1; i--)
+      {
+         v[i]=deg(C[i]);
+      }
+      if (v != w)
+      {
+         l[3][s]=list("wp",v);
+      }
+      else
+      {
+         l[3][s]=list("dp",v);
+      }
+   }
+   else
+   {
+      v=1:k;
+      l[3][s]=list("dp",v);
+   }
+   def nr = ring(l);
+
+//-------- create blowup map Bl: nr --> tr, x(i)->x(i), y(i)->t*fi ---------
+   setring tr;
+   ideal C = fetch(br,C);
+   ideal bl = x(1..n);
+   for( i=1; i<=k; i++) { bl = bl,t*C[i]; }
+   map Bl = nr,bl;
+   ideal Z;
+//------------------ compute blown up objects and return  -------------------
+   setring nr;
+   ideal bR = preimage(tr,Bl,Z);   //ideal of blown up affine space A^n
+   ideal C = fetch(br,C);
+   ideal J = fetch(br,J);
+   ideal W = fetch(br,W);
+   ideal aS = interred(bR+W);                //ideal of ambient space
+   ideal tT = interred(J+bR+W);              //ideal of total transform
+   ideal eD = interred(C+J+bR+W);            //ideal of exceptional divisor
+   ideal sT = sat(tT,C)[1];       //ideal of strict transform
+   ideal bM = x(1..n);            //ideal of blowup map br --> nr
+
+   export(bR,C,J,W,aS,tT,eD,sT,bM);
+   return(nr);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r  = 0,(x,y),dp;
+   poly f  = x2+y3;
+   ideal C = x,y;           //center of blowup
+   def B1 = blowup0(f,C);
+   setring B1;
+   aS;                      //ideal of blown up ambient space
+   tT;                      //ideal of total transform of f
+   sT;                      //ideal of strict transform of f
+   eD;                      //ideal of exceptional divisor
+   bM;                      //ideal of blowup map r --> B1
+
+   ring R  = 0,(x,y,z),ds;
+   poly f  = y2+x3+z5;
+   ideal C = y2,x,z;
+   ideal W = z-x;
+   def B2 = blowup0(f,C,W);
+   setring B2;
+   B2;                       //weighted ordering
+   bR;                       //ideal of blown up R
+   aS;                       //ideal of blown up R/W
+   sT;                       //strict transform of f
+   eD;                       //ideal of exceptional divisor
+   //Note that the different affine charts are {y(i)=1}
+ }
+
+//////////////////////////////////////////////////////////////////////////////
+proc elimRing ( poly vars, list #)
+"USAGE:   elimRing(vars [,w,str]); vars = product of variables to be eliminated
+         (type poly), w = intvec (specifying weights for all variables),
+         str = string either \"a\" or \"b\" (default: w=ringweights, str=\"a\")
+RETURN:  a list, say L, with R:=L[1] a ring and L[2] an intvec.
+         The ordering in R is an elimination ordering for the variables
+         appearing in vars depending on \"a\" resp. \"b\". Let w1 (resp. w2)
+         be the intvec of weights of the variables to be eliminated (resp. not
+         to be eliminated).
+         The monomial ordering of R has always 2 blocks, the first
+         block corresponds to the (given) variables to be eliminated.
+@*       If str = \"a\" the first block is a(w1,0..0) and the second block is
+         wp(w) resp. ws(w) if the first variable not to be eliminated is local.
+@*       If str = \"b\" the 1st block has ordering wp(w1) and the 2nd block
+         is wp(w2) resp. ws(w2) if the first variable not to be eliminated is
+         local.
+@*       If the basering is a quotient ring P/Q, then R is also a quotient ring
+         with Q replaced by a standard basis of Q w.r.t. the new ordering
+         (parameters are not touched).
+@*       The intvec L[2] is the intvec of variable weights (or the given w)
+         with weights <= 0 replaced by 1.
+PURPOSE: Prepare a ring for eliminating vars from an ideal/moduel by
+         computing a standard basis in R with a fast monomial ordering.
+         This procedure is used by the procedure elim.
+EXAMPLE: example elimRing; shows an example
+"
+{
+  def BR = basering;
+  int nvarBR = nvars(BR);
+  list BRlist = ringlist(BR);
+  //------------------ set resp. compute ring weights ----------------------
+  int ii;
+  intvec @w;              //to store weights of all variables
+  @w[nvarBR] = 0;
+  @w = @w + 1;            //initialize @w as 1..1
+  string str = "a";       //default for specifying elimination ordering
+  if (size(#) == 0)       //default values
+  {
+     @w = ringweights(BR);     //compute the ring weights (proc from ring.lib)
+  }
+
+  if (size(#) == 1)
+  {
+    if ( typeof(#[1]) == "intvec" )
+    {
+       @w = #[1];              //take the given weights
+    }
+    if ( typeof(#[1]) == "string" )
+    {
+       str = #[1];             //string for specifying elimination ordering
+    }
+  }
+
+  if (size(#) >= 2)
+  {
+    if ( typeof(#[1]) == "intvec" and typeof(#[2]) == "string" )
+    {
+       @w = #[1];              //take the given weights
+       str = #[2];             //string for specifying elimination ordering
+
+    }
+    if ( typeof(#[1]) == "string" and typeof(#[2]) == "intvec" )
+    {
+       str = #[1];             //string for specifying elimination ordering
+       @w = #[2];              //take the given weights
+    }
+  }
+
+  for ( ii=1; ii<=size(@w); ii++ )
+  {
+    if ( @w[ii] <= 0 )
+    {
+       @w[ii] = 1;             //replace non-positive weights by 1
+    }
+  }
+
+  //------ get variables to be eliminated together with their weights -------
+  intvec w1,w2;  //for ringweights of first (w1) and second (w2) block
+  list v1,v2;    //for variables of first (to be liminated) and second block
+
+  for( ii=1; ii<=nvarBR; ii++ )
+  {
+     if( vars/var(ii)==0 )    //treat variables not to be eliminated
+     {
+        w2 = w2, at w[ii];
+        v2 = v2+list(string(var(ii)));
+        if ( ! defined(local) )
+        {
+           int local = (var(ii) < 1);
+         }
+     }
+     else
+     {
+        w1 = w1, at w[ii];
+        v1 = v1+list(string(var(ii)));
+     }
+  }
+
+  if ( size(w1) <= 1 )
+  {
+    return(BR);
+  }
+  if ( size(w2) <= 1 )
+  {
+    ERROR("## elimination of all variables is not possible");
+  }
+
+  w1 = w1[2..size(w1)];
+  w2 = w2[2..size(w2)];
+  BRlist[2] = v1 + v2;         //put variables to be eliminated in front
+
+  //-------- create elimination ordering with two blocks and weights ---------
+  //Assume that the first r of the n variables are to be eliminated.
+  //Then, in case of an a-ordering (default), the new ring ordering will be
+  //of the form (a(1..1,0..0),dp) with r 1's and n-r 0's or (a(w1,0..0),wp(@w))
+  //if there are varaible weights which are not 1.
+  //In the case of a b-ordering the ordering will be a block ordering with two
+  //blocks of the form (dp(r),dp(n-r))  resp. (wp(w1),dp(w2))
+
+  list B3;                     //this will become the list for new ordering
+
+  //----- b-ordering case:
+  if ( str == "b" )
+  {
+    if( w1==1 )              //weights for vars to be eliminated are all 1
+    {
+       B3[1] = list("dp", w1);
+    }
+    else
+    {
+       B3[1] = list("wp", w1);
+    }
+
+    if( w2==1 )              //weights for vars not to be eliminated are all 1
+    {
+       if ( local )
+       {
+          B3[2] = list("ds", w2);
+       }
+       else
+       {
+          B3[2] = list("dp", w2);
+       }
+    }
+    else
+    {
+       if ( local )
+       {
+          B3[2] = list("ws", w2);
+       }
+       else
+       {
+          B3[2] = list("wp", w2);
+       }
+    }
+  }
+
+  //----- a-ordering case:
+  else
+  {
+    //define first the second block
+    if( @w==1 )              //weights for all vars are 1
+    {
+       if ( local )
+       {
+          B3[2] = list("ls", @w);
+       }
+       else
+       {
+          B3[2] = list("dp", @w);
+       }
+    }
+    else
+    {
+       if ( local )
+       {
+          B3[2] = list("ws", @w);
+       }
+       else
+       {
+          B3[2] = list("wp", @w);
+       }
+    }
+
+    //define now the first a-block of the form a(w1,0..0)
+    intvec @v;
+    @v[nvarBR] = 0;
+    @v = @v+w1;
+    B3[1] = list("a", @v);
+  }
+  BRlist[3] = B3;
+
+  //----------- put module ordering always at the end and return -------------
+
+  BRlist[3] = insert(BRlist[3],list("C",intvec(0)),size(B3));
+
+  def eRing = ring(quotientList(BRlist));
+  list result = eRing, @w;
+  return (result);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring R = 0,(x,y,z,u,v),(c,lp);
+   def P = elimRing(yu);  P;
+   intvec w = 1,1,3,4,5;
+   elimRing(yu,w);
+
+   ring S =  (0,a),(x,y,z,u,v),ws(1,2,3,4,5);
+   minpoly = a2+1;
+   qring T = std(ideal(x+y2+v3,(x+v)^2));
+   def Q = elimRing(yv)[1];
+   setring Q; Q;
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc elim (def id, list #)
+"USAGE:   elim(id,arg[,s]);  id ideal/module, arg can be either an intvec v or
+         a product p of variables (type poly), s a string determining the
+         method which can be \"slimgb\" or \"std\" or, additionally,
+         \"withWeigts\".
+RETURN: ideal/module obtained from id by eliminating either the variables
+        with indices appearing in v or the variables appearing in p.
+        Works also in a qring.
+METHOD: elim uses elimRing to create a ring with an elimination ordering for
+        the variables to be eliminated and then applies std if \"std\"
+        is given, or slimgb if \"slimgb\" is given, or a heuristically chosen
+        method.
+@*      If the variables in the basering have weights these weights are used
+        in elimRing. If a string \"withWeigts\" as (optional) argument is given
+        @sc{Singular} computes weights for the variables to make the input as
+        homogeneous as possible.
+@*      The method is different from that used by eliminate and elim1;
+        depending on the example, any of these commands can be faster.
+NOTE:   No special monomial ordering is required, i.e. the ordering can be
+        local or mixed. The result is a SB with respect to the ordering of
+        the second block used by elimRing. E.g. if the first var not to be
+        eliminated is global, resp. local, this ordering is dp, resp. ds
+        (or wp, resp. ws, with the given weights for these variables).
+        If printlevel > 0 the ring for which the output is a SB is shown.
+SEE ALSO: eliminate, elim1
+EXAMPLE: example elim; shows an example
+"
+{
+  if (size(#) == 0)
+  {
+    ERROR("## specify variables to be eliminated");
+  }
+  int pr = printlevel - voice + 2;   //for ring display if printlevel > 0
+  def BR = basering;
+  intvec save_opt=option(get);
+  list lER;                          //for list returned by elimRing
+//-------------------------------- check input -------------------------------
+  poly vars;
+  int ne;                           //for number of vars to be eliminated
+  int ii;
+  if (size(#) > 0)
+  {
+    if ( typeof(#[1]) == "poly" )
+    {
+      vars = #[1];
+      for( ii=1; ii<=nvars(BR); ii++ )
+      {
+        if ( vars/var(ii) != 0)
+        { ne++; }
+      }
+    }
+    if ( typeof(#[1]) == "intvec" or typeof(#[1]) == "int")
+    {
+      ne = size(#[1]);
+      vars=1;
+      for( ii=1; ii<=ne; ii++ )
+      {
+        vars=vars*var(#[1][ii]);
+      }
+    }
+  }
+
+  string method;                    //for "std" or "slimgb" or "withWeights"
+  if (size(#) >= 2)
+  {
+    if ( typeof(#[2]) == "string" )
+    {
+       if ( #[2] == "withWeights" )
+       {
+         intvec @w = weight(id);        //computation of weights
+       }
+       if ( #[2] == "std" ) { method = "std"; }
+       if ( #[2] == "slimgb" ) { method = "slimgb"; }
+
+    }
+    else
+    {
+      ERROR("expected `elim(ideal,intvec[,string])`");
+    }
+
+    if (size(#) == 3)
+    {
+       if ( typeof(#[3]) == "string" )
+       {
+          if ( #[3] == "withWeights" )
+          {
+            intvec @w = weight(id);        //computation of weights
+          }
+          if ( #[3] == "std" ) { method = "std"; }
+          if ( #[3] == "slimgb" ) { method = "slimgb"; }
+       }
+    }
+
+    if ( method == "" )
+    {
+      ERROR("expected \"std\" or \"slimgb\" or \"withWeights\" as the optional string parameters");
+    }
+  }
+
+//-------------- create new ring and map objects to new ring ------------------
+   if ( defined(@w) )
+   {
+      lER = elimRing(vars, at w);  //in this case lER[2] = @w
+   }
+   else
+   {
+      lER = elimRing(vars);
+      intvec @w = lER[2];      //in this case w is the intvec of
+                               //variable weights as computed in elimRing
+   }
+   def ER = lER[1];
+   setring ER;
+   def id = imap(BR,id);
+   poly vars = imap(BR,vars);
+
+//---------- now eliminate in new ring and map back to old ring ---------------
+  //if possible apply std(id,hi,w) where hi is the first hilbert function
+  //of id with respect to the weights w. If w is not defined (i.e. good weights
+  //@w are computed then id is only approximately @w-homogeneous and
+  //the hilbert driven std cannot be used directly; however, stdhilb
+  //homogenizes first and applies the hilbert driven std to the homogenization
+
+   option(redThrough);
+   if (typeof(id)=="matrix")
+   {
+     id = matrix(stdhilb(module(id),method, at w));
+   }
+   else
+   {
+     id = stdhilb(id,method, at w);
+   }
+
+   //### Todo: hier sollte id = groebner(id, "hilb"); verwendet werden.
+   //da z.Zt. (Jan 09) groebener bei extra Gewichtsvektor a(...) aber stets std
+   //aufruft und ausserdem "withWeigts" nicht kennt, ist groebner(id, "hilb")
+   //zunaechst nicht aktiviert. Ev. nach Ueberarbeitung von groebner aktivieren
+
+   id = nselect(id,1..ne);
+   if ( pr > 0 )
+   {
+     "// result is a SB in the following ring:";
+      ER;
+   }
+   option(set,save_opt);
+   setring BR;
+   return(imap(ER,id));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r=0,(x,y,u,v,w),dp;
+   ideal i=x-u,y-u2,w-u3,v-x+y3;
+   elim(i,3..4);
+   elim(i,uv);
+   int p = printlevel;
+   printlevel = 2;
+   elim(i,uv,"withWeights","slimgb");
+   printlevel = p;
+
+   ring S =  (0,a),(x,y,z,u,v),ws(1,2,3,4,5);
+   minpoly = a2+1;
+   qring T = std(ideal(ax+y2+v3,(x+v)^2));
+   ideal i=x-u,y-u2,az-u3,v-x+ay3;
+   module m=i*gen(1)+i*gen(2);
+   m=elim(m,xy);
+   show(m);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc elim2 (def id, intvec va)
+"USAGE:   elim2(id,v);  id ideal/module, v intvec
+RETURNS: ideal/module obtained from id by eliminating variables in v
+NOTE:    no special monomial ordering is required, result is a SB with
+         respect to ordering dp (resp. ls) if the first var not to be
+         eliminated belongs to a -p (resp. -s) blockordering
+         This proc uses 'execute' or calls a procedure using 'execute'.
+SEE ALSO: elim1, eliminate, elim
+EXAMPLE: example elim2; shows examples
+"
+{
+//---- get variables to be eliminated and create string for new ordering ------
+   int ii; poly vars=1;
+   for( ii=1; ii<=size(va); ii++ ) { vars=vars*var(va[ii]); }
+   if(  attrib(basering,"global")) { string ordering = "),dp;"; }
+   else { string ordering = "),ls;"; }
+   string mpoly=string(minpoly);
+//-------------- create new ring and map objects to new ring ------------------
+   def br = basering;
+   string str = "ring @newr = ("+charstr(br)+"),("+varstr(br)+ordering;
+   execute(str);
+   if (mpoly!="0") { execute("minpoly="+mpoly+";"); }
+   def i = imap(br,id);
+   poly vars = imap(br,vars);
+//---------- now eliminate in new ring and map back to old ring ---------------
+   i = eliminate(i,vars);
+   setring br;
+   return(imap(@newr,i));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r=0,(x,y,u,v,w),dp;
+   ideal i=x-u,y-u2,w-u3,v-x+y3;
+   elim2(i,3..4);
+   module m=i*gen(1)+i*gen(2);
+   m=elim2(m,3..4);show(m);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+proc elim1 (def id, list #)
+"USAGE:   elim1(id,arg); id ideal/module, arg can be either an intvec v or a
+         product p of variables (type poly)
+RETURN: ideal/module obtained from id by eliminating either the variables
+        with indices appearing in v or the variables appearing in p
+METHOD:  elim1 calls eliminate but in a ring with ordering dp (resp. ls)
+         if the first var not to be eliminated belongs to a -p (resp. -s)
+         ordering.
+NOTE:    no special monomial ordering is required.
+         This proc uses 'execute' or calls a procedure using 'execute'.
+SEE ALSO: elim, eliminate
+EXAMPLE: example elim1; shows examples
+"
+{
+   def br = basering;
+   if ( size(ideal(br)) != 0 )
+   {
+      ERROR ("elim1 cannot eliminate in a qring");
+   }
+//------------- create product vars of variables to be eliminated -------------
+  poly vars;
+  int ii;
+  if (size(#) > 0)
+  {
+    if ( typeof(#[1]) == "poly" ) {  vars = #[1]; }
+    if ( typeof(#[1]) == "intvec" or typeof(#[1]) == "int")
+    {
+      vars=1;
+      for( ii=1; ii<=size(#[1]); ii++ )
+      {
+        vars=vars*var(#[1][ii]);
+      }
+    }
+  }
+//---- get variables to be eliminated and create string for new ordering ------
+   for( ii=1; ii<=nvars(basering); ii++ )
+   {
+      if( vars/var(ii)==0 ) { poly p = 1+var(ii); break;}
+   }
+   if( ord(p)==0 ) { string ordering = "),ls;"; }
+   if( ord(p)>0 ) { string ordering = "),dp;"; }
+//-------------- create new ring and map objects to new ring ------------------
+   string str = "ring @newr = ("+charstr(br)+"),("+varstr(br)+ordering;
+   execute(str);
+   def id = fetch(br,id);
+   poly vars = fetch(br,vars);
+//---------- now eliminate in new ring and map back to old ring ---------------
+   id = eliminate(id,vars);
+   setring br;
+   return(imap(@newr,id));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r=0,(x,y,t,s,z),dp;
+   ideal i=x-t,y-t2,z-t3,s-x+y3;
+   elim1(i,ts);
+   module m=i*gen(1)+i*gen(2);
+   m=elim1(m,3..4); show(m);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc nselect (def id, intvec v)
+"USAGE:   nselect(id,v); id = ideal, module or matrix, v = intvec
+RETURN:  generators (or columns) of id not containing the variables with index
+         an entry of v
+SEE ALSO: select, select1
+EXAMPLE: example nselect; shows examples
+"
+{
+   if (typeof(id) != "ideal")
+   {
+      if (typeof(id)=="module" || typeof(id)=="matrix")
+      {
+        module id1 = module(id);
+      }
+      else
+      {
+        ERROR("// *** input must be of type ideal or module or matrix");
+      }
+   }
+   else
+   {
+      ideal id1 = id;
+   }
+   int j,k;
+   int n,m = size(v), ncols(id1);
+   for( k=1; k<=m; k++ )
+   {
+      for( j=1; j<=n; j++ )
+      {
+        if( size(id1[k]/var(v[j]))!=0 )
+        {
+           id1[k]=0; break;
+        }
+      }
+   }
+   if(typeof(id)=="matrix")
+   {
+      return(matrix(simplify(id1,2)));
+   }
+   return(simplify(id1,2));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r=0,(x,y,t,s,z),(c,dp);
+   ideal i=x-y,y-z2,z-t3,s-x+y3;
+   nselect(i,3);
+   module m=i*(gen(1)+gen(2));
+   m;
+   nselect(m,3..4);
+   nselect(matrix(m),3..4);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc sat (def id, ideal j)
+"USAGE:   sat(id,j);  id=ideal/module, j=ideal
+RETURN:  list of an ideal/module [1] and an integer [2]:
+         [1] = saturation of id with respect to j (= union_(k=1...) of id:j^k)
+         [2] = saturation exponent (= min( k | id:j^k = id:j^(k+1) ))
+NOTE:    [1] is a standard basis in the basering
+DISPLAY: saturation exponent during computation if printlevel >=1
+EXAMPLE: example sat; shows an example
+"{
+   int ii,kk;
+   def i=id;
+   id=std(id);
+   int p = printlevel-voice+3;  // p=printlevel+1 (default: p=1)
+   while( ii<=size(i) )
+   {
+      dbprint(p-1,"// compute quotient "+string(kk+1));
+      i=quotient(id,j);
+      for( ii=1; ii<=size(i); ii++ )
+      {
+         if( reduce(i[ii],id,1)!=0 ) break;
+      }
+      id=std(i); kk++;
+   }
+   dbprint(p-1,"// saturation becomes stable after "+string(kk-1)+" iteration(s)","");
+   list L = id,kk-1;
+   return (L);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   int p      = printlevel;
+   ring r     = 2,(x,y,z),dp;
+   poly F     = x5+y5+(x-y)^2*xyz;
+   ideal j    = jacob(F);
+   sat(j,maxideal(1));
+   printlevel = 2;
+   sat(j,maxideal(2));
+   printlevel = p;
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc select (def id, intvec v)
+"USAGE:   select(id,n[,m]); id = ideal/module/matrix, v = intvec
+RETURN:  generators/columns of id containing all variables with index
+         an entry of v
+NOTE:    use 'select1' for selecting generators/columns containing at least
+         one of the variables with index an entry of v
+SEE ALSO: select1, nselect
+EXAMPLE: example select; shows examples
+"
+{
+   if (typeof(id) != "ideal")
+   {
+      if (typeof(id)=="module" || typeof(id)=="matrix")
+      {
+        module id1 = module(id);
+      }
+      else
+      {
+        ERROR("// *** input must be of type ideal or module or matrix");
+      }
+   }
+   else
+   {
+      ideal id1 = id;
+   }
+   int j,k;
+   int n,m = size(v), ncols(id1);
+   for( k=1; k<=m; k++ )
+   {
+      for( j=1; j<=n; j++ )
+      {
+         if( size(id1[k]/var(v[j]))==0)
+         {
+            id1[k]=0; break;
+         }
+      }
+   }
+   if(typeof(id)=="matrix")
+   {
+      return(matrix(simplify(id1,2)));
+   }
+   return(simplify(id1,2));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r=0,(x,y,t,s,z),(c,dp);
+   ideal i=x-y,y-z2,z-t3,s-x+y3;
+   ideal j=select(i,1);
+   j;
+   module m=i*(gen(1)+gen(2));
+   m;
+   select(m,1..2);
+   select(matrix(m),1..2);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc select1 (def id, intvec v)
+"USAGE:   select1(id,v); id = ideal/module/matrix, v = intvec
+RETURN:  generators/columns of id containing at least one of the variables
+         with index an entry of v
+NOTE:    use 'select' for selecting generators/columns containing all variables
+         with index an entry of v
+SEE ALSO: select, nselect
+EXAMPLE: example select1; shows examples
+"
+{
+   if (typeof(id) != "ideal")
+   {
+      if (typeof(id)=="module" || typeof(id)=="matrix")
+      {
+        module id1 = module(id);
+        module I;
+      }
+      else
+      {
+        ERROR("// *** input must be of type ideal or module or matrix");
+      }
+   }
+   else
+   {
+      ideal id1 = id;
+      ideal I;
+   }
+   int j,k;
+   int n,m = size(v), ncols(id1);
+   for( k=1; k<=m; k++ )
+   {  for( j=1; j<=n; j++ )
+      {
+         if( size(subst(id1[k],var(v[j]),0)) != size(id1[k]) )
+         {
+            I = I,id1[k]; break;
+         }
+      }
+   }
+   if(typeof(id)=="matrix")
+   {
+      return(matrix(simplify(I,2)));
+   }
+   return(simplify(I,2));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r=0,(x,y,t,s,z),(c,dp);
+   ideal i=x-y,y-z2,z-t3,s-x+y3;
+   ideal j=select1(i,1);j;
+   module m=i*(gen(1)+gen(2)); m;
+   select1(m,1..2);
+   select1(matrix(m),1..2);
+}
+/*
+///////////////////////////////////////////////////////////////////////////////
+//                      EXAMPLEs
+///////////////////////////////////////////////////////////////////////////////
+// Siehe auch file 'tst-elim' mit grossem Beispiel;
+example blowup0;
+example elimRing;
+example elim;
+example elim1;
+example nselect;
+example sat;
+example select;
+example select1;
+//===========================================================================
+//         Rationale Normalkurve vom Grad d im P^d bzw. im A^d:
+//homogen s:t -> (t^d:t^(d-1)s: ...: s^d), inhomogen t ->(t^d:t^(d-1): ...:t)
+
+//------------------- 1. Homogen:
+//Varianten der Methode
+int d = 5;
+ring R = 0,(s,t,x(0..d)),dp;
+ideal I;
+for( int ii=0; ii<=d; ii++) {I = I,ideal(x(ii)-t^(d-ii)*s^ii); }
+
+int tt = timer;
+ideal eI = elim(I,1..2,"std");
+ideal eI = elim(I,1..2,"slimgb");
+ideal eI = elim(I,st,"withWeights");
+ideal eI = elim(I,st,"std","withWeights");
+//komplizierter
+int d = 50;
+ring R = 0,(s,t,x(0..d)),dp;
+ideal I;
+for( int ii=0; ii<=d; ii++) {I = I,ideal(x(ii)-t^(d-ii)*s^ii); }
+int tt = timer;
+ideal eI = elim(I,1..2);               //56(44)sec (slimgb 22(17),hilb 33(26))
+timer-tt; tt = timer;
+ideal eI = elim1(I,1..2);              //71(53)sec
+timer-tt; tt = timer;
+ideal eI = eliminate(I,st);            //70(51)sec (wie elim1)
+timer-tt;
+timer-tt; tt = timer;
+ideal eI = elim(I,1..2,"withWeights"); //190(138)sec
+                                //(weights73(49), slimgb43(33), hilb71(53)
+timer-tt;
+//------------------- 2. Inhomogen
+int d = 50;
+ring r = 0,(t,x(0..d)),dp;
+ideal I;
+for( int ii=0; ii<=d; ii++) {I = I+ideal(x(ii)-t^(d-ii)); }
+int tt = timer;
+ideal eI = elim(I,1,);                //20(15)sec (slimgb13(10), hilb6(5))
+ideal eI = elim(I,1,"std");           //17sec (std 11, hilb 6)
+timer-tt; tt = timer;
+ideal eI = elim1(I,t);               //8(6)sec
+timer-tt; tt = timer;
+ideal eI = eliminate(I,t);           //7(6)sec
+timer-tt;
+timer-tt; tt = timer;
+ideal eI = elim(I,1..1,"withWeights"); //189(47)sec
+//(weights73(42), slimgb43(1), hilb70(2)
+timer-tt;
+
+//===========================================================================
+//        Zufaellige Beispiele, homogen
+system("random",37);
+ring R = 0,x(1..6),lp;
+ideal I = sparseid(4,3);
+
+int tt = timer;
+ideal eI = elim(I,1);                //108(85)sec (slimgb 29(23), hilb79(61)
+timer-tt; tt = timer;
+ideal eI = elim(I,1,"std");          //(139)sec (std 77, hilb 61)
+timer-tt; tt = timer;
+ideal eI = elim1(I,1);               //(nach 45 min abgebrochen)
+timer-tt; tt = timer;
+ideal eI = eliminate(I,x(1));        //(nach 45 min abgebrochen)
+timer-tt; tt = timer;
+
+//        Zufaellige Beispiele, inhomogen
+system("random",37);
+ring R = 32003,x(1..5),dp;
+ideal I = sparseid(4,2,3);
+option(prot,redThrough);
+
+intvec w = 1,1,1,1,1,1;
+int tt = timer;
+ideal eI = elim(I,1,w);            //(nach 5min abgebr.) hilb schlaegt nicht zu
+timer-tt; tt = timer;              //BUG!!!!!!
+
+int tt = timer;
+ideal eI = elim(I,1);              //(nach 5min abgebr.) hilb schlaegt nicht zu
+timer-tt; tt = timer;              //BUG!!!!!!
+ideal eI = elim1(I,1);             //8(7.8)sec
+timer-tt; tt = timer;
+ideal eI = eliminate(I,x(1));      //8(7.8)sec
+timer-tt; tt = timer;
+
+                              BUG!!!!
+//        Zufaellige Beispiele, inhomogen, lokal
+system("random",37);
+ring R = 32003,x(1..6),ds;
+ideal I = sparseid(4,1,2);
+option(prot,redThrough);
+int tt = timer;
+ideal eI = elim(I,1);                //(haengt sich auf)
+timer-tt; tt = timer;
+ideal eI = elim1(I,1);               //(0)sec !!!!!!
+timer-tt; tt = timer;
+ideal eI = eliminate(I,x(1));        //(ewig mit ...., abgebrochen)
+timer-tt; tt = timer;
+
+ring R1 =(32003),(x(1),x(2),x(3),x(4),x(5),x(6)),(a(1,0,0,0,0,0),ds,C);
+ideal I = imap(R,I);
+I = std(I);                           //(haengt sich auf) !!!!!!!
+
+ideal eI = elim(I,1..1,"withWeights"); //(47)sec (weights42, slimgb1, hilb2)
+timer-tt;
+
+ring R1 =(32003),(x(1),x(2),x(3),x(4),x(5),x(6)),(a(1,0,0,0,0,0),ds,C);
+ideal I = imap(R,I);
+I = std(I);                           //(haengt sich auf) !!!!!!!
+
+ideal eI = elim(I,1..1,"withWeights"); //(47)sec (weights42, slimgb1, hilb2)
+timer-tt;
+*/
diff --git a/Singular/LIB/ellipticcovers.lib b/Singular/LIB/ellipticcovers.lib
new file mode 100644
index 0000000..4c843f9
--- /dev/null
+++ b/Singular/LIB/ellipticcovers.lib
@@ -0,0 +1,528 @@
+///////////////////////////////////////////////////////////////////////////////
+version="version ellipticcovers.lib 4.0.0.0 Dec_2013 ";
+category="Commutative Algebra";
+info="
+LIBRARY:  ellipticCovers.lib    Gromov-Witten numbers of elliptic curves
+
+AUTHORS:  J. Boehm, boehm @ mathematik.uni-kl.de
+          A. Buchholz, buchholz @ math.uni-sb.de
+          H. Markwig   hannah @ math.uni-sb.de
+
+OVERVIEW:
+
+We implement a formula for computing the number of covers of elliptic curves.
+It has beed obtained by proving mirror symmetry
+for arbitrary genus by tropical methods in [BBM]. A Feynman graph of genus
+g is a trivalent, connected graph of genus g (with 2g-2 vertices
+and 3g-3 edges). The branch type b=(b_1,...,b_(3g-3)) of a stable map is the
+multiplicity of the the edge i over a fixed base point.
+
+Given a Feynman graph G and a branch type b, we obtain the number
+N_(G,b) of stable maps of branch type b from a genus g curve of topological type G
+to the elliptic curve by computing a path integral
+over a rational function. The path integral is computed as a residue.
+
+The sum of N_(G,b) over all branch types b of sum d gives N_(G,d)*|Aut(G)|, with the
+Gromov-Witten invariant N_(G,d) of degree d stable maps from a genus g curve
+of topological type G to the elliptic curve.
+
+The sum of N_(G,d) over all such graphs gives the usual Gromov-Witten invariant N_(g,d)
+of degree d stable maps from a genus g curve to the elliptic curve.
+
+The key function computing the numbers N_(G,b) and N_(G,d) is gromovWitten.
+
+REFERENCES:
+
+[BBM] J. Boehm, A. Buchholz, H. Markwig: Tropical mirror symmetry for elliptic curves, arXiv:1309.5893 (2013).
+
+KEYWORDS:
+tropical geometry; mirror symmetry; tropical mirror symmetry; Gromov-Witten invariants; elliptic curves; propagator; Feynman graph; path integral
+
+TYPES:
+
+graph
+
+PROCEDURES:
+
+makeGraph(list, list)                     generate a graph from a list of vertices and a lsit of edges
+printGraph(graph)                         print procedure for graphs
+propagator(list,int)                      propagator factor of degree d in the quotient of two variables, or
+                                          propagator for fixed graph and branch type
+computeConstant(number, number)           constant coefficient in the Laurent series expansion of a rational function in a given variable
+evalutateIntegral(number, list)           path integral for a given propagator and ordered sequence of variables
+gromovWitten(number)                      sum of path integrals for a given propagator over all orderings of the variables, or
+                                          Gromov Witten invariant for a given graph and a fixed branch type, or
+                                          list of Gromov Witten invariants for a given graph and all branch types
+computeGromovWitten(graph, int, int)      compute the Gromov Witten invariants for a given graph and some branch types
+generatingFunction (graph, int)           multivariate generating function for the Gromov Witten invariants of a graph up to fixed degree
+
+partitions(int, int)                      partitions of an integer into a fixed number of summands
+permute(list)                             all permutations of a list
+lsum(list)                                sum of the elements of a list
+
+";
+
+
+LIB "parallel.lib";
+
+
+proc mod_init()
+{
+newstruct("graph","list vertices, list edges");
+newstruct("Net","list rows");
+
+system("install","graph","print",printGraph,1);
+system("install","Net","print",printNet,1);
+system("install","Net","+",catNet,2);
+
+}
+
+
+static proc catNet(Net N, Net M)
+{
+list L;
+list LN=N.rows;
+list LM=M.rows;
+int widthN=size(LN[1]);
+int widthM=size(LM[1]);
+int nm=max(size(LN),size(LM));
+for (int j=1; j<=nm; j++)
+{
+    if (j>size(LN)){LN[j]=emptyString(widthN);}
+    if (j>size(LM)){LM[j]=emptyString(widthM);}
+    L[j]=LN[j]+LM[j];
+}
+Net NM;
+NM.rows=L;
+return(NM);}
+
+
+static proc netList(list L1)
+{
+  Net N=net("[");
+  for (int j=1; j<=size(L1)-1; j++)
+  {
+     N=N+net(L1[j])+net(", ");
+  }
+  N=N+net(L1[size(L1)])+net("]");
+  return(N);
+}
+
+static proc printNet(Net N)
+{
+list L = N.rows;
+for (int j=1; j<=size(L); j++)
+{
+   print(L[j]);
+}
+}
+
+static proc net(def M){
+  if (typeof(M)=="list"){
+    return(netList(M));
+  }
+  Net N;
+  list L;
+  L[1]=string(M);
+  N.rows=L;
+return(N);}
+
+
+
+proc printGraph(graph G)
+"USAGE:  printGraph(G); G graph@*
+ASSUME:  G is a graph.
+THEORY:  This is the print function used by Singular to print a graph.
+KEYWORDS: graph
+EXAMPLE:  example printGraph; shows an example
+"
+{
+  print(netList(G.edges));
+  print("Graph with "+string(size(G.vertices))+" vertices and "+string(size(G.edges))+" edges")
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring R=(0,x1,x2,x3,x4),(q1,q2,q3,q4,q5,q6),dp;
+  graph G = makeGraph(list(1,2,3,4),list(list(1,3),list(1,2),list(1,2),list(2,4),list(3,4),list(3,4)));
+  G;
+}
+
+
+
+proc makeGraph(list v, list e)
+"USAGE:  makeGraph(v,e); v list, e list@*
+ASSUME:  v is a list of integers, e is a list of two element lists of v.
+RETURN:  graph with vertices v and edges e
+THEORY:  Creates a graph from a list of vertices and edges. The vertices can be any type.
+KEYWORDS: graph
+EXAMPLE:  example printGraph; shows an example
+"
+{
+  graph G;
+  G.vertices = v;
+  G.edges = e;
+  return(G);
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring R=(0,x1,x2,x3,x4),(q1,q2,q3,q4,q5,q6),dp;
+  graph G = makeGraph(list(1,2,3,4),list(list(1,3),list(1,2),list(1,2),list(2,4),list(3,4),list(3,4)));
+  G;
+}
+
+
+proc propagator(def xy, def d)
+"USAGE:  propagator(xy,d); xy list, d int@*
+         propagator(G,b); G graph, b list@*
+ASSUME:  xy is a list of two numbers x and y in a rational function field, d non-negative integer.@*
+         G is a Feynman graph, a is a list of integers of length equal to the number of edges of G.@*
+         We assume that the coefficient ring has one rational variable for each vertex of G.
+RETURN:  number, the propagator associated to the input data.
+THEORY:  If xy and d are specified, then the function returns x^2*y^2/(x^2-y^2)^2) for d=0, which
+         is a associated to an edge with vertices x and y not passing above the base point.
+         For d>0 it returns the sum of (j*x^(4*j)+j*y^(4*j))/(x*y)^(2*j) over all divisors j of d,
+         which is associated to an edge with vertices x and y passing with multiplicity d above the base point.
+
+         Essentially the variables x and y stand for the position of the base points.
+
+         In the second way of using this function, G is a Feynman graph and b is a branch type
+         over a fixed base point of a cover with source G and target an elliptic curve. It returns the
+         product of propagator(list(v[i],w[i]),b[i]) over all edges i with multiplicity b[i] over the base point
+         and vertices v[i] and w[i].
+
+KEYWORDS: elliptic curve
+EXAMPLE:  example propagator; shows an example
+"
+{
+  if ((typeof(xy)=="list")||(typeof(d)=="int")) {
+    number x = xy[1];
+    number y = xy[2];
+    if (d<0) {ERROR("expected non-negative degree");}
+    if (d==0) {return(x^2*y^2/(x^2-y^2)^2);}
+    number p=0;
+    for (int j=1; j<=d; j++){
+       if (d%j==0){p=p+(j*x^(4*j)+j*y^(4*j))/(x*y)^(2*j);}
+    }
+    return(p);
+  }
+  if ((typeof(xy)=="graph")||(typeof(d)=="list"))  {
+    list xl = ringlist(basering)[1][2];
+    list ed = xy.edges;
+    number f=1;
+    for (int j=1; j<=size(ed); j++){
+       execute("number xx1 = "+xl[ed[j][1]]);
+       execute("number xx2 = "+xl[ed[j][2]]);
+       f=f*propagator(list(xx1,xx2),d[j]);
+       kill xx1;
+       kill xx2;
+    }
+    return(f);
+  }
+  if ((typeof(xy)=="graph")||(typeof(d)=="int"))  {
+  }
+ERROR("wrong input type");}
+example
+{ "EXAMPLE:"; echo=2;
+  ring R=(0,x1,x2,x3,x4),(q1,q2,q3,q4,q5,q6),dp;
+  graph G = makeGraph(list(1,2,3,4),list(list(1,3),list(1,2),list(1,2),list(2,4),list(3,4),list(3,4)));
+  propagator(list(x1,x2),0);
+  propagator(list(x1,x2),2);
+  propagator(G,list(1,1,1,0,0,0));
+}
+
+
+
+
+
+proc computeConstant(number f,number xx)
+"USAGE:  computeConstant(f,x); f number, x number@*
+ASSUME:  f is a number in a rational function field, x is a variable of the field.@*
+RETURN:  number, the constant coefficient of the Laurent series of f in the variable x.
+THEORY:  Computes the constant coefficient of the Laurent series by iterative differentiation.
+
+KEYWORDS: Laurent series
+EXAMPLE:  example computeConstant; shows an example
+"
+{
+  int tst=0;
+  number ff=f;
+  int k;
+  int j;
+  poly de;
+  while (tst==0){
+     ff=f*xx^k;
+     for (j=1; j<=k; j++){
+        ff=diff(ff,xx)/j;
+     }
+  de = subst(denominator(ff),xx,0);
+  if (de!=0){
+     poly nu = subst(numerator(ff),xx,0);
+     return(number(nu/de));
+  }
+  k=k+1;
+  }
+ERROR("error in computeConstant");}
+example
+{ "EXAMPLE:"; echo=2;
+  ring R=(0,x1,x2,x3,x4),(q1,q2,q3,q4,q5,q6),dp;
+  graph G = makeGraph(list(1,2,3,4),list(list(1,3),list(1,2),list(1,2),list(2,4),list(3,4),list(3,4)));
+  number P = propagator(G,list(1,1,1,0,0,0));
+  computeConstant(P,x2);
+}
+
+
+
+
+proc evaluateIntegral(number P, list xL)
+"USAGE:  evaluateIntegral(P,xx); P number, xx list@*
+ASSUME:  P is a number in a rational function field, xx is a list of variables of the field@*
+RETURN:  number, the constant coefficient of the Laurent series of f in the variables in the list xx.
+THEORY:  Computes the constant coefficient of the Laurent series iteratively for the elements of xx.
+
+         In the setting of covers of elliptic curves this is the path integral over the
+         propagator divided by the product of all variables (corresponding to the vertices)
+         computed as a residue.
+
+KEYWORDS: residue; Laurent series
+EXAMPLE:  example evaluateIntegral; shows an example
+"
+{
+  number p = P;
+  for(int j=1; j<=size(xL); j++){
+     p=computeConstant(p,xL[j]);
+  }
+return(p);}
+example
+{ "EXAMPLE:"; echo=2;
+  ring R=(0,x1,x2,x3,x4),(q1,q2,q3,q4,q5,q6),dp;
+  graph G = makeGraph(list(1,2,3,4),list(list(1,3),list(1,2),list(1,2),list(2,4),list(3,4),list(3,4)));
+  number p = propagator(G,list(0,2,1,0,0,1));
+  evaluateIntegral(p,list(x1,x3,x4,x2));
+}
+
+
+proc permute (list N)
+"USAGE:  permute(N); N list@*
+ASSUME:  N is a list@*
+RETURN:  list with all permutations of N.
+THEORY:  Computes all permutations of N.
+
+         This will eventually be deleted and become a more efficient kernel function.
+
+KEYWORDS: permutations
+EXAMPLE:  example permute; shows an example
+"
+{
+   int i,j,k;
+   list L,L1;
+   if (size(N)==1){
+     return(list(N));
+   } else {
+     k=1;
+     for (i=1; i<=size(N); i++){
+       L=permute(delete(N,i));
+       for (j=1; j<=size(L); j++){
+          L1[k]=L[j]+list(N[i]);
+          k=k+1;
+       }
+     }
+   }
+return(L1);}
+example
+{ "EXAMPLE:"; echo=2;
+  ring R=(0,x1,x2,x3,x4),(q),dp;
+  permute(list(x1,x2,x3,x4));
+}
+
+
+
+proc partitions(int n, int a)
+"USAGE:  partitions(n,a); n int, a int@*
+ASSUME:  n and a  are positive integers@*
+RETURN:  list of all partitions of a into n summands.
+THEORY:  Computes all partitions of a into n summands.
+
+         This may eventually be deleted and become a more efficient kernel function.
+
+KEYWORDS: partitions
+EXAMPLE:  example partitions; shows an example
+"
+{
+ring R = 2,(x(1..n)),dp;
+ideal I = maxideal(a);
+list L;
+for (int j=1;j<=size(I);j++){
+  L[j]=leadexp(I[j]);
+}
+return(L);}
+example
+{ "EXAMPLE:"; echo=2;
+  partitions(3,7);
+}
+
+
+
+proc gromovWitten(def P,list #)
+"USAGE:  gromovWitten(P); P number@*
+         gromovWitten(G,d); G graph, d int@*
+         gromovWitten(G,b); G graph, b list@*
+ASSUME:  P is a propagator, or @*
+         G is a Feynman graph and d a non-negative integer, or@*
+         G is a Feynman graph and b is a list of integers of length equal to the number of edges of G@*
+         We assume that the coefficient ring has one rational variable for each vertex of G.@*
+RETURN:  Gromov-Witten invariant.
+THEORY:  Computes @*
+
+         - the Gromov-Witten invariant of a given propagator P, or @*
+
+         - the invariant N_(G,d)*|Aut(G)| where d is the degree of the covering, or @*
+
+         - the number N_(G,b) of coverings with source G and target an elliptic curves with branch type a over a
+         fixed base point (that is, the i-th edge passes over the base point with multiplicity b[i]).@*
+
+KEYWORDS: Gromov-Witten invariants; elliptic curves; coverings; Hurwitz numbers
+EXAMPLE:  example gromovWitten; shows an example
+"
+{
+  if (typeof(P)=="number") {
+  list xl = ringlist(basering)[1][2];
+  int j;
+  for(j=1; j<=size(xl); j++){
+     execute("number n= "+xl[j]);
+     xl[j]=n;
+     kill n;
+  }
+  list pxl = permute(xl);
+  number p = 0;
+  for(j=1; j<=size(pxl); j++){
+     p=p+evaluateIntegral(P,pxl[j]);
+  }
+  return(p);
+  }
+  if (typeof(P)=="graph"){
+     if (size(#)>1){
+       return(gromovWitten(propagator(P,#)));
+     } else {
+      int d =#[1];
+      list pa = partitions(size(P.edges),d);
+      list re;
+      int ti;
+      for (int j=1; j<=size(pa); j++) {
+       ti=timer;
+       re[j]=gromovWitten(propagator(P,pa[j]));
+       ti=timer-ti;
+       //print(string(j)+" / "+string(size(pa))+"    "+string(pa[j])+"     "+string(re[j])+"      "+string(sum(re))+"     "+string(ti));
+      }
+     return(lsum(re));
+     }
+  }
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring R=(0,x1,x2,x3,x4),(q1,q2,q3,q4,q5,q6),dp;
+  graph G = makeGraph(list(1,2,3,4),list(list(1,3),list(1,2),list(1,2),list(2,4),list(3,4),list(3,4)));
+  number P = propagator(G,list(0,2,1,0,0,1));
+  gromovWitten(P);
+  gromovWitten(G,list(0,2,1,0,0,1));
+  gromovWitten(G,2);
+}
+
+
+
+proc computeGromovWitten(graph P,int d, int st, int en, list #)
+"USAGE:  computeGromovWitten(G, d, st, en [, vb] ); G graph, d int, st int, en  int, optional: vb int@*
+ASSUME:  G is a Feynman graph, d a non-negative integer, st specified the start- and en the end partition
+         in the list pa = partition(d). Specifying a positive optional integer vb leads to intermediate printout.@*
+         We assume that the coefficient ring has one rational variable for each vertex of G.@*
+RETURN:  list L, where L[i] is gromovWitten(G,pa[i]) and all others are zero.
+THEORY:  This function does essentially the same as the function gromovWitten, but is designed for handling complicated examples.
+         Eventually it will also run in parallel.@*
+
+KEYWORDS: Gromov-Witten invariants; elliptic curves; coverings; Hurwitz numbers
+EXAMPLE:  example computeGromovWitten; shows an example
+"
+{
+     number s =0;
+     list pararg;
+     list re;
+     list pa = partitions(size(P.edges),d);
+     int vb=0;
+     if (size(#)>0){vb=#[1];}
+     int ti;
+     if (vb>0){print(size(pa));}
+     for (int j=1; j<=size(pa); j++) {
+      if ((j>=st)&(j<=en)){
+       ti=timer;
+       //pararg[j]=list(propagator(G,pa[j]));
+       re[j]=gromovWitten(propagator(P,pa[j]));
+       ti=timer-ti;
+       if (vb>0){print(string(j)+" / "+string(size(pa))+"    "+string(pa[j])+"     "+string(re[j])+"      "+string(lsum(re))+"     "+string(ti));}
+      } else {re[j]=s;}
+     }
+     //list re = parallelWaitAll("gromovWitten", pararg, list(list(list(2))));
+     return(re);
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring R=(0,x1,x2,x3,x4),(q1,q2,q3,q4,q5,q6),dp;
+  graph G = makeGraph(list(1,2,3,4),list(list(1,3),list(1,2),list(1,2),list(2,4),list(3,4),list(3,4)));
+  partitions(6,2);
+  computeGromovWitten(G,2,3,7);
+  computeGromovWitten(G,2,3,7,1);
+}
+
+
+proc lsum(list L)
+"USAGE:  lsum(L); L list@*
+ASSUME:  L is a list of things with the binary operator + defined.@*
+RETURN:  The sum of the elements of L.
+THEORY:  Sums the elements of a list.
+
+         Eventually this will be deleted and become a more efficient kernel function.@*
+
+EXAMPLE:  example lsum; shows an example
+"
+{
+  execute(typeof(L[1])+" s");
+  for(int j=1; j<=size(L); j++){
+     s=s+L[j];
+  }
+return(s);}
+example
+{ "EXAMPLE:"; echo=2;
+  list L = 1,2,3,4,5;
+  lsum(L);
+}
+
+
+
+proc generatingFunction(graph G, int d)
+"USAGE:  generatingFunction(G, d); G graph, d int@*
+ASSUME:  G is a Feynman graph, d a non-negative integer. The basering has one polynomial variable for each
+         edge, and the coefficient ring has one rational variable for each vertex.@*
+RETURN:  poly.
+THEORY:  This function compute the multivariate generating function of all Gromov-Witten invariants up to
+         degree d, that is, the sum of all gromovWitten(G,b)*q^b.@*
+
+KEYWORDS: generating function; Gromov-Witten invariants; elliptic curves; coverings; Hurwitz numbers
+EXAMPLE:  example generatingFunction; shows an example
+"
+{
+  poly  s =0;
+  int j,jj;
+  list pa,L;
+  for (j=1; j<=d; j++){
+    pa = partitions(size(G.edges),j);
+    L = computeGromovWitten(G,j,1,size(pa));
+    for (jj=1; jj<=size(pa); jj++) {
+       s=s+L[jj]*monomial(pa[jj]);
+    }
+  }
+return(s);}
+example
+{ "EXAMPLE:"; echo=2;
+  ring R=(0,x1,x2),(q1,q2,q3),dp;
+  graph G = makeGraph(list(1,2),list(list(1,2),list(1,2),list(1,2)));
+  generatingFunction(G,3);
+}
+
diff --git a/Singular/LIB/equising.lib b/Singular/LIB/equising.lib
new file mode 100644
index 0000000..fbc2c29
--- /dev/null
+++ b/Singular/LIB/equising.lib
@@ -0,0 +1,2147 @@
+///////////////////////////////////////////////////////////////////////
+version="version equising.lib 4.0.0.0 Jun_2013 "; // $Id: 046c5ddcc700302ea15bf90bb497d0d9f2693450 $
+category="Singularities";
+info="
+LIBRARY:  equising.lib  Equisingularity Stratum of a Family of Plane Curves
+AUTHOR:   Christoph Lossen, lossen at mathematik.uni-kl.de
+          Andrea Mindnich, mindnich at mathematik.uni-kl.de
+
+PROCEDURES:
+ tau_es(f);             codim of mu-const stratum in semi-universal def. base
+ esIdeal(f);            (Wahl's) equisingularity ideal of f
+ esStratum(F[,m,L]);    equisingularity stratum of a family F
+ isEquising(F[,m,L]);   tests if a given deformation is equisingular
+
+ control_Matrix(M);     computes list of blowing-up data
+";
+
+LIB "hnoether.lib";
+LIB "poly.lib";
+LIB "elim.lib";
+LIB "deform.lib";
+LIB "sing.lib";
+
+////////////////////////////////////////////////////////////////////////////////
+//
+//  The following (static) procedures are used by esComputation
+//
+////////////////////////////////////////////////////////////////////////////////
+// COMPUTES  a weight vector. x and y get weight 1 and all other
+//           variables get weight 0.
+static proc xyVector()
+{
+  intvec iv ;
+  iv[nvars(basering)]=0 ;
+  iv[rvar(x)] =1;
+  iv[rvar(y)] =1;
+  return (iv);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// exchanges the variables x and y in the polynomial f
+static proc swapXY(poly f)
+{
+  def r_base = basering;
+  ideal MI = maxideal(1);
+  MI[rvar(x)]=y;
+  MI[rvar(y)]=x;
+  map phi = r_base, MI;
+  f=phi(f);
+  return (f);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// computes m-jet w.r.t. the variables x,y (other variables weighted 0
+static proc m_Jet(poly F,int m);
+{
+  intvec w=xyVector();
+  poly Fd=jet(F,m,w);
+  return(Fd);
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+// computes the 4 control matrices (input is multsequence(L))
+proc control_Matrix(list M);
+"USAGE:   control_Matrix(L); L list
+ASSUME:  L is the output of multsequence(hnexpansion(f)).
+RETURN:  list M of 4 intmat's:
+ at format
+  M[1] contains the multiplicities at the respective infinitely near points
+       p[i,j] (i=step of blowup+1, j=branch) -- if branches j=k,...,k+m pass
+       through the same p[i,j] then the multiplicity is stored in M[1][k,j],
+       while M[1][k+1]=...=M[1][k+m]=0.
+  M[2] contains the number of branches meeting at p[i,j] (again, the information
+       is stored according to the above rule)
+  M[3] contains the information about the splitting of M[1][i,j] with respect to
+       different tangents of branches at p[i,j] (information is stored only for
+       minimal j>=k corresponding to a new tangent direction).
+       The entries are the sum of multiplicities of all branches with the
+       respective tangent.
+  M[4] contains the maximal sum of higher multiplicities for a branch passing
+       through p[i,j] ( = degree Bound for blowing up)
+ at end format
+NOTE:    the branches are ordered in such a way that only consecutive branches
+         can meet at an infinitely near point. @*
+         the final rows of the matrices M[1],...,M[3] is (1,1,1,...,1), and
+         correspond to infinitely near points such that the strict transforms
+         of the branches are smooth and intersect the exceptional divisor
+         transversally.
+SEE ALSO: multsequence
+EXAMPLE: example control_Matrix; shows an example
+"
+{
+  int i,j,k,dummy;
+
+  dummy=0;
+  for (j=1;j<=ncols(M[2]);j++)
+  {
+    dummy=dummy+M[1][nrows(M[1])-1,j]-M[1][nrows(M[1]),j];
+  }
+  intmat S[nrows(M[1])+dummy][ncols(M[1])];
+  intmat T[nrows(M[1])+dummy][ncols(M[1])];
+  intmat U[nrows(M[1])+dummy][ncols(M[1])];
+  intmat maxDeg[nrows(M[1])+dummy][ncols(M[1])];
+
+  for (i=1;i<=nrows(M[2]);i++)
+  {
+    dummy=1;
+    for (j=1;j<=ncols(M[2]);j++)
+    {
+      for (k=dummy;k<dummy+M[2][i,j];k++)
+      {
+        T[i,dummy]=T[i,dummy]+1;
+        S[i,dummy]=S[i,dummy]+M[1][i,k];
+        if (i>1)
+        {
+          U[i-1,dummy]=U[i-1,dummy]+M[1][i-1,k];
+        }
+      }
+      dummy=k;
+    }
+  }
+
+  // adding an extra row (in some cases needed to control ES-Stratum
+  // computation)
+  for (i=nrows(M[1]);i<=nrows(S);i++)
+  {
+    for (j=1;j<=ncols(M[2]);j++)
+    {
+      S[i,j]=1;
+      T[i,j]=1;
+      U[i,j]=1;
+    }
+  }
+
+  // Computing the degree Bounds to be stored in M[4]:
+  for (i=1;i<=nrows(S);i++)
+  {
+    dummy=1;
+    for (j=1;j<=ncols(S);j++)
+    {
+      for (k=dummy;k<dummy+T[i,j];k++)
+      {
+        maxDeg[i,k]=S[i,dummy];  // multiplicity at i-th blowup
+      }
+      dummy=k;
+    }
+  }
+  // adding up multiplicities
+  for (i=nrows(S);i>=2;i--)
+  {
+    for (j=1;j<=ncols(S);j++)
+    {
+      maxDeg[i-1,j]=maxDeg[i-1,j]+maxDeg[i,j];
+    }
+  }
+
+  list L=S,T,U,maxDeg;
+  return(L);
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+//  matrix of higher tangent directions:
+//  returns list: 1) tangent directions
+//                2) swapping information (x <--> y)
+static proc inf_Tangents(list L,int s); // L aus hnexpansion,
+{
+  int nv=nvars(basering);
+  matrix M;
+  matrix B[s][size(L)];
+  intvec V;
+  intmat Mult=multsequence(L)[1];
+
+  int i,j,k,counter,e;
+  for (k=1;k<=size(L);k++)
+  {
+    V[k]=L[k][3];  // switch: 0 --> tangent 2nd parameter
+                   //         1 --> tangent 1st parameter
+    e=0;
+    M=L[k][1];
+    counter=1;
+    B[counter,k]=M[1,1];
+
+    for (i=1;i<=nrows(M);i++)
+    {
+      for (j=2;j<=ncols(M);j++)
+      {
+        counter=counter+1;
+        if (M[i,j]==var(nv-1))
+        {
+          if (i<>nrows(M))
+          {
+            B[counter,k]=M[i,j];
+            j=ncols(M)+1; // goto new row of HNmatrix...
+            if (counter<>s)
+            {
+              if (counter+1<=nrows(Mult))
+              {
+                e=Mult[counter-1,k]-Mult[counter,k]-Mult[counter+1,k];
+              }
+              else
+              {
+                e=Mult[counter-1,k]-Mult[counter,k]-1;
+              }
+            }
+          }
+          else
+          {
+            B[counter,k]=0;
+            j=ncols(M)+1; // goto new row of HNmatrix...
+          }
+        }
+        else
+        {
+          if (e<=0)
+          {
+            B[counter,k]=M[i,j];
+          }
+          else  // point is still proximate to an earlier point
+          {
+            B[counter,k]=y; // marking proximity (without swap....)
+            if (counter+1<=nrows(Mult))
+            {
+              e=e-Mult[counter+1,k];
+            }
+            else
+            {
+              e=e-1;
+            }
+          }
+        }
+
+        if (counter==s) // given number of points determined
+        {
+            j=ncols(M)+1;
+            i=nrows(M)+1;
+            // leave procedure
+        }
+      }
+    }
+  }
+  L=B,V;
+  return(L);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// compute "good" upper bound for needed number of help variables
+//
+static proc Determine_no_b(intmat U,matrix B)
+// U is assumed to be 3rd output of control_Matrix
+// B is assumed to be 1st output of inf_Tangents
+{
+  int nv=nvars(basering);
+  int i,j,counter;
+  for (j=1;j<=ncols(U);j++)
+  {
+    for (i=1;i<=nrows(U);i++)
+    {
+      if (U[i,j]>1)
+      {
+        if (B[i,j]<>var(nv-1) and B[i,j]<>var(nv))
+        {
+          counter=counter+1;
+        }
+      }
+
+    }
+  }
+  counter=counter+ncols(U);
+  return(counter);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// compute number of infinitely near free points corresponding to non-zero
+// entries in control_Matrix[1] (except first row)
+//
+static proc no_freePoints(intmat Mult,matrix B)
+// Mult is assumed to be 1st output of control_Matrix
+// U is assumed to be 3rd output of control_Matrix
+// B is assumed to be 1st output of inf_Tangents
+{
+  int i,j,k,counter;
+  for (j=1;j<=ncols(Mult);j++)
+  {
+    for (i=2;i<=nrows(Mult);i++)
+    {
+      if (Mult[i,j]>=1)
+      {
+        if (B[i-1,j]<>x and B[i-1,j]<>y)
+        {
+          counter=counter+1;
+        }
+      }
+    }
+  }
+  return(counter);
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+// COMPUTES string(minpoly) and substitutes the parameter by newParName
+static proc makeMinPolyString (string newParName)
+{
+  int i;
+  string parName = parstr(basering);
+  int parNameSize = size(parName);
+
+  string oldMinPolyStr = string (minpoly);
+  int minPolySize = size(oldMinPolyStr);
+
+  string newMinPolyStr = "";
+
+  for (i=1;i <= minPolySize; i++)
+  {
+    if (oldMinPolyStr[i,parNameSize] == parName)
+    {
+      newMinPolyStr = newMinPolyStr + newParName;
+      i = i + parNameSize-1;
+    }
+    else
+    {
+      newMinPolyStr = newMinPolyStr + oldMinPolyStr[i];
+    }
+  }
+
+  return(newMinPolyStr);
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// DEFINES: A new basering, "myRing",
+//          with new names for the parameters and variables.
+//          The new names for the parameters are a(1..k),
+//          and t(1..s),x,y for the variables
+//          The ring ordering is ordStr.
+// NOTE:    This proc uses 'execute'.
+static proc createMyRing_new(poly p_F, string ordStr,
+                                string minPolyStr, int no_b)
+{
+  def r_old = basering;
+
+  int chara = char(basering);
+  string charaStr;
+  int i;
+  string helpStr;
+  int nDefParams = nvars(r_old)-2;
+
+  ideal qIdeal = ideal(basering);
+
+  if ((npars(basering)==0) and (minPolyStr==""))
+  {
+    helpStr = "ring myRing1 ="
+              + string(chara)+ ", (t(1..nDefParams), x, y),("+ ordStr +");";
+    execute(helpStr);
+  }
+  else
+  {
+    charaStr = charstr(basering);
+    if ((charaStr == string(chara) + "," + parstr(basering)) or (minPolyStr<>""))
+    {
+      if (minPolyStr<>"")
+      {
+        helpStr = "ring myRing1 =
+                 (" + string(chara) + ",a),
+                 (t(1..nDefParams), x, y),(" + ordStr + ");";
+        execute(helpStr);
+
+        execute (minPolyStr);
+      }
+      else // no minpoly given
+      {
+        helpStr = "ring myRing1 =
+                  (" + string(chara) + ",a(1..npars(basering)) ),
+                  (t(1..nDefParams), x, y),(" + ordStr + ");";
+        execute(helpStr);
+      }
+    }
+    else
+    {
+      // ground field is of type (p^k,a)....
+      i = find (charaStr,",");
+      helpStr = "ring myRing1 = (" + charaStr[1,i] + "a),
+              (t(1..nDefParams), x, y),(" + ordStr + ");";
+      execute (helpStr);
+    }
+  }
+
+  ideal mIdeal = maxideal(1);
+  ideal qIdeal = fetch(r_old, qIdeal);
+  poly p_F = fetch(r_old, p_F);
+  export p_F,mIdeal;
+
+  // Extension by no_b auxiliary variables
+  if (no_b>0)
+  {
+    if (npars(basering) == 0)
+    {
+      ordStr = "(dp("+string(no_b)+"),"+ordStr+")";
+      helpStr = "ring myRing ="
+                + string(chara)+ ", (b(1..no_b), t(1..nDefParams), x, y),"
+                + ordStr +";";
+      execute(helpStr);
+    }
+    else
+    {
+      charaStr = charstr(basering);
+      if (charaStr == string(chara) + "," + parstr(basering))
+      {
+        if (minpoly !=0)
+        {
+          ordStr = "(dp(" + string(no_b) + ")," + ordStr + ")";
+          minPolyStr = makeMinPolyString("a");
+          helpStr = "ring myRing =
+                   (" + string(chara) + ",a),
+                   (b(1..no_b), t(1..nDefParams), x, y)," + ordStr + ";";
+          execute(helpStr);
+
+          helpStr = "minpoly =" + minPolyStr + ";";
+          execute (helpStr);
+        }
+        else // no minpoly given
+        {
+          ordStr = "(dp(" + string(no_b) + ")," + ordStr + ")";
+          helpStr = "ring myRing =
+                    (" + string(chara) + ",a(1..npars(basering)) ),
+                    (b(1..no_b), t(1..nDefParams), x, y)," + ordStr + ";";
+          execute(helpStr);
+        }
+      }
+      else
+      {
+        i = find (charaStr,",");
+        ordStr = "(dp(" + string(no_b) + ")," + ordStr + ")";
+        helpStr = "ring myRing =
+                (" + charaStr[1,i] + "a),
+                (b(1..no_b), t(1..nDefParams), x, y)," + ordStr + ";";
+        execute (helpStr);
+      }
+    }
+    ideal qIdeal = imap(myRing1, qIdeal);
+
+    if(size(qIdeal) != 0)
+    {
+      def r_base = basering;
+      setring r_base;
+      kill myRing;
+      qring myRing = std(qIdeal);
+    }
+
+    poly p_F = imap(myRing1, p_F);
+    ideal mIdeal = imap(myRing1, mIdeal);
+    export p_F,mIdeal;
+    kill myRing1;
+  }
+  else
+  {
+    if(size(qIdeal) != 0)
+    {
+      def r_base = basering;
+      setring r_base;
+      kill myRing1;
+      qring myRing = std(qIdeal);
+      poly p_F = imap(myRing1, p_F);
+      ideal mIdeal = imap(myRing1, mIdeal);
+      export p_F,mIdeal;
+    }
+    else
+    {
+      def myRing=myRing1;
+    }
+    kill myRing1;
+  }
+
+  setring r_old;
+  return(myRing);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// returns list of coef, leadmonomial
+//
+static proc determine_coef (poly Fm)
+{
+  def r_base = basering; // is assumed to be the result of createMyRing
+
+  int chara = char(basering);
+  string charaStr;
+  int i;
+  string minPolyStr = "";
+  string helpStr = "";
+
+  if (npars(basering) == 0)
+  {
+    helpStr = "ring myRing1 ="
+              + string(chara)+ ", (y,x),ds;";
+    execute(helpStr);
+  }
+  else
+  {
+    charaStr = charstr(basering);
+    if (charaStr == string(chara) + "," + parstr(basering))
+    {
+      if (minpoly !=0)
+      {
+        minPolyStr = makeMinPolyString("a");
+        helpStr = "ring myRing1 = (" + string(chara) + ",a), (y,x),ds;";
+        execute(helpStr);
+
+        helpStr = "minpoly =" + minPolyStr + ";";
+        execute (helpStr);
+      }
+      else // no minpoly given
+      {
+        helpStr = "ring myRing1 =
+                  (" + string(chara) + ",a(1..npars(basering)) ), (y,x),ds;";
+        execute(helpStr);
+      }
+    }
+    else
+    {
+      i = find (charaStr,",");
+
+      helpStr = " ring myRing1 = (" + charaStr[1,i] + "a), (y,x),ds;";
+      execute (helpStr);
+    }
+  }
+  poly f=imap(r_base,Fm);
+  poly g=leadmonom(f);
+  setring r_base;
+  poly g=imap(myRing1,g);
+  kill myRing1;
+  def M=coef(Fm,xy);
+
+  for (i=1; i<=ncols(M); i++)
+  {
+    if (M[1,i]==g)
+    {
+      poly h=M[2,i];  // determine coefficient of leading monomial (in K[t])
+      i=ncols(M)+1;
+    }
+  }
+  return(list(h,g));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// RETURNS: 1, if p_f = 0 or char(basering) divides the order of p_f
+//             or p_f is not squarefree.
+//          0, otherwise
+static proc checkPoly (poly p_f)
+{
+  int i_print = printlevel - voice + 3;
+  int i_ord;
+
+  if (p_f == 0)
+  {
+    print("Input is a 'deformation'  of the zero polynomial!");
+    return(1);
+  }
+
+  i_ord = mindeg1(p_f);
+
+  if (number(i_ord) == 0)
+  {
+    print("Characteristic of coefficient field "
+            +"divides order of zero-fiber !");
+    return(1);
+  }
+
+  if (squarefree(p_f) != p_f)
+  {
+    print("Original polynomial (= zero-fiber) is not reduced!");
+    return(1);
+  }
+
+  return(0);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+static proc make_ring_small(ideal J)
+// returns varstr for new ring, the map and the number of vars
+{
+  attrib(J,"isSB",1);
+  int counter=0;
+  ideal newmap;
+  string newvar="";
+  for (int i=1; i<=nvars(basering); i++)
+  {
+    if (reduce(var(i),J)<>0)
+    {
+      newmap[i]=var(i);
+
+      if (newvar=="")
+      {
+        newvar=newvar+string(var(i));
+        counter=counter+1;
+      }
+      else
+      {
+        newvar=newvar+","+string(var(i));
+        counter=counter+1;
+      }
+    }
+    else
+    {
+      newmap[i]=0;
+    }
+  }
+  list L=newvar,newmap,counter;
+  attrib(J,"isSB",0);
+  return(L);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//  The following procedure is called by esStratum (typ=0), resp. by
+//  isEquising (typ=1)
+///////////////////////////////////////////////////////////////////////////////
+
+static proc esComputation (int typ, poly p_F, list #)
+{
+  intvec ov=option(get);  // store options set at beginning
+  option(redSB);
+  // Initialize variables
+  int branch=1;
+  int blowup=1;
+  int auxVar=1;
+  int nVars;
+
+  intvec upper_bound, upper_bound_old, fertig, soll;
+  list blowup_string;
+  int i_print= printlevel-voice+2;
+
+  int no_b, number_of_branches, swapped;
+  int i,j,k,m, counter, dummy;
+  string helpStr = "";
+  string ordStr = "";
+  string MinPolyStr = "";
+
+  if (nvars(basering)<=2)
+  {
+    print("family is trivial (no deformation parameters)!");
+    if (typ==1) //isEquising
+    {
+      option(set,ov);
+      return(1);
+    }
+    else
+    {
+      option(set,ov);
+      return(list(ideal(0),0));
+    }
+  }
+
+  if (size(#)>0)
+  {
+    if (typeof(#[1])=="int")
+    {
+      def artin_bd=#[1];  // compute modulo maxideal(artin_bd)
+      if (artin_bd <= 1)
+      {
+        print("Do you really want to compute over Basering/maxideal("
+              +string(artin_bd)+") ?");
+        print("No computation performed !");
+        if (typ==1) //isEquising
+        {
+          option(set,ov);
+          return(1);
+        }
+        else
+        {
+          option(set,ov);
+          return(list(ideal(0),int(1)));
+        }
+      }
+      if (size(#)>1)
+      {
+        if (typeof(#[2])=="list")
+        {
+          def @L=#[2];  // is assumed to be the Hamburger-Noether matrix
+        }
+      }
+    }
+    else
+    {
+      if (typeof(#)=="list")
+      {
+        def @L=#;  // is assumed to be the Hamburger-Noether matrix
+      }
+    }
+  }
+  int ring_is_changed;
+  def old_ring=basering;
+  if(defined(@L)<=0)
+  {
+    // define a new ring without deformation-parameters and change to it:
+    string str;
+    string minpolyStr = string(minpoly);
+    str = " ring HNERing = (" + charstr(basering) + "), (x,y), ls;";
+    execute (str);
+    if (minpolyStr!="0")
+    {str = "minpoly ="+ minpolyStr+";";execute(str);}
+    ring_is_changed=1;
+    // Basering changed to HNERing (variables x,y, with ls ordering)
+
+    k=nvars(old_ring);
+    matrix Map_Phi[1][k];
+    Map_Phi[1,k-1]=x;
+    Map_Phi[1,k]=y;
+    map phi=old_ring,Map_Phi;
+    poly f=phi(p_F);
+
+    // Heuristics: if x,y are transversal parameters then computation of HNE
+    // can be much faster when exchanging variables...!
+    if (2*size(coeffs(f,x))<size(coeffs(f,y)))
+    {
+      swapped=1;
+      f=swapXY(f);
+    }
+
+    int error=checkPoly(f);
+    if (error)
+    {
+      setring old_ring;
+      if (typ==1) //isEquising
+      {
+        print("Return value (=0) has no meaning!");
+        option(set,ov);
+        return(0);
+      }
+      else
+      {
+        option(set,ov);
+        return(list( ideal(0),error));
+      }
+    }
+
+    dbprint(i_print,"// ");
+    dbprint(i_print,"// Compute HN expansion");
+    dbprint(i_print,"// ---------------------");
+    i=printlevel;
+    printlevel=printlevel-5;
+    list LLL=hnexpansion(f);
+
+    if (size(LLL)==0) { // empty list returned by hnexpansion
+      setring old_ring;
+      print(i_print,"Unable to compute HN expansion !");
+      if (typ==1) //isEquising
+      {
+        print("Return value (=0) has no meaning!");
+        option(set,ov);
+        return(0);
+      }
+      else
+      {
+        option(set,ov);
+        return(list(ideal(0),int(1)));
+      }
+      option(set,ov);
+      return(0);
+    }
+    else
+    {
+      if (typeof(LLL[1])=="ring") {
+        def HNering = LLL[1];
+        setring HNering;
+        def @L=stripHNE(hne);
+      }
+      else {
+        def @L=stripHNE(LLL);
+      }
+    }
+    printlevel=i;
+    dbprint(i_print,"// finished");
+    dbprint(i_print,"// ");
+  }
+  def HNEring=basering;
+  list M=multsequence(@L);
+  M=control_Matrix(M);     // this returns the 4 control matrices
+  def maxDeg=M[4];
+
+  list L1=inf_Tangents(@L,nrows(M[1]));
+  matrix B=L1[1];
+  intvec V=L1[2];
+  kill L1;
+
+  // if we have computed the HNE for f after swapping x and y, we have
+  // to reinterprete the (swap) matrix V:
+  if (swapped==1)
+  {
+    for (i=1;i<=size(V);i++) { V[i]=V[i]-1; } // turns 0 into -1, 1 into 0
+  }
+
+  // Determine maximal number of needed auxiliary parameters (free tangents):
+  no_b=Determine_no_b(M[3],B);
+
+  // test whether HNexpansion needed field extension....
+  string minPolyStr = "";
+  if (minpoly !=0)
+  {
+    minPolyStr = makeMinPolyString("a");
+    minPolyStr = "minpoly =" + minPolyStr + ";";
+  }
+
+  setring old_ring;
+
+  def myRing=createMyRing_new(p_F,"dp",minPolyStr,no_b);
+  setring myRing;  // comes with mIdeal
+  map hole=HNEring,mIdeal;
+  // basering has changed to myRing, in particular, the "old"
+  // variable names, e.g., A,B,C,z,y are replaced by t(1),t(2),t(3),x,y
+
+  ideal bNodes;
+
+  // Initialize some variables:
+  map phi;
+  poly G, F_save;
+  poly b_dummy;
+  ideal J,Jnew,final_Map;
+  number_of_branches=ncols(M[1]);
+  for (i=1;i<=number_of_branches;i++)
+  {
+    poly F(i);
+    ideal bl_Map(i);
+  }
+  upper_bound[number_of_branches]=0;
+  upper_bound[1]=number_of_branches;
+  upper_bound_old=upper_bound;
+  fertig[number_of_branches]=0;
+  for (i=1;i<=number_of_branches;i++){ soll[i]=1; }
+
+  // Hole:  B = matrix of blowup points
+  if (ring_is_changed==0) { matrix B=hole(B); }
+  else                    { matrix B=imap(HNEring,B); }
+  m=M[1][blowup,branch];    // multiplicity at 0
+
+  // now, we start by checking equimultiplicity along trivial section
+  poly Fm=m_Jet(p_F,m-1);
+
+  matrix coef_Mat = coef(Fm,xy);
+  Jnew=coef_Mat[2,1..ncols(coef_Mat)];
+  J=J,Jnew;
+
+  if (defined(artin_bd)) // the artin_bd-th power of the maxideal of
+                         // deformation parameters can be cutted off
+  {
+    J=jet(J,artin_bd-1);
+  }
+
+  J=interred(J);
+  if (defined(artin_bd)) { J=jet(J,artin_bd-1); }
+
+// J=std(J);
+
+  if (typ==1) // isEquising
+  {
+    if(ideal(nselect(J,1..no_b))<>0)
+    {
+      setring old_ring;
+      option(set,ov);
+      return(0);
+    }
+  }
+
+  F(1)=p_F;
+
+  // and reduce the remaining terms in F(1):
+  bl_Map(1)=maxideal(1);
+
+  attrib(J,"isSB",1);
+  bl_Map(1)=reduce(bl_Map(1),J);
+  attrib(J,"isSB",0);
+
+  phi=myRing,bl_Map(1);
+  F(1)=phi(F(1));
+
+  // simplify F(1)
+  attrib(J,"isSB",1);
+  F(1)=reduce(F(1),J);
+  attrib(J,"isSB",0);
+
+  // now we compute the m-jet:
+  Fm=m_Jet(F(1),m);
+
+  G=1;
+  counter=branch;
+  k=upper_bound[branch];
+
+  F_save=F(1);  // is truncated differently in the following loop
+
+  while(counter<=k)
+  {
+    F(counter)=m_Jet(F_save,maxDeg[blowup,counter]);
+    if (V[counter]==0) // 2nd ring variable is tangent to this branch
+    {
+      G=G*(y-(b(auxVar)+B[blowup,counter])*x)^(M[3][blowup,counter]);
+    }
+    else // 1st ring variable is tangent to this branch
+    {
+      G=G*(x-(b(auxVar)+B[blowup,counter])*y)^(M[3][blowup,counter]);
+      F(counter)=swapXY(F(counter));
+    }
+    bl_Map(counter)=maxideal(1);
+    bl_Map(counter)[nvars(basering)]=xy+(b(auxVar)+B[blowup,counter])*x;
+
+    bNodes[counter]=b(auxVar);
+
+    auxVar=auxVar+1;
+    upper_bound[counter]=counter+M[2][blowup+1,counter]-1;
+    counter=counter+M[2][blowup+1,counter];
+
+  }
+
+  list LeadDataFm=determine_coef(Fm);
+  def LeadDataG=coef(G,xy);
+
+  for (i=1; i<=ncols(LeadDataG); i++)
+  {
+    if (LeadDataG[1,i]==LeadDataFm[2])
+    {
+      poly LeadG = LeadDataG[2,i];  // determine the coefficient of G
+      i=ncols(LeadDataG)+1;
+    }
+  }
+
+  G=LeadDataFm[1]*G-LeadG*Fm;  // leading terms in y should cancel...
+
+  coef_Mat = coef(G,xy);
+  Jnew=coef_Mat[2,1..ncols(coef_Mat)];
+
+  // simplification of Jnew
+
+  if (defined(artin_bd)) // the artin_bd-th power of the maxideal of
+                         // deformation parameters can be cutted off
+  {
+    Jnew=jet(Jnew,artin_bd-1);
+  }
+  Jnew=interred(Jnew);
+  if (defined(artin_bd)) { Jnew=jet(Jnew,artin_bd-1); }
+  J=J,Jnew;
+
+  if (typ==1) // isEquising
+  {
+    if(ideal(nselect(J,1..no_b))<>0)
+    {
+      setring old_ring;
+      option(set,ov);
+      return(0);
+    }
+  }
+
+  while (fertig<>soll and blowup<nrows(M[3]))
+  {
+    upper_bound_old=upper_bound;
+    dbprint(i_print,"// Blowup Step "+string(blowup)+" completed");
+    blowup=blowup+1;
+
+    for (branch=1;branch<=number_of_branches;branch=branch+1)
+    {
+      Jnew=0;
+
+      // First we check if the branch still has to be considered:
+      if (branch==upper_bound_old[branch] and fertig[branch]<>1)
+      {
+        if (M[3][blowup-1,branch]==1 and
+               ((B[blowup,branch]<>x and B[blowup,branch]<>y)
+            or (blowup==nrows(M[3])) ))
+        {
+          fertig[branch]=1;
+          dbprint(i_print,"// 1 branch finished");
+        }
+      }
+
+      if (branch<=upper_bound_old[branch] and fertig[branch]<>1)
+      {
+        for (i=branch;i>=1;i--)
+        {
+          if (M[1][blowup-1,i]<>0)
+          {
+            m=M[1][blowup-1,i]; // multiplicity before blowup
+            i=0;
+          }
+        }
+
+        // we blow up the branch and take the strict transform:
+        attrib(J,"isSB",1);
+        bl_Map(branch)=reduce(bl_Map(branch),J);
+        attrib(J,"isSB",0);
+
+        phi=myRing,bl_Map(branch);
+        F(branch)=phi(F(branch))/x^m;
+
+        // simplify F
+        attrib(Jnew,"isSB",1);
+
+        F(branch)=reduce(F(branch),Jnew);
+        attrib(Jnew,"isSB",0);
+
+        m=M[1][blowup,branch]; // multiplicity after blowup
+        Fm=m_Jet(F(branch),m); // homogeneous part of lowest degree
+
+
+        // we check for Fm=F[k]*...*F[k+s] where
+        //
+        //    F[j]=(y-b'(j)*x)^m(j), respectively F[j]=(-b'(j)*y+x)^m(j)
+        //
+        // according to the entries m(j)= M[3][blowup,j] and
+        //                          b'(j) mod m_A = B[blowup,j]
+        // computed from the HNE of the special fibre of the family:
+        G=1;
+        counter=branch;
+        k=upper_bound[branch];
+
+        F_save=F(branch);
+
+        while(counter<=k)
+        {
+          F(counter)=m_Jet(F_save,maxDeg[blowup,counter]);
+
+          if (B[blowup,counter]<>x and B[blowup,counter]<>y)
+          {
+            G=G*(y-(b(auxVar)+B[blowup,counter])*x)^(M[3][blowup,counter]);
+            bl_Map(counter)=maxideal(1);
+            bl_Map(counter)[nvars(basering)]=
+                                        xy+(b(auxVar)+B[blowup,counter])*x;
+            bNodes[counter]=b(auxVar);
+            auxVar=auxVar+1;
+          }
+          else
+          {
+            if (B[blowup,counter]==x)
+            {
+              G=G*x^(M[3][blowup,counter]);  // branch has tangent x !!
+              F(counter)=swapXY(F(counter)); // will turn x to y for blow up
+              bl_Map(counter)=maxideal(1);
+              bl_Map(counter)[nvars(basering)]=xy;
+            }
+            else
+            {
+              G=G*y^(M[3][blowup,counter]); // tangent has to be y
+              bl_Map(counter)=maxideal(1);
+              bl_Map(counter)[nvars(basering)]=xy;
+            }
+            bNodes[counter]=0;
+          }
+          upper_bound[counter]=counter+M[2][blowup+1,counter]-1;
+          counter=counter+M[2][blowup+1,counter];
+        }
+        G=determine_coef(Fm)[1]*G-Fm;  // leading terms in y should cancel
+        coef_Mat = coef(G,xy);
+        Jnew=coef_Mat[2,1..ncols(coef_Mat)];
+        if (defined(artin_bd)) // the artin_bd-th power of the maxideal of
+                              // deformation parameters can be cutted off
+        {
+          Jnew=jet(Jnew,artin_bd-1);
+        }
+
+        // simplification of J
+        Jnew=interred(Jnew);
+
+        J=J,Jnew;
+        if (typ==1) // isEquising
+        {
+          if (defined(artin_bd)) { J=jet(Jnew,artin_bd-1); }
+          if(ideal(nselect(J,1..no_b))<>0)
+          {
+            setring old_ring;
+            option(set,ov);
+            return(0);
+          }
+        }
+      }
+    }
+    if (number_of_branches>=2)
+    {
+      J=interred(J);
+      if (typ==1) // isEquising
+      {
+        if (defined(artin_bd)) { J=jet(Jnew,artin_bd-1); }
+        if(ideal(nselect(J,1..no_b))<>0)
+        {
+          setring old_ring;
+          option(set,ov);
+          return(0);
+        }
+      }
+    }
+  }
+
+  // Computation for all equimultiple sections being trivial (I^s(f))
+  ideal Jtriv=J;
+  for (i=1;i<=no_b; i++)
+  {
+    if (reduce(b(i),std(bNodes))!=0){
+      Jtriv=subst(Jtriv,b(i),0);
+    }
+  }
+  Jtriv=std(Jtriv);
+
+
+
+  dbprint(i_print,"// ");
+  dbprint(i_print,"// Elimination starts:");
+  dbprint(i_print,"// -------------------");
+
+  poly gg;
+  int b_left=no_b;
+
+  for (i=1;i<=no_b; i++)
+  {
+    attrib(J,"isSB",1);
+    gg=reduce(b(i),J);
+    if (gg==0)
+    {
+      b_left = b_left-1;  // another b(i) has to be 0
+    }
+    J = subst(J, b(i), gg);
+    attrib(J,"isSB",0);
+  }
+  J=simplify(J,10);
+  if (typ==1) // isEquising
+  {
+    if (defined(artin_bd)) { J=jet(Jnew,artin_bd-1); }
+    if(ideal(nselect(J,1..no_b))<>0)
+    {
+      setring old_ring;
+      option(set,ov);
+      return(0);
+    }
+  }
+
+  //new CL 11/06:  check in which equations b(k) appears and remove those b(k)
+  //               which appear in exactly one of the equations (by removing this
+  //               equation)
+  dbprint(i_print,"// ");
+  dbprint(i_print,"// Remove superfluous equations:");
+  dbprint(i_print,"// -----------------------------");
+  int Z,App_in;
+  ideal J_Tmp;
+  int ncJ=ncols(J);
+
+  intmat Mdet[ncJ][1];
+  for (Z=1;Z<=ncJ;Z++){ Mdet[Z,1]=Z; }
+
+  for (i=1;i<=no_b; i++)
+  {
+    ideal b_appears_in(i);            // Eintraege sind spaeter 1 oder 0
+    intmat b_app_in(i)[1][ncJ];       // Eintraege sind spaeter 1 oder 0
+    b_appears_in(i)[ncJ]=0;
+    J_Tmp = matrix(J)-subst(J,b(i),0);
+    for (Z=1; Z<=ncJ; Z++) {
+      if (J_Tmp[Z]<>0) {      // b(i) appear in J_Tmp[Z]
+        b_appears_in(i)[Z]=1;
+        b_app_in(i)[1,Z]=1;
+      }
+    }
+    if (size(b_appears_in(i))==1) { //b(i) appears only in one J_Tmp[Z]
+      App_in = (b_app_in(i)*Mdet)[1,1];  // determines Z
+      J[App_in]=0;
+      b_appears_in(i)[App_in]=0;
+      b_app_in(i)[1,App_in]=0;
+    }
+  }
+
+  for (i=1;i<=no_b; i++)
+  {
+    if (size(b_appears_in(i))==1) { //b(i) appears only in one J_Tmp[Z]
+      App_in = (b_app_in(i)*Mdet)[1,1];  // determines Z
+      J[App_in]=0;
+      b_appears_in(i)[App_in]=0;
+      b_app_in(i)[1,Z]=1;
+      i=0;
+    }
+  }
+
+  Jtriv = nselect(Jtriv,1..no_b);
+  ideal J_no_b = nselect(J,1..no_b);
+  if (size(J) > size(J_no_b))
+  {
+    dbprint(i_print,"// std computation started");
+    // some b(i) didn't appear in linear conditions and have to be eliminated
+    if (defined(artin_bd))
+    {
+      // first we make the ring smaller (removing variables, which are
+      // forced to 0 by J
+      list LL=make_ring_small(J);
+      ideal Shortmap=LL[2];
+      minPolyStr = "";
+      if (minpoly !=0)
+      {
+        minPolyStr = "minpoly = "+string(minpoly);
+      }
+      ordStr = "dp(" + string(b_left) + "),dp";
+      ideal qId = ideal(basering);
+
+      helpStr = "ring Shortring = ("
+                + charstr(basering) + "),("+ LL[1] +") , ("+ ordStr  +");";
+      execute(helpStr);
+      execute(minPolyStr);
+      // ring has changed to "Shortring"
+
+      ideal MM=maxideal(artin_bd);
+      MM=subst(MM,x,0);
+      MM=subst(MM,y,0);
+      MM=simplify(MM,2);
+      dbprint(i_print-1,"// maxideal("+string(artin_bd)+") has "
+                         +string(size(MM))+" elements");
+      dbprint(i_print-1,"//");
+
+      // we change to the qring mod m^artin_bd
+      // first, we have to check if we were in a qring when starting
+      ideal qId = imap(myRing, qId);
+      if (qId == 0)
+      {
+         attrib(MM,"isSB",1);
+         qring QQ=MM;
+      }
+      else
+      {
+         qId=qId,MM;
+         qring QQ = std(qId);
+      }
+
+      ideal Shortmap=imap(myRing,Shortmap);
+      map phiphi=myRing,Shortmap;
+
+      ideal J=phiphi(J);
+      option(redSB);
+      J=std(J);
+      J=nselect(J,1..no_b);
+
+      setring myRing;
+      // back to "myRing"
+
+      J=nselect(J,1..no_b);
+      Jnew=imap(QQ,J);
+
+      J=J,Jnew;
+      J=interred(J);
+      if (defined(artin_bd)){ J=jet(J,artin_bd-1); }
+    }
+    else
+    {
+      J=std(J);
+      J=nselect(J,1..no_b);
+      if (defined(artin_bd)){ J=jet(J,artin_bd-1); }
+    }
+  }
+
+  dbprint(i_print,"// finished");
+  dbprint(i_print,"// ");
+
+  minPolyStr = "";option(set,ov);
+  if (minpoly !=0)
+  {
+   minPolyStr = "minpoly = "+string(minpoly);
+  }
+
+  kill HNEring;
+
+  if (typ==1) // isEquising
+  {
+    if (defined(artin_bd)) { J=jet(Jnew,artin_bd-1); }
+    if(J<>0)
+    {
+      setring old_ring;
+      option(set,ov);
+      return(0);
+    }
+    else
+    {
+      setring old_ring;
+      option(set,ov);
+      return(1);
+    }
+  }
+
+  setring old_ring;
+  // we are back in the original ring
+
+  if (npars(myRing)<>0)
+  {
+    ideal qIdeal = ideal(basering);
+    helpStr = "ring ESSring = ("
+                 + string(char(basering))+ "," + parstr(myRing) +
+                 ") , ("+ varstr(basering)+") , ("+ ordstr(basering) +");";
+    execute(helpStr);
+    execute(minPolyStr);
+    // basering has changed to ESSring
+
+    ideal qIdeal = fetch(old_ring, qIdeal);
+    if(qIdeal != 0)
+    {
+      def r_base = basering;
+      kill ESSring;
+      qring ESSring = std(qIdeal);
+    }
+    kill qIdeal;
+
+    ideal SSS;
+    for (int ii=1;ii<=nvars(basering);ii++)
+    {
+      SSS[ii+no_b]=var(ii);
+    }
+    map phi=myRing,SSS;   // b(i) variables are mapped to zero
+
+    ideal ES=phi(J);
+    ideal ES_all_triv=phi(Jtriv);
+    kill phi;
+
+    if (defined(p_F)<=0)
+    {
+      poly p_F=fetch(old_ring,p_F);
+      export(p_F);
+    }
+    export(ES);
+    export(ES_all_triv);
+    setring old_ring;
+    dbprint(i_print+2,"
+// 'esStratum' created a list M of a ring and an integer.
+// To access the ideal defining the equisingularity stratum, type:
+        def ESSring = M[1]; setring ESSring;  ES; ");
+
+    option(set,ov);
+    return(list(ESSring,0));
+  }
+  else
+  {
+    // no new ring definition necessary
+    ideal SSS;
+    for (int ii=1;ii<=nvars(basering);ii++)
+    {
+      SSS[ii+no_b]=var(ii);
+    }
+    map phi=myRing,SSS;  // b(i) variables are mapped to zero
+
+    ideal ES=phi(J);
+    ideal ES_all_triv=phi(Jtriv);
+    kill phi;
+
+    setring old_ring;
+    dbprint(i_print,"// output of 'esStratum' is a list consisting of:
+//    _[1][1] = ideal defining the equisingularity stratum
+//    _[1][2] = ideal defining the part of the equisingularity stratum
+//              where all equimultiple sections are trivial
+//    _[2] = 0");
+
+    option(set,ov);
+    return(list(list(ES,ES_all_triv),0));
+  }
+
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+proc tau_es (poly f,list #)
+"USAGE:   tau_es(f); f poly
+ASSUME:  f is a reduced bivariate polynomial, the basering has precisely
+         two variables, is local and no qring.
+RETURN:  int, the codimension of the mu-const stratum in the semi-universal
+         deformation base.
+NOTE:    printlevel>=1 displays additional information.
+         When called with any additional parameter, the computation of the
+         Milnor number is avoided (no check for NND).
+SEE ALSO: esIdeal, tjurina, invariants
+EXAMPLE: example tau_es; shows an example.
+"
+{
+  int i,j,k,s;
+  int slope_x, slope_y, upper;
+  int i_print = printlevel - voice + 3;
+  string MinPolyStr;
+
+  // some checks first
+  if ( nvars(basering)<>2 )
+  {
+    print("// basering has not the correct number (two) of variables !");
+    print("// computation stopped");
+    return(0);
+  }
+  if ( mult(std(1+var(1)+var(2))) <> 0)
+  {
+    print("// basering is not local !");
+    print("// computation stopped");
+    return(0);
+  }
+
+  if (mult(std(f))<=1)
+  {
+    // f is rigid
+    return(0);
+  }
+
+  if ( deg(squarefree(f))!=deg(f) )
+  {
+    print("// input polynomial was not reduced");
+    print("// try    squarefree(f);   first");
+    return(0);
+  }
+
+  def old_ring=basering;
+  execute("ring @myRing=("+charstr(basering)+"),("+varstr(basering)+"),ds;");
+  poly f=imap(old_ring,f);
+
+  ideal Jacobi_Id = jacob(f);
+
+  // check for A_k singularity
+  // ----------------------------------------
+  if (mult(std(f))==2)
+  {
+    dbprint(i_print-1,"// ");
+    dbprint(i_print-1,"// polynomial defined A_k singularity");
+    dbprint(i_print-1,"// ");
+    return( vdim(std(Jacobi_Id)) );
+  }
+
+  // check for D_k singularity
+  // ----------------------------------------
+  if (mult(std(f))==3 and size(factorize(jet(f,3))[1])>=3)
+  {
+    dbprint(i_print,"// ");
+    dbprint(i_print,"// polynomial defined D_k singularity");
+    dbprint(i_print,"// ");
+    ideal ES_Id = f, jacob(f);
+    return( vdim(std(Jacobi_Id)));
+  }
+
+
+  if (size(#)==0)
+  {
+    // check if Newton polygon non-degenerate
+    // ----------------------------------------
+    Jacobi_Id=std(Jacobi_Id);
+    int mu = vdim(Jacobi_Id);
+    poly f_tilde=f+var(1)^mu+var(2)^mu;  //to obtain convenient Newton-polygon
+
+    list NP=newtonpoly(f_tilde);
+    dbprint(i_print-1,"// Newton polygon:");
+    dbprint(i_print-1,NP);
+    dbprint(i_print-1,"");
+
+    if(is_NND(f,mu,NP))          // f is Newton non-degenerate
+    {
+      upper=NP[1][2];
+      ideal ES_Id= x^k*y^upper;
+      dbprint(i_print-1,"polynomial is Newton non-degenerate");
+      dbprint(i_print-1,"");
+      k=0;
+      for (i=1;i<=size(NP)-1;i++)
+      {
+        slope_x=NP[i+1][1]-NP[i][1];
+        slope_y=NP[i][2]-NP[i+1][2];
+        for (k=NP[i][1]+1; k<=NP[i+1][1]; k++)
+        {
+          while ( slope_x*upper + slope_y*k >=
+                  slope_x*NP[i][2] + slope_y*NP[i][1])
+          {
+            upper=upper-1;
+          }
+          upper=upper+1;
+          ES_Id=ES_Id, x^k*y^upper;
+        }
+      }
+      ES_Id=std(ES_Id);
+      dbprint(i_print-2,"ideal of monomials above Newton bd. is generated by:");
+      dbprint(i_print-2,ES_Id);
+      ideal ESfix_Id = ES_Id, f, maxideal(1)*jacob(f);
+      ES_Id = ES_Id, Jacobi_Id;
+      ES_Id = std(ES_Id);
+      dbprint(i_print-1,"// ");
+      dbprint(i_print-1,"// Equisingularity ideal is computed!");
+      dbprint(i_print-1,"");
+      return(vdim(ES_Id));
+    }
+    else
+    {
+      dbprint(i_print-1,"polynomial is Newton degenerate !");
+      dbprint(i_print-1,"");
+    }
+  }
+
+  // for Newton degenerate polynomials, we compute the HN expansion, and
+  // count the number of free points .....
+
+  dbprint(i_print-1,"// ");
+  dbprint(i_print-1,"// Compute HN expansion");
+  dbprint(i_print-1,"// ---------------------");
+  i=printlevel;
+  printlevel=printlevel-5;
+  if (2*size(coeffs(f,x))<size(coeffs(f,y)))
+  {
+    f=swapXY(f);
+  }
+  list LLL=hnexpansion(f);
+  if (size(LLL)==0) { // empty list returned by hnexpansion
+    setring old_ring;
+    ERROR("Unable to compute HN expansion !");
+  }
+  else
+  {
+    if (typeof(LLL[1])=="ring") {
+      def HNering = LLL[1];
+      setring HNering;
+      def @L=hne;
+    }
+    else {
+      def @L=LLL;
+    }
+  }
+  def HNEring=basering;
+
+  printlevel=i;
+  dbprint(i_print-1,"// finished");
+  dbprint(i_print-1,"// ");
+
+  list M=multsequence(@L);
+  M=control_Matrix(M);     // this returns the 4 control matrices
+  intmat Mult=M[1];
+
+  list L1=inf_Tangents(@L,nrows(M[1]));
+  matrix B=L1[1];
+
+  // determine sum_i m_i(m_i+1)/2 (over inf. near points)
+  int conditions=0;
+  for (i=1;i<=nrows(Mult);i++)
+  {
+    for (j=1;j<=ncols(Mult);j++)
+    {
+      conditions=conditions+(Mult[i,j]*(Mult[i,j]+1) div 2);
+    }
+  }
+  int freePts=no_freePoints(M[1],B);
+  int taues=conditions-freePts-2;
+
+  setring old_ring;
+  return(taues);
+}
+example
+{
+   "EXAMPLE:"; echo=2;
+   ring r=32003,(x,y),ds;
+   poly f=(x4-y4)^2-x10;
+   tau_es(f);
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+
+proc esIdeal (poly f,list #)
+"USAGE:   esIdeal(f[,any]]); f poly
+ASSUME:  f is a reduced bivariate polynomial, the basering has precisely
+         two variables, is local and no qring, and the characteristic of
+         the ground field does not divide mult(f).
+RETURN:  if called with only one parameter: list of two ideals,
+ at format
+          _[1]:  equisingularity ideal of f (in sense of Wahl),
+          _[2]:  ideal of equisingularity with fixed position of the
+                 singularity;
+ at end format
+         if called with more than one parameter: list of three ideals,
+ at format
+          _[1]:  equisingularity ideal of f (in sense of Wahl)
+          _[2]:  ideal of equisingularity with fixed position of the
+                 singularity;
+          _[3]:  ideal of all g such that the deformation defined by f+eg
+                 (e^2=0) is isomorphic to an equisingular deformation
+                 of V(f) with all equimultiple sections being trivial.
+ at end format
+NOTE:    if some of the above condition is not satisfied then return
+         value is list(0,0).
+SEE ALSO: tau_es, esStratum
+KEYWORDS: equisingularity ideal
+EXAMPLE: example esIdeal; shows examples.
+"
+{
+
+  int typ;
+  if (size(#)>0) { typ=1; }   // I^s is also computed
+  int i,k,s;
+  int slope_x, slope_y, upper;
+  int i_print = printlevel - voice + 3;
+  string MinPolyStr;
+
+  // some checks first
+  if ( nvars(basering)<>2 )
+  {
+    print("// basering has not the correct number (two) of variables !");
+    print("// computation stopped");
+    return(list(0,0));
+  }
+  if ( mult(std(1+var(1)+var(2))) <> 0)
+  {
+    print("// basering is not local !");
+    print("// computation stopped");
+    return(list(0,0));
+  }
+
+  if (mult(std(f))<=1)
+  {
+    // f is rigid
+    if (typ==0)
+    {
+      return(list(ideal(1),ideal(1)));
+    }
+    else
+    {
+      return(list(ideal(1),ideal(1),ideal(1)));
+    }
+  }
+
+  if ( deg(squarefree(f))!=deg(f) )
+  {
+    print("// input polynomial was not squarefree");
+    print("// try    squarefree(f);   first");
+    return(list(0,0));
+  }
+
+  if (char(basering)<>0)
+  {
+    if (mult(std(f)) mod char(basering)==0)
+    {
+      print("// characteristic of ground field divides "
+            + "multiplicity of polynomial !");
+      print("// computation stopped");
+      return(list(0,0));
+    }
+  }
+
+  // check for A_k singularity
+  // ----------------------------------------
+  if (mult(std(f))==2)
+  {
+    dbprint(i_print,"// ");
+    dbprint(i_print,"// polynomial defined A_k singularity");
+    dbprint(i_print,"// ");
+    ideal ES_Id = f, jacob(f);
+    ES_Id = interred(ES_Id);
+    ideal ESfix_Id = f, maxideal(1)*jacob(f);
+    ESfix_Id= interred(ESfix_Id);
+    if (typ==0) // only for computation of I^es and I^es_fix
+    {
+      return( list(ES_Id,ESfix_Id) );
+    }
+    else
+    {
+      return( list(ES_Id,ESfix_Id,ES_Id) );
+    }
+  }
+
+  // check for D_k singularity
+  // ----------------------------------------
+  if (mult(std(f))==3 and size(factorize(jet(f,3))[1])>=3)
+  {
+    dbprint(i_print,"// ");
+    dbprint(i_print,"// polynomial defined D_k singularity");
+    dbprint(i_print,"// ");
+    ideal ES_Id = f, jacob(f);
+    ES_Id = interred(ES_Id);
+    ideal ESfix_Id = f, maxideal(1)*jacob(f);
+    ESfix_Id= interred(ESfix_Id);
+    if (typ==0) // only for computation of I^es and I^es_fix
+    {
+      return( list(ES_Id,ESfix_Id) );
+    }
+    else
+    {
+      return( list(ES_Id,ESfix_Id,ES_Id) );
+    }
+  }
+
+  // check if Newton polygon non-degenerate
+  // ----------------------------------------
+  int mu = milnor(f);
+  poly f_tilde=f+var(1)^mu+var(2)^mu;  //to obtain a convenient Newton-polygon
+
+  list NP=newtonpoly(f_tilde);
+  dbprint(i_print-1,"// Newton polygon:");
+  dbprint(i_print-1,NP);
+  dbprint(i_print-1,"");
+
+  if(is_NND(f,mu,NP))          // f is Newton non-degenerate
+  {
+    upper=NP[1][2];
+    ideal ES_Id= x^k*y^upper;
+    dbprint(i_print,"polynomial is Newton non-degenerate");
+    dbprint(i_print,"");
+    k=0;
+    for (i=1;i<=size(NP)-1;i++)
+    {
+      slope_x=NP[i+1][1]-NP[i][1];
+      slope_y=NP[i][2]-NP[i+1][2];
+      for (k=NP[i][1]+1; k<=NP[i+1][1]; k++)
+      {
+        while ( slope_x*upper + slope_y*k >=
+                slope_x*NP[i][2] + slope_y*NP[i][1])
+        {
+          upper=upper-1;
+        }
+        upper=upper+1;
+        ES_Id=ES_Id, x^k*y^upper;
+      }
+    }
+    ES_Id=std(ES_Id);
+    dbprint(i_print-1,"ideal of monomials above Newton bd. is generated by:");
+    dbprint(i_print-1,ES_Id);
+    ideal ESfix_Id = ES_Id, f, maxideal(1)*jacob(f);
+    ES_Id = ES_Id, f, jacob(f);
+    dbprint(i_print,"// ");
+    dbprint(i_print,"// equisingularity ideal is computed!");
+    if (typ==0)
+    {
+      return(list(ES_Id,ESfix_Id));
+    }
+    else
+    {
+      return(list(ES_Id,ESfix_Id,ES_Id));
+    }
+  }
+  else
+  {
+    dbprint(i_print,"polynomial is Newton degenerate !");
+    dbprint(i_print,"");
+  }
+
+  def old_ring=basering;
+
+  dbprint(i_print,"// ");
+  dbprint(i_print,"// versal deformation with triv. section");
+  dbprint(i_print,"// =====================================");
+  dbprint(i_print,"// ");
+
+  ideal JJ=maxideal(1)*jacob(f);
+  ideal kbase_versal=kbase(std(JJ));
+  s=size(kbase_versal);
+  string ring_versal="ring @Px = ("+charstr(basering)+"),(t(1.."+string(s)+"),"
+                        +varstr(basering)+"),(ds("+string(s)+"),"
+                        +ordstr(basering)+");";
+  MinPolyStr = string(minpoly);
+
+  execute(ring_versal);
+  if (MinPolyStr<>"0")
+  {
+    MinPolyStr = "minpoly="+MinPolyStr;
+    execute(MinPolyStr);
+  }
+  // basering has changed to @Px
+
+  poly F=imap(old_ring,f);
+  ideal kbase_versal=imap(old_ring,kbase_versal);
+  for (i=1; i<=s; i++)
+  {
+    F=F+var(i)*kbase_versal[i];
+  }
+  dbprint(i_print-1,F);
+  dbprint(i_print-1,"");
+
+
+  ideal ES_Id,ES_Id_all_triv;
+  poly Ftriv=F;
+
+  dbprint(i_print,"// ");
+  dbprint(i_print,"// Compute equisingularity Stratum over Spec(C[t]/t^2)");
+  dbprint(i_print,"// ===================================================");
+  dbprint(i_print,"// ");
+  list M=esStratum(F,2);
+  dbprint(i_print,"// finished");
+  dbprint(i_print,"// ");
+
+  if (M[2]==1) // error occured during esStratum computation
+  {
+    print("Some error has occured during the computation");
+    return(list(0,0));
+  }
+
+  if ( typeof(M[1])=="list" )
+  {
+    int defpars = nvars(basering)-2;
+    poly Fred,Ftrivred;
+    poly g;
+    F=reduce(F,std(M[1][1]));
+    Ftriv=reduce(Ftriv,std(M[1][2]));
+
+    for (i=1; i<=defpars; i++)
+    {
+      Fred=reduce(F,std(var(i)));
+      Ftrivred=reduce(Ftriv,std(var(i)));
+
+      g=subst(F-Fred,var(i),1);
+      ES_Id=ES_Id, g;
+      F=Fred;
+
+      g=subst(Ftriv-Ftrivred,var(i),1);
+      ES_Id_all_triv=ES_Id_all_triv, g;
+      Ftriv=Ftrivred;
+    }
+
+    setring old_ring;
+    // back to original ring
+
+    ideal ES_Id = imap(@Px,ES_Id);
+    ES_Id = interred(ES_Id);
+
+    ideal ES_Id_all_triv = imap(@Px,ES_Id_all_triv);
+    ES_Id_all_triv = interred(ES_Id_all_triv);
+
+    ideal ESfix_Id = ES_Id, f, maxideal(1)*jacob(f);
+    ES_Id = ES_Id, f, jacob(f);
+    ES_Id_all_triv = ES_Id_all_triv, f, jacob(f);
+
+    if (typ==0)
+    {
+      return(list(ES_Id,ESfix_Id));
+    }
+    else
+    {
+      return(list(ES_Id,ESfix_Id,ES_Id_all_triv));
+    }
+  }
+  else
+  {
+    def AuxRing=M[1];
+
+    dbprint(i_print,"// ");
+    dbprint(i_print,"// change ring to ESSring");
+
+    setring AuxRing;  // contains p_F, ES
+
+    int defpars = nvars(basering)-2;
+    poly Fred,Fredtriv;
+    poly g;
+    ideal ES_Id,ES_Id_all_triv;
+
+    poly p_Ftriv=p_F;
+
+    p_F=reduce(p_F,std(ES));
+    p_Ftriv=reduce(p_Ftriv,std(ES_all_triv));
+    for (i=1; i<=defpars; i++)
+    {
+      Fred=reduce(p_F,std(var(i)));
+      Fredtriv=reduce(p_Ftriv,std(var(i)));
+
+      g=subst(p_F-Fred,var(i),1);
+      ES_Id=ES_Id, g;
+      p_F=Fred;
+
+      g=subst(p_Ftriv-Fredtriv,var(i),1);
+      ES_Id_all_triv=ES_Id_all_triv, g;
+      p_Ftriv=Fredtriv;
+
+    }
+
+    dbprint(i_print,"// ");
+    dbprint(i_print,"// back to the original ring");
+
+    setring old_ring;
+    // back to original ring
+
+    ideal ES_Id = imap(AuxRing,ES_Id);
+    ES_Id = interred(ES_Id);
+
+    ideal ES_Id_all_triv = imap(AuxRing,ES_Id_all_triv);
+    ES_Id_all_triv = interred(ES_Id_all_triv);
+
+    kill @Px;
+    kill AuxRing;
+
+    ideal ESfix_Id = ES_Id, f, maxideal(1)*jacob(f);
+    ES_Id = ES_Id, f, jacob(f);
+    ES_Id_all_triv = ES_Id_all_triv, f, jacob(f);
+    dbprint(i_print,"// ");
+    dbprint(i_print,"// equisingularity ideal is computed!");
+    if (typ==0)
+    {
+      return(list(ES_Id,ESfix_Id));
+    }
+    else
+    {
+      return(list(ES_Id,ESfix_Id,ES_Id_all_triv));
+    }
+  }
+}
+example
+{
+  "EXAMPLE:"; echo=2;
+  ring r=0,(x,y),ds;
+  poly f=x7+y7+(x-y)^2*x2y2;
+  list K=esIdeal(f);
+  option(redSB);
+  // Wahl's equisingularity ideal:
+  std(K[1]);
+
+  ring rr=0,(x,y),ds;
+  poly f=x4+4x3y+6x2y2+4xy3+y4+2x2y15+4xy16+2y17+xy23+y24+y30+y31;
+  list K=esIdeal(f);
+  vdim(std(K[1]));
+  // the latter should be equal to:
+  tau_es(f);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc esStratum (poly p_F, list #)
+"USAGE:   esStratum(F[,m,L]); F poly, m int, L list
+ASSUME:  F defines a deformation of a reduced bivariate polynomial f
+         and the characteristic of the basering does not divide mult(f). @*
+         If nv is the number of variables of the basering, then the first
+         nv-2 variables are the deformation parameters. @*
+         If the basering is a qring, ideal(basering) must only depend
+         on the deformation parameters.
+COMPUTE: equations for the stratum of equisingular deformations with
+         fixed (trivial) section.
+RETURN:  list l: either consisting of a list and an integer, where
+ at format
+  l[1][1]=ideal defining the equisingularity stratum
+  l[1][2]=ideal defining the part of the equisingularity stratum where all
+          equimultiple sections through the non-nodes of the reduced total
+          transform are trivial sections
+  l[2]=1 if some error has occured,  l[2]=0 otherwise;
+ at end format
+or consisting of a ring and an integer, where
+ at format
+  l[1]=ESSring is a ring extension of basering containing the ideal ES
+        (describing the ES-stratum), the ideal ES_all_triv (describing the
+        part with trival equimultiple sections) and the polynomial p_F=F,
+  l[2]=1 if some error has occured,  l[2]=0 otherwise.
+ at end format
+NOTE:    L is supposed to be the output of hnexpansion (with the given ordering
+         of the variables appearing in f). @*
+         If m is given, the ES Stratum over A/maxideal(m) is computed. @*
+         This procedure uses @code{execute} or calls a procedure using
+         @code{execute}.
+         printlevel>=2 displays additional information.
+SEE ALSO: esIdeal, isEquising
+KEYWORDS: equisingularity stratum
+EXAMPLE: example esStratum; shows examples.
+"
+{
+  list l=esComputation (0,p_F,#);
+  return(l);
+}
+example
+{
+   "EXAMPLE:"; echo=2;
+   int p=printlevel;
+   printlevel=1;
+   ring r = 0,(a,b,c,d,e,f,g,x,y),ds;
+   poly F = (x2+2xy+y2+x5)+ax+by+cx2+dxy+ey2+fx3+gx4;
+   list M = esStratum(F);
+   M[1][1];
+
+   printlevel=3;     // displays additional information
+   esStratum(F,2)  ; // ES-stratum over Q[a,b,c,d,e,f,g] / <a,b,c,d,e,f,g>^2
+
+   ideal I = f-fa,e+b;
+   qring q = std(I);
+   poly F = imap(r,F);
+   esStratum(F);
+   printlevel=p;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc isEquising (poly p_F, list #)
+"USAGE:   isEquising(F[,m,L]); F poly, m int, L list
+ASSUME:  F defines a deformation of a reduced bivariate polynomial f
+         and the characteristic of the basering does not divide mult(f). @*
+         If nv is the number of variables of the basering, then the first
+         nv-2 variables are the deformation parameters. @*
+         If the basering is a qring, ideal(basering) must only depend
+         on the deformation parameters.
+COMPUTE: tests if the given family is equisingular along the trivial
+         section.
+RETURN:  int: 1 if the family is equisingular, 0 otherwise.
+NOTE:    L is supposed to be the output of hnexpansion (with the given ordering
+         of the variables appearing in f). @*
+         If m is given, the family is considered over A/maxideal(m). @*
+         This procedure uses @code{execute} or calls a procedure using
+         @code{execute}.
+         printlevel>=2 displays additional information.
+EXAMPLE: example isEquising; shows examples.
+"
+{
+  int check=esComputation (1,p_F,#);
+  return(check);
+}
+example
+{
+   "EXAMPLE:"; echo=2;
+   ring r = 0,(a,b,x,y),ds;
+   poly F = (x2+2xy+y2+x5)+ay3+bx5;
+   isEquising(F);
+   ideal I = ideal(a);
+   qring q = std(I);
+   poly F = imap(r,F);
+   isEquising(F);
+
+   ring rr=0,(A,B,C,x,y),ls;
+   poly f=x7+y7+(x-y)^2*x2y2;
+   poly F=f+A*y*diff(f,x)+B*x*diff(f,x);
+   isEquising(F);
+   isEquising(F,2);    // computation over  Q[a,b] / <a,b>^2
+}
+
+
+
+/*  Examples:
+
+LIB "equising.lib";
+ring r = 0,(x,y),ds;
+poly p1 = y^2+x^3;
+poly p2 = p1^2+x5y;
+poly p3 = p2^2+x^10*p1;
+poly p=p3^2+x^20*p2;
+p;
+list L=versal(p);
+def Px=L[1];
+setring Px;
+poly F=Fs[1,1];
+int t=timer;
+list M=esStratum(F);
+timer-t;  //-> 3
+
+LIB "equising.lib";
+option(prot);
+printlevel=2;
+ring r=0,(x,y),ds;
+poly f=(x-yx+y2)^2-(y+x)^31;
+list L=versal(f);
+def Px=L[1];
+setring Px;
+poly F=Fs[1,1];
+int t=timer;
+list M=esStratum(F);
+timer-t;  //-> 233
+
+LIB "equising.lib";
+printlevel=2;
+option(prot);
+timer=1;
+ring r=0,(x,y),ls;
+poly f=(x4-y4)^2-x10;
+list L=versal(f);
+def Px=L[1];
+setring Px;
+poly F=Fs[1,1];
+int t=timer;
+list M=esStratum(F,3);
+timer-t;  //-> 8
+
+LIB "equising.lib";
+printlevel=2;
+timer=1;
+ring rr=0,(x,y),ls;
+poly f=x7+y7+(x-y)^2*x2y2;
+list K=esIdeal(f);
+// tau_es
+vdim(std(K[1])); //-> 22
+// tau_es_fix
+vdim(std(K[2])); //-> 24
+
+LIB "equising.lib";
+printlevel=2;
+timer=1;
+ring rr=0,(x,y),ls;
+poly f=x7+y7+(x-y)^2*x2y2+x2y4; // Newton non-deg.
+list K=esIdeal(f);
+// tau_es
+vdim(std(K[1])); //-> 21
+// tau_es_fix
+vdim(std(K[2])); //-> 23
+
+LIB "equising.lib";
+ring r=0,(w,v),ds;
+poly f=w2-v199;
+list L=hnexpansion(f);
+list LL=versal(f);
+def Px=LL[1];
+setring Px;
+list L=imap(r,L);
+poly F=Fs[1,1];
+list M=esStratum(F,2,L);
+
+LIB "equising.lib";
+printlevel=2;
+timer=1;
+ring rr=0,(A,B,C,x,y),ls;
+poly f=x7+y7+(x-y)^2*x2y2;
+poly F=f+A*y*diff(f,x)+B*x*diff(f,x)+C*diff(f,y);
+list M=esStratum(F,6);
+std(M[1][1]);  // standard basis of equisingularity ideal
+
+LIB "equising.lib";
+printlevel=2;
+timer=1;
+ring rr=0,(x,y),ls;
+poly f=x20+y7+(x-y)^2*x2y2+x2y4; // Newton non-degenerate
+list K=esIdeal(f);
+K;
+
+ring rr=0,(x,y),ls;
+poly f=x6y-3x4y4-x4y5+3x2y7-x4y6+2x2y8-y10+2x2y9-y11+x2y10-y12-y13;
+list K=esIdeal(f);
+list L=versal(f);
+def Px=L[1];
+setring Px;
+poly F=Fs[1,1];
+list M=esStratum(F,2);
+
+LIB "equising.lib";
+ring R=0,(A,B,C,D,x,y),ds;
+poly f=x6y-3x4y4-x4y5+3x2y7-x4y6+2x2y8-y10+2x2y9-y11+x2y10-y12-y13;
+poly F=f+Ax9+Bx7y2+Cx9y+Dx8y2;
+list M=esStratum(F,2);
+
+LIB "equising.lib";
+printlevel=2;
+ring rr=0,(x,y),ls;
+poly f=x6y-3x4y4-x4y5+3x2y7-x4y6+2x2y8-y10+2x2y9-y11+x2y10-y12-y13;
+list K=esIdeal(f);
+vdim(std(K[1]));  //-> 51
+tau_es(f);        //-> 51
+
+printlevel=3;
+f=f*(y-x2)*(y2-x3)*(x-y5);
+int t=timer;
+list L=esIdeal(f);
+vdim(std(L[1]));  //-> 99
+timer-t;   //-> 42
+t=timer;
+tau_es(f);        //-> 99
+timer-t;   //-> 23
+
+LIB "equising.lib";
+printlevel=3;
+ring rr=0,(x,y),ds;
+poly f=x4+4x3y+6x2y2+4xy3+y4+2x2y15+4xy16+2y17+xy23+y24+y30+y31;
+list K=esIdeal(f);
+vdim(std(K[1]));  //-> 68
+tau_es(f);        //-> 68
+
+list L=versal(f);
+def Px=L[1];
+setring Px;
+poly F=Fs[1,1];
+list M=esStratum(F);
+timer-t;          //-> 0
+
+*/
diff --git a/Singular/LIB/ffsolve.lib b/Singular/LIB/ffsolve.lib
new file mode 100644
index 0000000..88ea0fa
--- /dev/null
+++ b/Singular/LIB/ffsolve.lib
@@ -0,0 +1,1076 @@
+/////////////////////////////////////////////////////////////////////
+version="version ffsolve.lib 4.0.0.0 Jun_2013 "; // $Id: e97c0ba10672bad4c406fc39987cdb60fdab380e $
+category="Symbolic-numerical solving";
+info="
+LIBRARY: ffsolve.lib        multivariate equation solving over finite fields
+AUTHOR: Gergo Gyula Borus, borisz at borisz.net
+KEYWORDS: multivariate equations; finite field
+
+PROCEDURES:
+ffsolve();         finite field solving using heuristically chosen method
+PEsolve();         solve system of multivariate equations over finite field
+simplesolver();    solver using modified exhausting search
+GBsolve();         multivariate solver using Groebner-basis
+XLsolve();         multivariate polynomial solver using linearization
+ZZsolve();         solve system of multivariate equations over finite field
+";
+
+LIB "presolve.lib";
+LIB "general.lib";
+LIB "ring.lib";
+LIB "standard.lib";
+LIB "matrix.lib";
+
+////////////////////////////////////////////////////////////////////
+proc ffsolve(ideal equations, list #)
+"USAGE:         ffsolve(I[, L]); I ideal, L list of strings
+RETURN:         list L, the common roots of I as ideal
+ASSUME:         basering is a finite field of type (p^n,a)
+"
+{
+  list solutions, lSolvers, tempsols;
+  int i,j, k,n, R, found;
+  ideal factors, linfacs;
+  poly lp;
+  // check assumptions
+  if(npars(basering)>1){
+    ERROR("Basering must have at most one parameter");
+  }
+  if(char(basering)==0){
+    ERROR("Basering must have finite characteristic");
+  }
+
+  if(size(#)){
+    if(size(#)==1 and typeof(#[1])=="list"){
+      lSolvers = #[1];
+    }else{
+      lSolvers = #;
+    }
+  }else{
+    if(deg(equations) == 2){
+      lSolvers = "XLsolve", "PEsolve", "simplesolver", "GBsolve", "ZZsolve";
+    }else{
+      lSolvers = "PEsolve", "simplesolver", "GBsolve", "ZZsolve", "XLsolve";
+    }
+    if(deg(equations) == 1){
+      lSolvers = "GBsolve";
+    }
+  }
+  n = size(lSolvers);
+  R = random(1, n*(3*n+1) div 2);
+  for(i=1;i<n+1;i++){
+    if(R<=(2*n+1-i)){
+      string solver = lSolvers[i];
+    }else{
+      R=R-(2*n+1-i);
+    }
+  }
+
+  if(nvars(basering)==1){
+    return(facstd(equations));
+  }
+
+  // search for the first univariate polynomial
+  found = 0;
+  for(i=1; i<=ncols(equations); i++){
+    if(univariate(equations[i])>0){
+      factors=factorize(equations[i],1);
+      for(j=1; j<=ncols(factors); j++){
+        if(deg(factors[j])==1){
+          linfacs[size(linfacs)+1] = factors[j];
+        }
+      }
+      if(deg(linfacs[1])>0){
+        found=1;
+        break;
+      }
+    }
+  }
+  //   if there is, collect its the linear factors
+  if(found){
+    // substitute the root and call recursively
+    ideal neweqs, invmapideal, ti;
+    map invmap;
+    for(k=1; k<=ncols(linfacs); k++){
+      lp = linfacs[k];
+      neweqs = reduce(equations, lp);
+
+      intvec varexp = leadexp(lp);
+      def original_ring = basering;
+      def newRing = clonering(nvars(original_ring)-1);
+      setring newRing;
+      ideal mappingIdeal;
+      j=1;
+      for(i=1; i<=size(varexp); i++){
+        if(varexp[i]){
+          mappingIdeal[i] = 0;
+        }else{
+          mappingIdeal[i] = var(j);
+          j++;
+        }
+      }
+      map recmap = original_ring, mappingIdeal;
+      list tsols = ffsolve(recmap(neweqs), lSolvers);
+      if(size(tsols)==0){
+        tsols = list(ideal(1));
+      }
+      setring original_ring;
+      j=1;
+      for(i=1;i<=size(varexp);i++){
+        if(varexp[i]==0){
+          invmapideal[j] = var(i);
+          j++;
+        }
+      }
+      invmap = newRing, invmapideal;
+      tempsols = invmap(tsols);
+
+      // combine the solutions
+      for(j=1; j<=size(tempsols); j++){
+        ti =  std(tempsols[j]+lp);
+        if(deg(ti)>0){
+          solutions = insert(solutions,ti);
+        }
+      }
+    }
+  }else{
+    execute("solutions="+solver+"(equations);") ;
+  }
+  return(solutions);
+}
+example
+{
+  "EXAMPLE:";echo=2;
+  ring R = (2,a),x(1..3),lp;
+  minpoly=a2+a+1;
+  ideal I;
+  I[1]=x(1)^2*x(2)+(a)*x(1)*x(2)^2+(a+1);
+  I[2]=x(1)^2*x(2)*x(3)^2+(a)*x(1);
+  I[3]=(a+1)*x(1)*x(3)+(a+1)*x(1);
+  ffsolve(I);
+}
+////////////////////////////////////////////////////////////////////
+proc PEsolve(ideal L, list #)
+"USAGE:         PEsolve(I[, i]); I ideal, i optional integer
+                solve I (system of multivariate equations) over a
+                finite field using an equvalence property when i is
+                not given or set to 2, otherwise if i is set to 0
+                then check whether common roots exists
+RETURN:         list if optional parameter is not given or set to 2,
+                integer if optional is set to 0
+ASSUME:         basering is a finite field of type (p^n,a)
+NOTE:           When the optional parameter is set to 0, speoff only
+                checks if I has common roots, then return 1, otherwise
+                return 0.
+
+"
+{
+  int mode, i,j;
+  list results, rs, start;
+  poly g;
+  // check assumptions
+  if(npars(basering)>1){
+    ERROR("Basering must have at most one parameter");
+  }
+  if(char(basering)==0){
+    ERROR("Basering must have finite characteristic");
+  }
+
+  if( size(#) > 0 ){
+    mode = #[1];
+  }else{
+    mode = 2;
+  }
+  L = simplify(L,15);
+  g = productOfEqs( L );
+
+  if(g == 0){
+    if(mode==0){
+      return(0);
+    }
+    return( list() );
+  }
+  if(g == 1){
+    list vectors = every_vector();
+    for(j=1; j<=size(vectors); j++){
+      ideal res;
+      for(i=1; i<=nvars(basering); i++){
+        res[i] = var(i)-vectors[j][i];
+      }
+      results[size(results)+1] = std(res);
+    }
+    return( results );
+  }
+
+  if( mode == 0 ){
+    return( 1 );
+  }else{
+    for(i=1; i<=nvars(basering); i++){
+      start[i] = 0:order_of_extension();
+    }
+
+    if( mode == 1){
+      results[size(results)+1] = melyseg(g, start);
+    }else{
+      while(1){
+        start = melyseg(g, start);
+        if( size(start) > 0 ){
+          ideal res;
+          for(i=1; i<=nvars(basering); i++){
+            res[i] = var(i)-vec2elm(start[i]);
+          }
+          results[size(results)+1] = std(res);
+          start = increment(start);
+        }else{
+          break;
+        }
+      }
+    }
+  }
+  return(results);
+}
+example
+{
+  "EXAMPLE:";echo=2;
+  ring R = (2,a),x(1..3),lp;
+  minpoly=a2+a+1;
+  ideal I;
+  I[1]=x(1)^2*x(2)+(a)*x(1)*x(2)^2+(a+1);
+  I[2]=x(1)^2*x(2)*x(3)^2+(a)*x(1);
+  I[3]=(a+1)*x(1)*x(3)+(a+1)*x(1);
+  PEsolve(I);
+}
+////////////////////////////////////////////////////////////////////
+proc simplesolver(ideal E)
+"USAGE:         simplesolver(I); I ideal
+                solve I (system of multivariate equations) over a
+                finite field by exhausting search
+RETURN:         list L, the common roots of I as ideal
+ASSUME:         basering is a finite field of type (p^n,a)
+"
+{
+  int i,j,k,t, correct;
+  list solutions = list(std(ideal()));
+  list partial_solutions;
+  ideal partial_system, curr_sol, curr_sys, factors;
+  poly univar_poly;
+  E = E+defaultIdeal();
+  // check assumptions
+  if(npars(basering)>1){
+    ERROR("Basering must have at most one parameter");
+  }
+  if(char(basering)==0){
+    ERROR("Basering must have finite characteristic");
+  }
+  for(k=1; k<=nvars(basering); k++){
+    partial_solutions = list();
+    for(i=1; i<=size(solutions); i++){
+      partial_system = reduce(E, solutions[i]);
+      for(j=1; j<=ncols(partial_system); j++){
+        if(univariate(partial_system[j])>0){
+          univar_poly = partial_system[j];
+          break;
+        }
+      }
+      factors = factorize(univar_poly,1);
+      for(j=1; j<=ncols(factors); j++){
+        if(deg(factors[j])==1){
+          curr_sol = std(solutions[i]+ideal(factors[j]));
+          curr_sys = reduce(E, curr_sol);
+          correct = 1;
+          for(t=1; t<=ncols(curr_sys); t++){
+            if(deg(curr_sys[t])==0){
+              correct = 0;
+              break;
+            }
+          }
+          if(correct){
+            partial_solutions = insert(partial_solutions, curr_sol);
+          }
+        }
+      }
+    }
+    solutions = partial_solutions;
+  }
+  return(solutions);
+}
+example
+{
+  "EXAMPLE:";echo=2;
+  ring R = (2,a),x(1..3),lp;
+  minpoly=a2+a+1;
+  ideal I;
+  I[1]=x(1)^2*x(2)+(a)*x(1)*x(2)^2+(a+1);
+  I[2]=x(1)^2*x(2)*x(3)^2+(a)*x(1);
+  I[3]=(a+1)*x(1)*x(3)+(a+1)*x(1);
+  simplesolver(I);
+}
+////////////////////////////////////////////////////////////////////
+proc GBsolve(ideal equation_system)
+"USAGE:         GBsolve(I); I ideal
+                solve I (system of multivariate equations) over an
+                extension of Z/p by Groebner basis methods
+RETURN:         list L, the common roots of I as ideal
+ASSUME:         basering is a finite field of type (p^n,a)
+"
+{
+  int i,j, prop, newelement, number_new_vars;
+  ideal ls;
+  list results, slvbl, linsol, ctrl, new_sols, varinfo;
+  ideal I, linear_solution, unsolved_part, univar_part, multivar_part, unsolved_vars;
+  intvec unsolved_var_nums;
+  string new_vars;
+  // check assumptions
+  if(npars(basering)>1){
+    ERROR("Basering must have at most one parameter");
+  }
+  if(char(basering)==0){
+    ERROR("Basering must have finite characteristic");
+  }
+
+  def original_ring = basering;
+  if(npars(basering)==1){
+    int prime_coeff_field=0;
+    string minpolystr = "minpoly="+
+    get_minpoly_str(size(original_ring),parstr(original_ring,1))+";" ;
+  }else{
+    int prime_coeff_field=1;
+  }
+
+  option(redSB);
+
+  equation_system = simplify(equation_system,15);
+
+  ideal standard_basis = std(equation_system);
+  list basis_factors = facstd(standard_basis);
+  if( basis_factors[1][1] == 1){
+    return(results)
+  };
+
+  for(i=1; i<= size(basis_factors); i++){
+    prop = 0;
+    for(j=1; j<=size(basis_factors[i]); j++){
+      if( univariate(basis_factors[i][j])>0 and deg(basis_factors[i][j])>1){
+        prop =1;
+        break;
+      }
+    }
+    if(prop == 0){
+      ls = solvelinearpart( basis_factors[i] );
+      if(ncols(ls) == nvars(basering) ){
+        ctrl, newelement = add_if_new(ctrl, ls);
+        if(newelement){
+          results = insert(results, ls);
+        }
+      }else{
+        slvbl = insert(slvbl, list(basis_factors[i],ls) );
+      }
+    }
+  }
+  if(size(slvbl)<>0){
+    for(int E = 1; E<= size(slvbl); E++){
+      I = slvbl[E][1];
+      linear_solution = slvbl[E][2];
+      attrib(I,"isSB",1);
+      unsolved_part = reduce(I,linear_solution);
+      univar_part = ideal();
+      multivar_part = ideal();
+      for(i=1; i<=ncols(I); i++){
+        if(univariate(I[i])>0){
+          univar_part = univar_part+I[i];
+        }else{
+          multivar_part = multivar_part+I[i];
+        }
+      }
+      varinfo = findvars(univar_part,1);
+      unsolved_vars = varinfo[3];
+      unsolved_var_nums = varinfo[4];
+      number_new_vars = ncols(unsolved_vars);
+
+      new_vars = "@y(1.."+string(number_new_vars)+")";
+      def R_new = changevar(new_vars, original_ring);
+      setring R_new;
+      if( !prime_coeff_field ){
+        execute(minpolystr);
+      }
+
+      ideal mapping_ideal;
+      for(i=1; i<=size(unsolved_var_nums); i++){
+        mapping_ideal[unsolved_var_nums[i]] = var(i);
+      }
+
+      map F = original_ring, mapping_ideal;
+      ideal I_new = F( multivar_part );
+
+      list sol_new;
+      int unsolvable = 0;
+      sol_new = simplesolver(I_new);
+      if( size(sol_new) == 0){
+        unsolvable = 1;
+      }
+
+      setring original_ring;
+
+      if(unsolvable){
+        list sol_old = list();
+      }else{
+        map G = R_new, unsolved_vars;
+        new_sols = G(sol_new);
+        for(i=1; i<=size(new_sols); i++){
+          ideal sol = new_sols[i]+linear_solution;
+          sol = std(sol);
+          ctrl, newelement = add_if_new(ctrl, sol);
+          if(newelement){
+            results = insert(results, sol);
+          }
+          kill sol;
+        }
+      }
+      kill G;
+      kill R_new;
+    }
+  }
+  return( results  );
+}
+example
+{
+  "EXAMPLE:";echo=2;
+  ring R = (2,a),x(1..3),lp;
+  minpoly=a2+a+1;
+  ideal I;
+  I[1]=x(1)^2*x(2)+(a)*x(1)*x(2)^2+(a+1);
+  I[2]=x(1)^2*x(2)*x(3)^2+(a)*x(1);
+  I[3]=(a+1)*x(1)*x(3)+(a+1)*x(1);
+  GBsolve(I);
+}
+////////////////////////////////////////////////////////////////////
+proc XLsolve(ideal I, list #)
+"USAGE:         XLsolve(I[, d]); I ideal, d optional integer
+                solve I (system of multivariate polynomials) with a
+                variant of the linearization technique, multiplying
+                the polynomials with monomials of degree at most d
+                (default is 2)
+RETURN:         list L of the common roots of I as ideals
+ASSUME:         basering is a finite field of type (p^n,a)"
+{
+  int i,j,k, D;
+  int SD = deg(I);
+  list solutions;
+  if(size(#)){
+    if(typeof(#[1])=="int"){ D = #[1]; }
+  }else{
+    D = 2;
+  }
+  list lMonomialsForMultiplying = monomialsOfDegreeAtMost(D+SD);
+
+  int m = ncols(I);
+  list extended_system;
+  list mm;
+  for(k=1; k<=size(lMonomialsForMultiplying)-SD; k++){
+    mm = lMonomialsForMultiplying[k];
+    for(i=1; i<=m; i++){
+      for(j=1; j<=size(mm); j++){
+        extended_system[size(extended_system)+1] = reduce(I[i]*mm[j], defaultIdeal());
+      }
+    }
+  }
+  ideal new_system = I;
+  for(i=1; i<=size(extended_system); i++){
+    new_system[m+i] = extended_system[i];
+  }
+  ideal reduced_system = linearReduce( new_system, lMonomialsForMultiplying);
+
+  solutions = simplesolver(reduced_system);
+
+  return(solutions);
+}
+example
+{
+  "EXAMPLE:";echo=2;
+  ring R = (2,a),x(1..3),lp;
+  minpoly=a2+a+1;
+  ideal I;
+  I[1]=(a)*x(1)^2+x(2)^2+(a+1);
+  I[2]=(a)*x(1)^2+(a)*x(1)*x(3)+(a)*x(2)^2+1;
+  I[3]=(a)*x(1)*x(3)+1;
+  I[4]=x(1)^2+x(1)*x(3)+(a);
+  XLsolve(I, 3);
+}
+
+////////////////////////////////////////////////////////////////////
+proc ZZsolve(ideal I)
+"USAGE:         ZZsolve(I); I ideal
+solve I (system of multivariate equations) over a
+finite field by mapping the polynomials to a single
+univariate polynomial over extension of the basering
+RETURN:         list, the common roots of I as ideal
+ASSUME:         basering is a finite field of type (p^n,a)
+"
+{
+  int i, j, nv, numeqs,r,l,e;
+  def original_ring = basering;
+  // check assumptions
+  if(npars(basering)>1){
+    ERROR("Basering must have at most one parameter");
+  }
+  if(char(basering)==0){
+    ERROR("Basering must have finite characteristic");
+  }
+
+  nv = nvars(original_ring);
+  numeqs = ncols(I);
+  l = numeqs % nv;
+  if( l == 0){
+    r = numeqs div nv;
+  }else{
+    r = (numeqs div nv) +1;
+  }
+
+
+  list list_of_equations;
+  for(i=1; i<=r; i++){
+    list_of_equations[i] = ideal();
+  }
+  for(i=0; i<numeqs; i++){
+    list_of_equations[(i div nv)+1][(i % nv) +1] = I[i+1];
+  }
+
+  ring ring_for_matrix = (char(original_ring), at y),(x(1..nv), at X, at c(1..nv)(1..nv)),lp;
+  execute("minpoly="+Z_get_minpoly(size(original_ring)^nv, parstr(1))+";");
+
+  ideal IV;
+  for(i=1; i<=nv; i++){
+    IV[i] = var(i);
+  }
+
+  matrix M_C[nv][nv];
+  for(i=1;i<=nrows(M_C); i++){
+    for(j=1; j<=ncols(M_C); j++){
+      M_C[i,j] = @c(i)(j);
+    }
+  }
+
+  poly X = Z_phi(IV);
+  ideal IX_power_poly;
+  ideal IX_power_var;
+  for(i=1; i<=nv; i++){
+    e = (size(original_ring)^(i-1));
+    IX_power_poly[i] = X^e;
+    IX_power_var[i] = @X^e;
+  }
+  IX_power_poly = reduce(IX_power_poly, Z_default_ideal(nv, size(original_ring)));
+
+  def M = matrix(IX_power_poly,1,nv)*M_C - matrix(IV,1,nv);
+
+  ideal IC;
+  for(i=1; i<=ncols(M); i++){
+    for(j=1; j<=ncols(IV); j++){
+      IC[(i-1)*ncols(M)+j] = coeffs(M[1,i],IV[j])[2,1];
+    }
+  }
+
+  ideal IC_solultion = std(Presolve::solvelinearpart(IC));
+
+
+  matrix M_C_sol[nv][nv];
+  for(i=1;i<=nrows(M_C_sol); i++){
+    for(j=1; j<=ncols(M_C_sol); j++){
+      M_C_sol[i,j] = reduce(@c(i)(j), std(IC_solultion));
+    }
+  }
+  ideal I_subs;
+  I_subs = ideal(matrix(IX_power_var,1,nv)*M_C_sol);
+
+  setring original_ring;
+  string var_str = varstr(original_ring)+", at X, at y";
+  string minpoly_str = "minpoly="+string(minpoly)+";";
+  def ring_for_substitution = Ring::changevar(var_str, original_ring);
+
+  setring ring_for_substitution;
+  execute(minpoly_str);
+
+  ideal I_subs = imap(ring_for_matrix, I_subs);
+  ideal I = imap(original_ring, I);
+  list list_of_equations = imap(original_ring, list_of_equations);
+
+  list list_of_F;
+  for(i=1; i<=r; i++){
+    list_of_F[i] = Z_phi( list_of_equations[i] );
+  }
+
+  for(i=1; i<=nv; i++){
+
+    for(j=1; j<=r; j++){
+      list_of_F[j] = subst( list_of_F[j], var(i), I_subs[i] );
+    }
+  }
+  int s = size(original_ring);
+  if(npars(original_ring)==1){
+    for(j=1; j<=r; j++){
+      list_of_F[j] = subst(list_of_F[j], par(1), (@y^( (s^nv-1) div (s-1) )));
+    }
+  }
+
+  ring temp_ring = (char(original_ring), at y), at X,lp;
+  list list_of_F = imap(ring_for_substitution, list_of_F);
+
+  ring ring_for_factorization = (char(original_ring), at y),X,lp;
+  execute("minpoly="+Z_get_minpoly(size(original_ring)^nv, parstr(1))+";");
+  map rho = temp_ring,X;
+  list list_of_F = rho(list_of_F);
+  poly G = 0;
+  for(i=1; i<=r; i++){
+    G = gcd(G, list_of_F[i]);
+  }
+  if(G==1){
+    return(list());
+  }
+
+  list factors = Presolve::linearpart(factorize(G,1));
+
+  ideal check;
+  for(i=1; i<=nv; i++){
+    check[i] = X^(size(original_ring)^(i-1));
+  }
+  list fsols;
+
+  matrix sc;
+  list sl;
+  def sM;
+  matrix M_for_sol = fetch(ring_for_matrix, M_C_sol);
+  for(i=1; i<=size(factors[1]); i++){
+    sc = matrix(reduce(check, std(factors[1][i])), 1,nv  );
+
+    sl = list();
+    sM = sc*M_for_sol;
+    for(j=1; j<=ncols(sM); j++){
+      sl[j] = sM[1,j];
+    }
+    fsols[i] = sl;
+  }
+  if(size(fsols)==0){
+    return(list());
+  }
+  setring ring_for_substitution;
+  list ssols = imap(ring_for_factorization, fsols);
+  if(npars(original_ring)==1){
+    execute("poly P="+Z_get_minpoly(size(original_ring)^nv, "@y"));
+    poly RP = gcd(P,  (@y^( (s^nv-1) div (s-1) ))-a);
+    for(i=1; i<=size(ssols); i++){
+      for(j=1; j<=size(ssols[i]); j++){
+        ssols[i][j] = reduce( ssols[i][j], std(RP));
+      }
+    }
+  }
+  setring original_ring;
+  list solutions = imap(ring_for_substitution, ssols);
+  list final_solutions;
+  ideal ps;
+  for(i=1; i<=size(solutions); i++){
+    ps = ideal();
+    for(j=1; j<=nvars(original_ring); j++){
+      ps[j] = var(j)-solutions[i][j];
+    }
+    final_solutions = insert(final_solutions, std(ps));
+  }
+  return(final_solutions);
+}
+example
+{
+  "EXAMPLE:";echo=2;
+  ring R = (2,a),x(1..3),lp;
+  minpoly=a2+a+1;
+  ideal I;
+  I[1]=x(1)^2*x(2)+(a)*x(1)*x(2)^2+(a+1);
+  I[2]=x(1)^2*x(2)*x(3)^2+(a)*x(1);
+  I[3]=(a+1)*x(1)*x(3)+(a+1)*x(1);
+  ZZsolve(I);
+}
+////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////
+static proc linearReduce(ideal I, list mons)
+{
+  system("--no-warn", 1);
+  int LRtime = rtimer;
+  int i,j ;
+  int prime_field = 1;
+  list solutions, monomials;
+  for(i=1; i<=size(mons); i++){
+    monomials = reorderMonomials(mons[i])+monomials;
+  }
+  int number_of_monomials = size(monomials);
+
+  def original_ring = basering;
+  if(npars(basering)==1){
+    prime_field=0;
+    string minpolystr = "minpoly="
+    +get_minpoly_str(size(original_ring),parstr(original_ring,1))+";" ;
+  }
+  string old_vars = varstr(original_ring);
+  string new_vars = "@y(1.."+string( number_of_monomials )+")";
+
+  def ring_for_var_change = changevar( old_vars+","+new_vars, original_ring);
+  setring ring_for_var_change;
+  if( prime_field == 0){
+    execute(minpolystr);
+  }
+
+  list monomials = imap(original_ring, monomials);
+  ideal I = imap(original_ring, I);
+  ideal C;
+  intvec weights=1:nvars(original_ring);
+
+  for(i=1; i<= number_of_monomials; i++){
+    C[i] = monomials[i] - @y(i);
+    weights = weights,deg(monomials[i])+1;
+  }
+  ideal linear_eqs = I;
+  for(i=1; i<=ncols(C); i++){
+    linear_eqs = reduce(linear_eqs, C[i]);
+  }
+
+  def ring_for_elimination = changevar( new_vars, ring_for_var_change);
+  setring ring_for_elimination;
+  if( prime_field == 0){
+    execute(minpolystr);
+  }
+
+  ideal I = imap(ring_for_var_change, linear_eqs);
+  ideal lin_sol = solvelinearpart(I);
+  def ring_for_back_change = changeord( list(list("wp",weights),list("C",0:1)), ring_for_var_change);
+
+  setring ring_for_back_change;
+  if( prime_field == 0){
+    execute(minpolystr);
+  }
+
+  ideal lin_sol = imap(ring_for_elimination, lin_sol);
+  ideal C = imap(ring_for_var_change, C);
+  ideal J = lin_sol;
+  for(i=1; i<=ncols(C); i++){
+    J = reduce(J, C[i]);
+  }
+  setring original_ring;
+  ideal J = imap(ring_for_back_change, J);
+  return(J);
+}
+
+static proc monomialsOfDegreeAtMost(int k)
+{
+  int Mtime = rtimer;
+  list monomials, monoms, monoms_one, lower_monoms;
+  int n = nvars(basering);
+  int t,i,l,j,s;
+  for(i=1; i<=n; i++){
+    monoms_one[i] = var(i);
+  }
+  monomials = list(monoms_one);
+  if(1 < k){
+    for(t=2; t<=k; t++){
+      lower_monoms = monomials[t-1];
+      monoms = list();
+      s = 1;
+      for(i=1; i<=n; i++){
+        for(j=s; j<=size(lower_monoms); j++){
+          monoms = monoms+list(lower_monoms[j]*var(i));
+        }
+        s = s + int(binomial(n+t-2-i, t-2));
+      }
+      monomials[t] = monoms;
+    }
+  }
+  return(monomials);
+}
+
+static proc reorderMonomials(list monomials)
+{
+  list univar_monoms, mixed_monoms;
+
+  for(int j=1; j<=size(monomials); j++){
+    if( univariate(monomials[j])>0 ){
+      univar_monoms = univar_monoms + list(monomials[j]);
+    }else{
+      mixed_monoms = mixed_monoms + list(monomials[j]);
+    }
+  }
+
+  return(univar_monoms + mixed_monoms);
+}
+
+static proc melyseg(poly g, list start)
+{
+  list gsub = g;
+  int i = 1;
+
+  while( start[1][1] <> char(basering) ){
+    gsub[i+1] = subst( gsub[i], var(i), vec2elm(start[i]));
+    if( gsub[i+1] == 0 ){
+      list new = increment(start,i);
+      for(int l=1; l<=size(start); l++){
+        if(start[l]<>new[l]){
+          i = l;
+          break;
+        }
+      }
+      start = new;
+    }else{
+      if(i == nvars(basering)){
+        return(start);
+      }else{
+        i++;
+      }
+    }
+  }
+  return(list());
+}
+
+static proc productOfEqs(ideal I)
+{
+  system("--no-warn", 1);
+  ideal eqs = sort_ideal(I);
+  int i,q;
+  poly g = 1;
+  q = size(basering);
+  ideal I = defaultIdeal();
+
+  for(i=1; i<=size(eqs); i++){
+    if(g==0){return(g);}
+    g = reduce(g*(eqs[i]^(q-1)-1), I);
+  }
+  return( g );
+}
+
+static proc clonering(list #)
+{
+  def original_ring = basering;
+  int n = nvars(original_ring);
+  int prime_field=npars(basering);
+  if(prime_field){
+    string minpolystr = "minpoly="+
+    get_minpoly_str(size(original_ring),parstr(original_ring,1))+";" ;
+  }
+
+  if(size(#)){
+    int newvars = #[1];
+
+  }else{
+    int newvars = nvars(original_ring);
+  }
+  string newvarstr = "v(1.."+string(newvars)+")";
+  def newring = changevar(newvarstr, original_ring);
+  setring newring;
+  if( prime_field ){
+    execute(minpolystr);
+  }
+  return(newring);
+}
+
+static proc defaultIdeal()
+{
+  ideal I;
+  for(int i=1; i<=nvars(basering); i++){
+    I[i] = var(i)^size(basering)-var(i);
+  }
+  return( std(I) );
+}
+
+static proc order_of_extension()
+{
+  int oe=1;
+  list rl = ringlist(basering);
+  if( size(rl[1]) <> 1){
+    oe = deg( subst(minpoly,par(1),var(1)) );
+  }
+  return(oe);
+}
+
+static proc vec2elm(intvec v)
+{
+  number g = 1;
+  if(npars(basering) == 1){ g=par(1); }
+  number e=0;
+  int oe = size(v);
+  for(int i=1; i<=oe; i++){
+    e = e+v[i]*g^(oe-i);
+  }
+  return(e);
+}
+
+static proc increment(list l, list #)
+{
+  int c, i, j, oe;
+  oe = order_of_extension();
+  c = char(basering);
+
+  if( size(#) == 1 ){
+    i = #[1];
+  }else{
+    i = size(l);
+  }
+
+  l[i] = nextVec(l[i]);
+  while( l[i][1] == c && i>1 ){
+    l[i] = 0:oe;
+    i--;
+    l[i] = nextVec(l[i]);
+  }
+  if( i < size(l) ){
+    for(j=i+1; j<=size(l); j++){
+      l[j] = 0:oe;
+    }
+  }
+  return(l);
+}
+
+static proc nextVec(intvec l)
+{
+  int c, i, j;
+  i = size(l);
+  c = char(basering);
+  l[i] = l[i] + 1;
+  while( l[i] == c && i>1 ){
+    l[i] = 0;
+    i--;
+    l[i] = l[i] + 1;
+  }
+  return(l);
+}
+
+static proc every_vector()
+{
+  list element, list_of_elements;
+
+  for(int i=1; i<=nvars(basering); i++){
+    element[i] = 0:order_of_extension();
+  }
+
+  while(size(list_of_elements) < size(basering)^nvars(basering)){
+    list_of_elements = list_of_elements + list(element);
+    element = increment(element);
+  }
+  for(int i=1; i<=size(list_of_elements); i++){
+    for(int j=1; j<=size(list_of_elements[i]); j++){
+      list_of_elements[i][j] = vec2elm(list_of_elements[i][j]);
+    }
+  }
+  return(list_of_elements);
+}
+
+static proc num2int(number a)
+{
+  int N=0;
+  if(order_of_extension() == 1){
+    N = int(a);
+    if(N<0){
+      N = N + char(basering);
+    }
+  }else{
+    ideal C = coeffs(subst(a,par(1),var(1)),var(1));
+    for(int i=1; i<=ncols(C); i++){
+      int c = int(C[i]);
+      if(c<0){ c = c + char(basering); }
+      N = N + c*char(basering)^(i-1);
+    }
+  }
+  return(N);
+}
+
+static proc get_minpoly_str(int size_of_ring, string parname)
+{
+  def original_ring = basering;
+  ring new_ring = (size_of_ring, A),x,lp;
+  string S = string(minpoly);
+  string SMP;
+  if(S=="0"){
+    SMP = SMP+parname;
+  }else{
+    for(int i=1; i<=size(S); i++){
+      if(S[i]=="A"){
+        SMP = SMP+parname;
+      }else{
+        SMP = SMP+S[i];
+      }
+    }
+  }
+  return(SMP);
+}
+
+static proc sort_ideal(ideal I)
+{
+  ideal OI;
+  int i,j,M;
+  poly P;
+  M = ncols(I);
+  OI = I;
+  for(i=2; i<=M; i++){
+    j=i;
+    while(size(OI[j-1])>size(OI[j])){
+      P = OI[j-1];
+      OI[j-1] = OI[j];
+      OI[j] = P;
+      j--;
+      if(j==1){ break; }
+    }
+  }
+  return(OI);
+}
+
+static proc add_if_new(list L, ideal I)
+{
+  int i, newelement;
+  poly P;
+
+  I=std(I);
+  for(i=1; i<=nvars(basering); i++){
+    P = P +  reduce(var(i),I)*var(1)^(i-1);
+  }
+  newelement=1;
+  for(i=1; i<=size(L); i++){
+    if(L[i]==P){
+      newelement=0;
+      break;
+    }
+  }
+  if(newelement){
+    L = insert(L, P);
+  }
+  return(L,newelement);
+}
+
+static proc Z_get_minpoly(int size_of_ring, string parname)
+{
+  def original_ring = basering;
+  ring new_ring = (size_of_ring, A),x,lp;
+  string S = string(minpoly);
+  string SMP;
+  if(S=="0"){
+    SMP = SMP+parname;
+  }else{
+    for(int i=1; i<=size(S); i++){
+      if(S[i]=="A"){
+        SMP = SMP+parname;
+      }else{
+        SMP = SMP+S[i];
+      }
+    }
+  }
+  return(SMP);
+}
+
+static proc Z_phi(ideal I)
+{
+  poly f;
+  for(int i=1; i<= ncols(I); i++){
+    f = f+I[i]*@y^(i-1);
+  }
+  return(f);
+}
+
+static proc Z_default_ideal(int number_of_variables, int q)
+{
+  ideal DI;
+  for(int i=1; i<=number_of_variables; i++){
+    DI[i] = var(i)^q-var(i);
+  }
+  return(std(DI));
+}
diff --git a/Singular/LIB/findifs.lib b/Singular/LIB/findifs.lib
new file mode 100644
index 0000000..8b59b0d
--- /dev/null
+++ b/Singular/LIB/findifs.lib
@@ -0,0 +1,778 @@
+//////////////////////////////////////////////////////////////////////////////
+version="version findifs.lib 4.0.0.0 Jun_2013 "; // $Id: d56248604e0535012373faef7e0ad53393269302 $
+category="System and Control Theory";
+info="
+LIBRARY: findifs.lib  Tools for the finite difference schemes
+AUTHORS: Viktor Levandovskyy,     levandov at math.rwth-aachen.de
+
+OVERVIEW:
+        We provide the presentation of difference operators in a polynomial,
+        semi-factorized and a nodal form. Running @code{findifs_example();}
+        will demonstrate, how we generate finite difference schemes of linear PDEs
+        from given approximations.
+
+Theory: The method we use have been developed by V. Levandovskyy and Bernd Martin. The
+computation of a finite difference scheme of a given single linear partial
+differential equation with constant coefficients with a given approximation
+rules boils down to the computation of a Groebner basis of a submodule of
+a free module with respect to the ordering, eliminating module components.
+
+
+Support: SpezialForschungsBereich F1301 of the Austrian FWF
+
+PROCEDURES:
+findifs_example();  containes a guided explanation of our approach
+decoef(P,n);  decompose polynomial P into summands with respect to the number n
+difpoly2tex(S,P[,Q]); present the difference scheme in the nodal form
+
+
+exp2pt(P[,L]); convert a polynomial M into the TeX format, in nodal form
+texcoef(n);  converts the number n into TeX
+npar(n); search for 'n' among the parameters and returns its number
+magnitude(P); compute the square of the magnitude of a complex expression
+replace(s,what,with);  replace in s all the substrings with a given string
+xchange(w,a,b); exchange two substrings in a given string
+
+SEE ALSO: latex_lib, finitediff_lib
+";
+
+
+LIB "latex.lib";
+LIB "poly.lib";
+
+proc tst_findif()
+{
+  example decoef;
+  example difpoly2tex;
+  example exp2pt;
+  example texcoef;
+  example npar;
+  example magnitude;
+  example replace;
+  example xchange;
+}
+
+// static procs:
+// par2tex(s);     convert special characters to TeX in s
+// mon2pt(P[,L]); convert a monomial M into the TeX format, in nodal form
+
+
+// 1. GLOBAL ASSUME: in the ring we have first Tx, then Tt: [FIXED, not needed anymore]!
+// 2. map vars other than Tx,Tt to parameters instead or just ignore them [?]
+// 3. clear the things with brackets
+// 4. todo: content resp lcmZ, gcdZ
+
+proc xchange(string where, string a, string b)
+"USAGE:  xchange(w,a,b);  w,a,b strings
+RETURN:  string
+PURPOSE:  exchanges substring 'a' with a substring 'b' in the string w
+NOTE:
+EXAMPLE: example xchange; shows examples
+"{
+  // replaces a<->b in where
+  // assume they are of the same size [? seems to work]
+  string s = "H";
+  string t;
+  t = replace(where,a,s);
+  t = replace(t,b,a);
+  t = replace(t,s,b);
+  return(t);
+}
+example
+{
+ " EXAMPLE:"; echo=2;
+ ring r = (0,dt,dh,A),Tt,dp;
+ poly p = (Tt*dt+dh+1)^2+2*A;
+ string s = texpoly("",p);
+ s;
+ string t = xchange(s,"dh","dt");
+ t;
+}
+
+static proc par2tex(string s)
+"USAGE:  par2tex(s);  s a string
+RETURN:  string
+PURPOSE: converts special characters to TeX in s
+NOTE: the convention is the following:
+      'Tx' goes to 'T_x',
+      'dx' to '\\tri x' (the same for dt, dy, dz),
+      'theta', 'ro', 'A', 'V' are converted to greek letters.
+EXAMPLE: example par2tex; shows examples
+"{
+  // can be done with the help of latex_lib
+
+// s is a tex string with a poly
+// replace theta with \theta
+// A with \lambda
+// dt with \tri t
+// dh with \tri h
+// Tx with T_x, Ty with T_y
+// Tt with T_t
+// V with \nu
+// ro with \rho
+// dx with \tri x
+// dy with \tri y
+  string t = s;
+  t = replace(t,"Tt","T_t");
+  t = replace(t,"Tx","T_x");
+  t = replace(t,"Ty","T_y");
+  t = replace(t,"dt","\\tri t");
+  t = replace(t,"dh","\\tri h");
+  t = replace(t,"dx","\\tri x");
+  t = replace(t,"dy","\\tri y");
+  t = replace(t,"theta","\\theta");
+  t = replace(t,"A","\\lambda");
+  t = replace(t,"V","\\nu");
+  t = replace(t,"ro","\\rho");
+  return(t);
+}
+example
+{
+ " EXAMPLE:"; echo=2;
+ ring r = (0,dt,theta,A),Tt,dp;
+ poly p = (Tt*dt+theta+1)^2+2*A;
+ string s = texfactorize("",p);
+ s;
+ par2tex(s);
+ string T = texfactorize("",p*(-theta*A));
+ par2tex(T);
+}
+
+proc replace(string s, string what, string with)
+"USAGE:  replace(s,what,with);  s,what,with strings
+RETURN:  string
+PURPOSE: replaces in 's' all the substrings 'what' with substring 'with'
+NOTE:
+EXAMPLE: example replace; shows examples
+"{
+  // clear: replace in s, "what" with "with"
+  int ss = size(s);
+  int cn = find(s,what);
+  if ( (cn==0) || (cn>ss))
+  {
+    return(s);
+  }
+  int gn = 0; // global counter
+  int sw = size(what);
+  int swith = size(with);
+  string out="";
+  string tmp;
+  gn  = 0;
+  while(cn!=0)
+  {
+//    "cn:";    cn;
+//    "gn";    gn;
+    tmp = "";
+    if (cn>gn)
+    {
+      tmp = s[gn..cn-1];
+    }
+//    "tmp:";tmp;
+//    out = out+tmp+" "+with;
+    out = out+tmp+with;
+//    "out:";out;
+    gn  = cn + sw;
+    if (gn>ss)
+    {
+      // ( (gn>ss) || ((sw>1) && (gn >= ss)) )
+      // no need to append smth
+      return(out);
+    }
+//     if (gn == ss)
+//     {
+
+//     }
+    cn  = find(s,what,gn);
+  }
+  // and now, append the rest of s
+  //  out = out + " "+ s[gn..ss];
+  out = out + s[gn..ss];
+  return(out);
+}
+example
+{
+ " EXAMPLE:"; echo=2;
+ ring r = (0,dt,theta),Tt,dp;
+ poly p = (Tt*dt+theta+1)^2+2;
+ string s = texfactorize("",p);
+ s;
+ s = replace(s,"Tt","T_t"); s;
+ s = replace(s,"dt","\\tri t"); s;
+ s = replace(s,"theta","\\theta"); s;
+}
+
+proc exp2pt(poly P, list #)
+"USAGE:  exp2pt(P[,L]);  P poly, L an optional list of strings
+RETURN:  string
+PURPOSE: convert a polynomial M into the TeX format, in nodal form
+ASSUME: coefficients must not be fractional
+NOTE: an optional list L contains a string, which will replace the default
+value 'u' for the discretized function
+EXAMPLE: example exp2pt; shows examples
+"{
+// given poly in vars [now Tx,Tt are fixed],
+// create Tex expression for points of lattice
+// coeffs must not be fractional
+  string varnm = "u";
+  if (size(#) > 0)
+  {
+    if (typeof(#[1])=="string")
+    {
+      varnm = string(#[1]);
+    }
+  }
+  //  varnm;
+  string rz,mz;
+  while (P!=0)
+  {
+    mz = mon2pt(P,varnm);
+    if (mz[1]=="-")
+    {
+      rz = rz+mz;
+    }
+    else
+    {
+      rz = rz + "+" + mz;
+    }
+    P = P-lead(P);
+  }
+  rz  = rz[2..size(rz)];
+  return(rz);
+}
+example
+{
+  " EXAMPLE:"; echo=2;
+  ring r = (0,dh,dt),(Tx,Tt),dp;
+  poly M = (4*dh*Tx^2+1)*(Tt-1)^2;
+  print(exp2pt(M));
+  print(exp2pt(M,"F"));
+}
+
+static proc mon2pt(poly M, string V)
+"USAGE:  mon2pt(M,V);  M poly, V a string
+RETURN:  string
+PURPOSE: convert a monomial M into the TeX format, nodal form
+EXAMPLE: example mon2pt; shows examples
+"{
+  // searches for Tx, then Tt
+  // monomial to the lattice point conversion
+  // c*X^a*Y^b --> c*U^{n+a}_{j+b}
+  number cM = leadcoef(M);
+  intvec e = leadexp(M);
+  //  int a = e[2]; // convention: first Tx, then Tt
+  //  int b = e[1];
+  int i;
+  int a , b, c = 0,0,0;
+  int ia,ib,ic = 0,0,0;
+  int nv = nvars(basering);
+  string s;
+  for (i=1; i<=nv ; i++)
+  {
+    s = string(var(i));
+    if (s=="Tt") { a = e[i]; ia = i;}
+    if (s=="Tx") { b = e[i]; ib = i;}
+    if (s=="Ty") { c = e[i]; ic = i;}
+  }
+  //  if (ia==0) {"Error:Tt not found!"; return("");}
+  //  if (ib==0) {"Error:Tx not found!"; return("");}
+  //  if (ic==0)   {"Error:Ty not found!"; return("");}
+  //  string tc = texobj("",c); // why not texpoly?
+  string tc = texcoef(cM);
+  string rs;
+  if (cM==-1)
+  {
+    rs = "-";
+  }
+  if (cM^2 != 1)
+  {
+// we don't need 1 or -1 as coeffs
+//    rs = clTex(tc)+" ";
+//    rs = par2tex(rmDol(tc))+" ";
+    rs = par2tex(tc)+" ";
+  }
+// a = 0 or b = 0
+  rs = rs + V +"^{n";
+  if (a!=0)
+  {
+    rs = rs +"+"+string(a);
+  }
+  rs = rs +"}_{j";
+  if (b!=0)
+  {
+    rs = rs +"+"+string(b);
+  }
+  if (c!=0)
+  {
+    rs = rs + ",k+";
+    rs = rs + string(c);
+  }
+  rs = rs +"}";
+  return(rs);
+}
+example
+{
+ "EXAMPLE:"; echo=2;
+  ring r = (0,dh,dt),(Tx,Tt),dp;
+  poly M = (4*dh^2-dt)*Tx^3*Tt;
+  print(mon2pt(M,"u"));
+  poly N = ((dh-dt)/(dh+dt))*Tx^2*Tt^2;
+  print(mon2pt(N,"f"));
+  ring r2 = (0,dh,dt),(Tx,Ty,Tt),dp;
+  poly M  = (4*dh^2-dt)*Tx^3*Ty^2*Tt;
+  print(mon2pt(M,"u"));
+}
+
+proc npar(number n)
+"USAGE:  npar(n);  n a number
+RETURN:  int
+PURPOSE: searches for 'n' among the parameters and returns its number
+EXAMPLE: example npar; shows examples
+"{
+  // searches for n amongst parameters
+  // and returns its number
+  int i,j=0,0;
+  list L = ringlist(basering);
+  list M = L[1][2]; // pars
+  string sn = string(n);
+  sn = sn[2..size(sn)-1];
+  for (i=1; i<=size(M);i++)
+  {
+    if (M[i] == sn)
+    {
+      j = i;
+    }
+  }
+  if (j==0)
+  {
+    "Incorrect parameter";
+  }
+  return(j);
+}
+example
+{
+ "EXAMPLE:"; echo=2;
+  ring r = (0,dh,dt,theta,A),t,dp;
+  npar(dh);
+  number T = theta;
+  npar(T);
+  npar(dh^2);
+}
+
+proc decoef(poly P, number n)
+"USAGE:  decoef(P,n);  P a poly, n a number
+RETURN:  ideal
+PURPOSE:  decompose polynomial P into summands with respect
+to the  presence of the number n in the coefficients
+NOTE:    n is usually a parameter with no power
+EXAMPLE: example decoef; shows examples
+"{
+  // decomposes polynomial into summands
+  // w.r.t. the presence of a number n in coeffs
+  // returns ideal
+  def br = basering;
+  int i,j=0,0;
+  int pos = npar(n);
+  if ((pos==0) || (P==0))
+  {
+    return(0);
+  }
+  pos = pos + nvars(basering);
+// map all pars except to vars, provided no things are in denominator
+  number con = content(P);
+  con = numerator(con);
+  P = cleardenom(P); //destroys content!
+  P = con*P; // restore the numerator part of the content
+  list M = ringlist(basering);
+  list L = M[1..4];
+  list Pars = L[1][2];
+  list Vars = L[2] + Pars;
+  L[1] = L[1][1]; // characteristic
+  L[2] = Vars;
+  // for non-comm things: don't need nc but graded algebra
+  //  list templ;
+  //  L[5] = templ;
+  //  L[6] = templ;
+  def @R = ring(L);
+  setring @R;
+  poly P = imap(br,P);
+  poly P0 = subst(P,var(pos),0);
+  poly P1 = P - P0;
+  ideal I = P0,P1;
+  setring br;
+  ideal I = imap(@R,I);
+  kill @R;
+  // check: P0+P1==P
+  poly Q = I[1]+I[2];
+  if (P!=Q)
+  {
+    "Warning: problem in decoef";
+  }
+  return(I);
+// substract the pure part from orig and check if n is remained there
+}
+example
+{
+ " EXAMPLE:"; echo=2;
+  ring r = (0,dh,dt),(Tx,Tt),dp;
+  poly P = (4*dh^2-dt)*Tx^3*Tt + dt*dh*Tt^2 + dh*Tt;
+  decoef(P,dt);
+  decoef(P,dh);
+}
+
+proc texcoef(number n)
+"USAGE:  texcoef(n);  n a number
+RETURN:  string
+PURPOSE:  converts the number n into TeX format
+NOTE: if n is a polynomial, texcoef adds extra brackets and performs some space substitutions
+EXAMPLE: example texcoef; shows examples
+"{
+  // makes tex from n
+  // and uses substitutions
+  // if n is a polynomial, adds brackets
+  number D  = denominator(n);
+  int DenIsOne = 0;
+  if ( D==number(1) )
+  {
+    DenIsOne = 1;
+  }
+  string sd = texpoly("",D);
+  sd = rmDol(sd);
+  sd = par2tex(sd);
+  number N  = numerator(n);
+  string sn = texpoly("",N);
+  sn = rmDol(sn);
+  sn = par2tex(sn);
+  string sout="";
+  int i;
+  int NisPoly = 0;
+  if (DenIsOne)
+  {
+    sout = sn;
+    for(i=1; i<=size(sout); i++)
+    {
+      if ( (sout[i]=="+") || (sout[i]=="-") )
+      {
+        NisPoly = 1;
+      }
+    }
+    if (NisPoly)
+    {
+      sout = "("+sout+")";
+    }
+  }
+  else
+  {
+    sout = "\\frac{"+sn+"}{"+sd+"}";
+  }
+  return(sout);
+}
+example
+{
+ " EXAMPLE:"; echo=2;
+  ring r = (0,dh,dt),(Tx,Tt),dp;
+  number n1,n2,n3 = dt/(4*dh^2-dt),(dt+dh)^2, 1/dh;
+  n1; texcoef(n1);
+  n2; texcoef(n2);
+  n3; texcoef(n3);
+}
+
+static proc rmDol(string s)
+{
+  // removes $s and _no_ (s on appearance
+  int i = size(s);
+  if (s[1] == "$") { s = s[2..i]; i--;}
+  if (s[1] == "(") { s = s[2..i]; i--;}
+  if (s[i] == "$") { s = s[1..i-1]; i--;}
+  if (s[i] == ")") { s = s[1..i-1];}
+  return(s);
+}
+
+proc difpoly2tex(ideal S, list P, list #)
+"USAGE:  difpoly2tex(S,P[,Q]);  S an ideal, P and optional Q are lists
+RETURN:  string
+PURPOSE: present the difference scheme in the nodal form
+ASSUME: ideal S is the result of @code{decoef} procedure
+NOTE: a list P may be empty or may contain parameters, which will not
+appear in denominators
+@* an optional list Q represents the part of the scheme, depending
+on other function, than the major part
+EXAMPLE: example difpoly2tex; shows examples
+"
+{
+  // S = sum s_i = orig diff poly or
+  // the result of decoef
+  // P = list of pars (numbers) not to be divided with, may be empty
+  // # is an optional list of polys, repr. the part dep. on "f", not on "u"
+  //  S = simplify(S,2); // destroys the leadcoef
+  // rescan S and remove 0s from it
+  int i;
+  ideal T;
+  int ss = ncols(S);
+  int j=1;
+  for(i=1; i<=ss; i++)
+  {
+    if (S[i]!=0)
+    {
+      T[j]=S[i];
+      j++;
+    }
+  }
+  S  = T;
+  ss = j-1;
+  int GotF = 1;
+  list F;
+  if (size(#)>0)
+  {
+    F = #;
+    if ( (size(F)==1) && (F[1]==0) )
+    {
+      GotF = 0;
+    }
+  }
+  else
+  {
+    GotF = 0;
+  }
+  int sf = size(F);
+
+  ideal SC;
+  int  sp = size(P);
+  intvec np;
+  int GotP = 1;
+  if (sp==0)
+  {
+    GotP = 0;
+  }
+  if (sp==1)
+  {
+    if (P[1]==0)
+    {
+      GotP = 0;
+    }
+  }
+  if (GotP)
+  {
+    for (i=1; i<=sp; i++)
+    {
+      np[i] = npar(P[i])+ nvars(basering);
+    }
+  }
+  for (i=1; i<=ss; i++)
+  {
+    SC[i] = leadcoef(S[i]);
+  }
+  if (GotF)
+  {
+    for (i=1; i<=sf; i++)
+    {
+      SC[ss+i] = leadcoef(F[i]);
+    }
+  }
+  def br = basering;
+// map all pars except to vars, provided no things are in denominator
+  list M = ringlist(basering);
+  list L = M[1..4]; // erase nc part
+  list Pars = L[1][2];
+  list Vars = L[2] + Pars;
+  L[1] = L[1][1]; // characteristic
+  L[2] = Vars;
+
+  def @R = ring(L);
+  setring @R;
+  ideal SC = imap(br,SC);
+  if (GotP)
+  {
+    for (i=1; i<=sp; i++)
+    {
+      SC = subst(SC,var(np[i]),1);
+    }
+  }
+  poly q=1;
+  q = lcm(q,SC);
+  setring br;
+  poly  q = imap(@R,q);
+  number lq = leadcoef(q);
+  //  lq;
+  number tmp;
+  string sout="";
+  string vname = "u";
+  for (i=1; i<=ss; i++)
+  {
+    tmp  = leadcoef(S[i]);
+    S[i] = S[i]/tmp;
+    tmp = tmp/lq;
+    sout = sout +"+ "+texcoef(tmp)+"\\cdot ("+exp2pt(S[i])+")";
+  }
+  if (GotF)
+  {
+    vname = "p"; //"f";
+    for (i=1; i<=sf; i++)
+    {
+      tmp  = leadcoef(F[i]);
+      F[i] = F[i]/tmp;
+      tmp = tmp/lq;
+      sout = sout +"+ "+texcoef(tmp)+"\\cdot ("+exp2pt(F[i],vname)+")";
+    }
+  }
+  sout = sout[3..size(sout)]; //rm first +
+  return(sout);
+}
+example
+{
+  "EXAMPLE:"; echo=2;
+  ring r = (0,dh,dt,V),(Tx,Tt),dp;
+  poly M = (4*dh*Tx+dt)^2*(Tt-1) + V*Tt*Tx;
+  ideal I = decoef(M,dt);
+  list L; L[1] = V;
+  difpoly2tex(I,L);
+  poly G = V*dh^2*(Tt-Tx)^2;
+  difpoly2tex(I,L,G);
+}
+
+
+proc magnitude(poly P)
+"USAGE:  magnitude(P);  P a poly
+RETURN:  poly
+PURPOSE: compute the square of the magnitude of a complex expression
+ASSUME: i is the variable of a basering
+EXAMPLE: example magnitude; shows examples
+"
+{
+  // check whether i is present among the vars
+  list L = ringlist(basering)[2]; // vars
+  int j; int cnt = 0;
+  for(j=size(L);j>0;j--)
+  {
+    if (L[j] == "i")
+    {
+      cnt = 1; break;
+    }
+  }
+  if (!cnt)
+  {
+    ERROR("a variable called i is expected in basering");
+  }
+  // i is present, check that i^2+1=0;
+//   if (NF(i^2+1,std(0)) != 0)
+//   {
+//     "Warning: i^2+1=0 does not hold. Reduce the output manually";
+//   }
+  poly re = subst(P,i,0);
+  poly im = (P - re)/i;
+  return(re^2+im^2);
+}
+example
+{
+  "EXAMPLE:"; echo=2;
+  ring r = (0,d),(g,i,sin,cos),dp;
+  poly P = d*i*sin - g*cos +d^2*i;
+  NF( magnitude(P), std(i^2+1) );
+}
+
+
+static proc clTex(string s)
+// removes beginning and ending $'s
+{
+  string t;
+  if (size(s)>2)
+  {
+    // why -3?
+     t = s[2..(size(s)-3)];
+  }
+  return(t);
+}
+
+static proc simfrac(poly up, poly down)
+{
+  // simplifies a fraction up/down
+  // into the form up/down = RT[1] + RT[2]/down
+  list LL = division(up,down);
+  list RT;
+  RT[1] =  LL[1][1,1]; // integer part
+  RT[2] = L[2][1]; // new numerator
+  return(RT);
+}
+
+proc findifs_example()
+"USAGE:  findifs_example();
+RETURN:  nothing (demo)
+PURPOSE:  demonstration of our approach and this library
+EXAMPLE: example findifs_example; shows examples
+"
+{
+
+  "* Equation: u_tt - A^2 u_xx -B^2 u_yy = 0; A,B are constants";
+  "* we employ three central differences";
+  "* the vector we act on is (u_xx, u_yy, u_tt, u)^T";
+  "* Set up the ring: ";
+  "ring r = (0,A,B,dt,dx,dy),(Tx,Ty,Tt),(c,dp);";
+  ring r = (0,A,B,dt,dx,dy),(Tx,Ty,Tt),(c,dp);
+  "* Set up the matrix with equation and approximations: ";
+  "matrix M[4][4] =";
+    "    // direct equation:";
+  "    -A^2, -B^2, 1, 0,";
+  "    // central difference u_tt";
+  "    0, 0,  -dt^2*Tt, (Tt-1)^2,";
+  "    // central difference u_xx";
+  "    -dx^2*Tx, 0, 0, (Tx-1)^2,";
+  "    // central difference u_yy";
+  "    0, -dy^2*Ty, 0, (Ty-1)^2;";
+  matrix M[4][4] =
+    // direct equation:
+    -A^2, -B^2, 1, 0,
+    // central difference u_tt
+    0, 0,  -dt^2*Tt, (Tt-1)^2,
+    // central difference u_xx
+    -dx^2*Tx, 0, 0, (Tx-1)^2,
+    // central difference u_yy
+    0, -dy^2*Ty, 0, (Ty-1)^2;
+//=========================================
+// CHECK THE CORRECTNESS OF EQUATIONS AS INPUT:
+ring rX = (0,A,B,dt,dx,dy,Tx,Ty,Tt),(Uxx, Uyy,Utt, U),(c,Dp);
+matrix M = imap(r,M);
+vector X = [Uxx, Uyy, Utt, U];
+ "* Print the differential form of equations: ";
+print(M*X);
+// END CHECK
+//=========================================
+ setring r;
+ "* Perform the elimination of module components:";
+ " module R = transpose(M);";
+ " module S = std(R);";
+ module R = transpose(M);
+ module S = std(R);
+ " * See the result of Groebner bases: generators are columns";
+ " print(S);";
+ print(S);
+ " * So, only the first column has its nonzero element in the last component";
+ " * Hence, this polynomial is the scheme";
+ " poly   p = S[4,1];" ;
+ poly   p = S[4,1]; // by elimination of module components
+ " print(p); ";
+ print(p);
+ list L; L[1]=A;L[2] = B;
+ ideal I = decoef(p,dt); // make splitting w.r.t. the appearance of dt
+ "* Create the nodal of the scheme in TeX format: ";
+ " ideal I = decoef(p,dt);";
+ " difpoly2tex(I,L);";
+ difpoly2tex(I,L); // the nodal form of the scheme in TeX
+ "* Preparations for the semi-factorized form: ";
+ poly pi1 = subst(I[2],B,0);
+ poly pi2 = I[2] - pi1;
+ " poly pi1 = subst(I[2],B,0);";
+ " poly pi2 = I[2] - pi1;";
+ "* Show the semi-factorized form of the scheme: 1st summand";
+ " factorize(I[1]); ";
+ factorize(I[1]); // semi-factorized form of the scheme: 1st summand
+ "* Show the semi-factorized form of the scheme: 2nd summand";
+ " factorize(pi1);";
+ factorize(pi1); // semi-factorized form of the scheme: 2nd summand
+ "* Show the semi-factorized form of the scheme: 3rd summand";
+ " factorize(pi1);";
+ factorize(pi2); // semi-factorized form of the scheme: 3rd summand
+}
+example
+{
+  "EXAMPLE:"; echo=1;
+ findifs_example();
+}
diff --git a/Singular/LIB/finitediff.lib b/Singular/LIB/finitediff.lib
new file mode 100644
index 0000000..61d6e1c
--- /dev/null
+++ b/Singular/LIB/finitediff.lib
@@ -0,0 +1,1770 @@
+/////////////////////////////////////////////////////////////////////////////
+version="version finitediff.lib 4.0.0.0 Jun_2013 "; // $Id: ed2686c3ffb984de38bf8e376c5e1ec8c5b5ec4b $
+category="Teaching";
+info="
+LIBRARY:  finitediff.lib   procedures to compute finite difference schemes
+                           for linear differential equations
+AUTHOR:                    Christian Dingler
+
+OVERVIEW:
+ at texinfo
+ Using @code{qepcad}/@code{qepcadsystem} from this
+ library requires the program @code{qepcad} to be installed.
+ You can download @code{qepcad} from
+ @uref{http://www.usna.edu/Users/cs/qepcad/INSTALL/IQ.html}
+ @end texinfo
+
+PROCEDURES:
+ visualize(f);            shows a scheme in index-notation
+ u(D[,#]);                gives some vector; depends on @derivatives
+ scheme([v1,..,vn]);      computes the finite difference scheme defined by v1,..,vn
+ laxfrT(Ut,U,space);      Lax-Friedrich-approximation for the time-direction
+ laxfrX(Ux,U,space);      Lax-Friedrich-approximation for the space-direction
+ forward(U1,U2,VAR);      forward-approximation
+ backward(U1,U2,VAR);     backward-approximation
+ central1st(U1,U2,VAR);   central-approximation of first order
+ central2nd(U1,U2,VAR);   central-approximation of second order
+ trapezoid(U1,U2,VAR);    trapezoid-approximation
+ midpoint(U1,U2,VAR);     midpoint-approximation
+ pyramid(U1,U2,VAR);      pyramid-approximation
+ setinitials(variable,der[,#]);    constructs and sets the basering for further computations
+ errormap(f);        performs the Fouriertransformation of a poly
+ matrixsystem(M,A);    gives the scheme of a pde-system as one matrix
+ timestep(M);        gives the several timelevels of a scheme derived from a pde-system
+ fouriersystem(M,A);  performs the Fouriertransformation of a matrix scheme
+ PartitionVar(f,n);      partitions a poly into the var(n)-part and the rest
+ ComplexValue(f);        computes the complex value of f, var(1) being the imaginary unit
+ VarToPar(f);            substitute var(i) by par(i)
+ ParToVar(f);            substitute par(i) by var(i)
+ qepcad(f);              ask QEPCAD for equivalent constraints to f<1
+ qepcadsystem(l);        ask QEPCAD for equivalent constraints to all eigenvals of some matrices being <1
+";
+
+LIB "ring.lib";
+LIB "general.lib";
+LIB "standard.lib";
+LIB "linalg.lib";
+LIB "matrix.lib";
+LIB "poly.lib";
+LIB "teachstd.lib";
+LIB "qhmoduli.lib";
+///////////////////////////////////////////////////////////////////////
+static proc getit(module M)
+{
+  int nderiv=pos(U, at derivatives);
+  def M2=groebner(M);
+  module N1=gen(nderiv);
+  def N2=intersect(M2,N1);
+  def S=N2[1][nderiv];
+  return(S);
+}
+///////////////////////////////////////////////////////////////////////
+proc visualize(poly f)
+"USAGE:   visualize(f); f of type poly.
+RETURN:  type string; translates the polynomial form of a finite difference scheme into an indexed one as often seen in literature
+EXAMPLE: example visualize; shows an example
+"
+{
+  def n=size(f);
+  string str;
+  intvec v;
+  if (n>0)
+  {
+    int i;
+    int j;
+    for(i=1;i<=n;i++)
+    {
+      intvec w=leadexp(f);
+      for(j=1;j<=size(@variables);j++)
+      {
+        v[j]=w[j+1];
+      }
+      if(i==1)
+      {
+        str=print(leadcoef(f),"%s")+"*"+"U("+print(v,"%s")+")";
+      }
+      else
+      {
+        str=str+"+"+print(leadcoef(f),"%s")+"*"+"U("+print(v,"%s")+")";
+      }
+      kill w;
+      f=f-lead(f);
+    }
+  }
+  return(str);
+}
+example
+{
+"EXAMPLE:";echo=2;
+ list D="Ux","Ut","U";
+ list P="a";
+ list V="t","x";
+ setinitials(V,D,P);
+ scheme(u(Ut)+a*u(Ux),trapezoid(Ux,U,x),backward(Ut,U,t));
+ visualize(_);
+}
+
+///////////////////////////////////
+static proc imageideal()
+{
+
+  def n=size(@variables)-1;
+  ideal IDEAL=var(1),var(2);
+  int j;
+  for(j=1;j<=n;j++)
+  {
+    ideal II=var(2+j+n)+var(1)*var(2+2*n+j);
+    IDEAL=IDEAL+II;
+    kill II;
+  }
+  return(IDEAL);
+}
+/////////////////////////////////////
+proc u(string D,list #)
+"USAGE: u(D[,#]); D a string that occurs in the list of @derivatives, # an optional list of integers.
+RETURN: type vector; gives the vector, that corresponds with gen(n)*m, where m is the monomial defined by #
+EXAMPLE: example u; shows an example
+"
+{
+  def n=size(#);
+  def nv=nvars(basering)-1;
+  int nn;
+  if(nv<=n)
+  {
+    nn=nv;
+  }
+  else
+  {
+    nn=n;
+  }
+  int index=pos(D, at derivatives);
+  poly g=1;
+  if(nn>=1)
+  {
+    int j;
+    for(j=1;j<=nn;j++)
+    {
+      int nnn;
+      nnn=int(#[j]);
+      g=var(1+j)**nnn*g;
+      kill nnn;
+    }
+    return(gen(index)*g);
+  }
+  else
+  {
+    return(gen(index)*g);
+  }
+}
+example
+{
+  "EXAMPLE:";echo=2;
+  list D="Ux","Uy","Ut","U";
+  list P="a","b";
+  list V="t","x","y";
+  setinitials(V,D,P);
+  u(Ux);
+  u(Ux,2,3,7);
+  u(Uy)+u(Ut)-u(Ux);
+  u(U)*234-dx*dt*dy*3*u(Uy);
+}
+
+/////////////////////////////////////////////////////////
+static proc pos(string D,list L)
+{
+  int j;
+  int index=-1;
+  def n=size(L);
+  for(j=1;j<=n;j++)
+  {
+    if(D==L[j])
+    {
+      index=j;
+    }
+  }
+  return(index);
+}
+///////////////////////////////////
+static proc re(list L)
+{
+  def n=size(L);
+  int j;
+  for(j=1;j<=n;j++)
+  {
+    string s="string "+print(L[j],"%s")+"="+"nameof("+print(L[j],"%s")+")"+";";
+    execute(s);
+    kill s;
+    exportto(Top,`L[j]`);
+  }
+}
+///////////////////////////////////////////////
+proc scheme(list #)
+"USAGE:  scheme([v1,..,vn]); v1,..,vn of type vector
+RETURN:  poly
+PURPOSE: performs substitutions by the means of Groebner basis computation
+of the submodule, generated by the input vectors, then intersects the
+intermediate result with the suitable component in order to get a finite
+difference scheme
+NOTE:  works only for a single PDE, for the case of a system use @code{matrixsystem}
+EXAMPLE: example scheme; shows an example
+"
+{
+  def N=size(#);
+  if(N==0)
+  {
+    if(defined(M)==1)
+    {
+      kill M;
+      module M;
+    }
+    else
+    {
+      module M;
+    }
+  }
+  else
+  {
+    int j;
+    if(defined(M)==1)
+    {
+      kill M;
+      module M;
+      for(j=1;j<=N;j++)
+      {
+        M=M+#[j];
+      }
+    }
+    else
+    {
+      module M;
+      for(j=1;j<=N;j++)
+      {
+        M=M+#[j];
+      }
+    }
+  }
+  def S=getit(M);
+  matrix mat[1][1]=S;
+  list l=timestep(mat);
+  poly f=l[2][1,1];
+  return(f);
+}
+example
+{
+  "EXAMPLE:";echo=2;
+  list D="Ux","Ut","U";
+  list P="a";
+  list V="t","x";
+  setinitials(V,D,P);
+  def s1=scheme(u(Ut)+a*u(Ux),backward(Ux,U,x),forward(Ut,U,t));
+  s1;
+}
+////////////////////////
+static proc diffpar(poly ff)
+{
+  def gg=print(ff,"%s");
+  def str="d"+gg;
+  return(`str`);
+}
+////////////////////////
+proc laxfrT(string Ut, string U, poly space)
+"USAGE:   laxfrT(U1,U2,var); U1, U2 are the names of occuring derivatives, var is a variable in the basering;
+RETURN:   type vector; gives a predefined approximation of the Lax-Friedrich-approximation for the derivation in the timevariable as often used in literature;
+NOTE:     see also laxfrX, setinitials, scheme; Warning: laxfrT is not to be interchanged with laxfrX
+EXAMPLE:  example laxfrT; shows an example
+"
+{
+  poly time=var(2);
+  poly dtime=diffpar(time);
+  poly dspace=diffpar(space);
+  def v=dtime*space*u(Ut)-time*space*u(U)+1/2*(space**2*u(U)+u(U));
+  return(v);
+}
+example
+{
+  "EXAMPLE:";echo=2;
+  list D="Ux","Ut","U";
+  list P="a";
+  list V="t","x";
+  setinitials(V,D,P);
+  laxfrT(Ux,U,x);
+}
+////////////////////////
+proc laxfrX(string Ux, string U, poly space)
+"USAGE: laxfrX(U1,U2,var); U1, U2 are the names of occuring derivatives, var is a variable in the basering;
+RETURN: type vector; gives a predefined approximation of the Lax-Friedrich-approximation for the derivation in one of the spatial variables as often used in literature;
+NOTE:   see also laxfrT, setinitials, scheme; Warning: laxfrX is not to be interchanged with laxfrT
+EXAMPLE: example laxfrX; shows an example
+"
+{
+  poly dspace = diffpar(space);
+  def v=2*dspace*space*u(Ux)-(space**2-1)*u(U);
+  return(v);
+}
+example
+{
+  "EXAMPLE:";echo=2;
+  list D="Ux","Ut","U";
+  list P="a";
+  list V="t","x";
+  setinitials(V,D,P);
+  laxfrX(Ux,U,x);
+}
+////////////////////////
+proc forward(string U1,string U2,poly VAR)
+"USAGE:   forward(U1,U2,var); U1, U2 are the names of occuring derivatives, var is a variable in the basering;
+RETURN:   type vector; gives a predefined approximation of the forward approximation as often used in literature;
+NOTE:     see also laxfrT,setinitials,scheme;
+EXAMPLE:  example forward; shows an example
+"
+{
+  if(pos(U1, at derivatives)<pos(U2, at derivatives))
+    {
+      def V1=U1;
+      def V2=U2;
+    }
+  else
+    {
+      def V1=U2;
+      def V2=U1;
+    }
+  def v=diffpar(VAR)*u(V1)+u(V2)-VAR*u(V2);
+  return(v);
+}
+example
+{
+  "EXAMPLE:";echo=2;
+  list D="Ut","Ux","Uy","U";
+  list V="t","x","y";
+  list P="a","b";
+  setinitials(V,D,P);
+  forward(Ux,U,x);
+  forward(Uy,U,y);
+  forward(Ut,U,t);
+}
+///////////////////////
+proc backward(string U1,string U2,poly VAR)
+"USAGE:   backward(U1,U2,var); U1, U2 are the names of occuring derivatives, var is a variable in the basering;
+RETURN:   type vector; gives a predefined approximation of the backward approximation as often used in literature;
+NOTE:     see also forward,laxfrT,setinitials,scheme;
+EXAMPLE:  example backward; shows an example
+"
+{
+  if(pos(U1, at derivatives)<pos(U2, at derivatives))
+    {
+      def V1=U1;
+      def V2=U2;
+    }
+  else
+    {
+      def V1=U2;
+      def V2=U1;
+    }
+  def v=diffpar(VAR)*VAR*u(V1)+u(V2)-VAR*u(V2);
+  return(v);
+}
+example
+{
+  "EXAMPLE:";echo=2;
+  list D="Ut","Ux","Uy","U";
+  list V="t","x","y";
+  list P="a","b";
+  setinitials(V,D,P);
+  backward(Ux,U,x);
+  backward(Uy,U,y);
+  backward(Ut,U,t);
+}
+/////////////////////////////
+proc central1st(string U1,string U2,poly VAR)
+"USAGE:   central1st(U1,U2,var); U1, U2 are the names of occuring derivatives, var is a variable in the basering;
+RETURN:   type vector; gives a predefined approximation of the first-order-central-approximation as often used in literature;
+NOTE:     see also forward,laxfrT,setinitials,scheme;
+EXAMPLE:  example central1st; shows an example
+"
+{
+  if(pos(U1, at derivatives)<pos(U2, at derivatives))
+    {
+      def V1=U1;
+      def V2=U2;
+    }
+  else
+    {
+      def V1=U2;
+      def V2=U1;
+    }
+  def v=2*diffpar(VAR)*VAR*u(V1)+u(V2)-VAR**2*u(V2);
+  return(v);
+}
+example
+{
+  "EXAMPLE:";echo=2;
+  list D="Ut","Ux","Uy","U";
+  list V="t","x","y";
+  list P="a","b";
+  setinitials(V,D,P);
+  central1st(Ux,U,x);
+  central1st(Uy,U,y);
+}
+////////////////////////////////
+proc central2nd(string U1,string U2,poly VAR)
+"USAGE:   central2nd(U1,U2,var); U1, U2 are the names of occuring derivatives, var is a variable in the basering;
+RETURN:   type vector; gives a predefined approximation of the second-order-central-approximation as often used in literature;
+NOTE:     see also forward,laxfrT,setinitials,scheme;
+EXAMPLE:  example central2nd; shows an example
+"
+{
+  if(pos(U1, at derivatives)<pos(U2, at derivatives))
+    {
+      def V1=U1;
+      def V2=U2;
+    }
+  else
+    {
+      def V1=U2;
+      def V2=U1;
+    }
+  def v=diffpar(VAR)**2*VAR*u(V1)-(VAR**2*u(V2)-2*VAR*u(V2)+u(V2));
+  return(v);
+}
+example
+{
+  "EXAMPLE:";echo=2;
+  list D="Uxx","Ux","Utt","Ut","U";
+  list P="lambda";
+  list V="t","x";
+  setinitials(V,D,P);
+  central2nd(Uxx,U,x);
+  central2nd(Utt,U,t);
+}
+/////////////////////////////////
+proc trapezoid(string U1,string U2,poly VAR)
+"USAGE:   trapezoid(U1,U2,var); U1, U2 are the names of occuring derivatives, var is a variable in the basering;
+RETURN:   type vector; gives a predefined approximation of the trapezoid-approximation as often used in literature;
+NOTE:     see also forward,laxfrT,setinitials,scheme;
+EXAMPLE:  example trapezoid; shows an example
+"
+{
+  if(pos(U1, at derivatives)<pos(U2, at derivatives))
+    {
+      def V1=U1;
+      def V2=U2;
+    }
+  else
+    {
+      def V1=U2;
+      def V2=U1;
+    }
+  def v=1/2*diffpar(VAR)*(VAR+1)*u(V1)+(1-VAR)*u(V2);
+  return(v);
+}
+example
+{
+  "EXAMPLE:";echo=2;
+  list D="Uxx","Ux","Utt","Ut","U";
+  list P="lambda";
+  list V="t","x";
+  setinitials(V,D,P);
+  trapezoid(Uxx,Ux,x);
+  trapezoid(Ux,U,x);
+}
+///////////////////////////////////
+proc midpoint(string U1,string U2,poly VAR)
+"USAGE:   midpoint(U1,U2,var); U1, U2 are the names of occuring derivatives, var is a variable in the basering;
+RETURN:   type vector; gives a predefined approximation of the midpoint-approximation as often used in literature;
+NOTE:     see also forward,laxfrT,setinitials,scheme;
+EXAMPLE:  example midpoint; shows an example
+"
+{
+  if(pos(U1, at derivatives)<pos(U2, at derivatives))
+    {
+      def V1=U1;
+      def V2=U2;
+    }
+  else
+    {
+      def V1=U2;
+      def V2=U1;
+    }
+  def v=2*diffpar(VAR)*VAR*u(V1)+(1-VAR**2)*u(V2);
+  return(v);
+}
+example
+{
+  "EXAMPLE:";echo=2;
+  list D="Uxx","Ux","Utt","Ut","U";
+  list P="lambda";
+  list V="t","x";
+  setinitials(V,D,P);
+  midpoint(Ux,U,x);
+}
+//////////////////////////////////////
+proc pyramid(string U1,string U2,poly VAR)
+"USAGE:   pyramid(U1,U2,var); U1, U2 are the names of occuring derivatives, var is a variable in the basering;
+RETURN:   type vector; gives a predefined approximation of the pyramid-approximation as often used in literature;
+NOTE:     see also forward,laxfrT,setinitials,scheme;
+EXAMPLE:  example pyramid; shows an example
+"
+{
+  if(pos(U1, at derivatives)<pos(U2, at derivatives))
+    {
+      def V1=U1;
+      def V2=U2;
+    }
+  else
+    {
+      def V1=U2;
+      def V2=U1;
+    }
+  def v=1/3*diffpar(VAR)*(VAR**2+VAR+1)*u(V1)+(VAR-VAR**3)*u(V2);
+  return(v);
+}
+example
+{
+  "EXAMPLE:";echo=2;
+  list D="Uxx","Ux","Utt","Ut","U";
+  list P="lambda";
+  list V="t","x";
+  setinitials(V,D,P);
+  pyramid(Ux,U,x);
+}
+//////////////////////////////////////////////
+proc setinitials(list variable, list der,list #)
+"USAGE:  setinitials(V,D[,P]); V,D,P are lists with strings as elements
+RETURN:  no return value: sets the dependence order of the occuring derivatives,
+constructs the suitable ring to compute in containing user chosen parameters, sets new basering
+NOTE:    P is optional, used to introduce some additional parameters into the ring. The Sine and
+Cosine values needed for the fourier transformation are symbolically introduced under the names
+string(c)+nameof(variable), i.e. if x is any spatial variable then cx:=cosine(dx*ksi), when
+regarding the fourier transform after ksi (for sine respectively). Artificial parameters I,T,Px,Py
+are introduced for the later eigenvalue analysis. Variables can be transformed into parameters
+of similar name
+EXAMPLE: example setinitials; shows an example
+"
+{
+  def LV=variable;
+  def @variables=variable;
+  def @derivatives=der;
+  export(@variables);
+  export(@derivatives);
+  re(der);
+  int j;
+  string dvar="d"+print(LV[1],"%s");
+  dvar=dvar+","+"d"+print(LV[2],"%s");
+  string pvar="P"+print(LV[2],"%s");
+  string COS="C"+print(LV[2],"%s");
+  string SIN="S"+print(LV[2],"%s");
+  for(j=3;j<=size(LV);j++)
+    {
+      dvar=dvar+","+"d"+print(LV[j],"%s");
+      pvar=pvar+","+"P"+print(LV[j],"%s");
+      COS=COS+","+"C"+print(LV[j],"%s");
+      SIN=SIN+","+"S"+print(LV[j],"%s");
+    }
+  string scf="(0,"+"I,"+"T,"+pvar+","+COS+","+SIN+","+print(#,"%s")+","+dvar+")";  //coefficient_field
+  string svars="(i";
+  kill j;
+  int j;
+  for(j=1;j<=size(LV);j++)
+    {
+      svars=svars+","+print(LV[j],"%s");
+    }
+  string cosine;
+  string sine;
+  kill j;
+  int j;
+  cosine="c"+print(LV[2],"%s");
+  sine="s"+print(LV[2],"%s");
+  for(j=3;j<=size(LV);j++)
+    {
+      cosine=cosine+","+"c"+print(LV[j],"%s");
+      sine=sine+","+"s"+print(LV[j],"%s");
+    }
+  kill j;
+  string strvar=cosine+","+sine+")";
+  svars=svars+","+strvar;            ////variables
+  string sord="(c,lp)";         ////ordering
+  string sring="ring Q="+scf+","+svars+","+sord+";";
+  execute(sring);
+  ideal Id=i**2+1;
+  int j;
+  for(j=1;j<=size(LV)-1;j++)
+    {
+      ideal II=var(2+j+size(LV)-1)**2+var(2+j+2*(size(LV)-1))**2-1;
+      Id=Id+II;
+      kill II;
+    }
+  if(defined(basering)==1)
+    {
+      kill basering;
+    }
+  qring R=std(Id);
+  setring R;
+  // comment by VL: it's better to return this ring! causes many changes
+  // across the library
+  export(R);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  list D="Ut","Ux","Uy","U";
+  list V="t","x","y";
+  list P="alpha","beta","gamma";
+  setinitials(V,D,P);////does not show the ring, since there is no output
+  basering;///does show the ring
+}
+////////////////////////////
+proc errormap(poly f)
+"USAGE:    errormap(f); f of type poly
+RETURN:   type poly; performs the fouriertransformation of a single polynomial
+EXAMPLE:  example errormap; shows an example
+"
+{
+  ideal Id=imageideal();
+  map phi=R,Id;
+  def g=phi(f);
+  g=reduce(g,std(0));
+  return(g);
+}
+example
+{
+  "EXAMPLE";echo=2;
+  list D="Ux","Ut","U";
+  list P="a";
+  list V="t","x";
+  setinitials(V,D,P);
+  scheme(u(Ut)+a*u(Ux),central1st(Ux,U,x),backward(Ut,U,t));
+  errormap(_);
+}
+/////////////////////////////////////
+static proc stepmatrix(int n, poly f)
+{
+  int spavars=size(@variables)-1;
+  int range=n*spavars;
+  if(f==0)
+    {
+      return(unitmat(range));
+    }
+  matrix M[range][range];
+  int length=size(f);
+  intvec max=maxexp(f);
+  int i;
+  intvec shiftback;
+  intvec vzero;
+  intvec vmax;
+  intvec shiftforward;
+  for(i=1;i<=size(max);i++)
+    {
+     shiftback[i]=int(floor(max[i]/2));
+     vzero[i]=0;
+     vmax[i]=n-1;
+     shiftforward[i]=0;
+    }
+  kill i;
+  int i;
+  for(i=1;i<=range;i++)
+    {
+      poly g=f;
+    }
+  kill i;
+}
+//////////////////////////////////////
+static proc floor(n)
+{
+  number h1=numerator(n);
+  number h2=denominator(n);
+  return((h1- (h1 mod h2))/h2);
+}
+/////////////////////////////////////
+static proc maxexp(poly f)
+{
+  int length=size(f);
+  poly g=f;
+  intvec v;
+  int i;
+  for(i=1;i<size(@variables);i++)
+    {
+      v[i]=leadexp(g)[i+2];
+    }
+  while(g!=0)
+    {
+      int j;
+      for(j=1;j<size(@variables);j++)
+  {
+    v[j]=maximal(leadexp(g)[j+2],v[j]);
+    g=g-lead(g);
+  }
+      kill j;
+    }
+  return(v);
+}
+////////////////////////////////////
+static proc maximal(int n1,int n2)
+{
+  if(n1>n2)
+    {
+      return(n1);
+    }
+  else
+    {
+      return(n2);
+    }
+}
+////////////////////////////////////
+static proc minimal(int n1, int n2)
+{
+  return(-maximal(-n1,-n2));
+}
+////////////////////////////////////
+static proc MatrixEntry(int n, intvec v)
+{
+  int j;
+  int entry;
+  int spavar=size(@variables)-1;
+  for(j=1;j<=spavar;j++)
+    {
+      entry=entry+v[j]*n**(spavar-j);
+    }
+  entry=entry+1;
+  return(entry);
+}
+//////////////////////////////////
+static proc CompareVec(intvec ToTest, intvec Reference)//1 if ToTest>=Reference, 0 else
+{
+  int i;
+  for(i=1;i<=size(@variables)-1;i++)
+    {
+      if(ToTest[i+2]<Reference[i])
+  {
+    return(0);
+  }
+    }
+  return(1);
+}
+/////////////////////////////////
+static proc MaxVecZero(intvec ToTest, intvec Reference) //KGV, size=size(input)
+{
+  int length=size(ToTest);
+  int i;
+  intvec Maximum;
+  for(i=1;i<=length;i++)
+    {
+      Maximum[i]=maximal(ToTest[i],Reference[i]);
+    }
+  return(Maximum);
+}
+//////////////////////////////////
+proc matrixsystem(list Matrices,list Approx)
+"USAGE:   matrixsytem(M,A); where the M=Mt,M1,..,Mn is a list with square matrices of the same dimension as entries, and A=At,A1,..,An gives the corresponding approximations for the several variables (t,x1,..,xn) as vector. Intended to solve Mt*U_t + M1*U_x1+..+Mn*U_xn=0 as a linear sytem of partial differential equations numerically by a finite difference scheme;
+RETURN:   type matrix; gives back the matrices B1,B2 that represent the finite difference scheme, partitioned into different time levels in the form:  B1*U(t=N)=B2*U(t<N), where N is the maximal occurring degree (timelevel) of t.
+EXAMPLE:  example matrixsystem; shows an example
+"
+{
+  if(size(Matrices)>size(@variables) or size(Matrices)!=size(Approx))
+    {
+      ERROR("Check number of variables: it must hold  #(matrices)<= #(spatial variables)+1  !!! ");
+    }
+  if(size(Matrices)!=size(Approx))
+    {
+      ERROR("Every variable needs EXACTLY ONE approximation rule, i.e. #(first argument) =#(second argument) ! ");
+    }
+  ideal Mon=leadmonomial(Approx[1]);
+  int N=size(Matrices);
+  int i;
+  for(i=2;i<=N;i++)
+    {
+      Mon=Mon,leadmonomial(Approx[i]);
+    }
+  kill i;
+  poly LCM=lcm(Mon);
+  matrix M[nrows(Matrices[1])][ncols(Matrices[1])];
+  int i;
+  for(i=1;i<=size(Matrices);i++)
+    {
+      M=M+(LCM/leadmonomial(Approx[i]))*normalize(Approx[i])[size(@derivatives)]*Matrices[i];
+    }
+  kill i;
+  return(M);
+}
+example
+{
+  "EXAMPLE:";echo=2;
+  list D="Ut","Ux","Uy","U";
+  list V="t","x","y";
+  list P="a","b";
+  setinitials(V,D,P);
+  list Mat=unitmat(2),unitmat(2);
+  list Appr=forward(Ut,U,t),forward(Ux,U,x);
+  matrixsystem(Mat,Appr);
+}
+//////////////////////////////////
+proc timestep(matrix M)
+"USAGE:   timestep(M); M a square matrix with polynomials over the basering as entries;
+RETURN:   type list; gives two  matrices M1,M2 that are the splitting of M with respect to the degree of the variable t in the entries, where the first list-entry M1 consists of the polynomials of the highest timelevel and M2 of the lower levels in the form:  M=0  =>  M1=M2,    i.e. M1-M2=M
+NOTE:     intended to be used for the finite-difference-scheme-construction and partition into the several time steps
+EXAMPLE:  example timestep; shows an example
+"
+{
+  int N=nrows(M);
+  int i;
+  int maxdegT;
+  for(i=1;i<=N;i++)
+    {
+      int j;
+      for(j=1;j<=N;j++)
+  {
+    poly f=M[i,j];
+    int k;
+    for(k=1;k<=size(f);k++)
+      {
+        if(leadexp(M[i,j])[2]>maxdegT)
+    {
+      maxdegT=leadexp(M[i,j])[2];
+    }
+        f=f-lead(f);
+      }
+    kill f;
+    kill k;
+  }
+      kill j;
+    }
+  kill i;
+  matrix highT[nrows(M)][nrows(M)];
+  vector leftside=0;
+  int GenIndex=0;
+  int i;
+  for(i=1;i<=N;i++)
+    {
+      int j;
+      for(j=1;j<=N;j++)
+  {
+    poly f=M[i,j];
+    int k;
+    for(k=1;k<=size(f)+1;k++)
+      {
+        if(leadexp(f)[2]==maxdegT)
+    {
+      GenIndex++;
+      highT[i,j]=highT[i,j]+lead(f);
+      leftside=leftside+highT[i,j]*gen(GenIndex);
+    }
+        f=f-lead(f);
+      }
+    kill k;
+    kill f;
+  }
+      kill j;
+    }
+  kill i;
+  matrix tUpper=highT;
+  matrix tLower=-1*(M-tUpper);
+  tUpper=tUpper/content(leftside);
+  tLower=tLower/content(leftside);
+  list L=tUpper,tLower;
+  return(L);
+}
+example
+{
+  "EXAMPLE:"; echo=2;
+  list D="Ut","Ux","Uy","U";
+  list V="t","x","y";
+  list P="a","b";
+  setinitials(V,D,P);
+  list Mat=unitmat(2),unitmat(2);
+  list Apr=forward(Ut,U,t),forward(Ux,U,x);
+  matrixsystem(Mat,Apr);
+  timestep(_);
+}
+//////////////////////////////////
+proc fouriersystem(list Matrices, list Approx)
+"USAGE:   fouriersystem(M,A); M a list of matrices, A a list of approximations;
+RETURN:   type list; each entry is some matrix obtained by performing the substitution of the single approximations into the system of pde's, partitioning the equation into the several timesteps and fouriertransforming these parts
+EXAMPLE:  example fouriersystem; shows an example
+"
+{
+  matrix M=matrixsystem(Matrices,Approx);
+  matrix T1=timestep(M)[1];
+  matrix T0=timestep(M)[2];
+  int i;
+  for(i=1;i<=nrows(M);i++)
+    {
+      int j;
+      for(j=1;j<=nrows(M);j++)
+  {
+    T1[i,j]=errormap(T1[i,j]);
+    T1[i,j]=VarToPar(T1[i,j]);
+    T0[i,j]=errormap(T0[i,j]);
+    T0[i,j]=VarToPar(T0[i,j]);
+  }
+      kill j;
+    }
+  kill i;
+  ideal EV1=eigenvals(T1)[1];
+  ideal EV0=eigenvals(T0)[1];
+  list L=list(T1,T0),list(EV1,EV0);
+  def N1=size(EV1);
+  def N0=size(EV0);
+  list CV1;
+  list CV0;
+  int i;
+  for(i=1;i<=N1;i++)
+  {
+  CV1[i]=VarToPar(EV1[i]);
+  if(content(CV1[i])==CV1[i])
+  {
+  CV1[i]=content(CV1[i]);
+  CV1[i]=VarToPar(ComplexValue(numerator(CV1[i])))/VarToPar(ComplexValue(denominator(CV1[i])));
+  }
+  }
+  kill i;
+  int i;
+  for(i=1;i<=N0;i++)
+  {
+  CV0[i]=VarToPar(EV0[i]);
+  if(content(CV0[i])==CV0[i])
+  {
+  CV0[i]=content(CV0[i]);
+  CV0[i]=VarToPar(ComplexValue(numerator(CV0[i])))/VarToPar(ComplexValue(denominator(CV0[i])));
+  }
+  }
+  kill i;
+  list CV=list(CV1,CV0);
+  L=L,CV;
+  return(L);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  list D="Ut","Ux","Uy","U";
+  list V="t","x","y";
+  list P="a","b";
+  setinitials(V,D,P);
+  matrix M[2][2]=0,-a,-a,0;
+  list Mat=unitmat(2),M;
+  list Appr=forward(Ut,U,t),trapezoid(Ux,U,x);
+  def s=fouriersystem(Mat,Appr);s;
+}
+//////////////////////////////////
+proc PartitionVar(poly f,int n)
+"USAGE:   PartitionVar(f); f a poly in the basering;
+RETURN:   type poly; gives back a list L=f1,f2 obtained by the partition of f into two parts f1,f2 with deg_var_n(f1) >0  deg_var_n(f2)=0
+EXAMPLE:  example PartitionVar; shows an example
+"
+{
+  if(n>=nvars(basering))
+    {
+      ERROR("this variable does not exist in the current basering");
+    }
+  int i;
+  poly partition=0;
+  poly g=f;
+  for(i=1;i<=size(f);i++)
+    {
+      if(leadexp(g)[n]!=0)
+  {
+    partition=partition+lead(g);
+  }
+      g=g-lead(g);
+    }
+  list L=partition,f-partition;
+  return(L);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  list D="Ut","Ux","Uy","U";
+  list V="t","x","y";
+  list P="a","b";
+  setinitials(V,D,P);////does not show the ring, since there is no output
+  basering;///does show the ring
+  poly f=t**3*cx**2-cy**2*dt+i**3*sx;
+  PartitionVar(f,1); ////i is the first variable
+}
+//////////////////////////////////
+proc ComplexValue(poly f)
+"USAGE:   ComplexValue(f); f a poly in the basering;
+RETURN:   type poly; gives back the formal complex-value of f, where var(1) is redarded as the imaginary unit. Does only make sence, if the proc <setinitials> is executed before -> nvars <= npars
+EXAMPLE:  example ComplexValue; shows an example
+"
+{
+  poly g=ParToVar(f);
+  def L=PartitionVar(g,1);
+  poly f1=subst(L[1],var(1),1);
+  poly f2=L[2];
+  poly result=reduce(f1**2+f2**2,std(0));
+  return(result);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  list D="Ut","Ux","Uy","U";
+  list V="t","x","y";
+  list P="a","b";
+  setinitials(V,D,P);////does not show the ring, as there is  no output
+  basering;///does show the ring
+  poly f=t**3*cx**2-cy**2*dt+i**3*sx;
+  f;
+  ComplexValue(f);
+}
+//////////////////////////////////
+proc VarToPar(poly f)
+"USAGE:   VarToPar(f); f a poly in the basering;
+RETURN:   type poly; gives back the poly obtained by substituting var(i) by par(i), for all variables. Does only make sence, if the proc <setinitials> is executed before -> nvars <= npars;
+EXAMPLE:  example VarToPar; shows an example
+"
+{
+  int N=nvars(basering);
+  int i;
+  def g=f;
+  for(i=1;i<=N;i++)
+    {
+      g=subst(g,var(i),par(i));
+    }
+  return(g);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  list D="Ut","Ux","Uy","U";
+  list V="t","x","y";
+  list P="a","b";
+  setinitials(V,D,P);////does not show the ring, as there is  no output
+  basering;///does show the ring
+  poly f=t**3*cx**2-cy**2*dt+i**3*sx;
+  f;
+  VarToPar(f);
+}
+/////////////////////////////////////
+proc ParToVar(poly f)
+"USAGE:   ParToVar(f); f a poly in the basering;
+RETURN:   type poly; gives back the poly obtained by substituting par(i) by var(i), for the first nvars(basering parameters. Does only make sence, if setinitials is executed before -> nvars <= npars. Is the opposite action to VarToPar, see example ParToVar;
+EXAMPLE:  example ParToVar; shows an example
+"
+{
+  int N=nvars(basering);
+  int i;
+  number g=number(VarToPar(f));
+  number denom=denominator(g);
+  g=denom*g;
+  def gg=subst(g,par(1),var(1));
+  for(i=2;i<=N;i++)
+    {
+      gg=subst(gg,par(i),var(i));
+    }
+  return(gg/denom);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  list D="Ut","Ux","Uy","U";
+  list V="t","x","y";
+  list P="a","b";
+  setinitials(V,D,P);////does not show the ring, as there is  no output
+  basering;///does show the ring
+  poly f=t**3*cx**2-cy**2*dt+i**3*sx/dt*dx;
+  f;
+  def g=VarToPar(f);
+  g;
+  def h=ParToVar(g);
+  h==f;
+}
+/////////////////////////////////////////
+proc qepcad(poly f)
+"USAGE:   qepcad(f); f a poly in the basering;
+RETURN:   type list; gives back some constraints that are equivalent to f<1 (computed by QEPCAD);
+EXAMPLE:  example qepcad; shows an example
+"
+{
+  // how to test, whether QEPCAD is installed?
+  createQCfilter(); // creates/overwrites qepcadfilter.pl
+  system("sh","rm -f QEPCAD-out");
+  system("sh","rm -f QEPCAD-in");
+  if(denominator(content(f))==1)
+  {
+    poly g=f-1;
+  }
+  else
+  {
+    if(f==content(f))
+    {
+      poly g=f*denominator(content(f))-1*denominator(content(f));
+      g=ParToVar(g);
+      g=reduce(g,std(0));
+    }
+    else
+    {
+      poly g=cleardenom(f)-1/content(f);
+      g=ParToVar(g);
+      g=reduce(g,std(0));
+    }
+  }
+  string in="QEPCAD-in";
+  string out="QEPCAD-out";
+  link l1=in;
+  link l2=out;
+  string s1="[trial]";    //description
+  string s2=varlist();    //the variables
+  string s3=nfreevars();  //number of free variables
+  string s4=aquantor()+"["+writepoly(g)+rel()+"]."; //the input prenex formula
+  string s5=projection();
+  string s6=projection();
+  string s7=choice();
+  string s8=solution();
+  write(l1,s1,s2,s3,s4,s5,s6,s7,s8);
+  system("sh","qepcad < QEPCAD-in | qepcadfilter.pl > QEPCAD-out");
+  string output=read(out);
+  print(output,"%s");
+  if(size(output)==0)
+  {
+    return("Try manually");    //maybe too few cells
+  }
+  if(find(output,"FALSE")!=0)
+  {
+    return("FALSE");
+  }
+  if(find(output,"WARNING")!=0)
+  {
+    return("WARNING! Try manually");
+  }
+  else
+  {
+    string strpolys=findthepoly(output);
+    list lpolys=listpolynew(strpolys);
+    return(lpolys);
+  }
+  system("sh","rm -f QEPCAD-out");
+  system("sh","rm -f QEPCAD-in");
+
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  list D="Ux","Ut","U";
+  list P="a";
+  list V="t","x";
+  setinitials(V,D,P);
+  def s1=scheme(u(Ut)+a*u(Ux),laxfrX(Ux,U,x),laxfrT(Ut,U,x));
+  s1;
+  def s2=errormap(s1);
+  s2;
+  def s3=ComplexValue(s2);s3;
+  qepcad(s3);
+}
+///////////////////////////////////////////
+proc createQCfilter()
+{
+  // writes the following to the file qepcadfilter.pl
+  // is there already such a file? remove it!
+  system("sh","rm -f qepcadfilter.pl");
+  link l=":w qepcadfilter.pl";
+  write(l, "#!/usr/bin/perl");
+  write(l, "$flag = 0;");
+  write(l, "$res = \"\";");
+  write(l,"while(<>)");
+  write(l,"{ if ($_ =~ /Warning|WARNING|warning|Error|error|ERROR/) { print $_; }");
+  write(l,"elsif ($_ =~ /An\ equivalent/) { $flag = 1; }");
+  write(l,"elsif ($flag == 1 && $_ ne \"\n\") { print $_; $flag = 0; } }");
+}
+
+///////////////////////////////////////////
+proc qepcadsystem(list l)
+"USAGE:  qepcadsytem(f); l a list;
+RETURN:  list
+PURPOSE: gives back some constraints that are equivalent to the
+eigenvalues of the matrices in the list l being < 1 (computed by QEPCAD)
+EXAMPLE:  example qepcadsystem; shows an example
+"
+{
+  // how to test, whether QEPCAD is installed?
+  createQCfilter(); // creates/overwrites qepcadfilter.pl
+  system("sh","rm -f QEPCAD-out");
+  system("sh","rm -f QEPCAD-in");
+  string in="QEPCAD-in";
+  string out="QEPCAD-out";
+  link l1=in;
+  link l2=out;
+  string s1="[trial]";    //description
+  string s2=varlist();    //the variables
+  string s3=nfreevars();  //number of free variables
+  string thepolys;
+  int n2=size(l[2]);
+  int count;
+  int i;
+  list lpolys;
+  int j;
+  for(j=1;j<=n2;j++)
+  {
+    count++;
+    poly g2=ParToVar(l[2][j]);
+    if(denominator(content(g2))==1)
+    {
+      lpolys[count]=writepoly(ParToVar(reduce(g2-1,std(0))))+rel();
+    }
+    else
+    {
+      if(g2==content(g2))
+      {
+        g2=g2*denominator(content(g2))-1*denominator(content(g2));
+        g2=ParToVar(g2);
+        g2=reduce(g2,std(0));
+        lpolys[count]=writepoly(g2)+rel();
+      }
+      else
+      {
+        lpolys[count]=writepoly(reduce(ParToVar(cleardenom(g2)-1/content(g2)),std(0)))+rel();
+      }
+    }
+    kill g2;
+  }
+  kill j;
+  int k;
+  for(k=1;k<=size(lpolys);k++)
+  {
+    thepolys=thepolys+lpolys[k];
+    if(k<size(lpolys))
+    {
+      thepolys=thepolys+print(" /","s%")+print("\\ ","s%");
+    }
+  }
+  string s4=aquantor()+"["+thepolys+"]."; //the input prenex formula
+  string s5=projection();
+  string s6=projection();
+  string s7=choice();
+  string s8=solution();
+  write(l1,s1,s2,s3,s4,s5,s6,s7,s8);
+  system("sh","qepcad < QEPCAD-in | qepcadfilter.pl > QEPCAD-out");
+  string output=read(out);
+  print(output,"%s");
+  if(size(output)==0)
+  {
+    ERROR("Try manually");    //maybe too few cells
+  }
+  if(find(output,"FALSE")!=0)
+  {
+    ERROR("FALSE");
+  }
+  if(find(output,"WARNING")!=0)
+  {
+    ERROR("WARNING! Try manually");
+  }
+  else
+  {
+    string strpolys=findthepoly(output);
+    list llpolys=listpolynew(strpolys);
+    return(llpolys);
+  }
+  system("sh","rm -f QEPCAD-out");
+  system("sh","rm -f QEPCAD-in");
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  list D="Ut","Ux","Uy","U";
+  list V="t","x","y";
+  list P="a","b";
+  setinitials(V,D,P);
+  matrix M[2][2]=0,-a,-a,0;
+  list Mat=unitmat(2),M;
+  list Appr=forward(Ut,U,t),forward(Ux,U,x);
+  //matrixsystem(Mat,Appr);
+  //timestep(_);
+  fouriersystem(Mat,Appr);
+  qepcadsystem(_[2]);
+}
+///////////////////////////////////////////
+static proc substbracketstar(string s)
+{
+  int i;
+  int k;
+  int index=1;
+  string finish=s;
+  for(k=1;k<=size(s);k++)
+  {
+    if(finish[1]=="(" or finish[1]=="*" or finish[1]==" ")
+    {
+      kill finish;
+      index=index+1;
+      string finish=s[index..size(s)];
+    }
+  }
+  for(i=1;i<=size(finish);i++)
+  {
+    if(finish[i]=="*" or finish[i]=="(" or finish[i]== ")")
+    {
+      finish[i]=" ";
+    }
+  }
+  return(finish);
+}
+
+////////////////////////////////////
+static proc distribution(string SUM, string MON)
+{
+  string sum=substbracketstar(SUM);
+  string mon=substbracketstar(MON);
+  string result;
+  list signs;
+  list p;
+  int i;
+  int j;
+  int init;
+  for(i=2;i<=size(sum);i++)
+  {
+    if(sum[i]=="+" or sum[i]=="-")
+    {
+      j++;
+      p[j]=i;
+    }
+  }
+  if(j==0)
+  {
+    if(sum[1]!="-")
+    {
+      result=sum+" "+" "+mon;
+      result="+"+" "+result;
+    }
+    else
+    {
+      result=sum+" "+mon;
+    }
+  }
+  else
+  {
+    int l;
+    int anfang;
+    if(sum[1]=="-")
+    {
+      result="-"+" "+result;
+      anfang=2;
+    }
+    else
+    {
+      result="+"+" "+result;
+      if(sum[1]=="+")
+      {
+        anfang=2;
+      }
+      else
+      {
+        anfang=1;
+      }
+    }
+    for(l=1;l<=j;l++)
+    {
+      string a;
+      int k;
+      for(k=anfang;k<=p[l]-1;k++)
+      {
+        a=a+sum[k];
+      }
+      result=result+" "+a+" "+mon+" "+sum[p[l]];
+      anfang=p[l]+1;
+      kill a;
+      kill k;
+    }
+    if(p[j]<size(sum))
+    {
+      int kk;
+      string aa;
+      for(kk=anfang;kk<=size(sum);kk++)
+      {
+        aa=aa+sum[kk];
+      }
+      result=result+" "+aa+" "+mon;
+      kill aa;
+      kill kk;
+    }
+    else
+    {
+      int kkk;
+      string aaa;
+      for(kkk=anfang;kkk<size(sum);kkk++)
+      {
+        aaa=aaa+sum[kkk];
+      }
+      result=result+" "+aaa+" "+mon;
+      kill aaa;
+      kill kkk;
+    }
+  }
+  return(result);
+}
+/////////////////////////////////////////////////////////////////
+static proc writepoly(poly f)
+{
+  poly g=f;
+  string lc;
+  string lm;
+  string strpoly;
+  string intermediate;
+  int n=size(f);
+  int i;
+  for(i=1;i<=n;i++)
+  {
+
+    lc=substbracketstar(string(leadcoef(g)));
+    lm=substbracketstar(string(leadmonom(g)));
+    intermediate=distribution(lc,lm);
+    strpoly=strpoly+" "+intermediate;
+    g=g-lead(g);
+  }
+  return(strpoly);
+}
+///////////////////////////////////////////////////////////////
+static proc varlist()
+{
+  poly p1=par(2+size(@variables));
+  p1=ParToVar(p1);
+  string name=print(p1,"%s");
+  string p="("+name+",";
+  int i;
+  for(i=3+size(@variables);i<=npars(basering);i++)
+  {
+    p1=ParToVar(par(i));
+    name=substbracketstar(print(p1,"%s"));
+    p=p+name+",";
+  }
+  p1=ParToVar(par(2));
+  name=print(p1,"%s");
+  p=p+name+")";
+  return(p);
+}
+///////////////////////////////////////////////////////
+static proc normalization()
+{
+  int n1=npars(basering)-size(@variables);
+  int n2=npars(basering)-n1;
+  string assumption="assume["+" "+substbracketstar(print(par(n1+1),"%s"))+" >0";
+  int i;
+  for(i=2;i<=n2;i++)
+  {
+    string s=" /\\"+" "+substbracketstar(print(par(n1+i),"%s"))+" >0";
+    assumption=assumption+" "+s;
+    kill s;
+  }
+  assumption=assumption+" ]"+newline+"go";
+  return(assumption);
+}
+///////////////////////////////////////////////////////
+static proc projection()
+{
+  string s="go";
+  return(s);
+}
+///////////////////////////////////////////////////////
+static proc choice()
+{
+  string s="go";
+  return(s);
+}
+///////////////////////////////////////////////////////
+static proc solution()
+{
+  string s="go";
+  return(s);
+}
+///////////////////////////////////////////////////////
+static proc nfreevars()
+{
+  int n=npars(basering)-size(@variables)-1;
+  string no=print(n,"%s");
+  return(no);
+}
+/////////////////////////////////////////////////////////
+static proc aquantor()
+{
+  string s="(A "+print(var(2),"%s")+")";
+  return(s);
+}
+////////////////////////////////////////////////////////
+static proc rel()
+{
+  return("<0");
+}
+/////////////////////////////////////////////////////////
+static proc rm()
+{
+  system("sh","rm -f dummy");
+  system("sh","rm -f QEPCAD-in");
+}
+////////////////////////////////////////////////////////
+static proc findthepoly(string word)
+{
+  int init=1;
+  int index=find(word,newline);
+  if(index==size(word) or index== 0)
+  {
+    return(word);
+  }
+  else
+  {
+    while(index<size(word))
+    {
+      init=index;
+      index=find(word,newline,index+1);
+    }
+  }
+  string thepoly=word[(init+1)..(size(word)-1)];
+  return(thepoly);
+}
+//////////////////////////////////////////////////
+static proc listpolynew(string thepoly)
+{
+  string p=thepoly;
+  intvec v;
+  p=TestAndDelete(p,"[")[1];
+  p=TestAndDelete(p,"]")[1];    //remove the brackets
+  string AND="/"+"\\";
+  string OR="\\"+"/";
+  list thesigns=AND,OR,"~","<==>","==>","<==";///these can occur in QEPCAD
+  int i;
+  for(i=1;i<=size(thesigns);i++)
+  {
+    list l=TestAndDelete(p,thesigns[i]);
+    p=l[1];
+    v=addintvec(v,l[2]);
+    kill l;
+  }
+  intvec w=rightorder(v);
+  int N=size(v);
+  list lstrings;
+  if(size(w)==1 and w[1]==0)
+  {
+    N=0;
+    lstrings[1]=p;
+  }
+  else
+  {
+    string s1=p[1..w[1]-1];
+    lstrings[1]=s1;
+    int j;
+    for(j=1;j<N;j++)
+    {
+      string s2=p[w[j]..w[j+1]-1];
+      lstrings[j+1]=s2;
+      kill s2;
+    }
+    string s3=p[w[N]..size(p)];
+    lstrings[N+1]=s3;
+  }
+  list cutstrings;
+  int k;
+  list Id;
+  for(k=1;k<=N+1;k++)
+  {
+    cutstrings[k]=cutoffrel(lstrings[k]);
+    Id[k]=translatenew(cutstrings[k]);
+  }
+  return(Id);
+
+
+}
+/////////////////////////////////////////////////
+static proc translatenew(string word)
+{
+  int n=size(word);
+  string subword=word[1..n];
+  string strpoly="poly f=";
+  list linterim;
+  int i;
+  for(i=1;i<=n;i++)
+  {
+    if(i<n and subword[i]==" " and subword[i+1]!="+" and subword[i+1]!="-" and subword[i+1]!=" " and subword[i-1]!="+" and subword[i-1]!="-" and subword[i-1]!=" " and i>1)
+    {
+      linterim[i]="*";
+    }
+    else
+    {
+      linterim[i]=word[i];
+    }
+    strpoly=strpoly+print(linterim[i],"%s");
+  }
+  strpoly=strpoly+";";
+  execute(strpoly);
+  return(f);
+}
+//////////////////////////////////////////////////
+static proc rightorder(intvec v)
+////////////orders the entries of an intvec from small to bigger
+{
+  list ldown=intveclist(v);
+  list lup;
+  intvec v1;
+  int counter;
+  int min;
+  int i;
+  for(i=1;i<=size(v);i++)
+  {
+    min=Min(listintvec(ldown));
+    lup[i]=min;
+    counter=listfind(ldown,min);
+    ldown=delete(ldown,counter);
+  }
+  intvec result=listintvec(lup);
+  return(result);
+}
+/////////////////////////////////////////////////
+static proc listfind(list l, int n)
+//////gives the position of n in l, 0 if not found
+{
+  int i;
+  intvec counter;
+  int j=1;
+  for(i=1;i<=size(l);i++)
+  {
+    if(n==l[i])
+    {
+      counter[j]=i;
+      j++;
+    }
+  }
+  int result=Min(counter);
+  return(result);
+}
+//////////////////////////////////////////////////
+static proc cutoffrel(string str)
+/////////cut off the relations "/=,<= etc." from output-string
+{
+  list rels="<=",">=","<",">","/=","=";  //these are all of qepcad's relations
+  int i;
+  list l;
+  for(i=1;i<=size(rels);i++)
+  {
+    l[i]=find(str,rels[i]);
+  }
+  intvec v=listintvec(l);
+  v=addintvec(v,v);
+  int position=Min(v);
+  string result;
+  if(position==0)
+  {
+    result=str;
+  }
+  else
+  {
+    result=str[1..position-1];
+  }
+  return(result);
+}
+//////////////////////////////////////////////////
+static proc addintvec(intvec v1, intvec v2)
+///////concatenates two intvecs and deletes occurring zeroentries, output intvec
+{
+  list lresult;
+  int i;
+  list l1;
+  list l2;
+  for(i=1;i<=size(v1);i++)
+  {
+    l1[i]=v1[i];
+  }
+  kill i;
+  int k;
+  for(k=1;k<=size(v2);k++)
+  {
+    l2[k]=v2[k];
+  }
+  lresult=l1+l2;
+  intvec result;
+  int j;
+  int counter=1;
+  for(j=1;j<=size(lresult);j++)
+  {
+    if(lresult[j]!=0)
+    {
+      result[counter]=lresult[j];
+      counter++;
+    }
+  }
+  return(result);
+
+}
+/////////////////////////////////////////////////
+static proc intveclist(intvec v)
+//////returns the intvec as list
+{
+  list l;
+  int i;
+  for(i=size(v);i>=1;i--)
+  {
+    l[i]=v[i];
+  }
+  return(l);
+}
+//////////////////////////////////////////////////
+static proc listintvec(list l)
+//////////returns the list as intvec: only integer-entries allowed
+{
+  intvec v;
+  int i;
+  for(i=size(l);i>=1;i--)
+  {
+    v[i]=l[i];
+  }
+  return(v);
+}
+//////////////////////////////////////////////////
+static proc TestAndDelete(string str, string booleansign)
+{
+  int decide=find(str,booleansign);
+  intvec v;
+  v[1]=decide;
+  while(decide!=0 and decide<size(str))//if booleansign ist not contained in str
+  {
+    int n=size(v);
+    decide=find(str,booleansign,decide+1);
+    if(decide!=0)
+    {
+      v[n+1]=decide;
+    }
+    kill n;
+  }
+  if(size(v)==1 and v[1]==0)/////i.e. booleansign NOT in str
+  {
+    list result=str,v;
+    return(result);
+  }
+  else
+  {
+    list l;
+    string p;
+    int i;
+    int j;
+    for(i=1;i<=size(str);i++)///copy the string str into l
+    {
+      l[i]=str[i];
+    }
+    kill i;
+    for(j=1;j<=size(v);j++)///replace booleansign by empty char
+    {
+      int k;
+      for(k=0;k<=size(booleansign)-1;k++)
+      {
+        l[v[j]+k]=" ";
+      }
+      kill k;
+    }
+    int s;
+    for(s=1;s<=size(l);s++)///copy back
+    {
+      p=p+string(l[s]);
+    }
+    kill s;
+    kill l;
+    list result=p,v;
+    return(result);
+  }
+}
+//////////////////////////////////////////////////
+static proc nchoice(int n1,int n2)
+{
+  int N2=maximal(n1,n2);
+  int N1=minimal(n1,n2);
+  if(N1==0)
+  {
+    return(N2);
+  }
+  else
+  {
+    return(N1);
+  }
+}
diff --git a/Singular/LIB/finvar.lib b/Singular/LIB/finvar.lib
new file mode 100644
index 0000000..b333cc2
--- /dev/null
+++ b/Singular/LIB/finvar.lib
@@ -0,0 +1,8485 @@
+//////////////////////////////////////////////////////////////////////////////
+version="version finvar.lib 4.0.1.1 Dec_2104 "; // $Id: d4acc15bf9565c90266ab993f8bf98965490043a $
+category="Invariant theory";
+info="
+LIBRARY:  finvar.lib    Invariant Rings of Finite Groups
+AUTHOR: Agnes E. Heydtmann, contact via Wolfram Decker: decker at mathematik.uni-kl.de
+        Simon A. King, email: simon.king at nuigalway.ie
+OVERVIEW:
+ A library for computing polynomial invariants of finite matrix groups and
+ generators of related varieties. The algorithms are based on B. Sturmfels,
+ G. Kemper, S. King and W. Decker et al..
+
+PROCEDURES:
+ invariant_ring()                  generators of the invariant ring (i.r.)
+ invariant_ring_random()           generators of the i.r., randomized alg.
+ primary_invariants()              primary invariants (p.i.)
+ primary_invariants_random()       primary invariants, randomized alg.
+ invariant_algebra_reynolds()      minimal generating set for the invariant
+                                   ring of a finite matrix group, in the non-modular case
+ invariant_algebra_perm()          minimal generating set for the invariant
+                                   ring or a permutation group, in the non-modular case
+
+ cyclotomic()                      cyclotomic polynomial
+ group_reynolds()                  finite group and Reynolds operator (R.o.)
+ molien()                          Molien series (M.s.)
+ reynolds_molien()                 Reynolds operator and Molien series
+ partial_molien()                  partial expansion of Molien series
+ evaluate_reynolds()               image under the Reynolds operator
+ invariant_basis()                 basis of homogeneous invariants of a degree
+ invariant_basis_reynolds()        as invariant_basis(), with R.o.
+ primary_char0()                   primary invariants (p.i.) in char 0
+ primary_charp()                   primary invariants in char p
+ primary_char0_no_molien()         p.i., char 0, without Molien series
+ primary_charp_no_molien()         p.i., char p, without Molien series
+ primary_charp_without()           p.i., char p, without R.o. or Molien series
+ primary_char0_random()            primary invariants in char 0, randomized
+ primary_charp_random()            primary invariants in char p, randomized
+ primary_char0_no_molien_random()  p.i., char 0, without M.s., randomized
+ primary_charp_no_molien_random()  p.i., char p, without M.s., randomized
+ primary_charp_without_random()    p.i., char p, without R.o. or M.s., random.
+ power_products()                  exponents for power products
+ secondary_char0()                 secondary invariants (s.i.) in char 0
+ irred_secondary_char0()           irreducible s.i. in char 0
+ secondary_charp()                 s.i. in char p, with Molien series and
+                                   Reynolds operator
+ secondary_no_molien()             s.i., without Molien series but with
+                                   Reynolds operator
+ irred_secondary_no_molien()       irreducible s.i., without Molien series
+                                   but with Reynolds operator
+ secondary_and_irreducibles_no_molien() s.i. & irreducible s.i., without M.s.
+ secondary_not_cohen_macaulay()    s.i. when the invariant ring is not Cohen-Macaulay
+ orbit_variety()                   ideal of the orbit variety
+ rel_orbit_variety()               ideal of a relative orbit variety (new version)
+ relative_orbit_variety()          ideal of a relative orbit variety (old version)
+ image_of_variety()                ideal of the image of a variety
+ orbit_sums                        orbit sums of a set of monomials under the action of
+                                   a permutation group
+";
+///////////////////////////////////////////////////////////////////////////////
+// perhaps useful procedures (no help provided):
+// unique()                        is a matrix among other matrices?
+// exponent()                      gives the exponent of a number
+// sort_of_invariant_basis()       lin. ind. invariants of a degree mod p.i.
+// next_vector                     lists all of Z^n with first nonzero entry 1
+// int_number_map                  integers 1..q are mapped to q field elements
+// search                          searches a number of p.i., char 0
+// p_search                        searches a number of p.i., char p
+// search_random                   searches a # of p.i., char 0, randomized
+// p_search_random                 searches a # of p.i., char p, randomized
+// concat_intmat                   concatenates two integer matrices
+// GetGroup                        gets disjoint cycle presentation of perm. group,
+//                                 yields permuation matrices
+///////////////////////////////////////////////////////////////////////////////
+
+LIB "matrix.lib";
+LIB "elim.lib";
+LIB "general.lib";
+LIB "algebra.lib";
+
+///////////////////////////////////////////////////////////////////////////////
+// Checks whether the last parameter, being a matrix, is among the previous
+// parameters, also being matrices
+///////////////////////////////////////////////////////////////////////////////
+proc unique (list #)
+{ int s=size(#); def m=#[s];
+  for (int i=1;i<s;i++)
+  {
+    if (#[i]==m) { return(0); }
+  }
+  return(1);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc cyclotomic (int i)
+"USAGE:   cyclotomic(i); i integer > 0
+RETURNS: the i-th cyclotomic polynomial (type <poly>) as one in the first ring
+         variable
+THEORY:  x^i-1 is divided by the j-th cyclotomic polynomial where j takes on
+         the value of proper divisors of i
+EXAMPLE: example cyclotomic; shows an example
+"
+{ if (i<=0)
+  { "ERROR:   the input should be > 0.";
+    return();
+  }
+  poly v1=var(1);
+  if (i==1)
+  { return(v1-1);                      // 1-st cyclotomic polynomial
+  }
+  poly min=v1^i-1;
+  matrix s[1][2];
+  min=min/(v1-1);                      // dividing by the 1-st cyclotomic
+                                       // polynomial
+  int j=2;
+  int n;
+  poly c;
+  int flag=1;
+  while(2*j<=i)                        // there are no proper divisors of i
+  { if ((i%j)==0)                      // greater than i/2
+    { if (flag==1)
+      { n=j;                           // n stores the first proper divisor of
+      }                                // i > 1
+      flag=0;
+      c=cyclotomic(j);                 // recursive computation
+      s=min,c;
+      s=matrix(syz(ideal(s)));         // dividing
+      min=s[2,1];
+    }
+    if (n*j==i)                        // the earliest possible point to break
+    { break;
+    }
+    j++;
+  }
+  min=min/leadcoef(min);               // making sure that the leading
+  return(min);                         // coefficient is 1
+}
+example
+{ "EXAMPLE:"; echo=2;
+          ring R=0,(x,y,z),dp;
+          print(cyclotomic(25));
+}
+
+proc group_reynolds (list #)
+"USAGE:   group_reynolds(G1,G2,...[,v]);
+         G1,G2,...: nxn <matrices> generating a finite matrix group, v: an
+         optional <int>
+ASSUME:  n is the number of variables of the basering, g the number of group
+         elements
+RETURN:  a <list>, the first list element will be a gxn <matrix> representing
+         the Reynolds operator if we are in the non-modular case; if the
+         characteristic is >0, minpoly==0 and the finite group non-cyclic the
+         second list element is an <int> giving the lowest common multiple of
+         the matrix group elements' order (used in molien); in general all
+         other list elements are nxn <matrices> listing all elements of the
+         finite group
+DISPLAY: information if v does not equal 0
+THEORY:  The entire matrix group is generated by getting all left products of
+         generators with the new elements from the last run through the loop
+         (or the generators themselves during the first run). All the ones that
+         have been generated before are thrown out and the program terminates
+         when no new elements found in one run. Additionally each time a new
+         group element is found the corresponding ring mapping of which the
+         Reynolds operator is made up is generated. They are stored in the rows
+         of the first return value.
+EXAMPLE: example group_reynolds; shows an example
+"
+{ int ch=char(basering);              // the existance of the Reynolds operator
+                                      // is dependent on the characteristic of
+                                      // the base field
+  int gen_num;                        // number of generators
+ //------------------------ making sure the input is okay ---------------------
+  if (typeof(#[size(#)])=="int")
+  { if (size(#)==1)
+    { "ERROR:   there are no matrices given among the parameters";
+      return();
+    }
+    int v=#[size(#)];
+    gen_num=size(#)-1;
+  }
+  else                                 // last parameter is not <int>
+  { int v=0;                           // no information is default
+    gen_num=size(#);
+  }
+  if (typeof(#[1])<>"matrix")
+  { "ERROR:   The parameters must be a list of matrices and maybe an <int>";
+    return();
+  }
+  int n=nrows(#[1]);
+  if (n<>nvars(basering))
+  { "ERROR:   the number of variables of the basering needs to be the same";
+    "         as the dimension of the matrices";
+    return();
+  }
+  if (n<>ncols(#[1]))
+  { "ERROR:   matrices need to be square and of the same dimensions";
+    return();
+  }
+  matrix vars=matrix(maxideal(1));     // creating an nx1-matrix containing the
+  vars=transpose(vars);                // variables of the ring -
+  matrix REY=#[1]*vars;                // calculating the first ring mapping -
+                                       // REY will contain the Reynolds
+                                       // operator -
+  matrix G(1)=#[1];                    // G(k) are elements of the group -
+  if (ch<>0 && minpoly==0 && gen_num<>1) // finding out of which order the
+  { matrix I=diag(1,n);                  // group element is
+    matrix TEST=G(1);
+    int o1=1;
+    int o2;
+    while (TEST<>I)
+    { TEST=TEST*G(1);
+      o1++;
+    }
+  }
+  int i=1;
+ // -------------- doubles among the generators should be avoided -------------
+  for (int j=2;j<=gen_num;j++)         // this loop adds the parameters to the
+  {                                    // group, leaving out doubles and
+                                       // checking whether the parameters are
+                                       // compatible with the task of the
+                                       // procedure
+    if (not(typeof(#[j])=="matrix"))
+    { "ERROR:   The parameters must be a list of matrices and maybe an <int>";
+      return();
+    }
+    if ((n!=nrows(#[j])) or (n!=ncols(#[j])))
+    { "ERROR:   matrices need to be square and of the same dimensions";
+       return();
+    }
+    if (unique(G(1..i),#[j]))
+    { i++;
+      matrix G(i)=#[j];
+      if (ch<>0 && minpoly==0)         // finding out of which order the group
+      { TEST=G(i);                     // element is
+        o2=1;
+        while (TEST<>I)
+        { TEST=TEST*G(i);
+          o2++;
+        }
+        o1=o1*o2 div gcd(o1,o2);       // lowest common multiple of the element
+      }                                // orders -
+      REY=concat(REY,#[j]*vars);       // adding ring homomorphisms to REY
+    }
+  }
+  int g=i;                             // G(1)..G(i) are generators without
+                                       // doubles - g generally is the number
+                                       // of elements in the group so far -
+  j=i;                                 // j is the number of new elements that
+                                       // we use as factors
+  int k, m, l;
+  if (v)
+  { "";
+    "  Generating the entire matrix group and the Reynolds operator...";
+    "";
+  }
+ // -------------- main loop that finds all the group elements ----------------
+  while (1)
+  { l=0;                               // l is the number of products we get in
+                                       // one going
+    for (m=g-j+1;m<=g;m++)
+    { for (k=1;k<=i;k++)
+      { l=l+1;
+        matrix P(l)=G(k)*G(m);         // possible new element
+      }
+    }
+    j=0;
+    for (k=1;k<=l;k++)
+    { if (unique(G(1..g),P(k)))
+      { j++;                           // a new factor for next run
+        g++;
+        matrix G(g)=P(k);              // a new group element -
+        if (ch<>0 && minpoly==0 && i<>1) // finding out of which order the
+        { TEST=G(g);                     //group element is
+          o2=1;
+          while (TEST<>I)
+          { TEST=TEST*G(g);
+            o2++;
+          }
+          o1=o1*o2 div gcd(o1,o2);         // lowest common multiple of the element
+        }                              // orders -
+        REY=concat(REY,P(k)*vars);     // adding new mapping to REY
+        if (v)
+        { "  Group element ",g," has been found.";
+        }
+      }
+      kill P(k);
+    }
+    if (j==0)                          // when we didn't add any new elements
+    { break;                           // in one run through the while loop
+    }                                  // we are done
+  }
+  if (v)
+  { if (g<=i)
+    { "  There are only ",g," group elements.";
+    }
+    "";
+  }
+  REY=transpose(REY);                 // when we evaluate the Reynolds operator
+                                      // later on, we actually want 1xn
+                                      // matrices
+  if (ch<>0)
+  { if ((g%ch)==0)
+    { if (voice==2)
+      { "WARNING: The characteristic of the coefficient field divides the group order.";
+        "         Proceed without the Reynolds operator!";
+      }
+      else
+      { if (v)
+        { "  The characteristic of the base field divides the group order.";
+          "  We have to continue without Reynolds operator...";
+          "";
+        }
+      }
+      kill REY;
+      matrix REY[1][1]=0;
+      return(list(REY,G(1..g)));
+    }
+    if (minpoly==0)
+    { if (i>1)
+      { return(list(REY,o1,G(1..g)));
+      }
+      return(list(REY,G(1..g)));
+    }
+  }
+  if (v)
+  { "  Done generating the group and the Reynolds operator.";
+    "";
+  }
+  return(list(REY,G(1..g)));
+}
+example
+{ "EXAMPLE: Sturmfels: Algorithms in Invariant Theory 2.3.7:"; echo=2;
+         ring R=0,(x,y,z),dp;
+         matrix A[3][3]=0,1,0,-1,0,0,0,0,-1;
+         list L=group_reynolds(A);
+         print(L[1]);
+         print(L[2..size(L)]);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Returns i such that root^i==n, i.e. it heavily relies on the right input.
+///////////////////////////////////////////////////////////////////////////////
+proc exponent(number n, number root)
+{ int i=0;
+   while((n/root^i)<>1)
+   { i++;
+   }
+   return(i);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc molien (list #)
+"USAGE:   molien(G1,G2,...[,ringname,lcm,flags]);
+         G1,G2,...: nxn <matrices>, all elements of a finite matrix group,
+         ringname: a <string> giving a name for a new ring of characteristic 0
+         for the Molien series in case of prime characteristic, lcm: an <int>
+         giving the lowest common multiple of the elements' orders in case of
+         prime characteristic, minpoly==0 and a non-cyclic group, flags: an
+         optional <intvec> with three components: if the first element is not
+         equal to 0 characteristic 0 is simulated, i.e. the Molien series is
+         computed as if the base field were characteristic 0 (the user must
+         choose a field of large prime characteristic, e.g. 32003), the second
+         component should give the size of intervals between canceling common
+         factors in the expansion of the Molien series, 0 (the default) means
+         only once after generating all terms, in prime characteristic also a
+         negative number can be given to indicate that common factors should
+         always be canceled when the expansion is simple (the root of the
+         extension field does not occur among the coefficients)
+ASSUME:  n is the number of variables of the basering, G1,G2... are the group
+         elements generated by group_reynolds(), lcm is the second return value
+         of group_reynolds()
+RETURN:  in case of characteristic 0 a 1x2 <matrix> giving enumerator and
+         denominator of Molien series; in case of prime characteristic a ring
+         with the name `ringname` of characteristic 0 is created where the same
+         Molien series (named M) is stored
+DISPLAY: information if the third component of flags does not equal 0
+THEORY:  In characteristic 0 the terms 1/det(1-xE) for all group elements of
+         the Molien series are computed in a straight forward way. In prime
+         characteristic a Brauer lift is involved. The returned matrix gives
+         enumerator and denominator of the expanded version where common
+         factors have been canceled.
+EXAMPLE: example molien; shows an example
+"
+{ def br=basering;                     // the Molien series depends on the
+  int ch=char(br);                     // characteristic of the coefficient
+                                       // field -
+  int g;                               // size of the group
+ //---------------------- making sure the input is okay -----------------------
+  if (typeof(#[size(#)])=="intvec")
+  { if (size(#[size(#)])==3)
+    { int mol_flag=#[size(#)][1];
+      if (#[size(#)][2]<0 && (ch==0 or (ch<>0 && mol_flag<>0)))
+      { "ERROR:   the second component of <intvec> should be >=0"
+        return();
+      }
+      int interval=#[size(#)][2];
+      int v=#[size(#)][3];
+    }
+    else
+    { "ERROR:   <intvec> should have three components";
+      return();
+    }
+    if (ch<>0)
+    { if (typeof(#[size(#)-1])=="int")
+      { int r=#[size(#)-1];
+        if (typeof(#[size(#)-2])<>"string")
+        { "ERROR:   In characteristic p>0 a <string> must be given for the name of a new";
+          "         ring where the Molien series can be stored";
+          return();
+        }
+        else
+        { if (#[size(#)-2]=="")
+          { "ERROR:   <string> may not be empty";
+            return();
+          }
+          string newring=#[size(#)-2];
+          g=size(#)-3;
+        }
+      }
+      else
+      { if (typeof(#[size(#)-1])<>"string")
+        { "ERROR:   In characteristic p>0 a <string> must be given for the name of a new";
+          "         ring where the Molien series can be stored";
+          return();
+        }
+        else
+        { if (#[size(#)-1]=="")
+          { "ERROR:   <string> may not be empty";
+            return();
+          }
+          string newring=#[size(#)-1];
+          g=size(#)-2;
+          int r=g;
+        }
+      }
+    }
+    else                               // then <string> ist not needed
+    { g=size(#)-1;
+    }
+  }
+  else                                 // last parameter is not <intvec>
+  { int v=0;                           // no information is default
+    int mol_flag=0;                    // computing of Molien series is default
+    int interval=0;
+    if (ch<>0)
+    { if (typeof(#[size(#)])=="int")
+      { int r=#[size(#)];
+        if (typeof(#[size(#)-1])<>"string")
+        { "ERROR:   in characteristic p>0 a <string> must be given for the name of a new";
+          "         ring where the Molien series can be stored";
+            return();
+        }
+        else
+        { if (#[size(#)-1]=="")
+          { "ERROR:   <string> may not be empty";
+            return();
+          }
+          string newring=#[size(#)-1];
+          g=size(#)-2;
+        }
+      }
+      else
+      { if (typeof(#[size(#)])<>"string")
+        { "ERROR:   in characteristic p>0 a <string> must be given for the name of a new";
+          "         ring where the Molien series can be stored";
+          return();
+        }
+        else
+        { if (#[size(#)]=="")
+          { "ERROR:   <string> may not be empty";
+            return();
+          }
+          string newring=#[size(#)];
+          g=size(#)-1;
+          int r=g;
+        }
+      }
+    }
+    else
+    { g=size(#);
+    }
+  }
+  if (ch<>0)
+  { if ((g div r)*r<>g)
+   { "ERROR:   <int> should divide the group order."
+      return();
+    }
+  }
+  if (ch<>0)
+  { if ((g%ch)==0)
+    { if (voice==2)
+      { "WARNING: The characteristic of the coefficient field divides the group";
+        "         order. Proceed without the Molien series!";
+      }
+      else
+      { if (v)
+        { "  The characteristic of the base field divides the group order.";
+          "  We have to continue without Molien series...";
+          "";
+        }
+      }
+    }
+    if (minpoly<>0 && mol_flag==0)
+    { if (voice==2)
+      { "WARNING: It is impossible for this program to calculate the Molien series";
+        "         for finite groups over extension fields of prime characteristic.";
+      }
+      else
+      { if (v)
+        { "  Since it is impossible for this program to calculate the Molien series for";
+          "  invariant rings over extension fields of prime characteristic, we have to";
+          "  continue without it.";
+          "";
+        }
+      }
+      return();
+    }
+  }
+ //----------------------------------------------------------------------------
+  if (not(typeof(#[1])=="matrix"))
+  { "ERROR:   the parameters must be a list of matrices and maybe an <intvec>";
+    return();
+  }
+  int n=nrows(#[1]);
+  if (n<>nvars(br))
+  { "ERROR:   the number of variables of the basering needs to be the same";
+    "         as the dimension of the square matrices";
+    return();
+  }
+  if (v && voice<>2)
+  { "";
+    "  Generating the Molien series...";
+    "";
+  }
+  if (v && voice==2)
+  { "";
+  }
+ //------------- calculating Molien series in characteristic 0 ----------------
+  if (ch==0)                           // when ch==0 we can calculate the Molien
+  { matrix I=diag(1,n);                // series in any case -
+    poly v1=maxideal(1)[1];            // the Molien series will be in terms of
+                                       // the first variable of the current
+                                       // ring -
+    matrix M[1][2];                    // M will contain the Molien series -
+    M[1,1]=0;                          // M[1,1] will be the numerator -
+    M[1,2]=1;                          // M[1,2] will be the denominator -
+    matrix s;                          // will help us canceling in the
+                                       // fraction
+    poly p;                            // will contain the denominator of the
+                                       // new term of the Molien series
+ //------------ computing 1/det(1+xE) for all E in the group ------------------
+    for (int j=1;j<=g;j++)
+    { if (not(typeof(#[j])=="matrix"))
+      { "ERROR:   the parameters must be a list of matrices and maybe an <intvec>";
+        return();
+      }
+      if ((n<>nrows(#[j])) or (n<>ncols(#[j])))
+      { "ERROR:   matrices need to be square and of the same dimensions";
+         return();
+      }
+      p=det(I-v1*#[j]);                // denominator of new term -
+      M[1,1]=M[1,1]*p+M[1,2];          // expanding M[1,1]/M[1,2] + 1/p
+      M[1,2]=M[1,2]*p;
+      if (interval<>0)                 // canceling common terms of denominator
+      { if ((j div interval)*interval==j or j==g) // and enumerator -
+        { s=matrix(syz(ideal(M)));     // once gcd() is faster than syz() these
+          M[1,1]=-s[2,1];              // three lines should be replaced by the
+          M[1,2]=s[1,1];               // following three
+          // p=gcd(M[1,1],M[1,2]);
+          // M[1,1]=M[1,1]/p;
+          // M[1,2]=M[1,2]/p;
+        }
+      }
+      if (v)
+      { "  Term ",j," of the Molien series has been computed.";
+      }
+    }
+    if (interval==0)                   // canceling common terms of denominator
+    {                                  // and enumerator -
+      s=matrix(syz(ideal(M)));         // once gcd() is faster than syz() these
+      M[1,1]=-s[2,1];                  // three lines should be replaced by the
+      M[1,2]=s[1,1];                   // following three
+      // p=gcd(M[1,1],M[1,2]);
+      // M[1,1]=M[1,1]/p;
+      // M[1,2]=M[1,2]/p;
+    }
+    map slead=br,ideal(0);
+    s=slead(M);
+    M[1,1]=1/s[1,1]*M[1,1];           // numerator and denominator have to have
+    M[1,2]=1/s[1,2]*M[1,2];           // a constant term of 1
+    if (v)
+    { "";
+      "  We are done calculating the Molien series.";
+      "";
+    }
+    return(M);
+  }
+ //---- calculating Molien series in prime characteristic with Brauer lift ----
+  if (ch<>0 && mol_flag==0)
+  { if (g<>1)
+    { matrix G(1..g)=#[1..g];
+      if (interval<0)
+      { string Mstring;
+      }
+ //------ preparing everything for Brauer lifts into characteristic 0 ---------
+      ring Q=0,x,dp;                  // we want to extend our ring as well as
+                                      // the ring of rational numbers Q to
+                                      // contain r-th primitive roots of unity
+                                      // in order to factor characteristic
+                                      // polynomials of group elements into
+                                      // linear factors and lift eigenvalues to
+                                      // characteristic 0 -
+      poly minq=cyclotomic(r);        // minq now contains the size-of-group-th
+                                      // cyclotomic polynomial of Q, it is
+                                      // irreducible there
+      ring `newring`=(0,e),x,dp;
+      map f=Q,ideal(e);
+      minpoly=number(f(minq));         // e is now a r-th primitive root of
+                                       // unity -
+      kill Q;                       // no longer needed -
+      poly p=1;                        // used to build the denominator of the
+                                       // new term in the Molien series
+      matrix s[1][2];                  // used for canceling -
+      matrix M[1][2]=0,1;              // will contain Molien series -
+      ring v1br=char(br),x,dp;         // we calculate the r-th cyclotomic
+      poly minp=cyclotomic(r);         // polynomial of the base field and pick
+      minp=factorize(minp)[1][2];      // an irreducible factor of it -
+      if (deg(minp)==1)                // in this case the base field contains
+      { ring bre=char(br),x,dp;        // r-th roots of unity already
+        map f1=v1br,ideal(0);
+        number e=-number((f1(minp)));  // e is a r-th primitive root of unity
+      }
+      else
+      { ring bre=(char(br),e),x,dp;
+        map f1=v1br,ideal(e);
+        minpoly=number(f1(minp));      // e is a r-th primitive root of unity
+      }
+      map f2=br,ideal(0);              // we need f2 to map our group elements
+                                       // to this new extension field bre
+      matrix xI=diag(x,n);
+      poly p;                         // used for the characteristic polynomial
+                                      // to factor -
+      list L;                         // will contain the linear factors of the
+      ideal F;                        // characteristic polynomial of the group
+      intvec C;                       // elements and their powers
+      int i, j, k;
+ // -------------- finding all the terms of the Molien series -----------------
+      for (i=1;i<=g;i++)
+      { setring br;
+        if (not(typeof(#[i])=="matrix"))
+        { "ERROR:   the parameters must be a list of matrices and maybe an <intvec>";
+          return();
+        }
+        if ((n<>nrows(#[i])) or (n<>ncols(#[i])))
+        { "ERROR:   matrices need to be square and of the same dimensions";
+           return();
+        }
+        setring bre;
+        p=det(xI-f2(G(i)));           // characteristic polynomial of G(i)
+        L=factorize(p);
+        F=L[1];
+        C=L[2];
+        for (j=2;j<=ncols(F);j++)
+        { F[j]=-1*(F[j]-x);           // F[j] is now an eigenvalue of G(i),
+                                      // it is a power of a primitive r-th root
+                                      // of unity -
+          k=exponent(number(F[j]),e); // F[j]==e^k
+          setring `newring`;
+          p=p*(1-x*(e^k))^C[j];       // building the denominator of the new
+          setring bre;                // term
+        }
+//         -----------
+//         k=0;
+//         while(k<r)
+//         { map f3=basering,ideal(e^k);
+//           while (f3(p)==0)
+//           { p=p/(x-e^k);
+//             setring `newring`;
+//             p=p*(1-x*(e^k));        // building the denominator of the new
+//             setring bre;
+//           }
+//           kill f3;
+//           if (p==1)
+//           { break;
+//           }
+//           k=k+1;
+//         }
+        setring `newring`;
+        M[1,1]=M[1,1]*p+M[1,2];        // expanding M[1,1]/M[1,2] + 1/p
+        M[1,2]=M[1,2]*p;
+        if (interval<0)
+        { if (i<>g)
+          { Mstring=string(M);
+            for (j=1;j<=size(Mstring);j++)
+            { if (Mstring[j]=="e")
+              { interval=0;
+                break;
+              }
+            }
+          }
+          if (interval<>0)
+          { s=matrix(syz(ideal(M)));   // once gcd() is faster than syz()
+            M[1,1]=-s[2,1];            // these three lines should be
+            M[1,2]=s[1,1];             // replaced by the following three
+            // p=gcd(M[1,1],M[1,2]);
+            // M[1,1]=M[1,1]/p;
+            // M[1,2]=M[1,2]/p;
+          }
+          else
+          { interval=-1;
+          }
+        }
+        else
+        { if (interval<>0)             // canceling common terms of denominator
+          { if ((i div interval)*interval==i or i==g) // and enumerator
+            { s=matrix(syz(ideal(M))); // once gcd() is faster than syz()
+              M[1,1]=-s[2,1];          // these three lines should be
+              M[1,2]=s[1,1];           // replaced by the following three
+              // p=gcd(M[1,1],M[1,2]);
+              // M[1,1]=M[1,1]/p;
+              // M[1,2]=M[1,2]/p;
+            }
+          }
+        }
+        p=1;
+        setring bre;
+        if (v)
+        { "  Term ",i," of the Molien series has been computed.";
+        }
+      }
+      if (v)
+      { "";
+      }
+      setring `newring`;
+      if (interval==0)                 // canceling common terms of denominator
+      {                                // and enumerator -
+        s=matrix(syz(ideal(M)));       // once gcd() is faster than syz() these
+        M[1,1]=-s[2,1];                // three lines should be replaced by the
+        M[1,2]=s[1,1];                 // following three
+        // p=gcd(M[1,1],M[1,2]);
+        // M[1,1]=M[1,1]/p;
+        // M[1,2]=M[1,2]/p;
+      }
+      map slead=`newring`,ideal(0);
+      s=slead(M);                     // forcing the constant term of numerator
+      M[1,1]=1/s[1,1]*M[1,1];         // and denominator to be 1
+      M[1,2]=1/s[1,2]*M[1,2];
+      kill slead;
+      kill s;
+      kill p;
+    }
+    else                              // if the group only contains an identity
+    { ring `newring`=0,x,dp;          // element, it is very easy to calculate
+      matrix M[1][2]=1,(1-x)^n;       // the Molien series
+    }
+    export(`newring`);                // we keep the ring where we computed the
+    export M;                         // Molien series in such that we can
+    setring br;                       // keep it
+    if (v)
+    { "  We are done calculating the Molien series.";
+      "";
+    }
+  }
+  else                                // i.e. char<>0 and mol_flag<>0, the user
+  {                                   // has specified that we are dealing with
+                                      // a ring of large characteristic which
+                                      // can be treated like a ring of
+                                      // characteristic 0; we'll avoid the
+                                      // Brauer lifts
+ //----------------------- simulating characteristic 0 ------------------------
+    string chst=charstr(br);
+    for (int i=1;i<=size(chst);i++)
+    { if (chst[i]==",")
+      { break;
+      }
+    }
+ //----------------- generating ring of characteristic 0 ----------------------
+    if (minpoly==0)
+    { if (i>size(chst))
+      { execute("ring "+newring+"=0,("+varstr(br)+"),("+ordstr(br)+")");
+      }
+      else
+      { chst=chst[i..size(chst)];
+        execute
+        ("ring "+newring+"=(0"+chst+"),("+varstr(br)+"),("+ordstr(br)+")");
+      }
+    }
+    else
+    { string minp=string(minpoly);
+      minp=minp[2..size(minp)-1];
+      chst=chst[i..size(chst)];
+      execute("ring "+newring+"=(0"+chst+"),("+varstr(br)+"),("+ordstr(br)+")");
+      execute("minpoly="+minp);
+    }
+    matrix I=diag(1,n);
+    poly v1=maxideal(1)[1];            // the Molien series will be in terms of
+                                       // the first variable of the current
+                                       // ring -
+    matrix M[1][2];                    // M will contain the Molien series -
+    M[1,1]=0;                          // M[1,1] will be the numerator -
+    M[1,2]=1;                          // M[1,2] will be the denominator -
+    matrix s;                          // will help us canceling in the
+                                       // fraction
+    poly p;                            // will contain the denominator of the
+                                       // new term of the Molien series
+    int j;
+    string links, rechts;
+ //----------------- finding all terms of the Molien series -------------------
+    for (i=1;i<=g;i++)
+    { setring br;
+      if (not(typeof(#[i])=="matrix"))
+      { "ERROR:   the parameters must be a list of matrices and maybe an <intvec>";
+        return();
+      }
+      if ((n<>nrows(#[i])) or (n<>ncols(#[i])))
+      { "ERROR:   matrices need to be square and of the same dimensions";
+         return();
+      }
+      string stM(i)=string(#[i]);
+      for (j=1;j<=size(stM(i));j++)
+      { if (stM(i)[j]=="
+")
+        { links=stM(i)[1..j-1];
+          rechts=stM(i)[j+1..size(stM(i))];
+          stM(i)=links+rechts;
+        }
+      }
+      setring `newring`;
+      execute("matrix G(i)["+string(n)+"]["+string(n)+"]="+stM(i));
+      p=det(I-v1*G(i));                // denominator of new term -
+      M[1,1]=M[1,1]*p+M[1,2];          // expanding M[1,1]/M[1,2] + 1/p
+      M[1,2]=M[1,2]*p;
+      if (interval<>0)                 // canceling common terms of denominator
+      { if ((i div interval)*interval==i or i==g) // and enumerator
+        {
+          s=matrix(syz(ideal(M)));     // once gcd() is faster than syz() these
+          M[1,1]=-s[2,1];              // three lines should be replaced by the
+          M[1,2]=s[1,1];               // following three
+          // p=gcd(M[1,1],M[1,2]);
+          // M[1,1]=M[1,1]/p;
+          // M[1,2]=M[1,2]/p;
+        }
+      }
+      if (v)
+      { "  Term ",i," of the Molien series has been computed.";
+      }
+    }
+    if (interval==0)                   // canceling common terms of denominator
+    {                                  // and enumerator -
+      s=matrix(syz(ideal(M)));         // once gcd() is faster than syz() these
+      M[1,1]=-s[2,1];                  // three lines should be replaced by the
+      M[1,2]=s[1,1];                   // following three
+      // p=gcd(M[1,1],M[1,2]);
+      // M[1,1]=M[1,1]/p;
+      // M[1,2]=M[1,2]/p;
+    }
+    map slead=`newring`,ideal(0);
+    s=slead(M);
+    M[1,1]=1/s[1,1]*M[1,1];           // numerator and denominator have to have
+    M[1,2]=1/s[1,2]*M[1,2];           // a constant term of 1
+    if (v)
+    { "";
+      "  We are done calculating the Molien series.";
+      "";
+    }
+    kill G(1..g), s, slead, p, v1, I;
+    export `newring`;                 // we keep the ring where we computed the
+    export M;                         // the Molien series such that we can
+    setring br;                       // keep it
+  }
+}
+example
+{ "EXAMPLE: Sturmfels: Algorithms in Invariant Theory 2.3.7:";
+  "         note the case of prime characteristic"; echo=2;
+         ring R=0,(x,y,z),dp;
+         matrix A[3][3]=0,1,0,-1,0,0,0,0,-1;
+         list L=group_reynolds(A);
+         matrix M=molien(L[2..size(L)]);
+         print(M);
+         ring S=3,(x,y,z),dp;
+         string newring="alksdfjlaskdjf";
+         matrix A[3][3]=0,1,0,-1,0,0,0,0,-1;
+         list L=group_reynolds(A);
+         molien(L[2..size(L)],newring);
+         setring Finvar::alksdfjlaskdjf;
+         print(M);
+         setring S;
+         kill Finvar::alksdfjlaskdjf;
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc reynolds_molien (list #)
+"USAGE:   reynolds_molien(G1,G2,...[,ringname,flags]);
+         G1,G2,...: nxn <matrices> generating a finite matrix group, ringname:
+         a <string> giving a name for a new ring of characteristic 0 for the
+         Molien series in case of prime characteristic, flags: an optional
+         <intvec> with three components: if the first element is not equal to 0
+         characteristic 0 is simulated, i.e. the Molien series is computed as
+         if the base field were characteristic 0 (the user must choose a field
+         of large prime characteristic, e.g. 32003) the second component should
+         give the size of intervals between canceling common factors in the
+         expansion of the Molien series, 0 (the default) means only once after
+         generating all terms, in prime characteristic also a negative number
+         can be given to indicate that common factors should always be canceled
+         when the expansion is simple (the root of the extension field does not
+         occur among the coefficients)
+ASSUME:  n is the number of variables of the basering, G1,G2... are the group
+         elements generated by group_reynolds(), g is the size of the group
+RETURN:  a gxn <matrix> representing the Reynolds operator is the first return
+         value and in case of characteristic 0 a 1x2 <matrix> giving enumerator
+         and denominator of Molien series is the second one; in case of prime
+         characteristic a ring with the name `ringname` of characteristic 0 is
+         created where the same Molien series (named M) is stored
+DISPLAY: information if the third component of flags does not equal 0
+THEORY:  The entire matrix group is generated by getting all left products of
+         the generators with new elements from the last run through the loop
+         (or the generators themselves during the first run). All the ones that
+         have been generated before are thrown out and the program terminates
+         when are no new elements found in one run. Additionally each time a
+         new group element is found the corresponding ring mapping of which the
+         Reynolds operator is made up is generated. They are stored in the rows
+         of the first return value. In characteristic 0 the terms 1/det(1-xE)
+         is computed whenever a new element E is found. In prime characteristic
+         a Brauer lift is involved and the terms are only computed after the
+         entire matrix group is generated (to avoid the modular case). The
+         returned matrix gives enumerator and denominator of the expanded
+         version where common factors have been canceled.
+EXAMPLE: example reynolds_molien; shows an example
+"
+{ def br=basering;                     // the Molien series depends on the
+  int ch=char(br);                     // characteristic of the coefficient
+                                       // field
+  int gen_num;
+ //------------------- making sure the input is okay --------------------------
+  if (typeof(#[size(#)])=="intvec")
+  { if (size(#[size(#)])==3)
+    { int mol_flag=#[size(#)][1];
+      if (#[size(#)][2]<0 && (ch==0 or (ch<>0 && mol_flag<>0)))
+      { "ERROR:   the second component of the <intvec> should be >=0";
+        return();
+      }
+      int interval=#[size(#)][2];
+      int v=#[size(#)][3];
+    }
+    else
+    { "ERROR:   <intvec> should have three components";
+      return();
+    }
+    if (ch<>0)
+    { if (typeof(#[size(#)-1])<>"string")
+      { "ERROR:   in characteristic p a <string> must be given for the name";
+        "         of a new ring where the Molien series can be stored";
+        return();
+      }
+      else
+      { if (#[size(#)-1]=="")
+        { "ERROR:   <string> may not be empty";
+          return();
+        }
+        string newring=#[size(#)-1];
+        gen_num=size(#)-2;
+      }
+    }
+    else                               // then <string> ist not needed
+    { gen_num=size(#)-1;
+    }
+  }
+  else                                 // last parameter is not <intvec>
+  { int v=0;                           // no information is default
+    int interval;
+    int mol_flag=0;                    // computing of Molien series is default
+    if (ch<>0)
+    { if (typeof(#[size(#)])<>"string")
+      { "ERROR:   in characteristic p a <string> must be given for the name";
+        "         of a new ring where the Molien series can be stored";
+        return();
+      }
+      else
+      { if (#[size(#)]=="")
+        { "ERROR:   <string> may not be empty";
+          return();
+        }
+        string newring=#[size(#)];
+        gen_num=size(#)-1;
+      }
+    }
+    else
+    { gen_num=size(#);
+    }
+  }
+ // ----------------- computing the terms with Brauer lift --------------------
+  if (ch<>0 && mol_flag==0)
+  { list L=group_reynolds(#[1..gen_num],v);
+    if (L[1]==0)
+    { if (voice==2)
+      { "WARNING: The characteristic of the coefficient field divides the group order.";
+        "         Proceed without the Reynolds operator or the Molien series!";
+        return();
+      }
+      if (v)
+      { "  The characteristic of the base field divides the group order.";
+        "  We have to continue without Reynolds operator or the Molien series...";
+        return();
+      }
+    }
+    if (minpoly<>0)
+    { if (voice==2)
+      { "WARNING: It is impossible for this program to calculate the Molien series";
+        "         for finite groups over extension fields of prime characteristic.";
+        return(L[1]);
+      }
+      else
+      { if (v)
+        { "  Since it is impossible for this program to calculate the Molien series for";
+          "  invariant rings over extension fields of prime characteristic, we have to";
+          "  continue without it.";
+          return(L[1]);
+        }
+      }
+    }
+    if (typeof(L[2])=="int")
+    { molien(L[3..size(L)],newring,L[2],intvec(mol_flag,interval,v));
+    }
+    else
+    { molien(L[2..size(L)],newring,intvec(mol_flag,interval,v));
+    }
+    return(L[1]);
+  }
+ //----------- computing Molien series in the straight forward way ------------
+  if (ch==0)
+  { if (typeof(#[1])<>"matrix")
+    { "ERROR:   the parameters must be a list of matrices and maybe an <intvec>";
+      return();
+    }
+    int n=nrows(#[1]);
+    if (n<>nvars(br))
+    { "ERROR:   the number of variables of the basering needs to be the same";
+      "         as the dimension of the matrices";
+      return();
+    }
+    if (n<>ncols(#[1]))
+    { "ERROR:   matrices need to be square and of the same dimensions";
+      return();
+    }
+    matrix vars=matrix(maxideal(1));   // creating an nx1-matrix containing the
+    vars=transpose(vars);              // variables of the ring -
+    matrix A(1)=#[1]*vars;             // calculating the first ring mapping -
+                                       // A(1) will contain the Reynolds
+                                       // operator -
+    poly v1=vars[1,1];                 // the Molien series will be in terms of
+                                       // the first variable of the current
+                                       // ring
+    matrix I=diag(1,n);
+    matrix A(2)[1][2];                 // A(2) will contain the Molien series -
+    A(2)[1,1]=1;                       // A(2)[1,1] will be the numerator
+    matrix G(1)=#[1];                  // G(k) are elements of the group -
+    A(2)[1,2]=det(I-v1*(G(1)));        // A(2)[1,2] will be the denominator -
+    matrix s;                          // will help us canceling in the
+                                       // fraction
+    poly p;                            // will contain the denominator of the
+                                       // new term of the Molien series
+    int i=1;
+    for (int j=2;j<=gen_num;j++)       // this loop adds the parameters to the
+    {                                  // group, leaving out doubles and
+                                       // checking whether the parameters are
+                                       // compatible with the task of the
+                                       // procedure
+      if (not(typeof(#[j])=="matrix"))
+      { "ERROR:   the parameters must be a list of matrices and maybe an <intvec>";
+        return();
+      }
+      if ((n!=nrows(#[j])) or (n!=ncols(#[j])))
+      { "ERROR:   matrices need to be square and of the same dimensions";
+         return();
+      }
+      if (unique(G(1..i),#[j]))
+      { i++;
+        matrix G(i)=#[j];
+        A(1)=concat(A(1),#[j]*vars);   // adding ring homomorphisms to A(1) -
+        p=det(I-v1*#[j]);              // denominator of new term -
+        A(2)[1,1]=A(2)[1,1]*p+A(2)[1,2]; // expanding A(2)[1,1]/A(2)[1,2] +1/p
+        A(2)[1,2]=A(2)[1,2]*p;
+        if (interval<>0)               // canceling common terms of denominator
+        { if ((i div interval)*interval==i) // and enumerator
+          {
+            s=matrix(syz(ideal(A(2)))); // once gcd() is faster than syz() these
+            A(2)[1,1]=-s[2,1];         // three lines should be replaced by the
+            A(2)[1,2]=s[1,1];          // following three
+            // p=gcd(A(2)[1,1],A(2)[1,2]);
+            // A(2)[1,1]=A(2)[1,1]/p;
+            // A(2)[1,2]=A(2)[1,2]/p;
+          }
+        }
+      }
+    }
+    int g=i;                           // G(1)..G(i) are generators without
+                                       // doubles - g generally is the number
+                                       // of elements in the group so far -
+    j=i;                               // j is the number of new elements that
+                                       // we use as factors
+    int k, m, l;
+    if (v)
+    { "";
+      "  Generating the entire matrix group. Whenever a new group element is found,";
+      "  the corresponding ring homomorphism of the Reynolds operator and the";
+      "  corresponding term of the Molien series is generated.";
+      "";
+    }
+ //----------- computing 1/det(I-xE) whenever a new element E is found --------
+    while (1)
+    { l=0;                             // l is the number of products we get in
+                                       // one going
+      for (m=g-j+1;m<=g;m=m+1)
+      { for (k=1;k<=i;k++)
+        { l++;
+          matrix P(l)=G(k)*G(m);       // possible new element
+        }
+      }
+      j=0;
+      for (k=1;k<=l;k++)
+      { if (unique(G(1..g),P(k)))
+        { j++;                         // a new factor for next run
+          g++;
+          matrix G(g)=P(k);            // a new group element -
+          A(1)=concat(A(1),P(k)*vars); // adding new mapping to A(1)
+          p=det(I-v1*P(k));            // denominator of new term
+          A(2)[1,1]=A(2)[1,1]*p+A(2)[1,2];
+          A(2)[1,2]=A(2)[1,2]*p;       // expanding A(2)[1,1]/A(2)[1,2] + 1/p -
+          if (interval<>0)             // canceling common terms of denominator
+          { if ((g div interval)*interval==g) // and enumerator
+            {
+              s=matrix(syz(ideal(A(2)))); // once gcd() is faster than syz()
+              A(2)[1,1]=-s[2,1];       // these three lines should be replaced
+              A(2)[1,2]=s[1,1];        // by the following three
+              // p=gcd(A(2)[1,1],A(2)[1,2]);
+              // A(2)[1,1]=A(2)[1,1]/p;
+              // A(2)[1,2]=A(2)[1,2]/p;
+            }
+          }
+          if (v)
+          { "  Group element ",g," has been found.";
+          }
+        }
+        kill P(k);
+      }
+      if (j==0)                        // when we didn't add any new elements
+      { break;                         // in one run through the while loop
+      }                                // we are done
+    }
+    if (v)
+    { if (g<=i)
+      { "  There are only ",g," group elements.";
+      }
+      "";
+    }
+    A(1)=transpose(A(1));             // when we evaluate the Reynolds operator
+                                      // later on, we actually want 1xn
+                                      // matrices
+    if (interval==0)                  // canceling common terms of denominator
+    {                                 // and enumerator -
+      s=matrix(syz(ideal(A(2))));     // once gcd() is faster than syz()
+      A(2)[1,1]=-s[2,1];              // these three lines should be replaced
+      A(2)[1,2]=s[1,1];               // by the following three
+      // p=gcd(A(2)[1,1],A(2)[1,2]);
+      // A(2)[1,1]=A(2)[1,1]/p;
+      // A(2)[1,2]=A(2)[1,2]/p;
+    }
+    if (interval<>0)                   // canceling common terms of denominator
+    { if ((g div interval)*interval<>g)    // and enumerator
+      {
+        s=matrix(syz(ideal(A(2))));    // once gcd() is faster than syz()
+        A(2)[1,1]=-s[2,1];             // these three lines should be replaced
+        A(2)[1,2]=s[1,1];              // by the following three
+        // p=gcd(A(2)[1,1],A(2)[1,2]);
+        // A(2)[1,1]=A(2)[1,1]/p;
+        // A(2)[1,2]=A(2)[1,2]/p;
+      }
+    }
+    map slead=br,ideal(0);
+    s=slead(A(2));
+    A(2)[1,1]=1/s[1,1]*A(2)[1,1];     // numerator and denominator have to have
+    A(2)[1,2]=1/s[1,2]*A(2)[1,2];     // a constant term of 1
+    if (v)
+    { "  Now we are done calculating Molien series and Reynolds operator.";
+      "";
+    }
+    return(A(1..2));
+  }
+ //------------------------ simulating characteristic 0 -----------------------
+  else                                 // if ch<>0 and mol_flag<>0
+  { if (typeof(#[1])<>"matrix")
+    { "ERROR:   the parameters must be a list of matrices and maybe an <intvec>";
+      return();
+    }
+    int n=nrows(#[1]);
+    if (n<>nvars(br))
+    { "ERROR:   the number of variables of the basering needs to be the same";
+      "         as the dimension of the matrices";
+      return();
+    }
+    if (n<>ncols(#[1]))
+    { "ERROR:   matrices need to be square and of the same dimensions";
+      return();
+    }
+    matrix vars=matrix(maxideal(1));   // creating an nx1-matrix containing the
+    vars=transpose(vars);              // variables of the ring -
+    matrix A(1)=#[1]*vars;             // calculating the first ring mapping -
+                                       // A(1) will contain the Reynolds
+                                       // operator
+    string chst=charstr(br);
+    for (int i=1;i<=size(chst);i++)
+    { if (chst[i]==",")
+      { break;
+      }
+    }
+    if (minpoly==0)
+    { if (i>size(chst))
+      { execute("ring "+newring+"=0,("+varstr(br)+"),("+ordstr(br)+")");
+      }
+      else
+      { chst=chst[i..size(chst)];
+        execute
+        ("ring "+newring+"=(0"+chst+"),("+varstr(br)+"),("+ordstr(br)+")");
+      }
+    }
+    else
+    { string minp=string(minpoly);
+      minp=minp[2..size(minp)-1];
+      chst=chst[i..size(chst)];
+      execute("ring "+newring+"=(0"+chst+"),("+varstr(br)+"),("+ordstr(br)+")");
+      execute("minpoly="+minp);
+    }
+    poly v1=var(1);                    // the Molien series will be in terms of
+                                       // the first variable of the current
+                                       // ring
+    matrix I=diag(1,n);
+    int o;
+    setring br;
+    matrix G(1)=#[1];
+    string links, rechts;
+    string stM(1)=string(#[1]);
+    for (o=1;o<=size(stM(1));o++)
+    { if (stM(1)[o]=="
+")
+      { links=stM(1)[1..o-1];
+        rechts=stM(1)[o+1..size(stM(1))];
+        stM(1)=links+rechts;
+      }
+    }
+    setring `newring`;
+    execute("matrix G(1)["+string(n)+"]["+string(n)+"]="+stM(1));
+    matrix A(2)[1][2];                 // A(2) will contain the Molien series -
+    A(2)[1,1]=1;                       // A(2)[1,1] will be the numerator
+    A(2)[1,2]=det(I-v1*(G(1)));        // A(2)[1,2] will be the denominator -
+    matrix s;                          // will help us canceling in the
+                                       // fraction
+    poly p;                            // will contain the denominator of the
+                                       // new term of the Molien series
+    i=1;
+    for (int j=2;j<=gen_num;j++)       // this loop adds the parameters to the
+    {                                  // group, leaving out doubles and
+                                       // checking whether the parameters are
+                                       // compatible with the task of the
+                                       // procedure
+      setring br;
+      if (not(typeof(#[j])=="matrix"))
+      { "ERROR:   the parameters must be a list of matrices and maybe an <intvec>";
+        return();
+      }
+      if ((n!=nrows(#[j])) or (n!=ncols(#[j])))
+      { "ERROR:   matrices need to be square and of the same dimensions";
+         return();
+      }
+      if (unique(G(1..i),#[j]))
+      { i++;
+        matrix G(i)=#[j];
+        A(1)=concat(A(1),G(i)*vars);   // adding ring homomorphisms to A(1)
+        string stM(i)=string(G(i));
+        for (o=1;o<=size(stM(i));o++)
+        { if (stM(i)[o]=="
+")
+          { links=stM(i)[1..o-1];
+            rechts=stM(i)[o+1..size(stM(i))];
+            stM(i)=links+rechts;
+          }
+        }
+        setring `newring`;
+        execute("matrix G(i)["+string(n)+"]["+string(n)+"]="+stM(i));
+        p=det(I-v1*G(i));              // denominator of new term -
+        A(2)[1,1]=A(2)[1,1]*p+A(2)[1,2]; // expanding A(2)[1,1]/A(2)[1,2] +1/p
+        A(2)[1,2]=A(2)[1,2]*p;
+        if (interval<>0)               // canceling common terms of denominator
+        { if ((i div interval)*interval==i) // and enumerator
+          {
+            s=matrix(syz(ideal(A(2)))); // once gcd() is faster than syz() these
+            A(2)[1,1]=-s[2,1];         // three lines should be replaced by the
+            A(2)[1,2]=s[1,1];          // following three
+            // p=gcd(A(2)[1,1],A(2)[1,2]);
+            // A(2)[1,1]=A(2)[1,1]/p;
+            // A(2)[1,2]=A(2)[1,2]/p;
+          }
+        }
+        setring br;
+      }
+    }
+    int g=i;                           // G(1)..G(i) are generators without
+                                       // doubles - g generally is the number
+                                       // of elements in the group so far -
+    j=i;                               // j is the number of new elements that
+                                       // we use as factors
+    int k, m, l;
+    if (v)
+    { "";
+      "  Generating the entire matrix group. Whenever a new group element is found,";
+      "  the corresponding ring homomorphism of the Reynolds operator and the";
+      "  corresponding term of the Molien series is generated.";
+      "";
+    }
+ // taking all elements in a ring of characteristic 0 and computing the terms
+ // of the Molien series there
+    while (1)
+    { l=0;                             // l is the number of products we get in
+                                       // one going
+      for (m=g-j+1;m<=g;m++)
+      { for (k=1;k<=i;k++)
+        { l++;
+          matrix P(l)=G(k)*G(m);       // possible new element
+        }
+      }
+      j=0;
+      for (k=1;k<=l;k++)
+      { if (unique(G(1..g),P(k)))
+        { j++;                         // a new factor for next run
+          g++;
+          matrix G(g)=P(k);            // a new group element -
+          A(1)=concat(A(1),G(g)*vars); // adding new mapping to A(1)
+          string stM(g)=string(G(g));
+          for (o=1;o<=size(stM(g));o++)
+          { if (stM(g)[o]=="
+")
+            { links=stM(g)[1..o-1];
+              rechts=stM(g)[o+1..size(stM(g))];
+              stM(g)=links+rechts;
+            }
+          }
+          setring `newring`;
+          execute("matrix G(g)["+string(n)+"]["+string(n)+"]="+stM(g));
+          p=det(I-v1*G(g));            // denominator of new term
+          A(2)[1,1]=A(2)[1,1]*p+A(2)[1,2];
+          A(2)[1,2]=A(2)[1,2]*p;       // expanding A(2)[1,1]/A(2)[1,2] + 1/p -
+          if (interval<>0)             // canceling common terms of denominator
+          { if ((g div interval)*interval==g) // and enumerator
+            {
+              s=matrix(syz(ideal(A(2)))); // once gcd() is faster than syz()
+              A(2)[1,1]=-s[2,1];       // these three lines should be replaced
+              A(2)[1,2]=s[1,1];        // by the following three
+              // p=gcd(A(2)[1,1],A(2)[1,2]);
+              // A(2)[1,1]=A(2)[1,1]/p;
+              // A(2)[1,2]=A(2)[1,2]/p;
+            }
+          }
+          if (v)
+          { "  Group element ",g," has been found.";
+          }
+          setring br;
+        }
+        kill P(k);
+      }
+      if (j==0)                        // when we didn't add any new elements
+      { break;                         // in one run through the while loop
+      }                                // we are done
+    }
+    if (v)
+    { if (g<=i)
+      { "  There are only ",g," group elements.";
+      }
+      "";
+    }
+    A(1)=transpose(A(1));              // when we evaluate the Reynolds operator
+                                       // later on, we actually want 1xn
+                                       // matrices
+    setring `newring`;
+    if (interval==0)                   // canceling common terms of denominator
+    {                                  // and enumerator -
+      s=matrix(syz(ideal(A(2))));      // once gcd() is faster than syz()
+      A(2)[1,1]=-s[2,1];               // these three lines should be replaced
+      A(2)[1,2]=s[1,1];                // by the following three
+      // p=gcd(A(2)[1,1],A(2)[1,2]);
+      // A(2)[1,1]=A(2)[1,1]/p;
+      // A(2)[1,2]=A(2)[1,2]/p;
+    }
+    if (interval<>0)                   // canceling common terms of denominator
+    { if ((g div interval)*interval<>g)    // and enumerator
+      {
+        s=matrix(syz(ideal(A(2))));    // once gcd() is faster than syz()
+        A(2)[1,1]=-s[2,1];             // these three lines should be replaced
+        A(2)[1,2]=s[1,1];              // by the following three
+        // p=gcd(A(2)[1,1],A(2)[1,2]);
+        // A(2)[1,1]=A(2)[1,1]/p;
+        // A(2)[1,2]=A(2)[1,2]/p;
+      }
+    }
+    map slead=`newring`,ideal(0);
+    s=slead(A(2));
+    A(2)[1,1]=1/s[1,1]*A(2)[1,1];     // numerator and denominator have to have
+    A(2)[1,2]=1/s[1,2]*A(2)[1,2];     // a constant term of 1
+    if (v)
+    { "  Now we are done calculating Molien series and Reynolds operator.";
+      "";
+    }
+    matrix M=A(2);
+    kill G(1..g), s, slead, p, v1, I, A(2);
+    export `newring`;                 // we keep the ring where we computed the
+    export M;                         // the Molien series such that we can
+    setring br;                       // keep it
+    return(A(1));
+  }
+}
+example
+{ "EXAMPLE: Sturmfels: Algorithms in Invariant Theory 2.3.7:";
+  "         note the case of prime characteristic"; echo=2;
+         ring R=0,(x,y,z),dp;
+         matrix A[3][3]=0,1,0,-1,0,0,0,0,-1;
+         matrix REY,M=reynolds_molien(A);
+         print(REY);
+         print(M);
+         ring S=3,(x,y,z),dp;
+         string newring="Qadjoint";
+         matrix A[3][3]=0,1,0,-1,0,0,0,0,-1;
+         matrix REY=reynolds_molien(A,newring);
+         print(REY);
+         setring Finvar::Qadjoint;
+         print(M);
+         setring S;
+         kill Finvar::Qadjoint;
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc partial_molien (matrix M, int n, list #)
+"USAGE:   partial_molien(M,n[,p]);
+         M: a 1x2 <matrix>, n: an <int> indicating  number of terms in the
+         expansion, p: an optional <poly>
+ASSUME:  M is the return value of molien or the second return value of
+         reynolds_molien, p ought to be the second return value of a previous
+         run of partial_molien and avoids recalculating known terms
+RETURN:  n terms (type <poly>) of the partial expansion of the Molien series
+         (first n if there is no third parameter given, otherwise the next n
+         terms depending on a previous calculation) and an intermediate result
+         (type <poly>) of the calculation to be used as third parameter in a
+         next run of partial_molien
+THEORY:  The following calculation is implemented:
+ at format
+(1+a1x+a2x^2+...+anx^n)/(1+b1x+b2x^2+...+bmx^m)=(1+(a1-b1)x+...
+(1+b1x+b2x^2+...+bmx^m)
+-----------------------
+   (a1-b1)x+(a2-b2)x^2+...
+   (a1-b1)x+b1(a1-b1)x^2+...
+ at end format
+EXAMPLE: example partial_molien; shows an example
+"
+{ poly A(2);                           // A(2) will contain the return value of
+                                       // the intermediate result
+  if (char(basering)<>0)
+  { "ERROR:   you have to change to a basering of characteristic 0, one in";
+    "         which the Molien series is defined";
+  }
+  if (ncols(M)==2 && nrows(M)==1 && n>0 && size(#)<2)
+  { def br=basering;                   // keeping track of the old ring
+    map slead=br,ideal(0);
+    matrix s=slead(M);
+    if (s[1,1]<>1 || s[1,2]<>1)
+    { "ERROR:   the constant terms of enumerator and denominator are not 1";
+      return();
+    }
+
+    if (size(#)==0)
+    { A(2)=M[1,1];                    // if a third parameter is not given, the
+                                      // intermediate result from the last run
+                                      // corresponds to the numerator - we need
+    }                                 // its smallest term
+    else
+    { if (typeof(#[1])=="poly")
+      { A(2)=#[1];                    // if a third term is given we 'start'
+      }                               // with its smallest term
+      else
+      { "ERROR:   <poly> as third parameter expected";
+        return();
+      }
+    }
+    poly A(1)=M[1,2];                 // denominator of Molien series (for now)
+    string mp=string(minpoly);
+    execute("ring R=("+charstr(br)+"),("+varstr(br)+"),ds;");
+    if (mp!="0")
+    {
+      execute("minpoly=number("+mp+");");
+    }
+    poly A(1)=0;                      // A(1) will contain the sum of n terms -
+    poly min;                         // min will be our smallest term -
+    poly A(2)=fetch(br,A(2));         // fetching A(2) and M[1,2] into R
+    poly den=fetch(br,A(1));
+    for (int i=1; i<=n; i++)          // getting n terms and adding them up
+    { min=lead(A(2));
+      A(1)=A(1)+min;
+      A(2)=A(2)-min*den;
+    }
+    setring br;                       // moving A(1) and A(2) back in the
+    A(1)=fetch(R,A(1));               // actual ring for output
+    A(2)=fetch(R,A(2));
+    return(A(1..2));
+  }
+  else
+  { "ERROR:   the first parameter has to be a 1x2-matrix, i.e. the matrix";
+    "         returned by the procedure 'reynolds_molien', the second one";
+    "         should be > 0 and there should be no more than 3 parameters;"
+    return();
+  }
+}
+example
+{ "EXAMPLE: Sturmfels: Algorithms in Invariant Theory 2.3.7:"; echo=2;
+         ring R=0,(x,y,z),dp;
+         matrix A[3][3]=0,1,0,-1,0,0,0,0,-1;
+         matrix REY,M=reynolds_molien(A);
+         poly p(1..2);
+         p(1..2)=partial_molien(M,5);
+         p(1);
+         p(1..2)=partial_molien(M,5,p(2));
+         p(1);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc evaluate_reynolds (matrix REY, ideal I)
+"USAGE:   evaluate_reynolds(REY,I);
+         REY: a <matrix> representing the Reynolds operator, I: an arbitrary
+         <ideal>
+ASSUME:  REY is the first return value of group_reynolds() or reynolds_molien()
+RETURNS: image of the polynomials defining I under the Reynolds operator
+         (type <ideal>)
+NOTE:    the characteristic of the coefficient field of the polynomial ring
+         should not divide the order of the finite matrix group
+THEORY:  REY has been constructed in such a way that each row serves as a ring
+         mapping of which the Reynolds operator is made up.
+EXAMPLE: example evaluate_reynolds; shows an example
+"
+{ def br=basering;
+  int n=nvars(br);
+  if (ncols(REY)==n)
+  { int m=nrows(REY);                  // we need m to 'cut' the ring
+                                       // homomorphisms 'out' of REY and to
+                                       // divide by the group order in the end
+    int num_poly=ncols(I);
+    matrix MI=matrix(I);
+    matrix MiI[1][num_poly];
+    map pREY;
+    matrix rowREY[1][n];
+    for (int i=1;i<=m;i++)
+    { rowREY=REY[i,1..n];
+      pREY=br,ideal(rowREY);           // f is now the i-th ring homomorphism
+      MiI=pREY(MI)+MiI;
+    }
+    MiI=(1/number(m))*MiI;
+    return(ideal(MiI));
+  }
+  else
+  { "ERROR:   the number of columns in the <matrix> should be the same as the";
+    "         number of variables in the basering; in fact it should be first";
+    "         return value of group_reynolds() or reynolds_molien().";
+    return();
+  }
+}
+example
+{ "EXAMPLE: Sturmfels: Algorithms in Invariant Theory 2.3.7:"; echo=2;
+         ring R=0,(x,y,z),dp;
+         matrix A[3][3]=0,1,0,-1,0,0,0,0,-1;
+         list L=group_reynolds(A);
+         ideal I=x2,y2,z2;
+         print(evaluate_reynolds(L[1],I));
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc invariant_basis (int g,list #)
+"USAGE:   invariant_basis(g,G1,G2,...);
+         g: an <int> indicating of which degree (>0) the homogeneous basis
+         shoud be, G1,G2,...: <matrices> generating a finite matrix group
+RETURNS: the basis (type <ideal>) of the space of invariants of degree g
+THEORY:  A general polynomial of degree g is generated and the generators of
+         the matrix group applied. The difference ought to be 0 and this way a
+         system of linear equations is created. It is solved by computing
+         syzygies.
+EXAMPLE: example invariant_basis; shows an example
+"
+{ if (g<=0)
+  { "ERROR:   the first parameter should be > 0";
+    return();
+  }
+  def br=basering;
+  ideal vars = maxideal(1);
+  ideal mon=sort(maxideal(g))[1];      // needed for constructing a general
+  int m=ncols(mon);                    // homogeneous polynomial of degree g
+  mon=sort(mon,intvec(m..1))[1];
+  int a=size(#);
+  int i;
+  int n=nvars(br);
+  int DGB = degBound;
+ //---------------------- checking that the input is ok -----------------------
+  for (i=1;i<=a;i++)
+  { if (typeof(#[i])=="matrix")
+    { if (nrows(#[i])==n && ncols(#[i])==n)
+      { matrix G(i)=#[i];
+      }
+      else
+      { "ERROR:   the number of variables of the base ring needs to be the same";
+        "         as the dimension of the square matrices";
+        return();
+      }
+    }
+    else
+    { "ERROR:   the last parameters should be a list of matrices";
+      return();
+    }
+  }
+ //----------------------------------------------------------------------------
+  ring tmpR = char(br),(p(1..m)),dp;
+  def T = br+tmpR;
+  setring T;
+  // execute("ring T=("+charstr(br)+"),("+varstr(br)+",p(1..m)),lp;");
+  // p(1..m) are the general coefficients of the general polynomial of degree g
+  ideal vars = fetch(br,vars);
+  map f;
+  ideal mon=imap(br,mon);
+  poly P=0;
+  for (i=m;i>=1;i--)
+  { P=P+p(i)*mon[i];                   // P is the general polynomial
+  }
+  ideal I;                             // will help substituting variables in P
+                                       // by linear combinations of variables -
+  poly Pnew,temp;                      // Pnew is P with substitutions -
+  matrix S[m*a][m];                    // will contain system of linear
+                                       // equations
+  int j,k;
+ //------------------- building the system of linear equations ----------------
+  for (i=1;i<=a;i++)
+  { I=ideal(matrix(vars)*transpose(imap(br,G(i))));
+    I=I,p(1..m);
+    f=T,I;
+    Pnew=f(P);
+    for (j=1;j<=m;j++)
+    { temp=P/mon[j]-Pnew/mon[j];
+      for (k=1;k<=m;k++)
+      { S[m*(i-1)+j,k]=temp/p(k);
+      }
+    }
+  }
+ //----------------------------------------------------------------------------
+  setring br;
+  map f=T,ideal(0);
+  matrix S=f(S);
+  degBound=1;
+  matrix s=matrix(syz(S));             // s contains a basis of the space of
+                                       // solutions -
+  ideal I=ideal(matrix(mon)*s);        // I contains a basis of homogeneous
+  if (I[1]<>0)                         // invariants of degree d
+  { for (i=1;i<=ncols(I);i++)
+    { I[i]=I[i]/leadcoef(I[i]);        // setting leading coefficients to 1
+    }
+  }
+  degBound=DGB;
+  return(I);
+}
+example
+{ "EXAMPLE: Sturmfels: Algorithms in Invariant Theory 2.3.7:"; echo=2;
+           ring R=0,(x,y,z),dp;
+           matrix A[3][3]=0,1,0,-1,0,0,0,0,-1;
+           print(invariant_basis(2,A));
+}
+///////////////////////////////////////////////////////////////////////////////
+
+
+proc invariant_basis_reynolds (matrix REY,int d,list #)
+"USAGE:   invariant_basis_reynolds(REY,d[,flags]);
+         REY: a <matrix> representing the Reynolds operator, d: an <int>
+         indicating of which degree (>0) the homogeneous basis shoud be, flags:
+         an optional <intvec> with two entries: its first component gives the
+         dimension of the space (default <0 meaning unknown) and its second
+         component is used as the number of polynomials that should be mapped
+         to invariants during one call of evaluate_reynolds if the dimension of
+         the space is unknown or the number such that number x dimension
+         polynomials are mapped to invariants during one call of
+         evaluate_reynolds
+ASSUME:  REY is the first return value of group_reynolds() or reynolds_molien()
+         and flags[1] given by partial_molien
+RETURN:  the basis (type <ideal>) of the space of invariants of degree d
+THEORY:  Monomials of degree d are mapped to invariants with the Reynolds
+         operator. A linearly independent set is generated with the help of
+         minbase.
+EXAMPLE: example invariant_basis_reynolds; shows an example
+"
+{
+ //---------------------- checking that the input is ok -----------------------
+  if (d<=0)
+  { "  ERROR:   the second parameter should be > 0";
+     return();
+  }
+  if (size(#)>1)
+  { "  ERROR:   there should be at most three parameters";
+    return();
+  }
+  if (size(#)==1)
+  { if (typeof(#[1])<>"intvec")
+    { "  ERROR: the third parameter should be of type <intvec>";
+      return();
+    }
+    if (size(#[1])<>2)
+    { "  ERROR: there should be two components in <intvec>";
+      return();
+    }
+    else
+    { int cd=#[1][1];
+      int step_fac=#[1][2];
+    }
+    if (step_fac<=0)
+    { "  ERROR: the second component of <intvec> should be > 0";
+      return();
+    }
+    if (cd==0)
+    { return(ideal(0));
+    }
+  }
+  else
+  { int step_fac=1;
+    int cd=-1;
+  }
+  if (ncols(REY)<>nvars(basering))
+  { "ERROR:   the number of columns in the <matrix> should be the same as the";
+    "         number of variables in the basering; in fact it should be first";
+    "         return value of group_reynolds() or reynolds_molien().";
+    return();
+  }
+ //----------------------------------------------------------------------------
+  ideal mon=sort(maxideal(d))[1];
+  int DEGB = degBound;
+  degBound=d;
+  int j=ncols(mon);
+  mon=sort(mon,intvec(j..1))[1];
+  ideal B;                             // will contain the basis
+  if (cd<0)
+  { if (step_fac>j)                    // all of mon will be mapped to
+    { B=evaluate_reynolds(REY,mon);    // invariants at once
+      B=minbase(B);
+      degBound=DEGB;
+      return(B);
+    }
+  }
+  else
+  { if (step_fac*cd>j)                 // all of mon will be mapped to
+    { B=evaluate_reynolds(REY,mon);    // invariants at once
+      B=minbase(B);
+      degBound=DEGB;
+      return(B);
+    }
+  }
+  int i,k;
+  int upper_bound=0;
+  int lower_bound=0;
+  ideal part_mon;                      // a part of mon of size step_fac*cd
+  while (1)
+  { lower_bound=upper_bound+1;
+    if (cd<0)
+    { upper_bound=upper_bound+step_fac;
+    }
+    else
+    { upper_bound=upper_bound+step_fac*cd;
+    }
+    if (upper_bound>j)
+    { upper_bound=j;
+    }
+    part_mon=mon[lower_bound..upper_bound];
+    B=minbase(B+evaluate_reynolds(REY,part_mon));
+    if ((ncols(B)==cd and B[1]<>0) or upper_bound==j)
+    { degBound=DEGB;
+      return(B);
+    }
+  }
+}
+example
+{ "EXAMPLE: Sturmfels: Algorithms in Invariant Theory 2.3.7:"; echo=2;
+           ring R=0,(x,y,z),dp;
+           matrix A[3][3]=0,1,0,-1,0,0,0,0,-1;
+           intvec flags=0,1,0;
+           matrix REY,M=reynolds_molien(A,flags);
+           flags=8,6;
+           print(invariant_basis_reynolds(REY,6,flags));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// This procedure generates linearly independent invariant polynomials of
+// degree d that do not reduce to 0 modulo the primary invariants. It does this
+// by applying the Reynolds operator to the monomials returned by kbase(sP,d).
+// The result is used when computing secondary invariants.
+///////////////////////////////////////////////////////////////////////////////
+proc sort_of_invariant_basis (ideal sP,matrix REY,int d,int step_fac)
+{ ideal mon=kbase(sP,d);
+  int DEGB=degBound;
+  degBound=d;
+  int j=ncols(mon);
+  int i;
+  mon=sort(mon,intvec(j..1))[1];
+  ideal B;                             // will contain the "sort of basis"
+  if (step_fac>j)
+  { B=compress(evaluate_reynolds(REY,mon));
+    for (i=1;i<=ncols(B);i++)          // those are taken our that are o mod sP
+    { if (reduce(B[i],sP)==0)
+      { B[i]=0;
+      }
+    }
+    B=minbase(B);                     // here are the linearly independent ones
+    degBound=DEGB;
+    return(B);
+  }
+  int upper_bound=0;
+  int lower_bound=0;
+  ideal part_mon;                      // parts of mon
+  while (1)
+  { lower_bound=upper_bound+1;
+    upper_bound=upper_bound+step_fac;
+    if (upper_bound>j)
+    { upper_bound=j;
+    }
+    part_mon=mon[lower_bound..upper_bound];
+    part_mon=compress(evaluate_reynolds(REY,part_mon));
+    for (i=1;i<=ncols(part_mon);i++)
+    { if (reduce(part_mon[i],sP)==0)
+      { part_mon[i]=0;
+      }
+    }
+    B=minbase(B+part_mon);            // here are the linearly independent ones
+    if (upper_bound==j)
+    { degBound=DEGB;
+      return(B);
+    }
+  }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Procedure returning the succeeding vector after vec. It is used to list
+// all the vectors of Z^n with first nonzero entry 1. They are listed by
+// increasing sum of the absolute value of their entries.
+///////////////////////////////////////////////////////////////////////////////
+proc next_vector(intmat vec)
+{ int n=ncols(vec);                    // p: >0, n: <0, p0: >=0, n0: <=0
+  for (int i=1;i<=n;i++)               // finding out which is the first
+  { if (vec[1,i]<>0)                   // component <>0
+    { break;
+    }
+  }
+  intmat new[1][n];
+  if (i>n)                             // 0,...,0 --> 1,0....,0
+  { new[1,1]=1;
+    return(new);
+  }
+  if (i==n)                            // 0,...,1 --> 1,1,0,...,0
+  { new[1,1..2]=1,1;
+    return(new);
+  }
+  if (i==n-1)
+  { if (vec[1,n]==0)                   // 0,...,0,1,0 --> 0,...,0,1
+    { new[1,n]=1;
+      return(new);
+    }
+    if (vec[1,n]>0)                    // 0,..,0,1,p --> 0,...,0,1,-p
+    { new[1,1..n]=vec[1,1..n-1],-vec[1,n];
+      return(new);
+    }
+    new[1,1..2]=1,1-vec[1,n];          // 0,..,0,1,n --> 1,1-n,0,..,0
+    return(new);
+  }
+  if (i>1)
+  { intmat temp[1][n-i+1]=vec[1,i..n]; // 0,...,0,1,*,...,* --> 1,*,...,*
+    temp=next_vector(temp);
+    new[1,i..n]=temp[1,1..n-i+1];
+    return(new);
+  }                                    // case left: 1,*,...,*
+  for (i=2;i<=n;i++)
+  { if (vec[1,i]>0)                    // make first positive negative and
+    { vec[1,i]=-vec[1,i];              // return
+      return(vec);
+    }
+    else
+    { vec[1,i]=-vec[1,i];             // make all negatives before positives
+    }                                 // positive
+  }
+  for (i=2;i<=n-1;i++)                // case: 1,p,...,p after 1,n,...,n
+  { if (vec[1,i]>0)
+    { vec[1,2]=vec[1,i]-1;            // shuffleing things around...
+      if (i>2)                        // same sum of absolute values of entries
+      { vec[1,i]=0;
+      }
+      vec[1,i+1]=vec[1,i+1]+1;
+      return(vec);
+    }
+  }                                    // case left: 1,0,...,0 --> 1,1,0,...,0
+  new[1,2..3]=1,vec[1,n];              // and: 1,0,...,0,1 --> 0,1,1,0,...,0
+  return(new);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Maps integers to elements of the base field. It is only called if the base
+// field is of prime characteristic. If the base field has q elements
+// (depending on minpoly) 1..q is mapped to those q elements.
+///////////////////////////////////////////////////////////////////////////////
+proc int_number_map (int i)
+{ int p=char(basering);
+  if (minpoly==0)                      // if no minpoly is given, we have p
+  { i=i%p;                             // elements in the field
+    return(number(i));
+  }
+  int d=pardeg(minpoly);
+  if (i<0)
+  { int bool=1;
+    i=(-1)*i;
+  }
+  i=i%p^d;                            // base field has p^d elements -
+  number a=par(1);                    // a is the root of the minpoly - we have
+  number out=0;                       // to construct a linear combination of
+  int j=1;                            // a^k
+  int k;
+  while (1)
+  { if (i<p^j)                         // finding an upper bound on i
+    { for (k=0;k<j-1;k++)
+      { out=out+((i/p^k)%p)*a^k;       // finding how often p^k is contained in
+      }                                // i
+      out=out+(i/p^(j-1))*a^(j-1);
+      if (defined(bool)==voice)
+      { return((-1)*out);
+      }
+      return(out);
+    }
+    j++;
+  }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// This procedure finds dif primary invariants in degree d. It returns all
+// primary invariants found so far. The coefficients lie in a field of
+// characteristic 0.
+///////////////////////////////////////////////////////////////////////////////
+proc search (int n,int d,ideal B,int cd,ideal P,ideal sP,int i,int dif,int dB,ideal CI)
+{ intmat vec[1][cd];                   // the coefficients for the next
+                                       // combination -
+  degBound=0;
+  poly test_poly;                      // the linear combination to test
+  int test_dim;
+  intvec h;                            // Hilbert series
+  int j=i+1;
+  matrix tB=transpose(B);
+  ideal TEST;
+  while(j<=i+dif)
+  { CI=CI+ideal(var(j)^d);             // homogeneous polynomial of the same
+                                       // degree as the one we're looking for is
+                                       // added
+    // h=hilb(std(CI),1);
+    dB=dB+d-1;                         // used as degBound
+    while(1)
+    { vec=next_vector(vec);            // next vector
+      test_poly=(vec*tB)[1,1];
+      // degBound=dB;
+      TEST=sP+ideal(test_poly);
+      attrib(TEST,"isSB",1);
+      test_dim=dim(TEST);
+      // degBound=0;
+      if (n-test_dim==j)               // the dimension has been lowered by one
+      { sP=TEST;
+        break;
+      }
+      // degBound=dB;
+      //TEST=std(sP+ideal(test_poly));   // should soon be replaced by next line
+      TEST=std(sP,test_poly);            // or, better:
+      //TEST=std(sP,test_poly,h);        // Hilbert driven std-calculation
+      test_dim=dim(TEST);
+      // degBound=0;
+      if (n-test_dim==j)               // the dimension has been lowered by one
+      { sP=TEST;
+        break;
+      }
+    }
+    P[j]=test_poly;                    // test_poly ist added to primary
+    j++;                               // invariants
+  }
+  return(P,sP,CI,dB);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// This procedure finds at most dif primary invariants in degree d. It returns
+// all primary invariants found so far. The coefficients lie in the field of
+// characteristic p>0.
+///////////////////////////////////////////////////////////////////////////////
+proc p_search (int n,int d,ideal B,int cd,ideal P,ideal sP,int i,int dif,int dB,ideal CI)
+{ def br=basering;
+  degBound=0;
+  matrix vec(1)[1][cd];                // starting with 0-vector -
+  intmat new[1][cd];                   // the coefficients for the next
+                                       // combination -
+  matrix pnew[1][cd];                  // new needs to be mapped into br -
+  int counter=1;                       // counts the vectors
+  int j;
+  int p=char(br);
+  if (minpoly<>0)
+  { int ext_deg=pardeg(minpoly);       // field has p^d elements
+  }
+  else
+  { int ext_deg=1;                     // field has p^d elements
+  }
+  poly test_poly;                      // the linear combination to test
+  int test_dim;
+  ring R=0,x,dp;                       // just to calculate next variable
+                                       // bound -
+  number bound=(number(p)^(ext_deg*cd)-1)/(number(p)^ext_deg-1)+1;
+                                       // this is how many linearly independent
+                                       // vectors of size cd exist having
+                                       // entries in the base field of br
+  setring br;
+  intvec h;                            // Hilbert series
+  int k=i+1;
+  if (ncols(B)<cd) { B[cd]=0; }
+  matrix tB=transpose(B);
+  ideal TEST;
+  while (k<=i+dif)
+  { CI=CI+ideal(var(k)^d);             // homogeneous polynomial of the same
+                                       //degree as the one we're looking for is
+                                       // added
+    // h=hilb(std(CI),1);
+    dB=dB+d-1;                         // used as degBound
+    setring R;
+    while (number(counter)<>bound)     // otherwise, we are done
+    { setring br;
+      new=next_vector(new);
+      for (j=1;j<=cd;j++)
+      { pnew[1,j]=int_number_map(new[1,j]); // mapping an integer into br
+      }
+      if (unique(vec(1..counter),pnew)) //checking whether we tried pnew before
+      { counter++;
+        matrix vec(counter)=pnew;      // keeping track of the ones we tried -
+        test_poly=(vec(counter)*tB)[1,1]; // linear combination -
+        // degBound=dB;
+        TEST=sP+ideal(test_poly);
+        attrib(TEST,"isSB",1);
+        test_dim=dim(TEST);
+        // degBound=0;
+        if (n-test_dim==k)             // the dimension has been lowered by one
+        { sP=TEST;
+          setring R;
+          break;
+        }
+        // degBound=dB;
+        //TEST=std(sP+ideal(test_poly)); // should soon to be replaced by next
+                                       // line
+        TEST=std(sP,test_poly);        // or, better:
+        // TEST=std(sP,test_poly,h);      // Hilbert driven std-calculation
+        test_dim=dim(TEST);
+        // degBound=0;
+        if (n-test_dim==k)             // the dimension has been lowered by one
+        { sP=TEST;
+          setring R;
+          break;
+        }
+      }
+      setring R;
+    }
+    if (number(counter)<=bound)
+    { setring br;
+      P[k]=test_poly;                  // test_poly ist added to primary
+    }                                  // invariants
+    else
+    { setring br;
+      CI=CI[1..size(CI)-1];
+      return(P,sP,CI,dB-d+1);
+    }
+    k++;
+  }
+  return(P,sP,CI,dB);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc primary_char0 (matrix REY,matrix M,list #)
+"USAGE:   primary_char0(REY,M[,v]);
+         REY: a <matrix> representing the Reynolds operator, M: a 1x2 <matrix>
+         representing the Molien series, v: an optional <int>
+ASSUME:  REY is the first return value of group_reynolds or reynolds_molien and
+         M the one of molien or the second one of reynolds_molien
+DISPLAY: information about the various stages of the programme if v does not
+         equal 0
+RETURN:  primary invariants (type <matrix>) of the invariant ring
+THEORY:  Bases of homogeneous invariants are generated successively and those
+         are chosen as primary invariants that lower the dimension of the ideal
+         generated by the previously found invariants (see paper \"Generating a
+         Noetherian Normalization of the Invariant Ring of a Finite Group\" by
+         Decker, Heydtmann, Schreyer (1998)).
+EXAMPLE: example primary_char0; shows an example
+"
+{ degBound=0;
+  if (char(basering)<>0)
+  { "ERROR:   primary_char0 should only be used with rings of characteristic 0.";
+    return();
+  }
+ //----------------- checking input and setting verbose mode ------------------
+  if (size(#)>1)
+  { "ERROR:   primary_char0 can only have three parameters.";
+    return();
+  }
+  if (size(#)==1)
+  { if (typeof(#[1])<>"int")
+    { "ERROR:   The third parameter should be of type <int>.";
+      return();
+    }
+    else
+    { int v=#[1];
+    }
+  }
+  else
+  { int v=0;
+  }
+  int n=nvars(basering);               // n is the number of variables, as well
+                                       // as the size of the matrices, as well
+                                       // as the number of primary invariants,
+                                       // we should get
+  if (ncols(REY)<>n)
+  { "ERROR:   First parameter ought to be the Reynolds operator."
+    return();
+  }
+  if (ncols(M)<>2 or nrows(M)<>1)
+  { "ERROR:   Second parameter ought to be the Molien series."
+    return();
+  }
+ //----------------------------------------------------------------------------
+  if (v && voice<>2)
+  { "  We can start looking for primary invariants...";
+    "";
+  }
+  if (v && voice==2)
+  { "";
+  }
+ //------------------------- initializing variables ---------------------------
+  int dB;
+  poly p(1..2);                        // p(1) will be used for single terms of
+                                       // the partial expansion, p(2) to store
+  p(1..2)=partial_molien(M,1);         // the intermediate result -
+  poly v1=var(1);                      // we need v1 to split off coefficients
+                                       // in the partial expansion of M (which
+                                       // is in terms of the first variable) -
+  int j,d,cd,newdim,dif;               // d: current degree, cd: dimension of
+                                       // space of invariants of degree d,
+                                       // newdim: dimension the ideal generated
+                                       // the primary invariants plus basis
+                                       // elements, dif=n-i-newdim, i.e. the
+                                       // number of new primary invairants that
+                                       // should be added in this degree -
+  ideal P,Pplus,sPplus,CI,B;           // P: will contain primary invariants,
+                                       // Pplus: P+B, CI: a complete
+                                       // intersection with the same Hilbert
+                                       // function as P
+  ideal sP=groebner(P);
+  dB=1;                                // used as degree bound
+  int i=0;
+ //-------------- loop that searches for primary invariants  ------------------
+  while(1)                             // repeat until n primary invariants are
+  {                                    // found -
+    p(1..2)=partial_molien(M,1,p(2));  // next term of the partial expansion -
+    d=deg(p(1));                       // degree where we'll search -
+    cd=int(coef(p(1),v1)[2,1]);        // dimension of the homogeneous space of
+                                       // inviarants of degree d
+    if (v)
+    { "  Computing primary invariants in degree ",d,":";
+    }
+    B=invariant_basis_reynolds(REY,d,intvec(cd,6)); // basis of invariants of
+                                       // degree d
+    if (B[1]<>0)
+    { Pplus=P+B;
+      sPplus=groebner(Pplus);
+      newdim=dim(sPplus);
+      dif=n-i-newdim;
+    }
+    else
+    { dif=0;
+    }
+    if (dif<>0)                        // we have to find dif new primary
+    {                                  // invariants
+      if (cd<>dif)
+      { P,sP,CI,dB=search(n,d,B,cd,P,sP,i,dif,dB,CI); // searching for dif invariants
+      }
+      else                             // i.e. we can take all of B
+      { for(j=i+1;j<=i+dif;j++)
+        { CI=CI+ideal(var(j)^d);
+        }
+        dB=dB+dif*(d-1);
+        P=Pplus;
+        sP=sPplus;
+      }
+      if (v)
+      { for (j=1;j<=dif;j++)
+        { "  We find: "+string(P[i+j]);
+        }
+      }
+      i=i+dif;
+      if (i==n)                        // found all primary invariants
+      { if (v)
+        { "";
+          "  We found all primary invariants.";
+          "";
+        }
+        return(matrix(P));
+      }
+    }                                  // done with degree d
+  }
+}
+example
+{ "EXAMPLE: Sturmfels: Algorithms in Invariant Theory 2.3.7:"; echo=2;
+         ring R=0,(x,y,z),dp;
+         matrix A[3][3]=0,1,0,-1,0,0,0,0,-1;
+         matrix REY,M=reynolds_molien(A);
+         matrix P=primary_char0(REY,M);
+         print(P);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc primary_charp (matrix REY,string ring_name,list #)
+"USAGE:   primary_charp(REY,ringname[,v]);
+         REY: a <matrix> representing the Reynolds operator, ringname: a
+         <string> giving the name of a ring where the Molien series is stored,
+         v: an optional <int>
+ASSUME:  REY is the first return value of group_reynolds or reynolds_molien and
+         ringname gives the name of a ring of characteristic 0 that has been
+         created by molien or reynolds_molien
+DISPLAY: information about the various stages of the programme if v does not
+         equal 0
+RETURN:  primary invariants (type <matrix>) of the invariant ring
+THEORY:  Bases of homogeneous invariants are generated successively and those
+         are chosen as primary invariants that lower the dimension of the ideal
+         generated by the previously found invariants (see paper \"Generating a
+         Noetherian Normalization of the Invariant Ring of a Finite Group\" by
+         Decker, Heydtmann, Schreyer (1998)).
+EXAMPLE: example primary_charp; shows an example
+"
+{ degBound=0;
+// ---------------- checking input and setting verbose mode -------------------
+  if (char(basering)==0)
+  { "ERROR:   primary_charp should only be used with rings of characteristic p>0.";
+    return();
+  }
+  if (size(#)>1)
+  { "ERROR:   primary_charp can only have three parameters.";
+    return();
+  }
+  if (size(#)==1)
+  { if (typeof(#[1])<>"int")
+    { "ERROR:   The third parameter should be of type <int>.";
+      return();
+    }
+    else
+    { int v=#[1];
+    }
+  }
+  else
+  { int v=0;
+  }
+  def br=basering;
+  int n=nvars(br);                     // n is the number of variables, as well
+                                       // as the size of the matrices, as well
+                                       // as the number of primary invariants,
+                                       // we should get
+  if (ncols(REY)<>n)
+  { "ERROR:   First parameter ought to be the Reynolds operator."
+    return();
+  }
+  if (typeof(`ring_name`)<>"ring")
+  { "ERROR:   Second parameter ought to be ring where ";
+    "         the Molien series is stored.";
+    return();
+  }
+ //----------------------------------------------------------------------------
+  if (v && voice<>2)
+  { "  We can start looking for primary invariants...";
+    "";
+  }
+  if (v && voice==2)
+  { "";
+  }
+ //----------------------- initializing variables -----------------------------
+  int dB;
+  setring `ring_name`;                 // the Molien series is stores here -
+  poly p(1..2);                        // p(1) will be used for single terms of
+                                       // the partial expansion, p(2) to store
+  p(1..2)=partial_molien(M,1);         // the intermediate result -
+  poly v1=var(1);                      // we need v1 to split off coefficients
+                                       // in the partial expansion of M (which
+                                       // is in terms of the first variable)
+  setring br;
+  int j,d,cd,newdim,dif;               // d: current degree, cd: dimension of
+                                       // space of invariants of degree d,
+                                       // newdim: dimension the ideal generated
+                                       // the primary invariants plus basis
+                                       // elements, dif=n-i-newdim, i.e. the
+                                       // number of new primary invairants that
+                                       // should be added in this degree -
+  ideal P,Pplus,sPplus,CI,B;           // P: will contain primary invariants,
+                                       // Pplus: P+B, CI: a complete
+                                       // intersection with the same Hilbert
+                                       // function as P
+  ideal sP=groebner(P);
+  dB=1;                                // used as degree bound
+  int i=0;
+ //---------------- loop that searches for primary invariants -----------------
+  while(1)                             // repeat until n primary invariants are
+  {                                    // found
+    setring `ring_name`;
+    p(1..2)=partial_molien(M,1,p(2));  // next term of the partial expansion -
+    d=deg(p(1));                       // degree where we'll search -
+    cd=int(coef(p(1),v1)[2,1]);        // dimension of the homogeneous space of
+                                       // inviarants of degree d
+    setring br;
+    if (v)
+    { "  Computing primary invariants in degree ",d,":";
+    }
+    B=invariant_basis_reynolds(REY,d,intvec(cd,6)); // basis of invariants of
+                                       // degree d
+    if (ncols(B)<cd)
+    {
+      " warning: expected ",cd," invars, found ",ncols(B);
+    }
+    if (B[1]<>0)
+    { Pplus=P+B;
+      sPplus=groebner(Pplus);
+      newdim=dim(sPplus);
+      dif=n-i-newdim;
+    }
+    else
+    { dif=0;
+    }
+    if (dif<>0)                        // we have to find dif new primary
+    {                                  // invariants
+      if (cd<>dif)
+      { P,sP,CI,dB=p_search(n,d,B,cd,P,sP,i,dif,dB,CI);
+      }
+      else                             // i.e. we can take all of B
+      { for(j=i+1;j>i+dif;j++)
+        { CI=CI+ideal(var(j)^d);
+        }
+        dB=dB+dif*(d-1);
+        P=Pplus;
+        sP=sPplus;
+      }
+      if (v)
+      { for (j=1;j<=size(P)-i;j++)
+        { "  We find: "+string(P[i+j]);
+        }
+      }
+      i=size(P);
+      if (i==n)                        // found all primary invariants
+      { if (v)
+        { "";
+          "  We found all primary invariants.";
+          "";
+        }
+        return(matrix(P));
+      }
+    }                                  // done with degree d
+  }
+}
+example
+{ "EXAMPLE: Sturmfels: Algorithms in Invariant Theory 2.3.7 (changed into char 3)"; echo=2;
+         ring R=3,(x,y,z),dp;
+         matrix A[3][3]=0,1,0,-1,0,0,0,0,-1;
+         list L=group_reynolds(A);
+         string newring="alskdfj";
+         molien(L[2..size(L)],newring);
+         matrix P=primary_charp(L[1],newring);
+         kill Finvar::`newring`;
+         print(P);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc primary_char0_no_molien (matrix REY, list #)
+"USAGE:   primary_char0_no_molien(REY[,v]);
+         REY: a <matrix> representing the Reynolds operator, v: an optional
+         <int>
+ASSUME:  REY is the first return value of group_reynolds or reynolds_molien
+DISPLAY: information about the various stages of the programme if v does not
+         equal 0
+RETURN:  primary invariants (type <matrix>) of the invariant ring and an
+         <intvec> listing some of the degrees where no non-trivial homogeneous
+         invariants are to be found
+THEORY:  Bases of homogeneous invariants are generated successively and those
+         are chosen as primary invariants that lower the dimension of the ideal
+         generated by the previously found invariants (see paper \"Generating a
+         Noetherian Normalization of the Invariant Ring of a Finite Group\" by
+         Decker, Heydtmann, Schreyer (1998)).
+EXAMPLE: example primary_char0_no_molien; shows an example
+"
+{ degBound=0;
+ //-------------- checking input and setting verbose mode ---------------------
+  if (char(basering)<>0)
+  { "ERROR:   primary_char0_no_molien should only be used with rings of";
+    "         characteristic 0.";
+    return();
+  }
+  if (size(#)>1)
+  { "ERROR:   primary_char0_no_molien can only have two parameters.";
+    return();
+  }
+  if (size(#)==1)
+  { if (typeof(#[1])<>"int")
+    { "ERROR:   The second parameter should be of type <int>.";
+      return();
+    }
+    else
+    { int v=#[1];
+    }
+  }
+  else
+  { int v=0;
+  }
+  int n=nvars(basering);               // n is the number of variables, as well
+                                       // as the size of the matrices, as well
+                                       // as the number of primary invariants,
+                                       // we should get
+  if (ncols(REY)<>n)
+  { "ERROR:   First parameter ought to be the Reynolds operator."
+    return();
+  }
+ //----------------------------------------------------------------------------
+  if (v && voice<>2)
+  { "  We can start looking for primary invariants...";
+    "";
+  }
+  if (v && voice==2)
+  { "";
+  }
+ //----------------------- initializing variables -----------------------------
+  int dB;
+  int j,d,cd,newdim,dif;               // d: current degree, cd: dimension of
+                                       // space of invariants of degree d,
+                                       // newdim: dimension the ideal generated
+                                       // the primary invariants plus basis
+                                       // elements, dif=n-i-newdim, i.e. the
+                                       // number of new primary invairants that
+                                       // should be added in this degree -
+  ideal P,Pplus,CI,B;                  // P: will contain primary invariants,
+                                       // Pplus: P+B, CI: a complete
+                                       // intersection with the same Hilbert
+                                       // function as P
+  ideal sP=groebner(P);
+  dB=1;                                // used as degree bound -
+  d=0;                                 // initializing
+  int i=0;
+  intvec deg_vector;
+ //------------------ loop that searches for primary invariants ---------------
+  while(1)                             // repeat until n primary invariants are
+  {                                    // found -
+    d++;                               // degree where we'll search
+    if (v)
+    { "  Computing primary invariants in degree ",d,":";
+    }
+    B=invariant_basis_reynolds(REY,d,intvec(-1,6)); // basis of invariants of
+                                       // degree d
+    if (B[1]<>0)
+    { Pplus=P+B;
+      newdim=dim(groebner(Pplus));
+      dif=n-i-newdim;
+    }
+    else
+    { dif=0;
+      deg_vector=deg_vector,d;
+    }
+    if (dif<>0)                        // we have to find dif new primary
+    {                                  // invariants
+      cd=size(B);
+      if (cd<>dif)
+      { P,sP,CI,dB=search(n,d,B,cd,P,sP,i,dif,dB,CI);
+      }
+      else                             // i.e. we can take all of B
+      { for(j=i+1;j<=i+dif;j++)
+        { CI=CI+ideal(var(j)^d);
+        }
+        dB=dB+dif*(d-1);
+        P=Pplus;
+        sP=groebner(P);
+      }
+      if (v)
+      { for (j=1;j<=dif;j++)
+        { "  We find: "+string(P[i+j]);
+        }
+      }
+      i=i+dif;
+      if (i==n)                        // found all primary invariants
+      { if (v)
+        { "";
+          "  We found all primary invariants.";
+          "";
+        }
+        if (deg_vector==0)
+        { return(matrix(P));
+        }
+        else
+        { return(matrix(P),compress(deg_vector));
+        }
+      }
+    }                                  // done with degree d
+    else
+    { if (v)
+      { "  None here...";
+      }
+    }
+  }
+}
+example
+{ "EXAMPLE: Sturmfels: Algorithms in Invariant Theory 2.3.7:"; echo=2;
+         ring R=0,(x,y,z),dp;
+         matrix A[3][3]=0,1,0,-1,0,0,0,0,-1;
+         list L=group_reynolds(A);
+         list l=primary_char0_no_molien(L[1]);
+         print(l[1]);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc primary_charp_no_molien (matrix REY, list #)
+"USAGE:   primary_charp_no_molien(REY[,v]);
+         REY: a <matrix> representing the Reynolds operator, v: an optional
+         <int>
+ASSUME:  REY is the first return value of group_reynolds or reynolds_molien
+DISPLAY: information about the various stages of the programme if v does not
+         equal 0
+RETURN:  primary invariants (type <matrix>) of the invariant ring  and an
+         <intvec> listing some of the degrees where no non-trivial homogeneous
+         invariants are to be found
+THEORY:  Bases of homogeneous invariants are generated successively and those
+         are chosen as primary invariants that lower the dimension of the ideal
+         generated by the previously found invariants (see paper \"Generating a
+         Noetherian Normalization of the Invariant Ring of a Finite Group\" by
+         Decker, Heydtmann, Schreyer (1998)).
+EXAMPLE: example primary_charp_no_molien; shows an example
+"
+{ degBound=0;
+ //----------------- checking input and setting verbose mode ------------------
+  if (char(basering)==0)
+  { "ERROR:   primary_charp_no_molien should only be used with rings of";
+    "         characteristic p>0.";
+    return();
+  }
+  if (size(#)>1)
+  { "ERROR:   primary_charp_no_molien can only have two parameters.";
+    return();
+  }
+  if (size(#)==1)
+  { if (typeof(#[1])<>"int")
+    { "ERROR:   The second parameter should be of type <int>.";
+      return();
+    }
+    else
+    { int v=#[1]; }
+  }
+  else
+  { int v=0;
+  }
+  int n=nvars(basering);               // n is the number of variables, as well
+                                       // as the size of the matrices, as well
+                                       // as the number of primary invariants,
+                                       // we should get
+  if (ncols(REY)<>n)
+  { "ERROR:   First parameter ought to be the Reynolds operator."
+    return();
+  }
+ //----------------------------------------------------------------------------
+  if (v && voice<>2)
+  { "  We can start looking for primary invariants...";
+    "";
+  }
+  if (v && voice==2)
+  { ""; }
+ //-------------------- initializing variables --------------------------------
+  int dB;
+  int j,d,cd,newdim,dif;               // d: current degree, cd: dimension of
+                                       // space of invariants of degree d,
+                                       // newdim: dimension the ideal generated
+                                       // the primary invariants plus basis
+                                       // elements, dif=n-i-newdim, i.e. the
+                                       // number of new primary invairants that
+                                       // should be added in this degree -
+  ideal P,Pplus,sPplus,CI,B;           // P: will contain primary invariants,
+                                       // Pplus: P+B, CI: a complete
+                                       // intersection with the same Hilbert
+                                       // function as P
+  ideal sP=groebner(P);
+  dB=1;                                // used as degree bound -
+  d=0;                                 // initializing
+  int i=0;
+  intvec deg_vector;
+ //------------------ loop that searches for primary invariants ---------------
+  while(1)                             // repeat until n primary invariants are
+  {                                    // found -
+    d++;                               // degree where we'll search
+    if (v)
+    { "  Computing primary invariants in degree ",d,":";
+    }
+    B=invariant_basis_reynolds(REY,d,intvec(-1,6)); // basis of invariants of
+                                       // degree d
+    if (B[1]<>0)
+    { Pplus=P+B;
+      sPplus=groebner(Pplus);
+      newdim=dim(sPplus);
+      dif=n-i-newdim;
+    }
+    else
+    { dif=0;
+      deg_vector=deg_vector,d;
+    }
+    if (dif<>0)                        // we have to find dif new primary
+    {                                  // invariants
+      cd=size(B);
+      if (cd<>dif)
+      { P,sP,CI,dB=p_search(n,d,B,cd,P,sP,i,dif,dB,CI);
+      }
+      else                             // i.e. we can take all of B
+      { for(j=i+1;j<=i+dif;j++)
+        { CI=CI+ideal(var(j)^d);
+        }
+        dB=dB+dif*(d-1);
+        P=Pplus;
+        sP=sPplus;
+      }
+      if (v)
+      { for (j=1;j<=size(P)-i;j++)
+        { "  We find: "+string(P[i+j]);
+        }
+      }
+      i=size(P);
+      if (i==n)                        // found all primary invariants
+      { if (v)
+        { "";
+          "  We found all primary invariants.";
+          "";
+        }
+        if (deg_vector==0)
+        { return(matrix(P));
+        }
+        else
+        { return(matrix(P),compress(deg_vector));
+        }
+      }
+    }                                  // done with degree d
+    else
+    { if (v)
+      { "  None here...";
+      }
+    }
+  }
+}
+example
+{ "EXAMPLE: Sturmfels: Algorithms in Invariant Theory 2.3.7 (changed into char 3)"; echo=2;
+         ring R=3,(x,y,z),dp;
+         matrix A[3][3]=0,1,0,-1,0,0,0,0,-1;
+         list L=group_reynolds(A);
+         list l=primary_charp_no_molien(L[1]);
+         print(l[1]);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc primary_charp_without (list #)
+"USAGE:   primary_charp_without(G1,G2,...[,v]);
+         G1,G2,...: <matrices> generating a finite matrix group, v: an optional
+         <int>
+DISPLAY: information about the various stages of the programme if v does not
+         equal 0
+RETURN:  primary invariants (type <matrix>) of the invariant ring
+THEORY:  Bases of homogeneous invariants are generated successively and those
+         are chosen as primary invariants that lower the dimension of the ideal
+         generated by the previously found invariants (see paper \"Generating a
+         Noetherian Normalization of the Invariant Ring of a Finite Group\" by
+         Decker, Heydtmann, Schreyer (1998)). No Reynolds
+         operator or Molien series is used.
+EXAMPLE: example primary_charp_without; shows an example
+"
+{ degBound=0;
+ //--------------------- checking input and setting verbose mode --------------
+  if (char(basering)==0)
+  { "ERROR:   primary_charp_without should not be used with rings of";
+    "         characteristic 0.";
+    return();
+  }
+  if (size(#)==0)
+  { "ERROR:   There are no parameters.";
+    return();
+  }
+  if (typeof(#[size(#)])=="int")
+  { int v=#[size(#)];
+    int gen_num=size(#)-1;
+    if (gen_num==0)
+    { "ERROR:   There are no generators of a finite matrix group given.";
+      return();
+    }
+  }
+  else
+  { int v=0;
+    int gen_num=size(#);
+  }
+  int n=nvars(basering);               // n is the number of variables, as well
+                                       // as the size of the matrices, as well
+                                       // as the number of primary invariants,
+                                       // we should get
+  for (int i=1;i<=gen_num;i++)
+  { if (typeof(#[i])=="matrix")
+    { if (nrows(#[i])<>n or ncols(#[i])<>n)
+      { "ERROR:   The number of variables of the base ring needs to be the same";
+        "         as the dimension of the square matrices";
+        return();
+      }
+    }
+    else
+    { "ERROR:   The first parameters should be a list of matrices";
+      return();
+    }
+  }
+ //----------------------------------------------------------------------------
+  if (v && voice==2)
+  { "";
+  }
+ //---------------------------- initializing variables ------------------------
+  int dB;
+  int j,d,cd,newdim,dif;               // d: current degree, cd: dimension of
+                                       // space of invariants of degree d,
+                                       // newdim: dimension the ideal generated
+                                       // by the primary invariants plus basis
+                                       // elements, dif=n-i-newdim, i.e. the
+                                       // number of new primary invairants that
+                                       // should be added in this degree -
+  ideal P,Pplus,sPplus,CI,B;           // P: will contain primary invariants,
+                                       // Pplus: P+B, CI: a complete
+                                       // intersection with the same Hilbert
+                                       // function as P
+  ideal sP=groebner(P);
+  dB=1;                                // used as degree bound -
+  d=0;                                 // initializing
+  i=0;
+  intvec deg_vector;
+ //-------------------- loop that searches for primary invariants -------------
+  while(1)                             // repeat until n primary invariants are
+  {                                    // found -
+    d++;                               // degree where we'll search
+    if (v)
+    { "  Computing primary invariants in degree ",d,":";
+    }
+    B=invariant_basis(d,#[1..gen_num]); // basis of invariants of degree d
+    if (B[1]<>0)
+    { Pplus=P+B;
+      sPplus=groebner(Pplus);
+      newdim=dim(sPplus);
+      dif=n-i-newdim;
+    }
+    else
+    { dif=0;
+      deg_vector=deg_vector,d;
+    }
+    if (dif<>0)                        // we have to find dif new primary
+    {                                  // invariants
+      cd=size(B);
+      if (cd<>dif)
+      { P,sP,CI,dB=p_search(n,d,B,cd,P,sP,i,dif,dB,CI);
+      }
+      else                             // i.e. we can take all of B
+      { for(j=i+1;j<=i+dif;j++)
+        { CI=CI+ideal(var(j)^d);
+        }
+        dB=dB+dif*(d-1);
+        P=Pplus;
+        sP=sPplus;
+      }
+      if (v)
+      { for (j=1;j<=size(P)-i;j++)
+        { "  We find: "+string(P[i+j]);
+        }
+      }
+      i=size(P);
+      if (i==n)                        // found all primary invariants
+      { if (v)
+        { "";
+          "  We found all primary invariants.";
+          "";
+        }
+        return(matrix(P));
+      }
+    }                                  // done with degree d
+    else
+    { if (v)
+      { "  None here...";
+      }
+    }
+  }
+}
+example
+{ "EXAMPLE:"; echo=2;
+         ring R=2,(x,y,z),dp;
+         matrix A[3][3]=0,1,0,-1,0,0,0,0,-1;
+         matrix P=primary_charp_without(A);
+         print(P);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc primary_invariants (list #)
+"USAGE:   primary_invariants(G1,G2,...[,flags]);
+         G1,G2,...: <matrices> generating a finite matrix group, flags: an
+         optional <intvec> with three entries, if the first one equals 0 (also
+         the default), the programme attempts to compute the Molien series and
+         Reynolds operator, if it equals 1, the programme is told that the
+         Molien series should not be computed, if it equals -1 characteristic 0
+         is simulated, i.e. the Molien series is computed as if the base field
+         were characteristic 0 (the user must choose a field of large prime
+         characteristic, e.g. 32003) and if the first one is anything else, it
+         means that the characteristic of the base field divides the group
+         order, the second component should give the size of intervals between
+         canceling common factors in the expansion of the Molien series, 0 (the
+         default) means only once after generating all terms, in prime
+         characteristic also a negative number can be given to indicate that
+         common factors should always be canceled when the expansion is simple
+         (the root of the extension field occurs not among the coefficients)
+DISPLAY: information about the various stages of the programme if the third
+         flag does not equal 0
+RETURN:  primary invariants (type <matrix>) of the invariant ring and if
+         computable Reynolds operator (type <matrix>) and Molien series (type
+         <matrix>) or ring name (type string) where the Molien series
+         can be found in the char p case; if the first flag is 1 and we are in
+         the non-modular case then an <intvec> is returned giving some of the
+         degrees where no non-trivial homogeneous invariants can be found
+THEORY:  Bases of homogeneous invariants are generated successively and those
+         are chosen as primary invariants that lower the dimension of the ideal
+         generated by the previously found invariants (see paper \"Generating a
+         Noetherian Normalization of the Invariant Ring of a Finite Group\" by
+         Decker, Heydtmann, Schreyer (1998)).
+EXAMPLE: example primary_invariants; shows an example
+"
+{
+ // ----------------- checking input and setting flags ------------------------
+  if (size(#)==0)
+  { "ERROR:   There are no parameters.";
+    return();
+  }
+  int ch=char(basering);               // the algorithms depend very much on the
+                                       // characteristic of the ground field
+  int n=nvars(basering);               // n is the number of variables, as well
+                                       // as the size of the matrices, as well
+                                       // as the number of primary invariants,
+                                       // we should get
+  int gen_num;
+  int mol_flag,v;
+  if (typeof(#[size(#)])=="intvec")
+  { if (size(#[size(#)])<>3)
+    { "ERROR:   <intvec> should have three entries.";
+      return();
+    }
+    gen_num=size(#)-1;
+    mol_flag=#[size(#)][1];
+    if (#[size(#)][2]<0 && (ch==0 or (ch<>0 && mol_flag==-1)))
+    { "ERROR:   the second component of <intvec> should be >=0";
+      return();
+    }
+    int interval=#[size(#)][2];
+    v=#[size(#)][3];
+    if (gen_num==0)
+    { "ERROR:   There are no generators of a finite matrix group given.";
+      return();
+    }
+  }
+  else
+  { gen_num=size(#);
+    mol_flag=0;
+    int interval=0;
+    v=0;
+  }
+  for (int i=1;i<=gen_num;i++)
+  { if (typeof(#[i])=="matrix")
+    { if (nrows(#[i])<>n or ncols(#[i])<>n)
+      { "ERROR:   The number of variables of the base ring needs to be the same";
+        "         as the dimension of the square matrices";
+        return();
+      }
+    }
+    else
+    { "ERROR:   The first parameters should be a list of matrices";
+      return();
+    }
+  }
+ //----------------------------------------------------------------------------
+  if (mol_flag==0)
+  { if (ch==0)
+    { matrix REY,M=reynolds_molien(#[1..gen_num],intvec(mol_flag,interval,v));
+                                       // one will contain Reynolds operator and
+                                       // the other enumerator and denominator
+                                       // of Molien series
+      matrix P=primary_char0(REY,M,v);
+      return(P,REY,M);
+    }
+    else
+    { list L=group_reynolds(#[1..gen_num],v);
+      if (L[1]<>0)                     // testing whether we are in the modular
+      { string newring="aksldfalkdsflkj"; // case
+        if (minpoly==0)
+        { if (v)
+          { "  We are dealing with the non-modular case.";
+          }
+          if (typeof(L[2])=="int")
+          { molien(L[3..size(L)],newring,L[2],intvec(mol_flag,interval,v));
+          }
+          else
+          { molien(L[2..size(L)],newring,intvec(mol_flag,interval,v));
+          }
+          matrix P=primary_charp(L[1],newring,v);
+          return(P,L[1],newring);
+        }
+        else
+        { if (v)
+          { "  Since it is impossible for this programme to calculate the Molien series for";
+            "  invariant rings over extension fields of prime characteristic, we have to";
+            "  continue without it.";
+            "";
+
+          }
+          list l=primary_charp_no_molien(L[1],v);
+          if (size(l)==2)
+          { return(l[1],L[1],l[2]);
+          }
+          else
+          { return(l[1],L[1]);
+          }
+        }
+      }
+      else                             // the modular case
+      { if (v)
+        { "  There is also no Molien series, we can make use of...";
+          "";
+          "  We can start looking for primary invariants...";
+          "";
+        }
+        return(primary_charp_without(#[1..gen_num],v));
+      }
+    }
+  }
+  if (mol_flag==1)                     // the user wants no calculation of the
+  { list L=group_reynolds(#[1..gen_num],v); // Molien series
+    if (ch==0)
+    { list l=primary_char0_no_molien(L[1],v);
+      if (size(l)==2)
+      { return(l[1],L[1],l[2]);
+      }
+      else
+      { return(l[1],L[1]);
+      }
+    }
+    else
+    { if (L[1]<>0)                     // testing whether we are in the modular
+      { list l=primary_charp_no_molien(L[1],v); // case
+        if (size(l)==2)
+        { return(l[1],L[1],l[2]);
+        }
+        else
+        { return(l[1],L[1]);
+        }
+      }
+      else                             // the modular case
+      { if (v)
+        { "  We can start looking for primary invariants...";
+          "";
+        }
+        return(primary_charp_without(#[1..gen_num],v));
+      }
+    }
+  }
+  if (mol_flag==-1)
+  { if (ch==0)
+    { "ERROR:   Characteristic 0 can only be simulated in characteristic p>>0.";
+      return();
+    }
+    list L=group_reynolds(#[1..gen_num],v);
+    string newring="aksldfalkdsflkj";
+    molien(L[2..size(L)],newring,intvec(1,interval,v));
+    matrix P=primary_charp(L[1],newring,v);
+    return(P,L[1],newring);
+  }
+  else                                 // the user specified that the
+  { if (ch==0)                         // characteristic divides the group order
+    { "ERROR:   The characteristic cannot divide the group order when it is 0.";
+      return();
+    }
+    if (v)
+    { "";
+    }
+    return(primary_charp_without(#[1..gen_num],v));
+  }
+}
+example
+{ "EXAMPLE: Sturmfels: Algorithms in Invariant Theory 2.3.7:";
+  echo=2;
+         ring R=0,(x,y,z),dp;
+         matrix A[3][3]=0,1,0,-1,0,0,0,0,-1;
+         list L=primary_invariants(A);
+         print(L[1]);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// This procedure finds dif primary invariants in degree d. It returns all
+// primary invariants found so far. The coefficients lie in a field of
+// characteristic 0.
+///////////////////////////////////////////////////////////////////////////////
+proc search_random (int n,int d,ideal B,int cd,ideal P,int i,int dif,int dB,ideal CI,int max)
+{ string answer;
+  degBound=0;
+  int j,k,test_dim,flag;
+  matrix test_matrix[1][dif];          // the linear combination to test
+  intvec h;                            // Hilbert series
+  for (j=i+1;j<=i+dif;j++)
+  { CI=CI+ideal(var(j)^d);             // homogeneous polynomial of the same
+                                       // degree as the one we're looking for
+                                       // is added
+  }
+  ideal TEST;
+  // h=hilb(std(CI),1);
+  dB=dB+dif*(d-1);                     // used as degBound
+  while (1)
+  { test_matrix=matrix(B)*random(max,cd,dif);
+    // degBound=dB;
+    TEST=P+ideal(test_matrix);
+    attrib(TEST,"isSB",1);
+    test_dim=dim(TEST);
+    // degBound=0;
+    if (n-test_dim==i+dif)
+    { break;
+    }
+    // degBound=dB;
+    test_dim=dim(groebner(TEST));
+    // test_dim=dim(std(TEST,h));         // Hilbert driven std-calculation
+    // degBound=0;
+    if (n-test_dim==i+dif)
+    { break;
+    }
+    else
+    { "HELP:    The ",dif," random combination(s) of the ",cd," basis elements with";
+      "         coefficients in the range from -",max," to ",max," did not lower the";
+      "         dimension by ",dif,". You can abort, try again or give a new range:";
+      answer="";
+      while (answer<>"n
+" && answer<>"y
+")
+      { "         Do you want to abort (y/n)?";
+        answer=read("");
+      }
+      if (answer=="y
+")
+      { flag=1;
+        break;
+      }
+      answer="";
+      while (answer<>"n
+" && answer<>"y
+")
+      { "         Do you want to try again (y/n)?";
+        answer=read("");
+      }
+      if (answer=="n
+")
+      { flag=1;
+        while (flag)
+        { "         Give a new <int> > ",max," that bounds the range of coefficients:";
+          answer=read("");
+          for (j=1;j<=size(answer)-1;j++)
+          { for (k=0;k<=9;k++)
+            { if (answer[j]==string(k))
+              { break;
+              }
+            }
+            if (k>9)
+            { flag=1;
+              break;
+            }
+            flag=0;
+          }
+          if (not(flag))
+          { execute("test_dim="+string(answer[1..size(answer)]));
+            if (test_dim<=max)
+            { flag=1;
+            }
+            else
+            { max=test_dim;
+            }
+          }
+        }
+      }
+    }
+  }
+  if (not(flag))
+  { P[(i+1)..(i+dif)]=test_matrix[1,1..dif];
+  }
+  return(P,CI,dB);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// This procedure finds at most dif primary invariants in degree d. It returns
+// all primary invariants found so far. The coefficients lie in the field of
+// characteristic p>0.
+///////////////////////////////////////////////////////////////////////////////
+proc p_search_random (int n,int d,ideal B,int cd,ideal P,int i,int dif,int dB,ideal CI,int max)
+{ string answer;
+  degBound=0;
+  int j,k,test_dim,flag;
+  matrix test_matrix[1][dif];          // the linear combination to test
+  intvec h;                            // Hilbert series
+  ideal TEST;
+  while (dif>0)
+  { for (j=i+1;j<=i+dif;j++)
+    { CI=CI+ideal(var(j)^d);           // homogeneous polynomial of the same
+                                       // degree as the one we're looking for
+                                       // is added
+    }
+    // h=hilb(std(CI),1);
+    dB=dB+dif*(d-1);                   // used as degBound
+    test_matrix=matrix(B)*random(max,cd,dif);
+    // degBound=dB;
+    TEST=P+ideal(test_matrix);
+    attrib(TEST,"isSB",1);
+    test_dim=dim(TEST);
+    // degBound=0;
+    if (n-test_dim==i+dif)
+    { break;
+    }
+    // degBound=dB;
+    test_dim=dim(groebner(TEST));
+    // test_dim=dim(std(TEST,h));         // Hilbert driven std-calculation
+    // degBound=0;
+    if (n-test_dim==i+dif)
+    { break;
+    }
+    else
+    { "HELP:    The ",dif," random combination(s) of the ",cd," basis elements with";
+      "         coefficients in the range from -",max," to ",max," did not lower the";
+      "         dimension by ",dif,". You can abort, try again, lower the number of";
+      "         combinations searched for by 1 or give a larger coefficient range:";
+      answer="";
+      while (answer<>"n
+" && answer<>"y
+")
+      { "         Do you want to abort (y/n)?";
+        answer=read("");
+      }
+      if (answer=="y
+")
+      { flag=1;
+        break;
+      }
+      answer="";
+      while (answer<>"n
+" && answer<>"y
+")
+      { "         Do you want to try again (y/n)?";
+        answer=read("");
+      }
+      if (answer=="n
+")
+      { answer="";
+        while (answer<>"n
+" && answer<>"y
+")
+        { "         Do you want to lower the number of combinations by 1 (y/n)?";
+          answer=read("");
+        }
+        if (answer=="y
+")
+        { dif=dif-1;
+        }
+        else
+        { flag=1;
+          while (flag)
+          { "         Give a new <int> > ",max," that bounds the range of coefficients:";
+            answer=read("");
+            for (j=1;j<=size(answer)-1;j++)
+            { for (k=0;k<=9;k++)
+              { if (answer[j]==string(k))
+                { break;
+                }
+              }
+              if (k>9)
+              { flag=1;
+                break;
+              }
+              flag=0;
+            }
+            if (not(flag))
+            { execute("test_dim="+string(answer[1..size(answer)]));
+              if (test_dim<=max)
+              { flag=1;
+              }
+              else
+              { max=test_dim;
+              }
+            }
+          }
+        }
+      }
+    }
+    CI=CI[1..i];
+    dB=dB-dif*(d-1);
+  }
+  if (dif && not(flag))
+  { P[(i+1)..(i+dif)]=test_matrix[1,1..dif];
+  }
+  if (dif && flag)
+  { P[n+1]=0;
+  }
+  return(P,CI,dB);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc primary_char0_random (matrix REY,matrix M,int max,list #)
+"USAGE:   primary_char0_random(REY,M,r[,v]);
+         REY: a <matrix> representing the Reynolds operator, M: a 1x2 <matrix>
+         representing the Molien series, r: an <int> where -|r| to |r| is the
+         range of coefficients of the random combinations of bases elements,
+         v: an optional <int>
+ASSUME:  REY is the first return value of group_reynolds or reynolds_molien and
+         M the one of molien or the second one of reynolds_molien
+DISPLAY: information about the various stages of the programme if v does not
+         equal 0
+RETURN:  primary invariants (type <matrix>) of the invariant ring
+THEORY:  Bases of homogeneous invariants are generated successively and random
+         linear combinations are chosen as primary invariants that lower the
+         dimension of the ideal generated by the previously found invariants
+         (see \"Generating a Noetherian Normalization of the Invariant Ring of
+         a Finite Group\" by Decker, Heydtmann, Schreyer (1998)).
+EXAMPLE: example primary_char0_random; shows an example
+"
+{ degBound=0;
+  if (char(basering)<>0)
+  { "ERROR:   primary_char0_random should only be used with rings of";
+    "         characteristic 0.";
+    return();
+  }
+ //----------------- checking input and setting verbose mode ------------------
+  if (size(#)>1)
+  { "ERROR:   primary_char0_random can only have four parameters.";
+    return();
+  }
+  if (size(#)==1)
+  { if (typeof(#[1])<>"int")
+    { "ERROR:   The fourth parameter should be of type <int>.";
+      return();
+    }
+    else
+    { int v=#[1];
+    }
+  }
+  else
+  { int v=0;
+  }
+  int n=nvars(basering);               // n is the number of variables, as well
+                                       // as the size of the matrices, as well
+                                       // as the number of primary invariants,
+                                       // we should get
+  if (ncols(REY)<>n)
+  { "ERROR:   First parameter ought to be the Reynolds operator."
+    return();
+  }
+  if (ncols(M)<>2 or nrows(M)<>1)
+  { "ERROR:   Second parameter ought to be the Molien series."
+    return();
+  }
+ //----------------------------------------------------------------------------
+  if (v && voice<>2)
+  { "  We can start looking for primary invariants...";
+    "";
+  }
+  if (v && voice==2)
+  { "";
+  }
+ //------------------------- initializing variables ---------------------------
+  int dB;
+  poly p(1..2);                        // p(1) will be used for single terms of
+                                       // the partial expansion, p(2) to store
+  p(1..2)=partial_molien(M,1);         // the intermediate result -
+  poly v1=var(1);                      // we need v1 to split off coefficients
+                                       // in the partial expansion of M (which
+                                       // is in terms of the first variable) -
+  int j,d,cd,newdim,dif;               // d: current degree, cd: dimension of
+                                       // space of invariants of degree d,
+                                       // newdim: dimension the ideal generated
+                                       // the primary invariants plus basis
+                                       // elements, dif=n-i-newdim, i.e. the
+                                       // number of new primary invairants that
+                                       // should be added in this degree -
+  ideal P,Pplus,CI,B;                  // P: will contain primary invariants,
+                                       // Pplus: P+B,CI: a complete
+                                       // intersection with the same Hilbert
+                                       // function as P -
+  dB=1;                                // used as degree bound
+  int i=0;
+ //-------------- loop that searches for primary invariants  ------------------
+  while(1)                             // repeat until n primary invariants are
+  {                                    // found -
+    p(1..2)=partial_molien(M,1,p(2));  // next term of the partial expansion -
+    d=deg(p(1));                       // degree where we'll search -
+    cd=int(coef(p(1),v1)[2,1]);        // dimension of the homogeneous space of
+                                       // inviarants of degree d
+    if (v)
+    { "  Computing primary invariants in degree ",d,":";
+    }
+    B=invariant_basis_reynolds(REY,d,intvec(cd,6)); // basis of invariants of
+                                       // degree d
+    if (B[1]<>0)
+    { Pplus=P+B;
+      newdim=dim(groebner(Pplus));
+      dif=n-i-newdim;
+    }
+    else
+    { dif=0;
+    }
+    if (dif<>0)                        // we have to find dif new primary
+    {                                  // invariants
+      if (cd<>dif)
+      { P,CI,dB=search_random(n,d,B,cd,P,i,dif,dB,CI,max); // searching for
+      }                                // dif invariants -
+      else                             // i.e. we can take all of B
+      { for(j=i+1;j>i+dif;j++)
+        { CI=CI+ideal(var(j)^d);
+        }
+        dB=dB+dif*(d-1);
+        P=Pplus;
+      }
+      if (ncols(P)==i)
+      { "WARNING: The return value is not a set of primary invariants, but";
+        "         polynomials qualifying as the first ",i," primary invariants.";
+        return(matrix(P));
+      }
+      if (v)
+      { for (j=1;j<=dif;j++)
+        { "  We find: "+string(P[i+j]);
+        }
+      }
+      i=i+dif;
+      if (i==n)                        // found all primary invariants
+      { if (v)
+        { "";
+          "  We found all primary invariants.";
+          "";
+        }
+        return(matrix(P));
+      }
+    }                                  // done with degree d
+  }
+}
+example
+{ "EXAMPLE: Sturmfels: Algorithms in Invariant Theory 2.3.7:"; echo=2;
+         ring R=0,(x,y,z),dp;
+         matrix A[3][3]=0,1,0,-1,0,0,0,0,-1;
+         matrix REY,M=reynolds_molien(A);
+         matrix P=primary_char0_random(REY,M,1);
+         print(P);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc primary_charp_random (matrix REY,string ring_name,int max,list #)
+"USAGE:   primary_charp_random(REY,ringname,r[,v]);
+         REY: a <matrix> representing the Reynolds operator, ringname: a
+         <string> giving the name of a ring where the Molien series is stored,
+         r: an <int> where -|r| to |r| is the range of coefficients of the
+         random combinations of bases elements, v: an optional <int>
+ASSUME:  REY is the first return value of group_reynolds or reynolds_molien and
+         ringname gives the name of a ring of characteristic 0 that has been
+         created by molien or reynolds_molien
+DISPLAY: information about the various stages of the programme if v does not
+         equal 0
+RETURN:  primary invariants (type <matrix>) of the invariant ring
+THEORY:  Bases of homogeneous invariants are generated successively and random
+         linear combinations are chosen as primary invariants that lower the
+         dimension of the ideal generated by the previously found invariants
+         (see \"Generating a Noetherian Normalization of the Invariant Ring of
+         a Finite Group\" by Decker, Heydtmann, Schreyer (1998)).
+EXAMPLE: example primary_charp_random; shows an example
+"
+{ degBound=0;
+ // ---------------- checking input and setting verbose mode ------------------
+  if (char(basering)==0)
+  { "ERROR:   primary_charp_random should only be used with rings of";
+    "         characteristic p>0.";
+    return();
+  }
+  if (size(#)>1)
+  { "ERROR:   primary_charp_random can only have four parameters.";
+    return();
+  }
+  if (size(#)==1)
+  { if (typeof(#[1])<>"int")
+    { "ERROR:   The fourth parameter should be of type <int>.";
+      return();
+    }
+    else
+    { int v=#[1];
+    }
+  }
+  else
+  { int v=0;
+  }
+  def br=basering;
+  int n=nvars(br);                     // n is the number of variables, as well
+                                       // as the size of the matrices, as well
+                                       // as the number of primary invariants,
+                                       // we should get
+  if (ncols(REY)<>n)
+  { "ERROR:   First parameter ought to be the Reynolds operator."
+    return();
+  }
+  if (typeof(`ring_name`)<>"ring")
+  { "ERROR:   Second parameter ought to the name of a ring where the Molien";
+    "         is stored.";
+    return();
+  }
+ //----------------------------------------------------------------------------
+  if (v && voice<>2)
+  { "  We can start looking for primary invariants...";
+    "";
+  }
+  if (v && voice==2)
+  { "";
+  }
+ //----------------------- initializing variables -----------------------------
+  int dB;
+  setring `ring_name`;                 // the Molien series is stores here -
+  poly p(1..2);                        // p(1) will be used for single terms of
+                                       // the partial expansion, p(2) to store
+  p(1..2)=partial_molien(M,1);         // the intermediate result -
+  poly v1=var(1);                      // we need v1 to split off coefficients
+                                       // in the partial expansion of M (which
+                                       // is in terms of the first variable)
+  setring br;
+  int j,d,cd,newdim,dif;               // d: current degree, cd: dimension of
+                                       // space of invariants of degree d,
+                                       // newdim: dimension the ideal generated
+                                       // the primary invariants plus basis
+                                       // elements, dif=n-i-newdim, i.e. the
+                                       // number of new primary invairants that
+                                       // should be added in this degree -
+  ideal P,Pplus,CI,B;                  // P: will contain primary invariants,
+                                       // Pplus: P+B, CI: a complete
+                                       // intersection with the same Hilbert
+                                       // function as P -
+  dB=1;                                // used as degree bound
+  int i=0;
+ //---------------- loop that searches for primary invariants -----------------
+  while(1)                             // repeat until n primary invariants are
+  {                                    // found
+    setring `ring_name`;
+    p(1..2)=partial_molien(M,1,p(2));  // next term of the partial expansion -
+    d=deg(p(1));                       // degree where we'll search -
+    cd=int(coef(p(1),v1)[2,1]);        // dimension of the homogeneous space of
+                                       // inviarants of degree d
+    setring br;
+    if (v)
+    { "  Computing primary invariants in degree ",d,":";
+    }
+    B=invariant_basis_reynolds(REY,d,intvec(cd,6)); // basis of invariants of
+                                       // degree d
+    if (B[1]<>0)
+    { Pplus=P+B;
+      newdim=dim(groebner(Pplus));
+      dif=n-i-newdim;
+    }
+    else
+    { dif=0;
+    }
+    if (dif<>0)                        // we have to find dif new primary
+    {                                  // invariants
+      if (cd<>dif)
+      { P,CI,dB=p_search_random(n,d,B,cd,P,i,dif,dB,CI,max);
+      }
+      else                             // i.e. we can take all of B
+      { for(j=i+1;j>i+dif;j++)
+        { CI=CI+ideal(var(j)^d);
+        }
+        dB=dB+dif*(d-1);
+        P=Pplus;
+      }
+      if (ncols(P)==n+1)
+      { "WARNING: The first return value is not a set of primary invariants,";
+        "         but polynomials qualifying as the first ",i," primary invariants.";
+        return(matrix(P));
+      }
+      if (v)
+      { for (j=1;j<=size(P)-i;j++)
+        { "  We find: "+string(P[i+j]);
+        }
+      }
+      i=size(P);
+      if (i==n)                        // found all primary invariants
+      { if (v)
+        { "";
+          "  We found all primary invariants.";
+          "";
+        }
+        return(matrix(P));
+      }
+    }                                  // done with degree d
+  }
+}
+example
+{ "EXAMPLE: Sturmfels: Algorithms in Invariant Theory 2.3.7 (changed into char 3)"; echo=2;
+         ring R=3,(x,y,z),dp;
+         matrix A[3][3]=0,1,0,-1,0,0,0,0,-1;
+         list L=group_reynolds(A);
+         string newring="alskdfj";
+         molien(L[2..size(L)],newring);
+         matrix P=primary_charp_random(L[1],newring,1);
+         kill Finvar::`newring`;
+         print(P);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc primary_char0_no_molien_random (matrix REY, int max, list #)
+"USAGE:   primary_char0_no_molien_random(REY,r[,v]);
+         REY: a <matrix> representing the Reynolds operator, r: an <int> where
+         -|r| to |r| is the range of coefficients of the random combinations of
+         bases elements, v: an optional <int>
+ASSUME:  REY is the first return value of group_reynolds or reynolds_molien
+DISPLAY: information about the various stages of the programme if v does not
+         equal 0
+RETURN:  primary invariants (type <matrix>) of the invariant ring  and an
+         <intvec> listing some of the degrees where no non-trivial homogeneous
+         invariants are to be found
+THEORY:  Bases of homogeneous invariants are generated successively and random
+         linear combinations are chosen as primary invariants that lower the
+         dimension of the ideal generated by the previously found invariants
+         (see \"Generating a Noetherian Normalization of the Invariant Ring of
+         a Finite Group\" by Decker, Heydtmann, Schreyer (1998)).
+EXAMPLE: example primary_char0_no_molien_random; shows an example
+"
+{ degBound=0;
+ //-------------- checking input and setting verbose mode ---------------------
+  if (char(basering)<>0)
+  { "ERROR:   primary_char0_no_molien_random should only be used with rings of";
+    "         characteristic 0.";
+    return();
+  }
+  if (size(#)>1)
+  { "ERROR:   primary_char0_no_molien_random can only have three parameters.";
+    return();
+  }
+  if (size(#)==1)
+  { if (typeof(#[1])<>"int")
+    { "ERROR:   The third parameter should be of type <int>.";
+      return();
+    }
+    else
+    { int v=#[1];
+    }
+  }
+  else
+  { int v=0;
+  }
+  int n=nvars(basering);               // n is the number of variables, as well
+                                       // as the size of the matrices, as well
+                                       // as the number of primary invariants,
+                                       // we should get
+  if (ncols(REY)<>n)
+  { "ERROR:   First parameter ought to be the Reynolds operator."
+    return();
+  }
+ //----------------------------------------------------------------------------
+  if (v && voice<>2)
+  { "  We can start looking for primary invariants...";
+    "";
+  }
+  if (v && voice==2)
+  { "";
+  }
+ //----------------------- initializing variables -----------------------------
+  int dB;
+  int j,d,cd,newdim,dif;               // d: current degree, cd: dimension of
+                                       // space of invariants of degree d,
+                                       // newdim: dimension the ideal generated
+                                       // the primary invariants plus basis
+                                       // elements, dif=n-i-newdim, i.e. the
+                                       // number of new primary invairants that
+                                       // should be added in this degree -
+  ideal P,Pplus,CI,B;                  // P: will contain primary invariants,
+                                       // Pplus: P+B, CI: a complete
+                                       // intersection with the same Hilbert
+                                       // function as P -
+  dB=1;                                // used as degree bound -
+  d=0;                                 // initializing
+  int i=0;
+  intvec deg_vector;
+ //------------------ loop that searches for primary invariants ---------------
+  while(1)                             // repeat until n primary invariants are
+  {                                    // found -
+    d++;                               // degree where we'll search
+    if (v)
+    { "  Computing primary invariants in degree ",d,":";
+    }
+    B=invariant_basis_reynolds(REY,d,intvec(-1,6)); // basis of invariants of
+                                       // degree d
+    if (B[1]<>0)
+    { Pplus=P+B;
+      newdim=dim(groebner(Pplus));
+      dif=n-i-newdim;
+    }
+    else
+    { dif=0;
+      deg_vector=deg_vector,d;
+    }
+    if (dif<>0)                        // we have to find dif new primary
+    {                                  // invariants
+      cd=size(B);
+      if (cd<>dif)
+      { P,CI,dB=search_random(n,d,B,cd,P,i,dif,dB,CI,max);
+      }
+      else                             // i.e. we can take all of B
+      { for(j=i+1;j<=i+dif;j++)
+        { CI=CI+ideal(var(j)^d);
+        }
+        dB=dB+dif*(d-1);
+        P=Pplus;
+      }
+      if (ncols(P)==i)
+      { "WARNING: The first return value is not a set of primary invariants,";
+        "         but polynomials qualifying as the first ",i," primary invariants.";
+        return(matrix(P));
+      }
+      if (v)
+      { for (j=1;j<=dif;j++)
+        { "  We find: "+string(P[i+j]);
+        }
+      }
+      i=i+dif;
+      if (i==n)                        // found all primary invariants
+      { if (v)
+        { "";
+          "  We found all primary invariants.";
+          "";
+        }
+        if (deg_vector==0)
+        { return(matrix(P));
+        }
+        else
+        { return(matrix(P),compress(deg_vector));
+        }
+      }
+    }                                  // done with degree d
+    else
+    { if (v)
+      { "  None here...";
+      }
+    }
+  }
+}
+example
+{ "EXAMPLE: Sturmfels: Algorithms in Invariant Theory 2.3.7:"; echo=2;
+         ring R=0,(x,y,z),dp;
+         matrix A[3][3]=0,1,0,-1,0,0,0,0,-1;
+         list L=group_reynolds(A);
+         list l=primary_char0_no_molien_random(L[1],1);
+         print(l[1]);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc primary_charp_no_molien_random (matrix REY, int max, list #)
+"USAGE:   primary_charp_no_molien_random(REY,r[,v]);
+         REY: a <matrix> representing the Reynolds operator, r: an <int> where
+         -|r| to |r| is the range of coefficients of the random combinations of
+         bases elements, v: an optional <int>
+ASSUME:  REY is the first return value of group_reynolds or reynolds_molien
+DISPLAY: information about the various stages of the programme if v does not
+         equal 0
+RETURN:  primary invariants (type <matrix>) of the invariant ring  and an
+         <intvec> listing some of the degrees where no non-trivial homogeneous
+         invariants are to be found
+THEORY:  Bases of homogeneous invariants are generated successively and random
+         linear combinations are chosen as primary invariants that lower the
+         dimension of the ideal generated by the previously found invariants
+         (see \"Generating a Noetherian Normalization of the Invariant Ring of
+         a Finite Group\" by Decker, Heydtmann, Schreyer (1998)).
+EXAMPLE: example primary_charp_no_molien_random; shows an example
+"
+{ degBound=0;
+ //----------------- checking input and setting verbose mode ------------------
+  if (char(basering)==0)
+  { "ERROR:   primary_charp_no_molien_random should only be used with rings of";
+    "         characteristic p>0.";
+    return();
+  }
+  if (size(#)>1)
+  { "ERROR:   primary_charp_no_molien_random can only have three parameters.";
+    return();
+  }
+  if (size(#)==1)
+  { if (typeof(#[1])<>"int")
+    { "ERROR:   The third parameter should be of type <int>.";
+      return();
+    }
+    else
+    { int v=#[1];
+    }
+  }
+  else
+  { int v=0;
+  }
+  int n=nvars(basering);               // n is the number of variables, as well
+                                       // as the size of the matrices, as well
+                                       // as the number of primary invariants,
+                                       // we should get
+  if (ncols(REY)<>n)
+  { "ERROR:   First parameter ought to be the Reynolds operator."
+    return();
+  }
+ //----------------------------------------------------------------------------
+  if (v && voice<>2)
+  { "  We can start looking for primary invariants...";
+    "";
+  }
+  if (v && voice==2)
+  { "";
+  }
+ //-------------------- initializing variables --------------------------------
+  int dB;
+  int j,d,cd,newdim,dif;               // d: current degree, cd: dimension of
+                                       // space of invariants of degree d,
+                                       // newdim: dimension the ideal generated
+                                       // the primary invariants plus basis
+                                       // elements, dif=n-i-newdim, i.e. the
+                                       // number of new primary invairants that
+                                       // should be added in this degree -
+  ideal P,Pplus,CI,B;                  // P: will contain primary invariants,
+                                       // Pplus: P+B, CI: a complete
+                                       // intersection with the same Hilbert
+                                       // function as P -
+  dB=1;                                // used as degree bound -
+  d=0;                                 // initializing
+  int i=0;
+  intvec deg_vector;
+ //------------------ loop that searches for primary invariants ---------------
+  while(1)                             // repeat until n primary invariants are
+  {                                    // found -
+    d++;                               // degree where we'll search
+    if (v)
+    { "  Computing primary invariants in degree ",d,":";
+    }
+    B=invariant_basis_reynolds(REY,d,intvec(-1,6)); // basis of invariants of
+                                       // degree d
+    if (B[1]<>0)
+    { Pplus=P+B;
+      newdim=dim(groebner(Pplus));
+      dif=n-i-newdim;
+    }
+    else
+    { dif=0;
+      deg_vector=deg_vector,d;
+    }
+    if (dif<>0)                        // we have to find dif new primary
+    {                                  // invariants
+      cd=size(B);
+      if (cd<>dif)
+      { P,CI,dB=p_search_random(n,d,B,cd,P,i,dif,dB,CI,max);
+      }
+      else                             // i.e. we can take all of B
+      { for(j=i+1;j<=i+dif;j++)
+        { CI=CI+ideal(var(j)^d);
+        }
+        dB=dB+dif*(d-1);
+        P=Pplus;
+      }
+      if (ncols(P)==n+1)
+      { "WARNING: The first return value is not a set of primary invariants,";
+        "         but polynomials qualifying as the first ",i," primary invariants.";
+        return(matrix(P));
+      }
+      if (v)
+      { for (j=1;j<=size(P)-i;j++)
+        { "  We find: "+string(P[i+j]);
+        }
+      }
+      i=size(P);
+      if (i==n)                        // found all primary invariants
+      { if (v)
+        { "";
+          "  We found all primary invariants.";
+          "";
+        }
+        if (deg_vector==0)
+        { return(matrix(P));
+        }
+        else
+        { return(matrix(P),compress(deg_vector));
+        }
+      }
+    }                                  // done with degree d
+    else
+    { if (v)
+      { "  None here...";
+      }
+    }
+  }
+}
+example
+{ "EXAMPLE: Sturmfels: Algorithms in Invariant Theory 2.3.7 (changed into char 3)"; echo=2;
+         ring R=3,(x,y,z),dp;
+         matrix A[3][3]=0,1,0,-1,0,0,0,0,-1;
+         list L=group_reynolds(A);
+         list l=primary_charp_no_molien_random(L[1],1);
+         print(l[1]);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc primary_charp_without_random (list #)
+"USAGE:   primary_charp_without_random(G1,G2,...,r[,v]);
+         G1,G2,...: <matrices> generating a finite matrix group, r: an <int>
+         where -|r| to |r| is the range of coefficients of the random
+         combinations of bases elements, v: an optional <int>
+DISPLAY: information about the various stages of the programme if v does not
+         equal 0
+RETURN:  primary invariants (type <matrix>) of the invariant ring
+THEORY:  Bases of homogeneous invariants are generated successively and random
+         linear combinations are chosen as primary invariants that lower the
+         dimension of the ideal generated by the previously found invariants
+         (see \"Generating a Noetherian Normalization of the Invariant Ring of
+         a Finite Group\" by Decker, Heydtmann, Schreyer (1998)). No Reynolds
+         operator or Molien series is used.
+EXAMPLE: example primary_charp_without_random; shows an example
+"
+{ degBound=0;
+ //--------------------- checking input and setting verbose mode --------------
+  if (char(basering)==0)
+  { "ERROR:   primary_charp_without_random should only be used with rings of";
+    "         characteristic 0.";
+    return();
+  }
+  if (size(#)<2)
+  { "ERROR:   There are too few parameters.";
+    return();
+  }
+  if (typeof(#[size(#)])=="int" && typeof(#[size(#)-1])=="int")
+  { int v=#[size(#)];
+    int max=#[size(#)-1];
+    int gen_num=size(#)-2;
+    if (gen_num==0)
+    { "ERROR:   There are no generators of a finite matrix group given.";
+      return();
+    }
+  }
+  else
+  { if (typeof(#[size(#)])=="int")
+    { int max=#[size(#)];
+      int v=0;
+      int gen_num=size(#)-1;
+    }
+    else
+    { "ERROR:   The last parameter should be an <int>.";
+      return();
+    }
+  }
+  int n=nvars(basering);               // n is the number of variables, as well
+                                       // as the size of the matrices, as well
+                                       // as the number of primary invariants,
+                                       // we should get
+  for (int i=1;i<=gen_num;i++)
+  { if (typeof(#[i])=="matrix")
+    { if (nrows(#[i])<>n or ncols(#[i])<>n)
+      { "ERROR:   The number of variables of the base ring needs to be the same";
+        "         as the dimension of the square matrices";
+        return();
+      }
+    }
+    else
+    { "ERROR:   The first parameters should be a list of matrices";
+      return();
+    }
+  }
+ //----------------------------------------------------------------------------
+  if (v && voice==2)
+  { "";
+  }
+ //---------------------------- initializing variables ------------------------
+  int dB;
+  int j,d,cd,newdim,dif;               // d: current degree, cd: dimension of
+                                       // space of invariants of degree d,
+                                       // newdim: dimension the ideal generated
+                                       // the primary invariants plus basis
+                                       // elements, dif=n-i-newdim, i.e. the
+                                       // number of new primary invairants that
+                                       // should be added in this degree -
+  ideal P,Pplus,CI,B;                  // P: will contain primary invariants,
+                                       // Pplus: P+B, CI: a complete
+                                       // intersection with the same Hilbert
+                                       // function as P -
+  dB=1;                                // used as degree bound -
+  d=0;                                 // initializing
+  i=0;
+  intvec deg_vector;
+ //-------------------- loop that searches for primary invariants -------------
+  while(1)                             // repeat until n primary invariants are
+  {                                    // found -
+    d++;                               // degree where we'll search
+    if (v)
+    { "  Computing primary invariants in degree ",d,":";
+    }
+    B=invariant_basis(d,#[1..gen_num]); // basis of invariants of degree d
+    if (B[1]<>0)
+    { Pplus=P+B;
+      newdim=dim(groebner(Pplus));
+      dif=n-i-newdim;
+    }
+    else
+    { dif=0;
+      deg_vector=deg_vector,d;
+    }
+    if (dif<>0)                        // we have to find dif new primary
+    {                                  // invariants
+      cd=size(B);
+      if (cd<>dif)
+      { P,CI,dB=p_search_random(n,d,B,cd,P,i,dif,dB,CI,max);
+      }
+      else                             // i.e. we can take all of B
+      { for(j=i+1;j<=i+dif;j++)
+        { CI=CI+ideal(var(j)^d);
+        }
+        dB=dB+dif*(d-1);
+        P=Pplus;
+      }
+      if (ncols(P)==n+1)
+      { "WARNING: The first return value is not a set of primary invariants,";
+        "         but polynomials qualifying as the first ",i," primary invariants.";
+        return(matrix(P));
+      }
+      if (v)
+      { for (j=1;j<=size(P)-i;j++)
+        { "  We find: "+string(P[i+j]);
+        }
+      }
+      i=size(P);
+      if (i==n)                        // found all primary invariants
+      { if (v)
+        { "";
+          "  We found all primary invariants.";
+          "";
+        }
+        return(matrix(P));
+      }
+    }                                  // done with degree d
+    else
+    { if (v)
+      { "  None here...";
+      }
+    }
+  }
+}
+example
+{ "EXAMPLE:"; echo=2;
+         ring R=2,(x,y,z),dp;
+         matrix A[3][3]=0,1,0,-1,0,0,0,0,-1;
+         matrix P=primary_charp_without_random(A,1);
+         print(P);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc primary_invariants_random (list #)
+"USAGE:   primary_invariants_random(G1,G2,...,r[,flags]);
+         G1,G2,...: <matrices> generating a finite matrix group, r: an <int>
+         where -|r| to |r| is the range of coefficients of the random
+         combinations of bases elements, flags: an optional <intvec> with three
+         entries, if the first one equals 0 (also the default), the programme
+         attempts to compute the Molien series and Reynolds operator, if it
+         equals 1, the programme is told that the Molien series should not be
+         computed, if it equals -1 characteristic 0 is simulated, i.e. the
+         Molien series is computed as if the base field were characteristic 0
+         (the user must choose a field of large prime characteristic, e.g.
+         32003) and if the first one is anything else, it means that the
+         characteristic of the base field divides the group order, the second
+         component should give the size of intervals between canceling common
+         factors in the expansion of the Molien series, 0 (the default) means
+         only once after generating all terms, in prime characteristic also a
+         negative number can be given to indicate that common factors should
+         always be canceled when the expansion is simple (the root of the
+         extension field does not occur among the coefficients)
+DISPLAY: information about the various stages of the programme if the third
+         flag does not equal 0
+RETURN:  primary invariants (type <matrix>) of the invariant ring and if
+         computable Reynolds operator (type <matrix>) and Molien series (type
+         <matrix>), if the first flag is 1 and we are in the non-modular case
+         then an <intvec> is returned giving some of the degrees where no
+         non-trivial homogeneous invariants can be found
+THEORY:  Bases of homogeneous invariants are generated successively and random
+         linear combinations are chosen as primary invariants that lower the
+         dimension of the ideal generated by the previously found invariants
+         (see \"Generating a Noetherian Normalization of the Invariant Ring of
+         a Finite Group\" by Decker, Heydtmann, Schreyer (1998)).
+EXAMPLE: example primary_invariants_random; shows an example
+"
+{
+ // ----------------- checking input and setting flags ------------------------
+  if (size(#)<2)
+  { "ERROR:   There are too few parameters.";
+    return();
+  }
+  int ch=char(basering);               // the algorithms depend very much on the
+                                       // characteristic of the ground field
+  int n=nvars(basering);               // n is the number of variables, as well
+                                       // as the size of the matrices, as well
+                                       // as the number of primary invariants,
+                                       // we should get
+  int gen_num;
+  int mol_flag,v;
+  if (typeof(#[size(#)])=="intvec" && typeof(#[size(#)-1])=="int")
+  { if (size(#[size(#)])<>3)
+    { "ERROR:   <intvec> should have three entries.";
+      return();
+    }
+    gen_num=size(#)-2;
+    mol_flag=#[size(#)][1];
+    if (#[size(#)][2]<0 && (ch==0 or (ch<>0 && mol_flag<>0)))
+    { "ERROR:   the second component of <intvec> should be >=0";
+      return();
+    }
+    int interval=#[size(#)][2];
+    v=#[size(#)][3];
+    int max=#[size(#)-1];
+    if (gen_num==0)
+    { "ERROR:   There are no generators of a finite matrix group given.";
+      return();
+    }
+  }
+  else
+  { if (typeof(#[size(#)])=="int")
+    { gen_num=size(#)-1;
+      mol_flag=0;
+      int interval=0;
+      v=0;
+      int max=#[size(#)];
+    }
+    else
+    { "ERROR:   If the two last parameters are not <int> and <intvec>, the last";
+      "         parameter should be an <int>.";
+      return();
+    }
+  }
+  for (int i=1;i<=gen_num;i++)
+  { if (typeof(#[i])=="matrix")
+    { if (nrows(#[i])<>n or ncols(#[i])<>n)
+      { "ERROR:   The number of variables of the base ring needs to be the same";
+        "         as the dimension of the square matrices";
+        return();
+      }
+    }
+    else
+    { "ERROR:   The first parameters should be a list of matrices";
+      return();
+    }
+  }
+ //----------------------------------------------------------------------------
+  if (mol_flag==0)
+  { if (ch==0)
+    { matrix REY,M=reynolds_molien(#[1..gen_num],intvec(0,interval,v));
+                                       // one will contain Reynolds operator and
+                                       // the other enumerator and denominator
+                                       // of Molien series
+      matrix P=primary_char0_random(REY,M,max,v);
+      return(P,REY,M);
+    }
+    else
+    { list L=group_reynolds(#[1..gen_num],v);
+      if (L[1]<>0)                     // testing whether we are in the modular
+      { string newring="aksldfalkdsflkj"; // case
+        if (minpoly==0)
+        { if (v)
+          { "  We are dealing with the non-modular case.";
+          }
+          if (typeof(L[2])=="int")
+          { molien(L[3..size(L)],newring,L[2],intvec(0,interval,v));
+          }
+          else
+          { molien(L[2..size(L)],newring,intvec(0,interval,v));
+          }
+          matrix P=primary_charp_random(L[1],newring,max,v);
+          return(P,L[1],newring);
+        }
+        else
+        { if (v)
+          { "  Since it is impossible for this programme to calculate the Molien series for";
+            "  invariant rings over extension fields of prime characteristic, we have to";
+            "  continue without it.";
+            "";
+
+          }
+          list l=primary_charp_no_molien_random(L[1],max,v);
+          if (size(l)==2)
+          { return(l[1],L[1],l[2]);
+          }
+          else
+          { return(l[1],L[1]);
+          }
+        }
+      }
+      else                             // the modular case
+      { if (v)
+        { "  There is also no Molien series, we can make use of...";
+          "";
+          "  We can start looking for primary invariants...";
+          "";
+        }
+        return(primary_charp_without_random(#[1..gen_num],max,v));
+      }
+    }
+  }
+  if (mol_flag==1)                     // the user wants no calculation of the
+  { list L=group_reynolds(#[1..gen_num],v); // Molien series
+    if (ch==0)
+    { list l=primary_char0_no_molien_random(L[1],max,v);
+      if (size(l)==2)
+      { return(l[1],L[1],l[2]);
+      }
+      else
+      { return(l[1],L[1]);
+      }
+    }
+    else
+    { if (L[1]<>0)                     // testing whether we are in the modular
+      { list l=primary_charp_no_molien_random(L[1],max,v); // case
+        if (size(l)==2)
+        { return(l[1],L[1],l[2]);
+        }
+        else
+        { return(l[1],L[1]);
+        }
+      }
+      else                             // the modular case
+      { if (v)
+        { "  We can start looking for primary invariants...";
+          "";
+        }
+        return(primary_charp_without_random(#[1..gen_num],max,v));
+      }
+    }
+  }
+  if (mol_flag==-1)
+  { if (ch==0)
+    { "ERROR:   Characteristic 0 can only be simulated in characteristic p>>0.";
+      return();
+    }
+    list L=group_reynolds(#[1..gen_num],v);
+    string newring="aksldfalkdsflkj";
+    if (typeof(L[2])=="int")
+    { molien(L[3..size(L)],newring,L[2],intvec(0,interval,v));
+    }
+    else
+    { molien(L[2..size(L)],newring,intvec(0,interval,v));
+    }
+    matrix P=primary_charp_random(L[1],newring,max,v);
+    return(P,L[1],newring);
+  }
+  else                                 // the user specified that the
+  { if (ch==0)                         // characteristic divides the group order
+    { "ERROR:   The characteristic cannot divide the group order when it is 0.";
+      return();
+    }
+    if (v)
+    { "";
+    }
+    return(primary_charp_without_random(#[1..gen_num],max,v));
+  }
+}
+example
+{ "EXAMPLE: Sturmfels: Algorithms in Invariant Theory 2.3.7:"; echo=2;
+         ring R=0,(x,y,z),dp;
+         matrix A[3][3]=0,1,0,-1,0,0,0,0,-1;
+         list L=primary_invariants_random(A,1);
+         print(L[1]);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc concat_intmat(intmat A,intmat B)
+{ int n=nrows(A);
+  int m1=ncols(A);
+  int m2=ncols(B);
+  intmat C[n][m1+m2];
+  C[1..n,1..m1]=A[1..n,1..m1];
+  C[1..n,m1+1..m1+m2]=B[1..n,1..m2];
+  return(C);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc power_products(intvec deg_vec,int d)
+"USAGE:   power_products(dv,d);
+         dv: an <intvec> giving the degrees of homogeneous polynomials, d: the
+         degree of the desired power products
+RETURN:  a size(dv)*m <intmat> where each column ought to be interpreted as
+         containing the exponents of the corresponding polynomials. The product
+         of the powers is then homogeneous of degree d.
+EXAMPLE: example power_products; shows an example
+"
+{ ring R=0,x,dp;
+  if (d<=0)
+  { "ERROR:   The <int> may not be <= 0";
+    return();
+  }
+  int d_neu,j,nc;
+  int s=size(deg_vec);
+  intmat PP[s][1];
+  intmat TEST[s][1];
+  for (int i=1;i<=s;i++)
+  { if (i<0)
+    { "ERROR:   The entries of <intvec> may not be <= 0";
+      return();
+    }
+    d_neu=d-deg_vec[i];
+    if (d_neu>0)
+    { intmat PPd_neu=power_products(intvec(deg_vec[i..s]),d_neu);
+      if (size(ideal(PPd_neu))<>0)
+      { nc=ncols(PPd_neu);
+        intmat PPd_neu_gross[s][nc];
+        PPd_neu_gross[i..s,1..nc]=PPd_neu[1..s-i+1,1..nc];
+        for (j=1;j<=nc;j++)
+        { PPd_neu_gross[i,j]=PPd_neu_gross[i,j]+1;
+        }
+        PP=concat_intmat(PP,PPd_neu_gross);
+        kill PPd_neu_gross;
+      }
+      kill PPd_neu;
+    }
+    if (d_neu==0)
+    { intmat PPd_neu[s][1];
+      PPd_neu[i,1]=1;
+      PP=concat_intmat(PP,PPd_neu);
+      kill PPd_neu;
+    }
+  }
+  if (matrix(PP)<>matrix(TEST))
+  { PP=compress(PP);
+  }
+  return(PP);
+}
+example
+{ "EXAMPLE:"; echo=2;
+         intvec dv=5,5,5,10,10;
+         print(power_products(dv,10));
+         print(power_products(dv,7));
+}
+///////////////////////////////////////////////////////////////////////////////
+
+static proc old_secondary_char0 (matrix P, matrix REY, matrix M, list #)
+"USAGE:   secondary_char0(P,REY,M[,v]);
+         P: a 1xn <matrix> with primary invariants,
+         REY: a gxn <matrix> representing the Reynolds operator,
+         M: a 1x2 <matrix> giving numerator and denominator of the Molien series,
+         v: an optional <int>
+ASSUME:  n is the number of variables of the basering, g the size of the group,
+         REY is the 1st return value of group_reynolds(), reynolds_molien() or
+         the second one of primary_invariants(), M the return value of molien()
+         or the second one of reynolds_molien() or the third one of
+         primary_invariants()
+RETURN:  secondary invariants of the invariant ring (type <matrix>) and
+         irreducible secondary invariants (type <matrix>)
+DISPLAY: information if v does not equal 0
+THEORY:  The secondary invariants are calculated by finding a basis (in terms
+         of monomials) of the basering modulo the primary invariants, mapping
+         those to invariants with the Reynolds operator and using these images
+         or their power products such that they are linearly independent modulo
+         the primary invariants (see paper \"Some Algorithms in Invariant
+         Theory of Finite Groups\" by Kemper and Steel (1997)).
+"
+{ def br=basering;
+  degBound=0;
+ //----------------- checking input and setting verbose mode ------------------
+  if (char(br)<>0)
+  { "ERROR:   secondary_char0 should only be used with rings of characteristic 0.";
+    return();
+  }
+  int i;
+  if (size(#)>0)
+  { if (typeof(#[size(#)])=="int")
+    { int v=#[size(#)];
+    }
+    else
+    { int v=0;
+    }
+  }
+  else
+  { int v=0;
+  }
+  int n=nvars(br);                     // n is the number of variables, as well
+                                       // as the size of the matrices, as well
+                                       // as the number of primary invariants,
+                                       // we should get
+  if (ncols(P)<>n)
+  { "ERROR:   The first parameter ought to be the matrix of the primary";
+    "         invariants."
+    return();
+  }
+  if (ncols(REY)<>n)
+  { "ERROR:   The second parameter ought to be the Reynolds operator."
+    return();
+  }
+  if (ncols(M)<>2 or nrows(M)<>1)
+  { "ERROR:   The third parameter ought to be the Molien series."
+    return();
+  }
+  if (v && voice==2)
+  { "";
+  }
+  int j, m, counter;
+ //- finding the polynomial giving number and degrees of secondary invariants -
+  poly p=1;
+  for (j=1;j<=n;j++)                   // calculating the denominator of the
+  { p=p*(1-var(1)^deg(P[j]));          // Hilbert series of the ring generated
+  }                                    // by the primary invariants -
+  matrix s[1][2]=M[1,1]*p,M[1,2];      // s is used for canceling
+  s=matrix(syz(ideal(s)));
+  p=s[2,1];                            // the polynomial telling us where to
+                                       // search for secondary invariants
+  map slead=br,ideal(0);
+  p=1/slead(p)*p;                      // smallest term of p needs to be 1
+  if (v)
+  { "  Polynomial telling us where to look for secondary invariants:";
+    "   "+string(p);
+    "";
+  }
+  matrix dimmat=coeffs(p,var(1));      // dimmat will contain the number of
+                                       // secondary invariants, we need to find
+                                       // of a certain degree -
+  m=nrows(dimmat);                     // m-1 is the highest degree
+  if (v)
+  { "In degree 0 we have: 1";
+    "";
+  }
+ //-------------------------- initializing variables --------------------------
+  intmat PP;
+  poly pp;
+  int k;
+  intvec deg_vec;
+  ideal sP=groebner(ideal(P));
+  ideal TEST,B,IS;
+  ideal S=1;                           // 1 is the first secondary invariant -
+ //--------------------- generating secondary invariants ----------------------
+  for (i=2;i<=m;i++)                   // going through dimmat -
+  { if (int(dimmat[i,1])<>0)           // when it is == 0 we need to find 0
+    {                                  // elements in the current degree (i-1)
+      if (v)
+      { "Searching in degree ",i-1,", we need to find ",int(dimmat[i,1])," invariant(s)...";
+      }
+      TEST=sP;
+      counter=0;                       // we'll count up to degvec[i]
+      if (IS[1]<>0)
+      { PP=power_products(deg_vec,i-1); // finding power products of irreducible
+      }                                // secondary invariants
+      if (size(ideal(PP))<>0)
+      { for (j=1;j<=ncols(PP);j++)     // going through all the power products
+        { pp=1;
+          for (k=1;k<=nrows(PP);k++)
+          { pp=pp*IS[1,k]^PP[k,j];
+          }
+          if (reduce(pp,TEST)<>0)
+          { S=S,pp;
+            counter++;
+            if (v)
+            { "  We find: "+string(pp);
+            }
+            if (int(dimmat[i,1])<>counter)
+            { // TEST=std(TEST+ideal(NF(pp,TEST))); // should be replaced by next
+                                                 // line soon
+              TEST=std(TEST,pp);
+            }
+            else
+            { break;
+            }
+          }
+        }
+      }
+      if (int(dimmat[i,1])<>counter)
+      { B=sort_of_invariant_basis(sP,REY,i-1,int(dimmat[i,1])*6); // B contains
+                                       // images of kbase(sP,i-1) under the
+                                       // Reynolds operator that are linearly
+                                       // independent and that don't reduce to
+                                       // 0 modulo sP -
+        if (counter==0 && ncols(B)==int(dimmat[i,1])) // then we can take all of
+        { S=S,B;                       // B
+          IS=IS+B;
+          if (deg_vec[1]==0)
+          { deg_vec=i-1;
+            if (v)
+            { "  We find: "+string(B[1]);
+            }
+            for (j=2;j<=int(dimmat[i,1]);j++)
+            { deg_vec=deg_vec,i-1;
+              if (v)
+              { "  We find: "+string(B[j]);
+              }
+            }
+          }
+          else
+          { for (j=1;j<=int(dimmat[i,1]);j++)
+            { deg_vec=deg_vec,i-1;
+              if (v)
+              { "  We find: "+string(B[j]);
+              }
+            }
+          }
+        }
+        else
+        { j=0;                         // j goes through all of B -
+          while (int(dimmat[i,1])<>counter) // need to find dimmat[i,1]
+          {                            // invariants that are linearly
+                                       // independent modulo TEST
+            j++;
+            if (reduce(B[j],TEST)<>0)  // B[j] should be added
+            { S=S,B[j];
+              IS=IS+ideal(B[j]);
+              if (deg_vec[1]==0)
+              { deg_vec[1]=i-1;
+              }
+              else
+              { deg_vec=deg_vec,i-1;
+              }
+              counter++;
+              if (v)
+              { "  We find: "+string(B[j]);
+              }
+              if (int(dimmat[i,1])<>counter)
+              { //TEST=std(TEST+ideal(NF(B[j],TEST))); // should be replaced by
+                                                     // next line
+                TEST=std(TEST,B[j]);
+              }
+            }
+          }
+        }
+      }
+      if (v)
+      { "";
+      }
+    }
+  }
+  if (v)
+  { "  We're done!";
+    "";
+  }
+  return(matrix(S),matrix(IS));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+
+proc secondary_char0 (matrix P, matrix REY, matrix M, list #)
+"USAGE:    secondary_char0(P,REY,M[,v][,\"old\"]);
+@*          P: a 1xn <matrix> with homogeneous primary invariants, where
+               n is the number of variables of the basering;
+@*          REY: a gxn <matrix> representing the Reynolds operator, where
+               g the size of the corresponding group;
+@*          M: a 1x2 <matrix> giving numerator and denominator of the Molien
+               series;
+@*          v: an optional <int>;
+@*          \"old\": if this string occurs as (optional) parameter, then an
+               old version of secondary_char0 is used (for downward
+               compatibility)
+ASSUME:   The characteristic of basering is zero;
+          REY is the 1st return value of group_reynolds(), reynolds_molien() or
+          the second one of primary_invariants();
+@*        M is the return value of molien()
+          or the second one of reynolds_molien() or the third one of
+          primary_invariants()
+RETURN:   Homogeneous secondary invariants and irreducible secondary
+          invariants of the invariant ring (both type <matrix>)
+DISPLAY:  Information on the progress of the computations if v is an integer
+          different from 0.
+THEORY:   The secondary invariants are calculated by finding a basis (in terms
+          of monomials) of the basering modulo the primary invariants, mapping
+          those to invariants with the Reynolds operator. Among these images
+          or their power products we pick secondary invariants using Groebner
+          basis techniques (see S. King: Fast Computation of Secondary
+          Invariants).
+          The size of this set can be read off from the Molien series.
+NOTE:     Secondary invariants are not uniquely determined by the given data.
+          Specifically, the output of secondary_char0(P,REY,M,\"old\") will
+          differ from the output of secondary_char0(P,REY,M). However, the
+          ideal generated by the irreducible homogeneous
+          secondary invariants will be the same in both cases.
+@*        There are three internal parameters \"pieces\", \"MonStep\" and \"IrrSwitch\".
+          The default values of the parameters should be fine in most cases. However,
+          in some cases, different values may provide a better balance of memory
+          consumption (smaller values) and speed (bigger values).
+SEE ALSO: irred_secondary_char0;
+EXAMPLE:  example secondary_char0; shows an example
+"
+{
+ //----------  Internal parameters, whose choice might improve the performance -----
+  int pieces = 3;   // For generating reducible secondaries, blocks of #pieces# secondaries
+                     // are formed.
+                     // If this parameter is small, the memory consumption will decrease.
+  int MonStep = 15;  // The Reynolds operator is applied to blocks of #MonStep# monomials.
+                     // If this parameter is small, the memory consumption will decrease.
+  int IrrSwitch = 7; // Up to degree #IrrSwitch#-1, we use a method for generating
+                     // irreducible secondaries that tends to produce a smaller output
+                     // (which is good for subsequent computations). However, this method
+                     // needs to much memory in high degrees, and so we use a sparser method
+                     // from degree #IrrSwitch# on.
+
+  def br=basering;
+
+ //----------------- checking input and setting verbose mode ------------------
+  if (char(br)<>0)
+  { "ERROR:   secondary_char0 can only be used with rings of characteristic 0.";
+    "         Try secondary_charp";
+      return();
+  }
+  int i;
+  if (size(#)>0)
+  { if (typeof(#[1])=="int")
+    { int v=#[1];
+    }
+    else
+    { int v=0;
+    }
+  }
+  else
+  { int v=0;
+  }
+  if (size(#)>0)
+  { if (typeof(#[size(#)])=="string")
+    { if (#[size(#)]=="old")
+      { if (typeof(#[1])=="int")
+        { matrix S,IS = old_secondary_char0(P,REY,M,#[1]);
+          return(S,IS);
+        }
+        else
+        { matrix S,IS = old_secondary_char0(P,REY,M);
+          return(S,IS);
+        }
+      }
+      else
+      { "ERROR:   If the last optional parameter is a string, it should be \"old\".";
+        return(matrix(ideal()),matrix(ideal()));
+      }
+    }
+  }
+  int n=nvars(br);                // n is the number of variables, as well
+                                  // as the size of the matrices, as well
+                                  // as the number of primary invariants,
+                                  // we should get
+  if (ncols(P)<>n)
+  { "ERROR:   The first parameter ought to be the matrix of the primary";
+    "         invariants.";
+    return();
+  }
+  if (ncols(REY)<>n)
+  { "ERROR:   The second parameter ought to be the Reynolds operator.";
+    return();
+  }
+  if (ncols(M)<>2 or nrows(M)<>1)
+  { "ERROR:   The third parameter ought to be the Molien series.";
+    return();
+  }
+  if (v && voice==2)
+  { "";
+  }
+  int j, m, counter, irrcounter;
+ //- finding the polynomial giving number and degrees of secondary invariants -
+  poly p=1;
+  for (j=1;j<=n;j++)                   // calculating the denominator of the
+  { p=p*(1-var(1)^deg(P[j]));          // Hilbert series of the ring generated
+  }                                    // by the primary invariants -
+  matrix s[1][2]=M[1,1]*p,M[1,2];      // s is used for canceling
+  s=matrix(syz(ideal(s)));
+  p=s[2,1];                            // the polynomial telling us where to
+                                       // search for secondary invariants
+  map slead=br,ideal(0);
+  p=1/slead(p)*p;                      // smallest [constant] term of
+                                       // p needs to be 1
+  matrix dimmat=coeffs(p,var(1));      // dimmat will contain the number of
+                                       // secondary invariants, we need to find
+                                       // of a certain degree -
+  m=nrows(dimmat);                     // m-1 is the highest degree
+  if (v)
+  { "We need to find";
+    for (j=1;j<=m;j++)
+     { if (int(dimmat[j,1])<>1)
+       { int(dimmat[j,1]), "secondary invariants in degree",j-1;
+       }
+       else
+       { "1 secondary invariant in degree",j-1;
+       }
+     }
+  }
+  if (v)
+  { "In degree 0 we have: 1";
+    "";
+  }
+ //-------------------------- initializing variables --------------------------
+  ideal ProdCand;          // contains products of secondary invariants,
+                           // i.e., candidates for reducible sec. inv.
+  ideal Mul1,Mul2;
+
+  int dgb=degBound;
+  degBound = 0;
+  intvec saveopt=option(get);
+  option(redSB);
+  ideal sP = groebner(ideal(P));
+                           // This is the only explicit Groebner basis computation!
+  ideal Reductor,SaveRed;  // sP union Reductor is a Groebner basis up to degree i-1
+  ideal sP_Reductor;          // will contain sP union Reductor.
+  int sPOffset = ncols(sP);
+  int SizeSave;
+
+  list SSort;         // sec. inv. first sorted by degree and then sorted by the
+                      // minimal degree of a non-constant invariant factor.
+  list ISSort;        // irr. sec. inv. sorted by degree
+  int NrIS;
+  poly helpP;
+  ideal helpI;
+  ideal Indicator;        // will tell us which candidates for sec. inv. we can choose
+  int helpint;
+  int k,k2,k3,minD;
+  int ii;
+  int saveAttr;
+  ideal mon,B,IS;              // IS will contain all irr. sec. inv.
+
+  for (i=1;i<m;i++)
+  { SSort[i] = list();
+    for (k=1;k<=i;k++)
+    { SSort[i][k]=ideal();
+      attrib(SSort[i][k],"size",0);
+    }
+  }
+//--------------------- generating secondary invariants ----------------------
+  for (i=2;i<=m;i++)                   // going through dimmat -
+  { if (int(dimmat[i,1])<>0)           // when it is == 0 we need to find no
+    {                                  // elements in the current degree (i-1)
+      if (v)
+      { "Searching in degree ",i-1,", we need to find ",int(dimmat[i,1]),
+        " invariant(s)...";
+        "  Looking for Power Products...";
+      }
+      sP_Reductor = sP;
+      counter = 0;                       // we'll count up to dimmat[i,1]
+      Reductor = ideal(0);
+      helpint = 0;
+      SaveRed = Reductor;
+      SizeSave = 0;
+      attrib(Reductor,"isSB",1);
+      attrib(SaveRed,"isSB",1);
+
+// We start searching for reducible secondary invariants in degree i-1, i.e., those
+// that are power products of irreducible secondary invariants.
+// It suffices to restrict the search at products of one _irreducible_ sec. inv. (Mul1)
+// with some sec. inv. (Mul2).
+// Moreover, we avoid to consider power products twice since we take a product
+// into account only if the minimal degree of a non-constant invariant factor in "Mul2" is not
+// smaller than the degree of "Mul1".
+      for (k=1;k<i-1;k++)
+      { if (int(dimmat[i,1])==counter)
+        { break;
+        }
+        if (typeof(ISSort[k])<>"none")
+        { Mul1 = ISSort[k];
+        }
+        else
+        { Mul1 = ideal(0);
+        }
+        if ((int(dimmat[i-k,1])>0) && (Mul1[1]<>0))
+        { for (minD=k;minD<i-k;minD++)
+          { if (int(dimmat[i,1])==counter)
+            { break;
+            }
+            for (k2=1;k2 <= ((attrib(SSort[i-k-1][minD],"size")-1) div pieces)+1; k2++)
+            { if (int(dimmat[i,1])==counter)
+              { break;
+              }
+              Mul2=ideal(0);
+              if (attrib(SSort[i-k-1][minD],"size")>=k2*pieces)
+              { for (k3=1;k3<=pieces;k3++)
+                { Mul2[k3] = SSort[i-k-1][minD][((k2-1)*pieces)+k3];
+                }
+              }
+              else
+              { for (k3=1;k3<=(attrib(SSort[i-k-1][minD],"size") mod pieces);k3++)
+                { Mul2[k3] = SSort[i-k-1][minD][((k2-1)*pieces)+k3];
+                }
+              }
+              ProdCand = simplify(Mul1*Mul2,4);
+                  // sP union SaveRed union Reductor is a homogeneous Groebner basis
+                  // up to degree i-1.
+              Indicator = reduce(ProdCand,sP_Reductor);
+                             // If Indicator[ii]<>0 then ProdCand[ii] can be taken as secondary invariant.
+              if (size(Indicator)<>0)
+              { for (ii=1;ii<=ncols(ProdCand);ii++)     // going through all the power products
+                { helpP = Indicator[ii];
+                  if (helpP <> 0)
+                  { counter++;
+                    saveAttr = attrib(SSort[i-1][k],"size")+1;
+                    SSort[i-1][k][saveAttr] = ProdCand[ii];
+                        // By construction, this is a _reducible_ s.i.
+                    attrib(SSort[i-1][k],"size",saveAttr);
+                    if (v)
+                    { "    We found",counter, "of", int(dimmat[i,1]),"secondaries in degree",i-1;
+                    }
+                    if (int(dimmat[i,1])<>counter)
+                    { Reductor = ideal(helpP);
+                      attrib(Reductor, "isSB",1);
+                      Indicator=reduce(Indicator,Reductor);
+                      SizeSave++;
+                      SaveRed[SizeSave] = helpP;
+                      sP_Reductor[sPOffset+SizeSave] = helpP;
+                      attrib(sP_Reductor, "isSB",1);
+                        // Lemma: If G is a homogeneous Groebner basis up to degree i-1 and p is a
+                        // homogeneous polynomial of degree i-1 then G union NF(p,G) is
+                        // a homogeneous Groebner basis up to degree i-1. Hence, sP_Reductor
+                        // is a homog. GB up to degree i-1.
+                      attrib(SaveRed, "isSB",1);
+                      attrib(Reductor, "isSB",1);
+                    }
+                    else
+                    { break;
+                    }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+      NrIS = int(dimmat[i,1])-counter;
+      // The remaining NrIS sec. inv. are irreducible!
+      if (NrIS>0)   // need more than all the power products
+      { if (v)
+        { "  There are ",NrIS,"irreducible secondary invariants in degree ", i-1;
+        }
+        mon = kbase(sP_Reductor,i-1);
+        ii = ncols(mon);
+        if ((i>IrrSwitch) or (ii>200)) // use sparse algorithm
+        { if (ii+counter==int(dimmat[i,1])) // then we can use all of mon
+          { B=normalize(evaluate_reynolds(REY,mon));
+            IS=IS+B;
+            saveAttr = attrib(SSort[i-1][i-1],"size")+ii;
+            SSort[i-1][i-1] = SSort[i-1][i-1] + B;
+            attrib(SSort[i-1][i-1],"size", saveAttr);
+            if (typeof(ISSort[i-1]) <> "none")
+            { ISSort[i-1] = ISSort[i-1] + B;
+            }
+            else
+            { ISSort[i-1] = B;
+            }
+            if (v) {"    We found all",NrIS,"irreducibles in degree ",i-1;}
+          }
+          else
+          { irrcounter=0;
+            j=0;                         // j goes through all of mon -
+// Compare the comments on the computation of reducible sec. inv.!
+            while (counter <> int(dimmat[i,1]))
+            { if ((j mod MonStep) == 0)
+              { if ((j+MonStep) <= ii)
+                { ideal tmp = normalize(evaluate_reynolds(REY,ideal(mon[j+1..j+MonStep])));
+                  B[j+1..j+MonStep] = tmp[1..MonStep];
+                  tmp = reduce(tmp,sP_Reductor);
+                  Indicator[j+1..j+MonStep] = tmp[1..MonStep];
+                  kill tmp;
+                }
+                else
+                { ideal tmp = normalize(evaluate_reynolds(REY,ideal(mon[j+1..ii])));
+                  B[j+1..ii] = tmp[1..ii-j];
+                  tmp = reduce(tmp,sP_Reductor);
+                  Indicator[j+1..ii] = tmp[1..ii-j];
+                  kill tmp;
+                }
+              }
+              j++;
+              helpP = Indicator[j];
+              if (helpP <>0)                  // B[j] should be added
+              { counter++; irrcounter++;
+                IS=IS,B[j];
+                saveAttr = attrib(SSort[i-1][i-1],"size")+1;
+                SSort[i-1][i-1][saveAttr] = B[j];
+                attrib(SSort[i-1][i-1],"size",saveAttr);
+                if (typeof(ISSort[i-1]) <> "none")
+                { ISSort[i-1][irrcounter] = B[j];
+                }
+                else
+                { ISSort[i-1] = ideal(B[j]);
+                }
+                if (v)
+                { "    We found", irrcounter,"of", NrIS ,"irr. sec. inv. in degree ",i-1;
+                }
+                Reductor = ideal(helpP);
+                attrib(Reductor, "isSB",1);
+                Indicator=reduce(Indicator,Reductor);
+                SizeSave++;
+                SaveRed[SizeSave] = helpP;
+                attrib(SaveRed, "isSB",1);
+                sP_Reductor[sPOffset+SizeSave] = helpP;
+                attrib(sP_Reductor, "isSB",1);
+              }
+              B[j]=0;
+              Indicator[j]=0;
+            }
+          }
+        }  // if i>IrrSwitch
+        else  // use fast algorithm
+        { B=sort_of_invariant_basis(sP_Reductor,REY,i-1,int(dimmat[i,1])*6);
+                                       // B contains
+                                       // images of kbase(sP,i-1) under the
+                                       // Reynolds operator that are linearly
+                                       // independent
+          if (counter==0 && ncols(B)==int(dimmat[i,1])) // then we can take all of B
+          { IS=IS+B;
+            saveAttr = attrib(SSort[i-1][i-1],"size")+int(dimmat[i,1]);
+            SSort[i-1][i-1] = SSort[i-1][i-1] + B;
+            attrib(SSort[i-1][i-1],"size", saveAttr);
+            if (typeof(ISSort[i-1]) <> "none")
+            { ISSort[i-1] = ISSort[i-1] + B;
+            }
+            else
+            { ISSort[i-1] = B;
+            }
+            if (v) {"    We found all",NrIS,"irreducibles in degree ",i-1;}
+          }
+          else
+          { irrcounter=0;
+            j=0;                         // j goes through all of B -
+// Compare the comments on the computation of reducible sec. inv.!
+            Indicator = reduce(B,sP_Reductor);
+            while (int(dimmat[i,1])<>counter)
+            { j++;
+              helpP = Indicator[j];
+              if (helpP <>0)                  // B[j] should be added
+              { counter++; irrcounter++;
+                IS=IS,B[j];
+                saveAttr = attrib(SSort[i-1][i-1],"size")+1;
+                SSort[i-1][i-1][saveAttr] = B[j];
+                attrib(SSort[i-1][i-1],"size",saveAttr);
+                if (typeof(ISSort[i-1]) <> "none")
+                { ISSort[i-1][irrcounter] = B[j];
+                }
+                else
+                { ISSort[i-1] = ideal(B[j]);
+                }
+                if (v)
+                { "    We found", irrcounter,"of", NrIS,"irr. sec. inv. in degree ",i-1;
+                }
+                Reductor = ideal(helpP);
+                attrib(Reductor, "isSB",1);
+                Indicator=reduce(Indicator,Reductor);
+                SizeSave++;
+                SaveRed[SizeSave] = helpP;
+                attrib(SaveRed, "isSB",1);
+                sP_Reductor[sPOffset+SizeSave] = helpP;
+                attrib(sP_Reductor, "isSB",1);
+              }
+              B[j]=0;
+              Indicator[j]=0;
+            }
+          }
+        } // i<=IrrSwitch
+      } // Computation of irreducible secondaries
+      if (v)
+      { "";
+      }
+    } // if (int(dimmat[i,1])<>0)
+  }  // for i
+  if (v)
+  { "  We're done!";
+    "";
+  }
+  degBound = dgb;
+
+  // Prepare return:
+  int TotalNumber;
+  for (k=1;k<=m;k++)
+  { TotalNumber = TotalNumber + int(dimmat[k,1]);
+  }
+  matrix S[1][TotalNumber];
+  S[1,1]=1;
+  j=1;
+  for (k=1;k<m;k++)
+  { for (k2=1;k2<=k;k2++)
+    { if (typeof(attrib(SSort[k][k2],"size"))=="int")
+     {for (i=1;i<=attrib(SSort[k][k2],"size");i++)
+      { j++;
+        S[1,j] = SSort[k][k2][i];
+      }
+      SSort[k][k2]=ideal();
+     }
+    }
+  }
+  option(set,saveopt);
+  return(S,matrix(compress(IS)));
+}
+
+example
+{ "EXAMPLE: Sturmfels: Algorithms in Invariant Theory 2.3.7:"; echo=2;
+         ring R=0,(x,y,z),dp;
+         matrix A[3][3]=0,1,0,-1,0,0,0,0,-1;
+         list L=primary_invariants(A);
+         matrix S,IS=secondary_char0(L[1..3],1);
+         print(S);
+         print(IS);
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc irred_secondary_char0 (matrix P, matrix REY, matrix M, list #)
+"USAGE:    irred_secondary_char0(P,REY,M[,v][,\"PP\"]);
+@*          P: a 1xn <matrix> with homogeneous primary invariants, where
+               n is the number of variables of the basering;
+@*          REY: a gxn <matrix> representing the Reynolds operator, where
+               g the size of the corresponding group;
+@*          M: a 1x2 <matrix> giving numerator and denominator of the
+               Molien series;
+@*          v: an optional <int>;
+@*          \"PP\": if this string occurs as (optional) parameter, then in
+               all degrees power products of irr. sec. inv. will be computed.
+RETURN:   Irreducible homogeneous secondary invariants of the invariant ring
+          (type <matrix>)
+ASSUME:   We are in the non-modular case, i.e., the characteristic of the basering
+          does not divide the group order;
+          REY is the 1st return value of group_reynolds(), reynolds_molien() or
+          the second one of primary_invariants();
+          M is the return value of molien() or the second one of
+          reynolds_molien() or the third one of primary_invariants()
+DISPLAY:  Information on the progress of computations if v does not equal 0
+THEORY:   The secondary invariants are calculated by finding a basis (in terms
+          of monomials) of the basering modulo the primary invariants, mapping
+          those to invariants with the Reynolds operator. Among these images
+          or their power products we pick secondary invariants using Groebner
+          basis techniques (see S. King: Fast Computation of Secondary Invariants).
+          The size of this set can be read off from the Molien series. Here, only
+          irreducible secondary invariants are explicitly computed, which saves time and
+          memory.
+@*        Moreover, if no irr. sec. inv. in degree d-1 have been found and unless the last
+          optional paramter \"PP\" is used, a Groebner basis of primary invariants and
+          irreducible secondary invariants up to degree d-2 is computed, which allows to
+          detect irr. sec. inv. in degree d without computing power products.
+@*        There are three internal parameters \"pieces\", \"MonStep\" and \"IrrSwitch\".
+          The default values of the parameters should be fine in most cases. However,
+          in some cases, different values may provide a better balance of memory
+          consumption (smaller values) and speed (bigger values).
+SEE ALSO: secondary_char0
+KEYWORDS: irreducible secondary invariant
+EXAMPLE:  example irred_secondary_char0; shows an example
+"
+{ //----------  Internal parameters, whose choice might improve the performance -----
+  int pieces = 3;    // For generating reducible secondaries, blocks of #pieces# secondaries
+                     // are formed.
+                     // If this parameter is small, the memory consumption will decrease.
+  int MonStep = 15;  // The Reynolds operator is applied to blocks of #MonStep# monomials.
+                     // If this parameter is small, the memory consumption will decrease.
+  int IrrSwitch = 7; // Up to degree #IrrSwitch#-1, or if there are few monomials in kbase(sP,i-1),
+                     // we use a method for generating irreducible secondaries that tends to
+                     // produce a smaller output (which is good for subsequent computations).
+                     // However, this method needs to much memory in high degrees, and so we
+                     // use a sparser method from degree #IrrSwitch# upwards.
+  def br=basering;
+ //----------------- checking input and setting verbose mode ------------------
+  if (char(br)<>0)
+  { "ERROR:   irred_secondary_char0 can only be used with rings of characteristic 0.";
+    "         Try irred_secondary_charp";
+      return();
+  }
+  int i;
+  if (size(#)>0)
+  { if (typeof(#[1])=="int")
+    { int v=#[1];
+    }
+    else
+    { int v=0;
+    }
+  }
+  else
+  { int v=0;
+  }
+
+  int UsePP;
+  if (size(#)>0)
+  { if (typeof(#[size(#)])=="string")
+    { if (#[size(#)]=="PP")
+      { UsePP = 1;
+      }
+      else
+      { "ERROR:   If the last optional parameter is a string, it should be \"PP\".";
+        return(matrix(ideal()),matrix(ideal()));
+      }
+    }
+  }
+  int n=nvars(br);                // n is the number of variables, as well
+                                  // as the size of the matrices, as well
+                                  // as the number of primary invariants,
+                                  // we should get
+  if (ncols(P)<>n)
+  { "ERROR:   The first parameter ought to be the matrix of the primary";
+    "         invariants."
+    return();
+  }
+  if (ncols(REY)<>n)
+  { "ERROR:   The second parameter ought to be the Reynolds operator."
+    return();
+  }
+  if (ncols(M)<>2 or nrows(M)<>1)
+  { "ERROR:   The third parameter ought to be the Molien series."
+    return();
+  }
+  if (v && voice==2)
+  { "";
+  }
+  int j, m, counter, irrcounter;
+ //- finding the polynomial giving number and degrees of secondary invariants -
+  poly p=1;
+  for (j=1;j<=n;j++)                   // calculating the denominator of the
+  { p=p*(1-var(1)^deg(P[j]));          // Hilbert series of the ring generated
+  }                                    // by the primary invariants -
+  matrix s[1][2]=M[1,1]*p,M[1,2];      // s is used for canceling
+  s=matrix(syz(ideal(s)));
+  p=s[2,1];                            // the polynomial telling us where to
+                                       // search for secondary invariants
+  map slead=br,ideal(0);
+  p=1/slead(p)*p;                      // smallest [constant] term of
+                                       // p needs to be 1
+  matrix dimmat=coeffs(p,var(1));      // dimmat will contain the number of
+                                       // secondary invariants, we need to find
+                                       // of a certain degree -
+  m=nrows(dimmat);                     // m-1 is the highest degree
+  if (v)
+  { "There are";
+    for (j=1;j<=m;j++)
+     { if (int(dimmat[j,1])<>1)
+       { int(dimmat[j,1]), "secondary invariants in degree",j-1;
+       }
+       else
+       { "1 secondary invariant in degree",j-1;
+       }
+     }
+  }
+  if (v)
+  { "In degree 0 we have: 1";
+    "";
+  }
+ //-------------------------- initializing variables --------------------------
+  ideal ProdCand;          // contains products of secondary invariants,
+                           // i.e., candidates for reducible sec. inv.
+
+  ideal Mul1,Mul2;
+
+  int dgb=degBound;
+  degBound = 0;
+  option(redSB);
+  ideal sP = groebner(ideal(P));
+  ideal TotalReductor = sP;        // will eventually be groebner(ideal(P)+IS)
+  ideal sP_Reductor;          // will contain sP union Reductor.
+  int sPOffset = ncols(sP);
+  int LastNewIS=-10;           // if the Last New Irr. Sec. was found in degree i-2 then
+                               // we compute TotalReductor again
+  int NoPP;                    // It NoPP==1, we must not use Power Products
+  ideal Reductor,SaveRed;   // sP union Reductor is a Groebner basis up to degree i-1
+  int SizeSave;
+
+  list RedSSort;           // sec. Inv. reduced by sP, sorted first by degree and then
+                           // by the minimal degree of a non-constant invariant factor
+  list RedISSort;          // irr. sec. Inv. reduced by sP, sorted by degree
+
+  poly helpP;
+  ideal helpI;
+  ideal Indicator;        // will tell us which candidates for sec. inv. we can choose
+  ideal ReducedCandidates;
+  int helpint;
+  int k,k2,k3,minD;
+  int ii;
+  int saveAttr;
+  ideal mon,B,IS;              // IS will contain all irr. sec. inv.
+
+  for (i=1;i<m;i++)
+  { RedSSort[i] = list();
+    for (k=1;k<=i;k++)
+    { RedSSort[i][k]=ideal();
+      attrib(RedSSort[i][k],"size",0);
+    }
+   }
+//--------------------- generating secondary invariants ----------------------
+  for (i=2;i<=m;i++)                   // going through dimmat -
+  { // Case 1: PP are not required by the user, and we guess that all irreducibles have
+    // been found.
+    // Afterwards, the use of PP is impossible.
+    if ((LastNewIS == i-3) and (UsePP==0))
+    { if (v) {"Computing Groebner basis for primaries and previously found irreducibles...";}
+      degBound = 0;
+      TotalReductor = groebner(sP+IS);
+      NoPP = 1;
+    }
+    // Case 2: The use of PP is impossible, but we did find a new irr. sec. inv.
+    // in the preceding degree
+    if ((LastNewIS == i-2) and (NoPP==1))
+    { degBound = i-1;
+      TotalReductor = groebner(TotalReductor+SaveRed); // lift from degree i-2 to degree i-1
+      attrib(TotalReductor, "isSB",1);
+    }
+    if (int(dimmat[i,1])<>0)           // when it is == 0 we need to find no
+    {                                  // elements in the current degree (i-1)
+      if (v)
+      { "Searching in degree ",i-1,". There are ",
+        int(dimmat[i,1])," secondary invariant(s)...";
+      }
+      counter = 0;                       // we'll count up to dimmat[i,1]
+      Reductor = ideal(0);
+      helpint = 0;
+      SaveRed = Reductor;
+      SizeSave = 0;
+      attrib(Reductor,"isSB",1);
+      attrib(SaveRed,"isSB",1);
+
+      // Case A: We use PP
+      if ( NoPP==0 )
+      { if (v)
+        {
+          "  Looking for Power Products...";
+        }
+        sP_Reductor = sP;
+// We start searching for reducible secondary invariants in degree i-1, i.e., those
+// that are power products of irreducible secondary invariants.
+// It suffices to restrict the search at products of one _irreducible_ sec. inv. (Mul1)
+// with some sec. inv. (Mul2).
+// Moreover, we avoid to consider power products twice since we take a product
+// into account only if the minimal degree of a non-constant invariant factor in "Mul2" is not
+// smaller than the degree of "Mul1".
+// Finally, as we are not interested in the reducible sec. inv., we will only
+// work with their reduction modulo sP --- this allows to detect a secondary invariant
+// without to actually compute it!
+        for (k=1;k<i-1;k++)
+        { if (int(dimmat[i,1])==counter)
+          { break;
+          }
+          if (typeof(RedISSort[k])<>"none")
+          { Mul1 = RedISSort[k];
+          }
+          else
+          { Mul1 = ideal(0);
+          }
+          if ((int(dimmat[i-k,1])>0) && (Mul1[1]<>0))
+          { for (minD=i-k-1;minD>0;minD--)
+            { if (int(dimmat[i,1])==counter)
+              { break;
+              }
+              for (k2=1;k2 <= ((attrib(RedSSort[i-k-1][minD],"size")-1) div pieces)+1; k2++)
+              { if (int(dimmat[i,1])==counter)
+                { break;
+                }
+                Mul2=ideal(0);
+                if (attrib(RedSSort[i-k-1][minD],"size")>=k2*pieces)
+                { for (k3=1;k3<=pieces;k3++)
+                  { Mul2[k3] = RedSSort[i-k-1][minD][((k2-1)*pieces)+k3];
+                  }
+                }
+                else
+                { for (k3=1;k3<=(attrib(RedSSort[i-k-1][minD],"size") mod pieces);k3++)
+                  { Mul2[k3] = RedSSort[i-k-1][minD][((k2-1)*pieces)+k3];
+                  }
+                }
+                ProdCand = simplify(Mul1*Mul2,4);
+                ReducedCandidates = reduce(ProdCand,sP);
+                    // sP union SaveRed union Reductor is a homogeneous Groebner basis
+                    // up to degree i-1.
+                    // We first reduce by sP (which is fixed, so we can do it once for all),
+                    // then by SaveRed resp. by Reductor (which is modified during
+                    // the computations).
+                Indicator = reduce(ReducedCandidates,SaveRed);
+                               // If Indicator[ii]==0 then ReducedCandidates it the reduction
+                               // of an invariant that is in the algebra generated by primary
+                               // invariants and previously computed secondary invariants.
+                               // Otherwise ReducedCandidates[ii] is the reduction of an invariant
+                               // that we can take as secondary invariant.
+                if (size(Indicator)<>0)
+                { for (ii=1;ii<=ncols(ProdCand);ii++)     // going through all the power products
+                  { helpP = Indicator[ii];
+                    if (helpP <> 0)
+                    { counter++;
+                      saveAttr = attrib(RedSSort[i-1][k],"size")+1;
+                      RedSSort[i-1][k][saveAttr] = ReducedCandidates[ii];
+                          // By construction, this is the reduction of a reducible s.i.
+                          // of degree i-1.
+                      attrib(RedSSort[i-1][k],"size",saveAttr);
+                      if (v)
+                      { "    We found reducible sec. inv. number ",counter;
+                      }
+                      if (int(dimmat[i,1])<>counter)
+                      { Reductor = ideal(helpP);
+                        attrib(Reductor, "isSB",1);
+                        Indicator=reduce(Indicator,Reductor);
+                        SizeSave++;
+                        SaveRed[SizeSave] = helpP;
+                        sP_Reductor[sPOffset+SizeSave] = helpP;
+                        attrib(sP_Reductor, "isSB",1);
+                          // Lemma: If G is a homogeneous Groebner basis up to degree i-1 and p is a
+                          // homogeneous polynomial of degree i-1 then G union NF(p,G) is
+                          // a homogeneous Groebner basis up to degree i-1. Hence, sP_Reductor
+                          // is a homog. GB up to degree i-1.
+                        attrib(SaveRed, "isSB",1);
+                        attrib(Reductor, "isSB",1);
+                      }
+                      else
+                      { break;
+                      }
+                    } // new reducible sec. inv. found
+                  } // loop through ProdCand
+                } // if there is some reducible sec. inv.
+                attrib(SaveRed, "isSB",1);
+                attrib(Reductor, "isSB",1);
+              }
+            }
+          }
+        }
+        TotalReductor = sP_Reductor;
+      } // if NoPP==0
+      else
+      { //if (v) {"  We don't compute Power Products!"; }
+// Instead of computing Power Products, we can compute a Groebner basis of the ideal
+// generated by the primary and previously found irr. sec. invariants up to degree i-2. An invariant
+// polynomial of degree i-1 belongs to this ideal if and only if it belongs to the sub-algebra
+// generated by primary and irreducible secondary invariants up to degree i-2.
+// Hence, if we find an invariant outside this ideal, it is an irreducible secondary
+// invariant of degree i-1.
+    }  // dealing with reducible sec. inv.
+    // The remaining sec. inv. are irreducible!
+    // Reason: If we use PP, TotalReductor detects the <<P>>-module generated by
+    //         all secondaries
+    //         If we don't, TotalReductor detects the algebra <<P union IS>>
+    if (int(dimmat[i,1])<>counter)   // need more than all the power products
+                                       // or work without power products
+      { if (v)
+        { "  Looking for irreducible secondary invariants in degree ", i-1;
+        }
+        mon = kbase(TotalReductor,i-1);
+        ii = ncols(mon);
+        if (mon[1]<>0)
+        { if ((i>IrrSwitch) or (ii>200))  // use sparse algorithm
+          { if (NoPP==0 && ii+counter==int(dimmat[i,1])) // then we can use all of mon
+            { B=normalize(evaluate_reynolds(REY,mon));
+              IS=IS+B;
+              saveAttr = attrib(RedSSort[i-1][i-1],"size")+ii;
+              RedSSort[i-1][i-1] = RedSSort[i-1][i-1] + NF(B,sP);
+              attrib(RedSSort[i-1][i-1],"size", saveAttr);
+              if (typeof(RedISSort[i-1]) <> "none")
+              { RedISSort[i-1] = RedISSort[i-1] + NF(B,sP);
+              }
+              else
+              { RedISSort[i-1] = NF(B,sP);
+              }
+              if (v) {"    We found ",size(B)," irred. sec. inv.";}
+            }
+            else
+            { irrcounter=0;
+              j=0;                         // j goes through all of mon -
+// Compare the comments on the computation of reducible sec. inv.!
+              while (j < ii) // we will break the loop if counter==int(dimmat[i,1])
+              { if ((j mod MonStep) == 0)
+                { if ((j+MonStep) <= ii)
+                  { ideal tmp = normalize(evaluate_reynolds(REY,ideal(mon[j+1..j+MonStep])));
+                    B[j+1..j+MonStep] = tmp[1..MonStep];
+                    if (NoPP == 0)  // we are still working with PowerProducts,
+                                    // hence, we need to store NF(sec.inv.,sP)
+                    { tmp = reduce(tmp,sP);
+                      ReducedCandidates[j+1..j+MonStep] = tmp[1..MonStep];
+                      tmp = reduce(tmp,SaveRed);
+                    }
+                    else
+                    { tmp = reduce(tmp,TotalReductor);
+                    }
+                    Indicator[j+1..j+MonStep] = tmp[1..MonStep];
+                    kill tmp;
+                  }
+                  else
+                  { ideal tmp = normalize(evaluate_reynolds(REY,ideal(mon[j+1..ii])));
+                    B[j+1..ii] = tmp[1..ii-j];
+                    if (NoPP == 0)
+                    { tmp = reduce(tmp,sP);
+                      ReducedCandidates[j+1..ii] = tmp[1..ii-j];
+                      tmp = reduce(tmp,SaveRed);
+                    }
+                    else
+                    { tmp = reduce(tmp,TotalReductor);
+                    }
+                    Indicator[j+1..ii] = tmp[1..ii-j];
+                    kill tmp;
+                  }
+                }
+                j++;
+                helpP = Indicator[j];
+                if (helpP <>0)                     // B[j] should be added
+                { counter++; irrcounter++;
+                  IS=IS,B[j];
+                  saveAttr = attrib(RedSSort[i-1][i-1],"size")+1;
+                  if (NoPP==0)   // we will still be working with Power Products
+                  { RedSSort[i-1][i-1][saveAttr] = ReducedCandidates[j];
+                    attrib(RedSSort[i-1][i-1],"size",saveAttr);
+                    if (typeof(RedISSort[i-1]) <> "none")
+                    { RedISSort[i-1][irrcounter] = ReducedCandidates[j];
+                    }
+                    else
+                    { RedISSort[i-1] = ideal(ReducedCandidates[j]);
+                    }
+                  }
+                  if (v)
+                  { "    We found irred. sec. inv. number ",irrcounter;
+                  }
+                  Reductor = ideal(helpP);
+                  attrib(Reductor, "isSB",1);
+                  Indicator=reduce(Indicator,Reductor);
+                  SizeSave++;
+                  SaveRed[SizeSave] = helpP;
+                  attrib(SaveRed, "isSB",1);
+                  attrib(Reductor, "isSB",1);
+                  LastNewIS = i-1;
+                  if (int(dimmat[i,1])==counter) { break; }
+                }
+                mon[j]=0;
+                B[j]=0;
+                ReducedCandidates[j]=0;
+                Indicator[j]=0;
+              }
+            }
+          }  // if i>IrrSwitch
+          else  // use fast algorithm
+          { B=sort_of_invariant_basis(TotalReductor,REY,i-1,int(dimmat[i,1])*6);
+                                       // B is a linearly independent set of reynolds
+                                       // images of monomials that do not occur
+                                       // as leading monomials of the ideal spanned
+                                       // by primary and previously found irreducible
+                                       // secondary invariants.
+            if (NoPP==0 && ncols(B)+counter==int(dimmat[i,1])) // then we can take all of B
+            { IS=IS+B;
+              saveAttr = attrib(RedSSort[i-1][i-1],"size")+int(dimmat[i,1]);
+              RedSSort[i-1][i-1] = RedSSort[i-1][i-1] + B;
+              attrib(RedSSort[i-1][i-1],"size", saveAttr);
+              if (typeof(RedISSort[i-1]) <> "none")
+              { RedISSort[i-1] = RedISSort[i-1] + B;
+              }
+              else
+              { RedISSort[i-1] = B;
+              }
+              if (v) {"    We found ",size(B)," irred. sec. inv.";}
+            }
+            else
+            { irrcounter=0;
+              j=0;                         // j goes through all of B
+// Compare the comments on the computation of reducible sec. inv.!
+              ReducedCandidates = reduce(B,sP);
+              Indicator = reduce(ReducedCandidates,SaveRed);
+              while (int(dimmat[i,1])<>counter)    // need to find dimmat[i,1]
+              {                                    // invariants that are linearly independent
+                j++;
+                helpP = Indicator[j];
+                if (helpP <>0)                     // B[j] should be added
+                { NoPP=0;  // i.e., TotalReductor needs to be re-computed
+                  counter++; irrcounter++;
+                  IS=IS,B[j];
+                  saveAttr = attrib(RedSSort[i-1][i-1],"size")+1;
+                  RedSSort[i-1][i-1][saveAttr] = ReducedCandidates[j];
+                  attrib(RedSSort[i-1][i-1],"size",saveAttr);
+                  if (typeof(RedISSort[i-1]) <> "none")
+                  { RedISSort[i-1][irrcounter] = ReducedCandidates[j];
+                  }
+                  else
+                  { RedISSort[i-1] = ideal(ReducedCandidates[j]);
+                  }
+                  if (v)
+                  { "    We found irred. sec. inv. number ",irrcounter;
+                  }
+                  Reductor = ideal(helpP);
+                  attrib(Reductor, "isSB",1);
+                  Indicator=reduce(Indicator,Reductor);
+                  SizeSave++;
+                  SaveRed[SizeSave] = helpP;
+                  attrib(SaveRed, "isSB",1);
+                  attrib(Reductor, "isSB",1);
+                  LastNewIS = i-1;
+                  if (int(dimmat[i,1])==counter) { break; }
+                }
+                B[j]=0;
+                ReducedCandidates[j]=0;
+                Indicator[j]=0;
+              }
+            }
+          } // i<=IrrSwitch
+        } // if mon[1]<>0
+      } // Computation of irreducible secondaries
+      if (v)
+      { "";
+      }
+    }
+  }
+  if (v)
+  { "  We're done!";
+    "";
+  }
+  degBound = dgb;
+  return(matrix(compress(IS)));
+}
+example
+{ "EXAMPLE: S. King"; echo=2;
+ring r= 0, (a,b,c,d,e,f),dp;
+matrix A1[6][6] = 0,0,0,1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0;
+matrix A2[6][6] = 0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1,0,0,0;
+list L = primary_invariants(A1,A2);
+matrix IS = irred_secondary_char0(L[1],L[2],L[3],0);
+IS;
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc old_secondary_charp (matrix P, matrix REY, string ring_name, list #)
+"USAGE:   secondary_charp(P,REY,ringname[,v]);
+         P: a 1xn <matrix> with primary invariants, REY: a gxn <matrix>
+         representing the Reynolds operator, ringname: a <string> giving the
+         name of a ring of characteristic 0 where the Molien series is stored,
+         v: an optional <int>
+ASSUME:  n is the number of variables of the basering, g the size of the group,
+         REY is the 1st return value of group_reynolds(), reynolds_molien() or
+         the second one of primary_invariants(), `ringname` is a ring of
+         char 0 that has been created by molien() or reynolds_molien() or
+         primary_invariants()
+RETURN:  secondary invariants of the invariant ring (type <matrix>) and
+         irreducible secondary invariants (type <matrix>)
+DISPLAY: information if v does not equal 0
+THEORY:  Secondary invariants are calculated by finding a basis (in terms of
+         monomials) of the basering modulo primary invariants, mapping those
+         to invariants with the Reynolds operator and using these images or
+         their power products such that they are linearly independent modulo
+         the primary invariants (see paper \"Some Algorithms in Invariant
+         Theory of Finite Groups\" by Kemper and Steel (1997)).
+EXAMPLE: example secondary_charp; shows an example
+"
+{ def br=basering;
+  degBound=0;
+ //---------------- checking input and setting verbose mode -------------------
+  if (char(br)==0)
+  { "ERROR:   secondary_charp should only be used with rings of characteristic p>0.";
+    return();
+  }
+  int i;
+  if (size(#)>0)
+  { if (typeof(#[size(#)])=="int")
+    { int v=#[size(#)];
+    }
+    else
+    { int v=0;
+    }
+  }
+  else
+  { int v=0;
+  }
+  int n=nvars(br);                     // n is the number of variables, as well
+                                       // as the size of the matrices, as well
+                                       // as the number of primary invariants,
+                                       // we should get
+  if (ncols(P)<>n)
+  { "ERROR:   The first parameter ought to be the matrix of the primary";
+    "         invariants."
+    return();
+  }
+  if (ncols(REY)<>n)
+  { "ERROR:   The second parameter ought to be the Reynolds operator."
+    return();
+  }
+  if (typeof(`ring_name`)<>"ring")
+  { "ERROR:   The <string> should give the name of the ring where the Molien."
+    "         series is stored.";
+    return();
+  }
+  if (v && voice==2)
+  { "";
+  }
+  int j, m, counter, d;
+  intvec deg_dim_vec;
+ //- finding the polynomial giving number and degrees of secondary invariants -
+  for (j=1;j<=n;j++)
+  { deg_dim_vec[j]=deg(P[j]);
+  }
+  setring `ring_name`;
+  poly p=1;
+  for (j=1;j<=n;j++)                   // calculating the denominator of the
+  { p=p*(1-var(1)^deg_dim_vec[j]);     // Hilbert series of the ring generated
+  }                                    // by the primary invariants -
+  matrix s[1][2]=M[1,1]*p,M[1,2];      // s is used for canceling
+  s=matrix(syz(ideal(s)));
+  p=s[2,1];                            // the polynomial telling us where to
+                                       // search for secondary invariants
+  map slead=basering,ideal(0);
+  p=1/slead(p)*p;                      // smallest term of p needs to be 1
+  if (v)
+  { "  Polynomial telling us where to look for secondary invariants:";
+    "   "+string(p);
+    "";
+  }
+  matrix dimmat=coeffs(p,var(1));      // dimmat will contain the number of
+                                       // secondary invariants, we need to find
+                                       // of a certain degree -
+  m=nrows(dimmat);                     // m-1 is the highest degree
+  deg_dim_vec=1;
+  for (j=2;j<=m;j++)
+  { deg_dim_vec=deg_dim_vec,int(dimmat[j,1]);
+  }
+  if (v)
+  { "In degree 0 we have: 1";
+    "";
+  }
+ //------------------------ initializing variables ----------------------------
+  setring br;
+  intmat PP;
+  poly pp;
+  int k;
+  intvec deg_vec;
+  ideal sP=groebner(ideal(P));
+  ideal TEST,B,IS;
+  ideal S=1;                           // 1 is the first secondary invariant
+ //------------------- generating secondary invariants ------------------------
+  for (i=2;i<=m;i++)                   // going through deg_dim_vec -
+  { if (deg_dim_vec[i]<>0)             // when it is == 0 we need to find 0
+    {                                  // elements in the current degree (i-1)
+      if (v)
+      { "Searching in degree ",i-1,", we need to find ",deg_dim_vec[i]," invariant(s)...";
+      }
+      TEST=sP;
+      counter=0;                       // we'll count up to degvec[i]
+      if (IS[1]<>0)
+      { PP=power_products(deg_vec,i-1); // generating power products of
+      }                                // irreducible secondary invariants
+      if (size(ideal(PP))<>0)
+      { for (j=1;j<=ncols(PP);j++)     // going through all of those
+        { pp=1;
+          for (k=1;k<=nrows(PP);k++)
+          { pp=pp*IS[1,k]^PP[k,j];
+          }
+          if (reduce(pp,TEST)<>0)
+          { S=S,pp;
+            counter++;
+            if (v)
+            { "  We find: "+string(pp);
+            }
+            if (deg_dim_vec[i]<>counter)
+            { //TEST=std(TEST+ideal(NF(pp,TEST))); // should be soon replaced by
+                                                 // next line
+              TEST=std(TEST,pp);
+            }
+            else
+            { break;
+            }
+          }
+        }
+      }
+      if (deg_dim_vec[i]<>counter)
+      { B=sort_of_invariant_basis(sP,REY,i-1,deg_dim_vec[i]*6); // B contains
+                                       // images of kbase(sP,i-1) under the
+                                       // Reynolds operator that are linearly
+                                       // independent and that don't reduce to
+                                       // 0 modulo sP -
+        if (counter==0 && ncols(B)==deg_dim_vec[i]) // then we can add all of B
+        { S=S,B;
+          IS=IS+B;
+          if (deg_vec[1]==0)
+          { deg_vec=i-1;
+            if (v)
+            { "  We find: "+string(B[1]);
+            }
+            for (j=2;j<=deg_dim_vec[i];j++)
+            { deg_vec=deg_vec,i-1;
+              if (v)
+              { "  We find: "+string(B[j]);
+              }
+            }
+          }
+          else
+          { for (j=1;j<=deg_dim_vec[i];j++)
+            { deg_vec=deg_vec,i-1;
+              if (v)
+              { "  We find: "+string(B[j]);
+              }
+            }
+          }
+        }
+        else
+        { j=0;                         // j goes through all of B -
+          while (deg_dim_vec[i]<>counter) // need to find deg_dim_vec[i]
+          {                            // invariants that are linearly
+                                       // independent modulo TEST
+            j++;
+            if (reduce(B[j],TEST)<>0)   // B[j] should be added
+            { S=S,B[j];
+              IS=IS+ideal(B[j]);
+              if (deg_vec[1]==0)
+              { deg_vec[1]=i-1;
+              }
+              else
+              { deg_vec=deg_vec,i-1;
+              }
+              counter++;
+              if (v)
+              { "  We find: "+string(B[j]);
+              }
+              if (deg_dim_vec[i]<>counter)
+              { //TEST=std(TEST+ideal(NF(B[j],TEST))); // should be soon replaced
+                                                     // by next line
+                TEST=std(TEST,B[j]);
+              }
+            }
+          }
+        }
+      }
+      if (v)
+      { "";
+      }
+    }
+  }
+  if (v)
+  { "  We're done!";
+    "";
+  }
+  if (ring_name=="aksldfalkdsflkj")
+  { kill `ring_name`;
+  }
+  return(matrix(S),matrix(IS));
+}
+example
+{ "EXAMPLE: Sturmfels: Algorithms in Invariant Theory 2.3.7 (changed into char 3)"; echo=2;
+         ring R=3,(x,y,z),dp;
+         matrix A[3][3]=0,1,0,-1,0,0,0,0,-1;
+         list L=primary_invariants(A);
+         matrix S,IS=secondary_charp(L[1..size(L)]);
+         print(S);
+         print(IS);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+
+proc secondary_charp (matrix P, matrix REY, string ring_name, list #)
+"USAGE:   secondary_charp(P,REY,ringname[,v][,\"old\"]);
+@*          P: a 1xn <matrix> with homogeneous primary invariants, where
+               n is the number of variables of the basering;
+@*          REY: a gxn <matrix> representing the Reynolds operator, where
+               g the size of the corresponding group;
+@*          ringname: a <string> giving the name of a ring of characteristic 0
+               containing a 1x2 <matrix> M giving numerator and denominator of the Molien
+               series;
+@*          v: an optional <int>;
+@*          \"old\": if this string occurs as (optional) parameter, then an
+               old version of secondary_char0 is used (for downward
+               compatibility)
+ASSUME:   The characteristic of basering is not zero;
+          REY is the 1st return value of group_reynolds(), reynolds_molien() or
+          the second one of primary_invariants();
+@*        `ringname` is the name of a ring of characteristic 0 that has been created
+          by molien() or reynolds_molien() or primary_invariants()
+RETURN:   secondary invariants of the invariant ring (type <matrix>) and
+          irreducible secondary invariants (type <matrix>)
+DISPLAY:  information if v does not equal 0
+THEORY:   The secondary invariants are calculated by finding a basis (in terms
+          of monomials) of the basering modulo the primary invariants, mapping
+          those to invariants with the Reynolds operator. Among these images
+          or their power products we pick secondary invariants using Groebner
+          basis techniques (see S. King: Fast Computation of Secondary Invariants).
+          The size of this set can be read off from the Molien series.
+EXAMPLE:  example secondary_charp; shows an example
+"
+{
+ //----------  Internal parameters, whose choice might improve the performance -----
+  int pieces = 3;   // For generating reducible secondaries, blocks of #pieces# secondaries
+                     // are formed.
+                     // If this parameter is small, the memory consumption will decrease.
+  int MonStep = 15;  // The Reynolds operator is applied to blocks of #MonStep# monomials.
+                     // If this parameter is small, the memory consumption will decrease.
+  int IrrSwitch = 7; // Up to degree #IrrSwitch#-1, we use a method for generating
+                     // irreducible secondaries that tends to produce a smaller output
+                     // (which is good for subsequent computations). However, this method
+                     // needs to much memory in high degrees, and so we use a sparser method
+                     // from degree #IrrSwitch# on.
+
+  def br=basering;
+
+ //---------------- checking input and setting verbose mode -------------------
+  if (char(br)==0)
+  { "ERROR:   secondary_charp should only be used with rings of characteristic p>0.";
+    return();
+  }
+  int i;
+  if (size(#)>0)
+  { if (typeof(#[size(#)])=="int")
+    { int v=#[size(#)];
+    }
+    else
+    { int v=0;
+    }
+  }
+  else
+  { int v=0;
+  }
+  if (size(#)>0)
+  { if (typeof(#[size(#)])=="string")
+    { if (#[size(#)]=="old")
+      { if (typeof(#[1])=="int")
+        { matrix S,IS = old_secondary_charp(P,REY,ring_name,#[1]);
+          return(S,IS);
+        }
+        else
+        { matrix S,IS = old_secondary_charp(P,REY,ring_name);
+          return(S,IS);
+        }
+      }
+      else
+      { "ERROR:   If the last optional parameter is a string, it should be \"old\".";
+        return(matrix(ideal()),matrix(ideal()));
+      }
+    }
+  }
+  int n=nvars(br);                     // n is the number of variables, as well
+                                       // as the size of the matrices, as well
+                                       // as the number of primary invariants,
+                                       // we should get
+  if (ncols(P)<>n)
+  { "ERROR:   The first parameter ought to be the matrix of the primary";
+    "         invariants."
+    return();
+  }
+  if (ncols(REY)<>n)
+  { "ERROR:   The second parameter ought to be the Reynolds operator."
+    return();
+  }
+  if (typeof(`ring_name`)<>"ring")
+  { "ERROR:   The <string> should give the name of the ring where the Molien."
+    "         series is stored.";
+    return();
+  }
+  if (v && voice==2)
+  { "";
+  }
+  int j, m, counter, irrcounter, d;
+  intvec deg_dim_vec;
+ //- finding the polynomial giving number and degrees of secondary invariants -
+  for (j=1;j<=n;j++)
+  { deg_dim_vec[j]=deg(P[j]);
+  }
+  setring `ring_name`;
+  poly p=1;
+  for (j=1;j<=n;j++)                   // calculating the denominator of the
+  { p=p*(1-var(1)^deg_dim_vec[j]);     // Hilbert series of the ring generated
+  }                                    // by the primary invariants -
+  matrix s[1][2]=M[1,1]*p,M[1,2];      // s is used for canceling
+  s=matrix(syz(ideal(s)));
+  p=s[2,1];                            // the polynomial telling us where to
+                                       // search for secondary invariants
+  map slead=basering,ideal(0);
+  p=1/slead(p)*p;                      // smallest term of p needs to be 1
+
+  matrix dimmat=coeffs(p,var(1));      // dimmat will contain the number of
+                                       // secondary invariants, we need to find
+                                       // of a certain degree -
+  m=nrows(dimmat);                     // m-1 is the highest degree
+  if (v)
+  { "We need to find";
+    for (j=1;j<=m;j++)
+     { if (int(dimmat[j,1])<>1)
+       { int(dimmat[j,1]), "secondary invariants in degree",j-1;
+       }
+       else
+       { "1 secondary invariant in degree",j-1;
+       }
+     }
+  }
+  deg_dim_vec=1;
+  for (j=2;j<=m;j++)
+  { deg_dim_vec=deg_dim_vec,int(dimmat[j,1]); // i.e., deg_dim_vec[i] = dimmat[i-1,1],
+                                              // which is the number of secondaries in degree i-1
+  }
+  if (v)
+  { "In degree 0 we have: 1";
+    "";
+  }
+ //------------------------ initializing variables ----------------------------
+  setring br;
+  ideal ProdCand;          // contains products of secondary invariants,
+                           // i.e., candidates for reducible sec. inv.
+  ideal Mul1,Mul2;
+
+  int dgb=degBound;
+  degBound = 0;
+  intvec saveopt=option(get);
+  option(redSB);
+  ideal sP = groebner(ideal(P));
+                           // This is the only explicit Groebner basis computation!
+  ideal Reductor,SaveRed;  // sP union Reductor is a Groebner basis up to degree i-1
+  ideal sP_Reductor;          // will contain sP union Reductor.
+  int sPOffset = ncols(sP);
+  int SizeSave;
+
+  list SSort;         // sec. inv. first sorted by degree and then sorted by the
+                      // minimal degree of a non-constant invariant factor.
+  list ISSort;        // irr. sec. inv. sorted by degree
+  int NrIS;
+
+  poly helpP;
+  ideal helpI;
+  ideal Indicator;        // will tell us which candidates for sec. inv. we can choose
+  ideal ReducedCandidates;
+  int helpint;
+  int k,k2,k3,minD;
+  int ii;
+  int saveAttr;
+  ideal mon,B,IS;              // IS will contain all irr. sec. inv.
+
+  for (i=1;i<m;i++)
+  { SSort[i] = list();
+    for (k=1;k<=i;k++)
+    { SSort[i][k]=ideal();
+      attrib(SSort[i][k],"size",0);
+    }
+  }
+ //------------------- generating secondary invariants ------------------------
+  for (i=2;i<=m;i++)                   // going through deg_dim_vec -
+  { if (deg_dim_vec[i]<>0)             // when it is == 0 we need to find no
+    {                                  // elements in the current degree (i-1)
+      if (v)
+      { "Searching in degree ",i-1,", we need to find ",deg_dim_vec[i],
+        " invariant(s)...";
+        "  Looking for Power Products...";
+      }
+      counter = 0;                       // we'll count up to deg_dim_vec[i]
+      Reductor = ideal(0);
+      sP_Reductor = sP;
+      helpint = 0;
+      SaveRed = Reductor;
+      SizeSave = 0;
+      attrib(Reductor,"isSB",1);
+      attrib(SaveRed,"isSB",1);
+
+// We start searching for reducible secondary invariants in degree i-1, i.e., those
+// that are power products of irreducible secondary invariants.
+// It suffices to restrict the search at products of one _irreducible_ sec. inv. (Mul1)
+// with some sec. inv. (Mul2).
+// Moreover, we avoid to consider power products twice since we take a product
+// into account only if the minimal degree of a non-constant invariant factor in "Mul2" is not
+// smaller than the degree of "Mul1".
+      for (k=1;k<i-1;k++)
+      { if (deg_dim_vec[i]==counter)
+        { break;
+        }
+        if (typeof(ISSort[k])<>"none")
+        { Mul1 = ISSort[k];
+        }
+        else
+        { Mul1 = ideal(0);
+        }
+        if ((deg_dim_vec[i-k]>0) && (Mul1[1]<>0))
+        { for (minD=k;minD<i-k;minD++)
+          { if (deg_dim_vec[i]==counter)
+            { break;
+            }
+            for (k2=1;k2 <= ((attrib(SSort[i-k-1][minD],"size")-1) div pieces)+1; k2++)
+            { if (deg_dim_vec[i]==counter)
+              { break;
+              }
+              Mul2=ideal(0);
+              if (attrib(SSort[i-k-1][minD],"size")>=k2*pieces)
+              { for (k3=1;k3<=pieces;k3++)
+                { Mul2[k3] = SSort[i-k-1][minD][((k2-1)*pieces)+k3];
+                }
+              }
+              else
+              { for (k3=1;k3<=(attrib(SSort[i-k-1][minD],"size") mod pieces);k3++)
+                { Mul2[k3] = SSort[i-k-1][minD][((k2-1)*pieces)+k3];
+                }
+              }
+              ProdCand = simplify(Mul1*Mul2,4);
+              ReducedCandidates = reduce(ProdCand,sP);
+                  // sP union SaveRed union Reductor is a homogeneous Groebner basis
+                  // up to degree i-1.
+                  // We first reduce by sP (which is fixed, so we can do it once for all),
+                  // then by SaveRed resp. by Reductor (which is modified during
+                  // the computations).
+              Indicator = reduce(ReducedCandidates,SaveRed);
+                             // If Indicator[ii]==0 then ReducedCandidates it the reduction
+                             // of an invariant that is in the algebra generated by primary
+                             // invariants and previously computed secondary invariants.
+                             // Otherwise ProdCand[ii] can be taken as secondary invariant.
+              if (size(Indicator)<>0)
+              { for (ii=1;ii<=ncols(ProdCand);ii++)     // going through all the power products
+                { helpP = Indicator[ii];
+                  if (helpP <> 0)
+                  { counter++;
+                    saveAttr = attrib(SSort[i-1][k],"size")+1;
+                    SSort[i-1][k][saveAttr] = ProdCand[ii];
+                        // By construction, this is a _reducible_ s.i.
+                    attrib(SSort[i-1][k],"size",saveAttr);
+                    if (v)
+                    { "    We found", counter, "of", deg_dim_vec[i], "secondaries in degree",i-1;
+                    }
+                    if (deg_dim_vec[i]<>counter)
+                    { Reductor = ideal(helpP);
+                      attrib(Reductor, "isSB",1);
+                      Indicator=reduce(Indicator,Reductor);
+                      SizeSave++;
+                      sP_Reductor[sPOffset+SizeSave] = helpP;
+                      attrib(sP_Reductor, "isSB",1);
+                        // Lemma: If G is a homogeneous Groebner basis up to degree i-1 and p is a
+                        // homogeneous polynomial of degree i-1 then G union NF(p,G) is
+                        // a homogeneous Groebner basis up to degree i-1. Hence, sP_Reductor
+                        // is a homog. GB up to degree i-1.
+                      SaveRed[SizeSave] = helpP;
+                      attrib(SaveRed, "isSB",1);
+                    }
+                    else
+                    { break;
+                    }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+      NrIS = deg_dim_vec[i]-counter;
+      // The remaining NrIS sec. inv. are irreducible!
+      if (NrIS>0)   // need more than all the power products
+      { if (v)
+        { "  There are ",NrIS,"irreducible secondary invariants in degree ", i-1;
+        }
+        mon = kbase(sP_Reductor,i-1);
+        ii = ncols(mon);
+        if ((i>IrrSwitch) or (ii>200)) // use sparse algorithm
+        { if (counter==0 && ncols(mon)==deg_dim_vec[i]) // then we can use all of mon
+          { B=normalize(evaluate_reynolds(REY,mon));
+            IS=IS+B;
+            saveAttr = attrib(SSort[i-1][i-1],"size")+deg_dim_vec[i];
+            SSort[i-1][i-1] = SSort[i-1][i-1] + B;
+            attrib(SSort[i-1][i-1],"size", saveAttr);
+            if (typeof(ISSort[i-1]) <> "none")
+            { ISSort[i-1] = ISSort[i-1] + B;
+            }
+            else
+            { ISSort[i-1] = B;
+            }
+            if (v) {"    We found all",NrIS,"irreducibles in degree ",i-1;}
+          }
+          else
+          { irrcounter=0;
+            j=0;                         // j goes through all of mon -
+            // Compare the comments on the computation of reducible sec. inv.!
+            while (deg_dim_vec[i]<>counter)
+            { if ((j mod MonStep) == 0)
+              { if ((j+MonStep) <= ii)
+                { ideal tmp = normalize(evaluate_reynolds(REY,ideal(mon[j+1..j+MonStep])));
+                  B[j+1..j+MonStep] = tmp[1..MonStep];
+                  tmp = reduce(tmp,sP);
+                  ReducedCandidates[j+1..j+MonStep] = tmp[1..MonStep];
+                  tmp = reduce(tmp,SaveRed);
+                  Indicator[j+1..j+MonStep] = tmp[1..MonStep];
+                  kill tmp;
+                }
+                else
+                { ideal tmp = normalize(evaluate_reynolds(REY,ideal(mon[j+1..ii])));
+                  B[j+1..ii] = tmp[1..ii-j];
+                  tmp = reduce(tmp,sP);
+                  ReducedCandidates[j+1..ii] = tmp[1..ii-j];
+                  tmp = reduce(tmp,SaveRed);
+                  Indicator[j+1..ii] = tmp[1..ii-j];
+                  kill tmp;
+                }
+              }
+              j++;
+              helpP = Indicator[j];
+              if (helpP <>0)                  // B[j] should be added
+              { counter++; irrcounter++;
+                IS=IS,B[j];
+                saveAttr = attrib(SSort[i-1][i-1],"size")+1;
+                SSort[i-1][i-1][saveAttr] = B[j];
+                attrib(SSort[i-1][i-1],"size",saveAttr);
+                if (typeof(ISSort[i-1]) <> "none")
+                { ISSort[i-1][irrcounter] = B[j];
+                }
+                else
+                { ISSort[i-1] = ideal(B[j]);
+                }
+                if (v)
+                { "    We found", irrcounter,"of", NrIS ,"irr. sec. inv. in degree ",i-1;
+                }
+                Reductor = ideal(helpP);
+                attrib(Reductor, "isSB",1);
+                Indicator=reduce(Indicator,Reductor);
+                SizeSave++;
+                SaveRed[SizeSave] = helpP;
+                attrib(SaveRed, "isSB",1);
+              }
+              B[j]=0;
+              ReducedCandidates[j]=0;
+              Indicator[j]=0;
+            }
+          }
+        }  // if i>IrrSwitch
+        else  // use fast algorithm
+        { B=sort_of_invariant_basis(sP,REY,i-1,deg_dim_vec[i]*6);
+                                       // B contains
+                                       // images of kbase(sP,i-1) under the
+                                       // Reynolds operator that are linearly
+                                       // independent
+          if (counter==0 && ncols(B)==deg_dim_vec[i]) // then we can take all of B
+          { IS=IS+B;
+            saveAttr = attrib(SSort[i-1][i-1],"size")+deg_dim_vec[i];
+            SSort[i-1][i-1] = SSort[i-1][i-1] + B;
+            attrib(SSort[i-1][i-1],"size", saveAttr);
+            if (typeof(ISSort[i-1]) <> "none")
+            { ISSort[i-1] = ISSort[i-1] + B;
+            }
+            else
+            { ISSort[i-1] = B;
+            }
+            if (v) {"    We found all",NrIS,"irreducibles in degree ",i-1;}
+          }
+          else
+          { irrcounter=0;
+            j=0;                         // j goes through all of B -
+            // Compare the comments on the computation of reducible sec. inv.!
+            ReducedCandidates = reduce(B,sP);
+            Indicator = reduce(ReducedCandidates,SaveRed);
+            while (deg_dim_vec[i]<>counter)
+            { j++;
+              helpP = Indicator[j];
+              if (helpP <>0)                  // B[j] should be added
+              { counter++; irrcounter++;
+                IS=IS,B[j];
+                saveAttr = attrib(SSort[i-1][i-1],"size")+1;
+                SSort[i-1][i-1][saveAttr] = B[j];
+                attrib(SSort[i-1][i-1],"size",saveAttr);
+                if (typeof(ISSort[i-1]) <> "none")
+                { ISSort[i-1][irrcounter] = B[j];
+                }
+                else
+                { ISSort[i-1] = ideal(B[j]);
+                }
+                if (v)
+                { "    We found", irrcounter,"of", NrIS ,"irr. sec. inv. in degree ",i-1;
+                }
+                Reductor = ideal(helpP);
+                attrib(Reductor, "isSB",1);
+                Indicator=reduce(Indicator,Reductor);
+                SizeSave++;
+                SaveRed[SizeSave] = helpP;
+                attrib(SaveRed, "isSB",1);
+              }
+              B[j]=0;
+              ReducedCandidates[j]=0;
+              Indicator[j]=0;
+            }
+          }
+        } // i<=IrrSwitch
+      } // Computation of irreducible secondaries
+      if (v)
+      { "";
+      }
+    } // if (deg_dim_vec[i]<>0)
+  }  // for i
+  if (v)
+  { "  We're done!";
+    "";
+  }
+  degBound = dgb;
+
+  // Prepare return:
+  int TotalNumber;
+  for (k=1;k<=m;k++)
+  { TotalNumber = TotalNumber + deg_dim_vec[k];
+  }
+  matrix S[1][TotalNumber];
+  S[1,1]=1;
+  j=1;
+  for (k=1;k<m;k++)
+  { for (k2=1;k2<=k;k2++)
+    { if (typeof(attrib(SSort[k][k2],"size"))=="int")
+     {for (i=1;i<=attrib(SSort[k][k2],"size");i++)
+      { j++;
+        S[1,j] = SSort[k][k2][i];
+      }
+      SSort[k][k2]=ideal();
+     }
+    }
+  }
+  if (ring_name=="aksldfalkdsflkj")
+  { kill `ring_name`;
+  }
+  option(set,saveopt);
+  return(matrix(S),matrix(compress(IS)));
+}
+example
+{ "EXAMPLE: Sturmfels: Algorithms in Invariant Theory 2.3.7 (changed into char 3)"; echo=2;
+         ring R=3,(x,y,z),dp;
+         matrix A[3][3]=0,1,0,-1,0,0,0,0,-1;
+         list L=primary_invariants(A);
+         matrix S,IS=secondary_charp(L[1..size(L)],1);
+         print(S);
+         print(IS);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc secondary_no_molien (matrix P, matrix REY, list #)
+"USAGE:   secondary_no_molien(P,REY[,deg_vec,v]);
+          P: a 1xn <matrix> with primary invariants, REY: a gxn <matrix>
+          representing the Reynolds operator, deg_vec: an optional <intvec>
+          listing some degrees where no non-trivial homogeneous invariants can
+          be found, v: an optional <int>
+ASSUME:   n is the number of variables of the basering, g the size of the group,
+          REY is the 1st return value of group_reynolds(), reynolds_molien() or
+          the second one of primary_invariants(), deg_vec is the second return
+          value of primary_char0_no_molien(), primary_charp_no_molien(),
+          primary_char0_no_molien_random() or primary_charp_no_molien_random()
+RETURN:   secondary invariants of the invariant ring (type <matrix>)
+DISPLAY:  information if v does not equal 0
+THEORY:   Secondary invariants are calculated by finding a basis (in terms of
+          monomials) of the basering modulo primary invariants, mapping those to
+          invariants with the Reynolds operator and using these images as
+          candidates for secondary invariants. We have the Reynolds operator, hence,
+          we are in the non-modular case. Therefore, the invariant ring is Cohen-Macaulay,
+          hence the number of secondary invariants is the product of the degrees of
+          primary invariants divided by the group order.
+NOTE:     <secondary_and_irreducibles_no_molien> should usually be faster and of
+          more useful functionality.
+SEE ALSO: secondary_and_irreducibles_no_molien
+EXAMPLE:  example secondary_no_molien; shows an example
+"
+{ int MonStep = 15;  // The Reynolds operator is applied to blocks of #MonStep# monomials.
+                     // If this parameter is small, the memory consumption will decrease.
+  int IrrSwitch = 7; // Up to degree #IrrSwitch#-1, we use a method for generating
+                     // irreducible secondaries that tends to produce a smaller output
+                     // (which is good for subsequent computations). However, this method
+                     // needs to much memory in high degrees, and so we use a sparser method
+                     // from degree #IrrSwitch# on.
+  int i;
+  def br=basering;
+ //------------------ checking input and setting verbose ----------------------
+  if (size(#)==1 or size(#)==2)
+  { if (typeof(#[size(#)])=="int")
+    { if (size(#)==2)
+      { if (typeof(#[size(#)-1])=="intvec")
+        { intvec deg_vec=#[size(#)-1];
+        }
+        else
+        { "ERROR:   the third parameter should be an <intvec>";
+          return();
+        }
+      }
+      int v=#[size(#)];
+    }
+    else
+    { if (size(#)==1)
+      { if (typeof(#[size(#)])=="intvec")
+        { intvec deg_vec=#[size(#)];
+          int v=0;
+        }
+        else
+        { "ERROR:   the third parameter should be an <intvec>";
+          return();
+        }
+      }
+      else
+      { "ERROR:   wrong list of parameters";
+        return();
+      }
+    }
+  }
+  else
+  { if (size(#)>2)
+    { "ERROR:   there are too many parameters";
+      return();
+    }
+    int v=0;
+  }
+  int n=nvars(basering);               // n is the number of variables, as well
+                                       // as the size of the matrices, as well
+                                       // as the number of primary invariants,
+                                       // we should get
+  if (ncols(P)<>n)
+  { "ERROR:   The first parameter ought to be the matrix of the primary";
+    "         invariants."
+    return();
+  }
+  if (ncols(REY)<>n)
+  { "ERROR:   The second parameter ought to be the Reynolds operator.";
+    return();
+  }
+  if (char(br)<>0)
+  { if (nrows(REY) mod char(br) == 0)
+    { "ERROR:   We need to be in the non-modular case.";
+      return();
+    }
+  }
+  else
+  { "WARNING: In char 0, secondary_char0 should be faster.";
+  }
+  if (v && voice==2)
+  { "";
+  }
+  int j, m, d;
+  int max=1;
+  for (j=1;j<=n;j++)
+  { max=max*deg(P[j]);
+  }
+  max=max div nrows(REY);
+  if (v)
+  { "  We need to find ",max," secondary invariants.";
+    "";
+    "In degree 0 we have: 1";
+    "";
+  }
+ //------------------------- initializing variables ---------------------------
+  int dgb = degBound;
+  degBound=0;
+  ideal sP=groebner(ideal(P));
+  ideal Reductor,SaveRed;  // sP union Reductor is a Groebner basis up to degree i-1
+  int SizeSave;
+  poly helpP;
+  ideal helpI;
+  ideal Indicator;        // will tell us which candidates for sec. inv. we can choose
+  ideal ReducedCandidates;
+  int helpint;
+  int k2,k3,minD;
+  int ii;
+  int saveAttr;
+  ideal mon,B;
+
+  ideal S=1;                           // 1 is the first secondary invariant
+  int counter=1;
+  i=0;
+  if (defined(deg_vec)<>voice)
+  { intvec deg_vec;
+  }
+  int k=1;
+ //--------------------- generating secondary invariants ----------------------
+  while (counter<>max)
+  { i++;
+    Reductor = ideal(0);
+    helpint = 0;
+    SaveRed = Reductor;
+    SizeSave = 0;
+    attrib(Reductor,"isSB",1);
+    attrib(SaveRed,"isSB",1);
+    if (deg_vec[k]<>i)
+    { if (v)
+      { "Searching in degree ",i,"...";
+      }
+      mon = kbase(sP,i);
+      ii = ncols(mon);
+      if ((i>IrrSwitch) or (ii>200)) // use sparse algorithm
+      { j=0;                         // j goes through all of mon -
+        // Compare the comments on the computation of reducible sec. inv.!
+        while ((j<ii) and (counter < max))
+        { if ((j mod MonStep) == 0)
+          { if ((j+MonStep) <= ii)
+            { ideal tmp = normalize(evaluate_reynolds(REY,ideal(mon[j+1..j+MonStep])));
+              B[j+1..j+MonStep] = tmp[1..MonStep];
+              tmp = reduce(tmp,sP);
+              ReducedCandidates[j+1..j+MonStep] = tmp[1..MonStep];
+              tmp = reduce(tmp,SaveRed);
+              Indicator[j+1..j+MonStep] = tmp[1..MonStep];
+              kill tmp;
+            }
+            else
+            { ideal tmp = normalize(evaluate_reynolds(REY,ideal(mon[j+1..ii])));
+              B[j+1..ii] = tmp[1..ii-j];
+              tmp = reduce(tmp,sP);
+              ReducedCandidates[j+1..ii] = tmp[1..ii-j];
+              tmp = reduce(tmp,SaveRed);
+              Indicator[j+1..ii] = tmp[1..ii-j];
+              kill tmp;
+            }
+          }
+          j++;
+          helpP = Indicator[j];
+          if (helpP <>0)                  // B[j] should be added
+          { counter++;
+            S[counter] = B[j];
+            if (v)
+            { "    We found sec. inv. number ",counter," in degree ",i;
+            }
+            if (counter == max) {break;}
+            Reductor = ideal(helpP);
+            attrib(Reductor, "isSB",1);
+            Indicator=reduce(Indicator,Reductor);
+            SizeSave++;
+            SaveRed[SizeSave] = helpP;
+            attrib(SaveRed, "isSB",1);
+          }
+          B[j]=0;
+          ReducedCandidates[j]=0;
+          Indicator[j]=0;
+        }
+      }  // if i>IrrSwitch
+      else  // use fast algorithm
+      { B=sort_of_invariant_basis(sP,REY,i,max); // B contains images of
+                                       // kbase(sP,i) under the Reynolds
+                                       // operator that are linearly independent
+                                       // and that don't reduce to 0 modulo sP
+        j=0;                         // j goes through all of B -
+        // Compare the comments on the computation of reducible sec. inv.!
+        ReducedCandidates = reduce(B,sP);
+        Indicator = reduce(ReducedCandidates,SaveRed);
+        ii = ncols(Indicator);
+        while ((j<ii) and (counter < max))
+        { j++;
+          helpP = Indicator[j];
+          if (helpP <>0)                  // B[j] should be added
+          { counter++;
+            S[counter] = B[j];
+            if (v)
+            { "    We found sec. inv. number ",counter," in degree ",i;
+            }
+            if (counter == max) {break;}
+            Reductor = ideal(helpP);
+            attrib(Reductor, "isSB",1);
+            Indicator=reduce(Indicator,Reductor);
+            SizeSave++;
+            SaveRed[SizeSave] = helpP;
+            attrib(SaveRed, "isSB",1);
+          }
+          B[j]=0;
+          ReducedCandidates[j]=0;
+          Indicator[j]=0;
+        }
+      } // i<=IrrSwitch
+    }
+    else // if deg_vec[k]=i:
+    { if (size(deg_vec)==k)
+      { k=1; }
+      else
+      { k++; }
+    }
+  }
+  if (v)
+  { ""; }
+  if (v)
+  { "  We're done!"; ""; }
+  degBound = dgb;
+  return(matrix(S));
+}
+example
+{ "EXAMPLE: Sturmfels: Algorithms in Invariant Theory 2.3.7:"; echo=2;
+         ring R=3,(x,y,z),dp;
+         matrix A[3][3]=0,1,0,-1,0,0,0,0,-1;
+         list L=primary_invariants(A,intvec(1,1,0));
+         // In that example, there are no secondary invariants
+         // in degree 1 or 2.
+         matrix S=secondary_no_molien(L[1..2],intvec(1,2),1);
+         print(S);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc secondary_and_irreducibles_no_molien (matrix P, matrix REY, list #)
+"USAGE:   secondary_and_irreducibles_no_molien(P,REY[,deg_vec,v]);
+         P: a 1xn <matrix> with primary invariants, REY: a gxn <matrix>
+         representing the Reynolds operator, deg_vec: an optional <intvec>
+         listing some degrees where no non-trivial homogeneous invariants can
+         be found, v: an optional <int>
+ASSUME:  n is the number of variables of the basering, g the size of the group,
+         REY is the 1st return value of group_reynolds(), reynolds_molien() or
+         the second one of primary_invariants()
+RETURN:  secondary invariants of the invariant ring (type <matrix>) and
+         irreducible secondary invariants (type <matrix>)
+DISPLAY: information if v does not equal 0
+THEORY:  Secondary invariants are calculated by finding a basis (in terms of
+         monomials) of the basering modulo primary invariants, mapping those to
+         invariants with the Reynolds operator. Among these images
+         or their power products we pick secondary invariants using Groebner
+         basis techniques (see S. King: Fast Computation of Secondary Invariants).
+         We have the Reynolds operator, hence, we are in the non-modular case.
+         Therefore, the invariant ring is Cohen-Macaulay, hence the number of
+         secondary invariants is the product of the degrees of primary invariants
+         divided by the group order.
+SEE ALSO: secondary_no_molien
+EXAMPLE: example secondary_and_irreducibles_no_molien; shows an example
+"
+{ int pieces = 3;    // For generating reducible secondaries, blocks of #pieces# secondaries
+                     // are formed.
+                     // If this parameter is small, the memory consumption will decrease.
+  int MonStep = 15;  // The Reynolds operator is applied to blocks of #MonStep# monomials.
+                     // If this parameter is small, the memory consumption will decrease.
+  int IrrSwitch = 7; // Up to degree #IrrSwitch#-1, we use a method for generating
+                     // irreducible secondaries that tends to produce a smaller output
+                     // (which is good for subsequent computations). However, this method
+                     // needs to much memory in high degrees, and so we use a sparser method
+                     // from degree #IrrSwitch# on.
+  int i;
+  def br=basering;
+ //------------------ checking input and setting verbose ----------------------
+  if (size(#)==1 or size(#)==2)
+  { if (typeof(#[size(#)])=="int")
+    { if (size(#)==2)
+      { if (typeof(#[size(#)-1])=="intvec")
+        { intvec deg_vec=#[size(#)-1];
+        }
+        else
+        { "ERROR:   the third parameter should be an <intvec>";
+          return();
+        }
+      }
+      int v=#[size(#)];
+    }
+    else
+    { if (size(#)==1)
+      { if (typeof(#[size(#)])=="intvec")
+        { intvec deg_vec=#[size(#)];
+          int v=0;
+        }
+        else
+        { "ERROR:   the third parameter should be an <intvec>";
+          return();
+        }
+      }
+      else
+      { "ERROR:   wrong list of parameters";
+        return();
+      }
+    }
+  }
+  else
+  { if (size(#)>2)
+    { "ERROR:   there are too many parameters";
+      return();
+    }
+    int v=0;
+  }
+  int n=nvars(basering);               // n is the number of variables, as well
+                                       // as the size of the matrices, as well
+                                       // as the number of primary invariants,
+                                       // we should get
+  if (ncols(P)<>n)
+  { "ERROR:   The first parameter ought to be the matrix of the primary";
+    "         invariants."
+    return();
+  }
+  if (ncols(REY)<>n)
+  { "ERROR:   The second parameter ought to be the Reynolds operator.";
+    return();
+  }
+  if (char(br)<>0)
+  { if (nrows(REY) mod char(br) == 0)
+    { "ERROR:   We need to be in the non-modular case.";
+      return();
+    }
+  }
+  else
+  { "WARNING: In char 0, secondary_char0 should be faster.";
+  }
+  if (v && voice==2)
+  { "";
+  }
+  int j, m, d;
+  int max=1;
+  for (j=1;j<=n;j++)
+  { max=max*deg(P[j]);
+  }
+  max=max div nrows(REY);
+  if (v)
+  { "  We need to find ",max," secondary invariants.";
+    "";
+    "In degree 0 we have: 1";
+    "";
+  }
+ //-------------------------- initializing variables --------------------------
+  ideal ProdCand;          // contains products of secondary invariants,
+                           // i.e., candidates for reducible sec. inv.
+  ideal Mul1,Mul2;
+
+  int dgb=degBound;
+  degBound = 0;
+  intvec saveopt=option(get);
+  option(redSB);
+  ideal sP = groebner(ideal(P));
+                           // This is the only explicit Groebner basis computation!
+  ideal Reductor,SaveRed;  // sP union Reductor is a Groebner basis up to degree i-1
+  int SizeSave;
+
+  list SSort;         // sec. inv. first sorted by degree and then sorted by the
+                      // minimal degree of a non-constant invariant factor.
+  list ISSort;        // irr. sec. inv. sorted by degree
+
+  poly helpP;
+  ideal helpI;
+  ideal Indicator;        // will tell us which candidates for sec. inv. we can choose
+  ideal ReducedCandidates;
+  int helpint;
+  int k,k2,k3,minD;
+  int ii;
+  int saveAttr;
+  ideal mon,B,IS;              // IS will contain all irr. sec. inv.
+
+  int counter=1;
+  int irrcounter;
+  i=1;      // the degree under consideration is i-1
+  SSort[i] = list();
+  for (k=1;k<=i;k++)
+  { SSort[i][k]=ideal();
+    attrib(SSort[i][k],"size",0);
+  }
+
+  if (defined(deg_vec)<>voice)
+  { intvec deg_vec;
+  }
+  int l=1;
+ //------------------- generating secondary invariants ------------------------
+  while (counter<>max)
+  { i++;
+    SSort[i] = list();
+    for (k=1;k<=i;k++)
+    { SSort[i][k]=ideal();
+      attrib(SSort[i][k],"size",0);
+    }
+    if (deg_vec[l]<>i-1)
+    { if (v)
+      { "Searching in degree ",i-1;
+        "  Looking for Power Products...";
+      }
+      Reductor = ideal(0);
+      helpint = 0;
+      SaveRed = Reductor;
+      SizeSave = 0;
+      attrib(Reductor,"isSB",1);
+      attrib(SaveRed,"isSB",1);
+// We start searching for reducible secondary invariants in degree i-1, i.e., those
+// that are power products of irreducible secondary invariants.
+// It suffices to restrict the search at products of one _irreducible_ sec. inv. (Mul1)
+// with some sec. inv. (Mul2).
+// Moreover, we avoid to consider power products twice since we take a product
+// into account only if the minimal degree of a non-constant invariant factor in "Mul2" is not
+// smaller than the degree of "Mul1".
+      for (k=1;k<i-1;k++)
+      { if (max==counter)
+        { break;
+        }
+        if (typeof(ISSort[k])<>"none")
+        { Mul1 = ISSort[k];
+        }
+        else
+        { Mul1 = ideal(0);
+        }
+        if (Mul1[1]<>0)
+        { for (minD=k;minD<i-k;minD++)
+          { if (max==counter)
+            { break;
+            }
+            for (k2=1;k2 <= ((attrib(SSort[i-k-1][minD],"size")-1) div pieces)+1; k2++)
+            { if (max==counter)
+              { break;
+              }
+              Mul2=ideal(0);
+              if (attrib(SSort[i-k-1][minD],"size")>=k2*pieces)
+              { for (k3=1;k3<=pieces;k3++)
+                { Mul2[k3] = SSort[i-k-1][minD][((k2-1)*pieces)+k3];
+                }
+              }
+              else
+              { for (k3=1;k3<=(attrib(SSort[i-k-1][minD],"size") mod pieces);k3++)
+                { Mul2[k3] = SSort[i-k-1][minD][((k2-1)*pieces)+k3];
+                }
+              }
+              ProdCand = simplify(Mul1*Mul2,4);
+              ReducedCandidates = reduce(ProdCand,sP);
+                  // sP union SaveRed union Reductor is a homogeneous Groebner basis
+                  // up to degree i-1.
+                  // We first reduce by sP (which is fixed, so we can do it once for all),
+                  // then by SaveRed resp. by Reductor (which is modified during
+                  // the computations).
+              Indicator = reduce(ReducedCandidates,SaveRed);
+                             // If Indicator[ii]==0 then ReducedCandidates it the reduction
+                             // of an invariant that is in the algebra generated by primary
+                             // invariants and previously computed secondary invariants.
+                             // Otherwise ProdCand[ii] can be taken as secondary invariant.
+              if (size(Indicator)<>0)
+              { for (ii=1;ii<=ncols(ProdCand);ii++)     // going through all the power products
+                { helpP = Indicator[ii];
+                  if (helpP <> 0)
+                  { counter++;
+                    saveAttr = attrib(SSort[i-1][k],"size")+1;
+                    SSort[i-1][k][saveAttr] = ProdCand[ii];
+                        // By construction, this is a _reducible_ s.i.
+                    attrib(SSort[i-1][k],"size",saveAttr);
+                    if (v)
+                    { "    We found sec. inv. number",counter, "in degree",i-1;
+                    }
+                    if (max<>counter)
+                    { Reductor = ideal(helpP);
+                        // Lemma: If G is a homogeneous Groebner basis up to degree i-1 and p is a
+                        // homogeneous polynomial of degree i-1 then G union NF(p,G) is
+                        // a homogeneous Groebner basis up to degree i-1.
+                      attrib(Reductor, "isSB",1);
+                        // if Reductor becomes too large, we reduce the whole of Indicator by
+                        // it, save it in SaveRed, and work with a smaller Reductor. This turns
+                        // out to save a little time.
+                      Indicator=reduce(Indicator,Reductor);
+                      SizeSave++;
+                      SaveRed[SizeSave] = helpP;
+                      attrib(SaveRed, "isSB",1);
+                    }
+                    else
+                    { break;
+                    }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+
+      // The remaining sec. inv. are irreducible!
+      if (max<>counter)
+      { if (v)
+        { "  Looking for irreducible secondary invariants in degree ", i-1;
+        }
+        mon = kbase(sP,i-1);
+        ii = ncols(mon);
+        if ((i>IrrSwitch) or (ii>200)) // use sparse algorithm
+        { irrcounter=0;
+          j=0;                         // j goes through all of mon -
+          // Compare the comments on the computation of reducible sec. inv.!
+          while ((j<ii) and (max<>counter))
+          { if ((j mod MonStep) == 0)
+            { if ((j+MonStep) <= ii)
+              { ideal tmp = normalize(evaluate_reynolds(REY,ideal(mon[j+1..j+MonStep])));
+                B[j+1..j+MonStep] = tmp[1..MonStep];
+                tmp = reduce(tmp,sP);
+                ReducedCandidates[j+1..j+MonStep] = tmp[1..MonStep];
+                tmp = reduce(tmp,SaveRed);
+                Indicator[j+1..j+MonStep] = tmp[1..MonStep];
+                kill tmp;
+              }
+              else
+              { ideal tmp = normalize(evaluate_reynolds(REY,ideal(mon[j+1..ii])));
+                B[j+1..ii] = tmp[1..ii-j];
+                tmp = reduce(tmp,sP);
+                ReducedCandidates[j+1..ii] = tmp[1..ii-j];
+                tmp = reduce(tmp,SaveRed);
+                Indicator[j+1..ii] = tmp[1..ii-j];
+                kill tmp;
+              }
+            }
+            j++;
+            helpP = Indicator[j];
+            if (helpP <>0)                  // B[j] should be added
+            { counter++; irrcounter++;
+              IS=IS,B[j];
+              saveAttr = attrib(SSort[i-1][i-1],"size")+1;
+              SSort[i-1][i-1][saveAttr] = B[j];
+              attrib(SSort[i-1][i-1],"size",saveAttr);
+              if (typeof(ISSort[i-1]) <> "none")
+              { ISSort[i-1][irrcounter] = B[j];
+              }
+              else
+              { ISSort[i-1] = ideal(B[j]);
+              }
+              if (v)
+              { "    We found irreducible sec. inv. number", irrcounter, "in degree", i-1;
+              }
+              if (counter == max) { break; }
+              Reductor = ideal(helpP);
+              attrib(Reductor, "isSB",1);
+              Indicator=reduce(Indicator,Reductor);
+              SizeSave++;
+              SaveRed[SizeSave] = helpP;
+              attrib(SaveRed, "isSB",1);
+            }
+            B[j]=0;
+            ReducedCandidates[j]=0;
+            Indicator[j]=0;
+          }
+        }  // if i>IrrSwitch
+        else  // use fast algorithm
+        { B=sort_of_invariant_basis(sP,REY,i-1,max);
+                                       // B contains
+                                       // images of kbase(sP,i-1) under the
+                                       // Reynolds operator that are linearly
+                                       // independent
+          irrcounter=0;
+          j=0;                         // j goes through all of B -
+          // Compare the comments on the computation of reducible sec. inv.!
+          ReducedCandidates = reduce(B,sP);
+          Indicator = reduce(ReducedCandidates,SaveRed);
+          ii = ncols(Indicator);
+          while ((j<ii) and (max<>counter))
+          { j++;
+            helpP = Indicator[j];
+            if (helpP <>0)                  // B[j] should be added
+            { counter++; irrcounter++;
+              IS=IS,B[j];
+              saveAttr = attrib(SSort[i-1][i-1],"size")+1;
+              SSort[i-1][i-1][saveAttr] = B[j];
+              attrib(SSort[i-1][i-1],"size",saveAttr);
+              if (typeof(ISSort[i-1]) <> "none")
+              { ISSort[i-1][irrcounter] = B[j];
+              }
+              else
+              { ISSort[i-1] = ideal(B[j]);
+              }
+              if (v)
+              { "    We found irreducible sec. inv. number", irrcounter, "in degree", i-1;
+              }
+              Reductor = ideal(helpP);
+              attrib(Reductor, "isSB",1);
+              Indicator=reduce(Indicator,Reductor);
+              SizeSave++;
+              SaveRed[SizeSave] = helpP;
+              attrib(SaveRed, "isSB",1);
+            }
+            if (max == counter) { break;}
+            B[j]=0;
+            ReducedCandidates[j]=0;
+            Indicator[j]=0;
+          }
+        } // i<=IrrSwitch
+      } // Computation of irreducible secondaries
+      if (v)
+      { "";
+      }
+    } // if (deg_vec[l]<>i-1)
+    else
+    { if (size(deg_vec)==l)
+      { l=1;
+      }
+      else
+      { l++;
+      }
+    }
+  } // while counter <> max
+  if (v)
+  { "";
+  }
+  if (v)
+  { "  We're done!";
+    "";
+  }
+  degBound = dgb;
+  // Prepare return:
+  matrix S[1][max];
+  S[1,1]=1;
+  j=1;
+  k=1;
+  while (j<>max)
+  { for (k2=1;k2<=k;k2++)
+    { if (typeof(attrib(SSort[k][k2],"size"))=="int")
+      { for (i=1;i<=attrib(SSort[k][k2],"size");i++)
+        { j++;
+          S[1,j] = SSort[k][k2][i];
+        }
+        SSort[k][k2]=ideal();
+      }
+    }
+    k++;
+  }
+  return(S,matrix(compress(IS)));
+}
+
+example
+{ "EXAMPLE: Sturmfels: Algorithms in Invariant Theory 2.3.7:"; echo=2;
+         ring R=3,(x,y,z),dp;
+         matrix A[3][3]=0,1,0,-1,0,0,0,0,-1;
+         list L=primary_invariants(A,intvec(1,1,0));
+         // In that example, there are no secondary invariants
+         // in degree 1 or 2.
+         matrix S,IS=secondary_and_irreducibles_no_molien(L[1..2],intvec(1,2),1);
+         print(S);
+         print(IS);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc irred_secondary_no_molien (matrix P, matrix REY, list #)
+"USAGE:   irred_secondary_no_molien(P,REY[,deg_vec,v]);
+         P: a 1xn <matrix> with primary invariants, REY: a gxn <matrix>
+         representing the Reynolds operator, deg_vec: an optional <intvec>
+         listing some degrees where no irreducible secondary invariants can
+         be found, v: an optional <int>
+ASSUME:  n is the number of variables of the basering, g the size of the group,
+         REY is the 1st return value of group_reynolds(), reynolds_molien() or
+         the second one of primary_invariants()
+RETURN:  Irreducible secondary invariants of the invariant ring (type <matrix>)
+DISPLAY: information if v does not equal 0
+THEORY:  Irred. secondary invariants are calculated by finding a basis (in terms of
+         monomials) of the basering modulo primary and previously found secondary
+         invariants, mapping those to invariants with the Reynolds operator. Among
+         these images we pick secondary invariants, using Groebner basis
+         techniques.
+SEE ALSO: irred_secondary_char0
+EXAMPLE: example irred_secondary_no_molien; shows an example
+"
+{ int MonStep = 29;
+
+  def br=basering;
+ //------------------ checking input and setting verbose ----------------------
+  if (size(#)==1 or size(#)==2)
+  { if (typeof(#[size(#)])=="int")
+    { if (size(#)==2)
+      { if (typeof(#[size(#)-1])=="intvec")
+        { intvec deg_vec=#[size(#)-1];
+        }
+        else
+        { "ERROR:   the third parameter should be an <intvec>";
+          return();
+        }
+      }
+      int v=#[size(#)];
+    }
+    else
+    { if (size(#)==1)
+      { if (typeof(#[size(#)])=="intvec")
+        { intvec deg_vec=#[size(#)];
+          int v=0;
+        }
+        else
+        { "ERROR:   the third parameter should be an <intvec>";
+          return();
+        }
+      }
+      else
+      { "ERROR:   wrong list of parameters";
+        return();
+      }
+    }
+  }
+  else
+  { if (size(#)>2)
+    { "ERROR:   there are too many parameters";
+      return();
+    }
+    int v=0;
+  }
+  int n=nvars(basering);               // n is the number of variables, as well
+                                       // as the size of the matrices, as well
+                                       // as the number of primary invariants,
+                                       // we should get
+  if (ncols(P)<>n)
+  { "ERROR:   The first parameter ought to be the matrix of the primary";
+    "         invariants."
+    return();
+  }
+  if (ncols(REY)<>n)
+  { "ERROR:   The second parameter ought to be the Reynolds operator.";
+    return();
+  }
+  if (char(br)<>0)
+  { if (nrows(REY) mod char(br) == 0)
+    { "ERROR:   We need to be in the non-modular case.";
+      return();
+    }
+  }
+  if (v && voice==2)
+  { "";
+  }
+  if (defined(deg_vec)<>voice)
+  { intvec deg_vec;
+  }
+  int l=1;
+
+ //-------------------------- initializing variables --------------------------
+
+  int dgb = degBound;
+  degBound = 0;
+  int d,block, counter, totalcount, monsize,i,j, fin,hlp;
+  poly helpP,lmp;
+  block = 1;
+  ideal mon, MON, Inv, IS,RedInv, NewIS, NewReductor;
+  int NewIScounter;
+  ideal sP = slimgb(ideal(P));
+  int Max = vdim(sP);
+  if (Max<0)
+  { ERROR("The first parameter ought to be a matrix of primary invariants.");
+  }
+  ideal sIS = sP;   // sIS will be a Groebner basis up to degree d of P+irred. sec. inv.
+  while (totalcount < Max)
+  { d++;
+    if (deg_vec[l]<>d)
+    { if (v) { "Searching irred. sec. inv. in degree ",d; }
+      NewIS = ideal();
+      NewIScounter=0;
+      MON = kbase(sP,d);
+      mon = kbase(sIS,d);
+      monsize=ncols(mon);
+      totalcount = totalcount + ncols(MON);
+      if (mon[1]<>0)
+      {
+        if (v) { "  We have ",monsize," candidates for irred. secondaries";}
+        block=0; // Loops through the monomials
+        while (block<monsize)
+        { if ((block mod MonStep) == 0)
+          { if ((block+MonStep) <= monsize)
+            { ideal tmp = normalize(evaluate_reynolds(REY,ideal(mon[block+1..block+MonStep])));
+              Inv[block+1..block+MonStep] = tmp[1..MonStep];
+              tmp = reduce(tmp,sIS);
+              RedInv[block+1..block+MonStep] = tmp[1..MonStep];
+              kill tmp;
+            }
+            else
+            { ideal tmp = normalize(evaluate_reynolds(REY,ideal(mon[block+1..monsize])));
+              Inv[block+1..monsize] = tmp[1..monsize-block];
+              tmp = reduce(tmp,sIS);
+              RedInv[block+1..monsize] = tmp[1..monsize-block];
+              kill tmp;
+            }
+          }
+          block++;
+          helpP = RedInv[block];
+          if (helpP<>0)
+          { counter++; // found new irr. sec. inv.!
+            if (v) { "    We found irr. sec. inv. number ",counter," in degree ",d; }
+            IS[counter] = Inv[block];
+            sIS = sIS,helpP;
+            attrib(sIS,"isSB",1);
+            NewIScounter++;
+            NewIS[NewIScounter] = helpP;
+            mon[block]=0;
+            Inv[block]=0;
+            RedInv[block]=0;
+            NewReductor[1]=helpP;
+            attrib(NewReductor,"isSB",1);
+            RedInv = reduce(RedInv,NewReductor);
+          }
+        } // loop through monomials
+      } // if mon[1]<>0
+      if (totalcount < Max)
+      { if (NewIScounter==0)
+        { if (fin==0)
+          { degBound = 0;
+            sIS = groebner(sIS);
+            fin=1;
+          }
+        }
+        else
+        { degBound = d+1;
+          sIS = groebner(sIS+NewIS);
+          degBound = 0;
+          fin = 0;
+        }
+      }
+      attrib(sIS,"isSB",1);
+    } // if degree d is not excluded by deg_vec
+    else
+    { if (size(deg_vec)==l)
+      { l=1;
+      }
+      else
+      { l++;
+      }
+    }
+  } // loop through degree
+  degBound = dgb;
+  return(matrix(IS));
+}
+
+example
+{ "EXAMPLE: Sturmfels: Algorithms in Invariant Theory 2.3.7:"; echo=2;
+         ring R=3,(x,y,z),dp;
+         matrix A[3][3]=0,1,0,-1,0,0,0,0,-1;
+         list L=primary_invariants(A,intvec(1,1,0));
+         // In that example, there are no secondary invariants
+         // in degree 1 or 2.
+         matrix IS=irred_secondary_no_molien(L[1..2],intvec(1,2),1);
+         print(IS);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc secondary_not_cohen_macaulay (matrix P, list #)
+"USAGE:   secondary_not_cohen_macaulay(P,G1,G2,...[,v]);
+         P: a 1xn <matrix> with primary invariants, G1,G2,...: nxn <matrices>
+         generating a finite matrix group, v: optional <int>
+ASSUME:  n is the number of variables of the basering
+RETURN:  secondary invariants of the invariant ring (type <matrix>)
+DISPLAY: information on the progress of computation if v does not equal 0
+THEORY:  Secondary invariants are generated following \"Generating Invariant
+         Rings of Finite Groups over Arbitrary Fields\" by Kemper (1996).
+EXAMPLE: example secondary_not_cohen_macaulay; shows an example
+"
+{ int i, j;
+  int v;
+  degBound=0;
+  def br=basering;
+  int n=nvars(br);                     // n is the number of variables, as well
+                                       // as the size of the matrices, as well
+                                       // as the number of primary invariants,
+                                       // we should get -
+  if (size(#)>0)                       // checking input and setting verbose
+  { if (typeof(#[size(#)])=="int")
+    { int gen_num=size(#)-1;
+      v=#[size(#)];
+      if (gen_num==0)
+      { "ERROR:   There are no generators of the finite matrix group given.";
+        return();
+      }
+      for (i=1;i<=gen_num;i++)
+      { if (typeof(#[i])<>"matrix")
+        { "ERROR:   These parameters should be generators of the finite matrix group.";
+          return();
+        }
+        if ((n<>nrows(#[i])) or (n<>ncols(#[i])))
+        { "ERROR:   matrices need to be square and of the same dimensions";
+          return();
+        }
+      }
+    }
+    else
+    { int gen_num=size(#);
+      for (i=1;i<=gen_num;i++)
+      { if (typeof(#[i])<>"matrix")
+        { "ERROR:   These parameters should be generators of the finite matrix group.";
+          return();
+        }
+        if ((n<>nrows(#[i])) or (n<>ncols(#[i])))
+        { "ERROR:   matrices need to be square and of the same dimensions";
+          return();
+        }
+      }
+    }
+  }
+  else
+  { "ERROR:   There are no generators of the finite matrix group given.";
+    return();
+  }
+  if (ncols(P)<>n)
+  { "ERROR:   The first parameter ought to be the matrix of the primary";
+    "         invariants."
+    return();
+  }
+  if (v && voice==2)
+  { "";
+  }
+  // ring alskdfalkdsj=0,x,dp;
+  // matrix M[1][2]=1,(1-x)^n;
+  // export alskdfalkdsj;
+  // export M;                            // we look at our primary invariants as
+  // setring br;                          // such of the subgroup that only
+  // matrix REY=matrix(maxideal(1));      // contains the identity, this means that
+                                       // ch does not divide the order anymore,
+                                       // this means that we can make use of the
+                                       // Molien series again - M[1,1]/M[1,2] is
+                                       // the Molien series of that group, we
+                                       // now calculate the secondary invariants
+                                       // of this subgroup in the usual fashion
+                                       // where the primary invariants are the
+                                       // ones from the bigger group
+  if (v)
+  { "  First, get secondary invariants for the trivial action, with respect to";
+    "  the primary invariants found previously. By the graded Nakayama lemma,";
+    "  this means to compute the standard monomials for the ideal generated by";
+    "  the primary invariants.";
+    "";
+  }
+  ideal GP = groebner(ideal(P));
+  if (dim(GP)<>0)
+  { "ERROR:   The ideal spanned by primary invariants of a finite group";
+    "         always is of dimension zero.";
+    return();
+  }
+  matrix trivialS = matrix(kbase(GP));// , trivialIS=secondary_charp(P,REY,"alskdfalkdsj",v);
+  // kill trivialIS;
+  // kill alskdfalkdsj;
+  // now we have those secondary invariants
+  int k=ncols(trivialS);               // k is the number of the secondary
+                                       // invariants, we just calculated
+  if (v)
+  { "  We calculate secondary invariants from the ones found for the trivial";
+    "  subgroup.";
+    "";
+  }
+  map f;                               // used to let generators act on
+                                       // secondary invariants with respect to
+                                       // the trivial group -
+  matrix M(1)[gen_num][k];             // M(1) will contain a module
+  ideal B;
+  for (i=1;i<=gen_num;i++)
+  { B=ideal(matrix(maxideal(1))*transpose(#[i])); // image of the various
+                                       // variables under the i-th generator -
+    f=br,B;                            // the corresponding mapping -
+    B=f(trivialS)-trivialS;            // these relations should be 0 -
+    M(1)[i,1..k]=B[1..k];              // we will look for the syzygies of M(1)
+  }
+//  intvec save_opts=option(get);
+//  option(returnSB,redSB);
+//  module M(2)=syz(M(1));               // nres(M(1),2)[2];
+//  option(set,save_opts);
+  if (v)
+  { "Syzygies of the \"trivial\" secondaries"; }
+  module M(2)=nres(M(1),2)[2];
+  int m=ncols(M(2));                   // number of generators of the module
+                                       // M(2) -
+  // the following steps calculates the intersection of the module M(2) with
+  // the algebra A^k where A denote the subalgebra of the usual polynomial
+  // ring, generated by the primary invariants
+
+  // generate a ring where we can do elimination
+  // in order to make it weighted homogeneous, we choose appropriate weights
+  if (v)
+  { "By elimination: Intersect with the invariant ring"; }
+  intvec dv = degvec(ideal(P)),1;
+  ring newR = char(br), (y(1..n),h),(a(dv),dp);
+  def R = br + newR;
+  setring R;
+  matrix P=fetch(br,P);                       // primary invariants in the new ring
+  ideal ElimP;
+  for (i=1;i<=n;i++)
+  { ElimP[i]=y(i)-P[1,i]; }
+  def RHilb = newR+br; // the new variables only appear linearly, so that block order wouldn't hurt
+  setring RHilb;
+  ideal ElimP=imap(R,ElimP);
+  intvec EPvec = hilb(groebner(ElimP),1,degvec(maxideal(1)));
+  setring R;
+  ideal GElimP = std(ElimP,EPvec,degvec(maxideal(1)));
+  attrib(GElimP,"isSB",1);
+  int newN = ncols(GElimP);
+  matrix M[k][m+k*newN];
+  M[1..k,1..m]=matrix(imap(br,M(2)));        // will contain a module -
+  for (i=1;i<=newN;i++)
+  { for (j=1;j<=k;j++)
+    { M[j,m+(i-1)*k+j]=GElimP[i]; // y(i)-P[1,i];
+    }
+  }
+  M=elim2(module(M),1..n);   // eliminating x(1..n), std-calculation
+                            // is done internally -
+  //M=std(module(M));                // we have already an elimination ordering
+  //M=nselect(M,1..n);
+  M=homog(module(M),h);            // homogenize for 'minbase'
+  M=minbase(module(M));
+  ideal substitute;
+  for (i=1;i<=n;i++)
+  { substitute[i]=var(i);
+  }
+  substitute = substitute,ideal(P),1;
+  map f=R,substitute;                      // replacing y(1..n) by primary
+                                       // invariants and h by 1 -
+  M=f(M);                              // we can't directly map from R to br
+  setring br;                          // if there is a minpoly.
+  module M(3)=imap(R,M);                     // M(2) is the new module
+  m=ncols(M(3));
+  matrix S[1][m];
+  S=matrix(trivialS)*matrix(M(3));     // S now contains the secondary
+                                       // invariants
+  for (i=1; i<=m;i++)
+  { S[1,i]=S[1,i]/leadcoef(S[1,i]);    // making elements nice
+  }
+  S=sort(ideal(S))[1];
+  if (v)
+  { "  These are the secondary invariants: ";
+    for (i=1;i<=m;i++)
+    { "   "+string(S[1,i]);
+    }
+    "";
+    "  We're done!";
+    "";
+  }
+  if ((v or (voice==2)) && (m>1))
+  { "  WARNING: The invariant ring might not have a Hironaka decomposition";
+    "           if the characteristic of the coefficient field divides the";
+    "           group order.";
+  }
+  return(matrix(S));
+}
+example
+{ "EXAMPLE:"; echo=2;
+           ring R=2,(x,y,z),dp;
+           matrix A[3][3]=0,1,0,-1,0,0,0,0,-1;
+           list L=primary_invariants(A);
+           matrix S=secondary_not_cohen_macaulay(L[1],A);
+           print(S);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc invariant_ring (list #)
+"USAGE:   invariant_ring(G1,G2,...[,flags]);
+         G1,G2,...: <matrices> generating a finite matrix group, flags: an
+         optional <intvec> with three entries: if the first one equals 0, the
+         program attempts to compute the Molien series and Reynolds operator,
+         if it equals 1, the program is told that the Molien series should not
+         be computed, if it equals -1 characteristic 0 is simulated, i.e. the
+         Molien series is computed as if the base field were characteristic 0
+         (the user must choose a field of large prime characteristic, e.g.
+         32003) and if the first one is anything else, it means that the
+         characteristic of the base field divides the group order (i.e. it will
+         not even be attempted to compute the Reynolds operator or Molien
+         series), the second component should give the size of intervals
+         between canceling common factors in the expansion of Molien series, 0
+         (the default) means only once after generating all terms, in prime
+         characteristic also a negative number can be given to indicate that
+         common factors should always be canceled when the expansion is simple
+         (the root of the extension field occurs not among the coefficients)
+RETURN:  primary and secondary invariants for any matrix representation of a
+         finite group
+DISPLAY: information about the various stages of the program if the third flag
+         does not equal 0
+THEORY:  Bases of homogeneous invariants are generated successively and those
+         are chosen as primary invariants that lower the dimension of the ideal
+         generated by the previously found invariants (see \"Generating a
+         Noetherian Normalization of the Invariant Ring of a Finite Group\" by
+         Decker, Heydtmann, Schreyer (1998)). In the
+         non-modular case secondary invariants are calculated by finding a
+         basis (in terms of monomials) of the basering modulo the primary
+         invariants, mapping to invariants with the Reynolds operator and using
+         those or their power products such that they are linearly independent
+         modulo the primary invariants (see \"Some Algorithms in Invariant
+         Theory of Finite Groups\" by Kemper and Steel (1997)). In the modular
+         case they are generated according to \"Generating Invariant Rings of
+         Finite Groups over Arbitrary Fields\" by Kemper (1996).
+EXAMPLE: example invariant_ring; shows an example
+"
+{ if (size(#)==0)
+  { "ERROR:   There are no generators given.";
+    return();
+  }
+  int ch=char(basering);               // the algorithms depend very much on the
+                                       // characteristic of the ground field -
+  int n=nvars(basering);               // n is the number of variables, as well
+                                       // as the size of the matrices, as well
+                                       // as the number of primary invariants,
+                                       // we should get
+  int gen_num;
+  int mol_flag, v;
+ //------------------- checking input and setting flags -----------------------
+  if (typeof(#[size(#)])=="intvec")
+  { if (size(#[size(#)])<>3)
+    { "ERROR:   The <intvec> should have three entries.";
+      return();
+    }
+    gen_num=size(#)-1;
+    mol_flag=#[size(#)][1];
+    if (#[size(#)][2]<0 && (ch==0 or (ch<>0 && mol_flag<>0)))
+    { "ERROR:   the second component of <intvec> should be >=0";
+      return();
+    }
+    int interval=#[size(#)][2];
+    v=#[size(#)][3];
+  }
+  else
+  { gen_num=size(#);
+    mol_flag=0;
+    int interval=0;
+    v=0;
+  }
+ //----------------------------------------------------------------------------
+  if (mol_flag==0)                     // calculation Molien series will be
+  { if (ch==0)                         // attempted -
+    { matrix REY,M=reynolds_molien(#[1..gen_num],intvec(0,interval,v)); // one
+                                       // will contain Reynolds operator and the
+                                       // other enumerator and denominator of
+                                       // Molien series
+      matrix P=primary_char0(REY,M,v);
+      matrix S,IS=secondary_char0(P,REY,M,v);
+      return(P,S,IS);
+    }
+    else
+    { list L=group_reynolds(#[1..gen_num],v);
+      if (L[1]<>0)                     // testing whether we are in the modular
+      { string newring="aksldfalkdsflkj"; // case
+        if (minpoly==0)
+        { if (v)
+          { "  We are dealing with the non-modular case.";
+          }
+          if (typeof(L[2])=="int")
+          { molien(L[3..size(L)],newring,L[2],intvec(0,interval,v));
+          }
+          else
+          { molien(L[2..size(L)],newring,intvec(0,interval,v));
+          }
+          matrix P=primary_charp(L[1],newring,v);
+          matrix S,IS=secondary_charp(P,L[1],newring,v);
+          if (defined(aksldfalkdsflkj)==2)
+          { kill aksldfalkdsflkj;
+          }
+          return(P,S,IS);
+        }
+        else
+        { if (v)
+          { "  Since it is impossible for this programme to calculate the Molien
+ series for";
+            "  invariant rings over extension fields of prime characteristic, we
+ have to";
+            "  continue without it.";
+            "";
+
+          }
+          list l=primary_charp_no_molien(L[1],v);
+          if (size(l)==2)
+          { matrix S,IS=secondary_and_irreducibles_no_molien(l[1],L[1],l[2],v);
+          }
+          else
+          { matrix S,IS=secondary_and_irreducibles_no_molien(l[1],L[1],v);
+          }
+          return(l[1],S,IS);
+        }
+      }
+      else                             // the modular case
+      { if (v)
+        { "  There is also no Molien series or Reynolds operator, we can make use of...";
+          "";
+          "  We can start looking for primary invariants...";
+          "";
+        }
+        matrix P=primary_charp_without(#[1..gen_num],v);
+        matrix S=secondary_not_cohen_macaulay(P,#[1..gen_num],v);
+        return(P,S);
+      }
+    }
+  }
+  if (mol_flag==1)                     // the user wants no calculation of the
+  { list L=group_reynolds(#[1..gen_num],v); // Molien series
+    if (ch==0)
+    { list l=primary_char0_no_molien(L[1],v);
+      if (size(l)==2)
+      { matrix S,IS=secondary_and_irreducibles_no_molien(l[1],L[1],l[2],v);
+      }
+      else
+      { matrix S,IS=secondary_and_irreducibles_no_molien(l[1],L[1],v);
+      }
+      return(l[1],S,IS);
+    }
+    else
+    { if (L[1]<>0)                     // testing whether we are in the modular
+      { list l=primary_charp_no_molien(L[1],v); // case
+        if (size(l)==2)
+        { matrix S,IS=secondary_and_irreducibles_no_molien(l[1],L[1],l[2],v);
+        }
+        else
+        { matrix S,IS=secondary_and_irreducibles_no_molien(l[1],L[1],v);
+        }
+        return(l[1],S,IS);
+      }
+      else                             // the modular case
+      { if (v)
+        { "  We can start looking for primary invariants...";
+          "";
+        }
+        matrix P=primary_charp_without(#[1..gen_num],v);
+        matrix S=secondary_not_cohen_macaulay(P,#[1..gen_num],v);
+        return(P,S);
+      }
+    }
+  }
+  if (mol_flag==-1)
+  { if (ch==0)
+    { "ERROR:   Characteristic 0 can only be simulated in characteristic p>>0.
+";
+      return();
+    }
+    list L=group_reynolds(#[1..gen_num],v);
+    string newring="aksldfalkdsflkj";
+    if (typeof(L[2])=="int")
+    { molien(L[3..size(L)],newring,L[2],intvec(1,interval,v));
+    }
+    else
+    { molien(L[2..size(L)],newring,intvec(1,interval,v));
+    }
+    matrix P=primary_charp(L[1],newring,v);
+    matrix S,IS=secondary_charp(P,L[1],newring,v);
+    kill aksldfalkdsflkj;
+    return(P,S,IS);
+  }
+  else                                 // the user specified that the
+  { if (ch==0)                         // characteristic divides the group order
+    { "ERROR:   The characteristic cannot divide the group order when it is 0.
+";
+      return();
+    }
+    if (v)
+    { "";
+    }
+    matrix P=primary_charp_without(#[1..gen_num],v);
+    matrix S=secondary_not_cohen_macaulay(P,#[1..gen_num],v);
+    return(L[1],S);
+  }
+}
+example
+{ "EXAMPLE: Sturmfels: Algorithms in Invariant Theory 2.3.7:"; echo=2;
+         ring R=0,(x,y,z),dp;
+         matrix A[3][3]=0,1,0,-1,0,0,0,0,-1;
+         matrix P,S,IS=invariant_ring(A);
+         print(P);
+         print(S);
+         print(IS);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc invariant_ring_random (list #)
+"USAGE:   invariant_ring_random(G1,G2,...,r[,flags]);
+         G1,G2,...: <matrices> generating a finite matrix group, r: an <int>
+         where -|r| to |r| is the range of coefficients of random
+         combinations of bases elements that serve as primary invariants,
+         flags: an optional <intvec> with three entries: if the first equals 0,
+         the program attempts to compute the Molien series and Reynolds
+         operator, if it equals 1, the program is told that the Molien series
+         should not be computed, if it equals -1 characteristic 0 is simulated,
+         i.e. the Molien series is computed as if the base field were
+         characteristic 0 (the user must choose a field of large prime
+         characteristic, e.g.  32003) and if the first one is anything else,
+         then the characteristic of the base field divides the group order
+         (i.e. we will not even attempt to compute the Reynolds operator or
+         Molien series), the second component should give the size of intervals
+         between canceling common factors in the expansion of the Molien
+         series, 0 (the default) means only once after generating all terms,
+         in prime characteristic also a negative number can be given to
+         indicate that common factors should always be canceled when the
+         expansion is simple (the root of the extension field does not occur
+         among the coefficients)
+RETURN:  primary and secondary invariants for any matrix representation of a
+         finite group
+DISPLAY: information about the various stages of the program if the third flag
+         does not equal 0
+THEORY:  is the same as for invariant_ring except that random combinations of
+         basis elements are chosen as candidates for primary invariants and
+         hopefully they lower the dimension of the previously found primary
+         invariants by the right amount.
+EXAMPLE: example invariant_ring_random; shows an example
+"
+{ if (size(#)<2)
+  { "ERROR:   There are too few parameters.";
+    return();
+  }
+  int ch=char(basering);               // the algorithms depend very much on the
+                                       // characteristic of the ground field
+  int n=nvars(basering);               // n is the number of variables, as well
+                                       // as the size of the matrices, as well
+                                       // as the number of primary invariants,
+                                       // we should get
+  int gen_num;
+  int mol_flag, v;
+ //------------------- checking input and setting flags -----------------------
+  if (typeof(#[size(#)])=="intvec" && typeof(#[size(#)-1])=="int")
+  { if (size(#[size(#)])<>3)
+    { "ERROR:   <intvec> should have three entries.";
+      return();
+    }
+    gen_num=size(#)-2;
+    mol_flag=#[size(#)][1];
+    if (#[size(#)][2]<0 && (ch==0 or (ch<>0 && mol_flag<>0)))
+    { "ERROR:   the second component of <intvec> should be >=0";
+      return();
+    }
+    int interval=#[size(#)][2];
+    v=#[size(#)][3];
+    int max=#[size(#)-1];
+    if (gen_num==0)
+    { "ERROR:   There are no generators of a finite matrix group given.";
+      return();
+    }
+  }
+  else
+  { if (typeof(#[size(#)])=="int")
+    { gen_num=size(#)-1;
+      mol_flag=0;
+      int interval=0;
+      v=0;
+      int max=#[size(#)];
+    }
+   else
+    { "ERROR:   If the two last parameters are not <int> and <intvec>, the last";
+      "         parameter should be an <int>.";
+      return();
+    }
+  }
+  for (int i=1;i<=gen_num;i++)
+  { if (typeof(#[i])=="matrix")
+    { if (nrows(#[i])<>n or ncols(#[i])<>n)
+      { "ERROR:   The number of variables of the base ring needs to be the same";
+        "         as the dimension of the square matrices";
+        return();
+      }
+    }
+    else
+    { "ERROR:   The first parameters should be a list of matrices";
+      return();
+    }
+  }
+ //----------------------------------------------------------------------------
+  if (mol_flag==0)
+  { if (ch==0)
+    { matrix REY,M=reynolds_molien(#[1..gen_num],intvec(0,interval,v)); // one
+                                       // will contain Reynolds operator and the
+                                       // other enumerator and denominator of
+                                       // Molien series
+      matrix P=primary_char0_random(REY,M,max,v);
+      matrix S,IS=secondary_char0(P,REY,M,v);
+      return(P,S,IS);
+    }
+    else
+    { list L=group_reynolds(#[1..gen_num],v);
+      if (L[1]<>0)                     // testing whether we are in the modular
+      { string newring="aksldfalkdsflkj"; // case
+        if (minpoly==0)
+        { if (v)
+          { "  We are dealing with the non-modular case.";
+          }
+          if (typeof(L[2])=="int")
+          { molien(L[3..size(L)],newring,L[2],intvec(0,interval,v));
+          }
+          else
+          { molien(L[2..size(L)],newring,intvec(0,interval,v));
+          }
+          matrix P=primary_charp_random(L[1],newring,max,v);
+          matrix S,IS=secondary_charp(P,L[1],newring,v);
+          if (voice==2)
+          { kill aksldfalkdsflkj;
+          }
+          return(P,S,IS);
+        }
+        else
+        { if (v)
+          { "  Since it is impossible for this programme to calculate the Molien
+ series for";
+            "  invariant rings over extension fields of prime characteristic, we
+ have to";
+            "  continue without it.";
+            "";
+
+          }
+          list l=primary_charp_no_molien_random(L[1],max,v);
+          if (size(l)==2)
+          { matrix S,IS=secondary_and_irreducibles_no_molien(l[1],L[1],l[2],v);
+          }
+          else
+          { matrix S,IS=secondary_and_irreducibles_no_molien(l[1],L[1],v);
+          }
+          return(l[1],S,IS);
+        }
+      }
+      else                             // the modular case
+      { if (v)
+        { "  There is also no Molien series, we can make use of...";
+          "";
+          "  We can start looking for primary invariants...";
+          "";
+        }
+        matrix P=primary_charp_without_random(#[1..gen_num],max,v);
+        matrix S=secondary_not_cohen_macaulay(P,#[1..gen_num],v);
+        return(P,S);
+      }
+    }
+  }
+  if (mol_flag==1)                     // the user wants no calculation of the
+  { list L=group_reynolds(#[1..gen_num],v); // Molien series
+    if (ch==0)
+    { list l=primary_char0_no_molien_random(L[1],max,v);
+      if (size(l)==2)
+      { matrix S,IS=secondary_and_irreducibles_no_molien(l[1],L[1],l[2],v);
+      }
+      else
+      { matrix S,IS=secondary_and_irreducibles_no_molien(l[1],L[1],v);
+      }
+      return(l[1],S,IS);
+    }
+    else
+    { if (L[1]<>0)                     // testing whether we are in the modular
+      { list l=primary_charp_no_molien_random(L[1],max,v); // case
+        if (size(l)==2)
+        { matrix S,IS=secondary_and_irreducibles_no_molien(l[1],L[1],l[2],v);
+        }
+        else
+        { matrix S,IS=secondary_and_irreducibles_no_molien(l[1],L[1],v);
+        }
+        return(l[1],S,IS);
+      }
+      else                             // the modular case
+      { if (v)
+        { "  We can start looking for primary invariants...";
+          "";
+        }
+        matrix P=primary_charp_without_random(#[1..gen_num],max,v);
+        matrix S=secondary_not_cohen_macaulay(P,#[1..gen_num],v);
+        return(L[1],S);
+      }
+    }
+  }
+  if (mol_flag==-1)
+  { if (ch==0)
+    { "ERROR:   Characteristic 0 can only be simulated in characteristic p>>0.
+";
+      return();
+    }
+    list L=group_reynolds(#[1..gen_num],v);
+    string newring="aksldfalkdsflkj";
+    if (typeof(L[2])=="int")
+    { molien(L[3..size(L)],newring,L[2],intvec(mol_flag,interval,v));
+    }
+    else
+    { molien(L[2..size(L)],newring,intvec(mol_flag,interval,v));
+    }
+    matrix P=primary_charp_random(L[1],newring,max,v);
+    matrix S,IS=secondary_charp(P,L[1],newring,v);
+    kill aksldfalkdsflkj;
+    return(P,S,IS);
+  }
+  else                                 // the user specified that the
+  { if (ch==0)                         // characteristic divides the group order
+    { "ERROR:   The characteristic cannot divide the group order when it is 0.
+";
+      return();
+    }
+    if (v)
+    { "";
+    }
+    matrix P=primary_charp_without_random(#[1..gen_num],max,v);
+    matrix S=secondary_not_cohen_macaulay(P,#[1..gen_num],v);
+    return(L[1],S);
+  }
+}
+example
+{ "EXAMPLE: Sturmfels: Algorithms in Invariant Theory 2.3.7:"; echo=2;
+         ring R=0,(x,y,z),dp;
+         matrix A[3][3]=0,1,0,-1,0,0,0,0,-1;
+         matrix P,S,IS=invariant_ring_random(A,1);
+         print(P);
+         print(S);
+         print(IS);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc orbit_variety (matrix F,string newring)
+"USAGE:   orbit_variety(F,s);
+         F: a 1xm <matrix> defing an invariant ring, s: a <string> giving the
+         name for a new ring
+RETURN:  a Groebner basis (type <ideal>, named G) for the ideal defining the
+         orbit variety (i.e. the syzygy ideal) in the new ring (named `s`)
+THEORY:  The ideal of algebraic relations of the invariant ring generators is
+         calculated, then the variables of the original ring are eliminated and
+         the polynomials that are left over define the orbit variety
+EXAMPLE: example orbit_variety; shows an example
+"
+{ if (newring=="")
+  { "ERROR:   the second parameter may not be an empty <string>";
+    return();
+  }
+  if (nrows(F)==1)
+  { def br=basering;
+    int n=nvars(br);
+    int m=ncols(F);
+    string mp=string(minpoly);
+    execute("ring R=("+charstr(br)+"),("+varstr(br)+",y(1..m)),dp;");
+    if (mp!="0")
+    { execute("minpoly=number("+mp+");"); }
+    ideal I=ideal(imap(br,F));
+    for (int i=1;i<=m;i++)
+    { I[i]=I[i]-y(i); }
+    I=elim(I,1..n);
+    execute("ring "+newring+"=("+charstr(br)+"),(y(1..m)),dp(m);");
+    if (mp!="0")
+    { execute("minpoly=number("+mp+");"); }
+    ideal vars;
+    for (i=2;i<=n;i++)
+    { vars[i]=0;
+    }
+    vars=vars,y(1..m);
+    map emb=R,vars;
+    ideal G=emb(I);
+    kill emb, vars, R;
+    keepring `newring`;
+    return();
+  }
+  else
+  { "ERROR:   the <matrix> may only have one row";
+    return();
+  }
+}
+example
+{ "EXAMPLE: Sturmfels: Algorithms in Invariant Theory 2.3.7:"; echo=2;
+         ring R=0,(x,y,z),dp;
+         matrix F[1][7]=x2+y2,z2,x4+y4,1,x2z-1y2z,xyz,x3y-1xy3;
+         string newring="E";
+         orbit_variety(F,newring);
+         print(G);
+         basering;
+}
+///////////////////////////////////////////////////////////////////////////////
+
+static proc degvec(ideal I)
+"USAGE:  degvec(I);
+         I an <ideal>.
+RETURN:  the <intvec> of degrees of the generators of I.
+"
+{ intvec v;
+  for (int j = 1;j<=ncols(I);j++)
+  { v[j]=deg(I[j]);
+  }
+  return(v);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc rel_orbit_variety(ideal I,matrix F,list #)
+"USAGE:    rel_orbit_variety(I,F[,s]);
+@*          I: an <ideal> invariant under the action of a group,
+@*          F: a 1xm <matrix> defining the invariant ring of this group.
+@*          s: optional <string>; if s is present then (for downward
+               compatibility) the old procedure <relative_orbit_variety>
+               is called, and in this case s gives the name of a new <ring>.
+RETURN:   Without optional string s, a list L of two rings is returned.
+@*        The ring L[1] carries a weighted degree order with variables
+            y(1..m), the weight of y(k) equal to the degree of the
+            k-th generators F[1,k] of the invariant ring.
+            L[1] contains a Groebner basis (type <ideal>, named G) of the
+            ideal defining the relative orbit variety with  respect to I.
+@*        The ring L[2] has the variables of the basering together with y(1..m)
+            and carries a block order: The first block is the order of the
+            basering, the second is the weighted degree order occuring in L[1].
+            L[2] contains G and a Groebner basis (type <ideal>, named Conv)
+            such that if p is any invariant polynomial expressed in the
+            variables of the basering then reduce(p,Conv) is a polynomial in
+            the new variables y(1..m) such that evaluation at the generators
+            of the invariant ring yields p. This can be used to avoid the
+            application of <algebra_containment>
+            (see @ref{algebra_containment}).
+@*        For the case of optional string s, the function is equivalent to
+          @ref{relative_orbit_variety}.
+THEORY:   A Groebner basis of the ideal of algebraic relations of the invariant
+          ring generators is calculated, then one of the basis elements plus
+          the ideal generators. The variables of the original ring are
+          eliminated and the polynomials that are left define the relative
+          orbit variety with respect to I. The elimination is done by a
+          weighted blockorder that has the advantage of dealing with
+          quasi-homogeneous ideals.
+NOTE:     We provide the ring L[1] for the sake of downward compatibility,
+          since it is closer to the ring returned by relative_orbit_variety
+          than L[2]. However, L[1] carries a weighted degree order, whereas
+          the ring returned by relative_orbit_variety is lexicographically
+          ordered.
+SEE ALSO: relative_orbit_variety
+EXAMPLE:  example rel_orbit_variety; shows an example.
+"
+{ if (size(#)>0)
+  { if (typeof(#[1])=="string")
+    { relative_orbit_variety(I,F,#[1]);
+      keepring basering;
+      return();
+    }
+    else
+    { "ERROR:    the third parameter may either be empty or a <string>.";
+      return();
+    }
+  }
+  degBound=0;
+  if (nrows(F)==1)
+  { option(redSB,noredTail);
+    def br=basering;
+    int n=nvars(br);
+    int m=ncols(F);
+    // In the following ring definition, any elimination order would work.
+    list rlist = ringlist(br);
+    int i;
+    for (i=1;i<=m;i++)
+    { rlist[2][n+i]="y("+string(i)+")";
+    }
+    rlist[3][size(rlist[3])+1] = rlist[3][size(rlist[3])];
+    rlist[3][size(rlist[3])-1][1] = "wp";
+    rlist[3][size(rlist[3])-1][2] = degvec(ideal(F));
+    def newring = ring(rlist);
+
+    list smallrlist;
+    smallrlist[1]=rlist[1];
+    smallrlist[2]=list();
+    for (i=1;i<=m;i++)
+    { smallrlist[2][i]="y("+string(i)+")";
+    }
+    smallrlist[3]=list();
+    smallrlist[3][1]=list();
+    smallrlist[3][1][1] = "wp";
+    smallrlist[3][1][2] = degvec(ideal(F));
+    smallrlist[3][2] = rlist[3][size(rlist[3])];
+    smallrlist[4] = rlist[4];
+    def smallring = ring(smallrlist);
+
+    setring(newring);
+    ideal J=ideal(imap(br,F));
+    ideal I=imap(br,I);
+    for (i=1;i<=m;i++)
+    { J[i]=J[i]-y(i);
+    }
+    // We chose the weighted block order since this makes J quasi-homogeneous!
+    ideal Conv=groebner(J);
+    J=Conv,I;
+    J=groebner(J);
+    ideal vars;
+    vars[n]=0;
+    vars=vars,y(1..m);
+    map emb=newring,vars;
+    ideal G=emb(J);
+    J=matrix(J)-G;
+    for (i=1;i<=ncols(G);i++)
+    { if (J[i]<>0)
+      { G[i]=0;
+      }
+    }
+    G=compress(G);
+    vars=ideal();
+    for (i=2;i<=n;i++)
+    { vars[i]=0;
+    }
+    vars=vars,y(1..m);
+    emb=newring,vars;
+    G=compress(emb(G));
+    export(G);
+    export(Conv);
+
+    setring(smallring);
+    ideal G = compress(imap(newring,G));
+    export(G);
+
+    list L;
+    L[1]=smallring;
+    L[2]=newring;
+
+    dbprint( printlevel-voice+3,"
+// 'rel_orbit_variety' created a list of two rings.
+// If L is the name of that list, you can access
+// the first ring by
+//   def R = L[1]; setring R;
+// (similarly for the second ring)");
+    return(L);
+  }
+  else
+  { "ERROR:   the <matrix> may only have one row";
+    return();
+  }
+}
+example
+{ "EXAMPLE: Sturmfels: Algorithms in Invariant Theory 2.6.3:"; echo=2;
+         ring R=0,(x,y,z),dp;
+         matrix F[1][3]=x+y+z,xy+xz+yz,xyz;
+         ideal I=x2+y2+z2-1,x2y+y2z+z2x-2x-2y-2z,xy2+yz2+zx2-2x-2y-2z;
+         list L = rel_orbit_variety(I,F);
+         def AllR = L[2];
+         setring(AllR);
+         print(G);
+         print(Conv);
+         basering;
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc relative_orbit_variety(ideal I,matrix F,string newring)
+"USAGE:   relative_orbit_variety(I,F,s);
+         I: an <ideal> invariant under the action of a group,
+@*       F: a 1xm  <matrix> defining the invariant ring of this group,
+@*       s: a <string> giving a name for a new ring
+RETURN:  The procedure ends with a new ring named s.
+         It contains a Groebner basis
+         (type <ideal>, named G) for the ideal defining the
+         relative orbit variety with respect to I in the new ring.
+THEORY:  A Groebner basis of the ideal of algebraic relations of the invariant
+         ring generators is calculated, then one of the basis elements plus the
+         ideal generators. The variables of the original ring are eliminated
+         and the polynomials that are left define the relative orbit variety
+         with respect to I.
+NOTE:    This procedure is now replaced by rel_orbit_variety
+         (see @ref{rel_orbit_variety}), which uses a different elemination
+         order that should usually allow faster computations.
+SEE ALSO: rel_orbit_variety
+EXAMPLE: example relative_orbit_variety; shows an example
+"
+{ if (newring=="")
+  { "ERROR:   the third parameter may not be empty a <string>";
+    return();
+  }
+  degBound=0;
+  if (nrows(F)==1)
+  { def br=basering;
+    int n=nvars(br);
+    int m=ncols(F);
+    string mp=string(minpoly);
+    execute("ring R=("+charstr(br)+"),("+varstr(br)+",y(1..m)),lp;");
+    if (mp!="0")
+    { execute("minpoly=number("+mp+");"); }
+    ideal J=ideal(imap(br,F));
+    ideal I=imap(br,I);
+    for (int i=1;i<=m;i++)
+    { J[i]=J[i]-y(i);
+    }
+    J=std(J);
+    J=J,I;
+    option(redSB);
+    J=std(J);
+    ideal vars;
+    //for (i=1;i<=n;i=i+1)
+    //{ vars[i]=0;
+    //}
+    vars[n]=0;
+    vars=vars,y(1..m);
+    map emb=R,vars;
+    ideal G=emb(J);
+    J=matrix(J)-G;
+    for (i=1;i<=ncols(G);i++)
+    { if (J[i]<>0)
+      { G[i]=0;
+      }
+    }
+    G=compress(G);
+    execute("ring "+newring+"=("+charstr(br)+"),(y(1..m)),lp;");
+    if (mp!="0")
+    { execute("minpoly=number("+mp+");"); }
+    ideal vars;
+    for (i=2;i<=n;i++)
+    { vars[i]=0;
+    }
+    vars=vars,y(1..m);
+    map emb=R,vars;
+    ideal G=emb(G);
+    kill vars, emb;
+    keepring `newring`;
+    return();
+  }
+  else
+  { "ERROR:   the <matrix> may only have one row";
+    return();
+  }
+}
+
+example
+{ "EXAMPLE: Sturmfels: Algorithms in Invariant Theory 2.6.3:"; echo=2;
+         ring R=0,(x,y,z),dp;
+         matrix F[1][3]=x+y+z,xy+xz+yz,xyz;
+         ideal I=x2+y2+z2-1,x2y+y2z+z2x-2x-2y-2z,xy2+yz2+zx2-2x-2y-2z;
+         string newring="E";
+         relative_orbit_variety(I,F,newring);
+         print(G);
+         basering;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc image_of_variety(ideal I,matrix F)
+"USAGE:   image_of_variety(I,F);
+@*         I: an arbitray <ideal>,
+@*       F: a 1xm <matrix> defining an invariant ring of some matrix group
+RETURN:  The <ideal> defining the image under that group of the variety defined
+         by I
+THEORY:  rel_orbit_variety(I,F) is called and the newly introduced
+@*       variables in the output are replaced by the generators of the
+@*       invariant ring. This ideal in the original variables defines the image
+@*       of the variety defined by I
+EXAMPLE: example image_of_variety; shows an example
+"
+{ if (nrows(F)==1)
+  { def br=basering;
+    int n=nvars(br);
+    list L = rel_orbit_variety(I,F);
+    def newring=L[2];
+    setring(newring);
+    ideal F=imap(br,F);
+    for (int i=1;i<=n;i++)
+    { F=0,F;
+    }
+    map emb2=newring,F;
+    ideal trafo = compress(emb2(G));
+    setring br;
+    return(imap(newring,trafo));
+  }
+  else
+  { "ERROR:   the <matrix> may only have one row";
+    return();
+  }
+}
+example
+{ "EXAMPLE: Sturmfels: Algorithms in Invariant Theory 2.6.8:"; echo=2;
+         ring R=0,(x,y,z),dp;
+         matrix F[1][3]=x+y+z,xy+xz+yz,xyz;
+         ideal I=xy;
+         print(image_of_variety(I,F));
+}
+///////////////////////////////////////////////////////////////////////////////
+
+static proc GetMatrix(list GEN)
+{ matrix M[nvars(basering)][nvars(basering)];
+  int i,j;
+  for (i=1;i<=size(GEN);i++)
+  { for (j=1;j<size(GEN[i]);j++)
+    { M[GEN[i][j+1],GEN[i][j]] = 1;
+    }
+    M[GEN[i][1],GEN[i][size(GEN[i])]] = 1;
+  }
+  return(M);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//           MINIMAL GENERATING SETS
+///////////////////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////////////////
+// Input: Disjoint cycle presentation of a permutation group
+// Output: Permutation matrices representing that group
+///////////////////////////////////////////////////////////////////////////////
+proc GetGroup(list GRP)
+{ list L;
+  int i,j,k;
+  intvec fix;
+  for (i=1;i<=size(GRP);i++)
+  { L[i] = GetMatrix(GRP[i]);
+// Fixelemente des Zyklus
+    fix = intvec(0);
+    fix[nvars(basering)]=0;
+    for (j=1;j<=size(GRP[i]);j++)
+    { for (k=1;k<=size(GRP[i][j]);k++)
+      { fix[GRP[i][j][k]]=1;
+      }
+    }
+    for (j=1;j<=nvars(basering);j++)
+    { if (fix[j]==0)
+      { L[i][j,j]=1;
+      }
+    }
+  }
+  return(L);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc orbit_sums (ideal mon, list M)
+"USAGE:    orbit_sums(mon, Per);
+          mon is of type <ideal> and is formed by monomials of degree d.
+          Per is a list of ideals providing a permutation of the ring variables.
+ASSUME:   mon contains at least the minimal monomial in each orbit sum of degree d
+          under the permutation group given by Per.
+RETURN:   an <ideal> whose generators are the orbit sums of degree d under the permutation
+          group given by Per.
+SEE ALSO: invariant_algebra_perm
+KEYWORDS: orbit sum
+EXAMPLE: example orbit_sums; shows an example
+"
+{
+//----------------- checking input ------------------
+  mon=simplify(mon,2); // remove 0
+  if (not homog(sum(mon)))
+  { "ERROR: Monomials in the first parameter must be of the same degree.";
+    return();
+  }
+  int k,k2;
+  for (k=1;k<=ncols(mon);k++)
+  { if (leadmonom(mon[k])!=mon[k])
+    { "ERROR: The first parameter must be formed by monomials.";
+      return();
+    }
+  }
+  for (k2=1;k2<=size(M);k2++)
+  { if (typeof(M[k2])!="ideal")
+    { "ERROR: The second parameter must be a list of ideals providing a ";
+      "       permutation of the ring variables.";
+      return();
+    }
+    if ((ncols(M[k2])!=nvars(basering))
+     or (ncols(M[k2])!=ncols(simplify(M[k2],6)))
+     or (M[k2][1]==0))
+    { "ERROR: The second parameter must be a list of ideals providing a ";
+      "       permutation of the ring variables.";
+      return();
+    }
+    for (k=1;k<=ncols(M[k2]);k++)
+    { if ((leadmonom(M[k2][k])!=M[k2][k]) or (deg(M[k2][k])!=1))
+      { "ERROR: The second parameter must be a list of ideals providing a ";
+        "       permutation of the ring variables.";
+        return();
+      }
+    }
+  }
+//--------------- preparing steps -------------------
+  int dgb = degBound;
+  degBound = 0;
+  def br = basering;
+  ideal tmpI;
+  int g;
+// rings that allow fast permutation of variables with >fetch< and >imap<
+  for (g=1;g<=size(M);g++)
+  { list tmpL(g);
+    execute("ring tmpR("+string(g)+") = "+charstr(br)+", ("+string(M[g])+"),("+ordstr(br)+")");
+    ideal tmpI; poly OrbitS; list L(g);
+    setring(br);
+  }
+// Remove non-minimal monomials.
+// Strategy: If m1, m2 are monomials related by a group generator
+//           then remember only the smaller of the two.
+// This is where we use the assumption on mon!
+  for (g=1;g<=size(M);g++)
+  { setring tmpR(g);
+    tmpI=fetch(br,mon);
+    setring br;
+    tmpI=imap(tmpR(g),tmpI);
+    for (k=1;k<=ncols(mon);k++)
+    { if ( mon[k]!=0)
+      { if (tmpI[k] < mon[k])
+        {
+          mon[k]=0;
+        }
+        else
+        { if (tmpI[k]>mon[k])
+          {
+            mon=NF(mon,std(tmpI[k]));
+          }
+        }
+      }
+    }
+  }
+  mon=simplify(mon,2);
+
+// main part: form orbits
+  list L,newL;  // contains partial orbits
+  for (k=1;k<=ncols(mon);k++)
+  { L[k]=ideal(mon[k]);
+    attrib(L[k],"isSB",1);
+  }
+  newL=L;
+  poly tmp;
+  int GenOK, j,i;
+  poly OrbitS=mon[1];
+  mon[1]=0;
+  int countOrbits;
+  ideal AllOrbits;
+  while (1) // apply all generators to the monomials that have been found
+            // in the preceding step
+  { GenOK = 0;
+    for (g=1;g<=size(M);g++)  // Generator g is applied to partial orbits
+    { setring tmpR(g);
+      L(g)=fetch(br,newL);
+      setring br;
+      tmpL(g)=imap(tmpR(g),L(g));
+    }
+    for (k=1;k<=size(L);k++)
+    { if (L[k][1]!=0)   // if the orbit was not fused or completed before
+      { newL[k] = tmpL(1)[k];
+        for (g=2;g<=size(M);g++)
+        { newL[k] = newL[k]+tmpL(g)[k];
+        }
+        newL[k] = simplify(NF(newL[k],L[k]),2);
+        attrib(newL[k],"isSB",1);
+        if (newL[k][1] != 0)  // i.e., the Orbit is not complete under all generators yet
+        { GenOK=-1;
+          L[k] = L[k],newL[k];
+          attrib(L[k],"isSB",1);
+          // fuse orbits:
+          for (k2=k+1;k2<=size(L);k2++)
+          { if (size(NF(newL[k2],L[k]))!=size(newL[k2]))
+            { L[k] = L[k]+L[k2];
+              attrib(L[k],"isSB",1);
+              newL[k] = newL[k]+newL[k2];
+              attrib(newL[k],"isSB",1);
+              L[k2]=ideal(0);
+              newL[k2]=ideal(0);
+            }
+          } // fuse orbits
+        } // the orbit was not complete yet
+        else
+        { countOrbits++;
+          AllOrbits[countOrbits]=sum(L[k]);
+          L[k]=ideal(0);
+          newL[k]=ideal(0);
+        } // the orbit was complete
+      } // if orbit was not yet fused/completed before
+    } // loop through partial orbits
+    if (GenOK == 0)  // i.e., all orbits are complete, so we can break the iteration
+    { break;
+    }
+  } // iterate
+  degBound = dgb;
+  return(AllOrbits);
+}
+example
+{ "EXAMPLE: orbit sums in degree 2 under the action of the alternating group;";
+  "         it doesn't matter that we are in the modular case"; echo=2;
+         ring R=3,(a,b,c,d),dp;
+         list Per=ideal(b,c,a,d),ideal(a,c,d,b);
+         ideal orb=orbit_sums(kbase(std(0),2),Per);
+         orb;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc invariant_algebra_perm (list #)
+"USAGE:    invariant_algebra_perm(GEN[,v]);
+@*        GEN: a list of generators of a permutation group. It is given in disjoint cycle
+          form, where trivial cycles can be omitted; e.g., the generator (1,2)(3,4)(5) is
+          given by <list(list(1,2),list(3,4))>.
+@*        v: an optional <int>
+RETURN:   A minimal homogeneous generating set of the invariant ring of the group presented
+          by GEN, type <matrix>
+ASSUME:   We are in the non-modular case, i.e., the characteristic of the basering
+          does not divide the group order. Note that the function does not verify whether
+          this assumption holds or not
+DISPLAY:  Information on the progress of computations if v does not equal 0
+THEORY:   We do an incremental search in increasing degree d. Generators of the invariant
+          ring are found among the orbit sums of degree d. The generators are chosen by
+          Groebner basis techniques (see S. King: Minimal generating sets of non-modular
+          invariant rings of finite groups).
+NOTE:     invariant_algebra_perm should not be used in rings with weighted orders.
+SEE ALSO: invariant_algebra_reynolds
+KEYWORDS: invariant ring minimal generating set permutation group
+EXAMPLE:  example invariant_algebra_perm; shows an example
+"
+{
+//----------------- checking input and setting verbose mode ------------------
+  if (size(#)==0)
+  { "ERROR: There are no parameters given.";
+    return();
+  }
+  if (typeof(#[size(#)])=="int")
+  { int v=#[size(#)];
+    list GEN=#[1..size(#)-1];
+  }
+  else
+  { int v=0;
+    list GEN=#;
+  }
+  int i,j,k,k2;
+  list TST;
+  for (i=1;i<=size(GEN);i++)
+  { if (typeof(GEN[i])!="list")
+    { "ERROR: The permutation group must be given by generators in";
+      "       disjoint cycle presentation";
+      return();
+    }
+    for (j=1;j<=size(GEN[i]);j++)
+    { if (typeof(GEN[i][j])!="list")
+      { "ERROR: The permutation group must be given by generators in";
+        "       disjoint cycle presentation";
+      return();
+      }
+      for (k=1;k<=size(GEN[i][j]);k++)
+      { if (typeof(GEN[i][j][k])!="int")
+        { "ERROR: The permutation group must be given by generators in";
+          "       disjoint cycle presentation";
+          return();
+        }
+      }
+    }
+    TST=sort(sum(sum(GEN[i])))[1];
+    if (TST[1]<=0)
+    { "ERROR: The permutation group must be given by generators in";
+      "       disjoint cycle presentation";
+      return();
+    }
+    for (k2=1;k2<size(TST);k2++)
+    { if ((TST[k2]==TST[k2+1]) or (TST[k2+1]>nvars(basering)))
+      { "ERROR: The permutation group must be given by generators in";
+        "       disjoint cycle presentation";
+        return();
+      }
+    }
+  }
+//-------------- starting computation -------------------------
+  list GRP = GetGroup(GEN);
+  def br=basering;
+  int dgb = degBound;
+  degBound = 0;
+  int counter, totalcount, OrbSize,
+      NextCand, sGoffset, fin,MaxD,LastGDeg;
+  ideal OrbSums, RedSums, NewReductor;
+  poly helpP,lmp;
+
+
+// Transform the matrices generating the group into ring maps
+  int maxG = size(GRP);
+
+  matrix vars=transpose(matrix(maxideal(1)));
+
+  ideal tmpI;
+  int g;
+  list M; // M provides maps corresponding to the group generators:
+  for (i=1;i<=maxG;i++)
+  { tmpI = ideal(GRP[i]*vars);
+    M[i] = tmpI;
+  }
+
+  ideal G;  // G will contain homog. alg.generators
+  poly Inv;
+  ideal mon;
+
+  ideal sG = std(G);
+  int d=1;
+  while ((fin==0) or (d<=MaxD))
+  { if (v)
+    { "Searching generators in degree",d;
+    }
+    counter = 0; // counts generators in degree d
+    OrbSums = orbit_sums(kbase(sG,d),M);
+    OrbSize = ncols(OrbSums);
+    if (v)
+    { "  We have ",OrbSize," orbit sums of degree ",d;
+    }
+    RedSums = reduce(OrbSums,sG);
+    sGoffset=ncols(sG);
+// loop through orbit_sum, and select generators among them
+    for (i=1;i<=OrbSize;i++)
+    { helpP = RedSums[i];
+      if (helpP<>0)
+      { counter++; // found new inv. algebra generator!
+        totalcount++;
+        if (v)
+        { "    We found generator number ",totalcount,
+          " in degree ",d;
+        }
+        G[totalcount] = OrbSums[i];
+        sG[sGoffset+counter] = helpP;
+        attrib(sG,"isSB",1);
+        NewReductor[1]=helpP;
+        attrib(NewReductor,"isSB",1);
+        RedSums = reduce(RedSums,NewReductor);
+        LastGDeg=d;
+      } // found new generator
+    } // loop through orbit sums
+    if ((MaxD>0) and (d==MaxD))
+    { if (v)
+      { "We went beyond the degree bound, so we are done!";
+      }
+      break;
+    }
+    d++;
+// Prepare computations of the next degree
+    if (LastGDeg==d-2)
+    { degBound=0;
+      if (v) {"Presumably all generators have been found";}
+      sG = groebner(sG);
+      fin = 0;
+    }
+    if (LastGDeg==d-1)
+    { degBound=d;
+      if (v) { "Computing Groebner basis up to the new degree",d; }
+      sG = groebner(sG);
+      attrib(sG,"isSB",1);
+      fin = 0;
+    }
+    if ((fin==0) and (dim(sG)==0))
+    { MaxD = maxdeg1(kbase(sG));
+      if (v)
+      { if (MaxD>=d) {"We found the degree bound",MaxD; }
+        else {"We found the degree bound",d-1;}
+      }
+      if (MaxD<d)
+      { if (v) {"We went beyond the degree bound, so, we are done!";}
+        break;
+      }
+      fin = 1;
+    } // computing degree bound
+  } // for increasing degrees
+  kill sG;
+  degBound=dgb;
+  return(matrix (G));
+}
+example
+{ "EXAMPLE: An action of S_2 on four variables"; echo=2;
+         ring R=0,(a,b,c,d),dp;
+         def GEN=list(list(list(1,3),list(2,4)));
+         matrix G = invariant_algebra_perm(GEN,1);
+         G;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc invariant_algebra_reynolds (matrix REY, list #)
+"USAGE:    invariant_algebra_reynolds(REY[,v]);
+@*        REY: a gxn <matrix> representing the Reynolds operator of a finite matrix group,
+               where g ist the group order and n is the number of variables of the basering;
+@*        v: an optional <int>
+RETURN:   A minimal homogeneous generating set of the invariant ring, type <matrix>
+ASSUME:   We are in the non-modular case, i.e., the characteristic of the basering
+          does not divide the group order;
+          REY is the 1st return value of group_reynolds(), reynolds_molien() or
+          the second one of primary_invariants()
+DISPLAY:  Information on the progress of computations if v does not equal 0
+THEORY:   We do an incremental search in increasing degree d. Generators of the invariant
+          ring are found among the Reynolds images of monomials of degree d. The generators are
+          chosen by Groebner basis techniques (see S. King: Minimal generating sets of
+          non-modular invariant rings of finite groups).
+NOTE:     invariant_algebra_reynolds should not be used in rings with weighted orders.
+SEE ALSO: invariant_algebra_perm
+KEYWORDS: invariant ring minimal generating set matrix group
+EXAMPLE:  example invariant_algebra_reynolds; shows an example
+"
+{ int MonStep = 10;
+  int v;
+  if (size(#))
+  { if (typeof(#[1])=="int")
+    { v=#[1];
+    }
+  }
+  def br=basering;
+  int dgb = degBound;
+  degBound = 0;
+  int block, counter, totalcount, monsize,i,j,
+      sGoffset, fin,MaxD,LastGDeg;
+  poly helpP,lmp;
+  block = 1;
+  ideal mon, MON, Inv, G;  // G will contain homog. alg.generators
+  ideal RedInv, NewG, NewReductor;
+  int NewGcounter;
+  intvec dimvec;
+
+  ideal sG = std(G);
+  int d=1;
+  dimvec[d] = dim(sG);
+  while ((fin==0) or (d<=MaxD))
+  { NewG = ideal();
+    NewGcounter=0;
+    mon = kbase(sG,d);
+    sGoffset=ncols(sG);
+    monsize = ncols(mon);
+    if (mon[1]<>0)
+    { if (v) { "  We have ",monsize,
+     " relevant monomials in degree ",d;}
+      block=0; // Loops through the monomials
+      while (block<monsize)
+      { if ((block mod MonStep) == 0)
+        { if ((block+MonStep) <= monsize)
+          { ideal tmp = normalize(evaluate_reynolds(REY,ideal(mon[block+1..block+MonStep])));
+            Inv[block+1..block+MonStep] = tmp[1..MonStep];
+            tmp = reduce(tmp,sG);
+            RedInv[block+1..block+MonStep] = tmp[1..MonStep];
+            kill tmp;
+          }
+          else
+          { ideal tmp = normalize(evaluate_reynolds(REY,ideal(mon[block+1..monsize])));
+            Inv[block+1..monsize] = tmp[1..monsize-block];
+            tmp = reduce(tmp,sG);
+            RedInv[block+1..monsize] = tmp[1..monsize-block];
+            kill tmp;
+          }
+        }
+        block++;
+        helpP = RedInv[block];
+        if (helpP<>0)
+        { counter++; // found new inv. algebra generator!
+          if (v) { "    We found generator number ",counter," in degree ",d; }
+          G[counter] = Inv[block];
+          sG[sGoffset+counter] = helpP;
+          attrib(sG,"isSB",1);
+          NewGcounter++;
+          NewG[NewGcounter] = helpP;
+          mon[block]=0;
+          Inv[block]=0;
+          RedInv[block]=0;
+          NewReductor[1]=helpP;
+          attrib(NewReductor,"isSB",1);
+          RedInv = reduce(RedInv,NewReductor);
+          LastGDeg=d;
+        }
+      } // loop through monomials
+    } // if mon[1]<>0
+    if ((MaxD>0) and (d==MaxD))
+    { if (v)
+      { "We went beyond the degree bound, so we are done!";
+      }
+      break;
+    }
+    d++;
+// Prepare computations of the next degree
+    if (LastGDeg==d-2)
+    { degBound=0;
+      if (v) {"Presumably all generators have been found";}
+      sG = groebner(sG);
+      fin = 0;
+    }
+    if (LastGDeg==d-1)
+    { degBound=d;
+      if (v) { "Computing Groebner basis up to the new degree",d; }
+      sG = groebner(sG);
+      attrib(sG,"isSB",1);
+      fin = 0;
+    }
+    if ((fin==0) and (dim(sG)==0))
+    { MaxD = maxdeg1(kbase(sG));
+      if (v)
+      { if (MaxD>=d) {"We found the degree bound",MaxD; }
+        else {"We found the degree bound",d-1;}
+      }
+      if (MaxD<d)
+      { if (v) {"We went beyond the degree bound, so, we are done!";}
+        break;
+      }
+      fin = 1;
+    } // computing degree bound
+  } // for increasing degrees
+  kill sG;
+  degBound=dgb;
+  return(matrix (G));
+}
+example
+{ "EXAMPLE: An action of S_2 on four variables"; echo=2;
+         ring R=0,(a,b,c,d),dp;
+         matrix A[4][4]=
+           0,0,1,0,
+           0,0,0,1,
+           1,0,0,0,
+           0,1,0,0;
+         list L = group_reynolds(A);
+         matrix G = invariant_algebra_reynolds(L[1],1);
+         G;
+}
+
+///////////////////////////////////////////////////////////////////////////////
diff --git a/Singular/LIB/fpadim.lib b/Singular/LIB/fpadim.lib
new file mode 100644
index 0000000..97fbabe
--- /dev/null
+++ b/Singular/LIB/fpadim.lib
@@ -0,0 +1,2186 @@
+////////////////////////////////////////////////////////
+version="version fpadim.lib 4.0.0.0 Jun_2013 "; // $Id: b03ed6db0b4a33e3eedba580c9b3d80e50e822fb $
+category="Noncommutative";
+info="
+LIBRARY: fpadim.lib     Algorithms for quotient algebras in the letterplace case
+AUTHORS: Grischa Studzinski,       grischa.studzinski at rwth-aachen.de
+
+Support: Joint projects LE 2697/2-1 and KR 1907/3-1 of the Priority Programme SPP 1489:
+@* 'Algorithmische und Experimentelle Methoden in Algebra, Geometrie und Zahlentheorie'
+@* of the German DFG
+
+OVERVIEW: Given the free algebra A = K<x_1,...,x_n> and a (finite) Groebner basis
+      GB = {g_1,..,g_w}, one is interested in the K-dimension and in the
+      explicit K-basis of A/<GB>.
+      Therefore one is interested in the following data:
+@*      - the Ufnarovskij graph induced by GB
+@*      - the mistletoes of A/<GB>
+@*      - the K-dimension of A/<GB>
+@*      - the Hilbert series of A/<GB>
+
+      The Ufnarovskij graph is used to determine whether A/<GB> has finite
+      K-dimension. One has to check if the graph contains cycles.
+      For the whole theory we refer to [ufna]. Given a
+      reduced set of monomials GB one can define the basis tree, whose vertex
+      set V consists of all normal monomials w.r.t. GB. For every two
+      monomials m_1, m_2 in V there is a direct edge from m_1 to m_2, if and
+      only if there exists x_k in {x_1,..,x_n}, such that m_1*x_k = m_2. The
+      set M = {m in V | there is no edge from m to another monomial in V} is
+      called the set of mistletoes. As one can easily see it consists of
+      the endpoints of the graph. Since there is a unique path to every
+      monomial in V the whole graph can be described only from the knowledge
+      of the mistletoes. Note that V corresponds to a basis of A/<GB>, so
+      knowing the mistletoes we know a K-basis. The name mistletoes was given
+      to those points because of these miraculous value and the algorithm is
+      named sickle, because a sickle is the tool to harvest mistletoes.
+      For more details see [studzins]. This package uses the Letterplace
+      format introduced by [lls]. The algebra can either be represented as a
+      Letterplace ring or via integer vectors: Every variable will only be
+      represented by its number, so variable one is represented as 1,
+      variable two as 2 and so on. The monomial x_1*x_3*x_2 for example will
+      be stored as (1,3,2). Multiplication is concatenation. Note that there
+      is no algorithm for computing the normal form needed for our case.
+      Note that the name fpadim.lib is short for dimensions of finite
+      presented algebras.
+
+REFERENCES:
+
+@*   [ufna] Ufnarovskij: Combinatorical and asymptotic methods in algebra, 1990
+@*   [lls] Levandovskyy, La Scala: Letterplace ideals and non-commutative
+          Groebner bases, 2009
+@*   [studzins] Studzinski: Dimension computations in non-commutative,
+                     associative algebras, Diploma thesis, RWTH Aachen, 2010
+
+Assumptions:
+@* - basering is always a Letterplace ring
+@* - all intvecs correspond to Letterplace monomials
+@* - if you specify a different degree bound d,
+     d <= attrib(basering,uptodeg) should hold.
+@* In the procedures below, 'iv' stands for intvec representation
+  and 'lp' for the letterplace representation of monomials
+
+PROCEDURES:
+
+ivDHilbert(L,n[,d]);       computes the K-dimension and the Hilbert series
+ivDHilbertSickle(L,n[,d]); computes mistletoes, K-dimension and Hilbert series
+ivDimCheck(L,n);           checks if the K-dimension of A/<L> is infinite
+ivHilbert(L,n[,d]);        computes the Hilbert series of A/<L> in intvec format
+ivKDim(L,n[,d]);           computes the K-dimension of A/<L> in intvec format
+ivMis2Base(M);             computes a K-basis of the factor algebra
+ivMis2Dim(M);              computes the K-dimension of the factor algebra
+ivOrdMisLex(M);            orders a list of intvecs lexicographically
+ivSickle(L,n[,d]);         computes the mistletoes of A/<L> in intvec format
+ivSickleHil(L,n[,d]);      computes the mistletoes and Hilbert series of A/<L>
+ivSickleDim(L,n[,d]);      computes the mistletoes and the K-dimension of A/<L>
+lpDHilbert(G[,d,n]);       computes the K-dimension and Hilbert series of A/<G>
+lpDHilbertSickle(G[,d,n]); computes mistletoes, K-dimension and Hilbert series
+lpHilbert(G[,d,n]);        computes the Hilbert series of A/<G> in lp format
+lpDimCheck(G);             checks if the K-dimension of A/<G> is infinite
+lpKDim(G[,d,n]);           computes the K-dimension of A/<G> in lp format
+lpMis2Base(M);             computes a K-basis of the factor algebra
+lpMis2Dim(M);              computes the K-dimension of the factor algebra
+lpOrdMisLex(M);            orders an ideal of lp-monomials lexicographically
+lpSickle(G[,d,n]);         computes the mistletoes of A/<G> in lp format
+lpSickleHil(G[,d,n]);      computes the mistletoes and Hilbert series of A/<G>
+lpSickleDim(G[,d,n]);      computes the mistletoes and the K-dimension of A/<G>
+sickle(G[,m,d,h]);         can be used to access all lp main procedures
+
+
+ivL2lpI(L);           transforms a list of intvecs into an ideal of lp monomials
+iv2lp(I);             transforms an intvec into the corresponding monomial
+iv2lpList(L);         transforms a list of intmats into an ideal of lp monomials
+iv2lpMat(M);          transforms an intmat into an ideal of lp monomials
+lp2iv(p);             transforms a polynomial into the corresponding intvec
+lp2ivId(G);           transforms an ideal into the corresponding list of intmats
+lpId2ivLi(G);         transforms a lp-ideal into the corresponding list of intvecs
+
+SEE ALSO: freegb_lib
+";
+
+LIB "freegb.lib"; //for letterplace rings
+LIB "general.lib";//for sorting mistletoes
+
+/////////////////////////////////////////////////////////
+
+
+//--------------- auxiliary procedures ------------------
+
+static proc allVars(list L, intvec P, int n)
+"USAGE: allVars(L,P,n); L a list of intmats, P an intvec, n an integer
+RETURN: int, 0 if all variables are contained in the quotient algebra, 1 otherwise
+"
+{int i,j,r;
+  intvec V;
+  for (i = 1; i <= size(P); i++) {if (P[i] == 1){ j = i; break;}}
+  V = L[j][1..nrows(L[j]),1];
+  for (i = 1; i <= n; i++) {if (isInVec(i,V) == 0) {r = 1; break;}}
+  if (r == 0) {return(1);}
+  else {return(0);}
+}
+
+static proc checkAssumptions(int d, list L)
+"PURPOSE: Checks, if all the Assumptions are holding
+"
+{if (typeof(attrib(basering,"isLetterplaceRing"))=="string") {ERROR("Basering is not a Letterplace ring!");}
+  if (d > attrib(basering,"uptodeg")) {ERROR("Specified degree bound exceeds ring parameter!");}
+  int i;
+  for (i = 1; i <= size(L); i++)
+  {if (entryViolation(L[i], attrib(basering,"lV")))
+    {ERROR("Not allowed monomial/intvec found!");}
+  }
+  return();
+}
+
+static proc createStartMat(int d, int n)
+"USAGE: createStartMat(d,n); d, n integers
+RETURN: intmat
+PURPOSE:Creating the intmat with all normal monomials in n variables and of degree d to start with
+NOTE:   d has to be > 0
+"
+{intmat M[(n^d)][d];
+  int i1,i2,i3,i4;
+  for (i1 = 1; i1 <= d; i1++)  //Spalten
+  {i2 = 1; //durchlaeuft Zeilen
+    while (i2 <= (n^d))
+    {for (i3 = 1; i3 <= n; i3++)
+      {for (i4 = 1; i4 <= (n^(i1-1)); i4++)
+      {
+        M[i2,i1] = i3;
+          i2 = i2 + 1;
+       }
+      }
+    }
+  }
+  return(M);
+}
+
+static proc createStartMat1(int n, intmat M)
+"USAGE: createStartMat1(n,M); n an integer, M an intmat
+RETURN: intmat, with all variables except those in M
+"
+{int i;
+  intvec V,Vt;
+  V = M[(1..nrows(M)),1];
+  for (i = 1; i <= size(V); i++) {if (isInVec(i,V) == 0) {Vt = Vt,i;}}
+  if (Vt == 0) {intmat S; return(S);}
+  else {Vt = Vt[2..size(Vt)]; intmat S [size(Vt)][1]; S[1..size(Vt),1] = Vt; return(S);}
+}
+
+static proc entryViolation(intmat M, int n)
+"PURPOSE:checks, if all entries in M are variable-related
+"
+{if ((nrows(M) == 1) && (ncols(M) == 1)) {if (M[1,1] == 0){return(0);}}
+ int i,j;
+  for (i = 1; i <= nrows(M); i++)
+  {for (j = 1; j <= ncols(M); j++)
+    {if(!((1<=M[i,j])&&(M[i,j]<=n))) {return(1);}}
+  }
+  return(0);
+}
+
+static proc findDimen(intvec V, int n, list L, intvec P, list #)
+"USAGE: findDimen(V,n,L,P,degbound); V,P intvecs, n, an integer, L a list,
+@*      degbound an optional integer
+RETURN: int
+PURPOSE:Computing the K-dimension of the quotient algebra
+"
+{int degbound = 0;
+  if (size(#) > 0) {if (#[1] > 0) {degbound = #[1];}}
+  int dimen,i,j,w,it;
+  intvec Vt,Vt2;
+  module M;
+  if (degbound == 0)
+  {for (i = 1; i <= n; i++)
+    {Vt = V, i; w = 0;
+      for (j = 1; j<= size(P); j++)
+      {if (P[j] <= size(Vt))
+        {Vt2 = Vt[(size(Vt)-P[j]+1)..size(Vt)];
+          if (isInMat(Vt2,L[j]) > 0) {w = 1; break;}
+        }
+      }
+      if (w == 0)
+      {vector Vtt;
+        for (it = 1; it <= size(Vt); it++){Vtt = Vtt + Vt[it]*gen(it);}
+        M = M,Vtt;
+        kill Vtt;
+      }
+    }
+    if (size(M) == 0) {return(0);}
+    else
+    {M = simplify(M,2);
+      for (i = 1; i <= size(M); i++)
+      {kill Vt; intvec Vt;
+        for (j =1; j <= size(M[i]); j++){Vt[j] =  int(leadcoef(M[i][j]));}
+        dimen = dimen + 1 + findDimen(Vt,n,L,P);
+      }
+      return(dimen);
+    }
+  }
+  else
+  {if (size(V) > degbound) {ERROR("monomial exceeds degreebound");}
+    if (size(V) == degbound) {return(0);}
+    for (i = 1; i <= n; i++)
+    {Vt = V, i; w = 0;
+      for (j = 1; j<= size(P); j++)
+      {if (P[j] <= size(Vt))
+        {Vt2 = Vt[(size(Vt)-P[j]+1)..size(Vt)];
+          if (isInMat(Vt2,L[j]) > 0) {w = 1; break;}
+        }
+      }
+      if (w == 0) {vector Vtt;
+        for (it = 1; it <= size(Vt); it++){Vtt = Vtt + Vt[it]*gen(it);}
+        M = M,Vtt;
+        kill Vtt;
+      }
+    }
+    if (size(M) == 0) {return(0);}
+    else
+    {M = simplify(M,2);
+      for (i = 1; i <= size(M); i++)
+      {kill Vt; intvec Vt;
+        for (j =1; j <= size(M[i]); j++){Vt[j] =  int(leadcoef(M[i][j]));}
+        dimen = dimen + 1 + findDimen(Vt,n,L,P,degbound);
+      }
+      return(dimen);
+    }
+  }
+}
+
+static proc findCycle(intvec V, list L, intvec P, int n, int ld, module M)
+"USAGE:
+RETURN: int, 1 if Ufn-graph contains a cycle, or 0 otherwise
+PURPOSE:Searching the Ufnarovskij graph for cycles
+"
+{int i,j,w,r;intvec Vt,Vt2;
+  int it, it2;
+  if (size(V) < ld)
+  {for (i = 1; i <= n; i++)
+    {Vt = V,i; w = 0;
+      for (j = 1; j <= size(P); j++)
+      {if (P[j] <= size(Vt))
+        {Vt2 = Vt[(size(Vt)-P[j]+1)..size(Vt)];
+          if (isInMat(Vt2,L[j]) > 0)
+          {w = 1; break;}
+        }
+      }
+      if (w == 0) {r = findCycle(Vt,L,P,n,ld,M);}
+      if (r == 1) {break;}
+    }
+    return(r);
+  }
+  else
+  {j = size(M);
+    if (j > 0)
+    {
+      intmat Mt[j][nrows(M)];
+      for (it = 1; it <= j; it++)
+      { for(it2 = 1; it2 <= nrows(M);it2++)
+        {Mt[it,it2] = int(leadcoef(M[it2,it]));}
+      }
+      Vt = V[(size(V)-ld+1)..size(V)];
+      //Mt; type(Mt);Vt;type(Vt);
+      if (isInMat(Vt,Mt) > 0) {return(1);}
+      else
+      {vector Vtt;
+        for (it =1; it <= size(Vt); it++)
+        {Vtt = Vtt + Vt[it]*gen(it);}
+        M = M,Vtt;
+        kill Vtt;
+        for (i = 1; i <= n; i++)
+        {Vt = V,i; w = 0;
+          for (j = 1; j <= size(P); j++)
+          {if (P[j] <= size(Vt))
+            {Vt2 = Vt[(size(Vt)-P[j]+1)..size(Vt)];
+              //L[j]; type(L[j]);Vt2;type(Vt2);
+              if (isInMat(Vt2,L[j]) > 0)
+              {w = 1; break;}
+            }
+          }
+          if (w == 0) {r = findCycle(Vt,L,P,n,ld,M);}
+          if (r == 1) {break;}
+        }
+        return(r);
+      }
+    }
+    else
+    { Vt = V[(size(V)-ld+1)..size(V)];
+      vector Vtt;
+      for (it = 1; it <= size(Vt); it++)
+      {Vtt = Vtt + Vt[it]*gen(it);}
+      M = Vtt;
+      kill Vtt;
+      for (i = 1; i <= n; i++)
+      {Vt = V,i; w = 0;
+        for (j = 1; j <= size(P); j++)
+        {if (P[j] <= size(Vt))
+          {Vt2 = Vt[(size(Vt)-P[j]+1)..size(Vt)];
+            //L[j]; type(L[j]);Vt2;type(Vt2);
+            if (isInMat(Vt2,L[j]) > 0)
+            {w = 1; break;}
+          }
+        }
+        if (w == 0) {r = findCycle(Vt,L,P,n,ld,M);}
+        if (r == 1) {break;}
+      }
+      return(r);
+    }
+  }
+}
+
+static proc findHCoeff(intvec V,int n,list L,intvec P,intvec H,list #)
+"USAGE: findHCoeff(V,n,L,P,H,degbound); L a list of intmats, degbound an integer
+RETURN: intvec
+PURPOSE:Computing the coefficient of the Hilbert series (upto degree degbound)
+NOTE:   Starting with a part of the Hilbert series we change the coefficient
+@*      depending on how many basis elements we found on the actual branch
+"
+{int degbound = 0;
+  if (size(#) > 0){if (#[1] > 0){degbound = #[1];}}
+  int i,w,j,it;
+  int h1 = 0;
+  intvec Vt,Vt2,H1;
+  module M;
+  if (degbound == 0)
+  {for (i = 1; i <= n; i++)
+    {Vt = V, i; w = 0;
+      for (j = 1; j<= size(P); j++)
+      {if (P[j] <= size(Vt))
+        {Vt2 = Vt[(size(Vt)-P[j]+1)..size(Vt)];
+          if (isInMat(Vt2,L[j]) > 0) {w = 1; break;}
+        }
+      }
+      if (w == 0)
+      {vector Vtt;
+        for (it = 1; it <= size(Vt); it++){Vtt = Vtt + Vt[it]*gen(it);}
+        M = M,Vtt;
+        kill Vtt;
+      }
+    }
+    if (size(M) == 0) {return(H);}
+    else
+    {M = simplify(M,2);
+      for (i = 1; i <= size(M); i++)
+      {kill Vt; intvec Vt;
+        for (j =1; j <= size(M[i]); j++) {Vt[j] =  int(leadcoef(M[i][j]));}
+        h1 = h1 + 1; H1 = findHCoeff(Vt,n,L,P,H1);
+      }
+      if (size(H1) < (size(V)+2)) {H1[(size(V)+2)] = h1;}
+      else {H1[(size(V)+2)] = H1[(size(V)+2)] + h1;}
+      H1 = H1 + H;
+      return(H1);
+    }
+  }
+  else
+  {if (size(V) > degbound) {ERROR("monomial exceeds degreebound");}
+    if (size(V) == degbound) {return(H);}
+    for (i = 1; i <= n; i++)
+    {Vt = V, i; w = 0;
+      for (j = 1; j<= size(P); j++)
+      {if (P[j] <= size(Vt))
+        {Vt2 = Vt[(size(Vt)-P[j]+1)..size(Vt)];
+          if (isInMat(Vt2,L[j]) > 0) {w = 1; break;}
+        }
+      }
+      if (w == 0)
+      {vector Vtt;
+        for (it = 1; it <= size(Vt); it++){Vtt = Vtt + Vt[it]*gen(it);}
+        M = M,Vtt;
+        kill Vtt;
+      }
+    }
+    if (size(M) == 0) {return(H);}
+    else
+    {M = simplify(M,2);
+      for (i = 1; i <= size(M); i++)
+      {kill Vt; intvec Vt;
+        for (j =1; j <= size(M[i]); j++)
+        {Vt[j] =  int(leadcoef(M[i][j]));}
+        h1 = h1 + 1; H1 = findHCoeff(Vt,n,L,P,H1,degbound);
+      }
+      if (size(H1) < (size(V)+2)) { H1[(size(V)+2)] = h1;}
+      else {H1[(size(V)+2)] = H1[(size(V)+2)] + h1;}
+      H1 = H1 + H;
+      return(H1);
+    }
+  }
+}
+
+static proc findHCoeffMis(intvec V, int n, list L, intvec P, list R,list #)
+"USAGE: findHCoeffMis(V,n,L,P,R,degbound); degbound an optional integer, L a
+@*      list of Intmats, R
+RETURN: list
+PURPOSE:Computing the coefficients of the Hilbert series and the Mistletoes all
+@*      at once
+"
+{int degbound = 0;
+  if (size(#) > 0) {if (#[1] > 0) {degbound = #[1];}}
+  int i,w,j,h1;
+  intvec Vt,Vt2,H1; int it;
+  module M;
+  if (degbound == 0)
+  {for (i = 1; i <= n; i++)
+    {Vt = V, i; w = 0;
+      for (j = 1; j<= size(P); j++)
+      {if (P[j] <= size(Vt))
+        {Vt2 = Vt[(size(Vt)-P[j]+1)..size(Vt)];
+          if (isInMat(Vt2,L[j]) > 0) {w = 1; break;}
+        }
+      }
+      if (w == 0)
+      {vector Vtt;
+        for (it = 1; it <= size(Vt); it++){Vtt = Vtt + Vt[it]*gen(it);}
+        M = M,Vtt;
+        kill Vtt;
+      }
+    }
+    if (size(M) == 0) {if (size(R) < 2){R[2] = list(V);} else {R[2] = R[2] + list(V);} return(R);}
+    else
+    {M = simplify(M,2);
+      for (i = 1; i <= size(M); i++)
+      {kill Vt; intvec Vt;
+        for (j =1; j <= size(M[i]); j++)
+        {Vt[j] =  int(leadcoef(M[i][j]));}
+        if (size(R[1]) < (size(V)+2)) { R[1][(size(V)+2)] = 1;}
+        else
+        {R[1][(size(V)+2)] = R[1][(size(V)+2)] + 1;}
+        R = findHCoeffMis(Vt,n,L,P,R);
+      }
+      return(R);
+    }
+  }
+  else
+  {if (size(V) > degbound) {ERROR("monomial exceeds degreebound");}
+    if (size(V) == degbound)
+    {if (size(R) < 2){R[2] = list (V);}
+      else{R[2] = R[2] + list (V);}
+      return(R);
+    }
+    for (i = 1; i <= n; i++)
+    {Vt = V, i; w = 0;
+      for (j = 1; j<= size(P); j++)
+      {if (P[j] <= size(Vt))
+        {Vt2 = Vt[(size(Vt)-P[j]+1)..size(Vt)];
+          if (isInMat(Vt2,L[j]) > 0) {w = 1; break;}
+        }
+      }
+      if (w == 0)
+      {vector Vtt;
+        for (it = 1; it <= size(Vt); it++){Vtt = Vtt + Vt[it]*gen(it);}
+        M = M,Vtt;
+        kill Vtt;
+      }
+    }
+    if (size(M) == 0) {if (size(R) < 2){R[2] = list(V);} else {R[2] = R[2] + list(V);} return(R);}
+    else
+    {M = simplify(M,2);
+      for (i = 1; i <= ncols(M); i++)
+      {kill Vt; intvec Vt;
+        for (j =1; j <= size(M[i]); j++)
+        {Vt[j] =  int(leadcoef(M[i][j]));}
+        if (size(R[1]) < (size(V)+2)) { R[1][(size(V)+2)] = 1;}
+        else
+        {R[1][(size(V)+2)] = R[1][(size(V)+2)] + 1;}
+        R = findHCoeffMis(Vt,n,L,P,R,degbound);
+      }
+      return(R);
+    }
+  }
+}
+
+
+static proc findMisDim(intvec V,int n,list L,intvec P,list R,list #)
+"USAGE:
+RETURN: list
+PURPOSE:Computing the K-dimension and the Mistletoes all at once
+"
+{int degbound = 0;
+  if (size(#) > 0) {if (#[1] > 0) {degbound = #[1];}}
+  int dimen,i,j,w;
+  intvec Vt,Vt2; int it;
+  module M;
+  if (degbound == 0)
+  {for (i = 1; i <= n; i++)
+    {Vt = V, i; w = 0;
+      for (j = 1; j<= size(P); j++)
+      {if (P[j] <= size(Vt))
+        {Vt2 = Vt[(size(Vt)-P[j]+1)..size(Vt)];
+          if (isInMat(Vt2,L[j]) > 0) {w = 1; break;}
+        }
+      }
+      if (w == 0)
+      {vector Vtt;
+        for (it = 1; it <= size(Vt); it++){Vtt = Vtt + Vt[it]*gen(it);}
+        M = M,Vtt;
+        kill Vtt;
+      }
+    }
+    if (size(M) == 0)
+    {if (size(R) < 2){R[2] = list (V);}
+      else{R[2] = R[2] + list(V);}
+      return(R);
+    }
+    else
+    {M = simplify(M,2);
+      for (i = 1; i <= size(M); i++)
+      {kill Vt; intvec Vt;
+        for (j =1; j <= size(M[i]); j++){Vt[j] =  int(leadcoef(M[i][j]));}
+        R[1] = R[1] + 1; R = findMisDim(Vt,n,L,P,R);
+      }
+      return(R);
+    }
+  }
+  else
+  {if (size(V) > degbound) {ERROR("monomial exceeds degreebound");}
+    if (size(V) == degbound)
+    {if (size(R) < 2){R[2] = list (V);}
+      else{R[2] = R[2] + list (V);}
+      return(R);
+    }
+    for (i = 1; i <= n; i++)
+    {Vt = V, i; w = 0;
+      for (j = 1; j<= size(P); j++)
+      {if (P[j] <= size(Vt))
+        {Vt2 = Vt[(size(Vt)-P[j]+1)..size(Vt)];
+          if (isInMat(Vt2,L[j]) > 0) {w = 1; break;}
+        }
+      }
+      if (w == 0)
+      {vector Vtt;
+        for (it = 1; it <= size(Vt); it++){Vtt = Vtt + Vt[it]*gen(it);}
+        M = M,Vtt;
+        kill Vtt;
+      }
+    }
+    if (size(M) == 0)
+    {if (size(R) < 2){R[2] = list (V);}
+      else{R[2] = R[2] + list(V);}
+      return(R);
+    }
+    else
+    {M = simplify(M,2);
+      for (i = 1; i <= size(M); i++)
+      {kill Vt; intvec Vt;
+        for (j =1; j <= size(M[i]); j++){Vt[j] =  int(leadcoef(M[i][j]));}
+        R[1] = R[1] + 1; R = findMisDim(Vt,n,L,P,R,degbound);
+      }
+      return(R);
+
+    }
+  }
+}
+
+
+static proc findmistletoes(intvec V, int n, list L, intvec P, list #)
+"USAGE: findmistletoes(V,n,L,P,degbound); V a normal word, n the number of
+@*      variables, L the GB, P the occuring degrees,
+@*      and degbound the (optional) degreebound
+RETURN:  list
+PURPOSE:Computing mistletoes starting in V
+NOTE:   V has to be normal w.r.t. L, it will not be checked for being so
+"
+{int degbound = 0;
+  if (size(#) > 0) {if (#[1] > 0) {degbound = #[1];}}
+  list R; intvec Vt,Vt2; int it;
+  int i,j;
+  module M;
+  if (degbound == 0)
+  {int w;
+    for (i = 1; i <= n; i++)
+    {Vt = V,i; w = 0;
+      for (j = 1; j <= size(P); j++)
+      {if (P[j] <= size(Vt))
+        {Vt2 = Vt[(size(Vt)-P[j]+1)..size(Vt)];
+          if (isInMat(Vt2,L[j]) > 0)
+          {w = 1; break;}
+        }
+      }
+      if (w == 0)
+      {vector Vtt;
+        for (it = 1; it <= size(Vt); it++){Vtt = Vtt + Vt[it]*gen(it);}
+        M = M,Vtt;
+        kill Vtt;
+      }
+    }
+    if (size(M)==0) {R = V; return(R);}
+    else
+    {M = simplify(M,2);
+      for (i = 1; i <= size(M); i++)
+      {kill Vt; intvec Vt;
+        for (j =1; j <= size(M[i]); j++){Vt[j] =  int(leadcoef(M[i][j]));}
+        R = R + findmistletoes(Vt,n,L,P);
+      }
+      return(R);
+    }
+  }
+  else
+  {if (size(V) > degbound) {ERROR("monomial exceeds degreebound");}
+    if (size(V) == degbound) {R = V; return(R);}
+    int w;
+    for (i = 1; i <= n; i++)
+    {Vt = V,i; w = 0;
+      for (j = 1; j <= size(P); j++)
+      {if (P[j] <= size(Vt))
+        {Vt2 = Vt[(size(Vt)-P[j]+1)..size(Vt)];
+          if (isInMat(Vt2,L[j]) > 0){w = 1; break;}
+        }
+      }
+      if (w == 0)
+      {vector Vtt;
+        for (it = 1; it <= size(Vt); it++){Vtt = Vtt + Vt[it]*gen(it);}
+        M = M,Vtt;
+        kill Vtt;
+      }
+    }
+    if (size(M) == 0) {R = V; return(R);}
+    else
+    {M = simplify(M,2);
+      for (i = 1; i <= ncols(M); i++)
+      {kill Vt; intvec Vt;
+        for (j =1; j <= size(M[i]); j++)
+        {Vt[j] =  int(leadcoef(M[i][j]));}
+        //Vt; typeof(Vt); size(Vt);
+        R = R + findmistletoes(Vt,n,L,P,degbound);
+      }
+      return(R);
+    }
+  }
+}
+
+static proc isInList(intvec V, list L)
+"USAGE: isInList(V,L); V an intvec, L a list of intvecs
+RETURN: int
+PURPOSE:Finding the position of V in L, returns 0, if V is not in M
+"
+{int i,n;
+  n = 0;
+  for (i = 1; i <= size(L); i++) {if (L[i] == V) {n = i; break;}}
+  return(n);
+}
+
+static proc isInMat(intvec V, intmat M)
+"USAGE: isInMat(V,M);V an intvec, M an intmat
+RETURN: int
+PURPOSE:Finding the position of V in M, returns 0, if V is not in M
+"
+{if (size(V) <> ncols(M)) {return(0);}
+  int i;
+  intvec Vt;
+  for (i = 1; i <= nrows(M); i++)
+  {Vt = M[i,1..ncols(M)];
+    if ((V-Vt) == 0){return(i);}
+  }
+  return(0);
+}
+
+static proc isInVec(int v,intvec V)
+"USAGE: isInVec(v,V); v an integer,V an intvec
+RETURN: int
+PURPOSE:Finding the position of v in V, returns 0, if v is not in V
+"
+{int i,n;
+  n = 0;
+  for (i = 1; i <= size(V); i++) {if (V[i] == v) {n = i; break;}}
+  return(n);
+}
+
+proc ivL2lpI(list L)
+"USAGE: ivL2lpI(L); L a list of intvecs
+RETURN: ideal
+PURPOSE:Transforming a list of intvecs into an ideal of Letterplace monomials.
+@*      For the encoding of the variables see the overview.
+ASSUME: - Intvec corresponds to a Letterplace monomial
+@*      - basering has to be a Letterplace ring
+EXAMPLE: example ivL2lpI; shows examples
+"
+{checkAssumptions(0,L);
+  int i; ideal G;
+  poly p;
+  for (i = 1; i <= size(L); i++)
+  {p = iv2lp(L[i]);
+    G[(size(G) + 1)] = p;
+  }
+  return(G);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y,z),dp;
+  def R = makeLetterplaceRing(5);// constructs a Letterplace ring
+  setring R; //sets basering to Letterplace ring
+  intvec u = 1,1,2; intvec v = 2,1,3; intvec w = 3,1,1;
+  // u = x^2y, v = yxz, w = zx^2 in intvec representation
+  list L = u,v,w;
+  ivL2lpI(L);// invokes the procedure, returns the ideal containing u,v,w
+}
+
+proc iv2lp(intvec I)
+"USAGE: iv2lp(I); I an intvec
+RETURN: poly
+PURPOSE:Transforming an intvec into the corresponding Letterplace polynomial
+@*      For the encoding of the variables see the overview.
+ASSUME: - Intvec corresponds to a Letterplace monomial
+@*      - basering has to be a Letterplace ring
+NOTE:   - Assumptions will not be checked!
+EXAMPLE: example iv2lp; shows examples
+"
+{if (I[1] == 0) {return(1);}
+  int i = size(I);
+  if (i > attrib(basering,"uptodeg")) {ERROR("polynomial exceeds degreebound");}
+  int j; poly p = 1;
+  for (j = 1; j <= i; j++) {if (I[j] > 0) { p = lpMult(p,var(I[j]));}} //ignore zeroes, because they correspond to 1
+  return(p);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y,z),dp;
+  def R = makeLetterplaceRing(5); // constructs a Letterplace ring
+  setring R; //sets basering to Letterplace ring
+  intvec u = 1,1,2; intvec v = 2,1,3; intvec w = 3,1,1;
+  // u = x^2y, v = yxz, w = zx^2 in intvec representation
+  iv2lp(u); // invokes the procedure and returns the corresponding poly
+  iv2lp(v);
+  iv2lp(w);
+}
+
+proc iv2lpList(list L)
+"USAGE: iv2lpList(L); L a list of intmats
+RETURN: ideal
+PURPOSE:Converting a list of intmats into an ideal of corresponding monomials
+@*      The rows of the intmat corresponds to an intvec, which stores the
+@*      monomial.
+@*      For the encoding of the variables see the overview.
+ASSUME: - The rows of each intmat in L must correspond to a Letterplace monomial
+@*      - basering has to be a Letterplace ring
+EXAMPLE: example iv2lpList; shows examples
+"
+{checkAssumptions(0,L);
+  ideal G;
+  int i;
+  for (i = 1; i <= size(L); i++){G = G + iv2lpMat(L[i]);}
+  return(G);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y,z),dp;
+  def R = makeLetterplaceRing(5); // constructs a Letterplace ring
+  setring R; // sets basering to Letterplace ring
+  intmat u[3][1] = 1,1,2; intmat v[1][3] = 2,1,3; intmat w[2][3] = 3,1,1,2,3,1;
+  // defines intmats of different size containing intvec representations of
+  // monomials as rows
+  list L = u,v,w;
+  print(u); print(v); print(w); // shows the intmats contained in L
+  iv2lpList(L); // returns the corresponding monomials as an ideal
+}
+
+
+proc iv2lpMat(intmat M)
+"USAGE: iv2lpMat(M); M an intmat
+RETURN: ideal
+PURPOSE:Converting an intmat into an ideal of the corresponding monomials.
+@*      The rows of the intmat corresponds to an intvec, which stores the
+@*      monomial.
+@*      For the encoding of the variables see the overview.
+ASSUME: - The rows of M must correspond to Letterplace monomials
+@*      - basering has to be a Letterplace ring
+EXAMPLE: example iv2lpMat; shows examples
+"
+{list L = M;
+  checkAssumptions(0,L);
+  kill L;
+  ideal G; poly p;
+  int i; intvec I;
+  for (i = 1; i <= nrows(M); i++)
+  { I = M[i,1..ncols(M)];
+    p = iv2lp(I);
+    G[size(G)+1] = p;
+  }
+  return(G);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y,z),dp;
+  def R = makeLetterplaceRing(5); // constructs a Letterplace ring
+  setring R; // sets basering to Letterplace ring
+  intmat u[3][1] = 1,1,2; intmat v[1][3] = 2,1,3; intmat w[2][3] = 3,1,1,2,3,1;
+  // defines intmats of different size containing intvec representations of
+  // monomials as rows
+  iv2lpMat(u); // returns the monomials contained in u
+  iv2lpMat(v); // returns the monomials contained in v
+  iv2lpMat(w); // returns the monomials contained in w
+}
+
+proc lpId2ivLi(ideal G)
+"USAGE: lpId2ivLi(G); G an ideal
+RETURN: list
+PURPOSE:Transforming an ideal into the corresponding list of intvecs.
+@*      For the encoding of the variables see the overview.
+ASSUME: - basering has to be a Letterplace ring
+EXAMPLE: example lpId2ivLi; shows examples
+"
+{int i,j,k;
+  list M;
+  checkAssumptions(0,M);
+  for (i = 1; i <= size(G); i++) {M[i] = lp2iv(G[i]);}
+  return(M);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y),dp;
+  def R = makeLetterplaceRing(5); // constructs a Letterplace ring
+  setring R; // sets basering to Letterplace ring
+  ideal L = x(1)*x(2),y(1)*y(2),x(1)*y(2)*x(3);
+  lpId2ivLi(L); // returns the corresponding intvecs as a list
+}
+
+proc lp2iv(poly p)
+"USAGE: lp2iv(p); p a poly
+RETURN: intvec
+PURPOSE:Transforming a monomial into the corresponding intvec.
+@*      For the encoding of the variables see the overview.
+ASSUME: - basering has to be a Letterplace ring
+NOTE:   - Assumptions will not be checked!
+EXAMPLE: example lp2iv; shows examples
+"
+{p = normalize(lead(p));
+  intvec I;
+  int i,j;
+  if (deg(p) > attrib(basering,"uptodeg")) {ERROR("Monomial exceeds degreebound");}
+  if (p == 1) {return(I);}
+  if (p == 0) {ERROR("Monomial is not allowed to equal zero");}
+  intvec lep = leadexp(p);
+  for ( i = 1; i <= attrib(basering,"lV"); i++) {if (lep[i] == 1) {I = i; break;}}
+  for (i = (attrib(basering,"lV")+1); i <= size(lep); i++)
+  {if (lep[i] == 1)
+    { j = (i mod attrib(basering,"lV"));
+      if (j == 0) {I = I,attrib(basering,"lV");}
+      else {I = I,j;}
+    }
+    else { if (lep[i] > 1) {ERROR("monomial has a not allowed multidegree");}}
+  }
+  if (I[1] == 0) {ERROR("monomial has a not allowed multidegree");}
+
+  return(I);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y,z),dp;
+  def R = makeLetterplaceRing(5); // constructs a Letterplace ring
+  setring R; // sets basering to Letterplace ring
+  poly p = x(1)*x(2)*z(3); poly q = y(1)*y(2)*x(3)*x(4);
+  poly w= z(1)*y(2)*x(3)*z(4)*z(5);
+  // p,q,w are some polynomials we want to transform into their
+  // intvec representation
+  lp2iv(p); lp2iv(q); lp2iv(w);
+}
+
+proc lp2ivId(ideal G)
+"USAGE: lp2ivId(G); G an ideal
+RETURN: list
+PURPOSE:Converting an ideal into an list of intmats,
+@*      the corresponding intvecs forming the rows.
+@*      For the encoding of the variables see the overview.
+ASSUME: - basering has to be a Letterplace ring
+EXAMPLE: example lp2ivId; shows examples
+"
+{G = normalize(lead(G));
+  intvec I; list L;
+  checkAssumptions(0,L);
+  int i,md;
+  for (i = 1; i <= size(G); i++) { if (md <= deg(G[i])) {md = deg(G[i]);}}
+  while (size(G) > 0)
+  {ideal Gt;
+    for (i = 1; i <= ncols(G); i++) {if (md == deg(G[i])) {Gt = Gt + G[i]; G[i] = 0;}}
+    if (size(Gt) > 0)
+    {G = simplify(G,2);
+      intmat M [size(Gt)][md];
+      for (i = 1; i <= size(Gt); i++) {M[i,1..md] = lp2iv(Gt[i]);}
+      L = insert(L,M);
+      kill M; kill Gt;
+      md = md - 1;
+    }
+    else {kill Gt; md = md - 1;}
+  }
+  return(L);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y,z),dp;
+  def R = makeLetterplaceRing(5); // constructs a Letterplace ring
+  setring R; // sets basering to Letterplace ring
+  poly p = x(1)*x(2)*z(3); poly q = y(1)*y(2)*x(3)*x(4);
+  poly w = z(1)*y(2)*x(3)*z(4);
+  // p,q,w are some polynomials we want to transform into their
+  // intvec representation
+  ideal G = p,q,w;
+  // define the ideal containing p,q and w
+  lp2ivId(G); // and return the list of intmats for this ideal
+}
+
+// -----------------main procedures----------------------
+
+proc ivDHilbert(list L, int n, list #)
+"USAGE: ivDHilbert(L,n[,degbound]); L a list of intmats, n an integer,
+@*      degbound an optional integer
+RETURN: list
+PURPOSE:Computing the K-dimension and the Hilbert series
+ASSUME: - basering is a Letterplace ring
+@*      - all rows of each intmat correspond to a Letterplace monomial
+@*        for the encoding of the variables see the overview
+@*      - if you specify a different degree bound degbound,
+@*        degbound <= attrib(basering,uptodeg) should hold.
+NOTE: - If L is the list returned, then L[1] is an integer corresponding to the
+@*      dimension, L[2] is an intvec which contains the coefficients of the
+@*      Hilbert series
+@*    - If degbound is set, there will be a degree bound added. By default there
+@*      is no degree bound
+@*    - n is the number of variables
+@*    - If I = L[2] is the intvec returned, then I[k] is the (k-1)-th coefficient of
+@*      the Hilbert series.
+@*    - If the K-dimension is known to be infinite, a degree bound is needed
+EXAMPLE: example ivDHilbert; shows examples
+"
+{int degbound = 0;
+  if (size(#) > 0){if (typeof(#[1])=="int"){if (#[1] > 0){degbound = #[1];}}}
+  checkAssumptions(degbound,L);
+  intvec H; int i,dimen;
+  H = ivHilbert(L,n,degbound);
+  for (i = 1; i <= size(H); i++){dimen = dimen + H[i];}
+  L = dimen,H;
+  return(L);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y),dp;
+  def R = makeLetterplaceRing(5); // constructs a Letterplace ring
+  R;
+  setring R; // sets basering to Letterplace ring
+  //some intmats, which contain monomials in intvec representation as rows
+  intmat I1 [2][2] = 1,1,2,2; intmat I2 [1][3]  = 1,2,1;
+  intmat J1 [1][2] =  1,1; intmat J2 [2][3] = 2,1,2,1,2,1;
+  print(I1);
+  print(I2);
+  print(J1);
+  print(J2);
+  list G = I1,I2; // ideal, which is already a Groebner basis
+  list I = J1,J2; // ideal, which is already a Groebner basis
+  //the procedure without a degree bound
+  ivDHilbert(G,2);
+  // the procedure with degree bound 5
+  ivDHilbert(I,2,5);
+}
+
+proc ivDHilbertSickle(list L, int n, list #)
+"USAGE: ivDHilbertSickle(L,n[,degbound]); L a list of intmats, n an integer,
+@*      degbound an optional integer
+RETURN: list
+PURPOSE:Computing K-dimension, Hilbert series and mistletoes
+ASSUME: - basering is a Letterplace ring.
+@*      - All rows of each intmat correspond to a Letterplace monomial.
+@*        for the encoding of the variables see the overview
+@*      - If you specify a different degree bound degbound,
+@*        degbound <= attrib(basering,uptodeg) should hold.
+NOTE: - If L is the list returned, then L[1] is an integer, L[2] is an intvec
+@*      which contains the coefficients of the Hilbert series and L[3]
+@*      is a list, containing the mistletoes as intvecs.
+@*    - If degbound is set, a degree bound will be added. By default there
+@*      is no degree bound.
+@*    - n is the number of variables.
+@*    - If I = L[2] is the intvec returned, then I[k] is the (k-1)-th
+@*      coefficient of the Hilbert series.
+@*    - If the K-dimension is known to be infinite, a degree bound is needed
+EXAMPLE: example ivDHilbertSickle; shows examples
+"
+{int degbound = 0;
+  if (size(#) > 0){if (typeof(#[1])=="int"){if (#[1] > 0){degbound = #[1];}}}
+  checkAssumptions(degbound,L);
+  int i,dimen; list R;
+  R = ivSickleHil(L,n,degbound);
+  for (i = 1; i <= size(R[1]); i++){dimen = dimen + R[1][i];}
+  R[3] = R[2]; R[2] = R[1]; R[1] = dimen;
+  return(R);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y),dp;
+  def R = makeLetterplaceRing(5); // constructs a Letterplace ring
+  R;
+  setring R; // sets basering to Letterplace ring
+  //some intmats, which contain monomials in intvec representation as rows
+  intmat I1 [2][2] = 1,1,2,2; intmat I2 [1][3]  = 1,2,1;
+  intmat J1 [1][2] =  1,1; intmat J2 [2][3] = 2,1,2,1,2,1;
+  print(I1);
+  print(I2);
+  print(J1);
+  print(J2);
+  list G = I1,I2;// ideal, which is already a Groebner basis
+  list I = J1,J2; // ideal, which is already a Groebner basis
+  ivDHilbertSickle(G,2); // invokes the procedure without a degree bound
+  ivDHilbertSickle(I,2,3); // invokes the procedure with degree bound 3
+}
+
+proc ivDimCheck(list L, int n)
+"USAGE: ivDimCheck(L,n); L a list of intmats, n an integer
+RETURN: int, 0 if the dimension is finite, or 1 otherwise
+PURPOSE:Decides, whether the K-dimension is finite or not
+ASSUME: - basering is a Letterplace ring
+@*      - All rows of each intmat correspond to a Letterplace monomial
+@*        For the encoding of the variables see the overview.
+NOTE:   - n is the number of variables
+EXAMPLE: example ivDimCheck; shows examples
+"
+{checkAssumptions(0,L);
+  int i,r;
+  intvec P,H;
+  for (i = 1; i <= size(L); i++)
+  {P[i] = ncols(L[i]);
+    if (P[i] == 1) {if (isInMat(H,L[i]) > 0) {ERROR("Quotient algebra is trivial");}}
+  }
+  if (size(L) == 0) {ERROR("GB is empty, quotient algebra corresponds to free algebra");}
+  kill H;
+  intmat S; int sd,ld; intvec V;
+  sd = P[1]; ld = P[1];
+  for (i = 2; i <= size(P); i++)
+  {if (P[i] < sd) {sd = P[i];}
+    if (P[i] > ld) {ld = P[i];}
+  }
+  sd = (sd - 1); ld = ld - 1;
+  if (ld == 0) { return(allVars(L,P,n));}
+  if (sd == 0) { for (i = 1; i <= size(L); i++){if (ncols(L[i]) == 1){S = createStartMat1(n,L[i]); break;}}}
+  else {S = createStartMat(sd,n);}
+  module M;
+  for (i = 1; i <= nrows(S); i++)
+  {V = S[i,1..ncols(S)];
+    if (findCycle(V,L,P,n,ld,M)) {r = 1; break;}
+  }
+  return(r);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y),dp;
+  def R = makeLetterplaceRing(5); // constructs a Letterplace ring
+  R;
+  setring R; // sets basering to Letterplace ring
+  //some intmats, which contain monomials in intvec representation as rows
+  intmat I1 [2][2] = 1,1,2,2; intmat I2 [1][3]  = 1,2,1;
+  intmat J1 [1][2] =  1,1; intmat J2 [2][3] = 2,1,2,1,2,1;
+  print(I1);
+  print(I2);
+  print(J1);
+  print(J2);
+  list G = I1,I2;// ideal, which is already a Groebner basis
+  list I = J1,J2; // ideal, which is already a Groebner basis and which
+  ivDimCheck(G,2); // invokes the procedure, factor is of finite K-dimension
+  ivDimCheck(I,2); // invokes the procedure, factor is not of finite K-dimension
+}
+
+proc ivHilbert(list L, int n, list #)
+"USAGE: ivHilbert(L,n[,degbound]); L a list of intmats, n an integer,
+@*      degbound an optional integer
+RETURN: intvec, containing the coefficients of the Hilbert series
+PURPOSE:Computing the Hilbert series
+ASSUME: - basering is a Letterplace ring.
+@*      - all rows of each intmat correspond to a Letterplace monomial
+@*        for the encoding of the variables see the overview
+@*      - if you specify a different degree bound degbound,
+@*       degbound <= attrib(basering,uptodeg) should hold.
+NOTE: - If degbound is set, a degree bound  will be added. By default there
+@*      is no degree bound.
+@*    - n is the number of variables.
+@*    - If I is returned, then I[k] is the (k-1)-th coefficient of the Hilbert
+@*      series.
+@*    - If the K-dimension is known to be infinite, a degree bound is needed
+EXAMPLE: example ivHilbert; shows examples
+"
+{int degbound = 0;
+  if (size(#) > 0) {if (typeof(#[1])=="int"){if (#[1] > 0) {degbound = #[1];}}}
+  intvec P,H; int i;
+  for (i = 1; i <= size(L); i++)
+  {P[i] = ncols(L[i]);
+    if (P[i] == 1) {if ( isInMat(H,L[i]) > 0) {ERROR("Quotient algebra is trivial");}}
+  }
+  if (size(L) == 0) {ERROR("GB is empty, quotient algebra corresponds to free algebra");}
+  H[1] = 1;
+  checkAssumptions(degbound,L);
+  if (degbound == 0)
+  {int sd;
+    intmat S;
+    sd = P[1];
+    for (i = 2; i <= size(P); i++) {if (P[i] < sd) {sd = P[i];}}
+    sd = (sd - 1);
+    if (sd == 0) { for (i = 1; i <= size(L); i++){if (ncols(L[i]) == 1){S = createStartMat1(n,L[i]); break;}}}
+    else {S = createStartMat(sd,n);}
+    if (intvec(S) == 0) {return(H);}
+    for (i = 1; i <= sd; i++) {H = H,(n^i);}
+    for (i = 1; i <= nrows(S); i++)
+    {intvec St = S[i,1..ncols(S)];
+      H = findHCoeff(St,n,L,P,H);
+      kill St;
+    }
+    return(H);
+  }
+  else
+  {for (i = 1; i <= size(P); i++)
+    {if (P[i] > degbound) {ERROR("degreebound is too small, GB contains elements of higher degree");}}
+    int sd;
+    intmat S;
+    sd = P[1];
+    for (i = 2; i <= size(P); i++) {if (P[i] < sd) {sd = P[i];}}
+    sd = (sd - 1);
+    if (sd == 0) { for (i = 1; i <= size(L); i++){if (ncols(L[i]) == 1){S = createStartMat1(n,L[i]); break;}}}
+    else {S = createStartMat(sd,n);}
+    if (intvec(S) == 0) {return(H);}
+    for (i = 1; i <= sd; i++) {H = H,(n^i);}
+    for (i = 1; i <= nrows(S); i++)
+    {intvec St = S[i,1..ncols(S)];
+      H = findHCoeff(St,n,L,P,H,degbound);
+      kill St;
+    }
+    return(H);
+  }
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y),dp;
+  def R = makeLetterplaceRing(5); // constructs a Letterplace ring
+  R;
+  setring R; // sets basering to Letterplace ring
+  //some intmats, which contain monomials in intvec representation as rows
+  intmat I1 [2][2] = 1,1,2,2; intmat I2 [1][3]  = 1,2,1;
+  intmat J1 [1][2] =  1,1; intmat J2 [2][3] = 2,1,2,1,2,1;
+  print(I1);
+  print(I2);
+  print(J1);
+  print(J2);
+  list G = I1,I2; // ideal, which is already a Groebner basis
+  list I = J1,J2; // ideal, which is already a Groebner basis
+  ivHilbert(G,2); // invokes the procedure without any degree bound
+  ivHilbert(I,2,5); // invokes the procedure with degree bound 5
+}
+
+
+proc ivKDim(list L, int n, list #)
+"USAGE: ivKDim(L,n[,degbound]); L a list of intmats,
+@*      n an integer, degbound an optional integer
+RETURN: int, the K-dimension of A/<L>
+PURPOSE:Computing the K-dimension of A/<L>
+ASSUME: - basering is a Letterplace ring.
+@*      - all rows of each intmat correspond to a Letterplace monomial
+@*        for the encoding of the variables see the overview
+@*      - if you specify a different degree bound degbound,
+@*        degbound <= attrib(basering,uptodeg) should hold.
+NOTE: - If degbound is set, a degree bound will be added. By default there
+@*      is no degree bound.
+@*    - n is the number of variables.
+@*    - If the K-dimension is known to be infinite, a degree bound is needed
+EXAMPLE: example ivKDim; shows examples
+"
+{int degbound = 0;
+  if (size(#) > 0) {if (typeof(#[1])=="int"){if (#[1] > 0) {degbound = #[1];}}}
+  intvec P,H; int i;
+  for (i = 1; i <= size(L); i++)
+  {P[i] = ncols(L[i]);
+    if (P[i] == 1) {if ( isInMat(H,L[i]) > 0) {ERROR("Quotient algebra is trivial");}}
+  }
+  if (size(L) == 0) {ERROR("GB is empty, quotient algebra corresponds to free algebra");}
+  kill H;
+  checkAssumptions(degbound,L);
+  if (degbound == 0)
+  {int sd; int dimen = 1;
+    intmat S;
+    sd = P[1];
+    for (i = 2; i <= size(P); i++) {if (P[i] < sd) {sd = P[i];}}
+    sd = (sd - 1);
+    if (sd == 0) { for (i = 1; i <= size(L); i++){if (ncols(L[i]) == 1){S = createStartMat1(n,L[i]); break;}}}
+    else {S = createStartMat(sd,n);}
+    if (intvec(S) == 0) {return(dimen);}
+    for (i = 1; i <= sd; i++) {dimen = dimen +(n^i);}
+    for (i = 1; i <= nrows(S); i++)
+    {intvec St = S[i,1..ncols(S)];
+      dimen = dimen + findDimen(St,n,L,P);
+      kill St;
+    }
+    return(dimen);
+  }
+  else
+  {for (i = 1; i <= size(P); i++)
+    {if (P[i] > degbound) {ERROR("degreebound is too small, GB contains elements of higher degree");}}
+    int sd; int dimen = 1;
+    intmat S;
+    sd = P[1];
+    for (i = 2; i <= size(P); i++) {if (P[i] < sd) {sd = P[i];}}
+    sd = (sd - 1);
+    if (sd == 0) { for (i = 1; i <= size(L); i++){if (ncols(L[i]) == 1){S = createStartMat1(n,L[i]); break;}}}
+    else {S = createStartMat(sd,n);}
+    if (intvec(S) == 0) {return(dimen);}
+    for (i = 1; i <= sd; i++) {dimen = dimen +(n^i);}
+    for (i = 1; i <= nrows(S); i++)
+    {intvec St = S[i,1..ncols(S)];
+      dimen = dimen + findDimen(St,n,L,P, degbound);
+      kill St;
+    }
+    return(dimen);
+  }
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y),dp;
+  def R = makeLetterplaceRing(5); // constructs a Letterplace ring
+  R;
+  setring R; // sets basering to Letterplace ring
+  //some intmats, which contain monomials in intvec representation as rows
+  intmat I1 [2][2] = 1,1,2,2; intmat I2 [1][3]  = 1,2,1;
+  intmat J1 [1][2] =  1,1; intmat J2 [2][3] = 2,1,2,1,2,1;
+  print(I1);
+  print(I2);
+  print(J1);
+  print(J2);
+  list G = I1,I2; // ideal, which is already a Groebner basis
+  list I = J1,J2; // ideal, which is already a Groebner basis
+  ivKDim(G,2); // invokes the procedure without any degree bound
+  ivKDim(I,2,5); // invokes the procedure with degree bound 5
+}
+
+proc ivMis2Base(list M)
+"USAGE: ivMis2Base(M); M a list of intvecs
+RETURN: ideal, a K-base of the given algebra
+PURPOSE:Computing the K-base out of given mistletoes
+ASSUME: - The mistletoes have to be ordered lexicographically -> OrdMisLex.
+@*        Otherwise there might some elements missing.
+@*      - basering is a Letterplace ring.
+@*      - mistletoes are stored as intvecs, as described in the overview
+EXAMPLE: example ivMis2Base; shows examples
+"
+{
+//checkAssumptions(0,M);
+  intvec L,A;
+  if (size(M) == 0){ERROR("There are no mistletoes, so it appears your dimension is infinite!");}
+  if (isInList(L,M) > 0) {print("1 is a mistletoe, therefore 1 is the only basis element"); return(list(intvec(0)));}
+  int i,j,d,s;
+  list Rt;
+  Rt[1] = intvec(0);
+  L = M[1];
+  for (i = size(L); 1 <= i; i--) {Rt = insert(Rt,intvec(L[1..i]));}
+  for (i = 2; i <= size(M); i++)
+  {A = M[i]; L = M[i-1];
+   s = size(A);
+   if (s > size(L))
+   {d = size(L);
+    for (j = s; j > d; j--) {Rt = insert(Rt,intvec(A[1..j]));}
+    A = A[1..d];
+   }
+   if (size(L) > s){L = L[1..s];}
+   while (A <> L)
+   {Rt = insert(Rt, intvec(A));
+    if (size(A) > 1)
+    {A = A[1..(size(A)-1)];
+     L = L[1..(size(L)-1)];
+    }
+    else {break;}
+   }
+  }
+  return(Rt);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y),dp;
+  def R = makeLetterplaceRing(5); // constructs a Letterplace ring
+  R;
+  setring R; // sets basering to Letterplace ring
+  intvec i1 = 1,2; intvec i2 = 2,1,2;
+  // the mistletoes are xy and yxy, which are already ordered lexicographically
+  list L = i1,i2;
+  ivMis2Base(L); // returns the basis of the factor algebra
+}
+
+
+proc ivMis2Dim(list M)
+"USAGE: ivMis2Dim(M); M a list of intvecs
+RETURN: int, the K-dimension of the given algebra
+PURPOSE:Computing the K-dimension out of given mistletoes
+ASSUME: - The mistletoes have to be ordered lexicographically -> OrdMisLex.
+@*        Otherwise the returned value may differ from the K-dimension.
+@*      - basering is a Letterplace ring.
+@*      - mistletoes are stored as intvecs, as described in the overview
+EXAMPLE: example ivMis2Dim; shows examples
+"
+{checkAssumptions(0,M);
+  intvec L;
+  if (size(M) == 0){ERROR("There are no mistletoes, so it appears your dimension is infinite!");}
+  if (isInList(L,M) > 0) {print("1 is a mistletoe, therefore dim = 1"); return(1);}
+  int i,j,d,s;
+  d = 1 + size(M[1]);
+  for (i = 1; i < size(M); i++)
+  {j = 1;
+   s = size(M[i]); if (s > size(M[i+1])){s = size(M[i+1]);}
+   while ((M[i][j] == M[i+1][j]) && (j <= s)){j = j + 1;}
+   d = d + size(M[i+1])- j + 1;
+  }
+  return(d);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y),dp;
+  def R = makeLetterplaceRing(5); // constructs a Letterplace ring
+  R;
+  setring R; // sets basering to Letterplace ring
+  intvec i1 = 1,2; intvec i2 = 2,1,2;
+  // the mistletoes are xy and yxy, which are already ordered lexicographically
+  list L = i1,i2;
+  ivMis2Dim(L); // returns the dimension of the factor algebra
+}
+
+proc ivOrdMisLex(list M)
+"USAGE: ivOrdMisLex(M); M a list of intvecs
+RETURN: list, containing the ordered intvecs of M
+PURPOSE:Orders a given set of mistletoes lexicographically
+ASSUME: - basering is a Letterplace ring.
+@*      - intvecs correspond to monomials, as explained in the overview
+NOTE:   - This is preprocessing, it's not needed if the mistletoes are returned
+@*        from the sickle algorithm.
+@*      - Each entry of the list returned is an intvec.
+EXAMPLE: example ivOrdMisLex; shows examples
+"
+{checkAssumptions(0,M);
+  return(sort(M)[1]);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y),dp;
+  def R = makeLetterplaceRing(5); // constructs a Letterplace ring
+  setring R; // sets basering to Letterplace ring
+  intvec i1 = 1,2,1; intvec i2 = 2,2,1; intvec i3 = 1,1; intvec i4 = 2,1,1,1;
+  // the corresponding monomials are xyx,y^2x,x^2,yx^3
+  list M = i1,i2,i3,i4;
+  M;
+  ivOrdMisLex(M);// orders the list of monomials
+}
+
+proc ivSickle(list L, int n, list #)
+"USAGE: ivSickle(L,n,[degbound]); L a list of intmats, n an int, degbound an
+@*      optional integer
+RETURN: list, containing intvecs, the mistletoes of A/<L>
+PURPOSE:Computing the mistletoes for a given Groebner basis L, given by intmats
+ASSUME: - basering is a Letterplace ring.
+@*      - all rows of each intmat correspond to a Letterplace monomial
+@*        as explained in the overview
+@*      - if you specify a different degree bound degbound,
+@*        degbound <= attrib(basering,uptodeg) should hold.
+NOTE: - If degbound is set, a degree bound will be added. By default there
+@*      is no degree bound.
+@*    - n is the number of variables.
+@*    - If the K-dimension is known to be infinite, a degree bound is needed
+EXAMPLE: example ivSickle; shows examples
+"
+{list M;
+  int degbound = 0;
+  if (size(#) > 0){if (typeof(#[1])=="int"){if (#[1] > 0){degbound = #[1];}}}
+  int i;
+  intvec P,H;
+  for (i = 1; i <= size(L); i++)
+  {P[i] = ncols(L[i]);
+    if (P[i] == 1) {if (isInMat(H,L[i]) > 0) {ERROR("Quotient algebra is trivial");}}
+  }
+  if (size(L) == 0) {ERROR("GB is empty, quotient algebra corresponds to free algebra");}
+  kill H;
+  checkAssumptions(degbound,L);
+  if (degbound == 0)
+  {intmat S; int sd;
+    sd = P[1];
+    for (i = 2; i <= size(P); i++) {if (P[i] < sd) {sd = P[i];}}
+    sd = (sd - 1);
+    if (sd == 0) { for (i = 1; i <= size(L); i++){if (ncols(L[i]) == 1){S = createStartMat1(n,L[i]); break;}}}
+    else {S = createStartMat(sd,n);}
+    if (intvec(S) == 0) {return(list (intvec(0)));}
+    for (i = 1; i <= nrows(S); i++)
+    {intvec St = S[i,1..ncols(S)];
+      M = M + findmistletoes(St,n,L,P);
+      kill St;
+    }
+    return(M);
+  }
+  else
+  {for (i = 1; i <= size(P); i++)
+    {if (P[i] > degbound) {ERROR("degreebound is too small, GB contains elements of higher degree");}}
+    intmat S; int sd;
+    sd = P[1];
+    for (i = 2; i <= size(P); i++) {if (P[i] < sd) {sd = P[i];}}
+    sd = (sd - 1);
+    if (sd == 0) { for (i = 1; i <= size(L); i++){if (ncols(L[i]) == 1){S = createStartMat1(n,L[i]); break;}}}
+    else {S = createStartMat(sd,n);}
+    if (intvec(S) == 0) {return(list (intvec(0)));}
+    for (i = 1; i <= nrows(S); i++)
+    {intvec St = S[i,1..ncols(S)];
+      M = M + findmistletoes(St,n,L,P,degbound);
+      kill St;
+    }
+    return(M);
+  }
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y),dp;
+  def R = makeLetterplaceRing(5); // constructs a Letterplace ring
+  setring R; // sets basering to Letterplace ring
+  //some intmats, which contain monomials in intvec representation as rows
+  intmat I1 [2][2] = 1,1,2,2; intmat I2 [1][3]  = 1,2,1;
+  intmat J1 [1][2] =  1,1; intmat J2 [2][3] = 2,1,2,1,2,1;
+  print(I1);
+  print(I2);
+  print(J1);
+  print(J2);
+  list G = I1,I2; // ideal, which is already a Groebner basis
+  list I =  J1,J2; // ideal, which is already a Groebner basis
+  ivSickle(G,2); // invokes the procedure without any degree bound
+  ivSickle(I,2,5); // invokes the procedure with degree bound 5
+}
+
+proc ivSickleDim(list L, int n, list #)
+"USAGE: ivSickleDim(L,n[,degbound]); L a list of intmats, n an integer, degbound
+@*      an optional integer
+RETURN: list
+PURPOSE:Computing mistletoes and the K-dimension
+ASSUME: - basering is a Letterplace ring.
+@*      - all rows of each intmat correspond to a Letterplace monomial
+@*        as explained in the overview
+@*      - if you specify a different degree bound degbound,
+@*        degbound <= attrib(basering,uptodeg) should hold.
+NOTE: - If L is the list returned, then L[1] is an integer, L[2] is a list,
+@*      containing the mistletoes as intvecs.
+@*    - If degbound is set, a degree bound will be added. By default there
+@*      is no degree bound.
+@*    - n is the number of variables.
+@*    - If the K-dimension is known to be infinite, a degree bound is needed
+EXAMPLE: example ivSickleDim; shows examples
+"
+{list M;
+  int degbound = 0;
+  if (size(#) > 0){if (typeof(#[1])=="int"){if (#[1] > 0){degbound = #[1];}}}
+  int i,dimen; list R;
+  intvec P,H;
+  for (i = 1; i <= size(L); i++)
+  {P[i] = ncols(L[i]);
+    if (P[i] == 1) {if (isInMat(H,L[i]) > 0) {ERROR("Quotient algebra is trivial, dimension equals zero");}}
+  }
+  if (size(L) == 0) {ERROR("GB is empty, quotient algebra corresponds to free algebra");}
+  kill H;
+  checkAssumptions(degbound,L);
+  if (degbound == 0)
+  {int sd; dimen = 1;
+    intmat S;
+    sd = P[1];
+    for (i = 2; i <= size(P); i++) {if (P[i] < sd) {sd = P[i];}}
+    sd = (sd - 1);
+    if (sd == 0) { for (i = 1; i <= size(L); i++){if (ncols(L[i]) == 1){S = createStartMat1(n,L[i]); break;}}}
+    else {S = createStartMat(sd,n);}
+    if (intvec(S) == 0) {return(list(dimen,list(intvec(0))));}
+    for (i = 1; i <= sd; i++) {dimen = dimen +(n^i);}
+    R[1] = dimen;
+    for (i = 1; i <= nrows(S); i++)
+    {intvec St = S[i,1..ncols(S)];
+      R = findMisDim(St,n,L,P,R);
+      kill St;
+    }
+    return(R);
+  }
+  else
+  {for (i = 1; i <= size(P); i++)
+    {if (P[i] > degbound) {ERROR("degreebound is too small, GB contains elements of higher degree");}}
+    int sd; dimen = 1;
+    intmat S;
+    sd = P[1];
+    for (i = 2; i <= size(P); i++) {if (P[i] < sd) {sd = P[i];}}
+    sd = (sd - 1);
+    if (sd == 0) { for (i = 1; i <= size(L); i++){if (ncols(L[i]) == 1){S = createStartMat1(n,L[i]); break;}}}
+    else {S = createStartMat(sd,n);}
+    if (intvec(S) == 0) {return(list(dimen,list(intvec(0))));}
+    for (i = 1; i <= sd; i++) {dimen = dimen +(n^i);}
+    R[1] = dimen;
+    for (i = 1; i <= nrows(S); i++)
+    {intvec St = S[i,1..ncols(S)];
+      R = findMisDim(St,n,L,P,R,degbound);
+      kill St;
+    }
+    return(R);
+  }
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y),dp;
+  def R = makeLetterplaceRing(5); // constructs a Letterplace ring
+  setring R; // sets basering to Letterplace ring
+  //some intmats, which contain monomials in intvec representation as rows
+  intmat I1 [2][2] = 1,1,2,2; intmat I2 [1][3]  = 1,2,1;
+  intmat J1 [1][2] =  1,1; intmat J2 [2][3] = 2,1,2,1,2,1;
+  print(I1);
+  print(I2);
+  print(J1);
+  print(J2);
+  list G = I1,I2;// ideal, which is already a Groebner basis
+  list I =  J1,J2; // ideal, which is already a Groebner basis
+  ivSickleDim(G,2); // invokes the procedure without any degree bound
+  ivSickleDim(I,2,5); // invokes the procedure with degree bound 5
+}
+
+proc ivSickleHil(list L, int n, list #)
+"USAGE:ivSickleHil(L,n[,degbound]); L a list of intmats, n an integer,
+@*     degbound an optional integer
+RETURN: list
+PURPOSE:Computing the mistletoes and the Hilbert series
+ASSUME: - basering is a Letterplace ring.
+@*      - all rows of each intmat correspond to a Letterplace monomial
+@*        as explained in the overview
+@*      - if you specify a different degree bound degbound,
+@*        degbound <= attrib(basering,uptodeg) should hold.
+NOTE: - If L is the list returned, then L[1] is an intvec, L[2] is a list,
+@*      containing the mistletoes as intvecs.
+@*    - If degbound is set, a degree bound will be added. By default there
+@*      is no degree bound.
+@*    - n is the number of variables.
+@*    - If I = L[1] is the intvec returned, then I[k] is the (k-1)-th
+@*      coefficient of the Hilbert series.
+@*    - If the K-dimension is known to be infinite, a degree bound is needed
+EXAMPLE: example ivSickleHil; shows examples
+"
+{int degbound = 0;
+  if (size(#) > 0) {if (typeof(#[1])=="int"){if (#[1] > 0) {degbound = #[1];}}}
+  intvec P,H; int i; list R;
+  for (i = 1; i <= size(L); i++)
+  {P[i] = ncols(L[i]);
+    if (P[i] == 1) {if ( isInMat(H,L[i]) > 0) {ERROR("Quotient algebra is trivial");}}
+  }
+  if (size(L) == 0) {ERROR("GB is empty, quotient algebra corresponds to free algebra");}
+  H[1] = 1;
+  checkAssumptions(degbound,L);
+  if (degbound == 0)
+  {int sd;
+    intmat S;
+    sd = P[1];
+    for (i = 2; i <= size(P); i++) {if (P[i] < sd) {sd = P[i];}}
+    sd = (sd - 1);
+    if (sd == 0) { for (i = 1; i <= size(L); i++){if (ncols(L[i]) == 1){S = createStartMat1(n,L[i]); break;}}}
+    else {S = createStartMat(sd,n);}
+    if (intvec(S) == 0) {return(list(H,list(intvec (0))));}
+    for (i = 1; i <= sd; i++) {H = H,(n^i);}
+    R[1] = H; kill H;
+    for (i = 1; i <= nrows(S); i++)
+    {intvec St = S[i,1..ncols(S)];
+      R = findHCoeffMis(St,n,L,P,R);
+      kill St;
+    }
+    return(R);
+  }
+  else
+  {for (i = 1; i <= size(P); i++)
+    {if (P[i] > degbound) {ERROR("degreebound is too small, GB contains elements of higher degree");}}
+    int sd;
+    intmat S;
+    sd = P[1];
+    for (i = 2; i <= size(P); i++) {if (P[i] < sd) {sd = P[i];}}
+    sd = (sd - 1);
+    if (sd == 0) { for (i = 1; i <= size(L); i++){if (ncols(L[i]) == 1){S = createStartMat1(n,L[i]); break;}}}
+    else {S = createStartMat(sd,n);}
+    if (intvec(S) == 0) {return(list(H,list(intvec(0))));}
+    for (i = 1; i <= sd; i++) {H = H,(n^i);}
+    R[1] = H; kill H;
+    for (i = 1; i <= nrows(S); i++)
+    {intvec St = S[i,1..ncols(S)];
+      R = findHCoeffMis(St,n,L,P,R,degbound);
+      kill St;
+    }
+    return(R);
+  }
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y),dp;
+  def R = makeLetterplaceRing(5); // constructs a Letterplace ring
+  setring R; // sets basering to Letterplace ring
+  //some intmats, which contain monomials in intvec representation as rows
+  intmat I1[2][2] = 1,1,2,2; intmat I2[1][3]  = 1,2,1;
+  intmat J1[1][2] =  1,1; intmat J2[2][3] = 2,1,2,1,2,1;
+  print(I1);
+  print(I2);
+  print(J1);
+  print(J2);
+  list G = I1,I2;// ideal, which is already a Groebner basis
+  list I =  J1,J2; // ideal, which is already a Groebner basis
+  ivSickleHil(G,2); // invokes the procedure without any degree bound
+  ivSickleHil(I,2,5); // invokes the procedure with degree bound 5
+}
+
+proc lpDHilbert(ideal G, list #)
+"USAGE: lpDHilbert(G[,degbound,n]); G an ideal, degbound, n optional integers
+RETURN: list
+PURPOSE:Computing K-dimension and Hilbert series, starting with a lp-ideal
+ASSUME: - basering is a Letterplace ring. G is a Letterplace ideal.
+@*      - if you specify a different degree bound degbound,
+@*        degbound <= attrib(basering,uptodeg) should hold.
+NOTE: - If L is the list returned, then L[1] is an integer corresponding to the
+@*      dimension, L[2] is an intvec which contains the coefficients of the
+@*      Hilbert series
+@*    - If degbound is set, there will be a degree bound added. 0 means no
+@*      degree bound. Default: attrib(basering,uptodeg).
+@*    - n can be set to a different number of variables.
+@*      Default: n = attrib(basering, lV).
+@*    - If I = L[2] is the intvec returned, then I[k] is the (k-1)-th
+@*      coefficient of the Hilbert series.
+@*    - If the K-dimension is known to be infinite, a degree bound is needed
+EXAMPLE: example lpDHilbert; shows examples
+"
+{int degbound = attrib(basering,"uptodeg");int n = attrib(basering, "lV");
+  if (size(#) > 0){if (typeof(#[1])=="int"){if (#[1] >= 0){degbound = #[1];}}}
+  if (size(#) > 1){if (typeof(#[1])=="int"){if (#[2] > 0){n = #[2];}}}
+  list L;
+  L = lp2ivId(normalize(lead(G)));
+  return(ivDHilbert(L,n,degbound));
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y),dp;
+  def R = makeLetterplaceRing(5); // constructs a Letterplace ring
+  setring R; // sets basering to Letterplace ring
+  ideal G = x(1)*x(2), y(1)*y(2),x(1)*y(2)*x(3); // ideal G contains a
+  //Groebner basis
+  lpDHilbert(G,5,2); // invokes procedure with degree bound 5 and 2 variables
+  // note that the optional parameters are not necessary, due to the finiteness
+  // of the K-dimension of the factor algebra
+  lpDHilbert(G); // procedure with ring parameters
+  lpDHilbert(G,0); // procedure without degreebound
+}
+
+proc lpDHilbertSickle(ideal G, list #)
+"USAGE: lpDHilbertSickle(G[,degbound,n]); G an ideal, degbound, n optional
+@*      integers
+RETURN: list
+PURPOSE:Computing K-dimension, Hilbert series and mistletoes at once
+ASSUME: - basering is a Letterplace ring.  G is a Letterplace ideal.
+@*      - if you specify a different degree bound degbound,
+@*        degbound <= attrib(basering,uptodeg) should hold.
+NOTE: - If L is the list returned, then L[1] is an integer, the K-dimension,
+@*      L[2] is an intvec, the Hilbert series and L[3] is an ideal,
+@*      the mistletoes
+@*    - If degbound is set, there will be a degree bound added. 0 means no
+@*      degree bound. Default: attrib(basering,uptodeg).
+@*    - n can be set to a different number of variables.
+@*      Default: n = attrib(basering, lV).
+@*    - If I = L[1] is the intvec returned, then I[k] is the (k-1)-th
+@*      coefficient of the Hilbert series.
+@*    - If the K-dimension is known to be infinite, a degree bound is needed
+EXAMPLE: example lpDHilbertSickle; shows examples
+"
+{int degbound = attrib(basering,"uptodeg");int n = attrib(basering, "lV");
+  if (size(#) > 0){if (typeof(#[1])=="int"){if (#[1] >= 0){degbound = #[1];}}}
+  if (size(#) > 1){if (typeof(#[1])=="int"){if (#[2] > 0){n = #[2];}}}
+  list L;
+  L = lp2ivId(normalize(lead(G)));
+  L = ivDHilbertSickle(L,n,degbound);
+  L[3] =  ivL2lpI(L[3]);
+  return(L);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y),dp;
+  def R = makeLetterplaceRing(5); // constructs a Letterplace ring
+  setring R; // sets basering to Letterplace ring
+  ideal G = x(1)*x(2), y(1)*y(2),x(1)*y(2)*x(3); // ideal G contains a
+  //Groebner basis
+  lpDHilbertSickle(G,5,2); //invokes procedure with degree bound 5 and 2 variables
+  // note that the optional parameters are not necessary, due to the finiteness
+  // of the K-dimension of the factor algebra
+  lpDHilbertSickle(G); // procedure with ring parameters
+  lpDHilbertSickle(G,0); // procedure without degreebound
+}
+
+proc lpHilbert(ideal G, list #)
+"USAGE: lpHilbert(G[,degbound,n]); G an ideal, degbound, n optional integers
+RETURN: intvec, containing the coefficients of the Hilbert series
+PURPOSE:Computing the Hilbert series
+ASSUME: - basering is a Letterplace ring.  G is a Letterplace ideal.
+@*      - if you specify a different degree bound degbound,
+@*        degbound <= attrib(basering,uptodeg) should hold.
+NOTE: - If degbound is set, there will be a degree bound added. 0 means no
+@*      degree bound. Default: attrib(basering,uptodeg).
+@*    - n is the number of variables, which can be set to a different number.
+@*      Default: attrib(basering, lV).
+@*    - If I is returned, then I[k] is the (k-1)-th coefficient of the Hilbert
+@*      series.
+@*    - If the K-dimension is known to be infinite, a degree bound is needed
+EXAMPLE: example lpHilbert; shows examples
+"
+{int degbound = attrib(basering,"uptodeg");int n = attrib(basering, "lV");
+  if (size(#) > 0){if (typeof(#[1])=="int"){if (#[1] >= 0){degbound = #[1];}}}
+  if (size(#) > 1){if (typeof(#[1])=="int"){if (#[2] > 0){n = #[2];}}}
+  list L;
+  L = lp2ivId(normalize(lead(G)));
+  return(ivHilbert(L,n,degbound));
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y),dp;
+  def R = makeLetterplaceRing(5); // constructs a Letterplace ring
+  setring R; // sets basering to Letterplace ring
+  ideal G = x(1)*x(2), y(1)*y(2),x(1)*y(2)*x(3); // ideal G contains a
+  //Groebner basis
+  lpHilbert(G,5,2); // invokes procedure with degree bound 5 and 2 variables
+  // note that the optional parameters are not necessary, due to the finiteness
+  // of the K-dimension of the factor algebra
+  lpDHilbert(G); // procedure with ring parameters
+  lpDHilbert(G,0); // procedure without degreebound
+}
+
+proc lpDimCheck(ideal G)
+"USAGE: lpDimCheck(G);
+RETURN: int, 1 if K-dimension of the factor algebra is infinite, 0 otherwise
+PURPOSE:Checking a factor algebra for finiteness of the K-dimension
+ASSUME: - basering is a Letterplace ring.  G is a Letterplace ideal.
+EXAMPLE: example lpDimCheck; shows examples
+"
+{int n = attrib(basering,"lV");
+  list L;
+  ideal R;
+  R = normalize(lead(G));
+  L = lp2ivId(R);
+  return(ivDimCheck(L,n));
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y),dp;
+  def R = makeLetterplaceRing(5); // constructs a Letterplace ring
+  setring R; // sets basering to Letterplace ring
+  ideal G = x(1)*x(2), y(1)*y(2),x(1)*y(2)*x(3);
+  // Groebner basis
+  ideal I = x(1)*x(2), y(1)*x(2)*y(3), x(1)*y(2)*x(3);
+  // Groebner basis
+  lpDimCheck(G); // invokes procedure, factor algebra is of finite K-dimension
+  lpDimCheck(I); // invokes procedure, factor algebra is of infinite Kdimension
+}
+
+proc lpKDim(ideal G, list #)
+"USAGE: lpKDim(G[,degbound, n]); G an ideal, degbound, n optional integers
+RETURN: int, the K-dimension of the factor algebra
+PURPOSE:Computing the K-dimension of a factor algebra, given via an ideal
+ASSUME: - basering is a Letterplace ring. G is a Letterplace ideal.
+@*      - if you specify a different degree bound degbound,
+@*        degbound <= attrib(basering,uptodeg) should hold.
+NOTE: - If degbound is set, there will be a degree bound added. 0 means no
+@*      degree bound. Default: attrib(basering, uptodeg).
+@*    - n is the number of variables, which can be set to a different number.
+@*      Default: attrib(basering, lV).
+@*    - If the K-dimension is known to be infinite, a degree bound is needed
+EXAMPLE: example lpKDim; shows examples
+"
+{int degbound = attrib(basering, "uptodeg");int n = attrib(basering, "lV");
+  if (size(#) > 0){if (typeof(#[1])=="int"){if (#[1] >= 0){degbound = #[1];}}}
+  if (size(#) > 1){if (typeof(#[1])=="int"){if (#[2] > 0){n = #[2];}}}
+  list L;
+  L = lp2ivId(normalize(lead(G)));
+  return(ivKDim(L,n,degbound));
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y),dp;
+  def R = makeLetterplaceRing(5); // constructs a Letterplace ring
+  setring R; // sets basering to Letterplace ring
+  ideal G = x(1)*x(2), y(1)*y(2),x(1)*y(2)*x(3);
+  // ideal G contains a Groebner basis
+  lpKDim(G); //procedure invoked with ring parameters
+  // the factor algebra is finite, so the degree bound given by the Letterplace
+  // ring is not necessary
+  lpKDim(G,0); // procedure without any degree bound
+}
+
+proc lpMis2Base(ideal M)
+"USAGE: lpMis2Base(M); M an ideal
+RETURN: ideal, a K-basis of the factor algebra
+PURPOSE:Computing a K-basis out of given mistletoes
+ASSUME: - basering is a Letterplace ring. G is a Letterplace ideal.
+@*      - M contains only monomials
+NOTE:   - The mistletoes have to be ordered lexicographically -> OrdMisLex.
+EXAMPLE: example lpMis2Base; shows examples
+"
+{list L;
+  L = lpId2ivLi(M);
+  return(ivL2lpI(ivMis2Base(L)));
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y),dp;
+  def R = makeLetterplaceRing(5); // constructs a Letterplace ring
+  setring R; // sets basering to Letterplace ring
+  ideal L = x(1)*y(2),y(1)*x(2)*y(3);
+  // ideal containing the mistletoes
+  lpMis2Base(L); // returns the K-basis of the factor algebra
+}
+
+proc lpMis2Dim(ideal M)
+"USAGE: lpMis2Dim(M); M an ideal
+RETURN: int, the K-dimension of the factor algebra
+PURPOSE:Computing the K-dimension out of given mistletoes
+ASSUME: - basering is a Letterplace ring. G is a Letterplace ideal.
+@*      - M contains only monomials
+NOTE:   - The mistletoes have to be ordered lexicographically -> OrdMisLex.
+EXAMPLE: example lpMis2Dim; shows examples
+"
+{list L;
+  L = lpId2ivLi(M);
+  return(ivMis2Dim(L));
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y),dp;
+  def R = makeLetterplaceRing(5); // constructs a Letterplace ring
+  setring R; // sets basering to Letterplace ring
+  ideal L = x(1)*y(2),y(1)*x(2)*y(3);
+  // ideal containing the mistletoes
+  lpMis2Dim(L); // returns the K-dimension of the factor algebra
+}
+
+proc lpOrdMisLex(ideal M)
+"USAGE: lpOrdMisLex(M); M an ideal of mistletoes
+RETURN: ideal, containing the mistletoes, ordered lexicographically
+PURPOSE:A given set of mistletoes is ordered lexicographically
+ASSUME: - basering is a Letterplace ring. G is a Letterplace ideal.
+NOTE:   This is preprocessing, it is not needed if the mistletoes are returned
+@*      from the sickle algorithm.
+EXAMPLE: example lpOrdMisLex; shows examples
+"
+{return(ivL2lpI(sort(lpId2ivLi(M))[1]));}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y),dp;
+  def R = makeLetterplaceRing(5); // constructs a Letterplace ring
+  setring R; // sets basering to Letterplace ring
+  ideal M = x(1)*y(2)*x(3), y(1)*y(2)*x(3), x(1)*x(2), y(1)*x(2)*x(3)*x(4);
+  // some monomials
+  lpOrdMisLex(M); // orders the monomials lexicographically
+}
+
+proc lpSickle(ideal G,  list #)
+"USAGE: lpSickle(G[,degbound,n]); G an ideal, degbound, n optional integers
+RETURN: ideal
+PURPOSE:Computing the mistletoes of K[X]/<G>
+ASSUME: - basering is a Letterplace ring. G is a Letterplace ideal.
+@*      - if you specify a different degree bound degbound,
+@*        degbound <= attrib(basering,uptodeg) should hold.
+NOTE: - If degbound is set, there will be a degree bound added. 0 means no
+@*      degree bound. Default: attrib(basering,uptodeg).
+@*    - n is the number of variables, which can be set to a different number.
+@*      Default: attrib(basering, lV).
+@*    - If the K-dimension is known to be infinite, a degree bound is needed
+EXAMPLE: example lpSickle; shows examples
+"
+{int degbound = attrib(basering,"uptodeg"); int n = attrib(basering, "lV");
+  if (size(#) > 0){if (typeof(#[1])=="int"){if (#[1] >= 0){degbound = #[1];}}}
+  if (size(#) > 1){if (typeof(#[1])=="int"){if (#[2] > 0){n = #[2];}}}
+  list L; ideal R;
+  R = normalize(lead(G));
+  L = lp2ivId(R);
+  L = ivSickle(L,n,degbound);
+  R = ivL2lpI(L);
+  return(R);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y),dp;
+  def R = makeLetterplaceRing(5); // constructs a Letterplace ring
+  setring R; // sets basering to Letterplace ring
+  ideal G = x(1)*x(2), y(1)*y(2),x(1)*y(2)*x(3); // ideal G contains a
+  //Groebner basis
+  lpSickle(G); //invokes the procedure with ring parameters
+  // the factor algebra is finite, so the degree bound given by the Letterplace
+  // ring is not necessary
+  lpSickle(G,0); // procedure without any degree bound
+}
+
+proc lpSickleDim(ideal G, list #)
+"USAGE: lpSickleDim(G[,degbound,n]); G an ideal, degbound, n optional integers
+RETURN: list
+PURPOSE:Computing the K-dimension and the mistletoes
+ASSUME: - basering is a Letterplace ring. G is a Letterplace ideal.
+@*      - if you specify a different degree bound degbound,
+@*        degbound <= attrib(basering,uptodeg) should hold.
+NOTE: - If L is the list returned, then L[1] is an integer, the K-dimension,
+@*      L[2] is an ideal, the mistletoes.
+@*    - If degbound is set, there will be a degree bound added. 0 means no
+@*      degree bound. Default: attrib(basering,uptodeg).
+@*    - n is the number of variables, which can be set to a different number.
+@*      Default: attrib(basering, lV).
+@*    - If the K-dimension is known to be infinite, a degree bound is needed
+EXAMPLE: example lpSickleDim; shows examples
+"
+{int degbound = attrib(basering,"uptodeg");int n = attrib(basering, "lV");
+  if (size(#) > 0){if (typeof(#[1])=="int"){if (#[1] >= 0){degbound = #[1];}}}
+  if (size(#) > 1){if (typeof(#[1])=="int"){if (#[2] > 0){n = #[2];}}}
+  list L;
+  L = lp2ivId(normalize(lead(G)));
+  L = ivSickleDim(L,n,degbound);
+  L[2] = ivL2lpI(L[2]);
+  return(L);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y),dp;
+  def R = makeLetterplaceRing(5); // constructs a Letterplace ring
+  setring R; // sets basering to Letterplace ring
+  ideal G = x(1)*x(2), y(1)*y(2),x(1)*y(2)*x(3); // ideal G contains a
+  //Groebner basis
+  lpSickleDim(G); // invokes the procedure with ring parameters
+  // the factor algebra is finite, so the degree bound given by the Letterplace
+  // ring is not necessary
+  lpSickleDim(G,0); // procedure without any degree bound
+}
+
+proc lpSickleHil(ideal G, list #)
+"USAGE: lpSickleHil(G);
+RETURN: list
+PURPOSE:Computing the Hilbert series and the mistletoes
+ASSUME: - basering is a Letterplace ring. G is a Letterplace ideal.
+@*      - if you specify a different degree bound degbound,
+@*        degbound <= attrib(basering,uptodeg) should hold.
+NOTE: - If L is the list returned, then L[1] is an intvec, corresponding to the
+@*      Hilbert series, L[2] is an ideal, the mistletoes.
+@*    - If degbound is set, there will be a degree bound added. 0 means no
+@*      degree bound. Default: attrib(basering,uptodeg).
+@*    - n is the number of variables, which can be set to a different number.
+@*      Default: attrib(basering, lV).
+@*    - If I = L[1] is the intvec returned, then I[k] is the (k-1)-th
+@*      coefficient of the Hilbert series.
+@*    - If the K-dimension is known to be infinite, a degree bound is needed
+EXAMPLE: example lpSickleHil; shows examples
+"
+{int degbound = attrib(basering,"uptodeg");int n = attrib(basering, "lV");
+  if (size(#) > 0){if (typeof(#[1])=="int"){if (#[1] >= 0){degbound = #[1];}}}
+  if (size(#) > 1){if (typeof(#[1])=="int"){if (#[2] > 0){n = #[2];}}}
+  list L;
+  L = lp2ivId(normalize(lead(G)));
+  L = ivSickleHil(L,n,degbound);
+  L[2] =  ivL2lpI(L[2]);
+  return(L);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y),dp;
+  def R = makeLetterplaceRing(5); // constructs a Letterplace ring
+  setring R; // sets basering to Letterplace ring
+  ideal G = x(1)*x(2), y(1)*y(2),x(1)*y(2)*x(3); // ideal G contains a
+  //Groebner basis
+  lpSickleHil(G); // invokes the procedure with ring parameters
+  // the factor algebra is finite, so the degree bound given by the Letterplace
+  // ring is not necessary
+  lpSickleHil(G,0); // procedure without any degree bound
+}
+
+proc sickle(ideal G, list #)
+"USAGE: sickle(G[,m, d, h, degbound]); G an ideal; m,d,h,degbound optional
+@*      integers
+RETURN: list
+PURPOSE:Allowing the user to access all procs with one command
+ASSUME: - basering is a Letterplace ring. G is a Letterplace ideal.
+@*      - if you specify a different degree bound degbound,
+@*        degbound <= attrib(basering,uptodeg) should hold.
+NOTE:   The returned object will always be a list, but the entries of the
+@*      returned list may be very different
+@* case m=1,d=1,h=1: see lpDHilbertSickle
+@* case m=1,d=1,h=0: see lpSickleDim
+@* case m=1,d=0,h=1: see lpSickleHil
+@* case m=1,d=0,h=0: see lpSickle (this is the default case)
+@* case m=0,d=1,h=1: see lpDHilbert
+@* case m=0,d=1,h=0: see lpKDim
+@* case m=0,d=0,h=1: see lpHilbert
+@* case m=0,d=0,h=0: returns an error
+@*    - If degbound is set, there will be a degree bound added. 0 means no
+@*      degree bound. Default: attrib(basering,uptodeg).
+@*    - If the K-dimension is known to be infinite, a degree bound is needed
+EXAMPLE: example sickle; shows examples
+"
+{int m,d,h,degbound;
+  m = 1; d = 0; h = 0; degbound = attrib(basering,"uptodeg");
+  if (size(#) > 0) {if (typeof(#[1])=="int"){if (#[1] < 1) {m = 0;}}}
+  if (size(#) > 1) {if (typeof(#[1])=="int"){if (#[2] > 0) {d = 1;}}}
+  if (size(#) > 2) {if (typeof(#[1])=="int"){if (#[3] > 0) {h = 1;}}}
+  if (size(#) > 3) {if (typeof(#[1])=="int"){if (#[4] >= 0) {degbound = #[4];}}}
+  if (m == 1)
+  {if (d == 0)
+    {if (h == 0) {return(lpSickle(G,degbound,attrib(basering,"lV")));}
+      else        {return(lpSickleHil(G,degbound,attrib(basering,"lV")));}
+    }
+    else
+    {if (h == 0) {return(lpSickleDim(G,degbound,attrib(basering,"lV")));}
+      else {return(lpDHilbertSickle(G,degbound,attrib(basering,"lV")));}
+    }
+  }
+  else
+  {if (d == 0)
+    {if (h == 0) {ERROR("You request to do nothing, so relax and do so");}
+      else        {return(lpHilbert(G,degbound,attrib(basering,"lV")));}
+    }
+    else
+    {if (h == 0) {return(lpKDim(G,degbound,attrib(basering,"lV")));}
+      else {return(lpDHilbert(G,degbound,attrib(basering,"lV")));}
+    }
+  }
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y),dp;
+  def R = makeLetterplaceRing(5); // constructs a Letterplace ring
+  setring R; // sets basering to Letterplace ring
+  ideal G = x(1)*x(2), y(1)*y(2),x(1)*y(2)*x(3);
+  // G contains a Groebner basis
+  sickle(G,1,1,1); // computes mistletoes, K-dimension and the Hilbert series
+  sickle(G,1,0,0); // computes mistletoes only
+  sickle(G,0,1,0); // computes K-dimension only
+  sickle(G,0,0,1); // computes Hilbert series only
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+
+proc tst_fpadim()
+{
+  example ivDHilbert;
+  example ivDHilbertSickle;
+  example ivDimCheck;
+  example ivHilbert;
+  example ivKDim;
+  example ivMis2Base;
+  example ivMis2Dim;
+  example ivOrdMisLex;
+  example ivSickle;
+  example ivSickleHil;
+  example ivSickleDim;
+  example lpDHilbert;
+  example lpDHilbertSickle;
+  example lpHilbert;
+  example lpDimCheck;
+  example lpKDim;
+  example lpMis2Base;
+  example lpMis2Dim;
+  example lpOrdMisLex;
+  example lpSickle;
+  example lpSickleHil;
+  example lpSickleDim;
+  example sickle;
+  example ivL2lpI;
+  example iv2lp;
+  example iv2lpList;
+  example iv2lpMat;
+  example lp2iv;
+  example lp2ivId;
+  example lpId2ivLi;
+}
+
+
+
+
+
+/*
+  Here are some examples one may try. Just copy them into your console.
+  These are relations for braid groups, up to degree d:
+
+
+  LIB "fpadim.lib";
+  ring r = 0,(x,y,z),dp;
+  int d =10; // degree
+  def R = makeLetterplaceRing(d);
+  setring R;
+  ideal I = y(1)*x(2)*y(3) - z(1)*y(2)*z(3), x(1)*y(2)*x(3) - z(1)*x(2)*y(3),
+  z(1)*x(2)*z(3) - y(1)*z(2)*x(3), x(1)*x(2)*x(3) + y(1)*y(2)*y(3) +
+  z(1)*z(2)*z(3) + x(1)*y(2)*z(3);
+  option(prot);
+  option(redSB);option(redTail);option(mem);
+  ideal J = system("freegb",I,d,3);
+  lpDimCheck(J);
+  sickle(J,1,1,1,d);//Computes mistletoes, K-dimension and the Hilbert series
+
+
+
+  LIB "fpadim.lib";
+  ring r = 0,(x,y,z),dp;
+  int d =11; // degree
+  def R = makeLetterplaceRing(d);
+  setring R;
+  ideal I = y(1)*x(2)*y(3) - z(1)*y(2)*z(3), x(1)*y(2)*z(3) - z(1)*x(2)*y(3),
+  z(1)*x(2)*z(3) - y(1)*z(2)*x(3), x(1)*x(2)*x(3) + y(1)*y(2)*y(3) +
+  z(1)*z(2)*z(3) + x(1)*y(2)*z(3);
+  option(prot);
+  option(redSB);option(redTail);option(mem);
+  ideal J = system("freegb",I,d,3);
+  lpDimCheck(J);
+  sickle(J,1,1,1,d);
+
+
+
+  LIB "fpadim.lib";
+  ring r = 0,(x,y,z),dp;
+  int d  = 6; // degree
+  def R  = makeLetterplaceRing(d);
+  setring R;
+  ideal I = y(1)*x(2)*y(3) - z(1)*y(2)*z(3), x(1)*y(2)*x(3) - z(1)*x(2)*y(3),
+  z(1)*x(2)*z(3) - y(1)*z(2)*x(3), x(1)*x(2)*x(3) -2*y(1)*y(2)*y(3) + 3*z(1)*z(2)*z(3) -4*x(1)*y(2)*z(3) + 5*x(1)*z(2)*z(3)- 6*x(1)*y(2)*y(3) +7*x(1)*x(2)*z(3) - 8*x(1)*x(2)*y(3);
+  option(prot);
+  option(redSB);option(redTail);option(mem);
+  ideal J = system("freegb",I,d,3);
+  lpDimCheck(J);
+  sickle(J,1,1,1,d);
+*/
+
+/*
+  Here are some examples, which can also be found in [studzins]:
+
+  // takes up to 880Mb of memory
+  LIB "fpadim.lib";
+  ring r = 0,(x,y,z),dp;
+  int d =10; // degree
+  def R = makeLetterplaceRing(d);
+  setring R;
+  ideal I =
+  z(1)*z(2)*z(3)*z(4) + y(1)*x(2)*y(3)*x(4) - x(1)*y(2)*y(3)*x(4) - 3*z(1)*y(2)*x(3)*z(4), x(1)*x(2)*x(3) + y(1)*x(2)*y(3) - x(1)*y(2)*x(3), z(1)*y(2)*x(3)-x(1)*y(2)*z(3) + z(1)*x(2)*z(3);
+  option(prot);
+  option(redSB);option(redTail);option(mem);
+  ideal J = system("freegb",I,d,nvars(r));
+  lpDimCheck(J);
+  sickle(J,1,1,1,d); // dimension is 24872
+
+
+  LIB "fpadim.lib";
+  ring r = 0,(x,y,z),dp;
+  int d =10; // degree
+  def R = makeLetterplaceRing(d);
+  setring R;
+  ideal I = x(1)*y(2) + y(1)*z(2), x(1)*x(2) + x(1)*y(2) - y(1)*x(2) - y(1)*y(2);
+  option(prot);
+  option(redSB);option(redTail);option(mem);
+  ideal J = system("freegb",I,d,3);
+  lpDimCheck(J);
+  sickle(J,1,1,1,d);
+*/
diff --git a/Singular/LIB/freegb.lib b/Singular/LIB/freegb.lib
new file mode 100644
index 0000000..599ad73
--- /dev/null
+++ b/Singular/LIB/freegb.lib
@@ -0,0 +1,3613 @@
+/////////////////////////////////////////////////////////////////////////////
+version="version freegb.lib 4.0.0.0 Jun_2013 "; // $Id: 60903f7719c53dc5b53ffb17de37a0b3053e6181 $
+category="Noncommutative";
+info="
+LIBRARY: freegb.lib   Compute two-sided Groebner bases in free algebras via
+@*                    letterplace
+AUTHORS: Viktor Levandovskyy,     viktor.levandovskyy at math.rwth-aachen.de
+@*       Grischa Studzinski,      grischa.studzinski at math.rwth-aachen.de
+
+OVERVIEW: For the theory, see chapter 'Letterplace' in the @sc{Singular} Manual
+
+PROCEDURES:
+makeLetterplaceRing(d);    creates a ring with d blocks of shifted original
+@*                         variables
+letplaceGBasis(I); computes two-sided Groebner basis of a letterplace ideal I
+@*                 up to a degree bound
+lpNF(f,I);      normal form of f with respect to ideal I
+freeGBasis(L, n);  computes two-sided Groebner basis of an ideal, encoded via
+@*                 list L, up to degree n
+setLetterplaceAttributes(R,d,b); supplies ring R with the letterplace structure
+
+
+lpMult(f,g);    letterplace multiplication of letterplace polynomials
+shiftPoly(p,i); compute the i-th shift of letterplace polynomial p
+lpPower(f,n);   natural power of a letterplace polynomial
+lp2lstr(K, s);      convert letter-place ideal to a list of modules
+lst2str(L[, n]);   convert a list (of modules) into polynomials in free algebra
+mod2str(M[, n]); convert a module into a polynomial in free algebra
+vct2str(M[, n]);   convert a vector into a word in free algebra
+lieBracket(a,b[, N]);  compute Lie bracket ab-ba of two letterplace polynomials
+serreRelations(A,z);   compute the homogeneous part of Serre's relations
+@*                     associated to a generalized Cartan matrix A
+fullSerreRelations(A,N,C,P,d); compute the ideal of all Serre's relations
+@*                             associated to a generalized Cartan matrix A
+isVar(p);                   check whether p is a power of a single variable
+ademRelations(i,j);    compute the ideal of Adem relations for i<2j in char 0
+
+SEE ALSO: fpadim_lib, LETTERPLACE
+";
+
+// this library computes two-sided GB of an ideal
+// in a free associative algebra
+
+// a monomial is encoded via a vector V
+// where V[1] = coefficient
+// V[1+i] = the corresponding symbol
+
+LIB "qhmoduli.lib"; // for Max
+LIB "bfun.lib"; // for inForm
+
+proc tstfreegb()
+{
+    /* tests all procs for consistency */
+  /* adding the new proc, add it here */
+  example makeLetterplaceRing;
+  example letplaceGBasis;
+  example freeGBasis;
+  example setLetterplaceAttributes;
+  /* secondary */
+  example   lpMult;
+  example   shiftPoly;
+  example   lpPower;
+  example   lp2lstr;
+  example   lst2str;
+  example   mod2str;
+  example   vct2str;
+  example   lieBracket;
+  example   serreRelations;
+  example fullSerreRelations;
+  example   isVar;
+  example   ademRelations;
+}
+
+proc setLetterplaceAttributes(def R, int uptodeg, int lV)
+"USAGE: setLetterplaceAttributes(R, d, b); R a ring, b,d integers
+RETURN: ring with special attributes set
+PURPOSE: sets attributes for a letterplace ring:
+@*      'isLetterplaceRing' = true, 'uptodeg' = d, 'lV' = b, where
+@*      'uptodeg' stands for the degree bound,
+@*      'lV' for the number of variables in the block 0.
+NOTE: Activate the resulting ring by using @code{setring}
+"
+{
+  if (uptodeg*lV != nvars(R))
+  {
+    ERROR("uptodeg and lV do not agree on the basering!");
+  }
+
+    // Set letterplace-specific attributes for the output ring!
+  attrib(R, "uptodeg", uptodeg);
+  attrib(R, "lV", lV);
+  attrib(R, "isLetterplaceRing", 1);
+  return (R);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x(1),y(1),x(2),y(2),x(3),y(3),x(4),y(4)),dp;
+  def R = setLetterplaceAttributes(r, 4, 2); setring R;
+  attrib(R,"isLetterplaceRing");
+  lieBracket(x(1),y(1),2);
+}
+
+
+// obsolete?
+
+static proc lshift(module M, int s, string varing, def lpring)
+{
+  // FINALLY IMPLEMENTED AS A PART OT THE CODE
+  // shifts a polynomial from the ring R to s positions
+  // M lives in varing, the result in lpring
+  // to be run from varing
+  int i, j, k, sm, sv;
+  vector v;
+  //  execute("setring "+lpring);
+  setring lpring;
+  poly @@p;
+  ideal I;
+  execute("setring "+varing);
+  sm = ncols(M);
+  for (i=1; i<=s; i++)
+  {
+    // modules, e.g. free polynomials
+    for (j=1; j<=sm; j++)
+    {
+      //vectors, e.g. free monomials
+      v  = M[j];
+      sv = size(v);
+      sp = "@@p = @@p + ";
+      for (k=2; k<=sv; k++)
+      {
+        sp = sp + string(v[k])+"("+string(k-1+s)+")*";
+      }
+      sp = sp + string(v[1])+";"; // coef;
+      setring lpring;
+      //      execute("setring "+lpring);
+      execute(sp);
+      execute("setring "+varing);
+    }
+    setring lpring;
+    //    execute("setring "+lpring);
+    I = I,@@p;
+    @@p = 0;
+  }
+  setring lpring;
+  //execute("setring "+lpring);
+  export(I);
+  //  setring varing;
+  execute("setring "+varing);
+}
+
+static proc skip0(vector v)
+{
+  // skips zeros in a vector, producing another vector
+  if ( (v[1]==0) || (v==0) ) { return(vector(0)); }
+  int sv = nrows(v);
+  int sw = size(v);
+  if (sv == sw)
+  {
+    return(v);
+  }
+  int i;
+  int j=1;
+  vector w;
+  for (i=1; i<=sv; i++)
+  {
+    if (v[i] != 0)
+    {
+      w = w + v[i]*gen(j);
+      j++;
+    }
+  }
+  return(w);
+}
+
+proc lst2str(list L, list #)
+"USAGE:  lst2str(L[,n]);  L a list of modules, n an optional integer
+RETURN:  list (of strings)
+PURPOSE: convert a list (of modules) into polynomials in free algebra
+EXAMPLE: example lst2str; shows examples
+NOTE: if an optional integer is not 0, stars signs are used in multiplication
+"
+{
+  // returns a list of strings
+  // being sentences in words built from L
+  // if #[1] = 1, use * between generators
+  int useStar = 0;
+  if ( size(#)>0 )
+  {
+    if ( typeof(#[1]) != "int")
+    {
+      ERROR("Second argument of type int expected");
+    }
+    if (#[1])
+    {
+      useStar = 1;
+    }
+  }
+  int i;
+  int s    = size(L);
+  if (s<1) { return(list(""));}
+  list N;
+  for(i=1; i<=s; i++)
+  {
+    if ((typeof(L[i]) == "module") || (typeof(L[i]) == "matrix") )
+    {
+      N[i] = mod2str(L[i],useStar);
+    }
+    else
+    {
+      "module or matrix expected in the list";
+      return(N);
+    }
+  }
+  return(N);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y,z),(dp(1),dp(2));
+  module M = [-1,x,y],[-7,y,y],[3,x,x];
+  module N = [1,x,y,x,y],[-2,y,x,y,x],[6,x,y,y,x,y];
+  list L; L[1] = M; L[2] = N;
+  lst2str(L);
+  lst2str(L[1],1);
+}
+
+
+proc mod2str(module M, list #)
+"USAGE:  mod2str(M[,n]);  M a module, n an optional integer
+RETURN:  string
+PURPOSE: convert a module into a polynomial in free algebra
+EXAMPLE: example mod2str; shows examples
+NOTE: if an optional integer is not 0, stars signs are used in multiplication
+"
+{
+  if (size(M)==0) { return(""); }
+  // returns a string
+  // a sentence in words built from M
+  // if #[1] = 1, use * between generators
+  int useStar = 0;
+  if ( size(#)>0 )
+  {
+    if ( typeof(#[1]) != "int")
+    {
+      ERROR("Second argument of type int expected");
+    }
+    if (#[1])
+    {
+      useStar = 1;
+    }
+  }
+  int i;
+  int s    = ncols(M);
+  string t;
+  string mp;
+  for(i=1; i<=s; i++)
+  {
+    mp = vct2str(M[i],useStar);
+    if (mp[1] == "-")
+    {
+      t = t + mp;
+    }
+    else
+    {
+      if (mp != "")
+      {
+         t = t + "+" + mp;
+      }
+    }
+  }
+  if (t[1]=="+")
+  {
+    t = t[2..size(t)]; // remove first "+"
+  }
+  return(t);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y,z),(dp);
+  module M = [1,x,y,x,y],[-2,y,x,y,x],[6,x,y,y,x,y];
+  mod2str(M);
+  mod2str(M,1);
+}
+
+proc vct2str(vector v, list #)
+"USAGE:  vct2str(v[,n]);  v a vector, n an optional integer
+RETURN:  string
+PURPOSE: convert a vector into a word in free algebra
+EXAMPLE: example vct2str; shows examples
+NOTE: if an optional integer is not 0, stars signs are used in multiplication
+"
+{
+  if (v==0) { return(""); }
+  // if #[1] = 1, use * between generators
+  int useStar = 0;
+  if ( size(#)>0 )
+  {
+    if (#[1])
+    {
+      useStar = 1;
+    }
+  }
+  int ppl = printlevel-voice+2;
+  // for a word, encoded by v
+  // produces a string for it
+  v = skip0(v);
+  if (v==0) { return(string(""));}
+  number cf = leadcoef(v[1]);
+  int s = size(v);
+  string vs,vv,vp,err;
+  int i,j,p,q;
+  for (i=1; i<=s-1; i++)
+  {
+    p     = isVar(v[i+1]);
+    if (p==0)
+    {
+      err = "Error: monomial expected at nonzero position " + string(i+1);
+      ERROR(err+" in vct2str");
+      //      dbprint(ppl,err);
+      //      return("_");
+    }
+    if (p==1)
+    {
+      if (useStar && (size(vs) >0))       {   vs = vs + "*"; }
+        vs = vs + string(v[i+1]);
+    }
+    else //power
+    {
+      vv = string(v[i+1]);
+      q = find(vv,"^");
+      if (q==0)
+      {
+        q = find(vv,string(p));
+        if (q==0)
+        {
+          err = "error in find for string "+vv;
+          dbprint(ppl,err);
+          return("_");
+        }
+      }
+      // q>0
+      vp = vv[1..q-1];
+      for(j=1;j<=p;j++)
+      {
+         if (useStar && (size(vs) >0))       {   vs = vs + "*"; }
+         vs = vs + vp;
+      }
+    }
+  }
+  string scf;
+  if (cf == -1)
+  {
+    scf = "-";
+  }
+  else
+  {
+    scf = string(cf);
+    if ( (cf == 1) && (size(vs)>0) )
+    {
+      scf = "";
+    }
+  }
+  if (useStar && (size(scf) >0) && (scf!="-") )       {   scf = scf + "*"; }
+  vs = scf + vs;
+  return(vs);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = (0,a),(x,y3,z(1)),dp;
+  vector v = [-7,x,y3^4,x2,z(1)^3];
+  vct2str(v);
+  vct2str(v,1);
+  vector w = [-7a^5+6a,x,y3,y3,x,z(1),z(1)];
+  vct2str(w);
+  vct2str(w,1);
+}
+
+proc isVar(poly p)
+"USAGE:  isVar(p);  poly p
+RETURN:  int
+PURPOSE: check, whether leading monomial of p is a power of a single variable
+@* from the basering. Returns the exponent or 0 if p is multivariate.
+EXAMPLE: example isVar; shows examples
+"
+{
+  // checks whether p is a variable indeed
+  // if it's a power of a variable, returns the power
+  if (p==0) {  return(0); } //"p=0";
+  poly q   = leadmonom(p);
+  if ( (p-lead(p)) !=0 ) { return(0); } // "p-lm(p)>0";
+  intvec v = leadexp(p);
+  int s = size(v);
+  int i=1;
+  int cnt = 0;
+  int pwr = 0;
+  for (i=1; i<=s; i++)
+  {
+    if (v[i] != 0)
+    {
+      cnt++;
+      pwr = v[i];
+    }
+  }
+  //  "cnt:";  cnt;
+  if (cnt==1) { return(pwr); }
+  else { return(0); }
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y),dp;
+  poly f = xy+1;
+  isVar(f);
+  poly g = y^3;
+  isVar(g);
+  poly h = 7*x^3;
+  isVar(h);
+  poly i = 1;
+  isVar(i);
+}
+
+// new conversion routines
+
+static proc id2words(ideal I, int d)
+{
+  // NOT FINISHED
+  // input: ideal I of polys in letter-place notation
+  // in the ring with d real vars
+  // output: the list of strings: associative words
+  // extract names of vars
+  int i,m,n; string s; string place = "(1)";
+  list lv;
+  for(i=1; i<=d; i++)
+  {
+    s = string(var(i));
+    // get rid of place
+    n = find(s, place);
+    if (n>0)
+    {
+      s = s[1..n-1];
+    }
+    lv[i] = s;
+  }
+  poly p,q;
+  for (i=1; i<=ncols(I); i++)
+  {
+    if (I[i] != 0)
+    {
+      p = I[i];
+      while (p!=0)
+      {
+         q = leadmonom(p);
+      }
+    }
+  }
+
+  return(lv);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x(1),y(1),z(1),x(2),y(2),z(2)),dp;
+  ideal I = x(1)*y(2) -z(1)*x(2);
+  id2words(I,3);
+}
+
+static proc mono2word(poly p, int d)
+{
+}
+
+proc letplaceGBasis(ideal I)
+"USAGE: letplaceGBasis(I);  I an ideal
+RETURN: ideal
+ASSUME: basering is a Letterplace ring, an ideal consists of Letterplace
+@*      polynomials
+PURPOSE: compute the two-sided Groebner basis of an ideal I via Letterplace
+@*       algorithm
+NOTE: the degree bound for this computation is read off the letterplace
+@*    structure of basering
+EXAMPLE: example letplaceGBasis; shows examples
+"
+{
+  if (lpAssumeViolation())
+  {
+    ERROR("Incomplete Letterplace structure on the basering!");
+  }
+  int ppl = printlevel-voice+2;
+  def save = basering;
+  // assumes of the ring have been checked
+  // run the computation - it will test assumes on the ideal
+  int uptodeg = attrib(save,"uptodeg");
+  int lV = attrib(save,"lV");
+  dbprint(ppl,"start computing GB");
+  ideal J = system("freegb",I,uptodeg,lV);
+  dbprint(ppl,"finished computing GB");
+  dbprint(ppl-1,"the result is:");
+  dbprint(ppl-1,J);
+  return(J);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y,z),(dp(1),dp(2));
+  int degree_bound = 5;
+  def R = makeLetterplaceRing(5);
+  setring R;
+  ideal I = -x(1)*y(2)-7*y(1)*y(2)+3*x(1)*x(2), x(1)*y(2)*x(3)-y(1)*x(2)*y(3);
+  ideal J = letplaceGBasis(I);
+  J;
+  // now transfom letterplace polynomials into strings of words
+  lp2lstr(J,r); // export an object called @code{@LN} to the ring r
+  setring r;  // change to the ring r
+  lst2str(@LN,1);
+}
+
+// given the element -7xy^2x, it is represented as [-7,x,y^2,x] or as [-7,x,y,y,x]
+// use the orig ord on (x,y,z) and expand it blockwise to (x(i),y(i),z(i))
+
+// the correspondences:
+// monomial in K<x,y,z>    <<--->> vector in R
+// polynomial in K<x,y,z>  <<--->> list of vectors (matrix/module) in R
+// ideal in K<x,y,z>       <<--->> list of matrices/modules in R
+
+
+// 1. form a new ring
+// 2. NOP
+// 3. compute GB -> with the kernel stuff
+// 4. skip shifted elts (check that no such exist?)
+// 5. go back to orig vars, produce strings/modules
+// 6. return the result
+
+proc freeGBasis(list LM, int d)
+"USAGE:  freeGBasis(L, d);  L a list of modules, d an integer
+RETURN:  ring
+ASSUME: L has a special form. Namely, it is a list of modules, where
+
+ - each generator of every module stands for a monomial times coefficient in
+@* free algebra,
+
+ - in such a vector generator, the 1st entry is a nonzero coefficient from the
+@* ground field
+
+ - and each next entry hosts a variable from the basering.
+PURPOSE: compute the two-sided Groebner basis of an ideal, encoded by L
+@* in the free associative algebra, up to degree d
+NOTE: Apply @code{lst2str} to the output in order to obtain a better readable
+@*    presentation
+EXAMPLE: example freeGBasis; shows examples
+"
+{
+  // d = up to degree, will be shifted to d+1
+  if (d<1) {"bad d"; return(0);}
+
+  int ppl = printlevel-voice+2;
+  string err = "";
+
+  int i,j,s;
+  def save = basering;
+  // determine max no of places in the input
+  int slm = size(LM); // numbers of polys in the ideal
+  int sm;
+  intvec iv;
+  module M;
+  for (i=1; i<=slm; i++)
+  {
+    // modules, e.g. free polynomials
+    M  = LM[i];
+    sm = ncols(M);
+    for (j=1; j<=sm; j++)
+    {
+      //vectors, e.g. free monomials
+      iv = iv, size(M[j])-1; // 1 place is reserved by the coeff
+    }
+  }
+  int D = Max(iv); // max size of input words
+  if (d<D) {"bad d"; return(LM);}
+  D = D + d-1;
+  //  D = d;
+  list LR  = ringlist(save);
+  list L, tmp;
+  L[1] = LR[1]; // ground field
+  L[4] = LR[4]; // quotient ideal
+  tmp  = LR[2]; // varnames
+  s = size(LR[2]);
+  for (i=1; i<=D; i++)
+  {
+    for (j=1; j<=s; j++)
+    {
+      tmp[i*s+j] = string(tmp[j])+"("+string(i+1)+")";
+    }
+  }
+  for (i=1; i<=s; i++)
+  {
+    tmp[i] = string(tmp[i])+"("+string(1)+")";
+  }
+  L[2] = tmp;
+  list OrigNames = LR[2];
+  // ordering: d blocks of the ord on r
+  // try to get whether the ord on r is blockord itself
+  s = size(LR[3]);
+  if (s==2)
+  {
+    // not a blockord, 1 block + module ord
+    tmp = LR[3][s]; // module ord
+    for (i=1; i<=D; i++)
+    {
+      LR[3][s-1+i] = LR[3][1];
+    }
+    LR[3][s+D] = tmp;
+  }
+  if (s>2)
+  {
+    // there are s-1 blocks
+    int nb = s-1;
+    tmp = LR[3][s]; // module ord
+    for (i=1; i<=D; i++)
+    {
+      for (j=1; j<=nb; j++)
+      {
+        LR[3][i*nb+j] = LR[3][j];
+      }
+    }
+    //    size(LR[3]);
+    LR[3][nb*(D+1)+1] = tmp;
+  }
+  L[3] = LR[3];
+  def @R = ring(L);
+  setring @R;
+  ideal I;
+  poly @p;
+  s = size(OrigNames);
+  //  "s:";s;
+  // convert LM to canonical vectors (no powers)
+  setring save;
+  kill M; // M was defined earlier
+  module M;
+  slm = size(LM); // numbers of polys in the ideal
+  int sv,k,l;
+  vector v;
+  //  poly p;
+  string sp;
+  setring @R;
+  poly @@p=0;
+  setring save;
+  for (l=1; l<=slm; l++)
+  {
+    // modules, e.g. free polynomials
+    M  = LM[l];
+    sm = ncols(M); // in intvec iv the sizes are stored
+    // modules, e.g. free polynomials
+    for (j=1; j<=sm; j++)
+    {
+      //vectors, e.g. free monomials
+      v  = M[j];
+      sv = size(v);
+      //        "sv:";sv;
+      sp = "@@p = @@p + ";
+      for (k=2; k<=sv; k++)
+      {
+        sp = sp + string(v[k])+"("+string(k-1)+")*";
+      }
+      sp = sp + string(v[1])+";"; // coef;
+      setring @R;
+      execute(sp);
+      setring save;
+    }
+    setring @R;
+    //      "@@p:"; @@p;
+    I = I,@@p;
+    @@p = 0;
+    setring save;
+  }
+  kill sp;
+  // 3. compute GB
+  setring @R;
+  dbprint(ppl,"computing GB");
+  ideal J = system("freegb",I,d,nvars(save));
+  //  ideal J = slimgb(I);
+  dbprint(ppl,J);
+  // 4. skip shifted elts
+  ideal K = select1(J,1..s); // s = size(OrigNames)
+  dbprint(ppl,K);
+  dbprint(ppl, "done with GB");
+  // K contains vars x(1),...z(1) = images of originals
+  // 5. go back to orig vars, produce strings/modules
+  if (K[1] == 0)
+  {
+    "no reasonable output, GB gives 0";
+    return(0);
+  }
+  int sk = size(K);
+  int sp, sx, a, b;
+  intvec x;
+  poly p,q;
+  poly pn;
+  // vars in 'save'
+  setring save;
+  module N;
+  list LN;
+  vector V;
+  poly pn;
+  // test and skip exponents >=2
+  setring @R;
+  for(i=1; i<=sk; i++)
+  {
+    p  = K[i];
+    while (p!=0)
+    {
+      q  = lead(p);
+      //      "processing q:";q;
+      x  = leadexp(q);
+      sx = size(x);
+      for(k=1; k<=sx; k++)
+      {
+        if ( x[k] >= 2 )
+        {
+          err = "skip: the value x[k] is " + string(x[k]);
+          dbprint(ppl,err);
+          //            return(0);
+          K[i] = 0;
+          p    = 0;
+          q    = 0;
+          break;
+        }
+      }
+      p  = p - q;
+    }
+  }
+  K  = simplify(K,2);
+  sk = size(K);
+  for(i=1; i<=sk; i++)
+  {
+    //    setring save;
+    //    V  = 0;
+    setring @R;
+    p  = K[i];
+    while (p!=0)
+    {
+      q  = lead(p);
+      err =  "processing q:" + string(q);
+      dbprint(ppl,err);
+      x  = leadexp(q);
+      sx = size(x);
+      pn = leadcoef(q);
+      setring save;
+      pn = imap(@R,pn);
+      V  = V + leadcoef(pn)*gen(1);
+      for(k=1; k<=sx; k++)
+      {
+        if (x[k] ==1)
+        {
+          a = k div s; // block number=a+1, a!=0
+          b = k % s; // remainder
+          //          printf("a: %s, b: %s",a,b);
+          if (b == 0)
+          {
+            // that is it's the last var in the block
+            b = s;
+            a = a-1;
+          }
+          V = V + var(b)*gen(a+2);
+        }
+//         else
+//         {
+//           printf("error: the value x[k] is %s", x[k]);
+//           return(0);
+//         }
+      }
+      err = "V: " + string(V);
+      dbprint(ppl,err);
+      //      printf("V: %s", string(V));
+      N = N,V;
+      V  = 0;
+      setring @R;
+      p  = p - q;
+      pn = 0;
+    }
+    setring save;
+    LN[i] = simplify(N,2);
+    N     = 0;
+  }
+  setring save;
+  return(LN);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y,z),(dp(1),dp(2)); //  ring r = 0,(x,y,z),(a(3,0,2), dp(2));
+  module M = [-1,x,y],[-7,y,y],[3,x,x]; // stands for free poly -xy - 7yy - 3xx
+  module N = [1,x,y,x],[-1,y,x,y]; // stands for free poly xyx - yxy
+  list L; L[1] = M; L[2] = N; // list of modules stands for an ideal in free algebra
+  lst2str(L); // list to string conversion of input polynomials
+  def U = freeGBasis(L,5); // 5 is the degree bound
+  lst2str(U);
+}
+
+static proc crs(list LM, int d)
+"USAGE:  crs(L, d);  L a list of modules, d an integer
+RETURN:  ring
+PURPOSE: create a ring and shift the ideal
+EXAMPLE: example crs; shows examples
+"
+{
+  // d = up to degree, will be shifted to d+1
+  if (d<1) {"bad d"; return(0);}
+
+  int ppl = printlevel-voice+2;
+  string err = "";
+
+  int i,j,s;
+  def save = basering;
+  // determine max no of places in the input
+  int slm = size(LM); // numbers of polys in the ideal
+  int sm;
+  intvec iv;
+  module M;
+  for (i=1; i<=slm; i++)
+  {
+    // modules, e.g. free polynomials
+    M  = LM[i];
+    sm = ncols(M);
+    for (j=1; j<=sm; j++)
+    {
+      //vectors, e.g. free monomials
+      iv = iv, size(M[j])-1; // 1 place is reserved by the coeff
+    }
+  }
+  int D = Max(iv); // max size of input words
+  if (d<D) {"bad d"; return(LM);}
+  D = D + d-1;
+  //  D = d;
+  list LR  = ringlist(save);
+  list L, tmp;
+  L[1] = LR[1]; // ground field
+  L[4] = LR[4]; // quotient ideal
+  tmp  = LR[2]; // varnames
+  s = size(LR[2]);
+  for (i=1; i<=D; i++)
+  {
+    for (j=1; j<=s; j++)
+    {
+      tmp[i*s+j] = string(tmp[j])+"("+string(i)+")";
+    }
+  }
+  for (i=1; i<=s; i++)
+  {
+    tmp[i] = string(tmp[i])+"("+string(0)+")";
+  }
+  L[2] = tmp;
+  list OrigNames = LR[2];
+  // ordering: d blocks of the ord on r
+  // try to get whether the ord on r is blockord itself
+  s = size(LR[3]);
+  if (s==2)
+  {
+    // not a blockord, 1 block + module ord
+    tmp = LR[3][s]; // module ord
+    for (i=1; i<=D; i++)
+    {
+      LR[3][s-1+i] = LR[3][1];
+    }
+    LR[3][s+D] = tmp;
+  }
+  if (s>2)
+  {
+    // there are s-1 blocks
+    int nb = s-1;
+    tmp = LR[3][s]; // module ord
+    for (i=1; i<=D; i++)
+    {
+      for (j=1; j<=nb; j++)
+      {
+        LR[3][i*nb+j] = LR[3][j];
+      }
+    }
+    //    size(LR[3]);
+    LR[3][nb*(D+1)+1] = tmp;
+  }
+  L[3] = LR[3];
+  def @R = ring(L);
+  setring @R;
+  ideal I;
+  poly @p;
+  s = size(OrigNames);
+  //  "s:";s;
+  // convert LM to canonical vectors (no powers)
+  setring save;
+  kill M; // M was defined earlier
+  module M;
+  slm = size(LM); // numbers of polys in the ideal
+  int sv,k,l;
+  vector v;
+  //  poly p;
+  string sp;
+  setring @R;
+  poly @@p=0;
+  setring save;
+  for (l=1; l<=slm; l++)
+  {
+    // modules, e.g. free polynomials
+    M  = LM[l];
+    sm = ncols(M); // in intvec iv the sizes are stored
+    for (i=0; i<=d-iv[l]; i++)
+    {
+      // modules, e.g. free polynomials
+      for (j=1; j<=sm; j++)
+      {
+        //vectors, e.g. free monomials
+        v  = M[j];
+        sv = size(v);
+        //        "sv:";sv;
+        sp = "@@p = @@p + ";
+        for (k=2; k<=sv; k++)
+        {
+          sp = sp + string(v[k])+"("+string(k-2+i)+")*";
+        }
+        sp = sp + string(v[1])+";"; // coef;
+        setring @R;
+        execute(sp);
+        setring save;
+      }
+      setring @R;
+      //      "@@p:"; @@p;
+      I = I,@@p;
+      @@p = 0;
+      setring save;
+    }
+  }
+  setring @R;
+  export I;
+  return(@R);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y,z),(dp(1),dp(2));
+  module M = [-1,x,y],[-7,y,y],[3,x,x];
+  module N = [1,x,y,x],[-1,y,x,y];
+  list L; L[1] = M; L[2] = N;
+  lst2str(L);
+  def U = crs(L,5);
+  setring U; U;
+  I;
+}
+
+static proc polylen(ideal I)
+{
+  // returns the ideal of length of polys
+  int i;
+  intvec J;
+  number s = 0;
+  for(i=1;i<=ncols(I);i++)
+  {
+    J[i] = size(I[i]);
+    s = s + J[i];
+  }
+  printf("the sum of length %s",s);
+  //  print(s);
+  return(J);
+}
+
+// new: uniting both mLR1 (homog) and mLR2 (nonhomog)
+proc makeLetterplaceRing(int d, list #)
+"USAGE:  makeLetterplaceRing(d [,h]); d an integer, h an optional integer
+RETURN:  ring
+PURPOSE: creates a ring with the ordering, used in letterplace computations
+NOTE: if h is given and nonzero, the pure homogeneous letterplace block
+@*    ordering will be used.
+EXAMPLE: example makeLetterplaceRing; shows examples
+"
+{
+  int use_old_mlr = 0;
+  if ( size(#)>0 )
+  {
+    if (( typeof(#[1]) == "int" ) || ( typeof(#[1]) == "poly" ) )
+    {
+      poly x = poly(#[1]);
+      if (x!=0)
+      {
+        use_old_mlr = 1;
+      }
+    }
+  }
+  if (use_old_mlr)
+  {
+    def @A = makeLetterplaceRing1(d);
+  }
+  else
+  {
+    def @A = makeLetterplaceRing2(d);
+  }
+  return(@A);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y,z),(dp(1),dp(2));
+  def A = makeLetterplaceRing(2);
+  setring A;  A;
+  attrib(A,"isLetterplaceRing");
+  attrib(A,"uptodeg");  // degree bound
+  attrib(A,"lV"); // number of variables in the main block
+  setring r; def B = makeLetterplaceRing(2,1); // to compare:
+  setring B;  B;
+}
+
+//proc freegbRing(int d)
+static proc makeLetterplaceRing1(int d)
+"USAGE:  makeLetterplaceRing1(d); d an integer
+RETURN:  ring
+PURPOSE: creates a ring with a special ordering, suitable for
+@* the use of homogeneous letterplace (d blocks of shifted original variables)
+EXAMPLE: example makeLetterplaceRing1; shows examples
+"
+{
+  // d = up to degree, will be shifted to d+1
+  if (d<1) {"bad d"; return(0);}
+
+  int uptodeg = d; int lV = nvars(basering);
+
+  int ppl = printlevel-voice+2;
+  string err = "";
+
+  int i,j,s;
+  def save = basering;
+  int D = d-1;
+  list LR  = ringlist(save);
+  list L, tmp;
+  L[1] = LR[1]; // ground field
+  L[4] = LR[4]; // quotient ideal
+  tmp  = LR[2]; // varnames
+  s = size(LR[2]);
+  for (i=1; i<=D; i++)
+  {
+    for (j=1; j<=s; j++)
+    {
+      tmp[i*s+j] = string(tmp[j])+"("+string(i+1)+")";
+    }
+  }
+  for (i=1; i<=s; i++)
+  {
+    tmp[i] = string(tmp[i])+"("+string(1)+")";
+  }
+  L[2] = tmp;
+  list OrigNames = LR[2];
+  // ordering: d blocks of the ord on r
+  // try to get whether the ord on r is blockord itself
+  // TODO: make L(2) ordering! exponent is maximally 2
+  s = size(LR[3]);
+  if (s==2)
+  {
+    // not a blockord, 1 block + module ord
+    tmp = LR[3][s]; // module ord
+    for (i=1; i<=D; i++)
+    {
+      LR[3][s-1+i] = LR[3][1];
+    }
+    LR[3][s+D] = tmp;
+  }
+  if (s>2)
+  {
+    // there are s-1 blocks
+    int nb = s-1;
+    tmp = LR[3][s]; // module ord
+    for (i=1; i<=D; i++)
+    {
+      for (j=1; j<=nb; j++)
+      {
+        LR[3][i*nb+j] = LR[3][j];
+      }
+    }
+    //    size(LR[3]);
+    LR[3][nb*(D+1)+1] = tmp;
+  }
+  L[3] = LR[3];
+  def @R = ring(L);
+  //  setring @R;
+  //  int uptodeg = d; int lV = nvars(basering); // were defined before
+  def @@R = setLetterplaceAttributes(@R,uptodeg,lV);
+  return (@@R);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y,z),(dp(1),dp(2));
+  def A = makeLetterplaceRing1(2);
+  setring A;
+  A;
+  attrib(A,"isLetterplaceRing");
+  attrib(A,"uptodeg");  // degree bound
+  attrib(A,"lV"); // number of variables in the main block
+}
+
+static proc makeLetterplaceRing2(int d)
+"USAGE:  makeLetterplaceRing2(d); d an integer
+RETURN:  ring
+PURPOSE: creates a ring with a special ordering, suitable for
+@* the use of non-homogeneous letterplace
+NOTE: the matrix for the ordering looks as follows: first row is 1,1,...,1
+@* then there come 'd' blocks of shifted original variables
+EXAMPLE: example makeLetterplaceRing2; shows examples
+"
+{
+
+  // ToDo future: inherit positive weights in the orig ring
+  // complain on nonpositive ones
+
+  // d = up to degree, will be shifted to d+1
+  if (d<1) {"bad d"; return(0);}
+
+  int uptodeg = d; int lV = nvars(basering);
+
+  int ppl = printlevel-voice+2;
+  string err = "";
+
+  int i,j,s;
+  def save = basering;
+  int D = d-1;
+  list LR  = ringlist(save);
+  list L, tmp, tmp2, tmp3;
+  L[1] = LR[1]; // ground field
+  L[4] = LR[4]; // quotient ideal
+  tmp  = LR[2]; // varnames
+  s = size(LR[2]);
+  for (i=1; i<=D; i++)
+  {
+    for (j=1; j<=s; j++)
+    {
+      tmp[i*s+j] = string(tmp[j])+"("+string(i+1)+")";
+    }
+  }
+  for (i=1; i<=s; i++)
+  {
+    tmp[i] = string(tmp[i])+"("+string(1)+")";
+  }
+  L[2] = tmp;
+  list OrigNames = LR[2];
+  // ordering: one 1..1 a above
+  // ordering: d blocks of the ord on r
+  // try to get whether the ord on r is blockord itself
+  // TODO: make L(2) ordering! exponent is maximally 2
+  s = size(LR[3]);
+  if (s==2)
+  {
+    // not a blockord, 1 block + module ord
+    tmp = LR[3][s]; // module ord
+    for (i=1; i<=d; i++)
+    {
+      LR[3][s-1+i] = LR[3][1];
+    }
+    //    LR[3][s+D] = tmp;
+    LR[3][s+1+D] = tmp;
+    LR[3][1] = list("a",intvec(1: int(d*lV))); // deg-ord
+  }
+  if (s>2)
+  {
+    // there are s-1 blocks
+    int nb = s-1;
+    tmp = LR[3][s]; // module ord to place at the very end
+    tmp2 = LR[3]; tmp2 = tmp2[1..nb];
+    tmp3[1] = list("a",intvec(1: int(d*lV))); // deg-ord, insert as the 1st
+    for (i=1; i<=d; i++)
+    {
+      tmp3 = tmp3 + tmp2;
+    }
+    tmp3 = tmp3 + list(tmp);
+    LR[3] = tmp3;
+//     for (i=1; i<=d; i++)
+//     {
+//       for (j=1; j<=nb; j++)
+//       {
+//         //        LR[3][i*nb+j+1]= LR[3][j];
+//         LR[3][i*nb+j+1]= tmp2[j];
+//       }
+//     }
+//     //    size(LR[3]);
+//     LR[3][(s-1)*d+2] = tmp;
+//     LR[3] = list("a",intvec(1: int(d*lV))) + LR[3]; // deg-ord, insert as the 1st
+    // remove everything behind nb*(D+1)+1 ?
+    //    tmp = LR[3];
+    //    LR[3] = tmp[1..size(tmp)-1];
+  }
+  L[3] = LR[3];
+  def @R = ring(L);
+  //  setring @R;
+  //  int uptodeg = d; int lV = nvars(basering); // were defined before
+  def @@R = setLetterplaceAttributes(@R,uptodeg,lV);
+  return (@@R);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y,z),(dp(1),dp(2));
+  def A = makeLetterplaceRing2(2);
+  setring A;
+  A;
+  attrib(A,"isLetterplaceRing");
+  attrib(A,"uptodeg");  // degree bound
+  attrib(A,"lV"); // number of variables in the main block
+}
+
+// P[s;sigma] approach
+static proc makeLetterplaceRing3(int d)
+"USAGE:  makeLetterplaceRing1(d); d an integer
+RETURN:  ring
+PURPOSE: creates a ring with a special ordering, representing
+@* the original P[s,sigma] (adds d blocks of shifted s)
+ASSUME: basering is a letterplace ring
+NOTE: experimental status
+EXAMPLE: example makeLetterplaceRing1; shows examples
+"
+{
+  // d = up to degree, will be shifted to d+1
+  if (d<1) {"bad d"; return(0);}
+
+  int uptodeg = d; int lV = nvars(basering);
+
+  int ppl = printlevel-voice+2;
+  string err = "";
+
+  int i,j,s;
+  def save = basering;
+  int D = d-1;
+  list LR  = ringlist(save);
+  list L, tmp;
+  L[1] = LR[1]; // ground field
+  L[4] = LR[4]; // quotient ideal
+  tmp  = LR[2]; // varnames
+  tmp[size(tmp)+1] = "s";
+  // add s's
+  //  string newSname = "@s";
+  s = size(LR[2]);
+  for (i=1; i<=D; i++)
+  {
+    for (j=1; j<=s; j++)
+    {
+      tmp[i*s+j] = string(tmp[j])+"("+string(i+1)+")";
+    }
+  }
+  // the final index is D*s+s = (D+1)*s = degBound*s
+  for (i=1; i<=d; i++)
+  {
+    tmp[FIndex + i] =  string(newSname)+"("+string(i)+")";
+  }
+  L[2] = tmp;
+  list OrigNames = LR[2];
+  // ordering: d blocks of the MODIFIED ord on r
+  // try to get whether the ord on r is blockord itself
+  // TODO: make L(2) ordering! exponent is maximally 2
+  s = size(LR[3]);
+
+  // assume: basering was a letterplace, so get its block
+  tmp = LR[3][1]; // ASSUME: it's a nice block
+  // modify it
+  // add (0,..,0,1) ... as antiblock part
+  intvec iv; list ttmp, tmp1;
+  for (i=1; i<=d; i++)
+  {
+    // the position to hold 1:
+    iv = intvec( gen( i*(lV+1)-1 ) );
+    ttmp[1] = "a";
+    ttmp[2] = iv;
+    tmp1[i] = ttmp;
+  }
+  // finished: antiblock part //TOCONTINUE
+
+  if (s==2)
+  {
+    // not a blockord, 1 block + module ord
+    tmp = LR[3][s]; // module ord
+    for (i=1; i<=D; i++)
+    {
+      LR[3][s-1+i] = LR[3][1];
+    }
+    LR[3][s+D] = tmp;
+  }
+  if (s>2)
+  {
+    // there are s-1 blocks
+    int nb = s-1;
+    tmp = LR[3][s]; // module ord
+    for (i=1; i<=D; i++)
+    {
+      for (j=1; j<=nb; j++)
+      {
+        LR[3][i*nb+j] = LR[3][j];
+      }
+    }
+    //    size(LR[3]);
+    LR[3][nb*(D+1)+1] = tmp;
+  }
+  L[3] = LR[3];
+  def @R = ring(L);
+  //  setring @R;
+  //  int uptodeg = d; int lV = nvars(basering); // were defined before
+  def @@R = setLetterplaceAttributes(@R,uptodeg,lV);
+  return (@@R);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y,z),(dp(1),dp(2));
+  def A = makeLetterplaceRing3(2);
+  setring A;
+  A;
+  attrib(A,"isLetterplaceRing");
+  attrib(A,"uptodeg");  // degree bound
+  attrib(A,"lV"); // number of variables in the main block
+}
+
+
+
+/* EXAMPLES:
+
+//static proc ex_shift()
+{
+  LIB "freegb.lib";
+  ring r = 0,(x,y,z),(dp(1),dp(2));
+  module M = [-1,x,y],[-7,y,y],[3,x,x];
+  module N = [1,x,y,x],[-1,y,x,y];
+  list L; L[1] = M; L[2] = N;
+  lst2str(L);
+  def U = crs(L,5);
+  setring U; U;
+  I;
+  poly p = I[2]; // I[8];
+  p;
+  system("stest",p,7,7,3); // error -> the world is ok
+  poly q1 = system("stest",p,1,7,3); //ok
+  poly q6 = system("stest",p,6,7,3); //ok
+  system("btest",p,3); //ok
+  system("btest",q1,3); //ok
+  system("btest",q6,3); //ok
+}
+
+//static proc test_shrink()
+{
+  LIB "freegb.lib";
+  ring r =0,(x,y,z),dp;
+  int d = 5;
+  def R = makeLetterplaceRing(d);
+  setring R;
+  poly p1 = x(1)*y(2)*z(3);
+  poly p2 = x(1)*y(4)*z(5);
+  poly p3 = x(1)*y(1)*z(3);
+  poly p4 = x(1)*y(2)*z(2);
+  poly p5 = x(3)*z(5);
+  poly p6 = x(1)*y(1)*x(3)*z(5);
+  poly p7 = x(1)*y(2)*x(3)*y(4)*z(5);
+  poly p8 = p1+p2+p3+p4+p5 + p6 + p7;
+  p1; system("shrinktest",p1,3);
+  p2; system("shrinktest",p2,3);
+  p3; system("shrinktest",p3,3);
+  p4; system("shrinktest",p4,3);
+  p5; system("shrinktest",p5,3);
+  p6; system("shrinktest",p6,3);
+  p7; system("shrinktest",p7,3);
+  p8; system("shrinktest",p8,3);
+  poly p9 = p1 + 2*p2 + 5*p5 + 7*p7;
+  p9; system("shrinktest",p9,3);
+}
+
+//static proc ex2()
+{
+  option(prot);
+  LIB "freegb.lib";
+  ring r = 0,(x,y),dp;
+  module M = [-1,x,y],[3,x,x]; // 3x^2 - xy
+  def U = freegb(M,7);
+  lst2str(U);
+}
+
+//static proc ex_nonhomog()
+{
+  option(prot);
+  LIB "freegb.lib";
+  ring r = 0,(x,y,h),dp;
+  list L;
+  module M;
+  M = [-1,y,y],[1,x,x,x];  // x3-y2
+  L[1] = M;
+  M = [1,x,h],[-1,h,x];  // xh-hx
+  L[2] = M;
+  M = [1,y,h],[-1,h,y];  // yh-hy
+  L[3] = M;
+  def U = freegb(L,4);
+  lst2str(U);
+  // strange elements in the basis
+}
+
+//static proc ex_nonhomog_comm()
+{
+  option(prot);
+  LIB "freegb.lib";
+  ring r = 0,(x,y),dp;
+  module M = [-1,y,y],[1,x,x,x];
+  def U = freegb(M,5);
+  lst2str(U);
+}
+
+//static proc ex_nonhomog_h()
+{
+  option(prot);
+  LIB "freegb.lib";
+  ring r = 0,(x,y,h),(a(1,1),dp);
+  module M = [-1,y,y,h],[1,x,x,x]; // x3 - y2h
+  def U = freegb(M,6);
+  lst2str(U);
+}
+
+//static proc ex_nonhomog_h2()
+{
+  option(prot);
+  LIB "freegb.lib";
+  ring r = 0,(x,y,h),(dp);
+  list L;
+  module M;
+  M = [-1,y,y,h],[1,x,x,x]; // x3 - y2h
+  L[1] = M;
+  M = [1,x,h],[-1,h,x]; // xh - hx
+  L[2] = M;
+  M = [1,y,h],[-1,h,y]; // yh - hy
+  L[3] = M;
+  def U = freeGBasis(L,3);
+  lst2str(U);
+  // strange answer CHECK
+}
+
+
+//static proc ex_nonhomog_3()
+{
+  option(prot);
+  LIB "./freegb.lib";
+  ring r = 0,(x,y,z),(dp);
+  list L;
+  module M;
+  M = [1,z,y],[-1,x]; // zy - x
+  L[1] = M;
+  M = [1,z,x],[-1,y]; // zx - y
+  L[2] = M;
+  M = [1,y,x],[-1,z]; // yx - z
+  L[3] = M;
+  lst2str(L);
+  list U = freegb(L,4);
+  lst2str(U);
+  // strange answer CHECK
+}
+
+//static proc ex_densep_2()
+{
+  option(prot);
+  LIB "freegb.lib";
+  ring r = (0,a,b,c),(x,y),(Dp); // deglex
+  module M = [1,x,x], [a,x,y], [b,y,x], [c,y,y];
+  lst2str(M);
+  list U = freegb(M,5);
+  lst2str(U);
+  // a=b is important -> finite basis!!!
+  module M = [1,x,x], [a,x,y], [a,y,x], [c,y,y];
+  lst2str(M);
+  list U = freegb(M,5);
+  lst2str(U);
+}
+
+// END COMMENTED EXAMPLES
+
+*/
+
+// 1. form a new ring
+// 2. produce shifted generators
+// 3. compute GB
+// 4. skip shifted elts
+// 5. go back to orig vars, produce strings/modules
+// 6. return the result
+
+static proc freegbold(list LM, int d)
+"USAGE:  freegbold(L, d);  L a list of modules, d an integer
+RETURN:  ring
+PURPOSE: compute the two-sided Groebner basis of an ideal, encoded by L in
+the free associative algebra, up to degree d
+EXAMPLE: example freegbold; shows examples
+"
+{
+  // d = up to degree, will be shifted to d+1
+  if (d<1) {"bad d"; return(0);}
+
+  int ppl = printlevel-voice+2;
+  string err = "";
+
+  int i,j,s;
+  def save = basering;
+  // determine max no of places in the input
+  int slm = size(LM); // numbers of polys in the ideal
+  int sm;
+  intvec iv;
+  module M;
+  for (i=1; i<=slm; i++)
+  {
+    // modules, e.g. free polynomials
+    M  = LM[i];
+    sm = ncols(M);
+    for (j=1; j<=sm; j++)
+    {
+      //vectors, e.g. free monomials
+      iv = iv, size(M[j])-1; // 1 place is reserved by the coeff
+    }
+  }
+  int D = Max(iv); // max size of input words
+  if (d<D) {"bad d"; return(LM);}
+  D = D + d-1;
+  //  D = d;
+  list LR  = ringlist(save);
+  list L, tmp;
+  L[1] = LR[1]; // ground field
+  L[4] = LR[4]; // quotient ideal
+  tmp  = LR[2]; // varnames
+  s = size(LR[2]);
+  for (i=1; i<=D; i++)
+  {
+    for (j=1; j<=s; j++)
+    {
+      tmp[i*s+j] = string(tmp[j])+"("+string(i+1)+")";
+    }
+  }
+  for (i=1; i<=s; i++)
+  {
+    tmp[i] = string(tmp[i])+"("+string(1)+")";
+  }
+  L[2] = tmp;
+  list OrigNames = LR[2];
+  // ordering: d blocks of the ord on r
+  // try to get whether the ord on r is blockord itself
+  // TODO: make L(2) ordering! exponent is maximally 2
+  s = size(LR[3]);
+  if (s==2)
+  {
+    // not a blockord, 1 block + module ord
+    tmp = LR[3][s]; // module ord
+    for (i=1; i<=D; i++)
+    {
+      LR[3][s-1+i] = LR[3][1];
+    }
+    LR[3][s+D] = tmp;
+  }
+  if (s>2)
+  {
+    // there are s-1 blocks
+    int nb = s-1;
+    tmp = LR[3][s]; // module ord
+    for (i=1; i<=D; i++)
+    {
+      for (j=1; j<=nb; j++)
+      {
+        LR[3][i*nb+j] = LR[3][j];
+      }
+    }
+    //    size(LR[3]);
+    LR[3][nb*(D+1)+1] = tmp;
+  }
+  L[3] = LR[3];
+  def @R = ring(L);
+  setring @R;
+  ideal I;
+  poly @p;
+  s = size(OrigNames);
+  //  "s:";s;
+  // convert LM to canonical vectors (no powers)
+  setring save;
+  kill M; // M was defined earlier
+  module M;
+  slm = size(LM); // numbers of polys in the ideal
+  int sv,k,l;
+  vector v;
+  //  poly p;
+  string sp;
+  setring @R;
+  poly @@p=0;
+  setring save;
+  for (l=1; l<=slm; l++)
+  {
+    // modules, e.g. free polynomials
+    M  = LM[l];
+    sm = ncols(M); // in intvec iv the sizes are stored
+    for (i=0; i<=d-iv[l]; i++)
+    {
+      // modules, e.g. free polynomials
+      for (j=1; j<=sm; j++)
+      {
+        //vectors, e.g. free monomials
+        v  = M[j];
+        sv = size(v);
+        //        "sv:";sv;
+        sp = "@@p = @@p + ";
+        for (k=2; k<=sv; k++)
+        {
+          sp = sp + string(v[k])+"("+string(k-1+i)+")*";
+        }
+        sp = sp + string(v[1])+";"; // coef;
+        setring @R;
+        execute(sp);
+        setring save;
+      }
+      setring @R;
+      //      "@@p:"; @@p;
+      I = I,@@p;
+      @@p = 0;
+      setring save;
+    }
+  }
+  kill sp;
+  // 3. compute GB
+  setring @R;
+  dbprint(ppl,"computing GB");
+  //  ideal J = groebner(I);
+  ideal J = slimgb(I);
+  dbprint(ppl,J);
+  // 4. skip shifted elts
+  ideal K = select1(J,1..s); // s = size(OrigNames)
+  dbprint(ppl,K);
+  dbprint(ppl, "done with GB");
+  // K contains vars x(1),...z(1) = images of originals
+  // 5. go back to orig vars, produce strings/modules
+  if (K[1] == 0)
+  {
+    "no reasonable output, GB gives 0";
+    return(0);
+  }
+  int sk = size(K);
+  int sp, sx, a, b;
+  intvec x;
+  poly p,q;
+  poly pn;
+  // vars in 'save'
+  setring save;
+  module N;
+  list LN;
+  vector V;
+  poly pn;
+  // test and skip exponents >=2
+  setring @R;
+  for(i=1; i<=sk; i++)
+  {
+    p  = K[i];
+    while (p!=0)
+    {
+      q  = lead(p);
+      //      "processing q:";q;
+      x  = leadexp(q);
+      sx = size(x);
+      for(k=1; k<=sx; k++)
+      {
+        if ( x[k] >= 2 )
+        {
+          err = "skip: the value x[k] is " + string(x[k]);
+          dbprint(ppl,err);
+          //            return(0);
+          K[i] = 0;
+          p    = 0;
+          q    = 0;
+          break;
+        }
+      }
+      p  = p - q;
+    }
+  }
+  K  = simplify(K,2);
+  sk = size(K);
+  for(i=1; i<=sk; i++)
+  {
+    //    setring save;
+    //    V  = 0;
+    setring @R;
+    p  = K[i];
+    while (p!=0)
+    {
+      q  = lead(p);
+      err =  "processing q:" + string(q);
+      dbprint(ppl,err);
+      x  = leadexp(q);
+      sx = size(x);
+      pn = leadcoef(q);
+      setring save;
+      pn = imap(@R,pn);
+      V  = V + leadcoef(pn)*gen(1);
+      for(k=1; k<=sx; k++)
+      {
+        if (x[k] ==1)
+        {
+          a = k div s; // block number=a+1, a!=0
+          b = k % s; // remainder
+          //          printf("a: %s, b: %s",a,b);
+          if (b == 0)
+          {
+            // that is it's the last var in the block
+            b = s;
+            a = a-1;
+          }
+          V = V + var(b)*gen(a+2);
+        }
+//         else
+//         {
+//           printf("error: the value x[k] is %s", x[k]);
+//           return(0);
+//         }
+      }
+      err = "V: " + string(V);
+      dbprint(ppl,err);
+      //      printf("V: %s", string(V));
+      N = N,V;
+      V  = 0;
+      setring @R;
+      p  = p - q;
+      pn = 0;
+    }
+    setring save;
+    LN[i] = simplify(N,2);
+    N     = 0;
+  }
+  setring save;
+  return(LN);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y,z),(dp(1),dp(2));
+  module M = [-1,x,y],[-7,y,y],[3,x,x];
+  module N = [1,x,y,x],[-1,y,x,y];
+  list L; L[1] = M; L[2] = N;
+  lst2str(L);
+  def U = freegbold(L,5);
+  lst2str(U);
+}
+
+/* begin older procs and tests
+
+static proc sgb(ideal I, int d)
+{
+  // new code
+  // map x_i to x_i(1) via map()
+  //LIB "freegb.lib";
+  def save = basering;
+  //int d =7;// degree
+  int nv = nvars(save);
+  def R = makeLetterplaceRing(d);
+  setring R;
+  int i;
+  ideal Imap;
+  for (i=1; i<=nv; i++)
+  {
+    Imap[i] = var(i);
+  }
+  //ideal I = x(1)*y(2), y(1)*x(2)+z(1)*z(2);
+  ideal I = x(1)*x(2),x(1)*y(2) + z(1)*x(2);
+  option(prot);
+  //option(teach);
+  ideal J = system("freegb",I,d,nv);
+}
+
+static proc checkCeq()
+{
+  ring r = 0,(x,y),Dp;
+  def A = makeLetterplaceRing(4);
+  setring A;
+  A;
+  // I = x2-xy
+  ideal I = x(1)*x(2) - x(1)*y(2), x(2)*x(3) - x(2)*y(3), x(3)*x(4) - x(3)*y(4);
+  ideal C = x(2)-x(1),x(3)-x(2),x(4)-x(3),y(2)-y(1),y(3)-y(2),y(4)-y(3);
+  ideal K = I,C;
+  groebner(K);
+}
+
+static proc exHom1()
+{
+  // we start with
+  // z*y - x, z*x - y, y*x - z
+  LIB "freegb.lib";
+  LIB "elim.lib";
+  ring r = 0,(x,y,z,h),dp;
+  list L;
+  module M;
+  M = [1,z,y],[-1,x,h]; // zy - xh
+  L[1] = M;
+  M = [1,z,x],[-1,y,h]; // zx - yh
+  L[2] = M;
+  M = [1,y,x],[-1,z,h]; // yx - zh
+  L[3] = M;
+  lst2str(L);
+  def U = crs(L,4);
+  setring U;
+  I = I,
+    y(2)*h(3)+z(2)*x(3),     y(3)*h(4)+z(3)*x(4),
+    y(2)*x(3)-z(2)*h(3),     y(3)*x(4)-z(3)*h(4);
+  I = simplify(I,2);
+  ring r2 = 0,(x(0..4),y(0..4),z(0..4),h(0..4)),dp;
+  ideal J = imap(U,I);
+  //  ideal K = homog(J,h);
+  option(redSB);
+  option(redTail);
+  ideal L = groebner(J); //(K);
+  ideal LL = sat(L,ideal(h))[1];
+  ideal M = subst(LL,h,1);
+  M = simplify(M,2);
+  setring U;
+  ideal M = imap(r2,M);
+  lst2str(U);
+}
+
+static proc test1()
+{
+  LIB "freegb.lib";
+  ring r = 0,(x,y),Dp;
+  int d = 10; // degree
+  def R = makeLetterplaceRing(d);
+  setring R;
+  ideal I = x(1)*x(2) - y(1)*y(2);
+  option(prot);
+  option(teach);
+  ideal J = system("freegb",I,d,2);
+  J;
+}
+
+static proc test2()
+{
+  LIB "freegb.lib";
+  ring r = 0,(x,y),Dp;
+  int d = 10; // degree
+  def R = makeLetterplaceRing(d);
+  setring R;
+  ideal I = x(1)*x(2) - x(1)*y(2);
+  option(prot);
+  option(teach);
+  ideal J = system("freegb",I,d,2);
+  J;
+}
+
+static proc test3()
+{
+  LIB "freegb.lib";
+  ring r = 0,(x,y,z),dp;
+  int d =5; // degree
+  def R = makeLetterplaceRing(d);
+  setring R;
+  ideal I = x(1)*y(2), y(1)*x(2)+z(1)*z(2);
+  option(prot);
+  option(teach);
+  ideal J = system("freegb",I,d,3);
+}
+
+static proc schur2-3()
+{
+  // nonhomog:
+  //  h^4-10*h^2+9,f*e-e*f+h, h*2-e*h-2*e,h*f-f*h+2*f
+  // homogenized with t
+  //  h^4-10*h^2*t^2+9*t^4,f*e-e*f+h*t, h*2-e*h-2*e*t,h*f-f*h+2*f*t,
+  // t*h - h*t, t*f - f*t, t*e - e*t
+}
+
+end older procs and tests */
+
+proc ademRelations(int i, int j)
+"USAGE:  ademRelations(i,j); i,j int
+RETURN:  ring (and exports ideal)
+ASSUME: there are at least i+j variables in the basering
+PURPOSE: compute the ideal of Adem relations for i<2j in characteristic 0
+@*  the ideal is exported under the name AdemRel in the output ring
+EXAMPLE: example ademRelations; shows examples
+"
+{
+  // produces Adem relations for i<2j in char 0
+  // assume: 0<i<2j
+  // requires presence of vars up to i+j
+  if ( (i<0) || (i >= 2*j) )
+  {
+    ERROR("arguments out of range"); return(0);
+  }
+  ring @r = 0,(s(i+j..0)),lp;
+  poly p,q;
+  number n;
+  int ii = i div 2; int k;
+  // k=0 => s(0)=1
+  n = binomial(j-1,i);
+  q = n*s(i+j)*s(0);
+  //  printf("k=0, term=%s",q);
+  p = p + q;
+  for (k=1; k<= ii; k++)
+  {
+    n = binomial(j-k-1,i-2*k);
+    q = n*s(i+j-k)*s(k);;
+    //    printf("k=%s, term=%s",k,q);
+    p = p + q;
+  }
+  poly AdemRel = p;
+  export AdemRel;
+  return(@r);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  def A = ademRelations(2,5);
+  setring A;
+  AdemRel;
+}
+
+/*
+1,1: 0
+1,2: s(3)*s(0) == s(3) -> def for s(3):=s(1)s(2)
+2,1: adm
+2,2: s(3)*s(1) == s(1)s(2)s(1)
+1,3: 0 ( since 2*s(4)*s(0) = 0 mod 2)
+3,1: adm
+2,3: s(5)*s(0)+s(4)*s(1) == s(5)+s(4)*s(1)
+3,2: 0
+3,3: s(5)*s(1)
+1,4: 3*s(5)*s(0) == s(5)  -> def for s(5):=s(1)*s(4)
+4,1: adm
+2,4: 3*s(6)*s(0)+s(5)*s(1) == s(6) + s(5)*s(1) == s(6) + s(1)*s(4)*s(1)
+4,2: adm
+4,3: s(5)*s(2)
+3,4: s(7)*s(0)+2*s(6)*s(1) == s(7) -> def for s(7):=s(3)*s(4)
+4,4: s(7)*s(1)+s(6)*s(2)
+*/
+
+/* s1,s2:
+s1*s1 =0, s2*s2 = s1*s2*s1
+*/
+
+/*
+try char 0:
+s1,s2:
+s1*s1 =0, s2*s2 = s1*s2*s1, s(1)*s(3)== s(1)*s(1)*s(3) == 0 = 2*s(4) ->def for s(4)
+hence 2==0! only in char 2
+ */
+
+  // Adem rels modulo 2 are interesting
+
+static proc stringpoly2lplace(string s)
+{
+  // decomposes sentence into terms
+  s = replace(s,newline,""); // get rid of newlines
+  s = replace(s," ",""); // get rid of empties
+  //arith symbols: +,-
+  // decompose into words with coeffs
+  list LS;
+  int i,j,ie,je,k,cnt;
+  // s[1]="-" situation
+  if (s[1]=="-")
+  {
+    LS = stringpoly2lplace(string(s[2..size(s)]));
+    LS[1] = string("-"+string(LS[1]));
+    return(LS);
+  }
+  i = find(s,"-",2);
+  // i==1 might happen if the 1st symbol coeff is negative
+  j = find(s,"+");
+  list LL;
+  if (i==j)
+  {
+    "return a monomial";
+    // that is both are 0 -> s is a monomial
+    LS[1] = s;
+    return(LS);
+  }
+  if (i==0)
+  {
+    "i==0 situation";
+    // no minuses at all => pluses only
+    cnt++;
+    LS[cnt] = string(s[1..j-1]);
+    s = s[j+1..size(s)];
+    while (s!= "")
+    {
+      j = find(s,"+");
+      cnt++;
+      if (j==0)
+      {
+        LS[cnt] = string(s);
+        s = "";
+      }
+      else
+      {
+        LS[cnt] = string(s[1..j-1]);
+        s = s[j+1..size(s)];
+      }
+    }
+    return(LS);
+  }
+  if (j==0)
+  {
+    "j==0 situation";
+    // no pluses at all except the lead coef => the rest are minuses only
+    cnt++;
+    LS[cnt] = string(s[1..i-1]);
+    s = s[i..size(s)];
+    while (s!= "")
+    {
+      i = find(s,"-",2);
+      cnt++;
+      if (i==0)
+      {
+        LS[cnt] = string(s);
+        s = "";
+      }
+      else
+      {
+        LS[cnt] = string(s[1..i-1]);
+        s = s[i..size(s)];
+      }
+    }
+    return(LS);
+  }
+  // now i, j are nonzero
+  if (i>j)
+  {
+    "i>j situation";
+    // + comes first, at place j
+    cnt++;
+    //    "cnt:"; cnt; "j:"; j;
+    LS[cnt] = string(s[1..j-1]);
+    s = s[j+1..size(s)];
+    LL = stringpoly2lplace(s);
+    LS = LS + LL;
+    kill LL;
+    return(LS);
+  }
+  else
+  {
+    "j>i situation";
+    // - might come first, at place i
+    if (i>1)
+    {
+      cnt++;
+      LS[cnt] = string(s[1..i-1]);
+      s = s[i..size(s)];
+    }
+    else
+    {
+      // i==1->  minus at leadcoef
+      ie = find(s,"-",i+1);
+      je = find(s,"+",i+1);
+      if (je == ie)
+      {
+         "ie=je situation";
+        //monomial
+        cnt++;
+        LS[cnt] = s;
+        return(LS);
+      }
+      if (je < ie)
+      {
+         "je<ie situation";
+        // + comes first
+        cnt++;
+        LS[cnt] = s[1..je-1];
+        s = s[je+1..size(s)];
+      }
+      else
+      {
+        // ie < je
+         "ie<je situation";
+        cnt++;
+        LS[cnt] = s[1..ie-1];
+        s = s[ie..size(s)];
+      }
+    }
+    "going into recursion with "+s;
+    LL = stringpoly2lplace(s);
+    LS = LS + LL;
+    return(LS);
+  }
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  string s = "x*y+y*z+z*t"; // + only
+  stringpoly2lplace(s);
+  string s2 = "x*y - y*z-z*t*w*w"; // +1, - only
+  stringpoly2lplace(s2);
+  string s3 = "-x*y + y - 2*x +7*w*w*w";
+  stringpoly2lplace(s3);
+}
+
+static proc addplaces(list L)
+{
+  // adds places to the list of strings
+  // according to their order in the list
+  int s = size(L);
+  int i;
+  for (i=1; i<=s; i++)
+  {
+    if (typeof(L[i]) == "string")
+    {
+      L[i] = L[i] + "(" + string(i) + ")";
+    }
+    else
+    {
+      ERROR("entry of type string expected");
+      return(0);
+    }
+  }
+  return(L);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  string a = "f1";   string b = "f2";
+  list L = a,b,a;
+  addplaces(L);
+}
+
+static proc sent2lplace(string s)
+{
+  // SENTence of words TO LetterPLACE
+  list L =   stringpoly2lplace(s);
+  int i; int ss = size(L);
+  for(i=1; i<=ss; i++)
+  {
+    L[i] = str2lplace(L[i]);
+  }
+  return(L);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(f2,f1),dp;
+  string s = "f2*f1*f1 - 2*f1*f2*f1+ f1*f1*f2";
+  sent2lplace(s);
+}
+
+static proc testnumber(string s)
+{
+  string t;
+  if (s[1]=="-")
+  {
+    // two situations: either there's a negative number
+    t = s[2..size(s)];
+    if (testnumber(t))
+    {
+      //a negative number
+    }
+    else
+    {
+      // a variable times -1
+    }
+    // or just a "-" for -1
+  }
+  t = "ring @r=(";
+  t = t + charstr(basering)+"),";
+  t = t + string(var(1))+",dp;";
+  //  write(":w tstnum.tst",t);
+  t = t+ "number @@Nn = " + s + ";"+"$";
+  write(":w tstnum.tst",t);
+  string runsing = system("Singular");
+  int k;
+  t = runsing+ " -teq <tstnum.tst >tstnum.out";
+  k = system("sh",t);
+  if (k!=0)
+  {
+    ERROR("Problems running Singular");
+  }
+  int i = system("sh", "grep error tstnum.out > /dev/NULL");
+  if (i!=0)
+  {
+    // no error: s is a number
+    i = 1;
+  }
+  k = system("sh","rm tstnum.tst tstnum.out > /dev/NULL");
+  return(i);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = (0,a),x,dp;
+  string s = "a^2+7*a-2";
+  testnumber(s);
+  s = "b+a";
+  testnumber(s);
+}
+
+static proc str2lplace(string s)
+{
+  // converts a word (monomial) with coeff into letter-place
+  // string: coef*var1^exp1*var2^exp2*...varN^expN
+  s = strpower2rep(s); // expand powers
+  if (size(s)==0) { return(0); }
+  int i,j,k,insC;
+  string a,b,c,d,t;
+  // 1. get coeff
+  i = find(s,"*");
+  if (i==0) { return(s); }
+  list VN;
+  c = s[1..i-1]; // incl. the case like (-a^2+1)
+  int tn = testnumber(c);
+  if (tn == 0)
+  {
+    // failed test
+    if (c[1]=="-")
+    {
+      // two situations: either there's a negative number
+      t = c[2..size(c)];
+      if (testnumber(t))
+      {
+         //a negative number
+        // nop here
+      }
+      else
+      {
+         // a variable times -1
+          c = "-1";
+          j++; VN[j] = t; //string(c[2..size(c)]);
+          insC = 1;
+      }
+    }
+    else
+    {
+      // just a variable with coeff 1
+          j++; VN[j] = string(c);
+          c = "1";
+          insC = 1;
+    }
+  }
+ // get vars
+  t = s;
+  //  t = s[i+1..size(s)];
+  k = size(t); //j = 0;
+  while (k>0)
+  {
+    t = t[i+1..size(t)]; //next part
+    i = find(t,"*"); // next *
+    if (i==0)
+    {
+      // last monomial
+      j++;
+      VN[j] = t;
+      k = size(t);
+      break;
+    }
+    b = t[1..i-1];
+    //    print(b);
+    j++;
+    VN[j] = b;
+    k = size(t);
+  }
+  VN = addplaces(VN);
+  VN[size(VN)+1] = string(c);
+  return(VN);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = (0,a),(f2,f1),dp;
+  str2lplace("-2*f2^2*f1^2*f2");
+  str2lplace("-f1*f2");
+  str2lplace("(-a^2+7a)*f1*f2");
+}
+
+static proc strpower2rep(string s)
+{
+  // makes x*x*x*x out of x^4 ., rep statys for repetitions
+  // looks for "-" problem
+  // exception: "-" as coeff
+  string ex,t;
+  int i,j,k;
+
+  i = find(s,"^"); // first ^
+  if (i==0) { return(s); } // no ^ signs
+
+  if (s[1] == "-")
+  {
+    // either -coef or -1
+    // got the coeff:
+    i = find(s,"*");
+    if (i==0)
+    {
+      // no *'s   => coef == -1 or s == -23
+      i = size(s)+1;
+    }
+    t = string(s[2..i-1]); // without "-"
+    if ( testnumber(t) )
+    {
+      // a good number
+      t = strpower2rep(string(s[2..size(s)]));
+      t = "-"+t;
+      return(t);
+    }
+    else
+    {
+      // a variable
+      t = strpower2rep(string(s[2..size(s)]));
+      t = "-1*"+ t;
+      return(t);
+    }
+  }
+  // the case when leadcoef is a number in ()
+  if (s[1] == "(")
+  {
+    i = find(s,")",2);    // must be nonzero
+    t = s[2..i-1];
+    if ( testnumber(t) )
+    {
+      // a good number
+    }
+    else {"strpower2rep: bad number as coef";}
+    ex = string(s[i+2..size(s)]); // 2 because of *
+    ex =  strpower2rep(ex);
+    t = "("+t+")*"+ex;
+    return(t);
+  }
+
+  i = find(s,"^"); // first ^
+  j = find(s,"*",i+1); // next * == end of ^
+  if (j==0)
+  {
+    ex = s[i+1..size(s)];
+  }
+  else
+  {
+    ex = s[i+1..j-1];
+  }
+  execute("int @exp = " + ex + ";"); //@exp = exponent
+  // got varname
+  for (k=i-1; k>0; k--)
+  {
+    if (s[k] == "*") break;
+  }
+  string varn = s[k+1..i-1];
+  //  "varn:";  varn;
+  string pref;
+  if (k>0)
+  {
+    pref = s[1..k]; // with * on the k-th place
+  }
+  //  "pref:";  pref;
+  string suf;
+  if ( (j>0) && (j+1 <= size(s)) )
+  {
+    suf = s[j+1..size(s)]; // without * on the 1st place
+  }
+  //  "suf:"; suf;
+  string toins;
+  for (k=1; k<=@exp; k++)
+  {
+    toins = toins + varn+"*";
+  }
+  //  "toins: ";  toins;
+  if (size(suf) == 0)
+  {
+    toins = toins[1..size(toins)-1]; // get rid of trailing *
+  }
+  else
+  {
+    suf = strpower2rep(suf);
+  }
+  ex = pref + toins + suf;
+  return(ex);
+  //  return(strpower2rep(ex));
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = (0,a),(x,y,z,t),dp;
+  strpower2rep("-x^4");
+  strpower2rep("-2*x^4*y^3*z*t^2");
+  strpower2rep("-a^2*x^4");
+}
+
+proc lieBracket(poly a, poly b, list #)
+"USAGE:  lieBracket(a,b[,N]); a,b letterplace polynomials, N an optional integer
+RETURN:  poly
+ASSUME: basering has a letterplace ring structure
+PURPOSE:compute the Lie bracket [a,b] = ab - ba between letterplace polynomials
+NOTE: if N>1 is specified, then the left normed bracket [a,[...[a,b]]]] is
+@*    computed.
+EXAMPLE: example lieBracket; shows examples
+"
+{
+  if (lpAssumeViolation())
+  {
+    //    ERROR("Either 'uptodeg' or 'lV' global variables are not set!");
+    ERROR("Incomplete Letterplace structure on the basering!");
+  }
+  // alias ppLiebr;
+  //if int N is given compute [a,[...[a,b]]]] left normed bracket
+  poly q;
+  int N=1;
+  if (size(#)>0)
+  {
+    if (typeof(#[1])=="int")
+    {
+      N = int(#[1]);
+    }
+  }
+  if (N<=0) { return(q); }
+  while (b!=0)
+  {
+    q = q + pmLiebr(a,lead(b));
+    b = b - lead(b);
+  }
+  int i;
+  if (N >1)
+  {
+    for(i=1; i<=N; i++)
+    {
+      q = lieBracket(a,q);
+    }
+  }
+  return(q);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x(1),y(1),x(2),y(2),x(3),y(3),x(4),y(4)),dp;
+  def R = setLetterplaceAttributes(r,4,2); // supply R with letterplace structure
+  setring R;
+  poly a = x(1)*y(2); poly b = y(1);
+  lieBracket(a,b);
+  lieBracket(x(1),y(1),2);
+}
+
+static proc pmLiebr(poly a, poly b)
+{
+  //  a poly, b mono
+  poly s;
+  while (a!=0)
+  {
+    s = s + mmLiebr(lead(a),lead(b));
+    a = a - lead(a);
+  }
+  return(s);
+}
+
+proc shiftPoly(poly a, int i)
+"USAGE:  shiftPoly(p,i); p letterplace poly, i int
+RETURN: poly
+ASSUME: basering has letterplace ring structure
+PURPOSE: compute the i-th shift of letterplace polynomial p
+EXAMPLE: example shiftPoly; shows examples
+"
+{
+  // shifts a monomial a by i
+  // calls pLPshift(p,sh,uptodeg,lVblock);
+  if (lpAssumeViolation())
+  {
+    ERROR("Incomplete Letterplace structure on the basering!");
+  }
+  int uptodeg = attrib(basering,"uptodeg");
+  int lV = attrib(basering,"lV");
+  if (deg(a) + i > uptodeg)
+  {
+    ERROR("degree bound violated by the shift!");
+  }
+  return(system("stest",a,i,uptodeg,lV));
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y,z),dp;
+  int uptodeg = 5; int lV = 3;
+  def R = makeLetterplaceRing(uptodeg);
+  setring R;
+  poly f = x(1)*z(2)*y(3) - 2*z(1)*y(2) + 3*x(1);
+  shiftPoly(f,1);
+  shiftPoly(f,2);
+}
+
+
+static proc mmLiebr(poly a, poly b)
+{
+  // a,b, monomials
+  a = lead(a);
+  b = lead(b);
+  int sa = deg(a);
+  int sb = deg(b);
+  poly v = a*shiftPoly(b,sa) - b*shiftPoly(a,sb);
+  return(v);
+}
+
+static proc test_shift()
+{
+  LIB "freegb.lib";
+  ring r = 0,(a,b),dp;
+  int d =5;
+  def R = makeLetterplaceRing(d);
+  setring R;
+  int uptodeg = d;
+  int lV = 2;
+  def R = setLetterplaceAttributes(r,uptodeg,2); // supply R with letterplace structure
+  setring R;
+  poly p = mmLiebr(a(1),b(1));
+  poly p = lieBracket(a(1),b(1));
+}
+
+proc serreRelations(intmat A, int zu)
+"USAGE:  serreRelations(A,z); A an intmat, z an int
+RETURN:  ideal
+ASSUME: basering has a letterplace ring structure and
+@*          A is a generalized Cartan matrix with integer entries
+PURPOSE: compute the ideal of Serre's relations associated to A
+EXAMPLE: example serreRelations; shows examples
+"
+{
+  // zu = 1 -> with commutators [f_i,f_j]; zu == 0 without them
+  // suppose that A is cartan matrix
+  // then Serre's relations are
+  // (ad f_j)^{1-A_{ij}} ( f_i)
+  int ppl = printlevel-voice+2;
+  int n = ncols(A); // hence n variables
+  int i,j,k,el;
+  poly p,q;
+  ideal I;
+  for (i=1; i<=n; i++)
+  {
+    for (j=1; j<=n; j++)
+    {
+      el = 1 - A[i,j];
+      //     printf("i:%s, j: %s, l: %s",i,j,l);
+      dbprint(ppl,"i, j, l: ",i,j,el);
+      //      if ((i!=j) && (l >0))
+      //      if ( (i!=j) &&  ( ((zu ==0) &&  (l >=2)) || ((zu ==1) &&  (l >=1)) ) )
+      if ((i!=j) && (el >0))
+      {
+        q = lieBracket(var(j),var(i));
+        dbprint(ppl,"first bracket: ",q);
+        //        if (l >=2)
+        //        {
+          for (k=1; k<=el-1; k++)
+          {
+            q = lieBracket(var(j),q);
+            dbprint(ppl,"further bracket:",q);
+          }
+          //        }
+      }
+      if (q!=0) { I = I,q; q=0;}
+    }
+  }
+  I = simplify(I,2);
+  return(I);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  intmat A[3][3] =
+    2, -1, 0,
+    -1, 2, -3,
+    0, -1, 2; // G^1_2 Cartan matrix
+  ring r = 0,(f1,f2,f3),dp;
+  int uptodeg = 5;
+  def R = makeLetterplaceRing(uptodeg);
+  setring R;
+  ideal I = serreRelations(A,1); I = simplify(I,1+2+8);
+  I;
+}
+
+/* setup for older example:
+  intmat A[2][2] = 2, -1, -1, 2; // sl_3 == A_2
+  ring r = 0,(f1,f2),dp;
+  int uptodeg = 5; int lV = 2;
+*/
+
+proc fullSerreRelations(intmat A, ideal rNegative, ideal rCartan, ideal rPositive, int uptodeg)
+"USAGE:  fullSerreRelations(A,N,C,P,d); A an intmat, N,C,P ideals, d an int
+RETURN:  ring (and ideal)
+PURPOSE: compute the inhomogeneous Serre's relations associated to A in given
+@*       variable names
+ASSUME: three ideals in the input are of the same sizes and contain merely
+@* variables which are interpreted as follows: N resp. P stand for negative
+@* resp. positive roots, C stand for Cartan elements. d is the degree bound for
+@* letterplace ring, which will be returned.
+@* The matrix A is a generalized Cartan matrix with integer entries
+@* The result is the ideal called 'fsRel' in the returned ring.
+EXAMPLE: example fullSerreRelations; shows examples
+"
+{
+  /* SerreRels on rNeg and rPos plus Cartans etc. */
+  int ppl = printlevel -voice+2;
+  /* ideals must be written in variables: assume each term is of degree 1 */
+  int i,j,k;
+  int N = nvars(basering);
+  def save = basering;
+  int comFlag = 0;
+  /* assume:  (size(rNegative) == size(rPositive)) */
+  /* assume:  (size(rNegative) == size(rCartan)) i.e. nonsimple Cartans */
+  if ( (size(rNegative) != size(rPositive)) || (size(rNegative) != size(rCartan)) )
+  {
+    ERROR("All input ideals must be of the same size");
+  }
+
+//   if (size(rNegative) != size(rPositive))
+//   {
+//     ERROR("The 1st and the 3rd input ideals must be of the same size");
+//   }
+
+  /* assume:  2*size(rNegative) + size(rCartan) >= nvars(basering) */
+  i = 2*size(rNegative) + size(rCartan);
+  if (i>N)
+  {
+    ERROR("The total number of elements in input ideals must not exceed the dimension of the ground ring");
+  }
+  if (i < N)
+  {
+    comFlag = N-i; // so many elements will commute
+    "Warning: some elements will be treated as mutually commuting";
+  }
+  /* extract varnames from input ideals */
+  intvec iNeg = varIdeal2intvec(rNegative);
+  intvec iCartan = varIdeal2intvec(rCartan);
+  intvec iPos = varIdeal2intvec(rPositive);
+  /* for each vector in rNeg and rPositive, go into the corr. ring and create SerreRels */
+  /* rNegative: */
+  list L = ringlist(save);
+  def LPsave = makeLetterplaceRing2(uptodeg); setring save;
+  list LNEG = L; list tmp;
+  /* L[1] field as is; L[2] vars: a subset; L[3] ordering: dp, L[4] as is */
+  for (i=1; i<=size(iNeg); i++)
+  {
+    tmp[i] = string(var(iNeg[i]));
+  }
+  LNEG[2] = tmp; LNEG[3] = list(list("dp",intvec(1:size(iNeg))), list("C",0));
+  def RNEG = ring(LNEG); setring RNEG;
+  def RRNEG = makeLetterplaceRing2(uptodeg);
+  setring RRNEG;
+  ideal I = serreRelations(A,1); I = simplify(I,1+2+8);
+  setring LPsave;
+  ideal srNeg = imap(RRNEG,I);
+  dbprint(ppl,"0-1 ideal of negative relations is ready");
+  dbprint(ppl-1,srNeg);
+  setring save; kill L,tmp,RRNEG,RNEG, LNEG;
+  /* rPositive: */
+  list L = ringlist(save);
+  list LPOS = L; list tmp;
+  /* L[1] field as is; L[2] vars: a subset; L[3] ordering: dp, L[4] as is */
+  for (i=1; i<=size(iPos); i++)
+  {
+    tmp[i] = string(var(iPos[i]));
+  }
+  LPOS[2] = tmp; LPOS[3] = list(list("dp",intvec(1:size(iPos))), list("C",0));
+  def RPOS = ring(LPOS); setring RPOS;
+  def RRPOS = makeLetterplaceRing2(uptodeg);
+  setring RRPOS;
+  ideal I = serreRelations(A,1); I = simplify(I,1+2+8);
+  setring LPsave;
+  ideal srPos = imap(RRPOS,I);
+  dbprint(ppl,"0-2 ideal of positive relations is ready");
+  dbprint(ppl-1,srPos);
+  setring save; kill L,tmp,RRPOS,RPOS, LPOS;
+  string sMap = "ideal Mmap =";
+  for (i=1; i<=nvars(save); i++)
+  {
+    sMap = sMap + string(var(i)) +"(1),";
+  }
+  sMap[size(sMap)] = ";";
+  /* cartans: h_j h_i = h_i h_j */
+  setring LPsave;
+  ideal ComCartan;
+  for (i=1; i<size(iCartan); i++)
+  {
+    for (j=i+1; j<=size(iCartan); j++)
+    {
+      ComCartan =  ComCartan + lieBracket(var(iCartan[j]),var(iCartan[i]));
+    }
+  }
+  ComCartan = simplify(ComCartan,1+2+8);
+  execute(sMap); // defines an ideal Mmap
+  map F = save, Mmap;
+  dbprint(ppl,"1. commuting Cartans: ");
+  dbprint(ppl-1,ComCartan);
+  /* [e_i, f_j] =0 if i<>j */
+  ideal ComPosNeg; // assume: #Neg=#Pos
+  for (i=1; i<size(iPos); i++)
+  {
+    for (j=1; j<=size(iPos); j++)
+    {
+      if (j !=i)
+      {
+        ComPosNeg =  ComPosNeg + lieBracket(var(iPos[i]),var(iNeg[j]));
+        ComPosNeg =  ComPosNeg + lieBracket(var(iPos[j]),var(iNeg[i]));
+      }
+    }
+  }
+  ComPosNeg = simplify(ComPosNeg,1+2+8);
+  dbprint(ppl,"2. commuting Positive and Negative:");
+  dbprint(ppl-1,ComPosNeg);
+  /* [e_i, f_i] = h_i */
+  poly tempo;
+  for (i=1; i<=size(iCartan); i++)
+  {
+    tempo = lieBracket(var(iPos[i]),var(iNeg[i])) - var(iCartan[i]);
+    ComPosNeg =  ComPosNeg + tempo;
+  }
+  //  ComPosNeg = simplify(ComPosNeg,1+2+8);
+  dbprint(ppl,"3. added sl2 triples [e_i,f_i]=h_i");
+  dbprint(ppl-1,ComPosNeg);
+
+  /* [h_i, e_j] = A_ij e_j */
+  /* [h_i, f_j] = -A_ij f_j */
+  ideal ActCartan; // assume: #Neg=#Pos
+  for (i=1; i<=size(iCartan); i++)
+  {
+    for (j=1; j<=size(iCartan); j++)
+    {
+      tempo = lieBracket(var(iCartan[i]),var(iPos[j])) - A[i,j]*var(iPos[j]);
+      ActCartan = ActCartan + tempo;
+      tempo = lieBracket(var(iCartan[i]),var(iNeg[j])) + A[i,j]*var(iNeg[j]);
+      ActCartan = ActCartan + tempo;
+    }
+  }
+  ActCartan = simplify(ActCartan,1+2+8);
+  dbprint(ppl,"4. actions of Cartan:");
+  dbprint(ppl-1, ActCartan);
+
+  /* final part: prepare the output */
+  setring LPsave;
+  ideal fsRel = srNeg, srPos, ComPosNeg, ComCartan, ActCartan;
+  export fsRel;
+  setring save;
+  return(LPsave);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  intmat A[2][2] =
+    2, -1,
+    -1, 2; // A_2 = sl_3 Cartan matrix
+  ring r = 0,(f1,f2,h1,h2,e1,e2),dp;
+  ideal negroots = f1,f2; ideal cartans = h1,h2; ideal posroots = e1,e2;
+  int uptodeg = 5;
+  def RS = fullSerreRelations(A,negroots,cartans,posroots,uptodeg);
+  setring RS; fsRel;
+}
+
+static proc varIdeal2intvec(ideal I)
+{
+  // used in SerreRelations
+  /* assume1:  input ideal is a list of variables of the ground ring */
+  int i,j; intvec V;
+  for (i=1; i<= size(I); i++)
+  {
+    j = univariate(I[i]);
+    if (j<=0)
+    {
+      ERROR("input ideal must contain only variables");
+    }
+    V[i] = j;
+  }
+  dbprint(printlevel-voice+2,V);
+  /* now we make a smaller list of non-repeating entries */
+  ideal iW = simplify(ideal(V),2+4); // no zeros, no repetitions
+  if (size(iW) < size(V))
+  {
+    /* extract intvec from iW */
+    intvec inW;
+    for(j=1; j<=size(iW); j++)
+    {
+      inW[j] = int(leadcoef(iW[j]));
+    }
+    return(inW);
+  }
+  return(V);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y,z),dp;
+  ideal I = x,z;
+  varIdeal2intvec(I);
+  varIdeal2intvec(ideal(x2,y^3,x+1));
+  varIdeal2intvec(ideal(x*y,y,x+1));
+}
+
+proc lp2lstr(ideal K, def save)
+"USAGE:  lp2lstr(K,s); K an ideal, s a ring name
+RETURN:  nothing (exports object @LN into the ring named s)
+ASSUME: basering has a letterplace ring structure
+PURPOSE: converts letterplace ideal to list of modules
+NOTE: useful as preprocessing to 'lst2str'
+EXAMPLE: example lp2lstr; shows examples
+"
+{
+  def @R = basering;
+  string err;
+  int s = nvars(save);
+  int i,j,k;
+    // K contains vars x(1),...z(1) = images of originals
+  // 5. go back to orig vars, produce strings/modules
+  int sk = size(K);
+  int sp, sx, a, b;
+  intvec x;
+  poly p,q;
+  poly pn;
+  // vars in 'save'
+  setring save;
+  module N;
+  list LN;
+  vector V;
+  poly pn;
+  // test and skip exponents >=2
+  setring @R;
+  for(i=1; i<=sk; i++)
+  {
+    p  = K[i];
+    while (p!=0)
+    {
+      q  = lead(p);
+      //      "processing q:";q;
+      x  = leadexp(q);
+      sx = size(x);
+      for(k=1; k<=sx; k++)
+      {
+        if ( x[k] >= 2 )
+        {
+          err = "skip: the value x[k] is " + string(x[k]);
+          dbprint(ppl,err);
+          //            return(0);
+          K[i] = 0;
+          p    = 0;
+          q    = 0;
+          break;
+        }
+      }
+      p  = p - q;
+    }
+  }
+  K  = simplify(K,2);
+  sk = size(K);
+  for(i=1; i<=sk; i++)
+  {
+    //    setring save;
+    //    V  = 0;
+    setring @R;
+    p  = K[i];
+    while (p!=0)
+    {
+      q  = lead(p);
+      err =  "processing q:" + string(q);
+      dbprint(ppl,err);
+      x  = leadexp(q);
+      sx = size(x);
+      pn = leadcoef(q);
+      setring save;
+      pn = imap(@R,pn);
+      V  = V + leadcoef(pn)*gen(1);
+      for(k=1; k<=sx; k++)
+      {
+        if (x[k] ==1)
+        {
+          a = k div s; // block number=a+1, a!=0
+          b = k % s; // remainder
+          //          printf("a: %s, b: %s",a,b);
+          if (b == 0)
+          {
+            // that is it's the last var in the block
+            b = s;
+            a = a-1;
+          }
+          V = V + var(b)*gen(a+2);
+        }
+      }
+      err = "V: " + string(V);
+      dbprint(ppl,err);
+      //      printf("V: %s", string(V));
+      N = N,V;
+      V  = 0;
+      setring @R;
+      p  = p - q;
+      pn = 0;
+    }
+    setring save;
+    LN[i] = simplify(N,2);
+    N     = 0;
+  }
+  setring save;
+  list @LN = LN;
+  export @LN;
+  //  return(LN);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  intmat A[2][2] = 2, -1, -1, 2; // sl_3 == A_2
+  ring r = 0,(f1,f2),dp;
+  def R = makeLetterplaceRing(3);
+  setring R;
+  ideal I = serreRelations(A,1);
+  lp2lstr(I,r);
+  setring r;
+  lst2str(@LN,1);
+}
+
+static proc strList2poly(list L)
+{
+  //  list L comes from sent2lplace (which takes a polynomial as input)
+  // each entry of L is a sublist with the coef on the last place
+  int s = size(L); int t;
+  int i,j;
+  list M;
+  poly p,q;
+  string Q;
+  for(i=1; i<=s; i++)
+  {
+    M = L[i];
+    t = size(M);
+    //    q = M[t]; // a constant
+    Q = string(M[t]);
+    for(j=1; j<t; j++)
+    {
+      //      q = q*M[j];
+      Q = Q+"*"+string(M[j]);
+    }
+    execute("q="+Q+";");
+    //    q;
+    p = p + q;
+  }
+  kill Q;
+  return(p);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r =0,(x,y,z,t),Dp;
+  def A = makeLetterplaceRing(4);
+  setring A;
+  string t = "-2*y*z*y*z + y*t*z*z - z*x*x*y  + 2*z*y*z*y";
+  list L = sent2lplace(t);
+  L;
+  poly p = strList2poly(L);
+  p;
+}
+
+static proc file2lplace(string fname)
+"USAGE:  file2lplace(fnm);  fnm a string
+RETURN:  ideal
+PURPOSE: convert the contents of the file fnm into ideal of polynomials in free algebra
+EXAMPLE: example file2lplace; shows examples
+"
+{
+  // format: from the usual string to letterplace
+  string s = read(fname);
+  // assume: file is a comma-sep list of polys
+  // the vars are declared before
+  // the file ends with ";"
+  string t; int i;
+  ideal I;
+  list tst;
+  while (s!="")
+  {
+    i = find(s,",");
+    "i"; i;
+    if (i==0)
+    {
+      i = find(s,";");
+      if (i==0)
+      {
+        // no ; ??
+         "no colon or semicolon found anymore";
+         return(I);
+      }
+      // no "," but ";" on the i-th place
+      t = s[1..i-1];
+      s = "";
+      "processing: "; t;
+      tst = sent2lplace(t);
+      tst;
+      I = I, strList2poly(tst);
+      return(I);
+    }
+    // here i !=0
+    t = s[1..i-1];
+    s = s[i+1..size(s)];
+    "processing: "; t;
+    tst = sent2lplace(t);
+    tst;
+    I = I, strList2poly(tst);
+  }
+  return(I);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r =0,(x,y,z,t),dp;
+  def A = makeLetterplaceRing(4);
+  setring A;
+  string fn = "myfile";
+  string s1 = "z*y*y*y - 3*y*z*x*y  + 3*y*y*z*y - y*x*y*z,";
+  string s2 = "-2*y*x*y*z + y*y*z*z - z*z*y*y + 2*z*y*z*y,";
+  string s3 = "z*y*x*t - 2*y*z*y*t + y*y*z*t - t*z*y*y + 2*t*y*z*y - t*x*y*z;";
+  write(":w "+fn,s1);  write(":a "+fn,s2);   write(":a "+fn,s3);
+  read(fn);
+  ideal I = file2lplace(fn);
+  I;
+}
+
+/* EXAMPLES AGAIN:
+//static proc get_ls3nilp()
+{
+//first app of file2lplace
+  ring r =0,(x,y,z,t),dp;
+  int d = 10;
+  def A = makeLetterplaceRing(d);
+  setring A;
+  ideal I = file2lplace("./ls3nilp.bg");
+  // and now test the correctness: go back from lplace to strings
+  lp2lstr(I,r);
+  setring r;
+  lst2str(@LN,1); // agree!
+}
+
+//static proc doc_example()
+{
+  LIB "freegb.lib";
+  ring r = 0,(x,y,z),dp;
+  int d =4; // degree bound
+  def R = makeLetterplaceRing(d);
+  setring R;
+  ideal I = x(1)*y(2) + y(1)*z(2), x(1)*x(2) + x(1)*y(2) - y(1)*x(2) - y(1)*y(2);
+  option(redSB);option(redTail);
+  ideal J = system("freegb",I,d,nvars(r));
+  J;
+  // visualization:
+  lp2lstr(J,r); // export an object called @LN to the ring r
+  setring r;  // change to the ring r
+  lst2str(@LN,1); // output the strings
+}
+
+*/
+
+//static
+proc lpMultX(poly f, poly g)
+{
+  /* multiplies two polys in a very general setting correctly */
+  /* alternative to lpMult, possibly better at non-positive orderings */
+
+  if (lpAssumeViolation())
+  {
+    ERROR("Incomplete Letterplace structure on the basering!");
+  }
+  // decompose f,g into graded pieces with inForm: need dmodapp.lib
+  int b = attrib(basering,"lV");  // the length of the block
+  intvec w; // inherit the graded on the oridinal ring
+  int i;
+  for(i=1; i<=b; i++)
+  {
+    w[i] = deg(var(i));
+  }
+  intvec v = w;
+  for(i=1; i< attrib(basering,"uptodeg"); i++)
+  {
+    v = v,w;
+  }
+  w = v;
+  poly p,q,s, result;
+  s = g;
+  while (f!=0)
+  {
+    p = inForm(f,w)[1];
+    f = f - p;
+    s = g;
+    while (s!=0)
+    {
+      q = inForm(s,w)[1];
+      s = s - q;
+      result = result + lpMult(p,q);
+    }
+  }
+  // shrinking
+  //  result;
+  return( system("shrinktest",result,attrib(basering, "lV")) );
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  // define a ring in letterplace form as follows:
+  ring r = 0,(x(1),y(1),x(2),y(2),x(3),y(3),x(4),y(4)),dp;
+  def R = setLetterplaceAttributes(r,4,2); // supply R with letterplace structure
+  setring R;
+  poly a = x(1)*y(2)+x(1)+y(1); poly b = y(1)+3;
+  lpMultX(b,a);
+  lpMultX(a,b);
+}
+
+// TODO:
+// multiply two letterplace polynomials, lpMult: done
+// reduction/ Normalform? needs kernel stuff
+
+
+proc lpMult(poly f, poly g)
+"USAGE:  lpMult(f,g); f,g letterplace polynomials
+RETURN:  poly
+ASSUME: basering has a letterplace ring structure
+PURPOSE: compute the letterplace form of f*g
+EXAMPLE: example lpMult; shows examples
+"
+{
+
+  // changelog:
+  // VL oct 2010: deg -> deg(_,w) for the length
+  // shrink the result => don't need to decompose polys
+  // since the shift is big enough
+
+  // indeed it's better to have that
+  // ASSUME: both f and g are quasi-homogeneous
+
+  if (lpAssumeViolation())
+  {
+    ERROR("Incomplete Letterplace structure on the basering!");
+  }
+  intvec w = 1:nvars(basering);
+  int sf = deg(f,w); // VL Oct 2010: we need rather length than degree
+  int sg = deg(g,w); // esp. in the case of weighted ordering
+  int uptodeg = attrib(basering, "uptodeg");
+  if (sf+sg > uptodeg)
+  {
+    ERROR("degree bound violated by the product!");
+  }
+  //  if (sf>1) { sf = sf -1; }
+  poly v = f*shiftPoly(g,sf);
+  // bug, reported by Simon King: in nonhomog case [solved]
+  // we need to shrink
+  return( system("shrinktest",v,attrib(basering, "lV")) );
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  // define a ring in letterplace form as follows:
+  ring r = 0,(x(1),y(1),x(2),y(2),x(3),y(3),x(4),y(4)),dp;
+  def R = setLetterplaceAttributes(r,4,2); // supply R with letterplace structure
+  setring R;
+  poly a = x(1)*y(2)+x(1)+y(1); poly b = y(1)+3;
+  lpMult(b,a);
+  lpMult(a,b);
+}
+
+proc lpPower(poly f, int n)
+"USAGE:  lpPower(f,n); f letterplace polynomial, int n
+RETURN:  poly
+ASSUME: basering has a letterplace ring structure
+PURPOSE: compute the letterplace form of f^n
+EXAMPLE: example lpPower; shows examples
+"
+{
+  if (n<0) { ERROR("the power must be a natural number!"); }
+  if (n==0) { return(poly(1)); }
+  if (n==1) { return(f); }
+  int i;
+  poly p = 1;
+  for(i=1; i<= n; i++)
+  {
+    p = lpMult(p,f);
+  }
+  return(p);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  // define a ring in letterplace form as follows:
+  ring r = 0,(x(1),y(1),x(2),y(2),x(3),y(3),x(4),y(4)),dp;
+  def R = setLetterplaceAttributes(r,4,2); // supply R with letterplace structure
+  setring R;
+  poly a = x(1)*y(2) + y(1); poly b = y(1) - 1;
+  lpPower(a,2);
+  lpPower(b,4);
+}
+
+// new: lp normal from by using shift-invariant data by Grischa Studzinski
+
+/////////////////////////////////////////////////////////
+//   ASSUMPTIONS: every polynomial is an element of V',
+//@* else there wouldn't be an dvec representation
+
+//Mainprocedure for the user
+
+proc lpNF(poly p, ideal G)
+"USAGE: lpNF(p,G); f letterplace polynomial, ideal I
+RETURN: poly
+PURPOSE: computation of the normalform of p with respect to G
+ASSUME: p is a Letterplace polynomial, G is a set Letterplace polynomials,
+being a Letterplace Groebner basis (no check for this will be done)
+NOTE: Strategy: take the smallest monomial wrt ordering for reduction
+@*     For homogenous ideals the shift does not matter
+@*     For non-homogenous ideals the first shift will be the smallest monomial
+EXAMPLE: example lpNF; shows examples
+"
+{if ((p==0) || (size(G) == 0)){return(p);}
+ checkAssumptions(p,G);
+ G = sort(G)[1];
+ list L = makeDVecI(G);
+ return(normalize(lpNormalForm1(p,G,L)));
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+ring r = 0,(x,y,z),dp;
+int d =5; // degree
+def R = makeLetterplaceRing(d);
+setring R;
+ideal I = y(1)*x(2)*y(3) - z(1)*y(2)*z(3), x(1)*y(2)*x(3) - z(1)*x(2)*y(3), z(1)*x(2)*z(3) - y(1)*z(2)*x(3), x(1)*x(2)*x(3) + y(1)*y(2)*y(3) + z(1)*z(2)*z(3) + x(1)*y(2)*z(3);
+ideal J = letplaceGBasis(I); // compute a Letterplace Groebner basis
+poly p = y(1)*x(2)*y(3)*z(4)*y(5) - y(1)*z(2)*z(3)*y(4) + z(1)*y(2)*z(3);
+poly q = z(1)*x(2)*z(3)*y(4)*z(5) - y(1)*z(2)*x(3)*y(4)*z(5);
+lpNF(p,J);
+lpNF(q,J);
+}
+
+//procedures to convert monomials into the DVec representation, all static
+////////////////////////////////////////////////////////
+
+
+static proc getExpVecs(ideal G)
+"USUAGE: getExpVecs(G);
+RETURN: list of intvecs
+PURPOSE: convert G into a list of intvecs, corresponding to the exponent vector
+@* of the leading monomials of G
+"
+{int i; list L;
+ for (i = 1; i <= size(G); i++) {L[i] = leadexp(G[i]); }
+ return(L);
+}
+
+
+static proc delSupZero(intvec I)
+"USUAGE:delSupZero(I);
+RETURN: intvec
+PURPOSE: Deletes superfluous zero blocks of an exponent vector
+ASSUME: Intvec is an exponent vector of a letterplace monomial contained in V'
+"
+{if (I==intvec(0)) {return(intvec(0));}
+ int j,k,l;
+ int n = attrib(basering,"lV"); int d = attrib(basering,"uptodeg");
+ intvec w; j = 1;
+ while (j <= d)
+ {w = I[1..n];
+  if (w<>intvec(0)){break;}
+   else {I = I[(n+1)..(n*d)]; d = d-1; j++;}
+ }
+ for (j = 1; j <= d; j++)
+  {l=(j-1)*n+1; k= j*n;
+   w = I[l..k];
+   if (w==intvec(0)){w = I[1..(l-1)]; return(w);}//if a zero block is found there are only zero blocks left,
+                                                 //otherwise there would be a hole in the monomial
+                                                 // shrink should take care that this will not happen
+  }
+ return(I);
+}
+
+
+static proc delSupZeroList(list L)
+"USUAGE:delSupZeroList(L); L a list, containing intvecs
+RETURN: list, containing intvecs
+PURPOSE: Deletes all superfluous zero blocks for a list of exponent vectors
+ASSUME: All intvecs are exponent vectors of letterplace monomials contained in V'
+"
+{int i;
+ for (i = size(L); 0 < i; i--){L[i] = delSupZero(L[i]);}
+ return(L);
+}
+
+
+static proc makeDVec(intvec V)
+"USUAGE:makeDVec(V);
+RETURN: intvec
+PURPOSE: Converts an modified exponent vector into an Dvec
+NOTE: Superfluos zero blocks must have been deleted befor using this procedure
+"
+{int i,j,k,r1,r2; intvec D;
+ int n = attrib(basering,"lV");
+ k = size(V) div n; r1 = 0; r2 = 0;
+ for (i=1; i<= k; i++)
+  {for (j=(1+((i-1)*n)); j <= (i*n); j++)
+   {if (V[j]>0){r2 = j - ((i-1)*n); j = (j mod n); break;}
+   }
+   D[size(D)+1] = r1+r2;
+   if (j == 0) {r1 = 0;} else{r1= n-j;}
+  }
+ D = D[2..size(D)];
+ return(D);
+}
+
+static proc makeDVecL(list L)
+"USUAGE:makeDVecL(L); L, a list containing intvecs
+RETURN: list, containing intvecs
+ASSUME:
+"
+{int i; list R;
+ for (i=1; i <= size(L); i++) {R[i] = makeDVec(L[i]);}
+ return(R);
+}
+
+static proc makeDVecI(ideal G)
+"USUAGE:makeDVecI(G);
+RETURN:list, containing intvecs
+PURPOSE:computing the DVec representation for lead(G)
+ASSUME:
+"
+{list L = delSupZeroList(getExpVecs(G));
+ return(makeDVecL(L));
+}
+
+
+//procedures, which are dealing with the DVec representation, all static
+
+static proc dShiftDiv(intvec V, intvec W)
+"USUAGE: dShiftDiv(V,W);
+RETURN: a list,containing integers, or -1, if no shift of W divides V
+PURPOSE: find all possible shifts s, such that s.W|V
+ASSUME: V,W are DVecs of monomials contained in V'
+"
+{if(size(V)<size(W)){return(list(-1));}
+
+ int i,j,r; intvec T; list R;
+ int n = attrib(basering,"lV");
+ int k = size(V) - size(W) + 1;
+ if (intvec(V[1..size(W)])-W == 0){R[1]=0;}
+ for (i =2; i <=k; i++)
+ {r = 0; kill T; intvec T;
+  for (j =1; j <= i; j++) {r = r + V[j];}
+  //if (i==1) {T[1] = r-(i-1)*n;} else
+  T[1] = r-(i-1)*n; if (size(W)>1) {T[2..size(W)] = V[(i+1)..(size(W)+i-1)];}
+  if (T-W == 0) {R[size(R)+1] = i-1;}
+ }
+ if (size(R)>0) {return(R);}
+ else {return(list(-1));}
+}
+
+
+
+//the actual normalform procedure, if a user want not to presort the ideal, just make it not static
+
+
+static proc lpNormalForm1(poly p, ideal G, list L)
+"USUAGE:lpNormalForm1(p,G);
+RETURN:poly
+PURPOSE:computation of the normalform of p w.r.t. G
+ASSUME: p is a Letterplace polynomial, G is a set of Letterplace polynomials
+NOTE: Taking the first possible reduction
+"
+{
+ if (deg(p) <1) {return(p);}
+ else
+  {
+  int i; int s;
+  intvec V = makeDVec(delSupZero(leadexp(p)));
+  for (i = 1; i <= size(L); i++)
+  {s = dShiftDiv(V, L[i])[1];
+   if (s <> -1)
+   {p = lpReduce(p,G[i],s);
+    p = lpNormalForm1(p,G,L);
+    break;
+   }
+  }
+  p = p[1] + lpNormalForm1(p-p[1],G,L);
+  return(p);
+ }
+}
+
+
+
+
+//secundary procedures, all static
+
+static proc getlpCoeffs(poly q, poly p)
+"
+"
+{list R; poly m; intvec cq,t,lv,rv,bla;
+ int n = attrib(basering,"lV"); int d = attrib(basering,"uptodeg");
+ int i;
+ m = p/q;
+ cq = leadexp(m);
+ for (i = 1; i<= d; i++)
+ {bla = cq[((i-1)*n+1)..(i*n)];
+  if (bla == 0) {lv = cq[1..i*n]; cq = cq[(i*n+1)..(d*n)]; break;}
+ }
+
+ d = size(cq) div n;
+ for (i = 1; i<= d; i++)
+ {bla = cq[((i-1)*n+1)..(i*n)];
+  if (bla <> 0){rv = cq[((i-1)*n+1)..(d*n)]; break;}
+ }
+ return(list(monomial(lv),monomial(rv)));
+}
+
+static proc lpReduce(poly p, poly g, int s)
+"NOTE: shift can not exceed the degree bound, because s*g | p
+"
+{poly l,r,qt; int i;
+ g = shiftPoly(g,s);
+ list K = getlpCoeffs(lead(g),lead(p));
+ l = K[1]; r = K[2];
+ kill K;
+ for (i = 1; i <= size(g); i++)
+ {qt = qt + lpMult(lpMult(l,g[i]),r);
+ }
+ return((leadcoef(qt)*p - leadcoef(p)*qt));
+}
+
+
+static proc lpShrink(poly p)
+"
+"
+{int n;
+ if (typeof(attrib(basering,"isLetterplaceRing"))=="int")
+ {n = attrib(basering,"lV");
+  return(system("shrinktest",p,n));
+ }
+ else {ERROR("Basering is not a Letterplace ring!");}
+}
+
+static proc checkAssumptions(poly p, ideal G)
+"
+"
+{checkLPRing();
+ checkAssumptionPoly(p);
+ checkAssumptionIdeal(G);
+ return();
+}
+
+static proc checkLPRing();
+"
+"
+{if (typeof(attrib(basering,"isLetterplaceRing"))=="string") {ERROR("Basering is not a Letterplace ring!");}
+ return();
+}
+
+static proc checkAssumptionIdeal(ideal G)
+"PURPOSE:Check if all elements of ideal are elements of V'
+"
+{ideal L = lead(normalize(G));
+ int i;
+ for (i = 1; i <= ncols(G); i++) {if (!isContainedInVp(G[i])) {ERROR("Ideal containes elements not contained in V'");}}
+ return();
+}
+
+static proc checkAssumptionPoly(poly p)
+"PURPOSE:Check if p is an element of V'
+"
+{poly l = lead(normalize(p));
+ if (!isContainedInVp(l)) {ERROR("Polynomial is not contained in V'");}
+ return();
+}
+
+static proc isContainedInVp(poly p)
+"PURPOSE: Check monomial for holes in the places
+"
+{int r = 0; intvec w;
+ intvec l = leadexp(p);
+ int n = attrib(basering,"lV"); int d = attrib(basering,"uptodeg");
+ int i,j,c,c1;
+ while (1 <= d)
+ {w = l[1..n];
+  if (w<>intvec(0)){break;}
+   else {l = l[(n+1)..(n*d)]; d = d-1;}
+ }
+
+ while (1 <= d)
+  {for (j = 1; j <= n; j++)
+   {if (l[j]<>0)
+    {if (c1<>0){return(0);}
+     if (c<>0){return(0);}
+     if (l[j]<>1){return(0);}
+     c=1;
+    }
+   }
+   if (c == 0){c1=1;if (1 < d){l = l[(n+1)..(n*d)]; d = d-1;} else {d = d -1;}}
+    else {c = 0; if (1 < d){l = l[(n+1)..(n*d)]; d = d-1;} else {d = d -1;}}
+  }
+ return(1);
+}
+
+// under development for Roberto
+static proc extractLinearPart(module M)
+{
+  /* returns vectors from a module whose max leadexp is 1 */
+  /* does not take place nonlinearity into account yet */
+  /* use rather kernel function isinV to get really nonlinear things */
+  int i; int s = ncols(M);
+  int answer = 1;
+  vector v; module Ret;
+  for(i=1; i<=s; i++)
+  {
+    if ( isLinearVector(M[i]) )
+    {
+      Ret = Ret, M[i];
+    }
+  }
+  Ret = simplify(Ret,2);
+  return(Ret);
+}
+
+// under development for Roberto
+static proc isLinearVector(vector v)
+{
+  /* returns true iff max leadexp is 1 */
+  int i,j,k;
+  intvec w;
+  int s = size(v);
+  poly p;
+  int answer = 1;
+  for(i=1; i<=s; i++)
+  {
+    p = v[i];
+    while (p != 0)
+    {
+      w = leadexp(p);
+      j = Max(w);
+      if (j >=2)
+      {
+        answer = 0;
+        return(answer);
+      }
+      p = p-lead(p);
+    }
+  }
+  return(answer);
+}
+
+
+// // the following is to determine a shift of a mono/poly from the
+// // interface
+
+// proc whichshift(poly p, int numvars)
+// {
+// // numvars = number of vars of the orig free algebra
+// // assume: we are in the letterplace ring
+// // takes  monomial on the input
+// poly q = lead(p);
+// intvec v = leadexp(v);
+// if (v==0) { return(int(0)); }
+// int sv = size(v);
+// int i=1;
+// while ( (v[i]==0) && (i<sv) ) { i++; }
+// i = sv div i;
+// return(i);
+// }
+
+
+// LIB "qhmoduli.lib";
+// proc polyshift(poly p,  int numvars)
+// {
+//   poly q = p; int i = 0;
+//   while (q!=0)
+//   {
+//     i = Max(i, whichshift(q,numvars));
+//     q = q - lead(q);
+//   }
+//   return(q);
+// }
+
+static proc lpAssumeViolation()
+{
+  // checks whether the global vars
+  // uptodeg and lV are defined
+  // returns Boolean : yes/no [for assume violation]
+  def lpring = attrib(basering,"isLetterplaceRing");
+  if ( typeof(lpring)!="int" )
+  {
+    //  if ( typeof(lpring)=="string" ) ??
+    // basering is NOT lp Ring
+    return(1);
+  }
+  def uptodeg = attrib(basering,"uptodeg");
+  if ( typeof(uptodeg)!="int" )
+  {
+    return(1);
+  }
+  def lV = attrib(basering,"lV");
+  if ( typeof(lV)!="int" )
+  {
+    return(1);
+  }
+  //  int i = ( defined(uptodeg) && (defined(lV)) );
+  //  return ( !i );
+  return(0);
+}
+
+static proc bugSKing()
+{
+  LIB "freegb.lib";
+  ring r=0,(a,b),dp;
+  def R = makeLetterplaceRing(5);
+  setring R;
+  poly p = a(1);
+  poly q = b(1);
+  poly p2 = lpPower(p,2);
+  lpMult(p2+q,q)-lpMult(p2,q)-lpMult(q,q); // now its 0
+}
+
+static proc bugRucker()
+{
+  // needs unstatic lpMultX
+  LIB "freegb.lib";
+  ring r=0,(a,b,c,d,p,q,r,s,t,u,v,w),(a(7,1,1,7),dp);
+  def R=makeLetterplaceRing(20,1);
+  setring R;
+  option(redSB); option(redTail);
+  ideal I=a(1)*b(2)*c(3)-p(1)*q(2)*r(3)*s(4)*t(5)*u(6),b(1)*c(2)*d(3)-v(1)*w(2);
+  poly ttt = a(1)*v(2)*w(3)-p(1)*q(2)*r(3)*s(4)*t(5)*u(6)*d(7);
+  // with lpMult
+  lpMult(I[1],d(1)) - lpMult(a(1),I[2]); // spoly; has been incorrect before
+  _ - ttt;
+  // with lpMultX
+  lpMultX(I[1],d(1)) - lpMultX(a(1),I[2]); // spoly; has been incorrect before
+  _ - ttt;
+}
+
+static proc checkWeightedExampleLP()
+{
+  ring r = 0,(x(1),y(1),x(2),y(2),x(3),y(3),x(4),y(4)),wp(2,1,2,1,2,1,2,1);
+  def R = setLetterplaceAttributes(r,4,2); // supply R with letterplace structure
+  setring R;
+  poly a = x(1)*y(2)+x(1)+y(1); poly b = y(1)+3;
+  lpMultX(b,a);
+  lpMultX(a,b); // seems to work properly
+}
diff --git a/Singular/LIB/general.lib b/Singular/LIB/general.lib
new file mode 100644
index 0000000..6d03e3f
--- /dev/null
+++ b/Singular/LIB/general.lib
@@ -0,0 +1,1274 @@
+///////////////////////////////////////////////////////////////////////////////
+version="version general.lib 4.0.0.1 Jan_2014 "; // $Id: cd2117d3b435d9c959fb961f6e64e1dcd670f42b $
+category="General purpose";
+info="
+LIBRARY:  general.lib   Elementary Computations of General Type
+
+PROCEDURES:
+ A_Z(\"a\",n);          string a,b,... of n comma separated letters
+ ASCII([n,m]);          string of printable ASCII characters (number n to m)
+ absValue(c);           absolute value of c
+ binomial(n,m[,../..]); n choose m (type int), [type bigint]
+ deleteSublist(iv,l);   delete entries given by iv from list l
+ factorial(n[,../..]);  n factorial (=n!) (type int), [type bigint]
+ fibonacci(n);          nth Fibonacci number
+ kmemory([n[,v]]);      active [allocated] memory in kilobyte
+ killall();             kill all user-defined variables
+ number_e(n);           compute exp(1) up to n decimal digits
+ number_pi(n);          compute pi (area of unit circle) up to n digits
+ primes(n,m);           intvec of primes p, n<=p<=m
+ product(../..[,v]);    multiply components of vector/ideal/...[indices v]
+ sort(ideal/module);    sort generators according to monomial ordering
+ sum(vector/id/..[,v]); add components of vector/ideal/...[with indices v]
+ watchdog(i,cmd);       only wait for result of command cmd for i seconds
+ primecoeffs(J[,q]);    primefactors <= min(p,32003) of coeffs of J
+ timeStd(i,d)           std(i) if the standard basis computation finished
+                        after d-1 seconds and i otherwhise
+ timeFactorize(p,d)     factorize(p) if the factorization finished after d-1
+                        seconds otherwhise f is considered to be irreducible
+ factorH(p)             changes variables to become the last variable the
+                        principal one in the multivariate factorization and
+                        factorizes then the polynomial
+
+           (parameters in square brackets [] are optional)
+";
+
+LIB "inout.lib";
+LIB "poly.lib";
+LIB "matrix.lib";
+///////////////////////////////////////////////////////////////////////////////
+
+proc A_Z (string s,int n)
+"USAGE:   A_Z(\"a\",n);  a any letter, n integer (-26<= n <=26, !=0)
+RETURN:  string of n small (if a is small) or capital (if a is capital)
+         letters, comma separated, beginning with a, in alphabetical
+         order (or reverse alphabetical order if n<0)
+EXAMPLE: example A_Z; shows an example
+"
+{
+  if ( n>=-26 and n<=26 and n!=0 )
+  {
+    string alpha =
+    "a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,"+
+    "a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,"+
+    "A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,"+
+    "A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z";
+    int ii; int aa;
+    for(ii=1; ii<=51; ii=ii+2)
+    {
+       if( alpha[ii]==s ) { aa=ii; }
+    }
+    if ( aa==0)
+    {
+      for(ii=105; ii<=155; ii=ii+2)
+      {
+        if( alpha[ii]==s ) { aa=ii; }
+      }
+    }
+    if( aa!=0 )
+    {
+      string out;
+      if (n > 0) { out = alpha[aa,2*(n)-1];  return (out); }
+      if (n < 0)
+      {
+        string beta =
+        "z,y,x,w,v,u,t,s,r,q,p,o,n,m,l,k,j,i,h,g,f,e,d,c,b,a,"+
+        "z,y,x,w,v,u,t,s,r,q,p,o,n,m,l,k,j,i,h,g,f,e,d,c,b,a,"+
+        "Z,Y,X,W,V,U,T,S,R,Q,P,O,N,M,L,K,J,I,H,G,F,E,D,C,B,A,"+
+        "Z,Y,X,W,V,U,T,S,R,Q,P,O,N,M,L,K,J,I,H,G,F,E,D,C,B,A";
+        if ( aa < 52 ) { aa=52-aa; }
+        if ( aa > 104 ) { aa=260-aa; }
+        out = beta[aa,2*(-n)-1]; return (out);
+      }
+    }
+  }
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   A_Z("c",5);
+   A_Z("Z",-5);
+   string sR = "ring R = (0,"+A_Z("A",6)+"),("+A_Z("a",10)+"),dp;";
+   sR;
+   execute(sR);
+   R;
+}
+///////////////////////////////////////////////////////////////////////////////
+proc ASCII (list #)
+"USAGE:   ASCII([n,m]); n,m= integers (32 <= n <= m <= 126)
+RETURN:   string of printable ASCII characters (no native language support)@*
+          ASCII():    string of  all ASCII characters with its numbers,@*
+          ASCII(n):   n-th ASCII character@*
+          ASCII(n,m): n-th up to m-th ASCII character (inclusive)
+EXAMPLE: example ASCII; shows an example
+"
+{
+  string s1 =
+ "     !    \"    #    $    %    &    '    (    )    *    +    ,    -    .
+32   33   34   35   36   37   38   39   40   41   42   43   44   45   46
+/    0    1    2    3    4    5    6    7    8    9    :    ;    <    =
+47   48   49   50   51   52   53   54   55   56   57   58   59   60   61
+>    ?    @    A    B    C    D    E    F    G    H    I    J    K    L
+62   63   64   65   66   67   68   69   70   71   72   73   74   75   76
+M    N    O    P    Q    R    S    T    U    V    W    X    Y    Z    [
+77   78   79   80   81   82   83   84   85   86   87   88   89   90   91
+\\    ]    ^    _    `    a    b    c    d    e    f    g    h    i    j
+92   93   94   95   96   97   98   99  100  101  102  103  104  105  10
+k    l    m    n    o    p    q    r    s    t    u    v    w    x    y
+107  108  109  110  111  112  113  114  115  116  117  118  119  120  121
+z    {    |    }    ~
+122  123  124  125  126 ";
+
+   string s2 =
+ " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
+
+   if ( size(#) == 0 )
+   {
+      return(s1);
+   }
+   if ( size(#) == 1 )
+   {
+      return( s2[#[1]-31] );
+   }
+   if ( size(#) == 2 )
+   {
+      return( s2[#[1]-31,#[2]-#[1]+1] );
+   }
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ASCII();"";
+   ASCII(42);
+   ASCII(32,126);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc absValue(def c)
+"USAGE:  absValue(c); c int, number or poly
+RETURN:  absValue(c); the absolute value of c
+NOTE:    absValue(c)=c if c>=0; absValue=-c if c<=0.
+@*       So the function can be applied to any type, for which comparison
+@*       operators are defined.
+EXAMPLE: example absValue; shows an example
+"
+{
+  if (c>=0) { return(c); }
+  else { return(-c); }
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r1 = 0,x,dp;
+   absValue(-2002);
+
+   poly f=-4;
+   absValue(f);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc binomial (int n, int k)
+"USAGE:   binomial(n,k); n,k integers
+RETURN:  binomial(n,k); binomial coefficient n choose k
+EXAMPLE: example binomial; shows an example
+"
+{
+   bigint l;
+   bigint r=1;
+   bigint kk=k;
+   bigint nn=n;
+   if ( k > n-k )
+   { k = n-k; }
+   if ( k<=0 or k>n )               //trivial cases
+   { r = (k==0)*r; }
+   for (l=1; l<=kk; l=l+1 )
+   {
+      r=r*(nn+1-l)/l;
+   }
+   return(r);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   binomial(200,100);"";                 //type bigint
+   int n,k = 200,100;
+   bigint b1 = binomial(n,k);
+   ring r = 0,x,dp;
+   poly b2 = coeffs((x+1)^n,x)[k+1,1];  //coefficient of x^k in (x+1)^n
+   b1-b2;                               //b1 and b2 should coincide
+}
+///////////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc factorial (int n)
+"USAGE:    factorial(n);  n integer
+RETURN:   factorial(n):   n! of type bigint.
+SEE ALSO: prime
+EXAMPLE:  example factorial; shows an example
+"
+{
+   bigint r=1;
+//------------------------------ computation --------------------------------
+   for (int l=2; l<=n; l++)
+   {
+      r=r*l;
+   }
+   return(r);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   factorial(37);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc fibonacci (int n)
+"USAGE:    fibonacci(n);  n,p integers
+RETURN:   fibonacci(n): nth Fibonacci number, f(0)=f(1)=1, f(i+1)=f(i-1)+f(i)
+@*        - computed in characteristic 0, of type bigint
+SEE ALSO: prime
+EXAMPLE: example fibonacci; shows an example
+"
+{
+  bigint f,g,h=1,1,1;
+//------------------------------ computation --------------------------------
+   for (int ii=3; ii<=n; ii++)
+   {
+      h = f+g; f = g; g = h;
+   }
+   return(h);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   fibonacci(42);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc kmemory (list #)
+"USAGE:   kmemory([n,[v]]); n,v integers
+RETURN:  memory in kilobyte of type bigint
+@*       n=0: memory used by active variables (same as no parameters)
+@*       n=1: total memory allocated by Singular
+DISPLAY: detailed information about allocated and used memory if v!=0
+NOTE:    kmemory uses internal function 'memory' to compute kilobyte, and
+         is the same as 'memory' for n!=0,1,2
+EXAMPLE: example kmemory; shows an example
+"
+{
+   int n;
+   int verb;
+   if (size(#) != 0)
+   {
+     n=#[1];
+     if (size(#) >1)
+     { verb=#[2]; }
+   }
+
+  if ( verb != 0)
+  {
+    if ( n==0)
+    { dbprint(printlevel-voice+3,
+      "// memory used, at the moment, by active variables (kilobyte):"); }
+    if ( n==1 )
+    { dbprint(printlevel-voice+3,
+      "// total memory allocated, at the moment, by SINGULAR (kilobyte):"); }
+  }
+  return ((memory(n)+1023) div 1024);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   kmemory();
+   kmemory(1,1);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc killall
+"USAGE:   killall(); (no parameter)
+         killall(\"type_name\");
+         killall(\"not\", \"type_name\");
+RETURN:  killall(); kills all user-defined variables except loaded procedures,
+         no return value.
+@*       - killall(\"type_name\"); kills all user-defined variables,
+           of type \"type_name\"
+@*       - killall(\"not\", \"type_name\"); kills all user-defined variables,
+           except those of type \"type_name\" and except loaded procedures
+@*       - killall(\"not\", \"name_1\", \"name_2\", ...);
+           kills all user-defined variables, except those of name \"name_i\"
+           and except loaded procedures
+NOTE:    killall should never be used inside a procedure
+EXAMPLE: example killall; shows an example AND KILLS ALL YOUR VARIABLES
+"
+{
+  list @marie=names(Top);
+  int j, no_kill, @joni;
+  for ( @joni=1; @joni<=size(#);  @joni++)
+  {
+    if (typeof(#[@joni]) != "string")
+    {
+      ERROR("Need string as " + string(@joni) + "th argument");
+    }
+  }
+
+  // kills all user-defined variables but not loaded procedures
+  if( size(#)==0 )
+  {
+    for ( @joni=size(@marie); @joni>0; @joni-- )
+    {
+      if( @marie[@joni]!="LIB" and typeof(`@marie[@joni]`)!="proc"
+      and typeof(`@marie[@joni]`)!="package")
+      { kill `@marie[@joni]`; }
+    }
+  }
+  else
+  {
+    // kills all user-defined variables
+    if( size(#)==1 )
+    {
+      // of type proc
+      if( #[1] == "proc" )
+      {
+        for ( @joni=size(@marie); @joni>0; @joni-- )
+        {
+          if( (@marie[@joni]!="General")
+          and (@marie[@joni]!="Top")
+          and (@marie[@joni]!="killall")
+          and (@marie[@joni]!="LIB") and
+              ((typeof(`@marie[@joni]`)=="package") or
+              (typeof(`@marie[@joni]`)=="proc")))
+          {
+            if (defined(`@marie[@joni]`)) {kill `@marie[@joni]`;}
+          }
+          if (!defined(@joni)) break;
+        }
+        if (defined(General))
+        {
+          @marie=names(General);
+          for ( @joni=size(@marie); @joni>0; @joni-- )
+          {
+            if(@marie[@joni]!="killall"
+            and typeof(`@marie[@joni]`)=="proc")
+            { kill General::`@marie[@joni]`; }
+          }
+          kill General::killall;
+        }
+      }
+      else
+      {
+        // other types
+        for ( @joni=size(@marie); @joni>2; @joni-- )
+        {
+          if(typeof(`@marie[@joni]`)==#[1] and @marie[@joni]!="LIB"
+             and typeof(`@marie[@joni]`)!="proc")
+          { kill `@marie[@joni]`; }
+        }
+      }
+    }
+    else
+    {
+      // kills all user-defined variables whose name or type is not #i
+      for ( @joni=size(@marie); @joni>2; @joni-- )
+      {
+        if ( @marie[@joni] != "LIB" && @marie[@joni] != "Top"
+             && typeof(`@marie[@joni]`) != "proc")
+        {
+          no_kill = 0;
+          for (j=2; j<= size(#); j++)
+          {
+            if (typeof(`@marie[@joni]`)==#[j] or @marie[@joni] == #[j])
+            {
+              no_kill = 1;
+              break;
+            }
+          }
+          if (! no_kill)
+          {
+            kill `@marie[@joni]`;
+          }
+        }
+        if (!defined(@joni)) break;
+      }
+    }
+  }
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring rtest; ideal i=x,y,z; string str="hi"; int j = 3;
+   export rtest,i,str,j;       //this makes the local variables global
+   listvar();
+   killall("ring");            // kills all rings
+   listvar();
+   killall("not", "int");      // kills all variables except int's (and procs)
+   listvar();
+   killall();                  // kills all vars except loaded procs
+   listvar();
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc number_e (int n)
+"USAGE:   number_e(n);  n integer
+RETURN:  Euler number e=exp(1) up to n decimal digits (no rounding)
+@*       - of type string if no basering of char 0 is defined
+@*       - of type number if a basering of char 0 is defined
+DISPLAY: decimal format of e if printlevel > 0 (default:printlevel=0 )
+NOTE:    procedure uses algorithm of A.H.J. Sale
+EXAMPLE: example number_e; shows an example
+"
+{
+   int i,m,s,t;
+   intvec u,e;
+   u[n+2]=0; e[n+1]=0; e=e+1;
+   if( defined(basering) )
+   {
+      if( char(basering)==0 ) { number r=2; t=1; }
+   }
+   string result = "2.";
+   for( i=1; i<=n+1; i=i+1 )
+   {
+      e = e*10;
+      for( m=n+1; m>=1; m=m-1 )
+      {
+         s    = e[m]+u[m+1];
+         u[m] = s div (m+1);
+         e[m] = s%(m+1);
+      }
+      result = result+string(u[1]);
+      if( t==1 ) { r = r+number(u[1])/number(10)^i; }
+   }
+   if( t==1 )
+   { dbprint(printlevel-voice+2,"// "+result[1,n+1]);
+     return(r);
+   }
+   return(result[1,n+1]);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   number_e(30);"";
+   ring R = 0,t,lp;
+   number e = number_e(30);
+   e;
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc number_pi (int n)
+"USAGE:   number_pi(n);  n positive integer
+RETURN:  pi (area of unit circle) up to n decimal digits (no rounding)
+@*       - of type string if no basering of char 0 is defined,
+@*       - of type number, if a basering of char 0 is defined
+DISPLAY: decimal format of pi if printlevel > 0 (default:printlevel=0 )
+NOTE:    procedure uses algorithm of S. Rabinowitz
+EXAMPLE: example number_pi; shows an example
+"
+{
+   int i,m,t,e,q,N;
+   intvec r,p,B,Prelim;
+   string result,prelim;
+   N = (10*n) div 3 + 2;
+   p[N+1]=0; p=p+2; r=p;
+   for( i=1; i<=N+1; i=i+1 ) { B[i]=2*i-1; }
+   if( defined(basering) )
+   {
+      if( char(basering)==0 ) { number pi; number pri; t=1; }
+   }
+   for( i=0; i<=n; i=i+1 )
+   {
+      p = r*10;
+      e = p[N+1];
+      for( m=N+1; m>=2; m=m-1 )
+      {
+         r[m] = e%B[m];
+         q    = e div B[m];
+         e    = q*(m-1)+p[m-1];
+      }
+      r[1] = e%10;
+      q    = e div 10;
+      if( q!=10 and q!=9 )
+      {
+         result = result+prelim;
+         Prelim = q;
+         prelim = string(q);
+      }
+      if( q==9 )
+      {
+         Prelim = Prelim,9;
+         prelim = prelim+"9";
+      }
+      if( q==10 )
+      {
+         Prelim = (Prelim+1)-((Prelim+1) div 10)*10;
+         for( m=size(Prelim); m>0; m=m-1)
+         {
+            prelim[m] = string(Prelim[m]);
+         }
+         result = result+prelim;
+         if( t==1 ) { pi=pi+pri; }
+         Prelim = 0;
+         prelim = "0";
+      }
+      if( t==1 ) { pi=pi+number(q)/number(10)^i; }
+   }
+   result = result,prelim[1];
+   result = "3."+result[2,n-1];
+   if( t==1 )
+   { dbprint(printlevel-voice+2,"// "+result);
+     return(pi);
+   }
+   return(result);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   number_pi(11);"";
+   ring r = (real,10),t,dp;
+   number pi = number_pi(11); pi;
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc primes (int n, int m)
+"USAGE:   primes(n,m);  n,m integers
+RETURN:  intvec, consisting of all primes p, prime(n)<=p<=m, in increasing
+         order if n<=m, resp. prime(m)<=p<=n, in decreasing order if m<n.
+NOTE:    prime(n); returns the biggest prime number <= min(n,32003)
+         if n>=2, else 2
+EXAMPLE: example primes; shows an example
+"
+{  int change;
+   if ( n>m ) { change=n; n=m ; m=change; change=1; }
+   int q,p = prime(m),prime(n); intvec v = q; q = q-1;
+   while ( q>=p ) { q = prime(q); v = q,v; q = q-1; }
+   if ( change==1 ) { v = v[size(v)..1]; }
+   return(v);
+}
+example
+{  "EXAMPLE:"; echo = 2;
+    primes(50,100);"";
+    intvec v = primes(37,1); v;
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc product (def id, list #)
+"USAGE:    product(id[,v]); id ideal/vector/module/matrix/intvec/intmat/list,
+          v intvec  (default: v=1..number of entries of id)
+ASSUME:   list members can be multiplied.
+RETURN:   The product of all entries of id [with index given by v] of type
+          depending on the entries of id.
+NOTE:     If id is not a list, id is treated as a list of polys resp. integers.
+          A module m is identified with the corresponding matrix M (columns
+          of M generate m).
+@*        If v is outside the range of id, we have the empty product and the
+          result will be 1 (of type int).
+EXAMPLE:  example product; shows an example
+"
+{
+//-------------------- initialization and special feature ---------------------
+   int n,j,tt;
+   string ty;                                //will become type of id
+   list l;
+
+// We wish to allow something like product(x(1..10)) if x(1),...,x(10) are
+// variables. x(1..10) is a list of polys and enters the procedure with
+// id=x(1) and # a list with 9 polys, #[1]= x(2),...,#[9]= x(10). Hence, in
+// this case # is never empty. If an additional intvec v is given,
+// it is added to #, so we have to separate it first and make
+// the rest a list which has to be multiplied.
+
+   int s = size(#);
+   if( s!=0 )
+   {  if ( typeof(#[s])=="intvec" or typeof(#[s])=="int")
+      {
+         intvec v = #[s];
+         tt=1;
+         s=s-1;
+         if ( s>0 ) { # = #[1..s]; }
+      }
+   }
+   if ( s>0 )
+   {
+      l = list(id)+#;
+      kill id;
+      list id = l;                                    //case: id = list
+      ty = "list";
+      n = size(id);
+   }
+   else
+   {
+      ty = typeof(id);
+      if( ty == "list" )
+      { n = size(id); }
+   }
+//------------------------------ reduce to 3 cases ---------------------------
+   if( ty=="poly" or ty=="ideal" or ty=="vector"
+       or ty=="module" or ty=="matrix" )
+   {
+      ideal i = ideal(matrix(id));
+      kill id;
+      ideal id = i;                                   //case: id = ideal
+      n = ncols(id);
+   }
+   if( ty=="int" or ty=="intvec" or ty=="intmat" )
+   {
+      if ( ty == "int" ) { intmat S =id; }
+      else { intmat S = intmat(id); }
+      intvec i = S[1..nrows(S),1..ncols(S)];
+      kill id;
+      intvec id = i;                                  //case: id = intvec
+      n = size(id);
+   }
+//--------------- consider intvec v and empty product  -----------------------
+   if( tt!=0 )
+   {
+      for (j=1; j<=size(v); j++)
+      {
+         if ( v[j] <= 0 or v[j] > n )                 //v outside range of id
+         {
+            return(1);                                //empty product is 1
+         }
+      }
+      id = id[v];                                     //consider part of id
+   }                                                  //corresponding to v
+//--------------------- special case: one factor is zero  ---------------------
+   if ( typeof(id) == "ideal")
+   {
+      if( size(id) < ncols(id) )
+      {
+          poly f; return(f);
+      }
+   }
+//-------------------------- finally, multiply objects  -----------------------
+   n = size(id);
+   def f(1) = id[1];
+   for( j=2; j<=n; j=j+1 ) { def f(j)=f(j-1)*id[j]; }
+   return(f(n));
+}
+example
+{  "EXAMPLE:"; echo = 2;
+   ring r= 0,(x,y,z),dp;
+   ideal m = maxideal(1);
+   product(m);
+   product(m[2..3]);
+   matrix M[2][3] = 1,x,2,y,3,z;
+   product(M);
+   intvec v=2,4,6;
+   product(M,v);
+   intvec iv = 1,2,3,4,5,6,7,8,9;
+   v=1..5,7,9;
+   product(iv,v);
+   intmat A[2][3] = 1,1,1,2,2,2;
+   product(A,3..5);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc sort (def id, list #)
+"USAGE:   sort(id[,v,o,n]); id = ideal/module/intvec/list
+@*       sort may be called with 1, 2 or 3 arguments in the following way:
+@*       sort(id[,v,n]); v=intvec of positive integers, n=integer,
+@*       sort(id[,o,n]); o=string (any allowed ordstr of a ring), n=integer
+RETURN:  a list l of two elements:
+ at format
+        l[1]: object of same type as input but sorted in the following way:
+           - if id=ideal/module: generators of id are sorted w.r.t. intvec v
+             (id[v[1]] becomes 1-st, id[v[2]]  2-nd element, etc.). If no v is
+             present, id is sorted w.r.t. ordering o (if o is given) or w.r.t.
+             actual monomial ordering (if no o is given):
+             NOTE: generators with SMALLER(!) leading term come FIRST
+             (e.g. sort(id); sorts backwards to actual monomial ordering)
+           - if id=list or intvec: sorted w.r.t. < (indep. of other arguments)
+           - if n!=0 the ordering is inverse, i.e. w.r.t. v(size(v)..1)
+             default: n=0
+         l[2]: intvec, describing the permutation of the input (hence l[2]=v
+             if v is given (with positive integers))
+ at end format
+NOTE:    If v is given id may be any simply indexed object (e.g. any list or
+         string); if v[i]<0 and i<=size(id) v[i] is set internally to i;
+         entries of v must be pairwise distinct to get a permutation id.
+         Zero generators of ideal/module are deleted
+         If 'o' is given, the input is sorted by considering leading terms
+         w.r.t. the new ring ordering given by 'o'
+EXAMPLE: example sort; shows an example
+"
+{  int ii,jj,s,n = 0,0,1,0;
+   intvec v;
+   if ( defined(basering) ) { def P = basering; }
+   if ( size(#)==0 and (typeof(id)=="ideal" or typeof(id)=="module"
+                        or typeof(id)=="matrix"))
+   {
+      id = simplify(id,2);
+      for ( ii=1; ii<ncols(id); ii++ )
+      {
+         if ( id[ii]!=id[ii+1] ) { break;}
+      }
+      if ( ii != ncols(id) ) { v = sortvec(id); }
+      else  { v = ncols(id)..1; }
+   }
+   if ( size(#)>=1 and (typeof(id)=="ideal" or typeof(id)=="module"
+                        or typeof(id)=="matrix") )
+   {
+      if ( typeof(#[1])=="string" )
+      {
+         execute("ring r1 =("+charstr(P)+"),("+varstr(P)+"),("+#[1]+");");
+         def i = imap(P,id);
+         v = sortvec(i);
+         setring P;
+         n=2;
+      }
+   }
+   if ( typeof(id)=="intvec" or typeof(id)=="list" )
+   {
+      int Bn,Bi,Bj,Bb;
+      intvec pivot;
+      for(Bi=size(id);Bi>0;Bi--) { pivot[Bi]=Bi; }
+      while(Bj==0)
+      {
+        Bi++;
+        Bj=1;
+        for(Bn=1;Bn<=size(id)-Bi;Bn++)
+        {
+          if(id[pivot[Bn]]>id[pivot[Bn+1]])
+          {
+            Bb=pivot[Bn];
+            pivot[Bn]=pivot[Bn+1];
+            pivot[Bn+1]=Bb;
+            Bj=0;
+          }
+        }
+      }
+      def Br=id;
+      for(Bi=size(id);Bi>0;Bi--) { Br[Bi]=id[pivot[Bi]]; }
+      return(list(Br,pivot));
+   }
+   if ( size(#)!=0 and n==0 ) { v = #[1]; }
+   if( size(#)==2 )
+   {
+      if ( #[2] != 0 ) { v = v[size(v)..1]; }
+   }
+   s = size(v);
+   if( size(id) < s ) { s = size(id); }
+   def m = id;
+   if ( size(m) != 0 )
+   {
+      for ( jj=1; jj<=s; jj++)
+      {
+         if ( v[jj]<=0 ) { v[jj]=jj; }
+         m[jj] = id[v[jj]];
+      }
+   }
+   if ( v == 0 ) { v = 1; }
+   list L=m,v;
+   return(L);
+}
+example
+{  "EXAMPLE:"; echo = 2;
+   ring r0 = 0,(x,y,z,t),lp;
+   ideal i = x3,z3,xyz;
+   sort(i);            //sorts using lex ordering, smaller polys come first
+
+   sort(i,3..1);
+
+   sort(i,"ls")[1];     //sort w.r.t. negative lex ordering
+
+   intvec v =1,10..5,2..4;v;
+   sort(v)[1];          // sort v lexicographically
+
+   sort(v,"Dp",1)[1];   // sort v w.r.t (total sum, reverse lex)
+
+   // Note that in general: lead(sort(M)) != sort(lead(M)), e.g:
+   module M = [0, 1, 1, 0], [1, 0, 0, 1]; M;
+   sort(lead(M), "c, dp")[1];
+   lead(sort(M, "c, dp")[1]);
+
+   // In order to sort M wrt a NEW ordering by considering OLD leading
+   // terms use one of the following equivalent commands:
+   module( M[ sort(lead(M), "c,dp")[2] ] );
+   sort( M, sort(lead(M), "c,dp")[2] )[1];
+
+   // BUG: Please, don't use this sort for integer vectors or lists
+   // with them if there can be negative integers!
+   // TODO: for some HiWi
+   sort(3..-3)[1];
+   sort(list(-v, v))[1];
+
+}
+///////////////////////////////////////////////////////////////////////////////
+
+static proc lsum (int n, list l)
+{ if (n>10)
+  { return( lsum(n div 2,list(l[1..(n div 2)])) + lsum(n-n div 2, list(l[(n div 2+1)..n])) );
+  }
+  else
+  { def Summe=l[1];
+    for (int i=2;i<=n;i++)
+    { Summe=Summe+l[i];
+    }
+    return(Summe);
+  }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc sum (def id, list #)
+"USAGE:    sum(id[,v]); id ideal/vector/module/matrix/intvec/intmat/list,
+          v intvec  (default: v=1..number of entries of id)
+ASSUME:   list members can be added.
+RETURN:   The sum of all entries of id [with index given by v] of type
+          depending on the entries of id.
+NOTE:     If id is not a list, id is treated as a list of polys resp. integers.
+          A module m is identified with the corresponding matrix M (columns
+          of M generate m).
+@*        If v is outside the range of id, we have the empty sum and the
+          result will be 0 (of type int).
+EXAMPLE:  example sum; shows an example
+"
+{
+//-------------------- initialization and special feature ---------------------
+   int n,j,tt;
+   string ty;                                  // will become type of id
+   list l;
+
+// We wish to allow something like sum(x(1..10)) if x(1),...,x(10) are
+// variables. x(1..10) is a list of polys and enters the procedure with
+// id=x(1) and # a list with 9 polys, #[1]= x(2),...,#[9]= x(10). Hence, in
+// this case # is never empty. If an additional intvec v is given,
+// it is added to #, so we have to separate it first and make
+// the rest a list which has to be added.
+
+   int s = size(#);
+   if( s!=0 )
+   {  if ( typeof(#[s])=="intvec" or typeof(#[s])=="int")
+      {  intvec v = #[s];
+         tt=1;
+         s=s-1;
+         if ( s>0 ) { # = #[1..s]; }
+      }
+   }
+   if ( s>0 )
+   {
+      l = list(id)+#;
+      kill id;
+      list id = l;                                    //case: id = list
+      ty = "list";
+   }
+   else
+   {
+      ty = typeof(id);
+   }
+//------------------------------ reduce to 3 cases ---------------------------
+   if( ty=="poly" or ty=="ideal" or ty=="vector"
+       or ty=="module" or ty=="matrix" )
+   {                                                 //case: id = ideal
+      ideal i = ideal(matrix(id));
+      kill id;
+      ideal id = simplify(i,2);                      //delete 0 entries
+   }
+   if( ty=="int" or ty=="intvec" or ty=="intmat" )
+   {                                                 //case: id = intvec
+      if ( ty == "int" ) { intmat S =id; }
+      else { intmat S = intmat(id); }
+      intvec i = S[1..nrows(S),1..ncols(S)];
+      kill id;
+      intvec id = i;
+   }
+//------------------- consider intvec v and empty sum  -----------------------
+   if( tt!=0 )
+   {
+      for (j=1; j<=size(v); j++)
+      {
+         if ( v[j] <= 0 or v[j] > size(id) )         //v outside range of id
+         {
+            return(0);                               //empty sum is 0
+         }
+      }
+      id = id[v];                                    //consider part of id
+   }                                                 //corresponding to v
+
+//-------------------------- finally, add objects  ---------------------------
+   n = size(id);
+   if (n>10)
+   { return( lsum(n div 2,list(id[1..(n div 2)])) + lsum(n-n div 2, list(id[(n div 2+1)..n])) );
+   }
+   else
+   { def Summe=id[1];
+     for (int lauf=2;lauf<=n;lauf++)
+     { Summe=Summe+id[lauf];
+     }
+     return(Summe);
+   }
+}
+example
+{  "EXAMPLE:"; echo = 2;
+   ring r1 = 0,(x,y,z),dp;
+   vector pv = [xy,xz,yz,x2,y2,z2];
+   sum(pv);
+   sum(pv,2..5);
+   matrix M[2][3] = 1,x,2,y,3,z;
+   intvec w=2,4,6;
+   sum(M,w);
+   intvec iv = 1,2,3,4,5,6,7,8,9;
+   sum(iv,2..4);
+   iv = intvec(1..100);
+   sum(iv);
+   ring r2 = 0,(x(1..10)),dp;
+   sum(x(3..7),intvec(1,3,5));
+}
+///////////////////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc watchdog(int i, string cmd)
+"USAGE:   watchdog(i,cmd); i integer, cmd string
+RETURN:  Result of cmd, if the result can be computed in i seconds.
+         Otherwise the computation is interrupted after i seconds,
+         the string "Killed" is returned and the global variable
+         'watchdog_interrupt' is defined.
+NOTE:    * the current basering should not be watchdog_rneu, since
+           watchdog_rneu will be killed
+         * if there are variable names of the structure x(i) all
+           polynomials have to be put into eval(...) in order to be
+           interpreted correctly
+         * a second Singular process is started by this procedure
+EXAMPLE: example watchdog; shows an example
+"
+{
+  if (defined(basering))
+  {
+    string rname=nameof(basering);
+    def rsave=basering;
+  }
+  if (defined(watchdog_rneu))
+  {
+    kill watchdog_rneu;
+  }
+  if ( i > 0 )
+  {
+// fork, get the pid of the child and send it the command
+    link l_fork="ssi:fork";
+    open(l_fork);
+    execute("write(l_fork,quote(" + cmd + "));");
+    list L=l_fork;
+    int j=waitfirst(L,i*1000);
+// check, whether we have a result, and return it
+    if (j==1)
+    {
+      def result = read(l_fork);
+      if (defined(rsave))
+      {
+        if (nameof(basering)!=rname)
+        {
+          def watchdog_rneu=basering;
+          setring rsave;
+          if (!defined(result))
+          {
+            def result=fetch(watchdog_rneu,result);
+          }
+        }
+      }
+      if(defined(watchdog_interrupt))
+      {
+        kill watchdog_interrupt;
+      }
+    }
+    else
+    {
+      string result="Killed";
+      if(!defined(watchdog_interrupt))
+      {
+        int watchdog_interrupt=1;
+        export watchdog_interrupt;
+      }
+    }
+    close(l_fork);
+    return(result);
+  }
+  else
+  {
+    ERROR("First argument of watchdog has to be a positive integer.");
+  }
+}
+example
+{ "EXAMPLE:"; echo=2;
+  proc sleep(int s) {return(system("sh","sleep "+string(s)));}
+  watchdog(1,"sleep(5)");
+  watchdog(10,"sleep(5)");
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc deleteSublist(intvec v,list l)
+"USAGE:   deleteSublist(v,l); intvec v; list l
+         where the entries of the integer vector v correspond to the
+         positions of the elements to be deleted
+RETURN:  list without the deleted elements
+EXAMPLE: example deleteSublist; shows an example"
+{
+  list k;
+  int i,j,skip;
+  j=1;
+  skip=0;
+  intvec vs=sort(v)[1];
+  for ( i=1 ; i <=size(vs) ; i++)
+  {
+    while ((j+skip) < vs[i])
+    {
+      k[j] = l[j+skip];
+      j++;
+    }
+    skip++;
+  }
+  if(vs[size(vs)]<size(l))
+  {
+    k=k+list(l[(vs[size(vs)]+1)..size(l)]);
+  }
+  return(k);
+}
+example
+{ "EXAMPLE:"; echo=2;
+   list l=1,2,3,4,5;
+   intvec v=1,3,4;
+   l=deleteSublist(v,l);
+   l;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+proc primecoeffs(def J, list #)
+"USAGE:   primecoeffs(J[,p]); J any type which can be converted to a matrix
+         e.g. ideal, matrix, vector, module, int, intvec
+         p = integer
+COMPUTE: primefactors <= p of coeffs of J (default p = 32003)
+RETURN:  a list, say l, of two intvectors:@*
+         l[1] : the different primefactors of all coefficients of J@*
+         l[2] : the different remaining factors
+EXAMPLE: example primecoeffs; shows an example
+"
+{
+   int q,ii,n,mark;;
+   if (size(#) == 0)
+   {
+      q=32003;
+   }
+   else
+   {
+     if( typeof(#[1]) != "int")
+     {
+       ERROR("2nd parameter must be of type int"+newline);
+     }
+     q=#[1];
+     if (q > 32003) { q = 32003; }
+   }
+
+   if (defined(basering) == 0)
+   {
+     mark=1;
+     ring r = 0,x,dp;
+   }
+   def I = ideal(matrix(J));
+   poly p = product(maxideal(1));
+   matrix Coef=coef(I[1],p);
+   ideal id, jd, rest;
+   intvec v,re;
+   list result,l;
+   for(ii=2; ii<=ncols(I); ii++)
+   {
+     Coef=concat(Coef,coef(I[ii],p));
+   }
+   id = Coef[2,1..ncols(Coef)];
+   id = simplify(id,6);
+   for (ii=1; ii<=size(id); ii++)
+   {
+     l = primefactors(number(id[ii]),q);
+     list jdl=l[1];
+     jd = jd,jdl[1..size(jdl)];
+     kill jdl;
+     rest=rest, l[3];
+   }
+   jd = simplify(jd,6);
+   for (ii=1; ii<=size(jd); ii++)
+   {
+     v[ii]=int(jd[ii]);
+   }
+   v = sort(v)[1];
+   rest = simplify(rest,6);
+   id = sort(id)[1];
+   if (mark)
+   {
+     for (ii=1; ii<=size(rest); ii++)
+     {
+       re[ii] = int(rest[ii]);
+     }
+     result = v,re;
+   }
+   else
+   {
+      result = v,rest;
+   }
+   return(result);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   primecoeffs(intvec(7*8*121,7*8));"";
+   ring r = 0,(b,c,t),dp;
+   ideal I = -13b6c3t+4b5c4t,-10b4c2t-5b4ct2;
+   primecoeffs(I);
+}
+///////////////////////////////////////////////////////////////////////////////
+proc timeFactorize(poly i,list #)
+"USAGE:  timeFactorize(p,d); poly p , integer d
+RETURN:  factorize(p) if the factorization finished after d-1
+         seconds otherwhise f is considered to be irreducible
+EXAMPLE: example timeFactorize; shows an example
+"
+{
+  def P=basering;
+  if (size(#) > 0)
+  {
+    if ((typeof(#[1]) == "int")&&(#[1]))
+    {
+      int wait = #[1];
+      int j = 10;
+
+      string bs = nameof(basering);
+      link l_fork = "ssi:fork";
+      open(l_fork);
+      write(l_fork, quote(timeFactorize(eval(i))));
+
+      // sleep in small intervalls for appr. one second
+      if (wait > 0)
+      {
+        while(j < 1000000)
+        {
+          if (status(l_fork, "read", "ready", j)) {break;}
+          j = j + j;
+        }
+      }
+
+      // sleep in intervalls of one second from now on
+      j = 1;
+      while (j < wait)
+      {
+        if (status(l_fork, "read", "ready", 1000000)) {break;}
+        j = j + 1;
+      }
+
+      if (status(l_fork, "read", "ready"))
+      {
+        def result = read(l_fork);
+        if (bs != nameof(basering))
+        {
+          def PP = basering;
+          setring P;
+          def result = imap(PP, result);
+          kill PP;
+        }
+        close(l_fork);
+      }
+      else
+      {
+        list result;
+        intvec v=1,1;
+        result[1]=list(1,i);
+        result[2]=v;
+        close(l_fork);
+      }
+      return (result);
+    }
+  }
+  return(factorH(i));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r=0,(x,y),dp;
+   poly p=((x2+y3)^2+xy6)*((x3+y2)^2+x10y);
+   p=p^2;
+   //timeFactorize(p,2);
+   //timeFactorize(p,20);
+}
+
+proc timeStd(ideal i,list #)
+"USAGE:  timeStd(i,d), i ideal, d integer
+RETURN:  std(i) if the standard basis computation finished after
+         d-1 seconds and i otherwhise
+EXAMPLE: example timeStd; shows an example
+"
+{
+  def P=basering;
+  if (size(#) > 0)
+  {
+    if ((typeof(#[1]) == "int")&&(#[1]))
+    {
+      int wait = #[1]*1000;
+
+      string bs = nameof(basering);
+      link l_fork = "ssi:fork";
+      open(l_fork);
+      write(l_fork, quote(std(eval(i))));
+      list L=l_fork;
+      int j=waitfirst(L,wait);
+      if (j==0) // timeout
+      {
+        ideal result=i;
+      }
+      else
+      {
+        def result = read(l_fork);
+        if (bs != nameof(basering))
+        {
+          def PP = basering;
+          setring P;
+          def result = imap(PP, result);
+          kill PP;
+        }
+      }
+      close(l_fork);
+      return (result);
+    }
+  }
+  return(std(i));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r=32003,(a,b,c,d,e),dp;
+   int n=7;
+   ideal i=
+   a^n-b^n,
+   b^n-c^n,
+   c^n-d^n,
+   d^n-e^n,
+   a^(n-1)*b+b^(n-1)*c+c^(n-1)*d+d^(n-1)*e+e^(n-1)*a;
+   def i1=timeStd(i,1);
+   def i2=timeStd(i,20);
+   listvar();
+}
+
+proc factorH(poly p)
+"USAGE:  factorH(p)  p poly
+RETURN:  factorize(p)
+NOTE:    changes variables to make the last variable the principal
+         one in the multivariate factorization and factorizes then
+         the polynomial
+EXAMPLE: example factorH; shows an example
+"
+{
+   def R=basering;
+   int i,j;
+   int n=1;
+   int d=nrows(coeffs(p,var(1)));
+   for(i=1;i<=nvars(R);i++)
+   {
+      j=nrows(coeffs(p,var(i)));
+      if(d>j)
+      {
+         n=i;
+         d=j;
+      }
+   }
+   ideal ma=maxideal(1);    //die letzte Variable ist die Hauptvariable
+   ma[nvars(R)]=var(n);
+   ma[n]=var(nvars(R));
+   map phi=R,ma;
+   list fac=factorize(phi(p));
+   list re=phi(fac);
+   return(re);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  system("random",992851144);
+  ring r=32003,(x,y,z,w,t),lp;
+  poly p=y2w9+yz7t-yz5w4-z2w4t4-w8t3;
+  factorize(p);  //fast
+  system("random",992851262);
+  //factorize(p);  //slow
+  system("random",992851262);
+  factorH(p);
+}
diff --git a/Singular/LIB/gitfan.lib b/Singular/LIB/gitfan.lib
new file mode 100644
index 0000000..986e542
--- /dev/null
+++ b/Singular/LIB/gitfan.lib
@@ -0,0 +1,577 @@
+///////////////////////////////////////////////////////////////////
+version="version gitfan.lib 4.0.0.0 Jun_2013 ";  // $Id: 1ebd885c6fd0687b5c222aa26ba5debcee9cc94f $
+category="Algebraic Geometry";
+info="
+LIBRARY:  gitfan.lib       Compute GIT-fans.
+
+AUTHORS:  Janko Boehm      boehm at mathematik.uni-kl.de
+@*        Simon Keicher    keicher at mail.mathematik.uni-tuebingen.de
+@*        Yue Ren          ren at mathematik.uni-kl.de
+
+OVERVIEW:
+This library computes GIT-fans, torus orbits and GKZ-fans.
+It uses the package 'gfanlib' by Anders N. Jensen
+and some algorithms have been outsourced to C++ to improve the performance.
+Check https://github.com/skeicher/gitfan_singular for updates.
+
+KEYWORDS: library; gitfan; GIT; geometric invariant theory; quotients
+
+PROCEDURES:
+afaces(ideal);                      Returns a list of intvecs that correspond to all a-faces
+gitCone(ideal,bigintmat,bigintmat); Returns the GIT-cone around the given weight vector w
+gitFan(ideal,bigintmat);            Returns the GIT-fan of the H-action defined by Q on V(a)
+gkzFan(bigintmat);                  Returns the GKZ-fan of the matrix Q
+isAface(ideal,intvec);              Checks whether intvec corresponds to an ideal-face
+orbitCones(ideal,bigintmat);        Returns the list of all projected a-faces
+";
+
+LIB "parallel.lib"; // for parallelWaitAll
+
+////////////////////////////////////////////////////
+proc mod_init()
+{
+  LIB"gfanlib.so";
+}
+
+static proc int2face(int n, int r)
+{
+  int k = r-1;
+  intvec v;
+  int n0 = n;
+
+  while(n0 > 0){
+    while(2^k > n0){
+      k--;
+      //v[size(v)+1] = 0;
+    }
+
+    v = k+1,v;
+    n0 = n0 - 2^k;
+    k--;
+  }
+  v = v[1..size(v)-1];
+  return(v);
+}
+
+/////////////////////////////////
+
+proc isAface(ideal a, intvec gam0)
+"USAGE:  isAface(a,gam0); a: ideal, gam0:intvec
+PURPOSE: Checks whether the face of the positive orthant,
+         that is spanned by all i-th unit vectors,
+         where i ranges amongst the entries of gam0,
+         is an a-face.
+RETURN:  int
+EXAMPLE: example isaface; shows an example
+"
+{
+  poly pz;
+
+  // special case: gam0 is the zero-cone:
+  if (size(gam0) == 1 and gam0[1] == 0){
+    ideal G;
+
+    // is an a-face if and only if RL0(0,...,0) = const
+    // set all entries to 0:
+    int i;
+    for (int k = 1; k <= size(a); k++) {
+      pz = subst(a[k], var(1), 0);
+      for (i = 2; i <= nvars(basering); i++) {
+        pz = subst(pz, var(i), 0);
+      }
+      G = G, pz;
+    }
+
+    G = std(G);
+
+    // monomial inside?:
+    if(1 == G){
+      return(0);
+    }
+
+    return(1);
+  }
+
+
+  // ring is too big: Switch to KK[T_i; e_i\in gam0] instead:
+  string initNewRing = "ring Rgam0 = 0,(";
+
+  for (int i=1; i<size(gam0); i++){
+    initNewRing = initNewRing + string(var(gam0[i])) + ",";
+  }
+
+  initNewRing = initNewRing + string(var(gam0[size(gam0)])) + "),dp;";
+  def R = basering;
+  execute(initNewRing);
+
+  ideal agam0 = imap(R,a);
+
+  poly p = var(1); // first entry of g; p = prod T_i with i element of g
+  for ( i = 2; i <= nvars(basering); i++ ) {
+      p = p * var(i);
+    }
+  // p is now the product over all T_i, with e_i in gam0
+
+  agam0 = agam0, p - 1; // rad-membership
+  ideal G = std(agam0);
+
+  // does G contain 1?, i.e. is G = 1?
+  if(G <> 1) {
+    return(1); // true
+  }
+
+  return(0); // false
+}
+example
+{
+  echo = 2;
+
+  ring R = 0,(T(1..4)),dp;
+  ideal I = T(1)*T(2)-T(4);
+
+  intvec w = 1,4;
+  intvec v = 1,2,4;
+
+  isAface(I,w); // should be 0
+  "-----------";
+  isAface(I,v); // should be 1
+}
+
+////////////////////////////////////////////////////
+
+proc afacesPart(ideal a, int d, int start, int end, int r){
+  intvec gam0;
+  int i;
+  list AF;
+
+  for(i = start; i <= end; i++){
+    if(i < 2^r){
+      gam0 = int2face(i,r);
+
+      // take gam0 only if it has
+      // at least d rays:
+      if(size(gam0) >= d){
+        if (isAface(a,gam0)){
+          AF[size(AF) + 1] = gam0;
+        }
+      }
+    }
+  }
+
+  return(AF);
+}
+
+////////////////////////////////////////////////////
+
+proc afaces(ideal a, list #)
+"USAGE:  afaces(a, b, c); a: ideal, d: int, c: int
+PURPOSE: Returns a list of all a-faces (represented by intvecs).
+         Moreover, it is possible to specify a dimensional bound b,
+         upon which only cones of that dimension and above are returned.
+         Lastly, as the computation is parallizable, one can specify c,
+         the number of cores to be used by the computation.
+RETURN:  a list of intvecs
+EXAMPLE: example afaces; shows an example
+"
+{
+  int d = 1;
+  int ncores = 1;
+
+  if ((size(#) > 0) and (typeof(#[1]) == "int")){
+    d = #[1];
+  }
+
+  if ((size(#) > 1) and (typeof(#[2]) == "int")){
+    ncores = #[2];
+  }
+
+  list AF;
+  intvec gam0;
+  int r = nvars(basering);
+
+  // check if 0 is an a-face:
+  gam0 = 0;
+  if (isAface(a,gam0)){
+      AF[size(AF) + 1] = gam0;
+  }
+
+  // check for other a-faces:
+  // make ncores processes:
+  int step = 2^r div ncores;
+  int i;
+
+  list args;
+  for(int k = 0; k < ncores; k++){
+    args[size(args) + 1] = list(a, d, k * step + 1, (k+1) * step, r);
+  }
+
+  string command = "afacesPart";
+  list out = parallelWaitAll(command, args);
+
+  // do remaining ones:
+  for(i = ncores * step +1; i < 2^r; i++){
+    "another one needed";
+    gam0 = int2face(i,r);
+
+    // take gam0 only if it has
+    // at least d rays:
+    if(size(gam0) >= d){
+      if (isAface(a,gam0)){
+        AF[size(AF) + 1] = gam0;
+      }
+    }
+  }
+
+  // read out afaces of out into AF:
+  for(i = 1; i <= size(out); i++){
+    AF = AF + out[i];
+  }
+
+  return(AF);
+}
+example
+{
+
+  echo = 2;
+  ring R = 0,T(1..3),dp;
+  ideal a = T(1)+T(2)+T(3);
+
+  list F = afaces(a,3,4);
+  print(F);
+  print(size(F));
+
+  // 2nd ex //
+  ring R2 = 0,T(1..3),dp;
+  ideal a2 = T(2)^2*T(3)^2+T(1)*T(3);
+
+  list F2 = afaces(a2,3,4);
+  print(F2);
+  print(size(F2));
+
+  // 3rd ex //
+  ring R3 = 0,T(1..3),dp;
+  ideal a3 = 0;
+
+  list F3 = afaces(a3,3,4);
+  print(F3);
+  print(size(F3));
+
+  // bigger example //
+  ring R = 0,T(1..15),dp;
+  ideal a =
+    T(1)*T(10)-T(2)*T(7)+T(3)*T(6),
+    T(1)*T(11)-T(2)*T(8)+T(4)*T(6),
+    T(1)*T(12)-T(2)*T(9)+T(5)*T(6),
+    T(1)*T(13)-T(3)*T(8)+T(4)*T(7),
+    T(1)*T(14)-T(3)*T(9)+T(5)*T(7),
+    T(1)*T(15)-T(4)*T(9)+T(5)*T(8),
+    T(2)*T(13)-T(3)*T(11)+T(4)*T(10),
+    T(2)*T(14)-T(3)*T(12)+T(5)*T(10),
+    T(2)*T(15)-T(4)*T(12)+T(5)*T(11),
+    T(3)*T(15)-T(4)*T(14)+T(5)*T(13),
+    T(6)*T(13)-T(7)*T(11)+T(8)*T(10),
+    T(6)*T(14)-T(7)*T(12)+T(9)*T(10),
+    T(6)*T(15)-T(8)*T(12)+T(9)*T(11),
+    T(7)*T(15)-T(8)*T(14)+T(9)*T(13),
+    T(10)*T(15)-T(11)*T(14)+T(12)*T(13);
+
+  int t = timer;
+  list F4 = afaces(a,0,2);
+  print(size(F4));
+  timer - t;
+
+  int t = timer;
+  list F4 = afaces(a,0);
+  print(size(F4));
+  timer - t;
+
+}
+
+///////////////////////////////////////
+
+proc orbitCones(ideal a, bigintmat Q, list #)
+"USAGE:  orbitCones(a, Q, b, c); a: ideal, Q: bigintmat, b: int, c: int
+PURPOSE: Returns a list consisting of all cones Q(gam0) where gam0 is an a-face.
+         Moreover, it is possible to specify a dimensional bound b,
+         upon which only cones of that dimension and above are returned.
+         Lastly, as the computation is parallizable, one can specify c,
+         the number of cores to be used by the computation.
+RETURN:  a list of cones
+EXAMPLE: example orbitCones; shows an example
+"
+{
+  list AF;
+
+  if((size(#) > 1) and (typeof(#[2]) == "int")){
+    AF = afaces(a, nrows(Q), #[2]);
+  } else
+  {
+    AF = afaces(a, nrows(Q));
+  }
+
+  int dimensionBound = 0;
+  if((size(#) > 0) and (typeof(#[1]) == "int")){
+    dimensionBound = #[1];
+  }
+
+  list OC;
+  intvec gam0;
+  int j;
+
+  for(int i = 1; i <= size(AF); i++){
+    gam0 = AF[i];
+
+    if(gam0 == 0){
+      bigintmat M[1][nrows(Q)];
+    } else {
+      bigintmat M[size(gam0)][nrows(Q)];
+      for (j = 1; j <= size(gam0); j++){
+        M[j,1..ncols(M)] = Q[1..nrows(Q),gam0[j]];
+      }
+    }
+    cone c = coneViaPoints(M);
+
+    if((dimension(c) >= dimensionBound) and (!(listContainsCone(OC, c)))){
+      OC[size(OC)+1] = c;
+    }
+
+    kill M, c;
+  }
+
+  return(OC);
+}
+example
+{
+  echo=2;
+  intmat Q[3][4] =
+    1,0,1,0,
+    0,1,0,1,
+    0,0,1,1;
+
+  ring R = 0,T(1..4),dp;
+  ideal a = 0;
+
+  orbitCones(a, Q);
+}
+
+///////////////////////////////////////
+
+proc gitCone(ideal a, bigintmat Q, bigintmat w)
+"USAGE: gitCone(a, Q, w); a: ideal, Q:bigintmat, w:bigintmat
+PURPOSE: Returns the GIT-cone lambda(w), i.e. the intersection of all
+orbit cones containing the vector w.
+NOTE: call this only if you are interested in a single GIT-cone.
+RETURN: a cone.
+EXAMPLE: example gitCone; shows an example
+"
+{
+  list OC =  orbitCones(a, Q);
+  cone lambda = nrows(Q);
+
+  for(int i = 1; i <= size(OC); i++){
+    cone c = OC[i];
+
+    if(containsInSupport(c, w)){
+      lambda = convexIntersection(lambda, c);
+    }
+
+    kill c;
+  }
+
+  return(lambda);
+}
+example
+{
+  echo=2;
+  intmat Q[3][4] =
+    1,0,1,0,
+    0,1,0,1,
+    0,0,1,1;
+
+  ring R = 0,T(1..4),dp;
+  ideal a = 0;
+
+  bigintmat w[1][3] = 3,3,1;
+  cone lambda = gitCone(a, Q, w);
+  rays(lambda);
+
+  bigintmat w2[1][3] = 1,1,1;
+  cone lambda2 = gitCone(a, Q, w2);
+  rays(lambda2);
+}
+
+/////////////////////////////////////
+
+proc gitFan(ideal a, bigintmat Q, list #)
+"USAGE: gitFan(a, Q); a: ideal, Q:bigintmat
+PURPOSE: Returns the GIT-fan of the H-action defined by Q on V(a).
+An optional third parameter of type 'int' is interpreted as the
+number of CPU-cores you would like to use.
+Note that 'system("--cpus");' returns the number of cpu available
+in your system.
+RETURN: a fan.
+EXAMPLE: example gitFan; shows an example
+"
+{
+  list OC = orbitCones(a, Q, #);
+
+  fan f = refineCones(OC, Q);
+  return(f);
+}
+example
+{
+  echo=2;
+  intmat Q[3][4] =
+    1,0,1,0,
+    0,1,0,1,
+    0,0,1,1;
+
+  ring R = 0,T(1..4),dp;
+  ideal a = 0;
+
+  gitFan(a, Q);
+
+  // 2nd example //
+  kill Q;
+  intmat Q[3][6] =
+    1,1,0,0,-1,-1,
+    0,1,1,-1,-1,0,
+    1,1,1,1,1,1;
+
+  ring R = 0,T(1..6),dp;
+  ideal a = T(1)*T(6) + T(2)*T(5) + T(3)*T(4);
+
+  int t = rtimer;
+  fan F = gitFan(a, Q);
+  t = rtimer - t;
+
+  int tt = rtimer;
+  fan F = gitFan(a, Q, 4);
+  tt = rtimer - tt;
+
+  t;
+  tt;
+  "--------";
+  kill R, Q, t, tt;
+  // next example //
+  ring R = 0,T(1..10),dp;
+  ideal a = T(5)*T(10)-T(6)*T(9)+T(7)*T(8),
+    T(1)*T(9)-T(2)*T(7)+T(4)*T(5),
+    T(1)*T(8)-T(2)*T(6)+T(3)*T(5),
+    T(1)*T(10)-T(3)*T(7)+T(4)*T(6),
+    T(2)*T(10)-T(3)*T(9)+T(4)*T(8);
+
+  bigintmat Q[4][10] =
+    1,0,0,0,1,1,1,0,0,0,
+    0,1,0,0,1,0,0,1,1,0,
+    0,0,1,0,0,1,0,1,0,1,
+    0,0,0,1,0,0,1,0,1,1;
+
+  int t = rtimer;
+  fan F = gitFan(a, Q);
+  t = rtimer - t;
+
+  int tt = rtimer;
+  fan F = gitFan(a, Q, 4);
+  tt = rtimer - tt;
+
+  t;
+  tt;
+
+  "--------";
+  kill R, Q, t, tt;
+  // next example //
+  ring R = 0,T(1..15),dp;
+  ideal a =
+    T(1)*T(10)-T(2)*T(7)+T(3)*T(6),
+    T(1)*T(11)-T(2)*T(8)+T(4)*T(6),
+    T(1)*T(12)-T(2)*T(9)+T(5)*T(6),
+    T(1)*T(13)-T(3)*T(8)+T(4)*T(7),
+    T(1)*T(14)-T(3)*T(9)+T(5)*T(7),
+    T(1)*T(15)-T(4)*T(9)+T(5)*T(8),
+    T(2)*T(13)-T(3)*T(11)+T(4)*T(10),
+    T(2)*T(14)-T(3)*T(12)+T(5)*T(10);
+
+  bigintmat Q[5][15] =
+    1,0,0,0,0,1,1,1,1,0,0,0,0,0,0,
+    0,1,0,0,0,1,0,0,0,1,1,1,0,0,0,
+    0,0,1,0,0,0,1,0,0,1,0,0,1,1,0,
+    0,0,0,1,0,0,0,1,0,0,1,0,1,0,1,
+    0,0,0,0,1,0,0,0,1,0,0,1,0,1,1;
+
+  int t = rtimer;
+  fan F = gitFan(a, Q);
+  t = rtimer - t;
+
+  int tt = rtimer;
+  fan F = gitFan(a, Q, 4);
+  tt = rtimer - tt;
+
+  t;
+  tt;
+
+}
+
+/////////////////////////////////////
+// Computes all simplicial orbit cones
+// w.r.t. the 0-ideal:
+
+static proc simplicialToricOrbitCones(bigintmat Q){
+  intvec gam0;
+  list OC;
+  cone c;
+  int r = ncols(Q);
+  int j;
+
+  for(int i = 1; i < 2^r; i++ ){
+    gam0 = int2face(i,r);
+
+    // each simplicial cone is generated by
+    // exactly nrows(Q) many columns of Q:
+    if(size(gam0) == nrows(Q)){
+      bigintmat M[size(gam0)][nrows(Q)];
+
+      for(j = 1; j <= size(gam0); j++){
+        M[j,1..ncols(M)] = Q[1..nrows(Q),gam0[j]];
+      }
+
+      c = coneViaPoints(M);
+
+      if((dimension(c) == nrows(Q)) and (!(listContainsCone(OC, c)))){
+        OC[size(OC)+1] = c;
+      }
+
+      kill M;
+    }
+  }
+
+  return(OC);
+}
+
+/////////////////////////////////////
+
+proc gkzFan(bigintmat Q)
+"USAGE: gkzFan(Q); a: ideal, Q:bigintmat
+PURPOSE: Returns the GKZ-fan of the matrix Q.
+RETURN: a fan.
+EXAMPLE: example gkzFan; shows an example
+"
+{
+  // only difference to gitFan:
+  // it suffices to consider all faces
+  // that are simplicial:
+  list OC = simplicialToricOrbitCones(Q);
+
+  fan f = refineCones(OC, Q);
+  return(f);
+}
+example
+{
+  echo=2;
+  intmat Q[3][4] =
+    1,0,1,0,
+    0,1,0,1,
+    0,0,1,1;
+
+  gkzFan(Q);
+}
diff --git a/Singular/LIB/gkdim.lib b/Singular/LIB/gkdim.lib
new file mode 100644
index 0000000..72381e7
--- /dev/null
+++ b/Singular/LIB/gkdim.lib
@@ -0,0 +1,99 @@
+//////////////////////////////////////////////////////////////////////////////
+version="version gkdim.lib 4.0.0.0 Jun_2013 "; // $Id: 9bd3587a6b567e4bb5339de91ac3afe94d3aeb31 $
+category="Noncommutative";
+info="
+LIBRARY: gkdim.lib     Procedures for calculating the Gelfand-Kirillov dimension
+AUTHORS: Lobillo, F.J.,     jlobillo at ugr.es
+@*         Rabelo, C.,        crabelo at ugr.es
+
+Support: 'Metodos algebraicos y efectivos en grupos cuanticos', BFM2001-3141, MCYT, Jose Gomez-Torrecillas (Main researcher).
+
+NOTE: The built-in command @code{dim}, executed for a module in @plural, computes the Gelfand-Kirillov dimension.
+
+PROCEDURES:
+  GKdim(M);        Gelfand-Kirillov dimension computation of the factor-module, whose presentation is given by the matrix M.
+";
+
+///////////////////////////////////////////////////////////////////////////////////
+static proc idGKdim(ideal I)
+"USAGE:   idGKdim(I), I is a left ideal
+RETURN:  int, the Gelfand-Kirillov dimension of the R/I
+NOTE: uses the dim procedure, if the factor-module is zero, -1 is returned
+"
+{
+  if (attrib(I,"isSB")<>1)
+  {
+    I=std(I);
+  }
+
+  int d    = dim(I);
+  //  if (d==-1) {d++;} // The GK-dimension of a finite dimensional module is zero
+  // levandov: but for consistency, GKdim(std(1)) == -1,
+  //           mimicking the behaviour of dim() procedure.
+  return (d);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+proc GKdim(list L)
+"USAGE:   GKdim(L);   L is a left ideal/module/matrix
+RETURN:  int
+PURPOSE: compute the Gelfand-Kirillov dimension of the factor-module, whose presentation is given by L, e.g. R^r/L
+NOTE:  if the factor-module is zero, -1 is returned
+EXAMPLE: example GKdim; shows examples
+"
+{
+  def M = L[1];
+  int d = -1;
+  if (typeof(M)=="ideal")
+  {
+    d=idGKdim(M);
+  }
+  else
+  {
+    if (typeof(M)=="matrix")
+    {
+      module N = module(M);
+      kill M;
+      module M = N;
+    }
+    if (typeof(M)=="module")
+    {
+      if (attrib(M,"isSB")<>1)
+      {
+        M=std(M);
+      }
+      d=dim(M);
+    }
+    else
+    {
+      ERROR("The input must be an ideal, a module or a matrix.");
+    }
+  }
+  return (d);
+}
+example
+{
+  "EXAMPLE:";echo=2;
+  ring R = 0,(x,y,z),Dp;
+  matrix C[3][3]=0,1,1,0,0,-1,0,0,0;
+  matrix D[3][3]=0,0,0,0,0,x;
+  def r = nc_algebra(C,D); setring r;
+  r;
+  ideal I=x;
+  GKdim(I);
+  ideal J=x2,y;
+  GKdim(J);
+  module M=[x2,y,1],[x,y2,0];
+  GKdim(M);
+  ideal A = x,y,z;
+  GKdim(A);
+  ideal B = 1;
+  GKdim(B);
+  GKdim(ideal(0)) == nvars(basering);  // should be true, i.e., evaluated to 1
+}
+///////////////////////////////////////////////////////////////////////////////
+proc gkdim(list L)
+{
+  return(GKdim(L));
+}
+///////////////////////////////////////////////////////////////////////////////
diff --git a/Singular/LIB/gmspoly.lib b/Singular/LIB/gmspoly.lib
new file mode 100644
index 0000000..9692897
--- /dev/null
+++ b/Singular/LIB/gmspoly.lib
@@ -0,0 +1,590 @@
+//////////////////////////////////////////////////////////////////////////////
+version="version gmspoly.lib 4.0.0.0 Jun_2013 "; // $Id: 3c735c6f40c59642aa84612e0da4c2cd7b7e4176 $
+category="Singularities";
+
+info="
+LIBRARY:  gmspoly.lib  Gauss-Manin System of Tame Polynomials
+
+AUTHOR:   Mathias Schulze, mschulze at mathematik.uni-kl.de
+
+OVERVIEW:
+A library for computing the Gauss-Manin system of a cohomologically tame
+polynomial f. Schulze's algorithm [Sch05], based on Sabbah's theory [Sab98],
+is used to compute a good basis of (the Brieskorn lattice of) the Gauss-Manin system and the differential operation of f in terms of this basis.
+In addition, there is a test for tameness in the sense of Broughton.
+Tame polynomials can be considered as an affine algebraic analogue of local
+analytic isolated hypersurface singularities. They have only finitely many
+citical points, and those at infinity do not give rise to atypical values
+in a sense depending on the precise notion of tameness considered. Well-known
+notions of tameness like tameness, M-tameness, Malgrange-tameness, and
+cohomological tameness, and their relations, are reviewed in [Sab98,8].
+For ordinary tameness, see Broughton [Bro88,3].
+Sabbah [Sab98] showed that the Gauss-Manin system, the D-module direct image
+of the structure sheaf, of a cohomologically tame polynomial carries a
+similar structure as in the isolated singularity case, coming from a Mixed
+Hodge structure on the cohomology of the Milnor (typical) fibre (see
+gmssing.lib). The data computed by this library encodes the differential structure of the Gauss-Manin system, and the Mixed Hodge structure of the Milnor fibre over the complex numbers. As a consequence, it yields the Hodge numbers, spectral pairs, and monodromy at infinity.
+
+REFERENCES:
+[Bro88] S. Broughton: Milnor numbers and the topology of polynomial
+        hypersurfaces. Inv. Math. 92 (1988) 217-241.
+[Sab98] C. Sabbah: Hypergeometric periods for a tame polynomial.
+        arXiv.org math.AG/9805077.
+[Sch05] M. Schulze: Good bases for tame polynomials.
+        J. Symb. Comp. 39,1 (2005), 103-126.
+
+PROCEDURES:
+  isTame(f);     test whether the polynomial f is tame
+  goodBasis(f);  good basis of Brieskorn lattice of cohom. tame polynomial f
+
+SEE ALSO: gmssing_lib
+
+KEYWORDS: tame polynomial; Gauss-Manin system; Brieskorn lattice;
+          mixed Hodge structure; V-filtration; weight filtration;
+          monodromy; spectrum; spectral pairs; good basis
+";
+
+LIB "linalg.lib";
+LIB "ring.lib";
+
+///////////////////////////////////////////////////////////////////////////////
+
+static proc mindegree(matrix A)
+{
+  int d=0;
+
+  while(A/var(1)^(d+1)*var(1)^(d+1)==A)
+  {
+    d++;
+  }
+
+  return(d);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+static proc maxdegree(matrix A)
+{
+  int d=0;
+  matrix N[nrows(A)][ncols(A)];
+
+  while(A/var(1)^(d+1)!=N)
+  {
+    d++;
+  }
+
+  return(d);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc isTame(poly f)
+"USAGE:    isTame(f); poly f
+ASSUME:   basering has no variables named w(1),w(2),...
+RETURN:
+ at format
+int k=
+  1;  if f is tame in the sense of Broughton [Bro88,3]
+  0;  if f is not tame
+ at end format
+REMARKS:  procedure implements Proposition 3.1 in [Bro88]
+KEYWORDS: tame polynomial
+EXAMPLE:  example isTame; shows examples
+"
+{
+  int d=vdim(std(jacob(f)));
+  def @X=basering;
+  int n=nvars(@X);
+  ring ext_ring=0,(w(1..n)),dp;
+  setring @X;
+  def @WX=changechar(ringlist(ext_ring));
+  setring @WX;
+  kill ext_ring;
+  ideal J=jacob(imap(@X,f));
+  int i;
+  for(i=1;i<=n;i++)
+  {
+    J[i]=J[i]+w(i);
+  }
+  int D=vdim(std(J));
+
+  setring(@X);
+  kill @WX;
+
+  return(d>0&&d==D);
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring R=0,(x,y),dp;
+  isTame(x2y+x);
+  isTame(x3+y3+xy);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+static proc chart(matrix A)
+{
+  A=ideal(homog(transpose(ideal(A)),var(2)));
+  def r=basering;
+  map h=r,1,var(1);
+  return(h(A));
+}
+///////////////////////////////////////////////////////////////////////////////
+
+static proc pidbasis(module M0,module M)
+{
+  int m=nrows(M);
+  int n=ncols(M);
+
+  module L,N;
+  module T=freemodule(m);
+  while(matrix(L)!=matrix(M))
+  {
+    L=M;
+
+    M=T,M;
+    N=transpose(std(transpose(M)));
+    T=N[1..m];
+    M=N[m+1..ncols(N)];
+
+    M=freemodule(n),transpose(M);
+    N=std(transpose(M));
+    N=transpose(simplify(N,1));
+    M=N[n+1..ncols(N)];
+    M=transpose(M);
+  }
+
+  if(maxdegree(M)>0)
+  {
+    print("   ? module not free");
+    return(module());
+  }
+
+  attrib(M,"isSB",1);
+  N=lift(T,simplify(reduce(M0,M),2));
+
+  return(N);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+static proc vfiltmat(matrix B,int d)
+{
+  int mu=ncols(B);
+
+  module V=freemodule(mu);
+  module V0=var(1)^(d-1)*freemodule(mu);
+  attrib(V0,"isSB",1);
+  module V1=B;
+  option(redSB);
+  while(size(reduce(V1,V0))>0)
+  {
+    V=std(V0+V1);
+    V0=var(1)^(d-1)*V;
+    attrib(V0,"isSB",1);
+    V1=B*matrix(V1)-var(1)^d*diff(matrix(V1),var(1));
+  }
+  option("noredSB");
+
+  B=lift(V0,B*matrix(V)-var(1)^d*diff(matrix(V),var(1)));
+  list l=eigenvals(B);
+  def e0,s0=l[1..2];
+
+  module U;
+  int i,j,i0,j0,i1,j1,k;
+  for(k=int(e0[ncols(e0)]-e0[1]);k>=1;k--)
+  {
+    U=0;
+    for(i=1;i<=ncols(e0);i++)
+    {
+      U=U+syz(power(jet(B,0)-e0[i],s0[i]));
+    }
+    B=lift(U,B*U);
+    V=V*U;
+
+    for(i0,i=1,1;i0<=ncols(e0);i0++)
+    {
+      for(i1=1;i1<=s0[i0];i1,i=i1+1,i+1)
+      {
+        for(j0,j=1,1;j0<=ncols(e0);j0++)
+        {
+          for(j1=1;j1<=s0[j0];j1,j=j1+1,j+1)
+          {
+            if(leadcoef(e0[i0]-e0[1])>=1&&leadcoef(e0[j0]-e0[1])<1)
+            {
+              B[i,j]=B[i,j]/var(1);
+            }
+            if(leadcoef(e0[i0]-e0[1])<1&&leadcoef(e0[j0]-e0[1])>=1)
+            {
+              B[i,j]=B[i,j]*var(1);
+            }
+          }
+        }
+      }
+    }
+
+    for(i0,i=1,1;i0<=ncols(e0);i0++)
+    {
+      if(leadcoef(e0[i0]-e0[1])>=1)
+      {
+        for(i1=1;i1<=s0[i0];i1,i=i1+1,i+1)
+        {
+          B[i,i]=B[i,i]-1;
+          V[i]=V[i]*var(1);
+        }
+        e0[i0]=e0[i0]-1;
+      }
+      else
+      {
+        i=i+s0[i0];
+      }
+    }
+
+    l=spnf(list(e0,s0));
+    e0,s0=l[1..2];
+  }
+
+  U=0;
+  for(i=1;i<=ncols(e0);i++)
+  {
+    U=U+syz(power(jet(B,0)-e0[i],s0[i]));
+  }
+  B=lift(U,B*U);
+  V=V*U;
+
+  d=mindegree(V);
+  V=V/var(1)^d;
+  B=B+d*matrix(freemodule(mu));
+  for(i=ncols(e0);i>=1;i--)
+  {
+    e0[i]=e0[i]+d;
+  }
+
+  return(e0,s0,V,B);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+static proc spec(ideal e0,intvec s0,module V,matrix B)
+{
+  int mu=ncols(B);
+
+  int i,j,k;
+
+  int d=maxdegree(V);
+  int d0=d;
+  V=chart(V);
+  module U=std(V);
+  while(size(reduce(var(1)^d*freemodule(mu),U))>0)
+  {
+    d++;
+  }
+  if(d>d0)
+  {
+    k=d-d0;
+    B=B-k*freemodule(mu);
+    for(i=1;i<=ncols(e0);i++)
+    {
+      e0[i]=e0[i]-k;
+    }
+  }
+  module G=lift(V,var(1)^d*freemodule(mu));
+  G=std(G);
+  G=simplify(G,1);
+
+  ideal e;
+  intvec s;
+  e[mu]=0;
+  for(j,k=1,1;j<=ncols(e0);j++)
+  {
+    for(i=s0[j];i>=1;i,k=i-1,k+1)
+    {
+      e[k]=e0[j];
+      s[k]=j;
+    }
+  }
+
+  ideal a;
+  a[mu]=0;
+  for(i=1;i<=mu;i++)
+  {
+    a[i]=leadcoef(e[leadexp(G[i])[nvars(basering)+1]])+leadexp(G[i])[1];
+  }
+
+  return(a,e0,e,s,V,B,G);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+static proc fsplit(ideal e0,ideal e,intvec s,module V,matrix B,module G)
+{
+  int mu=ncols(e);
+
+  int i,j,k;
+
+  number n,n0;
+  vector v,v0;
+  list F;
+  for(i=ncols(e0);i>=1;i--)
+  {
+    F[i]=module(matrix(0,mu,1));
+  }
+  for(i=mu;i>=1;i--)
+  {
+    v=G[i];
+    v0=lead(v);
+    n0=leadcoef(e[leadexp(v0)[nvars(basering)+1]])+leadexp(v0)[1];
+    v=v-lead(v);
+    while(v!=0)
+    {
+      n=leadcoef(e[leadexp(v)[nvars(basering)+1]])+leadexp(v)[1];
+      if(n==n0)
+      {
+        v0=v0+lead(v);
+        v=v-lead(v);
+      }
+      else
+      {
+        v=0;
+      }
+    }
+    j=s[leadexp(v0)[nvars(basering)+1]];
+    F[j]=F[j]+v0;
+  }
+
+  matrix B0=jet(B,0);
+  module U,U0,U1,U2;
+  matrix N;
+  for(i=size(F);i>=1;i--)
+  {
+    N=B0-e0[i];
+    U0=0;
+    while(size(F[i])>0)
+    {
+      k=0;
+      U1=jet(F[i],0);
+      while(size(U1)>0)
+      {
+        for(j=ncols(U1);j>=1;j--)
+        {
+          if(size(reduce(U1[j],std(U0)))>0)
+          {
+            U0=U1[j]+U0;
+          }
+        }
+        U1=N*U1;
+        k++;
+      }
+      F[i]=module(F[i]/var(1));
+    }
+    U=U0+U;
+  }
+
+  V=V*U;
+  G=lift(U,G);
+  B=lift(U,B*U);
+
+  return(e,V,B,G);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+static proc glift(ideal e,module V,matrix B,module G)
+{
+  int mu=ncols(e);
+
+  int d=maxdegree(B);
+  B=chart(B);
+  G=std(G);
+  G=simplify(G,1);
+
+  int i,j,k;
+
+  ideal v;
+  for(i=mu;i>=1;i--)
+  {
+    v[i]=e[leadexp(G[i])[nvars(basering)+1]]+leadexp(G[i])[1];
+  }
+
+  number c;
+  matrix g[mu][1];
+  matrix m[mu][1];
+  matrix a[mu][1];
+  matrix A[mu][mu];
+  module M=var(1)^d*G;
+  module N=var(1)*B*matrix(G)+var(1)^(d+2)*diff(matrix(G),var(1));
+  while(size(N)>0)
+  {
+    j=mu;
+    for(k=mu-1;k>=1;k--)
+    {
+      if(N[k]>N[j])
+      {
+        j=k;
+      }
+    }
+
+    i=mu;
+    while(leadexp(M[i])[nvars(basering)+1]!=leadexp(N[j])[nvars(basering)+1])
+    {
+      i--;
+    }
+
+    k=leadexp(N[j])[1]-leadexp(M[i])[1];
+    if(k==0||i==j)
+    {
+      c=leadcoef(N[j])/leadcoef(M[i]);
+      A[i,j]=A[i,j]+c*var(1)^k;
+      N[j]=N[j]-c*var(1)^k*M[i];
+    }
+    else
+    {
+      c=leadcoef(N[j])/leadcoef(M[i])/(1-k-leadcoef(v[i])+leadcoef(v[j]));
+      G[j]=G[j]+c*var(1)^(k-1)*G[i];
+      M[j]=M[j]+c*var(1)^(k-1)*M[i];
+      g=c*var(1)^(k-1)*G[i];
+      N[j]=N[j]+(var(1)*B*g+var(1)^(d+2)*diff(g,var(1)))[1];
+      m=M[i];
+      a=transpose(A)[j];
+      N=N-c*var(1)^(k-1)*m*transpose(a);
+    }
+  }
+
+  G=V*G;
+  G=G/var(1)^mindegree(G);
+
+  return(G,A);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc goodBasis(poly f)
+"USAGE:    goodBasis(f); poly f
+ASSUME:   f is cohomologically tame in the sense of Sabbah [Sab98,8]
+RETURN:
+ at format
+ring R;  basering with new variable s
+  ideal b;  [matrix(b)] is a good basis of the Brieskorn lattice
+  matrix A;  A(s)=A0+s*A1 and t[matrix(b)]=[matrix(b)](A(s)+s^2*(d/ds))
+ at end format
+REMARKS:  procedure implements Algorithm 6 in [Sch05]
+KEYWORDS: tame polynomial; Gauss-Manin system; Brieskorn lattice;
+          mixed Hodge structure; V-filtration; weight filtration;
+          monodromy; spectrum; spectral pairs; good basis
+SEE ALSO: gmssing_lib
+EXAMPLE:  example goodBasis; shows examples
+"
+{
+  def @X=basering;
+  int n=nvars(@X);
+  ideal J=jacob(f);
+
+  if(vdim(std(J))<=0)
+  {
+    ERROR("input is not cohomologically tame");
+  }
+
+  int i,j,k,l;
+
+  ideal X=maxideal(1);
+  string c="ring @XS=0,(s,"+varstr(@X)+"),(C,dp(1),dp(n));";
+  execute(c);
+  poly f=imap(@X,f);
+  ideal J=imap(@X,J);
+  ideal JS=std(J+var(1));
+  ideal b0=kbase(JS);
+  int mu=ncols(b0);
+  ideal X=imap(@X,X);
+
+  ideal b;
+  matrix A;
+  module B,B0;
+  ideal K,L,M=1,J,1;
+  ideal K0,L0,M0=X,X,X;
+  module K1,L1,K2,L2;
+  module LL1;
+  for(i=1;i<=deg(f)-1;i++)
+  {
+    M=M,M0;
+    M0=M0*X;
+  }
+
+  ring @S=0,(s,t),(dp,C);
+  number a0;
+  ideal a;
+  int d;
+  ideal e,e0;
+  intvec s,s0;
+  matrix A,B;
+  module V,G;
+
+  while(2*a0!=mu*n)
+  {
+    setring(@XS);
+
+    B=0;
+    while(size(B)<mu||size(B0)<mu||maxdegree(b)+deg(f)>k)
+    {
+      k++;
+      K=K,K0;
+      K0=K0*X;
+
+      B=0;
+      while(size(B)==0||size(B)>mu)
+      {
+        l++;
+        for(i=1;i<=size(L0);i++)
+        {
+          for(j=1;j<=n;j++)
+          {
+            L=L,J[j]*L0[i]-var(1)*diff(L0[i],var(j+1));
+          }
+        }
+        L0=L0*X;
+        M=M,M0;
+        M0=M0*X;
+
+        K1=coeffs(K,K,product(X));
+        L1=std(coeffs(L,M,product(X)));
+        LL1=jet(lead(L1),0);
+        attrib(LL1,"isSB",1);
+        K2=simplify(reduce(K1,LL1),2);
+        L2=intersect(K2,L1);
+
+        B=pidbasis(K2,L2);
+      }
+
+      B0=std(coeffs(reduce(matrix(K,nrows(K),nrows(B))*B,JS),b0));
+      b=matrix(K,nrows(K),nrows(B))*B;
+    }
+
+    A=lift(B,reduce(coeffs(f*b+var(1)^2*diff(b,var(1)),M,product(X)),L1));
+    d=maxdegree(A);
+    A=chart(A);
+
+    setring(@S);
+
+    e0,s0,V,B=vfiltmat(imap(@XS,A),d);
+    a,e0,e,s,V,B,G=spec(e0,s0,V,B);
+
+    a0=leadcoef(a[1]);
+    for(i=2;i<=mu;i++)
+    {
+      a0=a0+leadcoef(a[i]);
+    }
+  }
+
+  G,A=glift(fsplit(e0,e,s,V,B,G));
+
+  setring(@XS);
+  b=matrix(b)*imap(@S,G);
+  A=imap(@S,A);
+  export(b,A);
+  kill @S;
+
+  setring(@X);
+  return(@XS);
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring R=0,(x,y,z),dp;
+  poly f=x+y+z+x2y2z2;
+  def Rs=goodBasis(f);
+  setring(Rs);
+  b;
+  print(jet(A,0));
+  print(jet(A/var(1),0));
+}
+///////////////////////////////////////////////////////////////////////////////
diff --git a/Singular/LIB/gmssing.lib b/Singular/LIB/gmssing.lib
new file mode 100644
index 0000000..437163a
--- /dev/null
+++ b/Singular/LIB/gmssing.lib
@@ -0,0 +1,1741 @@
+//////////////////////////////////////////////////////////////////////////////
+version="version gmssing.lib 4.0.0.0 Jun_2013 "; // $Id: 06bf8ee546110ab7a9de3bcd1d5126c08805c862 $
+category="Singularities";
+
+info="
+LIBRARY: gmssing.lib  Gauss-Manin System of Isolated Singularities
+
+AUTHOR:  Mathias Schulze, mschulze at mathematik.uni-kl.de
+
+OVERVIEW:
+A library for computing invariants related to the Gauss-Manin system of an
+isolated hypersurface singularity.
+
+REFERENCES:
+[Sch01] M. Schulze: Algorithms for the Gauss-Manin connection. J. Symb. Comp.
+        32,5 (2001), 549-564.
+[Sch02] M. Schulze: The differential structure of the Brieskorn lattice.
+        In: A.M. Cohen et al.: Mathematical Software - ICMS 2002.
+        World Scientific (2002).
+[Sch03] M. Schulze: Monodromy of Hypersurface Singularities.
+        Acta Appl. Math. 75 (2003), 3-13.
+[Sch04] M. Schulze: A normal form algorithm for the Brieskorn lattice.
+        J. Symb. Comp. 38,4 (2004), 1207-1225.
+
+PROCEDURES:
+ gmsring(t,s);              Gauss-Manin system of t with variable s
+ gmsnf(p,K);                Gauss-Manin normal form of p
+ gmscoeffs(p,K);            Gauss-Manin basis representation of p
+ bernstein(t);              Bernstein-Sato polynomial of t
+ monodromy(t);              Jordan data of complex monodromy of t
+ spectrum(t);               singularity spectrum of t
+ sppairs(t);                spectral pairs of t
+ vfilt(t);                  V-filtration of t on Brieskorn lattice
+ vwfilt(t);                 weighted V-filtration of t on Brieskorn lattice
+ tmatrix(t);                matrix of t w.r.t. good basis of Brieskorn lattice
+ endvfilt(V);               endomorphism V-filtration on Jacobian algebra
+ sppnf(a,w[,m]);            spectral pairs normal form of (a,w[,m])
+ sppprint(spp);             print spectral pairs spp
+ spadd(sp1,sp2);            sum of spectra sp1 and sp2
+ spsub(sp1,sp2);            difference of spectra sp1 and sp2
+ spmul(sp0,k);              linear combination of spectra sp
+ spissemicont(sp[,opt]);    semicontinuity test of spectrum sp
+ spsemicont(sp0,sp[,opt]);  semicontinuous combinations of spectra sp0 in sp
+ spmilnor(sp);              Milnor number of spectrum sp
+ spgeomgenus(sp);           geometrical genus of spectrum sp
+ spgamma(sp);               gamma invariant of spectrum sp
+
+SEE ALSO: mondromy_lib, spectrum_lib, gmspoly_lib, dmod_lib
+
+KEYWORDS: singularities; Gauss-Manin system; Brieskorn lattice;
+          mixed Hodge structure; V-filtration; weight filtration;
+          Bernstein-Sato polynomial; monodromy; spectrum; spectral pairs;
+          good basis
+";
+
+LIB "linalg.lib";
+
+///////////////////////////////////////////////////////////////////////////////
+
+static proc stdtrans(ideal I)
+{
+  def @R=basering;
+
+  string os=ordstr(@R);
+  int j=find(os,",C");
+  if(j==0)
+  {
+    j=find(os,"C,");
+  }
+  if(j==0)
+  {
+    j=find(os,",c");
+  }
+  if(j==0)
+  {
+    j=find(os,"c,");
+  }
+  if(j>0)
+  {
+    os[j..j+1]="  ";
+  }
+
+  execute("ring @S="+charstr(@R)+",(gmspoly,"+varstr(@R)+"),(c,dp,"+os+");");
+
+  ideal I=homog(imap(@R,I),gmspoly);
+  module M=transpose(transpose(I)+freemodule(ncols(I)));
+  M=std(M);
+
+  setring(@R);
+  execute("map h=@S,1,"+varstr(@R)+";");
+  module M=h(M);
+
+  for(int i=ncols(M);i>=1;i--)
+  {
+    for(j=ncols(M);j>=1;j--)
+    {
+      if(M[i][1]==0)
+      {
+        M[i]=0;
+      }
+      if(i!=j&&M[j][1]!=0)
+      {
+        if(lead(M[i][1])/lead(M[j][1])!=0)
+        {
+          M[i]=0;
+        }
+      }
+    }
+  }
+
+  M=transpose(simplify(M,2));
+  I=M[1];
+  attrib(I,"isSB",1);
+  M=M[2..ncols(M)];
+  module U=transpose(M);
+
+  return(list(I,U));
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc gmsring(poly t,string s)
+"USAGE:    gmsring(t,s); poly t, string s
+ASSUME:   characteristic 0; local degree ordering;
+          isolated critical point 0 of t
+RETURN:
+ at format
+ring G;  Gauss-Manin system of t with variable s
+  poly gmspoly=t;
+  ideal gmsjacob;  Jacobian ideal of t
+  ideal gmsstd;  standard basis of Jacobian ideal
+  matrix gmsmatrix;  matrix(gmsjacob)*gmsmatrix==matrix(gmsstd)
+  ideal gmsbasis;  monomial vector space basis of Jacobian algebra
+  int Gmssing::gmsmaxdeg;  maximal weight of variables
+ at end format
+NOTE:     gmsbasis is a C[[s]]-basis of H'' and [t,s]=s^2
+KEYWORDS: singularities; Gauss-Manin system; Brieskorn lattice
+EXAMPLE:  example gmsring; shows examples
+"
+{
+  def @R=basering;
+  if(charstr(@R)!="0")
+  {
+    ERROR("characteristic 0 expected");
+  }
+  for(int i=nvars(@R);i>=1;i--)
+  {
+    if(var(i)>1)
+    {
+      ERROR("local ordering expected");
+    }
+  }
+
+  ideal dt=jacob(t);
+  list l=stdtrans(dt);
+  ideal g=l[1];
+  if(vdim(g)<=0)
+  {
+    if(vdim(g)==0)
+    {
+      ERROR("singularity at 0 expected");
+    }
+    else
+    {
+      ERROR("isolated critical point 0 expected");
+    }
+  }
+  matrix B=l[2];
+  ideal m=kbase(g);
+
+  int gmsmaxdeg;
+  for(i=nvars(@R);i>=1;i--)
+  {
+    if(deg(var(i))>gmsmaxdeg)
+    {
+      gmsmaxdeg=deg(var(i));
+    }
+  }
+
+  string os=ordstr(@R);
+  int j=find(os,",C");
+  if(j==0)
+  {
+    j=find(os,"C,");
+  }
+  if(j==0)
+  {
+    j=find(os,",c");
+  }
+  if(j==0)
+  {
+    j=find(os,"c,");
+  }
+  if(j>0)
+  {
+    os[j..j+1]="  ";
+  }
+
+  execute("ring G="+string(charstr(@R))+",("+s+","+varstr(@R)+"),(ws("+
+    string(deg(highcorner(g))+2*gmsmaxdeg)+"),"+os+",c);");
+
+  poly gmspoly=imap(@R,t);
+  ideal gmsjacob=imap(@R,dt);
+  ideal gmsstd=imap(@R,g);
+  matrix gmsmatrix=imap(@R,B);
+  ideal gmsbasis=imap(@R,m);
+
+  attrib(gmsstd,"isSB",1);
+  export gmspoly,gmsjacob,gmsstd,gmsmatrix,gmsbasis,gmsmaxdeg;
+
+  return(G);
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring @R=0,(x,y),ds;
+  poly t=x5+x2y2+y5;
+  def G=gmsring(t,"s");
+  setring(G);
+  gmspoly;
+  print(gmsjacob);
+  print(gmsstd);
+  print(gmsmatrix);
+  print(gmsbasis);
+  Gmssing::gmsmaxdeg;
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc gmsnf(ideal p,int K)
+"USAGE:    gmsnf(p,K); poly p, int K
+ASSUME:   basering returned by gmsring
+RETURN:
+  list nf;
+  ideal nf[1];  projection of p to <gmsbasis>C[[s]] mod s^(K+1)
+  ideal nf[2];  p==nf[1]+nf[2]
+NOTE:     computation can be continued by setting p=nf[2]
+KEYWORDS: singularities; Gauss-Manin system; Brieskorn lattice
+EXAMPLE:  example gmsnf; shows examples
+"
+{
+  if(system("with","gms"))
+  {
+    return(system("gmsnf",p,gmsstd,gmsmatrix,(K+1)*deg(var(1))-2*gmsmaxdeg,K));
+  }
+
+  intvec v=1;
+  v[nvars(basering)]=0;
+
+  int k;
+  ideal r,q;
+  r[ncols(p)]=0;
+  q[ncols(p)]=0;
+
+  poly s;
+  int i,j;
+  for(k=ncols(p);k>=1;k--)
+  {
+    while(p[k]!=0&&deg(lead(p[k]),v)<=K)
+    {
+      i=1;
+      s=lead(p[k])/lead(gmsstd[i]);
+      while(i<ncols(gmsstd)&&s==0)
+      {
+        i++;
+        s=lead(p[k])/lead(gmsstd[i]);
+      }
+      if(s!=0)
+      {
+        p[k]=p[k]-s*gmsstd[i];
+        for(j=1;j<=nrows(gmsmatrix);j++)
+        {
+          p[k]=p[k]+diff(s*gmsmatrix[j,i],var(j+1))*var(1);
+        }
+      }
+      else
+      {
+        r[k]=r[k]+lead(p[k]);
+        p[k]=p[k]-lead(p[k]);
+      }
+      while(deg(lead(p[k]))>(K+1)*deg(var(1))-2*gmsmaxdeg&&
+        deg(lead(p[k]),v)<=K)
+      {
+        q[k]=q[k]+lead(p[k]);
+        p[k]=p[k]-lead(p[k]);
+      }
+    }
+    q[k]=q[k]+p[k];
+  }
+
+  return(list(r,q));
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring R=0,(x,y),ds;
+  poly t=x5+x2y2+y5;
+  def G=gmsring(t,"s");
+  setring(G);
+  list l0=gmsnf(gmspoly,0);
+  print(l0[1]);
+  list l1=gmsnf(gmspoly,1);
+  print(l1[1]);
+  list l=gmsnf(l0[2],1);
+  print(l[1]);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc gmscoeffs(ideal p,int K)
+"USAGE:    gmscoeffs(p,K); poly p, int K
+ASSUME:   basering constructed by gmsring
+RETURN:
+ at format
+list l;
+  matrix l[1];  C[[s]]-basis representation of p mod s^(K+1)
+  ideal l[2];  p==matrix(gmsbasis)*l[1]+l[2]
+ at end format
+NOTE:     computation can be continued by setting p=l[2]
+KEYWORDS: singularities; Gauss-Manin system; Brieskorn lattice
+EXAMPLE:  example gmscoeffs; shows examples
+"
+{
+  list l=gmsnf(p,K);
+  ideal r,q=l[1..2];
+  poly v=1;
+  for(int i=2;i<=nvars(basering);i++)
+  {
+    v=v*var(i);
+  }
+  matrix C=coeffs(r,gmsbasis,v);
+  return(list(C,q));
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring R=0,(x,y),ds;
+  poly t=x5+x2y2+y5;
+  def G=gmsring(t,"s");
+  setring(G);
+  list l0=gmscoeffs(gmspoly,0);
+  print(l0[1]);
+  list l1=gmscoeffs(gmspoly,1);
+  print(l1[1]);
+  list l=gmscoeffs(l0[2],1);
+  print(l[1]);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+static proc mindegree(matrix A)
+{
+  int d=-1;
+
+  int i,j;
+  for(i=nrows(A);i>=1;i--)
+  {
+    for(j=ncols(A);j>=1;j--)
+    {
+      if(d==-1||(ord(A[i,j])<d&&ord(A[i,j])>-1))
+      {
+        d=ord(A[i,j]);
+      }
+    }
+  }
+
+  return(d);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+static proc maxdegree(matrix A)
+{
+  int d=-1;
+
+  int i,j;
+  for(i=nrows(A);i>=1;i--)
+  {
+    for(j=ncols(A);j>=1;j--)
+    {
+      if(deg(A[i,j])>d)
+      {
+        d=deg(A[i,j]);
+      }
+    }
+  }
+
+  return(d);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+static proc saturate()
+{
+  int mu=ncols(gmsbasis);
+  ideal r=gmspoly*gmsbasis;
+  matrix A0[mu][mu],C;
+  module H0;
+  module H,H1=freemodule(mu),freemodule(mu);
+  int k=-1;
+  list l;
+
+  dbprint(printlevel-voice+2,"// compute saturation of H''");
+  while(size(reduce(H,std(H0*var(1))))>0)
+  {
+    dbprint(printlevel-voice+2,"// compute matrix A of t");
+    k++;
+    dbprint(printlevel-voice+2,"// k="+string(k));
+    l=gmscoeffs(r,k);
+    C,r=l[1..2];
+    A0=A0+C;
+
+    dbprint(printlevel-voice+2,"// compute saturation step");
+    H0=H;
+    H1=jet(module(A0*H1+var(1)^2*diff(matrix(H1),var(1))),k);
+    H=H*var(1)+H1;
+  }
+
+  A0=A0-k*var(1);
+  dbprint(printlevel-voice+2,"// compute basis of saturation of H''");
+  H=std(H0);
+
+  dbprint(printlevel-voice+2,"// transform H'' to saturation of H''");
+  H0=division(freemodule(mu)*var(1)^k,H,k*deg(var(1)))[1];
+
+  return(A0,r,H,H0,k);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+static proc tjet(matrix A0,ideal r,module H,int K0,int K)
+{
+  dbprint(printlevel-voice+2,"// compute matrix A of t");
+  dbprint(printlevel-voice+2,"// k="+string(K0+K+1));
+  list l=gmscoeffs(r,K0+K+1);
+  matrix C;
+  C,r=l[1..2];
+  A0=A0+C;
+  dbprint(printlevel-voice+2,"// transform A to saturation of H''");
+  matrix A=division(A0*H+var(1)^2*diff(matrix(H),var(1)),H,
+    (K+1)*deg(var(1)))[1]/var(1);
+  return(A,A0,r);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+static proc eigenval(matrix A0,ideal r,module H,int K0)
+{
+  dbprint(printlevel-voice+2,
+    "// compute eigenvalues e with multiplicities m of A1");
+  matrix A;
+  A,A0,r=tjet(A0,r,H,K0,0);
+  list l=eigenvals(A);
+  def e,m=l[1..2];
+  dbprint(printlevel-voice+2,"// e="+string(e));
+  dbprint(printlevel-voice+2,"// m="+string(m));
+  return(e,m,A0,r);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+static proc transform(matrix A,matrix A0,ideal r,module H,module H0,ideal e,
+  intvec m,int K0,int K,int opt)
+{
+  int mu=ncols(gmsbasis);
+
+  int i,j,k;
+  intvec d;
+  d[ncols(e)]=0;
+  if(opt)
+  {
+    dbprint(printlevel-voice+2,
+      "// compute rounded maximal differences d of e");
+    for(i=1;i<=ncols(e);i++)
+    {
+      d[i]=int(e[ncols(e)]-e[i]);
+    }
+  }
+  else
+  {
+    dbprint(printlevel-voice+2,
+      "// compute maximal integer differences d of e");
+    for(i=1;i<ncols(e);i++)
+    {
+      for(j=i+1;j<=ncols(e);j++)
+      {
+        k=int(e[j]-e[i]);
+        if(number(e[j]-e[i])==k)
+        {
+          if(k>d[i])
+          {
+            d[i]=k;
+          }
+          if(-k>d[j])
+          {
+            d[j]=-k;
+          }
+        }
+      }
+    }
+  }
+  dbprint(printlevel-voice+2,"// d="+string(d));
+
+  for(i,k=1,0;i<=size(d);i++)
+  {
+    if(k<d[i])
+    {
+      k=d[i];
+    }
+  }
+  A,A0,r=tjet(A0,r,H,K0,K+k);
+
+  module U,V;
+  if(k>0)
+  {
+    int i0,j0,i1,j1;
+    list l;
+
+    while(k>0)
+    {
+      dbprint(printlevel-voice+2,"// transform to separate eigenvalues");
+      U=0;
+      for(i=1;i<=ncols(e);i++)
+      {
+        U=U+syz(power(jet(A,0)-e[i],m[i]));
+      }
+      V=inverse(U);
+      A=V*A*U;
+      H=H*U;
+      H0=V*H0;
+
+      dbprint(printlevel-voice+2,"// transform to reduce maximum of d by 1");
+      for(i0,i=1,1;i0<=ncols(e);i0++)
+      {
+        for(i1=1;i1<=m[i0];i1,i=i1+1,i+1)
+        {
+          for(j0,j=1,1;j0<=ncols(e);j0++)
+          {
+            for(j1=1;j1<=m[j0];j1,j=j1+1,j+1)
+            {
+              if(d[i0]==0&&d[j0]>=1)
+              {
+                A[i,j]=A[i,j]*var(1);
+              }
+              if(d[i0]>=1&&d[j0]==0)
+              {
+                A[i,j]=A[i,j]/var(1);
+              }
+            }
+          }
+        }
+      }
+
+      H0=transpose(H0);
+      for(i0,i=1,1;i0<=ncols(e);i0++)
+      {
+        if(d[i0]>=1)
+        {
+          for(i1=1;i1<=m[i0];i1,i=i1+1,i+1)
+          {
+            H[i]=H[i]*var(1);
+          }
+          d[i0]=d[i0]-1;
+        }
+        else
+        {
+          for(i1=1;i1<=m[i0];i1,i=i1+1,i+1)
+          {
+            A[i,i]=A[i,i]-1;
+            H0[i]=H0[i]*var(1);
+          }
+          e[i0]=e[i0]-1;
+        }
+      }
+      H0=transpose(H0);
+
+      l=sppnf(list(e,d,m));
+      e,d,m=l[1..3];
+
+      k--;
+      K0++;
+    }
+
+    A=jet(A,K);
+  }
+
+  dbprint(printlevel-voice+2,"// transform to separate eigenvalues");
+  U=0;
+  for(i=1;i<=ncols(e);i++)
+  {
+    U=U+syz(power(jet(A,0)-e[i],m[i]));
+  }
+  V=inverse(U);
+  A=V*A*U;
+  H=H*U;
+  H0=V*H0;
+
+  return(A,A0,r,H,H0,e,m,K0);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc bernstein(poly t)
+"USAGE:    bernstein(t); poly t
+ASSUME:   characteristic 0; local degree ordering;
+          isolated critical point 0 of t
+RETURN:
+ at format
+list bs;  Bernstein-Sato polynomial b(s) of t
+  ideal bs[1];
+    number bs[1][i];  i-th root of b(s)
+  intvec bs[2];
+    int bs[2][i];  multiplicity of i-th root of b(s)
+ at end format
+KEYWORDS: singularities; Gauss-Manin system; Brieskorn lattice;
+          Bernstein-Sato polynomial
+EXAMPLE:  example bernstein; shows examples
+"
+{
+  def @R=basering;
+  int n=nvars(@R)-1;
+  def @G=gmsring(t,"s");
+  setring(@G);
+
+  matrix A;
+  module U0;
+  ideal e;
+  intvec m;
+
+  def A0,r,H,H0,K0=saturate();
+  A,A0,r=tjet(A0,r,H,K0,0);
+  list l=minipoly(A);
+  e,m=l[1..2];
+  e=-e;
+  l=spnf(spadd(list(e,m),list(ideal(-1),intvec(1))));
+
+  setring(@R);
+  list l=imap(@G,l);
+  kill @G,gmsmaxdeg;
+
+  return(l);
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring R=0,(x,y),ds;
+  poly t=x5+x2y2+y5;
+  bernstein(t);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc monodromy(poly t)
+"USAGE:    monodromy(t); poly t
+ASSUME:   characteristic 0; local degree ordering;
+          isolated critical point 0 of t
+RETURN:
+ at format
+list l;  Jordan data jordan(M) of monodromy matrix exp(-2*pi*i*M)
+  ideal l[1];
+    number l[1][i];  eigenvalue of i-th Jordan block of M
+  intvec l[2];
+    int l[2][i];  size of i-th Jordan block of M
+  intvec l[3];
+    int l[3][i];  multiplicity of i-th Jordan block of M
+ at end format
+SEE ALSO: mondromy_lib, linalg_lib
+KEYWORDS: singularities; Gauss-Manin system; Brieskorn lattice; monodromy
+EXAMPLE:  example monodromy; shows examples
+"
+{
+  def @R=basering;
+  int n=nvars(@R)-1;
+  def @G=gmsring(t,"s");
+  setring(@G);
+
+  matrix A;
+  module U0;
+  ideal e;
+  intvec m;
+
+  def A0,r,H,H0,K0=saturate();
+  e,m,A0,r=eigenval(A0,r,H,K0);
+  A,A0,r,H,H0,e,m,K0=transform(A,A0,r,H,H0,e,m,K0,0,0);
+
+  list l=jordan(A,e,m);
+  setring(@R);
+  list l=imap(@G,l);
+  kill @G,gmsmaxdeg;
+
+  return(l);
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring R=0,(x,y),ds;
+  poly t=x5+x2y2+y5;
+  monodromy(t);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc spectrum(poly t)
+"USAGE:    spectrum(t); poly t
+ASSUME:   characteristic 0; local degree ordering;
+          isolated critical point 0 of t
+RETURN:
+ at format
+list sp;  singularity spectrum of t
+  ideal sp[1];
+    number sp[1][i];  i-th spectral number
+  intvec sp[2];
+    int sp[2][i];  multiplicity of i-th spectral number
+ at end format
+SEE ALSO: spectrum_lib
+KEYWORDS: singularities; Gauss-Manin system; Brieskorn lattice;
+          mixed Hodge structure; V-filtration; spectrum
+EXAMPLE:  example spectrum; shows examples
+"
+{
+  list l=vwfilt(t);
+  return(spnf(list(l[1],l[3])));
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring R=0,(x,y),ds;
+  poly t=x5+x2y2+y5;
+  spprint(spectrum(t));
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc sppairs(poly t)
+"USAGE:    sppairs(t); poly t
+ASSUME:   characteristic 0; local degree ordering;
+          isolated critical point 0 of t
+RETURN:
+ at format
+list spp;  spectral pairs of t
+  ideal spp[1];
+    number spp[1][i];  V-filtration index of i-th spectral pair
+  intvec spp[2];
+    int spp[2][i];  weight filtration index of i-th spectral pair
+  intvec spp[3];
+    int spp[3][i];  multiplicity of i-th spectral pair
+ at end format
+SEE ALSO: spectrum_lib
+KEYWORDS: singularities; Gauss-Manin system; Brieskorn lattice;
+          mixed Hodge structure; V-filtration; weight filtration;
+          spectrum; spectral pairs
+EXAMPLE:  example sppairs; shows examples
+"
+{
+  list l=vwfilt(t);
+  return(list(l[1],l[2],l[3]));
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring R=0,(x,y),ds;
+  poly t=x5+x2y2+y5;
+  sppprint(sppairs(t));
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc vfilt(poly t)
+"USAGE:    vfilt(t); poly t
+ASSUME:   characteristic 0; local degree ordering;
+          isolated critical point 0 of t
+RETURN:
+ at format
+list v;  V-filtration on H''/s*H''
+  ideal v[1];
+    number v[1][i];  V-filtration index of i-th spectral number
+  intvec v[2];
+    int v[2][i];  multiplicity of i-th spectral number
+  list v[3];
+    module v[3][i];  vector space of i-th graded part in terms of v[4]
+  ideal v[4];  monomial vector space basis of H''/s*H''
+  ideal v[5];  standard basis of Jacobian ideal
+ at end format
+SEE ALSO: spectrum_lib
+KEYWORDS: singularities; Gauss-Manin system; Brieskorn lattice;
+          mixed Hodge structure; V-filtration; spectrum
+EXAMPLE:  example vfilt; shows examples
+"
+{
+  list l=vwfilt(t);
+  return(spnf(list(l[1],l[3],l[4]))+list(l[5],l[6]));
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring R=0,(x,y),ds;
+  poly t=x5+x2y2+y5;
+  vfilt(t);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc vwfilt(poly t)
+"USAGE:    vwfilt(t); poly t
+ASSUME:   characteristic 0; local degree ordering;
+          isolated critical point 0 of t
+RETURN:
+ at format
+list vw;  weighted V-filtration on H''/s*H''
+  ideal vw[1];
+    number vw[1][i];  V-filtration index of i-th spectral pair
+  intvec vw[2];
+    int vw[2][i];  weight filtration index of i-th spectral pair
+  intvec vw[3];
+    int vw[3][i];  multiplicity of i-th spectral pair
+  list vw[4];
+    module vw[4][i];  vector space of i-th graded part in terms of vw[5]
+  ideal vw[5];  monomial vector space basis of H''/s*H''
+  ideal vw[6];  standard basis of Jacobian ideal
+ at end format
+SEE ALSO: spectrum_lib
+KEYWORDS: singularities; Gauss-Manin system; Brieskorn lattice;
+          mixed Hodge structure; V-filtration; weight filtration;
+          spectrum; spectral pairs
+EXAMPLE:  example vwfilt; shows examples
+"
+{
+  def @R=basering;
+  int n=nvars(@R)-1;
+  def @G=gmsring(t,"s");
+  setring(@G);
+
+  int mu=ncols(gmsbasis);
+  matrix A;
+  ideal e;
+  intvec m;
+
+  def A0,r,H,H0,K0=saturate();
+  e,m,A0,r=eigenval(A0,r,H,K0);
+  A,A0,r,H,H0,e,m,K0=transform(A,A0,r,H,H0,e,m,K0,0,1);
+
+  dbprint(printlevel-voice+2,"// compute weight filtration basis");
+  list l=jordanbasis(A,e,m);
+  def U,v=l[1..2];
+  kill l;
+  vector u0;
+  int v0;
+  int i,j,k,l;
+  for(k,l=1,1;l<=ncols(e);k,l=k+m[l],l+1)
+  {
+    for(i=k+m[l]-1;i>=k+1;i--)
+    {
+      for(j=i-1;j>=k;j--)
+      {
+        if(v[i]>v[j])
+        {
+          v0=v[i];v[i]=v[j];v[j]=v0;
+          u0=U[i];U[i]=U[j];U[j]=u0;
+        }
+      }
+    }
+  }
+
+  dbprint(printlevel-voice+2,"// transform to weight filtration basis");
+  matrix V=inverse(U);
+  A=V*A*U;
+  dbprint(printlevel-voice+2,"// compute standard basis of H''");
+  H=H*U;
+  H0=std(V*H0);
+
+  dbprint(printlevel-voice+2,"// compute spectral pairs");
+  ideal a;
+  intvec w;
+  for(i=1;i<=mu;i++)
+  {
+    j=leadexp(H0[i])[nvars(basering)+1];
+    a[i]=A[j,j]+ord(H0[i]) div deg(var(1))-1;
+    w[i]=v[j]+n;
+  }
+  H=H*H0;
+  H=simplify(jet(H/var(1)^(mindegree(H) div deg(var(1))),0),1);
+
+  kill l;
+  list l=sppnf(list(a,w,H))+list(gmsbasis,gmsstd);
+  setring(@R);
+  list l=imap(@G,l);
+  kill @G,gmsmaxdeg;
+  attrib(l[5],"isSB",1);
+
+  return(l);
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring R=0,(x,y),ds;
+  poly t=x5+x2y2+y5;
+  vwfilt(t);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+static proc fsplit(ideal e0,intvec m0,matrix A,module H,module H0)
+{
+  int mu=ncols(gmsbasis);
+
+  dbprint(printlevel-voice+2,"// compute standard basis of H''");
+  H0=std(H0);
+  H0=simplify(H0,1);
+
+  dbprint(printlevel-voice+2,"// compute Hodge filtration");
+  int i,j,k;
+  ideal e;
+  intvec m;
+  e[mu]=0;
+  for(i=1;i<=ncols(e0);i++)
+  {
+    for(j=m0[i];j>=1;j--)
+    {
+      k++;
+      e[k]=e0[i];
+      m[k]=i;
+    }
+  }
+
+  number n,n0;
+  vector v,v0;
+  list F;
+  for(i=ncols(e0);i>=1;i--)
+  {
+    F[i]=module(matrix(0,mu,1));
+  }
+  for(i=mu;i>=1;i--)
+  {
+    v=H0[i];
+    v0=lead(v);
+    n0=leadcoef(e[leadexp(v0)[nvars(basering)+1]])+leadexp(v0)[1];
+    v=v-lead(v);
+    while(v!=0)
+    {
+      n=leadcoef(e[leadexp(v)[nvars(basering)+1]])+leadexp(v)[1];
+      if(n==n0)
+      {
+        v0=v0+lead(v);
+        v=v-lead(v);
+      }
+      else
+      {
+        v=0;
+      }
+    }
+    j=m[leadexp(v0)[nvars(basering)+1]];
+    F[j]=F[j]+v0;
+  }
+
+  dbprint(printlevel-voice+2,"// compute splitting of Hodge filtration");
+  matrix A0=jet(A,0);
+  module U,U0,U1,U2;
+  matrix N;
+  s=0;
+  for(i=size(F);i>=1;i--)
+  {
+    N=A0-e0[i];
+    U0=0;
+    while(size(F[i])>0)
+    {
+      U1=jet(F[i],0);
+      k=0;
+      while(size(U1)>0)
+      {
+        for(j=ncols(U1);j>=1;j--)
+        {
+          if(size(reduce(U1[j],std(U0)))>0)
+          {
+            U0=U0+U1[j];
+          }
+        }
+        U1=N*U1;
+        k++;
+      }
+      F[i]=module(F[i]/var(1));
+    }
+    U=U0+U;
+  }
+
+  dbprint(printlevel-voice+2,"// transform to Hodge splitting basis");
+  H=H*U;
+  H0=lift(U,H0);
+  A=lift(U,A*U);
+
+  return(e,A,H,H0);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+static proc glift(ideal e,matrix A,module H,module H0,int K)
+{
+  poly s=var(1);
+  int mu=ncols(gmsbasis);
+
+  dbprint(printlevel-voice+2,"// compute standard basis of H''");
+  H0=std(H0);
+  H0=simplify(H0,1);
+
+  int i,j,k;
+  ideal v;
+  for(i=mu;i>=1;i--)
+  {
+    v[i]=e[leadexp(H0[i])[nvars(basering)+1]]+leadexp(H0[i])[1];
+  }
+
+  dbprint(printlevel-voice+2,
+    "// compute matrix A0 of t w.r.t. good basis H0 of H''");
+  number c;
+  matrix h0[mu][1];
+  matrix m[mu][1];
+  matrix a0[mu][1];
+  matrix A0[mu][mu];
+  module M=H0;
+  module N=jet(s*A*matrix(H0)+s^2*diff(matrix(H0),s),K+1);
+  while(size(N)>0)
+  {
+    j=mu;
+    for(k=mu-1;k>=1;k--)
+    {
+      if(N[k]>N[j])
+      {
+        j=k;
+      }
+    }
+    i=mu;
+    while(leadexp(M[i])[nvars(basering)+1]!=leadexp(N[j])[nvars(basering)+1])
+    {
+      i--;
+    }
+    k=leadexp(N[j])[1]-leadexp(M[i])[1];
+    if(k==0||i==j)
+    {
+      dbprint(printlevel-voice+3,"// compute A0["+string(i)+","+string(j)+"]");
+      c=leadcoef(N[j])/leadcoef(M[i]);
+      A0[i,j]=A0[i,j]+c*s^k;
+      N[j]=jet(N[j]-c*s^k*M[i],K+1);
+    }
+    else
+    {
+      dbprint(printlevel-voice+3,
+        "// reduce H0["+string(j)+"] with H0["+string(i)+"]");
+      c=leadcoef(N[j])/leadcoef(M[i])/(1-k-leadcoef(v[i])+leadcoef(v[j]));
+      H0[j]=H0[j]+c*s^(k-1)*H0[i];
+      M[j]=M[j]+c*s^(k-1)*M[i];
+      h0=c*s^(k-1)*H0[i];
+      N[j]=N[j]+jet(s*A*h0+s^2*diff(h0,s),K+1)[1];
+      m=M[i];
+      a0=transpose(A0)[j];
+      N=N-jet(c*s^(k-1)*m*transpose(a0),K+1);
+    }
+  }
+
+  H0=H*H0;
+  H0=H0/var(1)^(mindegree(H0) div deg(var(1)));
+
+  return(A0,H0);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc tmatrix(poly t)
+"USAGE:    tmatrix(t); poly t
+ASSUME:   characteristic 0; local degree ordering;
+          isolated critical point 0 of t
+RETURN:
+ at format
+list l=A0,A1,T,M;
+  matrix A0,A1;  t=A0+s*A1+s^2*(d/ds) on H'' w.r.t. C[[s]]-basis M*T
+  module T;  C-basis of C^mu
+  ideal M;  monomial C-basis of H''/sH''
+ at end format
+KEYWORDS: singularities; Gauss-Manin system; Brieskorn lattice;
+          mixed Hodge structure; V-filtration; weight filtration;
+          monodromy; spectrum; spectral pairs; good basis
+EXAMPLE:  example tmatrix; shows examples
+"
+{
+  def @R=basering;
+  int n=nvars(@R)-1;
+  def @G=gmsring(t,"s");
+  setring(@G);
+
+  int mu=ncols(gmsbasis);
+  matrix A;
+  module U0;
+  ideal e;
+  intvec m;
+
+  def A0,r,H,H0,K0=saturate();
+  e,m,A0,r=eigenval(A0,r,H,K0);
+  A,A0,r,H,H0,e,m,K0=transform(A,A0,r,H,H0,e,m,K0,K0+int(e[ncols(e)]-e[1]),1);
+  A,H0=glift(fsplit(e,m,A,H,H0),K0);
+
+  A0=jet(A,0);
+  A=jet(A/var(1),0);
+
+  list l=A0,A,H0,gmsbasis;
+  setring(@R);
+  list l=imap(@G,l);
+  kill @G,gmsmaxdeg;
+
+  return(l);
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring R=0,(x,y),ds;
+  poly t=x5+x2y2+y5;
+  list l=tmatrix(t);
+  print(l[1]);
+  print(l[2]);
+  print(l[3]);
+  print(l[4]);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc endvfilt(list v)
+"USAGE:   endvfilt(v); list v
+ASSUME:  v returned by vfilt
+RETURN:
+ at format
+list ev;  V-filtration on Jacobian algebra
+  ideal ev[1];
+    number ev[1][i];  i-th V-filtration index
+  intvec ev[2];
+    int ev[2][i];  i-th multiplicity
+  list ev[3];
+    module ev[3][i];  vector space of i-th graded part in terms of ev[4]
+  ideal ev[4];  monomial vector space basis of Jacobian algebra
+  ideal ev[5];  standard basis of Jacobian ideal
+ at end format
+KEYWORDS: singularities; Gauss-Manin system; Brieskorn lattice;
+          mixed Hodge structure; V-filtration; endomorphism filtration
+EXAMPLE:  example endvfilt; shows examples
+"
+{
+  def a,d,V,m,g=v[1..5];
+  attrib(g,"isSB",1);
+  int mu=ncols(m);
+
+  module V0=V[1];
+  for(int i=2;i<=size(V);i++)
+  {
+    V0=V0,V[i];
+  }
+
+  dbprint(printlevel-voice+2,"// compute multiplication in Jacobian algebra");
+  list M;
+  module U=freemodule(ncols(m));
+  for(i=ncols(m);i>=1;i--)
+  {
+    M[i]=division(coeffs(reduce(m[i]*m,g,U),m)*V0,V0)[1];
+  }
+
+  int j,k,i0,j0,i1,j1;
+  number b0=number(a[1]-a[ncols(a)]);
+  number b1,b2;
+  matrix M0;
+  module L;
+  list v0=freemodule(ncols(m));
+  ideal a0=b0;
+  list l;
+
+  while(b0<number(a[ncols(a)]-a[1]))
+  {
+    dbprint(printlevel-voice+2,"// find next possible index");
+    b1=number(a[ncols(a)]-a[1]);
+    for(j=ncols(a);j>=1;j--)
+    {
+      for(i=ncols(a);i>=1;i--)
+      {
+        b2=number(a[i]-a[j]);
+        if(b2>b0&&b2<b1)
+        {
+          b1=b2;
+        }
+        else
+        {
+          if(b2<=b0)
+          {
+            i=0;
+          }
+        }
+      }
+    }
+    b0=b1;
+
+    l=ideal();
+    for(k=ncols(m);k>=2;k--)
+    {
+      l=l+list(ideal());
+    }
+
+    dbprint(printlevel-voice+2,"// collect conditions for EV["+string(b0)+"]");
+    j=ncols(a);
+    j0=mu;
+    while(j>=1)
+    {
+      i0=1;
+      i=1;
+      while(i<ncols(a)&&a[i]<a[j]+b0)
+      {
+        i0=i0+d[i];
+        i++;
+      }
+      if(a[i]<a[j]+b0)
+      {
+        i0=i0+d[i];
+        i++;
+      }
+      for(k=1;k<=ncols(m);k++)
+      {
+        M0=M[k];
+        if(i0>1)
+        {
+          l[k]=l[k],M0[1..i0-1,j0-d[j]+1..j0];
+        }
+      }
+      j0=j0-d[j];
+      j--;
+    }
+
+    dbprint(printlevel-voice+2,"// compose condition matrix");
+    L=transpose(module(l[1]));
+    for(k=2;k<=ncols(m);k++)
+    {
+      L=L,transpose(module(l[k]));
+    }
+
+    dbprint(printlevel-voice+2,"// compute kernel of condition matrix");
+    v0=v0+list(syz(L));
+    a0=a0,b0;
+  }
+
+  dbprint(printlevel-voice+2,"// compute graded parts");
+  option(redSB);
+  for(i=1;i<size(v0);i++)
+  {
+    v0[i+1]=std(v0[i+1]);
+    v0[i]=std(reduce(v0[i],v0[i+1]));
+  }
+  option(noredSB);
+
+  dbprint(printlevel-voice+2,"// remove trivial graded parts");
+  i=1;
+  while(size(v0[i])==0)
+  {
+    i++;
+  }
+  list v1=v0[i];
+  intvec d1=size(v0[i]);
+  ideal a1=a0[i];
+  i++;
+  while(i<=size(v0))
+  {
+    if(size(v0[i])>0)
+    {
+      v1=v1+list(v0[i]);
+      d1=d1,size(v0[i]);
+      a1=a1,a0[i];
+    }
+    i++;
+  }
+  return(list(a1,d1,v1,m,g));
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring R=0,(x,y),ds;
+  poly t=x5+x2y2+y5;
+  endvfilt(vfilt(t));
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc sppnf(list sp)
+"USAGE:   sppnf(list(a,w[,m])); ideal a, intvec w, intvec m
+ASSUME:  ncols(a)==size(w)==size(m)
+RETURN:  order (a[i][,w[i]]) with multiplicity m[i] lexicographically
+EXAMPLE: example sppnf; shows examples
+"
+{
+  ideal a=sp[1];
+  intvec w=sp[2];
+  int n=ncols(a);
+  intvec m;
+  list V;
+  module v;
+  int i,j;
+  for(i=3;i<=size(sp);i++)
+  {
+    if(typeof(sp[i])=="intvec")
+    {
+      m=sp[i];
+    }
+    if(typeof(sp[i])=="module")
+    {
+      v=sp[i];
+      for(j=n;j>=1;j--)
+      {
+        V[j]=module(v[j]);
+      }
+    }
+    if(typeof(sp[i])=="list")
+    {
+      V=sp[i];
+    }
+  }
+  if(m==0)
+  {
+    for(i=n;i>=1;i--)
+    {
+      m[i]=1;
+    }
+  }
+
+  int k;
+  ideal a0;
+  intvec w0,m0;
+  list V0;
+  number a1;
+  int w1,m1;
+  for(i=n;i>=1;i--)
+  {
+    if(m[i]!=0)
+    {
+      for(j=i-1;j>=1;j--)
+      {
+        if(m[j]!=0)
+        {
+          if(number(a[i])>number(a[j])||
+            (number(a[i])==number(a[j])&&w[i]<w[j]))
+          {
+            a1=number(a[i]);
+            a[i]=a[j];
+            a[j]=a1;
+            w1=w[i];
+            w[i]=w[j];
+            w[j]=w1;
+            m1=m[i];
+            m[i]=m[j];
+            m[j]=m1;
+            if(size(V)>0)
+            {
+              v=V[i];
+              V[i]=V[j];
+              V[j]=v;
+            }
+          }
+          if(number(a[i])==number(a[j])&&w[i]==w[j])
+          {
+            m[i]=m[i]+m[j];
+            m[j]=0;
+            if(size(V)>0)
+            {
+              V[i]=V[i]+V[j];
+            }
+          }
+        }
+      }
+      k++;
+      a0[k]=a[i];
+      w0[k]=w[i];
+      m0[k]=m[i];
+      if(size(V)>0)
+      {
+        V0[k]=V[i];
+      }
+    }
+  }
+
+  if(size(V0)>0)
+  {
+    n=size(V0);
+    module U=std(V0[n]);
+    for(i=n-1;i>=1;i--)
+    {
+      V0[i]=simplify(reduce(V0[i],U),1);
+      if(i>=2)
+      {
+        U=std(U+V0[i]);
+      }
+    }
+  }
+
+  if(k>0)
+  {
+    sp=a0,w0,m0;
+    if(size(V0)>0)
+    {
+      sp[4]=V0;
+    }
+  }
+  return(sp);
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring R=0,(x,y),ds;
+  list sp=list(ideal(-1/2,-3/10,-3/10,-1/10,-1/10,0,1/10,1/10,3/10,3/10,1/2),
+    intvec(2,1,1,1,1,1,1,1,1,1,0));
+  sppprint(sppnf(sp));
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc sppprint(list spp)
+"USAGE:   sppprint(spp); list spp
+RETURN:  string s;  spectral pairs spp
+EXAMPLE: example sppprint; shows examples
+"
+{
+  string s;
+  for(int i=1;i<size(spp[3]);i++)
+  {
+    s=s+"(("+string(spp[1][i])+","+string(spp[2][i])+"),"
+      +string(spp[3][i])+"),";
+  }
+  s=s+"(("+string(spp[1][i])+","+string(spp[2][i])+"),"+string(spp[3][i])+")";
+  return(s);
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring R=0,(x,y),ds;
+  list spp=list(ideal(-1/2,-3/10,-1/10,0,1/10,3/10,1/2),intvec(2,1,1,1,1,1,0),
+    intvec(1,2,2,1,2,2,1));
+  sppprint(spp);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc spadd(list sp1,list sp2)
+"USAGE:   spadd(sp1,sp2); list sp1, list sp2
+RETURN:  list sp;  sum of spectra sp1 and sp2
+EXAMPLE: example spadd; shows examples
+"
+{
+  ideal s;
+  intvec m;
+  int i,i1,i2=1,1,1;
+  while(i1<=size(sp1[2])||i2<=size(sp2[2]))
+  {
+    if(i1<=size(sp1[2]))
+    {
+      if(i2<=size(sp2[2]))
+      {
+        if(number(sp1[1][i1])<number(sp2[1][i2]))
+        {
+          s[i]=sp1[1][i1];
+          m[i]=sp1[2][i1];
+          i++;
+          i1++;
+        }
+        else
+        {
+          if(number(sp1[1][i1])>number(sp2[1][i2]))
+          {
+            s[i]=sp2[1][i2];
+            m[i]=sp2[2][i2];
+            i++;
+            i2++;
+          }
+          else
+          {
+            if(sp1[2][i1]+sp2[2][i2]!=0)
+            {
+              s[i]=sp1[1][i1];
+              m[i]=sp1[2][i1]+sp2[2][i2];
+              i++;
+            }
+            i1++;
+            i2++;
+          }
+        }
+      }
+      else
+      {
+        s[i]=sp1[1][i1];
+        m[i]=sp1[2][i1];
+        i++;
+        i1++;
+      }
+    }
+    else
+    {
+      s[i]=sp2[1][i2];
+      m[i]=sp2[2][i2];
+      i++;
+      i2++;
+    }
+  }
+  return(list(s,m));
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring R=0,(x,y),ds;
+  list sp1=list(ideal(-1/2,-3/10,-1/10,0,1/10,3/10,1/2),intvec(1,2,2,1,2,2,1));
+  spprint(sp1);
+  list sp2=list(ideal(-1/6,1/6),intvec(1,1));
+  spprint(sp2);
+  spprint(spadd(sp1,sp2));
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc spsub(list sp1,list sp2)
+"USAGE:   spsub(sp1,sp2); list sp1, list sp2
+RETURN:  list sp;  difference of spectra sp1 and sp2
+EXAMPLE: example spsub; shows examples
+"
+{
+  return(spadd(sp1,spmul(sp2,-1)));
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring R=0,(x,y),ds;
+  list sp1=list(ideal(-1/2,-3/10,-1/10,0,1/10,3/10,1/2),intvec(1,2,2,1,2,2,1));
+  spprint(sp1);
+  list sp2=list(ideal(-1/6,1/6),intvec(1,1));
+  spprint(sp2);
+  spprint(spsub(sp1,sp2));
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc spmul(list #)
+"USAGE:   spmul(sp0,k); list sp0, int[vec] k
+RETURN:  list sp;  linear combination of spectra sp0 with coefficients k
+EXAMPLE: example spmul; shows examples
+"
+{
+  if(size(#)==2)
+  {
+    if(typeof(#[1])=="list")
+    {
+      if(typeof(#[2])=="int")
+      {
+        return(list(#[1][1],#[1][2]*#[2]));
+      }
+      if(typeof(#[2])=="intvec")
+      {
+        list sp0=list(ideal(),intvec(0));
+        for(int i=size(#[2]);i>=1;i--)
+        {
+          sp0=spadd(sp0,spmul(#[1][i],#[2][i]));
+        }
+        return(sp0);
+      }
+    }
+  }
+  return(list(ideal(),intvec(0)));
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring R=0,(x,y),ds;
+  list sp=list(ideal(-1/2,-3/10,-1/10,0,1/10,3/10,1/2),intvec(1,2,2,1,2,2,1));
+  spprint(sp);
+  spprint(spmul(sp,2));
+  list sp1=list(ideal(-1/6,1/6),intvec(1,1));
+  spprint(sp1);
+  list sp2=list(ideal(-1/3,0,1/3),intvec(1,2,1));
+  spprint(sp2);
+  spprint(spmul(list(sp1,sp2),intvec(1,2)));
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc spissemicont(list sp,list #)
+"USAGE:   spissemicont(sp[,1]); list sp, int opt
+RETURN:
+ at format
+int k=
+  1;  if sum of sp is positive on all intervals [a,a+1) [and (a,a+1)]
+  0;  if sum of sp is negative on some interval [a,a+1) [or (a,a+1)]
+ at end format
+EXAMPLE: example spissemicont; shows examples
+"
+{
+  int opt=0;
+  if(size(#)>0)
+  {
+    if(typeof(#[1])=="int")
+    {
+      opt=1;
+    }
+  }
+  int i,j,k;
+  i=1;
+  while(i<=size(sp[2])-1)
+  {
+    j=i+1;
+    k=0;
+    while(j+1<=size(sp[2])&&number(sp[1][j])<=number(sp[1][i])+1)
+    {
+      if(opt==0||number(sp[1][j])<number(sp[1][i])+1)
+      {
+        k=k+sp[2][j];
+      }
+      j++;
+    }
+    if(j==size(sp[2])&&number(sp[1][j])<=number(sp[1][i])+1)
+    {
+      if(opt==0||number(sp[1][j])<number(sp[1][i])+1)
+      {
+        k=k+sp[2][j];
+      }
+    }
+    if(k<0)
+    {
+      return(0);
+    }
+    i++;
+  }
+  return(1);
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring R=0,(x,y),ds;
+  list sp1=list(ideal(-1/2,-3/10,-1/10,0,1/10,3/10,1/2),intvec(1,2,2,1,2,2,1));
+  spprint(sp1);
+  list sp2=list(ideal(-1/6,1/6),intvec(1,1));
+  spprint(sp2);
+  spissemicont(spsub(sp1,spmul(sp2,3)));
+  spissemicont(spsub(sp1,spmul(sp2,4)));
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc spsemicont(list sp0,list sp,list #)
+"USAGE:   spsemicont(sp0,sp,k[,1]); list sp0, list sp
+RETURN:
+ at format
+list l;
+  intvec l[i];  if the spectra sp0 occur with multiplicities k
+                in a deformation of a [quasihomogeneous] singularity
+                with spectrum sp then k<=l[i]
+ at end format
+EXAMPLE: example spsemicont; shows examples
+"
+{
+  list l,l0;
+  int i,j,k;
+  while(spissemicont(sp0,#))
+  {
+    if(size(sp)>1)
+    {
+      l0=spsemicont(sp0,list(sp[1..size(sp)-1]));
+      for(i=1;i<=size(l0);i++)
+      {
+        if(size(l)>0)
+        {
+          j=1;
+          while(j<size(l)&&l[j]!=l0[i])
+          {
+            j++;
+          }
+          if(l[j]==l0[i])
+          {
+            l[j][size(sp)]=k;
+          }
+          else
+          {
+            l0[i][size(sp)]=k;
+            l=l+list(l0[i]);
+          }
+        }
+        else
+        {
+          l=l0;
+        }
+      }
+    }
+    sp0=spsub(sp0,sp[size(sp)]);
+    k++;
+  }
+  if(size(sp)>1)
+  {
+    return(l);
+  }
+  else
+  {
+    return(list(intvec(k-1)));
+  }
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring R=0,(x,y),ds;
+  list sp0=list(ideal(-1/2,-3/10,-1/10,0,1/10,3/10,1/2),intvec(1,2,2,1,2,2,1));
+  spprint(sp0);
+  list sp1=list(ideal(-1/6,1/6),intvec(1,1));
+  spprint(sp1);
+  list sp2=list(ideal(-1/3,0,1/3),intvec(1,2,1));
+  spprint(sp2);
+  list sp=sp1,sp2;
+  list l=spsemicont(sp0,sp);
+  l;
+  spissemicont(spsub(sp0,spmul(sp,l[1])));
+  spissemicont(spsub(sp0,spmul(sp,l[1]-1)));
+  spissemicont(spsub(sp0,spmul(sp,l[1]+1)));
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc spmilnor(list sp)
+"USAGE:   spmilnor(sp); list sp
+RETURN:  int mu;  Milnor number of spectrum sp
+EXAMPLE: example spmilnor; shows examples
+"
+{
+  return(sum(sp[2]));
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring R=0,(x,y),ds;
+  list sp=list(ideal(-1/2,-3/10,-1/10,0,1/10,3/10,1/2),intvec(1,2,2,1,2,2,1));
+  spprint(sp);
+  spmilnor(sp);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc spgeomgenus(list sp)
+"USAGE:   spgeomgenus(sp); list sp
+RETURN:  int g;  geometrical genus of spectrum sp
+EXAMPLE: example spgeomgenus; shows examples
+"
+{
+  int g=0;
+  int i=1;
+  while(i+1<=size(sp[2])&&number(sp[1][i])<=number(0))
+  {
+    g=g+sp[2][i];
+    i++;
+  }
+  if(i==size(sp[2])&&number(sp[1][i])<=number(0))
+  {
+    g=g+sp[2][i];
+  }
+  return(g);
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring R=0,(x,y),ds;
+  list sp=list(ideal(-1/2,-3/10,-1/10,0,1/10,3/10,1/2),intvec(1,2,2,1,2,2,1));
+  spprint(sp);
+  spgeomgenus(sp);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc spgamma(list sp)
+"USAGE:   spgamma(sp); list sp
+RETURN:  number gamma;  gamma invariant of spectrum sp
+EXAMPLE: example spgamma; shows examples
+"
+{
+  int i,j;
+  number g=0;
+  for(i=1;i<=ncols(sp[1]);i++)
+  {
+    for(j=1;j<=sp[2][i];j++)
+    {
+      g=g+(number(sp[1][i])-number(nvars(basering)-2)/2)^2;
+    }
+  }
+  g=-g/4+sum(sp[2])*number(sp[1][ncols(sp[1])]-sp[1][1])/48;
+  return(g);
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring R=0,(x,y),ds;
+  list sp=list(ideal(-1/2,-3/10,-1/10,0,1/10,3/10,1/2),intvec(1,2,2,1,2,2,1));
+  spprint(sp);
+  spgamma(sp);
+}
+///////////////////////////////////////////////////////////////////////////////
diff --git a/Singular/LIB/graphics.lib b/Singular/LIB/graphics.lib
new file mode 100644
index 0000000..a8b1d74
--- /dev/null
+++ b/Singular/LIB/graphics.lib
@@ -0,0 +1,360 @@
+//////////////////////////////////////////////////////////////////////////////
+version="version graphics.lib 4.0.0.0 Jun_2013 "; // $Id: 36a4d2e5c43fecf40662744669851fd85cbbd2b1 $
+category="Visualization";
+info="
+LIBRARY: graphics.lib    Procedures to use Graphics with Mathematica
+AUTHOR:   Christian Gorzel, gorzelc at math.uni-muenster.de
+
+PROCEDURES:
+ staircase(fname,I);  Mathematica text for displaying staircase of I
+ mathinit();          string for loading Mathematica's ImplicitPlot
+ mplot(fname,I[# s]); Mathematica text for various plots
+";
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc staircase(string fname,ideal I)
+"USAGE:   staircase(s,I); s a string, I ideal in two variables
+RETURN:  string with Mathematica input for displaying staircase diagrams of an
+         ideal I, i.e. exponent vectors of the initial ideal of I
+NOTE:    ideal I should be given by a standard basis. Let s=\"\" and copy and
+         paste the result into a Mathematica notebook.
+EXAMPLE: example staircase; shows an example
+"
+{
+  intvec v;
+  int maxx, maxy;
+  list l;
+  string s;
+  string el;
+
+ if(nvars(basering)!=2)
+ { "-- Error: need two variables ";
+   return();
+ }
+ if (not(attrib(I,"isSB")))
+ { " -- Warning: Ideal should be a standardbasis "; newline; }
+
+ for(int i=1; i<=ncols(I); i++)
+ {
+  if (i>1) { el = el + ",";}
+  v = leadexp(I[i]);
+  if (v[1] > maxx) { maxx = v[1];}
+  if (v[2] > maxy) { maxy = v[2];}
+  el = el + "{" + string(v) + "}";
+ }
+ el = "{" + el + "}";
+ maxx = maxx + 3;
+ maxy = maxy + 3;
+
+ s = newline +
+     "Show[Graphics[{" + newline +
+     "{GrayLevel[0.5],Map[Rectangle[#,{" +
+          string(maxx) + "," + string(maxy) + "}] &, " + el + "]}," + newline +
+     "{PointSize[0.03], Map[Point," + el + "]}," + newline +
+       "Table[Circle[{i,j},0.1],{i,0," +
+           string(maxx) + "},{j,0," + string(maxy) + "}]}," + newline +
+     "  Axes->True,AspectRatio->Automatic]]";
+ s = s + endstr(fname);
+ return(s);
+}
+example
+{ "EXAMPLE:"; echo =2;
+  ring r0 = 0,(x,y),ls;
+  ideal I = -1x2y6-1x4y2, 7x6y5+1/2x7y4+6x4y6;
+  staircase("",std(I));
+
+  ring r1 = 0,(x,y),dp;
+  ideal I = fetch(r0,I);
+  staircase("",std(I));
+
+  ring r2 = 0,(x,y),wp(2,3);
+  ideal I = fetch(r0,I);
+  staircase("",std(I));
+
+  // Paste the output into a Mathematica notebook
+  // active evalutation of the cell with SHIFT RETURN
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc mathinit()
+"USAGE:   mathinit();
+RETURN:  initializing string for loading Mathematica's ImplicitPlot
+EXAMPLE: example mathinit; shows an example
+"
+{
+  // write("init.m","<< Graphics`ImplicitPlot`");
+  return("<< Graphics`ImplicitPlot`");
+}
+example
+{ "EXAMPLE:"; echo =2;
+  mathinit();
+
+  // Paste the output into a Mathematica notebook
+  // active evalutation of the cell with SHIFT RETURN
+}
+///////////////////////////////////////////////////////////////////////////////
+
+static proc checkshort()
+{
+  ring @r;
+}
+static proc determvars(ideal I)
+// determine the variables which are in the ideal I
+{
+  intvec v;
+  int i,j,k;
+
+  k=1;
+  for(j=1;j<=size(I);j++)
+  { for(i=1;i<=nvars(basering);i++)
+    { if(I[j]!=subst(I[j],var(i),0)) {v[k] = i; k++;}
+    }
+  }
+  ring @r=0,x,ls;
+  poly f;
+  for(i=1;i<=size(v);i++)     // sort VARS
+  { f = f + x^v[i]; }
+  v=0;
+  for (i=1;i<=size(f);i++)
+  {v[i]=leadexp(f[i])[1];}
+ return(v);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+static proc endstr(string filename)
+{ int i;
+  string suffix,cmd,name;
+
+ if(size(filename))
+ {
+  for (i=size(filename);i;i--)
+  { if (filename[i] == ".") {break;}
+  }
+
+ if (i>0)
+ { suffix = filename[i,size(filename)-i+1];
+   name = ">" + filename[1,i-1]+ ".m";
+ }
+ else { print("--Error: Suffix of filename incorrect"); return("");}
+// if (suffix ==".m") { cmd = "Display[\" " + filename + "\",% ]";}
+ if (suffix ==".mps") { cmd = "Display[\" " + filename + "\",%] ";}
+ if (suffix ==".ps") { cmd = "Display[\" ! psfix > " + filename + "\", %]";}
+ if (suffix ==".eps")
+                { cmd = "Display[\" ! psfix -epsf > " + filename + "\", %]";}
+
+ }
+ return(newline + cmd);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+proc mplot(string fname,ideal I,list #)
+"USAGE:   mplot(fname, I [,I1,I2,..,s] ); fname=string; I,I1,I2,..=ideals,
+         s=string representing the plot region.@*
+         Use the ideals I1,I2,.. in order to produce multiple plots (they need
+         to have the same number of entries as I!).
+RETURN:  string, text with Mathematica commands to display a plot
+NOTE:    The plotregion is defaulted to -1,1 around zero.
+         For implicit given curves enter first the string returned by
+         procedure mathinit into Mathematica in order to load ImplicitPlot.
+         The following conventions for I are used:
+  @format
+  - ideal with 2 entries in one variable means a parametrised plane curve,
+  - ideal with 3 entries in one variable means a parametrised space curve,
+  - ideal with 3 entries in two variables means a parametrised surface,
+  - ideal with 2 entries in two variables means an implicit curve
+    given as I[1]==I[2],
+  - ideal with 1 entry (or one polynomial) in two variables means
+    an implicit curve given as  f == 0,
+  @end format
+EXAMPLE: example mplot; shows an example
+"
+{
+  int i,j,k,mapping;
+  int planecurve,spacecurve,implcrv,surface;
+  intvec VARS,v;
+  string xpart,ypart,zpart = "-1,1","-1,1","All";
+  string pstring,actstring,xname,yname,str,closing;
+  string basr = nameof(basering);
+  ideal J;
+
+  if (ncols(I)>3)
+  { "-- Error: can only draw upto dimension 3";
+    return("");
+  }
+  ring @r = 0,(s,t),lp;
+  ideal @J, at I;
+
+  setring(`basr`);
+  // def d = basering;
+  // d;
+  // listvar(d);
+
+  str = newline;
+
+  VARS = determvars(I);
+   // "VARS: ";VARS;
+
+  if (size(VARS)>2 or VARS==0)
+  { "-- Error: Need some variables, but can only draw in 2 or 3 dimensions";
+    return("");
+  }
+  if (size(matrix(I))==1 and size(VARS)==2)
+  { i =size(I[1]);
+   //I[2]=I[1][(i/ 2 + 1)..i]; I[2];
+   // I[1]=I[1][1..(i/ 2)]; I[1];
+   I[2]=0;
+  }
+  if (size(matrix(I))==2)
+  { if (size(VARS)==1) {planecurve=1; str = str + "ParametricPlot[";}
+    if (size(VARS)==2) {implcrv=1; str = str + "ImplicitPlot[";}
+  }
+  if (size(matrix(I))==3)
+  { if (size(VARS)==1) {spacecurve=1;}
+    if (size(VARS)==2) {surface=1;}
+    str =  str + "ParametricPlot3D[";
+  }
+
+  short = 0;
+
+  pstring = string(I);
+
+ // switch to another ring if necessary
+
+  checkshort();
+//  "short: "; short;
+
+  if (short!=1)      // construct a map
+  {
+    mapping = 1;
+    setring @r;
+    @J = 0;
+    for(i=1;i<=size(VARS);i++)
+    { @J[VARS[i]]=var(i);}
+    map phi = (`basr`, at J);
+    @I = phi(I);
+    short =0;
+    pstring = string(@I);
+    setring `basr`;
+  }
+
+  i = find(pstring,newline);
+  while(i)
+  {pstring[i]=" ";
+   i = find(pstring,newline,i);
+  }
+  if (implcrv)
+  { i = find(pstring,",");
+    pstring = pstring[1,i-1] + "==" + pstring[i+1,size(pstring)-i];
+  }
+  else
+  { pstring = "{" + pstring + "}";}
+//  "mapping "; mapping;
+  if (mapping)
+  { xname = "s";
+    if (size(VARS)==2) {yname="t";}
+  }
+  else
+  { xname = varstr(VARS[1]);
+    if (size(VARS)==2) {yname=varstr(VARS[2]);}
+  }
+
+  j =1;
+
+  for(k=1;k<=size(#);k++)
+  { if (typeof(#[k])=="ideal" or typeof(#[k])=="poly")
+    { //#[k] = ideal(#[k]);
+      v = determvars(#[k]);
+      J = #[k];
+      short =0;
+      if (size(matrix(J))==1 and size(VARS)==2 and implcrv)
+      { i =size(J[1]);
+      //  J[2]=J[1][(i/ 2 + 1)..i];
+      //  J[1]=J[1][1..(i/ 2)];
+        J[2] =0;
+      }
+      if ((v!= VARS) or (size(J)!=size(I)))
+      { print("--Error: ---- ");
+        return();
+      }
+      else
+      { if (mapping)
+        { setring @r;
+          short =0;
+          actstring = string(phi(J));
+          setring(`basr`);
+        }
+        else {actstring = string(J);}
+        i = find(actstring,newline);
+        while(i)
+        { actstring[i]=" ";
+         i = find(actstring,newline,i);
+        }
+        if (implcrv)
+        {i = find(actstring,",");
+         actstring = actstring[1,i-1]+ "==" + actstring[i+1,size(actstring)-i];
+         pstring = pstring + "," + actstring;
+        }
+        else
+        { pstring = pstring + ",{" + actstring +"}";
+        }
+
+      }
+    }
+    if (typeof(#[k])=="string")
+    {  if (j==3) {zpart = #[k];j++;}
+       if (j==2) {ypart = #[k];j++;}
+       if (j==1) {xpart = #[k];j++;}
+   }
+  }
+
+ if (spacecurve or planecurve or implcrv)
+ { str = str + "{" + pstring + "},{" + xname + "," + xpart + "}";}
+ if (implcrv and (j==3)) {str = str + ",{" + yname + "," + ypart + "}";}
+ if (surface)
+ { str = str + "{" + pstring + "},{" + xname + "," + xpart + "},{"
+                                     + yname + "," + ypart + "}";}
+
+  if (planecurve) {closing = "," + newline +" AspectRatio->Automatic";}
+  if (implcrv) {closing = "," + newline +
+   " AxesLabel->{\"" + varstr(VARS[1]) + "\",\"" + varstr(VARS[2]) + "\"}";}
+  if (spacecurve) { closing = "," + newline + " ViewPoint->{1.3,-2.4,2}";}
+  if (surface)
+  {closing = "," +newline +
+              " Boxed->True, Axes->True, ViewPoint->{1.3,-2.4,2}";}
+
+  str = str + closing + "];" + endstr(fname);
+
+  return(str);
+}
+example
+{ "EXAMPLE:"; echo =2;
+   // ---------  plane curves ------------
+   ring rr0 = 0,x,dp; export rr0;
+
+   ideal I = x3 + x, x2;
+   ideal J = x2, -x+x3;
+   mplot("",I,J,"-2,2");
+
+ // Paste the output into a Mathematica notebook
+ // active evalutation of the cell with SHIFT RETURN
+
+ pause("Hit RETURN to continue");
+   // --------- space curves --------------
+   I = x3,-1/10x3+x2,x2;
+   mplot("",I);
+
+ // Paste the output into a Mathematica notebook
+ // active evalutation of the cell with SHIFT RETURN
+
+ pause("Hit RETURN to continue");
+   // ----------- surfaces -------------------
+   ring rr1 = 0,(x,y),dp; export rr1;
+   ideal J = xy,y,x2;
+   mplot("",J,"-2,1","1,2");
+
+ // Paste the output into a Mathematica notebook
+ // active evalutation of the cell with SHIFT RETURN
+ kill rr0,rr1;
+}
+///////////////////////////////////////////////////////////////////////////////
diff --git a/Singular/LIB/grobcov.lib b/Singular/LIB/grobcov.lib
new file mode 100644
index 0000000..155f815
--- /dev/null
+++ b/Singular/LIB/grobcov.lib
@@ -0,0 +1,4831 @@
+//////////////////////////////////////////////////////////////////////////////
+version="version grobcov.lib 4-0-0-0 Dec_2013 ";
+category="General purpose";
+info="
+LIBRARY:  grobcov.lib   Groebner Cover for parametric ideals.
+PURPOSE:  Comprehensive Groebner Systems, Groebner Cover, Canonical Forms,
+          Parametric Polynomial Systems.
+          The library contains Montes-Wibmer's algorithms to compute the
+          canonical Groebner cover of a parametric ideal as described in
+          the paper:
+
+          Montes A., Wibmer M.,
+          \"Groebner Bases for Polynomial Systems with parameters\".
+          Journal of Symbolic Computation 45 (2010) 1391-1425.
+          The locus algorithm and definitions will be
+          published in a forthcoming paper by Abanades, Botana, Montes, Recio:
+          \''An Algebraic Taxonomy for Locus Computation in Dynamic Geometry\''.
+
+          The central routine is grobcov. Given a parametric
+          ideal, grobcov outputs its Canonical Groebner Cover, consisting
+          of a set of pairs of (basis, segment). The basis (after
+          normalization) is the reduced Groebner basis for each point
+          of the segment. The segments are disjoint, locally closed
+          and correspond to constant lpp (leading power product)
+          of the basis, and are represented in canonical prime
+          representation. The segments are disjoint and cover the
+          whole parameter space. The output is canonical, it only
+          depends on the given parametric ideal and the monomial order.
+          This is much more than a simple Comprehensive Groebner System.
+          The algorithm grobcov allows options to solve partially the
+          problem when the whole automatic algorithm does not finish
+          in reasonable time.
+
+          grobcov uses a first algorithm cgsdr that outputs a disjoint
+          reduced Comprehensive Groebner System with constant lpp.
+          For this purpose, in this library, the implemented algorithm is
+          Kapur-Sun-Wang algorithm, because it is the most efficient
+          algorithm known for this purpose.
+
+          D. Kapur, Y. Sun, and D.K. Wang.
+          \"A New Algorithm for Computing Comprehensive Groebner Systems\".
+          Proceedings of ISSAC'2010, ACM Press, (2010), 29-36.
+
+          cgsdr can be called directly if only a disjoint reduced
+          Comprehensive Groebner System (CGS) is required.
+
+AUTHORS:  Antonio Montes , Hans Schoenemann.
+OVERVIEW: see \"Groebner Bases for Polynomial Systems with parameters\"
+          Montes A., Wibmer M.,
+          Journal of Symbolic Computation 45 (2010) 1391-1425.
+          (http://www-ma2.upc.edu/~montes/).
+
+NOTATIONS: All given and determined polynomials and ideals are in the
+@*         basering Q[a][x]; (a=parameters, x=variables)
+@*         After defining the ring, the main routines
+@*         grobcov, cgsdr,
+@*         generate the global rings
+@*         @R   (Q[a][x]),
+@*         @P   (Q[a]),
+@*         @RP  (Q[x,a])
+@*         that are used inside and killed before the output.
+@*         If you want to use some internal routine you must
+@*         create before the above rings by calling setglobalrings();
+@*         because most of the internal routines use these rings.
+@*         The call to the basic routines grobcov, cgsdr will
+@*         kill these rings.
+
+PROCEDURES:
+
+grobcov(F);  Is the basic routine giving the canonical
+                   Groebner cover of the parametric ideal F.
+                   This routine accepts many options, that
+                   allow to obtain results even when the canonical
+                   computation does not finish in reasonable time.
+
+cgsdr(F);      Is the procedure for obtaining a first disjoint,
+                   reduced Comprehensive Groebner System that
+                   is used in grobcov, that can also be used
+                   independently if only the CGS is required.
+                   It is a more efficient routine than buildtree
+                   (the own routine that is no more used). It uses
+                   now KSW algorithm.
+
+setglobalrings();  Generates the global rings @R, @P and @PR that are
+                   respectively the rings Q[a][x], Q[a], Q[x,a].
+                   It is called inside each of the fundamental routines
+                   of the library: grobcov, cgsdr, locus, locusdg and killed before
+                   the output.
+                   So, if the user want to use some other internal routine,
+                   then setglobalrings() is to be called before, as most of them use
+                   these rings.
+
+pdivi(f,F);     Performs a pseudodivision of a parametric polynomial
+                   by a parametric ideal.
+                   Can be used without calling presiouly setglobalrings(),
+
+pnormalf(f,E,N);   Reduces a parametric polynomial f over V(E) \ V(N)
+                   E is the null ideal and N the non-null ideal
+                   over the parameters.
+                   Can be used without calling presiouly setglobalrings(),
+
+Prep(N,M);   Computes the P-representation of V(N) \ V(M).
+                   Can be used without calling previously setglobalrings().
+
+extend(GC); When the grobcov of an ideal has been computed
+                   with the default option ('ext',0) and the explicit
+                   option ('rep',2) (which is not the default), then
+                   one can call extend (GC) (and options) to obtain the
+                   full representation of the bases. With the default
+                   option ('ext',0) only the generic representation of
+                   the bases are computed, and one can obtain the full
+                   representation using extend.
+                   Can be used without calling presiouly setglobalrings(),
+
+locus(G):     Special routine for determining the locus of points
+                   of  objects. Given a parametric ideal J with
+                   parameters (a_1,..a_m) and variables (x_1,..,xn),
+                   representing the system determining
+                   the locus of points (a_1,..,a_m)) who verify certain
+                   properties, computing the grobcov G of
+                   J and applying to it locus, determines the different
+                   classes of locus components. They can be
+                   Normal, Special, Accumulation point, Degenerate.
+                   The output are the components given in P-canonical form
+                   of two constructible sets: Normal, and Non-Normal
+                   The Normal Set has Normal and Special components
+                   The Non-Normal set has Accumulation and Degenerate components.
+                   The description of the algorithm and definitions will be
+                   given in a forthcoming paper by Abanades, Botana, Montes, Recio:
+                   ''An Algebraic Taxonomy for Locus Computation in Dynamic Geometry''.
+                   Can be used without calling presiouly setglobalrings(),
+
+locusdg(G):  Is a special routine for computing the locus in dinamical geometry.
+                    It detects automatically a possible point that is to be avoided by the mover,
+                    whose coordinates must be the last two coordinates in the definition of the ring.
+                    If such a point is detected, then it eliminates the segments of the grobcov
+                    depending on the point that is to be avoided.
+                    Then it calls locus.
+                    Can be used without calling presiouly setglobalrings(),
+
+locusto(L):  Transforms the output of locus to a string that
+                  can be reed from different computational systems.
+                  Can be used without calling presiouly setglobalrings(),
+
+addcons(L): Given a disjoint set of locally closed subsets in P-representation,
+                  it returns the canonical P-representation of the constructible set
+                  formed by the union of them.
+                  Can be used without calling presiouly setglobalrings(),
+
+SEE ALSO: compregb_lib
+";
+
+LIB "primdec.lib";
+LIB "qhmoduli.lib";
+
+// ************ Begin of the grobcov library *********************
+
+// Library grobcov.lib
+// (Groebner cover):
+// Release 1: (public)
+// Initial data: 21-1-2008
+// Final data: 3-7-2008
+// Release 2: (private)
+// Initial data: 6-9-2009
+// Final data: 25-10-2011
+// Release 3:
+// Initial data: 1-7-2012
+// Final data: 4-9-2012
+// Release 4: (this release, public)
+// Initial data: 4-9-2012
+// Final data: 21-11-2013
+// basering Q[a][x];
+
+// ************ Begin of buildtree ******************************
+
+proc setglobalrings()
+"USAGE:   setglobalrings();
+          No arguments
+RETURN:   After its call the rings @R=Q[a][x], @P=Q[a], @RP=Q[x,a] are
+          defined as global variables.
+NOTE: It is called internally by the fundamental routines of the
+          library grobcov, cgsdr, extend, pdivi, pnormalf, locus, locusdg, locusto,
+          and killed before the output.
+          The user does not need to call it, except when it is interested
+          in using some internal routine of the library that
+          uses these rings.
+          The basering R, must be of the form Q[a][x], a=parameters,
+          x=variables, and should be defined previously.
+KEYWORDS: ring, rings
+EXAMPLE:  setglobalrings; shows an example"
+{
+  if (defined(@P))
+  {
+    kill @P; kill @R; kill @RP;
+  }
+  def RR=basering;
+  def @R=basering;  // must be of the form K[a][x], a=parameters, x=variables
+  list Rx=ringlist(RR);
+  def @P=ring(Rx[1]);
+  list Lx;
+  Lx[1]=0;
+  Lx[2]=Rx[2]+Rx[1][2];
+  Lx[3]=Rx[1][3];
+  Lx[4]=Rx[1][4];
+  Rx[1]=0;
+  def D=ring(Rx);
+  def @RP=D+ at P;
+  export(@R);      // global ring K[a][x]
+  export(@P);      // global ring K[a]
+  export(@RP);     // global ring K[x,a] with product order
+  setring(RR);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring R=(0,a,b),(x,y,z),dp;
+  setglobalrings();
+  Grobcov::@R;
+  Grobcov::@P;
+  Grobcov::@RP;
+ringlist(Grobcov::@R);
+ringlist(Grobcov::@P);
+ringlist(Grobcov::@RP);
+}
+
+//*************Auxiliary routines**************
+
+// cld : clears denominators of an ideal and normalizes to content 1
+//        can be used in @R or @P or @RP
+// input:
+//        ideal J (J can be also poly), but the output is an ideal;
+// output:
+//        ideal Jc (the new form of ideal J without denominators and
+//        normalized to content 1)
+proc cld(ideal J)
+{
+  if (size(J)==0){return(ideal(0));}
+  int te=0;
+  def RR=basering;
+  if(not(defined(@RP)))
+  {
+    te=1;
+    setglobalrings();
+  }
+  setring(@RP);
+  def Ja=imap(RR,J);
+  ideal Jb;
+  if (size(Ja)==0){setring(RR); return(ideal(0));}
+  int i;
+  def j=0;
+  for (i=1;i<=ncols(Ja);i++){if (size(Ja[i])!=0){j++; Jb[j]=cleardenom(Ja[i]);}}
+  setring(RR);
+  def Jc=imap(@RP,Jb);
+  if(te){kill @R; kill @RP; kill @P;}
+  return(Jc);
+}
+
+proc memberpos(f,J)
+//"USAGE:  memberpos(f,J);
+//         (f,J) expected (polynomial,ideal)
+//               or       (int,list(int))
+//               or       (int,intvec)
+//               or       (intvec,list(intvec))
+//               or       (list(int),list(list(int)))
+//               or       (ideal,list(ideal))
+//               or       (list(intvec),  list(list(intvec))).
+//         The ring can be @R or @P or @RP or any other.
+//RETURN:  The list (t,pos) t int; pos int;
+//         t is 1 if f belongs to J and 0 if not.
+//         pos gives the position in J (or 0 if f does not belong).
+//EXAMPLE: memberpos; shows an example"
+{
+  int pos=0;
+  int i=1;
+  int j;
+  int t=0;
+  int nt;
+  if (typeof(J)=="ideal"){nt=ncols(J);}
+  else{nt=size(J);}
+  if ((typeof(f)=="poly") or (typeof(f)=="int"))
+  { // (poly,ideal)  or
+    // (poly,list(poly))
+    // (int,list(int)) or
+    // (int,intvec)
+    i=1;
+    while(i<=nt)
+    {
+      if (f==J[i]){return(list(1,i));}
+      i++;
+    }
+    return(list(0,0));
+  }
+  else
+  {
+    if ((typeof(f)=="intvec") or ((typeof(f)=="list") and (typeof(f[1])=="int")))
+    { // (intvec,list(intvec)) or
+      // (list(int),list(list(int)))
+      i=1;
+      t=0;
+      pos=0;
+      while((i<=nt) and (t==0))
+      {
+        t=1;
+        j=1;
+        if (size(f)!=size(J[i])){t=0;}
+        else
+        {
+          while ((j<=size(f)) and t)
+          {
+            if (f[j]!=J[i][j]){t=0;}
+            j++;
+          }
+        }
+        if (t){pos=i;}
+        i++;
+      }
+      if (t){return(list(1,pos));}
+      else{return(list(0,0));}
+    }
+    else
+    {
+      if (typeof(f)=="ideal")
+      { // (ideal,list(ideal))
+        i=1;
+        t=0;
+        pos=0;
+        while((i<=nt) and (t==0))
+        {
+          t=1;
+          j=1;
+          if (ncols(f)!=ncols(J[i])){t=0;}
+          else
+          {
+            while ((j<=ncols(f)) and t)
+            {
+              if (f[j]!=J[i][j]){t=0;}
+              j++;
+            }
+          }
+          if (t){pos=i;}
+          i++;
+        }
+        if (t){return(list(1,pos));}
+        else{return(list(0,0));}
+      }
+      else
+      {
+        if ((typeof(f)=="list") and (typeof(f[1])=="intvec"))
+        { // (list(intvec),list(list(intvec)))
+          i=1;
+          t=0;
+          pos=0;
+          while((i<=nt) and (t==0))
+          {
+            t=1;
+            j=1;
+            if (size(f)!=size(J[i])){t=0;}
+            else
+            {
+              while ((j<=size(f)) and t)
+              {
+                if (f[j]!=J[i][j]){t=0;}
+                j++;
+              }
+            }
+            if (t){pos=i;}
+            i++;
+          }
+          if (t){return(list(1,pos));}
+          else{return(list(0,0));}
+        }
+      }
+    }
+  }
+}
+//example
+//{ "EXAMPLE:"; echo = 2;
+//  list L=(7,4,5,1,1,4,9);
+//  memberpos(1,L);
+//}
+
+proc subset(J,K)
+//"USAGE:   subset(J,K);
+//          (J,K)  expected (ideal,ideal)
+//                  or     (list, list)
+//RETURN:   1 if all the elements of J are in K, 0 if not.
+//EXAMPLE:  subset; shows an example;"
+{
+  int i=1;
+  int nt;
+  if (typeof(J)=="ideal"){nt=ncols(J);}
+  else{nt=size(J);}
+  if (size(J)==0){return(1);}
+  while(i<=nt)
+  {
+    if (memberpos(J[i],K)[1]){i++;}
+    else {return(0);}
+  }
+  return(1);
+}
+//example
+//{ "EXAMPLE:"; echo = 2;
+//  list J=list(7,3,2);
+//  list K=list(1,2,3,5,7,8);
+//  subset(J,K);
+//}
+
+// elimintfromideal: elimine the constant numbers from an ideal
+//        (designed for W, nonnull conditions)
+// input: ideal J
+// output:ideal K with the elements of J that are non constants, in the
+//        ring @P
+proc elimintfromideal(ideal J)
+{
+  int i;
+  int j=0;
+  ideal K;
+  if (size(J)==0){return(ideal(0));}
+  for (i=1;i<=ncols(J);i++){if (size(variables(J[i])) !=0){j++; K[j]=J[i];}}
+  return(K);
+}
+
+// simpqcoeffs : simplifies a quotient of two polynomials
+// input: two coeficients (or terms), that are considered as a quotient
+// output: the two coeficients reduced without common factors
+proc simpqcoeffs(poly n,poly m)
+{
+  number nc=content(n);
+  number mc=content(m);
+  number gc=gcd(nc,mc);
+  ideal s=n/gc,m/gc;
+  return (s);
+}
+
+// pdivi : pseudodivision of a parametric polynomial f by a parametric ideal F in Q[a][x].
+// input:
+//   poly  f
+//   ideal F
+// output:
+//   list (poly r, ideal q, poly mu)
+proc pdivi(poly f,ideal F)
+"USAGE:   pdivi(f,F);
+          poly f: the polynomial to be divided
+          ideal F: the divisor ideal
+RETURN:   A list (poly r, ideal q, poly m). r is the remainder of the
+          pseudodivision, q is the set of quotients, and m is the
+          coefficient factor by which f is to be multiplied.
+NOTE:     pseudodivision of a poly f by an ideal F in @R. Returns a
+          list (r,q,m) such that m*f=r+sum(q.G), and no lpp of a divisor
+          divides a pp of r.
+KEYWORDS: division, reduce
+EXAMPLE:  pdivi; shows an example"
+{
+  int i;
+  int j;
+//  string("T_f=",f);
+  poly v=1;
+  for(i=1;i<=nvars(basering);i++){v=v*var(i);}
+  int te=0;
+  def R=basering;
+  if (defined(@P)==1){te=1;}
+  else{setglobalrings();}
+  poly r=0;
+  poly mu=1;
+  def p=f;
+  ideal q;
+  for (i=1; i<=size(F); i++){q[i]=0;};
+  ideal lpf;
+  ideal lcf;
+  for (i=1;i<=size(F);i++){lpf[i]=leadmonom(F[i]);}
+  for (i=1;i<=size(F);i++){lcf[i]=leadcoef(F[i]);}
+  poly lpp;
+  poly lcp;
+  poly qlm;
+  poly nu;
+  poly rho;
+  int divoc=0;
+  ideal qlc;
+  while (p!=0)
+  {
+    i=1;
+    divoc=0;
+    lpp=leadmonom(p);
+    lcp=leadcoef(p);
+    while (divoc==0 and i<=size(F))
+    {
+      qlm=lpp/lpf[i];
+      if (qlm!=0)
+      {
+        qlc=simpqcoeffs(lcp,lcf[i]);
+        nu=qlc[2];
+        mu=mu*nu;
+        rho=qlc[1]*qlm;
+        p=nu*p-rho*F[i];
+//        string("i=",i,"  coef(p,v)=",coef(p,v));
+        r=nu*r;
+        for (j=1;j<=size(F);j++){q[j]=nu*q[j];}
+        q[i]=q[i]+rho;
+        divoc=1;
+      }
+      else {i++;}
+    }
+    if (divoc==0)
+    {
+      r=r+lcp*lpp;
+      p=p-lcp*lpp;
+//      string("pasa al rem p=",p);
+    }
+  }
+  list res=r,q,mu;
+  if(te==0){kill @P; kill @R; kill @RP;}
+  return(res);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring R=(0,a,b,c),(x,y),dp;
+  "Divisor=";
+  poly f=(ab-ac)*xy+(ab)*x+(5c);
+  "Dividends=";
+  ideal F=ax+b,cy+a;
+  "(Remainder, quotients, factor)=";
+  def r=pdivi(f,F);
+  r;
+  "Verifying the division: r[3]*f-(r[2][1]*F[1]+r[2][2]*F[2])-r[1] =";
+  r[3]*f-(r[2][1]*F[1]+r[2][2]*F[2])-r[1];
+}
+
+// pspol : S-poly of two polynomials in @R
+// @R
+// input:
+//   poly f (given in the ring @R)
+//   poly g (given in the ring @R)
+// output:
+//   list (S, red):  S is the S-poly(f,g) and red is a Boolean variable
+//                if red then S reduces by Buchberger 1st criterion
+//                (not used)
+proc pspol(poly f,poly g)
+{
+  def lcf=leadcoef(f);
+  def lcg=leadcoef(g);
+  def lpf=leadmonom(f);
+  def lpg=leadmonom(g);
+  def v=gcd(lpf,lpg);
+  def s=simpqcoeffs(lcf,lcg);
+  def vf=lpf/v;
+  def vg=lpg/v;
+  poly S=s[2]*vg*f-s[1]*vf*g;
+  return(S);
+}
+
+// facvar: Returns all the free-square factors of the elements
+//         of ideal J (non repeated). Integer factors are ignored,
+//         even 0 is ignored. It can be called from ideal @R, but
+//         the given ideal J must only contain poynomials in the
+//         parameters.
+//         Operates in the ring @P, but can be called from ring @R,
+//         and the ideal @P must be defined calling first setglobalrings();
+// input:  ideal J
+// output: ideal Jc: Returns all the free-square factors of the elements
+//         of ideal J (non repeated). Integer factors are ignored,
+//         even 0 is ignored. It can be called from ideal @R.
+proc facvar(ideal J)
+//"USAGE:   facvar(J);
+//          J: an ideal in the parameters
+//RETURN:   all the free-square factors of the elements
+//          of ideal J (non repeated). Integer factors are ignored,
+//          even 0 is ignored. It can be called from ideal @R, but
+//          the given ideal J must only contain poynomials in the
+//          parameters.
+//NOTE:     Operates in the ring @P, and the ideal J must contain only
+//          polynomials in the parameters, but can be called from ring @R.
+//KEYWORDS: factor
+//EXAMPLE:  facvar; shows an example"
+{
+  int i;
+  def RR=basering;
+  setring(@P);
+  def Ja=imap(RR,J);
+  if(size(Ja)==0){setring(RR); return(ideal(0));}
+  Ja=elimintfromideal(Ja); // also in ideal @P
+  ideal Jb;
+  if (size(Ja)==0){Jb=ideal(0);}
+  else
+  {
+    for (i=1;i<=ncols(Ja);i++){if(size(Ja[i])!=0){Jb=Jb,factorize(Ja[i],1);}}
+    Jb=simplify(Jb,2+4+8);
+    Jb=cld(Jb);
+    Jb=elimintfromideal(Jb); // also in ideal @P
+  }
+  setring(RR);
+  def Jc=imap(@P,Jb);
+  return(Jc);
+}
+//example
+//{ "EXAMPLE:"; echo = 2;
+//  ring R=(0,a,b,c),(x,y,z),dp;
+//  setglobalrings();
+//  ideal J=a2-b2,a2-2ab+b2,abc-bc;
+//  facvar(J);
+//}
+
+// Ered: eliminates the factors in the polynom f that are non-null.
+//       In ring @R
+// input:
+//   poly f:
+//   ideal E  of null-conditions
+//   ideal N  of non-null conditions
+//        (E,N) represents V(E)\V(N),
+//        Ered eliminates the non-null factors of f in V(E)\V(N)
+// output:
+//   poly f2  where the non-null conditions have been dropped from f
+proc Ered(poly f,ideal E, ideal N)
+{
+  def RR=basering;
+  setring(@R);
+  poly ff=imap(RR,f);
+  ideal EE=imap(RR,E);
+  ideal NN=imap(RR,N);
+  if((ff==0) or (equalideals(NN,ideal(1)))){setring(RR); return(f);}
+  def v=variables(ff);
+  int i;
+  poly X=1;
+  for(i=1;i<=size(v);i++){X=X*v[i];}
+  matrix M=coef(ff,X);
+  setring(@P);
+  def RPE=imap(@R,EE);
+  def RPN=imap(@R,NN);
+  matrix Mp=imap(@R,M);
+  poly g=Mp[2,1];
+  if (size(Mp)!=2)
+  {
+    for(i=2;i<=size(Mp) div 2;i++)
+    {
+      g=gcd(g,Mp[2,i]);
+    }
+  }
+  if (g==1){setring(RR); return(f);}
+  else
+  {
+    def wg=factorize(g,2);
+    if (wg[1][1]==1){setring(RR); return(f);}
+    else
+    {
+      poly simp=1;
+      int te;
+      for(i=1;i<=size(wg[1]);i++)
+      {
+        te=inconsistent(RPE+wg[1][i],RPN);
+        if(te)
+        {
+          simp=simp*(wg[1][i])^(wg[2][i]);
+        }
+      }
+    }
+    if (simp==1){setring(RR); return(f);}
+    else
+    {
+      setring(RR);
+      def simp0=imap(@P,simp);
+      def f2=f/simp0;
+      return(f2);
+    }
+  }
+}
+
+// pnormalf: reduces a polynomial f wrt a V(E)\V(N)
+//           dividing by E and eliminating factors in N.
+//           called in the ring @R,
+//           operates in the ring @RP.
+// input:
+//         poly  f
+//         ideal E  (depends only on the parameters)
+//         ideal N  (depends only on the parameters)
+//                  (E,N) represents V(E)\V(N)
+//         optional:
+// output: poly f2 reduced wrt to V(E)\V(N)
+proc pnormalf(poly f, ideal E, ideal N)
+"USAGE:   pnormalf(f,E,N);
+          f: the polynomial to be reduced modulo V(E)\V(N)
+          of a segment in the parameters.
+          E: the null conditions ideal
+          N: the non-null conditions
+RETURN:   a reduced polynomial g of f, whose coefficients are reduced
+          modulo E and having no factor in N.
+NOTE: Should be called from ring Q[a][x].
+          Ideals E and N must be given by polynomials
+          in the parameters.
+KEYWORDS: division, pdivi, reduce
+EXAMPLE:  pnormalf; shows an example"
+{
+    def RR=basering;
+    int te=0;
+    if (defined(@P)){te=1;}
+    else{setglobalrings();}
+    setring(@RP);
+    def fa=imap(RR,f);
+    def Ea=imap(RR,E);
+    def Na=imap(RR,N);
+    option(redSB);
+    Ea=std(Ea);
+    def r=cld(reduce(fa,Ea));
+    poly f1=r[1];
+    f1=Ered(r[1],Ea,Na);
+    setring(RR);
+    def f2=imap(@RP,f1);
+    if(te==0){kill @R; kill @RP; kill @P;}
+    return(f2)
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring R=(0,a,b,c),(x,y),dp;
+  poly f=(b^2-1)*x^3*y+(c^2-1)*x*y^2+(c^2*b-b)*x+(a-bc)*y;
+  ideal E=(c-1);
+  ideal N=a-b;
+  pnormalf(f,E,N);
+}
+
+// idint: ideal intersection
+//        in the ring @P.
+//        it works in an extended ring
+// input: two ideals in the ring @P
+// output the intersection of both (is not a GB)
+proc idint(ideal I, ideal J)
+{
+  def RR=basering;
+  ring T=0,t,lp;
+  def K=T+RR;
+  setring(K);
+  def Ia=imap(RR,I);
+  def Ja=imap(RR,J);
+  ideal IJ;
+  int i;
+  for(i=1;i<=size(Ia);i++){IJ[i]=t*Ia[i];}
+  for(i=1;i<=size(Ja);i++){IJ[size(Ia)+i]=(1-t)*Ja[i];}
+  ideal eIJ=eliminate(IJ,t);
+  setring(RR);
+  return(imap(K,eIJ));
+}
+
+// lesspol: compare two polynomials by its leading power products
+// input:  two polynomials f,g in the ring @R
+// output: 0 if f<g,  1 if f>=g
+proc lesspol(poly f, poly g)
+{
+  if (leadmonom(f)<leadmonom(g)){return(1);}
+  else
+  {
+    if (leadmonom(g)<leadmonom(f)){return(0);}
+    else
+    {
+      if (leadcoef(f)<leadcoef(g)){return(1);}
+      else {return(0);}
+    }
+  }
+}
+
+// delfromideal: deletes the i-th polynomial from the ideal F
+proc delfromideal(ideal F, int i)
+{
+  int j;
+  ideal G;
+  if (size(F)<i){ERROR("delfromideal was called incorrect arguments");}
+  if (size(F)<=1){return(ideal(0));}
+  if (i==0){return(F)};
+  for (j=1;j<=size(F);j++)
+  {
+    if (j!=i){G[size(G)+1]=F[j];}
+  }
+  return(G);
+}
+
+// delidfromid: deletes the polynomials in J that are in I
+// input: ideals I,J
+// output: the ideal J without the polynomials in I
+proc delidfromid(ideal I, ideal J)
+{
+  int i; list r;
+  ideal JJ=J;
+  for (i=1;i<=size(I);i++)
+  {
+    r=memberpos(I[i],JJ);
+    if (r[1])
+    {
+      JJ=delfromideal(JJ,r[2]);
+    }
+  }
+  return(JJ);
+}
+
+// sortideal: sorts the polynomials in an ideal by lm in ascending order
+proc sortideal(ideal Fi)
+{
+  def RR=basering;
+  setring(@RP);
+  def F=imap(RR,Fi);
+  def H=F;
+  ideal G;
+  int i;
+  int j;
+  poly p;
+  while (size(H)!=0)
+  {
+    j=1;
+    p=H[1];
+    for (i=1;i<=size(H);i++)
+    {
+      if(lesspol(H[i],p)){j=i;p=H[j];}
+    }
+    G[size(G)+1]=p;
+    H=delfromideal(H,j);
+  }
+  setring(RR);
+  def GG=imap(@RP,G);
+  return(GG);
+}
+
+// mingb: given a basis (gb reducing) it
+// order the polynomials is ascending order and
+// eliminates the polynomials whose lpp are divisible by some
+// smaller one
+proc mingb(ideal F)
+{
+  int t; int i; int j;
+  def H=sortideal(F);
+  ideal G;
+  if (ncols(H)<=1){return(H);}
+  G=H[1];
+  for (i=2; i<=ncols(H); i++)
+  {
+    t=1;
+    j=1;
+    while (t and (j<i))
+    {
+      if((leadmonom(H[i])/leadmonom(H[j]))!=0) {t=0;}
+      j++;
+    }
+    if (t) {G[size(G)+1]=H[i];}
+  }
+  return(G);
+}
+
+// redgbn: given a minimal basis (gb reducing) it
+// reduces each polynomial wrt to V(E) \ V(N)
+proc redgbn(ideal F, ideal E, ideal N)
+{
+  int te=0;
+  if (defined(@P)==1){te=1;}
+  ideal G=F;
+  ideal H;
+  int i;
+  if (size(G)==0){return(ideal(0));}
+  for (i=1;i<=size(G);i++)
+  {
+    H=delfromideal(G,i);
+    G[i]=pnormalf(pdivi(G[i],H)[1],E,N);
+    G[i]=primepartZ(G[i]);
+  }
+  if(te==1){setglobalrings();}
+  return(G);
+}
+
+// eliminates repeated elements form an ideal or matrix or module or intmat or bigintmat
+proc elimrepeated(F)
+{
+  int i;
+  int nt;
+  if (typeof(F)=="ideal"){nt=ncols(F);}
+  else{nt=size(F);}
+
+  def FF=F;
+  FF=F[1];
+  for (i=2;i<=nt;i++)
+  {
+    if (not(memberpos(F[i],FF)[1]))
+    {
+      FF[size(FF)+1]=F[i];
+    }
+  }
+  return(FF);
+}
+
+proc elimrepeatedvl(F)
+{
+  int i;
+  def FF=F;
+  FF=F[1];
+  for (i=2;i<=size(F);i++)
+  {
+    if (not(memberpos(F[i],FF)[1]))
+    {
+      FF[size(FF)+1]=F[i];
+    }
+  }
+  return(FF);
+}
+
+
+// equalideals
+// input: 2 ideals F and G;
+// output: 1 if they are identical (the same polynomials in the same order)
+//         0 else
+proc equalideals(ideal F, ideal G)
+{
+  int i=1; int t=1;
+  if (size(F)!=size(G)){return(0);}
+  while ((i<=size(F)) and (t))
+  {
+    if (F[i]!=G[i]){t=0;}
+    i++;
+  }
+  return(t);
+}
+
+// delintvec
+// input: intvec V
+//        int i
+// output:
+//        intvec W (equal to V but the coordinate i is deleted
+proc delintvec(intvec V, int i)
+{
+  int j;
+  intvec W;
+  for (j=1;j<i;j++){W[j]=V[j];}
+  for (j=i+1;j<=size(V);j++){W[j-1]=V[j];}
+  return(W);
+}
+
+//**************Begin homogenizing************************
+
+// ishomog:
+// Purpose: test if a polynomial is homogeneous in the variables or not
+// input:  poly f
+// output  1 if f is homogeneous, 0 if not
+proc ishomog(f)
+{
+  int i; poly r; int d; int dr;
+  if (f==0){return(1);}
+  d=deg(f); dr=d; r=f;
+  while ((d==dr) and (r!=0))
+  {
+    r=r-lead(r);
+    dr=deg(r);
+  }
+  if (r==0){return(1);}
+  else{return(0);}
+}
+
+// postredgb: given a minimal basis (gb reducing) it
+// reduces each polynomial wrt to the others
+proc postredgb(ideal F)
+{
+  int te=0;
+  if(defined(@P)==1){te=1;}
+  ideal G;
+  ideal H;
+  int i;
+  if (size(F)==0){return(ideal(0));}
+  for (i=1;i<=size(F);i++)
+  {
+    H=delfromideal(F,i);
+    G[i]=pdivi(F[i],H)[1];
+  }
+  if(te==1){setglobalrings();}
+  return(G);
+}
+
+//purpose ideal intersection called in @R and computed in @P
+proc idintR(ideal N, ideal M)
+{
+  def RR=basering;
+  setring(@P);
+  def Np=imap(RR,N);
+  def Mp=imap(RR,M);
+  def Jp=idint(Np,Mp);
+  setring(RR);
+  return(imap(@P,Jp));
+}
+
+//purpose reduced Groebner basis called in @R and computed in @P
+proc gbR(ideal N)
+{
+  def RR=basering;
+  setring(@P);
+  def Np=imap(RR,N);
+  option(redSB);
+  Np=std(Np);
+  setring(RR);
+  return(imap(@P,Np));
+}
+
+//**************End homogenizing************************
+
+//**************Begin of Groebner Cover*****************
+
+// incquotient
+// incremental quotient
+// Input: ideal N: a Groebner basis of an ideal
+//        poly f:
+// Output: Na = N:<f>
+proc incquotient(ideal N, poly f)
+{
+  poly g; int i;
+  ideal Nb; ideal Na=N;
+  if (size(Na)==1)
+  {
+    g=gcd(Na[1],f);
+    if (g!=1)
+    {
+      Na[1]=Na[1]/g;
+    }
+    attrib(Na,"IsSB",1);
+    return(Na);
+  }
+  def P=basering;
+  poly @t;
+  ring H=0, at t,lp;
+  def HP=H+P;
+  setring(HP);
+  def fh=imap(P,f);
+  def Nh=imap(P,N);
+  ideal Nht;
+  for (i=1;i<=size(Nh);i++)
+  {
+    Nht[i]=Nh[i]*@t;
+  }
+  attrib(Nht,"isSB",1);
+  def fht=(1- at t)*fh;
+  option(redSB);
+  Nht=std(Nht,fht);
+  ideal Nc; ideal v;
+  for (i=1;i<=size(Nht);i++)
+  {
+    v=variables(Nht[i]);
+    if(memberpos(@t,v)[1]==0)
+    {
+      Nc[size(Nc)+1]=Nht[i]/fh;
+    }
+  }
+  setring(P);
+  ideal HH;
+  def Nd=imap(HP,Nc); Nb=Nd;
+  option(redSB);
+  Nb=std(Nd);
+  return(Nb);
+}
+
+// eliminates the ith element from a list or an intvec
+proc elimfromlist(def l, int i)
+{
+  if(typeof(l)=="list"){list L;}
+  if (typeof(l)=="intvec"){intvec L;}
+  if (typeof(l)=="ideal"){ideal L;}
+  int j;
+  if((size(l)==0) or (size(l)==1 and i!=1)){return(l);}
+  if (size(l)==1 and i==1){return(L);}
+  // L=l[1];
+  if(i==1)
+  {
+    for(j=2;j<=size(l);j++)
+    {
+      L[j-1]=l[j];
+    }
+  }
+  else
+  {
+    for(j=1;j<=i-1;j++)
+    {
+      L[j]=l[j];
+    }
+    for(j=i+1;j<=size(l);j++)
+    {
+      L[j-1]=l[j];
+    }
+  }
+  return(L);
+}
+
+// Auxiliary routine to define an order for ideals
+// Returns 1 if the ideal a is shoud precede ideal b by sorting them in idbefid order
+//             2 if the the contrary happen
+//             0 if the order is not relevant
+proc idbefid(ideal a, ideal b)
+{
+  poly fa; poly fb; poly la; poly lb;
+  int te=1; int i; int j;
+  int na=size(a);
+  int nb=size(b);
+  int nm;
+  if (na<=nb){nm=na;} else{nm=nb;}
+  for (i=1;i<=nm; i++)
+  {
+    fa=a[i]; fb=b[i];
+    while((fa!=0) or (fb!=0))
+    {
+      la=lead(fa);
+      lb=lead(fb);
+      fa=fa-la;
+      fb=fb-lb;
+      la=leadmonom(la);
+      lb=leadmonom(lb);
+      if(leadmonom(la+lb)!=la){return(1);}
+      else{if(leadmonom(la+lb)!=lb){return(2);}}
+    }
+  }
+  if(na<nb){return(1);}
+  else
+  {
+    if(na>nb){return(2);}
+    else{return(0);}
+  }
+}
+
+// sort a list of ideals using idbefid
+proc sortlistideals(list L)
+{
+  int i; int j; int n;
+  ideal a; ideal b;
+  list LL=L;
+  list NL;
+  int k; int te;
+  i=1;
+  while(size(LL)>0)
+  {
+    k=1;
+    for(j=2;j<=size(LL);j++)
+    {
+      te=idbefid(LL[k],LL[j]);
+      if (te==2){k=j;}
+    }
+    NL[size(NL)+1]=LL[k];
+    n=size(LL);
+    if (n>1){LL=elimfromlist(LL,k);} else{LL=list();}
+  }
+  return(NL);
+}
+
+// returns 1 if the two lists of ideals are equal and 0 if not
+proc equallistideals(list L, list M)
+{
+  int t; int i;
+  if (size(L)!=size(M)){return(0);}
+  else
+  {
+    t=1;
+    if (size(L)>0)
+    {
+      i=1;
+      while ((t) and (i<=size(L)))
+      {
+        if (equalideals(L[i],M[i])==0){t=0;}
+        i++;
+      }
+    }
+    return(t);
+  }
+}
+
+// Prep
+// Computes the P-representation of V(N) \ V(M).
+// input:
+//    ideal N (null ideal) (not necessarily radical nor maximal)
+//    ideal M (hole ideal) (not necessarily containing N)
+// output:
+//    the ((p_1,(p_11,p_1k_1)),..,(p_r,(p_r1,p_rk_r)));
+//    the Prep of V(N)\V(M)
+// Assumed to work in the ring @P of the parameters
+// Can be used without calling previously setglobalrings().
+proc Prep(ideal N, ideal M)
+{
+  int te;
+  if (N[1]==1)
+  {
+    return(list(list(ideal(1),list(ideal(1)))));
+  }
+  def RR=basering;
+  if(defined(@P)){te=1;}
+  else{te=0; setglobalrings();}
+  setring(@P);
+  ideal Np=imap(RR,N);
+  ideal Mp=imap(RR,M);
+  int i; int j; list L0;
+
+  list Ni=minGTZ(Np);
+  list prep;
+  for(j=1;j<=size(Ni);j++)
+  {
+    option(redSB);
+    Ni[j]=std(Ni[j]);
+  }
+  list Mij;
+  for (i=1;i<=size(Ni);i++)
+  {
+    Mij=minGTZ(Ni[i]+Mp);
+    for(j=1;j<=size(Mij);j++)
+    {
+      option(redSB);
+      Mij[j]=std(Mij[j]);
+    }
+    if ((size(Mij)==1) and (equalideals(Ni[i],Mij[1])==1)){;}
+    else
+    {
+        prep[size(prep)+1]=list(Ni[i],Mij);
+    }
+  }
+  if (size(prep)==0){prep=list(list(ideal(1),list(ideal(1))));}
+  setring(RR);
+  def pprep=imap(@P,prep);
+  if(te==0){kill @P; kill @R; kill @RP;}
+  return(pprep);
+}
+
+// PtoCrep
+// Computes the C-representation from the P-representation.
+// input:
+//    list ((p_1,(p_11,p_1k_1)),..,(p_r,(p_r1,p_rk_r)));
+//         the P-representation of V(N)\V(M)
+// output:
+//    list (ideal ida, ideal idb)
+//    the C-representaion of V(N)\V(M) = V(ida)\V(idb)
+// Assumed to work in the ring @P of the parameters
+// If the routine is to be called from the top, a previous call to
+// setglobalrings() is needed.
+proc PtoCrep(list L)
+{
+  int te=0;
+  def RR=basering;
+  if(defined(@P)){te=1;}
+  else{te=0; setglobalrings();}
+  setring(@P);
+  def Lp=imap(RR,L);
+  int i; int j;
+  ideal ida=ideal(1); ideal idb=ideal(1); list Lb; ideal N;
+  for (i=1;i<=size(Lp);i++)
+  {
+    option(returnSB);
+    N=Lp[i][1];
+    ida=intersect(ida,N);
+    Lb=Lp[i][2];
+    for(j=1;j<=size(Lb);j++)
+    {
+      idb=intersect(idb,Lb[j]);
+    }
+  }
+  def La=list(ida,idb);
+  setring(RR);
+  def LL=imap(@P,La);
+  if(te==0){kill @P; kill @R; kill @RP;}
+  return(LL);
+}
+
+// input: F a parametric ideal in Q[a][x]
+// output: a rComprehensive Groebner System disjoint and reduced.
+//      It uses Kapur-Sun-Wang algorithm, and with the options
+//      can compute the homogenization before  (('can',0) or ( 'can',1))
+//      and dehomogenize the result.
+proc cgsdr(ideal F, list #)
+"USAGE: cgsdr(F); To compute a disjoint, reduced CGS.
+          cgsdr is the starting point of the fundamental routine grobcov.
+          Inside grobcov it is used only with options 'can' set to 0,1 and
+          not with options ('can',2).
+          It is to be used if only a disjoint reduced CGS is required.
+          F: ideal in Q[a][x] (parameters and variables) to be discussed.
+
+          Options: To modify the default options, pairs of arguments
+          -option name, value- of valid options must be added to the call.
+
+          Options:
+            \"can\",0-1-2: The default value is \"can\",2. In this case no
+                homogenization is done. With option (\"can\",0) the given
+                basis is homogenized, and with option (\"can\",1) the
+                whole given ideal is homogenized before computing the
+                cgs and dehomogenized after.
+                with option (\"can\",0) the homogenized basis is used
+                with option (\"can\",1) the homogenized ideal is used
+                with option (\"can\",2) the given basis is used
+            \"null\",ideal E: The default is (\"null\",ideal(0)).
+            \"nonnull\",ideal N: The default (\"nonnull\",ideal(1)).
+                When options 'null' and/or 'nonnull' are given, then
+                the parameter space is restricted to V(E)\V(N).
+            \"comment\",0-1: The default is (\"comment\",0). Setting (\"comment\",1)
+                will provide information about the development of the
+                computation.
+            \"out\",0-1: 1 (default) the output segments are given as
+                as difference of varieties.
+                0: the output segments are given in P-representation
+                and the segments grouped by lpp
+                With options (\"can\",0) and (\"can\",1) the option (\"out\",1)
+                is set to (out,0) because it is not compatible.
+          One can give none or whatever of these options.
+          With the default options (\"can\",2,\"out\",1), only the
+          Kapur-Sun-Wang algorithm is computed. This is very effectif
+          but is only the starting point for the computation.
+          When grobcov is computed, the call to cgsdr inside uses
+          specific options that are more expensive ("can",0-1,"out",0).
+RETURN:   Returns a list T describing a reduced and disjoint
+          Comprehensive Groebner System (CGS),
+          With option (\"out\",0)
+           the segments are grouped by
+           leading power products (lpp) of the reduced Groebner
+           basis and given in P-representation.
+           The returned list is of the form:
+           (
+             (lpp, (num,basis,segment),...,(num,basis,segment),lpp),
+             ..,,
+             (lpp, (num,basis,segment),...,(num,basis,segment),lpp)
+           )
+           The bases are the reduced Groebner bases (after normalization)
+           for each point of the corresponding segment.
+
+           The third element of each lpp segment is the lpp of the
+           used ideal in the CGS as a string:
+            with option (\"can\",0) the homogenized basis is used
+            with option (\"can\",1) the homogenized ideal is used
+            with option (\"can\",2) the given basis is used
+
+          With option (\"out\",1) (default)
+           only KSW is applied and segments are given as
+           difference of varieties and are not grouped
+           The returned list is of the form:
+           (
+             (E,N,B),..(E,N,B)
+           )
+           E is the null variety
+           N is the nonnull variety
+           segment = V(E)\V(N)
+           B is the reduced Groebner basis
+
+NOTE:     The basering R, must be of the form Q[a][x], a=parameters,
+          x=variables, and should be defined previously, and the ideal
+          defined on R.
+KEYWORDS: CGS, disjoint, reduced, Comprehensive Groebner System
+EXAMPLE:  cgsdr; shows an example"
+{
+  int te;
+  def RR=basering;
+  if(defined(@P)){te=1;}
+  else{te=0; setglobalrings();}
+  // INITIALIZING OPTIONS
+  int i; int j;
+  int can=2;
+  int out=1;
+  poly f;
+  ideal B;
+  def E=ideal(0);
+  def N=ideal(1);
+  int comment=0;
+  int start=timer;
+  list L=#;
+  for(i=1;i<=size(L) div 2;i++)
+  {
+    if(L[2*i-1]=="null"){E=L[2*i];}
+    else
+    {
+      if(L[2*i-1]=="nonnull"){N=L[2*i];}
+      else
+      {
+        if(L[2*i-1]=="comment"){comment=L[2*i];}
+        else
+        {
+          if(L[2*i-1]=="can"){can=L[2*i];}
+          else
+          {
+            if(L[2*i-1]=="out"){out=L[2*i];}
+          }
+        }
+      }
+    }
+  }
+  //if(can==2){out=1;}
+  B=F;
+  if ((printlevel) and (comment==0)){comment=printlevel;}
+  if((can<2) and (out>0)){"Option out,1 is not compatible with can,0,1"; out=0;}
+  // DEFINING OPTIONS
+  list LL;
+  LL[1]="can";     LL[2]=can;
+  LL[3]="comment"; LL[4]=comment;
+  LL[5]="out";     LL[6]=out;
+  LL[7]="null";    LL[8]=E;
+  LL[9]="nonnull"; LL[10]=N;
+  if(comment>=1)
+  {
+    string("Begin cgsdr with options: ",LL);
+  }
+  int ish;
+  for (i=1;i<=size(B);i++){ish=ishomog(B[i]); if(ish==0){break;};}
+  if (ish)
+  {
+    if(comment>0){string("The given system is homogneous");}
+    def GS=KSW(B,LL);
+    //can=0;
+  }
+  else
+  {
+  // ACTING DEPENDING ON OPTIONS
+  if(can==2)
+  {
+    // WITHOUT HOMOHGENIZING
+    if(comment>0){string("Option of cgsdr: do not homogenize");}
+    def GS=KSW(B,LL);
+    setglobalrings();
+  }
+  else
+  {
+    if(can==1)
+    {
+      // COMPUTING THE HOMOGOENIZED IDEAL
+      if(comment>0){string("Homogenizing the whole ideal: option can=1");}
+      list RRL=ringlist(RR);
+      RRL[3][1][1]="dp";
+      def Pa=ring(RRL[1]);
+      list Lx;
+      Lx[1]=0;
+      Lx[2]=RRL[2]+RRL[1][2];
+      Lx[3]=RRL[1][3];
+      Lx[4]=RRL[1][4];
+      RRL[1]=0;
+      def D=ring(RRL);
+      def RP=D+Pa;
+      setring(RP);
+      def B1=imap(RR,B);
+      option(redSB);
+      B1=std(B1);
+      setring(RR);
+      def B2=imap(RP,B1);
+    }
+    else
+    { // (can=0)
+       if(comment>0){string("Homogenizing the basis: option can=0");}
+      def B2=B;
+    }
+    // COMPUTING HOMOGENIZED CGS
+    poly @t;
+    ring H=0, at t,dp;
+    def RH=RR+H;
+    setring(RH);
+    setglobalrings();
+    def BH=imap(RR,B2);
+    def LH=imap(RR,LL);
+    for (i=1;i<=size(BH);i++)
+    {
+      BH[i]=homog(BH[i], at t);
+    }
+    if (comment>=1){string("Homogenized system = "); BH;}
+    def GSH=KSW(BH,LH);
+    setglobalrings();
+    // DEHOMOGENIZING THE RESULT
+    if(out==0)
+    {
+      for (i=1;i<=size(GSH);i++)
+      {
+        GSH[i][1]=subst(GSH[i][1], at t,1);
+        for(j=1;j<=size(GSH[i][2]);j++)
+        {
+          GSH[i][2][j][2]=subst(GSH[i][2][j][2], at t,1);
+        }
+      }
+    }
+    else
+    {
+      for (i=1;i<=size(GSH);i++)
+      {
+        GSH[i][3]=subst(GSH[i][3], at t,1);
+        GSH[i][7]=subst(GSH[i][7], at t,1);
+      }
+    }
+    setring(RR);
+    def GS=imap(RH,GSH);
+    }
+
+
+    setglobalrings();
+    if(out==0)
+    {
+      for (i=1;i<=size(GS);i++)
+      {
+        GS[i][1]=postredgb(mingb(GS[i][1]));
+        for(j=1;j<=size(GS[i][2]);j++)
+        {
+          GS[i][2][j][2]=postredgb(mingb(GS[i][2][j][2]));
+        }
+      }
+    }
+    else
+    {
+      for (i=1;i<=size(GS);i++)
+      {
+        if(GS[i][2]==1)
+        {
+          GS[i][3]=postredgb(mingb(GS[i][3]));
+          if (typeof(GS[i][7])=="ideal")
+          {
+            GS[i][7]=postredgb(mingb(GS[i][7]));
+          }
+        }
+      }
+    }
+  }
+  if(te==0){kill @P; kill @R; kill @RP;}
+  return(GS);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  "Casas conjecture for degree 4";
+  ring R=(0,a0,a1,a2,a3,a4),(x1,x2,x3),dp;
+  ideal F=x1^4+(4*a3)*x1^3+(6*a2)*x1^2+(4*a1)*x1+(a0),
+          x1^3+(3*a3)*x1^2+(3*a2)*x1+(a1),
+          x2^4+(4*a3)*x2^3+(6*a2)*x2^2+(4*a1)*x2+(a0),
+          x2^2+(2*a3)*x2+(a2),
+          x3^4+(4*a3)*x3^3+(6*a2)*x3^2+(4*a1)*x3+(a0),
+          x3+(a3);
+  cgsdr(F);
+}
+
+// input:  internal routine called by cgsdr at the end to group the
+//            lpp segments and improve the output
+// output: grouped segments by lpp obtained in cgsdr
+proc grsegments(list T)
+{
+  int i;
+  list L;
+  list lpp;
+  list lp;
+  list ls;
+  int n=size(T);
+  lpp[1]=T[n][1];
+  L[1]=list(lpp[1],list(list(T[n][2],T[n][3],T[n][4])));
+  if (n>1)
+  {
+    for (i=1;i<=size(T)-1;i++)
+    {
+      lp=memberpos(T[n-i][1],lpp);
+      if(lp[1]==1)
+      {
+        ls=L[lp[2]][2];
+        ls[size(ls)+1]=list(T[n-i][2],T[n-i][3],T[n-i][4]);
+        L[lp[2]][2]=ls;
+      }
+      else
+      {
+        lpp[size(lpp)+1]=T[n-i][1];
+        L[size(L)+1]=list(T[n-i][1],list(list(T[n-i][2],T[n-i][3],T[n-i][4])));
+      }
+    }
+  }
+  return(L);
+}
+
+// idcontains
+// input: ideal p, ideal q
+// output: 1 if p contains q,  0 otherwise
+// If the routine is to be called from the top, a previous call to
+// setglobalrings() is needed.
+proc idcontains(ideal p, ideal q)
+{
+  int t; int i;
+  t=1; i=1;
+  def RR=basering;
+  setring(@P);
+  def P=imap(RR,p);
+  def Q=imap(RR,q);
+  attrib(P,"isSB",1);
+  poly r;
+  while ((t) and (i<=size(Q)))
+  {
+    r=reduce(Q[i],P);
+    if (r!=0){t=0;}
+    i++;
+  }
+  setring(RR);
+  return(t);
+}
+
+// selectminindeals
+//   given a list of ideals returns the list of integers corresponding
+//   to the minimal ideals in the list
+// input: L (list of ideals)
+// output: the list of integers corresponding to the minimal ideals in L
+// If the routine is to be called from the top, a previous call to
+// setglobalrings() is needed.
+proc selectminideals(list L)
+{
+  if (size(L)==0){return(L)};
+  def RR=basering;
+  setring(@P);
+  def Lp=imap(RR,L);
+  int i; int j; int t; intvec notsel;
+  list P;
+  for (i=1;i<=size(Lp);i++)
+  {
+    if(memberpos(i,notsel)[1])
+    {
+      i++;
+      if(i>size(Lp)){break;}
+    }
+    t=1;
+    j=1;
+    while ((t) and (j<=size(Lp)))
+    {
+      if (i==j){j++;}
+      if ((j<=size(Lp)) and (memberpos(j,notsel)[1]==0))
+      {
+
+        if (idcontains(Lp[i],Lp[j]))
+        {
+          notsel[size(notsel)+1]=i;
+          t=0;
+        }
+      }
+      j++;
+    }
+    if (t){P[size(P)+1]=i;}
+  }
+  setring(RR);
+  return(P);
+}
+
+// LCUnion
+// Given a list of the P-representations of disjoint locally closed segments
+// for which we know that the union is also locally closed
+// it returns the P-representation of its union
+// input:  L list of segments in P-representation
+//      ((p_j^i,(p_j1^i,...,p_jk_j^i | j=1..t_i)) | i=1..s )
+//      where i represents a segment
+// output: P-representation of the union
+//       ((P_j,(P_j1,...,P_jk_j | j=1..t)))
+// If the routine is to be called from the top, a previous call to
+// setglobalrings() is needed.
+// Auxiliary routine called by grobcov and addcons
+// A previous call to setglobarings() is needed if it is to be used at the top.
+proc LCUnion(list LL)
+{
+  def RR=basering;
+  setring(@P);
+  int care;
+  def L=imap(RR,LL);
+  int i; int j; int k; list H; list C; list T;
+  list L0; list P0; list P; list Q0; list Q;  intvec Qi;
+  if(not(defined(@Q2))){list @Q2;}
+  else{kill @Q2; list @Q2;}
+  exportto(Top, at Q2);
+  for (i=1;i<=size(L);i++)
+  {
+    for (j=1;j<=size(L[i]);j++)
+    {
+      P0[size(P0)+1]=L[i][j][1];
+      L0[size(L0)+1]=intvec(i,j);
+    }
+  }
+  Q0=selectminideals(P0);
+  //"T_3Q0="; Q0;
+  kill P; list P;
+  for (i=1;i<=size(Q0);i++)
+  {
+    Qi=L0[Q0[i]];
+    Q[size(Q)+1]=Qi;
+      P[size(P)+1]=L[Qi[1]][Qi[2]];
+  }
+  @Q2=Q;
+  if(size(P)==0)
+  {
+    setring(RR);
+    list TT;
+    return(TT);
+  }
+  // P is the list of the maximal components of the union
+  //   with the corresponding initial holes.
+  // Q is the list of intvec positions in L of the first element of the P's
+  //   Its elements give (num of segment, num of max component (=min ideal))
+  for (k=1;k<=size(Q);k++)
+  {
+    H=P[k][2]; // holes of P[k][1]
+    for (i=1;i<=size(L);i++)
+    {
+      if (i!=Q[k][1])
+      {
+        for (j=1;j<=size(L[i]);j++)
+        {
+          C[size(C)+1]=L[i][j];
+          C[size(C)][3]=intvec(i,j);
+        }
+      }
+    }
+    if(size(P[k])>=3){T[size(T)+1]=list(Q[k],P[k][1],addpart(H,C),P[k][3]);}
+    else{T[size(T)+1]=list(Q[k],P[k][1],addpart(H,C));}
+  }
+  @Q2=sortpairs(@Q2);
+  setring(RR);
+  def TT=imap(@P,T);
+  return(TT);
+}
+
+// Auxiliary routine
+// called by LCUnion to modify the holes of a primepart of the union
+// by the addition of the segments that do not correspond to that part
+// Works on @P ring.
+// Input:
+//   H=(p_i1,..,p_is) the holes of a component to be transformed by the addition of
+//        the segments C that do not correspond to that component
+//   C=((q_1,(q_11,..,q_1l_1),pos1),..,(q_k,(q_k1,..,q_kl_k),posk))
+// posi=(i,j) position of the component
+//        the list of segments to be added to the holes
+proc addpart(list H, list C)
+{
+  list Q; int i; int j; int k; int l; int t; int t1;
+  Q=H; intvec notQ; list QQ; list addq;
+  // @Q2=list of (i,j) positions of the components that have been aded to some hole of the maximal ideals
+  //          plus those of the components added to the holes.
+  ideal q;
+  i=1;
+  while (i<=size(Q))
+  {
+    if (memberpos(i,notQ)[1]==0)
+    {
+      q=Q[i];
+      t=1; j=1;
+      while ((t) and (j<=size(C)))
+      {
+        if (equalideals(q,C[j][1]))
+        {
+          @Q2[size(@Q2)+1]=C[j][3];
+          t=0;
+          for (k=1;k<=size(C[j][2]);k++)
+          {
+            t1=1;
+            //kill addq;
+            //list addq;
+            l=1;
+            while((t1) and (l<=size(Q)))
+            {
+              if ((l!=i) and (memberpos(l,notQ)[1]==0))
+              {
+                if (idcontains(C[j][2][k],Q[l]))
+                {
+                  t1=0;
+                }
+              }
+              l++;
+            }
+            if (t1)
+            {
+              addq[size(addq)+1]=C[j][2][k];
+              @Q2[size(@Q2)+1]=C[j][3];
+            }
+          }
+          if((size(notQ)==1) and (notQ[1]==0)){notQ[1]=i;}
+          else {notQ[size(notQ)+1]=i;}
+        }
+        j++;
+      }
+      if (size(addq)>0)
+      {
+        for (k=1;k<=size(addq);k++)
+        {
+          Q[size(Q)+1]=addq[k];
+        }
+        kill addq;
+        list addq;
+      }
+      //print("Q="); Q; print("notQ="); notQ;
+    }
+    i++;
+  }
+  for (i=1;i<=size(Q);i++)
+  {
+    if(memberpos(i,notQ)[1]==0)
+    {
+      QQ[size(QQ)+1]=Q[i];
+    }
+  }
+  if (size(QQ)==0){QQ[1]=ideal(1);}
+  return(addpartfine(QQ,C));
+}
+
+// Auxiliary routine called by addpart to finish the modification of the holes of a primepart
+// of the union by the addition of the segments that do not correspond to
+// that part.
+// Works on @P ring.
+proc addpartfine(list H, list C0)
+{
+  int i; int j; int k; int te; intvec notQ; int l; list sel; int used;
+  intvec jtesC;
+  if ((size(H)==1) and (equalideals(H[1],ideal(1)))){return(H);}
+  if (size(C0)==0){return(H);}
+  def RR=basering;
+  setring(@P);
+  list newQ; list nQ; list Q; list nQ1; list Q0;
+  def Q1=imap(RR,H);
+  //Q1=sortlistideals(Q1);
+  def C=imap(RR,C0);
+  while(equallistideals(Q0,Q1)==0)
+  {
+    Q0=Q1;
+    i=0;
+    Q=Q1;
+    kill notQ; intvec notQ;
+    while(i<size(Q))
+    {
+      i++;
+      for(j=1;j<=size(C);j++)
+      {
+        te=idcontains(Q[i],C[j][1]);
+        if(te)
+        {
+          for(k=1;k<=size(C[j][2]);k++)
+          {
+            if(idcontains(Q[i],C[j][2][k]))
+            {
+              te=0; break;
+            }
+          }
+          if (te)
+          {
+            used++;
+            if ((size(notQ)==1) and (notQ[1]==0)){notQ[1]=i;}
+            else{notQ[size(notQ)+1]=i;}
+            kill newQ; list newQ;
+            for(k=1;k<=size(C[j][2]);k++)
+            {
+              nQ=minGTZ(Q[i]+C[j][2][k]);
+              for(l=1;l<=size(nQ);l++)
+              {
+                option(redSB);
+                nQ[l]=std(nQ[l]);
+                newQ[size(newQ)+1]=nQ[l];
+              }
+            }
+            sel=selectminideals(newQ);
+            kill nQ1; list nQ1;
+            for(l=1;l<=size(sel);l++)
+            {
+              nQ1[l]=newQ[sel[l]];
+            }
+            newQ=nQ1;
+            for(l=1;l<=size(newQ);l++)
+            {
+              Q[size(Q)+1]=newQ[l];
+            }
+            break;
+          }
+        }
+      }
+    }
+    kill Q1; list Q1;
+    for(i=1;i<=size(Q);i++)
+    {
+      if(memberpos(i,notQ)[1]==0)
+      {
+        Q1[size(Q1)+1]=Q[i];
+      }
+    }
+    sel=selectminideals(Q1);
+    kill nQ1; list nQ1;
+    for(l=1;l<=size(sel);l++)
+    {
+      nQ1[l]=Q1[sel[l]];
+    }
+    Q1=nQ1;
+  }
+  setring(RR);
+  //if(used>0){string("addpartfine was ", used, " times used");}
+  return(imap(@P,Q1));
+}
+
+// Auxiliary routine for grobcov: ideal F is assumed to be homogeneous
+// gcover
+// input: ideal F: a generating set of a homogeneous ideal in Q[a][x]
+//    list #: optional
+// output: the list
+//   S=((lpp, generic basis, Prep, Crep),..,(lpp, generic basis, Prep, Crep))
+//      where a Prep is ( (p1,(p11,..,p1k_1)),..,(pj,(pj1,..,p1k_j)) )
+//            a Crep is ( ida, idb )
+proc gcover(ideal F,list #)
+{
+  int i; int j; int k; ideal lpp; list GPi2; list pairspP; ideal B; int ti;
+  int i1; int tes; int j1; int selind; int i2; int m;
+  list prep; list crep; list LCU; poly p; poly lcp; ideal FF;
+  list lpi;
+  string lpph;
+  list L=#;
+  int canop=1;
+  int extop=1;
+  int repop=0;
+  ideal E=ideal(0);;
+  ideal N=ideal(1);;
+  int comment;
+  for(i=1;i<=size(L) div 2;i++)
+  {
+    if(L[2*i-1]=="can"){canop=L[2*i];}
+    else
+    {
+      if(L[2*i-1]=="ext"){extop=L[2*i];}
+      else
+      {
+        if(L[2*i-1]=="rep"){repop=L[2*i];}
+        else
+        {
+          if(L[2*i-1]=="null"){E=L[2*i];}
+          else
+          {
+            if(L[2*i-1]=="nonnull"){N=L[2*i];}
+            else
+            {
+              if (L[2*i-1]=="comment"){comment=L[2*i];}
+            }
+          }
+        }
+      }
+    }
+  }
+  list GS; list GP;
+  def RR=basering;
+  GS=cgsdr(F,L); // "null",NW[1],"nonnull",NW[2],"cgs",CGS,"comment",comment);
+  setglobalrings();
+  int start=timer;
+  GP=GS;
+  ideal lppr;
+  list LL;
+  list S;
+  poly sp;
+  ideal BB;
+  for (i=1;i<=size(GP);i++)
+  {
+    kill LL;
+    list LL;
+    lpp=GP[i][1];
+    GPi2=GP[i][2];
+    lpph=GP[i][3];
+    kill pairspP; list pairspP;
+    for(j=1;j<=size(GPi2);j++)
+    {
+      pairspP[size(pairspP)+1]=GPi2[j][3];
+    }
+    LCU=LCUnion(pairspP);
+    kill prep; list prep;
+    kill crep; list crep;
+    for(k=1;k<=size(LCU);k++)
+    {
+      prep[k]=list(LCU[k][2],LCU[k][3]);
+      B=GPi2[LCU[k][1][1]][2]; // ATENTION last 1 has been changed to [2]
+      LCU[k][1]=B;
+    }
+    //"Deciding if combine is needed";
+    kill BB;
+    ideal BB;
+    tes=1; m=1;
+    while((tes) and (m<=size(LCU[1][1])))
+    {
+      j=1;
+      while((tes) and (j<=size(LCU)))
+      {
+        k=1;
+        while((tes) and (k<=size(LCU)))
+        {
+          if(j!=k)
+          {
+            sp=pnormalf(pspol(LCU[j][1][m],LCU[k][1][m]),LCU[k][2],N);
+            if(sp!=0){tes=0;}
+          }
+          k++;
+        }        //setglobalrings();
+        if(tes)
+        {
+          BB[m]=LCU[j][1][m];
+        }
+        j++;
+      }
+      if(tes==0){break;}
+      m++;
+    }
+    crep=PtoCrep(prep);
+    if(tes==0)
+    {
+      // combine is needed
+      kill B; ideal B;
+      for (j=1;j<=size(LCU);j++)
+      {
+        LL[j]=LCU[j][2];
+      }
+      if (size(LCU)>1)
+      {
+        FF=precombint(LL);
+      }
+      for (k=1;k<=size(lpp);k++)
+      {
+        kill L; list L;
+        for (j=1;j<=size(LCU);j++)
+        {
+          L[j]=list(LCU[j][2],LCU[j][1][k]);
+        }
+        if (size(LCU)>1)
+        {
+          B[k]=combine(L,FF);
+        }
+        else{B[k]=L[1][2];}
+      }
+    }
+    else{B=BB;}
+    for(j=1;j<=size(B);j++)
+    {
+      B[j]=pnormalf(B[j],crep[1],crep[2]);
+    }
+    S[i]=list(lpp,B,prep,crep,lpph);
+    if(comment>=1)
+    {
+      lpi[size(lpi)+1]=string("[",i,"]");
+      lpi[size(lpi)+1]=S[i][1];
+    }
+  }
+  if(comment>=1)
+  {
+    string("Time in LCUnion + combine = ",timer-start);
+    if(comment>=2){string("lpp=",lpi)};
+  }
+  if(defined(@P)==1){kill @P; kill @RP; kill @R;}
+  return(S);
+}
+
+// grobcov
+// input:
+//    ideal F: a parametric ideal in Q[a][x], where a are the parameters
+//             and x the variables
+//    list #: (options) list("null",N,"nonnull",W,"can",0-1,ext",0-1, "rep",0-1-2)
+//            where
+//            N is the null conditions ideal (if desired)
+//            W is the ideal of non-null conditions (if desired)
+//            The value of \"can\"i s 1 by default and can be set to 0 if we do not
+//            need to obtain the canonical GC, but only a GC.
+//            The value of \"ext\" is 0 by default and so the generic representation
+//             of the bases is given. It can be set to 1, and then the full
+//             representation of the bases is given.
+//            The value of \"rep\" is 0 by default, and then the segments
+//            are given in canonical P-representation. It can be set to 1
+//            and then they are given in canonical C-representation.
+//            If it is set to 2, then both representations are given.
+// output:
+//    list S: ((lpp,basis,(idp_1,(idp_11,..,idp_1s_1))), ..
+//             (lpp,basis,(idp_r,(idp_r1,..,idp_rs_r))) ) where
+//            each element of S corresponds to a lpp-segment
+//            given by the lpp, the basis, and the P-representation of the segment
+proc grobcov(ideal F,list #)
+"USAGE:   grobcov(F); This is the fundamental routine of the
+          library. It computes the Groebner cover of a parametric ideal
+          (see (*) Montes A., Wibmer M., Groebner Bases for Polynomial
+          Systems with parameters. JSC 45 (2010) 1391-1425.)
+          The Groebner cover of a parametric ideal consist of a set of
+          pairs(S_i,B_i), where the S_i are disjoint locally closed
+          segments of the parameter space, and the B_i are the reduced
+          Groebner bases of the ideal on every point of S_i.
+
+          The ideal F must be defined on a parametric ring Q[a][x].
+          Options: To modify the default options, pair of arguments
+          -option name, value- of valid options must be added to the call.
+
+          Options:
+            \"null\",ideal E: The default is (\"null\",ideal(0)).
+            \"nonnull\",ideal N: The default (\"nonnull\",ideal(1)).
+                When options \"null\" and/or \"nonnull\" are given, then
+                the parameter space is restricted to V(E)\V(N).
+            \"can\",0-1: The default is (\"can\",1). With the default option
+                the homogenized ideal is computed before obtaining the
+                Groebner cover, so that the result is the canonical
+                Groebner cover. Setting (\"can\",0) only homogenizes the
+                basis so the result is not exactly canonical, but the
+                computation is shorter.
+            \"ext\",0-1: The default is (\"ext\",0). With the default
+                (\"ext\",0), only the generic representation is computed
+                (single polynomials, but not specializing to non-zero at
+                each point of the segment. With option (\"ext\",1) the
+                full representation of the bases is computed (possible
+                sheaves) and sometimes a simpler result is obtained.
+            \"rep\",0-1-2: The default is (\"rep\",0) and then the segments
+                are given in canonical P-representation. Option (\"rep\",1)
+                represents the segments in canonical C-representation,
+                and option (\"rep\",2) gives both representations.
+            \"comment\",0-3: The default is (\"comment\",0). Setting
+                \"comment\" higher will provide information about the
+                development of the computation.
+          One can give none or whatever of these options.
+RETURN:   The list
+          (
+           (lpp_1,basis_1,segment_1,lpph_1),
+           ...
+           (lpp_s,basis_s,segment_s,lpph_s)
+          )
+
+          The lpp are constant over a segment and correspond to the
+          set of lpp of the reduced Groebner basis for each point
+          of the segment.
+          The lpph corresponds to the lpp of the homogenized ideal
+          and is different for each segment. It is given as a string.
+
+          Basis: to each element of lpp corresponds an I-regular function given
+          in full representation (by option (\"ext\",1)) or in
+          generic representation (default option (\"ext\",0)). The
+          I-regular function is the corresponding element of the reduced
+          Groebner basis for each point of the segment with the given lpp.
+          For each point in the segment, the polynomial or the set of
+          polynomials representing it, if they do not specialize to 0,
+          then after normalization, specializes to the corresponding
+          element of the reduced Groebner basis. In the full representation
+          at least one of the polynomials representing the I-regular
+          function specializes to non-zero.
+
+          With the default option (\"rep\",0) the representation of the
+          segment is the P-representation.
+          With option (\"rep\",1) the representation of the segment is
+          the C-representation.
+          With option (\"rep\",2) both representations of the segment are
+          given.
+
+          The P-representation of a segment is of the form
+          ((p_1,(p_11,..,p_1k1)),..,(p_r,(p_r1,..,p_rkr))
+          representing the segment U_i (V(p_i) \ U_j (V(p_ij))),
+          where the p's are prime ideals.
+
+          The C-representation of a segment is of the form
+          (E,N) representing V(E)\V(N), and the ideals E and N are
+          radical and N contains E.
+
+NOTE: The basering R, must be of the form Q[a][x], a=parameters,
+          x=variables, and should be defined previously. The ideal must
+          be defined on R.
+KEYWORDS: Groebner cover, parametric ideal, canonical, discussion of
+          parametric ideal.
+EXAMPLE:  grobcov; shows an example"
+{
+  list S; int i; int ish=1; list GBR; list BR; int j; int k;
+  ideal idp; ideal idq; int s; ideal ext; list SS;
+  ideal E; ideal N; int canop;  int extop; int repop;
+  int comment=0; int m;
+  def RR=basering;
+  setglobalrings();
+  list L0=#;
+  int out=0;
+  L0[size(L0)+1]="res"; L0[size(L0)+1]=ideal(1);
+  // default options
+  int start=timer;
+  E=ideal(0);
+  N=ideal(1);
+  canop=1; // canop=0 for homogenizing the basis but not the ideal (not canonical)
+           // canop=1 for working with the homogenized ideal
+  repop=0; // repop=0 for representing the segments in Prep
+           // repop=1 for representing the segments in Crep
+           // repop=2 for representing the segments in Prep and Crep
+  extop=0; // extop=0 if only generic representation of the bases are to be computed
+           // extop=1 if the full representation of the bases are to be computed
+  for(i=1;i<=size(L0) div 2;i++)
+  {
+    if(L0[2*i-1]=="can"){canop=L0[2*i];}
+    else
+    {
+      if(L0[2*i-1]=="ext"){extop=L0[2*i];}
+      else
+      {
+        if(L0[2*i-1]=="rep"){repop=L0[2*i];}
+        else
+        {
+          if(L0[2*i-1]=="null"){E=L0[2*i];}
+          else
+          {
+            if(L0[2*i-1]=="nonnull"){N=L0[2*i];}
+            else
+            {
+              if (L0[2*i-1]=="comment"){comment=L0[2*i];}
+            }
+          }
+        }
+      }
+    }
+  }
+  if(not((canop==0) or (canop==1)))
+  {
+    string("Option can = ",canop," is not supported. It is changed to can = 1");
+    canop=1;
+  }
+  for(i=1;i<=size(L0) div 2;i++)
+  {
+    if(L0[2*i-1]=="can"){L0[2*i]=canop;}
+  }
+  if ((printlevel) and (comment==0)){comment=printlevel;}
+  list LL;
+  LL[1]="can";     LL[2]=canop;
+  LL[3]="comment"; LL[4]=comment;
+  LL[5]="out";     LL[6]=0;
+  LL[7]="null";    LL[8]=E;
+  LL[9]="nonnull"; LL[10]=N;
+  LL[11]="ext";    LL[12]=extop;
+  LL[13]="rep";    LL[14]=repop;
+  if (comment>=1)
+  {
+    string("Begin grobcov with options: ",LL);
+  }
+  kill S;
+  def S=gcover(F,LL);
+  // NOW extend
+  if(extop)
+  {
+    S=extend(S,LL);
+  }
+  else
+  {
+    // NOW representation of the segments by option repop
+    list Si; list nS;
+    if(repop==0)
+    {
+      for(i=1;i<=size(S);i++)
+      {
+        Si=list(S[i][1],S[i][2],S[i][3],S[i][5]);
+        nS[size(nS)+1]=Si;
+      }
+      kill S;
+      def S=nS;
+    }
+    else
+    {
+      if(repop==1)
+      {
+        for(i=1;i<=size(S);i++)
+        {
+          Si=list(S[i][1],S[i][2],S[i][4],S[i][5]);
+          nS[size(nS)+1]=Si;
+        }
+        kill S;
+        def S=nS;
+      }
+      else
+      {
+        for(i=1;i<=size(S);i++)
+        {
+          Si=list(S[i][1],S[i][2],S[i][3],S[i][4],S[i][5]);
+          nS[size(nS)+1]=Si;
+        }
+        kill S;
+        def S=nS;
+      }
+    }
+  }
+  if (comment>=1)
+  {
+    string("Time in grobcov = ", timer-start);
+    string("Number of segments of grobcov = ", size(S));
+  }
+  if(defined(@P)==1){kill @R; kill @P; kill @RP;}
+  return(S);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  "Casas conjecture for degree 4";
+  ring R=(0,a0,a1,a2,a3,a4),(x1,x2,x3),dp;
+  ideal F=x1^4+(4*a3)*x1^3+(6*a2)*x1^2+(4*a1)*x1+(a0),
+          x1^3+(3*a3)*x1^2+(3*a2)*x1+(a1),
+          x2^4+(4*a3)*x2^3+(6*a2)*x2^2+(4*a1)*x2+(a0),
+          x2^2+(2*a3)*x2+(a2),
+          x3^4+(4*a3)*x3^3+(6*a2)*x3^2+(4*a1)*x3+(a0),
+          x3+(a3);
+  grobcov(F);
+}
+
+// Input. GC the grobcov of an ideal in generic representation of the
+//        bases computed with option option ("rep",2).
+// Output The grobcov in full representation.
+// Option ("comment",1) shows the time.
+// Can be called from the top
+proc extend(list GC, list #);
+"USAGE:   extend(GC); When the grobcov of an ideal has been computed
+          with the default option (\"ext\",0) and the explicit option
+          (\"rep\",2) (which is not the default), then one can call
+          extend (GC) (and options) to obtain the full representation
+          of the bases. With the default option (\"ext\",0) only the
+          generic representation of the bases are computed, and one can
+          obtain the full representation using extend.
+            \"rep\",0-1-2: The default is (\"rep\",0) and then the segments
+                are given in canonical P-representation. Option (\"rep\",1)
+                represents the segments in canonical C-representation,
+                and option (\"rep\",2) gives both representations.
+            \"comment\",0-1: The default is (\"comment\",0). Setting
+                \"comment\" higher will provide information about the
+                time used in the computation.
+          One can give none or whatever of these options.
+RETURN:   The list
+          (
+           (lpp_1,basis_1,segment_1,lpph_1),
+           ...
+           (lpp_s,basis_s,segment_s,lpph_s)
+          )
+
+          The lpp are constant over a segment and correspond to the
+          set of lpp of the reduced Groebner basis for each point
+          of the segment.
+          The lpph corresponds to the lpp of the homogenized ideal
+          and is different for each segment. It is given as a string.
+
+          Basis: to each element of lpp corresponds an I-regular function given
+          in full representation. The
+          I-regular function is the corresponding element of the reduced
+          Groebner basis for each point of the segment with the given lpp.
+          For each point in the segment, the polynomial or the set of
+          polynomials representing it, if they do not specialize to 0,
+          then after normalization, specializes to the corresponding
+          element of the reduced Groebner basis. In the full representation
+          at least one of the polynomials representing the I-regular
+          function specializes to non-zero.
+
+          With the default option (\"rep\",0) the segments are given
+          in P-representation.
+          With option (\"rep\",1) the segments are given
+          in C-representation.
+          With option (\"rep\",2) both representations of the segments are
+          given.
+
+          The P-representation of a segment is of the form
+          ((p_1,(p_11,..,p_1k1)),..,(p_r,(p_r1,..,p_rkr))
+          representing the segment U_i (V(p_i) \ U_j (V(p_ij))),
+          where the p's are prime ideals.
+
+          The C-representation of a segment is of the form
+          (E,N) representing V(E)\V(N), and the ideals E and N are
+          radical and N contains E.
+
+NOTE: The basering R, must be of the form Q[a][x], a=parameters,
+          x=variables, and should be defined previously. The ideal must
+          be defined on R.
+KEYWORDS: Groebner cover, parametric ideal, canonical, discussion of
+          parametric ideal, full representation.
+EXAMPLE:  extend; shows an example"
+{
+  list L=#;
+  list S=GC;
+  ideal idp;
+  ideal idq;
+  int i; int j; int m; int s;
+  m=0; i=1;
+  while((i<=size(S)) and (m==0))
+  {
+    if(typeof(S[i][2])=="list"){m=1;}
+    i++;
+  }
+  if(m==1){"Warning! grobcov has already extended bases"; return(S);}
+  if(size(GC[1])!=5){"Warning! extend make sense only when grobcov has been called with options 'rep',2,'ext',0"; " "; return();}
+  int repop=0;
+  int start3=timer;
+  int comment;
+  for(i=1;i<=size(L) div 2;i++)
+  {
+    if(L[2*i-1]=="comment"){comment=L[2*i];}
+    else
+    {
+      if(L[2*i-1]=="rep"){repop=L[2*i];}
+    }
+  }
+  poly leadc;
+  poly ext;
+  int te=0;
+  list SS;
+  def R=basering;
+  if (defined(@R)){te=1;}
+  else{setglobalrings();}
+  // Now extend
+  for (i=1;i<=size(S);i++)
+  {
+    m=size(S[i][2]);
+     for (j=1;j<=m;j++)
+    {
+      idp=S[i][4][1];
+      idq=S[i][4][2];
+      if (size(idp)>0)
+      {
+        leadc=leadcoef(S[i][2][j]);
+        kill ext;
+        def ext=extend0(S[i][2][j],idp,idq);
+        if (typeof(ext)=="poly")
+        {
+          S[i][2][j]=pnormalf(ext,idp,idq);
+        }
+        else
+        {
+          if(size(ext)==1)
+          {
+            S[i][2][j]=ext[1];
+          }
+          else
+          {
+            kill SS; list SS;
+            for(s=1;s<=size(ext);s++)
+            {
+              ext[s]=pnormalf(ext[s],idp,idq);
+            }
+            for(s=1;s<=size(S[i][2]);s++)
+            {
+              if(s!=j){SS[s]=S[i][2][s];}
+              else{SS[s]=ext;}
+            }
+            S[i][2]=SS;
+          }
+        }
+      }
+    }
+  }
+  // NOW representation of the segments by option repop
+  list Si; list nS;
+  if (repop==0)
+  {
+    for(i=1;i<=size(S);i++)
+    {
+      Si=list(S[i][1],S[i][2],S[i][3],S[i][5]);
+      nS[size(nS)+1]=Si;
+    }
+    S=nS;
+  }
+  else
+  {
+    if (repop==1)
+    {
+      for(i=1;i<=size(S);i++)
+      {
+        Si=list(S[i][1],S[i][2],S[i][4],S[i][5]);
+        nS[size(nS)+1]=Si;
+      }
+      S=nS;
+    }
+    else
+    {
+      for(i=1;i<=size(S);i++)
+      {
+        Si=list(S[i][1],S[i][2],S[i][3],S[i][4],S[i][5]);
+        nS[size(nS)+1]=Si;
+      }
+
+    }
+  }
+  if(comment>=1){string("Time in extend = ",timer-start3);}
+  if(te==0){kill @R; kill @RP; kill @P;}
+  return(S);
+}
+example
+{
+  ring R=(0,a0,b0,c0,a1,b1,c1,a2,b2,c2),(x), dp;
+  short=0;
+  ideal S=a0*x^2+b0*x+c0,
+          a1*x^2+b1*x+c1,
+          a2*x^2+b2*x+c2;
+  "System S="; S;
+
+  def GCS=grobcov(S,"rep",2,"comment",1);
+  "grobcov(S,'rep',2,'comment',1)="; GCS;
+  def FGC=extend(GCS,"rep",0,"comment",1);
+  "Full representation="; FGC;
+}
+
+// Auxiliary routine
+// nonzerodivisor
+// input:
+//    poly g in K[a],
+//    list P=(p_1,..p_r) representing a minimal prime decomposition
+// output
+//    poly f such that f notin p_i for all i and
+//           g-f in p_i for all i such that g notin p_i
+proc nonzerodivisor(poly gr, list Pr)
+{
+  def RR=basering;
+  setring(@P);
+  def g=imap(RR,gr);
+  def P=imap(RR,Pr);
+  int i; int k;  list J; ideal F;
+  def f=g;
+  ideal Pi;
+  for (i=1;i<=size(P);i++)
+  {
+    option(redSB);
+    Pi=std(P[i]);
+    //attrib(Pi,"isSB",1);
+    if (reduce(g,Pi,1)==0){J[size(J)+1]=i;}
+  }
+  for (i=1;i<=size(J);i++)
+  {
+    F=ideal(1);
+    for (k=1;k<=size(P);k++)
+    {
+      if (k!=J[i])
+      {
+        F=idint(F,P[k]);
+      }
+    }
+    f=f+F[1];
+  }
+  setring(RR);
+  def fr=imap(@P,f);
+  return(fr);
+}
+
+// Auxiliary routine
+// deltai
+// input:
+//   int i:
+//   list LPr: (p1,..,pr) of prime components of an ideal in K[a]
+// output:
+//   list (fr,fnr) of two polynomials that are equal on V(pi)
+//       and fr=0 on V(P) \ V(pi), and fnr is nonzero on V(pj) for all j.
+proc deltai(int i, list LPr)
+{
+  def RR=basering;
+  setring(@P);
+  def LP=imap(RR,LPr);
+  int j; poly p;
+  ideal F=ideal(1);
+  poly f;
+  poly fn;
+  ideal LPi;
+  for (j=1;j<=size(LP);j++)
+  {
+    if (j!=i)
+    {
+      F=idint(F,LP[j]);
+    }
+  }
+  p=0; j=1;
+  while ((p==0) and (j<=size(F)))
+  {
+    LPi=LP[i];
+    attrib(LPi,"isSB",1);
+    p=reduce(F[j],LPi);
+    j++;
+  }
+  f=F[j-1];
+  fn=nonzerodivisor(f,LP);
+  setring(RR);
+  def fr=imap(@P,f);
+  def fnr=imap(@P,fn);
+  return(list(fr,fnr));
+}
+
+// Auxiliary routine
+// combine
+// input: a list of pairs ((p1,P1),..,(pr,Pr)) where
+//    ideal pi is a prime component
+//    poly Pi is the polynomial in Q[a][x] on V(pi)\ V(Mi)
+//    (p1,..,pr) are the prime decomposition of the lpp-segment
+//    list crep =(ideal ida,ideal idb): the Crep of the segment.
+//    list Pci of the intersecctions of all pj except the ith one
+// output:
+//    poly P on an open and dense set of V(p_1 int ... p_r)
+proc combine(list L, ideal F)
+{
+  // ATTENTION REVISE AND USE Pci and F
+  int i; poly f;
+  f=0;
+  for(i=1;i<=size(L);i++)
+  {
+    f=f+F[i]*L[i][2];
+  }
+//   f=elimconstfac(f);
+  f=primepartZ(f);
+  return(f);
+}
+
+// Auxiliary routine
+// elimconstfac: eliminate the factors in the polynom f that are in K[a]
+// input:
+//   poly f:
+//   list L: of components of the segment
+// output:
+//   poly f2  where the factors of f in K[a] that are non-null on any component
+//   have been dropped from f
+proc elimconstfac(poly f)
+{
+  int cond; int i; int j; int t;
+  if (f==0){return(f);}
+  def RR=basering;
+  setring(@R);
+  def ff=imap(RR,f);
+  list l=factorize(ff,0);
+  poly f1=1;
+  for(i=2;i<=size(l[1]);i++)
+  {
+      f1=f1*(l[1][i])^(l[2][i]);
+  }
+  setring(RR);
+  def f2=imap(@R,f1);
+  return(f2);
+}
+
+//Auxiliary routine
+// nullin
+// input:
+//   poly f:  a polynomial in Q[a]
+//   ideal P: an ideal in Q[a]
+//   called from ring @R
+// output:
+//   t:  with value 1 if f reduces modulo P, 0 if not.
+proc nullin(poly f,ideal P)
+{
+  int t;
+  def RR=basering;
+  setring(@P);
+  def f0=imap(RR,f);
+  def P0=imap(RR,P);
+  attrib(P0,"isSB",1);
+  if (reduce(f0,P0,1)==0){t=1;}
+  else{t=0;}
+  setring(RR);
+  return(t);
+}
+
+// Auxiliary routine
+// monoms
+// Input: A polynomial f
+// Output: The list of leading terms
+proc monoms(poly f)
+{
+  list L;
+  poly lm; poly lc; poly lp; poly Q; poly mQ;
+  def p=f;
+  int i=1;
+  while (p!=0)
+  {
+    lm=lead(p);
+    p=p-lm;
+    lc=leadcoef(lm);
+    lp=leadmonom(lm);
+    L[size(L)+1]=list(lc,lp);
+    i++;
+  }
+  return(L);
+}
+
+// Auxiliary routine called by extend
+// extend0
+// input:
+//   poly f: a generic polynomial in the basis
+//   ideal idp: such that ideal(S)=idp
+//   ideal idq: such that S=V(idp)\V(idq)
+////   NW the list of ((N1,W1),..,(Ns,Ws)) of red-rep of the grouped
+////      segments in the lpp-segment  NO MORE USED
+// output:
+proc extend0(poly f, ideal idp, ideal idq)
+{
+  matrix CC; poly Q; list NewMonoms;
+  int i;  int j;  poly fout; ideal idout;
+  list L=monoms(f);
+  int nummonoms=size(L)-1;
+  Q=L[1][1];
+  if (nummonoms==0){return(f);}
+  for (i=2;i<=size(L);i++)
+  {
+    CC=matrix(extendcoef(L[i][1],Q,idp,idq));
+    NewMonoms[i-1]=list(CC,L[i][2]);
+  }
+  if (nummonoms==1)
+  {
+    for(j=1;j<=ncols(NewMonoms[1][1]);j++)
+    {
+      fout=NewMonoms[1][1][2,j]*L[1][2]+NewMonoms[1][1][1,j]*NewMonoms[1][2];
+      //fout=pnormalf(fout,idp,W);
+      if(ncols(NewMonoms[1][1])>1){idout[j]=fout;}
+    }
+    if(ncols(NewMonoms[1][1])==1){return(fout);} else{return(idout);}
+  }
+  else
+  {
+    list cfi;
+    list coefs;
+    for (i=1;i<=nummonoms;i++)
+    {
+      kill cfi; list cfi;
+      for(j=1;j<=ncols(NewMonoms[i][1]);j++)
+      {
+        cfi[size(cfi)+1]=NewMonoms[i][1][2,j];
+      }
+      coefs[i]=cfi;
+    }
+    def indexpolys=findindexpolys(coefs);
+    for(i=1;i<=size(indexpolys);i++)
+    {
+      fout=L[1][2];
+      for(j=1;j<=nummonoms;j++)
+      {
+        fout=fout+(NewMonoms[j][1][1,indexpolys[i][j]])/(NewMonoms[j][1][2,indexpolys[i][j]])*NewMonoms[j][2];
+      }
+      fout=cleardenom(fout);
+      if(size(indexpolys)>1){idout[i]=fout;}
+    }
+    if (size(indexpolys)==1){return(fout);} else{return(idout);}
+  }
+}
+
+// Auxiliary routine
+// findindexpolys
+// input:
+//   list coefs=( (q11,..,q1r_1),..,(qs1,..,qsr_1) )
+//               of denominators of the monoms
+// output:
+//   list ind=(v_1,..,v_t) of intvec
+//        each intvec v=(i_1,..,is) corresponds to a polynomial in the sheaf
+//        that will be built from it in extend procedure.
+proc findindexpolys(list coefs)
+{
+  int i; int j; intvec numdens;
+  for(i=1;i<=size(coefs);i++)
+  {
+    numdens[i]=size(coefs[i]);
+  }
+  def RR=basering;
+  setring(@P);
+  def coefsp=imap(RR,coefs);
+  ideal cof; list combpolys; intvec v; int te; list mp;
+  for(i=1;i<=size(coefsp);i++)
+  {
+    cof=ideal(0);
+    for(j=1;j<=size(coefsp[i]);j++)
+    {
+      cof[j]=factorize(coefsp[i][j],3);
+    }
+    coefsp[i]=cof;
+  }
+  for(j=1;j<=size(coefsp[1]);j++)
+  {
+    v[1]=j;
+    te=1;
+    for (i=2;i<=size(coefsp);i++)
+    {
+      mp=memberpos(coefsp[1][j],coefsp[i]);
+      if(mp[1])
+      {
+        v[i]=mp[2];
+      }
+      else{v[i]=0;}
+    }
+    combpolys[j]=v;
+  }
+  combpolys=reform(combpolys,numdens);
+  setring(RR);
+  return(combpolys);
+}
+
+// Auxiliary routine
+// extendcoef: given Q,P in K[a] where P/Q specializes on an open and dense subset
+//      of the whole V(p1 int...int pr), it returns a basis of the module
+//      of all syzygies equivalent to P/Q,
+proc extendcoef(poly P, poly Q, ideal idp, ideal idq)
+{
+  def RR=basering;
+  setring(@P);
+  def PL=ringlist(@P);
+  PL[3][1][1]="dp";
+  def P1=ring(PL);
+  setring(P1);
+  ideal idp0=imap(RR,idp);
+  option(redSB);
+  qring q=std(idp0);
+  poly P0=imap(RR,P);
+  poly Q0=imap(RR,Q);
+  ideal PQ=Q0,-P0;
+  module C=syz(PQ);
+  setring(@P);
+  def idp1=imap(RR,idp);
+  def idq1=imap(RR,idq);
+  def C1=matrix(imap(q,C));
+  def redC=selectregularfun(C1,idp1,idq1);
+  setring(RR);
+  def CC=imap(@P,redC);
+  return(CC);
+}
+
+// Auxiliary routine
+// selectregularfun
+// input:
+//   list L of the polynomials matrix CC
+//      (we assume that one of them is non-null on V(N)\V(M))
+//   ideal N, ideal M: ideals representing the locally closed set V(N)\V(M)
+// assume to work in @P
+proc selectregularfun(matrix CC, ideal NN, ideal MM)
+{
+  int numcombused;
+  def RR=basering;
+  setring(@P);
+  def C=imap(RR,CC);
+  def N=imap(RR,NN);
+  def M=imap(RR,MM);
+  if (ncols(C)==1){return(C);}
+
+  int i; int j; int k; list c; intvec ci; intvec c0; intvec c1;
+  list T; list T0; list T1; list LL; ideal N1;ideal M1; int te=0;
+  for(i=1;i<=ncols(C);i++)
+  {
+    if((C[1,i]!=0) and (C[2,i]!=0))
+    {
+      if(c0==intvec(0)){c0[1]=i;}
+      else{c0[size(c0)+1]=i;}
+    }
+  }
+  def C1=submat(C,1..2,c0);
+  for (i=1;i<=ncols(C1);i++)
+  {
+    c=comb(ncols(C1),i);
+    for(j=1;j<=size(c);j++)
+    {
+      ci=c[j];
+      numcombused++;
+      if(i==1){N1=N+C1[2,j]; M1=M;}
+      if(i>1)
+      {
+        kill c0; intvec c0 ; kill c1; intvec c1;
+        c1=ci[size(ci)];
+        for(k=1;k<size(ci);k++){c0[k]=ci[k];}
+        T0=searchinlist(c0,LL);
+        T1=searchinlist(c1,LL);
+        N1=T0[1]+T1[1];
+        M1=intersect(T0[2],T1[2]);
+      }
+      T=list(ci,PtoCrep(Prep(N1,M1)));
+      LL[size(LL)+1]=T;
+      if(equalideals(T[2][1],ideal(1))){te=1; break;}
+    }
+    if(te){break;}
+  }
+  ci=T[1];
+  def Cs=submat(C1,1..2,ci);
+  setring(RR);
+  return(imap(@P,Cs));
+}
+
+// Auxiliary routine
+// searchinlist
+// input:
+//   intvec c:
+//   list L=( (c1,T1),..(ck,Tk) )
+//      where the c's are assumed to be intvects
+// output:
+//   object T with index c
+proc searchinlist(intvec c,list L)
+{
+  int i; list T;
+  for(i=1;i<=size(L);i++)
+  {
+    if (L[i][1]==c)
+    {
+      T=L[i][2];
+      break;
+    }
+  }
+  return(T);
+}
+
+// Auxiliary routine
+// comb: the list of combinations of elements (1,..n) of order p
+proc comb(int n, int p)
+{
+  list L; list L0;
+  intvec c; intvec d;
+  int i; int j; int last;
+  if ((n<0) or (n<p))
+  {
+    return(L);
+  }
+  if (p==1)
+  {
+    for (i=1;i<=n;i++)
+    {
+      c=i;
+      L[size(L)+1]=c;
+    }
+    return(L);
+  }
+  else
+  {
+    L0=comb(n,p-1);
+    for (i=1;i<=size(L0);i++)
+    {
+      c=L0[i]; d=c;
+      last=c[size(c)];
+      for (j=last+1;j<=n;j++)
+      {
+        d[size(c)+1]=j;
+        L[size(L)+1]=d;
+      }
+    }
+    return(L);
+  }
+}
+
+// Auxiliary routine
+// selectminsheaves
+// Input: L=((v_11,..,v_1k_1),..,(v_s1,..,v_sk_s))
+//    where:
+//    The s lists correspond to the s coefficients of the polynomial f
+//    (v_i1,..,v_ik_i) correspond to the k_i intvec v_ij of the
+//    spezializations of the jth rekpresentant (Q,P) of the ith coefficient
+//    v_ij is an intvec of size equal to the number of little segments
+//    forming the lpp-segment of 0,1, where 1 represents that it specializes
+//    to non-zedro an the whole little segment and 0 if not.
+// Output: S=(w_1,..,w_j)
+//    where the w_l=(n_l1,..,n_ls) are intvec of length size(L), where
+//    n_lt fixes which element of (v_t1,..,v_tk_t) is to be
+//    choosen to form the tth (Q,P) for the lth element of the sheaf
+//    representing the I-regular function.
+// The selection is done to obtian the minimal number of elements
+//    of the sheaf that specializes to non-null everywhere.
+proc selectminsheaves(list L)
+{
+  list C=allsheaves(L);
+  return(smsheaves(C[1],C[2]));
+}
+
+// Auxiliary routine
+// smsheaves
+// Input:
+//   list C of all the combrep
+//   list L of the intvec that correesponds to each element of C
+// Output:
+//   list LL of the subsets of C that cover all the subsegments
+//   (the union of the corresponding L(C) has all 1).
+proc smsheaves(list C, list L)
+{
+  int i; int i0; intvec W;
+  int nor; int norn;
+  intvec p;
+  int sp=size(L[1]); int j0=1;
+  for (i=1;i<=sp;i++){p[i]=1;}
+  while (p!=0)
+  {
+    i0=0; nor=0;
+    for (i=1; i<=size(L); i++)
+    {
+      norn=numones(L[i],pos(p));
+      if (nor<norn){nor=norn; i0=i;}
+    }
+    W[j0]=i0;
+    j0++;
+    p=actualize(p,L[i0]);
+  }
+  list LL;
+  for (i=1;i<=size(W);i++)
+  {
+    LL[size(LL)+1]=C[W[i]];
+  }
+  return(LL);
+}
+
+// Auxiliary routine
+// allsheaves
+// Input: L=((v_11,..,v_1k_1),..,(v_s1,..,v_sk_s))
+//    where:
+//    The s lists correspond to the s coefficients of the polynomial f
+//    (v_i1,..,v_ik_i) correspond to the k_i intvec v_ij of the
+//    spezializations of the jth rekpresentant (Q,P) of the ith coefficient
+//    v_ij is an intvec of size equal to the number of little segments
+//    forming the lpp-segment of 0,1, where 1 represents that it specializes
+//    to non-zero on the whole little segment and 1 if not.
+// Output:
+//    (list LL, list LLS)  where
+//    LL is the list of all combrep
+//    LLS is the list of intvec of the corresponding elements of LL
+proc allsheaves(list L)
+{
+  intvec V; list LL; intvec W; int r; intvec U;
+  int i; int j; int k;
+  int s=size(L[1][1]); // s = number of little segments of the lpp-segment
+  list LLS;
+  for (i=1;i<=size(L);i++)
+  {
+    V[i]=size(L[i]);
+  }
+  LL=combrep(V);
+  for (i=1;i<=size(LL);i++)
+  {
+    W=LL[i];   // size(W)= number of coefficients of the polynomial
+    kill U; intvec U;
+    for (j=1;j<=s;j++)
+    {
+      k=1; r=1; U[j]=1;
+      while((r==1) and (k<=size(W)))
+      {
+        if(L[k][W[k]][j]==0){r=0; U[j]=0;}
+        k++;
+      }
+    }
+    LLS[i]=U;
+  }
+  return(list(LL,LLS));
+}
+
+// Auxiliary routine
+// numones
+// Input:
+//   intvec v of (0,1) in each position
+//   intvec pos: the positions to test
+// Output:
+//   int nor: the nuber of 1 of v in the positions given by pos.
+proc numones(intvec v, intvec pos)
+{
+  int i; int n;
+  for (i=1;i<=size(pos);i++)
+  {
+    if (v[pos[i]]==1){n++;}
+  }
+  return(n);
+}
+
+// Auxiliary routine
+// pos
+// Input:  intvec p of zeros and ones
+// Output: intvec W of the positions where p has ones.
+proc pos(intvec p)
+{
+  int i;
+  intvec W; int j=1;
+  for (i=1; i<=size(p); i++)
+  {
+    if (p[i]==1){W[j]=i; j++;}
+  }
+  return(W);
+}
+
+// Auxiliary routine
+// actualize: actualizes zeroes of p
+// Input:
+//   intvec p: of zeroes and ones
+//   intvec c: of zeroes and ones (of the same length)
+// Output;
+//   intvec pp: of zeroes and ones, where a 0 stays in pp[i] if either
+//   already p[i]==0 or c[i]==1.
+proc actualize(intvec p, intvec c)
+{
+  int i; intvec pp=p;
+  for (i=1;i<=size(p);i++)
+  {
+    if ((pp[i]==1) and (c[i]==1)){pp[i]=0;}
+  }
+  return(pp);
+}
+
+// Auxiliary routine
+// combrep
+// Input: V=(n_1,..,n_i)
+// Output: L=(v_1,..,v_p) where p=prod_j=1^i (n_j)
+//    is the list of all intvec v_j=(v_j1,..,v_ji) where 1<=v_jk<=n_i
+proc combrep(intvec V)
+{
+  list L; list LL;
+  int i; int j; int k;  intvec W;
+  if (size(V)==1)
+  {
+    for (i=1;i<=V[1];i++)
+    {
+      L[i]=intvec(i);
+    }
+    return(L);
+  }
+  for (i=1;i<size(V);i++)
+  {
+    W[i]=V[i];
+  }
+  LL=combrep(W);
+  for (i=1;i<=size(LL);i++)
+  {
+    W=LL[i];
+    for (j=1;j<=V[size(V)];j++)
+    {
+      W[size(V)]=j;
+      L[size(L)+1]=W;
+    }
+  }
+  return(L);
+}
+
+// Auxiliary routine
+proc reducemodN(poly f,ideal E)
+{
+  def RR=basering;
+  setring(@RPt);
+  def fa=imap(RR,f);
+  def Ea=imap(RR,E);
+  attrib(Ea,"isSB",1);
+  // option(redSB);
+  // Ea=std(Ea);
+  fa=reduce(fa,Ea);
+  setring(RR);
+  def f1=imap(@RPt,fa);
+  return(f1);
+}
+
+// Auxiliary routine
+// intersp: computes the intersection of the ideals in S in @P
+proc intersp(list S)
+{
+  def RR=basering;
+  setring(@P);
+  def SP=imap(RR,S);
+  option(returnSB);
+  def NP=intersect(SP[1..size(SP)]);
+  setring(RR);
+  return(imap(@P,NP));
+}
+
+// Auxiliary routine
+// radicalmember
+proc radicalmember(poly f,ideal ida)
+{
+  int te;
+  def RR=basering;
+  setring(@P);
+  def fp=imap(RR,f);
+  def idap=imap(RR,ida);
+  poly @t;
+  ring H=0, at t,dp;
+  def PH=@P+H;
+  setring(PH);
+  def fH=imap(@P,fp);
+  def idaH=imap(@P,idap);
+  idaH[size(idaH)+1]=1- at t*fH;
+  option(redSB);
+  def G=std(idaH);
+  if (G==1){te=1;} else {te=0;}
+  setring(RR);
+  return(te);
+}
+
+// Auxiliary routine
+// NonNull: returns 1 if the poly f is nonnull on V(E)\V(N), 0 otherwise.
+proc NonNull(poly f, ideal E, ideal N)
+{
+  int te=1; int i;
+  def RR=basering;
+  setring(@P);
+  def fp=imap(RR,f);
+  def Ep=imap(RR,E);
+  def Np=imap(RR,N);
+  ideal H;
+  ideal Ef=Ep+fp;
+  for (i=1;i<=size(Np);i++)
+  {
+    te=radicalmember(Np[i],Ef);
+    if (te==0){break;}
+  }
+  setring(RR);
+  return(te);
+}
+
+// Auxiliary routine
+// selectextendcoef
+// input:
+//    matrix CC: CC=(p_a1 .. p_ar_a)
+//                  (q_a1 .. q_ar_a)
+//            the matrix of elements of a coefficient in oo[a].
+//    (ideal ida, ideal idb): the canonical representation of the segment S.
+// output:
+//    list caout
+//            the minimum set of elements of CC needed such that at least one
+//            of the q's is non-null on S, as well as the C-rep of of the
+//            points where the q's are null on S.
+//            The elements of caout are of the form (p,q,prep);
+proc selectextendcoef(matrix CC, ideal ida, ideal idb)
+{
+  def RR=basering;
+  setring(@P);
+  def ca=imap(RR,CC);
+  def E0=imap(RR,ida);
+  ideal E;
+  def N=imap(RR,idb);
+  int r=ncols(ca);
+  int i; int te=1; list com; int j; int k; intvec c; list prep;
+  list cs; list caout;
+  i=1;
+  while ((i<=r) and (te))
+  {
+    com=comb(r,i);
+    j=1;
+    while((j<=size(com)) and (te))
+    {
+      E=E0;
+      c=com[j];
+      for (k=1;k<=i;k++)
+      {
+        E=E+ca[2,c[k]];
+      }
+      prep=Prep(E,N);
+      if (i==1)
+      {
+        cs[j]=list(ca[1,j],ca[2,j],prep);
+      }
+      if ((size(prep)==1) and (equalideals(prep[1][1],ideal(1))))
+      {
+        te=0;
+        for(k=1;k<=size(c);k++)
+        {
+          caout[k]=cs[c[k]];
+        }
+      }
+      j++;
+    }
+    i++;
+  }
+  if (te){"error: extendcoef does not extend to the whole S";}
+  setring(RR);
+  return(imap(@P,caout));
+}
+
+// Auxiliary routine
+// input:
+//   ideal E1: in some basering (depends only on the parameters)
+//   ideal E2: in some basering (depends only on the parameters)
+// output:
+//   ideal Ep=E1+E2; computed in P
+proc plusP(ideal E1,ideal E2)
+{
+  def RR=basering;
+  setring(@P);
+  def E1p=imap(RR,E1);
+  def E2p=imap(RR,E2);
+  def Ep=E1p+E2p;
+  setring(RR);
+  return(imap(@P,Ep));
+}
+
+// Auxiliary routine
+// reform
+// input:
+//   list combpolys: (v1,..,vs)
+//      where vi are intvec.
+//   output outcomb: (w1,..,wt)
+//      whre wi are intvec.
+//      All the vi without zeroes are in outcomb, and those with zeroes are
+//         combined to form new intvec with the rest
+proc reform(list combpolys, intvec numdens)
+{
+  list combp0; list combp1; int i; int j; int k; int l; list rest; intvec notfree;
+  list free; intvec free1; int te; intvec v;  intvec w;
+  int nummonoms=size(combpolys[1]);
+  for(i=1;i<=size(combpolys);i++)
+  {
+    if(memberpos(0,combpolys[i])[1])
+    {
+      combp0[size(combp0)+1]=combpolys[i];
+    }
+    else {combp1[size(combp1)+1]=combpolys[i];}
+  }
+  for(i=1;i<=nummonoms;i++)
+  {
+    kill notfree; intvec notfree;
+    for(j=1;j<=size(combpolys);j++)
+    {
+      if(combpolys[j][i]<>0)
+      {
+        if(notfree[1]==0){notfree[1]=combpolys[j][i];}
+        else{notfree[size(notfree)+1]=combpolys[j][i];}
+      }
+    }
+    kill free1; intvec free1;
+    for(j=1;j<=numdens[i];j++)
+    {
+      if(memberpos(j,notfree)[1]==0)
+      {
+        if(free1[1]==0){free1[1]=j;}
+        else{free1[size(free1)+1]=j;}
+      }
+      free[i]=free1;
+    }
+  }
+  list amplcombp; list aux;
+  for(i=1;i<=size(combp0);i++)
+  {
+    v=combp0[i];
+    kill amplcombp; list amplcombp;
+    amplcombp[1]=intvec(v[1]);
+    for(j=2;j<=size(v);j++)
+    {
+      if(v[j]!=0)
+      {
+        for(k=1;k<=size(amplcombp);k++)
+        {
+          w=amplcombp[k];
+          w[size(w)+1]=v[j];
+          amplcombp[k]=w;
+        }
+      }
+      else
+      {
+        kill aux; list aux;
+        for(k=1;k<=size(amplcombp);k++)
+        {
+          for(l=1;l<=size(free[j]);l++)
+          {
+            w=amplcombp[k];
+            w[size(w)+1]=free[j][l];
+            aux[size(aux)+1]=w;
+          }
+        }
+        amplcombp=aux;
+      }
+    }
+    for(j=1;j<=size(amplcombp);j++)
+    {
+      combp1[size(combp1)+1]=amplcombp[j];
+    }
+  }
+  return(combp1);
+}
+
+// Auxiliary routine
+// nonnullCrep
+proc nonnullCrep(poly f0,ideal ida0,ideal idb0)
+{
+  int i;
+  def RR=basering;
+  setring(@P);
+  def f=imap(RR,f0);
+  def ida=imap(RR,ida0);
+  def idb=imap(RR,idb0);
+  def idaf=ida+f;
+  int te=1;
+  for(i=1;i<=size(idb);i++)
+  {
+    if(radicalmember(idb[i],idaf)==0)
+    {
+      te=0; break;
+    }
+  }
+  setring(RR);
+  return(te);
+}
+
+// Auxiliary routine
+// precombint
+// input:  L: list of ideals (works in @P)
+// output: F0: ideal of polys. F0[i] is a poly in the intersection of
+//             all ideals in L except in the ith one, where it is not.
+//             L=(p1,..,ps);  F0=(f1,..,fs);
+//             F0[i] \in intersect_{j#i} p_i
+proc precombint(list L)
+{
+  int i; int j; int tes;
+  def RR=basering;
+  setring(@P);
+  list L0; list L1; list L2; list L3; ideal F;
+  L0=imap(RR,L);
+  L1[1]=L0[1]; L2[1]=L0[size(L0)];
+  for (i=2;i<=size(L0)-1;i++)
+  {
+    L1[i]=intersect(L1[i-1],L0[i]);
+    L2[i]=intersect(L2[i-1],L0[size(L0)-i+1]);
+  }
+  L3[1]=L2[size(L2)];
+  for (i=2;i<=size(L0)-1;i++)
+  {
+    L3[i]=intersect(L1[i-1],L2[size(L0)-i]);
+  }
+  L3[size(L0)]=L1[size(L1)];
+  for (i=1;i<=size(L3);i++)
+  {
+    option(redSB); L3[i]=std(L3[i]);
+  }
+  for (i=1;i<=size(L3);i++)
+  {
+    tes=1; j=0;
+    while((tes) and (j<size(L3[i])))
+    {
+      j++;
+      option(redSB);
+      L0[i]=std(L0[i]);
+      if(reduce(L3[i][j],L0[i])!=0){tes=0; F[i]=L3[i][j];}
+    }
+    if (tes){"ERROR a polynomial in all p_j except p_i was not found";}
+  }
+  setring(RR);
+  def F0=imap(@P,F);
+  return(F0);
+}
+
+
+// Auxiliary routine
+// minAssGTZ eliminating denominators
+proc minGTZ(ideal N);
+{
+  int i; int j;
+  def L=minAssGTZ(N);
+  for(i=1;i<=size(L);i++)
+  {
+    for(j=1;j<=size(L[i]);j++)
+    {
+      L[i][j]=cleardenom(L[i][j]);
+    }
+  }
+  return(L);
+}
+
+//********************* Begin KapurSunWang *************************
+
+// Auxiliary routine
+// inconsistent
+// Input:
+//   ideal E: of null conditions
+//   ideal N: of non-null conditions representing V(E)\V(N)
+// Output:
+//   1 if V(E) \V(N) = empty
+//   0 if not
+proc inconsistent(ideal E, ideal N)
+{
+  int j;
+  int te=1;
+  def R=basering;
+  setring(@P);
+  def EP=imap(R,E);
+  def NP=imap(R,N);
+  poly @t;
+  ring H=0, at t,dp;
+  def RH=@P+H;
+  setring(RH);
+  def EH=imap(@P,EP);
+  def NH=imap(@P,NP);
+  ideal G;
+  j=1;
+  while((te==1) and j<=size(NH))
+  {
+    G=EH+(1- at t*NH[j]);
+    option(redSB);
+    G=std(G);
+    if (G[1]!=1){te=0;}
+    j++;
+  }
+  setring(R);
+  return(te);
+}
+
+// Auxiliary routine
+// MDBasis: Minimal Dickson Basis
+proc MDBasis(ideal G)
+{
+  int i; int j; int te=1;
+  G=sortideal(G);
+  ideal MD=G[1];
+  poly lm;
+  for (i=2;i<=size(G);i++)
+  {
+    te=1;
+    lm=leadmonom(G[i]);
+    j=1;
+    while ((te==1) and (j<=size(MD)))
+    {
+      if (lm/leadmonom(MD[j])!=0){te=0;}
+      j++;
+    }
+    if (te==1)
+    {
+      MD[size(MD)+1]=(G[i]);
+    }
+  }
+  return(MD);
+}
+
+// Auxiliary routine
+// primepartZ
+proc primepartZ(poly f);
+{
+  def R=basering;
+  def cp=content(f);
+  def fp=f/cp;
+  return(fp);
+}
+
+// LCMLC
+proc LCMLC(ideal H)
+{
+  int i;
+  def R=basering;
+  setring(@RP);
+  def HH=imap(R,H);
+  poly h=1;
+  for (i=1;i<=size(HH);i++)
+  {
+    h=lcm(h,HH[i]);
+  }
+  setring(R);
+  def hh=imap(@RP,h);
+  return(hh);
+}
+
+// KSW: Kapur-Sun-Wang algorithm for computing a CGS
+// Input:
+//   F:   parametric ideal to be discussed
+//   Options:
+//     \"out\",0 Transforms the description of the segments into
+//     canonical P-representation form.
+//     \"out\",1 Original KSW routine describing the segments as
+//     difference of varieties
+//   The ideal must be defined on C[parameters][variables]
+// Output:
+//   With option \"out\",0 :
+//     ((lpp,
+//       (1,B,((p_1,(p_11,..,p_1k_1)),..,(p_s,(p_s1,..,p_sk_s)))),
+//       string(lpp)
+//      )
+//      ,..,
+//      (lpp,
+//       (k,B,((p_1,(p_11,..,p_1k_1)),..,(p_s,(p_s1,..,p_sk_s)))),
+//       string(lpp))
+//      )
+//     )
+//   With option \"out\",1 ((default, original KSW) (shorter to be computed,
+//                    but without canonical description of the segments.
+//     ((B,E,N),..,(B,E,N))
+proc KSW(ideal F, list #)
+{
+  setglobalrings();
+  int start=timer;
+  ideal E=ideal(0);
+  ideal N=ideal(1);
+  int comment=0;
+  int out=1;
+  int i;
+  def L=#;
+  if (size(L)>0)
+  {
+    for (i=1;i<=size(L) div 2;i++)
+    {
+      if (L[2*i-1]=="null"){E=L[2*i];}
+      else
+      {
+        if (L[2*i-1]=="nonnull"){N=L[2*i];}
+        else
+        {
+          if (L[2*i-1]=="comment"){comment=L[2*i];}
+          else
+          {
+            if (L[2*i-1]=="out"){out=L[2*i];}
+          }
+        }
+      }
+    }
+  }
+  if (comment>0){string("Begin KSW with null = ",E," nonnull = ",N);}
+  def CG=KSW0(F,E,N,comment);
+  if (comment>0)
+  {
+    string("Number of segments in KSW (total) = ",size(CG));
+    string("Time in KSW = ",timer-start);
+  }
+  if(out==0)
+  {
+    CG=KSWtocgsdr(CG);
+    CG=groupKSWsegments(CG);
+    if (comment>0)
+    {
+      string("Number of lpp segments = ",size(CG));
+      string("Time in KSW + group + Prep = ",timer-start);
+    }
+  }
+  if(defined(@P)){kill @P; kill @R; kill @RP;}
+  return(CG);
+}
+
+// Auxiliary routine
+// sqf
+// This is for releases of Singular before 3-5-1
+// proc sqf(poly f)
+// {
+//  def RR=basering;
+//  setring(@P);
+//  def ff=imap(RR,f);
+//  def G=sqrfree(ff);
+//  poly fff=1;
+//  int i;
+//  for (i=1;i<=size(G);i++)
+//  {
+//    fff=fff*G[i];
+//  }
+//  setring(RR);
+//   def ffff=imap(@P,fff);
+//   return(ffff);
+// }
+
+// Auxiliary routine
+// sqf
+proc sqf(poly f)
+{
+  def RR=basering;
+  setring(@P);
+  def ff=imap(RR,f);
+  poly fff=sqrfree(ff,3);
+  setring(RR);
+  def ffff=imap(@P,fff);
+  return(ffff);
+}
+
+
+// Auxiliary routine
+// KSW0: Kapur-Sun-Wang algorithm for computing a CGS, called by KSW
+// Input:
+//   F:   parametric ideal to be discussed
+//   Options:
+//   The ideal must be defined on C[parameters][variables]
+// Output:
+proc KSW0(ideal F, ideal E, ideal N, int comment)
+{
+  def R=basering;
+  int i; int j; list emp;
+  list CGS;
+  ideal N0;
+  for (i=1;i<=size(N);i++)
+  {
+    N0[i]=sqf(N[i]);
+  }
+  ideal E0;
+  for (i=1;i<=size(E);i++)
+  {
+    E0[i]=sqf(leadcoef(E[i]));
+  }
+  setring(@P);
+  ideal E1=imap(R,E0);
+  E1=std(E1);
+  ideal N1=imap(R,N0);
+  N1=std(N1);
+  setring(R);
+  E0=imap(@P,E1);
+  N0=imap(@P,N1);
+//   E0=elimrepeated(E0);
+//   N0=elimrepeated(N0);
+  if (inconsistent(E0,N0)==1)
+  {
+    return(emp);
+  }
+  setring(@RP);
+  def FRP=imap(R,F);
+  def ERP=imap(R,E);
+  FRP=FRP+ERP;
+  option(redSB);
+  def GRP=std(FRP);
+  setring(R);
+  def G=imap(@RP,GRP);
+  if (memberpos(1,G)[1]==1)
+  {
+    if(comment>1){"Basis 1 is found"; E; N;}
+    list KK; KK[1]=list(E0,N0,ideal(1));
+    return(KK);
+   }
+  ideal Gr; ideal Gm; ideal GM;
+  for (i=1;i<=size(G);i++)
+  {
+    if (variables(G[i])[1]==0){Gr[size(Gr)+1]=G[i];}
+    else{Gm[size(Gm)+1]=G[i];}
+  }
+  ideal Gr0;
+  for (i=1;i<=size(Gr);i++)
+  {
+    Gr0[i]=sqf(Gr[i]);
+  }
+
+
+  Gr=elimrepeated(Gr0);
+  ideal GrN;
+  for (i=1;i<=size(Gr);i++)
+   {
+    for (j=1;j<=size(N0);j++)
+    {
+      GrN[size(GrN)+1]=sqf(Gr[i]*N0[j]);
+    }
+  }
+  if (inconsistent(E,GrN)){;}
+  else
+  {
+    if(comment>1){"Basis 1 is found in a branch with arguments"; E; GrN;}
+    CGS[size(CGS)+1]=list(E,GrN,ideal(1));
+  }
+  if (inconsistent(Gr,N0)){return(CGS);}
+  GM=Gm;
+  Gm=MDBasis(Gm);
+  ideal H;
+  for (i=1;i<=size(Gm);i++)
+  {
+    H[i]=sqf(leadcoef(Gm[i]));
+  }
+  H=facvar(H);
+  poly h=sqf(LCMLC(H));
+  if(comment>1){"H = "; H; "h = "; h;}
+  ideal Nh=N0;
+  if(size(N0)==0){Nh=h;}
+  else
+  {
+    for (i=1;i<=size(N0);i++)
+    {
+      Nh[i]=sqf(N0[i]*h);
+    }
+  }
+  if (inconsistent(Gr,Nh)){;}
+  else
+  {
+    CGS[size(CGS)+1]=list(Gr,Nh,Gm);
+  }
+  poly hc=1;
+  list KS;
+  ideal GrHi;
+  for (i=1;i<=size(H);i++)
+  {
+    kill GrHi;
+    ideal GrHi;
+    Nh=N0;
+    if (i>1){hc=sqf(hc*H[i-1]);}
+    for (j=1;j<=size(N0);j++){Nh[j]=sqf(N0[j]*hc);}
+    if (equalideals(Gr,ideal(0))==1){GrHi=H[i];}
+    else {GrHi=Gr,H[i];}
+//     else {for (j=1;j<=size(Gr);j++){GrHi[size(GrHi)+1]=Gr[j]*H[i];}}
+    if(comment>1){"Call to KSW with arguments "; GM; GrHi;  Nh;}
+    KS=KSW0(GM,GrHi,Nh,comment);
+    for (j=1;j<=size(KS);j++)
+    {
+      CGS[size(CGS)+1]=KS[j];
+    }
+    if(comment>1){"CGS after KSW = "; CGS;}
+  }
+  return(CGS);
+}
+
+// Auxiliary routine
+// KSWtocgsdr
+proc KSWtocgsdr(list L)
+{
+  int i; list CG; ideal B; ideal lpp; int j; list NKrep;
+  for(i=1;i<=size(L);i++)
+  {
+    B=redgbn(L[i][3],L[i][1],L[i][2]);
+    lpp=ideal(0);
+    for(j=1;j<=size(B);j++)
+    {
+      lpp[j]=leadmonom(B[j]);
+    }
+    NKrep=KtoPrep(L[i][1],L[i][2]);
+    CG[i]=list(lpp,B,NKrep);
+  }
+  return(CG);
+}
+
+// Auxiliary routine
+// KtoPrep
+// Computes the P-representaion of a K-representation (N,W) of a set
+// input:
+//    ideal E (null conditions)
+//    ideal N (non-null conditions ideal)
+// output:
+//    the ((p_1,(p_11,..,p_1k_1)),..,(p_r,(p_r1,..,p_rk_r)));
+//    the Prep of V(N) \ V(W)
+proc KtoPrep(ideal N, ideal W)
+{
+  int i; int j;
+  if (N[1]==1)
+  {
+    L0[1]=list(ideal(1),list(ideal(1)));
+    return(L0);
+  }
+  def RR=basering;
+  setring(@P);
+  ideal B; int te; poly f;
+  ideal Np=imap(RR,N);
+  ideal Wp=imap(RR,W);
+  list L;
+  list L0; list T0;
+  L0=minGTZ(Np);
+  for(j=1;j<=size(L0);j++)
+  {
+    option(redSB);
+    L0[j]=std(L0[j]);
+  }
+  for(i=1;i<=size(L0);i++)
+  {
+    if(inconsistent(L0[i],Wp)==0)
+    {
+      B=L0[i]+Wp;
+      T0=minGTZ(B);
+      option(redSB);
+      for(j=1;j<=size(T0);j++)
+      {
+        T0[j]=std(T0[j]);
+      }
+      L[size(L)+1]=list(L0[i],T0);
+    }
+  }
+  setring(RR);
+  def LL=imap(@P,L);
+  return(LL);
+}
+
+// Auxiliary routine
+// groupKSWsegments
+// input:  the list of vertices of KSW
+// output: the same terminal vertices grouped by lpp
+proc groupKSWsegments(list T)
+{
+  //"T_T="; T;
+  int i; int j;
+  list L;
+  list lpp; list lppor;
+  list kk;
+  lpp[1]=T[1][1]; j=1;
+  lppor[1]=intvec(1);
+  for(i=2;i<=size(T);i++)
+  {
+    kk=memberpos(T[i][1],lpp);
+    if(kk[1]==0){j++; lpp[j]=T[i][1]; lppor[j]=intvec(i);}
+    else{lppor[kk[2]][size(lppor[kk[2]])+1]=i;}
+  }
+  list ll;
+  for (j=1;j<=size(lpp);j++)
+  {
+    kill ll; list ll;
+    for(i=1;i<=size(lppor[j]);i++)
+    {
+      ll[size(ll)+1]=list(i,T[lppor[j][i]][2],T[lppor[j][i]][3]);
+    }
+    L[j]=list(lpp[j],ll,string(lpp[j]));
+  }
+  return(L);
+}
+
+//********************* End KapurSunWang *************************
+
+//******************** Begin locus ******************************
+
+// indepparameters
+// Auxiliary routine to detect "Special" components of the locus
+// Input: ideal B
+// Output:
+//   1 if the solutions of the ideal do not depend on the parameters
+//   0 if they depend
+proc indepparameters(ideal B)
+{
+  def R=basering;
+  ideal v=variables(B);
+  setring @RP;
+  def BP=imap(R,B);
+  def vp=imap(R,v);
+  ideal varpar=variables(BP);
+  int te;
+  te=equalideals(vp,varpar);
+  setring(R);
+  if(te){return(1);}
+  else{return(0);}
+}
+
+// dimP0: Auxiliary routine
+// if the dimension in @P of an ideal in the parameters has dimension 0 then it returns 0
+// else it retuns 1
+proc dimP0(ideal N)
+{
+  def R=basering;
+  setring(@P);
+  int te=1;
+  def NP=imap(R,N);
+  attrib(NP,"IsSB",1);
+  int d=dim(std(NP));
+  if(d==0){te=0;}
+  setring(R);
+  return(te);
+}
+
+// Auxiliary routine.
+// input:    ideals E and F (assumed in ring @P
+// returns: 1 if ideal E is contained in ideal F (assumed F is std basis)
+//              0 if not
+proc containedideal(ideal E, ideal F)
+{
+  int i; int t; poly f;
+  if(equalideals(F,ideal(0)))
+  {
+    if(equalideals(E,ideal(0))==0){return(0);}
+    else(return(1));
+  }
+  t=1; i=1;
+  while((t==1) and (i<=size(E)))
+  {
+    attrib(F,"isSB",1);
+    f=reduce(E[i],F);
+    if(f!=0){t=0;}
+    i++;
+  }
+  return(t);
+}
+
+// addcons: given a set of locally closed sets given in P-representation,
+//       (particularly a subset of components of a selection of segments
+//       of the Grobner cover), it builds the canonical P-representation
+//       of the corresponding constructible set, of its union, including levels it they are.
+// input: a list L of disjoint segments (for exmple a selection of segments of the Groebner cover)
+//       of the form
+//       ( ( (p1_1,(p1_11,..,p1_1k_1).. (p1_s,(p1_s1,..,p1_sk_s)),..,
+//         ( (pn_1,(pn_11,..,pn_1j_1).. (pn_s,(pn_s1,..,pn_sj_s))   )
+// output: The canonical P-representation of the  constructible set resulting by
+//       adding the given components.
+//       The first element of each component can be ignored. It is only for internal use.
+//       The fifth element of each component is the level of the constructible set
+//       of the component.
+//       It is no need a previous call to setglobalrings()
+proc addcons(list L)
+"USAGE:   addcons(  ( ( (p1_1,(p1_11,..,p1_1k_1).. (p1_s,(p1_s1,..,p1_sk_s)),..,
+  ( (pn_1,(pn_11,..,pn_1j_1).. (pn_s,(pn_s1,..,pn_sj_s))   )   )
+  a list L of locally closed sets in P-representation
+RETURN: the canonical P-representation of the constructible set of the union.
+NOTE:   It is called internally by the routines locus, locusdg,
+
+KEYWORDS: P-representation, constructible set
+EXAMPLE:  adccons; shows an example"
+{
+  int te;
+  if(defined(@P)){te=1;}
+  else{setglobalrings();}
+  list notadded; list P0;
+  int i; int j; int k; int l;
+  intvec v; intvec v1; intvec v0;
+  ideal J; list K; list L1;
+  for(i=1;i<=size(L);i++)
+  {
+    if(equalideals(L[i][1][1],ideal(1))==0)
+    {L1[size(L1)+1]=L[i];}
+  }
+  L=L1;
+  for(i=1;i<=size(L);i++)
+  {
+    for(j=1;j<=size(L[i]);j++)
+    {
+        v=i,j;
+        notadded[size(notadded)+1]=v;
+    }
+  }
+  //"T_notadded="; notadded;
+  int level=1;
+  list P=L;
+  list LL;
+  list Ln;
+  //int cont=0;
+  while(size(notadded)>0)
+  {
+    kill notadded; list notadded;
+    for(i=1;i<=size(P);i++)
+    {
+      for(j=1;j<=size(P[i]);j++)
+      {
+          v=i,j;
+          notadded[size(notadded)+1]=v;
+      }
+    }
+    //"T_notadded="; notadded;
+     //cont++;
+     P0=P;
+     Ln=LCUnion(P);
+     //"T_Ln="; Ln;
+     notadded=minuselements(notadded, at Q2);
+     //"T_ at Q2="; @Q2;
+     //"T_notadded="; notadded;
+     for(i=1;i<=size(Ln);i++)
+     {
+       //Ln[i][4]=  ; JA HAURIA DE VENIR DE LCUnion
+       Ln[i][5]=level;
+       LL[size(LL)+1]=Ln[i];
+     }
+     i=0;j=0;
+     v=0,0;
+     v0=0,0;
+     kill P; list P;
+     for(l=1;l<=size(notadded);l++)
+     {
+       v1=notadded[l];
+       if(v1[1]<>v0[1]){i++;j=1; P[i]=K;} // list P[i];
+       else
+       {
+         if(v1[2]<>v0[2])
+         {
+           j=j+1;
+         }
+       }
+       v=i,j;
+       //"T_v1="; v1;
+       P[i][j]=K; P[i][j][1]=J; P[i][j][2]=K;
+       P[i][j][1]=P0[v1[1]][v1[2]][1];
+       //"T_P0[v1[1]][v1[2]][2]="; P0[v1[1]][v1[2]][2];
+       //"T_size(P0[v1[1]][v1[2]][2])="; size(P0[v1[1]][v1[2]][2]);
+       for(k=1;k<=size(P0[v1[1]][v1[2]][2]);k++)
+       {
+         P[i][j][2][k]=P0[v1[1]][v1[2]][2][k];
+         //string("T_P[",i,"][",j,"][2][",k,"]="); P[i][j][2][k];
+       }
+       v0=v1;
+       //"T_P_1="; P;
+     }
+     //"T_P="; P;
+     level++;
+     //if(cont>3){break;}
+     //kill notadded; list notadded;
+  }
+  if(defined(@Q2)){kill @Q2;}
+  if(te==0){kill @P; kill @R; kill @RP;}
+  //"T_LL_sortida addcons="; LL; "Fi sortida";
+  return(LL);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+   ring R=(0,a,b),(x1,y1,x2,y2,p,r),dp;
+   ideal S93=(a+1)^2+b^2-(p+1)^2,
+                    (a-1)^2+b^2-(1-r)^2,
+                    a*y1-b*x1-y1+b,
+                    a*y2-b*x2+y2-b,
+                    -2*y1+b*x1-(a+p)*y1+b,
+                    2*y2+b*x2-(a+r)*y2-b,
+                    (x1+1)^2+y1^2-(x2-1)^2-y2^2;
+  short=0;
+  "System S93="; S93; " ";
+  def GC93=grobcov(S93);
+  "grobcov(S93)="; GC93; " ";
+  int i;
+  list H;
+  for(i=1;i<=size(GC93);i++){H[i]=GC93[i][3];}
+  "H="; H;
+  "addcons(H)="; addcons(H);
+}
+
+// Takes a list of intvec and sorts it and eliminates repeated elements.
+// Auxiliary routine used in addcons
+proc sortpairs(L)
+{
+  def L1=sort(L);
+  def L2=elimrepeated(L1[1]);
+  return(L2);
+}
+
+// Eliminates the pairs of L1 that are also in L2.
+// Auxiliary routine used in addcons
+proc minuselements(list L1,list L2)
+{
+  int i;
+  list L3;
+  for (i=1;i<=size(L1);i++)
+  {
+    if(not(memberpos(L1[i],L2)[1])){L3[size(L3)+1]=L1[i];}
+  }
+  return(L3);
+}
+
+// locus0(G): Private routine used by locus (the public routine), that
+//                builds the diferent components.
+// input:      The output G of the grobcov (in generic representation, which is the default option)
+// output:
+//         list, the canonical P-representation of the Normal and Non-Normal locus:
+//              The Normal locus has two kind of components: Normal and Special.
+//              The Non-normal locus has two kind of components: Accumulation and Degenerate.
+//              This routine is compemented by locus that calls it in order to eliminate problems
+//              with degenerate points of the mover.
+//         The output components are given as
+//              ((p1,(p11,..p1s_1),type_1,level_1),..,(pk,(pk1,..pks_k),type_k,level_k)
+//         The components are given in canonical P-representation of the subset.
+//              If all levels of a class of locus are 1, then the set is locally closed. Otherwise the level
+//              gives the depth of the component.
+proc locus0(list GG, list #)
+{
+  int t1=1; int t2=1;
+  def R=basering;
+  int moverdim=nvars(R);
+  list HHH;
+  if (GG[1][1][1]==1 and GG[1][2][1]==1 and GG[1][3][1][1][1]==0 and GG[1][3][1][2][1]==1){return(HHH);}
+  list Lop=#;
+  if(size(Lop)>0){moverdim=Lop[1];}
+  setglobalrings();
+  list G1; list G2;
+  def G=GG;
+  list Q1; list Q2;
+  int i; int d; int j; int k;
+  t1=1;
+  for(i=1;i<=size(G);i++)
+  {
+    attrib(G[i][1],"IsSB",1);
+    d=locusdim(G[i][2],moverdim);
+    if(d==0){G1[size(G1)+1]=G[i];}
+    else
+    {
+      if(d>0){G2[size(G2)+1]=G[i];}
+    }
+  }
+  if(size(G1)==0){t1=0;}
+  if(size(G2)==0){t2=0;}
+  setring(@RP);
+  if(t1)
+  {
+    list G1RP=imap(R,G1);
+  }
+  else {list G1RP;}
+  list P1RP;
+  ideal B;
+  for(i=1;i<=size(G1RP);i++)
+  {
+     kill B;
+     ideal B;
+     for(k=1;k<=size(G1RP[i][3]);k++)
+     {
+       attrib(G1RP[i][3][k][1],"IsSB",1);
+       G1RP[i][3][k][1]=std(G1RP[i][3][k][1]);
+       for(j=1;j<=size(G1RP[i][2]);j++)
+       {
+         B[j]=reduce(G1RP[i][2][j],G1RP[i][3][k][1]);
+       }
+       P1RP[size(P1RP)+1]=list(G1RP[i][3][k][1],G1RP[i][3][k][2],B);
+     }
+  }
+  setring(R);
+  ideal h;
+  if(t1)
+  {
+    def P1=imap(@RP,P1RP);
+    for(i=1;i<=size(P1);i++)
+    {
+      for(j=1;j<=size(P1[i][3]);j++)
+      {
+        h=factorize(P1[i][3][j],1);
+        P1[i][3][j]=h[1];
+        for(k=2;k<=size(h);k++)
+        {
+          P1[i][3][j]=P1[i][3][j]*h[k];
+        }
+      }
+    }
+  }
+  else{list P1;}
+  ideal BB;
+  for(i=1;i<=size(P1);i++)
+  {
+    if (indepparameters(P1[i][3])==1){P1[i][3]="Special";}
+    else{P1[i][3]="Normal";}
+  }
+  list P2;
+  for(i=1;i<=size(G2);i++)
+  {
+    for(k=1;k<=size(G2[i][3]);k++)
+    {
+      P2[size(P2)+1]=list(G2[i][3][k][1],G2[i][3][k][2]);
+    }
+  }
+  list l;
+  for(i=1;i<=size(P1);i++){Q1[i]=l; Q1[i][1]=P1[i];} P1=Q1;
+  for(i=1;i<=size(P2);i++){Q2[i]=l; Q2[i][1]=P2[i];} P2=Q2;
+
+  setring @P;
+  ideal J;
+  if(t1==1)
+  {
+    def C1=imap(R,P1);
+    def L1=addcons(C1);
+   }
+  else{list C1; list L1; kill P1; list P1;}
+  if(t2==1)
+  {
+    def C2=imap(R,P2);
+    def L2=addcons(C2);
+  }
+  else{list L2; list C2; kill P2; list P2;}
+    for(i=1;i<=size(L2);i++)
+    {
+      J=std(L2[i][2]);
+      d=dim(J); // AQUI
+      if(d==0)
+      {
+        L2[i][4]=string("Accumulation",L2[i][4]);
+      }
+      else{L2[i][4]=string("Degenerate",L2[i][4]);}
+    }
+  list LN;
+  if(t1==1)
+  {
+    for(i=1;i<=size(L1);i++){LN[size(LN)+1]=L1[i];}
+  }
+  if(t2==1)
+  {
+    for(i=1;i<=size(L2);i++){LN[size(LN)+1]=L2[i];}
+  }
+  setring(R);
+  def L=imap(@P,LN);
+  for(i=1;i<=size(L);i++){if(size(L[i][2])==0){L[i][2]=ideal(1);}}
+  kill @R; kill @RP; kill @P;
+  list LL;
+  for(i=1;i<=size(L);i++)
+  {
+    LL[i]=l;
+    LL[i]=elimfromlist(L[i],1);
+  }
+  return(LL);
+}
+
+// locus0dg(G): Private routine used by locusdg (the public routine), that
+//                builds the diferent components used in Dynamical Geometry
+// input:      The output G of the grobcov (in generic representation, which is the default option)
+// output:
+//         list, the canonical P-representation of the Relevant components of the locus in Dynamical Geometry,
+//              i.e. the Normal and Accumulation components.
+//              This routine is compemented by locusdg that calls it in order to eliminate problems
+//              with degenerate points of the mover.
+//         The output components are given as
+//              ((p1,(p11,..p1s_1),type_1,level_1),..,(pk,(pk1,..pks_k),type_k,level_k)
+//              whwre type_i is always "Relevant".
+//         The components are given in canonical P-representation of the subset.
+//              If all levels of a class of locus are 1, then the set is locally closed. Otherwise the level
+//              gives the depth of the component.
+proc locus0dg(list GG, list #)
+{
+  int t1=1; int t2=1; int ojo;
+  def R=basering;
+  int moverdim=nvars(R);
+  list HHH;
+  if (GG[1][1][1]==1 and GG[1][2][1]==1 and GG[1][3][1][1][1]==0 and GG[1][3][1][2][1]==1){return(HHH);}
+  list Lop=#;
+  if(size(Lop)>0){moverdim=Lop[1];}
+  setglobalrings();
+  list G1; list G2;
+  def G=GG;
+  list Q1; list Q2;
+  int i; int d; int j; int k;
+  t1=1;
+  for(i=1;i<=size(G);i++)
+  {
+    attrib(G[i][1],"IsSB",1);
+    d=locusdim(G[i][2],moverdim);
+    if(d==0){G1[size(G1)+1]=G[i];}
+    else
+    {
+      if(d>0){G2[size(G2)+1]=G[i];}
+    }
+  }
+  if(size(G1)==0){t1=0;}
+  if(size(G2)==0){t2=0;}
+  setring(@RP);
+  if(t1)
+  {
+    list G1RP=imap(R,G1);
+  }
+  else {list G1RP;}
+  list P1RP;
+  ideal B;
+  for(i=1;i<=size(G1RP);i++)
+  {
+     kill B;
+     ideal B;
+     for(k=1;k<=size(G1RP[i][3]);k++)
+     {
+       attrib(G1RP[i][3][k][1],"IsSB",1);
+       G1RP[i][3][k][1]=std(G1RP[i][3][k][1]);
+       for(j=1;j<=size(G1RP[i][2]);j++)
+       {
+         B[j]=reduce(G1RP[i][2][j],G1RP[i][3][k][1]);
+       }
+       P1RP[size(P1RP)+1]=list(G1RP[i][3][k][1],G1RP[i][3][k][2],B);
+     }
+  }
+  setring(R);
+  ideal h;
+  if(t1)
+  {
+    def P1=imap(@RP,P1RP);
+    for(i=1;i<=size(P1);i++)
+    {
+      for(j=1;j<=size(P1[i][3]);j++)
+      {
+        h=factorize(P1[i][3][j],1);
+        P1[i][3][j]=h[1];
+        for(k=2;k<=size(h);k++)
+        {
+          P1[i][3][j]=P1[i][3][j]*h[k];
+        }
+      }
+    }
+  }
+  else{list P1;}
+  ideal BB;
+  for(i=1;i<=size(P1);i++)
+  {
+    if (indepparameters(P1[i][3])==1){P1[i][3]="Special";}
+    else{P1[i][3]="Relevant";}
+  }
+  list P2;
+  for(i=1;i<=size(G2);i++)
+  {
+    for(k=1;k<=size(G2[i][3]);k++)
+    {
+      P2[size(P2)+1]=list(G2[i][3][k][1],G2[i][3][k][2]);
+    }
+  }
+  list l;
+  for(i=1;i<=size(P1);i++){Q1[i]=l; Q1[i][1]=P1[i];} P1=Q1;
+  for(i=1;i<=size(P2);i++){Q2[i]=l; Q2[i][1]=P2[i];} P2=Q2;
+
+  setring @P;
+  ideal J;
+  if(t1==1)
+  {
+    def C1=imap(R,P1);
+    def L1=addcons(C1);
+   }
+  else{list C1; list L1; kill P1; list P1;}
+  if(t2==1)
+  {
+    def C2=imap(R,P2);
+    def L2=addcons(C2);
+  }
+  else{list L2; list C2; kill P2; list P2;}
+    for(i=1;i<=size(L2);i++)
+    {
+      J=std(L2[i][2]);
+      d=dim(J); // AQUI
+      if(d==0)
+      {
+        L2[i][4]=string("Relevant",L2[i][4]);
+      }
+      else{L2[i][4]=string("Degenerate",L2[i][4]);}
+    }
+  list LN;
+  list ll; list l0;
+  if(t1==1)
+  {
+    for(i=1;i<=size(L1);i++)
+    {
+      if(L1[i][4]=="Relevant")
+      {
+       LN[size(LN)+1]=l0;
+       LN[size(LN)][1]=L1[i];
+     }
+    }
+  }
+  if(t2==1)
+  {
+    for(i=1;i<=size(L2);i++)
+    {
+      if(L2[i][4]=="Relevant")
+      {
+        LN[size(LN)+1]=l0;
+        LN[size(LN)][1]=L2[i];
+      }
+    }
+  }
+  list LNN;
+  kill ll; list ll; list lll; list llll;
+  for(i=1;i<=size(LN);i++)
+  {
+      LNN[size(LNN)+1]=l0;
+      ll=LN[i][1]; lll[1]=ll[2]; lll[2]=ll[3]; lll[3]=ll[4]; LNN[size(LNN)][1]=lll;
+  }
+  kill LN; list LN;
+  LN=addcons(LNN);
+  if(size(LN)==0){ojo=1;}
+  setring(R);
+  if(ojo==1){list L;}
+  else
+  {
+    def L=imap(@P,LN);
+    for(i=1;i<=size(L);i++){if(size(L[i][2])==0){L[i][2]=ideal(1);}}
+  }
+  kill @R; kill @RP; kill @P;
+  list LL;
+  for(i=1;i<=size(L);i++)
+  {
+    LL[i]=l;
+    LL[i]=elimfromlist(L[i],1);
+  }
+  return(LL);
+}
+
+
+//  locus(G):  Special routine for determining the locus of points
+//                 of  geometrical constructions. Given a parametric ideal J with
+//                 parameters (a_1,..a_m) and variables (x_1,..,xn),
+//                 representing the system determining
+//                 the locus of points (a_1,..,a_m) who verify certain
+//                 properties, computing the grobcov G of
+//                 J and applying to it locus, determines the different
+//                 classes of locus components. The components can be
+//                 Normal, Special, Accumulation, Degenerate.
+//                 The output are the components given in P-canonical form
+//                 of at most 4 constructible sets: Normal, Special, Accumulation,
+//                 Degenerate.
+//                 The description of the algorithm and definitions is
+//                 given in a forthcoming paper by Abanades, Botana, Montes, Recio.
+//                 Usually locus problems have mover coordinates, variables and tracer coordinates.
+//                 The mover coordinates are to be placed as the last variables, and by default,
+//                 its number is 2. If one consider locus problems in higer dimensions, the number of
+//                 mover coordinates (placed as the last variables) is to be given as an option.
+//
+//  input:      The output G of the grobcov (in generic representation, which is the default option for grobcov)
+//  output:
+//          list, the canonical P-representation of the Normal and Non-Normal locus:
+//               The Normal locus has two kind of components: Normal and Special.
+//               The Non-normal locus has two kind of components: Accumulation and Degenerate.
+//               Normal components: for each point in the component,
+//               the number of solutions in the variables is finite, and
+//               the solutions depend on the point in the component if the component is not 0-dimensional.
+//               Special components:  for each point in the component,
+//               the number of solutions in the variables is finite,
+//               the component is not 0-dimensional, but the solutions do not depend on the
+//               values of the parameters in the component.
+//               Accumlation points: are 0-dimensional components for which it exist
+//               an infinite number of solutions.
+//               Degenerate components: are components of dimension greater than 0 for which
+//               for every point in the component there exist infinite solutions.
+//          The output components are given as
+//               ((p1,(p11,..p1s_1),type_1,level_1),..,(pk,(pk1,..pks_k),type_k,level_k)
+//          The components are given in canonical P-representation of the subset.
+//               If all levels of a class of locus are 1, then the set is locally closed. Otherwise the level
+//               gives the depth of the component of the constructible set.
+proc locus(list GG, list #)
+  "USAGE:   locus(G);
+                 The input must be the grobcov  of a parametrical ideal
+  RETURN:  The  locus.
+                 The output are the components of four constructible subsets of the locus
+                 of the parametrical system: Normal , Special, Accumulation and Degenerate.
+                 These components are
+                 given as a list of  (pi,(pi1,..pis_i),type_i,level_i) varying i,
+                 where the p's are prime ideals, the type can be: Normal, Special,
+                 Accumulation, Degenerate.
+  NOTE:      It can only be called after computing the grobcov of the
+                 parametrical ideal in generic representation ('ext',0),
+                 which is the default.
+                 The basering R, must be of the form Q[a_1,..,a_m][x_1,..,x_n].
+  KEYWORDS: geometrical locus, locus, loci.
+  EXAMPLE:  locus; shows an example"
+{
+  def R=basering;
+  int dd=2; int comment=0;
+  list DD=#;
+  if (size(DD)>1){comment=1;}
+  if(size(DD)>0){dd=DD[1];}
+  int i; int j; int k;
+  def B0=GG[1][2];
+  if (equalideals(B0,ideal(1)))
+  {
+    return(locus0(GG));
+  }
+  else
+  {
+    int n=nvars(R);
+    ideal vmov=var(n-1),var(n);
+    ideal N;
+    intvec xw; intvec yw;
+    for(i=1;i<=n-1;i++){xw[i]=0;}
+    xw[n]=1;
+    for(i=1;i<=n;i++){yw[i]=0;}
+    yw[n-1]=1;
+    poly px; poly py;
+    int te=1;
+    i=1;
+    while( te and i<=size(B0))
+    {
+      if((deg(B0[i],xw)==1) and (deg(B0[i])==1)){px=B0[i]; te=0;}
+      i++;
+    }
+    i=1; te=1;
+    while( te and i<=size(B0))
+    {
+      if((deg(B0[i],yw)==1) and (deg(B0[i])==1)){py=B0[i]; te=0;}
+      i++;
+    }
+    N=px,py;
+    setglobalrings();
+    te=indepparameters(N);
+    if(te)
+    {
+      string("locus detected that the mover must avoid point (",N,") in order to obtain the correct locus");
+      // eliminates segments of GG where N is contained in the basis
+      list nGP;
+      def GP=GG;
+      ideal BP;
+      for(j=1;j<=size(GP);j++)
+      {
+        te=1; k=1;
+        BP=GP[j][2];
+        while((te==1) and (k<=size(N)))
+        {
+          if(pdivi(N[k],BP)[1]!=0){te=0;}
+          k++;
+        }
+        if(te==0){nGP[size(nGP)+1]=GP[j];}
+      }
+   }
+  }
+  kill @RP; kill @P; kill @R;
+  return(locus0(nGP,dd));
+}
+example
+{"EXAMPLE:"; echo = 2;
+  ring R=(0,a,b),(x4,x3,x2,x1),dp;
+  ideal S=(x1-3)^2+(x2-1)^2-9,
+             (4-x2)*(x3-3)+(x1-3)*(x4-1),
+             (3-x1)*(x3-x1)+(4-x2)*(x4-x2),
+             (4-x4)*a+(x3-3)*b+3*x4-4*x3,
+             (a-x1)^2+(b-x2)^2-(x1-x3)^2-(x2-x4)^2;
+  short=0;
+  locus(grobcov(S)); " ";
+  kill R;
+  ring R=(0,a,b),(x,y),dp;
+  short=0;
+  "Concoid";
+  ideal S96=x^2+y^2-4,(b-2)*x-a*y+2*a,(a-x)^2+(b-y)^2-1;
+  "System="; S96; " ";
+  locus(grobcov(S96));
+  kill R; ring R=(0,x,y),(x1,x2),dp;
+  ideal S=-(x - 5)*(x1 - 1) - (x2 - 2)*(y - 2),
+              (x1 - 5)^2 + (x2 - 2)^2 - 4,
+              -2*(x - 5)*(x2 - 2) + 2*(x1 - 5)*(y - 2);
+ "System="; S;
+  locus(grobcov(S)); " ";
+  ideal S1=-(x - x1)*(x1 - 4) + (x2 - y)*(x2 - 4),
+                (x1 - 4)^2 + (x2 - 2)^2 - 4,
+                -2*(x1 - 4)*(2*x2 - y - 4) - 2*(x - 2*x1 + 4)*(x2 - 2);
+ "System="; S1;
+  locus(grobcov(S1));
+}
+
+//  locusdg(G):  Special routine for determining the locus of points
+//                 of  geometrical constructions. Given a parametric ideal J with
+//                 parameters (a_1,..a_m) and variables (x_1,..,xn),
+//                 representing the system determining
+//                 the locus of points (a_1,..,a_m) who verify certain
+//                 properties, computing the grobcov G of
+//                 J and applying to it locus, determines the different
+//                 classes of locus components. The components can be
+//                 Normal, Special, Accumulation point, Degenerate.
+//                 The output are the components given in P-canonical form
+//                 of at most 4 constructible sets: Normal, Special, Accumulation,
+//                 Degenerate.
+//                 The description of the algorithm and definitions is
+//                 given in a forthcoming paper by Abanades, Botana, Montes, Recio.
+//                 Usually locus problems have mover coordinates, variables and tracer coordinates.
+//                 The mover coordinates are to be placed as the last variables, and by default,
+//                 its number is 2. If onw consider locus problems in higer dimensions, the number of
+//                 mover coordinates (placed as the last variables) is to be given as an option.
+//
+//  input:      The output G of the grobcov (in generic representation, which is the default option for grobcov)
+//  output:
+//          list, the canonical P-representation of the Normal and Non-Normal locus:
+//               The Normal locus has two kind of components: Normal and Special.
+//               The Non-normal locus has two kind of components: Accumulation and Degenerate.
+//               Normal components: for each point in the component,
+//               the number of solutions in the variables is finite, and
+//               the solutions depend on the point in the component if the component is not 0-dimensional.
+//               Special components:  for each point in the component,
+//               the number of solutions in the variables is finite,
+//               the component is not 0-dimensional, but the solutions do not depend on the
+//               values of the parameters in the component.
+//               Accumlation points: are 0-dimensional components for which it exist
+//               an infinite number of solutions.
+//               Degenerate components: are components of dimension greater than 0 for which
+//               for every point in the component there exist infinite solutions.
+//          The output components are given as
+//               ((p1,(p11,..p1s_1),type_1,level_1),..,(pk,(pk1,..pks_k),type_k,level_k)
+//          The components are given in canonical P-representation of the subset.
+//               If all levels of a class of locus are 1, then the set is locally closed. Otherwise the level
+//               gives the depth of the component of the constructible set.
+proc locusdg(list GG, list #)
+  "USAGE:   locus(G);
+                 The input must be the grobcov  of a parametrical ideal
+  RETURN:  The  locus.
+                 The output are the components of two constructible subsets of the locus
+                 of the parametrical system.: Normal and Non-normal.
+                 These components are
+                 given as a list of  (pi,(pi1,..pis_i),type_i,level_i) varying i,
+                 where the p's are prime ideals, the type can be: Normal, Special,
+                 Accumulation, Degenerate.
+  NOTE:      It can only be called after computing the grobcov of the
+                 parametrical ideal in generic representation ('ext',0),
+                 which is the default.
+                 The basering R, must be of the form Q[a_1,..,a_m][x_1,..,x_n].
+  KEYWORDS: geometrical locus, locus, loci.
+  EXAMPLE:  locusdg; shows an example"
+{
+  def R=basering;
+  int dd=2; int comment=0;
+  list DD=#;
+  if (size(DD)>1){comment=1;}
+  if(size(DD)>0){dd=DD[1];}
+  int i; int j; int k;
+  def B0=GG[1][2];
+  if (equalideals(B0,ideal(1)))
+  {
+    return(locus0dg(GG));
+  }
+  else
+  {
+    int n=nvars(R);
+    ideal vmov=var(n-1),var(n);
+    ideal N;
+    intvec xw; intvec yw;
+    for(i=1;i<=n-1;i++){xw[i]=0;}
+    xw[n]=1;
+    for(i=1;i<=n;i++){yw[i]=0;}
+    yw[n-1]=1;
+    poly px; poly py;
+    int te=1;
+    i=1;
+    while( te and i<=size(B0))
+    {
+      if((deg(B0[i],xw)==1) and (deg(B0[i])==1)){px=B0[i]; te=0;}
+      i++;
+    }
+    i=1; te=1;
+    while( te and i<=size(B0))
+    {
+      if((deg(B0[i],yw)==1) and (deg(B0[i])==1)){py=B0[i]; te=0;}
+      i++;
+    }
+    N=px,py;
+    setglobalrings();
+    te=indepparameters(N);
+    if(te)
+    {
+      string("locus detected that the mover must avoid point (",N,") in order to obtain the correct locus");
+      // eliminates segments of GG where N is contained in the basis
+      list nGP;
+      def GP=GG;
+      ideal BP;
+      for(j=1;j<=size(GP);j++)
+      {
+        te=1; k=1;
+        BP=GP[j][2];
+        while((te==1) and (k<=size(N)))
+        {
+          if(pdivi(N[k],BP)[1]!=0){te=0;}
+          k++;
+        }
+        if(te==0){nGP[size(nGP)+1]=GP[j];}
+      }
+   }
+  }
+  //"T_nGP="; nGP;
+  kill @RP; kill @P; kill @R;
+  return(locus0dg(nGP,dd));
+}
+example
+{"EXAMPLE:"; echo = 2;
+  ring R=(0,a,b),(x4,x3,x2,x1),dp;
+  ideal S=(x1-3)^2+(x2-1)^2-9,
+             (4-x2)*(x3-3)+(x1-3)*(x4-1),
+             (3-x1)*(x3-x1)+(4-x2)*(x4-x2),
+             (4-x4)*a+(x3-3)*b+3*x4-4*x3,
+             (a-x1)^2+(b-x2)^2-(x1-x3)^2-(x2-x4)^2;
+  short=0;
+  locus(grobcov(S)); " ";
+  kill R;
+  ring R=(0,a,b),(x,y),dp;
+  short=0;
+  "Concoid";
+  ideal S96=x^2+y^2-4,(b-2)*x-a*y+2*a,(a-x)^2+(b-y)^2-1;
+  "System="; S96; " ";
+  locusdg(grobcov(S96));
+  kill R; ring R=(0,x,y),(x1,x2),dp;
+  ideal S=-(x - 5)*(x1 - 1) - (x2 - 2)*(y - 2),
+              (x1 - 5)^2 + (x2 - 2)^2 - 4,
+              -2*(x - 5)*(x2 - 2) + 2*(x1 - 5)*(y - 2);
+ "System="; S;
+  locusdg(grobcov(S)); " ";
+  ideal S1=-(x - x1)*(x1 - 4) + (x2 - y)*(x2 - 4),
+                (x1 - 4)^2 + (x2 - 2)^2 - 4,
+                -2*(x1 - 4)*(2*x2 - y - 4) - 2*(x - 2*x1 + 4)*(x2 - 2);
+ "System="; S1;
+  locusdg(grobcov(S1));
+}
+
+// locusto: Transforms the output of locus to a string that
+//      can be read by different computational systems.
+// input:
+//     list L: The output of locus
+// output:
+//     string s: The output of locus converted to a string readable by other programs
+proc locusto(list L)
+"USAGE:   locusto(L);
+          The argument must be the output of locus of a parametrical ideal
+          It transforms the output into a string in standard form
+          readable in many languages (Geogebra).
+RETURN: The locus in string standard form
+NOTE:     It can only be called after computing the locus(grobcov(F)) of the
+              parametrical ideal.
+              The basering R, must be of the form Q[a,b,..][x,y,..].
+KEYWORDS: geometrical locus, locus, loci.
+EXAMPLE:  locusto; shows an example"
+{
+  int i; int j; int k;
+  string s="["; string sf="]"; string st=s+sf;
+  if(size(L)==0){return(st);}
+  ideal p;
+  ideal q;
+  for(i=1;i<=size(L);i++)
+  {
+    s=string(s,"[[");
+    for (j=1;j<=size(L[i][1]);j++)
+    {
+      s=string(s,L[i][1][j],",");
+    }
+    s[size(s)]="]";
+    s=string(s,",[");
+    for(j=1;j<=size(L[i][2]);j++)
+    {
+      s=string(s,"[");
+      for(k=1;k<=size(L[i][2][j]);k++)
+      {
+        s=string(s,L[i][2][j][k],",");
+      }
+      s[size(s)]="]";
+      s=string(s,",");
+    }
+    s[size(s)]="]";
+    s=string(s,"]");
+    if(size(L[i])>=3)
+    {
+      s[size(s)]=",";
+      s=string(s,string(L[i][3]),"]");
+    }
+    if(size(L[i])>=4)
+    {
+      s[size(s)]=",";
+      s=string(s,string(L[i][4]),"],");
+    }
+    s[size(s)]="]";
+    s=string(s,",");
+  }
+  s[size(s)]="]";
+  return(s);
+}
+example
+{"EXAMPLE:"; echo = 2;
+  ring R=(0,a,b),(x,y),dp;
+  short=0;
+  ideal S96=x^2+y^2-4,(b-2)*x-a*y+2*a,(a-x)^2+(b-y)^2-1;
+  "System="; S96; " ";
+  locusto(locus(grobcov(S96)));
+}
+
+// Auxiliary routione
+// locusdim
+// input:
+//    B:         ideal, a basis of a segment of the grobcov
+//    dgdim: int, the dimension of the mover (for locusdg)
+//                by default dgdim is equal to the number of variables
+proc locusdim(ideal B, list #)
+{
+  def R=basering;
+  int dgdim;
+  int nv=nvars(R);
+  if (size(#)>0){dgdim=#[1];}
+  else {dgdim=nv;}
+  int d;
+  list v;
+  ideal vi;
+  int i;
+  for(i=1;i<=dgdim;i++)
+  {
+    v[size(v)+1]=varstr(nv-dgdim+i);
+    vi[size(v)+1]=var(nv-dgdim+i);
+  }
+  ideal B0;
+  for(i=1;i<=size(B);i++)
+  {
+    if(subset(variables(B[i]),vi))
+    {
+      B0[size(B0)+1]=B[i];
+    }
+  }
+  //"T_B0="; B0;
+  //"T_v="; v;
+  def RR=ringlist(R);
+  def RR0=RR;
+  RR0[2]=v;
+  def R0=ring(RR0);
+  //ringlist(R0);
+  setring(R0);
+  def B0r=imap(R,B0);
+  B0r=std(B0r);
+  d=dim(B0r);
+  setring R;
+  return(d);
+}
+
+// locusdgto: Transforms the output of locus to a string that
+//      can be read by different computational systems.
+// input:
+//     list L: The output of locus
+// output:
+//     string s: The output of locus converted to a string readable by other programs
+//                   Outputs only the relevant dynamical geometry components.
+//                   Without unnecessary parenthesis
+proc locusdgto(list LL)
+{
+  def RR=basering;
+  int i; int j; int k; int short0=short; int ojo;
+  int te=0;
+  if(defined(@P)){te=1;}
+  else{setglobalrings();}
+  setring @P;
+  short=0;
+  if(size(LL)==0){ojo=1; list L;}
+  else
+  {
+    def L=imap(RR,LL);
+  }
+  string s="["; string sf="]"; string st=s+sf;
+  if(size(L)==0){return(st);}
+  ideal p;
+  ideal q;
+  for(i=1;i<=size(L);i++)
+  {
+    if(L[i][3]=="Relevant")
+    {
+      s=string(s,"[[");
+      for (j=1;j<=size(L[i][1]);j++)
+      {
+        s=string(s,L[i][1][j],",");
+      }
+      s[size(s)]="]";
+      s=string(s,",[");
+      for(j=1;j<=size(L[i][2]);j++)
+      {
+        s=string(s,"[");
+        for(k=1;k<=size(L[i][2][j]);k++)
+        {
+          s=string(s,L[i][2][j][k],",");
+        }
+        s[size(s)]="]";
+        s=string(s,",");
+      }
+      s[size(s)]="]";
+      s=string(s,"]");
+      s[size(s)]="]";
+      s=string(s,",");
+    }
+  }
+  if(s=="["){s="[]";}
+  else{s[size(s)]="]";}
+  setring(RR);
+  short=short0;
+  if(te==0){kill @P; kill @R; kill @RP;}
+  return(s);
+}
+
+//********************* End locus ****************************
+;
diff --git a/Singular/LIB/groups.lib b/Singular/LIB/groups.lib
new file mode 100644
index 0000000..001be3d
--- /dev/null
+++ b/Singular/LIB/groups.lib
@@ -0,0 +1,1123 @@
+//////////////////////////////////////////////////////////////////////////////
+version="version groups.lib 4.0.0.0 Jun_2013 "; // $Id: 0662b22472659602115c9b5d297e7c6c9391575b $
+category="Applications";
+info="
+LIBRARY:  groups.lib      Finite Group Theory
+AUTHORS:  Gert-Martin Greuel, email: greuel at mathematik.uni-kl.de @*
+          Gerhard Pfister, email: pfister at mathematik.uni-kl.de
+
+PROCEDURES:
+
+   noSolution(I)         I an ideal in a polynomial ring over Z[x1..xn]
+                         returns a list l of primes <=32003 such that 1
+                         is in IZ/p[x1..xn] for p not in l or an ERROR
+                         if this is wrong or not decided.
+"
+/*
+// ===================== A Problem in Finite Group Theory ===================
+// Posed by Boris Kunyavskii, Bar-Ilan University, Tel Aviv
+//
+// For any word w in X,Y,X^(-1),Y^(-1) consider the sequence U_n
+// of words (depending on w) inductively
+//           U_1 = w
+//         U_n+1 = [X*U_n*X^(-1),Y*U_n*Y^(-1)]
+// with
+//         [X,Y] = X*Y*X^(-1)*Y^(-1)  (the commutator)
+
+
+// Conjecture (1):
+// (by B. Plotkin, slightly modified):
+// A finite group G is solvable <==>
+// there is an n >= 1 such that U_n(x,y) = 1 for all x,y in G
+// and for any of the 4 following words
+//         w1 = X^(-1)*Y*X*Y^(-1)*X
+//         w2 = X^(-2)*Y^(-1)*X
+//         w3 = Y^(-2)*X^(-1)*X
+//         w4 = X*Y^(-2)*X^(-1)*Y*X^(-1)
+//
+// (These words remained as possibly good words by a computer search
+// through about 10 000 candidates, by Fritz Grunewald)
+
+
+//  ==>  is clear
+// The minimal finite non-solvable groups (i.e. every proper subgroup is
+// solvable) have been classified by Thompson in 1968, they are:
+//
+// 1. PSL(2,p)    (p=5 or p=+-2 (mod 5), p!=3)
+// 2. PSL(2,2^p)
+// 3. PSL(2,3^p)  (p odd)
+// 4. Sz(2^p)     (p odd)      (Suzuki group)
+// 5. PSL(3,3)
+//
+// In view of this result Conjecture (1) is equivalent to
+//
+// Conjecture (2):
+// Let G be one of the groups above, then, for at least one of the 4 words w
+// above there are x,y in G such that 1 != U_n(x,y) = U_n+1(x,y) for some n.
+// (then U_n(x,y) != 1 for all n by definitionof U_n)
+
+
+// We give a computer aided proof, using SINGULAR, of Conjecture (2) for
+// the groups 1. - 3. (up to checking for a small, explicit number of primes)
+// Hence only the Suzuki groups have to be checked.
+//
+// We show:  1 != U_1(x,y) = U_2(x,y) for word w1 and some x,y in G
+// We need:
+// Theory
+//   - simple facts from algebraic geometry, singularity theory, finite fields
+//   - theorem of Lang-Weil, estimating the number of rational points on an
+//     absolutely irreducible projective curve C defined over Z (g=genus):
+//     if q >= N(g) ==> #C(F_q) != 0
+//     (N(g) = 4g^2 -2, g arithmetic genus)
+// SINGULAR
+//   - Groebner basis (elimination), multivariate factorization, resolution of
+//     plane curve singularities (Hamburger Noether developement), primary
+//     decomposition
+
+*/
+
+LIB "standard.lib";
+LIB "general.lib";
+LIB "matrix.lib";
+///////////////////////////////////////////////////////////////////////////////
+
+static proc splitS1(ideal I,int s,list #)
+"USAGE: splitS1(I,s[,l]) I ideal, s integer, l list of ideals
+COMPUTE: Factorizes the generators of I. If for one generator f=f1*f2 and
+         fi=ni*gi^ri, ni an integer and gi a polynomial, then
+         compute a standardbasis of I1=I,g1 and I2=I,g2, if this can be
+         done in < s seconds. Then apply splitS to I1 and I2 and continue
+         in the same way. The procedure stops if no generator can be
+         factorized.
+RETURN:  A list L of ideals and prime numbers
+         L[1]: A list of ideals such that the radical of the intersection
+               of these ideals coincides with the radical of I
+               If the optional list l of the input is not empty then
+               the ideals of L[1] which contain an ideal of l are canceled.
+         L[2]: A list of prime numbers appearing as factors of the ni.
+NOTE:   The computation avoids division by integers (by using
+        option(contentSB)) hence the result is correct modulo any prime
+        number which does not appear in the list L[2].
+EXAMPLE: example splitS1; shows an example
+"
+{
+   option(redSB);
+   option(contentSB);
+   int j,k,e;
+   int i=1;
+   int l=attrib(I,"isSB");
+   ideal J;
+   list re,fac,te,pr,qr,w;
+   number n;
+   poly p;
+   re=#;
+
+   if(deg(I[1])==0){return(list(re+list(std(I)),qr));}
+
+   fac=factorize(I[1]);
+
+   while((size(fac[1])==2)&&(i<size(I)))
+   {
+      I[i]=fac[1][2]*fac[1][1];   //not in splitS
+      i++;
+      fac=factorize(I[i]);
+   }
+   if(size(fac[1])==2){I[size(I)]=fac[1][2]*fac[1][1];}  //not in splitS
+   if(size(fac[1])>2)
+   {
+      w=squarefreeP(number(fac[1][1]));
+      n=w[1];
+      qr=insResult(qr,w[2]);
+      for(j=2;j<=size(fac[1]);j++)
+      {
+         I[i]=fac[1][j];
+         attrib(I,"isSB",1);
+         e=1;
+         k=0;
+         while(k<size(re))
+         {
+            k++;
+            if(size(reduce(re[k],I))==0){e=0;break;}
+            attrib(re[k],"isSB",1);
+            if(size(reduce(I,re[k]))==0){re=delete(re,k);k--;}
+         }
+         if(j==2){I[i]=I[i]*n;}
+         if(e)
+         {
+            if(l)
+            {
+               J=I;
+               p=I[i];
+               J[i]=0;
+               J=simplify(J,2);
+               attrib(J,"isSB",1);
+               pr=splitS(std(J,p),s,re);
+               re=pr[1];
+               qr=insResult(qr,pr[2]);
+            }
+            else
+            {
+               J=interred(I);
+               pr=splitS(timeStd(J,s),s,re);
+               re=pr[1];
+               qr=insResult(qr,pr[2]);
+            }
+         }
+      }
+      return(list(re,qr));
+   }
+   J=timeStd(I,s);       //J=std(I) in splitS
+   attrib(I,"isSB",1);
+   if(size(reduce(J,I))==0){return(list(re+list(I),qr));}
+   pr=splitS(J,s,re);
+   return(list(re+pr[1],pr[2]));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r=0,(b,s,t,u,v,w,x,y,z),dp;
+   ideal i=
+   bv+su,
+   bw+tu,
+   sw+tv,
+   by+sx,
+   bz+tx,
+   sz+ty,
+   uy+vx,
+   uz+wx,
+   vz+wy,
+   bvz;
+   splitS1(i,5);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static proc splitS(ideal I,int s,list #)
+"USAGE: splitS(I,s[,l]) I ideal, s integer, l list of ideals
+COMPUTE: Factorizes the generators of I. If for one generator f=f1*f2 and
+         fi=ni*gi^ri, ni an integer and gi a polynomial, then
+         compute a standardbasis of I1=I,g1 and I2=I,g2, if this can be
+         done in < s seconds. Then apply splitS to I1 and I2 and continue
+         in the same way. The procedure stops if no generator can be
+         factorized.
+RETURN:  A list L of ideals and prime numbers
+         L[1]: A list of ideals such that the radical of the intersection
+               of these ideals coincides with the radical of I
+               If the optional list l of the input is not empty then
+               the ideals of L[1] which contain an ideal of l are canceled.
+         L[2]: A list of prime numbers appearing as factors of the ni.
+NOTE:   The computation avoids division by integers (by using
+        option(contentSB)) hence the result is correct modulo any prime
+        number which does not appear in the list L[2].
+EXAMPLE: example splitS; shows an example
+"
+{
+   option(redSB);
+   option(contentSB);
+   int j,k,e;
+   int i=1;
+   int l=attrib(I,"isSB");
+   ideal J;
+   list re,fac,te,pr,qr,w;
+   number n;
+   poly p;
+   re=#;
+
+   if(deg(I[1])==0){return(list(re+list(std(I)),qr));}
+
+   fac=factorize(I[1]);
+
+   while((size(fac[1])==2)&&(i<size(I)))
+   {
+      i++;
+      fac=factorize(I[i]);
+   }
+   if(size(fac[1])>2)
+   {
+      w=squarefreeP(number(fac[1][1]));
+      n=w[1];
+      qr=insResult(qr,w[2]);
+      for(j=2;j<=size(fac[1]);j++)
+      {
+         I[i]=fac[1][j];
+         attrib(I,"isSB",1);
+         e=1;
+         k=0;
+         while(k<size(re))
+         {
+            k++;
+            if(size(reduce(re[k],I))==0){e=0;break;}
+            attrib(re[k],"isSB",1);
+            if(size(reduce(I,re[k]))==0){re=delete(re,k);k--;}
+         }
+         if(j==2){I[i]=I[i]*n;}
+         if(e)
+         {
+            if(l)
+            {
+               J=I;
+               p=I[i];
+               J[i]=0;
+               J=simplify(J,2);
+               attrib(J,"isSB",1);
+               pr=splitS(std(J,p),s,re);
+               re=pr[1];
+               qr=insResult(qr,pr[2]);
+            }
+            else
+            {
+               J=interred(I);
+               pr=splitS(timeStd(J,s),s,re);
+               re=pr[1];
+               qr=insResult(qr,pr[2]);
+            }
+         }
+      }
+      return(list(re,qr));
+   }
+   J=std(I);
+   attrib(I,"isSB",1);
+   if(size(reduce(J,I))==0){return(list(re+list(I),qr));}
+   pr=splitS(J,s,re);
+   return(list(re+pr[1],pr[2]));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r=0,(b,s,t,u,v,w,x,y,z),dp;
+   ideal i=
+   bv+su,
+   bw+tu,
+   sw+tv,
+   by+sx,
+   bz+tx,
+   sz+ty,
+   uy+vx,
+   uz+wx,
+   vz+wy,
+   bvz;
+   splitS(i,5);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static proc finalSplit(list I,list qr)
+"USAGE: finalSplit(I,qr) I list of ideals, qr list of primes
+RETURN: list l of primes <=32003 such that 1 is in I[j]Z/p[x1..xn]
+        for p not in l and all j or an ERROR if this is wrong or
+        not decided.
+EXAMPLE: example finalSplit; shows an example
+"
+{
+   option(redThrough);
+   option(contentSB);
+   ideal J,K;
+   int i,j,k,n;
+   int count=1;
+   list q,pr,l;
+
+   "trivial splitting";
+   pr=trivialSplit(I,4);
+   l=pr[1];
+   qr=insResult(qr,pr[2]);
+   while(count)
+   {
+      k++;
+      "loop";k;size(l);"======";
+      count=0;list p;
+      for(i=1;i<=size(l);i++)
+      {
+         i;
+         K=changeOrdTest(l[i]);
+         if(deg(K[1])!=0)
+         {
+            "split";
+            pr=splitS1(shortid_L(K,3),2);
+            q=pr[1];
+            qr=insResult(qr,pr[2]);
+            size(q);"out";
+            for(j=1;j<=size(q);j++)
+            {
+               if(deg(q[j][1])==0)
+               {
+                  pr=contentS(q[j]);
+                  q[j]=pr[1];
+                  qr=insResult(qr,pr[2]);
+               }
+               else
+               {
+                  pr=simpliFy(q[j]+K);
+                  q[j]=pr[1];
+                  qr=insResult(qr,pr[2]);
+                  pr=contentS(q[j]);
+                  q[j]=pr[1];
+                  qr=insResult(qr,pr[2]);
+               }
+            }
+            if((size(q)==1)&&(deg(q[1][1])>0))
+            {
+               "split again";
+               K=sort(q[1])[1];
+               J=K[1..20+4*k];
+               pr=splitS(J,5);
+               q=pr[1];
+               qr=insResult(qr,pr[2]);
+               size(q);"out";
+               for(j=1;j<=size(q);j++)
+               {
+                  if(deg(q[j][1])==0)
+                  {
+                     pr=contentS(q[j]);
+                     q[j]=pr[1];
+                     qr=insResult(qr,pr[2]);
+                  }
+                  else
+                  {
+                     pr=simpliFy(q[j]+K);
+                     q[j]=pr[1];
+                     qr=insResult(qr,pr[2]);
+                     pr=contentS(q[j]);
+                     q[j]=pr[1];
+                     qr=insResult(qr,pr[2]);
+                  }
+               }
+
+            }
+            if((size(q)==1)&&(deg(q[1][1])>0))
+            {
+               n++;
+               "split again";
+               K=q[1];
+               J=shortid_L(K,3+n);
+               pr=splitS1(J,5);
+               if(size(pr[1])>1)
+               {
+                  q=pr[1];
+                  qr=insResult(qr,pr[2]);
+                  size(q);"out";
+                  for(j=1;j<=size(q);j++)
+                  {
+                     if(deg(q[j][1])==0)
+                     {
+                       pr=contentS(q[j]);
+                       q[j]=pr[1];
+                       qr=insResult(qr,pr[2]);
+                     }
+                     else
+                     {
+                       pr=simpliFy(q[j]+K);
+                       q[j]=pr[1];
+                       qr=insResult(qr,pr[2]);
+                       pr=contentS(q[j]);
+                       q[j]=pr[1];
+                       qr=insResult(qr,pr[2]);
+                     }
+                  }
+               }
+            }
+            if(size(q)>1)
+            {
+                count++;
+            }
+            else
+            {
+               if(deg(q[1][1])>0)
+               {
+                  q[1]=changeOrdTest(q[1]);
+               }
+            }
+            p=p+q;
+         }
+         else
+         {
+           pr=primefactors(number(K[1]));
+           qr=insResult(qr,pr[1]);
+         }
+      }
+      l=p;
+      kill p;
+   }
+l;
+   for(i=1;i<=size(l);i++)
+   {
+
+      if(deg(l[i][1])>0){l;ERROR("not ready");}
+      pr=primefactors(number(l[i][1]));
+      if(pr[3]!=1){pr;ERROR("not ready");}
+      qr=insResult(qr,pr[1]);
+   }
+   return(qr);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r=0,x,dp;
+   list qr=2,5,7;
+   ideal i=181x-181,11x+11;
+   list pr=i;
+   finalSplit(pr,qr);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+proc noSolution(ideal I)
+"USAGE: noSolution(I) I ideal
+RETURN: list l of primes <=32003 such that 1 is in IZ/p[x1..xn]
+        for p not in l or an ERROR if this is wrong or not decided.
+EXAMPLE: example noSolution; shows an example
+"
+{
+   int s=1;
+   int t=30;
+   option(redThrough);
+   option(contentSB);
+   ideal J=shortid_L(I,3);
+   ideal K;
+   number n;
+
+   "first splitting";
+   int i,j,k;
+   list l,p,q,re,pr,qr;
+   pr=splitS(J,s);
+   l=pr[1];
+   qr=pr[2];
+   size(l);
+
+   for(i=1;i<=size(l);i++)
+   {
+      if(deg(l[i][1])==0)
+      {
+         K=l[i][1];
+      }
+      else
+      {
+         pr=simpliFy(I+l[i]);
+         J=pr[1];
+         qr=insResult(qr,pr[2]);
+         pr=contentS(J);
+         J=pr[1];
+         qr=insResult(qr,pr[2]);
+         K=timeStd(J,1);
+      }
+      if(deg(K[1])==0)
+      {
+         n=number(K[1]);
+         pr=primefactors(n);
+         if(pr[3]!=1)
+         {
+             J=changeOrdTest(J);
+             p=p+list(J);
+         }
+         else
+         {
+             qr=insResult(qr,pr[1]);
+         }
+      }
+      else
+      {
+         pr=contentS(K);
+         p=p+list(pr[1]);
+         qr=insResult(qr,pr[2]);
+      }
+   }
+   "trivial splitting 1";
+   pr=trivialSplit(p,3);
+   p=pr[1];
+   qr=insResult(qr,pr[2]);
+   size(p);
+   "second splitting";
+
+   for(i=1;i<=size(p);i++)
+   {
+      i;
+      if(size(p[i])<t)
+      {
+         K=timeStd(p[i],10);
+         if(deg(K[1])==0)
+         {
+            n=number(K[1]);
+            pr=primefactors(n);
+            if(pr[3]!=1)
+            {
+                p[i]=changeOrdTest(p[i]);
+                re=re+list(p[i]);
+            }
+            else
+            {
+               qr=insResult(qr,pr[1]);
+            }
+         }
+         else
+         {
+            pr=contentS(K);
+            re=re+list(pr[1]);
+            qr=insResult(qr,pr[2]);
+         }
+      }
+      else
+      {
+         J=p[i];
+         J=J[1..t];
+         "in splitting";
+         pr=splitS(J,s);
+         l=pr[1];
+         qr=insResult(qr,pr[2]);
+         size(l);
+         "out";
+         for(k=1;k<=size(l);k++)
+         {
+            pr=contentS(l[k]);
+            l[k]= pr[1];
+            qr=insResult(qr,pr[2]);
+            pr=simpliFy(l[k]+p[i]);
+            J=pr[1];
+            qr=insResult(qr,pr[2]);
+            K=timeStd(J,10);
+            if(deg(K[1])==0)
+            {
+               n=number(K[1]);
+               pr=primefactors(n);
+               if(pr[3]!=1)
+               {
+                  pr=contentS(J);
+                  qr=insResult(qr,pr[2]);
+                  J=pr[1];
+                  J=changeOrdTest(J);
+                  re=re+list(J);
+               }
+               else
+               {
+                  qr=insResult(qr,pr[1]);
+               }
+            }
+            else
+            {
+               pr=contentS(K);
+               qr=insResult(qr,pr[2]);
+               re=re+list(pr[1]);
+            }
+         }
+      }
+   }
+   "trivial splitting 2";
+   size(re);
+   pr=trivialSplit(re,2);
+   re=pr[1];
+   qr=insResult(qr,pr[2]);
+   "third splitting";
+   size(re);
+   for(i=1;i<=size(re);i++)
+   {
+      if(deg(re[i][1])>0)
+      {
+         i;
+         pr=simpliFy(re[i]);
+         J=pr[1];
+         qr=insResult(qr,pr[2]);
+         "in splitting";
+         J=shortid_L(J,3);
+         pr=splitS(J,s);
+         l=pr[1];
+         if(size(l)==1)
+         {
+            "split again";
+            pr=simpliFy(re[i]);
+            J=pr[1];
+            qr=insResult(qr,pr[2]);
+            J=J[1..t];
+            pr=splitS(J,s);
+            l=pr[1];
+            qr=insResult(qr,pr[2]);
+         }
+         else
+         {
+            qr=insResult(qr,pr[2]);
+         }
+         size(l);
+         "out";
+         for(j=1;j<=size(l);j++)
+         {
+            pr=contentS(l[j]);
+            l[j]=pr[1];
+            qr=insResult(qr,pr[2]);
+            pr=simpliFy(re[i]+l[j]);
+            J=pr[1];
+            qr=insResult(qr,pr[2]);
+            K=timeStd(J,10);
+            if(deg(K[1])==0)
+            {
+               n=number(K[1]);
+               pr=primefactors(n);
+               if(pr[3]!=1)
+               {
+                  pr=contentS(J);
+                  J=pr[1];
+                  qr=insResult(qr,pr[2]);
+                  J=changeOrdTest(J);
+                  q=q+list(J);
+               }
+               else
+               {
+                 qr=insResult(qr,pr[1]);
+               }
+            }
+            else
+            {
+               pr=contentS(K);
+               qr=insResult(qr,pr[2]);
+               q=q+list(pr[1]);
+            }
+         }
+      }
+      else
+      {
+         i;
+         pr=primefactors(number(re[i][1]));
+         qr=insResult(qr,pr[1]);
+      }
+   }
+"jetzt geht es los";
+   return(finalSplit(q,qr));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r=0,x,dp;
+   ideal i=181x-181,11x+11;
+   noSolution(i);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static proc changeOrdTest(ideal I)
+{
+   def R=basering;
+   if(deg(I[1])==0){return(I);}
+   def RR=changeord(list(list("dp",1:nvars(basering))));
+   setring RR;
+   ideal I=imap(R,I);
+   ideal K=timeStd(I,5);
+   if(deg(K[1])==0)
+   {
+      number n=number(K[1]);
+      if(primefactors(n)[3]==1)
+      {
+         I=K;
+      }
+   }
+   setring R;
+   I=imap(RR,I);
+   kill RR;
+   return(I);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+static proc trivialSplit(list p,int depth, list #)
+"USAGE: trivialSplit(p,s) p list of ideals, s integer the number of iterations
+COMPUTE: Factorizes the monomials among the generators of I.
+         If  one monomial contains the variables x1,..xr, then
+         I1=I(x1=0),...,Ir=I(xr=0) is considered. Then apply
+         trivialSplit to I1 ...Ir and continue in the same way s times.
+RETURN:  A list L of ideals and prime numbers
+         L[1]: A list of ideals such that the radical of the intersection
+               of these ideals at x1=...=xr=0 coincides with the radical of
+               I at x1=...=xr=0.
+         L[2]: A list of prime numbers appearing as factors of the monomials.
+NOTE:   The computation avoids division by integers  hence the result
+        is correct modulo any prime
+        number which does not appear in the list L[2].
+EXAMPLE: example trivialSplit; shows an example
+"
+{
+   list re,l,pr,qr;
+   int i,k;
+   ideal J,K,T,Ke;
+   number n;
+
+   if(size(p)==0){return(list(p,qr));}
+   if(depth<=0){return(list(p,qr));}
+   if(size(#)>0)
+   {
+      T=#[1];
+   }
+   else
+   {
+      T=1;
+   }
+   for(k=1;k<=size(p);k++)
+   {
+      pr=simpliFy(p[k]);
+      p[k]=pr[1];
+      qr=insResult(qr,pr[2]);
+      J=shortid_L(p[k],1);
+      if((size(J)>0)&&(deg(J[1])>=1))
+      {
+         pr=splitS1(J,10);
+         l=pr[1];
+         qr=insResult(qr,pr[2]);
+         for(i=1;i<=size(l);i++)
+         {
+            Ke=l[i];
+            l[i]=trivialSimplify(p[k],l[i]);
+            pr=simpliFy(l[i]);
+            l[i]=pr[1];
+            qr=insResult(qr,pr[2]);
+            K=timeStd(l[i],1);
+            attrib(K,"isSB",1);
+            if(deg(K[1])==0)
+            {
+               n=number(K[1]);
+               if(primefactors(n)[3]!=1)
+               {
+                  l[i]=changeOrdTest(l[i]);
+                  pr=trivialSplit(l[i],depth-1,T);
+                  re=re+pr[1];
+                  qr=insResult(qr,pr[2]);
+               }
+               else
+               {
+                  l[i]=K; //neu
+               }
+            }
+            else
+            {
+               if(size(reduce(trivialSimplify(T,Ke),K))!=0)
+               {
+                  pr=trivialSplit(K,depth-1,trivialSimplify(T,Ke));
+                  re=re+pr[1];
+                  qr=insResult(qr,pr[2]);
+               }
+            }
+            T=intersect(T,Ke);
+         }
+      }
+      else
+      {
+         J=timeStd(p[k],5);
+         if(deg(J[1])==0)
+         {
+            n=number(J[1]);
+            if(primefactors(n)[3]!=1)
+            {
+               p[k]=changeOrdTest(p[k]);
+               re=re+list(p[k]);
+            }
+            else
+            {
+                re=re+list(J);
+            }
+         }
+         else
+         {
+            re=re+list(J);
+         }
+      }
+   }
+   return(list(re,qr));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r=0,(b,s,t,u,v,w,x,y,z),dp;
+   ideal i=
+   bv+su,
+   bw+tu,
+   sw+tv,
+   by+sx,
+   bz+tx,
+   sz+ty,
+   uy+vx,
+   uz+wx,
+   vz+wy,
+   bvz;
+   trivialSplit(i,2);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static proc trivialSimplify(ideal I, ideal J)
+"USAGE:  trivialSimplify(I,J);  I,J ideals, J generated by variables
+RETURN:  ideal K = eliminate(I,m) m the product of variables of J
+EXAMPLE: example trivialSimplify; shows an example
+"
+{
+   int i;
+   for(i=1;i<=size(J);i++){I=subst(I,J[i],0);}
+   return(simplify(I,2));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r=0,(x,y,z,w,t,u),dp;
+   ideal i=
+   t,u,
+   x3+y2+2z,
+   x2+3y,
+   x2+y2+z2,
+   w2+z+u;
+   ideal j=t,u;
+   trivialSimplify(i,j);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static proc simpliFy(ideal J,list #)
+"USAGE:  simpliFy(id);  id ideal
+RETURN:  ideal I = eliminate(Id,m) m is a product of variables
+         which are in linear equations involved in the generators of id
+EXAMPLE: example simpliFy; shows an example
+"
+{
+   ideal I=J;
+   if(size(#)!=0){I=#[1];}
+   def R=basering;
+   matrix M=jacob(I);
+   ideal ma=maxideal(1);
+   int i,j,k;
+   map phi;
+   list pr,re;
+
+   for(i=1;i<=nrows(M);i++)
+   {
+      for(j=1;j<=ncols(M);j++)
+      {
+         if((deg(M[i,j])==0)&&(deg(I[i])==1))
+         {
+            ma[j]=(-1/M[i,j])*(I[i]-M[i,j]*var(j));
+            pr=primefactors(number(M[i,j]));
+            if(pr[3]>1){pr[3];ERROR("number too big in simpliFy");}
+            re=insResult(re,pr[1]);
+            phi=R,ma;
+            I=phi(I);
+            J=phi(J);
+            for(k=1;k<=ncols(I);k++)
+            {
+               I[k]=cleardenom(I[k]);
+            }
+            M=jacob(I);
+         }
+      }
+   }
+   J=simplify(J,2);
+   for(i=1;i<=size(J);i++)
+   {
+      if(deg(J[i])==0){J=std(J);break;}
+      J[i]=cleardenom(J[i]);
+   }
+   return(list(J,re));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r=0,(x,y,z,w),dp;
+   ideal i=
+   x3+y2+2z,
+   x2+3y,
+   x2+y2+z2,
+   w2+z;
+   simpliFy(i);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+static proc squarefreeP(number n)
+"USAGE:  squarefreeP(n);  n number
+RETURN:  list l of numbers. l[2] contains all prime factors of n less
+         then 32003, l[1] is the part of m which has prime factors greater
+         then 32003
+EXAMPLE: example squarefreeP; shows an example
+"
+{
+   list re;
+   if(n<0){n=-n;}
+   if(n==1){return(list(n,re));}
+   list pr=primefactors(n);
+   int i;
+   number m=number(pr[3][1]);
+   re=insResult(re,pr[1]);
+   return(list(m,re));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r = 0,x,dp;
+   squarefreeP(123456789100);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static proc contentS(ideal I)
+"USAGE:  contentS(I);  I ideal
+RETURN:  list l
+         l[1] the ideal I. Te generators of I are the generators of the
+         input ideal devided by the part of the content which have
+         prime factors less then 32003.
+         l[2] contains the prime numbers which occured in the division
+EXAMPLE: example contentS; shows an example
+"
+
+{
+   option(contentSB);
+   int i,k;
+   number n,m;
+   list pr,re;
+   for(i=1;i<=size(I);i++)
+   {
+      n=leadcoef(I[i]);
+      if(n<0){n=-n;}
+      if(n>1)
+      {
+         pr=primefactors(n);
+         if(n<=32003)
+         {
+            m=n;
+         }
+         else
+         {
+            m=number(pr[1][1])^pr[2][1];
+            for(k=2;k<=size(pr[1]);k++)
+            {
+               m=m*number(pr[1][k])^pr[2][k];
+            }
+         }
+         I[i]=cleardenom(I[i]/m);
+         re=insResult(re,pr[1]);
+      }
+   }
+   return(list(I,re));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r = 0,(x,y),dp;
+   ideal I=2x+2,3y+3x,1234567891x+1234567891;
+   contentS(I);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static proc insResult(list r,#)
+{
+   if(size(#)==0){return(r);}
+   if(size(r)==0){r[1]=1;}
+   int i,j;
+   for(i=1;i<=size(#);i++)
+   {
+      j=1;
+      while((#[i]>r[j])&&(j<size(r))){j++;}
+      if(#[i]>r[j]){r=insert(r,#[i],j);}
+      if(#[i]<r[j]){r=insert(r,#[i],j-1);}
+   }
+   return(r);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   list r=list(3,7,13);
+   intvec v=2,3,5,11,17;
+   insResult(r,v);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+static proc shortid_L (ideal id,int n)
+{
+  ideal Lc;
+  intvec v;
+  int ii;
+  for(ii= 1; ii<=ncols(id); ii++)
+  {
+   if (size(id[ii])<=n and id[ii]!=0)
+   {
+       Lc = Lc,id[ii];
+       v=v,ii;
+   }
+  }
+  Lc = simplify(Lc,2);
+  list L = Lc,v;
+  return(Lc);
+}
+
+
+/*
+//-------------- the solution of the problem -----------------
+ring r = 0,(b,c,t),dp;   //global (affine) ring
+matrix X[2][2] = 0, -1,
+                 1, t;
+matrix Y[2][2] = 1, b,
+                 c, 1+bc;
+;
+
+//------------ create word W1 and ideal I of U1-U2 ------------
+matrix iX = inverse(X);
+matrix iY = inverse(Y);
+matrix U1 = iX*Y*X*iY*X;          //the word w1
+//matrix U1=iX*iX*iY*X;           //das neue Wort
+matrix N  = X*U1*iX;
+matrix M  = Y*U1*iY;
+matrix iN = inverse(N);
+matrix iM = inverse(M);
+matrix U2 = N*M*iN*iM;
+ideal I = ideal(U1-U2);
+
+//list qr=primdecGTZ(I);
+//I=qr[1][2];
+
+ring rh = 0,(b,c,t,h),dp;
+ideal I = imap(r,I);
+ideal sI = groebner(I);
+ideal hI = homog(sI,h);
+ideal shI =std(hI);
+ideal J = eliminate(shI,c);       //eliminate c
+poly f = J[1];
+
+ring r1 = 0,(b,t,h),dp;
+poly hf=b6t6-2b5t7+b4t8+b8t3h-4b7t4h+7b6t5h-6b5t6h+2b4t7h-7b6t4h2+12b5t5h2+b4t6h2-6b3t7h2-3b8th3+12b7t2h3-16b6t3h3+19b4t5h3-12b3t6h3-2b8h4+8b7th4-3b6t2h4+2b5t3h4-45b4t4h4+32b3t5h4+12b2t6h4-12b6th5+50b5t2h5-64b4t3h5+4b3t4h5+26b2t5h5-12b6h6+24b5th6+22b4t2h6+12b3t3h6-73b2t4h6-10bt5h6-8b5h7-6b4th7+88b3t2h7-68b2t3h7-26bt4h7-29b4h8+16b3th8+42b2t2h8+54bt3h8+3t4h8-28b3h9-12b2th9+88bt2h9+10t3h9-38b2h10-8bth10-11t2h10-28bh11-34th11-17h12;
+//poly hf=b3t4-b2t5+b4t2h-2b3t3h+2b2t4h-bt5h-2b3t2h2+4bt4h2+b2t2h3-bt3h3+t4h3
+//+2b2th4-6bt2h4-4t3h4+b2h5-2bth5+2t2h5+4th6+h7;
+
+int n,m,sA,sB;
+ n=6;
+//n=3;
+//m=7-n;
+
+ m = 12-n;
+ ideal A = maxideal(n);       ideal B = maxideal(m);
+ sA =size(A);
+ sB = size(B);
+
+ring R = 0,(b(1..sB),a(1..sA),b,t,h),dp;
+poly hf = imap(r1,hf);
+ideal A = imap(r1,A);
+ideal B = imap(r1,B);
+matrix aa[sA][1]= a(1..sA);
+matrix bb[sB][1] = b(1..sB);
+poly f1= (matrix(A)*aa)[1,1];   //Ansatz for degree n
+poly f2= (matrix(B)*bb)[1,1];   //Ansatz for degree m=12-n
+poly g = f1*f2-hf;              //assume hf factors
+matrix C = coef(g,bth);
+ideal co = submat(C,2,1..ncols(C));//condition for decomposition, size 91
+
+ring R1 = 0,(b(1..sB),a(1..sA)),lp;
+ideal co = imap(R,co);
+co=subst(co,a(1),1);          //OE a1=1
+co = subst(co,b(1),-17);      //co1[91]=b(1)+17
+//co = subst(co,b(1),1);
+
+int aa=timer;
+list pr=noSolution(co);
+timer-aa;
+
+
+//n=1 0 sec
+// keine Primzahl
+//n=2   628 sec
+// 2,3,5,7,11,13,17,19,23,29,31,37,43,47,61,89,293,347,367,487,491,3463,7498
+//n=3  1604 sec
+// 2,3,5,7,11,13,17,19,23,29,31,59,71,79,101,163,197,211,269,281,541,647,863,
+// 7129,9041,10343,18413,20857
+//n=4  8296 sec
+// 2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,61,67,71,73,83,89,101,109,127,
+   131,149,151,157,163,167,173,179,193,199,211,223,229,251,263,283,307,313,331,
+   347,373,401,601,607,631,643,701,719,727,829,857,887,971,1279,1361,1453,1721,
+   1847,2003,2069,2213,2671,2693,3299,3373,3391,3517,3593,3701,3779,4111,4409,
+   4423,4561,4657,4793,5273,5399,5659,5987,6949,7487,8011,8243,8887,9769,10159,
+   10177,12007,26347
+//n=5  4715 sec
+// 2,3,5,7,11,13,17,19,23,31,41,43,61,283,421,631,1609
+//n=6 18317 sec
+// 2,3,5,7,11,13,17,19,29,31,37,41,47,61,71,73,79,89,97,127,131,173,181,223,
+// 269,953,1039,6151,6343,7823
+
+
+//fuer das andere Wort
+//n=1  keine Primzahl
+//n=2  2,3,7,109
+//n=3  2,3,5,7,11,13,19,29,31,41,43,47,89,139,149,167,173,991,1381,1637,27367
+
+*/
diff --git a/Singular/LIB/grwalk.lib b/Singular/LIB/grwalk.lib
new file mode 100644
index 0000000..8bbb250
--- /dev/null
+++ b/Singular/LIB/grwalk.lib
@@ -0,0 +1,545 @@
+///////////////////////////////////////////////////////////////
+
+version="version grwalk.lib 4.0.0.0 Jun_2013 "; // $Id: 7c62e939cf3c459c9e2a3af80d83c9a8a0c2c619 $
+category="Commutative Algebra";
+
+info="
+LIBRARY: grwalk.lib   Groebner Walk Conversion Algorithms
+AUTHOR: I Made Sulandra
+
+PROCEDURES:
+ fwalk(ideal[,intvec]);   standard basis of ideal via fractalwalk alg
+ twalk(ideal[,intvec]);   standard basis of ideal via Tran's alg
+ awalk1(ideal[,intvec]);   standard basis of ideal via the first alt. alg
+ awalk2(ideal[,intvec]);   standard basis of ideal via the second alt. alg
+ pwalk(ideal[,intvec]);   standard basis of ideal via perturbation walk alg
+ gwalk(ideal[,intvec]);   standard basis of ideal via groebnerwalk alg
+";
+
+//////////////////////////////////////////////////////////////////////////////
+
+static proc OrderStringalp(string Wpal,list #)
+{
+  int n= nvars(basering);
+  string order_str;
+  intvec curr_weight, target_weight;
+  curr_weight = system("Mivdp",n);
+  target_weight = system("Mivlp",n);
+
+   if(size(#) != 0)
+   {
+     if(size(#) == 1)
+     {
+       if(typeof(#[1]) == "intvec")
+       {
+         if(Wpal == "al"){
+           order_str = "(a("+string(#[1])+"),lp("+string(n) + "),C)";
+         }
+         else {
+           order_str = "(Wp("+string(#[1])+"),C)";
+         }
+         curr_weight = #[1];
+       }
+       else
+       {
+        if(typeof(#[1]) == "string")
+        {
+          if(#[1] == "Dp") {
+            order_str = "Dp";
+          }
+          else {
+            order_str = "dp";
+          }
+        }
+        else {
+          order_str = "dp";
+        }
+     }
+    }
+    else
+    {
+     if(size(#) == 2)
+     {
+       if(typeof(#[2]) == "intvec")
+       {
+         target_weight = #[2];
+       }
+       if(typeof(#[1]) == "intvec")
+       {
+         if(Wpal == "al"){
+           order_str = "(a("+string(#[1])+"),lp("+string(n) + "),C)";
+         }
+         else {
+           order_str = "(Wp("+string(#[1])+"),C)";
+         }
+         curr_weight = #[1];
+       }
+       else
+       {
+        if(typeof(#[1]) == "string")
+        {
+          if(#[1] == "Dp") {
+            order_str = "Dp";
+           }
+           else {
+              order_str = "dp";
+           }
+        }
+        else {
+           order_str = "dp";
+        }
+      }
+     }
+    }
+   }
+   else {
+     order_str = "dp";
+   }
+   list result;
+   result[1] = order_str;
+   result[2] = curr_weight;
+   result[3] = target_weight;
+   return(result);
+}
+
+static proc OrderStringalp_NP(string Wpal,list #)
+{
+  int n= nvars(basering);
+  string order_str = "dp";
+  //string order_str = "Dp";
+
+  int nP = 1;// call LatsGB to compute the wanted GB  by pwalk
+
+  //Default:
+  // if size(#)=0, the Groebnerwalk algorithm and its developments compute
+  // a Groebner basis from "dp" to "lp"
+
+  intvec curr_weight = system("Mivdp",n); //define (1,1,...,1)
+  intvec target_weight = system("Mivlp",n); //define (1,0,...,0)
+
+  if(size(#) != 0)
+  {
+    if(size(#) == 1)
+    {
+      if(typeof(#[1]) == "intvec") {
+        curr_weight = #[1];
+
+        if(Wpal == "al"){
+          order_str = "(a("+string(#[1])+"),lp("+string(n) + "),C)";
+        }
+        else {
+          order_str = "(Wp("+string(#[1])+"),C)";
+        }
+      }
+      else {
+        if(typeof(#[1]) == "int"){
+          nP = #[1];
+        }
+        else {
+          print("// ** the input must be \"(ideal, int)\" or ");
+          print("// **                   \"(ideal, intvec)\"");
+          print("// ** a lex. GB will be computed from \"dp\" to \"lp\"");
+        }
+      }
+    }
+    else
+    {
+     if(size(#) == 2)
+     {
+       if(typeof(#[1]) == "intvec" and typeof(#[2]) == "int"){
+         curr_weight = #[1];
+
+         if(Wpal == "al"){
+           order_str = "(a("+string(#[1])+"),lp("+string(n) + "),C)";
+         }
+         else {
+           order_str = "(Wp("+string(#[1])+"),C)";
+         }
+       }
+       else{
+         if(typeof(#[1]) == "intvec" and typeof(#[2]) == "intvec"){
+           curr_weight = #[1];
+           target_weight = #[2];
+
+           if(Wpal == "al"){
+             order_str = "(a("+string(#[1])+"),lp("+string(n) + "),C)";
+           }
+           else {
+             order_str = "(Wp("+string(#[1])+"),C)";
+           }
+         }
+         else{
+           print("// ** the input  must be \"(ideal,intvec,int)\" or ");
+           print("// **                    \"(ideal,intvec,intvec)\"");
+           print("// ** and a lex. GB will be computed from \"dp\" to \"lp\"");
+         }
+       }
+     }
+     else {
+       if(size(#) == 3) {
+         if(typeof(#[1]) == "intvec" and typeof(#[2]) == "intvec" and
+            typeof(#[3]) == "int")
+         {
+           curr_weight = #[1];
+           target_weight = #[2];
+           nP = #[3];
+           if(Wpal == "al"){
+             order_str = "(a("+string(#[1])+"),lp("+string(n) + "),C)";
+           }
+           else {
+             order_str = "(Wp("+string(#[1])+"),C)";
+           }
+         }
+         else{
+           print("// ** the input must be \"(ideal,intvec,intvec,int)\"");
+           print("// ** and a lex. GB will be computed from \"dp\" to \"lp\"");
+
+         }
+       }
+       else{
+         print("// ** The given input is wrong");
+         print("// ** and a lex. GB will be computed from \"dp\" to \"lp\"");
+       }
+     }
+    }
+  }
+
+  list result;
+  result[1] = nP;
+  result[2] = order_str;
+  result[3] = curr_weight;
+  result[4] = target_weight;
+
+  return(result);
+}
+
+
+
+
+/* 16 Mai 2003 */
+proc awalk1(ideal G, list #)
+"SYNTAX: awalk1(ideal i);
+         awalk1(ideal i, int n);
+         awalk1(ideal i, int n, intvec v, intvec w);
+         awalk1(ideal i, intvec v, intvec w);
+TYPE:    ideal
+PURPOSE: compute the standard basis of the ideal, calculated via
+          the first alternative algorithm from an ordering
+         \"(a(v),lp)\", \"dp\" or \"Dp\" to the ordering
+         \"(a(w),lp)\" or \"(a(1,0,...,0),lp)\"
+         with a perturbation degree n for the weight vector w.
+SEE ALSO: std, stdfglm, groebner, gwalk, pwalk, fwalk, twalk, awalk2
+KEYWORDS: the first alternative algorithm
+EXAMPLE: example awalk1; shows an example"
+{
+  if (size(#) == 0)
+  {
+    return (awalk1_tmp(G, nvars(basering)-1));
+  }
+  else {
+    if(typeof(#[1]) == "int")
+    {
+      return (awalk1_tmp(G, #[1]));
+    }
+    else  {
+      return (awalk1_tmp(G, nvars(basering)-1, #));
+    }
+  }
+}
+example
+{
+    "EXAMPLE:"; echo = 2;
+    ring r = 32003,(z,y,x), lp;
+    ideal I = y3+xyz+y2z+xz3, 3+xy+x2y+y2z;
+    awalk1(I,3);
+}
+
+proc gwalk(ideal Go, list #)
+"SYNTAX: gwalk(ideal i);
+         gwalk(ideal i, intvec v, intvec w);
+TYPE:    ideal
+PURPOSE: compute the standard basis of the ideal, calculated via
+         the improved Groebner walk algorithm  from the ordering
+         \"(a(v),lp)\", \"dp\" or \"Dp\"
+         to the ordering  \"(a(w),lp)\" or \"(a(1,0,...,0),lp)\".
+SEE ALSO: std, stdfglm, groebner, pwalk, fwalk, twalk, awalk1, awalk2
+KEYWORDS: Groebner walk
+EXAMPLE: example gwalk; shows an example"
+{
+
+   /* we use ring with ordering (a(...),lp,C) */
+   list OSCTW    = OrderStringalp_NP("al", #);//"dp"
+   //list OSCTW    = OrderStringalp("al", "Dp");//Dp
+
+   string ord_str =   OSCTW[2];
+   intvec curr_weight   =   OSCTW[3]; /* original weight vector */
+   intvec target_weight =   OSCTW[4]; /* terget weight vector */
+   kill OSCTW;
+   option(redSB);
+   def xR = basering;
+
+   execute("ring ostR = ("+charstr(xR)+"),("+varstr(xR)+"),"+ord_str+";");
+   def old_ring = basering;
+
+   //print("//** help ring = " + string(basering));
+   ideal G = fetch(xR, Go);
+   G = system("Mwalk", G, curr_weight, target_weight,basering);
+
+   setring xR;
+   //kill Go;
+
+   keepring basering;
+   ideal result = fetch(old_ring, G);
+   attrib(result,"isSB",1);
+   return (result);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  //** compute a Groebner basis of I w.r.t. lp.
+  ring r = 32003,(z,y,x), lp;
+  ideal I = y3+xyz+y2z+xz3, 3+xy+x2y+y2z;
+  gwalk(I);
+}
+
+
+proc awalk1_tmp(ideal Go, int n2, list #)
+//proc awalk1(ideal Go, int n1, int n2, list #)
+{
+   int nV = nvars(basering);
+   int n1 = 1;
+
+   //assume(n1 >= 1 && n1 <= nV && n2 >= 1 && n2 <= nV);
+   if(n1 < 1 || n1 > nV || n2 < 1 || n2 > nV)
+   {
+     print("//Erorr: The perturbed degree is wrong!!");
+     print("//       It must be between 1 and " + string(nV));
+     return();
+   }
+
+   /* we use ring with ordering (a(...),lp,C) */
+   list OSCTW    = OrderStringalp_NP("al", #);
+   //list OSCTW    = OrderStringalp("al", "Dp");
+
+   string ord_str =   OSCTW[2];
+   intvec curr_weight   =   OSCTW[3]; /* original weight vector */
+   intvec target_weight =   OSCTW[4]; /* terget weight vector */
+   kill OSCTW;
+   option(redSB);
+
+   def xR = basering;
+
+   execute("ring ostR = ("+charstr(xR)+"),("+varstr(xR)+"),"+ord_str+";");
+   def old_ring = basering;
+   //print("//** help ring = " + string(basering));
+
+   ideal G = fetch(xR, Go);
+   G = system("MAltwalk1", G, n1, n2, curr_weight, target_weight);
+
+   setring xR;
+   //kill Go;
+
+   keepring basering;
+   ideal result = fetch(old_ring, G);
+   attrib(result,"isSB",1);
+   return (result);
+}
+
+proc fwalk(ideal Go, list #)
+"SYNTAX: fwalk(ideal i);
+         fwalk(ideal i, intvec v, intvec w);
+TYPE:    ideal
+PURPOSE: compute the standard basis of the ideal w.r.t. the
+        lexicographical ordering or a weighted-lex ordering,
+        calculated via  the fractal walk algorithm.
+SEE ALSO: std, stdfglm, groebner, gwalk, pwalk, twalk, awalk1, awalk2
+KEYWORDS: The fractal walk algorithm
+EXAMPLE: example fwalk; shows an example"
+{
+   /* we use ring with ordering (a(...),lp,C) */
+   list OSCTW    = OrderStringalp_NP("al", #);
+
+   string ord_str =   OSCTW[2];
+   intvec curr_weight   =   OSCTW[3]; /* original weight vector */
+   intvec target_weight =   OSCTW[4]; /* terget weight vector */
+   kill OSCTW;
+   option(redSB);
+   def xR = basering;
+
+   execute("ring ostR = ("+charstr(xR)+"),("+varstr(xR)+"),"+ord_str+";");
+   def old_ring = basering;
+   //print("//** help ring = " + string(basering));
+
+   ideal G = fetch(xR, Go);
+   G = system("Mfwalk", G, curr_weight, target_weight);
+
+   setring xR;
+   //kill Go;
+
+   keepring basering;
+   ideal result = fetch(old_ring, G);
+   attrib(result,"isSB",1);
+   return (result);
+}
+example
+{
+    "EXAMPLE:"; echo = 2;
+    ring r = 32003,(z,y,x), lp;
+    ideal I = y3+xyz+y2z+xz3, 3+xy+x2y+y2z;
+    fwalk(I);
+}
+
+
+
+proc awalk2(ideal Go, list #)
+"SYNTAX: awalk2(ideal i);
+         awalk2(ideal i, intvec v, intvec w);
+TYPE:    ideal
+PURPOSE: compute the standard basis of the ideal, calculated via
+         the second alternative algorithm from the ordering
+         \"(a(v),lp)\", \"dp\" or \"Dp\"
+         to the ordering  \"(a(w),lp)\" or \"(a(1,0,...,0),lp)\".
+SEE ALSO: std, stdfglm, groebner, gwalk, pwalk, fwalk, twalk, awalk1
+KEYWORDS: Groebner walk
+EXAMPLE: example awalk2; shows an example"
+{
+   /* we use ring with ordering (a(...),lp,C) */
+   list OSCTW    = OrderStringalp_NP("al", #);//"dp"
+   //list OSCTW    = OrderStringalp("al", "Dp");//Dp
+
+   string ord_str =   OSCTW[2];
+   intvec curr_weight   =   OSCTW[3]; /* original weight vector */
+   intvec target_weight =   OSCTW[4]; /* terget weight vector */
+   kill OSCTW;
+   option(redSB);   def xR = basering;
+
+   execute("ring ostR = ("+charstr(xR)+"),("+varstr(xR)+"),"+ord_str+";");
+   def old_ring = basering;
+
+   //print("//** help ring = " + string(basering));
+   ideal G = fetch(xR, Go);
+   G = system("MAltwalk2", G, curr_weight, target_weight);
+
+   setring xR;
+   //kill Go;
+
+   keepring basering;
+   ideal result = fetch(old_ring, G);
+   attrib(result,"isSB",1);
+   return (result);
+}
+example
+{
+    "EXAMPLE:"; echo = 2;
+    ring r = 32003,(z,y,x), lp;
+    ideal I = y3+xyz+y2z+xz3, 3+xy+x2y+y2z;
+    awalk2(I);
+}
+
+proc pwalk(ideal Go, int n1, int n2, list #)
+"SYNTAX: pwalk(int d, ideal i, int n1, int n2);
+         pwalk(int d, ideal i, int n1, int n2, intvec v, intvec w);
+TYPE:    ideal
+PURPOSE: compute the standard basis of the ideal, calculated via
+         the perturbation walk algorithm  from the ordering
+         \"(a(v),lp)\", \"dp\" or \"Dp\"
+         to the ordering  \"(a(w),lp)\" or \"(a(1,0,...,0),lp)\"
+         with a perturbation degree n, m for v and w, resp.
+SEE ALSO: std, stdfglm, groebner, gwalk, fwalk, twalk, awalk1, awalk2
+KEYWORDS: Perturbation walk
+EXAMPLE: example pwalk; shows an example"
+{
+  int nV = nvars(basering);
+  //assume(n1 >= 1 && n1 <= nV && n2 >= 1 && n2 <= nV);
+  if(n1 < 1 || n1 > nV || n2 < 1 || n2 > nV)
+  {
+    print("//Erorr: The perturbed degree is wrong!!");
+    print("//       It must be between 1 and " + string(nV));
+    return();
+  }
+
+  /* we use ring with ordering (a(...),lp,C) */
+  list OSCTW    = OrderStringalp_NP("al", #);
+  //list OSCTW    = OrderStringalp("al", "Dp");//Dp
+  int nP = OSCTW[1];
+
+  string ord_str =   OSCTW[2];
+  intvec curr_weight   =   OSCTW[3]; /* original weight vector */
+  intvec target_weight =   OSCTW[4]; /* terget weight vector */
+  kill OSCTW;
+  option(redSB);
+
+  def xR = basering;
+
+  execute("ring ostR = ("+charstr(xR)+"),("+varstr(xR)+"),"+ord_str+";");
+  def old_ring = basering;
+
+  ideal G = fetch(xR, Go);
+
+  G = system("Mpwalk", G, n1, n2, curr_weight, target_weight,nP);
+
+  setring xR;
+  //kill Go;
+
+  keepring basering;
+  ideal result = fetch(old_ring, G);
+  attrib(result,"isSB",1);
+  return (result);
+}
+example
+{
+    "EXAMPLE:"; echo = 2;
+    ring r = 32003,(z,y,x), lp;
+    ideal I = y3+xyz+y2z+xz3, 3+xy+x2y+y2z;
+    //I = std(I);
+    //ring rr = 32003,(z,y,x),lp;
+    //ideal I = fetch(r,I);
+    pwalk(I,2,2);
+}
+
+
+proc twalk(ideal Go, list #)
+"SYNTAX: twalk(ideal i);
+         twalk(ideal i, intvec v, intvec w);
+TYPE:    ideal
+PURPOSE: compute the standard basis of the ideal w.r.t.
+         the ordering  \"(a(w),lp)\" or \"(a(1,0,...,0),lp)\",
+         calculated via the Tran algorithm.
+SEE ALSO: std, stdfglm, groebner, gwalk, pwalk, fwalk, awalk1, awalk2
+KEYWORDS: The Tran algorithm
+EXAMPLE: example twalk; shows an example"
+{
+  list L = OrderStringalp_NP("al", #);
+  int nP = L[1];
+
+  /* we use ring with ordering (a(...),lp,C) */
+  string ord_str =   L[2];
+  intvec curr_weight   = L[3];
+  intvec target_weight =  L[4];
+  kill L;
+
+  option(redSB);
+  def xR = basering;
+
+  execute("ring ostR = ("+charstr(xR)+"),("+varstr(xR)+"),"+ord_str+";");
+  def old_ring = basering;
+
+  //print("//** help ring = " + string(basering));
+  ideal G = fetch(xR, Go);
+  G = system("TranMImprovwalk", G, curr_weight, target_weight, nP);
+
+  setring xR;
+   //kill Go;
+
+  keepring basering;
+  ideal result = fetch(old_ring, G);
+  attrib(result,"isSB",1);
+  return (result);
+}
+example
+{
+    "EXAMPLE:"; echo = 2;
+    ring r = 32003,(z,y,x), lp;
+    ideal I = y3+xyz+y2z+xz3, 3+xy+x2y+y2z;
+    twalk(I);
+}
diff --git a/Singular/LIB/hdepth.lib b/Singular/LIB/hdepth.lib
new file mode 100644
index 0000000..916b3d8
--- /dev/null
+++ b/Singular/LIB/hdepth.lib
@@ -0,0 +1,195 @@
+//////////////////////////////////////////////////////////////////////////////
+version="version hdepth.lib 4.0.0.0 Jun_2013"; //
+category="Commutative Algebra";
+info="
+LIBRARY: hdepth.lib     Procedures for computing hdepth_1
+AUTHORS: Popescu, A.,     popescu at mathematik.uni-kl.de
+
+SEE ALSO: 'An algorithm to compute the Hilbert depth', Adrian Popescu, arxiv/AC/1307.6084
+
+KEYWORDS: hdepth, library
+
+
+PROCEDURES:
+  hdepth(M [,debug]);        hdepth_1 computation of a module M (wrt Z-grading)
+  hdepth_p(g, d, debug) the minimum number t <= d s.t. 1/g^t is positive
+";
+
+///////////////////////////////////////////////////////////////////////////////////
+static proc myinverse(poly p, int bound)
+"USAGE:   myinverse(p,bound), p polynomial in one variable with p(0) nonzero, bound a nonnegative integer
+RETURN:  poly, the inverse of the poly p in the power series ring till order bound
+"
+{
+    if(bound<=1)
+        {
+            ERROR("My inverse : negative bound in the inverse");
+        }
+    if(p == 0)
+	    {
+	        ERROR("My inverse : p is 0");
+	    }
+	poly original;
+    original = p;
+    if(leadcoef(p) == 0)
+        {
+            ERROR("My inverse : the power series is not a unit.");
+        }
+    poly q = 1/p[1];
+    poly res = q;
+    p = q * (p[1] - jet(p,bound));
+    poly s = p;
+    while(p != 0)
+    {
+        res = res + q * p;
+        p = jet(p*s,bound);
+    }
+    //TEST
+    if(jet(original*res,bound) != poly(1))
+        {
+            ERROR("Myinverse does not work properly.");
+        }
+    return(res);
+}
+
+///////////////////////////////////////////////////////////////////////////////////
+static proc hilbconstruct(intvec v)
+"USAGE:   hilbconstruct(v), v is the result of hilb(M,2)
+RETURN:  poly, the Hilbert Series of M
+AASUME: the ring when called is R = 0,t,ds;
+"
+{
+    poly f;
+	int i;
+	for(i=0;i<size(v)-1;i++)
+	{
+		f=f+v[i+1]*t^i;
+	}
+	return(f);
+}
+///////////////////////////////////////////////////////////////////////////////////
+static proc positiv(poly f)
+"USAGE:   positiv(f), f is a polynomial
+RETURN:  int, 1 if all the coefficients of f are positive, 0 else
+"
+{
+    int pos=1;
+	while( (f!=0) && (pos==1) )
+	{
+		if(leadcoef(f)<0)
+		{
+			pos=0;
+		}
+		f=f-lead(f);
+	}
+	return(pos);
+}
+///////////////////////////////////////////////////////////////////////////////////
+static proc sumcoef(poly f)
+"USAGE:   sumcoef(f), f is a polynomial
+RETURN:  number, the sum of the coefficients
+"
+{
+    number c;
+	while(f!=0)
+	    {
+    		c = c+leadcoef(f);
+	    	f=f-lead(f);
+    	}
+	return(int(c));
+}
+///////////////////////////////////////////////////////////////////////////////////
+proc hdepth_p(poly g, int d, int debug)
+"USAGE:   hdepth_p(g,d,debug), g is the Hilbert Series of a module M and d is the dimension of M, for debug = 0 the steps will be printed.
+RETURN:  int, the minimum number t <= d s.t. 1/g^t is positive
+"
+{
+    int dd = d;
+	if(debug == 0)
+	    {"G(t)=",g;}
+	if(positiv(g)==1)
+		{
+		    if(debug == 0)
+		        {return("hdepth =",dd);}
+		    else
+		        {return(dd);}
+		}
+	poly f=g;
+	number ag;
+	int c1;
+	int bound;
+	bound = deg(g);
+	while(dd >= 0)
+	{
+	   dd = dd-1;
+	   f = jet( g*myinverse( (1-t)^(d-dd),2*bound ) , bound );
+       if(positiv(f) == 1)
+       {
+		    if(debug == 0)
+		        {
+		            "G(t)/(1-t)^",d-dd,"=",f,"+...";
+    		        return("hdepth =",dd);
+		        }
+		    else
+            	{return(d);}
+       }
+    c1=sumcoef(f);
+	if(c1<0)
+       {
+      		while(c1<0)
+                {
+                    bound=bound+1;
+                    f=jet( g*myinverse( (1-t)^(d-dd),2*bound ) , bound );
+                    c1=sumcoef(f);
+                }
+        }
+        if(debug == 0)
+            {"G(t)/(1-t)^",d-dd,"=",f,"+...";}
+    }
+    ERROR("g was not a Hilbert Series since the coefficient sum is not > 0");
+}
+
+example
+{
+  "EXAMPLE:";echo=2;
+  ring R = 0,t,ds;
+  poly f = 2-3t-2t2+2t3+4t4;
+  hdepth_p(f,5,0);
+  hdepth_p(f,5,1);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+proc hdepth(module M, list #)
+"USAGE:   hdepth(M [,debug]);   M is a module, if one want to print the steps debug = 0
+RETURN:  int
+PURPOSE: compute the hdepth_1 of a module M
+EXAMPLE: example hdepth; shows examples
+"
+{
+    int debug;
+    if(size(#)>0)
+        {
+            if(typeof(#[1])=="int")
+                {debug = #[1];}
+        }
+    else
+        {debug = 1;}
+    M = std(M);
+    int d=nvars(basering)-dim(M);
+    intvec v=hilb(M,2);
+    ring R = 0,t,ds;
+    poly hp=hilbconstruct(v);
+    if(debug == 0)
+        {"dim =",d;}
+    return(hdepth_p(hp,d,debug));
+}
+example
+{
+  "EXAMPLE:";echo=2;
+  ring R = 0,(x(1..10)),dp;
+  ideal i=maxideal(1);
+  module M=i;
+  hdepth(M);
+  hdepth(M,0);
+  hdepth(M,1);
+}
diff --git a/Singular/LIB/help.cnf b/Singular/LIB/help.cnf
new file mode 100644
index 0000000..6341b9e
--- /dev/null
+++ b/Singular/LIB/help.cnf
@@ -0,0 +1,57 @@
+# Singular help browser file
+# each line which start with an # is a comment
+# each other line defines a (possible) help browser
+# the format of the entries is: <name>!<requirements>!<shell command>
+#----------------------------------------------------
+# known requirements:
+#  x- requires singular.idx
+#  i- requires singular.hlp
+#  h- requires html dir
+#  D- requires the enviroment variable DISPLAY
+#  E:executable:- requires the named exectable
+#  O:`uname -m`-`uname -s`:- requires the named uname
+#  (ubuntu has an open completely different from open on OsX)
+#----------------------------------------------------
+# shell commands substitute the following:
+#  %h: the local html file (in the form file://localhost/some/dir/sing_123.htm)
+#  %f: the local html file (in the form /some/dir/sing_123.htm)
+#  %H: the www html  file
+#             (in the form http://www.singular.uni-kl.de/some/dir/sing_123.htm)
+#  %i: the complete path of singular.hlp
+#  %n: the info node
+#  %v: Singular version (in the form 4-0-0)
+#----------------------------------------------------
+# the default help browsers builtin, dummy and emacs are always
+#   available and should NOT be mentioned here
+#----------------------------------------------------
+htmlview!xDhE:htmlview:!htmlview %h &
+mac!xhE:open:O:x86_64-Darwin:!open %f &
+mac-net!xE:open:O:x86_64-Darwin:!open %H &
+mozilla!xDhE:mozilla:!(mozilla -remote "openURL(%h)")||(mozilla %h) &
+firefox!xDhE:firefox:!firefox %h &
+konqueror!xDhE:konqueror:!konqueror %h &
+galeon!xDhE:galeon:!galeon -n %h &
+netscape!xDhE:netscape:!(netscape -remote "openURL(%h)")||(netscape %h) &
+cygwin!xhE:cygstart:!cygstart "%h" &
+cygwin-www!E:cygstart:!cygstart "%H" &
+safari!xhE:/Applications/Safari.app:!open -a /Applications/Safari.app %h
+tkinfo!xDiE:tkinfo:!tkinfo '(%i)%n' &
+xinfo!xDiE:xterm:E:info:!xterm -e info -f %i --node='%n' &
+info!xiE:info:!info -f %i --node='%n'
+lynx!xhE:lynx:!lynx %h
+#----------------------------------------------------------------
+# dummy versions for pure online help
+mac-www!E:open:O:x86_64-Darwin:!open http://www.singular.uni-kl.de/Manual/%v/ &
+mozilla-www!DE:mozilla:!(mozilla -remote "openURL(http://www.singular.uni-kl.de/Manual/%v/)")||(mozilla http://www.singular.uni-kl.de/Manual/%v/) &
+firefox-www-idx!xDE:firefox:!firefox %H &
+firefox-www!DE:firefox:!firefox http://www.singular.uni-kl.de/Manual/%v/ &
+konqueror-www-idx!xDE:konqueror:!konqueror %H &
+konqueror-www!DE:konqueror:!konqueror http://www.singular.uni-kl.de/Manual/%v/ &
+galeon-www-idx!xDE:galeon:!galeon -n %H &
+galeon-www!DE:galeon:!galeon -n http://www.singular.uni-kl.de/Manual/%v/ &
+netscape-www!DE:netscape:!(netscape -remote "openURL(http://www.singular.uni-kl.de/Manual/%v/)")||(netscape http://www.singular.uni-kl.de/Manual/%v/) &
+safari-www-idx!xE:/Applications/Safari.app:!open -a /Applications/Safari.app %H
+safari-www!E:/Applications/Safari.app:!open -a /Applications/Safari.app http://www.singular.uni-kl.de/Manual/%v/
+lynx-www-idx!xE:lynx:!lynx %H
+lynx-www!E:lynx:!lynx http://www.singular.uni-kl.de/Manual/%v/
+
diff --git a/Singular/LIB/hnoether.lib b/Singular/LIB/hnoether.lib
new file mode 100644
index 0000000..ca915ab
--- /dev/null
+++ b/Singular/LIB/hnoether.lib
@@ -0,0 +1,4282 @@
+//////////////////////////////////////////////////////////////////////////////
+version="version hnoether.lib 4.0.0.0 Jun_2013 "; // $Id: 1e5aa570b5053f49874c3a563790bb1fbc786a5b $
+
+category="Singularities";
+info="
+LIBRARY:  hnoether.lib   Hamburger-Noether (Puiseux) Expansion
+AUTHORS:   Martin Lamm,      lamm at mathematik.uni-kl.de
+           Christoph Lossen, lossen at mathematik.uni-kl.de
+
+OVERVIEW:
+ A library for computing the Hamburger-Noether expansion (analogue of
+ Puiseux expansion over fields of arbitrary characteristic) of a reduced
+ plane curve singularity following [Campillo, A.: Algebroid curves in
+ positive characteristic, Springer LNM 813 (1980)]. @*
+ The library contains also procedures for computing the (topological)
+ numerical invariants of plane curve singularities.
+
+PROCEDURES:
+ hnexpansion(f [,\"ess\"]); Hamburger-Noether (HN) expansion of f
+ develop(f [,n]);           HN expansion of irreducible plane curve germs
+ extdevelop(hne,n);         extension of the H-N expansion hne of f
+ param(hne [,s]);           parametrization of branches described by HN data
+ displayHNE(hne);           display HN expansion as an ideal
+ invariants(hne);           invariants of f, e.g. the characteristic exponents
+ displayInvariants(hne);    display invariants of f
+ multsequence(hne);         sequence of multiplicities
+ displayMultsequence(hne);  display sequence of multiplicities
+ intersection(hne1,hne2);   intersection multiplicity of two local branches
+ is_irred(f);               test whether f is irreducible as power series
+ delta(f);                  delta invariant of f
+ newtonpoly(f);             (local) Newton polygon of f
+ is_NND(f);                 test whether f is Newton non-degenerate
+
+
+ stripHNE(hne);             reduce amount of memory consumed by hne
+ puiseux2generators(m,n);   convert Puiseux pairs to generators of semigroup
+ separateHNE(hne1,hne2);    number of quadratic transf. needed for separation
+ squarefree(f);             a squarefree divisor of the polynomial f
+ allsquarefree(f,l);        the maximal squarefree divisor of the polynomial f
+ further_hn_proc();         show further procedures useful for interactive use
+
+KEYWORDS: Hamburger-Noether expansion; Puiseux expansion; curve singularities
+";
+
+// essdevelop(f);             HN expansion of essential branches
+// multiplicities(hne);       multiplicities of blowed up curves
+
+///////////////////////////////////////////////////////////////////////////////
+LIB "primitiv.lib";
+LIB "inout.lib";
+LIB "sing.lib";
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc further_hn_proc()
+"USAGE: further_hn_proc();
+NOTE:  The library @code{hnoether.lib} contains some more procedures which
+       are not shown when typing @code{help hnoether.lib;}. They may be useful
+       for interactive use (e.g. if you want to do the calculation of an HN
+       development \"by hand\" to see the intermediate results), and they
+       can be enumerated by calling @code{further_hn_proc()}. @*
+       Use @code{help <procedure>;} for detailed information about each of
+       them.
+"
+{
+ "
+ The following procedures are also part of `hnoether.lib':
+
+ getnm(f);           intersection pts. of Newton polygon with axes
+ T_Transform(f,Q,N); returns f(y,xy^Q)/y^NQ (f: poly, Q,N: int)
+ T1_Transform(f,d,M); returns f(x,y+d*x^M)  (f: poly,d:number,M:int)
+ T2_Transform(f,d,M,N,ref);   a composition of T1 & T
+ koeff(f,I,J);       gets coefficient of indicated monomial of polynomial f
+ redleit(f,S,E);     restriction of monomials of f to line (S-E)
+ leit(f,n,m);        special case of redleit (for irred. polynomials)
+ testreducible(f,n,m); tests whether f is reducible
+ charPoly(f,M,N);    characteristic polynomial of f
+ find_in_list(L,p);  find int p in list L
+ get_last_divisor(M,N); last divisor in Euclid's algorithm
+ factorfirst(f,M,N); try to factor f without `factorize'
+ factorlist(L);      factorize a list L of polynomials
+ referencepoly(D);   a polynomial f s.t. D is the Newton diagram of f";
+
+//       static procedures not useful for interactive use:
+// polytest(f);        tests coefficients and exponents of polynomial f
+// extractHNEs(H,t);   extracts output H of HN to output of hnexpansion
+// HN(f,grenze);       recursive subroutine for hnexpansion
+// constructHNEs(...); subroutine for HN
+}
+example
+{ echo=2;
+  further_hn_proc();
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc getnm (poly f)
+"USAGE:   getnm(f); f bivariate polynomial
+RETURN:  intvec(n,m) : (0,n) is the intersection point of the Newton
+         polygon of f with the y-axis, n=-1 if it doesn't exist
+         (m,0) is its intersection point with the x-axis,
+         m=-1 if this point doesn't exist
+ASSUME:  ring has ordering `ls' or `ds'
+EXAMPLE: example getnm; shows an example
+"
+{
+ // assume being called by develop ==> ring ordering is ls (ds would also work)
+ return(ord(subst(f,var(1),0)),ord(subst(f,var(2),0)));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r = 0,(x,y),ds;
+   poly f = x5+x4y3-y2+y4;
+   getnm(f);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc leit (poly f, int n, int m)
+"USAGE:   leit(f,n,m);  poly f, int n,m
+RETURN:  all monomials on the line from (0,n) to (m,0) in the Newton diagram
+EXAMPLE: example leit;  shows an example
+"
+{
+ return(jet(f,m*n,intvec(n,m))-jet(f,m*n-1,intvec(n,m)))
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r = 0,(x,y),ds;
+   poly f = x5+x4y3-y2+y4;
+   leit(f,2,5);
+}
+///////////////////////////////////////////////////////////////////////////////
+proc testreducible (poly f, int n, int m)
+"USAGE:   testreducible(f,n,m);  f poly, n,m int
+RETURN:  1 if there are points in the Newton diagram below the line (0,n)-(m,0)
+         0 else
+EXAMPLE: example testreducible;  shows an example
+"
+{
+ return(size(jet(f,m*n-1,intvec(n,m))) != 0)
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring rg=0,(x,y),ls;
+  testreducible(x2+y3-xy4,3,2);
+}
+///////////////////////////////////////////////////////////////////////////////
+proc T_Transform (poly f, int Q, int N)
+"USAGE:   T_Transform(f,Q,N);  f poly, Q,N int
+RETURN:  f(y,xy^Q)/y^NQ   if x,y are the ring variables
+NOTE:    this is intended for irreducible power series f
+EXAMPLE: example T_Transform;  shows an example
+"
+{
+ map T = basering,var(2),var(1)*var(2)^Q;
+ return(T(f)/var(2)^(N*Q));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring exrg=0,(x,y),ls;
+  export exrg;
+  T_Transform(x3+y2-xy3,1,2);
+  kill exrg;
+}
+///////////////////////////////////////////////////////////////////////////////
+proc T1_Transform (poly f, number d, int Q)
+"USAGE:   T1_Transform(f,d,Q);  f poly, d number, Q int
+RETURN:  f(x,y+d*x^Q)   if x,y are the ring variables
+EXAMPLE: example T1_Transform;  shows an example
+"
+{
+ map T1 = basering,var(1),var(2)+d*var(1)^Q;
+ return(T1(f));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring exrg=0,(x,y),ls;
+  export exrg;
+  T1_Transform(y2-2xy+x2+x2y,1,1);
+  kill exrg;
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc T2_Transform (poly f_neu, number d, int M, int N, poly refpoly)
+"USAGE:   T2_Transform(f,d,M,N,ref); f poly, d number; M,N int; ref poly
+RETURN:  list: poly T2(f,d',M,N), number d' in \{ d, 1/d \}
+ASSUME:  ref has the same Newton polygon as f (but can be simpler)
+         for this you can e.g. use the proc `referencepoly' or simply f again
+COMMENT: T2 is a composition of T_Transform and T1_Transform; the exact
+         definition can be found in  Rybowicz: `Sur le calcul des places ...'
+         or in  Lamm: `Hamburger-Noether-Entwicklung von Kurvensingularitaeten'
+SEE ALSO: T_Transform, T1_Transform, referencepoly
+EXAMPLE: example T2_Transform;  shows an example
+"
+{
+ //---------------------- compute gcd and extgcd of N,M -----------------------
+  int ggt=gcd(M,N);
+  M=M div ggt; N=N div ggt;
+  list ts=extgcd(M,N);
+  int tau,sigma=ts[2],-ts[3];
+  int s,t;
+  poly xp=var(1);
+  poly yp=var(2);
+  poly hilf;
+  if (sigma<0) { tau=-tau; sigma=-sigma;}
+ // es gilt: 0<=tau<=N, 0<=sigma<=M, |N*sigma-M*tau| = 1 = ggT(M,N)
+  if (N*sigma < M*tau) { d = 1/d; }
+ //--------------------------- euklid. Algorithmus ----------------------------
+  int R;
+  int M1,N1=M,N;
+  for ( R=M1%N1; R!=0; ) { M1=N1; N1=R; R=M1%N1;}
+  int Q=M1 div N1;
+  map T1 = basering,xp,yp+d*xp^Q;
+  map Tstar=basering,xp^(N-Q*tau)*yp^tau,xp^(M-sigma*Q)*yp^sigma;
+  if (defined(HNDebugOn)) {
+   "Trafo. T2: x->x^"+string(N-Q*tau)+"*y^"+string(tau)+", y->x^"
+    +string(M-sigma*Q)+"*y^"+string(sigma);
+   "delt =",d,"Q =",Q,"tau,sigma =",tau,sigma;
+  }
+ //------------------- Durchfuehrung der Transformation T2 --------------------
+  f_neu=Tstar(f_neu);
+  refpoly=Tstar(refpoly);
+  //--- dividiere f_neu so lange durch x & y, wie die Division aufgeht,
+  //    benutze ein Referenzpolynom mit gleichem Newtonpolynom wie f_neu zur
+  //    Beschleunigung: ---
+  for (hilf=refpoly/xp; hilf*xp==refpoly; hilf=refpoly/xp) {refpoly=hilf; s++;}
+  for (hilf=refpoly/yp; hilf*yp==refpoly; hilf=refpoly/yp) {refpoly=hilf; t++;}
+  f_neu=f_neu/(xp^s*yp^t);
+  return(list(T1(f_neu),d));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring exrg=0,(x,y),ds;
+  export exrg;
+  poly f=y2-2x2y+x6-x5y+x4y2;
+  T2_Transform(f,1/2,4,1,f);
+  T2_Transform(f,1/2,4,1,referencepoly(newtonpoly(f,1)));
+  // if  size(referencepoly) << size(f)  the 2nd example would be faster
+  referencepoly(newtonpoly(f,1));
+  kill exrg;
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc koeff (poly f, int I, int J)
+"USAGE:   koeff(f,I,J); f bivariate polynomial, I,J integers
+RETURN:  if f = sum(a(i,j)*x^i*y^j), then koeff(f,I,J)= a(I,J) (of type number)
+NOTE:    J must be in the range of the exponents of the 2nd ring variable
+EXAMPLE: example koeff;  shows an example
+"
+{
+  matrix mat = coeffs(coeffs(f,var(2))[J+1,1],var(1));
+  if (size(mat) <= I) { return(0);}
+  else { return(leadcoef(mat[I+1,1]));}
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring r=0,(x,y),dp;
+  koeff(x2+2xy+3xy2-x2y-2y3,1,2);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc squarefree (poly f)
+"USAGE:  squarefree(f);  f poly
+ASSUME:  f is a bivariate polynomial (in the first 2 ring variables).
+RETURN:  poly, a squarefree divisor of f.
+NOTE:    Usually, the return value is the greatest squarefree divisor, but
+         there is one exception: factors with a p-th root, p the
+         characteristic of the basering, are lost.
+SEE ALSO: allsquarefree
+EXAMPLE: example squarefree; shows some examples.
+"
+{
+ //----------------- Wechsel in geeigneten Ring & Variablendefinition ---------
+  if (nvars(basering)!=2)
+  { ERROR("basering must have exactly 2 variables for Hnoether::squarefree"); }
+  def altring = basering;
+  int e;
+  int gcd_ok=1;
+  string mipl="0";
+  if (size(parstr(altring))==1) { mipl=string(minpoly); }
+ //---- test: char = (p^k,a) (-> gcd not implemented) or (p,a) (gcd works) ----
+  //if ((char(basering)!=0) and (charstr(basering)!=string(char(basering))))
+  gcd_ok= ! hasGFCoefficient(basering);
+  execute("ring rsqrf = ("+charstr(altring)+"),(x,y),dp;");
+  if ((gcd_ok!=0) && (mipl!="0")) { execute("minpoly="+mipl+";"); }
+  poly f=fetch(altring,f);
+  poly dif,g,l;
+  if ((char(basering)==0) and (charstr(basering)!=string(char(basering)))
+      and (mipl!="0")) {
+    gcd_ok=0;                   // since Singular 1.2 gcd no longer implemented
+  }
+  if (gcd_ok!=0) {
+ //--------------------- Berechne f/ggT(f,df/dx,df/dy) ------------------------
+    dif=diff(f,x);
+    if (dif==0) { g=f; }        // zur Beschleunigung
+    else { g=gcd(f,dif); }
+    if (g!=1) {                 // sonst schon sicher, dass f quadratfrei
+     dif=diff(f,y);
+     if (dif!=0) { g=gcd(g,dif); }
+    }
+    if (g!=1) {
+     e=0;
+     if (g==f) { l=1; }         // zur Beschleunigung
+     else {
+       module m=syz(ideal(g,f));
+       if (deg(m[2,1])>0) {
+         "!! The Singular command 'syz' has returned a wrong result !!";
+         l=1;                   // Division f/g muss aufgehen
+       }
+       else { l=m[1,1]; }
+     }
+    }
+    else { e=1; }
+  }
+  else {
+ //------------------- Berechne syz(f,df/dx) oder syz(f,df/dy) ----------------
+ //-- Achtung: Ist f reduzibel, koennen Faktoren mit Ableitung Null verloren --
+ //-- gehen! Ist aber nicht weiter schlimm, weil char (p^k,a) nur im irred.  --
+ //-- Fall vorkommen kann. Wenn f nicht g^p ist, wird auf jeden Fall         --
+ //------------------------ ein Faktor gefunden. ------------------------------
+    dif=diff(f,x);
+    if (dif == 0) {
+     dif=diff(f,y);
+     if (dif==0) { e=2; l=1; } // f is of power divisible by char of basefield
+     else { l=syz(ideal(dif,f))[1,1];  // x^p+y^(p-1) abgedeckt
+            if (subst(f,x,0)==0) { l=l*x; }
+            if (deg(l)==deg(f))  { e=1;}
+            else {e=0;}
+     }
+    }
+    else { l=syz(ideal(dif,f))[1,1];
+           if (subst(f,y,0)==0) { l=l*y; }
+           if (deg(l)==deg(f))  { e=1;}
+           else {e=0;}
+    }
+  }
+ //--------------- Wechsel in alten Ring und Rueckgabe des Ergebnisses --------
+  setring altring;
+  if (e==1) { return(f); }    // zur Beschleunigung
+  else {
+   poly l=fetch(rsqrf,l);
+   return(l);
+  }
+}
+example
+{ "EXAMPLE:"; echo = 2;
+ ring exring=3,(x,y),dp;
+ squarefree((x3+y)^2);
+ squarefree((x+y)^3*(x-y)^2); // Warning: (x+y)^3 is lost
+ squarefree((x+y)^4*(x-y)^2); // result is (x+y)*(x-y)
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc allsquarefree (poly f, poly l)
+"USAGE : allsquarefree(f,g);  f,g poly
+ASSUME: g is the output of @code{squarefree(f)}.
+RETURN: the greatest squarefree divisor of f.
+NOTE  : This proc uses factorize to get the missing factors of f not in g and,
+        therefore, may be slow.
+SEE ALSO: squarefree
+EXAMPLE: example allsquarefree;  shows an example
+"
+{
+ //------------------------ Wechsel in geeigneten Ring ------------------------
+ def altring = basering;
+ string mipl="0";
+ if (size(parstr(altring))==1) { mipl=string(minpoly); }
+ if ((char(basering)!=0) and (charstr(basering)!=string(char(basering)))) {
+   string tststr=charstr(basering);
+   tststr=tststr[1..find(tststr,",")-1];           //-> "p^k" bzw. "p"
+   if (tststr!=string(char(basering))) {
+     " Sorry -- not implemented for this ring (gcd doesn't work)";
+     return(l);
+   }
+ }
+ execute("ring rsqrf = ("+charstr(altring)+"),(x,y),dp;");
+ if (mipl!="0") { execute("minpoly="+mipl+";"); }
+ poly f=fetch(altring,f);
+ poly l=fetch(altring,l);
+ //---------- eliminiere bereits mit squarefree gefundene Faktoren ------------
+ poly g=l;
+ while (deg(g)!=0) {
+   f=syz(ideal(g,f))[1,1];                         // f=f/g;
+   g=gcd(f,l);
+ }                                                 // jetzt f=h^p
+ //--------------- Berechne uebrige Faktoren mit factorize --------------------
+ if (deg(f)>0) {
+  g=1;
+//*CL old:  ideal factf=factorize(f,1);
+//*         for (int i=1; i<=size(factf); i++) { g=g*factf[i]; }
+  ideal factf=factorize(f)[1];
+  for (int i=2; i<=size(factf); i++) { g=g*factf[i]; }
+  poly testp=squarefree(g);
+  if (deg(testp)<deg(g)) {
+    "!! factorize has not worked correctly !!";
+    if (testp==1) {" We cannot proceed ..."; g=1;}
+    else {" But we could recover some factors..."; g=testp;}
+  }
+  l=l*g;
+ }
+ //--------------- Wechsel in alten Ring und Rueckgabe des Ergebnisses --------
+ setring altring;
+ l=fetch(rsqrf,l);
+ return(l);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring exring=7,(x,y),dp;
+  poly f=(x+y)^7*(x-y)^8;
+  poly g=squarefree(f);
+  g;                      // factor x+y lost, since characteristic=7
+  allsquarefree(f,g);     // all factors (x+y)*(x-y) found
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc is_irred (poly f)
+"USAGE:   is_irred(f); f poly
+ASSUME:  f is a squarefree bivariate polynomial (in the first 2 ring
+         variables).
+RETURN:  int (0 or 1): @*
+         - @code{is_irred(f)=1} if f is irreducible as a formal power
+         series over the algebraic closure of its coefficient field (f
+         defines an analytically irreducible curve at zero), @*
+         - @code{is_irred(f)=0} otherwise.
+NOTE:    0 and units in the ring of formal power series are considered to be
+         not irreducible.
+KEYWORDS: irreducible power series
+EXAMPLE: example is_irred;  shows an example
+"
+{
+  int pl=printlevel;
+  printlevel=-1;
+  list hnl=develop(f,-1);
+  printlevel=pl;
+  return(hnl[5]);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring exring=0,(x,y),ls;
+  is_irred(x2+y3);
+  is_irred(x2+y2);
+  is_irred(x2+y3+1);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+static proc polytest(poly f)
+"USAGE : polytest(f); f poly in x and y
+RETURN: a monomial of f with |coefficient| > 16001
+          or exponent divisible by 32003, if there is one
+        0 else (in this case computing a squarefree divisor
+                in characteristic 32003 could make sense)
+NOTE:   this procedure is only useful in characteristic zero, because otherwise
+        there is no appropriate ordering of the leading coefficients
+"
+{
+ poly verbrecher=0;
+ intvec leitexp;
+ for (; (f<>0) and (verbrecher==0); f=f-lead(f)) {
+  if ((leadcoef(f)<-16001) or (leadcoef(f)>16001)) {verbrecher=lead(f);}
+  leitexp=leadexp(f);
+  if (( ((leitexp[1] % 32003) == 0)   and (leitexp[1]<>0))
+     or ( ((leitexp[2] % 32003) == 0) and (leitexp[2]<>0)) )
+       {verbrecher=lead(f);}
+ }
+ return(verbrecher);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+
+proc develop(list #)
+"USAGE:   develop(f [,n]); f poly, n int
+ASSUME:  f is a bivariate polynomial (in the first 2 ring variables) and
+         irreducible as power series (for reducible f use @code{hnexpansion}).
+RETURN:  list @code{L} with:
+ at texinfo
+ at table @asis
+ at item @code{L[1]}; matrix:
+         Each row contains the coefficients of the corresponding line of the
+         Hamburger-Noether expansion (HNE). The end of the line is marked in
+         the matrix by the first ring variable (usually x).
+ at item @code{L[2]}; intvec:
+         indicating the length of lines of the HNE
+ at item @code{L[3]}; int:
+         0  if the 1st ring variable was transversal (with respect to f), @*
+         1  if the variables were changed at the beginning of the
+            computation, @*
+        -1  if an error has occurred.
+ at item @code{L[4]}; poly:
+         the transformed polynomial of f to make it possible to extend the
+         Hamburger-Noether development a posteriori without having to do
+         all the previous calculation once again (0 if not needed)
+ at item @code{L[5]}; int:
+         1  if the curve has exactly one branch (i.e., is irreducible), @*
+         0  else (i.e., the curve has more than one HNE, or f is not valid).
+ at end table
+ at end texinfo
+DISPLAY: The (non zero) elements of the HNE (if not called by another proc).
+NOTE:    The optional parameter @code{n} affects only the computation of
+         the LAST line of the HNE. If it is given, the HN-matrix @code{L[1]}
+         will have at least @code{n} columns. @*
+         Otherwise, the number of columns will be chosen minimal such that the
+         matrix contains all necessary information (i.e., all lines of the HNE
+         but the last (which is in general infinite) have place). @*
+         If @code{n} is negative, the algorithm is stopped as soon as the
+         computed information is sufficient for @code{invariants(L)}, but the
+         HN-matrix @code{L[1]} may still contain undetermined elements, which
+         are marked with the 2nd variable (of the basering). @*
+         For time critical computations it is recommended to use
+         @code{ring ...,(x,y),ls} as basering - it increases the algorithm's
+         speed. @*
+         If @code{printlevel>=0} comments are displayed (default is
+         @code{printlevel=0}).
+SEE ALSO: hnexpansion, extdevelop, displayHNE
+EXAMPLES: example develop;         shows an example
+          example parametrize;     shows an example for using the 2nd parameter
+"
+{
+ //--------- Abfangen unzulaessiger Ringe: 1) nur eine Unbestimmte ------------
+ poly f=#[1];
+ if (size(#) > 1) {int maxspalte=#[2];}
+ else             {int maxspalte= 1 ; }
+ if (nvars(basering) < 2) {
+   " Sorry. I need two variables in the ring.";
+   return(list(matrix(maxideal(1)[1]),intvec(0),-1,poly(0),0));}
+ if (nvars(basering) > 2) {
+   dbprint(printlevel-voice+2,
+   " Warning! You have defined too many variables!
+ All variables except the first two will be ignored!"
+           );
+ }
+
+ string namex=varstr(1); string namey=varstr(2);
+ list return_error=matrix(maxideal(1)[2]),intvec(0),int(-1),poly(0),int(0);
+
+ //------------- 2) mehrere Unbestimmte, weitere unzulaessige Ringe -----------
+ // Wir koennen einheitlichen Rueckgabewert benutzen, aus dem ersichtlich ist,
+ // dass ein Fehler aufgetreten ist: return_error.
+ //----------------------------------------------------------------------------
+
+ if (charstr(basering)=="real") {
+  " The algorithm doesn't work with 'real' as coefficient field.";
+                     // denn : map from characteristic -1 to -1 not implemented
+  return(return_error);
+ }
+ if ((char(basering)!=0) and (charstr(basering)!=string(char(basering)))) {
+ //-- teste, ob char = (p^k,a) (-> a primitiv; erlaubt) oder (p,a[,b,...]) ----
+    string tststr=charstr(basering);
+    tststr=tststr[1..find(tststr,",")-1];           //-> "p^k" bzw. "p"
+    int primit=(tststr==string(char(basering)));
+    if (primit!=0) {
+      " Such extensions of Z/p are not implemented.";
+      " Please try (p^k,a) as ground field or use `hnexpansion'.";
+      return(return_error);
+    }
+ }
+ //---- Ende der unzulaessigen Ringe; Ringwechsel in einen guenstigen Ring: ---
+
+ int ringwechsel=(varstr(basering)!="x,y") or (ordstr(basering)!="ls(2),C");
+
+ def altring = basering;
+ if (ringwechsel) {
+   string mipl=string(minpoly);
+   execute("ring guenstig = ("+charstr(altring)+"),(x,y),ls;");
+   if ((char(basering)==0) && (mipl!="0")) {
+     execute("minpoly="+mipl+";");
+   }}
+ else { def guenstig=basering; }
+ export guenstig;
+
+ //-------------------------- Initialisierungen -------------------------------
+ map m=altring,x,y;
+ if (ringwechsel) { poly f=m(f); }
+ if (defined(HNDebugOn))
+ {"received polynomial: ",f,", where x =",namex,", y =",namey;}
+ kill m;
+ int M,N,Q,R,l,e,hilf,eps,getauscht,Abbruch,zeile,exponent,Ausgabe;
+
+ // Werte von Ausgabe: 0 : normale HNE-Matrix,
+ // 1 : Fehler aufgetreten - Matrix (namey) zurueck
+ // 2 : Die HNE ist eine Nullzeile - Matrix (0) zurueck
+ // int maxspalte=1; geaendert: wird jetzt am Anfang gesetzt
+
+ int minimalHNE=0;          // Flag fuer minimale HNE-Berechnung
+ int einzweig=1;            // Flag fuer Irreduzibilit"at
+ intvec hqs;                // erhaelt die Werte von h(zeile)=Q;
+
+ if (maxspalte<0) {
+   minimalHNE=1;
+   maxspalte=1;
+ }
+
+ number c,delt;
+ int p = char(basering);
+ string ringchar=charstr(basering);
+ map xytausch = basering,y,x;
+ if ((p!=0) and (ringchar != string(p))) {
+                            // coefficient field is extension of Z/pZ
+   execute("int n_elements="+
+           ringchar[1,size(ringchar)-size(parstr(basering))-1]+";");
+                            // number of elements of actual ring
+   number generat=par(1);   // generator of the coefficient field of the ring
+ }
+
+
+ //========= Abfangen von unzulaessigen oder trivialen Eingaben ===============
+ //------------ Nullpolynom oder Einheit im Potenzreihenring: -----------------
+ if (f == 0) {
+   dbprint(printlevel+1,"The given polynomial is the zero-polynomial !");
+   Abbruch=1; Ausgabe=1;
+ }
+ else {
+   intvec nm = getnm(f);
+   N = nm[1]; M = nm[2]; // Berechne Schnittpunkte Newtonpolygon mit Achsen
+   if (N == 0) {
+     dbprint(printlevel+1,"The given polynomial is a unit as power series !");
+     Abbruch=1; Ausgabe=1;
+   }
+   else {
+    if (N == -1) {
+      if ((voice==2) && (printlevel > -1)) { "The HNE is x = 0"; }
+      Abbruch=1; Ausgabe=2; getauscht=1;
+      if (M <> 1) { einzweig=0; }
+    }
+    else {
+     if (M == -1) {
+       if ((voice==2) && (printlevel > -1)) { "The HNE is y = 0"; }
+       Abbruch=1; Ausgabe=2;
+       if (N <> 1) { einzweig=0; }
+   }}}
+ }
+ //--------------------- Test auf Quadratfreiheit -----------------------------
+ if (Abbruch==0) {
+
+ //-------- Fall basering==0,... : Wechsel in Ring mit char >0 ----------------
+ // weil squarefree eine Standardbasis berechnen muss (verwendet Syzygien)
+ // -- wenn f in diesem Ring quadratfrei ist, dann erst recht im Ring guenstig
+ //----------------------------------------------------------------------------
+
+  if ((p==0) and (size(charstr(basering))==1)) {
+   int testerg=(polytest(f)==0);
+   ring zweitring = 32003,(x,y),dp;
+   map polyhinueber=guenstig,x,y;     // fetch geht nicht
+   poly f=polyhinueber(f);
+   poly test_sqr=squarefree(f);
+   if (test_sqr != f) {
+    if (printlevel>0) {
+      "Most probably the given polynomial is not squarefree. But the test was";
+      "made in characteristic 32003 and not 0 to improve speed. You can";
+      "(r) redo the test in char 0 (but this may take some time)";
+      "(c) continue the development, if you're sure that the polynomial",
+      "IS squarefree";
+      if (testerg==1) {
+        "(s) continue the development with a squarefree factor (*)";}
+      "(q) or just quit the algorithm (default action)";
+      "";"Please enter the letter of your choice:";
+      string str=read("")[1];
+    }
+    else { string str="r"; }      // printlevel <= 0: non-interactive behaviour
+    setring guenstig;
+    map polyhinueber=zweitring,x,y;
+    if (str=="r") {
+      poly test_sqr=squarefree(f);
+      if (test_sqr != f) {
+       if (printlevel>0) { "The given polynomial is in fact not squarefree."; }
+       else              { "The given polynomial is not squarefree!"; }
+       "I'll continue with the radical.";
+       if (printlevel>0) { pause("Hit RETURN to continue:"); }
+       f=test_sqr;
+      }
+      else {
+       dbprint(printlevel,
+        "everything is ok -- the polynomial is squarefree in char(k)=0");
+      }
+    }
+    else {
+      if ((str=="s") and (testerg==1)) {
+       "(*) attention: it could be that the factor is only one in char 32003!";
+        f=polyhinueber(test_sqr);
+      }
+      else {
+        if (str<>"c") {
+          setring altring;kill guenstig;kill zweitring;
+          return(return_error);}
+        else { "if the algorithm doesn't terminate, you were wrong...";}
+    }}
+    kill zweitring;
+    nm = getnm(f);             // N,M haben sich evtl. veraendert
+    N = nm[1]; M = nm[2];      // Berechne Schnittpunkte Newtonpolynom mit Achsen
+    if (defined(HNDebugOn)) {"I continue with the polynomial",f; }
+   }
+   else {
+     setring guenstig;
+     kill zweitring;
+   }
+  }
+ // ------------------- Fall Charakteristik > 0 -------------------------------
+  else {
+   poly test_sqr=squarefree(f);
+   if (test_sqr == 1) {
+    "The given polynomial is of the form g^"+string(p)+", therefore",
+    "reducible.";"Please try again.";
+    setring altring;
+    kill guenstig;
+    return(return_error);}
+   if (test_sqr != f) {
+    "The given polynomial is not squarefree. I'll continue with the radical.";
+    if (p != 0)
+     {"But if the polynomial contains a factor of the form g^"+string(p)+",";
+      "this factor will be lost.";}
+    if (printlevel>0) { pause("Hit RETURN to continue:"); }
+    f=test_sqr;
+    nm = getnm(f);              // N,M haben sich veraendert
+    N = nm[1]; M = nm[2];       // Berechne Schnittpunkte Newtonpolynom mit Achsen
+    if (defined(HNDebugOn)) {"I continue with the polynomial",f; }
+   }
+
+  }                             // endelse(p==0)
+
+  if (N==0) {
+    " Sorry. The remaining polynomial is a unit in the power series ring...";
+    setring altring;kill guenstig;return(return_error);
+  }
+ //---------------------- gewaehrleiste, dass x transvers ist -----------------
+  if (M < N)
+  { f = xytausch(f);            // Variablentausch : x jetzt transvers
+    getauscht = 1;              // den Tausch merken
+    M = M+N; N = M-N; M = M-N;  // M, N auch vertauschen
+  }
+  if (defined(HNDebugOn)) {
+   if (getauscht) {"x<->y were exchanged; polynomial is now ",f;}
+   else           {"x , y were not exchanged";}
+   "M resp. N are now",M,N;
+  }
+ }                              // end(if Abbruch==0)
+
+ ideal a(0);
+ while (Abbruch==0) {
+
+ //================= Beginn der Schleife (eigentliche Entwicklung) ============
+
+ //------------------- ist das Newtonpolygon eine gerade Linie? ---------------
+  if (testreducible(f,N,M)) {
+    dbprint(printlevel+1," The given polynomial is not irreducible");
+    kill guenstig;
+    setring altring;
+    return(return_error);       // Abbruch der Prozedur!
+  }
+  R = M%N;
+  Q = M div N;
+
+ //-------------------- Fall Rest der Division R = 0 : ------------------------
+  if (R == 0) {
+    c = koeff(f,0,N);
+    if (c == 0) {"Something has gone wrong! I didn't get N correctly!"; exit;}
+    e = gcd(M,N);
+ //----------------- Test, ob leitf = c*(y^N - delta*x^(m/e))^e ist -----------
+    if (p==0) {
+      delt = koeff(f,M div e,N - N div e) / (-1*e*c);
+      if (defined(HNDebugOn)) {"quasihomogeneous leading form:",
+         leit(f,N,M)," = ",c,"* (y -",delt,"* x^"+string(M div e)+")^",e," ?";}
+      if (leit(f,N,M) != c*(y^(N div e) - delt*x^(M div e))^e) {
+        dbprint(printlevel+1," The given polynomial is reducible !");
+        Abbruch=1; Ausgabe=1; }
+    }
+    else {                     // p!=0
+      if (e%p != 0) {
+        delt = koeff(f,M div e,N - N div e) / (-1*e*c);
+        if (defined(HNDebugOn)) {"quasihomogeneous leading form:",
+           leit(f,N,M)," = ",c,"* (y -",delt,"* x^"+string(M div e)+")^",e," ?";}
+        if (leit(f,N,M) != c*(y^(N div e) - delt*x^(M div e))^e) {
+           dbprint(printlevel+1," The given polynomial is reducible !");
+           Abbruch=1; Ausgabe=1; }
+      }
+
+      else {                   // e%p == 0
+        eps = e;
+        for (l = 0; eps%p == 0; l=l+1) { eps=eps div p;}
+        if (defined(HNDebugOn)) {e," -> ",eps,"*",p,"^",l;}
+        delt = koeff(f,(M div e)*p^l,(N div e)*p^l*(eps-1)) / (-1*eps*c);
+
+        if ((ringchar != string(p)) and (delt != 0)) {
+ //- coeff. field is not Z/pZ => we`ve to correct delta by taking (p^l)th root-
+          if (delt == generat) {exponent=1;}
+          else {
+           if (delt == 1) {exponent=0;}
+           else {
+            exponent=pardeg(delt);
+
+ //-- an dieser Stelle kann ein Fehler auftreten, wenn wir eine transzendente -
+ //-- Erweiterung von Z/pZ haben: dann ist das hinzuadjungierte Element kein  -
+ //-- Erzeuger der mult. Gruppe, d.h. in Z/pZ (a) gibt es i.allg. keinen      -
+ //-- Exponenten mit z.B. a2+a = a^exp                                        -
+ //----------------------------------------------------------------------------
+          }}
+          delt = generat^(extgcd(n_elements-1,p^l)[3]*exponent);
+        }
+
+        if (defined(HNDebugOn)) {"quasihomogeneous leading form:",
+          leit(f,N,M)," = ",c,"* (y^"+string(N div e),"-",delt,"* x^"
+          +string(M div e)+")^",e,"  ?";}
+        if (leit(f,N,M) != c*(y^(N div e) - delt*x^(M div e))^e) {
+          dbprint(printlevel+1," The given polynomial is reducible !");
+          Abbruch=1; Ausgabe=1; }
+      }
+    }
+    if (Abbruch == 0) {
+      f = T1_Transform(f,delt,M div e);
+      dbprint(printlevel-voice+2,"a("+string(zeile)+","+string(Q)+") = "
+              +string(delt));
+      a(zeile)[Q]=delt;
+      if (defined(HNDebugOn)) {"transformed polynomial: ",f;}}
+
+      nm=getnm(f); N=nm[1]; M=nm[2];        // Neuberechnung des Newtonpolygons
+  }
+ //--------------------------- Fall R > 0 : -----------------------------------
+  else {
+    dbprint(printlevel-voice+2, "h("+string(zeile)+ ") ="+string(Q));
+    hqs[zeile+1]=Q;                  // denn zeile beginnt mit dem Wert 0
+    a(zeile)[Q+1]=x;                 // Markierung des Zeilenendes der HNE
+    maxspalte=maxspalte*((Q+1) < maxspalte) + (Q+1)*((Q+1) >= maxspalte);
+                                     // Anpassung der Sp.zahl der HNE-Matrix
+    f = T_Transform(f,Q,N);
+    if (defined(HNDebugOn)) {"transformed polynomial: ",f;}
+    zeile=zeile+1;
+ //------------ Bereitstellung von Speicherplatz fuer eine neue Zeile: --------
+    ideal a(zeile);
+    M=N;N=R;
+  }
+
+ //--------------- schneidet das Newtonpolygon beide Achsen? ------------------
+  if (M==-1) {
+     dbprint(printlevel-voice+2,"The HNE is finite!");
+     a(zeile)[Q+1]=x;   // Markiere das Ende der Zeile
+     hqs[zeile+1]=Q;
+     maxspalte=maxspalte*((Q+1) < maxspalte) + (Q+1)*((Q+1) >= maxspalte);
+     if (N <> 1) { einzweig=0; }
+     f=0;               // transformiertes Polynom wird nicht mehr gebraucht
+     Abbruch=1;
+  }
+  else {if (M<N) {"Something has gone wrong: M<N";}}
+  if(defined(HNDebugOn)) {"new M,N:",M,N;}
+
+ //----------------- Abbruchbedingungen fuer die Schleife: --------------------
+  if ((N==1) and (Abbruch!=1) and ((M > maxspalte) or (minimalHNE==1))
+      and (size(a(zeile))>0))
+ //----------------------------------------------------------------------------
+ // Abbruch, wenn die Matrix so voll ist, dass eine neue Spalte angefangen
+ // werden muesste und die letzte Zeile nicht nur Nullen enthaelt
+ // oder wenn die Matrix nicht voll gemacht werden soll (minimale Information)
+ //----------------------------------------------------------------------------
+   { Abbruch=1; hqs[zeile+1]=-1;
+     if (maxspalte < ncols(a(zeile))) { maxspalte=ncols(a(zeile));}
+     if ((minimalHNE==1) and (M <= maxspalte)) {
+ // teile param mit, dass Eintraege der letzten Zeile nur teilw. richtig sind:-
+       hqs[zeile+1]=-M;
+ //------------- markiere den Rest der Zeile als unbekannt: -------------------
+       for (R=M; R <= maxspalte; R++) { a(zeile)[R]=y;}
+     }                  // R wird nicht mehr gebraucht
+   }
+ //========================= Ende der Schleife ================================
+
+ }
+ setring altring;
+ if (Ausgabe == 0) {
+ //-------------------- Ergebnis in den alten Ring transferieren: -------------
+   map zurueck=guenstig,maxideal(1)[1],maxideal(1)[2];
+   matrix amat[zeile+1][maxspalte];
+   ideal uebergabe;
+   for (e=0; e<=zeile; e=e+1) {
+     uebergabe=zurueck(a(e));
+     if (ncols(uebergabe) > 1) {
+      amat[e+1,1..ncols(uebergabe)]=uebergabe;}
+     else {amat[e+1,1]=uebergabe[1];}
+   }
+   if (ringwechsel) {
+     if (nvars(altring)==2) { f=fetch(guenstig,f); }
+     else                   { f=zurueck(f); }
+   }
+ }
+
+ kill guenstig;
+ if ((einzweig==0) && (voice==2) && (printlevel > -1)) {
+    "// Note: The curve is reducible, but we were able to compute a HNE.";
+    "// This means the result is only one of several existing HNE's.";
+ }
+ if (Ausgabe == 0) { return(list(amat,hqs,getauscht,f,einzweig));}
+ if (Ausgabe == 1) { return(return_error);}             // error has occurred
+ if (Ausgabe == 2) { return(list(matrix(ideal(0,x)),intvec(1),getauscht,
+                                 poly(0),einzweig));}   // HNE is x=0 or y=0
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring exring = 7,(x,y),ds;
+  list Hne=develop(4x98+2x49y7+x11y14+2y14);
+  print(Hne[1]);
+  // therefore the HNE is:
+  // z(-1)= 3*z(0)^7 + z(0)^7*z(1),
+  // z(0) = z(1)*z(2),       (there is 1 zero in the 2nd row before x)
+  // z(1) = z(2)^3*z(3),     (there are 3 zeroes in the 3rd row)
+  // z(2) = z(3)*z(4),
+  // z(3) = -z(4)^2 + 0*z(4)^3 +...+ 0*z(4)^8 + ?*z(4)^9 + ...
+  // (the missing x in the last line indicates that it is not complete.)
+  Hne[2];
+  param(Hne);
+  // parametrization:   x(t)= -t^14+O(t^21),  y(t)= -3t^98+O(t^105)
+  // (the term -t^109 in y may have a wrong coefficient)
+  displayHNE(Hne);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//               procedures to extract information out of HNE                //
+///////////////////////////////////////////////////////////////////////////////
+
+proc param (list L, list #)
+"USAGE:  param(L [,s]); L list, s any type (optional)
+ASSUME:  L is the output of @code{develop(f)}, or of
+        @code{extdevelop(develop(f),n)}, or (one entry in) the list of HN
+        data created by @code{hnexpansion(f[,\"ess\"])}.
+RETURN: If L are the HN data of an irreducible plane curve singularity f: a
+        parametrization for f in the following format: @*
+        - if only the list L is given, the result is an ideal of two
+        polynomials p[1],p[2]: if the HNE was finite then f(p[1],p[2])=0};
+        if not, the true parametrization will be given by two power series,
+        and p[1],p[2] are truncations of these series.@*
+        - if the optional parameter s is given, the result is a list l:
+        l[1]=param(L) (ideal) and l[2]=intvec with two entries indicating
+        the highest degree up to which the coefficients of the monomials in
+        l[1] are exact (entry -1 means that the corresponding parametrization
+        is exact).
+        If L collects the HN data of a reducible plane curve singularity f,
+        the return value is a list of parametrizations in the respective
+        format.
+NOTE:   If the basering has only 2 variables, the first variable is chosen
+        as indefinite. Otherwise, the 3rd variable is chosen.
+SEE ALSO: develop, extdevelop
+KEYWORDS: parametrization
+EXAMPLE: example param;     shows an example
+         example develop;   shows another example
+"
+{
+ //-------------------------- Initialisierungen -------------------------------
+ int return_list;
+ if (size(#)>0) { return_list=1; }
+
+ if (typeof(L[1])=="list") { // output of hnexpansion (> 1 branch)
+   list Ergebnis;
+   for (int i=1; i<=size(L); i++) {
+     dbprint(printlevel-voice+4,"// Parametrization of branch number "
+       +string(i)+" computed.");
+     printlevel=printlevel+1;
+     if (return_list==1) { Ergebnis[i]=param(L[i],1); }
+     else                { Ergebnis[i]=param(L[i]); }
+     printlevel=printlevel-1;
+   }
+   return(Ergebnis);
+ }
+ else {
+   matrix m=L[1];
+   intvec v=L[2];
+   int switch=L[3];
+ }
+ if (switch==-1) {
+   "An error has occurred in develop, so there is no HNE.";
+   return(ideal(0,0));
+ }
+ int fehler,fehlervor,untergrad,untervor,beginn,i,zeile,hilf;
+
+ if (nvars(basering) > 2) { poly z(size(v)+1)=var(3); }
+ else                     { poly z(size(v)+1)=var(1); }
+ poly z(size(v));
+ zeile=size(v);
+ //------------- Parametrisierung der untersten Zeile der HNE -----------------
+ if (v[zeile] > 0) {
+   fehler=0;           // die Parametrisierung wird exakt werden
+   for (i=1; i<=v[zeile]; i++) {
+     z(zeile)=z(zeile)+m[zeile,i]*z(zeile+1)^i;
+   }
+ }
+ else {
+   untervor=1;         // = Untergrad der vorhergehenden Zeile
+   if (v[zeile]==-1) {
+     fehler=ncols(m)+1;
+     for (i=1; i<=ncols(m); i++) {
+       z(zeile)=z(zeile)+m[zeile,i]*z(zeile+1)^i;
+       if ((untergrad==0) and (m[zeile,i]!=0)) {untergrad=i;}
+                       // = Untergrad der aktuellen Zeile
+     }
+   }
+   else {
+     fehler= -v[zeile];
+     for (i=1; i<-v[zeile]; i++) {
+       z(zeile)=z(zeile)+m[zeile,i]*z(zeile+1)^i;
+       if ((untergrad==0) and (m[zeile,i]!=0)) {untergrad=i;}
+     }
+   }
+ }
+ //------------- Parametrisierung der restlichen Zeilen der HNE ---------------
+ for (zeile=size(v)-1; zeile>0; zeile--) {
+   poly z(zeile);
+   beginn=0;             // Beginn der aktuellen Zeile
+   for (i=1; i<=v[zeile]; i++) {
+     z(zeile)=z(zeile)+m[zeile,i]*z(zeile+1)^i;
+     if ((beginn==0) and (m[zeile,i]!=0)) { beginn=i;}
+   }
+   z(zeile)=z(zeile) + z(zeile+1)^v[zeile] * z(zeile+2);
+   if (beginn==0) {
+     if (fehler>0) {     // damit fehler=0 bleibt bei exakter Param.
+     fehlervor=fehler;   // Fehler der letzten Zeile
+     fehler=fehler+untergrad*(v[zeile]-1)+untervor;   // Fehler dieser Zeile
+     hilf=untergrad;
+     untergrad=untergrad*v[zeile]+untervor;
+     untervor=hilf;}     // untervor = altes untergrad
+   }
+   else {
+     fehlervor=fehler;
+     fehler=fehler+untergrad*(beginn-1);
+     untervor=untergrad;
+     untergrad=untergrad*beginn;
+   }
+ }
+ //--------------------- Ausgabe der Fehlerabschaetzung -----------------------
+ if (switch==0) {
+   if (fehler>0) {
+     if (fehlervor>0) {
+       dbprint(printlevel-voice+4,""+
+         "// ** Warning: result is exact up to order "+string(fehlervor-1)+
+         " in "+ string(var(1))+" and "+string(fehler-1)+" in " +
+         string(var(2))+" !");
+     }
+     else {
+       dbprint(printlevel-voice+4,""+
+         "// ** Warning: result is exact up to order "+ string(fehler-1)+
+         " in "+string(var(2))+" !");
+     }
+   }
+   if (return_list==0) { return(ideal(z(2),z(1))); }
+   else   { return(list(ideal(z(2),z(1)),intvec(fehlervor-1,fehler-1))); }
+ }
+ else {
+   if (fehler>0) {
+     if (fehlervor>0) {
+       dbprint(printlevel-voice+4,""+
+         "// ** Warning: result is exact up to order "+string(fehler-1)+
+         " in "+ string(var(1))+" and "+string(fehlervor-1)+" in " +
+         string(var(2))+" !");
+     }
+     else {
+       dbprint(printlevel-voice+4,""+
+        "// ** Warning: result is exact up to order "+ string(fehler-1)+
+         " in "+string(var(1))+" !");
+     }
+   }
+   if (return_list==0) { return(ideal(z(1),z(2))); }
+   else   { return(list(ideal(z(1),z(2)),intvec(fehler-1,fehlervor-1))); }
+ }
+}
+example
+{ "EXAMPLE:"; echo = 2;
+ ring exring=0,(x,y,t),ds;
+ poly f=x3+2xy2+y2;
+ list Hne=develop(f);
+ list hne_extended=extdevelop(Hne,10);
+            //   compare the HNE matrices ...
+ print(Hne[1]);
+ print(hne_extended[1]);
+            // ... and the resulting parametrizations:
+ param(Hne);
+ param(hne_extended);
+ param(hne_extended,0);
+
+ // An example with more than one branch:
+ list L=hnexpansion(f*(x2+y4));
+ def HNring = L[1]; setring HNring;
+ param(hne);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc invariants
+"USAGE:   invariants(INPUT); INPUT list or poly
+ASSUME:  @code{INPUT} is the output of @code{develop(f)}, or of
+         @code{extdevelop(develop(f),n)}, or one entry of the list of HN data
+         computed by @code{hnexpansion(f[,\"ess\"])}.
+RETURN:  list @code{INV} of the following format:
+ at format
+    INV[1]:  intvec    (characteristic exponents)
+    INV[2]:  intvec    (generators of the semigroup)
+    INV[3]:  intvec    (Puiseux pairs, 1st components)
+    INV[4]:  intvec    (Puiseux pairs, 2nd components)
+    INV[5]:  int       (degree of the conductor)
+    INV[6]:  intvec    (sequence of multiplicities)
+ at end format
+         If @code{INPUT} contains no valid HN expansion, the empty list is
+         returned.
+ASSUME:  @code{INPUT} is a bivariate polynomial f, or the output of
+         @code{hnexpansion(f)}, or the list of HN data computed by
+         @code{hnexpansion(f [,\"ess\"])}.
+RETURN:  list @code{INV}, such that @code{INV[i]} coincides with the output of
+         @code{invariants(develop(f[i]))}, where f[i] is the i-th branch of
+         f, and the last entry of @code{INV} contains further invariants of
+         f in the format:
+ at format
+    INV[last][1] : intmat    (contact matrix of the branches)
+    INV[last][2] : intmat    (intersection multiplicities of the branches)
+    INV[last][3] : int       (delta invariant of f)
+ at end format
+NOTE:    In case the Hamburger-Noether expansion of the curve f is needed
+         for other purposes as well it is better to calculate this first
+         with the aid of @code{hnexpansion} and use it as input instead of
+         the polynomial itself.
+SEE ALSO: hnexpansion, develop, displayInvariants, multsequence, intersection
+KEYWORDS: characteristic exponents; semigroup of values; Puiseux pairs;
+          conductor, degree; multiplicities, sequence of
+EXAMPLE:  example invariants; shows an example
+"
+{
+ //---- INPUT = poly, or HNEring, or hne of reducible curve  -----------------
+ if (typeof(#[1])!="matrix") {
+   if (typeof(#[1])=="poly") {
+      list L=hnexpansion(#[1]);
+      if (typeof(L[1])=="ring") {
+        def altring = basering;
+        def HNring = L[1]; setring HNring;
+        list Ergebnis = invariants(hne);
+        setring altring;
+        kill HNring;
+        return(Ergebnis);
+      }
+      else {
+        return(invariants(L));
+      }
+   }
+   if (typeof(#[1])=="ring") {
+     def altring = basering;
+     def HNring = #[1]; setring HNring;
+     list Ergebnis = invariants(hne);
+     setring altring;
+     kill HNring;
+     return(Ergebnis);
+   }
+   if (typeof(#[1])=="list") {
+     list hne=#;
+     list Ergebnis;
+     for (int lauf=1;lauf<=size(hne);lauf++) {
+       Ergebnis[lauf]=invariants(hne[lauf]);
+     }
+     // Calculate the intersection matrix and the intersection multiplicities.
+     intmat contact[size(hne)][size(hne)];
+     intmat intersectionmatrix[size(hne)][size(hne)];
+     int Lauf;
+     for (lauf=1;lauf<=size(hne);lauf++) {
+       for (Lauf=lauf+1;Lauf<=size(hne);Lauf++) {
+         contact[lauf,Lauf]=separateHNE(hne[lauf],hne[Lauf]);
+         contact[Lauf,lauf]=contact[lauf,Lauf];
+         intersectionmatrix[lauf,Lauf]=intersection(hne[lauf],hne[Lauf]);
+         intersectionmatrix[Lauf,lauf]=intersectionmatrix[lauf,Lauf];
+       }
+     }
+     // Calculate the delta invariant.
+     int inters;
+     int del=Ergebnis[size(hne)][5] div 2;
+     for(lauf=1;lauf<=size(hne)-1;lauf++) {
+       del=del+Ergebnis[lauf][5] div 2;
+       for(Lauf=lauf+1;Lauf<=size(hne);Lauf++) {
+         inters=inters+intersectionmatrix[lauf,Lauf];
+       }
+     }
+     del=del+inters;
+     list LAST=contact,intersectionmatrix,del;
+     Ergebnis[size(hne)+1]=LAST;
+     return(Ergebnis);
+   }
+ }
+ //-------------------------- Initialisierungen -------------------------------
+ matrix m=#[1];
+ intvec v=#[2];
+ int switch=#[3];
+ list ergebnis;
+ if (switch==-1) {
+   "An error has occurred in develop, so there is no HNE.";
+   return(ergebnis);
+ }
+ intvec beta,s,svorl,ordnung,multseq,mpuiseux,npuiseux,halbgr;
+ int genus,zeile,i,j,k,summe,conductor,ggT;
+ string Ausgabe;
+ int nc=ncols(m); int nr=nrows(m);
+ ordnung[nr]=1;
+         // alle Indizes muessen (gegenueber [Ca]) um 1 erhoeht werden,
+         // weil 0..r nicht als Wertebereich erlaubt ist (aber nrows(m)==r+1)
+
+ //---------------- Bestimme den Untergrad der einzelnen Zeilen ---------------
+ for (zeile=nr; zeile>1; zeile--) {
+   if ((size(ideal(m[zeile,1..nc])) > 1) or (zeile==nr)) { // keine Nullzeile
+      k=1;
+      while (m[zeile,k]==0) {k++;}
+      ordnung[zeile-1]=k*ordnung[zeile]; // vgl. auch Def. von untergrad in
+      genus++;                           // proc param
+      svorl[genus]=zeile;} // werden gerade in umgekehrter Reihenfolge abgelegt
+   else {
+      ordnung[zeile-1]=v[zeile]*ordnung[zeile]+ordnung[zeile+1];
+ }}
+ //----------------- charakteristische Exponenten (beta) ----------------------
+ s[1]=1;
+ for (k=1; k <= genus; k++) { s[k+1]=svorl[genus-k+1];} // s[2]==s(1), u.s.w.
+ beta[1]=ordnung[1]; //charakt. Exponenten: Index wieder verschoben
+ for (k=1; k <= genus; k++) {
+   summe=0;
+   for (i=1; i <= s[k]; i++) {summe=summe+v[i]*ordnung[i];}
+   beta[k+1]=summe+ordnung[s[k]]+ordnung[s[k]+1]-ordnung[1];
+ }
+ //--------------------------- Puiseuxpaare -----------------------------------
+ int produkt=1;
+ for (i=1; i<=genus; i++) {
+   ggT=gcd(beta[1],beta[i+1]*produkt);
+   mpuiseux[i]=beta[i+1]*produkt div ggT;
+   npuiseux[i]=beta[1] div ggT;
+   produkt=produkt*npuiseux[i];
+ }
+ //---------------------- Grad des Konduktors ---------------------------------
+ summe=1-ordnung[1];
+ if (genus > 0) {
+   for (i=2; i <= genus+1; i++) {
+     summe=summe + beta[i] * (ordnung[s[i-1]] - ordnung[s[i]]);
+   }                              // n.b.: Indizierung wieder um 1 verschoben
+ }
+ conductor=summe;
+ //------------------- Erzeuger der Halbgruppe: -------------------------------
+ halbgr=puiseux2generators(mpuiseux,npuiseux);
+
+ //------------------- Multiplizitaetensequenz: -------------------------------
+ k=1;
+ for (i=1; i<size(v); i++) {
+   for (j=1; j<=v[i]; j++) {
+     multseq[k]=ordnung[i];
+     k++;
+ }}
+ multseq[k]=1;
+ //--- fuelle die Multipl.seq. mit den notwendigen Einsen auf -- T.Keilen ----
+ int tester=k;
+ while((multseq[tester]==1) and (tester>1))
+ {
+   tester=tester-1;
+ }
+ if ((multseq[tester]!=1) and (multseq[tester]!=k-tester))
+ {
+   for (i=k+1; i<=tester+multseq[tester]; i++)
+   {
+     multseq[i]=1;
+   }
+ }
+ //--- Ende T.Keilen --- 06.05.02
+ //------------------------- Rueckgabe ----------------------------------------
+ ergebnis=beta,halbgr,mpuiseux,npuiseux,conductor,multseq;
+ return(ergebnis);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+ ring exring=0,(x,y),dp;
+ list Hne=develop(y4+2x3y2+x6+x5y);
+ list INV=invariants(Hne);
+ INV[1];                   // the characteristic exponents
+ INV[2];                   // the generators of the semigroup of values
+ INV[3],INV[4];            // the Puiseux pairs in packed form
+ INV[5] div 2;             // the delta-invariant
+ INV[6];                   // the sequence of multiplicities
+                           // To display the invariants more 'nicely':
+ displayInvariants(Hne);
+ /////////////////////////////
+ INV=invariants((x2-y3)*(x3-y5));
+ INV[1][1];                // the characteristic exponents of the first branch
+ INV[2][6];                // the sequence of multiplicities of the second branch
+ print(INV[size(INV)][1]);         // the contact matrix of the branches
+ print(INV[size(INV)][2]);         // the intersection numbers of the branches
+ INV[size(INV)][3];                // the delta invariant of the curve
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc displayInvariants
+"USAGE:  displayInvariants(INPUT); INPUT list or poly
+ASSUME:  @code{INPUT} is a bivariate polynomial, or the output of
+         @code{develop(f)}, resp. of @code{extdevelop(develop(f),n)}, or (one
+         entry of) the list of HN data computed by
+         @code{hnexpansion(f[,\"ess\"])}.
+RETURN:  none
+DISPLAY: invariants of the corresponding branch, resp. of all branches,
+         in a better readable form.
+NOTE:    If the Hamburger-Noether expansion of the curve f is needed
+         for other purposes as well it is better to calculate this first
+         with the aid of @code{hnexpansion} and use it as input instead of
+         the polynomial itself.
+SEE ALSO: invariants, intersection, develop, hnexpansion
+EXAMPLE: example displayInvariants;  shows an example
+"
+{
+ // INPUT = polynomial or ring
+ if (typeof(#[1])=="poly") {
+   list L=hnexpansion(#[1]);
+   if (typeof(L[1])=="ring") {
+     def HNring = L[1]; setring HNring;
+     displayInvariants(hne);
+     return();
+   }
+   else {
+     displayInvariants(L);
+     return();
+   }
+ }
+ if (typeof(#[1])=="ring")
+ {
+   def HNring = #[1]; setring HNring;
+   displayInvariants(hne);
+   return();
+ }
+ // INPUT = hne of a plane curve
+ int i,j,k,mul;
+ string Ausgabe;
+ list ergebnis;
+ //-- entferne ueberfluessige Daten zur Erhoehung der Rechengeschwindigkeit: --
+ #=stripHNE(#);
+ //-------------------- Ausgabe eines Zweiges ---------------------------------
+ if (typeof(#[1])=="matrix") {
+   ergebnis=invariants(#);
+   if (size(ergebnis)!=0) {
+    " characteristic exponents  :",ergebnis[1];
+    " generators of semigroup   :",ergebnis[2];
+    if (size(ergebnis[1])>1) {
+     for (i=1; i<=size(ergebnis[3]); i++) {
+       Ausgabe=Ausgabe+"("+string(ergebnis[3][i])+","
+       +string(ergebnis[4][i])+")";
+    }}
+    " Puiseux pairs             :",Ausgabe;
+    " degree of the conductor   :",ergebnis[5];
+    " delta invariant           :",ergebnis[5] div 2;
+    " sequence of multiplicities:",ergebnis[6];
+ }}
+ //-------------------- Ausgabe aller Zweige ----------------------------------
+ else {
+  ergebnis=invariants(#);
+  intmat contact=ergebnis[size(#)+1][1];
+  intmat intersectionmatrix=ergebnis[size(#)+1][2];
+  for (j=1; j<=size(#); j++) {
+    " --- invariants of branch number",j,": ---";
+    " characteristic exponents  :",ergebnis[j][1];
+    " generators of semigroup   :",ergebnis[j][2];
+    Ausgabe="";
+    if (size(ergebnis[j][1])>1) {
+     for (i=1; i<=size(ergebnis[j][3]); i++) {
+       Ausgabe=Ausgabe+"("+string(ergebnis[j][3][i])+","
+       +string(ergebnis[j][4][i])+")";
+    }}
+    " Puiseux pairs             :",Ausgabe;
+    " degree of the conductor   :",ergebnis[j][5];
+    " delta invariant           :",ergebnis[j][5] div 2;
+    " sequence of multiplicities:",ergebnis[j][6];
+    "";
+  }
+  if (size(#)>1)
+  {
+    " -------------- contact numbers : -------------- ";"";
+    Ausgabe="branch |   ";
+    for (j=size(#); j>1; j--)
+    {
+      if (size(string(j))==1) { Ausgabe=Ausgabe+" "+string(j)+"    "; }
+      else                    { Ausgabe=Ausgabe+string(j)+"    "; }
+    }
+    Ausgabe;
+    Ausgabe="-------+";
+    for (j=2; j<size(#); j++) { Ausgabe=Ausgabe+"------"; }
+    Ausgabe=Ausgabe+"-----";
+    Ausgabe;
+  }
+  for (j=1; j<size(#); j++)
+  {
+    if (size(string(j))==1) { Ausgabe="    "+string(j)+"  |"; }
+    else                    { Ausgabe="   " +string(j)+"  |"; }
+    for (k=size(#); k>j; k--)
+    {
+      mul=contact[j,k];//separateHNE(#[j],#[k]);
+      for (i=1; i<=5-size(string(mul)); i++) { Ausgabe=Ausgabe+" "; }
+      Ausgabe=Ausgabe+string(mul);
+      if (k>j+1) { Ausgabe=Ausgabe+","; }
+    }
+    Ausgabe;
+  }
+  "";
+  if (size(#)>1)
+  {
+    " -------------- intersection multiplicities : -------------- ";"";
+    Ausgabe="branch |   ";
+    for (j=size(#); j>1; j--)
+    {
+      if (size(string(j))==1) { Ausgabe=Ausgabe+" "+string(j)+"    "; }
+      else                    { Ausgabe=Ausgabe+string(j)+"    "; }
+    }
+    Ausgabe;
+    Ausgabe="-------+";
+    for (j=2; j<size(#); j++) { Ausgabe=Ausgabe+"------"; }
+    Ausgabe=Ausgabe+"-----";
+    Ausgabe;
+  }
+  for (j=1; j<size(#); j++)
+  {
+    if (size(string(j))==1) { Ausgabe="    "+string(j)+"  |"; }
+    else                    { Ausgabe="   " +string(j)+"  |"; }
+    for (k=size(#); k>j; k--)
+    {
+      mul=intersectionmatrix[j,k];//intersection(#[j],#[k]);
+      for (i=1; i<=5-size(string(mul)); i++) { Ausgabe=Ausgabe+" "; }
+      Ausgabe=Ausgabe+string(mul);
+      if (k>j+1) { Ausgabe=Ausgabe+","; }
+    }
+    Ausgabe;
+  }
+  "";
+  " -------------- delta invariant of the curve : ",ergebnis[size(#)+1][3];
+
+ }
+ return();
+}
+example
+{ "EXAMPLE:"; echo = 2;
+ ring exring=0,(x,y),dp;
+ list Hne=develop(y4+2x3y2+x6+x5y);
+ displayInvariants(Hne);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc multiplicities
+"USAGE:   multiplicities(L); L list
+ASSUME:  L is the output of @code{develop(f)}, or of
+         @code{extdevelop(develop(f),n)}, or one entry in the list @code{hne}
+         in the ring created by @code{hnexpansion(f[,\"ess\"])}.
+RETURN:  intvec of the different multiplicities that occur when successively
+         blowing-up the curve singularity corresponding to f.
+SEE ALSO: multsequence, develop
+EXAMPLE: example multiplicities;  shows an example
+"
+{
+ matrix m=#[1];
+ intvec v=#[2];
+ int switch=#[3];
+ list ergebnis;
+ if (switch==-1) {
+   "An error has occurred in develop, so there is no HNE.";
+   return(intvec(0));
+ }
+ intvec ordnung;
+ int zeile,k;
+ int nc=ncols(m); int nr=nrows(m);
+ ordnung[nr]=1;
+ //---------------- Bestimme den Untergrad der einzelnen Zeilen ---------------
+ for (zeile=nr; zeile>1; zeile--) {
+   if ((size(ideal(m[zeile,1..nc])) > 1) or (zeile==nr)) { // keine Nullzeile
+      k=1;
+      while (m[zeile,k]==0) {k++;}
+      ordnung[zeile-1]=k*ordnung[zeile];
+   }
+   else {
+      ordnung[zeile-1]=v[zeile]*ordnung[zeile]+ordnung[zeile+1];
+ }}
+ return(ordnung);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  int p=printlevel; printlevel=-1;
+  ring r=0,(x,y),dp;
+  multiplicities(develop(x5+y7));
+  // The first value is the multiplicity of the curve itself, here it's 5
+  printlevel=p;
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc puiseux2generators (intvec m, intvec n)
+"USAGE:   puiseux2generators(m,n); m,n intvec
+ASSUME:  m, resp. n, represent the 1st, resp. 2nd, components of Puiseux pairs
+         (e.g., @code{m=invariants(L)[3]}, @code{n=invariants(L)[4]}).
+RETURN:  intvec of the generators of the semigroup of values.
+SEE ALSO: invariants
+EXAMPLE: example puiseux2generators;  shows an example
+"
+{
+ intvec beta;
+ int q=1;
+ //------------ glatte Kurve (eigentl. waeren m,n leer): ----------------------
+ if (m==0) { return(intvec(1)); }
+ //------------------- singulaere Kurve: --------------------------------------
+ for (int i=1; i<=size(n); i++) { q=q*n[i]; }
+ beta[1]=q; // == q_0
+ m=1,m; n=1,n; // m[1] ist damit m_0 usw., genau wie beta[1]==beta_0
+ for (i=2; i<=size(n); i++) {
+  beta[i]=m[i]*q div n[i] - m[i-1]*q + n[i-1]*beta[i-1];
+  q=q div n[i]; // == q_i
+ }
+ return(beta);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  // take (3,2),(7,2),(15,2),(31,2),(63,2),(127,2) as Puiseux pairs:
+  puiseux2generators(intvec(3,7,15,31,63,127),intvec(2,2,2,2,2,2));
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc intersection (list hn1, list hn2)
+"USAGE:   intersection(hne1,hne2); hne1, hne2 lists
+ASSUME: @code{hne1, hne2} represent an HN expansion of an irreducible plane
+        curve singularity (that is, are the output of @code{develop(f)}, or of
+        @code{extdevelop(develop(f),n)}, or one entry of the list of HN data
+        computed by @code{hnexpansion(f[,\"ess\"])}).
+RETURN:  int, the intersection multiplicity of the irreducible plane curve
+         singularities corresponding to @code{hne1} and @code{hne2}.
+SEE ALSO: hnexpansion, displayInvariants
+KEYWORDS: intersection multiplicity
+EXAMPLE: example intersection;  shows an example
+"
+{
+ //------------------ `intersect' ist schon reserviert ... --------------------
+ int i,j,s,sum,schnitt,unterschied;
+ matrix a1=hn1[1];
+ matrix a2=hn2[1];
+ intvec h1=hn1[2];
+ intvec h2=hn2[2];
+ intvec n1=multiplicities(hn1);
+ intvec n2=multiplicities(hn2);
+ if (hn1[3]!=hn2[3]) {
+ //-- die jeweils erste Zeile von hn1,hn2 gehoert zu verschiedenen Parametern -
+ //---------------- d.h. beide Kurven schneiden sich transversal --------------
+   schnitt=n1[1]*n2[1];        // = mult(hn1)*mult(hn2)
+ }
+ else {
+ //--------- die jeweils erste Zeile gehoert zum gleichen Parameter -----------
+   unterschied=0;
+   for (s=1; (h1[s]==h2[s]) && (s<size(h1)) && (s<size(h2))
+              && (unterschied==0); s++) {
+     for (i=1; (a1[s,i]==a2[s,i]) && (i<=h1[s]); i++) {;}
+     if (i<=h1[s]) {
+       unterschied=1;
+       s--;                    // um s++ am Schleifenende wieder auszugleichen
+     }
+   }
+   if (unterschied==0) {
+     if ((s<size(h1)) && (s<size(h2))) {
+       for (i=1; (a1[s,i]==a2[s,i]) && (i<=h1[s]) && (i<=h2[s]); i++) {;}
+     }
+     else {
+ //-------------- Sonderfall: Unterschied in letzter Zeile suchen -------------
+ // Beachte: Es koennen undefinierte Stellen auftreten, bei abbrechender HNE
+ // muss die Ende-Markierung weg, h_[r] ist unendlich, die Matrix muss mit
+ // Nullen fortgesetzt gedacht werden
+ //----------------------------------------------------------------------------
+       if (ncols(a1)>ncols(a2)) { j=ncols(a1); }
+       else                     { j=ncols(a2); }
+       unterschied=0;
+       if ((h1[s]>0) && (s==size(h1))) {
+         a1[s,h1[s]+1]=0;
+         if (ncols(a1)<=ncols(a2)) { unterschied=1; }
+       }
+       if ((h2[s]>0) && (s==size(h2))) {
+         a2[s,h2[s]+1]=0;
+         if (ncols(a2)<=ncols(a1)) { unterschied=1; }
+       }
+       if (unterschied==1) {                   // mind. eine HNE war endlich
+         matrix ma1[1][j]=a1[s,1..ncols(a1)];  // und bedarf der Fortsetzung
+         matrix ma2[1][j]=a2[s,1..ncols(a2)];  // mit Nullen
+       }
+       else {
+         if (ncols(a1)>ncols(a2)) { j=ncols(a2); }
+         else                     { j=ncols(a1); }
+         matrix ma1[1][j]=a1[s,1..j];          // Beschr. auf vergleichbaren
+         matrix ma2[1][j]=a2[s,1..j];          // Teil (der evtl. y's enth.)
+       }
+       for (i=1; (ma1[1,i]==ma2[1,i]) && (i<j) && (ma1[1,i]!=var(2)); i++) {;}
+       if (ma1[1,i]==ma2[1,i]) {
+         "//** The two HNE's are identical!";
+         "//** You have either tried to intersect a branch with itself,";
+         "//** or the two branches have been developed separately.";
+         "//   In the latter case use `extdevelop' to extend the HNE's until",
+         "they differ.";
+         return(-1);
+       }
+       if ((ma1[1,i]==var(2)) || (ma2[1,i]==var(2))) {
+         "//** The two HNE's are (so far) identical. This is because they",
+         "have been";
+         "//** computed separately. I need more data; use `extdevelop' to",
+         "extend them,";
+         if (ma1[1,i]==var(2)) {"//** at least the first one.";}
+         else                  {"//** at least the second one.";}
+         return(-1);
+       }
+     }
+   }
+   sum=0;
+   h1[size(h1)]=ncols(a1)+42;        // Ersatz fuer h1[r]=infinity
+   h2[size(h2)]=ncols(a2)+42;
+   for (j=1; j<s; j++) {sum=sum+h1[j]*n1[j]*n2[j];}
+   if ((i<=h1[s]) && (i<=h2[s]))    { schnitt=sum+i*n1[s]*n2[s]; }
+   if (i==h2[s]+1) { schnitt=sum+h2[s]*n1[s]*n2[s]+n2[s+1]*n1[s]; }
+   if (i==h1[s]+1) { schnitt=sum+h1[s]*n2[s]*n1[s]+n1[s+1]*n2[s]; }
+ // "s:",s-1,"i:",i,"S:",sum;
+ }
+ return(schnitt);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r=0,(x,y),dp;
+  list Hne=hnexpansion((x2-y3)*(x2+y3));
+  intersection(Hne[1],Hne[2]);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc multsequence
+"USAGE:   multsequence(INPUT); INPUT list or poly
+ASSUME:  @code{INPUT} is the output of @code{develop(f)}, or of
+         @code{extdevelop(develop(f),n)}, or one entry of the list of HN data
+         computed by @code{hnexpansion(f[,\"ess\"])}.
+RETURN:  intvec corresponding to the multiplicity sequence of the irreducible
+         plane curve singularity described by the HN data (return value
+         coincides with @code{invariants(INPUT)[6]}).
+
+ASSUME:  @code{INPUT} is a bivariate polynomial f, or the output of
+         @code{hnexpansion(f)}, or the list of HN data computed by
+         @code{hnexpansion(f [,\"ess\"])}.
+RETURN:  list of two integer matrices:
+ at texinfo
+ at table @asis
+ at item  @code{multsequence(INPUT)[1][i,*]}
+   contains the multiplicities of the branches at their infinitely near point
+   of 0 in its (i-1) order neighbourhood (i.e., i=1: multiplicity of the
+   branches themselves, i=2: multiplicity of their 1st quadratic transform,
+   etc., @*
+   Hence, @code{multsequence(INPUT)[1][*,j]} is the multiplicity sequence
+   of branch j.
+ at item  @code{multsequence(INPUT)[2][i,*]}:
+   contains the information which of these infinitely near points coincide.
+ at end table
+ at end texinfo
+NOTE:  The order of the elements of the list of HN data obtained from
+       @code{hnexpansion(f [,\"ess\"])} must not be changed (because otherwise
+       the coincident infinitely near points couldn't be grouped together,
+       see the meaning of the 2nd intmat in the example).
+       Hence, it is not wise to compute the HN expansion of polynomial factors
+       separately, put them into a list INPUT and call
+       @code{multsequence(INPUT)}. @*
+       Use @code{displayMultsequence} to produce a better readable output for
+       reducible curves on the screen. @*
+       In case the Hamburger-Noether expansion of the curve f is needed
+       for other purposes as well it is better to calculate this first
+       with the aid of @code{hnexpansion} and use it as input instead of
+       the polynomial itself.
+SEE ALSO: displayMultsequence, develop, hnexpansion, separateHNE
+KEYWORDS: multiplicity sequence
+EXAMPLE: example multsequence;  shows an example
+"
+{
+ //---- INPUT = poly, or HNEring --------------------
+ if (typeof(#[1])=="poly") {
+   list L=hnexpansion(#[1]);
+   if (typeof(L[1])=="ring") {
+     def altring = basering;
+     def HNring = L[1]; setring HNring;
+     list Ergebnis = multsequence(hne);
+     setring altring;
+     kill HNring;
+     return(Ergebnis);
+   }
+   else {
+     return(multsequence(L));
+   }
+ }
+ if (typeof(#[1])=="ring") {
+   def altring = basering;
+   def HNring = #[1]; setring HNring;
+   list Ergebnis = multsequence(hne);
+   setring altring;
+   kill HNring;
+   return(Ergebnis);
+ }
+ //-- entferne ueberfluessige Daten zur Erhoehung der Rechengeschwindigkeit: --
+ #=stripHNE(#);
+ int k,i,j;
+ //----------------- Multiplizitaetensequenz eines Zweiges --------------------
+ if (typeof(#[1])=="matrix") {
+  intvec v=#[2];
+  list ergebnis;
+  if (#[3]==-1) {
+    "An error has occurred in develop, so there is no HNE.";
+   return(intvec(0));
+  }
+  intvec multips,multseq;
+  multips=multiplicities(#);
+  k=1;
+  for (i=1; i<size(v); i++) {
+    for (j=1; j<=v[i]; j++) {
+      multseq[k]=multips[i];
+      k++;
+  }}
+  multseq[k]=1;
+  //--- fuelle die Multipl.seq. mit den notwendigen Einsen auf -- T.Keilen ----
+  int tester=k;
+  while((multseq[tester]==1) and (tester>1))
+  {
+    tester=tester-1;
+  }
+  if((multseq[tester]!=1) and (multseq[tester]!=k-tester))
+  {
+    for (i=k+1; i<=tester+multseq[tester]; i++)
+    {
+      multseq[i]=1;
+    }
+  }
+  //--- Ende T.Keilen --- 06.05.02
+  return(multseq);
+ }
+ //---------------------------- mehrere Zweige --------------------------------
+ else {
+   list HNEs=#;
+   int anzahl=size(HNEs);
+   int maxlength=0;
+   int bisher;
+   intvec schnitt,ones;
+   ones[anzahl]=0;
+   ones=ones+1;                  // = 1,1,...,1
+   for (i=1; i<anzahl; i++) {
+     schnitt[i]=separateHNE(HNEs[i],HNEs[i+1]);
+     j=size(multsequence(HNEs[i]));
+     maxlength=maxlength*(j < maxlength) + j*(j >= maxlength);
+     maxlength=maxlength*(schnitt[i]+1 < maxlength)
+               + (schnitt[i]+1)*(schnitt[i]+1 >= maxlength);
+   }
+   j=size(multsequence(HNEs[anzahl]));
+   maxlength=maxlength*(j < maxlength) + j*(j >= maxlength);
+
+//-------------- Konstruktion der ersten zu berechnenden Matrix ---------------
+   intmat allmults[maxlength][anzahl];
+   for (i=1; i<=maxlength; i++)  { allmults[i,1..anzahl]=ones[1..anzahl]; }
+   for (i=1; i<=anzahl; i++) {
+     ones=multsequence(HNEs[i]);
+     allmults[1..size(ones),i]=ones[1..size(ones)];
+   }
+//---------------------- Konstruktion der zweiten Matrix ----------------------
+   intmat separate[maxlength][anzahl];
+   for (i=1; i<=maxlength; i++) {
+     k=1;
+     bisher=0;
+     if (anzahl==1) { separate[i,1]=1; }
+     for (j=1; j<anzahl; j++)   {
+       if (schnitt[j]<i) {
+         separate[i,k]=j-bisher;
+         bisher=j;
+         k++;
+       }
+       separate[i,k]=anzahl-bisher;
+     }
+   }
+  return(list(allmults,separate));
+ }
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r=0,(x,y),dp;
+  list Hne=hnexpansion((x6-y10)*(x+y2-y3)*(x+y2+y3));
+  multsequence(Hne[1]),"  |  ",multsequence(Hne[2]),"  |  ",
+  multsequence(Hne[3]),"  |  ",multsequence(Hne[4]);
+  multsequence(Hne);
+  // The meaning of the entries of the 2nd matrix is as follows:
+  displayMultsequence(Hne);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc displayMultsequence
+"USAGE:   displayMultsequence(INPUT); INPUT list or poly
+ASSUME:  @code{INPUT} is a bivariate polynomial, or the output of
+         @code{develop(f)}, resp. of @code{extdevelop(develop(f),n)}, or (one
+         entry of) the list of HN data computed by @code{hnexpansion(f[,\"ess\"])},
+         or the output of @code{hnexpansion(f)}.
+RETURN:  nothing
+DISPLAY: the sequence of multiplicities:
+ at format
+ - if @code{INPUT=develop(f)} or @code{INPUT=extdevelop(develop(f),n)} or @code{INPUT=hne[i]}:
+                      @code{a , b , c , ....... , 1}
+ - if @code{INPUT=f} or @code{INPUT=hnexpansion(f)} or @code{INPUT=hne}:
+                      @code{[(a_1, .... , b_1 , .... , c_1)],}
+                      @code{[(a_2, ... ), ... , (... , c_2)],}
+                      @code{ ........................................ ,}
+                      @code{[(a_n),(b_n), ....., (c_n)]}
+     with:
+       @code{a_1 , ... , a_n} the sequence of multiplicities of the 1st branch,
+       @code{[...]} the multiplicities of the j-th transform of all branches,
+       @code{(...)} indicating branches meeting in an infinitely near point.
+ at end format
+NOTE:  The Same restrictions as in @code{multsequence} apply for the input.@*
+       In case the Hamburger-Noether expansion of the curve f is needed
+       for other purposes as well it is better to calculate this first
+       with the aid of @code{hnexpansion} and use it as input instead of
+       the polynomial itself.
+SEE ALSO: multsequence, develop, hnexpansion, separateHNE
+EXAMPLE: example displayMultsequence;  shows an example
+"
+{
+ //---- INPUT = poly, or HNEring --------------------
+ if (typeof(#[1])=="poly") {
+   list L=hnexpansion(#[1]);
+   if (typeof(L[1])=="ring") {
+     def HNring = L[1]; setring HNring;
+     displayMultsequence(hne);
+     return();
+   }
+   else {
+     displayMultsequence(L);
+     return();
+   }
+ }
+ if (typeof(#[1])=="ring") {
+   def HNring = #[1]; setring HNring;
+   displayMultsequence(hne);
+   return();
+ }
+
+ //-- entferne ueberfluessige Daten zur Erhoehung der Rechengeschwindigkeit: --
+ #=stripHNE(#);
+ //----------------- Multiplizitaetensequenz eines Zweiges --------------------
+ if (typeof(#[1])=="matrix") {
+   if (#[3]==-1) {
+     "An error has occurred in develop, so there is no HNE.";
+   }
+   else {
+     "The sequence of multiplicities is  ",multsequence(#);
+ }}
+ //---------------------------- mehrere Zweige --------------------------------
+ else {
+   list multips=multsequence(#);
+   int i,j,k,l;
+   string output;
+   for (i=1; i<=nrows(multips[1]); i++) {
+     output="[";
+     k=1;
+     for (l=1; k<=ncols(multips[1]); l++) {
+       output=output+"(";
+       for (j=1; j<=multips[2][i,l]; j++) {
+         output=output+string(multips[1][i,k]);
+         k++;
+         if (j<multips[2][i,l]) { output=output+","; }
+       }
+       output=output+")";
+       if ((k-1) < ncols(multips[1])) { output=output+","; }
+      }
+     output=output+"]";
+     if (i<nrows(multips[1])) { output=output+","; }
+     output;
+   }
+ }
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r=0,(x,y),dp;
+  // Example 1: Input = output of develop
+  displayMultsequence(develop(x3-y5));
+
+  // Example 2: Input = bivariate polynomial
+  displayMultsequence((x6-y10)*(x+y2-y3)*(x+y2+y3));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc separateHNE (list hn1,list hn2)
+"USAGE:    separateHNE(hne1,hne2);  hne1, hne2 lists
+ASSUME:   hne1, hne2 are HNEs (=output of
+          @code{develop(f)}, @code{extdevelop(develop(f),n)}, or
+          one entry in the list @code{hne} in the ring created by
+          @code{hnexpansion(f[,\"ess\"])}.
+RETURN:   number of quadratic transformations needed to separate both curves
+          (branches).
+SEE ALSO: develop, hnexpansion, multsequence, displayMultsequence
+EXAMPLE:  example separateHNE;  shows an example
+"
+{
+ int i,j,s,unterschied,separated;
+ matrix a1=hn1[1];
+ matrix a2=hn2[1];
+ intvec h1=hn1[2];
+ intvec h2=hn2[2];
+ if (hn1[3]!=hn2[3]) {
+ //-- die jeweils erste Zeile von hn1,hn2 gehoert zu verschiedenen Parametern -
+ //---------------- d.h. beide Kurven schneiden sich transversal --------------
+   separated=1;
+ }
+ else {
+ //--------- die jeweils erste Zeile gehoert zum gleichen Parameter -----------
+   unterschied=0;
+   for (s=1; (h1[s]==h2[s]) && (s<size(h1)) && (s<size(h2))
+              && (unterschied==0); s++) {
+     for (i=1; (a1[s,i]==a2[s,i]) && (i<=h1[s]); i++) {;}
+     if (i<=h1[s]) {
+       unterschied=1;
+       s--;                    // um s++ am Schleifenende wieder auszugleichen
+     }
+   }
+   if (unterschied==0) {
+     if ((s<size(h1)) && (s<size(h2))) {
+       for (i=1; (a1[s,i]==a2[s,i]) && (i<=h1[s]) && (i<=h2[s]); i++) {;}
+     }
+     else {
+ //-------------- Sonderfall: Unterschied in letzter Zeile suchen -------------
+ // Beachte: Es koennen undefinierte Stellen auftreten, bei abbrechender HNE
+ // muss die Ende-Markierung weg, h_[r] ist unendlich, die Matrix muss mit
+ // Nullen fortgesetzt gedacht werden
+ //----------------------------------------------------------------------------
+       if (ncols(a1)>ncols(a2)) { j=ncols(a1); }
+       else                     { j=ncols(a2); }
+       unterschied=0;
+       if ((h1[s]>0) && (s==size(h1))) {
+         a1[s,h1[s]+1]=0;
+         if (ncols(a1)<=ncols(a2)) { unterschied=1; }
+       }
+       if ((h2[s]>0) && (s==size(h2))) {
+         a2[s,h2[s]+1]=0;
+         if (ncols(a2)<=ncols(a1)) { unterschied=1; }
+       }
+       if (unterschied==1) {                   // mind. eine HNE war endlich
+         matrix ma1[1][j]=a1[s,1..ncols(a1)];  // und bedarf der Fortsetzung
+         matrix ma2[1][j]=a2[s,1..ncols(a2)];  // mit Nullen
+       }
+       else {
+         if (ncols(a1)>ncols(a2)) { j=ncols(a2); }
+         else                     { j=ncols(a1); }
+         matrix ma1[1][j]=a1[s,1..j];          // Beschr. auf vergleichbaren
+         matrix ma2[1][j]=a2[s,1..j];          // Teil (der evtl. y's enth.)
+       }
+       for (i=1; (ma1[1,i]==ma2[1,i]) && (i<j) && (ma1[1,i]!=var(2)); i++) {;}
+       if (ma1[1,i]==ma2[1,i]) {
+         "//** The two HNE's are identical!";
+         "//** You have either tried to compare a branch with itself,";
+         "//** or the two branches have been developed separately.";
+         "//   In the latter case use `extdevelop' to extend the HNE's until",
+         "they differ.";
+         return(-1);
+       }
+       if ((ma1[1,i]==var(2)) || (ma2[1,i]==var(2))) {
+         "//** The two HNE's are (so far) identical. This is because they",
+         "have been";
+         "//** computed separately. I need more data; use `extdevelop' to",
+         "extend them,";
+         if (ma1[1,i]==var(2)) {"//** at least the first one.";}
+         else                  {"//** at least the second one.";}
+         return(-1);
+       }
+     }
+   }
+   separated=i;
+   for (j=1; j<s; j++) { separated=separated+h1[j]; }
+ }
+ return(separated);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  int p=printlevel; printlevel=-1;
+  ring r=0,(x,y),dp;
+  list hne1=develop(x);
+  list hne2=develop(x+y);
+  list hne3=develop(x+y2);
+  separateHNE(hne1,hne2);  // two transversal lines
+  separateHNE(hne1,hne3);  // one quadratic transform. gives 1st example
+  printlevel=p;
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc displayHNE(list ldev,list #)
+"USAGE:   displayHNE(L[,n]); L list, n int
+ASSUME:  L is the output of @code{develop(f)}, or of @code{exdevelop(f,n)},
+         or of @code{hnexpansion(f[,\"ess\"])}, or (one entry in) the list
+         @code{hne} in the ring created by @code{hnexpansion(f[,\"ess\"])}.
+RETURN:  - if only one argument is given and if the input are the HN data
+         of an irreducible plane curve singularity, no return value, but
+         display an ideal HNE of the following form:
+     @example
+       y = []*x^1+[]*x^2   +...+x^<>*z(1)
+       x =        []*z(1)^2+...+z(1)^<>*z(2)
+       z(1) =     []*z(2)^2+...+z(2)^<>*z(3)
+       .......             ..........................
+       z(r-1) =   []*z(r)^2+[]*z(r)^3+......
+     @end example
+        where @code{x}, at code{y} are the first 2 variables of the basering.
+        The values of @code{[]} are the coefficients of the Hamburger-Noether
+        matrix, the values of @code{<>} are represented by @code{x} in the
+        HN matrix.@*
+        - if a second argument is given and if the input are the HN data
+        of an irreducible plane curve singularity, return a ring containing
+        an ideal @code{HNE} as described above.@*
+        - if L corresponds to the output of @code{hnexpansion(f)}
+        or to the list of HN data computed by @code{hnexpansion(f[,\"ess\"])},
+        @code{displayHNE(L[,n])} shows the HNE's of all branches of f in the
+        format described above. The optional parameter is then ignored.
+NOTE:  The 1st line of the above ideal (i.e., @code{HNE[1]}) means that
+     @code{y=[]*z(0)^1+...}, the 2nd line (@code{HNE[2]}) means that
+     @code{x=[]*z(1)^2+...}, so you can see which indeterminate
+     corresponds to which line (it's also possible that @code{x} corresponds
+     to the 1st line and @code{y} to the 2nd).
+
+SEE ALSO: develop, hnexpansion
+EXAMPLE: example displayHNE; shows an example
+"
+{
+ if ((typeof(ldev[1])=="list") || (typeof(ldev[1])=="none")) {
+   for (int i=1; i<=size(ldev); i++) {
+     "// Hamburger-Noether development of branch nr."+string(i)+":";
+     displayHNE(ldev[i]);"";
+   }
+   return();
+ }
+ //--------------------- Initialisierungen und Ringwechsel --------------------
+ matrix m=ldev[1];
+ intvec v=ldev[2];
+ int switch=ldev[3];
+ if (switch==-1) {
+   "An error has occurred throughout the expansion, so there is no HNE.";
+   return(ideal(0));
+ }
+ def altring=basering;
+ /////////////////////////////////////////////////////////
+ //  Change by T. Keilen 08.06.2002
+ //  ring + ring does not work if one ring is an algebraic extension
+/*
+ if (parstr(basering)!="") {
+   if (charstr(basering)!=string(char(basering))+","+parstr(basering)) {
+     execute
+      ("ring dazu=("+charstr(basering)+"),z(0.."+string(size(v)-1)+"),ls;");
+   }
+   else { ring dazu=char(altring),z(0..size(v)-1),ls; }
+ }
+ else   { ring dazu=char(altring),z(0..size(v)-1),ls; }
+ def displayring=dazu+altring;
+*/
+ execute("ring displayring=("+charstr(basering)+"),(z(0.."+string(size(v)-1)+"),"+varstr(basering)+"),(ls("+string(size(v))+"),"+ordstr(basering)+");");
+ // End change by T. Keilen
+ //////////////////////////////////////////////////////////////
+ setring displayring;
+ map holematrix=altring,0;        // mappt nur die Monome vom Grad Null
+ matrix m=holematrix(m);
+ int i,j;
+
+ // lossen: check the last row for finiteness (06/2004)
+ int rowM=nrows(m);
+ int colM=ncols(m);
+ int undef_bd=v[size(v)];
+ if ( undef_bd<-1 ){
+   for (j=-undef_bd; j<=colM; j++) { m[rowM,j]=0; }
+ }
+
+ //--------------------- Erzeuge Matrix n mit n[i,j]=z(j-1)^i -----------------
+ matrix n[colM][rowM];
+ for (j=1; j<=rowM; j++) {
+    for (i=1; i<=colM; i++) { n[i,j]=z(j-1)^i; }
+ }
+ matrix displaymat=m*n;
+ ideal HNE;
+ for (i=1; i<rowM; i++) { HNE[i]=displaymat[i,i]+z(i)*z(i-1)^v[i]; }
+ HNE[rowM]=displaymat[rowM,rowM];
+
+ // lossen: output modified (06/2004)
+ if (size(#) == 0)
+ {
+   if (switch==0) {
+     HNE=subst(HNE,z(0),var(size(v)+1));
+   }
+   else  {
+     HNE=subst(HNE,z(0),var(size(v)+2));
+   }
+
+   for (j=1; j<=ncols(HNE); j++){
+     string stHNE(j)=string(HNE[j]);
+   }
+   if (undef_bd<-1)
+   {
+     stHNE(size(v))=stHNE(size(v))+" + ..... (terms of degree >="
+                                 +string(-undef_bd)+")";
+   }
+   if (undef_bd==-1)
+   {
+     stHNE(size(v))=stHNE(size(v))+" + ..... (terms of degree >="
+                                 +string(colM+1)+")";
+   }
+
+   if (switch==0) {
+     stHNE(1) = "  "+string(var(size(v)+2))+" = "+stHNE(1);
+   }
+   else {
+     stHNE(1) = "  "+string(var(size(v)+1))+" = "+stHNE(1);
+   }
+   stHNE(1);
+   if (ncols(HNE)==1) {return();}
+
+   if (switch==0) {
+     stHNE(2) = "  "+string(var(size(v)+1))+" = "+stHNE(2);
+   }
+   else {
+     stHNE(2) = "  "+string(var(size(v)+2))+" = "+stHNE(2);
+   }
+   stHNE(2);
+
+   for (j=3; j<=ncols(HNE); j++){
+     stHNE(j)= "  "+"z(" +string(j-2)+ ") = "+stHNE(j);
+     stHNE(j);
+   }
+   return();
+ }
+
+ if (rowM<2) { HNE[2]=z(0); }
+
+ if (switch==0) {
+    HNE[1] = HNE[1]-var(size(v)+2);
+    HNE[2] = HNE[2]-var(size(v)+1);
+ }
+ else {
+    HNE[1] = HNE[1]-var(size(v)+1);
+    HNE[2] = HNE[2]-var(size(v)+2);
+ }
+if (size(#) == 0) {
+   HNE;
+   return();
+ }
+if (size(#) != 0) {
+   HNE;
+   export(HNE);
+   return(displayring);
+ }
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring r=0,(x,y),dp;
+  poly f=x3+2xy2+y2;
+  list hn=develop(f);
+  displayHNE(hn);
+}
+///////////////////////////////////////////////////////////////////////////////
+//                      procedures for reducible curves                      //
+///////////////////////////////////////////////////////////////////////////////
+
+// proc newtonhoehne (poly f)
+// USAGE:   newtonhoehne(f);   f poly
+// ASSUME:  basering = ...,(x,y),ds  or ls
+// RETURN:  list of intvec(x,y) of coordinates of the newtonpolygon of f
+// NOTE:    This proc is only available in versions of Singular that know the
+//         command  system("newton",f);  f poly
+// {
+// intvec nm = getnm(f);
+//  if ((nm[1]>0) && (nm[2]>0)) { f=jet(f,nm[1]*nm[2],nm); }
+//  list erg=system("newton",f);
+//  int i; list Ausgabe;
+//  for (i=1; i<=size(erg); i++) { Ausgabe[i]=leadexp(erg[i]); }
+// return(Ausgabe);
+// }
+///////////////////////////////////////////////////////////////////////////////
+
+proc newtonpoly (poly f, int #)
+"USAGE:   newtonpoly(f);   f poly
+ASSUME:  basering has exactly two variables; @*
+         f is convenient, that is, f(x,0) != 0 != f(0,y).
+RETURN:  list of intvecs (= coordinates x,y of the Newton polygon of f).
+NOTE:    Procedure uses @code{execute}; this can be avoided by calling
+         @code{newtonpoly(f,1)} if the ordering of the basering is @code{ls}.
+KEYWORDS: Newton polygon
+EXAMPLE: example newtonpoly;  shows an example
+"
+{
+  if (size(#)>=1)
+  {
+    if (typeof(#[1])=="int")
+    {
+      // this is done to avoid the "execute" command for procedures in
+      //  hnoether.lib
+      def is_ls=#[1];
+    }
+  }
+  if (defined(is_ls)<=0)
+  {
+    def @Rold=basering;
+    execute("ring @RR=("+charstr(basering)+"),("+varstr(basering)+"),ls;");
+    poly f=imap(@Rold,f);
+  }
+  intvec A=(0,ord(subst(f,var(1),0)));
+  intvec B=(ord(subst(f,var(2),0)),0);
+  intvec C,H; list L;
+  int abbruch,i;
+  poly hilf;
+  L[1]=A;
+  f=jet(f,A[2]*B[1]-1,intvec(A[2],B[1]));
+  if (defined(is_ls))
+  {
+    map xytausch=basering,var(2),var(1);
+  }
+  else
+  {
+    map xytausch=@RR,var(2),var(1);
+  }
+  for (i=2; f!=0; i++)
+  {
+     abbruch=0;
+     while (abbruch==0)
+     {
+        C=leadexp(f);
+        if(jet(f,A[2]*C[1]-A[1]*C[2]-1,intvec(A[2]-C[2],C[1]-A[1]))==0)
+        {
+           abbruch=1;
+        }
+        else
+        {
+           f=jet(f,-C[1]-1,intvec(-1,0));
+        }
+    }
+    hilf=jet(f,A[2]*C[1]-A[1]*C[2],intvec(A[2]-C[2],C[1]-A[1]));
+    H=leadexp(xytausch(hilf));
+    A=H[2],H[1];
+    L[i]=A;
+    f=jet(f,A[2]*B[1]-1,intvec(A[2],B[1]-A[1]));
+  }
+  L[i]=B;
+  if (defined(is_ls))
+  {
+    return(L);
+  }
+  else
+  {
+    setring @Rold;
+    return(L);
+  }
+}
+example
+{
+ "EXAMPLE:"; echo = 2;
+  ring r=0,(x,y),ls;
+  poly f=x5+2x3y-x2y2+3xy5+y6-y7;
+  newtonpoly(f);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc is_NND (poly f, list #)
+"USAGE:   is_NND(f[,mu,NP]);   f poly, mu int, NP list of intvecs
+ASSUME:  f is convenient, that is, f(x,0) != 0 != f(0,y);@*
+         mu (optional) is Milnor number of f.@*
+         NP (optional) is output of @code{newtonpoly(f)}.
+RETURN:  int: 1 if f is Newton non-degenerate, 0 otherwise.
+SEE ALSO: newtonpoly
+KEYWORDS: Newton non-degenerate; Newton polygon
+EXAMPLE: example is_NND;  shows examples
+"
+{
+  int i;
+  int i_print=printlevel-voice+2;
+
+  if (size(#)==0)
+  {
+    int mu=milnor(f);
+    list NP=newtonpoly(f);
+  }
+  else
+  {
+    if (typeof(#[1])=="int")
+    {
+      def mu=#[1];
+      def NP=#[2];
+      for (i=1;i<=size(NP);i++)
+      {
+        if (typeof(NP[i])!="intvec")
+        {
+          print("third input cannot be Newton polygon ==> ignored ")
+          NP=newtonpoly(f);
+          i=size(NP)+1;
+        }
+      }
+    }
+    else
+    {
+      print("second input cannot be Milnor number ==> ignored ")
+      int mu=milnor(f);
+      NP=newtonpoly(f);
+    }
+  }
+
+  // computation of the Newton number:
+  int s=size(NP);
+  int nN=-NP[1][2]-NP[s][1]+1;
+  intmat m[2][2];
+  for(i=1;i<=s-1;i++)
+  {
+    m=NP[i+1],NP[i];
+    nN=nN+det(m);
+  }
+
+  if(mu==nN)
+  { // the Newton-polygon is non-degenerate
+    // REFERENCE? (tfuer mehr als 2 Variable gilt nicht, dass mu=nu impliziert,
+    // dass NP nicht ausgeartet ist!, Siehe KOMMENTAR in equising.lib in esIdeal)
+    return(1);
+  }
+  else
+  {
+    return(0);
+  }
+}
+example
+{
+ "EXAMPLE:"; echo = 2;
+  ring r=0,(x,y),ls;
+  poly f=x5+y3;
+  is_NND(f);
+  poly g=(x-y)^5+3xy5+y6-y7;
+  is_NND(g);
+
+  // if already computed, one should give the Minor number and Newton polygon
+  // as second and third input:
+  int mu=milnor(g);
+  list NP=newtonpoly(g);
+  is_NND(g,mu,NP);
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc charPoly(poly f, int M, int N)
+"USAGE:  charPoly(f,M,N);  f bivariate poly,  M,N int: length and height
+                          of Newton polygon of f, which has to be only one line
+RETURN:  the characteristic polynomial of f
+EXAMPLE: example charPoly;  shows an example
+"
+{
+ poly charp;
+ int Np=N div gcd(M,N);
+ f=subst(f,var(1),1);
+ for(charp=0; f<>0; f=f-lead(f))
+  { charp=charp+leadcoef(f)*var(2)^(leadexp(f)[2] div Np);}
+ return(charp);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring exring=0,(x,y),dp;
+  charPoly(y4+2y3x2-yx6+x8,8,4);
+  charPoly(y6+3y3x2-x4,4,6);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc find_in_list(list L,int p)
+"USAGE:   find_in_list(L,p); L: list of intvec(x,y)
+         (sorted in y: L[1][2]>=L[2][2]), int p >= 0
+RETURN:  int i: L[i][2]=p if existent; otherwise i with L[i][2]<p if existent;
+         otherwise i = size(L)+1;
+EXAMPLE: example find_in_list;  shows an example
+"
+{
+ int i;
+ L[size(L)+1]=intvec(0,-1);          // falls p nicht in L[.][2] vorkommt
+ for (i=1; L[i][2]>p; i++) {;}
+ return(i);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  list L = intvec(0,4), intvec(1,2), intvec(2,1), intvec(4,0);
+  find_in_list(L,1);
+  L[find_in_list(L,2)];
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc get_last_divisor(int M, int N)
+"USAGE:   get_last_divisor(M,N); int M,N
+RETURN:  int Q: M=q1*N+r1, N=q2*r1+r2, ..., ri=Q*r(i+1) (Euclidean alg.)
+EXAMPLE: example get_last_divisor; shows an example
+"
+{
+ int R=M%N; int Q=M div N;
+ while (R!=0) {M=N; N=R; R=M%N; Q=M div N;}
+ return(Q)
+}
+example
+{ "EXAMPLE"; echo = 2;
+  ring r=0,(x,y),dp;
+  get_last_divisor(12,10);
+}
+///////////////////////////////////////////////////////////////////////////////
+proc redleit (poly f,intvec S, intvec E)
+"USAGE:   redleit(f,S,E);  f poly, S,E intvec(x,y)
+         S,E are two different points on a line in the Newton diagram of f
+RETURN:  poly g: all monomials of f which lie on or below that line
+NOTE:    The main purpose is that if the line defined by S and E is part of the
+         Newton polygon, the result is the quasihomogeneous leading form of f
+         w.r.t. that line.
+SEE ALSO: newtonpoly
+EXAMPLE: example redleit;  shows an example
+"
+{
+ if (E[1]<S[1]) { intvec H=E; E=S; S=H; } // S,E verkehrt herum eingegeben
+ return(jet(f,E[1]*S[2]-E[2]*S[1],intvec(S[2]-E[2],E[1]-S[1])));
+}
+example
+{ "EXAMPLE"; echo = 2;
+  ring exring=0,(x,y),dp;
+  redleit(y6+xy4-2x3y2+x4y+x6,intvec(3,2),intvec(4,1));
+}
+///////////////////////////////////////////////////////////////////////////////
+
+
+proc extdevelop (list l, int Exaktheit)
+"USAGE:   extdevelop(L,N); list L, int N
+ASSUME:  L is the output of @code{develop(f)}, or of @code{extdevelop(l,n)},
+         or one entry in the list @code{hne} in the ring created by
+          @code{hnexpansion(f[,\"ess\"])}.
+RETURN:  an extension of the Hamburger-Noether development of f as a list
+         in the same format as L has (up to the last entry in the output
+         of @code{develop(f)}).@*
+         Type @code{help develop;}, resp. @code{help hnexpansion;} for more
+         details.
+NOTE:    The new HN-matrix will have at least N columns (if the HNE is not
+         finite). In particular, if f is irreducible then (in most cases)
+         @code{extdevelop(develop(f),N)} will produce the same result as
+         @code{develop(f,N)}.@*
+         If the matrix M of L has n columns then, compared with
+         @code{parametrization(L)}, @code{paramametrize(extdevelop(L,N))} will increase the
+         exactness by at least (N-n) more significant monomials.
+SEE ALSO: develop, hnexpansion, param
+EXAMPLE: example extdevelop;  shows an example
+"
+{
+ //------------ Initialisierungen und Abfangen unzulaessiger Aufrufe ----------
+ matrix m=l[1];
+ intvec v=l[2];
+ int switch=l[3];
+ if (nvars(basering) < 2) {
+   " Sorry. I need two variables in the ring.";
+   return(list(matrix(maxideal(1)[1]),intvec(0),-1,poly(0)));}
+ if (switch==-1) {
+   "An error has occurred in develop, so there is no HNE and no extension.";
+   return(l);
+ }
+ poly f=l[4];
+ if (f==0) {
+   " No extension is possible";
+   return(l);
+ }
+ int Q=v[size(v)];
+ if (Q>0) {
+   " The HNE was already exact";
+   return(l);
+ }
+ else {
+   if (Q==-1) { Q=ncols(m); }
+   else { Q=-Q-1; }
+ }
+ int zeile=nrows(m);
+ int spalten,i,M;
+ ideal lastrow=m[zeile,1..Q];
+ int ringwechsel=(varstr(basering)!="x,y") or (ordstr(basering)!="ls(2),C");
+
+ //------------------------- Ringwechsel, falls noetig ------------------------
+ if (ringwechsel) {
+  def altring = basering;
+  int p = char(basering);
+  if (charstr(basering)!=string(p)) {
+     string tststr=charstr(basering);
+     tststr=tststr[1..find(tststr,",")-1];     //-> "p^k" bzw. "p"
+     if (tststr==string(p)) {
+       if (size(parstr(basering))>1) {         // ring (p,a,..),...
+        execute("ring extdguenstig=("+charstr(basering)+"),(x,y),ls;");
+       }
+       else {                                  // ring (p,a),...
+        string mipl=string(minpoly);
+        ring extdguenstig=(p,`parstr(basering)`),(x,y),ls;
+        if (mipl!="0") { execute("minpoly="+mipl+";"); }
+       }
+     }
+     else {
+       execute("ring extdguenstig=("+charstr(basering)+"),(x,y),ls;");
+     }
+  }
+  else {                               // charstr(basering)== p : no parameter
+     ring extdguenstig=p,(x,y),ls;
+  }
+  export extdguenstig;
+  map hole=altring,x,y;
+ //----- map kann sehr zeitaufwendig sein, daher Vermeidung, wo moeglich: -----
+  if (nvars(altring)==2) { poly f=fetch(altring,f); }
+  else                   { poly f=hole(f);          }
+  ideal a=hole(lastrow);
+ }
+ else { ideal a=lastrow; }
+ list Newton=newtonpoly(f,1);
+ int M1=Newton[size(Newton)-1][1];     // konstant
+ number delt;
+ if (Newton[size(Newton)-1][2]!=1) {
+    " *** The transformed polynomial was not valid!!";}
+ else {
+ //--------------------- Fortsetzung der HNE ----------------------------------
+  while (Q<Exaktheit) {
+    M=ord(subst(f,y,0));
+    Q=M-M1;
+ //------ quasihomogene Leitform ist c*x^M1*y+d*x^(M1+Q) => delta=-d/c: -------
+    delt=-koeff(f,M,0)/koeff(f,M1,1);
+    a[Q]=delt;
+    dbprint(printlevel-voice+2,"a("+string(zeile-1)+","+string(Q)+") = "+string(delt));
+    if (Q<Exaktheit) {
+     f=T1_Transform(f,delt,Q);
+     if (defined(HNDebugOn)) { "transformed polynomial:",f; }
+     if (subst(f,y,0)==0) {
+       dbprint(printlevel-voice+2,"The HNE is finite!");
+       a[Q+1]=x; Exaktheit=Q;
+       f=0;                        // Speicherersparnis: f nicht mehr gebraucht
+     }
+    }
+  }
+ }
+ //------- Wechsel in alten Ring, Zusammensetzung alte HNE + Erweiterung ------
+ if (ringwechsel) {
+  setring altring;
+  map zurueck=extdguenstig,var(1),var(2);
+  if (nvars(altring)==2) { f=fetch(extdguenstig,f); }
+  else                   { f=zurueck(f);            }
+  lastrow=zurueck(a);
+ }
+ else { lastrow=a; }
+ if (ncols(lastrow)>ncols(m)) { spalten=ncols(lastrow); }
+ else { spalten=ncols(m); }
+ matrix mneu[zeile][spalten];
+ for (i=1; i<nrows(m); i++) {
+  mneu[i,1..ncols(m)]=m[i,1..ncols(m)];
+ }
+ mneu[zeile,1..ncols(lastrow)]=lastrow;
+ if (lastrow[ncols(lastrow)]!=var(1)) {
+  if (ncols(lastrow)==spalten) { v[zeile]=-1; }  // keine undefinierten Stellen
+  else {
+   v[zeile]=-Q-1;
+   for (i=ncols(lastrow)+1; i<=spalten; i++) {
+    mneu[zeile,i]=var(2);           // fuelle nicht def. Stellen der Matrix auf
+ }}}
+ else { v[zeile]=Q; }               // HNE war exakt
+ if (ringwechsel)
+ {
+   kill extdguenstig;
+ }
+
+ return(list(mneu,v,switch,f));
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring exring=0,(x,y),dp;
+  list Hne=hnexpansion(x14-3y2x11-y3x10-y2x9+3y4x8+y5x7+3y4x6+x5*(-y6+y5)
+                      -3y6x3-y7x2+y8);
+  displayHNE(Hne);    // HNE of 1st,3rd branch is finite
+  print(extdevelop(Hne[1],5)[1]);
+  list ehne=extdevelop(Hne[2],5);
+  displayHNE(ehne);
+  param(Hne[2]);
+  param(ehne);
+
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc stripHNE (list l)
+"USAGE:   stripHNE(L);  L list
+ASSUME:  L is the output of @code{develop(f)}, or of
+         @code{extdevelop(develop(f),n)}, or (one entry of) the list
+         @code{hne} in the ring created by @code{hnexpansion(f[,\"ess\"])}.
+RETURN:  list in the same format as L, but all polynomials L[4], resp.
+         L[i][4], are set to zero.
+NOTE:    The purpose of this procedure is to remove huge amounts of data
+         no longer needed. It is useful, if one or more of the polynomials
+         in L consume much memory. It is still possible to compute invariants,
+         parametrizations etc. with the stripped HNE(s), but it is not possible
+         to use @code{extdevelop} with them.
+SEE ALSO: develop, hnexpansion, extdevelop
+EXAMPLE: example stripHNE;  shows an example
+"
+{
+ list h;
+ if (typeof(l[1])=="matrix") { l[4]=poly(0); }
+ else {
+  for (int i=1; i<=size(l); i++) {
+    h=l[i];
+    h[4]=poly(0);
+    l[i]=h;
+  }
+ }
+ return(l);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r=0,(x,y),dp;
+  list Hne=develop(x2+y3+y4);
+  Hne;
+  stripHNE(Hne);
+}
+///////////////////////////////////////////////////////////////////////////////
+static proc extractHNEs(list HNEs, int transvers)
+"USAGE:  extractHNEs(HNEs,transvers);  list HNEs (output from HN),
+        int transvers: 1 if x,y were exchanged, 0 else
+RETURN: list of Hamburger-Noether-Extensions in the form of hne in hnexpansion
+NOTE:   This procedure is only for internal purpose; examples don't make sense
+"
+{
+ int i,maxspalte,hspalte,hnezaehler;
+ list HNEaktu,Ergebnis;
+ for (hnezaehler=1; hnezaehler<=size(HNEs); hnezaehler++) {
+  maxspalte=0;
+  HNEaktu=HNEs[hnezaehler];
+  if (defined(HNDebugOn)) {"To process:";HNEaktu;}
+  if (size(HNEaktu)!=size(HNEaktu[1])+2) {
+     "The ideals and the hqs in HNEs[",hnezaehler,"] don't match!!";
+     HNEs[hnezaehler];
+  }
+ //------------ ermittle  maximale Anzahl benoetigter Spalten: ----------------
+  for (i=2; i<size(HNEaktu); i++) {
+    hspalte=ncols(HNEaktu[i]);
+    maxspalte=maxspalte*(hspalte < maxspalte)+hspalte*(hspalte >= maxspalte);
+  }
+ //------------- schreibe Ausgabe fuer hnezaehler-ten Zweig: ------------------
+  matrix ma[size(HNEaktu)-2][maxspalte];
+  for (i=1; i<=(size(HNEaktu)-2); i++) {
+    if (ncols(HNEaktu[i+1]) > 1) {
+      ma[i,1..ncols(HNEaktu[i+1])]=HNEaktu[i+1]; }
+    else { ma[i,1]=HNEaktu[i+1][1];}
+  }
+  Ergebnis[hnezaehler]=list(ma,HNEaktu[1],transvers,HNEaktu[size(HNEaktu)]);
+  kill ma;
+ }
+ return(Ergebnis);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc factorfirst(poly f, int M, int N)
+"USAGE : factorfirst(f,M,N); f poly, M,N int
+RETURN: number d such that f=const*(y^(N/e) - d*x^(M/e))^e, where e=gcd(M,N),
+        0 if such a d does not exist
+EXAMPLE: example factorfirst;  shows an example
+"
+{
+ number c = koeff(f,0,N);
+ number delt;
+ int eps,l;
+ int p=char(basering);
+ string ringchar=charstr(basering);
+
+ if (c == 0) {"Something has gone wrong! I didn't get N correctly!"; exit;}
+ int e = gcd(M,N);
+
+ if (p==0) { delt = koeff(f,M div e,N - N div e) / (-1*e*c); }
+ else {
+   if (e%p != 0) { delt = koeff(f,M div e,N - N div e) / (-1*e*c); }
+   else {
+     eps = e;
+     for (l = 0; eps%p == 0; l=l+1) { eps=eps div p;}
+     if (defined(HNDebugOn)) {e," -> ",eps,"*",p,"^",l;}
+     delt = koeff(f,(M div e)*p^l,(N div e)*p^l*(eps-1)) / (-1*eps*c);
+
+     if ((charstr(basering) != string(p)) and (delt != 0)) {
+ //------ coefficient field is not Z/pZ => (p^l)th root is not identity -------
+       delt=0;
+       if (defined(HNDebugOn)) {
+         "trivial factorization not implemented for",
+         "parameters---I've to use 'factorize'";
+       }
+     }
+   }
+ }
+ if (defined(HNDebugOn)) {"quasihomogeneous leading form:",f," = ",c,
+        "* (y^"+string(N div e),"-",delt,"* x^"+string(M div e)+")^",e," ?";}
+ if (f != c*(var(2)^(N div e) - delt*var(1)^(M div e))^e) {return(0);}
+ else {return(delt);}
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring exring=7,(x,y),dp;
+  factorfirst(2*(y3-3x4)^5,20,15);
+  factorfirst(x14+y7,14,7);
+  factorfirst(x14+x8y3+y7,14,7);
+}
+
+///////////////////////////////////////////////////////////////////////////
+
+proc hnexpansion(poly f,list #)
+"USAGE:   hnexpansion(f[,\"ess\"]);   f poly
+ASSUME:  f is a bivariate polynomial (in the first 2 ring variables)
+RETURN:  list @code{L}, containing Hamburger-Noether data of @code{f}:
+         If the computation of the HNE required no field extension, @code{L}
+         is a list of lists @code{L[i]} (corresponding to the output of
+         @code{develop}, applied to a branch of @code{f}, but the last entry
+         being omitted):
+ at texinfo
+ at table @asis
+ at item @code{L[i][1]}; matrix:
+         Each row contains the coefficients of the corresponding line of the
+         Hamburger-Noether expansion (HNE) for the i-th branch. The end of
+         the line is marked in the matrix by the first ring variable
+         (usually x).
+ at item @code{L[i][2]}; intvec:
+         indicating the length of lines of the HNE
+ at item @code{L[i][3]}; int:
+         0  if the 1st ring variable was transversal (with respect to the
+            i-th branch), @*
+         1  if the variables were changed at the beginning of the
+            computation, @*
+        -1  if an error has occurred.
+ at item @code{L[i][4]}; poly:
+         the transformed equation of the i-th branch to make it possible
+         to extend the Hamburger-Noether data a posteriori without having
+         to do all the previous calculation once again (0 if not needed).
+ at end table
+ at end texinfo
+         If the computation of the HNE required a field extension, the first
+         entry @code{L[1]} of the list is a ring, in which a list @code{hne}
+         of lists (the HN data, as above) and a polynomial @code{f} (image of
+         @code{f} over the new field) are stored.
+         @*
+         If called with an additional input parameter, @code{hnexpansion}
+         computes only one representative for each class of conjugate
+         branches (over the ground field active when calling the procedure).
+         In this case, the returned list @code{L} always has only two
+         entries: @code{L[1]} is either a list of lists (the HN data) or a
+         ring (as above), and @code{L[2]} is an integer vector (the number
+         of branches in the respective conjugacy classes).
+
+NOTE:    If f is known to be irreducible as a power series, @code{develop(f)}
+         could be chosen instead to avoid a change of basering during the
+         computations. @*
+         Increasing  @code{printlevel} leads to more and more comments. @*
+         Having defined a variable @code{HNDebugOn} leads to a maximum
+         number of comments.
+
+SEE ALSO: develop, extdevelop, param, displayHNE
+EXAMPLE: example hnexpansion;  shows an example
+"
+{
+ int essential;
+ if (size(#)==1) { essential=1; }
+ int field_ext;
+ def altring=basering;
+
+ //--------- Falls Ring (p^k,a),...: Wechsel in (p,a),... + minpoly -----------
+ if ( hasGFCoefficient(basering) )
+ {
+   string strmip=string(minpoly);
+   string strf=string(f);
+   execute("ring tempr=("+string(char(basering))+","+parstr(basering)+"),("
+           +varstr(basering)+"),dp;");
+   execute("minpoly="+strmip+";");
+   execute("poly f="+strf+";");
+   field_ext=1;
+   def L=pre_HN(f,essential);
+   if (size(L)==0) { return(list()); }
+   def HNEring=L[1];
+   setring HNEring;
+   if ((typeof(hne[1])=="ideal")) { return(list()); }
+   if ((voice==2) && (printlevel > -1)) {
+     "// Attention: The parameter",par(1),"may have changed its meaning!";
+     "// It needs no longer be a generator of the cyclic group of unities!";
+   }
+   dbprint(printlevel-voice+2,
+     "// result: "+string(size(hne))+" branch(es) successfully computed.");
+ }
+ else {
+   def L=pre_HN(f,essential);
+   if (size(L)==0) { return(list()); }
+   if (L[2]==1) { field_ext=1; }
+   intvec hne_conj=L[3];
+   def HNEring=L[1];
+   setring HNEring;
+   if ((typeof(hne[1])=="ideal")) { return(list()); }
+   dbprint(printlevel-voice+2,
+      "// result: "+string(size(hne))+" branch(es) successfully computed.");
+ }
+
+ // ----- Lossen 10/02 : the branches have to be resorted to be able to
+ // -----                display the multsequence in a nice way
+ if (size(hne)>2)
+ {
+   int i,j,k,m;
+   list dummy;
+   int nbsave;
+   int no_br = size(hne);
+   intmat nbhd[no_br][no_br];
+   for (i=1;i<no_br;i++)
+   {
+     for (j=i+1;j<=no_br;j++)
+     {
+       nbhd[i,j]=separateHNE(hne[i],hne[j]);
+       k=i+1;
+       while ( (nbhd[i,k] >= nbhd[i,j]) and (k<j) )
+       {
+         k++;
+       }
+       if (k<j)  // branches have to be resorted
+       {
+         dummy=hne[j];
+         nbsave=nbhd[i,j];
+         for (m=k; m<j; m++)
+         {
+           hne[m+1]=hne[m];
+           nbhd[i,m+1]=nbhd[i,m];
+         }
+         hne[k]=dummy;
+         nbhd[i,k]=nbsave;
+       }
+     }
+   }
+ }
+ // -----
+
+ if (field_ext==1) {
+   dbprint(printlevel-voice+3,"
+// 'hnexpansion' created a list of one ring.
+// To see the ring and the data stored in the ring, type (if you assigned
+// the name L to the list):
+     show(L);
+// To display the computed HN expansion, type
+     def HNring = L[1]; setring HNring;  displayHNE(hne); ");
+   if (essential==1) {
+     dbprint(printlevel-voice+3,""+
+"// As second entry of the returned list L, you obtain an integer vector,
+// indicating the number of conjugates for each of the computed branches.");
+     return(list(HNEring,hne_conj));
+   }
+   return(list(HNEring));
+ }
+ else { // no change of basering necessary --> map data to original ring
+   setring altring;
+   if ((npars(altring)==1) and (minpoly!=0)) {
+     ring HNhelpring=char(altring),(a,x,y),ls;
+     list hne=imap(HNEring,hne);
+     setring altring;
+     map mmm=HNhelpring,par(1),var(1),var(2);
+     list hne=mmm(hne);
+     kill mmm,HNhelpring;
+   }
+   else {
+     list hne=fetch(HNEring,hne);
+   }
+   kill HNEring;
+   if (essential==1) {
+     dbprint(printlevel-voice+3,""+
+"// No change of ring necessary, return value is a list:
+//   first entry  =  list :  HN expansion of essential branches.
+//   second entry =  intvec: numbers of conjugated branches ");
+     return(list(hne,hne_conj));
+   }
+   else {
+     dbprint(printlevel-voice+3,""+
+"// No change of ring necessary, return value is HN expansion.");
+     return(hne);
+   }
+ }
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r=0,(x,y),dp;
+  // First, an example which requires no field extension:
+  list Hne=hnexpansion(x4-y6);
+  size(Hne);           // number of branches
+  displayHNE(Hne);     // HN expansion of branches
+  param(Hne[1]);       // parametrization of 1st branch
+  param(Hne[2]);       // parametrization of 2nd branch
+
+  // An example which requires a field extension:
+  list L=hnexpansion((x4-y6)*(y2+x4));
+  def R=L[1]; setring R; displayHNE(hne);
+  basering;
+  setring r; kill R;
+
+  // Computing only one representative per conjugacy class:
+  L=hnexpansion((x4-y6)*(y2+x4),"ess");
+  def R=L[1]; setring R; displayHNE(hne);
+  L[2];     // number of branches in respective conjugacy classes
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static proc pre_HN (poly f, int essential)
+"NOTE: This procedure is only for internal use, it is called via
+       hnexpansion
+RETURN: list:  first entry = HNEring  (containing list hne, poly f)
+               second entry = 0  if no change of base ring necessary
+                              1  if change of base ring necessary
+               third entry = numbers of conjugates ( if essential = 1 )
+        if some error has occured, the empty list is returned
+"
+{
+ def altring = basering;
+ int p = char(basering);
+ int field_ext;
+ intvec hne_conj;
+
+ //-------------------- Tests auf Zulaessigkeit von basering ------------------
+ if (charstr(basering)=="real") {
+   " Singular cannot factorize over 'real' as ground field";
+   return(list());
+ }
+ if (size(maxideal(1))<2) {
+   " A univariate polynomial ring makes no sense !";
+   return(list());
+ }
+ if (size(maxideal(1))>2) {
+   dbprint(printlevel-voice+2,
+   " Warning: all variables except the first two will be ignored!");
+ }
+ if (hasGFCoefficient(basering))
+ {
+   ERROR(" ring of type (p^k,a) not implemented");
+ //----------------------------------------------------------------------------
+ // weder primitives Element noch factorize noch map "char p^k" -> "char -p"
+ // [(p^k,a)->(p,a) ground field] noch fetch
+ //----------------------------------------------------------------------------
+ }
+ //----------------- Definition eines neuen Ringes: HNEring -------------------
+ string namex=varstr(1); string namey=varstr(2);
+ if ((npars(altring)==0)&&(find(charstr(altring),"real")==0)) { // kein Parameter, nicht 'real'
+   ring HNEring = char(altring),(x,y),ls;
+   map m=altring,x,y;
+   poly f=m(f);
+   export f;
+   kill m;
+ }
+ else {
+   string mipl=string(minpoly);
+   if (mipl=="0") {
+     "// ** WARNING: Algebraic extension of given ground field not possible!";
+     "// ** We try to develop this polynomial, but if the need for a field";
+     "// ** extension occurs during the calculation, we cannot proceed with";
+     "// ** the corresponding branches.";
+     execute("ring HNEring=("+charstr(basering)+"),(x,y),ls;");
+   }
+   else {
+    string pa=parstr(altring);
+    ring HNhelpring=p,`pa`,dp;
+    execute("poly mipo="+mipl+";");  // Minimalpolynom in Polynom umgewandelt
+    ring HNEring=(p,a),(x,y),ls;
+    map getminpol=HNhelpring,a;
+    mipl=string(getminpol(mipo));    // String umgewandelt mit 'a' als Param.
+    execute("minpoly="+mipl+";");    // "minpoly=poly is not supported"
+    kill HNhelpring; if(defined(getminpol)){ kill getminpol; }
+   }
+   if (nvars(altring)==2) {
+     poly f=fetch(altring,f);
+     export f;
+   }
+   else {
+     if (defined(pa)) { // Parameter hatte vorher anderen Namen als 'a'
+       ring HNhelpring=p,(`pa`,x,y),ls;
+       poly f=imap(altring,f);
+       setring HNEring;
+       map m=HNhelpring,a,x,y;
+       poly f=m(f);
+       kill HNhelpring;
+     }
+     else {
+       map m=altring,x,y;
+       poly f=m(f);
+     }
+     export f;
+     kill m;
+   }
+ }
+
+ if (defined(HNDebugOn))
+ {"received polynomial: ",f,", with x =",namex,", y =",namey;}
+
+ //----------------------- Variablendefinitionen ------------------------------
+ int Abbruch,i,NullHNEx,NullHNEy;
+ string str;
+ list Newton,hne;
+
+ // --- changed for SINGULAR 3: ---
+ hne=ideal(0);
+ export hne;
+
+ //====================== Tests auf Zulaessigkeit des Polynoms ================
+
+ //-------------------------- Test, ob Einheit oder Null ----------------------
+ if (subst(subst(f,x,0),y,0)!=0) {
+   dbprint(printlevel+1,
+           "The given polynomial is a unit in the power series ring!");
+   setring altring; kill HNEring;
+   return(list());                   // there are no HNEs
+ }
+ if (f==0) {
+   dbprint(printlevel+1,"The given polynomial is zero!");
+   setring altring; kill HNEring;
+   return(list());                   // there are no HNEs
+ }
+
+ //-----------------------  Test auf Quadratfreiheit --------------------------
+
+ if ((p==0) and (size(charstr(basering))==1)) {
+
+ //-------- Fall basering==0,... : Wechsel in Ring mit char >0 ----------------
+ // weil squarefree eine Standardbasis berechnen muss (verwendet Syzygien)
+ // -- wenn f in diesem Ring quadratfrei ist, dann erst recht im Ring HNEring
+ //----------------------------------------------------------------------------
+  int testerg=(polytest(f)==0);
+  ring zweitring = 32003,(x,y),dp;
+
+  map polyhinueber=HNEring,x,y;         // fetch geht nicht
+  poly f=polyhinueber(f);
+  poly test_sqr=squarefree(f);
+  if (test_sqr != f) {
+   if (printlevel>0) {
+     "Most probably the given polynomial is not squarefree. But the test was";
+     "made in characteristic 32003 and not 0 to improve speed. You can";
+     "(r) redo the test in char 0 (but this may take some time)";
+     "(c) continue the development, if you're sure that the polynomial IS",
+     "squarefree";
+     if (testerg==1) {
+       "(s) continue the development with a squarefree factor (*)";}
+     "(q) or just quit the algorithm (default action)";
+     "";"Please enter the letter of your choice:";
+     str=read("")[1];             // reads one character
+   }
+   else { str="r"; }              // printlevel <= 0: non-interactive behaviour
+   setring HNEring;
+   map polyhinueber=zweitring,x,y;
+   if (str=="r") {
+     poly test_sqr=squarefree(f);
+     if (test_sqr != f) {
+      if (printlevel>0) { "The given polynomial is in fact not squarefree."; }
+      else              { "The given polynomial is not squarefree!"; }
+      "I'll continue with the radical.";
+      f=test_sqr;
+     }
+     else {
+      dbprint(printlevel,
+       "everything is ok -- the polynomial is squarefree in characteristic 0");
+     }
+   }
+   else {
+     if ((str=="s") and (testerg==1)) {
+       "(*)attention: it could be that the factor is only one in char 32003!";
+       f=polyhinueber(test_sqr);
+     }
+     else {
+       if (str<>"c") {
+         setring altring;
+         kill HNEring;kill zweitring;
+         return(list());}
+       else { "if the algorithm doesn't terminate, you were wrong...";}
+   }}
+   kill zweitring;
+   if (defined(HNDebugOn)) {"I continue with the polynomial",f; }
+  }
+  else {
+    setring HNEring;
+    kill zweitring;
+  }
+ }
+ //------------------ Fall Char > 0 oder Ring hat Parameter -------------------
+ else {
+  poly test_sqr=squarefree(f);
+  if (test_sqr != f) {
+   if (printlevel>0) {
+    if (test_sqr == 1) {
+     "The given polynomial is of the form g^"+string(p)+",";
+     "therefore not squarefree.  You can:";
+     " (q) quit the algorithm (recommended) or";
+     " (f) continue with the full radical (using a factorization of the";
+     "     pure power part; this could take much time)";
+     "";"Please enter the letter of your choice:";
+     str=read("")[1];
+     if (str<>"f") { str="q"; }
+    }
+    else {
+     "The given polynomial is not squarefree.";
+     if (p != 0)
+      {
+       " You can:";
+       " (c) continue with a squarefree divisor (but factors of the form g^"
+       +string(p);
+       "     are lost; this is recommended, takes no extra time)";
+       " (f) continue with the full radical (using a factorization of the";
+       "     pure power part; this could take some time)";
+       " (q) quit the algorithm";
+       "";"Please enter the letter of your choice:";
+       str=read("")[1];
+       if ((str<>"f") && (str<>"q")) { str="c"; }
+      }
+     else { "I'll continue with the radical."; str="c"; }
+    }                                // endelse (test_sqr!=1)
+   }
+   else {
+     "//** Error: The given polynomial is not squarefree!";
+     "//** Since the global variable `printlevel' has the value",printlevel,
+       "we stop here.";
+     "//   Either call me again with a squarefree polynomial f or assign";
+     "            printlevel=1;";
+     "//   before calling me with a non-squarefree f.";
+     "//   If printlevel > 0, I present some possibilities how to proceed.";
+     str="q";
+   }
+   if (str=="q") {
+    setring altring;kill HNEring;
+    return(list());
+   }
+   if (str=="c") { f=test_sqr; }
+   if (str=="f") { f=allsquarefree(f,test_sqr); }
+  }
+  if (defined(HNDebugOn)) {"I continue with the polynomial",f; }
+
+ }
+ //====================== Ende Test auf Quadratfreiheit =======================
+ if (subst(subst(f,x,0),y,0)!=0) {
+   "The polynomial is a unit in the power series ring. No HNE computed.";
+   setring altring;kill HNEring;
+   return(list());
+ }
+ //---------------------- Test, ob f teilbar durch x oder y -------------------
+ if (subst(f,y,0)==0) {
+   f=f/y; NullHNEy=1; }             // y=0 is a solution
+ if (subst(f,x,0)==0) {
+   f=f/x; NullHNEx=1; }             // x=0 is a solution
+
+ Newton=newtonpoly(f,1);
+ i=1; Abbruch=0;
+ //----------------------------------------------------------------------------
+ // finde Eckpkt. des Newtonpolys, der den Teil abgrenzt, fuer den x transvers:
+ // Annahme: Newton ist sortiert, s.d. Newton[1]=Punkt auf der y-Achse,
+ // Newton[letzt]=Punkt auf der x-Achse
+ //----------------------------------------------------------------------------
+ while ((i<size(Newton)) and (Abbruch==0)) {
+  if ((Newton[i+1][1]-Newton[i][1])>=(Newton[i][2]-Newton[i+1][2]))
+   {Abbruch=1;}
+  else {i=i+1;}
+ }
+ int grenze1=Newton[i][2];
+ int grenze2=Newton[i][1];
+ //----------------------------------------------------------------------------
+ // Stelle Ring bereit zur Uebertragung der Daten im Fall einer Koerperer-
+ // weiterung. Definiere Objekte, die spaeter uebertragen werden.
+ // Binde die Listen (azeilen,...) an den Ring (um sie nicht zu ueberschreiben
+ // bei Def. in einem anderen Ring).
+ //----------------------------------------------------------------------------
+ ring HNE_noparam = char(altring),(a,x,y),ls;
+ poly f;
+ list azeilen=ideal(0);
+ list HNEs=ideal(0);
+ list aneu=ideal(0);
+ list faktoren=ideal(0);
+
+ ideal deltais;
+ poly delt;
+
+ //----- hier steht die Anzahl bisher benoetigter Ringerweiterungen drin: -----
+ int EXTHNEnumber=0;
+
+ list EXTHNEring;
+ list HNE_RingDATA;
+ int number_of_letztring;
+ setring HNEring;
+ number_of_letztring=0;
+
+ // ================= Die eigentliche Berechnung der HNE: =====================
+
+ // ------- Berechne HNE von allen Zweigen, fuer die x transversal ist: -------
+ if (defined(HNDebugOn))
+   {"1st step: Treat Newton polygon until height",grenze1;}
+ if (grenze1>0) {
+  if (EXTHNEnumber>0){ EXTHNEring = EXTHNEring(1..EXTHNEnumber); }
+  HNE_RingDATA = list(HNEring, HNE_noparam, EXTHNEnumber, EXTHNEring,
+                      number_of_letztring);
+
+  list hilflist=HN(HNE_RingDATA,f,grenze1,1,essential,0,hne_conj,1);
+  kill HNEring, HNE_noparam;
+  if (EXTHNEnumber>0) { kill EXTHNEring(1..EXTHNEnumber);}
+  def HNEring = hilflist[1][1];
+  def HNE_noparam = hilflist[1][2];
+  EXTHNEnumber = hilflist[1][3];
+  for (i=1; i<=EXTHNEnumber; i++) { def EXTHNEring(i)=hilflist[1][4][i]; }
+  if (hilflist[2]==0) { setring HNEring; number_of_letztring=0; }
+  else                { setring EXTHNEring(hilflist[2]);}
+  if (hilflist[3]==1){field_ext=1;}
+  hne_conj=hilflist[5];
+
+  if (number_of_letztring != hilflist[2])
+  {  // Ringwechsel in Prozedur HN
+     map hole=HNE_noparam,transfproc,x,y;
+     setring HNE_noparam;
+     if (not(defined(f))) {poly f;}
+     f=imap(HNEring,f);
+     setring EXTHNEring(EXTHNEnumber);
+     if (not(defined(f))) {poly f; f=hole(f); export f;}
+     else                 {f=hole(f);}
+  }
+  number_of_letztring = hilflist[2];
+  kill hilflist;
+ }
+
+ if (NullHNEy==1) {
+  if ((typeof(hne[1])=="ideal")) { hne=list(); }
+  hne=hne+list(list(matrix(ideal(0,x)),intvec(1),int(0),poly(0)));
+  if (hne_conj==0) { hne_conj=1; }
+  else { hne_conj = hne_conj, 1; }
+ }
+ // --------------- Berechne HNE von allen verbliebenen Zweigen: --------------
+ if (defined(HNDebugOn))
+    {"2nd step: Treat Newton polygon until height",grenze2;}
+ if (grenze2>0) {
+
+  if (EXTHNEnumber>0){ EXTHNEring = EXTHNEring(1..EXTHNEnumber); }
+
+  if (essential==1) { number_of_letztring=0; }
+  if (number_of_letztring==0) { setring HNEring; }
+  else                        { setring EXTHNEring(number_of_letztring); }
+  map xytausch=basering,y,x;
+
+  HNE_RingDATA = list(HNEring, HNE_noparam, EXTHNEnumber, EXTHNEring,
+                      number_of_letztring);
+  list hilflist=HN(HNE_RingDATA,xytausch(f),grenze2,1,essential,1,hne_conj,1);
+  kill HNEring, HNE_noparam;
+  if (EXTHNEnumber>0){ kill EXTHNEring(1..EXTHNEnumber); }
+  def HNEring = hilflist[1][1];
+  def HNE_noparam = hilflist[1][2];
+  EXTHNEnumber = hilflist[1][3];
+  for (i=1; i<=EXTHNEnumber; i++) { def EXTHNEring(i)=hilflist[1][4][i]; }
+  if (hilflist[2]==0) { setring HNEring; number_of_letztring=0; }
+  else                { setring EXTHNEring(hilflist[2]);
+                        number_of_letztring=hilflist[2]; }
+  if (hilflist[3]==1){field_ext=1;}
+  hne_conj=hilflist[5];
+  kill hilflist;
+ }
+ if (NullHNEx==1) {
+  if ((typeof(hne[1])=="ideal")) { hne=list(); }
+  hne=hne+list(list(matrix(ideal(0,x)),intvec(1),int(1),poly(0)));
+  if (hne_conj==0) { hne_conj=1; }
+  else { hne_conj = hne_conj, 1; }
+ }
+
+
+ // --- aufraeumen ---
+ if (defined(HNEakut)){
+   kill HNEakut,faktoren,deltais,transformiert,teiler,leitf;
+ }
+ if (defined(hilflist)) {kill hilflist;}
+ if (defined(erg)) {kill erg;}
+ if (defined(delt)) {kill delt;}
+ if (defined(azeilen)) { kill azeilen;}
+ if (defined(aneu)) { kill aneu;}
+ if (defined(transfproc)) { kill transfproc;}
+ if (defined(transf)) { kill transf;}
+ if (not(defined(f))) { poly f = imap(HNEring,f); export f; }
+
+ return(list(basering,field_ext,hne_conj));
+}
+
+//////////////////////////////////////////////////////////////////////////////
+proc essdevelop (poly f)
+"USAGE:   essdevelop(f); f poly
+NOTE:     command is obsolete, use hnexpansion(f,\"ess\") instead.
+SEE ALSO: hnexpansion, develop, extdevelop, param
+"
+{
+ printlevel=printlevel+1;
+ list Ergebnis=hnexpansion(f,1);
+ printlevel=printlevel-1;
+ return(Ergebnis);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static proc HN (list HNE_RingDATA,poly fneu,int grenze,def Aufruf_Ebene,
+                def essential,def getauscht,intvec hne_conj,int conj_factor)
+"NOTE: This procedure is only for internal use, it is called via pre_HN
+RETURN: list: first entry = list of HNErings,
+              second entry = number of new base ring (0 for HNEring,
+                                                      -1 for HNE_noparam,
+                                                      i for EXTHNEring(i))
+              third entry = 0 if no field extension necessary
+                            1 if field extension necessary
+              forth entry = HNEs (only if no change of basering)
+"
+{
+ //---------- Variablendefinitionen fuer den unverzweigten Teil: --------------
+ if (defined(HNDebugOn)) {"procedure HN",Aufruf_Ebene;}
+ int Abbruch,ende,i,j,k,e,M,N,Q,R,zeiger,zeile,zeilevorher,dd,ii;
+ intvec hqs;
+ int field_ext;
+ int ring_changed, hneshift;
+ intvec conjugates,conj2,conj1;
+
+ list EXTHNEring;
+ def HNEring = HNE_RingDATA[1];
+ def HNE_noparam = HNE_RingDATA[2];
+ int EXTHNEnumber = HNE_RingDATA[3];
+ for (i=1; i<=EXTHNEnumber; i++) { def EXTHNEring(i)=HNE_RingDATA[4][i]; }
+ int number_of_letztring = HNE_RingDATA[5];
+ if (defined(basering))
+ {
+   if (number_of_letztring==0) { kill HNEring; def HNEring=basering; }
+   else                 { kill EXTHNEring(number_of_letztring);
+                          def EXTHNEring(number_of_letztring)=basering; }
+ }
+ else
+ {
+   if ( number_of_letztring==0) { setring HNEring; }
+   else                         { setring EXTHNEring(number_of_letztring); }
+ }
+ if (not(defined(hne))) {list hne;}
+ poly fvorher;
+ list erg=ideal(0); list HNEs=ideal(0); // um die Listen an den Ring zu binden
+
+ //-------------------- Bedeutung von Abbruch: --------------------------------
+ //------- 0:keine Verzweigung | 1:Verzweigung,nicht fertig | 2:fertig --------
+ //
+ // Struktur von HNEs : Liste von Listen L (fuer jeden Zweig) der Form
+ // L[1]=intvec (hqs), L[2],L[3],... ideal (die Zeilen (0,1,...) der HNE)
+ // L[letztes]=poly (transformiertes f)
+ //----------------------------------------------------------------------------
+ list Newton;
+ number delt;
+ int p = char(basering);                // Ringcharakteristik
+ list azeilen=ideal(0);
+
+ ideal hilfid; intvec hilfvec;
+
+ // ======================= der unverzweigte Teil: ============================
+ while (Abbruch==0) {
+  Newton=newtonpoly(fneu,1);
+  zeiger=find_in_list(Newton,grenze);
+  if (Newton[zeiger][2] != grenze)
+    {"Didn't find an edge in the Newton polygon!";}
+  if (zeiger==size(Newton)-1) {
+    if (defined(HNDebugOn)) {"only one relevant side in Newton polygon";}
+    M=Newton[zeiger+1][1]-Newton[zeiger][1];
+    N=Newton[zeiger][2]-Newton[zeiger+1][2];
+    R = M%N;
+    Q = M div N;
+
+    //-------- 1. Versuch: ist der quasihomogene Leitterm reine Potenz ? ------
+    //              (dann geht alles wie im irreduziblen Fall)
+    //-------------------------------------------------------------------------
+    e = gcd(M,N);
+    delt=factorfirst(redleit(fneu,Newton[zeiger],Newton[zeiger+1])
+                      /x^Newton[zeiger][1],M,N);
+    if (delt==0) {
+      if (defined(HNDebugOn)) {" The given polynomial is reducible !";}
+      Abbruch=1;
+    }
+    if (Abbruch==0) {
+      //----------- fneu,zeile retten fuer den Spezialfall (###): -------------
+      fvorher=fneu;zeilevorher=zeile;
+      if (R==0) {
+        //-------- transformiere fneu mit T1, wenn kein Abbruch nachher: ------
+        if (N>1) { fneu = T1_Transform(fneu,delt,M div e); }
+        else     { ende=1; }
+        if (defined(HNDebugOn)) {"a("+string(zeile)+","+string(Q)+") =",delt;}
+        azeilen[zeile+1][Q]=delt;
+      }
+      else {
+        //------------- R > 0 : transformiere fneu mit T2 ---------------------
+        erg=T2_Transform(fneu,delt,M,N,referencepoly(Newton));
+        fneu=erg[1];delt=erg[2];
+        //----- vollziehe Euklid.Alg. nach, um die HN-Matrix zu berechnen: ----
+        while (R!=0) {
+         if (defined(HNDebugOn)) { "h("+string(zeile)+") =",Q; }
+         hqs[zeile+1]=Q;         // denn zeile beginnt mit dem Wert 0
+         //--------------- markiere das Zeilenende der HNE: -------------------
+         azeilen[zeile+1][Q+1]=x;
+         zeile=zeile+1;
+         //-------- Bereitstellung von Speicherplatz fuer eine neue Zeile: ----
+         azeilen[zeile+1]=ideal(0);
+         M=N; N=R; R=M%N; Q=M div N;
+        }
+        if (defined(HNDebugOn)) {"a("+string(zeile)+","+string(Q)+") =",delt;}
+        azeilen[zeile+1][Q]=delt;
+      }
+      if (defined(HNDebugOn)) {"transformed polynomial: ",fneu;}
+      grenze=e;
+      //----------------------- teste Abbruchbedingungen: ---------------------
+      if (subst(fneu,y,0)==0) {              // <==> y|fneu
+        dbprint(printlevel-voice+3,"finite HNE of one branch found");
+           // voice abzufragen macht bei rekursiven procs keinen Sinn
+        azeilen[zeile+1][Q+1]=x;
+        //----- Q wird nur in hqs eingetragen, wenn der Spezialfall nicht
+        //      eintritt (siehe unten) -----
+        Abbruch=2;
+        if (grenze>1) {
+         if (jet(fneu,1,intvec(0,1))==0) {
+           //- jet(...)=alle Monome von fneu, die nicht durch y2 teilbar sind -
+           "THE TEST FOR SQUAREFREENESS WAS BAD!!";
+           " The polynomial was NOT squarefree!!!";}
+         else {
+           //----------------------- Spezialfall (###): -----------------------
+           // Wir haben das Problem, dass die HNE eines Zweiges hier abbricht,
+           // aber ein anderer Zweig bis hierher genau die gleiche HNE hat, die
+           // noch weiter geht
+           // Loesung: mache Transform. rueckgaengig und behandle fneu im
+           // Verzweigungsteil
+           //------------------------------------------------------------------
+          Abbruch=1;
+          fneu=fvorher;zeile=zeilevorher;grenze=Newton[zeiger][2];
+        }}
+        else {fneu=0;}     // fneu nicht mehr gebraucht - spare Speicher
+        if (Abbruch==2) { hqs[zeile+1]=Q; }
+      }                 // Spezialfall nicht eingetreten
+      else {
+        if (ende==1) {
+          dbprint(printlevel-voice+2,"HNE of one branch found");
+          Abbruch=2; hqs[zeile+1]=-Q-1;}
+      }
+    }                   // end(if Abbruch==0)
+  }                     // end(if zeiger...)
+  else { Abbruch=1;}
+ }                      // end(while Abbruch==0)
+
+ // ===================== der Teil bei Verzweigung: ===========================
+ if (Abbruch==1) {
+  //---------- Variablendefinitionen fuer den verzweigten Teil: ---------------
+  poly leitf,teiler,transformiert;
+  list aneu=ideal(0);
+  list faktoren;
+  ideal deltais;
+  list HNEakut=ideal(0);
+  intvec eis;
+  int zaehler,hnezaehler,zl,zl1,M1,N1,R1,Q1,needext;
+  int numberofRingchanges,lastRingnumber,ringischanged,flag;
+  string letztringname;
+
+  zeiger=find_in_list(Newton,grenze);
+  if (defined(HNDebugOn)) {
+    "Branching part reached---Newton polygon :",Newton;
+    "relevant part until height",grenze,", from",Newton[zeiger],"on";
+  }
+  azeilen=list(hqs)+azeilen; // hat jetzt Struktur von HNEs: hqs in der 1.Zeile
+
+  //======= Schleife fuer jede zu betrachtende Seite des Newtonpolygons: ======
+  for(i=zeiger; i<size(Newton); i++) {
+   if ((essential==1) and (EXTHNEnumber>number_of_letztring)) {
+     // ----- setze ring zurueck fuer neue Kante  -----
+     // ---- (damit konjugierte Zweige erkennbar) -----
+     hneshift=hneshift+hnezaehler;
+     hnezaehler=0;
+     ring_changed=0;
+     def SaveRing = EXTHNEring(EXTHNEnumber);
+     setring SaveRing;
+     if (not(defined(HNEs))) { // HN wurde zum 2.Mal von pre_HN aufgerufen
+       list HNEs=ideal(0);
+     }
+     for (k=number_of_letztring+1; k<=EXTHNEnumber; k++) { kill EXTHNEring(k);}
+     EXTHNEnumber=number_of_letztring;
+     if (EXTHNEnumber==0) { setring HNEring; }
+     else                 { setring EXTHNEring(EXTHNEnumber); }
+     if (not(defined(HNEs))) { list HNEs; }
+     HNEs=ideal(0);
+     deltais=0;
+     delt=0;
+     if (defined(zerlege)) { kill zerlege; }
+   }
+
+   if (defined(HNDebugOn)) { "we consider side",Newton[i],Newton[i+1]; }
+   M=Newton[i+1][1]-Newton[i][1];
+   N=Newton[i][2]-Newton[i+1][2];
+   R = M%N;
+   Q = M div N;
+   e=gcd(M,N);
+   needext=1;
+   letztringname=nameof(basering);
+   lastRingnumber=EXTHNEnumber;
+   faktoren=list(ideal(charPoly(redleit(fneu,Newton[i],Newton[i+1])
+                       /(x^Newton[i][1]*y^Newton[i+1][2]),M,N)  ),
+                 intvec(1));                  // = (zu faktoriserendes Poly, 1)
+   conjugates=conj_factor;
+
+   //-- wechsle so lange in Ringerweiterungen, bis Leitform vollstaendig
+   //   in Linearfaktoren zerfaellt -----
+   for (numberofRingchanges=1; needext==1; numberofRingchanges++) {
+    leitf=redleit(fneu,Newton[i],Newton[i+1])/
+                     (x^Newton[i][1]*y^Newton[i+1][2]);
+    delt=factorfirst(leitf,M,N);
+    needext=0;
+    if (delt==0) {
+     //---------- Sonderbehandlung: faktorisiere einige Polynome ueber Q(a): --
+     if ((charstr(basering)=="0,a") and (essential==0)) {
+        // ====================================================
+        // neu CL:  06.10.05
+        poly CHPOLY=charPoly(leitf,M,N);
+        poly tstpoly;
+        if (defined(faktoren)!=0) {
+          // Test, damit kein Fehler eingebaut (vermutlich nicht notwendig)
+          tstpoly = faktoren[1][1]^faktoren[2][1];
+          for (k=2; k<=size(faktoren[1]); k++) {
+            tstpoly = tstpoly * faktoren[1][k]^faktoren[2][k];
+          }
+          tstpoly = CHPOLY-tstpoly*(CHPOLY/tstpoly);
+          kill CHPOLY;
+        }
+        if ((numberofRingchanges>1) and (defined(faktoren)!=0) and (tstpoly==0)) {
+          def L_help=factorlist(faktoren,conjugates);
+          faktoren=L_help[1];
+          conjugates=L_help[2];
+          kill L_help;
+        }
+        else {
+          faktoren=factorize(charPoly(leitf,M,N));
+          conjugates=conj_factor;
+          for (k=2;k<=size(faktoren[2]);k++) {conjugates=conjugates,conj_factor;}
+        }
+        kill tstpoly;
+        // Ende neu (vorher nur else Fall)
+        // ====================================================
+     }
+     else {
+       //------------------ faktorisiere das charakt. Polynom: ----------------
+       if ((numberofRingchanges==1) or (essential==0)) {
+         def L_help=factorlist(faktoren,conjugates);
+         faktoren=L_help[1];
+         conjugates=L_help[2];
+         kill L_help;
+       }
+       else {     // eliminiere alle konjugierten Nullstellen bis auf eine:
+         ideal hilf_id;
+         for (zaehler=1; zaehler<=size(faktoren[1]); zaehler++) {
+           hilf_id=factorize(faktoren[1][zaehler],1);
+           if (size(hilf_id)>1) {
+             poly fac=hilf_id[1];
+             dd=deg(fac);
+             // Zur Sicherheit:
+             if (deg(fac)==0) { fac=hilf_id[2]; }
+             for (k=2;k<=size(hilf_id);k++) {
+               dd=dd+deg(hilf_id[k]);
+               if (deg(hilf_id[k])<deg(fac)) { fac=hilf_id[k]; }
+             }
+             faktoren[1][zaehler]=fac;
+             kill fac;
+             if (conjugates[zaehler]==conj_factor) {
+               // number of conjugates not yet determined for this factor
+               conjugates[zaehler]=conjugates[zaehler]*dd;
+             }
+           }
+           else {
+             faktoren[1][zaehler]=hilf_id[1];
+           }
+         }
+       }
+     }
+
+     zaehler=1; eis=0;
+     for (j=1; j<=size(faktoren[2]); j++) {
+      teiler=faktoren[1][j];
+      if (teiler/y != 0) {         // sonst war's eine Konstante --> wegwerfen!
+        if (defined(HNDebugOn)) {"factor of leading form found:",teiler;}
+        if (teiler/y2 == 0) {      // --> Faktor hat die Form cy+d
+          deltais[zaehler]=-subst(teiler,y,0)/koeff(teiler,0,1); //=-d/c
+          eis[zaehler]=faktoren[2][j];
+          conj2[zaehler]=conjugates[j];
+          zaehler++;
+        }
+        else {
+          dbprint(printlevel-voice+2,
+             " Change of basering (field extension) necessary!");
+          if (defined(HNDebugOn)) { teiler,"is not yet properly factorized!"; }
+          if (needext==0) { poly zerlege=teiler; }
+          needext=1;
+          field_ext=1;
+        }
+      }
+     }  // end(for j)
+    }
+    else { deltais=ideal(delt); eis=e; conj2=conj_factor; }
+    if (defined(HNDebugOn)) {"roots of char. poly:";deltais;
+                             "with multiplicities:",eis;}
+    if (needext==1) {
+      //--------------------- fuehre den Ringwechsel aus: ---------------------
+      ringischanged=1;
+      if ((size(parstr(basering))>0) && string(minpoly)=="0") {
+        " ** We've had bad luck! The HNE cannot be calculated completely!";
+        // HNE in transzendenter Erweiterung fehlgeschlagen
+        kill zerlege;
+        ringischanged=0; break;    // weiter mit gefundenen Faktoren
+      }
+      if (parstr(basering)=="") {
+        EXTHNEnumber++;
+        def EXTHNEring(EXTHNEnumber) = splitring(zerlege);
+        setring EXTHNEring(EXTHNEnumber);
+
+        poly transf=0;
+        poly transfproc=0;
+        ring_changed=1;
+        export transfproc;
+      }
+      else {
+        if (numberofRingchanges>1) {  // ein Ringwechsel hat nicht gereicht
+         def helpring = splitring(zerlege,list(transf,transfproc,faktoren));
+         kill EXTHNEring(EXTHNEnumber);
+         def EXTHNEring(EXTHNEnumber)=helpring;
+         setring EXTHNEring(EXTHNEnumber);
+         kill helpring;
+
+         poly transf=erg[1];
+         poly transfproc=erg[2];
+         ring_changed=1;
+         list faktoren=erg[3];
+         export transfproc;
+         kill erg;
+        }
+        else {
+         if (ring_changed==1) { // in dieser proc geschah schon Ringwechsel
+          EXTHNEnumber++;
+          def EXTHNEring(EXTHNEnumber) = splitring(zerlege,list(a,transfproc));
+          setring EXTHNEring(EXTHNEnumber);
+          poly transf=erg[1];
+          poly transfproc=erg[2];
+          export transfproc;
+          kill erg;
+         }
+         else { // parameter war vorher da
+          EXTHNEnumber++;
+          def EXTHNEring(EXTHNEnumber) = splitring(zerlege,a);
+          setring EXTHNEring(EXTHNEnumber);
+          poly transf=erg[1];
+          poly transfproc=transf;
+          ring_changed=1;
+          export transfproc;
+          kill erg;
+        }}
+      }
+      //-----------------------------------------------------------------------
+      // transf enthaelt jetzt den alten Parameter des Ringes, der aktiv war
+      // vor Beginn der Schleife (evtl. also ueber mehrere Ringwechsel
+      // weitergereicht),
+      // transfproc enthaelt den alten Parameter des Ringes, der aktiv war zu
+      // Beginn der Prozedur, und der an die aufrufende Prozedur zurueckgegeben
+      // werden muss
+      // transf ist Null, falls der alte Ring keinen Parameter hatte,
+      // das gleiche gilt fuer transfproc
+      //-----------------------------------------------------------------------
+
+      //---- Neudef. von Variablen, Uebertragung bisher errechneter Daten: ----
+      poly leitf,teiler,transformiert;
+      list aneu=ideal(0);
+      ideal deltais;
+      number delt;
+      setring HNE_noparam;
+      if (defined(letztring)) { kill letztring; }
+      if (EXTHNEnumber>1) { def letztring=EXTHNEring(EXTHNEnumber-1); }
+      else                { def letztring=HNEring; }
+      if (not defined(fneu)) {poly fneu;}
+      fneu=imap(letztring,fneu);
+      if (not defined(f)) {poly f;}
+      f=imap(letztring,f);
+      if (not defined(hne)) {list hne;}
+      hne=imap(letztring,hne);
+
+      if (not defined(faktoren)) {list faktoren; }
+      faktoren=imap(letztring,faktoren);
+
+      if (not(defined(azeilen))){list azeilen,HNEs;}
+      azeilen=imap(letztring,azeilen);
+      HNEs=imap(letztring,HNEs);
+
+      setring EXTHNEring(EXTHNEnumber);
+      if (not(defined(hole))) { map hole; }
+      hole=HNE_noparam,transf,x,y;
+      poly fneu=hole(fneu);
+      if (not defined(faktoren)) {
+        list faktoren;
+        faktoren=hole(faktoren);
+      }
+      if (not(defined(f)))
+      {
+        poly f=hole(f);
+        list hne=hole(hne);
+        export f,hne;
+      }
+    }
+   }    // end (while needext==1) bzw. for (numberofRingchanges)
+
+   if (eis==0) { i++; continue; }
+   if (ringischanged==1) {
+    list erg,HNEakut;            // dienen nur zum Sp. von Zwi.erg.
+
+    ideal hilfid;
+    erg=ideal(0); HNEakut=erg;
+
+    hole=HNE_noparam,transf,x,y;
+    setring HNE_noparam;
+    if (not(defined(azeilen))){list azeilen,HNEs;}
+    azeilen=imap(letztring,azeilen);
+    HNEs=imap(letztring,HNEs);
+
+    setring EXTHNEring(EXTHNEnumber);
+    list azeilen=hole(azeilen);
+    list HNEs=hole(HNEs);
+    kill letztring;
+    ringischanged=0;
+   }
+
+   //============ Schleife fuer jeden gefundenen Faktor der Leitform: =========
+   for (j=1; j<=size(eis); j++) {
+     //---- Mache Transformation T1 oder T2, trage Daten in HNEs ein,
+     //     falls HNE abbricht: ----
+
+    //------------------------ Fall R==0: -------------------------------------
+    if (R==0) {
+      transformiert = T1_Transform(fneu,number(deltais[j]),M div e);
+      if (defined(HNDebugOn)) {
+        "a("+string(zeile)+","+string(Q)+") =",deltais[j];
+        "transformed polynomial: ",transformiert;
+      }
+      if (subst(transformiert,y,0)==0) {
+       dbprint(printlevel-voice+3,"finite HNE found");
+       hnezaehler++;
+       //-------- trage deltais[j],x ein in letzte Zeile, fertig: -------------
+       HNEakut=azeilen+list(poly(0));        // =HNEs[hnezaehler];
+       hilfid=HNEakut[zeile+2]; hilfid[Q]=deltais[j]; hilfid[Q+1]=x;
+       HNEakut[zeile+2]=hilfid;
+       HNEakut[1][zeile+1]=Q;                // aktualisiere Vektor mit den hqs
+       HNEs[hnezaehler]=HNEakut;
+       conj1[hneshift+hnezaehler]=conj2[j];
+       if (eis[j]>1) {
+        transformiert=transformiert/y;
+        if (subst(transformiert,y,0)==0){"THE TEST FOR SQUAREFREENESS WAS BAD!"
+                                  +"! The polynomial was NOT squarefree!!!";}
+        else {
+          //--- Spezialfall (###) eingetreten: Noch weitere Zweige vorhanden --
+          eis[j]=eis[j]-1;
+        }
+       }
+      }
+    }
+    else {
+      //------------------------ Fall R <> 0: ---------------------------------
+      erg=T2_Transform(fneu,number(deltais[j]),M,N,referencepoly(Newton));
+      transformiert=erg[1];delt=erg[2];
+      if (defined(HNDebugOn)) {"transformed polynomial: ",transformiert;}
+      if (subst(transformiert,y,0)==0) {
+       dbprint(printlevel-voice+3,"finite HNE found");
+       hnezaehler++;
+       //---------------- trage endliche HNE in HNEs ein: ---------------------
+       HNEakut=azeilen;           // dupliziere den gemeins. Anfang der HNE's
+       zl=2;                      // (kommt schliesslich nach HNEs[hnezaehler])
+       //----------------------------------------------------------------------
+       // Werte von:  zeile: aktuelle Zeilennummer der HNE (gemeinsamer Teil)
+       //             zl : die HNE spaltet auf; zeile+zl ist der Index fuer die
+       //                  Zeile des aktuellen Zweigs; (zeile+zl-2) ist die
+       //                  tatsaechl. Zeilennr. (bei 0 angefangen) der HNE
+       //                  ([1] <- intvec(hqs), [2] <- 0. Zeile usw.)
+       //----------------------------------------------------------------------
+
+       //----- vollziehe Euklid.Alg. nach, um die HN-Matrix zu berechnen: -----
+       M1=M;N1=N;R1=R;Q1=M1 div N1;
+       while (R1!=0) {
+        if (defined(HNDebugOn)) { "h("+string(zeile+zl-2)+") =",Q1; }
+        HNEakut[1][zeile+zl-1]=Q1;
+        HNEakut[zeile+zl][Q1+1]=x;
+                                  // markiere das Zeilenende der HNE
+        zl=zl+1;
+        //----- Bereitstellung von Speicherplatz fuer eine neue Zeile: --------
+        HNEakut[zeile+zl]=ideal(0);
+
+        M1=N1; N1=R1; R1=M1%N1; Q1=M1 div N1;
+       }
+       if (defined(HNDebugOn)) {
+         "a("+string(zeile+zl-2)+","+string(Q1)+") =",delt;
+       }
+       HNEakut[zeile+zl][Q1]  =delt;
+       HNEakut[zeile+zl][Q1+1]=x;
+       HNEakut[1][zeile+zl-1] =Q1;     // aktualisiere Vektor mit hqs
+       HNEakut[zeile+zl+1]=poly(0);
+       HNEs[hnezaehler]=HNEakut;
+       conj1[hneshift+hnezaehler]=conj2[j];
+
+       //-------------------- Ende der Eintragungen in HNEs -------------------
+
+       if (eis[j]>1) {
+        transformiert=transformiert/y;
+        if (subst(transformiert,y,0)==0){"THE TEST FOR SQUAREFREENESS WAS BAD!"
+                               +" The polynomial was NOT squarefree!!!";}
+         else {
+          //--- Spezialfall (###) eingetreten: Noch weitere Zweige vorhanden --
+          eis[j]=eis[j]-1;
+       }}
+      }                           // endif (subst()==0)
+    }                             // endelse (R<>0)
+
+    //========== Falls HNE nicht abbricht: Rekursiver Aufruf von HN: ==========
+    //------------------- Berechne HNE von transformiert ----------------------
+    if (subst(transformiert,y,0)!=0) {
+     lastRingnumber=EXTHNEnumber;
+
+     if (EXTHNEnumber>0){ EXTHNEring = EXTHNEring(1..EXTHNEnumber); }
+     HNE_RingDATA = list( HNEring, HNE_noparam, EXTHNEnumber, EXTHNEring,
+                          lastRingnumber);
+     if (defined(HNerg)) {kill HNerg;}
+     list HNerg=HN(HNE_RingDATA,transformiert,eis[j],Aufruf_Ebene+1,
+                                essential,getauscht,hne_conj,conj2[j]);
+     HNE_RingDATA = HNerg[1];
+     if (conj1==0) { conj1=HNerg[5]; }
+     else  { conj1 = conj1,HNerg[5]; }
+
+     if (HNerg[3]==1) { field_ext=1; }
+     if (HNerg[2]==lastRingnumber) { // kein Ringwechsel in HN aufgetreten
+       if (not(defined(aneu))) { list aneu; }
+       aneu = HNerg[4];
+     }
+     else { // Ringwechsel aufgetreten
+       if (defined(HNDebugOn))
+          {" ring change in HN(",Aufruf_Ebene+1,") detected";}
+       EXTHNEnumber = HNerg[1][3];
+       for (ii=lastRingnumber+1; ii<=EXTHNEnumber; ii++) {
+         def EXTHNEring(ii)=HNerg[1][4][ii];
+       }
+       if (HNerg[2]==0) { setring HNEring; }
+       else             { setring EXTHNEring(HNerg[2]); }
+       def tempRing=HNerg[4];
+       def aneu=imap(tempRing,HNEs);
+       kill tempRing;
+
+       //--- stelle lokale Variablen im neuen Ring wieder her, und rette
+       //    gegebenenfalls ihren Inhalt: ----
+       list erg,faktoren,HNEakut;
+       ideal hilfid;
+       erg=ideal(0); faktoren=erg; HNEakut=erg;
+       poly leitf,teiler,transformiert;
+       map hole=HNE_noparam,transfproc,x,y;
+       setring HNE_noparam;
+       if (lastRingnumber>0) { def letztring=EXTHNEring(lastRingnumber); }
+       else                  { def letztring=HNEring; }
+       if (not defined(HNEs)) {list HNEs;}
+       HNEs=imap(letztring,HNEs);
+       if (not defined(azeilen)) {list azeilen;}
+       azeilen=imap(letztring,azeilen);
+       if (not defined(deltais)) {ideal deltais;}
+       deltais=imap(letztring,deltais);
+       if (not defined(delt)) {poly delt;}
+       delt=imap(letztring,delt);
+       if (not defined(fneu)) {poly fneu;}
+       fneu=imap(letztring,fneu);
+       if (not defined(f)) {poly f;}
+       f=imap(letztring,f);
+       if (not defined(hne)) {list hne;}
+       hne=imap(letztring,hne);
+
+       setring EXTHNEring(EXTHNEnumber);
+       list HNEs=hole(HNEs);
+       list azeilen=hole(azeilen);
+       ideal deltais=hole(deltais);
+       number delt=number(hole(delt));
+       poly fneu=hole(fneu);
+       if (not(defined(f)))
+       {
+         poly f=hole(f);
+         list hne=hole(hne);
+         export f,hne;
+       }
+     }
+
+     //========== Verknuepfe bisherige HNE mit von HN gelieferten HNEs: ======
+     if (R==0) {
+       HNEs,hnezaehler=constructHNEs(HNEs,hnezaehler,aneu,azeilen,zeile,
+                       deltais,Q,j);
+       kill aneu;
+     }
+     else {
+      for (zaehler=1; zaehler<=size(aneu); zaehler++) {
+       hnezaehler++;
+       HNEakut=azeilen;          // dupliziere den gemeinsamen Anfang der HNE's
+       zl=2;                     // (kommt schliesslich nach HNEs[hnezaehler])
+       //------------ Trage Beitrag dieser Transformation T2 ein: -------------
+       //------ Zur Bedeutung von zeile, zl: siehe Kommentar weiter oben ------
+
+       //----- vollziehe Euklid.Alg. nach, um die HN-Matrix zu berechnen: -----
+       M1=M;N1=N;R1=R;Q1=M1 div N1;
+       while (R1!=0) {
+        if (defined(HNDebugOn)) { "h("+string(zeile+zl-2)+") =",Q1; }
+        HNEakut[1][zeile+zl-1]=Q1;
+        HNEakut[zeile+zl][Q1+1]=x;    // Markierung des Zeilenendes der HNE
+        zl=zl+1;
+        //----- Bereitstellung von Speicherplatz fuer eine neue Zeile: --------
+        HNEakut[zeile+zl]=ideal(0);
+        M1=N1; N1=R1; R1=M1%N1; Q1=M1 div N1;
+       }
+       if (defined(HNDebugOn)) {
+         "a("+string(zeile+zl-2)+","+string(Q1)+") =",delt;
+       }
+       HNEakut[zeile+zl][Q1]=delt;
+
+       //-- Daten aus T2_Transform sind eingetragen; haenge Daten von HN an: --
+       hilfid=HNEakut[zeile+zl];
+       for (zl1=Q1+1; zl1<=ncols(aneu[zaehler][2]); zl1++) {
+        hilfid[zl1]=aneu[zaehler][2][zl1];
+       }
+       HNEakut[zeile+zl]=hilfid;
+       // ------ vorher HNEs[.][zeile+zl]<-aneu[.][2],
+       //        jetzt [zeile+zl+1] <- [3] usw.: --------
+       for (zl1=3; zl1<=size(aneu[zaehler]); zl1++) {
+         HNEakut[zeile+zl+zl1-2]=aneu[zaehler][zl1];
+       }
+       //--- setze hqs zusammen: HNEs[hnezaehler][1]=HNEs[..][1],aneu[..][1] --
+       hilfvec=HNEakut[1],aneu[zaehler][1];
+       HNEakut[1]=hilfvec;
+       //-------- weil nicht geht: liste[1]=liste[1],aneu[zaehler][1] ---------
+       HNEs[hnezaehler]=HNEakut;
+      }                     // end(for zaehler)
+     kill aneu;
+     }                      // endelse (R<>0)
+    }                       // endif (subst()!=0)  (weiteres Aufblasen mit HN)
+
+   }                        // end(for j) (Behandlung der einzelnen delta_i)
+
+
+   // ------------------------- new for essdevelop ----------------------------
+   if ((essential==1) and (defined(SaveRing))) {
+     // ----- uebertrage Daten in gemeinsame Koerpererweiterung ---------------
+     if (EXTHNEnumber>number_of_letztring) {
+       // ----- fuer aktuelle Kante war Koerpererweiterung erforderlich -------
+       EXTHNEnumber++;
+       string @miniPol_EXTHNEring(EXTHNEnumber-1) = string(minpoly);
+       setring SaveRing;
+       string @miniPol_SaveRing = string(minpoly);
+       setring HNE_noparam;
+       if (not(defined(a_x))){ map a_x,a_y; poly mp_save, mp_new; }
+       execute("mp_save= " + @miniPol_SaveRing + ";");
+       execute("mp_new = " + @miniPol_EXTHNEring(EXTHNEnumber-1) + ";" );;
+       if (mp_save==mp_new) { // Sonderfall: wieder gleicher Ring
+         def EXTHNEring(EXTHNEnumber)=SaveRing;
+         setring EXTHNEring(EXTHNEnumber);
+         if (not(defined(f))) {poly f; f=hole(f); export f;}
+         list dummyL=imap(EXTHNEring(EXTHNEnumber-1),HNEs);
+         if (not(defined(HNEs))) { def HNEs=list(); }
+         if ((size(HNEs)==1) and (typeof(HNEs[1])=="ideal")) {HNEs=list();}
+         HNEs[size(HNEs)+1..size(HNEs)+size(dummyL)]=dummyL[1..size(dummyL)];
+         kill dummyL,SaveRing;
+       }
+       else { // verschiedene Ringe
+         a_x=HNE_noparam,x,0,0;
+         a_y=HNE_noparam,y,0,0;
+         mp_save=a_x(mp_save); // minpoly aus SaveRing mit a --> x
+         mp_new=a_y(mp_new);   // minpoly aus SaveRing mit a --> y
+         setring SaveRing;
+         poly mp_new=imap(HNE_noparam,mp_new);
+         list Lfac=factorize(mp_new,1);
+         poly fac=Lfac[1][1];
+         for (k=2;k<=size(Lfac[1]);k++) {
+           if (deg(Lfac[1][k])<deg(fac)) { fac=Lfac[1][k]; }
+         }
+
+         if (deg(fac)==1) { // keine Erweiterung noetig
+           def EXTHNEring(EXTHNEnumber)=SaveRing;
+           setring HNE_noparam;
+           HNEs=imap(EXTHNEring(EXTHNEnumber-1),HNEs);
+           setring EXTHNEring(EXTHNEnumber);
+           if (not(defined(f))) {poly f; f=hole(f); export f;}
+           map phi=HNE_noparam,-subst(fac,y,0)/koeff(fac,0,1),x,y;
+           list dummyL=phi(HNEs);
+           if (not(defined(HNEs))) { def HNEs=list(); }
+           if ((size(HNEs)==1) and (typeof(HNEs[1])=="ideal")) {HNEs=list();}
+           HNEs[size(HNEs)+1..size(HNEs)+size(dummyL)]=dummyL[1..size(dummyL)];
+           kill dummyL,phi,SaveRing;
+         }
+         else { // Koerpererweiterung noetig
+           def EXTHNEring(EXTHNEnumber) = splitring(fac,list(a,transfproc));
+           setring EXTHNEring(EXTHNEnumber);
+           poly transf=erg[1];  // image of parameter from SaveRing
+           poly transfproc=erg[2];
+           poly transb=erg[3];  // image of parameter from EXTHNEring(..)
+           export transfproc;
+           kill erg;
+           setring HNE_noparam;
+           if (not(defined(HNEs1))) { list HNEs1=ideal(0); }
+           HNEs1=imap(EXTHNEring(EXTHNEnumber-1),HNEs);
+           if (not(defined(hne))) { list hne=ideal(0); }
+           hne=imap(SaveRing,hne);
+           HNEs=imap(SaveRing,HNEs);
+           setring EXTHNEring(EXTHNEnumber);
+           map hole=HNE_noparam,transf,x,y;
+           poly fneu=hole(fneu);
+           poly f=hole(f);
+           map phi=HNE_noparam,transb,x,y;
+           list HNEs=hole(HNEs);
+           list hne=hole(hne);
+           export f,hne;
+           if ((size(HNEs)==1) and (typeof(HNEs[1])=="ideal")) {HNEs=list();}
+           list dummyL=phi(HNEs1);
+           HNEs[size(HNEs)+1..size(HNEs)+size(dummyL)]=dummyL[1..size(dummyL)];
+           kill dummyL,phi,SaveRing;
+         }
+       }
+     }
+     else { // nur bei letzter Kante muss was getan werden
+       if (i==size(Newton)-1) {
+         EXTHNEnumber++;
+         if (number_of_letztring==0) { def letztring=HNEring; }
+         else       { def letztring=EXTHNEring(EXTHNEnumber); }
+         if (minpoly==0) {
+           def EXTHNEring(EXTHNEnumber)=SaveRing;
+           setring EXTHNEring(EXTHNEnumber);
+           if (not(defined(f))) {poly f; f=hole(f); export f;}
+           if ((size(HNEs)==1) and (typeof(HNEs[1])=="ideal")) {HNEs=list();}
+           list dummyL=imap(letztring,HNEs);
+           HNEs[size(HNEs)+1..size(HNEs)+size(dummyL)]=dummyL[1..size(dummyL)];
+           kill dummyL,letztring,SaveRing;
+         }
+         else { // muessen Daten nach SaveRing uebertragen;
+           setring HNE_noparam;
+           if (not(defined(HNEs))) { list HNEs; }
+           HNEs=imap(letztring,HNEs);
+           def EXTHNEring(EXTHNEnumber)=SaveRing;
+           setring EXTHNEring(EXTHNEnumber);
+           if (not(defined(hole))) { map hole; }
+           hole=HNE_noparam,transfproc,x,y;
+           list dummyL=hole(HNEs);
+           if (not(defined(HNEs))) { def HNEs=list(); }
+           if ((size(HNEs)==1) and (typeof(HNEs[1])=="ideal")) {HNEs=list();}
+           HNEs[size(HNEs)+1..size(HNEs)+size(dummyL)]=dummyL[1..size(dummyL)];
+           kill dummyL, letztring,SaveRing;
+         }
+       }
+     }
+   }
+   // -----------------end of new part (loop for essential=1) ----------------
+  } // end (Loop uber Kanten)
+  if (defined(SaveRing)) { kill SaveRing; }
+ }
+ else {
+  HNEs[1]=list(hqs)+azeilen+list(fneu); // fneu ist transform. Polynom oder Null
+  conj1[1]=conj_factor;
+ }
+
+ if (Aufruf_Ebene == 1)
+ {
+   if ((number_of_letztring!=EXTHNEnumber) and (not(defined(hne))))
+   {
+     //----- falls Zweige in transz. Erw. berechnet werden konnten ---------
+     if (defined(transfproc))
+     { // --- Ringwechsel hat stattgefunden ---
+       if (defined(HNDebugOn)) {" ring change in HN(",1,") detected";}
+       if (not(defined(hole))) { map hole; }
+       hole=HNE_noparam,transfproc,x,y;
+       setring HNE_noparam;
+       f=imap(HNEring,f);
+       if (number_of_letztring==0) { def letztring=HNEring; }
+       else                        { def letztring=EXTHNEring(EXTHNEnumber); }
+       if (not(defined(hne))) { list hne; }
+       hne=imap(letztring,hne);
+       setring EXTHNEring(EXTHNEnumber);
+       if (not(defined(f))) { poly f=hole(f); export f; }
+       list hne=hole(hne);
+       export hne;
+     }
+   }
+   if (size(HNEs)>0) {
+     if ((size(HNEs)>1) or (typeof(HNEs[1])!="ideal") or (size(HNEs[1])>0)) {
+       if ((typeof(hne[1])=="ideal")) { hne=list(); }
+       hne=hne+extractHNEs(HNEs,getauscht);
+       if (hne_conj==0) { hne_conj=conj1; }
+       else { hne_conj = hne_conj, conj1; }
+     }
+   }
+ }
+ else
+ { // HN wurde rekursiv aufgerufen
+   if (number_of_letztring!=EXTHNEnumber)
+   { // Ringwechsel hatte stattgefunden
+     string mipl_alt = string(minpoly);
+     execute("ring tempRing = ("+charstr(basering)+"),("+varstr(basering)+
+                              "),("+ordstr(basering)+");");
+     execute("minpoly="+ mipl_alt +";");
+     list HNEs=imap(EXTHNEring(EXTHNEnumber),HNEs);
+     export HNEs;
+     if (defined(HNDebugOn)) {" ! tempRing defined ! ";}
+   }
+   if (conj1!=0) { hne_conj=conj1; }
+   else          { hne_conj=conj_factor; }
+ }
+ if (EXTHNEnumber>0){ EXTHNEring = EXTHNEring(1..EXTHNEnumber); }
+ HNE_RingDATA = list(HNEring, HNE_noparam, EXTHNEnumber, EXTHNEring);
+ if (number_of_letztring==EXTHNEnumber) {
+   return(list(HNE_RingDATA,EXTHNEnumber,field_ext,HNEs,hne_conj));
+ }
+ else {
+   if (defined(tempRing)) {
+     return(list(HNE_RingDATA,EXTHNEnumber,field_ext,tempRing,hne_conj));
+   }
+   return(list(HNE_RingDATA,EXTHNEnumber,field_ext,0,hne_conj));
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static proc constructHNEs (list HNEs,int hnezaehler,list aneu,list azeilen,
+                    int zeile,ideal deltais,int Q,int j)
+"NOTE: This procedure is only for internal use, it is called via HN"
+{
+  int zaehler,zl;
+  ideal hilfid;
+  list hilflist;
+  intvec hilfvec;
+  for (zaehler=1; zaehler<=size(aneu); zaehler++) {
+     hnezaehler++;
+     // HNEs[hnezaehler]=azeilen;            // dupliziere gemeins. Anfang
+ //----------------------- trage neu berechnete Daten ein ---------------------
+     hilfid=azeilen[zeile+2];
+     hilfid[Q]=deltais[j];
+     for (zl=Q+1; zl<=ncols(aneu[zaehler][2]); zl++) {
+      hilfid[zl]=aneu[zaehler][2][zl];
+     }
+     hilflist=azeilen; hilflist[zeile+2]=hilfid;
+ //------------------ haenge uebrige Zeilen von aneu[] an: --------------------
+     for (zl=3; zl<=size(aneu[zaehler]); zl++) {
+      hilflist[zeile+zl]=aneu[zaehler][zl];
+     }
+ //--- setze die hqs zusammen: HNEs[hnezaehler][1]=HNEs[..][1],aneu[..][1] ----
+     if (hilflist[1]==0) { hilflist[1]=aneu[zaehler][1]; }
+     else { hilfvec=hilflist[1],aneu[zaehler][1]; hilflist[1]=hilfvec; }
+     HNEs[hnezaehler]=hilflist;
+  }
+  return(HNEs,hnezaehler);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc referencepoly (list newton)
+"USAGE:   referencepoly(newton);
+         newton is list of intvec(x,y) which represents points in the Newton
+         diagram (e.g. output of the proc newtonpoly)
+RETURN:  a polynomial which has newton as Newton diagram
+SEE ALSO: newtonpoly
+EXAMPLE: example referencepoly;  shows an example
+"
+{
+ poly f;
+ for (int i=1; i<=size(newton); i++) {
+   f=f+var(1)^newton[i][1]*var(2)^newton[i][2];
+ }
+ return(f);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+ ring exring=0,(x,y),ds;
+ referencepoly(list(intvec(0,4),intvec(2,3),intvec(5,1),intvec(7,0)));
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc factorlist (list L, list #)
+"USAGE:   factorlist(L);   L a list in the format of `factorize'
+RETURN:  the nonconstant irreducible factors of
+         L[1][1]^L[2][1] * L[1][2]^L[2][2] *...* L[1][size(L[1])]^...
+         with multiplicities (same format as factorize)
+SEE ALSO: factorize
+EXAMPLE: example factorlist;  shows an example
+"
+{
+ int k;
+ if ((size(#)>=1) and ((typeof(#[1])=="intvec") or (typeof(#[1])=="int"))) {
+   int with_conj = 1; intvec C = #[1];
+ }
+ else {
+   int with_conj = 0; intvec C = L[2];
+ }
+ // eine Sortierung der Faktoren eruebrigt sich, weil keine zwei versch.
+ // red.Fakt. einen gleichen irred. Fakt. haben koennen (I.3.27 Diplarb.)
+ int i,gross;
+ list faktoren,hilf;
+ intvec conjugates;
+ ideal hil1,hil2;
+ intvec v,w,hilf_conj;
+ for (i=1; (L[1][i] == jet(L[1][i],0)) && (i<size(L[1])); i++) {;}
+ if (L[1][i] != jet(L[1][i],0)) {
+   hilf=factorize(L[1][i]);
+ // Achtung!!! factorize(..,2) wirft entgegen der Beschreibung nicht nur
+ // konstante Faktoren raus, sondern alle Einheiten in der LOKALISIERUNG nach
+ // der Monomordnung!!! Im Beispiel unten verschwindet der Faktor x+y+1, wenn
+ // man ds statt dp als Ordnung nimmt!
+   hilf_conj=C[i];
+   for (k=2;k<=size(hilf[2]);k++){ hilf_conj=hilf_conj,C[i]; }
+   hilf[2]=hilf[2]*L[2][i];
+   hil1=hilf[1];
+   gross=size(hil1);
+   if (gross>1) {
+     v=hilf[2];
+     faktoren=list(ideal(hil1[2..gross]),intvec(v[2..gross]));
+     conjugates=intvec(hilf_conj[2..gross]);
+   }
+   else         { faktoren=hilf; conjugates=hilf_conj; }
+ }
+ else {
+   faktoren=L;
+   conjugates=C;
+ }
+
+ for (i++; i<=size(L[2]); i++) {
+ //------------------------- linearer Term -- irreduzibel ---------------------
+   if (L[1][i] == jet(L[1][i],1)) {
+     if (L[1][i] != jet(L[1][i],0)) {           // konst. Faktoren eliminieren
+       hil1=faktoren[1];
+       hil1[size(hil1)+1]=L[1][i];
+       faktoren[1]=hil1;
+       v=faktoren[2],L[2][i];
+       conjugates=conjugates,C[i];
+       faktoren[2]=v;
+     }
+   }
+ //----------------------- nichtlinearer Term -- faktorisiere -----------------
+   else {
+     hilf=factorize(L[1][i]);
+     hilf_conj=C[i];
+     for (k=2;k<=size(hilf[2]);k++){ hilf_conj=hilf_conj,C[i]; }
+     hilf[2]=hilf[2]*L[2][i];
+     hil1=faktoren[1];
+     hil2=hilf[1];
+     gross=size(hil2);
+       // hil2[1] ist konstant, wird weggelassen:
+     hil1[(size(hil1)+1)..(size(hil1)+gross-1)]=hil2[2..gross];
+       // ideal+ideal does not work due to simplification;
+       // ideal,ideal not allowed
+     faktoren[1]=hil1;
+     w=hilf[2];
+     v=faktoren[2],w[2..gross];
+     conjugates=conjugates,hilf_conj[2..gross];
+     faktoren[2]=v;
+   }
+ }
+ if (with_conj==0) { return(faktoren); }
+ else { return(list(faktoren,conjugates)); }  // for essential development
+}
+example
+{ "EXAMPLE:"; echo = 2;
+ ring exring=0,(x,y),ds;
+ list L=list(ideal(x,(x-y)^2*(x+y+1),x+y),intvec(2,2,1));
+ L;
+ factorlist(L);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc delta
+"USAGE:  delta(INPUT);  INPUT a polynomial defining an isolated plane curve
+         singularity at 0, or the Hamburger-Noether expansion thereof, i.e.
+         the output of @code{develop(f)}, or the output of @code{hnexpansion(f)},
+         or the list of HN data computed by @code{hnexpansion(f)}.
+RETURN:  int, the delta invariant of the singularity at 0, that is, the vector
+         space dimension of R~/R, (R~ the normalization of the local ring of
+         the singularity).
+NOTE:    In case the Hamburger-Noether expansion of the curve f is needed
+         for other purposes as well it is better to calculate this first
+         with the aid of @code{hnexpansion} and use it as input instead of
+         the polynomial itself.
+SEE ALSO: deltaLoc, invariants
+KEYWORDS: delta invariant
+EXAMPLE: example delta;  shows an example
+"
+{
+  if (typeof(#[1])=="poly") { // INPUT = polynomial defining the singularity
+    list L=hnexpansion(#[1]);
+    if (typeof(L[1])=="ring") {
+      def altring = basering;
+      def HNring = L[1]; setring HNring;
+      return(delta(hne));
+    }
+    else {
+      return(delta(L));
+    }
+  }
+  if (typeof(#[1])=="ring") { // INPUT = HNEring of curve
+    def HNring = #[1]; setring HNring;
+    return(delta(hne));
+  }
+  if (typeof(#[1])=="matrix")
+  { // INPUT = hne of an irreducible curve
+    return(invariants(#)[5] div 2);
+  }
+  else
+  { // INPUT = hne of a reducible curve
+    list INV=invariants(#);
+    return(INV[size(INV)][3]);
+  }
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring r = 32003,(x,y),ds;
+  poly f = x25+x24-4x23-1x22y+4x22+8x21y-2x21-12x20y-4x19y2+4x20+10x19y
+           +12x18y2-24x18y-20x17y2-4x16y3+x18+60x16y2+20x15y3-9x16y
+           -80x14y3-10x13y4+36x14y2+60x12y4+2x11y5-84x12y3-24x10y5
+           +126x10y4+4x8y6-126x8y5+84x6y6-36x4y7+9x2y8-1y9;
+  delta(f);
+}
+
+///////////////////////////////////////////////////////////////////////////////
diff --git a/Singular/LIB/homolog.lib b/Singular/LIB/homolog.lib
new file mode 100644
index 0000000..0c7927e
--- /dev/null
+++ b/Singular/LIB/homolog.lib
@@ -0,0 +1,1948 @@
+//////////////////////////////////////////////////////////////////////////////
+version="version homolog.lib 4.0.0.0 Jun_2013 "; // $Id: 490b227e6e34e14a582bda9263beced10be4c9d7 $
+category="Commutative Algebra";
+info="
+LIBRARY:  homolog.lib   Procedures for Homological Algebra
+AUTHORS:  Gert-Martin Greuel, greuel at mathematik.uni-kl.de,
+@*        Bernd Martin,  martin at math.tu-cottbus.de
+@*        Christoph Lossen,  lossen at mathematik.uni-kl.de
+
+PROCEDURES:
+ canonMap(id);          the kernel and the cokernel of the canonical map
+ cup(M);                cup: Ext^1(M',M') x Ext^1() --> Ext^2()
+ cupproduct(M,N,P,p,q); cup: Ext^p(M',N') x Ext^q(N',P') --> Ext^p+q(M',P')
+ depth(I,M);            depth(I,M'),    I ideal, M module, M'=coker(M)
+ Ext_R(k,M);            Ext^k(M',R),    M module, R basering, M'=coker(M)
+ Ext(k,M,N);            Ext^k(M',N'),   M,N modules, M'=coker(M), N'=coker(N)
+ fitting(M,n);          n-th Fitting ideal of M'=coker(M), M module, n int
+ flatteningStrat(M);    Flattening stratification of M'=coker(M), M module
+ Hom(M,N);              Hom(M',N'),     M,N modules, M'=coker(M), N'=coker(N)
+ homology(A,B,M,N);     ker(B)/im(A),   homology of complex R^k--A->M'--B->N'
+ isCM(M);               test if coker(M) is Cohen-Macaulay, M module
+ isFlat(M);             test if coker(M) is flat, M module
+ isLocallyFree(M,r);    test if coker(M) is locally free of constant rank r
+ isReg(I,M);            test if I is coker(M)-sequence, I ideal, M module
+ hom_kernel(A,M,N);     ker(M'--A->N')  M,N modules, A matrix
+ kohom(A,k);            Hom(R^k,A),     A matrix over basering R
+ kontrahom(A,k);        Hom(A,R^k),     A matrix over basering R
+ KoszulHomology(I,M,n); n-th Koszul homology H_n(I,coker(M)), I=ideal
+ tensorMod(M,N);        Tensor product of modules M'=coker(M), N'=coker(N)
+ Tor(k,M,N);            Tor_k(M',N'),   M,N modules, M'=coker(M), N'=coker(N)
+";
+
+LIB "general.lib";
+LIB "deform.lib";
+LIB "matrix.lib";
+LIB "poly.lib";
+LIB "primdec.lib";
+///////////////////////////////////////////////////////////////////////////////
+
+proc cup (module M,list #)
+"USAGE:   cup(M,[,any,any]);  M=module
+COMPUTE: cup-product Ext^1(M',M') x Ext^1(M',M') ---> Ext^2(M',M'), where
+         M':=R^m/M, if M in R^m, R basering (i.e. M':=coker(matrix(M))).
+@*       If called with >= 2 arguments: compute symmetrized cup-product
+ASSUME:  all Ext's  are finite dimensional
+RETURN:  - if called with 1 argument: matrix, the columns of the output present
+         the coordinates of b_i&b_j with respect to a kbase of Ext^2, where
+         b_1,b_2,... is a kbase of Ext^1 and & denotes cup product;@*
+         - if called with 2 arguments: matrix, the columns of the output
+         present the coordinates of (1/2)(b_i&b_j + b_j&b_i) with respect to
+         a kbase of Ext^2;
+         - if called with 3 arguments: list,
+ at format
+      L[1] = matrix see above (symmetric case, for >=2 arguments)
+      L[2] = matrix of kbase of Ext^1
+      L[3] = matrix of kbase of Ext^2
+ at end format
+NOTE:    printlevel >=1;  shows what is going on.
+         printlevel >=2;  shows result in another representation.
+@*       For computing cupproduct of M itself, apply proc to syz(M)!
+EXAMPLE: example cup; shows examples
+"
+{
+//---------- initialization ---------------------------------------------------
+   int    i,j,k,f0,f1,f2,f3,e1,e2;
+   module M1,M2,A,B,C,ker,ima,ext1,ext2,ext10,ext20;
+   matrix cup[1][0];
+   matrix kb1,lift1,kb2,mA,mB,mC;
+   ideal  tes1,tes2,null;
+   int p = printlevel-voice+3;  // p=printlevel+1 (default: p=1)
+//-----------------------------------------------------------------------------
+//take a resolution of M<--F(0)<--- ...  <---F(3)
+//apply Hom(-,M) and compute the Ext's
+//-----------------------------------------------------------------------------
+   list resM = nres(M,3);
+   M1 = resM[2];
+   M2 = resM[3];
+   f0 = nrows(M);
+   f1 = ncols(M);
+   f2 = ncols(M1);
+   f3 = ncols(M2);
+   tes1 = simplify(ideal(M),10);
+   tes2=simplify(ideal(M1),10);
+   if ((tes1[1]*tes2[1]==0) or (tes1[1]==1) or (tes2[1]==1))
+   {
+      dbprint(p,"// Ext == 0 , hence 'cup' is the zero-map");
+      return(@cup);
+   }
+//------ compute Ext^1 --------------------------------------------------------
+   B     = kohom(M,f2);
+   A     = kontrahom(M1,f0);
+   C     = intersect(A,B);
+   C     = reduce(C,std(null));C = simplify(C,10);
+   ker   = lift(A,C)+syz(A);
+   ima   = kohom(M,f1);
+   ima   = ima + kontrahom(M,f0);
+   ext1  = modulo(ker,ima);
+   ext10 = std(ext1);
+   e1    = vdim(ext10);
+   dbprint(p-1,"// vdim (Ext^1) = "+string(e1));
+   if (e1 < 0)
+   {
+     "// Ext^1 not of finite dimension";
+     return(cup);
+   }
+   kb1 = kbase(ext10);
+   kb1 = matrix(ker)*kb1;
+   dbprint(p-1,"// kbase of Ext^1(M,M)",
+              "//  - the columns present the kbase elements in Hom(F(1),F(0))",
+              "//  - F(*) a free resolution of M",kb1);
+
+//------ compute the liftings of Ext^1 ----------------------------------------
+   mC = matrix(A)*kb1;
+   lift1 =lift(B,mC);
+   dbprint(p-1,"// lift kbase of Ext^1:",
+    "//  - the columns present liftings of kbase elements into Hom(F(2),F(1))",
+    "//  - F(*) a free resolution of M ",lift1);
+
+//------ compute Ext^2  -------------------------------------------------------
+   B    = kohom(M,f3);
+   A    = kontrahom(M2,f0);
+   C    = intersect(A,B);
+   C    = reduce(C,std(null));C = simplify(C,10);
+   ker  = lift(A,C)+syz(A);
+   ima  = kohom(M,f2);
+   ima  = ima + kontrahom(M1,f0);
+   ext2 = modulo(ker,ima);
+   ext20= std(ext2);
+   e2   = vdim(ext20);
+   if (e2<0)
+   {
+     "// Ext^2 not of finite dimension";
+     return(cup);
+   }
+   dbprint(p-1,"// vdim (Ext^2) = "+string(e2));
+   kb2 = kbase(ext20);
+   kb2 = matrix(ker)*kb2;
+   dbprint(p-1,"// kbase of Ext^2(M,M)",
+             "//  - the columns present the kbase elements in Hom(F(2),F(0))",
+             "//  - F(*) is a free resolution of M ",kb2);
+//-------  compute: cup-products of base-elements -----------------------------
+   for (i=1;i<=e1;i=i+1)
+   {
+     for (j=1;j<=e1;j=j+1)
+     {
+       mA = matrix(ideal(lift1[j]),f1,f2);
+       mB = matrix(ideal(kb1[i]),f0,f1);
+       mC = mB*mA;
+       if (size(#)==0)
+       {                                          //non symmestric
+         mC = matrix(ideal(mC),f0*f2,1);
+         cup= concat(cup,mC);
+       }
+       else                                       //symmetric version
+       {
+         if (j>=i)
+         {
+           if (j>i)
+           {
+             mA = matrix(ideal(lift1[i]),f1,f2);
+             mB = matrix(ideal(kb1[j]),f0,f1);
+             mC = mC+mB*mA;mC=(1/2)*mC;
+           }
+           mC = matrix(ideal(mC),f0*f2,1);
+           cup= concat(cup,mC);
+         }
+       }
+     }
+   }
+   dbprint(p-1,"// matrix of cup-products (in Ext^2)",cup,
+               "////// end level 2 //////");
+//------- compute: presentation of base-elements -----------------------------
+   cup = lift(ker,cup);
+   cup = lift_kbase(cup,ext20);
+   if( p>2 )
+   {
+     "// the associated matrices of the bilinear mapping 'cup' ";
+     "// corresponding to the kbase elements of Ext^2(M,M) are shown,";
+     "//  i.e. the rows of the final matrix are written as matrix of";
+     "//  a bilinear form on Ext^1 x Ext^1";
+     matrix BL[e1][e1];
+     for (k=1;k<=e2;k=k+1)
+     {
+       "//-----component "+string(k)+":";
+       for (i=1;i<=e1;i=i+1)
+       {
+         for (j=1;j<=e1;j=j+1)
+         {
+           if (size(#)==0) { BL[i,j]=cup[k,j+e1*(i-1)]; }
+           else
+           {
+             if (i<=j)
+             {
+               BL[i,j]=cup[k,j+e1*(i-1)-binomial(i,2)];
+               BL[j,i]=BL[i,j];
+             }
+           }
+         }
+       }
+       print(BL);
+     }
+     "////// end level 3 //////";
+   }
+   if (size(#)>2) { return(cup,kb1,kb2);}
+   else {return(cup);}
+}
+example
+{"EXAMPLE";  echo=2;
+  int p      = printlevel;
+  ring  rr   = 32003,(x,y,z),(dp,C);
+  ideal  I   = x4+y3+z2;
+  qring  o   = std(I);
+  module M   = [x,y,0,z],[y2,-x3,z,0],[z,0,-y,-x3],[0,z,x,-y2];
+  print(cup(M));
+  print(cup(M,1));
+  // 2nd EXAMPLE  (shows what is going on)
+  printlevel = 3;
+  ring   r   = 0,(x,y),(dp,C);
+  ideal  i   = x2-y3;
+  qring  q   = std(i);
+  module M   = [-x,y],[-y2,x];
+  print(cup(M));
+  printlevel = p;
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc cupproduct (module M,module N,module P,int p,int q,list #)
+"USAGE:   cupproduct(M,N,P,p,q[,any]);  M,N,P modules, p,q integers
+COMPUTE: cup-product Ext^p(M',N') x Ext^q(N',P') ---> Ext^(p+q)(M',P'),
+         where M':=R^m/M, if M in R^m, R basering (i.e. M':=coker(matrix(M)))
+ASSUME:  all Ext's  are of finite dimension
+RETURN:  - if called with 5 arguments: matrix of the associated linear map
+         Ext^p (tensor) Ext^q --> Ext^(p+q),  i.e. the columns of <matrix>
+         present the coordinates of the cup products (b_i & c_j) with respect
+         to a kbase of Ext^p+q  (b_i resp. c_j are the chosen bases of Ext^p,
+         resp. Ext^q).@*
+         - if called with 6 arguments: list L,
+ at format
+      L[1] = matrix (see above)
+      L[2] = matrix of kbase of Ext^p(M',N')
+      L[3] = matrix of kbase of Ext^q(N',P')
+      L[4] = matrix of kbase of Ext^p+q(N',P')
+ at end format
+NOTE:    printlevel >=1;  shows what is going on.
+         printlevel >=2;  shows the result in another representation.@*
+         For computing the cupproduct of M,N itself, apply proc to syz(M),
+         syz(N)!
+EXAMPLE: example cupproduct; shows examples
+"
+{
+//---------- initialization ---------------------------------------------------
+   int    e1,e2,e3,i,j,k,f0,f1,f2;
+   module M1,M2,N1,N2,P1,P2,A,B,C,ker,ima,extMN,extMN0,extMP,
+          extMP0,extNP,extNP0;
+   matrix cup[1][0];
+   matrix kbMN,kbMP,kbNP,lift1,mA,mB,mC;
+   ideal  test1,test2,null;
+   int pp = printlevel-voice+3;  // pp=printlevel+1 (default: p=1)
+//-----------------------------------------------------------------------------
+//compute resolutions of M and N
+//                     M<--F(0)<--- ...  <---F(p+q+1)
+//                     N<--G(0)<--- ...  <---G(q+1)
+//-----------------------------------------------------------------------------
+   list resM = nres(M,p+q+1);
+   M1 = resM[p];
+   M2 = resM[p+1];
+   list resN = nres(N,q+1);
+   N1 = resN[q];
+   N2 = resN[q+1];
+   P1 = resM[p+q];
+   P2 = resM[p+q+1];
+//-------test: Ext==0?---------------------------------------------------------
+   test1 = simplify(ideal(M1),10);
+   test2 = simplify(ideal(N),10);
+   if (test1[1]==0) { dbprint(pp,"//Ext(M,N)=0");return(cup); }
+   test1 = simplify(ideal(N1),10);
+   test2 = simplify(ideal(P),10);
+   if (test1[1]==0) { dbprint(pp,"//Ext(N,P)=0");return(cup); }
+   test1 = simplify(ideal(P1),10);
+   if (test1[1]==0) { dbprint(pp,"//Ext(M,P)=0");return(cup); }
+ //------ compute kbases of Ext's ---------------------------------------------
+ //------ Ext(M,N)
+   test1 = simplify(ideal(M2),10);
+   if (test1[1]==0) { ker = freemodule(ncols(M1)*nrows(N));}
+   else
+   {
+     A   = kontrahom(M2,nrows(N));
+     B   = kohom(N,ncols(M2));
+     C   = intersect(A,B);
+     C   = reduce(C,std(ideal(0)));C=simplify(C,10);
+     ker = lift(A,C)+syz(A);
+   }
+   ima   = kohom(N,ncols(M1));
+   A     = kontrahom(M1,nrows(N));
+   ima   = ima+A;
+   extMN = modulo(ker,ima);
+   extMN0= std(extMN);
+   e1    = vdim(extMN0);
+   dbprint(pp-1,"// vdim Ext(M,N) = "+string(e1));
+   if (e1 < 0)
+   {
+     "// Ext(M,N) not of finite dimension";
+     return(cup);
+   }
+   kbMN  = kbase(extMN0);
+   kbMN = matrix(ker)*kbMN;
+   dbprint(pp-1,"// kbase of Ext^p(M,N)",
+          "//  - the columns present the kbase elements in Hom(F(p),G(0))",
+          "//  - F(*),G(*) are free resolutions of M and N",kbMN);
+//------- Ext(N,P)
+   test1 = simplify(ideal(N2),10);
+   if (test1[1]==0) {  ker = freemodule(ncols(N1)*nrows(P)); }
+   else
+   {
+     A = kontrahom(N2,nrows(P));
+     B = kohom(P,ncols(N2));
+     C = intersect(A,B);
+     C = reduce(C,std(ideal(0)));C=simplify(C,10);
+     ker = lift(A,C)+syz(A);
+   }
+   ima   = kohom(P,ncols(N1));
+   A     = kontrahom(N1,nrows(P));
+   ima   = ima+A;
+   extNP = modulo(ker,ima);
+   extNP0= std(extNP);
+   e2    = vdim(extNP0);
+   dbprint(pp-1,"// vdim Ext(N,P) = "+string(e2));
+   if (e2 < 0)
+   {
+     "// Ext(N,P) not of finite dimension";
+     return(cup);
+   }
+   kbNP  = kbase(extNP0);
+   kbNP  = matrix(ker)*kbNP;
+   dbprint(pp-1,"// kbase of Ext(N,P):",kbNP,
+          "// kbase of Ext^q(N,P)",
+          "//  - the columns present the kbase elements in Hom(G(q),H(0))",
+          "//  - G(*),H(*) are free resolutions of N and P",kbNP);
+
+//------ Ext(M,P)
+   test1 = simplify(ideal(P2),10);
+   if (test1[1]==0) { ker = freemodule(ncols(P1)*nrows(P)); }
+   else
+   {
+     A = kontrahom(P2,nrows(P));
+     B = kohom(P,ncols(P2));
+     C = intersect(A,B);
+     C = reduce(C,std(ideal(0)));C=simplify(C,10);
+     ker = lift(A,C)+syz(A);
+   }
+   ima   = kohom(P,ncols(P1));
+   A     = kontrahom(P1,nrows(P));
+   ima   = ima+A;
+   extMP = modulo(ker,ima);
+   extMP0= std(extMP);
+   e3    = vdim(extMP0);
+   dbprint(pp-1,"// vdim Ext(M,P) = "+string(e3));
+   if (e3 < 0)
+   {
+     "// Ext(M,P) not of finite dimension";
+     return(cup);
+   }
+   kbMP  = kbase(extMP0);
+   kbMP  = matrix(ker)*kbMP;
+   dbprint(pp-1,"// kbase of Ext^p+q(M,P)",
+          "//  - the columns present the kbase elements in Hom(F(p+q),H(0))",
+          "//  - F(*),H(*) are free resolutions of M and P",kbMP);
+//----- lift kbase of Ext(M,N) ------------------------------------------------
+   lift1 = kbMN;
+   for (i=1;i<=q;i=i+1)
+   {
+     mA = kontrahom(resM[p+i],nrows(resN[i]));
+     mB = kohom(resN[i],ncols(resM[p+i]));
+     lift1 = lift(mB,mA*lift1);
+   }
+   dbprint(pp-1,"// lifting of kbase of Ext^p(M,N)",
+   "//  - the columns present liftings of kbase elements"+
+   " in Hom(F(p+q),G(q))",lift1);
+//-------  compute: cup-products of base-elements -----------------------------
+   f0 = nrows(P);
+   f1 = ncols(N1);
+   f2 = ncols(resM[p+q]);
+   for (i=1;i<=e1;i=i+1)
+   {
+     for (j=1;j<=e2;j=j+1)
+     {
+       mA = matrix(ideal(lift1[j]),f1,f2);
+       mB = matrix(ideal(kbMP[i]),f0,f1);
+       mC = mB*mA;
+       mC = matrix(ideal(mC),f0*f2,1);
+       cup= concat(cup,mC);
+     }
+   }
+   dbprint(pp-1,"// matrix of cup-products (in Ext^p+q)",cup,
+                "////// end level 2 //////");
+//------- compute: presentation of base-elements -----------------------------
+   cup = lift(ker,cup);
+   cup = lift_kbase(cup,extMP0);
+//------- special output ------------------------------------------------------
+   if (pp>2)
+   {
+     "// the associated matrices of the bilinear mapping 'cup' ";
+     "// corresponding to the kbase elements of Ext^p+q(M,P) are shown,";
+     "//  i.e. the rows of the final matrix are written as matrix of";
+     "//  a bilinear form on Ext^p x Ext^q";
+     matrix BL[e1][e2];
+     for (k=1;k<=e3;k=k+1)
+     {
+       "//----component "+string(k)+":";
+       for (i=1;i<=e1;i=i+1)
+       {
+         for (j=1;j<=e2;j=j+1)
+         {
+           BL[i,j]=cup[k,j+e1*(i-1)];
+         }
+        }
+        print(BL);
+      }
+     "////// end level 3 //////";
+   }
+   if (size(#)) { return(cup,kbMN,kbNP,kbMP);}
+   else         { return(cup); }
+}
+example
+{"EXAMPLE";  echo=2;
+  int p      = printlevel;
+  ring  rr   = 32003,(x,y,z),(dp,C);
+  ideal  I   = x4+y3+z2;
+  qring  o   = std(I);
+  module M   = [x,y,0,z],[y2,-x3,z,0],[z,0,-y,-x3],[0,z,x,-y2];
+  print(cupproduct(M,M,M,1,3));
+  printlevel = 3;
+  list l     = (cupproduct(M,M,M,1,3,"any"));
+  show(l[1]);show(l[2]);
+  printlevel = p;
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc Ext_R (intvec v, module M, list #)
+"USAGE:   Ext_R(v,M[,p]);  v int resp. intvec , M module, p int
+COMPUTE: A presentation of Ext^k(M',R); for k=v[1],v[2],..., M'=coker(M).
+         Let
+ at example
+  0 <-- M' <-- F0 <-M-- F1 <-- F2 <-- ...
+ at end example
+         be a free resolution of M'. If
+ at example
+        0 --> F0* -A1-> F1* -A2-> F2* -A3-> ...
+ at end example
+         is the dual sequence, Fi*=Hom(Fi,R), then Ext^k = ker(Ak+1)/im(Ak)
+         is presented as in the following exact sequences:
+ at example
+    R^p --syz(Ak+1)-> Fk* ---Ak+1---->  Fk+1* ,
+    R^q ----Ext^k---> R^p --syz(Ak+1)-> Fk*/im(Ak).
+ at end example
+         Hence, Ext^k=modulo(syz(Ak+1),Ak) presents Ext^k(M',R).
+RETURN:  - module Ext, a presentation of Ext^k(M',R) if v is of type int@*
+         - a list of Ext^k (k=v[1],v[2],...) if v is of type intvec.@*
+         - In case of a third argument of type int return a list l:
+ at format
+     l[1] = module Ext^k resp. list of Ext^k
+     l[2] = SB of Ext^k resp. list of SB of Ext^k
+     l[3] = matrix resp. list of matrices, each representing a kbase of Ext^k
+              (if finite dimensional)
+ at end format
+DISPLAY: printlevel >=0: (affine) dimension of Ext^k for each k  (default)
+         printlevel >=1: Ak, Ak+1 and kbase of Ext^k in Fk*
+NOTE:    In order to compute Ext^k(M,R) use the command Ext_R(k,syz(M));@*
+         By default, the procedure uses the @code{mres} command. If called
+         with the additional parameter @code{\"sres\"}, the @code{sres} command
+         is used instead.@*
+         If the attribute @code{\"isHomog\"} has been set for the input module, it
+         is also set for the returned module (accordingly).
+EXAMPLE: example Ext_R; shows an example
+"
+{
+  // In case M is known to be a SB, set attrib(M,"isSB",1); in order to
+  // avoid  unnecessary SB computations
+
+  //------------ check for weight vector (graded case) -----------------------
+  int withWeight;
+  intvec weightM,weightR,ww;
+  if ( typeof(attrib(M,"isHomog"))!="string" )
+  {
+    weightM=attrib(M,"isHomog");
+    withWeight=1;
+  }
+
+  //------------ initialisation ----------------------------------------------
+  module m1t,m1,m2,m2t,ret,ret0,ker;
+  vector leadCol;
+  matrix kb;
+  module G;
+  list L1,L2,L3,L,K;
+  resolution resm2;
+  int j,k,max,ii,t1,t2,di,leadComp,shift;
+  intvec A1,A2,A3;
+  int s = size(v);
+  max = Max(v);                // the maximum integer occurring in intvec v
+  int p = printlevel-voice+3;  // p=printlevel+1 (default: p=1)
+  // --------------- Variante mit sres
+  for( ii=1; ii<=size(#); ii++ )
+  {
+    if (typeof(#[ii])=="int") { // return a list if t2=1
+      t2=1;
+    }
+    else {
+      if (typeof(#[ii])=="string") {
+        // NOTE: at this writing, sres does not return weights
+        if ( #[ii]=="sres" ) { t1=1; } // use sres instead of mres if t1=1
+      }
+    }
+  }
+
+//----------------- compute resolution of coker(M) ----------------------------
+  if( max<0 )
+  {
+    dbprint(p,"// Ext^i=0 for i<0!");
+    module Result=[1];
+    if (withWeight==1) { attrib(Result,"isHomog",intvec(0)); }
+    if (s==1) {
+      if (t2==0) { return(Result); }
+      else       { return( list(Result,Result,matrix(0)) ); }
+    }
+    list Out, KBOut;
+    for (j=1;j<=s;j++) {
+      Out[j] = Result;
+      KBOut[j] = matrix(0);
+    }
+    if (t2==0) { return(Out); }
+    else       { return( list(Out,Out,KBOut) ); }
+  }
+  if( t1==1 )
+  { // compute resolution via sres command
+    if( attrib(M,"isSB")==0 ) {
+      if (size(M)==0) { attrib(M,"isSB")=1; }
+      else { M=std(M); }
+    }
+    list resl = sres(M,max+1);
+    if (withWeight) {
+      // ****
+      // **** at this writing, sres does not return weights, we have to
+      // **** go through the resolution to compute them
+      // ****
+      attrib(resl,"isHomog",weightM);  // weightM = weights of M
+      G=resl[1];
+      attrib(G,"isHomog",weightM);
+      resl[1]=G;
+      weightR=weightM;
+
+      for (j=2; j<=size(resl); j++) {
+        if (size(G)!=0) {
+          ww=0;
+          for (k=1; k<=ncols(G); k++) {
+            if (size(G[k])==0) { ww[k]=0; }
+            else {
+              leadCol = leadmonom(G[k]);
+              leadComp = nrows(leadCol);
+              ww[k] = deg(leadCol)+weightR[leadComp];
+            }
+          }
+          G=resl[j];
+          attrib(G,"isHomog",ww);
+          resl[j]=G;
+          weightR=ww;
+        }
+      }
+    }
+  }
+  else { list resl = mres(M,max+1);
+    if ((withWeight) and (size(M)==0)) {
+      // ***** At this writing: special treatment for zero module needed
+      G=resl[1];
+      attrib(G,"isHomog",weightM);
+      resl[1]=G;
+    }
+  }
+  for( ii=1; ii<=s; ii++ )
+  {
+//-----------------  apply Hom(_,R) at k-th place -----------------------------
+    k=v[ii];
+    dbprint(p-1,"// Computing Ext^"+string(k)+":");
+    if( k<0 )                   // Ext^k=0 for negative k
+    {
+      dbprint(p-1,"// Ext^i=0 for i<0!");
+      ret    = gen(1);
+      ret0   = std(ret);
+      if (withWeight==1) {
+        attrib(ret,"isHomog",intvec(0));
+        attrib(ret0,"isHomog",intvec(0));
+      }
+      L1[ii] = ret;
+      L2[ii] = ret0;
+      L3[ii] = matrix(kbase(ret0));
+      di=dim(ret0);
+      dbprint(p,"// dimension of Ext^"+string(k)+":  "+string(di));
+      if (di==0)
+      {
+        dbprint(p,"// vdim of Ext^"+string(k)+":       "+string(vdim(ret0)));
+      }
+      dbprint(p,"");
+    }
+    else
+    {
+      m2t = resl[k+1];
+      m2 = transpose(m2t);
+      if ((typeof(attrib(m2t,"isHomog"))!="string" ) && (withWeight))
+      {
+        // ------------- compute weights for dual -----------------------------
+        weightR=attrib(m2t,"isHomog");
+        // --------------------------------------------------------------------
+        // *** set correct weights (at this writing, shift in resolution
+        // *** is not considered when defining the weights for the
+        // *** modules in the resolution):
+        A1=attrib(M,"isHomog");
+        A2=attrib(resl[1],"isHomog");
+        shift=A1[1]-A2[1];
+        for (j=1; j<=size(weightR); j++) { weightR[j]=weightR[j]+shift; }
+        attrib(m2t,"isHomog",weightR);
+        // --------------------------------------------------------------------
+        ww=0;
+        for (j=1; j<=nrows(m2); j++) {
+          if (size(m2t[j])==0) { ww[j]=0; }
+          else {
+            leadCol = leadmonom(m2t[j]);
+            leadComp = nrows(leadCol);
+            ww[j] = deg(leadCol)+weightR[leadComp];
+          }
+        }
+        attrib(m2,"isHomog",-ww);  // dualize --> negative weights
+        // --------------------------------------------------------------------
+        // *** the following should be replaced by the syz command,
+        // *** but syz forgets weights.....
+        resm2 = nres(m2,2);
+        ker = resm2[2];
+        if ((size(ker)>0) and (size(m2)>0)) {
+          // ------------------------------------------------------------------
+          // *** set correct weights (at this writing, shift in resolution
+          // *** is not considered when defining the weights for the
+          // *** modules in the resolution):
+          A1=attrib(resm2,"isHomog");
+          A2=attrib(resm2[1],"isHomog");
+          A3=attrib(ker,"isHomog");
+          shift=A1[1]-A2[1];
+          for (j=1; j<=size(A3); j++) { A3[j]=A3[j]+shift; }
+          // *** set correct weights where weights are undetermined due to
+          // *** zero columns in m2  (read weights from m2t)
+          for (j=1; j<=ncols(m2); j++) {
+            if (size(m2[j])==0) { A3[j]=-weightR[j]; }
+          }
+          attrib(ker,"isHomog",A3);
+          // ------------------------------------------------------------------
+        }
+      }
+      else {
+        ker = syz(m2);
+      }
+
+      if( k==0 ) { matrix MMM1[ncols(m2)][1];
+        m1=MMM1;
+      }
+      else { // k>0
+        m1t = resl[k];
+        m1 = transpose(resl[k]);
+        if ((typeof(attrib(m1t,"isHomog"))!="string" ) && (withWeight)) {
+        // ------------- compute weights for dual -----------------------------
+          weightR=attrib(resl[k],"isHomog");
+          // ------------------------------------------------------------------
+          // *** set correct weights (at this writing, shift in resolution
+          // *** is not considered when defining the weights for the
+          // *** modules in the resolution):
+          A1=attrib(M,"isHomog");
+          A2=attrib(resl[1],"isHomog");
+          shift=A1[1]-A2[1];
+          for (j=1; j<=size(weightR); j++) { weightR[j]=weightR[j]+shift; }
+          attrib(m1t,"isHomog",weightR);
+          // ------------------------------------------------------------------
+          ww=0;
+          for (j=1; j<=nrows(m1); j++) {
+            if (size(m1t[j])==0) { ww[j]=0; }
+            else {
+              leadCol = leadmonom(m1t[j]);
+              leadComp = nrows(leadCol);
+              ww[j] = deg(leadCol)+weightR[leadComp];
+            }
+          }
+          attrib(m1,"isHomog",-ww);  // dualize --> negative weights
+        }
+      }
+      //----------------- presentation of ker(m2)/im(m1) ---------------------
+      if ((k==0) and (size(M)==0)) {
+        ret = M;
+        if (withWeight) { attrib(ret,"isHomog",-weightM); }
+      }
+      else {
+        ret = modulo(ker,m1);
+      }
+      dbprint(p-1,
+         "// Let 0<--coker(M)<--F0<--F1<--F2<--... be a resolution of M,",
+         "// then F"+string(k)+"*-->F"+string(k+1)+"* is given by:",m2,
+         "// and F"+string(k-1)+"*-->F"+string(k)+"* is given by:",m1,"");
+      ret0 = std(ret);
+
+      di=dim(ret0);
+      dbprint(p,"// dimension of Ext^"+string(k)+":  "+string(di));
+      if (di==0)
+      {
+        dbprint(p,"// vdim of Ext^"+string(k)+":       "+string(vdim(ret0)));
+      }
+      dbprint(p,"");
+      if( t2 )
+      {
+         if( vdim(ret0)>=0 )
+         {
+            kb = kbase(ret0);
+            if ( size(ker)!=0 ) { kb = matrix(ker)*kb; }
+            dbprint(p-1,
+              "// columns of matrix are kbase of Ext^"+string(k)+" in F"
+              +string(k)+"*:",kb,"");
+            L3[ii] = kb;
+         }
+         L2[ii] = ret0;
+      }
+      L1[ii] = ret;
+    }
+  }
+  if( t2 )
+  {
+     if( s>1 ) { L = L1,L2,L3; return(L); }
+     else { L = ret,ret0,kb; return(L); }
+  }
+  else
+  {
+     if( s>1 ) { return(L1); }
+     else { return(ret); }
+  }
+}
+example
+{"EXAMPLE:";     echo=2;
+  int p      = printlevel;
+  printlevel = 1;
+  ring r     = 0,(x,y,z),dp;
+  ideal i    = x2y,y2z,z3x;
+  module E   = Ext_R(1,i);    //computes Ext^1(r/i,r)
+  is_zero(E);
+
+  qring R    = std(x2+yz);
+  intvec v   = 0,2;
+  printlevel = 2;             //shows what is going on
+  ideal i    = x,y,z;         //computes Ext^i(r/(x,y,z),r/(x2+yz)), i=0,2
+  list L     = Ext_R(v,i,1);  //over the qring R=r/(x2+yz), std and kbase
+  printlevel = p;
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc Ext (intvec v, module M, module N, list #)
+"USAGE:   Ext(v,M,N[,any]);  v int resp. intvec, M,N modules
+COMPUTE: A presentation of Ext^k(M',N'); for k=v[1],v[2],... where
+         M'=coker(M) and N'=coker(N). Let
+ at example
+       0 <-- M' <-- F0 <-M-- F1 <-- F2 <--... ,
+       0 <-- N' <-- G0 <--N- G1
+ at end example
+         be a free resolution of M', resp. a presentation of N'. Consider
+         the commutative diagram
+ at example
+           0                  0                  0
+           |^                 |^                 |^
+   --> Hom(Fk-1,N') -Ak-> Hom(Fk,N') -Ak+1-> Hom(Fk+1,N')
+           |^                 |^                 |^
+   --> Hom(Fk-1,G0) -Ak-> Hom(Fk,G0) -Ak+1-> Hom(Fk+1,G0)
+                              |^                 |^
+                              |C                 |B
+                          Hom(Fk,G1) ------> Hom(Fk+1,G1)
+
+      (Ak,Ak+1 induced by M and B,C induced by N).
+ at end example
+         Let K=modulo(Ak+1,B), J=module(Ak)+module(C) and Ext=modulo(K,J),
+         then we have exact sequences
+ at example
+    R^p --K-> Hom(Fk,G0) --Ak+1-> Hom(Fk+1,G0)/im(B),
+
+    R^q -Ext-> R^p --K-> Hom(Fk,G0)/(im(Ak)+im(C)).
+ at end example
+         Hence, Ext presents Ext^k(M',N').
+RETURN:  - module Ext, a presentation of Ext^k(M',N') if v is of type int@*
+         - a list of Ext^k (k=v[1],v[2],...) if v is of type intvec.@*
+         - In case of a third argument of any type return a list l:
+ at format
+             l[1] = module Ext/list of Ext^k
+             l[2] = SB of Ext/list of SB of Ext^k
+             l[3] = matrix/list of matrices, each representing a kbase of Ext^k
+                       (if finite dimensional)
+ at end format
+DISPLAY: printlevel >=0: dimension, vdim of Ext^k for each k  (default).
+@*       printlevel >=1: matrices Ak, Ak+1 and kbase of Ext^k in Hom(Fk,G0)
+         (if finite dimensional)
+NOTE:    In order to compute Ext^k(M,N) use the command Ext(k,syz(M),syz(N));
+         or: list P=mres(M,2); list Q=mres(N,2); Ext(k,P[2],Q[2]);
+EXAMPLE: example Ext; shows an example
+"
+{
+//---------- initialisation ---------------------------------------------------
+  int k,max,ii,l,row,col,di;
+  module A,B,C,D,M1,M2,N1,ker,imag,extMN,extMN0;
+  matrix kb;
+  list L1,L2,L3,L,resM,K;
+  ideal  test1;
+  intmat Be;
+  int s = size(v);
+  max = Max(v);                   // the maximum integer occurring in intvec v
+  int p = printlevel-voice+3;     // p=printlevel+1 (default: p=1)
+//---------- test: coker(N)=basering, coker(N)=0 ? ----------------------------
+  if( max<0 ) { dbprint(p,"// Ext^i=0 for i<0!"); return([1]); }
+  N1 = std(N);
+  if( size(N1)==0 )      //coker(N)=basering, in this case proc Ext_R is faster
+  { printlevel=printlevel+1;
+    if( size(#)==0 )
+    { def E = Ext_R(v,M);
+      printlevel=printlevel-1;
+      return(E);
+    }
+    else
+    { def E = Ext_R(v,M,#[1]);
+       printlevel=printlevel-1;
+       return(E);
+     }
+  }
+  if( dim(N1)==-1 )                          //coker(N)=0, all Ext-groups are 0
+  { dbprint(p-1,"2nd module presents 0, hence Ext^k=0, for all k");
+    for( ii=1; ii<=s; ii++ )
+    { k=v[ii];
+      extMN    = gen(1);
+      extMN0   = std(extMN);
+      L1[ii] = extMN;
+      L2[ii] = extMN0;
+      L3[ii] = matrix(kbase(extMN0));
+      di=dim(extMN0);
+      dbprint(p,"// dimension of Ext^"+string(k)+":  "+string(di));
+      if (di==0)
+      {
+        dbprint(p,"// vdim of Ext^"+string(k)+":       "+string(vdim(extMN0)));
+      }
+      dbprint(p,"");
+    }
+  }
+  else
+  {
+    if( size(N1) < size(N) ) { N=N1;}
+    row = nrows(N);
+//---------- resolution of M -------------------------------------------------
+    resM = mres(M,max+1);
+    for( ii=1; ii<=s; ii++ )
+    { k=v[ii];
+      if( k<0  )                                   // Ext^k is 0 for negative k
+      { dbprint(p-1,"// Ext^k=0 for k<0!");
+        extMN    = gen(1);
+        extMN0   = std(extMN);
+        L1[ii] = extMN;
+        L2[ii] = extMN0;
+        L3[ii] = matrix(kbase(extMN0));
+        di=dim(extMN0);
+        dbprint(p,"// dimension of Ext^"+string(k)+":  "+string(di));
+        if (di==0)
+        {
+          dbprint(p,"// vdim of Ext^"+string(k)+":       "
+                  +string(vdim(extMN0)));
+        }
+        dbprint(p,"");
+      }
+      else
+      { M2 = resM[k+1];
+        if( k==0 ) { M1=0; }
+        else { M1 = resM[k]; }
+        col = nrows(M2);
+        D = kohom(N,col);
+//---------- computing homology ----------------------------------------------
+        imag  = kontrahom(M1,row);
+        A     = kontrahom(M2,row);
+        B     = kohom(N,ncols(M2));
+        ker   = modulo(A,B);
+        imag  = imag,D;
+        extMN = modulo(ker,imag);
+        dbprint(p-1,"// Computing Ext^"+string(k)+
+         " (help Ext; gives an explanation):",
+      "// Let 0<--coker(M)<--F0<--F1<--F2<--... be a resolution of coker(M),",
+      "// and 0<--coker(N)<--G0<--G1 a presentation of coker(N),",
+      "// then Hom(F"+string(k)+",G0)-->Hom(F"+string(k+1)+
+      ",G0) is given by:",A,
+      "// and Hom(F"+string(k-1)+",G0) + Hom(F"+string(k)+",G1)-->Hom(F"
+                                      +string(k)+",G0) is given by:",imag,"");
+        extMN0 = std(extMN);
+        di=dim(extMN0);
+        dbprint(p,"// dimension of Ext^"+string(k)+":  "+string(di));
+        if (di==0)
+        {
+          dbprint(p,"// vdim of Ext^"+string(k)+":       "
+                  +string(vdim(extMN0)));
+        }
+        dbprint(p,"");
+
+//---------- more information -------------------------------------------------
+        if( size(#)>0 )
+        { if( vdim(extMN0) >= 0 )
+          { kb = kbase(extMN0);
+            if ( size(ker)!=0) { kb = matrix(ker)*kb; }
+            dbprint(p-1,"// columns of matrix are kbase of Ext^"+
+                     string(k)+" in Hom(F"+string(k)+",G0)",kb,"");
+            if( p>0 )
+            { for (l=1;l<=ncols(kb);l=l+1)
+              {
+                "// element",l,"of kbase of Ext^"+string(k)+" in Hom(F"+string(k)+",G0)";
+                "// as matrix: F"+string(k)+"-->G0";
+                print(matrix(ideal(kb[l]),row,col));
+              }
+              "";
+            }
+            L3[ii] = matrix(kb);
+          }
+          L2[ii] = extMN0;
+        }
+        L1[ii] = extMN;
+      }
+    }
+  }
+  if( size(#) )
+  {  if( s>1 ) { L = L1,L2,L3; return(L); }
+     else { L = extMN,extMN0,matrix(kb); return(L); }
+  }
+  else
+  {  if( s>1 ) { return(L1); }
+     else { return(extMN); }
+  }
+}
+example
+{"EXAMPLE:";   echo=2;
+  int p      = printlevel;
+  printlevel = 1;
+  ring r     = 0,(x,y),dp;
+  ideal i    = x2-y3;
+  ideal j    = x2-y5;
+  list E     = Ext(0..2,i,j);    // Ext^k(r/i,r/j) for k=0,1,2 over r
+  qring R    = std(i);
+  ideal j    = fetch(r,j);
+  module M   = [-x,y],[-y2,x];
+  printlevel = 2;
+  module E1  = Ext(1,M,j);       // Ext^1(R^2/M,R/j) over R=r/i
+  list l     = Ext(4,M,M,1);     // Ext^4(R^2/M,R^2/M) over R=r/i
+  printlevel = p;
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc Hom (module M, module N, list #)
+"USAGE:   Hom(M,N,[any]);  M,N=modules
+COMPUTE: A presentation of Hom(M',N'), M'=coker(M), N'=coker(N) as follows:
+         let
+ at example
+   F1 --M-> F0 -->M' --> 0,    G1 --N-> G0 --> N' --> 0
+ at end example
+         be presentations of M' and N'. Consider
+ at example
+                                  0               0
+                                  |^              |^
+       0 --> Hom(M',N') ----> Hom(F0,N') ----> Hom(F1,N')
+                                  |^              |^
+  (A:  induced by M)          Hom(F0,G0) --A-> Hom(F1,G0)
+                                  |^              |^
+  (B,C:induced by N)              |C              |B
+                              Hom(F0,G1) ----> Hom(F1,G1)
+
+ at end example
+         Let D=modulo(A,B) and Hom=modulo(D,C), then we have exact sequences
+ at example
+   R^p  --D-> Hom(F0,G0) --A-> Hom(F1,G0)/im(B),
+
+ R^q -Hom-> R^p --D-> Hom(F0,G0)/im(C) --A-> Hom(F1,G0)/im(B).
+ at end example
+         Hence Hom presents Hom(M',N')
+RETURN:  module Hom, a presentation of Hom(M',N'), resp., in case of
+         3 arguments, a list l (of size <=3):
+ at format
+           - l[1] = Hom
+           - l[2] = SB of Hom
+           - l[3] = kbase of coker(Hom) (if finite dimensional, not 0),
+                    represented by elements in Hom(F0,G0) via mapping D
+ at end format
+DISPLAY: printlevel >=0: (affine) dimension of Hom  (default)
+@*       printlevel >=1: D and C and kbase of coker(Hom) in Hom(F0,G0)
+@*       printlevel >=2: elements of kbase of coker(Hom) as matrix :F0-->G0
+NOTE:    DISPLAY is as described only for a direct call of 'Hom'. Calling 'Hom'
+         from another proc has the same effect as decreasing printlevel by 1.
+EXAMPLE: example Hom;  shows examples
+"
+{
+//---------- initialisation ---------------------------------------------------
+  int l,p,di;
+  matrix kb;
+  module A,B,C,D,homMN,homMN0;
+  list L;
+//---------- computation of Hom -----------------------------------------------
+  B = kohom(N,ncols(M));
+  A = kontrahom(M,nrows(N));
+  C = kohom(N,nrows(M));
+  D = modulo(A,B);
+  homMN = modulo(D,C);
+  homMN0= std(homMN);
+  p = printlevel-voice+3;       // p=printlevel+1 (default: p=1)
+  di= dim(homMN0);
+  dbprint(p,"// dimension of Hom:  "+string(di));
+  if (di==0)
+  {
+    dbprint(p,"// vdim of Hom:       "+string(vdim(homMN0)));
+  }
+  dbprint(p,"");
+  dbprint(p-1,
+   "// given  F1 --M-> F0 -->M'--> 0 and  G1 --N-> G0 -->N'--> 0,",
+   "// show D = ker( Hom(F0,G0) --> Hom(F1,G0)/im(Hom(F1,G1)->Hom(F1,G0)) )",D,
+   "// show C = im ( Hom(F0,G1) --> Hom(F0,G0) )",C,"");
+//---------- extra output if size(#)>0 ----------------------------------------
+  if( size(#)>0 )
+  {
+     if( vdim(homMN0)>0 )
+     {
+        kb = kbase(homMN0);
+        kb = matrix(D)*kb;
+        if( p>2 )
+        {
+          for (l=1;l<=ncols(kb);l=l+1)
+          {
+            "// element",l,"of kbase of Hom in Hom(F0,G0) as matrix: F0-->G0:";
+             print(matrix(ideal(kb[l]),nrows(N),nrows(M)));
+          }
+        }
+        else
+        {
+          dbprint(p-1,"// columns of matrix are kbase of Hom in Hom(F0,G0)",
+                      kb);
+        }
+        L=homMN,homMN0,kb;
+        return(L);
+     }
+     L=homMN,homMN0;
+     return(L);
+  }
+  return(homMN);
+}
+example
+{"EXAMPLE:";  echo = 2;
+  int p     = printlevel;
+  printlevel= 1;   //in 'example proc' printlevel has to be increased by 1
+  ring r    = 0,(x,y),dp;
+  ideal i   = x2-y3,xy;
+  qring q   = std(i);
+  ideal i   = fetch(r,i);
+  module M  = [-x,y],[-y2,x],[x3];
+  module H  = Hom(M,i);
+  print(H);
+
+  printlevel= 2;
+  list L    = Hom(M,i,1);"";
+
+  printlevel=1;
+  ring s    = 3,(x,y,z),(c,dp);
+  ideal i   = jacob(ideal(x2+y5+z4));
+  qring rq=std(i);
+  matrix M[2][2]=xy,x3,5y,4z,x2;
+  matrix N[3][2]=x2,x,y3,3xz,x2z,z;
+  print(M);
+  print(N);
+  list l=Hom(M,N,1);
+  printlevel = p;
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc homology (matrix A,matrix B,module M,module N,list #)
+"USAGE:   homology(A,B,M,N);
+COMPUTE: Let M and N be submodules of R^m and R^n presenting M'=R^m/M, N'=R^n/N
+         (R=basering) and let A,B matrices inducing maps
+ at example
+    R^k --A--> R^m --B--> R^n.
+ at end example
+         Compute a presentation of the module
+ at example
+    ker(B)/im(A) := ker(M'/im(A) --B--> N'/im(BM)+im(BA)).
+ at end example
+         If B induces a map M'-->N' (i.e BM=0) and if im(A) is contained in
+         ker(B) (that is, BA=0) then ker(B)/im(A) is the homology of the
+         complex
+ at example
+    R^k--A-->M'--B-->N'.
+ at end example
+RETURN:  module H, a presentation of ker(B)/im(A).
+NOTE:    homology returns a free module of rank m if ker(B)=im(A).
+EXAMPLE: example homology; shows examples
+"
+{
+  module ker,ima;
+  ker = modulo(B,N);
+  ima = A,M;
+  return(modulo(ker,ima));
+}
+example
+{"EXAMPLE";    echo=2;
+  ring r;
+  ideal id=maxideal(4);
+  qring qr=std(id);
+  module N=maxideal(3)*freemodule(2);
+  module M=maxideal(2)*freemodule(2);
+  module B=[2x,0],[x,y],[z2,y];
+  module A=M;
+  module H=homology(A,B,M,N);
+  H=std(H);
+  // dimension of homology:
+  dim(H);
+  // vector space dimension:
+  vdim(H);
+
+  ring s=0,x,ds;
+  qring qs=std(x4);
+  module A=[x];
+  module B=A;
+  module M=[x3];
+  module N=M;
+  homology(A,B,M,N);
+}
+//////////////////////////////////////////////////////////////////////////////
+
+proc hom_kernel (matrix A,module M,module N)
+"USAGE:   hom_kernel(A,M,N);
+COMPUTE: Let M and N be submodules of R^m and R^n, presenting M'=R^m/M,
+         N'=R^n/N (R=basering), and let A:R^m-->R^n be a matrix inducing a
+         map A':M'-->N'. Then ker(A,M,N); computes a presentation K of
+         ker(A') as in the commutative diagram:
+ at example
+          ker(A') --->  M' --A'--> N'
+             |^         |^         |^
+             |          |          |
+             R^r  ---> R^m --A--> R^n
+             |^         |^         |^
+             |K         |M         |N
+             |          |          |
+             R^s  ---> R^p -----> R^q
+ at end example
+RETURN:  module K, a presentation of ker(A':coker(M)->coker(N)).
+EXAMPLE: example hom_kernel; shows examples.
+"
+{
+  module M1 = modulo(A,N);
+  return(modulo(M1,M));
+}
+example
+{"EXAMPLE";    echo=2;
+  ring r;
+  module N=[2x,x],[0,y];
+  module M=maxideal(1)*freemodule(2);
+  matrix A[2][3]=2x,0,x,y,z2,y;
+  module K=hom_kernel(A,M,N);
+  // dimension of kernel:
+  dim(std(K));
+  // vector space dimension of kernel:
+  vdim(std(K));
+  print(K);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc kohom (matrix M, int j)
+"USAGE:   kohom(A,k); A=matrix, k=integer
+RETURN:  matrix Hom(R^k,A), i.e. let A be a matrix defining a map F1-->F2
+         of free R-modules, then the matrix of Hom(R^k,F1)-->Hom(R^k,F2)
+         is computed (R=basering).
+EXAMPLE: example kohom; shows an example.
+"
+{
+  if (j==1)
+  { return(M);}
+  if (j>1)
+  { return(tensor(M,diag(1,j))); }
+  else { return(0);}
+}
+example
+{"EXAMPLE:";   echo=2;
+  ring r;
+  matrix n[2][3]=x,y,5,z,77,33;
+  print(kohom(n,3));
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc kontrahom (matrix M, int j)
+"USAGE:   kontrahom(A,k); A=matrix, k=integer
+RETURN:  matrix Hom(A,R^k), i.e. let A be a matrix defining a map F1-->F2 of
+         free  R-modules, then the matrix of Hom(F2,R^k)-->Hom(F1,R^k) is
+         computed (R=basering).
+EXAMPLE: example kontrahom; shows an example.
+"
+{
+if (j==1)
+  { return(transpose(M));}
+  if (j>1)
+  { return(transpose(tensor(diag(1,j),M)));}
+  else { return(0);}
+}
+example
+{"EXAMPLE:";  echo=2;
+  ring r;
+  matrix n[2][3]=x,y,5,z,77,33;
+  print(kontrahom(n,3));
+}
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+
+proc tensorMod(module Phi, module Psi)
+"USAGE:   tensorMod(M,N);  M,N modules
+COMPUTE: presentation matrix A of the tensor product T of the modules
+         M'=coker(M), N'=coker(N): if matrix(M) defines a map M: R^r-->R^s and
+         matrix(N) defines a map N: R^p-->R^q, then A defines a presentation
+ at example
+         R^(sp+rq) --A-> R^(sq)  --> T --> 0 .
+ at end example
+RETURN:  matrix A satisfying coker(A) = tensorprod(coker(M),coker(N)) .
+EXAMPLE: example tensorMod; shows an example.
+"
+{
+   int s=nrows(Phi);
+   int q=nrows(Psi);
+   matrix A=tensor(unitmat(s),Psi);
+   matrix B=tensor(Phi,unitmat(q));
+   matrix R=concat(A,B);
+   return(R);
+}
+example
+{"EXAMPLE:";  echo=2;
+  ring A=0,(x,y,z),dp;
+  matrix M[3][3]=1,2,3,4,5,6,7,8,9;
+  matrix N[2][2]=x,y,0,z;
+  print(M);
+  print(N);
+  print(tensorMod(M,N));
+}
+///////////////////////////////////////////////////////////////////////////////
+proc Tor(intvec v, module M, module N, list #)
+"USAGE:   Tor(v,M,N[,any]);  v int resp. intvec, M,N modules
+COMPUTE: a presentation of Tor_k(M',N'), for k=v[1],v[2],... , where
+         M'=coker(M) and N'=coker(N): let
+ at example
+       0 <-- M' <-- G0 <-M-- G1
+       0 <-- N' <-- F0 <--N- F1 <-- F2 <--...
+ at end example
+         be a presentation of M', resp. a free resolution of N', and consider
+         the commutative diagram
+ at example
+          0                    0                    0
+          |^                   |^                   |^
+  Tensor(M',Fk+1) -Ak+1-> Tensor(M',Fk) -Ak-> Tensor(M',Fk-1)
+          |^                   |^                   |^
+  Tensor(G0,Fk+1) -Ak+1-> Tensor(G0,Fk) -Ak-> Tensor(G0,Fk-1)
+                               |^                   |^
+                               |C                   |B
+                          Tensor(G1,Fk) ----> Tensor(G1,Fk-1)
+
+       (Ak,Ak+1 induced by N and B,C induced by M).
+ at end example
+         Let K=modulo(Ak,B), J=module(C)+module(Ak+1) and Tor=modulo(K,J),
+         then we have exact sequences
+ at example
+    R^p  --K-> Tensor(G0,Fk) --Ak-> Tensor(G0,Fk-1)/im(B),
+
+    R^q -Tor-> R^p --K-> Tensor(G0,Fk)/(im(C)+im(Ak+1)).
+ at end example
+         Hence, Tor presents Tor_k(M',N').
+RETURN:  - if v is of type int: module Tor, a presentation of Tor_k(M',N');@*
+         - if v is of type intvec: a list of Tor_k(M',N') (k=v[1],v[2],...);@*
+         - in case of a third argument of any type: list l with
+ at format
+     l[1] = module Tor/list of Tor_k(M',N'),
+     l[2] = SB of Tor/list of SB of Tor_k(M',N'),
+     l[3] = matrix/list of matrices, each representing a kbase of Tor_k(M',N')
+                (if finite dimensional), or 0.
+ at end format
+DISPLAY: printlevel >=0: (affine) dimension of Tor_k for each k  (default).
+@*       printlevel >=1: matrices Ak, Ak+1 and kbase of Tor_k in Tensor(G0,Fk)
+         (if finite dimensional).
+NOTE:    In order to compute Tor_k(M,N) use the command Tor(k,syz(M),syz(N));
+         or: list P=mres(M,2); list Q=mres(N,2); Tor(k,P[2],Q[2]);
+EXAMPLE: example Tor; shows an example
+{
+//---------- initialisation ---------------------------------------------------
+  int k,max,ii,l,row,col,di;
+  module A,B,C,D,N1,N2,M1,ker,imag,Im,Im1,Im2,f,torMN,torMN0;
+  matrix kb;
+  list L1,L2,L3,L,resN,K;
+  ideal  test1;
+  intmat Be;
+  int s = size(v);
+  max = Max(v);                  // maximum integer occurring in intvec v
+  int p = printlevel-voice+3;    // p=printlevel+1 (default: p=1)
+
+//---------- test: coker(M)=basering, coker(M)=0 ? ----------------------------
+  if( max<0 ) { dbprint(p,"// Tor_i=0 for i<0!"); return([1]); }
+  M1 = std(M);
+
+  if( size(M1)==0 or size(N)==0 )  // coker(M)=basering ==> Tor_i=0 for i>0
+  {
+    dbprint(p-1,"// one of the modules M',N' is free, hence Tor_i=0 for i<>0");
+    for( ii=1; ii<=s; ii++ )
+    {
+      k=v[ii];
+      if (k==0) { torMN=module(tensorMod(M1,N)); }
+      else { torMN  = gen(1); }
+      torMN0 = std(torMN);
+      L1[ii] = torMN;
+      L2[ii] = torMN0;
+      L3[ii] = matrix(kbase(torMN0));
+      di=dim(torMN0);
+      dbprint(p,"// dimension of Tor_"+string(k)+":  "+string(di));
+      if (di==0)
+      {
+        dbprint(p,"// vdim of Tor_"+string(k)+":       "
+                  +string(vdim(torMN0)));
+      }
+      dbprint(p,"");
+    }
+
+    if( size(#) )
+    {  if( s>1 ) { L = L1,L2,L3; return(L); }
+       else { L = torMN,torMN0,L3[1]; return(L); }
+    }
+    else
+    {  if( s>1 ) { return(L1); }
+       else { return(torMN); }
+    }
+  }
+
+  if( dim(M1)==-1 )              // coker(M)=0, all Tor's are 0
+  { dbprint(p-1,"2nd module presents 0, hence Tor_k=0, for all k");
+    for( ii=1; ii<=s; ii++ )
+    { k=v[ii];
+      torMN    = gen(1);
+      torMN0   = std(torMN);
+      L1[ii] = torMN;
+      L2[ii] = torMN0;
+      L3[ii] = matrix(kbase(torMN0));
+      di=dim(torMN0);
+      dbprint(p,"// dimension of Tor_"+string(k)+":  "+string(di));
+      if (di==0)
+      {
+        dbprint(p,"// vdim of Tor_"+string(k)+":       "
+                  +string(vdim(torMN0)));
+      }
+      dbprint(p,"");
+    }
+  }
+  else
+  {
+    if( size(M1) < size(M) ) { M=M1;}
+    row = nrows(M);
+//---------- resolution of N -------------------------------------------------
+    resN = mres(N,max+1);
+    for( ii=1; ii<=s; ii++ )
+    { k=v[ii];
+      if( k<0  )                             // Tor_k is 0 for negative k
+      { dbprint(p-1,"// Tor_k=0 for k<0!");
+        torMN  = gen(1);
+        torMN0 = std(torMN);
+        L1[ii] = torMN;
+        L2[ii] = torMN0;
+        L3[ii] = matrix(kbase(torMN0));
+        di=dim(torMN0);
+        dbprint(p,"// dimension of Tor_"+string(k)+":  "+string(di));
+        if (di==0)
+        {
+          dbprint(p,"// vdim of Tor_"+string(k)+":       "
+                    +string(vdim(torMN0)));
+        }
+        dbprint(p,"");
+      }
+      else
+      {
+        N2 = resN[k+1];
+        if( k==0 ) { torMN=module(tensorMod(M,N)); }
+        else
+        {
+          N1 = resN[k];
+          col = ncols(N1);
+
+//---------- computing homology ----------------------------------------------
+          imag = tensor(unitmat(nrows(N1)),M);
+          f = tensor(matrix(N1),unitmat(row));
+          Im1 = tensor(unitmat(col),M);
+          Im2 = tensor(matrix(N2),unitmat(row));
+          ker = modulo(f,imag);
+          Im  = Im2,Im1;
+          torMN = modulo(ker,Im);
+          dbprint(p-1,"// Computing Tor_"+string(k)+
+                      " (help Tor; gives an explanation):",
+          "// Let 0 <- coker(M) <- G0 <-M- G1 be the present. of coker(M),",
+          "// and 0 <- coker(N) <- F0 <-N- F1 <- F2 <- ... a resolution of",
+          "// coker(N), then Tensor(G0,F"+string(k)+")-->Tensor(G0,F"+
+          string(k-1)+") is given by:",f,
+          "// and Tensor(G0,F"+string(k+1)+") + Tensor(G1,F"+string(k)+
+          ")-->Tensor(G0,F"+string(k)+") is given by:",Im,"");
+        }
+
+        torMN0 = std(torMN);
+        di=dim(torMN0);
+        dbprint(p,"// dimension of Tor_"+string(k)+":  "+string(di));
+        if (di==0)
+        {
+          dbprint(p,"// vdim of Tor_"+string(k)+":       "
+                    +string(vdim(torMN0)));
+        }
+        dbprint(p,"");
+
+//---------- more information -------------------------------------------------
+        if( size(#)>0 )
+        { if( vdim(torMN0) >= 0 )
+          { kb = kbase(torMN0);
+            if ( size(ker)!=0) { kb = matrix(ker)*kb; }
+            dbprint(p-1,"// columns of matrix are kbase of Tor_"+
+                     string(k)+" in Tensor(G0,F"+string(k)+")",kb,"");
+            L3[ii] = matrix(kb);
+          }
+          L2[ii] = torMN0;
+        }
+        L1[ii] = torMN;
+      }
+    }
+  }
+  if( size(#) )
+  {  if( s>1 ) { L = L1,L2,L3; return(L); }
+     else { L = torMN,torMN0,matrix(kb); return(L); }
+  }
+  else
+  {  if( s>1 ) { return(L1); }
+     else { return(torMN); }
+  }
+}
+example
+{"EXAMPLE:";   echo=2;
+  int p      = printlevel;
+  printlevel = 1;
+  ring r     = 0,(x,y),dp;
+  ideal i    = x2,y;
+  ideal j    = x;
+  list E     = Tor(0..2,i,j);    // Tor_k(r/i,r/j) for k=0,1,2 over r
+
+  qring R    = std(i);
+  ideal j    = fetch(r,j);
+  module M   = [x,0],[0,x];
+  printlevel = 2;
+  module E1  = Tor(1,M,j);       // Tor_1(R^2/M,R/j) over R=r/i
+
+  list l     = Tor(3,M,M,1);     // Tor_3(R^2/M,R^2/M) over R=r/i
+  printlevel = p;
+}
+///////////////////////////////////////////////////////////////////////////////
+proc fitting(module M, int n)
+"USAGE:   fitting (M,n);  M module, n int
+RETURN:  ideal, (standard basis of) n-th Fitting ideal of M'=coker(M).
+EXAMPLE: example fitting; shows an example
+"
+{
+  n=nrows(M)-n;
+  if(n<=0){return(ideal(1));}
+  if((n>nrows(M))||(n>ncols(M))){return(ideal(0));}
+  return(std(minor(M,n)));
+}
+example
+{"EXAMPLE:";   echo=2;
+  ring R=0,x(0..4),dp;
+  matrix M[2][4]=x(0),x(1),x(2),x(3),x(1),x(2),x(3),x(4);
+  print(M);
+  fitting(M,-1);
+  fitting(M,0);
+  fitting(M,1);
+  fitting(M,2);
+}
+///////////////////////////////////////////////////////////////////////////////
+proc isLocallyFree(matrix S, int r)
+"USAGE:   isLocallyFree(M,r);  M module, r int
+RETURN:  1 if M'=coker(M) is locally free of constant rank r;@*
+         0 if this is not the case.
+EXAMPLE: example isLocallyFree; shows an example.
+"
+{
+   ideal F=fitting(S,r);
+   ideal G=fitting(S,r-1);
+   if((deg(F[1])==0)&&(size(G)==0)){return(1);}
+   return(0);
+}
+example
+{"EXAMPLE:";   echo=2;
+  ring R=0,(x,y,z),dp;
+  matrix M[2][3];     // the presentation matrix
+  M=x-1,y-1,z,y-1,x-2,x;
+  ideal I=fitting(M,0); // 0-th Fitting ideal of coker(M)
+  qring Q=I;
+  matrix M=fetch(R,M);
+  isLocallyFree(M,1); // as R/I-module, coker(M) is locally free of rk 1
+  isLocallyFree(M,0);
+}
+///////////////////////////////////////////////////////////////////////////////
+proc flatteningStrat (module M)
+"USAGE:   flatteningStrat(M);  M module
+RETURN:  list of ideals.
+         The list entries L[1],...,L[r] describe the flattening stratification
+         of M'=coker(M): setting L[0]=0, L[r+1]=1, the flattening
+         stratification is given by the open sets Spec(A/V(L[i-1])) \ V(L[i]),
+         i=1,...,r+1  (A = basering).
+NOTE:    for more information see the book 'A Singular Introduction to
+         Commutative Algebra' (by Greuel/Pfister, Springer 2002).
+EXAMPLE: example flatteningStrat; shows an example
+"
+{
+   list l;
+   int v,w;
+   ideal F;
+   while(1)
+   {
+      F=interred(fitting(M,w));
+      if(F[1]==1){return(l);}
+      if(size(F)!=0){v++;l[v]=F;}
+      w++;
+   }
+   return(l);
+}
+example
+{"EXAMPLE:";   echo=2;
+  ring A = 0,x(0..4),dp;
+  // presentation matrix:
+  matrix M[2][4] = x(0),x(1),x(2),x(3),x(1),x(2),x(3),x(4);
+  list L = flatteningStrat(M);
+  L;
+}
+///////////////////////////////////////////////////////////////////////////////
+proc isFlat(module M)
+"USAGE:   isFlat(M);  M module
+RETURN:  1 if M'=coker(M) is flat;@*
+         0 if this is not the case.
+EXAMPLE: example isFlat; shows an example.
+"
+{
+   if (size(ideal(M))==0) {return(1);}
+   int w;
+   ideal F=fitting(M,0);
+   while(size(F)==0)
+   {
+      w++;
+      F=fitting(M,w);
+   }
+   if (deg(std(F)[1])==0) {return(1);}
+   return(0);
+}
+example
+{"EXAMPLE:";   echo=2;
+  ring A = 0,(x,y),dp;
+  matrix M[3][3] = x-1,y,x,x,x+1,y,x2,xy+x+1,x2+y;
+  print(M);
+  isFlat(M);             // coker(M) is not flat over A=Q[x,y]
+
+  qring B = std(x2+x-y);   // the ring B=Q[x,y]/<x2+x-y>
+  matrix M = fetch(A,M);
+  isFlat(M);             // coker(M) is flat over B
+
+  setring A;
+  qring C = std(x2+x+y);   // the ring C=Q[x,y]/<x2+x+y>
+  matrix M = fetch(A,M);
+  isFlat(M);             // coker(M) is not flat over C
+}
+///////////////////////////////////////////////////////////////////////////////
+proc flatLocus(module M)
+"USAGE:   flatLocus(M);  M module
+RETURN:  ideal I, s.th. complement of V(I) is flat locus of coker(M).
+NOTE:    computation is based on Fitting ideals;@*
+         output is not radical (in general)
+EXAMPLE: example flatLocus; shows an example
+"
+{
+   if (size(ideal(M))==0) {return(ideal(1));}
+   int v,w;
+   ideal F=fitting(M,0);
+   while(size(F)==0)
+   {
+      w++;
+      F=fitting(M,w);
+   }
+   if(typeof(basering)=="qring")
+   {
+      for(v=w+1;v<=nrows(M);v++)
+      {
+         F=F+intersect(fitting(M,v),quotient(ideal(0),fitting(M,v-1)));
+      }
+   }
+   return(interred(F));
+}
+example
+{"EXAMPLE:";   echo=2;
+  ring R=0,(x,y,z),dp;
+  matrix M[2][3]=x,y,z,0,x3,z3;
+  ideal I=flatLocus(M); // coker(M) is flat outside V(x,yz)
+  I;                    // computed ideal not radical
+  ideal J=radical(I);
+  J;
+
+  qring r=std(J);
+  matrix M=fetch(r,M);
+  flatLocus(M);         // coker(M) is flat over Spec(Q[x,y,z]/<x,yz>)
+
+  isFlat(M);            // flatness test
+}
+///////////////////////////////////////////////////////////////////////////////
+proc isReg(ideal I, module N)
+"USAGE:   isReg(I,M);  I ideal, M module
+RETURN:  1 if given (ordered) list of generators for I is coker(M)-sequence;@*
+         0 if this is not the case.
+EXAMPLE: example isReg; shows an example.
+"
+{
+  int n=nrows(N);
+  int i;
+  while(i<ncols(I))
+  {
+     i++;
+     N=std(N);
+     if(size(reduce(quotient(N,I[i]),N))!=0){return(0);}
+     N=N+I[i]*freemodule(n);
+  }
+  if (size(reduce(freemodule(n),std(N)))==0){return(0);}
+  return(1);
+}
+example
+{"EXAMPLE:";   echo=2;
+  ring R = 0,(x,y,z),dp;
+  ideal I = x*(y-1),y,z*(y-1);
+  isReg(I,0);             // given list of generators is Q[x,y,z]-sequence
+
+  I = x*(y-1),z*(y-1),y;  // change sorting of generators
+  isReg(I,0);
+
+  ring r = 0,(x,y,z),ds;  // local ring
+  ideal I=fetch(R,I);
+  isReg(I,0);             // result independent of sorting of generators
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// the following static procedures are used by KoszulHomology:
+//  * binom_int  (binomial coeff. as integer, or -1 if too large)
+//  * basisNumber
+//  * basisElement
+//  * KoszulMap
+// for details, see 'A Singular Introduction to Commutative Algebra' (by
+// Greuel/Pfister, Springer 2002), Chapter 7
+
+static proc binom_int(int n, int p)
+{
+  bigint s = binomial(n,p);
+  int a=int(s);
+  if ((s!=0)&&(a==0)) { return(-1); }
+  return(a);
+}
+
+static proc basisNumber(int n,intvec v)
+{
+  int p=size(v);
+  if(p==1){return(v[1]);}
+  int j=n-1;
+  int b;
+  while(j>=n-v[1]+1)
+  {
+    b=b+binom_int(j,p-1);
+    j--;
+  }
+  intvec w=v-v[1];
+  w=w[2..size(w)];
+  b=b+basisNumber(n-v[1],w);
+  return(b);
+}
+
+static proc basisElement(int n,int p,int N)
+{
+  if(p==1){return(N);}
+  int s,R;
+  while(R<N)
+  {
+     s++;
+     R=R+binom_int(n-s,p-1);
+  }
+  R=N-R+binom_int(n-s,p-1);
+  intvec v=basisElement(n-s,p-1,R);
+  intvec w=s,v+s;
+  return(w);
+}
+
+proc KoszulMap(ideal x,int p)
+{
+  int n=size(x);
+  int a=binom_int(n,p-1);
+  int b=binom_int(n,p);
+
+  matrix M[a][b];
+
+  if(p==1){M=x;return(M);}
+  int j,k;
+  intvec v,w;
+  for(j=1;j<=b;j++)
+  {
+    v=basisElement(n,p,j);
+    w=v[2..p];
+    M[basisNumber(n,w),j]=x[v[1]];
+    for(k=2;k<p;k++)
+    {
+      w=v[1..k-1],v[k+1..p];
+      M[basisNumber(n,w),j]=(-1)^(k-1)*x[v[k]];
+    }
+    w=v[1..p-1];
+    M[basisNumber(n,w),j]=(-1)^(p-1)*x[v[p]];
+  }
+  return(M);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc KoszulHomology(ideal x, module M, int p)
+"USAGE:   KoszulHomology(I,M,p);  I ideal, M module, p int
+COMPUTE: A presentation of the p-th Koszul homology module H_p(f_1,...,f_k;M'),
+         where M'=coker(M) and f_1,...,f_k are the given (ordered list
+         of non-zero) generators of the ideal I.
+         The computed presentation is minimized via prune.
+         In particular, if H_p(f_1,...,f_k;M')=0 then the return value is 0.
+RETURN:  module H, s.th. coker(H) = H_p(f_1,...,f_k;M').
+NOTE:    size of input ideal has to be <= 20.
+EXAMPLE: example KoszulHomology; shows an example.
+{
+  x=simplify(x,2);
+  int n     = size(x);
+  if (n==0)
+  {
+    ERROR("// KoszulHomology only for non-zero ideals");
+  }
+  if (n>20)
+  {
+    ERROR("// too many generators in input ideal");
+  }
+  if (p>n)
+  {
+    module hom=0;
+    return(hom);
+  }
+
+  int a     = binom_int(n,p-1);  // n over p-1 independent of char(basering)
+  int b     = binom_int(n,p);
+
+  matrix N  = matrix(M);
+  module ker= freemodule(nrows(N));
+  if(p!=0)
+  {
+    module im= tensor(unitmat(a),N);
+    module f = tensor(KoszulMap(x,p),unitmat(nrows(N)));
+    ker      = modulo(f,im);
+  }
+  module im1 = tensor(unitmat(b),N);
+  module im2 = tensor(KoszulMap(x,p+1),unitmat(nrows(N)));
+  module hom = modulo(ker,im1+im2);
+  hom        = prune(hom);
+  return(hom);
+}
+example
+{"EXAMPLE:";   echo=2;
+  ring R=0,x(1..3),dp;
+  ideal x=maxideal(1);
+  module M=0;
+  KoszulHomology(x,M,0);  // H_0(x,R), x=(x_1,x_2,x_3)
+
+  KoszulHomology(x,M,1);  // H_1(x,R), x=(x_1,x_2,x_3)
+
+  qring S=std(x(1)*x(2));
+  module M=0;
+  ideal x=maxideal(1);
+  KoszulHomology(x,M,1);
+
+  KoszulHomology(x,M,2);
+}
+///////////////////////////////////////////////////////////////////////////////
+proc depth(module M,ideal #)
+"USAGE:   depth(M,[I]);  M module, I ideal
+RETURN:  int,
+         - if called with 1 argument: the depth of M'=coker(M) w.r.t. the
+         maxideal in the basering (which is then assumed to be local)@*
+         - if called with 2 arguments: the depth of M'=coker(M) w.r.t. the
+         ideal I.
+NOTE:    procedure makes use of KoszulHomology.
+EXAMPLE: example depth; shows an example.
+"
+{
+  ideal m=maxideal(1);
+  int n=size(m);
+  int i;
+
+  if (size(#)==0)
+  {
+    // depth(M') over local basering
+    while(i<n)
+    {
+      i++;
+      if(size(KoszulHomology(m,M,i))==0){return(n-i+1);}
+    }
+    return(0);
+  }
+
+  ideal I=simplify(#,2);
+  while(i<size(I))
+  {
+    i++;
+    if(size(KoszulHomology(I,M,i))==0){return(size(I)-i+1);}
+  }
+  return(0);
+}
+example
+{"EXAMPLE:";   echo=2;
+  ring R=0,(x,y,z),dp;
+  ideal I=x2,xy,yz;
+  module M=0;
+  depth(M,I);   // depth(<x2,xy,yz>,Q[x,y,z])
+  ring r=0,(x,y,z),ds;  // local ring
+  matrix M[2][2]=x,xy,1+yz,0;
+  print(M);
+  depth(M);     // depth(maxideal,coker(M))
+  ideal I=x;
+  depth(M,I);   // depth(<x>,coker(M))
+  I=x+z;
+  depth(M,I);   // depth(<x+z>,coker(M))
+}
+
+///////////////////////////////////////////////////////////////////////////////
+proc isCM(module M)
+"USAGE:   isCM(M);  M module
+RETURN:  1 if M'=coker(M) is Cohen-Macaulay;@*
+         0 if this is not the case.
+ASSUME:  basering is local.
+EXAMPLE: example isCM; shows an example
+"
+{
+  // test if basering is local:
+  ideal m=maxideal(1);
+  int i;
+  poly f=1;
+  for (i=1; i<=size(m); i++)
+  {
+    f=f+m[i];
+  }
+  if (ord(f)>0)
+  {
+    print("// basering must be local -- result has no meaning");
+    return(0);
+  }
+
+  return(depth(M)==dim(std(Ann(M))));
+}
+example
+{"EXAMPLE:";   echo=2;
+  ring R=0,(x,y,z),ds;  // local ring R = Q[x,y,z]_<x,y,z>
+  module M=xz,yz,z2;
+  isCM(M);             // test if R/<xz,yz,z2> is Cohen-Macaulay
+
+  M=x2+y2,z7;          // test if R/<x2+y2,z7> is Cohen-Macaulay
+  isCM(M);
+}
+
+proc canonMap(list #)
+"USAGE:  canonMap(id); id= ideal/module,
+RETURN:  a list L, the kernel in two different representations and
+@*       the cokernel of the canonical map
+@*       M ---> Ext^c_R(Ext^c_R(M,R),R) given by presentations
+@*       Here M is the R-module (R=basering) given by the presentation
+@*       defined by id, i.e. M=R/id resp. M=R^n/id
+@*       c is the codimension of M
+@*       L[1] is the preimage of the kernel in R resp. R^n
+@*       L[2] is a presentation of the kernel
+@*       L[3] is a presentation of the cokernel
+EXAMPLE: example canonMap; shows an example
+"
+{
+   module M=#[1];
+   int c=nvars(basering)-dim(std(M));
+   if(c==0)
+   {
+      module K=syz(transpose(M));
+      module Ke=syz(transpose(K));
+      module Co=modulo(syz(transpose(syz(K))),transpose(K));
+    }
+   else
+   {
+      int i;
+      resolution F=mres(M,c+1);
+      module K=syz(transpose(F[c+1]));
+      K=simplify(reduce(K,std(transpose(F[c]))),2);
+      module A=modulo(K,transpose(F[c]));
+      resolution G=nres(A,c+1);
+      for(i=1;i<=c;i++)
+      {
+         K=lift(transpose(F[c-i+1]),K*G[i]);
+      }
+      module Ke=modulo(transpose(K),transpose(G[c]));
+      module Co=modulo(syz(transpose(G[c+1])),transpose(K)+transpose(G[c]));
+   }
+   return(list(Ke,prune(modulo(Ke,M)),prune(Co)));
+
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring s=0,(x,y),dp;
+   ideal i = x,y;
+   canonMap(i);
+   ring R = 0,(x,y,z,w),dp;
+   ideal I1 = x,y;
+   ideal I2 = z,w;
+   ideal I = intersect(I1,I2);
+   canonMap(I);
+   module M = syz(I);
+   canonMap(M);
+   ring S = 0,(x,y,z,t),Wp(3,4,5,1);
+   ideal I = x-t3,y-t4,z-t5;
+   ideal J = eliminate(I,t);
+   ring T = 0,(x,y,z),Wp(3,4,5);
+   ideal p = imap(S,J);
+   ideal p2 = p^2;
+   canonMap(p2);
+}
+
+// taken from qhmoduli.lib
+static proc Max(def data)
+"USAGE:   Max(data); intvec/list of integers
+PURPOSE: find the maximal integer contained in 'data'
+RETURN:  list
+ASSUME:  'data' contians only integers and is not empty
+"
+{
+  int i;
+  int max = data[1];
+
+  for(i = size(data); i>1;i--)
+  {
+    if(data[i] > max) { max = data[i]; }
+  }
+  return(max);
+}
+example
+{"EXAMPLE:";  echo = 2;
+  Max(list(1,2,3));
+}
diff --git a/Singular/LIB/hyperel.lib b/Singular/LIB/hyperel.lib
new file mode 100644
index 0000000..1547fb4
--- /dev/null
+++ b/Singular/LIB/hyperel.lib
@@ -0,0 +1,975 @@
+//////////////////////////////////////////////////////////////////////////////
+version="version hyperel.lib 4.0.0.0 Jun_2013 "; // $Id: c5138c4fc23f4b2d2fa03a8f7dfdd92b661521c1 $
+category="Teaching";
+info="
+LIBRARY:    hyperel.lib
+AUTHOR:     Markus Hochstetter, markushochstetter at gmx.de
+
+NOTE: The library provides procedures for computing with divisors in the
+      jacobian of hyperelliptic curves. In addition procedures are available
+      for computing the rational representation of divisors and vice versa.
+      The library is intended to be used for teaching and demonstrating
+      purposes but not for efficient computations.
+
+
+
+
+PROCEDURES:
+  ishyper(h,f)           test, if y^2+h(x)y=f(x) is hyperelliptic
+  isoncurve(P,h,f)       test, if point P is on C: y^2+h(x)y=f(x)
+  chinrestp(b,moduli)    compute polynom x, s.t. x=b[i] mod moduli[i]
+  norm(a,b,h,f)          norm of a(x)-b(x)y in IF[C]
+  multi(a,b,c,d,h,f)     (a(x)-b(x)y)*(c(x)-d(x)y)  in IF[C]
+  ratrep (P,h,f)         returns polynomials a,b, s.t. div(a,b)=P
+  divisor(a,b,h,f,[])    computes divisor of a(x)-b(x)y
+  gcddivisor(p,q)        gcd of the divisors p and q
+  semidiv(D,h,f)         semireduced divisor of the pair of polys D[1], D[2]
+  cantoradd(D,Q,h,f)     adding divisors of the hyperell. curve y^2+h(x)y=f(x)
+  cantorred(D,h,f)       returns reduced divisor which is equivalent to D
+  double(D,h,f)          computes 2*D on y^2+h(x)y=f(x)
+  cantormult(m,D,h,f)    computes m*D on y^2+h(x)y=f(x)
+
+              [parameters in square brackets are optional]
+";
+///////////////////////////////////////////////////////////////////////////////
+
+
+//=============== Test, if a given curve is hyperelliptic =====================
+
+proc ishyper(poly h, poly f)
+"USAGE:   ishyper(h,f); h,f=poly
+RETURN:  1 if y^2+h(x)y=f(x) is hyperelliptic, 0 otherwise
+NOTE:    Tests, if y^2+h(x)y=f(x) is a hyperelliptic curve.
+         Curve is defined over basering. Additionally shows error-messages.
+EXAMPLE: example ishyper; shows an example
+"
+{
+  // constructing a copy of the basering (only variable x),
+  // with variables x,y.
+  def R=basering;
+  list l= ringlist(R);
+  list ll=l[2];
+  ll="x","y";
+  l[2]=ll;
+  intvec v= l[3][1][2];
+  v=v,1;
+  l[3][1][2]=v;
+  def s=ring(l);
+  setring s;
+
+  // test, if y^2 + hy - f is hyperelliptic.
+  int i=1;
+  poly h=imap(R,h);
+  poly f=imap(R,f);
+  poly F=y2 + h*y - f;
+  ideal I=F, diff(F,x) , diff(F,y);
+  ideal J=std(I);
+  if ( J != 1 )
+  {
+      i=0;
+      "The curve is singular!";
+  }
+  if ( deg(f) mod 2 != 1 )
+  {
+     i=0;
+      "The polynomial ",f," has even degree!";
+  }
+  if ( leadcoef(f) != 1 )
+  {
+     i=0;
+     "The polynomial ",f," is not monic!";
+  }
+  if ( 2*deg(h) > deg(f)-1 )
+  {
+    i=0;
+     "The polynomial ",h," has degree ",deg(h),"!";
+  }
+  setring(R);
+  return(i);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring R=7,x,dp;
+   // hyperelliptic curve y^2 + h*y = f
+   poly h=x;
+   poly f=x5+5x4+6x2+x+3;
+   ishyper(h,f);
+}
+
+
+//================= Test, if a given ponit is on the curve ====================
+
+proc isoncurve(list P, poly h, poly f)
+"USAGE:   isoncurve(P,h,f); h,f=poly; P=list
+RETURN:  1 or 0 (if P is on curve or not)
+NOTE:    Tests, if P=(P[1],P[2]) is on the hyperelliptic curve y^2+h(x)y=f(x).
+         Curve is defined over basering.
+EXAMPLE: example isoncurve; shows an example
+"
+{
+   if ( P[2]^2 + subst(h,var(1),P[1])*P[2] - subst(f,var(1),P[1]) == 0 )
+   {
+      return(1);
+   }
+   return(0);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring R=7,x,dp;
+   // hyperelliptic curve y^2 + h*y = f
+   poly h=x;
+   poly f=x5+5x4+6x2+x+3;
+   list P=2,3;
+   isoncurve(P,h,f);
+}
+
+
+//====================== Remainder of a polynomial division ===================
+
+proc divrem(poly f,poly g)
+"USAGE:   divrem(f,g);  f,g poly
+RETURN:  remainder of the division f/g
+NOTE:    Computes R, s.t. f=a*g + R, and deg(R) < deg(g)
+EXAMPLE: example divrem; shows an example
+"
+{
+   return(reduce(f,std(g)));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring R=0,x,dp;
+   divrem(x2+1,x2);
+}
+
+
+//================ chinese remainder theorem for polynomials ==================
+
+proc chinrestp(list b,list moduli)
+"USAGE:   chinrestp(b,moduli); moduli, b, moduli=list of polynomials
+RETURN:  poly x, s.t. x= b[i] mod moduli[i]
+NOTE:    chinese remainder theorem for polynomials
+EXAMPLE: example chinrestp; shows an example
+"
+{
+   int i;
+   int n=size(moduli);
+   poly M=1;
+   for(i=1;i<=n;i++)
+   {
+      M=M*moduli[i];
+   }
+   list m;
+   for(i=1;i<=n;i++)
+   {
+      m[i]=M/moduli[i];
+   }
+   list y;
+   for(i=1;i<=n;i++)
+   {
+      y[i]= extgcd(moduli[i],m[i])[3];
+   }
+   poly B=0;
+   for(i=1;i<=n;i++)
+   {
+      B=B+y[i]*m[i]*b[i];
+   }
+   B=divrem(B,M);
+   return(B);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring R=7,x,dp;
+   list b=3x-4, -3x2+1, 1, 4;
+   list moduli=(x-2)^2, (x-5)^3, x-1, x-6;
+   chinrestp(b,moduli);
+}
+
+
+//========================= norm of a polynomial ===============================
+
+proc norm(poly a, poly b, poly h, poly f)
+"USAGE:   norm(a,b,h,f);
+RETURN:  norm of a(x)-b(x)y in IF[C]
+NOTE:    The norm is a polynomial in just one variable.
+         Curve C: y^2+h(x)y=f(x) is defined over basering.
+EXAMPLE: example norm; shows an example
+"
+{
+   poly n=a^2+a*b*h-b^2*f;
+   return(n);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring R=7,x,dp;
+   // hyperelliptic curve y^2 + h*y = f
+   poly h=x;
+   poly f=x5+5x4+6x2+x+3;
+   poly a=x2+1;
+   poly b=x;
+   norm(a,b,h,f);
+}
+
+
+//========== multiplikation of polynomials in the coordinate ring =============
+
+proc multi(poly a, poly b, poly c, poly d, poly h, poly f)
+"USAGE:   multi(a,b,c,d,h,f);
+RETURN:  list L with L[1]-L[2]y=(a(x)-b(x)y)*(c(x)-d(x)y) in IF[C]
+NOTE:    Curve C: y^2+h(x)y=f(x) is defined over basering.
+EXAMPLE: example multi; shows an example
+"
+{
+   poly A=a*c + b*d*f;
+   poly B=b*c +a*d + b*h*d;
+   return (list(A,B));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring R=7,x,dp;
+   poly h=x;
+   poly f=x5+5x4+6x2+x+3;
+   // hyperelliptic curve y^2 + h*y = f
+   poly a=x2+1;
+   poly b=x;
+   poly c=5;
+   poly d=-x;
+   multi(a,b,c,d,h,f);
+}
+
+
+//================== polynomial expansion around a point ========================
+
+proc darst(list P,int k, poly h, poly f)
+"USAGE:   darst(P,k,h,f);
+RETURN:  list c of length k
+NOTE:    expansion around point P in IF[C], s.t.
+         y=c[1]+c[2]*(x-P[1]) +...+c[k]*(x-P[1])^k-1 + rest.
+         Curve C:y^2+h(x)y=f(x) is defined over basering.
+EXAMPLE: example darst; shows an example
+"
+{
+
+   if ( P[2] == -P[2]- subst(h,var(1),P[1]))
+   {
+    ERROR("no special points allowed");
+   }
+   list c;
+   list r;
+   list n;
+   poly N;
+   c[1]=P[2];
+   r[1]=list(0,-1,1,0);
+   poly r1,r2,r3,r4;
+   // rational function are represented as (r1 - r2*y) / (r3 - r4*y)
+
+   for (int i=1; i<k ; i++)
+   {
+      r1=r[i][1]-c[i]*r[i][3];
+      r2=r[i][2]-c[i]*r[i][4];
+      r3=r[i][3];
+      r4=r[i][4];
+      n=multi(r3,r4,r1+r2*h,-r2,h,f);
+      N=r1*r1 + r1*r2*h-r2*r2*f;
+      r[i+1]=list(N/(var(1)-P[1]),0,n[1],n[2]);
+      while ((divrem(r[i+1][1],var(1)-P[1]) ==0) and (divrem(r[i+1][2],var(1)-P[1]) ==0) and (divrem(r[i+1][3],var(1)-P[1]) ==0) and (divrem(r[i+1][4],var(1)-P[1]) ==0))
+      {
+          // reducing the rationl function
+          //(r[i+1][1] - r[i+1][2]*y)/(r[i+1][3] - r[i+1][4]) , otherwise there
+          // could be a pole, s.t. conditions are not fulfilled.
+          r[i+1][1]=(r[i+1][1]) / (var(1)-P[1]);
+          r[i+1][2]=(r[i+1][2]) / (var(1)-P[1]);
+          r[i+1][3]=(r[i+1][3]) / (var(1)-P[1]);
+          r[i+1][4]=(r[i+1][4]) / (var(1)-P[1]);
+      }
+      c[i+1]=(subst(r[i+1][1],var(1),P[1]) - subst(r[i+1][2],var(1),P[1])*P[2]) / (subst(r[i+1][3],var(1),P[1]) - subst(r[i+1][4],var(1),P[1])*P[2]);
+   }
+   return(c);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring R=7,x,dp;
+   // hyperelliptic curve y^2 + h*y = f
+   poly h=x;
+   poly f=x5+5x4+6x2+x+3;
+   list P=5,3;
+   darst(P,3,h,f);
+}
+
+
+//================ rational representation of a divisor =======================
+
+proc ratrep1 (list P, poly h, poly f)
+"USAGE:   ratrep1(P,k,h,f);
+RETURN:  list (a,b)
+NOTE:    Important: P has to be semireduced!
+         Computes rational representation of the divisor
+         P[1][3]*(P[1][1], P[1][2]) +...+ P[sizeof(P)][3]*
+         *(P[sizeof(P)][1], P[sizeof(P)][2]) - (*)infty=div(a,b)
+         Divisor P has to be semireduced.
+         Curve C:y^2+h(x)y=f(x) is defined over basering.
+SEE AlSO: ratrep
+EXAMPLE: example ratrep1; shows an example
+"
+{
+   poly a=1;
+   list b;
+   list m;
+   list koef;
+   int k;
+
+   // Determination of the polynomial b[i] for each point using procedure darst
+   for (int i=1 ; i<= size(P); i++)
+   {
+      a=a*(var(1)-P[i][1])^(P[i][3]);    // computing polynomial a
+      m[i]=(var(1)-P[i][1])^(P[i][3]);
+      b[i]=P[i][2];
+      k=1;
+
+      while (divrem(b[i]*b[i] + b[i] *h - f,(var(1)-P[i][1])^(P[i][3])) != 0)
+      {
+          k=k+1;   // b[i]=P[i][2];
+          koef=darst(list (P[i][1],P[i][2]), k, h,f);
+          // could be improved, if one doesn't compute list coef completely new
+          // every time
+          b[i]=b[i]+ koef[k]*(var(1)-P[i][1])^(k-1);
+      }
+   }
+   // Return polynomial a and b. Polynomial b is solution of the congruencies
+   // b[i] mod m[i] .
+   return(list(a,chinrestp(b,m)));
+
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring R=7,x,dp;
+   // hyperelliptic curve y^2 + h*y = f
+   poly h=x;
+   poly f=x5+5x4+6x2+x+3;
+   //divisor P
+   list P=list(-1,-3,1),list(1,1,1);
+   ratrep1(P,h,f);
+}
+
+
+//================ rational representation of a divisor =======================
+
+proc ratrep (list P, poly h, poly f)
+"USAGE:   ratrep(P,k,h,f);
+RETURN:  list (a,b)
+NOTE:    Importatnt: P has to be semireduced!
+         Computes rational representation of the divisor
+         P[1][3]*(P[1][1], P[1][2]) +...+ P[sizeof(P)][3]*
+         *(P[sizeof(P)][1], P[sizeof(P)][2]) - (*)infty=div(a,b)
+         Divisor P has to be semireduced.
+         Curve C:y^2+h(x)y=f(x) is defined over basering.
+         Works faster than ratrep1.
+SEE ALSO: ratrep1
+EXAMPLE: example ratrep; shows an example
+"
+{
+   poly a=1;
+   list b;
+   list m;
+   list koef;
+   int k;
+
+   poly c;
+   list r;
+   list n;
+   poly Norm;
+   poly r1,r2,r3,r4;
+
+   // Determination of the polynomial b[i] for each point using procedure darst
+   for (int i=1 ; i<= size(P); i++)
+   {
+      a=a*(var(1)-P[i][1])^(P[i][3]);     // computing polynomial a
+      m[i]=(var(1)-P[i][1])^(P[i][3]);
+      b[i]=P[i][2];
+      k=1;
+      c=P[i][2];
+      r=0,-1,1,0;
+      while (divrem(b[i]*b[i] + b[i] *h - f,(var(1)-P[i][1])^(P[i][3])) != 0)
+      {
+          k=k+1;
+          // here, the procedure darst was integrateg. In every pass a new
+          // coefficient c[i] is determined.
+          r1=r[1]-c*r[3];
+          r2=r[2]-c*r[4];
+          r3=r[3];
+          r4=r[4];
+          n=multi(r3,r4,r1+r2*h,-r2,h,f);
+          Norm=r1*r1 + r1*r2*h-r2*r2*f;
+          r=list(Norm/(var(1)-P[i][1]),0,n[1],n[2]);
+          while ((divrem(r[1],var(1)-P[i][1]) ==0) and (divrem(r[2],var(1)-P[i][1]) ==0) and (divrem(r[3],var(1)-P[i][1]) ==0) and (divrem(r[4],var(1)-P[i][1]) ==0))
+          {
+
+           // reducing the rationl function
+           // (r[1]-r[2]y)/(r[3]-r[4]y) , otherwise there
+           // could be a pole, s.t. conditions are not fulfilled.
+              r[1]=(r[1]) / (var(1)-P[i][1]);
+              r[2]=(r[2]) / (var(1)-P[i][1]);
+              r[3]=(r[3]) / (var(1)-P[i][1]);
+              r[4]=(r[4]) / (var(1)-P[i][1]);
+          }
+          c=(subst(r[1],var(1),P[i][1]) - subst(r[2],var(1),P[i][1])*P[i][2]) / (subst(r[3],var(1),P[i][1]) - subst(r[4],var(1),P[i][1])*P[i][2]);
+          b[i]=b[i]+ c*(var(1)-P[i][1])^(k-1);
+      }
+   }
+   // return polynomial a and b. Polynomial b is solution of the congruencies
+   // b[i] mod m[i] .
+   return(list(a,chinrestp(b,m)));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring R=7,x,dp;
+   // hyperelliptic curve y^2 + h*y = f
+   poly h=x;
+   poly f=x5+5x4+6x2+x+3;
+   //Divisor P
+   list P=list(-1,-3,1),list(1,1,1);
+   ratrep(P,h,f);
+}
+
+
+//============== Order of a zero in a polynomial ==============================
+
+proc ordnung(poly x0 , poly g)
+"USAGE:   ordnung(x0,g);
+RETURN:  int i
+NOTE:    i is maximal, s.t. (x-x0)^i divides g
+EXAMPLE: example ordnung; shows an example
+"
+{
+   poly gg=g;
+   int i;
+   while ( divrem(gg,var(1)-x0) ==0 )
+   {
+      i=i+1;
+      gg=gg/(var(1)-x0);
+   }
+   return(i);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring R=0,x,dp;
+   poly g=(x-5)^7*(x-3)^2;
+   number x0=5;
+   ordnung(x0,g);
+}
+
+
+//================== divisor of a polynomial function =========================
+
+proc divisor(poly a, poly b, poly h, poly f, list #)
+"USAGE:   divisor(a,b,h,f); optional: divisor(a,b,h,f,s); s=0,1
+RETURN:  list P
+NOTE:    P[1][3]*(P[1][1], P[1][2]) +...+ P[size(P)][3]*
+         *(P[size(P)][1], P[size(P)][2]) - (*)infty=div(a(x)-b(x)y)
+         if there is an optional parameter s!=0, then divisor additonally
+         returns a parameter, which says, whether irreducible polynomials
+         occured during computations or not. Otherwise only warnings are
+         displayed on the monitor. For s=0 nothing happens.
+         Curve C: y^2+h(x)y=f(x) is defined over basering.
+EXAMPLE: example divisor; shows an example
+"
+{
+   list p;
+   int j;
+   poly x0;
+   list y;
+   list fa=factorize(gcd(a,b));  // wanted: common roots of a and b
+   poly Norm=norm(a,b,h,f);
+
+   int s;
+   int irred=0;
+   if (size(#)>0)
+   {
+      s=#[1];
+   }
+   else
+   {
+      s=0;
+   }
+
+   for (int i=2; i<=size(fa[1]) ; i++)
+   {
+      // searching roots by finding polynomials of degree 1
+      if ( deg(fa[1][i]) !=1 )
+      {
+         if (s==0)
+         {
+         "WARNIG: ", fa[1][i], "is irreducible over this field !";
+         }
+         else
+         {
+            irred=1;
+         }
+      }
+      else
+      {
+         x0=var(1) - fa[1][i];
+         // finding the y-coordinates; max. 2
+         y= factorize(var(1)^2 + var(1)*subst(h,var(1),x0) - subst(f,var(1),x0));
+         if ( deg(y[1][2]) == 1)
+         // if root belongs to point on curve, then...
+         {
+            // compute order of a-b*y in the founded point
+            j=j+1;
+            p[j]=list(x0,var(1)-y[1][2],fa[2][i]);
+            if ( y[2][2]== 1)          // ordinary point
+            {
+               j=j+1;
+               p[j]=list(x0 , var(1)-y[1][3] , fa[2][i] );
+               if (a/(var(1)-x0)^(fa[2][i]) - b/(var(1)-x0)^(fa[2][i]) * p[j][2] ==0 )
+               {
+                  p[j][3]= p[j][3] + ordnung(x0,norm(a/(var(1)-x0)^(fa[2][i]) , b/(var(1)-x0)^(fa[2][i]),h,f));
+               }
+               if (a/(var(1)-x0)^(fa[2][i]) - b/(var(1)-x0)^(fa[2][i]) * p[j-1][2] ==0 )
+               {
+               p[j-1][3]=p[j-1][3] + ordnung(x0,norm(a/(var(1)-x0)^(fa[2][i]) , b/(var(1)-x0)^(fa[2][i]),h,f));
+               }
+            }
+            else        // special point
+            {
+               p[j][3]=p[j][3] *2  ;
+               if (a/(var(1)-x0)^(fa[2][i]) - b/(var(1)-x0)^(fa[2][i]) * p[j][2] ==0 )
+               {
+                  p[j][3]=p[j][3] + ordnung(x0,norm(a/(var(1)-x0)^(fa[2][i]) , b/(var(1)-x0)^(fa[2][i]),h,f));
+               }
+            }
+
+         }
+         // Norm of a-b*y is reduced by common root of a and b
+         // (is worked off)
+         Norm = Norm/((var(1)-x0)^(ordnung(x0,Norm)));
+      }
+   }
+
+   // some points are still missing; points for which a and b have no common
+   // roots, but norm(a-b*Y)=0 .
+   fa=factorize(Norm);
+   for ( i=2 ; i<=size(fa[1]) ; i++)
+   {
+      if ( deg(fa[1][i]) !=1)
+      {
+         if (s==0)
+         {
+         "WARNING: ", fa[1][i], "is irreducible over this field !";
+         }
+         else
+         {
+            irred=1;
+         }
+      }
+      else
+      {
+         x0=var(1) - fa[1][i];
+         y= factorize(var(1)^2 + var(1)*subst(h,var(1),x0) - subst(f,var(1),x0));
+         if ( deg(y[1][2]) == 1)
+         // if root belongs to point on curve, then...
+         {
+            if (subst(a,var(1),x0)- subst(b,var(1),x0)* (var(1)-y[1][2]) ==0)
+            {
+               p[size(p)+1]=list(x0,var(1)-y[1][2], ordnung(x0,Norm,h,f));
+            }
+            if ( y[2][2]== 1)     // ordinary point
+            {
+               if (subst(a,var(1),x0)- subst(b,var(1),x0)* (var(1)-y[1][3]) ==0)
+               {
+               p[size(p)+1]=list(x0 , var(1)-y[1][3] , ordnung(x0,Norm,h,f));
+               }
+            }
+         }
+      }
+   }
+   if (s==0)
+   {
+      return(p);
+   }
+   return(p,irred);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring R=7,x,dp;
+   // hyperelliptic curve y^2 + h*y = f
+   poly h=x;
+   poly f=x5+5x4+6x2+x+3;
+   poly a=(x-1)^2*(x-6);
+   poly b=0;
+   divisor(a,b,h,f,1);
+}
+
+
+//===================== gcd of two divisors ===================================
+
+proc gcddivisor(list p, list q)
+"USAGE:   gcddivisor(p,q);
+RETURN:  list P
+NOTE:    gcd of two divisors
+EXAMPLE: example gcddivisor; shows an example
+"
+{
+   list e;
+   int i,j;
+   for (i=1 ; i<= size(p) ; i++)
+   {
+      for (j=1 ; j<= size(q) ; j++)
+      {
+         if ( p[i][1] == q[j][1] and p[i][2] == q[j][2])
+         {
+            if ( p[i][3] <= q[j][3] )
+            {
+               e[size(e)+1]= list (p[i][1] , p[i][2] , p[i][3]);
+            }
+            else
+            {
+               e[size(e)+1]= list (q[j][1] , q[j][2] , q[j][3]);
+            }
+         }
+      }
+   }
+   return(e);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring R=7,x,dp;
+   // hyperelliptic curve y^2 + h*y = f
+   poly h=x;
+   poly f=x5+5x4+6x2+x+3;
+   // two divisors
+   list p=list(-1,-3,1),list(1,1,2);
+   list q=list(1,1,1),list(2,2,1);
+   gcddivisor(p,q);
+}
+
+
+//========== semireduced divisor from rational representation=================
+
+proc semidiv(list D,poly h, poly f)
+"USAGE:   semidiv(D,h,f);
+RETURN:  list P
+NOTE:    important: Divisor D has to be semireduced!
+         Computes semireduced divisor P[1][3]*(P[1][1], P[1][2]) +...+ P[size(P)][3]*
+         *(P[size(P)][1], P[size(P)][2]) - (*)infty=div(D[1],D[2])@*
+         Curve C:y^2+h(x)y=f(x) is defined over basering.
+EXAMPLE: example semidiv; shows an example
+"
+{
+   if ( deg(D[2]) >= deg(D[1]) or divrem(D[2]^2+D[2]*h-f,D[1]) != 0 )
+   {
+      ERROR("Pair of polynomials doesn't belong to semireduced divisor!");
+   }
+   list D1,D2;
+   int s1,s2;
+   D1,s1=divisor(D[1],0,h,f,1);
+   D2,s2=divisor(D[2],1,h,f,1);
+
+   // Only if irreducible polynomials occured in D1 !and! D2 a warning
+   // is necessary.
+   if (s1==1 and s2==1)
+   {
+      "Attention:
+     Perhaps some points were not found over this field!";
+   }
+   return(gcddivisor(D1,D2));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring R=7,x,dp;
+   // hyperelliptic curve y^2 + h*y = f
+   poly h=x;
+   poly f=x5+5x4+6x2+x+3;
+   // Divisor
+   list D=x2-1,2x-1;
+   semidiv(D,h,f);
+}
+
+
+//=============== Cantor's algorithm - composition ============================
+
+proc cantoradd(list D, list Q, poly h, poly f)
+"USAGE:   cantoradd(D,Q,h,f);
+RETURN:  list P
+NOTE:    Cantor's Algorithm - composition
+         important: D and Q have to be semireduced!
+         Computes semireduced divisor div(P[1],P[2])= div(D[1],D[2]) + div(Q[1],Q[2])
+         The divisors are defined over the basering.
+         Curve C: y^2+h(x)y=f(x) is defined over the basering.
+EXAMPLE: example cantoradd; shows an example
+"
+{
+   poly a;
+   poly b;
+   list e=extgcd(D[1],Q[1]);
+   if ( e[1]==1 )
+   {
+      a=D[1]*Q[1];
+      b=divrem( e[2]*D[1]*Q[2] + e[3]*Q[1]*D[2] ,a);
+      return(list(a,b));
+   }
+   list c=extgcd(e[1],D[2]+Q[2]+h);
+   poly s1=e[2]*c[2];
+   poly s2=c[2]*e[3];
+   poly s3=c[3];
+   a=D[1]*Q[1]/c[1]^2;
+   b=divrem((s1*D[1]*Q[2] + s2*Q[1]*D[2] + s3*(D[2]*Q[2] + f))/c[1],a);
+   return(list(a,b));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring R=7,x,dp;
+   // hyperelliptic curve y^2 + h*y = f
+   poly h=x;
+   poly f=x5+5x4+6x2+x+3;
+   // two divisors in rational representation
+   list D=x2-1,2x-1;
+   list Q=x2-3x+2,-3x+1;
+   cantoradd(D,Q,h,f);
+}
+
+
+//==================== Cantor's algorithm - reduction =========================
+
+proc cantorred(list D,poly h,poly f)
+"USAGE:   cantorred(D,h,f);
+RETURN:  list N
+NOTE:    Cantor's algorithm - reduction.
+         important: Divisor D has to be semireduced!
+         Computes reduced divisor div(N[1],N[2])= div(D[1],D[2]).@*
+         The divisors are defined over the basering.
+         Curve C: y^2+h(x)y=f(x) is defined over the basering.
+EXAMPLE: example cantorred; shows an example
+"
+{
+   list N=D;
+   while ( 2*deg(N[1]) > deg(f)-1 )
+   {
+      N[1]=(f - N[2]*h - N[2]^2)/N[1];
+      N[2]=divrem(-h-N[2],N[1]);
+   }
+   N[1]=N[1]/leadcoef(N[1]);
+   return(N);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring R=7,x,dp;
+   // hyperelliptic curve y^2 + h*y = f
+   poly h=x;
+   poly f=x5+5x4+6x2+x+3;
+   // semireduced divisor
+   list D=2x4+3x3-3x-2, -x3-2x2+3x+1;
+   cantorred(D,h,f);
+}
+
+
+//================= doubling a semireduced divisor ============================
+
+proc double(list D, poly h, poly f)
+"USAGE:   double(D,h,f);
+RETURN:  list Q=2*D
+NOTE:    important: Divisor D has to be semireduced!
+         Special case of Cantor's algorithm.
+         Computes reduced divisor div(Q[1],Q[2])= 2*div(D[1],D[2]).@*
+         The divisors are defined over the basering.
+         Curve C:y^2+h(x)y=f(x) is defined over the basering.
+EXAMPLE: example double; shows an example
+"
+{
+   list c=extgcd(D[1], 2*D[2] + h);
+   poly a=D[1]*D[1]/c[1]^2;
+   poly b=divrem((c[2]*D[1]*D[2] + c[3]*(D[2]*D[2] + f))/c[1],a);
+   return(cantorred(list(a,b),h,f));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring R=7,x,dp;
+   // hyperelliptic curve y^2 + h*y = f
+   poly h=x;
+   poly f=x5+5x4+6x2+x+3;
+   // reduced divisor
+   list D=x2-1,2x-1;
+   double(D,h,f);
+}
+
+
+//================ multiples of a semireduced divisor =========================
+
+proc cantormult(int m, list D, poly h, poly f)
+"USAGE:   cantormult(m,D,h,f);
+RETURN:  list res=m*D
+NOTE:    important: Divisor D has to be semireduced!
+         Uses repeated doublings for a faster computation
+         of the reduced divisor m*D.
+         Attention: Factor m=int, this means bounded.
+         For m<0 the inverse of m*D is returned.
+         The divisors are defined over the basering.
+         Curve C: y^2+h(x)y=f(x) is defined over the basering.
+EXAMPLE: example cantormult; shows an example
+"
+{
+   list res=1,0;
+   list bas=D;
+   int exp=m;
+   if (exp==0) { return(list(1,0)); }
+   if (exp==1) { return(D); }
+   if (exp==-1) { return(list(D[1],-D[2]-h)) ; }
+   if ( exp < 0)
+   {
+      exp=-exp;
+   }
+   while ( exp > 0 )
+   {
+     if ( (exp mod 2) !=0 )
+     {
+       res = cantorred(cantoradd(res,bas,h,f),h,f);
+       exp=exp-1;
+     }
+     bas=double(bas,h,f);
+     exp=exp div 2;
+   }
+   if ( m < 0 )
+   {
+      res[2]=-res[2]-h;
+   }
+   return(res);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring R=7,x,dp;
+   // hyperelliptic curve y^2 + h*y = f
+   poly h=x;
+   poly f=x5+5x4+6x2+x+3;
+   // reduced divisor
+   list D=x2-1,2x-1;
+   cantormult(34,D,h,f);
+}
+
+
+/*
+//=============================================================================
+//   In the following you find a large example, which demostrates the use of
+//   the most important procedures.
+//=============================================================================
+//---- field with 2^5=32 elements ----
+ring r=(2,a),x,dp;
+minpoly=a5+a2+1;
+
+//---- hyperelliptic curve y^2 + hy = f ----
+poly h=x2+x;
+poly f=x5+x3+1;
+
+//---- two divisors ----
+list l1=list(a30,0,1),list(0,1,1);
+list l2=list(a30,a16,1),list(1,1,1);
+
+//---- their rational representation ----
+list D1=ratrep(l1,h,f); D1;
+//[1]:
+//   x2+(a4+a)*x
+//[2]:
+//   (a)*x+1
+
+list D2=ratrep(l2,h,f); D2;
+//[1]:
+//   x2+(a4+a+1)*x+(a4+a)
+//[2]:
+//   (a3+a2+a+1)*x+(a3+a2+a)
+
+//---- back to the point-based-representation ----
+semidiv(D1,h,f);
+//[1]:
+//   [1]:
+//      (a4+a)
+//   [2]:
+//      0
+//   [3]:
+//      1
+//[2]:
+//   [1]:
+//      0
+//   [2]:
+//      1
+//   [3]:
+//      1
+
+semidiv(D2,h,f);
+//[1]:
+//   [1]:
+//      (a4+a)
+//   [2]:
+//      (a4+a3+a+1)
+//   [3]:
+//      1
+//[2]:
+//   [1]:
+//      1
+//   [2]:
+//      1
+//   [3]:
+//      1
+
+//---- adding D1 and D2 ----
+list D12=cantorred(cantoradd(D1,D2,h,f),h,f);  D12;
+//[1]:
+//   x2+x
+//[2]:
+//   1
+
+//---- D1+D2 in point-based-representation ----
+semidiv(D12,h,f);
+//[1]:
+//   [1]:
+//      1
+//   [2]:
+//      1
+//   [3]:
+//      1
+//[2]:
+//   [1]:
+//      0
+//   [2]:
+//      1
+//   [3]:
+//      1
+
+//---- D1 + D1   (2 possible ways, same result) ----
+cantorred(cantoradd(D1,D1,h,f),h,f);
+double(D1,h,f);
+//[1]:
+//   x2+(a3+1)
+//[2]:
+//   (a4+a3+a+1)*x+(a4+a3+a2+a+1)
+
+//---- order of D1 in the jacobian over the basering ----
+int i=1;
+list E=D1;
+while (E[1] != 1 or E[2] != 0 )
+{
+   E= cantorred(cantoradd(E,D1,h,f),h,f);
+   i=i+1;
+}
+i;   // 482
+
+//---- proof with multiplikation validates the result ----
+cantormult(i,D1,h,f);
+//[1]:
+//   1
+//[2]:
+//   0
+
+//---- computing the inverse of D1 ----
+list d1= cantormult(-1,D1,h,f);  d1;
+//[1]:
+//   x2+(a4+a)*x
+//[2]:
+//   x2+(a+1)*x+1
+
+//---- proof validates the result ----
+cantoradd(d1,D1,h,f);
+//[1]:
+//   1
+//[2]:
+//   0
+
+
+*/
diff --git a/Singular/LIB/inout.lib b/Singular/LIB/inout.lib
new file mode 100644
index 0000000..65ddca1
--- /dev/null
+++ b/Singular/LIB/inout.lib
@@ -0,0 +1,703 @@
+//////////////////////////////////////////////////////////////////////////////
+version="version inout.lib 4.0.0.0 Jun_2013 "; // $Id: b43b0bc1007623c058283c67499feb63b81600a7 $
+category="General purpose";
+info="
+LIBRARY:  inout.lib     Printing and Manipulating In- and Output
+
+PROCEDURES:
+ allprint(list);        print list if ALLprint is defined, with pause if >0
+ lprint(poly/...[,n]);  display poly/... fitting to pagewidth [size n]
+ pmat(matrix[,n]);      print form-matrix [first n chars of each colum]
+ rMacaulay(string);     read Macaulay_1 output and return its @sc{Singular} format
+ show(any);             display any object in a compact format
+ showrecursive(id,p);   display id recursively with respect to variables in p
+ split(string,n);       split given string into lines of length n
+ tab(n);                string of n space tabs
+ pause([prompt]);       stop the computation until user input
+           (parameters in square brackets [] are optional)
+";
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc allprint (list #)
+"USAGE:   allprint(L);  L list
+DISPLAY: prints L[1], L[2], ... if an integer with name ALLprint is defined.
+@*       makes \"pause\",   if ALLprint > 0
+RETURN:  no return value
+EXAMPLE: example allprint; shows an example
+"
+{
+   if( defined(ALLprint) )
+   {
+      int i;
+      for( i=1; i<=size(#); i=i+1 ) { print(#[i]); }
+      if( ALLprint >0 ) { pause(); }
+   }
+   return();
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring S;
+   matrix M=matrix(freemodule(2),3,3);
+   int ALLprint; export ALLprint;
+   allprint("M =",M);
+   kill ALLprint;
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc lprint
+"USAGE:   lprint(id[,n]);  id poly/ideal/vector/module/matrix, n integer
+RETURN:  string of id in a format fitting into lines of size n, such that no
+         monomial gets destroyed, i.e. the new line starts with + or -;
+         (default: n = pagewidth).
+NOTE:    id is printed columnwise, each column separated by a blank line;
+         hence lprint(transpose(id)); displays a matrix id in a format which
+         can be used as input.
+EXAMPLE: example lprint; shows an example
+"
+{
+   if (size(#)==1) { int n = pagewidth-3; }
+   else {int n = #[2]-3; }
+   matrix M = matrix(#[1]);
+   poly p,h,L; string s1,s,S; int jj,ii,a;
+   for (jj=1; jj<=ncols(M); jj=jj+1)
+   {
+      for (ii=1; ii<=nrows(M); ii=ii+1)
+      {
+         a=2;
+         if (a+size(string(M[ii,jj])) <= n) {s = "  "+string(M[ii,jj]);}
+         else
+         {
+            h = lead(M[ii,jj]); p = M[ii,jj] - h; L = lead(p);
+            while (p != 0)
+            {
+               if (a+size(string(h+L)) > n)
+               {
+                  s = string(h);
+                  if (a != 0) { s = "  "+s; }
+                  if (a == 0 and s[1] != "-") { s = "+" + s; }
+                  a=0; h=0; S=S+newline+s;
+               }
+               h = h + L; p = p - L; L = lead(p);
+            }
+            s = string(h);
+            if (a == 0 and s[1] != "-") { s = "+" + s; }
+         }
+         if (ii != nrows(M)) { s = s+","; S=S+newline+s; }
+         else
+         {
+            if (jj != ncols(M)) { s = s+","; S=S+newline+s+newline;}
+            else { S=S+newline+s; }
+         }
+      }
+   }
+   return(S[2,size(S)-1]);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r= 0,(x,y,z),ds;
+   poly f=((x+y)*(x-y)*(x+z)*(y+z)^2);
+   lprint(f,40);
+   module m = [f*(x-y)],[0,f*(x-y)];
+   string s=lprint(m); s;"";
+   execute("matrix M[2][2]="+s+";");      //use the string s as input
+   module m1 = transpose(M);              //should be the same as m
+   print(matrix(m)-matrix(m1));
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc pmat (matrix m, list #)
+"USAGE:   pmat(M[,n]);  M matrix, n integer
+RETURN: A string representing M in array format if it fits into
+        pagewidth; if n is given, only the first n characters of
+        each column are shown (n>1 required), where a truncation
+        of a column is indicated by two dots (\'..\')
+EXAMPLE: example pmat; shows an example
+"
+{
+//------------- main case: input is a matrix, no second argument---------------
+   string OUT = "";
+   if ( size(#)==0)
+   {
+      int elems,mlen,slen,c,r;
+   //-------------- count maximal size of each column, and sum up -------------
+      for ( c=1; c<=ncols(m); c=c+1)
+      {  int len(c);
+         for (r=1; r<=nrows(m); r=r+1)
+         {
+            elems = elems+1;
+            string s(elems) = string(m[r,c])+",";
+            slen = size(s(elems));
+            if ( slen>len(c) ) { len(c) = slen; }
+         }
+         mlen = mlen+len(c);
+      }
+   //---------------------- print all - except last - rows --------------------
+      string aus; string sep = " ";
+      if (mlen >= pagewidth) { sep = newline; }
+      for (r=1; r<nrows(m); r=r+1)
+      {  elems = r; aus = "";
+         for (c=1; c<=ncols(m); c=c+1)
+         {
+            aus = aus + s(elems)[1,len(c)] + sep;
+            elems = elems + nrows(m);
+         }
+         OUT=OUT+aus+newline;
+      }
+   //--------------- print last row (no comma after last entry) ---------------
+      aus = ""; elems = nrows(m);
+      for (c=1; c<ncols(m); c=c+1)
+      {
+         aus = aus + s(elems)[1,len(c)] + sep;
+         elems = elems + nrows(m);
+      }
+      aus = aus + string(m[nrows(m),ncols(m)]);
+      OUT=OUT+aus;  return(OUT);
+   }
+//---------- second case: second argument is given and of type int ------------
+   if ( typeof(#[1])=="int" and #[1]>1)
+   {  string aus,tmp; int c,r;
+   //---------------------- print all - except last - rows --------------------
+      for ( r=1; r<nrows(m); r=r+1)
+      {  aus = "";
+         for (c=1; c<=ncols(m); c=c+1)
+         {
+            tmp=string(m[r,c]);
+            if (size(tmp)>#[1])
+            { tmp[#[1]-1]=".";
+              tmp[#[1]]  =".";
+              aus=aus+tmp[1,#[1]]+", ";
+            }
+            else
+            { tmp=tmp+",";
+              aus=aus+tmp[1,#[1]+1]+" ";
+            }
+         }
+         OUT=OUT+aus+newline;
+      }
+   //--------------- print last row (no comma after last entry) ---------------
+      aus = "";
+      for (c=1; c<ncols(m); c=c+1)
+      { tmp=string(m[r,c]);
+        if (size(tmp)>#[1])
+        { tmp[#[1]-1]=".";
+          tmp[#[1]]  =".";
+          aus=aus+tmp[1,#[1]]+", ";
+        }
+        else
+        { tmp=tmp+",";
+          aus=aus+tmp[1,#[1]+1]+" ";
+        }
+      }
+      tmp=string(m[nrows(m),ncols(m)]);
+      if (size(tmp)>#[1])
+      { tmp[#[1]-1]=".";
+        tmp[#[1]]  =".";
+      }
+      aus = aus + tmp[1,#[1]];
+      OUT=OUT+aus;  return(OUT);
+   }
+}
+example
+{  "EXAMPLE:"; echo = 2;
+   ring r=0,(x,y,z),ls;
+   ideal i= x,z+3y,x+y,z;
+   matrix m[3][3]=i^2;
+   pmat(m);
+   pmat(m,5);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc rMacaulay
+"USAGE:   rMacaulay(s[,n]);  s string, n integer
+RETURN:  A string denoting a file which should be readable by Singular
+         and it should be produced by Macaulay Classic.
+         If a second argument is present the first
+         n lines of the file are deleted (which is useful if the file was
+         produced e.g. by the putstd command of Macaulay).
+NOTE:    This does not always work with 'cut and paste' since the character
+         \ is treated differently
+EXAMPLE: example rMacaulay; shows an example
+"
+{
+   int n;
+   if( size(#)==2 ) { n=#[2]; }
+   string s0 = #[1];
+//------------------------ delete first n=#[2] lines --------------------------
+   int ii=find(s0,newline); int jj;
+   for ( jj=1; jj<=n; jj=jj+1)
+   {
+      s0 = s0[ii+1,size(s0)-ii];
+      ii = find(s0,newline);
+   }
+//--------------- delete blanks and 'newline' at start and end ----------------
+   ii = 1;
+   while( s0[ii]==" " or s0[ii]==newline ) { ii=ii+1; }
+   s0 = s0[ii,size(s0)-ii+1]; ii = size(s0);
+   while ( s0[ii]==" " or s0[ii]==newline) { ii=ii-1; }
+   s0 = s0[1,ii];
+//------------------------- make each line a string ---------------------------
+   ii = find(s0,newline); jj=0; int kk;
+   while( ii!=0 )
+   {  jj = jj+1;  kk = ii+1;
+      while( s0[kk]==" " or s0[kk]==newline ) {  kk=kk+1; }
+      string s(jj) = s0[1,ii-1];
+      s0 = s0[kk,size(s0)-kk+1];
+      ii = find(s0,newline);
+   }
+   jj=jj+1;
+   string s(jj) = s0;
+//------------ delete blanks and \ at end of each string and add , ------------
+   for( ii=1; ii<=jj; ii=ii+1 )
+   {  kk = 1;
+      while( s(ii)[kk]==" " ) { kk=kk+1; }
+      s(ii) = s(ii)[kk,size(s(ii))-kk+1];
+      kk = size(s(ii));
+      while( s(ii)[kk]==" " or s(ii)[kk]=="\\" or s(ii)[kk]==newline )
+         {  kk = kk-1; }
+      s(ii) = s(ii)[1,kk]+","+newline;
+   }
+//------------------------ replace blanks by , and add up ---------------------
+   int ll; s0 = ""; string s1,s2;
+   for( ii=1; ii<=jj; ii=ii+1 )
+   {
+      s1 = ""; s2 = s(ii);
+      kk = find(s(ii)," "); ll=kk+1;
+      while( kk!=0 )
+      {
+         while( s2[ll]==" ") { ll=ll+1; }
+         if( kk!=1 ) { s1=s1+s2[1,kk-1]+","+s2[kk+1,ll-kk]; }
+         if( kk==1 ) { s1 = s1+","+s2[kk+1,ll-kk]; }
+         s2 = s2[ll+1,size(s2)-ll];
+         kk = find(s2," "); ll=kk+1;
+      }
+      s(ii) = s1+s2; s0 = s0+s(ii);
+   }
+//---------------------------- replace [] by () -------------------------------
+   s1 = ""; s2 = s0;
+   ii = find(s2,"[");
+   while( ii!=0 )
+   {
+      s0 = s0[1,ii-1]+"("+s0[ii+1,size(s0)-ii];
+      if( ii>2 )
+      {
+         if(s0[ii-2]!="+" and s0[ii-2]!="-" and s0[ii-2]!="," and s0[ii-2]!=newline)
+         {
+            s0 = s0[1,ii-2]+"*"+s0[ii-1,size(s0)-ii+2];
+         }
+      }
+      ii = find(s0,"[");
+   }
+   jj = find(s0,"]");
+   while ( jj!=0 )
+   {
+      s0 = s0[1,jj-1]+")"+s0[jj+1,size(s0)-jj];
+      if(s0[jj+1]!="+"and s0[jj+1]!="-" and s0[jj+1]!="," and s0[jj+1]!="*")
+         { s0 = s0[1,jj] + "^" + s0[jj+1,size(s0)-jj]; }
+      jj = find(s0,"]");
+   }
+   s0 = s0[1,size(s0)-2];
+   return(s0);
+}
+example
+{  "EXAMPLE:"; echo = 2;
+   // Assume there exists a file 'Macid' with the following ideal in
+   // Macaulay format:"
+   // x[0]3-101/74x[0]2x[1]+7371x[0]x[1]2-13/83x[1]3-x[0]2x[2] \
+   //     -4/71x[0]x[1]x[2]
+   // Read this file into Singular and assign it to the string s1 by:
+   // string s1 = read("Macid");
+   // This is equivalent to";
+   string s1 =
+   "x[0]3-101/74x[0]2x[1]+7371x[0]x[1]2-13/83x[1]3-x[0]2x[2]-4/71x[0]x[1]x[2]";
+   rMacaulay(s1);
+   // You may wish to assign s1 to a Singular ideal id:
+   string sid = "ideal id =",rMacaulay(s1),";";
+   ring r = 0,x(0..3),dp;
+   execute(sid);
+   id; "";
+   // Now treat a matrix in Macaulay format. Using the execute
+   // command, this could be assinged to a Singular matrix as above.
+   string s2 = "
+   0  0  0  0  0
+   a3 0  0  0  0
+   0  b3 0  0  0
+   0  0  c3 0  0
+   0  0  0  d3 0
+   0  0  0  0  e3 ";
+   rMacaulay(s2);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc show (def @@id, list #)
+"USAGE:   show(id);   id any object of basering or of type ring/qring
+@*       show(R,s);  R=ring, s=string (s = name of an object belonging to R)
+DISPLAY: display id/s in a compact format together with some information
+RETURN:  no return value
+NOTE:    objects of type string, int, intvec, intmat belong to any ring.
+         id may be a ring or a qring. In this case the minimal polynomial is
+         displayed, and, for a qring, also the defining ideal.
+         id may be of type list but the list must not contain a ring.
+@*       show(R,s) does not work inside a procedure!
+EXAMPLE: example show; shows an example
+"
+{
+//------------- use funny names in order to avoid name conflicts --------------
+   int @li@, @ii;
+   string @s@,@@s;
+   int @short@=short; short=1;
+//----------------------------- check syntax ----------------------------------
+   if( size(#)!= 0 )
+   {
+      if( typeof(#[1])=="int" ) { @li@=#[1]; }
+   }
+   if ( typeof(@@id)!="list" )
+   {
+      if( size(#)==0 )
+      {
+          def @id@ = @@id;
+      }
+      if( size(#)==1 )
+      {
+         if( typeof(#[1])=="int" )
+         {
+             def @id@ = @@id;
+         }
+         if( typeof(#[1])=="string" )
+         {
+            if( typeof(@@id)=="ring" or typeof(@@id)=="qring")
+            {
+               def @R@ = @@id;
+               setring @R@;
+               def @id@=`#[1]`;
+            }
+         }
+      }
+   }
+//----------------------- case: @@id is of type list ----------------------------
+   if ( typeof(@@id)=="list" )
+   {
+//      @@s = tab(@li@)+"// list, "+string(size(@@id))+" element(s):";
+      @@s = tab((3*(voice-2)))+"// list, "+string(size(@@id))+" element(s):";
+      @@s;
+      for ( @ii=1; @ii<=size(@@id); @ii++ )
+      {
+         if( typeof(@@id[@ii])!="none" )
+         {
+            def @id(@ii) = @@id[@ii];
+            tab(3*(voice-2))+"["+string(@ii)+"]:";
+            //           show(@id(@ii), at li@+3*(voice-1));
+            show(@id(@ii),3*(voice-1));
+         }
+         else
+         {
+            "["+string(@ii)+"]:";
+            tab(@li at +2),"//",@@id[@ii];
+         }
+      }
+      short=@short@; return();
+    }
+   if( defined(@id@)!=voice ) { "// wrong syntax, type help show;";  return();}
+//-------------------- case: @id@ belongs to any ring -------------------------
+   if( typeof(@id@)=="string" or typeof(@id@)=="int" or typeof(@id@)=="intvec"
+       or typeof(@id@)=="intmat" or typeof(@id@)=="list" )
+   {
+      if( typeof(@id@)!="intmat" )
+      {
+         @@s = tab(@li@)+"// "+typeof(@id@)+", size "+string(size(@id@));
+         @@s;
+      }
+      if( typeof(@id@)=="intmat" )
+      {
+         @@s = tab(@li@)+"// "+typeof(@id@)+", "+string(nrows(@id@))+" rows, "
+               + string(ncols(@id@))+" columns";
+         @@s;
+      }
+      @id@;
+      short=@short@; return();
+   }
+//-------------------- case: @id@ belongs to basering -------------------------
+   if( typeof(@id@)=="poly" or typeof(@id@)=="ideal" or typeof(@id@)=="matrix" )
+   {
+      @@s = tab(@li@)+"// "+ typeof(@id@);
+      if( typeof(@id@)=="ideal" )
+      {
+         @@s=@@s + ", "+string(ncols(@id@))+" generator(s)";
+         @@s;
+         print(ideal(@id@));
+      }
+      if( typeof(@id@)=="poly" )
+      {
+         @@s=@@s + ", "+string(size(@id@))+" monomial(s)";
+         @@s;
+         print(poly(@id@));
+      }
+      if( typeof(@id@)=="matrix")
+      {
+         @@s=@@s + ", "+string(nrows(@id@))+"x"+string(ncols(@id@));
+         @@s;
+         print(matrix(@id@));
+      }
+      short=@short@; return();
+   }
+   if( typeof(@id@)=="vector" )
+   {
+      @@s = tab(@li@)+"// "+typeof(@id@);
+      @@s;
+      print(@id@);
+      short=@short@; return();
+   }
+   if( typeof(@id@)=="module" )
+   {
+      @s@=", "+string(ncols(@id@))+" generator(s)";
+      @@s = tab(@li@)+"// "+ typeof(@id@)+ @s@;
+      @@s;
+      int @n@;
+      for( @n@=1; @n@<=ncols(@id@); @n@=@n at +1 ) { print(@id@[@n@]); }
+      short=@short@; return();
+   }
+   if( typeof(@id@)=="number" or typeof(@id@)=="resolution" )
+   {
+      @@s = tab(@li@)+"// ", typeof(@id@);
+      @@s;
+      @id@; short=@short@; return();
+   }
+   if( typeof(@id@)=="map" )
+   {
+      def @map = @id@;
+      @@s = tab(@li@)+"// i-th variable of preimage ring is mapped to @map[i]";
+      @@s;
+      if( size(#)==0 ) { type @map; }
+      if( size(#)==1 )
+      {
+         if( typeof(#[1])=="int" )    { type @map; }
+         if( typeof(#[1])=="string" ) { type `#[1]`; }
+      }
+      short=@short@; return();
+   }
+//---------------------- case: @id@ is a ring/qring ---------------------------
+   if( typeof(@id@)=="ring" or typeof(@id@)=="qring" )
+   {
+      setring @id@;
+      string s="("+charstr(@id@)+"),("+varstr(@id@)+"),("+ordstr(@id@)+");";
+      if( typeof(@id@)=="ring" )
+      {
+         list na at me@s=names(@id@);
+         kill @id@;
+         @@s = tab(@li@)+"// ring:"; @@s,s;
+         @@s = tab(@li@)+"// minpoly ="; @@s,minpoly;
+         "// objects belonging to this ring:";
+         listvar(poly);listvar(ideal);
+         listvar(vector);listvar(module);
+         listvar(map);listvar(matrix);
+         listvar(number);listvar(resolution);
+         for(int names at i=1;names at i<=size(na at me@s);names at i++)
+         {
+           def @hi at lf@=`na at me@s[names at i]`;
+           if ((typeof(@hi at lf@)!="poly") and
+               (typeof(@hi at lf@)!="ideal") and
+               (typeof(@hi at lf@)!="vector") and
+               (typeof(@hi at lf@)!="module") and
+               (typeof(@hi at lf@)!="map") and
+               (typeof(@hi at lf@)!="matrix") and
+               (typeof(@hi at lf@)!="number") and
+               (typeof(@hi at lf@)!="resolution"))
+           {
+             listvar(`na at me@s[names at i]`);
+           }
+           kill @hi at lf@;
+         }
+      }
+      if( typeof(@id@)=="qring" )
+      {
+         list na at me@s=names(@id@);
+         @@s = tab(@li@)+"// qring:"; @@s,s;
+         @@s = tab(@li@)+"// minpoly ="; @@s, minpoly;
+         @@s = tab(@li@)+"// quotient ring from ideal:"; @@s;
+         ideal(@id@);
+         listvar(poly);listvar(ideal);
+         listvar(vector);listvar(module);
+         listvar(map);listvar(matrix);
+         listvar(number);listvar(resolution);
+         for(int names at i=1;names at i<=size(na at me@s);names at i++)
+         {
+           def @hi at lf@=`na at me@s[names at i]`;
+           if ((typeof(@hi at lf@)!="poly") and
+               (typeof(@hi at lf@)!="ideal") and
+               (typeof(@hi at lf@)!="vector") and
+               (typeof(@hi at lf@)!="module") and
+               (typeof(@hi at lf@)!="map") and
+               (typeof(@hi at lf@)!="matrix") and
+               (typeof(@hi at lf@)!="number") and
+               (typeof(@hi at lf@)!="resolution"))
+           {
+             listvar(`na at me@s[names at i]`);
+           }
+           kill @hi at lf@;
+         }
+      }
+      short=@short@; //return();
+   }
+}
+example
+{  "EXAMPLE:"; echo = 2;
+    ring r;
+    show(r);
+    ideal i=x^3+y^5-6*z^3,xy,x3-y2;
+    show(i,3);            // introduce 3 space tabs before information
+    vector v=x*gen(1)+y*gen(3);
+    module m=v,2*v+gen(4);
+    list L = i,v,m;
+    show(L);
+    ring S=(0,T),(a,b,c,d),ws(1,2,3,4);
+    minpoly = T^2+1;
+    ideal i=a2+b,c2+T^2*d2; i=std(i);
+    qring Q=i;
+    show(Q);
+    map F=r,a2,b^2,3*c3;
+    show(F);
+// Apply 'show' to i (which does not belong to the basering) by typing
+// ring r; ideal i=xy,x3-y2; ring Q; show(r,"i");
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc showrecursive (def @@id,poly p,list #)
+"USAGE:   showrecursive(id,p[,ord]); id any object of basering, p= product of
+         variables and ord=string (any allowed ordstr)
+DISPLAY: display 'id' in a recursive format as a polynomial in the variables
+         occuring in p with coefficients in the remaining variables. This is
+         done by mapping to a ring with parameters [and ordering 'ord',
+         if a 3rd argument is present (default: ord=\"dp\")] and applying
+         procedure 'show'
+RETURN:  no return value
+EXAMPLE: example showrecursive; shows an example
+"
+{
+   def P = basering;
+   int ii;
+   string newchar = charstr(P);
+   string neword = "dp";
+   if( size(#) == 1 ) { neword = #[1]; }
+   string newvar;
+   for( ii=1; ii <= nvars(P); ii++ )
+   {
+      if( p/var(ii) == 0 )
+      {
+         newchar = newchar + ","+varstr(ii);
+      }
+      else
+      {
+         newvar = newvar + ","+varstr(ii);
+      }
+   }
+   newvar = newvar[2,size(newvar)-1];
+
+   execute("ring newP=("+newchar+"),("+newvar+"),("+neword+");");
+   def @@id = imap(P,@@id);
+   show(@@id);
+   return();
+}
+example
+{ "EXAMPLE:"; echo=2;
+   ring r=2,(a,b,c,d,x,y),ds;
+   poly f=y+ax2+bx3+cx2y2+dxy3;
+   showrecursive(f,x);
+   showrecursive(f,xy,"lp");
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc split (string s, list #)
+"USAGE:    split(s[,n]); s string, n integer
+RETURN:   same string, split into lines of length n separated by \
+          (default: n=pagewidth)
+NOTE:     may be used in connection with lprint
+EXAMPLE:  example split; shows an example
+"
+{
+   string line,re; int p,l;
+   if( size(#)==0 ) { int n=pagewidth; }
+   else { int n=#[1]; }
+   if( s[size(s),1] != newline ) { s=s+newline; }
+   l=size(s);
+   while( 1 )
+   {
+      p=1;
+      l=find(s,newline); line=s[1,l];
+      while( l>=n )
+      {
+         re=re+line[p,n-2]+"\\"+newline;
+         p=p+n-2; l=l-n+2;
+      }
+      re=re+line[p,l-1]+"\\"+newline;
+      l=size(line);
+      if( l>=size(s) ) break;
+      s=s[l+1,size(s)-l];
+   }
+   return (re[1,size(re)-2]);
+}
+example
+{  "EXAMPLE:"; echo = 2;
+   ring r= 0,(x,y,z),ds;
+   poly f = (x+y+z)^4;
+   split(string(f),50);
+   split(lprint(f));
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc tab (int n)
+"USAGE:   tab(n);  n integer
+RETURN:  string of n space tabs
+EXAMPLE: example tab; shows an example
+"
+{
+   if( n==0 ) { return(""); }
+   string s=" ";
+   return(s[1,n]);
+}
+example
+{  "EXAMPLE:"; echo = 2;
+   for(int n=0; n<=5; n=n+1)
+   { tab(5-n)+"*"+tab(n)+"+"+tab(n)+"*"; }
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc pause(list #)
+"USAGE:    pause([ prompt ])  prompt string
+RETURN:   none
+PURPOSE:  interrupt the execution of commands, displays prompt or pause
+          and waits for user input
+NOTE:     pause is useful in procedures in connection with printlevel to
+          interrupt the computation and to display intermediate results.
+SEE ALSO: read, printlevel
+EXAMPLE : example pause; shows an example
+"
+{
+  string pr="pause>";
+  if (size(#)!=0)
+  {
+    pr=#[1];
+  }
+  pr=read("",pr);
+}
+example
+{ "EXAMPLE:"; echo=2;
+  // can only be shown interactively, try the following commands:
+  // pause("press <return> to continue");
+  // pause();
+  // In the following pocedure TTT, xxx is printed and the execution of
+  // TTT is stopped until the return-key is pressed, if printlevel>0.
+  // xxx may be any result of a previous computation or a comment, etc:
+  //
+  // proc TTT
+  // { int pp = printlevel-voice+2;  //pp=0 if printlevel=0 and if TTT is
+  //    ....                         //not called from another procedure
+  //    if( pp>0 )
+  //    {
+  //       print( xxx );
+  //       pause("press <return> to continue");
+  //    }
+  //     ....
+  // }
+}
+///////////////////////////////////////////////////////////////////////////////
diff --git a/Singular/LIB/integralbasis.lib b/Singular/LIB/integralbasis.lib
new file mode 100644
index 0000000..3506feb
--- /dev/null
+++ b/Singular/LIB/integralbasis.lib
@@ -0,0 +1,570 @@
+//////////////////////////////////////////////////////////////////////////////
+version="version integralbasis.lib 4.0.0.0 Jun_2013 "; // $Id: d0a216c867e95ba8d62e1343a552b5572404b936 $
+category="Commutative Algebra";
+info="
+LIBRARY:  integralbasis.lib  Integral basis in algebraic function fields
+AUTHORS:  J. Boehm, j.boehm at mx.uni-saarland.de @*
+          W. Decker, decker at mathematik.uni-kl.de> @*
+          S. Laplagne, slaplagn at dm.uba.ar @*
+          F. Seelisch, seelisch at mathematik.uni-kl.de
+
+OVERVIEW:
+Given an irreducible polynomial f in two variables defining a plane curve,
+this library implements an algorithm to compute an integral basis of the
+integral closure of the affine coordinate ring in the algebraic function
+field via normalization.@*
+The user can choose whether the algorithm will do the computation globally
+or (this is the default) compute in the localization at each component of
+the singular locus and put everything together.
+
+PROCEDURES:
+ integralBasis(f, intVar);     Integral basis of an algebraic function field
+";
+
+LIB "normal.lib";
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc integralBasis(poly f, int intVar, list #)
+"USAGE: integralBasis(f, intVar); f irreducible polynomial in two variables,
+        intVar integer indicating that the intVar-th variable of the ring is the
+        integral element.@*
+        The base ring must be a ring in two variables, and the polynomial f
+        must be monic as polynomial in the intVar-th variable.@*
+        Optional parameters in list choose (can be entered in any order):@*
+        Parameters for selecting the algorithm:@*
+        - \"global\" -> computes the integral basis by computing the
+        normalization of R/<f>, where R is the base ring.@*
+        - \"local\" -> computes the integral basis by computing the
+        normalization of R/<f> localized at each component of the singular
+        locus of R/<f>, and then putting everything together.
+        This is the default option.@*
+        Other parameters:@*
+        - \"isIrred\" -> assumes that the input polynomial f is irreducible,
+        and therefore will not check this. If this option is given but f is not
+        irreducible, the output might be wrong.@*
+        - list(\"inputJ\", ideal inputJ) -> takes as initial test ideal the
+        ideal inputJ. This option is only for use in other procedures. Using
+        this option, the result might not be the integral basis.@*
+        (When this option is given, the global option will be used.)@*
+        - list(\"inputC\", ideal inputC) -> takes as initial conductor the
+        ideal inputC. This option is only for use in other procedures. Using
+        this option, the result might not be the integral basis.@*
+        (When this option is given, the global option will be used.)@*
+RETURN: a list, say l, of size 2.
+        l[1] is an ideal I and l[2] is a polynomial D such that the integral
+        basis is b_0 = I[1] / D, b_1 = I[2] / D, ..., b_{n-1} = I[n] / D.@*
+        That is, the integral closure of k[x] in the algebraic function
+        field k(x,y) is @*
+        k[x] b_0 + k[x] b_1 + ... + k[x] b_{n-1},@*
+        where we assume that x is the transcendental variable, y is the integral
+        element (indicated by intVar), f gives the integral equation and n is
+        the degree of f as a polynomial in y.@*
+
+THEORY:  We compute the integral basis of the integral closure of k[x] in k(x,y)
+         by computing the normalization of the affine ring k[x,y]/<f> and
+         converting the k[x,y]-module generators into a k[x]-basis.@*
+KEYWORDS: integral basis; normalization.
+SEE ALSO: normal.
+EXAMPLE: example integralBasis; shows an example
+"
+{
+  int i;
+  ideal inputJ = 0;
+  ideal inputC = 0;
+  string algorithm = "local";     // The default option is "local"
+  int checkIrred = 1;
+
+//--------------------------- read the input options---------------------------
+  for ( i=1; i <= size(#); i++ )
+  {
+    if ( typeof(#[i]) == "string" )
+    {
+      if (#[i]=="local"){
+        algorithm = "local";
+      }
+      if (#[i]=="global"){
+        algorithm = "global";
+      }
+      if (#[i]=="isIrred"){
+        checkIrred = 0;
+      }
+    }
+    if(typeof(#[i]) == "list"){
+      if(size(#[i]) == 2){
+        if (#[i][1]=="inputJ"){
+          if((typeof(#[i][2]) == "ideal") or (typeof(#[i][2]) == "poly")){
+            inputJ = #[i][2];
+            algorithm = "global";
+          }
+        }
+      }
+      if (#[i][1]=="inputC"){
+        if(size(#[i]) == 2){
+          if((typeof(#[i][2]) == "ideal") or (typeof(#[i][2]) == "poly")){
+            inputC = #[i][2];
+            algorithm = "global";
+          }
+        }
+      }
+    }
+  }
+
+//--------------------------- preliminary checks ------------------------------
+  // The ring must have two variables.
+  if(nvars(basering) != 2){
+    ERROR("The base ring must be a ring in two variables.");
+  }
+
+  // intVar must be either 1 or 2.
+  if((intVar < 0) || (intVar > 2)){
+      ERROR("The second parameter intVar must be either 1 or 2, indicating the
+            integral variable.");
+  }
+
+  // No parameters or algebraic numbers are allowed.
+  if(npars(basering) >0){
+    ERROR("No parameters or algebraic extensions are allowed in the base ring.");
+  }
+
+  // The polynomial f must be monic in the intVar-th variable.
+  matrix cs = coeffs(f, var(intVar));
+  if(cs[size(cs),1] != 1){
+      ERROR("The input polynomial must be monic as a polynomial in the
+            intVar-th variable.");
+  }
+
+  // The polynomial f must be irreducible.
+  if(checkIrred == 1){
+    if(factorize(f)[2] != [1,1]){
+        ERROR("The input polynomial must be irreducible.");
+    }
+  }
+
+//--------------------- computing the integral basis --------------------------
+  return(cancelCF(integralBasisMain(f, algorithm, inputJ, inputC, intVar)));
+}
+example
+{ "EXAMPLE:";
+  printlevel = printlevel+1;
+  echo = 2;
+  ring s = 0,(x,y),dp;
+  poly f = y5-y4x+4y2x2-x4;
+  list l = integralBasis(f, 2);
+  l;
+// The integral basis of the integral closure of Q[x] in Q(x,y) consists
+// of the elements of l[1] divided by the polynomial l[2].
+  echo = 0;
+  printlevel = printlevel-1;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static proc integralBasisMain(poly f, string algorithm, ideal inputJ, ideal inputC, int intVar)
+// Computes the integral basis of R/<f>, from the normalizaiton of R/<f>.
+// inputC is the conductor ideal to be used in proc normal.
+// If inputC = < 0 >, then the default conductor ideal is used (the full
+// jacobian ideal).
+// inputJ is the test ideal to be used in proc normal.
+// If inputJ = < 0 >, then the default test ideal is used (the radical of the
+// conductor).
+{
+  int dbg = printlevel - voice + 2;
+  int i, j;
+  int newRing = 0;    // If = 1, a new ring with dp ordering was used.
+  def origR = basering;
+
+//--------------------- moving to a ring with dp ordering ---------------------
+  if(ordstr(origR) != "dp(2),C"){
+    // We change to dp ordering.
+    list rl = ringlist(origR);
+    list origOrd = rl[3];
+    list newOrd = list("dp", intvec(1:nvars(origR))), list("C", 0);
+    rl[3] = newOrd;
+    def R = ring(rl);
+    setring R;
+    poly f = fetch(origR, f);
+    ideal inputJ = fetch(origR, inputJ);
+    ideal inputC = fetch(origR, inputC);
+    newRing = 1;
+  } else {
+    def R = basering;
+  }
+
+//-------------------------------- basic data ---------------------------------
+  // The degree of f with respect to the variable intVar
+  ideal I = f;
+  int n = size(coeffs(f, var(intVar))) - 1;
+
+  // If the integral variable is the first, then the universal denominator
+  // must be a polynomial in the second variable (and viceversa).
+  string conduStr;
+  if(intVar == 1){
+    conduStr = "var2";
+  } else {
+    conduStr = "var1";
+  }
+  list opts = conduStr;
+
+//-------------------------- computes the normalization -----------------------
+  if(algorithm == "local"){
+    list nor = integralLocal(I, opts);
+  } else {
+    if(inputJ != 0){
+      opts = insert(opts, list("inputJ", inputJ));
+    }
+    if(inputC != 0){
+      opts = insert(opts, list("inputC", inputC));
+    }
+    list nor = normal(I, opts);
+  }
+  ideal normalGen = nor[2][1];
+  poly D = normalGen[size(normalGen)];  // The universal denominator
+
+  //Debug information
+  if(dbg >= 2){
+    "The universal denominator is: ", D;
+  }
+
+//--------------- computes the integral basis from the normalization ----------
+  // We define a new ring where the integral variable is the first (needed for
+  // reduction) and has the appropiate ordering.
+  list rl = ringlist(R);
+  rl[2] = list(var(intVar), var(3-intVar));
+  rl[3] = list(list("C", 0), list("lp", intvec(1,1)));
+  def S = ring(rl);
+  setring S;
+
+  // We map the elements in the previous ring to the new one
+  poly f = imap(R, f);
+  ideal normalGen = imap(R, normalGen);
+
+  // We create the system of generatos y^i*f_j.
+  list l;
+  ideal red = groebner(f);
+  for(j = 1; j <= size(normalGen); j++){
+    l[j] = reduce(normalGen[j], red);
+  }
+  for(i = 1; i <= n-1; i++){
+    for(j = 1; j <= size(normalGen); j++){
+      l[size(l)+1] = reduce(var(1)^i*normalGen[j], red);
+    }
+  }
+
+  // To eliminate the redundant elements, we look at the polynomials as
+  // elements of a free module where the coordinates are the coefficients
+  // of the polynomials regarded as polynomials in y.
+  // The groebner basis of the module generated by these elements
+  // gives the desired basis.
+  matrix vecs[n + 1][size(l)];
+  matrix coeffi[n + 1][2];
+
+  for(i = 1; i<= size(l); i++){
+    coeffi = coeffs(l[i], var(1));
+    vecs[1..nrows(coeffi), i] = coeffi[1..nrows(coeffi), 1];
+  }
+  module M = vecs;
+  M = std(M);
+
+  // We go back to the original ring.
+  setring origR;
+  module M = imap(S, M);
+  if(newRing == 1){
+    poly D = fetch(R, D);
+  }
+
+  // We go back from the module to the ring in two variables
+  ideal G;
+  poly g;
+  for(i = 1; i <= size(M); i++){
+    g = 0;
+    for(j = 0; j <= n; j++){
+      g = g + M[i][j+1] * var(intVar)^j;
+    }
+    G[i] = g;
+  }
+
+  // The first element in the output is the ideal of numerators.
+  // The second element is the denominator.
+  list outp = G, D;
+
+  return(outp);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static proc integralLocal(ideal I, list #){
+// Computes the integral basis  by localizing at the different components of
+// the singular locus.
+  int i;
+  int dbg = printlevel - voice + 4;
+  def R = basering;
+
+  list n;         // Output of proc normal
+  ideal norT;     // Temporary data.
+  poly denomT;    // Temporary data.
+
+  ideal nor;      // Output of normal with the denominator changed to the
+                  // common denominator.
+  ideal res;      // The full integral basis
+
+//--------------------------- read the input options---------------------------
+  int denomOption = 0;
+  for ( i=1; i <= size(#); i++ )
+  {
+    if ( typeof(#[i]) == "string" )
+    {
+      if (#[i]=="var1")
+      {denomOption = 1;}
+      if (#[i]=="var2")
+      {denomOption = 2;}
+    }
+  }
+
+//------------------------ singular locus computation -------------------------
+  // We use a general method that works for any ideal.
+  // For I defined by a single polynomial a simpler method could be used.
+  list IM = mstd(I);
+  I = IM[1];
+  int d = dim(I);
+  ideal IMin = IM[2];
+  qring Q = I;  // We work in the quotient by the Groebner basis of the ideal I
+  option("redSB");
+  option("returnSB");
+  ideal I = fetch(R, I);
+  attrib(I, "isSB", 1);
+  ideal IMin = fetch(R, IMin);
+  if(dbg >= 2){
+    int t = timer;
+  }
+  ideal J = minor(jacob(IMin), nvars(basering) - d, I);
+  if(dbg >= 2){
+    "singular locus time: ", timer - t;
+    t = timer;
+  }
+  setring R;
+  ideal J = fetch(Q, J);
+  J = J, I;
+  J = groebner(J);
+
+  if(dbg >= 2){
+    "groebner of the singular locus time: ", timer - t;
+    t = timer;
+  }
+
+  if(dbg >= 2){
+    "The original singular locus is";
+    J;
+  }
+
+//------------------------ universal denominator ------------------------------
+  // We could use the LCD of the denominators of each component, but we need
+  // a denominator in the required variable.
+  if(denomOption == 0){
+    poly condu = getSmallest(J);   // Choses the polynomial of smallest degree
+                                   // of J as universal denominator.
+  } else {
+    poly condu = getOneVar(J, denomOption);
+  }
+
+//------------------- components of the singular locus------------------------
+  list pd = primdecGTZ(J);
+  if(dbg >= 2){
+    "primary decomposition time:", timer - t;
+  }
+  if(dbg >= 1){
+    "The number of components of the Singular Locus is ", size(pd);
+  }
+
+  // The following commented lines are not needed for integral basis, since
+  // all components are maximal.
+  // Computes the maximal components and the components included in them
+  //list comps = maxComps(pd);
+  // For each maximal component, it intersects all the components included in it
+  //list locs = intersectList(comps);
+
+//------------------- normalization of each component--------------------------
+  list opts;
+  for(i = 1; i <= size(pd); i++){
+    //opts = #;
+    // We use the prime components as test ideals in the normalization.
+    //opts = list(list("inputJ", pd[i][2]));
+    // We use the primary components as conductor in the normalization.
+    opts = list(list("inputC", pd[i][1]));
+
+    if(dbg >= 2){
+      t = timer;
+    }
+    n = normal(I, opts);
+    if(dbg >= 2){
+      "normalization of component ", i, " time: ", timer - t;
+    }
+    if(size(n[2]) > 1){
+      ERROR("The input polynomial is not irreducible.");
+    }
+
+    // We add up the normalizations at each localization, to construct the
+    // normalization of the whole ideal.
+    norT = n[2][1];
+    denomT = norT[size(norT)];
+
+    // We change the denominator of the normalization of the localized ring,
+    // to have the same denominator for all the normalizations.
+    nor = changeDenominator(norT, denomT, condu, I);
+
+    // We sum the result to the previous results.
+    res = res, nor;
+  }
+  res = groebner(res);
+  res[size(res)+1] = condu;
+
+  // The output follows the output of proc normal, but we don't return the
+  // ring structure, only the generators. (We return 0 instead of the ring.)
+  return(list(0,list(res)));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static proc cancelCF(list IB)
+"USAGE:  cancelCF(IB); IB list of type returned by integralBasis
+RETURN:  list of same type with  common factor cancelled.
+KEYWORDS: greatest common divisor.
+"
+{
+  int l = size(IB[1]);
+  poly GrCoDi = IB[2];
+  int k = l;
+  while((GrCoDi != 1) && (k >=1))
+      {
+        GrCoDi = gcd(GrCoDi,IB[1][k]);
+        k = k-1;
+      }
+  if(GrCoDi != 1)
+    {
+      for(k = 1; k <= l; k++)
+         {
+           IB[1][k] = IB[1][k]/GrCoDi;
+         }
+      IB[2] = IB[2]/GrCoDi;
+    }
+  return(IB);
+}
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+/*
+/////////////////////////////////////////////////////////////////////////////
+/// Examples for testing the main procedures
+/// Timings on wawa Sept 30
+/////////////////////////////////////////////////////////////////////////////
+LIB"integralbasis.lib";
+// -------------------------------------------------------
+// Example 1
+// -------------------------------------------------------
+ring r = 0, (x, y), dp;
+poly f = y5-y4x+4y2x2-x4;
+integralBasis(f, 2, "global");  // time 0
+integralBasis(f, 1);
+integralBasis(f, 2);  // local by default, time 0
+normal(f);
+kill r;
+// -------------------------------------------------------
+// Example 2
+// -------------------------------------------------------
+ring r = 0, (x, y), dp;
+poly f = y2-x2*(x+1)^2*(x+2);
+integralBasis(f, 2, "global");  // time 0
+integralBasis(f, 2);  // local by default, time 0
+integralBasis(f, 2, list(list("inputJ", ideal(x,y))));
+kill r;
+// -------------------------------------------------------
+// Example 3
+// -------------------------------------------------------
+ring RR = 0, (x,y), dp;
+poly f = 11y7+7y6x+8y5x2-3y4x3-10y3x4-10y2x5-x7-33y6-29y5x-13y4x2+26y3x3;
+f = f+30y2x4+10yx5+3x6+33y5+37y4x-8y3x2-33y2x3-20yx4-3x5-11y4-15y3x;
+f = f+13y2x2+10yx3+x4; // 3 OMPs of mult 3, 1 OMP of mult 4
+integralBasis(f, 2);
+f =1/11*f;
+integralBasis(f, 2, "global");  // time 2
+integralBasis(f, 2);  // local by default, time 0
+kill RR;
+// -------------------------------------------------------
+// Example 4
+// -------------------------------------------------------
+ring RR = 0, (x,y), dp;
+poly f = y^20+x*y^13+x^4*y^5+x^5+2*x^4+x^3;
+integralBasis(f, 2, "global");  // time 0
+integralBasis(f, 2);  // local by default,  time 0
+kill RR;
+// -------------------------------------------------------
+// Example 5
+// -------------------------------------------------------
+ring SS = 0, (u,v,z), dp;
+poly f = u^6+3*u^4*v^2+3*u^2*v^4+v^6-4*u^4*z^2-34*u^3*v*z^2-7*u^2*v^2*z^2;
+f = f+12*u*v^3*z^2+6*v^4*z^2+36*u^2*z^4+36*u*v*z^4+9*v^2*z^4;
+f = subst(f,z,1);
+ring RR = 0, (x,y), dp;
+poly f = fetch(SS,f);
+integralBasis(f, 2);  integralBasis(f, 2, "global");  // time 1
+integralBasis(f, 2);  // local by default, time 0
+kill RR, SS;
+// -------------------------------------------------------
+// Example 6
+// -------------------------------------------------------
+ring SS = 0, (u,v,z), dp;
+poly f = -24135/322*u^6-532037/6440*u^5*v+139459/560*u^4*v^2;
+f = f-1464887/12880*u^3*v^3+72187/25760*u^2*v^4+9/8*u*v^5+1/8*v^6;
+f = f-403511/3220*u^5*z-40817/920*u^4*v*z+10059/80*u^3*v^2*z;
+f = f-35445/1288*u^2*v^3*z+19/4*u*v^4*z+3/4*v^5*z-20743/805*u^4*z^2;
+f = f+126379/3220*u^3*v*z^2-423417/6440*u^2*v^2*z^2+11/2*u*v^3*z^2;
+f = f+3/2*v^4*z^2+3443/140*u^3*z^3+u^2*v*z^3+u*v^2*z^3+v^3*z^3;
+f = 8/27*subst(f,z,u+v+z);
+f = subst(f,z,1);
+ring RR = 0, (x,y), dp;
+poly f = fetch(SS,f);
+integralBasis(f, 2, "global");  // time 3
+integralBasis(f, 2);  // local by default, time 0
+kill RR, SS;
+// -------------------------------------------------------
+// Example 8
+// -------------------------------------------------------
+ring SS = 0, (u,v,z), dp;
+poly f = 25*u^8+184*u^7*v+518*u^6*v^2+720*u^5*v^3+576*u^4*v^4+282*u^3*v^5;
+f = f+84*u^2*v^6+14*u*v^7+v^8+244*u^7*z+1326*u^6*v*z+2646*u^5*v^2*z;
+f = f+2706*u^4*v^3*z+1590*u^3*v^4*z+546*u^2*v^5*z+102*u*v^6*z+8*v^7*z;
+f = f+854*u^6*z^2+3252*u^5*v*z^2+4770*u^4*v^2*z^2+3582*u^3*v^3*z^2;
+f = f+1476*u^2*v^4*z^2+318*u*v^5*z^2+28*v^6*z^2+1338*u^5*z^3+3740*u^4*v*z^3;
+f = f+4030*u^3*v^2*z^3+2124*u^2*v^3*z^3+550*u*v^4*z^3+56*v^5*z^3+1101*u^4*z^4;
+f = f+2264*u^3*v*z^4+1716*u^2*v^2*z^4+570*u*v^3*z^4+70*v^4*z^4+508*u^3*z^5;
+f = f+738*u^2*v*z^5+354*u*v^2*z^5+56*v^3*z^5+132*u^2*z^6+122*u*v*z^6;
+f = f+28*v^2*z^6+18*u*z^7+8*v*z^7+z^8;
+f = subst(f,z,1);
+ring RR = 0, (x,y), dp;
+poly f = fetch(SS,f);
+integralBasis(f, 2, "global");  // time 95
+integralBasis(f, 2);  // local by default, time  13
+kill RR, SS;
+// -------------------------------------------------------
+// Example 9
+// -------------------------------------------------------
+ring SS = 0, (u,v,z), dp;
+poly f = u^10+6*u^9*v-30*u^7*v^3-15*u^6*v^4+u^5*v^5+u^4*v^6+6*u^3*v^7+u^2*v^8;
+f = f+7*u*v^9+v^10+5*u^9*z+24*u^8*v*z-30*u^7*v^2*z-120*u^6*v^3*z-43*u^5*v^4*z;
+f = f+5*u^4*v^5*z+20*u^3*v^6*z+10*u^2*v^7*z+29*u*v^8*z+5*v^9*z;
+f = f+10*u^8*z^2+36*u^7*v*z^2-105*u^6*v^2*z^2-179*u^5*v^3*z^2;
+f = f-38*u^4*v^4*z^2+25*u^3*v^5*z^2+25*u^2*v^6*z^2+46*u*v^7*z^2;
+f = f+10*v^8*z^2+10*u^7*z^3+24*u^6*v*z^3-135*u^5*v^2*z^3;
+f = f-117*u^4*v^3*z^3-u^3*v^4*z^3+25*u^2*v^5*z^3+34*u*v^6*z^3;
+f = f+10*v^7*z^3+5*u^6*z^4+6*u^5*v*z^4-75*u^4*v^2*z^4-27*u^3*v^3*z^4;
+f = f+10*u^2*v^4*z^4+11*u*v^5*z^4+5*v^6*z^4+u^5*z^5;
+f = f-15*u^3*v^2*z^5+u^2*v^3*z^5+u*v^4*z^5+v^5*z^5;
+f = subst(f,z,1);
+ring RR = 0, (x,y), dp;
+poly f = fetch(SS,f);
+// integralBasis(f, 2, "global");  // fail
+integralBasis(f, 2);  //  local by default, time 2
+kill RR, SS;
+*/
+
+
diff --git a/Singular/LIB/intprog.lib b/Singular/LIB/intprog.lib
new file mode 100644
index 0000000..dd195bb
--- /dev/null
+++ b/Singular/LIB/intprog.lib
@@ -0,0 +1,750 @@
+//////////////////////////////////////////////////////////////////////////////
+version="version intprog.lib 4.0.0.0 Jun_2013 "; // $Id: 559512f5026260600db36a9d4b72968e9eca6e7c $
+category="Commutative Algebra";
+info="
+LIBRARY: intprog.lib      Integer Programming with Groebner Basis Methods
+AUTHOR:  Christine Theis, email: ctheis at math.uni-sb.de
+
+PROCEDURES:
+ solve_IP(..);   procedures for solving Integer Programming  problems
+";
+
+///////////////////////////////////////////////////////////////////////////////
+static proc solve_IP_1(intmat A, intvec bx, intvec c, string alg)
+{
+  intvec v;
+  // to be returned
+
+  // check arguments as far as necessary
+  // other inconsistencies are detected by the external program
+  if(size(c)!=ncols(A))
+  {
+    "ERROR: The number of matrix columns does not equal the size of the cost vector.";
+    return(v);
+  }
+
+  // create first temporary file with which the external program is
+  // called
+
+  int process=system("pid");
+  string matrixfile="temp_MATRIX"+string(process);
+  link MATRIX=":w "+matrixfile;
+  open(MATRIX);
+
+  write(MATRIX,"MATRIX","columns:",ncols(A),"cost vector:");
+  int i,j;
+  for(j=1;j<=ncols(A);j++)
+  {
+    write(MATRIX,c[j]);
+  }
+  write(MATRIX,"rows:",nrows(A),"matrix:");
+  for(i=1;i<=nrows(A);i++)
+  {
+    for(j=1;j<=ncols(A);j++)
+    {
+      write(MATRIX,A[i,j]);
+    }
+  }
+
+  // search for positive row space vector, if required by the
+  // algorithm
+  int found=0;
+  if((alg=="blr") || (alg=="hs"))
+  {
+    for(i=1;i<=nrows(A);i++)
+    {
+      found=i;
+      for(j=1;j<=ncols(A);j++)
+      {
+        if(A[i,j]<=0)
+        {
+          found=0;
+        }
+      }
+      if(found>0)
+      {
+        break;
+      }
+    }
+    if(found==0)
+    {
+      "ERROR: The chosen algorithm needs a positive vector in the row space of the matrix.";
+      close(MATRIX);
+      system("sh","rm -f "+matrixfile);
+      return(v);
+    }
+    write(MATRIX,"positive row space vector:");
+    for(j=1;j<=ncols(A);j++)
+    {
+      write(MATRIX,A[found,j]);
+    }
+  }
+  close(MATRIX);
+
+  // create second temporary file for the external program
+
+  string problemfile="temp_PROBLEM"+string(process);
+  link PROBLEM=":w "+problemfile;
+  open(PROBLEM);
+
+  write(PROBLEM,"PROBLEM","vector size:",size(bx),"number of instances:",1,"right hand or initial solution vectors:");
+  for(i=1;i<=size(bx);i++)
+  {
+    write(PROBLEM,bx[i]);
+  }
+  close(PROBLEM);
+
+  // call external program
+  int dummy=system("sh","solve_IP -alg "+alg+" "+matrixfile+" "+problemfile);
+
+  // read solution from created file
+  link SOLUTION=":r "+matrixfile+".sol."+alg;
+  string solution=read(SOLUTION);
+  int pos;
+  string s;
+  if(alg=="ct" || alg=="pct")
+  {
+    pos=find(solution,"NO");
+    if(pos!=0)
+    {
+      "not solvable";
+    }
+    else
+    {
+      pos=find(solution,"YES");
+      pos=find(solution,":",pos);
+      pos++;
+      for(j=1;j<=ncols(A);j++)
+      {
+        while(solution[pos]==" " || solution[pos]==newline)
+        {
+          pos++;
+        }
+        s="";
+        while(solution[pos]!=" " && solution[pos]!=newline)
+        {
+          s=s+solution[pos];
+          pos++;
+        }
+        execute("v[j]="+s+";");
+      }
+    }
+  }
+  else
+  {
+    pos=find(solution,"optimal");
+    pos=find(solution,":",pos);
+    pos++;
+    for(j=1;j<=ncols(A);j++)
+    {
+      while(solution[pos]==" " || solution[pos]==newline)
+      {
+        pos++;
+      }
+      s="";
+      while(solution[pos]!=" " && solution[pos]!=newline)
+      {
+        s=s+solution[pos];
+        pos++;
+      }
+      execute("v[j]="+s+";");
+    }
+  }
+
+  // delete all created files
+  dummy=system("sh","rm -f "+matrixfile);
+  dummy=system("sh","rm -f "+matrixfile+".GB."+alg);
+  dummy=system("sh","rm -f "+problemfile);
+  dummy=system("sh","rm -f "+matrixfile+".sol."+alg);
+
+  return(v);
+}
+///////////////////////////////////////////////////////////////////////////////
+static proc solve_IP_2(intmat A, list bx, intvec c, string alg)
+{
+  list l;;
+  // to be returned
+
+  // check arguments as far as necessary
+  // other inconsistencies are detected by the external program
+  if(size(c)!=ncols(A))
+  {
+    "ERROR: The number of matrix columns does not equal the size of the cost vector.";
+    return(l);
+  }
+
+  int k;
+  for(k=2;k<=size(bx);k++)
+  {
+    if(size(bx[k])!=size(bx[1]))
+    {
+      "ERROR: The size of all right-hand vectors must be equal.";
+      return(l);
+    }
+  }
+
+  // create first temporary file with which the external program is
+  // called
+
+  int process=system("pid");
+  string matrixfile="temp_MATRIX"+string(process);
+  link MATRIX=":w "+matrixfile;
+  open(MATRIX);
+
+  write(MATRIX,"MATRIX","columns:",ncols(A),"cost vector:");
+  int i,j;
+  for(j=1;j<=ncols(A);j++)
+  {
+    write(MATRIX,c[j]);
+  }
+  write(MATRIX,"rows:",nrows(A),"matrix:");
+  for(i=1;i<=nrows(A);i++)
+  {
+    for(j=1;j<=ncols(A);j++)
+    {
+      write(MATRIX,A[i,j]);
+    }
+  }
+
+  // search for positive row space vector, if required by the
+  // algorithm
+  int found=0;
+  if((alg=="blr") || (alg=="hs"))
+  {
+    for(i=1;i<=nrows(A);i++)
+    {
+      found=i;
+      for(j=1;j<=ncols(A);j++)
+      {
+        if(A[i,j]<=0)
+        {
+          found=0;
+        }
+      }
+      if(found>0)
+      {
+        break;
+      }
+    }
+    if(found==0)
+    {
+      "ERROR: The chosen algorithm needs a positive vector in the row space of the matrix.";
+      close(MATRIX);
+      system("sh","rm -f "+matrixfile);
+      return(l);
+    }
+    write(MATRIX,"positive row space vector:");
+    for(j=1;j<=ncols(A);j++)
+    {
+      write(MATRIX,A[found,j]);
+    }
+  }
+  close(MATRIX);
+
+  // create second temporary file for the external program
+
+  string problemfile="temp_PROBLEM"+string(process);
+  link PROBLEM=":w "+problemfile;
+  open(PROBLEM);
+
+  write(PROBLEM,"PROBLEM","vector size:",size(bx[1]),"number of instances:",size(bx),"right hand or initial solution vectors:");
+  for(k=1;k<=size(bx);k++)
+  {
+    for(i=1;i<=size(bx[1]);i++)
+    {
+      write(PROBLEM,bx[k][i]);
+    }
+  }
+  close(PROBLEM);
+
+  // call external program
+  int dummy=system("sh","solve_IP -alg "+alg+" "+matrixfile+" "+problemfile);
+
+  // read solution from created file
+  link SOLUTION=":r "+matrixfile+".sol."+alg;
+  string solution=read(SOLUTION);
+  intvec v;
+  int pos,pos1,pos2;
+  string s;
+  if(alg=="ct" || alg=="pct")
+  {
+    pos=1;
+    for(k=1;k<=size(bx);k++)
+    {
+      pos1=find(solution,"NO",pos);
+      pos2=find(solution,"YES",pos);
+      if(pos1!=0 && (pos1<pos2 || pos2==0))
+        // first problem not solvable
+      {
+        pos=find(solution,":",pos1);
+        l=insert(l,"not solvable",size(l));
+      }
+      else
+        // first problem solvable
+      {
+        pos=find(solution,":",pos2);
+        pos++;
+        for(j=1;j<=ncols(A);j++)
+        {
+          while(solution[pos]==" " || solution[pos]==newline)
+          {
+            pos++;
+          }
+          s="";
+          while(solution[pos]!=" " && solution[pos]!=newline)
+          {
+            s=s+solution[pos];
+            pos++;
+          }
+          execute("v[j]="+s+";");
+        }
+        l=insert(l,v,size(l));
+      }
+    }
+  }
+  else
+  {
+    pos=1;
+    for(k=1;k<=size(bx);k++)
+    {
+      pos=find(solution,"optimal",pos);
+      pos=find(solution,":",pos);
+      pos++;
+      for(j=1;j<=ncols(A);j++)
+      {
+        while(solution[pos]==" " || solution[pos]==newline)
+        {
+          pos++;
+        }
+        s="";
+        while(solution[pos]!=" " && solution[pos]!=newline)
+        {
+          s=s+solution[pos];
+          pos++;
+        }
+        execute("v[j]="+s+";");
+      }
+      l=insert(l,v,size(l));
+    }
+  }
+
+  // delete all created files
+  dummy=system("sh","rm -f "+matrixfile);
+  dummy=system("sh","rm -f "+matrixfile+".GB."+alg);
+  dummy=system("sh","rm -f "+problemfile);
+  dummy=system("sh","rm -f "+matrixfile+".sol."+alg);
+
+  return(l);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+static proc solve_IP_3(intmat A, intvec bx, intvec c, string alg, intvec prsv)
+{
+  intvec v;
+  // to be returned
+
+  // check arguments as far as necessary
+  // other inconsistencies are detected by the external program
+  if(size(c)!=ncols(A))
+  {
+    "ERROR: The number of matrix columns does not equal the size of the cost vector.";
+    return(v);
+  }
+
+  if(size(prsv)!=ncols(A))
+  {
+    "ERROR: The number of matrix columns does not equal the size of the positive row space vector.";
+    return(v);
+  }
+
+  // create first temporary file with which the external program is
+  // called
+
+  int process=system("pid");
+  string matrixfile="temp_MATRIX"+string(process);
+  link MATRIX=":w "+matrixfile;
+  open(MATRIX);
+
+  write(MATRIX,"MATRIX","columns:",ncols(A),"cost vector:");
+  int i,j;
+  for(j=1;j<=ncols(A);j++)
+  {
+    write(MATRIX,c[j]);
+  }
+  write(MATRIX,"rows:",nrows(A),"matrix:");
+  for(i=1;i<=nrows(A);i++)
+  {
+    for(j=1;j<=ncols(A);j++)
+    {
+      write(MATRIX,A[i,j]);
+    }
+  }
+
+  // enter positive row space vector, if required by the algorithm
+  if((alg=="blr") || (alg=="hs"))
+  {
+    write(MATRIX,"positive row space vector:");
+    for(j=1;j<=ncols(A);j++)
+    {
+      write(MATRIX,prsv[j]);
+    }
+  }
+  close(MATRIX);
+
+  // create second temporary file for the external program
+
+  string problemfile="temp_PROBLEM"+string(process);
+  link PROBLEM=":w "+problemfile;
+  open(PROBLEM);
+
+  write(PROBLEM,"PROBLEM","vector size:",size(bx),"number of instances:",1,"right hand or initial solution vectors:");
+  for(i=1;i<=size(bx);i++)
+  {
+    write(PROBLEM,bx[i]);
+  }
+  close(PROBLEM);
+
+  // call external program
+  int dummy=system("sh","solve_IP -alg "+alg+" "+matrixfile+" "+problemfile);
+
+  // read solution from created file
+  link SOLUTION=":r "+matrixfile+".sol."+alg;
+  string solution=read(SOLUTION);
+  int pos;
+  string s;
+  if(alg=="ct" || alg=="pct")
+  {
+    pos=find(solution,"NO");
+    if(pos!=0)
+    {
+      "not solvable";
+    }
+    else
+    {
+      pos=find(solution,"YES");
+      pos=find(solution,":",pos);
+      pos++;
+      for(j=1;j<=ncols(A);j++)
+      {
+        while(solution[pos]==" " || solution[pos]==newline)
+        {
+          pos++;
+        }
+        s="";
+        while(solution[pos]!=" " && solution[pos]!=newline)
+        {
+          s=s+solution[pos];
+          pos++;
+        }
+        execute("v[j]="+s+";");
+      }
+    }
+  }
+  else
+  {
+    pos=find(solution,"optimal");
+    pos=find(solution,":",pos);
+    pos++;
+    for(j=1;j<=ncols(A);j++)
+    {
+      while(solution[pos]==" " || solution[pos]==newline)
+      {
+        pos++;
+      }
+      s="";
+      while(solution[pos]!=" " && solution[pos]!=newline)
+      {
+        s=s+solution[pos];
+        pos++;
+      }
+      execute("v[j]="+s+";");
+    }
+  }
+
+  // delete all created files
+  dummy=system("sh","rm -f "+matrixfile);
+  dummy=system("sh","rm -f "+matrixfile+".GB."+alg);
+  dummy=system("sh","rm -f "+problemfile);
+  dummy=system("sh","rm -f "+matrixfile+".sol."+alg);
+
+  return(v);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+static proc solve_IP_4(intmat A, list bx, intvec c, string alg, intvec prsv)
+{
+  list l;
+  // to be returned
+
+  // check arguments as far as necessary
+  // other inconsistencies are detected by the external program
+  if(size(c)!=ncols(A))
+  {
+    "ERROR: The number of matrix columns does not equal the size of the cost vector.";
+    return(l);
+  }
+
+  if(size(prsv)!=ncols(A))
+  {
+    "ERROR: The number of matrix columns does not equal the size of the positive row space vector";
+    return(v);
+  }
+
+  int k;
+  for(k=2;k<=size(bx);k++)
+  {
+    if(size(bx[k])!=size(bx[1]))
+    {
+      "ERROR: The size of all right-hand vectors must be equal.";
+      return(l);
+    }
+  }
+
+  // create first temporary file with which the external program is
+  // called
+
+  int process=system("pid");
+  string matrixfile="temp_MATRIX"+string(process);
+  link MATRIX=":w "+matrixfile;
+  open(MATRIX);
+
+  write(MATRIX,"MATRIX","columns:",ncols(A),"cost vector:");
+  int i,j;
+  for(j=1;j<=ncols(A);j++)
+  {
+    write(MATRIX,c[j]);
+  }
+  write(MATRIX,"rows:",nrows(A),"matrix:");
+  for(i=1;i<=nrows(A);i++)
+  {
+    for(j=1;j<=ncols(A);j++)
+    {
+      write(MATRIX,A[i,j]);
+    }
+  }
+
+  // enter positive row space vector if required by the algorithm
+  if((alg=="blr") || (alg=="hs"))
+  {
+    write(MATRIX,"positive row space vector:");
+    for(j=1;j<=ncols(A);j++)
+    {
+      write(MATRIX,prsv[j]);
+    }
+  }
+  close(MATRIX);
+
+  // create second temporary file for the external program
+
+  string problemfile="temp_PROBLEM"+string(process);
+  link PROBLEM=":w "+problemfile;
+  open(PROBLEM);
+
+  write(PROBLEM,"PROBLEM","vector size:",size(bx[1]),"number of instances:",size(bx),"right hand or initial solution vectors:");
+  for(k=1;k<=size(bx);k++)
+  {
+    for(i=1;i<=size(bx[1]);i++)
+    {
+      write(PROBLEM,bx[k][i]);
+    }
+  }
+  close(PROBLEM);
+
+  // call external program
+  int dummy=system("sh","solve_IP -alg "+alg+" "+matrixfile+" "+problemfile);
+
+  // read solution from created file
+  link SOLUTION=":r "+matrixfile+".sol."+alg;
+  string solution=read(SOLUTION);
+  intvec v;
+  int pos,pos1,pos2;
+  string s;
+  if(alg=="ct" || alg=="pct")
+  {
+    pos=1;
+    for(k=1;k<=size(bx);k++)
+    {
+      pos1=find(solution,"NO",pos);
+      pos2=find(solution,"YES",pos);
+      if(pos1!=0 && (pos1<pos2 || pos2==0))
+        // first problem not solvable
+      {
+        pos=find(solution,":",pos1);
+        l=insert(l,"not solvable",size(l));
+      }
+      else
+        // first problem solvable
+      {
+        pos=find(solution,":",pos2);
+        pos++;
+        for(j=1;j<=ncols(A);j++)
+        {
+          while(solution[pos]==" " || solution[pos]==newline)
+          {
+            pos++;
+          }
+          s="";
+          while(solution[pos]!=" " && solution[pos]!=newline)
+          {
+            s=s+solution[pos];
+            pos++;
+          }
+          execute("v[j]="+s+";");
+        }
+        l=insert(l,v,size(l));
+      }
+    }
+  }
+  else
+  {
+    pos=1;
+    for(k=1;k<=size(bx);k++)
+    {
+      pos=find(solution,"optimal",pos);
+      pos=find(solution,":",pos);
+      pos++;
+      for(j=1;j<=ncols(A);j++)
+      {
+        while(solution[pos]==" " || solution[pos]==newline)
+        {
+          pos++;
+        }
+        s="";
+        while(solution[pos]!=" " && solution[pos]!=newline)
+        {
+          s=s+solution[pos];
+          pos++;
+        }
+        execute("v[j]="+s+";");
+      }
+      l=insert(l,v,size(l));
+    }
+  }
+
+  // delete all created files
+  dummy=system("sh","rm -f "+matrixfile);
+  dummy=system("sh","rm -f "+matrixfile+".GB."+alg);
+  dummy=system("sh","rm -f "+problemfile);
+  dummy=system("sh","rm -f "+matrixfile+".sol."+alg);
+
+  return(l);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc solve_IP
+"USAGE:  solve_IP(A,bx,c,alg);  A intmat, bx intvec, c intvec, alg string.@*
+        solve_IP(A,bx,c,alg);  A intmat, bx list of intvec, c intvec,
+                                 alg string.@*
+        solve_IP(A,bx,c,alg,prsv);  A intmat, bx intvec, c intvec,
+                                 alg string, prsv intvec.@*
+        solve_IP(A,bx,c,alg,prsv);  A intmat, bx list of intvec, c intvec,
+                                 alg string, prsv intvec.
+RETURN: same type as bx: solution of the associated integer programming
+        problem(s) as explained in
+   @texinfo
+   @ref{Toric ideals and integer programming}.
+   @end texinfo
+NOTE:   This procedure returns the solution(s) of the given IP-problem(s)
+        or the message `not solvable'.
+        One may call the procedure with several different algorithms:
+        @*- the algorithm of Conti/Traverso (ct),
+        @*- the positive variant of the algorithm of Conti/Traverso (pct),
+        @*- the algorithm of Conti/Traverso using elimination (ect),
+        @*- the algorithm of Pottier (pt),
+        @*- an algorithm of Bigatti/La Scala/Robbiano (blr),
+        @*- the algorithm of Hosten/Sturmfels (hs),
+        @*- the algorithm of DiBiase/Urbanke (du).
+        @*The argument `alg' should be the abbreviation for an algorithm as
+        above: ct, pct, ect, pt, blr, hs or du.
+
+        `ct' allows computation of an optimal solution of the IP-problem
+        directly from the right-hand vector b.
+        The same is true for its `positive' variant `pct' which may only be
+        applied if A and b have nonnegative entries.
+        All other algorithms need initial solutions of the IP-problem.
+
+        If `alg' is chosen to be `ct' or `pct', bx is read as the right hand
+        vector b of the system Ax=b. b should then be an intvec of size m
+        where m is the number of rows of A.
+        Furthermore, bx and A should be nonnegative if `pct' is used.
+        If `alg' is chosen to be `ect',`pt',`blr',`hs' or `du',
+        bx is read as an initial solution x of the system Ax=b.
+        bx should then be a nonnegative intvec of size n where n is the
+        number of columns of A.
+
+        If `alg' is chosen to be `blr' or `hs', the algorithm needs a vector
+        with positive coefficients in the row space of A.
+        If no row of A contains only positive entries, one has to use the
+        versions of solve_IP which take such a vector prsv as an argument.
+
+        solve_IP may also be called with a list bx of intvecs instead of a
+        single intvec.
+SEE ALSO: intprog_lib, toric_lib, Integer programming
+EXAMPLE:  example solve_IP; shows an example
+"
+{
+  if(size(#)==4)
+  {
+    if(typeof(#[2])=="intvec")
+    {
+      return(solve_IP_1(#[1],#[2],#[3],#[4]));
+    }
+    else
+    {
+      return(solve_IP_2(#[1],#[2],#[3],#[4]));
+    }
+  }
+  else
+  {
+    if(typeof(#[2])=="intvec")
+    {
+      return(solve_IP_3(#[1],#[2],#[3],#[4],#[5]));
+    }
+    else
+    {
+      return(solve_IP_4(#[1],#[2],#[3],#[4],#[5]));
+    }
+  }
+}
+
+
+
+example
+{ "EXAMPLE"; echo=2;
+  // 1. call with single right-hand vector
+  intmat A[2][3]=1,1,0,0,1,1;
+  intvec b1=1,1;
+  intvec c=2,2,1;
+  intvec solution_vector=solve_IP(A,b1,c,"pct");
+  solution_vector;"";
+
+  // 2. call with list of right-hand vectors
+  intvec b2=-1,1;
+  list l=b1,b2;
+  l;
+  list solution_list=solve_IP(A,l,c,"ct");
+  solution_list;"";
+
+  // 3. call with single initial solution vector
+  A=2,1,-1,-1,1,2;
+  b1=3,4,5;
+  solve_IP(A,b1,c,"du");"";
+
+  // 4. call with single initial solution vector
+  //    and algorithm needing a positive row space vector
+  solution_vector=solve_IP(A,b1,c,"hs");"";
+
+  // 5. call with single initial solution vector
+  //     and positive row space vector
+  intvec prsv=1,2,1;
+  solution_vector=solve_IP(A,b1,c,"hs",prsv);
+  solution_vector;"";
+
+  // 6. call with list of initial solution vectors
+  //    and positive row space vector
+  b2=7,8,0;
+  l=b1,b2;
+  l;
+  solution_list=solve_IP(A,l,c,"blr",prsv);
+  solution_list;
+}
diff --git a/Singular/LIB/involut.lib b/Singular/LIB/involut.lib
new file mode 100644
index 0000000..138f91a
--- /dev/null
+++ b/Singular/LIB/involut.lib
@@ -0,0 +1,980 @@
+///////////////////////////////////////////////////////////////////
+version="version involut.lib 4.0.0.0 Jun_2013 "; // $Id: 864f88265ee45107261492c57d3979b1e7fa4982 $
+category="Noncommutative";
+info="
+LIBRARY:  involut.lib  Computations and operations with involutions
+AUTHORS:  Oleksandr Iena,       yena at mathematik.uni-kl.de,
+@*        Markus Becker,        mbecker at mathematik.uni-kl.de,
+@*        Viktor Levandovskyy,  levandov at mathematik.uni-kl.de
+
+OVERVIEW:
+Involution is an anti-automorphism of a non-commutative K-algebra
+with the property that applied an involution twice, one gets an identity.
+Involution is linear with respect to the ground field. In this library we
+compute linear involutions, distinguishing the case of a diagonal matrix
+(such involutions are called homothetic) and a general one.
+Also, linear automorphisms of different order can be computed.
+
+SUPPORT: Forschungsschwerpunkt 'Mathematik und Praxis' (Project of Dr. E. Zerz
+and V. Levandovskyy), Uni Kaiserslautern
+
+REMARK: This library provides algebraic tools for computations and operations
+with algebraic involutions and linear automorphisms of non-commutative algebras
+
+PROCEDURES:
+findInvo();          computes linear involutions on a basering;
+findInvoDiag();     computes homothetic (diagonal) involutions on a basering;
+findAuto(n);          computes linear automorphisms of order n of a basering;
+ncdetection();        computes an ideal, presenting an involution map on some particular noncommutative algebras;
+involution(m,theta);  applies the involution to an object;
+isInvolution(F); check whether a map F in an involution;
+isAntiEndo(F);   check whether a map F in an antiendomorphism.
+";
+
+LIB "nctools.lib";
+LIB "ncalg.lib";
+LIB "poly.lib";
+LIB "primdec.lib";
+///////////////////////////////////////////////////////////////////////////////
+proc ncdetection()
+"USAGE:  ncdetection();
+RETURN:  ideal, representing an involution map
+PURPOSE: compute classical involutions (i.e. acting rather on operators than on variables) for some particular noncommutative algebras
+ASSUME: the procedure is aimed at non-commutative algebras with differential, shift or advance operators arising in Control Theory.
+It has to be executed in a ring.
+EXAMPLE: example ncdetection; shows an example
+"{
+// in this procedure an involution map is generated from the NCRelations
+// that will be used in the function involution
+// in dieser proc. wird eine matrix erzeugt, die in der i-ten zeile die indices
+// der differential-, shift- oder advance-operatoren enthaelt mit denen die i-te
+// variable nicht kommutiert.
+  if ( nameof(basering)=="basering" )
+  {
+    "No current ring defined.";
+    return(ideal(0));
+  }
+  def r = basering;
+  setring r;
+  int i,j,k,LExp;
+  int NVars  = nvars(r);
+  matrix rel = ncRelations(r)[2];
+  intmat M[NVars][3];
+  int NRows = nrows(rel);
+  intvec v,w;
+  poly d,d_lead;
+  ideal I;
+  map theta;
+  for( j=NRows; j>=2; j-- )
+  {
+   if( rel[j] == w )       //the whole column is zero
+    {
+      j--;
+      continue;
+    }
+    for( i=1; i<j; i++ )
+    {
+      if( rel[i,j]==1 )        //relation of type var(j)*var(i) = var(i)*var(j) +1
+      {
+         M[i,1]=j;
+      }
+      if( rel[i,j] == -1 )    //relation of type var(i)*var(j) = var(j)*var(i) -1
+      {
+        M[j,1]=i;
+      }
+      d = rel[i,j];
+      d_lead = lead(d);
+      v = leadexp(d_lead); //in the next lines we check wether we have a  relation of differential or shift type
+      LExp=0;
+      for(k=1; k<=NVars; k++)
+      {
+        LExp = LExp + v[k];
+      }
+      //      if( (d-d_lead != 0) || (LExp > 1) )
+if ( ( (d-d_lead) != 0) || (LExp > 1) || ( (LExp==0) && ((d_lead>1) || (d_lead<-1)) ) )
+      {
+        return(theta);
+      }
+
+      if( v[j] == 1)                   //relation of type var(j)*var(i) = var(i)*var(j) -lambda*var(j)
+      {
+        if (leadcoef(d) < 0)
+        {
+          M[i,2] = j;
+        }
+        else
+        {
+          M[i,3] = j;
+        }
+      }
+      if( v[i]==1 )                    //relation of type var(j)*var(i) = var(i)*var(j) -lambda*var(i)
+      {
+        if (leadcoef(d) > 0)
+        {
+          M[j,2] = i;
+        }
+        else
+        {
+          M[j,3] = i;
+        }
+      }
+    }
+  }
+  // from here on, the map is computed
+  for(i=1;i<=NVars;i++)
+  {
+    I=I+var(i);
+  }
+
+  for(i=1;i<=NVars;i++)
+  {
+    if( M[i,1..3]==(0,0,0) )
+    {
+      i++;
+      continue;
+    }
+    if( M[i,1]!=0 )
+    {
+      if( (M[i,2]!=0) && (M[i,3]!=0) )
+      {
+        I[M[i,1]] = -var(M[i,1]);
+        I[M[i,2]] = var(M[i,3]);
+        I[M[i,3]] = var(M[i,2]);
+      }
+      if( (M[i,2]==0) && (M[i,3]==0) )
+      {
+        I[M[i,1]] = -var(M[i,1]);
+      }
+      if( ( (M[i,2]!=0) && (M[i,3]==0) )|| ( (M[i,2]!=0) && (M[i,3]==0) )
+)
+      {
+        I[i] = -var(i);
+      }
+    }
+    else
+    {
+      if( (M[i,2]!=0) && (M[i,3]!=0) )
+      {
+        I[i] = -var(i);
+        I[M[i,2]] = var(M[i,3]);
+        I[M[i,3]] = var(M[i,2]);
+      }
+      else
+      {
+        I[i] = -var(i);
+      }
+    }
+  }
+  return(I);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring R = 0,(x,y,z,D(1..3)),dp;
+  matrix D[6][6];
+  D[1,4]=1; D[2,5]=1;  D[3,6]=1;
+  def r = nc_algebra(1,D); setring r;
+  ncdetection();
+  kill r, R;
+  //----------------------------------------
+  ring R=0,(x,S),dp;
+  def r = nc_algebra(1,-S); setring r;
+  ncdetection();
+  kill r, R;
+  //----------------------------------------
+  ring R=0,(x,D(1),S),dp;
+  matrix D[3][3];
+  D[1,2]=1;  D[1,3]=-S;
+  def r = nc_algebra(1,D); setring r;
+  ncdetection();
+}
+
+static proc In_Poly(poly mm, list l, int NVars)
+// applies the involution to the polynomial mm
+// entries of a list l are images of variables under invo
+// more general than invo_poly; used in many rings setting
+{
+  int i,j;
+  intvec v;
+  poly pp, zz;
+  poly nn = 0;
+  i = 1;
+  while(mm[i]!=0)
+  {
+    v  = leadexp(mm[i]);
+    zz = 1;
+    for( j=NVars; j>=1; j--)
+    {
+      if (v[j]!=0)
+      {
+        pp = l[j];
+        zz = zz*(pp^v[j]);
+      }
+    }
+    nn = nn + (leadcoef(mm[i])*zz);
+    i++;
+  }
+  return(nn);
+}
+
+static proc Hom_Poly(poly mm, list l, int NVars)
+// applies the endomorphism to the polynomial mm
+// entries of a list l are images of variables under endo
+// should not be replaced by map-based stuff! used in
+// many rings setting
+{
+  int i,j;
+  intvec v;
+  poly pp, zz;
+  poly nn = 0;
+  i = 1;
+  while(mm[i]!=0)
+  {
+    v  = leadexp(mm[i]);
+    zz = 1;
+    for( j=NVars; j>=1; j--)
+    {
+      if (v[j]!=0)
+      {
+        pp = l[j];
+        zz = (pp^v[j])*zz;
+      }
+    }
+    nn = nn + (leadcoef(mm[i])*zz);
+    i++;
+  }
+  return(nn);
+}
+
+static proc invo_poly(poly m, map theta)
+// applies the involution map theta to m, where m=polynomial
+{
+  // compatibility:
+  ideal l = ideal(theta);
+  int i;
+  list L;
+  for (i=1; i<=size(l); i++)
+  {
+    L[i] = l[i];
+  }
+  int nv = nvars(basering);
+  return (In_Poly(m,L,nv));
+//   if (m==0) { return(m); }
+//   int i,j;
+//   intvec v;
+//   poly p,z;
+//   poly n = 0;
+//   i = 1;
+//   while(m[i]!=0)
+//   {
+//     v = leadexp(m[i]);
+//     z =1;
+//     for(j=nvars(basering); j>=1; j--)
+//     {
+//       if (v[j]!=0)
+//       {
+//         p = var(j);
+//         p = theta(p);
+//         z = z*(p^v[j]);
+//       }
+//     }
+//     n = n + (leadcoef(m[i])*z);
+//     i++;
+//   }
+//   return(n);
+}
+///////////////////////////////////////////////////////////////////////////////////
+proc involution(def m, map theta)
+"USAGE:  involution(m, theta); m is a poly/vector/ideal/matrix/module, theta is a map
+RETURN:  object of the same type as m
+PURPOSE: applies the involution, presented by theta to the object m
+THEORY: for an involution theta and two polynomials a,b from the algebra,
+@*  theta(ab) = theta(b) theta(a); theta is linear with respect to the ground field
+NOTE: This is generalized ''theta(m)'' for data types unsupported by ''map''.
+EXAMPLE: example involution; shows an example
+"{
+  // applies the involution map theta to m,
+  // where m= vector, polynomial, module, matrix, ideal
+  int i,j;
+  intvec v;
+  poly p,z;
+  if (typeof(m)=="poly")
+  {
+    return (invo_poly(m,theta));
+  }
+  if ( typeof(m)=="ideal" )
+  {
+    ideal n;
+    for (i=1; i<=size(m); i++)
+    {
+      n[i] = invo_poly(m[i], theta);
+    }
+    return(n);
+  }
+  if (typeof(m)=="vector")
+  {
+    for(i=1; i<=size(m); i++)
+    {
+      m[i] = invo_poly(m[i], theta);
+    }
+    return (m);
+  }
+  if ( (typeof(m)=="matrix") || (typeof(m)=="module"))
+  {
+    matrix n = matrix(m);
+    int @R=nrows(n);
+    int @C=ncols(n);
+    for(i=1; i<=@R; i++)
+    {
+      for(j=1; j<=@C; j++)
+      {
+        if (m[i,j]!=0)
+        {
+          n[i,j] = invo_poly( m[i,j], theta);
+        }
+      }
+    }
+    if (typeof(m)=="module")
+    {
+      return (module(n));
+    }
+    else // matrix
+    {
+      return(n);
+    }
+  }
+  // if m is not of the supported type:
+  "Error: unsupported argument type!";
+  return();
+}
+example
+{
+  "EXAMPLE:";echo = 2;
+  ring R = 0,(x,d),dp;
+  def r = nc_algebra(1,1); setring r; // Weyl-Algebra
+  map F = r,x,-d;
+  F(F);  // should be maxideal(1) for an involution
+  poly f =  x*d^2+d;
+  poly If = involution(f,F);
+  f-If;
+  poly g = x^2*d+2*x*d+3*x+7*d;
+  poly tg = -d*x^2-2*d*x+3*x-7*d;
+  poly Ig = involution(g,F);
+  tg-Ig;
+  ideal I = f,g;
+  ideal II = involution(I,F);
+  II;
+  matrix(I) - involution(II,F);
+  module M  = [f,g,0],[g,0,x^2*d];
+  module IM = involution(M,F);
+  print(IM);
+  print(matrix(M) - involution(IM,F));
+}
+///////////////////////////////////////////////////////////////////////////////////
+static proc new_var()
+//generates a string of new variables
+{
+
+  int NVars=nvars(basering);
+  int i,j;
+  //  string s="@_1_1";
+  string s="a11";
+  for(i=1; i<=NVars; i++)
+  {
+    for(j=1; j<=NVars; j++)
+    {
+      if(i*j!=1)
+      {
+        s = s+ ","+NVAR(i,j);
+      }
+    }
+  }
+  return(s);
+}
+
+static proc NVAR(int i, int j)
+{
+  //  return("@_"+string(i)+"_"+string(j));
+  return("a"+string(i)+string(j));
+}
+///////////////////////////////////////////////////////////////////////////////////
+static proc new_var_special()
+//generates a string of new variables
+{
+  int NVars=nvars(basering);
+  int i;
+  //  string s="@_1_1";
+  string s="a11";
+  for(i=2; i<=NVars; i++)
+  {
+    s = s+ ","+NVAR(i,i);
+  }
+  return(s);
+}
+///////////////////////////////////////////////////////////////////////////////////
+static proc RelMatr()
+// returns the matrix of relations
+// only Lie-type relations x_j x_i= x_i x_j + .. are taken into account
+{
+  int i,j;
+  int NVars = nvars(basering);
+  matrix Rel[NVars][NVars];
+  for(i=1; i<NVars; i++)
+  {
+    for(j=i+1; j<=NVars; j++)
+    {
+      Rel[i,j]=var(j)*var(i)-var(i)*var(j);
+    }
+  }
+  return(Rel);
+}
+/////////////////////////////////////////////////////////////////
+proc findInvo()
+"USAGE: findInvo();
+RETURN: a ring containing a list L of pairs, where
+@*        L[i][1]  =  ideal; a Groebner Basis of an i-th associated prime,
+@*        L[i][2]  =  matrix, defining a linear map, with entries, reduced with respect to L[i][1]
+PURPOSE: computed the ideal of linear involutions of the basering
+ASSUME: the relations on the algebra are of the form YX = XY + D, that is
+the current ring is a G-algebra of Lie type.
+NOTE: for convenience, the full ideal of relations @code{idJ}
+and the initial matrix with indeterminates @code{matD} are exported in the output ring
+SEE ALSO: findInvoDiag, involution
+EXAMPLE: example findInvo; shows examples
+
+"{
+  def @B    = basering; //save the name of basering
+  int NVars = nvars(@B); //number of variables in basering
+  int i, j;
+
+  // check basering is of Lie type:
+  if (!isLieType())
+  {
+    ERROR("Assume violated: basering is of non-Lie type");
+  }
+
+  matrix Rel = RelMatr(); //the matrix of relations
+
+  string @ss   = new_var(); //string of new variables
+  string Par = parstr(@B); //string of parameters in old ring
+
+  if (Par=="") // if there are no parameters
+  {
+    execute("ring @@@KK=0,("+varstr(@B)+","+ at ss+"), dp;"); //new ring with new variables
+  }
+  else //if there exist parameters
+  {
+     execute("ring @@@KK=(0,"+Par+") ,("+varstr(@B)+","+ at ss+"), dp;");//new ring with new variables
+  }
+
+  matrix Rel = imap(@B, Rel); //consider the matrix of relations in new ring
+
+  int Sz = NVars*NVars+NVars; // number of variables in new ring
+
+  matrix M[Sz][Sz]; //to be the matrix of relations in new ring
+
+  for(i=1; i<NVars; i++) //initialize that matrix of relations
+  {
+    for(j=i+1; j<=NVars; j++)
+    {
+      M[i,j] = Rel[i,j];
+    }
+  }
+
+  def @@K = nc_algebra(1, M); setring @@K; //now new ring @@K become a noncommutative ring
+
+  list l; //list to define an involution
+  poly @@F;
+  for(i=1; i<=NVars; i++) //initializing list for involution
+  {
+    @@F=0;
+    for(j=1; j<=NVars; j++)
+    {
+      execute( "@@F = @@F+"+NVAR(i,j)+"*"+string( var(j) )+";" );
+    }
+    l=l+list(@@F);
+  }
+
+  matrix N = imap(@@@KK,Rel);
+
+  for(i=1; i<NVars; i++)//get matrix by applying the involution to relations
+  {
+    for(j=i+1; j<=NVars; j++)
+    {
+      N[i,j]= l[j]*l[i] - l[i]*l[j] + In_Poly( N[i,j], l, NVars);
+    }
+  }
+  kill l;
+  //---------------------------------------------
+  //get the ideal of coefficients of N
+  ideal J;
+  ideal idN = simplify(ideal(N),2);
+  J = ideal(coeffs( idN, var(1) ) );
+  for(i=2; i<=NVars; i++)
+  {
+    J = ideal( coeffs( J, var(i) ) );
+  }
+  J = simplify(J,2);
+  //-------------------------------------------------
+  if ( Par=="" ) //initializes the ring of relations
+  {
+    execute("ring @@KK=0,("+ at ss+"), dp;");
+  }
+  else
+  {
+    execute("ring @@KK=(0,"+Par+"),("+ at ss+"), dp;");
+  }
+  ideal J = imap(@@K,J); // ideal, considered in @@KK now
+  string snv = "["+string(NVars)+"]";
+  execute("matrix @@D"+snv+snv+"="+ at ss+";"); // matrix with entries=new variables
+
+  J = J, ideal( @@D*@@D-matrix( freemodule(NVars) ) ); // add the condition that involution to square is just identity
+  J = simplify(J,2); // without extra zeros
+  list mL = minAssGTZ(J); // components not in GB
+  int sL  = size(mL);
+  intvec saveopt=option(get);
+  option(redSB);       // important for reduced GBs
+  option(redTail);
+  matrix IM = @@D;     // involution map
+  list L    = list();  // the answer
+  list TL;
+  ideal tmp = 0;
+  for (i=1; i<=sL; i++) // compute GBs of components
+  {
+    TL    = list();
+    TL[1] = std(mL[i]);
+    tmp   = NF( ideal(IM), TL[1] );
+    TL[2] = matrix(tmp, NVars,NVars);
+    L[i]  = TL;
+  }
+  export(L); // main export
+  ideal idJ = J; // debug-comfortable exports
+  matrix matD = @@D;
+  export(idJ);
+  export(matD);
+  option(set,saveopt);
+  return(@@KK);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  def a = makeWeyl(1);
+  setring a; // this algebra is a first Weyl algebra
+  a;
+  def X = findInvo();
+  setring X; // ring with new variables, corr. to unknown coefficients
+  X;
+  L;
+  // look at the matrix in the new variables, defining the linear involution
+  print(L[1][2]);
+  L[1][1];  // where new variables obey these relations
+  idJ;
+}
+///////////////////////////////////////////////////////////////////////////
+proc findInvoDiag()
+"USAGE: findInvoDiag();
+RETURN: a ring together with a list of pairs L, where
+@*        L[i][1]  =  ideal; a Groebner Basis of an i-th associated prime,
+@*        L[i][2]  =  matrix, defining a linear map, with entries, reduced with respect to L[i][1]
+PURPOSE: compute homothetic (diagonal) involutions of the basering
+ASSUME: the relations on the algebra are of the form YX = XY + D, that is
+the current ring is a G-algebra of Lie type.
+NOTE: for convenience, the full ideal of relations @code{idJ}
+and the initial matrix with indeterminates @code{matD} are exported in the output ring
+SEE ALSO: findInvo, involution
+EXAMPLE: example findInvoDiag; shows examples
+"{
+  def @B    = basering; //save the name of basering
+  int NVars = nvars(@B); //number of variables in basering
+  int i, j;
+
+  // check basering is of Lie type:
+  if (!isLieType())
+  {
+    ERROR("Assume violated: basering is of non-Lie type");
+  }
+
+  matrix Rel = RelMatr(); //the matrix of relations
+
+  string @ss   = new_var_special(); //string of new variables
+  string Par = parstr(@B); //string of parameters in old ring
+
+  if (Par=="") // if there are no parameters
+  {
+    execute("ring @@@KK=0,("+varstr(@B)+","+ at ss+"), dp;"); //new ring with new variables
+  }
+  else //if there exist parameters
+  {
+    execute("ring @@@KK=(0,"+Par+") ,("+varstr(@B)+","+ at ss+"), dp;");//new ring with new variables
+  }
+
+  matrix Rel = imap(@B, Rel); //consider the matrix of relations in new ring
+
+  int Sz = 2*NVars; // number of variables in new ring
+
+  matrix M[Sz][Sz]; //to be the matrix of relations in new ring
+  for(i=1; i<NVars; i++) //initialize that matrix of relations
+  {
+    for(j=i+1; j<=NVars; j++)
+    {
+      M[i,j] = Rel[i,j];
+    }
+  }
+
+  def @@K = nc_algebra(1, M); setring @@K; //now new ring @@K become a noncommutative ring
+
+  list l; //list to define an involution
+
+  for(i=1; i<=NVars; i++) //initializing list for involution
+  {
+    execute( "l["+string(i)+"]="+NVAR(i,i)+"*"+string( var(i) )+";" );
+
+  }
+  matrix N = imap(@@@KK,Rel);
+
+  for(i=1; i<NVars; i++)//get matrix by applying the involution to relations
+  {
+    for(j=i+1; j<=NVars; j++)
+    {
+      N[i,j]= l[j]*l[i] - l[i]*l[j] + In_Poly( N[i,j], l, NVars);
+    }
+  }
+  kill l;
+  //---------------------------------------------
+  //get the ideal of coefficients of N
+
+  ideal J;
+  ideal idN = simplify(ideal(N),2);
+  J = ideal(coeffs( idN, var(1) ) );
+  for(i=2; i<=NVars; i++)
+  {
+    J = ideal( coeffs( J, var(i) ) );
+  }
+  J = simplify(J,2);
+  //-------------------------------------------------
+
+  if ( Par=="" ) //initializes the ring of relations
+  {
+    execute("ring @@KK=0,("+ at ss+"), dp;");
+  }
+  else
+  {
+    execute("ring @@KK=(0,"+Par+"),("+ at ss+"), dp;");
+  }
+
+  ideal J = imap(@@K,J); // ideal, considered in @@KK now
+
+  matrix @@D[NVars][NVars]; // matrix with entries=new variables to square i.e. @@D=@@D^2
+  for(i=1;i<=NVars;i++)
+  {
+    execute("@@D["+string(i)+","+string(i)+"]="+NVAR(i,i)+";");
+  }
+  J = J, ideal( @@D*@@D - matrix( freemodule(NVars) ) ); // add the condition that involution to square is just identity
+  J = simplify(J,2); // without extra zeros
+
+  list mL = minAssGTZ(J); // components not in GB
+  int sL  = size(mL);
+  intvec saveopt=option(get);
+  option(redSB); // important for reduced GBs
+  option(redTail);
+  matrix IM = @@D; // involution map
+  list L = list(); // the answer
+  list TL;
+  ideal tmp = 0;
+  for (i=1; i<=sL; i++) // compute GBs of components
+  {
+    TL    = list();
+    TL[1] = std(mL[i]);
+    tmp   = NF( ideal(IM), TL[1] );
+    TL[2] = matrix(tmp, NVars,NVars);
+    L[i]  = TL;
+  }
+  export(L);
+  ideal idJ = J; // debug-comfortable exports
+  matrix matD = @@D;
+  export(idJ);
+  export(matD);
+  option(set,saveopt);
+  return(@@KK);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  def a = makeWeyl(1);
+  setring a; // this algebra is a first Weyl algebra
+  a;
+  def X = findInvoDiag();
+  setring X; // ring with new variables, corresponding to unknown coefficients
+  X;
+  // print matrices, defining linear involutions
+  print(L[1][2]);  // a first matrix: we see it is constant
+  print(L[2][2]);  // and a second possible matrix; it is constant too
+  L; // let us take a look on the whole list
+  idJ;
+}
+/////////////////////////////////////////////////////////////////////
+proc findAuto(int n)
+"USAGE: findAuto(n); n an integer
+RETURN: a ring together with a list of pairs L, where
+@*        L[i][1]  =  ideal; a Groebner Basis of an i-th associated prime,
+@*        L[i][2]  =  matrix, defining a linear map, with entries, reduced with respect to L[i][1]
+PURPOSE: compute the ideal of linear automorphisms of the basering,
+@*  given by a matrix, n-th power of which gives identity (i.e. unipotent matrix)
+ASSUME: the relations on the algebra are of the form YX = XY + D, that is
+the current ring is a G-algebra of Lie type.
+NOTE: if n=0, a matrix, defining an automorphism is not assumed to be unipotent
+@* but just non-degenerate. A nonzero parameter @code{@@p} is introduced as the value of
+@* the determinant of the matrix above.
+@* For convenience, the full ideal of relations @code{idJ} and the initial matrix with indeterminates
+@* @code{matD} are mutually exported in the output ring
+SEE ALSO: findInvo
+EXAMPLE: example findAuto; shows examples
+"{
+  if ((n<0 ) || (n==1))
+  {
+    "The index of unipotency is too small.";
+    return(0);
+  }
+
+
+  def @B    = basering; //save the name of basering
+  int NVars = nvars(@B); //number of variables in basering
+  int i, j;
+
+  // check basering is of Lie type:
+  if (!isLieType())
+  {
+    ERROR("Assume violated: basering is of non-Lie type");
+  }
+
+  matrix Rel = RelMatr(); //the matrix of relations
+
+  string @ss = new_var(); //string of new variables
+  string Par = parstr(@B); //string of parameters in old ring
+
+  if (Par=="") // if there are no parameters
+  {
+    execute("ring @@@K=0,("+varstr(@B)+","+ at ss+"), dp;"); //new ring with new variables
+  }
+  else //if there exist parameters
+  {
+     execute("ring @@@K=(0,"+Par+") ,("+varstr(@B)+","+ at ss+"), dp;");//new ring with new variables
+  }
+
+  matrix Rel = imap(@B, Rel); //consider the matrix of relations in new ring
+
+  int Sz = NVars*NVars+NVars; // number of variables in new ring
+
+  matrix M[Sz][Sz]; //to be the matrix of relations in new ring
+
+  for(i=1; i<NVars; i++) //initialize that matrix of relations
+  {
+    for(j=i+1; j<=NVars; j++)
+    {
+      M[i,j] = Rel[i,j];
+    }
+  }
+
+  def @@K = nc_algebra(1, M); setring @@K; //now new ring @@K become a noncommutative ring
+
+  list l; //list to define a homomorphism(isomorphism)
+  poly @@F;
+  for(i=1; i<=NVars; i++) //initializing list for involution
+  {
+    @@F=0;
+    for(j=1; j<=NVars; j++)
+    {
+      execute( "@@F = @@F+"+NVAR(i,j)+"*"+string( var(j) )+";" );
+    }
+    l=l+list(@@F);
+  }
+
+  matrix N = imap(@@@K,Rel);
+
+  for(i=1; i<NVars; i++)//get matrix by applying the homomorphism  to relations
+  {
+    for(j=i+1; j<=NVars; j++)
+    {
+      N[i,j]= l[j]*l[i] - l[i]*l[j] - Hom_Poly( N[i,j], l, NVars);
+    }
+  }
+  kill l;
+  //---------------------------------------------
+  //get the ideal of coefficients of N
+  ideal J;
+  ideal idN = simplify(ideal(N),2);
+  J = ideal(coeffs( idN, var(1) ) );
+  for(i=2; i<=NVars; i++)
+  {
+    J = ideal( coeffs( J, var(i) ) );
+  }
+  J = simplify(J,2);
+  //-------------------------------------------------
+  if (( Par=="" ) && (n!=0)) //initializes the ring of relations
+  {
+    execute("ring @@KK=0,("+ at ss+"), dp;");
+  }
+  if (( Par=="" ) && (n==0)) //initializes the ring of relations
+  {
+    execute("ring @@KK=(0, at p),("+ at ss+"), dp;");
+  }
+  if ( Par!="" )
+  {
+    execute("ring @@KK=(0,"+Par+"),("+ at ss+"), dp;");
+  }
+  //  execute("setring @@KK;");
+  //  basering;
+  ideal J = imap(@@K,J); // ideal, considered in @@KK now
+  string snv = "["+string(NVars)+"]";
+  execute("matrix @@D"+snv+snv+"="+ at ss+";"); // matrix with entries=new variables
+
+  if (n>=2)
+  {
+    J = J, ideal( @@D*@@D-matrix( freemodule(NVars) ) ); // add the condition that homomorphism to square is just identity
+  }
+  if (n==0)
+  {
+    J = J, det(@@D)- at p; // det of non-unipotent matrix is nonzero
+  }
+  J       = simplify(J,2); // without extra zeros
+  list mL = minAssGTZ(J); // components not in GB
+  int sL  = size(mL);
+  intvec saveopt=option(get);
+  option(redSB); // important for reduced GBs
+  option(redTail);
+  matrix IM = @@D; //  map
+  list L = list(); // the answer
+  list TL;
+  ideal tmp = 0;
+  for (i=1; i<=sL; i++)// compute GBs of components
+  {
+    TL    = list();
+    TL[1] = std(mL[i]);
+    tmp   = NF( ideal(IM), TL[1] );
+    TL[2] = matrix(tmp,NVars, NVars);
+    L[i]  = TL;
+  }
+  export(L);
+  ideal idJ = J; // debug-comfortable exports
+  matrix matD = @@D;
+  export(idJ);
+  export(matD);
+  option(set,saveopt);
+  return(@@KK);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  def a = makeWeyl(1);
+  setring a; // this algebra is a first Weyl algebra
+  a;
+  def X = findAuto(2);  // in contrast to findInvo look for automorphisms
+  setring X; // ring with new variables - unknown coefficients
+  X;
+  size(L); // we have (size(L)) families in the answer
+  // look at matrices, defining linear automorphisms:
+  print(L[1][2]);  // a first one: we see it is the identity
+  print(L[2][2]);  // and a second possible matrix; it is diagonal
+  // L; // we can take a look on the whole list, too
+  idJ;
+  kill X; kill a;
+  //----------- find all the linear automorphisms --------------------
+  //----------- use the call findAuto(0)          --------------------
+  ring R = 0,(x,s),dp;
+  def r = nc_algebra(1,s); setring r; // the shift algebra
+  s*x; // the only relation in the algebra is:
+  def Y = findAuto(0);
+  setring Y;
+  size(L); // here, we have 1 parametrized family
+  print(L[1][2]); // here, @p is a nonzero parameter
+  det(L[1][2]- at p);  // check whether determinante is zero
+}
+
+
+proc isAntiEndo(def F)
+"USAGE: isAntiEndo(F); F is a map from current ring to itself
+RETURN: integer, 1 if F determines an antiendomorphism of
+current ring and 0 otherwise
+ASSUME: F is a map from current ring to itself
+SEE ALSO: isInvolution, involution, findInvo
+EXAMPLE: example isAntiEndo; shows examples
+"
+{
+  // assumes:
+  // (1) F is from br to br
+  // I don't see how to check it; in case of error it will happen in the body
+  // (2) do not assume: F is linear, F is bijective
+  int n = nvars(basering);
+  int i,j;
+  poly pi,pj,q;
+  int answer=1;
+  ideal @f = ideal(F); list L=@f[1..ncols(@f)];
+  for (i=1; i<n; i++)
+  {
+    for (j=i+1; j<=n; j++)
+    {
+      // F( x_j x_i) =def= F(x_i) F(x_j)
+      pi = var(i);
+      pj = var(j);
+      //      q = involution(pj*pi,F) - F(pi)*F(pj);
+      q = In_Poly(pj*pi,L,n) - F[i]*F[j];
+      if (q!=0)
+      {
+        answer=0; return(answer);
+      }
+    }
+  }
+  return(answer);
+}
+example
+{"EXAMPLE:";echo = 2;
+  def A = makeUsl(2); setring A;
+  map I = A,-e,-f,-h; //correct antiauto involution
+  isAntiEndo(I);
+  map J = A,3*e,1/3*f,-h; // antiauto but not involution
+  isAntiEndo(J);
+  map K = A,f,e,-h; // not antiendo
+  isAntiEndo(K);
+}
+
+
+proc isInvolution(def F)
+"USAGE: isInvolution(F); F is a map from current ring to itself
+RETURN: integer, 1 if F determines an involution and 0 otherwise
+THEORY: involution is an antiautomorphism of order 2
+ASSUME: F is a map from current ring to itself
+SEE ALSO: involution, findInvo, isAntiEndo
+EXAMPLE: example isInvolution; shows examples
+"
+{
+  // does not assume: F is an antiautomorphism, can be antiendo
+  // allows to detect endos which are not autos
+  // isInvolution == ( F isAntiEndo && F(F)==id )
+  if (!isAntiEndo(F))
+  {
+    return(0);
+  }
+  //  def G = F(F);
+  int j; poly p; ideal @f = ideal(F); list L=@f[1..ncols(@f)];
+  int nv = nvars(basering);
+  for(j=nv; j>=1; j--)
+  {
+    //    p = var(j); p = F(p); p = F(p) - var(j);
+    //p = G(p) - p;
+    p = In_Poly(var(j),L,nv);
+    p = In_Poly(p,L,nv) -var(j) ;
+
+    if (p!=0)
+    {
+      return(0);
+    }
+  }
+  return(1);
+}
+example
+{"EXAMPLE:";echo = 2;
+  def A = makeUsl(2); setring A;
+  map I = A,-e,-f,-h; //correct antiauto involution
+  isInvolution(I);
+  map J = A,3*e,1/3*f,-h; // antiauto but not involution
+  isInvolution(J);
+  map K = A,f,e,-h; // not antiauto
+  isInvolution(K);
+}
diff --git a/Singular/LIB/jacobson.lib b/Singular/LIB/jacobson.lib
new file mode 100644
index 0000000..874180f
--- /dev/null
+++ b/Singular/LIB/jacobson.lib
@@ -0,0 +1,1215 @@
+/////////////////////////////////////////////////////////////////////////////
+version="version jacobson.lib 4.0.0.0 Jun_2013 "; // $Id: 89c042d436d3e016d3822e0d61e1c6850ea236de $
+category="System and Control Theory";
+info="
+LIBRARY: jacobson.lib     Algorithms for Smith and Jacobson Normal Form
+AUTHOR: Kristina Schindelar,     Kristina.Schindelar at math.rwth-aachen.de,
+@*           Viktor Levandovskyy,      levandov at math.rwth-aachen.de
+
+OVERVIEW:
+We work over a ring R, that is an Euclidean principal ideal domain.
+If R is commutative, we suppose R to be a polynomial ring in one variable.
+If R is non-commutative, we suppose R to have two variables, say x and d.
+We treat then the basering as the Ore localization of R
+with respect to the mult. closed set S = K[x] without 0.
+Thus, we treat basering as principal ideal ring with d a polynomial
+variable and x an invertible one.
+Note, that in computations no division by x will actually happen.
+
+Given a rectangular matrix M over R, one can compute unimodular (that is
+invertible) square matrices U and V, such that U*M*V=D is a diagonal matrix.
+Depending on the ring, the diagonal entries of D have certain properties.
+
+We call a square matrix D as before 'a weak Jacobson normal form of M'.
+It is known, that over the first rational Weyl algebra K(x)<d>, D can be further
+transformed into a diagonal matrix (1,1,...,1,f,0,..,0), where f is in K(x)<d>.
+We call such a form of D the strong Jacobson normal form.
+The existence of strong form in not guaranteed if one works with algebra,
+which is not rational Weyl algebra.
+
+
+REFERENCES:
+@* [1] N. Jacobson, 'The theory of rings', AMS, 1943.
+@* [2] Manuel Avelino Insua Hermo, 'Varias perspectives sobre las bases de Groebner :
+@* Forma normal de Smith, Algorithme de Berlekamp y algebras de Leibniz'.
+@* PhD thesis, Universidad de Santiago de Compostela, 2005.
+@* [3] V. Levandovskyy, K. Schindelar 'Computing Jacobson normal form using Groebner bases',
+@* to appear in Journal of Symbolic Computation, 2010.
+
+PROCEDURES:
+smith(M[,eng1,eng2]);  compute the Smith Normal Form of M over commutative ring
+jacobson(M[,eng]); compute a weak Jacobson Normal Form of M over non-commutative ring
+divideUnits(L);     create ones out of units in the output of smith or jacobson
+
+SEE ALSO: control_lib
+
+KEYWORDS: Jacobson form; Jacobson normal form; Smith form; Smith normal form; matrix diagonalization
+
+";
+
+LIB "poly.lib";
+LIB "involut.lib"; // involution
+LIB "dmodapp.lib"; // engine
+LIB "qhmoduli.lib"; // Min
+LIB "latex.lib"; // tex output for printlevel=4
+
+proc tstjacobson()
+{
+  /* tests all procs for consistency */
+  example divideUnits;
+  example smith;
+  example jacobson;
+}
+
+proc divideUnits(list L)
+"USAGE: divideUnits(L); list L
+RETURN: matrix or list of matrices
+ASSUME: L is an output of @code{smith} or a @code{jacobson} procedures, that is
+@* either L contains one rectangular matrix with elements only on the main diagonal
+@* or L consists of three matrices, where L[1] and L[3] are square invertible matrices
+@* while L[2] is a rectangular matrix with elements only on the main diagonal
+PURPOSE: divide out units from the diagonal and reflect this in transformation matrices
+EXAMPLE: example divideUnits; shows examples
+"
+{
+  // check assumptions
+  int s = size(L);
+  if ( (s!=1) && (s!=3) )
+  {
+    ERROR("The list has neither 1 nor 3 elements");
+  }
+  // check sizes of matrices
+
+  if (s==1)
+  {
+    list LL; LL[1] = L[1]; LL[2] = L[1];
+    L = LL;
+  }
+
+
+  // divide units out
+  matrix M = L[2];
+  int ncM = ncols(M);   int nrM = nrows(M);
+  //  matrix TM[nrM][nrM]; // m times m matrix
+  matrix TM = matrix(freemodule(nrM));
+  int i; int nsize = Min(intvec(nrM,ncM));
+  poly p; number n; intvec lexp;
+
+  for(i=1; i<=nsize; i++)
+  {
+    p = M[i,i];
+    lexp = leadexp(p);
+    //    TM[i,i] = 1;
+    // check: is p a unit?
+    if (p!=0)
+    {
+      if ( lexp == 0)
+      {
+        // hence p = n*1
+        n = leadcoef(p);
+        TM[i,i] = 1/n;
+      }
+    }
+  }
+  int ppl = printlevel-voice+2;
+  dbprint(ppl,"divideUnits: extra transformation matrix is: ");
+  dbprint(ppl, TM);
+  L[2] = TM*L[2];
+  if (s==3)
+  {
+    L[1] = TM*L[1];
+    return(L);
+  }
+  else
+  {
+    return(L[2]);
+  }
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring R=(0,m,M,L1,L2,m1,m2,g), D, lp; // two pendula example
+  matrix P[3][4]=m1*L1*D^2,m2*L2*D^2,(M+m1+m2)*D^2,-1,
+  m1*L1^2*D^2-m1*L1*g,0,m1*L1*D^2,0,0,
+  m2*L2^2*D^2-m2*L2*g,m2*L2*D^2,0;
+  list s=smith(P,1);  // returns a list with 3 entries
+  print(s[2]); // a diagonal form, close to the Smith form
+  print(s[1]); // U, left transformation matrix
+  list t = divideUnits(s);
+  print(t[2]); // the Smith form of the matrix P
+  print(t[1]); // U', modified left transformation matrix
+}
+
+proc smith(matrix MA, list #)
+"USAGE: smith(M[, eng1, eng2]);  M matrix, eng1 and eng2 are optional integers
+RETURN: matrix or list of matrices, depending on arguments
+ASSUME: Basering is a commutative polynomial ring in one variable
+PURPOSE: compute the Smith Normal Form of M with (optionally) transformation matrices
+THEORY: Groebner bases are used for the Smith form like in [2] and [3].
+NOTE: By default, just the Smith normal form of M is returned.
+@* If the optional integer @code{eng1} is non-zero, the list {U,D,V} is returned
+@* where U*M*V = D and the diagonal field entries of D are not normalized.
+@* The normalization of the latter can be done with the 'divideUnits' procedure.
+@* U and V above are square unimodular (invertible) matrices.
+@* Note, that the procedure works for a rectangular matrix M.
+@*
+@* The optional integer @code{eng2} determines the Groebner basis engine:
+@* 0 (default) ensures the use of 'slimgb' , otherwise 'std' is used.
+DISPLAY: If @code{printlevel}=1, progress debug messages will be printed,
+@* if @code{printlevel}>=2, all the debug messages will be printed.
+EXAMPLE: example smith; shows examples
+SEE ALSO: divideUnits, jacobson
+"
+{
+  def R = basering;
+  // check assume: R must be a polynomial ring in 1 variable
+  setring R;
+  if (nvars(R) >1 )
+  {
+    ERROR("Basering must have exactly one variable");
+  }
+
+  int eng = 0;
+  int BASIS;
+  if ( size(#)>0 )
+  {
+    eng=1;
+    if (typeof(#[1])=="int")
+    {
+      eng=int(#[1]); // zero can also happen
+    }
+  }
+  if (size(#)==2)
+  {
+  BASIS=#[2];
+  }
+  else{BASIS=0;}
+
+
+  int ROW=ncols(MA);
+  int COL=nrows(MA);
+
+  //generate a module consisting of the columns of MA
+  module m=MA[1];
+  int i;
+  for(i=2;i<=ROW;i++)
+  {
+    m=m,MA[i];
+  }
+
+  //if MA eqauls the zero matrix give back MA
+  if ( (size(module(m))==0) and (size(transpose(module(m)))==0) )
+  {
+    module L=freemodule(COL);
+    matrix LM=L;
+    L=freemodule(ROW);
+    matrix RM=L;
+    list RUECK=RM;
+    RUECK=insert(RUECK,MA);
+    RUECK=insert(RUECK,LM);
+    return(RUECK);
+  }
+
+  if(eng==1)
+  {
+    list rueckLI=diagonal_with_trafo(R,MA,BASIS);
+    list rueckLII=divisibility(rueckLI[2]);
+    matrix CON=divideByContent(rueckLII[2]);
+    list rueckL=CON*rueckLII[1]*rueckLI[1], CON*rueckLII[2], rueckLI[3]*rueckLII[3];
+    return(rueckL);
+  }
+  else
+  {
+    matrix rueckm=diagonal_without_trafo(R,MA,BASIS);
+    list rueckL=divisibility(rueckm);
+    matrix CON=divideByContent(rueckm);
+    rueckm=CON*rueckL[2];
+    return(rueckm);
+  }
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring r = 0,x,Dp;
+  matrix m[3][2]=x, x^4+x^2+21, x^4+x^2+x, x^3+x, 4*x^2+x, x;
+  list s=smith(m,1);
+  print(s[2]);  // non-normalized Smith form of m
+  print(s[1]*m*s[3] - s[2]); // check U*M*V = D
+  list t = divideUnits(s);
+  print(t[2]); // the Smith form of m
+}
+
+static proc diagonal_with_trafo(def R, matrix MA, int B)
+{
+
+int ppl = printlevel-voice+2;
+
+  int BASIS=B;
+  int ROW=ncols(MA);
+  int COL=nrows(MA);
+  module m=MA[1];
+  int i,j,k;
+  for(i=2;i<=ROW;i++)
+  {
+    m=m,MA[i];
+  }
+
+
+  //add zero rows or columns
+  //add zero rows or columns
+  int adrow=0;
+  for(i=1;i<=COL;i++)
+  {
+  k=0;
+  for(j=1;j<=ROW;j++)
+  {
+  if(MA[i,j]!=0){k=1;}
+  }
+  if(k==0){adrow++;}
+  }
+
+    m=transpose(m);
+    for(i=1;i<=adrow;i++){m=m,0;}
+    m=transpose(m);
+
+  list RINGLIST=ringlist(R);
+  list o="C",0;
+  list oo="lp",1;
+  list ORD=o,oo;
+  RINGLIST[3]=ORD;
+  def r=ring(RINGLIST);
+  setring r;
+  //fix the required ordering
+  map MAP=R,var(1);
+  module m=MAP(m);
+
+  int flag=1;  ///////////////counts if the underlying ring is r (flag mod 2 == 1) or ro (flag mod 2 == 0)
+
+    module TrafoL=freemodule(COL);
+    module TrafoR=freemodule(ROW);
+    module EXL=freemodule(COL); //because we start with transpose(m)
+    module EXR=freemodule(ROW);
+
+    option(redSB);
+    option(redTail);
+    module STD_EX;
+    module Trafo;
+
+    int s,st,p,ff;
+
+    module LT,TSTD;
+    module STD=transpose(m);
+    int finish=0;
+    int fehlpos;
+    list pos;
+    matrix END;
+    matrix ENDSTD;
+    matrix STDFIN;
+    STDFIN=STD;
+    list COMPARE=STDFIN;
+
+    while(finish==0)
+    {
+      dbprint(ppl,"Going into the while cycle");
+
+      if(flag mod 2==1)
+      {
+        STD_EX=EXL,transpose(STD);
+      }
+      else
+      {
+        STD_EX=EXR,transpose(STD);
+      }
+        dbprint(ppl,"Computing Groebner basis: start");
+        dbprint(ppl-1,STD);
+      STD=engine(STD,BASIS);
+        dbprint(ppl,"Computing Groebner basis: finished");
+        dbprint(ppl-1,STD);
+
+      if(flag mod 2==1){s=ROW; st=COL;}else{s=COL; st=ROW;}
+        dbprint(ppl,"Computing Groebner basis for transformation matrix: start");
+        dbprint(ppl-1,STD_EX);
+      STD_EX=transpose(STD_EX);
+      STD_EX=engine(STD_EX,BASIS);
+        dbprint(ppl,"Computing Groebner basis for transformation matrix: finished");
+        dbprint(ppl-1,STD_EX);
+
+      //////// split STD_EX in STD and the transformation matrix
+      STD_EX=transpose(STD_EX);
+      STD=STD_EX[st+1];
+      LT=STD_EX[1];
+
+      ENDSTD=STD_EX;
+      for(i=2; i<=ncols(ENDSTD); i++)
+      {
+        if (i<=st)
+        {
+         LT=LT,STD_EX[i];
+        }
+        if (i>st+1)
+        {
+          STD=STD,STD_EX[i];
+        }
+      }
+
+      STD=transpose(STD);
+      LT=transpose(LT);
+
+      ////////////////////// compute the transformation matrices
+
+      if (flag mod 2 ==1)
+      {
+        TrafoL=transpose(LT)*TrafoL;
+      }
+      else
+      {
+        TrafoR=TrafoR*LT;
+      }
+
+
+      STDFIN=STD;
+      /////////////////////////////////// check if the D-th row is finished ///////////////////////////////////
+      COMPARE=insert(COMPARE,STDFIN);
+             if(size(COMPARE)>=3)
+       {
+        if(STD==COMPARE[3]){finish=1;}
+       }
+////////////////////////////////// change to the opposite module
+       TSTD=transpose(STD);
+       STD=TSTD;
+       flag++;
+      dbprint(ppl,"Finished one while cycle");
+    }
+
+
+   if (flag mod 2!=0) { STD=transpose(STD); }
+
+
+   //zero colums to the end
+    matrix STDMM=STD;
+    pos=list();
+    fehlpos=0;
+    while( size(STD)+fehlpos-ncols(STDMM) < 0)
+    {
+      for(i=1; i<=ncols(STDMM); i++)
+      {
+        ff=0;
+        for(j=1; j<=nrows(STDMM); j++)
+        {
+          if (STD[j,i]==0) { ff++; }
+        }
+        if(ff==nrows(STDMM))
+        {
+          pos=insert(pos,i); fehlpos++;
+        }
+      }
+    }
+    int fehlposc=fehlpos;
+    module SORT;
+    for(i=1; i<=fehlpos; i++)
+    {
+      SORT=gen(2);
+      for (j=3;j<=ROW;j++)
+      {
+        SORT=SORT,gen(j);
+      }
+      SORT=SORT,gen(1);
+      STD=STD*SORT;
+      TrafoR=TrafoR*SORT;
+    }
+
+    //zero rows to the end
+    STDMM=transpose(STD);
+    pos=list();
+    fehlpos=0;
+    while( size(transpose(STD))+fehlpos-ncols(STDMM) < 0)
+    {
+      for(i=1; i<=ncols(STDMM); i++)
+      {
+        ff=0; for(j=1; j<=nrows(STDMM); j++)
+        {
+           if(transpose(STD)[j,i]==0){ ff++;}}
+           if(ff==nrows(STDMM)) { pos=insert(pos,i); fehlpos++; }
+      }
+    }
+    int fehlposr=fehlpos;
+
+    for(i=1; i<=fehlpos; i++)
+    {
+      SORT=gen(2);
+      for(j=3;j<=COL;j++){SORT=SORT,gen(j);}
+      SORT=SORT,gen(1);
+      SORT=transpose(SORT);
+      STD=SORT*STD;
+      TrafoL=SORT*TrafoL;
+    }
+
+    setring R;
+    map MAPinv=r,var(1);
+    module STD=MAPinv(STD);
+    module TrafoL=MAPinv(TrafoL);
+    matrix TrafoLM=TrafoL;
+    module TrafoR=MAPinv(TrafoR);
+    matrix TrafoRM=TrafoR;
+    matrix STDM=STD;
+
+    //Test
+    if(TrafoLM*m*TrafoRM!=STDM){ return(0); }
+
+    list RUECK=TrafoRM;
+    RUECK=insert(RUECK,STDM);
+    RUECK=insert(RUECK,TrafoLM);
+    return(RUECK);
+}
+
+
+static proc divisibility(matrix M)
+   {
+    matrix STDM=M;
+    int i,j;
+    int ROW=nrows(M);
+    int COL=ncols(M);
+    module TrafoR=freemodule(COL);
+    module TrafoL=freemodule(ROW);
+    module SORT;
+    matrix TrafoRM=TrafoR;
+    matrix TrafoLM=TrafoL;
+    list posdeg0;
+    int posdeg=0;
+    int act;
+    int Sort=ROW;
+    if(size(std(STDM))!=0)
+    { while( size(transpose(STDM)[Sort])==0 ){Sort--;}}
+
+    for(i=1;i<=Sort ;i++)
+    {
+      if(leadexp(STDM[i,i])==0){posdeg0=insert(posdeg0,i);posdeg++;}
+    }
+    //entries of degree 0 at the beginning
+    for(i=1; i<=posdeg; i++)
+    {
+      act=posdeg0[i];
+      SORT=gen(act);
+      for(j=1; j<=COL; j++){if(j!=act){SORT=SORT,gen(j);}}
+      STDM=STDM*SORT;
+      TrafoRM=TrafoRM*SORT;
+      SORT=gen(act);
+      for(j=1; j<=ROW; j++){if(j!=act){SORT=SORT,gen(j);}}
+      STDM=transpose(SORT)*STDM;
+      TrafoLM=transpose(SORT)*TrafoLM;
+    }
+
+    poly G;
+    module UNITL=freemodule(ROW);
+    matrix GCDL=UNITL;
+    module UNITR=freemodule(COL);
+    matrix GCDR=UNITR;
+    for(i=posdeg+1; i<=Sort; i++)
+    {
+      for(j=i+1; j<=Sort; j++)
+      {
+        GCDL=UNITL;
+        GCDR=UNITR;
+        G=gcd(STDM[i,i],STDM[j,j]);
+        ideal Z=STDM[i,i],STDM[j,j];
+        matrix T=lift(Z,G);
+        GCDL[i,i]=T[1,1];
+        GCDL[i,j]=T[2,1];
+        GCDL[j,i]=-STDM[j,j]/G;
+        GCDL[j,j]=STDM[i,i]/G;
+        GCDR[i,j]=T[2,1]*STDM[j,j]/G;
+        GCDR[j,j]=T[2,1]*STDM[j,j]/G-1;
+        GCDR[j,i]=1;
+        STDM=GCDL*STDM*GCDR;
+        TrafoLM=GCDL*TrafoLM;
+        TrafoRM=TrafoRM*GCDR;
+      }
+    }
+    list RUECK=TrafoRM;
+    RUECK=insert(RUECK,STDM);
+    RUECK=insert(RUECK,TrafoLM);
+    return(RUECK);
+}
+
+static proc diagonal_without_trafo( R, matrix MA, int B)
+{
+  int ppl = printlevel-voice+2;
+
+  int BASIS=B;
+  int ROW=ncols(MA);
+  int COL=nrows(MA);
+  module m=MA[1];
+  int i;
+  for(i=2;i<=ROW;i++)
+  {m=m,MA[i];}
+
+
+  list RINGLIST=ringlist(R);
+  list o="C",0;
+  list oo="lp",1;
+  list ORD=o,oo;
+  RINGLIST[3]=ORD;
+  def r=ring(RINGLIST);
+  setring r;
+  //RICHTIGE ORDNUNG MACHEN
+  map MAP=R,var(1);
+  module m=MAP(m);
+
+  int flag=1; ///////////////counts if the underlying ring is r (flag mod 2 == 1) or ro (flag mod 2 == 0)
+
+
+    int act, j, ff;
+    option(redSB);
+    option(redTail);
+
+
+    module STD=transpose(m);
+    module TSTD;
+    int finish=0;
+    matrix STDFIN;
+    STDFIN=STD;
+    list COMPARE=STDFIN;
+
+    while(finish==0)
+    {
+      dbprint(ppl,"Going into the while cycle");
+      dbprint(ppl,"Computing Groebner basis: start");
+      dbprint(ppl-1,STD);
+      STD=engine(STD,BASIS);
+      dbprint(ppl,"Computing Groebner basis: finished");
+      dbprint(ppl-1,STD);
+      STDFIN=STD;
+      /////////////////////////////////// check if the D-th row is finished ///////////////////////////////////
+      COMPARE=insert(COMPARE,STDFIN);
+             if(size(COMPARE)>=3)
+       {
+        if(STD==COMPARE[3]){finish=1;}
+       }
+        ////////////////////////////////// change to the opposite module
+
+        TSTD=transpose(STD);
+        STD=TSTD;
+        flag++;
+        dbprint(ppl,"Finished one while cycle");
+    }
+
+    matrix STDMM=STD;
+    list pos=list();
+    int fehlpos=0;
+    while( size(STD)+fehlpos-ncols(STDMM) < 0)
+    {
+      for(i=1; i<=ncols(STDMM); i++)
+      {
+        ff=0;
+        for(j=1; j<=nrows(STDMM); j++)
+        {
+          if (STD[j,i]==0) { ff++; }
+        }
+        if(ff==nrows(STDMM))
+        {
+          pos=insert(pos,i); fehlpos++;
+        }
+      }
+    }
+   int fehlposc=fehlpos;
+    module SORT;
+    for(i=1; i<=fehlpos; i++)
+    {
+      SORT=gen(2);
+      for (j=3;j<=ROW;j++)
+      {
+        SORT=SORT,gen(j);
+      }
+      SORT=SORT,gen(1);
+      STD=STD*SORT;
+    }
+
+    //zero rows to the end
+    STDMM=transpose(STD);
+    pos=list();
+    fehlpos=0;
+    while( size(transpose(STD))+fehlpos-ncols(STDMM) < 0)
+    {
+      for(i=1; i<=ncols(STDMM); i++)
+      {
+        ff=0; for(j=1; j<=nrows(STDMM); j++)
+        {
+           if(transpose(STD)[j,i]==0){ ff++;}}
+           if(ff==nrows(STDMM)) { pos=insert(pos,i); fehlpos++; }
+      }
+    }
+    int fehlposr=fehlpos;
+
+    for(i=1; i<=fehlpos; i++)
+    {
+      SORT=gen(2);
+      for(j=3;j<=COL;j++){SORT=SORT,gen(j);}
+      SORT=SORT,gen(1);
+      SORT=transpose(SORT);
+      STD=SORT*STD;
+    }
+
+   //add zero rows or columns
+
+    int adrow=COL-size(transpose(STD));
+    int adcol=ROW-size(STD);
+
+    for(i=1;i<=adcol;i++){STD=STD,0;}
+    STD=transpose(STD);
+    for(i=1;i<=adrow;i++){STD=STD,0;}
+    STD=transpose(STD);
+
+    setring R;
+    map MAPinv=r,var(1);
+    module STD=MAPinv(STD);
+    matrix STDM=STD;
+    return(STDM);
+}
+
+
+// VL : engine replaced by the one from dmodapp.lib
+// cases are changed
+
+// static proc engine(module I, int i)
+// {
+//   module J;
+//   if (i==0)
+//   {
+//     J = std(I);
+//   }
+//   if (i==1)
+//   {
+//     J = groebner(I);
+//   }
+//   if (i==2)
+//   {
+//     J = slimgb(I);
+//   }
+//   return(J);
+// }
+
+proc jacobson(matrix MA, list #)
+ "USAGE:  jacobson(M, eng);  M matrix, eng an optional int
+RETURN: list
+ASSUME: Basering is a (non-commutative) ring in two variables.
+PURPOSE: compute a weak Jacobson normal form of M over the basering
+THEORY: Groebner bases and involutions are used, following [3]
+NOTE: A list L of matrices {U,D,V} is returned. That is L[1]*M*L[3]=L[2],
+@*      where L[2] is a diagonal matrix and
+@*      L[1], L[3] are square invertible polynomial (unimodular) matrices.
+@*      Note, that M can be rectangular.
+@* The optional integer @code{eng2} determines the Groebner basis engine:
+@* 0 (default) ensures the use of 'slimgb' , otherwise 'std' is used.
+DISPLAY: If @code{printlevel}=1, progress debug messages will be printed,
+@* if @code{printlevel}>=2, all the debug messages will be printed.
+EXAMPLE: example jacobson; shows examples
+SEE ALSO: divideUnits, smith
+"
+{
+  def R = basering;
+  // check assume: R must be a polynomial ring in 2 variables
+  setring R;
+  if ( (nvars(R) !=2 ) )
+  {
+    ERROR("Basering must have exactly two variables");
+  }
+
+  // check if MA is zero matrix and return corr. U,V
+  if ( (size(module(MA))==0) and (size(transpose(module(MA)))==0) )
+  {
+    int nr = nrows(MA);
+    int nc = ncols(MA);
+    matrix U = matrix(freemodule(nr));
+    matrix V = matrix(freemodule(nc));
+    list L; L[1]=U; L[2] = MA; L[3] = V;
+    return(L);
+  }
+
+  int B=0;
+  if ( size(#)>0 )
+  {
+    B=1;
+    if (typeof(#[1])=="int")
+    {
+    B=int(#[1]); // zero can also happen
+    }
+  }
+
+  //change ring
+  list RINGLIST=ringlist(R);
+  list o="C",0;
+  intvec v=0,1;
+  list oo="a",v;
+  v=1,1;
+  list ooo="lp",v;
+  list ORD=o,oo,ooo;
+  RINGLIST[3]=ORD;
+  def r=ring(RINGLIST);
+  setring r;
+
+  //fix the required ordering
+  map MAP=R,var(1),var(2);
+  matrix M=MAP(MA);
+
+  module TrafoL, TrafoR;
+  list TRIANGLE;
+  TRIANGLE=triangle(M,B);
+  TrafoL=TRIANGLE[1];
+  TrafoR=TRIANGLE[3];
+  module m=TRIANGLE[2];
+
+  //back to the ring
+  setring R;
+  map MAPR=r,var(1),var(2);
+  module ma=MAPR(m);
+  matrix MAA=ma;
+  module TL=MAPR(TrafoL);
+  module TR=MAPR(TrafoR);
+  matrix TRR=TR;
+  matrix CON=divideByContent(MAA);
+
+list RUECK=CON*TL, CON*MAA, TRR;
+return(RUECK);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,d),Dp;
+  def R = nc_algebra(1,1);   setring R; // the 1st Weyl algebra
+  matrix m[2][2] = d,x,0,d; print(m);
+  list J = jacobson(m); // returns a list with 3 entries
+  print(J[2]); // a Jacobson Form D for m
+  print(J[1]*m*J[3] - J[2]); // check that U*M*V = D
+  /*   now, let us do the same for the shift algebra  */
+  ring r2 = 0,(x,s),Dp;
+  def R2 = nc_algebra(1,s);   setring R2; // the 1st shift algebra
+  matrix m[2][2] = s,x,0,s; print(m); // matrix of the same for as above
+  list J = jacobson(m);
+  print(J[2]); // a Jacobson Form D, quite different from above
+  print(J[1]*m*J[3] - J[2]); // check that U*M*V = D
+}
+
+//static
+proc triangle(matrix MA, int B)
+{
+ int ppl = printlevel-voice+2;
+
+  map inv=ncdetection();
+  int ROW=ncols(MA);
+  int COL=nrows(MA);
+
+  //generate a module consisting of the columns of MA
+  module m=MA[1];
+  int i,j,s,st,p,k,ff,ex, nz, ii,nextp;
+  for(i=2;i<=ROW;i++)
+  {
+    m=m,MA[i];
+  }
+  int BASIS=B;
+
+  //add zero rows or columns
+  int adrow=0;
+  for(i=1;i<=COL;i++)
+  {
+  k=0;
+  for(j=1;j<=ROW;j++)
+  {
+  if(MA[i,j]!=0){k=1;}
+  }
+  if(k==0){adrow++;}
+  }
+
+    m=transpose(m);
+    for(i=1;i<=adrow;i++){m=m,0;}
+    m=transpose(m);
+
+
+    int flag=1;  ///////////////counts if the underlying ring is r (flag mod 2 == 1) or ro (flag mod 2 == 0)
+
+    module TrafoL=freemodule(COL);
+    module TrafoR=freemodule(ROW);
+    module EXL=freemodule(COL); //because we start with transpose(m)
+    module EXR=freemodule(ROW);
+
+    option(redSB);
+    option(redTail);
+    module STD_EX,LT,TSTD, L, Trafo;
+
+
+
+    module STD=transpose(m);
+    int finish=0;
+    list pos, COM, COM_EX;
+    matrix END, ENDSTD, STDFIN;
+    STDFIN=STD;
+    list COMPARE=STDFIN;
+    string @s;
+
+  while(finish==0)
+    {
+      dbprint(ppl,"Going into the while cycle");
+      if(flag mod 2==1){STD_EX=EXL,transpose(STD); ex=2*COL;} else {STD_EX=EXR,transpose(STD); ex=2*ROW;}
+
+      dbprint(ppl,"Computing Groebner basis: start");
+      dbprint(ppl-1,STD);
+      STD=engine(STD,BASIS);
+      dbprint(ppl,"Computing Groebner basis: finished");
+      dbprint(ppl-1,STD);
+      if(flag mod 2==1){s=ROW; st=COL;}else{s=COL; st=ROW;}
+
+      STD_EX=transpose(STD_EX);
+      dbprint(ppl,"Computing Groebner basis for transformation matrix: start");
+      dbprint(ppl-1,STD_EX);
+      STD_EX=engine(STD_EX,BASIS);
+      dbprint(ppl,"Computing Groebner basis for transformation matrix: finished");
+      dbprint(ppl-1,STD_EX);
+
+      COM=1;
+      COM_EX=1;
+      for(i=2; i<=size(STD); i++)
+         { COM=COM[1..size(COM)],i; COM_EX=COM_EX[1..size(COM_EX)],i; }
+      nz=size(STD_EX)-size(STD);
+
+      //zero rows in the begining
+
+       if(size(STD)!=size(STD_EX) )
+       {
+         for(i=1; i<=size(STD_EX)-size(STD); i++)
+         {
+           COM_EX=0,COM_EX[1..size(COM_EX)];
+         }
+       }
+
+       for(i=nz+1; i<=size(STD_EX); i++ )
+        {if( leadcoef(STD[i-nz])!=leadcoef(STD_EX[i]) )          {STD[i-nz]=leadcoef(STD_EX[i])*STD[i-nz];}
+        }
+
+        //assign the zero rows in STD_EX
+
+       for (j=2; j<=nz; j++)
+       {
+        p=0;
+        i=1;
+        while(STD_EX[j-1][i]==0){i++;}
+        p=i-1;
+        nextp=1;
+        k=0;
+        i=1;
+        while(STD_EX[j][i]==0 and i<=p)
+        { k++; i++;}
+        if (k==p){ COM_EX[j]=-1; }
+       }
+
+      //assign the zero rows in STD
+      for (j=2; j<=size(STD); j++)
+       {
+        i=size(transpose(STD));
+        while(STD[j-1][i]==0){i--;}
+        p=i;
+        i=size(transpose(STD[j]));
+        while(STD[j][i]==0){i--;}
+        if (i==p){ COM[j]=-1; }
+       }
+
+       for(j=1; j<=size(COM); j++)
+        {
+        if(COM[j]<0){COM=delete(COM,j);}
+        }
+
+      for(i=1; i<=size(COM_EX); i++)
+        {ff=0;
+         if(COM_EX[i]==0){ff=1;}
+         else
+          {  for(j=1; j<=size(COM); j++)
+               { if(COM_EX[i]==COM[j]){ff=1;} }
+          }
+         if(ff==0){COM_EX[i]=-1;}
+        }
+
+      L=STD_EX[1];
+      for(i=2; i<=size(COM_EX); i++)
+       {
+        if(COM_EX[i]!=-1){L=L,STD_EX[i];}
+       }
+
+      //////// split STD_EX in STD and the transformation matrix
+
+       L=transpose(L);
+       STD=L[st+1];
+       LT=L[1];
+
+
+       for(i=2; i<=s+st; i++)
+        {
+         if (i<=st)
+          {
+           LT=LT,L[i];
+          }
+         if (i>st+1)
+          {
+          STD=STD,L[i];
+          }
+        }
+
+       STD=transpose(STD);
+       STDFIN=matrix(STD);
+       COMPARE=insert(COMPARE,STDFIN);
+       LT=transpose(LT);
+
+      ////////////////////// compute the transformation matrices
+
+       if (flag mod 2 ==1)
+        {
+         TrafoL=transpose(LT)*TrafoL;
+         dbprint(ppl-1,"Left transformation matrix:");
+         dbprint(ppl-1,TrafoL);
+         @s = texobj("",matrix(TrafoL));
+         dbprint(ppl-2,"Left transformation matrix in TeX format:");
+         dbprint(ppl-2, at s);
+        }
+       else
+        {
+         TrafoR=TrafoR*involution(LT,inv);
+         dbprint(ppl-1,"Right transformation matrix:");
+         dbprint(ppl-1,matrix(TrafoR));
+         @s = texobj("",TrafoR);
+         dbprint(ppl-2,"Right transformation matrix in TeX format:");
+         dbprint(ppl-2, at s);
+        }
+
+      ///////////////////////// check whether the alg terminated /////////////////
+      if(size(COMPARE)>=3)
+       {
+        if(STD==COMPARE[3]){finish=1;}
+       }
+       ////////////////////////////////// change to the opposite module
+      dbprint(ppl-1,"Matrix for the next step:");
+      dbprint(ppl-1,STD);
+      dbprint(ppl-2,"Matrix for the next step in TeX format:");
+      @s = texobj("",matrix(STD));
+      dbprint(ppl-2, at s);
+      TSTD=transpose(STD);
+      STD=involution(TSTD,inv);
+      flag++;
+      dbprint(ppl,"Finished one while cycle");
+    }
+
+if (flag mod 2 ==0){ STD = involution(STD,inv);} else { STD = transpose(STD);  }
+
+    list REVERSE=TrafoL,STD,TrafoR;
+    return(REVERSE);
+}
+
+static proc divideByContent(matrix M)
+{
+//find first entrie not equal to zero
+int i,k;
+k=1;
+vector CON;
+   for(i=1;i<=ncols(M);i++)
+   {
+    if(leadcoef(M[i])!=0){CON=CON+leadcoef(M[i])*gen(k); k++;}
+   }
+poly con=content(CON);
+matrix TL=1/con*freemodule(nrows(M));
+return(TL);
+}
+
+
+/////interesting examples for smith////////////////
+
+/*
+
+//static proc Ex_One_wheeled_bicycle()
+{
+ring RA=(0,m), D, lp;
+matrix bicycle[2][3]=(1+m)*D^2, D^2, 1, D^2, D^2-1, 0;
+list s=smith(bicycle, 1,0);
+print(s[2]);
+print(s[1]*bicycle*s[3]-s[2]);
+}
+
+
+//static proc Ex_RLC-circuit()
+{
+ring RA=(0,m,R1,R2,L,C), D, lp;
+matrix  circuit[2][3]=D+1/(R1*C), 0, -1/(R1*C), 0, D+R2/L, -1/L;
+list s=smith(circuit, 1,0);
+print(s[2]);
+print(s[1]*circuit*s[3]-s[2]);
+}
+
+
+//static proc Ex_two_pendula()
+{
+ring RA=(0,m,M,L1,L2,m1,m2,g), D, lp;
+matrix pendula[3][4]=m1*L1*D^2,m2*L2*D^2,(M+m1+m2)*D^2,-1,m1*L1^2*D^2-m1*L1*g,0,m1*L1*D^2,0,0,
+m2*L2^2*D^2-m2*L2*g,m2*L2*D^2,0;
+list s=smith(pendula, 1,0);
+print(s[2]);
+print(s[1]*pendula*s[3]-s[2]);
+}
+
+//static proc Ex_linerized_satellite_in_a_circular_equatorial_orbit()
+{
+ring RA=(0,m,omega,r,a,b), D, lp;
+matrix satellite[4][6]=
+D,-1,0,0,0,0,
+-3*omega^2,D,0,-2*omega*r,-a/m,0,
+0,0,D,-1,0,0,
+0,2*omega/r,0,D,0,-b/(m*r);
+list s=smith(satellite, 1,0);
+print(s[2]);
+print(s[1]*satellite*s[3]-s[2]);
+}
+
+//static proc Ex_flexible_one_link_robot()
+{
+ring RA=(0,M11,M12,M13,M21,M22,M31,M33,K1,K2), D, lp;
+matrix robot[3][4]=M11*D^2,M12*D^2,M13*D^2,-1,M21*D^2,M22*D^2+K1,0,0,M31*D^2,0,M33*D^2+K2,0;
+list s=smith(robot, 1,0);
+print(s[2]);
+print(s[1]*robot*s[3]-s[2]);
+}
+
+*/
+
+
+/////interesting examples for jacobson////////////////
+
+/*
+
+//static proc Ex_compare_output_with_maple_package_JanetOre()
+{
+    ring w = 0,(x,d),Dp;
+    def W=nc_algebra(1,1);
+    setring W;
+    matrix m[3][3]=[d2,d+1,0],[d+1,0,d3-x2*d],[2d+1, d3+d2, d2];
+    list J=jacobson(m,0);
+    print(J[1]*m*J[3]);
+    print(J[2]);
+    print(J[1]);
+    print(J[3]);
+    print(J[1]*m*J[3]-J[2]);
+}
+
+// modification for shift algebra
+{
+    ring w = 0,(x,s),Dp;
+    def W=nc_algebra(1,s);
+    setring W;
+    matrix m[3][3]=[s^2,s+1,0],[s+1,0,s^3-x^2*s],[2*s+1, s^3+s^2, s^2];
+    list J=jacobson(m,0);
+    print(J[1]*m*J[3]);
+    print(J[2]);
+    print(J[1]);
+    print(J[3]);
+    print(J[1]*m*J[3]-J[2]);
+}
+
+//static proc Ex_cyclic()
+{
+    ring w = 0,(x,d),Dp;
+    def W=nc_algebra(1,1);
+    setring W;
+    matrix m[3][3]=d,0,0,x*d+1,d,0,0,x*d,d;
+    list J=jacobson(m,0);
+    print(J[1]*m*J[3]);
+    print(J[2]);
+    print(J[1]);
+    print(J[3]);
+    print(J[1]*m*J[3]-J[2]);
+}
+
+// modification for shift algebra: gives a module with ann = s^2
+{
+    ring w = 0,(x,s),Dp;
+    def W=nc_algebra(1,s);
+    setring W;
+    matrix m[3][3]=s,0,0,x*s+1,s,0,0,x*s,s;
+    list J=jacobson(m,0);
+    print(J[1]*m*J[3]);
+    print(J[2]);
+    print(J[1]);
+    print(J[3]);
+    print(J[1]*m*J[3]-J[2]);
+}
+
+// yet another modification for shift algebra: gives a module with ann = s
+// xs+1 is replaced by x*s+s
+{
+    ring w = 0,(x,s),Dp;
+    def W=nc_algebra(1,s);
+    setring W;
+    matrix m[3][3]=s,0,0,x*s+s,s,0,0,x*s,s;
+    list J=jacobson(m,0);
+    print(J[1]*m*J[3]);
+    print(J[2]);
+    print(J[1]);
+    print(J[3]);
+    print(J[1]*m*J[3]-J[2]);
+}
+
+// variations for above setup with shift algebra:
+
+// easy but instructive one: see the difference to Weyl case!
+matrix m[2][2]=s,x,0,s; print(m);
+
+// more interesting:
+matrix n[3][3]=s,x,0,0,s,x,s,0,x;
+
+// things blow up
+matrix m[2][3] = s,x^2*s,x^3*s,s*x^2,s*x+1,(x+1)^3;
+matrix m[2][3] = s,x^2*s,x^3*s,s*x^2,s*x+1,(x+s)^2; // variation
+matrix m[2][4] = s,x^2*s,x^3*s,s*x^2,s*x+1,(x+1)^3, (x+s)^2, x*s; // bug (matrix sizes
+matrix m[3][4] = s,x^2*s,x^3*s,s*x^2,s*x+1,(x+1)^3, (x+s)^2, x*s; // here the last row contains zeros
+
+// this one is quite nasty and time consumig
+matrix m[3][4] = s,x^2*s,x^3*s,s*x^2,s*x+1,(x+1)^3, (x+s)^2, x*s,x,x^2,x^3,s;
+
+// example from the paper:
+    ring w = 0,(x,d),Dp;
+    def W=nc_algebra(1,1);
+    setring W;
+    matrix m[2][2]=d^2-1,d+1,d^2+1,d-x;
+    list J=jacobson(m,0);
+    print(J[1]*m*J[3]);     print(J[2]);     print(J[1]);     print(J[3]);
+    print(J[1]*m*J[3]-J[2]);
+
+    ring w2 = 0,(x,s),Dp;
+    def W2=nc_algebra(1,s);
+    setring W2;
+    poly d = s;
+    matrix m[2][2]=d^2-1,d+1,d^2+1,d-x;
+    list J=jacobson(m,0);
+    print(J[1]*m*J[3]);     print(J[2]);     print(J[1]);     print(J[3]);
+    print(J[1]*m*J[3]-J[2]);
+// here, both JNFs are cyclic
+
+// another example from the paper:
+    ring w = 0,(x,d),Dp;
+    def W=nc_algebra(1,1);
+    setring W;
+   matrix m[2][2]=-x*d+1, x^2*d, -d, x*d+1;
+    list J=jacobson(m,0);
+    print(J[1]*m*J[3]);     print(J[2]);     print(J[1]);     print(J[3]);
+    print(J[1]*m*J[3]-J[2]);
+
+    ring w2 = 0,(x,s),Dp;
+    def W2=nc_algebra(1,s);
+    setring W2;
+    poly d = s;
+   matrix m[2][2]=-x*d+1, x^2*d, -d, x*d+1;
+    list J=jacobson(m,0);
+    print(J[1]*m*J[3]);     print(J[2]);     print(J[1]);     print(J[3]);
+    print(J[1]*m*J[3]-J[2]);
+
+// yet another example from the paper, also Middeke
+   ring w = (0,y),(x,d),Dp;
+   def W=nc_algebra(1,1);
+   setring W;
+   matrix m[2][2]=y^2*d^2+d+1, 1, x*d, x^2*d^2+d+y;
+   list J=jacobson(m,0);
+   print(J[1]*m*J[3]);     print(J[2]);     print(J[1]);     print(J[3]);
+   print(J[1]*m*J[3]-J[2]);
+
+
+*/
diff --git a/Singular/LIB/kskernel.lib b/Singular/LIB/kskernel.lib
new file mode 100644
index 0000000..115770a
--- /dev/null
+++ b/Singular/LIB/kskernel.lib
@@ -0,0 +1,534 @@
+///////////////////////////////////////////////////////////////
+version="version kskernel.lib 4.0.0.0 Jun_2013 "; // $Id: e020a13d553fef7586c1f2e634c1fe11b3635ab5 $
+category="General purpose";
+info="
+LIBRARY:  kskernel.lib   PROCEDURES FOR COMPUTING THE KERNEL
+                         OF THE KODAIRA-SPENCER MAP
+
+AUTHOR:   Tetyana Povalyaeva, povalyae at mathematik.uni-kl.de
+
+PROCEDURES:
+ KSker(p,q);          kernel of the Kodaira-Spencer map of
+                      a versal deformation of an irreducible
+                      plane curve singularity
+ KSconvert(M);        kernel of the Kodaira-Spencer map in
+                      quasihomogeneous variables T with
+                      corresponding negative degrees
+ KSlinear(M);         matrix of linear terms of the kernel of
+                      the Kodaira-Spencer map
+ KScoef(i,j,P,Q,qq);  coefficient of the given term in the matrix
+                      of kernel of the Kodaira-Spencer map
+ StringF(i,j,p,q);    expression in variables T(i) with non-resolved
+                      brackets for the further computation of
+                      coefficient in the matrix of kernel of the
+                      Kodaira-Spencer map
+";
+LIB "general.lib";
+////////////////////////////////////////////////////////////////
+
+//-------------------------- ALGORITHM II ---------------------
+
+//---------------------------- sub procedure ------------------
+// used in sorter
+proc minim(intmat M, int t)
+{
+  int m=v[t];
+  int i,k,done;
+  k=0;done=0;
+  for (i=t+1;i<nrows(M);i++)
+  {
+    if (m>v[i])  { m=v[i];k=i;done=1; }
+  }
+  if (done==1)
+  {
+    for (i=1;i<=3;i++)
+    {
+      done=M[k,i];M[k,i]=M[t,i];M[t,i]=done;
+    }
+    i=v[k];v[k]=v[t];v[t]=i;
+  }
+  return(M);
+}
+
+//---------------------------- sub procedure --------------------
+// sorts M by the third row, ascending
+proc sorter(intmat M)
+{
+  intvec v;
+  int i;
+  for (i=1;i<=nrows(M);i++)
+  { v[i]=M[i,3]; }
+  export (v);
+  int n=1;
+  while (n<=nrows(M))
+  {
+    M=minim(M,n);
+    n++;
+  }
+  kill v;
+  return(M);
+}
+
+//---------------------------- sub procedure --------------------
+// M is a sorted matrix of triples {i,j,k(i,j)}
+// returns a list of coefficients of p
+// w.r.t. the base {x^i y^j,(i,j) in (M[i,j,k])}=B_u
+proc MonoDec(poly p, matrix M)
+{
+  poly q=p;
+  intvec V;
+  list C;
+  int nM=nrows(M); //cardinality of B_u
+  vector VC=gen(nM+1);
+  int k=1; int i=1; int j=1;
+  while (q!=0)
+  {
+    V=leadexp(q);
+    while ( !((V[1]==M[k,1]) && (V[2]==M[k,2])) )
+    {
+      if (k>=nM)
+      {
+        ERROR("error in monomial base");
+        return(0);
+      }
+      k++;
+    }
+    VC=VC+leadcoef(q)*gen(k);
+    q=q-lead(q);
+    k=1;
+  }
+  VC=VC-gen(nM+1);
+  return(VC);
+}
+
+//----------------------------- main program --------------------
+proc KSker (int p,int q)
+"USAGE:  KSker(int p,q); p,q relatively prime integers
+RETURN:  nothing; exports ring KSring, matrix KSkernel and list 'weights';
+         KSkernel is a matrix of coefficients of the
+         generators of the kernel of Kodaira-Spencer map,
+         'weights' is a list of degrees for variables T
+EXAMPLE: example KSker; shows an example
+"
+{
+  option(redSB);
+  option(redTail);
+  int c;
+  int i,j;
+  int k=0;
+  list LM;
+  list tmp;
+  for (i=0;i<=p-2;i++)
+  {
+    for (j=0;j<=q-2;j++)
+    {
+      c=(i*q)+(j*p)-(p*q);
+      if (c>0)
+      {
+        k++;
+        tmp[1]=i;
+        tmp[2]=j;
+        tmp[3]=c; // index of T
+        LM[k]=tmp;
+        tmp=0;
+      }
+    }
+  }
+  if (k==0)
+  {
+    "The kernel of the Kodaira-Spencer map equals zero";
+    return();
+  }
+  if (k==1)
+  {
+    ring KSring=0,(T(1)),ws(c);
+    matrix KSkernel[1][1]=c*T(1);
+    export(KSring);
+    export(KSkernel);
+    return();
+  }
+  int cnt=k; // the total number of T's, now k>1
+  intmat M[k][3]; // matrix with triples (i,j,k)
+  for (i=1; i<=k; i++)
+  {
+    M[i,1] = LM[i][1];
+    M[i,2] = LM[i][2];
+    M[i,3] = LM[i][3];
+  }
+  kill LM;
+  M = sorter(M); // now the third column of M contains ordered ascending values
+  list weights;
+  for (i=1; i<=k; i++)
+  {
+    weights[i] = M[i,3]; // positive weights for Ws ordering
+    M[i,3]   = i;
+  }
+  export(weights);
+  ring RT=0,(x,y,T(1..k)),(Ws(q,p),dp);
+  poly F=x^p+y^q;
+  i=0;j=0;
+  for (k=1;k<=cnt;k++)
+  {
+    i = M[k,1];
+    j = M[k,2];
+    F = F + T(k)*x^i*y^j;
+  }
+  ideal I = diff(F,x),diff(F,y);
+  I = std(I);
+  k=0;
+  list normal;
+  poly mul;
+  for (i=0;i<=p-2;i++)
+  {
+    for (j=0;j<=q-2;j++)
+    {
+      c = p*q - ((i+2)*q+(j+2)*p);
+      if ( c > 0 )
+      {
+        mul = x^i*y^j*p*q*F;
+        k++;
+        normal[k] = NF(mul,I);
+      }
+    }
+  }
+  // now we separate T's from (x,y) by treating T's as parameters
+  ring ST=(0,T(1..k)),(x,y),Ws(q,p);
+  setring ST;
+  list Snormal = imap(RT,normal);
+  ideal SI = imap(RT,I);
+  kill RT;
+  SI = std(SI);
+  module L;
+  for (i=1; i<=size(Snormal); i++)
+  {
+    Snormal[i] = NF(Snormal[i],SI);
+    L[i] = MonoDec(Snormal[i],M);
+    if (L[i]==0) // MonoDec has detected non-basis element
+    {
+      "Try reducing the input";
+      return(0);
+    }
+  }
+  // now L is a module in T's
+  ring KSring=0,(T(1..k)),(C,ws(-weights[1..k]));
+  module TL=imap(ST,L);
+  kill ST;
+  // sort it descendently
+  TL = sort(TL)[1];
+  // make the coefficients positive
+  if ((leadcoef(TL[1,1])<0) || (leadcoef(TL[k,k])<0)) { TL = -TL;}
+  matrix KSkernel=matrix(TL);
+  export(KSring);
+  export(KSkernel);
+  kill M;
+  return();
+}
+example
+{ "EXAMPLE:"; echo=2;
+   int p=6;
+   int q=7;
+   KSker(p,q);
+   setring Kskernel::KSring;
+   print(KSkernel);
+}
+
+//---------------------------- sub procedure ------------------
+// converts T(1..k) to T(w(1),..w(k)),
+// need global variable "weights"
+proc KSconvert(matrix M)
+"USAGE:  KSconvert(matrix M);
+         M is a matrix of coefficients of the generators of
+         the kernel of Kodaira-Spencer map in variables T(i)
+         from the basering. To be called after the procedure
+         KSker(p,q)
+RETURN:  nothing; exports ring KSring2 and matrix KSkernel2 within it,
+         such that KSring2 resp. KSkernel2 are in variables
+         T(w) with weights -w. These weights are computed
+         in the procedure KSker(p,q)
+EXAMPLE: example KSconvert; shows an example
+"
+{
+  int s=ncols(M); // the total numbers of T's
+  ring T1=0,(T(1..weights[s])),dp;
+  matrix TM=imap(KSring,M);
+  int i;
+  for (i=s;i>=1;i--)
+  {
+    TM=subst(TM,T(i),T(weights[i]));
+  }
+  string Tw="0,(";
+  string Ww="Ws(";
+  string tempo="";
+  for (i=1; i<=s; i++)
+  {
+    tempo=string(weights[i]);
+    Tw = Tw+"T("+tempo+"),";
+    Ww = Ww+"-"+tempo+",";
+  }
+  Tw[size(Tw)] = ")";
+  Ww[size(Ww)] = ")";
+  Tw=Tw+","+Ww+";";
+  execute("ring KSring2="+Tw);
+  matrix KSkernel2=imap(T1,TM);
+  kill T1;
+  export KSring2;
+  export(KSring2);
+  export KSkernel2;
+  return();
+}
+example
+{ "EXAMPLE:"; echo=2;
+   int p=6;
+   int q=7;
+   KSker(p,q);
+   setring Kskernel::KSring;
+   KSconvert(KSkernel);
+   setring Kskernel::KSring2;
+   print(KSkernel2);
+}
+
+proc KSlinear(matrix M)
+"USAGE:  KSlinear(matrix M);
+         computes matrix of linear terms of the kernel of the
+         Kodaira-Spencer map. To be called after the procedure
+         KSker(p,q)
+RETURN:  nothing; but replaces elements of the matrix KSkernel
+         in the ring Ksring with their leading monomials
+         w.r.t. the local ordering (ls)
+EXAMPLE: example KSlinear; shows an example
+"
+{
+  int s=ncols(M); // the total numbers of T's
+  ring T1=0,(T(1..weights[s])),ls;
+  matrix TM=imap(KSring,M);
+  int i; int j;
+  for (i=1; i<=s;i++)
+  {
+    for (j=1; j<=s;j++)
+    {
+      if (TM[i,j]!=0) { TM[i,j]=lead(TM[i,j]); }
+    }
+  }
+  setring KSring;
+  KSkernel=imap(T1,TM);
+  kill T1;
+}
+example
+{ "EXAMPLE:"; echo=2;
+   int p=6;
+   int q=7;
+   KSker(p,q);
+   setring Kskernel::KSring;
+   KSlinear(KSkernel);
+   print(KSkernel);
+}
+
+//-------------------------- ALGORITHM I ----------------------
+
+//---------------------------- sub procedure ------------------
+proc seq(int p,int q)
+// computes u,v such that 1<=u<=p-1, qu=1(mod p)
+//                        1<=v<=q-1, pv=1(mod q)
+{
+  int u=1;  int v=1;
+  for(u=1; u<=p-1; u++)
+  {
+    if (((q*u)%p)==1) {break;}
+   }
+  for(v=1; v<=q-1; v++)
+  {
+    if (((p*v)%q)==1) {break;}
+  }
+  return(u,v);
+}
+
+//---------------------------- sub procedure ------------------
+// returns maximal number i such that u(i)<=b
+proc mix(int b, list u)
+{
+  int result=0;
+  int s=size(u);
+  int w=s;
+  if (s==0) { "size of list is 0"; return(result); }
+  if (b<0 ) { "negative b in MIX"; return(result); }
+  while ((w>1) && (u[w]>b)) { w--;} // min w=1
+  if (w>1)
+  {
+    return(w);
+  }
+  else // w<=1
+  {
+    if ( (w==1) && (u[w]> b) )
+    {
+      w=0;
+      return(w);
+    }
+  }
+  return(w);
+}
+
+//---------------------------- sub procedure ------------------
+proc bracket_k(int r, int s)
+{
+  int b=s-r;
+  int q;
+  int k=1;
+  int SF;
+  F=F+"*(";
+  while (b>0) // simulate repeat ... until b==0
+  {
+    q=mix(b,u);
+    while (q>0)
+    {
+      b=u[q]-1;
+      if (u[q]==(s-r))   // adding T's of max degree
+      {
+        F=F+"T("+ string(q) +")"+ "+";
+      }
+      else
+      {
+        if (S[(1+r+u[q])]!="u")
+        {
+          F=F+"T("+ string(q) +")";
+          bracket_k(r+u[q],s);
+         }
+      }
+      q=mix(b,u);
+      if (q==0) {b=0;}
+    } // end  while q>0
+    SF=size(F);
+    if (F[SF]!="+")
+    {
+      if (SF<=2) { F="";}
+      else { F=F[1..SF-2];}
+    }
+    if (b==0) { break; }   // ... until b==0
+  }
+  F[size(F)]=")";
+  F=F+"+";
+}
+
+//---------------------------- sub procedure ------------------
+// exports S, l, u
+proc StringS(int p, int q)
+{
+  int i=1; int j=0;
+  int e,e1=0,0;
+  string S="";
+  list l,u=0,0;
+  S="l";
+  l[1]=0;
+  int a,b=seq(p,q);
+  int k=1;
+  for (k=1;k<=(p*q-2*p-2*q);k++)
+  {
+    e=(e+a)%p; e1=(e1+b)%q;
+    if ( (e==(p-1)) || (e1==(q-1)) ) { S=S+" "; }
+    else
+    {
+      if ((e*q+e1*p) <= (p*q))
+      {
+        i++; l[i]=k; S=S+"l";
+      }
+      else
+      {
+        j++; u[j]=k; S=S+"u";
+      }
+    }
+  }
+  export S;
+  export u;
+  export l;
+}
+
+//---------------------------- main procedures ----------------
+proc StringF(int i, int j,int p, int q)
+"USAGE:  StringF(int i,j,p,q);
+RETURN:  nothing; exports string F which contains an expression
+         in variables T(i) with non-resolved brackets
+EXAMPLE: example StringF; shows an example
+"
+{
+  string F;
+  export F;exportto(Top,F);
+  StringS(p,q);
+  bracket_k(l[i],u[j]);
+  F=F[3..(size(F)-2)];
+}
+example
+{ "EXAMPLE:"; echo=2;
+ int p=5; int q=14;
+ int i=2; int j=9;
+ StringF(i,j,p,q);
+ F;
+}
+
+proc KScoef(int i,int j,int P,int Q, list qq);
+"USAGE:  KScoef(int i,j,P,Q, list qq);
+RETURN:  exports ring RC and number C within it. C is
+         the coefficient of the word defined in the list qq,
+         being a part of C[i,j] for x^p+y^q
+EXAMPLE: example KScoef; shows an example
+"
+// qq is a list of integers, representing
+// monomial T_q[1] * ...* T_q[s]
+// returns a ring RC in char 0 and number C in it
+{
+  int s=size(qq);
+  int U,V=seq(P,Q);
+  StringS(P,Q);
+  int n=l[i];
+  int d=P*Q;
+  int k=1; int m=1;
+  ring RC=0,x,dp;
+  number C=0;
+  number aux=0;
+  int t=0;
+  int e=0;
+  int e1=0;
+  aux = u[(qq[1])];
+  C = ((-1)^s)*(aux/d);
+  for (k=2; k<=s; k++)
+  {
+    t  = u[(qq[k-1])];
+    e  = (U*n)%P;
+    e  = e+ ((U*t)%P);
+    e1 = (V*n)%Q;
+    e1 = e1 + ((V*t)%Q);
+    n  = n + qq[k-1];
+    t  = u[(qq[k])];
+    if (e>=(P-1))
+    {
+      aux = (U*t)%P;
+      aux = aux/P;
+      C = C*aux;
+    }
+    else
+    {
+      if (e1>=(Q-1))
+      {
+        aux = (V*t)%Q;
+        aux = aux/Q;
+        C = C*aux;
+      }
+    }
+  }
+  export RC;exportto(Top,RC);
+  export C;
+}
+example
+{ "EXAMPLE:"; echo=2;
+ int p=5; int q=14;
+ int i=2; int j=9;
+ list L;
+ ring r=0,x,dp;
+ number c;
+ L[1]=3; L[2]=1; L[3]=3; L[4]=2;
+ KScoef(i,j,p,q,L);
+ c=imap(RC,C);
+ c;
+ L[1]=3; L[2]=1; L[3]=2; L[4]=3;
+ KScoef(i,j,p,q,L);
+ c=c+imap(RC,C);
+ c; // it is a coefficient of T1*T2*T3^2 in C[2,9] for x^5+y^14
+}
diff --git a/Singular/LIB/latex.lib b/Singular/LIB/latex.lib
new file mode 100644
index 0000000..c4b4349
--- /dev/null
+++ b/Singular/LIB/latex.lib
@@ -0,0 +1,3137 @@
+//////////////////////////////////////////////////////////////////////////////
+version="version latex.lib 4.0.0.0 Jun_2013 "; // $Id: 32a2d94de9faf1f65b5e7ee22a537ed14c2987b3 $
+category="Visualization";
+info="
+LIBRARY: latex.lib    Typesetting of Singular-Objects in LaTeX2e
+AUTHOR: Christian Gorzel, gorzelc at math.uni-muenster.de
+
+GLOBAL VARIABLES:
+  TeXwidth, TeXnofrac, TeXbrack, TeXproj, TeXaligned, TeXreplace, NoDollars
+  are used to control the typesetting.
+  Call @code{texdemo();} to obtain a LaTeX2e file @code{texlibdemo.tex}
+  explaining the features of @code{latex.lib} and its global variables.
+ at format
+  @code{TeXwidth} (int) -1, 0, 1..9, >9:  controls breaking of long polynomials
+  @code{TeXnofrac} (int) flag:  write 1/2 instead of \\frac@{1@}@{2@}
+  @code{TeXbrack} (string) \"@{\", \"(\", \"<\", \"|\", empty string:
+                                   controls brackets around ideals and matrices
+  @code{TeXproj} (int) flag:  write \":\" instead of \",\" in vectors
+  @code{TeXaligned} (int) flag:  write maps (and ideals) aligned
+  @code{TeXreplace} (list) list entries = 2 strings:  replacing symbols
+  @code{NoDollars} (int) flag:  suppresses surrounding $ signs
+ at end format
+PROCEDURES:
+ closetex(fnm)       writes closing line for LaTeX-document
+ opentex(fnm)        writes header for LaTeX-file fnm
+ tex(fnm)            calls LaTeX2e for LaTeX-file fnm
+ texdemo([n])        produces a file explaining the features of this lib
+ texfactorize(fnm,f) creates string in LaTeX-format for factors of polynomial f
+ texmap(fnm,m,r1,r2) creates string in LaTeX-format for map m:r1->r2
+ texname(fnm,s)      creates string in LaTeX-format for identifier
+ texobj(l)           creates string in LaTeX-format for any (basic) type
+ texpoly(f,n[,l])    creates string in LaTeX-format for poly
+ texproc(fnm,p)      creates string in LaTeX-format of text from proc p
+ texring(fnm,r[,l])  creates string in LaTeX-format for ring/qring
+ rmx(s)              removes .aux and .log files of LaTeX-files
+ xdvi(s)             calls xdvi for dvi-files
+        (parameters in square brackets [] are optional)
+        (Procedures with file output assume sufficient write permissions
+        when trying to append existing or create new files.)
+
+";
+
+LIB "inout.lib";  // only needed for pause();
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc closetex(string fname, list #)
+"USAGE:   closetex(fname); fname string
+RETURN:  nothing; writes a LaTeX2e closing line into file @code{<fname>}.
+NOTE:    preceding \">>\" are deleted and suffix \".tex\" (if not given)
+         is added to @code{fname}.
+EXAMPLE: example closetex; shows an example
+"
+{
+  string default = "latex2e";
+  string s;
+  int i = 1;
+  int flag;
+
+  if (size(#)) { default = #[1];}
+
+  if (default=="latex2e" or default == "latex")
+   {  s = "\\end{document}"; flag = 1;}
+  if (default=="amstex") {s = "\\enddocument"; flag = 1;}
+  if (default=="tex") {s = "\\bye"; flag = 1;}
+  if (not(flag)) { s = "";}
+
+  if (size(fname))
+  {
+   while (fname[i]==">"){i++;}
+   fname = fname[i,size(fname)-i+1];
+
+   if (size(fname)>=4)               // check if filename is ending with ".tex"
+   { if(fname[size(fname)-3,4]!=".tex") {fname = fname +".tex"; }
+   }
+   else {fname = fname + ".tex";}
+   write(fname, s);
+   write(fname," % - Thanks latex.lib and Singular - ");
+  }
+  else {return(s);}
+}
+example
+{ "EXAMPLE:"; echo=2;
+   opentex("exmpl");
+   texobj("exmpl","{\\large \\bf hello}");
+   closetex("exmpl");
+   echo=0;
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc tex(string fname, list #)
+"USAGE:   tex(fname); fname string
+RETURN:  nothing; calls latex (LaTeX2e) for compiling the file fname
+NOTE:    preceding \">>\" are deleted and suffix \".tex\" (if not given)
+         is added to @code{fname}.
+EXAMPLE: example tex; shows an example
+"
+{
+  string default = "latex2e";
+  int retval;
+  int i=1;
+  if (size(#)) {default = string(#[1]);}
+  if (size(fname))
+  {
+   while (fname[i]==">"){i++;}
+   fname = fname[i,size(fname)-i+1];
+
+   if (size(fname)>=4)          // check if filename is ending with ".tex"
+   { if(fname[size(fname)-3,4]!=".tex") {fname = fname +".tex"; }
+   }
+   else {fname = fname + ".tex";}
+   "calling "+default+" for:",fname,newline;
+
+   if (default=="latex2e")
+   {
+     retval = system("sh","latex " +  fname);
+   }
+   else
+   {
+     retval = system("sh",default + " " +  fname);
+   }
+  }
+  else
+  { " // -- Need a filename ";
+    return();
+  }
+}
+example
+{ "EXAMPLE:"; echo =2;
+  ring r;
+  ideal I = maxideal(7);
+  opentex("exp001");              // open latex2e document
+  texobj("exp001","An ideal ",I);
+  closetex("exp001");
+  tex("exp001");
+  echo=0;
+  pause("the created files will be deleted after pressing <RETURN>");
+  system("sh","rm exp001.*");
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc opentex(string fname, list #)
+"USAGE:   opentex(fname); fname string
+RETURN:  nothing; writes a LaTeX2e header into a new file @code{<fname>}.
+NOTE:    preceding \">>\" are deleted and suffix \".tex\" (if not given)
+         is added to @code{fname}.
+EXAMPLE: example opentex; shows an example
+"
+{
+  string default = "latex2e";
+  string s;
+  int i =1;
+  int flag;
+
+  if (size(#)) { default = #[1];}
+
+  if (default == "latex2e")          // the default  latex2e header
+  { s =
+      "\\documentclass{article}" + newline +
+      "\\usepackage{amsmath,amssymb}" + newline +
+     "%\\setlength{\\textwidth}{390pt}" + newline +
+      "\\parindent=0pt" + newline +
+      "\\newcommand{\\C}{\\mathbb{C}}" + newline +
+      "\\newcommand{\\F}{\\mathbb{F}}" + newline +
+      "\\newcommand{\\N}{\\mathbb{N}}" + newline +
+   // "\\renewcommand{\\P}{{\\Bbb P}}" + newline +
+      "\\newcommand{\\Q}{\\mathbb{Q}}" + newline +
+      "\\newcommand{\\R}{\\mathbb{R}}" + newline +
+      "\\newcommand{\\T}{\\mathbb{T}}" + newline +
+      "\\newcommand{\\Z}{\\mathbb{Z}}" + newline + newline +
+      "\\begin{document}";
+    flag = 1;
+  }
+  if (default == "latex")
+  { s =
+      "\\documentstyle[12pt,amstex]{article}" + newline +
+      "\\parindent=0pt" + newline +
+      "\\newcommand{\\C}{\\mathbb{C}}" + newline +
+      "\\newcommand{\\F}{\\mathbb{F}}" + newline +
+      "\\newcommand{\\N}{\\mathbb{N}}" + newline +
+   // "\\newcommand{\\P}{\\mathbb{P}}" + newline +
+      "\\newcommand{\\Q}{\\mathbb{Q}}" + newline +
+      "\\newcommand{\\R}{\\mathbb{R}}" + newline +
+      "\\newcommand{\\T}{\\mathbb{T}}" + newline +
+      "\\newcommand{\\Z}{\\mathbb{Z}}" + newline + newline +
+      "\\begin{document}";
+    flag = 1;
+  }
+  if (default == "amstex")
+  { s =
+     "\\documentstyle{amsppt} " + newline + newline +
+     "\\document";
+    flag = 1;
+  }
+
+  if (default == "tex")
+  { s =
+     "";
+    flag = 1;
+  }
+  if (default == "own")            // the proper own header
+  { s = "";
+    flag = 1;
+  }
+  if (not(flag)) { s = "";}
+
+  if (size(fname))
+  {
+   while (fname[i]==">"){i++;}
+   fname = fname[i,size(fname)-i+1];
+
+   if (size(fname)>=4)               // check if filename is ending with ".tex"
+   { if(fname[size(fname)-3,4]!=".tex") {fname = fname +".tex"; }
+   }
+   else {fname = fname + ".tex";}
+   fname = ">" + fname;
+   write(fname,s);
+  }
+  else {return(s);}
+}
+example
+{ "EXAMPLE:"; echo=2;
+   opentex("exmpl");
+   texobj("exmpl","hello");
+   closetex("exmpl");
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc texdemo(list #)
+"USAGE:   texdemo();
+RETURN:  nothing; generates a LaTeX2e file called @code{texlibdemo.tex}
+         explaining the features of @code{latex.lib} and its global variables.
+"
+{ int TeXdemostart = system("pid");
+  string fname = "texlibdemo";
+
+  if (size(#))
+  { if (typeof(#[1])=="int") {TeXdemostart = #[1];}
+  }
+  system("--random",TeXdemostart);
+
+  //if (size(#) ==2)
+  //{ if (typeof(#[2]) == "string") { fname = #[2];}
+  //}
+
+    if (size(fname))
+    {
+     if (size(fname)>=4)           // check if filename is ending with ".tex"
+     { if(fname[size(fname)-3,4]!=".tex") {fname = fname +".tex"; }
+     } else {fname = fname + ".tex";}
+    }
+
+  // -------- save global variables ---------
+  if (defined(NoDollars)) {int NoDoll=NoDollars; kill NoDollars;}
+  if (defined(TeXaligned)) {int Teali=TeXaligned; kill TeXaligned;}
+  if (defined(TeXreplace)) {list Terep=TeXreplace; kill TeXreplace;}
+  if (defined(TeXwidth)) {int Tewid=TeXwidth; kill TeXwidth;}
+  if (defined(TeXbrack)) {string Tebra=TeXbrack; kill TeXbrack;}
+  if (defined(TeXnofrac)) {int Tenof=TeXnofrac; kill TeXnofrac;}
+  if (defined(TeXproj)) {int Tepro=TeXproj; kill TeXproj;}
+  // ----------------------------------------
+   print(" Generating demofile .");
+   part0(fname); print(" .");
+   part1(fname); print(" .");
+   part2(fname); print(" .");
+   part3(fname); print(" .");
+   print(" Demofile generated.");
+   if (size(fname))
+   {
+    print(" Call latex now by tex(\"texlibdemo\");" );
+    print(" To view the file, call xdvi by xdvi(\"texlibdemo\");" );
+    // print(" Call latex now by tex(\"" + fname + "\");" );
+    //print(" To view the file, call xdvi by xdvi(\"" + fname + "\");" );
+    print(" .log and .aux files may be deleted with rmx(\"texlibdemo\");");
+   }
+  // -------- save global variables ---------
+  if (defined(NoDoll)) {int NoDollars=NoDoll; export NoDollars; kill NoDoll;}
+  if (defined(Teali)) {int TeXaligned=Teali; export TeXaligned; kill Teali;}
+  if (defined(Terep)) {list TeXreplace=Terep; export TeXreplace; kill Terep;}
+  if (defined(Tewid)) {int TeXwidth=Tewid; export TeXwidth; kill Tewid;}
+  if (defined(Tebra)) {string TeXbrack=Tebra; export TeXbrack; kill Tebra;}
+  if (defined(Tenof)) {int TeXnofrac=Tenof; export TeXnofrac; kill Tenof;}
+  if (defined(Tepro)) {int TeXproj=Tepro; export TeXproj; kill Tepro;}
+  // ----------------------------------------
+
+  return();
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc texfactorize(string fname, poly f, list #)
+"USAGE:   texfactorize(fname,f); fname string, f poly
+RETURN:  if @code{fname=\"\"}: string, f as a product of its irreducible
+         factors@*
+         otherwise: append this string to the file @code{<fname>}, and
+         return nothing.
+NOTE:    preceding \">>\" are deleted and suffix \".tex\" (if not given)
+         is added to @code{fname}.
+EXAMPLE: example texfactorize; shows an example
+"
+{
+  def @r = basering;
+  list l;
+  int i,j,k,Tw,TW,ND;;
+  intvec v;
+  string s,t;
+  string D = "$";
+  poly g;
+
+  ND = defined(NoDollars);
+
+  if (!(ND)) {int NoDollars; export NoDollars;}
+  else { D = ""; }
+  TW = defined(TeXwidth);
+  if (TW) {Tw = TeXwidth; TeXwidth = -1;}
+  else {int TeXwidth = -1; export TeXwidth;}
+
+   l = factorize(f);
+   if (l[1][1]<>1){s = texpoly("",l[1][1]);}
+   if (size(l[1])>1)
+   {
+    if (l[1][1]!=-1 and l[1][1]!=1) { s = texpoly("",l[1][1]); }
+    if (l[1][1]==-1) { s = "-";}
+   }
+   else
+   {
+     s = texpoly("",l[1]);
+   }
+
+   for(i=2;i<=size(l[1]);i++)
+   {
+    if(size(s) and s!="-"){s = s+"\\cdot ";}
+    g = l[1][i];
+    v = leadexp(g);
+    k=0;
+    for(j=1;j<=size(v);j++){k = k + v[j];}
+    if(size(g)>1 or (size(g)==1 and k>1))
+    { t = "(" + texpoly("",l[1][i]) + ")";}
+    else { t =  texpoly("",l[1][i]);}
+    if (l[2][i]>1)
+    { t = t+"^{" +string(l[2][i]) + "}";}
+    s = s + t;
+   }
+   if (!(ND)) { kill NoDollars;}  // kill Latex::
+   s = D + s + D;
+   if (TW) {TeXwidth = Tw;}
+   if (!TW) {kill TeXwidth;}    // kill Latex::
+
+  if(size(fname))
+  { i=1;
+    while (fname[i]==">"){i++;}
+    fname = fname[i,size(fname)-i+1];
+
+    if (size(fname)>=4)             // check if filename is ending with ".tex"
+    { if(fname[size(fname)-3,4]!=".tex") {fname = fname +".tex"; }
+    }
+    else {fname = fname + ".tex";}
+    write(fname,s);
+  }
+  else{return(s);}
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring r2 = 13,(x,y),dp;
+  poly f = (x+1+y)^2*x3y*(2x-2y)*y12;
+  texfactorize("",f);
+  ring R49 = (7,a),x,dp;
+  minpoly = a2+a+3;
+  poly f = (a24x5+x3)*a2x6*(x+1)^2;
+  f;
+  texfactorize("",f);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc texmap(string fname, def m, def @r1, def @r2, list #)
+"USAGE:   texmap(fname,m, at r1, at r2); fname string, m string/map, @r1, at r2 rings
+RETURN:  if @code{fname=\"\"}: string, the map m from @r1 to @r2 (preceded
+         by its name if m = string) in TeX-typesetting;@*
+         otherwise: append this string to the file @code{<fname>}, and
+         return nothing.
+NOTE:    preceding \">>\" are deleted in @code{fname}, and suffix \".tex\"
+         (if not given) is added to @code{fname}.
+         If m is a string then it has to be the name of an existing map
+         from @r1 to @r2.
+EXAMPLE: example texmap; shows an example
+"
+{
+  int saveDollars= defined(NoDollars);
+  int TX = defined(TeXwidth);
+  int Tw;
+  int i,n;
+  string r1str,r2str, varr1str, varr2str;
+  string mapname,t,s;
+  string D,DD,vrg = "$","$$",",";
+  def @r = basering;
+  def themap;
+  list l1,l2;
+  string rr1,rr2 = "@r1","@r2";
+
+// --- store all actual informations
+  if(TX) { Tw = TeXwidth; TeXwidth = -1;}
+  else { int TeXwidth = -1; export TeXwidth;}
+  if (!(saveDollars)) { int  NoDollars; export NoDollars;}
+  if (defined(TeXproj)) {vrg = ":";}
+
+  if (size(#))
+  { if (typeof(#[1])=="list")
+    { l1 = #[1];
+      if(size(#)==2) { l2 = #[2];}
+    }
+    else {l1=#; l2 =#;}
+  }
+// --- tex the information in preimring r1
+
+  setring(@r1);
+  r1str = texring("", at r1,l1);
+// --- avoid an execute; hence construct an ideal
+
+  n = nvars(@r1);
+  if (n>1) { t = "\\left(";}
+  ideal @I = var(1);
+  t = t + texpoly("",var(1));
+  for(i=2;i<=n;i++)
+  { @I = @I + var(i);
+    t = t + vrg + texpoly("",var(i));
+  }
+  if (n>1) { t = t + "\\right)";}
+  varr1str = t;
+
+// --- now the things in ring ring r2
+
+  setring(@r2);
+ // listvar();
+
+  if (typeof(m)=="string")
+  { themap = `m`;
+    mapname = m;
+    if (defined(TeXreplace))
+    {
+     //mapname = rp(mapname);   // rp ausschreiben !
+     for(int ii=1;ii<=size(TeXreplace);ii++)
+     {
+      if (TeXreplace[ii][1]==mapname) {mapname= TeXreplace[ii][2]; break;}
+     }
+    }
+    mapname = mapname + ":";
+  }
+  if (typeof(m)=="map") { themap = m;}
+
+  r2str = texring("", at r2,l2);
+  ideal @J  = themap(@I);
+  n = size(matrix(@J));
+  if (n>1) { t = " \\left(";}
+  if (!(defined(TeXaligned)) and (n>1))
+      { t = t + newline + "\\begin{array}{c}" + newline;}
+  t = t + texpoly("", at J[1]);
+  for (i=2;i<=n; i++)
+  {if(defined(TeXaligned))
+   { t = t + vrg + texpoly("", at J[i]); }
+   else { t = t + "\\\\" + newline + texpoly("", at J[i]);}
+  }
+  if (!(defined(TeXaligned)) and (n>1))
+      { t = t + newline + "\\end{array}" + newline;}
+  if (n>1) {t = t + "\\right)";}
+  varr2str = t;
+
+// --- go back to  ring r1 to kill @I
+
+  setring(@r1);
+  kill @I;
+
+// --- now reset the old settings and stick all the information together
+
+  setring(@r);
+  if (!(saveDollars)) { kill NoDollars;}  // kill Latex::
+  if (TX) {TeXwidth = Tw;}
+  else { kill TeXwidth;}   // kill Latex::
+  if (defined(NoDollars))
+  { D,DD = "",""; }
+
+  if (defined(TeXaligned))
+  { s = D + mapname;
+    s =  s + r1str + "\\longrightarrow" + r2str + ", \\ " +
+        varr1str + "\\longmapsto" + varr2str + D; }
+  else
+  { s = DD;
+    s = s + newline + "\\begin{array}{rcc}" +  newline;
+    s = s + mapname + r1str + " & \\longrightarrow & " +  r2str + "\\\\[2mm]"
+          + newline;
+    s = s + varr1str + " & \\longmapsto & " +  newline + varr2str + newline;
+    s = s + "\\end{array}" + newline;
+    s = s +  DD;
+  }
+
+  if (size(fname))
+  { i=1;
+    while (fname[i]==">"){i++;}
+    fname = fname[i,size(fname)-i+1];
+
+    if (size(fname)>=4)          // check if filename is ending with ".tex"
+    { if(fname[size(fname)-3,4]!=".tex") {fname = fname +".tex"; }
+    }
+    else {fname = fname + ".tex";}
+    write(fname,s);
+  }
+  else {return(s);}
+}
+example
+{
+  echo=0;
+  // -------- prepare for example ---------
+  if (defined(TeXaligned)) {int Teali=TeXaligned; kill TeXaligned;}
+  if (defined(TeXreplace)) {list Terep=TeXreplace; kill TeXreplace;}
+  // -------- the example starts here ---------
+  //
+  "EXAMPLE:"; echo = 2;
+  string fname = "tldemo";
+  ring @r1=0,(x,y,z),dp;
+  export @r1;
+  ring r2=0,(u,v),dp;
+  map @phi =(@r1,u2,uv -v,v2); export @phi;
+  list TeXreplace;
+  TeXreplace[1] = list("@phi","\\phi");    // @phi --> \phi
+  export TeXreplace;
+  texmap("","@phi", at r1,r2);                // standard form
+  //
+  int TeXaligned; export TeXaligned;       // map in one line
+  texmap("", at phi, at r1,r2);
+  //
+  kill @r1,TeXreplace,TeXaligned;
+  echo = 0;
+  //
+  // --- restore global variables if previously defined ---
+  if (defined(Teali)) {int TeXaligned=Teali; export TeXaligned; kill Teali;}
+  if (defined(Terep)) {list TeXreplace=Terep; export TeXreplace; kill Terep;}
+}
+///////////////////////////////////////////////////////////////////////////////
+
+static proc manipul(string s)
+{
+  string st;
+  int i,anf,end,op,bigch;
+  int n;
+  if (s[1]=="{") { return(s[2,size(s)-2]);}
+  if (s=="") { return(s);}
+  s = s + newline;             // add a terminating sign
+  anf=1;
+  while(s[i]!=newline)
+  {
+    i =anf;
+    while(s[i]<"0" or s[i]>"9" and s[i]!="'" and s[i]!= "_" and s[i]!="~" and
+          s[i]!="(" and s[i]!=")" and s[i]!= "[" and s[i]!=newline) {i++;}
+    if (s[i]==newline){st = st + s[anf,i-anf]; n = n+10*(i-anf); return(st);}
+    st = st + s[anf,i-anf];                        // the starting letters
+    if (s[anf]>="A" and s[anf]<="Z") {bigch=1;}
+    if (s[i]=="'") { st = st + "'";i++;}
+    if (s[i]=="~") { st = "\\tilde{" + st + "}"; i++;}
+    if (s[i]=="_") { i++;}
+    if (s[i]=="(") { op =1;i++;}
+    if (s[i]=="[") { anf = i+1;
+    while(s[i]!="]"){i++;}                    // matrices and vectors
+    st = st + "_{" + s[anf,i-anf] + "}"; n = n+ 5*(i-anf); i++;
+   // besser: while s[i]<> nwline : scan forward: end, return
+  }
+  if (s[i]==newline) {return(st);}
+  anf =i;
+  while (s[i]>="0" and s[i]<="9") {i++;}  // parse number after the letters
+  if (bigch and not(op)) { st = st + "^{" + s[anf,i-anf] + "}"; bigch =0;}
+  else { st = st + "_{" + s[anf,i-anf] + "}";}
+  n = n+5*(i-anf);
+  anf =i;            // the next text in ( , ) as exponent
+  if (op)
+  {
+    if (s[i]== ","){anf = anf+1;}
+    while(s[i] !=")"){ i++;}
+    if (i<>anf)
+      {
+        st = st + "^{" + s[anf,i-anf] + "}"; n = n +5*(i-anf);}
+        i++;
+      }
+    anf =i;
+  }
+  return(st);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc texname(string fname, string s)
+"USAGE:   texname(fname,s);  fname,s  strings
+RETURN:  if @code{fname=\"\"}: the transformed string s, for which the
+         following rules apply:
+ at example
+      s' + \"~\"             -->  \"\\tilde@{\"+ s' +\"@}\"
+     \"_\" + int             -->       \"_@{\" + int +\"@}\"
+  \"[\" + s' + \"]\"           -->      \"_@{\" + s' + \"@}\"
+   \"A..Z\" + int            --> \"A..Z\" + \"^@{\" + int + \"@}\"
+   \"a..z\" + int            --> \"a..z\" + \"_@{\" + int + \"@}\"
+\"(\" + int + \",\" + s' + \")\" --> \"_@{\"+ int +\"@}\" + \"^@{\" + s'+\"@}\"
+ at end example
+         Furthermore, strings which begin with a left brace are modified
+         by deleting the first and the last character (which is then assumed to
+         be a right brace).
+
+         if @code{fname!=\"\"}: append the transformed string s to the file
+         @code{<fname>}, and return nothing.
+NOTE:    preceding \">>\" are deleted in @code{fname}, and suffix \".tex\"
+         (if not given) is added to @code{fname}.
+EXAMPLE: example texname; shows an example
+"
+{
+  string st, extr;
+  st=manipul(s);
+  if (size(fname))
+  {
+    int i=1;
+    while (fname[i]==">"){i++;}
+    fname = fname[i,size(fname)-i+1];
+    if (size(fname)>=4)            // check if filename is ending with ".tex"
+    {
+      if(fname[size(fname)-3,4]!=".tex") {fname = fname +".tex"; }
+    }
+    else {fname = fname + ".tex";}
+    write(fname,st);
+  }
+  else {return(st);}
+}
+example
+{ "EXAMPLE:"; echo =2;
+   ring r = 0,(x,y),lp;
+   poly f = 3xy4 + 2xy2 + x5y3 + x + y6;
+   texname("","{f(10)}");
+   texname("","f(10) =");
+   texname("","n1");
+   texname("","T1_12");
+   texname("","g'_11");
+   texname("","f23");
+   texname("","M[2,3]");
+   texname("","A(0,3);");
+   texname("","E~(3)");
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc texobj(string fname, list #)
+"USAGE:   texobj(fname,l); fname string, l list
+RETURN:  if @code{fname=\"\"}: string, the entries of l in LaTeX-typesetting;@*
+         otherwise: append this string to the file @code{<fname>}, and
+         return nothing.
+NOTE:    preceding \">>\" are deleted in @code{fname}, and suffix \".tex\"
+         (if not given) is added to @code{fname}.
+EXAMPLE: example texobj; shows an example
+"
+{
+ int i,j,k,nr,nc,linear,Tw,Dollars;
+ int ND = defined(NoDollars);
+ int TW = defined(TeXwidth);
+
+ if(defined(basering)){ poly g,h; matrix M;}
+ string s,t,l,ineq,sg,Iname;
+ string sep= ",";
+ string D,DA,DE = "$","$$"+newline,"$$";
+ string OB,CB = "(",")";
+ if (defined(TeXbrack))
+ {// if (TeXbrack=="(") {OB = "("; CB = ")";}
+   if (TeXbrack=="<") {OB = "<"; CB = ">";}
+   if (TeXbrack=="{") {OB = "{"; CB = "}";}
+   if (TeXbrack=="|") {OB = "|"; CB = "|";}
+   if (TeXbrack=="" ) {OB = "."; CB = ".";}
+ }
+
+ if (!(TW)) { int TeXwidth = -1; export TeXwidth; }
+ Tw = TeXwidth;
+
+ if (defined(TeXproj)){ sep = ":";}
+ if(ND) { D,DA,DE="","","";}
+ else {int NoDollars; export NoDollars;}
+
+ if (size(#)==1)
+ { if (typeof(#[1])=="int" or typeof(#[1])=="intvec" or typeof(#[1])=="vector"
+    or typeof(#[1])=="number" or typeof(#[1])=="bigint" or defined(TeXaligned))
+   { DA = D; DE = D; }
+}
+
+ s = DA;
+
+ for (k=1; k<=size(#); k++)
+ { def obj = #[k];
+   if (typeof(obj) == "string")
+   { if (defined(`obj`))
+     { if (typeof(`obj`)=="ideal")
+       {
+         Iname = obj; def e = `obj`;     //convert to correct type ideal
+         kill obj; def obj = e; kill e;
+       }
+       else {s = s + obj + newline;}
+     }
+    else {s = s + obj + newline;}
+   }
+   if (typeof(obj) == "int" or typeof(#[1])=="bigint")
+   { s = s + "  " + string(obj) + "  ";}
+
+   if (typeof(obj) == "intvec")
+   { s = s + " (";
+     for(j=1; j<size(obj);j++) { s = s + string(obj[j]) + sep;}
+     s = s +  string(obj[j]) + ") ";
+   }
+
+   if (typeof(obj) == "number" )
+   { s = s + texpoly("",obj) + newline;
+   }
+
+   if (typeof(obj) == "poly")
+   { int TeXdisplay; export TeXdisplay;
+     s = s + "\\begin{array}{rl}" + newline;
+     s = s + texpoly("",obj) + "\\\\" + newline;
+     s = s + "\\end{array}" + newline;
+    kill TeXdisplay;
+   }
+
+   if (typeof(obj) == "vector")
+   { if (obj==0) { s = s  + "0" ;}
+     else
+     { if (Tw==0) { TeXwidth = -1;}
+      s = s + "\\left" + OB;
+      for(j=1; j<nrows(obj); j++) {s = s + texpoly("",obj[j]) + sep;}
+      s = s + texpoly("",obj[j])  + "\\right" + CB + newline;
+      TeXwidth = Tw;
+     }
+    }
+
+   if (typeof(obj) == "ideal")
+   { if (size(Iname))   // verwende hier align
+     { if (Tw==0) {TeXwidth = -1;}
+
+      // Lasse hier TeXwidth == 0 zu !
+      // if (!(defined(TeXaligned)))
+      //  { untereinander }
+      // else { hintereinander }
+      //
+      //
+      //  s = s + Iname + "=" + texpoly("",obj,",");
+      //  siehe ebenso noch einmal am Ende : ! (TeXwidth <> 0 !? )
+
+       s =  s + "\\begin{array}{rcl}" + newline;
+       for (i=1;i<=size(matrix(obj));i++)
+       { s =  s + Iname+ "_{" + string(i) + "} & = & "
+               + texpoly("",obj[i]);
+         if (i<size(matrix(obj))){ s = s  + "\\\\" + newline;}
+       }
+       s = s + newline;
+       s = s + "\\end{array}" + newline;
+       TeXwidth = Tw;
+       Iname ="";
+     }
+     else
+     {
+      if (TeXwidth==0)
+      { TeXwidth = -1;
+        obj= simplify(obj,2);
+        linear = 1;
+        for (j=1;j<=size(obj);j++)
+        { if (deg(obj[j])>1){linear =0; break;}
+        }
+        if (!(linear))
+        { s = s + "\\begin{array}{rcl}" + newline;
+          for(j=1;j<=size(obj);j++)
+          { h = jet(obj[j],0);  // absterm
+            ineq = "=" ;
+            l = texpoly("",obj[j]-h) + " & " + ineq + " & " + texpoly("",-h);
+            if(j<size(obj)) { l = l + " \\\\";}
+            s =s+ l + newline;
+           }
+          s = s + "\\end{array}" + newline;
+        }
+        else   // linear
+        { s = s +
+   "\\begin{array}{*{" + string(2*nvars(basering)-1) + "}{c}cr}" + newline;
+           for(j=1; j<=size(obj);j++)
+           { h = jet(obj[j],0);   // absterm
+             ineq = "=";
+              l = ""; nc = 0;
+              for (i=1; i<=nvars(basering);i++)
+              { t = " "; sg ="";
+                g = obj[j]-subst(obj[j],var(i),0);
+                if (g!=0) { t = texpoly("",g);}
+                if (i>1)
+                { if (t[1]!="-" and t[1]!= " " and nc ){sg = "+";}
+                  if  (t[1]=="-") { sg = "-"; nc =1; t=t[2,size(t)-1];}
+                  if (t==" ") {sg ="";}
+                  l = l + " & " + sg + " & " + t;
+                }
+                else { l = t;}
+                if (g!=0) {nc = 1;}
+               }
+
+               l = l + " & " + ineq + " & " + texpoly("",-h);
+             if (j < size(obj)) { l = l + " \\\\";}
+             s = s + l + newline;
+            } // end for (j)
+          s = s + "\\end{array}";
+         }  // end else linear
+        TeXwidth = 0;
+       } // end TeXwidth == 0
+   else // TeXwidth <> 0
+   { s =  s + "\\left"+ OB;
+     if (defined(TeXaligned))
+     { s = s + texpoly("",obj,",");
+     }
+     else
+     { s = s + newline + "\\begin{array}{c}" + newline +
+               texpoly("",obj,", \\\\" + newline) +
+                newline + "\\end{array}" + newline;
+     }
+    s = s + "\\right" + CB;
+    } // end TeXwidth <> 0
+   }  // not Iname
+// s;
+  }
+
+   if (typeof(obj) == "module")
+   { M = matrix(obj);
+     if (Tw ==0 or Tw > 9) { TeXwidth = -1;}
+     s = s + "\\left" + OB + newline;
+     if (!(defined(TeXaligned)))
+     {  // Naechste Zeile nicht notwendig !
+     // s = s + "\\begin{array}{*{"+ string(ncols(M)) + "}{c}}" + newline;
+      for(j=1;j<=ncols(M);j++)
+      { l = "\\left" + OB + newline + "\\begin{array}{c}" + newline;
+        l = l + texpoly("",ideal(M[1..nrows(M),j]), " \\\\" + newline)
+              + newline + "\\end{array}" +newline + "\\right" + CB + newline;
+        if (j< ncols(M)) { l = l + " , " + newline;}
+        s = s + l ;
+      }
+     }
+     else    // TeXaligned
+     {
+      for(j=1;j<=ncols(M);j++)
+      { s = s + "\\left" + OB + newline +
+           texpoly("",ideal(M[1..nrows(M),j]),",") + newline + "\\right" + CB;
+        if (j<ncols(M)) { s = s + "," + newline; }
+      }
+     }
+    s = s  + "\\right" + CB + newline;
+   } // module part
+
+   if (typeof(obj) == "matrix")
+   { if (Tw==0 or Tw > 9) {TeXwidth = -1;}
+     l = "";
+   //  M = transpose(obj);
+     s = s + "\\left" + OB + newline +
+             "\\begin{array}{*{"+ string(ncols(obj)) + "}{c}" + "}"+ newline;
+     for(i=1;i<=nrows(obj);i++)
+     { l = l + texpoly("",ideal(obj[i,1..ncols(obj)])," & ");
+       if (i<nrows(obj)) { l = l + " \\\\" + newline;}
+     }
+     l = l + newline;
+     s = s + l + "\\end{array}" + newline +
+                 "\\right" + CB + newline;
+    TeXwidth = Tw;
+  }
+
+   if (typeof(obj) == "intmat")
+   { nr,nc = nrows(obj),ncols(obj);
+     l = "";
+     l =  "\\left" + OB + newline +
+          "\\begin{array}{*{"+ string(nc) + "}{r}}"+ newline;
+     for(i=1;i<=nr;i++)
+     { for(j=1;j<=nc;j++)
+       { l = l + string(obj[i,j]);
+         if (j <nc ) { l = l + " & ";}
+         else {if( i < nr) { l = l + "\\\\" + newline;}}
+       }
+     }
+     l = l + newline + "\\end{array}" + newline +
+             "\\right" + CB + newline;
+    s = s + l;
+  }
+
+  if (typeof(obj) == "ring" or
+      typeof(obj) == "qring") { s = s + D + texring("",obj) + D + newline;}
+
+  kill obj;
+ }
+
+ s = s +  DE;// + newline;
+
+ if(!(ND)) { kill NoDollars;}  // kill Latex::
+ if(!(TW)) { kill TeXwidth;}   // kill Latex::
+
+ if(size(fname))
+ { i=1;
+  while (fname[i]==">"){i++;}
+  fname = fname[i,size(fname)-i+1];
+  if (size(fname)>=4)               // check if filename is ending with ".tex"
+  { if(fname[size(fname)-3,4]!=".tex") {fname = fname +".tex"; }
+  }
+  else {fname = fname + ".tex";}
+  write(fname,s);
+ }
+ else {return(s);}
+}
+example
+{
+   echo=0;
+   // -------- prepare for example ---------
+   if (defined(TeXaligned)) {int Teali=TeXaligned; kill TeXaligned;}
+   if (defined(TeXbrack)){string Tebra=TeXbrack; kill TeXbrack;}
+   "EXAMPLE:"; echo = 2;
+   //
+   //  --------------  typesetting for polynomials ----------
+   ring r = 0,(x,y),lp;
+   poly f = x5y3 + 3xy4 + 2xy2 + y6;
+   f;
+   texobj("",f);
+   pause();
+   //  --------------  typesetting for ideals ----------
+   ideal G = jacob(f);
+   G;
+   texobj("",G);
+   pause();
+   //  --------------  variation of typesetting for ideals ----------
+   int TeXaligned = 1; export TeXaligned;
+   string TeXbrack = "<"; export TeXbrack;
+   texobj("",G);
+   pause();
+   kill TeXaligned, TeXbrack;
+   //  --------------  typesetting for matrices ----------
+   matrix J = jacob(G);
+   texobj("",J);
+   pause();
+   //  --------------  typesetting for intmats ----------
+   intmat m[3][4] = 9,2,4,5,2,5,-2,4,-6,10,-1,2,7;
+   texobj("",m);
+   echo=0;
+   //
+   // --- restore global variables if previously defined ---
+   if (defined(Teali)){int TeXaligned=Teali; export TeXaligned; kill Teali;}
+   if (defined(Tebra)){string TeXbrack=Tebra; export TeXbrack; kill Tebra;}
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc texproc(string fname,string pname)
+"USAGE:   texproc(fname,pname); fname,pname strings
+ASSUME:  @code{`pname`} is a procedure.
+RETURN:  if @code{fname=\"\"}: string, the proc @code{`pname`} in a verbatim
+         environment in LaTeX-typesetting;@*
+         otherwise: append this string to the file @code{<fname>}, and
+         return nothing.
+NOTE:    preceding \">>\" are deleted in @code{fname}, and suffix \".tex\"
+         (if not given) is added to @code{fname}.@*
+EXAMPLE: example texproc; shows an example
+"
+{
+  int i,j,k,nl;
+  string @p,s,t;
+
+  j = 1;
+
+  if (defined(`pname`))
+  { if (typeof(`pname`)=="proc")
+    { @p = string(`pname`);
+      nl = find(@p,newline);
+      s = "\\begin{verbatim}" + newline;
+      s = s + "proc " + pname + "(";
+      i = find(@p,"parameter");       // collecting the parameters
+      k = find(@p,"alias");           // and the alias arguments
+      while((i and i < nl) or (k and k < nl))
+      {
+        if (i and (k==0  or i<k))
+        {
+         j=find(@p,";",i);
+         t = @p[i+10,j-i-10];
+         if(i>1){s = s + ",";};
+         s = s + t;
+        }
+        if (k and (i==0  or k<i))
+        {
+         j=find(@p,";",k);
+         t = @p[k,j-k];
+         if(k>1){s = s + ",";};
+         s = s + t;
+        }
+        i = find(@p,"parameter",j);
+        k = find(@p,"alias",j);
+      }
+      s = s + ")" + newline;
+     j++;                      // skip one for the newline
+     i = find(@p,";"+"return();"+newline,j);
+     if (!(i))
+     { i = find(@p,";"+"RETURN();"+newline,j); }  // j kann hier weg
+     s = s + "{" + @p[j,i-j-1] + "}" + newline;
+     s = s + "\\end{verbatim}" + newline;
+   }
+  }
+  else
+  { print(" // -- Error: No such proc defined");
+    return();
+  }
+  if(size(fname))
+  { i=1;
+    while (fname[i]==">"){i++;}
+    fname = fname[i,size(fname)-i+1];
+    if (size(fname)>=4)        // check if filename is ending with ".tex"
+    { if(fname[size(fname)-3,4]!=".tex") {fname = fname +".tex"; }
+    }
+    else {fname = fname + ".tex";}
+    write(fname,s);
+  }
+  else{return(s);}
+}
+example
+{ "EXAMPLE:"; echo=2;
+  texproc("","texproc");
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static proc tvar(intvec v)
+{
+  int i,j,ldots;
+  string s;
+  j = 1;
+  s = texpoly("",var(1));
+
+  if (nvars(basering)==1) { return(s);}
+  if (nvars(basering)==2) { return(s + "," + texpoly("",var(2)));}
+  if (size(v)==1 and v[1] == 1)
+     {return(s + ",\\ldots,"+ texpoly("",var(nvars(basering))));}
+  if (v[1]==1 and size(v) >1) {j++;}
+  for(i=2;i<nvars(basering);i++)
+  { if (i<v[j]  and !(ldots))
+    { s = s + ",\\ldots";
+      ldots =1;
+    }
+    if (i== v[j])
+    { s = s + "," + texpoly("",var(i));
+      ldots =0;
+      if (j< size(v)) {j++;}
+    }
+  }
+  if (v[j]<nvars(basering)-1) { s = s + ",\\ldots";}
+  return(s + "," + texpoly("",var(nvars(basering))));
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc texring(string fname, def r, list #)
+"USAGE:   texring(fname, r[,L]); fname string, r ring, L list
+RETURN:  if @code{fname=\"\"}: string, the ring in TeX-typesetting;@*
+         otherwise: append this string to the file @code{<fname>} and
+         return nothing.
+NOTE:    preceding \">>\" are deleted and suffix \".tex\" (if not given)
+         is added to @code{fname}.@*
+         The optional list L is assumed to be a list of strings which control,
+         for instance the symbol for the field of coefficients.@*
+         For more details call @code{texdemo();} (generates a LaTeX2e
+         file called @code{texlibdemo.tex} which explains all features of
+         @code{texring}).
+EXAMPLE: example texring; shows an example
+"
+{
+  int i,galT,intT,flag,mipo,nopar,Dollars,TB,TA;
+  string ob,cb,cf,en,s,t,savebrack; //opening bracket, closing br, coef.field
+  intvec v;
+
+  setring r;
+  if (!(defined(NoDollars))){ Dollars = 1; int NoDollars; export NoDollars;}
+  ob,cb = "[","]";
+  if (find(ordstr(r),"s")) { ob,cb="[[","]]";}
+  if(char(r)==0){cf="\\Q";}
+  if(find(charstr(r),"integer"))    // 4.10.10
+  {
+    intT=1;
+    cf="\\Z";
+    if (char(r)>0) { cf=cf+"_{"+string(char(r))+"}";}
+  }
+  if(find(charstr(r),"real")){cf="\\R";}
+  if(find(charstr(r),"complex")){cf="\\C"; nopar=1;}   // 28.10.06
+  if(char(r)==prime(char(r))){cf="\\Z_{"+string(char(r))+"}";}
+  if(char(r)>0 and !intT)
+  { i = find(charstr(r),",");
+    if(i)
+    { t= charstr(r)[1,i-1];
+      galT = (t <> string(char(r)));
+      if (galT) { cf = "\\F_{"+ t + "}";}
+    }
+  }     // all other cases are cover already by char(r)=? prime(char)
+
+  if (size(#))
+  { if (typeof(#[1])=="list") { # = #[1];}
+  }
+  for (i=1;i<=size(#);i++)
+  { flag =0;
+    if(typeof(#[i])=="string")
+    {
+     if(#[i][1]=="^" or #[i][1]=="_"){en=en+#[i];flag = 1;}
+     if(#[i]=="mipo"){mipo=1; flag = 1;}
+     if(#[i]=="{"){ob,cb="\\{","\\}";flag=1;}
+     if(#[i]=="{{"){ob,cb="\\{\\{","\\}\\}";flag=1;}
+     if(#[i]=="["){ob,cb="[","]";flag=1;}
+     if(#[i]=="[["){ob,cb="[[","]]";flag=1;}
+     if(#[i]=="<"){ob,cb="<",">";flag=1;}
+     if(#[i]=="<<"){ob,cb="{\\ll}","{\\gg}";flag=1;}
+     if(#[i]=="C"){cf="\\C";flag=1;}
+     if(#[i]=="Q"){cf="\\Q";flag=1;}
+     if((#[i]=="k" or #[i]=="K" or #[i]=="R") and !(galT))
+                   {cf=#[i]; flag=1; nopar=1;}
+     if (flag!=1) {cf = #[i];}  // for all the cases not covered here e.g Z_(p)
+    }                           // or Q[i]
+
+    if ((typeof(#[i])=="intvec") or
+        (typeof(#[i])=="int")){v=#[i];}
+   }
+  s = cf;
+ // now the parameters
+ // t;
+  if(npars(r) and ((t==string(char(r))) or char(r)==0) and !(nopar))
+  {
+   s = s + "(";                      // !! mit ideal !!
+   for(i=1;i<npars(r);i++) {s = s + texpoly("",par(i)) + ",";}
+   s = s + texpoly("",par(npars(r))) + ")";
+  }                               // parameters done
+  if (!(galT) and mipo and minpoly!=0)
+  { s = s + "/" + list(parsp(string(minpoly),0))[1];}
+  s = s + ob;
+  if (v!=0 and nvars(r)>3)
+  { s = s + tvar(v);}
+  else
+  { s = s + texpoly("",maxideal(1),","); }
+   s = s + cb + en;
+
+  if (typeof(r)=="qring")
+  { ideal @I = ideal(r);
+    if (defined(TeXbrack))
+    {
+      TB =1; savebrack = TeXbrack;
+      if (TeXbrack!= "<" and TeXbrack!="(") { TeXbrack = "<";}
+    }
+    TA = defined(TeXaligned);
+    if (!(TA)) { int TeXaligned; export TeXaligned; }
+    t = texobj("", at I);
+ //   @I;
+ //   t;
+    if (TB) { TeXbrack = savebrack;}
+    if (!(TA)) { kill TeXaligned;}  // kill Latex::
+    s = s + "/" + t;
+  }
+
+  if (Dollars)
+  { kill NoDollars;   // kill Latex::
+    s =  "$" + s + "$";
+  }
+  if (size(fname))
+  { i=1;
+     while (fname[i]==">"){i++;}
+     fname = fname[i,size(fname)-i+1];
+
+     if (size(fname)>=4)           // check if filename is ending with ".tex"
+     { if(fname[size(fname)-3,4]!=".tex") {fname = fname +".tex"; }
+     }
+     else {fname = fname + ".tex";}
+     write(fname,s);
+  }
+  else{return(s);}
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring r0 = 0,(x,y),dp;                // char = 0, polynomial ordering
+  texring("",r0);
+  //
+  ring r7 =7,(x(0..2)),ds;             // char = 7, local ordering
+  texring("",r7);
+  //
+  ring r1 = 0,(x1,x2,y1,y2),wp(1,2,3,4);
+  texring("",r1);
+  //
+  ring rr = real,(x),dp;               // real numbers
+  texring("",rr);
+  //
+  ring rC = complex,x,dp;              // complex coefficients
+  texring("",rC);
+  //
+  pause();
+
+  ring rabc =(0,t1,t2,t3),(x,y),dp;    // ring with parameters
+  texring("",rabc);
+  //
+  ring ralg = (7,a),(x1,x2),ds;        // algebraic extension
+  minpoly = a2-a+3;
+  texring("",ralg);
+  texring("",ralg,"mipo");
+  //
+  ring r49=(49,a),x,dp;                // Galois field
+  texring("",r49);
+  //
+  setring r0;                          // quotient ring
+  ideal i = x2-y3;
+  qring q = std(i);
+  texring("",q);
+  //
+  pause();
+
+  // ------------------ additional features -------------------
+  ring r9 =0,(x(0..9)),ds;
+  texring("",r9,1);
+  texring("",r9,"C","{","^G");
+  //
+  ring rxy = 0,(x(1..5),y(1..6)),ds;
+  intvec v = 5,6;
+  texring("",rxy,v);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc rmx(string fname)
+"USAGE:   rmx(fname); fname string
+RETURN:  nothing; removes the @code{.log} and @code{.aux} files associated to
+         the LaTeX file <fname>.@*
+NOTE:    If @code{fname} ends by @code{\".dvi\"} or @code{\".tex\"}, the
+         @code{.dvi} or @code{.tex} file will be deleted, too.
+EXAMPLE: example rmx; shows an example
+"
+{
+  int i,suffix= 1,0;
+  int retval;
+
+  if (size(fname))
+  {
+   while (fname[i]==">"){i++;}
+   fname = fname[i,size(fname)-i+1];
+   if (size(fname)>4)
+   { if (fname[size(fname)-3,4]==".tex") { suffix = 2;}
+     if (fname[size(fname)-3,4]==".dvi") { suffix = 1; }
+     if (suffix) { fname = fname[1,size(fname)-4]; }
+   }
+   retval = system("sh","rm " + fname + ".aux");
+   retval = system("sh","rm " + fname + ".log");
+   if (suffix==2) {retval = system("sh","/bin/rm -i " + fname +".tex");}
+   if (suffix>=1) {retval = system("sh","/bin/rm -i " + fname +".dvi");}
+  }
+  else
+  {" -- Need a filename ";
+    return();
+  }
+}
+example
+{ "EXAMPLE:"; echo =2;
+  ring r;
+  poly f = x+y+z;
+  opentex("exp001");              // defaulted latex2e document
+  texobj("exp001","A polynom",f);
+  closetex("exp001");
+  tex("exp001");
+  rmx("exp001");   // removes aux and log file of exp001
+  echo = 0;
+  pause("remaining files will be deleted after pressing <RETURN>");
+  echo = 2;
+  system("sh","rm exp001.*");
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc xdvi(string fname, list #)
+"USAGE:   xdvi(fname[,style]); fname,style = string
+RETURN:  nothing; displays dvi-file fname.dvi with previewer xdvi
+NOTE:    suffix .dvi may be omitted in fname
+         style captures the program that will be called instead of the default (xdvi)
+EXAMPLE: example xdvi; shows an example
+"
+{
+  int i=1;
+  int retval;
+  string default = "xdvi";
+
+  if (size(#)) {default = string(#[1]);}
+
+  if (size(fname))
+  {
+   while (fname[i]==">") {i++;}
+   fname = fname[i,size(fname)-i+1];
+
+   if (size(fname)>=4)
+   { if(fname[size(fname)-3,4]==".tex") {fname = fname[1,size(fname)-4];}}
+
+   "calling ",default, " for :",fname,newline;
+
+   if (default=="latex2e")
+   {
+     retval = system("sh","latex " +  fname +" &");
+   }
+   else
+   {
+     retval = system("sh",default + " " +  fname +" &");
+   }
+  }
+  else
+  { " -- Need a filename ";
+    return();
+  }
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  intmat m[3][4] = 9,2,4,5,2,5,-2,4,-6,10,-1,2,7;
+  opentex("exp001");
+  texobj("exp001","An intmat:  ",m);
+  closetex("exp001");
+  tex("exp001");
+  xdvi("exp001");
+  echo = 0;
+  pause("the created files will be deleted after pressing <RETURN>");
+  echo = 2;
+  system("sh","rm exp001.*");
+}
+///////////////////////////////////////////////////////////////////////////////
+
+static proc parsr(string s)                     // parse real
+{
+  string t;
+  if (s=="(      Inf)") { return("\\infty",3);}
+  if (s=="(     -Inf)") { return("\\-infty",6);}
+  if (s[8]=="-"){t ="-";}
+  if (s[9]<>"0"){t = t + s[9];}
+  if (s[10]<>"0" or s[9]<>"0"){t = t + s[10];}
+  if (size(t))
+  { if (t=="1") {return(s[1,6]+"\\cdot 10",21);}
+    if (size(t)>1) {return(s[1,6]+"\\cdot 10^{"+t+"}",21+2*size(t));}
+    else {return(s[1,6]+"\\cdot 10^"+t+")",23);}
+  }
+  else
+  {
+    return(s[2,5],12);
+  }
+}
+///////////////////////////////////////////////////////////////////////////////
+
+static proc parsg(string s)                  // parse Galois field
+{
+  string t;
+
+  if (s=="1") {return("1",5);}
+  if (short)
+  {
+    t =s[1];
+    if(size(s)>1) {return(t+"^{" + s[2,size(s)-1] + "}",3+2*(size(s)-1));}
+    else{return(t,5);}
+  }
+  else
+  {
+    return(parselong(s+"!"));
+  }
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc texpoly(string fname,def p,list #)
+"USAGE:   texpoly(fname,p); fname string, p poly
+RETURN:  if @code{fname=\"\"}: string, the polynomial p in LaTeX-typesetting;@*
+         otherwise: append this string to the file @code{<fname>}, and
+         return nothing.
+NOTE:    preceding \">>\" are deleted in @code{fname}, and suffix \".tex\"
+         (if not given) is added to @code{fname}.
+EXAMPLE: example texpoly; shows an example
+"
+{
+  def @r = basering;
+
+  poly f,monom;
+  ideal I;
+  number cfm;
+  string sign,cfmt,pt,s,bg,t,monomt,lnbreak;
+  string sep = newline;
+  int i,b,b2,n, msz,linesz, count,k;
+  int realT, parT, galT, complT;
+  int TW = defined(TeXwidth);
+
+  int C = 2 + defined(TeXdisplay);
+
+  string notvalid = "intvec intmat vector matrix module map";
+
+  if (typeof(p) == "int") { return(p);}
+  if (typeof(p)  == "ring" or typeof(p) == "qring")
+  { " -- Call  texring  instead "; return();}
+  if (find(notvalid,typeof(p)))
+  { " -- Call  texobj  instead "; return();}
+  if (typeof(p)  == "map")
+  { " -- Call  texmap  instead "; return();}
+  if (typeof(p)  == "proc")
+  { " -- Call  texmap  instead "; return();}
+  if (typeof(p)  == "link" or typeof(p) == "list" or typeof(p) == "resolution")
+  { ERROR(" // -- Object cannot translated into tex "); return();}
+
+  if (!(defined(TeXdisplay))){ lnbreak = "\\\\[2mm]" + newline;}
+  else { lnbreak = "\\\\" + newline;}
+
+
+  if (defined(TeXdisplay)) { bg = "& ";}
+  if (!TW) { int TeXwidth = -1; export TeXwidth;}
+
+// -- Type check
+
+ if (typeof(p)=="string")
+  { if(defined(`p`))
+    { pt = p + " = ";
+      p = `p`;
+    }
+  }
+  if (typeof(p)=="poly" or typeof(p)=="number") {I = p;}
+
+  if (typeof(p)=="ideal")
+  { I = p;
+    if(size(#)){ sep = #[1];}
+  }
+
+  if (I==0)
+  { if (!(defined(NoDollars))){return("$0$");}
+    else {return("0");}
+  }
+
+// -- Type check ende
+
+//---------------------
+
+//------- set flags: --------------------------------------------------------
+
+  if (size(#))
+  { if (typeof(#[1])=="int") { linesz = #[1];}
+ //   if (typeof(#[1])=="string") { linesz = #[1];}
+  }
+
+  parT = npars(@r);
+  realT = (charstr(@r)=="real");
+  complT = find(charstr(@r),"complex");   // 28.10.06
+  if (complT) {parT=0;}
+  i = find(charstr(@r),",");
+  if (i and !realT and !complT)
+  { t = charstr(@r)[1,i-1];
+    galT = (t <> string(char(@r)));  // the char is not the same as the ...
+  }
+  i = 0;
+
+//------- parse the polynomial
+  pt = bg;
+
+ for(k=1;k<=ncols(I);k++)
+ { i = 0; linesz = 0; count =0;
+   sign ="";
+   f = I[k];
+   if (f==0) { pt = pt + "0";}
+  while(f<>0)
+  { count++; msz = 0;
+
+// ------ tex the coefficient
+    monom = lead(f);
+    f = f - monom;
+    cfm = leadcoef(monom);
+    if (cfm*1 != 0) { monom = leadmonom(monom);} // to conform with integer
+    if (defined(TeXreplace)) { short =0;}  // this is essential //31.5.07
+    s = string(monom) + "!";              // add a terminating sign
+    cfmt = "";
+
+    cfmt = string(cfm);
+    if (size(cfmt)>1)                   // check if sign is < 0
+    { if (cfmt[2]=="-") { cfm = (-1) *cfm; sign = "-";}}
+    if (cfmt[1] == "-") { cfm = (-1) * cfm; sign = "-";}
+    if  (cfm!=1 or monom==1) {cfmt = string(cfm);}
+    else {cfmt="";}
+
+    if (defined(TeXwidth) and TeXwidth > 0 and TeXwidth <9 and count> TeXwidth)
+    { pt = pt + sign + "\\ldots"; break;}
+   // ----------------------------------------  linesz ??
+
+    if (size(cfmt))                            // parse the coefficient
+    {
+     monomt = cfmt;                   // (already a good choice for integers)
+     msz = 3*size(cfmt);
+
+     if(realT) { monomt,msz = parsr(cfmt);}
+     if (galT) { monomt,msz = parsg(cfmt);}
+     b = find(cfmt,"/(");                     // look if fraction  // 31.5.07
+     b2 = find(cfmt,"/");
+     // if (b) {b++;}                         // 31.5.07
+     n = size(cfmt);
+     if (!(parT) and  !(realT) and !(galT))
+     { if( !(b2) or defined(TeXnofrac))
+       { monomt = cfmt; msz = 3*size(monomt);}
+       else
+       { monomt = "\\frac{" + cfmt[1,b2-1] + "}{" + cfmt[b2+1,n-b2] + "}";
+          if (n-2*b2>0) {msz = C*(n-b2);}
+          else {msz = C*b2;}
+       }
+     }
+     if (parT and !(galT))
+     { monomt,msz = parsp(cfmt,b);}
+    }
+    if (monom!=1 and monomt!="" and parT) // 21.4.10
+    { monomt = monomt+"\\cdot ";} // at least a blank is needed for TeXreplace
+
+// -- now parse the monom
+    if (monom <> 1)
+    { i = 1;
+      if(short)
+      { while(s[i]<>"!")
+        { monomt = monomt + s[i]; i++;
+          b = i;
+          msz = msz + 3; // it was a single lettered var
+          while(s[i]!="!" and s[i]>="0" and s[i]<="9"){i++;}
+          if (i-b)
+          { monomt = monomt + "^{" + s[b,i-b] + "}";
+            msz = msz + 2*(i-b);
+          }
+        }
+      }
+      else          //  not short
+      { t,i = parselong(s);
+        monomt = monomt + t;
+        msz = msz + i;
+      }
+    }
+
+   msz = msz + 6*size(sign);   // Wieso mal 6 ??
+//  string(msz) + "  ," + string(linesz) + "  " + string(cfm*monom);
+
+   if (TeXwidth > 10 and (linesz + msz > 3*TeXwidth) and linesz)
+   { pt = pt + lnbreak + bg;
+     linesz = msz;
+   }
+   else { linesz = linesz + msz; }  // 3 for sign
+    pt = pt + sign + monomt;
+   sign = "+";
+   monomt = "";
+  }
+
+  if (k<ncols(I)){ pt = pt + sep;}
+ }
+
+  if (TeXwidth==0 and typeof(p)=="poly"){ pt = pt + "= 0";}
+  if (!TW) { kill TeXwidth;}    // kill Latex::
+  if (not(defined(NoDollars))) { pt = "$"+pt+"$";}
+
+  if (size(fname))
+  { i=1;
+    while (fname[i]==">"){i++;}
+    fname = fname[i,size(fname)-i+1];
+
+    if (size(fname)>=4)         // check if filename is ending with ".tex"
+    { if(fname[size(fname)-3,4]!=".tex") {fname = fname +".tex"; }
+    }
+    else {fname = fname + ".tex";}
+    write(fname,pt);
+   }
+  else {return(pt);}
+}
+example
+{ "EXAMPLE:"; echo =2;
+  ring r0=0,(x,y,z),dp;
+  poly f = -1x^2 + 2;
+  texpoly("",f);
+  ring rr= real,(x,y,z),dp;
+  texpoly("",2x2y23z);
+  ring r7= 7,(x,y,z),dp;
+  poly f = 2x2y23z;
+  texpoly("",f);
+  ring rab =(0,a,b),(x,y,z),dp;
+  poly f = (-2a2 +b3 -2)/a * x2y4z5 + (a2+1)*x + a+1;
+  f;
+  texpoly("",f);
+  texpoly("",1/(a2+2)*x+2/b);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+static proc parsp(string cfmt, int b)
+{ string mt, nom,denom;
+  int fl1,fl2,sz1,sz2,msz;
+
+  if (!(b))
+  { mt,fl1 = parst(cfmt,0); msz = size(cfmt)-2;
+    if (fl1) { mt = "(" + mt + ")"; msz = msz +1; }
+  }
+  else
+  { nom,fl1 = parst(cfmt[1,b-1],1);
+    denom,fl2 = parst(cfmt[b+1,size(cfmt)-b],1);
+    if (defined(TeXnofrac))
+    { if(fl1) { nom = "(" + nom + ")"; sz1++;}
+      if(fl2) {denom = "(" + denom + ")"; sz2++;}
+      mt = "(" + nom+ "/"+ denom+ ")"; msz = sz1+sz2 +1;   //31.5.07
+    }
+    else
+    { mt = "\\frac{" + nom + "}{" + denom + "}";
+      if (sz1-sz2) { msz = 5*sz1;}
+      else {msz = 5*sz2;}
+    }
+   }
+  return(mt,msz);
+}
+example
+{"EXAMPLE:"; echo =2;
+  ring r=(0,a,b),x,dp;
+  int i;
+  poly f = (a2b12 + 23a2 -b13-1)/(a2+2b -1);
+  f;
+  string s;
+  s= string(f);
+  i = find(s,")/(");
+  parsp(s,i);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+static proc parst(string s,int sec)                // parse parameter
+// sec parameter to see if in parsp a fraction follows
+{
+  int i,j =1,-1;
+  int b,k,jj,mz,in;                         // begin and end, in for index
+  int saveshort=short;
+  string t,c,vn,nom,denom,sg;
+
+  if (s[1]=="(") { s = s[2,size(s)-2]; }
+  s = s + "!";
+
+  if (short)
+  { j = 0;  // 31.5.07
+    while(s[i]<>"!")
+    { b=i; if (s[i]=="+" or s[i]=="-") {j++;}  // 31.5.07
+      while(s[i]>="0" and s[i]<="9" or (s[i]=="+" or s[i]=="-") and s[i]!="!")
+      {i++;}     // scan the number
+        t =s[b,i-b];
+    //  if (t=="-1" and s[i]!="!" and s[i]!="-" and s[i]!="+"){t = "-";}
+      if (t=="-1" and (s[i]<="0" or s[i]>="9") and s[i]!= "/" and s[i]!="!")
+      {t = "-";}
+      if (s[i]=="/")
+      { i++;
+        sg = "";
+        if (t[1]=="+" or t[1]=="-")
+        { nom = t[2,size(t)-1];
+          sg = t[1];
+        }
+        else { nom = t;}
+        b =i;
+        while(s[i]>="0" and s[i]<="9") {i++;}
+        denom = s[b,i-b];
+        if (!(sec) and (!(defined(TeXaligned))))
+        { t = sg + "\\frac{" + nom + "}{" + denom + "}";}
+        else
+        { t = sg + "(" + nom + "/" + denom + ")";
+        }
+      }
+      c = c + t;
+      if(s[i]!="!"){c = c + s[i]; i++;}      // the parameter
+      b=i;
+      while(s[i]>="0" and s[i]<="9")
+      {i++;}  //the exponent
+      if(i-b){ c = c + "^{" + s[b,i-b]+"}";}
+     }
+   }
+   else                         // if not short ....
+   { while (s[i] <> "!")
+   { b=i; j++; in=0;         // 4.10.10
+       while(s[i]=="-" or s[i]=="+" or (s[i]>="0" and s[i]<="9")){i++;}
+       t = s[b,i-b];
+       if (t=="-1" and s[i]=="*" ) {t="-";}
+       if (s[i]=="/")
+       { i++;
+         sg = "";
+         if (t[1]=="+" or t[1]=="-")
+         { nom = t[2,size(t)-1];
+           sg = t[1];
+         }
+         else { nom = t;}
+         b =i;
+         while(s[i]>="0" and s[i]<="9") {i++;}
+         denom = s[b,i-b];
+         if (!(sec) and (!(defined(TeXaligned))))
+         { t = sg + "\\frac{" + nom + "}{" + denom + "}";}
+         else
+         { t = sg + "(" + nom + "/" + denom + ")";
+         }
+       }
+       c = c+t; t="";
+       if (s[i]=="*"){i++;}
+       b=i;
+      //  string(s[1,b]);
+
+       while(s[i]!="+" and s[i]!="-" and s[i]!="!")  //pass a monom
+       { // start with letters
+        // alternativ:
+        //in=0;         // 4.10.10
+        while((s[i]>="a" and s[i]<="z") or (s[i]>="A" and s[i]<="Z")){i++;}
+        k = i-b;
+        vn = s[b,k];
+        if (defined(TeXreplace))
+        { for (jj=1; jj<= size(TeXreplace);jj++)
+         { if (vn == TeXreplace[jj][1])
+           {vn = TeXreplace[jj][2]; k=1;
+             if (s[i]=="*") {vn = vn + " ";}
+            break;} //suppose replacing by a single sign
+         }
+        }
+        t = t + vn;
+        mz = mz + 10*k;
+        if (s[i]=="_"  or s[i]=="(") {in++; i++;}    // the index is coming
+        b = i;
+        while(s[i]>="0" and s[i]<="9"){ i++;}
+        k = i-b;
+        if (k and in<=1) {t = t + "_{";in++;} //and k  i.e. there was an index
+        if (k){ t = t +s[b,k];}
+        if(s[i]==")") {i++;}
+        if(k and s[i]!="(" and s[i]!="_"){ t = t + "}";} // index closed
+        if(s[i]=="(" or s[i]=="_") {i++; t = t + ",";in++;}
+        if (s[i]=="^")
+        { i++; b = i;
+          while(s[i]>="0" and s[i]<="9"){ i++;} // for neg. expon.
+          if (b-i) { t = t + "^{" + s[b,i-b] + "}";}
+        }
+        if (i-b > k) { mz = mz + 5*(i-b);}
+        else {mz = mz + 5*k;}
+        if (s[i]=="*"){i++;in=0;}
+        b=i;
+       }
+       c =c+t;
+      }
+   }
+   short = saveshort;
+   return(c,j);
+}
+example
+{ "EXAMPLE:"; echo =2;
+  ring r=(0,a,b),x,dp;
+  poly f = (a2b12 + 23a2 -b13-1);
+  f;
+  parst(string(f),0);
+
+  f =(-a +4b2 -2);
+  f;
+  parst(string(f),0);
+
+  f = a23;
+  f;
+  parst(string(f),0);
+  f = 2a12b3 -4ab15 +2a4b12 -2;
+  short =0;
+  f;
+  parst(string(f),0);
+   ring r2=(0,a1,b1),x,dp;
+  poly f = 2*a1^12*b1^3 -4*a1*b1^15 +2*a1^4*b1^12 -2;
+  f;
+  parst(string(f),0);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+static proc parselong(string s)
+{
+  int i,j,k,b,mz,in;    // in is a counter for indices
+  string t,vn;              // varname
+
+  i = 1;
+  while (s[i] <> "!")
+  { b=i;
+
+  // -- scan now the letter ...
+  //  while(s[i]!="!" and )
+
+// alternativ:
+ while((s[i]>="a" and s[i]<="z") or (s[i]>="A" and s[i]<="Z"))
+ { i++;}
+ // s[i]; i;
+   k = i-b;
+   vn = s[b,k];
+
+   if (defined(TeXreplace))
+   { for (j=1; j<= size(TeXreplace);j++)
+     { if (vn == TeXreplace[j][1])
+       {vn = TeXreplace[j][2]; k=1;
+        if (s[i]=="*") {vn = vn + " ";}
+         break;} //suppose replacing by a single sign
+     }
+   }
+   t = t + vn;
+   mz = mz + 10*k;
+   if (s[i]=="_"  or s[i]=="(") { in++;i++;}    // the index is coming
+   b = i;
+   while(s[i]>="0" and s[i]<="9" or s[i]=="-"){ i++;}  // "-" for neg indices
+   j = i-b;
+   // if (j){ t = t + "_{" +s[b,j] + "}";}  // formely
+   if (j and in<=1) {t = t + "_{";in++;}  // and j  i.e. there was an index
+   if (j){ t = t  +s[b,j];}
+   if(s[i]==")") {i++;}
+   if(j and s[i]!="(" and s[i]!="_"){ t = t + "}";} // index closed
+   if(s[i]=="(" or s[i]=="_") {i++; t = t + ",";in++;}
+   if (s[i]=="^")
+   { i++; b = i;
+     while(s[i]>="0" and s[i]<="9" or s[i]=="-")
+     { i++;}  // for neg. expon.
+     if (b-i) { t = t + "^{" + s[b,i-b] + "}";}
+   }
+   if (i-b > j) { mz = mz + 5*(i-b);}
+   else {mz = mz + 5*j;}
+   if (s[i]=="*"){i++;in=0;}
+  }
+  return(t,mz);
+}
+example
+{ "EXAMPLE:"; echo =2;
+  ring r =(49,a),x,dp;
+  number f = a13;
+  parsg(string(f));
+  list TeXreplace; export TeXreplace;
+  TeXreplace[1] = list("b","\\beta");
+  TeXreplace[2] = list("a","\\alpha");
+  TeXreplace[3] = list("c","\\gamma");
+  parselong(string(f)+"!");
+}
+///////////////////////////////////////////////////////////////////////////////
+
+/* obsolete
+static proc tktex (def d)
+{
+ // calls appropriate proc from latex lib
+
+ string typeofd =typeof(d);
+ if (typeofd=="int" or typeofd=="string" or typeofd=="resolution" or typeofd=="map" or typeofd =="list"){ return(d);}
+
+ if (typeofd=="intvec" or typeofd == "intmat" or typeofd =="vector" or
+     typeofd=="matrix" or typeofd == "module")   { return(texobj("",d));}
+ if (typeofd=="ring" or typeofd=="qring") { return(texring("",d));}
+ if (typeofd =="ideal") { return(texobj("",d));}
+ if (typeofd=="number" or typeofd=="poly" or typeofd=="ideal")
+                                                 { return(texpoly("",d));}
+ if (typeofd=="link") {return(d);}
+
+}
+*/
+/////////////////////////////  PART0 //////////////////////////////////////////
+
+static proc part0(string fname)
+{
+ int texdemopart =0;
+ export texdemopart;
+
+
+// Singular script for generating tldemo.tex
+
+ string nl = newline;
+ string nl2 = newline + newline;
+ string lb = "\\\\";
+ string bv = "\\begin{verbatim}" + newline ;
+ string ev = newline + "\\end{verbatim}" +newline ;
+
+// "generating part0 of " + fname  + nl;
+
+ opentex(fname);
+
+write(fname,"\\newcommand{\\Line}{{}\\par\\noindent\\rule{\\textwidth}{0.25mm}\\\\[1mm]}");
+
+   write(fname,"\\centerline{\\textbf{\\large Demo file for latex.lib }}");
+   //  write(fname,"\\centerline{\\textbf{\\large Christian Gorzel }}");
+   write(fname,"\\centerline{07/10/2010}");
+   write(fname,"\\vspace{1cm}");
+
+//--
+
+ write(fname,"","\\section{Introduction}");
+ write(fname,"The procedures in \\verb|latex.lib| translate the output of
+ {\\sc Singular} into \\LaTeX \\ text.
+ This document illustrates the functionality of the library."+"\\\\" +  nl);
+ write(fname,"\\begin{tabular}{ll}" + nl +
+"LIBRARY: {\\tt latex.lib} &   PROCEDURES FOR TYPESETTING SINGULAR" +
+"\\\\" +  nl +
+" & OBJECTS IN LATEX2E"+
+"\\\\" +  nl +
+"{\\tt closetex(fnm);} & writes closing line for \\LaTeX-document"+
+"\\\\" +  nl +
+"{\\tt  opentex(fnm);} & writes header for \\LaTeX-file fnm"+
+"\\\\" +  nl +
+"{\\tt  tex(fnm);} & calls \\LaTeX2e for file fnm"+
+"\\\\" +  nl +
+"{\\tt  texdemo([n]);} & produces a file explaining the features of this lib"+
+"\\\\" +  nl +
+"{\\tt  texfactorize(fnm,f);} & creates string in \\LaTeX-format for
+factors of polynomial f"+ "\\\\" +  nl +
+"{\\tt  texmap(fnm,m,r1,r2);} & creates string in \\LaTeX-format for
+map m:r1$\\rightarrow$r2"+ "\\\\" +  nl +
+"{\\tt  texname(fnm,s);} &      creates string in \\LaTeX-format for
+identifier"+ "\\\\" +  nl +
+"{\\tt  texobj(l);} &           creates string in \\LaTeX-format for
+any (basic) type"+ "\\\\" +  nl +
+"{\\tt  texpoly(f,n[,l]);} &    creates string in \\LaTeX-format for poly"+
+"\\\\" +  nl +
+"{\\tt  texproc(fnm,p);} &      creates string in \\LaTeX-format of
+text from proc p"+ "\\\\" +  nl +
+"{\\tt  texring(fnm,r[,l]);} &  creates string in \\LaTeX-format for
+ring/qring"+ "\\\\" +  nl +
+"{\\tt  rmx(s);} &              removes .aux and .log files of \\LaTeX-files"+
+"\\\\" +  nl +
+"{\\tt  xdvi(s);} &             calls xdvi for dvi-files"+
+"\\\\" +  nl +
+" \\end{tabular} " + nl2 + "\\vspace{0.2cm}" + nl2 +
+"(parameters in square brackets {\\tt [ ]} are optional)"+
+"\\\\" +  nl2 + "\\vspace{0.2cm}" + nl2 +
+"The global variables {\\tt TeXwidth}, {\\tt TeXnofrac}, {\\tt
+ TeXbrack}, {\\tt TeXproj}, {\\tt TeXaligned}, {\\tt TeXreplace}, {\\tt
+ NoDollars} are used to control the typesetting: "
+);
+
+write(fname,
+bv +
+"
+  TeXwidth   (int) -1, 0, 1..9, >9:  controls breaking of long polynomials
+  TeXnofrac  (int) flag:  write 1/2 instead of \\frac{1}{2}
+  TeXbrack   (string) \"{\", \"(\", \"<\", \"|\", empty string:
+                            controls brackets around ideals and matrices
+  TeXproj    (int) flag:  write \":\" instead of \",\" in vectors
+  TeXaligned (int) flag:  write mappings (and ideals) aligned
+  TeXreplace (list) list entries = 2 strings:  replacing symbols
+  NoDollars  (int) flag:  suppresses surrounding $ signs
+
+" +
+ev);
+write(fname,"Notice that none of these global variables are defined when
+loading \\verb|latex.lib|. A flag variable is set as soon as it is defined.");
+
+
+//% The procs and
+//% the global variables
+
+//----------------------- opentex -----------------------------
+   write(fname,"","\\section{Opening a \\LaTeX\\ file}");
+   write(fname,"","In order to create a \\LaTeX\\ document and write a standard
+header into it, use the following command."+ nl +
+bv+
+"> string fname = \"" + fname + "\";" + nl +
+"> texopen(fname);" +
+ev);
+
+write(fname,"The variable \\verb|fname| is always the first argument when
+calling one of the procedures of \\verb|latex.lib|. If this string is the
+empty string, then the output in not written into a file but displayed on
+the screen.");
+
+ //% opentex, defaulted to latex, possibly extension are ... and
+ //% ``own''
+
+
+pagewidth = 65;
+int TeXwidth = 100; export TeXwidth;
+// "part 0 generated " + nl;
+} //part0
+
+
+/////////////////////////////  PART1 //////////////////////////////////////////
+
+static proc part1(string fname)
+{
+
+  int st = defined(texdemopart);
+  string nl = newline;
+  string nl2 = newline + newline;
+  string lb = "\\\\";
+  string bv = "\\begin{verbatim}" + newline ;
+  string ev = newline + "\\end{verbatim}" + newline ;
+
+  if (not(st) or texdemopart>=1)
+  { print(" Call part0 first");
+    return();
+  }
+  else { texdemopart=1; }
+
+//"Continuing part1 of " + fname + nl;
+
+write(fname,"","\\section{Rings, polynomials and ideals}","");
+
+// -1a------ a ring in char 0, short varnames and poly. ordering ----------
+write(fname,
+" A ring in characteristic 0 with short names of variables and polynomial
+ordering." +nl);
+ ring r0=0,(x,y,z),dp;
+ poly g=-x2y+2y13z+1;
+write(fname,
+bv +
+"> ring r0=0,(x,y,z),dp;" +nl+
+"> texring(fname,r0);" +
+ev);
+  texring(fname,r0);
+  write(fname,nl2);
+write(fname,
+bv +
+"> poly g=-x2y+2y13z+1;  g;" + nl +
+"> texpoly(fname,g);" +
+ev);
+  texpoly(fname,g);
+  write(fname,"\\\\"+nl);
+
+// write(fname,"\\Line");
+
+// -1b------ still in the same ring, a polynomial with rational coefs --------
+write(fname,
+""," A polynomial with rational coefficients." +nl);
+write(fname,
+bv +
+"> texpoly(fname,g/280);" +
+ev
+);
+  texpoly(fname,g/280);
+  kill r0;
+
+write(fname,"\\Line","%-----------------------------------------------------");
+// -2-------- a ring in char 7, indexed varnames and series ordering ----------
+write(fname,
+" A ring in characteristic 7 with indexed names of variables and local
+ordering.","");
+ ring r1=7,(x1,x2,x3,x4),Ds;
+ poly g=-2*x1+x4-1;
+write(fname,
+bv +
+"> ring r1=7,(x1,x2,x3,x4),Ds;" +nl +
+"> texring(fname,r1);" +
+ev);
+texring(fname,r1);
+
+
+write(fname, bv +
+"> poly g=-2*x1+x4-1;  g;" +nl +
+"> texpoly(fname,g);" +
+ev);
+
+  texpoly(fname,g);
+
+write(fname,"\\Line","%-----------------------------------------------------");
+
+// -3-------- a ring in char 0, indexed varnames and local ordering ----------
+write(fname,
+" A ring in characteristic 0 with indexed names of variables and local
+ordering.
+" +nl);
+ ring r2=0,(x(1..5),y(1..2)),(ds(5),ls(2));
+ poly g=-y(1)^3*x(5) +y(1)*x(2);
+write(fname,
+bv +
+"> ring r2=0,(x(1..5),y(1..2)),(ds(5),ls(2));" + nl +
+"> texring(fname,r2);" +
+ev);
+  texring(fname,r2);
+
+write(fname,
+bv +
+"> poly g=-y(1)^3*x(5)+y(1)*x(2);  g;" +nl+
+ string(g) + nl +
+"> texpoly(fname,g);"  +
+ev
+);
+  texpoly(fname,g);
+
+write(fname,"\\Line","%-----------------------------------------------------");
+
+// -4-------- a ring in char 0, indexed varnames and weighted ordering ------
+write(fname,
+" A ring in characteristic 0 with indexed names of variables and weighted
+ ordering." +nl);
+ ring r3=0,(x_1,x_2,x_3),wp(3,2,1);
+ poly g=-x_1*x_2+2*x_2*x_3+x_1*x_3;
+write(fname,
+bv +
+"> ring r3=0,(x_1,x_2,x_3),wp(3,2,1);" +nl+
+"> texring(fname,r3);" +
+ev);
+  texring(fname,r3);
+write(fname,
+bv +
+"> poly g=-x_1*x_2+2*x_2*x_3+x_1*x_3;  g;" +nl+
+  string(g) + nl +
+"> texpoly(fname,g);"  +
+ev
+);
+texpoly(fname,g);
+
+write(fname,"\\Line","%-----------------------------------------------------");
+
+// -5-------- a ring with real coeff and matrix ordering -------------------
+write(fname,
+" A ring with real coefficients and matrix ordering.
+" +nl);
+ ring rr=real,(x,y),M(1,2,3,4);
+ poly g =-1.2e-10*x2+y+1;
+write(fname,
+bv +
+"> ring rr=real,(x,y),M(1,2,3,4);"+nl+
+"> texring(fname,rr);"+
+ev);
+  texring(fname,rr);
+
+write(fname,
+bv +
+"> poly g=-1.2e-10*x2+y+1;  g;"+nl+
+  string(g) + nl +
+"> texpoly(fname,g);" +
+ev);
+  texpoly(fname,g);
+
+write(fname,"\\Line","%-----------------------------------------------------");
+
+// -6a-------- a ring in char 0, and indexed parameters --------- ----------
+write(fname,
+" A ring in characteristic 0 with parameters.
+" +nl);
+ ring r0t=(0,s,t),(x,y),dp;
+ poly g=8*(-s+2t)/(st+t3)*x+t2*x-1;
+write(fname,
+bv +
+"> ring r0t=(0,s,t),(x,y),dp;" +nl +
+"> texring(fname,r0t);" +
+ev);
+ texring(fname,r0t);
+write(fname,
+bv +
+"> poly g=8*(-s+2t)/(st+t3)*x+t2*x-1;  g;"+nl+
+  string(g) +nl +
+"> texpoly(fname,g);" +
+ev);
+  texpoly(fname,g);
+write(fname,"\\Line","%-----------------------------------------------------");
+write(fname,"\\newpage");
+
+// -6b------- a ring in char 11003, and indexed parameters --------- ----------
+write(fname,
+" A ring in characteristic 11 and indexed parameters.
+" +nl);
+ ring rt=(11003,t1,t2,t3),(X,Y),dp;
+ poly g=8*(-t1+t2)/(t1+t3)*X+t2*Y-1;
+write(fname,
+bv +
+"> ring rt=(11003,t1,t2,t3),(X,Y),dp;" +nl +
+"> texring(fname,rt);" +
+ev);
+  texring(fname,rt);
+
+write(fname,
+bv +
+"> poly g=8*(-t1+t2)/(t1+t3)*X+t2*Y-1;  g;" + nl+
+ string(g) +nl +
+"> texpoly(fname,g);" +
+ev);
+  texpoly(fname,g);
+
+write(fname,"\\Line","%-----------------------------------------------------");
+
+// -7-------- a ring over an algebraic extension in char 7 ---------------
+write(fname," A ring over an algebraic extension in char 7.");
+
+  ring ralg = (7,a),x,dp;
+  minpoly = a2-a+3;
+  poly g = -(2a13+a)*x2+a2*x-a+1;
+
+write(fname,
+bv +
+"> ring ralg=(7,a),x,dp;" +nl +
+"> minpoly=a2-a+3;" +nl +
+"> texring(fname,ralg);" +
+ev);
+ texring(fname,ralg);
+
+write(fname,
+bv +
+"> poly g=-(2a13+a)*x2+a2*x-a+1;  g;"+nl+
+ string(g) +nl +
+"> texpoly(fname,g);" +
+ev
+);
+  texpoly(fname,g);
+
+write(fname,"\\Line","%-----------------------------------------------------");
+
+// -8-------- the same ring a in 7 ralg, defined with gftables -- F_49 -------
+write(fname,
+" A ring defined with \\verb|gftables|, the same as \\verb|ralg| before, but
+with primitive element in the Galois field $\\F_{49}$." +nl);
+ ring r49 =(49,a),x,dp;
+ poly g=-(2a13+a)*x2+a2*x-a+1;
+write(fname,
+bv +
+"> ring r49 =(49,a),x,dp;" +nl+
+"> texring(fname,r49);" +
+ev);
+ texring(fname,r49);
+
+write(fname,
+bv +
+"> poly g=-(2a13+a)*x2+a2*x-a+1;  g;" +nl+
+ string(g) +nl +
+"> texpoly(fname,g);" +
+ev);
+  texpoly(fname,g);
+
+write(fname,"\\Line","%-----------------------------------------------------");
+
+// -9-------- a ring over the Gaussian numbers  ----------
+write(fname,
+" A ring over the Gaussian numbers.
+" +nl);
+ ring ri=(0,i),(x,y,z),ls;
+ minpoly=i2+1;
+ poly g=-(i+1)*x+2i2y2+i+x;
+write(fname,
+bv +
+"> ring ri=(0,i),(x,y,z),ls;" +nl +
+"> minpoly=i2+1;" +nl +
+"> texring(fname,ri);" +
+ev);
+ texring(fname,ri);
+
+write(fname,
+bv +
+"> poly g=-(i+1)*x+2i2y2+i+x;  g;" +nl+
+ string(g) +nl +
+"> texpoly(fname,g);" +
+ev
+);
+  texpoly(fname,g);
+
+write(fname,"\\Line","%-----------------------------------------------------");
+
+// -10--------- a quotient ring performed from  ----------
+write(fname," A quotient ring performed of \\verb|r0| by an ideal.");
+ ring r0=0,(x,y,z),dp;
+ ideal I = x2-y, y+z2, xy;
+ I = std(I);
+string sI = string(I);
+ qring qr = I;
+write(fname,
+bv +
+"> setring r0;
+> ideal I=x2-y,y+z2, xy;
+> I=std(I);
+> string(I);" + nl +
+string(sI) + nl +
+"> qring qr=I;
+> texring(fname,qr);" +
+ev
+);
+texring(fname,qr);
+
+//write(fname,"\\Line","%-----------------------------------------------------");
+
+// ------------------------- Features for rings
+
+write(fname,"","\\subsection{Features for rings}");
+
+write(fname,
+"In many cases it might be convenient to change the standard typesetting
+of rings. This can be done by passing additional arguments to \\verb|texring|."
++nl);
+
+// changing the brackets
+
+write(fname,nl,"In order to change the displayed brackets one has to give
+the desired ones as additional argument (accepted brackets are: \\verb|\"\{\"|,
+\\verb|\"\{\{\"|,\\verb|\"[\"|,\\verb|\"[[\"|,\\verb|\"<\"|,\\verb|\"<<\"|).");
+
+write(fname,
+bv +
+"> texring(fname,rr,\"{{\");" +
+ev
+);
+
+texring(fname,rr,"{{");
+
+write(fname,
+bv +
+"> texring(fname,r2,\"[\");" +
+ev
+);
+
+texring(fname,r2,"[");
+
+write(fname,nl+"\\vspace{0.2cm}" + nl2);
+
+write(fname,"The brackets around the ideal in a quotient ring can be
+changed by setting  the global variable \\verb|TeXbrack| (see section
+{\\tt Ideals}).",nl);
+
+write(fname,
+bv +
+"> string TeXbrack = \"<\";" +nl +
+"> texring(fname,qr);" +
+ev
+);
+
+  string TeXbrack = "<"; export TeXbrack;
+  texring(fname,qr);
+  kill TeXbrack;
+
+write(fname,
+bv +
+"> kill TeXbrack;" +
+ev);
+
+//write(fname,"\\Line","%-----------------------------------------------------");
+
+// changing the ground field
+// -------------------------------------------------
+
+write(fname,
+"It is possible to display a ground field different from the
+actual one by passing any letter in \\LaTeX \\ notation as additional
+argument.  Predefined values are \\verb|\"\\\\C\"|, \\verb|\"\\\\R\"|,
+\\verb|\"k\"|, \\verb|\"K\"| and \\verb|\"R\"|."+nl+
+"If for example a ground field of characteristic 0 should be written as
+$\\C$ instead of $\\Q$ use this as additional argument.",nl);
+
+write(fname,
+bv +
+"> texring(fname,r3,\"\\\\C\");" +
+ev);
+
+texring(fname,r3,"\\C");
+write(fname,nl+ "\\vspace{0.2cm}" + nl2);
+
+write(fname,"The values \\verb|\"k\"|, \\verb|\"K\"|, \\verb|\"R\"| play a
+ special role when the ground field is an algebraic extension. In this case
+the parameters will be omitted.");
+
+write(fname,
+bv +
+"> texring(fname,ralg,\"k\");" +
+ev
+);
+
+texring(fname, ralg,"k");
+write(fname,nl+"\\vspace{0.2cm}" + nl2);
+
+write(fname,"If an algebraic extension should be displayed together with
+its minimal polynomial the optional parameter \\verb|mipo| has to be used.");
+
+write(fname,
+bv +
+"> texring(fname,ralg,\"mipo\");" +
+ev
+);
+
+texring(fname, ralg,"mipo");
+write(fname,"\\Line","%-----------------------------------------------------");
+
+// displaying only certain vars
+
+write(fname,"By default all variables of a ring will be displayed. It is
+possible to print only certain variables with $\\ldots$ between
+them. The positions of the variables which should be displayed have to be
+passed to \\verb|texring| as an \\verb|intvec|.");
+
+write(fname,
+bv +
+"> intvec v=5,6;
+> texring(fname,r2,v);" +
+ev
+);
+
+  intvec v = 5,6;
+  texring(fname,r2,v);
+  kill v;
+
+write(fname,
+bv +
+"> kill v;" +
+ev
+);
+
+write(fname,nl+ "\\vspace{0.2cm}" + nl2);
+
+write(fname,"The first and the last variable will always be printed.
+In order to print only these it is sufficient to give a 1 as third argument.");
+
+write(fname,
+bv +
+"> texring(fname,r1,1);" +
+ev
+);
+texring(fname,r1,1);
+
+write(fname,"\\Line","%-----------------------------------------------------");
+
+// invariant ring under a group action
+
+write(fname,"If you want for example to display a ring as the invariant ring
+under a group, additional information starting with \\verb|^| may be added.");
+
+write(fname,
+bv +
+"> texring(fname,r0,\"^G\");" +
+ev
+);
+
+texring(fname, r0,"^G");
+write(fname,"\\Line","%-----------------------------------------------------");
+
+// passing several optional arguments at once
+
+write(fname,"It is also possible to pass several of the arguments described
+above at once (in any order).");
+
+
+write(fname,
+bv +
+"> texring(fname,r3,\"\\\\R\",\"{{\",\"^G\");" +
+ev
+);
+
+texring(fname, r3,"\\R","{{","^G");
+//"end part 1" + nl;
+}
+
+
+/////////////////////////////  PART2 //////////////////////////////////////////
+
+
+static proc part2(string fname)
+{
+
+  int st = defined(texdemopart);
+  string nl = newline;
+  string nl2 = newline + newline;
+  string lb = "\\\\";
+  string bv = "\\begin{verbatim}" + newline ;
+  string ev = newline + "\\end{verbatim}" + newline ;
+//  string ev = "\\end{verbatim}" ;
+
+  if (not(st) or texdemopart>=2)
+  { print(" Call part1 first");
+    return();
+  }
+  else { texdemopart=2; }
+
+// "Continuing Part2 of " + fname + nl;
+
+//-------------------- texfactorize ------------------------------
+write(fname,"","\\subsection{Factorized polynomials}");
+
+write(fname,"The command \\verb|texfactorize| calls internally the
+{\\sc Singular} command \\verb|factorize| and returns the product of the
+irreducible factors. Note that, at the moment, it is not possible to pass
+any optional arguments for \\verb|factorize| through \\verb|texfactorize|.");
+
+  ring r0=0,(x,y,z),dp;
+  poly h=(x+1+y)^2*x3y*(2x-2y)*y12;
+
+write(fname,
+bv +
+"> setring r0;
+> poly h=(x+1+y)^2*x3y*(2x-2y)*y12;   h;" +nl+
+ string(h) + nl +
+"> texfactorize(fname,h);" +
+ev);
+texfactorize(fname,h);
+
+//  setring ralg;
+  ring ralg = (7,a),x,dp;
+  minpoly = a2-a+3;
+  poly h = (a24x5+x3)*a2x6*(x+1)^2;
+
+write(fname,
+bv +
+"> setring ralg;
+> poly h=(a24x5+x3)*a2x6*(x+1)^2;  h;"+ nl +
+ string(h) + nl +
+"> texfactorize(fname,h);"+
+ev);
+texfactorize(fname,h);
+
+//--------------------- features for polynomials -----------------
+write(fname,"","\\subsection{Features for polynomials}");
+
+// TeXreplace
+// ---------------------------------------------
+write(fname,"By setting the global variable \\verb|TeXreplace| it is possible
+to define rules for replacing strings or variable names.
+\\verb|TeXreplace| has to be a list of twoelemented lists where the first
+entry is the text which should be replaced by the second entry.
+This may be applied to replace names of variables, but is also used
+when calling \\verb|texname| or \\verb|texmap|. Note that it
+is necessary to write a double backslash \\verb|\\\\\| at the beginning of
+a \\TeX \\ symbol.","");
+
+write(fname,"Let us denote the primitive element of an algebraic extension
+by $\\xi$.");
+
+list TeXreplace; export TeXreplace;
+TeXreplace[1] = list("a","\\xi");
+// setring r49;
+  ring r49 =(49,a),x,dp;
+  poly g=-(2a13 +a)*x2+a2*x-a+1;
+write(fname,
+bv +
+"> list TeXreplace;" +nl +
+"> TeXreplace[1]=list(\"a\",\"\\\\xi\");" +nl+
+"> setring r49;" +nl+
+"> texpoly(fname,g);"+
+ev);
+
+texpoly(fname,g);
+
+write(fname,nl+ "\\vspace{0.2cm}" + nl2);
+write(fname,"Now let us write $\\lambda$ and $\\mu$ for deformation
+parameters.");
+TeXreplace[2]= list("s","\\lambda");
+TeXreplace[3]= list("t","\\mu");
+// setring(r0t);
+  ring r0t=(0,s,t),(x,y),dp;
+  poly g=8*(-s+2t)/(st+t3)*x+t2*x-1;
+write(fname,
+bv +
+"> TeXreplace[2]=list(\"s\",\"\\\\lambda\");"+nl+
+"> TeXreplace[3]=list(\"t\",\"\\\\mu\");"+nl+
+"> setring(r0t);"+nl+
+"> texpoly(fname,g);"+
+ev);
+texpoly(fname,g);
+
+kill TeXreplace;
+write(fname,nl+ "\\vspace{0.4cm}");
+write(fname,nl+"Note that, if \\verb|TeXreplace| is defined, the translation
+into \\LaTeX  code runs a little bit slower, because every polynomial is
+compiled in the \\verb|non short| mode."+ lb );
+
+write(fname,nl,"\\Line","%-----------------------------------------------------");
+
+//linebreaking   TeXwdith
+//-----------------------------------------------------------------------
+write(fname,"The global variable \\verb|TeXwidth| controls the wrapping of
+polynomials; possible values are:" + lb);
+
+write(fname,
+"\\[ " + nl +
+"\\text{\\tt TeXwidth} = ",
+"\\begin{cases} ",
+" -1 & \\text{no line-breaking} \\\\ ",
+"  0 & \\text{print the polynomial as equation } f=0 \\\\ ",
+" 1,\\dots,9 & \\text{the first n terms followed by the sign of the next
+term} \\\\ ",
+" > 9 & \\text{line break after terms of length n (see below)} ",
+"\\end{cases}",
+"\\]",nl);
+
+write(fname,"Note that the size of terms is calculated with certain
+multiplicities.",nl);
+
+//----------------------------------------------------------
+
+write(fname,"\\begin{itemize}");
+write(fname,"\\item");
+
+write(fname,
+bv +
+"> TeXwidth=-1;"+nl+
+"> setring r0;"+nl+
+"> poly f=g^2;"+nl+
+"> texpoly(fname,f);" +
+ev);
+
+  setring r0;
+  poly g=-x2y+2y13z+1;
+  poly f=g^2;
+  texpoly(fname,f);
+
+write(fname,"\\item");
+
+write(fname,
+bv +
+"> TeXwidth=0;
+> texpoly(fname,f);"+
+ev);
+TeXwidth = 0;
+texpoly(fname,f);
+
+write(fname,"\\item");
+write(fname,
+bv +
+"> TeXwidth=2;
+> texpoly(fname,f);"+
+ev);
+TeXwidth=2;
+texpoly(fname,f);
+
+write(fname,"\\item");
+write(fname,
+bv +
+"> TeXwidth=20;"+nl+
+"> texpoly(fname,f);"+
+ev);
+TeXwidth=20;
+texpoly(fname,f);
+TeXwidth=-1;
+
+write(fname,"\\end{itemize}");
+
+write(fname,"\\Line","%-----------------------------------------------------");
+
+write(fname,"There are two possibilities to convert a polynomial into
+\\LaTeX{} code: either by using \\verb|texpoly| or by calling \\verb|texobj|.
+The difference is that \\verb|texpoly| puts the polynomial in text-mode
+while \\verb|texobj| uses the display mode."+nl+
+"The following examples show the different outputs:");
+
+write(fname,
+bv +
+"> setring r3;
+> texpoly(fname,g/180);" +
+ev);
+
+// setring r3;
+
+  ring r3=0,(x_1,x_2,x_3),wp(3,2,1);
+  poly g=-x_1*x_2+2*x_2*x_3+x_1*x_3;
+  texpoly(fname,g/180);
+
+write(fname,
+bv +
+"> texobj(fname,g/180);
+" +
+ev);
+
+texobj(fname,g/180);
+
+//write(fname,"Some explanation how it works: if \\verb|texobj| is called for
+//a polynomial, then it defines a global variable \\verb|TeXdisp| which forces
+//\\verb|texpoly| to count fraction with space corresponding
+//the displaymode."+lb,nl2);
+//---------------------texobj for ideal ---------------
+
+write(fname,"","\\subsection{Ideals}");
+write(fname,"By default, ideals are displayed as column vectors.");
+
+  ring r;
+  ideal I=3xz5+x2y3-3z,7xz5+y3z+x-z,-xyz2+4yz+2x;
+
+write(fname,
+bv +
+"> ring r;   // the default ring"+nl+
+"> ideal I=3xz5+x2y3-3z,7xz5+y3z+x-z,-xyz2+4yz+2x;"+nl+
+"> texobj(fname,I);" +
+ev);
+
+texobj(fname,I);
+
+write(fname,"\\Line","%-----------------------------------------------------");
+//----------------------------------------------------------------------
+write(fname,"If the global variable \\verb|Texaligned| is set then the ideal
+is displayed as a row vector.");
+
+write(fname,
+bv +
+"> int TeXaligned;
+> texobj(fname,I);" +
+ev);
+
+int TeXaligned; export TeXaligned;
+texobj(fname,I);
+
+ write(fname,nl+"\\Line","%-----------------------------------------------------");
+//----------------------------------------------------------------------
+write(fname,"By setting the global variable \\verb|TeXbrack| it is possible
+to change the brackets.");
+
+write(fname,
+bv +
+"> string TeXbrack=\"<\";"+nl+
+"> texobj(fname,I);"+
+ev);
+
+string TeXbrack="<";  export TeXbrack;
+texobj(fname,I);
+
+write(fname,
+bv +
+"> kill TeXbrack, TeXaligned;" +
+ev);
+
+kill TeXbrack,TeXaligned;
+write(fname,"\\Line","%-----------------------------------------------------");
+//----------------------------------------------------------------------
+write(fname,
+" If \\verb|TeXwidth| is 0, an ideal is displayed as a system of
+equations.");
+
+// ------------- a linear equation system
+
+  ring r5=0,x(1..5),dp;
+  ideal I=-x(1)+2*x(3)+x(5), x(2)-x(4)+2*x(5)-1, 8*x(1)+x(4)+2;
+  TeXwidth=0;
+
+write(fname,
+bv +
+"> ring r5=0,x(1..5),dp;"+nl+
+"> ideal I=-x(1)+2*x(3)+x(5), x(2)-x(4)+2*x(5)-1, 8*x(1)+x(4)+2;"+nl+
+"> TeXwidth=0;"+nl+
+"> texobj(fname,I);" +
+ev);
+
+  texobj(fname,I);
+
+  setring r;
+  ideal J=4x4y21+z25y7-y2,x3+y2,y2-z4;
+
+write(fname,
+bv +
+"> setring r;"+nl+
+"> ideal J=4x4y21+z25y7-y2,x3+y2,y2-z4;"+nl+
+"> texobj(fname,J);" +
+ev
+);
+  texobj(fname,J);
+
+write(fname,"\\Line","%-----------------------------------------------------");
+//-----------------------------------------------------------------------
+write(fname,"Call the ideal by its name and it is printed as follows");
+
+write(fname,
+bv +
+"> setring r;
+> ideal I=3xz5+x2y3-3z,7xz5+y3z+x-z,-xyz2+4yz+2x;
+> texobj(fname,\"I\");" +
+ev);
+
+ setring r; export(I);
+ texobj(fname,"I");
+ kill I,r;
+//" end part 2 " + nl;
+}
+
+/////////////////////////////  PART3 //////////////////////////////////////////
+
+static proc part3(string fname)
+{
+  int st=defined(texdemopart);
+  string nl=newline;
+  string nl2=newline + newline;
+  string lb="\\\\";
+  string bv=newline+"\\begin{verbatim}";
+//  string ev = newline + "\\end{verbatim}" + newline ;
+  string ev="\\end{verbatim}" ;
+
+  if (not(st) or st>=3)
+
+  {
+    print(" Call part2 first");
+    return();
+  }
+  else { texdemopart=3; }
+
+// " Continuing part 3 of " + fname +
+// " : map,matrices,vectors,intvec,intmats,proc";
+
+//---------------------- texmap ------------------------------
+write(fname,"","\\section{Typesetting maps between rings}");
+write(fname,"By default, maps are displayed in the following way:");
+
+write(fname,
+bv,
+"> ring r4=0,(x,y,z),dp;
+> ring r5=0,(u,v),dp;
+> map phi=r1,u2,uv -v,v2;
+> texmap(fname,phi,r4,r5);",
+ev);
+
+  ring @r4_h=0,(x,y,z),dp;
+  export @r4_h;
+  ring r5=0,(u,v),dp;
+  map @phi_h=@r4_h,u2,uv -v,v2;  export @phi_h;
+  texmap(fname, at phi_h, at r4_h,r5);
+
+write(fname,"\\Line","%-----------------------------------------------------");
+//--------------------------------------------------------------------
+
+write(fname,"If the global variable \\verb|TeXaligned| is set, then the
+map is displayed in one line.");
+
+write(fname,
+bv,
+"> int TeXaligned;
+> texmap(fname,phi,r4,r5,\"\\\\C\");",
+ev );
+
+  int TeXaligned; export TeXaligned;
+  texmap(fname, at phi_h, at r4_h,r5,"\\C");
+
+write(fname,nl+"\\Line","%-----------------------------------------------------");
+//--------------------------------------------------------------------
+
+write(fname,"It is possible to pass the same additional arguments to
+\\verb|texmap| as to \\verb|texring| (see section {\\tt Rings}). This can
+be done by calling \\verb|texmap| with two lists as additional parameters,
+where the first list contains the optional parameters for the source and
+the second one contains the parameters for the domain. Note that if only one
+list is present then it is applied to both of the rings.");
+
+write(fname,
+bv,
+"> texmap(fname,phi,r4,r5,\"\\\\C\",\"{\");",
+ev );
+  texmap(fname, at phi_h, at r4_h,r5,"\\C","{");
+
+write(fname,nl+ "\\vspace{0.2cm}" + nl);
+write(fname,"The next example shows how to format the two rings in different
+ways.");
+
+write(fname,
+bv,
+"> texmap(fname,phi,r4,r5,list(),list(\"{\"));",
+ev );
+
+ texmap(fname, at phi_h, at r4_h,r5,list(),list("{"));
+
+write(fname,"\\Line","%-----------------------------------------------------");
+//--------------------------------------------------------------------
+
+write(fname,"If the map is called by its name then \\verb|texmap| displays,
+in addition, also the name of the map.");
+
+write(fname,
+bv,
+"> list TeXreplace;
+> TeXreplace[1]=list(\"phi\",\"\\\\phi\");
+> texmap(fname,\"phi\",r4,r5);",
+ev);
+
+  list TeXreplace;
+  TeXreplace[1]=list("@phi_h","\\phi");
+  export TeXreplace;
+  texmap(fname,"@phi_h", at r4_h,r5);
+  kill @phi_h, at r4_h,r5,TeXreplace,TeXaligned;
+
+write(fname,
+bv,
+      "> kill phi,r4,r5,TeXreplace,TeXaligned;",
+ev);
+
+
+//% the texobj part
+write(fname,"","\\section{Typesetting composed data structures}");
+//=======================================================================
+
+write(fname, "Complex data structures such as matrices, vectors or modules
+can be displayed by using the procedure \\verb|texobj|.");
+
+write(fname,"","\\subsection{Matrices and vectors}");
+//=======================================================================
+
+write(fname,"The following example shows how to typeset the Hessian of a
+polynomial.");
+
+write(fname,
+bv,
+"> ring r;
+> poly h=2xy3-x2z+x4z7+y4z2;
+> matrix H=jacob(jacob(h));
+> texobj(fname,H);",
+ev );
+
+ring r;
+poly h=2xy3-x2z+x4z7+y4z2;
+matrix H=jacob(jacob(h));
+texobj(fname,H);
+
+write(fname,"By default, \\verb|vectors| are written as row vectors:");
+
+vector V = H[2];
+
+write(fname,
+bv,
+"> vector V=H[2];
+> texobj(fname,V);",
+ev );
+
+texobj(fname,V);
+
+write(fname,nl+"\\vspace{0.2cm}"+nl);
+write(fname,"In order to transpose it, it has to be converted into a
+matrix.");
+write(fname,
+bv,
+"> texobj(fname,matrix(V));",
+ev );
+
+texobj(fname,matrix(V));
+
+write(fname,nl+"\\Line","%-----------------------------------------------------");
+//------------------------------------------------------------------------
+
+write(fname,"All the features for typesetting polynomials work also for
+matrices or vectors with polynomial entries.");
+write(fname,nl+ "\\vspace{0.2cm}" + nl);
+write(fname,"By setting the global variable \\verb|TeXwidth| it is possible
+to display only the first terms of the polynomials.");
+
+write(fname,bv,
+"> TeXwidth=1;
+> texobj(fname,H);
+> TeXwidth=-1;",
+ev );
+
+TeXwidth = 1;
+texobj(fname,H);
+TeXwidth = -1;
+
+write(fname,nl,"\\Line","%-----------------------------------------------------");
+//------------------------------------------------------------------------
+write(fname,"The flag variable \\verb|TeXnofrac| controls the typesetting
+of fractions.");
+
+write(fname,
+bv,
+"> ring R0=0,x,dp;
+> matrix M[2][3]=1/2, 0, 1/2, 0, 1/3, 2/3;
+> texobj(fname,M);",
+ev);
+
+
+ring R0 = 0,x,dp;
+matrix M[2][3] = 1/2, 0, 1/2, 0, 1/3, 2/3;
+texobj(fname,M);
+
+write(fname,bv,
+"> int TeXnofrac;
+> texobj(fname,M);",
+ev );
+
+  int TeXnofrac; export TeXnofrac;
+  texobj(fname,M);
+  kill TeXnofrac;
+
+write(fname,bv,
+"> kill TeXnofrac;",
+ev );
+
+write(fname,nl,"\\Line","%-----------------------------------------------------");
+//------------------------------------------------------------------------
+
+write(fname,"Printing a vector with homogeneous coordinates can be done by
+setting \\verb|TeXproj|.");
+write(fname,bv +
+"> setring r;
+> int TeXproj;
+> texobj(fname,V);",
+ev );
+
+  setring r;
+  ideal I=3xz5+x2y3-3z,7xz5+y3z+x-z,-xyz2+4yz+2x;
+  int TeXproj; export TeXproj;
+
+  texobj(fname,V);
+  kill TeXproj;
+
+write(fname,
+bv,
+      "> kill TeXproj;",
+ev);
+
+write(fname,"","\\subsection{Modules}");
+
+write(fname,"By default, modules are displayed in the following way:");
+write(fname,
+bv,
+"> setring r;
+> module md=module(H);
+> texobj(fname,md);",
+ev );
+
+setring r;
+module md = module(H);
+texobj(fname,md);
+
+write(fname,"\\Line","%-----------------------------------------------------");
+//------------------------------------------------------------------------
+
+write(fname,"In order to write the generators of a module aligned, the flag
+variable \\verb|TeXaligned| has to be defined.");
+
+write(fname,bv,
+"> int TeXaligned;
+> texobj(fname,md);",
+ev );
+
+int TeXaligned; export TeXaligned;
+texobj(fname,md);
+kill TeXaligned;
+write(fname,bv,
+"> kill TeXaligned;",
+ev );
+
+//----------------------------------------------------------------
+write(fname,"","\\subsection{Integer matrices and vectors}");
+
+write(fname,"Integer matrices are displayed in the following way.");
+
+intmat m[3][4]=-1,3,5,2,-2,8,6,0,2,5,8,7;
+
+write(fname,
+bv,
+"> intmat m[3][4]=-1,3,5,2,-2,8,6,0,2,5,8,7;
+> m;" + nl +
+string(m) + nl +
+"> texobj(fname,m);",
+ev );
+
+texobj(fname,m);
+write(fname,nl+ "\\vspace{0.2cm}" + nl);
+write(fname,"Integer vectors are displayed as row vectors.");
+intvec v = 1..4;
+write(fname,
+bv,
+"> intvec v=1..4;
+> v;" + nl +
+string(v) + nl +
+"> texobj(fname,v);",
+ev );
+
+texobj(fname,v);
+
+write(fname,nl+ "\\vspace{0.2cm}" + nl);
+write(fname,"To typeset the transposed vector, it has to be converted into
+an integer matrix."+
+bv,
+"> texobj(fname,intmat(v));",
+ev );
+
+texobj(fname,intmat(v));
+
+write(fname,nl+ "\\vspace{0.2cm}" + nl);
+
+write(fname,"The following example shows how to typeset the multiplication of
+a matrix with a vector.");
+write(fname,
+bv,
+"> texobj(fname,intmat(m*v),\"=\",m,\"*\",intmat(v));",
+ev );
+
+texobj(fname,intmat(m*v),"=",m,"*",intmat(v));
+
+//-----------------------------------------------------------------
+write(fname,"\\Line","%-----------------------------------------------------");
+
+write(fname,"Of course, the brackets of a \\verb|intmat| can be changed
+by setting \\verb|TeXbrack|.");
+
+write(fname,
+bv,
+"> intmat mat[3][3]=1,2,3,4,5,6,7,8,9;
+> string TeXbrack=\"|\";
+> texobj(fname,mat,\" = \",det(mat)); ",
+ev );
+
+intmat mat[3][3] = 1,2,3,4,5,6,7,8,9;
+string TeXbrack = "|"; export TeXbrack;
+texobj(fname,mat," = ",det(mat));
+kill TeXbrack;
+
+//----------------------------------texname-------------------
+
+//write(fname,"\\section{Names of identifiers}");
+
+
+//write(fname,"The proc \\verb|texname| is used to write indexed names in a
+//correct way"+lb,nl);
+
+
+
+// ------------------------------- texproc -------------------------------
+  proc milnor_number (poly p)
+  {
+    ideal i = std(jacob(p));
+    int m_nr = vdim(i);
+    if (m_nr<0)
+    {
+      "//--  not an isolated singularity";
+    }
+    return(m_nr);
+  }
+  export(milnor_number);
+
+write(fname,"","\\section{Typesetting procedures}");
+write(fname,"The following procedure allows to include the source code
+of procedures into a \\LaTeX document.");
+write(fname,
+bv,
+"> texproc(fname,\"milnor\_number\");",
+ev);
+
+ texproc(fname,"milnor_number");
+
+  kill milnor_number;
+
+// ------------------------------ closing the tex file -------------------
+write(fname,"","\\section{Closing the \\LaTeX\\ file}");
+write(fname,"To close the file use \\verb|closetex(fname);|. It should now
+contain pure \\LaTeX \\ code and may be compiled with " +
+"\\verb|tex(fname)| and displayed with \\verb|xdvi(fname)|.");
+
+// write(fname,"\\section{Remarks}");
+closetex(fname);
+//"end of part3" + nl;
+
+pagewidth =80;
+kill texdemopart,TeXwidth;
+}
+///////////////////////////////////////////////////////////////////////////////
+
+/*
+
+   texring extended for Z,Z_m,real,complex
+
+// Test for new functionality:
+// texring:
+  ring rZ = integer,x,dp;
+  texring("",rZ);
+  ring rZ8 = (integer,8),x,dp;
+  texring("",rZ8);
+
+  ring rR = real,x,dp;
+  texring("",rR);
+
+  ring rR2010 = (real,20,10),x,dp;
+  texring("",rR2010);
+
+  ring rC = complex,x,dp;
+  texring("",rC);
+
+  ring rC2010 = (complex,20,10),x,dp;
+  texring("",rC2010);
+
+// multi-indexed parameters and variables
+
+  ring rmultind34 = 0,(a(1..3)(1..4)),dp;
+  texring("",r34);
+  matrix A[3][4] = maxideal(1);
+  texobj("",A);
+
+  ring rmultind2 = 0,(x1_2,y_1_1,z),ds;
+  texring("",rmultind2);
+
+  ring rmultind3 = 0,(x(-1..1)(0)(3..4)),ds;
+  texobj("",maxideal(1));
+
+  ring rmultind4 = (0,b1(0..2),b2_1(3)),x,ds;
+  texpoly("",par(1)*par(2)*par(3)+par(4)*x);
+
+*/
+// last changed 10/10/10
+///////////////////////// end of latex.lib ////////////////////////////////////
+
diff --git a/Singular/LIB/linalg.lib b/Singular/LIB/linalg.lib
new file mode 100644
index 0000000..838b39f
--- /dev/null
+++ b/Singular/LIB/linalg.lib
@@ -0,0 +1,2044 @@
+/////////////////////////////////////////////////////////////////////////////
+version="version linalg.lib 4.0.0.0 Jun_2013 "; // $Id: 1787b6a0cf72603ecf310435b272f9bb3f2de854 $
+category="Linear Algebra";
+info="
+LIBRARY:  linalg.lib  Algorithmic Linear Algebra
+AUTHORS:  Ivor Saynisch (ivs at math.tu-cottbus.de)
+@*        Mathias Schulze (mschulze at mathematik.uni-kl.de)
+
+PROCEDURES:
+ inverse(A);          matrix, the inverse of A
+ inverse_B(A);        list(matrix Inv,poly p),Inv*A=p*En ( using busadj(A) )
+ inverse_L(A);        list(matrix Inv,poly p),Inv*A=p*En ( using lift )
+ sym_gauss(A);        symmetric gaussian algorithm
+ orthogonalize(A);    Gram-Schmidt orthogonalization
+ diag_test(A);        test whether A can be diagnolized
+ busadj(A);           coefficients of Adj(E*t-A) and coefficients of det(E*t-A)
+ charpoly(A,v);       characteristic polynomial of A ( using busadj(A) )
+ adjoint(A);          adjoint of A ( using busadj(A) )
+ det_B(A);            determinant of A ( using busadj(A) )
+ gaussred(A);         gaussian reduction: P*A=U*S, S a row reduced form of A
+ gaussred_pivot(A);   gaussian reduction: P*A=U*S, uses row pivoting
+ gauss_nf(A);         gaussian normal form of A
+ mat_rk(A);           rank of constant matrix A
+ U_D_O(A);            P*A=U*D*O, P,D,U,O=permutaion,diag,lower-,upper-triang
+ pos_def(A,i);        test symmetric matrix for positive definiteness
+ hessenberg(M);       Hessenberg form of M
+ eigenvals(M);        eigenvalues with multiplicities of M
+ minipoly(M);         minimal polynomial of M
+ spnf(sp);            normal form of spectrum sp
+ spprint(sp);         print spectrum sp
+ jordan(M);           Jordan data of M
+ jordanbasis(M);      Jordan basis and weight filtration of M
+ jordanmatrix(jd);    Jordan matrix with Jordan data jd
+ jordannf(M);         Jordan normal form of M
+";
+
+LIB "matrix.lib";
+LIB "ring.lib";
+LIB "elim.lib";
+LIB "general.lib";
+//////////////////////////////////////////////////////////////////////////////
+// help functions
+//////////////////////////////////////////////////////////////////////////////
+static proc const_mat(matrix A)
+"RETURN:   1 (0) if A is (is not) a constant matrix"
+{
+  int i;
+  int n=ncols(A);
+  def BR=basering;
+  def @R=changeord(list(list("dp",1:nvars(basering)),list("c",0:1)));
+  setring @R;
+  matrix A=fetch(BR,A);
+  for(i=1;i<=n;i=i+1){
+    if(deg(lead(A)[i])>=1){
+      //"input is not a constant matrix";
+      kill @R;
+      setring BR;
+      return(0);
+    }
+  }
+  kill @R;
+  setring BR;
+  return(1);
+}
+//////////////////////////////////////////////////////////////////////////////
+static proc red(matrix A,int i,int j)
+"USAGE:    red(A,i,j);  A = constant matrix
+          reduces column j with respect to A[i,i] and column i
+          reduces row j with respect to A[i,i] and row i
+RETURN:   matrix
+"
+{
+  module m=module(A);
+
+  if(A[i,i]==0)
+  {
+    m[i]=m[i]+m[j];
+    m=module(transpose(matrix(m)));
+    m[i]=m[i]+m[j];
+    m=module(transpose(matrix(m)));
+  }
+
+  A=matrix(m);
+  m[j]=m[j]-(A[i,j]/A[i,i])*m[i];
+  m=module(transpose(matrix(m)));
+  m[j]=m[j]-(A[i,j]/A[i,i])*m[i];
+  m=module(transpose(matrix(m)));
+
+  return(matrix(m));
+}
+
+//////////////////////////////////////////////////////////////////////////////
+proc inner_product(vector v1,vector v2)
+"RETURN:   inner product <v1,v2> "
+{
+  int k;
+  if (nrows(v2)>nrows(v1)) { k=nrows(v2); } else { k=nrows(v1); }
+  return ((transpose(matrix(v1,k,1))*matrix(v2,k,1))[1,1]);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// user functions
+/////////////////////////////////////////////////////////////////////////////
+
+proc inverse(matrix A, list #)
+"USAGE:    inverse(A [,opt]);  A a square matrix, opt integer
+RETURN:
+ at format
+          a matrix:
+          - the inverse matrix of A, if A is invertible;
+          - the 1x1 0-matrix if A is not invertible (in the polynomial ring!).
+          There are the following options:
+          - opt=0 or not given: heuristically best option from below
+          - opt=1 : apply std to (transpose(E,A)), ordering (C,dp).
+          - opt=2 : apply interred (transpose(E,A)), ordering (C,dp).
+          - opt=3 : apply lift(A,E), ordering (C,dp).
+ at end format
+NOTE:     parameters and minpoly are allowed; opt=2 is only correct for
+          matrices with entries in a field
+SEE ALSO: inverse_B, inverse_L
+EXAMPLE:  example inverse; shows an example
+"
+{
+//--------------------------- initialization and check ------------------------
+   int ii,u,notInvertible,opt;
+   matrix invA;
+   int db = printlevel-voice+3;      //used for comments
+   def R = basering;
+   int n = nrows(A);
+   module M = A;
+   intvec v = option(get);           //get options to reset it later
+   if ( ncols(A)!=n )
+   {
+     ERROR("// ** no square matrix");
+   }
+//----------------------- choose heurisitically best option ------------------
+// This may change later, depending on improvements of the implemantation
+// at the monent we use if opt=0 or opt not given:
+// opt = 1 (std) for everything
+// opt = 2 (interred) for nothing, NOTE: interred is ok for constant matricea
+// opt = 3 (lift) for nothing
+// NOTE: interred is ok for constant matrices only (Beispiele am Ende der lib)
+   if(size(#) != 0) {opt = #[1];}
+   if(opt == 0)
+   {
+      if(npars(R) == 0)                       //no parameters
+      {
+         if( size(ideal(A-jet(A,0))) == 0 )   //constant matrix
+         {opt = 1;}
+         else
+         {opt = 1;}
+      }
+      else {opt = 1;}
+   }
+//------------------------- change ring if necessary -------------------------
+   if( ordstr(R) != "C,dp(" + string(nvars(R)) + ")" )
+   {
+     u=1;
+     string mp = string(minpoly);
+     def @R=changeord(list(list("C",0:1),list("dp",1:nvars(basering))));
+     setring @R;
+     if (mp != string(minpoly))
+     {
+       execute("minpoly = " + mp + ";");
+     }
+     module M = fetch(R,M);
+   }
+//----------------------------- opt=3: use lift ------------------------------
+   if( opt==3 )
+   {
+      module D2;
+      D2 = lift(M,freemodule(n));
+      if (size(ideal(D2))==0)
+      {                                               //catch error in lift
+         dbprint(db,"// ** matrix is not invertible");
+         setring R;
+         if (u==1) { kill @R;}
+         return(invA);
+      }
+   }
+//-------------- opt = 1 resp. opt = 2: use std resp. interred --------------
+   if( opt==1 or opt==2 )
+   {
+      option(redSB);
+      module B = freemodule(n),M;
+      if(opt == 2)
+      {
+         module D = interred(transpose(B));
+         D = transpose(simplify(D,1));
+      }
+      if(opt == 1)
+      {
+         module D = std(transpose(B));
+         D = transpose(simplify(D,1));
+      }
+      module D2 = D[1..n];
+      module D1 = D[n+1..2*n];
+//----------------------- check if matrix is invertible ----------------------
+      for (ii=1; ii<=n; ii++)
+      {
+         if ( D1[ii] != gen(ii) )
+         {
+            notInvertible = 1;
+            break;
+         }
+      }
+   }
+   option(set,v);
+//------------------ return to basering and return result ---------------------
+   if ( u==1 )
+   {
+      setring R;
+      module D2 = fetch(@R,D2);
+      if( opt==1 or opt==2 )
+      { module D1 = fetch(@R,D1);}
+      kill @R;
+   }
+   if( notInvertible == 1 )
+   {
+     // The matrix A seems to be non-invertible.
+     // Note that there are examples, where this is not true but only due to
+     // inexact computations in the field of reals or complex numbers:
+     // ring r = complex, x, dp;
+     // The following matrix has non-zero determinante but seems non-invertible:
+     // matrix A[3][3] = 1,i,i,0,1,2,1,0,1+i;
+     // For this example, inverse_B yields the correct answer.
+     // So, let's use this as a workaround whenever we have this situation:
+     list myList = inverse_B(A);
+     matrix Try = inverse_B(A)[1];
+     if (myList[2] == poly(1)) { return (Try); }
+     else
+     {
+       dbprint(db,"// ** matrix is not invertible");
+       return(invA);
+     }
+   }
+   else { return(matrix(D2)); }     //matrix invertible with inverse D2
+
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring r=0,(x,y,z),lp;
+  matrix A[3][3]=
+   1,4,3,
+   1,5,7,
+   0,4,17;
+  print(inverse(A));"";
+  matrix B[3][3]=
+   y+1,  x+y,    y,
+   z,    z+1,    z,
+   y+z+2,x+y+z+2,y+z+1;
+  print(inverse(B));
+  print(B*inverse(B));
+}
+
+//////////////////////////////////////////////////////////////////////////////
+proc sym_gauss(matrix A)
+"USAGE:    sym_gauss(A);  A = symmetric matrix
+RETURN:   matrix, diagonalisation of A with symmetric gauss algorithm
+EXAMPLE:  example sym_gauss; shows an example"
+{
+  int i,j;
+  int n=nrows(A);
+
+  if (ncols(A)!=n)
+  {
+    ERROR("input is not a square matrix");
+  }
+
+  if(!const_mat(A))
+  {
+    ERROR("input is not a constant matrix");
+  }
+
+  if(deg(std(A-transpose(A))[1])!=-1)
+  {
+    ERROR("input is not a symmetric matrix");
+  }
+
+  for(i=1; i<n; i++)
+  {
+    for(j=i+1; j<=n; j++)
+    {
+      if(A[i,j]!=0){ A=red(A,i,j); }
+    }
+  }
+  return(A);
+}
+example
+{"EXAMPLE:"; echo = 2;
+  ring r=0,(x),lp;
+  matrix A[2][2]=1,4,4,15;
+  print(A);
+  print(sym_gauss(A));
+}
+
+//////////////////////////////////////////////////////////////////////////////
+proc orthogonalize(matrix A)
+"USAGE:    orthogonalize(A); A = matrix of constants
+RETURN:    matrix, orthogonal basis of the colum space of A
+EXAMPLE:   example orthogonalize; shows an example "
+{
+  int i,j;
+  int n=ncols(A);
+  poly k;
+
+  if(!const_mat(A)){
+    "// ** input is not a constant matrix";
+    matrix B;
+    return(B);
+  }
+
+  module B=module(interred(A));
+
+  for(i=1;i<=n;i=i+1) {
+    for(j=1;j<i;j=j+1) {
+      k=inner_product(B[j],B[j]);
+      if (k==0) { "Error: vector of length zero"; return(matrix(B)); }
+      B[i]=B[i]-(inner_product(B[i],B[j])/k)*B[j];
+    }
+  }
+
+  return(matrix(B));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring r=0,(x),lp;
+  matrix A[4][4]=5,6,12,4,7,3,2,6,12,1,1,2,6,4,2,10;
+  print(A);
+  print(orthogonalize(A));
+}
+
+////////////////////////////////////////////////////////////////////////////
+proc diag_test(matrix A)
+"USAGE:          diag_test(A); A = const square matrix
+RETURN:   int,  1 if A is diagonalizable,@*
+                0 if not@*
+               -1 if no statement is possible, since A does not split.
+NOTE:     The test works only for split matrices, i.e if eigenvalues of A
+          are in the ground field.
+          Does not work with parameters (uses factorize,gcd).
+EXAMPLE:  example diag_test; shows an example"
+{
+  int i,j;
+  int n     = nrows(A);
+  string mp = string(minpoly);
+  string cs = charstr(basering);
+  int np=0;
+
+  if(ncols(A) != n) {
+    "// input is not a square matrix";
+    return(-1);
+  }
+
+   if(!const_mat(A)){
+    "// input is not a constant matrix";
+    return(-1);
+  }
+
+  //Parameterring wegen factorize nicht erlaubt
+  for(i=1;i<size(cs);i=i+1){
+    if(cs[i]==","){np=np+1;} //Anzahl der Parameter
+  }
+  if(np>0){
+        "// rings with parameters not allowed";
+        return(-1);
+  }
+
+  //speichern des aktuellen Rings
+  def BR=basering;
+  //setze R[t]
+  execute("ring rt=("+charstr(basering)+"),(@t,"+varstr(basering)+"),lp;");
+  execute("minpoly="+mp+";");
+  matrix A=imap(BR,A);
+
+  intvec z;
+  intvec s;
+  poly X;         //characteristisches Polynom
+  poly dXdt;      //Ableitung von X nach t
+  ideal g;              //ggT(X,dXdt)
+  poly b;              //Komponente der Busadjunkten-Matrix
+  matrix E[n][n]; //Einheitsmatrix
+
+  E=E+1;
+  A=E*@t-A;
+  X=det(A);
+
+  matrix Xfactors=matrix(factorize(X,1));        //zerfaellt die Matrtix ?
+  int nf=ncols(Xfactors);
+
+  for(i=1;i<=nf;i++){
+    if(lead(Xfactors[1,i])>=@t^2){
+      //" matrix does not split";
+      setring BR;
+      return(-1);
+    }
+  }
+
+  dXdt=diff(X, at t);
+  g=std(ideal(gcd(X,dXdt)));
+
+  //Busadjunkte
+  z=2..n;
+  for(i=1;i<=n;i++){
+    s=2..n;
+    for(j=1;j<=n;j++){
+      b=det(submat(A,z,s));
+
+      if(0!=reduce(b,g)){
+        //" matrix not diagonalizable";
+        setring BR;
+        return(0);
+      }
+
+      s[j]=j;
+    }
+    z[i]=i;
+  }
+
+  //"Die Matrix ist diagonalisierbar";
+  setring BR;
+  return(1);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring r=0,(x),dp;
+  matrix A[4][4]=6,0,0,0,0,0,6,0,0,6,0,0,0,0,0,6;
+  print(A);
+  diag_test(A);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+proc busadj(matrix A)
+"USAGE:   busadj(A);  A = square matrix (of size nxn)
+RETURN:  list L:
+ at format
+         L[1] contains the (n+1) coefficients of the characteristic
+              polynomial X of A, i.e.
+              X = L[1][1]+..+L[1][k]*t^(k-1)+..+(L[1][n+1])*t^n
+         L[2] contains the n (nxn)-matrices Hk which are the coefficients of
+              the busadjoint bA = adjoint(E*t-A) of A, i.e.
+              bA = (Hn-1)*t^(n-1)+...+Hk*t^k+...+H0,  ( Hk=L[2][k+1] )
+ at end format
+EXAMPLE: example busadj; shows an example"
+{
+  int k;
+  int n    = nrows(A);
+  matrix E = unitmat(n);
+  matrix H[n][n];
+  matrix B[n][n];
+  list bA, X, L;
+  poly a;
+
+  if(ncols(A) != n) {
+    "input is not a square matrix";
+    return(L);
+  }
+
+  bA   = E;
+  X[1] = 1;
+  for(k=1; k<n; k++){
+    B  = A*bA[1];              //bA[1] is the last H
+    a  = -trace(B)/k;
+    H  = B+a*E;
+    bA = insert(bA,H);
+    X  = insert(X,a);
+  }
+  B = A*bA[1];
+  a = -trace(B)/n;
+  X = insert(X,a);
+
+  L = insert(L,bA);
+  L = insert(L,X);
+  return(L);
+}
+example
+{ "EXAMPLE"; echo = 2;
+  ring r = 0,(t,x),lp;
+  matrix A[2][2] = 1,x2,x,x2+3x;
+  print(A);
+  list L = busadj(A);
+  poly X = L[1][1]+L[1][2]*t+L[1][3]*t2; X;
+  matrix bA[2][2] = L[2][1]+L[2][2]*t;
+  print(bA);               //the busadjoint of A;
+  print(bA*(t*unitmat(2)-A));
+}
+
+//////////////////////////////////////////////////////////////////////////////
+proc charpoly(matrix A, list #)
+"USAGE:   charpoly(A[,v]); A square matrix, v string, name of a variable
+RETURN:  poly, the characteristic polynomial det(E*v-A)
+         (default: v=name of last variable)
+NOTE:    A must be independent of the variable v. The computation uses det.
+         If printlevel>0, det(E*v-A) is diplayed recursively.
+EXAMPLE: example charpoly; shows an example"
+{
+  int n = nrows(A);
+  int z = nvars(basering);
+  int i,j;
+  string v;
+  poly X;
+  if(ncols(A) != n)
+  {
+    "// input is not a square matrix";
+    return(X);
+  }
+  //---------------------- test for correct variable -------------------------
+  if( size(#)==0 ){
+    #[1] = varstr(z);
+  }
+  if( typeof(#[1]) == "string") { v = #[1]; }
+  else
+  {
+    "// 2nd argument must be a name of a variable not contained in the matrix";
+    return(X);
+  }
+  j=-1;
+  for(i=1; i<=z; i++)
+  {
+    if(varstr(i)==v){j=i;}
+  }
+  if(j==-1)
+  {
+    "// "+v+" is not a variable in the basering";
+    return(X);
+  }
+  if ( size(select1(module(A),j)) != 0 )
+  {
+    "// matrix must not contain the variable "+v;
+    "// change to a ring with an extra variable, if necessary."
+    return(X);
+  }
+  //-------------------------- compute charpoly ------------------------------
+  X = det(var(j)*unitmat(n)-A);
+  if( printlevel-voice+2 >0) { showrecursive(X,var(j));}
+  return(X);
+}
+example
+{ "EXAMPLE"; echo=2;
+  ring r=0,(x,t),dp;
+  matrix A[3][3]=1,x2,x,x2,6,4,x,4,1;
+  print(A);
+  charpoly(A,"t");
+}
+
+//////////////////////////////////////////////////////////////////////////////
+proc charpoly_B(matrix A, list #)
+"USAGE:   charpoly_B(A[,v]); A square matrix, v string, name of a variable
+RETURN:  poly, the characteristic polynomial det(E*v-A)
+         (default: v=name of last variable)
+NOTE:    A must be constant in the variable v. The computation uses busadj(A).
+EXAMPLE: example charpoly_B; shows an example"
+{
+  int i,j;
+  string s,v;
+  list L;
+  int n     = nrows(A);
+  poly X    = 0;
+  def BR    = basering;
+
+  if(ncols(A) != n){
+    "// input is not a square matrix";
+    return(X);
+  }
+
+  //test for correct variable
+  if( size(#)==0 ){
+    #[1] = varstr(nvars(BR));
+  }
+  if( typeof(#[1]) == "string"){
+     v = #[1];
+  }
+  else{
+    "// 2nd argument must be a name of a variable not contained in the matrix";
+    return(X);
+  }
+
+  j=-1;
+  for(i=1; i<=nvars(BR); i++){
+    if(varstr(i)==v){j=i;}
+  }
+  if(j==-1){
+    "// "+v+" is not a variable in the basering";
+    return(X);
+  }
+
+  //var cannot be in A
+  intvec is=0:nvars(BR);
+  is[j]=1;
+
+  def @R=changeord(list(list("Wp",is)));
+  setring @R;
+  matrix A = imap(BR,A);
+  for(i=1; i<=n; i++){
+    if(deg(lead(A)[i])>=1){
+      "// matrix must not contain the variable "+v;
+      kill @R;
+      setring BR;
+      return(X);
+    }
+  }
+
+  //get coefficients and build the char. poly
+  kill @R;
+  setring BR;
+  L = busadj(A);
+  for(i=1; i<=n+1; i++){
+    execute("X=X+L[1][i]*"+v+"^"+string(i-1)+";");
+  }
+
+  return(X);
+}
+example
+{ "EXAMPLE"; echo=2;
+  ring r=0,(x,t),dp;
+  matrix A[3][3]=1,x2,x,x2,6,4,x,4,1;
+  print(A);
+  charpoly_B(A,"t");
+}
+
+//////////////////////////////////////////////////////////////////////////////
+proc adjoint(matrix A)
+"USAGE:    adjoint(A);  A = square matrix
+RETURN:   adjoint matrix of A, i.e. Adj*A=det(A)*E
+NOTE:     computation uses busadj(A)
+EXAMPLE:  example adjoint; shows an example"
+{
+  int n=nrows(A);
+  matrix Adj[n][n];
+  list L;
+
+  if(ncols(A) != n) {
+    "// input is not a square matrix";
+    return(Adj);
+  }
+
+  L  = busadj(A);
+  Adj= (-1)^(n-1)*L[2][1];
+  return(Adj);
+
+}
+example
+{ "EXAMPLE"; echo=2;
+  ring r=0,(t,x),lp;
+  matrix A[2][2]=1,x2,x,x2+3x;
+  print(A);
+  matrix Adj[2][2]=adjoint(A);
+  print(Adj);                    //Adj*A=det(A)*E
+  print(Adj*A);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+proc inverse_B(matrix A)
+"USAGE:    inverse_B(A);  A = square matrix
+RETURN:   list Inv with
+          - Inv[1] = matrix I and
+          - Inv[2] = poly p
+          such that I*A = unitmat(n)*p;
+NOTE:     p=1 if 1/det(A) is computable and  p=det(A) if not;
+          the computation uses busadj.
+SEE ALSO: inverse, inverse_L
+EXAMPLE:  example inverse_B; shows an example"
+{
+  int i;
+  int n=nrows(A);
+  matrix I[n][n];
+  poly factor;
+  list L;
+  list Inv;
+
+  if(ncols(A) != n) {
+    "input is not a square matrix";
+    return(I);
+  }
+
+  L=busadj(A);
+  I=module(-L[2][1]);        //+-Adj(A)
+
+  if(reduce(1,std(L[1][1]))==0){
+    I=I*lift(L[1][1],1)[1][1];
+    factor=1;
+  }
+  else{ factor=L[1][1];}     //=+-det(A) or 1
+  Inv=insert(Inv,factor);
+  Inv=insert(Inv,matrix(I));
+
+  return(Inv);
+}
+example
+{ "EXAMPLE"; echo=2;
+  ring r=0,(x,y),lp;
+  matrix A[3][3]=x,y,1,1,x2,y,x,6,0;
+  print(A);
+  list Inv=inverse_B(A);
+  print(Inv[1]);
+  print(Inv[2]);
+  print(Inv[1]*A);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+proc det_B(matrix A)
+"USAGE:     det_B(A);  A any matrix
+RETURN:    returns the determinant of A
+NOTE:      the computation uses the busadj algorithm
+EXAMPLE:   example det_B; shows an example"
+{
+  int n=nrows(A);
+  list L;
+
+  if(ncols(A) != n){ return(0);}
+
+  L=busadj(A);
+  return((-1)^n*L[1][1]);
+}
+example
+{ "EXAMPLE"; echo=2;
+  ring r=0,(x),dp;
+  matrix A[10][10]=random(2,10,10)+unitmat(10)*x;
+  print(A);
+  det_B(A);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+proc inverse_L(matrix A)
+"USAGE:     inverse_L(A);  A = square matrix
+RETURN:    list Inv representing a left inverse of A, i.e
+           - Inv[1] = matrix I and
+           - Inv[2] = poly p
+           such that I*A = unitmat(n)*p;
+NOTE:      p=1 if 1/det(A) is computable and p=det(A) if not;
+           the computation computes first det(A) and then uses lift
+SEE ALSO:  inverse, inverse_B
+EXAMPLE:   example inverse_L; shows an example"
+{
+  int n=nrows(A);
+  matrix I;
+  matrix E[n][n]=unitmat(n);
+  poly factor;
+  poly d=1;
+  list Inv;
+
+  if (ncols(A)!=n){
+    "// input is not a square matrix";
+    return(I);
+  }
+
+  d=det(A);
+  if(d==0){
+    "// matrix is not invertible";
+    return(Inv);
+  }
+
+  // test if 1/det(A) exists
+  if(reduce(1,std(d))!=0){ E=E*d;}
+
+  I=lift(A,E);
+  if(I==unitmat(n)-unitmat(n)){ //catch error in lift
+    "// matrix is not invertible";
+    return(Inv);
+  }
+
+  factor=d;      //=det(A) or 1
+  Inv=insert(Inv,factor);
+  Inv=insert(Inv,I);
+
+  return(Inv);
+}
+example
+{ "EXAMPLE"; echo=2;
+  ring r=0,(x,y),lp;
+  matrix A[3][3]=x,y,1,1,x2,y,x,6,0;
+  print(A);
+  list Inv=inverse_L(A);
+  print(Inv[1]);
+  print(Inv[2]);
+  print(Inv[1]*A);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+proc gaussred(matrix A)
+"USAGE:   gaussred(A);   A any constant matrix
+RETURN:  list Z:  Z[1]=P , Z[2]=U , Z[3]=S , Z[4]=rank(A)
+         gives a row reduced matrix S, a permutation matrix P and a
+         normalized lower triangular matrix U, with P*A=U*S
+NOTE:    This procedure is designed for teaching purposes mainly.
+         The straight forward implementation in the interpreted library
+         is not very efficient (no standard basis computation).
+EXAMPLE: example gaussred; shows an example"
+{
+  int i,j,l,k,jp,rang;
+  poly c,pivo;
+  list Z;
+  int n = nrows(A);
+  int m = ncols(A);
+  int mr= n; //max. rang
+  matrix P[n][n] = unitmat(n);
+  matrix U[n][n] = P;
+
+  if(!const_mat(A)){
+    "// input is not a constant matrix";
+    return(Z);
+  }
+
+  if(n>m){mr=m;} //max. rang
+
+  for(i=1;i<=mr;i=i+1){
+    if((i+k)>m){break;}
+
+    //Test: Diagonalelement=0
+    if(A[i,i+k]==0){
+      jp=i;pivo=0;
+      for(j=i+1;j<=n;j=j+1){
+        c=absValue(A[j,i+k]);
+        if(pivo<c){ pivo=c;jp=j;}
+      }
+      if(jp != i){       //Zeilentausch
+        for(j=1;j<=m;j=j+1){ //Zeilentausch in A (und U) (i-te mit jp-ter)
+          c=A[i,j];
+          A[i,j]=A[jp,j];
+          A[jp,j]=c;
+        }
+        for(j=1;j<=n;j=j+1){ //Zeilentausch in P
+          c=P[i,j];
+          P[i,j]=P[jp,j];
+          P[jp,j]=c;
+        }
+      }
+      if(pivo==0){k++;continue;} //eine von selbst auftauchende Stufe !
+    }                          //i sollte im naechsten Lauf nicht erhoeht sein
+
+    //Eliminationsschritt
+    for(j=i+1;j<=n;j=j+1){
+      c=A[j,i+k]/A[i,i+k];
+      for(l=i+k+1;l<=m;l=l+1){
+        A[j,l]=A[j,l]-A[i,l]*c;
+      }
+      A[j,i+k]=0;  // nur wichtig falls k>0 ist
+      A[j,i]=c;    // bildet U
+    }
+  rang=i;
+  }
+
+  for(i=1;i<=mr;i=i+1){
+    for(j=i+1;j<=n;j=j+1){
+      U[j,i]=A[j,i];
+      A[j,i]=0;
+    }
+  }
+
+  Z=insert(Z,rang);
+  Z=insert(Z,A);
+  Z=insert(Z,U);
+  Z=insert(Z,P);
+
+  return(Z);
+}
+example
+{ "EXAMPLE";echo=2;
+  ring r=0,(x),dp;
+  matrix A[5][4]=1,3,-1,4,2,5,-1,3,1,3,-1,4,0,4,-3,1,-3,1,-5,-2;
+  print(A);
+  list Z=gaussred(A);   //construct P,U,S s.t. P*A=U*S
+  print(Z[1]);          //P
+  print(Z[2]);          //U
+  print(Z[3]);          //S
+  print(Z[4]);          //rank
+  print(Z[1]*A);        //P*A
+  print(Z[2]*Z[3]);     //U*S
+}
+
+//////////////////////////////////////////////////////////////////////////////
+proc gaussred_pivot(matrix A)
+"USAGE:     gaussred_pivot(A);   A any constant matrix
+RETURN:    list Z:  Z[1]=P , Z[2]=U , Z[3]=S , Z[4]=rank(A)
+           gives a row reduced matrix S, a permutation matrix P and a
+           normalized lower triangular matrix U, with P*A=U*S
+NOTE:      with row pivoting
+EXAMPLE:   example gaussred_pivot; shows an example"
+{
+  int i,j,l,k,jp,rang;
+  poly c,pivo;
+  list Z;
+  int n=nrows(A);
+  int m=ncols(A);
+  int mr=n; //max. rang
+  matrix P[n][n]=unitmat(n);
+  matrix U[n][n]=P;
+
+  if(!const_mat(A)){
+    "// input is not a constant matrix";
+    return(Z);
+  }
+
+  if(n>m){mr=m;} //max. rang
+
+  for(i=1;i<=mr;i=i+1){
+    if((i+k)>m){break;}
+
+    //Pivotisierung
+    pivo=absValue(A[i,i+k]);jp=i;
+    for(j=i+1;j<=n;j=j+1){
+      c=absValue(A[j,i+k]);
+      if(pivo<c){ pivo=c;jp=j;}
+    }
+    if(jp != i){ //Zeilentausch
+      for(j=1;j<=m;j=j+1){ //Zeilentausch in A (und U) (i-te mit jp-ter)
+        c=A[i,j];
+        A[i,j]=A[jp,j];
+        A[jp,j]=c;
+      }
+      for(j=1;j<=n;j=j+1){ //Zeilentausch in P
+        c=P[i,j];
+        P[i,j]=P[jp,j];
+        P[jp,j]=c;
+      }
+    }
+    if(pivo==0){k++;continue;} //eine von selbst auftauchende Stufe !
+                               //i sollte im naechsten Lauf nicht erhoeht sein
+    //Eliminationsschritt
+    for(j=i+1;j<=n;j=j+1){
+      c=A[j,i+k]/A[i,i+k];
+      for(l=i+k+1;l<=m;l=l+1){
+        A[j,l]=A[j,l]-A[i,l]*c;
+      }
+      A[j,i+k]=0;  // nur wichtig falls k>0 ist
+      A[j,i]=c;    // bildet U
+    }
+  rang=i;
+  }
+
+  for(i=1;i<=mr;i=i+1){
+    for(j=i+1;j<=n;j=j+1){
+      U[j,i]=A[j,i];
+      A[j,i]=0;
+    }
+  }
+
+  Z=insert(Z,rang);
+  Z=insert(Z,A);
+  Z=insert(Z,U);
+  Z=insert(Z,P);
+
+  return(Z);
+}
+example
+{ "EXAMPLE";echo=2;
+  ring r=0,(x),dp;
+  matrix A[5][4] = 1, 3,-1,4,
+                   2, 5,-1,3,
+                   1, 3,-1,4,
+                   0, 4,-3,1,
+                  -3,1,-5,-2;
+  list Z=gaussred_pivot(A);  //construct P,U,S s.t. P*A=U*S
+  print(Z[1]);               //P
+  print(Z[2]);               //U
+  print(Z[3]);               //S
+  print(Z[4]);               //rank
+  print(Z[1]*A);             //P*A
+  print(Z[2]*Z[3]);          //U*S
+}
+
+//////////////////////////////////////////////////////////////////////////////
+proc gauss_nf(matrix A)
+"USAGE:    gauss_nf(A); A any constant matrix
+RETURN:   matrix; gauss normal form of A (uses gaussred)
+EXAMPLE:  example gauss_nf; shows an example"
+{
+  list Z;
+  if(!const_mat(A)){
+    "// input is not a constant matrix";
+    return(A);
+  }
+  Z = gaussred(A);
+  return(Z[3]);
+}
+example
+{ "EXAMPLE";echo=2;
+  ring r = 0,(x),dp;
+  matrix A[4][4] = 1,4,4,7,2,5,5,4,4,1,1,3,0,2,2,7;
+  print(gauss_nf(A));
+}
+
+//////////////////////////////////////////////////////////////////////////////
+proc mat_rk(matrix A)
+"USAGE:    mat_rk(A); A any constant matrix
+RETURN:   int, rank of A
+EXAMPLE:  example mat_rk; shows an example"
+{
+  list Z;
+  if(!const_mat(A)){
+    "// input is not a constant matrix";
+    return(-1);
+  }
+  Z = gaussred(A);
+  return(Z[4]);
+}
+example
+{ "EXAMPLE";echo=2;
+  ring r = 0,(x),dp;
+  matrix A[4][4] = 1,4,4,7,2,5,5,4,4,1,1,3,0,2,2,7;
+  mat_rk(A);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+proc U_D_O(matrix A)
+"USAGE:     U_D_O(A);   constant invertible matrix A
+RETURN:    list Z:  Z[1]=P , Z[2]=U , Z[3]=D , Z[4]=O
+           gives a permutation matrix P,
+           a normalized lower triangular matrix U ,
+           a diagonal matrix D, and
+           a normalized upper triangular matrix O
+           with P*A=U*D*O
+NOTE:      Z[1]=-1 means that A is not regular (proc uses gaussred)
+EXAMPLE:   example U_D_O; shows an example"
+{
+  int i,j;
+  list Z,L;
+  int n=nrows(A);
+  matrix O[n][n]=unitmat(n);
+  matrix D[n][n];
+
+  if (ncols(A)!=n){
+    "// input is not a square matrix";
+    return(Z);
+  }
+  if(!const_mat(A)){
+    "// input is not a constant matrix";
+    return(Z);
+  }
+
+  L=gaussred(A);
+
+  if(L[4]!=n){
+    "// input is not an invertible matrix";
+    Z=insert(Z,-1);  //hint for calling procedures
+    return(Z);
+  }
+
+  D=L[3];
+
+  for(i=1; i<=n; i++){
+    for(j=i+1; j<=n; j++){
+      O[i,j] = D[i,j]/D[i,i];
+      D[i,j] = 0;
+    }
+  }
+
+  Z=insert(Z,O);
+  Z=insert(Z,D);
+  Z=insert(Z,L[2]);
+  Z=insert(Z,L[1]);
+  return(Z);
+}
+example
+{ "EXAMPLE";echo=2;
+  ring r = 0,(x),dp;
+  matrix A[5][5] = 10, 4,  0, -9,  8,
+                   -3, 6, -6, -4,  9,
+                    0, 3, -1, -9, -8,
+                   -4,-2, -6, -10,10,
+                   -9, 5, -1, -6,  5;
+  list Z = U_D_O(A);              //construct P,U,D,O s.t. P*A=U*D*O
+  print(Z[1]);                    //P
+  print(Z[2]);                    //U
+  print(Z[3]);                    //D
+  print(Z[4]);                    //O
+  print(Z[1]*A);                  //P*A
+  print(Z[2]*Z[3]*Z[4]);          //U*D*O
+}
+
+//////////////////////////////////////////////////////////////////////////////
+proc pos_def(matrix A)
+"USAGE:     pos_def(A); A = constant, symmetric square matrix
+RETURN:    int:
+           1  if A is positive definit ,
+           0  if not,
+           -1 if unknown
+EXAMPLE:   example pos_def; shows an example"
+{
+  int j;
+  list Z;
+  int n = nrows(A);
+  matrix H[n][n];
+
+  if (ncols(A)!=n){
+    "// input is not a square matrix";
+    return(0);
+  }
+  if(!const_mat(A)){
+    "// input is not a constant matrix";
+    return(-1);
+  }
+  if(deg(std(A-transpose(A))[1])!=-1){
+    "// input is not a hermitian (symmetric) matrix";
+    return(-1);
+  }
+
+  Z=U_D_O(A);
+
+  if(Z[1]==-1){
+    return(0);
+  }  //A not regular, therefore not pos. definit
+
+  H=Z[1];
+  //es fand Zeilentausch statt: also nicht positiv definit
+  if(deg(std(H-unitmat(n))[1])!=-1){
+    return(0);
+  }
+
+  H=Z[3];
+
+  for(j=1;j<=n;j=j+1){
+    if(H[j,j]<=0){
+      return(0);
+    } //eigenvalue<=0, not pos.definit
+  }
+
+  return(1); //positiv definit;
+}
+example
+{ "EXAMPLE"; echo=2;
+  ring r = 0,(x),dp;
+  matrix A[5][5] = 20,  4,  0, -9,   8,
+                    4, 12, -6, -4,   9,
+                    0, -6, -2, -9,  -8,
+                   -9, -4, -9, -20, 10,
+                    8,  9, -8,  10, 10;
+  pos_def(A);
+  matrix B[3][3] =  3,  2,  0,
+                    2, 12,  4,
+                    0,  4,  2;
+  pos_def(B);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+proc linsolve(matrix A, matrix b)
+"USAGE:     linsolve(A,b); A a constant nxm-matrix, b a constant nx1-matrix
+RETURN:    a 1xm matrix X, solution of inhomogeneous linear system A*X = b
+           return the 0-matrix if system is not solvable
+NOTE:      uses gaussred
+EXAMPLE:   example linsolve; shows an example"
+{
+  int i,j,k,rc,r;
+  poly c;
+  list Z;
+  int n  = nrows(A);
+  int m  = ncols(A);
+  int n_b= nrows(b);
+  matrix Ab[n][m+1];
+  matrix X[m][1];
+
+  if(ncols(b)!=1){
+    "// right hand side b is not a nx1 matrix";
+    return(X);
+  }
+
+  if(!const_mat(A)){
+    "// input hand is not a constant matrix";
+    return(X);
+  }
+
+  if(n_b>n){
+    for(i=n; i<=n_b; i++){
+      if(b[i,1]!=0){
+        "// right hand side b not in Image(A)";
+        return X;
+      }
+    }
+  }
+
+  if(n_b<n){
+    matrix copy[n_b][1]=b;
+    matrix b[n][1]=0;
+    for(i=1;i<=n_b;i=i+1){
+      b[i,1]=copy[i,1];
+    }
+  }
+
+  r=mat_rk(A);
+
+  //1. b constant vector
+  if(const_mat(b)){
+    //extend A with b
+    for(i=1; i<=n; i++){
+      for(j=1; j<=m; j++){
+        Ab[i,j]=A[i,j];
+      }
+      Ab[i,m+1]=b[i,1];
+    }
+
+    //Gauss reduction
+    Z  = gaussred(Ab);
+    Ab = Z[3];  //normal form
+    rc = Z[4];  //rank(Ab)
+    //print(Ab);
+
+    if(r<rc){
+        "// no solution";
+        return(X);
+    }
+    k=m;
+    for(i=r;i>=1;i=i-1){
+
+      j=1;
+      while(Ab[i,j]==0){j=j+1;}// suche Ecke
+
+      for(;k>j;k=k-1){ X[k]=0;}//springe zur Ecke
+
+
+      c=Ab[i,m+1]; //i-te Komponene von b
+      for(j=m;j>k;j=j-1){
+        c=c-X[j,1]*Ab[i,j];
+      }
+      if(Ab[i,k]==0){
+        X[k,1]=1; //willkuerlich
+      }
+      else{
+          X[k,1]=c/Ab[i,k];
+      }
+      k=k-1;
+      if(k==0){break;}
+    }
+
+
+  }//endif (const b)
+  else{  //b not constant
+    "// !not implemented!";
+
+  }
+
+  return(X);
+}
+example
+{ "EXAMPLE";echo=2;
+  ring r=0,(x),dp;
+  matrix A[3][2] = -4,-6,
+                    2, 3,
+                   -5, 7;
+  matrix b[3][1] = 10,
+                   -5,
+                    2;
+  matrix X = linsolve(A,b);
+  print(X);
+  print(A*X);
+}
+//////////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////////
+//    PROCEDURES for Jordan normal form
+//    AUTHOR:  Mathias Schulze, email: mschulze at mathematik.uni-kl.de
+///////////////////////////////////////////////////////////////////////////////
+
+static proc rowcolswap(matrix M,int i,int j)
+{
+  if(system("with","eigenval"))
+  {
+    return(system("rowcolswap",M,i,j));
+  }
+  //--------------------------------------------
+  if(i==j)
+  {
+    return(M);
+  }
+  poly p;
+  for(int k=1;k<=nrows(M);k++)
+  {
+    p=M[i,k];
+    M[i,k]=M[j,k];
+    M[j,k]=p;
+  }
+  for(k=1;k<=ncols(M);k++)
+  {
+    p=M[k,i];
+    M[k,i]=M[k,j];
+    M[k,j]=p;
+  }
+  return(M);
+}
+//////////////////////////////////////////////////////////////////////////////
+
+static proc rowelim(matrix M,int i,int j,int k)
+{
+  if(system("with","eigenval"))
+  {
+    return(system("rowelim",M,i,j,k));
+  }
+  // -----------------------
+  if(jet(M[i,k],0)==0||jet(M[j,k],0)==0)
+  {
+    return(M);
+  }
+  number n=number(jet(M[i,k],0))/number(jet(M[j,k],0));
+  for(int l=1;l<=ncols(M);l++)
+  {
+    M[i,l]=M[i,l]-n*M[j,l];
+  }
+  for(l=1;l<=nrows(M);l++)
+  {
+    M[l,j]=M[l,j]+n*M[l,i];
+  }
+  return(M);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+static proc colelim(matrix M,int i,int j,int k)
+{
+  if(jet(M[k,i],0)==0||jet(M[k,j],0)==0)
+  {
+    return(M);
+  }
+  number n=number(jet(M[k,i],0))/number(jet(M[k,j],0));
+  for(int l=1;l<=nrows(M);l++)
+  {
+    M[l,i]=M[l,i]-n*M[l,j];
+  }
+  for(l=1;l<=ncols(M);l++)
+  {
+    M[j,l]=M[j,l]+n*M[i,l];
+  }
+  return(M);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc hessenberg(matrix M)
+"USAGE:   hessenberg(M); matrix M
+ASSUME:  M constant square matrix
+RETURN:  matrix H;  Hessenberg form of M
+EXAMPLE: example hessenberg; shows examples
+"
+{
+  if(system("with","eigenval"))
+  {
+    return(system("hessenberg",M));
+  }
+
+  int n=ncols(M);
+  int i,j;
+  for(int k=1;k<n-1;k++)
+  {
+    j=k+1;
+    while(j<n&&jet(M[j,k],0)==0)
+    {
+      j++;
+    }
+    if(jet(M[j,k],0)!=0)
+    {
+      M=rowcolswap(M,j,k+1);
+      for(i=j+1;i<=n;i++)
+      {
+        M=rowelim(M,i,k+1,k);
+      }
+    }
+  }
+  return(M);
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring R=0,x,dp;
+  matrix M[3][3]=3,2,1,0,2,1,0,0,3;
+  print(M);
+  print(hessenberg(M));
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc eigenvals(matrix M)
+"USAGE:   eigenvals(M); matrix M
+ASSUME:  eigenvalues of M in basefield
+RETURN:
+ at format
+list l;
+  ideal l[1];
+    number l[1][i];  i-th eigenvalue of M
+  intvec l[2];
+    int l[2][i];  multiplicity of i-th eigenvalue of M
+ at end format
+EXAMPLE: example eigenvals; shows examples
+KEYWORDS: eigenvalue
+"
+{
+  if(system("with","eigenval"))
+  {
+    return(system("eigenvals",jet(M,0)));
+  }
+
+  M=jet(hessenberg(M),0);
+  int n=ncols(M);
+  int k;
+  ideal e;
+  intvec m;
+  number e0;
+  intvec v;
+  list l;
+  int i,j;
+  j=1;
+  while(j<=n)
+  {
+    v=j;
+    j++;
+    if(j<=n)
+    {
+      while(j<n&&M[j,j-1]!=0)
+      {
+        v=v,j;
+        j++;
+      }
+      if(M[j,j-1]!=0)
+      {
+        v=v,j;
+        j++;
+      }
+    }
+    if(size(v)==1)
+    {
+      k++;
+      e[k]=M[v,v];
+      m[k]=1;
+    }
+    else
+    {
+      l=factorize(det(submat(M,v,v)-var(1)));
+      for(i=size(l[1]);i>=1;i--)
+      {
+        e0=number(jet(l[1][i]/var(1),0));
+        if(e0!=0)
+        {
+          k++;
+          e[k]=(e0*var(1)-l[1][i])/e0;
+          m[k]=l[2][i];
+        }
+      }
+    }
+  }
+  return(spnf(list(e,m)));
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring R=0,x,dp;
+  matrix M[3][3]=3,2,1,0,2,1,0,0,3;
+  print(M);
+  eigenvals(M);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc minipoly(matrix M,list #)
+"USAGE:   minipoly(M); matrix M
+ASSUME:  eigenvalues of M in basefield
+RETURN:
+ at format
+list l;  minimal polynomial of M
+  ideal l[1];
+    number l[1][i];  i-th root of minimal polynomial of M
+  intvec l[2];
+    int l[2][i];  multiplicity of i-th root of minimal polynomial of M
+ at end format
+EXAMPLE: example minipoly; shows examples
+"
+{
+  if(nrows(M)==0)
+  {
+    ERROR("non empty expected");
+  }
+  if(ncols(M)!=nrows(M))
+  {
+    ERROR("square matrix expected");
+  }
+
+  M=jet(M,0);
+
+  if(size(#)==0)
+  {
+    #=eigenvals(M);
+  }
+  def e0,m0=#[1..2];
+
+  intvec m1;
+  matrix N0,N1;
+  for(int i=1;i<=ncols(e0);i++)
+  {
+    m1[i]=1;
+    N0=M-e0[i];
+    N1=N0;
+    while(size(syz(N1))<m0[i])
+    {
+      m1[i]=m1[i]+1;
+      N1=N1*N0;
+    }
+  }
+
+  return(list(e0,m1));
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring R=0,x,dp;
+  matrix M[3][3]=3,2,1,0,2,1,0,0,3;
+  print(M);
+  minipoly(M);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc spnf(list #)
+"USAGE:   spnf(list(a[,m])); ideal a, intvec m
+ASSUME:  ncols(a)==size(m)
+RETURN:  list l:
+            l[1] an ideal, the generators of a; sorted and with multiple entries displayed only once@*
+            l[2] an intvec, l[2][i] provides the multiplicity of l[1][i]
+EXAMPLE: example spnf; shows examples
+"
+{
+  list sp=#;
+  ideal a=sp[1];
+  int n=ncols(a);
+  intvec m;
+  list V;
+  module v;
+  int i,j;
+  for(i=2;i<=size(sp);i++)
+  {
+    if(typeof(sp[i])=="intvec")
+    {
+      m=sp[i];
+    }
+    if(typeof(sp[i])=="module")
+    {
+      v=sp[i];
+      for(j=n;j>=1;j--)
+      {
+        V[j]=module(v[j]);
+      }
+    }
+    if(typeof(sp[i])=="list")
+    {
+      V=sp[i];
+    }
+  }
+  if(m==0)
+  {
+    for(i=n;i>=1;i--)
+    {
+      m[i]=1;
+    }
+  }
+
+  int k;
+  ideal a0;
+  intvec m0;
+  list V0;
+  number a1;
+  int m1;
+  for(i=n;i>=1;i--)
+  {
+    if(m[i]!=0)
+    {
+      for(j=i-1;j>=1;j--)
+      {
+        if(m[j]!=0)
+        {
+          if(number(a[i])>number(a[j]))
+          {
+            a1=number(a[i]);
+            a[i]=a[j];
+            a[j]=a1;
+            m1=m[i];
+            m[i]=m[j];
+            m[j]=m1;
+            if(size(V)>0)
+            {
+              v=V[i];
+              V[i]=V[j];
+              V[j]=v;
+            }
+          }
+          if(number(a[i])==number(a[j]))
+          {
+            m[i]=m[i]+m[j];
+            m[j]=0;
+            if(size(V)>0)
+            {
+              V[i]=V[i]+V[j];
+            }
+          }
+        }
+      }
+      k++;
+      a0[k]=a[i];
+      m0[k]=m[i];
+      if(size(V)>0)
+      {
+        V0[k]=V[i];
+      }
+    }
+  }
+
+  if(size(V0)>0)
+  {
+    n=size(V0);
+    module U=std(V0[n]);
+    for(i=n-1;i>=1;i--)
+    {
+      V0[i]=simplify(reduce(V0[i],U),1);
+      if(i>=2)
+      {
+        U=std(U+V0[i]);
+      }
+    }
+  }
+
+  if(k>0)
+  {
+    sp=a0,m0;
+    if(size(V0)>0)
+    {
+      sp[3]=V0;
+    }
+  }
+  return(sp);
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring R=0,(x,y),ds;
+  list sp=list(ideal(-1/2,-3/10,-3/10,-1/10,-1/10,0,1/10,1/10,3/10,3/10,1/2));
+  spprint(spnf(sp));
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc spprint(list sp)
+"USAGE:   spprint(sp); list sp (helper routine for spnf)
+RETURN:  string s;  spectrum sp
+EXAMPLE: example spprint; shows examples
+SEE ALSO: gmssing_lib, spnf
+"
+{
+  string s;
+  for(int i=1;i<size(sp[2]);i++)
+  {
+    s=s+"("+string(sp[1][i])+","+string(sp[2][i])+"),";
+  }
+  s=s+"("+string(sp[1][i])+","+string(sp[2][i])+")";
+  return(s);
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring R=0,(x,y),ds;
+  list sp=list(ideal(-1/2,-3/10,-1/10,0,1/10,3/10,1/2),intvec(1,2,2,1,2,2,1));
+  spprint(sp);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc jordan(matrix M,list #)
+"USAGE:   jordan(M); matrix M
+ASSUME:  eigenvalues of M in basefield
+RETURN:
+ at format
+list l;  Jordan data of M
+  ideal l[1];
+    number l[1][i];  eigenvalue of i-th Jordan block of M
+  intvec l[2];
+    int l[2][i];  size of i-th Jordan block of M
+  intvec l[3];
+    int l[3][i];  multiplicity of i-th Jordan block of M
+ at end format
+EXAMPLE: example jordan; shows examples
+"
+{
+  if(nrows(M)==0)
+  {
+    ERROR("non empty expected");
+  }
+  if(ncols(M)!=nrows(M))
+  {
+    ERROR("square matrix expected");
+  }
+
+  M=jet(M,0);
+
+  if(size(#)==0)
+  {
+    #=eigenvals(M);
+  }
+  def e0,m0=#[1..2];
+
+  int i;
+  for(i=1;i<=ncols(e0);i++)
+  {
+    if(deg(e0[i])>0)
+    {
+
+      ERROR("eigenvalues in coefficient field expected");
+      return(list());
+    }
+  }
+
+  int j,k;
+  matrix N0,N1;
+  module K0;
+  list K;
+  ideal e;
+  intvec s,m;
+
+  for(i=1;i<=ncols(e0);i++)
+  {
+    N0=M-e0[i]*matrix(freemodule(ncols(M)));
+
+    N1=N0;
+    K0=0;
+    K=module();
+    while(size(K0)<m0[i])
+    {
+      K0=syz(N1);
+      K=K+list(K0);
+      N1=N1*N0;
+    }
+
+    for(j=2;j<size(K);j++)
+    {
+      if(2*size(K[j])-size(K[j-1])-size(K[j+1])>0)
+      {
+        k++;
+        e[k]=e0[i];
+        s[k]=j-1;
+        m[k]=2*size(K[j])-size(K[j-1])-size(K[j+1]);
+      }
+    }
+    if(size(K[j])-size(K[j-1])>0)
+    {
+      k++;
+      e[k]=e0[i];
+      s[k]=j-1;
+      m[k]=size(K[j])-size(K[j-1]);
+    }
+  }
+
+  return(list(e,s,m));
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring R=0,x,dp;
+  matrix M[3][3]=3,2,1,0,2,1,0,0,3;
+  print(M);
+  jordan(M);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc jordanbasis(matrix M,list #)
+"USAGE:   jordanbasis(M); matrix M
+ASSUME:  eigenvalues of M in basefield
+RETURN:
+ at format
+list l:
+  module l[1];  inverse(l[1])*M*l[1] in Jordan normal form
+  intvec l[2];
+    int l[2][i];  weight filtration index of l[1][i]
+ at end format
+EXAMPLE: example jordanbasis; shows examples
+"
+{
+  if(nrows(M)==0)
+  {
+    ERROR("non empty matrix expected");
+  }
+  if(ncols(M)!=nrows(M))
+  {
+    ERROR("square matrix expected");
+  }
+
+  M=jet(M,0);
+
+  if(size(#)==0)
+  {
+    #=eigenvals(M);
+  }
+  def e,m=#[1..2];
+
+  for(int i=1;i<=ncols(e);i++)
+  {
+    if(deg(e[i])>0)
+    {
+      ERROR("eigenvalues in coefficient field expected");
+      return(freemodule(ncols(M)));
+    }
+  }
+
+  int j,k,l,n;
+  matrix N0,N1;
+  module K0,K1;
+  list K;
+  matrix u[ncols(M)][1];
+  module U;
+  intvec w;
+
+  for(i=1;i<=ncols(e);i++)
+  {
+    N0=M-e[i]*matrix(freemodule(ncols(M)));
+
+    N1=N0;
+    K0=0;
+    K=list();
+    while(size(K0)<m[i])
+    {
+      K0=syz(N1);
+      K=K+list(K0);
+      N1=N1*N0;
+    }
+
+    K1=0;
+    for(j=1;j<size(K);j++)
+    {
+      K0=K[j];
+      K[j]=interred(reduce(K[j],std(K1+module(N0*K[j+1]))));
+      K1=K0;
+    }
+    K[j]=interred(reduce(K[j],std(K1)));
+
+    for(l=size(K);l>=1;l--)
+    {
+      for(k=size(K[l]);k>0;k--)
+      {
+        u=K[l][k];
+        for(j=l;j>=1;j--)
+        {
+          U=U+module(u);
+          n++;
+          w[n]=2*j-l-1;
+          u=N0*u;
+        }
+      }
+    }
+  }
+
+  return(list(U,w));
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring R=0,x,dp;
+  matrix M[3][3]=3,2,1,0,2,1,0,0,3;
+  print(M);
+  list l=jordanbasis(M);
+  print(l[1]);
+  print(l[2]);
+  print(inverse(l[1])*M*l[1]);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc jordanmatrix(list jd)
+"USAGE:   jordanmatrix(list(e,s,m)); ideal e, intvec s, intvec m
+ASSUME:  ncols(e)==size(s)==size(m)
+RETURN:
+ at format
+matrix J;  Jordan matrix with list(e,s,m)==jordan(J)
+ at end format
+EXAMPLE: example jordanmatrix; shows examples
+"
+{
+  ideal e=jd[1];
+  intvec s=jd[2];
+  intvec m=jd[3];
+  if(ncols(e)!=size(s)||ncols(e)!=size(m))
+  {
+    ERROR("arguments of equal size expected");
+  }
+
+  int i,j,k,l;
+  int n=int((transpose(matrix(s))*matrix(m))[1,1]);
+  matrix J[n][n];
+  for(k=1;k<=ncols(e);k++)
+  {
+    for(l=1;l<=m[k];l++)
+    {
+      j++;
+      J[j,j]=e[k];
+      for(i=s[k];i>=2;i--)
+      {
+        J[j+1,j]=1;
+        j++;
+        J[j,j]=e[k];
+      }
+    }
+  }
+
+  return(J);
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring R=0,x,dp;
+  ideal e=ideal(2,3);
+  intvec s=1,2;
+  intvec m=1,1;
+  print(jordanmatrix(list(e,s,m)));
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc jordannf(matrix M,list #)
+"USAGE:   jordannf(M); matrix M
+ASSUME:  eigenvalues of M in basefield
+RETURN:  matrix J; Jordan normal form of M
+EXAMPLE: example jordannf; shows examples
+"
+{
+  return(jordanmatrix(jordan(M,#)));
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring R=0,x,dp;
+  matrix M[3][3]=3,2,1,0,2,1,0,0,3;
+  print(M);
+  print(jordannf(M));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+/*
+///////////////////////////////////////////////////////////////////////////////
+//          Auskommentierte zusaetzliche Beispiele
+//
+///////////////////////////////////////////////////////////////////////////////
+// Singular for ix86-Linux version 1-3-10  (2000121517)  Dec 15 2000 17:55:12
+// Rechnungen auf AMD700 mit 632 MB
+
+ LIB "linalg.lib";
+
+1. Sparse integer Matrizen
+--------------------------
+ring r1=0,(x),dp;
+system("--random", 12345678);
+int n = 70;
+matrix m = sparsemat(n,n,50,100);
+option(prot,mem);
+
+int t=timer;
+matrix im = inverse(m,1)[1];
+timer-t;
+print(im*m);
+//list l0 = watchdog(100,"inverse("+"m"+",3)");
+//bricht bei 100 sec ab und gibt l0[1]: string Killed zurueck
+
+//inverse(m,1): std       5sec 5,5 MB
+//inverse(m,2): interred  12sec
+//inverse(m,2): lift      nach 180 sec 13MB abgebrochen
+//n=60: linalgorig: 3  linalg: 5
+//n=70: linalgorig: 6,7 linalg: 11,12
+// aber linalgorig rechnet falsch!
+
+2. Sparse poly Matrizen
+-----------------------
+ring r=(0),(a,b,c),dp;
+system("--random", 12345678);
+int n=6;
+matrix m = sparsematrix(n,n,2,0,50,50,9); //matrix of polys of deg <=2
+option(prot,mem);
+
+int t=timer;
+matrix im = inverse(m);
+timer-t;
+print(im*m);
+//inverse(m,1): std       0sec 1MB
+//inverse(m,2): interred  0sec 1MB
+//inverse(m,2): lift      nach 2000 sec 33MB abgebrochen
+
+3. Sparse Matrizen mit Parametern
+---------------------------------
+//liborig rechnet hier falsch!
+ring r=(0),(a,b),dp;
+system("--random", 12345678);
+int n=7;
+matrix m = sparsematrix(n,n,1,0,40,50,9);
+ring r1 = (0,a,b),(x),dp;
+matrix m = imap(r,m);
+option(prot,mem);
+
+int t=timer;
+matrix im = inverse(m);
+timer-t;
+print(im*m);
+//inverse(m)=inverse(m,3):15 sec inverse(m,1)=1sec inverse(m,2):>120sec
+//Bei Parametern vergeht die Zeit beim Normieren!
+
+3. Sparse Matrizen mit Variablen und Parametern
+-----------------------------------------------
+ring r=(0),(a,b),dp;
+system("--random", 12345678);
+int n=6;
+matrix m = sparsematrix(n,n,1,0,35,50,9);
+ring r1 = (0,a),(b),dp;
+matrix m = imap(r,m);
+option(prot,mem);
+
+int t=timer;
+matrix im = inverse(m,3);
+timer-t;
+print(im*m);
+//n=7: inverse(m,3):lange sec inverse(m,1)=1sec inverse(m,2):1sec
+
+4. Ueber Polynomring invertierbare Matrizen
+-------------------------------------------
+LIB"random.lib"; LIB"linalg.lib";
+system("--random", 12345678);
+int n =3;
+ring r= 0,(x,y,z),(C,dp);
+matrix A=triagmatrix(n,n,1,0,0,50,2);
+intmat B=sparsetriag(n,n,20,1);
+matrix M = A*transpose(B);
+M=M*transpose(M);
+M[1,1..ncols(M)]=M[1,1..n]+xyz*M[n,1..ncols(M)];
+print(M);
+//M hat det=1 nach Konstruktion
+
+int t=timer;
+matrix iM=inverse(M);
+timer-t;
+print(iM*M);                      //test
+
+//ACHTUNG: Interred liefert i.A. keine Inverse, Gegenbeispiel z.B.
+//mit n=3
+//eifacheres Gegenbeispiel:
+matrix M =
+9yz+3y+3z+2,             9y2+6y+1,
+9xyz+3xy+3xz-9z2+2x-6z-1,9xy2+6xy-9yz+x-3y-3z
+//det M=1, inverse(M,2); ->// ** matrix is not invertible
+//lead(M); 9xyz*gen(2) 9xy2*gen(2) nicht teilbar!
+
+5. charpoly:
+-----------
+//ring rp=(0,A,B,C),(x),dp;
+ring r=0,(A,B,C,x),dp;
+matrix m[12][12]=
+AC,BC,-3BC,0,-A2+B2,-3AC+1,B2,   B2,  1,   0, -C2+1,0,
+1, 1, 2C,  0,0,     B,     -A,   -4C, 2A+1,0, 0,    0,
+0, 0, 0,   1,0,     2C+1,  -4C+1,-A,  B+1, 0, B+1,  3B,
+AB,B2,0,   1,0,     1,     0,    1,   A,   0, 1,    B+1,
+1, 0, 1,   0,0,     1,     0,    -C2, 0,   1, 0,    1,
+0, 0, 2,   1,2A,    1,     0,    0,   0,   0, 1,    1,
+0, 1, 0,   1,1,     2,     A,    3B+1,1,   B2,1,    1,
+0, 1, 0,   1,1,     1,     1,    1,   2,   0, 0,    0,
+1, 0, 1,   0,0,     0,     1,    0,   1,   1, 0,    3,
+1, 3B,B2+1,0,0,     1,     0,    1,   0,   0, 1,    0,
+0, 0, 1,   0,0,     0,     0,    1,   0,   0, 0,    0,
+0, 1, 0,   1,1,     3,     3B+1, 0,   1,   1, 1,    0;
+option(prot,mem);
+
+int t=timer;
+poly q=charpoly(m,"x");         //1sec, charpoly_B 1sec, 16MB
+timer-t;
+//1sec, charpoly_B 1sec, 16MB  (gleich in r und rp)
+
+*/
diff --git a/Singular/LIB/locnormal.lib b/Singular/LIB/locnormal.lib
new file mode 100644
index 0000000..7fd0445
--- /dev/null
+++ b/Singular/LIB/locnormal.lib
@@ -0,0 +1,539 @@
+//////////////////////////////////////////////////////////////////////////////
+version="version locnormal.lib 4.0.0.0 Jun_2013 "; // $Id: cbacd89180cb6158f6be2724cb6bab17e23741e4 $
+category="Commutative Algebra";
+info="
+LIBRARY: locnormal.lib   Normalization of affine domains using local methods
+AUTHORS:  J. Boehm        boehm at mathematik.uni-kl.de
+          W. Decker       decker at mathematik.uni-kl.de
+          S. Laplagne     slaplagn at dm.uba.ar
+          G. Pfister      pfister at mathematik.uni-kl.de
+          S. Steidel      steidel at mathematik.uni-kl.de
+          A. Steenpass    steenpass at mathematik.uni-kl.de
+
+OVERVIEW:
+
+Suppose A is an affine domain over a perfect field.@*
+This library implements a local-to-global strategy for finding the normalization
+of A. Following [1], the idea is to stratify the singular locus of A, apply the
+normalization algorithm given in [2] locally at each stratum, and put the local
+results together. This approach is inherently parallel.@*
+Furthermore we allow for the optional modular computation of the local results
+as provided by modnormal.lib. See again [1] for details.
+
+REFERENCES:
+
+[1] Janko Boehm, Wolfram Decker, Santiago Laplagne, Gerhard Pfister, Stefan Steidel,
+Andreas Steenpass: Parallel algorithms for normalization, http://arxiv.org/abs/1110.4299, 2011.
+
+[2] Gert-Martin Greuel, Santiago Laplagne, Frank Seelisch: Normalization of Rings,
+Journal of Symbolic Computation 9 (2010), p. 887-901
+
+KEYWORDS:
+normalization; local methods; modular methods
+
+SEE ALSO: normal_lib, modnormal_lib
+
+PROCEDURES:
+locNormal(I, [...]);  normalization of R/I using local methods
+
+";
+
+LIB "normal.lib";
+LIB "sing.lib";
+LIB "modstd.lib";
+
+static proc changeDenom(ideal U1, poly c1, poly c2, ideal I){
+// Given a ring in the form 1/c1 * U, it computes a new ideal U2 such that the
+// ring is 1/c2 * U2.
+// The base ring is R, but the computations are to be done in R / I.
+  int a;      // counter
+  def R = basering;
+  qring Q = groebner(I);
+  ideal U1 = fetch(R, U1);
+  poly c1 = fetch(R, c1);
+  poly c2 = fetch(R, c2);
+  ideal U2 = changeDenomQ(U1, c1, c2);
+  setring R;
+  ideal U2 = fetch(Q, U2);
+  return(U2);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static proc changeDenomQ(ideal U1, poly c1, poly c2){
+// Given a ring in the form 1/c1 * U, it computes a new U2 st the ring
+// is 1/c2 * U2.
+// The base ring is already a quotient ring R / I.
+  int a;      // counter
+  ideal U2;
+  poly p;
+  for(a = 1; a <= ncols(U1); a++){
+    p = lift(c1, c2*U1[a])[1,1];
+    U2[a] = p;
+  }
+  return(U2);
+}
+
+/////////////////////////////////////////////////////////////////////////////////
+
+proc locNormal(ideal I, list #)
+"USAGE:  locNormal(I [,options]); I = prime ideal, options = list of options. @*
+         Optional parameters in list options (can be entered in any order):@*
+         modular: use a modular approach for the local computations. The number of primes is
+                  increased one at a time, starting with 2 primes, until the result stabelizes.@*
+         noVerificication: if the modular approach is used, the result will not be verified.
+ASSUME:  I is a prime ideal (the algorithm will also work for radical ideals as long as the
+         normal command does not detect that the ideal under consideration is not prime).
+RETURN:  a list of an ideal U and a universal denominator d such that U/d is the normalization.
+REMARKS: We use the local-to-global algorithm given in [1] to compute the normalization of
+         A = R/I, where R is the basering.@*
+         The idea is to stratify the singular locus of A, apply the normalization algorithm
+         given in [2] locally at each stratum, and put the local results together.@*
+         If the option modular is given, the result is returned as a probabilistic result
+         or verified, depending on whether the option noVerificication is used or not.@*
+         The normalization of A is represented as an R-module by returning a list of U and d,
+         where U is an ideal of A and d is an element of A such that U/d is the normalization of A.
+         In fact, U and d are returned as an ideal and a polynomial of the base ring R.
+
+REFERENCES:
+         [1] Janko Boehm, Wolfram Decker, Santiago Laplagne, Gerhard Pfister, Stefan Steidel,
+             Andreas Steenpass: Parallel algorithms for normalization, http://arxiv.org/abs/1110.4299, 2011.@*
+         [2] Gert-Martin Greuel, Santiago Laplagne, Frank Seelisch: Normalization of Rings,
+             Journal of Symbolic Computation 9 (2010), p. 887-901
+KEYWORDS: normalization; local methods; modular methods.
+SEE ALSO: normal_lib, modnormal_lib.
+EXAMPLE: example locNormal; shows an example
+"
+{
+// Computes the normalization by localizing at the different components of the singularity.
+  int i;
+  int totalLocalTime;
+  int dbg = printlevel - voice + 2;
+  def R = basering;
+
+  int totalTime = timer;
+  intvec LTimer;
+  int t;
+  int printTimings=0;
+
+  int locmod;
+  for ( i=1; i <= size(#); i++ )
+  {
+    if ( typeof(#[i]) == "string" )
+    {
+      if (#[i]=="modular") { locmod = 1;}
+      if (#[i]=="printTimings") { printTimings = 1;}
+    }
+  }
+
+  // Computes the Singular Locus
+  list IM = mstd(I);
+  I = IM[1];
+  int d = dim(I);
+  ideal IMin = IM[2];
+  qring Q = I;   // We work in the quotient by the groebner base of the ideal I
+  option("redSB");
+  option("returnSB");
+  ideal I = fetch(R, I);
+  attrib(I, "isSB", 1);
+  ideal IMin = fetch(R, IMin);
+  dbprint(dbg, "Computing the jacobian ideal...");
+  ideal J = minor(jacob(IMin), nvars(basering) - d, I);
+  t=timer;
+  int ch = char(basering);
+  if (ch==0) {J = modStd(J);} else {J = std(J);}
+  if (printTimings==1) {"Time for modStd/std Jacobian "+string(timer-t);}
+
+  setring R;
+  ideal J = fetch(Q, J);
+  // We compute a universal denominator
+  poly condu = getSmallest(J);
+  J = J, I;
+  if(dbg >= 2){
+    "Conductor: ", condu;
+    "The original singular locus is";
+    groebner(J);
+    if(dbg >= 2){pause();}
+    "";
+  }
+  t=timer;
+  list pd = locIdeals(J);
+  dbprint(dbg,pd);
+  if (printTimings==1) {
+    "Number of maximal components to localize at: ", size(pd);
+    "";
+  }
+
+  ideal U;
+  ideal resT;
+  ideal resu;
+  poly denomOld;
+  poly denom;
+  totalLocalTime = timer;
+  int maxLocalTime;
+  list Lnor;
+  list parallelArguments;
+  for(i = 1; i <= size(pd); i++){
+    parallelArguments[i] = list(pd[i], I, condu, i, locmod, printTimings, #);
+  }
+  list parallelResults = parallelWaitAll("locNormal_parallelTask",
+    parallelArguments);
+  for(i = 1; i <= size(pd); i++){
+    // We sum the result to the previous results.
+    resu = resu, parallelResults[i][1];
+    Lnor[i] = parallelResults[i][1];
+    if(parallelResults[i][2] > maxLocalTime) {
+      maxLocalTime = parallelResults[i][2];
+    }
+    LTimer[i] = parallelResults[i][2];
+  }
+  if (printTimings==1) {
+    "List of local times: "; LTimer;
+    "Maximal local time: "+string(maxLocalTime);
+  }
+  totalLocalTime = timer - totalLocalTime;
+  if (printTimings==1) {
+    "Total time local computations: "+string(totalLocalTime);
+  }
+
+  t=timer;
+  if (ch==0) {resu = modStd(resu);} else {resu = std(resu);}
+  if (printTimings==1) {
+     "Time for combining the local results, modStd/std "+string(timer-t);
+  }
+
+  totalTime = timer - totalTime;
+  if (printTimings==1) {
+    "Total time locNormal: "+string(totalTime);
+    "Simulated parallel time: "+string(totalTime + maxLocalTime - totalLocalTime);
+  }
+  return(list(resu, condu));
+}
+
+example
+{ "EXAMPLE:";
+ring R = 0,(x,y,z),dp;
+int k = 4;
+poly f = (x^(k+1)+y^(k+1)+z^(k+1))^2-4*(x^(k+1)*y^(k+1)+y^(k+1)*z^(k+1)+z^(k+1)*x^(k+1));
+f = subst(f,z,3x-2y+1);
+ring S = 0,(x,y),dp;
+poly f = imap(R,f);
+ideal i = f;
+list L = locNormal(i);
+}
+
+proc locNormal_parallelTask(ideal pdi, ideal I, poly condu, int i, int locmod,
+  int printTimings, list #)
+{
+  pdi=pdi;
+  int t = timer;
+  list opt = list(list("inputJ", pdi)) + #;
+  if (printTimings==1) {
+    "Local component ",i," of degree "+string(deg(pdi))+" and dimension "
+      +string(dim(pdi));
+  }
+  list n;
+  ideal norT;
+  poly denomT;
+  if (locmod==1) {
+     n = modNormal(I,1, opt);
+     norT = n[1];
+     denomT = n[2];
+  } else {
+     n = normal(I,opt);
+     if(size(n[2]) > 1){
+       ERROR("Input was not prime...");
+     }
+     norT = n[2][1];
+     denomT = norT[size(norT)];
+  }
+  t = timer-t;
+  // We compute the normalization of I localized at a component of the Singular
+  // Locus
+  if (printTimings==1) {
+    "Output of normalization of component ", i, ": "; norT;
+    "";
+  }
+  ideal nor = changeDenom(norT, denomT, condu, I);
+  return(list(nor, t));
+}
+
+static proc locComps(list l)
+{
+  int d = size(l);
+  int i;
+  int j;
+  intvec m = 1:d;   // 1 = maximal ideal
+  ideal IT;
+
+  // Check for maximal ideals
+  for(i = 1; i<d; i++)
+  {
+    for(j = i+1; j <= d; j++)
+    {
+      if(subset(l[i], l[j]))
+      {
+        m[i] = 0;
+        break;
+      }
+    }
+  }
+  list outL;
+  for(i = 1; i<= d; i++)
+  {
+    if(m[i] == 1){
+      // Maximal ideal
+      IT = l[i];
+      for(j = 1; j <= d; j++){
+        if(j != i)
+        {
+          if(subset(l[j], l[i]))
+          {
+            IT = intersect(IT, l[j]);
+          }
+        }
+      }
+      outL = insert(outL, IT);
+    }
+  }
+  return(outL);
+}
+
+// I C J ??
+static proc subset(ideal I, ideal J)
+{
+  J = groebner(J);
+  return(size(reduce(I, J)) == 0);
+}
+
+
+// Computes the different localizations of the radical of I at all the points of the space.
+static proc locIdeals(ideal I){
+  int i, j;
+  I = groebner(I);
+
+  // Minimal associated primes of I
+  list l = minAssGTZ(I);
+  //"Total number of components of the Singular Locus: ", size(l);
+
+  int s = size(l);
+  int d = dim(I);
+  if (d==0) {return(l)};
+  intvec m = (1:d);
+  // 1 = maximal ideal
+  ideal IT;
+
+  // inters will contain all the different intersections of components of I.
+  // It is a list of list. The j-th list contains the intersections of j components of I.
+  list inters;
+  list compIndex;   // Indicate the index of the last component in the corresponding intersection
+                    // This is used to intersect it with the remaining components.
+  for(i = 1; i<= d; i++)
+  {
+    l[i] = groebner(l[i]);
+  }
+
+  // We add all the components to the list of intersections
+  inters[1] = l;
+  compIndex[1] = 1..s;
+
+  ideal J;
+  int e;
+  int a;
+
+  // Intersections of two or more components
+  for(e = 1; e <= d; e++)
+  {
+    inters[e+1]  = list();
+    a = 1;
+    for(i = 1; j <= size(inters[e]); i++)
+    {
+      for(j = compIndex[e][i] + 1; j <= s; j++)
+      {
+        J = l[j] + inters[e][i];
+        J = groebner(J);
+        if(J[1] != 1)
+        {
+          inters[e+1] = inters[e+1]+list(J);
+          if(a == 1)
+          {
+            compIndex[e+1] = intvec(j);
+          } else
+          {
+            compIndex[e+1][a] = j;
+          }
+          a++;
+        }
+      }
+    }
+  }
+
+  list ids;
+  for(e = 1; e <= d+1; e++)
+  {
+    ids = ids + inters[e];
+  }
+  return(locComps(ids));
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+//                            EXAMPLES
+//
+///////////////////////////////////////////////////////////////////////////
+/*
+// plane curves
+
+ring r24 = 0,(x,y,z),dp;
+int k = 2;
+poly f = (x^(k+1)+y^(k+1)+z^(k+1))^2-4*(x^(k+1)*y^(k+1)+y^(k+1)*z^(k+1)+z^(k+1)*x^(k+1));
+f = subst(f,z,2x-y+1);
+ring s24 = 0,(x,y),dp;
+poly f = imap(r24,f);
+ideal i = f;
+
+locNormal(i);
+//modNormal(i,1);
+
+
+ring r24 = 0,(x,y,z),dp;
+int k = 3;
+poly f = (x^(k+1)+y^(k+1)+z^(k+1))^2-4*(x^(k+1)*y^(k+1)+y^(k+1)*z^(k+1)+z^(k+1)*x^(k+1));
+f = subst(f,z,2x-y+1);
+ring s24 = 0,(x,y),dp;
+poly f = imap(r24,f);
+ideal i = f;
+
+locNormal(i);
+//modNormal(i,1,"noVerification");
+
+
+ring r24 = 0,(x,y,z),dp;
+int k = 4;
+poly f = (x^(k+1)+y^(k+1)+z^(k+1))^2-4*(x^(k+1)*y^(k+1)+y^(k+1)*z^(k+1)+z^(k+1)*x^(k+1));
+f = subst(f,z,2x-y+1);
+ring s24 = 0,(x,y),dp;
+poly f = imap(r24,f);
+ideal i = f;
+
+locNormal(i);
+//modNormal(i,1,"noVerification");
+
+
+ring r24 = 0,(x,y,z),dp;
+int k = 5;
+poly f = (x^(k+1)+y^(k+1)+z^(k+1))^2-4*(x^(k+1)*y^(k+1)+y^(k+1)*z^(k+1)+z^(k+1)*x^(k+1));
+f = subst(f,z,2x-y+1);
+ring s24 = 0,(x,y),dp;
+poly f = imap(r24,f);
+ideal i = f;
+
+locNormal(i);
+
+
+
+ring s24 = 0,(x,y),dp;
+int a=7;
+ideal i = ((x-1)^a-y^3)*((x+1)^a-y^3)*((x)^a-y^3)*((x-2)^a-y^3)*((x+2)^a-y^3)+y^15;
+
+locNormal(i);
+//modNormal(i,1);
+
+
+ring s24 = 0,(x,y),dp;
+int a=7;
+ideal i = ((x-1)^a-y^3)*((x+1)^a-y^3)*((x)^a-y^3)*((x-2)^a-y^3)*((x+2)^a-y^3)+y^15;
+
+locNormal(i);
+//modNormal(i,1);
+
+ring s24 = 0,(x,y),dp;
+int a=7;
+ideal i = ((x-1)^a-y^3)*((x+1)^a-y^3)*((x)^a-y^3)*((x-2)^a-y^3)*((x+2)^a-y^3)+y^15;
+
+locNormal(i);
+//modNormal(i,1,"noVerification");
+
+
+
+
+ring r=0,(x,y),dp;
+ideal i=9127158539954x10+3212722859346x8y2+228715574724x6y4-34263110700x4y6
+-5431439286x2y8-201803238y10-134266087241x8-15052058268x6y2+12024807786x4y4
++506101284x2y6-202172841y8+761328152x6-128361096x4y2+47970216x2y4-6697080y6
+-2042158x4+660492x2y2-84366y4+2494x2-474y2-1;
+
+locNormal(i);
+//modNormal(i,1);
+
+
+// surfaces in A3
+
+
+ring r7 = 0,(x,y,t),dp;
+int a=11;
+ideal i = x*y*(x-y)*(x+y)*(y-1)*t+(x^a-y^2)*(x^10-(y-1)^2);
+locNormal(i);
+//modNormal(i,1,"noVerification");
+
+ring r7 = 0,(x,y,t),dp;
+int a=12;
+ideal i = x*y*(x-y)*(x+y)*(y-1)*t+(x^a-y^2)*(x^10-(y-1)^2);
+locNormal(i);
+//modNormal(i,1,"noVerification");
+
+
+ring r7 = 0,(x,y,t),dp;
+int a=13;
+ideal i = x*y*(x-y)*(x+y)*(y-1)*t+(x^a-y^2)*(x^10-(y-1)^2);
+
+locNormal(i);
+modNormal(i,1,"noVerification");
+
+
+ring r22 = 0,(x,y,z),dp;
+ideal i = z2-(y2-1234x3)^2*(15791x2-y3)*(1231y2-x2*(x+158))*(1357y5-3x11);
+
+locNormal(i);
+//modNormal(i,1,"noVerification");
+
+
+ring r22 = 0,(x,y,z),dp;
+ideal i = z2-(y2-1234x3)^3*(15791x2-y3)*(1231y2-x2*(x+158))*(1357y5-3x11);
+
+locNormal(i);
+//modNormal(i,1,"noVerification");
+
+
+ring r23 = 0,(x,y,z),dp;
+ideal i = z5-((13x-17y)*(5x2-7y3)*(3x3-2y2)*(19y2-23x2*(x+29)))^2;
+
+locNormal(i);
+//modNormal(i,1,"noVerification");
+
+
+// curve in A3
+
+ring r23 = 0,(x,y,z),dp;
+ideal i = z3-(19y2-23x2*(x+29))^2,x3-(11y2-13z2*(z+1));
+
+locNormal(i);
+//modNormal(i,1,"noVerification");
+
+
+ring r23 = 0,(x,y,z),dp;
+ideal i = z3-(19y2-23x2*(x+29))^2,x3-(11y2-13z2*(z+1))^2;
+
+locNormal(i);
+//modNormal(i,1,"noVerification");
+
+// surface in A4
+
+ring r23 = 0,(x,y,z,w),dp;
+ideal i = z2-(y3-123456w2)*(15791x2-y3)^2, w*z-(1231y2-x*(111x+158));
+
+
+locNormal(i);
+//modNormal(i,1,"noVerification");
+*/
+
diff --git a/Singular/LIB/makedbm.lib b/Singular/LIB/makedbm.lib
new file mode 100644
index 0000000..992244c
--- /dev/null
+++ b/Singular/LIB/makedbm.lib
@@ -0,0 +1,294 @@
+/////////////////////////////////////////////////////////////////////////////
+version="version makedbm.lib 4.0.0.0 Jun_2013 "; // $Id: cdb9d3be92061e5db246fa86d180aba1e3eaa85a $
+category="Miscellaneous";
+info="
+LIBRARY:  makedbm.lib     Data Base of Singularities for the Arnold-Classifier
+AUTHOR:   Kai Krueger, krueger at mathematik.uni-kl.de
+
+PROCEDURES:
+ dbm_read(l);          read all entries from a DBM-databaes pointed by l
+ dbm_getnext(l);       read next entry from a DBM-databaes pointed by l
+ create_sing_dbm();
+ read_sing_dbm();
+";
+
+//=============================================================================
+
+proc makedbm_init()
+{
+  string s;
+  link l="DBM:r NFlist";
+  s = read(l,"VERSION");
+  if (s == "" ) {
+    "Need to create database...";
+    create_sing_dbm();
+  }
+  close(l);
+  l="DBM:r NFlist";
+  s = read(l,"VERSION");
+  "Creation done. Current version:", s;
+}
+//=============================================================================
+
+proc dbm_read (link l)
+{
+  string s="";
+  s=read(l);
+  while( s != "" )
+  {
+    s,"=",read(l,s);
+    s=read(l);
+  }
+}
+
+//=============================================================================
+proc dbm_getnext (link l)
+{
+  string s="";
+  s=read(l);
+  if( s != "" ) { s,"=",read(l,s); }
+}
+
+//=============================================================================
+proc create_sing_dbm
+{
+// DatenFormat: crk=#; Mu=#; MlrCd=#;
+  string s;
+  link l="DBM:rw NFlist";
+
+  write(l, "A[k]", "x^(k+1)");
+  s ="crk=1; Mu=k; MlnCd=k;";
+  write(l, "I_A[k]", s);
+
+  write(l, "D[k]", "x2y+y^(k-1)");
+  s = "crk=2; Mu=k; MlnCd=1,1,k-3";
+  write(l, "I_D[k]", s);
+
+  write(l, "E[6k]", "x3+y^(3*k+1)+a*x*(y^(2*k+1))");
+  s = "crk=2; Mu=6*k; MlnCd=1,2*k,2*k-1";
+  write(l, "I_E[6k]", s);
+
+  write(l, "E[6k+1]", "x3+x*(y^(2*k+1))+a*(y^(3*k+2))");
+  write(l, "E[6k+2]", "x3+y^(3*k+2)+a*x*(y^(2*k+2))");
+  write(l, "J[k,0]", "x3+b*x^2*y^k+y^(3*k)+c*x*y^(2*k+1)");
+  write(l, "J[k,r]", "x3+x2*y^k+a*y^(3*k+r)");
+  write(l, "X[1,0]", "x4+a*x2y2+y4");
+  write(l, "X[1,r]", "x4+x2y2+a*y^(4+r)");
+  write(l, "X[k,0]", "x4+b*x^3*y^k+a*x^2*y^(2*k) + x*y^(3*k)");
+  write(l, "X[k,r]", "x4+a*x^3*y^k+x^2*y^(2*k)+b*(y^(4*k+r))");
+  write(l, "W[12k]", "x4+y^(4*k+1)+a*x*(y^(3*k+1))+c*x^2*(y^(2*k+1))");
+  write(l, "W[12k+1]", "x4+x*(y^(3*k+1))+a*x^2*(y^(2*k+1))+c*y^(4*k+2)");
+  write(l, "W[12k+5]", "x4+x*(y^(3*k+2))+a*x2*(y^(2*k+2))+b*y^(4*k+3)");
+  write(l, "W[12k+6]", "x4+y^(4*k+3)+a*x*(y^(3*k+3))+b*x2*(y^(2*k+2))");
+  write(l, "W[k,0]", "x4+b*x2*(y^(2*k+1))+a*x*(y^(3*k+2))+y^(4*k+2)");
+  write(l, "W[k,r]", "x4+a*x3*(y^(k+1))+x2*(y^(2*k+1))+b*y^(4*k+2+r)");
+  write(l, "W#[k,2r-1]", "(x2+y^(2*k+1))^2+b*x*(y^(3*k+1+r))+a*y^(4*k+2+r)");
+  write(l, "W#[k,2r]", "(x2+y^(2*k+1))^2+b*x2*(y^(2*k+1+r))+a*x*(y^(3*k+2+r))");
+  write(l, "Y[1,r,s]", "x^(4+r)+a*x2*(y2)+y^(4+s)");
+  write(l, "Y[k,r,s]", "((x+a*y^k)^2 + b*y^(2*k+s))*( x2 + y^(2*k+r))");
+  write(l, "Z[1,0]", "x3y + x2y3 + xy6 +y7");
+  write(l, "Z[1,r]", "x3y + x2*(y^3) + a*y^(7+r)");
+  write(l, "Z[k,r,s]", "(x2+a*x*(y^k)+b*y^(2*k+r))*(x2+y^(2*k+2*r+s))");
+  write(l, "Z[k,r,0]", "(x+a*(y^k))*(x3+d*x2*(y^(k+r))+c*x*(y^(2*k+2*r+1))+y^(3*k+3*r))");
+  write(l, "Z[k,12k+6r-1]", "(x+a*(y^k))*(x3+b*x*(y^(2*k+2*r+1))+y^(3*k+3*r+1))");
+  write(l, "Z[k,12k+6r]", "(x+a*(y^k))*(x3+x*(y^(2*k+2*r+1))+b*y^(3*k+3*r+2))");
+  write(l, "Z[k,12k+6r+1]", "(x+a*(y^k))*(x3+b*x*(y^(2*k+2*r+2))+y^(3*k+3*r+2))");
+  write(l, "Z[k,0]", "y*(x3+d*x2*(y^(k+1))+c*x*(y^(2*k+3))+y^(3*k+3))");
+  write(l, "Z[k,r]", "y*(x3+x^2*y^(k+1)+b*(y^(3*k+r+3)))");
+  write(l, "Z[6k+5]", "y*(x3+b*x*(y^(2*k+1))+y^(3*k+1))");
+  write(l, "Z[6k+6]", "y*(x3+x*(y^(2*k+1))+b*y^(3*k+2))");
+  write(l, "Z[6k+7]", "y*(x3+b*x*(y^(2*k+2))+y^(3*k+2))");
+  write(l, "Q[k,0]", "x3+z2y+b*x2*(y^k)+x*(y^(2*k))");
+  write(l, "Q[k,r]", "x3+z2y+x2*(y^k)+b*y^(3*k+r)");
+  write(l, "Q[6k+4]", "x3+z2y+y^(3*k+1)+b*x*(y^(2*k+1))");
+  write(l, "Q[6k+5]", "x3+z2y+x*(y^(2*k+1))+b*y^(3*k+2)");
+  write(l, "Q[6k+6]", "x3+z2y+y^(3*k+2)+b*x*(y^(2*k+2))");
+  write(l, "S[12k-1]", "x2z+z2y+y^(4*k)+a*x*(y^(3*k))+c*z*(y^(2*k+1))");
+  write(l, "S[12k]", "x2z+z2y+x*(y^(3*k))+c*y^(4*k+1)+a*z*(y^(2*k+1))");
+  write(l, "S[k,0]", "x2z+z2y+y^(4*k+1)+a*x*(y^(3*k+1))+b*z*(y^(2*k+1))");
+  write(l, "S[k,r]", "x2z+z2y+x2*(y^(2*k))+a*x3*(y^k)+b*y^(4*k+r+1)");
+  write(l, "S#[k,2r-1]", "x2z+z2y+z*(y^(2*k+1))+b*x*(y^(3*k+r))+a*(y^(4*k+r+1))");
+  write(l, "S#[k,2r]", "x2z+z2y+z*(y^(2*k+1))+b*x2*(y^(2*k+r))");
+  write(l, "S[12k+4]", "x2z+z2y+x*(y^(3*k+1))+a*z*(y^(2*k+2))+b*y^(4*k+2)");
+  write(l, "S[12k+5]", "x2z+z2y+y^(4*k+2)+a*x*(y^(3*k+2))+b*z*(y^(2*k+2))");
+  write(l, "U[12k]", "x3+z2x+y^(3*k+1)+a*x*(y^(2*k+1))+b*z*(y^(2*k+1))+d*x2*(y^(k+1))");
+  write(l, "U[k,2r-1]", "x3+z2x+x*(y^(2*k+1))+a*x2*(y^(k+1))+b*(y^(3*k+r+2))+c*z*(y^(2*k+r+1))");
+  write(l, "U[k,2r]", "x3+z2x+x*(y^(2*k+1))+a*x2*(y^(k+1))+b*z*(y^(2*k+r+1))+c*z2*(y^(k+r))");
+  write(l, "U[12k+4]", "x3+z2x+y^(3*k+2)+a*x*(y^(2*k+2))+b*z*(y^(2*k+2))+c*x2*(y^(k+1))");
+  write(l, "V[1,0]", "x2y+z4+a*z3y+b*z2y2+y3z");
+  write(l, "V[1,r]", "x2y+z4+b*z3y+z2y2+a*(y^(r+4))");
+  write(l, "V#[1,2r-1]", "x2y+z3y+a*z2y2+y4+b*x*(z^(r+2))");
+  write(l, "V#[1,2r]", "x2y+z3y+a*z2y2+y4+b*(z^(r+4))");
+  write(l, "T[k,r,s]", "x^k+y^r+z^s+xyz");
+
+  s = "crk=2; Mu=6*k+1; MlnCd=1,2*k,2*k";
+  write(l, "I_E[6k+1]", s);
+//"I_E[6k+1]=", read(l, "I_E[6k+1]");
+  s = "crk=2; Mu=6*k+2; MlnCd=1,2*k+1,2*k-1";
+  write(l, "I_E[6k+2]", s);
+  s = "crk=2; Mu=6*k-2; MlnCd=1,2*k-1,2*k-1";
+  write(l, "I_J[k,0]", s);
+//"I_J[k,0]=", read(l, "I_J[k,0]");
+  s = "crk=2; Mu=6*k-2+r; MlnCd=1,2*k-1,2*k-1+r";
+  write(l, "I_J[k,r]", s);
+//"I_J[k,r]=", read(l, "I_J[k,r]");
+  s = "crk=2; Mu=9; MlnCd=1,1,1,1,1";
+  write(l, "I_X[1,0]", s);
+  s = "crk=2; Mu=9+r; MlnCd=1,1,1,1,1+r";
+  write(l, "I_X[1,r]", s);
+  s = "crk=2; Mu=12*k-3; MlnCd=1,1,2*k-1,2*k-1,2*k-1";
+  write(l, "I_X[k,0]", s);
+  s = "crk=2; Mu=12*k-3+r; MlnCd=1,1,2*k-1,2*k-1,2*k-1+r";
+  write(l, "I_X[k,r]", s);
+  s = "crk=2; Mu=12*k;";
+  write(l, "I_W[12k]", s);
+  s = "crk=2; Mu=12*k+1;";
+  write(l, "I_W[12k+1]", s);
+  s = "crk=2; Mu=12*k+5;";
+  write(l, "I_W[12k+5]", s);
+  s = "crk=2; Mu=12*k+6;";
+  write(l, "I_W[12k+6]", s);
+  s = "crk=2; Mu=12*k+3;";
+  write(l, "I_W[k,0]", s);
+  s = "crk=2; Mu=12*k+3+r;";
+  write(l, "I_W[k,r]", s);
+  s = "crk=2; Mu=12*k+2+2*r;";
+  write(l, "I_W#[k,2r-1]", s);
+  s = "crk=2; Mu=12*k+3+2*r;";
+  write(l, "I_W#[k,2r]", s);
+  s = "crk=2; Mu=9+r+s;";
+  write(l, "I_Y[1,r,s]", s);
+  s = "crk=2; Mu=12*k-3+r+s;";
+  write(l, "I_Y[k,r,s]", s);
+  s = "crk=2; Mu=15;";
+  write(l, "I_Z[1,0]", s);
+  s = "crk=2; Mu=15+r;";
+  write(l, "I_Z[1,r]", s);
+  s = "crk=2; Mu=9+6*k+r;";
+  write(l, "I_Z[k,r]", s);
+  s = "crk=2; Mu=12*k+6*r-3;";
+  write(l, "I_Z[k,r,0]", s);
+  s = "crk=2; Mu=12*k+6*r+s-3;";
+  write(l, "I_Z[k,r,s]", s);
+  s = "crk=2; Mu=12*k+6*r-1;";
+  write(l, "I_Z[k,12k+6r-1]", s);
+  s = "crk=2; Mu=12*k+6*r;";
+  write(l, "I_Z[k,12k+6r]", s);
+  s = "crk=2; Mu=12*k+6*r+1;";
+  write(l, "I_Z[k,12k+6r+1]", s);
+  s = "crk=2; Mu=9+6*k;";
+  write(l, "I_Z[k,0]", s);
+  s = "crk=2; Mu=6*(r+1)-1;";
+  write(l, "I_Z[6k+5]", s);
+  s = "crk=2; Mu=6*(r+1);";
+  write(l, "I_Z[6k+6]", s);
+  s = "crk=2; Mu=6*(r+1)+1;";
+  write(l, "I_Z[6k+7]", s);
+  s = "crk=3; Mu=6*k+2;";
+  write(l, "I_Q[k,0]", s);
+  s = "crk=3; Mu=6*k+2+r;";
+  write(l, "I_Q[k,r]", s);
+  s = "crk=3; Mu=6*k+4;";
+  write(l, "I_Q[6k+4]", s);
+  s = "crk=3; Mu=6*k+5;";
+  write(l, "I_Q[6k+5]", s);
+  s = "crk=3; Mu=6*k+6;";
+  write(l, "I_Q[6k+6]", s);
+  s = "crk=3; Mu=12*k-1;";
+  write(l, "I_S[12k-1]", s);
+  s = "crk=3; Mu=12*k;";
+  write(l, "I_S[12k]", s);
+  s = "crk=3; Mu=12*k+2;";
+  write(l, "I_S[k,0]", s);
+  s = "crk=3; Mu=12*k+2+r;";
+  write(l, "I_S[k,r]", s);
+  s = "crk=3; Mu=12*k+2*r+1;";
+  write(l, "I_S#[k,2r-1]", s);
+  s = "crk=3; Mu=12*k+2*r+2;";
+  write(l, "I_S#[k,2r]", s);
+  s = "crk=3; Mu=12*k+4;";
+  write(l, "I_S[12k+4]", s);
+  s = "crk=3; Mu=12*k+5;";
+  write(l, "I_S[12k+5]", s);
+  s = "crk=3; Mu=12*k;";
+  write(l, "I_U[12k]", s);
+  s = "crk=3; Mu=12*k+4;";
+  write(l, "I_U[12k+4]", s);
+  s = "crk=3; Mu=12*k+1+2*r;";
+  write(l, "I_U[k,2r-1]", s);
+  s = "crk=3; Mu=12*k+2+2*r;";
+  write(l, "I_U[k,2r]", s);
+  s = "crk=3; Mu=15;";
+  write(l, "I_V[1,0]", s);
+  s = "crk=3; Mu=15+r;";
+  write(l, "I_V[1,r]", s);
+  s = "crk=3; Mu=14+2*r;";
+  write(l, "I_V#[1,2r-1]", s);
+  s = "crk=3; Mu=15+2*r;";
+  write(l, "I_V#[1,2r]", s);
+  s = "crk=3; Mu=0;";
+  write(l, "I_T[k,r,s]", s);
+  write(l,"VERSION", "1.0");
+  close(l);
+}
+
+proc read_sing_dbm
+{
+  link l="DBM: NFlist";
+  "A[k]     = "+read(l, "A[k]");
+  "D[k]     = "+read(l, "D[k]");
+  "E[6k]    = "+read(l, "E[6k]");
+  "E[6k+1]  = "+read(l, "E[6k+1]");
+  "E[6k+2]  = "+read(l, "E[6k+2]");
+  "J[k,0]   = "+read(l, "J[k,0]");
+  "J[k,r]   = "+read(l, "J[k,r]");
+  "X[1,0]   = "+read(l, "X[1,0]");
+  "X[1,r]   = "+read(l, "X[1,r]");
+  "X[k,0]   = "+read(l, "X[k,0]");
+  "X[k,r]   = "+read(l, "X[k,r]");
+  "W[12k]   = "+read(l, "W[12k]");
+  "W[12k+1] = "+read(l, "W[12k+1]");
+  "W[12k+5] = "+read(l, "W[12k+5]");
+  "W[12k+6] = "+read(l, "W[12k+6]");
+  "W[k,0]   = "+read(l, "W[k,0]");
+  "W[k,r]   = "+read(l, "W[k,r]");
+  "W#[k,2r-1]   = "+read(l, "W#[k,2r-1]");
+  "W#[k,2r] = "+read(l, "W#[k,2r]");
+  "Y[1,r,s] = "+read(l, "Y[1,r,s]");
+  "Y[k,r,s] = "+read(l, "Y[k,r,s]");
+  "Z[1,0]   = "+read(l, "Z[1,0]");
+  "Z[1,r]   = "+read(l, "Z[1,r]");
+  "Z[k,r,s] = "+read(l, "Z[k,r,s]");
+  "Z[k,r,0] = "+read(l, "Z[k,r,0]");
+  "Z[k,12k+6r-1]= "+read(l, "Z[k,12k+6r-1]");
+  "Z[k,12k+6r]  = "+read(l, "Z[k,12k+6r]");
+  "Z[k,12k+6r+1]= "+read(l, "Z[k,12k+6r+1]");
+  "Z[k,0]   = "+read(l, "Z[k,0]");
+  "Z[k,r]   = "+read(l, "Z[k,r]");
+  "Z[6k+5]  = "+read(l, "Z[6k+5]");
+  "Z[6k+6]  = "+read(l, "Z[6k+6]");
+  "Z[6k+7]  = "+read(l, "Z[6k+7]");
+  "Q[k,0]   = "+read(l, "Q[k,0]");
+  "Q[k,r]   = "+read(l, "Q[k,r]");
+  "Q[6k+4]  = "+read(l, "Q[6k+4]");
+  "Q[6k+5]  = "+read(l, "Q[6k+5]");
+  "Q[6k+6]  = "+read(l, "Q[6k+6]");
+  "S[12k-1] = "+read(l, "S[12k-1]");
+  "S[12k]   = "+read(l, "S[12k]");
+  "S[k,0]   = "+read(l, "S[k,0]");
+  "S[k,r]   = "+read(l, "S[k,r]");
+  "S#[k,2r-1]   = "+read(l, "S#[k,2r-1]");
+  "S#[k,2r] = "+read(l, "S#[k,2r]");
+  "S[12k+4] = "+read(l, "S[12k+4]");
+  "S[12k+5] = "+read(l, "S[12k+5]");
+  "U[12k]   = "+read(l, "U[12k]");
+  "U[k,2r-1]= "+read(l, "U[k,2r-1]");
+  "U[k,2r]  = "+read(l, "U[k,2r]");
+  "U[12k+4] = "+read(l, "U[12k+4]");
+  "V[1,0]   = "+read(l, "V[1,0]");
+  "V[1,r]   = "+read(l, "V[1,r]");
+  "V#[1,2r-1]   = "+read(l, "V#[1,2r-1]");
+  "V#[1,2r] = "+read(l, "V#[1,2r]");
+  "T[k,r,s] = "+read(l, "T[k,r,s]");
+  close(l);
+}
diff --git a/Singular/LIB/matrix.lib b/Singular/LIB/matrix.lib
new file mode 100644
index 0000000..06d5dfb
--- /dev/null
+++ b/Singular/LIB/matrix.lib
@@ -0,0 +1,1397 @@
+//////////////////////////////////////////////////////////////////////////////
+version="version matrix.lib 4.0.0.0 Jun_2013 "; // $Id: e142e87a157b0b44f7a346cad1623353ddc530b0 $
+category="Linear Algebra";
+info="
+LIBRARY:  matrix.lib    Elementary Matrix Operations
+
+PROCEDURES:
+ compress(A);           matrix, zero columns from A deleted
+ concat(A1,A2,..);      matrix, concatenation of matrices A1,A2,...
+ diag(p,n);             matrix, nxn diagonal matrix with entries poly p
+ dsum(A1,A2,..);        matrix, direct sum of matrices A1,A2,...
+ flatten(A);            ideal, generated by entries of matrix A
+ genericmat(n,m[,id]);  generic nxm matrix [entries from id]
+ is_complex(c);         1 if list c is a complex, 0 if not
+ outer(A,B);            matrix, outer product of matrices A and B
+ power(A,n);            matrix/intmat, n-th power of matrix/intmat A
+ skewmat(n[,id]);       generic skew-symmetric nxn matrix [entries from id]
+ submat(A,r,c);         submatrix of A with rows/cols specified by intvec r/c
+ symmat(n[,id]);        generic symmetric nxn matrix [entries from id]
+ tensor(A,B);           matrix, tensor product of matrices A nd B
+ unitmat(n);            unit square matrix of size n
+ gauss_col(A);          transform a matrix into col-reduced Gauss normal form
+ gauss_row(A);          transform a matrix into row-reduced Gauss normal form
+ addcol(A,c1,p,c2);     add p*(c1-th col) to c2-th column of matrix A, p poly
+ addrow(A,r1,p,r2);     add p*(r1-th row) to r2-th row of matrix A, p poly
+ multcol(A,c,p);        multiply c-th column of A with poly p
+ multrow(A,r,p);        multiply r-th row of A with poly p
+ permcol(A,i,j);        permute i-th and j-th columns
+ permrow(A,i,j);        permute i-th and j-th rows
+ rowred(A[,any]);       reduction of matrix A with elementary row-operations
+ colred(A[,any]);       reduction of matrix A with elementary col-operations
+ linear_relations(E);   find linear relations between homogeneous vectors
+ rm_unitrow(A);         remove unit rows and associated columns of A
+ rm_unitcol(A);         remove unit columns and associated rows of A
+ headStand(A);          A[n-i+1,m-j+1]:=A[i,j]
+ symmetricBasis(n,k[,s]); basis of k-th symmetric power of n-dim v.space
+ exteriorBasis(n,k[,s]); basis of k-th exterior power of n-dim v.space
+ symmetricPower(A,k);   k-th symmetric power of a module/matrix A
+ exteriorPower(A,k);    k-th exterior power of a module/matrix A
+          (parameters in square brackets [] are optional)
+";
+
+LIB "inout.lib";
+LIB "ring.lib";
+LIB "random.lib";
+LIB "general.lib"; // for sort
+LIB "nctools.lib"; // for superCommutative
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc compress (def A)
+"USAGE:   compress(A); A matrix/ideal/module/intmat/intvec
+RETURN:  same type, zero columns/generators from A deleted
+         (if A=intvec, zero elements are deleted)
+EXAMPLE: example compress; shows an example
+"
+{
+   if( typeof(A)=="matrix" ) { return(matrix(simplify(A,2))); }
+   if( typeof(A)=="intmat" or typeof(A)=="intvec" )
+   {
+      ring r=0,x,lp;
+      if( typeof(A)=="intvec" ) { intmat C=transpose(A); kill A; intmat A=C; }
+      module m = matrix(A);
+      if ( size(m) == 0)
+      { intmat B; }
+      else
+      { intmat B[nrows(A)][size(m)]; }
+      int i,j;
+      for( i=1; i<=ncols(A); i++ )
+      {
+         if( m[i]!=[0] )
+         {
+            j++;
+            B[1..nrows(A),j]=A[1..nrows(A),i];
+         }
+      }
+      if( defined(C) ) { return(intvec(B)); }
+      return(B);
+    }
+   return(simplify(A,2));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r=0,(x,y,z),ds;
+   matrix A[3][4]=1,0,3,0,x,0,z,0,x2,0,z2,0;
+   print(A);
+   print(compress(A));
+   module m=module(A); show(m);
+   show(compress(m));
+   intmat B[3][4]=1,0,3,0,4,0,5,0,6,0,7,0;
+   compress(B);
+   intvec C=0,0,1,2,0,3;
+   compress(C);
+}
+///////////////////////////////////////////////////////////////////////////////
+proc concat (list #)
+"USAGE:   concat(A1,A2,..); A1,A2,... matrices
+RETURN:  matrix, concatenation of A1,A2,.... Number of rows of result matrix
+         is max(nrows(A1),nrows(A2),...)
+EXAMPLE: example concat; shows an example
+"
+{
+   int i;
+   for( i=size(#);i>0; i-- ) { #[i]=module(#[i]); }
+   module B=#[1..size(#)];
+   return(matrix(B));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r=0,(x,y,z),ds;
+   matrix A[3][3]=1,2,3,x,y,z,x2,y2,z2;
+   matrix B[2][2]=1,0,2,0; matrix C[1][4]=4,5,x,y;
+   print(A);
+   print(B);
+   print(C);
+   print(concat(A,B,C));
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc diag (list #)
+"USAGE:   diag(p,n); p poly, n integer
+         diag(A);   A matrix
+RETURN:  diag(p,n): diagonal matrix, p times unit matrix of size n.
+@*       diag(A)  : n*m x n*m diagonal matrix with entries all the entries of
+                    the nxm matrix A, taken from the 1st row, 2nd row etc of A
+EXAMPLE: example diag; shows an example
+"
+{
+   if( size(#)==2 ) { return(matrix(#[1]*freemodule(#[2]))); }
+   if( size(#)==1 )
+   {
+      int i; ideal id=#[1];
+      int n=ncols(id); matrix A[n][n];
+      for( i=1; i<=n; i++ ) { A[i,i]=id[i]; }
+   }
+   return(A);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r = 0,(x,y,z),ds;
+   print(diag(xy,4));
+   matrix A[3][2] = 1,2,3,4,5,6;
+   print(A);
+   print(diag(A));
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc dsum (list #)
+"USAGE:   dsum(A1,A2,..); A1,A2,... matrices
+RETURN:  matrix, direct sum of A1,A2,...
+EXAMPLE: example dsum; shows an example
+"
+{
+   int i,N,a;
+   list L;
+   for( i=1; i<=size(#); i++ ) { N=N+nrows(#[i]); }
+   for( i=1; i<=size(#); i++ )
+   {
+      matrix B[N][ncols(#[i])];
+      B[a+1..a+nrows(#[i]),1..ncols(#[i])]=#[i];
+      a=a+nrows(#[i]);
+      L[i]=B; kill B;
+   }
+   return(concat(L));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r = 0,(x,y,z),ds;
+   matrix A[3][3] = 1,2,3,4,5,6,7,8,9;
+   matrix B[2][2] = 1,x,y,z;
+   print(A);
+   print(B);
+   print(dsum(A,B));
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc flatten (def A)
+"USAGE:   flatten(A); A matrix
+RETURN:  ideal, generated by all entries from A
+EXAMPLE: example flatten; shows an example
+"
+{
+   return(ideal(A));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r = 0,(x,y,z),ds;
+   matrix A[2][3] = 1,2,x,y,z,7;
+   print(A);
+   flatten(A);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc genericmat (int n,int m,list #)
+"USAGE:   genericmat(n,m[,id]);  n,m=integers, id=ideal
+RETURN:  nxm matrix, with entries from id.
+NOTE:    if id has less than nxm elements, the matrix is filled with 0's,
+         (default: id=maxideal(1)).
+         genericmat(n,m); creates the generic nxm matrix
+EXAMPLE: example genericmat; shows an example
+"
+{
+   if( size(#)==0 ) { ideal id=maxideal(1); }
+   if( size(#)==1 ) { ideal id=#[1]; }
+   if( size(#)>=2 ) { "// give 3 arguments, 3-rd argument must be an ideal"; }
+   matrix B[n][m]=id;
+   return(B);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring R = 0,x(1..16),lp;
+   print(genericmat(3,3));      // the generic 3x3 matrix
+   ring R1 = 0,(a,b,c,d),dp;
+   matrix A = genericmat(3,4,maxideal(1)^3);
+   print(A);
+   int n,m = 3,2;
+   ideal i = ideal(randommat(1,n*m,maxideal(1),9));
+   print(genericmat(n,m,i));    // matrix of generic linear forms
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc is_complex (list c)
+"USAGE:   is_complex(c); c = list of size-compatible modules or matrices
+RETURN:  1 if c[i]*c[i+1]=0 for all i, 0 if not, hence checking whether the
+         list of matrices forms a complex.
+NOTE:    Ideals are treated internally as 1-line matrices.
+         If printlevel > 0, the position where c is not a complex is shown.
+EXAMPLE: example is_complex; shows an example
+"
+{
+   int i;
+   module @test;
+   for( i=1; i<=size(c)-1; i++ )
+   {
+      c[i]=matrix(c[i]); c[i+1]=matrix(c[i+1]);
+      @test=c[i]*c[i+1];
+      if (size(@test)!=0)
+      {
+        dbprint(printlevel-voice+2,"// not a complex at position " +string(i));
+         return(0);
+      }
+   }
+   return(1);
+}
+example
+{ "EXAMPLE:";   echo = 2;
+   ring r  = 32003,(x,y,z),ds;
+   ideal i = x4+y5+z6,xyz,yx2+xz2+zy7;
+   list L  = nres(i,0);
+   is_complex(L);
+   L[4]    = matrix(i);
+   is_complex(L);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc outer (matrix A, matrix B)
+"USAGE:   outer(A,B); A,B matrices
+RETURN:  matrix, outer (tensor) product of A and B
+EXAMPLE: example outer; shows an example
+"
+{
+   int i,j; list L;
+   int triv = nrows(B)*ncols(B);
+   if( triv==1 )
+   {
+     return(B[1,1]*A);
+   }
+   else
+   {
+     int N = nrows(A)*nrows(B);
+     matrix C[N][ncols(B)];
+     for( i=ncols(A);i>0; i-- )
+     {
+       for( j=1; j<=nrows(A); j++ )
+       {
+          C[(j-1)*nrows(B)+1..j*nrows(B),1..ncols(B)]=A[j,i]*B;
+       }
+       L[i]=C;
+     }
+     return(concat(L));
+   }
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r=32003,(x,y,z),ds;
+   matrix A[3][3]=1,2,3,4,5,6,7,8,9;
+   matrix B[2][2]=x,y,0,z;
+   print(A);
+   print(B);
+   print(outer(A,B));
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc power (def A, int n)
+"USAGE:   power(A,n);  A a square-matrix of type intmat or matrix, n=integer>=0
+RETURN:  intmat resp. matrix, the n-th power of A
+NOTE:    for A=intmat and big n the result may be wrong because of int overflow
+EXAMPLE: example power; shows an example
+"
+{
+//---------------------------- type checking ----------------------------------
+   if( typeof(A)!="matrix" and typeof(A)!="intmat" )
+   {
+      ERROR("no matrix or intmat!");
+   }
+   if( ncols(A) != nrows(A) )
+   {
+      ERROR("not a square matrix!");
+   }
+//---------------------------- trivial cases ----------------------------------
+   int ii;
+   if( n <= 0 )
+   {
+      if( typeof(A)=="matrix" )
+      {
+         return (unitmat(nrows(A)));
+      }
+      if( typeof(A)=="intmat" )
+      {
+         intmat B[nrows(A)][nrows(A)];
+         for( ii=1; ii<=nrows(A); ii++ )
+         {
+            B[ii,ii] = 1;
+         }
+         return (B);
+      }
+   }
+   if( n == 1 ) { return (A); }
+//---------------------------- sub procedure ----------------------------------
+   proc matpow (def A, int n)
+   {
+      def B = A*A;
+      int ii= 2;
+      int jj= 4;
+      while( jj <= n )
+      {
+         B=B*B;
+         ii=jj;
+         jj=2*jj;
+      }
+      return(B,n-ii);
+   }
+//----------------------------- main program ----------------------------------
+   list L = matpow(A,n);
+   def B  = L[1];
+   ii     = L[2];
+   while( ii>=2 )
+   {
+      L = matpow(A,ii);
+      B = B*L[1];
+      ii= L[2];
+   }
+   if( ii == 0) { return(B); }
+   if( ii == 1) { return(A*B); }
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   intmat A[3][3]=1,2,3,4,5,6,7,8,9;
+   print(power(A,3));"";
+   ring r=0,(x,y,z),dp;
+   matrix B[3][3]=0,x,y,z,0,0,y,z,0;
+   print(power(B,3));"";
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc skewmat (int n, list #)
+"USAGE:   skewmat(n[,id]);  n integer, id ideal
+RETURN:  skew-symmetric nxn matrix, with entries from id
+         (default: id=maxideal(1))
+         skewmat(n); creates the generic skew-symmetric matrix
+NOTE:    if id has less than n*(n-1)/2 elements, the matrix is
+         filled with 0's,
+EXAMPLE: example skewmat; shows an example
+"
+{
+   matrix B[n][n];
+   if( size(#)==0 ) { ideal id=maxideal(1); }
+   else { ideal id=#[1]; }
+   id = id,B[1..n,1..n];
+   int i,j;
+   for( i=0; i<=n-2; i++ )
+   {
+      B[i+1,i+2..n]=id[j+1..j+n-i-1];
+      j=j+n-i-1;
+   }
+   matrix A=transpose(B);
+   B=B-A;
+   return(B);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring R=0,x(1..5),lp;
+   print(skewmat(4));    // the generic skew-symmetric matrix
+   ring R1 = 0,(a,b,c),dp;
+   matrix A=skewmat(4,maxideal(1)^2);
+   print(A);
+   int n=3;
+   ideal i = ideal(randommat(1,n*(n-1) div 2,maxideal(1),9));
+   print(skewmat(n,i));  // skew matrix of generic linear forms
+   kill R1;
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc submat (matrix A, intvec r, intvec c)
+"USAGE:   submat(A,r,c);  A=matrix, r,c=intvec
+RETURN:  matrix, submatrix of A with rows specified by intvec r
+         and columns specified by intvec c.
+EXAMPLE: example submat; shows an example
+"
+{
+   matrix B[size(r)][size(c)]=A[r,c];
+   return(B);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring R=32003,(x,y,z),lp;
+   matrix A[4][4]=x,y,z,0,1,2,3,4,5,6,7,8,9,x2,y2,z2;
+   print(A);
+   intvec v=1,3,4;
+   matrix B=submat(A,v,1..3);
+   print(B);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc symmat (int n, list #)
+"USAGE:   symmat(n[,id]);  n integer, id ideal
+RETURN:  symmetric nxn matrix, with entries from id (default: id=maxideal(1))
+NOTE:    if id has less than n*(n+1)/2 elements, the matrix is filled with 0's,
+         symmat(n); creates the generic symmetric matrix
+EXAMPLE: example symmat; shows an example
+"
+{
+   matrix B[n][n];
+   if( size(#)==0 ) { ideal id=maxideal(1); }
+   else { ideal id=#[1]; }
+   id = id,B[1..n,1..n];
+   int i,j;
+   for( i=0; i<=n-1; i++ )
+   {
+      B[i+1,i+1..n]=id[j+1..j+n-i];
+      j=j+n-i;
+   }
+   matrix A=transpose(B);
+   for( i=1; i<=n; i++ ) {  A[i,i]=0; }
+   B=A+B;
+   return(B);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring R=0,x(1..10),lp;
+   print(symmat(4));    // the generic symmetric matrix
+   ring R1 = 0,(a,b,c),dp;
+   matrix A=symmat(4,maxideal(1)^3);
+   print(A);
+   int n=3;
+   ideal i = ideal(randommat(1,n*(n+1) div 2,maxideal(1),9));
+   print(symmat(n,i));  // symmetric matrix of generic linear forms
+   kill R1;
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc tensor (matrix A, matrix B)
+"USAGE:   tensor(A,B); A,B matrices
+RETURN:  matrix, tensor product of A and B
+EXAMPLE: example tensor; shows an example
+"
+{
+   if (ncols(A)==0)
+   {
+     int q=nrows(A)*nrows(B);
+     matrix D[q][0];
+     return(D);
+   }
+
+   int i,j;
+   matrix C,D;
+   for( i=1; i<=nrows(A); i++ )
+   {
+     C = A[i,1]*B;
+     for( j=2; j<=ncols(A); j++ )
+     {
+       C = concat(C,A[i,j]*B);
+     }
+     D = concat(D,transpose(C));
+   }
+   D = transpose(D);
+   return(submat(D,2..nrows(D),1..ncols(D)));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r=32003,(x,y,z),(c,ds);
+   matrix A[3][3]=1,2,3,4,5,6,7,8,9;
+   matrix B[2][2]=x,y,0,z;
+   print(A);
+   print(B);
+   print(tensor(A,B));
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc unitmat (int n)
+"USAGE:   unitmat(n);  n integer >= 0
+RETURN:  nxn unit matrix
+NOTE:    needs a basering, diagonal entries are numbers (=1) in the basering
+EXAMPLE: example unitmat; shows an example
+"
+{
+   return(matrix(freemodule(n)));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r=32003,(x,y,z),lp;
+   print(xyz*unitmat(4));
+   print(unitmat(5));
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc gauss_col (matrix A, list #)
+"USAGE:   gauss_col(A[,e]); A a matrix, e any type
+RETURN:  - a matrix B, if called with one argument; B is the complete column-
+           reduced upper-triangular normal form of A if A is constant,
+           (resp. as far as this is possible if A is a polynomial matrix;
+           no division by polynomials).
+@*       - a list L of two matrices, if called with two arguments;
+           L satisfies L[1] = A * L[2] with L[1] the column-reduced form of A
+           and L[2] the transformation matrix.
+NOTE:    * The procedure just applies interred to A with ordering (C,dp).
+           The transformation matrix is obtained by applying 'lift'.
+           This should be faster than the procedure colred.
+@*       * It should only be used with exact coefficient field (there is no
+           pivoting and rounding error treatment).
+@*       * Parameters are allowed. Hence, if the entries of A are parameters,
+           B is the column-reduced form of A over the rational function field.
+SEE ALSO:  colred
+EXAMPLE: example gauss_col; shows an example
+"
+{
+   def R=basering; int u;
+   string mp = string(minpoly);
+   int n = nrows(A);
+   int m = ncols(A);
+   module M = A;
+   intvec v = option(get);
+//------------------------ change ordering if necessary ----------------------
+   if( ordstr(R) != ("C,dp("+string(nvars(R))+")") )
+   {
+     def @R=changeord(list(list("C",0:1),list("dp",1:nvars(R))),R);
+     setring @R; u=1;
+     if (mp!="0") { execute("minpoly="+mp+";");}
+     matrix A = imap(R,A);
+     module M = A;
+   }
+//------------------------------ start computation ---------------------------
+   option(redSB);
+   M = simplify(interred(M),1);
+   if(size(#) != 0)
+   {
+      module N = lift(A,M);
+   }
+//--------------- reset ring and options and return --------------------------
+   if ( u==1 )
+   {
+      setring R;
+      M=imap(@R,M);
+      if (size(#) != 0)
+      {
+         module N = imap(@R,N);
+      }
+      kill @R;
+   }
+   option(set,v);
+   // M = sort(M,size(M)..1)[1];
+   A = matrix(M,n,m);
+   if (size(#) != 0)
+   {
+     list L= A,matrix(N,m,m);
+     return(L);
+   }
+   return(matrix(M,n,m));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r=(0,a,b),(A,B,C),dp;
+   matrix m[8][6]=
+   0,    2*C, 0,    0,  0,   0,
+   0,    -4*C,a*A,  0,  0,   0,
+   b*B,  -A,  0,    0,  0,   0,
+   -A,   B,   0,    0,  0,   0,
+   -4*C, 0,   B,    2,  0,   0,
+   2*A,  B,   0,    0,  0,   0,
+   0,    3*B, 0,    0,  2b,  0,
+   0,    AB,  0,    2*A,A,   2a;"";
+   list L=gauss_col(m,1);
+   print(L[1]);
+   print(L[2]);
+
+   ring S=0,x,(c,dp);
+   matrix A[5][4] =
+    3, 1, 1, 1,
+   13, 8, 6,-7,
+   14,10, 6,-7,
+    7, 4, 3,-3,
+    2, 1, 0, 3;
+   print(gauss_col(A));
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc gauss_row (matrix A, list #)
+"USAGE:  gauss_row(A [,e]); A matrix, e any type
+RETURN: - a matrix B, if called with one argument; B is the complete row-
+          reduced lower-triangular normal form of A if A is constant,
+          (resp. as far as this is possible if A is a polynomial matrix;
+          no division by polynomials).
+@*      - a list L of two matrices, if called with two arguments;
+          L satisfies transpose(L[2])*A=transpose(L[1])
+          with L[1] the row-reduced form of A
+          and L[2] the transformation matrix.
+NOTE:   * This procedure just applies gauss_col to the transposed matrix.
+          The transformation matrix is obtained by applying lift.
+          This should be faster than the procedure rowred.
+@*      * It should only be used with exact coefficient field (there is no
+          pivoting and rounding error treatment).
+@*      * Parameters are allowed. Hence, if the entries of A are parameters,
+          B is the row-reduced form of A over the rational function field.
+SEE ALSO: rowred
+EXAMPLE: example gauss_row; shows an example
+"
+{
+   if(size(#) > 0)
+   {
+     list L = gauss_col(transpose(A),1);
+     return(L);
+   }
+   A = gauss_col(transpose(A));
+   return(transpose(A));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r=(0,a,b),(A,B,C),dp;
+   matrix m[6][8]=
+   0, 0,  b*B, -A,-4C,2A,0, 0,
+   2C,-4C,-A,B, 0,  B, 3B,AB,
+   0,a*A,  0, 0, B,  0, 0, 0,
+   0, 0,  0, 0, 2,  0, 0, 2A,
+   0, 0,  0, 0, 0,  0, 2b, A,
+   0, 0,  0, 0, 0,  0, 0, 2a;"";
+   print(gauss_row(m));"";
+   ring S=0,x,dp;
+   matrix A[4][5] =  3, 1,1,-1,2,
+                    13, 8,6,-7,1,
+                    14,10,6,-7,1,
+                     7, 4,3,-3,3;
+   list L=gauss_row(A,1);
+   print(L[1]);
+   print(L[2]);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc addcol (matrix A, int c1, poly p, int c2)
+"USAGE:   addcol(A,c1,p,c2);  A matrix, p poly, c1, c2 positive integers
+RETURN:  matrix,  A being modified by adding p times column c1 to column c2
+EXAMPLE: example addcol; shows an example
+"
+{
+   int k=nrows(A);
+   A[1..k,c2]=A[1..k,c2]+p*A[1..k,c1];
+   return(A);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r=32003,(x,y,z),lp;
+   matrix A[3][3]=1,2,3,4,5,6,7,8,9;
+   print(A);
+   print(addcol(A,1,xy,2));
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc addrow (matrix A, int r1, poly p, int r2)
+"USAGE:   addrow(A,r1,p,r2);  A matrix, p poly, r1, r2 positive integers
+RETURN:  matrix,  A being modified by adding p times row r1 to row r2
+EXAMPLE: example addrow; shows an example
+"
+{
+   int k=ncols(A);
+   A[r2,1..k]=A[r2,1..k]+p*A[r1,1..k];
+   return(A);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r=32003,(x,y,z),lp;
+   matrix A[3][3]=1,2,3,4,5,6,7,8,9;
+   print(A);
+   print(addrow(A,1,xy,3));
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc multcol (matrix A, int c, poly p)
+"USAGE:   multcol(A,c,p);  A matrix, p poly, c positive integer
+RETURN:  matrix,  A being modified by multiplying column c by p
+EXAMPLE: example multcol; shows an example
+"
+{
+   int k=nrows(A);
+   A[1..k,c]=p*A[1..k,c];
+   return(A);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r=32003,(x,y,z),lp;
+   matrix A[3][3]=1,2,3,4,5,6,7,8,9;
+   print(A);
+   print(multcol(A,2,xy));
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc multrow (matrix A, int r, poly p)
+"USAGE:   multrow(A,r,p);  A matrix, p poly, r positive integer
+RETURN:  matrix,  A being modified by multiplying row r by p
+EXAMPLE: example multrow; shows an example
+"
+{
+   int k=ncols(A);
+   A[r,1..k]=p*A[r,1..k];
+   return(A);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r=32003,(x,y,z),lp;
+   matrix A[3][3]=1,2,3,4,5,6,7,8,9;
+   print(A);
+   print(multrow(A,2,xy));
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc permcol (matrix A, int c1, int c2)
+"USAGE:   permcol(A,c1,c2);  A matrix, c1,c2 positive integers
+RETURN:  matrix,  A being modified by permuting columns c1 and c2
+EXAMPLE: example permcol; shows an example
+"
+{
+   matrix B=A;
+   int k=nrows(B);
+   B[1..k,c1]=A[1..k,c2];
+   B[1..k,c2]=A[1..k,c1];
+   return(B);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r=32003,(x,y,z),lp;
+   matrix A[3][3]=1,x,3,4,y,6,7,z,9;
+   print(A);
+   print(permcol(A,2,3));
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc permrow (matrix A, int r1, int r2)
+"USAGE:   permrow(A,r1,r2);  A matrix, r1,r2 positive integers
+RETURN:  matrix,  A being modified by permuting rows r1 and r2
+EXAMPLE: example permrow; shows an example
+"
+{
+   matrix B=A;
+   int k=ncols(B);
+   B[r1,1..k]=A[r2,1..k];
+   B[r2,1..k]=A[r1,1..k];
+   return(B);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r=32003,(x,y,z),lp;
+   matrix A[3][3]=1,2,3,x,y,z,7,8,9;
+   print(A);
+   print(permrow(A,2,1));
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc rowred (matrix A,list #)
+"USAGE:   rowred(A[,e]);  A matrix, e any type
+RETURN:  - a matrix B, being the row reduced form of A, if rowred is called
+           with one argument.
+           (as far as this is possible over the polynomial ring; no division
+           by polynomials)
+@*       - a list L of two matrices, such that L[1] = L[2] * A with L[1]
+           the row-reduced form of A and L[2] the transformation matrix
+           (if rowred is called with two arguments).
+ASSUME:  The entries of A are in the base field. It is not verified whether
+         this assumption holds.
+NOTE:    * This procedure is designed for teaching purposes mainly.
+@*       * The straight forward Gaussian algorithm is implemented in the
+           library (no standard basis computation).
+           The transformation matrix is obtained by concatenating a unit
+           matrix to A. proc gauss_row should be faster.
+@*       * It should only be used with exact coefficient field (there is no
+           pivoting) over the polynomial ring (ordering lp or dp).
+@*       * Parameters are allowed. Hence, if the entries of A are parameters
+           the computation takes place over the field of rational functions.
+SEE ALSO:  gauss_row
+EXAMPLE: example rowred; shows an example
+"
+{
+   int m,n=nrows(A),ncols(A);
+   int i,j,k,l,rk;
+   poly p;
+   matrix d[m][n];
+   for (i=1;i<=m;i++)
+   {  for (j=1;j<=n;j++)
+      {  p = A[i,j];
+         if (ord(p)==0)
+         {  if (deg(p)==0) { d[i,j]=p; }
+         }
+      }
+   }
+   matrix b = A;
+   if (size(#) != 0) { b = concat(b,unitmat(m)); }
+      for (l=1;l<=n;l=l+1)
+   {
+      k  = findfirst(ideal(d[l]),rk+1);
+      if (k)
+      {  rk = rk+1;
+         b  = permrow(b,rk,k);
+         p  = b[rk,l];         p = 1/p;
+         b  = multrow(b,rk,p);
+         for (i=1;i<=m;i++)
+         {
+            if (rk-i) { b = addrow(b,rk,-b[i,l],i);}
+         }
+         d = 0;
+         for (i=rk+1;i<=m;i++)
+         {  for (j=l+1;j<=n;j++)
+            {  p = b[i,j];
+               if (ord(p)==0)
+               {  if (deg(p)==0) { d[i,j]=p; }
+               }
+            }
+         }
+
+      }
+   }
+   d = submat(b,1..m,1..n);
+   if (size(#))
+   {
+      list L=d,submat(b,1..m,n+1..n+m);
+      return(L);
+   }
+   return(d);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r=(0,a,b),(A,B,C),dp;
+   matrix m[6][8]=
+   0, 0,  b*B, -A,-4C,2A,0, 0,
+   2C,-4C,-A,B, 0,  B, 3B,AB,
+   0,a*A,  0, 0, B,  0, 0, 0,
+   0, 0,  0, 0, 2,  0, 0, 2A,
+   0, 0,  0, 0, 0,  0, 2b, A,
+   0, 0,  0, 0, 0,  0, 0, 2a;"";
+   print(rowred(m));"";
+   list L=rowred(m,1);
+   print(L[1]);
+   print(L[2]);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc colred (matrix A,list #)
+"USAGE:   colred(A[,e]);  A matrix, e any type
+RETURN:  - a matrix B, being the column reduced form of A, if colred is
+           called with one argument.
+           (as far as this is possible over the polynomial ring;
+           no division by polynomials)
+@*       - a list L of two matrices, such that L[1] = A * L[2] with L[1]
+           the column-reduced form of A and L[2] the transformation matrix
+           (if colred is called with two arguments).
+ASSUME:  The entries of A are in the base field. It is not verified whether
+         this assumption holds.
+NOTE:    * This procedure is designed for teaching purposes mainly.
+@*       * It applies rowred to the transposed matrix.
+           proc gauss_col should be faster.
+@*       * It should only be used with exact coefficient field (there is no
+           pivoting) over the polynomial ring (ordering lp or dp).
+@*       * Parameters are allowed. Hence, if the entries of A are parameters
+           the computation takes place over the field of rational functions.
+SEE ALSO:  gauss_col
+EXAMPLE: example colred; shows an example
+"
+{
+   A = transpose(A);
+   if (size(#))
+   { list L = rowred(A,1); return(transpose(L[1]),transpose(L[2]));}
+   else
+   { return(transpose(rowred(A)));}
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r=(0,a,b),(A,B,C),dp;
+   matrix m[8][6]=
+   0,    2*C, 0,    0,  0,   0,
+   0,    -4*C,a*A,  0,  0,   0,
+   b*B,  -A,  0,    0,  0,   0,
+   -A,   B,   0,    0,  0,   0,
+   -4*C, 0,   B,    2,  0,   0,
+   2*A,  B,   0,    0,  0,   0,
+   0,    3*B, 0,    0,  2b,  0,
+   0,    AB,  0,    2*A,A,   2a;"";
+   print(colred(m));"";
+   list L=colred(m,1);
+   print(L[1]);
+   print(L[2]);
+}
+//////////////////////////////////////////////////////////////////////////////
+
+proc linear_relations(module M)
+"USAGE:   linear_relations(M);
+         M: a module
+ASSUME:  All non-zero entries of M are homogeneous polynomials of the same
+         positive degree. The base field must be an exact field (not real
+         or complex).
+         It is not checked whether these assumptions hold.
+RETURN:  a maximal module R such that M*R is formed by zero vectors.
+EXAMPLE: example linear_relations; shows an example.
+"
+{ int n = ncols(M);
+  def BaseR = basering;
+  def br = changeord(list(list("dp",1:nvars(basering))));
+  setring br;
+  module M = imap(BaseR,M);
+  ideal vars = maxideal(1);
+  ring tmpR = 0, ('y(1..n)), dp;
+  def newR = br + tmpR;
+  setring newR;
+  module M = imap(br,M);
+  ideal vars = imap(br,vars);
+  attrib(vars,"isSB",1);
+  for (int i = 1; i<=n; i++) {
+    M[i] = M[i] + 'y(i)*gen(1);
+  }
+  M = interred(M);
+  module redM = NF(M,vars);
+  module REL;
+  int sizeREL;
+  int j;
+  for (i=1; i<=n; i++) {
+    if (M[i][1]==redM[i][1]) { //-- relation found!
+      sizeREL++;
+      REL[sizeREL]=0;
+      for (j=1; j<=n; j++) {
+        REL[sizeREL] = REL[sizeREL] + (M[i][1]/'y(j))*gen(j);
+      }
+    }
+  }
+  setring BaseR;
+  return(minbase(imap(newR,REL)));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring r = (3,w), (a,b,c,d),dp;
+  minpoly = w2-w-1;
+  module M = [a2,b2],[wab,w2c2+2b2],[(w-2)*a2+wab,wb2+w2c2];
+  module REL = linear_relations(M);
+  pmat(REL);
+  pmat(M*REL);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+static proc findfirst (ideal i,int t)
+{
+   int n,k;
+   for (n=t;n<=ncols(i);n=n+1)
+   {
+      if (i[n]!=0) { k=n;break;}
+   }
+   return(k);
+}
+//////////////////////////////////////////////////////////////////////////////
+
+proc rm_unitcol(matrix A)
+"USAGE:   rm_unitcol(A); A matrix (being row-reduced)
+RETURN:  matrix, obtained from A by deleting unit columns (having just one 1
+         and else 0 as entries) and associated rows
+EXAMPLE: example rm_unitcol; shows an example
+"
+{
+ int l,j;
+ intvec v;
+ for (j=1;j<=ncols(A);j++)
+ {
+    if (gen(l+1)==module(A)[j]) {l=l+1;}
+    else { v=v,j;}
+ }
+ if (size(v)>1)
+    {  v = v[2..size(v)];
+       return(submat(A,l+1..nrows(A),v));
+    }
+ else
+    { return(0);}
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r=0,(A,B,C),dp;
+   matrix m[6][8]=
+   0,  0,    A,   0, 1,0,  0,0,
+   0,  0,  -C2,   0, 0,0,  1,0,
+   0,  0,    0,1/2B, 0,0,  0,1,
+   0,  0,    B,  -A, 0,2A, 0,0,
+   2C,-4C,  -A,   B, 0,B,  0,0,
+   0,  A,    0,   0, 0,0,  0,0;
+   print(rm_unitcol(m));
+}
+//////////////////////////////////////////////////////////////////////////////
+
+proc rm_unitrow (matrix A)
+"USAGE:   rm_unitrow(A); A matrix (being col-reduced)
+RETURN:  matrix, obtained from A by deleting unit rows (having just one 1
+         and else 0 as entries) and associated columns
+EXAMPLE: example rm_unitrow; shows an example
+"
+{
+ int l,j;
+ intvec v;
+ module M = transpose(A);
+ for (j=1; j <= nrows(A); j++)
+ {
+    if (gen(l+1) == M[j]) { l=l+1; }
+    else { v=v,j; }
+ }
+ if (size(v) > 1)
+    {  v = v[2..size(v)];
+       return(submat(A,v,l+1..ncols(A)));
+    }
+ else
+    { return(0);}
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r=0,(A,B,C),dp;
+   matrix m[8][6]=
+   0,0,  0,   0, 2C, 0,
+   0,0,  0,   0, -4C,A,
+   A,-C2,0,   B, -A, 0,
+   0,0,  1/2B,-A,B,  0,
+   1,0,  0,   0, 0,  0,
+   0,0,  0,   2A,B,  0,
+   0,1,  0,   0, 0,  0,
+   0,0,  1,   0, 0,  0;
+   print(rm_unitrow(m));
+}
+//////////////////////////////////////////////////////////////////////////////
+proc headStand(matrix M)
+"USAGE:   headStand(M);  M matrix
+RETURN:  matrix B such that B[i][j]=M[n-i+1,m-j+1], n=nrows(M), m=ncols(M)
+EXAMPLE: example headStand; shows an example
+"
+{
+  int i,j;
+  int n=nrows(M);
+  int m=ncols(M);
+  matrix B[n][m];
+  for(i=1;i<=n;i++)
+  {
+     for(j=1;j<=m;j++)
+     {
+        B[n-i+1,m-j+1]=M[i,j];
+     }
+  }
+  return(B);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r=0,(A,B,C),dp;
+   matrix M[2][3]=
+   0,A,  B,
+   A2, B2, C;
+   print(M);
+   print(headStand(M));
+}
+//////////////////////////////////////////////////////////////////////////////
+
+// Symmetric/Exterior powers thanks to Oleksandr Iena for his persistence ;-)
+
+proc symmetricBasis(int n, int k, list #)
+"USAGE:    symmetricBasis(n, k[,s]); n int, k int, s string
+RETURN:   ring, poynomial ring containing the ideal \"symBasis\",
+          being a basis of the k-th symmetric power of an n-dim vector space.
+NOTE:     The output polynomial ring has characteristics 0 and n variables
+          named \"S(i)\", where the base variable name S is either given by the
+          optional string argument(which must not contain brackets) or equal to
+          "e" by default.
+SEE ALSO: exteriorBasis
+KEYWORDS: symmetric basis
+EXAMPLE:  example symmetricBasis; shows an example"
+{
+//------------------------ handle optional base variable name---------------
+  string S = "e";
+  if( size(#) > 0 )
+  {
+    if( typeof(#[1]) != "string" )
+    {
+      ERROR("Wrong optional argument: must be a string");
+    }
+    S = #[1];
+    if( (find(S, "(") + find(S, ")")) > 0 )
+    {
+      ERROR("Wrong optional argument: must be a string without brackets");
+    }
+  }
+
+//------------------------- create ring container for symmetric power basis-
+  execute("ring @@@SYM_POWER_RING_NAME=(0),("+S+"(1.."+string(n)+")),dp;");
+
+//------------------------- choose symmetric basis -------------------------
+  ideal symBasis = maxideal(k);
+
+//------------------------- export and return      -------------------------
+  export symBasis;
+  return(basering);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+
+// basis of the 3-rd symmetricPower of a 4-dim vector space:
+def R = symmetricBasis(4, 3, "@e"); setring R;
+R;  // container ring:
+symBasis; // symmetric basis:
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+proc exteriorBasis(int n, int k, list #)
+"USAGE:    exteriorBasis(n, k[,s]); n int, k int, s string
+RETURN:   qring, an exterior algebra containing the ideal \"extBasis\",
+          being a basis of the k-th exterior power of an n-dim vector space.
+NOTE:     The output polynomial ring has characteristics 0 and n variables
+          named \"S(i)\", where the base variable name S is either given by the
+          optional string argument(which must not contain brackets) or equal to
+          "e" by default.
+SEE ALSO: symmetricBasis
+KEYWORDS: exterior basis
+EXAMPLE:  example exteriorBasis; shows an example"
+{
+//------------------------ handle optional base variable name---------------
+  string S = "e";
+  if( size(#) > 0 )
+  {
+    if( typeof(#[1]) != "string" )
+    {
+      ERROR("Wrong optional argument: must be a string");
+    }
+    S = #[1];
+    if( (find(S, "(") + find(S, ")")) > 0 )
+    {
+      ERROR("Wrong optional argument: must be a string without brackets");
+    }
+  }
+
+//------------------------- create ring container for symmetric power basis-
+  execute("ring @@@EXT_POWER_RING_NAME=(0),("+S+"(1.."+string(n)+")),dp;");
+
+//------------------------- choose exterior basis -------------------------
+  def T = superCommutative(); setring T;
+  ideal extBasis = simplify( NF(maxideal(k), std(0)), 1 + 2 + 8 );
+
+//------------------------- export and return      -------------------------
+  export extBasis;
+  return(basering);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+// basis of the 3-rd symmetricPower of a 4-dim vector space:
+def r = exteriorBasis(4, 3, "@e"); setring r;
+r; // container ring:
+extBasis; // exterior basis:
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+static proc chooseSafeVarName(string prefix, string suffix)
+"USAGE: give appropreate prefix for variable names
+RETURN: safe variable name (repeated prefix + suffix)
+"
+{
+  string V = varstr(basering);
+  string S = suffix;
+  while( find(V, S) > 0 )
+  {
+    S = prefix + S;
+  }
+  return(S);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+static proc mapPower(int p, module A, int k, def Tn, def Tm)
+"USAGE: by both symmetric- and exterior-Power"
+NOTE: everything over the basering!
+      module A (matrix of the map), int k (power)
+      rings Tn is source- and Tm is image-ring with bases
+          resp. Ink and Imk.
+      M = max dim of Image, N - dim. of source
+SEE ALSO: symmetricPower, exteriorPower"
+{
+  def save = basering;
+
+  int n = nvars(save);
+  int M = nrows(A);
+  int N = ncols(A);
+
+  int i, j;
+
+//------------------------- compute matrix of single images ------------------
+  def Rm = save + Tm;  setring Rm;
+  dbprint(p-2, "Temporary Working Ring", Rm);
+
+  module A = imap(save, A);
+
+  ideal B; poly t;
+
+  for( i = N; i > 0; i-- )
+  {
+    t = 0;
+    for( j = M; j > 0; j-- )
+    {
+      t = t + A[i][j] * var(n + j);
+    }
+
+    B[i] = t;
+  }
+
+  dbprint(p-1, "Matrix of single images", B);
+
+//------------------------- compute image ---------------------
+  // apply S^k(A): Tn -> Rm  to Source basis vectors Ink:
+  map TMap = Tn, B;
+
+  ideal C = NF(TMap(Ink), std(0));
+  dbprint(p-1, "Image Matrix: ", C);
+
+
+//------------------------- write it in Image basis ---------------------
+  ideal Imk = imap(Tm, Imk);
+
+  module D; poly lm; vector tt;
+
+  for( i = ncols(C); i > 0; i-- )
+  {
+    t = C[i];
+    tt = 0;
+
+    while( t != 0 )
+    {
+      lm = leadmonom(t);
+      //    lm;
+      for( j = ncols(Imk); j > 0; j-- )
+      {
+        if( lm / Imk[j] != 0 )
+        {
+          tt = tt + (lead(t) / Imk[j]) * gen(j);
+          break;
+        }
+      }
+      t = t - lead(t);
+    }
+
+    D[i] = tt;
+  }
+
+//------------------------- map it back and return  ---------------------
+  setring save;
+  return( imap(Rm, D) );
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+
+proc symmetricPower(module A, int k)
+"USAGE:    symmetricPower(A, k); A module, k int
+RETURN:   module: the k-th symmetric power of A
+NOTE:     the chosen bases and most of intermediate data will be shown if
+          printlevel is big enough
+SEE ALSO: exteriorPower
+KEYWORDS: symmetric power
+EXAMPLE:  example symmetricPower; shows an example"
+{
+  int p = printlevel - voice + 2;
+
+  def save = basering;
+
+  int M = nrows(A);
+  int N = ncols(A);
+
+  string S = chooseSafeVarName("@", "@_e");
+
+//------------------------- choose source basis -------------------------
+  def Tn = symmetricBasis(N, k, S); setring Tn;
+  ideal Ink = symBasis;
+  export Ink;
+  dbprint(p-3, "Temporary Source Ring", basering);
+  dbprint(p, "S^k(Source Basis)", Ink);
+
+//------------------------- choose image basis -------------------------
+  def Tm = symmetricBasis(M, k, S); setring Tm;
+  ideal Imk = symBasis;
+  export Imk;
+  dbprint(p-3, "Temporary Image Ring", basering);
+  dbprint(p, "S^k(Image Basis)", Imk);
+
+//------------------------- compute and return S^k(A) in chosen bases --
+  setring save;
+
+  return(mapPower(p, A, k, Tn, Tm));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+
+ring r = (0),(a, b, c, d), dp; r;
+module B = a*gen(1) + c* gen(2), b * gen(1) + d * gen(2); print(B);
+
+// symmetric power over a commutative K-algebra:
+print(symmetricPower(B, 2));
+print(symmetricPower(B, 3));
+
+// symmetric power over an exterior algebra:
+def g = superCommutative(); setring g; g;
+
+module B = a*gen(1) + c* gen(2), b * gen(1) + d * gen(2); print(B);
+
+print(symmetricPower(B, 2)); // much smaller!
+print(symmetricPower(B, 3)); // zero! (over an exterior algebra!)
+
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+proc exteriorPower(module A, int k)
+"USAGE:    exteriorPower(A, k); A module, k int
+RETURN:   module: the k-th exterior power of A
+NOTE:     the chosen bases and most of intermediate data will be shown if
+          printlevel is big enough. Last rows will be invisible if zero.
+SEE ALSO: symmetricPower
+KEYWORDS: exterior power
+EXAMPLE:  example exteriorPower; shows an example"
+{
+  int p = printlevel - voice + 2;
+  def save = basering;
+
+  int M = nrows(A);
+  int N = ncols(A);
+
+  string S = chooseSafeVarName("@", "@_e");
+
+//------------------------- choose source basis -------------------------
+  def Tn = exteriorBasis(N, k, S); setring Tn;
+  ideal Ink = extBasis;
+  export Ink;
+  dbprint(p-3, "Temporary Source Ring", basering);
+  dbprint(p, "E^k(Source Basis)", Ink);
+
+//------------------------- choose image basis -------------------------
+  def Tm = exteriorBasis(M, k, S); setring Tm;
+  ideal Imk = extBasis;
+  export Imk;
+  dbprint(p-3, "Temporary Image Ring", basering);
+  dbprint(p, "E^k(Image Basis)", Imk);
+
+//------------------------- compute and return E^k(A) in chosen bases --
+  setring save;
+  return(mapPower(p, A, k, Tn, Tm));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring r = (0),(a, b, c, d, e, f), dp;
+  r; "base ring:";
+
+  module B = a*gen(1) + c*gen(2) + e*gen(3),
+             b*gen(1) + d*gen(2) + f*gen(3),
+                        e*gen(1) + f*gen(3);
+
+  print(B);
+  print(exteriorPower(B, 2));
+  print(exteriorPower(B, 3));
+
+  def g = superCommutative(); setring g; g;
+
+  module A = a*gen(1), b * gen(1), c*gen(2), d * gen(2);
+  print(A);
+
+  print(exteriorPower(A, 2));
+
+  module B = a*gen(1) + c*gen(2) + e*gen(3),
+             b*gen(1) + d*gen(2) + f*gen(3),
+                        e*gen(1) + f*gen(3);
+  print(B);
+
+  print(exteriorPower(B, 2));
+  print(exteriorPower(B, 3));
+
+}
+
+//////////////////////////////////////////////////////////////////////////////
diff --git a/Singular/LIB/modnormal.lib b/Singular/LIB/modnormal.lib
new file mode 100644
index 0000000..5d10e81
--- /dev/null
+++ b/Singular/LIB/modnormal.lib
@@ -0,0 +1,693 @@
+//////////////////////////////////////////////////////////////////////////////
+version="version modnormal.lib 4.0.0.0 Dec_2013 "; // $Id: 1616152b5bce97c46cfb18c1f9c08a574ad00235 $
+category = "Commutative Algebra";
+info="
+LIBRARY:  modnormal.lib    Normalization of affine domains using modular methods
+
+AUTHORS:  J. Boehm        boehm at mathematik.uni-kl.de
+          W. Decker       decker at mathematik.uni-kl.de
+          S. Laplagne     slaplagn at dm.uba.ar
+          G. Pfister      pfister at mathematik.uni-kl.de
+          A. Steenpass    steenpass at mathematik.uni-kl.de
+          S. Steidel      steidel at mathematik.uni-kl.de
+@*
+
+OVERVIEW:
+Suppose A is an affine domain over a perfect field.@*
+This library implements a modular strategy for finding the normalization of A.
+Following [1], the idea is to apply the normalization algorithm given in [2]
+over finite fields and lift the results via Chinese remaindering and rational
+reconstruction as described in [3]. This approch is inherently parallel.@*
+The strategy is available both as a randomized and as a verified algorithm.
+
+REFERENCES:
+
+[1] Janko Boehm, Wolfram Decker, Santiago Laplagne, Gerhard Pfister, Stefan Steidel,
+Andreas Steenpass: Parallel algorithms for normalization, preprint, 2011.
+
+[2] Gert-Martin Greuel, Santiago Laplagne, Frank Seelisch: Normalization of Rings,
+Journal of Symbolic Computation 9 (2010), p. 887-901
+
+[3] Janko Boehm, Wolfram Decker, Claus Fieker, Gerhard Pfister:
+The use of Bad Primes in Rational Reconstruction, preprint, 2012.
+
+KEYWORDS:
+normalization; modular methods
+
+SEE ALSO: normal_lib, locnormal_lib
+
+PROCEDURES:
+modNormal(I);        normalization of R/I using modular methods
+
+";
+
+LIB "poly.lib";
+LIB "ring.lib";
+LIB "normal.lib";
+LIB "modstd.lib";
+LIB "parallel.lib";
+
+////////////////////////////////////////////////////////////////////////////////
+// Verify the char 0 result L of normalization of I modulo a prime p
+
+static proc pTestNormal(ideal I, list L, int p, ideal normalIP)
+{
+   // We change the characteristic of the ring to p.
+  def R0 = basering;
+  ideal U = L[1];
+  poly condu=L[2];
+  list rl = ringlist(R0);
+  rl[1] = p;
+  def @r = ring(rl);
+  setring @r;
+  ideal IP = fetch(R0,I);
+  ideal UP = fetch(R0,U);
+  poly conduP = fetch(R0, condu);
+  ideal outP = fetch(R0,normalIP);
+  poly denOutP = outP[1];
+
+  // Check if the universal denominator is valid
+  ideal cOut = conduP*outP;
+  ideal dI = ideal(denOutP) + IP;
+  int inc = size(reduce(cOut, groebner(dI)));
+  if(inc > 0)
+  {
+    "Inclusion is not satisfied. Unlucky prime?";
+    return(ideal(0));
+  }
+  return(outComp(UP, outP, conduP, denOutP, IP))
+  }
+
+////////////////////////////////////////////////////////////////////////////////
+
+
+// Computes the normalization of I in characterisitic p.
+// Returns an ideal Out such that the normalization mod p is the
+// module 1/condu * Out
+static proc modpNormal(ideal I, int p, poly condu,int printTimings,list #)
+{
+  int tt = timer;
+  int liftRelations;
+  // We change the characteristic of the ring to p.
+  def R0 = basering;
+  list rl = ringlist(R0);
+  rl[1] = p;
+  def @r = ring(rl);
+  int loc;
+  int i;
+  for ( i=1; i <= size(#); i++ )
+  {
+    if ( typeof(#[i]) == "string" )
+    {
+      if (#[i]=="inputJ") { loc = 1;ideal J=#[i][2];}
+    }
+  }
+  setring @r;
+  if (loc==1) {ideal JP = fetch(R0,J)};
+  //int t=timer;
+  ideal IP = groebner(fetch(R0,I));
+  //"Time for groebner mod p "+string(timer -t);
+  poly conduP = fetch(R0, condu);
+
+  option(redSB);
+
+  int t = timer;
+  // We compute the normalization mod p
+  if (loc==0)
+  {
+    //global
+    list l = normal(IP);
+  } else {
+    //local
+    list l = normal(IP,list(list("inputJ", JP)));
+  }
+  if (printTimings==1) {"Time for modular normal: "+string(timer - t);}
+
+  t = timer;
+
+  // Currently, the algorithm only works if no splitting occurs during the
+  // normalization process. (For example, if I is prime.)
+  if(size(l[2]) > 1){
+    ERRROR("Original ideal is not prime (Not implemented.) or unlucky prime");
+  }
+
+  ideal outP = l[2][1];
+  poly denOutP = outP[size(outP)];
+
+  // Check if the universal denominator is valid
+  ideal cOut = conduP*outP;
+  ideal dI = ideal(denOutP) + IP;
+  int inc = size(reduce(cOut, groebner(dI)));
+  if(inc > 0)
+  {
+    ERROR("Inclusion is not satisfied. Unlucky prime?");
+  }
+
+  // We change the denominator to the universal denominator
+  outP = changeDenominator(outP, denOutP, conduP, IP);
+  if(size(outP) > 1)
+  {
+    ideal JP = conduP, outP[1..size(outP)-1];
+  } else
+  {
+    ERROR("Normal ring - Special case not fully implemented.");
+    ideal JP = conduP;
+    ideal norid = 0;
+    export norid;
+    def RP = @r;
+  }
+
+  setring R0;
+  ideal out = fetch(@r, JP);
+
+  if (printTimings==1) {"Prime: "+string(p);}
+  tt = timer-tt;
+  return(list(out, p, tt));
+}
+
+// Computes the normalization using modular methods.
+// Basic algorithm based on modstd.
+proc modNormal(ideal I, int nPrimes, list #)
+"USAGE:  modNormal(I, n [,options]); I = prime ideal, n = positive integer, options = list of options. @*
+         Optional parameters in list options (can be entered in any order):@*
+         noVerificication: do not verify the result.@*
+         printTimings: print timings.@*
+         int ncores: number of cores to be used (default = 1).
+ASSUME:  I is a prime ideal (the algorithm will also work for radical ideals as long as the
+         normal command does not detect that the ideal under consideration is not prime).
+RETURN:  a list of an ideal U and a universal denominator d such that U/d is the normalization.
+REMARKS: We use the algorithm given in [1] to compute the normalization of A = R/I where R is the
+         basering. We apply the algorithm for n primes at a time until the result lifted to the
+         rationals is correct modulo one additional prime. Depending on whether the option
+         noVerificication is used or not, the result is returned as a probabilistic result
+         or verified over the rationals.@*
+         The normalization of A is represented as an R-module by returning a list of U and d,
+         where U is an ideal of A and d is an element of A such that U/d is the normalization of A.
+         In fact, U and d are returned as an ideal and a polynomial of the base ring R.
+KEYWORDS: normalization; modular techniques.
+SEE ALSO: normal_lib, locnormal_lib.
+EXAMPLE: example modNormal; shows an example
+"
+{
+
+  int i,noVerif,printTimings;
+  int liftRelations;
+  int ncores = 1;
+  for ( i=1; i <= size(#); i++ )
+  {
+    if ( typeof(#[i]) == "string" )
+    {
+      if (#[i]=="noVerification") { noVerif = 1;}
+      if (#[i]=="printTimings") { printTimings = 1;}
+    }
+    if ( typeof(#[i]) == "int" )
+    {
+      ncores = #[i];
+    }
+  }
+
+
+  int totalTime = timer;
+
+  intvec LTimer;
+  int t;
+
+  def R = basering;
+  int j;
+
+//--------------------  Initialize the list of primes  -------------------------
+  int n2 = nPrimes;
+
+
+
+//---Computation of the jacobian ideal and the universal denominator
+
+  list IM = mstd(I);
+  I = IM[1];
+  int d = dim(I);
+  ideal IMin = IM[2];
+  qring Q = I;   // We work in the quotient by the groebner base of the ideal I
+  option("redSB");
+  option("returnSB");
+  ideal I = fetch(R, I);
+  attrib(I, "isSB", 1);
+  ideal IMin = fetch(R, IMin);
+  dbprint(dbg, "Computing the jacobian ideal...");
+  ideal J = minor(jacob(IMin), nvars(basering) - d, I);
+  t=timer;
+  J = modStd(J);
+  if (printTimings==1) {"Time for modStd Jacobian "+string(timer-t);}
+
+  setring R;
+  ideal J = fetch(Q, J);
+
+  //------------------ We check if the singular locus is empty -------------
+  if(J[1] == 1)
+  {
+    // The original ring R/I was normal. Nothing to do.
+    return(ideal(1));
+  }
+
+//--- Universal denominator---
+  poly condu = getSmallest(J);   // Choses the polynomial of smallest degree
+                                 // of J as universal denominator.
+  if (printTimings==1) {"conductor: ", condu;}
+
+//--------------  Main standard basis computations in positive  ----------------
+//----------------------  characteristic start here  ---------------------------
+  list resultNormal,currentPrimes;
+  list resultNormalX,currentPrimesX;
+  list LL;
+
+  ideal ChremLift;
+  ideal Out;
+  list OutCondu;
+
+  int ptn;
+  int k = 1;
+  int sh;
+  int p;
+  int h;
+
+  intvec L;
+  bigint N;
+
+  int totalModularTime;
+  int maxModularTime;
+  int sumMaxModularTime;
+  int sumTotalModularTime;
+
+  ideal normalIP;
+
+  I = groebner(I);
+  // Largest prime:     2147483647
+  // Max prime for gcd:  536870909
+
+  // loop increasing the number of primes by n2 until pTest is true
+  list modarguments;
+  list modresults;
+  int lastPrime;
+  while (ptn==0)
+  {
+    L = primeList(I,k*n2+1,intvec(536870627),1);
+    maxModularTime=0;
+    totalModularTime = timer;
+    if (k==1) {sh=0;} else {sh=1;}
+    if (ncores == 1)
+    {
+      for(j = (k-1)*n2+1+sh; j <= k*n2+1; j++)
+      {
+        t = timer;
+        normalIP = modpNormal(I, L[j], condu,printTimings,#)[1];
+        if(timer - t > maxModularTime) { maxModularTime = timer - t; }
+        LTimer[j] = timer - t;
+        setring R;
+        resultNormalX[j] = normalIP;
+        currentPrimesX[j] = bigint(L[j]);
+      }
+      lastPrime = L[k*n2+1];
+    }
+    else
+    {
+      for(j = (k-1)*n2+1+sh; j <= k*n2+1; j++)
+      {
+        modarguments[j-(k-1)*n2-sh] = list(I, L[j], condu, printTimings, #);
+      }
+      modresults = parallelWaitAll("modpNormal", modarguments, 0, ncores);
+      for(j = (k-1)*n2+1+sh; j <= k*n2+1; j++)
+      {
+        resultNormalX[j] = modresults[j-(k-1)*n2-sh][1];
+        currentPrimesX[j] = bigint(modresults[j-(k-1)*n2-sh][2]);
+        LTimer[j] = modresults[j-(k-1)*n2-sh][3];
+        if(LTimer[j] > maxModularTime) { maxModularTime = LTimer[j]; }
+      }
+      normalIP = resultNormalX[k*n2+1];
+      lastPrime = modresults[n2-sh+1][2];
+    }
+
+    if (printTimings==1) {"List of times for all modular computations so far: "+string(LTimer);}
+    if (printTimings==1) {"Maximal modular time of current step: "+string(maxModularTime);}
+    sumMaxModularTime=sumMaxModularTime+maxModularTime;
+    totalModularTime = timer - totalModularTime;
+    sumTotalModularTime=sumTotalModularTime+totalModularTime;
+    if (printTimings==1) {"Total modular time of current step: "+string(totalModularTime);}
+    resultNormal=delete(resultNormalX,size(resultNormalX));
+    currentPrimes=delete(currentPrimesX,size(currentPrimesX));
+    //------------------------  Delete unlucky primes  -----------------------------
+    //-------------  unlucky if and only if the leading ideal is wrong  ------------
+    // Polynomials are not homogeneous: h = 0
+    LL = deleteUnluckyPrimes(resultNormal,currentPrimes,h);
+    resultNormal = LL[1];
+    currentPrimes = LL[2];
+    if (printTimings==1) {"Number of lucky primes: ", size(currentPrimes);}
+
+    //-------------------  Now all leading ideals are the same  --------------------
+    //-------------------  Lift results to basering via farey  ---------------------
+    N = currentPrimes[1];
+    for(i = 2; i <= size(currentPrimes); i++)
+    {
+      N = N*currentPrimes[i];
+    }
+    // Chinese remainder
+    ChremLift = chinrem(resultNormal,currentPrimes);
+    // Farey lifting
+    Out = farey(ChremLift,N);
+
+    OutCondu=Out,condu;
+    // pTest
+    if (pTestNormal(I,OutCondu,lastPrime,normalIP)==0)
+    {
+      if (printTimings==1) {"pTestNormal has failed, increasing the number of primes by "+string(n2);}
+      k=k+1;
+    } else
+    {
+       ptn=1;
+    }
+  }
+  if (printTimings==1)
+  {
+      "Time for all modular computations: "+string(sumTotalModularTime);
+      "Parallel time for all modular computations: "+string(sumMaxModularTime);
+      "Time for randomized normal: "+string(timer - totalTime);
+      "Simulated parallel time for randomized normal: "+string(timer - totalTime + sumMaxModularTime - sumTotalModularTime);
+  }
+  // return the result if no verification
+  if (noVerif==1) {
+      Out[size(Out) + 1] = Out[1];
+      Out = Out[2..size(Out)];
+      OutCondu=modStd(Out),condu;
+      return(OutCondu);
+   };
+
+//------------------- Optional tests to ensure correctness --------------------
+  // Check for finiteness. We do this by checking if the reconstruction of
+  // the ring structure is still valid
+
+  t = timer;
+  int tVerif=timer;
+  if (printTimings==1) {"Verification:";}
+  setring R;
+
+  int isNormal = normalCheck(Out, I,printTimings);
+
+
+  if(isNormal == 0)
+  {
+    ERROR("Not normal!");
+  } else {
+    if (printTimings==1) {"Normal!";}
+  }
+
+
+  if (printTimings==1)
+  {
+     "Time for verifying normal: "+string(timer - t);
+     "Time for all verification tests: "+string(timer - tVerif);
+     "Simulated parallel time including verfications: "+string(timer - totalTime + sumMaxModularTime - sumTotalModularTime);
+     "Total time: "+string(timer - totalTime);
+  }
+  // We put the denominator at the end
+  // however we return condu anyway
+  Out[size(Out) + 1] = Out[1];
+  Out = Out[2..size(Out)];
+  OutCondu=modStd(Out),condu;
+  return(OutCondu);
+}
+
+example
+{ "EXAMPLE:";
+ring R = 0,(x,y,z),dp;
+int k = 4;
+poly f = (x^(k+1)+y^(k+1)+z^(k+1))^2-4*(x^(k+1)*y^(k+1)+y^(k+1)*z^(k+1)+z^(k+1)*x^(k+1));
+f = subst(f,z,3x-2y+1);
+ring S = 0,(x,y),dp;
+poly f = imap(R,f);
+ideal i = f;
+list L = modNormal(i,1,"noVerification");
+}
+
+
+// Computes the Jacobian ideal
+// I is assumed to be a groebner base
+static proc jacobIdOne(ideal I,int printTimings)
+{
+  def R = basering;
+
+  int d = dim(I);
+
+  if (printTimings==1) {"Computing the ideal of minors...";}
+  ideal J = minor(jacob(I), nvars(basering) - d, I);
+  if (printTimings==1) {"Computing the modstd of the ideal of minors...";}
+  J = modStd(J);
+  if (printTimings==1)
+  {
+       "Groebner base computed.";
+       "ideal of minors: "; J;
+  }
+  return(J);
+}
+
+// Procedure for comparing timings and outputs between the modular approach
+// and the classical approach. Remove static to be used.
+static proc norComp(ideal I, int nPrimes)
+{
+  // nPrimes is the number of primes to use.
+
+  int t = timer;
+  list Out2 = modNormal(I, nPrimes,"noVerification");
+  "Time modNormal: ", timer - t;
+  t = timer;
+  ideal Out1 = normal(I)[2][1];
+  "Time normal: ", timer - t;
+  "Same output?";
+  outComp(Out1, Out2[1], Out1[size(Out1)], Out2[2], I);
+}
+
+static proc outComp(ideal Out1, ideal Out2, poly den1, poly den2, ideal I)
+{
+  I = groebner(I);
+  Out1 = changeDenominator(Out1, den1, den1, I);
+  Out2 = changeDenominator(Out2, den2, den1, I);
+  Out1 = groebner(I+Out1);
+  Out2 = groebner(I+Out2);
+  return((size(reduce(Out1, Out2)) == 0) * (size(reduce(Out2, Out1)) == 0));
+}
+
+
+// Make p homogeneous of degree d taking h as the aux variable of deg 1.
+static proc polyHomogenize(poly p, int d, intvec degs, poly h)
+{
+  int i;
+  poly q;
+  for(i = 1; i <= size(p); i++)
+  {
+    q = q + p[i]*h^(d-deg(p[i], degs));
+  }
+  return(q);
+}
+
+
+// verification procedure
+static proc normalCheck(ideal U, ideal I,int printTimings)
+// U / U[1] = output of the normalization
+{
+  if (printTimings==1) {"normalCheck: computes the new ring structure and checks if the ring is normal";}
+
+  def R = basering;
+  poly D = U[1];  // universal denominator
+
+  if (printTimings==1) {"Computing the new ring structure";}
+  list ele = Normal::computeRing(U, I, "noRed");
+
+  def origEre = ele[1];
+  setring origEre;
+  if (printTimings==1) {"Number of variables: ", nvars(basering);}
+
+  if (printTimings==1) {"Computing the groebner base of the relations...";}
+  norid = modStd(norid);
+
+  if (printTimings==1) {"Computing the jacobian ideal...";}
+  ideal J = jacobIdOne(norid,printTimings);
+  ideal JI = J + norid;
+  if (printTimings==1) {"Computing the radical...";}
+  ideal JR = radical(JI);
+  poly testP = getSmallest(JR);   // Choses the polynomial of smallest degree
+
+  qring Q = norid;
+  ideal J = fetch(origEre, JR);
+  poly D = fetch(origEre, testP);
+  if (printTimings==1) {"Computing the quotient (DJ : J)...";}
+  ideal oldU = 1;
+  ideal U = quotient(D*J, J);
+  U = groebner(U);
+
+  // ----------------- Grauer-Remmert criterion check -----------------------
+  // We check if the equality in Grauert - Remmert criterion is satisfied.
+  int isNormal = Normal::checkInclusions(D*oldU, U);
+  setring R;
+  return(isNormal);
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+//                            EXAMPLES
+//
+///////////////////////////////////////////////////////////////////////////
+/*
+// plane curves
+
+ring r24 = 0,(x,y,z),dp;
+int k = 2;
+poly f = (x^(k+1)+y^(k+1)+z^(k+1))^2-4*(x^(k+1)*y^(k+1)+y^(k+1)*z^(k+1)+z^(k+1)*x^(k+1));
+f = subst(f,z,2x-y+1);
+ring s24 = 0,(x,y),dp;
+poly f = imap(r24,f);
+ideal i = f;
+
+//locNormal(i);
+modNormal(i,1);
+
+
+ring r24 = 0,(x,y,z),dp;
+int k = 3;
+poly f = (x^(k+1)+y^(k+1)+z^(k+1))^2-4*(x^(k+1)*y^(k+1)+y^(k+1)*z^(k+1)+z^(k+1)*x^(k+1));
+f = subst(f,z,2x-y+1);
+ring s24 = 0,(x,y),dp;
+poly f = imap(r24,f);
+ideal i = f;
+
+//locNormal(i);
+modNormal(i,1,"noVerification");
+
+
+ring r24 = 0,(x,y,z),dp;
+int k = 4;
+poly f = (x^(k+1)+y^(k+1)+z^(k+1))^2-4*(x^(k+1)*y^(k+1)+y^(k+1)*z^(k+1)+z^(k+1)*x^(k+1));
+f = subst(f,z,2x-y+1);
+ring s24 = 0,(x,y),dp;
+poly f = imap(r24,f);
+ideal i = f;
+
+//locNormal(i);
+modNormal(i,1,"noVerification");
+
+
+ring r24 = 0,(x,y,z),dp;
+int k = 5;
+poly f = (x^(k+1)+y^(k+1)+z^(k+1))^2-4*(x^(k+1)*y^(k+1)+y^(k+1)*z^(k+1)+z^(k+1)*x^(k+1));
+f = subst(f,z,2x-y+1);
+ring s24 = 0,(x,y),dp;
+poly f = imap(r24,f);
+ideal i = f;
+
+//locNormal(i);
+modNormal(i,1);
+
+
+ring s24 = 0,(x,y),dp;
+int a=7;
+ideal i = ((x-1)^a-y^3)*((x+1)^a-y^3)*((x)^a-y^3)*((x-2)^a-y^3)*((x+2)^a-y^3)+y^15;
+
+//locNormal(i);
+modNormal(i,1);
+
+
+ring s24 = 0,(x,y),dp;
+int a=8;
+ideal i = ((x-1)^a-y^3)*((x+1)^a-y^3)*((x)^a-y^3)*((x-2)^a-y^3)*((x+2)^a-y^3)+y^15;
+
+//locNormal(i);
+modNormal(i,1);
+
+ring s24 = 0,(x,y),dp;
+int a=9;
+ideal i = ((x-1)^a-y^3)*((x+1)^a-y^3)*((x)^a-y^3)*((x-2)^a-y^3)*((x+2)^a-y^3)+y^15;
+
+//locNormal(i);
+modNormal(i,1,"noVerification");
+
+
+
+
+ring r=0,(x,y),dp;
+ideal i=9127158539954x10+3212722859346x8y2+228715574724x6y4-34263110700x4y6
+-5431439286x2y8-201803238y10-134266087241x8-15052058268x6y2+12024807786x4y4
++506101284x2y6-202172841y8+761328152x6-128361096x4y2+47970216x2y4-6697080y6
+-2042158x4+660492x2y2-84366y4+2494x2-474y2-1;
+
+//locNormal(i);
+modNormal(i,1);
+
+
+// surfaces in A3
+
+
+ring r7 = 0,(x,y,t),dp;
+int a=11;
+ideal i = x*y*(x-y)*(x+y)*(y-1)*t+(x^a-y^2)*(x^10-(y-1)^2);
+//locNormal(i);
+modNormal(i,1,"noVerification");
+
+ring r7 = 0,(x,y,t),dp;
+int a=12;
+ideal i = x*y*(x-y)*(x+y)*(y-1)*t+(x^a-y^2)*(x^10-(y-1)^2);
+//locNormal(i);
+modNormal(i,1,"noVerification");
+
+
+ring r7 = 0,(x,y,t),dp;
+int a=13;
+ideal i = x*y*(x-y)*(x+y)*(y-1)*t+(x^a-y^2)*(x^10-(y-1)^2);
+
+//locNormal(i);
+modNormal(i,1,"noVerification");
+
+
+ring r22 = 0,(x,y,z),dp;
+ideal i = z2-(y2-1234x3)^2*(15791x2-y3)*(1231y2-x2*(x+158))*(1357y5-3x11);
+
+//locNormal(i);
+modNormal(i,1,"noVerification");
+
+
+ring r22 = 0,(x,y,z),dp;
+ideal i = z2-(y2-1234x3)^3*(15791x2-y3)*(1231y2-x2*(x+158))*(1357y5-3x11);
+
+//locNormal(i);
+modNormal(i,1,"noVerification");
+
+
+ring r23 = 0,(x,y,z),dp;
+ideal i = z5-((13x-17y)*(5x2-7y3)*(3x3-2y2)*(19y2-23x2*(x+29)))^2;
+
+//locNormal(i);
+modNormal(i,1,"noVerification");
+
+
+// curve in A3
+
+ring r23 = 0,(x,y,z),dp;
+ideal i = z3-(19y2-23x2*(x+29))^2,x3-(11y2-13z2*(z+1));
+
+//locNormal(i);
+modNormal(i,1,"noVerification");
+
+
+ring r23 = 0,(x,y,z),dp;
+ideal i = z3-(19y2-23x2*(x+29))^2,x3-(11y2-13z2*(z+1))^2;
+
+//locNormal(i);
+modNormal(i,1,"noVerification");
+
+// surface in A4
+
+ring r23 = 0,(x,y,z,w),dp;
+ideal i = z2-(y3-123456w2)*(15791x2-y3)^2, w*z-(1231y2-x*(111x+158));
+
+
+//locNormal(i);
+modNormal(i,1,"noVerification");
+
+*/
+
+
diff --git a/Singular/LIB/modstd.lib b/Singular/LIB/modstd.lib
new file mode 100644
index 0000000..6fe8a66
--- /dev/null
+++ b/Singular/LIB/modstd.lib
@@ -0,0 +1,778 @@
+///////////////////////////////////////////////////////////////////////////////
+version="version modstd.lib 4.0.0.0 May_2014 "; // $Id: 1255404c5eea998576de2162553853f7326dda9f $
+category="Commutative Algebra";
+info="
+LIBRARY:  modstd.lib      Groebner bases of ideals using modular methods
+
+AUTHORS:  A. Hashemi      Amir.Hashemi at lip6.fr
+          G. Pfister      pfister at mathematik.uni-kl.de
+          H. Schoenemann  hannes at mathematik.uni-kl.de
+          A. Steenpass    steenpass at mathematik.uni-kl.de
+          S. Steidel      steidel at mathematik.uni-kl.de
+
+OVERVIEW:
+  A library for computing Groebner bases of ideals in the polynomial ring over
+  the rational numbers using modular methods.
+
+REFERENCES:
+  E. A. Arnold: Modular algorithms for computing Groebner bases.
+  J. Symb. Comp. 35, 403-419 (2003).
+
+  N. Idrees, G. Pfister, S. Steidel: Parallelization of Modular Algorithms.
+  J. Symb. Comp. 46, 672-684 (2011).
+
+PROCEDURES:
+  modStd(I);    standard basis of I using modular methods
+";
+
+LIB "poly.lib";
+LIB "modular.lib";
+
+proc modStd(ideal I, list #)
+"USAGE:   modStd(I[, exactness]); I ideal, exactness int
+RETURN:   a standard basis of I
+NOTE:     The procedure computes a standard basis of I (over the rational
+          numbers) by using modular methods.
+       @* An optional parameter 'exactness' can be provided.
+          If exactness = 1, the procedure computes a standard basis of I for
+          sure; if exactness = 0, it computes a standard basis of I
+          with high probability.
+SEE ALSO: modular
+EXAMPLE:  example modStd; shows an example"
+{
+    /* read optional parameter */
+    int exactness = 1;
+    if (size(#) > 0) {
+        /* For compatibility, we only test size(#) > 4. This can be changed to
+         * size(#) > 1 in the future. */
+        if (size(#) > 4 || typeof(#[1]) != "int") {
+            ERROR("wrong optional parameter");
+        }
+        exactness = #[1];
+    }
+
+    /* save options */
+    intvec opt = option(get);
+    option(redSB);
+
+    /* choose the right command */
+    string command = "groebner";
+    if (npars(basering) > 0) {
+        command = "Modstd::groebner_norm";
+    }
+
+    /* call modular() */
+    if (exactness) {
+        I = modular(command, list(I), primeTest_std,
+            deleteUnluckyPrimes_std, pTest_std, finalTest_std);
+    }
+    else {
+        I = modular(command, list(I), primeTest_std,
+            deleteUnluckyPrimes_std, pTest_std);
+    }
+
+    /* return the result */
+    attrib(I, "isSB", 1);
+    option(set, opt);
+    return(I);
+}
+example
+{
+    "EXAMPLE:";
+    echo = 2;
+    ring R1 = 0, (x,y,z,t), dp;
+    ideal I = 3x3+x2+1, 11y5+y3+2, 5z4+z2+4;
+    ideal J = modStd(I);
+    J;
+    I = homog(I, t);
+    J = modStd(I);
+    J;
+
+    ring R2 = 0, (x,y,z), ds;
+    ideal I = jacob(x5+y6+z7+xyz);
+    ideal J = modStd(I, 0);
+    J;
+
+    ring R3 = 0, x(1..4), lp;
+    ideal I = cyclic(4);
+    ideal J1 = modStd(I, 1);   // default
+    ideal J2 = modStd(I, 0);
+    size(reduce(J1, J2));
+    size(reduce(J2, J1));
+}
+
+/* compute a normalized GB via groebner() */
+static proc groebner_norm(ideal I)
+{
+    I = simplify(groebner(I), 1);
+    attrib(I, "isSB", 1);
+    return(I);
+}
+
+/* test if the prime p is suitable for the input, i.e. it does not divide
+ * the numerator or denominator of any of the coefficients */
+static proc primeTest_std(int p, alias list args)
+{
+    /* erase zero generators */
+    ideal I = simplify(args[1], 2);
+
+    /* clear denominators and count the terms */
+    ideal J;
+    ideal K;
+    int n = ncols(I);
+    intvec sizes;
+    number cnt;
+    int i;
+    for(i = n; i > 0; i--) {
+        J[i] = cleardenom(I[i]);
+        cnt = leadcoef(J[i])/leadcoef(I[i]);
+        K[i] = numerator(cnt)*var(1)+denominator(cnt);
+    }
+    sizes = size(J[1..n]);
+
+    /* change to characteristic p */
+    def br = basering;
+    list lbr = ringlist(br);
+    if (typeof(lbr[1]) == "int") {
+        lbr[1] = p;
+    }
+    else {
+        lbr[1][1] = p;
+    }
+    def rp = ring(lbr);
+    setring(rp);
+    ideal Jp = fetch(br, J);
+    ideal Kp = fetch(br, K);
+
+    /* test if any coefficient is missing */
+    if (intvec(size(Kp[1..n])) != 2:n) {
+        setring(br);
+        return(0);
+    }
+    if (intvec(size(Jp[1..n])) != sizes) {
+        setring(br);
+        return(0);
+    }
+    setring(br);
+    return(1);
+}
+
+/* find entries in modresults which come from unlucky primes.
+ * For this, sort the entries into categories depending on their leading
+ * ideal and return the indices in all but the biggest category. */
+static proc deleteUnluckyPrimes_std(alias list modresults)
+{
+    int size_modresults = size(modresults);
+
+    /* sort results into categories.
+     * each category is represented by three entries:
+     * - the corresponding leading ideal
+     * - the number of elements
+     * - the indices of the elements
+     */
+    list cat;
+    int size_cat;
+    ideal L;
+    int i;
+    int j;
+    for (i = 1; i <= size_modresults; i++) {
+        L = lead(modresults[i]);
+        attrib(L, "isSB", 1);
+        for (j = 1; j <= size_cat; j++) {
+            if (size(L) == size(cat[j][1])
+                && size(reduce(L, cat[j][1])) == 0
+                && size(reduce(cat[j][1], L)) == 0) {
+                cat[j][2] = cat[j][2]+1;
+                cat[j][3][cat[j][2]] = i;
+                break;
+            }
+        }
+        if (j > size_cat) {
+            size_cat++;
+            cat[size_cat] = list();
+            cat[size_cat][1] = L;
+            cat[size_cat][2] = 1;
+            cat[size_cat][3] = list(i);
+        }
+    }
+
+    /* find the biggest categories */
+    int cat_max = 1;
+    int max = cat[1][2];
+    for (i = 2; i <= size_cat; i++) {
+        if (cat[i][2] > max) {
+            cat_max = i;
+            max = cat[i][2];
+        }
+    }
+
+    /* return all other indices */
+    list unluckyIndices;
+    for (i = 1; i <= size_cat; i++) {
+        if (i != cat_max) {
+            unluckyIndices = unluckyIndices + cat[i][3];
+        }
+    }
+    return(unluckyIndices);
+}
+
+/* test if 'command' applied to 'args' in characteristic p is the same as
+   'result' mapped to characteristic p */
+static proc pTest_std(string command, list args, ideal result, int p)
+{
+    /* change to characteristic p */
+    def br = basering;
+    list lbr = ringlist(br);
+    if (typeof(lbr[1]) == "int") {
+        lbr[1] = p;
+    }
+    else {
+        lbr[1][1] = p;
+    }
+    def rp = ring(lbr);
+    setring(rp);
+    ideal Ip = fetch(br, args)[1];
+    ideal Gp = fetch(br, result);
+    attrib(Gp, "isSB", 1);
+
+    /* test if Ip is in Gp */
+    int i;
+    for (i = ncols(Ip); i > 0; i--) {
+        if (reduce(Ip[i], Gp, 1) != 0) {
+            setring(br);
+            return(0);
+        }
+    }
+
+    /* compute command(args) */
+    execute("Ip = "+command+"(Ip);");
+
+    /* test if Gp is in Ip */
+    for (i = ncols(Gp); i > 0; i--) {
+        if (reduce(Gp[i], Ip, 1) != 0) {
+            setring(br);
+            return(0);
+        }
+    }
+    setring(br);
+    return(1);
+}
+
+/* test if 'result' is a GB of the input ideal */
+static proc finalTest_std(string command, alias list args, ideal result)
+{
+    /* test if args[1] is in result */
+    attrib(result, "isSB", 1);
+    int i;
+    for (i = ncols(args[1]); i > 0; i--) {
+        if (reduce(args[1][i], result, 1) != 0) {
+            return(0);
+        }
+    }
+
+    /* test if result is a GB */
+    ideal G = std(result);
+    if (reduce_parallel(G, result)) {
+        return(0);
+    }
+    return(1);
+}
+
+/* return 1, if I_reduce is _not_ in G_reduce,
+ *        0, otherwise
+ * (same as size(reduce(I_reduce, G_reduce))).
+ * Uses parallelization. */
+static proc reduce_parallel(ideal I_reduce, ideal G_reduce)
+{
+    exportto(Modstd, I_reduce);
+    exportto(Modstd, G_reduce);
+    int size_I = ncols(I_reduce);
+    int chunks = Modular::par_range(size_I);
+    intvec range;
+    int i;
+    for (i = chunks; i > 0; i--) {
+        range = Modular::par_range(size_I, i);
+        task t(i) = "Modstd::reduce_task", list(range);
+    }
+    startTasks(t(1..chunks));
+    waitAllTasks(t(1..chunks));
+    int result = 0;
+    for (i = chunks; i > 0; i--) {
+        if (getResult(t(i))) {
+            result = 1;
+            break;
+        }
+    }
+    kill I_reduce;
+    kill G_reduce;
+    return(result);
+}
+
+/* compute a chunk of reductions for reduce_parallel */
+static proc reduce_task(intvec range)
+{
+    int result = 0;
+    int i;
+    for (i = range[1]; i <= range[2]; i++) {
+        if (reduce(I_reduce[i], G_reduce, 1) != 0) {
+            result = 1;
+            break;
+        }
+    }
+    return(result);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/*
+ * The following procedures are kept for backward compatibility with the old
+ * version of modstd.lib. As of now (May 2014), they are still needed in
+ * modnormal.lib, modwalk.lib, and symodstd.lib. They can be removed here as
+ * soon as they are not longer needed in these libraries.
+ */
+
+LIB "parallel.lib";
+
+static proc mod_init()
+{
+   newstruct("idealPrimeTest", "ideal Ideal");
+}
+
+static proc redFork(ideal I, ideal J, int n)
+{
+   attrib(J,"isSB",1);
+   return(reduce(I,J,1));
+}
+
+proc isIncluded(ideal I, ideal J, list #)
+"USAGE:  isIncluded(I,J); I,J ideals
+RETURN:  1 if J includes I,
+@*       0 if there is an element f in I which does not reduce to 0 w.r.t. J.
+EXAMPLE: example isIncluded; shows an example
+"
+{
+   def R = basering;
+   setring R;
+
+   attrib(J,"isSB",1);
+   int i,j,k;
+
+   if(size(#) > 0)
+   {
+      int n = #[1];
+      if(n >= ncols(I)) { n = ncols(I); }
+      if(n > 1)
+      {
+         for(i = 1; i <= n - 1; i++)
+         {
+            //link l(i) = "MPtcp:fork";
+            link l(i) = "ssi:fork";
+            open(l(i));
+
+            write(l(i), quote(redFork(eval(I[ncols(I)-i]), eval(J), 1)));
+         }
+
+         int t = timer;
+         if(reduce(I[ncols(I)], J, 1) != 0)
+         {
+            for(i = 1; i <= n - 1; i++)
+            {
+               close(l(i));
+            }
+            return(0);
+         }
+         t = timer - t;
+         if(t > 60) { t = 60; }
+         int i_sleep = system("sh", "sleep "+string(t));
+
+         j = ncols(I) - n;
+
+         while(j >= 0)
+         {
+            for(i = 1; i <= n - 1; i++)
+            {
+               if(status(l(i), "read", "ready"))
+               {
+                  if(read(l(i)) != 0)
+                  {
+                     for(i = 1; i <= n - 1; i++)
+                     {
+                        close(l(i));
+                     }
+                     return(0);
+                  }
+                  else
+                  {
+                     if(j >= 1)
+                     {
+                        write(l(i), quote(redFork(eval(I[j]), eval(J), 1)));
+                        j--;
+                     }
+                     else
+                     {
+                        k++;
+                        close(l(i));
+                     }
+                  }
+               }
+            }
+            if(k == n - 1)
+            {
+               j--;
+            }
+            i_sleep = system("sh", "sleep "+string(t));
+         }
+         return(1);
+      }
+   }
+
+   for(i = ncols(I); i >= 1; i--)
+   {
+      if(reduce(I[i],J,1) != 0){ return(0); }
+   }
+   return(1);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r=0,(x,y,z),dp;
+   ideal I = x+1,x+y+1;
+   ideal J = x+1,y;
+   isIncluded(I,J);
+   isIncluded(J,I);
+   isIncluded(I,J,4);
+
+   ring R = 0, x(1..5), dp;
+   ideal I1 = cyclic(4);
+   ideal I2 = I1,x(5)^2;
+   isIncluded(I1,I2,4);
+}
+
+proc deleteUnluckyPrimes(list T, list L, int ho, list #)
+"USAGE:  deleteUnluckyPrimes(T,L,ho,#); T/L list of polys/primes, ho integer
+RETURN:  lists T,L(,M),lT with T/L(/M) list of polys/primes(/type of #),
+         lT ideal
+NOTE:    - if ho = 1, the polynomials in T are homogeneous, else ho = 0,
+@*       - lT is prevalent, i.e. the most appearing leading ideal in T
+EXAMPLE: example deleteUnluckyPrimes; shows an example
+"
+{
+   ho = ((ho)||(ord_test(basering) == -1));
+   int j,k,c;
+   intvec hl,hc;
+   ideal cT,lT,cK;
+   lT = lead(T[size(T)]);
+   attrib(lT,"isSB",1);
+   if(!ho)
+   {
+      for(j = 1; j < size(T); j++)
+      {
+         cT = lead(T[j]);
+         attrib(cT,"isSB",1);
+         if((size(reduce(cT,lT))!=0)||(size(reduce(lT,cT))!=0))
+         {
+            cK = cT;
+            c++;
+         }
+      }
+      if(c > size(T) div 2){ lT = cK; }
+   }
+   else
+   {
+      hl = hilb(lT,1);
+      for(j = 1; j < size(T); j++)
+      {
+         cT = lead(T[j]);
+         attrib(cT,"isSB",1);
+         hc = hilb(cT,1);
+         if(hl == hc)
+         {
+            for(k = 1; k <= size(lT); k++)
+            {
+               if(lT[k] < cT[k]) { lT = cT; c++; break; }
+               if(lT[k] > cT[k]) { c++; break; }
+            }
+         }
+         else
+         {
+            if(hc < hl){ lT = cT; hl = hilb(lT,1); c++; }
+         }
+      }
+   }
+
+   int addList;
+   if(size(#) > 0) { list M = #; addList = 1; }
+   j = 1;
+   attrib(lT,"isSB",1);
+   while((j <= size(T))&&(c > 0))
+   {
+      cT = lead(T[j]);
+      attrib(cT,"isSB",1);
+      if((size(reduce(cT,lT)) != 0)||(size(reduce(lT,cT)) != 0))
+      {
+         T = delete(T,j);
+         if(j == 1)
+         {
+            L = L[2..size(L)];
+            if(addList == 1) { M = M[2..size(M)]; }
+         }
+         else
+         {
+            if(j == size(L))
+            {
+               L = L[1..size(L)-1];
+               if(addList == 1) { M = M[1..size(M)-1]; }
+            }
+            else
+            {
+               L = L[1..j-1],L[j+1..size(L)];
+               if(addList == 1) { M = M[1..j-1],M[j+1..size(M)]; }
+            }
+         }
+         j--;
+      }
+      j++;
+   }
+
+   for(j = 1; j <= size(L); j++)
+   {
+      L[j] = bigint(L[j]);
+   }
+
+   if(addList == 0) { return(list(T,L,lT)); }
+   if(addList == 1) { return(list(T,L,M,lT)); }
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   list L = 2,3,5,7,11;
+   ring r = 0,(y,x),Dp;
+   ideal I1 = 2y2x,y6;
+   ideal I2 = yx2,y3x,x5,y6;
+   ideal I3 = y2x,x3y,x5,y6;
+   ideal I4 = y2x,11x3y,x5;
+   ideal I5 = y2x,yx3,x5,7y6;
+   list T = I1,I2,I3,I4,I5;
+   deleteUnluckyPrimes(T,L,1);
+   list P = poly(x),poly(x2),poly(x3),poly(x4),poly(x5);
+   deleteUnluckyPrimes(T,L,1,P);
+}
+
+proc primeTest(def II, bigint p)
+{
+   if(typeof(II) == "string")
+   {
+      ideal I = `II`.Ideal;
+   }
+   else
+   {
+      ideal I = II;
+   }
+
+   I = simplify(I, 2);   // erase zero generators
+
+   int i,j;
+   poly f;
+   number cnt;
+   for(i = 1; i <= size(I); i++)
+   {
+      f = cleardenom(I[i]);
+      if(f == 0) { return(0); }
+      cnt = leadcoef(I[i])/leadcoef(f);
+      if((bigint(numerator(cnt)) mod p) == 0) { return(0); }
+      if((bigint(denominator(cnt)) mod p) == 0) { return(0); }
+      for(j = size(f); j > 0; j--)
+      {
+         if((bigint(leadcoef(f[j])) mod p) == 0) { return(0); }
+      }
+   }
+   return(1);
+}
+
+proc primeList(ideal I, int n, list #)
+"USAGE:  primeList(I,n[,ncores]); ( resp. primeList(I,n[,L,ncores]); ) I ideal,
+         n integer
+RETURN:  the intvec of n greatest primes <= 2147483647 (resp. n greatest primes
+         < L[size(L)] union with L) such that none of these primes divides any
+         coefficient occuring in I
+NOTE:    The number of cores to use can be defined by ncores, default is 1.
+EXAMPLE: example primeList; shows an example
+"
+{
+   intvec L;
+   int i,p;
+   int ncores = 1;
+
+//-----------------  Initialize optional parameter ncores  ---------------------
+   if(size(#) > 0)
+   {
+      if(size(#) == 1)
+      {
+         if(typeof(#[1]) == "int")
+         {
+            ncores = #[1];
+            # = list();
+         }
+      }
+      else
+      {
+         ncores = #[2];
+      }
+   }
+
+   if(size(#) == 0)
+   {
+      p = 2147483647;
+      while(!primeTest(I,p))
+      {
+         p = prime(p-1);
+         if(p == 2) { ERROR("no more primes"); }
+      }
+      L[1] = p;
+   }
+   else
+   {
+      L = #[1];
+      p = prime(L[size(L)]-1);
+      while(!primeTest(I,p))
+      {
+         p = prime(p-1);
+         if(p == 2) { ERROR("no more primes"); }
+      }
+      L[size(L)+1] = p;
+   }
+   if(p == 2) { ERROR("no more primes"); }
+   if(ncores == 1)
+   {
+      for(i = 2; i <= n; i++)
+      {
+         p = prime(p-1);
+         while(!primeTest(I,p))
+         {
+            p = prime(p-1);
+            if(p == 2) { ERROR("no more primes"); }
+         }
+         L[size(L)+1] = p;
+      }
+   }
+   else
+   {
+      int neededSize = size(L)+n-1;;
+      list parallelResults;
+      list arguments;
+      int neededPrimes = neededSize-size(L);
+      idealPrimeTest Id;
+      Id.Ideal = I;
+      export(Id);
+      while(neededPrimes > 0)
+      {
+         arguments = list();
+         for(i = ((neededPrimes div ncores)+1-(neededPrimes%ncores == 0))
+            *ncores; i > 0; i--)
+         {
+            p = prime(p-1);
+            if(p == 2) { ERROR("no more primes"); }
+            arguments[i] = list("Id", p);
+         }
+         parallelResults = parallelWaitAll("primeTest", arguments, 0, ncores);
+         for(i = size(arguments); i > 0; i--)
+         {
+            if(parallelResults[i])
+            {
+               L[size(L)+1] = arguments[i][2];
+            }
+         }
+         neededPrimes = neededSize-size(L);
+      }
+      kill Id;
+      if(size(L) > neededSize)
+      {
+         L = L[1..neededSize];
+      }
+   }
+   return(L);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r = 0,(x,y,z),dp;
+   ideal I = 2147483647x+y, z-181;
+   intvec L = primeList(I,10);
+   size(L);
+   L[1];
+   L[size(L)];
+   L = primeList(I,5,L);
+   size(L);
+   L[size(L)];
+}
+
+////////////////////////////// further examples ////////////////////////////////
+
+/*
+ring r = 0, (x,y,z), lp;
+poly s1 = 5x3y2z+3y3x2z+7xy2z2;
+poly s2 = 3xy2z2+x5+11y2z2;
+poly s3 = 4xyz+7x3+12y3+1;
+poly s4 = 3x3-4y3+yz2;
+ideal i =  s1, s2, s3, s4;
+
+ring r = 0, (x,y,z), lp;
+poly s1 = 2xy4z2+x3y2z-x2y3z+2xyz2+7y3+7;
+poly s2 = 2x2y4z+x2yz2-xy2z2+2x2yz-12x+12y;
+poly s3 = 2y5z+x2y2z-xy3z-xy3+y4+2y2z;
+poly s4 = 3xy4z3+x2y2z-xy3z+4y3z2+3xyz3+4z2-x+y;
+ideal i =  s1, s2, s3, s4;
+
+ring r = 0, (x,y,z), lp;
+poly s1 = 8x2y2 + 5xy3 + 3x3z + x2yz;
+poly s2 = x5 + 2y3z2 + 13y2z3 + 5yz4;
+poly s3 = 8x3 + 12y3 + xz2 + 3;
+poly s4 = 7x2y4 + 18xy3z2 +  y3z3;
+ideal i = s1, s2, s3, s4;
+
+int n = 6;
+ring r = 0,(x(1..n)),lp;
+ideal i = cyclic(n);
+ring s = 0, (x(1..n),t), lp;
+ideal i = imap(r,i);
+i = homog(i,t);
+
+ring r = 0, (x(1..4),s), (dp(4),dp);
+poly s1 = 1 + s^2*x(1)*x(3) + s^8*x(2)*x(3) + s^19*x(1)*x(2)*x(4);
+poly s2 = x(1) + s^8 *x(1)* x(2)* x(3) + s^19* x(2)* x(4);
+poly s3 = x(2) + s^10*x(3)*x(4) + s^11*x(1)*x(4);
+poly s4 = x(3) + s^4*x(1)*x(2) + s^19*x(1)*x(3)*x(4) +s^24*x(2)*x(3)*x(4);
+poly s5 = x(4) + s^31* x(1)* x(2)* x(3)* x(4);
+ideal i =  s1, s2, s3, s4, s5;
+
+ring r = 0, (x,y,z), ds;
+int a = 16;
+int b = 15;
+int c = 4;
+int t = 1;
+poly f = x^a+y^b+z^(3*c)+x^(c+2)*y^(c-1)+x^(c-1)*y^(c-1)*z3
+         +x^(c-2)*y^c*(y2+t*x)^2;
+ideal i = jacob(f);
+
+ring r = 0, (x,y,z), ds;
+int a = 25;
+int b = 25;
+int c = 5;
+int t = 1;
+poly f = x^a+y^b+z^(3*c)+x^(c+2)*y^(c-1)+x^(c-1)*y^(c-1)*z3
+         +x^(c-2)*y^c*(y2+t*x)^2;
+ideal i = jacob(f),f;
+
+ring r = 0, (x,y,z), ds;
+int a = 10;
+poly f = xyz*(x+y+z)^2 +(x+y+z)^3 +x^a+y^a+z^a;
+ideal i = jacob(f);
+
+ring r = 0, (x,y,z), ds;
+int a = 6;
+int b = 8;
+int c = 10;
+int alpha = 5;
+int beta = 5;
+int t = 1;
+poly f = x^a+y^b+z^c+x^alpha*y^(beta-5)+x^(alpha-2)*y^(beta-3)
+         +x^(alpha-3)*y^(beta-4)*z^2+x^(alpha-4)*y^(beta-4)*(y^2+t*x)^2;
+ideal i = jacob(f);
+*/
+
diff --git a/Singular/LIB/modular.lib b/Singular/LIB/modular.lib
new file mode 100644
index 0000000..74b6517
--- /dev/null
+++ b/Singular/LIB/modular.lib
@@ -0,0 +1,347 @@
+////////////////////////////////////////////////////////////////////
+version="version modular.lib 4.0.0.0 May_2014 "; // $Id: 8ddfaa704f484308caea760eba0539949021a028 $
+category="General purpose";
+info="
+LIBRARY:   modular.lib  An abstraction layer for modular techniques
+AUTHOR:    Andreas Steenpass, e-mail: steenpass at mathematik.uni-kl.de
+
+OVERVIEW:
+This library is an abstraction layer for modular techniques which are
+well-known to speed up many computations and to be easy parallelizable.
+@* The basic idea is to execute some computation modulo several primes and then
+to lift the result back to characteristic zero via the farey rational map and
+chinese remaindering. It is thus possible to overcome the often problematic
+coefficient swell and to run the modular computations in parallel.
+@* In Singular, modular techniques have been quite successfully employed for
+several applications. A first implementation was done for Groebner bases in
+Singular's @ref{modstd_lib}, a pioneering work by Stefan Steidel. Since the
+algorithm is basically the same for all applications, this library aims at
+preventing library authors from writing the same code over and over again by
+providing an appropriate abstraction layer. It also offers one-line commands
+for ordinary Singular users who want to take advantage of modular techniques
+for their own calculations. Thus modular techniques can be regarded as
+a parallel skeleton of their own.
+@* The terminology (such as 'pTest' and 'finalTest') follows Singular's
+ at ref{modstd_lib} and [1].
+
+REFERENCES:
+[1] Nazeran Idrees, Gerhard Pfister, Stefan Steidel: Parallelization of
+    Modular Algorithms. Journal of Symbolic Computation 46, 672-684 (2011).
+    http://arxiv.org/abs/1005.5663
+
+SEE ALSO:  link, tasks_lib, parallel_lib, modstd_lib, assprimeszerodim_lib
+
+KEYWORDS:  modular_lib; Modular techniques; Parallelization;
+           Skeletons for parallelization; Distributed computing
+
+PROCEDURES:
+  modular(...)  execute a command modulo several primes and lift the result
+                back to characteristic zero
+";
+
+LIB "resources.lib";
+LIB "tasks.lib";
+LIB "parallel.lib";
+
+static proc mod_init()
+{
+    if (!defined(Resources)) {
+        LIB "resources.lib";
+    }
+    int sem_cores = Resources::sem_cores;   // the number of processor cores
+    exportto(Modular, sem_cores);
+}
+
+proc modular(string Command, alias list Arguments, list #)
+"USAGE:   modular(command, arguments[, primeTest, deleteUnluckyPrimes, pTest,
+          finalTest, pmax), command string, arguments list, primeTest proc,
+          deleteUnluckyPrimes proc, pTest proc, finalTest proc, pmax int
+RETURN:   the result of @code{command} applied to @code{arguments},
+          computed using modular methods.
+NOTE:     For the general algorithm and the role of the optional arguments
+          primeTest, deleteUnluckyPrimes, pTest, and finalTest, see
+          @ref{modStd} and the reference given in @ref{modular_lib}. The
+          default for these arguments is that all tests succeed and that all
+          primes are assumed to be lucky.
+       @* The optional argument pmax is an upper bound for the prime numbers
+          to be used for the modular computations. The default is 2147483647
+          (largest prime which can be represented as an @code{int} in
+          Singular), or 536870909 (largest prime below 2^29} for baserings with
+          parameters.
+SEE ALSO: modStd
+EXAMPLE:  example modular; shows an example"
+{
+    /* check for errors */
+    if (char(basering) != 0) {
+        ERROR("The characteristic must be zero.");
+    }
+
+    /* auxiliary variables */
+    int i;
+
+    /* set maximal prime number */
+    int pmax = 2147483647;
+    if (npars(basering) > 0) {
+        pmax = 536870909;   // prime(2^29)
+    }
+
+    /* read optional parameters */
+    list defaults = list(primeTest_default, deleteUnluckyPrimes_default,
+        pTest_default, finalTest_default, pmax);
+    for (i = 1; i <= size(defaults); i++) {
+        if (typeof(#[i]) != typeof(defaults[i])) {
+            # = insert(#, defaults[i], i-1);
+        }
+    }
+    if (size(#) != size(defaults)) {
+        ERROR("wrong optional parameters");
+    }
+    proc primeTest = #[1];
+    proc deleteUnluckyPrimes = #[2];
+    proc pTest = #[3];
+    proc finalTest = #[4];
+    pmax = #[5];
+    exportto(Modular, primeTest);
+
+    /* export command and arguments */
+    exportto(Modular, Command);
+    exportto(Modular, Arguments);
+
+    /* modular computations */
+    def result;
+    def result_lift;
+    bigint N = 1;
+    list modresults;
+    list primes;
+    int nAllPrimes;
+    int nNewPrimes;
+    int p;
+    list indices;
+    int ncores_available;
+    while (1) {
+        // compute list of primes
+        if (nAllPrimes == 0) {
+            nNewPrimes = NbModProcs();
+        }
+        else {
+            ncores_available = system("semaphore", "get_value", sem_cores)+1;
+            if (nAllPrimes < ncores_available) {
+                nNewPrimes = nAllPrimes;
+            }
+            else {
+                nNewPrimes = (nAllPrimes div ncores_available)
+                    *ncores_available;
+            }
+        }
+        primes = primeList(nNewPrimes, pmax);
+        pmax = primes[size(primes)]-1;
+        nAllPrimes = nAllPrimes+nNewPrimes;
+
+        // do computation modulo several primes
+        for (i = size(primes); i > 0; i--) {
+            task t(i) = "Modular::modp", primes[i];
+        }
+        startTasks(t(1..size(primes)));
+        waitAllTasks(t(1..size(primes)));
+        for (i = size(primes); i > 0; i--) {
+            modresults[i] = getResult(t(i));
+            killTask(t(i));
+            kill t(i);
+        }
+
+        // delete unlucky primes
+        indices = deleteUnluckyPrimes(modresults);
+        for (i = size(indices); i > 0; i--) {
+            modresults = delete(modresults, indices[i]);
+            primes = delete(primes, indices[i]);
+        }
+
+        // lift result
+        if (N == 1) {
+            result_lift = chinrem(modresults, primes);
+        }
+        else {
+            result_lift = chinrem(list(result_lift)+modresults,
+                list(N)+primes);
+        }
+        modresults = list();
+        for (i = size(primes); i > 0; i--) {
+            N = N*primes[i];
+        }
+
+        // apply farey
+        result = farey_parallel(result_lift, N);
+
+        // pTest
+        p = prime(random(pmax div 2, pmax-1));
+        while (!Modular::primeTest(p, Arguments)) {
+            if (p <= 2) {
+                ERROR("no more primes");
+            }
+            p = prime(random(p div 2, p-1));
+        }
+        if (!pTest(Command, Arguments, result, p)) {
+            continue;
+        }
+
+        // finalTest
+        if (finalTest(Command, Arguments, result)) {
+            break;
+        }
+    }
+
+    /* kill exported data */
+    kill Command;
+    kill Arguments;
+    kill primeTest;
+
+    /* return of result */
+    return(result);
+}
+example
+{
+    "EXAMPLE:";
+    echo = 2;
+    ring R = 0, (x,y), dp;
+    ideal I = x9y2+x10, x2y7-y8;
+    modular("std", list(I));
+}
+
+static proc primeList(int n, int pmax)
+{
+    list primes;
+    int p = pmax;
+    int i;
+    for (i = 1; i <= n; i++) {
+        if (p < 2) {
+            ERROR("no more primes");
+        }
+        p = prime(p);
+        task t(i) = "Modular::primeList_task", list(p);
+        p--;
+    }
+    startTasks(t(1..n));
+    waitAllTasks(t(1..n));
+    int j;
+    for (i = 1; i <= n; i++) {
+        if (getResult(t(i))) {
+            j++;
+            primes[j] = getArguments(t(i))[1];
+        }
+        killTask(t(i));
+    }
+    if (j < n) {
+        primes = primes+primeList(n-j, p);
+    }
+    return(primes);
+}
+
+static proc primeList_task(int p)
+{
+    return(Modular::primeTest(p, Arguments));
+}
+
+static proc modp(int p)
+{
+    def br = basering;
+    list lbr = ringlist(br);
+    if (typeof(lbr[1]) == "int") {
+        lbr[1] = p;
+    }
+    else {
+        lbr[1][1] = p;
+    }
+    def rp = ring(lbr);
+    setring(rp);
+    list args = fetch(br, Arguments);
+    execute("def result = "+Command+"("+Tasks::argsToString("args", size(args))
+        +");");
+    setring(br);
+    def result = fetch(rp, result);
+    return(result);
+}
+
+static proc primeTest_default(int p, alias list args)
+{
+    return(1);
+}
+
+static proc deleteUnluckyPrimes_default(alias list modresults)
+{
+    return(list());
+}
+
+static proc pTest_default(string command, alias list args, def result, int p)
+{
+    return(1);
+}
+
+static proc finalTest_default(string command, alias list args, def result)
+{
+    return(1);
+}
+
+static proc farey_parallel(ideal farey_arg, bigint farey_N)
+{
+    exportto(Modular, farey_arg);
+    exportto(Modular, farey_N);
+    int size_arg = ncols(farey_arg);
+    int chunks = par_range(size_arg);
+    intvec range;
+    int i;
+    for (i = chunks; i > 0; i--) {
+        range = par_range(size_arg, i);
+        task t(i) = "Modular::farey_task", list(range);
+    }
+    startTasks(t(1..chunks));
+    waitAllTasks(t(1..chunks));
+    ideal result = getResult(t(chunks));
+    for (i = chunks-1; i > 0; i--) {
+        result = getResult(t(i)), result;
+        killTask(t(i));
+    }
+    kill farey_arg;
+    kill farey_N;
+    return(result);
+}
+
+static proc farey_task(intvec range)
+{
+    ideal result = farey(ideal(farey_arg[range[1]..range[2]]), farey_N);
+    return(result);
+}
+
+static proc par_range(int N, list #)
+{
+    int nchunks = 2*getcores();
+    if (nchunks > N) {
+        nchunks = N;
+    }
+    if (size(#)) {
+        int index = #[1];
+        intvec range = ((N*(index-1)) div nchunks)+1, (N*index) div nchunks;
+        return(range);
+    }
+    else {
+        return(nchunks);
+    }
+}
+
+static proc NbModProcs()
+{
+    int available = system("semaphore", "get_value", sem_cores)+1;
+    int nb;
+    if (available < 16) {
+        nb = ((10 div available)+1-(10%available == 0))*available;
+    }
+    else {   // gives approx. (log_2(available))^2
+        int tmp = available;
+        while (tmp > 1) {
+            tmp = tmp div 2;
+            nb++;
+        }   // nb = log_2(available)
+        nb = ((2*nb+1)*available) div (2^nb) + (nb-1)^2 - 2;
+    }
+    return(nb);
+}
+
diff --git a/Singular/LIB/mondromy.lib b/Singular/LIB/mondromy.lib
new file mode 100644
index 0000000..c95a8f0
--- /dev/null
+++ b/Singular/LIB/mondromy.lib
@@ -0,0 +1,1016 @@
+//////////////////////////////////////////////////////////////////////////////
+version="version mondromy.lib 4.0.1.0 Sep_2014 "; // $Id: 737b881a8ea764e0f5a86518f4ebe8188ebca3cb $
+category="Singularities";
+info="
+LIBRARY:  mondromy.lib  Monodromy of an Isolated Hypersurface Singularity
+AUTHOR:   Mathias Schulze, email: mschulze at mathematik.uni-kl.de
+
+OVERVIEW:
+ A library to compute the monodromy of an isolated hypersurface singularity.
+ It uses an algorithm by Brieskorn (manuscripta math. 2 (1970), 103-161) to
+ compute a connection matrix of the meromorphic Gauss-Manin connection up to
+ arbitrarily high order, and an algorithm of Gerard and Levelt (Ann. Inst.
+ Fourier, Grenoble 23,1 (1973), pp. 157-195) to transform it to a simple pole.
+
+PROCEDURES:
+ detadj(U);            determinant and adjoint matrix of square matrix U
+ invunit(u,n);         series inverse of polynomial u up to order n
+ jacoblift(f);         lifts f^kappa in jacob(f) with minimal kappa
+ monodromyB(f[,opt]);  monodromy of isolated hypersurface singularity f
+ H2basis(f);           basis of Brieskorn lattice H''
+
+KEYWORDS: Monodromy; hypersurface singularity; Gauss-Manin connection;
+          Brieskorn lattice
+
+SEE ALSO: gmspoly_lib, gmssing_lib
+";
+
+LIB "ring.lib";
+LIB "sing.lib";
+LIB "linalg.lib";
+
+///////////////////////////////////////////////////////////////////////////////
+
+static proc pcvladdl(list l1,list l2)
+{
+  return(system("pcvLAddL",l1,l2));
+}
+
+static proc pcvpmull(poly p,list l)
+{
+  return(system("pcvPMulL",p,l));
+}
+
+static proc pcvmindeg(list #)
+{
+  return(system("pcvMinDeg",#[1]));
+}
+
+static proc pcvp2cv(list l,int i0,int i1)
+{
+  return(system("pcvP2CV",l,i0,i1));
+}
+
+static proc pcvcv2p(list l,int i0,int i1)
+{
+  return(system("pcvCV2P",l,i0,i1));
+}
+
+static proc pcvdim(int i0,int i1)
+{
+  return(system("pcvDim",i0,i1));
+}
+
+static proc pcvbasis(int i0,int i1)
+{
+  return(system("pcvBasis",i0,i1));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static proc min(intvec v)
+{
+  int m=v[1];
+  int i;
+  for(i=2;i<=size(v);i++)
+  {
+    if(m>v[i])
+    {
+      m=v[i];
+    }
+  }
+  return(m);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+static proc max(intvec v)
+{
+  int m=v[1];
+  int i;
+  for(i=2;i<=size(v);i++)
+  {
+    if(m<v[i])
+    {
+      m=v[i];
+    }
+  }
+  return(m);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+static proc mdivp(matrix m,poly p)
+{
+  int i,j;
+  for(i=nrows(m);i>=1;i--)
+  {
+    for(j=ncols(m);j>=1;j--)
+    {
+      m[i,j]=m[i,j]/p;
+    }
+  }
+  return(m);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc codimV(list V,int N)
+{
+  int codim=pcvdim(0,N);
+  if(size(V)>0)
+  {
+    dbprint(printlevel-voice+2,"//vector space dimension: "+string(codim));
+    dbprint(printlevel-voice+2,
+      "//number of subspace generators: "+string(size(V)));
+    int t=timer;
+    codim=codim-ncols(interred(module(V[1..size(V)])));
+    dbprint(printlevel-voice+2,"//codimension: "+string(codim));
+  }
+  return(codim);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc quotV(list V,int N)
+{
+  module Q=freemodule(pcvdim(0,N));
+  if(size(V)>0)
+  {
+    dbprint(printlevel-voice+2,"//vector space dimension: "+string(nrows(Q)));
+    dbprint(printlevel-voice+2,
+      "//number of subspace generators: "+string(size(V)));
+    int t=timer;
+    Q=interred(reduce(std(Q),std(module(V[1..size(V)]))));
+  }
+  return(list(Q[1..size(Q)]));
+}
+///////////////////////////////////////////////////////////////////////////////
+proc invunit(poly u,int n)
+"USAGE:   invunit(u,n); u poly, n int
+ASSUME:  The polynomial u is a series unit.
+RETURN:  The procedure returns the series inverse of u up to order n
+         or a zero polynomial if u is no series unit.
+DISPLAY: The procedure displays comments if printlevel>=1.
+EXAMPLE: example invunit; shows an example.
+"
+{
+  if(pcvmindeg(u)==0)
+  {
+    dbprint(printlevel-voice+2,"//computing inverse...");
+    int t=timer;
+    poly u0=jet(u,0);
+    u=jet(1-u/u0,n);
+    poly ui=u;
+    poly v=1+u;
+    int i;
+    for(i=n div pcvmindeg(u);i>1;i--)
+    {
+      ui=jet(ui*u,n);
+      v=v+ui;
+    }
+    v=jet(v,n)/u0;
+    dbprint(printlevel-voice+2,"//...inverse computed ["+string(timer-t)+
+      " secs, "+string((memory(1)+1023)/1024)+" K]");
+    return(v);
+  }
+  else
+  {
+    print("//no series unit");
+    return(poly(0));
+  }
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring R=0,(x,y),dp;
+  invunit(2+x3+xy4,10);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc detadj(module U)
+"USAGE:   detadj(U); U matrix
+ASSUME:  U is a square matrix with non zero determinant.
+RETURN:  The procedure returns a list with at most 2 entries.
+         If U is not a sqaure matrix, the list is empty.
+         If U is a sqaure matrix, then the first entry is the determinant of U.
+         If U is a square matrix and the determinant of U not zero,
+         then the second entry is the adjoint matrix of U.
+DISPLAY: The procedure displays comments if printlevel>=1.
+EXAMPLE: example detadj; shows an example.
+"
+{
+  if(nrows(U)==ncols(U))
+  {
+    dbprint(printlevel-voice+2,"//computing determinant...");
+    int t=timer;
+    poly detU=det(U);
+    dbprint(printlevel-voice+2,"//...determinant computed ["+string(timer-t)+
+      " secs, "+string((memory(1)+1023)/1024)+" K]");
+
+    if(detU==0)
+    {
+      print("//determinant zero");
+      return(list(detU));
+    }
+    else
+    {
+      def br=basering;
+      def pr=changeord(list(list("dp",1:nvars(basering))));
+      setring pr;
+      matrix U=fetch(br,U);
+      poly detU=fetch(br,detU);
+
+      dbprint(printlevel-voice+2,"//computing adjoint matrix...");
+      t=timer;
+      matrix adjU=lift(U,detU*freemodule(nrows(U)));
+      dbprint(printlevel-voice+2,"//...adjoint matrix computed ["
+        +string(timer-t)+" secs, "+string((memory(1)+1023)/1024)+" K]");
+
+      setring br;
+      matrix adjU=fetch(pr,adjU);
+      kill pr;
+    }
+  }
+  else
+  {
+    print("//no square matrix");
+    return(list());
+  }
+
+  return(list(detU,adjU));
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring R=0,x,dp;
+  matrix U[2][2]=1,1+x,1+x2,1+x3;
+  list daU=detadj(U);
+  daU[1];
+  print(daU[2]);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc jacoblift(poly f)
+"USAGE:   jacoblift(f); f poly
+ASSUME:  The polynomial f in a series ring (local ordering) defines
+         an isolated hypersurface singularity.
+RETURN:  The procedure returns a list with entries kappa, xi, u of type
+         int, vector, poly such that kappa is minimal with f^kappa in jacob(f),
+         u is a unit, and u*f^kappa=(matrix(jacob(f))*xi)[1,1].
+DISPLAY: The procedure displays comments if printlevel>=1.
+EXAMPLE: example jacoblift; shows an example.
+"
+{
+  dbprint(printlevel-voice+2,"//computing kappa...");
+  int t=timer;
+  ideal jf=jacob(f);
+  ideal sjf=std(jf);
+  int kappa=1;
+  poly fkappa=f;
+  while(reduce(fkappa,sjf)!=0)
+  {
+    dbprint(printlevel-voice+2,"//kappa="+string(kappa));
+    kappa++;
+    fkappa=fkappa*f;
+  }
+  dbprint(printlevel-voice+2,"//kappa="+string(kappa));
+  dbprint(printlevel-voice+2,"//...kappa computed ["+string(timer-t)+" secs, "
+    +string((memory(1)+1023)/1024)+" K]");
+
+  dbprint(printlevel-voice+2,"//computing xi...");
+  t=timer;
+  vector xi=lift(jf,fkappa)[1];
+  dbprint(printlevel-voice+2,"//...xi computed ["+string(timer-t)+" secs, "
+    +string((memory(1)+1023)/1024)+" K]");
+
+  dbprint(printlevel-voice+2,"//computing u...");
+  t=timer;
+  poly u=(matrix(jf)*xi)[1,1]/fkappa;
+  dbprint(printlevel-voice+2,"//...u computed ["+string(timer-t)+" secs, "
+    +string((memory(1)+1023)/1024)+" K]");
+
+  return(list(kappa,xi,u));
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring R=0,(x,y),ds;
+  poly f=x2y2+x6+y6;
+  jacoblift(f);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+static proc getdeltaP1(poly f,int K,int N,int dN)
+{
+  return(pcvpmull(f^K,pcvbasis(0,N+dN-K*pcvmindeg(f))));
+}
+///////////////////////////////////////////////////////////////////////////////
+
+static proc getdeltaP2(poly f,int N,int dN)
+{
+  def of,jf=pcvmindeg(f),jacob(f);
+  list b=pcvbasis(N-of+2,N+dN-of+2);
+  list P2;
+  P2[size(b)*((nvars(basering)-1)*nvars(basering)) div 2]=0;
+  int i,j,k,l;
+  intvec alpha;
+  for(k,l=1,1;k<=size(b);k++)
+  {
+    alpha=leadexp(b[k]);
+    for(i=nvars(basering)-1;i>=1;i--)
+    {
+      for(j=nvars(basering);j>i;j--)
+      {
+        P2[l]=alpha[i]*jf[j]*(b[k]/var(i))-alpha[j]*jf[i]*(b[k]/var(j));
+        l++;
+      }
+    }
+  }
+  return(P2);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+static proc getdeltaPe(poly f,list e,int K,int dK)
+{
+  int k;
+  list Pe,fke;
+  for(k,fke=K,pcvpmull(f^K,e);k<K+dK;k,fke=k+1,pcvpmull(f,fke))
+  {
+    Pe=Pe+fke;
+  }
+  return(Pe);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+static proc incK(poly f,int mu,int K,int deltaK,int N,
+  list e,list P1,list P2,list Pe,list V1,list V2,list Ve)
+{
+  int deltaN=deltaK*pcvmindeg(f);
+
+  list deltaP1;
+  P1=pcvpmull(f^deltaK,P1);
+  V1=pcvp2cv(P1,0,N+deltaN);
+
+  list deltaP2=getdeltaP2(f,N,deltaN);
+  V2=pcvladdl(V2,pcvp2cv(P2,N,N+deltaN))+pcvp2cv(deltaP2,0,N+deltaN);
+  P2=P2+deltaP2;
+
+  list deltaPe=getdeltaPe(f,e,K,deltaK);
+  Ve=pcvladdl(Ve,pcvp2cv(Pe,N,N+deltaN))+pcvp2cv(deltaPe,0,N+deltaN);
+  Pe=Pe+deltaPe;
+
+  K=K+deltaK;
+  dbprint(printlevel-voice+2,"//K="+string(K));
+
+  N=N+deltaN;
+  dbprint(printlevel-voice+2,"//N="+string(N));
+
+  deltaN=1;
+  dbprint(printlevel-voice+2,"//computing codimension of");
+  dbprint(printlevel-voice+2,"//df^dOmega^(n-1)+f^K*Omega^(n+1) in "
+    +"Omega^(n+1) mod m^N*Omega^(n+1)...");
+  int t=timer;
+  while(codimV(V1+V2,N)<K*mu)
+  {
+    dbprint(printlevel-voice+2,"//...codimension computed ["+string(timer-t)
+      +" secs, "+string((memory(1)+1023)/1024)+" K]");
+
+    deltaP1=getdeltaP1(f,K,N,deltaN);
+    V1=pcvladdl(V1,pcvp2cv(P1,N,N+deltaN))+pcvp2cv(deltaP1,0,N+deltaN);
+    P1=P1+deltaP1;
+
+    deltaP2=getdeltaP2(f,N,deltaN);
+    V2=pcvladdl(V2,pcvp2cv(P2,N,N+deltaN))+pcvp2cv(deltaP2,0,N+deltaN);
+    P2=P2+deltaP2;
+
+    Ve=pcvladdl(Ve,pcvp2cv(Pe,N,N+deltaN));
+
+    N=N+deltaN;
+    dbprint(printlevel-voice+2,"//N="+string(N));
+
+    dbprint(printlevel-voice+2,"//computing codimension of");
+    dbprint(printlevel-voice+2,"//df^dOmega^(n-1)+f^K*Omega^(n+1) in "
+      +"Omega^(n+1) mod m^N*Omega^(n+1)...");
+    t=timer;
+  }
+  dbprint(printlevel-voice+2,"//...codimension computed ["+string(timer-t)
+    +" secs, "+string((memory(1)+1023)/1024)+" K]");
+
+  return(K,N,P1,P2,Pe,V1,V2,Ve);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+static proc nablaK(poly f,int kappa,vector xi,poly u,int N,int prevN,
+  list Vnablae,list e)
+{
+  xi=jet(xi,N);
+  u=invunit(u,N);
+  poly fkappa=kappa*f^(kappa-1);
+
+  poly p,q;
+  list nablae;
+  int i,j;
+  for(i=1;i<=size(e);i++)
+  {
+    for(j,p=nvars(basering),0;j>=1;j--)
+    {
+      q=jet(e[i]*xi[j],N);
+      if(q!=0)
+      {
+        p=p+diff(q*jet(u,N-pcvmindeg(q)),var(j));
+      }
+    }
+    nablae=nablae+list(p-jet(fkappa*e[i],N-1));
+  }
+
+  return(pcvladdl(Vnablae,pcvp2cv(nablae,prevN,N-prevN)));
+}
+///////////////////////////////////////////////////////////////////////////////
+
+static proc MK(poly f,int mu,int kappa,vector xi,poly u,
+  int K,int N,int prevN,list e,list V1,list V2,list Ve,list Vnablae)
+{
+  dbprint(printlevel-voice+2,"//computing nabla(e)...");
+  int t=timer;
+  Vnablae=nablaK(f,kappa,xi,u,N,prevN,Vnablae,e);
+  dbprint(printlevel-voice+2,"//...nabla(e) computed ["+string(timer-t)
+    +" secs, "+string((memory(1)+1023)/1024)+" K]");
+
+  dbprint(printlevel-voice+2,
+    "//lifting nabla(e) to C-basis of H''/t^KH''...");
+  list V=Ve+V1+V2;
+  module W=module(V[1..size(V)]);
+  dbprint(printlevel-voice+2,"//vector space dimension: "+string(nrows(W)));
+  dbprint(printlevel-voice+2,"//number of generators: "+string(ncols(W)));
+  t=timer;
+  matrix C=lift(W,module(Vnablae[1..size(Vnablae)]));
+  dbprint(printlevel-voice+2,"//...nabla(e) lifted ["+string(timer-t)
+    +" secs, "+string((memory(1)+1023)/1024)+" K]");
+
+  dbprint(printlevel-voice+2,"//computing e-lift of nabla(e)...");
+  t=timer;
+  int i1,i2,j,k;
+  matrix M[mu][mu];
+  for(j=1;j<=mu;j++)
+  {
+    for(k,i2=0,1;k<K;k++)
+    {
+      for(i1=1;i1<=mu;i1,i2=i1+1,i2+1)
+      {
+        M[i1,j]=M[i1,j]+C[i2,j]*var(1)^k;
+      }
+    }
+  }
+  dbprint(printlevel-voice+2,"//...e-lift of nabla(e) computed ["
+    +string(timer-t)+" secs, "+string((memory(1)+1023)/1024)+" K]");
+
+  return(M,N,Vnablae);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+static proc mid(ideal l)
+{
+  int i,j,id;
+  int mid=0;
+  for(i=size(l);i>=1;i--)
+  {
+    for(j=i-1;j>=1;j--)
+    {
+      id=int(l[i]-l[j]);
+      id=max(intvec(id,-id));
+      mid=max(intvec(id,mid));
+    }
+  }
+  return(mid);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+static proc decmide(matrix M,ideal eM0,list bM0)
+{
+  matrix M0=jet(M,0);
+
+  dbprint(printlevel-voice+2,
+    "//computing basis U of generalized eigenspaces of M0...");
+  int t=timer;
+  int i,j;
+  matrix U,M0e;
+  matrix E=freemodule(nrows(M));
+  for(i=ncols(eM0);i>=1;i--)
+  {
+    M0e=E;
+    for(j=max(bM0[i]);j>=1;j--)
+    {
+      M0e=M0e*(M0-eM0[i]*E);
+    }
+    U=syz(M0e)+U;
+  }
+  dbprint(printlevel-voice+2,"//...U computed ["+string(timer-t)+" secs, "
+    +string((memory(1)+1023)/1024)+" K]");
+
+  dbprint(printlevel-voice+2,"//transforming M to U...");
+  t=timer;
+  list daU=detadj(U);
+  daU[2]=(1/number(daU[1]))*daU[2];
+  M=daU[2]*M*U;
+  dbprint(printlevel-voice+2,"//...M transformed ["+string(timer-t)+" secs, "
+    +string((memory(1)+1023)/1024)+" K]");
+
+  dbprint(printlevel-voice+2,
+    "//computing integer differences of eigenvalues of M0...");
+  t=timer;
+  int k;
+  intvec ideM0;
+  ideM0[ncols(eM0)]=0;
+  for(i=ncols(eM0);i>=1;i--)
+  {
+    for(j=ncols(eM0);j>=1;j--)
+    {
+      k=int(eM0[i]-eM0[j]);
+      if(k)
+      {
+        if(k>0)
+        {
+          ideM0[i]=max(intvec(k,ideM0[i]));
+        }
+        else
+        {
+          ideM0[j]=max(intvec(-k,ideM0[j]));
+        }
+      }
+    }
+  }
+  for(i,k=size(bM0),nrows(M);i>=1;i--)
+  {
+    for(j=sum(bM0[i]);j>=1;j--)
+    {
+      ideM0[k]=ideM0[i];
+      k--;
+    }
+  }
+  dbprint(printlevel-voice+2,
+    "//...integer differences of eigenvalues of M0 computed ["+string(timer-t)
+    +" secs, "+string((memory(1)+1023)/1024)+" K]");
+
+  dbprint(printlevel-voice+2,"//transforming M...");
+  t=timer;
+  for(i=nrows(M);i>=1;i--)
+  {
+    if(!ideM0[i])
+    {
+      M[i,i]=M[i,i]+1;
+    }
+    for(j=ncols(M);j>=1;j--)
+    {
+      if(ideM0[i]&&!ideM0[j])
+      {
+        M[i,j]=M[i,j]*var(1);
+      }
+      else
+      {
+        if(!ideM0[i]&&ideM0[j])
+        {
+          M[i,j]=M[i,j]/var(1);
+        }
+      }
+    }
+  }
+  dbprint(printlevel-voice+2,"//...M transformed ["+string(timer-t)+" secs, "
+    +string((memory(1)+1023)/1024)+" K]");
+
+  return(M);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+static proc nonqhmonodromy(poly f,int mu,int opt)
+{
+  dbprint(printlevel-voice+2,"//computing kappa, xi and u with "+
+    "u*f^kappa=(matrix(jacob(f))*xi)[1,1]...");
+  list jl=jacoblift(f);
+  def kappa,xi,u=jl[1..3];
+  dbprint(printlevel-voice+2,"//...kappa, xi and u computed");
+  dbprint(printlevel-voice+2,"//kappa="+string(kappa));
+  if(kappa==1)
+  {
+    dbprint(printlevel-voice+2,
+      "//f quasihomogenous with respect to suitable coordinates");
+  }
+  else
+  {
+    dbprint(printlevel-voice+2,
+      "//f not quasihomogenous for any choice of coordinates");
+  }
+  dbprint(printlevel-voice+2,"//xi=");
+  dbprint(printlevel-voice+2,xi);
+  dbprint(printlevel-voice+2,"//u="+string(u));
+
+  int K,N,prevN;
+  list e,P1,P2,Pe,V1,V2,Ve,Vnablae;
+
+  dbprint(printlevel-voice+2,"//increasing K and N...");
+  K,N,P1,P2,Pe,V1,V2,Ve=incK(f,mu,K,1,N,e,P1,P2,Pe,V1,V2,Ve);
+  dbprint(printlevel-voice+2,"//...K and N increased");
+
+  dbprint(printlevel-voice+2,"//computing C{f}-basis e of Brieskorn lattice "
+    +"H''=Omega^(n+1)/df^dOmega^(n-1)...");
+  int t=timer;
+  e=pcvcv2p(quotV(V1+V2,N),0,N);
+  dbprint(printlevel-voice+2,"//...e computed ["+string(timer-t)+" secs, "
+    +string((memory(1)+1023)/1024)+" K]");
+
+  dbprint(printlevel-voice+2,"//e=");
+  dbprint(printlevel-voice+2,e);
+
+  Pe=e;
+  Ve=pcvp2cv(Pe,0,N);
+
+  if(kappa==1)
+  {
+    dbprint(printlevel-voice+2,
+      "//computing 0-jet M of e-matrix of t*nabla...");
+    matrix M=list(MK(f,mu,kappa,xi,u,K,N,prevN,e,V1,V2,Ve,Vnablae))[1];
+    dbprint(printlevel-voice+2,"//...M computed");
+  }
+  else
+  {
+    dbprint(printlevel-voice+2,
+      "//computing transformation matrix U to simple pole...");
+
+    dbprint(printlevel-voice+2,"//computing t*nabla-stable lattice...");
+    matrix M,prevU;
+    matrix U=freemodule(mu)*var(1)^((mu-1)*(kappa-1));
+    int i;
+    dbprint(printlevel-voice+2,"//comparing with previous lattice...");
+    t=timer;
+    for(i=mu-1;i>=1&&size(reduce(U,std(prevU)))>0;i--)
+    {
+      dbprint(printlevel-voice+2,"//...compared with previous lattice ["
+        +string(timer-t)+" secs, "+string((memory(1)+1023)/1024)+" K]");
+
+      dbprint(printlevel-voice+2,"//increasing K and N...");
+      K,N,P1,P2,Pe,V1,V2,Ve=incK(f,mu,K,kappa-1,N,e,P1,P2,Pe,V1,V2,Ve);
+      dbprint(printlevel-voice+2,"//...K and N increased");
+
+      dbprint(printlevel-voice+2,
+        "//computing (K-1)-jet M of e-matrix of t^kappa*nabla...");
+      M,prevN,Vnablae=MK(f,mu,kappa,xi,u,K,N,prevN,e,V1,V2,Ve,Vnablae);
+      dbprint(printlevel-voice+2,"//...M computed");
+
+      prevU=U;
+
+      dbprint(printlevel-voice+2,"//enlarging lattice...");
+      t=timer;
+      U=interred(jet(module(U)+module(var(1)*diff(U,var(1)))+
+        module(mdivp(M*U,var(1)^(kappa-1))),(kappa-1)*(mu-1)));
+      dbprint(printlevel-voice+2,"//...lattice enlarged ["+string(timer-t)
+        +" secs, "+string((memory(1)+1023)/1024)+" K]");
+
+      dbprint(printlevel-voice+2,"//comparing with previous lattice...");
+      t=timer;
+    }
+    dbprint(printlevel-voice+2,"//...compared with previous lattice ["
+      +string(timer-t)+" secs, "+string((memory(1)+1023)/1024)+" K]");
+    dbprint(printlevel-voice+2,"//...t*nabla-stable lattice computed");
+
+    if(ncols(U)>nrows(U))
+    {
+      dbprint(printlevel-voice+2,
+        "//computing C{f}-basis of t*nabla-stable lattice...");
+      t=timer;
+      U=minbase(U);
+      dbprint(printlevel-voice+2,
+        "//...C{f}-basis of t*nabla-stable lattice computed ["+string(timer-t)
+        +" secs, "+string((memory(1)+1023)/1024)+" K]");
+    }
+
+    U=mdivp(U,var(1)^pcvmindeg(U));
+
+    dbprint(printlevel-voice+2,"//...U computed");
+
+    dbprint(printlevel-voice+2,
+      "//computing determinant and adjoint matrix of U...");
+    list daU=detadj(U);
+    poly p=var(1)^min(intvec(pcvmindeg(daU[2]),pcvmindeg(daU[1])));
+    daU[1]=daU[1]/p;
+    daU[2]=mdivp(daU[2],p);
+    dbprint(printlevel-voice+2,
+      "//...determinant and adjoint matrix of U computed");
+
+    if(K<kappa+pcvmindeg(daU[1]))
+    {
+      dbprint(printlevel-voice+2,"//increasing K and N...");
+      K,N,P1,P2,Pe,V1,V2,Ve=
+        incK(f,mu,K,kappa+pcvmindeg(daU[1])-K,N,e,P1,P2,Pe,V1,V2,Ve);
+      dbprint(printlevel-voice+2,"//...K and N increased");
+
+      dbprint(printlevel-voice+2,"//computing M...");
+      M,prevN,Vnablae=MK(f,mu,kappa,xi,u,K,N,prevN,e,V1,V2,Ve,Vnablae);
+      dbprint(printlevel-voice+2,"//...M computed");
+    }
+
+    dbprint(printlevel-voice+2,"//transforming M/t^kappa to simple pole...");
+    t=timer;
+    M=mdivp(daU[2]*(var(1)^kappa*diff(U,var(1))+M*U),
+      leadcoef(daU[1])*var(1)^(kappa+pcvmindeg(daU[1])-1));
+    dbprint(printlevel-voice+2,"//...M/t^kappa transformed to simple pole ["
+      +string(timer-t)+" secs, "+string((memory(1)+1023)/1024)+" K]");
+  }
+
+  if(opt==0)
+  {
+    dbprint(printlevel-voice+2,
+      "//computing maximal integer difference delta of eigenvalues of M0...");
+    t=timer;
+    list jd=jordan(M);
+    def eM0,bM0=jd[1..2];
+    int delta=mid(eM0);
+    dbprint(printlevel-voice+2,"//...delta computed ["+string(timer-t)
+      +" secs, "+string((memory(1)+1023)/1024)+" K]");
+
+    dbprint(printlevel-voice+2,"//delta="+string(delta));
+
+    if(delta>0)
+    {
+      dbprint(printlevel-voice+2,"//increasing K and N...");
+      if(kappa==1)
+      {
+        K,N,P1,P2,Pe,V1,V2,Ve=incK(f,mu,K,1+delta-K,N,e,P1,P2,Pe,V1,V2,Ve);
+      }
+      else
+      {
+        K,N,P1,P2,Pe,V1,V2,Ve=
+          incK(f,mu,K,kappa+pcvmindeg(daU[1])+delta-K,N,e,P1,P2,Pe,V1,V2,Ve);
+      }
+      dbprint(printlevel-voice+2,"//...K and N increased");
+
+      dbprint(printlevel-voice+2,"//computing M...");
+      M,prevN,Vnablae=MK(f,mu,kappa,xi,u,K,N,prevN,e,V1,V2,Ve,Vnablae);
+      dbprint(printlevel-voice+2,"//...M computed");
+
+      if(kappa>1)
+      {
+        dbprint(printlevel-voice+2,
+          "//transforming M/t^kappa to simple pole...");
+        t=timer;
+        M=mdivp(invunit(daU[1]/var(1)^pcvmindeg(daU[1]),delta)*
+          daU[2]*(var(1)^kappa*diff(U,var(1))+M*U),
+          var(1)^(kappa+pcvmindeg(daU[1])-1));
+        dbprint(printlevel-voice+2,
+          "//...M/t^kappa transformed to simple pole ["+string(timer-t)
+          +" secs, "+string((memory(1)+1023)/1024)+" K]");
+      }
+
+      dbprint(printlevel-voice+2,"//decreasing delta...");
+      M=decmide(M,eM0,bM0);
+      delta--;
+      dbprint(printlevel-voice+2,"//delta="+string(delta));
+
+      while(delta>0)
+      {
+        jd=jordan(M);
+        eM0,bM0=jd[1..2];
+        M=decmide(M,eM0,bM0);
+        delta--;
+        dbprint(printlevel-voice+2,"//delta="+string(delta));
+      }
+      dbprint(printlevel-voice+2,"//...delta decreased");
+    }
+  }
+
+  dbprint(printlevel-voice+2,"//computing 0-jet M0 of M...");
+  matrix M0=jet(M,0);
+  dbprint(printlevel-voice+2,"//...M0 computed");
+
+  return(M0);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+static proc qhmonodromy(poly f,intvec w)
+{
+  dbprint(printlevel-voice+2,"//computing basis e of Milnor algebra...");
+  int t=timer;
+  ideal e=kbase(std(jacob(f)));
+  dbprint(printlevel-voice+2,"//...e computed ["+string(timer-t)+" secs, "
+    +string((memory(1)+1023)/1024)+" K]");
+
+  dbprint(printlevel-voice+2,
+    "//computing Milnor number mu and quasihomogeneous degree d...");
+  int mu,d=size(e),(transpose(leadexp(f))*w)[1];
+  dbprint(printlevel-voice+2,"...mu and d computed");
+
+  dbprint(printlevel-voice+2,"//computing te-matrix M of t*nabla...");
+  matrix M[mu][mu];
+  int i;
+  for(i=mu;i>=1;i--)
+  {
+    M[i,i]=number((transpose(leadexp(e[i])+1)*w)[1])/d;
+  }
+  dbprint(printlevel-voice+2,"//...M computed");
+
+  return(M);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc monodromyB(poly f, list #)
+"USAGE:   monodromyB(f[,opt]); f poly, opt int
+ASSUME:  The polynomial f in a series ring (local ordering) defines
+         an isolated hypersurface singularity.
+RETURN:  The procedure returns a residue matrix M of the meromorphic
+         Gauss-Manin connection of the singularity defined by f
+         or an empty matrix if the assumptions are not fulfilled.
+         If opt=0 (default), exp(-2*pi*i*M) is a monodromy matrix of f,
+         else, only the characteristic polynomial of exp(-2*pi*i*M) coincides
+         with the characteristic polynomial of the monodromy of f.
+DISPLAY: The procedure displays more comments for higher printlevel.
+EXAMPLE: example monodromyB; shows an example.
+"
+{
+  int opt;
+  if(size(#)>0)
+  {
+    if(typeof(#[1])=="int")
+    {
+      opt=#[1];
+    }
+    else
+    {
+      print("\\second parameter no int");
+      return();
+    }
+
+  }
+
+  dbprint(printlevel-voice+2,"//basering="+string(basering));
+
+  int i;
+  for(i=nvars(basering);i>=1;i--)
+  {
+    if(1<var(i))
+    {
+      i=-1;
+    }
+  }
+
+  if(i<0)
+  {
+    print("//no series ring (local ordering)");
+
+    matrix M[1][0];
+    return(M);
+  }
+  else
+  {
+    dbprint(printlevel-voice+2,"//f="+string(f));
+
+    dbprint(printlevel-voice+2,"//computing milnor number mu of f...");
+    int t=timer;
+    int mu=milnor(f);
+    dbprint(printlevel-voice+2,"//...mu computed ["+string(timer-t)+" secs, "
+      +string((memory(1)+1023)/1024)+" K]");
+
+    dbprint(printlevel-voice+2,"//mu="+string(mu));
+
+    if(mu<=0)
+    {
+      if(mu==0)
+      {
+        print("//no singularity");
+      }
+      else
+      {
+        print("//non isolated singularity");
+      }
+
+      matrix M[1][0];
+      return(M);
+    }
+    else
+    {
+      dbprint(printlevel-voice+2,"//computing weight vector w...");
+      intvec w=qhweight(f);
+      dbprint(printlevel-voice+2,"//...w computed");
+
+      dbprint(printlevel-voice+2,"//w="+string(w));
+
+      if(w==0)
+      {
+        dbprint(printlevel-voice+2,
+          "//f not quasihomogeneous with respect to given coordinates");
+        return(nonqhmonodromy(f,mu,opt));
+      }
+      else
+      {
+        dbprint(printlevel-voice+2,
+          "//f quasihomogeneous with respect to given coordinates");
+        return(qhmonodromy(f,w));
+      }
+    }
+  }
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring R=0,(x,y),ds;
+  poly f=x2y2+x6+y6;
+  matrix M=monodromyB(f);
+  print(M);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc H2basis(poly f)
+"USAGE:   H2basis(f); f poly
+ASSUME:  The polynomial f in a series ring (local ordering) defines
+         an isolated hypersurface singularity.
+RETURN:  The procedure returns a list of representatives of a C{f}-basis of the
+         Brieskorn lattice H''=Omega^(n+1)/df^dOmega^(n-1).
+THEORY:  H'' is a free C{f}-module of rank milnor(f).
+DISPLAY: The procedure displays more comments for higher printlevel.
+EXAMPLE: example H2basis; shows an example.
+"
+{
+  dbprint(printlevel-voice+2,"//basering="+string(basering));
+
+  int i;
+  for(i=nvars(basering);i>=1;i--)
+  {
+    if(1<var(i))
+    {
+      i=-1;
+    }
+  }
+
+  if(i<0)
+  {
+    print("//no series ring (local ordering)");
+
+    return(list());
+  }
+  else
+  {
+    dbprint(printlevel-voice+2,"//f="+string(f));
+
+    dbprint(printlevel-voice+2,"//computing milnor number mu of f...");
+    int t=timer;
+    int mu=milnor(f);
+    dbprint(printlevel-voice+2,"//...mu computed ["+string(timer-t)+" secs, "
+      +string((memory(1)+1023)/1024)+" K]");
+
+    dbprint(printlevel-voice+2,"//mu="+string(mu));
+
+    if(mu<=0)
+    {
+      if(mu==0)
+      {
+        print("//no singularity");
+      }
+      else
+      {
+        print("//non isolated singularity");
+      }
+
+      return(list());
+    }
+    else
+    {
+      dbprint(printlevel-voice+2,"//computing kappa, xi and u with "+
+        "u*f^kappa=(matrix(jacob(f))*xi)[1,1]...");
+      list jl=jacoblift(f);
+      def kappa,xi,u=jl[1..3];
+      dbprint(printlevel-voice+2,"//...kappa, xi and u computed");
+      dbprint(printlevel-voice+2,"//kappa="+string(kappa));
+      if(kappa==1)
+      {
+        dbprint(printlevel-voice+2,
+          "//f quasihomogenous with respect to suitable coordinates");
+      }
+      else
+      {
+        dbprint(printlevel-voice+2,
+          "//f not quasihomogenous for any choice of coordinates");
+      }
+      dbprint(printlevel-voice+2,"//xi=");
+      dbprint(printlevel-voice+2,xi);
+      dbprint(printlevel-voice+2,"//u="+string(u));
+
+      int K,N,prevN;
+      list e,P1,P2,Pe,V1,V2,Ve,Vnablae;
+
+      dbprint(printlevel-voice+2,"//increasing K and N...");
+      K,N,P1,P2,Pe,V1,V2,Ve=incK(f,mu,K,1,N,e,P1,P2,Pe,V1,V2,Ve);
+      dbprint(printlevel-voice+2,"//...K and N increased");
+
+      dbprint(printlevel-voice+2,
+        "//computing C{f}-basis e of Brieskorn lattice "
+        +"H''=Omega^(n+1)/df^dOmega^(n-1)...");
+      t=timer;
+      e=pcvcv2p(quotV(V1+V2,N),0,N);
+      dbprint(printlevel-voice+2,"//...e computed ["+string(timer-t)+" secs, "
+        +string((memory(1)+1023)/1024)+" K]");
+
+      dbprint(printlevel-voice+2,"//e=");
+      dbprint(printlevel-voice+2,e);
+
+      return(e);
+    }
+  }
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring R=0,(x,y),ds;
+  poly f=x2y2+x6+y6;
+  H2basis(f);
+}
+///////////////////////////////////////////////////////////////////////////////
diff --git a/Singular/LIB/monomialideal.lib b/Singular/LIB/monomialideal.lib
new file mode 100644
index 0000000..6dd9d5a
--- /dev/null
+++ b/Singular/LIB/monomialideal.lib
@@ -0,0 +1,3851 @@
+//////////////////////////////////////////////////////////////////////////////
+version="version monomialideal.lib 4.0.0.0 Jun_2013 "; // $Id: fd06bdc4a3b430712c535cdd05a900d6e1f737f5 $
+category = "Commutative Algebra";
+info = "
+LIBRARY: monomialideal.lib   Primary and irreducible decompositions of monomial
+                             ideals
+AUTHORS: I.Bermejo,           ibermejo at ull.es
+@*       E.Garcia-Llorente,   evgarcia at ull.es
+@*       Ph.Gimenez,          pgimenez at agt.uva.es
+
+OVERVIEW:
+ A library for computing a primary and the irreducible decompositions of a
+ monomial ideal using several methods.
+ In this library we also take advantage of the fact that the ideal is
+ monomial to make some computations that are Grobner free in this case
+ (radical, intersection, quotient...).
+
+PROCEDURES:
+ isMonomial(id);       checks whether an ideal id is monomial
+ minbaseMon(id);       computes the minimal monomial generating set of a
+                       monomial ideal id
+ gcdMon(f,g);          computes the gcd of two monomials f, g
+ lcmMon(f,g);          computes the lcm of two monomials f, g
+ membershipMon(f,id);  checks whether a polynomial f belongs to a monomial
+                       ideal id
+ intersectMon(id1,id2);intersection of monomial ideals id1 and id2
+ quotientMon(id1,id2); quotient ideal id1:id2
+ radicalMon(id);       computes the radical of a monomial ideal id
+ isprimeMon(id);       checks whether a monomial ideal id is prime
+ isprimaryMon(id);     checks whether a monomial ideal id is primary
+ isirreducibleMon(id); checks whether a monomial ideal id is irreducible
+ isartinianMon(id);    checks whether a monomial ideal id is artininan
+ isgenericMon(id);     checks whether a monomial ideal id is generic
+ dimMon(id);           dimension of a monomial ideal id
+ irreddecMon(id,..);   computes the irreducible decomposition of a monomial
+                       ideal id
+ primdecMon(id,..);    computes a minimal primary decomposition of a monomial
+                       ideal id
+";
+LIB "poly.lib";  // Para "maxdeg1" en "isprimeMon"
+//---------------------------------------------------------------------------
+//-----------------------   INTERNOS    -------------------------------------
+//---------------------------------------------------------------------------
+/////////////////////////////////////////////////////////////////////////////
+//
+static proc checkIdeal (ideal I)
+"
+USAGE:    checkIdeal (I); I ideal.
+RETURN:   1, if ideal is generated by monomials; 0, otherwise.
+"
+// Aqui NO estoy quitando el caso de que el ideal sea el trivial.
+{
+  int i,n;
+  n = ncols(I);
+  for (i = n ; i >= 1 ; i --)
+  {
+    if ( size(I[i]) > 1 )
+    {
+      return (0);
+    }
+  }
+  return (1);
+}
+/////////////////////////////////////////////////////////////////////////////
+//
+static proc quotientIdealMon (ideal I,poly f)
+"
+USAGE:    quotientIdealMon(I,f); I ideal, f polynomial.
+RETURN:   an ideal, the quotient ideal I:(f).
+ASSUME:   I is an ideal generated by a list of monomials and f is a monomial
+          of the basering.
+"
+{
+  // Variables
+  int i,j;
+  poly g,generator;
+  intvec v;
+  ideal J;
+  J = 0;
+
+  int sizI = ncols(I);
+  for (i = 1 ; i <= sizI ; i++)
+  {
+    g = gcd(I[i],f);
+    // Cociente de dos monomios: restamos los exponentes, y en el
+    // denominador va el mcd
+    v = leadexp(I[i]) - leadexp(g);
+    generator = monomial (v);
+    if (membershipMon(generator,J) == 0)
+    {
+      J=J,generator;
+    }
+  }
+  // minimal monomial basis
+  return ( minbase(J) );
+}
+/////////////////////////////////////////////////////////////////////////////
+//
+static proc soporte (poly f)
+"
+USAGE:    soporte(f); f polynomial.
+RETURN:   0, if the monomial f is product of more than one variable;
+          otherwise, an integer j, 1<=j<=n, if the monomial f is a power of
+          x(j).
+ASSUME:   f is a monomial of the basering K[x(1)..x(n)].
+"
+{
+  // Variables
+  int i,cont,sop;
+  intvec expf;
+  int nvar = nvars(basering);
+  expf = leadexp(f);
+  cont = 0;
+  // cont va a contar el numero de componentes del vector no nulas.
+  // En sop guardamos el subindice de la componente no nula.
+  for (i = nvar ; i >= 1 ; i--)
+  {
+    if (expf[i] > 0)
+    {
+      cont ++;
+      sop = i;
+      // Si cont > 1 ==> aparece mas de una variable, devolvemos 0
+      if (cont > 1)
+      {
+        return (0);
+      }
+    }
+  }
+  return(sop);
+}
+/////////////////////////////////////////////////////////////////////////////
+//
+static proc irredAux (ideal I)
+"
+USAGE:    irredAux (I); I ideal.
+RETURN:   1, if I is irreducible; otherwise, an intvec whose fist entry is
+          the position of a generator which is the product of more than one
+          variable, the next entries are the indexes of those variables.
+ASSUME:   I is a monomial ideal of the basering K[x(1)..x(n)] and it is
+          generated by its minimal monomial generators.
+NOTE:     This procedure is a modification of isirreducibleMon to give
+          more information when ideal is not irreducible.
+"
+{
+  // Variables
+  int sizI,i,nvar,j,sum;
+  intvec w,exp;
+  sizI = ncols(I);
+  nvar = nvars(basering);
+  for (i = 1 ; i <= sizI ; i++)
+  {
+    sum = 0;
+    exp = leadexp(I[i]);
+    for (j = 1 ; j <= nvar ; j++)
+    {
+      // Al menos tenemos una variable en cada generador, luego
+      // entramos minimo 1 vez, luego sum >= 1.
+      if (exp[j] <> 0)
+      {
+        sum++;
+        w[sum] = j;
+      }
+    }
+    // Si hay mas de una variable la suma sera mayor que 1; y ya
+    // sabemos que I no es irreducible.
+    if (sum <> 1)
+    {
+      return(i,w);
+    }
+  }
+  return(1);
+}
+//////////////////////////////////////////////////////////////////////
+//
+static proc contents (ideal I,ideal J)
+"
+USAGE:    contents (I,J); I,J ideals.
+RETURN:   1, if I is contained in J; 0, otherwise.
+ASSUME:   I,J are monomial ideals of the basering.
+"
+{
+  // Variables
+  poly f;
+  int i,resp;
+  int n = ncols(I);
+  // Desde que haya un generador que no pertenzca al ideal, ya no se da
+  // el contenido y terminamos.
+  for (i = 1 ; i <= n ; i++)
+  {
+    resp = membershipMon(I[i],J);
+    if (resp == 0)
+    {
+      return(0);
+    }
+  }
+  return(1);
+}
+/////////////////////////////////////////////////////////////////////////////
+//
+static proc equal (ideal I,ideal J)
+"
+USAGE:    equal (I,J); I,J ideals.
+RETURN:   1, if I and J are the same ideal; 0, otherwise.
+ASSUME:   I,J are monomial ideals of the basering and are defined by their
+          minimal monomial generators.
+"
+{
+  // Variables
+  int n,i,j;
+  intvec resps;
+  // Si no tienen el mismo numero de generadores, no pueden ser iguales; ya
+  // que vienen dados por el sistema minimal de generadores.
+  if (size(I) <> size(J))
+  {
+    return(0);
+  }
+  // Como ambos ideales vienen dados por la base minimal, no vamos a
+  // tener problemas con que comparemos uno de I con otro de J, pues
+  // no puede haber generadores iguales en el mismo ideal.
+  // Si los ordenamos, se puede comparar uno a uno
+  return(matrix( sort(I)[1])==matrix(sort(J)[1]));
+  //n = size(I);
+  //I = sort(I)[1];
+  //J = sort(J)[1];
+  //for (i = 1 ; i <= n ; i++)
+  //{
+  //  if (I[i] <> J[i])
+  //  {
+  //    return(0);
+  //  }
+  //}
+  //return(1);
+}
+/////////////////////////////////////////////////////////////////////////////
+//
+static proc radicalAux (ideal I)
+"
+USAGE:    radicalAux (I); I ideal.
+RETURN:   an ideal, the radical ideal of I
+ASSUME:   I is an irreducible monomial ideal of the basering given by its
+          minimal monomial generators.
+"
+{
+  // Cambiamos de anillo
+  int nvar = nvars(basering);
+  // Variables
+  int i,cont;
+  intvec exp;
+  ideal rad;
+  // Como en cada generador aparece solo una variable,  y ademas la
+  // la misma variable no va a aparecer dos veces, es suficiente
+  // con sumar los exponentes de todos los generadores para saber que
+  // variables aparecen.
+  int n = ncols(I);
+  for (i = 1 ; i <= n ; i++)
+  {
+    exp = exp + leadexp (I[i]);
+  }
+  cont = 1;
+  for (i = 1 ; i <= nvar ; i++)
+  {
+    if (exp[i] <> 0)
+    {
+      rad[cont] = var(i);
+      cont ++;
+    }
+  }
+  return (rad);
+}
+/////////////////////////////////////////////////////////////////////////////
+//
+static proc primAux (ideal I)
+"
+USAGE:    primAux (I); I ideal.
+RETURN:   1, if I is primary; otherwise, an intvec, whose first element is
+          0, the second is the index of one variable such that a power of it
+          does not appear as a generator of I, the rest of the elements are
+          the situation in the ideal of that elements of I which
+          are product of more than one variable.
+ASSUME:   I is a monomial ideal of the basering K[x(1)..x(n)].
+NOTE:     This procedure detects if the ideal is primary, when the
+          ideal is not primary, it gives some additional information.
+"
+{
+  // Variables
+  int control,nvar,i,sub_in,l,j;
+  intvec v,w,exp_gen;
+  // El ideal ya entra generado por el sistema minimal
+  nvar = nvars(basering);
+  int sizI = ncols(I);
+  v[nvar] = 0;
+  int cont = 1;
+  // v = 1 en la posicion en el ideal de variables sueltas, que son
+  // las que no hay que tocar, 0 en las demas. w = posiciones de los
+  // generadores de I que hay que comprobar.
+  for (i = 1 ; i <= sizI ; i++ )
+  {
+    sub_in = soporte(I[i]);
+    if ( sub_in <> 0)
+    {
+      v[sub_in] = 1;
+    }
+    else
+    {
+      w[cont] = i;
+      cont ++;
+    }
+  }
+  l = size(w);
+  // No hay ningun generador que tenga productos de variables, luego
+  //  este ideal ya es primario.
+  if (l == 1 && w[1] == 0)
+  {
+    return (1);
+  }
+  for (i = 1 ; i <= l ; i++)
+  {
+    exp_gen = leadexp(I[w[i]]);
+    // Ahora hay que ver que valor tiene el exponente de los
+    // generadores oportunos en la posicion que es cero dentro del
+    // vector v.
+    for (j = 1 ; j <= nvar ; j++)
+    {
+      if (v[j] == 0)
+      {
+        if (exp_gen[j] <> 0)
+        {
+          return (0,j,w);
+        }
+      }
+    }
+  }
+  // Si hemos llegado hasta aqui hemos recorrido todo el ideal y por tanto
+  // es primario.
+  return (1);
+}
+/////////////////////////////////////////////////////////////////////////////
+//
+static proc maxExp (ideal I,intvec v)
+"
+USAGE:    maxExp (I,v); I ideal, v integer vector.
+RETURN:   an integer, the greatest power of a variable in the minimal
+          monomial set of generators of I.
+ASSUME:   I is a monomial ideal of the basering, v=primAux(I) and the
+          variable considered is v[2].
+          If the ideal I is primary, it returns 0.
+NOTE:     The elements of the vector shows what variable and what
+          generators we must consider to look for the greatest power
+          of this variable.
+"
+{
+  // Variables
+  int n,i,max;
+  intvec exp;
+  // Ponemos el tama?o de v menos 2 porque en el vector v a partir de
+  // la tercera componente es donde tenemos la posicion de los
+  // generadores que tenemos que estudiar.
+  n = size(v)-2;
+  // Buscamos el maximo de la variable que no aparece "sola" en los
+  // generadores del ideal (donde nos indica v).
+  max = 0;
+  for (i = 1 ; i <= n ; i++)
+  {
+    exp = leadexp (I[v[i+2]]);
+    if (exp[v[2]] > max)
+    {
+      max = exp[v[2]];
+    }
+  }
+  return (max);
+}
+/////////////////////////////////////////////////////////////////////////////
+//
+static proc irredundant (list l)
+"
+USAGE:    irredundant (l); l, list.
+RETURN:   a list such that the intersection of the elements in that list has
+          no redundant component.
+ASSUME:   elements of l are monomial ideals of the basering.
+"
+{
+  // Variables
+  int i,j,resp;
+  ideal J;
+  // Recalculamos el tamano de l cuando modificamos la lista (sizl)
+  int sizl = size(l);
+  for (i = 1 ; i <= sizl ; i++)
+  {
+    J = 1;
+    for (j = 1 ; j <= sizl ; j++)
+    {
+      // Hacemos la interseccion de todos los ideales menos uno y
+      // luego se estudia el contenido.
+      if (j <> i)
+      {
+        J = intersect (J,l[j]);
+      }
+    }
+    J = minbase(J);
+    resp = contents(J,l[i]);
+    if (resp == 1)
+    {
+      l = delete (l,i);
+      i--;
+      sizl = size(l);
+    }
+  }
+  return (l);
+}
+/////////////////////////////////////////////////////////////////////////////
+//
+static proc alexDif (intvec v,ideal I)
+"
+USAGE:    alexDif (v,I); v, intvec; I, ideal.
+RETURN:   a list, irreducible monomial ideals whose intersection is the
+          Alexander dual of I with respect to v.
+ASSUME:   I is a monomial ideal of the basering K[x(1),...,x(n)] given by
+          its minimal monomial generators and v is an integer vector with
+          n entries s.t.monomial(v) is a multiple of all minimal monomial
+          generators of I.
+"
+{
+  // Cambiamos de anillo
+  int nvar = nvars(basering);
+  // Variables
+  int i,j;
+  intvec exp_I,exp;
+  list l;
+  ideal J;
+  int sizI = ncols(I);
+  // Vamos a tener tantas componentes como generadores minimales tiene el
+  // ideal, por eso el bucle es de 1 a size(I).
+  for (i = 1 ; i <= sizI ; i++)
+  {
+    J = 0;
+    exp_I = leadexp (I[i]);
+    for (j = 1 ; j <= nvar ; j++)
+    {
+      if (exp_I[j] <> 0)
+      {
+        exp[j] = v[j] + 1 - exp_I[j];
+        J = J, var(j)^exp[j];
+      }
+    }
+    // Tenemos siempre un cero por la inicializacion de J, entonces
+    // lo quitamos.
+    J = simplify (J,2);
+    l = insert (l,J);
+  }
+  return (l);
+}
+/////////////////////////////////////////////////////////////////////////////
+//
+static proc irredPrimary (list l1)
+"
+USAGE:    irredPrimary (l1); l1, list of ideals.
+RETURN:   a list, primary monomial ideals whose intersection is an
+          irredundant primary decomposition.
+ASSUME:   list l1 is the list of the irredundant irreducible components of a
+          monomial ideal I of the basering.
+"
+{
+  // Variables
+  int i,sizl1,sizl2,j;
+  ideal J,K;
+  list l2,l3;
+//----- irredundant primary decomposition
+  sizl1 = size(l1);
+  for (i = 1 ; i <= sizl1 ; i++)
+  {
+    l2[i] = radicalAux (l1[i]);
+  }
+  sizl2 = size(l2);
+  int sizl2i, sizl2j;
+  // Looking for irreducible components whose radicals are equal.
+  // l1 = irreducible components list
+  // l2 = radical of irreducible components list
+  // l3 = primary components list
+  for (i = 1 ; i <= sizl1 ; i++)
+  {
+    J = l2[i];
+    sizl2i = size(l2[i]);
+    K = l1[i];
+    for (j = i+1 ; j <= sizl2 ; j++)
+    {
+      sizl2j = size(l2[j]);
+      if (sizl2i == sizl2j)
+      {
+        if (equal (J,l2[j]) == 1)
+        {
+          K = minbase(intersect (K,l1[j]));
+          l1 = delete (l1,j);
+          sizl1 = size(l1);
+          l2 = delete (l2,j);
+          sizl2 = size(l2);
+          j--;
+        }
+      }
+    }
+    l3 = insert (l3,K);
+  }
+  return (l3);
+}
+/////////////////////////////////////////////////////////////////////////////
+//
+static proc isMinimal (ideal I)
+"
+USAGE:    isMinimal (I); I ideal.
+RETURN:   1, if the generators of I are the minimal ones;
+          0 & minimal generators of I, otherwise.
+ASSUME:   I is an ideal of the basering generated by monomials.
+"
+{
+  // VARIABLES
+  int i;
+  ideal J;
+ // Quitamos los ceros del sistema de generadores.
+  I = simplify(I,2);
+  int resp = 1;
+  int sizI = ncols(I);
+  // Cambiamos el tamano de I cuando eliminamos generadores
+  for (i = 1 ; i <= sizI ; i++)
+  {
+    if (sizI <> 1)
+    {
+      if (i == 1)
+      {
+        J = I[2..sizI];
+      }
+      else
+      {
+        if (i > 1 && i < sizI)
+        {
+          J = I[1..i-1], I[i+1..sizI];
+        }
+        else
+        {
+          J = I[1..sizI-1];
+        }
+      }
+      // Si quitamos el generador del lugar "i", luego el que
+      // ocupa ahora el lugar "i" es el "i+1", de ahi que restemos
+      // 1 al i para volver al for de manera que recorramos los
+      // generadores como debemos.
+      if (membershipMon(I[i],J) == 1)
+      {
+        resp = 0;
+        I = J;
+        i--;
+        sizI = size(I);
+      }
+    }
+  }
+  if (resp == 1)
+  {
+    return (1);
+  }
+  else
+  {
+    return (0,I);
+  }
+}
+/////////////////////////////////////////////////////////////////////////////
+//
+static proc isMonomialGB (ideal I)
+"
+USAGE:    isMonomialGB (I); I ideal.
+RETURN:   a list, 1 & the minimal generators of I, if I is a monomial ideal;
+          0, otherwise.
+ASSUME:   I is an ideal of the basering which is not generated by
+          monomials.
+NOTE:     this procedure is NOT Grobner free and should be used only if the
+          ideal has non-monomial generators (use first checkIdeal)
+"
+{
+  // Variables
+  int resp;
+  // Si el ideal es cero, no es monomial.
+  if ( size(I) == 0)
+  {
+    return(0);
+  }
+  // Queremos la base de Grobner reducida, para uncidad.
+  intvec save_opt=option(get);
+  option(redSB);
+  // Base de Grobner
+  I = std(I);
+  option(set,save_opt);
+  // Una vez que tenemos la GB, no es mas que comprobar que el ideal
+  // esta generado por monomios.
+  resp = checkIdeal(I);
+  if (resp == 0)
+  {
+    return (0);
+  }
+  else
+  {
+    return (1,I);
+  }
+}
+/////////////////////////////////////////////////////////////////////////////
+//
+// Comparing irreducible decompsitions
+// WARNING: this is not a test, when the answer is 1 and the decompositions
+//          may not coincide but it is fast and easy and when the answer is
+//          0 the decomposition do not coincide.
+//
+proc areEqual(list l1,list l2)
+{
+  int i,j,sizIdeal;
+  poly generator;
+  ideal l1Ideal,l2Ideal;
+  int sizl1 = size(l1);
+  for (i = 1 ; i <= sizl1 ; i ++)
+  {
+    sizIdeal = size(l1[i]);
+    generator = 1;
+    for (j = 1 ; j <= sizIdeal ; j ++)
+    {
+      generator = generator*l1[i][j];
+    }
+    l1Ideal[i] = generator;
+  }
+  int sizl2 = size(l2);
+  for (i = 1 ; i <= sizl2 ; i ++)
+  {
+    sizIdeal = size(l2[i]);
+    generator = 1;
+    for (j = 1 ; j <= sizIdeal ; j ++)
+    {
+      generator = generator*l2[i][j];
+    }
+    l2Ideal[i] = generator;
+  }
+  return (equal(l1Ideal,l2Ideal));
+}
+/////////////////////////////////////////////////////////////////////////////
+//-------------------------------------------------------------------------//
+//-----------------------   EXTERNOS   ------------------------------------//
+//-------------------------------------------------------------------------//
+/////////////////////////////////////////////////////////////////////////////
+//
+proc isMonomial (ideal I)
+"USAGE:    isMonomial (I); I ideal.
+RETURN:   1, if I is monomial ideal; 0, otherwise.
+ASSUME:   I is an ideal of the basering.
+EXAMPLE:  example isMonomial; shows some examples.
+"
+{
+  // Si el ideal es cero, no es monomial.
+  if ( size(I) == 0)
+  {
+    return(0);
+  }
+  // Si ya viene dado por sistema de generadores monomiales, devolvemos 1
+  if (checkIdeal (I) == 1)
+  {
+    return(1);
+  }
+  // Variables
+  int resp,m,k;
+  // Queremos la base de Grobner reducida, para uncidad.
+  intvec save_opt=option(get);
+  option(redSB);
+  // Hallamos GB
+  I = std(I);
+  option(set,save_opt);
+  // Una vez que tenemos la GB, no es mas que comprobar si el ideal
+  // esta generado por monomios.
+  resp = checkIdeal(I);
+  // Volvemos a dejar el comando "std" devolviendo una GB estandar.
+  return(resp);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+ ring R = 0,(w,x,y,z,t),lp;
+ ideal I = w^3*x*y, w^2*x^2*y^2*z^2 - y^3*z+x^4*z^4*t^4, w*x*y*z*t - w*x^6*y^5*z^4, x^2*z^4*t^3 , w^6*y^4*z^2 + x^2*y^2*z^2;
+ isMonomial(I);
+ ideal J = w^3*x*y + x^3*y^9*t^3, w^2*x^2*y^2*z^2 - y^3*z, w*x*y*z*t - w*x^6*y^5*z^4, x^2*z^4*t^3 + y^4*z^4*t^4, w^6*y^4*z^2 + x^2*y^2*z^2;
+ isMonomial(J);
+}
+/////////////////////////////////////////////////////////////////////////////
+//
+proc minbaseMon (ideal I)
+"USAGE:    minbaseMon (I); I ideal.
+RETURN:   an ideal, the minimal monomial generators of I.
+          (-1 if the generators of I are not monomials)
+ASSUME:   I is an  ideal generated by a list of monomials of the basering.
+EXAMPLE:  example minbaseMon; shows an example.
+"
+{
+  // VARIABLES
+  int i;
+  ideal J;
+  // Si no esta generado por monomios este metodo no vale
+  int control = checkIdeal(I);
+  if (control == 0)
+  {
+    return (-1);
+  }
+  // Quitamos los ceros del sistema de generadores.
+  I = simplify(I,2);
+  int sizI = ncols(I);
+  for (i = 1 ; i <= sizI ; i++)
+  {
+    if (sizI > 1)
+    {
+      if (i == 1)
+      {
+        J = I[2..sizI];
+      }
+      else
+      {
+        if (i > 1 && i < sizI)
+        {
+          J = I[1..i-1], I[i+1..sizI];
+        }
+        else
+        {
+          if (i == sizI)
+          {
+            J = I[1..sizI-1];
+          }
+        }
+      }
+      // Si quitamos el generador del lugar "i", luego el que
+      // ocupa ahora el lugar "i" es el "i+1", de ahi que restemos
+      // 1 al i para volver al for de manera que recorramos los
+      // generadores como debemos.
+      if (membershipMon(I[i],J) == 1)
+      {
+        I = J;
+        i--;
+        sizI = ncols(I);
+      }
+    }
+  }
+  return (I);
+}
+example
+{"EXAMPLE:"; echo = 2;
+ ring R = 0,(w,x,y,z,t),lp;
+ ideal I = w^3*x*y, w^2*x^2*y^2*z^2, y^3*z,x^4*z^4*t^4, w*x*y*z*t,w*x^6*y^5*z^4, x^2*z^4*t^3 , w^6*y^4*z^2,x^2*y^2*z^2;
+ minbaseMon(I);
+}
+/////////////////////////////////////////////////////////////////////////////
+//
+proc gcdMon (poly f,poly g)
+"USAGE:    gcdMon (f,g); f,g polynomials.
+RETURN:   a monomial, the greatest common divisor of f and g.
+ASSUME:   f and g are monomials of the basering.
+EXAMPLE:  example gcdMon; shows an example.
+"
+{
+  if (size(f) <> 1 or size(g) <> 1)
+  {
+    ERROR ("the input must be 2 monomials.");
+  }
+  return(gcd(f,g));
+
+//  // Variables
+//  int k;
+//  intvec exp;
+//  int nvar = nvars(basering);
+//  // intput: monomials
+//
+//  intvec expf = leadexp(f);
+//  intvec expg = leadexp(g);
+//  // Nos quedamos con el menor exponente de cada variable.
+//  for (k = 1 ; k <= nvar ; k++)
+//    {
+//      if (expf[k] <= expg[k])
+//        {
+//          exp[k] = expf[k];
+//        }
+//      else
+//        {
+//          exp[k] = expg[k];
+//        }
+//    }
+//  // Devolvemos el monomio correspondiente al exponente que hemos
+//  // calculado.
+//  return(monomial(exp));
+}
+example
+{"EXAMPLE:"; echo = 2;
+  ring R = 0,(x,y,z,t),dp;
+  poly f = x^3*z^5*t^2;
+  poly g = y^6*z^3*t^3;
+  gcdMon(f,g);
+}
+/////////////////////////////////////////////////////////////////////////////
+//
+proc lcmMon (poly f,poly g)
+"USAGE:    lcmMon (f,g); f,g polynomials.
+RETURN:   a monomial,the least common multiple of f and g.
+ASSUME:   f,g are monomials of the basering.
+EXAMPLE:  example lcmMon; shows an example.
+"
+{
+  // Hay que verificar que son monomios
+  if (size(f) <> 1 or size(g) <> 1)
+  {
+    ERROR ("the input must be 2 monomials.");
+  }
+  return(f*g/gcd(f,g));
+  //// Variables.
+  //int k;
+  //intvec exp;
+  //int nvar = nvars(basering);
+
+  //// No tenemos mas que tomar el mayor exponente.
+  //intvec expf = leadexp (f);
+  //intvec expg = leadexp (g);
+
+  //for (k = 1 ; k <= nvar ; k ++)
+  //{
+  //  if (expf[k] <= expg[k])
+  //  {
+  //    exp[k] = expg[k];
+  //  }
+  //  else
+  //  {
+  //     exp[k] = expf[k];
+  //  }
+  //}
+  //// Transformamos el vector de exponentes al monomio correspondiente.
+  //return(monomial (exp));
+}
+example
+{"EXAMPLE:"; echo = 2;
+  ring R = 0,(x,y,z,t),dp;
+  poly f = x^3*z^5*t^2;
+  poly g = y^6*z^3*t^3;
+  lcmMon(f,g);
+}
+//////////////////////////////////////////////////////////////////////
+//
+proc membershipMon(poly f,ideal I)
+"USAGE:    membershipMon(f,I); f polynomial, I ideal.
+RETURN:   1, if f lies in I; 0 otherwise.
+          (-1 if I and f are nonzero and I is not a monomial ideal)
+ASSUME:   I is a monomial ideal of the basering.
+EXAMPLE:  example membershipMon; shows some examples
+"
+{
+  // Variables
+  int i,j,resp,k,control;
+  intvec restf;
+  // Si el ideal es cero no es monomial, pero la pertenencia no se da si
+  // el polinomio es no nulo
+  if ( size(I) == 0 && size(f) > 0)
+  {
+    return (0);
+  }
+ // El cero esta en todos los ideales.
+  if (f == 0)
+  {
+    return (1);
+  }
+  // COMPROBACIONES
+  control = checkIdeal(I);
+  if (control == 0)
+  {
+    list isMon = isMonomialGB (I);
+    if (isMon[1] == 0)
+    {
+      ERROR ("the ideal is not monomial.");
+    }
+    else
+    {
+      // Sabemos que I ya viene dado por el sistema minimal de
+      // generadores, aunque aqui no sea necesario.
+      I = isMon[2];
+    }
+  }
+  // Quitamos ceros.
+  I = simplify(I,2);
+  int n = ncols(I);
+  int m = size(f);
+  int nvar = nvars(basering);
+  for (i=1 ; i<=m ; i++)
+  {
+    resp = 0;
+    for (j=1 ; j<=n  ;j++)
+    {
+      // Vamos termino a termino viendo si son divididos por algun
+      // generador. Trabajamos con los exponentes, pues es mas
+      // simple.
+      restf = leadexp(f) - leadexp(I[j]);
+      for (k=1 ; k<=nvar; k++)
+      {
+        // Si hay una componente negativa es que este generador
+        // no divide. Queremos entonces ir al siguiente
+        // generador.
+        if (restf[k] < 0)
+        {
+          break;
+        }
+      }
+      // Si no ha habido componente nula, hemos encontrado un
+      // divisor para el actual termino de f. En esta situacion
+      // queremos pasar a otro termino de f, no seguir con los
+      // otros generadores.
+      if (k == nvar+1)
+      {
+        resp = 1;
+        break;
+      }
+    }
+    // Si hemos encontrado para el anterior termino, voy al
+    // siguiente; en caso contrario salimos, pues desde que un
+    // termino no sea dividido, f no esta en I.
+    if (resp == 1)
+    {
+      f = f - lead(f);
+    }
+    else
+    {
+      break;
+    }
+  }
+  // Si hemos recorrido todo el bucle, f esta en I.
+  if (i == m+1)
+  {
+    return (1);
+  }
+  return (0);
+}
+example
+{"EXAMPLE:"; echo = 2;
+ ring R = 0,(w,x,y,z,t),lp;
+ ideal I =  w*x, x^2, y*z*t, y^5*t;
+ poly f =  3*x^2*y + 6*t^5*z*y^6 - 4*x^2 + 8*w*x^5*y^6 - 10*y^10*t^10;
+ membershipMon(f,I);
+ poly g = 3*w^2*t^3 - 4*y^3*z*t^3 - 2*x^2*y^5*t + 4*x*y^3;
+ membershipMon(g,I);
+}
+//////////////////////////////////////////////////////////////////////
+//
+proc intersectMon (ideal I,ideal J)
+"USAGE:    intersectMon (I,J); I,J ideals.
+RETURN:   an ideal, the intersection of I and J.
+          (it returns -1 if I or J are not monomial ideals)
+ASSUME:   I,J are monomial ideals of the basering.
+NOTE:     the minimal monomial generating set is returned.
+EXAMPLE:  example intersectMon; shows some examples
+"
+{
+  // Variables
+  ideal K;
+  int i,j,control;
+  list isMon;
+  // El ideal trivial no es monomial.
+  if ( size(I) == 0 || size(J) == 0)
+  {
+    ERROR("one of the ideals is zero, hence not monomial.");
+  }
+ // COMPROBACIONES
+  control = checkIdeal(I);
+  if (control == 0)
+  {
+    isMon = isMonomialGB(I);
+    if (isMon[1] == 0)
+    {
+      ERROR ("the first ideal is not monomial.");
+    }
+    else
+    {
+      // Sabemos que I ya viene dado por el sistema minimal de
+      // generadores, aunque aqui no sea necesario.
+      I = isMon[2];
+    }
+  }
+  else
+  {
+    // Los generadores son monomiales, hallamos el sistema minimal
+    I = minbase(I);
+  }
+  control = checkIdeal(J);
+  if (control == 0)
+  {
+    isMon = isMonomialGB (J);
+    if (isMon[1] == 0)
+    {
+      ERROR ("the second ideal is not monomial.");
+    }
+    else
+    {
+      // Sabemos que J ya viene dado por el sistema minimal de
+      // generadores, aunque aqui no sea necesario.
+      J = isMon[2];
+    }
+  }
+  else
+  {
+    // Los generadores son monomiales,hallamos la base minimal
+    J = minbase(J);
+  }
+  // Hemos asegurado que los ideales sean monomiales.
+  // Quitamos ceros de la base para no alargar calculos.
+  int n = ncols(I);
+  int m = ncols(J);
+  // Hallamos el m.c.m.de cada par de generadores de uno y otro ideal
+  // y los a?adimos al ideal interseccion.
+  for (i=1 ; i<=n ; i++)
+  {
+    for (j=1 ; j<=m ; j++)
+    {
+      K = K , lcmMon (I[i],J[j]);
+    }
+  }
+  // Devolvemos el ideal ya dado por la base minimal porque sabemos
+  // que este procedimiento genera muchos generadores redundantes.
+  return(minbase(K));
+}
+example
+{"EXAMPLE:"; echo = 2;
+ ring R = 0,(w,x,y,z,t),lp;
+ ideal I = w^3*x*y,w*x*y*z*t,x^2*y^2*z^2,x^2*z^4*t^3,y^3*z;
+ ideal J = w*x, x^2, y*z*t, y^5*t;
+ intersectMon (I,J);
+}
+//////////////////////////////////////////////////////////////////////
+//
+proc quotientMon (ideal I,ideal J)
+"USAGE:    quotientMon (I,J); I,J ideals.
+RETURN:   an ideal, the quotient I:J.
+          (returns -1 if I or J is not monomial)
+ASSUME:   I,J are monomial ideals of the basering.
+NOTE:     the minimal monomial generating set is returned.
+EXAMPLE:  example quotientMon; shows an example.
+"
+{
+  // Variables
+  int i,control,n;
+  poly f;
+  list isMon;
+  //COMPROBACIONES
+  if (size(I) == 0 || size(J) == 0)
+  {
+    ERROR("one of the ideals is zero, hence not monomial.");
+  }
+  control = checkIdeal(I);
+  if (control == 0)
+  {
+    isMon = isMonomialGB (I);
+    if (isMon[1] == 0)
+    {
+      ERROR ("the first ideal is not monomial.");
+    }
+    else
+    {
+      // Sabemos que I ya viene dado por el sistema minimal de
+      // generadores, aunque aqui no sea necesario.
+      I = isMon[2];
+    }
+  }
+  else
+  {
+    // Los generadores son monomiales,hallamos sistema minimal
+    I = minbase(I);
+  }
+  control = checkIdeal(J);
+  if (control == 0)
+  {
+    isMon = isMonomialGB (J);
+    if (isMon[1] == 0)
+    {
+      ERROR ("the second ideal is not monomial.");
+      return (-1);
+    }
+    else
+    {
+      // Sabemos que J ya viene dado por el sistema minimal de
+      // generadores, aunque aqui no sea necesario.
+      J = isMon[2];
+    }
+  }
+  else
+  {
+    // Los generadores son monomiales, hallamos el sistema minimal
+    J = minbase(J);
+  }
+  // Tenemos los ideales dados por su sistema minimal (aunque no es necesario, ahorra
+  // calculos. En K vamos a tener la interseccion de los ideales.
+  ideal K = 1;
+  // ------ Empezamos a hacer el cociente.
+  // Los ideales estan dados por su sistema minimal, con lo que no aparecen ceros.
+  // Luego podemos usar size(J).
+  n = ncols(J);
+  for (i = 1 ; i <= n ; i++)
+  {
+    K = intersect (K ,quotientIdealMon(I,J[i]));
+  }
+  // Aqui tambien surgen muchos generadores que no forman parte de la
+  // base minimal del ideal obtenido.
+  return(minbase(K));
+}
+example
+{"EXAMPLE:"; echo = 2;
+ ring R = 0,(w,x,y,z,t),lp;
+ ideal I = w^3*x*y,w*x*y*z*t,x^2*y^2*z^2,x^2*z^4*t^3,y^3*z;
+ ideal J = w*x, x^2, y*z*t, y^5*t;
+ quotientMon (I,J);
+}
+//////////////////////////////////////////////////////////////////////
+//
+proc radicalMon(ideal I)
+"USAGE:    radicalMon(I); I ideal
+RETURN:   an ideal, the radical ideal of the ideal I.
+          (returns -1 if I is not a monomial ideal)
+ASSUME:   I is a monomial ideal of the basering.
+NOTE:     the minimal monomial generating set is returned.
+EXAMPLE:  example radicalMon; shows an example.
+"
+{
+  // Cambiamos de anillo
+  int nvar = nvars(basering);
+  // Variables
+  int i,m,j,control;
+  poly f;
+  intvec v;
+  ideal rad_I;
+  // COMPROBACIONES
+  control = checkIdeal(I);
+  // Si el sistema de generadores no esta formado por monomios, hay
+  // que comprobar si el ideal es monomial.
+  if (control == 0)
+  {
+    list isMon = isMonomialGB (I);
+    if (isMon[1] == 0)
+    {
+      ERROR ("the ideal is not monomial.");
+    }
+    else
+    {
+      I = isMon[2];
+      // Ya lo tenemos con los generadores monomiales minimales
+    }
+  }
+  else
+  {
+    // Generadores monomiales, hallamos sistema minimal
+    I = minbase(I);
+  }
+  // Ya tenemos el ideal generado por la BASE MINIMAL MONOMIAL
+  m = ncols(I);
+  // Solo hay que poner exponente 1 a todas las variables que tengan
+  // exponente >1.
+  for (i = 1 ; i <= m ; i++)
+  {
+    v = leadexp(I[i]);
+    f = 1;
+    for (j = 1 ; j <= nvar ; j++)
+    {
+      if (v[j] <> 0)
+      {
+        f = f*var(j);
+      }
+    }
+    rad_I = rad_I,f;
+  }
+  // Hay que devolver el ideal dado por la base minimal, pues se
+  // producen muchos generadores redundantes.
+  return( minbase (rad_I));
+}
+example
+{"EXAMPLE:"; echo = 2;
+ ring R = 0,(w,x,y,z,t),lp;
+ ideal I = w^3*x*y,w*x*y*z*t,x^2*y^2*z^2,x^2*z^4*t^3,y^3*z;
+ radicalMon(I);
+}
+//////////////////////////////////////////////////////////////////////
+//
+proc isprimeMon (ideal I)
+"USAGE:    isprimeMon (I); I ideal
+RETURN:   1, if I is prime; 0, otherwise.
+          (returns -1 if I is not a monomial ideal)
+ASSUME:   I is a monomial ideal of the basering.
+EXAMPLE:  example isprimeMon; shows some example.
+"
+{
+  // Variables
+  int control,i,j,suma;
+  intvec expin;
+ // COMPROBACIONES
+  control = checkIdeal(I);
+  // Si el sistema de generadores no esta formado por monomios, hay
+  // que comprobar si el ideal es monomial.
+  if (control == 0)
+  {
+    list isMon = isMonomialGB (I);
+    if (isMon[1] == 0)
+    {
+      ERROR ("the ideal is not monomial.");
+    }
+    else
+    {
+      I = isMon[2];
+      // Ya lo tenemos con los generadores minimales
+    }
+  }
+  else
+  {
+    // Generadores monomiales, hallamos el sistema minimal
+    I = minbase(I);
+  }
+  // Ya tenemos el ideal generado por la BASE MINIMAL
+  if (maxdeg1(I) == 1)
+  {
+    return (1);
+  }
+  return (0);
+}
+example
+{"EXAMPLE:"; echo = 2;
+ ring R = 0,(w,x,y,z,t),lp;
+ ideal I = w,y,t;
+ isprimeMon (I);
+ ideal J = w,y,t,x*z;
+ isprimeMon (J);
+}
+//////////////////////////////////////////////////////////////////////
+//
+proc isprimaryMon (ideal I)
+"USAGE:    isprimaryMon (I); I ideal
+RETURN:   1, if I is primary; 0, otherwise.
+          (returns -1 if I is not a monomial ideal)
+ASSUME:   I is a monomial ideal of the basering.
+EXAMPLE:  example isprimaryMon; shows some examples
+"
+{
+  // Variables
+  int nvar,control,m,l,sub_in,i,j,k;
+  intvec v,w,exp_gen;
+  // COMPROBACIONES
+  control = checkIdeal(I);
+  // Si el sistema de generadores no esta formado por monomios, hay
+  // que comprobar si el ideal es monomial.
+  if (control == 0)
+  {
+    list isMon = isMonomialGB (I);
+    if (isMon[1] == 0)
+    {
+      ERROR ("the ideal is not monomial.");
+    }
+    else
+    {
+      I = isMon[2];
+      // Ya lo tenemos con los generadores minimales
+    }
+  }
+  else
+  {
+    // Generadores monomiales, hallamos el sistema minimal
+    I = minbase(I);
+  }
+  // Ya tenemos el ideal generado por la BASE MINIMAL
+  // Usamos la funcion "soporte" que hemos creado, para saber que
+  // variables aparecen en la base de generadores como producto de si
+  // mismas y tambien cuales son los generadores del ideal donde
+  // tenemos que comprobar si aparecen tales variables.
+  nvar = nvars(basering);
+  m = ncols(I);
+  // Inicializo la ultima componente del vector para que contenga a
+  // todas las variables (el subindice de la variable es el lugar
+  // que ocupa como componente de v).
+  v[nvar] = 0;
+  k = 1;
+  // v = 1 en variables solas y 0 en el resto.
+  // w = lugar de los generadores de I que son producto de mas de una variable.
+  for (i = 1 ; i <= m ; i++)
+  {
+    sub_in = soporte(I[i]);
+    // Si soporte <> 0 la variable aparece sola, en caso contrario
+    // el generador es producto de mas de una variable
+    if (sub_in <> 0)
+    {
+      v[sub_in] = 1;
+    }
+    else
+    {
+      w[k] = i;
+      k++;
+    }
+  }
+  // Ahora solo hay que ver que no aparecen variables distintas de
+  // las que tenemos marcadas con 1 en v.
+  l = size(w);
+  // Si w es cero, quiere decir que todos los generadores del ideal
+  // son producto de una sola variable, luego es primario.
+  if (l == 1 && w[1] == 0)
+  {
+    return(1);
+  }
+  // Estudiamos el exponente de los generadores de I oportunos (los
+  // que nos indica w).
+  for (i = 1 ; i <= l ; i++)
+  {
+    exp_gen = leadexp(I[w[i]]);
+    for (j = 1 ; j <= nvar ; j++)
+    {
+      if (v[j] == 0)
+      {
+        if (exp_gen[j] <> 0)
+        {
+          return (0);
+        }
+      }
+    }
+  }
+  // Si hemos recorrido todo el ideal sin que salte el "for"
+  // quiere decir que no se ha contradicho la caracterizacion,
+  // luego el ideal es primario.
+  return(1);
+}
+example
+{"EXAMPLE:"; echo = 2;
+ ring R = 0,(w,x,y,z,t),lp;
+ ideal I = w^4,x^3,z^2,t^5,x*t,w*x^2*z;
+ isprimaryMon (I);
+ ideal J = w^4,x^3,z^2,t^5,x*t,w*x^2*z,y^3*t^3;
+ isprimaryMon (J);
+}
+//////////////////////////////////////////////////////////////////////
+//
+proc isirreducibleMon (ideal I)
+"USAGE:    isirreducibleMon(I); I ideal
+RETURN:   1, if I is irreducible; 0, otherwise.
+          (return -1 if I is not a monomial ideal)
+ASSUME:   I is a monomial ideal of the basering.
+EXAMPLE:  example isirreducibleMon; shows some examples
+"
+{
+  // Variables
+  intvec v;
+  int n,i,j,sum,control;
+  control = checkIdeal(I);
+  // Si el sistema de generadores no esta formado por monomios, hay
+  // que comprobar si el ideal es monomial.
+  if (control == 0)
+  {
+    list isMon = isMonomialGB (I);
+    if (isMon[1] == 0)
+    {
+      ERROR ("the ideal is not monomial.");
+    }
+    else
+    {
+      I = isMon[2];
+      // Ya lo tenemos con los generadores minimales
+    }
+  }
+  else
+  {
+    // Generadores monomiales, hallamos sistema minimal
+    I = minbase(I);
+  }
+  // Ya tenemos el ideal generado por la BASE MINIMAL
+  n = ncols(I);
+  // La funcion soporte devuelve 0 si el monomio es producto de mas
+  // de una variable. Chequeamos generador a generador si el ideal
+  // esta generado por potencias de variables.
+  for (i = 1 ; i <= n ; i ++)
+  {
+    if (soporte(I[i]) == 0)
+    {
+      return(0);
+    }
+  }
+  return (1);
+}
+example
+{"EXAMPLE:"; echo = 2;
+ ring R = 0,(w,x,y,z,t),lp;
+ ideal I = w^4,x^3,z^2,t^5;
+ isirreducibleMon (I);
+ ideal J = w^4*x,x^3,z^2,t^5;
+ isirreducibleMon (J);
+}
+//////////////////////////////////////////////////////////////////////
+//
+proc isartinianMon (ideal I)
+"USAGE:    isartinianMon(I); I ideal.
+RETURN:   1, if ideal is artinian; 0, otherwise.
+          (return -1 if ideal I is not a monmomial ideal).
+ASSUME:   I is a monomial ideal of the basering.
+EXAMPLE:  example isartinianMon; shows some examples
+"
+{
+  int  nvar  = nvars(basering);
+  // Declaracion de variables
+  int i,j,k,cont,sizI;
+  intvec v;
+  // COMPROBACIONES
+  int control = checkIdeal(I);
+  // Si el sistema de generadores no esta formado por monomios, hay
+  // que comprobar si el ideal es monomial.
+  if (control == 0)
+  {
+    list isMon = isMonomialGB (I);
+    if (isMon[1] == 0)
+    {
+      ERROR ("the ideal is not monomial.");
+    }
+    else
+    {
+      I = isMon[2];
+      // Ya lo tenemos con los generadores minimales
+    }
+  }
+  else
+  {
+    // Generadores monomiales, hallamos sistema minimal
+    I = minbase(I);
+  }
+  // Ya tenemos el ideal generado por la BASE MINIMAL
+  sizI = ncols(I);
+  // Comprobamos que entre los generadores minimales aparece una
+  // potencia de cada. Cuando encontramos un generador que es potencia
+  // de una sola variable aumento contador
+  cont = 0;
+  for (i = 1 ; i <= sizI ; i++)
+  {
+    if (soporte(I[i]) <> 0)
+    {
+      cont ++;
+      // Solo volvemos a evaluar en caso de que hayamos aumentado
+      if (cont == nvar)
+      {
+        // Ya hemos encontrado que todas las variables aparrecen en
+        // el sistema minimal como potencia pura. No queremos seguir
+        // buscando
+        return (1);
+      }
+    }
+  }
+  // Si ha salido, es que faltan variables
+  return(0);
+}
+example
+{"EXAMPLE:"; echo = 2;
+ ring R = 0,(w,x,y,z,t),lp;
+ ideal I = w^4,x^3,y^4,z^2,t^6,w^2*x^2*y,w*z*t^4,x^2*y^3,z^2*t^5;
+ isartinianMon (I);
+ ideal J = w^4,x^3,y^4,z^2,w^2*x^2*y,w*z*t^4,x^2*y^3,z^2*t^5;
+ isartinianMon (J);
+}
+//////////////////////////////////////////////////////////////////////
+//
+proc isgenericMon (ideal I)
+"USAGE:    isgenericMon(I); I ideal.
+RETURN:   1, if ideal is generic; 0, otherwise.
+          (return -1 if ideal I is not a monomial ideal)
+ASSUME:   I is a monomial ideal of the basering.
+EXAMPLE:  example isgenericMon; shows some examples.
+"
+{
+  int nvar = nvars(basering);
+  // Declaracion de variables
+  int sizI,i,j,k;
+  list exp;
+ // COMPROBACIONES
+  int control = checkIdeal(I);
+  // Si el sistema de generadores no esta formado por monomios, hay
+  // que comprobar si el ideal es monomial.
+  if (control == 0)
+  {
+    list isMon = isMonomialGB (I);
+    if (isMon[1] == 0)
+    {
+      ERROR ("the ideal is not monomial.");
+    }
+    else
+    {
+      I = isMon[2];
+      // Ya lo tenemos con los generadores minimales
+    }
+  }
+  else
+  {
+    // Generadores monomiales, hallamos sistema minimal
+    I = minbase(I);
+  }
+  // Ya tenemos el ideal generado por la BASE MINIMAL
+  sizI = ncols(I);
+  // Creamos una lista que tenga los exponentes de todos los
+  // generadores.
+  for (i = 1 ; i <= sizI ; i++)
+  {
+    exp[i] = leadexp(I[i]);
+  }
+  // Ahora hay que ver si alguno se repite, y si uno de ellos
+  // lo hace, ya no es gen?rico.
+  for (i = 1 ; i <= nvar ; i++)
+  {
+    for (j = 1 ; j <= sizI-1 ; j++)
+    {
+      for (k = j+1 ; k <= sizI ; k++)
+      {
+        // Notar que no se pueden repetir si la variable realmente
+        // aparece en el generador, es decir, exponente >1.
+        if (exp[j][i] == exp[k][i] & exp[j][i] <> 0)
+        {
+          return (0);
+        }
+      }
+    }
+  }
+  return (1);
+}
+example
+{"EXAMPLE:"; echo = 2;
+ ring R = 0,(w,x,y,z,t),lp;
+ ideal I = w^4,x^3,y^4,z^2,w^2*x^2*y,w*z*t^4,x*y^3,z*t^5;
+ isgenericMon (I);
+ ideal J = w^4,x^3,y^4,z^3,w^2*x^2*y,w*z*t^4,x*y^3,z^2*t^5;
+ isgenericMon (J);
+}
+//////////////////////////////////////////////////////////////////////
+//
+proc dimMon (ideal I)
+"USAGE:   dimMon (I); I ideal
+RETURN:  an integer, the dimension of the affine variety defined by
+         the ideal I.
+         (returns -1 if I is not a monomial ideal)
+ASSUME:  I is a monomial ideal of the basering.
+EXAMPLE: example dimMon; shows some examples.
+"
+{
+ // El ideal trivial no es monomial.
+  if ( size(I) == 0 )
+  {
+    ERROR("the ideal is zero, hence not monomial.");
+  }
+  // VARIABLES
+  int control,sizSum,sumandos,i,j,k,cont;
+ // COMPROBACIONES
+  control = checkIdeal(I);
+  if (control == 0)
+  {
+    list isMon = isMonomialGB (I);
+    if (isMon[1] == 0)
+    {
+      ERROR ("the ideal is not monomial.");
+    }
+    else
+    {
+      // Sabemos que I ya viene dado por el sistema minimal de
+      // generadores, aunque aqui no sea necesario.
+      I = isMon[2];
+    }
+  }
+  attrib(I,"isSB",1);
+  return (dim(I));
+//  int nvar = nvars(basering);
+//  intvec index,indexAux,vaux,w;
+//  list sum, sumAux;
+//  // La base del ideal tiene que ser la monomial
+//  // Si el ideal es artiniano, es 0-dimensional
+//  if (isartinianMon(I) == 1)
+//  {
+//    return (0);
+//  }
+//  int sizI = ncols(I);
+//  // v(i) = vector con sizI entradas y donde cada entrada "j" se corresponde
+//  //        con el exponente del generador "i" en la variable "j"
+//  for (i = 1 ; i <= nvar ; i++)
+//  {
+//    intvec v(i);
+//    for (j = 1 ; j <= sizI ;j++ )
+//    {
+//      v(i)[j] = leadexp(I[j])[i];
+//    }
+//  }
+//  // Vamos a guardar en el vector "index" la ultima variable que se ha
+//  // sumado y en cada "sum(i)" el vector suma que se corresponde con la
+//  // entrada "i" del vector index.
+//  // Inicializo los valores de index y de cada sum
+//  w[sizI] = 0;
+//  sum[1] = w;
+//  index[1] = 0;
+//  sizSum = 1;
+//  while ( 1 )
+//  {
+//    cont = 1;
+//    sumandos ++;
+//    for (i = 1 ; i <= sizSum ; i ++)
+//    {
+//      for (j = index[i] + 1 ; j <= nvar ; j ++)
+//      {
+//        w = sum[i];
+//        vaux = w + v(j);
+//        // Comprobamos
+//        for (k = 1 ; k <= sizI ; k ++)
+//        {
+//          if (vaux[k] == 0)
+//          {
+//            break;
+//          }
+//        }
+//        if (k == sizI +1)
+//        {
+//          return (nvar - sumandos);
+//        }
+//        if (j <> nvar)
+//        {
+//          sumAux[cont] = vaux;
+//          indexAux[cont] = j;
+//          cont ++;
+//        }
+//      }
+//    }
+//    index = indexAux;
+//    sum = sumAux;
+//    sizSum = size(sumAux);
+//  }
+}
+example
+{"EXAMPLE:"; echo = 2;
+ ring R = 0,(w,x,y,z,t),lp;
+ ideal I = w^3*x*y,w*x*y*z*t,x^2*y^2*z^2,x^2*z^4*t^3,y^3*z;
+ dimMon (I);
+ ideal J = w^4,x^3,y^4,z^2,t^6,w^2*x^2*y,w*z*t^4,x^2*y^3,z*t^5;
+ dimMon (J);
+}
+/////////////////////////////////////////////////////////////////////////////
+//-------------------------------------------------------------------------//
+//-----------------------  DESCOMPOSICIONES  -----------------------------_//
+//-------------------------------------------------------------------------//
+/////////////////////////////////////////////////////////////////////////////
+//
+// METODO 1: Metodo directo para descomp. irreducible (ver Vasconcelos)
+//
+//////////////////////////////////////////////////////////////////////
+// Este procedimiento calcula la descomposicion en irreducibles de  //
+// un ideal monomial dado por su base minimal de generadores        //
+// haciendo uso de la caracterizacion de ideal monomial irreducible //
+// (Vasconcelos)                                                    //
+//////////////////////////////////////////////////////////////////////
+//
+static proc irredDec1 (ideal I)
+{
+  // Variables
+  int i,j,n,resp;
+  list l1,l2;
+  intvec exp,v;
+  ideal J,K;
+  // ----- DESCOMPOSICION IRREDUCIBLE
+  // Inicializamos la lista que va a estar formada por los ideales
+  // que tenemos que comprobar son irreducibles.
+  I = simplify(I,1);
+  l1 = I;
+  while (size(l1) > 0)
+  {
+    for (i = 1 ; i <= size(l1) ; i++)
+    {
+      J = l1[i];
+      n = ncols(J);
+      l1 = delete(l1,i);
+      // Llamamos a la funcion que va a detectar si el ideal es o
+      // no irreducible, y en caso de no serlo sabemos sobre que
+      // generador y con que variables hay que aplicar el
+      // el resultado teorico.
+      v = irredAux (J);
+      // No irreducible
+      if (size(v) > 1)
+      {
+        // En este caso, v[1] nos indica el generador del ideal
+        // que debemos eliminar.
+        exp = leadexp(J[v[1]]);
+        if (v[1] == 1)
+        {
+          J = J[2..n];
+        }
+        if (v[1] > 1 && v[1] < n)
+        {
+          J = J[1..v[1]-1],J[v[1]+1..n];
+        }
+        if (v[1] == n)
+        {
+          J = J[1..n-1];
+        }
+        // Ahora vamos a introducir los nuevos generadores en
+        // cada uno de los nuevos ideales que generamos. Los
+        // ponemos en la lista en la que comprobamos.
+        for (j = 1 ; j <= size(v)-1 ; j++)
+        {
+          K = J,var(v[j+1])^exp[v[j+1]];
+          l1 = insert(l1,minbase(K));
+        }
+      }
+      // Si v[1]=0, el ideal es irreducible y lo introducimos en
+      // la lista l2, que es la que finalmente devolvera las
+      // componentes de la descomposicion.
+      else
+      {
+        l2 = insert(l2,J);
+      }
+    }
+  }
+  // ---- IRREDUNDANTE
+  l2 = irredundant (l2);
+  // La salida es la lista de los ideales irreducibles.
+  return (l2);
+}
+//////////////////////////////////////////////////////////////////////
+// La siguiente funcion va a obtener una descomposicion primaria    //
+// minimal a partir de la irreducible anterior.                     //
+//////////////////////////////////////////////////////////////////////
+//
+static proc primDec1 (ideal I)
+{
+  // Variables
+  list l1,l2;
+// ----- DESCOMPOSICION IRREDUCIBLE
+  l1 = irredDec1 (I);
+// ----- DESCOMPOSICION PRIMARIA
+  l2 = irredPrimary (l1);
+  return (l2);
+}
+//
+// METODO 2: Metodo directo para descomp. primaria (ver Vasconcelos)
+//
+//////////////////////////////////////////////////////////////////////
+// La siguiente funcion va a calcular una descomposicion primaria   //
+// minimal de un ideal monomial, pero esta vez usando la            //
+// caracterizacion de ideal monomial primario y un resultado que    //
+//  hace uso de esta (Vasconcelos).                                 //
+//////////////////////////////////////////////////////////////////////
+//
+static proc primDec2 (ideal I)
+{
+  // Variables en el nuevo anillo
+  int i,n,max;
+  list l1,l2;
+  intvec v;
+  ideal J,K;
+  // Vamos a tener dos listas: l1 que va a guardar todos los ideales
+  // que vayamos generando con el resultado citado antes, que seran
+  // los que vamos a comprobar si son primarios; y l2, donde guardamos
+  // aquellos de l1 que verifiquemos son primarios.
+  I = simplify(I,1);
+  l1 = I;
+  while (size(l1) > 0)
+  {
+    for (i = 1 ; i <= size(l1) ; i++)
+    {
+      J = l1[i];
+      n = ncols(J);
+      l1 = delete (l1,i);
+      // Usamos la funcion que hemos creado para saber si el ideal
+      // es primario. Si no lo es devuelve la variable que crea
+      // conflicto y los generadores del ideal que luego hay que
+      // usar (los que tienen productos de mas de una vble).
+      // Se le llama con el sistema minimal de generadores
+      v = primAux (J);
+      // En caso de no ser primario, hay que buscar el maximo
+      // exponente de la variable que aparece en los generadores
+      // del ideal multiplicada siempre por otras variables,
+      // nunca por si misma.
+      if (v[1] == 0)
+      {
+        max = maxExp(J,v);
+        K = J,var(v[2])^max;
+        l1 = insert (l1,minbase(K));
+        K = quotientIdealMon(J,var(v[2])^max);
+        // quotientidealMon devuelve sistema minimal de generadores
+        l1 = insert (l1,minbase(K));
+      }
+      // En caso de ser primario, lo introducimos en la lista
+      // conveniente.
+      else
+      {
+        l2 = insert (l2,J);
+      }
+    }
+  }
+// ------   IRREDUNDANTE
+  l2 = irredundant (l2);
+  return (l2);
+}
+//
+// METODO 3: via dual de Alexander y doble dual (Miller)
+//
+//////////////////////////////////////////////////////////////////////
+// Esta funcion calcula la descomposicion irreducible usando el     //
+// dual de Alexander teniendo en cuenta que el dual del dual es el  //
+// ideal de partida (Miller)                                        //
+//////////////////////////////////////////////////////////////////////
+//
+static proc irredDec3 (ideal I)
+{
+  int i,n,j;
+  poly lcm;
+  intvec v,exp_I,exp;
+  ideal J;
+  list l;
+  // Hallamos el m.c.m. de los generadores minimales del ideal.
+  n = ncols (I);
+  lcm = I[1];
+  for ( i = 2 ; i <= n ; i++ )
+  {
+    lcm = lcmMon (lcm,I[i]);
+  }
+  v = leadexp (lcm);
+  // Calculamos el dual de Alexander.
+  // Hacemos una funcion para este paso porque luego lo volveremos a
+  // utilizar.
+  l = alexDif (v,I);
+  // Tenemos los ideales irreducibles cuya interseccion nos da el dual
+  // de Alexander. Notar que tenemos tantos ideales como generadores
+  // minimales tiene I.
+  // Hallamos la base minimal.
+  J = minbase(intersect(l[1..size(l)]));
+  // Ya solo queda el ultimo paso: hallar de nuevo el dual de
+  // Alexander. Sabemos que este proceso ya devuelve la descomposicion
+  // irreducible irredundante.
+  l = alexDif (v,J);
+  return (l);
+}
+//////////////////////////////////////////////////////////////////////
+// En este caso hallamos una descomposicion primaria minimal usando //
+// la irreducible irredundante del procedimiento anterior.          //
+//////////////////////////////////////////////////////////////////////
+//
+static proc primDec3 (ideal I)
+{
+  // Variables
+  list l1,l2;
+// ----- DESCOMPOSICION IREDUCIBLE
+  l1 = irredDec3 (I);
+// ----- DESCOMPOSICION PRIMARIA
+  l2 = irredPrimary (l1);
+  return (l2);
+}
+//
+// METODO 4: via dual de Alexander y cociente (Miller)
+//
+//////////////////////////////////////////////////////////////////////
+// Vamos a hallar las componentes irreducibles de un ideal monomial //
+// dado por sus generadores minimales haciendo uso del dual de      //
+// Alexander (con el cociente) (Miller)                             //
+//////////////////////////////////////////////////////////////////////
+//
+static proc irredDec4 (ideal I)
+{
+  // Cambiamos de anillo.
+  int nvar = nvars(basering);
+ // Variables
+  int n,i,j,m,resp;
+  poly lcm;
+  intvec v;
+  ideal J,K;
+  list L;
+  // Calculamos el l.c.m. de los generadores minimales del ideal.
+  n = ncols (I);
+  lcm = I[1];
+  for ( i = 2 ; i <= n ; i++ )
+  {
+    lcm = lcmMon (lcm,I[i]);
+  }
+  v = leadexp (lcm);
+  // Hallamos el ideal J = (x(1)^(l(1)+1),...,x(n)^(l(n)+1)). Como
+  // luego, en el procedimiento quotientMon, vamos a hallar la base
+  // minimal de cada ideal, no nos preocupa que tengamos un cero en
+  // el ideal J.
+  for ( i = 1 ; i <= nvar ; i++ )
+  {
+    J[i] = (var(i))^(v[i]+1);
+  }
+  // Ahora hacemos el cociente oportuno.
+  K = minbase(quotient (J,I));
+  // Buscamos aquellos generadores de K que no son divisibles por los
+  // generadores de J. Los generadores que son divisibles los hacemos
+  // cero y luego los eliminamos.
+  m = ncols (K);
+  for ( i = 1 ; i <= m ; i++ )
+  {
+    resp = membershipMon(K[i],J);
+    if ( resp == 1)
+    {
+      K[i] = 0;
+    }
+  }
+  K = simplify (K,2);
+  // Ahora obtenemos las componentes de la descomposicion irreducible,
+  // que estan en correspondencia con los generadores minimales de K.
+  L = alexDif (v,K);
+  // Volvemos al anillo de partida y devolvemos la lista de las
+  // componentes irreducibles irredundantes.
+  return (L);
+}
+//////////////////////////////////////////////////////////////////////
+// Ahora hallamos una descomposicion primaria irredundante usando   //
+// la ultima funcion para hallar las componentes irreducibles de un //
+// ideal monomial dado por sus generadores minimales.               //
+//////////////////////////////////////////////////////////////////////
+//
+static proc primDec4 (ideal I)
+{
+  // Variables
+  list l1,l2;
+// ----- DESCOMPOSICION IREDUCIBLE
+  l1 = irredDec4 (I);
+// ----- DESCOMPOSICION PRIMARIA
+  l2 = irredPrimary (l1);
+  return (l2);
+}
+//
+// METODO 5: un misterio!!
+//
+//////////////////////////////////////////////////////////////////////
+// Este procedimiento halla los elementos maximales de la base      //
+// estandar del ideal, que se correspoenden con las componentes     //
+// irreducibles del ideal 1-1.                                      //
+//////////////////////////////////////////////////////////////////////
+//
+static proc irredDec5 (ideal I)
+{
+  int nvar = nvars(basering);
+  //Variables
+  int i,j;
+  ideal K;
+  // Artinianization
+  list artiniano = artinian (I);
+  if (artiniano[1] == 0)
+  {
+    I = artiniano[2];
+    intvec elimina = artiniano[3];
+  }
+  // Quotient
+  ideal M = maxideal(1);
+  ideal J = quotient (I,M);
+  // Deleting generators lying in I
+  for (i = 1 ; i <= ncols(J) ; i ++)
+  {
+    if (membershipMon(J[i],I) == 1)
+    {
+      if (i == 1)
+      {
+        J = J[2..ncols(J)];
+        i --;
+      }
+      else
+      {
+        if (i == ncols(J))
+        {
+          J = J[1..i-1];
+          i --;
+        }
+        else
+        {
+          J = J[1..i-1],J[i+1..ncols(J)];
+          i --;
+        }
+      }
+    }
+  }
+  // Exponents of the ideals are going to form the decomposition
+  int sizJ = ncols(J);
+  for (i = 1 ; i <= sizJ ; i ++ )
+  {
+    intvec exp(i) = leadexp(J[i]) + 1;
+  }
+  // Deleting artinianization process
+  if (artiniano[1] == 0)
+  {
+    // En elimina estan guardadas las variables que hay que eliminar
+    for (i = 1 ; i <= nvar ; i ++)
+    {
+      if (elimina[i] <> 0)
+      {
+        for (j = 1 ; j <= sizJ ; j ++)
+        {
+          if (exp(j)[i] == elimina[i])
+          {
+            exp(j)[i] = 0;
+          }
+        }
+      }
+    }
+  }
+  // En exp(i) tengo los exponentes de cada variable de las que aparecen
+  // en cada ideal.
+  list facets;
+  for (i = 1 ; i <= sizJ ; i ++)
+  {
+    J = 0;
+    for (j = 1 ; j <= nvar ; j ++)
+    {
+      if (exp(i)[j] <> 0)
+      {
+        J = J,var(j)^exp(i)[j];
+      }
+    }
+    J = simplify(J,2);
+    facets[i] = J;
+  }
+  return (facets);
+}
+//////////////////////////////////////////////////////////////////////
+// Ahora hallamos una descomposicion primaria irredundante usando   //
+// la ultima funcion para hallar las componentes irreducibles de un //
+// ideal monomial dado por sus generadores minimales.               //
+//////////////////////////////////////////////////////////////////////
+//
+static proc primDec5 (ideal I)
+{
+  // Variables
+  list l1,l2;
+// ----- IRREDUCIBLE DECOMPOSITION
+  l1 = irredDec5 (I);
+// ----- PRIMARY DECOMPOSITION
+  l2 = irredPrimary (l1);
+  return (l2);
+}
+//
+// METODO 6: via complejo de Scarf (Milovsky)
+//
+//////////////////////////////////////////////////////////////////////
+// Metodo que usa el complejo de Scarf asociado a un ideal monomial //
+// de k[x(1)..x(n)] (Milowski)                                      //
+//////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////
+// Calcula el maximo exponente de la variable x(i) entre los        //
+// generadores del ideal.                                           //
+//////////////////////////////////////////////////////////////////////
+//
+static proc maximoExp(ideal I,int i)
+{
+  // VARIABLES
+  int max,j,k,sizI;
+  intvec exp;
+  sizI = ncols(I);
+  max = 0;
+  for (j = 1 ; j <= sizI ; j ++)
+  {
+    exp = leadexp(I[j]);
+    if ( exp[i] > max)
+    {
+      max = exp[i];
+    }
+  }
+  return(max);
+}
+//////////////////////////////////////////////////////////////////////
+// Esta funcion estudia si un ideal monomial dado por su sistema    //
+// minimal de generadores es o no artiniano. En caso de no serlo,   //
+// halla el artiniano mas proximo y ademas devuelve los generadores //
+// que han sido introducidos.                                       //
+//////////////////////////////////////////////////////////////////////
+//
+static proc artinian (ideal I)
+{
+  // Cambiamos de anillo
+  int  nvar  = nvars(basering);
+  // Declaracion de variables
+  int i,j,k,cont1,cont2,sizI,marcavar,max;
+  intvec v,variablesin,cambio;
+  list nuevo;
+  ideal J;
+  sizI = ncols(I);
+  // Comprobamos que entre los generadores minimales aparece una
+  // potencia de cada
+  cont2 = 0;
+  for (i = 1 ; i <= sizI ; i++)
+  {
+    v = leadexp(I[i]);
+    marcavar  = 0;
+    cont1 = 0;
+    for (j = 1 ; j <= nvar ; j++)
+    {
+      if (v[j] <> 0)
+      {
+        cont1 ++;
+        marcavar = j;
+      }
+    }
+    // Si cont1=1 hemos encontrado un generador de los que nos
+    // interesa."variablesin" guarda el indice de las que estan.
+    if (cont1 == 1)
+    {
+      cont2 ++;
+      variablesin[cont2] = marcavar;
+    }
+  }
+  // Notar que como el sistema de generadores es minimal no se
+  // va a repetir la potencia de la misma variable. Por tanto basta
+  // comprobar si cont2 es o no nvar.
+  if (cont2 == nvar)
+  {
+    list output;
+    output[1] = 1;
+    return(output);
+  }
+  else
+  {
+    J = I;
+    // Buscamos las que no estan
+    if (cont2 == 0)
+    {
+      for (i = 1 ; i <= nvar ; i ++)
+      {
+        max = maximoExp(I,i);
+        cambio[i] = max + 1;
+        J = J,var(i)^(max + 1);
+      }
+    }
+    else
+    {
+      for (i = 1 ; i <= nvar ; i++)
+      {
+        for (j = 1 ; j <= cont2 ; j ++)
+        {
+          if (i == variablesin[j])
+          {
+            cambio[i] = 0;
+            break;
+          }
+        }
+        if (j == cont2 + 1)
+        {
+          max = maximoExp(I,i);
+          cambio[i] = max + 1;
+          J = J,var(i)^(max + 1);
+        }
+      }
+    }
+    list output;
+    output[1] = 0;
+    output[2] = J;
+    output[3] = cambio;
+    return(output);
+  }
+}
+//////////////////////////////////////////////////////////////////////
+// En este caso vamos primero a chequear si el ideal es o no        //
+// generico y en caso de no serlo vamos a devolver  los cambios,    //
+// pues estos son una aplicacion biyectiva.                         //
+//////////////////////////////////////////////////////////////////////
+//
+static proc generic (ideal I)
+{
+  // New ring
+  int nvar = nvars(basering);
+  // VARIABLES
+  int i,j,k;
+  // Cargamos la matriz con los exponentes
+  int sizI = ncols(I);
+  intmat EXP[sizI][nvar];
+  for (i = 1 ; i <= sizI ; i ++)
+  {
+    // Ordenamos el vector de exponentes oportuno
+    EXP[i,1..nvar] = leadexp(I[i]);
+  }
+
+  // Ahora tenemos que ordenarla segun la variable que este en conficto.
+  intvec vari,change;
+  intmat NEWEXP = EXP;
+  list aux;
+  int count = 0;
+  for (i = 1 ; i <= nvar ; i ++)
+  {
+    // Buscamos conflicto en la variable x(i), para ello tengo que ordenar
+    // la columna i de EXP
+    vari = EXP[1..sizI,i];
+    aux = sort(vari);
+    vari = aux[1];
+    change = aux[2];
+    for (j = 1 ; j <= sizI - 1 ; j ++)
+    {
+      if (vari[j] > 0)
+      {
+        while (NEWEXP[change[j + count] , i] >= vari[j + 1 + count])
+        {
+          NEWEXP[change[j + 1 + count] , i] = NEWEXP[change[j + count] , i] + 1;
+          count ++;
+          if (j + 1 + count > sizI)
+          {
+            break;
+          }
+        }
+      }
+      j = j + count;
+      count = 0;
+    }
+  }
+  // Devolvemos tambien la matriz, pues aqui tengo la biyeccion entre los exponentes
+  if (EXP == NEWEXP)
+  {
+    return (1,I);
+  }
+  else
+  {
+    // Hallamos el ideal con los nuevos exponentes
+    intvec expI;
+    for (i = 1 ; i <= sizI ; i ++)
+    {
+      expI = NEWEXP[i,1..nvar];
+      I[i] = monomial(expI);
+    }
+    return(0,I,EXP,NEWEXP);
+  }
+}
+//////////////////////////////////////////////////////////////////////
+// Esta funci?n obtiene una descomposicion irreducible del ideal    //
+// monomial a partir de la descomposicion irreducible del idal      //
+// generico que le asociamos.                                       //
+//////////////////////////////////////////////////////////////////////
+//
+static proc nonGeneric (def EXP,def NEWEXP,def Faces,def sizI)
+{
+  int nvar = nvars(basering);
+  int sizFaces = size(Faces);
+  // Variables
+  int i,j,k;
+  // Vamos variable a variable
+  intvec exp, newexp;
+  list newFaces;
+  newFaces = Faces;
+  for (i = 1 ; i <= nvar ; i ++)
+  {
+    // comparamos las matrices de exponentes por columnas
+    exp = EXP[1..sizI,i];
+    newexp = NEWEXP[1..sizI,i];
+    if (exp <> newexp)
+    {
+      for (j = 1 ; j <= sizI ; j ++)
+      {
+        if (exp[j] <> newexp[j])
+        {
+          for (k = 1 ; k <= sizFaces ; k ++)
+          {
+            if (Faces[k][i] == newexp[j])
+            {
+              newFaces[k][i] = exp[j];
+            }
+          }
+        }
+      }
+    }
+  }
+  return (newFaces);
+}
+//////////////////////////////////////////////////////////////////////
+// Este procedimiento va a dar una faceta inicial para el complejo  //
+// de Scarf asociado a I, donde I es un ideal monomial artiniano    //
+// y generico (evidentemente I dado por la bse minimal)             //
+//////////////////////////////////////////////////////////////////////
+//
+static proc initialFacet (ideal I)
+{
+  // Cambiamos de anillo
+  // Queremos usar x(1)..x(n) como variables.
+  int nvar = nvars(basering);
+  // Declaracion de variables.
+  int i,sizJ,j,max,aux,sizK,l, elim;
+  intvec v;
+  list face;
+  // Hacemos una copia de I pues ahora modificaremos el sistema
+  // de generadores.
+  ideal J = I;
+  sizJ = ncols(J);
+  // Para cada variable buscamos el maximo exponente, teniendo en
+  // cuenta que un mismo generador no puede dar dos exponentes.
+  // Vamos a guardar los exponentes en "expIni"
+  intvec expIni;
+  for (i = 1 ; i <= nvar ; i++)
+  {
+    max = 0;
+    for (j = 1 ; j <= sizJ ; j++)
+    {
+      aux = leadexp(J[j])[i];
+      if (aux > max)
+      {
+        max = aux;
+        elim = j;
+      }
+    }
+    // Guardamos el exponente
+    expIni[i] = max;
+    // Ahora tenemos el maximo de la variable x(i), por lo que
+    // eliminamos el generador en el que la encontramos.
+    // Si queda un generador no hay nada que hacer
+    if (sizJ <> 1)
+    {
+      if (elim <> 1 & elim <> sizJ)
+      {
+        J = J[1..elim-1],J[elim+1..sizJ];
+      }
+      else
+      {
+        if (elim == 1)
+        {
+          J = J[2..sizJ];
+        }
+        else
+        {
+          J = J[1..sizJ-1];
+        }
+      }
+      sizJ = ncols(J);
+      // Eliminamos la variable x(i) en todos los generadores.
+      for (j = 1 ; j <= sizJ ; j++)
+      {
+        v = leadexp(J[j]);
+        if (v [i] <> 0)
+        {
+          v[i] = 0;
+          J[j] = monomial(v);
+        }
+      }
+      // Hallamos el sistema minimal de generadores que
+      // corresponde al ideal que nos ha quedado.
+      J = minbase(J);
+      sizJ = ncols(J);
+    }
+  }
+  // En expIni tenemos los exponentes de los monomios que dan la cara
+  // inicial, ahora hay que buscar en el ideal original a que
+  // generador se corresponde (el ideal es generico)
+  int sizI = ncols(I);
+  for (i = 1 ; i <= nvar ; i ++)
+  {
+    for (j = 1 ; j <= sizI ; j ++)
+    {
+      if (expIni[i] == leadexp(I[j])[i])
+      {
+        face = insert(face, I[j]);
+        // Si lo encontramos buscamos el siguiente
+        break;
+      }
+    }
+  }
+  return (face);
+}
+//////////////////////////////////////////////////////////////////////
+// La funcion que sigue devuelve las facetas adyacentes a una dada  //
+// en el complejo de Scarf asociado a I.                            //
+//////////////////////////////////////////////////////////////////////
+//
+static proc adyacency (list l1, ideal I)
+{
+  // Cambiamos de anillo
+  // Queremos usar x(1)..x(n) como variables.
+  int nvar = nvars(basering);
+  // Declaracion de variables.
+  int i,j,cambio,sizI,k,min,m,generador,max;
+  list l2,newl1,w,expI;
+  poly LCM,newLCM;
+  intvec v,newv,expgen;
+  sizI = ncols(I);
+  // Hallamos el lcm de los elementos, e. d., la faceta del
+  // complejo para luego comparar con los nuevos
+  LCM = 1;
+  for (i = 1 ; i <= nvar ; i++)
+  {
+    LCM = lcmMon(LCM,l1[i]);
+  }
+  v = leadexp(LCM);
+  // Calculo los exponentes de los monomios de I
+  for (i = 1 ; i <= sizI ; i++)
+  {
+    expI[i] = leadexp(I[i]);
+  }
+  // Hay que quitar cada elemento de la lista y comprobar si hay o no
+  // cara adyacente al simplice que queda, y en caso de haberla, la
+  // calculamos.
+  for (i = 1 ; i <= nvar ; i++)
+  {
+    newl1 = delete(l1,i);
+    // Hallamos el lcm de los elementos que hay en la nueva lista.
+    newLCM = 1;
+    for (j = 1 ; j <= nvar - 1 ; j++)
+    {
+      newLCM = lcmMon(newLCM,newl1[j]);
+    }
+    // Ahora hay que detectar si alguna variable ha desaparecido
+    // en este LCM.
+    newv = leadexp(newLCM);
+    for (j = 1 ; j <= nvar ; j++)
+    {
+      if (newv[j] == 0)
+      {
+        l2[i] = 0;
+        break;
+      }
+    }
+    if (j == nvar+1)
+    {
+      // Si no ha habido ceros, queremos hallar la cara adyacente,
+      // es decir, buscar un generador que introducido en l1 de una
+      // faceta del complejo.
+      // Comparamos los lcm entre s?, para comprobar en que variable
+      // contribu?a el monomio que hemos eliminado.
+      for (j = 1 ; j <= nvar ; j++)
+      {
+        if (v[j] <> newv[j])
+        {
+          cambio = j;
+          // Una vez encontrado no hay mas
+          break;
+        }
+      }
+      // Hallamos los exponentes de los monomios que quedan
+      // para ver cual da el exponente en "newv"
+      for (j = 1 ; j <= nvar - 1 ; j++)
+      {
+        w[j] = leadexp(newl1[j]);
+      }
+      for (j = 1 ; j <= nvar ; j++)
+      {
+        for (k = 1 ; k <= nvar - 1 ; k++)
+        {
+          if (newv[cambio] == w[k][cambio])
+          {
+            cambio = k;
+            break;
+          }
+        }
+        // Si no termino el for con k es que hemos encontrado ya
+        // los que son iguales.
+        if (k <> nvar)
+        {
+          break;
+        }
+      }
+
+      // Donde contribuye antes, e.d., en "v"
+      for (j = 1 ; j <= nvar ; j++)
+      {
+        if (w[cambio][j] == v[j])
+        {
+          cambio = j;
+          break;
+        }
+      }
+      // Ahora ya buscamos entre los generadores el nuevo monomio.
+      // Ponemos de tope para encontrar el minimo el maximo de
+      // las variables en el ideal
+      max = 0;
+      for (m = 1 ; m <= sizI ; m ++)
+      {
+        if (expI[m][cambio] > max)
+        {
+          max = expI[m][cambio];
+        }
+      }
+      min = max;
+      for (j = 1 ; j <= sizI ; j++)
+      {
+        for (k = 1 ; k <= nvar ; k ++)
+        {
+          if (I[j] == l1[k])
+          {
+            break;
+          }
+        }
+        // El generador no esta en la lista, es de los que hay que
+        // comprobar
+        if (k == nvar +1)
+        {
+          for (m = 1 ; m <= nvar ; m++)
+          {
+            if (m <> cambio)
+            {
+              if (expI[j][m] > newv[m])
+              {
+                break;
+              }
+            }
+            else
+            {
+              if (expI[j][m] <= newv[m])
+              {
+                break;
+              }
+            }
+          }
+          // Si termina el bucle cumple las condiciones
+          // oportunas, solo hay que comparar con el
+          // otro que tengamos.
+          if (m == nvar + 1)
+          {
+            if (expI[j][cambio] <=  min)
+            {
+              min = expI[j][cambio];
+              generador = j;
+            }
+          }
+        }
+      }
+      // En la lista ponemos en el lugar "i" el generador que
+      // hay que introducir cuando eliminamos el generador
+      // "i" de la lista de entrada.
+      l2[i] = I[generador];
+    }
+  }
+  return(l2);
+}
+//////////////////////////////////////////////////////////////////////
+// Metodo que calcula la descomposicion irreducible de un ideal     //
+// monomial usando el complejo de Scarf (Milowski)                  //
+//////////////////////////////////////////////////////////////////////
+//
+static proc ScarfMethod (ideal I)
+{
+  // Cambiamos de anillo
+  // Queremos usar x(1)..x(n) como variables.
+  int nvar = nvars(basering);
+  // Sabemos que dp siempre es mejor para trabajar, auqque luego para
+  // comparar I y genI vamos a cambiarlo al lexicografico.
+  // Variables
+  int i,j,k,sizl1,sizl,cont1,cont2;
+  int sizI;
+  list auxl,expl1,l1,l,l2,newLCM,expI,expgenI,Faces;
+  poly LCM,mon;
+  intvec v,w,betas;
+  ideal J,genI,artgenI;
+  // Comprobamos si el ideal es generico y artiniano, y, en caso de
+  // no serlo, obtenemos una modificacion de este ideal que si
+  // verifique estas propiedades
+  list genericlist = generic(I);
+  if (genericlist[1] == 0)
+  {
+    genI = genericlist[2];
+  }
+  else
+  {
+    genI = I;
+  }
+  list artinianization = artinian (genI);
+  if (artinianization[1] == 0)
+  {
+    artgenI = artinianization[2];
+  }
+  else
+  {
+    artgenI = genI;
+  }
+  // Una vez tenemos el ideal artiniano y generico, podemos hallar
+  // el complejo de Scarf asociado al ideal modificado
+
+  // Hay que obtener una cara inicial del ideal.
+  list initial = initialFacet(artgenI);
+  // Ahora de cada cara que tengamos en una lista obtenemos sus
+  // caras adyacentes. Hay que tener en cuenta que si una cara la
+  // obtengo como adyacente de otra, cuando calculemos sus adyacentes
+  // sale la anterior, luego hay que evitar repetir.
+  // Guardamos la primera faceta, su LCM
+  LCM = 1;
+  for (i = 1 ; i <= nvar ; i++)
+  {
+    mon = initial[i];
+    LCM = lcmMon(LCM,mon);
+  }
+  v = leadexp(LCM);
+  // Guardamos la primera faceta
+  Faces[1] = v;
+  int sizfaces = 1;
+  // Lista de monomios que dan las facetas para hallar sus caras
+  // adyacentes
+  l[1] = initial;
+  sizl = 1;
+  // Ahora hayamos las posibles caras maximales adyacentes
+  while (sizl <> 0)
+  {
+    // Hallamos la lista de monomios que hay que introducir
+    // cuando eliminamos cada monomio.
+    auxl = adyacency(l[1],artgenI);
+    cont1 = 1;
+    cont2 = 0;
+    l1 = 0;
+    for (j = 1 ; j <= nvar ; j++)
+    {
+      if (auxl[j] <> 0)
+      {
+        l2 = delete(l[1],j);
+        l1[cont1] = insert(l2,auxl[j],cont1 + cont2 - 1);
+        cont1 ++;
+      }
+      else
+      {
+        cont2 ++;
+      }
+    }
+    // Hallamos los nuevos LCM
+    sizl1 = size(l1);
+    for (i = 1 ; i <= sizl1 ; i++)
+    {
+      newLCM[i] = 1;
+      for (j = 1 ; j <= nvar ; j++)
+      {
+        newLCM[i] = lcmMon(newLCM[i],l1[i][j]);
+      }
+      expl1[i] = leadexp(newLCM[i]);
+    }
+    // Hallamos los LCM de las nuevas caras y eliminamos las que
+    // ya esten en la lista Faces
+    cont1 = 0;
+    cont2 = 0;
+    for (i = 1 ; i <= sizl1 ; i++)
+    {
+      for (j = 1 ; j <= sizfaces ; j++)
+      {
+        v = expl1[i];
+        w = Faces[j];
+        if (v == w)
+        {
+          // Si ya esta el LCM en la lista, no queremos
+          // seguir buscando
+          break;
+        }
+      }
+      // Si no ha salido del bucle en "j" es que este LCM
+      // no esta en la lista de las caras, la introducimos
+      if (j == sizfaces + 1)
+      {
+        Faces = insert(Faces,expl1[i],sizfaces + cont1);
+        l = insert(l,l1[i]);
+        cont1 ++;
+      }
+    }
+    l = delete(l,cont1 + 1);
+    sizl = size(l);
+    sizfaces = size(Faces);
+  }
+  // En "Faces" ya tengo los exponentes que luego seran los exponentes
+  // de los ideales que forman la descomposicion.
+  // Deshacemos la artinianizacion
+  intvec elimin = artinianization[3];
+  if (artinianization[1] == 0)
+  {
+    // En elimina tenemos las variables que hemos introducido
+    // y cual es la potencia
+    // Solo miro las que tengan cambio
+    for (i = 1 ; i <= nvar ; i ++)
+    {
+      if (elimin[i] <> 0)
+      {
+        for (j = 1 ; j <= sizfaces ; j ++)
+        {
+          if (Faces[j][i] == elimin[i])
+          {
+            Faces[j][i] = 0;
+          }
+        }
+      }
+    }
+  }
+  // Generico
+  sizI = size(I);
+  if (genericlist[1] == 0)
+  {
+    Faces = nonGeneric(genericlist[3],genericlist[4],Faces,sizI);
+  }
+  // Ya tenemos en Faces los exponentes de las componentes
+  // ahora solo hay que obtener los ideales.
+  for (i = 1 ; i <= sizfaces ; i ++)
+  {
+    J = 0;
+    for (j = 1 ; j <= nvar ; j ++)
+    {
+      if (Faces[i][j] <> 0)
+      {
+        J = J,var(j)^(Faces[i][j]);
+      }
+    }
+    J = simplify(J,2);
+    Faces[i] = J;
+  }
+  // Esta es la parte LENTA computacionalmente si el ideal de partida
+  // no es generico
+  if (genericlist[1] == 0)
+  {
+    Faces = irredundant(Faces);
+  }
+  return(Faces);
+}
+//////////////////////////////////////////////////////////////////////
+// Devuelve una descomposicion primaria minimal de un ideal         //
+// monomial via el complejo de Scarf.                               //
+//////////////////////////////////////////////////////////////////////
+//
+static proc scarfMethodPrim (ideal I)
+{
+ // VARIABLES
+  list l1,l2;
+  // Hallamos la despomposicion irreducible del ideal dado usando
+  // el complejo de Scarf
+  l1 = ScarfMethod (I);
+// ----- DESCOMPOSICION PRIMARIA
+  l2 = irredPrimary (l1);
+  return (l2);
+}
+//
+// METODO 7: algoritmo de etiquetas (Roune)
+//
+//////////////////////////////////////////////////////////////////////
+// Las siguientes funciones calculan la descomposicion en           //
+// irreducibles de un ideal monomial. En este caso utilizamos el    //
+// algoritmo de etiquetas de B. Roune.                              //
+//////////////////////////////////////////////////////////////////////
+//
+static proc phi (list F)
+{
+  // Cambiamos de anillo
+  int nvar = nvars(basering);
+  // Variables
+  int sizF,i,j;
+  poly f;
+  list listphi;
+  intvec exp,newexp;
+  // F es una lista de pares, que indica una x(i) etiqueta de una
+  // cara del ideal. Suponemos que F tiene ordenados sus elementos
+  // segun las x(i)
+  sizF = size(F);
+  for (i = 1 ; i <= sizF ; i ++)
+  {
+    f = F[i];
+    exp = leadexp(f);
+    for (j = 1 ; j <= nvar ; j ++)
+    {
+      if (j <> i)
+      {
+        exp[j] = exp[j] + 1;
+      }
+    }
+    listphi[i] = monomial(exp);
+  }
+  // Ya tenemos la lista de los monomios a los que
+  // luego haremos el "lcm"
+  return (listphi);
+}
+//////////////////////////////////////////////////////////////////////
+//
+static proc pi(poly f)
+{
+ // Cambiamos de anillo
+  int nvar = nvars(basering);
+  int i,sizI;
+  intvec exp;
+  exp = leadexp(f);
+  for (i = nvar ; i > 0  ; i --)
+  {
+    if (exp[i] <> 0)
+    {
+      exp[i] = exp[i] - 1;
+    }
+  }
+  f = monomial(exp);
+  return (f);
+}
+//////////////////////////////////////////////////////////////////////
+//
+static proc conditionComplex (intvec posActual,ideal I,ideal S)
+{
+  int nvar = nvars(basering);
+  // VARIABLES
+  int i,nuevo;
+  list F;
+  // Vemos cual ha sido la ultima incorporacion al ideal, que es el
+  // ultimo dentro de posActual que es distinto de 0.
+  for (i = 1 ; i <= nvar ; i ++)
+  {
+    if (posActual[i] == 0)
+    {
+      break;
+    }
+  }
+  nuevo = i - 1;
+  // No se pueden repetir generadores, se mira que el ultimo que se ha
+  // ha introducido no sea de los que ya tenemos
+  for (i = 1 ; i <= nuevo - 1 ; i ++)
+  {
+    if (posActual[i] == posActual[nuevo])
+    {
+      return (0);
+    }
+  }
+  // Vemos si la variable oportuna divide al generador
+  if (leadexp(I[i]) == 0)
+  {
+    return (0);
+  }
+  // Caso de que el LCM sea multiplo de los que ya tenemos
+  poly LCM = 1;
+  for (i = 1 ; i <= nuevo ; i ++)
+  {
+    F = insert (F,I[posActual[i]],size(F));
+  }
+  list phiF = phi(F);
+  for (i = 1 ; i <= nuevo ; i ++)
+  {
+    LCM = lcmMon(phiF[i],LCM);
+  }
+  // Comprobamos si ya tenemos algun divisor del actual
+  if (membershipMon(LCM,S) == 1)
+  {
+    return (0);
+  }
+  // Ahora vemos si la lista esta en el complejo simplicial
+  if (membershipMon(LCM,I) == 1)
+  {
+    if (membershipMon(pi(LCM),I) == 0)
+    {
+      return (1,LCM);
+    }
+  }
+  return (0);
+}
+//////////////////////////////////////////////////////////////////////
+//
+static proc findFaces (ideal I)
+{
+  int nvar = nvars(basering);
+  // Variables
+  int i;
+  ideal S;
+  list condiciones;
+  // Inicializamos valores
+  list F;
+  intvec posActual;
+  posActual[nvar] = 0;
+
+  int variable = 1;
+  int sizI = ncols(I);
+  while (1)
+  {
+    while (posActual[variable] == sizI)
+    {
+      posActual[variable] = 0;
+      variable --;
+      if (variable == 0)
+      {
+        break;
+      }
+    }
+    // Comprobamos si hemos recorrido todas las posibilidades. Si
+    // es as?, terminamos el while
+    if (variable == 0)
+    {
+      break;
+    }
+    posActual[variable] = posActual[variable] + 1;
+    // Comprobamos las condiciones para saber si los generadores que
+    // tenemos est?n o no en el complejo.
+    condiciones = conditionComplex (posActual,I,S);
+
+    if (condiciones[1] == 1 )
+    {
+      if (posActual[nvar] <> 0)
+      {
+        S = S,condiciones[2];
+        F = insert (F,condiciones[2]);
+      }
+      if (variable < nvar)
+      {
+        variable ++;
+      }
+    }
+  }
+  return (F);
+}
+//////////////////////////////////////////////////////////////////////
+// La siguiente funcion calcula la descomposicion en irreducibles de//
+// un ideal monomial artininano usando el algoritmo de etiquetas del//
+// metodo de Bjarke Roune.                                          //
+//////////////////////////////////////////////////////////////////////
+//
+static proc labelAlgorithm(ideal I)
+{
+  int nvar = nvars(basering);
+
+  // Variables
+  int i,j,sizComponents;
+  list components;
+  // El ideal tiene que ser artininano, si no lo es hacemos el cambio
+  // oportuno para que lo sea (luego se deshace).
+  ideal artI;
+  list artiniano = artinian (I);
+  if (artiniano[1] == 0)
+  {
+    artI = artiniano[2];
+    intvec elimina = artiniano[3];
+  }
+  else
+  {
+    artI = I;
+  }
+  // Llamamos a findFaces para que encuentre las caras maximales del
+  // complejo asociado al ideal
+  components = findFaces(artI);
+  sizComponents = size(components);
+  list expComponents;
+  poly f;
+  for (i = 1 ; i <= sizComponents ; i ++)
+  {
+    f = components[i];
+    expComponents[i] = leadexp(f);
+  }
+  // Deshacemos la artinianizacion
+  if (artiniano[1] == 0)
+  {
+    // En elimina tenemos las variables que hemos introducido
+    // y cual es la potencia
+    // Solo miro las que tengan cambio
+    for (i = 1 ; i <= nvar ; i ++)
+    {
+      if (elimina[i] <> 0)
+      {
+        for (j = 1 ; j <= sizComponents ; j ++)
+        {
+          if (expComponents[j][i] == elimina[i])
+          {
+            expComponents[j][i] = 0;
+          }
+        }
+      }
+    }
+  }
+  // En exp(i) tengo los exponentes de cada variable de las que aparecen
+  // en cada ideal.
+  ideal J;
+  list facets;
+  for (i = 1 ; i <= sizComponents ; i ++)
+  {
+    J = 0;
+    for (j = 1 ; j <= nvar ; j ++)
+    {
+      if (expComponents[i][j] <> 0)
+      {
+        J = J,var(j)^expComponents[i][j];
+      }
+    }
+    J = simplify(J,2);
+    facets[i] = J;
+  }
+  return (facets);
+}
+//////////////////////////////////////////////////////////////////////
+// Devuelve una descomposicion primaria minimal de un ideal monomial//
+// dado.                                                            //
+//////////////////////////////////////////////////////////////////////
+//
+static proc  labelAlgPrim (ideal I)
+{
+  // VARIABLES
+  list l1,l2;
+  // Hallamos la despomposicion irreducible del ideal dado usando
+  // el complejo de Scarf
+  l1 = labelAlgorithm (I);
+// ----- DESCOMPOSICION PRIMARIA
+  l2 = irredPrimary (l1);
+  return (l2);
+}
+//
+// METODO 8: Gao-Zhu
+//
+//////////////////////////////////////////////////////////////////////
+//
+static proc divide (intvec v, intvec w, int k)
+{
+  int nvar = nvars(basering);
+  // Variables
+  int i;
+  for (i = nvar ; i > 0 ; i --)
+  {
+    if (i == k)
+    {
+      if (v[i] <> w[i])
+      {
+        return (0);
+      }
+    }
+    else
+    {
+      if (v[i] >= w[i])
+      {
+        return (0);
+      }
+    }
+  }
+  return (1);
+}
+//////////////////////////////////////////////////////////////////////
+//                                        //
+//////////////////////////////////////////////////////////////////////
+//
+static proc incrementalAlg (ideal I)
+{
+  int nvar = nvars(basering);
+  // COMPROBACIONES
+  // Variables
+  int i,sop,j,k,l,m,cont,cont2;
+  intvec beta,dbeta,betaaux,elimina;
+  // El ideal tiene que ser artininano, si no lo es hacemos el cambio
+  // oportuno para que lo sea (luego se deshace).
+  list artiniano = artinian (I);
+  ideal artI;
+  if (artiniano[1] == 0)
+  {
+    artI = artiniano[2];
+    elimina = artiniano[3];
+  }
+  else
+  {
+    artI = I;
+    elimina[nvar] = 0;
+  }
+  // Buscamos la primera componente irreducible o, lo que es lo
+  // mismo, aquellos generadores que son potencia de una variable.
+  // Si el tama?o de elimina es nvar es que hemos a?adido todos los
+  // generadores que son potencia luego estar?n todos al final del
+  // ideal.
+  list MinI,componentes;
+  int sizartI = ncols(artI);
+  int sizelimina = size(elimina);
+  for (i = 1 ; i <= nvar ; i ++)
+  {
+    if (elimina[i] == 0)
+    {
+      // Buscamos en el ideal los generadores que nos interesan
+      for (j = 1 ; j <= sizartI ; j ++)
+      {
+        sop = soporte(artI[j]);
+        if (sop <> 0)
+        {
+          beta[sop] = leadexp(artI[j])[sop];
+          MinI = insert(MinI,leadexp(artI[j]));
+          if (j <> 1 and j <> sizartI)
+          {
+            artI = artI[1..j - 1],artI[j + 1..sizartI];
+          }
+          else
+          {
+            if (j == 1)
+            {
+              artI = artI[2..sizartI];
+            }
+            else
+            {
+              artI = artI[1..sizartI - 1];
+            }
+          }
+          sizartI = ncols(artI);
+          break;
+        }
+      }
+    }
+    else
+    {
+      // Buscamos la que esta al final
+      sop = soporte(artI[sizartI]);
+      beta[sop] = leadexp(artI[sizartI])[sop];
+      MinI = insert(MinI,leadexp(artI[sizartI]));
+      if (sizartI <> 1)
+      {
+        artI = artI[1..sizartI - 1];
+      }
+      else
+      {
+        artI = artI[1];
+      }
+      sizartI = ncols(artI);
+    }
+  }
+  // En beta tenemos la primera componente
+  componentes = insert(componentes,beta);
+  int sizcomponents = size(componentes);
+  int sizMin = size(MinI);
+  // Es mas facil trabajar con los exponentes para nuestro objetivo
+  // Se elige un nuevo generador, que en nuestro caso es un nuevo
+  // exponente.
+  int min,max;
+  intvec expartI;
+  for(i = 1 ; i <= sizartI ; i ++)
+  {
+    expartI = leadexp(artI[1]);
+    if (size(artI) <> 1)
+    {
+      artI = artI[2..size(artI)];
+    }
+    // Hay que distinguir T_1 y T_2. Para ello se comparar vectores
+    // de la lista actual de generadores con el que se acaba de
+    // introducir.
+    cont2 = 0;
+    for (j = 1 ; j <= sizcomponents ; j ++)
+    {
+      beta = componentes[1 + cont2];
+      // Si el nuevo generador divide a la componente beta, hay
+      // que buscar las nuevas componentes
+      for (k = 1 ; k <= nvar ; k ++)
+      {
+        if (expartI[k] >= beta[k])
+        {
+          break;
+        }
+      }
+      // Si el bucle anterior termino, divide y hay que hacer
+      // los cambios.
+      if (k == nvar + 1)
+      {
+        componentes = delete (componentes,1 + cont2);
+        // Buscamos las nuevas componentes calculando las
+        // distancias. Para cada variable busco d(beta,k,l)
+        for (k = 1 ; k <= nvar ; k ++)
+        {
+          betaaux = beta;
+          max = -1;
+          cont = 0;
+          dbeta = 0;
+          for (l = 1 ; l <= nvar ; l ++)
+          {
+            if (l <> k)
+            {
+              min = 32767;
+              cont ++;
+              for (m = 1 ; m <= sizMin ; m ++)
+              {
+                // Estos son de los buenos
+                if (divide(MinI[m],beta,l) == 1)
+                {
+                  if (MinI[m][k] < min)
+                  {
+                    min = MinI[m][k];
+                  }
+                }
+              }
+              dbeta[cont] = min;
+            }
+          }
+          // Aqui ya tenemos d(beta,k,l) para cada k
+          // Hallamos el maximo cuando terminemos
+          for (l = 1 ; l <= cont ; l ++)
+          {
+            if (dbeta[l] > max)
+            {
+              max = dbeta[l];
+            }
+          }
+          // Condicion para introducir nueva componente
+          if (max < expartI[k])
+          {
+            betaaux[k] = expartI[k];
+            componentes = insert(componentes,betaaux,size(componentes));
+          }
+        }
+      }
+      else
+      {
+        cont2 ++;
+      }
+    }
+    MinI = insert(MinI,expartI);
+    sizMin = size(MinI);
+    sizcomponents = size(componentes);
+  }
+  // Deahacer los cambios de artiniano si se han hecho
+  if (artiniano[1] == 0)
+  {
+    // En elimina tenemos las variables que hemos introducido
+    // y cual es la potencia
+    // Solo miro las que tengan cambio
+    for (i = 1 ; i <= nvar ; i ++)
+    {
+      if (elimina[i] <> 0)
+      {
+        for (j = 1 ; j <= sizcomponents ; j ++)
+        {
+          if (componentes[j][i] == elimina[i])
+          {
+            componentes[j][i] = 0;
+          }
+        }
+      }
+    }
+  }
+  // En exp(i) tengo los exponentes de cada variable de las que aparecen
+  // en cada ideal.
+  ideal J;
+  list facets;
+  for (i = 1 ; i <= sizcomponents ; i ++)
+  {
+    J = 0;
+    for (j = 1 ; j <= nvar ; j ++)
+    {
+      if (componentes[i][j] <> 0)
+      {
+        J = J,var(j)^componentes[i][j];
+      }
+    }
+    J = simplify(J,2);
+    facets[i] = J;
+  }
+  return (facets);
+}
+//////////////////////////////////////////////////////////////////////
+//
+static proc  incrementalAlgPrim (ideal I)
+{
+  // VARIABLES
+  list l1,l2;
+  // Hallamos la despomposicion irreducible del ideal dado usando
+  // el algoritmo de Gao-Zhu
+  l1 = incrementalAlg (I);
+// ----- DESCOMPOSICION PRIMARIA
+  l2 = irredPrimary (l1);
+  return (l2);
+}
+//
+// METODO 9: slice algorithm (Roune)
+//
+//////////////////////////////////////////////////////////////////////
+// SLICE ALGORITHM (B.Roune)                                        //
+//////////////////////////////////////////////////////////////////////
+//
+static proc divideMon (poly f , poly g)
+{
+  return (lead(g)/lead(f)!=0);
+  //int nvar = nvars(basering);
+  //intvec expf = leadexp(f);
+  //intvec expg = leadexp(g);
+  //for (int i = 1 ; i <= nvar ; i ++)
+  //{
+  //  if (expf[i] > expg[i])
+  //  {
+  //    return (0);
+  //  }
+  //}
+  //return (1);
+}
+//////////////////////////////////////////////////////////////////////
+//
+static proc pivot (ideal I , poly lcmMin, ideal S)
+{
+  // I is monomial ideal
+  int sizI = ncols(I);
+  int nvar = nvars(basering);
+  intvec explcmMin = leadexp(lcmMin);
+  // Variables
+  int i,j;
+  // The median estrategy
+  poly p;
+  int cont, exp, median, sizxi, max;
+  intvec xiexp;
+  for (i = 1 ; i <= nvar ; i ++)
+  {
+    if (explcmMin[i] >= 2 )
+    {
+      // Median exponent of x(i) from intersection(minI,x(i))
+      cont = 0;
+      for (j = 1 ; j <= sizI ; j ++)
+      {
+        exp = leadexp(I[j])[i];
+        if (exp > 0)
+        {
+          cont ++;
+          xiexp[cont] = exp;
+        }
+      }
+      xiexp = sort(xiexp)[1];
+      sizxi = size(xiexp);
+      if (size(xiexp) == 1)
+      {
+        median = xiexp[1] - 1;
+      }
+      else
+      {
+        if (size(xiexp) == 2)
+        {
+          median = xiexp[2] - 1;
+        }
+        else
+        {
+          median = xiexp[(size(xiexp) + 1) div 2];
+        }
+      }
+      p = var(i)^median;
+      // valid pivot??
+      if ( membershipMon(p,S) == 0)
+      {
+        return(p);
+      }
+      else
+      {
+        max = maximoExp(S,i);
+        if ( xiexp[sizxi] == max )
+        {
+          return(var(i)^(max-1));
+        }
+      }
+      xiexp = 0;
+    }
+  }
+}
+//////////////////////////////////////////////////////////////////////
+//
+static proc simplification (def I)
+{
+  // VARIABLES
+  int i, j, k, cont, numdeleted;
+  intvec isMaximal;
+  int sizI = ncols(I);
+  int nvar = nvars(basering);
+  poly lcmMinI = 1;
+  for (i = 1 ; i <= sizI ; i ++)
+  {
+    lcmMinI = lcmMon(I[i],lcmMinI);
+  }
+  intvec explcmMinI = leadexp(lcmMinI);
+  // Buscamos los elementos que son x(i) maximales. En caso de que
+  // un generador del ideal sea maximal para 2 variables distintas,
+  // ese generador se elimina.
+  isMaximal[sizI] = 0;
+  intvec genexp;
+  for (i = 1 ; i <= sizI ; i ++)
+  {
+    genexp = leadexp(I[i]);
+    cont = 0;
+    for ( j = 1 ; j <= nvar ; j ++)
+    {
+      if (genexp[j] <> 0 && genexp[j] == explcmMinI[j])
+      {
+        if (cont == 0)
+        {
+          cont ++;
+          isMaximal[i] = j;
+        }
+        else
+        {
+          // Porque cuando encontramos que era maximal para
+          // la primera variable, lo guardamos
+          isMaximal[i] = 0;
+          // Eliminamos del ideal
+          if (i <> 1 && i <> sizI)
+          {
+            I = I[1..i - 1],I[i + 1..sizI];
+          }
+          else
+          {
+            if (i == 1)
+            {
+              I = I[2..sizI];
+            }
+            else
+            {
+              I = I[1..sizI - 1];
+            }
+          }
+          i --;
+          sizI = ncols(I);
+          // Generador i eliminado, miramos el siguiente
+          break;
+        }
+      }
+    }
+  }
+   // En isMaximal[i] tenemos 0 si I[i] no es maximal,
+   // y j si I[i] es maximal en x(j).
+  // Matriz de exponentes de los generadores del ideal
+  intmat expI[sizI][nvar];
+  for (i = 1 ; i <= sizI ; i++)
+  {
+    expI[i,1..nvar] = leadexp(I[i]);
+  }
+  // Buscamos ahora cota inferior
+  poly lcmMi = 1;
+  poly l,gcdMi;
+  intvec Mi, mincol,expgcd;
+  for (i = 1 ; i <= nvar ; i ++)
+  {
+    Mi = 0;
+    cont = 0;
+    for (j = 1 ; j <= sizI ; j ++)
+    {
+      // De isMaximal solo se usan las entradas que se corresponden con elementos del ideal
+      if (expI[j,i] <> 0)
+      {
+        if (isMaximal[j] == 0 or isMaximal[j] == i)
+        {
+          // Elementos del sistema minimal que estan
+          // en Mi
+          cont ++;
+          Mi[cont] = j;
+        }
+      }
+    }
+    // Si solo hay un elemento en Mi, no hay nada que hacer
+    if (cont > 1)
+    {
+      gcdMi = I[Mi[1]];
+      // Tenemos los generadores a los que hay que hallar el gcd
+      for (j = 2; j <= cont ; j ++)
+      {
+        gcdMi = gcd(gcdMi,I[Mi[j]]);
+      }
+    }
+    else
+    {
+      if (Mi <> 0)
+      {
+        gcdMi = I[Mi[1]];
+      }
+      else
+      {
+        // Falta alguna variable
+        return (0,I);
+      }
+    }
+    l = gcdMi/var(i);
+    lcmMi = lcmMon(lcmMi,l);
+  }
+  // Ahora devolvemos la cota inferior, que luego hay que multiplicar
+  // por el monomio que define el corte.
+  // Devolvemos tambien el ideal (por si se ha modificado).
+  return (lcmMi,I);
+}
+//////////////////////////////////////////////////////////////////////
+//
+static proc con (ideal I , ideal S , poly q)
+{
+  int nvar = nvars(basering);
+  // Variables
+  int i;
+  poly piI;
+  int sizI = ncols(I);
+  // Simplification process
+  poly p;
+  list sol;
+  while (1)
+  {
+    // (I,S,q) normal slice?
+    // Como cada vez que introducimos una cota inferior sabemos
+    // que la slice actual es la inner slice (la otra es vacio),
+    // hay que volver a verificar si es normal
+    if ( S <> 0 )
+    {
+      // m/rad(m) esta en S, para m generador minimal de I??
+      for (i = 1 ; i <= sizI ; i ++)
+      {
+        piI = pi(I[i]);
+        if (membershipMon(piI,S) == 1)
+        {
+          if (i == 1)
+          {
+            I = I[2..sizI];
+          }
+          else
+          {
+            if (i == sizI)
+            {
+              I = I[1..sizI - 1];
+            }
+            else
+            {
+              I = I[1..i - 1],I[i + 1..sizI];
+            }
+          }
+          sizI = ncols(I);
+          i --;
+        }
+      }
+    }
+    // Buscamos cota inferior, y si es distinta de 1, simplificamos
+    sol = simplification(I);
+    p = sol[1];
+    if (p == 1)
+    {
+      break;
+    }
+    else
+    {
+      if (p == 0)
+      {
+        break;
+      }
+      else
+      {
+        if (membershipMon(p,I) == 1 )
+        {
+          break;
+        }
+      }
+    }
+    // Changing slice by simplification
+    I = sol[2];
+    I = minbase(quotient(I,p));
+    q = p*q;
+    S = minbase(quotient(S,p));
+    sizI = ncols(I);
+  }
+  sizI = ncols(I);
+  // (I,S,q) base case?
+  poly lcmMinI;
+  lcmMinI = 1;
+  for (i = 1 ; i <= sizI ; i ++)
+  {
+    lcmMinI = lcmMon(lcmMinI,I[i]);
+  }
+  // a:b generates an intvec of length b with constant entries a
+  intvec one = 1:nvar;
+  if (divideMon(monomial(one),lcmMinI) == 0)
+  {
+    return (0);
+  }
+  if (equal(radicalMon(I),I) == 1)
+  {
+    if (equal(I, maxideal(1)) == 0)
+    {
+      return (0);
+    }
+    else
+    {
+      for (i = 1 ; i <= nvar ; i ++)
+      {
+        q = q * var(i);
+      }
+      return (q);
+    }
+  }
+  // Selecting pivot
+  p = pivot(I,lcmMinI,S);
+  // New slices
+  ideal S1 = minbase(quotient(S,p));
+  ideal I1 = minbase(quotient(I,p));
+  ideal S2 = S,p;
+  S2 = minbase(S2);
+  return (con(I1,S1,p*q),con(I,S2,q));
+}
+//////////////////////////////////////////////////////////////////////
+//
+static proc irredDecMonSlice (ideal I)
+{
+  int nvar = nvars(basering);
+  int sizI = ncols(I);
+  int i,j;
+  // Artinian ideal
+  ideal artI;
+  list artinianization = artinian(I);
+  if (artinianization[1] == 0)
+  {
+    artI = artinianization[2];
+  }
+  else
+  {
+    artI = I;
+  }
+  // Easy case: 2 variables
+  if (nvar == 2)
+  {
+    artI = sort(artI)[1];
+    int sizartI = size(artI);
+    for (i = 1 ; i <= sizartI - 1 ; i ++)
+    {
+      components[i] = var(1)^(leadexp[artI[i]][1])*var(2)^(leadexp[artI[i + 1]][2]);
+    }
+    return (components);
+  }
+  ideal irredDec = con (artI,0,1);
+  // Delelting zeros
+  irredDec = simplify(irredDec,2);
+  // Delting, in case, generators
+  intvec elimina;
+  if (artinianization[1] == 0)
+  {
+    elimina = artinianization[3];
+  }
+  else
+  {
+    elimina = 0;
+  }
+ // Each generator (monomial) corresponds to an ideal
+  list components;
+  poly comp;
+  intvec exp;
+  int sizIrred = size(irredDec);
+  ideal auxIdeal;
+  for (i = 1 ; i <= sizIrred ; i ++)
+  {
+    comp = irredDec[i];
+    exp = leadexp(comp);
+    for (j = 1 ; j <= nvar ; j ++)
+    {
+      if (exp[j] <> 0)
+      {
+        if (elimina <> 0)
+        {
+          if (exp[j] == elimina[j])
+          {
+            auxIdeal[j] = 0;
+          }
+          else
+          {
+            auxIdeal[j] = var(j)^exp[j];
+          }
+        }
+        else
+        {
+          auxIdeal[j] = var(j)^exp[j];
+        }
+      }
+    }
+    components[i] = simplify(auxIdeal,2);
+    auxIdeal = 0;
+  }
+  return (components);
+}
+//////////////////////////////////////////////////////////////////////
+//
+static proc primDecMonSlice (ideal I)
+{
+ // VARIABLES
+  list l1,l2;
+  // ---- Irreducible decomposition
+  // Slice Method
+  l1 = irredDecMonSlice (I);
+// ----- Primary decomposition
+  l2 = irredPrimary (l1);
+  return (l2);
+}
+//////////////////////////////////////////////////////////////////////
+//                                                                  //
+//                       DECOMPOSITIONS                             //
+//                                                                  //
+//////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////
+//
+proc irreddecMon
+"USAGE:    irreddecMon (I[,alg]); I ideal, alg string.
+RETURN:   list, the irreducible components of the monomial ideal I.
+          (returns -1 if I is not a monomial ideal).
+ASSUME:   I is a monomial ideal of the basering k[x(1)..x(n)].
+NOTE:     This procesure returns the irreducible decomposition of I.
+          One may call the procedure with different algorithms using
+          the optional argument 'alg':
+          - the direct method following Vasconcelos' book (alg=vas)
+          - via the Alexander dual and using doble dual (alg=add),
+          - via the Alexander dual and quotients following E. Miller
+            (alg=ad),
+          - the formula of irreducible components (alg=for),
+          - via the Scarf complex following Milowski (alg=mil),
+          - using the label algorihtm of Roune (alg=lr),
+          - using the algorithm of Gao-Zhu (alg=gz).
+          - using the slice algorithm of Roune (alg=sr).
+EXAMPLE:  example irreddecMon; shows some examples.
+"
+{
+  // COMPROBACIONES
+  ideal I = #[1];
+  int control = checkIdeal(I);
+  // Si el sistema de generadores no esta formado por monomios, hay
+  // que comprobar si el ideal es monomial.
+  if (control == 0)
+  {
+    list isMon = isMonomialGB (I);
+    if (isMon[1] == 0)
+    {
+      ERROR ("the ideal is not monomial.");
+    }
+    else
+    {
+      I = isMon[2];
+      // Ya lo tenemos con los generadores minimales
+    }
+  }
+  else
+  {
+    // Generadores monomiales, hallamos sistema minimal
+    I = minbase(I);
+  }
+  // Si el ideal es irreducible, devolvemos el mismo
+  if (isirreducibleMon(I) == 1)
+  {
+    return (I);
+  }
+  // Si no me han dado opcion, elijo una yo.
+  if (size(#) == 1)
+  {
+    return (irredDec3(I));
+  }
+  // Leo la opcion y llamo al procedimiento oportuno
+  else
+  {
+    if (#[2] == "vas")
+    {
+      return (irredDec1(I));
+    }
+    if (#[2] == "add")
+    {
+      return (irredDec3(I));
+    }
+    if (#[2] == "ad")
+    {
+      return (irredDec4(I));
+    }
+    if (#[2] == "for")
+    {
+      return (irredDec5(I));
+    }
+    if (#[2] == "mil")
+    {
+      return (ScarfMethod(I));
+    }
+    if (#[2] == "lr")
+    {
+      return (labelAlgorithm(I));
+    }
+    if (#[2] == "gz")
+    {
+      return (incrementalAlg(I));
+    }
+    if (#[2] == "sr")
+    {
+      return (irredDecMonSlice(I));
+    }
+  }
+}
+example
+{"EXAMPLE:"; echo = 2;
+ ring R = 0,(w,x,y,z),Dp;
+ideal I = w^3*x*y,w*x*y*z,x^2*y^2*z^2,x^2*z^4,y^3*z;
+// Vasconcelos
+ irreddecMon (I,"vas");
+// Alexander Dual
+ irreddecMon (I,"ad");
+ // Scarf Complex
+ irreddecMon (I,"mil");
+ // slice algorithm
+ irreddecMon(I,"sr");
+}
+//////////////////////////////////////////////////////////////////////
+//
+proc primdecMon
+"USAGE:    primdecMon (I[,alg]); I ideal, alg string
+RETURN:   list, the components in a minimal primary decomposition of I.
+          (returns -1 if I is not a monomial ideal).
+ASSUME:   I is a monomial ideal of the basering k[x(1)..x(n)].
+NOTE:     This procesure returns a minimal primary decomposition of I.
+          One may call the procedure with different algorithms using
+          the optional argument 'alg':
+          - the direct method for a primary decomposition following
+            Vasconcelos' book (alg=vp),
+          - from the irreducible decomposition obtained via the direct
+            method following Vasconcelos' book (alg=vi),
+          - from the irreducible decomposition obtained via the
+            Alexander dual and using doble dual (alg=add),
+          - from the irreducible decomposition obtained via the
+            Alexander dual and quotients following E. Miller (alg=ad),
+          - from the irreducible decomposition obtained
+            via ........ (alg=for),
+          - from the irreducible decomposition obtained via the Scarf
+            complex following Milowski (alg=mil),
+          - from the irreducible decomposition obtained using the label
+            algorihtm of Roune (alg=lr),
+          - from the irreducible decomposition obtained using the
+            algorithm of Gao-Zhu (alg=gz),
+          - from the irreducible decomposition obtained using the slice
+            algorithm of Roune (alg=sr).
+EXAMPLE:  example primdecMon; shows some examples.
+"
+{
+  // COMPROBACIONES
+  ideal I = #[1];
+  int control = checkIdeal(I);
+  // Si el sistema de generadores no esta formado por monomios, hay
+  // que comprobar si el ideal es monomial.
+  if (control == 0)
+  {
+    list isMon = isMonomialGB (I);
+    if (isMon[1] == 0)
+    {
+      ERROR ("the ideal is not monomial.");
+    }
+    else
+    {
+      I = isMon[2];
+      // Ya lo tenemos con los generadores minimales
+    }
+  }
+  else
+  {
+    // Generadores monomiales, hallamos sistema minimal
+    I = minbase(I);
+  }
+  // Estudiamos si el ideal es o no primario
+  if (isprimaryMon(I) == 1)
+  {
+    return (I);
+  }
+  // Si no me han dado opcion, elijo una yo.
+  if (size(#) == 1)
+  {
+    return(primDec3(I));
+  }
+  // Leo la opcion y llamo al procedimiento oportuno
+  else
+  {
+    if (#[2] == "vi")
+    {
+      return (primDec1(I));
+    }
+    if (#[2] == "vp")
+    {
+      return (primDec2(I));
+    }
+    if (#[2] == "add")
+    {
+      return (primDec3(I));
+    }
+    if (#[2] == "ad")
+    {
+      return (primDec4(I));
+    }
+    if (#[2] == "for")
+    {
+      return (primDec5(I));
+    }
+    if (#[2] == "mil")
+    {
+      return (scarfMethodPrim(I));
+    }
+    if (#[2] == "lr")
+    {
+      return (labelAlgPrim(I));
+    }
+    if (#[2] == "gz")
+    {
+      return (incrementalAlgPrim(I));
+    }
+    if (#[2] == "sr")
+    {
+      return (primDecMonSlice(I));
+    }
+  }
+}
+example
+{"EXAMPLE:"; echo = 2;
+ ring R = 0,(w,x,y,z),Dp;
+ideal I = w^3*x*y,w*x*y*z,x^2*y^2*z^2,x^2*z^4,y^3*z;
+// Vasconcelos para primaria
+ primdecMon(I,"vp");
+// Alexander dual
+ primdecMon(I,"add");
+ // label algorithm
+ primdecMon(I,"lr");
+ //slice algorithm
+ primdecMon(I,"sr");
+}
diff --git a/Singular/LIB/mprimdec.lib b/Singular/LIB/mprimdec.lib
new file mode 100644
index 0000000..64c3d53
--- /dev/null
+++ b/Singular/LIB/mprimdec.lib
@@ -0,0 +1,2352 @@
+//////////////////////////////////////////////////////////////////////////////
+
+version="version mprimdec.lib 4.0.0.0 Jun_2013 "; // $Id: a661e43a02223401912a8a968a795aef53a9d30a $
+category="Commutative Algebra";
+
+info="
+LIBRARY: mprimdec.lib   PROCEDURES FOR PRIMARY DECOMPOSITION OF MODULES
+AUTHORS:  Alexander Dreyer, dreyer at mathematik.uni-kl.de; adreyer at web.de
+
+OVERVIEW:
+ Algorithms for primary decomposition for modules based on
+ the algorithms of Gianni, Trager and Zacharias and
+ Shimoyama and Yokoyama (generalization of the latter
+ suggested by Hans-Gert Graebe, Leipzig  )
+ using elments of primdec.lib
+
+REMARK:
+These procedures are implemented to be used in characteristic 0.
+@*They also work in positive characteristic >> 0.
+@*In small characteristic and for algebraic extensions, the
+procedures via Gianni, Trager, Zacharias may not terminate.
+
+PROCEDURES:
+  separator(l);                computes a list of separators of prime ideals
+  PrimdecA(N[,i]);             (not necessarily minimal) primary decomposition
+                               via Shimoyama/Yokoyama (suggested by Graebe)
+  PrimdecB(N,p);               (not necessarily minimal) primary decomposition
+                               for pseudo-primary ideals
+  modDec(N[,i]);               minimal primary decomposition
+                               via Shimoyama/Yokoyama (suggested by Graebe)
+  zeroMod(N[,check]);          minimal zero-dimensional primary decomposition
+                               via Gianni, Trager and Zacharias
+  GTZmod(N[,check]);           minimal primary decomposition
+                               via Gianni, Trager and Zacharias
+  dec1var(N[,check[,ann]]);    primary decomposition for one variable
+  annil(N);                    the annihilator of M/N in the basering
+  splitting(N[,check[,ann]]);  splitting to simpler modules
+  primTest(i[,p]);             tests whether i is prime or homogeneous
+  preComp(N,check[,ann]);      enhanced Version of splitting
+  indSet(i);                   lists with varstrings of(in)dependend variables
+  GTZopt(N[,check[,ann]]);     a faster version of GTZmod
+  zeroOpt(N[,check[,ann]]);    a faster version of zeroMod
+";
+
+LIB "primdec.lib";
+LIB "ring.lib";
+
+
+/////////////////////////////////////////////////////////////////////////////
+// separator(l)
+// computes a list of separators for a list of prime ideals
+// it in a generalization of parts of pseudo_prim_dec_i from primdec.lib
+/////////////////////////////////////////////////////////////////////////////
+
+proc separator (list @L)
+"USAGE:   separator(l); list l of prime ideals
+RETURN:  list sepList;
+         a list of separators of the prime ideals in l,
+         i.e. polynomials p_ij, s.th. p_ij is in l[j],
+         for all l[j] not contained in l[i]
+         but p_ij is not in l[i]
+EXAMPLE: example separator; shows an example
+"
+
+{
+  ideal p_ij;                        // generating p_ij in @L[@j], not in @L[@i]
+  list f_i;                        // generating f_i NOT in @L[@i], but in all @L[@j]
+  int @i, at j, at k;
+  int sizeL=size(@L);
+  poly @tmp;
+
+  for(@i=1;@i<=sizeL;@i++)
+  {
+    p_ij=0;
+
+    @L[@i]=std(@L[@i]);
+    for(@j=1;@j<=sizeL;@j++)            // compute the separator sep_i
+                                        // of the i-th component
+                                        // f_i separates {Pj not incl in Pi} from Pi
+    {
+      if (@i!=@j)                       // searching for g: not in @L[@i], but @L[@j]
+      {
+        for(@k=1;@k<=ncols(@L[@j]);@k++)
+        {
+          if(NF(@L[@j][@k], at L[@i],1)!=0)
+          {
+            p_ij=p_ij+ at L[@j][@k];
+            break;
+          }
+        }
+      }
+    }
+  @tmp=lcm(p_ij);
+  if(@tmp==0)
+  {
+    @tmp=1;
+  }
+  f_i=f_i+list(@tmp);
+  }
+  return(f_i);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring r=0,(x,y,z),dp;
+  ideal i=(x2y,xz2,y2z,z3);
+  list l=minAssGTZ(i);
+  list sepL=separator(l);
+  sepL;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// PrimdecA(N[,i])
+// computes a primary decomposition, not necessarily minimal,
+// using a generalization of the algorithm of Shimoyama/Yokoyama,
+// suggested by Hans-Gerd Graebe, Leipzig
+// [Hans-Gert Graebe, Minimal Primary Decompostion
+//  and Factorized Groebner Bases, AAECC 8, 265-278 (1997)]
+/////////////////////////////////////////////////////////////////////////////
+
+
+proc PrimdecA(module @N, list #)
+"USAGE:   PrimdecA (N[, i]); module N, int i
+RETURN:  list l
+         a (not necessarily minimal) primary decomposition of N
+         computed by a generalized version of the algorithm of Shimoyama/Yokoyama,
+         @*if i!=0 is given, the factorizing Groebner is used to compute the
+         isolated primes
+EXAMPLE: example PrimdecA; shows an example
+"
+
+{
+  module @M=freemodule(nrows(@N));        // @M=basering^k
+  ideal ann=annil(@N);                    // the annihilator of @N
+  ////////////////////////////////////////////////////////////////
+  // in the trivial case we avoid to compute anything
+  ////////////////////////////////////////////////////////////////
+  if (ann[1]==1)
+  {
+    return(list());
+  }
+  ////////////////////////////////////////////////////////////////
+  // Computation of the Associated Primes
+  ////////////////////////////////////////////////////////////////
+  if (ann[1]==0)
+  {
+    list pr=list(ideal(0));
+  }
+  else
+  {
+    if( (size(#)>0) ){
+      list pr = minAssChar(ann);   // causes message  "/ ** redefining @res **"
+    }
+    else{
+      list pr = minAssGTZ(ann);
+    }
+  }
+
+  list sp, pprimary;     // the separators and the pseudo-primary modules
+  int @i;
+  ideal rest;            // for the computation of the remaining components
+  sp=separator(pr);
+  int sizeSp=size(sp);   // the number of separators
+
+  ////////////////////////////////////////////////////////////////
+  // Computation of the pseudo-primary modules
+  // and an ideal rest s.th. @N is the intersection of the
+  // pseudo-primary modules and @N+rest*@M
+  ////////////////////////////////////////////////////////////////
+  for(@i=1;@i<=sizeSp;@i++)
+  {
+    pprimary=pprimary+list(sat(@N,sp[@i]));
+    rest=rest+sp[@i]^pprimary[@i][2];
+  }
+  list result;           // a primary decomposition of @N
+
+  ////////////////////////////////////////////////////////////////
+  // Extraction of the pseudo-primary modules
+  ////////////////////////////////////////////////////////////////
+  for (@i=1;@i<=size(pprimary);@i++)
+  {
+   result=result+PrimdecB(pprimary[@i][1],pr[@i]);
+  }
+
+  ////////////////////////////////////////////////////////////////
+  // Computation of remaining components
+  ////////////////////////////////////////////////////////////////
+  result=result+PrimdecA(@N+rest*@M);
+
+  return(result);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring r=0,(x,y,z),dp;
+  module N=x*gen(1)+ y*gen(2),
+           x*gen(1)-x2*gen(2);
+  list l=PrimdecA(N);
+  l;
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+// PrimdecB(N, p)
+// computes a primary decomposition, not necessarily minimal,
+// of a pseudo-primary module N with isolated prime p
+// it is based on extraction in primdec.lib
+/////////////////////////////////////////////////////////////////////////////
+
+proc PrimdecB(module @N, ideal isoPrim)
+"USAGE:   PrimdecB (N, p); pseudo-primary module N, isolated prime ideal p
+RETURN:  list l
+         a (not necessarily minimal) primary decomposition of N
+EXAMPLE: example PrimdecB; shows an example
+"
+
+{
+  module @M=freemodule(nrows(@N));        // @M=basering^k
+  ideal ann=annil(@N);                    // the annihilator of @N
+
+  ////////////////////////////////////////////////////////////////
+  // the not-that-trivial case of ann==0
+  ////////////////////////////////////////////////////////////////
+  if(size(ann)==0)
+  {
+    def BAS=basering;
+    execute("ring Rloc=("+charstr(basering)+","+varstr(basering)+"),dummy,("+ordstr(basering)+");");
+    module @N=imap(BAS, @N);
+    poly @q=prepareSat(@N);
+
+    setring BAS;
+    poly @q=imap(Rloc, @q);
+    list satu=sat(@N, at q);
+    if(satu[2]==0)
+    {
+      return(list(list(@N,ideal(0))));
+    }
+    else
+    {
+      return(list(list(satu[1],ideal(0)))+ PrimdecA(@N+(@q^satu[2])*@M));
+    }
+  }
+
+  ////////////////////////////////////////////////////////////////
+  // Extraction of the isolated component @N' and
+  // searching for a polynomial @f of minimal degree
+  // s.th. @N=intersect(@N', @N+ at f*@M)
+  ////////////////////////////////////////////////////////////////
+  list indSets=indepSet(ann,0);
+  poly @f;
+  if(size(indSets)!=0)           //check, whether dim isoPrim !=0
+  {
+    intvec indVec;               // a maximal independent set of variables
+                                 // modulo isoPrim
+    string @U;                   // the independent variables
+    string @A;                   // the dependent variables
+    int @j, at k;
+    int szA;                     //  the size of @A
+    int degf;
+    ideal @g;
+    list polys;
+    int sizePolys;
+    list newPoly;
+
+    ////////////////////////////////////////////////////////////////
+    // the preparation of the quotient ring
+    ////////////////////////////////////////////////////////////////
+    def BAS=basering;
+    for (@k=1;@k<=size(indSets);@k++)
+    {
+      indVec=indSets[@k];
+      for (@j=1;@j<=nvars(BAS);@j++)
+      {
+        if (indVec[@j]==1)
+        {
+          @U=@U+varstr(@j)+",";
+        }
+        else
+        {
+          @A=@A+varstr(@j)+",";
+          szA++;
+        }
+      }
+
+      @U[size(@U)]=")";           // we compute the extractor (w.r.t. @U)
+      execute("ring RAU="+charstr(basering)+",("+ at A+@U+",(C,dp("+string(szA)+"),dp);");
+      module @N=std(imap(BAS, at N));
+                                  // this is also a standard basis in (R[U])[A]
+      @A[size(@A)]=")";
+      execute("ring Rloc=("+charstr(basering)+","+ at U+",("+ at A+",(C,dp);");
+      ideal @N=imap(RAU, at N);
+      ideal @h;
+      for(@j=ncols(@N);@j>=1;@j--)
+      {
+        @h[@j]=leadcoef(@N[@j]);  // consider I in (R(U))[A]
+      }
+      setring BAS;
+      @g=imap(Rloc, at h);
+      kill RAU,Rloc;
+      @U="";
+      @A="";
+      szA=0;
+      @f=lcm(@g);
+      newPoly[1]=@f;
+      polys=polys+newPoly;
+      newPoly=list();
+    }
+    @f=polys[1];
+    degf=deg(@f);
+    sizePolys=size(polys);
+    for (@k=2;@k<=sizePolys;@k++)
+    {
+      if (deg(polys[@k])<degf)
+      {
+        //Waehlt das poly mit dem geringsten Grad.
+        @f=polys[@k];
+        degf=deg(@f);
+      }
+    }
+  }
+  else
+  {
+    @f=1;
+  }
+  if(@f!=1)
+  {
+    list satu = minSatMod(@N, at f);
+    return(list(list(satu[1],isoPrim))+ PrimdecA(@N+satu[2]*@M));
+    //    list satu = sat(@N, at f);
+    //return(list(list(satu[1],isoPrim))+ PrimdecA(@N+ at f^satu[2]*@M));
+  }
+  else
+  {
+    return(list(list(@N,isoPrim)));
+  }
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring r=0,(x,y,z),dp;
+  module N=y*gen(1),y2*gen(2),yz*gen(2),yx*gen(2);
+  ideal p=y;
+  list l=PrimdecB(N,p);
+  l;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// modDec(N[,i])
+// extracts a minimal primary decomposition from the
+// primary decomposition computed by PrimdecA(N[, i])
+// using a Minimality Test suggested by Hans-Gerd Graebe, Leipzig
+/////////////////////////////////////////////////////////////////////////////
+
+proc modDec(module @N, list #)
+"USAGE:   modDec (N[, i]); module N, int i
+RETURN:  list l
+         a minimal primary decomposition of N
+         computed by an generalized version of the algorithm of Shimoyama/Yokoyama,
+         @*if i=1 is given, the factorizing Groebner basis algorithm is used internally.
+EXAMPLE: example modDec; shows an example
+"
+{
+  list prim = PrimdecA(@N, #);
+  int @i, at j, at k, at l;
+  int sizePrim=size(prim);
+
+  ////////////////////////////////////////////////////////////////
+  // the trivial case
+  ////////////////////////////////////////////////////////////////
+  if (sizePrim==0)
+  {
+    return(list(list(@N, ideal(1))));
+  }
+
+  ////////////////////////////////////////////////////////////////
+  // collect primary components with the same associated prime
+  // and substitute them by their intersection
+  ////////////////////////////////////////////////////////////////
+  for(@i=1;@i<=sizePrim;@i++)
+  {
+    for(@j=@i+1;@j<=sizePrim;@j++)
+    {
+      if (@j!=@i)
+      {
+        if (modulesEqual(prim[@i][2],prim[@j- at l][2])==1)
+        {
+          prim[@i][1]=intersect(prim[@i][1],prim[@j- at l][1]);
+          prim=delete(prim, at j-@l);
+          @l++;
+          sizePrim--;
+        }
+      }
+    }
+  }
+
+  ////////////////////////////////////////////////////////////////
+  // minimality test suggested by Graebe:
+  // if f separates the prime p from the primes not contained in p,
+  // then p is not in Ass(M/N) <=> sat(N,f)=sat(sat(N,f),p)
+  ////////////////////////////////////////////////////////////////
+  list tempList;
+  for(@i=1;@i<=sizePrim;@i++)
+  {
+    tempList=tempList+list(prim[@i][2]);
+  }
+  list sepPrimes=separator(tempList);   // the separators of the primes
+  tempList=list();
+  for(@i=1;@i<=sizePrim;@i++)     // compute sat(N,f), for all separators f
+  {
+    tempList=tempList+list(sat(@N,sepPrimes[@i])[1]);
+  }
+  module testMod;
+  @k=0;
+  for(@i=1;@i<=sizePrim;@i++)
+  {
+    testMod=sat(tempList[@i],prim[@i- at k][2])[1];  // computes sat(sat(N,f),p)
+    if (size(NF(testMod,std(tempList[@i]),1))==0) // tests if equal to sat(N,f)
+    {
+      prim=delete(prim, at i-@k);                    // if yes: the component
+      @k++;                                       // is superfluous
+    }
+  }
+
+  return(prim);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring r=0,(x,y,z),dp;
+  module N=x*gen(1)+ y*gen(2),
+           x*gen(1)-x2*gen(2);
+  list l=modDec(N);
+  l;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// zeroMod (N[, check])
+// computes a minimal primary decomposition of a zero-dimensional Module
+// using a generalized version of the algorithm of
+// Gianni, Trager and Zacharias, suggested by Alexander Dreyer
+// [Diploma Thesis, University of Kaiserslautern, 2001]
+/////////////////////////////////////////////////////////////////////////////
+
+proc zeroMod (module @N, list #)
+"USAGE:   zeroMod (N[, check]); zero-dimensional module N[, module check]
+RETURN:  list l
+         the minimal primary decomposition of a zero-dimensional module N,
+         computed by a generalized version of the algorithm of Gianni, Trager and Zacharias
+NOTE:    if the parameter check is given, only components not containing check are computed
+EXAMPLE: example zeroMod; shows an example
+"
+{
+  ////////////////////////////////////////////////////////////////
+  // the module check is needed to compute a minimal decomposition
+  // components containing check are ignored
+  ////////////////////////////////////////////////////////////////
+  if (size(#)>0)
+  {
+    module check=#[1];
+    if (size(NF(check,std(@N),1))==0)
+    {
+      return(list());
+    }
+  }
+  else
+  {
+    module check=freemodule(nrows(@N));
+  }
+
+  ////////////////////////////////////////////////////////////////
+  // the ordering is changed to lex
+  ////////////////////////////////////////////////////////////////
+  def BAS = basering;
+  def @R=changeord(list(list("lp",1:nvars(basering))));
+  setring @R;
+  module @N=fetch(BAS, at N);
+  int nVar=nvars(@R);
+  module @M=freemodule(nrows(@N));     // @M=basering^k
+  ideal ann=std(quotient(@N, at M));      // the annihilator of @M/@N
+  int @k;
+  list result, rest;
+  ideal primary, prim;
+  module primMod;
+
+  ////////////////////////////////////////////////////////////////
+  // the random coordnate change and its inverse
+  ////////////////////////////////////////////////////////////////
+  option(redSB);
+  ideal prepMap=maxideal(1);
+  prepMap[nVar]=0;
+  prepMap[nVar]=(random(100,1,nVar)*transpose(prepMap))[1,1]+var(nVar);
+  map phi=@R,prepMap;
+  prepMap[nVar]=2*var(nVar)-prepMap[nVar];
+  map invphi=@R,prepMap;
+
+  ideal @j=std(phi(ann));
+
+  list fac=factorize(@j[1],2);   // factorization of the 1st elt. in Ann(@N)
+
+  ////////////////////////////////////////////////////////////////
+  // Case: 1st element irreducible
+  ////////////////////////////////////////////////////////////////
+  if(size(fac[2])==1)
+  {
+    prim=primaryTest(@j,fac[1][1]);
+    prim=invphi(prim);
+    setring BAS;
+    @N=std(@N);
+    ideal prim=std(imap(@R,prim));
+    kill @R;
+    if(prim!=0)
+    {
+      return(list(list(@N,prim)));
+    }
+    else
+    {
+      return(zeroMod(@N,check));
+    }
+   }
+2;
+  ////////////////////////////////////////////////////////////////
+  // Computation of the - hopefully primary - modules
+  // their annihilators and associated primes
+  ////////////////////////////////////////////////////////////////
+  poly @p, @h;
+  module check;
+  for (@k=1;@k<=size(fac[1]);@k++)
+  {
+    @p=fac[1][@k]^fac[2][@k];
+    @h=@j[1]/@p;
+    primMod=std(quotient(phi(@N), at h));
+    check=imap(BAS,check);
+    check=phi(check);
+    if (size(NF(check,primMod,1))>0)
+    {
+      primary=std(@j+ at p);
+      // test if the modules were primary and in general position
+      prim=primaryTest(primary,fac[1][@k]);
+      if (prim==0)
+      {
+            rest[size(rest)+1]=invphi(primMod);
+      }
+      else
+      {
+            result[size(result)+1]=list(std(invphi(primMod)),std(invphi(prim)));
+      }
+
+    }
+  }
+
+  ////////////////////////////////////////////////////////////////
+  // the bad cases
+  ////////////////////////////////////////////////////////////////
+
+  for (@k=1; @k<=size(rest);@k++)
+  {
+    result = result+zeroMod(rest[@k],invphi(check));
+  }
+
+  option(noredSB);
+  setring BAS;
+  list result=imap(@R, result);
+  kill @R;
+  return(result);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring r=0,z,dp;
+  module N=z*gen(1),(z-1)*gen(2),(z+1)*gen(3);
+  list l=zeroMod(N);
+  l;
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+// GTZmod (N[, check])
+// computes a minimal primary decomposition of N
+// using a generalized version of the algorithm of
+// Gianni, Trager and Zacharias, suggested by Alexander Dreyer
+// [Diploma Thesis, University of Kaiserslautern, Germany, 2001]
+/////////////////////////////////////////////////////////////////////////////
+
+proc GTZmod (module @N, list #)
+"USAGE:   GTZmod (N[, check]); module N[, module check]
+RETURN:  list l
+         the minimal primary decomposition of the module N,
+         computed by a generalized version of the algorithm of Gianni, Trager and Zacharias
+NOTE:    if the parameter check is given, only components not containing check are computed
+EXAMPLE: example GTZmod; shows an example
+"
+{
+  if (size(@N)==0)
+  {
+    return(list(@N,ideal(0)));
+  }
+
+  ////////////////////////////////////////////////////////////////
+  // the module check is needed to compute a minimal decomposition
+  // components containing check are ignored
+  ////////////////////////////////////////////////////////////////
+  if (size(#)>0)
+  {
+    module check=#[1];
+    if (size(NF(check,std(@N),1))==0)
+    {
+      return(list());
+    }
+  }
+  else
+  {
+    module check= freemodule(nrows(@N));
+  }
+
+  module @M=freemodule(nrows(@N));
+  def BAS = basering;
+  int @j;
+  int nVar=nvars(BAS);
+  int @k;
+  string @U;                       // the independent variables
+  string @A;                       // the dependent variables
+  @N=std(@N);
+  ideal ann=std(quotient(@N, at M));  // the annihilator of @M/@N
+
+
+  ////////////////////////////////////////////////////////////////
+  // the trivial and the zero-dimensional case
+  ////////////////////////////////////////////////////////////////
+  int Ndim=dim(@N);
+  if ((Ndim==0)||(Ndim==-1))
+  {
+    return(zeroMod(@N, check));
+  }
+
+  ////////////////////////////////////////////////////////////////
+  // the not-that-trivial case of ann==0
+  ////////////////////////////////////////////////////////////////
+  if(size(ann)==0)
+  {
+    execute("ring Rloc=("+charstr(basering)+","+varstr(basering)+"),dummy,("+ordstr(basering)+");");
+    module @N=imap(BAS, @N);
+    poly @q=prepareSat(@N);
+
+    setring BAS;
+    poly @q=imap(Rloc, @q);
+    list satu=sat(@N, at q);
+    if(satu[2]==0)
+    {
+      return(list(list(@N,ideal(0))));
+    }
+    else
+    {
+      check=intersect(check,satu[1]);
+      return(list(list(satu[1],ideal(0)))+GTZmod(@N+(@q^satu[2])*@M,check));
+    }
+  }
+
+  ////////////////////////////////////////////////////////////////
+  // the preparation of the quotient ring
+  ////////////////////////////////////////////////////////////////
+  intvec indVec=indepSet(ann);
+  int szA;
+  for (@k=1;@k<=size(indVec);@k++)
+  {
+    if (indVec[@k]==1)
+    {
+      @U=@U+varstr(@k)+",";
+    }
+    else
+    {
+      @A=@A+varstr(@k)+",";
+      szA++;
+    }
+  }
+  @U[size(@U)]=")";             // we compute the extractor (w.r.t. @U)
+  execute("ring RAU="+charstr(basering)+",("+ at A+@U+",(C,dp("+string(szA)+"),dp);");
+  module @N=std(imap(BAS, at N));  // this is also a standard basis in (R[U])[A]
+  @A[size(@A)]=")";
+  execute("ring Rloc=("+charstr(basering)+","+ at U+",("+ at A+",(C,dp);");
+  module @N=imap(RAU, at N);
+  kill RAU;
+
+  ////////////////////////////////////////////////////////////////
+  // the zero-dimensional decomposition
+  ////////////////////////////////////////////////////////////////
+  list qprim=zeroMod(@N,imap(BAS,check));
+
+  ////////////////////////////////////////////////////////////////
+  //  preparation for saturation
+  ////////////////////////////////////////////////////////////////
+  poly @q=prepareSat(@N);
+  if (size(qprim)==0)
+  {
+    setring BAS;
+    poly @q=imap(Rloc, at q);
+    kill Rloc;
+    @q=@q^sat(@N, at q)[2];
+    if (deg(@q)>0)
+    {
+      return(GTZmod(@N+ at q*@M,check));
+    }
+    else
+    {
+      return(list());
+    }
+  }
+
+  list @p;
+  for (@k=1;@k<=size(qprim);@k++)
+  {
+    @p[@k]=list(prepareSat(qprim[@k][1]),prepareSat(qprim[@k][2]));
+  }
+
+  ////////////////////////////////////////////////////////////////
+  // compute the recontractions
+  // back in the original ring
+  ////////////////////////////////////////////////////////////////
+  setring BAS;
+  list @p=imap(Rloc, at p);
+  list qprim=imap(Rloc,qprim);
+  poly @q=imap(Rloc, at q);
+  kill Rloc;
+  for(@k=1;@k<=size(qprim);@k++)
+  {
+    qprim[@k]=list(sat(qprim[@k][1], at p[@k][1])[1],
+                   sat(qprim[@k][2], at p[@k][2])[1]);
+    check=intersect(check,qprim[@k][1]);
+  }
+  @q=@q^sat(@N, at q)[2];
+  if (deg(@q)>0)
+  {
+    qprim=qprim+GTZmod(@N+ at q*@M,check);
+  }
+
+  return(qprim);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring r=0,(x,y,z),dp;
+  module N=x*gen(1)+ y*gen(2),
+           x*gen(1)-x2*gen(2);
+  list l=GTZmod(N);
+  l;
+}
+
+
+proc prepareSat(module @N, list #)
+
+{
+  int @k;
+  poly @p=leadcoef(@N[1]);
+  for (@k=2;@k<=size(@N);@k++)
+  {
+    @p=lcm_chr(@p,leadcoef(@N[@k]));
+    //    @p=@p*leadcoef(@N[@k]);
+  }
+  return(@p);
+}
+
+proc lcm_chr(poly @i, poly @j)
+
+{
+  def LBAS = basering;
+  if (npars(basering)==0)
+  {
+    string strg="";
+  }
+  else
+  {
+     if (nvars(basering)==0)
+     {
+       string strg=parstr(basering);
+     }
+     else
+     {
+       string strg=parstr(basering)+",";
+     }
+  }
+  execute("ring PRing="+string(char(basering))+",("+strg+varstr(basering)+"),dp");
+  ideal @a=ideal(imap(LBAS, at i),imap(LBAS, at j));
+  poly @p=lcm(@a);
+  setring LBAS;
+  poly @p=imap(PRing, at p);
+  kill PRing;
+  return(@p);
+}
+
+///////////////////////////////////////////////////////////////////////
+// The optimized procedures and procdures needed for this optimization
+///////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// testit (N, l)
+// a small procedure, which checks whether
+// N=intersect(l[1][1],...,l[size(l)][1])
+// and whether annil(l[i][1]) is primary
+// Just for testing the procedures.
+/////////////////////////////////////////////////////////////////////////////
+
+proc testit (module N, list #)
+"USAGE:   testit (N, l); module N, list l
+EXAMPLE: example testit; shows an example
+"
+{
+  if (size(#)==0)
+  {
+    return()
+  }
+  int i;
+  list l=#;
+  module nn=freemodule(nrows(N));
+  module M=freemodule(nrows(N));
+
+  for(i=1;i<=size(l);i++)
+  {
+    nn=intersect(nn,l[i][1]);
+    if ((size(decomp(quotient(l[i][1],M)))>2)&&(size(l[i][2])>0))
+    {
+     "nicht primary obwohl erkannt!";
+     l[i];std(quotient(l[i][1],M));std(radical(quotient(l[i][1],M)));
+      pause();
+     }
+  }
+  int j,k;
+  j=size(NF(nn,std(N),1));
+  k=size(NF(N,std(nn),1));
+  if ((j!=0)||(k!=0))
+  {
+    "testit fehler!!!";
+    pause();
+  }
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring r=0,(x,y,z),dp;
+  module N=x*gen(1)+ y*gen(2),
+           x*gen(1)-x2*gen(2);
+  list l=GTZmod(N);
+  testit(N,l);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// annil (N)
+// computes the annihilator of M/N in the basering
+/////////////////////////////////////////////////////////////////////////////
+
+proc annil (module N)
+"USAGE:   annil(N);  modul N
+RETURN:  ideal ann=std(quotient(N,freemodule(nrows(N))));
+         the annihilator of M/N in the basering
+NOTE:    ann is a std basis in the basering
+EXAMPLE: example annil; shows an example
+"
+{
+ intvec optionsVec=option(get);
+ option (returnSB);
+ ideal ann=quotient(N,freemodule(nrows(N)));
+ attrib (ann, "isSB",1);
+ option (set,optionsVec);
+ return(ann);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring r=0,(x,y,z),dp;
+  module N=x*gen(1), y*gen(2);
+  ideal ann=annil(N);
+  ann;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+//  splitting(N[,check[, ann]])
+//  INPUT:  a zero-dimensional module N, module check, ideal ann=annil(N)
+//          splitting computes an list of modules
+//          using the factorization of the elements of annil(N)
+//          s.th. N is equal to the intersections of these modules
+//          A prim test is used to check if the modules are primary
+//  OUTPUT: (l, check)
+/////////////////////////////////////////////////////////////////////////////
+
+proc splitting (module @N, list #)
+"USAGE:   splitting(N[,check[, ann]]);  modul N, module check, ideal ann
+RETURN:  (l, check) list l, module check
+         the elements of l consists of quadruples, where
+         [1] is of type module, [2], [3] and [4] are of type ideal,
+         s.th. the intersection of the modules is equal to the
+         zero-dimensional module N, furthermore l[j][3]=annil(l[j][1])
+         and l[j][4] contains internal ideal data;
+         if l[j][2]!=0 then the module l[j][1] is primary
+            with associated prime l[j][2], and check=intersect(check, l[j][1]) is computed
+NOTE:    if the parameter check is given, only components not containing
+         check are computed; if ann is given, ann is used instead of annil(N)
+EXAMPLE: example splitting; shows an example
+"
+{
+  ideal ann; module check, @M; int checked;
+  (ann, check, @M,checked)=getData(@N,#);
+  if(checked)
+  {
+    return(list());
+  }
+  if(size(#)>=3)
+  {
+    ideal splitPrime=#[3];
+  }
+  else
+  {
+    ideal splitPrime=ann;
+  }
+
+  list fact, result, splitTemp;
+  int @i, at k, at j,szFact;
+  for (@i=1;@i<=size(ann);@i++)
+  {
+    fact=factorize(ann[@i],2);
+    szFact=size(fact[2]);
+    // if the element is the power of an irreducible element
+    if(szFact==1)
+    {
+      if(vdim(ann)==deg(ann[@i]))
+      {
+        splitPrime=interred(splitPrime+ideal(fact[1][1]));
+        result=result+list(list(@N,splitPrime,ann,splitPrime));
+      }
+      else
+      {
+        splitPrime=interred(splitPrime+ideal(fact[1][1]));
+        if (homog(splitPrime))
+        {
+           result=result+list(list(@N,maxideal(1),ann,splitPrime));
+        }
+      }
+    }
+    else
+    {
+      if(gcdTest(fact[1]))       // Case: (f1,...,fk)=(1)
+      {
+        (splitTemp, check)=sp1(@N,fact,check,ann,splitPrime);
+        result=result+splitTemp;
+      }
+      else
+      {
+                                // if the element is not irreducible
+        (splitTemp, check)=sp2(@N,fact[1][1],check,ann,splitPrime);
+        result=result+splitTemp;
+      }
+    }
+  }
+  @i=1;@k=size(result);
+
+  ////////////////////////////////////////////////////////////////
+  // delete multiple Modules
+  ////////////////////////////////////////////////////////////////
+  while (@i<=@k)
+  {
+    @j=1;
+    while(@j<=@i-1)
+    {
+      if (stdModulesEqual(result[@j][1],result[@k][1]))
+      {
+        result=delete(result, at i);
+        @k--;@i--;break;
+      }
+      @j++;
+    }
+    @i++;
+  }
+  list rest;
+  @i=1;@k=size(result);
+
+  ////////////////////////////////////////////////////////////////
+  // if not primary then split the obtained modules once again
+  ////////////////////////////////////////////////////////////////
+  while (@i<=@k)
+  {
+    if (size(result[@i][2])==0)
+    {
+      rest=rest+list(list(result[@i][1],result[@i][3],result[@i][4]));
+      result=delete(result, at i);
+      @k--;@i--;
+    }
+    else
+    {
+      check=intersect(check,result[@i][1]);
+    }
+    @i++;
+  }
+  for(@i=1;@i<=size(rest);@i++)
+  {
+    (splitTemp,check)=splitting(rest[@i][1],check,rest[@i][2],rest[@i][3]);
+    result=result+splitTemp;
+  }
+
+  if (size(result)==0)
+  {
+    result=list(list(@N,ideal(0),ann,ann));
+  }
+  return(result, check);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring r=0,z,lp;
+  module N=z*gen(1), (z+1)*gen(2);
+  N=std(N);
+  list l; module check;
+  (l, check)=splitting(N);
+  l;
+  check;
+}
+
+  ////////////////////////////////////////////////////////////////
+  // sp1: splits a module as follows
+  // (N+f*g*M)=intersect((N+f*M),(N+g*M)) if (f,g)=(1)
+  ////////////////////////////////////////////////////////////////
+
+static proc sp1(module @N,list fact,list #)
+{
+  ideal ann; module check, @M; int @i;
+  (ann, check, @M, @i)=getData(@N, #);
+  if(size(#)>=3)
+  {
+    ideal splitPrime=#[3];
+  }
+  else
+  {
+    ideal splitPrime=ann;
+  }
+  list pr;
+  module splitMod;
+  ideal splitAnn, prim, tempPrime;
+  for(@i=1;@i<=size(fact[2]);@i++)
+  {
+    splitMod=std(@N+(fact[1][@i]^fact[2][@i])*@M);
+    if(size(NF(check,splitMod,1))>0)
+    {
+      splitAnn=std(ann,(fact[1][@i]^fact[2][@i]));
+      tempPrime=interred(splitPrime+ideal(fact[1][@i]));
+      prim=primTest(splitAnn,fact[1][@i],tempPrime);
+      pr=pr+list(list(splitMod,prim,splitAnn,tempPrime));
+      if (size(prim)>0)
+      {
+        check=intersect(check,splitMod);
+      }
+    }
+  }
+  return (pr, check);
+}
+
+  ////////////////////////////////////////////////////////////////
+  // sp2: splits a module as follows
+  // N=intersect((N:f),(N+f*M))
+  ////////////////////////////////////////////////////////////////
+
+static proc sp2(module @N,  poly p, list #)
+{
+  ideal ann; module check, @M; int @i;
+  (ann, check, @M, @i)=getData(@N, #);
+  if(size(#)>=3)
+  {
+    ideal splitPrime=#[3];
+  }
+  else
+  {
+    ideal splitPrime=ann;
+  }
+  list fact=sat(@N, p);
+  list splitList;
+  ideal splitAnn, prim, tempPrime;
+  if (fact[2]>0)
+  {
+   module n1=std(@N+(p^fact[2]*@M));
+   module n2=fact[1];
+   if (size(NF(check,n1,1))>0)
+   {
+    splitAnn=std(ann+ideal(p^fact[2]));
+    tempPrime=interred(splitPrime+ideal(p));
+    prim=primTest(tempPrime);
+    splitList=list(list(n1, prim, splitAnn,tempPrime));
+    if(size(prim)>0)
+    {
+      check=intersect(check, n1);
+    }
+   }
+   if(size(NF(check,n2,1))>0)
+   {
+    splitAnn=annil(n2);
+    prim=primTest(splitAnn);
+    splitList=splitList+list(list(n2,prim,splitAnn,splitAnn));
+    if(size(prim)>0)
+    {
+    check=intersect(check, n2);
+    }
+   }
+   return(splitList, check);
+  }
+  else
+  {
+   return (list(list(@N,ideal(0),ideal(0))), check);
+  }
+}
+
+/////////////////////////////////////////////////////////////////////////////
+//  primeTest(i[, p])
+//  tests whether i is prime or homogeneous
+//  is both cases radical(i) is returned
+/////////////////////////////////////////////////////////////////////////////
+
+proc primTest(ideal id, list #)
+"USAGE:   primTest(i[, p]); a zero-dimensional ideal i, irreducible poly p in i
+RETURN:  if i is neither prime nor homogeneous then ideal(0) is returned,
+         otherwise radical(i)
+EXAMPLE: example primTest; shows an example
+"
+{
+  ideal tempPrime;
+  int testTempPrime;
+  if (size(#)>0)
+  {
+    poly @p=#[1];
+    if(size(#)>1)
+    {
+      tempPrime=#[2];
+      testTempPrime=1;
+    }
+  }
+  else
+  {
+    poly @p=0;
+
+  }
+  ideal prim=ideal(0);
+  if((size(#)>0)&&(vdim(id)==deg(@p)))
+  {
+    prim=id;
+  }
+  else
+  {
+    if ((homog(id))||((testTempPrime)&&(homog(tempPrime))))
+    {
+      prim=maxideal(1);
+    }
+  }
+  return (prim);
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring r=0,(x,y,z),lp;
+  ideal i=x+1,y-1,z;
+  i=std(i);
+  ideal primId=primTest(i,z);
+  primId;
+
+  i=x,z2,yz,y2;
+  i=std(i);
+  primId=primTest(i);
+  primId;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// preComp(N, check[, ann])
+// preComp is an enhanced version of splitting,
+// but before computing splitting the first element of std(annil(N))
+// is factorized and the obtained modules are tested for primarity
+/////////////////////////////////////////////////////////////////////////////
+
+proc preComp (module @N, list #)
+"USAGE:   preComp(N,check[, ann]);  modul N, module check, ideal ann
+RETURN:  (l, check) list l, module check
+         the elements of l consists of a triple with
+         [1] of type module [2] and [3] of type ideal
+         s.th. the intersection of the modules is equal to the
+         zero-dimensional module N, furthermore l[j][3]=annil(l[j][1])
+         if l[j][2]!=0 then the module l[j][1] is primary
+            with associated prime l[j][2],
+            and check=intersect(check, l[j][1]) is computed
+NOTE:    only components not containing check are computed;
+         if ann is given, ann is used instead of annil(N)
+EXAMPLE: example preComp; shows an example
+"
+{
+  def BAS=basering;
+  def @R=changeord(list(list("C",0:1),list("lp",1:nvars(basering))));
+  setring @R;
+  module @N=std(imap(BAS, at N));
+  ideal ann; module check, @M; int @k;
+  (ann, check, @M, @k)=getData(@N,imap(BAS,#),1);
+  list act,primary;
+  ideal primid,helpid;
+  module primmod;
+
+  ////////////////////////////////////////////////////////////////
+  // the first element of the standardbase is factorized
+  ////////////////////////////////////////////////////////////////
+  if(deg(ann[1])>0)
+  {
+    act=factorize(ann[1],2);
+  }
+  else
+  {
+    setring BAS;
+    module check=imap(@R,check);
+    kill @R;
+    return(list(), check);
+  }
+
+  ////////////////////////////////////////////////////////////////
+  // with the factors new modules are created
+  // (hopefully the primary decomposition)
+  ////////////////////////////////////////////////////////////////
+  if(size(act[1])>1)               // Case: act[1] not irreducible
+  {
+     for(@k=1;@k<=size(act[1]);@k++)
+     {
+       primmod=std(@N+(act[1][@k]^act[2][@k])*@M);
+       if (size(NF(check,primmod,1))>0)
+       {
+         primid=std(ann,act[1][@k]^act[2][@k]);
+         if((act[2][@k]==1)&&(vdim(primid)==deg(act[1][@k])))
+         {
+           primary = primary+list(list(primmod,primid,primid));
+         }
+         else
+         {
+           helpid=primid;
+           primid=primaryTest(primid,act[1][@k]);
+           primary = primary+list(list(primmod,primid,helpid));
+         }
+       }
+       if (size(primid)>0)
+       {
+         check=intersect(check, primmod);
+       }
+     }
+   }
+   else                            // Case: act[1]  irreducible
+   {
+     primid=ann;
+     primmod=@N;
+
+     if (size(NF(check,primmod,1))>0)
+     {
+       if((act[2][1]==1)&&(vdim(primid)==deg(act[1][1])))
+       {
+         primary = primary+list(list(primmod,primid,primid));
+       }
+       else
+       {
+         primid = primaryTest(primid,act[1][1]);
+         primary = primary+list(list(primmod,primid,ann));
+       }
+       if (size(primid)>0)
+       {
+         check=intersect(check,primmod);
+       }
+     }
+  }
+
+  if (size(primary)==0)
+  {
+    setring BAS;
+    module check=imap(@R,check);
+    kill @R;
+    return(list(), check);
+  }
+
+  ////////////////////////////////////////////////////////////////
+  // the modules which are not primary are splitted
+  ////////////////////////////////////////////////////////////////
+  list splitTemp;
+  int sz=size(primary);
+  @k=1;
+  while (@k<=sz)
+  {
+    if (size(primary[@k][2])==0)
+    {
+      (splitTemp, check)=splitting(primary[@k][1],check,primary[@k][3]);
+      primary = delete(primary, @k)+splitTemp;
+      @k--;sz--;
+    }
+    @k++;
+  }
+
+  setring BAS;
+  list primary=imap(@R,primary);
+  module check=imap(@R,check);
+  kill @R;
+  return(primary,check);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring r=0,z,lp;
+  module N=z*gen(1), (z+1)*gen(2);
+  N=std(N);
+  list l; module check;
+  (l, check)=preComp(N,freemodule(2));
+  l;
+  check;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// indSet(i)
+// based on independendSet from primdec.lib
+/////////////////////////////////////////////////////////////////////////////
+
+proc indSet (ideal @j)
+"USAGE:   indSet(i); i ideal
+RETURN:  list with two entries
+         both are lists of new varstrings with the dependent variables,
+         the independent set, the ordstring with the corresp. block ordering,
+         and the integer where the independent set starts in the varstring
+NOTE:    the first entry gives the strings for all maximal independent sets
+         the second gives the strings for the independent sets,
+         which cannot be enhanced
+EXAMPLE: example indSet; shows an example
+"
+{
+   int n,k,di;
+   int jdim=dim(@j);
+   list maxind, rest,hilf;
+   string var1,var2;
+   list v=indepSet(@j,1);
+
+   for(n=1;n<=size(v);n++)
+   {
+      di=0;
+      var1="";
+      var2="";
+      for(k=1;k<=size(v[n]);k++)
+      {
+         if(v[n][k]!=0)
+         {
+            di++;
+            var2=var2+string(var(k))+",";
+         }
+         else
+         {
+            var1=var1+string(var(k))+",";
+         }
+      }
+      if(di>0)
+      {
+         var1=var1[1..size(var1)-1];
+         var2=var2[1..size(var2)-1];
+         hilf[1]=var1;
+         hilf[2]=var2;
+         hilf[3]="(C,dp("+string(nvars(basering)-di)+"),dp)";
+         //"lp("+string(nvars(basering)-di)+"),dp("+string(di)+")";
+         hilf[4]=di;
+         if(di==jdim)
+         {
+          maxind=maxind+list(hilf);
+         }
+         else
+         {
+          rest=rest+list(hilf);
+         }
+     }
+      else
+      {
+
+        if(jdim==0)
+         {
+          maxind=maxind+list(varstr(basering),"dummy",ordstr(basering),0);
+         }
+         else
+         {
+          rest=rest+list(varstr(basering),"dummy",ordstr(basering),0);
+         }
+         resu[n]=varstr(basering),ordstr(basering),0;
+      }
+   }
+   return(list(maxind,rest));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring s1=(0,x,y),(a,b,c,d,e,f,g),lp;
+   ideal i=ea-fbg,fa+be,ec-fdg,fc+de;
+   i=std(i);
+   list  l=indSet(i);
+   l;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// GTZopt(N[,check[, ann]])
+// a faster version of GTZMod
+/////////////////////////////////////////////////////////////////////////////
+
+proc GTZopt (module @N, list #)
+"USAGE:   GTZopt (N[, check]); module N[, module check]
+RETURN:  list l
+         the minimal primary decomposition of the module N,
+         computed by a generalized and optimized version of
+         the algorithm of Gianni, Trager and Zacharias
+NOTE:    if the parameter check is given, only components
+         not containing check are computed
+EXAMPLE: example GTZmod; shows an example
+"
+{
+  @N=std(@N);
+  if (size(@N)==0)
+  {
+    return(list(@N,ideal(0)));
+  }
+
+  ////////////////////////////////////////////////////////////////
+  // the module check is needed to compute a minimal decomposition
+  // components containing check are ignored
+  ////////////////////////////////////////////////////////////////
+  ideal ann; module check, @M; int checked;
+  (ann, check, @M, checked)=getData(@N, #);
+  if (checked)
+  {
+    return(list());
+  }
+
+  ////////////////////////////////////////////////////////////////
+  // if ann is zero-dimensional and homogeneous
+  // then it is primary with associated prime maxideal(1)
+  ////////////////////////////////////////////////////////////////
+  if((homog(ann)==1)&&(dim(ann)==0))
+  {
+    return(list(list(@N,maxideal(1))));
+  }
+
+  ////////////////////////////////////////////////////////////////
+  // the not-that-trivial case of ann==0
+  ////////////////////////////////////////////////////////////////
+  def BAS = basering;
+  if(size(ann)==0)      //check, whether ann=0
+  {
+   execute("ring Rloc=("+charstr(basering)+","+varstr(basering)+"),dummy,("+ordstr(basering)+");");
+   module @N=clrSBmod(imap(BAS, @N));
+   module @M=freemodule(nrows(@N));
+   poly @q=prepareSat(@N);
+
+   setring BAS;
+   poly @q=imap(Rloc, @q);
+   list satu=sat(@N, at q);
+
+   if(satu[2]==0)
+   {
+     return(list(list(@N,ideal(0))));
+   }
+   else
+   {
+    check=intersect(check,satu[1]);
+    return(list(list(satu[1],ideal(0)))+GTZopt(@N+(@q^satu[2])*@M,check));
+   }
+  }
+
+  int @k1, @k2, @k3, @k4;   // the indices for nested for/while loops
+  int nVar=nvars(BAS);
+  int Ndim=dim(@N);
+
+  ////////////////////////////////////////////////////////////////
+  // Simplification of the modules using
+  // N=N/(a*x_i+b)*M+(a*x_i+b)*M, for (a*x_i+b) in ann
+  ////////////////////////////////////////////////////////////////
+  if (size(#)==0)
+  {
+    ideal fried;
+    @k2=size(ann);
+    for(@k1=1;@k1<=@k2;@k1++)
+    {
+      if(deg(lead(ann[@k1]))==1)
+      {
+        fried[size(fried)+1]=ann[@k1];
+      }
+    }
+    if(size(fried)==nVar)
+    {
+       return(list(list(@N, ann)));
+    }
+    if(size(fried)>0)
+    {
+       string newva;
+       string newma;
+       for(@k1=1;@k1<=nVar;@k1++)
+       {
+          checked=0;
+          for(@k2=1;@k2<=size(fried);@k2++)
+          {
+             if(leadmonom(fried[@k2])==var(@k1))
+             {
+                checked=1;
+                break;
+             }
+          }
+          if(checked==0)
+          {
+            newva=newva+string(var(@k1))+",";
+            newma=newma+string(var(@k1))+",";
+          }
+          else
+          {
+            newma=newma+string(var(@k1)-((1/leadcoef(fried[@k2]))*fried[@k2]))+",";
+          }
+       }
+       newva[size(newva)]=")";
+       newma[size(newma)]=";";
+       execute("ring @deirf=("+charstr(BAS)+"),("+newva+",(C,lp);");
+       execute("map @kappa=BAS,"+newma);
+       ideal @j = @kappa(ann);
+       module @N = @kappa(@N);
+       @N=simplify(@N,2);
+       @j=simplify(@j,2);
+       list pr=GTZopt(@N,freemodule(nrows(@N)), at j);
+       setring BAS;
+       list pr=imap(@deirf,pr);
+
+       for(@k1=1;@k1<=size(pr);@k1++)
+       {
+         pr[@k1][1]=std(pr[@k1][1]+fried*@M);
+         pr[@k1][2]=std(pr[@k1][2]+fried);
+       }
+       return(pr);
+    }
+  }
+
+  ////////////////////////////////////////////////////////////////
+  // the trivial case
+  ////////////////////////////////////////////////////////////////
+  if(Ndim==-1)
+  {
+    return(list(list(@N,ideal(1))));
+  }
+
+  ////////////////////////////////////////////////////////////////
+  // the case of one variable
+  ////////////////////////////////////////////////////////////////
+  if(nVar==1)
+  {
+    return(dec1var(@N));
+  }
+
+  ////////////////////////////////////////////////////////////////
+  // the zerodimensional case
+  ////////////////////////////////////////////////////////////////
+  if (Ndim==0)
+  {
+    return(zeroOpt(@N, check, ann));
+  }
+
+  ////////////////////////////////////////////////////////////////
+  // the preparation of the quotient ring
+  ////////////////////////////////////////////////////////////////
+  list result;
+  list indep =indSet(ann);
+  poly @q;
+  list @p,primary;
+  ideal @h;
+  int szIndep;
+  for (@k1=1;@k1<=2;@k1++)
+  {
+    szIndep=size(indep[@k1]);
+    for (@k2=1;@k2<=szIndep;@k2++)
+    {
+      execute("ring RAU=("+charstr(basering)+"),("+indep[@k1][@k2][1]+","+indep[@k1][@k2][2]+"),"+indep[@k1][@k2][3]+";");
+      module @N=std(imap(BAS, at N)); // the standard basis in (R[U])[A]
+      execute("ring Rloc=("+charstr(basering)+","+indep[@k1][@k2][2]+"),("+indep[@k1][@k2][1]+"),(C,dp);");
+      module @N=imap(RAU, at N); //std in lokalisierung
+      @N=clrSBmod(@N);
+      kill RAU;
+
+      ////////////////////////////////////////////////////////////////
+      // the zero-dimensional decomposition
+      ////////////////////////////////////////////////////////////////
+      list qprim, preList;
+      module check=imap(BAS, check);
+      (preList,check)=preComp(@N,check);
+      for (@k3=1; @k3<=size(preList); @k3++)
+      {
+        if(size(preList[@k3][2])>0)
+        {
+          qprim=qprim+list(list(preList[@k3][1],preList[@k3][2]));
+        }
+        else
+        {
+          checked=size(qprim);
+          qprim=qprim+zeroOpt(preList[@k3][1], check, preList[@k3][3]);
+          for(@k4=checked+1;@k4<=size(qprim);@k4++)
+          {
+            check=intersect(check, qprim[@k4][1]);
+          }
+        }
+      }  // end of for(@k3...)
+      kill preList;
+
+      ////////////////////////////////////////////////////////////////
+      // Preparation of the saturation of @N
+      ////////////////////////////////////////////////////////////////
+      //poly pp=prepareSat(@N);
+      ideal @h2;
+      for (@k3=1;@k3<=size(@N);@k3++)
+      {
+        @h2[@k3]=leadcoef(@N[@k3]);
+      }
+
+      if (size(qprim)==0)     // there aren't any new components
+      {
+        setring BAS;
+        check=imap(Rloc,check);
+        @h=imap(Rloc, at h2);
+        @q=minSatMod(imap(BAS, at N), at h)[2];
+        // @q=imap(Rloc,pp)^sat(imap(BAS, at N),imap(Rloc,pp))[2];
+        kill Rloc;
+        if (deg(@q)>0)
+        {
+          @N=std(@N+ at q*@M);
+          ann=std(ideal(ann+ at q));
+          kill qprim;
+        }
+      }
+      else                    // there are new components
+      {
+        ////////////////////////////////////////////////////////////////
+        // Preparation of the saturation of qprim
+        ////////////////////////////////////////////////////////////////
+        list @p2;
+        for (@k3=1;@k3<=size(qprim);@k3++)
+        {
+          @p2[@k3]=list(prepareSat(qprim[@k3][1]),prepareSat(qprim[@k3][2]));
+        }
+
+
+        ////////////////////////////////////////////////////////////////
+        // compute the recontractions
+        // back in the original ring
+        ////////////////////////////////////////////////////////////////
+        setring BAS;
+        @p=imap(Rloc, at p2);
+        primary=imap(Rloc,qprim);
+        @h=imap(Rloc, at h2);
+        kill Rloc;
+        for(@k3=1;@k3<=size(primary);@k3++)
+        {
+          primary[@k3]=list(sat(primary[@k3][1], at p[@k3][1])[1],
+                            sat(primary[@k3][2], at p[@k3][2])[1]);
+          check=intersect(check,primary[@k3][1]);
+        }
+        @q=minSatMod(imap(BAS, at N), at h)[2];
+        result=result+primary;
+        if (deg(@q)>0)
+        {
+          @N=std(@N+ at q*@M);
+          ann=std(ideal(ann+ at q));
+        }
+      }                       // end of else
+      if ((@k1==1)&&(@k2<szIndep)&&(Ndim>dim(ann)))
+      {
+        break;
+      }
+    }
+  }
+  return(result+GTZopt(@N,check,ann));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring r=0,(x,y,z),dp;
+  module N=x*gen(1)+ y*gen(2),
+           x*gen(1)-x2*gen(2);
+  list l=GTZopt(N);
+  l;
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+// dec1var(N[,check[, ann]])
+// primary decompostion for a ring with one variable
+/////////////////////////////////////////////////////////////////////////////
+
+proc dec1var (module @N, list #)
+"USAGE:   dec1var (N); zero-dimensional module N[, module check]
+RETURN:  list l
+         the minimal primary decomposition of a submodule N of R^s
+         if nvars(R)=1
+NOTE:    if the parameter check is given, only components not containing check are computed
+EXAMPLE: example zeroMod; shows an example
+"
+{
+  ideal ann; module @M, check; int checked;
+  (ann, check, @M, checked)=getData(@N, #);
+
+  list fac = factorize(ann[1],2);
+  if(size(fac[2])==1)
+  {
+   return(list(list(@N,ann)));
+  }
+  // comp of the primary modules, the primary ideals and the primes
+  poly @h;
+  module primod;
+  list result;
+  int @k;
+  for (@k=1;@k<=size(fac[1]);@k++)
+  {
+    @h=ann[1]/(fac[1][@k]^fac[2][@k]);
+    result =result+list(list(std(quotient(@N, at h)), std(ann,fac[1][@k])));
+  }
+    return(result);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring r=0,z,dp;
+  module N=z*gen(1),(z-1)*gen(2),(z+1)*gen(3);
+  list l=dec1var(N);
+  l;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// zeroOpt(N[,check[, ann]])
+// a faster version of zeroMod
+/////////////////////////////////////////////////////////////////////////////
+
+proc zeroOpt (module @N, list #)
+"USAGE:   zeroOpt (N[, check]); zero-dimensional module N[, module check]
+RETURN:  list l
+         the minimal primary decomposition of a zero-dimensional module N,
+         computed by a generalized and optimized version of the algorithm
+         of Gianni, Trager and Zacharias
+NOTE:    if the parameter check is given, only components
+         not containing check are computed
+EXAMPLE: example zeroMod; shows an example
+"
+{
+  @N=interred(@N);
+  attrib(@N,"isSB",1);
+
+  ////////////////////////////////////////////////////////////////
+  // the module check is needed to compute a minimal decomposition
+  // components containing check are ignored
+  ////////////////////////////////////////////////////////////////
+  ideal ann; module @M, check; int checked;
+  (ann, check, @M, checked)=getData(@N, #);
+
+  if (checked)
+  {
+    return(list());
+  }
+  ////////////////////////////////////////////////////////////////
+  // the ordering is changed to lex
+  ////////////////////////////////////////////////////////////////
+  def BAS = basering;
+  def @R=changeord(list(list("C",0:1),list("lp",1:nvars(basering))));
+  setring @R;
+  module @N=std(imap(BAS, at N));
+  module @M=imap(BAS, at M);
+  ideal ann=std(imap(BAS,ann));
+  module check=imap(BAS,check);
+
+  ////////////////////////////////////////////////////////////////
+  if(vdim(ann)==deg(ann[1]))           // if ann ist prime
+  {
+    list fact=factorize(ann[1],2);
+    int k;ideal id;list result;
+    module hilf;
+    for(k=1;k<=size(fact[1]);k++)
+    {
+      id=ann;
+      hilf=std(@N+(fact[1][k]^fact[2][k])*@M);
+      id[1]=fact[1][k];
+      if(size(NF(check,hilf,1))>0)
+      {
+        result=result+list(list(hilf,interred(id)));
+      }
+    }
+    setring BAS;
+    list result=imap(@R, result);
+    kill @R;
+    return(result);
+
+  }
+
+
+  if (homog(ann))                      // if ann is homogeneous
+  {                                    // then radical(ann)=maxideal(1)
+    if(size(NF(check, at N,1))>0)
+    {
+      setring BAS;
+      kill @R;
+      return (list(list(@N,maxideal(1))));
+    }
+    else
+    {
+      setring BAS;
+      kill @R;
+      return(list());
+    }
+  }
+
+  ////////////////////////////////////////////////////////////////
+  // the random coordnate change and its inverse
+  // furthermore the module is simplified using
+  // N=N/(a*x_i+b)+(a*x_i+b)*M, for a*x_i+b in ann
+  ////////////////////////////////////////////////////////////////
+  int nVar=nvars(@R);
+  int @k, @k1;
+  list result, rest;
+  ideal primary, prim;
+  module primmod;
+  ideal fried;
+  intvec optionsVec=option(get);
+  option(redSB);
+  ideal prepMap = randomLast(100);
+  ideal prepInv=maxideal(1);
+  for(@k=1;@k<=size(ann);@k++)
+  {
+    if(deg(lead(ann[@k]))==1)
+    {
+      fried[size(fried)+1]=ann[@k];
+    }
+  }
+  if(size(fried)==nVar)
+  {
+    return(list(list(@N, ann)));
+  }
+  if(size(fried)>0)
+  {
+    for(@k=1;@k<@k1;@k1++)
+    {
+      for(@k1=1;@k1<=size(fried);@k1++)
+      {
+        if(leadmonom(fried[@k1])==var(@k))
+        {
+          prepMap[@k]=var(@k)+((1/leadcoef(fried[@k1]))*(var(@k)-fried[@k1]));
+          prepMap[nVar]=subst(prepMap[nVar],var(@k),0);
+          prepInv[@k]=fried[@k1];
+        }
+      }
+    }
+  }
+  map phi=@R,prepMap;
+  prepInv[nVar]=2*var(nVar)-prepMap[nVar];
+  map invphi=@R,prepInv;
+  ideal @j=std(phi(ann));         // factorization of the 1st elt. in Ann(@N)
+  list fac = factorize(@j[1],2);
+
+  ////////////////////////////////////////////////////////////////
+  // Case: 1st element irreducible
+  ////////////////////////////////////////////////////////////////
+  if(size(fac[2])==1)
+  {
+    prim=primaryTest(@j,fac[1][1]);
+    prim=invphi(prim);
+    setring BAS;
+    @N=std(@N);
+    ideal prim =imap(@R,prim);
+    kill @R;
+    if(prim!=0)
+    {
+      return(list(list(@N,prim)));
+    }
+    else
+    {
+      return(zeroOpt(@N,check));
+    }
+  }
+
+  ////////////////////////////////////////////////////////////////
+  // Computation of the - hopefully primary - modules
+  // their annihilators and associated primes
+  ////////////////////////////////////////////////////////////////
+  poly @p, @h;
+  for (@k=1;@k<=size(fac[1]);@k++)
+  {
+    @p=fac[1][@k]^fac[2][@k];
+    @h=@j[1]/@p;
+    primmod=std(quotient(phi(@N), at h));
+    check=phi(check);
+    if (size(NF(check,primmod,1))>0)
+    {
+      primary=std(@j+ at p);
+      // test if the modules were primary and in general position
+      prim=primTest(primary,fac[1][@k]);
+      if(size(prim)==0)
+      {
+        prim=primaryTest(primary,fac[1][@k]);
+      }
+      if (prim==0)
+      {
+        rest[size(rest)+1]=invphi(primmod);
+      }
+      else
+      {
+        result[size(result)+1]=list(std(invphi(primmod)),std(invphi(prim)));
+      }
+    }
+  }
+
+  ////////////////////////////////////////////////////////////////
+  // the bad cases
+  ////////////////////////////////////////////////////////////////
+  for (@k=1; @k<=size(rest);@k++)
+  {
+    result = result+zeroOpt(rest[@k],check);
+  }
+  option (set,optionsVec);
+  if(size(result)==0)
+  {
+    setring BAS;
+    kill @R;
+    return(list());
+  }
+  setring BAS;
+  list result=imap(@R, result);
+  kill @R;
+
+  return(result);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring r=0,z,dp;
+  module N=z*gen(1),(z-1)*gen(2),(z+1)*gen(3);
+  list l=zeroOpt(N);
+  l;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// clrSBmod(N)
+// Generalization of clearSB from primdec.lib
+/////////////////////////////////////////////////////////////////////////////
+
+static proc clrSBmod (module @N)
+"USAGE:   clrSBmod(N); N module which is SB ordered by monomial ordering
+RETURN:  module = minimal SB
+EXAMPLE: example clrSBmod; shows an example
+"
+{
+  int @k, at j;
+  list Nsizes;
+  for (@k=1;@k<=size(@N);@k++)
+  {
+    Nsizes[@k]=size(@N[@k]);
+  }
+  module leadVec;
+  int szN=size(@N);
+  @j=0;
+  while(@j<szN-1)
+  {
+    @j++;
+    if(deg(@N[@j])>0)
+    {
+      leadVec=lead(@N[@j]);
+      attrib(leadVec,"isSB",1);
+      for(@k=@j+1;@k<=szN;@k++)
+      {
+        if(size(NF(lead(@N[@k]),leadVec,1))==0)
+        {
+          if((leadexp(leadVec[1])!=leadexp(@N[@k]))||(Nsizes[@j]<=Nsizes[@k]))
+          {
+            @N[@k]=0;
+          }
+          else
+          {
+            @N[@j]=0;
+             break;
+          }
+        }
+      }
+    }
+  }
+  return(simplify(@N,2));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring  r = (0,a,b),(x,y,z),dp;
+   module N1=ax2+y,a2x+y,bx;
+   module N2=clrSBmod(N1);
+   N2;
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+// minSatMod(N, id)
+// Generalization of minsat from primdec.lib
+/////////////////////////////////////////////////////////////////////////////
+
+static proc minSatMod(module Nnew, ideal @h)
+"USAGE:   minSatMod(N, I); module N, ideal I
+RETURN:  list with 2 elements:
+         [1]=sat(N,product(I))[1],
+         [2]=p, the polynomial of minimal degree s.th. [1]=quotient(N,p)
+EXAMPLE: example minSatMod; shows an example
+"
+{
+   int @i, at k;
+   poly @f=1;
+   module Nold;
+   ideal fac;
+   list quotM, at l;
+
+   for(@i=1;@i<=ncols(@h);@i++)
+   {
+      if(deg(@h[@i])>0)
+      {
+         fac=fac+factorize(@h[@i],1);
+      }
+   }
+   fac=simplify(fac,4);
+   if(size(fac)==0)
+   {
+      @l=Nnew,1;
+      return(@l);
+   }
+   fac=sort(fac)[1];
+   for(@i=1;@i<=size(fac);@i++)
+   {
+      @f=@f*fac[@i];
+   }
+   quotM[1]=Nnew;
+   quotM[2]=fac;
+   quotM[3]=@f;
+   @f=1;
+   while(specialModulesEqual(Nold,quotM[1])==0)
+   {
+      if(@k>0)
+      {
+         @f=@f*quotM[3];
+      }
+      Nold=quotM[1];
+      quotM=quotMinMod(quotM);
+      @k++;
+   }
+   @l=quotM[1], at f;
+   return(@l);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring  r = 0,(x,y,z),dp;
+   module N=xy*gen(1);
+   ideal h=yz,z2;
+   list l=minSatMod(N,h);
+   l;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// quotMinMod(N, fac, f)
+// Generalization of quotMin from primdec.lib
+/////////////////////////////////////////////////////////////////////////////
+
+proc quotMinMod(list tsil)
+{
+   int @i, at j,action;
+   module verg;
+   list @l;
+   poly @g;
+   intvec optionsVec;
+
+   module laedi=tsil[1];
+   ideal fac=tsil[2];
+   poly @f=tsil[3];
+   optionsVec=option(get);
+   option(returnSB);
+   module star=quotient(laedi, at f);
+   option(set,optionsVec);
+   if(specialModulesEqual(star,laedi))
+   {
+      @l=star,fac, at f;
+      return(@l);
+   }
+
+   action=1;
+   while(action==1)
+   {
+      if(size(fac)==1)
+      {
+         action=0;
+         break;
+      }
+      for(@i=1;@i<=size(fac);@i++)
+      {
+        @g=1;
+        verg=laedi;
+
+         for(@j=1;@j<=size(fac);@j++)
+         {
+            if(@i!=@j)
+            {
+               @g=@g*fac[@j];
+            }
+         }
+         optionsVec=option(get);
+         option(returnSB);
+         verg=quotient(laedi, at g);
+         option(set,optionsVec);
+         if(specialModulesEqual(verg,star)==1)
+         {
+            @f=@g;
+            fac[@i]=0;
+            fac=simplify(fac,2);
+            break;
+         }
+
+         if(@i==size(fac))
+         {
+            action=0;
+         }
+      }
+   }
+   @l=star,fac, at f;
+   return(@l);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// specialModulesEqual(N1,N2)
+// Generalization of specialIdealsEqual from primdec.lib
+/////////////////////////////////////////////////////////////////////////////
+
+static proc specialModulesEqual( module k1, module k2)
+"USAGE:   specialModulesEqual(N1, N2) N1, N2 standard bases of modules,
+         s.th. N1 is contained in N2 or vice versa
+RETURN:  int i
+         if (N1==N2) then i=1
+         else i=0
+EXAMPLE: example specialModulesEqual; shows an example
+"
+{
+   int @j;
+
+   if(size(k1)==size(k2))
+   {
+      for(@j=1;@j<=size(k1);@j++)
+      {
+         if(leadexp(k1[@j])!=leadexp(k2[@j]))
+         {
+            return(0);
+         }
+      }
+      return(1);
+   }
+   return(0);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring  r = 0,(x,y,z),dp;
+   module N1=x*freemodule(2);
+   module N2=xy*freemodule(2);
+   int i=specialModulesEqual(N1,N2);
+   i;
+
+   N2=N1;
+   i=specialModulesEqual(N1,N2);
+   i;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// sat2mod(N,i)
+// Generalization of sat2 from primdec.lib
+/////////////////////////////////////////////////////////////////////////////
+
+proc sat2mod (module id, ideal h1)
+"USAGE:   sat2mod(id,j);  id ideal, j polynomial
+RETURN:  saturation of id with respect to j (= union_(k=1...) of id:j^k)
+NOTE:    result is a std basis in the basering
+"
+{
+   int @k, at i;
+   def @P= basering;
+   if(ordstr(basering)[1,2]!="dp")
+   {
+      execute("ring @Phelp=("+charstr(@P)+"),("+varstr(@P)+"),(C,dp);");
+      module inew=std(imap(@P,id));
+      ideal  @h=imap(@P,h1);
+   }
+   else
+   {
+      ideal @h=h1;
+      module inew=std(id);
+   }
+   ideal fac;
+
+   for(@i=1;@i<=ncols(@h);@i++)
+   {
+     if(deg(@h[@i])>0)
+     {
+        fac=fac+factorize(@h[@i],1);
+     }
+   }
+   fac=simplify(fac,4);
+   poly @f=1;
+   if(deg(fac[1])>0)
+   {
+      module iold;
+
+      for(@i=1;@i<=size(fac);@i++)
+      {
+        @f=@f*fac[@i];
+      }
+      intvec optionsVec=option(get)
+      option(returnSB);
+      while(specialModulesEqual(iold,inew)==0 )
+      {
+         iold=inew;
+         if(deg(iold[size(iold)])!=1)
+         {
+            inew=quotient(iold, at f);
+         }
+         else
+         {
+            inew=iold;
+         }
+         @k++;
+      }
+      option(set,optionsVec);
+      @k--;
+   }
+
+   if(ordstr(@P)[1,2]!="dp")
+   {
+      setring @P;
+      module inew=std(imap(@Phelp,inew));
+      poly @f=imap(@Phelp, at f);
+   }
+   list L =inew, at f^@k;
+   return (L);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// stdModulesEqual(N1,N2)
+// Generalization of stdIdealsEqual from primdec.lib
+/////////////////////////////////////////////////////////////////////////////
+
+static proc stdModulesEqual(module k1, module k2)
+"USAGE:   stdModulesEqual(N1, N2) N1, N2 standard bases of modules,
+RETURN:  int i
+         if (N1==N2) then i=1
+         else i=0
+EXAMPLE: example stdModulesEqual; shows an example
+"
+{
+   int @j;
+
+   if(size(k1)==size(k2))
+   {
+      for(@j=1;@j<=size(k1);@j++)
+      {
+         if(leadexp(k1[@j])!=leadexp(k2[@j]))
+         {
+            return(0);
+         }
+      }
+      attrib(k2,"isSB",1);
+      if(size(reduce(k1,k2,1))==0)
+      {
+         return(1);
+      }
+   }
+   return(0);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring  r = 0,(x,y,z),dp;
+   module N1=x*freemodule(2);
+   module N2=xy*freemodule(2);
+   int i=stdModulesEqual(N1,N2);
+   i;
+
+   N2=N1;
+   i=stdModulesEqual(N1,N2);
+   i;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// ModulesEqual(N1,N2)
+// Generalization of IdealsEqual from primdec.lib
+/////////////////////////////////////////////////////////////////////////////
+
+static proc modulesEqual( module @k, module @j)
+"USAGE:   modulesEqual(N1, N2) N1, N2 modules,
+RETURN:  int i
+         if (N1==N2) then i=1
+         else i=0
+EXAMPLE: example modulesEqual; shows an example
+"
+{
+   return(stdModulesEqual(std(@k),std(@j)));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring  r = 0,(x,y,z),dp;
+   module N1=x*freemodule(2);
+   module N2=xy*freemodule(2);
+   int i=stdModulesEqual(N1,N2);
+   i;
+
+   N2=N1;
+   i=modulesEqual(N1,N2);
+   i;
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring  r = 0,(x,y,z),dp;
+   module N1=x*freemodule(2);
+   module N2=xy*freemodule(2);
+   int i=modulesEqual(N1,N2);
+   i;
+
+   N2=N1;
+   i=modulesEqual(N1,N2);
+   i;
+}
+
+static proc getData (module @N, list oldData, list #)
+"USAGE:   getData(N, l[, noCheck]);  module N, list l[, int noCheck]
+RETURN:  (ann, check, M, checked)
+         ideal ann, module check, M, int checked
+
+         if l[1] is contained in N [and noCheck is not given]
+            then checked=1, ann=ideal(0), check=0, M=0;
+         else checked=0, M=freemodule(nrows(N)); check=l[1]
+            (resp. check=M if l is an empty list) and
+            if size(l)>1 then  ann=l[2] else ann is the annihilator of M/N.
+
+NOTE:    ann is a std basis in the basering
+EXAMPLE: example getData; shows an example
+"
+{
+  if (size(oldData)>0)
+  {
+    if ((size(#)==0)&&(size(NF(oldData[1], at N,1))==0))
+    {
+      return(ideal(0), 0 ,  0, 1);
+    }
+    module @M=freemodule(nrows(@N));
+    if (size(oldData)>1)
+    {
+      ideal ann=oldData[2];
+      attrib(ann,"isSB",1);
+    }
+    else
+    {
+      ideal ann=annil(@N);
+    }
+  }
+  else
+  {
+   module @M=freemodule(nrows(@N));
+   oldData[1]=@M;
+   ideal ann=annil(@N);
+  }
+ return(ann, oldData[1], @M, 0);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring  r = 0,(x,y,z),lp;
+   module N=x*gen(1),y*gen(2);
+   N=std(N);
+   ideal ann; module check, M; int checked; list l;
+   (ann, check, M, checked)=getData(N,l);
+   ann; check; M; checked;
+
+   l=list(check,ann);
+   (ann, check, M, checked)=getData(N,l);
+   ann; check; M; checked;
+
+   l=list(N);
+   (ann, check, M, checked)=getData(N,l);
+   ann; check; M; checked;
+}
diff --git a/Singular/LIB/mregular.lib b/Singular/LIB/mregular.lib
new file mode 100644
index 0000000..94e9a7e
--- /dev/null
+++ b/Singular/LIB/mregular.lib
@@ -0,0 +1,1778 @@
+//////////////////////////////////////////////////////////////////////////////
+version="version mregular.lib 4.0.0.0 Jun_2013 "; // $Id: 65c9ff28baa31013620d93b4f3033bcb6d5632ad $
+category="Commutative Algebra";
+info="
+LIBRARY: mregular.lib   Castelnuovo-Mumford regularity of homogeneous ideals
+AUTHORS: I.Bermejo,     ibermejo at ull.es
+@*       Ph.Gimenez,    pgimenez at agt.uva.es
+@*       G.-M.Greuel,   greuel at mathematik.uni-kl.de
+
+OVERVIEW:
+ A library for computing the Castelnuovo-Mumford regularity of a homogeneous
+ ideal that DOES NOT require the computation of a minimal graded free
+ resolution of the ideal.
+ It also determines depth(basering/ideal) and satiety(ideal).
+ The procedures are based on 3 papers by Isabel Bermejo and Philippe Gimenez:
+ 'On Castelnuovo-Mumford regularity of projective curves' Proc.Amer.Math.Soc.
+ 128(5) (2000), 'Computing the Castelnuovo-Mumford regularity of some
+ subschemes of Pn using quotients of monomial ideals', Proceedings of
+ MEGA-2000, J. Pure Appl. Algebra 164 (2001), and 'Saturation and
+ Castelnuovo-Mumford regularity', Preprint (2004).
+
+PROCEDURES:
+ regIdeal(id,[,e]);    regularity of homogeneous ideal id
+ depthIdeal(id,[,e]);  depth of S/id with S=basering, id homogeneous ideal
+ satiety(id,[,e]);     saturation index of homogeneous ideal id
+ regMonCurve(li);      regularity of projective monomial curve defined by li
+ NoetherPosition(id);  Noether normalization of ideal id
+ is_NP(id);            checks whether variables are in Noether position
+ is_nested(id);        checks whether monomial ideal id is of nested type
+";
+
+LIB "general.lib";
+LIB "algebra.lib";
+LIB "sing.lib";
+LIB "poly.lib";
+//////////////////////////////////////////////////////////////////////////////
+//
+proc regIdeal (ideal i, list #)
+"
+USAGE:   regIdeal (i[,e]); i ideal, e integer
+RETURN:  an integer, the Castelnuovo-Mumford regularity of i.
+         (returns -1 if i is not homogeneous)
+ASSUME:  i is a homogeneous ideal of the basering S=K[x(0)..x(n)].
+         e=0:  (default)
+               If K is an infinite field, makes random changes of coordinates.
+               If K is a finite field, works over a transcendental extension.
+         e=1:  Makes random changes of coordinates even when K is finite.
+               It works if it terminates, but may result in an infinite
+               loop. After 30 loops, a warning message is displayed and
+               -1 is returned.
+NOTE:    If printlevel > 0 (default = 0), additional info is displayed:
+         dim(S/i), depth(S/i) and end(H^(depth(S/i))(S/i)) are computed,
+         and an upper bound for the a-invariant of S/i is given.
+         The algorithm also determines whether the regularity is attained
+         or not at the last step of a minimal graded free resolution of i,
+         and if the answer is positive, the regularity of the Hilbert
+         function of S/i is given.
+EXAMPLE: example regIdeal; shows some examples
+"
+{
+//--------------------------- initialisation ---------------------------------
+   int e,ii,jj,H,h,d,time,lastv,sat,firstind;
+   int lastind,ch,nesttest,NPtest,nl,N,acc;
+   intmat ran;
+   def r0 = basering;
+   int n = nvars(r0)-1;
+   if ( size(#) > 0 )
+   {
+      e = #[1];
+   }
+   string s = "ring r1 = ",charstr(r0),",x(0..n),dp;";
+   execute(s);
+   ideal i,sbi,I,J,K,chcoord,m;
+   poly P;
+   map phi;
+   i = fetch(r0,i);
+   time=rtimer;
+   sbi=std(i);
+   ch=char(r1);
+//----- Check ideal homogeneous
+   if ( homog(sbi) == 0 )
+   {
+       "// WARNING from proc regIdeal from lib mregular.lib:
+// The ideal is not homogeneous!";
+       return (-1);
+   }
+   I=simplify(lead(sbi),1);
+   attrib(I,"isSB",1);
+   d=dim(I);
+//----- If the ideal i is not proper:
+   if ( d == -1 )
+   {
+     dbprint(printlevel-voice+2,
+             "// The ideal i is (1)!
+// Its Castelnuovo-Mumford regularity is:");
+     return (0);
+   }
+//----- If the ideal i is 0:
+   if ( size(I) == 0 )
+   {
+     dbprint(printlevel-voice+2,
+             "// The ideal i is (0)!
+// Its Castelnuovo-Mumford regularity is:");
+     return (0);
+   }
+//----- When the ideal i is 0-dimensional:
+   if ( d == 0 )
+   {
+     H=maxdeg1(minbase(quotient(I,maxideal(1))))+1;
+     time=rtimer-time;
+     // Additional information:
+     dbprint(printlevel-voice+2,
+             "// Dimension of S/i : 0");
+     dbprint(printlevel-voice+2,
+             "// Time for computing regularity: " + string(time) + " sec.");
+     dbprint(printlevel-voice+2,
+"// The Castelnuovo-Mumford regularity of i coincides with its satiety, and
+ // with the regularity of the Hilbert function of S/i. Its value is:");
+     return (H);
+   }
+//----- Determine the situation: NT, or NP, or nothing.
+//----- Choose the method depending on the situation, on the
+//----- characteristic of the ground field, and on the option argument
+//----- in order to get the mon. ideal of nested type associated to i
+   if ( e == 1 )
+   { ch=0; }
+   NPtest=is_NP(I);
+   if ( NPtest == 1 )
+   {
+     nesttest=is_nested(I);
+   }
+   if ( ch != 0 )
+   {
+     if ( NPtest == 0 )
+     {
+       N=d*n-d*(d-1)/2;
+       s = "ring rtr = (ch,t(1..N)),x(0..n),dp;";
+       execute(s);
+       ideal chcoord,m,i,I;
+       poly P;
+       map phi;
+       i=imap(r1,i);
+       chcoord=select1(maxideal(1),1..(n-d+1));
+       acc=0;
+       for ( ii = 1; ii<=d; ii++ )
+       {
+         matrix trex[1][n-d+ii+1]=t((1+acc)..(n-d+ii+acc)),1;
+         m=select1(maxideal(1),1..(n-d+1+ii));
+         for ( jj = 1; jj<=n-d+ii+1; jj++ )
+         {
+           P=P+trex[1,jj]*m[jj];
+         }
+         chcoord[n-d+1+ii]=P;
+         P=0;
+         acc=acc+n-d+ii;
+         kill trex;
+       }
+       phi=rtr,chcoord;
+       I=simplify(lead(std(phi(i))),1);
+       setring r1;
+       I=imap(rtr,I);
+       attrib(I,"isSB",1);
+     }
+     else
+     {
+       if ( nesttest == 0 )
+       {
+         N=d*(d-1)/2;
+         s = "ring rtr = (ch,t(1..N)),x(0..n),dp;";
+         execute(s);
+         ideal chcoord,m,i,I;
+         poly P;
+         map phi;
+         i=imap(r1,i);
+         chcoord=select1(maxideal(1),1..(n-d+2));
+         acc=0;
+         for ( ii = 1; ii<=d-1; ii++ )
+         {
+           matrix trex[1][ii+1]=t((1+acc)..(ii+acc)),1;
+           m=select1(maxideal(1),(n-d+2)..(n-d+2+ii));
+           for ( jj = 1; jj<=ii+1; jj++ )
+           {
+             P=P+trex[1,jj]*m[jj];
+           }
+           chcoord[n-d+2+ii]=P;
+           P=0;
+           acc=acc+ii;
+           kill trex;
+         }
+         phi=rtr,chcoord;
+         I=simplify(lead(std(phi(i))),1);
+         setring r1;
+         I=imap(rtr,I);
+         attrib(I,"isSB",1);
+       }
+     }
+   }
+   else
+   {
+     if ( NPtest == 0 )
+     {
+       while ( nl < 30 )
+       {
+         chcoord=select1(maxideal(1),1..(n-d+1));
+         nl=nl+1;
+         for ( ii = 1; ii<=d; ii++ )
+         {
+           ran=random(100,1,n-d+ii);
+           ran=intmat(ran,1,n-d+ii+1);
+           ran[1,n-d+ii+1]=1;
+           m=select1(maxideal(1),1..(n-d+1+ii));
+           for ( jj = 1; jj<=n-d+ii+1; jj++ )
+           {
+             P=P+ran[1,jj]*m[jj];
+           }
+           chcoord[n-d+1+ii]=P;
+           P=0;
+         }
+         phi=r1,chcoord;
+         dbprint(printlevel-voice+2,"// (1 random change of coord.)");
+         I=simplify(lead(std(phi(i))),1);
+         attrib(I,"isSB",1);
+         NPtest=is_NP(I);
+         if ( NPtest == 1 )
+         {
+           break;
+         }
+       }
+       if ( NPtest == 0 )
+       {
+       "// WARNING from proc regIdeal from lib mregular.lib:
+// The procedure has entered in 30 loops and could not put the variables
+// in Noether position: in your example the method using random changes
+// of coordinates may enter an infinite loop when the field is finite.
+// Try removing this optional argument.";
+         return (-1);
+       }
+       i=phi(i);
+       nesttest=is_nested(I);
+     }
+     if ( nesttest == 0 )
+     {
+       while ( nl < 30 )
+       {
+         chcoord=select1(maxideal(1),1..(n-d+2));
+         nl=nl+1;
+         for ( ii = 1; ii<=d-1; ii++ )
+         {
+           ran=random(100,1,ii);
+           ran=intmat(ran,1,ii+1);
+           ran[1,ii+1]=1;
+           m=select1(maxideal(1),(n-d+2)..(n-d+2+ii));
+           for ( jj = 1; jj<=ii+1; jj++ )
+           {
+             P=P+ran[1,jj]*m[jj];
+           }
+           chcoord[n-d+2+ii]=P;
+           P=0;
+         }
+         phi=r1,chcoord;
+         dbprint(printlevel-voice+2,"// (1 random change of coord.)");
+         I=simplify(lead(std(phi(i))),1);
+         attrib(I,"isSB",1);
+         nesttest=is_nested(I);
+         if ( nesttest == 1 )
+         {
+           break;
+         }
+       }
+       if ( nesttest == 0 )
+       {
+       "// WARNING from proc regIdeal from lib mregular.lib:
+// The procedure has entered in 30 loops and could not find a monomial
+// ideal of nested type with the same regularity as your ideal: in your
+// example the method using random changes of coordinates may enter an
+// infinite loop when the field is finite.
+// Try removing this optional argument.";
+         return (-1);
+       }
+     }
+   }
+//
+// At this stage, we have obtained a monomial ideal I of nested type
+// such that reg(i)=reg(I). We now compute reg(I).
+//
+//----- When S/i is Cohen-Macaulay:
+   for ( ii = n-d+2; ii <= n+1; ii++ )
+   {
+     K=K+select(I,ii);
+   }
+   if ( size(K) == 0 )
+   {
+     s="ring nr = ",charstr(r0),",x(0..n-d),dp;";
+     execute(s);
+     ideal I;
+     I = imap(r1,I);
+     H=maxdeg1(minbase(quotient(I,maxideal(1))))+1;
+     time=rtimer-time;
+     // Additional information:
+     dbprint(printlevel-voice+2,
+               "// S/i is Cohen-Macaulay");
+     dbprint(printlevel-voice+2,
+               "// Dimension of S/i ( = depth(S/i) ): "+string(d));
+     dbprint(printlevel-voice+2,
+               "// Regularity attained at the last step of m.g.f.r. of i: YES");
+     dbprint(printlevel-voice+2,
+               "// Regularity of the Hilbert function of S/i: " + string(H-d));
+     dbprint(printlevel-voice+2,
+               "// Time for computing regularity: " + string(time) + " sec.");
+     dbprint(printlevel-voice+2,
+               "// The Castelnuovo-Mumford regularity of i is:");
+     return(H);
+   }
+//----- When d=1:
+   if ( d == 1 )
+   {
+     H=maxdeg1(simplify(reduce(quotient(I,maxideal(1)),I),2))+1;
+     sat=H;
+     J=subst(I,x(n),1);
+     s = "ring nr = ",charstr(r0),",x(0..n-1),dp;";
+     execute(s);
+     ideal J=imap(r1,J);
+     attrib(J,"isSB",1);
+     h=maxdeg1(minbase(quotient(J,maxideal(1))))+1;
+     time=rtimer-time;
+     if ( h > H )
+     {
+       H=h;
+     }
+     // Additional information:
+     dbprint(printlevel-voice+2,
+               "// Dimension of S/i: 1");
+     dbprint(printlevel-voice+2,
+               "// Depth of S/i: 0");
+     dbprint(printlevel-voice+2,
+               "// Satiety of i: "+string(sat));
+     dbprint(printlevel-voice+2,
+               "// Upper bound for the a-invariant of S/i: end(H^1(S/i)) <= "+
+               string(h-2));
+     if ( H == sat )
+     {
+       dbprint(printlevel-voice+2,
+                   "// Regularity attained at the last step of m.g.f.r. of i: YES");
+       dbprint(printlevel-voice+2,
+                   "// Regularity of the Hilbert function of S/i: "+string(H));
+     }
+     else
+     {
+       dbprint(printlevel-voice+2,
+                   "// Regularity attained at the last step of m.g.f.r. of i: NO");
+     }
+     dbprint(printlevel-voice+2,
+                   "// Time for computing regularity: "+ string(time) + " sec.");
+     dbprint(printlevel-voice+2,
+                   "// The Castelnuovo-Mumford regularity of i is:");
+     return(H);
+   }
+//----- Now d>1 and S/i is not Cohen-Macaulay:
+//
+//----- First, determine the last variable really occuring
+   lastv=n-d;
+   h=n;
+   while ( lastv == n-d and h > n-d )
+   {
+     K=select(I,h+1);
+     if ( size(K) == 0 )
+     {
+       h=h-1;
+     }
+     else
+     {
+       lastv=h;
+     }
+   }
+//----- and compute Castelnuovo-Mumford regularity:
+   s = "ring nr = ",charstr(r0),",x(0..lastv),dp;";
+   execute(s);
+   ideal I,K,KK,LL;
+   I=imap(r1,I);
+   attrib(I,"isSB",1);
+   K=simplify(reduce(quotient(I,maxideal(1)),I),2);
+   H=maxdeg1(K)+1;
+   firstind=H;
+   KK=minbase(subst(I,x(lastv),1));
+   for ( ii = n-lastv; ii<=d-2; ii++ )
+   {
+     LL=minbase(subst(I,x(n-ii-1),1));
+     attrib(LL,"isSB",1);
+     s = "ring mr = ",charstr(r0),",x(0..n-ii-1),dp;";
+     execute(s);
+     ideal K,KK;
+     KK=imap(nr,KK);
+     attrib(KK,"isSB",1);
+     K=simplify(reduce(quotient(KK,maxideal(1)),KK),2);
+     h=maxdeg1(K)+1;
+     if ( h > H )
+     {
+       H=h;
+     }
+     setring nr;
+     kill mr;
+     KK=LL;
+   }
+   // We must determine one more sat. index:
+   s = "ring mr = ",charstr(r0),",x(0..n-d),dp;";
+   execute(s);
+   ideal KK,K;
+   KK=imap(nr,KK);
+   attrib(KK,"isSB",1);
+   K=simplify(reduce(quotient(KK,maxideal(1)),KK),2);
+   h=maxdeg1(K)+1;
+   lastind=h;
+   if ( h > H )
+   {
+     H=h;
+   }
+   setring nr;
+   kill mr;
+   time=rtimer-time;
+   // Additional information:
+   dbprint(printlevel-voice+2,
+               "// Dimension of S/i: "+string(d));
+   dbprint(printlevel-voice+2,
+               "// Depth of S/i: "+string(n-lastv));
+   dbprint(printlevel-voice+2,
+               "// end(H^"+string(n-lastv)+"(S/i)) = "
+               +string(firstind-n+lastv-1));
+   dbprint(printlevel-voice+2,
+               "// Upper bound for the a-invariant of S/i: end(H^"
+               +string(d)+"(S/i)) <= "+string(lastind-d-1));
+   if ( H == firstind )
+   {
+     dbprint(printlevel-voice+2,
+                   "// Regularity attained at the last step of m.g.f.r. of i: YES");
+     dbprint(printlevel-voice+2,
+                   "// Regularity of the Hilbert function of S/i: "
+                   +string(H-n+lastv));
+   }
+   else
+   {
+     dbprint(printlevel-voice+2,
+                   "// Regularity attained at the last step of m.g.f.r. of i: NO");
+   }
+   dbprint(printlevel-voice+2,
+               "// Time for computing regularity: "+ string(time) + " sec.");
+   dbprint(printlevel-voice+2,
+               "// The Castelnuovo-Mumford regularity of i is:");
+   return(H);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r=0,(x,y,z,t,w),dp;
+   ideal i=y2t,x2y-x2z+yt2,x2y2,xyztw,x3z2,y5+xz3w-x2zw2,x7-yt2w4;
+   regIdeal(i);
+   regIdeal(lead(std(i)));
+// Additional information is displayed if you change printlevel (=1);
+}
+////////////////////////////////////////////////////////////////////////////////
+/*
+Out-commented examples:
+//
+   ring s=0,x(0..5),dp;
+   ideal i=x(2)^2-x(4)*x(5),x(1)*x(2)-x(0)*x(5),x(0)*x(2)-x(1)*x(4),
+           x(1)^2-x(3)*x(5),x(0)*x(1)-x(2)*x(3),x(0)^2-x(3)*x(4);
+   regIdeal(i);
+   // Our procedure works when a min. graded free resol. can
+   // not be computed. In this easy example, regularity can also
+   // be obtained using a m.g.f.r.:
+   nrows(betti(mres(i,0)));
+   ring r1=0,(x,y,z,t),dp;
+// Ex.2.5 in [Bermejo-Gimenez], Proc.Amer.Math.Soc. 128(5):
+   ideal i  = x17y14-y31, x20y13, x60-y36z24-x20z20t20;
+   regIdeal(i);
+// Ex.2.9 in [Bermejo-Gimenez], Proc.Amer.Math.Soc. 128(5):
+   int k=43;
+   ideal j=x17y14-y31,x20y13,x60-y36z24-x20z20t20,y41*z^k-y40*z^(k+1);
+   regIdeal(j);
+   k=14;
+   j=x17y14-y31,x20y13,x60-y36z24-x20z20t20,y41*z^k-y40*z^(k+1);
+   regIdeal(j);
+   k=22;
+   j=x17y14-y31,x20y13,x60-y36z24-x20z20t20,y41*z^k-y40*z^(k+1);
+   regIdeal(j);
+   k=315;
+   j=x17y14-y31,x20y13,x60-y36z24-x20z20t20,y41*z^k-y40*z^(k+1);
+   regIdeal(j);
+// Example in Rk.2.10 in [Bermejo-Gimenez], ProcAMS 128(5):
+   ideal h=x2-3xy+5xt,xy-3y2+5yt,xz-3yz,2xt-yt,y2-yz-2yt;
+   regIdeal(h);
+// The initial ideal is not saturated
+   regIdeal(lead(std(h)));
+// More examples:
+   i=y4-t3z, x3t-y2z2, x3y2-t2z3, x6-tz5;
+   regIdeal(i);
+//
+   regIdeal(maxideal(4));
+//
+   ring r2=0,(x,y,z,t,w),dp;
+   ideal i = xy-zw,x3-yw2,x2z-y2w,y3-xz2,-y2z3+xw4+tw4+w5,-yz4+x2w3+xtw3+xw4,
+            -z5+x2tw2+x2w3+yw4;
+   regIdeal(i);
+//
+   ring r3=0,(x,y,z,t,w,u),dp;
+   ideal i=imap(r2,i);
+   regIdeal(i);
+// Next example is the defining ideal of the 2nd. Veronesean of P3, a variety
+// in P8 which is arithmetically Cohen-Macaulay:
+   ring r4=0,(a,b,c,d,x(0..9)),dp;
+   ideal i= x(0)-ab,x(1)-ac,x(2)-ad,x(3)-bc,x(4)-bd,x(5)-cd,
+            x(6)-a2,x(7)-b2,x(8)-c2,x(9)-d2;
+   ideal ei=eliminate(i,abcd);
+   ring r5=0,x(0..9),dp;
+   ideal i=imap(r4,ei);
+   regIdeal(i);
+// Here is an example where the computation of a m.g.f.r. of I costs:
+   ring r8=0,(x,y,z,t,u,a,b),dp;
+   ideal i=u-b40,t-a40,x-a23b17,y-a22b18+ab39,z-a25b15;
+   ideal ei=eliminate(i,ab); // It takes a few seconds to compute the ideal
+   ring r9=0,(x,y,z,t,u),dp;
+   ideal i=imap(r8,ei);
+   regIdeal(i);   // This is very fast.
+// Now you can use mres(i,0) to compute a m.g.f.r. of the ideal!
+//
+// The computation of the m.g.f.r. of the following example did not succeed
+// using the command mres:
+   ring r10=0,(x(0..8),s,t),dp;
+   ideal i=x(0)-st24,x(1)-s2t23,x(2)-s3t22,x(3)-s9t16,x(4)-s11t14,x(5)-s18t7,
+           x(6)-s24t,x(7)-t25,x(8)-s25;
+   ideal ei=eliminate(i,st);
+   ring r11=0,x(0..8),dp;
+   ideal i=imap(r10,ei);
+   regIdeal(i);
+// More examples where not even sres works:
+// Be careful: elimination takes some time here, but it succeeds!
+   ring r12=0,(s,t,u,x(0..14)),dp;
+   ideal i=x(0)-st6u8,x(1)-s5t3u7,x(2)-t11u4,x(3)-s9t4u2,x(4)-s2t7u6,x(5)-s7t7u,
+           x(6)-s10t5,x(7)-s4t6u5,x(8)-s13tu,x(9)-s14u,x(10)-st2u12,x(11)-s3t9u3,
+           x(12)-s15,x(13)-t15,x(14)-u15;
+   ideal ei=eliminate(i,stu);
+   size(ei);
+   ring r13=0,x(0..14),dp;
+   ideal i=imap(r12,ei);
+   size(i);
+   regIdeal(i);
+*/
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+
+proc depthIdeal (ideal i, list #)
+"
+USAGE:   depthIdeal (i[,e]); i ideal, e integer
+RETURN:  an integer, the depth of S/i where S=K[x(0)..x(n)] is the basering.
+         (returns -1 if i is not homogeneous or if i=(1))
+ASSUME:  i is a proper homogeneous ideal.
+         e=0:  (default)
+               If K is an infinite field, makes random changes of coordinates.
+               If K is a finite field, works over a transcendental extension.
+         e=1:  Makes random changes of coordinates even when K is finite.
+               It works if it terminates, but may result in an infinite
+               loop. After 30 loops, a warning message is displayed and
+               -1 is returned.
+NOTE:    If printlevel > 0 (default = 0), dim(S/i) is also displayed.
+EXAMPLE: example depthIdeal; shows some examples
+"
+{
+//--------------------------- initialisation ---------------------------------
+   int e,ii,jj,h,d,time,lastv,ch,nesttest,NPtest,nl,N,acc;
+   intmat ran;
+   def r0 = basering;
+   int n = nvars(r0)-1;
+   if ( size(#) > 0 )
+   {
+      e = #[1];
+   }
+   string s = "ring r1 = ",charstr(r0),",x(0..n),dp;";
+   execute(s);
+   ideal i,sbi,I,J,K,chcoord,m;
+   poly P;
+   map phi;
+   i = fetch(r0,i);
+   time=rtimer;
+   sbi=std(i);
+   ch=char(r1);
+//----- Check ideal homogeneous
+   if ( homog(sbi) == 0 )
+   {
+       "// WARNING from proc depthIdeal from lib mregular.lib:
+// The ideal is not homogeneous!";
+       return (-1);
+   }
+   I=simplify(lead(sbi),1);
+   attrib(I,"isSB",1);
+   d=dim(I);
+//----- If the ideal i is not proper:
+   if ( d == -1 )
+     {
+       "// WARNING from proc depthIdeal from lib mregular.lib:
+// The ideal i is (1)!";
+       return (-1);
+     }
+//----- If the ideal i is 0:
+   if ( size(I) == 0 )
+     {
+       dbprint(printlevel-voice+2,
+               "// The ideal i is (0)!
+// The depth of S/i is:");
+       return (d);
+     }
+//----- When the ideal i is 0-dimensional:
+   if ( d == 0 )
+     {
+       time=rtimer-time;
+       // Additional information:
+       dbprint(printlevel-voice+2,
+               "// Dimension of S/i : 0 (S/i is Cohen-Macaulay)");
+       dbprint(printlevel-voice+2,
+               "// Time for computing the depth: " + string(time) + " sec.");
+       dbprint(printlevel-voice+2,
+               "// The depth of S/i is:");
+       return (0);
+     }
+//----- Determine the situation: NT, or NP, or nothing.
+//----- Choose the method depending on the situation, on the
+//----- characteristic of the ground field, and on the option argument
+//----- in order to get the mon. ideal of nested type associated to i
+   if ( e == 1 )
+     {
+       ch=0;
+     }
+   NPtest=is_NP(I);
+   if ( NPtest == 1 )
+     {
+       nesttest=is_nested(I);
+     }
+   if ( ch != 0 )
+     {
+       if ( NPtest == 0 )
+         {
+           N=d*n-d*(d-1)/2;
+           s = "ring rtr = (ch,t(1..N)),x(0..n),dp;";
+           execute(s);
+           ideal chcoord,m,i,I;
+           poly P;
+           map phi;
+           i=imap(r1,i);
+           chcoord=select1(maxideal(1),1..(n-d+1));
+           acc=0;
+           for ( ii = 1; ii<=d; ii++ )
+             {
+               matrix trex[1][n-d+ii+1]=t((1+acc)..(n-d+ii+acc)),1;
+               m=select1(maxideal(1),1..(n-d+1+ii));
+               for ( jj = 1; jj<=n-d+ii+1; jj++ )
+                 {
+                   P=P+trex[1,jj]*m[jj];
+                 }
+               chcoord[n-d+1+ii]=P;
+               P=0;
+               acc=acc+n-d+ii;
+               kill trex;
+             }
+               phi=rtr,chcoord;
+               I=simplify(lead(std(phi(i))),1);
+               setring r1;
+               I=imap(rtr,I);
+               attrib(I,"isSB",1);
+         }
+       else
+         {
+           if ( nesttest == 0 )
+             {
+               N=d*(d-1)/2;
+               s = "ring rtr = (ch,t(1..N)),x(0..n),dp;";
+               execute(s);
+               ideal chcoord,m,i,I;
+               poly P;
+               map phi;
+               i=imap(r1,i);
+               chcoord=select1(maxideal(1),1..(n-d+2));
+               acc=0;
+               for ( ii = 1; ii<=d-1; ii++ )
+                 {
+                   matrix trex[1][ii+1]=t((1+acc)..(ii+acc)),1;
+                    m=select1(maxideal(1),(n-d+2)..(n-d+2+ii));
+                   for ( jj = 1; jj<=ii+1; jj++ )
+                     {
+                       P=P+trex[1,jj]*m[jj];
+                     }
+                   chcoord[n-d+2+ii]=P;
+                   P=0;
+                   acc=acc+ii;
+                   kill trex;
+                 }
+               phi=rtr,chcoord;
+               I=simplify(lead(std(phi(i))),1);
+               setring r1;
+               I=imap(rtr,I);
+               attrib(I,"isSB",1);
+             }
+         }
+     }
+   else
+     {
+       if ( NPtest == 0 )
+         {
+           while ( nl < 30 )
+             {
+               chcoord=select1(maxideal(1),1..(n-d+1));
+               nl=nl+1;
+               for ( ii = 1; ii<=d; ii++ )
+                 {
+                   ran=random(100,1,n-d+ii);
+                   ran=intmat(ran,1,n-d+ii+1);
+                   ran[1,n-d+ii+1]=1;
+                   m=select1(maxideal(1),1..(n-d+1+ii));
+                   for ( jj = 1; jj<=n-d+ii+1; jj++ )
+                     {
+                       P=P+ran[1,jj]*m[jj];
+                     }
+                   chcoord[n-d+1+ii]=P;
+                   P=0;
+                 }
+               phi=r1,chcoord;
+               dbprint(printlevel-voice+2,"// (1 random change of coord.)");
+               I=simplify(lead(std(phi(i))),1);
+               attrib(I,"isSB",1);
+               NPtest=is_NP(I);
+               if ( NPtest == 1 )
+                 {
+                   break;
+                 }
+             }
+           if ( NPtest == 0 )
+             {
+       "// WARNING from proc depthIdeal from lib mregular.lib:
+// The procedure has entered in 30 loops and could not put the variables
+// in Noether position: in your example the method using random changes
+// of coordinates may enter an infinite loop when the field is finite.
+// Try removing this optional argument.";
+       return (-1);
+             }
+           i=phi(i);
+           nesttest=is_nested(I);
+         }
+       if ( nesttest == 0 )
+         {
+           while ( nl < 30 )
+             {
+               chcoord=select1(maxideal(1),1..(n-d+2));
+               nl=nl+1;
+               for ( ii = 1; ii<=d-1; ii++ )
+                 {
+                   ran=random(100,1,ii);
+                   ran=intmat(ran,1,ii+1);
+                   ran[1,ii+1]=1;
+                   m=select1(maxideal(1),(n-d+2)..(n-d+2+ii));
+                   for ( jj = 1; jj<=ii+1; jj++ )
+                     {
+                       P=P+ran[1,jj]*m[jj];
+                     }
+                   chcoord[n-d+2+ii]=P;
+                   P=0;
+                 }
+               phi=r1,chcoord;
+               dbprint(printlevel-voice+2,"// (1 random change of coord.)");
+               I=simplify(lead(std(phi(i))),1);
+               attrib(I,"isSB",1);
+               nesttest=is_nested(I);
+               if ( nesttest == 1 )
+                 {
+                   break;
+                 }
+             }
+           if ( nesttest == 0 )
+             {
+       "// WARNING from proc depthIdeal from lib mregular.lib:
+// The procedure has entered in 30 loops and could not find a monomial
+// ideal of nested type with the same depth as your ideal: in your
+// example the method using random changes of coordinates may enter an
+// infinite loop when the field is finite.
+// Try removing this optional argument.";
+       return (-1);
+             }
+         }
+     }
+//
+// At this stage, we have obtained a monomial ideal I of nested type
+// such that depth(S/i)=depth(S/I). We now compute depth(I).
+//
+//----- When S/i is Cohen-Macaulay:
+   for ( ii = n-d+2; ii <= n+1; ii++ )
+     {
+       K=K+select(I,ii);
+     }
+   if ( size(K) == 0 )
+     {
+       time=rtimer-time;
+       // Additional information:
+       dbprint(printlevel-voice+2,
+               "// Dimension of S/i: "+string(d)+" (S/i is Cohen-Macaulay)");
+       dbprint(printlevel-voice+2,
+               "// Time for computing depth: " + string(time) + " sec.");
+       dbprint(printlevel-voice+2,
+               "// The depth of S/i is:");
+       return(d);
+     }
+//----- When d=1 (and S/i is not Cohen-Macaulay) ==> depth =0:
+   if ( d == 1 )
+     {
+       time=rtimer-time;
+       // Additional information:
+       dbprint(printlevel-voice+2,
+               "// Dimension of S/i: 1");
+       dbprint(printlevel-voice+2,
+               "// Time for computing depth: "+ string(time) + " sec.");
+       dbprint(printlevel-voice+2,
+               "// The depth of S/i is:");
+       return(0);
+
+     }
+//----- Now d>1 and S/i is not Cohen-Macaulay:
+//
+//----- First, determine the last variable really occuring
+       lastv=n-d;
+       h=n;
+       while ( lastv == n-d and h > n-d )
+         {
+           K=select(I,h+1);
+           if ( size(K) == 0 )
+             {
+               h=h-1;
+             }
+           else
+             {
+               lastv=h;
+             }
+         }
+//----- and compute the depth:
+       time=rtimer-time;
+       // Additional information:
+       dbprint(printlevel-voice+2,
+               "// Dimension of S/i: "+string(d));
+       dbprint(printlevel-voice+2,
+               "// Time for computing depth: "+ string(time) + " sec.");
+       dbprint(printlevel-voice+2,
+               "// The depth of S/i is:");
+       return(n-lastv);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r=0,(x,y,z,t,w),dp;
+   ideal i=y2t,x2y-x2z+yt2,x2y2,xyztw,x3z2,y5+xz3w-x2zw2,x7-yt2w4;
+   depthIdeal(i);
+   depthIdeal(lead(std(i)));
+// Additional information is displayed if you change printlevel (=1);
+}
+////////////////////////////////////////////////////////////////////////////////
+/*
+Out-commented examples:
+   ring s=0,x(0..5),dp;
+   ideal i=x(2)^2-x(4)*x(5),x(1)*x(2)-x(0)*x(5),x(0)*x(2)-x(1)*x(4),
+           x(1)^2-x(3)*x(5),x(0)*x(1)-x(2)*x(3),x(0)^2-x(3)*x(4);
+   depthIdeal(i);
+   // Our procedure works when a min. graded free resol. can
+   // not be computed. In this easy example, depth can also
+   // be obtained using a m.g.f.r. (Auslander-Buchsbaum formula):
+   nvars(s)-ncols(betti(mres(i,0)))+1;
+   ring r1=0,(x,y,z,t),dp;
+// Ex.2.5 in [Bermejo-Gimenez], Proc.Amer.Math.Soc. 128(5):
+   ideal i  = x17y14-y31, x20y13, x60-y36z24-x20z20t20;
+   depthIdeal(i);
+// Ex.2.9 in [Bermejo-Gimenez], Proc.Amer.Math.Soc. 128(5):
+   int k=43;
+   ideal j=x17y14-y31,x20y13,x60-y36z24-x20z20t20,y41*z^k-y40*z^(k+1);
+   depthIdeal(j);
+// Example in Rk.2.10 in [Bermejo-Gimenez], ProcAMS 128(5):
+   ideal h=x2-3xy+5xt,xy-3y2+5yt,xz-3yz,2xt-yt,y2-yz-2yt;
+   depthIdeal(h);
+// The initial ideal is not saturated
+   depthIdeal(lead(std(h)));
+// More examples:
+   i=y4-t3z, x3t-y2z2, x3y2-t2z3, x6-tz5;
+   depthIdeal(i);
+//
+   depthIdeal(maxideal(4));
+//
+   ring r2=0,(x,y,z,t,w),dp;
+   ideal i = xy-zw,x3-yw2,x2z-y2w,y3-xz2,-y2z3+xw4+tw4+w5,-yz4+x2w3+xtw3+xw4,
+            -z5+x2tw2+x2w3+yw4;
+   depthIdeal(i);
+//
+   ring r3=0,(x,y,z,t,w,u),dp;
+   ideal i=imap(r2,i);
+   depthIdeal(i);
+// Next example is the defining ideal of the 2nd. Veronesean of P3, a variety
+// in P8 which is arithmetically Cohen-Macaulay:
+   ring r4=0,(a,b,c,d,x(0..9)),dp;
+   ideal i= x(0)-ab,x(1)-ac,x(2)-ad,x(3)-bc,x(4)-bd,x(5)-cd,
+            x(6)-a2,x(7)-b2,x(8)-c2,x(9)-d2;
+   ideal ei=eliminate(i,abcd);
+   ring r5=0,x(0..9),dp;
+   ideal i=imap(r4,ei);
+   depthIdeal(i);
+// Here is an example where the computation of a m.g.f.r. of I costs:
+   ring r8=0,(x,y,z,t,u,a,b),dp;
+   ideal i=u-b40,t-a40,x-a23b17,y-a22b18+ab39,z-a25b15;
+   ideal ei=eliminate(i,ab); // It takes a few seconds to compute the ideal
+   ring r9=0,(x,y,z,t,u),dp;
+   ideal i=imap(r8,ei);
+   depthIdeal(i);   // This is very fast.
+// Now you can use mres(i,0) to compute a m.g.f.r. of the ideal!
+//
+// Another one:
+   ring r10=0,(x(0..8),s,t),dp;
+   ideal i=x(0)-st24,x(1)-s2t23,x(2)-s3t22,x(3)-s9t16,x(4)-s11t14,x(5)-s18t7,
+           x(6)-s24t,x(7)-t25,x(8)-s25;
+   ideal ei=eliminate(i,st);
+   ring r11=0,x(0..8),dp;
+   ideal i=imap(r10,ei);
+   depthIdeal(i);
+// More examples where not even sres works:
+// Be careful: elimination takes some time here, but it succeeds!
+ring r12=0,(s,t,u,x(0..14)),dp;
+ideal i=x(0)-st6u8,x(1)-s5t3u7,x(2)-t11u4,x(3)-s9t4u2,x(4)-s2t7u6,x(5)-s7t7u,
+        x(6)-s10t5,x(7)-s4t6u5,x(8)-s13tu,x(9)-s14u,x(10)-st2u12,x(11)-s3t9u3,
+        x(12)-s15,x(13)-t15,x(14)-u15;
+ideal ei=eliminate(i,stu);
+size(ei);
+ring r13=0,x(0..14),dp;
+ideal i=imap(r12,ei);
+size(i);
+depthIdeal(i);
+//
+*/
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+
+proc satiety (ideal i, list #)
+"
+USAGE:   satiety (i[,e]); i ideal, e integer
+RETURN:  an integer, the satiety of i.
+         (returns -1 if i is not homogeneous)
+ASSUME:  i is a homogeneous ideal of the basering S=K[x(0)..x(n)].
+         e=0:  (default)
+               The satiety is computed determining the fresh elements in the
+               socle of i. It works over arbitrary fields.
+         e=1:  Makes random changes of coordinates to find a monomial ideal
+               with same satiety. It works over infinite fields only. If K
+               is finite, it works if it terminates, but may result in an
+               infinite loop. After 30 loops, a warning message is displayed
+               and -1 is returned.
+THEORY:  The satiety, or saturation index, of a homogeneous ideal i is the
+         least integer s such that, for all d>=s, the degree d part of the
+         ideals i and isat=sat(i,maxideal(1))[1] coincide.
+NOTE:    If printlevel > 0 (default = 0), dim(S/i) is also displayed.
+EXAMPLE: example satiety; shows some examples
+"
+{
+//--------------------------- initialisation ---------------------------------
+   int e,ii,jj,h,d,time,lastv,nesttest,NPtest,nl,sat;
+   intmat ran;
+   def r0 = basering;
+   int n = nvars(r0)-1;
+   if ( size(#) > 0 )
+   {
+      e = #[1];
+   }
+   string s = "ring r1 = ",charstr(r0),",x(0..n),dp;";
+   execute(s);
+   ideal i,sbi,I,K,chcoord,m,KK;
+   poly P;
+   map phi;
+   i = fetch(r0,i);
+   time=rtimer;
+   sbi=std(i);
+//----- Check ideal homogeneous
+   if ( homog(sbi) == 0 )
+   {
+       "// WARNING from proc satiety from lib mregular.lib:
+// The ideal is not homogeneous!";
+       return (-1);
+   }
+   I=simplify(lead(sbi),1);
+   attrib(I,"isSB",1);
+   d=dim(I);
+//----- If the ideal i is not proper:
+   if ( d == -1 )
+     {
+       dbprint(printlevel-voice+2,
+               "// The ideal i is (1)!
+// Its satiety is:");
+       return (0);
+     }
+//----- If the ideal i is 0:
+   if ( size(I) == 0 )
+     {
+       dbprint(printlevel-voice+2,
+               "// The ideal i is (0)!
+// Its satiety is:");
+       return (0);
+     }
+//----- When the ideal i is 0-dimensional:
+   if ( d == 0 )
+     {
+       sat=maxdeg1(minbase(quotient(I,maxideal(1))))+1;
+       time=rtimer-time;
+       // Additional information:
+       dbprint(printlevel-voice+2,
+               "// Dimension of S/i: 0");
+       dbprint(printlevel-voice+2,
+               "// Time for computing the satiety: " + string(time) + " sec.");
+       dbprint(printlevel-voice+2,
+               "// The satiety of i is:");
+       return (sat);
+     }
+//----- When one has option e=1:
+//
+//----- Determine the situation: NT, or NP, or nothing.
+//----- Choose the method depending on the situation in order to
+//----- get the mon. ideal of nested type associated to i
+   if ( e == 1 )
+     {
+       NPtest=is_NP(I);
+       if ( NPtest == 0 )
+         {
+           while ( nl < 30 )
+             {
+               chcoord=select1(maxideal(1),1..(n-d+1));
+               nl=nl+1;
+               for ( ii = 1; ii<=d; ii++ )
+                 {
+                   ran=random(100,1,n-d+ii);
+                   ran=intmat(ran,1,n-d+ii+1);
+                   ran[1,n-d+ii+1]=1;
+                   m=select1(maxideal(1),1..(n-d+1+ii));
+                   for ( jj = 1; jj<=n-d+ii+1; jj++ )
+                     {
+                       P=P+ran[1,jj]*m[jj];
+                     }
+                   chcoord[n-d+1+ii]=P;
+                   P=0;
+                 }
+               phi=r1,chcoord;
+               dbprint(printlevel-voice+2,"// (1 random change of coord.)");
+               I=simplify(lead(std(phi(i))),1);
+               attrib(I,"isSB",1);
+               NPtest=is_NP(I);
+               if ( NPtest == 1 )
+                 {
+                   break;
+                 }
+             }
+           if ( NPtest == 0 )
+             {
+       "// WARNING from proc satiety from lib mregular.lib:
+// The procedure has entered in 30 loops and could not put the variables
+// in Noether position: in your example the method using random changes
+// of coordinates may enter an infinite loop when the field is finite.
+// Try removing the optional argument.";
+       return (-1);
+             }
+           i=phi(i);
+         }
+       nesttest=is_nested(I);
+       if ( nesttest == 0 )
+         {
+           while ( nl < 30 )
+             {
+               chcoord=select1(maxideal(1),1..(n-d+2));
+               nl=nl+1;
+               for ( ii = 1; ii<=d-1; ii++ )
+                 {
+                   ran=random(100,1,ii);
+                   ran=intmat(ran,1,ii+1);
+                   ran[1,ii+1]=1;
+                   m=select1(maxideal(1),(n-d+2)..(n-d+2+ii));
+                   for ( jj = 1; jj<=ii+1; jj++ )
+                     {
+                       P=P+ran[1,jj]*m[jj];
+                     }
+                   chcoord[n-d+2+ii]=P;
+                   P=0;
+                 }
+               phi=r1,chcoord;
+               dbprint(printlevel-voice+2,"// (1 random change of coord.)");
+               I=simplify(lead(std(phi(i))),1);
+               attrib(I,"isSB",1);
+               nesttest=is_nested(I);
+               if ( nesttest == 1 )
+                 {
+                   break;
+                 }
+             }
+           if ( nesttest == 0 )
+             {
+       "// WARNING from proc satiety from lib mregular.lib:
+// The procedure has entered in 30 loops and could not find a monomial
+// ideal of nested type with the same satiety as your ideal: in your
+// example the method using random changes of coordinates may enter an
+// infinite loop when the field is finite.
+// Try removing the optional argument.";
+       return (-1);
+             }
+         }
+//
+// At this stage, we have obtained a monomial ideal I of nested type
+// such that depth(S/i)=depth(S/I). We now compute depth(I).
+//
+//----- When S/i is Cohen-Macaulay:
+//
+       for ( ii = n-d+2; ii <= n+1; ii++ )
+         {
+           K=K+select(I,ii);
+         }
+       if ( size(K) == 0 )
+         {
+           time=rtimer-time;
+           // Additional information:
+           dbprint(printlevel-voice+2,
+                   "// Dimension of S/i: "+string(d));
+           dbprint(printlevel-voice+2,
+                   "// Time for computing satiety: " + string(time) + " sec.");
+           dbprint(printlevel-voice+2,
+                   "// The satiety of i is:");
+           return(0);
+         }
+//----- When d=1 (and S/i is not Cohen-Macaulay) ==> depth =0:
+       if ( d == 1 )
+         {
+           KK=simplify(reduce(quotient(I,maxideal(1)),I),2);
+           sat=maxdeg1(KK)+1;
+           time=rtimer-time;
+           // Additional information:
+           dbprint(printlevel-voice+2,
+                   "// Dimension of S/i: 1");
+           dbprint(printlevel-voice+2,
+                   "// Time for computing satiety: "+ string(time) + " sec.");
+           dbprint(printlevel-voice+2,
+                   "// The satiety of i is:");
+           return(sat);
+         }
+//----- Now d>1 and S/i is not Cohen-Macaulay:
+//
+//----- First, determine the last variable really occuring
+       lastv=n-d;
+       h=n;
+       while ( lastv == n-d and h > n-d )
+         {
+           K=select(I,h+1);
+           if ( size(K) == 0 )
+             {
+               h=h-1;
+             }
+           else
+             {
+               lastv=h;
+             }
+         }
+//----- and compute the satiety:
+       sat=0;
+       if ( lastv == n )
+         {
+           KK=simplify(reduce(quotient(I,maxideal(1)),I),2);
+           sat=maxdeg1(KK)+1;
+         }
+       time=rtimer-time;
+       // Additional information:
+       dbprint(printlevel-voice+2,
+               "// Dimension of S/i: "+string(d));
+       dbprint(printlevel-voice+2,
+               "// Time for computing satiety: "+ string(time) + " sec.");
+       dbprint(printlevel-voice+2,
+               "// The satiety of i is:");
+       return(sat);
+     }
+//---- If no option: direct computation
+   sat=maxdeg1(reduce(quotient(i,maxideal(1)),sbi))+1;
+   time=rtimer-time;
+       // Additional information:
+   dbprint(printlevel-voice+2,
+           "// Dimension of S/i: "+string(d)+";");
+   dbprint(printlevel-voice+2,
+           "// Time for computing satiety: "+ string(time) + " sec.");
+   dbprint(printlevel-voice+2,
+           "// The satiety of i is:");
+   return(sat);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r=0,(x,y,z,t,w),dp;
+   ideal i=y2t,x2y-x2z+yt2,x2y2,xyztw,x3z2,y5+xz3w-x2zw2,x7-yt2w4;
+   satiety(i);
+   ideal I=lead(std(i));
+   satiety(I);   // First  method: direct computation
+   satiety(I,1); // Second method: doing changes of coordinates
+// Additional information is displayed if you change printlevel (=1);
+}
+////////////////////////////////////////////////////////////////////////////////
+/*
+Out-commented examples:
+   ring s1=0,(x,y,z,t),dp;
+   ideal I=zt3,z2t2,yz2t,xz2t,xy2t,x3y;
+   satiety(I);
+   satiety(I,1);
+// Another example:
+   ring s2=0,(z,y,x),dp;
+   ideal I=z38,z26y2,z14y4,z12x,z10x5,z8x9,z6x16,z4x23,z2y6,y32;
+   satiety(I);
+   satiety(I,1);
+// One more:
+   ring s3=0,(s,t,u,x(0..8)),dp;
+   ideal i=x(0)-st6u8,x(1)-s5t3u7,x(2)-t11u4,x(3)-s9t4u2,
+           x(4)-s2t7u6,x(5)-s7t7u,x(6)-s15,x(7)-t15,x(8)-u15;
+   ideal ei=eliminate(i,stu);
+   size(ei);
+   ring s4=0,x(0..8),dp;
+   ideal i=imap(s3,ei);
+   ideal m=maxideal(1);
+   m[8]=m[8]+m[7];
+   map phi=m;
+   ideal phii=phi(i);
+   ideal nI=lead(std(phii));
+   ring s5=0,x(0..7),dp;
+   ideal nI=imap(s4,nI);
+   satiety(nI);
+   satiety(nI,1);
+   ideal I1=subst(nI,x(7),1);
+   ring s6=0,x(0..6),dp;
+   ideal I1=imap(s5,I1);
+   satiety(I1);
+   satiety(I1,1);
+   ideal I2=subst(I1,x(6),1);
+   ring s7=0,x(0..5),dp;
+   ideal I2=imap(s6,I2);
+   satiety(I2);
+   satiety(I2,1);
+//
+*/
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+
+proc regMonCurve (list #)
+"
+USAGE:   regMonCurve (a0,...,an) ; ai integers with a0=0 < a1 < ... < an=:d
+RETURN:  an integer, the Castelnuovo-Mumford regularity of the projective
+         monomial curve C in Pn(K) parametrically defined by
+              x(0) = t^d , x(1) = s^(a1)t^(d-a1) , ..... , x(n) = s^d
+         where K is the field of complex numbers.
+         (returns -1 if a0=0 < a1 < ... < an is not satisfied)
+ASSUME:  a0=0 < a1 < ... < an are integers.
+NOTES:   1. The defining ideal of the curve C, I in S=K[x(0),...,x(n)], is
+            determined by elimination.
+         2. The procedure regIdeal has been improved in this case since one
+            knows beforehand that the monomial ideal J=lead(std(I)) is of
+            nested type if the monomial ordering is dp, and that
+            reg(C)=reg(J) (see preprint 'Saturation and Castelnuovo-Mumford
+            regularity' by Bermejo-Gimenez, 2004).
+         3. If printlevel > 0 (default = 0) additional info is displayed:
+            - It says whether C is arithmetically Cohen-Macaulay or not.
+            - If C is not arith. Cohen-Macaulay, end(H^1(S/I)) is computed
+              and an upper bound for the a-invariant of S/I is given.
+            - It also determines one step of the minimal graded free
+              resolution (m.g.f.r.) of I where the regularity is attained
+              and gives the value of the regularity of the Hilbert function
+              of S/I when reg(I) is attained at the last step of a m.g.f.r.
+EXAMPLE: example regMonCurve; shows some examples
+"
+{
+//--------------------------- initialisation ---------------------------------
+   int ii,H,h,hh,time,ttime,firstind,lastind;
+   int n = size(#)-1;
+//------------------  Check assumptions on integers  -------------------------
+   if ( #[1] != 0 )
+   {"// WARNING from proc regMonCurve from lib mregular.lib:
+// USAGE: your input must be a list of integers a0,a1,...,an such that
+// a0=0 < a1 < a2 < ... < an";
+      return(-1);
+   }
+   for ( ii=1; ii<= n; ii++ )
+   {
+      if ( #[ii] >= #[ii+1] )
+      {
+      "// WARNING from proc regMonCurve from lib mregular.lib:
+// USAGE: your input must be a list of integers a0,a1,...,an such that
+// a0=0 < a1 < a2 < ... < an";
+      return(-1);
+      }
+   }
+   ring R=0,(x(0..n),s,t),dp;
+   ideal param,m,i;
+   poly f(0..n);
+   for (ii=0;ii<=n;ii++)
+      {
+      f(ii)=s^(#[n+1]-#[ii+1])*t^(#[ii+1]);
+      param=param+f(ii);
+      }
+   m=subst(maxideal(1),s,0);
+   m=simplify(subst(m,t,0),2);
+   i=matrix(m)-matrix(param);
+   ttime=rtimer;
+   i=eliminate(i,st);
+   ring r=0,(x(1..n),x(0)),dp;
+   ideal i,I;
+   i=imap(R,i);
+   I=minbase(lead(std(i)));
+   attrib(I,"isSB",1);
+   ttime=rtimer-ttime;
+   time=rtimer;
+   ring nr=0,x(1..n),dp;
+   ideal I,K,KK,J;
+   I=imap(r,I);
+   attrib(I,"isSB",1);
+   K=select(I,n);
+//------------------ Cohen-Macaulay case ------------
+   if ( size(K) == 0 )
+     {
+       ring mr=0,x(1..n-1),dp;
+       ideal I=imap(nr,I);
+       H=maxdeg1(minbase(quotient(I,maxideal(1))))+1;
+       time=rtimer-time;
+       // Additional information:
+       dbprint(printlevel-voice+2,
+               "// The sequence of integers defines a monomial curve C in P"
+               + string(n));
+       dbprint(printlevel-voice+2,
+               "//    C is arithmetically Cohen-Macaulay");
+       dbprint(printlevel-voice+2,
+               "//    Regularity attained at the last step of a m.g.f.r. of I(C)");
+       dbprint(printlevel-voice+2,
+               "//    Regularity of the Hilbert function of S/I(C): "
+               + string(H-2));
+       dbprint(printlevel-voice+2,
+               "//    Time for computing ideal I(C) (by elimination): "
+               + string(ttime) + " sec.");
+       dbprint(printlevel-voice+2,
+               "//    Time for computing reg(C) once I(C) has been determined: "
+               + string(time) + " sec.");
+       dbprint(printlevel-voice+2,
+               "// The Castelnuovo-Mumford regularity of C is:");
+       return(H);
+     }
+   else
+     {
+       KK=simplify(reduce(quotient(I,maxideal(1)),I),2);
+       firstind=maxdeg1(KK)+1;
+       J=subst(I,x(n),1);
+       ring mr=0,x(1..n-1),dp;
+       ideal J=imap(nr,J);
+       lastind=maxdeg1(minbase(quotient(J,maxideal(1))))+1;
+       H=firstind;
+       if ( lastind > H )
+         {
+           H=lastind;
+         }
+       time=rtimer-time;
+       // Additional information:
+       dbprint(printlevel-voice+2,
+               "// The sequence of integers defines a monomial curve C in P"
+               + string(n));
+       dbprint(printlevel-voice+2,
+               "//    C is not arithmetically Cohen-Macaulay");
+       dbprint(printlevel-voice+2,
+               "//    end(H^1(S/I(C))) = "
+               +string(firstind-2));
+       dbprint(printlevel-voice+2,
+               "//    Upper bound for the a-invariant of S/I(C): end(H^2(S/I(C))) <= "
+               +string(lastind-3));
+       if ( H == firstind )
+         {
+           dbprint(printlevel-voice+2,
+                   "//    Regularity attained at the last step of a m.g.f.r. of I(C)");
+           dbprint(printlevel-voice+2,
+                   "//    Regularity of the Hilbert function of S/I(C): "
+                   + string(H-1));
+         }
+       else
+         {
+           dbprint(printlevel-voice+2,
+                   "//    Regularity attained at the second last step of a m.g.f.r. of I(C)");
+           dbprint(printlevel-voice+2,
+                   "//    (and not attained at the last step)");
+         }
+       dbprint(printlevel-voice+2,
+               "//    Time for computing ideal I(C) (by elimination): "
+               + string(ttime) + " sec.");
+       dbprint(printlevel-voice+2,
+               "//    Time for computing reg(C) once I(C) has been determined: "
+               + string(time) + " sec.");
+       dbprint(printlevel-voice+2,
+               "// The Castelnuovo-Mumford regularity of C is:");
+       return(H);
+     }
+}
+example
+{ "EXAMPLE:"; echo = 2;
+// The 1st example is the twisted cubic:
+   regMonCurve(0,1,2,3);
+// The 2nd. example is the non arithm. Cohen-Macaulay monomial curve in P4
+// parametrized by: x(0)-s6,x(1)-s5t,x(2)-s3t3,x(3)-st5,x(4)-t6:
+   regMonCurve(0,1,3,5,6);
+// Additional information is displayed if you change printlevel (=1);
+}
+////////////////////////////////////////////////////////////////////////////////
+/*
+Out-commented examples:
+//
+// The sequence of integers must be strictly increasing
+   regMonCurve(1,4,6,9);
+   regMonCurve(0,3,8,5,23);
+   regMonCurve(0,4,7,7,9);
+//
+// A curve in P3 s.t. the regularity is attained at the last step:
+   regMonCurve(0,2,12,15);
+//
+// A curve in P4 s.t. the regularity attained at the last but one
+// but NOT at the last step (Ex. 3.3 Preprint 2004):
+   regMonCurve(0,5,9,11,20);
+//
+// A curve in P8 s.t. the m.g.f.r. of the defining ideal is not easily
+// obtained through m.g.f.r.:
+   regMonCurve(0,1,2,3,9,11,18,24,25);
+//
+// A curve in P11 of degree 37:
+   regMonCurve(0,1,2,7,16,17,25,27,28,30,36,37);
+// It takes some time to compute the eliminated ideal; the computation of
+// the regularity is then rather fast as one can check using proc regIdeal:
+   ring q=0,(s,t,x(0..11)),dp;
+   ideal i=x(0)-st36,x(1)-s2t35,x(2)-s7t30,x(3)-s16t21,x(4)-s17t20,x(5)-s25t12,
+           x(6)-s27t10,x(7)-s28t9,x(8)-s30t7,x(9)-s36t,x(10)-s37,x(11)-t37;
+   ideal ei=eliminate(i,st);
+   ring qq=0,x(0..11),dp;
+   ideal i=imap(q,ei);
+   regIdeal(i);
+//
+// A curve in P14 of degree 55:
+   regMonCurve(0,1,2,7,16,17,25,27,28,30,36,37,40,53,55);
+//
+*/
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+
+proc NoetherPosition (ideal i)
+"
+USAGE:   NoetherPosition (i); i ideal
+RETURN:  ideal such that, for the homogeneous linear transformation
+         map phi=S,NoetherPosition(i);
+         one has that K[x(n-d+1),...,x(n)] is a Noether normalization of
+         S/phi(i) where S=K[x(0),...x(n)] is the basering and d=dim(S/i).
+         (returns -1 if i = (0) or (1)).
+ASSUME:  The field K is infinite and i is a nonzero proper ideal.
+NOTE:    1. It works also if K is a finite field if it terminates, but
+            may result in an infinite loop. If the procedure enters more
+            than 30 loops, -1 is returned and a warning message is displayed.@*
+         2. If printlevel > 0 (default = 0), additional info is displayed:
+            dim(S/i) and K[x(n-d+1),...,x(n)] are given.
+EXAMPLE: example NoetherPosition; shows some examples
+"
+{
+//--------------------------- initialisation ---------------------------------
+   int ii,jj,d,time,nl,NPtest;
+   intmat ran;
+   def r0 = basering;
+   ideal K,chcoord;
+   int n = nvars(r0)-1;
+   string s = "ring r1 = ",charstr(r0),",x(0..n),dp;";
+   execute(s);
+   ideal i,sbi,I,K,chcoord,m;
+   poly P;
+   map phi;
+   i = fetch(r0,i);
+   time=rtimer;
+   sbi=std(i);
+   I=simplify(lead(sbi),1);
+   attrib(I,"isSB",1);
+   d=dim(I);
+//----- If the ideal i is not proper:
+   if ( d == -1 )
+     {
+       "// WARNING from proc NoetherPosition from lib mregular.lib:
+// The ideal i is (1)!";
+       return (-1);
+     }
+//----- If the ideal i is 0:
+   if ( size(I) == 0 )
+     {
+       "// WARNING from proc NoetherPosition from lib mregular.lib:
+// The ideal i is (0)!";
+       return (-1);
+     }
+//----- When the ideal i is 0-dimensional:
+   if ( d == 0 )
+     {
+       time=rtimer-time;
+       // Additional information:
+       dbprint(printlevel-voice+2,
+               "// Dimension of S/i: 0");
+       dbprint(printlevel-voice+2,
+               "// Time for computing a Noether normalization: "
+               + string(time) + " sec.");
+       dbprint(printlevel-voice+2,
+               "// K is a Noether normalization of S/phi(i)");
+       dbprint(printlevel-voice+2,
+               "// where the map phi: S --> S is:");
+       setring r0;
+       return (maxideal(1));
+     }
+   NPtest=is_NP(I);
+   if ( NPtest == 1 )
+     {
+       K=x(n-d+1..n);
+       setring r0;
+       K=fetch(r1,K);
+       time=rtimer-time;
+       // Additional information:
+       dbprint(printlevel-voice+2,
+               "// Dimension of S/i: " + string(d) );
+       dbprint(printlevel-voice+2,
+               "// Time for computing a Noether normalization: " +
+               string(time) + " sec.");
+       dbprint(printlevel-voice+2,
+               "// K[" + string(K) +
+               "] is a Noether normalization of S/phi(i)");
+       dbprint(printlevel-voice+2,
+               "// where the map phi: S --> S is:");
+       return (maxideal(1));
+     }
+//---- Otherwise, random change of coordinates and
+//---- test for Noether normalization.
+//---- If we were unlucky, another change of coord. will be done:
+   while ( nl < 30 )
+   {
+     chcoord=select1(maxideal(1),1..(n-d+1));
+     nl=nl+1;
+     for ( ii = 1; ii<=d; ii++ )
+     {
+       ran=random(100,1,n-d+ii);
+       ran=intmat(ran,1,n-d+ii+1);
+       ran[1,n-d+ii+1]=1;
+       m=select1(maxideal(1),1..(n-d+1+ii));
+       for ( jj = 1; jj<=n-d+ii+1; jj++ )
+       {
+       P=P+ran[1,jj]*m[jj];
+       }
+       chcoord[n-d+1+ii]=P;
+       P=0;
+     }
+     phi=r1,chcoord;
+     dbprint(printlevel-voice+2,"// (1 random change of coord.)");
+     I=simplify(lead(std(phi(i))),1);
+     attrib(I,"isSB",1);
+     NPtest=is_NP(I);
+     if ( NPtest == 1 )
+       {
+       K=x(n-d+1..n);
+       setring r0;
+       K=fetch(r1,K);
+       chcoord=fetch(r1,chcoord);
+       time=rtimer-time;
+       // Additional information:
+       dbprint(printlevel-voice+2,
+               "// Dimension of S/i: " + string(d) );
+       dbprint(printlevel-voice+2,
+               "// Time for computing a Noether normalization: " +
+               string(time) + " sec.");
+       dbprint(printlevel-voice+2,
+               "// K[" + string(K) +
+               "] is a Noether normalization of S/phi(i)");
+       dbprint(printlevel-voice+2,
+               "// where the map phi: S --> S is:");
+       return (chcoord);
+       }
+   }
+       "// WARNING from proc NoetherPosition from lib mregular.lib:
+// The procedure has entered in more than 30 loops: in your example
+// the method may enter an infinite loop over a finite field!";
+       return (-1);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r=0,(x,y,z,t,u),dp;
+   ideal i1=y,z,t,u; ideal i2=x,z,t,u; ideal i3=x,y,t,u; ideal i4=x,y,z,u;
+   ideal i5=x,y,z,t; ideal i=intersect(i1,i2,i3,i4,i5);
+   map phi=r,NoetherPosition(i);
+   phi;
+   ring r5=5,(x,y,z,t,u),dp;
+   ideal i=imap(r,i);
+   map phi=r5,NoetherPosition(i);
+   phi;
+// Additional information is displayed if you change printlevel (=1);
+}
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+
+proc is_NP (ideal i)
+"
+USAGE:   is_NP (i); i ideal
+RETURN:  1  if K[x(n-d+1),...,x(n)] is a Noether normalization of
+            S/i where S=K[x(0),...x(n)] is the basering, and d=dim(S/i),
+         0  otherwise.
+         (returns -1 if i=(0) or i=(1)).
+ASSUME:  i is a nonzero proper homogeneous ideal.
+NOTE:    1. If i is not homogeneous and is_NP(i)=1 then K[x(n-d+1),...,x(n)]
+            is a Noether normalization of S/i. The converse may be wrong if
+            the ideal is not homogeneous.
+         2. is_NP is used in the procedures regIdeal, depthIdeal, satiety,
+            and NoetherPosition.
+EXAMPLE: example is_NP; shows some examples
+"
+{
+//--------------------------- initialisation ---------------------------------
+   int ii,d,dz;
+   def r0 = basering;
+   int n = nvars(r0)-1;
+   string s = "ring r1 = ",charstr(r0),",x(0..n),dp;";
+   execute(s);
+   ideal i,sbi,I,J;
+   i = fetch(r0,i);
+   sbi=std(i);
+   I=simplify(lead(sbi),1);
+   attrib(I,"isSB",1);
+   d=dim(I);
+//----- If the ideal i is not proper:
+   if ( d == -1 )
+     {
+       "// WARNING from proc is_NP from lib mregular.lib:
+// The ideal i is (1)!";
+       return (-1);
+     }
+//----- If the ideal i is 0:
+   if ( size(I) == 0 )
+     {
+       "// WARNING from proc is_NP from lib mregular.lib:
+// The ideal i is (0)!";
+       return (-1);
+     }
+//----- When the ideal i is 0-dimensional:
+   if ( d == 0 )
+     {
+       return (1);
+     }
+//----- Check Noether position
+   J=I;
+   for ( ii = n-d+1; ii <= n; ii++ )
+     {
+       J=subst(J,x(ii),0);
+     }
+   attrib(J,"isSB",1);
+   dz=dim(J);
+   if ( dz == d )
+     {
+       return (1);
+     }
+   else
+     {
+       return(0);
+     }
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r=0,(x,y,z,t,u),dp;
+   ideal i1=y,z,t,u; ideal i2=x,z,t,u; ideal i3=x,y,t,u; ideal i4=x,y,z,u;
+   ideal i5=x,y,z,t; ideal i=intersect(i1,i2,i3,i4,i5);
+   is_NP(i);
+   ideal ch=x,y,z,t,x+y+z+t+u;
+   map phi=ch;
+   is_NP(phi(i));
+}
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+
+proc is_nested (ideal i)
+"
+USAGE:   is_nested (i); i monomial ideal
+RETURN:  1 if i is of nested type, 0 otherwise.
+         (returns -1 if i=(0) or i=(1)).
+ASSUME:  i is a nonzero proper monomial ideal.
+NOTES:   1. The ideal must be monomial, otherwise the result has no meaning
+            (so check this before using this procedure).@*
+         2. is_nested is used in procedures depthIdeal, regIdeal and satiety.@*
+         3. When i is a monomial ideal of nested type of S=K[x(0)..x(n)],
+            the a-invariant of S/i coincides with the upper bound obtained
+            using the procedure regIdeal with printlevel > 0.
+THEORY:  A monomial ideal is of nested type if its associated primes are all
+         of the form (x(0),...,x(i)) for some i<=n.
+         (see definition and effective criterion to check this property in
+         the preprint 'Saturation and Castelnuovo-Mumford regularity' by
+         Bermejo-Gimenez, 2004).
+EXAMPLE: example is_nested; shows some examples
+"
+{
+//--------------------------- initialisation ---------------------------------
+   int ii,d,tev,lastv,h,NPtest;
+   def r0 = basering;
+   int n = nvars(r0)-1;
+   string s = "ring r1 = ",charstr(r0),",x(0..n),dp;";
+   execute(s);
+   ideal I,K,KK,LL;
+   I = fetch(r0,i);
+   I=minbase(I);
+   attrib(I,"isSB",1);
+   d=dim(I);
+//----- If the ideal i is not proper:
+   if ( d == -1 )
+   {
+       "// WARNING from proc is_nested from lib mregular.lib:
+// The ideal i is (1)!";
+       return (-1);
+   }
+//----- If the ideal i is 0:
+   if ( size(I) == 0 )
+     {
+       "// WARNING from proc is_nested from lib mregular.lib:
+// The ideal i is (0)!";
+       return (-1);
+     }
+//----- When the ideal i is 0-dimensional:
+   if ( d == 0 )
+     {
+       return (1);
+     }
+//----- Check Noether position
+   NPtest=is_NP(I);
+   if ( NPtest != 1 )
+   {
+       return (0);
+   }
+//----- When ideal is 1-dim. + var. in Noether position -> Nested Type
+   if ( d == 1 )
+     {
+       return (1);
+     }
+//----- Determ. of the last variable really occuring
+   lastv=n-d;
+   h=n;
+   while ( lastv == n-d and h > n-d )
+     {
+       K=select(I,h+1);
+       if ( size(K) == 0 )
+         {
+           h=h-1;
+         }
+       else
+         {
+           lastv=h;
+         }
+     }
+//----- Check the second property by evaluation when NP + d>1
+   KK=subst(I,x(lastv),1);
+   for ( ii = n-lastv; ii<=d-2; ii++ )
+   {
+     LL=minbase(subst(I,x(n-ii-1),1));
+     attrib(LL,"isSB",1);
+     tev=size(reduce(KK,LL));
+     if ( tev > 0 )
+     {
+       return(0);
+     }
+     KK=LL;
+   }
+   return(1);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring s=0,(x,y,z,t),dp;
+   ideal i1=x2,y3; ideal i2=x3,y2,z2; ideal i3=x3,y2,t2;
+   ideal i=intersect(i1,i2,i3);
+   is_nested(i);
+   ideal ch=x,y,z,z+t;
+   map phi=ch;
+   ideal I=lead(std(phi(i)));
+   is_nested(I);
+}
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+
diff --git a/Singular/LIB/multigrading.lib b/Singular/LIB/multigrading.lib
new file mode 100644
index 0000000..c414e12
--- /dev/null
+++ b/Singular/LIB/multigrading.lib
@@ -0,0 +1,5619 @@
+// -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+// Vi-modeline: vim: filetype=c:syntax:shiftwidth=2:tabstop=8:textwidth=0:expandtab
+/////////////////////////////////////////////////////////////////
+version="version multigrading.lib 4.0.0.0 Jun_2013 "; // $Id: 56791f115eb624889434986f7e04920a1172d446 $
+category="Combinatorial Commutative Algebra";
+info="
+LIBRARY:  multigrading.lib          Multigraded Rings
+
+AUTHORS:  Benjamin Bechtold, benjamin.bechtold at googlemail.com
+@*        Rene Birkner, rbirkner at math.fu-berlin.de
+@*        Lars Kastner, lkastner at math.fu-berlin.de
+@*        Simon Keicher, keicher at mail.mathematik.uni-tuebingen.de
+@*        Oleksandr Motsak, U at D, where U={motsak}, D={mathematik.uni-kl.de}
+@*        Anna-Lena Winz, anna-lena.winz at math.fu-berlin.de
+
+OVERVIEW: This library allows one to virtually add multigradings to Singular:
+grade multivariate polynomial rings with arbitrary (fin. gen. Abelian) groups.
+For more see http://code.google.com/p/convex-singular/wiki/Multigrading
+For theoretical references see:
+@* E. Miller, B. Sturmfels: 'Combinatorial Commutative Algebra'
+and
+@* M. Kreuzer, L. Robbiano: 'Computational Commutative Algebra'.
+
+NOTE: 'multiDegBasis' relies on 4ti2 for computing Hilbert Bases.
+All groups are finitely generated Abelian
+
+PROCEDURES:
+setBaseMultigrading(M,L); attach multiweights/grading group matrices to the basering
+getVariableWeights([R]);  get matrix of multidegrees of vars attached to a ring
+
+getGradingGroup([R]);     get grading group attached to a ring
+getLattice([R[,choice]]); get grading group' lattice attached to a ring (or its NF)
+
+createGroup(S,L);          create a group generated by S, with relations L
+createQuotientGroup(L);    create a group generated by the unit matrix whith relations L
+createTorsionFreeGroup(S); create a group generated by S which is torsionfree
+printGroup(G);             print a group
+
+isGroup(G);                   test whether G is a valid group
+isGroupHomomorphism(L1,L2,A); test wheter A defines a group homomrphism from L1 to L2
+
+isGradedRingHomomorphism(R,f,A);  test graded ring homomorph
+createGradedRingHomomorphism(R,f,A);  create a graded ring homomorph
+
+setModuleGrading(M,v);    attach multiweights of units to a module and return it
+getModuleGrading(M);      get multiweights of module units (attached to M)
+
+isSublattice(A,B);        test whether A is a sublattice of B
+imageLattice(P,L);        computes an integral basis for P(L)
+intRank(A);               computes the rank of the intmat A
+kernelLattice(P);         computes an integral basis for the kernel of the linear map P.
+latticeBasis(B);          computes an integral basis of the lattice B
+preimageLattice(P,L);     computes an integral basis for the preimage of the lattice L under the linear map P.
+projectLattice(B);        computes a linear map of lattices having the primitive span of B as its kernel.
+intersectLattices(A,B);   computes an integral basis for the intersection of the lattices A and B.
+isIntegralSurjective(P);  test whether the map P of lattices is surjective.
+isPrimitiveSublattice(A); test whether A generates a primitive sublattice.
+intInverse(A);            computes the integral inverse matrix of the intmat A
+integralSection(P);       for a given linear surjective map P of lattices this procedure returns an integral section of P.
+primitiveSpan(A);         computes a basis for the minimal primitive sublattice that contains the given vectors (by A).
+
+factorgroup(G,H);         create the group G mod H
+productgroup(G,H);        create the group G x H
+
+multiDeg(A);                  compute the multidegree of A
+multiDegBasis(d);             compute all monomials of multidegree d
+multiDegPartition(p);         compute the multigraded-homogeneous components of p
+
+isTorsionFree();          test whether the current multigrading is  free
+isPositive();             test whether the current multigrading is positive
+isZeroElement(p);         test whether p has zero multidegree
+areZeroElements(M);       test whether an integer matrix M considered as a collection of columns has zero multidegree
+isHomogeneous(a);         test whether 'a' is multigraded-homogeneous
+
+equalMultiDeg(e1,e2[,V]);     test whether e1==e2 in the current multigrading
+
+multiDegGroebner(M);          compute the multigraded GB/SB of M
+multiDegSyzygy(M);            compute the multigraded syzygies of M
+multiDegModulo(I,J);          compute the multigraded 'modulo' module of I and J
+multiDegResolution(M,l[,m]);  compute the multigraded resolution of M
+multiDegTensor(m,n);          compute the tensor product of multigraded modules m,n
+multiDegTor(i,m,n);           compute the Tor_i(m,n) for multigraded modules m,n
+
+defineHomogeneous(p);     get a grading group wrt which p becomes homogeneous
+pushForward(f);           find the finest grading on the image ring, homogenizing f
+gradiator(h);             coarsens grading of the ring until h becomes homogeneous
+
+hermiteNormalForm(A);     compute the Hermite Normal Form of a matrix
+smithNormalForm(A,#);     compute matrices D,P,Q with D=P*A*Q and D is the smith normal form of A
+
+hilbertSeries(M);         compute the multigraded Hilbert Series of M
+
+lll(A);                   applies LLL(.) of lll.lib which only works for lists on a matrix A
+
+           (parameters in square brackets [] are optional)
+
+KEYWORDS:  multigrading, multidegree, multiweights, multigraded-homogeneous, integral linear algebra
+";
+
+/// evalHilbertSeries(h,v);   evaluate hilberts series h by substituting v[i] for t_(i) (too experimentall)
+
+// finestMDeg(def r)
+// newMap(map F, intmat Q, list #)
+
+LIB "standard.lib"; // for groebner
+// LIB "lll.lib"; // for lll_matrix // no need now, right?
+LIB "matrix.lib"; // for multiDegTor
+
+/******************************************************/
+
+static proc concatintmat(intmat A, intmat B)
+{
+
+ if ( nrows(A) != nrows(B) )
+   {
+     ERROR("matrices A and B have different number of rows.");
+   }
+
+ intmat At = transpose(A);
+ intmat Bt = transpose(B);
+
+ intmat Ct[nrows(At) + nrows(Bt)][ncols(At)] = At, Bt;
+
+ return(transpose(Ct));
+}
+
+
+/******************************************************/
+proc createGradedRingHomomorphism(def src, ideal Im, def A)
+"USAGE: createGradedRingHomomorphism(R, f, A); ring R, ideal f, group homomorphism A
+PURPOSE: create a multigraded group ring homomorphism defined by
+a ring map from R to the current ring, given by generators images f
+and a group homomorphism A between grading groups
+RETURN: graded ring homorphism
+EXAMPLE: example createGradedRingHomomorphism; shows an example
+"
+{
+  string isGRH = "isGRH";
+
+  if( !isGradedRingHomomorphism(src, Im, A) )
+  {
+    ERROR("Input data is wrong");
+  }
+
+  list h;
+  h[3] = A;
+
+//  map f = src, Im;
+  h[2] = Im; // f?
+  h[1] = src;
+
+  attrib(h, isGRH, (1==1)); // mark it "a graded ring homomorphism"
+
+  return(h);
+}
+example
+{
+  "EXAMPLE:"; echo=2;
+
+  ring r = 0, (x, y, z), dp;
+  intmat S1[3][3] =
+                   1, 0, 0,
+                   0, 1, 0,
+                   0, 0, 1;
+  intmat L1[3][1] =
+                   0,
+                   0,
+                   0;
+
+  def G1 = createGroup(S1, L1); // (S1 + L1)/L1
+  printGroup(G1);
+
+  setBaseMultigrading(S1, L1); // to change...
+
+  ring R = 0, (a, b, c), dp;
+  intmat S2[2][3] =
+                   1, 0,
+                   0, 1;
+  intmat L2[2][1] =
+                   0,
+                   2;
+
+  def G2 = createGroup(S2, L2);
+  printGroup(G2);
+
+  setBaseMultigrading(S2, L2); // to change...
+
+
+  map F = r, a, b, c;
+  intmat A[nrows(L2)][nrows(L1)] =
+                                  1, 0, 0,
+                                  3, 2, -6;
+
+  // graded ring homomorphism is given by (compatible):
+  print(F);
+  print(A);
+
+  isGradedRingHomomorphism(r, ideal(F), A);
+  def h = createGradedRingHomomorphism(r, ideal(F), A);
+
+  print(h);
+}
+
+
+/******************************************************/
+proc isGradedRingHomomorphism(def src, ideal Im, def A)
+"USAGE: isGradedRingHomomorphism(R, f, A); ring R, ideal f, group homomorphism A
+PURPOSE: test a multigraded group ring homomorphism defined by
+a ring map from R to the current ring, given by generators images f
+and a group homomorphism A between grading groups
+RETURN: int, 1 for TRUE, 0 otherwise
+EXAMPLE: example isGradedRingHomomorphism; shows an example
+"
+{
+  def dst = basering;
+
+  intmat result_degs = multiDeg(Im);
+//  print(result_degs);
+
+  setring src;
+
+  intmat input_degs = multiDeg(maxideal(1));
+//  print(input_degs);
+
+  def image_degs = A * input_degs;
+//  print( image_degs );
+
+  def df = image_degs - result_degs;
+//  print(df);
+
+  setring dst;
+
+  return (areZeroElements( df ));
+}
+example
+{
+  "EXAMPLE:"; echo=2;
+
+  ring r = 0, (x, y, z), dp;
+  intmat S1[3][3] =
+    1, 0, 0,
+    0, 1, 0,
+    0, 0, 1;
+  intmat L1[3][1] =
+    0,
+    0,
+    0;
+
+  def G1 = createGroup(S1, L1); // (S1 + L1)/L1
+  printGroup(G1);
+
+  setBaseMultigrading(S1, L1); // to change...
+
+  ring R = 0, (a, b, c), dp;
+  intmat S2[2][3] =
+    1, 0,
+    0, 1;
+  intmat L2[2][1] =
+    0,
+    2;
+
+  def G2 = createGroup(S2, L2);
+  printGroup(G2);
+
+  setBaseMultigrading(S2, L2); // to change...
+
+
+  map F = r, a, b, c;
+  intmat A[nrows(L2)][nrows(L1)] =
+      1, 0, 0,
+      3, 2, -6;
+
+  // graded ring homomorphism is given by (compatible):
+  print(F);
+  print(A);
+
+  isGradedRingHomomorphism(r, ideal(F), A);
+  def h = createGradedRingHomomorphism(r, ideal(F), A);
+
+  print(h);
+
+  // not a homo..
+  intmat B[nrows(L2)][nrows(L1)] =
+     1, 1, 1,
+     0, 0, 0;
+  print(B);
+
+  isGradedRingHomomorphism(r, ideal(F), B); // FALSE: there is no such homomorphism!
+  // Therefore: the following command should return an error
+  // createGradedRingHomomorphism(r, ideal(F), B);
+
+}
+
+
+proc createQuotientGroup(intmat L)
+"USAGE: createGroup(L); L is an integer matrix
+PURPOSE: create the group of the form (I+L)/L,
+where I is the square identity matrix of size nrows(L) x nrows(L)
+NOTE: L specifies relations between free generators of Z^nrows(L)
+RETURN: group
+EXAMPLE: example createQuotientGroup; shows an example
+"
+{
+  int r = nrows(L); int i;
+  intmat S[r][r]; // SQUARE!!!
+  for(i = r; i > 0; i--){ S[i, i] = 1; }
+  return (createGroup(S,L));
+}
+example
+{
+  "EXAMPLE:"; echo=2;
+
+  intmat I[3][3] =
+                  1, 0, 0,
+                  0, 1, 0,
+                  0, 0, 1;
+
+  intmat L[3][2] =
+                  1, 1,
+                  1, 3,
+                  1, 5;
+
+
+  // The group Z^3 / L can be constructed as follows:
+
+  // shortcut:
+  def G = createQuotientGroup(L);
+  printGroup(G);
+
+  // the general way:
+  def GG = createGroup(I, L); // (I+L)/L
+  printGroup(GG);
+}
+
+proc createTorsionFreeGroup(intmat S)
+"USAGE: createTorsionFreeGroup(S); S is an integer matrix
+PURPOSE: create the free subgroup generated by S within the
+free Abelian group of rank nrows(S)
+RETURN: group
+EXAMPLE: example createTorsionFreeGroup; shows an example
+"
+{
+  int r = nrows(S); int i;
+  intmat L[r][1] = 0;
+  return (createGroup(S,L));
+}
+example
+{
+  "EXAMPLE:"; echo=2;
+
+  // ----------- extreme case ------------ //
+  intmat S[1][3] =
+                  1,  -1, 10;
+
+  // Torsion:
+  intmat L[1][1] =
+                  0;
+
+
+  // The free subgroup generated by elements of S within Z^1
+  // can be constructed as follows:
+
+  // shortcut:
+  def G = createTorsionFreeGroup(S);
+  printGroup(G);
+
+  // the general way:
+  def GG = createGroup(S, L); // (S+L)/L
+  printGroup(GG);
+}
+
+
+/******************************************************/
+proc createGroup(intmat S, intmat L)
+"USAGE: createGroup(S, L); S, L are integer matrices
+PURPOSE: create the group of the form (S+L)/L, i.e.
+S specifies generators, L specifies relations.
+RETURN: group
+EXAMPLE: example createGroup; shows an example
+"
+{
+  string isGroup = "isGroup";
+  string attrGroupHNF = "hermite";
+  string attrGroupSNF = "smith";
+
+
+/*
+  if( size(#) > 0 )
+  {
+    if( typeof(#[1]) == "intmat" )
+    {
+      intmat S = #[1];
+    } else { ERROR("Wrong optional argument: 1"); }
+
+    if( size(#) > 1 )
+    {
+      if( typeof(#[2]) == "intmat" )
+      {
+        intmat L = #[2];
+      } else { ERROR("Wrong optional argument: 2"); }
+    }
+  }
+*/
+
+  if( nrows(L) != nrows(S) )
+  {
+    ERROR("Incompatible matrices!");
+  }
+
+  def H = attrib(L, attrGroupHNF);
+  if( typeof(H) != "intmat")
+  {
+    attrib(L, attrGroupHNF, hermiteNormalForm(L));
+  } else { kill H; }
+
+  def HH = attrib(L, attrGroupSNF);
+  if( typeof(HH) != "intmat")
+  {
+    attrib(L, attrGroupSNF, smithNormalForm(L));
+  } else { kill HH; }
+
+  list G; // Please, note the order: Generators + Relations:
+  G[1] = S;
+  G[2] = L;
+  // And now a quick-and-dirty fix of Singular inability to handle attribs of attribs:
+  // For the use of a group as an attribute for multigraded rings
+  G[3] = attrib(L, attrGroupHNF);
+  G[4] = attrib(L, attrGroupSNF);
+
+
+  attrib(G, isGroup, (1==1)); // mark it "a group"
+
+  return (G);
+}
+example
+{
+  "EXAMPLE:"; echo=2;
+
+  intmat S[3][3] =
+    1, 0, 0,
+    0, 1, 0,
+    0, 0, 1;
+
+  intmat L[3][2] =
+    1, 1,
+    1, 3,
+    1, 5;
+
+  def G = createGroup(S, L); // (S+L)/L
+
+  printGroup(G);
+
+  kill S, L, G;
+
+  /////////////////////////////////////////////////
+  intmat S[2][3] =
+    1, -2, 1,
+    1,  1, 0;
+
+  intmat L[2][1] =
+    0,
+    2;
+
+  def G = createGroup(S, L); // (S+L)/L
+
+  printGroup(G);
+
+  kill S, L, G;
+
+  // ----------- extreme case ------------ //
+  intmat S[1][3] =
+    1,  -1, 10;
+
+  // Torsion:
+  intmat L[1][1] =
+    0;
+
+  def G = createGroup(S, L); // (S+L)/L
+
+  printGroup(G);
+}
+
+
+/******************************************************/
+proc printGroup(def G)
+"USAGE: printGroup(G); G is a group
+PURPOSE: prints the group G
+RETURN: nothing
+EXAMPLE: example printGroup; shows an example
+"
+{
+  "Generators: ";
+  print(G[1]);
+
+  "Relations: ";
+  print(G[2]);
+
+//  attrib(G[2]);
+}
+example
+{
+  "EXAMPLE:"; echo=2;
+
+  intmat S[3][3] =
+                  1, 0, 0,
+                  0, 1, 0,
+                  0, 0, 1;
+
+  intmat L[3][2] =
+                  1, 1,
+                  1, 3,
+                  1, 5;
+
+  def G = createGroup(S, L); // (S+L)/L
+  printGroup(G);
+
+}
+
+/******************************************************/
+static proc areIsomorphicGroups(def G, def H)
+"USAGE: areIsomorphicGroups(G, H); G and H are groups
+PURPOSE: Check whether G and H define isomorphic groups.
+RETURN: int, 1 for TRUE, 0 otherwise
+EXAMPLE: example areIsomorphicGroups; shows an example
+"
+{
+  ERROR("areIsomorphicGroups: Not yet implemented!");
+  return (1); // TRUE
+}
+example
+{
+  "EXAMPLE:"; echo=2;
+
+  // TODO!
+
+}
+
+/******************************************************/
+proc isGroup(def G)
+"USAGE: isGroup(G); G a list
+PURPOSE: checks whether G is a valid group
+NOTE: G should be created by createGroup
+(or createQuotientGroup, createTorsionFreeGroup)
+RETURN: int, 1 if G is a valid group and 0 otherwise
+EXAMPLE: example isGroup; shows an example
+"
+{
+  string isGroup = "isGroup";
+
+  // valid?
+  if( typeof(G) != "list" ){ return(0); }
+
+  def a = attrib(G, isGroup);
+
+///// TODO for Hans: fix attr^2 bug in Singular!
+
+//  if( !defined(a) ) { return(0); }
+//  if( typeof(a) != "int" ) { return(0); }
+  if( defined(a) ){ if(typeof(a) == "int") { return(a); } }
+
+
+  if( (size(G) != 2) && (size(G) != 4) ){ return(0); }
+  if( typeof(G[1]) != "intmat" ){ return(0); }
+  if( typeof(G[2]) != "intmat" ){ return(0); }
+  if( nrows(G[1]) != nrows(G[2]) ){ return(0); }
+
+  return(1);
+}
+example
+{
+  "EXAMPLE:"; echo=2;
+
+  intmat S[3][3] =
+                  1, 0, 0,
+                  0, 1, 0,
+                  0, 0, 1;
+
+  intmat L[3][2] =
+                  1, 1,
+                  1, 3,
+                  1, 5;
+
+  def G = createGroup(S, L); // (S+L)/L
+
+  isGroup(G);
+
+  printGroup(G);
+
+}
+
+
+
+/******************************************************/
+proc setBaseMultigrading(intmat M, list #)
+"USAGE: setBaseMultigrading(M[, G]); M is an integer matrix, G is a group (or lattice)
+PURPOSE: attaches weights of variables and grading group to the basering.
+NOTE: M encodes the weights of variables column-wise.
+RETURN: nothing
+EXAMPLE: example setBaseMultigrading; shows an example
+"
+{
+  string attrMgrad   = "mgrad";
+  string attrGradingGroup = "gradingGroup";
+
+  int i = 1;
+  if( size(#) >= i )
+  {
+    def a = #[i];
+    if( typeof(a) == "intmat" )
+    {
+      def L = createGroup(M, a);
+      i++;
+    }
+
+    if( isGroup(a) )
+    {
+      def L = a;
+
+      if( !isSublattice(M, L[1]) )
+      {
+        ERROR("Multigrading is not contained in the grading group!");
+      }
+      i++;
+    }
+    if( i == 1 ){ ERROR("Wrong arguments: no group given?"); }
+    kill a;
+  }
+  else
+  {
+    def L = createTorsionFreeGroup(M);
+  }
+
+
+  attrib(basering, attrMgrad, M);
+  attrib(basering, attrGradingGroup, L);
+
+  ideal Q = ideal(basering); // quotient ideal is assumed to be a GB!
+  if( !isHomogeneous(Q, "checkGens") ) // easy now, but would be hard before setting ring attributes!
+  {
+    "Warning: your quotient ideal is not homogenous (multigrading was set anyway)!";
+  }
+
+}
+example
+{
+  "EXAMPLE:"; echo=2;
+
+  ring R = 0, (x, y, z), dp;
+
+  // Weights of variables
+  intmat M[3][3] =
+    1, 0, 0,
+    0, 1, 0,
+    0, 0, 1;
+
+  // GradingGroup:
+  intmat L[3][2] =
+    1, 1,
+    1, 3,
+    1, 5;
+
+  // attaches M & L to R (==basering):
+  setBaseMultigrading(M, L); // Grading: Z^3/L
+
+  // Weights are accessible via "getVariableWeights()":
+  getVariableWeights();
+
+  // Test all possible usages:
+  (getVariableWeights() == M) && (getVariableWeights(R) == M) && (getVariableWeights(basering) == M);
+
+  // Grading group is accessible via "getLattice()":
+  getLattice();
+
+  // Test all possible usages:
+  (getLattice() == L) && (getLattice(R) == L) && (getLattice(basering) == L);
+
+  // And its hermite NF via getLattice("hermite"):
+  getLattice("hermite");
+
+  // Test all possible usages:
+  intmat H = hermiteNormalForm(L);
+  (getLattice("hermite") == H) && (getLattice(R, "hermite") == H) && (getLattice(basering, "hermite") == H);
+
+  kill L, M;
+
+  // ----------- isomorphic multigrading -------- //
+
+  // Weights of variables
+  intmat M[2][3] =
+    1, -2, 1,
+    1,  1, 0;
+
+  // Torsion:
+  intmat L[2][1] =
+    0,
+    2;
+
+  // attaches M & L to R (==basering):
+  setBaseMultigrading(M, L); // Grading: Z + (Z/2Z)
+
+  // Weights are accessible via "getVariableWeights()":
+  getVariableWeights() == M;
+
+  // Torsion is accessible via "getLattice()":
+  getLattice() == L;
+
+  kill L, M;
+  // ----------- extreme case ------------ //
+
+  // Weights of variables
+  intmat M[1][3] =
+    1,  -1, 10;
+
+  // Torsion:
+  intmat L[1][1] =
+    0;
+
+  // attaches M & L to R (==basering):
+  setBaseMultigrading(M); // Grading: Z^3
+
+  // Weights are accessible via "getVariableWeights()":
+  getVariableWeights() == M;
+
+  // Torsion is accessible via "getLattice()":
+  getLattice() == L;
+}
+
+
+/******************************************************/
+proc getVariableWeights(list #)
+"USAGE: getVariableWeights([R])
+PURPOSE: get associated multigrading matrix for the basering [or R]
+RETURN:  intmat, matrix of multidegrees of variables
+EXAMPLE: example getVariableWeights; shows an example
+"
+{
+  string attrMgrad = "mgrad";
+
+
+  if( size(#) > 0 )
+  {
+    if(( typeof(#[1]) == "ring" ) || ( typeof(#[1]) == "qring" ))
+    {
+      def R = #[1];
+    }
+    else
+    {
+      ERROR("Optional argument must be a ring!");
+    }
+  }
+  else
+  {
+    def R = basering;
+  }
+
+  def M = attrib(R, attrMgrad);
+  if( typeof(M) == "intmat"){ return (M); }
+  ERROR( "Sorry no multigrading matrix!" );
+}
+example
+{
+  "EXAMPLE:"; echo=2;
+
+  ring R = 0, (x, y, z), dp;
+
+  // Weights of variables
+  intmat M[3][3] =
+    1, 0, 0,
+    0, 1, 0,
+    0, 0, 1;
+
+  // Grading group:
+  intmat L[3][2] =
+    1, 1,
+    1, 3,
+    1, 5;
+
+  // attaches M & L to R (==basering):
+  setBaseMultigrading(M, L); // Grading: Z^3/L
+
+  // Weights are accessible via "getVariableWeights()":
+  getVariableWeights() == M;
+
+  kill L, M;
+
+  // ----------- isomorphic multigrading -------- //
+
+  // Weights of variables
+  intmat M[2][3] =
+    1, -2, 1,
+    1,  1, 0;
+
+  // Grading group:
+  intmat L[2][1] =
+    0,
+    2;
+
+  // attaches M & L to R (==basering):
+  setBaseMultigrading(M, L); // Grading: Z + (Z/2Z)
+
+  // Weights are accessible via "getVariableWeights()":
+  getVariableWeights() == M;
+
+  kill L, M;
+
+  // ----------- extreme case ------------ //
+
+  // Weights of variables
+  intmat M[1][3] =
+    1,  -1, 10;
+
+  // Grading group:
+  intmat L[1][1] =
+    0;
+
+  // attaches M & L to R (==basering):
+  setBaseMultigrading(M); // Grading: Z^3
+
+  // Weights are accessible via "getVariableWeights()":
+  getVariableWeights() == M;
+}
+
+
+proc getGradingGroup(list #)
+"USAGE: getGradingGroup([R])
+PURPOSE: get associated grading group
+RETURN: group, the grading group
+EXAMPLE: example getGradingGroup; shows an example
+"
+{
+  string attrGradingGroup    = "gradingGroup";
+
+  int i = 1;
+
+  if( size(#) >= i )
+  {
+    if( ( typeof(#[i]) == "ring" ) or ( typeof(#[i]) == "qring" ) )
+    {
+      def R = #[i];
+      i++;
+    }
+  }
+
+  if( i == 1 )
+  {
+    def R = basering;
+  }
+
+  def G = attrib(R, attrGradingGroup);
+
+  if( !isGroup(G) )
+  {
+    ERROR("Sorry no grading group!");
+  }
+
+  return(G);
+}
+example
+{
+  "EXAMPLE:"; echo=2;
+
+  ring R = 0, (x, y, z), dp;
+
+  // Weights of variables
+  intmat M[3][3] =
+    1, 0, 0,
+    0, 1, 0,
+    0, 0, 1;
+
+  // Torsion:
+  intmat L[3][2] =
+    1, 1,
+    1, 3,
+    1, 5;
+
+  // attaches M & L to R (==basering):
+  setBaseMultigrading(M, L); // Grading: Z^3/L
+
+  def G = getGradingGroup();
+
+  printGroup( G );
+
+  G[1] == M; G[2] == L;
+
+  kill L, M, G;
+
+  // ----------- isomorphic multigrading -------- //
+
+  // Weights of variables
+  intmat M[2][3] =
+    1, -2, 1,
+    1,  1, 0;
+
+  // Torsion:
+  intmat L[2][1] =
+    0,
+    2;
+
+  // attaches M & L to R (==basering):
+  setBaseMultigrading(M, L); // Grading: Z + (Z/2Z)
+
+  def G = getGradingGroup();
+
+  printGroup( G );
+
+  G[1] == M; G[2] == L;
+
+  kill L, M, G;
+  // ----------- extreme case ------------ //
+
+  // Weights of variables
+  intmat M[1][3] =
+    1,  -1, 10;
+
+  // Torsion:
+  intmat L[1][1] =
+    0;
+
+  // attaches M & L to R (==basering):
+  setBaseMultigrading(M); // Grading: Z^3
+
+  def G = getGradingGroup();
+
+  printGroup( G );
+
+  G[1] == M; G[2] == L;
+
+  kill L, M, G;
+}
+
+
+/******************************************************/
+proc getLattice(list #)
+"USAGE: getLattice([R[,opt]])
+PURPOSE: get associated grading group matrix, i.e. generators (cols) of the grading group
+RETURN: intmat, the grading group matrix, or
+its hermite normal form if an optional argument (\"hermiteNormalForm\") is given or
+smith normal form if an optional argument (\"smith\") is given
+EXAMPLE: example getLattice; shows an example
+"
+{
+  int i = 1;
+  if( size(#) >= i )
+  {
+    def a = #[i];
+    if( ( typeof(a) == "ring" ) or ( typeof(a) == "qring" ) )
+    {
+      i++;
+    }
+    kill a;
+  }
+
+  string attrGradingGroupHNF = "hermite";
+  string attrGradingGroupSNF = "smith";
+
+  def G = getGradingGroup(#);
+
+//  printGroup(G);
+
+
+
+  def T = G[2];
+
+  if( size(#) >= i )
+  {
+    def a = #[i];
+
+    if( typeof(a) != "string" )
+    {
+      ERROR("Sorry wrong arguments!");
+    }
+
+    if( a == "hermite" )
+    {
+      def M = attrib(T, attrGradingGroupHNF);
+      if( typeof(M) != "intmat" )
+      {
+        if( size(G) > 2 )
+        {
+          M = G[3];
+        } else
+        {
+          M = hermiteNormalForm(T);
+        }
+      }
+      return (M);
+    }
+
+    if( a == "smith" )
+    {
+      def M = attrib(T, attrGradingGroupSNF);
+      if( typeof(M) != "intmat" )
+      {
+        if( size(G) > 2 )
+        {
+          M = G[4];
+        } else
+        {
+          M = smithNormalForm(T);
+        }
+      }
+      return (M);
+    }
+  }
+
+  return(T);
+}
+example
+{
+  "EXAMPLE:"; echo=2;
+
+  ring R = 0, (x, y, z), dp;
+
+  // Weights of variables
+  intmat M[3][3] =
+    1, 0, 0,
+    0, 1, 0,
+    0, 0, 1;
+
+  // Torsion:
+  intmat L[3][2] =
+    1, 1,
+    1, 3,
+    1, 5;
+
+  // attaches M & L to R (==basering):
+  setBaseMultigrading(M, L); // Grading: Z^3/L
+
+  // Torsion is accessible via "getLattice()":
+  getLattice() == L;
+
+  // its hermite NF:
+  print(getLattice("hermite"));
+
+  kill L, M;
+
+  // ----------- isomorphic multigrading -------- //
+
+  // Weights of variables
+  intmat M[2][3] =
+    1, -2, 1,
+    1,  1, 0;
+
+  // Torsion:
+  intmat L[2][1] =
+    0,
+    2;
+
+  // attaches M & L to R (==basering):
+  setBaseMultigrading(M, L); // Grading: Z + (Z/2Z)
+
+  // Torsion is accessible via "getLattice()":
+  getLattice() == L;
+
+  // its hermite NF:
+  print(getLattice("hermite"));
+
+  kill L, M;
+
+  // ----------- extreme case ------------ //
+
+  // Weights of variables
+  intmat M[1][3] =
+    1,  -1, 10;
+
+  // Torsion:
+  intmat L[1][1] =
+    0;
+
+  // attaches M & L to R (==basering):
+  setBaseMultigrading(M); // Grading: Z^3
+
+  // Torsion is accessible via "getLattice()":
+  getLattice() == L;
+
+  // its hermite NF:
+  print(getLattice("hermite"));
+}
+
+proc getGradedGenerator(def m, int i)
+"USAGE: getGradedGenerator(M, i), 'M' module/ideal, 'i' int
+RETURN: returns the i-th generator of M, endowed with the module grading from M
+EXAMPLE: example getGradedGenerator; shows an example
+"
+{
+  if( typeof(m) == "ideal" )
+  {
+    return (m[i]);
+  }
+
+  if( typeof(m) == "module" )
+  {
+    def v = getModuleGrading(m);
+
+    return ( setModuleGrading(m[i],v) );
+  }
+
+  ERROR("m is expected to be an ideal or a module");
+}
+example
+{
+  "EXAMPLE:"; echo=2;
+
+  ring r = 0,(x,y,z,w),dp;
+  intmat MM[2][4]=
+                  1,1,1,1,
+                  0,1,3,4;
+  setBaseMultigrading(MM);
+
+  module M = ideal(  xw-yz, x2z-y3, xz2-y2w, yw2-z3);
+
+
+  intmat v[2][nrows(M)]=
+                        1,
+                        0;
+
+  M = setModuleGrading(M, v);
+
+  isHomogeneous(M);
+  "Multidegrees: "; print(multiDeg(M));
+
+  // Let's compute syzygies!
+  def S = multiDegSyzygy(M); S;
+  "Module Units Multigrading: "; print( getModuleGrading(S) );
+  "Multidegrees: "; print(multiDeg(S));
+
+  isHomogeneous(S);
+
+  // same as S[1] together with the induced module weighting
+  def v = getGradedGenerator(S, 1);
+  print(v);
+  print(setModuleGrading(v));
+
+  isHomogeneous(v);
+
+  isHomogeneous(S[1]);
+}
+
+/******************************************************/
+proc getModuleGrading(def m)
+"USAGE: getModuleGrading(m), 'm' module/vector
+RETURN: integer matrix of the multiweights of free module generators attached to 'm'
+EXAMPLE: example getModuleGrading; shows an example
+"
+{
+  string attrModuleGrading = "genWeights";
+
+  //  print(m);  typeof(m);  attrib(m);
+
+  def V = attrib(m, attrModuleGrading);
+
+  if( typeof(V) != "intmat" )
+  {
+    if( (typeof(m) == "ideal") or (typeof(m) == "poly") )
+    {
+      intmat M = getVariableWeights();
+      intmat VV[nrows(M)][1];
+      return (VV);
+    }
+
+    ERROR("Sorry: vector or module need module-grading-matrix! See 'getModuleGrading'.");
+  }
+
+  if( nrows(V) != nrows(getVariableWeights()) )
+  {
+    ERROR("Sorry wrong height of V: " + string(nrows(V)));
+  }
+
+  if( ncols(V) < nrows(m) )
+  {
+    ERROR("Sorry wrong width of V: " + string(ncols(V)));
+  }
+
+  return (V);
+}
+example
+{
+  "EXAMPLE:"; echo=2;
+
+   ring R = 0, (x,y), dp;
+   intmat M[2][2]=
+     1, 1,
+     0, 2;
+   intmat T[2][5]=
+     1,  2,  3,  4, 0,
+     0, 10, 20, 30, 1;
+
+   setBaseMultigrading(M, T);
+
+   ideal I = x, y, xy^5;
+   isHomogeneous(I);
+
+   intmat V = multiDeg(I); print(V);
+
+   module S = syz(I); print(S);
+
+   S = setModuleGrading(S, V);
+
+   getModuleGrading(S) == V;
+
+   vector v = getGradedGenerator(S, 1);
+   getModuleGrading(v) == V;
+   isHomogeneous(v);
+   print( multiDeg(v) );
+
+   isHomogeneous(S);
+   print( multiDeg(S) );
+}
+
+/******************************************************/
+proc setModuleGrading(def m, intmat G)
+"USAGE: setModuleGrading(m, G), m module/vector, G intmat
+PURPOSE: attaches the multiweights of free module generators to 'm'
+WARNING: The method does not verify whether the multigrading makes the
+         module/vector homogeneous. One can do that using isHomogeneous(m).
+EXAMPLE: example setModuleGrading; shows an example
+"
+{
+  string attrModuleGrading = "genWeights";
+
+  intmat R = getVariableWeights();
+
+  if(nrows(G) != nrows(R)){ ERROR("Incompatible gradings.");}
+  if(ncols(G) < nrows(m)){ ERROR("Multigrading does not fit to module.");}
+
+  attrib(m, attrModuleGrading, G);
+  return(m);
+}
+example
+{
+  "EXAMPLE:"; echo=2;
+
+   ring R = 0, (x,y), dp;
+   intmat M[2][2]=
+     1, 1,
+     0, 2;
+   intmat T[2][5]=
+     1,  2,  3,  4, 0,
+     0, 10, 20, 30, 1;
+
+   setBaseMultigrading(M, T);
+
+   ideal I = x, y, xy^5;
+   intmat V = multiDeg(I);
+
+   // V == M; modulo T
+   print(V);
+
+   module S = syz(I);
+
+   S = setModuleGrading(S, V);
+   getModuleGrading(S) == V;
+
+   print(S);
+
+   vector v = getGradedGenerator(S, 1);
+   getModuleGrading(v) == V;
+
+   print( multiDeg(v) );
+
+   isHomogeneous(S);
+
+   print( multiDeg(S) );
+}
+
+
+proc multiDegTensor(module m, module n)
+"
+USAGE: multiDegTensor(m, n), m,n  modules or matrices.
+PURPOSE: Computes the multigraded tensor product of to multigraded modules.
+RETURN: A module.
+EXAMPLE: example multiDegTensor; shows an example
+"
+{
+  matrix M = m;
+  matrix N = n;
+  intmat gm = getModuleGrading(m);
+  intmat gn = getModuleGrading(n);
+  int grows = nrows(gm);
+  int mr = nrows(M);
+  int mc = ncols(M);
+  if(rank(M) == 0){ mc = 0;}
+  int nr = nrows(N);
+  int nc = ncols(N);
+  if(rank(N) == 0){ nc = 0;}
+  intmat gresult[nrows(gm)][mr*nr];
+  matrix result[mr*nr][mr*nc+mc*nr];
+  int i, j;
+  int column = 1;
+  for(i = 1; i<=mr; i++){
+    for(j = 1; j<=nr; j++){
+      gresult[1..grows,(i-1)*nr+j] = gm[1..grows,i]+gn[1..grows,j];
+    }
+  }
+  //gresult;
+  if( nc!=0 ){
+    for(i = 1; i<=mr; i++)
+    {
+      result[((i-1)*nr+1)..(i*nr),((i-1)*nc+1)..(i*nc)] = N[1..nr,1..nc];
+    }
+  }
+  list rownumbers, colnumbers;
+  //print(result);
+  if( mc!=0 ){
+    for(j = 1; j<=nr; j++)
+    {
+      rownumbers = nr*(0..(mr-1))+j*(1:mr);
+      colnumbers = ((mr*nc+j):mc)+nr*(0..(mc-1));
+      result[rownumbers[1..mr],colnumbers[1..mc] ] = M[1..mr,1..mc];
+    }
+  }
+  module res = result;
+  res = setModuleGrading(res, gresult);
+  //getModuleGrading(res);
+  return(res);
+}
+example
+{
+"EXAMPLE: ";echo=2;
+ring r = 0,(x),dp;
+intmat g[2][1]=1,1;
+setBaseMultigrading(g);
+matrix m[5][3]=1,2,3,4,5,6,7,8,9,10,11,12,13,14,15;
+matrix n[3][2]=x,x2,x3,x4,x5,x6;
+module mm = m;
+module nn = n;
+intmat gm[2][5]=1,2,3,4,5,0,0,0,0,0;
+intmat gn[2][3]=0,0,0,1,2,3;
+mm = setModuleGrading(mm, gm);
+nn = setModuleGrading(nn, gn);
+module mmtnn = multiDegTensor(mm, nn);
+print(mmtnn);
+getModuleGrading(mmtnn);
+LIB "homolog.lib";
+module tt = tensorMod(mm,nn);
+print(tt);
+
+kill m, mm, n, nn, gm, gn;
+
+matrix m[7][3] = x, x-1,x+2, 3x, 4x, x5, x6, x-7, x-8, 9, 10, 11x, 12 -x, 13x, 14x, x15, (x-4)^2, x17, 18x, 19x, 20x, 21x;
+matrix n[2][4] = 1, 2, 3, 4, x, x2, x3, x4;
+module mm = m;
+module nn = n;
+print(mm);
+print(nn);
+intmat gm[2][7] = 1, 2, 3, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0;
+intmat gn[2][2] = 0, 0, 1, 2;
+mm = setModuleGrading(mm, gm);
+nn = setModuleGrading(nn, gn);
+module mmtnn = multiDegTensor(mm, nn);
+print(mmtnn);
+getModuleGrading(mmtnn);
+matrix a = mmtnn;
+matrix b = tensorMod(mm, nn);
+print(a-b);
+
+}
+
+proc multiDegTor(int i, module m, module n)
+{
+  def res = multiDegResolution(n, 0, 1);
+  //print(res);
+  list l = res;
+  if(size(l)<i){ return(0);}
+  else
+  {
+
+    matrix fd[nrows(m)][0];
+    matrix fd2[nrows(l[i+1])][0];
+    matrix fd3[nrows(l[i])][0];
+
+    module freedim = fd;
+    module freedim2 = fd2;
+    module freedim3 = fd3;
+
+    freedim = setModuleGrading(freedim,getModuleGrading(m));
+    freedim2 = setModuleGrading(freedim2,getModuleGrading(l[i+1]));
+    freedim3 = setModuleGrading(freedim3, getModuleGrading(l[i]));
+
+    module mimag = multiDegTensor(freedim3, m);
+    //"mimag ok.";
+    module mf = multiDegTensor(l[i], freedim);
+    //"mf ok.";
+    module mim1 = multiDegTensor(freedim2 ,m);
+    module mim2 = multiDegTensor(l[i+1],freedim);
+    //"mim1+2 ok.";
+    module mker = multiDegModulo(mf,mimag);
+    //"mker ok.";
+    module mim = mim1,mim2;
+    mim = setModuleGrading(mim, getModuleGrading(mim1));
+    //"mim: r: ",nrows(mim)," c: ",ncols(mim);
+    //"mim1: r: ",nrows(mim1)," c: ",ncols(mim1);
+    //"mim2: r: ",nrows(mim2)," c: ",ncols(mim2);
+    //matrix mimmat = mim;
+    //matrix mimmat1[16][4]=mimmat[1..16,25..28];
+    //print(mimmat1-matrix(mim2));
+    return(multiDegModulo(mker,mim));
+    //return(0);
+  }
+  return(0);
+}
+example
+{
+"EXAMPLE: ";echo=2;
+LIB "homolog.lib";
+ring r = 0,(x_(1..4)),dp;
+intmat g[2][4]=1,1,0,0,0,1,1,-1;
+setBaseMultigrading(g);
+ideal i = maxideal(1);
+module m = multiDegSyzygy(i);
+module rt = Tor(2,m,m);
+module multiDegT = multiDegTor(2,m,m);
+print(matrix(rt)-matrix(multiDegT));
+/*
+ring r = 0,(x),dp;
+intmat g[2][1]=1,1;
+setBaseMultigrading(g);
+matrix m[5][3]=1,2,3,4,5,6,7,8,9,10,11,12,13,14,15;
+matrix n[3][2]=x,x2,x3,x4,x5,x6;
+module mm = m;
+module nn = n;
+intmat gm[2][5]=1,1,1,1,1,1,1,1,1,1,1;
+intmat gn[2][3]=0,-2,-4,0,-2,-4;
+mm = setModuleGrading(mm, gm);
+nn = setModuleGrading(nn, gn);
+isHomogeneous(mm,"checkGens");
+isHomogeneous(nn,"checkGens");
+multiDegTor(1,mm, nn);
+
+kill m, mm, n, nn, gm, gn;
+
+matrix m[7][3] = x, x-1,x+2, 3x, 4x, x5, x6, x-7, x-8, 9, 10, 11x, 12 -x, 13x, 14x, x15, (x-4)^2, x17, 18x, 19x, 20x, 21x;
+matrix n[2][4] = 1, 2, 3, 4, x, x2, x3, x4;
+module mm = m;
+module nn = n;
+print(mm);
+print(nn);
+intmat gm[2][7] = 1, 2, 3, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0;
+intmat gn[2][2] = 0, 0, 1, 2;
+mm = setModuleGrading(mm, gm);
+nn = setModuleGrading(nn, gn);
+module mmtnn = multiDegTensor(mm, nn);
+*/
+}
+
+
+/******************************************************/
+proc isGroupHomomorphism(def L1, def L2, intmat A)
+"USAGE: isGoupHomomorphism(L1,L2,A); L1 and L2 are groups, A is an integer matrix
+PURPOSE: checks whether A defines a group homomorphism phi: L1 --> L2
+RETURN: int, 1 if A defines the homomorphism and 0 otherwise
+EXAMPLE: example isGroupHomomorphism; shows an example
+"
+{
+  // TODO: L1, L2
+  if( (ncols(A) != nrows(L1)) or (nrows(A) != nrows(L2)) )
+  {
+    ERROR("Incompatible sizes!");
+  }
+
+  intmat im = A * L1;
+
+  return  (areZeroElements(im, L2));
+}
+example
+{
+  "EXAMPLE:"; echo=2;
+
+   intmat L1[4][1]=
+     0,
+     0,
+     0,
+     2;
+
+   intmat L2[3][2]=
+     0, 0,
+     2, 0,
+     0, 3;
+
+  intmat A[3][4] =
+     1, 2, 3, 0,
+     7, 0, 0, 0,
+     1, 2, 0, 3;
+  print( A );
+
+  isGroupHomomorphism(L1, L2, A);
+
+  intmat B[3][4] =
+     1, 2, 3, 0,
+     7, 0, 0, 0,
+     1, 2, 0, 2;
+  print( B );
+
+  isGroupHomomorphism(L1, L2, B); // Not a homomorphism!
+}
+
+/******************************************************/
+proc isTorsionFree()
+"USAGE: isTorsionFree()
+PURPOSE: Determines whether the multigrading attached to the current ring is free.
+RETURN: boolean, the result of the test
+EXAMPLE: example isTorsionFree; shows an example
+"
+{
+  intmat H = smithNormalForm(getLattice()); // TODO: ?cache it?  //******
+
+  int i, j;
+  int r = nrows(H);
+  int c = ncols(H);
+  int d = 1;
+  for( i = 1; (i <= c) && (i <= r); i++ )
+  {
+    for( j = i; (H[j, i] == 0)&&(j < r); j++ )
+    {
+    }
+
+    if(H[j, i]!=0)
+    {
+      d=d*H[j, i];
+    }
+  }
+
+  if( (d*d)==1 )
+  {
+    return(1==1);
+  }
+  return(0==1);
+}
+example
+{
+  "EXAMPLE:"; echo=2;
+
+   ring R = 0,(x,y),dp;
+   intmat M[2][2]=
+     1,0,
+     0,1;
+   intmat T[2][5]=
+     1, 2, 3, 4, 0,
+     0,10,20,30, 1;
+
+   setBaseMultigrading(M,T);
+
+   // Is the resulting group  free?
+   isTorsionFree();
+
+   kill R, M, T;
+   ///////////////////////////////////////////
+
+   ring R=0,(x,y,z),dp;
+   intmat A[3][3] =
+     1,0,0,
+     0,1,0,
+     0,0,1;
+   intmat B[3][4]=
+     3,3,3,3,
+     2,1,3,0,
+     1,2,0,3;
+   setBaseMultigrading(A,B);
+   // Is the resulting group  free?
+   isTorsionFree();
+
+   kill R, A, B;
+}
+
+
+static proc gcdcomb(int a, int b)
+{
+  // a;
+  // b;
+  intvec av = a,1,0;
+  intvec bv = b,0,1;
+  intvec save;
+  while(av[1]*bv[1] != 0)
+  {
+    bv = bv - (bv[1] - bv[1]%av[1]) div av[1] * av;
+    save = bv;
+    bv = av;
+    av = save;
+  }
+  if(bv[1] < 0)
+  {
+    bv = -bv;
+  }
+  return(bv);
+}
+
+
+proc lll(def A)
+"
+The lll algorithm of NTL only works for intmat/matrix.
+This method will convert the input, call lll and
+return the result in the same format.
+(list of intvec resp. intmat)
+"
+{
+  if(typeof(A) == "list")
+  {
+    int sizeA= size (A);
+    if (sizeA == 0)
+    {
+      return (A);
+    }
+    if (typeof (A [1]) != "intvec")
+    {
+      ERROR("Unrecognized type.");
+    }
+    int columns= size (A [1]);
+    int i;
+    for (i= 2; i <= sizeA; i++)
+    {
+      if (typeof (A[i]) != "intvec")
+      {
+        ERROR("Unrecognized type.");
+      }
+      if (size (A [i]) != columns)
+      {
+        ERROR ("expected equal dimension");
+      }
+    }
+    int j;
+    intmat m [columns] [sizeA];
+    for (i= 1; i <= sizeA; i++)
+    {
+      for (j= 1; j <= columns; j++)
+      {
+        m[i,j]= A[i] [j];
+      }
+    }
+    m= system ("LLL", m);
+    list result;
+    intvec buf;
+
+    for (i= sizeA; i >=1 ; i--)
+    {
+      buf = intvec (m[i , 1..columns]);
+      result[i]= buf;
+    }
+    return(result);
+  }
+  else
+  {
+    if(typeof(A) == "intmat")
+    {
+      A= system ("LLL", A);
+      return(A);
+    }
+    else
+    {
+      ERROR("Unrecognized type.");
+    }
+  }
+}
+example
+{
+  "EXAMPLE:"; echo=2;
+
+  ring R = 0,x,dp;
+  intmat m[5][5] =
+                  13,25,37,83,294,
+                  12,-33,9,0,64,
+                  77,12,34,6,1,
+                  43,2,88,91,100,
+                  -46,32,37,42,15;
+  lll(m);
+
+  list l =
+      intvec(13,25,37, 83, 294),
+      intvec(12, -33, 9,0,64),
+      intvec (77,12,34,6,1),
+      intvec (43,2,88,91,100),
+      intvec (-46,32,37,42,15);
+  lll(l);
+}
+
+
+proc smithNormalForm(intmat A, list #)
+"USAGE: smithNormalForm(A[,opt]); intmat A
+PURPOSE: Computes the Smith Normal Form of A
+RETURN: if no optional argument is given: intmat, the Smith Normal Form of A,
+otherwise: a list of 3 integer matrices P, D Q, such that D == P*A*Q.
+EXAMPLE: example smithNormalForm; shows an example
+"
+{
+  list l1 = hermiteNormalForm(A, 5);
+  // l1;
+  intmat B = transpose(l1[1]);
+  list l2 = hermiteNormalForm(B, 5);
+  // l2;
+  intmat P = transpose(l2[2]);
+  intmat D = transpose(l2[1]);
+  intmat Q = l1[2];
+  int cc = ncols(D);
+  int rr = nrows(D);
+  intmat transform;
+  int k = 1;
+  int a, b, c;
+  // D;
+  intvec v;
+  if((cc==1)||(rr==1)){
+    if(size(#)==0)
+    {
+      return(D);
+    } else
+    {
+      return(list(P,D,Q));
+    }
+  }
+  while(D[k+1,k+1] !=0){
+    if(D[k+1,k+1]%D[k,k]!=0){
+      b = D[k, k]; c = D[k+1, k+1];
+      v = gcdcomb(D[k,k],D[k+1,k+1]);
+      transform = unitMatrix(cc);
+      transform[k+1,k] = 1;
+      a = -v[3]*D[k+1,k+1] div v[1];
+      transform[k, k+1] = a;
+      transform[k+1, k+1] = a+1;
+      //det(transform);
+      D = D*transform;
+      Q = Q*transform;
+      //D;
+      transform = unitMatrix(rr);
+      transform[k,k] = v[2];
+      transform[k,k+1] = v[3];
+      transform[k+1,k] = -c div v[1];
+      transform[k+1,k+1] = b div v[1];
+      D = transform * D;
+      P = transform * P;
+      //" ";
+      //D;
+      //"small transform: ", det(transform);
+      //transform;
+      k=0;
+    }
+    k++;
+    if((k==rr) || (k==cc)){
+      break;
+    }
+  }
+  //"here is the size ",size(#);
+  if(size(#) == 0){
+    return(D);
+  } else {
+    return(list(P, D, Q));
+  }
+}
+example
+{
+  "EXAMPLE:"; echo=2;
+
+
+  intmat A[5][7] =
+                  1,0,1,0,-2,9,-71,
+                  0,-24,248,-32,-96,448,-3496,
+                  0,4,-42,4,-8,30,-260,
+                  0,0,0,18,-90,408,-3168,
+                  0,0,0,-32,224,-1008,7872;
+
+  print( smithNormalForm(A) );
+
+  list l = smithNormalForm(A, 5);
+
+  l;
+
+  l[1]*A*l[3];
+
+  det(l[1]);
+  det(l[3]);
+}
+
+
+/******************************************************/
+proc hermiteNormalForm(intmat A, list #)
+"USAGE: hermiteNormalForm( A );
+PURPOSE: Computes the (lower triangular) Hermite Normal Form
+           of the matrix A by column operations.
+RETURN: intmat, the Hermite Normal Form of A
+EXAMPLE: example hermiteNormalForm; shows an example
+"
+{
+
+  int row, column, i, j;
+  int rr = nrows(A);
+  int cc = ncols(A);
+  intvec savev, gcdvec, v1, v2;
+  intmat q = unitMatrix(cc);
+  intmat transform;
+  column = 1;
+  for(row = 1; (row<=rr)&&(column<=cc); row++)
+    {
+      if(A[row,column]==0)
+        {
+          for(j = column; j<=cc; j++)
+            {
+              if(A[row, j]!=0)
+                {
+                  transform = unitMatrix(cc);
+                  transform[j,j] = 0;
+                  transform[column, column] = 0;
+                  transform[column,j] = 1;
+                  transform[j,column] = 1;
+                  q = q*transform;
+                  A = A*transform;
+                  break;
+                }
+            }
+        }
+      if(A[row,column] == 0)
+        {
+          row++;
+          continue;
+        }
+      for(j = column+1; j<=cc; j++)
+        {
+          if(A[row, j]!=0)
+            {
+              gcdvec = gcdcomb(A[row,column],A[row,j]);
+              // gcdvec;
+              // typeof(A[1..rr,column]);
+              v1 = A[1..rr,column];
+              v2 = A[1..rr,j];
+              transform = unitMatrix(cc);
+              transform[j,j] = v1[row] div gcdvec[1];
+              transform[column, column] = gcdvec[2];
+              transform[column,j] = -v2[row] div gcdvec[1];
+              transform[j,column] = gcdvec[3];
+              q = q*transform;
+              A = A*transform;
+              // A;
+            }
+        }
+      if(A[row,column]<0)
+        {
+          transform = unitMatrix(cc);
+          transform[column,column] = -1;
+          q = q*transform;
+          A = A*transform;
+        }
+      for( j=1; j<column; j++){
+        if(A[row, j]!=0){
+          transform = unitMatrix(cc);
+          transform[column, j] = (-A[row,j]+A[row, j]%A[row, column]) div A[row, column];
+          if(A[row,j]<0){
+            transform[column,j]=transform[column,j]+1;}
+          q = q*transform;
+          A = A*transform;
+        }
+      }
+      column++;
+    }
+  if(size(#) > 0){
+    return(list(A, q));
+  }
+  return(A);
+}
+example
+{
+  "EXAMPLE:"; echo=2;
+
+   intmat M[2][5] =
+     1, 2, 3, 4, 0,
+     0,10,20,30, 1;
+
+   // Hermite Normal Form of M:
+   print(hermiteNormalForm(M));
+
+   intmat T[3][4] =
+     3,3,3,3,
+     2,1,3,0,
+     1,2,0,3;
+
+   // Hermite Normal Form of T:
+   print(hermiteNormalForm(T));
+
+   intmat A[4][5] =
+     1,2,3,2,2,
+     1,2,3,4,0,
+     0,5,4,2,1,
+     3,2,4,0,2;
+
+   // Hermite Normal Form of A:
+   print(hermiteNormalForm(A));
+}
+
+proc areZeroElements(intmat m, list #)
+"USAGE: areZeroElements(D, [T]); intmat D, group T
+PURPOSE: For a integer matrix D, considered column-wise as a set of
+   integer vecors representing the multidegree of some polynomial
+   or vector this method checks whether all these multidegrees
+   are contained in the grading group
+   group (either set globally or given as an optional argument),
+i.e. if they all are zero in the multigrading.
+EXAMPLE: example areZeroElements; shows an example
+"
+{
+  int r = nrows(m);
+  int i = ncols(m);
+
+  intvec v;
+
+  for( ; i > 0; i-- )
+  {
+    v = m[1..r, i];
+    if( !isZeroElement(v, #) )
+    {
+      return (0);
+    }
+  }
+  return(1);
+}
+example
+{
+  "EXAMPLE:"; echo=2;
+
+  ring r = 0,(x,y,z),dp;
+
+  intmat S[2][3]=
+    1,0,1,
+    0,1,1;
+
+  intmat L[2][1]=
+    2,
+    2;
+
+  setBaseMultigrading(S,L);
+
+  poly a = 1;
+  poly b = xyz;
+
+  ideal I = a, b;
+  print(multiDeg(I));
+
+  intmat m[5][2]=multiDeg(a),multiDeg(b); m=transpose(m);
+
+  print(multiDeg(a));
+  print(multiDeg(b));
+
+  print(m);
+
+  areZeroElements(m);
+
+  intmat LL[2][1]=
+     1,
+    -1;
+
+  areZeroElements(m,LL);
+}
+
+
+/******************************************************/
+proc isZeroElement(intvec mdeg, list #)
+"USAGE: isZeroElement(d, [T]); intvec d, group T
+PURPOSE: For a integer vector 'd' representing the multidegree of some polynomial
+or vector this method computes if the multidegree is contained in the grading group
+group (either set globally or given as an optional argument), i.e. if it is zero in the multigrading.
+EXAMPLE: example isZeroElement; shows an example
+"
+{
+  int i = 1;
+  if( size(#) >= i )
+  {
+    def a = #[1];
+    if( typeof(a) == "intmat" )
+    {
+      intmat H = hermiteNormalForm(a);
+      i++;
+    }
+    if( typeof(a) == "list" )
+    {
+      list L = a;
+      intmat H = attrib(L, "hermite"); // todo
+      i++;
+    }
+    kill a;
+  }
+
+  if( i == 1 )
+  {
+    intmat H = getLattice("hermite");
+  }
+
+  int x, k, row;
+
+  int r = nrows(H);
+  int c = ncols(H);
+
+  int rr = nrows(mdeg);
+  row = 1;
+  intvec v;
+  for(i=1; (i<=r)&&(row<=r)&&(i<=c); i++)
+  {
+    while((H[row,i]==0)&&(row<=r))
+    {
+      row++;
+      if(row == (r+1)){
+        break;
+      }
+    }
+    if(row<=r){
+      if(H[row,i]!=0)
+      {
+        v = H[1..r,i];
+        mdeg = mdeg-(mdeg[row]-mdeg[row]%v[row]) div v[row]*v;
+      }
+    }
+  }
+  return( mdeg == 0 );
+
+}
+example
+{
+ "EXAMPLE:"; echo=2;
+
+  ring r = 0,(x,y,z),dp;
+
+  intmat g[2][3]=
+    1,0,1,
+    0,1,1;
+  intmat t[2][1]=
+    -2,
+    1;
+
+  intmat tt[2][1]=
+    1,
+    -1;
+
+  setBaseMultigrading(g,t);
+
+  poly a = x10yz;
+  poly b = x8y2z;
+  poly c = x4z2;
+  poly d = y5;
+  poly e = x2y2;
+  poly f = z2;
+
+  intvec v1 = multiDeg(a) - multiDeg(b);
+  v1;
+  isZeroElement(v1);
+  isZeroElement(v1, tt);
+
+  intvec v2 = multiDeg(a) - multiDeg(c);
+  v2;
+  isZeroElement(v2);
+  isZeroElement(v2, tt);
+
+  intvec v3 = multiDeg(e) - multiDeg(f);
+  v3;
+  isZeroElement(v3);
+  isZeroElement(v3, tt);
+
+  intvec v4 = multiDeg(c) - multiDeg(d);
+  v4;
+  isZeroElement(v4);
+  isZeroElement(v4, tt);
+}
+
+
+/******************************************************/
+proc defineHomogeneous(poly f, list #)
+"USAGE: defineHomogeneous(f[, G]); polynomial f, integer matrix G
+PURPOSE: Yields a matrix which has to be appended to the grading group matrix to make the
+polynomial f homogeneous in the grading by grad.
+EXAMPLE: example defineHomogeneous; shows an example
+"
+{
+  int i = 1;
+  if( size(#) >= i )
+  {
+    def a = #[1];
+    if( typeof(a) == "intmat" )
+    {
+      intmat grad = a;
+      i++;
+    }
+    kill a;
+  }
+
+  if( i == 1 )
+  {
+    intmat grad = getVariableWeights();
+  }
+
+  intmat newgg[nrows(grad)][size(f)-1];
+  int j;
+  intvec l = grad*leadexp(f);
+  intvec v;
+  for(i=2; i <= size(f); i++)
+  {
+    v = grad * leadexp(f[i]) - l;
+    for( j=1; j<=size(v); j++)
+    {
+      newgg[j,i-1] = v[j];
+    }
+  }
+  return(newgg);
+}
+example
+{
+  "EXAMPLE:"; echo=2;
+
+  ring r =0,(x,y,z),dp;
+  intmat grad[2][3] =
+    1,0,1,
+    0,1,1;
+
+  setBaseMultigrading(grad);
+
+  poly f = x2y3-z5+x-3zx;
+
+  intmat M = defineHomogeneous(f);
+  M;
+  defineHomogeneous(f, grad) == M;
+
+  isHomogeneous(f);
+  setBaseMultigrading(grad, M);
+  isHomogeneous(f);
+}
+
+
+proc gradiator(def h)
+"PURPOSE: coarsens the grading of the basering until the polynom or ideal h becomes homogeneous."
+{
+  if(typeof(h)=="poly"){
+    intmat W = getVariableWeights();
+    intmat L = getLattice();
+    intmat toadd = defineHomogeneous(h);
+    //h;
+    //toadd;
+    if(ncols(toadd) == 0)
+    {
+      return(1==1);
+    }
+    int rr = nrows(W);
+    intmat newL[rr][ncols(L)+ncols(toadd)];
+    newL[1..rr,1..ncols(L)] = L[1..rr,1..ncols(L)];
+    newL[1..rr,(ncols(L)+1)..(ncols(L)+ncols(toadd))] = toadd[1..rr,1..ncols(toadd)];
+    setBaseMultigrading(W,newL);
+    return(1==1);
+  }
+  if(typeof(h)=="ideal"){
+    int i;
+    def s = (1==1);
+    for(i=1;i<=size(h);i++){
+      s = s && gradiator(h[i]);
+    }
+    return(s);
+  }
+  return(1==0);
+}
+example
+{
+  "EXAMPLE:"; echo=2;
+
+ring r = 0,(x,y,z),dp;
+intmat g[2][3] = 1,0,1,0,1,1;
+intmat l[2][1] = 3,0;
+
+setBaseMultigrading(g,l);
+
+getLattice();
+
+ideal i = -y5+x4,
+          y6+xz,
+          x2y;
+gradiator(i);
+getLattice();
+isHomogeneous(i);
+}
+
+
+proc pushForward(map f)
+"USAGE: pushForward(f);
+PURPOSE: Computes the finest grading of the image ring which makes the map f
+a map of graded rings. The group map between the two grading groups is given
+by transpose( (Id, 0) ). Pay attention that the group spanned by the columns of
+the grading group matrix may not be a subgroup of the grading group. Still all columns
+are needed to find the correct image of the preimage gradings.
+EXAMPLE: example pushForward; shows an example
+"
+{
+
+  int k,i,j;
+//  f;
+
+//  listvar();
+  def pre = preimage(f);
+
+//  "pre: ";  pre;
+
+  intmat oldgrad=getVariableWeights(pre);
+  intmat oldlat=getLattice(pre);
+
+  int n=nvars(pre);
+  int np=nvars(basering);
+  int p=nrows(oldgrad);
+  int pp=p+np;
+
+  intmat newgrad[pp][np];
+
+  //This will set the finest grading on the image ring. We will proceed by coarsening this grading until f becomes homogeneous.
+  for(i=1;i<=np;i++){ newgrad[p+i,i]=1;}
+
+  //newgrad;
+
+
+
+  list newlat;
+  intmat toadd;
+  int columns=0;
+
+  intmat toadd1[pp][n];
+  intvec v;
+  poly im;
+
+  for(i=1;i<=p;i++){
+    for(j=1;j<=n;j++){ toadd1[i,j]=oldgrad[i,j];}
+  }
+
+  // This will make the images of homogeneous elements homogeneous, namely the variables of the preimage ring.
+  for(i=1;i<=n;i++){
+    im=f[i];
+    //im;
+    toadd = defineHomogeneous(im, newgrad);
+    newlat=insert(newlat,toadd);
+    columns=columns+ncols(toadd);
+
+    v=leadexp(f[i]);
+    for(j=p+1;j<=p+np;j++){ toadd1[j,i]=-v[j-p];}
+  }
+
+  newlat=insert(newlat,toadd1);
+  columns=columns+ncols(toadd1);
+
+  //If the image ring is a quotient ring by some ideal, we have to coarsen the grading in order to make the ideal homogeneous.
+  if(typeof(basering)=="qring"){
+    //"Entering qring";
+    ideal a=ideal(basering);
+    for(i=1;i<=size(a);i++){
+      toadd = defineHomogeneous(a[i], newgrad);
+      //toadd;
+      columns=columns+ncols(toadd);
+      newlat=insert(newlat,toadd);
+    }
+  }
+
+  //The grading group of the preimage ring might not have been torsion free. We have to add this torsion to the grading group of the image ring.
+  intmat imofoldlat[pp][ncols(oldlat)];
+  for(i=1; i<=nrows(oldlat);i++){
+    for(j=1; j<=ncols(oldlat); j++){
+      imofoldlat[i,j]=oldlat[i,j];
+    }
+  }
+
+  columns=columns+ncols(oldlat);
+  newlat=insert(newlat, imofoldlat);
+
+  intmat gragr[pp][columns];
+  columns=0;
+  for(k=1;k<=size(newlat);k++){
+    for(i=1;i<=pp;i++){
+      for(j=1;j<=ncols(newlat[k]);j++){gragr[i,j+columns]=newlat[k][i,j];}
+    }
+    columns=columns+ncols(newlat[k]);
+  }
+
+  //The following is just for reducing the size of the matrices.
+  gragr=hermiteNormalForm(gragr);
+  intmat result[pp][pp];
+  for(i=1;i<=pp;i++){
+    for(j=1;j<=pp;j++){result[i,j]=gragr[i,j];}
+  }
+
+  setBaseMultigrading(newgrad, result);
+
+}
+example
+{
+  "EXAMPLE:"; echo=2;
+
+  ring r = 0,(x,y,z),dp;
+
+
+
+  // Setting degrees for preimage ring.;
+  intmat grad[3][3] =
+    1,0,0,
+    0,1,0,
+    0,0,1;
+
+  setBaseMultigrading(grad);
+
+  // grading on r:
+  getVariableWeights();
+  getLattice();
+
+  // only for the purpose of this example
+  if( voice > 1 ){ /*keepring(r);*/ export(r); }
+
+  ring R = 0,(a,b),dp;
+  ideal i = a2-b2+a6-b5+ab3,a7b+b15-ab6+a6b6;
+
+  // The quotient ring by this ideal will become our image ring.;
+  qring Q = std(i);
+
+  listvar();
+
+  map f = r,-a2b6+b5+a3b+a2+ab,-a2b7-3a2b5+b4+a,a6-b6-b3+a2; f;
+
+
+  // TODO: Unfortunately this is not a very spectacular example...:
+  // Pushing forward f:
+  pushForward(f);
+
+  // due to pushForward we have got new grading on Q
+  getVariableWeights();
+  getLattice();
+
+
+  // only for the purpose of this example
+  if( voice > 1 ){ kill r; }
+
+}
+
+
+/******************************************************/
+proc equalMultiDeg(intvec exp1, intvec exp2, list #)
+"USAGE: equalMultiDeg(exp1, exp2[, V]); intvec exp1, exp2, intmat V
+PURPOSE: Tests if the exponent vectors of two monomials (given by exp1 and exp2)
+represent the same multidegree.
+NOTE: the integer matrix V encodes multidegrees of module components,
+if module component is present in exp1 and exp2
+EXAMPLE: example equalMultiDeg; shows an example
+"
+{
+  if( size(exp1) != size(exp2) )
+  {
+    ERROR("Sorry: we cannot compare exponents comming from a polynomial and a vector yet!");
+  }
+
+  if( exp1 == exp2)
+  {
+    return (1==1);
+  }
+
+
+
+  intmat M = getVariableWeights();
+
+  if( nrows(exp1) > ncols(M) ) // vectors => last exponent is the module component!
+  {
+    if( (size(#) == 0) or (typeof(#[1])!="intmat") )
+    {
+      ERROR("Sorry: wrong or missing module-unit-weights-matrix V!");
+    }
+    intmat V = #[1];
+
+    // typeof(V); print(V);
+
+    int N = ncols(M);
+    int r = nrows(M);
+
+    intvec d = intvec(exp1[1..N]) - intvec(exp2[1..N]);
+    intvec dm = intvec(V[1..r, exp1[N+1]]) - intvec(V[1..r, exp2[N+1]]);
+
+    intvec difference = M * d + dm;
+  }
+  else
+  {
+    intvec d = (exp1 - exp2);
+    intvec difference = M * d;
+  }
+
+  if (isFreeRepresented()) // no grading group!?
+  {
+    return ( difference == 0);
+  }
+  return ( isZeroElement( difference ) );
+}
+example
+{
+  "EXAMPLE:"; echo=2;printlevel=3;
+
+  ring r = 0,(x,y,z),dp;
+
+  intmat g[2][3]=
+    1,0,1,
+    0,1,1;
+
+  intmat t[2][1]=
+    -2,
+    1;
+
+  setBaseMultigrading(g,t);
+
+  poly a = x10yz;
+  poly b = x8y2z;
+  poly c = x4z2;
+  poly d = y5;
+  poly e = x2y2;
+  poly f = z2;
+
+
+  equalMultiDeg(leadexp(a), leadexp(b));
+  equalMultiDeg(leadexp(a), leadexp(c));
+  equalMultiDeg(leadexp(a), leadexp(d));
+  equalMultiDeg(leadexp(a), leadexp(e));
+  equalMultiDeg(leadexp(a), leadexp(f));
+
+  equalMultiDeg(leadexp(b), leadexp(c));
+  equalMultiDeg(leadexp(b), leadexp(d));
+  equalMultiDeg(leadexp(b), leadexp(e));
+  equalMultiDeg(leadexp(b), leadexp(f));
+
+  equalMultiDeg(leadexp(c), leadexp(d));
+  equalMultiDeg(leadexp(c), leadexp(e));
+  equalMultiDeg(leadexp(c), leadexp(f));
+
+  equalMultiDeg(leadexp(d), leadexp(e));
+  equalMultiDeg(leadexp(d), leadexp(f));
+
+  equalMultiDeg(leadexp(e), leadexp(f));
+
+}
+
+
+
+/******************************************************/
+static proc isFreeRepresented()
+"check whether the base muligrading is free (it is zero).
+"
+{
+  intmat T = getLattice();
+
+  intmat Z[nrows(T)][ncols(T)];
+
+  return (T == Z); // no grading group!
+}
+
+
+/******************************************************/
+proc isHomogeneous(def a, list #)
+"USAGE: isHomogeneous(a[, f]); a polynomial/vector/ideal/module
+RETURN: boolean, TRUE if a is (multi)homogeneous, and FALSE otherwise
+EXAMPLE: example isHomogeneous; shows an example
+"
+{
+  if( (typeof(a) == "poly") or (typeof(a) == "vector") )
+  {
+    return ( size(multiDegPartition(a)) <= 1 )
+  }
+
+  if( (typeof(a) == "ideal") or (typeof(a) == "module") )
+  {
+    if(size(#) > 0)
+    {
+      if (#[1] == "checkGens")
+      {
+        def aa;
+        for( int i = ncols(a); i > 0; i-- )
+        {
+          aa = getGradedGenerator(a, i);
+
+          if(!isHomogeneous(aa))
+          {
+            return(0==1);
+          }
+        }
+        return(1==1);
+      }
+    }
+
+    def g = groebner(a); // !!!!
+
+    def b, aa; int j;
+    for( int i = ncols(a); i > 0; i-- )
+    {
+      aa = getGradedGenerator(a, i);
+
+      b = multiDegPartition(aa);
+      for( j = ncols(b); j > 0; j-- )
+      {
+        if(NF(b[j],g) != 0)
+        {
+          return(0==1);
+        }
+      }
+    }
+    return(1==1);
+  }
+}
+example
+{
+  "EXAMPLE:"; echo=2;
+
+  ring r = 0,(x,y,z),dp;
+
+  //Grading and Torsion matrices:
+  intmat M[3][3] =
+    1,0,0,
+    0,1,0,
+    0,0,1;
+
+  intmat T[3][1] =
+    1,2,3;
+
+  setBaseMultigrading(M,T);
+
+  attrib(r);
+
+  poly f = x-yz;
+
+  multiDegPartition(f);
+  print(multiDeg(_));
+
+  isHomogeneous(f);   // f: is not homogeneous
+
+  poly g = 1-xy2z3;
+  isHomogeneous(g); // g: is homogeneous
+  multiDegPartition(g);
+
+  kill T;
+  /////////////////////////////////////////////////////////
+  // new Torsion matrix:
+  intmat T[3][4] =
+    3,3,3,3,
+    2,1,3,0,
+    1,2,0,3;
+
+  setBaseMultigrading(M,T);
+
+  f;
+  isHomogeneous(f);
+  multiDegPartition(f);
+
+  // ---------------------
+  g;
+  isHomogeneous(g);
+  multiDegPartition(g);
+
+  kill r, T, M;
+
+  ring R = 0, (x,y,z), dp;
+
+  intmat A[2][3] =
+    0,0,1,
+    3,2,1;
+  intmat T[2][1] =
+    -1,
+     4;
+  setBaseMultigrading(A, T);
+
+  isHomogeneous(ideal(x2 - y3 -xy +z, x*y-z, x^3 - y^2*z + x^2 -y^3)); // 1
+  isHomogeneous(ideal(x2 - y3 -xy +z, x*y-z, x^3 - y^2*z + x^2 -y^3), "checkGens");
+  isHomogeneous(ideal(x+y, x2 - y2)); // 0
+
+  // Degree partition:
+  multiDegPartition(x2 - y3 -xy +z);
+  multiDegPartition(x3 -y2z + x2 -y3 + z + 1);
+
+
+  module N = gen(1) + (x+y) * gen(2), z*gen(3);
+
+  intmat V[2][3] = 0; // 1, 2, 3,  4, 5, 6; //  column-wise weights of components!!??
+
+  vector v1, v2;
+
+  v1 = setModuleGrading(N[1], V); v1;
+  multiDegPartition(v1);
+  print( multiDeg(_) );
+
+  v2 = setModuleGrading(N[2], V); v2;
+  multiDegPartition(v2);
+  print( multiDeg(_) );
+
+  N = setModuleGrading(N, V);
+  isHomogeneous(N);
+  print( multiDeg(N) );
+
+  ///////////////////////////////////////
+
+  V =
+    1, 2, 3,
+    4, 5, 6;
+
+  v1 = setModuleGrading(N[1], V); v1;
+  multiDegPartition(v1);
+  print( multiDeg(_) );
+
+  v2 = setModuleGrading(N[2], V); v2;
+  multiDegPartition(v2);
+  print( multiDeg(_) );
+
+  N = setModuleGrading(N, V);
+  isHomogeneous(N);
+  print( multiDeg(N) );
+
+  ///////////////////////////////////////
+
+  V =
+    0, 0, 0,
+    4, 1, 0;
+
+  N = gen(1) + x * gen(2), z*gen(3);
+  N = setModuleGrading(N, V); print(N);
+  isHomogeneous(N);
+  print( multiDeg(N) );
+  v1 = getGradedGenerator(N,1); print(v1);
+  multiDegPartition(v1);
+  print( multiDeg(_) );
+  N = setModuleGrading(N, V); print(N);
+  isHomogeneous(N);
+  print( multiDeg(N) );
+}
+
+/******************************************************/
+proc multiDeg(def A)
+"USAGE: multiDeg(A); polynomial/vector/ideal/module A
+PURPOSE: compute multidegree
+EXAMPLE: example multiDeg; shows an example
+"
+{
+  def a = attrib(A, "grad");
+  if( typeof(a) == "intvec" || typeof(a) == "intmat" )
+  {
+    return (a);
+  }
+
+  intmat M = getVariableWeights();
+  int N = nvars(basering);
+
+  if( ncols(M) != N )
+  {
+    ERROR("Sorry wrong mgrad-size of M: " + string(ncols(M)));
+  }
+
+  int r = nrows(M);
+
+  if( (typeof(A) == "vector") or (typeof(A) == "module") )
+  {
+    intmat V = getModuleGrading(A);
+
+    if( nrows(V) != r )
+    {
+      ERROR("Sorry wrong mgrad-size of V: " + string(nrows(V)));
+    }
+  }
+
+  if( A == 0 )
+  {
+    intvec v; v[r] = 0;
+    return (v);
+  }
+
+  intvec m; m[r] = 0;
+
+  if( typeof(A) == "poly" )
+  {
+    intvec v = leadexp(A); //  v;
+    m = M * v;
+
+    // We assume homogeneous input!
+    return(m);
+
+    A = A - lead(A);
+    while( size(A) > 0 )
+    {
+      v = leadexp(A); //  v;
+      m = max( m, M * v, r ); // ????
+      A = A - lead(A);
+    }
+
+    return(m);
+  }
+
+
+  if( typeof(A) == "vector" )
+  {
+    intvec v;
+    v = leadexp(A); //  v;
+    m = intvec(M * intvec(v[1..N])) + intvec(V[1..r, v[N+1]]);
+
+    // We assume homogeneous input!
+    return(m);
+
+    A = A - lead(A);
+    while( size(A) > 0 )
+    {
+      v = leadexp(A); //  v;
+
+      // intvec(M * intvec(v[1..N])) + intvec(V[1..r, v[N+1]]);
+
+      m = max( m, intvec(M * intvec(v[1..N])) + intvec(V[1..r, v[N+1]]), r ); // ???
+
+      A = A - lead(A);
+    }
+
+    return(m);
+  }
+
+  int i, j; intvec d;
+
+  if( typeof(A) == "ideal" )
+  {
+    intmat G[ r ] [ ncols(A)];
+    for( i = ncols(A); i > 0; i-- )
+    {
+      d = multiDeg( A[i] );
+
+      for( j = 1; j <= r; j++ ) // see ticket: 253
+      {
+        G[j, i] = d[j];
+      }
+    }
+    return(G);
+  }
+
+  if( typeof(A) == "module" )
+  {
+    intmat G[ r ] [ ncols(A)];
+    vector v;
+
+    for( i = ncols(A); i > 0; i-- )
+    {
+      v = getGradedGenerator(A, i);
+
+      // G[1..r, i]
+      d = multiDeg(v);
+
+      for( j = 1; j <= r; j++ ) // see ticket: 253
+      {
+        G[j, i] = d[j];
+      }
+
+    }
+
+    return(G);
+  }
+
+}
+example
+{
+  "EXAMPLE:"; echo=2;
+
+  ring r = 0,(x, y), dp;
+
+  intmat A[2][2] = 1, 0, 0, 1;
+  print(A);
+
+  intmat Ta[2][1] = 0, 3;
+  print(Ta);
+
+  //   attrib(A, "gradingGroup", Ta); // to think about
+
+//  "poly:";
+  setBaseMultigrading(A);
+
+
+  multiDeg( x*x, A );
+  multiDeg( y*y*y, A );
+
+  setBaseMultigrading(A, Ta);
+
+  multiDeg( x*x*y );
+
+  multiDeg( y*y*y*x );
+
+  multiDeg( x*y + x + 1 );
+
+  multiDegPartition(x*y + x + 1);
+
+  print ( multiDeg(0) );
+  poly zero = 0;
+  print ( multiDeg(zero) );
+
+//  "ideal:";
+
+  ideal I = y*x*x, x*y*y*y;
+  print( multiDeg(I) );
+
+  print ( multiDeg(ideal(0)) );
+  print ( multiDeg(ideal(0,0,0)) );
+
+//  "vectors:";
+
+  intmat B[2][2] = 0, 1, 1, 0;
+  print(B);
+
+  multiDeg( setModuleGrading(y*y*y*gen(2), B ));
+  multiDeg( setModuleGrading(x*x*gen(1), B ));
+
+
+  vector V = x*gen(1) + y*gen(2);
+  V = setModuleGrading(V, B);
+  multiDeg( V );
+
+  vector v1 = setModuleGrading([0, 0, 0], B);
+  print( multiDeg( v1 ) );
+
+  vector v2 = setModuleGrading([0], B);
+  print( multiDeg( v2 ) );
+
+//  "module:";
+
+  module D = x*gen(1), y*gen(2);
+  D;
+  D = setModuleGrading(D, B);
+  print( multiDeg( D ) );
+
+
+  module DD = [0, 0],[0, 0, 0];
+  DD = setModuleGrading(DD, B);
+  print( multiDeg( DD ) );
+
+  module DDD = [0, 0];
+  DDD = setModuleGrading(DDD, B);
+  print( multiDeg( DDD ) );
+
+};
+
+
+
+
+
+/******************************************************/
+proc multiDegPartition(def p)
+"USAGE: multiDegPartition(def p), p polynomial/vector
+RETURNS: an ideal/module consisting of multigraded-homogeneous parts of p
+EXAMPLE: example multiDegPartition; shows an example
+"
+{ // TODO: What about an ideal or module???
+
+  if( typeof(p) == "poly" )
+  {
+    ideal I;
+    poly mp, t, tt;
+    intmat V;
+  }
+  else
+  {
+    if(  typeof(p) == "vector" )
+    {
+      module I;
+      vector mp, t, tt;
+      intmat V = getModuleGrading(p);
+    }
+    else
+    {
+      ERROR("Wrong ARGUMENT type!");
+    }
+  }
+
+  if( size(p) > 1)
+  {
+    intvec m;
+
+    while( p != 0 )
+    {
+      m = leadexp(p);
+      mp = lead(p);
+      p = p - lead(p);
+      tt = p; t = 0;
+
+      while( size(tt) > 0 )
+      {
+        // TODO: we do not cache matrices (M,T,H,V), which remain the same :(
+        // TODO: we need some low-level procedure with all these arguments...!
+        if( equalMultiDeg( leadexp(tt), m, V  ) )
+        {
+          mp = mp + lead(tt); // "mp", mp;
+        }
+        else
+        {
+          t = t + lead(tt);  //  "t", t;
+        }
+
+        tt = tt - lead(tt);
+      }
+
+      I[size(I)+1] = mp;
+
+      p = t;
+    }
+  }
+  else
+  {
+    I[1] = p; // single monom
+  }
+
+  if( typeof(I) == "module" )
+  {
+    I = setModuleGrading(I, V);
+  }
+
+  return (I);
+}
+example
+{
+  "EXAMPLE:"; echo=2;
+
+  ring r = 0,(x,y,z),dp;
+
+  intmat g[2][3]=
+    1,0,1,
+    0,1,1;
+  intmat t[2][1]=
+    -2,
+    1;
+
+  setBaseMultigrading(g,t);
+
+  poly f = x10yz+x8y2z-x4z2+y5+x2y2-z2+x17z3-y6;
+
+  multiDegPartition(f);
+
+  vector v = xy*gen(1)-x3y2*gen(2)+x4y*gen(3);
+  intmat B[2][3]=1,-1,-2,0,0,1;
+  v = setModuleGrading(v,B);
+  getModuleGrading(v);
+
+  multiDegPartition(v, B);
+}
+
+
+
+/******************************************************/
+static proc unitMatrix(int n)
+{
+  intmat A[n][n];
+
+  for( int i = n; i > 0; i-- )
+  {
+    A[i,i] = 1;
+  }
+
+  return (A);
+}
+
+
+
+/******************************************************/
+static proc finestMDeg(def r)
+"
+USAGE: finestMDeg(r); ring r
+RETURN: ring, r endowed with the finest multigrading
+TODO: not yet...
+"
+{
+  def save = basering;
+  setring (r);
+
+  // in basering
+      ideal I = ideal(basering);
+
+  int n = 0; int i; poly p;
+  for( i = ncols(I); i > 0; i-- )
+  {
+    p = I[i];
+    if( size(p) > 1 )
+    {
+      n = n + (size(p) - 1);
+    }
+    else
+    {
+      I[i] = 0;
+    }
+  }
+
+  int N = nvars(basering);
+  intmat A = unitMatrix(N);
+
+
+
+  if( n > 0)
+  {
+
+    intmat L[N][n];
+    //  list L;
+    int j = n;
+
+    for(  i = ncols(I); i > 0; i-- )
+    {
+      p = I[i];
+
+      if( size(p) > 1 )
+      {
+        intvec m0 = leadexp(p);
+        p = p - lead(p);
+
+        while( size(p) > 0 )
+        {
+          L[ 1..N, j ] = leadexp(p) - m0;
+          p = p - lead(p);
+          j--;
+        }
+      }
+    }
+
+    print(L);
+    setBaseMultigrading(A, L);
+  }
+  else
+  {
+    setBaseMultigrading(A);
+  }
+
+  //  ERROR("nope");
+
+  //  ring T = integer, (x), (C, dp);
+
+  setring(save);
+  return (r);
+}
+example
+{
+  "EXAMPLE:"; echo=2;
+
+  ring r = 0,(x, y), dp;
+  qring q  = std(x^2 - y);
+
+  finestMDeg(q);
+
+}
+
+
+
+
+/******************************************************/
+static proc newMap(map F, intmat Q, list #)
+"
+USAGE: newMap(F, Q[, P]); map F, intmat Q[, intmat P]
+PURPOSE: endowe the map F with the integer matrices P [and Q]
+"
+{
+  attrib(F, "Q", Q);
+
+  if( size(#) > 0 and typeof(#[1]) == "intmat" )
+  {
+    attrib(F, "P", #[1]);
+  }
+  return (F);
+}
+
+/******************************************************/
+static proc matrix2intmat( matrix M )
+{
+  execute( "intmat A[ "+ string(nrows(M)) + "]["+ string(ncols(M)) + "] = " + string(M) + ";" );
+  return (A);
+}
+
+
+/******************************************************/
+static proc leftKernelZ(intmat M)
+"USAGE:  leftKernel(M);   M a matrix
+RETURN:  module
+PURPOSE: computes left kernel of matrix M (a module of all elements v such that vM=0)
+EXAMPLE: example leftKernel; shows an example
+"
+{
+  int @bf = 0;
+  if( nameof(basering) != "basering" )
+  {
+    @bf = 1;
+    def @save@ = basering;
+  }
+
+  ring r = integer, (x), dp;
+
+
+  //  basering;
+  module N = matrix((M)); // transpose
+  //  print(N);
+
+  def MM = modulo( N, std(0) ) ;
+  //  print(MM);
+
+  intmat R = (  matrix2intmat( MM ) ); // transpose
+
+  if( @bf == 1 )
+  {
+    setring @save@;
+  }
+
+  kill r;
+  return( R );
+}
+example
+{
+  "EXAMPLE:"; echo=2;
+
+  ring r= 0,(x,y,z),dp;
+  matrix M[3][1] = x,y,z;
+  print(M);
+  matrix L = leftKernel(M);
+  print(L);
+  // check:
+  print(L*M);
+};
+
+
+
+/******************************************************/
+// the following is taken from "sing4ti2.lib" as we need 'hilbert' from 4ti2
+
+static proc hilbert4ti2intmat(intmat A, list #)
+"USAGE:  hilbert4ti2(A[,i]);
+@*       A=intmat
+@*       i=int
+ASSUME:  - A is a matrix with integer entries which describes the lattice
+@*         as ker(A), if second argument is not present, and
+@*         as the left image Im(A) = {zA : z \in ZZ^k}, if second argument is a positive integer
+@*       - number of variables of basering equals number of columns of A
+@*         (for ker(A)) resp. of rows of A (for Im(A))
+CREATE:  temporary files sing4ti2.mat, sing4ti2.lat, sing4ti2.mar
+@*       in the current directory (I/O files for communication with 4ti2)
+NOTE:    input rules for 4ti2 also apply to input to this procedure
+@*       hence ker(A)={x|Ax=0} and Im(A)={xA}
+RETURN:  toric ideal specified by Hilbert basis thereof
+EXAMPLE: example graver4ti2; shows an example
+"
+{
+   if( system("sh","which hilbert 2> /dev/null 1> /dev/null") != 0 )
+   {
+     ERROR("Sorry: cannot find 'hilbert' command from 4ti2. Please install 4ti2!");
+   }
+
+//--------------------------------------------------------------------------
+// Initialization and Sanity Checks
+//--------------------------------------------------------------------------
+   int i,j;
+   int nr=nrows(A);
+   int nc=ncols(A);
+   string fileending="mat";
+   if (size(#)!=0)
+   {
+//--- default behaviour: use ker(A) as lattice
+//--- if #[1]!=0 use Im(A) as lattice
+      if(typeof(#[1])!="int")
+      {
+         ERROR("optional parameter needs to be integer value");
+      }
+      if(#[1]!=0)
+      {
+         fileending="lat";
+      }
+   }
+//--- we should also be checking whether all entries are indeed integers
+//--- or whether there are fractions, but in this case the error message
+//--- of 4ti2 is printed directly
+
+//--------------------------------------------------------------------------
+// preparing input file for 4ti2
+//--------------------------------------------------------------------------
+   link eing=":w sing4ti2."+fileending;
+   string eingstring=string(nr)+" "+string(nc);
+   write(eing,eingstring);
+   for(i=1;i<=nr;i++)
+   {
+      kill eingstring;
+      string eingstring;
+      for(j=1;j<=nc;j++)
+      {
+        //          if(g(A[i,j])>0)||(char(basering)!=0)||(npars(basering)>0))
+        //          {
+        //             ERROR("Input to hilbert4ti2 needs to be a matrix with integer entries");
+        //          }
+        eingstring=eingstring+string(A[i,j])+" ";
+      }
+      write(eing, eingstring);
+   }
+   close(eing);
+
+//----------------------------------------------------------------------
+// calling 4ti2 and converting output
+// Singular's string is too clumsy for this, hence we first prepare
+// using standard unix commands
+//----------------------------------------------------------------------
+
+
+   j=system("sh","hilbert -q -n sing4ti2 >/dev/null 2>&1"); ////////// be quiet + no loggin!!!
+
+   j=system("sh", "awk \'BEGIN{ORS=\",\";}{print $0;}\' sing4ti2.hil " +
+                "| sed s/[\\\ \\\t\\\v\\\f]/,/g " +
+                "| sed s/,+/,/g|sed s/,,/,/g " +
+                "| sed s/,,/,/g " +
+                "> sing4ti2.converted" );
+
+
+//----------------------------------------------------------------------
+// reading output of 4ti2
+//----------------------------------------------------------------------
+   link ausg=":r sing4ti2.converted";
+//--- last entry ideal(0) is used to tie the list to the basering
+//--- it will not be processed any further
+
+   string s = read(ausg);
+
+   if( defined(keepfiles) <= 0)
+   {
+      j=system("sh",("rm -f sing4ti2.hil sing4ti2.converted sing4ti2."+fileending));
+   }
+
+   string ergstr = "intvec erglist = " + s + "0;";
+   execute(ergstr);
+
+   //   print(erglist);
+
+   int Rnc = erglist[1];
+   int Rnr = erglist[2];
+
+   intmat R[Rnr][Rnc];
+
+   int k = 3;
+
+   for(i=1;i<=Rnc;i++)
+   {
+     for(j=1;j<=Rnr;j++)
+     {
+       //       "i: ", i, ", j: ", j, ", v: ", erglist[k];
+       R[j, i] = erglist[k];
+       k = k + 1;
+     }
+   }
+
+
+
+   return (R);
+//--- get rid of leading entry 0;
+//   toric=toric[2..ncols(toric)];
+//   return(toric);
+}
+// A nice example here is the 3x3 Magic Squares
+example
+{
+  "EXAMPLE:"; echo=2;
+
+   ring r=0,(x1,x2,x3,x4,x5,x6,x7,x8,x9),dp;
+   intmat M[7][9]=
+      1, 1, 1, -1, -1, -1, 0, 0, 0,
+      1, 1, 1,  0,  0,  0,-1,-1,-1,
+      0, 1, 1, -1,  0,  0,-1, 0, 0,
+      1, 0, 1,  0, -1,  0, 0,-1, 0,
+      1, 1, 0,  0,  0, -1, 0, 0,-1,
+      0, 1, 1,  0, -1,  0, 0, 0,-1,
+      1, 1, 0,  0, -1,  0,-1, 0, 0;
+   hilbert4ti2intmat(M);
+   hermiteNormalForm(M);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+static proc getMonomByExponent(intvec exp)
+{
+  int n = nvars(basering);
+
+  if( nrows(exp) < n )
+  {
+    n = nrows(exp);
+  }
+
+  poly m = 1; int e;
+
+  for( int i = 1; i <= n; i++ )
+  {
+    e = exp[i];
+    if( e < 0 )
+    {
+      ERROR("Negative exponent!!!");
+    }
+
+    m = m * (var(i)^e);
+  }
+
+  return (m);
+
+}
+
+/******************************************************/
+proc multiDegBasis(intvec d)
+"USAGE: multidegree d
+ASSUME: current ring is multigraded, monomial ordering is global
+PURPOSE: compute all monomials of multidegree d
+EXAMPLE: example multiDegBasis; shows an example
+"
+{
+  def R = basering;  // setring R;
+
+  intmat M = getVariableWeights(R);
+
+  //  print(M);
+
+  int nr = nrows(M);
+  int nc = ncols(M);
+
+  intmat A[nr][nc+1];
+  A[1..nr, 1..nc] = M[1..nr, 1..nc];
+  //typeof(A[1..nr, nc+1]);
+  if( nr==1)
+  {
+    A[1..nr, nc+1]=-d[1];
+  }
+  else
+  {
+    A[1..nr, nc+1] = -d;
+  }
+
+  intmat T = getLattice(R);
+
+  if( isFreeRepresented() )
+  {
+    intmat B = hilbert4ti2intmat(A);
+
+    //      matrix B = unitMatrix(nrows(T));
+  }
+  else
+  {
+    int n = ncols(T);
+
+    nc = ncols(A);
+
+    intmat AA[nr][nc + 2 * n];
+    AA[1..nr, 1.. nc] = A[1..nr, 1.. nc];
+    AA[1..nr, nc + (1.. n)] = T[1..nr, 1.. n];
+    AA[1..nr, nc + n + (1.. n)] = -T[1..nr, 1.. n];
+
+
+    //      print ( AA );
+
+    intmat K = leftKernelZ(( AA ) ); //
+
+    //      print(K);
+
+    intmat KK[nc][ncols(K)] = K[ 1.. nc, 1.. ncols(K) ];
+
+    //      print(KK);
+    //      "!";
+
+    intmat B = hilbert4ti2intmat(transpose(KK), 1);
+
+    //      "!";      print(B);
+
+  }
+
+
+  //  print(A);
+
+
+
+  int i;
+  int nnr = nrows(B);
+  int nnc = ncols(B);
+  ideal I, J;
+  if(nnc==0){
+    I=0;
+    return(I);
+  }
+  I[nnc] = 0;
+  J[nnc] = 0;
+
+  for( i = 1; i <= nnc; i++ )
+  {
+    //      "i: ", i;    B[nnr, i];
+
+    if( B[nnr, i] == 1)
+    {
+      // intvec(B[1..nnr-1, i]);
+      I[i] = getMonomByExponent(intvec(B[1..nnr-1, i]));
+    }
+    else
+    {
+      if( B[nnr, i] == 0)
+      {
+        // intvec(B[1..nnr-1, i]);
+        J[i] = getMonomByExponent(intvec(B[1..nnr-1, i]));
+      }
+    }
+    //      I[i];
+  }
+
+  ideal Q = (ideal(basering));
+
+  if ( size(Q) > 0 )
+  {
+    I = NF( I, lead(Q) );
+    J = NF( J, lead(Q) ); // Global ordering!!!
+  }
+
+  I = simplify(I, 2); // d
+  J = simplify(J, 2); // d
+
+  attrib(I, "ZeroPart", J);
+
+  return (I);
+
+  //  setring ;
+}
+example
+{
+  "EXAMPLE:"; echo=2;
+
+  ring R = 0, (x, y), dp;
+
+  intmat g1[2][2]=1,0,0,1;
+  intmat l[2][1]=2,0;
+  intmat g2[2][2]=1,1,1,1;
+  intvec v1=4,0;
+  intvec v2=4,4;
+
+  intmat g3[1][2]=1,1;
+  setBaseMultigrading(g3);
+  intvec v3=4:1;
+  v3;
+  multiDegBasis(v3);
+
+  setBaseMultigrading(g1,l);
+  multiDegBasis(v1);
+  setBaseMultigrading(g2);
+  multiDegBasis(v2);
+
+  intmat M[2][2] = 1, -1, -1, 1;
+  intvec d = -2, 2;
+
+  setBaseMultigrading(M);
+
+  multiDegBasis(d);
+  attrib(_, "ZeroPart");
+
+  kill R, M, d;
+  ring R = 0, (x, y, z), dp;
+
+  intmat M[2][3] = 1, -2, 1,     1, 1, 0;
+
+  intmat L[2][1] = 0, 2;
+
+  intvec d = 4, 1;
+
+  setBaseMultigrading(M, L);
+
+  multiDegBasis(d);
+  attrib(_, "ZeroPart");
+
+
+  kill R, M, d;
+
+  ring R = 0, (x, y, z), dp;
+  qring Q = std(ideal( y^6+ x*y^3*z-x^2*z^2 ));
+
+
+  intmat M[2][3] = 1, 1, 2,     2, 1, 1;
+  //  intmat T[2][1] = 0, 2;
+
+  setBaseMultigrading(M); // BUG????
+
+  intvec d = 6, 6;
+  multiDegBasis(d);
+  attrib(_, "ZeroPart");
+
+
+
+  kill R, Q, M, d;
+  ring R = 0, (x, y, z), dp;
+  qring Q = std(ideal( x*z^3 - y *z^6, x*y*z  - x^4*y^2 ));
+
+
+  intmat M[2][3] = 1, -2, 1,     1, 1, 0;
+  intmat T[2][1] = 0, 2;
+
+  intvec d = 4, 1;
+
+  setBaseMultigrading(M, T); // BUG????
+
+  multiDegBasis(d);
+  attrib(_, "ZeroPart");
+}
+
+
+proc multiDegSyzygy(def I)
+"USAGE: multiDegSyzygy(I); I is a ideal or a module
+PURPOSE: computes the multigraded syzygy module of I
+RETURNS: module, the syzygy module of I
+NOTE: generators of I must be multigraded homogeneous
+EXAMPLE: example multiDegSyzygy; shows an example
+"
+{
+  if( isHomogeneous(I, "checkGens") == 0)
+  {
+    ERROR ("Sorry: inhomogeneous input!");
+  }
+  module S = syz(I);
+  S = setModuleGrading(S, multiDeg(I));
+  return (S);
+}
+example
+{
+  "EXAMPLE:"; echo=2;
+
+  ring r = 0,(x,y,z,w),dp;
+  intmat MM[2][4]=
+    1,1,1,1,
+    0,1,3,4;
+  setBaseMultigrading(MM);
+  module M = ideal(  xw-yz, x2z-y3, xz2-y2w, yw2-z3);
+
+
+  intmat v[2][nrows(M)]=
+    1,
+    0;
+
+  M = setModuleGrading(M, v);
+
+  isHomogeneous(M);
+  "Multidegrees: "; print(multiDeg(M));
+  // Let's compute syzygies!
+  def S = multiDegSyzygy(M); S;
+  "Module Units Multigrading: "; print( getModuleGrading(S) );
+  "Multidegrees: "; print(multiDeg(S));
+
+  isHomogeneous(S);
+}
+
+
+
+proc multiDegModulo(def I, def J)
+"USAGE: multiDegModulo(I); I, J are ideals or modules
+PURPOSE: computes the multigraded 'modulo' module of I and J
+RETURNS: module, see 'modulo' command
+NOTE: I and J should have the same multigrading, and their
+generators must be multigraded homogeneous
+EXAMPLE: example multiDegModulo; shows an example
+"
+{
+  if( (isHomogeneous(I, "checkGens") == 0) or (isHomogeneous(J, "checkGens") == 0) )
+  {
+    ERROR ("Sorry: inhomogeneous input!");
+  }
+  module K = modulo(I, J);
+  K = setModuleGrading(K, multiDeg(I));
+  return (K);
+}
+example
+{
+  "EXAMPLE:"; echo=2;
+
+  ring r = 0,(x,y,z),dp;
+  intmat MM[2][3]=
+    -1,1,1,
+     0,1,3;
+  setBaseMultigrading(MM);
+
+  ideal h1 = x, y, z;
+  ideal h2 = x;
+
+  "Multidegrees: "; print(multiDeg(h1));
+
+  // Let's compute modulo(h1, h2):
+  def K = multiDegModulo(h1, h2); K;
+
+  "Module Units Multigrading: "; print( getModuleGrading(K) );
+  "Multidegrees: "; print(multiDeg(K));
+
+  isHomogeneous(K);
+}
+
+
+proc multiDegGroebner(def I)
+"USAGE: multiDegGroebner(I); I is a poly/vector/ideal/module
+PURPOSE: computes the multigraded standard/groebner basis of I
+NOTE: I must be multigraded homogeneous
+RETURNS: ideal/module, the computed basis
+EXAMPLE: example multiDegGroebner; shows an example
+"
+{
+  if( isHomogeneous(I) == 0)
+  {
+    ERROR ("Sorry: inhomogeneous input!");
+  }
+
+  def S = groebner(I);
+
+  if( typeof(I) == "module" or typeof(I) == "vector" )
+  {
+    S = setModuleGrading(S, getModuleGrading(I));
+  }
+
+  return(S);
+}
+example
+{
+  "EXAMPLE:"; echo=2;
+
+  ring r = 0,(x,y,z,w),dp;
+
+  intmat MM[2][4]=
+    1,1,1,1,
+    0,1,3,4;
+
+  setBaseMultigrading(MM);
+
+
+  module M = ideal(  xw-yz, x2z-y3, xz2-y2w, yw2-z3);
+
+
+  intmat v[2][nrows(M)]=
+    1,
+    0;
+
+  M = setModuleGrading(M, v);
+
+
+  /////////////////////////////////////////////////////////////////////////////
+  // GB:
+  M = multiDegGroebner(M); M;
+  "Module Units Multigrading: "; print( getModuleGrading(M) );
+  "Multidegrees: "; print(multiDeg(M));
+
+  isHomogeneous(M);
+
+  /////////////////////////////////////////////////////////////////////////////
+  // Let's compute Syzygy!
+  def S = multiDegSyzygy(M); S;
+  "Module Units Multigrading: "; print( getModuleGrading(S) );
+  "Multidegrees: "; print(multiDeg(S));
+
+  isHomogeneous(S);
+
+  /////////////////////////////////////////////////////////////////////////////
+  // GB:
+  S = multiDegGroebner(S); S;
+  "Module Units Multigrading: "; print( getModuleGrading(S) );
+  "Multidegrees: "; print(multiDeg(S));
+
+  isHomogeneous(S);
+}
+
+
+/******************************************************/
+proc multiDegResolution(def I, int ll, list #)
+"USAGE: multiDegResolution(I,l,[f]); I is poly/vector/ideal/module; l,f are integers
+PURPOSE: computes the multigraded resolution of I of the length l,
+or the whole resolution if l is zero. Returns minimal resolution if an optional
+argument 1 is supplied
+NOTE: input must have multigraded-homogeneous generators.
+The returned list is truncated beginning with the first zero differential.
+RETURNS: list, the computed resolution
+EXAMPLE: example multiDegResolution; shows an example
+"
+{
+  if( isHomogeneous(I, "checkGens") == 0)
+  {
+    ERROR ("Sorry: inhomogeneous input!");
+  }
+
+  def R = res(I, ll, #); list L = R; int l = size(L);
+  def V = getModuleGrading(I);
+  if( (typeof(I) == "module") or (typeof(I) == "vector") )
+  {
+    L[1] = setModuleGrading(L[1], V);
+  }
+
+  int i;
+  for( i = 2; i <= l; i++ )
+  {
+    if( size(L[i]) > 0 )
+    {
+      L[i] = setModuleGrading( L[i], multiDeg(L[i-1]) );
+    } else
+    {
+      return (L[1..(i-1)]);
+    }
+  }
+
+  return (L);
+
+
+}
+example
+{
+  "EXAMPLE:"; echo=2;
+
+  ring r = 0,(x,y,z,w),dp;
+
+  intmat M[2][4]=
+    1,1,1,1,
+    0,1,3,4;
+
+  setBaseMultigrading(M);
+
+
+  module m= ideal(  xw-yz, x2z-y3, xz2-y2w, yw2-z3);
+
+  isHomogeneous(ideal(  xw-yz, x2z-y3, xz2-y2w, yw2-z3), "checkGens");
+
+  ideal A = xw-yz, x2z-y3, xz2-y2w, yw2-z3;
+
+  int j;
+
+  for(j=1; j<=ncols(A); j++)
+  {
+    multiDegPartition(A[j]);
+  }
+
+  intmat v[2][1]=
+    1,
+    0;
+
+  m = setModuleGrading(m, v);
+
+  // Let's compute Syzygy!
+  def S = multiDegSyzygy(m); S;
+  "Module Units Multigrading: "; print( getModuleGrading(S) );
+  "Multidegrees: "; print(multiDeg(S));
+
+  /////////////////////////////////////////////////////////////////////////////
+
+  S = multiDegGroebner(S); S;
+  "Module Units Multigrading: "; print( getModuleGrading(S) );
+  "Multidegrees: "; print(multiDeg(S));
+
+  /////////////////////////////////////////////////////////////////////////////
+
+  list L = multiDegResolution(m, 0, 1);
+
+  for( j =1; j<=size(L); j++)
+  {
+    "----------------------------------- ", j, " -----------------------------";
+    L[j];
+    "Module Multigrading: "; print( getModuleGrading(L[j]) );
+    "Multigrading: "; print(multiDeg(L[j]));
+  }
+
+  /////////////////////////////////////////////////////////////////////////////
+
+  L = multiDegResolution(maxideal(1), 0, 1);
+
+  for( j =1; j<=size(L); j++)
+  {
+    "----------------------------------- ", j, " -----------------------------";
+    L[j];
+    "Module Multigrading: "; print( getModuleGrading(L[j]) );
+    "Multigrading: "; print(multiDeg(L[j]));
+  }
+
+  kill v;
+
+
+  def h = hilbertSeries(m);
+  setring h;
+
+  numerator1;
+  factorize(numerator1);
+
+  denominator1;
+  factorize(denominator1);
+
+  numerator2;
+  factorize(numerator2);
+
+  denominator2;
+  factorize(denominator2);
+}
+
+/******************************************************/
+proc hilbertSeries(def I)
+"USAGE: hilbertSeries(I); I is poly/vector/ideal/module
+PURPOSE: computes the multigraded Hilbert Series of I
+NOTE: input must have multigraded-homogeneous generators.
+Multigrading should be positive.
+RETURNS: a ring in variables t_(i), s_(i), with polynomials
+numerator1 and denominator1 and mutually prime numerator2
+and denominator2, quotients of which give the series.
+EXAMPLE: example hilbertSeries; shows an example
+"
+{
+
+  if( !isFreeRepresented() )
+  {
+    "Things might happen, since we are not  free.";
+    //ERROR("SORRY: ONLY TORSION-FREE CASE (POSITIVE GRADING)");
+  }
+
+  int i, j, k, v;
+
+  intmat M = getVariableWeights();
+
+  int cc = ncols(M);
+  int n = nrows(M);
+
+  if( n == 0 )
+  {
+    ERROR("Error: wrong Variable Weights?");
+  }
+
+  list RES = multiDegResolution(I,0,1);
+
+  int l = size(RES);
+
+  list L; L[l + 1] = 0;
+
+  if(typeof(I) == "ideal")
+  {
+    intmat zeros[n][1];
+    L[1] = zeros;
+  }
+  else
+  {
+    L[1] = getModuleGrading(RES[1]);
+  }
+
+  for( j = 1; j <= l; j++)
+  {
+    L[j + 1] = multiDeg(RES[j]);
+  }
+
+  l++;
+
+  ring R = 0,(t_(1..n),s_(1..n)),dp;
+
+  ideal units;
+  for( i=n; i>=1; i--)
+  {
+    units[i] = (var(i) * var(n + i) - 1);
+  }
+
+  qring Q = std(units);
+
+  // TODO: should not it be a quotient ring depending on Torsion???
+  // I am not sure about what to do in the torsion case, but since
+  // we want to evaluate the polynomial at certain points to get
+  // a dimension we need uniqueness for this. I think we would lose
+  // this uniqueness if switching to this torsion ring.
+
+  poly monom, summand, @numerator;
+  poly @denominator = 1;
+
+  for( i = 1; i <= cc; i++)
+  {
+    monom = 1;
+    for( k = 1; k <= n; k++)
+    {
+      v = M[k,i];
+
+      if(v >= 0)
+      {
+        monom = monom * (var(k)^(v));
+      }
+      else
+      {
+        monom = monom * (var(n+k)^(-v));
+      }
+    }
+
+    if( monom == 1)
+    {
+      ERROR("Multigrading not positive.");
+    }
+
+    @denominator = @denominator * (1 - monom);
+  }
+
+  for( j = 1; j<= l; j++)
+  {
+    summand = 0;
+    M = L[j];
+
+    for( i = 1; i <= ncols(M); i++)
+    {
+      monom = 1;
+      for( k = 1; k <= n; k++)
+      {
+        v = M[k,i];
+        if( v > 0 )
+        {
+          monom = monom * (var(k)^v);
+        }
+        else
+        {
+          monom = monom * (var(n+k)^(-v));
+        }
+      }
+      summand = summand + monom;
+    }
+    @numerator = @numerator - (-1)^j * summand;
+  }
+
+  if( @denominator == 0 )
+  {
+    ERROR("Multigrading not positive.");
+  }
+
+  poly denominator1 = @denominator;
+  poly numerator1 = @numerator;
+
+  export denominator1;
+  export numerator1;
+
+  if( @numerator != 0 )
+  {
+    poly d = gcd(@denominator, @numerator);
+
+    poly denominator2 = @denominator/d;
+    poly numerator2 = @numerator/d;
+
+    if( gcd(denominator2, numerator2) != 1 )
+    {
+      ERROR("Sorry: gcd should be 1 (after dividing out gcd)! Something went wrong!");
+    }
+  }
+  else
+  {
+    poly denominator2 = @denominator;
+    poly numerator2 = @numerator;
+  }
+
+
+  export denominator2;
+  export numerator2;
+
+  " ------------ ";
+  "This proc returns a ring with polynomials called 'numerator1/2' and 'denominator1/2'!";
+  "They represent the first and the second Hilbert Series.";
+  "The s_(i)-variables are defined to be the inverse of the t_(i)-variables.";
+  " ------------ ";
+
+  return(Q);
+}
+example
+{
+  "EXAMPLE:"; echo=2;
+
+  ring r = 0,(x,y,z,w),dp;
+  intmat g[2][4]=
+    1,1,1,1,
+    0,1,3,4;
+  setBaseMultigrading(g);
+
+  module M = ideal(xw-yz, x2z-y3, xz2-y2w, yw2-z3);
+  intmat V[2][1]=
+    1,
+    0;
+
+  M = setModuleGrading(M, V);
+
+  def h = hilbertSeries(M); setring h;
+
+  factorize(numerator2);
+  factorize(denominator2);
+
+  kill g, h; setring r;
+
+  intmat g[2][4]=
+    1,2,3,4,
+    0,0,5,8;
+
+  setBaseMultigrading(g);
+
+  ideal I = x^2, y, z^3;
+  I = std(I);
+  list L = multiDegResolution(I, 0, 1);
+
+  for( int j = 1; j<=size(L); j++)
+  {
+    "----------------------------------- ", j, " -----------------------------";
+    L[j];
+    "Module Multigrading: "; print( getModuleGrading(L[j]) );
+    "Multigrading: "; print(multiDeg(L[j]));
+  }
+
+  multiDeg(I);
+  def h = hilbertSeries(I); setring h;
+
+  factorize(numerator2);
+  factorize(denominator2);
+
+  kill r, h, g, V;
+  ////////////////////////////////////////////////
+  ring R = 0,(x,y,z),dp;
+  intmat W[2][3] =
+     1,1, 1,
+     0,0,-1;
+  setBaseMultigrading(W);
+  ideal I = x3y,yz2,y2z,z4;
+
+  def h = hilbertSeries(I); setring h;
+
+  factorize(numerator2);
+  factorize(denominator2);
+
+  kill R, W, h;
+  ////////////////////////////////////////////////
+  ring R = 0,(x,y,z,a,b,c),dp;
+  intmat W[2][6] =
+     1,1, 1,1,1,1,
+     0,0,-1,0,0,0;
+  setBaseMultigrading(W);
+  ideal I = x3y,yz2,y2z,z4;
+
+  def h = hilbertSeries(I); setring h;
+
+  factorize(numerator2);
+  factorize(denominator2);
+
+  kill R, W, h;
+  ////////////////////////////////////////////////
+  // This is example 5.3.9. from Robbianos book.
+
+  ring R = 0,(x,y,z,w),dp;
+  intmat W[1][4] =
+     1,1, 1,1;
+  setBaseMultigrading(W);
+  ideal I = z3,y3zw2,x2y4w2xyz2;
+
+  hilb(std(I));
+
+  def h = hilbertSeries(I); setring h;
+
+  numerator1;
+  denominator1;
+
+  factorize(numerator2);
+  factorize(denominator2);
+
+
+  kill h;
+  ////////////////////////////////////////////////
+  setring R;
+
+  ideal I2 = x2,y2,z2; I2;
+
+  hilb(std(I2));
+
+  def h = hilbertSeries(I2); setring h;
+
+  numerator1;
+  denominator1;
+
+
+  kill h;
+  ////////////////////////////////////////////////
+  setring R;
+
+  W = 2,2,2,2;
+
+  setBaseMultigrading(W);
+
+  getVariableWeights();
+
+  intvec w = 2,2,2,2;
+
+  hilb(std(I2), 1, w);
+
+  kill w;
+
+
+  def h = hilbertSeries(I2); setring h;
+
+
+  numerator1; denominator1;
+  kill h;
+
+
+  kill R, W;
+
+  ////////////////////////////////////////////////
+  ring R = 0,(x),dp;
+  intmat W[1][1] =
+     1;
+  setBaseMultigrading(W);
+
+  ideal I;
+
+  I = 1; I;
+
+  hilb(std(I));
+
+  def h = hilbertSeries(I); setring h;
+
+  numerator1; denominator1;
+
+  kill h;
+  ////////////////////////////////////////////////
+  setring R;
+
+  I = x; I;
+
+  hilb(std(I));
+
+  def h = hilbertSeries(I); setring h;
+
+  numerator1; denominator1;
+
+  kill h;
+  ////////////////////////////////////////////////
+  setring R;
+
+  I = x^5; I;
+
+  hilb(std(I));
+  hilb(std(I), 1);
+
+  def h = hilbertSeries(I); setring h;
+
+  numerator1; denominator1;
+
+
+  kill h;
+  ////////////////////////////////////////////////
+  setring R;
+
+  I = x^10; I;
+
+  hilb(std(I));
+
+  def h = hilbertSeries(I); setring h;
+
+  numerator1; denominator1;
+
+  kill h;
+  ////////////////////////////////////////////////
+  setring R;
+
+  module M = 1;
+
+  M = setModuleGrading(M, W);
+
+
+  hilb(std(M));
+
+  def h = hilbertSeries(M); setring h;
+
+  numerator1; denominator1;
+
+  kill h;
+  ////////////////////////////////////////////////
+  setring R;
+
+  kill M; module M = x^5*gen(1);
+//  intmat V[1][3] = 0; // TODO: this would lead to a wrong result!!!?
+  intmat V[1][1] = 0; // all gen(i) of degree 0!
+
+  M = setModuleGrading(M, V);
+
+  hilb(std(M));
+
+  def h = hilbertSeries(M); setring h;
+
+  numerator1; denominator1;
+
+  kill h;
+  ////////////////////////////////////////////////
+  setring R;
+
+  module N = x^5*gen(3);
+
+  kill V;
+
+  intmat V[1][3] = 0; // all gen(i) of degree 0!
+
+  N = setModuleGrading(N, V);
+
+  hilb(std(N));
+
+  def h = hilbertSeries(N); setring h;
+
+  numerator1; denominator1;
+
+  kill h;
+  ////////////////////////////////////////////////
+  setring R;
+
+
+  module S = M + N;
+
+  S = setModuleGrading(S, V);
+
+  hilb(std(S));
+
+  def h = hilbertSeries(S); setring h;
+
+  numerator1; denominator1;
+
+  kill h;
+
+  kill V;
+  kill R, W;
+
+}
+
+static proc evalHilbertSeries(def h, intvec v)
+"
+   TODO
+   evaluate hilbert series h by substibuting v[i] for t_(i) (1/v[i] for s_(i))
+  return: int (h(v))
+"
+{
+  if( 2*size(v) != nvars(h) )
+  {
+    ERROR("Wrong input/size!");
+  }
+
+  setring h;
+
+  if( defined(numerator2) and defined(denominator2) )
+  {
+    poly n = numerator2; poly d = denominator2;
+  } else
+  {
+    poly n = numerator1; poly d = denominator1;
+  }
+
+  int N = size(v);
+  int i; number k;
+  ideal V;
+
+  for( i = N; i > 0; i -- )
+  {
+    k = v[i];
+    V[i] = var(i) - k;
+  }
+
+  V = groebner(V);
+
+  n = NF(n, V);
+  d = NF(d, V);
+
+  n;
+  d;
+
+  if( d == 0 )
+  {
+    ERROR("Sorry: denominator is zero!");
+  }
+
+  if( n == 0 )
+  {
+    return (0);
+  }
+
+  poly g = gcd(n, d);
+
+  if( g != leadcoef(g) )
+  {
+    n = n / g;
+    d = d / g;
+  }
+
+  n;
+  d;
+
+
+  for( i = N; i > 0; i -- )
+  {
+    "i: ", i;
+    n;
+    d;
+
+    k = v[i];
+    k;
+
+    n = subst(n, var(i), k);
+    d = subst(d, var(i), k);
+
+    if( k != 0 )
+    {
+      k = 1/k;
+      n = subst(n, var(N+i), k);
+      d = subst(d, var(N+i), k);
+    }
+  }
+
+  n;
+  d;
+
+  if( d == 0 )
+  {
+    ERROR("Sorry: denominator is zero!");
+  }
+
+  if( n == 0 )
+  {
+    return (0);
+  }
+
+  poly g = gcd(n, d);
+
+  if( g != leadcoef(g) )
+  {
+    n = n / g;
+    d = d / g;
+  }
+
+  n;
+  d;
+
+  if( n != leadcoef(n) || d != leadcoef(d) )
+  {
+    ERROR("Sorry cannot completely evaluate. Partial result: (" + string(n) + ")/(" + string(d) + ")");
+  }
+
+  n;
+  d;
+
+  return (leadcoef(n)/leadcoef(d));
+}
+example
+{
+  "EXAMPLE:"; echo=2;
+
+  // TODO!
+
+}
+
+
+proc isPositive()
+"USAGE: isPositive()
+PURPOSE: Computes whether the multigrading of the ring is positive.
+For computation theorem 8.6 of the Miller/Sturmfels book is used.
+RETURNS: true if the multigrading is positive
+EXAMPLE: example isPositive; shows an example
+"
+{
+ideal I = multiDegBasis(0);
+ideal J = attrib(I,"ZeroPart");
+/*
+I am not quite sure what this ZeroPart is anymore. I thought it
+should contain all monomials of degree 0, but then apparently 1 should
+be contained. It makes sense to exclude 1, but was this also the intention?
+*/
+return(J==0);
+}
+example
+{
+  echo = 2; printlevel = 3;
+  ring r = 0,(x,y),dp;
+  intmat A[1][2]=-1,1;
+  setBaseMultigrading(A);
+  isPositive();
+
+  intmat B[1][2]=1,1;
+  setBaseMultigrading(B);
+  isPositive(B);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// testing for consistency of the library:
+proc testMultigradingLib ()
+{
+  example setBaseMultigrading;
+  example setModuleGrading;
+
+  example getVariableWeights;
+  example getLattice;
+  example getGradingGroup;
+  example getModuleGrading;
+
+
+  example multiDeg;
+  example multiDegPartition;
+
+
+  example hermiteNormalForm;
+  example isHomogeneous;
+  example isTorsionFree;
+  example pushForward;
+  example defineHomogeneous;
+
+  example equalMultiDeg;
+  example isZeroElement;
+
+  example multiDegResolution;
+
+  "// ******************* example hilbertSeries ************************//";
+  example hilbertSeries;
+
+
+// example multiDegBasis; // needs 4ti2!
+
+  "The End!";
+}
+
+
+static proc multiDegTruncate(def M, intvec md)
+{
+  "d: ";
+  print(md);
+
+  "M: ";
+  module LL = M; // + L for d+1
+  LL;
+  print(multiDeg(LL));
+
+
+  intmat V = getModuleGrading(M);
+  intvec vi;
+  int s = nrows(M);
+  int r = nrows(V);
+  int i;
+  module L; def B;
+  for (i=s; i>0; i--)
+  {
+    "comp: ", i;
+    vi = V[1..r, i];
+    "v[i]: "; vi;
+
+    B = multiDegBasis(md - vi); // ZeroPart is always the same...
+    "B: "; B;
+
+    L = L, B*gen(i);
+  }
+  L = simplify(L, 2);
+  L = setModuleGrading(L,V);
+
+  "L: "; L;
+  print(multiDeg(L));
+
+  L = multiDegModulo(L, LL);
+  L = multiDegGroebner(L);
+//  L = minbase(prune(L));
+
+  "??????????";
+  print(L);
+  print(multiDeg(L));
+
+  V = getModuleGrading(L);
+
+  // take out other degrees
+  for(i = ncols(L); i > 0; i-- )
+  {
+    if( !equalMultiDeg( multiDeg(getGradedGenerator(L, i)), md ) )
+    {
+      L[i] = 0;
+    }
+  }
+
+  L = simplify(L, 2);
+  L = setModuleGrading(L, V);
+  print(L);
+  print(multiDeg(L));
+
+  return(L);
+}
+example
+{
+  "EXAMPLE:"; echo=2;
+
+  // TODO!
+  ring r = 32003, (x,y), dp;
+
+  intmat M[2][2] =
+    1, 0,
+    0, 1;
+
+  setBaseMultigrading(M);
+
+  intmat V[2][1] =
+    0,
+    0;
+
+  "X:";
+  module h1 = x;
+  h1 = setModuleGrading(h1, V);
+  multiDegTruncate(h1, multiDeg(x));
+  multiDegTruncate(h1, multiDeg(y));
+
+  "XY:";
+  module h2 = ideal(x, y);
+  h2 = setModuleGrading(h2, V);
+  multiDegTruncate(h2, multiDeg(x));
+  multiDegTruncate(h2, multiDeg(y));
+  multiDegTruncate(h2, multiDeg(xy));
+}
+
+
+/******************************************************/
+/* Some functions on lattices.
+TODO Tuebingen: - add functionality (see wiki) and
+- adjust them to work for groups as well.*/
+/******************************************************/
+
+
+
+/******************************************************/
+proc imageLattice(intmat Q, intmat L)
+"USAGE: imageLattice(Q,L); Q and L are of type intmat
+PURPOSE: compute an integral basis for the image of the
+lattice L under the homomorphism of lattices Q.
+RETURN: intmat
+EXAMPLE: example imageLattice; shows an example
+"
+{
+  intmat Mul = Q*L;
+  intmat LL = latticeBasis(Mul);
+
+  return(LL);
+}
+example
+{
+  "EXAMPLE:"; echo=2;
+
+  intmat Q[2][3] =
+    1,2,3,
+    3,2,1;
+
+  intmat L[3][2] =
+    1,4,
+    2,5,
+    3,6;
+
+  // should be a 2x2 matrix with columns
+  // [2,-14], [0,36]
+  imageLattice(Q,L);
+
+}
+
+/******************************************************/
+proc intRank(intmat A)
+"USAGE: intRank(A); intmat A
+PURPOSE: compute the rank of the integral matrix A
+by computing a hermite normalform.
+RETURNS: int
+EXAMPLE: example intRank; shows an example
+"
+{
+  intmat B = hermiteNormalForm(A);
+
+  // get number of zero columns
+  int nzerocols = 0;
+  int j;
+  int i;
+  int iszero;
+  for ( j = 1; j <= ncols(B); j++ )
+  {
+    iszero = 1;
+
+    for ( i = 1; i <= nrows(B); i++ )
+    {
+      if ( B[i,j] != 0 )
+      {
+        iszero = 0;
+        break;
+      }
+    }
+
+    if ( iszero == 1 )
+    {
+      nzerocols++;
+    }
+  }
+
+  // get number of zero rows
+  int nzerorows = 0;
+
+  for ( i = 1; i <= nrows(B); i++ )
+  {
+    iszero = 1;
+
+    for ( j = 1; j <= ncols(B); j++ )
+    {
+      if ( B[i,j] != 0 )
+      {
+        iszero = 0;
+        break;
+      }
+    }
+
+    if ( iszero == 1 )
+    {
+      nzerorows++;
+    }
+  }
+
+  int r = nrows(B) - nzerorows;
+
+  if ( ncols(B) - nzerocols < r )
+  {
+    r = ncols(B) - nzerocols;
+  }
+
+  return(r);
+}
+example
+{
+  "EXAMPLE:"; echo=2;
+
+  intmat A[3][4] =
+    1,0,1,0,
+    1,2,0,0,
+    0,0,0,0;
+
+  int r = intRank(A);
+
+  print(A);
+  print(r); // Should be 2
+
+  // another example
+  intmat B[2][2] =
+    1,2,
+    1,2;
+
+  int d = intRank(B);
+
+  print(B);
+  print(d); // Should be 1
+
+  kill A, B, r, d;
+
+}
+
+/*****************************************************/
+
+proc isSublattice(intmat L, intmat S)
+"USAGE: isSublattice(L, S); L, S are of tpye intmat
+PURPOSE: checks whether the lattice created by L is a
+sublattice of the lattice created by S.
+The procedure checks whether each generator of L is
+contained in S.
+RETURN: integer, 0 if false, 1 if true
+EXAMPLE: example isSublattice; shows an example
+"
+{
+  int a,b,g,i,j,k;
+  intmat Ker;
+
+  // check whether each column v of L is contained in
+  // the lattice generated by S
+  for ( i = 1; i <= ncols(L); i++ )
+  {
+
+    // v is the i-th column of L
+    intvec v;
+     for ( j = 1; j <= nrows(L); j++ )
+    {
+      v[j] = L[j,i];
+    }
+
+    // concatenate B = [S,v]
+    intmat B[nrows(L)][ncols(S) + 1];
+
+    for ( a = 1; a <= nrows(S); a++ )
+    {
+      for ( b = 1; b <= ncols(S); b++ )
+      {
+        B[a,b] = S[a,b];
+      }
+    }
+
+    for ( a = 1; a <= size(v); a++ )
+    {
+      B[a,ncols(B)] = v[a];
+    }
+
+
+    // check gcd
+    Ker = kernelLattice(B);
+    k = nrows(Ker);
+    list R; // R is the last row
+
+    for ( j = 1; j <= ncols(Ker); j++ )
+    {
+      R[j] = Ker[k,j];
+    }
+
+    g = R[1];
+
+    for ( j = 2; j <= size(R); j++ )
+    {
+      g = gcd(g,R[j]);
+    }
+
+    if ( g != 1 and g != -1 )
+    {
+      return(0);
+    }
+
+    kill B, v, R;
+
+  }
+
+  return(1);
+}
+example
+{
+  "EXAMPLE:"; echo=2;
+
+  //ring R = 0,(x,y),dp;
+  intmat S2[3][3]=
+    0, 2, 3,
+    0, 1, 1,
+    3, 0, 2;
+
+  intmat S1[3][2]=
+    0, 6,
+    0, 2,
+    3, 4;
+
+  isSublattice(S1,S2); // Yes!
+
+  intmat S3[3][1] =
+    0,
+    0,
+    1;
+
+  not(isSublattice(S3,S2)); // Yes!
+
+}
+
+/******************************************************/
+
+proc latticeBasis(intmat B)
+"USAGE: latticeBasis(B); intmat B
+PURPOSE: compute an integral basis for the lattice defined by
+the columns of B.
+RETURNS: intmat
+EXAMPLE: example latticeBasis; shows an example
+"
+{
+  int n = ncols(B);
+  int r = intRank(B);
+
+  if ( r == 0 )
+  {
+    intmat H[nrows(B)][1];
+    int j;
+
+    for ( j = 1; j <= nrows(B); j++ )
+    {
+      H[j,1] = 0;
+    }
+  }
+  else
+  {
+    intmat H = hermiteNormalForm(B);;
+
+    if (r < n)
+    {
+      // delete columns r+1 to n
+      // should be identical with the function
+      // H = submat(H,1..nrows(H),1..r);
+      // for matrices
+      intmat Hdel[nrows(H)][r];
+      int k;
+      int m;
+
+      for ( k = 1; k <= nrows(H); k++ )
+      {
+        for ( m = 1; m <= r; m++ )
+        {
+          Hdel[k,m] = H[k,m];
+        }
+      }
+
+      H = Hdel;
+    }
+  }
+
+  return(H);
+}
+example
+{
+  "EXAMPLE:"; echo=2;
+
+  intmat L[3][3] =
+    1,4,8,
+    2,5,10,
+    3,6,12;
+
+  intmat B = latticeBasis(L);
+  print(B); // should result in a matrix whose columns generate the same lattice as  [1,2,3] and [0,3,6]:
+
+   // another example
+  intmat C[2][4] =
+    1,1,2,0,
+    2,3,4,0;
+
+  // should result in a matrix whose
+  // colums create the same  lattice as
+  // [0,1],[1,0]
+  intmat D = latticeBasis(C);
+
+  print(D);
+
+  kill B,L;
+}
+
+/******************************************************/
+
+proc kernelLattice(def P)
+"USAGE: kernelLattice(P); intmat P
+PURPOSE: compute a integral basis for the kernel of the
+homomorphism of lattices defined by the intmat P.
+RETURNS: intmat
+EXAMPLE: example kernelLattice; shows an example
+"
+{
+  int n = ncols(P);
+  int r = intRank(P);
+
+  if ( r == 0 )
+  {
+    intmat U = unitMatrix(n);
+  }
+  else
+  {
+    if ( r == n )
+    {
+      intmat U[n][1];  // now all entries are zero.
+    }
+    else
+    {
+      list L = hermiteNormalForm(P, "transform"); //hermite(P, "transform");  // now, Hermite = L[1] = A*L[2]
+      intmat U = L[2];
+
+      // delete columns 1 to r
+      // should be identical with the function
+      // U = submat(U,1..nrows(U),r+1..);
+      // for matrices
+      intmat Udel[nrows(U)][ncols(U) - r];
+      int k;
+      int m;
+
+      for ( k = 1; k <= nrows(U); k++ )
+      {
+        for ( m = r + 1; m <= ncols(U); m++ )
+        {
+          Udel[k,m - r] = U[k,m];
+        }
+      }
+
+      U = Udel;
+
+    }
+  }
+
+  return(U);
+}
+example
+{
+  "EXAMPLE"; echo = 2;
+
+  intmat LL[3][4] =
+    1,4,7,10,
+    2,5,8,11,
+    3,6,9,12;
+
+  // should be a 4x2 matrix whose columns
+  // generate the same lattice as [-1,2,-1,0],[2,-3,0,1]
+  intmat B = kernelLattice(LL);
+
+  print(B);
+
+  // another example
+  intmat C[2][4] =
+    1,0,2,0,
+    0,1,2,0;
+
+  // should result in a matrix whose
+  // colums create the same  lattice as
+  // [-2,-2,1,0], [0,0,0,1]
+  intmat D = kernelLattice(C);
+
+  print(D);
+
+  kill B;
+
+}
+
+/*****************************************************/
+
+proc preimageLattice(def P, def B)
+"
+USAGE: preimageLattice(P, B); intmat P, intmat B
+PURPOSE: compute an integral basis for the preimage of B under
+ the homomorphism of lattices defined by the intmat P.
+RETURNS: intmat
+EXAMPLE: example preimageLattice; shows an example
+"
+{
+  // concatenate matrices: Con = [P,-B]
+  intmat Con[nrows(P)][ncols(P) + ncols(B)];
+  int i;
+  int j;
+
+  for ( i = 1; i <= nrows(Con); i++ )
+  {
+    for ( j = 1; j <= ncols(P); j++ ) // P first
+    {
+      Con[i,j] = P[i,j];
+    }
+  }
+
+  for ( i = 1; i <= nrows(Con); i++ )
+  {
+    for ( j = 1; j <= ncols(B); j++ ) // now -B
+    {
+      Con[i,ncols(P) + j] = - B[i,j];
+    }
+  }
+
+  intmat L = kernelLattice(Con);
+
+  // delete rows ncols(P)+1 to nrows(L) out of L
+  intmat Del[ncols(P)][ncols(L)];
+  int k;
+  int m;
+
+  for ( k = 1; k <= nrows(Del); k++ )
+  {
+    for ( m = 1; m <= ncols(Del); m++ )
+    {
+      Del[k,m] = L[k,m];
+    }
+  }
+
+  L = latticeBasis(Del);
+
+  return(L);
+
+}
+example
+{
+  "EXAMPLE"; echo = 2;
+
+  intmat P[2][3] =
+    2,6,10,
+    4,8,12;
+
+  intmat B[2][1] =
+    1,
+    0;
+
+  // should be a (3x2)-matrix with columns e.g. [1,1,-1] and [0,3,-2] (the generated lattice should be identical)
+  print(preimageLattice(P,B));
+
+  // another example
+  intmat W[3][3] =
+    1,0,0,
+    0,1,1,
+    0,2,0;
+
+  intmat Z[3][2] =
+    1,0,
+    0,1,
+    0,0;
+
+  // should be a (3x2)-matrix with columns e.g. [1,0,0] and [0,0,-1] (the generated lattice should be identical)
+  print(preimageLattice(W,Z));
+
+}
+
+/******************************************************/
+proc isPrimitiveSublattice(intmat A);
+"USAGE: isPrimitiveSublattice(A); intmat A
+PURPOSE: check whether the given set of integral vectors in ZZ^m,
+i.e. the columns of A, generate a primitive sublattice in ZZ^m
+(a direct summand of ZZ^m).
+RETURNS: int, where 0 is false and 1 is true.
+EXAMPLE: example isPrimitiveSublattice; shows an example
+"
+{
+  intmat B = smithNormalForm(A);
+  int r = intRank(B);
+
+  if ( r == 0 )
+  {
+    return(1);
+  }
+
+  if ( 1 < B[r,r] )
+  {
+    return(0);
+  }
+
+  return(1);
+}
+example
+{
+  "EXAMPLE"; echo = 2;
+
+  intmat A[3][2] =
+    1,4,
+    2,5,
+    3,6;
+
+  // should be 0
+  int b = isPrimitiveSublattice(A);
+  print(b);
+
+  // another example
+
+  intmat B[2][2] =
+    1,0,
+    0,1;
+
+  // should be 1
+  int c = isPrimitiveSublattice(B);
+  print(c);
+
+  kill A, b, B, c;
+}
+
+/******************************************************/
+proc isIntegralSurjective(intmat P);
+"USAGE: isIntegralSurjective(P); intmat P
+PURPOSE: test whether the given linear map P of lattices is
+surjective.
+RETURNS: int, where 0 is false and 1 is true.
+EXAMPLE: example isIntegralSurjective; shows an example
+"
+{
+  int r = intRank(P);
+
+  if ( r < nrows(P) )
+  {
+    return(0);
+  }
+
+
+  if ( isPrimitiveSublattice(P) == 1 )
+  {
+    return(1);
+  }
+
+  return(0);
+}
+example
+{
+  "EXAMPLE"; echo = 2;
+
+  intmat A[2][3] =
+    1,3,5,
+    2,4,6;
+
+  // should be 0
+  int b = isIntegralSurjective(A);
+  print(b);
+
+  // another example
+  intmat B[2][3] =
+    1,1,5,
+    2,3,6;
+
+  // should be 1
+  int c = isIntegralSurjective(B);
+  print(c);
+
+  kill A, b, B, c;
+}
+
+/******************************************************/
+proc projectLattice(intmat B)
+"USAGE: projectLattice(B); intmat B
+PURPOSE: A set of vectors in ZZ^m is given as the columns of B.
+Then this function provides a linear map ZZ^m --> ZZ^n
+having the primitive span of B its kernel.
+RETURNS: intmat
+EXAMPLE: example projectLattice; shows an example
+"
+{
+  int n = nrows(B);
+  int r = intRank(B);
+
+  if ( r == 0 )
+  {
+    intmat U = unitMatrix(n);
+  }
+  else
+  {
+    if ( r == n )
+    {
+      intmat U[1][n]; // U now is the n-dim zero-vector
+    }
+    else
+    {
+      // we want a matrix with column operations so we transpose
+      intmat BB = transpose(B);
+      list L = hermiteNormalForm(BB, "transform");
+      intmat U = transpose(L[2]);
+
+
+      // delete rows 1 to r
+      intmat Udel[nrows(U) - r][ncols(U)];
+      int k;
+      int m;
+
+      for ( k = 1; k <= nrows(U) - r ; k++ )
+      {
+        for ( m = 1; m <= ncols(U); m++ )
+        {
+          Udel[k,m] = U[k + r,m];
+        }
+      }
+
+      U = Udel;
+
+    }
+  }
+
+  return(U);
+}
+example
+{
+  "EXAMPLE"; echo = 2;
+
+  intmat B[4][2] =
+    1,5,
+    2,6,
+    3,7,
+    4,8;
+
+  // should result in a (2x4)-matrix such that the corresponding lattice is created by
+  // [-1, 2], [-2, 3], [-1, 0] and [0, 1]
+  print(projectLattice(B));
+
+  // another example
+
+  intmat BB[4][2] =
+    1,0,
+    0,1,
+    0,0,
+    0,0;
+
+  // should result in a (2x4)-matrix such that the corresponding lattice is created by
+  // [0,0],[0,0],[1,0],[0,1]
+  print(projectLattice(BB));
+
+  // another example
+
+  intmat BBB[3][4] =
+    1,0,1,2,
+    1,1,0,0,
+    3,0,0,3;
+
+  // should result in the (1x3)-matrix that consists of just zeros
+  print(projectLattice(BBB));
+
+}
+
+/******************************************************/
+proc intersectLattices(intmat A, intmat B)
+"USAGE: intersectLattices(A, B); intmat A, intmat B
+PURPOSE: compute an integral basis for the intersection of the
+lattices A and B.
+RETURNS: intmat
+EXAMPLE: example intersectLattices; shows an example
+"
+{
+  // concatenate matrices: Con = [A,-B]
+  intmat Con[nrows(A)][ncols(A) + ncols(B)];
+  int i;
+  int j;
+
+  for ( i = 1; i <= nrows(Con); i++ )
+  {
+    for ( j = 1; j <= ncols(A); j++ ) // A first
+    {
+      Con[i,j] = A[i,j];
+    }
+  }
+
+  for ( i = 1; i <= nrows(Con); i++ )
+  {
+    for ( j = 1; j <= ncols(B); j++ ) // now -B
+    {
+      Con[i,ncols(A) + j] = - B[i,j];
+    }
+  }
+
+  intmat K = kernelLattice(Con);
+
+  // delete all rows in K from ncols(A)+1 onwards
+  intmat Bas[ncols(A)][ncols(K)];
+
+  for ( i = 1; i <= nrows(Bas); i++ )
+  {
+    for ( j = 1; j <= ncols(Bas); j++ )
+    {
+      Bas[i,j] = K[i,j];
+    }
+  }
+
+  // take product in order to obtain the intersection
+  intmat S = A * Bas;
+  intmat Cut = hermiteNormalForm(S); //hermite(S);
+  int r = intRank(Cut);
+
+  if ( r == 0 )
+  {
+    intmat Cutdel[nrows(Cut)][1]; // is now the zero-vector
+
+    Cut = Cutdel;
+  }
+  else
+  {
+    // delte columns from r+1 onwards
+    intmat Cutdel[nrows(Cut)][r];
+
+    for ( i = 1; i <= nrows(Cutdel); i++ )
+    {
+      for ( j = 1; j <= r; j++ )
+      {
+        Cutdel[i,j] = Cut[i,j];
+      }
+    }
+
+    Cut = Cutdel;
+  }
+
+  return(Cut);
+}
+example
+{
+  "EXAMPLE"; echo = 2;
+
+  intmat A[3][2] =
+    1,4,
+    2,5,
+    3,6;
+
+  intmat B[3][2] =
+    6,9,
+    7,10,
+    8,11;
+
+  // should result in a (3x2)-matrix with columns
+  //  e.g. [0, 3, 6], [-3, 0, 3] (the lattice should be the same)
+  print(intersectLattices(A,B));
+
+  // another example
+  intmat C[2][3] =
+    1,0,0,
+    3,2,5;
+
+  intmat D[2][3] =
+    4,5,0,
+    0,5,0;
+
+  // should result in a (3x2)-matrix whose columns generate the
+  // same lattice as [1,5], [0, 20]
+  print(intersectLattices(C,D));
+}
+
+////////////////////////////////////
+
+proc intInverse(intmat A);
+"USAGE: intInverse(A); intmat A
+PURPOSE: compute the integral inverse of the intmat A.
+If det(A) is neither 1 nor -1 an error is returned.
+RETURNS: intmat
+EXAMPLE: example intInverse; shows an example
+"
+{
+  int d = det(A);
+
+  if ( d * d != 1 ) // is d = 1 or -1? Else: error
+  {
+    ERROR("determinant of the given intmat has to be 1 or -1.");
+  }
+
+  int c;
+  int i,j;
+  intmat C[nrows(A)][ncols(A)];
+  intmat Ad;
+  int s;
+
+  for ( i = 1; i <= nrows(C); i++ )
+  {
+    for ( j = 1; j <= ncols(C); j++ )
+    {
+      Ad = intAdjoint(A,i,j);
+      s = 1;
+
+      if ( ((i + j) % 2) > 0 )
+      {
+        s = -1;
+      }
+
+      C[i,j] = d * s * det(Ad); // mult by d is equal to div by det
+    }
+  }
+
+  C = transpose(C);
+
+  return(C);
+}
+example
+{
+  "EXAMPLE"; echo = 2;
+
+  intmat A[3][3] =
+    1,1,3,
+    3,2,0,
+    0,0,1;
+
+  intmat B = intInverse(A);
+
+  // should be the unit matrix
+  print(A * B);
+
+  // another example
+  intmat C[2][2] =
+    2,1,
+    3,2;
+
+  intmat D  = intInverse(C);
+
+  // should be the unit matrix
+  print(C * D);
+
+  kill A, B, C, D;
+}
+
+
+/******************************************************/
+static proc intAdjoint(intmat A, int indrow, int indcol)
+"USAGE: intAdjoint(A); intmat A
+PURPOSE: return the matrix where the given row and column are deleted.
+RETURNS: intmat
+EXAMPLE: example intAdjoint; shows an example
+"
+{
+  int n = nrows(A);
+  int m = ncols(A);
+  int i, j;
+  intmat B[n - 1][m - 1];
+  int a, b;
+
+  for ( i = 1; i < indrow; i++ )
+  {
+    for ( j = 1; j < indcol; j++ )
+    {
+      B[i,j] = A[i,j];
+    }
+    for ( j = indcol + 1; j <= ncols(A); j++ )
+    {
+      B[i,j - 1] = A[i,j];
+    }
+  }
+
+  for ( i = indrow + 1; i <= nrows(A); i++ )
+  {
+    for ( j = 1; j < indcol; j++ )
+    {
+      B[i - 1,j] = A[i,j];
+    }
+    for ( j = indcol+1; j <= ncols(A); j++ )
+    {
+      B[i - 1,j - 1] = A[i,j];
+    }
+  }
+
+  return(B);
+}
+example
+{
+  "EXAMPLE"; echo = 2;
+
+  intmat A[2][3] =
+    1,3,5,
+    2,4,6;
+
+  intmat B = intAdjoint(A,2,2);
+  print(B);
+
+  kill A,B;
+}
+
+/******************************************************/
+proc integralSection(intmat P);
+"USAGE: integralSection(P); intmat P
+PURPOSE: for a given linear surjective map P of lattices
+ this procedure returns an integral section of P.
+RETURNS: intmat
+EXAMPLE: example integralSection; shows an example
+"
+{
+  int m = nrows(P);
+  int n = ncols(P);
+
+  if ( m == n )
+  {
+    intmat U = intInverse(P);
+  }
+  else
+  {
+    intmat U = (hermiteNormalForm(P, "transform"))[2];
+
+    // delete columns m+1 to n
+    intmat Udel[nrows(U)][ncols(U) - (n - m)];
+    int k;
+    int z;
+
+    for ( k = 1; k <= nrows(U); k++ )
+    {
+      for ( z = 1; z <= m; z++ )
+      {
+        Udel[k,z] = U[k,z];
+      }
+    }
+
+    U = Udel;
+  }
+
+  return(U);
+}
+example
+{
+  "EXAMPLE"; echo = 2;
+
+  intmat P[2][4] =
+    1,3,4,6,
+    2,4,5,7;
+
+  // should be a matrix with two columns
+  // for example: [-2, 1, 0, 0], [3, -3, 0, 1]
+  intmat U = integralSection(P);
+
+  print(U);
+  print(P * U);
+
+  kill U;
+}
+
+
+
+/******************************************************/
+proc factorgroup(G,H)
+"USAGE: factorgroup(G,H); list G, list H
+PURPOSE: returns a representation of the factor group G mod H using the first isomorphism thm
+RETURNS: list
+EXAMPLE: example factorgroup(G,H); shows an example
+"
+{
+  intmat S1 = G[1];
+  intmat L1 = G[2];
+  intmat S2 = H[1];
+  intmat L2 = H[2];
+
+  // check whether G,H are subgroups of a common group, i.e. whether L1 and L2 span the same lattice
+  if ( !isSublattice(L1,L2) || !isSublattice(L2,L1))
+  {
+    ERROR("G and H are not subgroups of a common group.");
+  }
+
+  // check whether H is a subgroup of G, i.e. whether S2 is a sublattice of S1+L1
+  intmat B = concatintmat(S1,L1); // check whether this gives the concatinated matrix
+  if ( !isSublattice(S2,B) )
+  {
+    ERROR("H is not a subgroup of G");
+  }
+  // use first isomorphism thm to get the factor group
+  intmat L = concatintmat(L1,S2); // check whether this gives the concatinated matrix
+  list GmodH;
+  GmodH[1]=S1;
+  GmodH[2]=L;
+  return(GmodH);
+}
+example
+{
+  "EXAMPLE"; echo = 2;
+
+  intmat S1[2][2] =
+    1,0,
+    0,1;
+  intmat L1[2][1] =
+    2,
+    0;
+
+  intmat S2[2][1] =
+    1,
+    0;
+  intmat L2[2][1] =
+    2,
+    0;
+
+  list G = createGroup(S1,L1);
+  list H = createGroup(S2,L2);
+
+  list N = factorgroup(G,H);
+  print(N);
+
+  kill G,H,N,S1,L1,S2,L2;
+
+}
+
+/******************************************************/
+proc productgroup(G,H)
+"USAGE: productgroup(G,H); list G, list H
+PURPOSE: Returns a representation of the group G x H
+RETURNS: list
+EXAMPLE: example productgroup(G,H); shows an example
+"
+{
+  intmat S1 = G[1];
+  intmat L1 = G[2];
+  intmat S2 = H[1];
+  intmat L2 = H[2];
+  intmat OS1[nrows(S1)][ncols(S2)];
+  intmat OS2[nrows(S2)][ncols(S1)];
+  intmat OL1[nrows(L1)][ncols(L2)];
+  intmat OL2[nrows(L2)][ncols(L1)];
+
+  // concatinate matrices to get S
+  intmat A = concatintmat(S1,OS1);
+  intmat B = concatintmat(OS2,S2);
+  intmat At = transpose(A);
+  intmat Bt = transpose(B);
+  intmat St = concatintmat(At,Bt);
+  intmat S = transpose(St);
+
+  // concatinate matrices to get L
+  intmat C = concatintmat(L1,OL1);
+  intmat D = concatintmat(OL2,L2);
+  intmat Ct = transpose(C);
+  intmat Dt = transpose(D);
+  intmat Lt = concatintmat(Ct,Dt);
+  intmat L = transpose(Lt);
+
+  list GxH;
+  GxH[1]=S;
+  GxH[2]=L;
+  return(GxH);
+}
+example
+{
+  "EXAMPLE"; echo = 2;
+
+  intmat S1[2][2] =
+    1,0,
+    0,1;
+  intmat L1[2][1] =
+    2,
+    0;
+
+  intmat S2[2][2] =
+    1,0,
+    0,2;
+  intmat L2[2][1] =
+    0,
+    3;
+
+  list G = createGroup(S1,L1);
+  list H = createGroup(S2,L2);
+
+  list N = productgroup(G,H);
+  print(N);
+
+  kill G,H,N,S1,L1,S2,L2;
+
+}
+
+/******************************************************/
+proc primitiveSpan(intmat V);
+"USAGE: primitiveSpan(V); intmat V
+PURPOSE: compute an integral basis for the minimal primitive
+sublattice that contains the given vectors, i.e. the columns of V.
+RETURNS: int, where 0 is false and 1 is true.
+EXAMPLE: example primitiveSpan; shows an example
+"
+{
+  int n = ncols(V);
+  int m = nrows(V);
+  int r = intRank(V);
+
+
+  if ( r == 0 )
+  {
+    intmat P[m][1]; //  this is the m-zero-vector now
+  }
+  else
+  {
+    list L = smithNormalForm(V, "transform"); // L = [A,S,B] where S is the smith-NF and S = A*S*B
+    intmat P = intInverse(L[1]);
+
+//    print(L);
+
+    if ( r < m )
+    {
+      // delete columns r+1 to m in P:
+      intmat Pdel[nrows(P)][r];
+      int i,j;
+
+      for ( i = 1; i <= nrows(Pdel); i++ )
+      {
+        for ( j = 1; j <= ncols(Pdel); j++ )
+        {
+          Pdel[i,j] = P[i,j];
+        }
+      }
+
+      P = Pdel;
+    }
+  }
+
+  return(P);
+}
+example
+{
+  "EXAMPLE"; echo = 2;
+
+  intmat V[3][2] =
+    1,4,
+    2,5,
+    3,6;
+
+  // should return a (3x2)-matrix whose columns
+  // generate the same lattice as [1, 2, 3] and [0, 1, 2]
+  intmat R = primitiveSpan(V);
+  print(R);
+
+  // another example
+  intmat W[2][2] =
+    1,0,
+    0,1;
+
+  // should return a (2x2)-matrix whose columns
+  // generate the same lattice as [1, 0] and [0, 1]
+  intmat S = primitiveSpan(W);
+  print(S);
+
+  kill V, R, S, W;
+}
+
+/***********************************************************/
diff --git a/Singular/LIB/ncalg.lib b/Singular/LIB/ncalg.lib
new file mode 100644
index 0000000..651a4bb
--- /dev/null
+++ b/Singular/LIB/ncalg.lib
@@ -0,0 +1,16288 @@
+//////////////////////////////////////////////////////////////////////////////
+version="version ncalg.lib 4.0.0.0 Jun_2013 "; // $Id: a480d0fbd674960ea587aca8205cece0ab43a3f5 $
+category="Noncommutative";
+info="
+LIBRARY:  ncalg.lib      Definitions of important G- and GR-algebras
+AUTHORS:  Viktor Levandovskyy,     levandov at mathematik.uni-kl.de,
+@*        Oleksandr Motsak,        U at D, where U={motsak}, D={mathematik.uni-kl.de}
+
+CONVENTIONS: This library provides pre-defined important noncommutative algebras.
+@* For universal enveloping algebras of finite dimensional Lie algebras sl_n, gl_n, g_2 etc.
+there are functions @code{makeUsl}, @code{makeUgl}, @code{makeUg2} etc.
+@* For quantized enveloping algebras U_q(sl_2) and U_q(sl_3), there are functions @code{makeQsl2}, @code{makeQsl3})
+and for non-standard quantum deformation of so_3, there is the function @code{makeQso3}.
+@* For bigger algebras we suppress the output of the (lengthy) list of non-commutative relations
+and provide only the number of these relations instead.
+
+PROCEDURES:
+  makeUsl2([p])    create U(sl_2) in the variables (e,f,h) in char p>=0
+  makeUsl(n[,p])   create U(sl_n) in char p>=0
+  makeUgl(n,[p])   create U(gl_n) in the variables (e_i_j (1<i,j<n)) in char p>=0
+  makeUso5([p])    create U(so_5) in the variables (x(i),y(i),H(i)) in char p>=0
+  makeUso6([p])    create U(so_6) in the variables (x(i),y(i),H(i)) in char p>=0
+  makeUso7([p])    create U(so_7) in the variables (x(i),y(i),H(i)) in char p>=0
+  makeUso8([p])    create U(so_8) in the variables (x(i),y(i),H(i)) in char p>=0
+  makeUso9([p])    create U(so_9) in the variables (x(i),y(i),H(i)) in char p>=0
+  makeUso10([p])   create U(so_{10}) in the variables (x(i),y(i),H(i)) in char p>=0
+  makeUso11([p])   create U(so_{11}) in the variables (x(i),y(i),H(i)) in char p>=0
+  makeUso12([p])   create U(so_{12}) in the variables (x(i),y(i),H(i)) in char p>=0
+  makeUsp1([p])    create U(sp_1) in the variables (x(i),y(i),H(i)) in char p>=0
+  makeUsp2([p])    create U(sp_2) in the variables (x(i),y(i),H(i)) in char p>=0
+  makeUsp3([p])    create U(sp_3) in the variables (x(i),y(i),H(i)) in char p>=0
+  makeUsp4([p])    create U(sp_4) in the variables (x(i),y(i),H(i)) in char p>=0
+  makeUsp5([p])    create U(sp_5) in the variables (x(i),y(i),H(i)) in char p>=0
+  makeUg2([p])     create U(g_2) in the variables (x(i),y(i),Ha,Hb) in char p>=0
+  makeUf4([p])     create U(f_4) in the variables (x(i),y(i),H(i)) in char p>=0
+  makeUe6([p])     create U(e_6) in the variables (x(i),y(i),H(i)) in char p>=0
+  makeUe7([p])     create U(e_7) in the variables (x(i),y(i),H(i)) in char p>=0
+  makeUe8([p])     create U(e_8) in the variables (x(i),y(i),H(i)) in char p>=0
+  makeQso3([n])    create U_q(so_3) in the presentation of Klimyk (if int n is given, the quantum parameter will be specialized at the 2n-th root of unity)
+  makeQsl2([n])    preparation for U_q(sl_2) as factor-algebra; if n is specified, the quantum parameter q will be specialized at the n-th root of unity
+  makeQsl3([n])    preparation for U_q(sl_3) as factor-algebra; if n is specified, the quantum parameter q will be specialized at the n-th root of unity
+  Qso3Casimir(n [,m]) returns a list with the (optionally normalized) Casimir elements of U_q(so_3) for the quantum parameter specialized at the 2n-th root of unity
+  GKZsystem(A, sord, alg [,v])  define a ring and a Gelfand-Kapranov-Zelevinsky system of differential equations
+";
+
+LIB "nctools.lib"; // rootofUnity,
+LIB "general.lib";
+LIB "toric.lib"; // needed for GKZsystem
+
+///////////////////////////////////////////////////////////////////////////////
+static proc defInt ( list # )
+// return 0 or int(#)
+{
+  int @p = 0;
+  if ( size(#) > 0 )
+  {
+    if ( typeof( #[1] ) == "int" )
+    {
+      @p = #[1];
+    }
+  }
+  return (@p);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+proc makeUsl2(list #)
+"USAGE:   makeUsl2([p]), p an optional integer (field characteristic)
+RETURN:  ring
+PURPOSE: set up the U(sl_2) in the variables e,f,h over the field of char p
+NOTE:    activate this ring with the @code{setring} command
+SEE ALSO: makeUsl, makeUg2, makeUgl
+EXAMPLE: example makeUsl2; shows examples
+"{
+   int @p = defInt(#);
+   ring @@@rrr=@p,(e,f,h),dp;
+   matrix D[3][3]=0;
+   D[1,2]=-h;
+   D[1,3]=2*e;
+   D[2,3]=-2*f;
+   def @@RR=nc_algebra(1,D);
+   return(@@RR);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   def a=makeUsl2();
+   setring a;
+   a;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+proc makeUsl(int n, list #)
+"USAGE:   makeUsl(n,[p]); n an integer, n>1; p an optional integer (field characteristic)
+RETURN:  ring
+PURPOSE: set up the U(sl_n) in the variables ( x(i),y(i),h(i) | i=1..n+1) over the field of char p
+NOTE:    activate this ring with the @code{setring} command
+@*       This presentation of U(sl_n) is the standard one, i.e. positive resp. negative roots are denoted by x(i) resp. y(i) and the Cartan elements are denoted by h(i).
+@* The variables are ordered as x(1),...x(n),y(1),...,y(n),h(1),...h(n).
+SEE ALSO: makeUsl2, makeUg2, makeUgl, makeQsl3, makeQso3
+EXAMPLE: example makeUsl; shows examples
+"{
+  if (n<2)
+  {
+    print("Incorrect input");
+    return(0);
+  }
+  if (n==2)
+  {
+    def @@@a=makeUsl2(#);
+    setring @@@a;
+    return(@@@a);
+  }
+
+  int @p = defInt(#);
+
+  ring @@@rr=@p,(x(1..n*(n-1) div 2),y(1..n*(n-1) div 2 ),h(1..n-1)),dp;
+  matrix TMP[n][n]=0;
+  int k,l=1,1;
+  int buf=0;
+  list X,Y,H;
+  for(k=1; k<=n; k++)
+  {
+    for(l=k+1; l<=n; l++)
+    {
+      buf = (l-k-1)*(2*n-l+k) div 2 + k;
+      TMP[k,l] = -1; // for conformance with GAP
+      X[buf] = TMP;
+      TMP = 0;
+      TMP[l,k] = -1;
+      Y[buf] = TMP;
+      TMP=0;
+    }
+  }
+  for(k=1; k<=n-1; k++)
+  {
+    TMP[k,k]=1;
+    TMP[k+1,k+1]=-1;
+    H[k]=TMP;
+    TMP=0;
+  }
+
+  int i,j=1,1;
+  number p,q=0,0;
+  list V=X+Y+H;
+
+  int v = size(V);
+
+  matrix D[v][v]=0;
+
+  for(k=1; k<=v; k++)
+  {
+    for(l=k+1; l<=v; l++)
+    {
+      TMP=V[l]*V[k]-V[k]*V[l];
+
+      for(i=1; i<=n; i++)
+      {
+        for(j=i+1; j<=n; j++)
+        {
+          buf=(j-i-1)*(2*n-j+i) div 2+i;
+          if (TMP[i,j]!=0)
+          {
+            D[k,l]=D[k,l]+(leadcoef(TMP[i,j])/leadcoef(X[buf][i,j]))*x(buf);
+          }
+          if (TMP[j,i]!=0)
+          {
+            D[k,l]=D[k,l]+(leadcoef(TMP[j,i])/leadcoef(Y[buf][j,i]))*y(buf);
+          }
+        }
+      }
+
+      i=1;
+      while ( (TMP[i,i]==0) && (i<n) ) { i++; }
+
+      for(j=i; j<=n-1; j++)
+      {
+        p=leadcoef(TMP[j,j]);
+        if( p != 0 )
+        {
+                // q=leadcoef(TMP[j+1,j+1]);
+                D[k,l]=D[k,l]+(p/leadcoef(H[j][j,j]))*h(j);
+                //        if ((j!=n-1)&&((p+q)!=0)) {D[k,l]=D[k,l]+(p+q)*h(j+1);}
+                TMP[j+1,j+1]=TMP[j+1,j+1]-p*leadcoef(H[j][j+1,j+1]);
+        }
+      }
+    }
+  }
+  def @@RR=nc_algebra(1,D);
+  return(@@RR);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   def a=makeUsl(3);
+   setring a;
+   a;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+proc makeUg2(list #)
+"USAGE:  makeUg2([p]), p an optional int (field characteristic)
+RETURN:  ring
+PURPOSE: set up the U(g_2) in variables (x(i),y(i),Ha,Hb) for i=1..6 over the field of char p
+NOTE:    activate this ring with the @code{setring} command
+@* the variables are ordered as x(1),...x(6),y(1),...,y(6),Ha,Hb.
+SEE ALSO: makeUsl, makeUgl
+EXAMPLE: example makeUg2; shows examples
+"
+{
+   int @p = defInt(#);
+
+   ring @@@rrr = @p,(x(1..6),y(1..6), Ha, Hb),dp;
+   int N = nvars(@@@rrr);
+   matrix D[N][N]=0;
+
+        // H(i) * X(j):
+                D[1,13] = (2)*var(1); // [ var(13) , var(1) ]
+                D[2,13] = (-3)*var(2); // [ var(13) , var(2) ]
+                D[3,13] = (-1)*var(3); // [ var(13) , var(3) ]
+                D[4,13] = var(4); // [ var(13) , var(4) ]
+                D[5,13] = (3)*var(5); // [ var(13) , var(5) ]
+                D[1,14] = (-1)*var(1); // [ var(14) , var(1) ]
+                D[2,14] = (2)*var(2); // [ var(14) , var(2) ]
+                D[3,14] = var(3); // [ var(14) , var(3) ]
+                D[5,14] = (-1)*var(5); // [ var(14) , var(5) ]
+                D[6,14] = var(6); // [ var(14) , var(6) ]
+        // H(i) * Y(j):
+                D[7,13] = (-2)*var(7); // [ var(13) , var(7) ]
+                D[8,13] = (3)*var(8); // [ var(13) , var(8) ]
+                D[9,13] = var(9); // [ var(13) , var(9) ]
+                D[10,13] = (-1)*var(10); // [ var(13) , var(10) ]
+                D[11,13] = (-3)*var(11); // [ var(13) , var(11) ]
+                D[7,14] = var(7); // [ var(14) , var(7) ]
+                D[8,14] = (-2)*var(8); // [ var(14) , var(8) ]
+                D[9,14] = (-1)*var(9); // [ var(14) , var(9) ]
+                D[11,14] = var(11); // [ var(14) , var(11) ]
+                D[12,14] = (-1)*var(12); // [ var(14) , var(12) ]
+        // Y(i) * X(j):
+                D[1,7] = (-1)*var(13); // [ var(7) , var(1) ]
+                D[3,7] = (-3)*var(2); // [ var(7) , var(3) ]
+                D[4,7] = (-2)*var(3); // [ var(7) , var(4) ]
+                D[5,7] = (-1)*var(4); // [ var(7) , var(5) ]
+                D[2,8] = (-1)*var(14); // [ var(8) , var(2) ]
+                D[3,8] = var(1); // [ var(8) , var(3) ]
+                D[6,8] = (-1)*var(5); // [ var(8) , var(6) ]
+                D[1,9] = (-3)*var(8); // [ var(9) , var(1) ]
+                D[2,9] = var(7); // [ var(9) , var(2) ]
+                D[3,9] = (-1)*var(13)+(-3)*var(14); // [ var(9) , var(3) ]
+                D[4,9] = (2)*var(1); // [ var(9) , var(4) ]
+                D[6,9] = var(4); // [ var(9) , var(6) ]
+                D[1,10] = (-2)*var(9); // [ var(10) , var(1) ]
+                D[3,10] = (2)*var(7); // [ var(10) , var(3) ]
+                D[4,10] = (-2)*var(13)+(-3)*var(14); // [ var(10) , var(4) ]
+                D[5,10] = var(1); // [ var(10) , var(5) ]
+                D[6,10] = (-1)*var(3); // [ var(10) , var(6) ]
+                D[1,11] = (-1)*var(10); // [ var(11) , var(1) ]
+                D[4,11] = var(7); // [ var(11) , var(4) ]
+                D[5,11] = (-1)*var(13)+(-1)*var(14); // [ var(11) , var(5) ]
+                D[6,11] = var(2); // [ var(11) , var(6) ]
+                D[2,12] = (-1)*var(11); // [ var(12) , var(2) ]
+                D[3,12] = var(10); // [ var(12) , var(3) ]
+                D[4,12] = (-1)*var(9); // [ var(12) , var(4) ]
+                D[5,12] = var(8); // [ var(12) , var(5) ]
+                D[6,12] = (-1)*var(13)+(-2)*var(14); // [ var(12) , var(6) ]
+        // X(i) * X(j):
+                D[1,2] = var(3); // [ var(2) , var(1) ]
+                D[1,3] = (2)*var(4); // [ var(3) , var(1) ]
+                D[1,4] = (3)*var(5); // [ var(4) , var(1) ]
+                D[2,5] = var(6); // [ var(5) , var(2) ]
+                D[3,4] = (-3)*var(6); // [ var(4) , var(3) ]
+        // Y(i) * Y(j):
+                D[7,8] = (-1)*var(9); // [ var(8) , var(7) ]
+                D[7,9] = (-2)*var(10); // [ var(9) , var(7) ]
+                D[7,10] = (-3)*var(11); // [ var(10) , var(7) ]
+                D[8,11] = (-1)*var(12); // [ var(11) , var(8) ]
+                D[9,10] = (3)*var(12); // [ var(10) , var(9) ]
+
+   def @@RR=nc_algebra(1,D);
+   return(@@RR);
+
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   def a = makeUg2();
+   a;
+   setring a;
+   // ...  56  noncommutative relations
+}
+
+///////////////////////////////////////////////////////////////////////////////
+proc makeUgl(int n, list #)
+"USAGE:   makeUgl(n,[p]); n an int, n>1;  p an optional int (field characteristic)
+RETURN:  ring
+PURPOSE: set up the U(gl_n) in the (e_ij (1<i,j<n)) presentation (where e_ij corresponds to a matrix with 1 at i,j only) over the field of char p
+NOTE:    activate this ring with the @code{setring} command
+@* the variables are ordered as e_12,e_13,...,e_1n,e_21,...,e_nn.
+SEE ALSO: makeUsl, makeUg2
+EXAMPLE: example makeUgl; shows examples
+"{
+  if (n<2)
+  {
+    print("Incorrect input");
+    return(0);
+  }
+  int @p = defInt(#);
+  int i, j;
+  string vs = "";
+  for ( i = 1; i<= n ; i++ )
+  {
+        for ( j = 1; j<= n ; j++ )
+        {
+            if ( vs != "" )
+            {
+                vs = vs + ", ";
+            }
+            vs = vs + "e_" + string(i) + "_" + string(j);
+        }
+  }
+  string strRING = "ring RING_MAKEUGL=(" + string (@p) + "), (" + vs + "),dp;";
+  execute( strRING );
+  int N = nvars( RING_MAKEUGL ); // n*n
+  matrix D[N][N]=0;
+  int k, l;
+  int ik,il,jk,jl;
+  poly p ;
+  for( k=1; k<=N; k++)
+  {
+    ik = 1 + ((k-1) div n);
+    jk = k -  n*(ik-1);
+
+    for( l=k+1; l<=N; l++)
+    {
+        il = 1 + ((l-1) div n);
+        jl = l -  n*(il-1);
+        p = 0;
+        if( jl == ik )
+        {
+            p = p + var ( (il-1)*n + jk );
+        }
+        if( jk == il )
+        {
+            p = p - var ( (ik-1)*n + jl );
+        }
+        D[k,l]=p;
+    }
+  }
+  def @@RR=nc_algebra(1,D);
+  return(@@RR);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   def a=makeUgl(3);
+   setring a; a;
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+proc makeQso3(list #)
+"USAGE:   makeQso3([n]), n an optional int
+PURPOSE: set up the U_q(so_3) in the presentation of Klimyk; if n is specified, the quantum parameter Q will be specialized at the (2n)-th root of unity
+RETURN:  ring
+NOTE:    activate this ring with the @code{setring} command
+SEE ALSO: makeUsl, makeUg2, makeUgl, makeQsl2, makeQsl3, Qso3Casimir
+EXAMPLE: example makeQso3; shows examples
+"{
+  int @p = 2*defInt(#);
+  ring @@@r=(0,Q),(x,y,z),dp;
+  minpoly = rootofUnity(@p);
+  matrix C[3][3];
+  C[1,2]=Q2;
+  C[1,3]=1/Q2;
+  C[2,3]=Q2;
+  matrix D[3][3];
+  D[1,2]=-Q*z;
+  D[1,3]=1/Q*y;
+  D[2,3]=-Q*x;
+  def @@RR=nc_algebra(C,D);
+  return(@@RR);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   def K = makeQso3(3);
+   setring K;
+   K;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+proc Qso3Casimir(int n, list #)
+"USAGE:   Qso3Casimir(n [,m]), n an integer, m an optional integer
+RETURN:  list (of polynomials)
+PURPOSE: compute the Casimir (central) elements of U_q(so_3) for the quantum parameter specialized at the n-th root of unity; if m!=0 is given, polynomials will be normalized
+ASSUME:    the basering must be U_q(so_3)
+SEE ALSO: makeQso3
+EXAMPLE: example Qso3Casimir; shows examples
+"{
+  if ( npars(basering) !=1 )
+  {
+    "Error: wrong algebra. U_q(so3) has only one parameter";
+    return(0);
+  }
+  if (n<1) { return(0); }
+  number Q = par(1);
+  int N=(n-1) div 2;
+  int NV=nvars(basering);
+  number k1,k2;
+  poly p,rs,hlp;
+  list cp;
+  int j;
+  p=var(1);
+  for(j=0; j<=N; j++)
+  {
+    k1 = binomial(n-j,j);
+    k1=k1/(n-j);
+    k1=k1*((-1)^j);
+    k2=((Q^2)/(Q^4-1))^(2*j);
+    k2=k2*k1;
+    hlp=k2*(p)^(n-(2*j));
+    rs=rs+hlp;
+    hlp=0; k2=0; k1=0;
+  }
+  if (size(#)>0)
+  {
+    int m = int(#[1]);
+    if (m!=0)
+    {
+       rs = cleardenom(rs);
+    }
+  }
+  cp[1] = rs;
+  for(j=2; j<=NV; j++)
+  {
+    cp[j] = subst(rs,var(1),var(j));
+  }
+  return(cp);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   def R = makeQso3(5);
+   setring R;
+   list C = Qso3Casimir(5);
+   C;
+   list Cnorm = Qso3Casimir(5,1);
+   Cnorm;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+proc makeQsl2(list #)
+"USAGE:   makeQsl2([n]), n an optional int
+RETURN:   ring
+PURPOSE:  define the U_q(sl_2) as a factor-ring of a ring V_q(sl_2) modulo the ideal @code{Qideal}
+NOTE:   the output consists of a ring, presenting V_q(sl_2) together with the ideal called @code{Qideal} in this ring
+@* activate this ring with the @code{setring} command
+@* in order to create the U_q(sl_2) from the output, execute the command like @code{qring Usl2q = Qideal;}
+@* If n is specified, the quantum parameter q will be specialized at the n-th root of unity
+SEE ALSO: makeUsl, makeQsl3, makeQso3
+EXAMPLE: example makeQsl2; shows examples
+"{
+  ring r=(0,q),(E,F,Ke,Kf),dp;
+  int @p = defInt(#);
+  if (@p >1)
+  {
+    minpoly = rootofUnity(@p);
+  }
+  matrix C = UpOneMatrix(4);;
+  matrix D[4][4];
+  C[1,3]=q^2;
+  C[2,3]=1/(q^2);
+  C[1,4]=1/(q^2);
+  C[2,4]=q^2;
+  D[1,2]=(1/(q-(1/q)))*(-Ke+Kf);
+  def @@RR=nc_algebra(C,D);
+  setring @@RR;
+  ideal Qideal = Ke*Kf-1;
+  Qideal = twostd(Qideal);
+  export Qideal;
+  return(@@RR);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   def A = makeQsl2(3);
+   setring A;
+   Qideal;
+   qring Usl2q = Qideal;
+   Usl2q;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+proc makeQsl3(list #)
+"USAGE:   makeQsl3([n]), n an optional int
+RETURN:   ring
+PURPOSE:  define the U_q(sl_3) as a factor-ring of a ring V_q(sl_3) modulo the ideal @code{Qideal}
+NOTE:   the output consists of a ring, presenting V_q(sl_3) together with the ideal called @code{Qideal} in this ring
+@* activate this ring with the @code{setring} command
+@* in order to create the U_q(sl_3) from the output, execute the command like @code{qring Usl3q = Qideal;}
+@* If n is specified, the quantum parameter q will be specialized at the n-th root of unity
+SEE ALSO: makeUsl, makeQsl2, makeQso3
+EXAMPLE: example makeQsl3; shows examples
+"{
+  int @p = defInt(#);
+  ring @@@rrr=(0, q), (f12, f13, f23, k1, k2, l1, l2, e12, e13, e23), wp(2, 3, 2, 1, 1, 1, 1, 2, 3, 2);
+  if (@p >1)
+  {
+    minpoly = rootofUnity(@p);
+  }
+  int @n = nvars(@@@rrr);
+  matrix C = UpOneMatrix(@n);
+  matrix D[@n][@n];
+  // some constants
+  number q1 =    1/q;
+  number Q  = (q )^2;
+  number Q1 = (q1)^2;
+  //   number QQ = Q - Q1; // q2 - 1/(q2)
+  number QQ1= 1 / (Q - Q1);
+  // relations:
+  C[1,2] = Q1;
+  C[2,3] = C[1,2];
+  C[8,9] = C[1,2];
+  C[9,10]= C[1,2];
+  C[1,3] = Q;
+  C[8,10]= C[1,3];
+
+  D[1,3] = -q*(f13);
+  D[8,10]= -q*(e13);
+  // V_q(sl_3)
+  D[1,8] = QQ1 * ( (k1) ^ 2 - (l1) ^ 2 );
+  D[3,10]= QQ1 * ( (k2) ^ 2 - (l2) ^ 2 );
+  D[2,9] = -QQ1 * ( ((k1)^2)*((k2)^2) - ((l1)^2)*((l2)^2) );
+  D[2, 8] =   q * (f23) * ((k1)^2);
+  D[3, 9] =   q * ((k2)^2) * (e12);
+  D[1, 9] = -q1 * ((l1)^2) * (e23);
+  D[2, 10]= -q1 * (f12) * ((l2)^2);
+  // k1
+  C[ 4, 8 ]= Q1;
+  C[ 4, 9 ]= q1;
+  C[ 4, 10]= q;
+  // l1
+  C[ 6, 8 ]= Q;
+  C[ 6, 9 ]= q;
+  C[ 6, 10]= q1;
+  // k2
+  C[ 5, 8 ]= q;
+  C[ 5, 9 ]= q1;
+  C[ 5, 10]= Q1;
+  // l2
+  C[ 7, 8 ]= q1;
+  C[ 7, 9 ]= q;
+  C[ 7, 10]= Q;
+  // k1
+  C[ 1, 4 ]= Q1;
+  C[ 2, 4 ]= q1;
+  C[ 3, 4 ]= q;
+  // l1
+  C[ 1, 6 ]= Q;
+  C[ 2, 6 ]= q;
+  C[ 3, 6 ]= q1;
+  // k2
+  C[ 1, 5 ]= q;
+  C[ 2, 5 ]= q1;
+  C[ 3, 5 ]= Q1;
+  // l2
+  C[ 1, 7 ]= q1;
+  C[ 2, 7 ]= q;
+  C[ 3, 7 ]= Q;
+  def @@RR=nc_algebra(C,D); // the V_q(makeUsl3) is done
+  setring @@RR;
+  ideal Qideal = k1*l1-1,  k2*l2-1;
+  Qideal = twostd(Qideal);
+  export Qideal;
+  return(@@RR);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   def B = makeQsl3(5);
+   setring B;
+   qring Usl3q = Qideal;
+   Usl3q;
+}
+
+proc GKZsystem(intmat A, string sord, string alg, list #)
+"USAGE:   GKZsystem(A, sord, alg, [,v]); A intmat, sord, alg string, v intvec
+RETURN:  ring
+PURPOSE: define a ring (Weyl algebra) and create a Gelfand-Kapranov-Zelevinsky (GKZ) system of equations in a ring from the following data:
+@*        @code{A}    is an intmat, defining the system,
+@*        @code{sord} is a string with desired term ordering,
+@*        @code{alg}  is a string, saying which algorithm to use (exactly like in toric_lib),
+@*        @code{v}    is an optional intvec.
+@* In addition, the ideal called @code{GKZid} containing actual equations is calculated and exported to the ring.
+NOTE:    activate the output ring with the @code{setring} command. This procedure is elaborated by Oleksandr Iena
+ASSUME: This procedure uses toric_lib and therefore inherits its input requirements:
+@*        possible values for input variable @code{alg} are: \"ect\",\"pt\",\"blr\", \"hs\", \"du\".
+@*        As for the term ordering, it should be a string @code{sord} in @sc{Singular} format like \"lp\",\"dp\", etc.
+@*        Please consult the toric_lib for allowed orderings and more details.
+SEE ALSO: toric_lib
+EXAMPLE: example GKZsystem; shows examples
+"{
+  int @d = nrows(A);
+  int n = ncols(A);
+  execute("ring r1=0,(d(1..n)),"+sord+";");
+  ideal I0;
+  if (size(#)==0)
+  {
+    I0 = toric_ideal(A, alg);
+  }
+  else
+  {
+    if ( typeof(#[1]) == "intvec" )
+    {
+      intvec V = intvec(#[1]);
+      I0 = toric_ideal(A, alg, V);
+    }
+    else
+    {
+      "Wrong type of the optional argument. Intvec expected.";
+      return();
+    }
+  }
+  string sord2 = "(a(0:" + string(n) + ")," + sord + ")";
+  execute("ring GR = (0,b(1.. at d)),(x(1..n),d(1..n)),"+sord2+";");
+  def W=Weyl(); setring W;
+  kill GR;
+  int i,j;
+  poly p;
+  ideal I;
+  for (i=1; i<=@d; i++)
+  {
+    p = -b(i);
+    for (j=1; j<=n; j++)
+    {
+      p = p+ A[i,j]*x(j)*d(j);
+    }
+    I = I, p;
+  }
+  I = I, imap(r1,I0);
+  I = simplify(I,2);
+  ideal GKZid = I;
+  export(GKZid);
+  return(W);
+}
+example
+{"EXAMPLE:"; echo = 2;
+  // example 3.1.4 from the [SST] without the vector w
+  intmat A[2][4]=3,2,1,0,0,1,2,3;
+  print(A);
+  def D1 = GKZsystem(A,"lp","ect");
+  setring D1;
+  D1;
+  print(GKZid);
+  // now, consider A with the vector w=1,1,1,1
+  intvec v=1,1,1,1;
+  def D2 = GKZsystem(A,"lp","blr",v);
+  setring D2;
+  print(GKZid);
+}
+// easier example: 3.1.1 from SST
+//   intmat A[2][3]=2,1,0,0,1,2;
+
+///////////////////////////////////////////////////////////////////////////////
+
+// need: real Uso3 in the symmetric presentation
+// is not isomorphic to Usl2 over R (but C)
+proc makeUso3(list #)
+"USAGE:   makeUso3([p]), p an optional int
+PURPOSE: set up the real U(so_3) algebra in the symmetric presentation; if p is specified,
+RETURN:  ring
+NOTE:    activate this ring with the @code{setring} command
+SEE ALSO: makeUsl, makeUgl, makeUso5
+EXAMPLE: example makeUso3; shows examples
+"{
+  int @p = defInt(#);
+  ring @@@r=@p,(x,y,z),dp;
+  matrix D[3][3];
+  D[1,2]=-z;
+  D[1,3]=y;
+  D[2,3]=-x;
+  def @@RR=nc_algebra(1,D);
+  return(@@RR);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   def K = makeUso3(5);
+   setring K;
+   K;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+
+// Algebra: so5(Q) has the type: B2, and defined by:
+
+proc makeUso5(list #)
+"USAGE:   makeUso5([p]); p an optional integer (field characteristic)
+RETURN:  a ring, describing U(so_5)
+NOTE:    You have to activate this ring with the 'setring' command. The presentation of U(so_5) is derived from the Chevalley representation of so_5, positive resp. negative roots are denoted by x(i) resp. y(i); Cartan elements are denoted by h(i).
+SEE ALSO: makeUsl, makeUsp1, makeUe6, makeUe7, makeUe8, makeUg2, makeUf4
+EXAMPLE: example makeUso5; shows examples
+"
+{
+   int @p = defInt(#);
+
+   ring @@@rrr = @p,(X(1..4),Y(1..4),H(1..2)),dp;
+   int N = nvars(@@@rrr);
+   matrix D[N][N]=0;
+
+        // H(i) * X(j):
+                D[1,9] = (2)*var(1); // [ var(9) , var(1) ]
+                D[2,9] = (-1)*var(2); // [ var(9) , var(2) ]
+                D[3,9] = var(3); // [ var(9) , var(3) ]
+                D[1,10] = (-2)*var(1); // [ var(10) , var(1) ]
+                D[2,10] = (2)*var(2); // [ var(10) , var(2) ]
+                D[4,10] = (2)*var(4); // [ var(10) , var(4) ]
+        // H(i) * Y(j):
+                D[5,9] = (-2)*var(5); // [ var(9) , var(5) ]
+                D[6,9] = var(6); // [ var(9) , var(6) ]
+                D[7,9] = (-1)*var(7); // [ var(9) , var(7) ]
+                D[5,10] = (2)*var(5); // [ var(10) , var(5) ]
+                D[6,10] = (-2)*var(6); // [ var(10) , var(6) ]
+                D[8,10] = (-2)*var(8); // [ var(10) , var(8) ]
+        // Y(i) * X(j):
+                D[1,5] = (-1)*var(9); // [ var(5) , var(1) ]
+                D[3,5] = var(2); // [ var(5) , var(3) ]
+                D[2,6] = (-1)*var(10); // [ var(6) , var(2) ]
+                D[3,6] = (-2)*var(1); // [ var(6) , var(3) ]
+                D[4,6] = (-1)*var(3); // [ var(6) , var(4) ]
+                D[1,7] = var(6); // [ var(7) , var(1) ]
+                D[2,7] = (-2)*var(5); // [ var(7) , var(2) ]
+                D[3,7] = (-2)*var(9)+(-1)*var(10); // [ var(7) , var(3) ]
+                D[4,7] = var(2); // [ var(7) , var(4) ]
+                D[2,8] = (-1)*var(7); // [ var(8) , var(2) ]
+                D[3,8] = var(6); // [ var(8) , var(3) ]
+                D[4,8] = (-1)*var(9)+(-1)*var(10); // [ var(8) , var(4) ]
+        // X(i) * X(j):
+                D[1,2] = (-1)*var(3); // [ var(2) , var(1) ]
+                D[2,3] = (2)*var(4); // [ var(3) , var(2) ]
+        // Y(i) * Y(j):
+                D[5,6] = var(7); // [ var(6) , var(5) ]
+                D[6,7] = (-2)*var(8); // [ var(7) , var(6) ]
+   def @@RR=nc_algebra(1,D);
+   return(@@RR);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   def ncAlgebra = makeUso5();
+   ncAlgebra;
+   setring ncAlgebra;
+  // ...  28  noncommutative relations
+}
+////////////////////////////////////////////////////////////////////
+
+// Algebra: so7(Q) has the type: B3, and defined by:
+
+proc makeUso7(list #)
+"USAGE:   makeUso7([p]); p an optional integer (field characteristic)
+RETURN:  a ring, describing U(so_7)
+NOTE:    You have to activate this ring with the 'setring' command. The presentation of U(so_7) is derived from the Chevalley representation of so_7, positive resp. negative roots are denoted by x(i) resp. y(i); Cartan elements are denoted by h(i).
+SEE ALSO: makeUsl, makeUso5, makeUsp1, makeUe6, makeUe7, makeUe8, makeUg2, makeUf4
+EXAMPLE: example makeUso7; shows examples
+"
+{
+   int @p = defInt(#);
+
+   ring @@@rrr = @p,(X(1..9),Y(1..9),H(1..3)),dp;
+   int N = nvars(@@@rrr);
+   matrix D[N][N]=0;
+
+        // H(i) * X(j):
+                D[1,19] = (2)*var(1); // [ var(19) , var(1) ]
+                D[2,19] = (-1)*var(2); // [ var(19) , var(2) ]
+                D[4,19] = var(4); // [ var(19) , var(4) ]
+                D[5,19] = (-1)*var(5); // [ var(19) , var(5) ]
+                D[6,19] = var(6); // [ var(19) , var(6) ]
+                D[7,19] = (-1)*var(7); // [ var(19) , var(7) ]
+                D[8,19] = var(8); // [ var(19) , var(8) ]
+                D[1,20] = (-1)*var(1); // [ var(20) , var(1) ]
+                D[2,20] = (2)*var(2); // [ var(20) , var(2) ]
+                D[3,20] = (-1)*var(3); // [ var(20) , var(3) ]
+                D[4,20] = var(4); // [ var(20) , var(4) ]
+                D[5,20] = var(5); // [ var(20) , var(5) ]
+                D[8,20] = (-1)*var(8); // [ var(20) , var(8) ]
+                D[9,20] = var(9); // [ var(20) , var(9) ]
+                D[2,21] = (-2)*var(2); // [ var(21) , var(2) ]
+                D[3,21] = (2)*var(3); // [ var(21) , var(3) ]
+                D[4,21] = (-2)*var(4); // [ var(21) , var(4) ]
+                D[7,21] = (2)*var(7); // [ var(21) , var(7) ]
+                D[8,21] = (2)*var(8); // [ var(21) , var(8) ]
+        // H(i) * Y(j):
+                D[10,19] = (-2)*var(10); // [ var(19) , var(10) ]
+                D[11,19] = var(11); // [ var(19) , var(11) ]
+                D[13,19] = (-1)*var(13); // [ var(19) , var(13) ]
+                D[14,19] = var(14); // [ var(19) , var(14) ]
+                D[15,19] = (-1)*var(15); // [ var(19) , var(15) ]
+                D[16,19] = var(16); // [ var(19) , var(16) ]
+                D[17,19] = (-1)*var(17); // [ var(19) , var(17) ]
+                D[10,20] = var(10); // [ var(20) , var(10) ]
+                D[11,20] = (-2)*var(11); // [ var(20) , var(11) ]
+                D[12,20] = var(12); // [ var(20) , var(12) ]
+                D[13,20] = (-1)*var(13); // [ var(20) , var(13) ]
+                D[14,20] = (-1)*var(14); // [ var(20) , var(14) ]
+                D[17,20] = var(17); // [ var(20) , var(17) ]
+                D[18,20] = (-1)*var(18); // [ var(20) , var(18) ]
+                D[11,21] = (2)*var(11); // [ var(21) , var(11) ]
+                D[12,21] = (-2)*var(12); // [ var(21) , var(12) ]
+                D[13,21] = (2)*var(13); // [ var(21) , var(13) ]
+                D[16,21] = (-2)*var(16); // [ var(21) , var(16) ]
+                D[17,21] = (-2)*var(17); // [ var(21) , var(17) ]
+        // Y(i) * X(j):
+                D[1,10] = (-1)*var(19); // [ var(10) , var(1) ]
+                D[4,10] = var(2); // [ var(10) , var(4) ]
+                D[6,10] = var(5); // [ var(10) , var(6) ]
+                D[8,10] = var(7); // [ var(10) , var(8) ]
+                D[2,11] = (-1)*var(20); // [ var(11) , var(2) ]
+                D[4,11] = (-1)*var(1); // [ var(11) , var(4) ]
+                D[5,11] = var(3); // [ var(11) , var(5) ]
+                D[9,11] = var(8); // [ var(11) , var(9) ]
+                D[3,12] = (-1)*var(21); // [ var(12) , var(3) ]
+                D[5,12] = (-2)*var(2); // [ var(12) , var(5) ]
+                D[6,12] = (-2)*var(4); // [ var(12) , var(6) ]
+                D[7,12] = (-1)*var(5); // [ var(12) , var(7) ]
+                D[8,12] = (-1)*var(6); // [ var(12) , var(8) ]
+                D[1,13] = var(11); // [ var(13) , var(1) ]
+                D[2,13] = (-1)*var(10); // [ var(13) , var(2) ]
+                D[4,13] = (-1)*var(19)+(-1)*var(20); // [ var(13) , var(4) ]
+                D[6,13] = var(3); // [ var(13) , var(6) ]
+                D[9,13] = (-1)*var(7); // [ var(13) , var(9) ]
+                D[2,14] = var(12); // [ var(14) , var(2) ]
+                D[3,14] = (-2)*var(11); // [ var(14) , var(3) ]
+                D[5,14] = (-2)*var(20)+(-1)*var(21); // [ var(14) , var(5) ]
+                D[6,14] = (-2)*var(1); // [ var(14) , var(6) ]
+                D[7,14] = var(3); // [ var(14) , var(7) ]
+                D[9,14] = (-1)*var(6); // [ var(14) , var(9) ]
+                D[1,15] = var(14); // [ var(15) , var(1) ]
+                D[3,15] = (-2)*var(13); // [ var(15) , var(3) ]
+                D[4,15] = var(12); // [ var(15) , var(4) ]
+                D[5,15] = (-2)*var(10); // [ var(15) , var(5) ]
+                D[6,15] = (-2)*var(19)+(-2)*var(20)+(-1)*var(21); // [ var(15) , var(6) ]
+                D[8,15] = var(3); // [ var(15) , var(8) ]
+                D[9,15] = var(5); // [ var(15) , var(9) ]
+                D[3,16] = (-1)*var(14); // [ var(16) , var(3) ]
+                D[5,16] = var(12); // [ var(16) , var(5) ]
+                D[7,16] = (-1)*var(20)+(-1)*var(21); // [ var(16) , var(7) ]
+                D[8,16] = (-1)*var(1); // [ var(16) , var(8) ]
+                D[9,16] = var(4); // [ var(16) , var(9) ]
+                D[1,17] = var(16); // [ var(17) , var(1) ]
+                D[3,17] = (-1)*var(15); // [ var(17) , var(3) ]
+                D[6,17] = var(12); // [ var(17) , var(6) ]
+                D[7,17] = (-1)*var(10); // [ var(17) , var(7) ]
+                D[8,17] = (-1)*var(19)+(-1)*var(20)+(-1)*var(21); // [ var(17) , var(8) ]
+                D[9,17] = (-1)*var(2); // [ var(17) , var(9) ]
+                D[2,18] = var(17); // [ var(18) , var(2) ]
+                D[4,18] = (-1)*var(16); // [ var(18) , var(4) ]
+                D[5,18] = (-1)*var(15); // [ var(18) , var(5) ]
+                D[6,18] = var(14); // [ var(18) , var(6) ]
+                D[7,18] = var(13); // [ var(18) , var(7) ]
+                D[8,18] = (-1)*var(11); // [ var(18) , var(8) ]
+                D[9,18] = (-1)*var(19)+(-2)*var(20)+(-1)*var(21); // [ var(18) , var(9) ]
+        // X(i) * X(j):
+                D[1,2] = (-1)*var(4); // [ var(2) , var(1) ]
+                D[1,5] = (-1)*var(6); // [ var(5) , var(1) ]
+                D[1,7] = (-1)*var(8); // [ var(7) , var(1) ]
+                D[2,3] = (-1)*var(5); // [ var(3) , var(2) ]
+                D[2,8] = (-1)*var(9); // [ var(8) , var(2) ]
+                D[3,4] = var(6); // [ var(4) , var(3) ]
+                D[3,5] = (2)*var(7); // [ var(5) , var(3) ]
+                D[3,6] = (2)*var(8); // [ var(6) , var(3) ]
+                D[4,7] = var(9); // [ var(7) , var(4) ]
+                D[5,6] = (2)*var(9); // [ var(6) , var(5) ]
+        // Y(i) * Y(j):
+                D[10,11] = var(13); // [ var(11) , var(10) ]
+                D[10,14] = var(15); // [ var(14) , var(10) ]
+                D[10,16] = var(17); // [ var(16) , var(10) ]
+                D[11,12] = var(14); // [ var(12) , var(11) ]
+                D[11,17] = var(18); // [ var(17) , var(11) ]
+                D[12,13] = (-1)*var(15); // [ var(13) , var(12) ]
+                D[12,14] = (-2)*var(16); // [ var(14) , var(12) ]
+                D[12,15] = (-2)*var(17); // [ var(15) , var(12) ]
+                D[13,16] = (-1)*var(18); // [ var(16) , var(13) ]
+                D[14,15] = (-2)*var(18); // [ var(15) , var(14) ]
+   def @@RR=nc_algebra(1,D);
+   return(@@RR);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   def ncAlgebra = makeUso7();
+   ncAlgebra;
+   setring ncAlgebra;
+   // ...  107  noncommutative relations
+}
+////////////////////////////////////////////////////////////////////
+
+// Algebra: so9(Q) has the type: B4, and defined by:
+
+proc makeUso9(list #)
+"USAGE:   makeUso9([p]); p an optional integer (field characteristic)
+RETURN:  a ring, describing U(so_9)
+NOTE:    You have to activate this ring with the 'setring' command. The presentation of U(so_9) is derived from the Chevalley representation of so_9, positive resp. negative roots are denoted by x(i) resp. y(i); Cartan elements are denoted by h(i).
+SEE ALSO: makeUsl, makeUso5, makeUsp1, makeUe6, makeUe7, makeUe8, makeUg2, makeUf4
+EXAMPLE: example makeUso9; shows examples
+"
+{
+   int @p = defInt(#);
+
+   ring @@@rrr = @p,(X(1..16),Y(1..16),H(1..4)),dp;
+   int N = nvars(@@@rrr);
+   matrix D[N][N]=0;
+
+        // H(i) * X(j):
+                D[1,33] = (2)*var(1); // [ var(33) , var(1) ]
+                D[2,33] = (-1)*var(2); // [ var(33) , var(2) ]
+                D[5,33] = var(5); // [ var(33) , var(5) ]
+                D[6,33] = (-1)*var(6); // [ var(33) , var(6) ]
+                D[8,33] = var(8); // [ var(33) , var(8) ]
+                D[9,33] = (-1)*var(9); // [ var(33) , var(9) ]
+                D[11,33] = var(11); // [ var(33) , var(11) ]
+                D[12,33] = (-1)*var(12); // [ var(33) , var(12) ]
+                D[13,33] = var(13); // [ var(33) , var(13) ]
+                D[14,33] = (-1)*var(14); // [ var(33) , var(14) ]
+                D[15,33] = var(15); // [ var(33) , var(15) ]
+                D[1,34] = (-1)*var(1); // [ var(34) , var(1) ]
+                D[2,34] = (2)*var(2); // [ var(34) , var(2) ]
+                D[3,34] = (-1)*var(3); // [ var(34) , var(3) ]
+                D[5,34] = var(5); // [ var(34) , var(5) ]
+                D[6,34] = var(6); // [ var(34) , var(6) ]
+                D[7,34] = (-1)*var(7); // [ var(34) , var(7) ]
+                D[9,34] = var(9); // [ var(34) , var(9) ]
+                D[10,34] = (-1)*var(10); // [ var(34) , var(10) ]
+                D[12,34] = var(12); // [ var(34) , var(12) ]
+                D[15,34] = (-1)*var(15); // [ var(34) , var(15) ]
+                D[16,34] = var(16); // [ var(34) , var(16) ]
+                D[2,35] = (-1)*var(2); // [ var(35) , var(2) ]
+                D[3,35] = (2)*var(3); // [ var(35) , var(3) ]
+                D[4,35] = (-1)*var(4); // [ var(35) , var(4) ]
+                D[5,35] = (-1)*var(5); // [ var(35) , var(5) ]
+                D[6,35] = var(6); // [ var(35) , var(6) ]
+                D[7,35] = var(7); // [ var(35) , var(7) ]
+                D[8,35] = var(8); // [ var(35) , var(8) ]
+                D[12,35] = (-1)*var(12); // [ var(35) , var(12) ]
+                D[13,35] = (-1)*var(13); // [ var(35) , var(13) ]
+                D[14,35] = var(14); // [ var(35) , var(14) ]
+                D[15,35] = var(15); // [ var(35) , var(15) ]
+                D[3,36] = (-2)*var(3); // [ var(36) , var(3) ]
+                D[4,36] = (2)*var(4); // [ var(36) , var(4) ]
+                D[6,36] = (-2)*var(6); // [ var(36) , var(6) ]
+                D[8,36] = (-2)*var(8); // [ var(36) , var(8) ]
+                D[10,36] = (2)*var(10); // [ var(36) , var(10) ]
+                D[12,36] = (2)*var(12); // [ var(36) , var(12) ]
+                D[13,36] = (2)*var(13); // [ var(36) , var(13) ]
+        // H(i) * Y(j):
+                D[17,33] = (-2)*var(17); // [ var(33) , var(17) ]
+                D[18,33] = var(18); // [ var(33) , var(18) ]
+                D[21,33] = (-1)*var(21); // [ var(33) , var(21) ]
+                D[22,33] = var(22); // [ var(33) , var(22) ]
+                D[24,33] = (-1)*var(24); // [ var(33) , var(24) ]
+                D[25,33] = var(25); // [ var(33) , var(25) ]
+                D[27,33] = (-1)*var(27); // [ var(33) , var(27) ]
+                D[28,33] = var(28); // [ var(33) , var(28) ]
+                D[29,33] = (-1)*var(29); // [ var(33) , var(29) ]
+                D[30,33] = var(30); // [ var(33) , var(30) ]
+                D[31,33] = (-1)*var(31); // [ var(33) , var(31) ]
+                D[17,34] = var(17); // [ var(34) , var(17) ]
+                D[18,34] = (-2)*var(18); // [ var(34) , var(18) ]
+                D[19,34] = var(19); // [ var(34) , var(19) ]
+                D[21,34] = (-1)*var(21); // [ var(34) , var(21) ]
+                D[22,34] = (-1)*var(22); // [ var(34) , var(22) ]
+                D[23,34] = var(23); // [ var(34) , var(23) ]
+                D[25,34] = (-1)*var(25); // [ var(34) , var(25) ]
+                D[26,34] = var(26); // [ var(34) , var(26) ]
+                D[28,34] = (-1)*var(28); // [ var(34) , var(28) ]
+                D[31,34] = var(31); // [ var(34) , var(31) ]
+                D[32,34] = (-1)*var(32); // [ var(34) , var(32) ]
+                D[18,35] = var(18); // [ var(35) , var(18) ]
+                D[19,35] = (-2)*var(19); // [ var(35) , var(19) ]
+                D[20,35] = var(20); // [ var(35) , var(20) ]
+                D[21,35] = var(21); // [ var(35) , var(21) ]
+                D[22,35] = (-1)*var(22); // [ var(35) , var(22) ]
+                D[23,35] = (-1)*var(23); // [ var(35) , var(23) ]
+                D[24,35] = (-1)*var(24); // [ var(35) , var(24) ]
+                D[28,35] = var(28); // [ var(35) , var(28) ]
+                D[29,35] = var(29); // [ var(35) , var(29) ]
+                D[30,35] = (-1)*var(30); // [ var(35) , var(30) ]
+                D[31,35] = (-1)*var(31); // [ var(35) , var(31) ]
+                D[19,36] = (2)*var(19); // [ var(36) , var(19) ]
+                D[20,36] = (-2)*var(20); // [ var(36) , var(20) ]
+                D[22,36] = (2)*var(22); // [ var(36) , var(22) ]
+                D[24,36] = (2)*var(24); // [ var(36) , var(24) ]
+                D[26,36] = (-2)*var(26); // [ var(36) , var(26) ]
+                D[28,36] = (-2)*var(28); // [ var(36) , var(28) ]
+                D[29,36] = (-2)*var(29); // [ var(36) , var(29) ]
+        // Y(i) * X(j):
+                D[1,17] = (-1)*var(33); // [ var(17) , var(1) ]
+                D[5,17] = var(2); // [ var(17) , var(5) ]
+                D[8,17] = var(6); // [ var(17) , var(8) ]
+                D[11,17] = var(9); // [ var(17) , var(11) ]
+                D[13,17] = var(12); // [ var(17) , var(13) ]
+                D[15,17] = var(14); // [ var(17) , var(15) ]
+                D[2,18] = (-1)*var(34); // [ var(18) , var(2) ]
+                D[5,18] = (-1)*var(1); // [ var(18) , var(5) ]
+                D[6,18] = var(3); // [ var(18) , var(6) ]
+                D[9,18] = var(7); // [ var(18) , var(9) ]
+                D[12,18] = var(10); // [ var(18) , var(12) ]
+                D[16,18] = var(15); // [ var(18) , var(16) ]
+                D[3,19] = (-1)*var(35); // [ var(19) , var(3) ]
+                D[6,19] = (-1)*var(2); // [ var(19) , var(6) ]
+                D[7,19] = var(4); // [ var(19) , var(7) ]
+                D[8,19] = (-1)*var(5); // [ var(19) , var(8) ]
+                D[14,19] = var(12); // [ var(19) , var(14) ]
+                D[15,19] = var(13); // [ var(19) , var(15) ]
+                D[4,20] = (-1)*var(36); // [ var(20) , var(4) ]
+                D[7,20] = (-2)*var(3); // [ var(20) , var(7) ]
+                D[9,20] = (-2)*var(6); // [ var(20) , var(9) ]
+                D[10,20] = (-1)*var(7); // [ var(20) , var(10) ]
+                D[11,20] = (-2)*var(8); // [ var(20) , var(11) ]
+                D[12,20] = (-1)*var(9); // [ var(20) , var(12) ]
+                D[13,20] = (-1)*var(11); // [ var(20) , var(13) ]
+                D[1,21] = var(18); // [ var(21) , var(1) ]
+                D[2,21] = (-1)*var(17); // [ var(21) , var(2) ]
+                D[5,21] = (-1)*var(33)+(-1)*var(34); // [ var(21) , var(5) ]
+                D[8,21] = var(3); // [ var(21) , var(8) ]
+                D[11,21] = var(7); // [ var(21) , var(11) ]
+                D[13,21] = var(10); // [ var(21) , var(13) ]
+                D[16,21] = (-1)*var(14); // [ var(21) , var(16) ]
+                D[2,22] = var(19); // [ var(22) , var(2) ]
+                D[3,22] = (-1)*var(18); // [ var(22) , var(3) ]
+                D[6,22] = (-1)*var(34)+(-1)*var(35); // [ var(22) , var(6) ]
+                D[8,22] = (-1)*var(1); // [ var(22) , var(8) ]
+                D[9,22] = var(4); // [ var(22) , var(9) ]
+                D[14,22] = (-1)*var(10); // [ var(22) , var(14) ]
+                D[16,22] = var(13); // [ var(22) , var(16) ]
+                D[3,23] = var(20); // [ var(23) , var(3) ]
+                D[4,23] = (-2)*var(19); // [ var(23) , var(4) ]
+                D[7,23] = (-2)*var(35)+(-1)*var(36); // [ var(23) , var(7) ]
+                D[9,23] = (-2)*var(2); // [ var(23) , var(9) ]
+                D[10,23] = var(4); // [ var(23) , var(10) ]
+                D[11,23] = (-2)*var(5); // [ var(23) , var(11) ]
+                D[14,23] = (-1)*var(9); // [ var(23) , var(14) ]
+                D[15,23] = (-1)*var(11); // [ var(23) , var(15) ]
+                D[1,24] = var(22); // [ var(24) , var(1) ]
+                D[3,24] = (-1)*var(21); // [ var(24) , var(3) ]
+                D[5,24] = var(19); // [ var(24) , var(5) ]
+                D[6,24] = (-1)*var(17); // [ var(24) , var(6) ]
+                D[8,24] = (-1)*var(33)+(-1)*var(34)+(-1)*var(35); // [ var(24) , var(8) ]
+                D[11,24] = var(4); // [ var(24) , var(11) ]
+                D[15,24] = (-1)*var(10); // [ var(24) , var(15) ]
+                D[16,24] = (-1)*var(12); // [ var(24) , var(16) ]
+                D[2,25] = var(23); // [ var(25) , var(2) ]
+                D[4,25] = (-2)*var(22); // [ var(25) , var(4) ]
+                D[6,25] = var(20); // [ var(25) , var(6) ]
+                D[7,25] = (-2)*var(18); // [ var(25) , var(7) ]
+                D[9,25] = (-2)*var(34)+(-2)*var(35)+(-1)*var(36); // [ var(25) , var(9) ]
+                D[11,25] = (-2)*var(1); // [ var(25) , var(11) ]
+                D[12,25] = var(4); // [ var(25) , var(12) ]
+                D[14,25] = var(7); // [ var(25) , var(14) ]
+                D[16,25] = (-1)*var(11); // [ var(25) , var(16) ]
+                D[4,26] = (-1)*var(23); // [ var(26) , var(4) ]
+                D[7,26] = var(20); // [ var(26) , var(7) ]
+                D[10,26] = (-1)*var(35)+(-1)*var(36); // [ var(26) , var(10) ]
+                D[12,26] = (-1)*var(2); // [ var(26) , var(12) ]
+                D[13,26] = (-1)*var(5); // [ var(26) , var(13) ]
+                D[14,26] = var(6); // [ var(26) , var(14) ]
+                D[15,26] = var(8); // [ var(26) , var(15) ]
+                D[1,27] = var(25); // [ var(27) , var(1) ]
+                D[4,27] = (-2)*var(24); // [ var(27) , var(4) ]
+                D[5,27] = var(23); // [ var(27) , var(5) ]
+                D[7,27] = (-2)*var(21); // [ var(27) , var(7) ]
+                D[8,27] = var(20); // [ var(27) , var(8) ]
+                D[9,27] = (-2)*var(17); // [ var(27) , var(9) ]
+                D[11,27] = (-2)*var(33)+(-2)*var(34)+(-2)*var(35)+(-1)*var(36); // [ var(27) , var(11) ]
+                D[13,27] = var(4); // [ var(27) , var(13) ]
+                D[15,27] = var(7); // [ var(27) , var(15) ]
+                D[16,27] = var(9); // [ var(27) , var(16) ]
+                D[2,28] = var(26); // [ var(28) , var(2) ]
+                D[4,28] = (-1)*var(25); // [ var(28) , var(4) ]
+                D[9,28] = var(20); // [ var(28) , var(9) ]
+                D[10,28] = (-1)*var(18); // [ var(28) , var(10) ]
+                D[12,28] = (-1)*var(34)+(-1)*var(35)+(-1)*var(36); // [ var(28) , var(12) ]
+                D[13,28] = (-1)*var(1); // [ var(28) , var(13) ]
+                D[14,28] = (-1)*var(3); // [ var(28) , var(14) ]
+                D[16,28] = var(8); // [ var(28) , var(16) ]
+                D[1,29] = var(28); // [ var(29) , var(1) ]
+                D[4,29] = (-1)*var(27); // [ var(29) , var(4) ]
+                D[5,29] = var(26); // [ var(29) , var(5) ]
+                D[10,29] = (-1)*var(21); // [ var(29) , var(10) ]
+                D[11,29] = var(20); // [ var(29) , var(11) ]
+                D[12,29] = (-1)*var(17); // [ var(29) , var(12) ]
+                D[13,29] = (-1)*var(33)+(-1)*var(34)+(-1)*var(35)+(-1)*var(36); // [ var(29) , var(13) ]
+                D[15,29] = (-1)*var(3); // [ var(29) , var(15) ]
+                D[16,29] = (-1)*var(6); // [ var(29) , var(16) ]
+                D[3,30] = var(28); // [ var(30) , var(3) ]
+                D[6,30] = (-1)*var(26); // [ var(30) , var(6) ]
+                D[7,30] = (-1)*var(25); // [ var(30) , var(7) ]
+                D[9,30] = var(23); // [ var(30) , var(9) ]
+                D[10,30] = var(22); // [ var(30) , var(10) ]
+                D[12,30] = (-1)*var(19); // [ var(30) , var(12) ]
+                D[14,30] = (-1)*var(34)+(-2)*var(35)+(-1)*var(36); // [ var(30) , var(14) ]
+                D[15,30] = (-1)*var(1); // [ var(30) , var(15) ]
+                D[16,30] = var(5); // [ var(30) , var(16) ]
+                D[1,31] = var(30); // [ var(31) , var(1) ]
+                D[3,31] = var(29); // [ var(31) , var(3) ]
+                D[7,31] = (-1)*var(27); // [ var(31) , var(7) ]
+                D[8,31] = (-1)*var(26); // [ var(31) , var(8) ]
+                D[10,31] = var(24); // [ var(31) , var(10) ]
+                D[11,31] = var(23); // [ var(31) , var(11) ]
+                D[13,31] = (-1)*var(19); // [ var(31) , var(13) ]
+                D[14,31] = (-1)*var(17); // [ var(31) , var(14) ]
+                D[15,31] = (-1)*var(33)+(-1)*var(34)+(-2)*var(35)+(-1)*var(36); // [ var(31) , var(15) ]
+                D[16,31] = (-1)*var(2); // [ var(31) , var(16) ]
+                D[2,32] = var(31); // [ var(32) , var(2) ]
+                D[5,32] = (-1)*var(30); // [ var(32) , var(5) ]
+                D[6,32] = var(29); // [ var(32) , var(6) ]
+                D[8,32] = (-1)*var(28); // [ var(32) , var(8) ]
+                D[9,32] = (-1)*var(27); // [ var(32) , var(9) ]
+                D[11,32] = var(25); // [ var(32) , var(11) ]
+                D[12,32] = var(24); // [ var(32) , var(12) ]
+                D[13,32] = (-1)*var(22); // [ var(32) , var(13) ]
+                D[14,32] = var(21); // [ var(32) , var(14) ]
+                D[15,32] = (-1)*var(18); // [ var(32) , var(15) ]
+                D[16,32] = (-1)*var(33)+(-2)*var(34)+(-2)*var(35)+(-1)*var(36); // [ var(32) , var(16) ]
+        // X(i) * X(j):
+                D[1,2] = (-1)*var(5); // [ var(2) , var(1) ]
+                D[1,6] = (-1)*var(8); // [ var(6) , var(1) ]
+                D[1,9] = (-1)*var(11); // [ var(9) , var(1) ]
+                D[1,12] = (-1)*var(13); // [ var(12) , var(1) ]
+                D[1,14] = (-1)*var(15); // [ var(14) , var(1) ]
+                D[2,3] = (-1)*var(6); // [ var(3) , var(2) ]
+                D[2,7] = (-1)*var(9); // [ var(7) , var(2) ]
+                D[2,10] = (-1)*var(12); // [ var(10) , var(2) ]
+                D[2,15] = (-1)*var(16); // [ var(15) , var(2) ]
+                D[3,4] = (-1)*var(7); // [ var(4) , var(3) ]
+                D[3,5] = var(8); // [ var(5) , var(3) ]
+                D[3,12] = (-1)*var(14); // [ var(12) , var(3) ]
+                D[3,13] = (-1)*var(15); // [ var(13) , var(3) ]
+                D[4,6] = var(9); // [ var(6) , var(4) ]
+                D[4,7] = (2)*var(10); // [ var(7) , var(4) ]
+                D[4,8] = var(11); // [ var(8) , var(4) ]
+                D[4,9] = (2)*var(12); // [ var(9) , var(4) ]
+                D[4,11] = (2)*var(13); // [ var(11) , var(4) ]
+                D[5,7] = (-1)*var(11); // [ var(7) , var(5) ]
+                D[5,10] = (-1)*var(13); // [ var(10) , var(5) ]
+                D[5,14] = var(16); // [ var(14) , var(5) ]
+                D[6,10] = var(14); // [ var(10) , var(6) ]
+                D[6,13] = (-1)*var(16); // [ var(13) , var(6) ]
+                D[7,9] = (2)*var(14); // [ var(9) , var(7) ]
+                D[7,11] = (2)*var(15); // [ var(11) , var(7) ]
+                D[8,10] = var(15); // [ var(10) , var(8) ]
+                D[8,12] = var(16); // [ var(12) , var(8) ]
+                D[9,11] = (2)*var(16); // [ var(11) , var(9) ]
+        // Y(i) * Y(j):
+                D[17,18] = var(21); // [ var(18) , var(17) ]
+                D[17,22] = var(24); // [ var(22) , var(17) ]
+                D[17,25] = var(27); // [ var(25) , var(17) ]
+                D[17,28] = var(29); // [ var(28) , var(17) ]
+                D[17,30] = var(31); // [ var(30) , var(17) ]
+                D[18,19] = var(22); // [ var(19) , var(18) ]
+                D[18,23] = var(25); // [ var(23) , var(18) ]
+                D[18,26] = var(28); // [ var(26) , var(18) ]
+                D[18,31] = var(32); // [ var(31) , var(18) ]
+                D[19,20] = var(23); // [ var(20) , var(19) ]
+                D[19,21] = (-1)*var(24); // [ var(21) , var(19) ]
+                D[19,28] = var(30); // [ var(28) , var(19) ]
+                D[19,29] = var(31); // [ var(29) , var(19) ]
+                D[20,22] = (-1)*var(25); // [ var(22) , var(20) ]
+                D[20,23] = (-2)*var(26); // [ var(23) , var(20) ]
+                D[20,24] = (-1)*var(27); // [ var(24) , var(20) ]
+                D[20,25] = (-2)*var(28); // [ var(25) , var(20) ]
+                D[20,27] = (-2)*var(29); // [ var(27) , var(20) ]
+                D[21,23] = var(27); // [ var(23) , var(21) ]
+                D[21,26] = var(29); // [ var(26) , var(21) ]
+                D[21,30] = (-1)*var(32); // [ var(30) , var(21) ]
+                D[22,26] = (-1)*var(30); // [ var(26) , var(22) ]
+                D[22,29] = var(32); // [ var(29) , var(22) ]
+                D[23,25] = (-2)*var(30); // [ var(25) , var(23) ]
+                D[23,27] = (-2)*var(31); // [ var(27) , var(23) ]
+                D[24,26] = (-1)*var(31); // [ var(26) , var(24) ]
+                D[24,28] = (-1)*var(32); // [ var(28) , var(24) ]
+                D[25,27] = (-2)*var(32); // [ var(27) , var(25) ]
+   def @@RR=nc_algebra(1,D);
+   return(@@RR);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   def ncAlgebra = makeUso9();
+   ncAlgebra;
+   setring ncAlgebra;
+   // ...  264  noncommutative relations
+}
+////////////////////////////////////////////////////////////////////
+
+// Algebra: so11(Q) has the type: B5, and defined by:
+
+proc makeUso11(list #)
+"USAGE:   makeUso11([p]); p an optional integer (field characteristic)
+RETURN:  a ring, describing U(so_{11})
+NOTE:    You have to activate this ring with the 'setring' command. The presentation of U(so_{11}) is derived from the Chevalley representation of so_{11}, positive resp. negative roots are denoted by x(i) resp. y(i); Cartan elements are denoted by h(i).
+SEE ALSO: makeUsl, makeUso5, makeUsp1, makeUe6, makeUe7, makeUe8, makeUg2, makeUf4
+EXAMPLE: example makeUso11; shows examples
+"
+{
+   int @p = defInt(#);
+
+   ring @@@rrr = @p,(X(1..25),Y(1..25),H(1..5)),dp;
+   int N = nvars(@@@rrr);
+   matrix D[N][N]=0;
+
+        // H(i) * X(j):
+                D[1,51] = (2)*var(1); // [ var(51) , var(1) ]
+                D[2,51] = (-1)*var(2); // [ var(51) , var(2) ]
+                D[6,51] = var(6); // [ var(51) , var(6) ]
+                D[7,51] = (-1)*var(7); // [ var(51) , var(7) ]
+                D[10,51] = var(10); // [ var(51) , var(10) ]
+                D[11,51] = (-1)*var(11); // [ var(51) , var(11) ]
+                D[14,51] = var(14); // [ var(51) , var(14) ]
+                D[15,51] = (-1)*var(15); // [ var(51) , var(15) ]
+                D[17,51] = var(17); // [ var(51) , var(17) ]
+                D[18,51] = (-1)*var(18); // [ var(51) , var(18) ]
+                D[20,51] = var(20); // [ var(51) , var(20) ]
+                D[21,51] = (-1)*var(21); // [ var(51) , var(21) ]
+                D[22,51] = var(22); // [ var(51) , var(22) ]
+                D[23,51] = (-1)*var(23); // [ var(51) , var(23) ]
+                D[24,51] = var(24); // [ var(51) , var(24) ]
+                D[1,52] = (-1)*var(1); // [ var(52) , var(1) ]
+                D[2,52] = (2)*var(2); // [ var(52) , var(2) ]
+                D[3,52] = (-1)*var(3); // [ var(52) , var(3) ]
+                D[6,52] = var(6); // [ var(52) , var(6) ]
+                D[7,52] = var(7); // [ var(52) , var(7) ]
+                D[8,52] = (-1)*var(8); // [ var(52) , var(8) ]
+                D[11,52] = var(11); // [ var(52) , var(11) ]
+                D[12,52] = (-1)*var(12); // [ var(52) , var(12) ]
+                D[15,52] = var(15); // [ var(52) , var(15) ]
+                D[16,52] = (-1)*var(16); // [ var(52) , var(16) ]
+                D[18,52] = var(18); // [ var(52) , var(18) ]
+                D[19,52] = (-1)*var(19); // [ var(52) , var(19) ]
+                D[21,52] = var(21); // [ var(52) , var(21) ]
+                D[24,52] = (-1)*var(24); // [ var(52) , var(24) ]
+                D[25,52] = var(25); // [ var(52) , var(25) ]
+                D[2,53] = (-1)*var(2); // [ var(53) , var(2) ]
+                D[3,53] = (2)*var(3); // [ var(53) , var(3) ]
+                D[4,53] = (-1)*var(4); // [ var(53) , var(4) ]
+                D[6,53] = (-1)*var(6); // [ var(53) , var(6) ]
+                D[7,53] = var(7); // [ var(53) , var(7) ]
+                D[8,53] = var(8); // [ var(53) , var(8) ]
+                D[9,53] = (-1)*var(9); // [ var(53) , var(9) ]
+                D[10,53] = var(10); // [ var(53) , var(10) ]
+                D[12,53] = var(12); // [ var(53) , var(12) ]
+                D[13,53] = (-1)*var(13); // [ var(53) , var(13) ]
+                D[16,53] = var(16); // [ var(53) , var(16) ]
+                D[21,53] = (-1)*var(21); // [ var(53) , var(21) ]
+                D[22,53] = (-1)*var(22); // [ var(53) , var(22) ]
+                D[23,53] = var(23); // [ var(53) , var(23) ]
+                D[24,53] = var(24); // [ var(53) , var(24) ]
+                D[3,54] = (-1)*var(3); // [ var(54) , var(3) ]
+                D[4,54] = (2)*var(4); // [ var(54) , var(4) ]
+                D[5,54] = (-1)*var(5); // [ var(54) , var(5) ]
+                D[7,54] = (-1)*var(7); // [ var(54) , var(7) ]
+                D[8,54] = var(8); // [ var(54) , var(8) ]
+                D[9,54] = var(9); // [ var(54) , var(9) ]
+                D[10,54] = (-1)*var(10); // [ var(54) , var(10) ]
+                D[11,54] = var(11); // [ var(54) , var(11) ]
+                D[14,54] = var(14); // [ var(54) , var(14) ]
+                D[16,54] = (-1)*var(16); // [ var(54) , var(16) ]
+                D[18,54] = (-1)*var(18); // [ var(54) , var(18) ]
+                D[19,54] = var(19); // [ var(54) , var(19) ]
+                D[20,54] = (-1)*var(20); // [ var(54) , var(20) ]
+                D[21,54] = var(21); // [ var(54) , var(21) ]
+                D[22,54] = var(22); // [ var(54) , var(22) ]
+                D[4,55] = (-2)*var(4); // [ var(55) , var(4) ]
+                D[5,55] = (2)*var(5); // [ var(55) , var(5) ]
+                D[8,55] = (-2)*var(8); // [ var(55) , var(8) ]
+                D[11,55] = (-2)*var(11); // [ var(55) , var(11) ]
+                D[13,55] = (2)*var(13); // [ var(55) , var(13) ]
+                D[14,55] = (-2)*var(14); // [ var(55) , var(14) ]
+                D[16,55] = (2)*var(16); // [ var(55) , var(16) ]
+                D[18,55] = (2)*var(18); // [ var(55) , var(18) ]
+                D[20,55] = (2)*var(20); // [ var(55) , var(20) ]
+        // H(i) * Y(j):
+                D[26,51] = (-2)*var(26); // [ var(51) , var(26) ]
+                D[27,51] = var(27); // [ var(51) , var(27) ]
+                D[31,51] = (-1)*var(31); // [ var(51) , var(31) ]
+                D[32,51] = var(32); // [ var(51) , var(32) ]
+                D[35,51] = (-1)*var(35); // [ var(51) , var(35) ]
+                D[36,51] = var(36); // [ var(51) , var(36) ]
+                D[39,51] = (-1)*var(39); // [ var(51) , var(39) ]
+                D[40,51] = var(40); // [ var(51) , var(40) ]
+                D[42,51] = (-1)*var(42); // [ var(51) , var(42) ]
+                D[43,51] = var(43); // [ var(51) , var(43) ]
+                D[45,51] = (-1)*var(45); // [ var(51) , var(45) ]
+                D[46,51] = var(46); // [ var(51) , var(46) ]
+                D[47,51] = (-1)*var(47); // [ var(51) , var(47) ]
+                D[48,51] = var(48); // [ var(51) , var(48) ]
+                D[49,51] = (-1)*var(49); // [ var(51) , var(49) ]
+                D[26,52] = var(26); // [ var(52) , var(26) ]
+                D[27,52] = (-2)*var(27); // [ var(52) , var(27) ]
+                D[28,52] = var(28); // [ var(52) , var(28) ]
+                D[31,52] = (-1)*var(31); // [ var(52) , var(31) ]
+                D[32,52] = (-1)*var(32); // [ var(52) , var(32) ]
+                D[33,52] = var(33); // [ var(52) , var(33) ]
+                D[36,52] = (-1)*var(36); // [ var(52) , var(36) ]
+                D[37,52] = var(37); // [ var(52) , var(37) ]
+                D[40,52] = (-1)*var(40); // [ var(52) , var(40) ]
+                D[41,52] = var(41); // [ var(52) , var(41) ]
+                D[43,52] = (-1)*var(43); // [ var(52) , var(43) ]
+                D[44,52] = var(44); // [ var(52) , var(44) ]
+                D[46,52] = (-1)*var(46); // [ var(52) , var(46) ]
+                D[49,52] = var(49); // [ var(52) , var(49) ]
+                D[50,52] = (-1)*var(50); // [ var(52) , var(50) ]
+                D[27,53] = var(27); // [ var(53) , var(27) ]
+                D[28,53] = (-2)*var(28); // [ var(53) , var(28) ]
+                D[29,53] = var(29); // [ var(53) , var(29) ]
+                D[31,53] = var(31); // [ var(53) , var(31) ]
+                D[32,53] = (-1)*var(32); // [ var(53) , var(32) ]
+                D[33,53] = (-1)*var(33); // [ var(53) , var(33) ]
+                D[34,53] = var(34); // [ var(53) , var(34) ]
+                D[35,53] = (-1)*var(35); // [ var(53) , var(35) ]
+                D[37,53] = (-1)*var(37); // [ var(53) , var(37) ]
+                D[38,53] = var(38); // [ var(53) , var(38) ]
+                D[41,53] = (-1)*var(41); // [ var(53) , var(41) ]
+                D[46,53] = var(46); // [ var(53) , var(46) ]
+                D[47,53] = var(47); // [ var(53) , var(47) ]
+                D[48,53] = (-1)*var(48); // [ var(53) , var(48) ]
+                D[49,53] = (-1)*var(49); // [ var(53) , var(49) ]
+                D[28,54] = var(28); // [ var(54) , var(28) ]
+                D[29,54] = (-2)*var(29); // [ var(54) , var(29) ]
+                D[30,54] = var(30); // [ var(54) , var(30) ]
+                D[32,54] = var(32); // [ var(54) , var(32) ]
+                D[33,54] = (-1)*var(33); // [ var(54) , var(33) ]
+                D[34,54] = (-1)*var(34); // [ var(54) , var(34) ]
+                D[35,54] = var(35); // [ var(54) , var(35) ]
+                D[36,54] = (-1)*var(36); // [ var(54) , var(36) ]
+                D[39,54] = (-1)*var(39); // [ var(54) , var(39) ]
+                D[41,54] = var(41); // [ var(54) , var(41) ]
+                D[43,54] = var(43); // [ var(54) , var(43) ]
+                D[44,54] = (-1)*var(44); // [ var(54) , var(44) ]
+                D[45,54] = var(45); // [ var(54) , var(45) ]
+                D[46,54] = (-1)*var(46); // [ var(54) , var(46) ]
+                D[47,54] = (-1)*var(47); // [ var(54) , var(47) ]
+                D[29,55] = (2)*var(29); // [ var(55) , var(29) ]
+                D[30,55] = (-2)*var(30); // [ var(55) , var(30) ]
+                D[33,55] = (2)*var(33); // [ var(55) , var(33) ]
+                D[36,55] = (2)*var(36); // [ var(55) , var(36) ]
+                D[38,55] = (-2)*var(38); // [ var(55) , var(38) ]
+                D[39,55] = (2)*var(39); // [ var(55) , var(39) ]
+                D[41,55] = (-2)*var(41); // [ var(55) , var(41) ]
+                D[43,55] = (-2)*var(43); // [ var(55) , var(43) ]
+                D[45,55] = (-2)*var(45); // [ var(55) , var(45) ]
+        // Y(i) * X(j):
+                D[1,26] = (-1)*var(51); // [ var(26) , var(1) ]
+                D[6,26] = var(2); // [ var(26) , var(6) ]
+                D[10,26] = var(7); // [ var(26) , var(10) ]
+                D[14,26] = var(11); // [ var(26) , var(14) ]
+                D[17,26] = var(15); // [ var(26) , var(17) ]
+                D[20,26] = var(18); // [ var(26) , var(20) ]
+                D[22,26] = var(21); // [ var(26) , var(22) ]
+                D[24,26] = var(23); // [ var(26) , var(24) ]
+                D[2,27] = (-1)*var(52); // [ var(27) , var(2) ]
+                D[6,27] = (-1)*var(1); // [ var(27) , var(6) ]
+                D[7,27] = var(3); // [ var(27) , var(7) ]
+                D[11,27] = var(8); // [ var(27) , var(11) ]
+                D[15,27] = var(12); // [ var(27) , var(15) ]
+                D[18,27] = var(16); // [ var(27) , var(18) ]
+                D[21,27] = var(19); // [ var(27) , var(21) ]
+                D[25,27] = var(24); // [ var(27) , var(25) ]
+                D[3,28] = (-1)*var(53); // [ var(28) , var(3) ]
+                D[7,28] = (-1)*var(2); // [ var(28) , var(7) ]
+                D[8,28] = var(4); // [ var(28) , var(8) ]
+                D[10,28] = (-1)*var(6); // [ var(28) , var(10) ]
+                D[12,28] = var(9); // [ var(28) , var(12) ]
+                D[16,28] = var(13); // [ var(28) , var(16) ]
+                D[23,28] = var(21); // [ var(28) , var(23) ]
+                D[24,28] = var(22); // [ var(28) , var(24) ]
+                D[4,29] = (-1)*var(54); // [ var(29) , var(4) ]
+                D[8,29] = (-1)*var(3); // [ var(29) , var(8) ]
+                D[9,29] = var(5); // [ var(29) , var(9) ]
+                D[11,29] = (-1)*var(7); // [ var(29) , var(11) ]
+                D[14,29] = (-1)*var(10); // [ var(29) , var(14) ]
+                D[19,29] = var(16); // [ var(29) , var(19) ]
+                D[21,29] = var(18); // [ var(29) , var(21) ]
+                D[22,29] = var(20); // [ var(29) , var(22) ]
+                D[5,30] = (-1)*var(55); // [ var(30) , var(5) ]
+                D[9,30] = (-2)*var(4); // [ var(30) , var(9) ]
+                D[12,30] = (-2)*var(8); // [ var(30) , var(12) ]
+                D[13,30] = (-1)*var(9); // [ var(30) , var(13) ]
+                D[15,30] = (-2)*var(11); // [ var(30) , var(15) ]
+                D[16,30] = (-1)*var(12); // [ var(30) , var(16) ]
+                D[17,30] = (-2)*var(14); // [ var(30) , var(17) ]
+                D[18,30] = (-1)*var(15); // [ var(30) , var(18) ]
+                D[20,30] = (-1)*var(17); // [ var(30) , var(20) ]
+                D[1,31] = var(27); // [ var(31) , var(1) ]
+                D[2,31] = (-1)*var(26); // [ var(31) , var(2) ]
+                D[6,31] = (-1)*var(51)+(-1)*var(52); // [ var(31) , var(6) ]
+                D[10,31] = var(3); // [ var(31) , var(10) ]
+                D[14,31] = var(8); // [ var(31) , var(14) ]
+                D[17,31] = var(12); // [ var(31) , var(17) ]
+                D[20,31] = var(16); // [ var(31) , var(20) ]
+                D[22,31] = var(19); // [ var(31) , var(22) ]
+                D[25,31] = (-1)*var(23); // [ var(31) , var(25) ]
+                D[2,32] = var(28); // [ var(32) , var(2) ]
+                D[3,32] = (-1)*var(27); // [ var(32) , var(3) ]
+                D[7,32] = (-1)*var(52)+(-1)*var(53); // [ var(32) , var(7) ]
+                D[10,32] = (-1)*var(1); // [ var(32) , var(10) ]
+                D[11,32] = var(4); // [ var(32) , var(11) ]
+                D[15,32] = var(9); // [ var(32) , var(15) ]
+                D[18,32] = var(13); // [ var(32) , var(18) ]
+                D[23,32] = (-1)*var(19); // [ var(32) , var(23) ]
+                D[25,32] = var(22); // [ var(32) , var(25) ]
+                D[3,33] = var(29); // [ var(33) , var(3) ]
+                D[4,33] = (-1)*var(28); // [ var(33) , var(4) ]
+                D[8,33] = (-1)*var(53)+(-1)*var(54); // [ var(33) , var(8) ]
+                D[11,33] = (-1)*var(2); // [ var(33) , var(11) ]
+                D[12,33] = var(5); // [ var(33) , var(12) ]
+                D[14,33] = (-1)*var(6); // [ var(33) , var(14) ]
+                D[19,33] = (-1)*var(13); // [ var(33) , var(19) ]
+                D[23,33] = var(18); // [ var(33) , var(23) ]
+                D[24,33] = var(20); // [ var(33) , var(24) ]
+                D[4,34] = var(30); // [ var(34) , var(4) ]
+                D[5,34] = (-2)*var(29); // [ var(34) , var(5) ]
+                D[9,34] = (-2)*var(54)+(-1)*var(55); // [ var(34) , var(9) ]
+                D[12,34] = (-2)*var(3); // [ var(34) , var(12) ]
+                D[13,34] = var(5); // [ var(34) , var(13) ]
+                D[15,34] = (-2)*var(7); // [ var(34) , var(15) ]
+                D[17,34] = (-2)*var(10); // [ var(34) , var(17) ]
+                D[19,34] = (-1)*var(12); // [ var(34) , var(19) ]
+                D[21,34] = (-1)*var(15); // [ var(34) , var(21) ]
+                D[22,34] = (-1)*var(17); // [ var(34) , var(22) ]
+                D[1,35] = var(32); // [ var(35) , var(1) ]
+                D[3,35] = (-1)*var(31); // [ var(35) , var(3) ]
+                D[6,35] = var(28); // [ var(35) , var(6) ]
+                D[7,35] = (-1)*var(26); // [ var(35) , var(7) ]
+                D[10,35] = (-1)*var(51)+(-1)*var(52)+(-1)*var(53); // [ var(35) , var(10) ]
+                D[14,35] = var(4); // [ var(35) , var(14) ]
+                D[17,35] = var(9); // [ var(35) , var(17) ]
+                D[20,35] = var(13); // [ var(35) , var(20) ]
+                D[24,35] = (-1)*var(19); // [ var(35) , var(24) ]
+                D[25,35] = (-1)*var(21); // [ var(35) , var(25) ]
+                D[2,36] = var(33); // [ var(36) , var(2) ]
+                D[4,36] = (-1)*var(32); // [ var(36) , var(4) ]
+                D[7,36] = var(29); // [ var(36) , var(7) ]
+                D[8,36] = (-1)*var(27); // [ var(36) , var(8) ]
+                D[11,36] = (-1)*var(52)+(-1)*var(53)+(-1)*var(54); // [ var(36) , var(11) ]
+                D[14,36] = (-1)*var(1); // [ var(36) , var(14) ]
+                D[15,36] = var(5); // [ var(36) , var(15) ]
+                D[21,36] = (-1)*var(13); // [ var(36) , var(21) ]
+                D[23,36] = (-1)*var(16); // [ var(36) , var(23) ]
+                D[25,36] = var(20); // [ var(36) , var(25) ]
+                D[3,37] = var(34); // [ var(37) , var(3) ]
+                D[5,37] = (-2)*var(33); // [ var(37) , var(5) ]
+                D[8,37] = var(30); // [ var(37) , var(8) ]
+                D[9,37] = (-2)*var(28); // [ var(37) , var(9) ]
+                D[12,37] = (-2)*var(53)+(-2)*var(54)+(-1)*var(55); // [ var(37) , var(12) ]
+                D[15,37] = (-2)*var(2); // [ var(37) , var(15) ]
+                D[16,37] = var(5); // [ var(37) , var(16) ]
+                D[17,37] = (-2)*var(6); // [ var(37) , var(17) ]
+                D[19,37] = var(9); // [ var(37) , var(19) ]
+                D[23,37] = (-1)*var(15); // [ var(37) , var(23) ]
+                D[24,37] = (-1)*var(17); // [ var(37) , var(24) ]
+                D[5,38] = (-1)*var(34); // [ var(38) , var(5) ]
+                D[9,38] = var(30); // [ var(38) , var(9) ]
+                D[13,38] = (-1)*var(54)+(-1)*var(55); // [ var(38) , var(13) ]
+                D[16,38] = (-1)*var(3); // [ var(38) , var(16) ]
+                D[18,38] = (-1)*var(7); // [ var(38) , var(18) ]
+                D[19,38] = var(8); // [ var(38) , var(19) ]
+                D[20,38] = (-1)*var(10); // [ var(38) , var(20) ]
+                D[21,38] = var(11); // [ var(38) , var(21) ]
+                D[22,38] = var(14); // [ var(38) , var(22) ]
+                D[1,39] = var(36); // [ var(39) , var(1) ]
+                D[4,39] = (-1)*var(35); // [ var(39) , var(4) ]
+                D[6,39] = var(33); // [ var(39) , var(6) ]
+                D[8,39] = (-1)*var(31); // [ var(39) , var(8) ]
+                D[10,39] = var(29); // [ var(39) , var(10) ]
+                D[11,39] = (-1)*var(26); // [ var(39) , var(11) ]
+                D[14,39] = (-1)*var(51)+(-1)*var(52)+(-1)*var(53)+(-1)*var(54); // [ var(39) , var(14) ]
+                D[17,39] = var(5); // [ var(39) , var(17) ]
+                D[22,39] = (-1)*var(13); // [ var(39) , var(22) ]
+                D[24,39] = (-1)*var(16); // [ var(39) , var(24) ]
+                D[25,39] = (-1)*var(18); // [ var(39) , var(25) ]
+                D[2,40] = var(37); // [ var(40) , var(2) ]
+                D[5,40] = (-2)*var(36); // [ var(40) , var(5) ]
+                D[7,40] = var(34); // [ var(40) , var(7) ]
+                D[9,40] = (-2)*var(32); // [ var(40) , var(9) ]
+                D[11,40] = var(30); // [ var(40) , var(11) ]
+                D[12,40] = (-2)*var(27); // [ var(40) , var(12) ]
+                D[15,40] = (-2)*var(52)+(-2)*var(53)+(-2)*var(54)+(-1)*var(55); // [ var(40) , var(15) ]
+                D[17,40] = (-2)*var(1); // [ var(40) , var(17) ]
+                D[18,40] = var(5); // [ var(40) , var(18) ]
+                D[21,40] = var(9); // [ var(40) , var(21) ]
+                D[23,40] = var(12); // [ var(40) , var(23) ]
+                D[25,40] = (-1)*var(17); // [ var(40) , var(25) ]
+                D[3,41] = var(38); // [ var(41) , var(3) ]
+                D[5,41] = (-1)*var(37); // [ var(41) , var(5) ]
+                D[12,41] = var(30); // [ var(41) , var(12) ]
+                D[13,41] = (-1)*var(28); // [ var(41) , var(13) ]
+                D[16,41] = (-1)*var(53)+(-1)*var(54)+(-1)*var(55); // [ var(41) , var(16) ]
+                D[18,41] = (-1)*var(2); // [ var(41) , var(18) ]
+                D[19,41] = (-1)*var(4); // [ var(41) , var(19) ]
+                D[20,41] = (-1)*var(6); // [ var(41) , var(20) ]
+                D[23,41] = var(11); // [ var(41) , var(23) ]
+                D[24,41] = var(14); // [ var(41) , var(24) ]
+                D[1,42] = var(40); // [ var(42) , var(1) ]
+                D[5,42] = (-2)*var(39); // [ var(42) , var(5) ]
+                D[6,42] = var(37); // [ var(42) , var(6) ]
+                D[9,42] = (-2)*var(35); // [ var(42) , var(9) ]
+                D[10,42] = var(34); // [ var(42) , var(10) ]
+                D[12,42] = (-2)*var(31); // [ var(42) , var(12) ]
+                D[14,42] = var(30); // [ var(42) , var(14) ]
+                D[15,42] = (-2)*var(26); // [ var(42) , var(15) ]
+                D[17,42] = (-2)*var(51)+(-2)*var(52)+(-2)*var(53)+(-2)*var(54)+(-1)*var(55); // [ var(42) , var(17) ]
+                D[20,42] = var(5); // [ var(42) , var(20) ]
+                D[22,42] = var(9); // [ var(42) , var(22) ]
+                D[24,42] = var(12); // [ var(42) , var(24) ]
+                D[25,42] = var(15); // [ var(42) , var(25) ]
+                D[2,43] = var(41); // [ var(43) , var(2) ]
+                D[5,43] = (-1)*var(40); // [ var(43) , var(5) ]
+                D[7,43] = var(38); // [ var(43) , var(7) ]
+                D[13,43] = (-1)*var(32); // [ var(43) , var(13) ]
+                D[15,43] = var(30); // [ var(43) , var(15) ]
+                D[16,43] = (-1)*var(27); // [ var(43) , var(16) ]
+                D[18,43] = (-1)*var(52)+(-1)*var(53)+(-1)*var(54)+(-1)*var(55); // [ var(43) , var(18) ]
+                D[20,43] = (-1)*var(1); // [ var(43) , var(20) ]
+                D[21,43] = (-1)*var(4); // [ var(43) , var(21) ]
+                D[23,43] = (-1)*var(8); // [ var(43) , var(23) ]
+                D[25,43] = var(14); // [ var(43) , var(25) ]
+                D[4,44] = var(41); // [ var(44) , var(4) ]
+                D[8,44] = (-1)*var(38); // [ var(44) , var(8) ]
+                D[9,44] = (-1)*var(37); // [ var(44) , var(9) ]
+                D[12,44] = var(34); // [ var(44) , var(12) ]
+                D[13,44] = var(33); // [ var(44) , var(13) ]
+                D[16,44] = (-1)*var(29); // [ var(44) , var(16) ]
+                D[19,44] = (-1)*var(53)+(-2)*var(54)+(-1)*var(55); // [ var(44) , var(19) ]
+                D[21,44] = (-1)*var(2); // [ var(44) , var(21) ]
+                D[22,44] = (-1)*var(6); // [ var(44) , var(22) ]
+                D[23,44] = var(7); // [ var(44) , var(23) ]
+                D[24,44] = var(10); // [ var(44) , var(24) ]
+                D[1,45] = var(43); // [ var(45) , var(1) ]
+                D[5,45] = (-1)*var(42); // [ var(45) , var(5) ]
+                D[6,45] = var(41); // [ var(45) , var(6) ]
+                D[10,45] = var(38); // [ var(45) , var(10) ]
+                D[13,45] = (-1)*var(35); // [ var(45) , var(13) ]
+                D[16,45] = (-1)*var(31); // [ var(45) , var(16) ]
+                D[17,45] = var(30); // [ var(45) , var(17) ]
+                D[18,45] = (-1)*var(26); // [ var(45) , var(18) ]
+                D[20,45] = (-1)*var(51)+(-1)*var(52)+(-1)*var(53)+(-1)*var(54)+(-1)*var(55); // [ var(45) , var(20) ]
+                D[22,45] = (-1)*var(4); // [ var(45) , var(22) ]
+                D[24,45] = (-1)*var(8); // [ var(45) , var(24) ]
+                D[25,45] = (-1)*var(11); // [ var(45) , var(25) ]
+                D[2,46] = var(44); // [ var(46) , var(2) ]
+                D[4,46] = var(43); // [ var(46) , var(4) ]
+                D[9,46] = (-1)*var(40); // [ var(46) , var(9) ]
+                D[11,46] = (-1)*var(38); // [ var(46) , var(11) ]
+                D[13,46] = var(36); // [ var(46) , var(13) ]
+                D[15,46] = var(34); // [ var(46) , var(15) ]
+                D[18,46] = (-1)*var(29); // [ var(46) , var(18) ]
+                D[19,46] = (-1)*var(27); // [ var(46) , var(19) ]
+                D[21,46] = (-1)*var(52)+(-1)*var(53)+(-2)*var(54)+(-1)*var(55); // [ var(46) , var(21) ]
+                D[22,46] = (-1)*var(1); // [ var(46) , var(22) ]
+                D[23,46] = (-1)*var(3); // [ var(46) , var(23) ]
+                D[25,46] = var(10); // [ var(46) , var(25) ]
+                D[1,47] = var(46); // [ var(47) , var(1) ]
+                D[4,47] = var(45); // [ var(47) , var(4) ]
+                D[6,47] = var(44); // [ var(47) , var(6) ]
+                D[9,47] = (-1)*var(42); // [ var(47) , var(9) ]
+                D[13,47] = var(39); // [ var(47) , var(13) ]
+                D[14,47] = (-1)*var(38); // [ var(47) , var(14) ]
+                D[17,47] = var(34); // [ var(47) , var(17) ]
+                D[19,47] = (-1)*var(31); // [ var(47) , var(19) ]
+                D[20,47] = (-1)*var(29); // [ var(47) , var(20) ]
+                D[21,47] = (-1)*var(26); // [ var(47) , var(21) ]
+                D[22,47] = (-1)*var(51)+(-1)*var(52)+(-1)*var(53)+(-2)*var(54)+(-1)*var(55); // [ var(47) , var(22) ]
+                D[24,47] = (-1)*var(3); // [ var(47) , var(24) ]
+                D[25,47] = (-1)*var(7); // [ var(47) , var(25) ]
+                D[3,48] = var(46); // [ var(48) , var(3) ]
+                D[7,48] = (-1)*var(44); // [ var(48) , var(7) ]
+                D[8,48] = var(43); // [ var(48) , var(8) ]
+                D[11,48] = (-1)*var(41); // [ var(48) , var(11) ]
+                D[12,48] = (-1)*var(40); // [ var(48) , var(12) ]
+                D[15,48] = var(37); // [ var(48) , var(15) ]
+                D[16,48] = var(36); // [ var(48) , var(16) ]
+                D[18,48] = (-1)*var(33); // [ var(48) , var(18) ]
+                D[19,48] = var(32); // [ var(48) , var(19) ]
+                D[21,48] = (-1)*var(28); // [ var(48) , var(21) ]
+                D[23,48] = (-1)*var(52)+(-2)*var(53)+(-2)*var(54)+(-1)*var(55); // [ var(48) , var(23) ]
+                D[24,48] = (-1)*var(1); // [ var(48) , var(24) ]
+                D[25,48] = var(6); // [ var(48) , var(25) ]
+                D[1,49] = var(48); // [ var(49) , var(1) ]
+                D[3,49] = var(47); // [ var(49) , var(3) ]
+                D[8,49] = var(45); // [ var(49) , var(8) ]
+                D[10,49] = (-1)*var(44); // [ var(49) , var(10) ]
+                D[12,49] = (-1)*var(42); // [ var(49) , var(12) ]
+                D[14,49] = (-1)*var(41); // [ var(49) , var(14) ]
+                D[16,49] = var(39); // [ var(49) , var(16) ]
+                D[17,49] = var(37); // [ var(49) , var(17) ]
+                D[19,49] = var(35); // [ var(49) , var(19) ]
+                D[20,49] = (-1)*var(33); // [ var(49) , var(20) ]
+                D[22,49] = (-1)*var(28); // [ var(49) , var(22) ]
+                D[23,49] = (-1)*var(26); // [ var(49) , var(23) ]
+                D[24,49] = (-1)*var(51)+(-1)*var(52)+(-2)*var(53)+(-2)*var(54)+(-1)*var(55); // [ var(49) , var(24) ]
+                D[25,49] = (-1)*var(2); // [ var(49) , var(25) ]
+                D[2,50] = var(49); // [ var(50) , var(2) ]
+                D[6,50] = (-1)*var(48); // [ var(50) , var(6) ]
+                D[7,50] = var(47); // [ var(50) , var(7) ]
+                D[10,50] = (-1)*var(46); // [ var(50) , var(10) ]
+                D[11,50] = var(45); // [ var(50) , var(11) ]
+                D[14,50] = (-1)*var(43); // [ var(50) , var(14) ]
+                D[15,50] = (-1)*var(42); // [ var(50) , var(15) ]
+                D[17,50] = var(40); // [ var(50) , var(17) ]
+                D[18,50] = var(39); // [ var(50) , var(18) ]
+                D[20,50] = (-1)*var(36); // [ var(50) , var(20) ]
+                D[21,50] = var(35); // [ var(50) , var(21) ]
+                D[22,50] = (-1)*var(32); // [ var(50) , var(22) ]
+                D[23,50] = var(31); // [ var(50) , var(23) ]
+                D[24,50] = (-1)*var(27); // [ var(50) , var(24) ]
+                D[25,50] = (-1)*var(51)+(-2)*var(52)+(-2)*var(53)+(-2)*var(54)+(-1)*var(55); // [ var(50) , var(25) ]
+        // X(i) * X(j):
+                D[1,2] = (-1)*var(6); // [ var(2) , var(1) ]
+                D[1,7] = (-1)*var(10); // [ var(7) , var(1) ]
+                D[1,11] = (-1)*var(14); // [ var(11) , var(1) ]
+                D[1,15] = (-1)*var(17); // [ var(15) , var(1) ]
+                D[1,18] = (-1)*var(20); // [ var(18) , var(1) ]
+                D[1,21] = (-1)*var(22); // [ var(21) , var(1) ]
+                D[1,23] = (-1)*var(24); // [ var(23) , var(1) ]
+                D[2,3] = (-1)*var(7); // [ var(3) , var(2) ]
+                D[2,8] = (-1)*var(11); // [ var(8) , var(2) ]
+                D[2,12] = (-1)*var(15); // [ var(12) , var(2) ]
+                D[2,16] = (-1)*var(18); // [ var(16) , var(2) ]
+                D[2,19] = (-1)*var(21); // [ var(19) , var(2) ]
+                D[2,24] = (-1)*var(25); // [ var(24) , var(2) ]
+                D[3,4] = (-1)*var(8); // [ var(4) , var(3) ]
+                D[3,6] = var(10); // [ var(6) , var(3) ]
+                D[3,9] = (-1)*var(12); // [ var(9) , var(3) ]
+                D[3,13] = (-1)*var(16); // [ var(13) , var(3) ]
+                D[3,21] = (-1)*var(23); // [ var(21) , var(3) ]
+                D[3,22] = (-1)*var(24); // [ var(22) , var(3) ]
+                D[4,5] = (-1)*var(9); // [ var(5) , var(4) ]
+                D[4,7] = var(11); // [ var(7) , var(4) ]
+                D[4,10] = var(14); // [ var(10) , var(4) ]
+                D[4,16] = (-1)*var(19); // [ var(16) , var(4) ]
+                D[4,18] = (-1)*var(21); // [ var(18) , var(4) ]
+                D[4,20] = (-1)*var(22); // [ var(20) , var(4) ]
+                D[5,8] = var(12); // [ var(8) , var(5) ]
+                D[5,9] = (2)*var(13); // [ var(9) , var(5) ]
+                D[5,11] = var(15); // [ var(11) , var(5) ]
+                D[5,12] = (2)*var(16); // [ var(12) , var(5) ]
+                D[5,14] = var(17); // [ var(14) , var(5) ]
+                D[5,15] = (2)*var(18); // [ var(15) , var(5) ]
+                D[5,17] = (2)*var(20); // [ var(17) , var(5) ]
+                D[6,8] = (-1)*var(14); // [ var(8) , var(6) ]
+                D[6,12] = (-1)*var(17); // [ var(12) , var(6) ]
+                D[6,16] = (-1)*var(20); // [ var(16) , var(6) ]
+                D[6,19] = (-1)*var(22); // [ var(19) , var(6) ]
+                D[6,23] = var(25); // [ var(23) , var(6) ]
+                D[7,9] = (-1)*var(15); // [ var(9) , var(7) ]
+                D[7,13] = (-1)*var(18); // [ var(13) , var(7) ]
+                D[7,19] = var(23); // [ var(19) , var(7) ]
+                D[7,22] = (-1)*var(25); // [ var(22) , var(7) ]
+                D[8,13] = var(19); // [ var(13) , var(8) ]
+                D[8,18] = (-1)*var(23); // [ var(18) , var(8) ]
+                D[8,20] = (-1)*var(24); // [ var(20) , var(8) ]
+                D[9,10] = var(17); // [ var(10) , var(9) ]
+                D[9,12] = (2)*var(19); // [ var(12) , var(9) ]
+                D[9,15] = (2)*var(21); // [ var(15) , var(9) ]
+                D[9,17] = (2)*var(22); // [ var(17) , var(9) ]
+                D[10,13] = (-1)*var(20); // [ var(13) , var(10) ]
+                D[10,19] = var(24); // [ var(19) , var(10) ]
+                D[10,21] = var(25); // [ var(21) , var(10) ]
+                D[11,13] = var(21); // [ var(13) , var(11) ]
+                D[11,16] = var(23); // [ var(16) , var(11) ]
+                D[11,20] = (-1)*var(25); // [ var(20) , var(11) ]
+                D[12,15] = (2)*var(23); // [ var(15) , var(12) ]
+                D[12,17] = (2)*var(24); // [ var(17) , var(12) ]
+                D[13,14] = (-1)*var(22); // [ var(14) , var(13) ]
+                D[14,16] = var(24); // [ var(16) , var(14) ]
+                D[14,18] = var(25); // [ var(18) , var(14) ]
+                D[15,17] = (2)*var(25); // [ var(17) , var(15) ]
+        // Y(i) * Y(j):
+                D[26,27] = var(31); // [ var(27) , var(26) ]
+                D[26,32] = var(35); // [ var(32) , var(26) ]
+                D[26,36] = var(39); // [ var(36) , var(26) ]
+                D[26,40] = var(42); // [ var(40) , var(26) ]
+                D[26,43] = var(45); // [ var(43) , var(26) ]
+                D[26,46] = var(47); // [ var(46) , var(26) ]
+                D[26,48] = var(49); // [ var(48) , var(26) ]
+                D[27,28] = var(32); // [ var(28) , var(27) ]
+                D[27,33] = var(36); // [ var(33) , var(27) ]
+                D[27,37] = var(40); // [ var(37) , var(27) ]
+                D[27,41] = var(43); // [ var(41) , var(27) ]
+                D[27,44] = var(46); // [ var(44) , var(27) ]
+                D[27,49] = var(50); // [ var(49) , var(27) ]
+                D[28,29] = var(33); // [ var(29) , var(28) ]
+                D[28,31] = (-1)*var(35); // [ var(31) , var(28) ]
+                D[28,34] = var(37); // [ var(34) , var(28) ]
+                D[28,38] = var(41); // [ var(38) , var(28) ]
+                D[28,46] = var(48); // [ var(46) , var(28) ]
+                D[28,47] = var(49); // [ var(47) , var(28) ]
+                D[29,30] = var(34); // [ var(30) , var(29) ]
+                D[29,32] = (-1)*var(36); // [ var(32) , var(29) ]
+                D[29,35] = (-1)*var(39); // [ var(35) , var(29) ]
+                D[29,41] = var(44); // [ var(41) , var(29) ]
+                D[29,43] = var(46); // [ var(43) , var(29) ]
+                D[29,45] = var(47); // [ var(45) , var(29) ]
+                D[30,33] = (-1)*var(37); // [ var(33) , var(30) ]
+                D[30,34] = (-2)*var(38); // [ var(34) , var(30) ]
+                D[30,36] = (-1)*var(40); // [ var(36) , var(30) ]
+                D[30,37] = (-2)*var(41); // [ var(37) , var(30) ]
+                D[30,39] = (-1)*var(42); // [ var(39) , var(30) ]
+                D[30,40] = (-2)*var(43); // [ var(40) , var(30) ]
+                D[30,42] = (-2)*var(45); // [ var(42) , var(30) ]
+                D[31,33] = var(39); // [ var(33) , var(31) ]
+                D[31,37] = var(42); // [ var(37) , var(31) ]
+                D[31,41] = var(45); // [ var(41) , var(31) ]
+                D[31,44] = var(47); // [ var(44) , var(31) ]
+                D[31,48] = (-1)*var(50); // [ var(48) , var(31) ]
+                D[32,34] = var(40); // [ var(34) , var(32) ]
+                D[32,38] = var(43); // [ var(38) , var(32) ]
+                D[32,44] = (-1)*var(48); // [ var(44) , var(32) ]
+                D[32,47] = var(50); // [ var(47) , var(32) ]
+                D[33,38] = (-1)*var(44); // [ var(38) , var(33) ]
+                D[33,43] = var(48); // [ var(43) , var(33) ]
+                D[33,45] = var(49); // [ var(45) , var(33) ]
+                D[34,35] = (-1)*var(42); // [ var(35) , var(34) ]
+                D[34,37] = (-2)*var(44); // [ var(37) , var(34) ]
+                D[34,40] = (-2)*var(46); // [ var(40) , var(34) ]
+                D[34,42] = (-2)*var(47); // [ var(42) , var(34) ]
+                D[35,38] = var(45); // [ var(38) , var(35) ]
+                D[35,44] = (-1)*var(49); // [ var(44) , var(35) ]
+                D[35,46] = (-1)*var(50); // [ var(46) , var(35) ]
+                D[36,38] = (-1)*var(46); // [ var(38) , var(36) ]
+                D[36,41] = (-1)*var(48); // [ var(41) , var(36) ]
+                D[36,45] = var(50); // [ var(45) , var(36) ]
+                D[37,40] = (-2)*var(48); // [ var(40) , var(37) ]
+                D[37,42] = (-2)*var(49); // [ var(42) , var(37) ]
+                D[38,39] = var(47); // [ var(39) , var(38) ]
+                D[39,41] = (-1)*var(49); // [ var(41) , var(39) ]
+                D[39,43] = (-1)*var(50); // [ var(43) , var(39) ]
+                D[40,42] = (-2)*var(50); // [ var(42) , var(40) ]
+   def @@RR=nc_algebra(1,D);
+   return(@@RR);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   def ncAlgebra = makeUso11();
+   ncAlgebra;
+   setring ncAlgebra;
+   // ...  523  noncommutative relations
+}
+////////////////////////////////////////////////////////////////////
+
+// Algebra: sp1(Q) has the type: C1, and defined by:
+
+proc makeUsp1(list #)
+"USAGE:   makeUsp1([p]); p an optional integer (field characteristic)
+RETURN:  a ring, describing U(sp_1)
+NOTE:    You have to activate this ring with the 'setring' command. The presentation of U(sp_1) is derived from the Chevalley representation of sp_1, positive resp. negative roots are denoted by x(i) resp. y(i); Cartan elements are denoted by h(i).
+SEE ALSO: makeUsl, makeUso5, makeUe6, makeUe7, makeUe8, makeUg2, makeUf4
+EXAMPLE: example makeUsp1; shows examples
+"
+{
+   int @p = defInt(#);
+
+   ring @@@rrr = @p,(X(1..1),Y(1..1),H(1..1)),dp;
+   int N = nvars(@@@rrr);
+   matrix D[N][N]=0;
+
+        // H(i) * X(j):
+                D[1,3] = (2)*var(1); // [ var(3) , var(1) ]
+        // H(i) * Y(j):
+                D[2,3] = (-2)*var(2); // [ var(3) , var(2) ]
+        // Y(i) * X(j):
+                D[1,2] = (-1)*var(3); // [ var(2) , var(1) ]
+        // X(i) * X(j):
+        // Y(i) * Y(j):
+   def @@RR=nc_algebra(1,D);
+   return(@@RR);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   def ncAlgebra = makeUsp1();
+   setring ncAlgebra;
+   ncAlgebra;
+}
+////////////////////////////////////////////////////////////////////
+
+// Algebra: sp2(Q) has the type: C2, and defined by:
+
+proc makeUsp2(list #)
+"USAGE:   makeUsp2([p]); p an optional integer (field characteristic)
+RETURN:  a ring, describing U(sp_2)
+NOTE:    You have to activate this ring with the 'setring' command. The presentation of U(sp_2) is derived from the Chevalley representation of sp_2, positive resp. negative roots are denoted by x(i) resp. y(i); Cartan elements are denoted by h(i).
+SEE ALSO: makeUsl, makeUso5, makeUsp1, makeUe6, makeUe7, makeUe8, makeUg2, makeUf4
+EXAMPLE: example makeUsp2; shows examples
+"
+{
+   int @p = defInt(#);
+
+   ring @@@rrr = @p,(X(1..4),Y(1..4),H(1..2)),dp;
+   int N = nvars(@@@rrr);
+   matrix D[N][N]=0;
+
+        // H(i) * X(j):
+                D[1,9] = (2)*var(1); // [ var(9) , var(1) ]
+                D[2,9] = (-2)*var(2); // [ var(9) , var(2) ]
+                D[4,9] = (2)*var(4); // [ var(9) , var(4) ]
+                D[1,10] = (-1)*var(1); // [ var(10) , var(1) ]
+                D[2,10] = (2)*var(2); // [ var(10) , var(2) ]
+                D[3,10] = var(3); // [ var(10) , var(3) ]
+        // H(i) * Y(j):
+                D[5,9] = (-2)*var(5); // [ var(9) , var(5) ]
+                D[6,9] = (2)*var(6); // [ var(9) , var(6) ]
+                D[8,9] = (-2)*var(8); // [ var(9) , var(8) ]
+                D[5,10] = var(5); // [ var(10) , var(5) ]
+                D[6,10] = (-2)*var(6); // [ var(10) , var(6) ]
+                D[7,10] = (-1)*var(7); // [ var(10) , var(7) ]
+        // Y(i) * X(j):
+                D[1,5] = (-1)*var(9); // [ var(5) , var(1) ]
+                D[3,5] = (-2)*var(2); // [ var(5) , var(3) ]
+                D[4,5] = (-1)*var(3); // [ var(5) , var(4) ]
+                D[2,6] = (-1)*var(10); // [ var(6) , var(2) ]
+                D[3,6] = var(1); // [ var(6) , var(3) ]
+                D[1,7] = (-2)*var(6); // [ var(7) , var(1) ]
+                D[2,7] = var(5); // [ var(7) , var(2) ]
+                D[3,7] = (-1)*var(9)+(-2)*var(10); // [ var(7) , var(3) ]
+                D[4,7] = var(1); // [ var(7) , var(4) ]
+                D[1,8] = (-1)*var(7); // [ var(8) , var(1) ]
+                D[3,8] = var(5); // [ var(8) , var(3) ]
+                D[4,8] = (-1)*var(9)+(-1)*var(10); // [ var(8) , var(4) ]
+        // X(i) * X(j):
+                D[1,2] = var(3); // [ var(2) , var(1) ]
+                D[1,3] = (2)*var(4); // [ var(3) , var(1) ]
+        // Y(i) * Y(j):
+                D[5,6] = (-1)*var(7); // [ var(6) , var(5) ]
+                D[5,7] = (-2)*var(8); // [ var(7) , var(5) ]
+   def @@RR=nc_algebra(1,D);
+   return(@@RR);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   def ncAlgebra = makeUsp2();
+   setring ncAlgebra;
+   ncAlgebra;
+}
+////////////////////////////////////////////////////////////////////
+
+// Algebra: sp3(Q) has the type: C3, and defined by:
+
+proc makeUsp3(list #)
+"USAGE:   makeUsp3([p]); p an optional integer (field characteristic)
+RETURN:  a ring, describing U(sp_3)
+NOTE:    You have to activate this ring with the 'setring' command. The presentation of U(sp_3) is derived from the Chevalley representation of sp_3, positive resp. negative roots are denoted by x(i) resp. y(i); Cartan elements are denoted by h(i).
+SEE ALSO: makeUsl, makeUso5, makeUsp1, makeUe6, makeUe7, makeUe8, makeUg2, makeUf4
+EXAMPLE: example makeUsp3; shows examples
+"
+{
+   int @p = defInt(#);
+
+   ring @@@rrr = @p,(X(1..9),Y(1..9),H(1..3)),dp;
+   int N = nvars(@@@rrr);
+   matrix D[N][N]=0;
+
+        // H(i) * X(j):
+                D[1,19] = (2)*var(1); // [ var(19) , var(1) ]
+                D[2,19] = (-1)*var(2); // [ var(19) , var(2) ]
+                D[4,19] = var(4); // [ var(19) , var(4) ]
+                D[5,19] = (-1)*var(5); // [ var(19) , var(5) ]
+                D[6,19] = var(6); // [ var(19) , var(6) ]
+                D[7,19] = (-2)*var(7); // [ var(19) , var(7) ]
+                D[9,19] = (2)*var(9); // [ var(19) , var(9) ]
+                D[1,20] = (-1)*var(1); // [ var(20) , var(1) ]
+                D[2,20] = (2)*var(2); // [ var(20) , var(2) ]
+                D[3,20] = (-2)*var(3); // [ var(20) , var(3) ]
+                D[4,20] = var(4); // [ var(20) , var(4) ]
+                D[6,20] = (-1)*var(6); // [ var(20) , var(6) ]
+                D[7,20] = (2)*var(7); // [ var(20) , var(7) ]
+                D[8,20] = var(8); // [ var(20) , var(8) ]
+                D[2,21] = (-1)*var(2); // [ var(21) , var(2) ]
+                D[3,21] = (2)*var(3); // [ var(21) , var(3) ]
+                D[4,21] = (-1)*var(4); // [ var(21) , var(4) ]
+                D[5,21] = var(5); // [ var(21) , var(5) ]
+                D[6,21] = var(6); // [ var(21) , var(6) ]
+        // H(i) * Y(j):
+                D[10,19] = (-2)*var(10); // [ var(19) , var(10) ]
+                D[11,19] = var(11); // [ var(19) , var(11) ]
+                D[13,19] = (-1)*var(13); // [ var(19) , var(13) ]
+                D[14,19] = var(14); // [ var(19) , var(14) ]
+                D[15,19] = (-1)*var(15); // [ var(19) , var(15) ]
+                D[16,19] = (2)*var(16); // [ var(19) , var(16) ]
+                D[18,19] = (-2)*var(18); // [ var(19) , var(18) ]
+                D[10,20] = var(10); // [ var(20) , var(10) ]
+                D[11,20] = (-2)*var(11); // [ var(20) , var(11) ]
+                D[12,20] = (2)*var(12); // [ var(20) , var(12) ]
+                D[13,20] = (-1)*var(13); // [ var(20) , var(13) ]
+                D[15,20] = var(15); // [ var(20) , var(15) ]
+                D[16,20] = (-2)*var(16); // [ var(20) , var(16) ]
+                D[17,20] = (-1)*var(17); // [ var(20) , var(17) ]
+                D[11,21] = var(11); // [ var(21) , var(11) ]
+                D[12,21] = (-2)*var(12); // [ var(21) , var(12) ]
+                D[13,21] = var(13); // [ var(21) , var(13) ]
+                D[14,21] = (-1)*var(14); // [ var(21) , var(14) ]
+                D[15,21] = (-1)*var(15); // [ var(21) , var(15) ]
+        // Y(i) * X(j):
+                D[1,10] = (-1)*var(19); // [ var(10) , var(1) ]
+                D[4,10] = (-1)*var(2); // [ var(10) , var(4) ]
+                D[6,10] = (-1)*var(5); // [ var(10) , var(6) ]
+                D[8,10] = (-2)*var(7); // [ var(10) , var(8) ]
+                D[9,10] = (-1)*var(8); // [ var(10) , var(9) ]
+                D[2,11] = (-1)*var(20); // [ var(11) , var(2) ]
+                D[4,11] = var(1); // [ var(11) , var(4) ]
+                D[5,11] = (-2)*var(3); // [ var(11) , var(5) ]
+                D[7,11] = (-1)*var(5); // [ var(11) , var(7) ]
+                D[8,11] = (-1)*var(6); // [ var(11) , var(8) ]
+                D[3,12] = (-1)*var(21); // [ var(12) , var(3) ]
+                D[5,12] = var(2); // [ var(12) , var(5) ]
+                D[6,12] = var(4); // [ var(12) , var(6) ]
+                D[1,13] = (-1)*var(11); // [ var(13) , var(1) ]
+                D[2,13] = var(10); // [ var(13) , var(2) ]
+                D[4,13] = (-1)*var(19)+(-1)*var(20); // [ var(13) , var(4) ]
+                D[6,13] = (-2)*var(3); // [ var(13) , var(6) ]
+                D[8,13] = (-1)*var(5); // [ var(13) , var(8) ]
+                D[9,13] = (-1)*var(6); // [ var(13) , var(9) ]
+                D[2,14] = (-2)*var(12); // [ var(14) , var(2) ]
+                D[3,14] = var(11); // [ var(14) , var(3) ]
+                D[5,14] = (-1)*var(20)+(-2)*var(21); // [ var(14) , var(5) ]
+                D[6,14] = var(1); // [ var(14) , var(6) ]
+                D[7,14] = var(2); // [ var(14) , var(7) ]
+                D[8,14] = var(4); // [ var(14) , var(8) ]
+                D[1,15] = (-1)*var(14); // [ var(15) , var(1) ]
+                D[3,15] = var(13); // [ var(15) , var(3) ]
+                D[4,15] = (-2)*var(12); // [ var(15) , var(4) ]
+                D[5,15] = var(10); // [ var(15) , var(5) ]
+                D[6,15] = (-1)*var(19)+(-1)*var(20)+(-2)*var(21); // [ var(15) , var(6) ]
+                D[8,15] = var(2); // [ var(15) , var(8) ]
+                D[9,15] = var(4); // [ var(15) , var(9) ]
+                D[2,16] = (-1)*var(14); // [ var(16) , var(2) ]
+                D[5,16] = var(11); // [ var(16) , var(5) ]
+                D[7,16] = (-1)*var(20)+(-1)*var(21); // [ var(16) , var(7) ]
+                D[8,16] = var(1); // [ var(16) , var(8) ]
+                D[1,17] = (-2)*var(16); // [ var(17) , var(1) ]
+                D[2,17] = (-1)*var(15); // [ var(17) , var(2) ]
+                D[4,17] = (-1)*var(14); // [ var(17) , var(4) ]
+                D[5,17] = var(13); // [ var(17) , var(5) ]
+                D[6,17] = var(11); // [ var(17) , var(6) ]
+                D[7,17] = var(10); // [ var(17) , var(7) ]
+                D[8,17] = (-1)*var(19)+(-2)*var(20)+(-2)*var(21); // [ var(17) , var(8) ]
+                D[9,17] = var(1); // [ var(17) , var(9) ]
+                D[1,18] = (-1)*var(17); // [ var(18) , var(1) ]
+                D[4,18] = (-1)*var(15); // [ var(18) , var(4) ]
+                D[6,18] = var(13); // [ var(18) , var(6) ]
+                D[8,18] = var(10); // [ var(18) , var(8) ]
+                D[9,18] = (-1)*var(19)+(-1)*var(20)+(-1)*var(21); // [ var(18) , var(9) ]
+        // X(i) * X(j):
+                D[1,2] = var(4); // [ var(2) , var(1) ]
+                D[1,5] = var(6); // [ var(5) , var(1) ]
+                D[1,7] = var(8); // [ var(7) , var(1) ]
+                D[1,8] = (2)*var(9); // [ var(8) , var(1) ]
+                D[2,3] = var(5); // [ var(3) , var(2) ]
+                D[2,5] = (2)*var(7); // [ var(5) , var(2) ]
+                D[2,6] = var(8); // [ var(6) , var(2) ]
+                D[3,4] = (-1)*var(6); // [ var(4) , var(3) ]
+                D[4,5] = var(8); // [ var(5) , var(4) ]
+                D[4,6] = (2)*var(9); // [ var(6) , var(4) ]
+        // Y(i) * Y(j):
+                D[10,11] = (-1)*var(13); // [ var(11) , var(10) ]
+                D[10,14] = (-1)*var(15); // [ var(14) , var(10) ]
+                D[10,16] = (-1)*var(17); // [ var(16) , var(10) ]
+                D[10,17] = (-2)*var(18); // [ var(17) , var(10) ]
+                D[11,12] = (-1)*var(14); // [ var(12) , var(11) ]
+                D[11,14] = (-2)*var(16); // [ var(14) , var(11) ]
+                D[11,15] = (-1)*var(17); // [ var(15) , var(11) ]
+                D[12,13] = var(15); // [ var(13) , var(12) ]
+                D[13,14] = (-1)*var(17); // [ var(14) , var(13) ]
+                D[13,15] = (-2)*var(18); // [ var(15) , var(13) ]
+   def @@RR=nc_algebra(1,D);
+   return(@@RR);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   def ncAlgebra = makeUsp3();
+   ncAlgebra;
+   setring ncAlgebra;
+   // ...  107  noncommutative relations
+}
+////////////////////////////////////////////////////////////////////
+
+// Algebra: sp4(Q) has the type: C4, and defined by:
+
+proc makeUsp4(list #)
+"USAGE:   makeUsp4([p]); p an optional integer (field characteristic)
+RETURN:  a ring, describing U(sp_4)
+NOTE:    You have to activate this ring with the 'setring' command. The presentation of U(sp_4) is derived from the Chevalley representation of sp_4, positive resp. negative roots are denoted by x(i) resp. y(i); Cartan elements are denoted by h(i).
+SEE ALSO: makeUsl, makeUso5, makeUsp1, makeUe6, makeUe7, makeUe8, makeUg2, makeUf4
+EXAMPLE: example makeUsp4; shows examples
+"
+{
+   int @p = defInt(#);
+
+   ring @@@rrr = @p,(X(1..16),Y(1..16),H(1..4)),dp;
+   int N = nvars(@@@rrr);
+   matrix D[N][N]=0;
+
+        // H(i) * X(j):
+                D[1,33] = (2)*var(1); // [ var(33) , var(1) ]
+                D[2,33] = (-1)*var(2); // [ var(33) , var(2) ]
+                D[5,33] = var(5); // [ var(33) , var(5) ]
+                D[6,33] = (-1)*var(6); // [ var(33) , var(6) ]
+                D[8,33] = var(8); // [ var(33) , var(8) ]
+                D[9,33] = (-1)*var(9); // [ var(33) , var(9) ]
+                D[11,33] = var(11); // [ var(33) , var(11) ]
+                D[12,33] = (-1)*var(12); // [ var(33) , var(12) ]
+                D[13,33] = var(13); // [ var(33) , var(13) ]
+                D[14,33] = (-2)*var(14); // [ var(33) , var(14) ]
+                D[16,33] = (2)*var(16); // [ var(33) , var(16) ]
+                D[1,34] = (-1)*var(1); // [ var(34) , var(1) ]
+                D[2,34] = (2)*var(2); // [ var(34) , var(2) ]
+                D[3,34] = (-1)*var(3); // [ var(34) , var(3) ]
+                D[5,34] = var(5); // [ var(34) , var(5) ]
+                D[6,34] = var(6); // [ var(34) , var(6) ]
+                D[7,34] = (-1)*var(7); // [ var(34) , var(7) ]
+                D[9,34] = var(9); // [ var(34) , var(9) ]
+                D[10,34] = (-2)*var(10); // [ var(34) , var(10) ]
+                D[13,34] = (-1)*var(13); // [ var(34) , var(13) ]
+                D[14,34] = (2)*var(14); // [ var(34) , var(14) ]
+                D[15,34] = var(15); // [ var(34) , var(15) ]
+                D[2,35] = (-1)*var(2); // [ var(35) , var(2) ]
+                D[3,35] = (2)*var(3); // [ var(35) , var(3) ]
+                D[4,35] = (-2)*var(4); // [ var(35) , var(4) ]
+                D[5,35] = (-1)*var(5); // [ var(35) , var(5) ]
+                D[6,35] = var(6); // [ var(35) , var(6) ]
+                D[8,35] = var(8); // [ var(35) , var(8) ]
+                D[9,35] = (-1)*var(9); // [ var(35) , var(9) ]
+                D[10,35] = (2)*var(10); // [ var(35) , var(10) ]
+                D[11,35] = (-1)*var(11); // [ var(35) , var(11) ]
+                D[12,35] = var(12); // [ var(35) , var(12) ]
+                D[13,35] = var(13); // [ var(35) , var(13) ]
+                D[3,36] = (-1)*var(3); // [ var(36) , var(3) ]
+                D[4,36] = (2)*var(4); // [ var(36) , var(4) ]
+                D[6,36] = (-1)*var(6); // [ var(36) , var(6) ]
+                D[7,36] = var(7); // [ var(36) , var(7) ]
+                D[8,36] = (-1)*var(8); // [ var(36) , var(8) ]
+                D[9,36] = var(9); // [ var(36) , var(9) ]
+                D[11,36] = var(11); // [ var(36) , var(11) ]
+        // H(i) * Y(j):
+                D[17,33] = (-2)*var(17); // [ var(33) , var(17) ]
+                D[18,33] = var(18); // [ var(33) , var(18) ]
+                D[21,33] = (-1)*var(21); // [ var(33) , var(21) ]
+                D[22,33] = var(22); // [ var(33) , var(22) ]
+                D[24,33] = (-1)*var(24); // [ var(33) , var(24) ]
+                D[25,33] = var(25); // [ var(33) , var(25) ]
+                D[27,33] = (-1)*var(27); // [ var(33) , var(27) ]
+                D[28,33] = var(28); // [ var(33) , var(28) ]
+                D[29,33] = (-1)*var(29); // [ var(33) , var(29) ]
+                D[30,33] = (2)*var(30); // [ var(33) , var(30) ]
+                D[32,33] = (-2)*var(32); // [ var(33) , var(32) ]
+                D[17,34] = var(17); // [ var(34) , var(17) ]
+                D[18,34] = (-2)*var(18); // [ var(34) , var(18) ]
+                D[19,34] = var(19); // [ var(34) , var(19) ]
+                D[21,34] = (-1)*var(21); // [ var(34) , var(21) ]
+                D[22,34] = (-1)*var(22); // [ var(34) , var(22) ]
+                D[23,34] = var(23); // [ var(34) , var(23) ]
+                D[25,34] = (-1)*var(25); // [ var(34) , var(25) ]
+                D[26,34] = (2)*var(26); // [ var(34) , var(26) ]
+                D[29,34] = var(29); // [ var(34) , var(29) ]
+                D[30,34] = (-2)*var(30); // [ var(34) , var(30) ]
+                D[31,34] = (-1)*var(31); // [ var(34) , var(31) ]
+                D[18,35] = var(18); // [ var(35) , var(18) ]
+                D[19,35] = (-2)*var(19); // [ var(35) , var(19) ]
+                D[20,35] = (2)*var(20); // [ var(35) , var(20) ]
+                D[21,35] = var(21); // [ var(35) , var(21) ]
+                D[22,35] = (-1)*var(22); // [ var(35) , var(22) ]
+                D[24,35] = (-1)*var(24); // [ var(35) , var(24) ]
+                D[25,35] = var(25); // [ var(35) , var(25) ]
+                D[26,35] = (-2)*var(26); // [ var(35) , var(26) ]
+                D[27,35] = var(27); // [ var(35) , var(27) ]
+                D[28,35] = (-1)*var(28); // [ var(35) , var(28) ]
+                D[29,35] = (-1)*var(29); // [ var(35) , var(29) ]
+                D[19,36] = var(19); // [ var(36) , var(19) ]
+                D[20,36] = (-2)*var(20); // [ var(36) , var(20) ]
+                D[22,36] = var(22); // [ var(36) , var(22) ]
+                D[23,36] = (-1)*var(23); // [ var(36) , var(23) ]
+                D[24,36] = var(24); // [ var(36) , var(24) ]
+                D[25,36] = (-1)*var(25); // [ var(36) , var(25) ]
+                D[27,36] = (-1)*var(27); // [ var(36) , var(27) ]
+        // Y(i) * X(j):
+                D[1,17] = (-1)*var(33); // [ var(17) , var(1) ]
+                D[5,17] = (-1)*var(2); // [ var(17) , var(5) ]
+                D[8,17] = (-1)*var(6); // [ var(17) , var(8) ]
+                D[11,17] = (-1)*var(9); // [ var(17) , var(11) ]
+                D[13,17] = (-1)*var(12); // [ var(17) , var(13) ]
+                D[15,17] = (-2)*var(14); // [ var(17) , var(15) ]
+                D[16,17] = (-1)*var(15); // [ var(17) , var(16) ]
+                D[2,18] = (-1)*var(34); // [ var(18) , var(2) ]
+                D[5,18] = var(1); // [ var(18) , var(5) ]
+                D[6,18] = (-1)*var(3); // [ var(18) , var(6) ]
+                D[9,18] = (-1)*var(7); // [ var(18) , var(9) ]
+                D[12,18] = (-2)*var(10); // [ var(18) , var(12) ]
+                D[14,18] = (-1)*var(12); // [ var(18) , var(14) ]
+                D[15,18] = (-1)*var(13); // [ var(18) , var(15) ]
+                D[3,19] = (-1)*var(35); // [ var(19) , var(3) ]
+                D[6,19] = var(2); // [ var(19) , var(6) ]
+                D[7,19] = (-2)*var(4); // [ var(19) , var(7) ]
+                D[8,19] = var(5); // [ var(19) , var(8) ]
+                D[10,19] = (-1)*var(7); // [ var(19) , var(10) ]
+                D[12,19] = (-1)*var(9); // [ var(19) , var(12) ]
+                D[13,19] = (-1)*var(11); // [ var(19) , var(13) ]
+                D[4,20] = (-1)*var(36); // [ var(20) , var(4) ]
+                D[7,20] = var(3); // [ var(20) , var(7) ]
+                D[9,20] = var(6); // [ var(20) , var(9) ]
+                D[11,20] = var(8); // [ var(20) , var(11) ]
+                D[1,21] = (-1)*var(18); // [ var(21) , var(1) ]
+                D[2,21] = var(17); // [ var(21) , var(2) ]
+                D[5,21] = (-1)*var(33)+(-1)*var(34); // [ var(21) , var(5) ]
+                D[8,21] = (-1)*var(3); // [ var(21) , var(8) ]
+                D[11,21] = (-1)*var(7); // [ var(21) , var(11) ]
+                D[13,21] = (-2)*var(10); // [ var(21) , var(13) ]
+                D[15,21] = (-1)*var(12); // [ var(21) , var(15) ]
+                D[16,21] = (-1)*var(13); // [ var(21) , var(16) ]
+                D[2,22] = (-1)*var(19); // [ var(22) , var(2) ]
+                D[3,22] = var(18); // [ var(22) , var(3) ]
+                D[6,22] = (-1)*var(34)+(-1)*var(35); // [ var(22) , var(6) ]
+                D[8,22] = var(1); // [ var(22) , var(8) ]
+                D[9,22] = (-2)*var(4); // [ var(22) , var(9) ]
+                D[12,22] = (-1)*var(7); // [ var(22) , var(12) ]
+                D[14,22] = (-1)*var(9); // [ var(22) , var(14) ]
+                D[15,22] = (-1)*var(11); // [ var(22) , var(15) ]
+                D[3,23] = (-2)*var(20); // [ var(23) , var(3) ]
+                D[4,23] = var(19); // [ var(23) , var(4) ]
+                D[7,23] = (-1)*var(35)+(-2)*var(36); // [ var(23) , var(7) ]
+                D[9,23] = var(2); // [ var(23) , var(9) ]
+                D[10,23] = var(3); // [ var(23) , var(10) ]
+                D[11,23] = var(5); // [ var(23) , var(11) ]
+                D[12,23] = var(6); // [ var(23) , var(12) ]
+                D[13,23] = var(8); // [ var(23) , var(13) ]
+                D[1,24] = (-1)*var(22); // [ var(24) , var(1) ]
+                D[3,24] = var(21); // [ var(24) , var(3) ]
+                D[5,24] = (-1)*var(19); // [ var(24) , var(5) ]
+                D[6,24] = var(17); // [ var(24) , var(6) ]
+                D[8,24] = (-1)*var(33)+(-1)*var(34)+(-1)*var(35); // [ var(24) , var(8) ]
+                D[11,24] = (-2)*var(4); // [ var(24) , var(11) ]
+                D[13,24] = (-1)*var(7); // [ var(24) , var(13) ]
+                D[15,24] = (-1)*var(9); // [ var(24) , var(15) ]
+                D[16,24] = (-1)*var(11); // [ var(24) , var(16) ]
+                D[2,25] = (-1)*var(23); // [ var(25) , var(2) ]
+                D[4,25] = var(22); // [ var(25) , var(4) ]
+                D[6,25] = (-2)*var(20); // [ var(25) , var(6) ]
+                D[7,25] = var(18); // [ var(25) , var(7) ]
+                D[9,25] = (-1)*var(34)+(-1)*var(35)+(-2)*var(36); // [ var(25) , var(9) ]
+                D[11,25] = var(1); // [ var(25) , var(11) ]
+                D[12,25] = var(3); // [ var(25) , var(12) ]
+                D[14,25] = var(6); // [ var(25) , var(14) ]
+                D[15,25] = var(8); // [ var(25) , var(15) ]
+                D[3,26] = (-1)*var(23); // [ var(26) , var(3) ]
+                D[7,26] = var(19); // [ var(26) , var(7) ]
+                D[10,26] = (-1)*var(35)+(-1)*var(36); // [ var(26) , var(10) ]
+                D[12,26] = var(2); // [ var(26) , var(12) ]
+                D[13,26] = var(5); // [ var(26) , var(13) ]
+                D[1,27] = (-1)*var(25); // [ var(27) , var(1) ]
+                D[4,27] = var(24); // [ var(27) , var(4) ]
+                D[5,27] = (-1)*var(23); // [ var(27) , var(5) ]
+                D[7,27] = var(21); // [ var(27) , var(7) ]
+                D[8,27] = (-2)*var(20); // [ var(27) , var(8) ]
+                D[9,27] = var(17); // [ var(27) , var(9) ]
+                D[11,27] = (-1)*var(33)+(-1)*var(34)+(-1)*var(35)+(-2)*var(36); // [ var(27) , var(11) ]
+                D[13,27] = var(3); // [ var(27) , var(13) ]
+                D[15,27] = var(6); // [ var(27) , var(15) ]
+                D[16,27] = var(8); // [ var(27) , var(16) ]
+                D[2,28] = (-2)*var(26); // [ var(28) , var(2) ]
+                D[3,28] = (-1)*var(25); // [ var(28) , var(3) ]
+                D[6,28] = (-1)*var(23); // [ var(28) , var(6) ]
+                D[7,28] = var(22); // [ var(28) , var(7) ]
+                D[9,28] = var(19); // [ var(28) , var(9) ]
+                D[10,28] = var(18); // [ var(28) , var(10) ]
+                D[12,28] = (-1)*var(34)+(-2)*var(35)+(-2)*var(36); // [ var(28) , var(12) ]
+                D[13,28] = var(1); // [ var(28) , var(13) ]
+                D[14,28] = var(2); // [ var(28) , var(14) ]
+                D[15,28] = var(5); // [ var(28) , var(15) ]
+                D[1,29] = (-1)*var(28); // [ var(29) , var(1) ]
+                D[3,29] = (-1)*var(27); // [ var(29) , var(3) ]
+                D[5,29] = (-2)*var(26); // [ var(29) , var(5) ]
+                D[7,29] = var(24); // [ var(29) , var(7) ]
+                D[8,29] = (-1)*var(23); // [ var(29) , var(8) ]
+                D[10,29] = var(21); // [ var(29) , var(10) ]
+                D[11,29] = var(19); // [ var(29) , var(11) ]
+                D[12,29] = var(17); // [ var(29) , var(12) ]
+                D[13,29] = (-1)*var(33)+(-1)*var(34)+(-2)*var(35)+(-2)*var(36); // [ var(29) , var(13) ]
+                D[15,29] = var(2); // [ var(29) , var(15) ]
+                D[16,29] = var(5); // [ var(29) , var(16) ]
+                D[2,30] = (-1)*var(28); // [ var(30) , var(2) ]
+                D[6,30] = (-1)*var(25); // [ var(30) , var(6) ]
+                D[9,30] = var(22); // [ var(30) , var(9) ]
+                D[12,30] = var(18); // [ var(30) , var(12) ]
+                D[14,30] = (-1)*var(34)+(-1)*var(35)+(-1)*var(36); // [ var(30) , var(14) ]
+                D[15,30] = var(1); // [ var(30) , var(15) ]
+                D[1,31] = (-2)*var(30); // [ var(31) , var(1) ]
+                D[2,31] = (-1)*var(29); // [ var(31) , var(2) ]
+                D[5,31] = (-1)*var(28); // [ var(31) , var(5) ]
+                D[6,31] = (-1)*var(27); // [ var(31) , var(6) ]
+                D[8,31] = (-1)*var(25); // [ var(31) , var(8) ]
+                D[9,31] = var(24); // [ var(31) , var(9) ]
+                D[11,31] = var(22); // [ var(31) , var(11) ]
+                D[12,31] = var(21); // [ var(31) , var(12) ]
+                D[13,31] = var(18); // [ var(31) , var(13) ]
+                D[14,31] = var(17); // [ var(31) , var(14) ]
+                D[15,31] = (-1)*var(33)+(-2)*var(34)+(-2)*var(35)+(-2)*var(36); // [ var(31) , var(15) ]
+                D[16,31] = var(1); // [ var(31) , var(16) ]
+                D[1,32] = (-1)*var(31); // [ var(32) , var(1) ]
+                D[5,32] = (-1)*var(29); // [ var(32) , var(5) ]
+                D[8,32] = (-1)*var(27); // [ var(32) , var(8) ]
+                D[11,32] = var(24); // [ var(32) , var(11) ]
+                D[13,32] = var(21); // [ var(32) , var(13) ]
+                D[15,32] = var(17); // [ var(32) , var(15) ]
+                D[16,32] = (-1)*var(33)+(-1)*var(34)+(-1)*var(35)+(-1)*var(36); // [ var(32) , var(16) ]
+        // X(i) * X(j):
+                D[1,2] = var(5); // [ var(2) , var(1) ]
+                D[1,6] = var(8); // [ var(6) , var(1) ]
+                D[1,9] = var(11); // [ var(9) , var(1) ]
+                D[1,12] = var(13); // [ var(12) , var(1) ]
+                D[1,14] = var(15); // [ var(14) , var(1) ]
+                D[1,15] = (2)*var(16); // [ var(15) , var(1) ]
+                D[2,3] = var(6); // [ var(3) , var(2) ]
+                D[2,7] = var(9); // [ var(7) , var(2) ]
+                D[2,10] = var(12); // [ var(10) , var(2) ]
+                D[2,12] = (2)*var(14); // [ var(12) , var(2) ]
+                D[2,13] = var(15); // [ var(13) , var(2) ]
+                D[3,4] = var(7); // [ var(4) , var(3) ]
+                D[3,5] = (-1)*var(8); // [ var(5) , var(3) ]
+                D[3,7] = (2)*var(10); // [ var(7) , var(3) ]
+                D[3,9] = var(12); // [ var(9) , var(3) ]
+                D[3,11] = var(13); // [ var(11) , var(3) ]
+                D[4,6] = (-1)*var(9); // [ var(6) , var(4) ]
+                D[4,8] = (-1)*var(11); // [ var(8) , var(4) ]
+                D[5,7] = var(11); // [ var(7) , var(5) ]
+                D[5,10] = var(13); // [ var(10) , var(5) ]
+                D[5,12] = var(15); // [ var(12) , var(5) ]
+                D[5,13] = (2)*var(16); // [ var(13) , var(5) ]
+                D[6,7] = var(12); // [ var(7) , var(6) ]
+                D[6,9] = (2)*var(14); // [ var(9) , var(6) ]
+                D[6,11] = var(15); // [ var(11) , var(6) ]
+                D[7,8] = (-1)*var(13); // [ var(8) , var(7) ]
+                D[8,9] = var(15); // [ var(9) , var(8) ]
+                D[8,11] = (2)*var(16); // [ var(11) , var(8) ]
+        // Y(i) * Y(j):
+                D[17,18] = (-1)*var(21); // [ var(18) , var(17) ]
+                D[17,22] = (-1)*var(24); // [ var(22) , var(17) ]
+                D[17,25] = (-1)*var(27); // [ var(25) , var(17) ]
+                D[17,28] = (-1)*var(29); // [ var(28) , var(17) ]
+                D[17,30] = (-1)*var(31); // [ var(30) , var(17) ]
+                D[17,31] = (-2)*var(32); // [ var(31) , var(17) ]
+                D[18,19] = (-1)*var(22); // [ var(19) , var(18) ]
+                D[18,23] = (-1)*var(25); // [ var(23) , var(18) ]
+                D[18,26] = (-1)*var(28); // [ var(26) , var(18) ]
+                D[18,28] = (-2)*var(30); // [ var(28) , var(18) ]
+                D[18,29] = (-1)*var(31); // [ var(29) , var(18) ]
+                D[19,20] = (-1)*var(23); // [ var(20) , var(19) ]
+                D[19,21] = var(24); // [ var(21) , var(19) ]
+                D[19,23] = (-2)*var(26); // [ var(23) , var(19) ]
+                D[19,25] = (-1)*var(28); // [ var(25) , var(19) ]
+                D[19,27] = (-1)*var(29); // [ var(27) , var(19) ]
+                D[20,22] = var(25); // [ var(22) , var(20) ]
+                D[20,24] = var(27); // [ var(24) , var(20) ]
+                D[21,23] = (-1)*var(27); // [ var(23) , var(21) ]
+                D[21,26] = (-1)*var(29); // [ var(26) , var(21) ]
+                D[21,28] = (-1)*var(31); // [ var(28) , var(21) ]
+                D[21,29] = (-2)*var(32); // [ var(29) , var(21) ]
+                D[22,23] = (-1)*var(28); // [ var(23) , var(22) ]
+                D[22,25] = (-2)*var(30); // [ var(25) , var(22) ]
+                D[22,27] = (-1)*var(31); // [ var(27) , var(22) ]
+                D[23,24] = var(29); // [ var(24) , var(23) ]
+                D[24,25] = (-1)*var(31); // [ var(25) , var(24) ]
+                D[24,27] = (-2)*var(32); // [ var(27) , var(24) ]
+   def @@RR=nc_algebra(1,D);
+   return(@@RR);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   def ncAlgebra = makeUsp4();
+   ncAlgebra;
+   setring ncAlgebra;
+   // ...  264  noncommutative relations
+}
+////////////////////////////////////////////////////////////////////
+
+// Algebra: sp5(Q) has the type: C5, and defined by:
+
+proc makeUsp5(list #)
+"USAGE:   makeUsp5([p]); p an optional integer (field characteristic)
+RETURN:  a ring, describing U(sp_5)
+NOTE:    You have to activate this ring with the 'setring' command. The presentation of U(sp_5) is derived from the Chevalley representation of sp_5, positive resp. negative roots are denoted by x(i) resp. y(i); Cartan elements are denoted by h(i).
+SEE ALSO: makeUsl, makeUso5, makeUsp1, makeUe6, makeUe7, makeUe8, makeUg2, makeUf4
+EXAMPLE: example makeUsp5; shows examples
+"
+{
+   int @p = defInt(#);
+
+   ring @@@rrr = @p,(X(1..25),Y(1..25),H(1..5)),dp;
+   int N = nvars(@@@rrr);
+   matrix D[N][N]=0;
+
+        // H(i) * X(j):
+                D[1,51] = (2)*var(1); // [ var(51) , var(1) ]
+                D[2,51] = (-1)*var(2); // [ var(51) , var(2) ]
+                D[6,51] = var(6); // [ var(51) , var(6) ]
+                D[7,51] = (-1)*var(7); // [ var(51) , var(7) ]
+                D[10,51] = var(10); // [ var(51) , var(10) ]
+                D[11,51] = (-1)*var(11); // [ var(51) , var(11) ]
+                D[14,51] = var(14); // [ var(51) , var(14) ]
+                D[15,51] = (-1)*var(15); // [ var(51) , var(15) ]
+                D[17,51] = var(17); // [ var(51) , var(17) ]
+                D[18,51] = (-1)*var(18); // [ var(51) , var(18) ]
+                D[20,51] = var(20); // [ var(51) , var(20) ]
+                D[21,51] = (-1)*var(21); // [ var(51) , var(21) ]
+                D[22,51] = var(22); // [ var(51) , var(22) ]
+                D[23,51] = (-2)*var(23); // [ var(51) , var(23) ]
+                D[25,51] = (2)*var(25); // [ var(51) , var(25) ]
+                D[1,52] = (-1)*var(1); // [ var(52) , var(1) ]
+                D[2,52] = (2)*var(2); // [ var(52) , var(2) ]
+                D[3,52] = (-1)*var(3); // [ var(52) , var(3) ]
+                D[6,52] = var(6); // [ var(52) , var(6) ]
+                D[7,52] = var(7); // [ var(52) , var(7) ]
+                D[8,52] = (-1)*var(8); // [ var(52) , var(8) ]
+                D[11,52] = var(11); // [ var(52) , var(11) ]
+                D[12,52] = (-1)*var(12); // [ var(52) , var(12) ]
+                D[15,52] = var(15); // [ var(52) , var(15) ]
+                D[16,52] = (-1)*var(16); // [ var(52) , var(16) ]
+                D[18,52] = var(18); // [ var(52) , var(18) ]
+                D[19,52] = (-2)*var(19); // [ var(52) , var(19) ]
+                D[22,52] = (-1)*var(22); // [ var(52) , var(22) ]
+                D[23,52] = (2)*var(23); // [ var(52) , var(23) ]
+                D[24,52] = var(24); // [ var(52) , var(24) ]
+                D[2,53] = (-1)*var(2); // [ var(53) , var(2) ]
+                D[3,53] = (2)*var(3); // [ var(53) , var(3) ]
+                D[4,53] = (-1)*var(4); // [ var(53) , var(4) ]
+                D[6,53] = (-1)*var(6); // [ var(53) , var(6) ]
+                D[7,53] = var(7); // [ var(53) , var(7) ]
+                D[8,53] = var(8); // [ var(53) , var(8) ]
+                D[9,53] = (-1)*var(9); // [ var(53) , var(9) ]
+                D[10,53] = var(10); // [ var(53) , var(10) ]
+                D[12,53] = var(12); // [ var(53) , var(12) ]
+                D[13,53] = (-2)*var(13); // [ var(53) , var(13) ]
+                D[18,53] = (-1)*var(18); // [ var(53) , var(18) ]
+                D[19,53] = (2)*var(19); // [ var(53) , var(19) ]
+                D[20,53] = (-1)*var(20); // [ var(53) , var(20) ]
+                D[21,53] = var(21); // [ var(53) , var(21) ]
+                D[22,53] = var(22); // [ var(53) , var(22) ]
+                D[3,54] = (-1)*var(3); // [ var(54) , var(3) ]
+                D[4,54] = (2)*var(4); // [ var(54) , var(4) ]
+                D[5,54] = (-2)*var(5); // [ var(54) , var(5) ]
+                D[7,54] = (-1)*var(7); // [ var(54) , var(7) ]
+                D[8,54] = var(8); // [ var(54) , var(8) ]
+                D[10,54] = (-1)*var(10); // [ var(54) , var(10) ]
+                D[11,54] = var(11); // [ var(54) , var(11) ]
+                D[12,54] = (-1)*var(12); // [ var(54) , var(12) ]
+                D[13,54] = (2)*var(13); // [ var(54) , var(13) ]
+                D[14,54] = var(14); // [ var(54) , var(14) ]
+                D[15,54] = (-1)*var(15); // [ var(54) , var(15) ]
+                D[16,54] = var(16); // [ var(54) , var(16) ]
+                D[17,54] = (-1)*var(17); // [ var(54) , var(17) ]
+                D[18,54] = var(18); // [ var(54) , var(18) ]
+                D[20,54] = var(20); // [ var(54) , var(20) ]
+                D[4,55] = (-1)*var(4); // [ var(55) , var(4) ]
+                D[5,55] = (2)*var(5); // [ var(55) , var(5) ]
+                D[8,55] = (-1)*var(8); // [ var(55) , var(8) ]
+                D[9,55] = var(9); // [ var(55) , var(9) ]
+                D[11,55] = (-1)*var(11); // [ var(55) , var(11) ]
+                D[12,55] = var(12); // [ var(55) , var(12) ]
+                D[14,55] = (-1)*var(14); // [ var(55) , var(14) ]
+                D[15,55] = var(15); // [ var(55) , var(15) ]
+                D[17,55] = var(17); // [ var(55) , var(17) ]
+        // H(i) * Y(j):
+                D[26,51] = (-2)*var(26); // [ var(51) , var(26) ]
+                D[27,51] = var(27); // [ var(51) , var(27) ]
+                D[31,51] = (-1)*var(31); // [ var(51) , var(31) ]
+                D[32,51] = var(32); // [ var(51) , var(32) ]
+                D[35,51] = (-1)*var(35); // [ var(51) , var(35) ]
+                D[36,51] = var(36); // [ var(51) , var(36) ]
+                D[39,51] = (-1)*var(39); // [ var(51) , var(39) ]
+                D[40,51] = var(40); // [ var(51) , var(40) ]
+                D[42,51] = (-1)*var(42); // [ var(51) , var(42) ]
+                D[43,51] = var(43); // [ var(51) , var(43) ]
+                D[45,51] = (-1)*var(45); // [ var(51) , var(45) ]
+                D[46,51] = var(46); // [ var(51) , var(46) ]
+                D[47,51] = (-1)*var(47); // [ var(51) , var(47) ]
+                D[48,51] = (2)*var(48); // [ var(51) , var(48) ]
+                D[50,51] = (-2)*var(50); // [ var(51) , var(50) ]
+                D[26,52] = var(26); // [ var(52) , var(26) ]
+                D[27,52] = (-2)*var(27); // [ var(52) , var(27) ]
+                D[28,52] = var(28); // [ var(52) , var(28) ]
+                D[31,52] = (-1)*var(31); // [ var(52) , var(31) ]
+                D[32,52] = (-1)*var(32); // [ var(52) , var(32) ]
+                D[33,52] = var(33); // [ var(52) , var(33) ]
+                D[36,52] = (-1)*var(36); // [ var(52) , var(36) ]
+                D[37,52] = var(37); // [ var(52) , var(37) ]
+                D[40,52] = (-1)*var(40); // [ var(52) , var(40) ]
+                D[41,52] = var(41); // [ var(52) , var(41) ]
+                D[43,52] = (-1)*var(43); // [ var(52) , var(43) ]
+                D[44,52] = (2)*var(44); // [ var(52) , var(44) ]
+                D[47,52] = var(47); // [ var(52) , var(47) ]
+                D[48,52] = (-2)*var(48); // [ var(52) , var(48) ]
+                D[49,52] = (-1)*var(49); // [ var(52) , var(49) ]
+                D[27,53] = var(27); // [ var(53) , var(27) ]
+                D[28,53] = (-2)*var(28); // [ var(53) , var(28) ]
+                D[29,53] = var(29); // [ var(53) , var(29) ]
+                D[31,53] = var(31); // [ var(53) , var(31) ]
+                D[32,53] = (-1)*var(32); // [ var(53) , var(32) ]
+                D[33,53] = (-1)*var(33); // [ var(53) , var(33) ]
+                D[34,53] = var(34); // [ var(53) , var(34) ]
+                D[35,53] = (-1)*var(35); // [ var(53) , var(35) ]
+                D[37,53] = (-1)*var(37); // [ var(53) , var(37) ]
+                D[38,53] = (2)*var(38); // [ var(53) , var(38) ]
+                D[43,53] = var(43); // [ var(53) , var(43) ]
+                D[44,53] = (-2)*var(44); // [ var(53) , var(44) ]
+                D[45,53] = var(45); // [ var(53) , var(45) ]
+                D[46,53] = (-1)*var(46); // [ var(53) , var(46) ]
+                D[47,53] = (-1)*var(47); // [ var(53) , var(47) ]
+                D[28,54] = var(28); // [ var(54) , var(28) ]
+                D[29,54] = (-2)*var(29); // [ var(54) , var(29) ]
+                D[30,54] = (2)*var(30); // [ var(54) , var(30) ]
+                D[32,54] = var(32); // [ var(54) , var(32) ]
+                D[33,54] = (-1)*var(33); // [ var(54) , var(33) ]
+                D[35,54] = var(35); // [ var(54) , var(35) ]
+                D[36,54] = (-1)*var(36); // [ var(54) , var(36) ]
+                D[37,54] = var(37); // [ var(54) , var(37) ]
+                D[38,54] = (-2)*var(38); // [ var(54) , var(38) ]
+                D[39,54] = (-1)*var(39); // [ var(54) , var(39) ]
+                D[40,54] = var(40); // [ var(54) , var(40) ]
+                D[41,54] = (-1)*var(41); // [ var(54) , var(41) ]
+                D[42,54] = var(42); // [ var(54) , var(42) ]
+                D[43,54] = (-1)*var(43); // [ var(54) , var(43) ]
+                D[45,54] = (-1)*var(45); // [ var(54) , var(45) ]
+                D[29,55] = var(29); // [ var(55) , var(29) ]
+                D[30,55] = (-2)*var(30); // [ var(55) , var(30) ]
+                D[33,55] = var(33); // [ var(55) , var(33) ]
+                D[34,55] = (-1)*var(34); // [ var(55) , var(34) ]
+                D[36,55] = var(36); // [ var(55) , var(36) ]
+                D[37,55] = (-1)*var(37); // [ var(55) , var(37) ]
+                D[39,55] = var(39); // [ var(55) , var(39) ]
+                D[40,55] = (-1)*var(40); // [ var(55) , var(40) ]
+                D[42,55] = (-1)*var(42); // [ var(55) , var(42) ]
+        // Y(i) * X(j):
+                D[1,26] = (-1)*var(51); // [ var(26) , var(1) ]
+                D[6,26] = (-1)*var(2); // [ var(26) , var(6) ]
+                D[10,26] = (-1)*var(7); // [ var(26) , var(10) ]
+                D[14,26] = (-1)*var(11); // [ var(26) , var(14) ]
+                D[17,26] = (-1)*var(15); // [ var(26) , var(17) ]
+                D[20,26] = (-1)*var(18); // [ var(26) , var(20) ]
+                D[22,26] = (-1)*var(21); // [ var(26) , var(22) ]
+                D[24,26] = (-2)*var(23); // [ var(26) , var(24) ]
+                D[25,26] = (-1)*var(24); // [ var(26) , var(25) ]
+                D[2,27] = (-1)*var(52); // [ var(27) , var(2) ]
+                D[6,27] = var(1); // [ var(27) , var(6) ]
+                D[7,27] = (-1)*var(3); // [ var(27) , var(7) ]
+                D[11,27] = (-1)*var(8); // [ var(27) , var(11) ]
+                D[15,27] = (-1)*var(12); // [ var(27) , var(15) ]
+                D[18,27] = (-1)*var(16); // [ var(27) , var(18) ]
+                D[21,27] = (-2)*var(19); // [ var(27) , var(21) ]
+                D[23,27] = (-1)*var(21); // [ var(27) , var(23) ]
+                D[24,27] = (-1)*var(22); // [ var(27) , var(24) ]
+                D[3,28] = (-1)*var(53); // [ var(28) , var(3) ]
+                D[7,28] = var(2); // [ var(28) , var(7) ]
+                D[8,28] = (-1)*var(4); // [ var(28) , var(8) ]
+                D[10,28] = var(6); // [ var(28) , var(10) ]
+                D[12,28] = (-1)*var(9); // [ var(28) , var(12) ]
+                D[16,28] = (-2)*var(13); // [ var(28) , var(16) ]
+                D[19,28] = (-1)*var(16); // [ var(28) , var(19) ]
+                D[21,28] = (-1)*var(18); // [ var(28) , var(21) ]
+                D[22,28] = (-1)*var(20); // [ var(28) , var(22) ]
+                D[4,29] = (-1)*var(54); // [ var(29) , var(4) ]
+                D[8,29] = var(3); // [ var(29) , var(8) ]
+                D[9,29] = (-2)*var(5); // [ var(29) , var(9) ]
+                D[11,29] = var(7); // [ var(29) , var(11) ]
+                D[13,29] = (-1)*var(9); // [ var(29) , var(13) ]
+                D[14,29] = var(10); // [ var(29) , var(14) ]
+                D[16,29] = (-1)*var(12); // [ var(29) , var(16) ]
+                D[18,29] = (-1)*var(15); // [ var(29) , var(18) ]
+                D[20,29] = (-1)*var(17); // [ var(29) , var(20) ]
+                D[5,30] = (-1)*var(55); // [ var(30) , var(5) ]
+                D[9,30] = var(4); // [ var(30) , var(9) ]
+                D[12,30] = var(8); // [ var(30) , var(12) ]
+                D[15,30] = var(11); // [ var(30) , var(15) ]
+                D[17,30] = var(14); // [ var(30) , var(17) ]
+                D[1,31] = (-1)*var(27); // [ var(31) , var(1) ]
+                D[2,31] = var(26); // [ var(31) , var(2) ]
+                D[6,31] = (-1)*var(51)+(-1)*var(52); // [ var(31) , var(6) ]
+                D[10,31] = (-1)*var(3); // [ var(31) , var(10) ]
+                D[14,31] = (-1)*var(8); // [ var(31) , var(14) ]
+                D[17,31] = (-1)*var(12); // [ var(31) , var(17) ]
+                D[20,31] = (-1)*var(16); // [ var(31) , var(20) ]
+                D[22,31] = (-2)*var(19); // [ var(31) , var(22) ]
+                D[24,31] = (-1)*var(21); // [ var(31) , var(24) ]
+                D[25,31] = (-1)*var(22); // [ var(31) , var(25) ]
+                D[2,32] = (-1)*var(28); // [ var(32) , var(2) ]
+                D[3,32] = var(27); // [ var(32) , var(3) ]
+                D[7,32] = (-1)*var(52)+(-1)*var(53); // [ var(32) , var(7) ]
+                D[10,32] = var(1); // [ var(32) , var(10) ]
+                D[11,32] = (-1)*var(4); // [ var(32) , var(11) ]
+                D[15,32] = (-1)*var(9); // [ var(32) , var(15) ]
+                D[18,32] = (-2)*var(13); // [ var(32) , var(18) ]
+                D[21,32] = (-1)*var(16); // [ var(32) , var(21) ]
+                D[23,32] = (-1)*var(18); // [ var(32) , var(23) ]
+                D[24,32] = (-1)*var(20); // [ var(32) , var(24) ]
+                D[3,33] = (-1)*var(29); // [ var(33) , var(3) ]
+                D[4,33] = var(28); // [ var(33) , var(4) ]
+                D[8,33] = (-1)*var(53)+(-1)*var(54); // [ var(33) , var(8) ]
+                D[11,33] = var(2); // [ var(33) , var(11) ]
+                D[12,33] = (-2)*var(5); // [ var(33) , var(12) ]
+                D[14,33] = var(6); // [ var(33) , var(14) ]
+                D[16,33] = (-1)*var(9); // [ var(33) , var(16) ]
+                D[19,33] = (-1)*var(12); // [ var(33) , var(19) ]
+                D[21,33] = (-1)*var(15); // [ var(33) , var(21) ]
+                D[22,33] = (-1)*var(17); // [ var(33) , var(22) ]
+                D[4,34] = (-2)*var(30); // [ var(34) , var(4) ]
+                D[5,34] = var(29); // [ var(34) , var(5) ]
+                D[9,34] = (-1)*var(54)+(-2)*var(55); // [ var(34) , var(9) ]
+                D[12,34] = var(3); // [ var(34) , var(12) ]
+                D[13,34] = var(4); // [ var(34) , var(13) ]
+                D[15,34] = var(7); // [ var(34) , var(15) ]
+                D[16,34] = var(8); // [ var(34) , var(16) ]
+                D[17,34] = var(10); // [ var(34) , var(17) ]
+                D[18,34] = var(11); // [ var(34) , var(18) ]
+                D[20,34] = var(14); // [ var(34) , var(20) ]
+                D[1,35] = (-1)*var(32); // [ var(35) , var(1) ]
+                D[3,35] = var(31); // [ var(35) , var(3) ]
+                D[6,35] = (-1)*var(28); // [ var(35) , var(6) ]
+                D[7,35] = var(26); // [ var(35) , var(7) ]
+                D[10,35] = (-1)*var(51)+(-1)*var(52)+(-1)*var(53); // [ var(35) , var(10) ]
+                D[14,35] = (-1)*var(4); // [ var(35) , var(14) ]
+                D[17,35] = (-1)*var(9); // [ var(35) , var(17) ]
+                D[20,35] = (-2)*var(13); // [ var(35) , var(20) ]
+                D[22,35] = (-1)*var(16); // [ var(35) , var(22) ]
+                D[24,35] = (-1)*var(18); // [ var(35) , var(24) ]
+                D[25,35] = (-1)*var(20); // [ var(35) , var(25) ]
+                D[2,36] = (-1)*var(33); // [ var(36) , var(2) ]
+                D[4,36] = var(32); // [ var(36) , var(4) ]
+                D[7,36] = (-1)*var(29); // [ var(36) , var(7) ]
+                D[8,36] = var(27); // [ var(36) , var(8) ]
+                D[11,36] = (-1)*var(52)+(-1)*var(53)+(-1)*var(54); // [ var(36) , var(11) ]
+                D[14,36] = var(1); // [ var(36) , var(14) ]
+                D[15,36] = (-2)*var(5); // [ var(36) , var(15) ]
+                D[18,36] = (-1)*var(9); // [ var(36) , var(18) ]
+                D[21,36] = (-1)*var(12); // [ var(36) , var(21) ]
+                D[23,36] = (-1)*var(15); // [ var(36) , var(23) ]
+                D[24,36] = (-1)*var(17); // [ var(36) , var(24) ]
+                D[3,37] = (-1)*var(34); // [ var(37) , var(3) ]
+                D[5,37] = var(33); // [ var(37) , var(5) ]
+                D[8,37] = (-2)*var(30); // [ var(37) , var(8) ]
+                D[9,37] = var(28); // [ var(37) , var(9) ]
+                D[12,37] = (-1)*var(53)+(-1)*var(54)+(-2)*var(55); // [ var(37) , var(12) ]
+                D[15,37] = var(2); // [ var(37) , var(15) ]
+                D[16,37] = var(4); // [ var(37) , var(16) ]
+                D[17,37] = var(6); // [ var(37) , var(17) ]
+                D[19,37] = var(8); // [ var(37) , var(19) ]
+                D[21,37] = var(11); // [ var(37) , var(21) ]
+                D[22,37] = var(14); // [ var(37) , var(22) ]
+                D[4,38] = (-1)*var(34); // [ var(38) , var(4) ]
+                D[9,38] = var(29); // [ var(38) , var(9) ]
+                D[13,38] = (-1)*var(54)+(-1)*var(55); // [ var(38) , var(13) ]
+                D[16,38] = var(3); // [ var(38) , var(16) ]
+                D[18,38] = var(7); // [ var(38) , var(18) ]
+                D[20,38] = var(10); // [ var(38) , var(20) ]
+                D[1,39] = (-1)*var(36); // [ var(39) , var(1) ]
+                D[4,39] = var(35); // [ var(39) , var(4) ]
+                D[6,39] = (-1)*var(33); // [ var(39) , var(6) ]
+                D[8,39] = var(31); // [ var(39) , var(8) ]
+                D[10,39] = (-1)*var(29); // [ var(39) , var(10) ]
+                D[11,39] = var(26); // [ var(39) , var(11) ]
+                D[14,39] = (-1)*var(51)+(-1)*var(52)+(-1)*var(53)+(-1)*var(54); // [ var(39) , var(14) ]
+                D[17,39] = (-2)*var(5); // [ var(39) , var(17) ]
+                D[20,39] = (-1)*var(9); // [ var(39) , var(20) ]
+                D[22,39] = (-1)*var(12); // [ var(39) , var(22) ]
+                D[24,39] = (-1)*var(15); // [ var(39) , var(24) ]
+                D[25,39] = (-1)*var(17); // [ var(39) , var(25) ]
+                D[2,40] = (-1)*var(37); // [ var(40) , var(2) ]
+                D[5,40] = var(36); // [ var(40) , var(5) ]
+                D[7,40] = (-1)*var(34); // [ var(40) , var(7) ]
+                D[9,40] = var(32); // [ var(40) , var(9) ]
+                D[11,40] = (-2)*var(30); // [ var(40) , var(11) ]
+                D[12,40] = var(27); // [ var(40) , var(12) ]
+                D[15,40] = (-1)*var(52)+(-1)*var(53)+(-1)*var(54)+(-2)*var(55); // [ var(40) , var(15) ]
+                D[17,40] = var(1); // [ var(40) , var(17) ]
+                D[18,40] = var(4); // [ var(40) , var(18) ]
+                D[21,40] = var(8); // [ var(40) , var(21) ]
+                D[23,40] = var(11); // [ var(40) , var(23) ]
+                D[24,40] = var(14); // [ var(40) , var(24) ]
+                D[3,41] = (-2)*var(38); // [ var(41) , var(3) ]
+                D[4,41] = (-1)*var(37); // [ var(41) , var(4) ]
+                D[8,41] = (-1)*var(34); // [ var(41) , var(8) ]
+                D[9,41] = var(33); // [ var(41) , var(9) ]
+                D[12,41] = var(29); // [ var(41) , var(12) ]
+                D[13,41] = var(28); // [ var(41) , var(13) ]
+                D[16,41] = (-1)*var(53)+(-2)*var(54)+(-2)*var(55); // [ var(41) , var(16) ]
+                D[18,41] = var(2); // [ var(41) , var(18) ]
+                D[19,41] = var(3); // [ var(41) , var(19) ]
+                D[20,41] = var(6); // [ var(41) , var(20) ]
+                D[21,41] = var(7); // [ var(41) , var(21) ]
+                D[22,41] = var(10); // [ var(41) , var(22) ]
+                D[1,42] = (-1)*var(40); // [ var(42) , var(1) ]
+                D[5,42] = var(39); // [ var(42) , var(5) ]
+                D[6,42] = (-1)*var(37); // [ var(42) , var(6) ]
+                D[9,42] = var(35); // [ var(42) , var(9) ]
+                D[10,42] = (-1)*var(34); // [ var(42) , var(10) ]
+                D[12,42] = var(31); // [ var(42) , var(12) ]
+                D[14,42] = (-2)*var(30); // [ var(42) , var(14) ]
+                D[15,42] = var(26); // [ var(42) , var(15) ]
+                D[17,42] = (-1)*var(51)+(-1)*var(52)+(-1)*var(53)+(-1)*var(54)+(-2)*var(55); // [ var(42) , var(17) ]
+                D[20,42] = var(4); // [ var(42) , var(20) ]
+                D[22,42] = var(8); // [ var(42) , var(22) ]
+                D[24,42] = var(11); // [ var(42) , var(24) ]
+                D[25,42] = var(14); // [ var(42) , var(25) ]
+                D[2,43] = (-1)*var(41); // [ var(43) , var(2) ]
+                D[4,43] = (-1)*var(40); // [ var(43) , var(4) ]
+                D[7,43] = (-2)*var(38); // [ var(43) , var(7) ]
+                D[9,43] = var(36); // [ var(43) , var(9) ]
+                D[11,43] = (-1)*var(34); // [ var(43) , var(11) ]
+                D[13,43] = var(32); // [ var(43) , var(13) ]
+                D[15,43] = var(29); // [ var(43) , var(15) ]
+                D[16,43] = var(27); // [ var(43) , var(16) ]
+                D[18,43] = (-1)*var(52)+(-1)*var(53)+(-2)*var(54)+(-2)*var(55); // [ var(43) , var(18) ]
+                D[20,43] = var(1); // [ var(43) , var(20) ]
+                D[21,43] = var(3); // [ var(43) , var(21) ]
+                D[23,43] = var(7); // [ var(43) , var(23) ]
+                D[24,43] = var(10); // [ var(43) , var(24) ]
+                D[3,44] = (-1)*var(41); // [ var(44) , var(3) ]
+                D[8,44] = (-1)*var(37); // [ var(44) , var(8) ]
+                D[12,44] = var(33); // [ var(44) , var(12) ]
+                D[16,44] = var(28); // [ var(44) , var(16) ]
+                D[19,44] = (-1)*var(53)+(-1)*var(54)+(-1)*var(55); // [ var(44) , var(19) ]
+                D[21,44] = var(2); // [ var(44) , var(21) ]
+                D[22,44] = var(6); // [ var(44) , var(22) ]
+                D[1,45] = (-1)*var(43); // [ var(45) , var(1) ]
+                D[4,45] = (-1)*var(42); // [ var(45) , var(4) ]
+                D[6,45] = (-1)*var(41); // [ var(45) , var(6) ]
+                D[9,45] = var(39); // [ var(45) , var(9) ]
+                D[10,45] = (-2)*var(38); // [ var(45) , var(10) ]
+                D[13,45] = var(35); // [ var(45) , var(13) ]
+                D[14,45] = (-1)*var(34); // [ var(45) , var(14) ]
+                D[16,45] = var(31); // [ var(45) , var(16) ]
+                D[17,45] = var(29); // [ var(45) , var(17) ]
+                D[18,45] = var(26); // [ var(45) , var(18) ]
+                D[20,45] = (-1)*var(51)+(-1)*var(52)+(-1)*var(53)+(-2)*var(54)+(-2)*var(55); // [ var(45) , var(20) ]
+                D[22,45] = var(3); // [ var(45) , var(22) ]
+                D[24,45] = var(7); // [ var(45) , var(24) ]
+                D[25,45] = var(10); // [ var(45) , var(25) ]
+                D[2,46] = (-2)*var(44); // [ var(46) , var(2) ]
+                D[3,46] = (-1)*var(43); // [ var(46) , var(3) ]
+                D[7,46] = (-1)*var(41); // [ var(46) , var(7) ]
+                D[8,46] = (-1)*var(40); // [ var(46) , var(8) ]
+                D[11,46] = (-1)*var(37); // [ var(46) , var(11) ]
+                D[12,46] = var(36); // [ var(46) , var(12) ]
+                D[15,46] = var(33); // [ var(46) , var(15) ]
+                D[16,46] = var(32); // [ var(46) , var(16) ]
+                D[18,46] = var(28); // [ var(46) , var(18) ]
+                D[19,46] = var(27); // [ var(46) , var(19) ]
+                D[21,46] = (-1)*var(52)+(-2)*var(53)+(-2)*var(54)+(-2)*var(55); // [ var(46) , var(21) ]
+                D[22,46] = var(1); // [ var(46) , var(22) ]
+                D[23,46] = var(2); // [ var(46) , var(23) ]
+                D[24,46] = var(6); // [ var(46) , var(24) ]
+                D[1,47] = (-1)*var(46); // [ var(47) , var(1) ]
+                D[3,47] = (-1)*var(45); // [ var(47) , var(3) ]
+                D[6,47] = (-2)*var(44); // [ var(47) , var(6) ]
+                D[8,47] = (-1)*var(42); // [ var(47) , var(8) ]
+                D[10,47] = (-1)*var(41); // [ var(47) , var(10) ]
+                D[12,47] = var(39); // [ var(47) , var(12) ]
+                D[14,47] = (-1)*var(37); // [ var(47) , var(14) ]
+                D[16,47] = var(35); // [ var(47) , var(16) ]
+                D[17,47] = var(33); // [ var(47) , var(17) ]
+                D[19,47] = var(31); // [ var(47) , var(19) ]
+                D[20,47] = var(28); // [ var(47) , var(20) ]
+                D[21,47] = var(26); // [ var(47) , var(21) ]
+                D[22,47] = (-1)*var(51)+(-1)*var(52)+(-2)*var(53)+(-2)*var(54)+(-2)*var(55); // [ var(47) , var(22) ]
+                D[24,47] = var(2); // [ var(47) , var(24) ]
+                D[25,47] = var(6); // [ var(47) , var(25) ]
+                D[2,48] = (-1)*var(46); // [ var(48) , var(2) ]
+                D[7,48] = (-1)*var(43); // [ var(48) , var(7) ]
+                D[11,48] = (-1)*var(40); // [ var(48) , var(11) ]
+                D[15,48] = var(36); // [ var(48) , var(15) ]
+                D[18,48] = var(32); // [ var(48) , var(18) ]
+                D[21,48] = var(27); // [ var(48) , var(21) ]
+                D[23,48] = (-1)*var(52)+(-1)*var(53)+(-1)*var(54)+(-1)*var(55); // [ var(48) , var(23) ]
+                D[24,48] = var(1); // [ var(48) , var(24) ]
+                D[1,49] = (-2)*var(48); // [ var(49) , var(1) ]
+                D[2,49] = (-1)*var(47); // [ var(49) , var(2) ]
+                D[6,49] = (-1)*var(46); // [ var(49) , var(6) ]
+                D[7,49] = (-1)*var(45); // [ var(49) , var(7) ]
+                D[10,49] = (-1)*var(43); // [ var(49) , var(10) ]
+                D[11,49] = (-1)*var(42); // [ var(49) , var(11) ]
+                D[14,49] = (-1)*var(40); // [ var(49) , var(14) ]
+                D[15,49] = var(39); // [ var(49) , var(15) ]
+                D[17,49] = var(36); // [ var(49) , var(17) ]
+                D[18,49] = var(35); // [ var(49) , var(18) ]
+                D[20,49] = var(32); // [ var(49) , var(20) ]
+                D[21,49] = var(31); // [ var(49) , var(21) ]
+                D[22,49] = var(27); // [ var(49) , var(22) ]
+                D[23,49] = var(26); // [ var(49) , var(23) ]
+                D[24,49] = (-1)*var(51)+(-2)*var(52)+(-2)*var(53)+(-2)*var(54)+(-2)*var(55); // [ var(49) , var(24) ]
+                D[25,49] = var(1); // [ var(49) , var(25) ]
+                D[1,50] = (-1)*var(49); // [ var(50) , var(1) ]
+                D[6,50] = (-1)*var(47); // [ var(50) , var(6) ]
+                D[10,50] = (-1)*var(45); // [ var(50) , var(10) ]
+                D[14,50] = (-1)*var(42); // [ var(50) , var(14) ]
+                D[17,50] = var(39); // [ var(50) , var(17) ]
+                D[20,50] = var(35); // [ var(50) , var(20) ]
+                D[22,50] = var(31); // [ var(50) , var(22) ]
+                D[24,50] = var(26); // [ var(50) , var(24) ]
+                D[25,50] = (-1)*var(51)+(-1)*var(52)+(-1)*var(53)+(-1)*var(54)+(-1)*var(55); // [ var(50) , var(25) ]
+        // X(i) * X(j):
+                D[1,2] = var(6); // [ var(2) , var(1) ]
+                D[1,7] = var(10); // [ var(7) , var(1) ]
+                D[1,11] = var(14); // [ var(11) , var(1) ]
+                D[1,15] = var(17); // [ var(15) , var(1) ]
+                D[1,18] = var(20); // [ var(18) , var(1) ]
+                D[1,21] = var(22); // [ var(21) , var(1) ]
+                D[1,23] = var(24); // [ var(23) , var(1) ]
+                D[1,24] = (2)*var(25); // [ var(24) , var(1) ]
+                D[2,3] = var(7); // [ var(3) , var(2) ]
+                D[2,8] = var(11); // [ var(8) , var(2) ]
+                D[2,12] = var(15); // [ var(12) , var(2) ]
+                D[2,16] = var(18); // [ var(16) , var(2) ]
+                D[2,19] = var(21); // [ var(19) , var(2) ]
+                D[2,21] = (2)*var(23); // [ var(21) , var(2) ]
+                D[2,22] = var(24); // [ var(22) , var(2) ]
+                D[3,4] = var(8); // [ var(4) , var(3) ]
+                D[3,6] = (-1)*var(10); // [ var(6) , var(3) ]
+                D[3,9] = var(12); // [ var(9) , var(3) ]
+                D[3,13] = var(16); // [ var(13) , var(3) ]
+                D[3,16] = (2)*var(19); // [ var(16) , var(3) ]
+                D[3,18] = var(21); // [ var(18) , var(3) ]
+                D[3,20] = var(22); // [ var(20) , var(3) ]
+                D[4,5] = var(9); // [ var(5) , var(4) ]
+                D[4,7] = (-1)*var(11); // [ var(7) , var(4) ]
+                D[4,9] = (2)*var(13); // [ var(9) , var(4) ]
+                D[4,10] = (-1)*var(14); // [ var(10) , var(4) ]
+                D[4,12] = var(16); // [ var(12) , var(4) ]
+                D[4,15] = var(18); // [ var(15) , var(4) ]
+                D[4,17] = var(20); // [ var(17) , var(4) ]
+                D[5,8] = (-1)*var(12); // [ var(8) , var(5) ]
+                D[5,11] = (-1)*var(15); // [ var(11) , var(5) ]
+                D[5,14] = (-1)*var(17); // [ var(14) , var(5) ]
+                D[6,8] = var(14); // [ var(8) , var(6) ]
+                D[6,12] = var(17); // [ var(12) , var(6) ]
+                D[6,16] = var(20); // [ var(16) , var(6) ]
+                D[6,19] = var(22); // [ var(19) , var(6) ]
+                D[6,21] = var(24); // [ var(21) , var(6) ]
+                D[6,22] = (2)*var(25); // [ var(22) , var(6) ]
+                D[7,9] = var(15); // [ var(9) , var(7) ]
+                D[7,13] = var(18); // [ var(13) , var(7) ]
+                D[7,16] = var(21); // [ var(16) , var(7) ]
+                D[7,18] = (2)*var(23); // [ var(18) , var(7) ]
+                D[7,20] = var(24); // [ var(20) , var(7) ]
+                D[8,9] = var(16); // [ var(9) , var(8) ]
+                D[8,12] = (2)*var(19); // [ var(12) , var(8) ]
+                D[8,15] = var(21); // [ var(15) , var(8) ]
+                D[8,17] = var(22); // [ var(17) , var(8) ]
+                D[9,10] = (-1)*var(17); // [ var(10) , var(9) ]
+                D[9,11] = (-1)*var(18); // [ var(11) , var(9) ]
+                D[9,14] = (-1)*var(20); // [ var(14) , var(9) ]
+                D[10,13] = var(20); // [ var(13) , var(10) ]
+                D[10,16] = var(22); // [ var(16) , var(10) ]
+                D[10,18] = var(24); // [ var(18) , var(10) ]
+                D[10,20] = (2)*var(25); // [ var(20) , var(10) ]
+                D[11,12] = var(21); // [ var(12) , var(11) ]
+                D[11,15] = (2)*var(23); // [ var(15) , var(11) ]
+                D[11,17] = var(24); // [ var(17) , var(11) ]
+                D[12,14] = (-1)*var(22); // [ var(14) , var(12) ]
+                D[14,15] = var(24); // [ var(15) , var(14) ]
+                D[14,17] = (2)*var(25); // [ var(17) , var(14) ]
+        // Y(i) * Y(j):
+                D[26,27] = (-1)*var(31); // [ var(27) , var(26) ]
+                D[26,32] = (-1)*var(35); // [ var(32) , var(26) ]
+                D[26,36] = (-1)*var(39); // [ var(36) , var(26) ]
+                D[26,40] = (-1)*var(42); // [ var(40) , var(26) ]
+                D[26,43] = (-1)*var(45); // [ var(43) , var(26) ]
+                D[26,46] = (-1)*var(47); // [ var(46) , var(26) ]
+                D[26,48] = (-1)*var(49); // [ var(48) , var(26) ]
+                D[26,49] = (-2)*var(50); // [ var(49) , var(26) ]
+                D[27,28] = (-1)*var(32); // [ var(28) , var(27) ]
+                D[27,33] = (-1)*var(36); // [ var(33) , var(27) ]
+                D[27,37] = (-1)*var(40); // [ var(37) , var(27) ]
+                D[27,41] = (-1)*var(43); // [ var(41) , var(27) ]
+                D[27,44] = (-1)*var(46); // [ var(44) , var(27) ]
+                D[27,46] = (-2)*var(48); // [ var(46) , var(27) ]
+                D[27,47] = (-1)*var(49); // [ var(47) , var(27) ]
+                D[28,29] = (-1)*var(33); // [ var(29) , var(28) ]
+                D[28,31] = var(35); // [ var(31) , var(28) ]
+                D[28,34] = (-1)*var(37); // [ var(34) , var(28) ]
+                D[28,38] = (-1)*var(41); // [ var(38) , var(28) ]
+                D[28,41] = (-2)*var(44); // [ var(41) , var(28) ]
+                D[28,43] = (-1)*var(46); // [ var(43) , var(28) ]
+                D[28,45] = (-1)*var(47); // [ var(45) , var(28) ]
+                D[29,30] = (-1)*var(34); // [ var(30) , var(29) ]
+                D[29,32] = var(36); // [ var(32) , var(29) ]
+                D[29,34] = (-2)*var(38); // [ var(34) , var(29) ]
+                D[29,35] = var(39); // [ var(35) , var(29) ]
+                D[29,37] = (-1)*var(41); // [ var(37) , var(29) ]
+                D[29,40] = (-1)*var(43); // [ var(40) , var(29) ]
+                D[29,42] = (-1)*var(45); // [ var(42) , var(29) ]
+                D[30,33] = var(37); // [ var(33) , var(30) ]
+                D[30,36] = var(40); // [ var(36) , var(30) ]
+                D[30,39] = var(42); // [ var(39) , var(30) ]
+                D[31,33] = (-1)*var(39); // [ var(33) , var(31) ]
+                D[31,37] = (-1)*var(42); // [ var(37) , var(31) ]
+                D[31,41] = (-1)*var(45); // [ var(41) , var(31) ]
+                D[31,44] = (-1)*var(47); // [ var(44) , var(31) ]
+                D[31,46] = (-1)*var(49); // [ var(46) , var(31) ]
+                D[31,47] = (-2)*var(50); // [ var(47) , var(31) ]
+                D[32,34] = (-1)*var(40); // [ var(34) , var(32) ]
+                D[32,38] = (-1)*var(43); // [ var(38) , var(32) ]
+                D[32,41] = (-1)*var(46); // [ var(41) , var(32) ]
+                D[32,43] = (-2)*var(48); // [ var(43) , var(32) ]
+                D[32,45] = (-1)*var(49); // [ var(45) , var(32) ]
+                D[33,34] = (-1)*var(41); // [ var(34) , var(33) ]
+                D[33,37] = (-2)*var(44); // [ var(37) , var(33) ]
+                D[33,40] = (-1)*var(46); // [ var(40) , var(33) ]
+                D[33,42] = (-1)*var(47); // [ var(42) , var(33) ]
+                D[34,35] = var(42); // [ var(35) , var(34) ]
+                D[34,36] = var(43); // [ var(36) , var(34) ]
+                D[34,39] = var(45); // [ var(39) , var(34) ]
+                D[35,38] = (-1)*var(45); // [ var(38) , var(35) ]
+                D[35,41] = (-1)*var(47); // [ var(41) , var(35) ]
+                D[35,43] = (-1)*var(49); // [ var(43) , var(35) ]
+                D[35,45] = (-2)*var(50); // [ var(45) , var(35) ]
+                D[36,37] = (-1)*var(46); // [ var(37) , var(36) ]
+                D[36,40] = (-2)*var(48); // [ var(40) , var(36) ]
+                D[36,42] = (-1)*var(49); // [ var(42) , var(36) ]
+                D[37,39] = var(47); // [ var(39) , var(37) ]
+                D[39,40] = (-1)*var(49); // [ var(40) , var(39) ]
+                D[39,42] = (-2)*var(50); // [ var(42) , var(39) ]
+   def @@RR=nc_algebra(1,D);
+   return(@@RR);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   def ncAlgebra = makeUsp5();
+   ncAlgebra;
+   setring ncAlgebra;
+   // ...  523  noncommutative relations
+}
+////////////////////////////////////////////////////////////////////
+
+// Algebra: so6(Q) has the type: D3, and defined by:
+
+proc makeUso6(list #)
+"USAGE:   makeUso6([p]); p an optional integer (field characteristic)
+RETURN:  a ring, describing U(so_6)
+NOTE:    You have to activate this ring with the 'setring' command. The presentation of U(so_6) is derived from the Chevalley representation of so_6, positive resp. negative roots are denoted by x(i) resp. y(i); Cartan elements are denoted by h(i).
+SEE ALSO: makeUsl, makeUso5, makeUsp1, makeUe6, makeUe7, makeUe8, makeUg2, makeUf4
+EXAMPLE: example makeUso6; shows examples
+"
+{
+   int @p = defInt(#);
+
+   ring @@@rrr = @p,(X(1..6),Y(1..6),H(1..3)),dp;
+   int N = nvars(@@@rrr);
+   matrix D[N][N]=0;
+
+        // H(i) * X(j):
+                D[1,13] = (2)*var(1); // [ var(13) , var(1) ]
+                D[2,13] = (-1)*var(2); // [ var(13) , var(2) ]
+                D[3,13] = (-1)*var(3); // [ var(13) , var(3) ]
+                D[4,13] = var(4); // [ var(13) , var(4) ]
+                D[5,13] = var(5); // [ var(13) , var(5) ]
+                D[1,14] = (-1)*var(1); // [ var(14) , var(1) ]
+                D[2,14] = (2)*var(2); // [ var(14) , var(2) ]
+                D[4,14] = var(4); // [ var(14) , var(4) ]
+                D[5,14] = (-1)*var(5); // [ var(14) , var(5) ]
+                D[6,14] = var(6); // [ var(14) , var(6) ]
+                D[1,15] = (-1)*var(1); // [ var(15) , var(1) ]
+                D[3,15] = (2)*var(3); // [ var(15) , var(3) ]
+                D[4,15] = (-1)*var(4); // [ var(15) , var(4) ]
+                D[5,15] = var(5); // [ var(15) , var(5) ]
+                D[6,15] = var(6); // [ var(15) , var(6) ]
+        // H(i) * Y(j):
+                D[7,13] = (-2)*var(7); // [ var(13) , var(7) ]
+                D[8,13] = var(8); // [ var(13) , var(8) ]
+                D[9,13] = var(9); // [ var(13) , var(9) ]
+                D[10,13] = (-1)*var(10); // [ var(13) , var(10) ]
+                D[11,13] = (-1)*var(11); // [ var(13) , var(11) ]
+                D[7,14] = var(7); // [ var(14) , var(7) ]
+                D[8,14] = (-2)*var(8); // [ var(14) , var(8) ]
+                D[10,14] = (-1)*var(10); // [ var(14) , var(10) ]
+                D[11,14] = var(11); // [ var(14) , var(11) ]
+                D[12,14] = (-1)*var(12); // [ var(14) , var(12) ]
+                D[7,15] = var(7); // [ var(15) , var(7) ]
+                D[9,15] = (-2)*var(9); // [ var(15) , var(9) ]
+                D[10,15] = var(10); // [ var(15) , var(10) ]
+                D[11,15] = (-1)*var(11); // [ var(15) , var(11) ]
+                D[12,15] = (-1)*var(12); // [ var(15) , var(12) ]
+        // Y(i) * X(j):
+                D[1,7] = (-1)*var(13); // [ var(7) , var(1) ]
+                D[4,7] = (-1)*var(2); // [ var(7) , var(4) ]
+                D[5,7] = (-1)*var(3); // [ var(7) , var(5) ]
+                D[2,8] = (-1)*var(14); // [ var(8) , var(2) ]
+                D[4,8] = var(1); // [ var(8) , var(4) ]
+                D[6,8] = var(5); // [ var(8) , var(6) ]
+                D[3,9] = (-1)*var(15); // [ var(9) , var(3) ]
+                D[5,9] = var(1); // [ var(9) , var(5) ]
+                D[6,9] = var(4); // [ var(9) , var(6) ]
+                D[1,10] = (-1)*var(8); // [ var(10) , var(1) ]
+                D[2,10] = var(7); // [ var(10) , var(2) ]
+                D[4,10] = (-1)*var(13)+(-1)*var(14); // [ var(10) , var(4) ]
+                D[6,10] = (-1)*var(3); // [ var(10) , var(6) ]
+                D[1,11] = (-1)*var(9); // [ var(11) , var(1) ]
+                D[3,11] = var(7); // [ var(11) , var(3) ]
+                D[5,11] = (-1)*var(13)+(-1)*var(15); // [ var(11) , var(5) ]
+                D[6,11] = (-1)*var(2); // [ var(11) , var(6) ]
+                D[2,12] = var(11); // [ var(12) , var(2) ]
+                D[3,12] = var(10); // [ var(12) , var(3) ]
+                D[4,12] = (-1)*var(9); // [ var(12) , var(4) ]
+                D[5,12] = (-1)*var(8); // [ var(12) , var(5) ]
+                D[6,12] = (-1)*var(13)+(-1)*var(14)+(-1)*var(15); // [ var(12) , var(6) ]
+        // X(i) * X(j):
+                D[1,2] = var(4); // [ var(2) , var(1) ]
+                D[1,3] = var(5); // [ var(3) , var(1) ]
+                D[2,5] = (-1)*var(6); // [ var(5) , var(2) ]
+                D[3,4] = (-1)*var(6); // [ var(4) , var(3) ]
+        // Y(i) * Y(j):
+                D[7,8] = (-1)*var(10); // [ var(8) , var(7) ]
+                D[7,9] = (-1)*var(11); // [ var(9) , var(7) ]
+                D[8,11] = var(12); // [ var(11) , var(8) ]
+                D[9,10] = var(12); // [ var(10) , var(9) ]
+   def @@RR=nc_algebra(1,D);
+   return(@@RR);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   def ncAlgebra = makeUso6();
+   ncAlgebra;
+   setring ncAlgebra;
+  // ...  60  noncommutative relations
+}
+////////////////////////////////////////////////////////////////////
+
+// Algebra: so8(Q) has the type: D4, and defined by:
+
+proc makeUso8(list #)
+"USAGE:   makeUso8([p]); p an optional integer (field characteristic)
+RETURN:  a ring, describing U(so_8)
+NOTE:    You have to activate this ring with the 'setring' command. The presentation of U(so_8) is derived from the Chevalley representation of so_8, positive resp. negative roots are denoted by x(i) resp. y(i); Cartan elements are denoted by h(i).
+SEE ALSO: makeUsl, makeUso5, makeUsp1, makeUe6, makeUe7, makeUe8, makeUg2, makeUf4
+EXAMPLE: example makeUso8; shows examples
+"
+{
+   int @p = defInt(#);
+
+   ring @@@rrr = @p,(X(1..12),Y(1..12),H(1..4)),dp;
+   int N = nvars(@@@rrr);
+   matrix D[N][N]=0;
+
+        // H(i) * X(j):
+                D[1,25] = (2)*var(1); // [ var(25) , var(1) ]
+                D[2,25] = (-1)*var(2); // [ var(25) , var(2) ]
+                D[5,25] = var(5); // [ var(25) , var(5) ]
+                D[6,25] = (-1)*var(6); // [ var(25) , var(6) ]
+                D[7,25] = (-1)*var(7); // [ var(25) , var(7) ]
+                D[8,25] = var(8); // [ var(25) , var(8) ]
+                D[9,25] = var(9); // [ var(25) , var(9) ]
+                D[10,25] = (-1)*var(10); // [ var(25) , var(10) ]
+                D[11,25] = var(11); // [ var(25) , var(11) ]
+                D[1,26] = (-1)*var(1); // [ var(26) , var(1) ]
+                D[2,26] = (2)*var(2); // [ var(26) , var(2) ]
+                D[3,26] = (-1)*var(3); // [ var(26) , var(3) ]
+                D[4,26] = (-1)*var(4); // [ var(26) , var(4) ]
+                D[5,26] = var(5); // [ var(26) , var(5) ]
+                D[6,26] = var(6); // [ var(26) , var(6) ]
+                D[7,26] = var(7); // [ var(26) , var(7) ]
+                D[11,26] = (-1)*var(11); // [ var(26) , var(11) ]
+                D[12,26] = var(12); // [ var(26) , var(12) ]
+                D[2,27] = (-1)*var(2); // [ var(27) , var(2) ]
+                D[3,27] = (2)*var(3); // [ var(27) , var(3) ]
+                D[5,27] = (-1)*var(5); // [ var(27) , var(5) ]
+                D[6,27] = var(6); // [ var(27) , var(6) ]
+                D[7,27] = (-1)*var(7); // [ var(27) , var(7) ]
+                D[8,27] = var(8); // [ var(27) , var(8) ]
+                D[9,27] = (-1)*var(9); // [ var(27) , var(9) ]
+                D[10,27] = var(10); // [ var(27) , var(10) ]
+                D[11,27] = var(11); // [ var(27) , var(11) ]
+                D[2,28] = (-1)*var(2); // [ var(28) , var(2) ]
+                D[4,28] = (2)*var(4); // [ var(28) , var(4) ]
+                D[5,28] = (-1)*var(5); // [ var(28) , var(5) ]
+                D[6,28] = (-1)*var(6); // [ var(28) , var(6) ]
+                D[7,28] = var(7); // [ var(28) , var(7) ]
+                D[8,28] = (-1)*var(8); // [ var(28) , var(8) ]
+                D[9,28] = var(9); // [ var(28) , var(9) ]
+                D[10,28] = var(10); // [ var(28) , var(10) ]
+                D[11,28] = var(11); // [ var(28) , var(11) ]
+        // H(i) * Y(j):
+                D[13,25] = (-2)*var(13); // [ var(25) , var(13) ]
+                D[14,25] = var(14); // [ var(25) , var(14) ]
+                D[17,25] = (-1)*var(17); // [ var(25) , var(17) ]
+                D[18,25] = var(18); // [ var(25) , var(18) ]
+                D[19,25] = var(19); // [ var(25) , var(19) ]
+                D[20,25] = (-1)*var(20); // [ var(25) , var(20) ]
+                D[21,25] = (-1)*var(21); // [ var(25) , var(21) ]
+                D[22,25] = var(22); // [ var(25) , var(22) ]
+                D[23,25] = (-1)*var(23); // [ var(25) , var(23) ]
+                D[13,26] = var(13); // [ var(26) , var(13) ]
+                D[14,26] = (-2)*var(14); // [ var(26) , var(14) ]
+                D[15,26] = var(15); // [ var(26) , var(15) ]
+                D[16,26] = var(16); // [ var(26) , var(16) ]
+                D[17,26] = (-1)*var(17); // [ var(26) , var(17) ]
+                D[18,26] = (-1)*var(18); // [ var(26) , var(18) ]
+                D[19,26] = (-1)*var(19); // [ var(26) , var(19) ]
+                D[23,26] = var(23); // [ var(26) , var(23) ]
+                D[24,26] = (-1)*var(24); // [ var(26) , var(24) ]
+                D[14,27] = var(14); // [ var(27) , var(14) ]
+                D[15,27] = (-2)*var(15); // [ var(27) , var(15) ]
+                D[17,27] = var(17); // [ var(27) , var(17) ]
+                D[18,27] = (-1)*var(18); // [ var(27) , var(18) ]
+                D[19,27] = var(19); // [ var(27) , var(19) ]
+                D[20,27] = (-1)*var(20); // [ var(27) , var(20) ]
+                D[21,27] = var(21); // [ var(27) , var(21) ]
+                D[22,27] = (-1)*var(22); // [ var(27) , var(22) ]
+                D[23,27] = (-1)*var(23); // [ var(27) , var(23) ]
+                D[14,28] = var(14); // [ var(28) , var(14) ]
+                D[16,28] = (-2)*var(16); // [ var(28) , var(16) ]
+                D[17,28] = var(17); // [ var(28) , var(17) ]
+                D[18,28] = var(18); // [ var(28) , var(18) ]
+                D[19,28] = (-1)*var(19); // [ var(28) , var(19) ]
+                D[20,28] = var(20); // [ var(28) , var(20) ]
+                D[21,28] = (-1)*var(21); // [ var(28) , var(21) ]
+                D[22,28] = (-1)*var(22); // [ var(28) , var(22) ]
+                D[23,28] = (-1)*var(23); // [ var(28) , var(23) ]
+        // Y(i) * X(j):
+                D[1,13] = (-1)*var(25); // [ var(13) , var(1) ]
+                D[5,13] = (-1)*var(2); // [ var(13) , var(5) ]
+                D[8,13] = (-1)*var(6); // [ var(13) , var(8) ]
+                D[9,13] = (-1)*var(7); // [ var(13) , var(9) ]
+                D[11,13] = (-1)*var(10); // [ var(13) , var(11) ]
+                D[2,14] = (-1)*var(26); // [ var(14) , var(2) ]
+                D[5,14] = var(1); // [ var(14) , var(5) ]
+                D[6,14] = (-1)*var(3); // [ var(14) , var(6) ]
+                D[7,14] = (-1)*var(4); // [ var(14) , var(7) ]
+                D[12,14] = (-1)*var(11); // [ var(14) , var(12) ]
+                D[3,15] = (-1)*var(27); // [ var(15) , var(3) ]
+                D[6,15] = var(2); // [ var(15) , var(6) ]
+                D[8,15] = var(5); // [ var(15) , var(8) ]
+                D[10,15] = var(7); // [ var(15) , var(10) ]
+                D[11,15] = var(9); // [ var(15) , var(11) ]
+                D[4,16] = (-1)*var(28); // [ var(16) , var(4) ]
+                D[7,16] = var(2); // [ var(16) , var(7) ]
+                D[9,16] = var(5); // [ var(16) , var(9) ]
+                D[10,16] = var(6); // [ var(16) , var(10) ]
+                D[11,16] = var(8); // [ var(16) , var(11) ]
+                D[1,17] = (-1)*var(14); // [ var(17) , var(1) ]
+                D[2,17] = var(13); // [ var(17) , var(2) ]
+                D[5,17] = (-1)*var(25)+(-1)*var(26); // [ var(17) , var(5) ]
+                D[8,17] = (-1)*var(3); // [ var(17) , var(8) ]
+                D[9,17] = (-1)*var(4); // [ var(17) , var(9) ]
+                D[12,17] = var(10); // [ var(17) , var(12) ]
+                D[2,18] = (-1)*var(15); // [ var(18) , var(2) ]
+                D[3,18] = var(14); // [ var(18) , var(3) ]
+                D[6,18] = (-1)*var(26)+(-1)*var(27); // [ var(18) , var(6) ]
+                D[8,18] = var(1); // [ var(18) , var(8) ]
+                D[10,18] = (-1)*var(4); // [ var(18) , var(10) ]
+                D[12,18] = var(9); // [ var(18) , var(12) ]
+                D[2,19] = (-1)*var(16); // [ var(19) , var(2) ]
+                D[4,19] = var(14); // [ var(19) , var(4) ]
+                D[7,19] = (-1)*var(26)+(-1)*var(28); // [ var(19) , var(7) ]
+                D[9,19] = var(1); // [ var(19) , var(9) ]
+                D[10,19] = (-1)*var(3); // [ var(19) , var(10) ]
+                D[12,19] = var(8); // [ var(19) , var(12) ]
+                D[1,20] = (-1)*var(18); // [ var(20) , var(1) ]
+                D[3,20] = var(17); // [ var(20) , var(3) ]
+                D[5,20] = (-1)*var(15); // [ var(20) , var(5) ]
+                D[6,20] = var(13); // [ var(20) , var(6) ]
+                D[8,20] = (-1)*var(25)+(-1)*var(26)+(-1)*var(27); // [ var(20) , var(8) ]
+                D[11,20] = (-1)*var(4); // [ var(20) , var(11) ]
+                D[12,20] = (-1)*var(7); // [ var(20) , var(12) ]
+                D[1,21] = (-1)*var(19); // [ var(21) , var(1) ]
+                D[4,21] = var(17); // [ var(21) , var(4) ]
+                D[5,21] = (-1)*var(16); // [ var(21) , var(5) ]
+                D[7,21] = var(13); // [ var(21) , var(7) ]
+                D[9,21] = (-1)*var(25)+(-1)*var(26)+(-1)*var(28); // [ var(21) , var(9) ]
+                D[11,21] = (-1)*var(3); // [ var(21) , var(11) ]
+                D[12,21] = (-1)*var(6); // [ var(21) , var(12) ]
+                D[3,22] = var(19); // [ var(22) , var(3) ]
+                D[4,22] = var(18); // [ var(22) , var(4) ]
+                D[6,22] = (-1)*var(16); // [ var(22) , var(6) ]
+                D[7,22] = (-1)*var(15); // [ var(22) , var(7) ]
+                D[10,22] = (-1)*var(26)+(-1)*var(27)+(-1)*var(28); // [ var(22) , var(10) ]
+                D[11,22] = var(1); // [ var(22) , var(11) ]
+                D[12,22] = (-1)*var(5); // [ var(22) , var(12) ]
+                D[1,23] = (-1)*var(22); // [ var(23) , var(1) ]
+                D[3,23] = var(21); // [ var(23) , var(3) ]
+                D[4,23] = var(20); // [ var(23) , var(4) ]
+                D[8,23] = (-1)*var(16); // [ var(23) , var(8) ]
+                D[9,23] = (-1)*var(15); // [ var(23) , var(9) ]
+                D[10,23] = var(13); // [ var(23) , var(10) ]
+                D[11,23] = (-1)*var(25)+(-1)*var(26)+(-1)*var(27)+(-1)*var(28); // [ var(23) , var(11) ]
+                D[12,23] = var(2); // [ var(23) , var(12) ]
+                D[2,24] = (-1)*var(23); // [ var(24) , var(2) ]
+                D[5,24] = var(22); // [ var(24) , var(5) ]
+                D[6,24] = var(21); // [ var(24) , var(6) ]
+                D[7,24] = var(20); // [ var(24) , var(7) ]
+                D[8,24] = (-1)*var(19); // [ var(24) , var(8) ]
+                D[9,24] = (-1)*var(18); // [ var(24) , var(9) ]
+                D[10,24] = (-1)*var(17); // [ var(24) , var(10) ]
+                D[11,24] = var(14); // [ var(24) , var(11) ]
+                D[12,24] = (-1)*var(25)+(-2)*var(26)+(-1)*var(27)+(-1)*var(28); // [ var(24) , var(12) ]
+        // X(i) * X(j):
+                D[1,2] = var(5); // [ var(2) , var(1) ]
+                D[1,6] = var(8); // [ var(6) , var(1) ]
+                D[1,7] = var(9); // [ var(7) , var(1) ]
+                D[1,10] = var(11); // [ var(10) , var(1) ]
+                D[2,3] = var(6); // [ var(3) , var(2) ]
+                D[2,4] = var(7); // [ var(4) , var(2) ]
+                D[2,11] = var(12); // [ var(11) , var(2) ]
+                D[3,5] = (-1)*var(8); // [ var(5) , var(3) ]
+                D[3,7] = (-1)*var(10); // [ var(7) , var(3) ]
+                D[3,9] = (-1)*var(11); // [ var(9) , var(3) ]
+                D[4,5] = (-1)*var(9); // [ var(5) , var(4) ]
+                D[4,6] = (-1)*var(10); // [ var(6) , var(4) ]
+                D[4,8] = (-1)*var(11); // [ var(8) , var(4) ]
+                D[5,10] = (-1)*var(12); // [ var(10) , var(5) ]
+                D[6,9] = (-1)*var(12); // [ var(9) , var(6) ]
+                D[7,8] = (-1)*var(12); // [ var(8) , var(7) ]
+        // Y(i) * Y(j):
+                D[13,14] = (-1)*var(17); // [ var(14) , var(13) ]
+                D[13,18] = (-1)*var(20); // [ var(18) , var(13) ]
+                D[13,19] = (-1)*var(21); // [ var(19) , var(13) ]
+                D[13,22] = (-1)*var(23); // [ var(22) , var(13) ]
+                D[14,15] = (-1)*var(18); // [ var(15) , var(14) ]
+                D[14,16] = (-1)*var(19); // [ var(16) , var(14) ]
+                D[14,23] = (-1)*var(24); // [ var(23) , var(14) ]
+                D[15,17] = var(20); // [ var(17) , var(15) ]
+                D[15,19] = var(22); // [ var(19) , var(15) ]
+                D[15,21] = var(23); // [ var(21) , var(15) ]
+                D[16,17] = var(21); // [ var(17) , var(16) ]
+                D[16,18] = var(22); // [ var(18) , var(16) ]
+                D[16,20] = var(23); // [ var(20) , var(16) ]
+                D[17,22] = var(24); // [ var(22) , var(17) ]
+                D[18,21] = var(24); // [ var(21) , var(18) ]
+                D[19,20] = var(24); // [ var(20) , var(19) ]
+   def @@RR=nc_algebra(1,D);
+   return(@@RR);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   def ncAlgebra = makeUso8();
+   ncAlgebra;
+   setring ncAlgebra;
+   // ...  180  noncommutative relations
+}
+////////////////////////////////////////////////////////////////////
+
+// Algebra: so10(Q) has the type: D5, and defined by:
+
+proc makeUso10(list #)
+"USAGE:   makeUso10([p]); p an optional integer (field characteristic)
+RETURN:  a ring, describing U(so_{10})
+NOTE:    You have to activate this ring with the 'setring' command. The presentation of U(so_{10}) is derived from the Chevalley representation of so_{10}, positive resp. negative roots are denoted by x(i) resp. y(i); Cartan elements are denoted by h(i).
+SEE ALSO: makeUsl, makeUso5, makeUsp1, makeUe6, makeUe7, makeUe8, makeUg2, makeUf4
+EXAMPLE: example makeUso10; shows examples
+"
+{
+   int @p = defInt(#);
+
+   ring @@@rrr = @p,(X(1..20),Y(1..20),H(1..5)),dp;
+   int N = nvars(@@@rrr);
+   matrix D[N][N]=0;
+
+        // H(i) * X(j):
+                D[1,41] = (2)*var(1); // [ var(41) , var(1) ]
+                D[2,41] = (-1)*var(2); // [ var(41) , var(2) ]
+                D[6,41] = var(6); // [ var(41) , var(6) ]
+                D[7,41] = (-1)*var(7); // [ var(41) , var(7) ]
+                D[10,41] = var(10); // [ var(41) , var(10) ]
+                D[11,41] = (-1)*var(11); // [ var(41) , var(11) ]
+                D[12,41] = (-1)*var(12); // [ var(41) , var(12) ]
+                D[14,41] = var(14); // [ var(41) , var(14) ]
+                D[15,41] = var(15); // [ var(41) , var(15) ]
+                D[16,41] = (-1)*var(16); // [ var(41) , var(16) ]
+                D[17,41] = var(17); // [ var(41) , var(17) ]
+                D[18,41] = (-1)*var(18); // [ var(41) , var(18) ]
+                D[19,41] = var(19); // [ var(41) , var(19) ]
+                D[1,42] = (-1)*var(1); // [ var(42) , var(1) ]
+                D[2,42] = (2)*var(2); // [ var(42) , var(2) ]
+                D[3,42] = (-1)*var(3); // [ var(42) , var(3) ]
+                D[6,42] = var(6); // [ var(42) , var(6) ]
+                D[7,42] = var(7); // [ var(42) , var(7) ]
+                D[8,42] = (-1)*var(8); // [ var(42) , var(8) ]
+                D[9,42] = (-1)*var(9); // [ var(42) , var(9) ]
+                D[11,42] = var(11); // [ var(42) , var(11) ]
+                D[12,42] = var(12); // [ var(42) , var(12) ]
+                D[13,42] = (-1)*var(13); // [ var(42) , var(13) ]
+                D[16,42] = var(16); // [ var(42) , var(16) ]
+                D[19,42] = (-1)*var(19); // [ var(42) , var(19) ]
+                D[20,42] = var(20); // [ var(42) , var(20) ]
+                D[2,43] = (-1)*var(2); // [ var(43) , var(2) ]
+                D[3,43] = (2)*var(3); // [ var(43) , var(3) ]
+                D[4,43] = (-1)*var(4); // [ var(43) , var(4) ]
+                D[5,43] = (-1)*var(5); // [ var(43) , var(5) ]
+                D[6,43] = (-1)*var(6); // [ var(43) , var(6) ]
+                D[7,43] = var(7); // [ var(43) , var(7) ]
+                D[8,43] = var(8); // [ var(43) , var(8) ]
+                D[9,43] = var(9); // [ var(43) , var(9) ]
+                D[10,43] = var(10); // [ var(43) , var(10) ]
+                D[16,43] = (-1)*var(16); // [ var(43) , var(16) ]
+                D[17,43] = (-1)*var(17); // [ var(43) , var(17) ]
+                D[18,43] = var(18); // [ var(43) , var(18) ]
+                D[19,43] = var(19); // [ var(43) , var(19) ]
+                D[3,44] = (-1)*var(3); // [ var(44) , var(3) ]
+                D[4,44] = (2)*var(4); // [ var(44) , var(4) ]
+                D[7,44] = (-1)*var(7); // [ var(44) , var(7) ]
+                D[8,44] = var(8); // [ var(44) , var(8) ]
+                D[9,44] = (-1)*var(9); // [ var(44) , var(9) ]
+                D[10,44] = (-1)*var(10); // [ var(44) , var(10) ]
+                D[11,44] = var(11); // [ var(44) , var(11) ]
+                D[12,44] = (-1)*var(12); // [ var(44) , var(12) ]
+                D[13,44] = var(13); // [ var(44) , var(13) ]
+                D[14,44] = var(14); // [ var(44) , var(14) ]
+                D[15,44] = (-1)*var(15); // [ var(44) , var(15) ]
+                D[16,44] = var(16); // [ var(44) , var(16) ]
+                D[17,44] = var(17); // [ var(44) , var(17) ]
+                D[3,45] = (-1)*var(3); // [ var(45) , var(3) ]
+                D[5,45] = (2)*var(5); // [ var(45) , var(5) ]
+                D[7,45] = (-1)*var(7); // [ var(45) , var(7) ]
+                D[8,45] = (-1)*var(8); // [ var(45) , var(8) ]
+                D[9,45] = var(9); // [ var(45) , var(9) ]
+                D[10,45] = (-1)*var(10); // [ var(45) , var(10) ]
+                D[11,45] = (-1)*var(11); // [ var(45) , var(11) ]
+                D[12,45] = var(12); // [ var(45) , var(12) ]
+                D[13,45] = var(13); // [ var(45) , var(13) ]
+                D[14,45] = (-1)*var(14); // [ var(45) , var(14) ]
+                D[15,45] = var(15); // [ var(45) , var(15) ]
+                D[16,45] = var(16); // [ var(45) , var(16) ]
+                D[17,45] = var(17); // [ var(45) , var(17) ]
+        // H(i) * Y(j):
+                D[21,41] = (-2)*var(21); // [ var(41) , var(21) ]
+                D[22,41] = var(22); // [ var(41) , var(22) ]
+                D[26,41] = (-1)*var(26); // [ var(41) , var(26) ]
+                D[27,41] = var(27); // [ var(41) , var(27) ]
+                D[30,41] = (-1)*var(30); // [ var(41) , var(30) ]
+                D[31,41] = var(31); // [ var(41) , var(31) ]
+                D[32,41] = var(32); // [ var(41) , var(32) ]
+                D[34,41] = (-1)*var(34); // [ var(41) , var(34) ]
+                D[35,41] = (-1)*var(35); // [ var(41) , var(35) ]
+                D[36,41] = var(36); // [ var(41) , var(36) ]
+                D[37,41] = (-1)*var(37); // [ var(41) , var(37) ]
+                D[38,41] = var(38); // [ var(41) , var(38) ]
+                D[39,41] = (-1)*var(39); // [ var(41) , var(39) ]
+                D[21,42] = var(21); // [ var(42) , var(21) ]
+                D[22,42] = (-2)*var(22); // [ var(42) , var(22) ]
+                D[23,42] = var(23); // [ var(42) , var(23) ]
+                D[26,42] = (-1)*var(26); // [ var(42) , var(26) ]
+                D[27,42] = (-1)*var(27); // [ var(42) , var(27) ]
+                D[28,42] = var(28); // [ var(42) , var(28) ]
+                D[29,42] = var(29); // [ var(42) , var(29) ]
+                D[31,42] = (-1)*var(31); // [ var(42) , var(31) ]
+                D[32,42] = (-1)*var(32); // [ var(42) , var(32) ]
+                D[33,42] = var(33); // [ var(42) , var(33) ]
+                D[36,42] = (-1)*var(36); // [ var(42) , var(36) ]
+                D[39,42] = var(39); // [ var(42) , var(39) ]
+                D[40,42] = (-1)*var(40); // [ var(42) , var(40) ]
+                D[22,43] = var(22); // [ var(43) , var(22) ]
+                D[23,43] = (-2)*var(23); // [ var(43) , var(23) ]
+                D[24,43] = var(24); // [ var(43) , var(24) ]
+                D[25,43] = var(25); // [ var(43) , var(25) ]
+                D[26,43] = var(26); // [ var(43) , var(26) ]
+                D[27,43] = (-1)*var(27); // [ var(43) , var(27) ]
+                D[28,43] = (-1)*var(28); // [ var(43) , var(28) ]
+                D[29,43] = (-1)*var(29); // [ var(43) , var(29) ]
+                D[30,43] = (-1)*var(30); // [ var(43) , var(30) ]
+                D[36,43] = var(36); // [ var(43) , var(36) ]
+                D[37,43] = var(37); // [ var(43) , var(37) ]
+                D[38,43] = (-1)*var(38); // [ var(43) , var(38) ]
+                D[39,43] = (-1)*var(39); // [ var(43) , var(39) ]
+                D[23,44] = var(23); // [ var(44) , var(23) ]
+                D[24,44] = (-2)*var(24); // [ var(44) , var(24) ]
+                D[27,44] = var(27); // [ var(44) , var(27) ]
+                D[28,44] = (-1)*var(28); // [ var(44) , var(28) ]
+                D[29,44] = var(29); // [ var(44) , var(29) ]
+                D[30,44] = var(30); // [ var(44) , var(30) ]
+                D[31,44] = (-1)*var(31); // [ var(44) , var(31) ]
+                D[32,44] = var(32); // [ var(44) , var(32) ]
+                D[33,44] = (-1)*var(33); // [ var(44) , var(33) ]
+                D[34,44] = (-1)*var(34); // [ var(44) , var(34) ]
+                D[35,44] = var(35); // [ var(44) , var(35) ]
+                D[36,44] = (-1)*var(36); // [ var(44) , var(36) ]
+                D[37,44] = (-1)*var(37); // [ var(44) , var(37) ]
+                D[23,45] = var(23); // [ var(45) , var(23) ]
+                D[25,45] = (-2)*var(25); // [ var(45) , var(25) ]
+                D[27,45] = var(27); // [ var(45) , var(27) ]
+                D[28,45] = var(28); // [ var(45) , var(28) ]
+                D[29,45] = (-1)*var(29); // [ var(45) , var(29) ]
+                D[30,45] = var(30); // [ var(45) , var(30) ]
+                D[31,45] = var(31); // [ var(45) , var(31) ]
+                D[32,45] = (-1)*var(32); // [ var(45) , var(32) ]
+                D[33,45] = (-1)*var(33); // [ var(45) , var(33) ]
+                D[34,45] = var(34); // [ var(45) , var(34) ]
+                D[35,45] = (-1)*var(35); // [ var(45) , var(35) ]
+                D[36,45] = (-1)*var(36); // [ var(45) , var(36) ]
+                D[37,45] = (-1)*var(37); // [ var(45) , var(37) ]
+        // Y(i) * X(j):
+                D[1,21] = (-1)*var(41); // [ var(21) , var(1) ]
+                D[6,21] = (-1)*var(2); // [ var(21) , var(6) ]
+                D[10,21] = (-1)*var(7); // [ var(21) , var(10) ]
+                D[14,21] = (-1)*var(11); // [ var(21) , var(14) ]
+                D[15,21] = (-1)*var(12); // [ var(21) , var(15) ]
+                D[17,21] = (-1)*var(16); // [ var(21) , var(17) ]
+                D[19,21] = (-1)*var(18); // [ var(21) , var(19) ]
+                D[2,22] = (-1)*var(42); // [ var(22) , var(2) ]
+                D[6,22] = var(1); // [ var(22) , var(6) ]
+                D[7,22] = (-1)*var(3); // [ var(22) , var(7) ]
+                D[11,22] = (-1)*var(8); // [ var(22) , var(11) ]
+                D[12,22] = (-1)*var(9); // [ var(22) , var(12) ]
+                D[16,22] = (-1)*var(13); // [ var(22) , var(16) ]
+                D[20,22] = (-1)*var(19); // [ var(22) , var(20) ]
+                D[3,23] = (-1)*var(43); // [ var(23) , var(3) ]
+                D[7,23] = var(2); // [ var(23) , var(7) ]
+                D[8,23] = (-1)*var(4); // [ var(23) , var(8) ]
+                D[9,23] = (-1)*var(5); // [ var(23) , var(9) ]
+                D[10,23] = var(6); // [ var(23) , var(10) ]
+                D[18,23] = (-1)*var(16); // [ var(23) , var(18) ]
+                D[19,23] = (-1)*var(17); // [ var(23) , var(19) ]
+                D[4,24] = (-1)*var(44); // [ var(24) , var(4) ]
+                D[8,24] = var(3); // [ var(24) , var(8) ]
+                D[11,24] = var(7); // [ var(24) , var(11) ]
+                D[13,24] = var(9); // [ var(24) , var(13) ]
+                D[14,24] = var(10); // [ var(24) , var(14) ]
+                D[16,24] = var(12); // [ var(24) , var(16) ]
+                D[17,24] = var(15); // [ var(24) , var(17) ]
+                D[5,25] = (-1)*var(45); // [ var(25) , var(5) ]
+                D[9,25] = var(3); // [ var(25) , var(9) ]
+                D[12,25] = var(7); // [ var(25) , var(12) ]
+                D[13,25] = var(8); // [ var(25) , var(13) ]
+                D[15,25] = var(10); // [ var(25) , var(15) ]
+                D[16,25] = var(11); // [ var(25) , var(16) ]
+                D[17,25] = var(14); // [ var(25) , var(17) ]
+                D[1,26] = (-1)*var(22); // [ var(26) , var(1) ]
+                D[2,26] = var(21); // [ var(26) , var(2) ]
+                D[6,26] = (-1)*var(41)+(-1)*var(42); // [ var(26) , var(6) ]
+                D[10,26] = (-1)*var(3); // [ var(26) , var(10) ]
+                D[14,26] = (-1)*var(8); // [ var(26) , var(14) ]
+                D[15,26] = (-1)*var(9); // [ var(26) , var(15) ]
+                D[17,26] = (-1)*var(13); // [ var(26) , var(17) ]
+                D[20,26] = var(18); // [ var(26) , var(20) ]
+                D[2,27] = (-1)*var(23); // [ var(27) , var(2) ]
+                D[3,27] = var(22); // [ var(27) , var(3) ]
+                D[7,27] = (-1)*var(42)+(-1)*var(43); // [ var(27) , var(7) ]
+                D[10,27] = var(1); // [ var(27) , var(10) ]
+                D[11,27] = (-1)*var(4); // [ var(27) , var(11) ]
+                D[12,27] = (-1)*var(5); // [ var(27) , var(12) ]
+                D[18,27] = var(13); // [ var(27) , var(18) ]
+                D[20,27] = (-1)*var(17); // [ var(27) , var(20) ]
+                D[3,28] = (-1)*var(24); // [ var(28) , var(3) ]
+                D[4,28] = var(23); // [ var(28) , var(4) ]
+                D[8,28] = (-1)*var(43)+(-1)*var(44); // [ var(28) , var(8) ]
+                D[11,28] = var(2); // [ var(28) , var(11) ]
+                D[13,28] = (-1)*var(5); // [ var(28) , var(13) ]
+                D[14,28] = var(6); // [ var(28) , var(14) ]
+                D[18,28] = var(12); // [ var(28) , var(18) ]
+                D[19,28] = var(15); // [ var(28) , var(19) ]
+                D[3,29] = (-1)*var(25); // [ var(29) , var(3) ]
+                D[5,29] = var(23); // [ var(29) , var(5) ]
+                D[9,29] = (-1)*var(43)+(-1)*var(45); // [ var(29) , var(9) ]
+                D[12,29] = var(2); // [ var(29) , var(12) ]
+                D[13,29] = (-1)*var(4); // [ var(29) , var(13) ]
+                D[15,29] = var(6); // [ var(29) , var(15) ]
+                D[18,29] = var(11); // [ var(29) , var(18) ]
+                D[19,29] = var(14); // [ var(29) , var(19) ]
+                D[1,30] = (-1)*var(27); // [ var(30) , var(1) ]
+                D[3,30] = var(26); // [ var(30) , var(3) ]
+                D[6,30] = (-1)*var(23); // [ var(30) , var(6) ]
+                D[7,30] = var(21); // [ var(30) , var(7) ]
+                D[10,30] = (-1)*var(41)+(-1)*var(42)+(-1)*var(43); // [ var(30) , var(10) ]
+                D[14,30] = (-1)*var(4); // [ var(30) , var(14) ]
+                D[15,30] = (-1)*var(5); // [ var(30) , var(15) ]
+                D[19,30] = var(13); // [ var(30) , var(19) ]
+                D[20,30] = var(16); // [ var(30) , var(20) ]
+                D[2,31] = (-1)*var(28); // [ var(31) , var(2) ]
+                D[4,31] = var(27); // [ var(31) , var(4) ]
+                D[7,31] = (-1)*var(24); // [ var(31) , var(7) ]
+                D[8,31] = var(22); // [ var(31) , var(8) ]
+                D[11,31] = (-1)*var(42)+(-1)*var(43)+(-1)*var(44); // [ var(31) , var(11) ]
+                D[14,31] = var(1); // [ var(31) , var(14) ]
+                D[16,31] = (-1)*var(5); // [ var(31) , var(16) ]
+                D[18,31] = (-1)*var(9); // [ var(31) , var(18) ]
+                D[20,31] = var(15); // [ var(31) , var(20) ]
+                D[2,32] = (-1)*var(29); // [ var(32) , var(2) ]
+                D[5,32] = var(27); // [ var(32) , var(5) ]
+                D[7,32] = (-1)*var(25); // [ var(32) , var(7) ]
+                D[9,32] = var(22); // [ var(32) , var(9) ]
+                D[12,32] = (-1)*var(42)+(-1)*var(43)+(-1)*var(45); // [ var(32) , var(12) ]
+                D[15,32] = var(1); // [ var(32) , var(15) ]
+                D[16,32] = (-1)*var(4); // [ var(32) , var(16) ]
+                D[18,32] = (-1)*var(8); // [ var(32) , var(18) ]
+                D[20,32] = var(14); // [ var(32) , var(20) ]
+                D[4,33] = var(29); // [ var(33) , var(4) ]
+                D[5,33] = var(28); // [ var(33) , var(5) ]
+                D[8,33] = (-1)*var(25); // [ var(33) , var(8) ]
+                D[9,33] = (-1)*var(24); // [ var(33) , var(9) ]
+                D[13,33] = (-1)*var(43)+(-1)*var(44)+(-1)*var(45); // [ var(33) , var(13) ]
+                D[16,33] = var(2); // [ var(33) , var(16) ]
+                D[17,33] = var(6); // [ var(33) , var(17) ]
+                D[18,33] = (-1)*var(7); // [ var(33) , var(18) ]
+                D[19,33] = (-1)*var(10); // [ var(33) , var(19) ]
+                D[1,34] = (-1)*var(31); // [ var(34) , var(1) ]
+                D[4,34] = var(30); // [ var(34) , var(4) ]
+                D[6,34] = (-1)*var(28); // [ var(34) , var(6) ]
+                D[8,34] = var(26); // [ var(34) , var(8) ]
+                D[10,34] = (-1)*var(24); // [ var(34) , var(10) ]
+                D[11,34] = var(21); // [ var(34) , var(11) ]
+                D[14,34] = (-1)*var(41)+(-1)*var(42)+(-1)*var(43)+(-1)*var(44); // [ var(34) , var(14) ]
+                D[17,34] = (-1)*var(5); // [ var(34) , var(17) ]
+                D[19,34] = (-1)*var(9); // [ var(34) , var(19) ]
+                D[20,34] = (-1)*var(12); // [ var(34) , var(20) ]
+                D[1,35] = (-1)*var(32); // [ var(35) , var(1) ]
+                D[5,35] = var(30); // [ var(35) , var(5) ]
+                D[6,35] = (-1)*var(29); // [ var(35) , var(6) ]
+                D[9,35] = var(26); // [ var(35) , var(9) ]
+                D[10,35] = (-1)*var(25); // [ var(35) , var(10) ]
+                D[12,35] = var(21); // [ var(35) , var(12) ]
+                D[15,35] = (-1)*var(41)+(-1)*var(42)+(-1)*var(43)+(-1)*var(45); // [ var(35) , var(15) ]
+                D[17,35] = (-1)*var(4); // [ var(35) , var(17) ]
+                D[19,35] = (-1)*var(8); // [ var(35) , var(19) ]
+                D[20,35] = (-1)*var(11); // [ var(35) , var(20) ]
+                D[2,36] = (-1)*var(33); // [ var(36) , var(2) ]
+                D[4,36] = var(32); // [ var(36) , var(4) ]
+                D[5,36] = var(31); // [ var(36) , var(5) ]
+                D[11,36] = (-1)*var(25); // [ var(36) , var(11) ]
+                D[12,36] = (-1)*var(24); // [ var(36) , var(12) ]
+                D[13,36] = var(22); // [ var(36) , var(13) ]
+                D[16,36] = (-1)*var(42)+(-1)*var(43)+(-1)*var(44)+(-1)*var(45); // [ var(36) , var(16) ]
+                D[17,36] = var(1); // [ var(36) , var(17) ]
+                D[18,36] = var(3); // [ var(36) , var(18) ]
+                D[20,36] = (-1)*var(10); // [ var(36) , var(20) ]
+                D[1,37] = (-1)*var(36); // [ var(37) , var(1) ]
+                D[4,37] = var(35); // [ var(37) , var(4) ]
+                D[5,37] = var(34); // [ var(37) , var(5) ]
+                D[6,37] = (-1)*var(33); // [ var(37) , var(6) ]
+                D[13,37] = var(26); // [ var(37) , var(13) ]
+                D[14,37] = (-1)*var(25); // [ var(37) , var(14) ]
+                D[15,37] = (-1)*var(24); // [ var(37) , var(15) ]
+                D[16,37] = var(21); // [ var(37) , var(16) ]
+                D[17,37] = (-1)*var(41)+(-1)*var(42)+(-1)*var(43)+(-1)*var(44)+(-1)*var(45); // [ var(37) , var(17) ]
+                D[19,37] = var(3); // [ var(37) , var(19) ]
+                D[20,37] = var(7); // [ var(37) , var(20) ]
+                D[3,38] = (-1)*var(36); // [ var(38) , var(3) ]
+                D[7,38] = var(33); // [ var(38) , var(7) ]
+                D[8,38] = var(32); // [ var(38) , var(8) ]
+                D[9,38] = var(31); // [ var(38) , var(9) ]
+                D[11,38] = (-1)*var(29); // [ var(38) , var(11) ]
+                D[12,38] = (-1)*var(28); // [ var(38) , var(12) ]
+                D[13,38] = (-1)*var(27); // [ var(38) , var(13) ]
+                D[16,38] = var(23); // [ var(38) , var(16) ]
+                D[18,38] = (-1)*var(42)+(-2)*var(43)+(-1)*var(44)+(-1)*var(45); // [ var(38) , var(18) ]
+                D[19,38] = var(1); // [ var(38) , var(19) ]
+                D[20,38] = (-1)*var(6); // [ var(38) , var(20) ]
+                D[1,39] = (-1)*var(38); // [ var(39) , var(1) ]
+                D[3,39] = (-1)*var(37); // [ var(39) , var(3) ]
+                D[8,39] = var(35); // [ var(39) , var(8) ]
+                D[9,39] = var(34); // [ var(39) , var(9) ]
+                D[10,39] = var(33); // [ var(39) , var(10) ]
+                D[13,39] = (-1)*var(30); // [ var(39) , var(13) ]
+                D[14,39] = (-1)*var(29); // [ var(39) , var(14) ]
+                D[15,39] = (-1)*var(28); // [ var(39) , var(15) ]
+                D[17,39] = var(23); // [ var(39) , var(17) ]
+                D[18,39] = var(21); // [ var(39) , var(18) ]
+                D[19,39] = (-1)*var(41)+(-1)*var(42)+(-2)*var(43)+(-1)*var(44)+(-1)*var(45); // [ var(39) , var(19) ]
+                D[20,39] = var(2); // [ var(39) , var(20) ]
+                D[2,40] = (-1)*var(39); // [ var(40) , var(2) ]
+                D[6,40] = var(38); // [ var(40) , var(6) ]
+                D[7,40] = (-1)*var(37); // [ var(40) , var(7) ]
+                D[10,40] = var(36); // [ var(40) , var(10) ]
+                D[11,40] = var(35); // [ var(40) , var(11) ]
+                D[12,40] = var(34); // [ var(40) , var(12) ]
+                D[14,40] = (-1)*var(32); // [ var(40) , var(14) ]
+                D[15,40] = (-1)*var(31); // [ var(40) , var(15) ]
+                D[16,40] = (-1)*var(30); // [ var(40) , var(16) ]
+                D[17,40] = var(27); // [ var(40) , var(17) ]
+                D[18,40] = (-1)*var(26); // [ var(40) , var(18) ]
+                D[19,40] = var(22); // [ var(40) , var(19) ]
+                D[20,40] = (-1)*var(41)+(-2)*var(42)+(-2)*var(43)+(-1)*var(44)+(-1)*var(45); // [ var(40) , var(20) ]
+        // X(i) * X(j):
+                D[1,2] = var(6); // [ var(2) , var(1) ]
+                D[1,7] = var(10); // [ var(7) , var(1) ]
+                D[1,11] = var(14); // [ var(11) , var(1) ]
+                D[1,12] = var(15); // [ var(12) , var(1) ]
+                D[1,16] = var(17); // [ var(16) , var(1) ]
+                D[1,18] = var(19); // [ var(18) , var(1) ]
+                D[2,3] = var(7); // [ var(3) , var(2) ]
+                D[2,8] = var(11); // [ var(8) , var(2) ]
+                D[2,9] = var(12); // [ var(9) , var(2) ]
+                D[2,13] = var(16); // [ var(13) , var(2) ]
+                D[2,19] = var(20); // [ var(19) , var(2) ]
+                D[3,4] = var(8); // [ var(4) , var(3) ]
+                D[3,5] = var(9); // [ var(5) , var(3) ]
+                D[3,6] = (-1)*var(10); // [ var(6) , var(3) ]
+                D[3,16] = var(18); // [ var(16) , var(3) ]
+                D[3,17] = var(19); // [ var(17) , var(3) ]
+                D[4,7] = (-1)*var(11); // [ var(7) , var(4) ]
+                D[4,9] = (-1)*var(13); // [ var(9) , var(4) ]
+                D[4,10] = (-1)*var(14); // [ var(10) , var(4) ]
+                D[4,12] = (-1)*var(16); // [ var(12) , var(4) ]
+                D[4,15] = (-1)*var(17); // [ var(15) , var(4) ]
+                D[5,7] = (-1)*var(12); // [ var(7) , var(5) ]
+                D[5,8] = (-1)*var(13); // [ var(8) , var(5) ]
+                D[5,10] = (-1)*var(15); // [ var(10) , var(5) ]
+                D[5,11] = (-1)*var(16); // [ var(11) , var(5) ]
+                D[5,14] = (-1)*var(17); // [ var(14) , var(5) ]
+                D[6,8] = var(14); // [ var(8) , var(6) ]
+                D[6,9] = var(15); // [ var(9) , var(6) ]
+                D[6,13] = var(17); // [ var(13) , var(6) ]
+                D[6,18] = (-1)*var(20); // [ var(18) , var(6) ]
+                D[7,13] = (-1)*var(18); // [ var(13) , var(7) ]
+                D[7,17] = var(20); // [ var(17) , var(7) ]
+                D[8,12] = (-1)*var(18); // [ var(12) , var(8) ]
+                D[8,15] = (-1)*var(19); // [ var(15) , var(8) ]
+                D[9,11] = (-1)*var(18); // [ var(11) , var(9) ]
+                D[9,14] = (-1)*var(19); // [ var(14) , var(9) ]
+                D[10,13] = (-1)*var(19); // [ var(13) , var(10) ]
+                D[10,16] = (-1)*var(20); // [ var(16) , var(10) ]
+                D[11,15] = (-1)*var(20); // [ var(15) , var(11) ]
+                D[12,14] = (-1)*var(20); // [ var(14) , var(12) ]
+        // Y(i) * Y(j):
+                D[21,22] = (-1)*var(26); // [ var(22) , var(21) ]
+                D[21,27] = (-1)*var(30); // [ var(27) , var(21) ]
+                D[21,31] = (-1)*var(34); // [ var(31) , var(21) ]
+                D[21,32] = (-1)*var(35); // [ var(32) , var(21) ]
+                D[21,36] = (-1)*var(37); // [ var(36) , var(21) ]
+                D[21,38] = (-1)*var(39); // [ var(38) , var(21) ]
+                D[22,23] = (-1)*var(27); // [ var(23) , var(22) ]
+                D[22,28] = (-1)*var(31); // [ var(28) , var(22) ]
+                D[22,29] = (-1)*var(32); // [ var(29) , var(22) ]
+                D[22,33] = (-1)*var(36); // [ var(33) , var(22) ]
+                D[22,39] = (-1)*var(40); // [ var(39) , var(22) ]
+                D[23,24] = (-1)*var(28); // [ var(24) , var(23) ]
+                D[23,25] = (-1)*var(29); // [ var(25) , var(23) ]
+                D[23,26] = var(30); // [ var(26) , var(23) ]
+                D[23,36] = (-1)*var(38); // [ var(36) , var(23) ]
+                D[23,37] = (-1)*var(39); // [ var(37) , var(23) ]
+                D[24,27] = var(31); // [ var(27) , var(24) ]
+                D[24,29] = var(33); // [ var(29) , var(24) ]
+                D[24,30] = var(34); // [ var(30) , var(24) ]
+                D[24,32] = var(36); // [ var(32) , var(24) ]
+                D[24,35] = var(37); // [ var(35) , var(24) ]
+                D[25,27] = var(32); // [ var(27) , var(25) ]
+                D[25,28] = var(33); // [ var(28) , var(25) ]
+                D[25,30] = var(35); // [ var(30) , var(25) ]
+                D[25,31] = var(36); // [ var(31) , var(25) ]
+                D[25,34] = var(37); // [ var(34) , var(25) ]
+                D[26,28] = (-1)*var(34); // [ var(28) , var(26) ]
+                D[26,29] = (-1)*var(35); // [ var(29) , var(26) ]
+                D[26,33] = (-1)*var(37); // [ var(33) , var(26) ]
+                D[26,38] = var(40); // [ var(38) , var(26) ]
+                D[27,33] = var(38); // [ var(33) , var(27) ]
+                D[27,37] = (-1)*var(40); // [ var(37) , var(27) ]
+                D[28,32] = var(38); // [ var(32) , var(28) ]
+                D[28,35] = var(39); // [ var(35) , var(28) ]
+                D[29,31] = var(38); // [ var(31) , var(29) ]
+                D[29,34] = var(39); // [ var(34) , var(29) ]
+                D[30,33] = var(39); // [ var(33) , var(30) ]
+                D[30,36] = var(40); // [ var(36) , var(30) ]
+                D[31,35] = var(40); // [ var(35) , var(31) ]
+                D[32,34] = var(40); // [ var(34) , var(32) ]
+   def @@RR=nc_algebra(1,D);
+   return(@@RR);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   def ncAlgebra = makeUso10();
+   ncAlgebra;
+   setring ncAlgebra;
+   // ...  390  noncommutative relations
+}
+////////////////////////////////////////////////////////////////////
+
+// Algebra: so12(Q) has the type: D6, and defined by:
+
+proc makeUso12(list #)
+"USAGE:   makeUso12([p]); p an optional integer (field characteristic)
+RETURN:  a ring, describing U(so_{12})
+NOTE:    You have to activate this ring with the 'setring' command. The presentation of U(so_{12}) is derived from the Chevalley representation of so_{12}, positive resp. negative roots are denoted by x(i) resp. y(i); Cartan elements are denoted by h(i).
+SEE ALSO: makeUsl, makeUso5, makeUso5, makeUsp1, makeUe6, makeUe7, makeUe8, makeUg2, makeUf4
+EXAMPLE: example makeUso12; shows examples
+"
+{
+   int @p = defInt(#);
+
+   ring @@@rrr = @p,(X(1..30),Y(1..30),H(1..6)),dp;
+   int N = nvars(@@@rrr);
+   matrix D[N][N]=0;
+
+        // H(i) * X(j):
+                D[1,61] = (2)*var(1); // [ var(61) , var(1) ]
+                D[2,61] = (-1)*var(2); // [ var(61) , var(2) ]
+                D[7,61] = var(7); // [ var(61) , var(7) ]
+                D[8,61] = (-1)*var(8); // [ var(61) , var(8) ]
+                D[12,61] = var(12); // [ var(61) , var(12) ]
+                D[13,61] = (-1)*var(13); // [ var(61) , var(13) ]
+                D[17,61] = var(17); // [ var(61) , var(17) ]
+                D[18,61] = (-1)*var(18); // [ var(61) , var(18) ]
+                D[19,61] = (-1)*var(19); // [ var(61) , var(19) ]
+                D[21,61] = var(21); // [ var(61) , var(21) ]
+                D[22,61] = var(22); // [ var(61) , var(22) ]
+                D[23,61] = (-1)*var(23); // [ var(61) , var(23) ]
+                D[25,61] = var(25); // [ var(61) , var(25) ]
+                D[26,61] = (-1)*var(26); // [ var(61) , var(26) ]
+                D[27,61] = var(27); // [ var(61) , var(27) ]
+                D[28,61] = (-1)*var(28); // [ var(61) , var(28) ]
+                D[29,61] = var(29); // [ var(61) , var(29) ]
+                D[1,62] = (-1)*var(1); // [ var(62) , var(1) ]
+                D[2,62] = (2)*var(2); // [ var(62) , var(2) ]
+                D[3,62] = (-1)*var(3); // [ var(62) , var(3) ]
+                D[7,62] = var(7); // [ var(62) , var(7) ]
+                D[8,62] = var(8); // [ var(62) , var(8) ]
+                D[9,62] = (-1)*var(9); // [ var(62) , var(9) ]
+                D[13,62] = var(13); // [ var(62) , var(13) ]
+                D[14,62] = (-1)*var(14); // [ var(62) , var(14) ]
+                D[15,62] = (-1)*var(15); // [ var(62) , var(15) ]
+                D[18,62] = var(18); // [ var(62) , var(18) ]
+                D[19,62] = var(19); // [ var(62) , var(19) ]
+                D[20,62] = (-1)*var(20); // [ var(62) , var(20) ]
+                D[23,62] = var(23); // [ var(62) , var(23) ]
+                D[24,62] = (-1)*var(24); // [ var(62) , var(24) ]
+                D[26,62] = var(26); // [ var(62) , var(26) ]
+                D[29,62] = (-1)*var(29); // [ var(62) , var(29) ]
+                D[30,62] = var(30); // [ var(62) , var(30) ]
+                D[2,63] = (-1)*var(2); // [ var(63) , var(2) ]
+                D[3,63] = (2)*var(3); // [ var(63) , var(3) ]
+                D[4,63] = (-1)*var(4); // [ var(63) , var(4) ]
+                D[7,63] = (-1)*var(7); // [ var(63) , var(7) ]
+                D[8,63] = var(8); // [ var(63) , var(8) ]
+                D[9,63] = var(9); // [ var(63) , var(9) ]
+                D[10,63] = (-1)*var(10); // [ var(63) , var(10) ]
+                D[11,63] = (-1)*var(11); // [ var(63) , var(11) ]
+                D[12,63] = var(12); // [ var(63) , var(12) ]
+                D[14,63] = var(14); // [ var(63) , var(14) ]
+                D[15,63] = var(15); // [ var(63) , var(15) ]
+                D[16,63] = (-1)*var(16); // [ var(63) , var(16) ]
+                D[20,63] = var(20); // [ var(63) , var(20) ]
+                D[26,63] = (-1)*var(26); // [ var(63) , var(26) ]
+                D[27,63] = (-1)*var(27); // [ var(63) , var(27) ]
+                D[28,63] = var(28); // [ var(63) , var(28) ]
+                D[29,63] = var(29); // [ var(63) , var(29) ]
+                D[3,64] = (-1)*var(3); // [ var(64) , var(3) ]
+                D[4,64] = (2)*var(4); // [ var(64) , var(4) ]
+                D[5,64] = (-1)*var(5); // [ var(64) , var(5) ]
+                D[6,64] = (-1)*var(6); // [ var(64) , var(6) ]
+                D[8,64] = (-1)*var(8); // [ var(64) , var(8) ]
+                D[9,64] = var(9); // [ var(64) , var(9) ]
+                D[10,64] = var(10); // [ var(64) , var(10) ]
+                D[11,64] = var(11); // [ var(64) , var(11) ]
+                D[12,64] = (-1)*var(12); // [ var(64) , var(12) ]
+                D[13,64] = var(13); // [ var(64) , var(13) ]
+                D[17,64] = var(17); // [ var(64) , var(17) ]
+                D[20,64] = (-1)*var(20); // [ var(64) , var(20) ]
+                D[23,64] = (-1)*var(23); // [ var(64) , var(23) ]
+                D[24,64] = var(24); // [ var(64) , var(24) ]
+                D[25,64] = (-1)*var(25); // [ var(64) , var(25) ]
+                D[26,64] = var(26); // [ var(64) , var(26) ]
+                D[27,64] = var(27); // [ var(64) , var(27) ]
+                D[4,65] = (-1)*var(4); // [ var(65) , var(4) ]
+                D[5,65] = (2)*var(5); // [ var(65) , var(5) ]
+                D[9,65] = (-1)*var(9); // [ var(65) , var(9) ]
+                D[10,65] = var(10); // [ var(65) , var(10) ]
+                D[11,65] = (-1)*var(11); // [ var(65) , var(11) ]
+                D[13,65] = (-1)*var(13); // [ var(65) , var(13) ]
+                D[14,65] = var(14); // [ var(65) , var(14) ]
+                D[15,65] = (-1)*var(15); // [ var(65) , var(15) ]
+                D[16,65] = var(16); // [ var(65) , var(16) ]
+                D[17,65] = (-1)*var(17); // [ var(65) , var(17) ]
+                D[18,65] = var(18); // [ var(65) , var(18) ]
+                D[19,65] = (-1)*var(19); // [ var(65) , var(19) ]
+                D[20,65] = var(20); // [ var(65) , var(20) ]
+                D[21,65] = var(21); // [ var(65) , var(21) ]
+                D[22,65] = (-1)*var(22); // [ var(65) , var(22) ]
+                D[23,65] = var(23); // [ var(65) , var(23) ]
+                D[25,65] = var(25); // [ var(65) , var(25) ]
+                D[4,66] = (-1)*var(4); // [ var(66) , var(4) ]
+                D[6,66] = (2)*var(6); // [ var(66) , var(6) ]
+                D[9,66] = (-1)*var(9); // [ var(66) , var(9) ]
+                D[10,66] = (-1)*var(10); // [ var(66) , var(10) ]
+                D[11,66] = var(11); // [ var(66) , var(11) ]
+                D[13,66] = (-1)*var(13); // [ var(66) , var(13) ]
+                D[14,66] = (-1)*var(14); // [ var(66) , var(14) ]
+                D[15,66] = var(15); // [ var(66) , var(15) ]
+                D[16,66] = var(16); // [ var(66) , var(16) ]
+                D[17,66] = (-1)*var(17); // [ var(66) , var(17) ]
+                D[18,66] = (-1)*var(18); // [ var(66) , var(18) ]
+                D[19,66] = var(19); // [ var(66) , var(19) ]
+                D[20,66] = var(20); // [ var(66) , var(20) ]
+                D[21,66] = (-1)*var(21); // [ var(66) , var(21) ]
+                D[22,66] = var(22); // [ var(66) , var(22) ]
+                D[23,66] = var(23); // [ var(66) , var(23) ]
+                D[25,66] = var(25); // [ var(66) , var(25) ]
+        // H(i) * Y(j):
+                D[31,61] = (-2)*var(31); // [ var(61) , var(31) ]
+                D[32,61] = var(32); // [ var(61) , var(32) ]
+                D[37,61] = (-1)*var(37); // [ var(61) , var(37) ]
+                D[38,61] = var(38); // [ var(61) , var(38) ]
+                D[42,61] = (-1)*var(42); // [ var(61) , var(42) ]
+                D[43,61] = var(43); // [ var(61) , var(43) ]
+                D[47,61] = (-1)*var(47); // [ var(61) , var(47) ]
+                D[48,61] = var(48); // [ var(61) , var(48) ]
+                D[49,61] = var(49); // [ var(61) , var(49) ]
+                D[51,61] = (-1)*var(51); // [ var(61) , var(51) ]
+                D[52,61] = (-1)*var(52); // [ var(61) , var(52) ]
+                D[53,61] = var(53); // [ var(61) , var(53) ]
+                D[55,61] = (-1)*var(55); // [ var(61) , var(55) ]
+                D[56,61] = var(56); // [ var(61) , var(56) ]
+                D[57,61] = (-1)*var(57); // [ var(61) , var(57) ]
+                D[58,61] = var(58); // [ var(61) , var(58) ]
+                D[59,61] = (-1)*var(59); // [ var(61) , var(59) ]
+                D[31,62] = var(31); // [ var(62) , var(31) ]
+                D[32,62] = (-2)*var(32); // [ var(62) , var(32) ]
+                D[33,62] = var(33); // [ var(62) , var(33) ]
+                D[37,62] = (-1)*var(37); // [ var(62) , var(37) ]
+                D[38,62] = (-1)*var(38); // [ var(62) , var(38) ]
+                D[39,62] = var(39); // [ var(62) , var(39) ]
+                D[43,62] = (-1)*var(43); // [ var(62) , var(43) ]
+                D[44,62] = var(44); // [ var(62) , var(44) ]
+                D[45,62] = var(45); // [ var(62) , var(45) ]
+                D[48,62] = (-1)*var(48); // [ var(62) , var(48) ]
+                D[49,62] = (-1)*var(49); // [ var(62) , var(49) ]
+                D[50,62] = var(50); // [ var(62) , var(50) ]
+                D[53,62] = (-1)*var(53); // [ var(62) , var(53) ]
+                D[54,62] = var(54); // [ var(62) , var(54) ]
+                D[56,62] = (-1)*var(56); // [ var(62) , var(56) ]
+                D[59,62] = var(59); // [ var(62) , var(59) ]
+                D[60,62] = (-1)*var(60); // [ var(62) , var(60) ]
+                D[32,63] = var(32); // [ var(63) , var(32) ]
+                D[33,63] = (-2)*var(33); // [ var(63) , var(33) ]
+                D[34,63] = var(34); // [ var(63) , var(34) ]
+                D[37,63] = var(37); // [ var(63) , var(37) ]
+                D[38,63] = (-1)*var(38); // [ var(63) , var(38) ]
+                D[39,63] = (-1)*var(39); // [ var(63) , var(39) ]
+                D[40,63] = var(40); // [ var(63) , var(40) ]
+                D[41,63] = var(41); // [ var(63) , var(41) ]
+                D[42,63] = (-1)*var(42); // [ var(63) , var(42) ]
+                D[44,63] = (-1)*var(44); // [ var(63) , var(44) ]
+                D[45,63] = (-1)*var(45); // [ var(63) , var(45) ]
+                D[46,63] = var(46); // [ var(63) , var(46) ]
+                D[50,63] = (-1)*var(50); // [ var(63) , var(50) ]
+                D[56,63] = var(56); // [ var(63) , var(56) ]
+                D[57,63] = var(57); // [ var(63) , var(57) ]
+                D[58,63] = (-1)*var(58); // [ var(63) , var(58) ]
+                D[59,63] = (-1)*var(59); // [ var(63) , var(59) ]
+                D[33,64] = var(33); // [ var(64) , var(33) ]
+                D[34,64] = (-2)*var(34); // [ var(64) , var(34) ]
+                D[35,64] = var(35); // [ var(64) , var(35) ]
+                D[36,64] = var(36); // [ var(64) , var(36) ]
+                D[38,64] = var(38); // [ var(64) , var(38) ]
+                D[39,64] = (-1)*var(39); // [ var(64) , var(39) ]
+                D[40,64] = (-1)*var(40); // [ var(64) , var(40) ]
+                D[41,64] = (-1)*var(41); // [ var(64) , var(41) ]
+                D[42,64] = var(42); // [ var(64) , var(42) ]
+                D[43,64] = (-1)*var(43); // [ var(64) , var(43) ]
+                D[47,64] = (-1)*var(47); // [ var(64) , var(47) ]
+                D[50,64] = var(50); // [ var(64) , var(50) ]
+                D[53,64] = var(53); // [ var(64) , var(53) ]
+                D[54,64] = (-1)*var(54); // [ var(64) , var(54) ]
+                D[55,64] = var(55); // [ var(64) , var(55) ]
+                D[56,64] = (-1)*var(56); // [ var(64) , var(56) ]
+                D[57,64] = (-1)*var(57); // [ var(64) , var(57) ]
+                D[34,65] = var(34); // [ var(65) , var(34) ]
+                D[35,65] = (-2)*var(35); // [ var(65) , var(35) ]
+                D[39,65] = var(39); // [ var(65) , var(39) ]
+                D[40,65] = (-1)*var(40); // [ var(65) , var(40) ]
+                D[41,65] = var(41); // [ var(65) , var(41) ]
+                D[43,65] = var(43); // [ var(65) , var(43) ]
+                D[44,65] = (-1)*var(44); // [ var(65) , var(44) ]
+                D[45,65] = var(45); // [ var(65) , var(45) ]
+                D[46,65] = (-1)*var(46); // [ var(65) , var(46) ]
+                D[47,65] = var(47); // [ var(65) , var(47) ]
+                D[48,65] = (-1)*var(48); // [ var(65) , var(48) ]
+                D[49,65] = var(49); // [ var(65) , var(49) ]
+                D[50,65] = (-1)*var(50); // [ var(65) , var(50) ]
+                D[51,65] = (-1)*var(51); // [ var(65) , var(51) ]
+                D[52,65] = var(52); // [ var(65) , var(52) ]
+                D[53,65] = (-1)*var(53); // [ var(65) , var(53) ]
+                D[55,65] = (-1)*var(55); // [ var(65) , var(55) ]
+                D[34,66] = var(34); // [ var(66) , var(34) ]
+                D[36,66] = (-2)*var(36); // [ var(66) , var(36) ]
+                D[39,66] = var(39); // [ var(66) , var(39) ]
+                D[40,66] = var(40); // [ var(66) , var(40) ]
+                D[41,66] = (-1)*var(41); // [ var(66) , var(41) ]
+                D[43,66] = var(43); // [ var(66) , var(43) ]
+                D[44,66] = var(44); // [ var(66) , var(44) ]
+                D[45,66] = (-1)*var(45); // [ var(66) , var(45) ]
+                D[46,66] = (-1)*var(46); // [ var(66) , var(46) ]
+                D[47,66] = var(47); // [ var(66) , var(47) ]
+                D[48,66] = var(48); // [ var(66) , var(48) ]
+                D[49,66] = (-1)*var(49); // [ var(66) , var(49) ]
+                D[50,66] = (-1)*var(50); // [ var(66) , var(50) ]
+                D[51,66] = var(51); // [ var(66) , var(51) ]
+                D[52,66] = (-1)*var(52); // [ var(66) , var(52) ]
+                D[53,66] = (-1)*var(53); // [ var(66) , var(53) ]
+                D[55,66] = (-1)*var(55); // [ var(66) , var(55) ]
+        // Y(i) * X(j):
+                D[1,31] = (-1)*var(61); // [ var(31) , var(1) ]
+                D[7,31] = (-1)*var(2); // [ var(31) , var(7) ]
+                D[12,31] = (-1)*var(8); // [ var(31) , var(12) ]
+                D[17,31] = (-1)*var(13); // [ var(31) , var(17) ]
+                D[21,31] = (-1)*var(18); // [ var(31) , var(21) ]
+                D[22,31] = (-1)*var(19); // [ var(31) , var(22) ]
+                D[25,31] = (-1)*var(23); // [ var(31) , var(25) ]
+                D[27,31] = (-1)*var(26); // [ var(31) , var(27) ]
+                D[29,31] = (-1)*var(28); // [ var(31) , var(29) ]
+                D[2,32] = (-1)*var(62); // [ var(32) , var(2) ]
+                D[7,32] = var(1); // [ var(32) , var(7) ]
+                D[8,32] = (-1)*var(3); // [ var(32) , var(8) ]
+                D[13,32] = (-1)*var(9); // [ var(32) , var(13) ]
+                D[18,32] = (-1)*var(14); // [ var(32) , var(18) ]
+                D[19,32] = (-1)*var(15); // [ var(32) , var(19) ]
+                D[23,32] = (-1)*var(20); // [ var(32) , var(23) ]
+                D[26,32] = (-1)*var(24); // [ var(32) , var(26) ]
+                D[30,32] = (-1)*var(29); // [ var(32) , var(30) ]
+                D[3,33] = (-1)*var(63); // [ var(33) , var(3) ]
+                D[8,33] = var(2); // [ var(33) , var(8) ]
+                D[9,33] = (-1)*var(4); // [ var(33) , var(9) ]
+                D[12,33] = var(7); // [ var(33) , var(12) ]
+                D[14,33] = (-1)*var(10); // [ var(33) , var(14) ]
+                D[15,33] = (-1)*var(11); // [ var(33) , var(15) ]
+                D[20,33] = (-1)*var(16); // [ var(33) , var(20) ]
+                D[28,33] = (-1)*var(26); // [ var(33) , var(28) ]
+                D[29,33] = (-1)*var(27); // [ var(33) , var(29) ]
+                D[4,34] = (-1)*var(64); // [ var(34) , var(4) ]
+                D[9,34] = var(3); // [ var(34) , var(9) ]
+                D[10,34] = (-1)*var(5); // [ var(34) , var(10) ]
+                D[11,34] = (-1)*var(6); // [ var(34) , var(11) ]
+                D[13,34] = var(8); // [ var(34) , var(13) ]
+                D[17,34] = var(12); // [ var(34) , var(17) ]
+                D[24,34] = (-1)*var(20); // [ var(34) , var(24) ]
+                D[26,34] = (-1)*var(23); // [ var(34) , var(26) ]
+                D[27,34] = (-1)*var(25); // [ var(34) , var(27) ]
+                D[5,35] = (-1)*var(65); // [ var(35) , var(5) ]
+                D[10,35] = var(4); // [ var(35) , var(10) ]
+                D[14,35] = var(9); // [ var(35) , var(14) ]
+                D[16,35] = var(11); // [ var(35) , var(16) ]
+                D[18,35] = var(13); // [ var(35) , var(18) ]
+                D[20,35] = var(15); // [ var(35) , var(20) ]
+                D[21,35] = var(17); // [ var(35) , var(21) ]
+                D[23,35] = var(19); // [ var(35) , var(23) ]
+                D[25,35] = var(22); // [ var(35) , var(25) ]
+                D[6,36] = (-1)*var(66); // [ var(36) , var(6) ]
+                D[11,36] = var(4); // [ var(36) , var(11) ]
+                D[15,36] = var(9); // [ var(36) , var(15) ]
+                D[16,36] = var(10); // [ var(36) , var(16) ]
+                D[19,36] = var(13); // [ var(36) , var(19) ]
+                D[20,36] = var(14); // [ var(36) , var(20) ]
+                D[22,36] = var(17); // [ var(36) , var(22) ]
+                D[23,36] = var(18); // [ var(36) , var(23) ]
+                D[25,36] = var(21); // [ var(36) , var(25) ]
+                D[1,37] = (-1)*var(32); // [ var(37) , var(1) ]
+                D[2,37] = var(31); // [ var(37) , var(2) ]
+                D[7,37] = (-1)*var(61)+(-1)*var(62); // [ var(37) , var(7) ]
+                D[12,37] = (-1)*var(3); // [ var(37) , var(12) ]
+                D[17,37] = (-1)*var(9); // [ var(37) , var(17) ]
+                D[21,37] = (-1)*var(14); // [ var(37) , var(21) ]
+                D[22,37] = (-1)*var(15); // [ var(37) , var(22) ]
+                D[25,37] = (-1)*var(20); // [ var(37) , var(25) ]
+                D[27,37] = (-1)*var(24); // [ var(37) , var(27) ]
+                D[30,37] = var(28); // [ var(37) , var(30) ]
+                D[2,38] = (-1)*var(33); // [ var(38) , var(2) ]
+                D[3,38] = var(32); // [ var(38) , var(3) ]
+                D[8,38] = (-1)*var(62)+(-1)*var(63); // [ var(38) , var(8) ]
+                D[12,38] = var(1); // [ var(38) , var(12) ]
+                D[13,38] = (-1)*var(4); // [ var(38) , var(13) ]
+                D[18,38] = (-1)*var(10); // [ var(38) , var(18) ]
+                D[19,38] = (-1)*var(11); // [ var(38) , var(19) ]
+                D[23,38] = (-1)*var(16); // [ var(38) , var(23) ]
+                D[28,38] = var(24); // [ var(38) , var(28) ]
+                D[30,38] = (-1)*var(27); // [ var(38) , var(30) ]
+                D[3,39] = (-1)*var(34); // [ var(39) , var(3) ]
+                D[4,39] = var(33); // [ var(39) , var(4) ]
+                D[9,39] = (-1)*var(63)+(-1)*var(64); // [ var(39) , var(9) ]
+                D[13,39] = var(2); // [ var(39) , var(13) ]
+                D[14,39] = (-1)*var(5); // [ var(39) , var(14) ]
+                D[15,39] = (-1)*var(6); // [ var(39) , var(15) ]
+                D[17,39] = var(7); // [ var(39) , var(17) ]
+                D[24,39] = var(16); // [ var(39) , var(24) ]
+                D[28,39] = (-1)*var(23); // [ var(39) , var(28) ]
+                D[29,39] = (-1)*var(25); // [ var(39) , var(29) ]
+                D[4,40] = (-1)*var(35); // [ var(40) , var(4) ]
+                D[5,40] = var(34); // [ var(40) , var(5) ]
+                D[10,40] = (-1)*var(64)+(-1)*var(65); // [ var(40) , var(10) ]
+                D[14,40] = var(3); // [ var(40) , var(14) ]
+                D[16,40] = (-1)*var(6); // [ var(40) , var(16) ]
+                D[18,40] = var(8); // [ var(40) , var(18) ]
+                D[21,40] = var(12); // [ var(40) , var(21) ]
+                D[24,40] = var(15); // [ var(40) , var(24) ]
+                D[26,40] = var(19); // [ var(40) , var(26) ]
+                D[27,40] = var(22); // [ var(40) , var(27) ]
+                D[4,41] = (-1)*var(36); // [ var(41) , var(4) ]
+                D[6,41] = var(34); // [ var(41) , var(6) ]
+                D[11,41] = (-1)*var(64)+(-1)*var(66); // [ var(41) , var(11) ]
+                D[15,41] = var(3); // [ var(41) , var(15) ]
+                D[16,41] = (-1)*var(5); // [ var(41) , var(16) ]
+                D[19,41] = var(8); // [ var(41) , var(19) ]
+                D[22,41] = var(12); // [ var(41) , var(22) ]
+                D[24,41] = var(14); // [ var(41) , var(24) ]
+                D[26,41] = var(18); // [ var(41) , var(26) ]
+                D[27,41] = var(21); // [ var(41) , var(27) ]
+                D[1,42] = (-1)*var(38); // [ var(42) , var(1) ]
+                D[3,42] = var(37); // [ var(42) , var(3) ]
+                D[7,42] = (-1)*var(33); // [ var(42) , var(7) ]
+                D[8,42] = var(31); // [ var(42) , var(8) ]
+                D[12,42] = (-1)*var(61)+(-1)*var(62)+(-1)*var(63); // [ var(42) , var(12) ]
+                D[17,42] = (-1)*var(4); // [ var(42) , var(17) ]
+                D[21,42] = (-1)*var(10); // [ var(42) , var(21) ]
+                D[22,42] = (-1)*var(11); // [ var(42) , var(22) ]
+                D[25,42] = (-1)*var(16); // [ var(42) , var(25) ]
+                D[29,42] = var(24); // [ var(42) , var(29) ]
+                D[30,42] = var(26); // [ var(42) , var(30) ]
+                D[2,43] = (-1)*var(39); // [ var(43) , var(2) ]
+                D[4,43] = var(38); // [ var(43) , var(4) ]
+                D[8,43] = (-1)*var(34); // [ var(43) , var(8) ]
+                D[9,43] = var(32); // [ var(43) , var(9) ]
+                D[13,43] = (-1)*var(62)+(-1)*var(63)+(-1)*var(64); // [ var(43) , var(13) ]
+                D[17,43] = var(1); // [ var(43) , var(17) ]
+                D[18,43] = (-1)*var(5); // [ var(43) , var(18) ]
+                D[19,43] = (-1)*var(6); // [ var(43) , var(19) ]
+                D[26,43] = var(16); // [ var(43) , var(26) ]
+                D[28,43] = var(20); // [ var(43) , var(28) ]
+                D[30,43] = (-1)*var(25); // [ var(43) , var(30) ]
+                D[3,44] = (-1)*var(40); // [ var(44) , var(3) ]
+                D[5,44] = var(39); // [ var(44) , var(5) ]
+                D[9,44] = (-1)*var(35); // [ var(44) , var(9) ]
+                D[10,44] = var(33); // [ var(44) , var(10) ]
+                D[14,44] = (-1)*var(63)+(-1)*var(64)+(-1)*var(65); // [ var(44) , var(14) ]
+                D[18,44] = var(2); // [ var(44) , var(18) ]
+                D[20,44] = (-1)*var(6); // [ var(44) , var(20) ]
+                D[21,44] = var(7); // [ var(44) , var(21) ]
+                D[24,44] = (-1)*var(11); // [ var(44) , var(24) ]
+                D[28,44] = var(19); // [ var(44) , var(28) ]
+                D[29,44] = var(22); // [ var(44) , var(29) ]
+                D[3,45] = (-1)*var(41); // [ var(45) , var(3) ]
+                D[6,45] = var(39); // [ var(45) , var(6) ]
+                D[9,45] = (-1)*var(36); // [ var(45) , var(9) ]
+                D[11,45] = var(33); // [ var(45) , var(11) ]
+                D[15,45] = (-1)*var(63)+(-1)*var(64)+(-1)*var(66); // [ var(45) , var(15) ]
+                D[19,45] = var(2); // [ var(45) , var(19) ]
+                D[20,45] = (-1)*var(5); // [ var(45) , var(20) ]
+                D[22,45] = var(7); // [ var(45) , var(22) ]
+                D[24,45] = (-1)*var(10); // [ var(45) , var(24) ]
+                D[28,45] = var(18); // [ var(45) , var(28) ]
+                D[29,45] = var(21); // [ var(45) , var(29) ]
+                D[5,46] = var(41); // [ var(46) , var(5) ]
+                D[6,46] = var(40); // [ var(46) , var(6) ]
+                D[10,46] = (-1)*var(36); // [ var(46) , var(10) ]
+                D[11,46] = (-1)*var(35); // [ var(46) , var(11) ]
+                D[16,46] = (-1)*var(64)+(-1)*var(65)+(-1)*var(66); // [ var(46) , var(16) ]
+                D[20,46] = var(3); // [ var(46) , var(20) ]
+                D[23,46] = var(8); // [ var(46) , var(23) ]
+                D[24,46] = (-1)*var(9); // [ var(46) , var(24) ]
+                D[25,46] = var(12); // [ var(46) , var(25) ]
+                D[26,46] = (-1)*var(13); // [ var(46) , var(26) ]
+                D[27,46] = (-1)*var(17); // [ var(46) , var(27) ]
+                D[1,47] = (-1)*var(43); // [ var(47) , var(1) ]
+                D[4,47] = var(42); // [ var(47) , var(4) ]
+                D[7,47] = (-1)*var(39); // [ var(47) , var(7) ]
+                D[9,47] = var(37); // [ var(47) , var(9) ]
+                D[12,47] = (-1)*var(34); // [ var(47) , var(12) ]
+                D[13,47] = var(31); // [ var(47) , var(13) ]
+                D[17,47] = (-1)*var(61)+(-1)*var(62)+(-1)*var(63)+(-1)*var(64); // [ var(47) , var(17) ]
+                D[21,47] = (-1)*var(5); // [ var(47) , var(21) ]
+                D[22,47] = (-1)*var(6); // [ var(47) , var(22) ]
+                D[27,47] = var(16); // [ var(47) , var(27) ]
+                D[29,47] = var(20); // [ var(47) , var(29) ]
+                D[30,47] = var(23); // [ var(47) , var(30) ]
+                D[2,48] = (-1)*var(44); // [ var(48) , var(2) ]
+                D[5,48] = var(43); // [ var(48) , var(5) ]
+                D[8,48] = (-1)*var(40); // [ var(48) , var(8) ]
+                D[10,48] = var(38); // [ var(48) , var(10) ]
+                D[13,48] = (-1)*var(35); // [ var(48) , var(13) ]
+                D[14,48] = var(32); // [ var(48) , var(14) ]
+                D[18,48] = (-1)*var(62)+(-1)*var(63)+(-1)*var(64)+(-1)*var(65); // [ var(48) , var(18) ]
+                D[21,48] = var(1); // [ var(48) , var(21) ]
+                D[23,48] = (-1)*var(6); // [ var(48) , var(23) ]
+                D[26,48] = (-1)*var(11); // [ var(48) , var(26) ]
+                D[28,48] = (-1)*var(15); // [ var(48) , var(28) ]
+                D[30,48] = var(22); // [ var(48) , var(30) ]
+                D[2,49] = (-1)*var(45); // [ var(49) , var(2) ]
+                D[6,49] = var(43); // [ var(49) , var(6) ]
+                D[8,49] = (-1)*var(41); // [ var(49) , var(8) ]
+                D[11,49] = var(38); // [ var(49) , var(11) ]
+                D[13,49] = (-1)*var(36); // [ var(49) , var(13) ]
+                D[15,49] = var(32); // [ var(49) , var(15) ]
+                D[19,49] = (-1)*var(62)+(-1)*var(63)+(-1)*var(64)+(-1)*var(66); // [ var(49) , var(19) ]
+                D[22,49] = var(1); // [ var(49) , var(22) ]
+                D[23,49] = (-1)*var(5); // [ var(49) , var(23) ]
+                D[26,49] = (-1)*var(10); // [ var(49) , var(26) ]
+                D[28,49] = (-1)*var(14); // [ var(49) , var(28) ]
+                D[30,49] = var(21); // [ var(49) , var(30) ]
+                D[3,50] = (-1)*var(46); // [ var(50) , var(3) ]
+                D[5,50] = var(45); // [ var(50) , var(5) ]
+                D[6,50] = var(44); // [ var(50) , var(6) ]
+                D[14,50] = (-1)*var(36); // [ var(50) , var(14) ]
+                D[15,50] = (-1)*var(35); // [ var(50) , var(15) ]
+                D[16,50] = var(33); // [ var(50) , var(16) ]
+                D[20,50] = (-1)*var(63)+(-1)*var(64)+(-1)*var(65)+(-1)*var(66); // [ var(50) , var(20) ]
+                D[23,50] = var(2); // [ var(50) , var(23) ]
+                D[24,50] = var(4); // [ var(50) , var(24) ]
+                D[25,50] = var(7); // [ var(50) , var(25) ]
+                D[28,50] = (-1)*var(13); // [ var(50) , var(28) ]
+                D[29,50] = (-1)*var(17); // [ var(50) , var(29) ]
+                D[1,51] = (-1)*var(48); // [ var(51) , var(1) ]
+                D[5,51] = var(47); // [ var(51) , var(5) ]
+                D[7,51] = (-1)*var(44); // [ var(51) , var(7) ]
+                D[10,51] = var(42); // [ var(51) , var(10) ]
+                D[12,51] = (-1)*var(40); // [ var(51) , var(12) ]
+                D[14,51] = var(37); // [ var(51) , var(14) ]
+                D[17,51] = (-1)*var(35); // [ var(51) , var(17) ]
+                D[18,51] = var(31); // [ var(51) , var(18) ]
+                D[21,51] = (-1)*var(61)+(-1)*var(62)+(-1)*var(63)+(-1)*var(64)+(-1)*var(65); // [ var(51) , var(21) ]
+                D[25,51] = (-1)*var(6); // [ var(51) , var(25) ]
+                D[27,51] = (-1)*var(11); // [ var(51) , var(27) ]
+                D[29,51] = (-1)*var(15); // [ var(51) , var(29) ]
+                D[30,51] = (-1)*var(19); // [ var(51) , var(30) ]
+                D[1,52] = (-1)*var(49); // [ var(52) , var(1) ]
+                D[6,52] = var(47); // [ var(52) , var(6) ]
+                D[7,52] = (-1)*var(45); // [ var(52) , var(7) ]
+                D[11,52] = var(42); // [ var(52) , var(11) ]
+                D[12,52] = (-1)*var(41); // [ var(52) , var(12) ]
+                D[15,52] = var(37); // [ var(52) , var(15) ]
+                D[17,52] = (-1)*var(36); // [ var(52) , var(17) ]
+                D[19,52] = var(31); // [ var(52) , var(19) ]
+                D[22,52] = (-1)*var(61)+(-1)*var(62)+(-1)*var(63)+(-1)*var(64)+(-1)*var(66); // [ var(52) , var(22) ]
+                D[25,52] = (-1)*var(5); // [ var(52) , var(25) ]
+                D[27,52] = (-1)*var(10); // [ var(52) , var(27) ]
+                D[29,52] = (-1)*var(14); // [ var(52) , var(29) ]
+                D[30,52] = (-1)*var(18); // [ var(52) , var(30) ]
+                D[2,53] = (-1)*var(50); // [ var(53) , var(2) ]
+                D[5,53] = var(49); // [ var(53) , var(5) ]
+                D[6,53] = var(48); // [ var(53) , var(6) ]
+                D[8,53] = (-1)*var(46); // [ var(53) , var(8) ]
+                D[16,53] = var(38); // [ var(53) , var(16) ]
+                D[18,53] = (-1)*var(36); // [ var(53) , var(18) ]
+                D[19,53] = (-1)*var(35); // [ var(53) , var(19) ]
+                D[20,53] = var(32); // [ var(53) , var(20) ]
+                D[23,53] = (-1)*var(62)+(-1)*var(63)+(-1)*var(64)+(-1)*var(65)+(-1)*var(66); // [ var(53) , var(23) ]
+                D[25,53] = var(1); // [ var(53) , var(25) ]
+                D[26,53] = var(4); // [ var(53) , var(26) ]
+                D[28,53] = var(9); // [ var(53) , var(28) ]
+                D[30,53] = (-1)*var(17); // [ var(53) , var(30) ]
+                D[4,54] = (-1)*var(50); // [ var(54) , var(4) ]
+                D[9,54] = var(46); // [ var(54) , var(9) ]
+                D[10,54] = var(45); // [ var(54) , var(10) ]
+                D[11,54] = var(44); // [ var(54) , var(11) ]
+                D[14,54] = (-1)*var(41); // [ var(54) , var(14) ]
+                D[15,54] = (-1)*var(40); // [ var(54) , var(15) ]
+                D[16,54] = (-1)*var(39); // [ var(54) , var(16) ]
+                D[20,54] = var(34); // [ var(54) , var(20) ]
+                D[24,54] = (-1)*var(63)+(-2)*var(64)+(-1)*var(65)+(-1)*var(66); // [ var(54) , var(24) ]
+                D[26,54] = var(2); // [ var(54) , var(26) ]
+                D[27,54] = var(7); // [ var(54) , var(27) ]
+                D[28,54] = (-1)*var(8); // [ var(54) , var(28) ]
+                D[29,54] = (-1)*var(12); // [ var(54) , var(29) ]
+                D[1,55] = (-1)*var(53); // [ var(55) , var(1) ]
+                D[5,55] = var(52); // [ var(55) , var(5) ]
+                D[6,55] = var(51); // [ var(55) , var(6) ]
+                D[7,55] = (-1)*var(50); // [ var(55) , var(7) ]
+                D[12,55] = (-1)*var(46); // [ var(55) , var(12) ]
+                D[16,55] = var(42); // [ var(55) , var(16) ]
+                D[20,55] = var(37); // [ var(55) , var(20) ]
+                D[21,55] = (-1)*var(36); // [ var(55) , var(21) ]
+                D[22,55] = (-1)*var(35); // [ var(55) , var(22) ]
+                D[23,55] = var(31); // [ var(55) , var(23) ]
+                D[25,55] = (-1)*var(61)+(-1)*var(62)+(-1)*var(63)+(-1)*var(64)+(-1)*var(65)+(-1)*var(66); // [ var(55) , var(25) ]
+                D[27,55] = var(4); // [ var(55) , var(27) ]
+                D[29,55] = var(9); // [ var(55) , var(29) ]
+                D[30,55] = var(13); // [ var(55) , var(30) ]
+                D[2,56] = (-1)*var(54); // [ var(56) , var(2) ]
+                D[4,56] = (-1)*var(53); // [ var(56) , var(4) ]
+                D[10,56] = var(49); // [ var(56) , var(10) ]
+                D[11,56] = var(48); // [ var(56) , var(11) ]
+                D[13,56] = var(46); // [ var(56) , var(13) ]
+                D[16,56] = (-1)*var(43); // [ var(56) , var(16) ]
+                D[18,56] = (-1)*var(41); // [ var(56) , var(18) ]
+                D[19,56] = (-1)*var(40); // [ var(56) , var(19) ]
+                D[23,56] = var(34); // [ var(56) , var(23) ]
+                D[24,56] = var(32); // [ var(56) , var(24) ]
+                D[26,56] = (-1)*var(62)+(-1)*var(63)+(-2)*var(64)+(-1)*var(65)+(-1)*var(66); // [ var(56) , var(26) ]
+                D[27,56] = var(1); // [ var(56) , var(27) ]
+                D[28,56] = var(3); // [ var(56) , var(28) ]
+                D[30,56] = (-1)*var(12); // [ var(56) , var(30) ]
+                D[1,57] = (-1)*var(56); // [ var(57) , var(1) ]
+                D[4,57] = (-1)*var(55); // [ var(57) , var(4) ]
+                D[7,57] = (-1)*var(54); // [ var(57) , var(7) ]
+                D[10,57] = var(52); // [ var(57) , var(10) ]
+                D[11,57] = var(51); // [ var(57) , var(11) ]
+                D[16,57] = (-1)*var(47); // [ var(57) , var(16) ]
+                D[17,57] = var(46); // [ var(57) , var(17) ]
+                D[21,57] = (-1)*var(41); // [ var(57) , var(21) ]
+                D[22,57] = (-1)*var(40); // [ var(57) , var(22) ]
+                D[24,57] = var(37); // [ var(57) , var(24) ]
+                D[25,57] = var(34); // [ var(57) , var(25) ]
+                D[26,57] = var(31); // [ var(57) , var(26) ]
+                D[27,57] = (-1)*var(61)+(-1)*var(62)+(-1)*var(63)+(-2)*var(64)+(-1)*var(65)+(-1)*var(66); // [ var(57) , var(27) ]
+                D[29,57] = var(3); // [ var(57) , var(29) ]
+                D[30,57] = var(8); // [ var(57) , var(30) ]
+                D[3,58] = (-1)*var(56); // [ var(58) , var(3) ]
+                D[8,58] = var(54); // [ var(58) , var(8) ]
+                D[9,58] = (-1)*var(53); // [ var(58) , var(9) ]
+                D[13,58] = var(50); // [ var(58) , var(13) ]
+                D[14,58] = var(49); // [ var(58) , var(14) ]
+                D[15,58] = var(48); // [ var(58) , var(15) ]
+                D[18,58] = (-1)*var(45); // [ var(58) , var(18) ]
+                D[19,58] = (-1)*var(44); // [ var(58) , var(19) ]
+                D[20,58] = (-1)*var(43); // [ var(58) , var(20) ]
+                D[23,58] = var(39); // [ var(58) , var(23) ]
+                D[24,58] = (-1)*var(38); // [ var(58) , var(24) ]
+                D[26,58] = var(33); // [ var(58) , var(26) ]
+                D[28,58] = (-1)*var(62)+(-2)*var(63)+(-2)*var(64)+(-1)*var(65)+(-1)*var(66); // [ var(58) , var(28) ]
+                D[29,58] = var(1); // [ var(58) , var(29) ]
+                D[30,58] = (-1)*var(7); // [ var(58) , var(30) ]
+                D[1,59] = (-1)*var(58); // [ var(59) , var(1) ]
+                D[3,59] = (-1)*var(57); // [ var(59) , var(3) ]
+                D[9,59] = (-1)*var(55); // [ var(59) , var(9) ]
+                D[12,59] = var(54); // [ var(59) , var(12) ]
+                D[14,59] = var(52); // [ var(59) , var(14) ]
+                D[15,59] = var(51); // [ var(59) , var(15) ]
+                D[17,59] = var(50); // [ var(59) , var(17) ]
+                D[20,59] = (-1)*var(47); // [ var(59) , var(20) ]
+                D[21,59] = (-1)*var(45); // [ var(59) , var(21) ]
+                D[22,59] = (-1)*var(44); // [ var(59) , var(22) ]
+                D[24,59] = (-1)*var(42); // [ var(59) , var(24) ]
+                D[25,59] = var(39); // [ var(59) , var(25) ]
+                D[27,59] = var(33); // [ var(59) , var(27) ]
+                D[28,59] = var(31); // [ var(59) , var(28) ]
+                D[29,59] = (-1)*var(61)+(-1)*var(62)+(-2)*var(63)+(-2)*var(64)+(-1)*var(65)+(-1)*var(66); // [ var(59) , var(29) ]
+                D[30,59] = var(2); // [ var(59) , var(30) ]
+                D[2,60] = (-1)*var(59); // [ var(60) , var(2) ]
+                D[7,60] = var(58); // [ var(60) , var(7) ]
+                D[8,60] = (-1)*var(57); // [ var(60) , var(8) ]
+                D[12,60] = var(56); // [ var(60) , var(12) ]
+                D[13,60] = (-1)*var(55); // [ var(60) , var(13) ]
+                D[17,60] = var(53); // [ var(60) , var(17) ]
+                D[18,60] = var(52); // [ var(60) , var(18) ]
+                D[19,60] = var(51); // [ var(60) , var(19) ]
+                D[21,60] = (-1)*var(49); // [ var(60) , var(21) ]
+                D[22,60] = (-1)*var(48); // [ var(60) , var(22) ]
+                D[23,60] = (-1)*var(47); // [ var(60) , var(23) ]
+                D[25,60] = var(43); // [ var(60) , var(25) ]
+                D[26,60] = (-1)*var(42); // [ var(60) , var(26) ]
+                D[27,60] = var(38); // [ var(60) , var(27) ]
+                D[28,60] = (-1)*var(37); // [ var(60) , var(28) ]
+                D[29,60] = var(32); // [ var(60) , var(29) ]
+                D[30,60] = (-1)*var(61)+(-2)*var(62)+(-2)*var(63)+(-2)*var(64)+(-1)*var(65)+(-1)*var(66); // [ var(60) , var(30) ]
+        // X(i) * X(j):
+                D[1,2] = var(7); // [ var(2) , var(1) ]
+                D[1,8] = var(12); // [ var(8) , var(1) ]
+                D[1,13] = var(17); // [ var(13) , var(1) ]
+                D[1,18] = var(21); // [ var(18) , var(1) ]
+                D[1,19] = var(22); // [ var(19) , var(1) ]
+                D[1,23] = var(25); // [ var(23) , var(1) ]
+                D[1,26] = var(27); // [ var(26) , var(1) ]
+                D[1,28] = var(29); // [ var(28) , var(1) ]
+                D[2,3] = var(8); // [ var(3) , var(2) ]
+                D[2,9] = var(13); // [ var(9) , var(2) ]
+                D[2,14] = var(18); // [ var(14) , var(2) ]
+                D[2,15] = var(19); // [ var(15) , var(2) ]
+                D[2,20] = var(23); // [ var(20) , var(2) ]
+                D[2,24] = var(26); // [ var(24) , var(2) ]
+                D[2,29] = var(30); // [ var(29) , var(2) ]
+                D[3,4] = var(9); // [ var(4) , var(3) ]
+                D[3,7] = (-1)*var(12); // [ var(7) , var(3) ]
+                D[3,10] = var(14); // [ var(10) , var(3) ]
+                D[3,11] = var(15); // [ var(11) , var(3) ]
+                D[3,16] = var(20); // [ var(16) , var(3) ]
+                D[3,26] = var(28); // [ var(26) , var(3) ]
+                D[3,27] = var(29); // [ var(27) , var(3) ]
+                D[4,5] = var(10); // [ var(5) , var(4) ]
+                D[4,6] = var(11); // [ var(6) , var(4) ]
+                D[4,8] = (-1)*var(13); // [ var(8) , var(4) ]
+                D[4,12] = (-1)*var(17); // [ var(12) , var(4) ]
+                D[4,20] = var(24); // [ var(20) , var(4) ]
+                D[4,23] = var(26); // [ var(23) , var(4) ]
+                D[4,25] = var(27); // [ var(25) , var(4) ]
+                D[5,9] = (-1)*var(14); // [ var(9) , var(5) ]
+                D[5,11] = (-1)*var(16); // [ var(11) , var(5) ]
+                D[5,13] = (-1)*var(18); // [ var(13) , var(5) ]
+                D[5,15] = (-1)*var(20); // [ var(15) , var(5) ]
+                D[5,17] = (-1)*var(21); // [ var(17) , var(5) ]
+                D[5,19] = (-1)*var(23); // [ var(19) , var(5) ]
+                D[5,22] = (-1)*var(25); // [ var(22) , var(5) ]
+                D[6,9] = (-1)*var(15); // [ var(9) , var(6) ]
+                D[6,10] = (-1)*var(16); // [ var(10) , var(6) ]
+                D[6,13] = (-1)*var(19); // [ var(13) , var(6) ]
+                D[6,14] = (-1)*var(20); // [ var(14) , var(6) ]
+                D[6,17] = (-1)*var(22); // [ var(17) , var(6) ]
+                D[6,18] = (-1)*var(23); // [ var(18) , var(6) ]
+                D[6,21] = (-1)*var(25); // [ var(21) , var(6) ]
+                D[7,9] = var(17); // [ var(9) , var(7) ]
+                D[7,14] = var(21); // [ var(14) , var(7) ]
+                D[7,15] = var(22); // [ var(15) , var(7) ]
+                D[7,20] = var(25); // [ var(20) , var(7) ]
+                D[7,24] = var(27); // [ var(24) , var(7) ]
+                D[7,28] = (-1)*var(30); // [ var(28) , var(7) ]
+                D[8,10] = var(18); // [ var(10) , var(8) ]
+                D[8,11] = var(19); // [ var(11) , var(8) ]
+                D[8,16] = var(23); // [ var(16) , var(8) ]
+                D[8,24] = (-1)*var(28); // [ var(24) , var(8) ]
+                D[8,27] = var(30); // [ var(27) , var(8) ]
+                D[9,16] = (-1)*var(24); // [ var(16) , var(9) ]
+                D[9,23] = var(28); // [ var(23) , var(9) ]
+                D[9,25] = var(29); // [ var(25) , var(9) ]
+                D[10,12] = (-1)*var(21); // [ var(12) , var(10) ]
+                D[10,15] = (-1)*var(24); // [ var(15) , var(10) ]
+                D[10,19] = (-1)*var(26); // [ var(19) , var(10) ]
+                D[10,22] = (-1)*var(27); // [ var(22) , var(10) ]
+                D[11,12] = (-1)*var(22); // [ var(12) , var(11) ]
+                D[11,14] = (-1)*var(24); // [ var(14) , var(11) ]
+                D[11,18] = (-1)*var(26); // [ var(18) , var(11) ]
+                D[11,21] = (-1)*var(27); // [ var(21) , var(11) ]
+                D[12,16] = var(25); // [ var(16) , var(12) ]
+                D[12,24] = (-1)*var(29); // [ var(24) , var(12) ]
+                D[12,26] = (-1)*var(30); // [ var(26) , var(12) ]
+                D[13,16] = (-1)*var(26); // [ var(16) , var(13) ]
+                D[13,20] = (-1)*var(28); // [ var(20) , var(13) ]
+                D[13,25] = var(30); // [ var(25) , var(13) ]
+                D[14,19] = (-1)*var(28); // [ var(19) , var(14) ]
+                D[14,22] = (-1)*var(29); // [ var(22) , var(14) ]
+                D[15,18] = (-1)*var(28); // [ var(18) , var(15) ]
+                D[15,21] = (-1)*var(29); // [ var(21) , var(15) ]
+                D[16,17] = var(27); // [ var(17) , var(16) ]
+                D[17,20] = (-1)*var(29); // [ var(20) , var(17) ]
+                D[17,23] = (-1)*var(30); // [ var(23) , var(17) ]
+                D[18,22] = (-1)*var(30); // [ var(22) , var(18) ]
+                D[19,21] = (-1)*var(30); // [ var(21) , var(19) ]
+        // Y(i) * Y(j):
+                D[31,32] = (-1)*var(37); // [ var(32) , var(31) ]
+                D[31,38] = (-1)*var(42); // [ var(38) , var(31) ]
+                D[31,43] = (-1)*var(47); // [ var(43) , var(31) ]
+                D[31,48] = (-1)*var(51); // [ var(48) , var(31) ]
+                D[31,49] = (-1)*var(52); // [ var(49) , var(31) ]
+                D[31,53] = (-1)*var(55); // [ var(53) , var(31) ]
+                D[31,56] = (-1)*var(57); // [ var(56) , var(31) ]
+                D[31,58] = (-1)*var(59); // [ var(58) , var(31) ]
+                D[32,33] = (-1)*var(38); // [ var(33) , var(32) ]
+                D[32,39] = (-1)*var(43); // [ var(39) , var(32) ]
+                D[32,44] = (-1)*var(48); // [ var(44) , var(32) ]
+                D[32,45] = (-1)*var(49); // [ var(45) , var(32) ]
+                D[32,50] = (-1)*var(53); // [ var(50) , var(32) ]
+                D[32,54] = (-1)*var(56); // [ var(54) , var(32) ]
+                D[32,59] = (-1)*var(60); // [ var(59) , var(32) ]
+                D[33,34] = (-1)*var(39); // [ var(34) , var(33) ]
+                D[33,37] = var(42); // [ var(37) , var(33) ]
+                D[33,40] = (-1)*var(44); // [ var(40) , var(33) ]
+                D[33,41] = (-1)*var(45); // [ var(41) , var(33) ]
+                D[33,46] = (-1)*var(50); // [ var(46) , var(33) ]
+                D[33,56] = (-1)*var(58); // [ var(56) , var(33) ]
+                D[33,57] = (-1)*var(59); // [ var(57) , var(33) ]
+                D[34,35] = (-1)*var(40); // [ var(35) , var(34) ]
+                D[34,36] = (-1)*var(41); // [ var(36) , var(34) ]
+                D[34,38] = var(43); // [ var(38) , var(34) ]
+                D[34,42] = var(47); // [ var(42) , var(34) ]
+                D[34,50] = (-1)*var(54); // [ var(50) , var(34) ]
+                D[34,53] = (-1)*var(56); // [ var(53) , var(34) ]
+                D[34,55] = (-1)*var(57); // [ var(55) , var(34) ]
+                D[35,39] = var(44); // [ var(39) , var(35) ]
+                D[35,41] = var(46); // [ var(41) , var(35) ]
+                D[35,43] = var(48); // [ var(43) , var(35) ]
+                D[35,45] = var(50); // [ var(45) , var(35) ]
+                D[35,47] = var(51); // [ var(47) , var(35) ]
+                D[35,49] = var(53); // [ var(49) , var(35) ]
+                D[35,52] = var(55); // [ var(52) , var(35) ]
+                D[36,39] = var(45); // [ var(39) , var(36) ]
+                D[36,40] = var(46); // [ var(40) , var(36) ]
+                D[36,43] = var(49); // [ var(43) , var(36) ]
+                D[36,44] = var(50); // [ var(44) , var(36) ]
+                D[36,47] = var(52); // [ var(47) , var(36) ]
+                D[36,48] = var(53); // [ var(48) , var(36) ]
+                D[36,51] = var(55); // [ var(51) , var(36) ]
+                D[37,39] = (-1)*var(47); // [ var(39) , var(37) ]
+                D[37,44] = (-1)*var(51); // [ var(44) , var(37) ]
+                D[37,45] = (-1)*var(52); // [ var(45) , var(37) ]
+                D[37,50] = (-1)*var(55); // [ var(50) , var(37) ]
+                D[37,54] = (-1)*var(57); // [ var(54) , var(37) ]
+                D[37,58] = var(60); // [ var(58) , var(37) ]
+                D[38,40] = (-1)*var(48); // [ var(40) , var(38) ]
+                D[38,41] = (-1)*var(49); // [ var(41) , var(38) ]
+                D[38,46] = (-1)*var(53); // [ var(46) , var(38) ]
+                D[38,54] = var(58); // [ var(54) , var(38) ]
+                D[38,57] = (-1)*var(60); // [ var(57) , var(38) ]
+                D[39,46] = var(54); // [ var(46) , var(39) ]
+                D[39,53] = (-1)*var(58); // [ var(53) , var(39) ]
+                D[39,55] = (-1)*var(59); // [ var(55) , var(39) ]
+                D[40,42] = var(51); // [ var(42) , var(40) ]
+                D[40,45] = var(54); // [ var(45) , var(40) ]
+                D[40,49] = var(56); // [ var(49) , var(40) ]
+                D[40,52] = var(57); // [ var(52) , var(40) ]
+                D[41,42] = var(52); // [ var(42) , var(41) ]
+                D[41,44] = var(54); // [ var(44) , var(41) ]
+                D[41,48] = var(56); // [ var(48) , var(41) ]
+                D[41,51] = var(57); // [ var(51) , var(41) ]
+                D[42,46] = (-1)*var(55); // [ var(46) , var(42) ]
+                D[42,54] = var(59); // [ var(54) , var(42) ]
+                D[42,56] = var(60); // [ var(56) , var(42) ]
+                D[43,46] = var(56); // [ var(46) , var(43) ]
+                D[43,50] = var(58); // [ var(50) , var(43) ]
+                D[43,55] = (-1)*var(60); // [ var(55) , var(43) ]
+                D[44,49] = var(58); // [ var(49) , var(44) ]
+                D[44,52] = var(59); // [ var(52) , var(44) ]
+                D[45,48] = var(58); // [ var(48) , var(45) ]
+                D[45,51] = var(59); // [ var(51) , var(45) ]
+                D[46,47] = (-1)*var(57); // [ var(47) , var(46) ]
+                D[47,50] = var(59); // [ var(50) , var(47) ]
+                D[47,53] = var(60); // [ var(53) , var(47) ]
+                D[48,52] = var(60); // [ var(52) , var(48) ]
+                D[49,51] = var(60); // [ var(51) , var(49) ]
+   def @@RR=nc_algebra(1,D);
+   return(@@RR);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   def ncAlgebra = makeUso12();
+   ncAlgebra;
+   setring ncAlgebra;
+   // ...  714  noncommutative relations
+}
+////////////////////////////////////////////////////////////////////
+
+// Algebra: f4(Q) has the type: F4, and defined by:
+
+proc makeUf4(list #)
+"USAGE:   makeUf4([p]); p an optional integer (field characteristic)
+RETURN:  a ring, describing U(f_4)
+NOTE:    You have to activate this ring with the 'setring' command. The presentation of U(f_4) is derived from the Chevalley representation of f_4, positive resp. negative roots are denoted by x(i) resp. y(i); Cartan elements are denoted by h(i).
+SEE ALSO: makeUsl, makeUso5, makeUsp1, makeUe6, makeUe7, makeUe8, makeUg2, makeUe8
+EXAMPLE: example makeUf4; shows examples
+"
+{
+   int @p = defInt(#);
+
+   ring @@@rrr = @p,(X(1..24),Y(1..24),H(1..4)),dp;
+   int N = nvars(@@@rrr);
+   matrix D[N][N]=0;
+
+        // H(i) * X(j):
+                D[1,49] = (2)*var(1); // [ var(49) , var(1) ]
+                D[3,49] = (-1)*var(3); // [ var(49) , var(3) ]
+                D[5,49] = var(5); // [ var(49) , var(5) ]
+                D[7,49] = (-1)*var(7); // [ var(49) , var(7) ]
+                D[8,49] = var(8); // [ var(49) , var(8) ]
+                D[9,49] = (-1)*var(9); // [ var(49) , var(9) ]
+                D[10,49] = (-2)*var(10); // [ var(49) , var(10) ]
+                D[11,49] = var(11); // [ var(49) , var(11) ]
+                D[13,49] = (-2)*var(13); // [ var(49) , var(13) ]
+                D[15,49] = (2)*var(15); // [ var(49) , var(15) ]
+                D[16,49] = (-2)*var(16); // [ var(49) , var(16) ]
+                D[18,49] = (2)*var(18); // [ var(49) , var(18) ]
+                D[19,49] = (-1)*var(19); // [ var(49) , var(19) ]
+                D[20,49] = (2)*var(20); // [ var(49) , var(20) ]
+                D[21,49] = var(21); // [ var(49) , var(21) ]
+                D[2,50] = (2)*var(2); // [ var(50) , var(2) ]
+                D[4,50] = (-1)*var(4); // [ var(50) , var(4) ]
+                D[6,50] = var(6); // [ var(50) , var(6) ]
+                D[7,50] = (-1)*var(7); // [ var(50) , var(7) ]
+                D[8,50] = (-1)*var(8); // [ var(50) , var(8) ]
+                D[9,50] = var(9); // [ var(50) , var(9) ]
+                D[10,50] = (-1)*var(10); // [ var(50) , var(10) ]
+                D[11,50] = var(11); // [ var(50) , var(11) ]
+                D[12,50] = (-1)*var(12); // [ var(50) , var(12) ]
+                D[13,50] = var(13); // [ var(50) , var(13) ]
+                D[14,50] = var(14); // [ var(50) , var(14) ]
+                D[15,50] = (-1)*var(15); // [ var(50) , var(15) ]
+                D[18,50] = var(18); // [ var(50) , var(18) ]
+                D[23,50] = (-1)*var(23); // [ var(50) , var(23) ]
+                D[24,50] = var(24); // [ var(50) , var(24) ]
+                D[1,51] = (-1)*var(1); // [ var(51) , var(1) ]
+                D[3,51] = (2)*var(3); // [ var(51) , var(3) ]
+                D[4,51] = (-2)*var(4); // [ var(51) , var(4) ]
+                D[5,51] = var(5); // [ var(51) , var(5) ]
+                D[6,51] = (-2)*var(6); // [ var(51) , var(6) ]
+                D[8,51] = (-1)*var(8); // [ var(51) , var(8) ]
+                D[10,51] = (2)*var(10); // [ var(51) , var(10) ]
+                D[11,51] = (-1)*var(11); // [ var(51) , var(11) ]
+                D[12,51] = var(12); // [ var(51) , var(12) ]
+                D[13,51] = (2)*var(13); // [ var(51) , var(13) ]
+                D[14,51] = var(14); // [ var(51) , var(14) ]
+                D[17,51] = (-1)*var(17); // [ var(51) , var(17) ]
+                D[19,51] = var(19); // [ var(51) , var(19) ]
+                D[20,51] = (-2)*var(20); // [ var(51) , var(20) ]
+                D[22,51] = (2)*var(22); // [ var(51) , var(22) ]
+                D[2,52] = (-1)*var(2); // [ var(52) , var(2) ]
+                D[3,52] = (-1)*var(3); // [ var(52) , var(3) ]
+                D[4,52] = (2)*var(4); // [ var(52) , var(4) ]
+                D[5,52] = (-1)*var(5); // [ var(52) , var(5) ]
+                D[6,52] = var(6); // [ var(52) , var(6) ]
+                D[7,52] = var(7); // [ var(52) , var(7) ]
+                D[8,52] = var(8); // [ var(52) , var(8) ]
+                D[13,52] = (-1)*var(13); // [ var(52) , var(13) ]
+                D[14,52] = (-1)*var(14); // [ var(52) , var(14) ]
+                D[16,52] = var(16); // [ var(52) , var(16) ]
+                D[17,52] = var(17); // [ var(52) , var(17) ]
+                D[18,52] = (-1)*var(18); // [ var(52) , var(18) ]
+                D[20,52] = var(20); // [ var(52) , var(20) ]
+                D[22,52] = (-1)*var(22); // [ var(52) , var(22) ]
+                D[23,52] = var(23); // [ var(52) , var(23) ]
+        // H(i) * Y(j):
+                D[25,49] = (-2)*var(25); // [ var(49) , var(25) ]
+                D[27,49] = var(27); // [ var(49) , var(27) ]
+                D[29,49] = (-1)*var(29); // [ var(49) , var(29) ]
+                D[31,49] = var(31); // [ var(49) , var(31) ]
+                D[32,49] = (-1)*var(32); // [ var(49) , var(32) ]
+                D[33,49] = var(33); // [ var(49) , var(33) ]
+                D[34,49] = (2)*var(34); // [ var(49) , var(34) ]
+                D[35,49] = (-1)*var(35); // [ var(49) , var(35) ]
+                D[37,49] = (2)*var(37); // [ var(49) , var(37) ]
+                D[39,49] = (-2)*var(39); // [ var(49) , var(39) ]
+                D[40,49] = (2)*var(40); // [ var(49) , var(40) ]
+                D[42,49] = (-2)*var(42); // [ var(49) , var(42) ]
+                D[43,49] = var(43); // [ var(49) , var(43) ]
+                D[44,49] = (-2)*var(44); // [ var(49) , var(44) ]
+                D[45,49] = (-1)*var(45); // [ var(49) , var(45) ]
+                D[26,50] = (-2)*var(26); // [ var(50) , var(26) ]
+                D[28,50] = var(28); // [ var(50) , var(28) ]
+                D[30,50] = (-1)*var(30); // [ var(50) , var(30) ]
+                D[31,50] = var(31); // [ var(50) , var(31) ]
+                D[32,50] = var(32); // [ var(50) , var(32) ]
+                D[33,50] = (-1)*var(33); // [ var(50) , var(33) ]
+                D[34,50] = var(34); // [ var(50) , var(34) ]
+                D[35,50] = (-1)*var(35); // [ var(50) , var(35) ]
+                D[36,50] = var(36); // [ var(50) , var(36) ]
+                D[37,50] = (-1)*var(37); // [ var(50) , var(37) ]
+                D[38,50] = (-1)*var(38); // [ var(50) , var(38) ]
+                D[39,50] = var(39); // [ var(50) , var(39) ]
+                D[42,50] = (-1)*var(42); // [ var(50) , var(42) ]
+                D[47,50] = var(47); // [ var(50) , var(47) ]
+                D[48,50] = (-1)*var(48); // [ var(50) , var(48) ]
+                D[25,51] = var(25); // [ var(51) , var(25) ]
+                D[27,51] = (-2)*var(27); // [ var(51) , var(27) ]
+                D[28,51] = (2)*var(28); // [ var(51) , var(28) ]
+                D[29,51] = (-1)*var(29); // [ var(51) , var(29) ]
+                D[30,51] = (2)*var(30); // [ var(51) , var(30) ]
+                D[32,51] = var(32); // [ var(51) , var(32) ]
+                D[34,51] = (-2)*var(34); // [ var(51) , var(34) ]
+                D[35,51] = var(35); // [ var(51) , var(35) ]
+                D[36,51] = (-1)*var(36); // [ var(51) , var(36) ]
+                D[37,51] = (-2)*var(37); // [ var(51) , var(37) ]
+                D[38,51] = (-1)*var(38); // [ var(51) , var(38) ]
+                D[41,51] = var(41); // [ var(51) , var(41) ]
+                D[43,51] = (-1)*var(43); // [ var(51) , var(43) ]
+                D[44,51] = (2)*var(44); // [ var(51) , var(44) ]
+                D[46,51] = (-2)*var(46); // [ var(51) , var(46) ]
+                D[26,52] = var(26); // [ var(52) , var(26) ]
+                D[27,52] = var(27); // [ var(52) , var(27) ]
+                D[28,52] = (-2)*var(28); // [ var(52) , var(28) ]
+                D[29,52] = var(29); // [ var(52) , var(29) ]
+                D[30,52] = (-1)*var(30); // [ var(52) , var(30) ]
+                D[31,52] = (-1)*var(31); // [ var(52) , var(31) ]
+                D[32,52] = (-1)*var(32); // [ var(52) , var(32) ]
+                D[37,52] = var(37); // [ var(52) , var(37) ]
+                D[38,52] = var(38); // [ var(52) , var(38) ]
+                D[40,52] = (-1)*var(40); // [ var(52) , var(40) ]
+                D[41,52] = (-1)*var(41); // [ var(52) , var(41) ]
+                D[42,52] = var(42); // [ var(52) , var(42) ]
+                D[44,52] = (-1)*var(44); // [ var(52) , var(44) ]
+                D[46,52] = var(46); // [ var(52) , var(46) ]
+                D[47,52] = (-1)*var(47); // [ var(52) , var(47) ]
+        // Y(i) * X(j):
+                D[1,25] = (-1)*var(49); // [ var(25) , var(1) ]
+                D[5,25] = (-1)*var(3); // [ var(25) , var(5) ]
+                D[8,25] = (-1)*var(7); // [ var(25) , var(8) ]
+                D[11,25] = (-1)*var(9); // [ var(25) , var(11) ]
+                D[12,25] = (-2)*var(10); // [ var(25) , var(12) ]
+                D[14,25] = (-2)*var(13); // [ var(25) , var(14) ]
+                D[15,25] = (-1)*var(12); // [ var(25) , var(15) ]
+                D[17,25] = (-2)*var(16); // [ var(25) , var(17) ]
+                D[18,25] = (-1)*var(14); // [ var(25) , var(18) ]
+                D[20,25] = (-1)*var(17); // [ var(25) , var(20) ]
+                D[21,25] = (-1)*var(19); // [ var(25) , var(21) ]
+                D[2,26] = (-1)*var(50); // [ var(26) , var(2) ]
+                D[6,26] = (-1)*var(4); // [ var(26) , var(6) ]
+                D[9,26] = (-1)*var(7); // [ var(26) , var(9) ]
+                D[11,26] = (-1)*var(8); // [ var(26) , var(11) ]
+                D[13,26] = (-1)*var(10); // [ var(26) , var(13) ]
+                D[14,26] = (-1)*var(12); // [ var(26) , var(14) ]
+                D[18,26] = (-1)*var(15); // [ var(26) , var(18) ]
+                D[24,26] = var(23); // [ var(26) , var(24) ]
+                D[3,27] = (-1)*var(51); // [ var(27) , var(3) ]
+                D[5,27] = var(1); // [ var(27) , var(5) ]
+                D[7,27] = (-2)*var(4); // [ var(27) , var(7) ]
+                D[9,27] = (-2)*var(6); // [ var(27) , var(9) ]
+                D[10,27] = (-1)*var(7); // [ var(27) , var(10) ]
+                D[12,27] = (-1)*var(8); // [ var(27) , var(12) ]
+                D[13,27] = (-1)*var(9); // [ var(27) , var(13) ]
+                D[14,27] = (-1)*var(11); // [ var(27) , var(14) ]
+                D[19,27] = (-1)*var(17); // [ var(27) , var(19) ]
+                D[21,27] = (-2)*var(20); // [ var(27) , var(21) ]
+                D[22,27] = (-1)*var(21); // [ var(27) , var(22) ]
+                D[4,28] = (-1)*var(52); // [ var(28) , var(4) ]
+                D[6,28] = var(2); // [ var(28) , var(6) ]
+                D[7,28] = var(3); // [ var(28) , var(7) ]
+                D[8,28] = var(5); // [ var(28) , var(8) ]
+                D[16,28] = (-1)*var(13); // [ var(28) , var(16) ]
+                D[17,28] = (-1)*var(14); // [ var(28) , var(17) ]
+                D[20,28] = (-1)*var(18); // [ var(28) , var(20) ]
+                D[23,28] = var(22); // [ var(28) , var(23) ]
+                D[1,29] = (-1)*var(27); // [ var(29) , var(1) ]
+                D[3,29] = var(25); // [ var(29) , var(3) ]
+                D[5,29] = (-1)*var(49)+(-1)*var(51); // [ var(29) , var(5) ]
+                D[8,29] = (-2)*var(4); // [ var(29) , var(8) ]
+                D[11,29] = (-2)*var(6); // [ var(29) , var(11) ]
+                D[12,29] = (-1)*var(7); // [ var(29) , var(12) ]
+                D[14,29] = (-1)*var(9); // [ var(29) , var(14) ]
+                D[15,29] = (-1)*var(8); // [ var(29) , var(15) ]
+                D[18,29] = (-1)*var(11); // [ var(29) , var(18) ]
+                D[19,29] = (2)*var(16); // [ var(29) , var(19) ]
+                D[21,29] = var(17); // [ var(29) , var(21) ]
+                D[22,29] = var(19); // [ var(29) , var(22) ]
+                D[2,30] = (-1)*var(28); // [ var(30) , var(2) ]
+                D[4,30] = var(26); // [ var(30) , var(4) ]
+                D[6,30] = (-1)*var(50)+(-1)*var(52); // [ var(30) , var(6) ]
+                D[9,30] = var(3); // [ var(30) , var(9) ]
+                D[11,30] = var(5); // [ var(30) , var(11) ]
+                D[16,30] = var(10); // [ var(30) , var(16) ]
+                D[17,30] = var(12); // [ var(30) , var(17) ]
+                D[20,30] = var(15); // [ var(30) , var(20) ]
+                D[24,30] = (-1)*var(22); // [ var(30) , var(24) ]
+                D[3,31] = (-2)*var(28); // [ var(31) , var(3) ]
+                D[4,31] = var(27); // [ var(31) , var(4) ]
+                D[7,31] = (-1)*var(51)+(-2)*var(52); // [ var(31) , var(7) ]
+                D[8,31] = var(1); // [ var(31) , var(8) ]
+                D[9,31] = (2)*var(2); // [ var(31) , var(9) ]
+                D[10,31] = var(3); // [ var(31) , var(10) ]
+                D[12,31] = var(5); // [ var(31) , var(12) ]
+                D[16,31] = var(9); // [ var(31) , var(16) ]
+                D[17,31] = var(11); // [ var(31) , var(17) ]
+                D[19,31] = (-1)*var(14); // [ var(31) , var(19) ]
+                D[21,31] = (-2)*var(18); // [ var(31) , var(21) ]
+                D[23,31] = (-1)*var(21); // [ var(31) , var(23) ]
+                D[1,32] = (-1)*var(31); // [ var(32) , var(1) ]
+                D[4,32] = var(29); // [ var(32) , var(4) ]
+                D[5,32] = (-2)*var(28); // [ var(32) , var(5) ]
+                D[7,32] = var(25); // [ var(32) , var(7) ]
+                D[8,32] = (-1)*var(49)+(-1)*var(51)+(-2)*var(52); // [ var(32) , var(8) ]
+                D[11,32] = (2)*var(2); // [ var(32) , var(11) ]
+                D[12,32] = var(3); // [ var(32) , var(12) ]
+                D[15,32] = var(5); // [ var(32) , var(15) ]
+                D[17,32] = var(9); // [ var(32) , var(17) ]
+                D[19,32] = (2)*var(13); // [ var(32) , var(19) ]
+                D[20,32] = var(11); // [ var(32) , var(20) ]
+                D[21,32] = var(14); // [ var(32) , var(21) ]
+                D[23,32] = var(19); // [ var(32) , var(23) ]
+                D[2,33] = (-1)*var(31); // [ var(33) , var(2) ]
+                D[3,33] = (-2)*var(30); // [ var(33) , var(3) ]
+                D[6,33] = var(27); // [ var(33) , var(6) ]
+                D[7,33] = (2)*var(26); // [ var(33) , var(7) ]
+                D[9,33] = (-2)*var(50)+(-1)*var(51)+(-2)*var(52); // [ var(33) , var(9) ]
+                D[11,33] = var(1); // [ var(33) , var(11) ]
+                D[13,33] = var(3); // [ var(33) , var(13) ]
+                D[14,33] = var(5); // [ var(33) , var(14) ]
+                D[16,33] = (-1)*var(7); // [ var(33) , var(16) ]
+                D[17,33] = (-1)*var(8); // [ var(33) , var(17) ]
+                D[19,33] = var(12); // [ var(33) , var(19) ]
+                D[21,33] = (2)*var(15); // [ var(33) , var(21) ]
+                D[24,33] = var(21); // [ var(33) , var(24) ]
+                D[3,34] = (-1)*var(31); // [ var(34) , var(3) ]
+                D[7,34] = var(27); // [ var(34) , var(7) ]
+                D[10,34] = (-1)*var(51)+(-1)*var(52); // [ var(34) , var(10) ]
+                D[12,34] = var(1); // [ var(34) , var(12) ]
+                D[13,34] = var(2); // [ var(34) , var(13) ]
+                D[16,34] = (-1)*var(6); // [ var(34) , var(16) ]
+                D[19,34] = var(11); // [ var(34) , var(19) ]
+                D[22,34] = (-1)*var(18); // [ var(34) , var(22) ]
+                D[23,34] = var(20); // [ var(34) , var(23) ]
+                D[1,35] = (-1)*var(33); // [ var(35) , var(1) ]
+                D[2,35] = (-1)*var(32); // [ var(35) , var(2) ]
+                D[5,35] = (-2)*var(30); // [ var(35) , var(5) ]
+                D[6,35] = var(29); // [ var(35) , var(6) ]
+                D[8,35] = (2)*var(26); // [ var(35) , var(8) ]
+                D[9,35] = var(25); // [ var(35) , var(9) ]
+                D[11,35] = (-1)*var(49)+(-2)*var(50)+(-1)*var(51)+(-2)*var(52); // [ var(35) , var(11) ]
+                D[14,35] = var(3); // [ var(35) , var(14) ]
+                D[17,35] = (-1)*var(7); // [ var(35) , var(17) ]
+                D[18,35] = var(5); // [ var(35) , var(18) ]
+                D[19,35] = (-2)*var(10); // [ var(35) , var(19) ]
+                D[20,35] = (-1)*var(8); // [ var(35) , var(20) ]
+                D[21,35] = (-1)*var(12); // [ var(35) , var(21) ]
+                D[24,35] = (-1)*var(19); // [ var(35) , var(24) ]
+                D[1,36] = (-2)*var(34); // [ var(36) , var(1) ]
+                D[3,36] = (-1)*var(32); // [ var(36) , var(3) ]
+                D[5,36] = (-1)*var(31); // [ var(36) , var(5) ]
+                D[7,36] = var(29); // [ var(36) , var(7) ]
+                D[8,36] = var(27); // [ var(36) , var(8) ]
+                D[10,36] = var(25); // [ var(36) , var(10) ]
+                D[12,36] = (-1)*var(49)+(-2)*var(51)+(-2)*var(52); // [ var(36) , var(12) ]
+                D[14,36] = (2)*var(2); // [ var(36) , var(14) ]
+                D[15,36] = var(1); // [ var(36) , var(15) ]
+                D[17,36] = (-2)*var(6); // [ var(36) , var(17) ]
+                D[19,36] = (-1)*var(9); // [ var(36) , var(19) ]
+                D[21,36] = var(11); // [ var(36) , var(21) ]
+                D[22,36] = var(14); // [ var(36) , var(22) ]
+                D[23,36] = (-1)*var(17); // [ var(36) , var(23) ]
+                D[2,37] = (-1)*var(34); // [ var(37) , var(2) ]
+                D[3,37] = (-1)*var(33); // [ var(37) , var(3) ]
+                D[9,37] = var(27); // [ var(37) , var(9) ]
+                D[10,37] = var(26); // [ var(37) , var(10) ]
+                D[13,37] = (-1)*var(50)+(-1)*var(51)+(-1)*var(52); // [ var(37) , var(13) ]
+                D[14,37] = var(1); // [ var(37) , var(14) ]
+                D[16,37] = var(4); // [ var(37) , var(16) ]
+                D[19,37] = (-1)*var(8); // [ var(37) , var(19) ]
+                D[22,37] = var(15); // [ var(37) , var(22) ]
+                D[24,37] = (-1)*var(20); // [ var(37) , var(24) ]
+                D[1,38] = (-2)*var(37); // [ var(38) , var(1) ]
+                D[2,38] = (-1)*var(36); // [ var(38) , var(2) ]
+                D[3,38] = (-1)*var(35); // [ var(38) , var(3) ]
+                D[5,38] = (-1)*var(33); // [ var(38) , var(5) ]
+                D[9,38] = var(29); // [ var(38) , var(9) ]
+                D[11,38] = var(27); // [ var(38) , var(11) ]
+                D[12,38] = (2)*var(26); // [ var(38) , var(12) ]
+                D[13,38] = var(25); // [ var(38) , var(13) ]
+                D[14,38] = (-1)*var(49)+(-2)*var(50)+(-2)*var(51)+(-2)*var(52); // [ var(38) , var(14) ]
+                D[17,38] = (2)*var(4); // [ var(38) , var(17) ]
+                D[18,38] = var(1); // [ var(38) , var(18) ]
+                D[19,38] = var(7); // [ var(38) , var(19) ]
+                D[21,38] = (-1)*var(8); // [ var(38) , var(21) ]
+                D[22,38] = (-1)*var(12); // [ var(38) , var(22) ]
+                D[24,38] = var(17); // [ var(38) , var(24) ]
+                D[1,39] = (-1)*var(36); // [ var(39) , var(1) ]
+                D[5,39] = (-1)*var(32); // [ var(39) , var(5) ]
+                D[8,39] = var(29); // [ var(39) , var(8) ]
+                D[12,39] = var(25); // [ var(39) , var(12) ]
+                D[15,39] = (-1)*var(49)+(-1)*var(51)+(-1)*var(52); // [ var(39) , var(15) ]
+                D[18,39] = var(2); // [ var(39) , var(18) ]
+                D[20,39] = (-1)*var(6); // [ var(39) , var(20) ]
+                D[21,39] = (-1)*var(9); // [ var(39) , var(21) ]
+                D[22,39] = (-1)*var(13); // [ var(39) , var(22) ]
+                D[23,39] = var(16); // [ var(39) , var(23) ]
+                D[4,40] = (-1)*var(37); // [ var(40) , var(4) ]
+                D[6,40] = var(34); // [ var(40) , var(6) ]
+                D[7,40] = var(33); // [ var(40) , var(7) ]
+                D[9,40] = (-1)*var(31); // [ var(40) , var(9) ]
+                D[10,40] = (-1)*var(30); // [ var(40) , var(10) ]
+                D[13,40] = var(28); // [ var(40) , var(13) ]
+                D[16,40] = (-1)*var(50)+(-1)*var(51)+(-2)*var(52); // [ var(40) , var(16) ]
+                D[17,40] = var(1); // [ var(40) , var(17) ]
+                D[19,40] = (-1)*var(5); // [ var(40) , var(19) ]
+                D[23,40] = (-1)*var(15); // [ var(40) , var(23) ]
+                D[24,40] = var(18); // [ var(40) , var(24) ]
+                D[1,41] = (-2)*var(40); // [ var(41) , var(1) ]
+                D[4,41] = (-1)*var(38); // [ var(41) , var(4) ]
+                D[6,41] = var(36); // [ var(41) , var(6) ]
+                D[7,41] = var(35); // [ var(41) , var(7) ]
+                D[8,41] = var(33); // [ var(41) , var(8) ]
+                D[9,41] = (-1)*var(32); // [ var(41) , var(9) ]
+                D[11,41] = (-1)*var(31); // [ var(41) , var(11) ]
+                D[12,41] = (-2)*var(30); // [ var(41) , var(12) ]
+                D[14,41] = (2)*var(28); // [ var(41) , var(14) ]
+                D[16,41] = var(25); // [ var(41) , var(16) ]
+                D[17,41] = (-1)*var(49)+(-2)*var(50)+(-2)*var(51)+(-4)*var(52); // [ var(41) , var(17) ]
+                D[19,41] = var(3); // [ var(41) , var(19) ]
+                D[20,41] = var(1); // [ var(41) , var(20) ]
+                D[21,41] = (-1)*var(5); // [ var(41) , var(21) ]
+                D[23,41] = var(12); // [ var(41) , var(23) ]
+                D[24,41] = (-1)*var(14); // [ var(41) , var(24) ]
+                D[1,42] = (-1)*var(38); // [ var(42) , var(1) ]
+                D[2,42] = (-1)*var(39); // [ var(42) , var(2) ]
+                D[5,42] = (-1)*var(35); // [ var(42) , var(5) ]
+                D[11,42] = var(29); // [ var(42) , var(11) ]
+                D[14,42] = var(25); // [ var(42) , var(14) ]
+                D[15,42] = var(26); // [ var(42) , var(15) ]
+                D[18,42] = (-1)*var(49)+(-1)*var(50)+(-1)*var(51)+(-1)*var(52); // [ var(42) , var(18) ]
+                D[20,42] = var(4); // [ var(42) , var(20) ]
+                D[21,42] = var(7); // [ var(42) , var(21) ]
+                D[22,42] = var(10); // [ var(42) , var(22) ]
+                D[24,42] = (-1)*var(16); // [ var(42) , var(24) ]
+                D[3,43] = (-1)*var(41); // [ var(43) , var(3) ]
+                D[5,43] = (2)*var(40); // [ var(43) , var(5) ]
+                D[7,43] = (-1)*var(38); // [ var(43) , var(7) ]
+                D[8,43] = (2)*var(37); // [ var(43) , var(8) ]
+                D[9,43] = var(36); // [ var(43) , var(9) ]
+                D[10,43] = var(35); // [ var(43) , var(10) ]
+                D[11,43] = (-2)*var(34); // [ var(43) , var(11) ]
+                D[12,43] = (-1)*var(33); // [ var(43) , var(12) ]
+                D[13,43] = (-1)*var(32); // [ var(43) , var(13) ]
+                D[14,43] = var(31); // [ var(43) , var(14) ]
+                D[16,43] = (-1)*var(29); // [ var(43) , var(16) ]
+                D[17,43] = var(27); // [ var(43) , var(17) ]
+                D[19,43] = (-1)*var(49)+(-2)*var(50)+(-3)*var(51)+(-4)*var(52); // [ var(43) , var(19) ]
+                D[21,43] = var(1); // [ var(43) , var(21) ]
+                D[22,43] = (-1)*var(5); // [ var(43) , var(22) ]
+                D[23,43] = (-1)*var(8); // [ var(43) , var(23) ]
+                D[24,43] = var(11); // [ var(43) , var(24) ]
+                D[1,44] = (-1)*var(41); // [ var(44) , var(1) ]
+                D[4,44] = (-1)*var(42); // [ var(44) , var(4) ]
+                D[6,44] = var(39); // [ var(44) , var(6) ]
+                D[8,44] = var(35); // [ var(44) , var(8) ]
+                D[11,44] = (-1)*var(32); // [ var(44) , var(11) ]
+                D[15,44] = (-1)*var(30); // [ var(44) , var(15) ]
+                D[17,44] = var(25); // [ var(44) , var(17) ]
+                D[18,44] = var(28); // [ var(44) , var(18) ]
+                D[20,44] = (-1)*var(49)+(-1)*var(50)+(-1)*var(51)+(-2)*var(52); // [ var(44) , var(20) ]
+                D[21,44] = var(3); // [ var(44) , var(21) ]
+                D[23,44] = (-1)*var(10); // [ var(44) , var(23) ]
+                D[24,44] = var(13); // [ var(44) , var(24) ]
+                D[1,45] = (-1)*var(43); // [ var(45) , var(1) ]
+                D[3,45] = (-2)*var(44); // [ var(45) , var(3) ]
+                D[5,45] = var(41); // [ var(45) , var(5) ]
+                D[7,45] = (-2)*var(42); // [ var(45) , var(7) ]
+                D[8,45] = var(38); // [ var(45) , var(8) ]
+                D[9,45] = (2)*var(39); // [ var(45) , var(9) ]
+                D[11,45] = (-1)*var(36); // [ var(45) , var(11) ]
+                D[12,45] = var(35); // [ var(45) , var(12) ]
+                D[14,45] = (-1)*var(32); // [ var(45) , var(14) ]
+                D[15,45] = (-1)*var(33); // [ var(45) , var(15) ]
+                D[17,45] = (-1)*var(29); // [ var(45) , var(17) ]
+                D[18,45] = var(31); // [ var(45) , var(18) ]
+                D[19,45] = var(25); // [ var(45) , var(19) ]
+                D[20,45] = var(27); // [ var(45) , var(20) ]
+                D[21,45] = (-2)*var(49)+(-2)*var(50)+(-3)*var(51)+(-4)*var(52); // [ var(45) , var(21) ]
+                D[22,45] = var(3); // [ var(45) , var(22) ]
+                D[23,45] = var(7); // [ var(45) , var(23) ]
+                D[24,45] = (-1)*var(9); // [ var(45) , var(24) ]
+                D[3,46] = (-1)*var(45); // [ var(46) , var(3) ]
+                D[5,46] = var(43); // [ var(46) , var(5) ]
+                D[10,46] = (-1)*var(42); // [ var(46) , var(10) ]
+                D[12,46] = var(38); // [ var(46) , var(12) ]
+                D[13,46] = var(39); // [ var(46) , var(13) ]
+                D[14,46] = (-1)*var(36); // [ var(46) , var(14) ]
+                D[15,46] = (-1)*var(37); // [ var(46) , var(15) ]
+                D[18,46] = var(34); // [ var(46) , var(18) ]
+                D[19,46] = (-1)*var(29); // [ var(46) , var(19) ]
+                D[21,46] = var(27); // [ var(46) , var(21) ]
+                D[22,46] = (-1)*var(49)+(-1)*var(50)+(-2)*var(51)+(-2)*var(52); // [ var(46) , var(22) ]
+                D[23,46] = (-1)*var(4); // [ var(46) , var(23) ]
+                D[24,46] = var(6); // [ var(46) , var(24) ]
+                D[4,47] = var(46); // [ var(47) , var(4) ]
+                D[7,47] = (-1)*var(45); // [ var(47) , var(7) ]
+                D[8,47] = var(43); // [ var(47) , var(8) ]
+                D[10,47] = var(44); // [ var(47) , var(10) ]
+                D[12,47] = (-1)*var(41); // [ var(47) , var(12) ]
+                D[15,47] = var(40); // [ var(47) , var(15) ]
+                D[16,47] = (-1)*var(39); // [ var(47) , var(16) ]
+                D[17,47] = var(36); // [ var(47) , var(17) ]
+                D[19,47] = (-1)*var(32); // [ var(47) , var(19) ]
+                D[20,47] = (-1)*var(34); // [ var(47) , var(20) ]
+                D[21,47] = var(31); // [ var(47) , var(21) ]
+                D[22,47] = (-1)*var(28); // [ var(47) , var(22) ]
+                D[23,47] = (-1)*var(49)+(-1)*var(50)+(-2)*var(51)+(-3)*var(52); // [ var(47) , var(23) ]
+                D[24,47] = (-1)*var(2); // [ var(47) , var(24) ]
+                D[2,48] = var(47); // [ var(48) , var(2) ]
+                D[6,48] = (-1)*var(46); // [ var(48) , var(6) ]
+                D[9,48] = var(45); // [ var(48) , var(9) ]
+                D[11,48] = (-1)*var(43); // [ var(48) , var(11) ]
+                D[13,48] = (-1)*var(44); // [ var(48) , var(13) ]
+                D[14,48] = var(41); // [ var(48) , var(14) ]
+                D[16,48] = var(42); // [ var(48) , var(16) ]
+                D[17,48] = (-1)*var(38); // [ var(48) , var(17) ]
+                D[18,48] = (-1)*var(40); // [ var(48) , var(18) ]
+                D[19,48] = var(35); // [ var(48) , var(19) ]
+                D[20,48] = var(37); // [ var(48) , var(20) ]
+                D[21,48] = (-1)*var(33); // [ var(48) , var(21) ]
+                D[22,48] = var(30); // [ var(48) , var(22) ]
+                D[23,48] = (-1)*var(26); // [ var(48) , var(23) ]
+                D[24,48] = (-1)*var(49)+(-2)*var(50)+(-2)*var(51)+(-3)*var(52); // [ var(48) , var(24) ]
+        // X(i) * X(j):
+                D[1,3] = var(5); // [ var(3) , var(1) ]
+                D[1,7] = var(8); // [ var(7) , var(1) ]
+                D[1,9] = var(11); // [ var(9) , var(1) ]
+                D[1,10] = var(12); // [ var(10) , var(1) ]
+                D[1,12] = (2)*var(15); // [ var(12) , var(1) ]
+                D[1,13] = var(14); // [ var(13) , var(1) ]
+                D[1,14] = (2)*var(18); // [ var(14) , var(1) ]
+                D[1,16] = var(17); // [ var(16) , var(1) ]
+                D[1,17] = (2)*var(20); // [ var(17) , var(1) ]
+                D[1,19] = var(21); // [ var(19) , var(1) ]
+                D[2,4] = var(6); // [ var(4) , var(2) ]
+                D[2,7] = var(9); // [ var(7) , var(2) ]
+                D[2,8] = var(11); // [ var(8) , var(2) ]
+                D[2,10] = var(13); // [ var(10) , var(2) ]
+                D[2,12] = var(14); // [ var(12) , var(2) ]
+                D[2,15] = var(18); // [ var(15) , var(2) ]
+                D[2,23] = (-1)*var(24); // [ var(23) , var(2) ]
+                D[3,4] = var(7); // [ var(4) , var(3) ]
+                D[3,6] = var(9); // [ var(6) , var(3) ]
+                D[3,7] = (2)*var(10); // [ var(7) , var(3) ]
+                D[3,8] = var(12); // [ var(8) , var(3) ]
+                D[3,9] = (2)*var(13); // [ var(9) , var(3) ]
+                D[3,11] = var(14); // [ var(11) , var(3) ]
+                D[3,17] = var(19); // [ var(17) , var(3) ]
+                D[3,20] = var(21); // [ var(20) , var(3) ]
+                D[3,21] = (2)*var(22); // [ var(21) , var(3) ]
+                D[4,5] = (-1)*var(8); // [ var(5) , var(4) ]
+                D[4,13] = var(16); // [ var(13) , var(4) ]
+                D[4,14] = var(17); // [ var(14) , var(4) ]
+                D[4,18] = var(20); // [ var(18) , var(4) ]
+                D[4,22] = (-1)*var(23); // [ var(22) , var(4) ]
+                D[5,6] = var(11); // [ var(6) , var(5) ]
+                D[5,7] = var(12); // [ var(7) , var(5) ]
+                D[5,8] = (2)*var(15); // [ var(8) , var(5) ]
+                D[5,9] = var(14); // [ var(9) , var(5) ]
+                D[5,11] = (2)*var(18); // [ var(11) , var(5) ]
+                D[5,16] = (-1)*var(19); // [ var(16) , var(5) ]
+                D[5,17] = (-1)*var(21); // [ var(17) , var(5) ]
+                D[5,19] = (-2)*var(22); // [ var(19) , var(5) ]
+                D[6,10] = (-1)*var(16); // [ var(10) , var(6) ]
+                D[6,12] = (-1)*var(17); // [ var(12) , var(6) ]
+                D[6,15] = (-1)*var(20); // [ var(15) , var(6) ]
+                D[6,22] = var(24); // [ var(22) , var(6) ]
+                D[7,9] = (-2)*var(16); // [ var(9) , var(7) ]
+                D[7,11] = (-1)*var(17); // [ var(11) , var(7) ]
+                D[7,14] = var(19); // [ var(14) , var(7) ]
+                D[7,18] = var(21); // [ var(18) , var(7) ]
+                D[7,21] = (2)*var(23); // [ var(21) , var(7) ]
+                D[8,9] = (-1)*var(17); // [ var(9) , var(8) ]
+                D[8,11] = (-2)*var(20); // [ var(11) , var(8) ]
+                D[8,13] = (-1)*var(19); // [ var(13) , var(8) ]
+                D[8,14] = (-1)*var(21); // [ var(14) , var(8) ]
+                D[8,19] = (-2)*var(23); // [ var(19) , var(8) ]
+                D[9,12] = (-1)*var(19); // [ var(12) , var(9) ]
+                D[9,15] = (-1)*var(21); // [ var(15) , var(9) ]
+                D[9,21] = (-2)*var(24); // [ var(21) , var(9) ]
+                D[10,11] = (-1)*var(19); // [ var(11) , var(10) ]
+                D[10,18] = var(22); // [ var(18) , var(10) ]
+                D[10,20] = (-1)*var(23); // [ var(20) , var(10) ]
+                D[11,12] = var(21); // [ var(12) , var(11) ]
+                D[11,19] = (2)*var(24); // [ var(19) , var(11) ]
+                D[12,14] = (-2)*var(22); // [ var(14) , var(12) ]
+                D[12,17] = (2)*var(23); // [ var(17) , var(12) ]
+                D[13,15] = (-1)*var(22); // [ var(15) , var(13) ]
+                D[13,20] = var(24); // [ var(20) , var(13) ]
+                D[14,17] = (-2)*var(24); // [ var(17) , var(14) ]
+                D[15,16] = (-1)*var(23); // [ var(16) , var(15) ]
+                D[16,18] = (-1)*var(24); // [ var(18) , var(16) ]
+        // Y(i) * Y(j):
+                D[25,27] = (-1)*var(29); // [ var(27) , var(25) ]
+                D[25,31] = (-1)*var(32); // [ var(31) , var(25) ]
+                D[25,33] = (-1)*var(35); // [ var(33) , var(25) ]
+                D[25,34] = (-1)*var(36); // [ var(34) , var(25) ]
+                D[25,36] = (-2)*var(39); // [ var(36) , var(25) ]
+                D[25,37] = (-1)*var(38); // [ var(37) , var(25) ]
+                D[25,38] = (-2)*var(42); // [ var(38) , var(25) ]
+                D[25,40] = (-1)*var(41); // [ var(40) , var(25) ]
+                D[25,41] = (-2)*var(44); // [ var(41) , var(25) ]
+                D[25,43] = (-1)*var(45); // [ var(43) , var(25) ]
+                D[26,28] = (-1)*var(30); // [ var(28) , var(26) ]
+                D[26,31] = (-1)*var(33); // [ var(31) , var(26) ]
+                D[26,32] = (-1)*var(35); // [ var(32) , var(26) ]
+                D[26,34] = (-1)*var(37); // [ var(34) , var(26) ]
+                D[26,36] = (-1)*var(38); // [ var(36) , var(26) ]
+                D[26,39] = (-1)*var(42); // [ var(39) , var(26) ]
+                D[26,47] = var(48); // [ var(47) , var(26) ]
+                D[27,28] = (-1)*var(31); // [ var(28) , var(27) ]
+                D[27,30] = (-1)*var(33); // [ var(30) , var(27) ]
+                D[27,31] = (-2)*var(34); // [ var(31) , var(27) ]
+                D[27,32] = (-1)*var(36); // [ var(32) , var(27) ]
+                D[27,33] = (-2)*var(37); // [ var(33) , var(27) ]
+                D[27,35] = (-1)*var(38); // [ var(35) , var(27) ]
+                D[27,41] = (-1)*var(43); // [ var(41) , var(27) ]
+                D[27,44] = (-1)*var(45); // [ var(44) , var(27) ]
+                D[27,45] = (-2)*var(46); // [ var(45) , var(27) ]
+                D[28,29] = var(32); // [ var(29) , var(28) ]
+                D[28,37] = (-1)*var(40); // [ var(37) , var(28) ]
+                D[28,38] = (-1)*var(41); // [ var(38) , var(28) ]
+                D[28,42] = (-1)*var(44); // [ var(42) , var(28) ]
+                D[28,46] = var(47); // [ var(46) , var(28) ]
+                D[29,30] = (-1)*var(35); // [ var(30) , var(29) ]
+                D[29,31] = (-1)*var(36); // [ var(31) , var(29) ]
+                D[29,32] = (-2)*var(39); // [ var(32) , var(29) ]
+                D[29,33] = (-1)*var(38); // [ var(33) , var(29) ]
+                D[29,35] = (-2)*var(42); // [ var(35) , var(29) ]
+                D[29,40] = var(43); // [ var(40) , var(29) ]
+                D[29,41] = var(45); // [ var(41) , var(29) ]
+                D[29,43] = (2)*var(46); // [ var(43) , var(29) ]
+                D[30,34] = var(40); // [ var(34) , var(30) ]
+                D[30,36] = var(41); // [ var(36) , var(30) ]
+                D[30,39] = var(44); // [ var(39) , var(30) ]
+                D[30,46] = (-1)*var(48); // [ var(46) , var(30) ]
+                D[31,33] = (2)*var(40); // [ var(33) , var(31) ]
+                D[31,35] = var(41); // [ var(35) , var(31) ]
+                D[31,38] = (-1)*var(43); // [ var(38) , var(31) ]
+                D[31,42] = (-1)*var(45); // [ var(42) , var(31) ]
+                D[31,45] = (-2)*var(47); // [ var(45) , var(31) ]
+                D[32,33] = var(41); // [ var(33) , var(32) ]
+                D[32,35] = (2)*var(44); // [ var(35) , var(32) ]
+                D[32,37] = var(43); // [ var(37) , var(32) ]
+                D[32,38] = var(45); // [ var(38) , var(32) ]
+                D[32,43] = (2)*var(47); // [ var(43) , var(32) ]
+                D[33,36] = var(43); // [ var(36) , var(33) ]
+                D[33,39] = var(45); // [ var(39) , var(33) ]
+                D[33,45] = (2)*var(48); // [ var(45) , var(33) ]
+                D[34,35] = var(43); // [ var(35) , var(34) ]
+                D[34,42] = (-1)*var(46); // [ var(42) , var(34) ]
+                D[34,44] = var(47); // [ var(44) , var(34) ]
+                D[35,36] = (-1)*var(45); // [ var(36) , var(35) ]
+                D[35,43] = (-2)*var(48); // [ var(43) , var(35) ]
+                D[36,38] = (2)*var(46); // [ var(38) , var(36) ]
+                D[36,41] = (-2)*var(47); // [ var(41) , var(36) ]
+                D[37,39] = var(46); // [ var(39) , var(37) ]
+                D[37,44] = (-1)*var(48); // [ var(44) , var(37) ]
+                D[38,41] = (2)*var(48); // [ var(41) , var(38) ]
+                D[39,40] = var(47); // [ var(40) , var(39) ]
+                D[40,42] = var(48); // [ var(42) , var(40) ]
+   def @@RR=nc_algebra(1,D);
+   return(@@RR);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   def ncAlgebra = makeUf4();
+   ncAlgebra;
+   setring ncAlgebra;
+   // ...  552  noncommutative relations
+}
+////////////////////////////////////////////////////////////////////
+
+// Algebra: e6(Q) has the type: E6, and defined by:
+
+proc makeUe6(list #)
+"USAGE:   makeUe6([p]); p an optional integer (field characteristic)
+RETURN:  a ring, describing U(e_6)
+NOTE:    You have to activate this ring with the 'setring' command. The presentation of U(e_6) is derived from the Chevalley representation of e_6, positive resp. negative roots are denoted by x(i) resp. y(i); Cartan elements are denoted by h(i).
+SEE ALSO: makeUsl, makeUso5, makeUsp1, makeUe6, makeUe7, makeUe8, makeUg2, makeUf4
+EXAMPLE: example makeUe6; shows examples
+"
+{
+   int @p = defInt(#);
+
+   ring @@@rrr = @p,(X(1..36),Y(1..36),H(1..6)),dp;
+   int N = nvars(@@@rrr);
+   matrix D[N][N]=0;
+
+        // H(i) * X(j):
+                D[1,73] = (2)*var(1); // [ var(73) , var(1) ]
+                D[3,73] = (-1)*var(3); // [ var(73) , var(3) ]
+                D[7,73] = var(7); // [ var(73) , var(7) ]
+                D[9,73] = (-1)*var(9); // [ var(73) , var(9) ]
+                D[12,73] = var(12); // [ var(73) , var(12) ]
+                D[13,73] = (-1)*var(13); // [ var(73) , var(13) ]
+                D[15,73] = (-1)*var(15); // [ var(73) , var(15) ]
+                D[17,73] = var(17); // [ var(73) , var(17) ]
+                D[18,73] = var(18); // [ var(73) , var(18) ]
+                D[19,73] = (-1)*var(19); // [ var(73) , var(19) ]
+                D[21,73] = (-1)*var(21); // [ var(73) , var(21) ]
+                D[22,73] = var(22); // [ var(73) , var(22) ]
+                D[23,73] = var(23); // [ var(73) , var(23) ]
+                D[24,73] = (-1)*var(24); // [ var(73) , var(24) ]
+                D[25,73] = (-1)*var(25); // [ var(73) , var(25) ]
+                D[26,73] = var(26); // [ var(73) , var(26) ]
+                D[27,73] = var(27); // [ var(73) , var(27) ]
+                D[28,73] = (-1)*var(28); // [ var(73) , var(28) ]
+                D[30,73] = var(30); // [ var(73) , var(30) ]
+                D[31,73] = (-1)*var(31); // [ var(73) , var(31) ]
+                D[33,73] = var(33); // [ var(73) , var(33) ]
+                D[2,74] = (2)*var(2); // [ var(74) , var(2) ]
+                D[4,74] = (-1)*var(4); // [ var(74) , var(4) ]
+                D[8,74] = var(8); // [ var(74) , var(8) ]
+                D[9,74] = (-1)*var(9); // [ var(74) , var(9) ]
+                D[10,74] = (-1)*var(10); // [ var(74) , var(10) ]
+                D[12,74] = (-1)*var(12); // [ var(74) , var(12) ]
+                D[13,74] = var(13); // [ var(74) , var(13) ]
+                D[14,74] = var(14); // [ var(74) , var(14) ]
+                D[15,74] = (-1)*var(15); // [ var(74) , var(15) ]
+                D[16,74] = (-1)*var(16); // [ var(74) , var(16) ]
+                D[17,74] = var(17); // [ var(74) , var(17) ]
+                D[18,74] = (-1)*var(18); // [ var(74) , var(18) ]
+                D[19,74] = var(19); // [ var(74) , var(19) ]
+                D[20,74] = var(20); // [ var(74) , var(20) ]
+                D[21,74] = (-1)*var(21); // [ var(74) , var(21) ]
+                D[22,74] = var(22); // [ var(74) , var(22) ]
+                D[23,74] = (-1)*var(23); // [ var(74) , var(23) ]
+                D[25,74] = var(25); // [ var(74) , var(25) ]
+                D[27,74] = var(27); // [ var(74) , var(27) ]
+                D[35,74] = (-1)*var(35); // [ var(74) , var(35) ]
+                D[36,74] = var(36); // [ var(74) , var(36) ]
+                D[1,75] = (-1)*var(1); // [ var(75) , var(1) ]
+                D[3,75] = (2)*var(3); // [ var(75) , var(3) ]
+                D[4,75] = (-1)*var(4); // [ var(75) , var(4) ]
+                D[7,75] = var(7); // [ var(75) , var(7) ]
+                D[8,75] = (-1)*var(8); // [ var(75) , var(8) ]
+                D[9,75] = var(9); // [ var(75) , var(9) ]
+                D[10,75] = (-1)*var(10); // [ var(75) , var(10) ]
+                D[13,75] = var(13); // [ var(75) , var(13) ]
+                D[14,75] = (-1)*var(14); // [ var(75) , var(14) ]
+                D[15,75] = var(15); // [ var(75) , var(15) ]
+                D[16,75] = (-1)*var(16); // [ var(75) , var(16) ]
+                D[19,75] = var(19); // [ var(75) , var(19) ]
+                D[20,75] = (-1)*var(20); // [ var(75) , var(20) ]
+                D[21,75] = var(21); // [ var(75) , var(21) ]
+                D[25,75] = var(25); // [ var(75) , var(25) ]
+                D[26,75] = (-1)*var(26); // [ var(75) , var(26) ]
+                D[29,75] = var(29); // [ var(75) , var(29) ]
+                D[30,75] = (-1)*var(30); // [ var(75) , var(30) ]
+                D[32,75] = var(32); // [ var(75) , var(32) ]
+                D[33,75] = (-1)*var(33); // [ var(75) , var(33) ]
+                D[34,75] = var(34); // [ var(75) , var(34) ]
+                D[2,76] = (-1)*var(2); // [ var(76) , var(2) ]
+                D[3,76] = (-1)*var(3); // [ var(76) , var(3) ]
+                D[4,76] = (2)*var(4); // [ var(76) , var(4) ]
+                D[5,76] = (-1)*var(5); // [ var(76) , var(5) ]
+                D[7,76] = (-1)*var(7); // [ var(76) , var(7) ]
+                D[8,76] = var(8); // [ var(76) , var(8) ]
+                D[9,76] = var(9); // [ var(76) , var(9) ]
+                D[10,76] = var(10); // [ var(76) , var(10) ]
+                D[11,76] = (-1)*var(11); // [ var(76) , var(11) ]
+                D[12,76] = var(12); // [ var(76) , var(12) ]
+                D[16,76] = var(16); // [ var(76) , var(16) ]
+                D[19,76] = (-1)*var(19); // [ var(76) , var(19) ]
+                D[22,76] = (-1)*var(22); // [ var(76) , var(22) ]
+                D[24,76] = var(24); // [ var(76) , var(24) ]
+                D[25,76] = (-1)*var(25); // [ var(76) , var(25) ]
+                D[26,76] = var(26); // [ var(76) , var(26) ]
+                D[27,76] = (-1)*var(27); // [ var(76) , var(27) ]
+                D[28,76] = var(28); // [ var(76) , var(28) ]
+                D[30,76] = var(30); // [ var(76) , var(30) ]
+                D[34,76] = (-1)*var(34); // [ var(76) , var(34) ]
+                D[35,76] = var(35); // [ var(76) , var(35) ]
+                D[4,77] = (-1)*var(4); // [ var(77) , var(4) ]
+                D[5,77] = (2)*var(5); // [ var(77) , var(5) ]
+                D[6,77] = (-1)*var(6); // [ var(77) , var(6) ]
+                D[8,77] = (-1)*var(8); // [ var(77) , var(8) ]
+                D[9,77] = (-1)*var(9); // [ var(77) , var(9) ]
+                D[10,77] = var(10); // [ var(77) , var(10) ]
+                D[11,77] = var(11); // [ var(77) , var(11) ]
+                D[12,77] = (-1)*var(12); // [ var(77) , var(12) ]
+                D[13,77] = (-1)*var(13); // [ var(77) , var(13) ]
+                D[14,77] = var(14); // [ var(77) , var(14) ]
+                D[15,77] = var(15); // [ var(77) , var(15) ]
+                D[17,77] = (-1)*var(17); // [ var(77) , var(17) ]
+                D[18,77] = var(18); // [ var(77) , var(18) ]
+                D[19,77] = var(19); // [ var(77) , var(19) ]
+                D[22,77] = var(22); // [ var(77) , var(22) ]
+                D[28,77] = (-1)*var(28); // [ var(77) , var(28) ]
+                D[30,77] = (-1)*var(30); // [ var(77) , var(30) ]
+                D[31,77] = var(31); // [ var(77) , var(31) ]
+                D[32,77] = (-1)*var(32); // [ var(77) , var(32) ]
+                D[33,77] = var(33); // [ var(77) , var(33) ]
+                D[34,77] = var(34); // [ var(77) , var(34) ]
+                D[5,78] = (-1)*var(5); // [ var(78) , var(5) ]
+                D[6,78] = (2)*var(6); // [ var(78) , var(6) ]
+                D[10,78] = (-1)*var(10); // [ var(78) , var(10) ]
+                D[11,78] = var(11); // [ var(78) , var(11) ]
+                D[14,78] = (-1)*var(14); // [ var(78) , var(14) ]
+                D[15,78] = (-1)*var(15); // [ var(78) , var(15) ]
+                D[16,78] = var(16); // [ var(78) , var(16) ]
+                D[18,78] = (-1)*var(18); // [ var(78) , var(18) ]
+                D[19,78] = (-1)*var(19); // [ var(78) , var(19) ]
+                D[20,78] = var(20); // [ var(78) , var(20) ]
+                D[21,78] = var(21); // [ var(78) , var(21) ]
+                D[22,78] = (-1)*var(22); // [ var(78) , var(22) ]
+                D[23,78] = var(23); // [ var(78) , var(23) ]
+                D[24,78] = (-1)*var(24); // [ var(78) , var(24) ]
+                D[25,78] = var(25); // [ var(78) , var(25) ]
+                D[26,78] = (-1)*var(26); // [ var(78) , var(26) ]
+                D[27,78] = var(27); // [ var(78) , var(27) ]
+                D[28,78] = var(28); // [ var(78) , var(28) ]
+                D[29,78] = (-1)*var(29); // [ var(78) , var(29) ]
+                D[30,78] = var(30); // [ var(78) , var(30) ]
+                D[32,78] = var(32); // [ var(78) , var(32) ]
+        // H(i) * Y(j):
+                D[37,73] = (-2)*var(37); // [ var(73) , var(37) ]
+                D[39,73] = var(39); // [ var(73) , var(39) ]
+                D[43,73] = (-1)*var(43); // [ var(73) , var(43) ]
+                D[45,73] = var(45); // [ var(73) , var(45) ]
+                D[48,73] = (-1)*var(48); // [ var(73) , var(48) ]
+                D[49,73] = var(49); // [ var(73) , var(49) ]
+                D[51,73] = var(51); // [ var(73) , var(51) ]
+                D[53,73] = (-1)*var(53); // [ var(73) , var(53) ]
+                D[54,73] = (-1)*var(54); // [ var(73) , var(54) ]
+                D[55,73] = var(55); // [ var(73) , var(55) ]
+                D[57,73] = var(57); // [ var(73) , var(57) ]
+                D[58,73] = (-1)*var(58); // [ var(73) , var(58) ]
+                D[59,73] = (-1)*var(59); // [ var(73) , var(59) ]
+                D[60,73] = var(60); // [ var(73) , var(60) ]
+                D[61,73] = var(61); // [ var(73) , var(61) ]
+                D[62,73] = (-1)*var(62); // [ var(73) , var(62) ]
+                D[63,73] = (-1)*var(63); // [ var(73) , var(63) ]
+                D[64,73] = var(64); // [ var(73) , var(64) ]
+                D[66,73] = (-1)*var(66); // [ var(73) , var(66) ]
+                D[67,73] = var(67); // [ var(73) , var(67) ]
+                D[69,73] = (-1)*var(69); // [ var(73) , var(69) ]
+                D[38,74] = (-2)*var(38); // [ var(74) , var(38) ]
+                D[40,74] = var(40); // [ var(74) , var(40) ]
+                D[44,74] = (-1)*var(44); // [ var(74) , var(44) ]
+                D[45,74] = var(45); // [ var(74) , var(45) ]
+                D[46,74] = var(46); // [ var(74) , var(46) ]
+                D[48,74] = var(48); // [ var(74) , var(48) ]
+                D[49,74] = (-1)*var(49); // [ var(74) , var(49) ]
+                D[50,74] = (-1)*var(50); // [ var(74) , var(50) ]
+                D[51,74] = var(51); // [ var(74) , var(51) ]
+                D[52,74] = var(52); // [ var(74) , var(52) ]
+                D[53,74] = (-1)*var(53); // [ var(74) , var(53) ]
+                D[54,74] = var(54); // [ var(74) , var(54) ]
+                D[55,74] = (-1)*var(55); // [ var(74) , var(55) ]
+                D[56,74] = (-1)*var(56); // [ var(74) , var(56) ]
+                D[57,74] = var(57); // [ var(74) , var(57) ]
+                D[58,74] = (-1)*var(58); // [ var(74) , var(58) ]
+                D[59,74] = var(59); // [ var(74) , var(59) ]
+                D[61,74] = (-1)*var(61); // [ var(74) , var(61) ]
+                D[63,74] = (-1)*var(63); // [ var(74) , var(63) ]
+                D[71,74] = var(71); // [ var(74) , var(71) ]
+                D[72,74] = (-1)*var(72); // [ var(74) , var(72) ]
+                D[37,75] = var(37); // [ var(75) , var(37) ]
+                D[39,75] = (-2)*var(39); // [ var(75) , var(39) ]
+                D[40,75] = var(40); // [ var(75) , var(40) ]
+                D[43,75] = (-1)*var(43); // [ var(75) , var(43) ]
+                D[44,75] = var(44); // [ var(75) , var(44) ]
+                D[45,75] = (-1)*var(45); // [ var(75) , var(45) ]
+                D[46,75] = var(46); // [ var(75) , var(46) ]
+                D[49,75] = (-1)*var(49); // [ var(75) , var(49) ]
+                D[50,75] = var(50); // [ var(75) , var(50) ]
+                D[51,75] = (-1)*var(51); // [ var(75) , var(51) ]
+                D[52,75] = var(52); // [ var(75) , var(52) ]
+                D[55,75] = (-1)*var(55); // [ var(75) , var(55) ]
+                D[56,75] = var(56); // [ var(75) , var(56) ]
+                D[57,75] = (-1)*var(57); // [ var(75) , var(57) ]
+                D[61,75] = (-1)*var(61); // [ var(75) , var(61) ]
+                D[62,75] = var(62); // [ var(75) , var(62) ]
+                D[65,75] = (-1)*var(65); // [ var(75) , var(65) ]
+                D[66,75] = var(66); // [ var(75) , var(66) ]
+                D[68,75] = (-1)*var(68); // [ var(75) , var(68) ]
+                D[69,75] = var(69); // [ var(75) , var(69) ]
+                D[70,75] = (-1)*var(70); // [ var(75) , var(70) ]
+                D[38,76] = var(38); // [ var(76) , var(38) ]
+                D[39,76] = var(39); // [ var(76) , var(39) ]
+                D[40,76] = (-2)*var(40); // [ var(76) , var(40) ]
+                D[41,76] = var(41); // [ var(76) , var(41) ]
+                D[43,76] = var(43); // [ var(76) , var(43) ]
+                D[44,76] = (-1)*var(44); // [ var(76) , var(44) ]
+                D[45,76] = (-1)*var(45); // [ var(76) , var(45) ]
+                D[46,76] = (-1)*var(46); // [ var(76) , var(46) ]
+                D[47,76] = var(47); // [ var(76) , var(47) ]
+                D[48,76] = (-1)*var(48); // [ var(76) , var(48) ]
+                D[52,76] = (-1)*var(52); // [ var(76) , var(52) ]
+                D[55,76] = var(55); // [ var(76) , var(55) ]
+                D[58,76] = var(58); // [ var(76) , var(58) ]
+                D[60,76] = (-1)*var(60); // [ var(76) , var(60) ]
+                D[61,76] = var(61); // [ var(76) , var(61) ]
+                D[62,76] = (-1)*var(62); // [ var(76) , var(62) ]
+                D[63,76] = var(63); // [ var(76) , var(63) ]
+                D[64,76] = (-1)*var(64); // [ var(76) , var(64) ]
+                D[66,76] = (-1)*var(66); // [ var(76) , var(66) ]
+                D[70,76] = var(70); // [ var(76) , var(70) ]
+                D[71,76] = (-1)*var(71); // [ var(76) , var(71) ]
+                D[40,77] = var(40); // [ var(77) , var(40) ]
+                D[41,77] = (-2)*var(41); // [ var(77) , var(41) ]
+                D[42,77] = var(42); // [ var(77) , var(42) ]
+                D[44,77] = var(44); // [ var(77) , var(44) ]
+                D[45,77] = var(45); // [ var(77) , var(45) ]
+                D[46,77] = (-1)*var(46); // [ var(77) , var(46) ]
+                D[47,77] = (-1)*var(47); // [ var(77) , var(47) ]
+                D[48,77] = var(48); // [ var(77) , var(48) ]
+                D[49,77] = var(49); // [ var(77) , var(49) ]
+                D[50,77] = (-1)*var(50); // [ var(77) , var(50) ]
+                D[51,77] = (-1)*var(51); // [ var(77) , var(51) ]
+                D[53,77] = var(53); // [ var(77) , var(53) ]
+                D[54,77] = (-1)*var(54); // [ var(77) , var(54) ]
+                D[55,77] = (-1)*var(55); // [ var(77) , var(55) ]
+                D[58,77] = (-1)*var(58); // [ var(77) , var(58) ]
+                D[64,77] = var(64); // [ var(77) , var(64) ]
+                D[66,77] = var(66); // [ var(77) , var(66) ]
+                D[67,77] = (-1)*var(67); // [ var(77) , var(67) ]
+                D[68,77] = var(68); // [ var(77) , var(68) ]
+                D[69,77] = (-1)*var(69); // [ var(77) , var(69) ]
+                D[70,77] = (-1)*var(70); // [ var(77) , var(70) ]
+                D[41,78] = var(41); // [ var(78) , var(41) ]
+                D[42,78] = (-2)*var(42); // [ var(78) , var(42) ]
+                D[46,78] = var(46); // [ var(78) , var(46) ]
+                D[47,78] = (-1)*var(47); // [ var(78) , var(47) ]
+                D[50,78] = var(50); // [ var(78) , var(50) ]
+                D[51,78] = var(51); // [ var(78) , var(51) ]
+                D[52,78] = (-1)*var(52); // [ var(78) , var(52) ]
+                D[54,78] = var(54); // [ var(78) , var(54) ]
+                D[55,78] = var(55); // [ var(78) , var(55) ]
+                D[56,78] = (-1)*var(56); // [ var(78) , var(56) ]
+                D[57,78] = (-1)*var(57); // [ var(78) , var(57) ]
+                D[58,78] = var(58); // [ var(78) , var(58) ]
+                D[59,78] = (-1)*var(59); // [ var(78) , var(59) ]
+                D[60,78] = var(60); // [ var(78) , var(60) ]
+                D[61,78] = (-1)*var(61); // [ var(78) , var(61) ]
+                D[62,78] = var(62); // [ var(78) , var(62) ]
+                D[63,78] = (-1)*var(63); // [ var(78) , var(63) ]
+                D[64,78] = (-1)*var(64); // [ var(78) , var(64) ]
+                D[65,78] = var(65); // [ var(78) , var(65) ]
+                D[66,78] = (-1)*var(66); // [ var(78) , var(66) ]
+                D[68,78] = (-1)*var(68); // [ var(78) , var(68) ]
+        // Y(i) * X(j):
+                D[1,37] = (-1)*var(73); // [ var(37) , var(1) ]
+                D[7,37] = (-1)*var(3); // [ var(37) , var(7) ]
+                D[12,37] = (-1)*var(9); // [ var(37) , var(12) ]
+                D[17,37] = (-1)*var(13); // [ var(37) , var(17) ]
+                D[18,37] = (-1)*var(15); // [ var(37) , var(18) ]
+                D[22,37] = (-1)*var(19); // [ var(37) , var(22) ]
+                D[23,37] = (-1)*var(21); // [ var(37) , var(23) ]
+                D[26,37] = (-1)*var(24); // [ var(37) , var(26) ]
+                D[27,37] = (-1)*var(25); // [ var(37) , var(27) ]
+                D[30,37] = (-1)*var(28); // [ var(37) , var(30) ]
+                D[33,37] = (-1)*var(31); // [ var(37) , var(33) ]
+                D[2,38] = (-1)*var(74); // [ var(38) , var(2) ]
+                D[8,38] = (-1)*var(4); // [ var(38) , var(8) ]
+                D[13,38] = (-1)*var(9); // [ var(38) , var(13) ]
+                D[14,38] = (-1)*var(10); // [ var(38) , var(14) ]
+                D[17,38] = (-1)*var(12); // [ var(38) , var(17) ]
+                D[19,38] = (-1)*var(15); // [ var(38) , var(19) ]
+                D[20,38] = (-1)*var(16); // [ var(38) , var(20) ]
+                D[22,38] = (-1)*var(18); // [ var(38) , var(22) ]
+                D[25,38] = (-1)*var(21); // [ var(38) , var(25) ]
+                D[27,38] = (-1)*var(23); // [ var(38) , var(27) ]
+                D[36,38] = var(35); // [ var(38) , var(36) ]
+                D[3,39] = (-1)*var(75); // [ var(39) , var(3) ]
+                D[7,39] = var(1); // [ var(39) , var(7) ]
+                D[9,39] = (-1)*var(4); // [ var(39) , var(9) ]
+                D[13,39] = (-1)*var(8); // [ var(39) , var(13) ]
+                D[15,39] = (-1)*var(10); // [ var(39) , var(15) ]
+                D[19,39] = (-1)*var(14); // [ var(39) , var(19) ]
+                D[21,39] = (-1)*var(16); // [ var(39) , var(21) ]
+                D[25,39] = (-1)*var(20); // [ var(39) , var(25) ]
+                D[29,39] = (-1)*var(26); // [ var(39) , var(29) ]
+                D[32,39] = (-1)*var(30); // [ var(39) , var(32) ]
+                D[34,39] = (-1)*var(33); // [ var(39) , var(34) ]
+                D[4,40] = (-1)*var(76); // [ var(40) , var(4) ]
+                D[8,40] = var(2); // [ var(40) , var(8) ]
+                D[9,40] = var(3); // [ var(40) , var(9) ]
+                D[10,40] = (-1)*var(5); // [ var(40) , var(10) ]
+                D[12,40] = var(7); // [ var(40) , var(12) ]
+                D[16,40] = (-1)*var(11); // [ var(40) , var(16) ]
+                D[24,40] = var(19); // [ var(40) , var(24) ]
+                D[26,40] = var(22); // [ var(40) , var(26) ]
+                D[28,40] = var(25); // [ var(40) , var(28) ]
+                D[30,40] = var(27); // [ var(40) , var(30) ]
+                D[35,40] = var(34); // [ var(40) , var(35) ]
+                D[5,41] = (-1)*var(77); // [ var(41) , var(5) ]
+                D[10,41] = var(4); // [ var(41) , var(10) ]
+                D[11,41] = (-1)*var(6); // [ var(41) , var(11) ]
+                D[14,41] = var(8); // [ var(41) , var(14) ]
+                D[15,41] = var(9); // [ var(41) , var(15) ]
+                D[18,41] = var(12); // [ var(41) , var(18) ]
+                D[19,41] = var(13); // [ var(41) , var(19) ]
+                D[22,41] = var(17); // [ var(41) , var(22) ]
+                D[31,41] = var(28); // [ var(41) , var(31) ]
+                D[33,41] = var(30); // [ var(41) , var(33) ]
+                D[34,41] = var(32); // [ var(41) , var(34) ]
+                D[6,42] = (-1)*var(78); // [ var(42) , var(6) ]
+                D[11,42] = var(5); // [ var(42) , var(11) ]
+                D[16,42] = var(10); // [ var(42) , var(16) ]
+                D[20,42] = var(14); // [ var(42) , var(20) ]
+                D[21,42] = var(15); // [ var(42) , var(21) ]
+                D[23,42] = var(18); // [ var(42) , var(23) ]
+                D[25,42] = var(19); // [ var(42) , var(25) ]
+                D[27,42] = var(22); // [ var(42) , var(27) ]
+                D[28,42] = var(24); // [ var(42) , var(28) ]
+                D[30,42] = var(26); // [ var(42) , var(30) ]
+                D[32,42] = var(29); // [ var(42) , var(32) ]
+                D[1,43] = (-1)*var(39); // [ var(43) , var(1) ]
+                D[3,43] = var(37); // [ var(43) , var(3) ]
+                D[7,43] = (-1)*var(73)+(-1)*var(75); // [ var(43) , var(7) ]
+                D[12,43] = (-1)*var(4); // [ var(43) , var(12) ]
+                D[17,43] = (-1)*var(8); // [ var(43) , var(17) ]
+                D[18,43] = (-1)*var(10); // [ var(43) , var(18) ]
+                D[22,43] = (-1)*var(14); // [ var(43) , var(22) ]
+                D[23,43] = (-1)*var(16); // [ var(43) , var(23) ]
+                D[27,43] = (-1)*var(20); // [ var(43) , var(27) ]
+                D[29,43] = var(24); // [ var(43) , var(29) ]
+                D[32,43] = var(28); // [ var(43) , var(32) ]
+                D[34,43] = var(31); // [ var(43) , var(34) ]
+                D[2,44] = (-1)*var(40); // [ var(44) , var(2) ]
+                D[4,44] = var(38); // [ var(44) , var(4) ]
+                D[8,44] = (-1)*var(74)+(-1)*var(76); // [ var(44) , var(8) ]
+                D[13,44] = var(3); // [ var(44) , var(13) ]
+                D[14,44] = (-1)*var(5); // [ var(44) , var(14) ]
+                D[17,44] = var(7); // [ var(44) , var(17) ]
+                D[20,44] = (-1)*var(11); // [ var(44) , var(20) ]
+                D[24,44] = (-1)*var(15); // [ var(44) , var(24) ]
+                D[26,44] = (-1)*var(18); // [ var(44) , var(26) ]
+                D[28,44] = (-1)*var(21); // [ var(44) , var(28) ]
+                D[30,44] = (-1)*var(23); // [ var(44) , var(30) ]
+                D[36,44] = (-1)*var(34); // [ var(44) , var(36) ]
+                D[3,45] = (-1)*var(40); // [ var(45) , var(3) ]
+                D[4,45] = var(39); // [ var(45) , var(4) ]
+                D[9,45] = (-1)*var(75)+(-1)*var(76); // [ var(45) , var(9) ]
+                D[12,45] = var(1); // [ var(45) , var(12) ]
+                D[13,45] = var(2); // [ var(45) , var(13) ]
+                D[15,45] = (-1)*var(5); // [ var(45) , var(15) ]
+                D[21,45] = (-1)*var(11); // [ var(45) , var(21) ]
+                D[24,45] = (-1)*var(14); // [ var(45) , var(24) ]
+                D[28,45] = (-1)*var(20); // [ var(45) , var(28) ]
+                D[29,45] = var(22); // [ var(45) , var(29) ]
+                D[32,45] = var(27); // [ var(45) , var(32) ]
+                D[35,45] = (-1)*var(33); // [ var(45) , var(35) ]
+                D[4,46] = (-1)*var(41); // [ var(46) , var(4) ]
+                D[5,46] = var(40); // [ var(46) , var(5) ]
+                D[10,46] = (-1)*var(76)+(-1)*var(77); // [ var(46) , var(10) ]
+                D[14,46] = var(2); // [ var(46) , var(14) ]
+                D[15,46] = var(3); // [ var(46) , var(15) ]
+                D[16,46] = (-1)*var(6); // [ var(46) , var(16) ]
+                D[18,46] = var(7); // [ var(46) , var(18) ]
+                D[24,46] = (-1)*var(13); // [ var(46) , var(24) ]
+                D[26,46] = (-1)*var(17); // [ var(46) , var(26) ]
+                D[31,46] = var(25); // [ var(46) , var(31) ]
+                D[33,46] = var(27); // [ var(46) , var(33) ]
+                D[35,46] = (-1)*var(32); // [ var(46) , var(35) ]
+                D[5,47] = (-1)*var(42); // [ var(47) , var(5) ]
+                D[6,47] = var(41); // [ var(47) , var(6) ]
+                D[11,47] = (-1)*var(77)+(-1)*var(78); // [ var(47) , var(11) ]
+                D[16,47] = var(4); // [ var(47) , var(16) ]
+                D[20,47] = var(8); // [ var(47) , var(20) ]
+                D[21,47] = var(9); // [ var(47) , var(21) ]
+                D[23,47] = var(12); // [ var(47) , var(23) ]
+                D[25,47] = var(13); // [ var(47) , var(25) ]
+                D[27,47] = var(17); // [ var(47) , var(27) ]
+                D[31,47] = (-1)*var(24); // [ var(47) , var(31) ]
+                D[33,47] = (-1)*var(26); // [ var(47) , var(33) ]
+                D[34,47] = (-1)*var(29); // [ var(47) , var(34) ]
+                D[1,48] = (-1)*var(45); // [ var(48) , var(1) ]
+                D[4,48] = var(43); // [ var(48) , var(4) ]
+                D[7,48] = (-1)*var(40); // [ var(48) , var(7) ]
+                D[9,48] = var(37); // [ var(48) , var(9) ]
+                D[12,48] = (-1)*var(73)+(-1)*var(75)+(-1)*var(76); // [ var(48) , var(12) ]
+                D[17,48] = var(2); // [ var(48) , var(17) ]
+                D[18,48] = (-1)*var(5); // [ var(48) , var(18) ]
+                D[23,48] = (-1)*var(11); // [ var(48) , var(23) ]
+                D[26,48] = (-1)*var(14); // [ var(48) , var(26) ]
+                D[29,48] = (-1)*var(19); // [ var(48) , var(29) ]
+                D[30,48] = (-1)*var(20); // [ var(48) , var(30) ]
+                D[32,48] = (-1)*var(25); // [ var(48) , var(32) ]
+                D[35,48] = var(31); // [ var(48) , var(35) ]
+                D[2,49] = (-1)*var(45); // [ var(49) , var(2) ]
+                D[3,49] = (-1)*var(44); // [ var(49) , var(3) ]
+                D[8,49] = var(39); // [ var(49) , var(8) ]
+                D[9,49] = var(38); // [ var(49) , var(9) ]
+                D[13,49] = (-1)*var(74)+(-1)*var(75)+(-1)*var(76); // [ var(49) , var(13) ]
+                D[17,49] = var(1); // [ var(49) , var(17) ]
+                D[19,49] = (-1)*var(5); // [ var(49) , var(19) ]
+                D[24,49] = var(10); // [ var(49) , var(24) ]
+                D[25,49] = (-1)*var(11); // [ var(49) , var(25) ]
+                D[28,49] = var(16); // [ var(49) , var(28) ]
+                D[29,49] = (-1)*var(18); // [ var(49) , var(29) ]
+                D[32,49] = (-1)*var(23); // [ var(49) , var(32) ]
+                D[36,49] = var(33); // [ var(49) , var(36) ]
+                D[2,50] = (-1)*var(46); // [ var(50) , var(2) ]
+                D[5,50] = var(44); // [ var(50) , var(5) ]
+                D[8,50] = (-1)*var(41); // [ var(50) , var(8) ]
+                D[10,50] = var(38); // [ var(50) , var(10) ]
+                D[14,50] = (-1)*var(74)+(-1)*var(76)+(-1)*var(77); // [ var(50) , var(14) ]
+                D[19,50] = var(3); // [ var(50) , var(19) ]
+                D[20,50] = (-1)*var(6); // [ var(50) , var(20) ]
+                D[22,50] = var(7); // [ var(50) , var(22) ]
+                D[24,50] = var(9); // [ var(50) , var(24) ]
+                D[26,50] = var(12); // [ var(50) , var(26) ]
+                D[31,50] = (-1)*var(21); // [ var(50) , var(31) ]
+                D[33,50] = (-1)*var(23); // [ var(50) , var(33) ]
+                D[36,50] = var(32); // [ var(50) , var(36) ]
+                D[3,51] = (-1)*var(46); // [ var(51) , var(3) ]
+                D[5,51] = var(45); // [ var(51) , var(5) ]
+                D[9,51] = (-1)*var(41); // [ var(51) , var(9) ]
+                D[10,51] = var(39); // [ var(51) , var(10) ]
+                D[15,51] = (-1)*var(75)+(-1)*var(76)+(-1)*var(77); // [ var(51) , var(15) ]
+                D[18,51] = var(1); // [ var(51) , var(18) ]
+                D[19,51] = var(2); // [ var(51) , var(19) ]
+                D[21,51] = (-1)*var(6); // [ var(51) , var(21) ]
+                D[24,51] = var(8); // [ var(51) , var(24) ]
+                D[29,51] = (-1)*var(17); // [ var(51) , var(29) ]
+                D[31,51] = (-1)*var(20); // [ var(51) , var(31) ]
+                D[34,51] = var(27); // [ var(51) , var(34) ]
+                D[35,51] = var(30); // [ var(51) , var(35) ]
+                D[4,52] = (-1)*var(47); // [ var(52) , var(4) ]
+                D[6,52] = var(46); // [ var(52) , var(6) ]
+                D[10,52] = (-1)*var(42); // [ var(52) , var(10) ]
+                D[11,52] = var(40); // [ var(52) , var(11) ]
+                D[16,52] = (-1)*var(76)+(-1)*var(77)+(-1)*var(78); // [ var(52) , var(16) ]
+                D[20,52] = var(2); // [ var(52) , var(20) ]
+                D[21,52] = var(3); // [ var(52) , var(21) ]
+                D[23,52] = var(7); // [ var(52) , var(23) ]
+                D[28,52] = (-1)*var(13); // [ var(52) , var(28) ]
+                D[30,52] = (-1)*var(17); // [ var(52) , var(30) ]
+                D[31,52] = (-1)*var(19); // [ var(52) , var(31) ]
+                D[33,52] = (-1)*var(22); // [ var(52) , var(33) ]
+                D[35,52] = var(29); // [ var(52) , var(35) ]
+                D[1,53] = (-1)*var(49); // [ var(53) , var(1) ]
+                D[2,53] = (-1)*var(48); // [ var(53) , var(2) ]
+                D[7,53] = (-1)*var(44); // [ var(53) , var(7) ]
+                D[8,53] = var(43); // [ var(53) , var(8) ]
+                D[12,53] = var(38); // [ var(53) , var(12) ]
+                D[13,53] = var(37); // [ var(53) , var(13) ]
+                D[17,53] = (-1)*var(73)+(-1)*var(74)+(-1)*var(75)+(-1)*var(76); // [ var(53) , var(17) ]
+                D[22,53] = (-1)*var(5); // [ var(53) , var(22) ]
+                D[26,53] = var(10); // [ var(53) , var(26) ]
+                D[27,53] = (-1)*var(11); // [ var(53) , var(27) ]
+                D[29,53] = var(15); // [ var(53) , var(29) ]
+                D[30,53] = var(16); // [ var(53) , var(30) ]
+                D[32,53] = var(21); // [ var(53) , var(32) ]
+                D[36,53] = (-1)*var(31); // [ var(53) , var(36) ]
+                D[1,54] = (-1)*var(51); // [ var(54) , var(1) ]
+                D[5,54] = var(48); // [ var(54) , var(5) ]
+                D[7,54] = (-1)*var(46); // [ var(54) , var(7) ]
+                D[10,54] = var(43); // [ var(54) , var(10) ]
+                D[12,54] = (-1)*var(41); // [ var(54) , var(12) ]
+                D[15,54] = var(37); // [ var(54) , var(15) ]
+                D[18,54] = (-1)*var(73)+(-1)*var(75)+(-1)*var(76)+(-1)*var(77); // [ var(54) , var(18) ]
+                D[22,54] = var(2); // [ var(54) , var(22) ]
+                D[23,54] = (-1)*var(6); // [ var(54) , var(23) ]
+                D[26,54] = var(8); // [ var(54) , var(26) ]
+                D[29,54] = var(13); // [ var(54) , var(29) ]
+                D[33,54] = (-1)*var(20); // [ var(54) , var(33) ]
+                D[34,54] = (-1)*var(25); // [ var(54) , var(34) ]
+                D[35,54] = (-1)*var(28); // [ var(54) , var(35) ]
+                D[2,55] = (-1)*var(51); // [ var(55) , var(2) ]
+                D[3,55] = (-1)*var(50); // [ var(55) , var(3) ]
+                D[5,55] = var(49); // [ var(55) , var(5) ]
+                D[13,55] = (-1)*var(41); // [ var(55) , var(13) ]
+                D[14,55] = var(39); // [ var(55) , var(14) ]
+                D[15,55] = var(38); // [ var(55) , var(15) ]
+                D[19,55] = (-1)*var(74)+(-1)*var(75)+(-1)*var(76)+(-1)*var(77); // [ var(55) , var(19) ]
+                D[22,55] = var(1); // [ var(55) , var(22) ]
+                D[24,55] = (-1)*var(4); // [ var(55) , var(24) ]
+                D[25,55] = (-1)*var(6); // [ var(55) , var(25) ]
+                D[29,55] = var(12); // [ var(55) , var(29) ]
+                D[31,55] = var(16); // [ var(55) , var(31) ]
+                D[34,55] = (-1)*var(23); // [ var(55) , var(34) ]
+                D[36,55] = (-1)*var(30); // [ var(55) , var(36) ]
+                D[2,56] = (-1)*var(52); // [ var(56) , var(2) ]
+                D[6,56] = var(50); // [ var(56) , var(6) ]
+                D[8,56] = (-1)*var(47); // [ var(56) , var(8) ]
+                D[11,56] = var(44); // [ var(56) , var(11) ]
+                D[14,56] = (-1)*var(42); // [ var(56) , var(14) ]
+                D[16,56] = var(38); // [ var(56) , var(16) ]
+                D[20,56] = (-1)*var(74)+(-1)*var(76)+(-1)*var(77)+(-1)*var(78); // [ var(56) , var(20) ]
+                D[25,56] = var(3); // [ var(56) , var(25) ]
+                D[27,56] = var(7); // [ var(56) , var(27) ]
+                D[28,56] = var(9); // [ var(56) , var(28) ]
+                D[30,56] = var(12); // [ var(56) , var(30) ]
+                D[31,56] = var(15); // [ var(56) , var(31) ]
+                D[33,56] = var(18); // [ var(56) , var(33) ]
+                D[36,56] = (-1)*var(29); // [ var(56) , var(36) ]
+                D[3,57] = (-1)*var(52); // [ var(57) , var(3) ]
+                D[6,57] = var(51); // [ var(57) , var(6) ]
+                D[9,57] = (-1)*var(47); // [ var(57) , var(9) ]
+                D[11,57] = var(45); // [ var(57) , var(11) ]
+                D[15,57] = (-1)*var(42); // [ var(57) , var(15) ]
+                D[16,57] = var(39); // [ var(57) , var(16) ]
+                D[21,57] = (-1)*var(75)+(-1)*var(76)+(-1)*var(77)+(-1)*var(78); // [ var(57) , var(21) ]
+                D[23,57] = var(1); // [ var(57) , var(23) ]
+                D[25,57] = var(2); // [ var(57) , var(25) ]
+                D[28,57] = var(8); // [ var(57) , var(28) ]
+                D[31,57] = var(14); // [ var(57) , var(31) ]
+                D[32,57] = (-1)*var(17); // [ var(57) , var(32) ]
+                D[34,57] = (-1)*var(22); // [ var(57) , var(34) ]
+                D[35,57] = (-1)*var(26); // [ var(57) , var(35) ]
+                D[1,58] = (-1)*var(55); // [ var(58) , var(1) ]
+                D[2,58] = (-1)*var(54); // [ var(58) , var(2) ]
+                D[5,58] = var(53); // [ var(58) , var(5) ]
+                D[7,58] = (-1)*var(50); // [ var(58) , var(7) ]
+                D[14,58] = var(43); // [ var(58) , var(14) ]
+                D[17,58] = (-1)*var(41); // [ var(58) , var(17) ]
+                D[18,58] = var(38); // [ var(58) , var(18) ]
+                D[19,58] = var(37); // [ var(58) , var(19) ]
+                D[22,58] = (-1)*var(73)+(-1)*var(74)+(-1)*var(75)+(-1)*var(76)+(-1)*var(77); // [ var(58) , var(22) ]
+                D[26,58] = (-1)*var(4); // [ var(58) , var(26) ]
+                D[27,58] = (-1)*var(6); // [ var(58) , var(27) ]
+                D[29,58] = (-1)*var(9); // [ var(58) , var(29) ]
+                D[33,58] = var(16); // [ var(58) , var(33) ]
+                D[34,58] = var(21); // [ var(58) , var(34) ]
+                D[36,58] = var(28); // [ var(58) , var(36) ]
+                D[1,59] = (-1)*var(57); // [ var(59) , var(1) ]
+                D[6,59] = var(54); // [ var(59) , var(6) ]
+                D[7,59] = (-1)*var(52); // [ var(59) , var(7) ]
+                D[11,59] = var(48); // [ var(59) , var(11) ]
+                D[12,59] = (-1)*var(47); // [ var(59) , var(12) ]
+                D[16,59] = var(43); // [ var(59) , var(16) ]
+                D[18,59] = (-1)*var(42); // [ var(59) , var(18) ]
+                D[21,59] = var(37); // [ var(59) , var(21) ]
+                D[23,59] = (-1)*var(73)+(-1)*var(75)+(-1)*var(76)+(-1)*var(77)+(-1)*var(78); // [ var(59) , var(23) ]
+                D[27,59] = var(2); // [ var(59) , var(27) ]
+                D[30,59] = var(8); // [ var(59) , var(30) ]
+                D[32,59] = var(13); // [ var(59) , var(32) ]
+                D[33,59] = var(14); // [ var(59) , var(33) ]
+                D[34,59] = var(19); // [ var(59) , var(34) ]
+                D[35,59] = var(24); // [ var(59) , var(35) ]
+                D[4,60] = var(55); // [ var(60) , var(4) ]
+                D[8,60] = (-1)*var(51); // [ var(60) , var(8) ]
+                D[9,60] = (-1)*var(50); // [ var(60) , var(9) ]
+                D[10,60] = (-1)*var(49); // [ var(60) , var(10) ]
+                D[13,60] = var(46); // [ var(60) , var(13) ]
+                D[14,60] = var(45); // [ var(60) , var(14) ]
+                D[15,60] = var(44); // [ var(60) , var(15) ]
+                D[19,60] = (-1)*var(40); // [ var(60) , var(19) ]
+                D[24,60] = (-1)*var(74)+(-1)*var(75)+(-2)*var(76)+(-1)*var(77); // [ var(60) , var(24) ]
+                D[26,60] = var(1); // [ var(60) , var(26) ]
+                D[28,60] = (-1)*var(6); // [ var(60) , var(28) ]
+                D[29,60] = (-1)*var(7); // [ var(60) , var(29) ]
+                D[31,60] = var(11); // [ var(60) , var(31) ]
+                D[35,60] = (-1)*var(23); // [ var(60) , var(35) ]
+                D[36,60] = var(27); // [ var(60) , var(36) ]
+                D[2,61] = (-1)*var(57); // [ var(61) , var(2) ]
+                D[3,61] = (-1)*var(56); // [ var(61) , var(3) ]
+                D[6,61] = var(55); // [ var(61) , var(6) ]
+                D[11,61] = var(49); // [ var(61) , var(11) ]
+                D[13,61] = (-1)*var(47); // [ var(61) , var(13) ]
+                D[19,61] = (-1)*var(42); // [ var(61) , var(19) ]
+                D[20,61] = var(39); // [ var(61) , var(20) ]
+                D[21,61] = var(38); // [ var(61) , var(21) ]
+                D[25,61] = (-1)*var(74)+(-1)*var(75)+(-1)*var(76)+(-1)*var(77)+(-1)*var(78); // [ var(61) , var(25) ]
+                D[27,61] = var(1); // [ var(61) , var(27) ]
+                D[28,61] = (-1)*var(4); // [ var(61) , var(28) ]
+                D[31,61] = (-1)*var(10); // [ var(61) , var(31) ]
+                D[32,61] = var(12); // [ var(61) , var(32) ]
+                D[34,61] = var(18); // [ var(61) , var(34) ]
+                D[36,61] = var(26); // [ var(61) , var(36) ]
+                D[1,62] = (-1)*var(60); // [ var(62) , var(1) ]
+                D[4,62] = var(58); // [ var(62) , var(4) ]
+                D[8,62] = (-1)*var(54); // [ var(62) , var(8) ]
+                D[10,62] = (-1)*var(53); // [ var(62) , var(10) ]
+                D[12,62] = (-1)*var(50); // [ var(62) , var(12) ]
+                D[14,62] = var(48); // [ var(62) , var(14) ]
+                D[17,62] = var(46); // [ var(62) , var(17) ]
+                D[18,62] = var(44); // [ var(62) , var(18) ]
+                D[22,62] = (-1)*var(40); // [ var(62) , var(22) ]
+                D[24,62] = var(37); // [ var(62) , var(24) ]
+                D[26,62] = (-1)*var(73)+(-1)*var(74)+(-1)*var(75)+(-2)*var(76)+(-1)*var(77); // [ var(62) , var(26) ]
+                D[29,62] = var(3); // [ var(62) , var(29) ]
+                D[30,62] = (-1)*var(6); // [ var(62) , var(30) ]
+                D[33,62] = var(11); // [ var(62) , var(33) ]
+                D[35,62] = var(21); // [ var(62) , var(35) ]
+                D[36,62] = (-1)*var(25); // [ var(62) , var(36) ]
+                D[1,63] = (-1)*var(61); // [ var(63) , var(1) ]
+                D[2,63] = (-1)*var(59); // [ var(63) , var(2) ]
+                D[6,63] = var(58); // [ var(63) , var(6) ]
+                D[7,63] = (-1)*var(56); // [ var(63) , var(7) ]
+                D[11,63] = var(53); // [ var(63) , var(11) ]
+                D[17,63] = (-1)*var(47); // [ var(63) , var(17) ]
+                D[20,63] = var(43); // [ var(63) , var(20) ]
+                D[22,63] = (-1)*var(42); // [ var(63) , var(22) ]
+                D[23,63] = var(38); // [ var(63) , var(23) ]
+                D[25,63] = var(37); // [ var(63) , var(25) ]
+                D[27,63] = (-1)*var(73)+(-1)*var(74)+(-1)*var(75)+(-1)*var(76)+(-1)*var(77)+(-1)*var(78); // [ var(63) , var(27) ]
+                D[30,63] = (-1)*var(4); // [ var(63) , var(30) ]
+                D[32,63] = (-1)*var(9); // [ var(63) , var(32) ]
+                D[33,63] = (-1)*var(10); // [ var(63) , var(33) ]
+                D[34,63] = (-1)*var(15); // [ var(63) , var(34) ]
+                D[36,63] = (-1)*var(24); // [ var(63) , var(36) ]
+                D[4,64] = var(61); // [ var(64) , var(4) ]
+                D[6,64] = var(60); // [ var(64) , var(6) ]
+                D[8,64] = (-1)*var(57); // [ var(64) , var(8) ]
+                D[9,64] = (-1)*var(56); // [ var(64) , var(9) ]
+                D[13,64] = var(52); // [ var(64) , var(13) ]
+                D[16,64] = (-1)*var(49); // [ var(64) , var(16) ]
+                D[20,64] = var(45); // [ var(64) , var(20) ]
+                D[21,64] = var(44); // [ var(64) , var(21) ]
+                D[24,64] = (-1)*var(42); // [ var(64) , var(24) ]
+                D[25,64] = (-1)*var(40); // [ var(64) , var(25) ]
+                D[28,64] = (-1)*var(74)+(-1)*var(75)+(-2)*var(76)+(-1)*var(77)+(-1)*var(78); // [ var(64) , var(28) ]
+                D[30,64] = var(1); // [ var(64) , var(30) ]
+                D[31,64] = (-1)*var(5); // [ var(64) , var(31) ]
+                D[32,64] = (-1)*var(7); // [ var(64) , var(32) ]
+                D[35,64] = var(18); // [ var(64) , var(35) ]
+                D[36,64] = (-1)*var(22); // [ var(64) , var(36) ]
+                D[3,65] = (-1)*var(62); // [ var(65) , var(3) ]
+                D[7,65] = var(60); // [ var(65) , var(7) ]
+                D[9,65] = var(58); // [ var(65) , var(9) ]
+                D[12,65] = (-1)*var(55); // [ var(65) , var(12) ]
+                D[13,65] = (-1)*var(54); // [ var(65) , var(13) ]
+                D[15,65] = (-1)*var(53); // [ var(65) , var(15) ]
+                D[17,65] = var(51); // [ var(65) , var(17) ]
+                D[18,65] = var(49); // [ var(65) , var(18) ]
+                D[19,65] = var(48); // [ var(65) , var(19) ]
+                D[22,65] = (-1)*var(45); // [ var(65) , var(22) ]
+                D[24,65] = (-1)*var(43); // [ var(65) , var(24) ]
+                D[26,65] = var(39); // [ var(65) , var(26) ]
+                D[29,65] = (-1)*var(73)+(-1)*var(74)+(-2)*var(75)+(-2)*var(76)+(-1)*var(77); // [ var(65) , var(29) ]
+                D[32,65] = (-1)*var(6); // [ var(65) , var(32) ]
+                D[34,65] = var(11); // [ var(65) , var(34) ]
+                D[35,65] = (-1)*var(16); // [ var(65) , var(35) ]
+                D[36,65] = var(20); // [ var(65) , var(36) ]
+                D[1,66] = (-1)*var(64); // [ var(66) , var(1) ]
+                D[4,66] = var(63); // [ var(66) , var(4) ]
+                D[6,66] = var(62); // [ var(66) , var(6) ]
+                D[8,66] = (-1)*var(59); // [ var(66) , var(8) ]
+                D[12,66] = (-1)*var(56); // [ var(66) , var(12) ]
+                D[16,66] = (-1)*var(53); // [ var(66) , var(16) ]
+                D[17,66] = var(52); // [ var(66) , var(17) ]
+                D[20,66] = var(48); // [ var(66) , var(20) ]
+                D[23,66] = var(44); // [ var(66) , var(23) ]
+                D[26,66] = (-1)*var(42); // [ var(66) , var(26) ]
+                D[27,66] = (-1)*var(40); // [ var(66) , var(27) ]
+                D[28,66] = var(37); // [ var(66) , var(28) ]
+                D[30,66] = (-1)*var(73)+(-1)*var(74)+(-1)*var(75)+(-2)*var(76)+(-1)*var(77)+(-1)*var(78); // [ var(66) , var(30) ]
+                D[32,66] = var(3); // [ var(66) , var(32) ]
+                D[33,66] = (-1)*var(5); // [ var(66) , var(33) ]
+                D[35,66] = (-1)*var(15); // [ var(66) , var(35) ]
+                D[36,66] = var(19); // [ var(66) , var(36) ]
+                D[5,67] = var(64); // [ var(67) , var(5) ]
+                D[10,67] = var(61); // [ var(67) , var(10) ]
+                D[11,67] = (-1)*var(60); // [ var(67) , var(11) ]
+                D[14,67] = (-1)*var(57); // [ var(67) , var(14) ]
+                D[15,67] = (-1)*var(56); // [ var(67) , var(15) ]
+                D[16,67] = (-1)*var(55); // [ var(67) , var(16) ]
+                D[19,67] = var(52); // [ var(67) , var(19) ]
+                D[20,67] = var(51); // [ var(67) , var(20) ]
+                D[21,67] = var(50); // [ var(67) , var(21) ]
+                D[24,67] = var(47); // [ var(67) , var(24) ]
+                D[25,67] = (-1)*var(46); // [ var(67) , var(25) ]
+                D[28,67] = (-1)*var(41); // [ var(67) , var(28) ]
+                D[31,67] = (-1)*var(74)+(-1)*var(75)+(-2)*var(76)+(-2)*var(77)+(-1)*var(78); // [ var(67) , var(31) ]
+                D[33,67] = var(1); // [ var(67) , var(33) ]
+                D[34,67] = (-1)*var(7); // [ var(67) , var(34) ]
+                D[35,67] = (-1)*var(12); // [ var(67) , var(35) ]
+                D[36,67] = var(17); // [ var(67) , var(36) ]
+                D[3,68] = (-1)*var(66); // [ var(68) , var(3) ]
+                D[6,68] = var(65); // [ var(68) , var(6) ]
+                D[7,68] = var(64); // [ var(68) , var(7) ]
+                D[9,68] = var(63); // [ var(68) , var(9) ]
+                D[12,68] = (-1)*var(61); // [ var(68) , var(12) ]
+                D[13,68] = (-1)*var(59); // [ var(68) , var(13) ]
+                D[17,68] = var(57); // [ var(68) , var(17) ]
+                D[21,68] = (-1)*var(53); // [ var(68) , var(21) ]
+                D[23,68] = var(49); // [ var(68) , var(23) ]
+                D[25,68] = var(48); // [ var(68) , var(25) ]
+                D[27,68] = (-1)*var(45); // [ var(68) , var(27) ]
+                D[28,68] = (-1)*var(43); // [ var(68) , var(28) ]
+                D[29,68] = (-1)*var(42); // [ var(68) , var(29) ]
+                D[30,68] = var(39); // [ var(68) , var(30) ]
+                D[32,68] = (-1)*var(73)+(-1)*var(74)+(-2)*var(75)+(-2)*var(76)+(-1)*var(77)+(-1)*var(78); // [ var(68) , var(32) ]
+                D[34,68] = (-1)*var(5); // [ var(68) , var(34) ]
+                D[35,68] = var(10); // [ var(68) , var(35) ]
+                D[36,68] = (-1)*var(14); // [ var(68) , var(36) ]
+                D[1,69] = (-1)*var(67); // [ var(69) , var(1) ]
+                D[5,69] = var(66); // [ var(69) , var(5) ]
+                D[10,69] = var(63); // [ var(69) , var(10) ]
+                D[11,69] = (-1)*var(62); // [ var(69) , var(11) ]
+                D[14,69] = (-1)*var(59); // [ var(69) , var(14) ]
+                D[16,69] = (-1)*var(58); // [ var(69) , var(16) ]
+                D[18,69] = (-1)*var(56); // [ var(69) , var(18) ]
+                D[20,69] = var(54); // [ var(69) , var(20) ]
+                D[22,69] = var(52); // [ var(69) , var(22) ]
+                D[23,69] = var(50); // [ var(69) , var(23) ]
+                D[26,69] = var(47); // [ var(69) , var(26) ]
+                D[27,69] = (-1)*var(46); // [ var(69) , var(27) ]
+                D[30,69] = (-1)*var(41); // [ var(69) , var(30) ]
+                D[31,69] = var(37); // [ var(69) , var(31) ]
+                D[33,69] = (-1)*var(73)+(-1)*var(74)+(-1)*var(75)+(-2)*var(76)+(-2)*var(77)+(-1)*var(78); // [ var(69) , var(33) ]
+                D[34,69] = var(3); // [ var(69) , var(34) ]
+                D[35,69] = var(9); // [ var(69) , var(35) ]
+                D[36,69] = (-1)*var(13); // [ var(69) , var(36) ]
+                D[3,70] = (-1)*var(69); // [ var(70) , var(3) ]
+                D[5,70] = var(68); // [ var(70) , var(5) ]
+                D[7,70] = var(67); // [ var(70) , var(7) ]
+                D[11,70] = (-1)*var(65); // [ var(70) , var(11) ]
+                D[15,70] = var(63); // [ var(70) , var(15) ]
+                D[18,70] = (-1)*var(61); // [ var(70) , var(18) ]
+                D[19,70] = (-1)*var(59); // [ var(70) , var(19) ]
+                D[21,70] = (-1)*var(58); // [ var(70) , var(21) ]
+                D[22,70] = var(57); // [ var(70) , var(22) ]
+                D[23,70] = var(55); // [ var(70) , var(23) ]
+                D[25,70] = var(54); // [ var(70) , var(25) ]
+                D[27,70] = (-1)*var(51); // [ var(70) , var(27) ]
+                D[29,70] = var(47); // [ var(70) , var(29) ]
+                D[31,70] = (-1)*var(43); // [ var(70) , var(31) ]
+                D[32,70] = (-1)*var(41); // [ var(70) , var(32) ]
+                D[33,70] = var(39); // [ var(70) , var(33) ]
+                D[34,70] = (-1)*var(73)+(-1)*var(74)+(-2)*var(75)+(-2)*var(76)+(-2)*var(77)+(-1)*var(78); // [ var(70) , var(34) ]
+                D[35,70] = (-1)*var(4); // [ var(70) , var(35) ]
+                D[36,70] = var(8); // [ var(70) , var(36) ]
+                D[4,71] = var(70); // [ var(71) , var(4) ]
+                D[9,71] = (-1)*var(69); // [ var(71) , var(9) ]
+                D[10,71] = (-1)*var(68); // [ var(71) , var(10) ]
+                D[12,71] = var(67); // [ var(71) , var(12) ]
+                D[15,71] = var(66); // [ var(71) , var(15) ]
+                D[16,71] = var(65); // [ var(71) , var(16) ]
+                D[18,71] = (-1)*var(64); // [ var(71) , var(18) ]
+                D[21,71] = (-1)*var(62); // [ var(71) , var(21) ]
+                D[23,71] = var(60); // [ var(71) , var(23) ]
+                D[24,71] = (-1)*var(59); // [ var(71) , var(24) ]
+                D[26,71] = var(57); // [ var(71) , var(26) ]
+                D[28,71] = var(54); // [ var(71) , var(28) ]
+                D[29,71] = (-1)*var(52); // [ var(71) , var(29) ]
+                D[30,71] = (-1)*var(51); // [ var(71) , var(30) ]
+                D[31,71] = (-1)*var(48); // [ var(71) , var(31) ]
+                D[32,71] = var(46); // [ var(71) , var(32) ]
+                D[33,71] = var(45); // [ var(71) , var(33) ]
+                D[34,71] = (-1)*var(40); // [ var(71) , var(34) ]
+                D[35,71] = (-1)*var(73)+(-1)*var(74)+(-2)*var(75)+(-3)*var(76)+(-2)*var(77)+(-1)*var(78); // [ var(71) , var(35) ]
+                D[36,71] = (-1)*var(2); // [ var(71) , var(36) ]
+                D[2,72] = var(71); // [ var(72) , var(2) ]
+                D[8,72] = (-1)*var(70); // [ var(72) , var(8) ]
+                D[13,72] = var(69); // [ var(72) , var(13) ]
+                D[14,72] = var(68); // [ var(72) , var(14) ]
+                D[17,72] = (-1)*var(67); // [ var(72) , var(17) ]
+                D[19,72] = (-1)*var(66); // [ var(72) , var(19) ]
+                D[20,72] = (-1)*var(65); // [ var(72) , var(20) ]
+                D[22,72] = var(64); // [ var(72) , var(22) ]
+                D[24,72] = var(63); // [ var(72) , var(24) ]
+                D[25,72] = var(62); // [ var(72) , var(25) ]
+                D[26,72] = (-1)*var(61); // [ var(72) , var(26) ]
+                D[27,72] = (-1)*var(60); // [ var(72) , var(27) ]
+                D[28,72] = (-1)*var(58); // [ var(72) , var(28) ]
+                D[29,72] = var(56); // [ var(72) , var(29) ]
+                D[30,72] = var(55); // [ var(72) , var(30) ]
+                D[31,72] = var(53); // [ var(72) , var(31) ]
+                D[32,72] = (-1)*var(50); // [ var(72) , var(32) ]
+                D[33,72] = (-1)*var(49); // [ var(72) , var(33) ]
+                D[34,72] = var(44); // [ var(72) , var(34) ]
+                D[35,72] = (-1)*var(38); // [ var(72) , var(35) ]
+                D[36,72] = (-1)*var(73)+(-2)*var(74)+(-2)*var(75)+(-3)*var(76)+(-2)*var(77)+(-1)*var(78); // [ var(72) , var(36) ]
+        // X(i) * X(j):
+                D[1,3] = var(7); // [ var(3) , var(1) ]
+                D[1,9] = var(12); // [ var(9) , var(1) ]
+                D[1,13] = var(17); // [ var(13) , var(1) ]
+                D[1,15] = var(18); // [ var(15) , var(1) ]
+                D[1,19] = var(22); // [ var(19) , var(1) ]
+                D[1,21] = var(23); // [ var(21) , var(1) ]
+                D[1,24] = var(26); // [ var(24) , var(1) ]
+                D[1,25] = var(27); // [ var(25) , var(1) ]
+                D[1,28] = var(30); // [ var(28) , var(1) ]
+                D[1,31] = var(33); // [ var(31) , var(1) ]
+                D[2,4] = var(8); // [ var(4) , var(2) ]
+                D[2,9] = var(13); // [ var(9) , var(2) ]
+                D[2,10] = var(14); // [ var(10) , var(2) ]
+                D[2,12] = var(17); // [ var(12) , var(2) ]
+                D[2,15] = var(19); // [ var(15) , var(2) ]
+                D[2,16] = var(20); // [ var(16) , var(2) ]
+                D[2,18] = var(22); // [ var(18) , var(2) ]
+                D[2,21] = var(25); // [ var(21) , var(2) ]
+                D[2,23] = var(27); // [ var(23) , var(2) ]
+                D[2,35] = (-1)*var(36); // [ var(35) , var(2) ]
+                D[3,4] = var(9); // [ var(4) , var(3) ]
+                D[3,8] = var(13); // [ var(8) , var(3) ]
+                D[3,10] = var(15); // [ var(10) , var(3) ]
+                D[3,14] = var(19); // [ var(14) , var(3) ]
+                D[3,16] = var(21); // [ var(16) , var(3) ]
+                D[3,20] = var(25); // [ var(20) , var(3) ]
+                D[3,26] = var(29); // [ var(26) , var(3) ]
+                D[3,30] = var(32); // [ var(30) , var(3) ]
+                D[3,33] = var(34); // [ var(33) , var(3) ]
+                D[4,5] = var(10); // [ var(5) , var(4) ]
+                D[4,7] = (-1)*var(12); // [ var(7) , var(4) ]
+                D[4,11] = var(16); // [ var(11) , var(4) ]
+                D[4,19] = (-1)*var(24); // [ var(19) , var(4) ]
+                D[4,22] = (-1)*var(26); // [ var(22) , var(4) ]
+                D[4,25] = (-1)*var(28); // [ var(25) , var(4) ]
+                D[4,27] = (-1)*var(30); // [ var(27) , var(4) ]
+                D[4,34] = (-1)*var(35); // [ var(34) , var(4) ]
+                D[5,6] = var(11); // [ var(6) , var(5) ]
+                D[5,8] = (-1)*var(14); // [ var(8) , var(5) ]
+                D[5,9] = (-1)*var(15); // [ var(9) , var(5) ]
+                D[5,12] = (-1)*var(18); // [ var(12) , var(5) ]
+                D[5,13] = (-1)*var(19); // [ var(13) , var(5) ]
+                D[5,17] = (-1)*var(22); // [ var(17) , var(5) ]
+                D[5,28] = (-1)*var(31); // [ var(28) , var(5) ]
+                D[5,30] = (-1)*var(33); // [ var(30) , var(5) ]
+                D[5,32] = (-1)*var(34); // [ var(32) , var(5) ]
+                D[6,10] = (-1)*var(16); // [ var(10) , var(6) ]
+                D[6,14] = (-1)*var(20); // [ var(14) , var(6) ]
+                D[6,15] = (-1)*var(21); // [ var(15) , var(6) ]
+                D[6,18] = (-1)*var(23); // [ var(18) , var(6) ]
+                D[6,19] = (-1)*var(25); // [ var(19) , var(6) ]
+                D[6,22] = (-1)*var(27); // [ var(22) , var(6) ]
+                D[6,24] = (-1)*var(28); // [ var(24) , var(6) ]
+                D[6,26] = (-1)*var(30); // [ var(26) , var(6) ]
+                D[6,29] = (-1)*var(32); // [ var(29) , var(6) ]
+                D[7,8] = var(17); // [ var(8) , var(7) ]
+                D[7,10] = var(18); // [ var(10) , var(7) ]
+                D[7,14] = var(22); // [ var(14) , var(7) ]
+                D[7,16] = var(23); // [ var(16) , var(7) ]
+                D[7,20] = var(27); // [ var(20) , var(7) ]
+                D[7,24] = (-1)*var(29); // [ var(24) , var(7) ]
+                D[7,28] = (-1)*var(32); // [ var(28) , var(7) ]
+                D[7,31] = (-1)*var(34); // [ var(31) , var(7) ]
+                D[8,11] = var(20); // [ var(11) , var(8) ]
+                D[8,15] = var(24); // [ var(15) , var(8) ]
+                D[8,18] = var(26); // [ var(18) , var(8) ]
+                D[8,21] = var(28); // [ var(21) , var(8) ]
+                D[8,23] = var(30); // [ var(23) , var(8) ]
+                D[8,34] = var(36); // [ var(34) , var(8) ]
+                D[9,11] = var(21); // [ var(11) , var(9) ]
+                D[9,14] = var(24); // [ var(14) , var(9) ]
+                D[9,20] = var(28); // [ var(20) , var(9) ]
+                D[9,22] = (-1)*var(29); // [ var(22) , var(9) ]
+                D[9,27] = (-1)*var(32); // [ var(27) , var(9) ]
+                D[9,33] = var(35); // [ var(33) , var(9) ]
+                D[10,13] = var(24); // [ var(13) , var(10) ]
+                D[10,17] = var(26); // [ var(17) , var(10) ]
+                D[10,25] = (-1)*var(31); // [ var(25) , var(10) ]
+                D[10,27] = (-1)*var(33); // [ var(27) , var(10) ]
+                D[10,32] = var(35); // [ var(32) , var(10) ]
+                D[11,12] = (-1)*var(23); // [ var(12) , var(11) ]
+                D[11,13] = (-1)*var(25); // [ var(13) , var(11) ]
+                D[11,17] = (-1)*var(27); // [ var(17) , var(11) ]
+                D[11,24] = var(31); // [ var(24) , var(11) ]
+                D[11,26] = var(33); // [ var(26) , var(11) ]
+                D[11,29] = var(34); // [ var(29) , var(11) ]
+                D[12,14] = var(26); // [ var(14) , var(12) ]
+                D[12,19] = var(29); // [ var(19) , var(12) ]
+                D[12,20] = var(30); // [ var(20) , var(12) ]
+                D[12,25] = var(32); // [ var(25) , var(12) ]
+                D[12,31] = (-1)*var(35); // [ var(31) , var(12) ]
+                D[13,16] = (-1)*var(28); // [ var(16) , var(13) ]
+                D[13,18] = var(29); // [ var(18) , var(13) ]
+                D[13,23] = var(32); // [ var(23) , var(13) ]
+                D[13,33] = (-1)*var(36); // [ var(33) , var(13) ]
+                D[14,21] = var(31); // [ var(21) , var(14) ]
+                D[14,23] = var(33); // [ var(23) , var(14) ]
+                D[14,32] = (-1)*var(36); // [ var(32) , var(14) ]
+                D[15,17] = var(29); // [ var(17) , var(15) ]
+                D[15,20] = var(31); // [ var(20) , var(15) ]
+                D[15,27] = (-1)*var(34); // [ var(27) , var(15) ]
+                D[15,30] = (-1)*var(35); // [ var(30) , var(15) ]
+                D[16,17] = var(30); // [ var(17) , var(16) ]
+                D[16,19] = var(31); // [ var(19) , var(16) ]
+                D[16,22] = var(33); // [ var(22) , var(16) ]
+                D[16,29] = (-1)*var(35); // [ var(29) , var(16) ]
+                D[17,21] = (-1)*var(32); // [ var(21) , var(17) ]
+                D[17,31] = var(36); // [ var(31) , var(17) ]
+                D[18,20] = var(33); // [ var(20) , var(18) ]
+                D[18,25] = var(34); // [ var(25) , var(18) ]
+                D[18,28] = var(35); // [ var(28) , var(18) ]
+                D[19,23] = var(34); // [ var(23) , var(19) ]
+                D[19,30] = var(36); // [ var(30) , var(19) ]
+                D[20,29] = var(36); // [ var(29) , var(20) ]
+                D[21,22] = var(34); // [ var(22) , var(21) ]
+                D[21,26] = var(35); // [ var(26) , var(21) ]
+                D[22,28] = (-1)*var(36); // [ var(28) , var(22) ]
+                D[23,24] = (-1)*var(35); // [ var(24) , var(23) ]
+                D[24,27] = (-1)*var(36); // [ var(27) , var(24) ]
+                D[25,26] = (-1)*var(36); // [ var(26) , var(25) ]
+        // Y(i) * Y(j):
+                D[37,39] = (-1)*var(43); // [ var(39) , var(37) ]
+                D[37,45] = (-1)*var(48); // [ var(45) , var(37) ]
+                D[37,49] = (-1)*var(53); // [ var(49) , var(37) ]
+                D[37,51] = (-1)*var(54); // [ var(51) , var(37) ]
+                D[37,55] = (-1)*var(58); // [ var(55) , var(37) ]
+                D[37,57] = (-1)*var(59); // [ var(57) , var(37) ]
+                D[37,60] = (-1)*var(62); // [ var(60) , var(37) ]
+                D[37,61] = (-1)*var(63); // [ var(61) , var(37) ]
+                D[37,64] = (-1)*var(66); // [ var(64) , var(37) ]
+                D[37,67] = (-1)*var(69); // [ var(67) , var(37) ]
+                D[38,40] = (-1)*var(44); // [ var(40) , var(38) ]
+                D[38,45] = (-1)*var(49); // [ var(45) , var(38) ]
+                D[38,46] = (-1)*var(50); // [ var(46) , var(38) ]
+                D[38,48] = (-1)*var(53); // [ var(48) , var(38) ]
+                D[38,51] = (-1)*var(55); // [ var(51) , var(38) ]
+                D[38,52] = (-1)*var(56); // [ var(52) , var(38) ]
+                D[38,54] = (-1)*var(58); // [ var(54) , var(38) ]
+                D[38,57] = (-1)*var(61); // [ var(57) , var(38) ]
+                D[38,59] = (-1)*var(63); // [ var(59) , var(38) ]
+                D[38,71] = var(72); // [ var(71) , var(38) ]
+                D[39,40] = (-1)*var(45); // [ var(40) , var(39) ]
+                D[39,44] = (-1)*var(49); // [ var(44) , var(39) ]
+                D[39,46] = (-1)*var(51); // [ var(46) , var(39) ]
+                D[39,50] = (-1)*var(55); // [ var(50) , var(39) ]
+                D[39,52] = (-1)*var(57); // [ var(52) , var(39) ]
+                D[39,56] = (-1)*var(61); // [ var(56) , var(39) ]
+                D[39,62] = (-1)*var(65); // [ var(62) , var(39) ]
+                D[39,66] = (-1)*var(68); // [ var(66) , var(39) ]
+                D[39,69] = (-1)*var(70); // [ var(69) , var(39) ]
+                D[40,41] = (-1)*var(46); // [ var(41) , var(40) ]
+                D[40,43] = var(48); // [ var(43) , var(40) ]
+                D[40,47] = (-1)*var(52); // [ var(47) , var(40) ]
+                D[40,55] = var(60); // [ var(55) , var(40) ]
+                D[40,58] = var(62); // [ var(58) , var(40) ]
+                D[40,61] = var(64); // [ var(61) , var(40) ]
+                D[40,63] = var(66); // [ var(63) , var(40) ]
+                D[40,70] = var(71); // [ var(70) , var(40) ]
+                D[41,42] = (-1)*var(47); // [ var(42) , var(41) ]
+                D[41,44] = var(50); // [ var(44) , var(41) ]
+                D[41,45] = var(51); // [ var(45) , var(41) ]
+                D[41,48] = var(54); // [ var(48) , var(41) ]
+                D[41,49] = var(55); // [ var(49) , var(41) ]
+                D[41,53] = var(58); // [ var(53) , var(41) ]
+                D[41,64] = var(67); // [ var(64) , var(41) ]
+                D[41,66] = var(69); // [ var(66) , var(41) ]
+                D[41,68] = var(70); // [ var(68) , var(41) ]
+                D[42,46] = var(52); // [ var(46) , var(42) ]
+                D[42,50] = var(56); // [ var(50) , var(42) ]
+                D[42,51] = var(57); // [ var(51) , var(42) ]
+                D[42,54] = var(59); // [ var(54) , var(42) ]
+                D[42,55] = var(61); // [ var(55) , var(42) ]
+                D[42,58] = var(63); // [ var(58) , var(42) ]
+                D[42,60] = var(64); // [ var(60) , var(42) ]
+                D[42,62] = var(66); // [ var(62) , var(42) ]
+                D[42,65] = var(68); // [ var(65) , var(42) ]
+                D[43,44] = (-1)*var(53); // [ var(44) , var(43) ]
+                D[43,46] = (-1)*var(54); // [ var(46) , var(43) ]
+                D[43,50] = (-1)*var(58); // [ var(50) , var(43) ]
+                D[43,52] = (-1)*var(59); // [ var(52) , var(43) ]
+                D[43,56] = (-1)*var(63); // [ var(56) , var(43) ]
+                D[43,60] = var(65); // [ var(60) , var(43) ]
+                D[43,64] = var(68); // [ var(64) , var(43) ]
+                D[43,67] = var(70); // [ var(67) , var(43) ]
+                D[44,47] = (-1)*var(56); // [ var(47) , var(44) ]
+                D[44,51] = (-1)*var(60); // [ var(51) , var(44) ]
+                D[44,54] = (-1)*var(62); // [ var(54) , var(44) ]
+                D[44,57] = (-1)*var(64); // [ var(57) , var(44) ]
+                D[44,59] = (-1)*var(66); // [ var(59) , var(44) ]
+                D[44,70] = (-1)*var(72); // [ var(70) , var(44) ]
+                D[45,47] = (-1)*var(57); // [ var(47) , var(45) ]
+                D[45,50] = (-1)*var(60); // [ var(50) , var(45) ]
+                D[45,56] = (-1)*var(64); // [ var(56) , var(45) ]
+                D[45,58] = var(65); // [ var(58) , var(45) ]
+                D[45,63] = var(68); // [ var(63) , var(45) ]
+                D[45,69] = (-1)*var(71); // [ var(69) , var(45) ]
+                D[46,49] = (-1)*var(60); // [ var(49) , var(46) ]
+                D[46,53] = (-1)*var(62); // [ var(53) , var(46) ]
+                D[46,61] = var(67); // [ var(61) , var(46) ]
+                D[46,63] = var(69); // [ var(63) , var(46) ]
+                D[46,68] = (-1)*var(71); // [ var(68) , var(46) ]
+                D[47,48] = var(59); // [ var(48) , var(47) ]
+                D[47,49] = var(61); // [ var(49) , var(47) ]
+                D[47,53] = var(63); // [ var(53) , var(47) ]
+                D[47,60] = (-1)*var(67); // [ var(60) , var(47) ]
+                D[47,62] = (-1)*var(69); // [ var(62) , var(47) ]
+                D[47,65] = (-1)*var(70); // [ var(65) , var(47) ]
+                D[48,50] = (-1)*var(62); // [ var(50) , var(48) ]
+                D[48,55] = (-1)*var(65); // [ var(55) , var(48) ]
+                D[48,56] = (-1)*var(66); // [ var(56) , var(48) ]
+                D[48,61] = (-1)*var(68); // [ var(61) , var(48) ]
+                D[48,67] = var(71); // [ var(67) , var(48) ]
+                D[49,52] = var(64); // [ var(52) , var(49) ]
+                D[49,54] = (-1)*var(65); // [ var(54) , var(49) ]
+                D[49,59] = (-1)*var(68); // [ var(59) , var(49) ]
+                D[49,69] = var(72); // [ var(69) , var(49) ]
+                D[50,57] = (-1)*var(67); // [ var(57) , var(50) ]
+                D[50,59] = (-1)*var(69); // [ var(59) , var(50) ]
+                D[50,68] = var(72); // [ var(68) , var(50) ]
+                D[51,53] = (-1)*var(65); // [ var(53) , var(51) ]
+                D[51,56] = (-1)*var(67); // [ var(56) , var(51) ]
+                D[51,63] = var(70); // [ var(63) , var(51) ]
+                D[51,66] = var(71); // [ var(66) , var(51) ]
+                D[52,53] = (-1)*var(66); // [ var(53) , var(52) ]
+                D[52,55] = (-1)*var(67); // [ var(55) , var(52) ]
+                D[52,58] = (-1)*var(69); // [ var(58) , var(52) ]
+                D[52,65] = var(71); // [ var(65) , var(52) ]
+                D[53,57] = var(68); // [ var(57) , var(53) ]
+                D[53,67] = (-1)*var(72); // [ var(67) , var(53) ]
+                D[54,56] = (-1)*var(69); // [ var(56) , var(54) ]
+                D[54,61] = (-1)*var(70); // [ var(61) , var(54) ]
+                D[54,64] = (-1)*var(71); // [ var(64) , var(54) ]
+                D[55,59] = (-1)*var(70); // [ var(59) , var(55) ]
+                D[55,66] = (-1)*var(72); // [ var(66) , var(55) ]
+                D[56,65] = (-1)*var(72); // [ var(65) , var(56) ]
+                D[57,58] = (-1)*var(70); // [ var(58) , var(57) ]
+                D[57,62] = (-1)*var(71); // [ var(62) , var(57) ]
+                D[58,64] = var(72); // [ var(64) , var(58) ]
+                D[59,60] = var(71); // [ var(60) , var(59) ]
+                D[60,63] = var(72); // [ var(63) , var(60) ]
+                D[61,62] = var(72); // [ var(62) , var(61) ]
+   def @@RR=nc_algebra(1,D);
+   return(@@RR);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   def ncAlgebra = makeUe6();
+   ncAlgebra;
+   setring ncAlgebra;
+   // ...  1008  noncommutative relations
+}
+////////////////////////////////////////////////////////////////////
+
+// Algebra: e7(Q) has the type: E7, and defined by:
+
+proc makeUe7(list #)
+"USAGE:   makeUe7([p]); p an optional integer (field characteristic)
+RETURN:  a ring, describing U(e_7)
+NOTE:    You have to activate this ring with the 'setring' command. The presentation of U(e_7) is derived from the Chevalley representation of e_7, positive resp. negative roots are denoted by x(i) resp. y(i); Cartan elements are denoted by h(i).
+SEE ALSO: makeUsl, makeUso5, makeUsp1, makeUe6, makeUe7, makeUe8, makeUg2, makeUf4
+EXAMPLE: example makeUe7; shows examples
+"
+{
+   int @p = defInt(#);
+
+   ring @@@rrr = @p,(X(1..63),Y(1..63),H(1..7)),dp;
+   int N = nvars(@@@rrr);
+   matrix D[N][N]=0;
+
+        // H(i) * X(j):
+                D[1,127] = (2)*var(1); // [ var(127) , var(1) ]
+                D[3,127] = (-1)*var(3); // [ var(127) , var(3) ]
+                D[8,127] = var(8); // [ var(127) , var(8) ]
+                D[10,127] = (-1)*var(10); // [ var(127) , var(10) ]
+                D[14,127] = var(14); // [ var(127) , var(14) ]
+                D[15,127] = (-1)*var(15); // [ var(127) , var(15) ]
+                D[17,127] = (-1)*var(17); // [ var(127) , var(17) ]
+                D[20,127] = var(20); // [ var(127) , var(20) ]
+                D[21,127] = var(21); // [ var(127) , var(21) ]
+                D[22,127] = (-1)*var(22); // [ var(127) , var(22) ]
+                D[24,127] = (-1)*var(24); // [ var(127) , var(24) ]
+                D[26,127] = var(26); // [ var(127) , var(26) ]
+                D[27,127] = var(27); // [ var(127) , var(27) ]
+                D[28,127] = (-1)*var(28); // [ var(127) , var(28) ]
+                D[29,127] = (-1)*var(29); // [ var(127) , var(29) ]
+                D[31,127] = (-1)*var(31); // [ var(127) , var(31) ]
+                D[32,127] = var(32); // [ var(127) , var(32) ]
+                D[33,127] = var(33); // [ var(127) , var(33) ]
+                D[34,127] = var(34); // [ var(127) , var(34) ]
+                D[35,127] = (-1)*var(35); // [ var(127) , var(35) ]
+                D[36,127] = (-1)*var(36); // [ var(127) , var(36) ]
+                D[38,127] = var(38); // [ var(127) , var(38) ]
+                D[39,127] = var(39); // [ var(127) , var(39) ]
+                D[40,127] = (-1)*var(40); // [ var(127) , var(40) ]
+                D[41,127] = (-1)*var(41); // [ var(127) , var(41) ]
+                D[43,127] = var(43); // [ var(127) , var(43) ]
+                D[44,127] = var(44); // [ var(127) , var(44) ]
+                D[45,127] = (-1)*var(45); // [ var(127) , var(45) ]
+                D[48,127] = var(48); // [ var(127) , var(48) ]
+                D[49,127] = (-1)*var(49); // [ var(127) , var(49) ]
+                D[52,127] = var(52); // [ var(127) , var(52) ]
+                D[62,127] = (-1)*var(62); // [ var(127) , var(62) ]
+                D[63,127] = var(63); // [ var(127) , var(63) ]
+                D[2,128] = (2)*var(2); // [ var(128) , var(2) ]
+                D[4,128] = (-1)*var(4); // [ var(128) , var(4) ]
+                D[9,128] = var(9); // [ var(128) , var(9) ]
+                D[10,128] = (-1)*var(10); // [ var(128) , var(10) ]
+                D[11,128] = (-1)*var(11); // [ var(128) , var(11) ]
+                D[14,128] = (-1)*var(14); // [ var(128) , var(14) ]
+                D[15,128] = var(15); // [ var(128) , var(15) ]
+                D[16,128] = var(16); // [ var(128) , var(16) ]
+                D[17,128] = (-1)*var(17); // [ var(128) , var(17) ]
+                D[18,128] = (-1)*var(18); // [ var(128) , var(18) ]
+                D[20,128] = var(20); // [ var(128) , var(20) ]
+                D[21,128] = (-1)*var(21); // [ var(128) , var(21) ]
+                D[22,128] = var(22); // [ var(128) , var(22) ]
+                D[23,128] = var(23); // [ var(128) , var(23) ]
+                D[24,128] = (-1)*var(24); // [ var(128) , var(24) ]
+                D[25,128] = (-1)*var(25); // [ var(128) , var(25) ]
+                D[26,128] = var(26); // [ var(128) , var(26) ]
+                D[27,128] = (-1)*var(27); // [ var(128) , var(27) ]
+                D[29,128] = var(29); // [ var(128) , var(29) ]
+                D[30,128] = var(30); // [ var(128) , var(30) ]
+                D[31,128] = (-1)*var(31); // [ var(128) , var(31) ]
+                D[33,128] = var(33); // [ var(128) , var(33) ]
+                D[34,128] = (-1)*var(34); // [ var(128) , var(34) ]
+                D[36,128] = var(36); // [ var(128) , var(36) ]
+                D[39,128] = var(39); // [ var(128) , var(39) ]
+                D[50,128] = (-1)*var(50); // [ var(128) , var(50) ]
+                D[53,128] = var(53); // [ var(128) , var(53) ]
+                D[54,128] = (-1)*var(54); // [ var(128) , var(54) ]
+                D[56,128] = var(56); // [ var(128) , var(56) ]
+                D[57,128] = (-1)*var(57); // [ var(128) , var(57) ]
+                D[58,128] = var(58); // [ var(128) , var(58) ]
+                D[59,128] = (-1)*var(59); // [ var(128) , var(59) ]
+                D[60,128] = var(60); // [ var(128) , var(60) ]
+                D[1,129] = (-1)*var(1); // [ var(129) , var(1) ]
+                D[3,129] = (2)*var(3); // [ var(129) , var(3) ]
+                D[4,129] = (-1)*var(4); // [ var(129) , var(4) ]
+                D[8,129] = var(8); // [ var(129) , var(8) ]
+                D[9,129] = (-1)*var(9); // [ var(129) , var(9) ]
+                D[10,129] = var(10); // [ var(129) , var(10) ]
+                D[11,129] = (-1)*var(11); // [ var(129) , var(11) ]
+                D[15,129] = var(15); // [ var(129) , var(15) ]
+                D[16,129] = (-1)*var(16); // [ var(129) , var(16) ]
+                D[17,129] = var(17); // [ var(129) , var(17) ]
+                D[18,129] = (-1)*var(18); // [ var(129) , var(18) ]
+                D[22,129] = var(22); // [ var(129) , var(22) ]
+                D[23,129] = (-1)*var(23); // [ var(129) , var(23) ]
+                D[24,129] = var(24); // [ var(129) , var(24) ]
+                D[25,129] = (-1)*var(25); // [ var(129) , var(25) ]
+                D[29,129] = var(29); // [ var(129) , var(29) ]
+                D[30,129] = (-1)*var(30); // [ var(129) , var(30) ]
+                D[31,129] = var(31); // [ var(129) , var(31) ]
+                D[32,129] = (-1)*var(32); // [ var(129) , var(32) ]
+                D[36,129] = var(36); // [ var(129) , var(36) ]
+                D[37,129] = var(37); // [ var(129) , var(37) ]
+                D[38,129] = (-1)*var(38); // [ var(129) , var(38) ]
+                D[42,129] = var(42); // [ var(129) , var(42) ]
+                D[43,129] = (-1)*var(43); // [ var(129) , var(43) ]
+                D[44,129] = (-1)*var(44); // [ var(129) , var(44) ]
+                D[46,129] = var(46); // [ var(129) , var(46) ]
+                D[47,129] = var(47); // [ var(129) , var(47) ]
+                D[48,129] = (-1)*var(48); // [ var(129) , var(48) ]
+                D[51,129] = var(51); // [ var(129) , var(51) ]
+                D[52,129] = (-1)*var(52); // [ var(129) , var(52) ]
+                D[55,129] = var(55); // [ var(129) , var(55) ]
+                D[61,129] = (-1)*var(61); // [ var(129) , var(61) ]
+                D[62,129] = var(62); // [ var(129) , var(62) ]
+                D[2,130] = (-1)*var(2); // [ var(130) , var(2) ]
+                D[3,130] = (-1)*var(3); // [ var(130) , var(3) ]
+                D[4,130] = (2)*var(4); // [ var(130) , var(4) ]
+                D[5,130] = (-1)*var(5); // [ var(130) , var(5) ]
+                D[8,130] = (-1)*var(8); // [ var(130) , var(8) ]
+                D[9,130] = var(9); // [ var(130) , var(9) ]
+                D[10,130] = var(10); // [ var(130) , var(10) ]
+                D[11,130] = var(11); // [ var(130) , var(11) ]
+                D[12,130] = (-1)*var(12); // [ var(130) , var(12) ]
+                D[14,130] = var(14); // [ var(130) , var(14) ]
+                D[18,130] = var(18); // [ var(130) , var(18) ]
+                D[19,130] = (-1)*var(19); // [ var(130) , var(19) ]
+                D[22,130] = (-1)*var(22); // [ var(130) , var(22) ]
+                D[25,130] = var(25); // [ var(130) , var(25) ]
+                D[26,130] = (-1)*var(26); // [ var(130) , var(26) ]
+                D[28,130] = var(28); // [ var(130) , var(28) ]
+                D[29,130] = (-1)*var(29); // [ var(130) , var(29) ]
+                D[32,130] = var(32); // [ var(130) , var(32) ]
+                D[33,130] = (-1)*var(33); // [ var(130) , var(33) ]
+                D[35,130] = var(35); // [ var(130) , var(35) ]
+                D[36,130] = (-1)*var(36); // [ var(130) , var(36) ]
+                D[38,130] = var(38); // [ var(130) , var(38) ]
+                D[39,130] = (-1)*var(39); // [ var(130) , var(39) ]
+                D[41,130] = var(41); // [ var(130) , var(41) ]
+                D[44,130] = var(44); // [ var(130) , var(44) ]
+                D[46,130] = (-1)*var(46); // [ var(130) , var(46) ]
+                D[50,130] = var(50); // [ var(130) , var(50) ]
+                D[51,130] = (-1)*var(51); // [ var(130) , var(51) ]
+                D[54,130] = var(54); // [ var(130) , var(54) ]
+                D[55,130] = (-1)*var(55); // [ var(130) , var(55) ]
+                D[57,130] = var(57); // [ var(130) , var(57) ]
+                D[60,130] = (-1)*var(60); // [ var(130) , var(60) ]
+                D[61,130] = var(61); // [ var(130) , var(61) ]
+                D[4,131] = (-1)*var(4); // [ var(131) , var(4) ]
+                D[5,131] = (2)*var(5); // [ var(131) , var(5) ]
+                D[6,131] = (-1)*var(6); // [ var(131) , var(6) ]
+                D[9,131] = (-1)*var(9); // [ var(131) , var(9) ]
+                D[10,131] = (-1)*var(10); // [ var(131) , var(10) ]
+                D[11,131] = var(11); // [ var(131) , var(11) ]
+                D[12,131] = var(12); // [ var(131) , var(12) ]
+                D[13,131] = (-1)*var(13); // [ var(131) , var(13) ]
+                D[14,131] = (-1)*var(14); // [ var(131) , var(14) ]
+                D[15,131] = (-1)*var(15); // [ var(131) , var(15) ]
+                D[16,131] = var(16); // [ var(131) , var(16) ]
+                D[17,131] = var(17); // [ var(131) , var(17) ]
+                D[19,131] = var(19); // [ var(131) , var(19) ]
+                D[20,131] = (-1)*var(20); // [ var(131) , var(20) ]
+                D[21,131] = var(21); // [ var(131) , var(21) ]
+                D[22,131] = var(22); // [ var(131) , var(22) ]
+                D[26,131] = var(26); // [ var(131) , var(26) ]
+                D[35,131] = (-1)*var(35); // [ var(131) , var(35) ]
+                D[38,131] = (-1)*var(38); // [ var(131) , var(38) ]
+                D[40,131] = var(40); // [ var(131) , var(40) ]
+                D[41,131] = (-1)*var(41); // [ var(131) , var(41) ]
+                D[42,131] = (-1)*var(42); // [ var(131) , var(42) ]
+                D[43,131] = var(43); // [ var(131) , var(43) ]
+                D[44,131] = (-1)*var(44); // [ var(131) , var(44) ]
+                D[45,131] = var(45); // [ var(131) , var(45) ]
+                D[46,131] = var(46); // [ var(131) , var(46) ]
+                D[47,131] = (-1)*var(47); // [ var(131) , var(47) ]
+                D[48,131] = var(48); // [ var(131) , var(48) ]
+                D[51,131] = var(51); // [ var(131) , var(51) ]
+                D[57,131] = (-1)*var(57); // [ var(131) , var(57) ]
+                D[58,131] = (-1)*var(58); // [ var(131) , var(58) ]
+                D[59,131] = var(59); // [ var(131) , var(59) ]
+                D[60,131] = var(60); // [ var(131) , var(60) ]
+                D[5,132] = (-1)*var(5); // [ var(132) , var(5) ]
+                D[6,132] = (2)*var(6); // [ var(132) , var(6) ]
+                D[7,132] = (-1)*var(7); // [ var(132) , var(7) ]
+                D[11,132] = (-1)*var(11); // [ var(132) , var(11) ]
+                D[12,132] = var(12); // [ var(132) , var(12) ]
+                D[13,132] = var(13); // [ var(132) , var(13) ]
+                D[16,132] = (-1)*var(16); // [ var(132) , var(16) ]
+                D[17,132] = (-1)*var(17); // [ var(132) , var(17) ]
+                D[18,132] = var(18); // [ var(132) , var(18) ]
+                D[21,132] = (-1)*var(21); // [ var(132) , var(21) ]
+                D[22,132] = (-1)*var(22); // [ var(132) , var(22) ]
+                D[23,132] = var(23); // [ var(132) , var(23) ]
+                D[24,132] = var(24); // [ var(132) , var(24) ]
+                D[26,132] = (-1)*var(26); // [ var(132) , var(26) ]
+                D[27,132] = var(27); // [ var(132) , var(27) ]
+                D[28,132] = (-1)*var(28); // [ var(132) , var(28) ]
+                D[29,132] = var(29); // [ var(132) , var(29) ]
+                D[32,132] = (-1)*var(32); // [ var(132) , var(32) ]
+                D[33,132] = var(33); // [ var(132) , var(33) ]
+                D[35,132] = var(35); // [ var(132) , var(35) ]
+                D[37,132] = (-1)*var(37); // [ var(132) , var(37) ]
+                D[38,132] = var(38); // [ var(132) , var(38) ]
+                D[42,132] = var(42); // [ var(132) , var(42) ]
+                D[45,132] = (-1)*var(45); // [ var(132) , var(45) ]
+                D[48,132] = (-1)*var(48); // [ var(132) , var(48) ]
+                D[49,132] = var(49); // [ var(132) , var(49) ]
+                D[51,132] = (-1)*var(51); // [ var(132) , var(51) ]
+                D[52,132] = var(52); // [ var(132) , var(52) ]
+                D[54,132] = (-1)*var(54); // [ var(132) , var(54) ]
+                D[55,132] = var(55); // [ var(132) , var(55) ]
+                D[56,132] = (-1)*var(56); // [ var(132) , var(56) ]
+                D[57,132] = var(57); // [ var(132) , var(57) ]
+                D[58,132] = var(58); // [ var(132) , var(58) ]
+                D[6,133] = (-1)*var(6); // [ var(133) , var(6) ]
+                D[7,133] = (2)*var(7); // [ var(133) , var(7) ]
+                D[12,133] = (-1)*var(12); // [ var(133) , var(12) ]
+                D[13,133] = var(13); // [ var(133) , var(13) ]
+                D[18,133] = (-1)*var(18); // [ var(133) , var(18) ]
+                D[19,133] = var(19); // [ var(133) , var(19) ]
+                D[23,133] = (-1)*var(23); // [ var(133) , var(23) ]
+                D[24,133] = (-1)*var(24); // [ var(133) , var(24) ]
+                D[25,133] = var(25); // [ var(133) , var(25) ]
+                D[27,133] = (-1)*var(27); // [ var(133) , var(27) ]
+                D[29,133] = (-1)*var(29); // [ var(133) , var(29) ]
+                D[30,133] = var(30); // [ var(133) , var(30) ]
+                D[31,133] = var(31); // [ var(133) , var(31) ]
+                D[33,133] = (-1)*var(33); // [ var(133) , var(33) ]
+                D[34,133] = var(34); // [ var(133) , var(34) ]
+                D[35,133] = (-1)*var(35); // [ var(133) , var(35) ]
+                D[36,133] = var(36); // [ var(133) , var(36) ]
+                D[38,133] = (-1)*var(38); // [ var(133) , var(38) ]
+                D[39,133] = var(39); // [ var(133) , var(39) ]
+                D[40,133] = (-1)*var(40); // [ var(133) , var(40) ]
+                D[41,133] = var(41); // [ var(133) , var(41) ]
+                D[42,133] = (-1)*var(42); // [ var(133) , var(42) ]
+                D[43,133] = (-1)*var(43); // [ var(133) , var(43) ]
+                D[44,133] = var(44); // [ var(133) , var(44) ]
+                D[45,133] = var(45); // [ var(133) , var(45) ]
+                D[46,133] = (-1)*var(46); // [ var(133) , var(46) ]
+                D[47,133] = var(47); // [ var(133) , var(47) ]
+                D[48,133] = var(48); // [ var(133) , var(48) ]
+                D[50,133] = (-1)*var(50); // [ var(133) , var(50) ]
+                D[51,133] = var(51); // [ var(133) , var(51) ]
+                D[53,133] = (-1)*var(53); // [ var(133) , var(53) ]
+                D[54,133] = var(54); // [ var(133) , var(54) ]
+                D[56,133] = var(56); // [ var(133) , var(56) ]
+        // H(i) * Y(j):
+                D[64,127] = (-2)*var(64); // [ var(127) , var(64) ]
+                D[66,127] = var(66); // [ var(127) , var(66) ]
+                D[71,127] = (-1)*var(71); // [ var(127) , var(71) ]
+                D[73,127] = var(73); // [ var(127) , var(73) ]
+                D[77,127] = (-1)*var(77); // [ var(127) , var(77) ]
+                D[78,127] = var(78); // [ var(127) , var(78) ]
+                D[80,127] = var(80); // [ var(127) , var(80) ]
+                D[83,127] = (-1)*var(83); // [ var(127) , var(83) ]
+                D[84,127] = (-1)*var(84); // [ var(127) , var(84) ]
+                D[85,127] = var(85); // [ var(127) , var(85) ]
+                D[87,127] = var(87); // [ var(127) , var(87) ]
+                D[89,127] = (-1)*var(89); // [ var(127) , var(89) ]
+                D[90,127] = (-1)*var(90); // [ var(127) , var(90) ]
+                D[91,127] = var(91); // [ var(127) , var(91) ]
+                D[92,127] = var(92); // [ var(127) , var(92) ]
+                D[94,127] = var(94); // [ var(127) , var(94) ]
+                D[95,127] = (-1)*var(95); // [ var(127) , var(95) ]
+                D[96,127] = (-1)*var(96); // [ var(127) , var(96) ]
+                D[97,127] = (-1)*var(97); // [ var(127) , var(97) ]
+                D[98,127] = var(98); // [ var(127) , var(98) ]
+                D[99,127] = var(99); // [ var(127) , var(99) ]
+                D[101,127] = (-1)*var(101); // [ var(127) , var(101) ]
+                D[102,127] = (-1)*var(102); // [ var(127) , var(102) ]
+                D[103,127] = var(103); // [ var(127) , var(103) ]
+                D[104,127] = var(104); // [ var(127) , var(104) ]
+                D[106,127] = (-1)*var(106); // [ var(127) , var(106) ]
+                D[107,127] = (-1)*var(107); // [ var(127) , var(107) ]
+                D[108,127] = var(108); // [ var(127) , var(108) ]
+                D[111,127] = (-1)*var(111); // [ var(127) , var(111) ]
+                D[112,127] = var(112); // [ var(127) , var(112) ]
+                D[115,127] = (-1)*var(115); // [ var(127) , var(115) ]
+                D[125,127] = var(125); // [ var(127) , var(125) ]
+                D[126,127] = (-1)*var(126); // [ var(127) , var(126) ]
+                D[65,128] = (-2)*var(65); // [ var(128) , var(65) ]
+                D[67,128] = var(67); // [ var(128) , var(67) ]
+                D[72,128] = (-1)*var(72); // [ var(128) , var(72) ]
+                D[73,128] = var(73); // [ var(128) , var(73) ]
+                D[74,128] = var(74); // [ var(128) , var(74) ]
+                D[77,128] = var(77); // [ var(128) , var(77) ]
+                D[78,128] = (-1)*var(78); // [ var(128) , var(78) ]
+                D[79,128] = (-1)*var(79); // [ var(128) , var(79) ]
+                D[80,128] = var(80); // [ var(128) , var(80) ]
+                D[81,128] = var(81); // [ var(128) , var(81) ]
+                D[83,128] = (-1)*var(83); // [ var(128) , var(83) ]
+                D[84,128] = var(84); // [ var(128) , var(84) ]
+                D[85,128] = (-1)*var(85); // [ var(128) , var(85) ]
+                D[86,128] = (-1)*var(86); // [ var(128) , var(86) ]
+                D[87,128] = var(87); // [ var(128) , var(87) ]
+                D[88,128] = var(88); // [ var(128) , var(88) ]
+                D[89,128] = (-1)*var(89); // [ var(128) , var(89) ]
+                D[90,128] = var(90); // [ var(128) , var(90) ]
+                D[92,128] = (-1)*var(92); // [ var(128) , var(92) ]
+                D[93,128] = (-1)*var(93); // [ var(128) , var(93) ]
+                D[94,128] = var(94); // [ var(128) , var(94) ]
+                D[96,128] = (-1)*var(96); // [ var(128) , var(96) ]
+                D[97,128] = var(97); // [ var(128) , var(97) ]
+                D[99,128] = (-1)*var(99); // [ var(128) , var(99) ]
+                D[102,128] = (-1)*var(102); // [ var(128) , var(102) ]
+                D[113,128] = var(113); // [ var(128) , var(113) ]
+                D[116,128] = (-1)*var(116); // [ var(128) , var(116) ]
+                D[117,128] = var(117); // [ var(128) , var(117) ]
+                D[119,128] = (-1)*var(119); // [ var(128) , var(119) ]
+                D[120,128] = var(120); // [ var(128) , var(120) ]
+                D[121,128] = (-1)*var(121); // [ var(128) , var(121) ]
+                D[122,128] = var(122); // [ var(128) , var(122) ]
+                D[123,128] = (-1)*var(123); // [ var(128) , var(123) ]
+                D[64,129] = var(64); // [ var(129) , var(64) ]
+                D[66,129] = (-2)*var(66); // [ var(129) , var(66) ]
+                D[67,129] = var(67); // [ var(129) , var(67) ]
+                D[71,129] = (-1)*var(71); // [ var(129) , var(71) ]
+                D[72,129] = var(72); // [ var(129) , var(72) ]
+                D[73,129] = (-1)*var(73); // [ var(129) , var(73) ]
+                D[74,129] = var(74); // [ var(129) , var(74) ]
+                D[78,129] = (-1)*var(78); // [ var(129) , var(78) ]
+                D[79,129] = var(79); // [ var(129) , var(79) ]
+                D[80,129] = (-1)*var(80); // [ var(129) , var(80) ]
+                D[81,129] = var(81); // [ var(129) , var(81) ]
+                D[85,129] = (-1)*var(85); // [ var(129) , var(85) ]
+                D[86,129] = var(86); // [ var(129) , var(86) ]
+                D[87,129] = (-1)*var(87); // [ var(129) , var(87) ]
+                D[88,129] = var(88); // [ var(129) , var(88) ]
+                D[92,129] = (-1)*var(92); // [ var(129) , var(92) ]
+                D[93,129] = var(93); // [ var(129) , var(93) ]
+                D[94,129] = (-1)*var(94); // [ var(129) , var(94) ]
+                D[95,129] = var(95); // [ var(129) , var(95) ]
+                D[99,129] = (-1)*var(99); // [ var(129) , var(99) ]
+                D[100,129] = (-1)*var(100); // [ var(129) , var(100) ]
+                D[101,129] = var(101); // [ var(129) , var(101) ]
+                D[105,129] = (-1)*var(105); // [ var(129) , var(105) ]
+                D[106,129] = var(106); // [ var(129) , var(106) ]
+                D[107,129] = var(107); // [ var(129) , var(107) ]
+                D[109,129] = (-1)*var(109); // [ var(129) , var(109) ]
+                D[110,129] = (-1)*var(110); // [ var(129) , var(110) ]
+                D[111,129] = var(111); // [ var(129) , var(111) ]
+                D[114,129] = (-1)*var(114); // [ var(129) , var(114) ]
+                D[115,129] = var(115); // [ var(129) , var(115) ]
+                D[118,129] = (-1)*var(118); // [ var(129) , var(118) ]
+                D[124,129] = var(124); // [ var(129) , var(124) ]
+                D[125,129] = (-1)*var(125); // [ var(129) , var(125) ]
+                D[65,130] = var(65); // [ var(130) , var(65) ]
+                D[66,130] = var(66); // [ var(130) , var(66) ]
+                D[67,130] = (-2)*var(67); // [ var(130) , var(67) ]
+                D[68,130] = var(68); // [ var(130) , var(68) ]
+                D[71,130] = var(71); // [ var(130) , var(71) ]
+                D[72,130] = (-1)*var(72); // [ var(130) , var(72) ]
+                D[73,130] = (-1)*var(73); // [ var(130) , var(73) ]
+                D[74,130] = (-1)*var(74); // [ var(130) , var(74) ]
+                D[75,130] = var(75); // [ var(130) , var(75) ]
+                D[77,130] = (-1)*var(77); // [ var(130) , var(77) ]
+                D[81,130] = (-1)*var(81); // [ var(130) , var(81) ]
+                D[82,130] = var(82); // [ var(130) , var(82) ]
+                D[85,130] = var(85); // [ var(130) , var(85) ]
+                D[88,130] = (-1)*var(88); // [ var(130) , var(88) ]
+                D[89,130] = var(89); // [ var(130) , var(89) ]
+                D[91,130] = (-1)*var(91); // [ var(130) , var(91) ]
+                D[92,130] = var(92); // [ var(130) , var(92) ]
+                D[95,130] = (-1)*var(95); // [ var(130) , var(95) ]
+                D[96,130] = var(96); // [ var(130) , var(96) ]
+                D[98,130] = (-1)*var(98); // [ var(130) , var(98) ]
+                D[99,130] = var(99); // [ var(130) , var(99) ]
+                D[101,130] = (-1)*var(101); // [ var(130) , var(101) ]
+                D[102,130] = var(102); // [ var(130) , var(102) ]
+                D[104,130] = (-1)*var(104); // [ var(130) , var(104) ]
+                D[107,130] = (-1)*var(107); // [ var(130) , var(107) ]
+                D[109,130] = var(109); // [ var(130) , var(109) ]
+                D[113,130] = (-1)*var(113); // [ var(130) , var(113) ]
+                D[114,130] = var(114); // [ var(130) , var(114) ]
+                D[117,130] = (-1)*var(117); // [ var(130) , var(117) ]
+                D[118,130] = var(118); // [ var(130) , var(118) ]
+                D[120,130] = (-1)*var(120); // [ var(130) , var(120) ]
+                D[123,130] = var(123); // [ var(130) , var(123) ]
+                D[124,130] = (-1)*var(124); // [ var(130) , var(124) ]
+                D[67,131] = var(67); // [ var(131) , var(67) ]
+                D[68,131] = (-2)*var(68); // [ var(131) , var(68) ]
+                D[69,131] = var(69); // [ var(131) , var(69) ]
+                D[72,131] = var(72); // [ var(131) , var(72) ]
+                D[73,131] = var(73); // [ var(131) , var(73) ]
+                D[74,131] = (-1)*var(74); // [ var(131) , var(74) ]
+                D[75,131] = (-1)*var(75); // [ var(131) , var(75) ]
+                D[76,131] = var(76); // [ var(131) , var(76) ]
+                D[77,131] = var(77); // [ var(131) , var(77) ]
+                D[78,131] = var(78); // [ var(131) , var(78) ]
+                D[79,131] = (-1)*var(79); // [ var(131) , var(79) ]
+                D[80,131] = (-1)*var(80); // [ var(131) , var(80) ]
+                D[82,131] = (-1)*var(82); // [ var(131) , var(82) ]
+                D[83,131] = var(83); // [ var(131) , var(83) ]
+                D[84,131] = (-1)*var(84); // [ var(131) , var(84) ]
+                D[85,131] = (-1)*var(85); // [ var(131) , var(85) ]
+                D[89,131] = (-1)*var(89); // [ var(131) , var(89) ]
+                D[98,131] = var(98); // [ var(131) , var(98) ]
+                D[101,131] = var(101); // [ var(131) , var(101) ]
+                D[103,131] = (-1)*var(103); // [ var(131) , var(103) ]
+                D[104,131] = var(104); // [ var(131) , var(104) ]
+                D[105,131] = var(105); // [ var(131) , var(105) ]
+                D[106,131] = (-1)*var(106); // [ var(131) , var(106) ]
+                D[107,131] = var(107); // [ var(131) , var(107) ]
+                D[108,131] = (-1)*var(108); // [ var(131) , var(108) ]
+                D[109,131] = (-1)*var(109); // [ var(131) , var(109) ]
+                D[110,131] = var(110); // [ var(131) , var(110) ]
+                D[111,131] = (-1)*var(111); // [ var(131) , var(111) ]
+                D[114,131] = (-1)*var(114); // [ var(131) , var(114) ]
+                D[120,131] = var(120); // [ var(131) , var(120) ]
+                D[121,131] = var(121); // [ var(131) , var(121) ]
+                D[122,131] = (-1)*var(122); // [ var(131) , var(122) ]
+                D[123,131] = (-1)*var(123); // [ var(131) , var(123) ]
+                D[68,132] = var(68); // [ var(132) , var(68) ]
+                D[69,132] = (-2)*var(69); // [ var(132) , var(69) ]
+                D[70,132] = var(70); // [ var(132) , var(70) ]
+                D[74,132] = var(74); // [ var(132) , var(74) ]
+                D[75,132] = (-1)*var(75); // [ var(132) , var(75) ]
+                D[76,132] = (-1)*var(76); // [ var(132) , var(76) ]
+                D[79,132] = var(79); // [ var(132) , var(79) ]
+                D[80,132] = var(80); // [ var(132) , var(80) ]
+                D[81,132] = (-1)*var(81); // [ var(132) , var(81) ]
+                D[84,132] = var(84); // [ var(132) , var(84) ]
+                D[85,132] = var(85); // [ var(132) , var(85) ]
+                D[86,132] = (-1)*var(86); // [ var(132) , var(86) ]
+                D[87,132] = (-1)*var(87); // [ var(132) , var(87) ]
+                D[89,132] = var(89); // [ var(132) , var(89) ]
+                D[90,132] = (-1)*var(90); // [ var(132) , var(90) ]
+                D[91,132] = var(91); // [ var(132) , var(91) ]
+                D[92,132] = (-1)*var(92); // [ var(132) , var(92) ]
+                D[95,132] = var(95); // [ var(132) , var(95) ]
+                D[96,132] = (-1)*var(96); // [ var(132) , var(96) ]
+                D[98,132] = (-1)*var(98); // [ var(132) , var(98) ]
+                D[100,132] = var(100); // [ var(132) , var(100) ]
+                D[101,132] = (-1)*var(101); // [ var(132) , var(101) ]
+                D[105,132] = (-1)*var(105); // [ var(132) , var(105) ]
+                D[108,132] = var(108); // [ var(132) , var(108) ]
+                D[111,132] = var(111); // [ var(132) , var(111) ]
+                D[112,132] = (-1)*var(112); // [ var(132) , var(112) ]
+                D[114,132] = var(114); // [ var(132) , var(114) ]
+                D[115,132] = (-1)*var(115); // [ var(132) , var(115) ]
+                D[117,132] = var(117); // [ var(132) , var(117) ]
+                D[118,132] = (-1)*var(118); // [ var(132) , var(118) ]
+                D[119,132] = var(119); // [ var(132) , var(119) ]
+                D[120,132] = (-1)*var(120); // [ var(132) , var(120) ]
+                D[121,132] = (-1)*var(121); // [ var(132) , var(121) ]
+                D[69,133] = var(69); // [ var(133) , var(69) ]
+                D[70,133] = (-2)*var(70); // [ var(133) , var(70) ]
+                D[75,133] = var(75); // [ var(133) , var(75) ]
+                D[76,133] = (-1)*var(76); // [ var(133) , var(76) ]
+                D[81,133] = var(81); // [ var(133) , var(81) ]
+                D[82,133] = (-1)*var(82); // [ var(133) , var(82) ]
+                D[86,133] = var(86); // [ var(133) , var(86) ]
+                D[87,133] = var(87); // [ var(133) , var(87) ]
+                D[88,133] = (-1)*var(88); // [ var(133) , var(88) ]
+                D[90,133] = var(90); // [ var(133) , var(90) ]
+                D[92,133] = var(92); // [ var(133) , var(92) ]
+                D[93,133] = (-1)*var(93); // [ var(133) , var(93) ]
+                D[94,133] = (-1)*var(94); // [ var(133) , var(94) ]
+                D[96,133] = var(96); // [ var(133) , var(96) ]
+                D[97,133] = (-1)*var(97); // [ var(133) , var(97) ]
+                D[98,133] = var(98); // [ var(133) , var(98) ]
+                D[99,133] = (-1)*var(99); // [ var(133) , var(99) ]
+                D[101,133] = var(101); // [ var(133) , var(101) ]
+                D[102,133] = (-1)*var(102); // [ var(133) , var(102) ]
+                D[103,133] = var(103); // [ var(133) , var(103) ]
+                D[104,133] = (-1)*var(104); // [ var(133) , var(104) ]
+                D[105,133] = var(105); // [ var(133) , var(105) ]
+                D[106,133] = var(106); // [ var(133) , var(106) ]
+                D[107,133] = (-1)*var(107); // [ var(133) , var(107) ]
+                D[108,133] = (-1)*var(108); // [ var(133) , var(108) ]
+                D[109,133] = var(109); // [ var(133) , var(109) ]
+                D[110,133] = (-1)*var(110); // [ var(133) , var(110) ]
+                D[111,133] = (-1)*var(111); // [ var(133) , var(111) ]
+                D[113,133] = var(113); // [ var(133) , var(113) ]
+                D[114,133] = (-1)*var(114); // [ var(133) , var(114) ]
+                D[116,133] = var(116); // [ var(133) , var(116) ]
+                D[117,133] = (-1)*var(117); // [ var(133) , var(117) ]
+                D[119,133] = (-1)*var(119); // [ var(133) , var(119) ]
+        // Y(i) * X(j):
+                D[1,64] = (-1)*var(127); // [ var(64) , var(1) ]
+                D[8,64] = (-1)*var(3); // [ var(64) , var(8) ]
+                D[14,64] = (-1)*var(10); // [ var(64) , var(14) ]
+                D[20,64] = (-1)*var(15); // [ var(64) , var(20) ]
+                D[21,64] = (-1)*var(17); // [ var(64) , var(21) ]
+                D[26,64] = (-1)*var(22); // [ var(64) , var(26) ]
+                D[27,64] = (-1)*var(24); // [ var(64) , var(27) ]
+                D[32,64] = (-1)*var(28); // [ var(64) , var(32) ]
+                D[33,64] = (-1)*var(29); // [ var(64) , var(33) ]
+                D[34,64] = (-1)*var(31); // [ var(64) , var(34) ]
+                D[38,64] = (-1)*var(35); // [ var(64) , var(38) ]
+                D[39,64] = (-1)*var(36); // [ var(64) , var(39) ]
+                D[43,64] = (-1)*var(40); // [ var(64) , var(43) ]
+                D[44,64] = (-1)*var(41); // [ var(64) , var(44) ]
+                D[48,64] = (-1)*var(45); // [ var(64) , var(48) ]
+                D[52,64] = (-1)*var(49); // [ var(64) , var(52) ]
+                D[63,64] = var(62); // [ var(64) , var(63) ]
+                D[2,65] = (-1)*var(128); // [ var(65) , var(2) ]
+                D[9,65] = (-1)*var(4); // [ var(65) , var(9) ]
+                D[15,65] = (-1)*var(10); // [ var(65) , var(15) ]
+                D[16,65] = (-1)*var(11); // [ var(65) , var(16) ]
+                D[20,65] = (-1)*var(14); // [ var(65) , var(20) ]
+                D[22,65] = (-1)*var(17); // [ var(65) , var(22) ]
+                D[23,65] = (-1)*var(18); // [ var(65) , var(23) ]
+                D[26,65] = (-1)*var(21); // [ var(65) , var(26) ]
+                D[29,65] = (-1)*var(24); // [ var(65) , var(29) ]
+                D[30,65] = (-1)*var(25); // [ var(65) , var(30) ]
+                D[33,65] = (-1)*var(27); // [ var(65) , var(33) ]
+                D[36,65] = (-1)*var(31); // [ var(65) , var(36) ]
+                D[39,65] = (-1)*var(34); // [ var(65) , var(39) ]
+                D[53,65] = var(50); // [ var(65) , var(53) ]
+                D[56,65] = var(54); // [ var(65) , var(56) ]
+                D[58,65] = var(57); // [ var(65) , var(58) ]
+                D[60,65] = var(59); // [ var(65) , var(60) ]
+                D[3,66] = (-1)*var(129); // [ var(66) , var(3) ]
+                D[8,66] = var(1); // [ var(66) , var(8) ]
+                D[10,66] = (-1)*var(4); // [ var(66) , var(10) ]
+                D[15,66] = (-1)*var(9); // [ var(66) , var(15) ]
+                D[17,66] = (-1)*var(11); // [ var(66) , var(17) ]
+                D[22,66] = (-1)*var(16); // [ var(66) , var(22) ]
+                D[24,66] = (-1)*var(18); // [ var(66) , var(24) ]
+                D[29,66] = (-1)*var(23); // [ var(66) , var(29) ]
+                D[31,66] = (-1)*var(25); // [ var(66) , var(31) ]
+                D[36,66] = (-1)*var(30); // [ var(66) , var(36) ]
+                D[37,66] = (-1)*var(32); // [ var(66) , var(37) ]
+                D[42,66] = (-1)*var(38); // [ var(66) , var(42) ]
+                D[46,66] = (-1)*var(43); // [ var(66) , var(46) ]
+                D[47,66] = (-1)*var(44); // [ var(66) , var(47) ]
+                D[51,66] = (-1)*var(48); // [ var(66) , var(51) ]
+                D[55,66] = (-1)*var(52); // [ var(66) , var(55) ]
+                D[62,66] = var(61); // [ var(66) , var(62) ]
+                D[4,67] = (-1)*var(130); // [ var(67) , var(4) ]
+                D[9,67] = var(2); // [ var(67) , var(9) ]
+                D[10,67] = var(3); // [ var(67) , var(10) ]
+                D[11,67] = (-1)*var(5); // [ var(67) , var(11) ]
+                D[14,67] = var(8); // [ var(67) , var(14) ]
+                D[18,67] = (-1)*var(12); // [ var(67) , var(18) ]
+                D[25,67] = (-1)*var(19); // [ var(67) , var(25) ]
+                D[28,67] = var(22); // [ var(67) , var(28) ]
+                D[32,67] = var(26); // [ var(67) , var(32) ]
+                D[35,67] = var(29); // [ var(67) , var(35) ]
+                D[38,67] = var(33); // [ var(67) , var(38) ]
+                D[41,67] = var(36); // [ var(67) , var(41) ]
+                D[44,67] = var(39); // [ var(67) , var(44) ]
+                D[50,67] = var(46); // [ var(67) , var(50) ]
+                D[54,67] = var(51); // [ var(67) , var(54) ]
+                D[57,67] = var(55); // [ var(67) , var(57) ]
+                D[61,67] = var(60); // [ var(67) , var(61) ]
+                D[5,68] = (-1)*var(131); // [ var(68) , var(5) ]
+                D[11,68] = var(4); // [ var(68) , var(11) ]
+                D[12,68] = (-1)*var(6); // [ var(68) , var(12) ]
+                D[16,68] = var(9); // [ var(68) , var(16) ]
+                D[17,68] = var(10); // [ var(68) , var(17) ]
+                D[19,68] = (-1)*var(13); // [ var(68) , var(19) ]
+                D[21,68] = var(14); // [ var(68) , var(21) ]
+                D[22,68] = var(15); // [ var(68) , var(22) ]
+                D[26,68] = var(20); // [ var(68) , var(26) ]
+                D[40,68] = var(35); // [ var(68) , var(40) ]
+                D[43,68] = var(38); // [ var(68) , var(43) ]
+                D[45,68] = var(41); // [ var(68) , var(45) ]
+                D[46,68] = var(42); // [ var(68) , var(46) ]
+                D[48,68] = var(44); // [ var(68) , var(48) ]
+                D[51,68] = var(47); // [ var(68) , var(51) ]
+                D[59,68] = var(57); // [ var(68) , var(59) ]
+                D[60,68] = var(58); // [ var(68) , var(60) ]
+                D[6,69] = (-1)*var(132); // [ var(69) , var(6) ]
+                D[12,69] = var(5); // [ var(69) , var(12) ]
+                D[13,69] = (-1)*var(7); // [ var(69) , var(13) ]
+                D[18,69] = var(11); // [ var(69) , var(18) ]
+                D[23,69] = var(16); // [ var(69) , var(23) ]
+                D[24,69] = var(17); // [ var(69) , var(24) ]
+                D[27,69] = var(21); // [ var(69) , var(27) ]
+                D[29,69] = var(22); // [ var(69) , var(29) ]
+                D[33,69] = var(26); // [ var(69) , var(33) ]
+                D[35,69] = var(28); // [ var(69) , var(35) ]
+                D[38,69] = var(32); // [ var(69) , var(38) ]
+                D[42,69] = var(37); // [ var(69) , var(42) ]
+                D[49,69] = var(45); // [ var(69) , var(49) ]
+                D[52,69] = var(48); // [ var(69) , var(52) ]
+                D[55,69] = var(51); // [ var(69) , var(55) ]
+                D[57,69] = var(54); // [ var(69) , var(57) ]
+                D[58,69] = var(56); // [ var(69) , var(58) ]
+                D[7,70] = (-1)*var(133); // [ var(70) , var(7) ]
+                D[13,70] = var(6); // [ var(70) , var(13) ]
+                D[19,70] = var(12); // [ var(70) , var(19) ]
+                D[25,70] = var(18); // [ var(70) , var(25) ]
+                D[30,70] = var(23); // [ var(70) , var(30) ]
+                D[31,70] = var(24); // [ var(70) , var(31) ]
+                D[34,70] = var(27); // [ var(70) , var(34) ]
+                D[36,70] = var(29); // [ var(70) , var(36) ]
+                D[39,70] = var(33); // [ var(70) , var(39) ]
+                D[41,70] = var(35); // [ var(70) , var(41) ]
+                D[44,70] = var(38); // [ var(70) , var(44) ]
+                D[45,70] = var(40); // [ var(70) , var(45) ]
+                D[47,70] = var(42); // [ var(70) , var(47) ]
+                D[48,70] = var(43); // [ var(70) , var(48) ]
+                D[51,70] = var(46); // [ var(70) , var(51) ]
+                D[54,70] = var(50); // [ var(70) , var(54) ]
+                D[56,70] = var(53); // [ var(70) , var(56) ]
+                D[1,71] = (-1)*var(66); // [ var(71) , var(1) ]
+                D[3,71] = var(64); // [ var(71) , var(3) ]
+                D[8,71] = (-1)*var(127)+(-1)*var(129); // [ var(71) , var(8) ]
+                D[14,71] = (-1)*var(4); // [ var(71) , var(14) ]
+                D[20,71] = (-1)*var(9); // [ var(71) , var(20) ]
+                D[21,71] = (-1)*var(11); // [ var(71) , var(21) ]
+                D[26,71] = (-1)*var(16); // [ var(71) , var(26) ]
+                D[27,71] = (-1)*var(18); // [ var(71) , var(27) ]
+                D[33,71] = (-1)*var(23); // [ var(71) , var(33) ]
+                D[34,71] = (-1)*var(25); // [ var(71) , var(34) ]
+                D[37,71] = var(28); // [ var(71) , var(37) ]
+                D[39,71] = (-1)*var(30); // [ var(71) , var(39) ]
+                D[42,71] = var(35); // [ var(71) , var(42) ]
+                D[46,71] = var(40); // [ var(71) , var(46) ]
+                D[47,71] = var(41); // [ var(71) , var(47) ]
+                D[51,71] = var(45); // [ var(71) , var(51) ]
+                D[55,71] = var(49); // [ var(71) , var(55) ]
+                D[63,71] = (-1)*var(61); // [ var(71) , var(63) ]
+                D[2,72] = (-1)*var(67); // [ var(72) , var(2) ]
+                D[4,72] = var(65); // [ var(72) , var(4) ]
+                D[9,72] = (-1)*var(128)+(-1)*var(130); // [ var(72) , var(9) ]
+                D[15,72] = var(3); // [ var(72) , var(15) ]
+                D[16,72] = (-1)*var(5); // [ var(72) , var(16) ]
+                D[20,72] = var(8); // [ var(72) , var(20) ]
+                D[23,72] = (-1)*var(12); // [ var(72) , var(23) ]
+                D[28,72] = (-1)*var(17); // [ var(72) , var(28) ]
+                D[30,72] = (-1)*var(19); // [ var(72) , var(30) ]
+                D[32,72] = (-1)*var(21); // [ var(72) , var(32) ]
+                D[35,72] = (-1)*var(24); // [ var(72) , var(35) ]
+                D[38,72] = (-1)*var(27); // [ var(72) , var(38) ]
+                D[41,72] = (-1)*var(31); // [ var(72) , var(41) ]
+                D[44,72] = (-1)*var(34); // [ var(72) , var(44) ]
+                D[53,72] = (-1)*var(46); // [ var(72) , var(53) ]
+                D[56,72] = (-1)*var(51); // [ var(72) , var(56) ]
+                D[58,72] = (-1)*var(55); // [ var(72) , var(58) ]
+                D[61,72] = var(59); // [ var(72) , var(61) ]
+                D[3,73] = (-1)*var(67); // [ var(73) , var(3) ]
+                D[4,73] = var(66); // [ var(73) , var(4) ]
+                D[10,73] = (-1)*var(129)+(-1)*var(130); // [ var(73) , var(10) ]
+                D[14,73] = var(1); // [ var(73) , var(14) ]
+                D[15,73] = var(2); // [ var(73) , var(15) ]
+                D[17,73] = (-1)*var(5); // [ var(73) , var(17) ]
+                D[24,73] = (-1)*var(12); // [ var(73) , var(24) ]
+                D[28,73] = (-1)*var(16); // [ var(73) , var(28) ]
+                D[31,73] = (-1)*var(19); // [ var(73) , var(31) ]
+                D[35,73] = (-1)*var(23); // [ var(73) , var(35) ]
+                D[37,73] = var(26); // [ var(73) , var(37) ]
+                D[41,73] = (-1)*var(30); // [ var(73) , var(41) ]
+                D[42,73] = var(33); // [ var(73) , var(42) ]
+                D[47,73] = var(39); // [ var(73) , var(47) ]
+                D[50,73] = (-1)*var(43); // [ var(73) , var(50) ]
+                D[54,73] = (-1)*var(48); // [ var(73) , var(54) ]
+                D[57,73] = (-1)*var(52); // [ var(73) , var(57) ]
+                D[62,73] = (-1)*var(60); // [ var(73) , var(62) ]
+                D[4,74] = (-1)*var(68); // [ var(74) , var(4) ]
+                D[5,74] = var(67); // [ var(74) , var(5) ]
+                D[11,74] = (-1)*var(130)+(-1)*var(131); // [ var(74) , var(11) ]
+                D[16,74] = var(2); // [ var(74) , var(16) ]
+                D[17,74] = var(3); // [ var(74) , var(17) ]
+                D[18,74] = (-1)*var(6); // [ var(74) , var(18) ]
+                D[21,74] = var(8); // [ var(74) , var(21) ]
+                D[25,74] = (-1)*var(13); // [ var(74) , var(25) ]
+                D[28,74] = (-1)*var(15); // [ var(74) , var(28) ]
+                D[32,74] = (-1)*var(20); // [ var(74) , var(32) ]
+                D[40,74] = var(29); // [ var(74) , var(40) ]
+                D[43,74] = var(33); // [ var(74) , var(43) ]
+                D[45,74] = var(36); // [ var(74) , var(45) ]
+                D[48,74] = var(39); // [ var(74) , var(48) ]
+                D[50,74] = (-1)*var(42); // [ var(74) , var(50) ]
+                D[54,74] = (-1)*var(47); // [ var(74) , var(54) ]
+                D[59,74] = var(55); // [ var(74) , var(59) ]
+                D[61,74] = (-1)*var(58); // [ var(74) , var(61) ]
+                D[5,75] = (-1)*var(69); // [ var(75) , var(5) ]
+                D[6,75] = var(68); // [ var(75) , var(6) ]
+                D[12,75] = (-1)*var(131)+(-1)*var(132); // [ var(75) , var(12) ]
+                D[18,75] = var(4); // [ var(75) , var(18) ]
+                D[19,75] = (-1)*var(7); // [ var(75) , var(19) ]
+                D[23,75] = var(9); // [ var(75) , var(23) ]
+                D[24,75] = var(10); // [ var(75) , var(24) ]
+                D[27,75] = var(14); // [ var(75) , var(27) ]
+                D[29,75] = var(15); // [ var(75) , var(29) ]
+                D[33,75] = var(20); // [ var(75) , var(33) ]
+                D[40,75] = (-1)*var(28); // [ var(75) , var(40) ]
+                D[43,75] = (-1)*var(32); // [ var(75) , var(43) ]
+                D[46,75] = (-1)*var(37); // [ var(75) , var(46) ]
+                D[49,75] = var(41); // [ var(75) , var(49) ]
+                D[52,75] = var(44); // [ var(75) , var(52) ]
+                D[55,75] = var(47); // [ var(75) , var(55) ]
+                D[59,75] = (-1)*var(54); // [ var(75) , var(59) ]
+                D[60,75] = (-1)*var(56); // [ var(75) , var(60) ]
+                D[6,76] = (-1)*var(70); // [ var(76) , var(6) ]
+                D[7,76] = var(69); // [ var(76) , var(7) ]
+                D[13,76] = (-1)*var(132)+(-1)*var(133); // [ var(76) , var(13) ]
+                D[19,76] = var(5); // [ var(76) , var(19) ]
+                D[25,76] = var(11); // [ var(76) , var(25) ]
+                D[30,76] = var(16); // [ var(76) , var(30) ]
+                D[31,76] = var(17); // [ var(76) , var(31) ]
+                D[34,76] = var(21); // [ var(76) , var(34) ]
+                D[36,76] = var(22); // [ var(76) , var(36) ]
+                D[39,76] = var(26); // [ var(76) , var(39) ]
+                D[41,76] = var(28); // [ var(76) , var(41) ]
+                D[44,76] = var(32); // [ var(76) , var(44) ]
+                D[47,76] = var(37); // [ var(76) , var(47) ]
+                D[49,76] = (-1)*var(40); // [ var(76) , var(49) ]
+                D[52,76] = (-1)*var(43); // [ var(76) , var(52) ]
+                D[55,76] = (-1)*var(46); // [ var(76) , var(55) ]
+                D[57,76] = (-1)*var(50); // [ var(76) , var(57) ]
+                D[58,76] = (-1)*var(53); // [ var(76) , var(58) ]
+                D[1,77] = (-1)*var(73); // [ var(77) , var(1) ]
+                D[4,77] = var(71); // [ var(77) , var(4) ]
+                D[8,77] = (-1)*var(67); // [ var(77) , var(8) ]
+                D[10,77] = var(64); // [ var(77) , var(10) ]
+                D[14,77] = (-1)*var(127)+(-1)*var(129)+(-1)*var(130); // [ var(77) , var(14) ]
+                D[20,77] = var(2); // [ var(77) , var(20) ]
+                D[21,77] = (-1)*var(5); // [ var(77) , var(21) ]
+                D[27,77] = (-1)*var(12); // [ var(77) , var(27) ]
+                D[32,77] = (-1)*var(16); // [ var(77) , var(32) ]
+                D[34,77] = (-1)*var(19); // [ var(77) , var(34) ]
+                D[37,77] = (-1)*var(22); // [ var(77) , var(37) ]
+                D[38,77] = (-1)*var(23); // [ var(77) , var(38) ]
+                D[42,77] = (-1)*var(29); // [ var(77) , var(42) ]
+                D[44,77] = (-1)*var(30); // [ var(77) , var(44) ]
+                D[47,77] = (-1)*var(36); // [ var(77) , var(47) ]
+                D[50,77] = var(40); // [ var(77) , var(50) ]
+                D[54,77] = var(45); // [ var(77) , var(54) ]
+                D[57,77] = var(49); // [ var(77) , var(57) ]
+                D[63,77] = var(60); // [ var(77) , var(63) ]
+                D[2,78] = (-1)*var(73); // [ var(78) , var(2) ]
+                D[3,78] = (-1)*var(72); // [ var(78) , var(3) ]
+                D[9,78] = var(66); // [ var(78) , var(9) ]
+                D[10,78] = var(65); // [ var(78) , var(10) ]
+                D[15,78] = (-1)*var(128)+(-1)*var(129)+(-1)*var(130); // [ var(78) , var(15) ]
+                D[20,78] = var(1); // [ var(78) , var(20) ]
+                D[22,78] = (-1)*var(5); // [ var(78) , var(22) ]
+                D[28,78] = var(11); // [ var(78) , var(28) ]
+                D[29,78] = (-1)*var(12); // [ var(78) , var(29) ]
+                D[35,78] = var(18); // [ var(78) , var(35) ]
+                D[36,78] = (-1)*var(19); // [ var(78) , var(36) ]
+                D[37,78] = (-1)*var(21); // [ var(78) , var(37) ]
+                D[41,78] = var(25); // [ var(78) , var(41) ]
+                D[42,78] = (-1)*var(27); // [ var(78) , var(42) ]
+                D[47,78] = (-1)*var(34); // [ var(78) , var(47) ]
+                D[53,78] = var(43); // [ var(78) , var(53) ]
+                D[56,78] = var(48); // [ var(78) , var(56) ]
+                D[58,78] = var(52); // [ var(78) , var(58) ]
+                D[62,78] = (-1)*var(59); // [ var(78) , var(62) ]
+                D[2,79] = (-1)*var(74); // [ var(79) , var(2) ]
+                D[5,79] = var(72); // [ var(79) , var(5) ]
+                D[9,79] = (-1)*var(68); // [ var(79) , var(9) ]
+                D[11,79] = var(65); // [ var(79) , var(11) ]
+                D[16,79] = (-1)*var(128)+(-1)*var(130)+(-1)*var(131); // [ var(79) , var(16) ]
+                D[22,79] = var(3); // [ var(79) , var(22) ]
+                D[23,79] = (-1)*var(6); // [ var(79) , var(23) ]
+                D[26,79] = var(8); // [ var(79) , var(26) ]
+                D[28,79] = var(10); // [ var(79) , var(28) ]
+                D[30,79] = (-1)*var(13); // [ var(79) , var(30) ]
+                D[32,79] = var(14); // [ var(79) , var(32) ]
+                D[40,79] = (-1)*var(24); // [ var(79) , var(40) ]
+                D[43,79] = (-1)*var(27); // [ var(79) , var(43) ]
+                D[45,79] = (-1)*var(31); // [ var(79) , var(45) ]
+                D[48,79] = (-1)*var(34); // [ var(79) , var(48) ]
+                D[53,79] = var(42); // [ var(79) , var(53) ]
+                D[56,79] = var(47); // [ var(79) , var(56) ]
+                D[60,79] = (-1)*var(55); // [ var(79) , var(60) ]
+                D[61,79] = (-1)*var(57); // [ var(79) , var(61) ]
+                D[3,80] = (-1)*var(74); // [ var(80) , var(3) ]
+                D[5,80] = var(73); // [ var(80) , var(5) ]
+                D[10,80] = (-1)*var(68); // [ var(80) , var(10) ]
+                D[11,80] = var(66); // [ var(80) , var(11) ]
+                D[17,80] = (-1)*var(129)+(-1)*var(130)+(-1)*var(131); // [ var(80) , var(17) ]
+                D[21,80] = var(1); // [ var(80) , var(21) ]
+                D[22,80] = var(2); // [ var(80) , var(22) ]
+                D[24,80] = (-1)*var(6); // [ var(80) , var(24) ]
+                D[28,80] = var(9); // [ var(80) , var(28) ]
+                D[31,80] = (-1)*var(13); // [ var(80) , var(31) ]
+                D[37,80] = (-1)*var(20); // [ var(80) , var(37) ]
+                D[40,80] = (-1)*var(23); // [ var(80) , var(40) ]
+                D[45,80] = (-1)*var(30); // [ var(80) , var(45) ]
+                D[46,80] = var(33); // [ var(80) , var(46) ]
+                D[50,80] = var(38); // [ var(80) , var(50) ]
+                D[51,80] = var(39); // [ var(80) , var(51) ]
+                D[54,80] = var(44); // [ var(80) , var(54) ]
+                D[59,80] = (-1)*var(52); // [ var(80) , var(59) ]
+                D[62,80] = var(58); // [ var(80) , var(62) ]
+                D[4,81] = (-1)*var(75); // [ var(81) , var(4) ]
+                D[6,81] = var(74); // [ var(81) , var(6) ]
+                D[11,81] = (-1)*var(69); // [ var(81) , var(11) ]
+                D[12,81] = var(67); // [ var(81) , var(12) ]
+                D[18,81] = (-1)*var(130)+(-1)*var(131)+(-1)*var(132); // [ var(81) , var(18) ]
+                D[23,81] = var(2); // [ var(81) , var(23) ]
+                D[24,81] = var(3); // [ var(81) , var(24) ]
+                D[25,81] = (-1)*var(7); // [ var(81) , var(25) ]
+                D[27,81] = var(8); // [ var(81) , var(27) ]
+                D[35,81] = (-1)*var(15); // [ var(81) , var(35) ]
+                D[38,81] = (-1)*var(20); // [ var(81) , var(38) ]
+                D[40,81] = (-1)*var(22); // [ var(81) , var(40) ]
+                D[43,81] = (-1)*var(26); // [ var(81) , var(43) ]
+                D[49,81] = var(36); // [ var(81) , var(49) ]
+                D[50,81] = var(37); // [ var(81) , var(50) ]
+                D[52,81] = var(39); // [ var(81) , var(52) ]
+                D[57,81] = (-1)*var(47); // [ var(81) , var(57) ]
+                D[59,81] = (-1)*var(51); // [ var(81) , var(59) ]
+                D[61,81] = var(56); // [ var(81) , var(61) ]
+                D[5,82] = (-1)*var(76); // [ var(82) , var(5) ]
+                D[7,82] = var(75); // [ var(82) , var(7) ]
+                D[12,82] = (-1)*var(70); // [ var(82) , var(12) ]
+                D[13,82] = var(68); // [ var(82) , var(13) ]
+                D[19,82] = (-1)*var(131)+(-1)*var(132)+(-1)*var(133); // [ var(82) , var(19) ]
+                D[25,82] = var(4); // [ var(82) , var(25) ]
+                D[30,82] = var(9); // [ var(82) , var(30) ]
+                D[31,82] = var(10); // [ var(82) , var(31) ]
+                D[34,82] = var(14); // [ var(82) , var(34) ]
+                D[36,82] = var(15); // [ var(82) , var(36) ]
+                D[39,82] = var(20); // [ var(82) , var(39) ]
+                D[45,82] = (-1)*var(28); // [ var(82) , var(45) ]
+                D[48,82] = (-1)*var(32); // [ var(82) , var(48) ]
+                D[49,82] = (-1)*var(35); // [ var(82) , var(49) ]
+                D[51,82] = (-1)*var(37); // [ var(82) , var(51) ]
+                D[52,82] = (-1)*var(38); // [ var(82) , var(52) ]
+                D[55,82] = (-1)*var(42); // [ var(82) , var(55) ]
+                D[59,82] = var(50); // [ var(82) , var(59) ]
+                D[60,82] = var(53); // [ var(82) , var(60) ]
+                D[1,83] = (-1)*var(78); // [ var(83) , var(1) ]
+                D[2,83] = (-1)*var(77); // [ var(83) , var(2) ]
+                D[8,83] = (-1)*var(72); // [ var(83) , var(8) ]
+                D[9,83] = var(71); // [ var(83) , var(9) ]
+                D[14,83] = var(65); // [ var(83) , var(14) ]
+                D[15,83] = var(64); // [ var(83) , var(15) ]
+                D[20,83] = (-1)*var(127)+(-1)*var(128)+(-1)*var(129)+(-1)*var(130); // [ var(83) , var(20) ]
+                D[26,83] = (-1)*var(5); // [ var(83) , var(26) ]
+                D[32,83] = var(11); // [ var(83) , var(32) ]
+                D[33,83] = (-1)*var(12); // [ var(83) , var(33) ]
+                D[37,83] = var(17); // [ var(83) , var(37) ]
+                D[38,83] = var(18); // [ var(83) , var(38) ]
+                D[39,83] = (-1)*var(19); // [ var(83) , var(39) ]
+                D[42,83] = var(24); // [ var(83) , var(42) ]
+                D[44,83] = var(25); // [ var(83) , var(44) ]
+                D[47,83] = var(31); // [ var(83) , var(47) ]
+                D[53,83] = (-1)*var(40); // [ var(83) , var(53) ]
+                D[56,83] = (-1)*var(45); // [ var(83) , var(56) ]
+                D[58,83] = (-1)*var(49); // [ var(83) , var(58) ]
+                D[63,83] = var(59); // [ var(83) , var(63) ]
+                D[1,84] = (-1)*var(80); // [ var(84) , var(1) ]
+                D[5,84] = var(77); // [ var(84) , var(5) ]
+                D[8,84] = (-1)*var(74); // [ var(84) , var(8) ]
+                D[11,84] = var(71); // [ var(84) , var(11) ]
+                D[14,84] = (-1)*var(68); // [ var(84) , var(14) ]
+                D[17,84] = var(64); // [ var(84) , var(17) ]
+                D[21,84] = (-1)*var(127)+(-1)*var(129)+(-1)*var(130)+(-1)*var(131); // [ var(84) , var(21) ]
+                D[26,84] = var(2); // [ var(84) , var(26) ]
+                D[27,84] = (-1)*var(6); // [ var(84) , var(27) ]
+                D[32,84] = var(9); // [ var(84) , var(32) ]
+                D[34,84] = (-1)*var(13); // [ var(84) , var(34) ]
+                D[37,84] = var(15); // [ var(84) , var(37) ]
+                D[43,84] = (-1)*var(23); // [ var(84) , var(43) ]
+                D[46,84] = (-1)*var(29); // [ var(84) , var(46) ]
+                D[48,84] = (-1)*var(30); // [ var(84) , var(48) ]
+                D[50,84] = (-1)*var(35); // [ var(84) , var(50) ]
+                D[51,84] = (-1)*var(36); // [ var(84) , var(51) ]
+                D[54,84] = (-1)*var(41); // [ var(84) , var(54) ]
+                D[59,84] = var(49); // [ var(84) , var(59) ]
+                D[63,84] = (-1)*var(58); // [ var(84) , var(63) ]
+                D[2,85] = (-1)*var(80); // [ var(85) , var(2) ]
+                D[3,85] = (-1)*var(79); // [ var(85) , var(3) ]
+                D[5,85] = var(78); // [ var(85) , var(5) ]
+                D[15,85] = (-1)*var(68); // [ var(85) , var(15) ]
+                D[16,85] = var(66); // [ var(85) , var(16) ]
+                D[17,85] = var(65); // [ var(85) , var(17) ]
+                D[22,85] = (-1)*var(128)+(-1)*var(129)+(-1)*var(130)+(-1)*var(131); // [ var(85) , var(22) ]
+                D[26,85] = var(1); // [ var(85) , var(26) ]
+                D[28,85] = (-1)*var(4); // [ var(85) , var(28) ]
+                D[29,85] = (-1)*var(6); // [ var(85) , var(29) ]
+                D[36,85] = (-1)*var(13); // [ var(85) , var(36) ]
+                D[37,85] = var(14); // [ var(85) , var(37) ]
+                D[40,85] = var(18); // [ var(85) , var(40) ]
+                D[45,85] = var(25); // [ var(85) , var(45) ]
+                D[46,85] = (-1)*var(27); // [ var(85) , var(46) ]
+                D[51,85] = (-1)*var(34); // [ var(85) , var(51) ]
+                D[53,85] = (-1)*var(38); // [ var(85) , var(53) ]
+                D[56,85] = (-1)*var(44); // [ var(85) , var(56) ]
+                D[60,85] = var(52); // [ var(85) , var(60) ]
+                D[62,85] = var(57); // [ var(85) , var(62) ]
+                D[2,86] = (-1)*var(81); // [ var(86) , var(2) ]
+                D[6,86] = var(79); // [ var(86) , var(6) ]
+                D[9,86] = (-1)*var(75); // [ var(86) , var(9) ]
+                D[12,86] = var(72); // [ var(86) , var(12) ]
+                D[16,86] = (-1)*var(69); // [ var(86) , var(16) ]
+                D[18,86] = var(65); // [ var(86) , var(18) ]
+                D[23,86] = (-1)*var(128)+(-1)*var(130)+(-1)*var(131)+(-1)*var(132); // [ var(86) , var(23) ]
+                D[29,86] = var(3); // [ var(86) , var(29) ]
+                D[30,86] = (-1)*var(7); // [ var(86) , var(30) ]
+                D[33,86] = var(8); // [ var(86) , var(33) ]
+                D[35,86] = var(10); // [ var(86) , var(35) ]
+                D[38,86] = var(14); // [ var(86) , var(38) ]
+                D[40,86] = var(17); // [ var(86) , var(40) ]
+                D[43,86] = var(21); // [ var(86) , var(43) ]
+                D[49,86] = (-1)*var(31); // [ var(86) , var(49) ]
+                D[52,86] = (-1)*var(34); // [ var(86) , var(52) ]
+                D[53,86] = (-1)*var(37); // [ var(86) , var(53) ]
+                D[58,86] = var(47); // [ var(86) , var(58) ]
+                D[60,86] = var(51); // [ var(86) , var(60) ]
+                D[61,86] = var(54); // [ var(86) , var(61) ]
+                D[3,87] = (-1)*var(81); // [ var(87) , var(3) ]
+                D[6,87] = var(80); // [ var(87) , var(6) ]
+                D[10,87] = (-1)*var(75); // [ var(87) , var(10) ]
+                D[12,87] = var(73); // [ var(87) , var(12) ]
+                D[17,87] = (-1)*var(69); // [ var(87) , var(17) ]
+                D[18,87] = var(66); // [ var(87) , var(18) ]
+                D[24,87] = (-1)*var(129)+(-1)*var(130)+(-1)*var(131)+(-1)*var(132); // [ var(87) , var(24) ]
+                D[27,87] = var(1); // [ var(87) , var(27) ]
+                D[29,87] = var(2); // [ var(87) , var(29) ]
+                D[31,87] = (-1)*var(7); // [ var(87) , var(31) ]
+                D[35,87] = var(9); // [ var(87) , var(35) ]
+                D[40,87] = var(16); // [ var(87) , var(40) ]
+                D[42,87] = (-1)*var(20); // [ var(87) , var(42) ]
+                D[46,87] = (-1)*var(26); // [ var(87) , var(46) ]
+                D[49,87] = (-1)*var(30); // [ var(87) , var(49) ]
+                D[50,87] = (-1)*var(32); // [ var(87) , var(50) ]
+                D[55,87] = var(39); // [ var(87) , var(55) ]
+                D[57,87] = var(44); // [ var(87) , var(57) ]
+                D[59,87] = var(48); // [ var(87) , var(59) ]
+                D[62,87] = (-1)*var(56); // [ var(87) , var(62) ]
+                D[4,88] = (-1)*var(82); // [ var(88) , var(4) ]
+                D[7,88] = var(81); // [ var(88) , var(7) ]
+                D[11,88] = (-1)*var(76); // [ var(88) , var(11) ]
+                D[13,88] = var(74); // [ var(88) , var(13) ]
+                D[18,88] = (-1)*var(70); // [ var(88) , var(18) ]
+                D[19,88] = var(67); // [ var(88) , var(19) ]
+                D[25,88] = (-1)*var(130)+(-1)*var(131)+(-1)*var(132)+(-1)*var(133); // [ var(88) , var(25) ]
+                D[30,88] = var(2); // [ var(88) , var(30) ]
+                D[31,88] = var(3); // [ var(88) , var(31) ]
+                D[34,88] = var(8); // [ var(88) , var(34) ]
+                D[41,88] = (-1)*var(15); // [ var(88) , var(41) ]
+                D[44,88] = (-1)*var(20); // [ var(88) , var(44) ]
+                D[45,88] = (-1)*var(22); // [ var(88) , var(45) ]
+                D[48,88] = (-1)*var(26); // [ var(88) , var(48) ]
+                D[49,88] = (-1)*var(29); // [ var(88) , var(49) ]
+                D[52,88] = (-1)*var(33); // [ var(88) , var(52) ]
+                D[54,88] = var(37); // [ var(88) , var(54) ]
+                D[57,88] = var(42); // [ var(88) , var(57) ]
+                D[59,88] = var(46); // [ var(88) , var(59) ]
+                D[61,88] = (-1)*var(53); // [ var(88) , var(61) ]
+                D[1,89] = (-1)*var(85); // [ var(89) , var(1) ]
+                D[2,89] = (-1)*var(84); // [ var(89) , var(2) ]
+                D[5,89] = var(83); // [ var(89) , var(5) ]
+                D[8,89] = (-1)*var(79); // [ var(89) , var(8) ]
+                D[16,89] = var(71); // [ var(89) , var(16) ]
+                D[20,89] = (-1)*var(68); // [ var(89) , var(20) ]
+                D[21,89] = var(65); // [ var(89) , var(21) ]
+                D[22,89] = var(64); // [ var(89) , var(22) ]
+                D[26,89] = (-1)*var(127)+(-1)*var(128)+(-1)*var(129)+(-1)*var(130)+(-1)*var(131); // [ var(89) , var(26) ]
+                D[32,89] = (-1)*var(4); // [ var(89) , var(32) ]
+                D[33,89] = (-1)*var(6); // [ var(89) , var(33) ]
+                D[37,89] = (-1)*var(10); // [ var(89) , var(37) ]
+                D[39,89] = (-1)*var(13); // [ var(89) , var(39) ]
+                D[43,89] = var(18); // [ var(89) , var(43) ]
+                D[46,89] = var(24); // [ var(89) , var(46) ]
+                D[48,89] = var(25); // [ var(89) , var(48) ]
+                D[51,89] = var(31); // [ var(89) , var(51) ]
+                D[53,89] = var(35); // [ var(89) , var(53) ]
+                D[56,89] = var(41); // [ var(89) , var(56) ]
+                D[60,89] = (-1)*var(49); // [ var(89) , var(60) ]
+                D[63,89] = (-1)*var(57); // [ var(89) , var(63) ]
+                D[1,90] = (-1)*var(87); // [ var(90) , var(1) ]
+                D[6,90] = var(84); // [ var(90) , var(6) ]
+                D[8,90] = (-1)*var(81); // [ var(90) , var(8) ]
+                D[12,90] = var(77); // [ var(90) , var(12) ]
+                D[14,90] = (-1)*var(75); // [ var(90) , var(14) ]
+                D[18,90] = var(71); // [ var(90) , var(18) ]
+                D[21,90] = (-1)*var(69); // [ var(90) , var(21) ]
+                D[24,90] = var(64); // [ var(90) , var(24) ]
+                D[27,90] = (-1)*var(127)+(-1)*var(129)+(-1)*var(130)+(-1)*var(131)+(-1)*var(132); // [ var(90) , var(27) ]
+                D[33,90] = var(2); // [ var(90) , var(33) ]
+                D[34,90] = (-1)*var(7); // [ var(90) , var(34) ]
+                D[38,90] = var(9); // [ var(90) , var(38) ]
+                D[42,90] = var(15); // [ var(90) , var(42) ]
+                D[43,90] = var(16); // [ var(90) , var(43) ]
+                D[46,90] = var(22); // [ var(90) , var(46) ]
+                D[50,90] = var(28); // [ var(90) , var(50) ]
+                D[52,90] = (-1)*var(30); // [ var(90) , var(52) ]
+                D[55,90] = (-1)*var(36); // [ var(90) , var(55) ]
+                D[57,90] = (-1)*var(41); // [ var(90) , var(57) ]
+                D[59,90] = (-1)*var(45); // [ var(90) , var(59) ]
+                D[63,90] = var(56); // [ var(90) , var(63) ]
+                D[4,91] = var(85); // [ var(91) , var(4) ]
+                D[9,91] = (-1)*var(80); // [ var(91) , var(9) ]
+                D[10,91] = (-1)*var(79); // [ var(91) , var(10) ]
+                D[11,91] = (-1)*var(78); // [ var(91) , var(11) ]
+                D[15,91] = var(74); // [ var(91) , var(15) ]
+                D[16,91] = var(73); // [ var(91) , var(16) ]
+                D[17,91] = var(72); // [ var(91) , var(17) ]
+                D[22,91] = (-1)*var(67); // [ var(91) , var(22) ]
+                D[28,91] = (-1)*var(128)+(-1)*var(129)+(-2)*var(130)+(-1)*var(131); // [ var(91) , var(28) ]
+                D[32,91] = var(1); // [ var(91) , var(32) ]
+                D[35,91] = (-1)*var(6); // [ var(91) , var(35) ]
+                D[37,91] = (-1)*var(8); // [ var(91) , var(37) ]
+                D[40,91] = var(12); // [ var(91) , var(40) ]
+                D[41,91] = (-1)*var(13); // [ var(91) , var(41) ]
+                D[45,91] = var(19); // [ var(91) , var(45) ]
+                D[50,91] = (-1)*var(27); // [ var(91) , var(50) ]
+                D[53,91] = var(33); // [ var(91) , var(53) ]
+                D[54,91] = (-1)*var(34); // [ var(91) , var(54) ]
+                D[56,91] = var(39); // [ var(91) , var(56) ]
+                D[61,91] = var(52); // [ var(91) , var(61) ]
+                D[62,91] = (-1)*var(55); // [ var(91) , var(62) ]
+                D[2,92] = (-1)*var(87); // [ var(92) , var(2) ]
+                D[3,92] = (-1)*var(86); // [ var(92) , var(3) ]
+                D[6,92] = var(85); // [ var(92) , var(6) ]
+                D[12,92] = var(78); // [ var(92) , var(12) ]
+                D[15,92] = (-1)*var(75); // [ var(92) , var(15) ]
+                D[22,92] = (-1)*var(69); // [ var(92) , var(22) ]
+                D[23,92] = var(66); // [ var(92) , var(23) ]
+                D[24,92] = var(65); // [ var(92) , var(24) ]
+                D[29,92] = (-1)*var(128)+(-1)*var(129)+(-1)*var(130)+(-1)*var(131)+(-1)*var(132); // [ var(92) , var(29) ]
+                D[33,92] = var(1); // [ var(92) , var(33) ]
+                D[35,92] = (-1)*var(4); // [ var(92) , var(35) ]
+                D[36,92] = (-1)*var(7); // [ var(92) , var(36) ]
+                D[40,92] = (-1)*var(11); // [ var(92) , var(40) ]
+                D[42,92] = var(14); // [ var(92) , var(42) ]
+                D[46,92] = var(21); // [ var(92) , var(46) ]
+                D[49,92] = var(25); // [ var(92) , var(49) ]
+                D[53,92] = var(32); // [ var(92) , var(53) ]
+                D[55,92] = (-1)*var(34); // [ var(92) , var(55) ]
+                D[58,92] = (-1)*var(44); // [ var(92) , var(58) ]
+                D[60,92] = (-1)*var(48); // [ var(92) , var(60) ]
+                D[62,92] = (-1)*var(54); // [ var(92) , var(62) ]
+                D[2,93] = (-1)*var(88); // [ var(93) , var(2) ]
+                D[7,93] = var(86); // [ var(93) , var(7) ]
+                D[9,93] = (-1)*var(82); // [ var(93) , var(9) ]
+                D[13,93] = var(79); // [ var(93) , var(13) ]
+                D[16,93] = (-1)*var(76); // [ var(93) , var(16) ]
+                D[19,93] = var(72); // [ var(93) , var(19) ]
+                D[23,93] = (-1)*var(70); // [ var(93) , var(23) ]
+                D[25,93] = var(65); // [ var(93) , var(25) ]
+                D[30,93] = (-1)*var(128)+(-1)*var(130)+(-1)*var(131)+(-1)*var(132)+(-1)*var(133); // [ var(93) , var(30) ]
+                D[36,93] = var(3); // [ var(93) , var(36) ]
+                D[39,93] = var(8); // [ var(93) , var(39) ]
+                D[41,93] = var(10); // [ var(93) , var(41) ]
+                D[44,93] = var(14); // [ var(93) , var(44) ]
+                D[45,93] = var(17); // [ var(93) , var(45) ]
+                D[48,93] = var(21); // [ var(93) , var(48) ]
+                D[49,93] = var(24); // [ var(93) , var(49) ]
+                D[52,93] = var(27); // [ var(93) , var(52) ]
+                D[56,93] = (-1)*var(37); // [ var(93) , var(56) ]
+                D[58,93] = (-1)*var(42); // [ var(93) , var(58) ]
+                D[60,93] = (-1)*var(46); // [ var(93) , var(60) ]
+                D[61,93] = (-1)*var(50); // [ var(93) , var(61) ]
+                D[3,94] = (-1)*var(88); // [ var(94) , var(3) ]
+                D[7,94] = var(87); // [ var(94) , var(7) ]
+                D[10,94] = (-1)*var(82); // [ var(94) , var(10) ]
+                D[13,94] = var(80); // [ var(94) , var(13) ]
+                D[17,94] = (-1)*var(76); // [ var(94) , var(17) ]
+                D[19,94] = var(73); // [ var(94) , var(19) ]
+                D[24,94] = (-1)*var(70); // [ var(94) , var(24) ]
+                D[25,94] = var(66); // [ var(94) , var(25) ]
+                D[31,94] = (-1)*var(129)+(-1)*var(130)+(-1)*var(131)+(-1)*var(132)+(-1)*var(133); // [ var(94) , var(31) ]
+                D[34,94] = var(1); // [ var(94) , var(34) ]
+                D[36,94] = var(2); // [ var(94) , var(36) ]
+                D[41,94] = var(9); // [ var(94) , var(41) ]
+                D[45,94] = var(16); // [ var(94) , var(45) ]
+                D[47,94] = (-1)*var(20); // [ var(94) , var(47) ]
+                D[49,94] = var(23); // [ var(94) , var(49) ]
+                D[51,94] = (-1)*var(26); // [ var(94) , var(51) ]
+                D[54,94] = (-1)*var(32); // [ var(94) , var(54) ]
+                D[55,94] = (-1)*var(33); // [ var(94) , var(55) ]
+                D[57,94] = (-1)*var(38); // [ var(94) , var(57) ]
+                D[59,94] = (-1)*var(43); // [ var(94) , var(59) ]
+                D[62,94] = var(53); // [ var(94) , var(62) ]
+                D[1,95] = (-1)*var(91); // [ var(95) , var(1) ]
+                D[4,95] = var(89); // [ var(95) , var(4) ]
+                D[9,95] = (-1)*var(84); // [ var(95) , var(9) ]
+                D[11,95] = (-1)*var(83); // [ var(95) , var(11) ]
+                D[14,95] = (-1)*var(79); // [ var(95) , var(14) ]
+                D[16,95] = var(77); // [ var(95) , var(16) ]
+                D[20,95] = var(74); // [ var(95) , var(20) ]
+                D[21,95] = var(72); // [ var(95) , var(21) ]
+                D[26,95] = (-1)*var(67); // [ var(95) , var(26) ]
+                D[28,95] = var(64); // [ var(95) , var(28) ]
+                D[32,95] = (-1)*var(127)+(-1)*var(128)+(-1)*var(129)+(-2)*var(130)+(-1)*var(131); // [ var(95) , var(32) ]
+                D[37,95] = var(3); // [ var(95) , var(37) ]
+                D[38,95] = (-1)*var(6); // [ var(95) , var(38) ]
+                D[43,95] = var(12); // [ var(95) , var(43) ]
+                D[44,95] = (-1)*var(13); // [ var(95) , var(44) ]
+                D[48,95] = var(19); // [ var(95) , var(48) ]
+                D[50,95] = var(24); // [ var(95) , var(50) ]
+                D[53,95] = (-1)*var(29); // [ var(95) , var(53) ]
+                D[54,95] = var(31); // [ var(95) , var(54) ]
+                D[56,95] = (-1)*var(36); // [ var(95) , var(56) ]
+                D[61,95] = (-1)*var(49); // [ var(95) , var(61) ]
+                D[63,95] = var(55); // [ var(95) , var(63) ]
+                D[1,96] = (-1)*var(92); // [ var(96) , var(1) ]
+                D[2,96] = (-1)*var(90); // [ var(96) , var(2) ]
+                D[6,96] = var(89); // [ var(96) , var(6) ]
+                D[8,96] = (-1)*var(86); // [ var(96) , var(8) ]
+                D[12,96] = var(83); // [ var(96) , var(12) ]
+                D[20,96] = (-1)*var(75); // [ var(96) , var(20) ]
+                D[23,96] = var(71); // [ var(96) , var(23) ]
+                D[26,96] = (-1)*var(69); // [ var(96) , var(26) ]
+                D[27,96] = var(65); // [ var(96) , var(27) ]
+                D[29,96] = var(64); // [ var(96) , var(29) ]
+                D[33,96] = (-1)*var(127)+(-1)*var(128)+(-1)*var(129)+(-1)*var(130)+(-1)*var(131)+(-1)*var(132); // [ var(96) , var(33) ]
+                D[38,96] = (-1)*var(4); // [ var(96) , var(38) ]
+                D[39,96] = (-1)*var(7); // [ var(96) , var(39) ]
+                D[42,96] = (-1)*var(10); // [ var(96) , var(42) ]
+                D[43,96] = (-1)*var(11); // [ var(96) , var(43) ]
+                D[46,96] = (-1)*var(17); // [ var(96) , var(46) ]
+                D[52,96] = var(25); // [ var(96) , var(52) ]
+                D[53,96] = (-1)*var(28); // [ var(96) , var(53) ]
+                D[55,96] = var(31); // [ var(96) , var(55) ]
+                D[58,96] = var(41); // [ var(96) , var(58) ]
+                D[60,96] = var(45); // [ var(96) , var(60) ]
+                D[63,96] = var(54); // [ var(96) , var(63) ]
+                D[1,97] = (-1)*var(94); // [ var(97) , var(1) ]
+                D[7,97] = var(90); // [ var(97) , var(7) ]
+                D[8,97] = (-1)*var(88); // [ var(97) , var(8) ]
+                D[13,97] = var(84); // [ var(97) , var(13) ]
+                D[14,97] = (-1)*var(82); // [ var(97) , var(14) ]
+                D[19,97] = var(77); // [ var(97) , var(19) ]
+                D[21,97] = (-1)*var(76); // [ var(97) , var(21) ]
+                D[25,97] = var(71); // [ var(97) , var(25) ]
+                D[27,97] = (-1)*var(70); // [ var(97) , var(27) ]
+                D[31,97] = var(64); // [ var(97) , var(31) ]
+                D[34,97] = (-1)*var(127)+(-1)*var(129)+(-1)*var(130)+(-1)*var(131)+(-1)*var(132)+(-1)*var(133); // [ var(97) , var(34) ]
+                D[39,97] = var(2); // [ var(97) , var(39) ]
+                D[44,97] = var(9); // [ var(97) , var(44) ]
+                D[47,97] = var(15); // [ var(97) , var(47) ]
+                D[48,97] = var(16); // [ var(97) , var(48) ]
+                D[51,97] = var(22); // [ var(97) , var(51) ]
+                D[52,97] = var(23); // [ var(97) , var(52) ]
+                D[54,97] = var(28); // [ var(97) , var(54) ]
+                D[55,97] = var(29); // [ var(97) , var(55) ]
+                D[57,97] = var(35); // [ var(97) , var(57) ]
+                D[59,97] = var(40); // [ var(97) , var(59) ]
+                D[63,97] = (-1)*var(53); // [ var(97) , var(63) ]
+                D[4,98] = var(92); // [ var(98) , var(4) ]
+                D[6,98] = var(91); // [ var(98) , var(6) ]
+                D[9,98] = (-1)*var(87); // [ var(98) , var(9) ]
+                D[10,98] = (-1)*var(86); // [ var(98) , var(10) ]
+                D[15,98] = var(81); // [ var(98) , var(15) ]
+                D[18,98] = (-1)*var(78); // [ var(98) , var(18) ]
+                D[23,98] = var(73); // [ var(98) , var(23) ]
+                D[24,98] = var(72); // [ var(98) , var(24) ]
+                D[28,98] = (-1)*var(69); // [ var(98) , var(28) ]
+                D[29,98] = (-1)*var(67); // [ var(98) , var(29) ]
+                D[35,98] = (-1)*var(128)+(-1)*var(129)+(-2)*var(130)+(-1)*var(131)+(-1)*var(132); // [ var(98) , var(35) ]
+                D[38,98] = var(1); // [ var(98) , var(38) ]
+                D[40,98] = (-1)*var(5); // [ var(98) , var(40) ]
+                D[41,98] = (-1)*var(7); // [ var(98) , var(41) ]
+                D[42,98] = (-1)*var(8); // [ var(98) , var(42) ]
+                D[49,98] = var(19); // [ var(98) , var(49) ]
+                D[50,98] = var(21); // [ var(98) , var(50) ]
+                D[53,98] = (-1)*var(26); // [ var(98) , var(53) ]
+                D[57,98] = (-1)*var(34); // [ var(98) , var(57) ]
+                D[58,98] = var(39); // [ var(98) , var(58) ]
+                D[61,98] = (-1)*var(48); // [ var(98) , var(61) ]
+                D[62,98] = var(51); // [ var(98) , var(62) ]
+                D[2,99] = (-1)*var(94); // [ var(99) , var(2) ]
+                D[3,99] = (-1)*var(93); // [ var(99) , var(3) ]
+                D[7,99] = var(92); // [ var(99) , var(7) ]
+                D[13,99] = var(85); // [ var(99) , var(13) ]
+                D[15,99] = (-1)*var(82); // [ var(99) , var(15) ]
+                D[19,99] = var(78); // [ var(99) , var(19) ]
+                D[22,99] = (-1)*var(76); // [ var(99) , var(22) ]
+                D[29,99] = (-1)*var(70); // [ var(99) , var(29) ]
+                D[30,99] = var(66); // [ var(99) , var(30) ]
+                D[31,99] = var(65); // [ var(99) , var(31) ]
+                D[36,99] = (-1)*var(128)+(-1)*var(129)+(-1)*var(130)+(-1)*var(131)+(-1)*var(132)+(-1)*var(133); // [ var(99) , var(36) ]
+                D[39,99] = var(1); // [ var(99) , var(39) ]
+                D[41,99] = (-1)*var(4); // [ var(99) , var(41) ]
+                D[45,99] = (-1)*var(11); // [ var(99) , var(45) ]
+                D[47,99] = var(14); // [ var(99) , var(47) ]
+                D[49,99] = (-1)*var(18); // [ var(99) , var(49) ]
+                D[51,99] = var(21); // [ var(99) , var(51) ]
+                D[55,99] = var(27); // [ var(99) , var(55) ]
+                D[56,99] = var(32); // [ var(99) , var(56) ]
+                D[58,99] = var(38); // [ var(99) , var(58) ]
+                D[60,99] = var(43); // [ var(99) , var(60) ]
+                D[62,99] = var(50); // [ var(99) , var(62) ]
+                D[3,100] = (-1)*var(95); // [ var(100) , var(3) ]
+                D[8,100] = var(91); // [ var(100) , var(8) ]
+                D[10,100] = var(89); // [ var(100) , var(10) ]
+                D[14,100] = (-1)*var(85); // [ var(100) , var(14) ]
+                D[15,100] = (-1)*var(84); // [ var(100) , var(15) ]
+                D[17,100] = (-1)*var(83); // [ var(100) , var(17) ]
+                D[20,100] = var(80); // [ var(100) , var(20) ]
+                D[21,100] = var(78); // [ var(100) , var(21) ]
+                D[22,100] = var(77); // [ var(100) , var(22) ]
+                D[26,100] = (-1)*var(73); // [ var(100) , var(26) ]
+                D[28,100] = (-1)*var(71); // [ var(100) , var(28) ]
+                D[32,100] = var(66); // [ var(100) , var(32) ]
+                D[37,100] = (-1)*var(127)+(-1)*var(128)+(-2)*var(129)+(-2)*var(130)+(-1)*var(131); // [ var(100) , var(37) ]
+                D[42,100] = (-1)*var(6); // [ var(100) , var(42) ]
+                D[46,100] = var(12); // [ var(100) , var(46) ]
+                D[47,100] = (-1)*var(13); // [ var(100) , var(47) ]
+                D[50,100] = (-1)*var(18); // [ var(100) , var(50) ]
+                D[51,100] = var(19); // [ var(100) , var(51) ]
+                D[53,100] = var(23); // [ var(100) , var(53) ]
+                D[54,100] = (-1)*var(25); // [ var(100) , var(54) ]
+                D[56,100] = var(30); // [ var(100) , var(56) ]
+                D[62,100] = var(49); // [ var(100) , var(62) ]
+                D[63,100] = (-1)*var(52); // [ var(100) , var(63) ]
+                D[1,101] = (-1)*var(98); // [ var(101) , var(1) ]
+                D[4,101] = var(96); // [ var(101) , var(4) ]
+                D[6,101] = var(95); // [ var(101) , var(6) ]
+                D[9,101] = (-1)*var(90); // [ var(101) , var(9) ]
+                D[14,101] = (-1)*var(86); // [ var(101) , var(14) ]
+                D[18,101] = (-1)*var(83); // [ var(101) , var(18) ]
+                D[20,101] = var(81); // [ var(101) , var(20) ]
+                D[23,101] = var(77); // [ var(101) , var(23) ]
+                D[27,101] = var(72); // [ var(101) , var(27) ]
+                D[32,101] = (-1)*var(69); // [ var(101) , var(32) ]
+                D[33,101] = (-1)*var(67); // [ var(101) , var(33) ]
+                D[35,101] = var(64); // [ var(101) , var(35) ]
+                D[38,101] = (-1)*var(127)+(-1)*var(128)+(-1)*var(129)+(-2)*var(130)+(-1)*var(131)+(-1)*var(132); // [ var(101) , var(38) ]
+                D[42,101] = var(3); // [ var(101) , var(42) ]
+                D[43,101] = (-1)*var(5); // [ var(101) , var(43) ]
+                D[44,101] = (-1)*var(7); // [ var(101) , var(44) ]
+                D[50,101] = (-1)*var(17); // [ var(101) , var(50) ]
+                D[52,101] = var(19); // [ var(101) , var(52) ]
+                D[53,101] = var(22); // [ var(101) , var(53) ]
+                D[57,101] = var(31); // [ var(101) , var(57) ]
+                D[58,101] = (-1)*var(36); // [ var(101) , var(58) ]
+                D[61,101] = var(45); // [ var(101) , var(61) ]
+                D[63,101] = (-1)*var(51); // [ var(101) , var(63) ]
+                D[1,102] = (-1)*var(99); // [ var(102) , var(1) ]
+                D[2,102] = (-1)*var(97); // [ var(102) , var(2) ]
+                D[7,102] = var(96); // [ var(102) , var(7) ]
+                D[8,102] = (-1)*var(93); // [ var(102) , var(8) ]
+                D[13,102] = var(89); // [ var(102) , var(13) ]
+                D[19,102] = var(83); // [ var(102) , var(19) ]
+                D[20,102] = (-1)*var(82); // [ var(102) , var(20) ]
+                D[26,102] = (-1)*var(76); // [ var(102) , var(26) ]
+                D[30,102] = var(71); // [ var(102) , var(30) ]
+                D[33,102] = (-1)*var(70); // [ var(102) , var(33) ]
+                D[34,102] = var(65); // [ var(102) , var(34) ]
+                D[36,102] = var(64); // [ var(102) , var(36) ]
+                D[39,102] = (-1)*var(127)+(-1)*var(128)+(-1)*var(129)+(-1)*var(130)+(-1)*var(131)+(-1)*var(132)+(-1)*var(133); // [ var(102) , var(39) ]
+                D[44,102] = (-1)*var(4); // [ var(102) , var(44) ]
+                D[47,102] = (-1)*var(10); // [ var(102) , var(47) ]
+                D[48,102] = (-1)*var(11); // [ var(102) , var(48) ]
+                D[51,102] = (-1)*var(17); // [ var(102) , var(51) ]
+                D[52,102] = (-1)*var(18); // [ var(102) , var(52) ]
+                D[55,102] = (-1)*var(24); // [ var(102) , var(55) ]
+                D[56,102] = (-1)*var(28); // [ var(102) , var(56) ]
+                D[58,102] = (-1)*var(35); // [ var(102) , var(58) ]
+                D[60,102] = (-1)*var(40); // [ var(102) , var(60) ]
+                D[63,102] = (-1)*var(50); // [ var(102) , var(63) ]
+                D[5,103] = var(98); // [ var(103) , var(5) ]
+                D[11,103] = var(92); // [ var(103) , var(11) ]
+                D[12,103] = (-1)*var(91); // [ var(103) , var(12) ]
+                D[16,103] = (-1)*var(87); // [ var(103) , var(16) ]
+                D[17,103] = (-1)*var(86); // [ var(103) , var(17) ]
+                D[18,103] = (-1)*var(85); // [ var(103) , var(18) ]
+                D[22,103] = var(81); // [ var(103) , var(22) ]
+                D[23,103] = var(80); // [ var(103) , var(23) ]
+                D[24,103] = var(79); // [ var(103) , var(24) ]
+                D[28,103] = var(75); // [ var(103) , var(28) ]
+                D[29,103] = (-1)*var(74); // [ var(103) , var(29) ]
+                D[35,103] = (-1)*var(68); // [ var(103) , var(35) ]
+                D[40,103] = (-1)*var(128)+(-1)*var(129)+(-2)*var(130)+(-2)*var(131)+(-1)*var(132); // [ var(103) , var(40) ]
+                D[43,103] = var(1); // [ var(103) , var(43) ]
+                D[45,103] = (-1)*var(7); // [ var(103) , var(45) ]
+                D[46,103] = (-1)*var(8); // [ var(103) , var(46) ]
+                D[49,103] = var(13); // [ var(103) , var(49) ]
+                D[50,103] = (-1)*var(14); // [ var(103) , var(50) ]
+                D[53,103] = var(20); // [ var(103) , var(53) ]
+                D[59,103] = (-1)*var(34); // [ var(103) , var(59) ]
+                D[60,103] = var(39); // [ var(103) , var(60) ]
+                D[61,103] = var(44); // [ var(103) , var(61) ]
+                D[62,103] = (-1)*var(47); // [ var(103) , var(62) ]
+                D[4,104] = var(99); // [ var(104) , var(4) ]
+                D[7,104] = var(98); // [ var(104) , var(7) ]
+                D[9,104] = (-1)*var(94); // [ var(104) , var(9) ]
+                D[10,104] = (-1)*var(93); // [ var(104) , var(10) ]
+                D[13,104] = var(91); // [ var(104) , var(13) ]
+                D[15,104] = var(88); // [ var(104) , var(15) ]
+                D[25,104] = (-1)*var(78); // [ var(104) , var(25) ]
+                D[28,104] = (-1)*var(76); // [ var(104) , var(28) ]
+                D[30,104] = var(73); // [ var(104) , var(30) ]
+                D[31,104] = var(72); // [ var(104) , var(31) ]
+                D[35,104] = (-1)*var(70); // [ var(104) , var(35) ]
+                D[36,104] = (-1)*var(67); // [ var(104) , var(36) ]
+                D[41,104] = (-1)*var(128)+(-1)*var(129)+(-2)*var(130)+(-1)*var(131)+(-1)*var(132)+(-1)*var(133); // [ var(104) , var(41) ]
+                D[44,104] = var(1); // [ var(104) , var(44) ]
+                D[45,104] = (-1)*var(5); // [ var(104) , var(45) ]
+                D[47,104] = (-1)*var(8); // [ var(104) , var(47) ]
+                D[49,104] = (-1)*var(12); // [ var(104) , var(49) ]
+                D[54,104] = var(21); // [ var(104) , var(54) ]
+                D[56,104] = (-1)*var(26); // [ var(104) , var(56) ]
+                D[57,104] = var(27); // [ var(104) , var(57) ]
+                D[58,104] = (-1)*var(33); // [ var(104) , var(58) ]
+                D[61,104] = var(43); // [ var(104) , var(61) ]
+                D[62,104] = (-1)*var(46); // [ var(104) , var(62) ]
+                D[3,105] = (-1)*var(101); // [ var(105) , var(3) ]
+                D[6,105] = var(100); // [ var(105) , var(6) ]
+                D[8,105] = var(98); // [ var(105) , var(8) ]
+                D[10,105] = var(96); // [ var(105) , var(10) ]
+                D[14,105] = (-1)*var(92); // [ var(105) , var(14) ]
+                D[15,105] = (-1)*var(90); // [ var(105) , var(15) ]
+                D[20,105] = var(87); // [ var(105) , var(20) ]
+                D[24,105] = (-1)*var(83); // [ var(105) , var(24) ]
+                D[27,105] = var(78); // [ var(105) , var(27) ]
+                D[29,105] = var(77); // [ var(105) , var(29) ]
+                D[33,105] = (-1)*var(73); // [ var(105) , var(33) ]
+                D[35,105] = (-1)*var(71); // [ var(105) , var(35) ]
+                D[37,105] = (-1)*var(69); // [ var(105) , var(37) ]
+                D[38,105] = var(66); // [ var(105) , var(38) ]
+                D[42,105] = (-1)*var(127)+(-1)*var(128)+(-2)*var(129)+(-2)*var(130)+(-1)*var(131)+(-1)*var(132); // [ var(105) , var(42) ]
+                D[46,105] = (-1)*var(5); // [ var(105) , var(46) ]
+                D[47,105] = (-1)*var(7); // [ var(105) , var(47) ]
+                D[50,105] = var(11); // [ var(105) , var(50) ]
+                D[53,105] = (-1)*var(16); // [ var(105) , var(53) ]
+                D[55,105] = var(19); // [ var(105) , var(55) ]
+                D[57,105] = (-1)*var(25); // [ var(105) , var(57) ]
+                D[58,105] = var(30); // [ var(105) , var(58) ]
+                D[62,105] = (-1)*var(45); // [ var(105) , var(62) ]
+                D[63,105] = var(48); // [ var(105) , var(63) ]
+                D[1,106] = (-1)*var(103); // [ var(106) , var(1) ]
+                D[5,106] = var(101); // [ var(106) , var(5) ]
+                D[11,106] = var(96); // [ var(106) , var(11) ]
+                D[12,106] = (-1)*var(95); // [ var(106) , var(12) ]
+                D[16,106] = (-1)*var(90); // [ var(106) , var(16) ]
+                D[18,106] = (-1)*var(89); // [ var(106) , var(18) ]
+                D[21,106] = (-1)*var(86); // [ var(106) , var(21) ]
+                D[23,106] = var(84); // [ var(106) , var(23) ]
+                D[26,106] = var(81); // [ var(106) , var(26) ]
+                D[27,106] = var(79); // [ var(106) , var(27) ]
+                D[32,106] = var(75); // [ var(106) , var(32) ]
+                D[33,106] = (-1)*var(74); // [ var(106) , var(33) ]
+                D[38,106] = (-1)*var(68); // [ var(106) , var(38) ]
+                D[40,106] = var(64); // [ var(106) , var(40) ]
+                D[43,106] = (-1)*var(127)+(-1)*var(128)+(-1)*var(129)+(-2)*var(130)+(-2)*var(131)+(-1)*var(132); // [ var(106) , var(43) ]
+                D[46,106] = var(3); // [ var(106) , var(46) ]
+                D[48,106] = (-1)*var(7); // [ var(106) , var(48) ]
+                D[50,106] = var(10); // [ var(106) , var(50) ]
+                D[52,106] = var(13); // [ var(106) , var(52) ]
+                D[53,106] = (-1)*var(15); // [ var(106) , var(53) ]
+                D[59,106] = var(31); // [ var(106) , var(59) ]
+                D[60,106] = (-1)*var(36); // [ var(106) , var(60) ]
+                D[61,106] = (-1)*var(41); // [ var(106) , var(61) ]
+                D[63,106] = var(47); // [ var(106) , var(63) ]
+                D[1,107] = (-1)*var(104); // [ var(107) , var(1) ]
+                D[4,107] = var(102); // [ var(107) , var(4) ]
+                D[7,107] = var(101); // [ var(107) , var(7) ]
+                D[9,107] = (-1)*var(97); // [ var(107) , var(9) ]
+                D[13,107] = var(95); // [ var(107) , var(13) ]
+                D[14,107] = (-1)*var(93); // [ var(107) , var(14) ]
+                D[20,107] = var(88); // [ var(107) , var(20) ]
+                D[25,107] = (-1)*var(83); // [ var(107) , var(25) ]
+                D[30,107] = var(77); // [ var(107) , var(30) ]
+                D[32,107] = (-1)*var(76); // [ var(107) , var(32) ]
+                D[34,107] = var(72); // [ var(107) , var(34) ]
+                D[38,107] = (-1)*var(70); // [ var(107) , var(38) ]
+                D[39,107] = (-1)*var(67); // [ var(107) , var(39) ]
+                D[41,107] = var(64); // [ var(107) , var(41) ]
+                D[44,107] = (-1)*var(127)+(-1)*var(128)+(-1)*var(129)+(-2)*var(130)+(-1)*var(131)+(-1)*var(132)+(-1)*var(133); // [ var(107) , var(44) ]
+                D[47,107] = var(3); // [ var(107) , var(47) ]
+                D[48,107] = (-1)*var(5); // [ var(107) , var(48) ]
+                D[52,107] = (-1)*var(12); // [ var(107) , var(52) ]
+                D[54,107] = (-1)*var(17); // [ var(107) , var(54) ]
+                D[56,107] = var(22); // [ var(107) , var(56) ]
+                D[57,107] = (-1)*var(24); // [ var(107) , var(57) ]
+                D[58,107] = var(29); // [ var(107) , var(58) ]
+                D[61,107] = (-1)*var(40); // [ var(107) , var(61) ]
+                D[63,107] = var(46); // [ var(107) , var(63) ]
+                D[5,108] = var(104); // [ var(108) , var(5) ]
+                D[7,108] = var(103); // [ var(108) , var(7) ]
+                D[11,108] = var(99); // [ var(108) , var(11) ]
+                D[16,108] = (-1)*var(94); // [ var(108) , var(16) ]
+                D[17,108] = (-1)*var(93); // [ var(108) , var(17) ]
+                D[19,108] = (-1)*var(91); // [ var(108) , var(19) ]
+                D[22,108] = var(88); // [ var(108) , var(22) ]
+                D[25,108] = (-1)*var(85); // [ var(108) , var(25) ]
+                D[28,108] = var(82); // [ var(108) , var(28) ]
+                D[30,108] = var(80); // [ var(108) , var(30) ]
+                D[31,108] = var(79); // [ var(108) , var(31) ]
+                D[36,108] = (-1)*var(74); // [ var(108) , var(36) ]
+                D[40,108] = (-1)*var(70); // [ var(108) , var(40) ]
+                D[41,108] = (-1)*var(68); // [ var(108) , var(41) ]
+                D[45,108] = (-1)*var(128)+(-1)*var(129)+(-2)*var(130)+(-2)*var(131)+(-1)*var(132)+(-1)*var(133); // [ var(108) , var(45) ]
+                D[48,108] = var(1); // [ var(108) , var(48) ]
+                D[49,108] = (-1)*var(6); // [ var(108) , var(49) ]
+                D[51,108] = (-1)*var(8); // [ var(108) , var(51) ]
+                D[54,108] = (-1)*var(14); // [ var(108) , var(54) ]
+                D[56,108] = var(20); // [ var(108) , var(56) ]
+                D[59,108] = var(27); // [ var(108) , var(59) ]
+                D[60,108] = (-1)*var(33); // [ var(108) , var(60) ]
+                D[61,108] = (-1)*var(38); // [ var(108) , var(61) ]
+                D[62,108] = var(42); // [ var(108) , var(62) ]
+                D[3,109] = (-1)*var(106); // [ var(109) , var(3) ]
+                D[5,109] = var(105); // [ var(109) , var(5) ]
+                D[8,109] = var(103); // [ var(109) , var(8) ]
+                D[12,109] = (-1)*var(100); // [ var(109) , var(12) ]
+                D[17,109] = var(96); // [ var(109) , var(17) ]
+                D[21,109] = (-1)*var(92); // [ var(109) , var(21) ]
+                D[22,109] = (-1)*var(90); // [ var(109) , var(22) ]
+                D[24,109] = (-1)*var(89); // [ var(109) , var(24) ]
+                D[26,109] = var(87); // [ var(109) , var(26) ]
+                D[27,109] = var(85); // [ var(109) , var(27) ]
+                D[29,109] = var(84); // [ var(109) , var(29) ]
+                D[33,109] = (-1)*var(80); // [ var(109) , var(33) ]
+                D[37,109] = var(75); // [ var(109) , var(37) ]
+                D[40,109] = (-1)*var(71); // [ var(109) , var(40) ]
+                D[42,109] = (-1)*var(68); // [ var(109) , var(42) ]
+                D[43,109] = var(66); // [ var(109) , var(43) ]
+                D[46,109] = (-1)*var(127)+(-1)*var(128)+(-2)*var(129)+(-2)*var(130)+(-2)*var(131)+(-1)*var(132); // [ var(109) , var(46) ]
+                D[50,109] = (-1)*var(4); // [ var(109) , var(50) ]
+                D[51,109] = (-1)*var(7); // [ var(109) , var(51) ]
+                D[53,109] = var(9); // [ var(109) , var(53) ]
+                D[55,109] = var(13); // [ var(109) , var(55) ]
+                D[59,109] = (-1)*var(25); // [ var(109) , var(59) ]
+                D[60,109] = var(30); // [ var(109) , var(60) ]
+                D[62,109] = var(41); // [ var(109) , var(62) ]
+                D[63,109] = (-1)*var(44); // [ var(109) , var(63) ]
+                D[3,110] = (-1)*var(107); // [ var(110) , var(3) ]
+                D[7,110] = var(105); // [ var(110) , var(7) ]
+                D[8,110] = var(104); // [ var(110) , var(8) ]
+                D[10,110] = var(102); // [ var(110) , var(10) ]
+                D[13,110] = var(100); // [ var(110) , var(13) ]
+                D[14,110] = (-1)*var(99); // [ var(110) , var(14) ]
+                D[15,110] = (-1)*var(97); // [ var(110) , var(15) ]
+                D[20,110] = var(94); // [ var(110) , var(20) ]
+                D[31,110] = (-1)*var(83); // [ var(110) , var(31) ]
+                D[34,110] = var(78); // [ var(110) , var(34) ]
+                D[36,110] = var(77); // [ var(110) , var(36) ]
+                D[37,110] = (-1)*var(76); // [ var(110) , var(37) ]
+                D[39,110] = (-1)*var(73); // [ var(110) , var(39) ]
+                D[41,110] = (-1)*var(71); // [ var(110) , var(41) ]
+                D[42,110] = (-1)*var(70); // [ var(110) , var(42) ]
+                D[44,110] = var(66); // [ var(110) , var(44) ]
+                D[47,110] = (-1)*var(127)+(-1)*var(128)+(-2)*var(129)+(-2)*var(130)+(-1)*var(131)+(-1)*var(132)+(-1)*var(133); // [ var(110) , var(47) ]
+                D[51,110] = (-1)*var(5); // [ var(110) , var(51) ]
+                D[54,110] = var(11); // [ var(110) , var(54) ]
+                D[55,110] = (-1)*var(12); // [ var(110) , var(55) ]
+                D[56,110] = (-1)*var(16); // [ var(110) , var(56) ]
+                D[57,110] = var(18); // [ var(110) , var(57) ]
+                D[58,110] = (-1)*var(23); // [ var(110) , var(58) ]
+                D[62,110] = var(40); // [ var(110) , var(62) ]
+                D[63,110] = (-1)*var(43); // [ var(110) , var(63) ]
+                D[1,111] = (-1)*var(108); // [ var(111) , var(1) ]
+                D[5,111] = var(107); // [ var(111) , var(5) ]
+                D[7,111] = var(106); // [ var(111) , var(7) ]
+                D[11,111] = var(102); // [ var(111) , var(11) ]
+                D[16,111] = (-1)*var(97); // [ var(111) , var(16) ]
+                D[19,111] = (-1)*var(95); // [ var(111) , var(19) ]
+                D[21,111] = (-1)*var(93); // [ var(111) , var(21) ]
+                D[25,111] = (-1)*var(89); // [ var(111) , var(25) ]
+                D[26,111] = var(88); // [ var(111) , var(26) ]
+                D[30,111] = var(84); // [ var(111) , var(30) ]
+                D[32,111] = var(82); // [ var(111) , var(32) ]
+                D[34,111] = var(79); // [ var(111) , var(34) ]
+                D[39,111] = (-1)*var(74); // [ var(111) , var(39) ]
+                D[43,111] = (-1)*var(70); // [ var(111) , var(43) ]
+                D[44,111] = (-1)*var(68); // [ var(111) , var(44) ]
+                D[45,111] = var(64); // [ var(111) , var(45) ]
+                D[48,111] = (-1)*var(127)+(-1)*var(128)+(-1)*var(129)+(-2)*var(130)+(-2)*var(131)+(-1)*var(132)+(-1)*var(133); // [ var(111) , var(48) ]
+                D[51,111] = var(3); // [ var(111) , var(51) ]
+                D[52,111] = (-1)*var(6); // [ var(111) , var(52) ]
+                D[54,111] = var(10); // [ var(111) , var(54) ]
+                D[56,111] = (-1)*var(15); // [ var(111) , var(56) ]
+                D[59,111] = (-1)*var(24); // [ var(111) , var(59) ]
+                D[60,111] = var(29); // [ var(111) , var(60) ]
+                D[61,111] = var(35); // [ var(111) , var(61) ]
+                D[63,111] = (-1)*var(42); // [ var(111) , var(63) ]
+                D[6,112] = var(108); // [ var(112) , var(6) ]
+                D[12,112] = var(104); // [ var(112) , var(12) ]
+                D[13,112] = (-1)*var(103); // [ var(112) , var(13) ]
+                D[18,112] = var(99); // [ var(112) , var(18) ]
+                D[19,112] = (-1)*var(98); // [ var(112) , var(19) ]
+                D[23,112] = (-1)*var(94); // [ var(112) , var(23) ]
+                D[24,112] = (-1)*var(93); // [ var(112) , var(24) ]
+                D[25,112] = (-1)*var(92); // [ var(112) , var(25) ]
+                D[29,112] = var(88); // [ var(112) , var(29) ]
+                D[30,112] = var(87); // [ var(112) , var(30) ]
+                D[31,112] = var(86); // [ var(112) , var(31) ]
+                D[35,112] = var(82); // [ var(112) , var(35) ]
+                D[36,112] = (-1)*var(81); // [ var(112) , var(36) ]
+                D[40,112] = var(76); // [ var(112) , var(40) ]
+                D[41,112] = (-1)*var(75); // [ var(112) , var(41) ]
+                D[45,112] = (-1)*var(69); // [ var(112) , var(45) ]
+                D[49,112] = (-1)*var(128)+(-1)*var(129)+(-2)*var(130)+(-2)*var(131)+(-2)*var(132)+(-1)*var(133); // [ var(112) , var(49) ]
+                D[52,112] = var(1); // [ var(112) , var(52) ]
+                D[55,112] = (-1)*var(8); // [ var(112) , var(55) ]
+                D[57,112] = (-1)*var(14); // [ var(112) , var(57) ]
+                D[58,112] = var(20); // [ var(112) , var(58) ]
+                D[59,112] = (-1)*var(21); // [ var(112) , var(59) ]
+                D[60,112] = var(26); // [ var(112) , var(60) ]
+                D[61,112] = var(32); // [ var(112) , var(61) ]
+                D[62,112] = (-1)*var(37); // [ var(112) , var(62) ]
+                D[4,113] = var(109); // [ var(113) , var(4) ]
+                D[10,113] = (-1)*var(106); // [ var(113) , var(10) ]
+                D[11,113] = (-1)*var(105); // [ var(113) , var(11) ]
+                D[14,113] = var(103); // [ var(113) , var(14) ]
+                D[17,113] = var(101); // [ var(113) , var(17) ]
+                D[18,113] = var(100); // [ var(113) , var(18) ]
+                D[21,113] = (-1)*var(98); // [ var(113) , var(21) ]
+                D[24,113] = (-1)*var(95); // [ var(113) , var(24) ]
+                D[27,113] = var(91); // [ var(113) , var(27) ]
+                D[28,113] = (-1)*var(90); // [ var(113) , var(28) ]
+                D[32,113] = var(87); // [ var(113) , var(32) ]
+                D[35,113] = var(84); // [ var(113) , var(35) ]
+                D[37,113] = (-1)*var(81); // [ var(113) , var(37) ]
+                D[38,113] = (-1)*var(80); // [ var(113) , var(38) ]
+                D[40,113] = (-1)*var(77); // [ var(113) , var(40) ]
+                D[42,113] = var(74); // [ var(113) , var(42) ]
+                D[43,113] = var(73); // [ var(113) , var(43) ]
+                D[46,113] = (-1)*var(67); // [ var(113) , var(46) ]
+                D[50,113] = (-1)*var(127)+(-1)*var(128)+(-2)*var(129)+(-3)*var(130)+(-2)*var(131)+(-1)*var(132); // [ var(113) , var(50) ]
+                D[53,113] = (-1)*var(2); // [ var(113) , var(53) ]
+                D[54,113] = (-1)*var(7); // [ var(113) , var(54) ]
+                D[57,113] = var(13); // [ var(113) , var(57) ]
+                D[59,113] = (-1)*var(19); // [ var(113) , var(59) ]
+                D[61,113] = var(30); // [ var(113) , var(61) ]
+                D[62,113] = (-1)*var(36); // [ var(113) , var(62) ]
+                D[63,113] = var(39); // [ var(113) , var(63) ]
+                D[3,114] = (-1)*var(111); // [ var(114) , var(3) ]
+                D[5,114] = var(110); // [ var(114) , var(5) ]
+                D[7,114] = var(109); // [ var(114) , var(7) ]
+                D[8,114] = var(108); // [ var(114) , var(8) ]
+                D[17,114] = var(102); // [ var(114) , var(17) ]
+                D[19,114] = (-1)*var(100); // [ var(114) , var(19) ]
+                D[21,114] = (-1)*var(99); // [ var(114) , var(21) ]
+                D[22,114] = (-1)*var(97); // [ var(114) , var(22) ]
+                D[26,114] = var(94); // [ var(114) , var(26) ]
+                D[31,114] = (-1)*var(89); // [ var(114) , var(31) ]
+                D[34,114] = var(85); // [ var(114) , var(34) ]
+                D[36,114] = var(84); // [ var(114) , var(36) ]
+                D[37,114] = var(82); // [ var(114) , var(37) ]
+                D[39,114] = (-1)*var(80); // [ var(114) , var(39) ]
+                D[45,114] = (-1)*var(71); // [ var(114) , var(45) ]
+                D[46,114] = (-1)*var(70); // [ var(114) , var(46) ]
+                D[47,114] = (-1)*var(68); // [ var(114) , var(47) ]
+                D[48,114] = var(66); // [ var(114) , var(48) ]
+                D[51,114] = (-1)*var(127)+(-1)*var(128)+(-2)*var(129)+(-2)*var(130)+(-2)*var(131)+(-1)*var(132)+(-1)*var(133); // [ var(114) , var(51) ]
+                D[54,114] = (-1)*var(4); // [ var(114) , var(54) ]
+                D[55,114] = (-1)*var(6); // [ var(114) , var(55) ]
+                D[56,114] = var(9); // [ var(114) , var(56) ]
+                D[59,114] = var(18); // [ var(114) , var(59) ]
+                D[60,114] = (-1)*var(23); // [ var(114) , var(60) ]
+                D[62,114] = (-1)*var(35); // [ var(114) , var(62) ]
+                D[63,114] = var(38); // [ var(114) , var(63) ]
+                D[1,115] = (-1)*var(112); // [ var(115) , var(1) ]
+                D[6,115] = var(111); // [ var(115) , var(6) ]
+                D[12,115] = var(107); // [ var(115) , var(12) ]
+                D[13,115] = (-1)*var(106); // [ var(115) , var(13) ]
+                D[18,115] = var(102); // [ var(115) , var(18) ]
+                D[19,115] = (-1)*var(101); // [ var(115) , var(19) ]
+                D[23,115] = (-1)*var(97); // [ var(115) , var(23) ]
+                D[25,115] = (-1)*var(96); // [ var(115) , var(25) ]
+                D[27,115] = (-1)*var(93); // [ var(115) , var(27) ]
+                D[30,115] = var(90); // [ var(115) , var(30) ]
+                D[33,115] = var(88); // [ var(115) , var(33) ]
+                D[34,115] = var(86); // [ var(115) , var(34) ]
+                D[38,115] = var(82); // [ var(115) , var(38) ]
+                D[39,115] = (-1)*var(81); // [ var(115) , var(39) ]
+                D[43,115] = var(76); // [ var(115) , var(43) ]
+                D[44,115] = (-1)*var(75); // [ var(115) , var(44) ]
+                D[48,115] = (-1)*var(69); // [ var(115) , var(48) ]
+                D[49,115] = var(64); // [ var(115) , var(49) ]
+                D[52,115] = (-1)*var(127)+(-1)*var(128)+(-1)*var(129)+(-2)*var(130)+(-2)*var(131)+(-2)*var(132)+(-1)*var(133); // [ var(115) , var(52) ]
+                D[55,115] = var(3); // [ var(115) , var(55) ]
+                D[57,115] = var(10); // [ var(115) , var(57) ]
+                D[58,115] = (-1)*var(15); // [ var(115) , var(58) ]
+                D[59,115] = var(17); // [ var(115) , var(59) ]
+                D[60,115] = (-1)*var(22); // [ var(115) , var(60) ]
+                D[61,115] = (-1)*var(28); // [ var(115) , var(61) ]
+                D[63,115] = var(37); // [ var(115) , var(63) ]
+                D[2,116] = var(113); // [ var(116) , var(2) ]
+                D[9,116] = (-1)*var(109); // [ var(116) , var(9) ]
+                D[15,116] = var(106); // [ var(116) , var(15) ]
+                D[16,116] = var(105); // [ var(116) , var(16) ]
+                D[20,116] = (-1)*var(103); // [ var(116) , var(20) ]
+                D[22,116] = (-1)*var(101); // [ var(116) , var(22) ]
+                D[23,116] = (-1)*var(100); // [ var(116) , var(23) ]
+                D[26,116] = var(98); // [ var(116) , var(26) ]
+                D[28,116] = var(96); // [ var(116) , var(28) ]
+                D[29,116] = var(95); // [ var(116) , var(29) ]
+                D[32,116] = (-1)*var(92); // [ var(116) , var(32) ]
+                D[33,116] = (-1)*var(91); // [ var(116) , var(33) ]
+                D[35,116] = (-1)*var(89); // [ var(116) , var(35) ]
+                D[37,116] = var(86); // [ var(116) , var(37) ]
+                D[38,116] = var(85); // [ var(116) , var(38) ]
+                D[40,116] = var(83); // [ var(116) , var(40) ]
+                D[42,116] = (-1)*var(79); // [ var(116) , var(42) ]
+                D[43,116] = (-1)*var(78); // [ var(116) , var(43) ]
+                D[46,116] = var(72); // [ var(116) , var(46) ]
+                D[50,116] = (-1)*var(65); // [ var(116) , var(50) ]
+                D[53,116] = (-1)*var(127)+(-2)*var(128)+(-2)*var(129)+(-3)*var(130)+(-2)*var(131)+(-1)*var(132); // [ var(116) , var(53) ]
+                D[56,116] = (-1)*var(7); // [ var(116) , var(56) ]
+                D[58,116] = var(13); // [ var(116) , var(58) ]
+                D[60,116] = (-1)*var(19); // [ var(116) , var(60) ]
+                D[61,116] = var(25); // [ var(116) , var(61) ]
+                D[62,116] = (-1)*var(31); // [ var(116) , var(62) ]
+                D[63,116] = var(34); // [ var(116) , var(63) ]
+                D[4,117] = var(114); // [ var(117) , var(4) ]
+                D[7,117] = var(113); // [ var(117) , var(7) ]
+                D[10,117] = (-1)*var(111); // [ var(117) , var(10) ]
+                D[11,117] = (-1)*var(110); // [ var(117) , var(11) ]
+                D[14,117] = var(108); // [ var(117) , var(14) ]
+                D[17,117] = var(107); // [ var(117) , var(17) ]
+                D[21,117] = (-1)*var(104); // [ var(117) , var(21) ]
+                D[25,117] = var(100); // [ var(117) , var(25) ]
+                D[28,117] = (-1)*var(97); // [ var(117) , var(28) ]
+                D[31,117] = (-1)*var(95); // [ var(117) , var(31) ]
+                D[32,117] = var(94); // [ var(117) , var(32) ]
+                D[34,117] = var(91); // [ var(117) , var(34) ]
+                D[37,117] = (-1)*var(88); // [ var(117) , var(37) ]
+                D[41,117] = var(84); // [ var(117) , var(41) ]
+                D[44,117] = (-1)*var(80); // [ var(117) , var(44) ]
+                D[45,117] = (-1)*var(77); // [ var(117) , var(45) ]
+                D[47,117] = var(74); // [ var(117) , var(47) ]
+                D[48,117] = var(73); // [ var(117) , var(48) ]
+                D[50,117] = (-1)*var(70); // [ var(117) , var(50) ]
+                D[51,117] = (-1)*var(67); // [ var(117) , var(51) ]
+                D[54,117] = (-1)*var(127)+(-1)*var(128)+(-2)*var(129)+(-3)*var(130)+(-2)*var(131)+(-1)*var(132)+(-1)*var(133); // [ var(117) , var(54) ]
+                D[56,117] = (-1)*var(2); // [ var(117) , var(56) ]
+                D[57,117] = (-1)*var(6); // [ var(117) , var(57) ]
+                D[59,117] = var(12); // [ var(117) , var(59) ]
+                D[61,117] = (-1)*var(23); // [ var(117) , var(61) ]
+                D[62,117] = var(29); // [ var(117) , var(62) ]
+                D[63,117] = (-1)*var(33); // [ var(117) , var(63) ]
+                D[3,118] = (-1)*var(115); // [ var(118) , var(3) ]
+                D[6,118] = var(114); // [ var(118) , var(6) ]
+                D[8,118] = var(112); // [ var(118) , var(8) ]
+                D[12,118] = var(110); // [ var(118) , var(12) ]
+                D[13,118] = (-1)*var(109); // [ var(118) , var(13) ]
+                D[19,118] = (-1)*var(105); // [ var(118) , var(19) ]
+                D[24,118] = var(102); // [ var(118) , var(24) ]
+                D[27,118] = (-1)*var(99); // [ var(118) , var(27) ]
+                D[29,118] = (-1)*var(97); // [ var(118) , var(29) ]
+                D[31,118] = (-1)*var(96); // [ var(118) , var(31) ]
+                D[33,118] = var(94); // [ var(118) , var(33) ]
+                D[34,118] = var(92); // [ var(118) , var(34) ]
+                D[36,118] = var(90); // [ var(118) , var(36) ]
+                D[39,118] = (-1)*var(87); // [ var(118) , var(39) ]
+                D[42,118] = var(82); // [ var(118) , var(42) ]
+                D[46,118] = var(76); // [ var(118) , var(46) ]
+                D[47,118] = (-1)*var(75); // [ var(118) , var(47) ]
+                D[49,118] = (-1)*var(71); // [ var(118) , var(49) ]
+                D[51,118] = (-1)*var(69); // [ var(118) , var(51) ]
+                D[52,118] = var(66); // [ var(118) , var(52) ]
+                D[55,118] = (-1)*var(127)+(-1)*var(128)+(-2)*var(129)+(-2)*var(130)+(-2)*var(131)+(-2)*var(132)+(-1)*var(133); // [ var(118) , var(55) ]
+                D[57,118] = (-1)*var(4); // [ var(118) , var(57) ]
+                D[58,118] = var(9); // [ var(118) , var(58) ]
+                D[59,118] = (-1)*var(11); // [ var(118) , var(59) ]
+                D[60,118] = var(16); // [ var(118) , var(60) ]
+                D[62,118] = var(28); // [ var(118) , var(62) ]
+                D[63,118] = (-1)*var(32); // [ var(118) , var(63) ]
+                D[2,119] = var(117); // [ var(119) , var(2) ]
+                D[7,119] = var(116); // [ var(119) , var(7) ]
+                D[9,119] = (-1)*var(114); // [ var(119) , var(9) ]
+                D[15,119] = var(111); // [ var(119) , var(15) ]
+                D[16,119] = var(110); // [ var(119) , var(16) ]
+                D[20,119] = (-1)*var(108); // [ var(119) , var(20) ]
+                D[22,119] = (-1)*var(107); // [ var(119) , var(22) ]
+                D[26,119] = var(104); // [ var(119) , var(26) ]
+                D[28,119] = var(102); // [ var(119) , var(28) ]
+                D[30,119] = (-1)*var(100); // [ var(119) , var(30) ]
+                D[32,119] = (-1)*var(99); // [ var(119) , var(32) ]
+                D[36,119] = var(95); // [ var(119) , var(36) ]
+                D[37,119] = var(93); // [ var(119) , var(37) ]
+                D[39,119] = (-1)*var(91); // [ var(119) , var(39) ]
+                D[41,119] = (-1)*var(89); // [ var(119) , var(41) ]
+                D[44,119] = var(85); // [ var(119) , var(44) ]
+                D[45,119] = var(83); // [ var(119) , var(45) ]
+                D[47,119] = (-1)*var(79); // [ var(119) , var(47) ]
+                D[48,119] = (-1)*var(78); // [ var(119) , var(48) ]
+                D[51,119] = var(72); // [ var(119) , var(51) ]
+                D[53,119] = (-1)*var(70); // [ var(119) , var(53) ]
+                D[54,119] = (-1)*var(65); // [ var(119) , var(54) ]
+                D[56,119] = (-1)*var(127)+(-2)*var(128)+(-2)*var(129)+(-3)*var(130)+(-2)*var(131)+(-1)*var(132)+(-1)*var(133); // [ var(119) , var(56) ]
+                D[58,119] = (-1)*var(6); // [ var(119) , var(58) ]
+                D[60,119] = var(12); // [ var(119) , var(60) ]
+                D[61,119] = (-1)*var(18); // [ var(119) , var(61) ]
+                D[62,119] = var(24); // [ var(119) , var(62) ]
+                D[63,119] = (-1)*var(27); // [ var(119) , var(63) ]
+                D[4,120] = var(118); // [ var(120) , var(4) ]
+                D[6,120] = var(117); // [ var(120) , var(6) ]
+                D[10,120] = (-1)*var(115); // [ var(120) , var(10) ]
+                D[13,120] = (-1)*var(113); // [ var(120) , var(13) ]
+                D[14,120] = var(112); // [ var(120) , var(14) ]
+                D[18,120] = (-1)*var(110); // [ var(120) , var(18) ]
+                D[24,120] = var(107); // [ var(120) , var(24) ]
+                D[25,120] = var(105); // [ var(120) , var(25) ]
+                D[27,120] = (-1)*var(104); // [ var(120) , var(27) ]
+                D[31,120] = (-1)*var(101); // [ var(120) , var(31) ]
+                D[34,120] = var(98); // [ var(120) , var(34) ]
+                D[35,120] = (-1)*var(97); // [ var(120) , var(35) ]
+                D[38,120] = var(94); // [ var(120) , var(38) ]
+                D[41,120] = var(90); // [ var(120) , var(41) ]
+                D[42,120] = (-1)*var(88); // [ var(120) , var(42) ]
+                D[44,120] = (-1)*var(87); // [ var(120) , var(44) ]
+                D[47,120] = var(81); // [ var(120) , var(47) ]
+                D[49,120] = (-1)*var(77); // [ var(120) , var(49) ]
+                D[50,120] = var(76); // [ var(120) , var(50) ]
+                D[52,120] = var(73); // [ var(120) , var(52) ]
+                D[54,120] = (-1)*var(69); // [ var(120) , var(54) ]
+                D[55,120] = (-1)*var(67); // [ var(120) , var(55) ]
+                D[57,120] = (-1)*var(127)+(-1)*var(128)+(-2)*var(129)+(-3)*var(130)+(-2)*var(131)+(-2)*var(132)+(-1)*var(133); // [ var(120) , var(57) ]
+                D[58,120] = (-1)*var(2); // [ var(120) , var(58) ]
+                D[59,120] = (-1)*var(5); // [ var(120) , var(59) ]
+                D[61,120] = var(16); // [ var(120) , var(61) ]
+                D[62,120] = (-1)*var(22); // [ var(120) , var(62) ]
+                D[63,120] = var(26); // [ var(120) , var(63) ]
+                D[2,121] = var(120); // [ var(121) , var(2) ]
+                D[6,121] = var(119); // [ var(121) , var(6) ]
+                D[9,121] = (-1)*var(118); // [ var(121) , var(9) ]
+                D[13,121] = (-1)*var(116); // [ var(121) , var(13) ]
+                D[15,121] = var(115); // [ var(121) , var(15) ]
+                D[20,121] = (-1)*var(112); // [ var(121) , var(20) ]
+                D[23,121] = var(110); // [ var(121) , var(23) ]
+                D[29,121] = (-1)*var(107); // [ var(121) , var(29) ]
+                D[30,121] = (-1)*var(105); // [ var(121) , var(30) ]
+                D[33,121] = var(104); // [ var(121) , var(33) ]
+                D[35,121] = var(102); // [ var(121) , var(35) ]
+                D[36,121] = var(101); // [ var(121) , var(36) ]
+                D[38,121] = (-1)*var(99); // [ var(121) , var(38) ]
+                D[39,121] = (-1)*var(98); // [ var(121) , var(39) ]
+                D[41,121] = (-1)*var(96); // [ var(121) , var(41) ]
+                D[42,121] = var(93); // [ var(121) , var(42) ]
+                D[44,121] = var(92); // [ var(121) , var(44) ]
+                D[47,121] = (-1)*var(86); // [ var(121) , var(47) ]
+                D[49,121] = var(83); // [ var(121) , var(49) ]
+                D[52,121] = (-1)*var(78); // [ var(121) , var(52) ]
+                D[53,121] = var(76); // [ var(121) , var(53) ]
+                D[55,121] = var(72); // [ var(121) , var(55) ]
+                D[56,121] = (-1)*var(69); // [ var(121) , var(56) ]
+                D[57,121] = (-1)*var(65); // [ var(121) , var(57) ]
+                D[58,121] = (-1)*var(127)+(-2)*var(128)+(-2)*var(129)+(-3)*var(130)+(-2)*var(131)+(-2)*var(132)+(-1)*var(133); // [ var(121) , var(58) ]
+                D[60,121] = (-1)*var(5); // [ var(121) , var(60) ]
+                D[61,121] = var(11); // [ var(121) , var(61) ]
+                D[62,121] = (-1)*var(17); // [ var(121) , var(62) ]
+                D[63,121] = var(21); // [ var(121) , var(63) ]
+                D[5,122] = var(120); // [ var(122) , var(5) ]
+                D[11,122] = var(118); // [ var(122) , var(11) ]
+                D[12,122] = (-1)*var(117); // [ var(122) , var(12) ]
+                D[17,122] = (-1)*var(115); // [ var(122) , var(17) ]
+                D[18,122] = (-1)*var(114); // [ var(122) , var(18) ]
+                D[19,122] = var(113); // [ var(122) , var(19) ]
+                D[21,122] = var(112); // [ var(122) , var(21) ]
+                D[24,122] = var(111); // [ var(122) , var(24) ]
+                D[25,122] = var(109); // [ var(122) , var(25) ]
+                D[27,122] = (-1)*var(108); // [ var(122) , var(27) ]
+                D[31,122] = (-1)*var(106); // [ var(122) , var(31) ]
+                D[34,122] = var(103); // [ var(122) , var(34) ]
+                D[40,122] = (-1)*var(97); // [ var(122) , var(40) ]
+                D[43,122] = var(94); // [ var(122) , var(43) ]
+                D[45,122] = var(90); // [ var(122) , var(45) ]
+                D[46,122] = (-1)*var(88); // [ var(122) , var(46) ]
+                D[48,122] = (-1)*var(87); // [ var(122) , var(48) ]
+                D[49,122] = (-1)*var(84); // [ var(122) , var(49) ]
+                D[50,122] = (-1)*var(82); // [ var(122) , var(50) ]
+                D[51,122] = var(81); // [ var(122) , var(51) ]
+                D[52,122] = var(80); // [ var(122) , var(52) ]
+                D[54,122] = var(75); // [ var(122) , var(54) ]
+                D[55,122] = (-1)*var(74); // [ var(122) , var(55) ]
+                D[57,122] = (-1)*var(68); // [ var(122) , var(57) ]
+                D[59,122] = (-1)*var(127)+(-1)*var(128)+(-2)*var(129)+(-3)*var(130)+(-3)*var(131)+(-2)*var(132)+(-1)*var(133); // [ var(122) , var(59) ]
+                D[60,122] = (-1)*var(2); // [ var(122) , var(60) ]
+                D[61,122] = (-1)*var(9); // [ var(122) , var(61) ]
+                D[62,122] = var(15); // [ var(122) , var(62) ]
+                D[63,122] = (-1)*var(20); // [ var(122) , var(63) ]
+                D[2,123] = var(122); // [ var(123) , var(2) ]
+                D[5,123] = var(121); // [ var(123) , var(5) ]
+                D[12,123] = (-1)*var(119); // [ var(123) , var(12) ]
+                D[16,123] = (-1)*var(118); // [ var(123) , var(16) ]
+                D[19,123] = var(116); // [ var(123) , var(19) ]
+                D[22,123] = var(115); // [ var(123) , var(22) ]
+                D[23,123] = var(114); // [ var(123) , var(23) ]
+                D[26,123] = (-1)*var(112); // [ var(123) , var(26) ]
+                D[29,123] = (-1)*var(111); // [ var(123) , var(29) ]
+                D[30,123] = (-1)*var(109); // [ var(123) , var(30) ]
+                D[33,123] = var(108); // [ var(123) , var(33) ]
+                D[36,123] = var(106); // [ var(123) , var(36) ]
+                D[39,123] = (-1)*var(103); // [ var(123) , var(39) ]
+                D[40,123] = var(102); // [ var(123) , var(40) ]
+                D[43,123] = (-1)*var(99); // [ var(123) , var(43) ]
+                D[45,123] = (-1)*var(96); // [ var(123) , var(45) ]
+                D[46,123] = var(93); // [ var(123) , var(46) ]
+                D[48,123] = var(92); // [ var(123) , var(48) ]
+                D[49,123] = var(89); // [ var(123) , var(49) ]
+                D[51,123] = (-1)*var(86); // [ var(123) , var(51) ]
+                D[52,123] = (-1)*var(85); // [ var(123) , var(52) ]
+                D[53,123] = (-1)*var(82); // [ var(123) , var(53) ]
+                D[55,123] = var(79); // [ var(123) , var(55) ]
+                D[56,123] = var(75); // [ var(123) , var(56) ]
+                D[58,123] = (-1)*var(68); // [ var(123) , var(58) ]
+                D[59,123] = (-1)*var(65); // [ var(123) , var(59) ]
+                D[60,123] = (-1)*var(127)+(-2)*var(128)+(-2)*var(129)+(-3)*var(130)+(-3)*var(131)+(-2)*var(132)+(-1)*var(133); // [ var(123) , var(60) ]
+                D[61,123] = (-1)*var(4); // [ var(123) , var(61) ]
+                D[62,123] = var(10); // [ var(123) , var(62) ]
+                D[63,123] = (-1)*var(14); // [ var(123) , var(63) ]
+                D[4,124] = var(123); // [ var(124) , var(4) ]
+                D[9,124] = var(122); // [ var(124) , var(9) ]
+                D[11,124] = (-1)*var(121); // [ var(124) , var(11) ]
+                D[16,124] = (-1)*var(120); // [ var(124) , var(16) ]
+                D[18,124] = var(119); // [ var(124) , var(18) ]
+                D[23,124] = var(117); // [ var(124) , var(23) ]
+                D[25,124] = (-1)*var(116); // [ var(124) , var(25) ]
+                D[28,124] = var(115); // [ var(124) , var(28) ]
+                D[30,124] = (-1)*var(113); // [ var(124) , var(30) ]
+                D[32,124] = (-1)*var(112); // [ var(124) , var(32) ]
+                D[35,124] = (-1)*var(111); // [ var(124) , var(35) ]
+                D[38,124] = var(108); // [ var(124) , var(38) ]
+                D[40,124] = var(107); // [ var(124) , var(40) ]
+                D[41,124] = var(106); // [ var(124) , var(41) ]
+                D[43,124] = (-1)*var(104); // [ var(124) , var(43) ]
+                D[44,124] = (-1)*var(103); // [ var(124) , var(44) ]
+                D[45,124] = (-1)*var(101); // [ var(124) , var(45) ]
+                D[48,124] = var(98); // [ var(124) , var(48) ]
+                D[49,124] = var(95); // [ var(124) , var(49) ]
+                D[50,124] = var(93); // [ var(124) , var(50) ]
+                D[52,124] = (-1)*var(91); // [ var(124) , var(52) ]
+                D[53,124] = var(88); // [ var(124) , var(53) ]
+                D[54,124] = (-1)*var(86); // [ var(124) , var(54) ]
+                D[56,124] = (-1)*var(81); // [ var(124) , var(56) ]
+                D[57,124] = var(79); // [ var(124) , var(57) ]
+                D[58,124] = var(74); // [ var(124) , var(58) ]
+                D[59,124] = (-1)*var(72); // [ var(124) , var(59) ]
+                D[60,124] = (-1)*var(67); // [ var(124) , var(60) ]
+                D[61,124] = (-1)*var(127)+(-2)*var(128)+(-2)*var(129)+(-4)*var(130)+(-3)*var(131)+(-2)*var(132)+(-1)*var(133); // [ var(124) , var(61) ]
+                D[62,124] = (-1)*var(3); // [ var(124) , var(62) ]
+                D[63,124] = var(8); // [ var(124) , var(63) ]
+                D[3,125] = var(124); // [ var(125) , var(3) ]
+                D[10,125] = (-1)*var(123); // [ var(125) , var(10) ]
+                D[15,125] = (-1)*var(122); // [ var(125) , var(15) ]
+                D[17,125] = var(121); // [ var(125) , var(17) ]
+                D[22,125] = var(120); // [ var(125) , var(22) ]
+                D[24,125] = (-1)*var(119); // [ var(125) , var(24) ]
+                D[28,125] = (-1)*var(118); // [ var(125) , var(28) ]
+                D[29,125] = (-1)*var(117); // [ var(125) , var(29) ]
+                D[31,125] = var(116); // [ var(125) , var(31) ]
+                D[35,125] = var(114); // [ var(125) , var(35) ]
+                D[36,125] = var(113); // [ var(125) , var(36) ]
+                D[37,125] = var(112); // [ var(125) , var(37) ]
+                D[40,125] = (-1)*var(110); // [ var(125) , var(40) ]
+                D[41,125] = (-1)*var(109); // [ var(125) , var(41) ]
+                D[42,125] = (-1)*var(108); // [ var(125) , var(42) ]
+                D[45,125] = var(105); // [ var(125) , var(45) ]
+                D[46,125] = var(104); // [ var(125) , var(46) ]
+                D[47,125] = var(103); // [ var(125) , var(47) ]
+                D[49,125] = (-1)*var(100); // [ var(125) , var(49) ]
+                D[50,125] = (-1)*var(99); // [ var(125) , var(50) ]
+                D[51,125] = (-1)*var(98); // [ var(125) , var(51) ]
+                D[53,125] = (-1)*var(94); // [ var(125) , var(53) ]
+                D[54,125] = var(92); // [ var(125) , var(54) ]
+                D[55,125] = var(91); // [ var(125) , var(55) ]
+                D[56,125] = var(87); // [ var(125) , var(56) ]
+                D[57,125] = (-1)*var(85); // [ var(125) , var(57) ]
+                D[58,125] = (-1)*var(80); // [ var(125) , var(58) ]
+                D[59,125] = var(78); // [ var(125) , var(59) ]
+                D[60,125] = var(73); // [ var(125) , var(60) ]
+                D[61,125] = (-1)*var(66); // [ var(125) , var(61) ]
+                D[62,125] = (-1)*var(127)+(-2)*var(128)+(-3)*var(129)+(-4)*var(130)+(-3)*var(131)+(-2)*var(132)+(-1)*var(133); // [ var(125) , var(62) ]
+                D[63,125] = (-1)*var(1); // [ var(125) , var(63) ]
+                D[1,126] = var(125); // [ var(126) , var(1) ]
+                D[8,126] = (-1)*var(124); // [ var(126) , var(8) ]
+                D[14,126] = var(123); // [ var(126) , var(14) ]
+                D[20,126] = var(122); // [ var(126) , var(20) ]
+                D[21,126] = (-1)*var(121); // [ var(126) , var(21) ]
+                D[26,126] = (-1)*var(120); // [ var(126) , var(26) ]
+                D[27,126] = var(119); // [ var(126) , var(27) ]
+                D[32,126] = var(118); // [ var(126) , var(32) ]
+                D[33,126] = var(117); // [ var(126) , var(33) ]
+                D[34,126] = (-1)*var(116); // [ var(126) , var(34) ]
+                D[37,126] = (-1)*var(115); // [ var(126) , var(37) ]
+                D[38,126] = (-1)*var(114); // [ var(126) , var(38) ]
+                D[39,126] = (-1)*var(113); // [ var(126) , var(39) ]
+                D[42,126] = var(111); // [ var(126) , var(42) ]
+                D[43,126] = var(110); // [ var(126) , var(43) ]
+                D[44,126] = var(109); // [ var(126) , var(44) ]
+                D[46,126] = (-1)*var(107); // [ var(126) , var(46) ]
+                D[47,126] = (-1)*var(106); // [ var(126) , var(47) ]
+                D[48,126] = (-1)*var(105); // [ var(126) , var(48) ]
+                D[50,126] = var(102); // [ var(126) , var(50) ]
+                D[51,126] = var(101); // [ var(126) , var(51) ]
+                D[52,126] = var(100); // [ var(126) , var(52) ]
+                D[53,126] = var(97); // [ var(126) , var(53) ]
+                D[54,126] = (-1)*var(96); // [ var(126) , var(54) ]
+                D[55,126] = (-1)*var(95); // [ var(126) , var(55) ]
+                D[56,126] = (-1)*var(90); // [ var(126) , var(56) ]
+                D[57,126] = var(89); // [ var(126) , var(57) ]
+                D[58,126] = var(84); // [ var(126) , var(58) ]
+                D[59,126] = (-1)*var(83); // [ var(126) , var(59) ]
+                D[60,126] = (-1)*var(77); // [ var(126) , var(60) ]
+                D[61,126] = var(71); // [ var(126) , var(61) ]
+                D[62,126] = (-1)*var(64); // [ var(126) , var(62) ]
+                D[63,126] = (-2)*var(127)+(-2)*var(128)+(-3)*var(129)+(-4)*var(130)+(-3)*var(131)+(-2)*var(132)+(-1)*var(133); // [ var(126) , var(63) ]
+        // X(i) * X(j):
+                D[1,3] = var(8); // [ var(3) , var(1) ]
+                D[1,10] = var(14); // [ var(10) , var(1) ]
+                D[1,15] = var(20); // [ var(15) , var(1) ]
+                D[1,17] = var(21); // [ var(17) , var(1) ]
+                D[1,22] = var(26); // [ var(22) , var(1) ]
+                D[1,24] = var(27); // [ var(24) , var(1) ]
+                D[1,28] = var(32); // [ var(28) , var(1) ]
+                D[1,29] = var(33); // [ var(29) , var(1) ]
+                D[1,31] = var(34); // [ var(31) , var(1) ]
+                D[1,35] = var(38); // [ var(35) , var(1) ]
+                D[1,36] = var(39); // [ var(36) , var(1) ]
+                D[1,40] = var(43); // [ var(40) , var(1) ]
+                D[1,41] = var(44); // [ var(41) , var(1) ]
+                D[1,45] = var(48); // [ var(45) , var(1) ]
+                D[1,49] = var(52); // [ var(49) , var(1) ]
+                D[1,62] = (-1)*var(63); // [ var(62) , var(1) ]
+                D[2,4] = var(9); // [ var(4) , var(2) ]
+                D[2,10] = var(15); // [ var(10) , var(2) ]
+                D[2,11] = var(16); // [ var(11) , var(2) ]
+                D[2,14] = var(20); // [ var(14) , var(2) ]
+                D[2,17] = var(22); // [ var(17) , var(2) ]
+                D[2,18] = var(23); // [ var(18) , var(2) ]
+                D[2,21] = var(26); // [ var(21) , var(2) ]
+                D[2,24] = var(29); // [ var(24) , var(2) ]
+                D[2,25] = var(30); // [ var(25) , var(2) ]
+                D[2,27] = var(33); // [ var(27) , var(2) ]
+                D[2,31] = var(36); // [ var(31) , var(2) ]
+                D[2,34] = var(39); // [ var(34) , var(2) ]
+                D[2,50] = (-1)*var(53); // [ var(50) , var(2) ]
+                D[2,54] = (-1)*var(56); // [ var(54) , var(2) ]
+                D[2,57] = (-1)*var(58); // [ var(57) , var(2) ]
+                D[2,59] = (-1)*var(60); // [ var(59) , var(2) ]
+                D[3,4] = var(10); // [ var(4) , var(3) ]
+                D[3,9] = var(15); // [ var(9) , var(3) ]
+                D[3,11] = var(17); // [ var(11) , var(3) ]
+                D[3,16] = var(22); // [ var(16) , var(3) ]
+                D[3,18] = var(24); // [ var(18) , var(3) ]
+                D[3,23] = var(29); // [ var(23) , var(3) ]
+                D[3,25] = var(31); // [ var(25) , var(3) ]
+                D[3,30] = var(36); // [ var(30) , var(3) ]
+                D[3,32] = var(37); // [ var(32) , var(3) ]
+                D[3,38] = var(42); // [ var(38) , var(3) ]
+                D[3,43] = var(46); // [ var(43) , var(3) ]
+                D[3,44] = var(47); // [ var(44) , var(3) ]
+                D[3,48] = var(51); // [ var(48) , var(3) ]
+                D[3,52] = var(55); // [ var(52) , var(3) ]
+                D[3,61] = (-1)*var(62); // [ var(61) , var(3) ]
+                D[4,5] = var(11); // [ var(5) , var(4) ]
+                D[4,8] = (-1)*var(14); // [ var(8) , var(4) ]
+                D[4,12] = var(18); // [ var(12) , var(4) ]
+                D[4,19] = var(25); // [ var(19) , var(4) ]
+                D[4,22] = (-1)*var(28); // [ var(22) , var(4) ]
+                D[4,26] = (-1)*var(32); // [ var(26) , var(4) ]
+                D[4,29] = (-1)*var(35); // [ var(29) , var(4) ]
+                D[4,33] = (-1)*var(38); // [ var(33) , var(4) ]
+                D[4,36] = (-1)*var(41); // [ var(36) , var(4) ]
+                D[4,39] = (-1)*var(44); // [ var(39) , var(4) ]
+                D[4,46] = (-1)*var(50); // [ var(46) , var(4) ]
+                D[4,51] = (-1)*var(54); // [ var(51) , var(4) ]
+                D[4,55] = (-1)*var(57); // [ var(55) , var(4) ]
+                D[4,60] = (-1)*var(61); // [ var(60) , var(4) ]
+                D[5,6] = var(12); // [ var(6) , var(5) ]
+                D[5,9] = (-1)*var(16); // [ var(9) , var(5) ]
+                D[5,10] = (-1)*var(17); // [ var(10) , var(5) ]
+                D[5,13] = var(19); // [ var(13) , var(5) ]
+                D[5,14] = (-1)*var(21); // [ var(14) , var(5) ]
+                D[5,15] = (-1)*var(22); // [ var(15) , var(5) ]
+                D[5,20] = (-1)*var(26); // [ var(20) , var(5) ]
+                D[5,35] = (-1)*var(40); // [ var(35) , var(5) ]
+                D[5,38] = (-1)*var(43); // [ var(38) , var(5) ]
+                D[5,41] = (-1)*var(45); // [ var(41) , var(5) ]
+                D[5,42] = (-1)*var(46); // [ var(42) , var(5) ]
+                D[5,44] = (-1)*var(48); // [ var(44) , var(5) ]
+                D[5,47] = (-1)*var(51); // [ var(47) , var(5) ]
+                D[5,57] = (-1)*var(59); // [ var(57) , var(5) ]
+                D[5,58] = (-1)*var(60); // [ var(58) , var(5) ]
+                D[6,7] = var(13); // [ var(7) , var(6) ]
+                D[6,11] = (-1)*var(18); // [ var(11) , var(6) ]
+                D[6,16] = (-1)*var(23); // [ var(16) , var(6) ]
+                D[6,17] = (-1)*var(24); // [ var(17) , var(6) ]
+                D[6,21] = (-1)*var(27); // [ var(21) , var(6) ]
+                D[6,22] = (-1)*var(29); // [ var(22) , var(6) ]
+                D[6,26] = (-1)*var(33); // [ var(26) , var(6) ]
+                D[6,28] = (-1)*var(35); // [ var(28) , var(6) ]
+                D[6,32] = (-1)*var(38); // [ var(32) , var(6) ]
+                D[6,37] = (-1)*var(42); // [ var(37) , var(6) ]
+                D[6,45] = (-1)*var(49); // [ var(45) , var(6) ]
+                D[6,48] = (-1)*var(52); // [ var(48) , var(6) ]
+                D[6,51] = (-1)*var(55); // [ var(51) , var(6) ]
+                D[6,54] = (-1)*var(57); // [ var(54) , var(6) ]
+                D[6,56] = (-1)*var(58); // [ var(56) , var(6) ]
+                D[7,12] = (-1)*var(19); // [ var(12) , var(7) ]
+                D[7,18] = (-1)*var(25); // [ var(18) , var(7) ]
+                D[7,23] = (-1)*var(30); // [ var(23) , var(7) ]
+                D[7,24] = (-1)*var(31); // [ var(24) , var(7) ]
+                D[7,27] = (-1)*var(34); // [ var(27) , var(7) ]
+                D[7,29] = (-1)*var(36); // [ var(29) , var(7) ]
+                D[7,33] = (-1)*var(39); // [ var(33) , var(7) ]
+                D[7,35] = (-1)*var(41); // [ var(35) , var(7) ]
+                D[7,38] = (-1)*var(44); // [ var(38) , var(7) ]
+                D[7,40] = (-1)*var(45); // [ var(40) , var(7) ]
+                D[7,42] = (-1)*var(47); // [ var(42) , var(7) ]
+                D[7,43] = (-1)*var(48); // [ var(43) , var(7) ]
+                D[7,46] = (-1)*var(51); // [ var(46) , var(7) ]
+                D[7,50] = (-1)*var(54); // [ var(50) , var(7) ]
+                D[7,53] = (-1)*var(56); // [ var(53) , var(7) ]
+                D[8,9] = var(20); // [ var(9) , var(8) ]
+                D[8,11] = var(21); // [ var(11) , var(8) ]
+                D[8,16] = var(26); // [ var(16) , var(8) ]
+                D[8,18] = var(27); // [ var(18) , var(8) ]
+                D[8,23] = var(33); // [ var(23) , var(8) ]
+                D[8,25] = var(34); // [ var(25) , var(8) ]
+                D[8,28] = (-1)*var(37); // [ var(28) , var(8) ]
+                D[8,30] = var(39); // [ var(30) , var(8) ]
+                D[8,35] = (-1)*var(42); // [ var(35) , var(8) ]
+                D[8,40] = (-1)*var(46); // [ var(40) , var(8) ]
+                D[8,41] = (-1)*var(47); // [ var(41) , var(8) ]
+                D[8,45] = (-1)*var(51); // [ var(45) , var(8) ]
+                D[8,49] = (-1)*var(55); // [ var(49) , var(8) ]
+                D[8,61] = var(63); // [ var(61) , var(8) ]
+                D[9,12] = var(23); // [ var(12) , var(9) ]
+                D[9,17] = var(28); // [ var(17) , var(9) ]
+                D[9,19] = var(30); // [ var(19) , var(9) ]
+                D[9,21] = var(32); // [ var(21) , var(9) ]
+                D[9,24] = var(35); // [ var(24) , var(9) ]
+                D[9,27] = var(38); // [ var(27) , var(9) ]
+                D[9,31] = var(41); // [ var(31) , var(9) ]
+                D[9,34] = var(44); // [ var(34) , var(9) ]
+                D[9,46] = var(53); // [ var(46) , var(9) ]
+                D[9,51] = var(56); // [ var(51) , var(9) ]
+                D[9,55] = var(58); // [ var(55) , var(9) ]
+                D[9,59] = (-1)*var(61); // [ var(59) , var(9) ]
+                D[10,12] = var(24); // [ var(12) , var(10) ]
+                D[10,16] = var(28); // [ var(16) , var(10) ]
+                D[10,19] = var(31); // [ var(19) , var(10) ]
+                D[10,23] = var(35); // [ var(23) , var(10) ]
+                D[10,26] = (-1)*var(37); // [ var(26) , var(10) ]
+                D[10,30] = var(41); // [ var(30) , var(10) ]
+                D[10,33] = (-1)*var(42); // [ var(33) , var(10) ]
+                D[10,39] = (-1)*var(47); // [ var(39) , var(10) ]
+                D[10,43] = var(50); // [ var(43) , var(10) ]
+                D[10,48] = var(54); // [ var(48) , var(10) ]
+                D[10,52] = var(57); // [ var(52) , var(10) ]
+                D[10,60] = var(62); // [ var(60) , var(10) ]
+                D[11,13] = var(25); // [ var(13) , var(11) ]
+                D[11,15] = var(28); // [ var(15) , var(11) ]
+                D[11,20] = var(32); // [ var(20) , var(11) ]
+                D[11,29] = (-1)*var(40); // [ var(29) , var(11) ]
+                D[11,33] = (-1)*var(43); // [ var(33) , var(11) ]
+                D[11,36] = (-1)*var(45); // [ var(36) , var(11) ]
+                D[11,39] = (-1)*var(48); // [ var(39) , var(11) ]
+                D[11,42] = var(50); // [ var(42) , var(11) ]
+                D[11,47] = var(54); // [ var(47) , var(11) ]
+                D[11,55] = (-1)*var(59); // [ var(55) , var(11) ]
+                D[11,58] = var(61); // [ var(58) , var(11) ]
+                D[12,14] = (-1)*var(27); // [ var(14) , var(12) ]
+                D[12,15] = (-1)*var(29); // [ var(15) , var(12) ]
+                D[12,20] = (-1)*var(33); // [ var(20) , var(12) ]
+                D[12,28] = var(40); // [ var(28) , var(12) ]
+                D[12,32] = var(43); // [ var(32) , var(12) ]
+                D[12,37] = var(46); // [ var(37) , var(12) ]
+                D[12,41] = (-1)*var(49); // [ var(41) , var(12) ]
+                D[12,44] = (-1)*var(52); // [ var(44) , var(12) ]
+                D[12,47] = (-1)*var(55); // [ var(47) , var(12) ]
+                D[12,54] = var(59); // [ var(54) , var(12) ]
+                D[12,56] = var(60); // [ var(56) , var(12) ]
+                D[13,16] = (-1)*var(30); // [ var(16) , var(13) ]
+                D[13,17] = (-1)*var(31); // [ var(17) , var(13) ]
+                D[13,21] = (-1)*var(34); // [ var(21) , var(13) ]
+                D[13,22] = (-1)*var(36); // [ var(22) , var(13) ]
+                D[13,26] = (-1)*var(39); // [ var(26) , var(13) ]
+                D[13,28] = (-1)*var(41); // [ var(28) , var(13) ]
+                D[13,32] = (-1)*var(44); // [ var(32) , var(13) ]
+                D[13,37] = (-1)*var(47); // [ var(37) , var(13) ]
+                D[13,40] = var(49); // [ var(40) , var(13) ]
+                D[13,43] = var(52); // [ var(43) , var(13) ]
+                D[13,46] = var(55); // [ var(46) , var(13) ]
+                D[13,50] = var(57); // [ var(50) , var(13) ]
+                D[13,53] = var(58); // [ var(53) , var(13) ]
+                D[14,16] = var(32); // [ var(16) , var(14) ]
+                D[14,19] = var(34); // [ var(19) , var(14) ]
+                D[14,22] = var(37); // [ var(22) , var(14) ]
+                D[14,23] = var(38); // [ var(23) , var(14) ]
+                D[14,29] = var(42); // [ var(29) , var(14) ]
+                D[14,30] = var(44); // [ var(30) , var(14) ]
+                D[14,36] = var(47); // [ var(36) , var(14) ]
+                D[14,40] = (-1)*var(50); // [ var(40) , var(14) ]
+                D[14,45] = (-1)*var(54); // [ var(45) , var(14) ]
+                D[14,49] = (-1)*var(57); // [ var(49) , var(14) ]
+                D[14,60] = (-1)*var(63); // [ var(60) , var(14) ]
+                D[15,18] = (-1)*var(35); // [ var(18) , var(15) ]
+                D[15,19] = var(36); // [ var(19) , var(15) ]
+                D[15,21] = var(37); // [ var(21) , var(15) ]
+                D[15,25] = (-1)*var(41); // [ var(25) , var(15) ]
+                D[15,27] = var(42); // [ var(27) , var(15) ]
+                D[15,34] = var(47); // [ var(34) , var(15) ]
+                D[15,43] = (-1)*var(53); // [ var(43) , var(15) ]
+                D[15,48] = (-1)*var(56); // [ var(48) , var(15) ]
+                D[15,52] = (-1)*var(58); // [ var(52) , var(15) ]
+                D[15,59] = var(62); // [ var(59) , var(15) ]
+                D[16,24] = var(40); // [ var(24) , var(16) ]
+                D[16,27] = var(43); // [ var(27) , var(16) ]
+                D[16,31] = var(45); // [ var(31) , var(16) ]
+                D[16,34] = var(48); // [ var(34) , var(16) ]
+                D[16,42] = (-1)*var(53); // [ var(42) , var(16) ]
+                D[16,47] = (-1)*var(56); // [ var(47) , var(16) ]
+                D[16,55] = var(60); // [ var(55) , var(16) ]
+                D[16,57] = var(61); // [ var(57) , var(16) ]
+                D[17,20] = var(37); // [ var(20) , var(17) ]
+                D[17,23] = var(40); // [ var(23) , var(17) ]
+                D[17,30] = var(45); // [ var(30) , var(17) ]
+                D[17,33] = (-1)*var(46); // [ var(33) , var(17) ]
+                D[17,38] = (-1)*var(50); // [ var(38) , var(17) ]
+                D[17,39] = (-1)*var(51); // [ var(39) , var(17) ]
+                D[17,44] = (-1)*var(54); // [ var(44) , var(17) ]
+                D[17,52] = var(59); // [ var(52) , var(17) ]
+                D[17,58] = (-1)*var(62); // [ var(58) , var(17) ]
+                D[18,20] = var(38); // [ var(20) , var(18) ]
+                D[18,22] = var(40); // [ var(22) , var(18) ]
+                D[18,26] = var(43); // [ var(26) , var(18) ]
+                D[18,36] = (-1)*var(49); // [ var(36) , var(18) ]
+                D[18,37] = (-1)*var(50); // [ var(37) , var(18) ]
+                D[18,39] = (-1)*var(52); // [ var(39) , var(18) ]
+                D[18,47] = var(57); // [ var(47) , var(18) ]
+                D[18,51] = var(59); // [ var(51) , var(18) ]
+                D[18,56] = (-1)*var(61); // [ var(56) , var(18) ]
+                D[19,20] = (-1)*var(39); // [ var(20) , var(19) ]
+                D[19,28] = var(45); // [ var(28) , var(19) ]
+                D[19,32] = var(48); // [ var(32) , var(19) ]
+                D[19,35] = var(49); // [ var(35) , var(19) ]
+                D[19,37] = var(51); // [ var(37) , var(19) ]
+                D[19,38] = var(52); // [ var(38) , var(19) ]
+                D[19,42] = var(55); // [ var(42) , var(19) ]
+                D[19,50] = (-1)*var(59); // [ var(50) , var(19) ]
+                D[19,53] = (-1)*var(60); // [ var(53) , var(19) ]
+                D[20,24] = (-1)*var(42); // [ var(24) , var(20) ]
+                D[20,25] = (-1)*var(44); // [ var(25) , var(20) ]
+                D[20,31] = (-1)*var(47); // [ var(31) , var(20) ]
+                D[20,40] = var(53); // [ var(40) , var(20) ]
+                D[20,45] = var(56); // [ var(45) , var(20) ]
+                D[20,49] = var(58); // [ var(49) , var(20) ]
+                D[20,59] = (-1)*var(63); // [ var(59) , var(20) ]
+                D[21,23] = var(43); // [ var(23) , var(21) ]
+                D[21,29] = var(46); // [ var(29) , var(21) ]
+                D[21,30] = var(48); // [ var(30) , var(21) ]
+                D[21,35] = var(50); // [ var(35) , var(21) ]
+                D[21,36] = var(51); // [ var(36) , var(21) ]
+                D[21,41] = var(54); // [ var(41) , var(21) ]
+                D[21,49] = (-1)*var(59); // [ var(49) , var(21) ]
+                D[21,58] = var(63); // [ var(58) , var(21) ]
+                D[22,25] = (-1)*var(45); // [ var(25) , var(22) ]
+                D[22,27] = var(46); // [ var(27) , var(22) ]
+                D[22,34] = var(51); // [ var(34) , var(22) ]
+                D[22,38] = var(53); // [ var(38) , var(22) ]
+                D[22,44] = var(56); // [ var(44) , var(22) ]
+                D[22,52] = (-1)*var(60); // [ var(52) , var(22) ]
+                D[22,57] = (-1)*var(62); // [ var(57) , var(22) ]
+                D[23,31] = var(49); // [ var(31) , var(23) ]
+                D[23,34] = var(52); // [ var(34) , var(23) ]
+                D[23,37] = var(53); // [ var(37) , var(23) ]
+                D[23,47] = (-1)*var(58); // [ var(47) , var(23) ]
+                D[23,51] = (-1)*var(60); // [ var(51) , var(23) ]
+                D[23,54] = (-1)*var(61); // [ var(54) , var(23) ]
+                D[24,26] = var(46); // [ var(26) , var(24) ]
+                D[24,30] = var(49); // [ var(30) , var(24) ]
+                D[24,32] = var(50); // [ var(32) , var(24) ]
+                D[24,39] = (-1)*var(55); // [ var(39) , var(24) ]
+                D[24,44] = (-1)*var(57); // [ var(44) , var(24) ]
+                D[24,48] = (-1)*var(59); // [ var(48) , var(24) ]
+                D[24,56] = var(62); // [ var(56) , var(24) ]
+                D[25,26] = var(48); // [ var(26) , var(25) ]
+                D[25,29] = var(49); // [ var(29) , var(25) ]
+                D[25,33] = var(52); // [ var(33) , var(25) ]
+                D[25,37] = (-1)*var(54); // [ var(37) , var(25) ]
+                D[25,42] = (-1)*var(57); // [ var(42) , var(25) ]
+                D[25,46] = (-1)*var(59); // [ var(46) , var(25) ]
+                D[25,53] = var(61); // [ var(53) , var(25) ]
+                D[26,31] = (-1)*var(51); // [ var(31) , var(26) ]
+                D[26,35] = (-1)*var(53); // [ var(35) , var(26) ]
+                D[26,41] = (-1)*var(56); // [ var(41) , var(26) ]
+                D[26,49] = var(60); // [ var(49) , var(26) ]
+                D[26,57] = var(63); // [ var(57) , var(26) ]
+                D[27,28] = (-1)*var(50); // [ var(28) , var(27) ]
+                D[27,30] = var(52); // [ var(30) , var(27) ]
+                D[27,36] = var(55); // [ var(36) , var(27) ]
+                D[27,41] = var(57); // [ var(41) , var(27) ]
+                D[27,45] = var(59); // [ var(45) , var(27) ]
+                D[27,56] = (-1)*var(63); // [ var(56) , var(27) ]
+                D[28,33] = (-1)*var(53); // [ var(33) , var(28) ]
+                D[28,34] = var(54); // [ var(34) , var(28) ]
+                D[28,39] = (-1)*var(56); // [ var(39) , var(28) ]
+                D[28,52] = (-1)*var(61); // [ var(52) , var(28) ]
+                D[28,55] = var(62); // [ var(55) , var(28) ]
+                D[29,32] = (-1)*var(53); // [ var(32) , var(29) ]
+                D[29,34] = var(55); // [ var(34) , var(29) ]
+                D[29,44] = var(58); // [ var(44) , var(29) ]
+                D[29,48] = var(60); // [ var(48) , var(29) ]
+                D[29,54] = var(62); // [ var(54) , var(29) ]
+                D[30,37] = var(56); // [ var(37) , var(30) ]
+                D[30,42] = var(58); // [ var(42) , var(30) ]
+                D[30,46] = var(60); // [ var(46) , var(30) ]
+                D[30,50] = var(61); // [ var(50) , var(30) ]
+                D[31,32] = var(54); // [ var(32) , var(31) ]
+                D[31,33] = var(55); // [ var(33) , var(31) ]
+                D[31,38] = var(57); // [ var(38) , var(31) ]
+                D[31,43] = var(59); // [ var(43) , var(31) ]
+                D[31,53] = (-1)*var(62); // [ var(53) , var(31) ]
+                D[32,36] = var(56); // [ var(36) , var(32) ]
+                D[32,49] = var(61); // [ var(49) , var(32) ]
+                D[32,55] = (-1)*var(63); // [ var(55) , var(32) ]
+                D[33,41] = (-1)*var(58); // [ var(41) , var(33) ]
+                D[33,45] = (-1)*var(60); // [ var(45) , var(33) ]
+                D[33,54] = (-1)*var(63); // [ var(54) , var(33) ]
+                D[34,35] = (-1)*var(57); // [ var(35) , var(34) ]
+                D[34,40] = (-1)*var(59); // [ var(40) , var(34) ]
+                D[34,53] = var(63); // [ var(53) , var(34) ]
+                D[35,39] = (-1)*var(58); // [ var(39) , var(35) ]
+                D[35,48] = var(61); // [ var(48) , var(35) ]
+                D[35,51] = (-1)*var(62); // [ var(51) , var(35) ]
+                D[36,38] = (-1)*var(58); // [ var(38) , var(36) ]
+                D[36,43] = (-1)*var(60); // [ var(43) , var(36) ]
+                D[36,50] = (-1)*var(62); // [ var(50) , var(36) ]
+                D[37,49] = (-1)*var(62); // [ var(49) , var(37) ]
+                D[37,52] = var(63); // [ var(52) , var(37) ]
+                D[38,45] = (-1)*var(61); // [ var(45) , var(38) ]
+                D[38,51] = var(63); // [ var(51) , var(38) ]
+                D[39,40] = var(60); // [ var(40) , var(39) ]
+                D[39,50] = var(63); // [ var(50) , var(39) ]
+                D[40,44] = (-1)*var(61); // [ var(44) , var(40) ]
+                D[40,47] = var(62); // [ var(47) , var(40) ]
+                D[41,43] = (-1)*var(61); // [ var(43) , var(41) ]
+                D[41,46] = var(62); // [ var(46) , var(41) ]
+                D[42,45] = var(62); // [ var(45) , var(42) ]
+                D[42,48] = (-1)*var(63); // [ var(48) , var(42) ]
+                D[43,47] = (-1)*var(63); // [ var(47) , var(43) ]
+                D[44,46] = (-1)*var(63); // [ var(46) , var(44) ]
+        // Y(i) * Y(j):
+                D[64,66] = (-1)*var(71); // [ var(66) , var(64) ]
+                D[64,73] = (-1)*var(77); // [ var(73) , var(64) ]
+                D[64,78] = (-1)*var(83); // [ var(78) , var(64) ]
+                D[64,80] = (-1)*var(84); // [ var(80) , var(64) ]
+                D[64,85] = (-1)*var(89); // [ var(85) , var(64) ]
+                D[64,87] = (-1)*var(90); // [ var(87) , var(64) ]
+                D[64,91] = (-1)*var(95); // [ var(91) , var(64) ]
+                D[64,92] = (-1)*var(96); // [ var(92) , var(64) ]
+                D[64,94] = (-1)*var(97); // [ var(94) , var(64) ]
+                D[64,98] = (-1)*var(101); // [ var(98) , var(64) ]
+                D[64,99] = (-1)*var(102); // [ var(99) , var(64) ]
+                D[64,103] = (-1)*var(106); // [ var(103) , var(64) ]
+                D[64,104] = (-1)*var(107); // [ var(104) , var(64) ]
+                D[64,108] = (-1)*var(111); // [ var(108) , var(64) ]
+                D[64,112] = (-1)*var(115); // [ var(112) , var(64) ]
+                D[64,125] = var(126); // [ var(125) , var(64) ]
+                D[65,67] = (-1)*var(72); // [ var(67) , var(65) ]
+                D[65,73] = (-1)*var(78); // [ var(73) , var(65) ]
+                D[65,74] = (-1)*var(79); // [ var(74) , var(65) ]
+                D[65,77] = (-1)*var(83); // [ var(77) , var(65) ]
+                D[65,80] = (-1)*var(85); // [ var(80) , var(65) ]
+                D[65,81] = (-1)*var(86); // [ var(81) , var(65) ]
+                D[65,84] = (-1)*var(89); // [ var(84) , var(65) ]
+                D[65,87] = (-1)*var(92); // [ var(87) , var(65) ]
+                D[65,88] = (-1)*var(93); // [ var(88) , var(65) ]
+                D[65,90] = (-1)*var(96); // [ var(90) , var(65) ]
+                D[65,94] = (-1)*var(99); // [ var(94) , var(65) ]
+                D[65,97] = (-1)*var(102); // [ var(97) , var(65) ]
+                D[65,113] = var(116); // [ var(113) , var(65) ]
+                D[65,117] = var(119); // [ var(117) , var(65) ]
+                D[65,120] = var(121); // [ var(120) , var(65) ]
+                D[65,122] = var(123); // [ var(122) , var(65) ]
+                D[66,67] = (-1)*var(73); // [ var(67) , var(66) ]
+                D[66,72] = (-1)*var(78); // [ var(72) , var(66) ]
+                D[66,74] = (-1)*var(80); // [ var(74) , var(66) ]
+                D[66,79] = (-1)*var(85); // [ var(79) , var(66) ]
+                D[66,81] = (-1)*var(87); // [ var(81) , var(66) ]
+                D[66,86] = (-1)*var(92); // [ var(86) , var(66) ]
+                D[66,88] = (-1)*var(94); // [ var(88) , var(66) ]
+                D[66,93] = (-1)*var(99); // [ var(93) , var(66) ]
+                D[66,95] = (-1)*var(100); // [ var(95) , var(66) ]
+                D[66,101] = (-1)*var(105); // [ var(101) , var(66) ]
+                D[66,106] = (-1)*var(109); // [ var(106) , var(66) ]
+                D[66,107] = (-1)*var(110); // [ var(107) , var(66) ]
+                D[66,111] = (-1)*var(114); // [ var(111) , var(66) ]
+                D[66,115] = (-1)*var(118); // [ var(115) , var(66) ]
+                D[66,124] = var(125); // [ var(124) , var(66) ]
+                D[67,68] = (-1)*var(74); // [ var(68) , var(67) ]
+                D[67,71] = var(77); // [ var(71) , var(67) ]
+                D[67,75] = (-1)*var(81); // [ var(75) , var(67) ]
+                D[67,82] = (-1)*var(88); // [ var(82) , var(67) ]
+                D[67,85] = var(91); // [ var(85) , var(67) ]
+                D[67,89] = var(95); // [ var(89) , var(67) ]
+                D[67,92] = var(98); // [ var(92) , var(67) ]
+                D[67,96] = var(101); // [ var(96) , var(67) ]
+                D[67,99] = var(104); // [ var(99) , var(67) ]
+                D[67,102] = var(107); // [ var(102) , var(67) ]
+                D[67,109] = var(113); // [ var(109) , var(67) ]
+                D[67,114] = var(117); // [ var(114) , var(67) ]
+                D[67,118] = var(120); // [ var(118) , var(67) ]
+                D[67,123] = var(124); // [ var(123) , var(67) ]
+                D[68,69] = (-1)*var(75); // [ var(69) , var(68) ]
+                D[68,72] = var(79); // [ var(72) , var(68) ]
+                D[68,73] = var(80); // [ var(73) , var(68) ]
+                D[68,76] = (-1)*var(82); // [ var(76) , var(68) ]
+                D[68,77] = var(84); // [ var(77) , var(68) ]
+                D[68,78] = var(85); // [ var(78) , var(68) ]
+                D[68,83] = var(89); // [ var(83) , var(68) ]
+                D[68,98] = var(103); // [ var(98) , var(68) ]
+                D[68,101] = var(106); // [ var(101) , var(68) ]
+                D[68,104] = var(108); // [ var(104) , var(68) ]
+                D[68,105] = var(109); // [ var(105) , var(68) ]
+                D[68,107] = var(111); // [ var(107) , var(68) ]
+                D[68,110] = var(114); // [ var(110) , var(68) ]
+                D[68,120] = var(122); // [ var(120) , var(68) ]
+                D[68,121] = var(123); // [ var(121) , var(68) ]
+                D[69,70] = (-1)*var(76); // [ var(70) , var(69) ]
+                D[69,74] = var(81); // [ var(74) , var(69) ]
+                D[69,79] = var(86); // [ var(79) , var(69) ]
+                D[69,80] = var(87); // [ var(80) , var(69) ]
+                D[69,84] = var(90); // [ var(84) , var(69) ]
+                D[69,85] = var(92); // [ var(85) , var(69) ]
+                D[69,89] = var(96); // [ var(89) , var(69) ]
+                D[69,91] = var(98); // [ var(91) , var(69) ]
+                D[69,95] = var(101); // [ var(95) , var(69) ]
+                D[69,100] = var(105); // [ var(100) , var(69) ]
+                D[69,108] = var(112); // [ var(108) , var(69) ]
+                D[69,111] = var(115); // [ var(111) , var(69) ]
+                D[69,114] = var(118); // [ var(114) , var(69) ]
+                D[69,117] = var(120); // [ var(117) , var(69) ]
+                D[69,119] = var(121); // [ var(119) , var(69) ]
+                D[70,75] = var(82); // [ var(75) , var(70) ]
+                D[70,81] = var(88); // [ var(81) , var(70) ]
+                D[70,86] = var(93); // [ var(86) , var(70) ]
+                D[70,87] = var(94); // [ var(87) , var(70) ]
+                D[70,90] = var(97); // [ var(90) , var(70) ]
+                D[70,92] = var(99); // [ var(92) , var(70) ]
+                D[70,96] = var(102); // [ var(96) , var(70) ]
+                D[70,98] = var(104); // [ var(98) , var(70) ]
+                D[70,101] = var(107); // [ var(101) , var(70) ]
+                D[70,103] = var(108); // [ var(103) , var(70) ]
+                D[70,105] = var(110); // [ var(105) , var(70) ]
+                D[70,106] = var(111); // [ var(106) , var(70) ]
+                D[70,109] = var(114); // [ var(109) , var(70) ]
+                D[70,113] = var(117); // [ var(113) , var(70) ]
+                D[70,116] = var(119); // [ var(116) , var(70) ]
+                D[71,72] = (-1)*var(83); // [ var(72) , var(71) ]
+                D[71,74] = (-1)*var(84); // [ var(74) , var(71) ]
+                D[71,79] = (-1)*var(89); // [ var(79) , var(71) ]
+                D[71,81] = (-1)*var(90); // [ var(81) , var(71) ]
+                D[71,86] = (-1)*var(96); // [ var(86) , var(71) ]
+                D[71,88] = (-1)*var(97); // [ var(88) , var(71) ]
+                D[71,91] = var(100); // [ var(91) , var(71) ]
+                D[71,93] = (-1)*var(102); // [ var(93) , var(71) ]
+                D[71,98] = var(105); // [ var(98) , var(71) ]
+                D[71,103] = var(109); // [ var(103) , var(71) ]
+                D[71,104] = var(110); // [ var(104) , var(71) ]
+                D[71,108] = var(114); // [ var(108) , var(71) ]
+                D[71,112] = var(118); // [ var(112) , var(71) ]
+                D[71,124] = (-1)*var(126); // [ var(124) , var(71) ]
+                D[72,75] = (-1)*var(86); // [ var(75) , var(72) ]
+                D[72,80] = (-1)*var(91); // [ var(80) , var(72) ]
+                D[72,82] = (-1)*var(93); // [ var(82) , var(72) ]
+                D[72,84] = (-1)*var(95); // [ var(84) , var(72) ]
+                D[72,87] = (-1)*var(98); // [ var(87) , var(72) ]
+                D[72,90] = (-1)*var(101); // [ var(90) , var(72) ]
+                D[72,94] = (-1)*var(104); // [ var(94) , var(72) ]
+                D[72,97] = (-1)*var(107); // [ var(97) , var(72) ]
+                D[72,109] = (-1)*var(116); // [ var(109) , var(72) ]
+                D[72,114] = (-1)*var(119); // [ var(114) , var(72) ]
+                D[72,118] = (-1)*var(121); // [ var(118) , var(72) ]
+                D[72,122] = var(124); // [ var(122) , var(72) ]
+                D[73,75] = (-1)*var(87); // [ var(75) , var(73) ]
+                D[73,79] = (-1)*var(91); // [ var(79) , var(73) ]
+                D[73,82] = (-1)*var(94); // [ var(82) , var(73) ]
+                D[73,86] = (-1)*var(98); // [ var(86) , var(73) ]
+                D[73,89] = var(100); // [ var(89) , var(73) ]
+                D[73,93] = (-1)*var(104); // [ var(93) , var(73) ]
+                D[73,96] = var(105); // [ var(96) , var(73) ]
+                D[73,102] = var(110); // [ var(102) , var(73) ]
+                D[73,106] = (-1)*var(113); // [ var(106) , var(73) ]
+                D[73,111] = (-1)*var(117); // [ var(111) , var(73) ]
+                D[73,115] = (-1)*var(120); // [ var(115) , var(73) ]
+                D[73,123] = (-1)*var(125); // [ var(123) , var(73) ]
+                D[74,76] = (-1)*var(88); // [ var(76) , var(74) ]
+                D[74,78] = (-1)*var(91); // [ var(78) , var(74) ]
+                D[74,83] = (-1)*var(95); // [ var(83) , var(74) ]
+                D[74,92] = var(103); // [ var(92) , var(74) ]
+                D[74,96] = var(106); // [ var(96) , var(74) ]
+                D[74,99] = var(108); // [ var(99) , var(74) ]
+                D[74,102] = var(111); // [ var(102) , var(74) ]
+                D[74,105] = (-1)*var(113); // [ var(105) , var(74) ]
+                D[74,110] = (-1)*var(117); // [ var(110) , var(74) ]
+                D[74,118] = var(122); // [ var(118) , var(74) ]
+                D[74,121] = (-1)*var(124); // [ var(121) , var(74) ]
+                D[75,77] = var(90); // [ var(77) , var(75) ]
+                D[75,78] = var(92); // [ var(78) , var(75) ]
+                D[75,83] = var(96); // [ var(83) , var(75) ]
+                D[75,91] = (-1)*var(103); // [ var(91) , var(75) ]
+                D[75,95] = (-1)*var(106); // [ var(95) , var(75) ]
+                D[75,100] = (-1)*var(109); // [ var(100) , var(75) ]
+                D[75,104] = var(112); // [ var(104) , var(75) ]
+                D[75,107] = var(115); // [ var(107) , var(75) ]
+                D[75,110] = var(118); // [ var(110) , var(75) ]
+                D[75,117] = (-1)*var(122); // [ var(117) , var(75) ]
+                D[75,119] = (-1)*var(123); // [ var(119) , var(75) ]
+                D[76,79] = var(93); // [ var(79) , var(76) ]
+                D[76,80] = var(94); // [ var(80) , var(76) ]
+                D[76,84] = var(97); // [ var(84) , var(76) ]
+                D[76,85] = var(99); // [ var(85) , var(76) ]
+                D[76,89] = var(102); // [ var(89) , var(76) ]
+                D[76,91] = var(104); // [ var(91) , var(76) ]
+                D[76,95] = var(107); // [ var(95) , var(76) ]
+                D[76,100] = var(110); // [ var(100) , var(76) ]
+                D[76,103] = (-1)*var(112); // [ var(103) , var(76) ]
+                D[76,106] = (-1)*var(115); // [ var(106) , var(76) ]
+                D[76,109] = (-1)*var(118); // [ var(109) , var(76) ]
+                D[76,113] = (-1)*var(120); // [ var(113) , var(76) ]
+                D[76,116] = (-1)*var(121); // [ var(116) , var(76) ]
+                D[77,79] = (-1)*var(95); // [ var(79) , var(77) ]
+                D[77,82] = (-1)*var(97); // [ var(82) , var(77) ]
+                D[77,85] = (-1)*var(100); // [ var(85) , var(77) ]
+                D[77,86] = (-1)*var(101); // [ var(86) , var(77) ]
+                D[77,92] = (-1)*var(105); // [ var(92) , var(77) ]
+                D[77,93] = (-1)*var(107); // [ var(93) , var(77) ]
+                D[77,99] = (-1)*var(110); // [ var(99) , var(77) ]
+                D[77,103] = var(113); // [ var(103) , var(77) ]
+                D[77,108] = var(117); // [ var(108) , var(77) ]
+                D[77,112] = var(120); // [ var(112) , var(77) ]
+                D[77,123] = var(126); // [ var(123) , var(77) ]
+                D[78,81] = var(98); // [ var(81) , var(78) ]
+                D[78,82] = (-1)*var(99); // [ var(82) , var(78) ]
+                D[78,84] = (-1)*var(100); // [ var(84) , var(78) ]
+                D[78,88] = var(104); // [ var(88) , var(78) ]
+                D[78,90] = (-1)*var(105); // [ var(90) , var(78) ]
+                D[78,97] = (-1)*var(110); // [ var(97) , var(78) ]
+                D[78,106] = var(116); // [ var(106) , var(78) ]
+                D[78,111] = var(119); // [ var(111) , var(78) ]
+                D[78,115] = var(121); // [ var(115) , var(78) ]
+                D[78,122] = (-1)*var(125); // [ var(122) , var(78) ]
+                D[79,87] = (-1)*var(103); // [ var(87) , var(79) ]
+                D[79,90] = (-1)*var(106); // [ var(90) , var(79) ]
+                D[79,94] = (-1)*var(108); // [ var(94) , var(79) ]
+                D[79,97] = (-1)*var(111); // [ var(97) , var(79) ]
+                D[79,105] = var(116); // [ var(105) , var(79) ]
+                D[79,110] = var(119); // [ var(110) , var(79) ]
+                D[79,118] = (-1)*var(123); // [ var(118) , var(79) ]
+                D[79,120] = (-1)*var(124); // [ var(120) , var(79) ]
+                D[80,83] = (-1)*var(100); // [ var(83) , var(80) ]
+                D[80,86] = (-1)*var(103); // [ var(86) , var(80) ]
+                D[80,93] = (-1)*var(108); // [ var(93) , var(80) ]
+                D[80,96] = var(109); // [ var(96) , var(80) ]
+                D[80,101] = var(113); // [ var(101) , var(80) ]
+                D[80,102] = var(114); // [ var(102) , var(80) ]
+                D[80,107] = var(117); // [ var(107) , var(80) ]
+                D[80,115] = (-1)*var(122); // [ var(115) , var(80) ]
+                D[80,121] = var(125); // [ var(121) , var(80) ]
+                D[81,83] = (-1)*var(101); // [ var(83) , var(81) ]
+                D[81,85] = (-1)*var(103); // [ var(85) , var(81) ]
+                D[81,89] = (-1)*var(106); // [ var(89) , var(81) ]
+                D[81,99] = var(112); // [ var(99) , var(81) ]
+                D[81,100] = var(113); // [ var(100) , var(81) ]
+                D[81,102] = var(115); // [ var(102) , var(81) ]
+                D[81,110] = (-1)*var(120); // [ var(110) , var(81) ]
+                D[81,114] = (-1)*var(122); // [ var(114) , var(81) ]
+                D[81,119] = var(124); // [ var(119) , var(81) ]
+                D[82,83] = var(102); // [ var(83) , var(82) ]
+                D[82,91] = (-1)*var(108); // [ var(91) , var(82) ]
+                D[82,95] = (-1)*var(111); // [ var(95) , var(82) ]
+                D[82,98] = (-1)*var(112); // [ var(98) , var(82) ]
+                D[82,100] = (-1)*var(114); // [ var(100) , var(82) ]
+                D[82,101] = (-1)*var(115); // [ var(101) , var(82) ]
+                D[82,105] = (-1)*var(118); // [ var(105) , var(82) ]
+                D[82,113] = var(122); // [ var(113) , var(82) ]
+                D[82,116] = var(123); // [ var(116) , var(82) ]
+                D[83,87] = var(105); // [ var(87) , var(83) ]
+                D[83,88] = var(107); // [ var(88) , var(83) ]
+                D[83,94] = var(110); // [ var(94) , var(83) ]
+                D[83,103] = (-1)*var(116); // [ var(103) , var(83) ]
+                D[83,108] = (-1)*var(119); // [ var(108) , var(83) ]
+                D[83,112] = (-1)*var(121); // [ var(112) , var(83) ]
+                D[83,122] = var(126); // [ var(122) , var(83) ]
+                D[84,86] = (-1)*var(106); // [ var(86) , var(84) ]
+                D[84,92] = (-1)*var(109); // [ var(92) , var(84) ]
+                D[84,93] = (-1)*var(111); // [ var(93) , var(84) ]
+                D[84,98] = (-1)*var(113); // [ var(98) , var(84) ]
+                D[84,99] = (-1)*var(114); // [ var(99) , var(84) ]
+                D[84,104] = (-1)*var(117); // [ var(104) , var(84) ]
+                D[84,112] = var(122); // [ var(112) , var(84) ]
+                D[84,121] = (-1)*var(126); // [ var(121) , var(84) ]
+                D[85,88] = var(108); // [ var(88) , var(85) ]
+                D[85,90] = (-1)*var(109); // [ var(90) , var(85) ]
+                D[85,97] = (-1)*var(114); // [ var(97) , var(85) ]
+                D[85,101] = (-1)*var(116); // [ var(101) , var(85) ]
+                D[85,107] = (-1)*var(119); // [ var(107) , var(85) ]
+                D[85,115] = var(123); // [ var(115) , var(85) ]
+                D[85,120] = var(125); // [ var(120) , var(85) ]
+                D[86,94] = (-1)*var(112); // [ var(94) , var(86) ]
+                D[86,97] = (-1)*var(115); // [ var(97) , var(86) ]
+                D[86,100] = (-1)*var(116); // [ var(100) , var(86) ]
+                D[86,110] = var(121); // [ var(110) , var(86) ]
+                D[86,114] = var(123); // [ var(114) , var(86) ]
+                D[86,117] = var(124); // [ var(117) , var(86) ]
+                D[87,89] = (-1)*var(109); // [ var(89) , var(87) ]
+                D[87,93] = (-1)*var(112); // [ var(93) , var(87) ]
+                D[87,95] = (-1)*var(113); // [ var(95) , var(87) ]
+                D[87,102] = var(118); // [ var(102) , var(87) ]
+                D[87,107] = var(120); // [ var(107) , var(87) ]
+                D[87,111] = var(122); // [ var(111) , var(87) ]
+                D[87,119] = (-1)*var(125); // [ var(119) , var(87) ]
+                D[88,89] = (-1)*var(111); // [ var(89) , var(88) ]
+                D[88,92] = (-1)*var(112); // [ var(92) , var(88) ]
+                D[88,96] = (-1)*var(115); // [ var(96) , var(88) ]
+                D[88,100] = var(117); // [ var(100) , var(88) ]
+                D[88,105] = var(120); // [ var(105) , var(88) ]
+                D[88,109] = var(122); // [ var(109) , var(88) ]
+                D[88,116] = (-1)*var(124); // [ var(116) , var(88) ]
+                D[89,94] = var(114); // [ var(94) , var(89) ]
+                D[89,98] = var(116); // [ var(98) , var(89) ]
+                D[89,104] = var(119); // [ var(104) , var(89) ]
+                D[89,112] = (-1)*var(123); // [ var(112) , var(89) ]
+                D[89,120] = (-1)*var(126); // [ var(120) , var(89) ]
+                D[90,91] = var(113); // [ var(91) , var(90) ]
+                D[90,93] = (-1)*var(115); // [ var(93) , var(90) ]
+                D[90,99] = (-1)*var(118); // [ var(99) , var(90) ]
+                D[90,104] = (-1)*var(120); // [ var(104) , var(90) ]
+                D[90,108] = (-1)*var(122); // [ var(108) , var(90) ]
+                D[90,119] = var(126); // [ var(119) , var(90) ]
+                D[91,96] = var(116); // [ var(96) , var(91) ]
+                D[91,97] = (-1)*var(117); // [ var(97) , var(91) ]
+                D[91,102] = var(119); // [ var(102) , var(91) ]
+                D[91,115] = var(124); // [ var(115) , var(91) ]
+                D[91,118] = (-1)*var(125); // [ var(118) , var(91) ]
+                D[92,95] = var(116); // [ var(95) , var(92) ]
+                D[92,97] = (-1)*var(118); // [ var(97) , var(92) ]
+                D[92,107] = (-1)*var(121); // [ var(107) , var(92) ]
+                D[92,111] = (-1)*var(123); // [ var(111) , var(92) ]
+                D[92,117] = (-1)*var(125); // [ var(117) , var(92) ]
+                D[93,100] = (-1)*var(119); // [ var(100) , var(93) ]
+                D[93,105] = (-1)*var(121); // [ var(105) , var(93) ]
+                D[93,109] = (-1)*var(123); // [ var(109) , var(93) ]
+                D[93,113] = (-1)*var(124); // [ var(113) , var(93) ]
+                D[94,95] = (-1)*var(117); // [ var(95) , var(94) ]
+                D[94,96] = (-1)*var(118); // [ var(96) , var(94) ]
+                D[94,101] = (-1)*var(120); // [ var(101) , var(94) ]
+                D[94,106] = (-1)*var(122); // [ var(106) , var(94) ]
+                D[94,116] = var(125); // [ var(116) , var(94) ]
+                D[95,99] = (-1)*var(119); // [ var(99) , var(95) ]
+                D[95,112] = (-1)*var(124); // [ var(112) , var(95) ]
+                D[95,118] = var(126); // [ var(118) , var(95) ]
+                D[96,104] = var(121); // [ var(104) , var(96) ]
+                D[96,108] = var(123); // [ var(108) , var(96) ]
+                D[96,117] = var(126); // [ var(117) , var(96) ]
+                D[97,98] = var(120); // [ var(98) , var(97) ]
+                D[97,103] = var(122); // [ var(103) , var(97) ]
+                D[97,116] = (-1)*var(126); // [ var(116) , var(97) ]
+                D[98,102] = var(121); // [ var(102) , var(98) ]
+                D[98,111] = (-1)*var(124); // [ var(111) , var(98) ]
+                D[98,114] = var(125); // [ var(114) , var(98) ]
+                D[99,101] = var(121); // [ var(101) , var(99) ]
+                D[99,106] = var(123); // [ var(106) , var(99) ]
+                D[99,113] = var(125); // [ var(113) , var(99) ]
+                D[100,112] = var(125); // [ var(112) , var(100) ]
+                D[100,115] = (-1)*var(126); // [ var(115) , var(100) ]
+                D[101,108] = var(124); // [ var(108) , var(101) ]
+                D[101,114] = (-1)*var(126); // [ var(114) , var(101) ]
+                D[102,103] = (-1)*var(123); // [ var(103) , var(102) ]
+                D[102,113] = (-1)*var(126); // [ var(113) , var(102) ]
+                D[103,107] = var(124); // [ var(107) , var(103) ]
+                D[103,110] = (-1)*var(125); // [ var(110) , var(103) ]
+                D[104,106] = var(124); // [ var(106) , var(104) ]
+                D[104,109] = (-1)*var(125); // [ var(109) , var(104) ]
+                D[105,108] = (-1)*var(125); // [ var(108) , var(105) ]
+                D[105,111] = var(126); // [ var(111) , var(105) ]
+                D[106,110] = var(126); // [ var(110) , var(106) ]
+                D[107,109] = var(126); // [ var(109) , var(107) ]
+   def @@RR=nc_algebra(1,D);
+   return(@@RR);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   def ncAlgebra = makeUe7();
+   ncAlgebra;
+   setring ncAlgebra;
+   // ...  2541  noncommutative relations
+}
+////////////////////////////////////////////////////////////////////
+
+// Algebra: e8(Q) has the type: E8, and defined by:
+
+proc makeUe8(list #)
+"USAGE:   makeUe8([p]); p an optional integer (field characteristic)
+RETURN:  a ring, describing U(e_8)
+NOTE:    You have to activate this ring with the 'setring' command. The presentation of U(e_8) is derived from the Chevalley representation of e_8, positive resp. negative roots are denoted by x(i) resp. y(i); Cartan elements are denoted by h(i).
+SEE ALSO: makeUsl, makeUso5, makeUsp1, makeUe6, makeUe7, makeUe8, makeUg2, makeUf4
+EXAMPLE: example makeUe8; shows examples
+"
+{
+   int @p = defInt(#);
+
+   ring @@@rrr = @p,(X(1..120),Y(1..120),H(1..8)),dp;
+   int N = nvars(@@@rrr);
+   matrix D[N][N]=0;
+
+        // H(i) * X(j):
+                D[1,241] = (2)*var(1); // [ var(241) , var(1) ]
+                D[3,241] = (-1)*var(3); // [ var(241) , var(3) ]
+                D[9,241] = var(9); // [ var(241) , var(9) ]
+                D[11,241] = (-1)*var(11); // [ var(241) , var(11) ]
+                D[16,241] = var(16); // [ var(241) , var(16) ]
+                D[17,241] = (-1)*var(17); // [ var(241) , var(17) ]
+                D[19,241] = (-1)*var(19); // [ var(241) , var(19) ]
+                D[23,241] = var(23); // [ var(241) , var(23) ]
+                D[24,241] = var(24); // [ var(241) , var(24) ]
+                D[25,241] = (-1)*var(25); // [ var(241) , var(25) ]
+                D[27,241] = (-1)*var(27); // [ var(241) , var(27) ]
+                D[30,241] = var(30); // [ var(241) , var(30) ]
+                D[31,241] = var(31); // [ var(241) , var(31) ]
+                D[32,241] = (-1)*var(32); // [ var(241) , var(32) ]
+                D[33,241] = (-1)*var(33); // [ var(241) , var(33) ]
+                D[35,241] = (-1)*var(35); // [ var(241) , var(35) ]
+                D[37,241] = var(37); // [ var(241) , var(37) ]
+                D[38,241] = var(38); // [ var(241) , var(38) ]
+                D[39,241] = var(39); // [ var(241) , var(39) ]
+                D[40,241] = (-1)*var(40); // [ var(241) , var(40) ]
+                D[41,241] = (-1)*var(41); // [ var(241) , var(41) ]
+                D[43,241] = (-1)*var(43); // [ var(241) , var(43) ]
+                D[45,241] = var(45); // [ var(241) , var(45) ]
+                D[46,241] = var(46); // [ var(241) , var(46) ]
+                D[47,241] = var(47); // [ var(241) , var(47) ]
+                D[48,241] = (-1)*var(48); // [ var(241) , var(48) ]
+                D[49,241] = (-1)*var(49); // [ var(241) , var(49) ]
+                D[50,241] = (-1)*var(50); // [ var(241) , var(50) ]
+                D[52,241] = var(52); // [ var(241) , var(52) ]
+                D[53,241] = var(53); // [ var(241) , var(53) ]
+                D[54,241] = var(54); // [ var(241) , var(54) ]
+                D[55,241] = (-1)*var(55); // [ var(241) , var(55) ]
+                D[56,241] = (-1)*var(56); // [ var(241) , var(56) ]
+                D[59,241] = var(59); // [ var(241) , var(59) ]
+                D[60,241] = var(60); // [ var(241) , var(60) ]
+                D[61,241] = (-1)*var(61); // [ var(241) , var(61) ]
+                D[62,241] = (-1)*var(62); // [ var(241) , var(62) ]
+                D[66,241] = var(66); // [ var(241) , var(66) ]
+                D[67,241] = var(67); // [ var(241) , var(67) ]
+                D[68,241] = (-1)*var(68); // [ var(241) , var(68) ]
+                D[73,241] = var(73); // [ var(241) , var(73) ]
+                D[74,241] = (-1)*var(74); // [ var(241) , var(74) ]
+                D[79,241] = var(79); // [ var(241) , var(79) ]
+                D[93,241] = (-1)*var(93); // [ var(241) , var(93) ]
+                D[97,241] = var(97); // [ var(241) , var(97) ]
+                D[98,241] = (-1)*var(98); // [ var(241) , var(98) ]
+                D[101,241] = var(101); // [ var(241) , var(101) ]
+                D[102,241] = (-1)*var(102); // [ var(241) , var(102) ]
+                D[104,241] = var(104); // [ var(241) , var(104) ]
+                D[105,241] = (-1)*var(105); // [ var(241) , var(105) ]
+                D[107,241] = var(107); // [ var(241) , var(107) ]
+                D[108,241] = (-1)*var(108); // [ var(241) , var(108) ]
+                D[109,241] = var(109); // [ var(241) , var(109) ]
+                D[110,241] = (-1)*var(110); // [ var(241) , var(110) ]
+                D[111,241] = var(111); // [ var(241) , var(111) ]
+                D[112,241] = (-1)*var(112); // [ var(241) , var(112) ]
+                D[113,241] = var(113); // [ var(241) , var(113) ]
+                D[2,242] = (2)*var(2); // [ var(242) , var(2) ]
+                D[4,242] = (-1)*var(4); // [ var(242) , var(4) ]
+                D[10,242] = var(10); // [ var(242) , var(10) ]
+                D[11,242] = (-1)*var(11); // [ var(242) , var(11) ]
+                D[12,242] = (-1)*var(12); // [ var(242) , var(12) ]
+                D[16,242] = (-1)*var(16); // [ var(242) , var(16) ]
+                D[17,242] = var(17); // [ var(242) , var(17) ]
+                D[18,242] = var(18); // [ var(242) , var(18) ]
+                D[19,242] = (-1)*var(19); // [ var(242) , var(19) ]
+                D[20,242] = (-1)*var(20); // [ var(242) , var(20) ]
+                D[23,242] = var(23); // [ var(242) , var(23) ]
+                D[24,242] = (-1)*var(24); // [ var(242) , var(24) ]
+                D[25,242] = var(25); // [ var(242) , var(25) ]
+                D[26,242] = var(26); // [ var(242) , var(26) ]
+                D[27,242] = (-1)*var(27); // [ var(242) , var(27) ]
+                D[28,242] = (-1)*var(28); // [ var(242) , var(28) ]
+                D[30,242] = var(30); // [ var(242) , var(30) ]
+                D[31,242] = (-1)*var(31); // [ var(242) , var(31) ]
+                D[33,242] = var(33); // [ var(242) , var(33) ]
+                D[34,242] = var(34); // [ var(242) , var(34) ]
+                D[35,242] = (-1)*var(35); // [ var(242) , var(35) ]
+                D[36,242] = (-1)*var(36); // [ var(242) , var(36) ]
+                D[38,242] = var(38); // [ var(242) , var(38) ]
+                D[39,242] = (-1)*var(39); // [ var(242) , var(39) ]
+                D[41,242] = var(41); // [ var(242) , var(41) ]
+                D[42,242] = var(42); // [ var(242) , var(42) ]
+                D[43,242] = (-1)*var(43); // [ var(242) , var(43) ]
+                D[46,242] = var(46); // [ var(242) , var(46) ]
+                D[47,242] = (-1)*var(47); // [ var(242) , var(47) ]
+                D[50,242] = var(50); // [ var(242) , var(50) ]
+                D[54,242] = var(54); // [ var(242) , var(54) ]
+                D[63,242] = (-1)*var(63); // [ var(242) , var(63) ]
+                D[69,242] = var(69); // [ var(242) , var(69) ]
+                D[70,242] = (-1)*var(70); // [ var(242) , var(70) ]
+                D[75,242] = var(75); // [ var(242) , var(75) ]
+                D[76,242] = (-1)*var(76); // [ var(242) , var(76) ]
+                D[77,242] = (-1)*var(77); // [ var(242) , var(77) ]
+                D[80,242] = var(80); // [ var(242) , var(80) ]
+                D[81,242] = var(81); // [ var(242) , var(81) ]
+                D[82,242] = (-1)*var(82); // [ var(242) , var(82) ]
+                D[83,242] = (-1)*var(83); // [ var(242) , var(83) ]
+                D[85,242] = var(85); // [ var(242) , var(85) ]
+                D[86,242] = var(86); // [ var(242) , var(86) ]
+                D[87,242] = (-1)*var(87); // [ var(242) , var(87) ]
+                D[88,242] = (-1)*var(88); // [ var(242) , var(88) ]
+                D[90,242] = var(90); // [ var(242) , var(90) ]
+                D[91,242] = var(91); // [ var(242) , var(91) ]
+                D[92,242] = (-1)*var(92); // [ var(242) , var(92) ]
+                D[95,242] = var(95); // [ var(242) , var(95) ]
+                D[96,242] = (-1)*var(96); // [ var(242) , var(96) ]
+                D[100,242] = var(100); // [ var(242) , var(100) ]
+                D[110,242] = (-1)*var(110); // [ var(242) , var(110) ]
+                D[111,242] = (-1)*var(111); // [ var(242) , var(111) ]
+                D[112,242] = var(112); // [ var(242) , var(112) ]
+                D[113,242] = var(113); // [ var(242) , var(113) ]
+                D[114,242] = (-1)*var(114); // [ var(242) , var(114) ]
+                D[115,242] = var(115); // [ var(242) , var(115) ]
+                D[1,243] = (-1)*var(1); // [ var(243) , var(1) ]
+                D[3,243] = (2)*var(3); // [ var(243) , var(3) ]
+                D[4,243] = (-1)*var(4); // [ var(243) , var(4) ]
+                D[9,243] = var(9); // [ var(243) , var(9) ]
+                D[10,243] = (-1)*var(10); // [ var(243) , var(10) ]
+                D[11,243] = var(11); // [ var(243) , var(11) ]
+                D[12,243] = (-1)*var(12); // [ var(243) , var(12) ]
+                D[17,243] = var(17); // [ var(243) , var(17) ]
+                D[18,243] = (-1)*var(18); // [ var(243) , var(18) ]
+                D[19,243] = var(19); // [ var(243) , var(19) ]
+                D[20,243] = (-1)*var(20); // [ var(243) , var(20) ]
+                D[25,243] = var(25); // [ var(243) , var(25) ]
+                D[26,243] = (-1)*var(26); // [ var(243) , var(26) ]
+                D[27,243] = var(27); // [ var(243) , var(27) ]
+                D[28,243] = (-1)*var(28); // [ var(243) , var(28) ]
+                D[33,243] = var(33); // [ var(243) , var(33) ]
+                D[34,243] = (-1)*var(34); // [ var(243) , var(34) ]
+                D[35,243] = var(35); // [ var(243) , var(35) ]
+                D[36,243] = (-1)*var(36); // [ var(243) , var(36) ]
+                D[37,243] = (-1)*var(37); // [ var(243) , var(37) ]
+                D[41,243] = var(41); // [ var(243) , var(41) ]
+                D[42,243] = (-1)*var(42); // [ var(243) , var(42) ]
+                D[43,243] = var(43); // [ var(243) , var(43) ]
+                D[44,243] = var(44); // [ var(243) , var(44) ]
+                D[45,243] = (-1)*var(45); // [ var(243) , var(45) ]
+                D[50,243] = var(50); // [ var(243) , var(50) ]
+                D[51,243] = var(51); // [ var(243) , var(51) ]
+                D[52,243] = (-1)*var(52); // [ var(243) , var(52) ]
+                D[53,243] = (-1)*var(53); // [ var(243) , var(53) ]
+                D[57,243] = var(57); // [ var(243) , var(57) ]
+                D[58,243] = var(58); // [ var(243) , var(58) ]
+                D[59,243] = (-1)*var(59); // [ var(243) , var(59) ]
+                D[60,243] = (-1)*var(60); // [ var(243) , var(60) ]
+                D[64,243] = var(64); // [ var(243) , var(64) ]
+                D[65,243] = var(65); // [ var(243) , var(65) ]
+                D[66,243] = (-1)*var(66); // [ var(243) , var(66) ]
+                D[67,243] = (-1)*var(67); // [ var(243) , var(67) ]
+                D[71,243] = var(71); // [ var(243) , var(71) ]
+                D[72,243] = var(72); // [ var(243) , var(72) ]
+                D[73,243] = (-1)*var(73); // [ var(243) , var(73) ]
+                D[78,243] = var(78); // [ var(243) , var(78) ]
+                D[79,243] = (-1)*var(79); // [ var(243) , var(79) ]
+                D[84,243] = var(84); // [ var(243) , var(84) ]
+                D[89,243] = (-1)*var(89); // [ var(243) , var(89) ]
+                D[93,243] = var(93); // [ var(243) , var(93) ]
+                D[94,243] = (-1)*var(94); // [ var(243) , var(94) ]
+                D[98,243] = var(98); // [ var(243) , var(98) ]
+                D[99,243] = (-1)*var(99); // [ var(243) , var(99) ]
+                D[102,243] = var(102); // [ var(243) , var(102) ]
+                D[103,243] = (-1)*var(103); // [ var(243) , var(103) ]
+                D[105,243] = var(105); // [ var(243) , var(105) ]
+                D[106,243] = (-1)*var(106); // [ var(243) , var(106) ]
+                D[108,243] = var(108); // [ var(243) , var(108) ]
+                D[111,243] = (-1)*var(111); // [ var(243) , var(111) ]
+                D[113,243] = (-1)*var(113); // [ var(243) , var(113) ]
+                D[114,243] = var(114); // [ var(243) , var(114) ]
+                D[115,243] = var(115); // [ var(243) , var(115) ]
+                D[2,244] = (-1)*var(2); // [ var(244) , var(2) ]
+                D[3,244] = (-1)*var(3); // [ var(244) , var(3) ]
+                D[4,244] = (2)*var(4); // [ var(244) , var(4) ]
+                D[5,244] = (-1)*var(5); // [ var(244) , var(5) ]
+                D[9,244] = (-1)*var(9); // [ var(244) , var(9) ]
+                D[10,244] = var(10); // [ var(244) , var(10) ]
+                D[11,244] = var(11); // [ var(244) , var(11) ]
+                D[12,244] = var(12); // [ var(244) , var(12) ]
+                D[13,244] = (-1)*var(13); // [ var(244) , var(13) ]
+                D[16,244] = var(16); // [ var(244) , var(16) ]
+                D[20,244] = var(20); // [ var(244) , var(20) ]
+                D[21,244] = (-1)*var(21); // [ var(244) , var(21) ]
+                D[25,244] = (-1)*var(25); // [ var(244) , var(25) ]
+                D[28,244] = var(28); // [ var(244) , var(28) ]
+                D[29,244] = (-1)*var(29); // [ var(244) , var(29) ]
+                D[30,244] = (-1)*var(30); // [ var(244) , var(30) ]
+                D[32,244] = var(32); // [ var(244) , var(32) ]
+                D[33,244] = (-1)*var(33); // [ var(244) , var(33) ]
+                D[36,244] = var(36); // [ var(244) , var(36) ]
+                D[37,244] = var(37); // [ var(244) , var(37) ]
+                D[38,244] = (-1)*var(38); // [ var(244) , var(38) ]
+                D[40,244] = var(40); // [ var(244) , var(40) ]
+                D[41,244] = (-1)*var(41); // [ var(244) , var(41) ]
+                D[45,244] = var(45); // [ var(244) , var(45) ]
+                D[46,244] = (-1)*var(46); // [ var(244) , var(46) ]
+                D[49,244] = var(49); // [ var(244) , var(49) ]
+                D[50,244] = (-1)*var(50); // [ var(244) , var(50) ]
+                D[53,244] = var(53); // [ var(244) , var(53) ]
+                D[54,244] = (-1)*var(54); // [ var(244) , var(54) ]
+                D[56,244] = var(56); // [ var(244) , var(56) ]
+                D[57,244] = (-1)*var(57); // [ var(244) , var(57) ]
+                D[60,244] = var(60); // [ var(244) , var(60) ]
+                D[63,244] = var(63); // [ var(244) , var(63) ]
+                D[64,244] = (-1)*var(64); // [ var(244) , var(64) ]
+                D[70,244] = var(70); // [ var(244) , var(70) ]
+                D[71,244] = (-1)*var(71); // [ var(244) , var(71) ]
+                D[72,244] = (-1)*var(72); // [ var(244) , var(72) ]
+                D[76,244] = var(76); // [ var(244) , var(76) ]
+                D[77,244] = var(77); // [ var(244) , var(77) ]
+                D[78,244] = (-1)*var(78); // [ var(244) , var(78) ]
+                D[83,244] = var(83); // [ var(244) , var(83) ]
+                D[84,244] = (-1)*var(84); // [ var(244) , var(84) ]
+                D[85,244] = (-1)*var(85); // [ var(244) , var(85) ]
+                D[88,244] = var(88); // [ var(244) , var(88) ]
+                D[89,244] = var(89); // [ var(244) , var(89) ]
+                D[90,244] = (-1)*var(90); // [ var(244) , var(90) ]
+                D[94,244] = var(94); // [ var(244) , var(94) ]
+                D[95,244] = (-1)*var(95); // [ var(244) , var(95) ]
+                D[99,244] = var(99); // [ var(244) , var(99) ]
+                D[100,244] = (-1)*var(100); // [ var(244) , var(100) ]
+                D[103,244] = var(103); // [ var(244) , var(103) ]
+                D[108,244] = (-1)*var(108); // [ var(244) , var(108) ]
+                D[109,244] = (-1)*var(109); // [ var(244) , var(109) ]
+                D[110,244] = var(110); // [ var(244) , var(110) ]
+                D[111,244] = var(111); // [ var(244) , var(111) ]
+                D[115,244] = (-1)*var(115); // [ var(244) , var(115) ]
+                D[116,244] = var(116); // [ var(244) , var(116) ]
+                D[4,245] = (-1)*var(4); // [ var(245) , var(4) ]
+                D[5,245] = (2)*var(5); // [ var(245) , var(5) ]
+                D[6,245] = (-1)*var(6); // [ var(245) , var(6) ]
+                D[10,245] = (-1)*var(10); // [ var(245) , var(10) ]
+                D[11,245] = (-1)*var(11); // [ var(245) , var(11) ]
+                D[12,245] = var(12); // [ var(245) , var(12) ]
+                D[13,245] = var(13); // [ var(245) , var(13) ]
+                D[14,245] = (-1)*var(14); // [ var(245) , var(14) ]
+                D[16,245] = (-1)*var(16); // [ var(245) , var(16) ]
+                D[17,245] = (-1)*var(17); // [ var(245) , var(17) ]
+                D[18,245] = var(18); // [ var(245) , var(18) ]
+                D[19,245] = var(19); // [ var(245) , var(19) ]
+                D[21,245] = var(21); // [ var(245) , var(21) ]
+                D[22,245] = (-1)*var(22); // [ var(245) , var(22) ]
+                D[23,245] = (-1)*var(23); // [ var(245) , var(23) ]
+                D[24,245] = var(24); // [ var(245) , var(24) ]
+                D[25,245] = var(25); // [ var(245) , var(25) ]
+                D[29,245] = var(29); // [ var(245) , var(29) ]
+                D[30,245] = var(30); // [ var(245) , var(30) ]
+                D[40,245] = (-1)*var(40); // [ var(245) , var(40) ]
+                D[45,245] = (-1)*var(45); // [ var(245) , var(45) ]
+                D[48,245] = var(48); // [ var(245) , var(48) ]
+                D[49,245] = (-1)*var(49); // [ var(245) , var(49) ]
+                D[51,245] = (-1)*var(51); // [ var(245) , var(51) ]
+                D[52,245] = var(52); // [ var(245) , var(52) ]
+                D[53,245] = (-1)*var(53); // [ var(245) , var(53) ]
+                D[55,245] = var(55); // [ var(245) , var(55) ]
+                D[56,245] = (-1)*var(56); // [ var(245) , var(56) ]
+                D[57,245] = var(57); // [ var(245) , var(57) ]
+                D[58,245] = (-1)*var(58); // [ var(245) , var(58) ]
+                D[59,245] = var(59); // [ var(245) , var(59) ]
+                D[60,245] = (-1)*var(60); // [ var(245) , var(60) ]
+                D[62,245] = var(62); // [ var(245) , var(62) ]
+                D[64,245] = var(64); // [ var(245) , var(64) ]
+                D[65,245] = (-1)*var(65); // [ var(245) , var(65) ]
+                D[67,245] = var(67); // [ var(245) , var(67) ]
+                D[72,245] = var(72); // [ var(245) , var(72) ]
+                D[76,245] = (-1)*var(76); // [ var(245) , var(76) ]
+                D[80,245] = (-1)*var(80); // [ var(245) , var(80) ]
+                D[82,245] = var(82); // [ var(245) , var(82) ]
+                D[83,245] = (-1)*var(83); // [ var(245) , var(83) ]
+                D[85,245] = var(85); // [ var(245) , var(85) ]
+                D[86,245] = (-1)*var(86); // [ var(245) , var(86) ]
+                D[87,245] = var(87); // [ var(245) , var(87) ]
+                D[88,245] = (-1)*var(88); // [ var(245) , var(88) ]
+                D[90,245] = var(90); // [ var(245) , var(90) ]
+                D[91,245] = (-1)*var(91); // [ var(245) , var(91) ]
+                D[92,245] = var(92); // [ var(245) , var(92) ]
+                D[95,245] = var(95); // [ var(245) , var(95) ]
+                D[103,245] = (-1)*var(103); // [ var(245) , var(103) ]
+                D[105,245] = (-1)*var(105); // [ var(245) , var(105) ]
+                D[106,245] = var(106); // [ var(245) , var(106) ]
+                D[107,245] = (-1)*var(107); // [ var(245) , var(107) ]
+                D[108,245] = var(108); // [ var(245) , var(108) ]
+                D[109,245] = var(109); // [ var(245) , var(109) ]
+                D[116,245] = (-1)*var(116); // [ var(245) , var(116) ]
+                D[117,245] = var(117); // [ var(245) , var(117) ]
+                D[5,246] = (-1)*var(5); // [ var(246) , var(5) ]
+                D[6,246] = (2)*var(6); // [ var(246) , var(6) ]
+                D[7,246] = (-1)*var(7); // [ var(246) , var(7) ]
+                D[12,246] = (-1)*var(12); // [ var(246) , var(12) ]
+                D[13,246] = var(13); // [ var(246) , var(13) ]
+                D[14,246] = var(14); // [ var(246) , var(14) ]
+                D[15,246] = (-1)*var(15); // [ var(246) , var(15) ]
+                D[18,246] = (-1)*var(18); // [ var(246) , var(18) ]
+                D[19,246] = (-1)*var(19); // [ var(246) , var(19) ]
+                D[20,246] = var(20); // [ var(246) , var(20) ]
+                D[22,246] = var(22); // [ var(246) , var(22) ]
+                D[24,246] = (-1)*var(24); // [ var(246) , var(24) ]
+                D[25,246] = (-1)*var(25); // [ var(246) , var(25) ]
+                D[26,246] = var(26); // [ var(246) , var(26) ]
+                D[27,246] = var(27); // [ var(246) , var(27) ]
+                D[30,246] = (-1)*var(30); // [ var(246) , var(30) ]
+                D[31,246] = var(31); // [ var(246) , var(31) ]
+                D[32,246] = (-1)*var(32); // [ var(246) , var(32) ]
+                D[33,246] = var(33); // [ var(246) , var(33) ]
+                D[37,246] = (-1)*var(37); // [ var(246) , var(37) ]
+                D[38,246] = var(38); // [ var(246) , var(38) ]
+                D[40,246] = var(40); // [ var(246) , var(40) ]
+                D[44,246] = (-1)*var(44); // [ var(246) , var(44) ]
+                D[45,246] = var(45); // [ var(246) , var(45) ]
+                D[51,246] = var(51); // [ var(246) , var(51) ]
+                D[55,246] = (-1)*var(55); // [ var(246) , var(55) ]
+                D[59,246] = (-1)*var(59); // [ var(246) , var(59) ]
+                D[61,246] = var(61); // [ var(246) , var(61) ]
+                D[62,246] = (-1)*var(62); // [ var(246) , var(62) ]
+                D[64,246] = (-1)*var(64); // [ var(246) , var(64) ]
+                D[66,246] = var(66); // [ var(246) , var(66) ]
+                D[67,246] = (-1)*var(67); // [ var(246) , var(67) ]
+                D[68,246] = var(68); // [ var(246) , var(68) ]
+                D[70,246] = (-1)*var(70); // [ var(246) , var(70) ]
+                D[71,246] = var(71); // [ var(246) , var(71) ]
+                D[72,246] = (-1)*var(72); // [ var(246) , var(72) ]
+                D[73,246] = var(73); // [ var(246) , var(73) ]
+                D[75,246] = (-1)*var(75); // [ var(246) , var(75) ]
+                D[76,246] = var(76); // [ var(246) , var(76) ]
+                D[77,246] = (-1)*var(77); // [ var(246) , var(77) ]
+                D[78,246] = var(78); // [ var(246) , var(78) ]
+                D[80,246] = var(80); // [ var(246) , var(80) ]
+                D[81,246] = (-1)*var(81); // [ var(246) , var(81) ]
+                D[83,246] = var(83); // [ var(246) , var(83) ]
+                D[86,246] = var(86); // [ var(246) , var(86) ]
+                D[92,246] = (-1)*var(92); // [ var(246) , var(92) ]
+                D[95,246] = (-1)*var(95); // [ var(246) , var(95) ]
+                D[96,246] = var(96); // [ var(246) , var(96) ]
+                D[99,246] = (-1)*var(99); // [ var(246) , var(99) ]
+                D[100,246] = var(100); // [ var(246) , var(100) ]
+                D[102,246] = (-1)*var(102); // [ var(246) , var(102) ]
+                D[103,246] = var(103); // [ var(246) , var(103) ]
+                D[104,246] = (-1)*var(104); // [ var(246) , var(104) ]
+                D[105,246] = var(105); // [ var(246) , var(105) ]
+                D[107,246] = var(107); // [ var(246) , var(107) ]
+                D[117,246] = (-1)*var(117); // [ var(246) , var(117) ]
+                D[118,246] = var(118); // [ var(246) , var(118) ]
+                D[6,247] = (-1)*var(6); // [ var(247) , var(6) ]
+                D[7,247] = (2)*var(7); // [ var(247) , var(7) ]
+                D[8,247] = (-1)*var(8); // [ var(247) , var(8) ]
+                D[13,247] = (-1)*var(13); // [ var(247) , var(13) ]
+                D[14,247] = var(14); // [ var(247) , var(14) ]
+                D[15,247] = var(15); // [ var(247) , var(15) ]
+                D[20,247] = (-1)*var(20); // [ var(247) , var(20) ]
+                D[21,247] = var(21); // [ var(247) , var(21) ]
+                D[26,247] = (-1)*var(26); // [ var(247) , var(26) ]
+                D[27,247] = (-1)*var(27); // [ var(247) , var(27) ]
+                D[28,247] = var(28); // [ var(247) , var(28) ]
+                D[31,247] = (-1)*var(31); // [ var(247) , var(31) ]
+                D[33,247] = (-1)*var(33); // [ var(247) , var(33) ]
+                D[34,247] = var(34); // [ var(247) , var(34) ]
+                D[35,247] = var(35); // [ var(247) , var(35) ]
+                D[38,247] = (-1)*var(38); // [ var(247) , var(38) ]
+                D[39,247] = var(39); // [ var(247) , var(39) ]
+                D[40,247] = (-1)*var(40); // [ var(247) , var(40) ]
+                D[41,247] = var(41); // [ var(247) , var(41) ]
+                D[45,247] = (-1)*var(45); // [ var(247) , var(45) ]
+                D[46,247] = var(46); // [ var(247) , var(46) ]
+                D[48,247] = (-1)*var(48); // [ var(247) , var(48) ]
+                D[49,247] = var(49); // [ var(247) , var(49) ]
+                D[51,247] = (-1)*var(51); // [ var(247) , var(51) ]
+                D[52,247] = (-1)*var(52); // [ var(247) , var(52) ]
+                D[53,247] = var(53); // [ var(247) , var(53) ]
+                D[55,247] = var(55); // [ var(247) , var(55) ]
+                D[57,247] = (-1)*var(57); // [ var(247) , var(57) ]
+                D[58,247] = var(58); // [ var(247) , var(58) ]
+                D[59,247] = var(59); // [ var(247) , var(59) ]
+                D[63,247] = (-1)*var(63); // [ var(247) , var(63) ]
+                D[64,247] = var(64); // [ var(247) , var(64) ]
+                D[68,247] = (-1)*var(68); // [ var(247) , var(68) ]
+                D[69,247] = (-1)*var(69); // [ var(247) , var(69) ]
+                D[70,247] = var(70); // [ var(247) , var(70) ]
+                D[73,247] = (-1)*var(73); // [ var(247) , var(73) ]
+                D[74,247] = var(74); // [ var(247) , var(74) ]
+                D[75,247] = var(75); // [ var(247) , var(75) ]
+                D[78,247] = (-1)*var(78); // [ var(247) , var(78) ]
+                D[79,247] = var(79); // [ var(247) , var(79) ]
+                D[83,247] = (-1)*var(83); // [ var(247) , var(83) ]
+                D[84,247] = var(84); // [ var(247) , var(84) ]
+                D[86,247] = (-1)*var(86); // [ var(247) , var(86) ]
+                D[87,247] = (-1)*var(87); // [ var(247) , var(87) ]
+                D[88,247] = var(88); // [ var(247) , var(88) ]
+                D[90,247] = (-1)*var(90); // [ var(247) , var(90) ]
+                D[91,247] = var(91); // [ var(247) , var(91) ]
+                D[92,247] = var(92); // [ var(247) , var(92) ]
+                D[94,247] = (-1)*var(94); // [ var(247) , var(94) ]
+                D[95,247] = var(95); // [ var(247) , var(95) ]
+                D[98,247] = (-1)*var(98); // [ var(247) , var(98) ]
+                D[99,247] = var(99); // [ var(247) , var(99) ]
+                D[101,247] = (-1)*var(101); // [ var(247) , var(101) ]
+                D[102,247] = var(102); // [ var(247) , var(102) ]
+                D[104,247] = var(104); // [ var(247) , var(104) ]
+                D[118,247] = (-1)*var(118); // [ var(247) , var(118) ]
+                D[119,247] = var(119); // [ var(247) , var(119) ]
+                D[7,248] = (-1)*var(7); // [ var(248) , var(7) ]
+                D[8,248] = (2)*var(8); // [ var(248) , var(8) ]
+                D[14,248] = (-1)*var(14); // [ var(248) , var(14) ]
+                D[15,248] = var(15); // [ var(248) , var(15) ]
+                D[21,248] = (-1)*var(21); // [ var(248) , var(21) ]
+                D[22,248] = var(22); // [ var(248) , var(22) ]
+                D[28,248] = (-1)*var(28); // [ var(248) , var(28) ]
+                D[29,248] = var(29); // [ var(248) , var(29) ]
+                D[34,248] = (-1)*var(34); // [ var(248) , var(34) ]
+                D[35,248] = (-1)*var(35); // [ var(248) , var(35) ]
+                D[36,248] = var(36); // [ var(248) , var(36) ]
+                D[39,248] = (-1)*var(39); // [ var(248) , var(39) ]
+                D[41,248] = (-1)*var(41); // [ var(248) , var(41) ]
+                D[42,248] = var(42); // [ var(248) , var(42) ]
+                D[43,248] = var(43); // [ var(248) , var(43) ]
+                D[46,248] = (-1)*var(46); // [ var(248) , var(46) ]
+                D[47,248] = var(47); // [ var(248) , var(47) ]
+                D[49,248] = (-1)*var(49); // [ var(248) , var(49) ]
+                D[50,248] = var(50); // [ var(248) , var(50) ]
+                D[53,248] = (-1)*var(53); // [ var(248) , var(53) ]
+                D[54,248] = var(54); // [ var(248) , var(54) ]
+                D[55,248] = (-1)*var(55); // [ var(248) , var(55) ]
+                D[56,248] = var(56); // [ var(248) , var(56) ]
+                D[58,248] = (-1)*var(58); // [ var(248) , var(58) ]
+                D[59,248] = (-1)*var(59); // [ var(248) , var(59) ]
+                D[60,248] = var(60); // [ var(248) , var(60) ]
+                D[61,248] = (-1)*var(61); // [ var(248) , var(61) ]
+                D[62,248] = var(62); // [ var(248) , var(62) ]
+                D[64,248] = (-1)*var(64); // [ var(248) , var(64) ]
+                D[65,248] = var(65); // [ var(248) , var(65) ]
+                D[66,248] = (-1)*var(66); // [ var(248) , var(66) ]
+                D[67,248] = var(67); // [ var(248) , var(67) ]
+                D[68,248] = var(68); // [ var(248) , var(68) ]
+                D[70,248] = (-1)*var(70); // [ var(248) , var(70) ]
+                D[71,248] = (-1)*var(71); // [ var(248) , var(71) ]
+                D[72,248] = var(72); // [ var(248) , var(72) ]
+                D[73,248] = var(73); // [ var(248) , var(73) ]
+                D[75,248] = (-1)*var(75); // [ var(248) , var(75) ]
+                D[76,248] = (-1)*var(76); // [ var(248) , var(76) ]
+                D[77,248] = var(77); // [ var(248) , var(77) ]
+                D[78,248] = var(78); // [ var(248) , var(78) ]
+                D[80,248] = (-1)*var(80); // [ var(248) , var(80) ]
+                D[81,248] = var(81); // [ var(248) , var(81) ]
+                D[82,248] = (-1)*var(82); // [ var(248) , var(82) ]
+                D[83,248] = var(83); // [ var(248) , var(83) ]
+                D[85,248] = (-1)*var(85); // [ var(248) , var(85) ]
+                D[86,248] = var(86); // [ var(248) , var(86) ]
+                D[87,248] = var(87); // [ var(248) , var(87) ]
+                D[89,248] = (-1)*var(89); // [ var(248) , var(89) ]
+                D[90,248] = var(90); // [ var(248) , var(90) ]
+                D[93,248] = (-1)*var(93); // [ var(248) , var(93) ]
+                D[94,248] = var(94); // [ var(248) , var(94) ]
+                D[97,248] = (-1)*var(97); // [ var(248) , var(97) ]
+                D[98,248] = var(98); // [ var(248) , var(98) ]
+                D[101,248] = var(101); // [ var(248) , var(101) ]
+                D[119,248] = (-1)*var(119); // [ var(248) , var(119) ]
+                D[120,248] = var(120); // [ var(248) , var(120) ]
+        // H(i) * Y(j):
+                D[121,241] = (-2)*var(121); // [ var(241) , var(121) ]
+                D[123,241] = var(123); // [ var(241) , var(123) ]
+                D[129,241] = (-1)*var(129); // [ var(241) , var(129) ]
+                D[131,241] = var(131); // [ var(241) , var(131) ]
+                D[136,241] = (-1)*var(136); // [ var(241) , var(136) ]
+                D[137,241] = var(137); // [ var(241) , var(137) ]
+                D[139,241] = var(139); // [ var(241) , var(139) ]
+                D[143,241] = (-1)*var(143); // [ var(241) , var(143) ]
+                D[144,241] = (-1)*var(144); // [ var(241) , var(144) ]
+                D[145,241] = var(145); // [ var(241) , var(145) ]
+                D[147,241] = var(147); // [ var(241) , var(147) ]
+                D[150,241] = (-1)*var(150); // [ var(241) , var(150) ]
+                D[151,241] = (-1)*var(151); // [ var(241) , var(151) ]
+                D[152,241] = var(152); // [ var(241) , var(152) ]
+                D[153,241] = var(153); // [ var(241) , var(153) ]
+                D[155,241] = var(155); // [ var(241) , var(155) ]
+                D[157,241] = (-1)*var(157); // [ var(241) , var(157) ]
+                D[158,241] = (-1)*var(158); // [ var(241) , var(158) ]
+                D[159,241] = (-1)*var(159); // [ var(241) , var(159) ]
+                D[160,241] = var(160); // [ var(241) , var(160) ]
+                D[161,241] = var(161); // [ var(241) , var(161) ]
+                D[163,241] = var(163); // [ var(241) , var(163) ]
+                D[165,241] = (-1)*var(165); // [ var(241) , var(165) ]
+                D[166,241] = (-1)*var(166); // [ var(241) , var(166) ]
+                D[167,241] = (-1)*var(167); // [ var(241) , var(167) ]
+                D[168,241] = var(168); // [ var(241) , var(168) ]
+                D[169,241] = var(169); // [ var(241) , var(169) ]
+                D[170,241] = var(170); // [ var(241) , var(170) ]
+                D[172,241] = (-1)*var(172); // [ var(241) , var(172) ]
+                D[173,241] = (-1)*var(173); // [ var(241) , var(173) ]
+                D[174,241] = (-1)*var(174); // [ var(241) , var(174) ]
+                D[175,241] = var(175); // [ var(241) , var(175) ]
+                D[176,241] = var(176); // [ var(241) , var(176) ]
+                D[179,241] = (-1)*var(179); // [ var(241) , var(179) ]
+                D[180,241] = (-1)*var(180); // [ var(241) , var(180) ]
+                D[181,241] = var(181); // [ var(241) , var(181) ]
+                D[182,241] = var(182); // [ var(241) , var(182) ]
+                D[186,241] = (-1)*var(186); // [ var(241) , var(186) ]
+                D[187,241] = (-1)*var(187); // [ var(241) , var(187) ]
+                D[188,241] = var(188); // [ var(241) , var(188) ]
+                D[193,241] = (-1)*var(193); // [ var(241) , var(193) ]
+                D[194,241] = var(194); // [ var(241) , var(194) ]
+                D[199,241] = (-1)*var(199); // [ var(241) , var(199) ]
+                D[213,241] = var(213); // [ var(241) , var(213) ]
+                D[217,241] = (-1)*var(217); // [ var(241) , var(217) ]
+                D[218,241] = var(218); // [ var(241) , var(218) ]
+                D[221,241] = (-1)*var(221); // [ var(241) , var(221) ]
+                D[222,241] = var(222); // [ var(241) , var(222) ]
+                D[224,241] = (-1)*var(224); // [ var(241) , var(224) ]
+                D[225,241] = var(225); // [ var(241) , var(225) ]
+                D[227,241] = (-1)*var(227); // [ var(241) , var(227) ]
+                D[228,241] = var(228); // [ var(241) , var(228) ]
+                D[229,241] = (-1)*var(229); // [ var(241) , var(229) ]
+                D[230,241] = var(230); // [ var(241) , var(230) ]
+                D[231,241] = (-1)*var(231); // [ var(241) , var(231) ]
+                D[232,241] = var(232); // [ var(241) , var(232) ]
+                D[233,241] = (-1)*var(233); // [ var(241) , var(233) ]
+                D[122,242] = (-2)*var(122); // [ var(242) , var(122) ]
+                D[124,242] = var(124); // [ var(242) , var(124) ]
+                D[130,242] = (-1)*var(130); // [ var(242) , var(130) ]
+                D[131,242] = var(131); // [ var(242) , var(131) ]
+                D[132,242] = var(132); // [ var(242) , var(132) ]
+                D[136,242] = var(136); // [ var(242) , var(136) ]
+                D[137,242] = (-1)*var(137); // [ var(242) , var(137) ]
+                D[138,242] = (-1)*var(138); // [ var(242) , var(138) ]
+                D[139,242] = var(139); // [ var(242) , var(139) ]
+                D[140,242] = var(140); // [ var(242) , var(140) ]
+                D[143,242] = (-1)*var(143); // [ var(242) , var(143) ]
+                D[144,242] = var(144); // [ var(242) , var(144) ]
+                D[145,242] = (-1)*var(145); // [ var(242) , var(145) ]
+                D[146,242] = (-1)*var(146); // [ var(242) , var(146) ]
+                D[147,242] = var(147); // [ var(242) , var(147) ]
+                D[148,242] = var(148); // [ var(242) , var(148) ]
+                D[150,242] = (-1)*var(150); // [ var(242) , var(150) ]
+                D[151,242] = var(151); // [ var(242) , var(151) ]
+                D[153,242] = (-1)*var(153); // [ var(242) , var(153) ]
+                D[154,242] = (-1)*var(154); // [ var(242) , var(154) ]
+                D[155,242] = var(155); // [ var(242) , var(155) ]
+                D[156,242] = var(156); // [ var(242) , var(156) ]
+                D[158,242] = (-1)*var(158); // [ var(242) , var(158) ]
+                D[159,242] = var(159); // [ var(242) , var(159) ]
+                D[161,242] = (-1)*var(161); // [ var(242) , var(161) ]
+                D[162,242] = (-1)*var(162); // [ var(242) , var(162) ]
+                D[163,242] = var(163); // [ var(242) , var(163) ]
+                D[166,242] = (-1)*var(166); // [ var(242) , var(166) ]
+                D[167,242] = var(167); // [ var(242) , var(167) ]
+                D[170,242] = (-1)*var(170); // [ var(242) , var(170) ]
+                D[174,242] = (-1)*var(174); // [ var(242) , var(174) ]
+                D[183,242] = var(183); // [ var(242) , var(183) ]
+                D[189,242] = (-1)*var(189); // [ var(242) , var(189) ]
+                D[190,242] = var(190); // [ var(242) , var(190) ]
+                D[195,242] = (-1)*var(195); // [ var(242) , var(195) ]
+                D[196,242] = var(196); // [ var(242) , var(196) ]
+                D[197,242] = var(197); // [ var(242) , var(197) ]
+                D[200,242] = (-1)*var(200); // [ var(242) , var(200) ]
+                D[201,242] = (-1)*var(201); // [ var(242) , var(201) ]
+                D[202,242] = var(202); // [ var(242) , var(202) ]
+                D[203,242] = var(203); // [ var(242) , var(203) ]
+                D[205,242] = (-1)*var(205); // [ var(242) , var(205) ]
+                D[206,242] = (-1)*var(206); // [ var(242) , var(206) ]
+                D[207,242] = var(207); // [ var(242) , var(207) ]
+                D[208,242] = var(208); // [ var(242) , var(208) ]
+                D[210,242] = (-1)*var(210); // [ var(242) , var(210) ]
+                D[211,242] = (-1)*var(211); // [ var(242) , var(211) ]
+                D[212,242] = var(212); // [ var(242) , var(212) ]
+                D[215,242] = (-1)*var(215); // [ var(242) , var(215) ]
+                D[216,242] = var(216); // [ var(242) , var(216) ]
+                D[220,242] = (-1)*var(220); // [ var(242) , var(220) ]
+                D[230,242] = var(230); // [ var(242) , var(230) ]
+                D[231,242] = var(231); // [ var(242) , var(231) ]
+                D[232,242] = (-1)*var(232); // [ var(242) , var(232) ]
+                D[233,242] = (-1)*var(233); // [ var(242) , var(233) ]
+                D[234,242] = var(234); // [ var(242) , var(234) ]
+                D[235,242] = (-1)*var(235); // [ var(242) , var(235) ]
+                D[121,243] = var(121); // [ var(243) , var(121) ]
+                D[123,243] = (-2)*var(123); // [ var(243) , var(123) ]
+                D[124,243] = var(124); // [ var(243) , var(124) ]
+                D[129,243] = (-1)*var(129); // [ var(243) , var(129) ]
+                D[130,243] = var(130); // [ var(243) , var(130) ]
+                D[131,243] = (-1)*var(131); // [ var(243) , var(131) ]
+                D[132,243] = var(132); // [ var(243) , var(132) ]
+                D[137,243] = (-1)*var(137); // [ var(243) , var(137) ]
+                D[138,243] = var(138); // [ var(243) , var(138) ]
+                D[139,243] = (-1)*var(139); // [ var(243) , var(139) ]
+                D[140,243] = var(140); // [ var(243) , var(140) ]
+                D[145,243] = (-1)*var(145); // [ var(243) , var(145) ]
+                D[146,243] = var(146); // [ var(243) , var(146) ]
+                D[147,243] = (-1)*var(147); // [ var(243) , var(147) ]
+                D[148,243] = var(148); // [ var(243) , var(148) ]
+                D[153,243] = (-1)*var(153); // [ var(243) , var(153) ]
+                D[154,243] = var(154); // [ var(243) , var(154) ]
+                D[155,243] = (-1)*var(155); // [ var(243) , var(155) ]
+                D[156,243] = var(156); // [ var(243) , var(156) ]
+                D[157,243] = var(157); // [ var(243) , var(157) ]
+                D[161,243] = (-1)*var(161); // [ var(243) , var(161) ]
+                D[162,243] = var(162); // [ var(243) , var(162) ]
+                D[163,243] = (-1)*var(163); // [ var(243) , var(163) ]
+                D[164,243] = (-1)*var(164); // [ var(243) , var(164) ]
+                D[165,243] = var(165); // [ var(243) , var(165) ]
+                D[170,243] = (-1)*var(170); // [ var(243) , var(170) ]
+                D[171,243] = (-1)*var(171); // [ var(243) , var(171) ]
+                D[172,243] = var(172); // [ var(243) , var(172) ]
+                D[173,243] = var(173); // [ var(243) , var(173) ]
+                D[177,243] = (-1)*var(177); // [ var(243) , var(177) ]
+                D[178,243] = (-1)*var(178); // [ var(243) , var(178) ]
+                D[179,243] = var(179); // [ var(243) , var(179) ]
+                D[180,243] = var(180); // [ var(243) , var(180) ]
+                D[184,243] = (-1)*var(184); // [ var(243) , var(184) ]
+                D[185,243] = (-1)*var(185); // [ var(243) , var(185) ]
+                D[186,243] = var(186); // [ var(243) , var(186) ]
+                D[187,243] = var(187); // [ var(243) , var(187) ]
+                D[191,243] = (-1)*var(191); // [ var(243) , var(191) ]
+                D[192,243] = (-1)*var(192); // [ var(243) , var(192) ]
+                D[193,243] = var(193); // [ var(243) , var(193) ]
+                D[198,243] = (-1)*var(198); // [ var(243) , var(198) ]
+                D[199,243] = var(199); // [ var(243) , var(199) ]
+                D[204,243] = (-1)*var(204); // [ var(243) , var(204) ]
+                D[209,243] = var(209); // [ var(243) , var(209) ]
+                D[213,243] = (-1)*var(213); // [ var(243) , var(213) ]
+                D[214,243] = var(214); // [ var(243) , var(214) ]
+                D[218,243] = (-1)*var(218); // [ var(243) , var(218) ]
+                D[219,243] = var(219); // [ var(243) , var(219) ]
+                D[222,243] = (-1)*var(222); // [ var(243) , var(222) ]
+                D[223,243] = var(223); // [ var(243) , var(223) ]
+                D[225,243] = (-1)*var(225); // [ var(243) , var(225) ]
+                D[226,243] = var(226); // [ var(243) , var(226) ]
+                D[228,243] = (-1)*var(228); // [ var(243) , var(228) ]
+                D[231,243] = var(231); // [ var(243) , var(231) ]
+                D[233,243] = var(233); // [ var(243) , var(233) ]
+                D[234,243] = (-1)*var(234); // [ var(243) , var(234) ]
+                D[235,243] = (-1)*var(235); // [ var(243) , var(235) ]
+                D[122,244] = var(122); // [ var(244) , var(122) ]
+                D[123,244] = var(123); // [ var(244) , var(123) ]
+                D[124,244] = (-2)*var(124); // [ var(244) , var(124) ]
+                D[125,244] = var(125); // [ var(244) , var(125) ]
+                D[129,244] = var(129); // [ var(244) , var(129) ]
+                D[130,244] = (-1)*var(130); // [ var(244) , var(130) ]
+                D[131,244] = (-1)*var(131); // [ var(244) , var(131) ]
+                D[132,244] = (-1)*var(132); // [ var(244) , var(132) ]
+                D[133,244] = var(133); // [ var(244) , var(133) ]
+                D[136,244] = (-1)*var(136); // [ var(244) , var(136) ]
+                D[140,244] = (-1)*var(140); // [ var(244) , var(140) ]
+                D[141,244] = var(141); // [ var(244) , var(141) ]
+                D[145,244] = var(145); // [ var(244) , var(145) ]
+                D[148,244] = (-1)*var(148); // [ var(244) , var(148) ]
+                D[149,244] = var(149); // [ var(244) , var(149) ]
+                D[150,244] = var(150); // [ var(244) , var(150) ]
+                D[152,244] = (-1)*var(152); // [ var(244) , var(152) ]
+                D[153,244] = var(153); // [ var(244) , var(153) ]
+                D[156,244] = (-1)*var(156); // [ var(244) , var(156) ]
+                D[157,244] = (-1)*var(157); // [ var(244) , var(157) ]
+                D[158,244] = var(158); // [ var(244) , var(158) ]
+                D[160,244] = (-1)*var(160); // [ var(244) , var(160) ]
+                D[161,244] = var(161); // [ var(244) , var(161) ]
+                D[165,244] = (-1)*var(165); // [ var(244) , var(165) ]
+                D[166,244] = var(166); // [ var(244) , var(166) ]
+                D[169,244] = (-1)*var(169); // [ var(244) , var(169) ]
+                D[170,244] = var(170); // [ var(244) , var(170) ]
+                D[173,244] = (-1)*var(173); // [ var(244) , var(173) ]
+                D[174,244] = var(174); // [ var(244) , var(174) ]
+                D[176,244] = (-1)*var(176); // [ var(244) , var(176) ]
+                D[177,244] = var(177); // [ var(244) , var(177) ]
+                D[180,244] = (-1)*var(180); // [ var(244) , var(180) ]
+                D[183,244] = (-1)*var(183); // [ var(244) , var(183) ]
+                D[184,244] = var(184); // [ var(244) , var(184) ]
+                D[190,244] = (-1)*var(190); // [ var(244) , var(190) ]
+                D[191,244] = var(191); // [ var(244) , var(191) ]
+                D[192,244] = var(192); // [ var(244) , var(192) ]
+                D[196,244] = (-1)*var(196); // [ var(244) , var(196) ]
+                D[197,244] = (-1)*var(197); // [ var(244) , var(197) ]
+                D[198,244] = var(198); // [ var(244) , var(198) ]
+                D[203,244] = (-1)*var(203); // [ var(244) , var(203) ]
+                D[204,244] = var(204); // [ var(244) , var(204) ]
+                D[205,244] = var(205); // [ var(244) , var(205) ]
+                D[208,244] = (-1)*var(208); // [ var(244) , var(208) ]
+                D[209,244] = (-1)*var(209); // [ var(244) , var(209) ]
+                D[210,244] = var(210); // [ var(244) , var(210) ]
+                D[214,244] = (-1)*var(214); // [ var(244) , var(214) ]
+                D[215,244] = var(215); // [ var(244) , var(215) ]
+                D[219,244] = (-1)*var(219); // [ var(244) , var(219) ]
+                D[220,244] = var(220); // [ var(244) , var(220) ]
+                D[223,244] = (-1)*var(223); // [ var(244) , var(223) ]
+                D[228,244] = var(228); // [ var(244) , var(228) ]
+                D[229,244] = var(229); // [ var(244) , var(229) ]
+                D[230,244] = (-1)*var(230); // [ var(244) , var(230) ]
+                D[231,244] = (-1)*var(231); // [ var(244) , var(231) ]
+                D[235,244] = var(235); // [ var(244) , var(235) ]
+                D[236,244] = (-1)*var(236); // [ var(244) , var(236) ]
+                D[124,245] = var(124); // [ var(245) , var(124) ]
+                D[125,245] = (-2)*var(125); // [ var(245) , var(125) ]
+                D[126,245] = var(126); // [ var(245) , var(126) ]
+                D[130,245] = var(130); // [ var(245) , var(130) ]
+                D[131,245] = var(131); // [ var(245) , var(131) ]
+                D[132,245] = (-1)*var(132); // [ var(245) , var(132) ]
+                D[133,245] = (-1)*var(133); // [ var(245) , var(133) ]
+                D[134,245] = var(134); // [ var(245) , var(134) ]
+                D[136,245] = var(136); // [ var(245) , var(136) ]
+                D[137,245] = var(137); // [ var(245) , var(137) ]
+                D[138,245] = (-1)*var(138); // [ var(245) , var(138) ]
+                D[139,245] = (-1)*var(139); // [ var(245) , var(139) ]
+                D[141,245] = (-1)*var(141); // [ var(245) , var(141) ]
+                D[142,245] = var(142); // [ var(245) , var(142) ]
+                D[143,245] = var(143); // [ var(245) , var(143) ]
+                D[144,245] = (-1)*var(144); // [ var(245) , var(144) ]
+                D[145,245] = (-1)*var(145); // [ var(245) , var(145) ]
+                D[149,245] = (-1)*var(149); // [ var(245) , var(149) ]
+                D[150,245] = (-1)*var(150); // [ var(245) , var(150) ]
+                D[160,245] = var(160); // [ var(245) , var(160) ]
+                D[165,245] = var(165); // [ var(245) , var(165) ]
+                D[168,245] = (-1)*var(168); // [ var(245) , var(168) ]
+                D[169,245] = var(169); // [ var(245) , var(169) ]
+                D[171,245] = var(171); // [ var(245) , var(171) ]
+                D[172,245] = (-1)*var(172); // [ var(245) , var(172) ]
+                D[173,245] = var(173); // [ var(245) , var(173) ]
+                D[175,245] = (-1)*var(175); // [ var(245) , var(175) ]
+                D[176,245] = var(176); // [ var(245) , var(176) ]
+                D[177,245] = (-1)*var(177); // [ var(245) , var(177) ]
+                D[178,245] = var(178); // [ var(245) , var(178) ]
+                D[179,245] = (-1)*var(179); // [ var(245) , var(179) ]
+                D[180,245] = var(180); // [ var(245) , var(180) ]
+                D[182,245] = (-1)*var(182); // [ var(245) , var(182) ]
+                D[184,245] = (-1)*var(184); // [ var(245) , var(184) ]
+                D[185,245] = var(185); // [ var(245) , var(185) ]
+                D[187,245] = (-1)*var(187); // [ var(245) , var(187) ]
+                D[192,245] = (-1)*var(192); // [ var(245) , var(192) ]
+                D[196,245] = var(196); // [ var(245) , var(196) ]
+                D[200,245] = var(200); // [ var(245) , var(200) ]
+                D[202,245] = (-1)*var(202); // [ var(245) , var(202) ]
+                D[203,245] = var(203); // [ var(245) , var(203) ]
+                D[205,245] = (-1)*var(205); // [ var(245) , var(205) ]
+                D[206,245] = var(206); // [ var(245) , var(206) ]
+                D[207,245] = (-1)*var(207); // [ var(245) , var(207) ]
+                D[208,245] = var(208); // [ var(245) , var(208) ]
+                D[210,245] = (-1)*var(210); // [ var(245) , var(210) ]
+                D[211,245] = var(211); // [ var(245) , var(211) ]
+                D[212,245] = (-1)*var(212); // [ var(245) , var(212) ]
+                D[215,245] = (-1)*var(215); // [ var(245) , var(215) ]
+                D[223,245] = var(223); // [ var(245) , var(223) ]
+                D[225,245] = var(225); // [ var(245) , var(225) ]
+                D[226,245] = (-1)*var(226); // [ var(245) , var(226) ]
+                D[227,245] = var(227); // [ var(245) , var(227) ]
+                D[228,245] = (-1)*var(228); // [ var(245) , var(228) ]
+                D[229,245] = (-1)*var(229); // [ var(245) , var(229) ]
+                D[236,245] = var(236); // [ var(245) , var(236) ]
+                D[237,245] = (-1)*var(237); // [ var(245) , var(237) ]
+                D[125,246] = var(125); // [ var(246) , var(125) ]
+                D[126,246] = (-2)*var(126); // [ var(246) , var(126) ]
+                D[127,246] = var(127); // [ var(246) , var(127) ]
+                D[132,246] = var(132); // [ var(246) , var(132) ]
+                D[133,246] = (-1)*var(133); // [ var(246) , var(133) ]
+                D[134,246] = (-1)*var(134); // [ var(246) , var(134) ]
+                D[135,246] = var(135); // [ var(246) , var(135) ]
+                D[138,246] = var(138); // [ var(246) , var(138) ]
+                D[139,246] = var(139); // [ var(246) , var(139) ]
+                D[140,246] = (-1)*var(140); // [ var(246) , var(140) ]
+                D[142,246] = (-1)*var(142); // [ var(246) , var(142) ]
+                D[144,246] = var(144); // [ var(246) , var(144) ]
+                D[145,246] = var(145); // [ var(246) , var(145) ]
+                D[146,246] = (-1)*var(146); // [ var(246) , var(146) ]
+                D[147,246] = (-1)*var(147); // [ var(246) , var(147) ]
+                D[150,246] = var(150); // [ var(246) , var(150) ]
+                D[151,246] = (-1)*var(151); // [ var(246) , var(151) ]
+                D[152,246] = var(152); // [ var(246) , var(152) ]
+                D[153,246] = (-1)*var(153); // [ var(246) , var(153) ]
+                D[157,246] = var(157); // [ var(246) , var(157) ]
+                D[158,246] = (-1)*var(158); // [ var(246) , var(158) ]
+                D[160,246] = (-1)*var(160); // [ var(246) , var(160) ]
+                D[164,246] = var(164); // [ var(246) , var(164) ]
+                D[165,246] = (-1)*var(165); // [ var(246) , var(165) ]
+                D[171,246] = (-1)*var(171); // [ var(246) , var(171) ]
+                D[175,246] = var(175); // [ var(246) , var(175) ]
+                D[179,246] = var(179); // [ var(246) , var(179) ]
+                D[181,246] = (-1)*var(181); // [ var(246) , var(181) ]
+                D[182,246] = var(182); // [ var(246) , var(182) ]
+                D[184,246] = var(184); // [ var(246) , var(184) ]
+                D[186,246] = (-1)*var(186); // [ var(246) , var(186) ]
+                D[187,246] = var(187); // [ var(246) , var(187) ]
+                D[188,246] = (-1)*var(188); // [ var(246) , var(188) ]
+                D[190,246] = var(190); // [ var(246) , var(190) ]
+                D[191,246] = (-1)*var(191); // [ var(246) , var(191) ]
+                D[192,246] = var(192); // [ var(246) , var(192) ]
+                D[193,246] = (-1)*var(193); // [ var(246) , var(193) ]
+                D[195,246] = var(195); // [ var(246) , var(195) ]
+                D[196,246] = (-1)*var(196); // [ var(246) , var(196) ]
+                D[197,246] = var(197); // [ var(246) , var(197) ]
+                D[198,246] = (-1)*var(198); // [ var(246) , var(198) ]
+                D[200,246] = (-1)*var(200); // [ var(246) , var(200) ]
+                D[201,246] = var(201); // [ var(246) , var(201) ]
+                D[203,246] = (-1)*var(203); // [ var(246) , var(203) ]
+                D[206,246] = (-1)*var(206); // [ var(246) , var(206) ]
+                D[212,246] = var(212); // [ var(246) , var(212) ]
+                D[215,246] = var(215); // [ var(246) , var(215) ]
+                D[216,246] = (-1)*var(216); // [ var(246) , var(216) ]
+                D[219,246] = var(219); // [ var(246) , var(219) ]
+                D[220,246] = (-1)*var(220); // [ var(246) , var(220) ]
+                D[222,246] = var(222); // [ var(246) , var(222) ]
+                D[223,246] = (-1)*var(223); // [ var(246) , var(223) ]
+                D[224,246] = var(224); // [ var(246) , var(224) ]
+                D[225,246] = (-1)*var(225); // [ var(246) , var(225) ]
+                D[227,246] = (-1)*var(227); // [ var(246) , var(227) ]
+                D[237,246] = var(237); // [ var(246) , var(237) ]
+                D[238,246] = (-1)*var(238); // [ var(246) , var(238) ]
+                D[126,247] = var(126); // [ var(247) , var(126) ]
+                D[127,247] = (-2)*var(127); // [ var(247) , var(127) ]
+                D[128,247] = var(128); // [ var(247) , var(128) ]
+                D[133,247] = var(133); // [ var(247) , var(133) ]
+                D[134,247] = (-1)*var(134); // [ var(247) , var(134) ]
+                D[135,247] = (-1)*var(135); // [ var(247) , var(135) ]
+                D[140,247] = var(140); // [ var(247) , var(140) ]
+                D[141,247] = (-1)*var(141); // [ var(247) , var(141) ]
+                D[146,247] = var(146); // [ var(247) , var(146) ]
+                D[147,247] = var(147); // [ var(247) , var(147) ]
+                D[148,247] = (-1)*var(148); // [ var(247) , var(148) ]
+                D[151,247] = var(151); // [ var(247) , var(151) ]
+                D[153,247] = var(153); // [ var(247) , var(153) ]
+                D[154,247] = (-1)*var(154); // [ var(247) , var(154) ]
+                D[155,247] = (-1)*var(155); // [ var(247) , var(155) ]
+                D[158,247] = var(158); // [ var(247) , var(158) ]
+                D[159,247] = (-1)*var(159); // [ var(247) , var(159) ]
+                D[160,247] = var(160); // [ var(247) , var(160) ]
+                D[161,247] = (-1)*var(161); // [ var(247) , var(161) ]
+                D[165,247] = var(165); // [ var(247) , var(165) ]
+                D[166,247] = (-1)*var(166); // [ var(247) , var(166) ]
+                D[168,247] = var(168); // [ var(247) , var(168) ]
+                D[169,247] = (-1)*var(169); // [ var(247) , var(169) ]
+                D[171,247] = var(171); // [ var(247) , var(171) ]
+                D[172,247] = var(172); // [ var(247) , var(172) ]
+                D[173,247] = (-1)*var(173); // [ var(247) , var(173) ]
+                D[175,247] = (-1)*var(175); // [ var(247) , var(175) ]
+                D[177,247] = var(177); // [ var(247) , var(177) ]
+                D[178,247] = (-1)*var(178); // [ var(247) , var(178) ]
+                D[179,247] = (-1)*var(179); // [ var(247) , var(179) ]
+                D[183,247] = var(183); // [ var(247) , var(183) ]
+                D[184,247] = (-1)*var(184); // [ var(247) , var(184) ]
+                D[188,247] = var(188); // [ var(247) , var(188) ]
+                D[189,247] = var(189); // [ var(247) , var(189) ]
+                D[190,247] = (-1)*var(190); // [ var(247) , var(190) ]
+                D[193,247] = var(193); // [ var(247) , var(193) ]
+                D[194,247] = (-1)*var(194); // [ var(247) , var(194) ]
+                D[195,247] = (-1)*var(195); // [ var(247) , var(195) ]
+                D[198,247] = var(198); // [ var(247) , var(198) ]
+                D[199,247] = (-1)*var(199); // [ var(247) , var(199) ]
+                D[203,247] = var(203); // [ var(247) , var(203) ]
+                D[204,247] = (-1)*var(204); // [ var(247) , var(204) ]
+                D[206,247] = var(206); // [ var(247) , var(206) ]
+                D[207,247] = var(207); // [ var(247) , var(207) ]
+                D[208,247] = (-1)*var(208); // [ var(247) , var(208) ]
+                D[210,247] = var(210); // [ var(247) , var(210) ]
+                D[211,247] = (-1)*var(211); // [ var(247) , var(211) ]
+                D[212,247] = (-1)*var(212); // [ var(247) , var(212) ]
+                D[214,247] = var(214); // [ var(247) , var(214) ]
+                D[215,247] = (-1)*var(215); // [ var(247) , var(215) ]
+                D[218,247] = var(218); // [ var(247) , var(218) ]
+                D[219,247] = (-1)*var(219); // [ var(247) , var(219) ]
+                D[221,247] = var(221); // [ var(247) , var(221) ]
+                D[222,247] = (-1)*var(222); // [ var(247) , var(222) ]
+                D[224,247] = (-1)*var(224); // [ var(247) , var(224) ]
+                D[238,247] = var(238); // [ var(247) , var(238) ]
+                D[239,247] = (-1)*var(239); // [ var(247) , var(239) ]
+                D[127,248] = var(127); // [ var(248) , var(127) ]
+                D[128,248] = (-2)*var(128); // [ var(248) , var(128) ]
+                D[134,248] = var(134); // [ var(248) , var(134) ]
+                D[135,248] = (-1)*var(135); // [ var(248) , var(135) ]
+                D[141,248] = var(141); // [ var(248) , var(141) ]
+                D[142,248] = (-1)*var(142); // [ var(248) , var(142) ]
+                D[148,248] = var(148); // [ var(248) , var(148) ]
+                D[149,248] = (-1)*var(149); // [ var(248) , var(149) ]
+                D[154,248] = var(154); // [ var(248) , var(154) ]
+                D[155,248] = var(155); // [ var(248) , var(155) ]
+                D[156,248] = (-1)*var(156); // [ var(248) , var(156) ]
+                D[159,248] = var(159); // [ var(248) , var(159) ]
+                D[161,248] = var(161); // [ var(248) , var(161) ]
+                D[162,248] = (-1)*var(162); // [ var(248) , var(162) ]
+                D[163,248] = (-1)*var(163); // [ var(248) , var(163) ]
+                D[166,248] = var(166); // [ var(248) , var(166) ]
+                D[167,248] = (-1)*var(167); // [ var(248) , var(167) ]
+                D[169,248] = var(169); // [ var(248) , var(169) ]
+                D[170,248] = (-1)*var(170); // [ var(248) , var(170) ]
+                D[173,248] = var(173); // [ var(248) , var(173) ]
+                D[174,248] = (-1)*var(174); // [ var(248) , var(174) ]
+                D[175,248] = var(175); // [ var(248) , var(175) ]
+                D[176,248] = (-1)*var(176); // [ var(248) , var(176) ]
+                D[178,248] = var(178); // [ var(248) , var(178) ]
+                D[179,248] = var(179); // [ var(248) , var(179) ]
+                D[180,248] = (-1)*var(180); // [ var(248) , var(180) ]
+                D[181,248] = var(181); // [ var(248) , var(181) ]
+                D[182,248] = (-1)*var(182); // [ var(248) , var(182) ]
+                D[184,248] = var(184); // [ var(248) , var(184) ]
+                D[185,248] = (-1)*var(185); // [ var(248) , var(185) ]
+                D[186,248] = var(186); // [ var(248) , var(186) ]
+                D[187,248] = (-1)*var(187); // [ var(248) , var(187) ]
+                D[188,248] = (-1)*var(188); // [ var(248) , var(188) ]
+                D[190,248] = var(190); // [ var(248) , var(190) ]
+                D[191,248] = var(191); // [ var(248) , var(191) ]
+                D[192,248] = (-1)*var(192); // [ var(248) , var(192) ]
+                D[193,248] = (-1)*var(193); // [ var(248) , var(193) ]
+                D[195,248] = var(195); // [ var(248) , var(195) ]
+                D[196,248] = var(196); // [ var(248) , var(196) ]
+                D[197,248] = (-1)*var(197); // [ var(248) , var(197) ]
+                D[198,248] = (-1)*var(198); // [ var(248) , var(198) ]
+                D[200,248] = var(200); // [ var(248) , var(200) ]
+                D[201,248] = (-1)*var(201); // [ var(248) , var(201) ]
+                D[202,248] = var(202); // [ var(248) , var(202) ]
+                D[203,248] = (-1)*var(203); // [ var(248) , var(203) ]
+                D[205,248] = var(205); // [ var(248) , var(205) ]
+                D[206,248] = (-1)*var(206); // [ var(248) , var(206) ]
+                D[207,248] = (-1)*var(207); // [ var(248) , var(207) ]
+                D[209,248] = var(209); // [ var(248) , var(209) ]
+                D[210,248] = (-1)*var(210); // [ var(248) , var(210) ]
+                D[213,248] = var(213); // [ var(248) , var(213) ]
+                D[214,248] = (-1)*var(214); // [ var(248) , var(214) ]
+                D[217,248] = var(217); // [ var(248) , var(217) ]
+                D[218,248] = (-1)*var(218); // [ var(248) , var(218) ]
+                D[221,248] = (-1)*var(221); // [ var(248) , var(221) ]
+                D[239,248] = var(239); // [ var(248) , var(239) ]
+                D[240,248] = (-1)*var(240); // [ var(248) , var(240) ]
+        // Y(i) * X(j):
+                D[1,121] = (-1)*var(241); // [ var(121) , var(1) ]
+                D[9,121] = (-1)*var(3); // [ var(121) , var(9) ]
+                D[16,121] = (-1)*var(11); // [ var(121) , var(16) ]
+                D[23,121] = (-1)*var(17); // [ var(121) , var(23) ]
+                D[24,121] = (-1)*var(19); // [ var(121) , var(24) ]
+                D[30,121] = (-1)*var(25); // [ var(121) , var(30) ]
+                D[31,121] = (-1)*var(27); // [ var(121) , var(31) ]
+                D[37,121] = (-1)*var(32); // [ var(121) , var(37) ]
+                D[38,121] = (-1)*var(33); // [ var(121) , var(38) ]
+                D[39,121] = (-1)*var(35); // [ var(121) , var(39) ]
+                D[45,121] = (-1)*var(40); // [ var(121) , var(45) ]
+                D[46,121] = (-1)*var(41); // [ var(121) , var(46) ]
+                D[47,121] = (-1)*var(43); // [ var(121) , var(47) ]
+                D[52,121] = (-1)*var(48); // [ var(121) , var(52) ]
+                D[53,121] = (-1)*var(49); // [ var(121) , var(53) ]
+                D[54,121] = (-1)*var(50); // [ var(121) , var(54) ]
+                D[59,121] = (-1)*var(55); // [ var(121) , var(59) ]
+                D[60,121] = (-1)*var(56); // [ var(121) , var(60) ]
+                D[66,121] = (-1)*var(61); // [ var(121) , var(66) ]
+                D[67,121] = (-1)*var(62); // [ var(121) , var(67) ]
+                D[73,121] = (-1)*var(68); // [ var(121) , var(73) ]
+                D[79,121] = (-1)*var(74); // [ var(121) , var(79) ]
+                D[97,121] = var(93); // [ var(121) , var(97) ]
+                D[101,121] = var(98); // [ var(121) , var(101) ]
+                D[104,121] = var(102); // [ var(121) , var(104) ]
+                D[107,121] = var(105); // [ var(121) , var(107) ]
+                D[109,121] = var(108); // [ var(121) , var(109) ]
+                D[111,121] = var(110); // [ var(121) , var(111) ]
+                D[113,121] = var(112); // [ var(121) , var(113) ]
+                D[2,122] = (-1)*var(242); // [ var(122) , var(2) ]
+                D[10,122] = (-1)*var(4); // [ var(122) , var(10) ]
+                D[17,122] = (-1)*var(11); // [ var(122) , var(17) ]
+                D[18,122] = (-1)*var(12); // [ var(122) , var(18) ]
+                D[23,122] = (-1)*var(16); // [ var(122) , var(23) ]
+                D[25,122] = (-1)*var(19); // [ var(122) , var(25) ]
+                D[26,122] = (-1)*var(20); // [ var(122) , var(26) ]
+                D[30,122] = (-1)*var(24); // [ var(122) , var(30) ]
+                D[33,122] = (-1)*var(27); // [ var(122) , var(33) ]
+                D[34,122] = (-1)*var(28); // [ var(122) , var(34) ]
+                D[38,122] = (-1)*var(31); // [ var(122) , var(38) ]
+                D[41,122] = (-1)*var(35); // [ var(122) , var(41) ]
+                D[42,122] = (-1)*var(36); // [ var(122) , var(42) ]
+                D[46,122] = (-1)*var(39); // [ var(122) , var(46) ]
+                D[50,122] = (-1)*var(43); // [ var(122) , var(50) ]
+                D[54,122] = (-1)*var(47); // [ var(122) , var(54) ]
+                D[69,122] = var(63); // [ var(122) , var(69) ]
+                D[75,122] = var(70); // [ var(122) , var(75) ]
+                D[80,122] = var(76); // [ var(122) , var(80) ]
+                D[81,122] = var(77); // [ var(122) , var(81) ]
+                D[85,122] = var(82); // [ var(122) , var(85) ]
+                D[86,122] = var(83); // [ var(122) , var(86) ]
+                D[90,122] = var(87); // [ var(122) , var(90) ]
+                D[91,122] = var(88); // [ var(122) , var(91) ]
+                D[95,122] = var(92); // [ var(122) , var(95) ]
+                D[100,122] = var(96); // [ var(122) , var(100) ]
+                D[112,122] = (-1)*var(110); // [ var(122) , var(112) ]
+                D[113,122] = (-1)*var(111); // [ var(122) , var(113) ]
+                D[115,122] = (-1)*var(114); // [ var(122) , var(115) ]
+                D[3,123] = (-1)*var(243); // [ var(123) , var(3) ]
+                D[9,123] = var(1); // [ var(123) , var(9) ]
+                D[11,123] = (-1)*var(4); // [ var(123) , var(11) ]
+                D[17,123] = (-1)*var(10); // [ var(123) , var(17) ]
+                D[19,123] = (-1)*var(12); // [ var(123) , var(19) ]
+                D[25,123] = (-1)*var(18); // [ var(123) , var(25) ]
+                D[27,123] = (-1)*var(20); // [ var(123) , var(27) ]
+                D[33,123] = (-1)*var(26); // [ var(123) , var(33) ]
+                D[35,123] = (-1)*var(28); // [ var(123) , var(35) ]
+                D[41,123] = (-1)*var(34); // [ var(123) , var(41) ]
+                D[43,123] = (-1)*var(36); // [ var(123) , var(43) ]
+                D[44,123] = (-1)*var(37); // [ var(123) , var(44) ]
+                D[50,123] = (-1)*var(42); // [ var(123) , var(50) ]
+                D[51,123] = (-1)*var(45); // [ var(123) , var(51) ]
+                D[57,123] = (-1)*var(52); // [ var(123) , var(57) ]
+                D[58,123] = (-1)*var(53); // [ var(123) , var(58) ]
+                D[64,123] = (-1)*var(59); // [ var(123) , var(64) ]
+                D[65,123] = (-1)*var(60); // [ var(123) , var(65) ]
+                D[71,123] = (-1)*var(66); // [ var(123) , var(71) ]
+                D[72,123] = (-1)*var(67); // [ var(123) , var(72) ]
+                D[78,123] = (-1)*var(73); // [ var(123) , var(78) ]
+                D[84,123] = (-1)*var(79); // [ var(123) , var(84) ]
+                D[93,123] = var(89); // [ var(123) , var(93) ]
+                D[98,123] = var(94); // [ var(123) , var(98) ]
+                D[102,123] = var(99); // [ var(123) , var(102) ]
+                D[105,123] = var(103); // [ var(123) , var(105) ]
+                D[108,123] = var(106); // [ var(123) , var(108) ]
+                D[114,123] = var(111); // [ var(123) , var(114) ]
+                D[115,123] = var(113); // [ var(123) , var(115) ]
+                D[4,124] = (-1)*var(244); // [ var(124) , var(4) ]
+                D[10,124] = var(2); // [ var(124) , var(10) ]
+                D[11,124] = var(3); // [ var(124) , var(11) ]
+                D[12,124] = (-1)*var(5); // [ var(124) , var(12) ]
+                D[16,124] = var(9); // [ var(124) , var(16) ]
+                D[20,124] = (-1)*var(13); // [ var(124) , var(20) ]
+                D[28,124] = (-1)*var(21); // [ var(124) , var(28) ]
+                D[32,124] = var(25); // [ var(124) , var(32) ]
+                D[36,124] = (-1)*var(29); // [ var(124) , var(36) ]
+                D[37,124] = var(30); // [ var(124) , var(37) ]
+                D[40,124] = var(33); // [ var(124) , var(40) ]
+                D[45,124] = var(38); // [ var(124) , var(45) ]
+                D[49,124] = var(41); // [ var(124) , var(49) ]
+                D[53,124] = var(46); // [ var(124) , var(53) ]
+                D[56,124] = var(50); // [ var(124) , var(56) ]
+                D[60,124] = var(54); // [ var(124) , var(60) ]
+                D[63,124] = var(57); // [ var(124) , var(63) ]
+                D[70,124] = var(64); // [ var(124) , var(70) ]
+                D[76,124] = var(71); // [ var(124) , var(76) ]
+                D[77,124] = var(72); // [ var(124) , var(77) ]
+                D[83,124] = var(78); // [ var(124) , var(83) ]
+                D[88,124] = var(84); // [ var(124) , var(88) ]
+                D[89,124] = var(85); // [ var(124) , var(89) ]
+                D[94,124] = var(90); // [ var(124) , var(94) ]
+                D[99,124] = var(95); // [ var(124) , var(99) ]
+                D[103,124] = var(100); // [ var(124) , var(103) ]
+                D[110,124] = var(108); // [ var(124) , var(110) ]
+                D[111,124] = var(109); // [ var(124) , var(111) ]
+                D[116,124] = (-1)*var(115); // [ var(124) , var(116) ]
+                D[5,125] = (-1)*var(245); // [ var(125) , var(5) ]
+                D[12,125] = var(4); // [ var(125) , var(12) ]
+                D[13,125] = (-1)*var(6); // [ var(125) , var(13) ]
+                D[18,125] = var(10); // [ var(125) , var(18) ]
+                D[19,125] = var(11); // [ var(125) , var(19) ]
+                D[21,125] = (-1)*var(14); // [ var(125) , var(21) ]
+                D[24,125] = var(16); // [ var(125) , var(24) ]
+                D[25,125] = var(17); // [ var(125) , var(25) ]
+                D[29,125] = (-1)*var(22); // [ var(125) , var(29) ]
+                D[30,125] = var(23); // [ var(125) , var(30) ]
+                D[48,125] = var(40); // [ var(125) , var(48) ]
+                D[52,125] = var(45); // [ var(125) , var(52) ]
+                D[55,125] = var(49); // [ var(125) , var(55) ]
+                D[57,125] = var(51); // [ var(125) , var(57) ]
+                D[59,125] = var(53); // [ var(125) , var(59) ]
+                D[62,125] = var(56); // [ var(125) , var(62) ]
+                D[64,125] = var(58); // [ var(125) , var(64) ]
+                D[67,125] = var(60); // [ var(125) , var(67) ]
+                D[72,125] = var(65); // [ var(125) , var(72) ]
+                D[82,125] = var(76); // [ var(125) , var(82) ]
+                D[85,125] = var(80); // [ var(125) , var(85) ]
+                D[87,125] = var(83); // [ var(125) , var(87) ]
+                D[90,125] = var(86); // [ var(125) , var(90) ]
+                D[92,125] = var(88); // [ var(125) , var(92) ]
+                D[95,125] = var(91); // [ var(125) , var(95) ]
+                D[106,125] = var(103); // [ var(125) , var(106) ]
+                D[108,125] = var(105); // [ var(125) , var(108) ]
+                D[109,125] = var(107); // [ var(125) , var(109) ]
+                D[117,125] = (-1)*var(116); // [ var(125) , var(117) ]
+                D[6,126] = (-1)*var(246); // [ var(126) , var(6) ]
+                D[13,126] = var(5); // [ var(126) , var(13) ]
+                D[14,126] = (-1)*var(7); // [ var(126) , var(14) ]
+                D[20,126] = var(12); // [ var(126) , var(20) ]
+                D[22,126] = (-1)*var(15); // [ var(126) , var(22) ]
+                D[26,126] = var(18); // [ var(126) , var(26) ]
+                D[27,126] = var(19); // [ var(126) , var(27) ]
+                D[31,126] = var(24); // [ var(126) , var(31) ]
+                D[33,126] = var(25); // [ var(126) , var(33) ]
+                D[38,126] = var(30); // [ var(126) , var(38) ]
+                D[40,126] = var(32); // [ var(126) , var(40) ]
+                D[45,126] = var(37); // [ var(126) , var(45) ]
+                D[51,126] = var(44); // [ var(126) , var(51) ]
+                D[61,126] = var(55); // [ var(126) , var(61) ]
+                D[66,126] = var(59); // [ var(126) , var(66) ]
+                D[68,126] = var(62); // [ var(126) , var(68) ]
+                D[71,126] = var(64); // [ var(126) , var(71) ]
+                D[73,126] = var(67); // [ var(126) , var(73) ]
+                D[76,126] = var(70); // [ var(126) , var(76) ]
+                D[78,126] = var(72); // [ var(126) , var(78) ]
+                D[80,126] = var(75); // [ var(126) , var(80) ]
+                D[83,126] = var(77); // [ var(126) , var(83) ]
+                D[86,126] = var(81); // [ var(126) , var(86) ]
+                D[96,126] = var(92); // [ var(126) , var(96) ]
+                D[100,126] = var(95); // [ var(126) , var(100) ]
+                D[103,126] = var(99); // [ var(126) , var(103) ]
+                D[105,126] = var(102); // [ var(126) , var(105) ]
+                D[107,126] = var(104); // [ var(126) , var(107) ]
+                D[118,126] = (-1)*var(117); // [ var(126) , var(118) ]
+                D[7,127] = (-1)*var(247); // [ var(127) , var(7) ]
+                D[14,127] = var(6); // [ var(127) , var(14) ]
+                D[15,127] = (-1)*var(8); // [ var(127) , var(15) ]
+                D[21,127] = var(13); // [ var(127) , var(21) ]
+                D[28,127] = var(20); // [ var(127) , var(28) ]
+                D[34,127] = var(26); // [ var(127) , var(34) ]
+                D[35,127] = var(27); // [ var(127) , var(35) ]
+                D[39,127] = var(31); // [ var(127) , var(39) ]
+                D[41,127] = var(33); // [ var(127) , var(41) ]
+                D[46,127] = var(38); // [ var(127) , var(46) ]
+                D[49,127] = var(40); // [ var(127) , var(49) ]
+                D[53,127] = var(45); // [ var(127) , var(53) ]
+                D[55,127] = var(48); // [ var(127) , var(55) ]
+                D[58,127] = var(51); // [ var(127) , var(58) ]
+                D[59,127] = var(52); // [ var(127) , var(59) ]
+                D[64,127] = var(57); // [ var(127) , var(64) ]
+                D[70,127] = var(63); // [ var(127) , var(70) ]
+                D[74,127] = var(68); // [ var(127) , var(74) ]
+                D[75,127] = var(69); // [ var(127) , var(75) ]
+                D[79,127] = var(73); // [ var(127) , var(79) ]
+                D[84,127] = var(78); // [ var(127) , var(84) ]
+                D[88,127] = var(83); // [ var(127) , var(88) ]
+                D[91,127] = var(86); // [ var(127) , var(91) ]
+                D[92,127] = var(87); // [ var(127) , var(92) ]
+                D[95,127] = var(90); // [ var(127) , var(95) ]
+                D[99,127] = var(94); // [ var(127) , var(99) ]
+                D[102,127] = var(98); // [ var(127) , var(102) ]
+                D[104,127] = var(101); // [ var(127) , var(104) ]
+                D[119,127] = (-1)*var(118); // [ var(127) , var(119) ]
+                D[8,128] = (-1)*var(248); // [ var(128) , var(8) ]
+                D[15,128] = var(7); // [ var(128) , var(15) ]
+                D[22,128] = var(14); // [ var(128) , var(22) ]
+                D[29,128] = var(21); // [ var(128) , var(29) ]
+                D[36,128] = var(28); // [ var(128) , var(36) ]
+                D[42,128] = var(34); // [ var(128) , var(42) ]
+                D[43,128] = var(35); // [ var(128) , var(43) ]
+                D[47,128] = var(39); // [ var(128) , var(47) ]
+                D[50,128] = var(41); // [ var(128) , var(50) ]
+                D[54,128] = var(46); // [ var(128) , var(54) ]
+                D[56,128] = var(49); // [ var(128) , var(56) ]
+                D[60,128] = var(53); // [ var(128) , var(60) ]
+                D[62,128] = var(55); // [ var(128) , var(62) ]
+                D[65,128] = var(58); // [ var(128) , var(65) ]
+                D[67,128] = var(59); // [ var(128) , var(67) ]
+                D[68,128] = var(61); // [ var(128) , var(68) ]
+                D[72,128] = var(64); // [ var(128) , var(72) ]
+                D[73,128] = var(66); // [ var(128) , var(73) ]
+                D[77,128] = var(70); // [ var(128) , var(77) ]
+                D[78,128] = var(71); // [ var(128) , var(78) ]
+                D[81,128] = var(75); // [ var(128) , var(81) ]
+                D[83,128] = var(76); // [ var(128) , var(83) ]
+                D[86,128] = var(80); // [ var(128) , var(86) ]
+                D[87,128] = var(82); // [ var(128) , var(87) ]
+                D[90,128] = var(85); // [ var(128) , var(90) ]
+                D[94,128] = var(89); // [ var(128) , var(94) ]
+                D[98,128] = var(93); // [ var(128) , var(98) ]
+                D[101,128] = var(97); // [ var(128) , var(101) ]
+                D[120,128] = (-1)*var(119); // [ var(128) , var(120) ]
+                D[1,129] = (-1)*var(123); // [ var(129) , var(1) ]
+                D[3,129] = var(121); // [ var(129) , var(3) ]
+                D[9,129] = (-1)*var(241)+(-1)*var(243); // [ var(129) , var(9) ]
+                D[16,129] = (-1)*var(4); // [ var(129) , var(16) ]
+                D[23,129] = (-1)*var(10); // [ var(129) , var(23) ]
+                D[24,129] = (-1)*var(12); // [ var(129) , var(24) ]
+                D[30,129] = (-1)*var(18); // [ var(129) , var(30) ]
+                D[31,129] = (-1)*var(20); // [ var(129) , var(31) ]
+                D[38,129] = (-1)*var(26); // [ var(129) , var(38) ]
+                D[39,129] = (-1)*var(28); // [ var(129) , var(39) ]
+                D[44,129] = var(32); // [ var(129) , var(44) ]
+                D[46,129] = (-1)*var(34); // [ var(129) , var(46) ]
+                D[47,129] = (-1)*var(36); // [ var(129) , var(47) ]
+                D[51,129] = var(40); // [ var(129) , var(51) ]
+                D[54,129] = (-1)*var(42); // [ var(129) , var(54) ]
+                D[57,129] = var(48); // [ var(129) , var(57) ]
+                D[58,129] = var(49); // [ var(129) , var(58) ]
+                D[64,129] = var(55); // [ var(129) , var(64) ]
+                D[65,129] = var(56); // [ var(129) , var(65) ]
+                D[71,129] = var(61); // [ var(129) , var(71) ]
+                D[72,129] = var(62); // [ var(129) , var(72) ]
+                D[78,129] = var(68); // [ var(129) , var(78) ]
+                D[84,129] = var(74); // [ var(129) , var(84) ]
+                D[97,129] = (-1)*var(89); // [ var(129) , var(97) ]
+                D[101,129] = (-1)*var(94); // [ var(129) , var(101) ]
+                D[104,129] = (-1)*var(99); // [ var(129) , var(104) ]
+                D[107,129] = (-1)*var(103); // [ var(129) , var(107) ]
+                D[109,129] = (-1)*var(106); // [ var(129) , var(109) ]
+                D[114,129] = var(110); // [ var(129) , var(114) ]
+                D[115,129] = var(112); // [ var(129) , var(115) ]
+                D[2,130] = (-1)*var(124); // [ var(130) , var(2) ]
+                D[4,130] = var(122); // [ var(130) , var(4) ]
+                D[10,130] = (-1)*var(242)+(-1)*var(244); // [ var(130) , var(10) ]
+                D[17,130] = var(3); // [ var(130) , var(17) ]
+                D[18,130] = (-1)*var(5); // [ var(130) , var(18) ]
+                D[23,130] = var(9); // [ var(130) , var(23) ]
+                D[26,130] = (-1)*var(13); // [ var(130) , var(26) ]
+                D[32,130] = (-1)*var(19); // [ var(130) , var(32) ]
+                D[34,130] = (-1)*var(21); // [ var(130) , var(34) ]
+                D[37,130] = (-1)*var(24); // [ var(130) , var(37) ]
+                D[40,130] = (-1)*var(27); // [ var(130) , var(40) ]
+                D[42,130] = (-1)*var(29); // [ var(130) , var(42) ]
+                D[45,130] = (-1)*var(31); // [ var(130) , var(45) ]
+                D[49,130] = (-1)*var(35); // [ var(130) , var(49) ]
+                D[53,130] = (-1)*var(39); // [ var(130) , var(53) ]
+                D[56,130] = (-1)*var(43); // [ var(130) , var(56) ]
+                D[60,130] = (-1)*var(47); // [ var(130) , var(60) ]
+                D[69,130] = (-1)*var(57); // [ var(130) , var(69) ]
+                D[75,130] = (-1)*var(64); // [ var(130) , var(75) ]
+                D[80,130] = (-1)*var(71); // [ var(130) , var(80) ]
+                D[81,130] = (-1)*var(72); // [ var(130) , var(81) ]
+                D[86,130] = (-1)*var(78); // [ var(130) , var(86) ]
+                D[89,130] = var(82); // [ var(130) , var(89) ]
+                D[91,130] = (-1)*var(84); // [ var(130) , var(91) ]
+                D[94,130] = var(87); // [ var(130) , var(94) ]
+                D[99,130] = var(92); // [ var(130) , var(99) ]
+                D[103,130] = var(96); // [ var(130) , var(103) ]
+                D[112,130] = var(108); // [ var(130) , var(112) ]
+                D[113,130] = var(109); // [ var(130) , var(113) ]
+                D[116,130] = var(114); // [ var(130) , var(116) ]
+                D[3,131] = (-1)*var(124); // [ var(131) , var(3) ]
+                D[4,131] = var(123); // [ var(131) , var(4) ]
+                D[11,131] = (-1)*var(243)+(-1)*var(244); // [ var(131) , var(11) ]
+                D[16,131] = var(1); // [ var(131) , var(16) ]
+                D[17,131] = var(2); // [ var(131) , var(17) ]
+                D[19,131] = (-1)*var(5); // [ var(131) , var(19) ]
+                D[27,131] = (-1)*var(13); // [ var(131) , var(27) ]
+                D[32,131] = (-1)*var(18); // [ var(131) , var(32) ]
+                D[35,131] = (-1)*var(21); // [ var(131) , var(35) ]
+                D[40,131] = (-1)*var(26); // [ var(131) , var(40) ]
+                D[43,131] = (-1)*var(29); // [ var(131) , var(43) ]
+                D[44,131] = var(30); // [ var(131) , var(44) ]
+                D[49,131] = (-1)*var(34); // [ var(131) , var(49) ]
+                D[51,131] = var(38); // [ var(131) , var(51) ]
+                D[56,131] = (-1)*var(42); // [ var(131) , var(56) ]
+                D[58,131] = var(46); // [ var(131) , var(58) ]
+                D[63,131] = (-1)*var(52); // [ var(131) , var(63) ]
+                D[65,131] = var(54); // [ var(131) , var(65) ]
+                D[70,131] = (-1)*var(59); // [ var(131) , var(70) ]
+                D[76,131] = (-1)*var(66); // [ var(131) , var(76) ]
+                D[77,131] = (-1)*var(67); // [ var(131) , var(77) ]
+                D[83,131] = (-1)*var(73); // [ var(131) , var(83) ]
+                D[88,131] = (-1)*var(79); // [ var(131) , var(88) ]
+                D[93,131] = (-1)*var(85); // [ var(131) , var(93) ]
+                D[98,131] = (-1)*var(90); // [ var(131) , var(98) ]
+                D[102,131] = (-1)*var(95); // [ var(131) , var(102) ]
+                D[105,131] = (-1)*var(100); // [ var(131) , var(105) ]
+                D[110,131] = var(106); // [ var(131) , var(110) ]
+                D[114,131] = (-1)*var(109); // [ var(131) , var(114) ]
+                D[116,131] = (-1)*var(113); // [ var(131) , var(116) ]
+                D[4,132] = (-1)*var(125); // [ var(132) , var(4) ]
+                D[5,132] = var(124); // [ var(132) , var(5) ]
+                D[12,132] = (-1)*var(244)+(-1)*var(245); // [ var(132) , var(12) ]
+                D[18,132] = var(2); // [ var(132) , var(18) ]
+                D[19,132] = var(3); // [ var(132) , var(19) ]
+                D[20,132] = (-1)*var(6); // [ var(132) , var(20) ]
+                D[24,132] = var(9); // [ var(132) , var(24) ]
+                D[28,132] = (-1)*var(14); // [ var(132) , var(28) ]
+                D[32,132] = (-1)*var(17); // [ var(132) , var(32) ]
+                D[36,132] = (-1)*var(22); // [ var(132) , var(36) ]
+                D[37,132] = (-1)*var(23); // [ var(132) , var(37) ]
+                D[48,132] = var(33); // [ var(132) , var(48) ]
+                D[52,132] = var(38); // [ var(132) , var(52) ]
+                D[55,132] = var(41); // [ var(132) , var(55) ]
+                D[59,132] = var(46); // [ var(132) , var(59) ]
+                D[62,132] = var(50); // [ var(132) , var(62) ]
+                D[63,132] = (-1)*var(51); // [ var(132) , var(63) ]
+                D[67,132] = var(54); // [ var(132) , var(67) ]
+                D[70,132] = (-1)*var(58); // [ var(132) , var(70) ]
+                D[77,132] = (-1)*var(65); // [ var(132) , var(77) ]
+                D[82,132] = var(71); // [ var(132) , var(82) ]
+                D[87,132] = var(78); // [ var(132) , var(87) ]
+                D[89,132] = (-1)*var(80); // [ var(132) , var(89) ]
+                D[92,132] = var(84); // [ var(132) , var(92) ]
+                D[94,132] = (-1)*var(86); // [ var(132) , var(94) ]
+                D[99,132] = (-1)*var(91); // [ var(132) , var(99) ]
+                D[106,132] = var(100); // [ var(132) , var(106) ]
+                D[110,132] = (-1)*var(105); // [ var(132) , var(110) ]
+                D[111,132] = (-1)*var(107); // [ var(132) , var(111) ]
+                D[117,132] = var(115); // [ var(132) , var(117) ]
+                D[5,133] = (-1)*var(126); // [ var(133) , var(5) ]
+                D[6,133] = var(125); // [ var(133) , var(6) ]
+                D[13,133] = (-1)*var(245)+(-1)*var(246); // [ var(133) , var(13) ]
+                D[20,133] = var(4); // [ var(133) , var(20) ]
+                D[21,133] = (-1)*var(7); // [ var(133) , var(21) ]
+                D[26,133] = var(10); // [ var(133) , var(26) ]
+                D[27,133] = var(11); // [ var(133) , var(27) ]
+                D[29,133] = (-1)*var(15); // [ var(133) , var(29) ]
+                D[31,133] = var(16); // [ var(133) , var(31) ]
+                D[33,133] = var(17); // [ var(133) , var(33) ]
+                D[38,133] = var(23); // [ var(133) , var(38) ]
+                D[48,133] = (-1)*var(32); // [ var(133) , var(48) ]
+                D[52,133] = (-1)*var(37); // [ var(133) , var(52) ]
+                D[57,133] = (-1)*var(44); // [ var(133) , var(57) ]
+                D[61,133] = var(49); // [ var(133) , var(61) ]
+                D[66,133] = var(53); // [ var(133) , var(66) ]
+                D[68,133] = var(56); // [ var(133) , var(68) ]
+                D[71,133] = var(58); // [ var(133) , var(71) ]
+                D[73,133] = var(60); // [ var(133) , var(73) ]
+                D[78,133] = var(65); // [ var(133) , var(78) ]
+                D[82,133] = (-1)*var(70); // [ var(133) , var(82) ]
+                D[85,133] = (-1)*var(75); // [ var(133) , var(85) ]
+                D[87,133] = (-1)*var(77); // [ var(133) , var(87) ]
+                D[90,133] = (-1)*var(81); // [ var(133) , var(90) ]
+                D[96,133] = var(88); // [ var(133) , var(96) ]
+                D[100,133] = var(91); // [ var(133) , var(100) ]
+                D[106,133] = (-1)*var(99); // [ var(133) , var(106) ]
+                D[108,133] = (-1)*var(102); // [ var(133) , var(108) ]
+                D[109,133] = (-1)*var(104); // [ var(133) , var(109) ]
+                D[118,133] = var(116); // [ var(133) , var(118) ]
+                D[6,134] = (-1)*var(127); // [ var(134) , var(6) ]
+                D[7,134] = var(126); // [ var(134) , var(7) ]
+                D[14,134] = (-1)*var(246)+(-1)*var(247); // [ var(134) , var(14) ]
+                D[21,134] = var(5); // [ var(134) , var(21) ]
+                D[22,134] = (-1)*var(8); // [ var(134) , var(22) ]
+                D[28,134] = var(12); // [ var(134) , var(28) ]
+                D[34,134] = var(18); // [ var(134) , var(34) ]
+                D[35,134] = var(19); // [ var(134) , var(35) ]
+                D[39,134] = var(24); // [ var(134) , var(39) ]
+                D[41,134] = var(25); // [ var(134) , var(41) ]
+                D[46,134] = var(30); // [ var(134) , var(46) ]
+                D[49,134] = var(32); // [ var(134) , var(49) ]
+                D[53,134] = var(37); // [ var(134) , var(53) ]
+                D[58,134] = var(44); // [ var(134) , var(58) ]
+                D[61,134] = (-1)*var(48); // [ var(134) , var(61) ]
+                D[66,134] = (-1)*var(52); // [ var(134) , var(66) ]
+                D[71,134] = (-1)*var(57); // [ var(134) , var(71) ]
+                D[74,134] = var(62); // [ var(134) , var(74) ]
+                D[76,134] = (-1)*var(63); // [ var(134) , var(76) ]
+                D[79,134] = var(67); // [ var(134) , var(79) ]
+                D[80,134] = (-1)*var(69); // [ var(134) , var(80) ]
+                D[84,134] = var(72); // [ var(134) , var(84) ]
+                D[88,134] = var(77); // [ var(134) , var(88) ]
+                D[91,134] = var(81); // [ var(134) , var(91) ]
+                D[96,134] = (-1)*var(87); // [ var(134) , var(96) ]
+                D[100,134] = (-1)*var(90); // [ var(134) , var(100) ]
+                D[103,134] = (-1)*var(94); // [ var(134) , var(103) ]
+                D[105,134] = (-1)*var(98); // [ var(134) , var(105) ]
+                D[107,134] = (-1)*var(101); // [ var(134) , var(107) ]
+                D[119,134] = var(117); // [ var(134) , var(119) ]
+                D[7,135] = (-1)*var(128); // [ var(135) , var(7) ]
+                D[8,135] = var(127); // [ var(135) , var(8) ]
+                D[15,135] = (-1)*var(247)+(-1)*var(248); // [ var(135) , var(15) ]
+                D[22,135] = var(6); // [ var(135) , var(22) ]
+                D[29,135] = var(13); // [ var(135) , var(29) ]
+                D[36,135] = var(20); // [ var(135) , var(36) ]
+                D[42,135] = var(26); // [ var(135) , var(42) ]
+                D[43,135] = var(27); // [ var(135) , var(43) ]
+                D[47,135] = var(31); // [ var(135) , var(47) ]
+                D[50,135] = var(33); // [ var(135) , var(50) ]
+                D[54,135] = var(38); // [ var(135) , var(54) ]
+                D[56,135] = var(40); // [ var(135) , var(56) ]
+                D[60,135] = var(45); // [ var(135) , var(60) ]
+                D[62,135] = var(48); // [ var(135) , var(62) ]
+                D[65,135] = var(51); // [ var(135) , var(65) ]
+                D[67,135] = var(52); // [ var(135) , var(67) ]
+                D[72,135] = var(57); // [ var(135) , var(72) ]
+                D[74,135] = (-1)*var(61); // [ var(135) , var(74) ]
+                D[77,135] = var(63); // [ var(135) , var(77) ]
+                D[79,135] = (-1)*var(66); // [ var(135) , var(79) ]
+                D[81,135] = var(69); // [ var(135) , var(81) ]
+                D[84,135] = (-1)*var(71); // [ var(135) , var(84) ]
+                D[88,135] = (-1)*var(76); // [ var(135) , var(88) ]
+                D[91,135] = (-1)*var(80); // [ var(135) , var(91) ]
+                D[92,135] = (-1)*var(82); // [ var(135) , var(92) ]
+                D[95,135] = (-1)*var(85); // [ var(135) , var(95) ]
+                D[99,135] = (-1)*var(89); // [ var(135) , var(99) ]
+                D[102,135] = (-1)*var(93); // [ var(135) , var(102) ]
+                D[104,135] = (-1)*var(97); // [ var(135) , var(104) ]
+                D[120,135] = var(118); // [ var(135) , var(120) ]
+                D[1,136] = (-1)*var(131); // [ var(136) , var(1) ]
+                D[4,136] = var(129); // [ var(136) , var(4) ]
+                D[9,136] = (-1)*var(124); // [ var(136) , var(9) ]
+                D[11,136] = var(121); // [ var(136) , var(11) ]
+                D[16,136] = (-1)*var(241)+(-1)*var(243)+(-1)*var(244); // [ var(136) , var(16) ]
+                D[23,136] = var(2); // [ var(136) , var(23) ]
+                D[24,136] = (-1)*var(5); // [ var(136) , var(24) ]
+                D[31,136] = (-1)*var(13); // [ var(136) , var(31) ]
+                D[37,136] = (-1)*var(18); // [ var(136) , var(37) ]
+                D[39,136] = (-1)*var(21); // [ var(136) , var(39) ]
+                D[44,136] = (-1)*var(25); // [ var(136) , var(44) ]
+                D[45,136] = (-1)*var(26); // [ var(136) , var(45) ]
+                D[47,136] = (-1)*var(29); // [ var(136) , var(47) ]
+                D[51,136] = (-1)*var(33); // [ var(136) , var(51) ]
+                D[53,136] = (-1)*var(34); // [ var(136) , var(53) ]
+                D[58,136] = (-1)*var(41); // [ var(136) , var(58) ]
+                D[60,136] = (-1)*var(42); // [ var(136) , var(60) ]
+                D[63,136] = var(48); // [ var(136) , var(63) ]
+                D[65,136] = (-1)*var(50); // [ var(136) , var(65) ]
+                D[70,136] = var(55); // [ var(136) , var(70) ]
+                D[76,136] = var(61); // [ var(136) , var(76) ]
+                D[77,136] = var(62); // [ var(136) , var(77) ]
+                D[83,136] = var(68); // [ var(136) , var(83) ]
+                D[88,136] = var(74); // [ var(136) , var(88) ]
+                D[97,136] = var(85); // [ var(136) , var(97) ]
+                D[101,136] = var(90); // [ var(136) , var(101) ]
+                D[104,136] = var(95); // [ var(136) , var(104) ]
+                D[107,136] = var(100); // [ var(136) , var(107) ]
+                D[111,136] = (-1)*var(106); // [ var(136) , var(111) ]
+                D[114,136] = (-1)*var(108); // [ var(136) , var(114) ]
+                D[116,136] = (-1)*var(112); // [ var(136) , var(116) ]
+                D[2,137] = (-1)*var(131); // [ var(137) , var(2) ]
+                D[3,137] = (-1)*var(130); // [ var(137) , var(3) ]
+                D[10,137] = var(123); // [ var(137) , var(10) ]
+                D[11,137] = var(122); // [ var(137) , var(11) ]
+                D[17,137] = (-1)*var(242)+(-1)*var(243)+(-1)*var(244); // [ var(137) , var(17) ]
+                D[23,137] = var(1); // [ var(137) , var(23) ]
+                D[25,137] = (-1)*var(5); // [ var(137) , var(25) ]
+                D[32,137] = var(12); // [ var(137) , var(32) ]
+                D[33,137] = (-1)*var(13); // [ var(137) , var(33) ]
+                D[40,137] = var(20); // [ var(137) , var(40) ]
+                D[41,137] = (-1)*var(21); // [ var(137) , var(41) ]
+                D[44,137] = (-1)*var(24); // [ var(137) , var(44) ]
+                D[49,137] = var(28); // [ var(137) , var(49) ]
+                D[50,137] = (-1)*var(29); // [ var(137) , var(50) ]
+                D[51,137] = (-1)*var(31); // [ var(137) , var(51) ]
+                D[56,137] = var(36); // [ var(137) , var(56) ]
+                D[58,137] = (-1)*var(39); // [ var(137) , var(58) ]
+                D[65,137] = (-1)*var(47); // [ var(137) , var(65) ]
+                D[69,137] = var(52); // [ var(137) , var(69) ]
+                D[75,137] = var(59); // [ var(137) , var(75) ]
+                D[80,137] = var(66); // [ var(137) , var(80) ]
+                D[81,137] = var(67); // [ var(137) , var(81) ]
+                D[86,137] = var(73); // [ var(137) , var(86) ]
+                D[91,137] = var(79); // [ var(137) , var(91) ]
+                D[93,137] = (-1)*var(82); // [ var(137) , var(93) ]
+                D[98,137] = (-1)*var(87); // [ var(137) , var(98) ]
+                D[102,137] = (-1)*var(92); // [ var(137) , var(102) ]
+                D[105,137] = (-1)*var(96); // [ var(137) , var(105) ]
+                D[112,137] = var(106); // [ var(137) , var(112) ]
+                D[115,137] = (-1)*var(109); // [ var(137) , var(115) ]
+                D[116,137] = var(111); // [ var(137) , var(116) ]
+                D[2,138] = (-1)*var(132); // [ var(138) , var(2) ]
+                D[5,138] = var(130); // [ var(138) , var(5) ]
+                D[10,138] = (-1)*var(125); // [ var(138) , var(10) ]
+                D[12,138] = var(122); // [ var(138) , var(12) ]
+                D[18,138] = (-1)*var(242)+(-1)*var(244)+(-1)*var(245); // [ var(138) , var(18) ]
+                D[25,138] = var(3); // [ var(138) , var(25) ]
+                D[26,138] = (-1)*var(6); // [ var(138) , var(26) ]
+                D[30,138] = var(9); // [ var(138) , var(30) ]
+                D[32,138] = var(11); // [ var(138) , var(32) ]
+                D[34,138] = (-1)*var(14); // [ var(138) , var(34) ]
+                D[37,138] = var(16); // [ var(138) , var(37) ]
+                D[42,138] = (-1)*var(22); // [ var(138) , var(42) ]
+                D[48,138] = (-1)*var(27); // [ var(138) , var(48) ]
+                D[52,138] = (-1)*var(31); // [ var(138) , var(52) ]
+                D[55,138] = (-1)*var(35); // [ var(138) , var(55) ]
+                D[59,138] = (-1)*var(39); // [ var(138) , var(59) ]
+                D[62,138] = (-1)*var(43); // [ var(138) , var(62) ]
+                D[67,138] = (-1)*var(47); // [ var(138) , var(67) ]
+                D[69,138] = var(51); // [ var(138) , var(69) ]
+                D[75,138] = var(58); // [ var(138) , var(75) ]
+                D[81,138] = var(65); // [ var(138) , var(81) ]
+                D[85,138] = (-1)*var(71); // [ var(138) , var(85) ]
+                D[89,138] = (-1)*var(76); // [ var(138) , var(89) ]
+                D[90,138] = (-1)*var(78); // [ var(138) , var(90) ]
+                D[94,138] = (-1)*var(83); // [ var(138) , var(94) ]
+                D[95,138] = (-1)*var(84); // [ var(138) , var(95) ]
+                D[99,138] = (-1)*var(88); // [ var(138) , var(99) ]
+                D[106,138] = var(96); // [ var(138) , var(106) ]
+                D[112,138] = (-1)*var(105); // [ var(138) , var(112) ]
+                D[113,138] = (-1)*var(107); // [ var(138) , var(113) ]
+                D[117,138] = (-1)*var(114); // [ var(138) , var(117) ]
+                D[3,139] = (-1)*var(132); // [ var(139) , var(3) ]
+                D[5,139] = var(131); // [ var(139) , var(5) ]
+                D[11,139] = (-1)*var(125); // [ var(139) , var(11) ]
+                D[12,139] = var(123); // [ var(139) , var(12) ]
+                D[19,139] = (-1)*var(243)+(-1)*var(244)+(-1)*var(245); // [ var(139) , var(19) ]
+                D[24,139] = var(1); // [ var(139) , var(24) ]
+                D[25,139] = var(2); // [ var(139) , var(25) ]
+                D[27,139] = (-1)*var(6); // [ var(139) , var(27) ]
+                D[32,139] = var(10); // [ var(139) , var(32) ]
+                D[35,139] = (-1)*var(14); // [ var(139) , var(35) ]
+                D[43,139] = (-1)*var(22); // [ var(139) , var(43) ]
+                D[44,139] = (-1)*var(23); // [ var(139) , var(44) ]
+                D[48,139] = (-1)*var(26); // [ var(139) , var(48) ]
+                D[55,139] = (-1)*var(34); // [ var(139) , var(55) ]
+                D[57,139] = var(38); // [ var(139) , var(57) ]
+                D[62,139] = (-1)*var(42); // [ var(139) , var(62) ]
+                D[63,139] = var(45); // [ var(139) , var(63) ]
+                D[64,139] = var(46); // [ var(139) , var(64) ]
+                D[70,139] = var(53); // [ var(139) , var(70) ]
+                D[72,139] = var(54); // [ var(139) , var(72) ]
+                D[77,139] = var(60); // [ var(139) , var(77) ]
+                D[82,139] = (-1)*var(66); // [ var(139) , var(82) ]
+                D[87,139] = (-1)*var(73); // [ var(139) , var(87) ]
+                D[92,139] = (-1)*var(79); // [ var(139) , var(92) ]
+                D[93,139] = var(80); // [ var(139) , var(93) ]
+                D[98,139] = var(86); // [ var(139) , var(98) ]
+                D[102,139] = var(91); // [ var(139) , var(102) ]
+                D[108,139] = (-1)*var(100); // [ var(139) , var(108) ]
+                D[110,139] = (-1)*var(103); // [ var(139) , var(110) ]
+                D[114,139] = var(107); // [ var(139) , var(114) ]
+                D[117,139] = var(113); // [ var(139) , var(117) ]
+                D[4,140] = (-1)*var(133); // [ var(140) , var(4) ]
+                D[6,140] = var(132); // [ var(140) , var(6) ]
+                D[12,140] = (-1)*var(126); // [ var(140) , var(12) ]
+                D[13,140] = var(124); // [ var(140) , var(13) ]
+                D[20,140] = (-1)*var(244)+(-1)*var(245)+(-1)*var(246); // [ var(140) , var(20) ]
+                D[26,140] = var(2); // [ var(140) , var(26) ]
+                D[27,140] = var(3); // [ var(140) , var(27) ]
+                D[28,140] = (-1)*var(7); // [ var(140) , var(28) ]
+                D[31,140] = var(9); // [ var(140) , var(31) ]
+                D[36,140] = (-1)*var(15); // [ var(140) , var(36) ]
+                D[40,140] = (-1)*var(17); // [ var(140) , var(40) ]
+                D[45,140] = (-1)*var(23); // [ var(140) , var(45) ]
+                D[48,140] = (-1)*var(25); // [ var(140) , var(48) ]
+                D[52,140] = (-1)*var(30); // [ var(140) , var(52) ]
+                D[61,140] = var(41); // [ var(140) , var(61) ]
+                D[63,140] = var(44); // [ var(140) , var(63) ]
+                D[66,140] = var(46); // [ var(140) , var(66) ]
+                D[68,140] = var(50); // [ var(140) , var(68) ]
+                D[73,140] = var(54); // [ var(140) , var(73) ]
+                D[76,140] = (-1)*var(58); // [ var(140) , var(76) ]
+                D[82,140] = (-1)*var(64); // [ var(140) , var(82) ]
+                D[83,140] = (-1)*var(65); // [ var(140) , var(83) ]
+                D[87,140] = (-1)*var(72); // [ var(140) , var(87) ]
+                D[89,140] = var(75); // [ var(140) , var(89) ]
+                D[94,140] = var(81); // [ var(140) , var(94) ]
+                D[96,140] = var(84); // [ var(140) , var(96) ]
+                D[103,140] = (-1)*var(91); // [ var(140) , var(103) ]
+                D[106,140] = (-1)*var(95); // [ var(140) , var(106) ]
+                D[110,140] = var(102); // [ var(140) , var(110) ]
+                D[111,140] = var(104); // [ var(140) , var(111) ]
+                D[118,140] = (-1)*var(115); // [ var(140) , var(118) ]
+                D[5,141] = (-1)*var(134); // [ var(141) , var(5) ]
+                D[7,141] = var(133); // [ var(141) , var(7) ]
+                D[13,141] = (-1)*var(127); // [ var(141) , var(13) ]
+                D[14,141] = var(125); // [ var(141) , var(14) ]
+                D[21,141] = (-1)*var(245)+(-1)*var(246)+(-1)*var(247); // [ var(141) , var(21) ]
+                D[28,141] = var(4); // [ var(141) , var(28) ]
+                D[29,141] = (-1)*var(8); // [ var(141) , var(29) ]
+                D[34,141] = var(10); // [ var(141) , var(34) ]
+                D[35,141] = var(11); // [ var(141) , var(35) ]
+                D[39,141] = var(16); // [ var(141) , var(39) ]
+                D[41,141] = var(17); // [ var(141) , var(41) ]
+                D[46,141] = var(23); // [ var(141) , var(46) ]
+                D[55,141] = (-1)*var(32); // [ var(141) , var(55) ]
+                D[59,141] = (-1)*var(37); // [ var(141) , var(59) ]
+                D[61,141] = (-1)*var(40); // [ var(141) , var(61) ]
+                D[64,141] = (-1)*var(44); // [ var(141) , var(64) ]
+                D[66,141] = (-1)*var(45); // [ var(141) , var(66) ]
+                D[71,141] = (-1)*var(51); // [ var(141) , var(71) ]
+                D[74,141] = var(56); // [ var(141) , var(74) ]
+                D[79,141] = var(60); // [ var(141) , var(79) ]
+                D[82,141] = var(63); // [ var(141) , var(82) ]
+                D[84,141] = var(65); // [ var(141) , var(84) ]
+                D[85,141] = var(69); // [ var(141) , var(85) ]
+                D[92,141] = (-1)*var(77); // [ var(141) , var(92) ]
+                D[95,141] = (-1)*var(81); // [ var(141) , var(95) ]
+                D[96,141] = (-1)*var(83); // [ var(141) , var(96) ]
+                D[100,141] = (-1)*var(86); // [ var(141) , var(100) ]
+                D[106,141] = var(94); // [ var(141) , var(106) ]
+                D[108,141] = var(98); // [ var(141) , var(108) ]
+                D[109,141] = var(101); // [ var(141) , var(109) ]
+                D[119,141] = (-1)*var(116); // [ var(141) , var(119) ]
+                D[6,142] = (-1)*var(135); // [ var(142) , var(6) ]
+                D[8,142] = var(134); // [ var(142) , var(8) ]
+                D[14,142] = (-1)*var(128); // [ var(142) , var(14) ]
+                D[15,142] = var(126); // [ var(142) , var(15) ]
+                D[22,142] = (-1)*var(246)+(-1)*var(247)+(-1)*var(248); // [ var(142) , var(22) ]
+                D[29,142] = var(5); // [ var(142) , var(29) ]
+                D[36,142] = var(12); // [ var(142) , var(36) ]
+                D[42,142] = var(18); // [ var(142) , var(42) ]
+                D[43,142] = var(19); // [ var(142) , var(43) ]
+                D[47,142] = var(24); // [ var(142) , var(47) ]
+                D[50,142] = var(25); // [ var(142) , var(50) ]
+                D[54,142] = var(30); // [ var(142) , var(54) ]
+                D[56,142] = var(32); // [ var(142) , var(56) ]
+                D[60,142] = var(37); // [ var(142) , var(60) ]
+                D[65,142] = var(44); // [ var(142) , var(65) ]
+                D[68,142] = (-1)*var(48); // [ var(142) , var(68) ]
+                D[73,142] = (-1)*var(52); // [ var(142) , var(73) ]
+                D[74,142] = (-1)*var(55); // [ var(142) , var(74) ]
+                D[78,142] = (-1)*var(57); // [ var(142) , var(78) ]
+                D[79,142] = (-1)*var(59); // [ var(142) , var(79) ]
+                D[83,142] = (-1)*var(63); // [ var(142) , var(83) ]
+                D[84,142] = (-1)*var(64); // [ var(142) , var(84) ]
+                D[86,142] = (-1)*var(69); // [ var(142) , var(86) ]
+                D[88,142] = (-1)*var(70); // [ var(142) , var(88) ]
+                D[91,142] = (-1)*var(75); // [ var(142) , var(91) ]
+                D[96,142] = var(82); // [ var(142) , var(96) ]
+                D[100,142] = var(85); // [ var(142) , var(100) ]
+                D[103,142] = var(89); // [ var(142) , var(103) ]
+                D[105,142] = var(93); // [ var(142) , var(105) ]
+                D[107,142] = var(97); // [ var(142) , var(107) ]
+                D[120,142] = (-1)*var(117); // [ var(142) , var(120) ]
+                D[1,143] = (-1)*var(137); // [ var(143) , var(1) ]
+                D[2,143] = (-1)*var(136); // [ var(143) , var(2) ]
+                D[9,143] = (-1)*var(130); // [ var(143) , var(9) ]
+                D[10,143] = var(129); // [ var(143) , var(10) ]
+                D[16,143] = var(122); // [ var(143) , var(16) ]
+                D[17,143] = var(121); // [ var(143) , var(17) ]
+                D[23,143] = (-1)*var(241)+(-1)*var(242)+(-1)*var(243)+(-1)*var(244); // [ var(143) , var(23) ]
+                D[30,143] = (-1)*var(5); // [ var(143) , var(30) ]
+                D[37,143] = var(12); // [ var(143) , var(37) ]
+                D[38,143] = (-1)*var(13); // [ var(143) , var(38) ]
+                D[44,143] = var(19); // [ var(143) , var(44) ]
+                D[45,143] = var(20); // [ var(143) , var(45) ]
+                D[46,143] = (-1)*var(21); // [ var(143) , var(46) ]
+                D[51,143] = var(27); // [ var(143) , var(51) ]
+                D[53,143] = var(28); // [ var(143) , var(53) ]
+                D[54,143] = (-1)*var(29); // [ var(143) , var(54) ]
+                D[58,143] = var(35); // [ var(143) , var(58) ]
+                D[60,143] = var(36); // [ var(143) , var(60) ]
+                D[65,143] = var(43); // [ var(143) , var(65) ]
+                D[69,143] = (-1)*var(48); // [ var(143) , var(69) ]
+                D[75,143] = (-1)*var(55); // [ var(143) , var(75) ]
+                D[80,143] = (-1)*var(61); // [ var(143) , var(80) ]
+                D[81,143] = (-1)*var(62); // [ var(143) , var(81) ]
+                D[86,143] = (-1)*var(68); // [ var(143) , var(86) ]
+                D[91,143] = (-1)*var(74); // [ var(143) , var(91) ]
+                D[97,143] = var(82); // [ var(143) , var(97) ]
+                D[101,143] = var(87); // [ var(143) , var(101) ]
+                D[104,143] = var(92); // [ var(143) , var(104) ]
+                D[107,143] = var(96); // [ var(143) , var(107) ]
+                D[113,143] = (-1)*var(106); // [ var(143) , var(113) ]
+                D[115,143] = (-1)*var(108); // [ var(143) , var(115) ]
+                D[116,143] = var(110); // [ var(143) , var(116) ]
+                D[1,144] = (-1)*var(139); // [ var(144) , var(1) ]
+                D[5,144] = var(136); // [ var(144) , var(5) ]
+                D[9,144] = (-1)*var(132); // [ var(144) , var(9) ]
+                D[12,144] = var(129); // [ var(144) , var(12) ]
+                D[16,144] = (-1)*var(125); // [ var(144) , var(16) ]
+                D[19,144] = var(121); // [ var(144) , var(19) ]
+                D[24,144] = (-1)*var(241)+(-1)*var(243)+(-1)*var(244)+(-1)*var(245); // [ var(144) , var(24) ]
+                D[30,144] = var(2); // [ var(144) , var(30) ]
+                D[31,144] = (-1)*var(6); // [ var(144) , var(31) ]
+                D[37,144] = var(10); // [ var(144) , var(37) ]
+                D[39,144] = (-1)*var(14); // [ var(144) , var(39) ]
+                D[44,144] = var(17); // [ var(144) , var(44) ]
+                D[47,144] = (-1)*var(22); // [ var(144) , var(47) ]
+                D[52,144] = (-1)*var(26); // [ var(144) , var(52) ]
+                D[57,144] = (-1)*var(33); // [ var(144) , var(57) ]
+                D[59,144] = (-1)*var(34); // [ var(144) , var(59) ]
+                D[63,144] = (-1)*var(40); // [ var(144) , var(63) ]
+                D[64,144] = (-1)*var(41); // [ var(144) , var(64) ]
+                D[67,144] = (-1)*var(42); // [ var(144) , var(67) ]
+                D[70,144] = (-1)*var(49); // [ var(144) , var(70) ]
+                D[72,144] = (-1)*var(50); // [ var(144) , var(72) ]
+                D[77,144] = (-1)*var(56); // [ var(144) , var(77) ]
+                D[82,144] = var(61); // [ var(144) , var(82) ]
+                D[87,144] = var(68); // [ var(144) , var(87) ]
+                D[92,144] = var(74); // [ var(144) , var(92) ]
+                D[97,144] = (-1)*var(80); // [ var(144) , var(97) ]
+                D[101,144] = (-1)*var(86); // [ var(144) , var(101) ]
+                D[104,144] = (-1)*var(91); // [ var(144) , var(104) ]
+                D[109,144] = var(100); // [ var(144) , var(109) ]
+                D[111,144] = var(103); // [ var(144) , var(111) ]
+                D[114,144] = var(105); // [ var(144) , var(114) ]
+                D[117,144] = var(112); // [ var(144) , var(117) ]
+                D[2,145] = (-1)*var(139); // [ var(145) , var(2) ]
+                D[3,145] = (-1)*var(138); // [ var(145) , var(3) ]
+                D[5,145] = var(137); // [ var(145) , var(5) ]
+                D[17,145] = (-1)*var(125); // [ var(145) , var(17) ]
+                D[18,145] = var(123); // [ var(145) , var(18) ]
+                D[19,145] = var(122); // [ var(145) , var(19) ]
+                D[25,145] = (-1)*var(242)+(-1)*var(243)+(-1)*var(244)+(-1)*var(245); // [ var(145) , var(25) ]
+                D[30,145] = var(1); // [ var(145) , var(30) ]
+                D[32,145] = (-1)*var(4); // [ var(145) , var(32) ]
+                D[33,145] = (-1)*var(6); // [ var(145) , var(33) ]
+                D[41,145] = (-1)*var(14); // [ var(145) , var(41) ]
+                D[44,145] = var(16); // [ var(145) , var(44) ]
+                D[48,145] = var(20); // [ var(145) , var(48) ]
+                D[50,145] = (-1)*var(22); // [ var(145) , var(50) ]
+                D[55,145] = var(28); // [ var(145) , var(55) ]
+                D[57,145] = (-1)*var(31); // [ var(145) , var(57) ]
+                D[62,145] = var(36); // [ var(145) , var(62) ]
+                D[64,145] = (-1)*var(39); // [ var(145) , var(64) ]
+                D[69,145] = (-1)*var(45); // [ var(145) , var(69) ]
+                D[72,145] = (-1)*var(47); // [ var(145) , var(72) ]
+                D[75,145] = (-1)*var(53); // [ var(145) , var(75) ]
+                D[81,145] = (-1)*var(60); // [ var(145) , var(81) ]
+                D[85,145] = var(66); // [ var(145) , var(85) ]
+                D[90,145] = var(73); // [ var(145) , var(90) ]
+                D[93,145] = var(76); // [ var(145) , var(93) ]
+                D[95,145] = var(79); // [ var(145) , var(95) ]
+                D[98,145] = var(83); // [ var(145) , var(98) ]
+                D[102,145] = var(88); // [ var(145) , var(102) ]
+                D[108,145] = (-1)*var(96); // [ var(145) , var(108) ]
+                D[112,145] = (-1)*var(103); // [ var(145) , var(112) ]
+                D[115,145] = var(107); // [ var(145) , var(115) ]
+                D[117,145] = (-1)*var(111); // [ var(145) , var(117) ]
+                D[2,146] = (-1)*var(140); // [ var(146) , var(2) ]
+                D[6,146] = var(138); // [ var(146) , var(6) ]
+                D[10,146] = (-1)*var(133); // [ var(146) , var(10) ]
+                D[13,146] = var(130); // [ var(146) , var(13) ]
+                D[18,146] = (-1)*var(126); // [ var(146) , var(18) ]
+                D[20,146] = var(122); // [ var(146) , var(20) ]
+                D[26,146] = (-1)*var(242)+(-1)*var(244)+(-1)*var(245)+(-1)*var(246); // [ var(146) , var(26) ]
+                D[33,146] = var(3); // [ var(146) , var(33) ]
+                D[34,146] = (-1)*var(7); // [ var(146) , var(34) ]
+                D[38,146] = var(9); // [ var(146) , var(38) ]
+                D[40,146] = var(11); // [ var(146) , var(40) ]
+                D[42,146] = (-1)*var(15); // [ var(146) , var(42) ]
+                D[45,146] = var(16); // [ var(146) , var(45) ]
+                D[48,146] = var(19); // [ var(146) , var(48) ]
+                D[52,146] = var(24); // [ var(146) , var(52) ]
+                D[61,146] = (-1)*var(35); // [ var(146) , var(61) ]
+                D[66,146] = (-1)*var(39); // [ var(146) , var(66) ]
+                D[68,146] = (-1)*var(43); // [ var(146) , var(68) ]
+                D[69,146] = (-1)*var(44); // [ var(146) , var(69) ]
+                D[73,146] = (-1)*var(47); // [ var(146) , var(73) ]
+                D[80,146] = var(58); // [ var(146) , var(80) ]
+                D[85,146] = var(64); // [ var(146) , var(85) ]
+                D[86,146] = var(65); // [ var(146) , var(86) ]
+                D[89,146] = var(70); // [ var(146) , var(89) ]
+                D[90,146] = var(72); // [ var(146) , var(90) ]
+                D[94,146] = var(77); // [ var(146) , var(94) ]
+                D[100,146] = (-1)*var(84); // [ var(146) , var(100) ]
+                D[103,146] = (-1)*var(88); // [ var(146) , var(103) ]
+                D[106,146] = (-1)*var(92); // [ var(146) , var(106) ]
+                D[112,146] = var(102); // [ var(146) , var(112) ]
+                D[113,146] = var(104); // [ var(146) , var(113) ]
+                D[118,146] = var(114); // [ var(146) , var(118) ]
+                D[3,147] = (-1)*var(140); // [ var(147) , var(3) ]
+                D[6,147] = var(139); // [ var(147) , var(6) ]
+                D[11,147] = (-1)*var(133); // [ var(147) , var(11) ]
+                D[13,147] = var(131); // [ var(147) , var(13) ]
+                D[19,147] = (-1)*var(126); // [ var(147) , var(19) ]
+                D[20,147] = var(123); // [ var(147) , var(20) ]
+                D[27,147] = (-1)*var(243)+(-1)*var(244)+(-1)*var(245)+(-1)*var(246); // [ var(147) , var(27) ]
+                D[31,147] = var(1); // [ var(147) , var(31) ]
+                D[33,147] = var(2); // [ var(147) , var(33) ]
+                D[35,147] = (-1)*var(7); // [ var(147) , var(35) ]
+                D[40,147] = var(10); // [ var(147) , var(40) ]
+                D[43,147] = (-1)*var(15); // [ var(147) , var(43) ]
+                D[48,147] = var(18); // [ var(147) , var(48) ]
+                D[51,147] = (-1)*var(23); // [ var(147) , var(51) ]
+                D[57,147] = (-1)*var(30); // [ var(147) , var(57) ]
+                D[61,147] = (-1)*var(34); // [ var(147) , var(61) ]
+                D[63,147] = (-1)*var(37); // [ var(147) , var(63) ]
+                D[68,147] = (-1)*var(42); // [ var(147) , var(68) ]
+                D[71,147] = var(46); // [ var(147) , var(71) ]
+                D[76,147] = var(53); // [ var(147) , var(76) ]
+                D[78,147] = var(54); // [ var(147) , var(78) ]
+                D[82,147] = var(59); // [ var(147) , var(82) ]
+                D[83,147] = var(60); // [ var(147) , var(83) ]
+                D[87,147] = var(67); // [ var(147) , var(87) ]
+                D[93,147] = (-1)*var(75); // [ var(147) , var(93) ]
+                D[96,147] = (-1)*var(79); // [ var(147) , var(96) ]
+                D[98,147] = (-1)*var(81); // [ var(147) , var(98) ]
+                D[105,147] = var(91); // [ var(147) , var(105) ]
+                D[108,147] = var(95); // [ var(147) , var(108) ]
+                D[110,147] = var(99); // [ var(147) , var(110) ]
+                D[114,147] = (-1)*var(104); // [ var(147) , var(114) ]
+                D[118,147] = (-1)*var(113); // [ var(147) , var(118) ]
+                D[4,148] = (-1)*var(141); // [ var(148) , var(4) ]
+                D[7,148] = var(140); // [ var(148) , var(7) ]
+                D[12,148] = (-1)*var(134); // [ var(148) , var(12) ]
+                D[14,148] = var(132); // [ var(148) , var(14) ]
+                D[20,148] = (-1)*var(127); // [ var(148) , var(20) ]
+                D[21,148] = var(124); // [ var(148) , var(21) ]
+                D[28,148] = (-1)*var(244)+(-1)*var(245)+(-1)*var(246)+(-1)*var(247); // [ var(148) , var(28) ]
+                D[34,148] = var(2); // [ var(148) , var(34) ]
+                D[35,148] = var(3); // [ var(148) , var(35) ]
+                D[36,148] = (-1)*var(8); // [ var(148) , var(36) ]
+                D[39,148] = var(9); // [ var(148) , var(39) ]
+                D[49,148] = (-1)*var(17); // [ var(148) , var(49) ]
+                D[53,148] = (-1)*var(23); // [ var(148) , var(53) ]
+                D[55,148] = (-1)*var(25); // [ var(148) , var(55) ]
+                D[59,148] = (-1)*var(30); // [ var(148) , var(59) ]
+                D[61,148] = (-1)*var(33); // [ var(148) , var(61) ]
+                D[66,148] = (-1)*var(38); // [ var(148) , var(66) ]
+                D[70,148] = var(44); // [ var(148) , var(70) ]
+                D[74,148] = var(50); // [ var(148) , var(74) ]
+                D[76,148] = var(51); // [ var(148) , var(76) ]
+                D[79,148] = var(54); // [ var(148) , var(79) ]
+                D[82,148] = var(57); // [ var(148) , var(82) ]
+                D[88,148] = (-1)*var(65); // [ var(148) , var(88) ]
+                D[89,148] = (-1)*var(69); // [ var(148) , var(89) ]
+                D[92,148] = (-1)*var(72); // [ var(148) , var(92) ]
+                D[96,148] = (-1)*var(78); // [ var(148) , var(96) ]
+                D[99,148] = var(81); // [ var(148) , var(99) ]
+                D[103,148] = var(86); // [ var(148) , var(103) ]
+                D[106,148] = var(90); // [ var(148) , var(106) ]
+                D[110,148] = (-1)*var(98); // [ var(148) , var(110) ]
+                D[111,148] = (-1)*var(101); // [ var(148) , var(111) ]
+                D[119,148] = var(115); // [ var(148) , var(119) ]
+                D[5,149] = (-1)*var(142); // [ var(149) , var(5) ]
+                D[8,149] = var(141); // [ var(149) , var(8) ]
+                D[13,149] = (-1)*var(135); // [ var(149) , var(13) ]
+                D[15,149] = var(133); // [ var(149) , var(15) ]
+                D[21,149] = (-1)*var(128); // [ var(149) , var(21) ]
+                D[22,149] = var(125); // [ var(149) , var(22) ]
+                D[29,149] = (-1)*var(245)+(-1)*var(246)+(-1)*var(247)+(-1)*var(248); // [ var(149) , var(29) ]
+                D[36,149] = var(4); // [ var(149) , var(36) ]
+                D[42,149] = var(10); // [ var(149) , var(42) ]
+                D[43,149] = var(11); // [ var(149) , var(43) ]
+                D[47,149] = var(16); // [ var(149) , var(47) ]
+                D[50,149] = var(17); // [ var(149) , var(50) ]
+                D[54,149] = var(23); // [ var(149) , var(54) ]
+                D[62,149] = (-1)*var(32); // [ var(149) , var(62) ]
+                D[67,149] = (-1)*var(37); // [ var(149) , var(67) ]
+                D[68,149] = (-1)*var(40); // [ var(149) , var(68) ]
+                D[72,149] = (-1)*var(44); // [ var(149) , var(72) ]
+                D[73,149] = (-1)*var(45); // [ var(149) , var(73) ]
+                D[74,149] = (-1)*var(49); // [ var(149) , var(74) ]
+                D[78,149] = (-1)*var(51); // [ var(149) , var(78) ]
+                D[79,149] = (-1)*var(53); // [ var(149) , var(79) ]
+                D[84,149] = (-1)*var(58); // [ var(149) , var(84) ]
+                D[87,149] = var(63); // [ var(149) , var(87) ]
+                D[90,149] = var(69); // [ var(149) , var(90) ]
+                D[92,149] = var(70); // [ var(149) , var(92) ]
+                D[95,149] = var(75); // [ var(149) , var(95) ]
+                D[96,149] = var(76); // [ var(149) , var(96) ]
+                D[100,149] = var(80); // [ var(149) , var(100) ]
+                D[106,149] = (-1)*var(89); // [ var(149) , var(106) ]
+                D[108,149] = (-1)*var(93); // [ var(149) , var(108) ]
+                D[109,149] = (-1)*var(97); // [ var(149) , var(109) ]
+                D[120,149] = var(116); // [ var(149) , var(120) ]
+                D[1,150] = (-1)*var(145); // [ var(150) , var(1) ]
+                D[2,150] = (-1)*var(144); // [ var(150) , var(2) ]
+                D[5,150] = var(143); // [ var(150) , var(5) ]
+                D[9,150] = (-1)*var(138); // [ var(150) , var(9) ]
+                D[18,150] = var(129); // [ var(150) , var(18) ]
+                D[23,150] = (-1)*var(125); // [ var(150) , var(23) ]
+                D[24,150] = var(122); // [ var(150) , var(24) ]
+                D[25,150] = var(121); // [ var(150) , var(25) ]
+                D[30,150] = (-1)*var(241)+(-1)*var(242)+(-1)*var(243)+(-1)*var(244)+(-1)*var(245); // [ var(150) , var(30) ]
+                D[37,150] = (-1)*var(4); // [ var(150) , var(37) ]
+                D[38,150] = (-1)*var(6); // [ var(150) , var(38) ]
+                D[44,150] = (-1)*var(11); // [ var(150) , var(44) ]
+                D[46,150] = (-1)*var(14); // [ var(150) , var(46) ]
+                D[52,150] = var(20); // [ var(150) , var(52) ]
+                D[54,150] = (-1)*var(22); // [ var(150) , var(54) ]
+                D[57,150] = var(27); // [ var(150) , var(57) ]
+                D[59,150] = var(28); // [ var(150) , var(59) ]
+                D[64,150] = var(35); // [ var(150) , var(64) ]
+                D[67,150] = var(36); // [ var(150) , var(67) ]
+                D[69,150] = var(40); // [ var(150) , var(69) ]
+                D[72,150] = var(43); // [ var(150) , var(72) ]
+                D[75,150] = var(49); // [ var(150) , var(75) ]
+                D[81,150] = var(56); // [ var(150) , var(81) ]
+                D[85,150] = (-1)*var(61); // [ var(150) , var(85) ]
+                D[90,150] = (-1)*var(68); // [ var(150) , var(90) ]
+                D[95,150] = (-1)*var(74); // [ var(150) , var(95) ]
+                D[97,150] = (-1)*var(76); // [ var(150) , var(97) ]
+                D[101,150] = (-1)*var(83); // [ var(150) , var(101) ]
+                D[104,150] = (-1)*var(88); // [ var(150) , var(104) ]
+                D[109,150] = var(96); // [ var(150) , var(109) ]
+                D[113,150] = var(103); // [ var(150) , var(113) ]
+                D[115,150] = var(105); // [ var(150) , var(115) ]
+                D[117,150] = (-1)*var(110); // [ var(150) , var(117) ]
+                D[1,151] = (-1)*var(147); // [ var(151) , var(1) ]
+                D[6,151] = var(144); // [ var(151) , var(6) ]
+                D[9,151] = (-1)*var(140); // [ var(151) , var(9) ]
+                D[13,151] = var(136); // [ var(151) , var(13) ]
+                D[16,151] = (-1)*var(133); // [ var(151) , var(16) ]
+                D[20,151] = var(129); // [ var(151) , var(20) ]
+                D[24,151] = (-1)*var(126); // [ var(151) , var(24) ]
+                D[27,151] = var(121); // [ var(151) , var(27) ]
+                D[31,151] = (-1)*var(241)+(-1)*var(243)+(-1)*var(244)+(-1)*var(245)+(-1)*var(246); // [ var(151) , var(31) ]
+                D[38,151] = var(2); // [ var(151) , var(38) ]
+                D[39,151] = (-1)*var(7); // [ var(151) , var(39) ]
+                D[45,151] = var(10); // [ var(151) , var(45) ]
+                D[47,151] = (-1)*var(15); // [ var(151) , var(47) ]
+                D[51,151] = var(17); // [ var(151) , var(51) ]
+                D[52,151] = var(18); // [ var(151) , var(52) ]
+                D[57,151] = var(25); // [ var(151) , var(57) ]
+                D[63,151] = var(32); // [ var(151) , var(63) ]
+                D[66,151] = (-1)*var(34); // [ var(151) , var(66) ]
+                D[71,151] = (-1)*var(41); // [ var(151) , var(71) ]
+                D[73,151] = (-1)*var(42); // [ var(151) , var(73) ]
+                D[76,151] = (-1)*var(49); // [ var(151) , var(76) ]
+                D[78,151] = (-1)*var(50); // [ var(151) , var(78) ]
+                D[82,151] = (-1)*var(55); // [ var(151) , var(82) ]
+                D[83,151] = (-1)*var(56); // [ var(151) , var(83) ]
+                D[87,151] = (-1)*var(62); // [ var(151) , var(87) ]
+                D[96,151] = var(74); // [ var(151) , var(96) ]
+                D[97,151] = var(75); // [ var(151) , var(97) ]
+                D[101,151] = var(81); // [ var(151) , var(101) ]
+                D[107,151] = (-1)*var(91); // [ var(151) , var(107) ]
+                D[109,151] = (-1)*var(95); // [ var(151) , var(109) ]
+                D[111,151] = (-1)*var(99); // [ var(151) , var(111) ]
+                D[114,151] = (-1)*var(102); // [ var(151) , var(114) ]
+                D[118,151] = (-1)*var(112); // [ var(151) , var(118) ]
+                D[4,152] = var(145); // [ var(152) , var(4) ]
+                D[10,152] = (-1)*var(139); // [ var(152) , var(10) ]
+                D[11,152] = (-1)*var(138); // [ var(152) , var(11) ]
+                D[12,152] = (-1)*var(137); // [ var(152) , var(12) ]
+                D[17,152] = var(132); // [ var(152) , var(17) ]
+                D[18,152] = var(131); // [ var(152) , var(18) ]
+                D[19,152] = var(130); // [ var(152) , var(19) ]
+                D[25,152] = (-1)*var(124); // [ var(152) , var(25) ]
+                D[32,152] = (-1)*var(242)+(-1)*var(243)+(-2)*var(244)+(-1)*var(245); // [ var(152) , var(32) ]
+                D[37,152] = var(1); // [ var(152) , var(37) ]
+                D[40,152] = (-1)*var(6); // [ var(152) , var(40) ]
+                D[44,152] = (-1)*var(9); // [ var(152) , var(44) ]
+                D[48,152] = var(13); // [ var(152) , var(48) ]
+                D[49,152] = (-1)*var(14); // [ var(152) , var(49) ]
+                D[55,152] = var(21); // [ var(152) , var(55) ]
+                D[56,152] = (-1)*var(22); // [ var(152) , var(56) ]
+                D[62,152] = var(29); // [ var(152) , var(62) ]
+                D[63,152] = (-1)*var(31); // [ var(152) , var(63) ]
+                D[69,152] = var(38); // [ var(152) , var(69) ]
+                D[70,152] = (-1)*var(39); // [ var(152) , var(70) ]
+                D[75,152] = var(46); // [ var(152) , var(75) ]
+                D[77,152] = (-1)*var(47); // [ var(152) , var(77) ]
+                D[81,152] = var(54); // [ var(152) , var(81) ]
+                D[89,152] = var(66); // [ var(152) , var(89) ]
+                D[93,152] = (-1)*var(71); // [ var(152) , var(93) ]
+                D[94,152] = var(73); // [ var(152) , var(94) ]
+                D[98,152] = (-1)*var(78); // [ var(152) , var(98) ]
+                D[99,152] = var(79); // [ var(152) , var(99) ]
+                D[102,152] = (-1)*var(84); // [ var(152) , var(102) ]
+                D[110,152] = (-1)*var(96); // [ var(152) , var(110) ]
+                D[112,152] = var(100); // [ var(152) , var(112) ]
+                D[116,152] = (-1)*var(107); // [ var(152) , var(116) ]
+                D[117,152] = var(109); // [ var(152) , var(117) ]
+                D[2,153] = (-1)*var(147); // [ var(153) , var(2) ]
+                D[3,153] = (-1)*var(146); // [ var(153) , var(3) ]
+                D[6,153] = var(145); // [ var(153) , var(6) ]
+                D[13,153] = var(137); // [ var(153) , var(13) ]
+                D[17,153] = (-1)*var(133); // [ var(153) , var(17) ]
+                D[25,153] = (-1)*var(126); // [ var(153) , var(25) ]
+                D[26,153] = var(123); // [ var(153) , var(26) ]
+                D[27,153] = var(122); // [ var(153) , var(27) ]
+                D[33,153] = (-1)*var(242)+(-1)*var(243)+(-1)*var(244)+(-1)*var(245)+(-1)*var(246); // [ var(153) , var(33) ]
+                D[38,153] = var(1); // [ var(153) , var(38) ]
+                D[40,153] = (-1)*var(4); // [ var(153) , var(40) ]
+                D[41,153] = (-1)*var(7); // [ var(153) , var(41) ]
+                D[48,153] = (-1)*var(12); // [ var(153) , var(48) ]
+                D[50,153] = (-1)*var(15); // [ var(153) , var(50) ]
+                D[51,153] = var(16); // [ var(153) , var(51) ]
+                D[57,153] = var(24); // [ var(153) , var(57) ]
+                D[61,153] = var(28); // [ var(153) , var(61) ]
+                D[68,153] = var(36); // [ var(153) , var(68) ]
+                D[69,153] = var(37); // [ var(153) , var(69) ]
+                D[71,153] = (-1)*var(39); // [ var(153) , var(71) ]
+                D[78,153] = (-1)*var(47); // [ var(153) , var(78) ]
+                D[80,153] = (-1)*var(53); // [ var(153) , var(80) ]
+                D[85,153] = (-1)*var(59); // [ var(153) , var(85) ]
+                D[86,153] = (-1)*var(60); // [ var(153) , var(86) ]
+                D[90,153] = (-1)*var(67); // [ var(153) , var(90) ]
+                D[93,153] = (-1)*var(70); // [ var(153) , var(93) ]
+                D[98,153] = (-1)*var(77); // [ var(153) , var(98) ]
+                D[100,153] = var(79); // [ var(153) , var(100) ]
+                D[105,153] = var(88); // [ var(153) , var(105) ]
+                D[108,153] = var(92); // [ var(153) , var(108) ]
+                D[112,153] = var(99); // [ var(153) , var(112) ]
+                D[115,153] = (-1)*var(104); // [ var(153) , var(115) ]
+                D[118,153] = var(111); // [ var(153) , var(118) ]
+                D[2,154] = (-1)*var(148); // [ var(154) , var(2) ]
+                D[7,154] = var(146); // [ var(154) , var(7) ]
+                D[10,154] = (-1)*var(141); // [ var(154) , var(10) ]
+                D[14,154] = var(138); // [ var(154) , var(14) ]
+                D[18,154] = (-1)*var(134); // [ var(154) , var(18) ]
+                D[21,154] = var(130); // [ var(154) , var(21) ]
+                D[26,154] = (-1)*var(127); // [ var(154) , var(26) ]
+                D[28,154] = var(122); // [ var(154) , var(28) ]
+                D[34,154] = (-1)*var(242)+(-1)*var(244)+(-1)*var(245)+(-1)*var(246)+(-1)*var(247); // [ var(154) , var(34) ]
+                D[41,154] = var(3); // [ var(154) , var(41) ]
+                D[42,154] = (-1)*var(8); // [ var(154) , var(42) ]
+                D[46,154] = var(9); // [ var(154) , var(46) ]
+                D[49,154] = var(11); // [ var(154) , var(49) ]
+                D[53,154] = var(16); // [ var(154) , var(53) ]
+                D[55,154] = var(19); // [ var(154) , var(55) ]
+                D[59,154] = var(24); // [ var(154) , var(59) ]
+                D[61,154] = var(27); // [ var(154) , var(61) ]
+                D[66,154] = var(31); // [ var(154) , var(66) ]
+                D[74,154] = (-1)*var(43); // [ var(154) , var(74) ]
+                D[75,154] = (-1)*var(44); // [ var(154) , var(75) ]
+                D[79,154] = (-1)*var(47); // [ var(154) , var(79) ]
+                D[80,154] = (-1)*var(51); // [ var(154) , var(80) ]
+                D[85,154] = (-1)*var(57); // [ var(154) , var(85) ]
+                D[89,154] = (-1)*var(63); // [ var(154) , var(89) ]
+                D[91,154] = var(65); // [ var(154) , var(91) ]
+                D[95,154] = var(72); // [ var(154) , var(95) ]
+                D[99,154] = var(77); // [ var(154) , var(99) ]
+                D[100,154] = var(78); // [ var(154) , var(100) ]
+                D[103,154] = var(83); // [ var(154) , var(103) ]
+                D[106,154] = var(87); // [ var(154) , var(106) ]
+                D[112,154] = (-1)*var(98); // [ var(154) , var(112) ]
+                D[113,154] = (-1)*var(101); // [ var(154) , var(113) ]
+                D[119,154] = (-1)*var(114); // [ var(154) , var(119) ]
+                D[3,155] = (-1)*var(148); // [ var(155) , var(3) ]
+                D[7,155] = var(147); // [ var(155) , var(7) ]
+                D[11,155] = (-1)*var(141); // [ var(155) , var(11) ]
+                D[14,155] = var(139); // [ var(155) , var(14) ]
+                D[19,155] = (-1)*var(134); // [ var(155) , var(19) ]
+                D[21,155] = var(131); // [ var(155) , var(21) ]
+                D[27,155] = (-1)*var(127); // [ var(155) , var(27) ]
+                D[28,155] = var(123); // [ var(155) , var(28) ]
+                D[35,155] = (-1)*var(243)+(-1)*var(244)+(-1)*var(245)+(-1)*var(246)+(-1)*var(247); // [ var(155) , var(35) ]
+                D[39,155] = var(1); // [ var(155) , var(39) ]
+                D[41,155] = var(2); // [ var(155) , var(41) ]
+                D[43,155] = (-1)*var(8); // [ var(155) , var(43) ]
+                D[49,155] = var(10); // [ var(155) , var(49) ]
+                D[55,155] = var(18); // [ var(155) , var(55) ]
+                D[58,155] = (-1)*var(23); // [ var(155) , var(58) ]
+                D[61,155] = var(26); // [ var(155) , var(61) ]
+                D[64,155] = (-1)*var(30); // [ var(155) , var(64) ]
+                D[70,155] = (-1)*var(37); // [ var(155) , var(70) ]
+                D[71,155] = (-1)*var(38); // [ var(155) , var(71) ]
+                D[74,155] = (-1)*var(42); // [ var(155) , var(74) ]
+                D[76,155] = (-1)*var(45); // [ var(155) , var(76) ]
+                D[82,155] = (-1)*var(52); // [ var(155) , var(82) ]
+                D[84,155] = var(54); // [ var(155) , var(84) ]
+                D[88,155] = var(60); // [ var(155) , var(88) ]
+                D[92,155] = var(67); // [ var(155) , var(92) ]
+                D[93,155] = var(69); // [ var(155) , var(93) ]
+                D[96,155] = var(73); // [ var(155) , var(96) ]
+                D[102,155] = (-1)*var(81); // [ var(155) , var(102) ]
+                D[105,155] = (-1)*var(86); // [ var(155) , var(105) ]
+                D[108,155] = (-1)*var(90); // [ var(155) , var(108) ]
+                D[110,155] = (-1)*var(94); // [ var(155) , var(110) ]
+                D[114,155] = var(101); // [ var(155) , var(114) ]
+                D[119,155] = var(113); // [ var(155) , var(119) ]
+                D[4,156] = (-1)*var(149); // [ var(156) , var(4) ]
+                D[8,156] = var(148); // [ var(156) , var(8) ]
+                D[12,156] = (-1)*var(142); // [ var(156) , var(12) ]
+                D[15,156] = var(140); // [ var(156) , var(15) ]
+                D[20,156] = (-1)*var(135); // [ var(156) , var(20) ]
+                D[22,156] = var(132); // [ var(156) , var(22) ]
+                D[28,156] = (-1)*var(128); // [ var(156) , var(28) ]
+                D[29,156] = var(124); // [ var(156) , var(29) ]
+                D[36,156] = (-1)*var(244)+(-1)*var(245)+(-1)*var(246)+(-1)*var(247)+(-1)*var(248); // [ var(156) , var(36) ]
+                D[42,156] = var(2); // [ var(156) , var(42) ]
+                D[43,156] = var(3); // [ var(156) , var(43) ]
+                D[47,156] = var(9); // [ var(156) , var(47) ]
+                D[56,156] = (-1)*var(17); // [ var(156) , var(56) ]
+                D[60,156] = (-1)*var(23); // [ var(156) , var(60) ]
+                D[62,156] = (-1)*var(25); // [ var(156) , var(62) ]
+                D[67,156] = (-1)*var(30); // [ var(156) , var(67) ]
+                D[68,156] = (-1)*var(33); // [ var(156) , var(68) ]
+                D[73,156] = (-1)*var(38); // [ var(156) , var(73) ]
+                D[74,156] = (-1)*var(41); // [ var(156) , var(74) ]
+                D[77,156] = var(44); // [ var(156) , var(77) ]
+                D[79,156] = (-1)*var(46); // [ var(156) , var(79) ]
+                D[83,156] = var(51); // [ var(156) , var(83) ]
+                D[87,156] = var(57); // [ var(156) , var(87) ]
+                D[88,156] = var(58); // [ var(156) , var(88) ]
+                D[92,156] = var(64); // [ var(156) , var(92) ]
+                D[94,156] = (-1)*var(69); // [ var(156) , var(94) ]
+                D[96,156] = var(71); // [ var(156) , var(96) ]
+                D[99,156] = (-1)*var(75); // [ var(156) , var(99) ]
+                D[103,156] = (-1)*var(80); // [ var(156) , var(103) ]
+                D[106,156] = (-1)*var(85); // [ var(156) , var(106) ]
+                D[110,156] = var(93); // [ var(156) , var(110) ]
+                D[111,156] = var(97); // [ var(156) , var(111) ]
+                D[120,156] = (-1)*var(115); // [ var(156) , var(120) ]
+                D[1,157] = (-1)*var(152); // [ var(157) , var(1) ]
+                D[4,157] = var(150); // [ var(157) , var(4) ]
+                D[10,157] = (-1)*var(144); // [ var(157) , var(10) ]
+                D[12,157] = (-1)*var(143); // [ var(157) , var(12) ]
+                D[16,157] = (-1)*var(138); // [ var(157) , var(16) ]
+                D[18,157] = var(136); // [ var(157) , var(18) ]
+                D[23,157] = var(132); // [ var(157) , var(23) ]
+                D[24,157] = var(130); // [ var(157) , var(24) ]
+                D[30,157] = (-1)*var(124); // [ var(157) , var(30) ]
+                D[32,157] = var(121); // [ var(157) , var(32) ]
+                D[37,157] = (-1)*var(241)+(-1)*var(242)+(-1)*var(243)+(-2)*var(244)+(-1)*var(245); // [ var(157) , var(37) ]
+                D[44,157] = var(3); // [ var(157) , var(44) ]
+                D[45,157] = (-1)*var(6); // [ var(157) , var(45) ]
+                D[52,157] = var(13); // [ var(157) , var(52) ]
+                D[53,157] = (-1)*var(14); // [ var(157) , var(53) ]
+                D[59,157] = var(21); // [ var(157) , var(59) ]
+                D[60,157] = (-1)*var(22); // [ var(157) , var(60) ]
+                D[63,157] = var(27); // [ var(157) , var(63) ]
+                D[67,157] = var(29); // [ var(157) , var(67) ]
+                D[69,157] = (-1)*var(33); // [ var(157) , var(69) ]
+                D[70,157] = var(35); // [ var(157) , var(70) ]
+                D[75,157] = (-1)*var(41); // [ var(157) , var(75) ]
+                D[77,157] = var(43); // [ var(157) , var(77) ]
+                D[81,157] = (-1)*var(50); // [ var(157) , var(81) ]
+                D[89,157] = (-1)*var(61); // [ var(157) , var(89) ]
+                D[94,157] = (-1)*var(68); // [ var(157) , var(94) ]
+                D[97,157] = var(71); // [ var(157) , var(97) ]
+                D[99,157] = (-1)*var(74); // [ var(157) , var(99) ]
+                D[101,157] = var(78); // [ var(157) , var(101) ]
+                D[104,157] = var(84); // [ var(157) , var(104) ]
+                D[111,157] = var(96); // [ var(157) , var(111) ]
+                D[113,157] = (-1)*var(100); // [ var(157) , var(113) ]
+                D[116,157] = (-1)*var(105); // [ var(157) , var(116) ]
+                D[117,157] = var(108); // [ var(157) , var(117) ]
+                D[1,158] = (-1)*var(153); // [ var(158) , var(1) ]
+                D[2,158] = (-1)*var(151); // [ var(158) , var(2) ]
+                D[6,158] = var(150); // [ var(158) , var(6) ]
+                D[9,158] = (-1)*var(146); // [ var(158) , var(9) ]
+                D[13,158] = var(143); // [ var(158) , var(13) ]
+                D[23,158] = (-1)*var(133); // [ var(158) , var(23) ]
+                D[26,158] = var(129); // [ var(158) , var(26) ]
+                D[30,158] = (-1)*var(126); // [ var(158) , var(30) ]
+                D[31,158] = var(122); // [ var(158) , var(31) ]
+                D[33,158] = var(121); // [ var(158) , var(33) ]
+                D[38,158] = (-1)*var(241)+(-1)*var(242)+(-1)*var(243)+(-1)*var(244)+(-1)*var(245)+(-1)*var(246); // [ var(158) , var(38) ]
+                D[45,158] = (-1)*var(4); // [ var(158) , var(45) ]
+                D[46,158] = (-1)*var(7); // [ var(158) , var(46) ]
+                D[51,158] = (-1)*var(11); // [ var(158) , var(51) ]
+                D[52,158] = (-1)*var(12); // [ var(158) , var(52) ]
+                D[54,158] = (-1)*var(15); // [ var(158) , var(54) ]
+                D[57,158] = (-1)*var(19); // [ var(158) , var(57) ]
+                D[66,158] = var(28); // [ var(158) , var(66) ]
+                D[69,158] = (-1)*var(32); // [ var(158) , var(69) ]
+                D[71,158] = var(35); // [ var(158) , var(71) ]
+                D[73,158] = var(36); // [ var(158) , var(73) ]
+                D[78,158] = var(43); // [ var(158) , var(78) ]
+                D[80,158] = var(49); // [ var(158) , var(80) ]
+                D[85,158] = var(55); // [ var(158) , var(85) ]
+                D[86,158] = var(56); // [ var(158) , var(86) ]
+                D[90,158] = var(62); // [ var(158) , var(90) ]
+                D[97,158] = var(70); // [ var(158) , var(97) ]
+                D[100,158] = (-1)*var(74); // [ var(158) , var(100) ]
+                D[101,158] = var(77); // [ var(158) , var(101) ]
+                D[107,158] = (-1)*var(88); // [ var(158) , var(107) ]
+                D[109,158] = (-1)*var(92); // [ var(158) , var(109) ]
+                D[113,158] = (-1)*var(99); // [ var(158) , var(113) ]
+                D[115,158] = (-1)*var(102); // [ var(158) , var(115) ]
+                D[118,158] = var(110); // [ var(158) , var(118) ]
+                D[1,159] = (-1)*var(155); // [ var(159) , var(1) ]
+                D[7,159] = var(151); // [ var(159) , var(7) ]
+                D[9,159] = (-1)*var(148); // [ var(159) , var(9) ]
+                D[14,159] = var(144); // [ var(159) , var(14) ]
+                D[16,159] = (-1)*var(141); // [ var(159) , var(16) ]
+                D[21,159] = var(136); // [ var(159) , var(21) ]
+                D[24,159] = (-1)*var(134); // [ var(159) , var(24) ]
+                D[28,159] = var(129); // [ var(159) , var(28) ]
+                D[31,159] = (-1)*var(127); // [ var(159) , var(31) ]
+                D[35,159] = var(121); // [ var(159) , var(35) ]
+                D[39,159] = (-1)*var(241)+(-1)*var(243)+(-1)*var(244)+(-1)*var(245)+(-1)*var(246)+(-1)*var(247); // [ var(159) , var(39) ]
+                D[46,159] = var(2); // [ var(159) , var(46) ]
+                D[47,159] = (-1)*var(8); // [ var(159) , var(47) ]
+                D[53,159] = var(10); // [ var(159) , var(53) ]
+                D[58,159] = var(17); // [ var(159) , var(58) ]
+                D[59,159] = var(18); // [ var(159) , var(59) ]
+                D[64,159] = var(25); // [ var(159) , var(64) ]
+                D[66,159] = var(26); // [ var(159) , var(66) ]
+                D[70,159] = var(32); // [ var(159) , var(70) ]
+                D[71,159] = var(33); // [ var(159) , var(71) ]
+                D[76,159] = var(40); // [ var(159) , var(76) ]
+                D[79,159] = (-1)*var(42); // [ var(159) , var(79) ]
+                D[82,159] = var(48); // [ var(159) , var(82) ]
+                D[84,159] = (-1)*var(50); // [ var(159) , var(84) ]
+                D[88,159] = (-1)*var(56); // [ var(159) , var(88) ]
+                D[92,159] = (-1)*var(62); // [ var(159) , var(92) ]
+                D[96,159] = (-1)*var(68); // [ var(159) , var(96) ]
+                D[97,159] = (-1)*var(69); // [ var(159) , var(97) ]
+                D[104,159] = var(81); // [ var(159) , var(104) ]
+                D[107,159] = var(86); // [ var(159) , var(107) ]
+                D[109,159] = var(90); // [ var(159) , var(109) ]
+                D[111,159] = var(94); // [ var(159) , var(111) ]
+                D[114,159] = var(98); // [ var(159) , var(114) ]
+                D[119,159] = var(112); // [ var(159) , var(119) ]
+                D[4,160] = var(153); // [ var(160) , var(4) ]
+                D[6,160] = var(152); // [ var(160) , var(6) ]
+                D[10,160] = (-1)*var(147); // [ var(160) , var(10) ]
+                D[11,160] = (-1)*var(146); // [ var(160) , var(11) ]
+                D[17,160] = var(140); // [ var(160) , var(17) ]
+                D[20,160] = (-1)*var(137); // [ var(160) , var(20) ]
+                D[26,160] = var(131); // [ var(160) , var(26) ]
+                D[27,160] = var(130); // [ var(160) , var(27) ]
+                D[32,160] = (-1)*var(126); // [ var(160) , var(32) ]
+                D[33,160] = (-1)*var(124); // [ var(160) , var(33) ]
+                D[40,160] = (-1)*var(242)+(-1)*var(243)+(-2)*var(244)+(-1)*var(245)+(-1)*var(246); // [ var(160) , var(40) ]
+                D[45,160] = var(1); // [ var(160) , var(45) ]
+                D[48,160] = (-1)*var(5); // [ var(160) , var(48) ]
+                D[49,160] = (-1)*var(7); // [ var(160) , var(49) ]
+                D[51,160] = (-1)*var(9); // [ var(160) , var(51) ]
+                D[56,160] = (-1)*var(15); // [ var(160) , var(56) ]
+                D[61,160] = var(21); // [ var(160) , var(61) ]
+                D[63,160] = var(24); // [ var(160) , var(63) ]
+                D[68,160] = var(29); // [ var(160) , var(68) ]
+                D[69,160] = (-1)*var(30); // [ var(160) , var(69) ]
+                D[76,160] = (-1)*var(39); // [ var(160) , var(76) ]
+                D[80,160] = var(46); // [ var(160) , var(80) ]
+                D[83,160] = (-1)*var(47); // [ var(160) , var(83) ]
+                D[86,160] = var(54); // [ var(160) , var(86) ]
+                D[89,160] = (-1)*var(59); // [ var(160) , var(89) ]
+                D[93,160] = var(64); // [ var(160) , var(93) ]
+                D[94,160] = (-1)*var(67); // [ var(160) , var(94) ]
+                D[98,160] = var(72); // [ var(160) , var(98) ]
+                D[103,160] = var(79); // [ var(160) , var(103) ]
+                D[105,160] = (-1)*var(84); // [ var(160) , var(105) ]
+                D[110,160] = var(92); // [ var(160) , var(110) ]
+                D[112,160] = (-1)*var(95); // [ var(160) , var(112) ]
+                D[116,160] = var(104); // [ var(160) , var(116) ]
+                D[118,160] = (-1)*var(109); // [ var(160) , var(118) ]
+                D[2,161] = (-1)*var(155); // [ var(161) , var(2) ]
+                D[3,161] = (-1)*var(154); // [ var(161) , var(3) ]
+                D[7,161] = var(153); // [ var(161) , var(7) ]
+                D[14,161] = var(145); // [ var(161) , var(14) ]
+                D[17,161] = (-1)*var(141); // [ var(161) , var(17) ]
+                D[21,161] = var(137); // [ var(161) , var(21) ]
+                D[25,161] = (-1)*var(134); // [ var(161) , var(25) ]
+                D[33,161] = (-1)*var(127); // [ var(161) , var(33) ]
+                D[34,161] = var(123); // [ var(161) , var(34) ]
+                D[35,161] = var(122); // [ var(161) , var(35) ]
+                D[41,161] = (-1)*var(242)+(-1)*var(243)+(-1)*var(244)+(-1)*var(245)+(-1)*var(246)+(-1)*var(247); // [ var(161) , var(41) ]
+                D[46,161] = var(1); // [ var(161) , var(46) ]
+                D[49,161] = (-1)*var(4); // [ var(161) , var(49) ]
+                D[50,161] = (-1)*var(8); // [ var(161) , var(50) ]
+                D[55,161] = (-1)*var(12); // [ var(161) , var(55) ]
+                D[58,161] = var(16); // [ var(161) , var(58) ]
+                D[61,161] = (-1)*var(20); // [ var(161) , var(61) ]
+                D[64,161] = var(24); // [ var(161) , var(64) ]
+                D[71,161] = var(31); // [ var(161) , var(71) ]
+                D[74,161] = var(36); // [ var(161) , var(74) ]
+                D[75,161] = var(37); // [ var(161) , var(75) ]
+                D[80,161] = var(45); // [ var(161) , var(80) ]
+                D[84,161] = (-1)*var(47); // [ var(161) , var(84) ]
+                D[85,161] = var(52); // [ var(161) , var(85) ]
+                D[91,161] = (-1)*var(60); // [ var(161) , var(91) ]
+                D[93,161] = var(63); // [ var(161) , var(93) ]
+                D[95,161] = (-1)*var(67); // [ var(161) , var(95) ]
+                D[100,161] = (-1)*var(73); // [ var(161) , var(100) ]
+                D[102,161] = (-1)*var(77); // [ var(161) , var(102) ]
+                D[105,161] = (-1)*var(83); // [ var(161) , var(105) ]
+                D[108,161] = (-1)*var(87); // [ var(161) , var(108) ]
+                D[112,161] = (-1)*var(94); // [ var(161) , var(112) ]
+                D[115,161] = var(101); // [ var(161) , var(115) ]
+                D[119,161] = (-1)*var(111); // [ var(161) , var(119) ]
+                D[2,162] = (-1)*var(156); // [ var(162) , var(2) ]
+                D[8,162] = var(154); // [ var(162) , var(8) ]
+                D[10,162] = (-1)*var(149); // [ var(162) , var(10) ]
+                D[15,162] = var(146); // [ var(162) , var(15) ]
+                D[18,162] = (-1)*var(142); // [ var(162) , var(18) ]
+                D[22,162] = var(138); // [ var(162) , var(22) ]
+                D[26,162] = (-1)*var(135); // [ var(162) , var(26) ]
+                D[29,162] = var(130); // [ var(162) , var(29) ]
+                D[34,162] = (-1)*var(128); // [ var(162) , var(34) ]
+                D[36,162] = var(122); // [ var(162) , var(36) ]
+                D[42,162] = (-1)*var(242)+(-1)*var(244)+(-1)*var(245)+(-1)*var(246)+(-1)*var(247)+(-1)*var(248); // [ var(162) , var(42) ]
+                D[50,162] = var(3); // [ var(162) , var(50) ]
+                D[54,162] = var(9); // [ var(162) , var(54) ]
+                D[56,162] = var(11); // [ var(162) , var(56) ]
+                D[60,162] = var(16); // [ var(162) , var(60) ]
+                D[62,162] = var(19); // [ var(162) , var(62) ]
+                D[67,162] = var(24); // [ var(162) , var(67) ]
+                D[68,162] = var(27); // [ var(162) , var(68) ]
+                D[73,162] = var(31); // [ var(162) , var(73) ]
+                D[74,162] = var(35); // [ var(162) , var(74) ]
+                D[79,162] = var(39); // [ var(162) , var(79) ]
+                D[81,162] = (-1)*var(44); // [ var(162) , var(81) ]
+                D[86,162] = (-1)*var(51); // [ var(162) , var(86) ]
+                D[90,162] = (-1)*var(57); // [ var(162) , var(90) ]
+                D[91,162] = (-1)*var(58); // [ var(162) , var(91) ]
+                D[94,162] = (-1)*var(63); // [ var(162) , var(94) ]
+                D[95,162] = (-1)*var(64); // [ var(162) , var(95) ]
+                D[99,162] = (-1)*var(70); // [ var(162) , var(99) ]
+                D[100,162] = (-1)*var(71); // [ var(162) , var(100) ]
+                D[103,162] = (-1)*var(76); // [ var(162) , var(103) ]
+                D[106,162] = (-1)*var(82); // [ var(162) , var(106) ]
+                D[112,162] = var(93); // [ var(162) , var(112) ]
+                D[113,162] = var(97); // [ var(162) , var(113) ]
+                D[120,162] = var(114); // [ var(162) , var(120) ]
+                D[3,163] = (-1)*var(156); // [ var(163) , var(3) ]
+                D[8,163] = var(155); // [ var(163) , var(8) ]
+                D[11,163] = (-1)*var(149); // [ var(163) , var(11) ]
+                D[15,163] = var(147); // [ var(163) , var(15) ]
+                D[19,163] = (-1)*var(142); // [ var(163) , var(19) ]
+                D[22,163] = var(139); // [ var(163) , var(22) ]
+                D[27,163] = (-1)*var(135); // [ var(163) , var(27) ]
+                D[29,163] = var(131); // [ var(163) , var(29) ]
+                D[35,163] = (-1)*var(128); // [ var(163) , var(35) ]
+                D[36,163] = var(123); // [ var(163) , var(36) ]
+                D[43,163] = (-1)*var(243)+(-1)*var(244)+(-1)*var(245)+(-1)*var(246)+(-1)*var(247)+(-1)*var(248); // [ var(163) , var(43) ]
+                D[47,163] = var(1); // [ var(163) , var(47) ]
+                D[50,163] = var(2); // [ var(163) , var(50) ]
+                D[56,163] = var(10); // [ var(163) , var(56) ]
+                D[62,163] = var(18); // [ var(163) , var(62) ]
+                D[65,163] = (-1)*var(23); // [ var(163) , var(65) ]
+                D[68,163] = var(26); // [ var(163) , var(68) ]
+                D[72,163] = (-1)*var(30); // [ var(163) , var(72) ]
+                D[74,163] = var(34); // [ var(163) , var(74) ]
+                D[77,163] = (-1)*var(37); // [ var(163) , var(77) ]
+                D[78,163] = (-1)*var(38); // [ var(163) , var(78) ]
+                D[83,163] = (-1)*var(45); // [ var(163) , var(83) ]
+                D[84,163] = (-1)*var(46); // [ var(163) , var(84) ]
+                D[87,163] = (-1)*var(52); // [ var(163) , var(87) ]
+                D[88,163] = (-1)*var(53); // [ var(163) , var(88) ]
+                D[92,163] = (-1)*var(59); // [ var(163) , var(92) ]
+                D[96,163] = (-1)*var(66); // [ var(163) , var(96) ]
+                D[98,163] = var(69); // [ var(163) , var(98) ]
+                D[102,163] = var(75); // [ var(163) , var(102) ]
+                D[105,163] = var(80); // [ var(163) , var(105) ]
+                D[108,163] = var(85); // [ var(163) , var(108) ]
+                D[110,163] = var(89); // [ var(163) , var(110) ]
+                D[114,163] = (-1)*var(97); // [ var(163) , var(114) ]
+                D[120,163] = (-1)*var(113); // [ var(163) , var(120) ]
+                D[3,164] = (-1)*var(157); // [ var(164) , var(3) ]
+                D[9,164] = var(152); // [ var(164) , var(9) ]
+                D[11,164] = var(150); // [ var(164) , var(11) ]
+                D[16,164] = (-1)*var(145); // [ var(164) , var(16) ]
+                D[17,164] = (-1)*var(144); // [ var(164) , var(17) ]
+                D[19,164] = (-1)*var(143); // [ var(164) , var(19) ]
+                D[23,164] = var(139); // [ var(164) , var(23) ]
+                D[24,164] = var(137); // [ var(164) , var(24) ]
+                D[25,164] = var(136); // [ var(164) , var(25) ]
+                D[30,164] = (-1)*var(131); // [ var(164) , var(30) ]
+                D[32,164] = (-1)*var(129); // [ var(164) , var(32) ]
+                D[37,164] = var(123); // [ var(164) , var(37) ]
+                D[44,164] = (-1)*var(241)+(-1)*var(242)+(-2)*var(243)+(-2)*var(244)+(-1)*var(245); // [ var(164) , var(44) ]
+                D[51,164] = (-1)*var(6); // [ var(164) , var(51) ]
+                D[57,164] = var(13); // [ var(164) , var(57) ]
+                D[58,164] = (-1)*var(14); // [ var(164) , var(58) ]
+                D[63,164] = (-1)*var(20); // [ var(164) , var(63) ]
+                D[64,164] = var(21); // [ var(164) , var(64) ]
+                D[65,164] = (-1)*var(22); // [ var(164) , var(65) ]
+                D[69,164] = var(26); // [ var(164) , var(69) ]
+                D[70,164] = (-1)*var(28); // [ var(164) , var(70) ]
+                D[72,164] = var(29); // [ var(164) , var(72) ]
+                D[75,164] = var(34); // [ var(164) , var(75) ]
+                D[77,164] = (-1)*var(36); // [ var(164) , var(77) ]
+                D[81,164] = var(42); // [ var(164) , var(81) ]
+                D[93,164] = var(61); // [ var(164) , var(93) ]
+                D[97,164] = (-1)*var(66); // [ var(164) , var(97) ]
+                D[98,164] = var(68); // [ var(164) , var(98) ]
+                D[101,164] = (-1)*var(73); // [ var(164) , var(101) ]
+                D[102,164] = var(74); // [ var(164) , var(102) ]
+                D[104,164] = (-1)*var(79); // [ var(164) , var(104) ]
+                D[114,164] = (-1)*var(96); // [ var(164) , var(114) ]
+                D[115,164] = var(100); // [ var(164) , var(115) ]
+                D[116,164] = (-1)*var(103); // [ var(164) , var(116) ]
+                D[117,164] = var(106); // [ var(164) , var(117) ]
+                D[1,165] = (-1)*var(160); // [ var(165) , var(1) ]
+                D[4,165] = var(158); // [ var(165) , var(4) ]
+                D[6,165] = var(157); // [ var(165) , var(6) ]
+                D[10,165] = (-1)*var(151); // [ var(165) , var(10) ]
+                D[16,165] = (-1)*var(146); // [ var(165) , var(16) ]
+                D[20,165] = (-1)*var(143); // [ var(165) , var(20) ]
+                D[23,165] = var(140); // [ var(165) , var(23) ]
+                D[26,165] = var(136); // [ var(165) , var(26) ]
+                D[31,165] = var(130); // [ var(165) , var(31) ]
+                D[37,165] = (-1)*var(126); // [ var(165) , var(37) ]
+                D[38,165] = (-1)*var(124); // [ var(165) , var(38) ]
+                D[40,165] = var(121); // [ var(165) , var(40) ]
+                D[45,165] = (-1)*var(241)+(-1)*var(242)+(-1)*var(243)+(-2)*var(244)+(-1)*var(245)+(-1)*var(246); // [ var(165) , var(45) ]
+                D[51,165] = var(3); // [ var(165) , var(51) ]
+                D[52,165] = (-1)*var(5); // [ var(165) , var(52) ]
+                D[53,165] = (-1)*var(7); // [ var(165) , var(53) ]
+                D[60,165] = (-1)*var(15); // [ var(165) , var(60) ]
+                D[63,165] = (-1)*var(19); // [ var(165) , var(63) ]
+                D[66,165] = var(21); // [ var(165) , var(66) ]
+                D[69,165] = var(25); // [ var(165) , var(69) ]
+                D[73,165] = var(29); // [ var(165) , var(73) ]
+                D[76,165] = var(35); // [ var(165) , var(76) ]
+                D[80,165] = (-1)*var(41); // [ var(165) , var(80) ]
+                D[83,165] = var(43); // [ var(165) , var(83) ]
+                D[86,165] = (-1)*var(50); // [ var(165) , var(86) ]
+                D[89,165] = var(55); // [ var(165) , var(89) ]
+                D[94,165] = var(62); // [ var(165) , var(94) ]
+                D[97,165] = (-1)*var(64); // [ var(165) , var(97) ]
+                D[101,165] = (-1)*var(72); // [ var(165) , var(101) ]
+                D[103,165] = (-1)*var(74); // [ var(165) , var(103) ]
+                D[107,165] = var(84); // [ var(165) , var(107) ]
+                D[111,165] = (-1)*var(92); // [ var(165) , var(111) ]
+                D[113,165] = var(95); // [ var(165) , var(113) ]
+                D[116,165] = var(102); // [ var(165) , var(116) ]
+                D[118,165] = (-1)*var(108); // [ var(165) , var(118) ]
+                D[1,166] = (-1)*var(161); // [ var(166) , var(1) ]
+                D[2,166] = (-1)*var(159); // [ var(166) , var(2) ]
+                D[7,166] = var(158); // [ var(166) , var(7) ]
+                D[9,166] = (-1)*var(154); // [ var(166) , var(9) ]
+                D[14,166] = var(150); // [ var(166) , var(14) ]
+                D[21,166] = var(143); // [ var(166) , var(21) ]
+                D[23,166] = (-1)*var(141); // [ var(166) , var(23) ]
+                D[30,166] = (-1)*var(134); // [ var(166) , var(30) ]
+                D[34,166] = var(129); // [ var(166) , var(34) ]
+                D[38,166] = (-1)*var(127); // [ var(166) , var(38) ]
+                D[39,166] = var(122); // [ var(166) , var(39) ]
+                D[41,166] = var(121); // [ var(166) , var(41) ]
+                D[46,166] = (-1)*var(241)+(-1)*var(242)+(-1)*var(243)+(-1)*var(244)+(-1)*var(245)+(-1)*var(246)+(-1)*var(247); // [ var(166) , var(46) ]
+                D[53,166] = (-1)*var(4); // [ var(166) , var(53) ]
+                D[54,166] = (-1)*var(8); // [ var(166) , var(54) ]
+                D[58,166] = (-1)*var(11); // [ var(166) , var(58) ]
+                D[59,166] = (-1)*var(12); // [ var(166) , var(59) ]
+                D[64,166] = (-1)*var(19); // [ var(166) , var(64) ]
+                D[66,166] = (-1)*var(20); // [ var(166) , var(66) ]
+                D[71,166] = (-1)*var(27); // [ var(166) , var(71) ]
+                D[75,166] = (-1)*var(32); // [ var(166) , var(75) ]
+                D[79,166] = var(36); // [ var(166) , var(79) ]
+                D[80,166] = (-1)*var(40); // [ var(166) , var(80) ]
+                D[84,166] = var(43); // [ var(166) , var(84) ]
+                D[85,166] = (-1)*var(48); // [ var(166) , var(85) ]
+                D[91,166] = var(56); // [ var(166) , var(91) ]
+                D[95,166] = var(62); // [ var(166) , var(95) ]
+                D[97,166] = (-1)*var(63); // [ var(166) , var(97) ]
+                D[100,166] = var(68); // [ var(166) , var(100) ]
+                D[104,166] = var(77); // [ var(166) , var(104) ]
+                D[107,166] = var(83); // [ var(166) , var(107) ]
+                D[109,166] = var(87); // [ var(166) , var(109) ]
+                D[113,166] = var(94); // [ var(166) , var(113) ]
+                D[115,166] = var(98); // [ var(166) , var(115) ]
+                D[119,166] = (-1)*var(110); // [ var(166) , var(119) ]
+                D[1,167] = (-1)*var(163); // [ var(167) , var(1) ]
+                D[8,167] = var(159); // [ var(167) , var(8) ]
+                D[9,167] = (-1)*var(156); // [ var(167) , var(9) ]
+                D[15,167] = var(151); // [ var(167) , var(15) ]
+                D[16,167] = (-1)*var(149); // [ var(167) , var(16) ]
+                D[22,167] = var(144); // [ var(167) , var(22) ]
+                D[24,167] = (-1)*var(142); // [ var(167) , var(24) ]
+                D[29,167] = var(136); // [ var(167) , var(29) ]
+                D[31,167] = (-1)*var(135); // [ var(167) , var(31) ]
+                D[36,167] = var(129); // [ var(167) , var(36) ]
+                D[39,167] = (-1)*var(128); // [ var(167) , var(39) ]
+                D[43,167] = var(121); // [ var(167) , var(43) ]
+                D[47,167] = (-1)*var(241)+(-1)*var(243)+(-1)*var(244)+(-1)*var(245)+(-1)*var(246)+(-1)*var(247)+(-1)*var(248); // [ var(167) , var(47) ]
+                D[54,167] = var(2); // [ var(167) , var(54) ]
+                D[60,167] = var(10); // [ var(167) , var(60) ]
+                D[65,167] = var(17); // [ var(167) , var(65) ]
+                D[67,167] = var(18); // [ var(167) , var(67) ]
+                D[72,167] = var(25); // [ var(167) , var(72) ]
+                D[73,167] = var(26); // [ var(167) , var(73) ]
+                D[77,167] = var(32); // [ var(167) , var(77) ]
+                D[78,167] = var(33); // [ var(167) , var(78) ]
+                D[79,167] = var(34); // [ var(167) , var(79) ]
+                D[83,167] = var(40); // [ var(167) , var(83) ]
+                D[84,167] = var(41); // [ var(167) , var(84) ]
+                D[87,167] = var(48); // [ var(167) , var(87) ]
+                D[88,167] = var(49); // [ var(167) , var(88) ]
+                D[92,167] = var(55); // [ var(167) , var(92) ]
+                D[96,167] = var(61); // [ var(167) , var(96) ]
+                D[101,167] = (-1)*var(69); // [ var(167) , var(101) ]
+                D[104,167] = (-1)*var(75); // [ var(167) , var(104) ]
+                D[107,167] = (-1)*var(80); // [ var(167) , var(107) ]
+                D[109,167] = (-1)*var(85); // [ var(167) , var(109) ]
+                D[111,167] = (-1)*var(89); // [ var(167) , var(111) ]
+                D[114,167] = (-1)*var(93); // [ var(167) , var(114) ]
+                D[120,167] = (-1)*var(112); // [ var(167) , var(120) ]
+                D[5,168] = var(160); // [ var(168) , var(5) ]
+                D[12,168] = var(153); // [ var(168) , var(12) ]
+                D[13,168] = (-1)*var(152); // [ var(168) , var(13) ]
+                D[18,168] = (-1)*var(147); // [ var(168) , var(18) ]
+                D[19,168] = (-1)*var(146); // [ var(168) , var(19) ]
+                D[20,168] = (-1)*var(145); // [ var(168) , var(20) ]
+                D[25,168] = var(140); // [ var(168) , var(25) ]
+                D[26,168] = var(139); // [ var(168) , var(26) ]
+                D[27,168] = var(138); // [ var(168) , var(27) ]
+                D[32,168] = var(133); // [ var(168) , var(32) ]
+                D[33,168] = (-1)*var(132); // [ var(168) , var(33) ]
+                D[40,168] = (-1)*var(125); // [ var(168) , var(40) ]
+                D[48,168] = (-1)*var(242)+(-1)*var(243)+(-2)*var(244)+(-2)*var(245)+(-1)*var(246); // [ var(168) , var(48) ]
+                D[52,168] = var(1); // [ var(168) , var(52) ]
+                D[55,168] = (-1)*var(7); // [ var(168) , var(55) ]
+                D[57,168] = (-1)*var(9); // [ var(168) , var(57) ]
+                D[61,168] = var(14); // [ var(168) , var(61) ]
+                D[62,168] = (-1)*var(15); // [ var(168) , var(62) ]
+                D[63,168] = (-1)*var(16); // [ var(168) , var(63) ]
+                D[68,168] = var(22); // [ var(168) , var(68) ]
+                D[69,168] = var(23); // [ var(168) , var(69) ]
+                D[82,168] = (-1)*var(39); // [ var(168) , var(82) ]
+                D[85,168] = var(46); // [ var(168) , var(85) ]
+                D[87,168] = (-1)*var(47); // [ var(168) , var(87) ]
+                D[89,168] = var(53); // [ var(168) , var(89) ]
+                D[90,168] = var(54); // [ var(168) , var(90) ]
+                D[93,168] = (-1)*var(58); // [ var(168) , var(93) ]
+                D[94,168] = var(60); // [ var(168) , var(94) ]
+                D[98,168] = (-1)*var(65); // [ var(168) , var(98) ]
+                D[106,168] = var(79); // [ var(168) , var(106) ]
+                D[108,168] = (-1)*var(84); // [ var(168) , var(108) ]
+                D[110,168] = (-1)*var(88); // [ var(168) , var(110) ]
+                D[112,168] = var(91); // [ var(168) , var(112) ]
+                D[117,168] = (-1)*var(104); // [ var(168) , var(117) ]
+                D[118,168] = var(107); // [ var(168) , var(118) ]
+                D[4,169] = var(161); // [ var(169) , var(4) ]
+                D[7,169] = var(160); // [ var(169) , var(7) ]
+                D[10,169] = (-1)*var(155); // [ var(169) , var(10) ]
+                D[11,169] = (-1)*var(154); // [ var(169) , var(11) ]
+                D[14,169] = var(152); // [ var(169) , var(14) ]
+                D[17,169] = var(148); // [ var(169) , var(17) ]
+                D[28,169] = (-1)*var(137); // [ var(169) , var(28) ]
+                D[32,169] = (-1)*var(134); // [ var(169) , var(32) ]
+                D[34,169] = var(131); // [ var(169) , var(34) ]
+                D[35,169] = var(130); // [ var(169) , var(35) ]
+                D[40,169] = (-1)*var(127); // [ var(169) , var(40) ]
+                D[41,169] = (-1)*var(124); // [ var(169) , var(41) ]
+                D[49,169] = (-1)*var(242)+(-1)*var(243)+(-2)*var(244)+(-1)*var(245)+(-1)*var(246)+(-1)*var(247); // [ var(169) , var(49) ]
+                D[53,169] = var(1); // [ var(169) , var(53) ]
+                D[55,169] = (-1)*var(5); // [ var(169) , var(55) ]
+                D[56,169] = (-1)*var(8); // [ var(169) , var(56) ]
+                D[58,169] = (-1)*var(9); // [ var(169) , var(58) ]
+                D[61,169] = (-1)*var(13); // [ var(169) , var(61) ]
+                D[70,169] = var(24); // [ var(169) , var(70) ]
+                D[74,169] = var(29); // [ var(169) , var(74) ]
+                D[75,169] = (-1)*var(30); // [ var(169) , var(75) ]
+                D[76,169] = var(31); // [ var(169) , var(76) ]
+                D[80,169] = (-1)*var(38); // [ var(169) , var(80) ]
+                D[88,169] = (-1)*var(47); // [ var(169) , var(88) ]
+                D[89,169] = var(52); // [ var(169) , var(89) ]
+                D[91,169] = var(54); // [ var(169) , var(91) ]
+                D[93,169] = (-1)*var(57); // [ var(169) , var(93) ]
+                D[99,169] = (-1)*var(67); // [ var(169) , var(99) ]
+                D[102,169] = var(72); // [ var(169) , var(102) ]
+                D[103,169] = (-1)*var(73); // [ var(169) , var(103) ]
+                D[105,169] = var(78); // [ var(169) , var(105) ]
+                D[110,169] = (-1)*var(87); // [ var(169) , var(110) ]
+                D[112,169] = var(90); // [ var(169) , var(112) ]
+                D[116,169] = (-1)*var(101); // [ var(169) , var(116) ]
+                D[119,169] = var(109); // [ var(169) , var(119) ]
+                D[2,170] = (-1)*var(163); // [ var(170) , var(2) ]
+                D[3,170] = (-1)*var(162); // [ var(170) , var(3) ]
+                D[8,170] = var(161); // [ var(170) , var(8) ]
+                D[15,170] = var(153); // [ var(170) , var(15) ]
+                D[17,170] = (-1)*var(149); // [ var(170) , var(17) ]
+                D[22,170] = var(145); // [ var(170) , var(22) ]
+                D[25,170] = (-1)*var(142); // [ var(170) , var(25) ]
+                D[29,170] = var(137); // [ var(170) , var(29) ]
+                D[33,170] = (-1)*var(135); // [ var(170) , var(33) ]
+                D[41,170] = (-1)*var(128); // [ var(170) , var(41) ]
+                D[42,170] = var(123); // [ var(170) , var(42) ]
+                D[43,170] = var(122); // [ var(170) , var(43) ]
+                D[50,170] = (-1)*var(242)+(-1)*var(243)+(-1)*var(244)+(-1)*var(245)+(-1)*var(246)+(-1)*var(247)+(-1)*var(248); // [ var(170) , var(50) ]
+                D[54,170] = var(1); // [ var(170) , var(54) ]
+                D[56,170] = (-1)*var(4); // [ var(170) , var(56) ]
+                D[62,170] = (-1)*var(12); // [ var(170) , var(62) ]
+                D[65,170] = var(16); // [ var(170) , var(65) ]
+                D[68,170] = (-1)*var(20); // [ var(170) , var(68) ]
+                D[72,170] = var(24); // [ var(170) , var(72) ]
+                D[74,170] = (-1)*var(28); // [ var(170) , var(74) ]
+                D[78,170] = var(31); // [ var(170) , var(78) ]
+                D[81,170] = var(37); // [ var(170) , var(81) ]
+                D[84,170] = var(39); // [ var(170) , var(84) ]
+                D[86,170] = var(45); // [ var(170) , var(86) ]
+                D[90,170] = var(52); // [ var(170) , var(90) ]
+                D[91,170] = var(53); // [ var(170) , var(91) ]
+                D[95,170] = var(59); // [ var(170) , var(95) ]
+                D[98,170] = var(63); // [ var(170) , var(98) ]
+                D[100,170] = var(66); // [ var(170) , var(100) ]
+                D[102,170] = var(70); // [ var(170) , var(102) ]
+                D[105,170] = var(76); // [ var(170) , var(105) ]
+                D[108,170] = var(82); // [ var(170) , var(108) ]
+                D[112,170] = var(89); // [ var(170) , var(112) ]
+                D[115,170] = (-1)*var(97); // [ var(170) , var(115) ]
+                D[120,170] = var(111); // [ var(170) , var(120) ]
+                D[3,171] = (-1)*var(165); // [ var(171) , var(3) ]
+                D[6,171] = var(164); // [ var(171) , var(6) ]
+                D[9,171] = var(160); // [ var(171) , var(9) ]
+                D[11,171] = var(158); // [ var(171) , var(11) ]
+                D[16,171] = (-1)*var(153); // [ var(171) , var(16) ]
+                D[17,171] = (-1)*var(151); // [ var(171) , var(17) ]
+                D[23,171] = var(147); // [ var(171) , var(23) ]
+                D[27,171] = (-1)*var(143); // [ var(171) , var(27) ]
+                D[31,171] = var(137); // [ var(171) , var(31) ]
+                D[33,171] = var(136); // [ var(171) , var(33) ]
+                D[38,171] = (-1)*var(131); // [ var(171) , var(38) ]
+                D[40,171] = (-1)*var(129); // [ var(171) , var(40) ]
+                D[44,171] = (-1)*var(126); // [ var(171) , var(44) ]
+                D[45,171] = var(123); // [ var(171) , var(45) ]
+                D[51,171] = (-1)*var(241)+(-1)*var(242)+(-2)*var(243)+(-2)*var(244)+(-1)*var(245)+(-1)*var(246); // [ var(171) , var(51) ]
+                D[57,171] = (-1)*var(5); // [ var(171) , var(57) ]
+                D[58,171] = (-1)*var(7); // [ var(171) , var(58) ]
+                D[63,171] = var(12); // [ var(171) , var(63) ]
+                D[65,171] = (-1)*var(15); // [ var(171) , var(65) ]
+                D[69,171] = (-1)*var(18); // [ var(171) , var(69) ]
+                D[71,171] = var(21); // [ var(171) , var(71) ]
+                D[76,171] = (-1)*var(28); // [ var(171) , var(76) ]
+                D[78,171] = var(29); // [ var(171) , var(78) ]
+                D[80,171] = var(34); // [ var(171) , var(80) ]
+                D[83,171] = (-1)*var(36); // [ var(171) , var(83) ]
+                D[86,171] = var(42); // [ var(171) , var(86) ]
+                D[93,171] = (-1)*var(55); // [ var(171) , var(93) ]
+                D[97,171] = var(59); // [ var(171) , var(97) ]
+                D[98,171] = (-1)*var(62); // [ var(171) , var(98) ]
+                D[101,171] = var(67); // [ var(171) , var(101) ]
+                D[105,171] = var(74); // [ var(171) , var(105) ]
+                D[107,171] = (-1)*var(79); // [ var(171) , var(107) ]
+                D[114,171] = var(92); // [ var(171) , var(114) ]
+                D[115,171] = (-1)*var(95); // [ var(171) , var(115) ]
+                D[116,171] = var(99); // [ var(171) , var(116) ]
+                D[118,171] = (-1)*var(106); // [ var(171) , var(118) ]
+                D[1,172] = (-1)*var(168); // [ var(172) , var(1) ]
+                D[5,172] = var(165); // [ var(172) , var(5) ]
+                D[12,172] = var(158); // [ var(172) , var(12) ]
+                D[13,172] = (-1)*var(157); // [ var(172) , var(13) ]
+                D[18,172] = (-1)*var(151); // [ var(172) , var(18) ]
+                D[20,172] = (-1)*var(150); // [ var(172) , var(20) ]
+                D[24,172] = (-1)*var(146); // [ var(172) , var(24) ]
+                D[26,172] = var(144); // [ var(172) , var(26) ]
+                D[30,172] = var(140); // [ var(172) , var(30) ]
+                D[31,172] = var(138); // [ var(172) , var(31) ]
+                D[37,172] = var(133); // [ var(172) , var(37) ]
+                D[38,172] = (-1)*var(132); // [ var(172) , var(38) ]
+                D[45,172] = (-1)*var(125); // [ var(172) , var(45) ]
+                D[48,172] = var(121); // [ var(172) , var(48) ]
+                D[52,172] = (-1)*var(241)+(-1)*var(242)+(-1)*var(243)+(-2)*var(244)+(-2)*var(245)+(-1)*var(246); // [ var(172) , var(52) ]
+                D[57,172] = var(3); // [ var(172) , var(57) ]
+                D[59,172] = (-1)*var(7); // [ var(172) , var(59) ]
+                D[63,172] = var(11); // [ var(172) , var(63) ]
+                D[66,172] = var(14); // [ var(172) , var(66) ]
+                D[67,172] = (-1)*var(15); // [ var(172) , var(67) ]
+                D[69,172] = (-1)*var(17); // [ var(172) , var(69) ]
+                D[73,172] = var(22); // [ var(172) , var(73) ]
+                D[82,172] = var(35); // [ var(172) , var(82) ]
+                D[85,172] = (-1)*var(41); // [ var(172) , var(85) ]
+                D[87,172] = var(43); // [ var(172) , var(87) ]
+                D[89,172] = (-1)*var(49); // [ var(172) , var(89) ]
+                D[90,172] = (-1)*var(50); // [ var(172) , var(90) ]
+                D[94,172] = (-1)*var(56); // [ var(172) , var(94) ]
+                D[97,172] = var(58); // [ var(172) , var(97) ]
+                D[101,172] = var(65); // [ var(172) , var(101) ]
+                D[106,172] = (-1)*var(74); // [ var(172) , var(106) ]
+                D[109,172] = var(84); // [ var(172) , var(109) ]
+                D[111,172] = var(88); // [ var(172) , var(111) ]
+                D[113,172] = (-1)*var(91); // [ var(172) , var(113) ]
+                D[117,172] = (-1)*var(102); // [ var(172) , var(117) ]
+                D[118,172] = var(105); // [ var(172) , var(118) ]
+                D[1,173] = (-1)*var(169); // [ var(173) , var(1) ]
+                D[4,173] = var(166); // [ var(173) , var(4) ]
+                D[7,173] = var(165); // [ var(173) , var(7) ]
+                D[10,173] = (-1)*var(159); // [ var(173) , var(10) ]
+                D[14,173] = var(157); // [ var(173) , var(14) ]
+                D[16,173] = (-1)*var(154); // [ var(173) , var(16) ]
+                D[23,173] = var(148); // [ var(173) , var(23) ]
+                D[28,173] = (-1)*var(143); // [ var(173) , var(28) ]
+                D[34,173] = var(136); // [ var(173) , var(34) ]
+                D[37,173] = (-1)*var(134); // [ var(173) , var(37) ]
+                D[39,173] = var(130); // [ var(173) , var(39) ]
+                D[45,173] = (-1)*var(127); // [ var(173) , var(45) ]
+                D[46,173] = (-1)*var(124); // [ var(173) , var(46) ]
+                D[49,173] = var(121); // [ var(173) , var(49) ]
+                D[53,173] = (-1)*var(241)+(-1)*var(242)+(-1)*var(243)+(-2)*var(244)+(-1)*var(245)+(-1)*var(246)+(-1)*var(247); // [ var(173) , var(53) ]
+                D[58,173] = var(3); // [ var(173) , var(58) ]
+                D[59,173] = (-1)*var(5); // [ var(173) , var(59) ]
+                D[60,173] = (-1)*var(8); // [ var(173) , var(60) ]
+                D[66,173] = (-1)*var(13); // [ var(173) , var(66) ]
+                D[70,173] = (-1)*var(19); // [ var(173) , var(70) ]
+                D[75,173] = var(25); // [ var(173) , var(75) ]
+                D[76,173] = (-1)*var(27); // [ var(173) , var(76) ]
+                D[79,173] = var(29); // [ var(173) , var(79) ]
+                D[80,173] = var(33); // [ var(173) , var(80) ]
+                D[88,173] = var(43); // [ var(173) , var(88) ]
+                D[89,173] = (-1)*var(48); // [ var(173) , var(89) ]
+                D[91,173] = (-1)*var(50); // [ var(173) , var(91) ]
+                D[97,173] = var(57); // [ var(173) , var(97) ]
+                D[99,173] = var(62); // [ var(173) , var(99) ]
+                D[103,173] = var(68); // [ var(173) , var(103) ]
+                D[104,173] = (-1)*var(72); // [ var(173) , var(104) ]
+                D[107,173] = (-1)*var(78); // [ var(173) , var(107) ]
+                D[111,173] = var(87); // [ var(173) , var(111) ]
+                D[113,173] = (-1)*var(90); // [ var(173) , var(113) ]
+                D[116,173] = (-1)*var(98); // [ var(173) , var(116) ]
+                D[119,173] = var(108); // [ var(173) , var(119) ]
+                D[1,174] = (-1)*var(170); // [ var(174) , var(1) ]
+                D[2,174] = (-1)*var(167); // [ var(174) , var(2) ]
+                D[8,174] = var(166); // [ var(174) , var(8) ]
+                D[9,174] = (-1)*var(162); // [ var(174) , var(9) ]
+                D[15,174] = var(158); // [ var(174) , var(15) ]
+                D[22,174] = var(150); // [ var(174) , var(22) ]
+                D[23,174] = (-1)*var(149); // [ var(174) , var(23) ]
+                D[29,174] = var(143); // [ var(174) , var(29) ]
+                D[30,174] = (-1)*var(142); // [ var(174) , var(30) ]
+                D[38,174] = (-1)*var(135); // [ var(174) , var(38) ]
+                D[42,174] = var(129); // [ var(174) , var(42) ]
+                D[46,174] = (-1)*var(128); // [ var(174) , var(46) ]
+                D[47,174] = var(122); // [ var(174) , var(47) ]
+                D[50,174] = var(121); // [ var(174) , var(50) ]
+                D[54,174] = (-1)*var(241)+(-1)*var(242)+(-1)*var(243)+(-1)*var(244)+(-1)*var(245)+(-1)*var(246)+(-1)*var(247)+(-1)*var(248); // [ var(174) , var(54) ]
+                D[60,174] = (-1)*var(4); // [ var(174) , var(60) ]
+                D[65,174] = (-1)*var(11); // [ var(174) , var(65) ]
+                D[67,174] = (-1)*var(12); // [ var(174) , var(67) ]
+                D[72,174] = (-1)*var(19); // [ var(174) , var(72) ]
+                D[73,174] = (-1)*var(20); // [ var(174) , var(73) ]
+                D[78,174] = (-1)*var(27); // [ var(174) , var(78) ]
+                D[79,174] = (-1)*var(28); // [ var(174) , var(79) ]
+                D[81,174] = (-1)*var(32); // [ var(174) , var(81) ]
+                D[84,174] = (-1)*var(35); // [ var(174) , var(84) ]
+                D[86,174] = (-1)*var(40); // [ var(174) , var(86) ]
+                D[90,174] = (-1)*var(48); // [ var(174) , var(90) ]
+                D[91,174] = (-1)*var(49); // [ var(174) , var(91) ]
+                D[95,174] = (-1)*var(55); // [ var(174) , var(95) ]
+                D[100,174] = (-1)*var(61); // [ var(174) , var(100) ]
+                D[101,174] = (-1)*var(63); // [ var(174) , var(101) ]
+                D[104,174] = (-1)*var(70); // [ var(174) , var(104) ]
+                D[107,174] = (-1)*var(76); // [ var(174) , var(107) ]
+                D[109,174] = (-1)*var(82); // [ var(174) , var(109) ]
+                D[113,174] = (-1)*var(89); // [ var(174) , var(113) ]
+                D[115,174] = (-1)*var(93); // [ var(174) , var(115) ]
+                D[120,174] = var(110); // [ var(174) , var(120) ]
+                D[5,175] = var(169); // [ var(175) , var(5) ]
+                D[7,175] = var(168); // [ var(175) , var(7) ]
+                D[12,175] = var(161); // [ var(175) , var(12) ]
+                D[18,175] = (-1)*var(155); // [ var(175) , var(18) ]
+                D[19,175] = (-1)*var(154); // [ var(175) , var(19) ]
+                D[21,175] = (-1)*var(152); // [ var(175) , var(21) ]
+                D[25,175] = var(148); // [ var(175) , var(25) ]
+                D[28,175] = (-1)*var(145); // [ var(175) , var(28) ]
+                D[32,175] = var(141); // [ var(175) , var(32) ]
+                D[34,175] = var(139); // [ var(175) , var(34) ]
+                D[35,175] = var(138); // [ var(175) , var(35) ]
+                D[41,175] = (-1)*var(132); // [ var(175) , var(41) ]
+                D[48,175] = (-1)*var(127); // [ var(175) , var(48) ]
+                D[49,175] = (-1)*var(125); // [ var(175) , var(49) ]
+                D[55,175] = (-1)*var(242)+(-1)*var(243)+(-2)*var(244)+(-2)*var(245)+(-1)*var(246)+(-1)*var(247); // [ var(175) , var(55) ]
+                D[59,175] = var(1); // [ var(175) , var(59) ]
+                D[61,175] = (-1)*var(6); // [ var(175) , var(61) ]
+                D[62,175] = (-1)*var(8); // [ var(175) , var(62) ]
+                D[64,175] = (-1)*var(9); // [ var(175) , var(64) ]
+                D[70,175] = (-1)*var(16); // [ var(175) , var(70) ]
+                D[74,175] = var(22); // [ var(175) , var(74) ]
+                D[75,175] = var(23); // [ var(175) , var(75) ]
+                D[82,175] = var(31); // [ var(175) , var(82) ]
+                D[85,175] = (-1)*var(38); // [ var(175) , var(85) ]
+                D[89,175] = (-1)*var(45); // [ var(175) , var(89) ]
+                D[92,175] = (-1)*var(47); // [ var(175) , var(92) ]
+                D[93,175] = var(51); // [ var(175) , var(93) ]
+                D[95,175] = var(54); // [ var(175) , var(95) ]
+                D[99,175] = var(60); // [ var(175) , var(99) ]
+                D[102,175] = (-1)*var(65); // [ var(175) , var(102) ]
+                D[106,175] = (-1)*var(73); // [ var(175) , var(106) ]
+                D[108,175] = var(78); // [ var(175) , var(108) ]
+                D[110,175] = var(83); // [ var(175) , var(110) ]
+                D[112,175] = (-1)*var(86); // [ var(175) , var(112) ]
+                D[117,175] = var(101); // [ var(175) , var(117) ]
+                D[119,175] = (-1)*var(107); // [ var(175) , var(119) ]
+                D[4,176] = var(170); // [ var(176) , var(4) ]
+                D[8,176] = var(169); // [ var(176) , var(8) ]
+                D[10,176] = (-1)*var(163); // [ var(176) , var(10) ]
+                D[11,176] = (-1)*var(162); // [ var(176) , var(11) ]
+                D[15,176] = var(160); // [ var(176) , var(15) ]
+                D[17,176] = var(156); // [ var(176) , var(17) ]
+                D[22,176] = var(152); // [ var(176) , var(22) ]
+                D[32,176] = (-1)*var(142); // [ var(176) , var(32) ]
+                D[36,176] = (-1)*var(137); // [ var(176) , var(36) ]
+                D[40,176] = (-1)*var(135); // [ var(176) , var(40) ]
+                D[42,176] = var(131); // [ var(176) , var(42) ]
+                D[43,176] = var(130); // [ var(176) , var(43) ]
+                D[49,176] = (-1)*var(128); // [ var(176) , var(49) ]
+                D[50,176] = (-1)*var(124); // [ var(176) , var(50) ]
+                D[56,176] = (-1)*var(242)+(-1)*var(243)+(-2)*var(244)+(-1)*var(245)+(-1)*var(246)+(-1)*var(247)+(-1)*var(248); // [ var(176) , var(56) ]
+                D[60,176] = var(1); // [ var(176) , var(60) ]
+                D[62,176] = (-1)*var(5); // [ var(176) , var(62) ]
+                D[65,176] = (-1)*var(9); // [ var(176) , var(65) ]
+                D[68,176] = (-1)*var(13); // [ var(176) , var(68) ]
+                D[74,176] = (-1)*var(21); // [ var(176) , var(74) ]
+                D[77,176] = var(24); // [ var(176) , var(77) ]
+                D[81,176] = (-1)*var(30); // [ var(176) , var(81) ]
+                D[83,176] = var(31); // [ var(176) , var(83) ]
+                D[86,176] = (-1)*var(38); // [ var(176) , var(86) ]
+                D[88,176] = var(39); // [ var(176) , var(88) ]
+                D[91,176] = (-1)*var(46); // [ var(176) , var(91) ]
+                D[94,176] = var(52); // [ var(176) , var(94) ]
+                D[98,176] = (-1)*var(57); // [ var(176) , var(98) ]
+                D[99,176] = var(59); // [ var(176) , var(99) ]
+                D[102,176] = (-1)*var(64); // [ var(176) , var(102) ]
+                D[103,176] = var(66); // [ var(176) , var(103) ]
+                D[105,176] = (-1)*var(71); // [ var(176) , var(105) ]
+                D[110,176] = var(82); // [ var(176) , var(110) ]
+                D[112,176] = (-1)*var(85); // [ var(176) , var(112) ]
+                D[116,176] = var(97); // [ var(176) , var(116) ]
+                D[120,176] = (-1)*var(109); // [ var(176) , var(120) ]
+                D[3,177] = (-1)*var(172); // [ var(177) , var(3) ]
+                D[5,177] = var(171); // [ var(177) , var(5) ]
+                D[9,177] = var(168); // [ var(177) , var(9) ]
+                D[13,177] = (-1)*var(164); // [ var(177) , var(13) ]
+                D[19,177] = var(158); // [ var(177) , var(19) ]
+                D[24,177] = (-1)*var(153); // [ var(177) , var(24) ]
+                D[25,177] = (-1)*var(151); // [ var(177) , var(25) ]
+                D[27,177] = (-1)*var(150); // [ var(177) , var(27) ]
+                D[30,177] = var(147); // [ var(177) , var(30) ]
+                D[31,177] = var(145); // [ var(177) , var(31) ]
+                D[33,177] = var(144); // [ var(177) , var(33) ]
+                D[38,177] = (-1)*var(139); // [ var(177) , var(38) ]
+                D[44,177] = var(133); // [ var(177) , var(44) ]
+                D[48,177] = (-1)*var(129); // [ var(177) , var(48) ]
+                D[51,177] = (-1)*var(125); // [ var(177) , var(51) ]
+                D[52,177] = var(123); // [ var(177) , var(52) ]
+                D[57,177] = (-1)*var(241)+(-1)*var(242)+(-2)*var(243)+(-2)*var(244)+(-2)*var(245)+(-1)*var(246); // [ var(177) , var(57) ]
+                D[63,177] = (-1)*var(4); // [ var(177) , var(63) ]
+                D[64,177] = (-1)*var(7); // [ var(177) , var(64) ]
+                D[69,177] = var(10); // [ var(177) , var(69) ]
+                D[71,177] = var(14); // [ var(177) , var(71) ]
+                D[72,177] = (-1)*var(15); // [ var(177) , var(72) ]
+                D[78,177] = var(22); // [ var(177) , var(78) ]
+                D[82,177] = (-1)*var(28); // [ var(177) , var(82) ]
+                D[85,177] = var(34); // [ var(177) , var(85) ]
+                D[87,177] = (-1)*var(36); // [ var(177) , var(87) ]
+                D[90,177] = var(42); // [ var(177) , var(90) ]
+                D[93,177] = var(49); // [ var(177) , var(93) ]
+                D[97,177] = (-1)*var(53); // [ var(177) , var(97) ]
+                D[98,177] = var(56); // [ var(177) , var(98) ]
+                D[101,177] = (-1)*var(60); // [ var(177) , var(101) ]
+                D[108,177] = var(74); // [ var(177) , var(108) ]
+                D[109,177] = (-1)*var(79); // [ var(177) , var(109) ]
+                D[114,177] = (-1)*var(88); // [ var(177) , var(114) ]
+                D[115,177] = var(91); // [ var(177) , var(115) ]
+                D[117,177] = (-1)*var(99); // [ var(177) , var(117) ]
+                D[118,177] = var(103); // [ var(177) , var(118) ]
+                D[3,178] = (-1)*var(173); // [ var(178) , var(3) ]
+                D[7,178] = var(171); // [ var(178) , var(7) ]
+                D[9,178] = var(169); // [ var(178) , var(9) ]
+                D[11,178] = var(166); // [ var(178) , var(11) ]
+                D[14,178] = var(164); // [ var(178) , var(14) ]
+                D[16,178] = (-1)*var(161); // [ var(178) , var(16) ]
+                D[17,178] = (-1)*var(159); // [ var(178) , var(17) ]
+                D[23,178] = var(155); // [ var(178) , var(23) ]
+                D[35,178] = (-1)*var(143); // [ var(178) , var(35) ]
+                D[39,178] = var(137); // [ var(178) , var(39) ]
+                D[41,178] = var(136); // [ var(178) , var(41) ]
+                D[44,178] = (-1)*var(134); // [ var(178) , var(44) ]
+                D[46,178] = (-1)*var(131); // [ var(178) , var(46) ]
+                D[49,178] = (-1)*var(129); // [ var(178) , var(49) ]
+                D[51,178] = (-1)*var(127); // [ var(178) , var(51) ]
+                D[53,178] = var(123); // [ var(178) , var(53) ]
+                D[58,178] = (-1)*var(241)+(-1)*var(242)+(-2)*var(243)+(-2)*var(244)+(-1)*var(245)+(-1)*var(246)+(-1)*var(247); // [ var(178) , var(58) ]
+                D[64,178] = (-1)*var(5); // [ var(178) , var(64) ]
+                D[65,178] = (-1)*var(8); // [ var(178) , var(65) ]
+                D[70,178] = var(12); // [ var(178) , var(70) ]
+                D[71,178] = (-1)*var(13); // [ var(178) , var(71) ]
+                D[75,178] = (-1)*var(18); // [ var(178) , var(75) ]
+                D[76,178] = var(20); // [ var(178) , var(76) ]
+                D[80,178] = (-1)*var(26); // [ var(178) , var(80) ]
+                D[84,178] = var(29); // [ var(178) , var(84) ]
+                D[88,178] = (-1)*var(36); // [ var(178) , var(88) ]
+                D[91,178] = var(42); // [ var(178) , var(91) ]
+                D[93,178] = var(48); // [ var(178) , var(93) ]
+                D[97,178] = (-1)*var(52); // [ var(178) , var(97) ]
+                D[102,178] = (-1)*var(62); // [ var(178) , var(102) ]
+                D[104,178] = var(67); // [ var(178) , var(104) ]
+                D[105,178] = (-1)*var(68); // [ var(178) , var(105) ]
+                D[107,178] = var(73); // [ var(178) , var(107) ]
+                D[114,178] = (-1)*var(87); // [ var(178) , var(114) ]
+                D[115,178] = var(90); // [ var(178) , var(115) ]
+                D[116,178] = (-1)*var(94); // [ var(178) , var(116) ]
+                D[119,178] = var(106); // [ var(178) , var(119) ]
+                D[1,179] = (-1)*var(175); // [ var(179) , var(1) ]
+                D[5,179] = var(173); // [ var(179) , var(5) ]
+                D[7,179] = var(172); // [ var(179) , var(7) ]
+                D[12,179] = var(166); // [ var(179) , var(12) ]
+                D[18,179] = (-1)*var(159); // [ var(179) , var(18) ]
+                D[21,179] = (-1)*var(157); // [ var(179) , var(21) ]
+                D[24,179] = (-1)*var(154); // [ var(179) , var(24) ]
+                D[28,179] = (-1)*var(150); // [ var(179) , var(28) ]
+                D[30,179] = var(148); // [ var(179) , var(30) ]
+                D[34,179] = var(144); // [ var(179) , var(34) ]
+                D[37,179] = var(141); // [ var(179) , var(37) ]
+                D[39,179] = var(138); // [ var(179) , var(39) ]
+                D[46,179] = (-1)*var(132); // [ var(179) , var(46) ]
+                D[52,179] = (-1)*var(127); // [ var(179) , var(52) ]
+                D[53,179] = (-1)*var(125); // [ var(179) , var(53) ]
+                D[55,179] = var(121); // [ var(179) , var(55) ]
+                D[59,179] = (-1)*var(241)+(-1)*var(242)+(-1)*var(243)+(-2)*var(244)+(-2)*var(245)+(-1)*var(246)+(-1)*var(247); // [ var(179) , var(59) ]
+                D[64,179] = var(3); // [ var(179) , var(64) ]
+                D[66,179] = (-1)*var(6); // [ var(179) , var(66) ]
+                D[67,179] = (-1)*var(8); // [ var(179) , var(67) ]
+                D[70,179] = var(11); // [ var(179) , var(70) ]
+                D[75,179] = (-1)*var(17); // [ var(179) , var(75) ]
+                D[79,179] = var(22); // [ var(179) , var(79) ]
+                D[82,179] = (-1)*var(27); // [ var(179) , var(82) ]
+                D[85,179] = var(33); // [ var(179) , var(85) ]
+                D[89,179] = var(40); // [ var(179) , var(89) ]
+                D[92,179] = var(43); // [ var(179) , var(92) ]
+                D[95,179] = (-1)*var(50); // [ var(179) , var(95) ]
+                D[97,179] = (-1)*var(51); // [ var(179) , var(97) ]
+                D[99,179] = (-1)*var(56); // [ var(179) , var(99) ]
+                D[104,179] = var(65); // [ var(179) , var(104) ]
+                D[106,179] = var(68); // [ var(179) , var(106) ]
+                D[109,179] = (-1)*var(78); // [ var(179) , var(109) ]
+                D[111,179] = (-1)*var(83); // [ var(179) , var(111) ]
+                D[113,179] = var(86); // [ var(179) , var(113) ]
+                D[117,179] = var(98); // [ var(179) , var(117) ]
+                D[119,179] = (-1)*var(105); // [ var(179) , var(119) ]
+                D[1,180] = (-1)*var(176); // [ var(180) , var(1) ]
+                D[4,180] = var(174); // [ var(180) , var(4) ]
+                D[8,180] = var(173); // [ var(180) , var(8) ]
+                D[10,180] = (-1)*var(167); // [ var(180) , var(10) ]
+                D[15,180] = var(165); // [ var(180) , var(15) ]
+                D[16,180] = (-1)*var(162); // [ var(180) , var(16) ]
+                D[22,180] = var(157); // [ var(180) , var(22) ]
+                D[23,180] = var(156); // [ var(180) , var(23) ]
+                D[36,180] = (-1)*var(143); // [ var(180) , var(36) ]
+                D[37,180] = (-1)*var(142); // [ var(180) , var(37) ]
+                D[42,180] = var(136); // [ var(180) , var(42) ]
+                D[45,180] = (-1)*var(135); // [ var(180) , var(45) ]
+                D[47,180] = var(130); // [ var(180) , var(47) ]
+                D[53,180] = (-1)*var(128); // [ var(180) , var(53) ]
+                D[54,180] = (-1)*var(124); // [ var(180) , var(54) ]
+                D[56,180] = var(121); // [ var(180) , var(56) ]
+                D[60,180] = (-1)*var(241)+(-1)*var(242)+(-1)*var(243)+(-2)*var(244)+(-1)*var(245)+(-1)*var(246)+(-1)*var(247)+(-1)*var(248); // [ var(180) , var(60) ]
+                D[65,180] = var(3); // [ var(180) , var(65) ]
+                D[67,180] = (-1)*var(5); // [ var(180) , var(67) ]
+                D[73,180] = (-1)*var(13); // [ var(180) , var(73) ]
+                D[77,180] = (-1)*var(19); // [ var(180) , var(77) ]
+                D[79,180] = (-1)*var(21); // [ var(180) , var(79) ]
+                D[81,180] = var(25); // [ var(180) , var(81) ]
+                D[83,180] = (-1)*var(27); // [ var(180) , var(83) ]
+                D[86,180] = var(33); // [ var(180) , var(86) ]
+                D[88,180] = (-1)*var(35); // [ var(180) , var(88) ]
+                D[91,180] = var(41); // [ var(180) , var(91) ]
+                D[94,180] = (-1)*var(48); // [ var(180) , var(94) ]
+                D[99,180] = (-1)*var(55); // [ var(180) , var(99) ]
+                D[101,180] = var(57); // [ var(180) , var(101) ]
+                D[103,180] = (-1)*var(61); // [ var(180) , var(103) ]
+                D[104,180] = var(64); // [ var(180) , var(104) ]
+                D[107,180] = var(71); // [ var(180) , var(107) ]
+                D[111,180] = (-1)*var(82); // [ var(180) , var(111) ]
+                D[113,180] = var(85); // [ var(180) , var(113) ]
+                D[116,180] = var(93); // [ var(180) , var(116) ]
+                D[120,180] = (-1)*var(108); // [ var(180) , var(120) ]
+                D[6,181] = var(175); // [ var(181) , var(6) ]
+                D[13,181] = var(169); // [ var(181) , var(13) ]
+                D[14,181] = (-1)*var(168); // [ var(181) , var(14) ]
+                D[20,181] = var(161); // [ var(181) , var(20) ]
+                D[21,181] = (-1)*var(160); // [ var(181) , var(21) ]
+                D[26,181] = (-1)*var(155); // [ var(181) , var(26) ]
+                D[27,181] = (-1)*var(154); // [ var(181) , var(27) ]
+                D[28,181] = (-1)*var(153); // [ var(181) , var(28) ]
+                D[33,181] = var(148); // [ var(181) , var(33) ]
+                D[34,181] = var(147); // [ var(181) , var(34) ]
+                D[35,181] = var(146); // [ var(181) , var(35) ]
+                D[40,181] = var(141); // [ var(181) , var(40) ]
+                D[41,181] = (-1)*var(140); // [ var(181) , var(41) ]
+                D[48,181] = var(134); // [ var(181) , var(48) ]
+                D[49,181] = (-1)*var(133); // [ var(181) , var(49) ]
+                D[55,181] = (-1)*var(126); // [ var(181) , var(55) ]
+                D[61,181] = (-1)*var(242)+(-1)*var(243)+(-2)*var(244)+(-2)*var(245)+(-2)*var(246)+(-1)*var(247); // [ var(181) , var(61) ]
+                D[66,181] = var(1); // [ var(181) , var(66) ]
+                D[68,181] = (-1)*var(8); // [ var(181) , var(68) ]
+                D[71,181] = (-1)*var(9); // [ var(181) , var(71) ]
+                D[74,181] = var(15); // [ var(181) , var(74) ]
+                D[76,181] = (-1)*var(16); // [ var(181) , var(76) ]
+                D[80,181] = var(23); // [ var(181) , var(80) ]
+                D[82,181] = (-1)*var(24); // [ var(181) , var(82) ]
+                D[85,181] = var(30); // [ var(181) , var(85) ]
+                D[89,181] = var(37); // [ var(181) , var(89) ]
+                D[93,181] = (-1)*var(44); // [ var(181) , var(93) ]
+                D[96,181] = (-1)*var(47); // [ var(181) , var(96) ]
+                D[100,181] = var(54); // [ var(181) , var(100) ]
+                D[103,181] = var(60); // [ var(181) , var(103) ]
+                D[105,181] = (-1)*var(65); // [ var(181) , var(105) ]
+                D[106,181] = var(67); // [ var(181) , var(106) ]
+                D[108,181] = (-1)*var(72); // [ var(181) , var(108) ]
+                D[110,181] = (-1)*var(77); // [ var(181) , var(110) ]
+                D[112,181] = var(81); // [ var(181) , var(112) ]
+                D[118,181] = (-1)*var(101); // [ var(181) , var(118) ]
+                D[119,181] = var(104); // [ var(181) , var(119) ]
+                D[5,182] = var(176); // [ var(182) , var(5) ]
+                D[8,182] = var(175); // [ var(182) , var(8) ]
+                D[12,182] = var(170); // [ var(182) , var(12) ]
+                D[15,182] = var(168); // [ var(182) , var(15) ]
+                D[18,182] = (-1)*var(163); // [ var(182) , var(18) ]
+                D[19,182] = (-1)*var(162); // [ var(182) , var(19) ]
+                D[25,182] = var(156); // [ var(182) , var(25) ]
+                D[29,182] = (-1)*var(152); // [ var(182) , var(29) ]
+                D[32,182] = var(149); // [ var(182) , var(32) ]
+                D[36,182] = (-1)*var(145); // [ var(182) , var(36) ]
+                D[42,182] = var(139); // [ var(182) , var(42) ]
+                D[43,182] = var(138); // [ var(182) , var(43) ]
+                D[48,182] = (-1)*var(135); // [ var(182) , var(48) ]
+                D[50,182] = (-1)*var(132); // [ var(182) , var(50) ]
+                D[55,182] = (-1)*var(128); // [ var(182) , var(55) ]
+                D[56,182] = (-1)*var(125); // [ var(182) , var(56) ]
+                D[62,182] = (-1)*var(242)+(-1)*var(243)+(-2)*var(244)+(-2)*var(245)+(-1)*var(246)+(-1)*var(247)+(-1)*var(248); // [ var(182) , var(62) ]
+                D[67,182] = var(1); // [ var(182) , var(67) ]
+                D[68,182] = (-1)*var(6); // [ var(182) , var(68) ]
+                D[72,182] = (-1)*var(9); // [ var(182) , var(72) ]
+                D[74,182] = (-1)*var(14); // [ var(182) , var(74) ]
+                D[77,182] = (-1)*var(16); // [ var(182) , var(77) ]
+                D[81,182] = var(23); // [ var(182) , var(81) ]
+                D[87,182] = var(31); // [ var(182) , var(87) ]
+                D[90,182] = (-1)*var(38); // [ var(182) , var(90) ]
+                D[92,182] = var(39); // [ var(182) , var(92) ]
+                D[94,182] = (-1)*var(45); // [ var(182) , var(94) ]
+                D[95,182] = (-1)*var(46); // [ var(182) , var(95) ]
+                D[98,182] = var(51); // [ var(182) , var(98) ]
+                D[99,182] = (-1)*var(53); // [ var(182) , var(99) ]
+                D[102,182] = var(58); // [ var(182) , var(102) ]
+                D[106,182] = var(66); // [ var(182) , var(106) ]
+                D[108,182] = (-1)*var(71); // [ var(182) , var(108) ]
+                D[110,182] = (-1)*var(76); // [ var(182) , var(110) ]
+                D[112,182] = var(80); // [ var(182) , var(112) ]
+                D[117,182] = (-1)*var(97); // [ var(182) , var(117) ]
+                D[120,182] = var(107); // [ var(182) , var(120) ]
+                D[4,183] = var(177); // [ var(183) , var(4) ]
+                D[11,183] = (-1)*var(172); // [ var(183) , var(11) ]
+                D[12,183] = (-1)*var(171); // [ var(183) , var(12) ]
+                D[16,183] = var(168); // [ var(183) , var(16) ]
+                D[19,183] = var(165); // [ var(183) , var(19) ]
+                D[20,183] = var(164); // [ var(183) , var(20) ]
+                D[24,183] = (-1)*var(160); // [ var(183) , var(24) ]
+                D[27,183] = (-1)*var(157); // [ var(183) , var(27) ]
+                D[31,183] = var(152); // [ var(183) , var(31) ]
+                D[32,183] = (-1)*var(151); // [ var(183) , var(32) ]
+                D[37,183] = var(147); // [ var(183) , var(37) ]
+                D[40,183] = var(144); // [ var(183) , var(40) ]
+                D[44,183] = (-1)*var(140); // [ var(183) , var(44) ]
+                D[45,183] = (-1)*var(139); // [ var(183) , var(45) ]
+                D[48,183] = (-1)*var(136); // [ var(183) , var(48) ]
+                D[51,183] = var(132); // [ var(183) , var(51) ]
+                D[52,183] = var(131); // [ var(183) , var(52) ]
+                D[57,183] = (-1)*var(124); // [ var(183) , var(57) ]
+                D[63,183] = (-1)*var(241)+(-1)*var(242)+(-2)*var(243)+(-3)*var(244)+(-2)*var(245)+(-1)*var(246); // [ var(183) , var(63) ]
+                D[69,183] = (-1)*var(2); // [ var(183) , var(69) ]
+                D[70,183] = (-1)*var(7); // [ var(183) , var(70) ]
+                D[76,183] = var(14); // [ var(183) , var(76) ]
+                D[77,183] = (-1)*var(15); // [ var(183) , var(77) ]
+                D[82,183] = (-1)*var(21); // [ var(183) , var(82) ]
+                D[83,183] = var(22); // [ var(183) , var(83) ]
+                D[87,183] = (-1)*var(29); // [ var(183) , var(87) ]
+                D[89,183] = var(34); // [ var(183) , var(89) ]
+                D[93,183] = (-1)*var(41); // [ var(183) , var(93) ]
+                D[94,183] = var(42); // [ var(183) , var(94) ]
+                D[97,183] = var(46); // [ var(183) , var(97) ]
+                D[98,183] = (-1)*var(50); // [ var(183) , var(98) ]
+                D[101,183] = var(54); // [ var(183) , var(101) ]
+                D[110,183] = var(74); // [ var(183) , var(110) ]
+                D[111,183] = (-1)*var(79); // [ var(183) , var(111) ]
+                D[114,183] = var(84); // [ var(183) , var(114) ]
+                D[116,183] = (-1)*var(91); // [ var(183) , var(116) ]
+                D[117,183] = var(95); // [ var(183) , var(117) ]
+                D[118,183] = (-1)*var(100); // [ var(183) , var(118) ]
+                D[3,184] = (-1)*var(179); // [ var(184) , var(3) ]
+                D[5,184] = var(178); // [ var(184) , var(5) ]
+                D[7,184] = var(177); // [ var(184) , var(7) ]
+                D[9,184] = var(175); // [ var(184) , var(9) ]
+                D[19,184] = var(166); // [ var(184) , var(19) ]
+                D[21,184] = (-1)*var(164); // [ var(184) , var(21) ]
+                D[24,184] = (-1)*var(161); // [ var(184) , var(24) ]
+                D[25,184] = (-1)*var(159); // [ var(184) , var(25) ]
+                D[30,184] = var(155); // [ var(184) , var(30) ]
+                D[35,184] = (-1)*var(150); // [ var(184) , var(35) ]
+                D[39,184] = var(145); // [ var(184) , var(39) ]
+                D[41,184] = var(144); // [ var(184) , var(41) ]
+                D[44,184] = var(141); // [ var(184) , var(44) ]
+                D[46,184] = (-1)*var(139); // [ var(184) , var(46) ]
+                D[55,184] = (-1)*var(129); // [ var(184) , var(55) ]
+                D[57,184] = (-1)*var(127); // [ var(184) , var(57) ]
+                D[58,184] = (-1)*var(125); // [ var(184) , var(58) ]
+                D[59,184] = var(123); // [ var(184) , var(59) ]
+                D[64,184] = (-1)*var(241)+(-1)*var(242)+(-2)*var(243)+(-2)*var(244)+(-2)*var(245)+(-1)*var(246)+(-1)*var(247); // [ var(184) , var(64) ]
+                D[70,184] = (-1)*var(4); // [ var(184) , var(70) ]
+                D[71,184] = (-1)*var(6); // [ var(184) , var(71) ]
+                D[72,184] = (-1)*var(8); // [ var(184) , var(72) ]
+                D[75,184] = var(10); // [ var(184) , var(75) ]
+                D[82,184] = var(20); // [ var(184) , var(82) ]
+                D[84,184] = var(22); // [ var(184) , var(84) ]
+                D[85,184] = (-1)*var(26); // [ var(184) , var(85) ]
+                D[92,184] = (-1)*var(36); // [ var(184) , var(92) ]
+                D[93,184] = (-1)*var(40); // [ var(184) , var(93) ]
+                D[95,184] = var(42); // [ var(184) , var(95) ]
+                D[97,184] = var(45); // [ var(184) , var(97) ]
+                D[102,184] = var(56); // [ var(184) , var(102) ]
+                D[104,184] = (-1)*var(60); // [ var(184) , var(104) ]
+                D[108,184] = (-1)*var(68); // [ var(184) , var(108) ]
+                D[109,184] = var(73); // [ var(184) , var(109) ]
+                D[114,184] = var(83); // [ var(184) , var(114) ]
+                D[115,184] = (-1)*var(86); // [ var(184) , var(115) ]
+                D[117,184] = var(94); // [ var(184) , var(117) ]
+                D[119,184] = (-1)*var(103); // [ var(184) , var(119) ]
+                D[3,185] = (-1)*var(180); // [ var(185) , var(3) ]
+                D[8,185] = var(178); // [ var(185) , var(8) ]
+                D[9,185] = var(176); // [ var(185) , var(9) ]
+                D[11,185] = var(174); // [ var(185) , var(11) ]
+                D[15,185] = var(171); // [ var(185) , var(15) ]
+                D[16,185] = (-1)*var(170); // [ var(185) , var(16) ]
+                D[17,185] = (-1)*var(167); // [ var(185) , var(17) ]
+                D[22,185] = var(164); // [ var(185) , var(22) ]
+                D[23,185] = var(163); // [ var(185) , var(23) ]
+                D[43,185] = (-1)*var(143); // [ var(185) , var(43) ]
+                D[44,185] = (-1)*var(142); // [ var(185) , var(44) ]
+                D[47,185] = var(137); // [ var(185) , var(47) ]
+                D[50,185] = var(136); // [ var(185) , var(50) ]
+                D[51,185] = (-1)*var(135); // [ var(185) , var(51) ]
+                D[54,185] = (-1)*var(131); // [ var(185) , var(54) ]
+                D[56,185] = (-1)*var(129); // [ var(185) , var(56) ]
+                D[58,185] = (-1)*var(128); // [ var(185) , var(58) ]
+                D[60,185] = var(123); // [ var(185) , var(60) ]
+                D[65,185] = (-1)*var(241)+(-1)*var(242)+(-2)*var(243)+(-2)*var(244)+(-1)*var(245)+(-1)*var(246)+(-1)*var(247)+(-1)*var(248); // [ var(185) , var(65) ]
+                D[72,185] = (-1)*var(5); // [ var(185) , var(72) ]
+                D[77,185] = var(12); // [ var(185) , var(77) ]
+                D[78,185] = (-1)*var(13); // [ var(185) , var(78) ]
+                D[81,185] = (-1)*var(18); // [ var(185) , var(81) ]
+                D[83,185] = var(20); // [ var(185) , var(83) ]
+                D[84,185] = (-1)*var(21); // [ var(185) , var(84) ]
+                D[86,185] = (-1)*var(26); // [ var(185) , var(86) ]
+                D[88,185] = var(28); // [ var(185) , var(88) ]
+                D[91,185] = (-1)*var(34); // [ var(185) , var(91) ]
+                D[98,185] = var(48); // [ var(185) , var(98) ]
+                D[101,185] = (-1)*var(52); // [ var(185) , var(101) ]
+                D[102,185] = var(55); // [ var(185) , var(102) ]
+                D[104,185] = (-1)*var(59); // [ var(185) , var(104) ]
+                D[105,185] = var(61); // [ var(185) , var(105) ]
+                D[107,185] = (-1)*var(66); // [ var(185) , var(107) ]
+                D[114,185] = var(82); // [ var(185) , var(114) ]
+                D[115,185] = (-1)*var(85); // [ var(185) , var(115) ]
+                D[116,185] = var(89); // [ var(185) , var(116) ]
+                D[120,185] = (-1)*var(106); // [ var(185) , var(120) ]
+                D[1,186] = (-1)*var(181); // [ var(186) , var(1) ]
+                D[6,186] = var(179); // [ var(186) , var(6) ]
+                D[13,186] = var(173); // [ var(186) , var(13) ]
+                D[14,186] = (-1)*var(172); // [ var(186) , var(14) ]
+                D[20,186] = var(166); // [ var(186) , var(20) ]
+                D[21,186] = (-1)*var(165); // [ var(186) , var(21) ]
+                D[26,186] = (-1)*var(159); // [ var(186) , var(26) ]
+                D[28,186] = (-1)*var(158); // [ var(186) , var(28) ]
+                D[31,186] = (-1)*var(154); // [ var(186) , var(31) ]
+                D[34,186] = var(151); // [ var(186) , var(34) ]
+                D[38,186] = var(148); // [ var(186) , var(38) ]
+                D[39,186] = var(146); // [ var(186) , var(39) ]
+                D[45,186] = var(141); // [ var(186) , var(45) ]
+                D[46,186] = (-1)*var(140); // [ var(186) , var(46) ]
+                D[52,186] = var(134); // [ var(186) , var(52) ]
+                D[53,186] = (-1)*var(133); // [ var(186) , var(53) ]
+                D[59,186] = (-1)*var(126); // [ var(186) , var(59) ]
+                D[61,186] = var(121); // [ var(186) , var(61) ]
+                D[66,186] = (-1)*var(241)+(-1)*var(242)+(-1)*var(243)+(-2)*var(244)+(-2)*var(245)+(-2)*var(246)+(-1)*var(247); // [ var(186) , var(66) ]
+                D[71,186] = var(3); // [ var(186) , var(71) ]
+                D[73,186] = (-1)*var(8); // [ var(186) , var(73) ]
+                D[76,186] = var(11); // [ var(186) , var(76) ]
+                D[79,186] = var(15); // [ var(186) , var(79) ]
+                D[80,186] = (-1)*var(17); // [ var(186) , var(80) ]
+                D[82,186] = var(19); // [ var(186) , var(82) ]
+                D[85,186] = (-1)*var(25); // [ var(186) , var(85) ]
+                D[89,186] = (-1)*var(32); // [ var(186) , var(89) ]
+                D[96,186] = var(43); // [ var(186) , var(96) ]
+                D[97,186] = var(44); // [ var(186) , var(97) ]
+                D[100,186] = (-1)*var(50); // [ var(186) , var(100) ]
+                D[103,186] = (-1)*var(56); // [ var(186) , var(103) ]
+                D[106,186] = (-1)*var(62); // [ var(186) , var(106) ]
+                D[107,186] = var(65); // [ var(186) , var(107) ]
+                D[109,186] = var(72); // [ var(186) , var(109) ]
+                D[111,186] = var(77); // [ var(186) , var(111) ]
+                D[113,186] = (-1)*var(81); // [ var(186) , var(113) ]
+                D[118,186] = (-1)*var(98); // [ var(186) , var(118) ]
+                D[119,186] = var(102); // [ var(186) , var(119) ]
+                D[1,187] = (-1)*var(182); // [ var(187) , var(1) ]
+                D[5,187] = var(180); // [ var(187) , var(5) ]
+                D[8,187] = var(179); // [ var(187) , var(8) ]
+                D[12,187] = var(174); // [ var(187) , var(12) ]
+                D[15,187] = var(172); // [ var(187) , var(15) ]
+                D[18,187] = (-1)*var(167); // [ var(187) , var(18) ]
+                D[24,187] = (-1)*var(162); // [ var(187) , var(24) ]
+                D[29,187] = (-1)*var(157); // [ var(187) , var(29) ]
+                D[30,187] = var(156); // [ var(187) , var(30) ]
+                D[36,187] = (-1)*var(150); // [ var(187) , var(36) ]
+                D[37,187] = var(149); // [ var(187) , var(37) ]
+                D[42,187] = var(144); // [ var(187) , var(42) ]
+                D[47,187] = var(138); // [ var(187) , var(47) ]
+                D[52,187] = (-1)*var(135); // [ var(187) , var(52) ]
+                D[54,187] = (-1)*var(132); // [ var(187) , var(54) ]
+                D[59,187] = (-1)*var(128); // [ var(187) , var(59) ]
+                D[60,187] = (-1)*var(125); // [ var(187) , var(60) ]
+                D[62,187] = var(121); // [ var(187) , var(62) ]
+                D[67,187] = (-1)*var(241)+(-1)*var(242)+(-1)*var(243)+(-2)*var(244)+(-2)*var(245)+(-1)*var(246)+(-1)*var(247)+(-1)*var(248); // [ var(187) , var(67) ]
+                D[72,187] = var(3); // [ var(187) , var(72) ]
+                D[73,187] = (-1)*var(6); // [ var(187) , var(73) ]
+                D[77,187] = var(11); // [ var(187) , var(77) ]
+                D[79,187] = (-1)*var(14); // [ var(187) , var(79) ]
+                D[81,187] = (-1)*var(17); // [ var(187) , var(81) ]
+                D[87,187] = (-1)*var(27); // [ var(187) , var(87) ]
+                D[90,187] = var(33); // [ var(187) , var(90) ]
+                D[92,187] = (-1)*var(35); // [ var(187) , var(92) ]
+                D[94,187] = var(40); // [ var(187) , var(94) ]
+                D[95,187] = var(41); // [ var(187) , var(95) ]
+                D[99,187] = var(49); // [ var(187) , var(99) ]
+                D[101,187] = (-1)*var(51); // [ var(187) , var(101) ]
+                D[104,187] = (-1)*var(58); // [ var(187) , var(104) ]
+                D[106,187] = (-1)*var(61); // [ var(187) , var(106) ]
+                D[109,187] = var(71); // [ var(187) , var(109) ]
+                D[111,187] = var(76); // [ var(187) , var(111) ]
+                D[113,187] = (-1)*var(80); // [ var(187) , var(113) ]
+                D[117,187] = (-1)*var(93); // [ var(187) , var(117) ]
+                D[120,187] = var(105); // [ var(187) , var(120) ]
+                D[6,188] = var(182); // [ var(188) , var(6) ]
+                D[8,188] = var(181); // [ var(188) , var(8) ]
+                D[13,188] = var(176); // [ var(188) , var(13) ]
+                D[20,188] = var(170); // [ var(188) , var(20) ]
+                D[22,188] = (-1)*var(168); // [ var(188) , var(22) ]
+                D[26,188] = (-1)*var(163); // [ var(188) , var(26) ]
+                D[27,188] = (-1)*var(162); // [ var(188) , var(27) ]
+                D[29,188] = (-1)*var(160); // [ var(188) , var(29) ]
+                D[33,188] = var(156); // [ var(188) , var(33) ]
+                D[36,188] = (-1)*var(153); // [ var(188) , var(36) ]
+                D[40,188] = var(149); // [ var(188) , var(40) ]
+                D[42,188] = var(147); // [ var(188) , var(42) ]
+                D[43,188] = var(146); // [ var(188) , var(43) ]
+                D[48,188] = var(142); // [ var(188) , var(48) ]
+                D[50,188] = (-1)*var(140); // [ var(188) , var(50) ]
+                D[56,188] = (-1)*var(133); // [ var(188) , var(56) ]
+                D[61,188] = (-1)*var(128); // [ var(188) , var(61) ]
+                D[62,188] = (-1)*var(126); // [ var(188) , var(62) ]
+                D[68,188] = (-1)*var(242)+(-1)*var(243)+(-2)*var(244)+(-2)*var(245)+(-2)*var(246)+(-1)*var(247)+(-1)*var(248); // [ var(188) , var(68) ]
+                D[73,188] = var(1); // [ var(188) , var(73) ]
+                D[74,188] = (-1)*var(7); // [ var(188) , var(74) ]
+                D[78,188] = (-1)*var(9); // [ var(188) , var(78) ]
+                D[83,188] = (-1)*var(16); // [ var(188) , var(83) ]
+                D[86,188] = var(23); // [ var(188) , var(86) ]
+                D[87,188] = (-1)*var(24); // [ var(188) , var(87) ]
+                D[90,188] = var(30); // [ var(188) , var(90) ]
+                D[94,188] = var(37); // [ var(188) , var(94) ]
+                D[96,188] = var(39); // [ var(188) , var(96) ]
+                D[98,188] = (-1)*var(44); // [ var(188) , var(98) ]
+                D[100,188] = (-1)*var(46); // [ var(188) , var(100) ]
+                D[103,188] = (-1)*var(53); // [ var(188) , var(103) ]
+                D[105,188] = var(58); // [ var(188) , var(105) ]
+                D[106,188] = (-1)*var(59); // [ var(188) , var(106) ]
+                D[108,188] = var(64); // [ var(188) , var(108) ]
+                D[110,188] = var(70); // [ var(188) , var(110) ]
+                D[112,188] = (-1)*var(75); // [ var(188) , var(112) ]
+                D[118,188] = var(97); // [ var(188) , var(118) ]
+                D[120,188] = (-1)*var(104); // [ var(188) , var(120) ]
+                D[2,189] = var(183); // [ var(189) , var(2) ]
+                D[10,189] = (-1)*var(177); // [ var(189) , var(10) ]
+                D[17,189] = var(172); // [ var(189) , var(17) ]
+                D[18,189] = var(171); // [ var(189) , var(18) ]
+                D[23,189] = (-1)*var(168); // [ var(189) , var(23) ]
+                D[25,189] = (-1)*var(165); // [ var(189) , var(25) ]
+                D[26,189] = (-1)*var(164); // [ var(189) , var(26) ]
+                D[30,189] = var(160); // [ var(189) , var(30) ]
+                D[32,189] = var(158); // [ var(189) , var(32) ]
+                D[33,189] = var(157); // [ var(189) , var(33) ]
+                D[37,189] = (-1)*var(153); // [ var(189) , var(37) ]
+                D[38,189] = (-1)*var(152); // [ var(189) , var(38) ]
+                D[40,189] = (-1)*var(150); // [ var(189) , var(40) ]
+                D[44,189] = var(146); // [ var(189) , var(44) ]
+                D[45,189] = var(145); // [ var(189) , var(45) ]
+                D[48,189] = var(143); // [ var(189) , var(48) ]
+                D[51,189] = (-1)*var(138); // [ var(189) , var(51) ]
+                D[52,189] = (-1)*var(137); // [ var(189) , var(52) ]
+                D[57,189] = var(130); // [ var(189) , var(57) ]
+                D[63,189] = (-1)*var(122); // [ var(189) , var(63) ]
+                D[69,189] = (-1)*var(241)+(-2)*var(242)+(-2)*var(243)+(-3)*var(244)+(-2)*var(245)+(-1)*var(246); // [ var(189) , var(69) ]
+                D[75,189] = (-1)*var(7); // [ var(189) , var(75) ]
+                D[80,189] = var(14); // [ var(189) , var(80) ]
+                D[81,189] = (-1)*var(15); // [ var(189) , var(81) ]
+                D[85,189] = (-1)*var(21); // [ var(189) , var(85) ]
+                D[86,189] = var(22); // [ var(189) , var(86) ]
+                D[89,189] = var(28); // [ var(189) , var(89) ]
+                D[90,189] = (-1)*var(29); // [ var(189) , var(90) ]
+                D[93,189] = (-1)*var(35); // [ var(189) , var(93) ]
+                D[94,189] = var(36); // [ var(189) , var(94) ]
+                D[97,189] = var(39); // [ var(189) , var(97) ]
+                D[98,189] = (-1)*var(43); // [ var(189) , var(98) ]
+                D[101,189] = var(47); // [ var(189) , var(101) ]
+                D[112,189] = (-1)*var(74); // [ var(189) , var(112) ]
+                D[113,189] = var(79); // [ var(189) , var(113) ]
+                D[115,189] = (-1)*var(84); // [ var(189) , var(115) ]
+                D[116,189] = var(88); // [ var(189) , var(116) ]
+                D[117,189] = (-1)*var(92); // [ var(189) , var(117) ]
+                D[118,189] = var(96); // [ var(189) , var(118) ]
+                D[4,190] = var(184); // [ var(190) , var(4) ]
+                D[7,190] = var(183); // [ var(190) , var(7) ]
+                D[11,190] = (-1)*var(179); // [ var(190) , var(11) ]
+                D[12,190] = (-1)*var(178); // [ var(190) , var(12) ]
+                D[16,190] = var(175); // [ var(190) , var(16) ]
+                D[19,190] = var(173); // [ var(190) , var(19) ]
+                D[24,190] = (-1)*var(169); // [ var(190) , var(24) ]
+                D[28,190] = var(164); // [ var(190) , var(28) ]
+                D[32,190] = (-1)*var(159); // [ var(190) , var(32) ]
+                D[35,190] = (-1)*var(157); // [ var(190) , var(35) ]
+                D[37,190] = var(155); // [ var(190) , var(37) ]
+                D[39,190] = var(152); // [ var(190) , var(39) ]
+                D[44,190] = (-1)*var(148); // [ var(190) , var(44) ]
+                D[49,190] = var(144); // [ var(190) , var(49) ]
+                D[53,190] = (-1)*var(139); // [ var(190) , var(53) ]
+                D[55,190] = (-1)*var(136); // [ var(190) , var(55) ]
+                D[58,190] = var(132); // [ var(190) , var(58) ]
+                D[59,190] = var(131); // [ var(190) , var(59) ]
+                D[63,190] = (-1)*var(127); // [ var(190) , var(63) ]
+                D[64,190] = (-1)*var(124); // [ var(190) , var(64) ]
+                D[70,190] = (-1)*var(241)+(-1)*var(242)+(-2)*var(243)+(-3)*var(244)+(-2)*var(245)+(-1)*var(246)+(-1)*var(247); // [ var(190) , var(70) ]
+                D[75,190] = (-1)*var(2); // [ var(190) , var(75) ]
+                D[76,190] = (-1)*var(6); // [ var(190) , var(76) ]
+                D[77,190] = (-1)*var(8); // [ var(190) , var(77) ]
+                D[82,190] = var(13); // [ var(190) , var(82) ]
+                D[88,190] = var(22); // [ var(190) , var(88) ]
+                D[89,190] = (-1)*var(26); // [ var(190) , var(89) ]
+                D[92,190] = (-1)*var(29); // [ var(190) , var(92) ]
+                D[93,190] = var(33); // [ var(190) , var(93) ]
+                D[97,190] = (-1)*var(38); // [ var(190) , var(97) ]
+                D[99,190] = var(42); // [ var(190) , var(99) ]
+                D[102,190] = (-1)*var(50); // [ var(190) , var(102) ]
+                D[104,190] = var(54); // [ var(190) , var(104) ]
+                D[110,190] = (-1)*var(68); // [ var(190) , var(110) ]
+                D[111,190] = var(73); // [ var(190) , var(111) ]
+                D[114,190] = (-1)*var(78); // [ var(190) , var(114) ]
+                D[116,190] = var(86); // [ var(190) , var(116) ]
+                D[117,190] = (-1)*var(90); // [ var(190) , var(117) ]
+                D[119,190] = var(100); // [ var(190) , var(119) ]
+                D[3,191] = (-1)*var(186); // [ var(191) , var(3) ]
+                D[6,191] = var(184); // [ var(191) , var(6) ]
+                D[9,191] = var(181); // [ var(191) , var(9) ]
+                D[13,191] = var(178); // [ var(191) , var(13) ]
+                D[14,191] = (-1)*var(177); // [ var(191) , var(14) ]
+                D[21,191] = (-1)*var(171); // [ var(191) , var(21) ]
+                D[27,191] = var(166); // [ var(191) , var(27) ]
+                D[31,191] = (-1)*var(161); // [ var(191) , var(31) ]
+                D[33,191] = (-1)*var(159); // [ var(191) , var(33) ]
+                D[35,191] = (-1)*var(158); // [ var(191) , var(35) ]
+                D[38,191] = var(155); // [ var(191) , var(38) ]
+                D[39,191] = var(153); // [ var(191) , var(39) ]
+                D[41,191] = var(151); // [ var(191) , var(41) ]
+                D[46,191] = (-1)*var(147); // [ var(191) , var(46) ]
+                D[51,191] = var(141); // [ var(191) , var(51) ]
+                D[57,191] = var(134); // [ var(191) , var(57) ]
+                D[58,191] = (-1)*var(133); // [ var(191) , var(58) ]
+                D[61,191] = (-1)*var(129); // [ var(191) , var(61) ]
+                D[64,191] = (-1)*var(126); // [ var(191) , var(64) ]
+                D[66,191] = var(123); // [ var(191) , var(66) ]
+                D[71,191] = (-1)*var(241)+(-1)*var(242)+(-2)*var(243)+(-2)*var(244)+(-2)*var(245)+(-2)*var(246)+(-1)*var(247); // [ var(191) , var(71) ]
+                D[76,191] = (-1)*var(4); // [ var(191) , var(76) ]
+                D[78,191] = (-1)*var(8); // [ var(191) , var(78) ]
+                D[80,191] = var(10); // [ var(191) , var(80) ]
+                D[82,191] = (-1)*var(12); // [ var(191) , var(82) ]
+                D[84,191] = var(15); // [ var(191) , var(84) ]
+                D[85,191] = var(18); // [ var(191) , var(85) ]
+                D[93,191] = var(32); // [ var(191) , var(93) ]
+                D[96,191] = (-1)*var(36); // [ var(191) , var(96) ]
+                D[97,191] = (-1)*var(37); // [ var(191) , var(97) ]
+                D[100,191] = var(42); // [ var(191) , var(100) ]
+                D[105,191] = var(56); // [ var(191) , var(105) ]
+                D[107,191] = (-1)*var(60); // [ var(191) , var(107) ]
+                D[108,191] = var(62); // [ var(191) , var(108) ]
+                D[109,191] = (-1)*var(67); // [ var(191) , var(109) ]
+                D[114,191] = (-1)*var(77); // [ var(191) , var(114) ]
+                D[115,191] = var(81); // [ var(191) , var(115) ]
+                D[118,191] = (-1)*var(94); // [ var(191) , var(118) ]
+                D[119,191] = var(99); // [ var(191) , var(119) ]
+                D[3,192] = (-1)*var(187); // [ var(192) , var(3) ]
+                D[5,192] = var(185); // [ var(192) , var(5) ]
+                D[8,192] = var(184); // [ var(192) , var(8) ]
+                D[9,192] = var(182); // [ var(192) , var(9) ]
+                D[15,192] = var(177); // [ var(192) , var(15) ]
+                D[19,192] = var(174); // [ var(192) , var(19) ]
+                D[24,192] = (-1)*var(170); // [ var(192) , var(24) ]
+                D[25,192] = (-1)*var(167); // [ var(192) , var(25) ]
+                D[29,192] = (-1)*var(164); // [ var(192) , var(29) ]
+                D[30,192] = var(163); // [ var(192) , var(30) ]
+                D[43,192] = (-1)*var(150); // [ var(192) , var(43) ]
+                D[44,192] = var(149); // [ var(192) , var(44) ]
+                D[47,192] = var(145); // [ var(192) , var(47) ]
+                D[50,192] = var(144); // [ var(192) , var(50) ]
+                D[54,192] = (-1)*var(139); // [ var(192) , var(54) ]
+                D[57,192] = (-1)*var(135); // [ var(192) , var(57) ]
+                D[62,192] = (-1)*var(129); // [ var(192) , var(62) ]
+                D[64,192] = (-1)*var(128); // [ var(192) , var(64) ]
+                D[65,192] = (-1)*var(125); // [ var(192) , var(65) ]
+                D[67,192] = var(123); // [ var(192) , var(67) ]
+                D[72,192] = (-1)*var(241)+(-1)*var(242)+(-2)*var(243)+(-2)*var(244)+(-2)*var(245)+(-1)*var(246)+(-1)*var(247)+(-1)*var(248); // [ var(192) , var(72) ]
+                D[77,192] = (-1)*var(4); // [ var(192) , var(77) ]
+                D[78,192] = (-1)*var(6); // [ var(192) , var(78) ]
+                D[81,192] = var(10); // [ var(192) , var(81) ]
+                D[84,192] = (-1)*var(14); // [ var(192) , var(84) ]
+                D[87,192] = var(20); // [ var(192) , var(87) ]
+                D[90,192] = (-1)*var(26); // [ var(192) , var(90) ]
+                D[92,192] = var(28); // [ var(192) , var(92) ]
+                D[95,192] = (-1)*var(34); // [ var(192) , var(95) ]
+                D[98,192] = (-1)*var(40); // [ var(192) , var(98) ]
+                D[101,192] = var(45); // [ var(192) , var(101) ]
+                D[102,192] = (-1)*var(49); // [ var(192) , var(102) ]
+                D[104,192] = var(53); // [ var(192) , var(104) ]
+                D[108,192] = var(61); // [ var(192) , var(108) ]
+                D[109,192] = (-1)*var(66); // [ var(192) , var(109) ]
+                D[114,192] = (-1)*var(76); // [ var(192) , var(114) ]
+                D[115,192] = var(80); // [ var(192) , var(115) ]
+                D[117,192] = (-1)*var(89); // [ var(192) , var(117) ]
+                D[120,192] = var(103); // [ var(192) , var(120) ]
+                D[1,193] = (-1)*var(188); // [ var(193) , var(1) ]
+                D[6,193] = var(187); // [ var(193) , var(6) ]
+                D[8,193] = var(186); // [ var(193) , var(8) ]
+                D[13,193] = var(180); // [ var(193) , var(13) ]
+                D[20,193] = var(174); // [ var(193) , var(20) ]
+                D[22,193] = (-1)*var(172); // [ var(193) , var(22) ]
+                D[26,193] = (-1)*var(167); // [ var(193) , var(26) ]
+                D[29,193] = (-1)*var(165); // [ var(193) , var(29) ]
+                D[31,193] = (-1)*var(162); // [ var(193) , var(31) ]
+                D[36,193] = (-1)*var(158); // [ var(193) , var(36) ]
+                D[38,193] = var(156); // [ var(193) , var(38) ]
+                D[42,193] = var(151); // [ var(193) , var(42) ]
+                D[45,193] = var(149); // [ var(193) , var(45) ]
+                D[47,193] = var(146); // [ var(193) , var(47) ]
+                D[52,193] = var(142); // [ var(193) , var(52) ]
+                D[54,193] = (-1)*var(140); // [ var(193) , var(54) ]
+                D[60,193] = (-1)*var(133); // [ var(193) , var(60) ]
+                D[66,193] = (-1)*var(128); // [ var(193) , var(66) ]
+                D[67,193] = (-1)*var(126); // [ var(193) , var(67) ]
+                D[68,193] = var(121); // [ var(193) , var(68) ]
+                D[73,193] = (-1)*var(241)+(-1)*var(242)+(-1)*var(243)+(-2)*var(244)+(-2)*var(245)+(-2)*var(246)+(-1)*var(247)+(-1)*var(248); // [ var(193) , var(73) ]
+                D[78,193] = var(3); // [ var(193) , var(78) ]
+                D[79,193] = (-1)*var(7); // [ var(193) , var(79) ]
+                D[83,193] = var(11); // [ var(193) , var(83) ]
+                D[86,193] = (-1)*var(17); // [ var(193) , var(86) ]
+                D[87,193] = var(19); // [ var(193) , var(87) ]
+                D[90,193] = (-1)*var(25); // [ var(193) , var(90) ]
+                D[94,193] = (-1)*var(32); // [ var(193) , var(94) ]
+                D[96,193] = (-1)*var(35); // [ var(193) , var(96) ]
+                D[100,193] = var(41); // [ var(193) , var(100) ]
+                D[101,193] = var(44); // [ var(193) , var(101) ]
+                D[103,193] = var(49); // [ var(193) , var(103) ]
+                D[106,193] = var(55); // [ var(193) , var(106) ]
+                D[107,193] = (-1)*var(58); // [ var(193) , var(107) ]
+                D[109,193] = (-1)*var(64); // [ var(193) , var(109) ]
+                D[111,193] = (-1)*var(70); // [ var(193) , var(111) ]
+                D[113,193] = var(75); // [ var(193) , var(113) ]
+                D[118,193] = var(93); // [ var(193) , var(118) ]
+                D[120,193] = (-1)*var(102); // [ var(193) , var(120) ]
+                D[7,194] = var(188); // [ var(194) , var(7) ]
+                D[14,194] = var(182); // [ var(194) , var(14) ]
+                D[15,194] = (-1)*var(181); // [ var(194) , var(15) ]
+                D[21,194] = var(176); // [ var(194) , var(21) ]
+                D[22,194] = (-1)*var(175); // [ var(194) , var(22) ]
+                D[28,194] = var(170); // [ var(194) , var(28) ]
+                D[29,194] = (-1)*var(169); // [ var(194) , var(29) ]
+                D[34,194] = (-1)*var(163); // [ var(194) , var(34) ]
+                D[35,194] = (-1)*var(162); // [ var(194) , var(35) ]
+                D[36,194] = (-1)*var(161); // [ var(194) , var(36) ]
+                D[41,194] = var(156); // [ var(194) , var(41) ]
+                D[42,194] = var(155); // [ var(194) , var(42) ]
+                D[43,194] = var(154); // [ var(194) , var(43) ]
+                D[49,194] = var(149); // [ var(194) , var(49) ]
+                D[50,194] = (-1)*var(148); // [ var(194) , var(50) ]
+                D[55,194] = var(142); // [ var(194) , var(55) ]
+                D[56,194] = (-1)*var(141); // [ var(194) , var(56) ]
+                D[61,194] = var(135); // [ var(194) , var(61) ]
+                D[62,194] = (-1)*var(134); // [ var(194) , var(62) ]
+                D[68,194] = (-1)*var(127); // [ var(194) , var(68) ]
+                D[74,194] = (-1)*var(242)+(-1)*var(243)+(-2)*var(244)+(-2)*var(245)+(-2)*var(246)+(-2)*var(247)+(-1)*var(248); // [ var(194) , var(74) ]
+                D[79,194] = var(1); // [ var(194) , var(79) ]
+                D[84,194] = (-1)*var(9); // [ var(194) , var(84) ]
+                D[88,194] = (-1)*var(16); // [ var(194) , var(88) ]
+                D[91,194] = var(23); // [ var(194) , var(91) ]
+                D[92,194] = (-1)*var(24); // [ var(194) , var(92) ]
+                D[95,194] = var(30); // [ var(194) , var(95) ]
+                D[96,194] = (-1)*var(31); // [ var(194) , var(96) ]
+                D[99,194] = var(37); // [ var(194) , var(99) ]
+                D[100,194] = var(38); // [ var(194) , var(100) ]
+                D[102,194] = (-1)*var(44); // [ var(194) , var(102) ]
+                D[103,194] = var(45); // [ var(194) , var(103) ]
+                D[105,194] = (-1)*var(51); // [ var(194) , var(105) ]
+                D[106,194] = var(52); // [ var(194) , var(106) ]
+                D[108,194] = (-1)*var(57); // [ var(194) , var(108) ]
+                D[110,194] = (-1)*var(63); // [ var(194) , var(110) ]
+                D[112,194] = var(69); // [ var(194) , var(112) ]
+                D[119,194] = (-1)*var(97); // [ var(194) , var(119) ]
+                D[120,194] = var(101); // [ var(194) , var(120) ]
+                D[2,195] = var(190); // [ var(195) , var(2) ]
+                D[7,195] = var(189); // [ var(195) , var(7) ]
+                D[10,195] = (-1)*var(184); // [ var(195) , var(10) ]
+                D[17,195] = var(179); // [ var(195) , var(17) ]
+                D[18,195] = var(178); // [ var(195) , var(18) ]
+                D[23,195] = (-1)*var(175); // [ var(195) , var(23) ]
+                D[25,195] = (-1)*var(173); // [ var(195) , var(25) ]
+                D[30,195] = var(169); // [ var(195) , var(30) ]
+                D[32,195] = var(166); // [ var(195) , var(32) ]
+                D[34,195] = (-1)*var(164); // [ var(195) , var(34) ]
+                D[37,195] = (-1)*var(161); // [ var(195) , var(37) ]
+                D[41,195] = var(157); // [ var(195) , var(41) ]
+                D[44,195] = var(154); // [ var(195) , var(44) ]
+                D[46,195] = (-1)*var(152); // [ var(195) , var(46) ]
+                D[49,195] = (-1)*var(150); // [ var(195) , var(49) ]
+                D[53,195] = var(145); // [ var(195) , var(53) ]
+                D[55,195] = var(143); // [ var(195) , var(55) ]
+                D[58,195] = (-1)*var(138); // [ var(195) , var(58) ]
+                D[59,195] = (-1)*var(137); // [ var(195) , var(59) ]
+                D[64,195] = var(130); // [ var(195) , var(64) ]
+                D[69,195] = (-1)*var(127); // [ var(195) , var(69) ]
+                D[70,195] = (-1)*var(122); // [ var(195) , var(70) ]
+                D[75,195] = (-1)*var(241)+(-2)*var(242)+(-2)*var(243)+(-3)*var(244)+(-2)*var(245)+(-1)*var(246)+(-1)*var(247); // [ var(195) , var(75) ]
+                D[80,195] = (-1)*var(6); // [ var(195) , var(80) ]
+                D[81,195] = (-1)*var(8); // [ var(195) , var(81) ]
+                D[85,195] = var(13); // [ var(195) , var(85) ]
+                D[89,195] = (-1)*var(20); // [ var(195) , var(89) ]
+                D[91,195] = var(22); // [ var(195) , var(91) ]
+                D[93,195] = var(27); // [ var(195) , var(93) ]
+                D[95,195] = (-1)*var(29); // [ var(195) , var(95) ]
+                D[97,195] = (-1)*var(31); // [ var(195) , var(97) ]
+                D[99,195] = var(36); // [ var(195) , var(99) ]
+                D[102,195] = (-1)*var(43); // [ var(195) , var(102) ]
+                D[104,195] = var(47); // [ var(195) , var(104) ]
+                D[112,195] = var(68); // [ var(195) , var(112) ]
+                D[113,195] = (-1)*var(73); // [ var(195) , var(113) ]
+                D[115,195] = var(78); // [ var(195) , var(115) ]
+                D[116,195] = (-1)*var(83); // [ var(195) , var(116) ]
+                D[117,195] = var(87); // [ var(195) , var(117) ]
+                D[119,195] = (-1)*var(96); // [ var(195) , var(119) ]
+                D[4,196] = var(191); // [ var(196) , var(4) ]
+                D[6,196] = var(190); // [ var(196) , var(6) ]
+                D[11,196] = (-1)*var(186); // [ var(196) , var(11) ]
+                D[14,196] = (-1)*var(183); // [ var(196) , var(14) ]
+                D[16,196] = var(181); // [ var(196) , var(16) ]
+                D[20,196] = (-1)*var(178); // [ var(196) , var(20) ]
+                D[27,196] = var(173); // [ var(196) , var(27) ]
+                D[28,196] = var(171); // [ var(196) , var(28) ]
+                D[31,196] = (-1)*var(169); // [ var(196) , var(31) ]
+                D[35,196] = (-1)*var(165); // [ var(196) , var(35) ]
+                D[39,196] = var(160); // [ var(196) , var(39) ]
+                D[40,196] = (-1)*var(159); // [ var(196) , var(40) ]
+                D[45,196] = var(155); // [ var(196) , var(45) ]
+                D[49,196] = var(151); // [ var(196) , var(49) ]
+                D[51,196] = (-1)*var(148); // [ var(196) , var(51) ]
+                D[53,196] = (-1)*var(147); // [ var(196) , var(53) ]
+                D[58,196] = var(140); // [ var(196) , var(58) ]
+                D[61,196] = (-1)*var(136); // [ var(196) , var(61) ]
+                D[63,196] = var(134); // [ var(196) , var(63) ]
+                D[66,196] = var(131); // [ var(196) , var(66) ]
+                D[70,196] = (-1)*var(126); // [ var(196) , var(70) ]
+                D[71,196] = (-1)*var(124); // [ var(196) , var(71) ]
+                D[76,196] = (-1)*var(241)+(-1)*var(242)+(-2)*var(243)+(-3)*var(244)+(-2)*var(245)+(-2)*var(246)+(-1)*var(247); // [ var(196) , var(76) ]
+                D[80,196] = (-1)*var(2); // [ var(196) , var(80) ]
+                D[82,196] = (-1)*var(5); // [ var(196) , var(82) ]
+                D[83,196] = (-1)*var(8); // [ var(196) , var(83) ]
+                D[88,196] = var(15); // [ var(196) , var(88) ]
+                D[89,196] = var(18); // [ var(196) , var(89) ]
+                D[93,196] = (-1)*var(25); // [ var(196) , var(93) ]
+                D[96,196] = (-1)*var(29); // [ var(196) , var(96) ]
+                D[97,196] = var(30); // [ var(196) , var(97) ]
+                D[103,196] = var(42); // [ var(196) , var(103) ]
+                D[105,196] = (-1)*var(50); // [ var(196) , var(105) ]
+                D[107,196] = var(54); // [ var(196) , var(107) ]
+                D[110,196] = var(62); // [ var(196) , var(110) ]
+                D[111,196] = (-1)*var(67); // [ var(196) , var(111) ]
+                D[114,196] = var(72); // [ var(196) , var(114) ]
+                D[116,196] = (-1)*var(81); // [ var(196) , var(116) ]
+                D[118,196] = var(90); // [ var(196) , var(118) ]
+                D[119,196] = (-1)*var(95); // [ var(196) , var(119) ]
+                D[4,197] = var(192); // [ var(197) , var(4) ]
+                D[8,197] = var(190); // [ var(197) , var(8) ]
+                D[11,197] = (-1)*var(187); // [ var(197) , var(11) ]
+                D[12,197] = (-1)*var(185); // [ var(197) , var(12) ]
+                D[15,197] = var(183); // [ var(197) , var(15) ]
+                D[16,197] = var(182); // [ var(197) , var(16) ]
+                D[19,197] = var(180); // [ var(197) , var(19) ]
+                D[24,197] = (-1)*var(176); // [ var(197) , var(24) ]
+                D[32,197] = (-1)*var(167); // [ var(197) , var(32) ]
+                D[36,197] = var(164); // [ var(197) , var(36) ]
+                D[37,197] = var(163); // [ var(197) , var(37) ]
+                D[43,197] = (-1)*var(157); // [ var(197) , var(43) ]
+                D[44,197] = (-1)*var(156); // [ var(197) , var(44) ]
+                D[47,197] = var(152); // [ var(197) , var(47) ]
+                D[56,197] = var(144); // [ var(197) , var(56) ]
+                D[60,197] = (-1)*var(139); // [ var(197) , var(60) ]
+                D[62,197] = (-1)*var(136); // [ var(197) , var(62) ]
+                D[63,197] = (-1)*var(135); // [ var(197) , var(63) ]
+                D[65,197] = var(132); // [ var(197) , var(65) ]
+                D[67,197] = var(131); // [ var(197) , var(67) ]
+                D[70,197] = (-1)*var(128); // [ var(197) , var(70) ]
+                D[72,197] = (-1)*var(124); // [ var(197) , var(72) ]
+                D[77,197] = (-1)*var(241)+(-1)*var(242)+(-2)*var(243)+(-3)*var(244)+(-2)*var(245)+(-1)*var(246)+(-1)*var(247)+(-1)*var(248); // [ var(197) , var(77) ]
+                D[81,197] = (-1)*var(2); // [ var(197) , var(81) ]
+                D[83,197] = (-1)*var(6); // [ var(197) , var(83) ]
+                D[87,197] = var(13); // [ var(197) , var(87) ]
+                D[88,197] = (-1)*var(14); // [ var(197) , var(88) ]
+                D[92,197] = var(21); // [ var(197) , var(92) ]
+                D[94,197] = (-1)*var(26); // [ var(197) , var(94) ]
+                D[98,197] = var(33); // [ var(197) , var(98) ]
+                D[99,197] = (-1)*var(34); // [ var(197) , var(99) ]
+                D[101,197] = (-1)*var(38); // [ var(197) , var(101) ]
+                D[102,197] = var(41); // [ var(197) , var(102) ]
+                D[104,197] = (-1)*var(46); // [ var(197) , var(104) ]
+                D[110,197] = var(61); // [ var(197) , var(110) ]
+                D[111,197] = (-1)*var(66); // [ var(197) , var(111) ]
+                D[114,197] = var(71); // [ var(197) , var(114) ]
+                D[116,197] = (-1)*var(80); // [ var(197) , var(116) ]
+                D[117,197] = var(85); // [ var(197) , var(117) ]
+                D[120,197] = (-1)*var(100); // [ var(197) , var(120) ]
+                D[3,198] = (-1)*var(193); // [ var(198) , var(3) ]
+                D[6,198] = var(192); // [ var(198) , var(6) ]
+                D[8,198] = var(191); // [ var(198) , var(8) ]
+                D[9,198] = var(188); // [ var(198) , var(9) ]
+                D[13,198] = var(185); // [ var(198) , var(13) ]
+                D[22,198] = (-1)*var(177); // [ var(198) , var(22) ]
+                D[27,198] = var(174); // [ var(198) , var(27) ]
+                D[29,198] = (-1)*var(171); // [ var(198) , var(29) ]
+                D[31,198] = (-1)*var(170); // [ var(198) , var(31) ]
+                D[33,198] = (-1)*var(167); // [ var(198) , var(33) ]
+                D[38,198] = var(163); // [ var(198) , var(38) ]
+                D[43,198] = (-1)*var(158); // [ var(198) , var(43) ]
+                D[47,198] = var(153); // [ var(198) , var(47) ]
+                D[50,198] = var(151); // [ var(198) , var(50) ]
+                D[51,198] = var(149); // [ var(198) , var(51) ]
+                D[54,198] = (-1)*var(147); // [ var(198) , var(54) ]
+                D[57,198] = var(142); // [ var(198) , var(57) ]
+                D[65,198] = (-1)*var(133); // [ var(198) , var(65) ]
+                D[68,198] = (-1)*var(129); // [ var(198) , var(68) ]
+                D[71,198] = (-1)*var(128); // [ var(198) , var(71) ]
+                D[72,198] = (-1)*var(126); // [ var(198) , var(72) ]
+                D[73,198] = var(123); // [ var(198) , var(73) ]
+                D[78,198] = (-1)*var(241)+(-1)*var(242)+(-2)*var(243)+(-2)*var(244)+(-2)*var(245)+(-2)*var(246)+(-1)*var(247)+(-1)*var(248); // [ var(198) , var(78) ]
+                D[83,198] = (-1)*var(4); // [ var(198) , var(83) ]
+                D[84,198] = (-1)*var(7); // [ var(198) , var(84) ]
+                D[86,198] = var(10); // [ var(198) , var(86) ]
+                D[87,198] = (-1)*var(12); // [ var(198) , var(87) ]
+                D[90,198] = var(18); // [ var(198) , var(90) ]
+                D[96,198] = var(28); // [ var(198) , var(96) ]
+                D[98,198] = var(32); // [ var(198) , var(98) ]
+                D[100,198] = (-1)*var(34); // [ var(198) , var(100) ]
+                D[101,198] = (-1)*var(37); // [ var(198) , var(101) ]
+                D[105,198] = (-1)*var(49); // [ var(198) , var(105) ]
+                D[107,198] = var(53); // [ var(198) , var(107) ]
+                D[108,198] = (-1)*var(55); // [ var(198) , var(108) ]
+                D[109,198] = var(59); // [ var(198) , var(109) ]
+                D[114,198] = var(70); // [ var(198) , var(114) ]
+                D[115,198] = (-1)*var(75); // [ var(198) , var(115) ]
+                D[118,198] = var(89); // [ var(198) , var(118) ]
+                D[120,198] = (-1)*var(99); // [ var(198) , var(120) ]
+                D[1,199] = (-1)*var(194); // [ var(199) , var(1) ]
+                D[7,199] = var(193); // [ var(199) , var(7) ]
+                D[14,199] = var(187); // [ var(199) , var(14) ]
+                D[15,199] = (-1)*var(186); // [ var(199) , var(15) ]
+                D[21,199] = var(180); // [ var(199) , var(21) ]
+                D[22,199] = (-1)*var(179); // [ var(199) , var(22) ]
+                D[28,199] = var(174); // [ var(199) , var(28) ]
+                D[29,199] = (-1)*var(173); // [ var(199) , var(29) ]
+                D[34,199] = (-1)*var(167); // [ var(199) , var(34) ]
+                D[36,199] = (-1)*var(166); // [ var(199) , var(36) ]
+                D[39,199] = (-1)*var(162); // [ var(199) , var(39) ]
+                D[42,199] = var(159); // [ var(199) , var(42) ]
+                D[46,199] = var(156); // [ var(199) , var(46) ]
+                D[47,199] = var(154); // [ var(199) , var(47) ]
+                D[53,199] = var(149); // [ var(199) , var(53) ]
+                D[54,199] = (-1)*var(148); // [ var(199) , var(54) ]
+                D[59,199] = var(142); // [ var(199) , var(59) ]
+                D[60,199] = (-1)*var(141); // [ var(199) , var(60) ]
+                D[66,199] = var(135); // [ var(199) , var(66) ]
+                D[67,199] = (-1)*var(134); // [ var(199) , var(67) ]
+                D[73,199] = (-1)*var(127); // [ var(199) , var(73) ]
+                D[74,199] = var(121); // [ var(199) , var(74) ]
+                D[79,199] = (-1)*var(241)+(-1)*var(242)+(-1)*var(243)+(-2)*var(244)+(-2)*var(245)+(-2)*var(246)+(-2)*var(247)+(-1)*var(248); // [ var(199) , var(79) ]
+                D[84,199] = var(3); // [ var(199) , var(84) ]
+                D[88,199] = var(11); // [ var(199) , var(88) ]
+                D[91,199] = (-1)*var(17); // [ var(199) , var(91) ]
+                D[92,199] = var(19); // [ var(199) , var(92) ]
+                D[95,199] = (-1)*var(25); // [ var(199) , var(95) ]
+                D[96,199] = var(27); // [ var(199) , var(96) ]
+                D[99,199] = (-1)*var(32); // [ var(199) , var(99) ]
+                D[100,199] = (-1)*var(33); // [ var(199) , var(100) ]
+                D[103,199] = (-1)*var(40); // [ var(199) , var(103) ]
+                D[104,199] = var(44); // [ var(199) , var(104) ]
+                D[106,199] = (-1)*var(48); // [ var(199) , var(106) ]
+                D[107,199] = var(51); // [ var(199) , var(107) ]
+                D[109,199] = var(57); // [ var(199) , var(109) ]
+                D[111,199] = var(63); // [ var(199) , var(111) ]
+                D[113,199] = (-1)*var(69); // [ var(199) , var(113) ]
+                D[119,199] = (-1)*var(93); // [ var(199) , var(119) ]
+                D[120,199] = var(98); // [ var(199) , var(120) ]
+                D[2,200] = var(196); // [ var(200) , var(2) ]
+                D[6,200] = var(195); // [ var(200) , var(6) ]
+                D[10,200] = (-1)*var(191); // [ var(200) , var(10) ]
+                D[14,200] = (-1)*var(189); // [ var(200) , var(14) ]
+                D[17,200] = var(186); // [ var(200) , var(17) ]
+                D[23,200] = (-1)*var(181); // [ var(200) , var(23) ]
+                D[26,200] = var(178); // [ var(200) , var(26) ]
+                D[33,200] = (-1)*var(173); // [ var(200) , var(33) ]
+                D[34,200] = (-1)*var(171); // [ var(200) , var(34) ]
+                D[38,200] = var(169); // [ var(200) , var(38) ]
+                D[40,200] = var(166); // [ var(200) , var(40) ]
+                D[41,200] = var(165); // [ var(200) , var(41) ]
+                D[45,200] = (-1)*var(161); // [ var(200) , var(45) ]
+                D[46,200] = (-1)*var(160); // [ var(200) , var(46) ]
+                D[49,200] = (-1)*var(158); // [ var(200) , var(49) ]
+                D[51,200] = var(154); // [ var(200) , var(51) ]
+                D[53,200] = var(153); // [ var(200) , var(53) ]
+                D[58,200] = (-1)*var(146); // [ var(200) , var(58) ]
+                D[61,200] = var(143); // [ var(200) , var(61) ]
+                D[66,200] = (-1)*var(137); // [ var(200) , var(66) ]
+                D[69,200] = var(134); // [ var(200) , var(69) ]
+                D[71,200] = var(130); // [ var(200) , var(71) ]
+                D[75,200] = (-1)*var(126); // [ var(200) , var(75) ]
+                D[76,200] = (-1)*var(122); // [ var(200) , var(76) ]
+                D[80,200] = (-1)*var(241)+(-2)*var(242)+(-2)*var(243)+(-3)*var(244)+(-2)*var(245)+(-2)*var(246)+(-1)*var(247); // [ var(200) , var(80) ]
+                D[85,200] = (-1)*var(5); // [ var(200) , var(85) ]
+                D[86,200] = (-1)*var(8); // [ var(200) , var(86) ]
+                D[89,200] = var(12); // [ var(200) , var(89) ]
+                D[91,200] = var(15); // [ var(200) , var(91) ]
+                D[93,200] = (-1)*var(19); // [ var(200) , var(93) ]
+                D[97,200] = var(24); // [ var(200) , var(97) ]
+                D[100,200] = (-1)*var(29); // [ var(200) , var(100) ]
+                D[103,200] = var(36); // [ var(200) , var(103) ]
+                D[105,200] = (-1)*var(43); // [ var(200) , var(105) ]
+                D[107,200] = var(47); // [ var(200) , var(107) ]
+                D[112,200] = (-1)*var(62); // [ var(200) , var(112) ]
+                D[113,200] = var(67); // [ var(200) , var(113) ]
+                D[115,200] = (-1)*var(72); // [ var(200) , var(115) ]
+                D[116,200] = var(77); // [ var(200) , var(116) ]
+                D[118,200] = (-1)*var(87); // [ var(200) , var(118) ]
+                D[119,200] = var(92); // [ var(200) , var(119) ]
+                D[2,201] = var(197); // [ var(201) , var(2) ]
+                D[8,201] = var(195); // [ var(201) , var(8) ]
+                D[10,201] = (-1)*var(192); // [ var(201) , var(10) ]
+                D[15,201] = var(189); // [ var(201) , var(15) ]
+                D[17,201] = var(187); // [ var(201) , var(17) ]
+                D[18,201] = var(185); // [ var(201) , var(18) ]
+                D[23,201] = (-1)*var(182); // [ var(201) , var(23) ]
+                D[25,201] = (-1)*var(180); // [ var(201) , var(25) ]
+                D[30,201] = var(176); // [ var(201) , var(30) ]
+                D[32,201] = var(174); // [ var(201) , var(32) ]
+                D[37,201] = (-1)*var(170); // [ var(201) , var(37) ]
+                D[42,201] = (-1)*var(164); // [ var(201) , var(42) ]
+                D[44,201] = var(162); // [ var(201) , var(44) ]
+                D[50,201] = var(157); // [ var(201) , var(50) ]
+                D[54,201] = (-1)*var(152); // [ var(201) , var(54) ]
+                D[56,201] = (-1)*var(150); // [ var(201) , var(56) ]
+                D[60,201] = var(145); // [ var(201) , var(60) ]
+                D[62,201] = var(143); // [ var(201) , var(62) ]
+                D[65,201] = (-1)*var(138); // [ var(201) , var(65) ]
+                D[67,201] = (-1)*var(137); // [ var(201) , var(67) ]
+                D[69,201] = (-1)*var(135); // [ var(201) , var(69) ]
+                D[72,201] = var(130); // [ var(201) , var(72) ]
+                D[75,201] = (-1)*var(128); // [ var(201) , var(75) ]
+                D[77,201] = (-1)*var(122); // [ var(201) , var(77) ]
+                D[81,201] = (-1)*var(241)+(-2)*var(242)+(-2)*var(243)+(-3)*var(244)+(-2)*var(245)+(-1)*var(246)+(-1)*var(247)+(-1)*var(248); // [ var(201) , var(81) ]
+                D[86,201] = (-1)*var(6); // [ var(201) , var(86) ]
+                D[90,201] = var(13); // [ var(201) , var(90) ]
+                D[91,201] = (-1)*var(14); // [ var(201) , var(91) ]
+                D[94,201] = (-1)*var(20); // [ var(201) , var(94) ]
+                D[95,201] = var(21); // [ var(201) , var(95) ]
+                D[98,201] = var(27); // [ var(201) , var(98) ]
+                D[99,201] = (-1)*var(28); // [ var(201) , var(99) ]
+                D[101,201] = (-1)*var(31); // [ var(201) , var(101) ]
+                D[102,201] = var(35); // [ var(201) , var(102) ]
+                D[104,201] = (-1)*var(39); // [ var(201) , var(104) ]
+                D[112,201] = (-1)*var(61); // [ var(201) , var(112) ]
+                D[113,201] = var(66); // [ var(201) , var(113) ]
+                D[115,201] = (-1)*var(71); // [ var(201) , var(115) ]
+                D[116,201] = var(76); // [ var(201) , var(116) ]
+                D[117,201] = (-1)*var(82); // [ var(201) , var(117) ]
+                D[120,201] = var(96); // [ var(201) , var(120) ]
+                D[5,202] = var(196); // [ var(202) , var(5) ]
+                D[12,202] = var(191); // [ var(202) , var(12) ]
+                D[13,202] = (-1)*var(190); // [ var(202) , var(13) ]
+                D[19,202] = (-1)*var(186); // [ var(202) , var(19) ]
+                D[20,202] = (-1)*var(184); // [ var(202) , var(20) ]
+                D[21,202] = var(183); // [ var(202) , var(21) ]
+                D[24,202] = var(181); // [ var(202) , var(24) ]
+                D[27,202] = var(179); // [ var(202) , var(27) ]
+                D[28,202] = var(177); // [ var(202) , var(28) ]
+                D[31,202] = (-1)*var(175); // [ var(202) , var(31) ]
+                D[35,202] = (-1)*var(172); // [ var(202) , var(35) ]
+                D[39,202] = var(168); // [ var(202) , var(39) ]
+                D[48,202] = (-1)*var(159); // [ var(202) , var(48) ]
+                D[52,202] = var(155); // [ var(202) , var(52) ]
+                D[55,202] = var(151); // [ var(202) , var(55) ]
+                D[57,202] = (-1)*var(148); // [ var(202) , var(57) ]
+                D[59,202] = (-1)*var(147); // [ var(202) , var(59) ]
+                D[61,202] = (-1)*var(144); // [ var(202) , var(61) ]
+                D[63,202] = (-1)*var(141); // [ var(202) , var(63) ]
+                D[64,202] = var(140); // [ var(202) , var(64) ]
+                D[66,202] = var(139); // [ var(202) , var(66) ]
+                D[70,202] = var(133); // [ var(202) , var(70) ]
+                D[71,202] = (-1)*var(132); // [ var(202) , var(71) ]
+                D[76,202] = (-1)*var(125); // [ var(202) , var(76) ]
+                D[82,202] = (-1)*var(241)+(-1)*var(242)+(-2)*var(243)+(-3)*var(244)+(-3)*var(245)+(-2)*var(246)+(-1)*var(247); // [ var(202) , var(82) ]
+                D[85,202] = (-1)*var(2); // [ var(202) , var(85) ]
+                D[87,202] = (-1)*var(8); // [ var(202) , var(87) ]
+                D[89,202] = (-1)*var(10); // [ var(202) , var(89) ]
+                D[92,202] = var(15); // [ var(202) , var(92) ]
+                D[93,202] = var(17); // [ var(202) , var(93) ]
+                D[96,202] = (-1)*var(22); // [ var(202) , var(96) ]
+                D[97,202] = (-1)*var(23); // [ var(202) , var(97) ]
+                D[106,202] = var(42); // [ var(202) , var(106) ]
+                D[108,202] = (-1)*var(50); // [ var(202) , var(108) ]
+                D[109,202] = var(54); // [ var(202) , var(109) ]
+                D[110,202] = (-1)*var(56); // [ var(202) , var(110) ]
+                D[111,202] = var(60); // [ var(202) , var(111) ]
+                D[114,202] = (-1)*var(65); // [ var(202) , var(114) ]
+                D[117,202] = var(81); // [ var(202) , var(117) ]
+                D[118,202] = (-1)*var(86); // [ var(202) , var(118) ]
+                D[119,202] = var(91); // [ var(202) , var(119) ]
+                D[4,203] = var(198); // [ var(203) , var(4) ]
+                D[6,203] = var(197); // [ var(203) , var(6) ]
+                D[8,203] = var(196); // [ var(203) , var(8) ]
+                D[11,203] = (-1)*var(193); // [ var(203) , var(11) ]
+                D[16,203] = var(188); // [ var(203) , var(16) ]
+                D[20,203] = (-1)*var(185); // [ var(203) , var(20) ]
+                D[22,203] = (-1)*var(183); // [ var(203) , var(22) ]
+                D[27,203] = var(180); // [ var(203) , var(27) ]
+                D[31,203] = (-1)*var(176); // [ var(203) , var(31) ]
+                D[36,203] = var(171); // [ var(203) , var(36) ]
+                D[40,203] = (-1)*var(167); // [ var(203) , var(40) ]
+                D[43,203] = (-1)*var(165); // [ var(203) , var(43) ]
+                D[45,203] = var(163); // [ var(203) , var(45) ]
+                D[47,203] = var(160); // [ var(203) , var(47) ]
+                D[51,203] = (-1)*var(156); // [ var(203) , var(51) ]
+                D[56,203] = var(151); // [ var(203) , var(56) ]
+                D[60,203] = (-1)*var(147); // [ var(203) , var(60) ]
+                D[63,203] = var(142); // [ var(203) , var(63) ]
+                D[65,203] = var(140); // [ var(203) , var(65) ]
+                D[68,203] = (-1)*var(136); // [ var(203) , var(68) ]
+                D[73,203] = var(131); // [ var(203) , var(73) ]
+                D[76,203] = (-1)*var(128); // [ var(203) , var(76) ]
+                D[77,203] = (-1)*var(126); // [ var(203) , var(77) ]
+                D[78,203] = (-1)*var(124); // [ var(203) , var(78) ]
+                D[83,203] = (-1)*var(241)+(-1)*var(242)+(-2)*var(243)+(-3)*var(244)+(-2)*var(245)+(-2)*var(246)+(-1)*var(247)+(-1)*var(248); // [ var(203) , var(83) ]
+                D[86,203] = (-1)*var(2); // [ var(203) , var(86) ]
+                D[87,203] = (-1)*var(5); // [ var(203) , var(87) ]
+                D[88,203] = (-1)*var(7); // [ var(203) , var(88) ]
+                D[94,203] = var(18); // [ var(203) , var(94) ]
+                D[96,203] = var(21); // [ var(203) , var(96) ]
+                D[98,203] = (-1)*var(25); // [ var(203) , var(98) ]
+                D[101,203] = var(30); // [ var(203) , var(101) ]
+                D[103,203] = (-1)*var(34); // [ var(203) , var(103) ]
+                D[105,203] = var(41); // [ var(203) , var(105) ]
+                D[107,203] = (-1)*var(46); // [ var(203) , var(107) ]
+                D[110,203] = (-1)*var(55); // [ var(203) , var(110) ]
+                D[111,203] = var(59); // [ var(203) , var(111) ]
+                D[114,203] = (-1)*var(64); // [ var(203) , var(114) ]
+                D[116,203] = var(75); // [ var(203) , var(116) ]
+                D[118,203] = (-1)*var(85); // [ var(203) , var(118) ]
+                D[120,203] = var(95); // [ var(203) , var(120) ]
+                D[3,204] = (-1)*var(199); // [ var(204) , var(3) ]
+                D[7,204] = var(198); // [ var(204) , var(7) ]
+                D[9,204] = var(194); // [ var(204) , var(9) ]
+                D[14,204] = var(192); // [ var(204) , var(14) ]
+                D[15,204] = (-1)*var(191); // [ var(204) , var(15) ]
+                D[21,204] = var(185); // [ var(204) , var(21) ]
+                D[22,204] = (-1)*var(184); // [ var(204) , var(22) ]
+                D[29,204] = (-1)*var(178); // [ var(204) , var(29) ]
+                D[35,204] = var(174); // [ var(204) , var(35) ]
+                D[39,204] = (-1)*var(170); // [ var(204) , var(39) ]
+                D[41,204] = (-1)*var(167); // [ var(204) , var(41) ]
+                D[43,204] = (-1)*var(166); // [ var(204) , var(43) ]
+                D[46,204] = var(163); // [ var(204) , var(46) ]
+                D[47,204] = var(161); // [ var(204) , var(47) ]
+                D[50,204] = var(159); // [ var(204) , var(50) ]
+                D[54,204] = (-1)*var(155); // [ var(204) , var(54) ]
+                D[58,204] = var(149); // [ var(204) , var(58) ]
+                D[64,204] = var(142); // [ var(204) , var(64) ]
+                D[65,204] = (-1)*var(141); // [ var(204) , var(65) ]
+                D[71,204] = var(135); // [ var(204) , var(71) ]
+                D[72,204] = (-1)*var(134); // [ var(204) , var(72) ]
+                D[74,204] = (-1)*var(129); // [ var(204) , var(74) ]
+                D[78,204] = (-1)*var(127); // [ var(204) , var(78) ]
+                D[79,204] = var(123); // [ var(204) , var(79) ]
+                D[84,204] = (-1)*var(241)+(-1)*var(242)+(-2)*var(243)+(-2)*var(244)+(-2)*var(245)+(-2)*var(246)+(-2)*var(247)+(-1)*var(248); // [ var(204) , var(84) ]
+                D[88,204] = (-1)*var(4); // [ var(204) , var(88) ]
+                D[91,204] = var(10); // [ var(204) , var(91) ]
+                D[92,204] = (-1)*var(12); // [ var(204) , var(92) ]
+                D[95,204] = var(18); // [ var(204) , var(95) ]
+                D[96,204] = (-1)*var(20); // [ var(204) , var(96) ]
+                D[100,204] = var(26); // [ var(204) , var(100) ]
+                D[102,204] = var(32); // [ var(204) , var(102) ]
+                D[104,204] = (-1)*var(37); // [ var(204) , var(104) ]
+                D[105,204] = var(40); // [ var(204) , var(105) ]
+                D[107,204] = (-1)*var(45); // [ var(204) , var(107) ]
+                D[108,204] = var(48); // [ var(204) , var(108) ]
+                D[109,204] = (-1)*var(52); // [ var(204) , var(109) ]
+                D[114,204] = (-1)*var(63); // [ var(204) , var(114) ]
+                D[115,204] = var(69); // [ var(204) , var(115) ]
+                D[119,204] = (-1)*var(89); // [ var(204) , var(119) ]
+                D[120,204] = var(94); // [ var(204) , var(120) ]
+                D[2,205] = var(202); // [ var(205) , var(2) ]
+                D[5,205] = var(200); // [ var(205) , var(5) ]
+                D[13,205] = (-1)*var(195); // [ var(205) , var(13) ]
+                D[18,205] = (-1)*var(191); // [ var(205) , var(18) ]
+                D[21,205] = var(189); // [ var(205) , var(21) ]
+                D[25,205] = var(186); // [ var(205) , var(25) ]
+                D[26,205] = var(184); // [ var(205) , var(26) ]
+                D[30,205] = (-1)*var(181); // [ var(205) , var(30) ]
+                D[33,205] = (-1)*var(179); // [ var(205) , var(33) ]
+                D[34,205] = (-1)*var(177); // [ var(205) , var(34) ]
+                D[38,205] = var(175); // [ var(205) , var(38) ]
+                D[41,205] = var(172); // [ var(205) , var(41) ]
+                D[46,205] = (-1)*var(168); // [ var(205) , var(46) ]
+                D[48,205] = var(166); // [ var(205) , var(48) ]
+                D[52,205] = (-1)*var(161); // [ var(205) , var(52) ]
+                D[55,205] = (-1)*var(158); // [ var(205) , var(55) ]
+                D[57,205] = var(154); // [ var(205) , var(57) ]
+                D[59,205] = var(153); // [ var(205) , var(59) ]
+                D[61,205] = var(150); // [ var(205) , var(61) ]
+                D[64,205] = (-1)*var(146); // [ var(205) , var(64) ]
+                D[66,205] = (-1)*var(145); // [ var(205) , var(66) ]
+                D[69,205] = (-1)*var(141); // [ var(205) , var(69) ]
+                D[71,205] = var(138); // [ var(205) , var(71) ]
+                D[75,205] = var(133); // [ var(205) , var(75) ]
+                D[80,205] = (-1)*var(125); // [ var(205) , var(80) ]
+                D[82,205] = (-1)*var(122); // [ var(205) , var(82) ]
+                D[85,205] = (-1)*var(241)+(-2)*var(242)+(-2)*var(243)+(-3)*var(244)+(-3)*var(245)+(-2)*var(246)+(-1)*var(247); // [ var(205) , var(85) ]
+                D[89,205] = (-1)*var(4); // [ var(205) , var(89) ]
+                D[90,205] = (-1)*var(8); // [ var(205) , var(90) ]
+                D[93,205] = var(11); // [ var(205) , var(93) ]
+                D[95,205] = var(15); // [ var(205) , var(95) ]
+                D[97,205] = (-1)*var(16); // [ var(205) , var(97) ]
+                D[100,205] = (-1)*var(22); // [ var(205) , var(100) ]
+                D[106,205] = var(36); // [ var(205) , var(106) ]
+                D[108,205] = (-1)*var(43); // [ var(205) , var(108) ]
+                D[109,205] = var(47); // [ var(205) , var(109) ]
+                D[112,205] = var(56); // [ var(205) , var(112) ]
+                D[113,205] = (-1)*var(60); // [ var(205) , var(113) ]
+                D[115,205] = var(65); // [ var(205) , var(115) ]
+                D[117,205] = (-1)*var(77); // [ var(205) , var(117) ]
+                D[118,205] = var(83); // [ var(205) , var(118) ]
+                D[119,205] = (-1)*var(88); // [ var(205) , var(119) ]
+                D[2,206] = var(203); // [ var(206) , var(2) ]
+                D[6,206] = var(201); // [ var(206) , var(6) ]
+                D[8,206] = var(200); // [ var(206) , var(8) ]
+                D[10,206] = (-1)*var(198); // [ var(206) , var(10) ]
+                D[17,206] = var(193); // [ var(206) , var(17) ]
+                D[22,206] = (-1)*var(189); // [ var(206) , var(22) ]
+                D[23,206] = (-1)*var(188); // [ var(206) , var(23) ]
+                D[26,206] = var(185); // [ var(206) , var(26) ]
+                D[33,206] = (-1)*var(180); // [ var(206) , var(33) ]
+                D[38,206] = var(176); // [ var(206) , var(38) ]
+                D[40,206] = var(174); // [ var(206) , var(40) ]
+                D[42,206] = (-1)*var(171); // [ var(206) , var(42) ]
+                D[45,206] = (-1)*var(170); // [ var(206) , var(45) ]
+                D[50,206] = var(165); // [ var(206) , var(50) ]
+                D[51,206] = var(162); // [ var(206) , var(51) ]
+                D[54,206] = (-1)*var(160); // [ var(206) , var(54) ]
+                D[56,206] = (-1)*var(158); // [ var(206) , var(56) ]
+                D[60,206] = var(153); // [ var(206) , var(60) ]
+                D[65,206] = (-1)*var(146); // [ var(206) , var(65) ]
+                D[68,206] = var(143); // [ var(206) , var(68) ]
+                D[69,206] = var(142); // [ var(206) , var(69) ]
+                D[73,206] = (-1)*var(137); // [ var(206) , var(73) ]
+                D[78,206] = var(130); // [ var(206) , var(78) ]
+                D[80,206] = (-1)*var(128); // [ var(206) , var(80) ]
+                D[81,206] = (-1)*var(126); // [ var(206) , var(81) ]
+                D[83,206] = (-1)*var(122); // [ var(206) , var(83) ]
+                D[86,206] = (-1)*var(241)+(-2)*var(242)+(-2)*var(243)+(-3)*var(244)+(-2)*var(245)+(-2)*var(246)+(-1)*var(247)+(-1)*var(248); // [ var(206) , var(86) ]
+                D[90,206] = (-1)*var(5); // [ var(206) , var(90) ]
+                D[91,206] = (-1)*var(7); // [ var(206) , var(91) ]
+                D[94,206] = var(12); // [ var(206) , var(94) ]
+                D[98,206] = (-1)*var(19); // [ var(206) , var(98) ]
+                D[100,206] = var(21); // [ var(206) , var(100) ]
+                D[101,206] = var(24); // [ var(206) , var(101) ]
+                D[103,206] = (-1)*var(28); // [ var(206) , var(103) ]
+                D[105,206] = var(35); // [ var(206) , var(105) ]
+                D[107,206] = (-1)*var(39); // [ var(206) , var(107) ]
+                D[112,206] = var(55); // [ var(206) , var(112) ]
+                D[113,206] = (-1)*var(59); // [ var(206) , var(113) ]
+                D[115,206] = var(64); // [ var(206) , var(115) ]
+                D[116,206] = (-1)*var(70); // [ var(206) , var(116) ]
+                D[118,206] = var(82); // [ var(206) , var(118) ]
+                D[120,206] = (-1)*var(92); // [ var(206) , var(120) ]
+                D[5,207] = var(203); // [ var(207) , var(5) ]
+                D[8,207] = var(202); // [ var(207) , var(8) ]
+                D[12,207] = var(198); // [ var(207) , var(12) ]
+                D[13,207] = (-1)*var(197); // [ var(207) , var(13) ]
+                D[19,207] = (-1)*var(193); // [ var(207) , var(19) ]
+                D[20,207] = (-1)*var(192); // [ var(207) , var(20) ]
+                D[24,207] = var(188); // [ var(207) , var(24) ]
+                D[27,207] = var(187); // [ var(207) , var(27) ]
+                D[29,207] = var(183); // [ var(207) , var(29) ]
+                D[31,207] = (-1)*var(182); // [ var(207) , var(31) ]
+                D[36,207] = var(177); // [ var(207) , var(36) ]
+                D[43,207] = (-1)*var(172); // [ var(207) , var(43) ]
+                D[47,207] = var(168); // [ var(207) , var(47) ]
+                D[48,207] = (-1)*var(167); // [ var(207) , var(48) ]
+                D[52,207] = var(163); // [ var(207) , var(52) ]
+                D[57,207] = (-1)*var(156); // [ var(207) , var(57) ]
+                D[62,207] = var(151); // [ var(207) , var(62) ]
+                D[63,207] = (-1)*var(149); // [ var(207) , var(63) ]
+                D[67,207] = (-1)*var(147); // [ var(207) , var(67) ]
+                D[68,207] = (-1)*var(144); // [ var(207) , var(68) ]
+                D[72,207] = var(140); // [ var(207) , var(72) ]
+                D[73,207] = var(139); // [ var(207) , var(73) ]
+                D[77,207] = var(133); // [ var(207) , var(77) ]
+                D[78,207] = (-1)*var(132); // [ var(207) , var(78) ]
+                D[82,207] = (-1)*var(128); // [ var(207) , var(82) ]
+                D[83,207] = (-1)*var(125); // [ var(207) , var(83) ]
+                D[87,207] = (-1)*var(241)+(-1)*var(242)+(-2)*var(243)+(-3)*var(244)+(-3)*var(245)+(-2)*var(246)+(-1)*var(247)+(-1)*var(248); // [ var(207) , var(87) ]
+                D[90,207] = (-1)*var(2); // [ var(207) , var(90) ]
+                D[92,207] = (-1)*var(7); // [ var(207) , var(92) ]
+                D[94,207] = (-1)*var(10); // [ var(207) , var(94) ]
+                D[96,207] = var(14); // [ var(207) , var(96) ]
+                D[98,207] = var(17); // [ var(207) , var(98) ]
+                D[101,207] = (-1)*var(23); // [ var(207) , var(101) ]
+                D[106,207] = (-1)*var(34); // [ var(207) , var(106) ]
+                D[108,207] = var(41); // [ var(207) , var(108) ]
+                D[109,207] = (-1)*var(46); // [ var(207) , var(109) ]
+                D[110,207] = var(49); // [ var(207) , var(110) ]
+                D[111,207] = (-1)*var(53); // [ var(207) , var(111) ]
+                D[114,207] = var(58); // [ var(207) , var(114) ]
+                D[117,207] = (-1)*var(75); // [ var(207) , var(117) ]
+                D[118,207] = var(80); // [ var(207) , var(118) ]
+                D[120,207] = (-1)*var(91); // [ var(207) , var(120) ]
+                D[4,208] = var(204); // [ var(208) , var(4) ]
+                D[7,208] = var(203); // [ var(208) , var(7) ]
+                D[11,208] = (-1)*var(199); // [ var(208) , var(11) ]
+                D[14,208] = var(197); // [ var(208) , var(14) ]
+                D[15,208] = (-1)*var(196); // [ var(208) , var(15) ]
+                D[16,208] = var(194); // [ var(208) , var(16) ]
+                D[22,208] = (-1)*var(190); // [ var(208) , var(22) ]
+                D[28,208] = (-1)*var(185); // [ var(208) , var(28) ]
+                D[35,208] = var(180); // [ var(208) , var(35) ]
+                D[36,208] = var(178); // [ var(208) , var(36) ]
+                D[39,208] = (-1)*var(176); // [ var(208) , var(39) ]
+                D[43,208] = (-1)*var(173); // [ var(208) , var(43) ]
+                D[47,208] = var(169); // [ var(208) , var(47) ]
+                D[49,208] = (-1)*var(167); // [ var(208) , var(49) ]
+                D[53,208] = var(163); // [ var(208) , var(53) ]
+                D[56,208] = var(159); // [ var(208) , var(56) ]
+                D[58,208] = (-1)*var(156); // [ var(208) , var(58) ]
+                D[60,208] = (-1)*var(155); // [ var(208) , var(60) ]
+                D[65,208] = var(148); // [ var(208) , var(65) ]
+                D[70,208] = var(142); // [ var(208) , var(70) ]
+                D[74,208] = (-1)*var(136); // [ var(208) , var(74) ]
+                D[76,208] = var(135); // [ var(208) , var(76) ]
+                D[77,208] = (-1)*var(134); // [ var(208) , var(77) ]
+                D[79,208] = var(131); // [ var(208) , var(79) ]
+                D[83,208] = (-1)*var(127); // [ var(208) , var(83) ]
+                D[84,208] = (-1)*var(124); // [ var(208) , var(84) ]
+                D[88,208] = (-1)*var(241)+(-1)*var(242)+(-2)*var(243)+(-3)*var(244)+(-2)*var(245)+(-2)*var(246)+(-2)*var(247)+(-1)*var(248); // [ var(208) , var(88) ]
+                D[91,208] = (-1)*var(2); // [ var(208) , var(91) ]
+                D[92,208] = (-1)*var(5); // [ var(208) , var(92) ]
+                D[96,208] = (-1)*var(13); // [ var(208) , var(96) ]
+                D[99,208] = var(18); // [ var(208) , var(99) ]
+                D[102,208] = (-1)*var(25); // [ var(208) , var(102) ]
+                D[103,208] = var(26); // [ var(208) , var(103) ]
+                D[104,208] = var(30); // [ var(208) , var(104) ]
+                D[105,208] = (-1)*var(33); // [ var(208) , var(105) ]
+                D[107,208] = var(38); // [ var(208) , var(107) ]
+                D[110,208] = var(48); // [ var(208) , var(110) ]
+                D[111,208] = (-1)*var(52); // [ var(208) , var(111) ]
+                D[114,208] = var(57); // [ var(208) , var(114) ]
+                D[116,208] = (-1)*var(69); // [ var(208) , var(116) ]
+                D[119,208] = var(85); // [ var(208) , var(119) ]
+                D[120,208] = (-1)*var(90); // [ var(208) , var(120) ]
+                D[4,209] = var(205); // [ var(209) , var(4) ]
+                D[10,209] = var(202); // [ var(209) , var(10) ]
+                D[12,209] = (-1)*var(200); // [ var(209) , var(12) ]
+                D[18,209] = (-1)*var(196); // [ var(209) , var(18) ]
+                D[20,209] = var(195); // [ var(209) , var(20) ]
+                D[26,209] = var(190); // [ var(209) , var(26) ]
+                D[28,209] = (-1)*var(189); // [ var(209) , var(28) ]
+                D[32,209] = var(186); // [ var(209) , var(32) ]
+                D[34,209] = (-1)*var(183); // [ var(209) , var(34) ]
+                D[37,209] = (-1)*var(181); // [ var(209) , var(37) ]
+                D[40,209] = (-1)*var(179); // [ var(209) , var(40) ]
+                D[45,209] = var(175); // [ var(209) , var(45) ]
+                D[48,209] = var(173); // [ var(209) , var(48) ]
+                D[49,209] = var(172); // [ var(209) , var(49) ]
+                D[52,209] = (-1)*var(169); // [ var(209) , var(52) ]
+                D[53,209] = (-1)*var(168); // [ var(209) , var(53) ]
+                D[55,209] = (-1)*var(165); // [ var(209) , var(55) ]
+                D[59,209] = var(160); // [ var(209) , var(59) ]
+                D[61,209] = var(157); // [ var(209) , var(61) ]
+                D[63,209] = var(154); // [ var(209) , var(63) ]
+                D[66,209] = (-1)*var(152); // [ var(209) , var(66) ]
+                D[69,209] = var(148); // [ var(209) , var(69) ]
+                D[70,209] = (-1)*var(146); // [ var(209) , var(70) ]
+                D[75,209] = (-1)*var(140); // [ var(209) , var(75) ]
+                D[76,209] = var(138); // [ var(209) , var(76) ]
+                D[80,209] = var(132); // [ var(209) , var(80) ]
+                D[82,209] = (-1)*var(130); // [ var(209) , var(82) ]
+                D[85,209] = (-1)*var(124); // [ var(209) , var(85) ]
+                D[89,209] = (-1)*var(241)+(-2)*var(242)+(-2)*var(243)+(-4)*var(244)+(-3)*var(245)+(-2)*var(246)+(-1)*var(247); // [ var(209) , var(89) ]
+                D[93,209] = (-1)*var(3); // [ var(209) , var(93) ]
+                D[94,209] = (-1)*var(8); // [ var(209) , var(94) ]
+                D[97,209] = var(9); // [ var(209) , var(97) ]
+                D[99,209] = var(15); // [ var(209) , var(99) ]
+                D[103,209] = (-1)*var(22); // [ var(209) , var(103) ]
+                D[106,209] = var(29); // [ var(209) , var(106) ]
+                D[110,209] = (-1)*var(43); // [ var(209) , var(110) ]
+                D[111,209] = var(47); // [ var(209) , var(111) ]
+                D[112,209] = (-1)*var(50); // [ var(209) , var(112) ]
+                D[113,209] = var(54); // [ var(209) , var(113) ]
+                D[116,209] = (-1)*var(65); // [ var(209) , var(116) ]
+                D[117,209] = var(72); // [ var(209) , var(117) ]
+                D[118,209] = (-1)*var(78); // [ var(209) , var(118) ]
+                D[119,209] = var(84); // [ var(209) , var(119) ]
+                D[2,210] = var(207); // [ var(210) , var(2) ]
+                D[5,210] = var(206); // [ var(210) , var(5) ]
+                D[8,210] = var(205); // [ var(210) , var(8) ]
+                D[13,210] = (-1)*var(201); // [ var(210) , var(13) ]
+                D[18,210] = (-1)*var(198); // [ var(210) , var(18) ]
+                D[25,210] = var(193); // [ var(210) , var(25) ]
+                D[26,210] = var(192); // [ var(210) , var(26) ]
+                D[29,210] = var(189); // [ var(210) , var(29) ]
+                D[30,210] = (-1)*var(188); // [ var(210) , var(30) ]
+                D[33,210] = (-1)*var(187); // [ var(210) , var(33) ]
+                D[38,210] = var(182); // [ var(210) , var(38) ]
+                D[42,210] = (-1)*var(177); // [ var(210) , var(42) ]
+                D[48,210] = var(174); // [ var(210) , var(48) ]
+                D[50,210] = var(172); // [ var(210) , var(50) ]
+                D[52,210] = (-1)*var(170); // [ var(210) , var(52) ]
+                D[54,210] = (-1)*var(168); // [ var(210) , var(54) ]
+                D[57,210] = var(162); // [ var(210) , var(57) ]
+                D[62,210] = (-1)*var(158); // [ var(210) , var(62) ]
+                D[67,210] = var(153); // [ var(210) , var(67) ]
+                D[68,210] = var(150); // [ var(210) , var(68) ]
+                D[69,210] = (-1)*var(149); // [ var(210) , var(69) ]
+                D[72,210] = (-1)*var(146); // [ var(210) , var(72) ]
+                D[73,210] = (-1)*var(145); // [ var(210) , var(73) ]
+                D[78,210] = var(138); // [ var(210) , var(78) ]
+                D[81,210] = var(133); // [ var(210) , var(81) ]
+                D[85,210] = (-1)*var(128); // [ var(210) , var(85) ]
+                D[86,210] = (-1)*var(125); // [ var(210) , var(86) ]
+                D[87,210] = (-1)*var(122); // [ var(210) , var(87) ]
+                D[90,210] = (-1)*var(241)+(-2)*var(242)+(-2)*var(243)+(-3)*var(244)+(-3)*var(245)+(-2)*var(246)+(-1)*var(247)+(-1)*var(248); // [ var(210) , var(90) ]
+                D[94,210] = (-1)*var(4); // [ var(210) , var(94) ]
+                D[95,210] = (-1)*var(7); // [ var(210) , var(95) ]
+                D[98,210] = var(11); // [ var(210) , var(98) ]
+                D[100,210] = var(14); // [ var(210) , var(100) ]
+                D[101,210] = (-1)*var(16); // [ var(210) , var(101) ]
+                D[106,210] = (-1)*var(28); // [ var(210) , var(106) ]
+                D[108,210] = var(35); // [ var(210) , var(108) ]
+                D[109,210] = (-1)*var(39); // [ var(210) , var(109) ]
+                D[112,210] = (-1)*var(49); // [ var(210) , var(112) ]
+                D[113,210] = var(53); // [ var(210) , var(113) ]
+                D[115,210] = (-1)*var(58); // [ var(210) , var(115) ]
+                D[117,210] = var(70); // [ var(210) , var(117) ]
+                D[118,210] = (-1)*var(76); // [ var(210) , var(118) ]
+                D[120,210] = var(88); // [ var(210) , var(120) ]
+                D[2,211] = var(208); // [ var(211) , var(2) ]
+                D[7,211] = var(206); // [ var(211) , var(7) ]
+                D[10,211] = (-1)*var(204); // [ var(211) , var(10) ]
+                D[14,211] = var(201); // [ var(211) , var(14) ]
+                D[15,211] = (-1)*var(200); // [ var(211) , var(15) ]
+                D[17,211] = var(199); // [ var(211) , var(17) ]
+                D[22,211] = (-1)*var(195); // [ var(211) , var(22) ]
+                D[23,211] = (-1)*var(194); // [ var(211) , var(23) ]
+                D[34,211] = var(185); // [ var(211) , var(34) ]
+                D[41,211] = (-1)*var(180); // [ var(211) , var(41) ]
+                D[42,211] = (-1)*var(178); // [ var(211) , var(42) ]
+                D[46,211] = var(176); // [ var(211) , var(46) ]
+                D[49,211] = var(174); // [ var(211) , var(49) ]
+                D[50,211] = var(173); // [ var(211) , var(50) ]
+                D[53,211] = (-1)*var(170); // [ var(211) , var(53) ]
+                D[54,211] = (-1)*var(169); // [ var(211) , var(54) ]
+                D[56,211] = (-1)*var(166); // [ var(211) , var(56) ]
+                D[58,211] = var(162); // [ var(211) , var(58) ]
+                D[60,211] = var(161); // [ var(211) , var(60) ]
+                D[65,211] = (-1)*var(154); // [ var(211) , var(65) ]
+                D[74,211] = var(143); // [ var(211) , var(74) ]
+                D[75,211] = var(142); // [ var(211) , var(75) ]
+                D[79,211] = (-1)*var(137); // [ var(211) , var(79) ]
+                D[80,211] = var(135); // [ var(211) , var(80) ]
+                D[81,211] = (-1)*var(134); // [ var(211) , var(81) ]
+                D[84,211] = var(130); // [ var(211) , var(84) ]
+                D[86,211] = (-1)*var(127); // [ var(211) , var(86) ]
+                D[88,211] = (-1)*var(122); // [ var(211) , var(88) ]
+                D[91,211] = (-1)*var(241)+(-2)*var(242)+(-2)*var(243)+(-3)*var(244)+(-2)*var(245)+(-2)*var(246)+(-2)*var(247)+(-1)*var(248); // [ var(211) , var(91) ]
+                D[95,211] = (-1)*var(5); // [ var(211) , var(95) ]
+                D[99,211] = var(12); // [ var(211) , var(99) ]
+                D[100,211] = (-1)*var(13); // [ var(211) , var(100) ]
+                D[102,211] = (-1)*var(19); // [ var(211) , var(102) ]
+                D[103,211] = var(20); // [ var(211) , var(103) ]
+                D[104,211] = var(24); // [ var(211) , var(104) ]
+                D[105,211] = (-1)*var(27); // [ var(211) , var(105) ]
+                D[107,211] = var(31); // [ var(211) , var(107) ]
+                D[112,211] = (-1)*var(48); // [ var(211) , var(112) ]
+                D[113,211] = var(52); // [ var(211) , var(113) ]
+                D[115,211] = (-1)*var(57); // [ var(211) , var(115) ]
+                D[116,211] = var(63); // [ var(211) , var(116) ]
+                D[119,211] = (-1)*var(82); // [ var(211) , var(119) ]
+                D[120,211] = var(87); // [ var(211) , var(120) ]
+                D[5,212] = var(208); // [ var(212) , var(5) ]
+                D[7,212] = var(207); // [ var(212) , var(7) ]
+                D[12,212] = var(204); // [ var(212) , var(12) ]
+                D[15,212] = (-1)*var(202); // [ var(212) , var(15) ]
+                D[19,212] = (-1)*var(199); // [ var(212) , var(19) ]
+                D[21,212] = (-1)*var(197); // [ var(212) , var(21) ]
+                D[24,212] = var(194); // [ var(212) , var(24) ]
+                D[28,212] = (-1)*var(192); // [ var(212) , var(28) ]
+                D[29,212] = var(190); // [ var(212) , var(29) ]
+                D[35,212] = var(187); // [ var(212) , var(35) ]
+                D[36,212] = var(184); // [ var(212) , var(36) ]
+                D[39,212] = (-1)*var(182); // [ var(212) , var(39) ]
+                D[43,212] = (-1)*var(179); // [ var(212) , var(43) ]
+                D[47,212] = var(175); // [ var(212) , var(47) ]
+                D[55,212] = (-1)*var(167); // [ var(212) , var(55) ]
+                D[59,212] = var(163); // [ var(212) , var(59) ]
+                D[62,212] = var(159); // [ var(212) , var(62) ]
+                D[64,212] = (-1)*var(156); // [ var(212) , var(64) ]
+                D[67,212] = (-1)*var(155); // [ var(212) , var(67) ]
+                D[70,212] = (-1)*var(149); // [ var(212) , var(70) ]
+                D[72,212] = var(148); // [ var(212) , var(72) ]
+                D[74,212] = (-1)*var(144); // [ var(212) , var(74) ]
+                D[77,212] = var(141); // [ var(212) , var(77) ]
+                D[79,212] = var(139); // [ var(212) , var(79) ]
+                D[82,212] = var(135); // [ var(212) , var(82) ]
+                D[84,212] = (-1)*var(132); // [ var(212) , var(84) ]
+                D[87,212] = (-1)*var(127); // [ var(212) , var(87) ]
+                D[88,212] = (-1)*var(125); // [ var(212) , var(88) ]
+                D[92,212] = (-1)*var(241)+(-1)*var(242)+(-2)*var(243)+(-3)*var(244)+(-3)*var(245)+(-2)*var(246)+(-2)*var(247)+(-1)*var(248); // [ var(212) , var(92) ]
+                D[95,212] = (-1)*var(2); // [ var(212) , var(95) ]
+                D[96,212] = (-1)*var(6); // [ var(212) , var(96) ]
+                D[99,212] = (-1)*var(10); // [ var(212) , var(99) ]
+                D[102,212] = var(17); // [ var(212) , var(102) ]
+                D[104,212] = (-1)*var(23); // [ var(212) , var(104) ]
+                D[106,212] = var(26); // [ var(212) , var(106) ]
+                D[108,212] = (-1)*var(33); // [ var(212) , var(108) ]
+                D[109,212] = var(38); // [ var(212) , var(109) ]
+                D[110,212] = (-1)*var(40); // [ var(212) , var(110) ]
+                D[111,212] = var(45); // [ var(212) , var(111) ]
+                D[114,212] = (-1)*var(51); // [ var(212) , var(114) ]
+                D[117,212] = var(69); // [ var(212) , var(117) ]
+                D[119,212] = (-1)*var(80); // [ var(212) , var(119) ]
+                D[120,212] = var(86); // [ var(212) , var(120) ]
+                D[3,213] = var(209); // [ var(213) , var(3) ]
+                D[11,213] = (-1)*var(205); // [ var(213) , var(11) ]
+                D[17,213] = (-1)*var(202); // [ var(213) , var(17) ]
+                D[19,213] = var(200); // [ var(213) , var(19) ]
+                D[25,213] = var(196); // [ var(213) , var(25) ]
+                D[27,213] = (-1)*var(195); // [ var(213) , var(27) ]
+                D[32,213] = (-1)*var(191); // [ var(213) , var(32) ]
+                D[33,213] = (-1)*var(190); // [ var(213) , var(33) ]
+                D[35,213] = var(189); // [ var(213) , var(35) ]
+                D[40,213] = var(184); // [ var(213) , var(40) ]
+                D[41,213] = var(183); // [ var(213) , var(41) ]
+                D[44,213] = var(181); // [ var(213) , var(44) ]
+                D[48,213] = (-1)*var(178); // [ var(213) , var(48) ]
+                D[49,213] = (-1)*var(177); // [ var(213) , var(49) ]
+                D[51,213] = (-1)*var(175); // [ var(213) , var(51) ]
+                D[55,213] = var(171); // [ var(213) , var(55) ]
+                D[57,213] = var(169); // [ var(213) , var(57) ]
+                D[58,213] = var(168); // [ var(213) , var(58) ]
+                D[61,213] = (-1)*var(164); // [ var(213) , var(61) ]
+                D[63,213] = (-1)*var(161); // [ var(213) , var(63) ]
+                D[64,213] = (-1)*var(160); // [ var(213) , var(64) ]
+                D[69,213] = (-1)*var(155); // [ var(213) , var(69) ]
+                D[70,213] = var(153); // [ var(213) , var(70) ]
+                D[71,213] = var(152); // [ var(213) , var(71) ]
+                D[75,213] = var(147); // [ var(213) , var(75) ]
+                D[76,213] = (-1)*var(145); // [ var(213) , var(76) ]
+                D[80,213] = (-1)*var(139); // [ var(213) , var(80) ]
+                D[82,213] = var(137); // [ var(213) , var(82) ]
+                D[85,213] = var(131); // [ var(213) , var(85) ]
+                D[89,213] = (-1)*var(123); // [ var(213) , var(89) ]
+                D[93,213] = (-1)*var(241)+(-2)*var(242)+(-3)*var(243)+(-4)*var(244)+(-3)*var(245)+(-2)*var(246)+(-1)*var(247); // [ var(213) , var(93) ]
+                D[97,213] = (-1)*var(1); // [ var(213) , var(97) ]
+                D[98,213] = (-1)*var(8); // [ var(213) , var(98) ]
+                D[102,213] = var(15); // [ var(213) , var(102) ]
+                D[105,213] = (-1)*var(22); // [ var(213) , var(105) ]
+                D[108,213] = var(29); // [ var(213) , var(108) ]
+                D[110,213] = (-1)*var(36); // [ var(213) , var(110) ]
+                D[112,213] = (-1)*var(42); // [ var(213) , var(112) ]
+                D[114,213] = var(47); // [ var(213) , var(114) ]
+                D[115,213] = var(54); // [ var(213) , var(115) ]
+                D[116,213] = (-1)*var(60); // [ var(213) , var(116) ]
+                D[117,213] = var(67); // [ var(213) , var(117) ]
+                D[118,213] = (-1)*var(73); // [ var(213) , var(118) ]
+                D[119,213] = var(79); // [ var(213) , var(119) ]
+                D[4,214] = var(210); // [ var(214) , var(4) ]
+                D[8,214] = var(209); // [ var(214) , var(8) ]
+                D[10,214] = var(207); // [ var(214) , var(10) ]
+                D[12,214] = (-1)*var(206); // [ var(214) , var(12) ]
+                D[18,214] = (-1)*var(203); // [ var(214) , var(18) ]
+                D[20,214] = var(201); // [ var(214) , var(20) ]
+                D[26,214] = var(197); // [ var(214) , var(26) ]
+                D[32,214] = var(193); // [ var(214) , var(32) ]
+                D[36,214] = (-1)*var(189); // [ var(214) , var(36) ]
+                D[37,214] = (-1)*var(188); // [ var(214) , var(37) ]
+                D[40,214] = (-1)*var(187); // [ var(214) , var(40) ]
+                D[42,214] = (-1)*var(183); // [ var(214) , var(42) ]
+                D[45,214] = var(182); // [ var(214) , var(45) ]
+                D[48,214] = var(180); // [ var(214) , var(48) ]
+                D[52,214] = (-1)*var(176); // [ var(214) , var(52) ]
+                D[56,214] = var(172); // [ var(214) , var(56) ]
+                D[60,214] = (-1)*var(168); // [ var(214) , var(60) ]
+                D[62,214] = (-1)*var(165); // [ var(214) , var(62) ]
+                D[63,214] = var(162); // [ var(214) , var(63) ]
+                D[67,214] = var(160); // [ var(214) , var(67) ]
+                D[68,214] = var(157); // [ var(214) , var(68) ]
+                D[69,214] = var(156); // [ var(214) , var(69) ]
+                D[73,214] = (-1)*var(152); // [ var(214) , var(73) ]
+                D[77,214] = (-1)*var(146); // [ var(214) , var(77) ]
+                D[81,214] = (-1)*var(140); // [ var(214) , var(81) ]
+                D[83,214] = var(138); // [ var(214) , var(83) ]
+                D[86,214] = var(132); // [ var(214) , var(86) ]
+                D[87,214] = (-1)*var(130); // [ var(214) , var(87) ]
+                D[89,214] = (-1)*var(128); // [ var(214) , var(89) ]
+                D[90,214] = (-1)*var(124); // [ var(214) , var(90) ]
+                D[94,214] = (-1)*var(241)+(-2)*var(242)+(-2)*var(243)+(-4)*var(244)+(-3)*var(245)+(-2)*var(246)+(-1)*var(247)+(-1)*var(248); // [ var(214) , var(94) ]
+                D[98,214] = (-1)*var(3); // [ var(214) , var(98) ]
+                D[99,214] = (-1)*var(7); // [ var(214) , var(99) ]
+                D[101,214] = var(9); // [ var(214) , var(101) ]
+                D[103,214] = var(14); // [ var(214) , var(103) ]
+                D[106,214] = (-1)*var(21); // [ var(214) , var(106) ]
+                D[110,214] = var(35); // [ var(214) , var(110) ]
+                D[111,214] = (-1)*var(39); // [ var(214) , var(111) ]
+                D[112,214] = var(41); // [ var(214) , var(112) ]
+                D[113,214] = (-1)*var(46); // [ var(214) , var(113) ]
+                D[116,214] = var(58); // [ var(214) , var(116) ]
+                D[117,214] = (-1)*var(64); // [ var(214) , var(117) ]
+                D[118,214] = var(71); // [ var(214) , var(118) ]
+                D[120,214] = (-1)*var(84); // [ var(214) , var(120) ]
+                D[2,215] = var(212); // [ var(215) , var(2) ]
+                D[5,215] = var(211); // [ var(215) , var(5) ]
+                D[7,215] = var(210); // [ var(215) , var(7) ]
+                D[15,215] = (-1)*var(205); // [ var(215) , var(15) ]
+                D[18,215] = (-1)*var(204); // [ var(215) , var(18) ]
+                D[21,215] = (-1)*var(201); // [ var(215) , var(21) ]
+                D[25,215] = var(199); // [ var(215) , var(25) ]
+                D[29,215] = var(195); // [ var(215) , var(29) ]
+                D[30,215] = (-1)*var(194); // [ var(215) , var(30) ]
+                D[34,215] = var(192); // [ var(215) , var(34) ]
+                D[41,215] = (-1)*var(187); // [ var(215) , var(41) ]
+                D[42,215] = (-1)*var(184); // [ var(215) , var(42) ]
+                D[46,215] = var(182); // [ var(215) , var(46) ]
+                D[50,215] = var(179); // [ var(215) , var(50) ]
+                D[54,215] = (-1)*var(175); // [ var(215) , var(54) ]
+                D[55,215] = var(174); // [ var(215) , var(55) ]
+                D[59,215] = (-1)*var(170); // [ var(215) , var(59) ]
+                D[62,215] = (-1)*var(166); // [ var(215) , var(62) ]
+                D[64,215] = var(162); // [ var(215) , var(64) ]
+                D[67,215] = var(161); // [ var(215) , var(67) ]
+                D[72,215] = (-1)*var(154); // [ var(215) , var(72) ]
+                D[74,215] = var(150); // [ var(215) , var(74) ]
+                D[75,215] = (-1)*var(149); // [ var(215) , var(75) ]
+                D[79,215] = (-1)*var(145); // [ var(215) , var(79) ]
+                D[81,215] = var(141); // [ var(215) , var(81) ]
+                D[84,215] = var(138); // [ var(215) , var(84) ]
+                D[85,215] = var(135); // [ var(215) , var(85) ]
+                D[90,215] = (-1)*var(127); // [ var(215) , var(90) ]
+                D[91,215] = (-1)*var(125); // [ var(215) , var(91) ]
+                D[92,215] = (-1)*var(122); // [ var(215) , var(92) ]
+                D[95,215] = (-1)*var(241)+(-2)*var(242)+(-2)*var(243)+(-3)*var(244)+(-3)*var(245)+(-2)*var(246)+(-2)*var(247)+(-1)*var(248); // [ var(215) , var(95) ]
+                D[99,215] = (-1)*var(4); // [ var(215) , var(99) ]
+                D[100,215] = (-1)*var(6); // [ var(215) , var(100) ]
+                D[102,215] = var(11); // [ var(215) , var(102) ]
+                D[104,215] = (-1)*var(16); // [ var(215) , var(104) ]
+                D[106,215] = var(20); // [ var(215) , var(106) ]
+                D[108,215] = (-1)*var(27); // [ var(215) , var(108) ]
+                D[109,215] = var(31); // [ var(215) , var(109) ]
+                D[112,215] = var(40); // [ var(215) , var(112) ]
+                D[113,215] = (-1)*var(45); // [ var(215) , var(113) ]
+                D[115,215] = var(51); // [ var(215) , var(115) ]
+                D[117,215] = (-1)*var(63); // [ var(215) , var(117) ]
+                D[119,215] = var(76); // [ var(215) , var(119) ]
+                D[120,215] = (-1)*var(83); // [ var(215) , var(120) ]
+                D[6,216] = var(212); // [ var(216) , var(6) ]
+                D[13,216] = var(208); // [ var(216) , var(13) ]
+                D[14,216] = (-1)*var(207); // [ var(216) , var(14) ]
+                D[20,216] = var(204); // [ var(216) , var(20) ]
+                D[21,216] = (-1)*var(203); // [ var(216) , var(21) ]
+                D[22,216] = var(202); // [ var(216) , var(22) ]
+                D[27,216] = (-1)*var(199); // [ var(216) , var(27) ]
+                D[28,216] = (-1)*var(198); // [ var(216) , var(28) ]
+                D[29,216] = var(196); // [ var(216) , var(29) ]
+                D[31,216] = var(194); // [ var(216) , var(31) ]
+                D[35,216] = var(193); // [ var(216) , var(35) ]
+                D[36,216] = var(191); // [ var(216) , var(36) ]
+                D[39,216] = (-1)*var(188); // [ var(216) , var(39) ]
+                D[43,216] = (-1)*var(186); // [ var(216) , var(43) ]
+                D[47,216] = var(181); // [ var(216) , var(47) ]
+                D[61,216] = (-1)*var(167); // [ var(216) , var(61) ]
+                D[66,216] = var(163); // [ var(216) , var(66) ]
+                D[68,216] = var(159); // [ var(216) , var(68) ]
+                D[71,216] = (-1)*var(156); // [ var(216) , var(71) ]
+                D[73,216] = (-1)*var(155); // [ var(216) , var(73) ]
+                D[74,216] = (-1)*var(151); // [ var(216) , var(74) ]
+                D[76,216] = (-1)*var(149); // [ var(216) , var(76) ]
+                D[78,216] = var(148); // [ var(216) , var(78) ]
+                D[79,216] = var(147); // [ var(216) , var(79) ]
+                D[82,216] = (-1)*var(142); // [ var(216) , var(82) ]
+                D[83,216] = var(141); // [ var(216) , var(83) ]
+                D[84,216] = (-1)*var(140); // [ var(216) , var(84) ]
+                D[87,216] = var(134); // [ var(216) , var(87) ]
+                D[88,216] = (-1)*var(133); // [ var(216) , var(88) ]
+                D[92,216] = (-1)*var(126); // [ var(216) , var(92) ]
+                D[96,216] = (-1)*var(241)+(-1)*var(242)+(-2)*var(243)+(-3)*var(244)+(-3)*var(245)+(-3)*var(246)+(-2)*var(247)+(-1)*var(248); // [ var(216) , var(96) ]
+                D[100,216] = (-1)*var(2); // [ var(216) , var(100) ]
+                D[103,216] = (-1)*var(10); // [ var(216) , var(103) ]
+                D[105,216] = var(17); // [ var(216) , var(105) ]
+                D[106,216] = (-1)*var(18); // [ var(216) , var(106) ]
+                D[107,216] = (-1)*var(23); // [ var(216) , var(107) ]
+                D[108,216] = var(25); // [ var(216) , var(108) ]
+                D[109,216] = (-1)*var(30); // [ var(216) , var(109) ]
+                D[110,216] = var(32); // [ var(216) , var(110) ]
+                D[111,216] = (-1)*var(37); // [ var(216) , var(111) ]
+                D[114,216] = var(44); // [ var(216) , var(114) ]
+                D[118,216] = (-1)*var(69); // [ var(216) , var(118) ]
+                D[119,216] = var(75); // [ var(216) , var(119) ]
+                D[120,216] = (-1)*var(81); // [ var(216) , var(120) ]
+                D[1,217] = var(213); // [ var(217) , var(1) ]
+                D[9,217] = (-1)*var(209); // [ var(217) , var(9) ]
+                D[16,217] = var(205); // [ var(217) , var(16) ]
+                D[23,217] = var(202); // [ var(217) , var(23) ]
+                D[24,217] = (-1)*var(200); // [ var(217) , var(24) ]
+                D[30,217] = (-1)*var(196); // [ var(217) , var(30) ]
+                D[31,217] = var(195); // [ var(217) , var(31) ]
+                D[37,217] = var(191); // [ var(217) , var(37) ]
+                D[38,217] = var(190); // [ var(217) , var(38) ]
+                D[39,217] = (-1)*var(189); // [ var(217) , var(39) ]
+                D[44,217] = (-1)*var(186); // [ var(217) , var(44) ]
+                D[45,217] = (-1)*var(184); // [ var(217) , var(45) ]
+                D[46,217] = (-1)*var(183); // [ var(217) , var(46) ]
+                D[51,217] = var(179); // [ var(217) , var(51) ]
+                D[52,217] = var(178); // [ var(217) , var(52) ]
+                D[53,217] = var(177); // [ var(217) , var(53) ]
+                D[57,217] = (-1)*var(173); // [ var(217) , var(57) ]
+                D[58,217] = (-1)*var(172); // [ var(217) , var(58) ]
+                D[59,217] = (-1)*var(171); // [ var(217) , var(59) ]
+                D[63,217] = var(166); // [ var(217) , var(63) ]
+                D[64,217] = var(165); // [ var(217) , var(64) ]
+                D[66,217] = var(164); // [ var(217) , var(66) ]
+                D[69,217] = var(159); // [ var(217) , var(69) ]
+                D[70,217] = (-1)*var(158); // [ var(217) , var(70) ]
+                D[71,217] = (-1)*var(157); // [ var(217) , var(71) ]
+                D[75,217] = (-1)*var(151); // [ var(217) , var(75) ]
+                D[76,217] = var(150); // [ var(217) , var(76) ]
+                D[80,217] = var(144); // [ var(217) , var(80) ]
+                D[82,217] = (-1)*var(143); // [ var(217) , var(82) ]
+                D[85,217] = (-1)*var(136); // [ var(217) , var(85) ]
+                D[89,217] = var(129); // [ var(217) , var(89) ]
+                D[93,217] = (-1)*var(121); // [ var(217) , var(93) ]
+                D[97,217] = (-2)*var(241)+(-2)*var(242)+(-3)*var(243)+(-4)*var(244)+(-3)*var(245)+(-2)*var(246)+(-1)*var(247); // [ var(217) , var(97) ]
+                D[101,217] = (-1)*var(8); // [ var(217) , var(101) ]
+                D[104,217] = var(15); // [ var(217) , var(104) ]
+                D[107,217] = (-1)*var(22); // [ var(217) , var(107) ]
+                D[109,217] = var(29); // [ var(217) , var(109) ]
+                D[111,217] = (-1)*var(36); // [ var(217) , var(111) ]
+                D[113,217] = (-1)*var(42); // [ var(217) , var(113) ]
+                D[114,217] = var(43); // [ var(217) , var(114) ]
+                D[115,217] = var(50); // [ var(217) , var(115) ]
+                D[116,217] = (-1)*var(56); // [ var(217) , var(116) ]
+                D[117,217] = var(62); // [ var(217) , var(117) ]
+                D[118,217] = (-1)*var(68); // [ var(217) , var(118) ]
+                D[119,217] = var(74); // [ var(217) , var(119) ]
+                D[3,218] = var(214); // [ var(218) , var(3) ]
+                D[8,218] = var(213); // [ var(218) , var(8) ]
+                D[11,218] = (-1)*var(210); // [ var(218) , var(11) ]
+                D[17,218] = (-1)*var(207); // [ var(218) , var(17) ]
+                D[19,218] = var(206); // [ var(218) , var(19) ]
+                D[25,218] = var(203); // [ var(218) , var(25) ]
+                D[27,218] = (-1)*var(201); // [ var(218) , var(27) ]
+                D[32,218] = (-1)*var(198); // [ var(218) , var(32) ]
+                D[33,218] = (-1)*var(197); // [ var(218) , var(33) ]
+                D[40,218] = var(192); // [ var(218) , var(40) ]
+                D[43,218] = var(189); // [ var(218) , var(43) ]
+                D[44,218] = var(188); // [ var(218) , var(44) ]
+                D[48,218] = (-1)*var(185); // [ var(218) , var(48) ]
+                D[50,218] = var(183); // [ var(218) , var(50) ]
+                D[51,218] = (-1)*var(182); // [ var(218) , var(51) ]
+                D[56,218] = (-1)*var(177); // [ var(218) , var(56) ]
+                D[57,218] = var(176); // [ var(218) , var(57) ]
+                D[62,218] = var(171); // [ var(218) , var(62) ]
+                D[63,218] = (-1)*var(170); // [ var(218) , var(63) ]
+                D[65,218] = var(168); // [ var(218) , var(65) ]
+                D[68,218] = (-1)*var(164); // [ var(218) , var(68) ]
+                D[69,218] = (-1)*var(163); // [ var(218) , var(69) ]
+                D[72,218] = (-1)*var(160); // [ var(218) , var(72) ]
+                D[77,218] = var(153); // [ var(218) , var(77) ]
+                D[78,218] = var(152); // [ var(218) , var(78) ]
+                D[81,218] = var(147); // [ var(218) , var(81) ]
+                D[83,218] = (-1)*var(145); // [ var(218) , var(83) ]
+                D[86,218] = (-1)*var(139); // [ var(218) , var(86) ]
+                D[87,218] = var(137); // [ var(218) , var(87) ]
+                D[90,218] = var(131); // [ var(218) , var(90) ]
+                D[93,218] = (-1)*var(128); // [ var(218) , var(93) ]
+                D[94,218] = (-1)*var(123); // [ var(218) , var(94) ]
+                D[98,218] = (-1)*var(241)+(-2)*var(242)+(-3)*var(243)+(-4)*var(244)+(-3)*var(245)+(-2)*var(246)+(-1)*var(247)+(-1)*var(248); // [ var(218) , var(98) ]
+                D[101,218] = (-1)*var(1); // [ var(218) , var(101) ]
+                D[102,218] = (-1)*var(7); // [ var(218) , var(102) ]
+                D[105,218] = var(14); // [ var(218) , var(105) ]
+                D[108,218] = (-1)*var(21); // [ var(218) , var(108) ]
+                D[110,218] = var(28); // [ var(218) , var(110) ]
+                D[112,218] = var(34); // [ var(218) , var(112) ]
+                D[114,218] = (-1)*var(39); // [ var(218) , var(114) ]
+                D[115,218] = (-1)*var(46); // [ var(218) , var(115) ]
+                D[116,218] = var(53); // [ var(218) , var(116) ]
+                D[117,218] = (-1)*var(59); // [ var(218) , var(117) ]
+                D[118,218] = var(66); // [ var(218) , var(118) ]
+                D[120,218] = (-1)*var(79); // [ var(218) , var(120) ]
+                D[4,219] = var(215); // [ var(219) , var(4) ]
+                D[7,219] = var(214); // [ var(219) , var(7) ]
+                D[10,219] = var(212); // [ var(219) , var(10) ]
+                D[12,219] = (-1)*var(211); // [ var(219) , var(12) ]
+                D[15,219] = (-1)*var(209); // [ var(219) , var(15) ]
+                D[18,219] = (-1)*var(208); // [ var(219) , var(18) ]
+                D[28,219] = var(201); // [ var(219) , var(28) ]
+                D[32,219] = var(199); // [ var(219) , var(32) ]
+                D[34,219] = var(197); // [ var(219) , var(34) ]
+                D[36,219] = (-1)*var(195); // [ var(219) , var(36) ]
+                D[37,219] = (-1)*var(194); // [ var(219) , var(37) ]
+                D[42,219] = (-1)*var(190); // [ var(219) , var(42) ]
+                D[49,219] = (-1)*var(187); // [ var(219) , var(49) ]
+                D[53,219] = var(182); // [ var(219) , var(53) ]
+                D[55,219] = var(180); // [ var(219) , var(55) ]
+                D[56,219] = var(179); // [ var(219) , var(56) ]
+                D[59,219] = (-1)*var(176); // [ var(219) , var(59) ]
+                D[60,219] = (-1)*var(175); // [ var(219) , var(60) ]
+                D[62,219] = (-1)*var(173); // [ var(219) , var(62) ]
+                D[67,219] = var(169); // [ var(219) , var(67) ]
+                D[70,219] = var(162); // [ var(219) , var(70) ]
+                D[74,219] = var(157); // [ var(219) , var(74) ]
+                D[75,219] = var(156); // [ var(219) , var(75) ]
+                D[77,219] = (-1)*var(154); // [ var(219) , var(77) ]
+                D[79,219] = (-1)*var(152); // [ var(219) , var(79) ]
+                D[81,219] = (-1)*var(148); // [ var(219) , var(81) ]
+                D[88,219] = var(138); // [ var(219) , var(88) ]
+                D[89,219] = var(135); // [ var(219) , var(89) ]
+                D[91,219] = var(132); // [ var(219) , var(91) ]
+                D[92,219] = (-1)*var(130); // [ var(219) , var(92) ]
+                D[94,219] = (-1)*var(127); // [ var(219) , var(94) ]
+                D[95,219] = (-1)*var(124); // [ var(219) , var(95) ]
+                D[99,219] = (-1)*var(241)+(-2)*var(242)+(-2)*var(243)+(-4)*var(244)+(-3)*var(245)+(-2)*var(246)+(-2)*var(247)+(-1)*var(248); // [ var(219) , var(99) ]
+                D[102,219] = (-1)*var(3); // [ var(219) , var(102) ]
+                D[103,219] = (-1)*var(6); // [ var(219) , var(103) ]
+                D[104,219] = var(9); // [ var(219) , var(104) ]
+                D[106,219] = var(13); // [ var(219) , var(106) ]
+                D[110,219] = (-1)*var(27); // [ var(219) , var(110) ]
+                D[111,219] = var(31); // [ var(219) , var(111) ]
+                D[112,219] = (-1)*var(33); // [ var(219) , var(112) ]
+                D[113,219] = var(38); // [ var(219) , var(113) ]
+                D[116,219] = (-1)*var(51); // [ var(219) , var(116) ]
+                D[117,219] = var(57); // [ var(219) , var(117) ]
+                D[119,219] = (-1)*var(71); // [ var(219) , var(119) ]
+                D[120,219] = var(78); // [ var(219) , var(120) ]
+                D[2,220] = var(216); // [ var(220) , var(2) ]
+                D[6,220] = var(215); // [ var(220) , var(6) ]
+                D[13,220] = var(211); // [ var(220) , var(13) ]
+                D[14,220] = (-1)*var(210); // [ var(220) , var(14) ]
+                D[21,220] = (-1)*var(206); // [ var(220) , var(21) ]
+                D[22,220] = var(205); // [ var(220) , var(22) ]
+                D[26,220] = (-1)*var(204); // [ var(220) , var(26) ]
+                D[29,220] = var(200); // [ var(220) , var(29) ]
+                D[33,220] = var(199); // [ var(220) , var(33) ]
+                D[34,220] = var(198); // [ var(220) , var(34) ]
+                D[38,220] = (-1)*var(194); // [ var(220) , var(38) ]
+                D[41,220] = (-1)*var(193); // [ var(220) , var(41) ]
+                D[42,220] = (-1)*var(191); // [ var(220) , var(42) ]
+                D[46,220] = var(188); // [ var(220) , var(46) ]
+                D[50,220] = var(186); // [ var(220) , var(50) ]
+                D[54,220] = (-1)*var(181); // [ var(220) , var(54) ]
+                D[61,220] = var(174); // [ var(220) , var(61) ]
+                D[66,220] = (-1)*var(170); // [ var(220) , var(66) ]
+                D[68,220] = (-1)*var(166); // [ var(220) , var(68) ]
+                D[71,220] = var(162); // [ var(220) , var(71) ]
+                D[73,220] = var(161); // [ var(220) , var(73) ]
+                D[74,220] = var(158); // [ var(220) , var(74) ]
+                D[78,220] = (-1)*var(154); // [ var(220) , var(78) ]
+                D[79,220] = (-1)*var(153); // [ var(220) , var(79) ]
+                D[80,220] = (-1)*var(149); // [ var(220) , var(80) ]
+                D[84,220] = var(146); // [ var(220) , var(84) ]
+                D[85,220] = (-1)*var(142); // [ var(220) , var(85) ]
+                D[86,220] = var(141); // [ var(220) , var(86) ]
+                D[90,220] = var(134); // [ var(220) , var(90) ]
+                D[91,220] = (-1)*var(133); // [ var(220) , var(91) ]
+                D[95,220] = (-1)*var(126); // [ var(220) , var(95) ]
+                D[96,220] = (-1)*var(122); // [ var(220) , var(96) ]
+                D[100,220] = (-1)*var(241)+(-2)*var(242)+(-2)*var(243)+(-3)*var(244)+(-3)*var(245)+(-3)*var(246)+(-2)*var(247)+(-1)*var(248); // [ var(220) , var(100) ]
+                D[103,220] = (-1)*var(4); // [ var(220) , var(103) ]
+                D[105,220] = var(11); // [ var(220) , var(105) ]
+                D[106,220] = (-1)*var(12); // [ var(220) , var(106) ]
+                D[107,220] = (-1)*var(16); // [ var(220) , var(107) ]
+                D[108,220] = var(19); // [ var(220) , var(108) ]
+                D[109,220] = (-1)*var(24); // [ var(220) , var(109) ]
+                D[112,220] = (-1)*var(32); // [ var(220) , var(112) ]
+                D[113,220] = var(37); // [ var(220) , var(113) ]
+                D[115,220] = (-1)*var(44); // [ var(220) , var(115) ]
+                D[118,220] = var(63); // [ var(220) , var(118) ]
+                D[119,220] = (-1)*var(70); // [ var(220) , var(119) ]
+                D[120,220] = var(77); // [ var(220) , var(120) ]
+                D[1,221] = var(218); // [ var(221) , var(1) ]
+                D[8,221] = var(217); // [ var(221) , var(8) ]
+                D[9,221] = (-1)*var(214); // [ var(221) , var(9) ]
+                D[16,221] = var(210); // [ var(221) , var(16) ]
+                D[23,221] = var(207); // [ var(221) , var(23) ]
+                D[24,221] = (-1)*var(206); // [ var(221) , var(24) ]
+                D[30,221] = (-1)*var(203); // [ var(221) , var(30) ]
+                D[31,221] = var(201); // [ var(221) , var(31) ]
+                D[37,221] = var(198); // [ var(221) , var(37) ]
+                D[38,221] = var(197); // [ var(221) , var(38) ]
+                D[44,221] = (-1)*var(193); // [ var(221) , var(44) ]
+                D[45,221] = (-1)*var(192); // [ var(221) , var(45) ]
+                D[47,221] = (-1)*var(189); // [ var(221) , var(47) ]
+                D[51,221] = var(187); // [ var(221) , var(51) ]
+                D[52,221] = var(185); // [ var(221) , var(52) ]
+                D[54,221] = (-1)*var(183); // [ var(221) , var(54) ]
+                D[57,221] = (-1)*var(180); // [ var(221) , var(57) ]
+                D[60,221] = var(177); // [ var(221) , var(60) ]
+                D[63,221] = var(174); // [ var(221) , var(63) ]
+                D[65,221] = (-1)*var(172); // [ var(221) , var(65) ]
+                D[67,221] = (-1)*var(171); // [ var(221) , var(67) ]
+                D[69,221] = var(167); // [ var(221) , var(69) ]
+                D[72,221] = var(165); // [ var(221) , var(72) ]
+                D[73,221] = var(164); // [ var(221) , var(73) ]
+                D[77,221] = (-1)*var(158); // [ var(221) , var(77) ]
+                D[78,221] = (-1)*var(157); // [ var(221) , var(78) ]
+                D[81,221] = (-1)*var(151); // [ var(221) , var(81) ]
+                D[83,221] = var(150); // [ var(221) , var(83) ]
+                D[86,221] = var(144); // [ var(221) , var(86) ]
+                D[87,221] = (-1)*var(143); // [ var(221) , var(87) ]
+                D[90,221] = (-1)*var(136); // [ var(221) , var(90) ]
+                D[94,221] = var(129); // [ var(221) , var(94) ]
+                D[97,221] = (-1)*var(128); // [ var(221) , var(97) ]
+                D[98,221] = (-1)*var(121); // [ var(221) , var(98) ]
+                D[101,221] = (-2)*var(241)+(-2)*var(242)+(-3)*var(243)+(-4)*var(244)+(-3)*var(245)+(-2)*var(246)+(-1)*var(247)+(-1)*var(248); // [ var(221) , var(101) ]
+                D[104,221] = (-1)*var(7); // [ var(221) , var(104) ]
+                D[107,221] = var(14); // [ var(221) , var(107) ]
+                D[109,221] = (-1)*var(21); // [ var(221) , var(109) ]
+                D[111,221] = var(28); // [ var(221) , var(111) ]
+                D[113,221] = var(34); // [ var(221) , var(113) ]
+                D[114,221] = (-1)*var(35); // [ var(221) , var(114) ]
+                D[115,221] = (-1)*var(41); // [ var(221) , var(115) ]
+                D[116,221] = var(49); // [ var(221) , var(116) ]
+                D[117,221] = (-1)*var(55); // [ var(221) , var(117) ]
+                D[118,221] = var(61); // [ var(221) , var(118) ]
+                D[120,221] = (-1)*var(74); // [ var(221) , var(120) ]
+                D[3,222] = var(219); // [ var(222) , var(3) ]
+                D[7,222] = var(218); // [ var(222) , var(7) ]
+                D[11,222] = (-1)*var(215); // [ var(222) , var(11) ]
+                D[15,222] = (-1)*var(213); // [ var(222) , var(15) ]
+                D[17,222] = (-1)*var(212); // [ var(222) , var(17) ]
+                D[19,222] = var(211); // [ var(222) , var(19) ]
+                D[25,222] = var(208); // [ var(222) , var(25) ]
+                D[32,222] = (-1)*var(204); // [ var(222) , var(32) ]
+                D[35,222] = (-1)*var(201); // [ var(222) , var(35) ]
+                D[41,222] = (-1)*var(197); // [ var(222) , var(41) ]
+                D[43,222] = var(195); // [ var(222) , var(43) ]
+                D[44,222] = var(194); // [ var(222) , var(44) ]
+                D[49,222] = var(192); // [ var(222) , var(49) ]
+                D[50,222] = var(190); // [ var(222) , var(50) ]
+                D[55,222] = (-1)*var(185); // [ var(222) , var(55) ]
+                D[56,222] = (-1)*var(184); // [ var(222) , var(56) ]
+                D[58,222] = (-1)*var(182); // [ var(222) , var(58) ]
+                D[62,222] = var(178); // [ var(222) , var(62) ]
+                D[64,222] = var(176); // [ var(222) , var(64) ]
+                D[65,222] = var(175); // [ var(222) , var(65) ]
+                D[70,222] = (-1)*var(170); // [ var(222) , var(70) ]
+                D[72,222] = (-1)*var(169); // [ var(222) , var(72) ]
+                D[74,222] = (-1)*var(164); // [ var(222) , var(74) ]
+                D[75,222] = (-1)*var(163); // [ var(222) , var(75) ]
+                D[77,222] = var(161); // [ var(222) , var(77) ]
+                D[81,222] = var(155); // [ var(222) , var(81) ]
+                D[84,222] = var(152); // [ var(222) , var(84) ]
+                D[88,222] = (-1)*var(145); // [ var(222) , var(88) ]
+                D[91,222] = (-1)*var(139); // [ var(222) , var(91) ]
+                D[92,222] = var(137); // [ var(222) , var(92) ]
+                D[93,222] = var(135); // [ var(222) , var(93) ]
+                D[95,222] = var(131); // [ var(222) , var(95) ]
+                D[98,222] = (-1)*var(127); // [ var(222) , var(98) ]
+                D[99,222] = (-1)*var(123); // [ var(222) , var(99) ]
+                D[102,222] = (-1)*var(241)+(-2)*var(242)+(-3)*var(243)+(-4)*var(244)+(-3)*var(245)+(-2)*var(246)+(-2)*var(247)+(-1)*var(248); // [ var(222) , var(102) ]
+                D[104,222] = (-1)*var(1); // [ var(222) , var(104) ]
+                D[105,222] = (-1)*var(6); // [ var(222) , var(105) ]
+                D[108,222] = var(13); // [ var(222) , var(108) ]
+                D[110,222] = (-1)*var(20); // [ var(222) , var(110) ]
+                D[112,222] = (-1)*var(26); // [ var(222) , var(112) ]
+                D[114,222] = var(31); // [ var(222) , var(114) ]
+                D[115,222] = var(38); // [ var(222) , var(115) ]
+                D[116,222] = (-1)*var(45); // [ var(222) , var(116) ]
+                D[117,222] = var(52); // [ var(222) , var(117) ]
+                D[119,222] = (-1)*var(66); // [ var(222) , var(119) ]
+                D[120,222] = var(73); // [ var(222) , var(120) ]
+                D[4,223] = var(220); // [ var(223) , var(4) ]
+                D[6,223] = var(219); // [ var(223) , var(6) ]
+                D[10,223] = var(216); // [ var(223) , var(10) ]
+                D[14,223] = (-1)*var(214); // [ var(223) , var(14) ]
+                D[20,223] = (-1)*var(211); // [ var(223) , var(20) ]
+                D[22,223] = var(209); // [ var(223) , var(22) ]
+                D[26,223] = (-1)*var(208); // [ var(223) , var(26) ]
+                D[28,223] = var(206); // [ var(223) , var(28) ]
+                D[34,223] = var(203); // [ var(223) , var(34) ]
+                D[36,223] = (-1)*var(200); // [ var(223) , var(36) ]
+                D[40,223] = var(199); // [ var(223) , var(40) ]
+                D[42,223] = (-1)*var(196); // [ var(223) , var(42) ]
+                D[45,223] = (-1)*var(194); // [ var(223) , var(45) ]
+                D[49,223] = (-1)*var(193); // [ var(223) , var(49) ]
+                D[53,223] = var(188); // [ var(223) , var(53) ]
+                D[56,223] = var(186); // [ var(223) , var(56) ]
+                D[60,223] = (-1)*var(181); // [ var(223) , var(60) ]
+                D[61,223] = var(180); // [ var(223) , var(61) ]
+                D[66,223] = (-1)*var(176); // [ var(223) , var(66) ]
+                D[68,223] = (-1)*var(173); // [ var(223) , var(68) ]
+                D[73,223] = var(169); // [ var(223) , var(73) ]
+                D[74,223] = var(165); // [ var(223) , var(74) ]
+                D[76,223] = var(162); // [ var(223) , var(76) ]
+                D[79,223] = (-1)*var(160); // [ var(223) , var(79) ]
+                D[80,223] = var(156); // [ var(223) , var(80) ]
+                D[83,223] = (-1)*var(154); // [ var(223) , var(83) ]
+                D[86,223] = (-1)*var(148); // [ var(223) , var(86) ]
+                D[88,223] = var(146); // [ var(223) , var(88) ]
+                D[89,223] = (-1)*var(142); // [ var(223) , var(89) ]
+                D[91,223] = var(140); // [ var(223) , var(91) ]
+                D[94,223] = var(134); // [ var(223) , var(94) ]
+                D[96,223] = (-1)*var(130); // [ var(223) , var(96) ]
+                D[99,223] = (-1)*var(126); // [ var(223) , var(99) ]
+                D[100,223] = (-1)*var(124); // [ var(223) , var(100) ]
+                D[103,223] = (-1)*var(241)+(-2)*var(242)+(-2)*var(243)+(-4)*var(244)+(-3)*var(245)+(-3)*var(246)+(-2)*var(247)+(-1)*var(248); // [ var(223) , var(103) ]
+                D[105,223] = (-1)*var(3); // [ var(223) , var(105) ]
+                D[106,223] = (-1)*var(5); // [ var(223) , var(106) ]
+                D[107,223] = var(9); // [ var(223) , var(107) ]
+                D[110,223] = var(19); // [ var(223) , var(110) ]
+                D[111,223] = (-1)*var(24); // [ var(223) , var(111) ]
+                D[112,223] = var(25); // [ var(223) , var(112) ]
+                D[113,223] = (-1)*var(30); // [ var(223) , var(113) ]
+                D[116,223] = var(44); // [ var(223) , var(116) ]
+                D[118,223] = (-1)*var(57); // [ var(223) , var(118) ]
+                D[119,223] = var(64); // [ var(223) , var(119) ]
+                D[120,223] = (-1)*var(72); // [ var(223) , var(120) ]
+                D[1,224] = var(222); // [ var(224) , var(1) ]
+                D[7,224] = var(221); // [ var(224) , var(7) ]
+                D[9,224] = (-1)*var(219); // [ var(224) , var(9) ]
+                D[15,224] = (-1)*var(217); // [ var(224) , var(15) ]
+                D[16,224] = var(215); // [ var(224) , var(16) ]
+                D[23,224] = var(212); // [ var(224) , var(23) ]
+                D[24,224] = (-1)*var(211); // [ var(224) , var(24) ]
+                D[30,224] = (-1)*var(208); // [ var(224) , var(30) ]
+                D[37,224] = var(204); // [ var(224) , var(37) ]
+                D[39,224] = var(201); // [ var(224) , var(39) ]
+                D[44,224] = (-1)*var(199); // [ var(224) , var(44) ]
+                D[46,224] = var(197); // [ var(224) , var(46) ]
+                D[47,224] = (-1)*var(195); // [ var(224) , var(47) ]
+                D[53,224] = (-1)*var(192); // [ var(224) , var(53) ]
+                D[54,224] = (-1)*var(190); // [ var(224) , var(54) ]
+                D[58,224] = var(187); // [ var(224) , var(58) ]
+                D[59,224] = var(185); // [ var(224) , var(59) ]
+                D[60,224] = var(184); // [ var(224) , var(60) ]
+                D[64,224] = (-1)*var(180); // [ var(224) , var(64) ]
+                D[65,224] = (-1)*var(179); // [ var(224) , var(65) ]
+                D[67,224] = (-1)*var(178); // [ var(224) , var(67) ]
+                D[70,224] = var(174); // [ var(224) , var(70) ]
+                D[72,224] = var(173); // [ var(224) , var(72) ]
+                D[75,224] = var(167); // [ var(224) , var(75) ]
+                D[77,224] = (-1)*var(166); // [ var(224) , var(77) ]
+                D[79,224] = var(164); // [ var(224) , var(79) ]
+                D[81,224] = (-1)*var(159); // [ var(224) , var(81) ]
+                D[84,224] = (-1)*var(157); // [ var(224) , var(84) ]
+                D[88,224] = var(150); // [ var(224) , var(88) ]
+                D[91,224] = var(144); // [ var(224) , var(91) ]
+                D[92,224] = (-1)*var(143); // [ var(224) , var(92) ]
+                D[95,224] = (-1)*var(136); // [ var(224) , var(95) ]
+                D[97,224] = var(135); // [ var(224) , var(97) ]
+                D[99,224] = var(129); // [ var(224) , var(99) ]
+                D[101,224] = (-1)*var(127); // [ var(224) , var(101) ]
+                D[102,224] = (-1)*var(121); // [ var(224) , var(102) ]
+                D[104,224] = (-2)*var(241)+(-2)*var(242)+(-3)*var(243)+(-4)*var(244)+(-3)*var(245)+(-2)*var(246)+(-2)*var(247)+(-1)*var(248); // [ var(224) , var(104) ]
+                D[107,224] = (-1)*var(6); // [ var(224) , var(107) ]
+                D[109,224] = var(13); // [ var(224) , var(109) ]
+                D[111,224] = (-1)*var(20); // [ var(224) , var(111) ]
+                D[113,224] = (-1)*var(26); // [ var(224) , var(113) ]
+                D[114,224] = var(27); // [ var(224) , var(114) ]
+                D[115,224] = var(33); // [ var(224) , var(115) ]
+                D[116,224] = (-1)*var(40); // [ var(224) , var(116) ]
+                D[117,224] = var(48); // [ var(224) , var(117) ]
+                D[119,224] = (-1)*var(61); // [ var(224) , var(119) ]
+                D[120,224] = var(68); // [ var(224) , var(120) ]
+                D[3,225] = var(223); // [ var(225) , var(3) ]
+                D[6,225] = var(222); // [ var(225) , var(6) ]
+                D[11,225] = (-1)*var(220); // [ var(225) , var(11) ]
+                D[14,225] = (-1)*var(218); // [ var(225) , var(14) ]
+                D[17,225] = (-1)*var(216); // [ var(225) , var(17) ]
+                D[22,225] = var(213); // [ var(225) , var(22) ]
+                D[27,225] = var(211); // [ var(225) , var(27) ]
+                D[33,225] = var(208); // [ var(225) , var(33) ]
+                D[35,225] = (-1)*var(206); // [ var(225) , var(35) ]
+                D[40,225] = (-1)*var(204); // [ var(225) , var(40) ]
+                D[41,225] = (-1)*var(203); // [ var(225) , var(41) ]
+                D[43,225] = var(200); // [ var(225) , var(43) ]
+                D[49,225] = var(198); // [ var(225) , var(49) ]
+                D[50,225] = var(196); // [ var(225) , var(50) ]
+                D[51,225] = var(194); // [ var(225) , var(51) ]
+                D[56,225] = (-1)*var(191); // [ var(225) , var(56) ]
+                D[58,225] = (-1)*var(188); // [ var(225) , var(58) ]
+                D[61,225] = (-1)*var(185); // [ var(225) , var(61) ]
+                D[65,225] = var(181); // [ var(225) , var(65) ]
+                D[68,225] = var(178); // [ var(225) , var(68) ]
+                D[71,225] = var(176); // [ var(225) , var(71) ]
+                D[74,225] = (-1)*var(171); // [ var(225) , var(74) ]
+                D[76,225] = (-1)*var(170); // [ var(225) , var(76) ]
+                D[78,225] = (-1)*var(169); // [ var(225) , var(78) ]
+                D[80,225] = (-1)*var(163); // [ var(225) , var(80) ]
+                D[83,225] = var(161); // [ var(225) , var(83) ]
+                D[84,225] = var(160); // [ var(225) , var(84) ]
+                D[86,225] = var(155); // [ var(225) , var(86) ]
+                D[88,225] = (-1)*var(153); // [ var(225) , var(88) ]
+                D[91,225] = (-1)*var(147); // [ var(225) , var(91) ]
+                D[93,225] = (-1)*var(142); // [ var(225) , var(93) ]
+                D[96,225] = var(137); // [ var(225) , var(96) ]
+                D[98,225] = var(134); // [ var(225) , var(98) ]
+                D[100,225] = var(131); // [ var(225) , var(100) ]
+                D[102,225] = (-1)*var(126); // [ var(225) , var(102) ]
+                D[103,225] = (-1)*var(123); // [ var(225) , var(103) ]
+                D[105,225] = (-1)*var(241)+(-2)*var(242)+(-3)*var(243)+(-4)*var(244)+(-3)*var(245)+(-3)*var(246)+(-2)*var(247)+(-1)*var(248); // [ var(225) , var(105) ]
+                D[107,225] = (-1)*var(1); // [ var(225) , var(107) ]
+                D[108,225] = (-1)*var(5); // [ var(225) , var(108) ]
+                D[110,225] = var(12); // [ var(225) , var(110) ]
+                D[112,225] = var(18); // [ var(225) , var(112) ]
+                D[114,225] = (-1)*var(24); // [ var(225) , var(114) ]
+                D[115,225] = (-1)*var(30); // [ var(225) , var(115) ]
+                D[116,225] = var(37); // [ var(225) , var(116) ]
+                D[118,225] = (-1)*var(52); // [ var(225) , var(118) ]
+                D[119,225] = var(59); // [ var(225) , var(119) ]
+                D[120,225] = (-1)*var(67); // [ var(225) , var(120) ]
+                D[5,226] = var(223); // [ var(226) , var(5) ]
+                D[12,226] = var(220); // [ var(226) , var(12) ]
+                D[13,226] = (-1)*var(219); // [ var(226) , var(13) ]
+                D[18,226] = var(216); // [ var(226) , var(18) ]
+                D[20,226] = (-1)*var(215); // [ var(226) , var(20) ]
+                D[21,226] = var(214); // [ var(226) , var(21) ]
+                D[26,226] = (-1)*var(212); // [ var(226) , var(26) ]
+                D[28,226] = var(210); // [ var(226) , var(28) ]
+                D[29,226] = (-1)*var(209); // [ var(226) , var(29) ]
+                D[34,226] = var(207); // [ var(226) , var(34) ]
+                D[36,226] = (-1)*var(205); // [ var(226) , var(36) ]
+                D[42,226] = (-1)*var(202); // [ var(226) , var(42) ]
+                D[48,226] = var(199); // [ var(226) , var(48) ]
+                D[52,226] = (-1)*var(194); // [ var(226) , var(52) ]
+                D[55,226] = (-1)*var(193); // [ var(226) , var(55) ]
+                D[59,226] = var(188); // [ var(226) , var(59) ]
+                D[61,226] = var(187); // [ var(226) , var(61) ]
+                D[62,226] = var(186); // [ var(226) , var(62) ]
+                D[66,226] = (-1)*var(182); // [ var(226) , var(66) ]
+                D[67,226] = (-1)*var(181); // [ var(226) , var(67) ]
+                D[68,226] = (-1)*var(179); // [ var(226) , var(68) ]
+                D[73,226] = var(175); // [ var(226) , var(73) ]
+                D[74,226] = var(172); // [ var(226) , var(74) ]
+                D[79,226] = (-1)*var(168); // [ var(226) , var(79) ]
+                D[82,226] = var(162); // [ var(226) , var(82) ]
+                D[85,226] = var(156); // [ var(226) , var(85) ]
+                D[87,226] = (-1)*var(154); // [ var(226) , var(87) ]
+                D[89,226] = var(149); // [ var(226) , var(89) ]
+                D[90,226] = (-1)*var(148); // [ var(226) , var(90) ]
+                D[92,226] = var(146); // [ var(226) , var(92) ]
+                D[94,226] = (-1)*var(141); // [ var(226) , var(94) ]
+                D[95,226] = var(140); // [ var(226) , var(95) ]
+                D[96,226] = (-1)*var(138); // [ var(226) , var(96) ]
+                D[99,226] = var(133); // [ var(226) , var(99) ]
+                D[100,226] = (-1)*var(132); // [ var(226) , var(100) ]
+                D[103,226] = (-1)*var(125); // [ var(226) , var(103) ]
+                D[106,226] = (-1)*var(241)+(-2)*var(242)+(-2)*var(243)+(-4)*var(244)+(-4)*var(245)+(-3)*var(246)+(-2)*var(247)+(-1)*var(248); // [ var(226) , var(106) ]
+                D[108,226] = (-1)*var(3); // [ var(226) , var(108) ]
+                D[109,226] = var(9); // [ var(226) , var(109) ]
+                D[110,226] = (-1)*var(11); // [ var(226) , var(110) ]
+                D[111,226] = var(16); // [ var(226) , var(111) ]
+                D[112,226] = (-1)*var(17); // [ var(226) , var(112) ]
+                D[113,226] = var(23); // [ var(226) , var(113) ]
+                D[117,226] = (-1)*var(44); // [ var(226) , var(117) ]
+                D[118,226] = var(51); // [ var(226) , var(118) ]
+                D[119,226] = (-1)*var(58); // [ var(226) , var(119) ]
+                D[120,226] = var(65); // [ var(226) , var(120) ]
+                D[1,227] = var(225); // [ var(227) , var(1) ]
+                D[6,227] = var(224); // [ var(227) , var(6) ]
+                D[9,227] = (-1)*var(223); // [ var(227) , var(9) ]
+                D[14,227] = (-1)*var(221); // [ var(227) , var(14) ]
+                D[16,227] = var(220); // [ var(227) , var(16) ]
+                D[22,227] = var(217); // [ var(227) , var(22) ]
+                D[23,227] = var(216); // [ var(227) , var(23) ]
+                D[31,227] = (-1)*var(211); // [ var(227) , var(31) ]
+                D[38,227] = (-1)*var(208); // [ var(227) , var(38) ]
+                D[39,227] = var(206); // [ var(227) , var(39) ]
+                D[45,227] = var(204); // [ var(227) , var(45) ]
+                D[46,227] = var(203); // [ var(227) , var(46) ]
+                D[47,227] = (-1)*var(200); // [ var(227) , var(47) ]
+                D[51,227] = (-1)*var(199); // [ var(227) , var(51) ]
+                D[53,227] = (-1)*var(198); // [ var(227) , var(53) ]
+                D[54,227] = (-1)*var(196); // [ var(227) , var(54) ]
+                D[58,227] = var(193); // [ var(227) , var(58) ]
+                D[60,227] = var(191); // [ var(227) , var(60) ]
+                D[65,227] = (-1)*var(186); // [ var(227) , var(65) ]
+                D[66,227] = var(185); // [ var(227) , var(66) ]
+                D[71,227] = (-1)*var(180); // [ var(227) , var(71) ]
+                D[73,227] = (-1)*var(178); // [ var(227) , var(73) ]
+                D[76,227] = var(174); // [ var(227) , var(76) ]
+                D[78,227] = var(173); // [ var(227) , var(78) ]
+                D[79,227] = var(171); // [ var(227) , var(79) ]
+                D[80,227] = var(167); // [ var(227) , var(80) ]
+                D[83,227] = (-1)*var(166); // [ var(227) , var(83) ]
+                D[84,227] = (-1)*var(165); // [ var(227) , var(84) ]
+                D[86,227] = (-1)*var(159); // [ var(227) , var(86) ]
+                D[88,227] = var(158); // [ var(227) , var(88) ]
+                D[91,227] = var(151); // [ var(227) , var(91) ]
+                D[96,227] = (-1)*var(143); // [ var(227) , var(96) ]
+                D[97,227] = (-1)*var(142); // [ var(227) , var(97) ]
+                D[100,227] = (-1)*var(136); // [ var(227) , var(100) ]
+                D[101,227] = var(134); // [ var(227) , var(101) ]
+                D[103,227] = var(129); // [ var(227) , var(103) ]
+                D[104,227] = (-1)*var(126); // [ var(227) , var(104) ]
+                D[105,227] = (-1)*var(121); // [ var(227) , var(105) ]
+                D[107,227] = (-2)*var(241)+(-2)*var(242)+(-3)*var(243)+(-4)*var(244)+(-3)*var(245)+(-3)*var(246)+(-2)*var(247)+(-1)*var(248); // [ var(227) , var(107) ]
+                D[109,227] = (-1)*var(5); // [ var(227) , var(109) ]
+                D[111,227] = var(12); // [ var(227) , var(111) ]
+                D[113,227] = var(18); // [ var(227) , var(113) ]
+                D[114,227] = (-1)*var(19); // [ var(227) , var(114) ]
+                D[115,227] = (-1)*var(25); // [ var(227) , var(115) ]
+                D[116,227] = var(32); // [ var(227) , var(116) ]
+                D[118,227] = (-1)*var(48); // [ var(227) , var(118) ]
+                D[119,227] = var(55); // [ var(227) , var(119) ]
+                D[120,227] = (-1)*var(62); // [ var(227) , var(120) ]
+                D[3,228] = var(226); // [ var(228) , var(3) ]
+                D[5,228] = var(225); // [ var(228) , var(5) ]
+                D[13,228] = (-1)*var(222); // [ var(228) , var(13) ]
+                D[19,228] = (-1)*var(220); // [ var(228) , var(19) ]
+                D[21,228] = var(218); // [ var(228) , var(21) ]
+                D[25,228] = (-1)*var(216); // [ var(228) , var(25) ]
+                D[27,228] = var(215); // [ var(228) , var(27) ]
+                D[29,228] = (-1)*var(213); // [ var(228) , var(29) ]
+                D[33,228] = var(212); // [ var(228) , var(33) ]
+                D[35,228] = (-1)*var(210); // [ var(228) , var(35) ]
+                D[41,228] = (-1)*var(207); // [ var(228) , var(41) ]
+                D[43,228] = var(205); // [ var(228) , var(43) ]
+                D[48,228] = (-1)*var(204); // [ var(228) , var(48) ]
+                D[50,228] = var(202); // [ var(228) , var(50) ]
+                D[55,228] = var(198); // [ var(228) , var(55) ]
+                D[57,228] = var(194); // [ var(228) , var(57) ]
+                D[61,228] = (-1)*var(192); // [ var(228) , var(61) ]
+                D[62,228] = (-1)*var(191); // [ var(228) , var(62) ]
+                D[64,228] = (-1)*var(188); // [ var(228) , var(64) ]
+                D[68,228] = var(184); // [ var(228) , var(68) ]
+                D[71,228] = var(182); // [ var(228) , var(71) ]
+                D[72,228] = var(181); // [ var(228) , var(72) ]
+                D[74,228] = (-1)*var(177); // [ var(228) , var(74) ]
+                D[78,228] = (-1)*var(175); // [ var(228) , var(78) ]
+                D[82,228] = (-1)*var(170); // [ var(228) , var(82) ]
+                D[84,228] = var(168); // [ var(228) , var(84) ]
+                D[85,228] = (-1)*var(163); // [ var(228) , var(85) ]
+                D[87,228] = var(161); // [ var(228) , var(87) ]
+                D[90,228] = var(155); // [ var(228) , var(90) ]
+                D[92,228] = (-1)*var(153); // [ var(228) , var(92) ]
+                D[93,228] = var(149); // [ var(228) , var(93) ]
+                D[95,228] = (-1)*var(147); // [ var(228) , var(95) ]
+                D[96,228] = var(145); // [ var(228) , var(96) ]
+                D[98,228] = (-1)*var(141); // [ var(228) , var(98) ]
+                D[100,228] = var(139); // [ var(228) , var(100) ]
+                D[102,228] = var(133); // [ var(228) , var(102) ]
+                D[105,228] = (-1)*var(125); // [ var(228) , var(105) ]
+                D[106,228] = (-1)*var(123); // [ var(228) , var(106) ]
+                D[108,228] = (-1)*var(241)+(-2)*var(242)+(-3)*var(243)+(-4)*var(244)+(-4)*var(245)+(-3)*var(246)+(-2)*var(247)+(-1)*var(248); // [ var(228) , var(108) ]
+                D[109,228] = (-1)*var(1); // [ var(228) , var(109) ]
+                D[110,228] = (-1)*var(4); // [ var(228) , var(110) ]
+                D[112,228] = (-1)*var(10); // [ var(228) , var(112) ]
+                D[114,228] = var(16); // [ var(228) , var(114) ]
+                D[115,228] = var(23); // [ var(228) , var(115) ]
+                D[117,228] = (-1)*var(37); // [ var(228) , var(117) ]
+                D[118,228] = var(45); // [ var(228) , var(118) ]
+                D[119,228] = (-1)*var(53); // [ var(228) , var(119) ]
+                D[120,228] = var(60); // [ var(228) , var(120) ]
+                D[1,229] = var(228); // [ var(229) , var(1) ]
+                D[5,229] = var(227); // [ var(229) , var(5) ]
+                D[9,229] = (-1)*var(226); // [ var(229) , var(9) ]
+                D[13,229] = (-1)*var(224); // [ var(229) , var(13) ]
+                D[21,229] = var(221); // [ var(229) , var(21) ]
+                D[24,229] = var(220); // [ var(229) , var(24) ]
+                D[29,229] = (-1)*var(217); // [ var(229) , var(29) ]
+                D[30,229] = var(216); // [ var(229) , var(30) ]
+                D[31,229] = (-1)*var(215); // [ var(229) , var(31) ]
+                D[38,229] = (-1)*var(212); // [ var(229) , var(38) ]
+                D[39,229] = var(210); // [ var(229) , var(39) ]
+                D[46,229] = var(207); // [ var(229) , var(46) ]
+                D[47,229] = (-1)*var(205); // [ var(229) , var(47) ]
+                D[52,229] = var(204); // [ var(229) , var(52) ]
+                D[54,229] = (-1)*var(202); // [ var(229) , var(54) ]
+                D[57,229] = (-1)*var(199); // [ var(229) , var(57) ]
+                D[59,229] = (-1)*var(198); // [ var(229) , var(59) ]
+                D[64,229] = var(193); // [ var(229) , var(64) ]
+                D[66,229] = var(192); // [ var(229) , var(66) ]
+                D[67,229] = var(191); // [ var(229) , var(67) ]
+                D[71,229] = (-1)*var(187); // [ var(229) , var(71) ]
+                D[72,229] = (-1)*var(186); // [ var(229) , var(72) ]
+                D[73,229] = (-1)*var(184); // [ var(229) , var(73) ]
+                D[78,229] = var(179); // [ var(229) , var(78) ]
+                D[79,229] = var(177); // [ var(229) , var(79) ]
+                D[82,229] = var(174); // [ var(229) , var(82) ]
+                D[84,229] = (-1)*var(172); // [ var(229) , var(84) ]
+                D[85,229] = var(167); // [ var(229) , var(85) ]
+                D[87,229] = (-1)*var(166); // [ var(229) , var(87) ]
+                D[90,229] = (-1)*var(159); // [ var(229) , var(90) ]
+                D[92,229] = var(158); // [ var(229) , var(92) ]
+                D[95,229] = var(151); // [ var(229) , var(95) ]
+                D[96,229] = (-1)*var(150); // [ var(229) , var(96) ]
+                D[97,229] = var(149); // [ var(229) , var(97) ]
+                D[100,229] = (-1)*var(144); // [ var(229) , var(100) ]
+                D[101,229] = (-1)*var(141); // [ var(229) , var(101) ]
+                D[104,229] = var(133); // [ var(229) , var(104) ]
+                D[106,229] = var(129); // [ var(229) , var(106) ]
+                D[107,229] = (-1)*var(125); // [ var(229) , var(107) ]
+                D[108,229] = (-1)*var(121); // [ var(229) , var(108) ]
+                D[109,229] = (-2)*var(241)+(-2)*var(242)+(-3)*var(243)+(-4)*var(244)+(-4)*var(245)+(-3)*var(246)+(-2)*var(247)+(-1)*var(248); // [ var(229) , var(109) ]
+                D[111,229] = (-1)*var(4); // [ var(229) , var(111) ]
+                D[113,229] = (-1)*var(10); // [ var(229) , var(113) ]
+                D[114,229] = var(11); // [ var(229) , var(114) ]
+                D[115,229] = var(17); // [ var(229) , var(115) ]
+                D[117,229] = (-1)*var(32); // [ var(229) , var(117) ]
+                D[118,229] = var(40); // [ var(229) , var(118) ]
+                D[119,229] = (-1)*var(49); // [ var(229) , var(119) ]
+                D[120,229] = var(56); // [ var(229) , var(120) ]
+                D[4,230] = var(228); // [ var(230) , var(4) ]
+                D[11,230] = var(226); // [ var(230) , var(11) ]
+                D[12,230] = (-1)*var(225); // [ var(230) , var(12) ]
+                D[19,230] = (-1)*var(223); // [ var(230) , var(19) ]
+                D[20,230] = var(222); // [ var(230) , var(20) ]
+                D[27,230] = var(219); // [ var(230) , var(27) ]
+                D[28,230] = (-1)*var(218); // [ var(230) , var(28) ]
+                D[32,230] = (-1)*var(216); // [ var(230) , var(32) ]
+                D[35,230] = (-1)*var(214); // [ var(230) , var(35) ]
+                D[36,230] = var(213); // [ var(230) , var(36) ]
+                D[40,230] = var(212); // [ var(230) , var(40) ]
+                D[43,230] = var(209); // [ var(230) , var(43) ]
+                D[48,230] = (-1)*var(208); // [ var(230) , var(48) ]
+                D[49,230] = (-1)*var(207); // [ var(230) , var(49) ]
+                D[55,230] = var(203); // [ var(230) , var(55) ]
+                D[56,230] = var(202); // [ var(230) , var(56) ]
+                D[61,230] = (-1)*var(197); // [ var(230) , var(61) ]
+                D[62,230] = (-1)*var(196); // [ var(230) , var(62) ]
+                D[63,230] = var(194); // [ var(230) , var(63) ]
+                D[68,230] = var(190); // [ var(230) , var(68) ]
+                D[70,230] = (-1)*var(188); // [ var(230) , var(70) ]
+                D[74,230] = (-1)*var(183); // [ var(230) , var(74) ]
+                D[76,230] = var(182); // [ var(230) , var(76) ]
+                D[77,230] = var(181); // [ var(230) , var(77) ]
+                D[82,230] = (-1)*var(176); // [ var(230) , var(82) ]
+                D[83,230] = (-1)*var(175); // [ var(230) , var(83) ]
+                D[87,230] = var(169); // [ var(230) , var(87) ]
+                D[88,230] = var(168); // [ var(230) , var(88) ]
+                D[89,230] = (-1)*var(163); // [ var(230) , var(89) ]
+                D[92,230] = (-1)*var(160); // [ var(230) , var(92) ]
+                D[93,230] = (-1)*var(156); // [ var(230) , var(93) ]
+                D[94,230] = var(155); // [ var(230) , var(94) ]
+                D[96,230] = var(152); // [ var(230) , var(96) ]
+                D[98,230] = var(148); // [ var(230) , var(98) ]
+                D[99,230] = (-1)*var(147); // [ var(230) , var(99) ]
+                D[102,230] = (-1)*var(140); // [ var(230) , var(102) ]
+                D[103,230] = var(139); // [ var(230) , var(103) ]
+                D[105,230] = var(132); // [ var(230) , var(105) ]
+                D[106,230] = (-1)*var(131); // [ var(230) , var(106) ]
+                D[108,230] = (-1)*var(124); // [ var(230) , var(108) ]
+                D[110,230] = (-1)*var(241)+(-2)*var(242)+(-3)*var(243)+(-5)*var(244)+(-4)*var(245)+(-3)*var(246)+(-2)*var(247)+(-1)*var(248); // [ var(230) , var(110) ]
+                D[111,230] = (-1)*var(1); // [ var(230) , var(111) ]
+                D[112,230] = var(2); // [ var(230) , var(112) ]
+                D[114,230] = (-1)*var(9); // [ var(230) , var(114) ]
+                D[116,230] = (-1)*var(23); // [ var(230) , var(116) ]
+                D[117,230] = var(30); // [ var(230) , var(117) ]
+                D[118,230] = (-1)*var(38); // [ var(230) , var(118) ]
+                D[119,230] = var(46); // [ var(230) , var(119) ]
+                D[120,230] = (-1)*var(54); // [ var(230) , var(120) ]
+                D[1,231] = var(230); // [ var(231) , var(1) ]
+                D[4,231] = var(229); // [ var(231) , var(4) ]
+                D[12,231] = (-1)*var(227); // [ var(231) , var(12) ]
+                D[16,231] = (-1)*var(226); // [ var(231) , var(16) ]
+                D[20,231] = var(224); // [ var(231) , var(20) ]
+                D[24,231] = var(223); // [ var(231) , var(24) ]
+                D[28,231] = (-1)*var(221); // [ var(231) , var(28) ]
+                D[31,231] = (-1)*var(219); // [ var(231) , var(31) ]
+                D[36,231] = var(217); // [ var(231) , var(36) ]
+                D[37,231] = var(216); // [ var(231) , var(37) ]
+                D[39,231] = var(214); // [ var(231) , var(39) ]
+                D[45,231] = (-1)*var(212); // [ var(231) , var(45) ]
+                D[47,231] = (-1)*var(209); // [ var(231) , var(47) ]
+                D[52,231] = var(208); // [ var(231) , var(52) ]
+                D[53,231] = var(207); // [ var(231) , var(53) ]
+                D[59,231] = (-1)*var(203); // [ var(231) , var(59) ]
+                D[60,231] = (-1)*var(202); // [ var(231) , var(60) ]
+                D[63,231] = (-1)*var(199); // [ var(231) , var(63) ]
+                D[66,231] = var(197); // [ var(231) , var(66) ]
+                D[67,231] = var(196); // [ var(231) , var(67) ]
+                D[70,231] = var(193); // [ var(231) , var(70) ]
+                D[73,231] = (-1)*var(190); // [ var(231) , var(73) ]
+                D[76,231] = (-1)*var(187); // [ var(231) , var(76) ]
+                D[77,231] = (-1)*var(186); // [ var(231) , var(77) ]
+                D[79,231] = var(183); // [ var(231) , var(79) ]
+                D[82,231] = var(180); // [ var(231) , var(82) ]
+                D[83,231] = var(179); // [ var(231) , var(83) ]
+                D[87,231] = (-1)*var(173); // [ var(231) , var(87) ]
+                D[88,231] = (-1)*var(172); // [ var(231) , var(88) ]
+                D[89,231] = var(167); // [ var(231) , var(89) ]
+                D[92,231] = var(165); // [ var(231) , var(92) ]
+                D[94,231] = (-1)*var(159); // [ var(231) , var(94) ]
+                D[96,231] = (-1)*var(157); // [ var(231) , var(96) ]
+                D[97,231] = (-1)*var(156); // [ var(231) , var(97) ]
+                D[99,231] = var(151); // [ var(231) , var(99) ]
+                D[101,231] = var(148); // [ var(231) , var(101) ]
+                D[103,231] = (-1)*var(144); // [ var(231) , var(103) ]
+                D[104,231] = (-1)*var(140); // [ var(231) , var(104) ]
+                D[106,231] = var(136); // [ var(231) , var(106) ]
+                D[107,231] = var(132); // [ var(231) , var(107) ]
+                D[109,231] = (-1)*var(124); // [ var(231) , var(109) ]
+                D[110,231] = (-1)*var(121); // [ var(231) , var(110) ]
+                D[111,231] = (-2)*var(241)+(-2)*var(242)+(-3)*var(243)+(-5)*var(244)+(-4)*var(245)+(-3)*var(246)+(-2)*var(247)+(-1)*var(248); // [ var(231) , var(111) ]
+                D[113,231] = var(2); // [ var(231) , var(113) ]
+                D[114,231] = (-1)*var(3); // [ var(231) , var(114) ]
+                D[116,231] = (-1)*var(17); // [ var(231) , var(116) ]
+                D[117,231] = var(25); // [ var(231) , var(117) ]
+                D[118,231] = (-1)*var(33); // [ var(231) , var(118) ]
+                D[119,231] = var(41); // [ var(231) , var(119) ]
+                D[120,231] = (-1)*var(50); // [ var(231) , var(120) ]
+                D[2,232] = (-1)*var(230); // [ var(232) , var(2) ]
+                D[10,232] = var(228); // [ var(232) , var(10) ]
+                D[17,232] = var(226); // [ var(232) , var(17) ]
+                D[18,232] = (-1)*var(225); // [ var(232) , var(18) ]
+                D[25,232] = (-1)*var(223); // [ var(232) , var(25) ]
+                D[26,232] = var(222); // [ var(232) , var(26) ]
+                D[32,232] = var(220); // [ var(232) , var(32) ]
+                D[33,232] = var(219); // [ var(232) , var(33) ]
+                D[34,232] = (-1)*var(218); // [ var(232) , var(34) ]
+                D[40,232] = (-1)*var(215); // [ var(232) , var(40) ]
+                D[41,232] = (-1)*var(214); // [ var(232) , var(41) ]
+                D[42,232] = var(213); // [ var(232) , var(42) ]
+                D[48,232] = var(211); // [ var(232) , var(48) ]
+                D[49,232] = var(210); // [ var(232) , var(49) ]
+                D[50,232] = var(209); // [ var(232) , var(50) ]
+                D[55,232] = (-1)*var(206); // [ var(232) , var(55) ]
+                D[56,232] = (-1)*var(205); // [ var(232) , var(56) ]
+                D[61,232] = var(201); // [ var(232) , var(61) ]
+                D[62,232] = var(200); // [ var(232) , var(62) ]
+                D[68,232] = (-1)*var(195); // [ var(232) , var(68) ]
+                D[69,232] = (-1)*var(194); // [ var(232) , var(69) ]
+                D[74,232] = var(189); // [ var(232) , var(74) ]
+                D[75,232] = var(188); // [ var(232) , var(75) ]
+                D[80,232] = (-1)*var(182); // [ var(232) , var(80) ]
+                D[81,232] = (-1)*var(181); // [ var(232) , var(81) ]
+                D[85,232] = var(176); // [ var(232) , var(85) ]
+                D[86,232] = var(175); // [ var(232) , var(86) ]
+                D[89,232] = (-1)*var(170); // [ var(232) , var(89) ]
+                D[90,232] = (-1)*var(169); // [ var(232) , var(90) ]
+                D[91,232] = (-1)*var(168); // [ var(232) , var(91) ]
+                D[93,232] = (-1)*var(162); // [ var(232) , var(93) ]
+                D[94,232] = var(161); // [ var(232) , var(94) ]
+                D[95,232] = var(160); // [ var(232) , var(95) ]
+                D[98,232] = var(154); // [ var(232) , var(98) ]
+                D[99,232] = (-1)*var(153); // [ var(232) , var(99) ]
+                D[100,232] = (-1)*var(152); // [ var(232) , var(100) ]
+                D[102,232] = (-1)*var(146); // [ var(232) , var(102) ]
+                D[103,232] = var(145); // [ var(232) , var(103) ]
+                D[105,232] = var(138); // [ var(232) , var(105) ]
+                D[106,232] = (-1)*var(137); // [ var(232) , var(106) ]
+                D[108,232] = (-1)*var(130); // [ var(232) , var(108) ]
+                D[110,232] = var(122); // [ var(232) , var(110) ]
+                D[112,232] = (-1)*var(241)+(-3)*var(242)+(-3)*var(243)+(-5)*var(244)+(-4)*var(245)+(-3)*var(246)+(-2)*var(247)+(-1)*var(248); // [ var(232) , var(112) ]
+                D[113,232] = (-1)*var(1); // [ var(232) , var(113) ]
+                D[115,232] = (-1)*var(9); // [ var(232) , var(115) ]
+                D[116,232] = var(16); // [ var(232) , var(116) ]
+                D[117,232] = (-1)*var(24); // [ var(232) , var(117) ]
+                D[118,232] = var(31); // [ var(232) , var(118) ]
+                D[119,232] = (-1)*var(39); // [ var(232) , var(119) ]
+                D[120,232] = var(47); // [ var(232) , var(120) ]
+                D[1,233] = var(232); // [ var(233) , var(1) ]
+                D[2,233] = (-1)*var(231); // [ var(233) , var(2) ]
+                D[10,233] = var(229); // [ var(233) , var(10) ]
+                D[18,233] = (-1)*var(227); // [ var(233) , var(18) ]
+                D[23,233] = (-1)*var(226); // [ var(233) , var(23) ]
+                D[26,233] = var(224); // [ var(233) , var(26) ]
+                D[30,233] = var(223); // [ var(233) , var(30) ]
+                D[34,233] = (-1)*var(221); // [ var(233) , var(34) ]
+                D[37,233] = (-1)*var(220); // [ var(233) , var(37) ]
+                D[38,233] = (-1)*var(219); // [ var(233) , var(38) ]
+                D[42,233] = var(217); // [ var(233) , var(42) ]
+                D[45,233] = var(215); // [ var(233) , var(45) ]
+                D[46,233] = var(214); // [ var(233) , var(46) ]
+                D[52,233] = (-1)*var(211); // [ var(233) , var(52) ]
+                D[53,233] = (-1)*var(210); // [ var(233) , var(53) ]
+                D[54,233] = (-1)*var(209); // [ var(233) , var(54) ]
+                D[59,233] = var(206); // [ var(233) , var(59) ]
+                D[60,233] = var(205); // [ var(233) , var(60) ]
+                D[66,233] = (-1)*var(201); // [ var(233) , var(66) ]
+                D[67,233] = (-1)*var(200); // [ var(233) , var(67) ]
+                D[69,233] = var(199); // [ var(233) , var(69) ]
+                D[73,233] = var(195); // [ var(233) , var(73) ]
+                D[75,233] = (-1)*var(193); // [ var(233) , var(75) ]
+                D[79,233] = (-1)*var(189); // [ var(233) , var(79) ]
+                D[80,233] = var(187); // [ var(233) , var(80) ]
+                D[81,233] = var(186); // [ var(233) , var(81) ]
+                D[85,233] = (-1)*var(180); // [ var(233) , var(85) ]
+                D[86,233] = (-1)*var(179); // [ var(233) , var(86) ]
+                D[89,233] = var(174); // [ var(233) , var(89) ]
+                D[90,233] = var(173); // [ var(233) , var(90) ]
+                D[91,233] = var(172); // [ var(233) , var(91) ]
+                D[94,233] = (-1)*var(166); // [ var(233) , var(94) ]
+                D[95,233] = (-1)*var(165); // [ var(233) , var(95) ]
+                D[97,233] = (-1)*var(162); // [ var(233) , var(97) ]
+                D[99,233] = var(158); // [ var(233) , var(99) ]
+                D[100,233] = var(157); // [ var(233) , var(100) ]
+                D[101,233] = var(154); // [ var(233) , var(101) ]
+                D[103,233] = (-1)*var(150); // [ var(233) , var(103) ]
+                D[104,233] = (-1)*var(146); // [ var(233) , var(104) ]
+                D[106,233] = var(143); // [ var(233) , var(106) ]
+                D[107,233] = var(138); // [ var(233) , var(107) ]
+                D[109,233] = (-1)*var(130); // [ var(233) , var(109) ]
+                D[111,233] = var(122); // [ var(233) , var(111) ]
+                D[112,233] = (-1)*var(121); // [ var(233) , var(112) ]
+                D[113,233] = (-2)*var(241)+(-3)*var(242)+(-3)*var(243)+(-5)*var(244)+(-4)*var(245)+(-3)*var(246)+(-2)*var(247)+(-1)*var(248); // [ var(233) , var(113) ]
+                D[115,233] = (-1)*var(3); // [ var(233) , var(115) ]
+                D[116,233] = var(11); // [ var(233) , var(116) ]
+                D[117,233] = (-1)*var(19); // [ var(233) , var(117) ]
+                D[118,233] = var(27); // [ var(233) , var(118) ]
+                D[119,233] = (-1)*var(35); // [ var(233) , var(119) ]
+                D[120,233] = var(43); // [ var(233) , var(120) ]
+                D[3,234] = var(231); // [ var(234) , var(3) ]
+                D[9,234] = var(230); // [ var(234) , var(9) ]
+                D[11,234] = (-1)*var(229); // [ var(234) , var(11) ]
+                D[16,234] = (-1)*var(228); // [ var(234) , var(16) ]
+                D[19,234] = var(227); // [ var(234) , var(19) ]
+                D[24,234] = var(225); // [ var(234) , var(24) ]
+                D[27,234] = (-1)*var(224); // [ var(234) , var(27) ]
+                D[31,234] = (-1)*var(222); // [ var(234) , var(31) ]
+                D[35,234] = var(221); // [ var(234) , var(35) ]
+                D[39,234] = var(218); // [ var(234) , var(39) ]
+                D[43,234] = (-1)*var(217); // [ var(234) , var(43) ]
+                D[44,234] = (-1)*var(216); // [ var(234) , var(44) ]
+                D[47,234] = (-1)*var(213); // [ var(234) , var(47) ]
+                D[51,234] = var(212); // [ var(234) , var(51) ]
+                D[57,234] = (-1)*var(208); // [ var(234) , var(57) ]
+                D[58,234] = (-1)*var(207); // [ var(234) , var(58) ]
+                D[63,234] = var(204); // [ var(234) , var(63) ]
+                D[64,234] = var(203); // [ var(234) , var(64) ]
+                D[65,234] = var(202); // [ var(234) , var(65) ]
+                D[70,234] = (-1)*var(198); // [ var(234) , var(70) ]
+                D[71,234] = (-1)*var(197); // [ var(234) , var(71) ]
+                D[72,234] = (-1)*var(196); // [ var(234) , var(72) ]
+                D[76,234] = var(192); // [ var(234) , var(76) ]
+                D[77,234] = var(191); // [ var(234) , var(77) ]
+                D[78,234] = var(190); // [ var(234) , var(78) ]
+                D[82,234] = (-1)*var(185); // [ var(234) , var(82) ]
+                D[83,234] = (-1)*var(184); // [ var(234) , var(83) ]
+                D[84,234] = (-1)*var(183); // [ var(234) , var(84) ]
+                D[87,234] = var(178); // [ var(234) , var(87) ]
+                D[88,234] = var(177); // [ var(234) , var(88) ]
+                D[92,234] = (-1)*var(171); // [ var(234) , var(92) ]
+                D[93,234] = var(167); // [ var(234) , var(93) ]
+                D[96,234] = var(164); // [ var(234) , var(96) ]
+                D[97,234] = var(163); // [ var(234) , var(97) ]
+                D[98,234] = (-1)*var(159); // [ var(234) , var(98) ]
+                D[101,234] = (-1)*var(155); // [ var(234) , var(101) ]
+                D[102,234] = var(151); // [ var(234) , var(102) ]
+                D[104,234] = var(147); // [ var(234) , var(104) ]
+                D[105,234] = (-1)*var(144); // [ var(234) , var(105) ]
+                D[107,234] = (-1)*var(139); // [ var(234) , var(107) ]
+                D[108,234] = var(136); // [ var(234) , var(108) ]
+                D[109,234] = var(131); // [ var(234) , var(109) ]
+                D[110,234] = (-1)*var(129); // [ var(234) , var(110) ]
+                D[111,234] = (-1)*var(123); // [ var(234) , var(111) ]
+                D[114,234] = (-2)*var(241)+(-2)*var(242)+(-4)*var(243)+(-5)*var(244)+(-4)*var(245)+(-3)*var(246)+(-2)*var(247)+(-1)*var(248); // [ var(234) , var(114) ]
+                D[115,234] = var(2); // [ var(234) , var(115) ]
+                D[116,234] = (-1)*var(10); // [ var(234) , var(116) ]
+                D[117,234] = var(18); // [ var(234) , var(117) ]
+                D[118,234] = (-1)*var(26); // [ var(234) , var(118) ]
+                D[119,234] = var(34); // [ var(234) , var(119) ]
+                D[120,234] = (-1)*var(42); // [ var(234) , var(120) ]
+                D[2,235] = (-1)*var(234); // [ var(235) , var(2) ]
+                D[3,235] = var(233); // [ var(235) , var(3) ]
+                D[9,235] = var(232); // [ var(235) , var(9) ]
+                D[17,235] = (-1)*var(229); // [ var(235) , var(17) ]
+                D[23,235] = (-1)*var(228); // [ var(235) , var(23) ]
+                D[25,235] = var(227); // [ var(235) , var(25) ]
+                D[30,235] = var(225); // [ var(235) , var(30) ]
+                D[33,235] = (-1)*var(224); // [ var(235) , var(33) ]
+                D[38,235] = (-1)*var(222); // [ var(235) , var(38) ]
+                D[41,235] = var(221); // [ var(235) , var(41) ]
+                D[44,235] = var(220); // [ var(235) , var(44) ]
+                D[46,235] = var(218); // [ var(235) , var(46) ]
+                D[50,235] = (-1)*var(217); // [ var(235) , var(50) ]
+                D[51,235] = (-1)*var(215); // [ var(235) , var(51) ]
+                D[54,235] = (-1)*var(213); // [ var(235) , var(54) ]
+                D[57,235] = var(211); // [ var(235) , var(57) ]
+                D[58,235] = var(210); // [ var(235) , var(58) ]
+                D[64,235] = (-1)*var(206); // [ var(235) , var(64) ]
+                D[65,235] = (-1)*var(205); // [ var(235) , var(65) ]
+                D[69,235] = (-1)*var(204); // [ var(235) , var(69) ]
+                D[71,235] = var(201); // [ var(235) , var(71) ]
+                D[72,235] = var(200); // [ var(235) , var(72) ]
+                D[75,235] = var(198); // [ var(235) , var(75) ]
+                D[78,235] = (-1)*var(195); // [ var(235) , var(78) ]
+                D[80,235] = (-1)*var(192); // [ var(235) , var(80) ]
+                D[81,235] = (-1)*var(191); // [ var(235) , var(81) ]
+                D[84,235] = var(189); // [ var(235) , var(84) ]
+                D[85,235] = var(185); // [ var(235) , var(85) ]
+                D[86,235] = var(184); // [ var(235) , var(86) ]
+                D[90,235] = (-1)*var(178); // [ var(235) , var(90) ]
+                D[91,235] = (-1)*var(177); // [ var(235) , var(91) ]
+                D[93,235] = var(174); // [ var(235) , var(93) ]
+                D[95,235] = var(171); // [ var(235) , var(95) ]
+                D[97,235] = var(170); // [ var(235) , var(97) ]
+                D[98,235] = (-1)*var(166); // [ var(235) , var(98) ]
+                D[100,235] = (-1)*var(164); // [ var(235) , var(100) ]
+                D[101,235] = (-1)*var(161); // [ var(235) , var(101) ]
+                D[102,235] = var(158); // [ var(235) , var(102) ]
+                D[104,235] = var(153); // [ var(235) , var(104) ]
+                D[105,235] = (-1)*var(150); // [ var(235) , var(105) ]
+                D[107,235] = (-1)*var(145); // [ var(235) , var(107) ]
+                D[108,235] = var(143); // [ var(235) , var(108) ]
+                D[109,235] = var(137); // [ var(235) , var(109) ]
+                D[112,235] = (-1)*var(129); // [ var(235) , var(112) ]
+                D[113,235] = (-1)*var(123); // [ var(235) , var(113) ]
+                D[114,235] = var(122); // [ var(235) , var(114) ]
+                D[115,235] = (-2)*var(241)+(-3)*var(242)+(-4)*var(243)+(-5)*var(244)+(-4)*var(245)+(-3)*var(246)+(-2)*var(247)+(-1)*var(248); // [ var(235) , var(115) ]
+                D[116,235] = var(4); // [ var(235) , var(116) ]
+                D[117,235] = (-1)*var(12); // [ var(235) , var(117) ]
+                D[118,235] = var(20); // [ var(235) , var(118) ]
+                D[119,235] = (-1)*var(28); // [ var(235) , var(119) ]
+                D[120,235] = var(36); // [ var(235) , var(120) ]
+                D[4,236] = (-1)*var(235); // [ var(236) , var(4) ]
+                D[10,236] = var(234); // [ var(236) , var(10) ]
+                D[11,236] = (-1)*var(233); // [ var(236) , var(11) ]
+                D[16,236] = (-1)*var(232); // [ var(236) , var(16) ]
+                D[17,236] = var(231); // [ var(236) , var(17) ]
+                D[23,236] = var(230); // [ var(236) , var(23) ]
+                D[32,236] = (-1)*var(227); // [ var(236) , var(32) ]
+                D[37,236] = (-1)*var(225); // [ var(236) , var(37) ]
+                D[40,236] = var(224); // [ var(236) , var(40) ]
+                D[44,236] = (-1)*var(223); // [ var(236) , var(44) ]
+                D[45,236] = var(222); // [ var(236) , var(45) ]
+                D[49,236] = (-1)*var(221); // [ var(236) , var(49) ]
+                D[51,236] = var(219); // [ var(236) , var(51) ]
+                D[53,236] = (-1)*var(218); // [ var(236) , var(53) ]
+                D[56,236] = var(217); // [ var(236) , var(56) ]
+                D[58,236] = (-1)*var(214); // [ var(236) , var(58) ]
+                D[60,236] = var(213); // [ var(236) , var(60) ]
+                D[63,236] = (-1)*var(211); // [ var(236) , var(63) ]
+                D[65,236] = var(209); // [ var(236) , var(65) ]
+                D[69,236] = var(208); // [ var(236) , var(69) ]
+                D[70,236] = var(206); // [ var(236) , var(70) ]
+                D[75,236] = (-1)*var(203); // [ var(236) , var(75) ]
+                D[76,236] = (-1)*var(201); // [ var(236) , var(76) ]
+                D[77,236] = (-1)*var(200); // [ var(236) , var(77) ]
+                D[80,236] = var(197); // [ var(236) , var(80) ]
+                D[81,236] = var(196); // [ var(236) , var(81) ]
+                D[83,236] = var(195); // [ var(236) , var(83) ]
+                D[86,236] = (-1)*var(190); // [ var(236) , var(86) ]
+                D[88,236] = (-1)*var(189); // [ var(236) , var(88) ]
+                D[89,236] = (-1)*var(185); // [ var(236) , var(89) ]
+                D[91,236] = var(183); // [ var(236) , var(91) ]
+                D[93,236] = (-1)*var(180); // [ var(236) , var(93) ]
+                D[94,236] = var(178); // [ var(236) , var(94) ]
+                D[97,236] = (-1)*var(176); // [ var(236) , var(97) ]
+                D[98,236] = var(173); // [ var(236) , var(98) ]
+                D[99,236] = (-1)*var(171); // [ var(236) , var(99) ]
+                D[101,236] = var(169); // [ var(236) , var(101) ]
+                D[102,236] = (-1)*var(165); // [ var(236) , var(102) ]
+                D[103,236] = var(164); // [ var(236) , var(103) ]
+                D[104,236] = (-1)*var(160); // [ var(236) , var(104) ]
+                D[105,236] = var(157); // [ var(236) , var(105) ]
+                D[107,236] = var(152); // [ var(236) , var(107) ]
+                D[110,236] = (-1)*var(143); // [ var(236) , var(110) ]
+                D[111,236] = (-1)*var(137); // [ var(236) , var(111) ]
+                D[112,236] = var(136); // [ var(236) , var(112) ]
+                D[113,236] = var(131); // [ var(236) , var(113) ]
+                D[114,236] = (-1)*var(130); // [ var(236) , var(114) ]
+                D[115,236] = var(124); // [ var(236) , var(115) ]
+                D[116,236] = (-2)*var(241)+(-3)*var(242)+(-4)*var(243)+(-6)*var(244)+(-4)*var(245)+(-3)*var(246)+(-2)*var(247)+(-1)*var(248); // [ var(236) , var(116) ]
+                D[117,236] = var(5); // [ var(236) , var(117) ]
+                D[118,236] = (-1)*var(13); // [ var(236) , var(118) ]
+                D[119,236] = var(21); // [ var(236) , var(119) ]
+                D[120,236] = (-1)*var(29); // [ var(236) , var(120) ]
+                D[5,237] = (-1)*var(236); // [ var(237) , var(5) ]
+                D[12,237] = var(235); // [ var(237) , var(12) ]
+                D[18,237] = (-1)*var(234); // [ var(237) , var(18) ]
+                D[19,237] = var(233); // [ var(237) , var(19) ]
+                D[24,237] = var(232); // [ var(237) , var(24) ]
+                D[25,237] = (-1)*var(231); // [ var(237) , var(25) ]
+                D[30,237] = (-1)*var(230); // [ var(237) , var(30) ]
+                D[32,237] = var(229); // [ var(237) , var(32) ]
+                D[37,237] = var(228); // [ var(237) , var(37) ]
+                D[44,237] = var(226); // [ var(237) , var(44) ]
+                D[48,237] = (-1)*var(224); // [ var(237) , var(48) ]
+                D[52,237] = (-1)*var(222); // [ var(237) , var(52) ]
+                D[55,237] = var(221); // [ var(237) , var(55) ]
+                D[57,237] = (-1)*var(219); // [ var(237) , var(57) ]
+                D[59,237] = var(218); // [ var(237) , var(59) ]
+                D[62,237] = (-1)*var(217); // [ var(237) , var(62) ]
+                D[63,237] = var(215); // [ var(237) , var(63) ]
+                D[64,237] = var(214); // [ var(237) , var(64) ]
+                D[67,237] = (-1)*var(213); // [ var(237) , var(67) ]
+                D[69,237] = (-1)*var(212); // [ var(237) , var(69) ]
+                D[70,237] = (-1)*var(210); // [ var(237) , var(70) ]
+                D[72,237] = (-1)*var(209); // [ var(237) , var(72) ]
+                D[75,237] = var(207); // [ var(237) , var(75) ]
+                D[77,237] = var(205); // [ var(237) , var(77) ]
+                D[81,237] = (-1)*var(202); // [ var(237) , var(81) ]
+                D[82,237] = var(201); // [ var(237) , var(82) ]
+                D[85,237] = (-1)*var(197); // [ var(237) , var(85) ]
+                D[87,237] = (-1)*var(195); // [ var(237) , var(87) ]
+                D[89,237] = var(192); // [ var(237) , var(89) ]
+                D[90,237] = var(190); // [ var(237) , var(90) ]
+                D[92,237] = var(189); // [ var(237) , var(92) ]
+                D[93,237] = var(187); // [ var(237) , var(93) ]
+                D[94,237] = (-1)*var(184); // [ var(237) , var(94) ]
+                D[95,237] = (-1)*var(183); // [ var(237) , var(95) ]
+                D[97,237] = var(182); // [ var(237) , var(97) ]
+                D[98,237] = (-1)*var(179); // [ var(237) , var(98) ]
+                D[99,237] = var(177); // [ var(237) , var(99) ]
+                D[101,237] = (-1)*var(175); // [ var(237) , var(101) ]
+                D[102,237] = var(172); // [ var(237) , var(102) ]
+                D[104,237] = var(168); // [ var(237) , var(104) ]
+                D[106,237] = (-1)*var(164); // [ var(237) , var(106) ]
+                D[108,237] = (-1)*var(157); // [ var(237) , var(108) ]
+                D[109,237] = (-1)*var(152); // [ var(237) , var(109) ]
+                D[110,237] = var(150); // [ var(237) , var(110) ]
+                D[111,237] = var(145); // [ var(237) , var(111) ]
+                D[112,237] = (-1)*var(144); // [ var(237) , var(112) ]
+                D[113,237] = (-1)*var(139); // [ var(237) , var(113) ]
+                D[114,237] = var(138); // [ var(237) , var(114) ]
+                D[115,237] = (-1)*var(132); // [ var(237) , var(115) ]
+                D[116,237] = var(125); // [ var(237) , var(116) ]
+                D[117,237] = (-2)*var(241)+(-3)*var(242)+(-4)*var(243)+(-6)*var(244)+(-5)*var(245)+(-3)*var(246)+(-2)*var(247)+(-1)*var(248); // [ var(237) , var(117) ]
+                D[118,237] = var(6); // [ var(237) , var(118) ]
+                D[119,237] = (-1)*var(14); // [ var(237) , var(119) ]
+                D[120,237] = var(22); // [ var(237) , var(120) ]
+                D[6,238] = (-1)*var(237); // [ var(238) , var(6) ]
+                D[13,238] = var(236); // [ var(238) , var(13) ]
+                D[20,238] = (-1)*var(235); // [ var(238) , var(20) ]
+                D[26,238] = var(234); // [ var(238) , var(26) ]
+                D[27,238] = (-1)*var(233); // [ var(238) , var(27) ]
+                D[31,238] = (-1)*var(232); // [ var(238) , var(31) ]
+                D[33,238] = var(231); // [ var(238) , var(33) ]
+                D[38,238] = var(230); // [ var(238) , var(38) ]
+                D[40,238] = (-1)*var(229); // [ var(238) , var(40) ]
+                D[45,238] = (-1)*var(228); // [ var(238) , var(45) ]
+                D[48,238] = var(227); // [ var(238) , var(48) ]
+                D[51,238] = (-1)*var(226); // [ var(238) , var(51) ]
+                D[52,238] = var(225); // [ var(238) , var(52) ]
+                D[57,238] = var(223); // [ var(238) , var(57) ]
+                D[61,238] = (-1)*var(221); // [ var(238) , var(61) ]
+                D[63,238] = (-1)*var(220); // [ var(238) , var(63) ]
+                D[66,238] = (-1)*var(218); // [ var(238) , var(66) ]
+                D[68,238] = var(217); // [ var(238) , var(68) ]
+                D[69,238] = var(216); // [ var(238) , var(69) ]
+                D[71,238] = (-1)*var(214); // [ var(238) , var(71) ]
+                D[73,238] = var(213); // [ var(238) , var(73) ]
+                D[76,238] = var(210); // [ var(238) , var(76) ]
+                D[78,238] = var(209); // [ var(238) , var(78) ]
+                D[80,238] = (-1)*var(207); // [ var(238) , var(80) ]
+                D[82,238] = (-1)*var(206); // [ var(238) , var(82) ]
+                D[83,238] = (-1)*var(205); // [ var(238) , var(83) ]
+                D[85,238] = var(203); // [ var(238) , var(85) ]
+                D[86,238] = var(202); // [ var(238) , var(86) ]
+                D[87,238] = var(200); // [ var(238) , var(87) ]
+                D[89,238] = (-1)*var(198); // [ var(238) , var(89) ]
+                D[90,238] = (-1)*var(196); // [ var(238) , var(90) ]
+                D[93,238] = (-1)*var(193); // [ var(238) , var(93) ]
+                D[94,238] = var(191); // [ var(238) , var(94) ]
+                D[96,238] = (-1)*var(189); // [ var(238) , var(96) ]
+                D[97,238] = (-1)*var(188); // [ var(238) , var(97) ]
+                D[98,238] = var(186); // [ var(238) , var(98) ]
+                D[100,238] = var(183); // [ var(238) , var(100) ]
+                D[101,238] = var(181); // [ var(238) , var(101) ]
+                D[103,238] = (-1)*var(177); // [ var(238) , var(103) ]
+                D[105,238] = (-1)*var(172); // [ var(238) , var(105) ]
+                D[106,238] = var(171); // [ var(238) , var(106) ]
+                D[107,238] = (-1)*var(168); // [ var(238) , var(107) ]
+                D[108,238] = var(165); // [ var(238) , var(108) ]
+                D[109,238] = var(160); // [ var(238) , var(109) ]
+                D[110,238] = (-1)*var(158); // [ var(238) , var(110) ]
+                D[111,238] = (-1)*var(153); // [ var(238) , var(111) ]
+                D[112,238] = var(151); // [ var(238) , var(112) ]
+                D[113,238] = var(147); // [ var(238) , var(113) ]
+                D[114,238] = (-1)*var(146); // [ var(238) , var(114) ]
+                D[115,238] = var(140); // [ var(238) , var(115) ]
+                D[116,238] = (-1)*var(133); // [ var(238) , var(116) ]
+                D[117,238] = var(126); // [ var(238) , var(117) ]
+                D[118,238] = (-2)*var(241)+(-3)*var(242)+(-4)*var(243)+(-6)*var(244)+(-5)*var(245)+(-4)*var(246)+(-2)*var(247)+(-1)*var(248); // [ var(238) , var(118) ]
+                D[119,238] = var(7); // [ var(238) , var(119) ]
+                D[120,238] = (-1)*var(15); // [ var(238) , var(120) ]
+                D[7,239] = (-1)*var(238); // [ var(239) , var(7) ]
+                D[14,239] = var(237); // [ var(239) , var(14) ]
+                D[21,239] = (-1)*var(236); // [ var(239) , var(21) ]
+                D[28,239] = var(235); // [ var(239) , var(28) ]
+                D[34,239] = (-1)*var(234); // [ var(239) , var(34) ]
+                D[35,239] = var(233); // [ var(239) , var(35) ]
+                D[39,239] = var(232); // [ var(239) , var(39) ]
+                D[41,239] = (-1)*var(231); // [ var(239) , var(41) ]
+                D[46,239] = (-1)*var(230); // [ var(239) , var(46) ]
+                D[49,239] = var(229); // [ var(239) , var(49) ]
+                D[53,239] = var(228); // [ var(239) , var(53) ]
+                D[55,239] = (-1)*var(227); // [ var(239) , var(55) ]
+                D[58,239] = var(226); // [ var(239) , var(58) ]
+                D[59,239] = (-1)*var(225); // [ var(239) , var(59) ]
+                D[61,239] = var(224); // [ var(239) , var(61) ]
+                D[64,239] = (-1)*var(223); // [ var(239) , var(64) ]
+                D[66,239] = var(222); // [ var(239) , var(66) ]
+                D[70,239] = var(220); // [ var(239) , var(70) ]
+                D[71,239] = var(219); // [ var(239) , var(71) ]
+                D[74,239] = (-1)*var(217); // [ var(239) , var(74) ]
+                D[75,239] = (-1)*var(216); // [ var(239) , var(75) ]
+                D[76,239] = (-1)*var(215); // [ var(239) , var(76) ]
+                D[79,239] = (-1)*var(213); // [ var(239) , var(79) ]
+                D[80,239] = var(212); // [ var(239) , var(80) ]
+                D[82,239] = var(211); // [ var(239) , var(82) ]
+                D[84,239] = (-1)*var(209); // [ var(239) , var(84) ]
+                D[85,239] = (-1)*var(208); // [ var(239) , var(85) ]
+                D[88,239] = var(205); // [ var(239) , var(88) ]
+                D[89,239] = var(204); // [ var(239) , var(89) ]
+                D[91,239] = (-1)*var(202); // [ var(239) , var(91) ]
+                D[92,239] = (-1)*var(200); // [ var(239) , var(92) ]
+                D[93,239] = var(199); // [ var(239) , var(93) ]
+                D[95,239] = var(196); // [ var(239) , var(95) ]
+                D[96,239] = var(195); // [ var(239) , var(96) ]
+                D[97,239] = var(194); // [ var(239) , var(97) ]
+                D[99,239] = (-1)*var(191); // [ var(239) , var(99) ]
+                D[100,239] = (-1)*var(190); // [ var(239) , var(100) ]
+                D[102,239] = (-1)*var(186); // [ var(239) , var(102) ]
+                D[103,239] = var(184); // [ var(239) , var(103) ]
+                D[104,239] = (-1)*var(181); // [ var(239) , var(104) ]
+                D[105,239] = var(179); // [ var(239) , var(105) ]
+                D[106,239] = (-1)*var(178); // [ var(239) , var(106) ]
+                D[107,239] = var(175); // [ var(239) , var(107) ]
+                D[108,239] = (-1)*var(173); // [ var(239) , var(108) ]
+                D[109,239] = (-1)*var(169); // [ var(239) , var(109) ]
+                D[110,239] = var(166); // [ var(239) , var(110) ]
+                D[111,239] = var(161); // [ var(239) , var(111) ]
+                D[112,239] = (-1)*var(159); // [ var(239) , var(112) ]
+                D[113,239] = (-1)*var(155); // [ var(239) , var(113) ]
+                D[114,239] = var(154); // [ var(239) , var(114) ]
+                D[115,239] = (-1)*var(148); // [ var(239) , var(115) ]
+                D[116,239] = var(141); // [ var(239) , var(116) ]
+                D[117,239] = (-1)*var(134); // [ var(239) , var(117) ]
+                D[118,239] = var(127); // [ var(239) , var(118) ]
+                D[119,239] = (-2)*var(241)+(-3)*var(242)+(-4)*var(243)+(-6)*var(244)+(-5)*var(245)+(-4)*var(246)+(-3)*var(247)+(-1)*var(248); // [ var(239) , var(119) ]
+                D[120,239] = var(8); // [ var(239) , var(120) ]
+                D[8,240] = (-1)*var(239); // [ var(240) , var(8) ]
+                D[15,240] = var(238); // [ var(240) , var(15) ]
+                D[22,240] = (-1)*var(237); // [ var(240) , var(22) ]
+                D[29,240] = var(236); // [ var(240) , var(29) ]
+                D[36,240] = (-1)*var(235); // [ var(240) , var(36) ]
+                D[42,240] = var(234); // [ var(240) , var(42) ]
+                D[43,240] = (-1)*var(233); // [ var(240) , var(43) ]
+                D[47,240] = (-1)*var(232); // [ var(240) , var(47) ]
+                D[50,240] = var(231); // [ var(240) , var(50) ]
+                D[54,240] = var(230); // [ var(240) , var(54) ]
+                D[56,240] = (-1)*var(229); // [ var(240) , var(56) ]
+                D[60,240] = (-1)*var(228); // [ var(240) , var(60) ]
+                D[62,240] = var(227); // [ var(240) , var(62) ]
+                D[65,240] = (-1)*var(226); // [ var(240) , var(65) ]
+                D[67,240] = var(225); // [ var(240) , var(67) ]
+                D[68,240] = (-1)*var(224); // [ var(240) , var(68) ]
+                D[72,240] = var(223); // [ var(240) , var(72) ]
+                D[73,240] = (-1)*var(222); // [ var(240) , var(73) ]
+                D[74,240] = var(221); // [ var(240) , var(74) ]
+                D[77,240] = (-1)*var(220); // [ var(240) , var(77) ]
+                D[78,240] = (-1)*var(219); // [ var(240) , var(78) ]
+                D[79,240] = var(218); // [ var(240) , var(79) ]
+                D[81,240] = var(216); // [ var(240) , var(81) ]
+                D[83,240] = var(215); // [ var(240) , var(83) ]
+                D[84,240] = var(214); // [ var(240) , var(84) ]
+                D[86,240] = (-1)*var(212); // [ var(240) , var(86) ]
+                D[87,240] = (-1)*var(211); // [ var(240) , var(87) ]
+                D[88,240] = (-1)*var(210); // [ var(240) , var(88) ]
+                D[90,240] = var(208); // [ var(240) , var(90) ]
+                D[91,240] = var(207); // [ var(240) , var(91) ]
+                D[92,240] = var(206); // [ var(240) , var(92) ]
+                D[94,240] = (-1)*var(204); // [ var(240) , var(94) ]
+                D[95,240] = (-1)*var(203); // [ var(240) , var(95) ]
+                D[96,240] = (-1)*var(201); // [ var(240) , var(96) ]
+                D[98,240] = (-1)*var(199); // [ var(240) , var(98) ]
+                D[99,240] = var(198); // [ var(240) , var(99) ]
+                D[100,240] = var(197); // [ var(240) , var(100) ]
+                D[101,240] = (-1)*var(194); // [ var(240) , var(101) ]
+                D[102,240] = var(193); // [ var(240) , var(102) ]
+                D[103,240] = (-1)*var(192); // [ var(240) , var(103) ]
+                D[104,240] = var(188); // [ var(240) , var(104) ]
+                D[105,240] = (-1)*var(187); // [ var(240) , var(105) ]
+                D[106,240] = var(185); // [ var(240) , var(106) ]
+                D[107,240] = (-1)*var(182); // [ var(240) , var(107) ]
+                D[108,240] = var(180); // [ var(240) , var(108) ]
+                D[109,240] = var(176); // [ var(240) , var(109) ]
+                D[110,240] = (-1)*var(174); // [ var(240) , var(110) ]
+                D[111,240] = (-1)*var(170); // [ var(240) , var(111) ]
+                D[112,240] = var(167); // [ var(240) , var(112) ]
+                D[113,240] = var(163); // [ var(240) , var(113) ]
+                D[114,240] = (-1)*var(162); // [ var(240) , var(114) ]
+                D[115,240] = var(156); // [ var(240) , var(115) ]
+                D[116,240] = (-1)*var(149); // [ var(240) , var(116) ]
+                D[117,240] = var(142); // [ var(240) , var(117) ]
+                D[118,240] = (-1)*var(135); // [ var(240) , var(118) ]
+                D[119,240] = var(128); // [ var(240) , var(119) ]
+                D[120,240] = (-2)*var(241)+(-3)*var(242)+(-4)*var(243)+(-6)*var(244)+(-5)*var(245)+(-4)*var(246)+(-3)*var(247)+(-2)*var(248); // [ var(240) , var(120) ]
+        // X(i) * X(j):
+                D[1,3] = var(9); // [ var(3) , var(1) ]
+                D[1,11] = var(16); // [ var(11) , var(1) ]
+                D[1,17] = var(23); // [ var(17) , var(1) ]
+                D[1,19] = var(24); // [ var(19) , var(1) ]
+                D[1,25] = var(30); // [ var(25) , var(1) ]
+                D[1,27] = var(31); // [ var(27) , var(1) ]
+                D[1,32] = var(37); // [ var(32) , var(1) ]
+                D[1,33] = var(38); // [ var(33) , var(1) ]
+                D[1,35] = var(39); // [ var(35) , var(1) ]
+                D[1,40] = var(45); // [ var(40) , var(1) ]
+                D[1,41] = var(46); // [ var(41) , var(1) ]
+                D[1,43] = var(47); // [ var(43) , var(1) ]
+                D[1,48] = var(52); // [ var(48) , var(1) ]
+                D[1,49] = var(53); // [ var(49) , var(1) ]
+                D[1,50] = var(54); // [ var(50) , var(1) ]
+                D[1,55] = var(59); // [ var(55) , var(1) ]
+                D[1,56] = var(60); // [ var(56) , var(1) ]
+                D[1,61] = var(66); // [ var(61) , var(1) ]
+                D[1,62] = var(67); // [ var(62) , var(1) ]
+                D[1,68] = var(73); // [ var(68) , var(1) ]
+                D[1,74] = var(79); // [ var(74) , var(1) ]
+                D[1,93] = (-1)*var(97); // [ var(93) , var(1) ]
+                D[1,98] = (-1)*var(101); // [ var(98) , var(1) ]
+                D[1,102] = (-1)*var(104); // [ var(102) , var(1) ]
+                D[1,105] = (-1)*var(107); // [ var(105) , var(1) ]
+                D[1,108] = (-1)*var(109); // [ var(108) , var(1) ]
+                D[1,110] = (-1)*var(111); // [ var(110) , var(1) ]
+                D[1,112] = (-1)*var(113); // [ var(112) , var(1) ]
+                D[2,4] = var(10); // [ var(4) , var(2) ]
+                D[2,11] = var(17); // [ var(11) , var(2) ]
+                D[2,12] = var(18); // [ var(12) , var(2) ]
+                D[2,16] = var(23); // [ var(16) , var(2) ]
+                D[2,19] = var(25); // [ var(19) , var(2) ]
+                D[2,20] = var(26); // [ var(20) , var(2) ]
+                D[2,24] = var(30); // [ var(24) , var(2) ]
+                D[2,27] = var(33); // [ var(27) , var(2) ]
+                D[2,28] = var(34); // [ var(28) , var(2) ]
+                D[2,31] = var(38); // [ var(31) , var(2) ]
+                D[2,35] = var(41); // [ var(35) , var(2) ]
+                D[2,36] = var(42); // [ var(36) , var(2) ]
+                D[2,39] = var(46); // [ var(39) , var(2) ]
+                D[2,43] = var(50); // [ var(43) , var(2) ]
+                D[2,47] = var(54); // [ var(47) , var(2) ]
+                D[2,63] = (-1)*var(69); // [ var(63) , var(2) ]
+                D[2,70] = (-1)*var(75); // [ var(70) , var(2) ]
+                D[2,76] = (-1)*var(80); // [ var(76) , var(2) ]
+                D[2,77] = (-1)*var(81); // [ var(77) , var(2) ]
+                D[2,82] = (-1)*var(85); // [ var(82) , var(2) ]
+                D[2,83] = (-1)*var(86); // [ var(83) , var(2) ]
+                D[2,87] = (-1)*var(90); // [ var(87) , var(2) ]
+                D[2,88] = (-1)*var(91); // [ var(88) , var(2) ]
+                D[2,92] = (-1)*var(95); // [ var(92) , var(2) ]
+                D[2,96] = (-1)*var(100); // [ var(96) , var(2) ]
+                D[2,110] = var(112); // [ var(110) , var(2) ]
+                D[2,111] = var(113); // [ var(111) , var(2) ]
+                D[2,114] = var(115); // [ var(114) , var(2) ]
+                D[3,4] = var(11); // [ var(4) , var(3) ]
+                D[3,10] = var(17); // [ var(10) , var(3) ]
+                D[3,12] = var(19); // [ var(12) , var(3) ]
+                D[3,18] = var(25); // [ var(18) , var(3) ]
+                D[3,20] = var(27); // [ var(20) , var(3) ]
+                D[3,26] = var(33); // [ var(26) , var(3) ]
+                D[3,28] = var(35); // [ var(28) , var(3) ]
+                D[3,34] = var(41); // [ var(34) , var(3) ]
+                D[3,36] = var(43); // [ var(36) , var(3) ]
+                D[3,37] = var(44); // [ var(37) , var(3) ]
+                D[3,42] = var(50); // [ var(42) , var(3) ]
+                D[3,45] = var(51); // [ var(45) , var(3) ]
+                D[3,52] = var(57); // [ var(52) , var(3) ]
+                D[3,53] = var(58); // [ var(53) , var(3) ]
+                D[3,59] = var(64); // [ var(59) , var(3) ]
+                D[3,60] = var(65); // [ var(60) , var(3) ]
+                D[3,66] = var(71); // [ var(66) , var(3) ]
+                D[3,67] = var(72); // [ var(67) , var(3) ]
+                D[3,73] = var(78); // [ var(73) , var(3) ]
+                D[3,79] = var(84); // [ var(79) , var(3) ]
+                D[3,89] = (-1)*var(93); // [ var(89) , var(3) ]
+                D[3,94] = (-1)*var(98); // [ var(94) , var(3) ]
+                D[3,99] = (-1)*var(102); // [ var(99) , var(3) ]
+                D[3,103] = (-1)*var(105); // [ var(103) , var(3) ]
+                D[3,106] = (-1)*var(108); // [ var(106) , var(3) ]
+                D[3,111] = (-1)*var(114); // [ var(111) , var(3) ]
+                D[3,113] = (-1)*var(115); // [ var(113) , var(3) ]
+                D[4,5] = var(12); // [ var(5) , var(4) ]
+                D[4,9] = (-1)*var(16); // [ var(9) , var(4) ]
+                D[4,13] = var(20); // [ var(13) , var(4) ]
+                D[4,21] = var(28); // [ var(21) , var(4) ]
+                D[4,25] = (-1)*var(32); // [ var(25) , var(4) ]
+                D[4,29] = var(36); // [ var(29) , var(4) ]
+                D[4,30] = (-1)*var(37); // [ var(30) , var(4) ]
+                D[4,33] = (-1)*var(40); // [ var(33) , var(4) ]
+                D[4,38] = (-1)*var(45); // [ var(38) , var(4) ]
+                D[4,41] = (-1)*var(49); // [ var(41) , var(4) ]
+                D[4,46] = (-1)*var(53); // [ var(46) , var(4) ]
+                D[4,50] = (-1)*var(56); // [ var(50) , var(4) ]
+                D[4,54] = (-1)*var(60); // [ var(54) , var(4) ]
+                D[4,57] = (-1)*var(63); // [ var(57) , var(4) ]
+                D[4,64] = (-1)*var(70); // [ var(64) , var(4) ]
+                D[4,71] = (-1)*var(76); // [ var(71) , var(4) ]
+                D[4,72] = (-1)*var(77); // [ var(72) , var(4) ]
+                D[4,78] = (-1)*var(83); // [ var(78) , var(4) ]
+                D[4,84] = (-1)*var(88); // [ var(84) , var(4) ]
+                D[4,85] = (-1)*var(89); // [ var(85) , var(4) ]
+                D[4,90] = (-1)*var(94); // [ var(90) , var(4) ]
+                D[4,95] = (-1)*var(99); // [ var(95) , var(4) ]
+                D[4,100] = (-1)*var(103); // [ var(100) , var(4) ]
+                D[4,108] = (-1)*var(110); // [ var(108) , var(4) ]
+                D[4,109] = (-1)*var(111); // [ var(109) , var(4) ]
+                D[4,115] = var(116); // [ var(115) , var(4) ]
+                D[5,6] = var(13); // [ var(6) , var(5) ]
+                D[5,10] = (-1)*var(18); // [ var(10) , var(5) ]
+                D[5,11] = (-1)*var(19); // [ var(11) , var(5) ]
+                D[5,14] = var(21); // [ var(14) , var(5) ]
+                D[5,16] = (-1)*var(24); // [ var(16) , var(5) ]
+                D[5,17] = (-1)*var(25); // [ var(17) , var(5) ]
+                D[5,22] = var(29); // [ var(22) , var(5) ]
+                D[5,23] = (-1)*var(30); // [ var(23) , var(5) ]
+                D[5,40] = (-1)*var(48); // [ var(40) , var(5) ]
+                D[5,45] = (-1)*var(52); // [ var(45) , var(5) ]
+                D[5,49] = (-1)*var(55); // [ var(49) , var(5) ]
+                D[5,51] = (-1)*var(57); // [ var(51) , var(5) ]
+                D[5,53] = (-1)*var(59); // [ var(53) , var(5) ]
+                D[5,56] = (-1)*var(62); // [ var(56) , var(5) ]
+                D[5,58] = (-1)*var(64); // [ var(58) , var(5) ]
+                D[5,60] = (-1)*var(67); // [ var(60) , var(5) ]
+                D[5,65] = (-1)*var(72); // [ var(65) , var(5) ]
+                D[5,76] = (-1)*var(82); // [ var(76) , var(5) ]
+                D[5,80] = (-1)*var(85); // [ var(80) , var(5) ]
+                D[5,83] = (-1)*var(87); // [ var(83) , var(5) ]
+                D[5,86] = (-1)*var(90); // [ var(86) , var(5) ]
+                D[5,88] = (-1)*var(92); // [ var(88) , var(5) ]
+                D[5,91] = (-1)*var(95); // [ var(91) , var(5) ]
+                D[5,103] = (-1)*var(106); // [ var(103) , var(5) ]
+                D[5,105] = (-1)*var(108); // [ var(105) , var(5) ]
+                D[5,107] = (-1)*var(109); // [ var(107) , var(5) ]
+                D[5,116] = var(117); // [ var(116) , var(5) ]
+                D[6,7] = var(14); // [ var(7) , var(6) ]
+                D[6,12] = (-1)*var(20); // [ var(12) , var(6) ]
+                D[6,15] = var(22); // [ var(15) , var(6) ]
+                D[6,18] = (-1)*var(26); // [ var(18) , var(6) ]
+                D[6,19] = (-1)*var(27); // [ var(19) , var(6) ]
+                D[6,24] = (-1)*var(31); // [ var(24) , var(6) ]
+                D[6,25] = (-1)*var(33); // [ var(25) , var(6) ]
+                D[6,30] = (-1)*var(38); // [ var(30) , var(6) ]
+                D[6,32] = (-1)*var(40); // [ var(32) , var(6) ]
+                D[6,37] = (-1)*var(45); // [ var(37) , var(6) ]
+                D[6,44] = (-1)*var(51); // [ var(44) , var(6) ]
+                D[6,55] = (-1)*var(61); // [ var(55) , var(6) ]
+                D[6,59] = (-1)*var(66); // [ var(59) , var(6) ]
+                D[6,62] = (-1)*var(68); // [ var(62) , var(6) ]
+                D[6,64] = (-1)*var(71); // [ var(64) , var(6) ]
+                D[6,67] = (-1)*var(73); // [ var(67) , var(6) ]
+                D[6,70] = (-1)*var(76); // [ var(70) , var(6) ]
+                D[6,72] = (-1)*var(78); // [ var(72) , var(6) ]
+                D[6,75] = (-1)*var(80); // [ var(75) , var(6) ]
+                D[6,77] = (-1)*var(83); // [ var(77) , var(6) ]
+                D[6,81] = (-1)*var(86); // [ var(81) , var(6) ]
+                D[6,92] = (-1)*var(96); // [ var(92) , var(6) ]
+                D[6,95] = (-1)*var(100); // [ var(95) , var(6) ]
+                D[6,99] = (-1)*var(103); // [ var(99) , var(6) ]
+                D[6,102] = (-1)*var(105); // [ var(102) , var(6) ]
+                D[6,104] = (-1)*var(107); // [ var(104) , var(6) ]
+                D[6,117] = var(118); // [ var(117) , var(6) ]
+                D[7,8] = var(15); // [ var(8) , var(7) ]
+                D[7,13] = (-1)*var(21); // [ var(13) , var(7) ]
+                D[7,20] = (-1)*var(28); // [ var(20) , var(7) ]
+                D[7,26] = (-1)*var(34); // [ var(26) , var(7) ]
+                D[7,27] = (-1)*var(35); // [ var(27) , var(7) ]
+                D[7,31] = (-1)*var(39); // [ var(31) , var(7) ]
+                D[7,33] = (-1)*var(41); // [ var(33) , var(7) ]
+                D[7,38] = (-1)*var(46); // [ var(38) , var(7) ]
+                D[7,40] = (-1)*var(49); // [ var(40) , var(7) ]
+                D[7,45] = (-1)*var(53); // [ var(45) , var(7) ]
+                D[7,48] = (-1)*var(55); // [ var(48) , var(7) ]
+                D[7,51] = (-1)*var(58); // [ var(51) , var(7) ]
+                D[7,52] = (-1)*var(59); // [ var(52) , var(7) ]
+                D[7,57] = (-1)*var(64); // [ var(57) , var(7) ]
+                D[7,63] = (-1)*var(70); // [ var(63) , var(7) ]
+                D[7,68] = (-1)*var(74); // [ var(68) , var(7) ]
+                D[7,69] = (-1)*var(75); // [ var(69) , var(7) ]
+                D[7,73] = (-1)*var(79); // [ var(73) , var(7) ]
+                D[7,78] = (-1)*var(84); // [ var(78) , var(7) ]
+                D[7,83] = (-1)*var(88); // [ var(83) , var(7) ]
+                D[7,86] = (-1)*var(91); // [ var(86) , var(7) ]
+                D[7,87] = (-1)*var(92); // [ var(87) , var(7) ]
+                D[7,90] = (-1)*var(95); // [ var(90) , var(7) ]
+                D[7,94] = (-1)*var(99); // [ var(94) , var(7) ]
+                D[7,98] = (-1)*var(102); // [ var(98) , var(7) ]
+                D[7,101] = (-1)*var(104); // [ var(101) , var(7) ]
+                D[7,118] = var(119); // [ var(118) , var(7) ]
+                D[8,14] = (-1)*var(22); // [ var(14) , var(8) ]
+                D[8,21] = (-1)*var(29); // [ var(21) , var(8) ]
+                D[8,28] = (-1)*var(36); // [ var(28) , var(8) ]
+                D[8,34] = (-1)*var(42); // [ var(34) , var(8) ]
+                D[8,35] = (-1)*var(43); // [ var(35) , var(8) ]
+                D[8,39] = (-1)*var(47); // [ var(39) , var(8) ]
+                D[8,41] = (-1)*var(50); // [ var(41) , var(8) ]
+                D[8,46] = (-1)*var(54); // [ var(46) , var(8) ]
+                D[8,49] = (-1)*var(56); // [ var(49) , var(8) ]
+                D[8,53] = (-1)*var(60); // [ var(53) , var(8) ]
+                D[8,55] = (-1)*var(62); // [ var(55) , var(8) ]
+                D[8,58] = (-1)*var(65); // [ var(58) , var(8) ]
+                D[8,59] = (-1)*var(67); // [ var(59) , var(8) ]
+                D[8,61] = (-1)*var(68); // [ var(61) , var(8) ]
+                D[8,64] = (-1)*var(72); // [ var(64) , var(8) ]
+                D[8,66] = (-1)*var(73); // [ var(66) , var(8) ]
+                D[8,70] = (-1)*var(77); // [ var(70) , var(8) ]
+                D[8,71] = (-1)*var(78); // [ var(71) , var(8) ]
+                D[8,75] = (-1)*var(81); // [ var(75) , var(8) ]
+                D[8,76] = (-1)*var(83); // [ var(76) , var(8) ]
+                D[8,80] = (-1)*var(86); // [ var(80) , var(8) ]
+                D[8,82] = (-1)*var(87); // [ var(82) , var(8) ]
+                D[8,85] = (-1)*var(90); // [ var(85) , var(8) ]
+                D[8,89] = (-1)*var(94); // [ var(89) , var(8) ]
+                D[8,93] = (-1)*var(98); // [ var(93) , var(8) ]
+                D[8,97] = (-1)*var(101); // [ var(97) , var(8) ]
+                D[8,119] = var(120); // [ var(119) , var(8) ]
+                D[9,10] = var(23); // [ var(10) , var(9) ]
+                D[9,12] = var(24); // [ var(12) , var(9) ]
+                D[9,18] = var(30); // [ var(18) , var(9) ]
+                D[9,20] = var(31); // [ var(20) , var(9) ]
+                D[9,26] = var(38); // [ var(26) , var(9) ]
+                D[9,28] = var(39); // [ var(28) , var(9) ]
+                D[9,32] = (-1)*var(44); // [ var(32) , var(9) ]
+                D[9,34] = var(46); // [ var(34) , var(9) ]
+                D[9,36] = var(47); // [ var(36) , var(9) ]
+                D[9,40] = (-1)*var(51); // [ var(40) , var(9) ]
+                D[9,42] = var(54); // [ var(42) , var(9) ]
+                D[9,48] = (-1)*var(57); // [ var(48) , var(9) ]
+                D[9,49] = (-1)*var(58); // [ var(49) , var(9) ]
+                D[9,55] = (-1)*var(64); // [ var(55) , var(9) ]
+                D[9,56] = (-1)*var(65); // [ var(56) , var(9) ]
+                D[9,61] = (-1)*var(71); // [ var(61) , var(9) ]
+                D[9,62] = (-1)*var(72); // [ var(62) , var(9) ]
+                D[9,68] = (-1)*var(78); // [ var(68) , var(9) ]
+                D[9,74] = (-1)*var(84); // [ var(74) , var(9) ]
+                D[9,89] = var(97); // [ var(89) , var(9) ]
+                D[9,94] = var(101); // [ var(94) , var(9) ]
+                D[9,99] = var(104); // [ var(99) , var(9) ]
+                D[9,103] = var(107); // [ var(103) , var(9) ]
+                D[9,106] = var(109); // [ var(106) , var(9) ]
+                D[9,110] = (-1)*var(114); // [ var(110) , var(9) ]
+                D[9,112] = (-1)*var(115); // [ var(112) , var(9) ]
+                D[10,13] = var(26); // [ var(13) , var(10) ]
+                D[10,19] = var(32); // [ var(19) , var(10) ]
+                D[10,21] = var(34); // [ var(21) , var(10) ]
+                D[10,24] = var(37); // [ var(24) , var(10) ]
+                D[10,27] = var(40); // [ var(27) , var(10) ]
+                D[10,29] = var(42); // [ var(29) , var(10) ]
+                D[10,31] = var(45); // [ var(31) , var(10) ]
+                D[10,35] = var(49); // [ var(35) , var(10) ]
+                D[10,39] = var(53); // [ var(39) , var(10) ]
+                D[10,43] = var(56); // [ var(43) , var(10) ]
+                D[10,47] = var(60); // [ var(47) , var(10) ]
+                D[10,57] = var(69); // [ var(57) , var(10) ]
+                D[10,64] = var(75); // [ var(64) , var(10) ]
+                D[10,71] = var(80); // [ var(71) , var(10) ]
+                D[10,72] = var(81); // [ var(72) , var(10) ]
+                D[10,78] = var(86); // [ var(78) , var(10) ]
+                D[10,82] = (-1)*var(89); // [ var(82) , var(10) ]
+                D[10,84] = var(91); // [ var(84) , var(10) ]
+                D[10,87] = (-1)*var(94); // [ var(87) , var(10) ]
+                D[10,92] = (-1)*var(99); // [ var(92) , var(10) ]
+                D[10,96] = (-1)*var(103); // [ var(96) , var(10) ]
+                D[10,108] = (-1)*var(112); // [ var(108) , var(10) ]
+                D[10,109] = (-1)*var(113); // [ var(109) , var(10) ]
+                D[10,114] = (-1)*var(116); // [ var(114) , var(10) ]
+                D[11,13] = var(27); // [ var(13) , var(11) ]
+                D[11,18] = var(32); // [ var(18) , var(11) ]
+                D[11,21] = var(35); // [ var(21) , var(11) ]
+                D[11,26] = var(40); // [ var(26) , var(11) ]
+                D[11,29] = var(43); // [ var(29) , var(11) ]
+                D[11,30] = (-1)*var(44); // [ var(30) , var(11) ]
+                D[11,34] = var(49); // [ var(34) , var(11) ]
+                D[11,38] = (-1)*var(51); // [ var(38) , var(11) ]
+                D[11,42] = var(56); // [ var(42) , var(11) ]
+                D[11,46] = (-1)*var(58); // [ var(46) , var(11) ]
+                D[11,52] = var(63); // [ var(52) , var(11) ]
+                D[11,54] = (-1)*var(65); // [ var(54) , var(11) ]
+                D[11,59] = var(70); // [ var(59) , var(11) ]
+                D[11,66] = var(76); // [ var(66) , var(11) ]
+                D[11,67] = var(77); // [ var(67) , var(11) ]
+                D[11,73] = var(83); // [ var(73) , var(11) ]
+                D[11,79] = var(88); // [ var(79) , var(11) ]
+                D[11,85] = var(93); // [ var(85) , var(11) ]
+                D[11,90] = var(98); // [ var(90) , var(11) ]
+                D[11,95] = var(102); // [ var(95) , var(11) ]
+                D[11,100] = var(105); // [ var(100) , var(11) ]
+                D[11,106] = (-1)*var(110); // [ var(106) , var(11) ]
+                D[11,109] = var(114); // [ var(109) , var(11) ]
+                D[11,113] = var(116); // [ var(113) , var(11) ]
+                D[12,14] = var(28); // [ var(14) , var(12) ]
+                D[12,17] = var(32); // [ var(17) , var(12) ]
+                D[12,22] = var(36); // [ var(22) , var(12) ]
+                D[12,23] = var(37); // [ var(23) , var(12) ]
+                D[12,33] = (-1)*var(48); // [ var(33) , var(12) ]
+                D[12,38] = (-1)*var(52); // [ var(38) , var(12) ]
+                D[12,41] = (-1)*var(55); // [ var(41) , var(12) ]
+                D[12,46] = (-1)*var(59); // [ var(46) , var(12) ]
+                D[12,50] = (-1)*var(62); // [ var(50) , var(12) ]
+                D[12,51] = var(63); // [ var(51) , var(12) ]
+                D[12,54] = (-1)*var(67); // [ var(54) , var(12) ]
+                D[12,58] = var(70); // [ var(58) , var(12) ]
+                D[12,65] = var(77); // [ var(65) , var(12) ]
+                D[12,71] = (-1)*var(82); // [ var(71) , var(12) ]
+                D[12,78] = (-1)*var(87); // [ var(78) , var(12) ]
+                D[12,80] = var(89); // [ var(80) , var(12) ]
+                D[12,84] = (-1)*var(92); // [ var(84) , var(12) ]
+                D[12,86] = var(94); // [ var(86) , var(12) ]
+                D[12,91] = var(99); // [ var(91) , var(12) ]
+                D[12,100] = (-1)*var(106); // [ var(100) , var(12) ]
+                D[12,105] = var(110); // [ var(105) , var(12) ]
+                D[12,107] = var(111); // [ var(107) , var(12) ]
+                D[12,115] = (-1)*var(117); // [ var(115) , var(12) ]
+                D[13,15] = var(29); // [ var(15) , var(13) ]
+                D[13,16] = (-1)*var(31); // [ var(16) , var(13) ]
+                D[13,17] = (-1)*var(33); // [ var(17) , var(13) ]
+                D[13,23] = (-1)*var(38); // [ var(23) , var(13) ]
+                D[13,32] = var(48); // [ var(32) , var(13) ]
+                D[13,37] = var(52); // [ var(37) , var(13) ]
+                D[13,44] = var(57); // [ var(44) , var(13) ]
+                D[13,49] = (-1)*var(61); // [ var(49) , var(13) ]
+                D[13,53] = (-1)*var(66); // [ var(53) , var(13) ]
+                D[13,56] = (-1)*var(68); // [ var(56) , var(13) ]
+                D[13,58] = (-1)*var(71); // [ var(58) , var(13) ]
+                D[13,60] = (-1)*var(73); // [ var(60) , var(13) ]
+                D[13,65] = (-1)*var(78); // [ var(65) , var(13) ]
+                D[13,70] = var(82); // [ var(70) , var(13) ]
+                D[13,75] = var(85); // [ var(75) , var(13) ]
+                D[13,77] = var(87); // [ var(77) , var(13) ]
+                D[13,81] = var(90); // [ var(81) , var(13) ]
+                D[13,88] = (-1)*var(96); // [ var(88) , var(13) ]
+                D[13,91] = (-1)*var(100); // [ var(91) , var(13) ]
+                D[13,99] = var(106); // [ var(99) , var(13) ]
+                D[13,102] = var(108); // [ var(102) , var(13) ]
+                D[13,104] = var(109); // [ var(104) , var(13) ]
+                D[13,116] = (-1)*var(118); // [ var(116) , var(13) ]
+                D[14,18] = (-1)*var(34); // [ var(18) , var(14) ]
+                D[14,19] = (-1)*var(35); // [ var(19) , var(14) ]
+                D[14,24] = (-1)*var(39); // [ var(24) , var(14) ]
+                D[14,25] = (-1)*var(41); // [ var(25) , var(14) ]
+                D[14,30] = (-1)*var(46); // [ var(30) , var(14) ]
+                D[14,32] = (-1)*var(49); // [ var(32) , var(14) ]
+                D[14,37] = (-1)*var(53); // [ var(37) , var(14) ]
+                D[14,44] = (-1)*var(58); // [ var(44) , var(14) ]
+                D[14,48] = var(61); // [ var(48) , var(14) ]
+                D[14,52] = var(66); // [ var(52) , var(14) ]
+                D[14,57] = var(71); // [ var(57) , var(14) ]
+                D[14,62] = (-1)*var(74); // [ var(62) , var(14) ]
+                D[14,63] = var(76); // [ var(63) , var(14) ]
+                D[14,67] = (-1)*var(79); // [ var(67) , var(14) ]
+                D[14,69] = var(80); // [ var(69) , var(14) ]
+                D[14,72] = (-1)*var(84); // [ var(72) , var(14) ]
+                D[14,77] = (-1)*var(88); // [ var(77) , var(14) ]
+                D[14,81] = (-1)*var(91); // [ var(81) , var(14) ]
+                D[14,87] = var(96); // [ var(87) , var(14) ]
+                D[14,90] = var(100); // [ var(90) , var(14) ]
+                D[14,94] = var(103); // [ var(94) , var(14) ]
+                D[14,98] = var(105); // [ var(98) , var(14) ]
+                D[14,101] = var(107); // [ var(101) , var(14) ]
+                D[14,117] = (-1)*var(119); // [ var(117) , var(14) ]
+                D[15,20] = (-1)*var(36); // [ var(20) , var(15) ]
+                D[15,26] = (-1)*var(42); // [ var(26) , var(15) ]
+                D[15,27] = (-1)*var(43); // [ var(27) , var(15) ]
+                D[15,31] = (-1)*var(47); // [ var(31) , var(15) ]
+                D[15,33] = (-1)*var(50); // [ var(33) , var(15) ]
+                D[15,38] = (-1)*var(54); // [ var(38) , var(15) ]
+                D[15,40] = (-1)*var(56); // [ var(40) , var(15) ]
+                D[15,45] = (-1)*var(60); // [ var(45) , var(15) ]
+                D[15,48] = (-1)*var(62); // [ var(48) , var(15) ]
+                D[15,51] = (-1)*var(65); // [ var(51) , var(15) ]
+                D[15,52] = (-1)*var(67); // [ var(52) , var(15) ]
+                D[15,57] = (-1)*var(72); // [ var(57) , var(15) ]
+                D[15,61] = var(74); // [ var(61) , var(15) ]
+                D[15,63] = (-1)*var(77); // [ var(63) , var(15) ]
+                D[15,66] = var(79); // [ var(66) , var(15) ]
+                D[15,69] = (-1)*var(81); // [ var(69) , var(15) ]
+                D[15,71] = var(84); // [ var(71) , var(15) ]
+                D[15,76] = var(88); // [ var(76) , var(15) ]
+                D[15,80] = var(91); // [ var(80) , var(15) ]
+                D[15,82] = var(92); // [ var(82) , var(15) ]
+                D[15,85] = var(95); // [ var(85) , var(15) ]
+                D[15,89] = var(99); // [ var(89) , var(15) ]
+                D[15,93] = var(102); // [ var(93) , var(15) ]
+                D[15,97] = var(104); // [ var(97) , var(15) ]
+                D[15,118] = (-1)*var(120); // [ var(118) , var(15) ]
+                D[16,18] = var(37); // [ var(18) , var(16) ]
+                D[16,21] = var(39); // [ var(21) , var(16) ]
+                D[16,25] = var(44); // [ var(25) , var(16) ]
+                D[16,26] = var(45); // [ var(26) , var(16) ]
+                D[16,29] = var(47); // [ var(29) , var(16) ]
+                D[16,33] = var(51); // [ var(33) , var(16) ]
+                D[16,34] = var(53); // [ var(34) , var(16) ]
+                D[16,41] = var(58); // [ var(41) , var(16) ]
+                D[16,42] = var(60); // [ var(42) , var(16) ]
+                D[16,48] = (-1)*var(63); // [ var(48) , var(16) ]
+                D[16,50] = var(65); // [ var(50) , var(16) ]
+                D[16,55] = (-1)*var(70); // [ var(55) , var(16) ]
+                D[16,61] = (-1)*var(76); // [ var(61) , var(16) ]
+                D[16,62] = (-1)*var(77); // [ var(62) , var(16) ]
+                D[16,68] = (-1)*var(83); // [ var(68) , var(16) ]
+                D[16,74] = (-1)*var(88); // [ var(74) , var(16) ]
+                D[16,85] = (-1)*var(97); // [ var(85) , var(16) ]
+                D[16,90] = (-1)*var(101); // [ var(90) , var(16) ]
+                D[16,95] = (-1)*var(104); // [ var(95) , var(16) ]
+                D[16,100] = (-1)*var(107); // [ var(100) , var(16) ]
+                D[16,106] = var(111); // [ var(106) , var(16) ]
+                D[16,108] = var(114); // [ var(108) , var(16) ]
+                D[16,112] = var(116); // [ var(112) , var(16) ]
+                D[17,20] = (-1)*var(40); // [ var(20) , var(17) ]
+                D[17,21] = var(41); // [ var(21) , var(17) ]
+                D[17,24] = var(44); // [ var(24) , var(17) ]
+                D[17,28] = (-1)*var(49); // [ var(28) , var(17) ]
+                D[17,29] = var(50); // [ var(29) , var(17) ]
+                D[17,31] = var(51); // [ var(31) , var(17) ]
+                D[17,36] = (-1)*var(56); // [ var(36) , var(17) ]
+                D[17,39] = var(58); // [ var(39) , var(17) ]
+                D[17,47] = var(65); // [ var(47) , var(17) ]
+                D[17,52] = (-1)*var(69); // [ var(52) , var(17) ]
+                D[17,59] = (-1)*var(75); // [ var(59) , var(17) ]
+                D[17,66] = (-1)*var(80); // [ var(66) , var(17) ]
+                D[17,67] = (-1)*var(81); // [ var(67) , var(17) ]
+                D[17,73] = (-1)*var(86); // [ var(73) , var(17) ]
+                D[17,79] = (-1)*var(91); // [ var(79) , var(17) ]
+                D[17,82] = var(93); // [ var(82) , var(17) ]
+                D[17,87] = var(98); // [ var(87) , var(17) ]
+                D[17,92] = var(102); // [ var(92) , var(17) ]
+                D[17,96] = var(105); // [ var(96) , var(17) ]
+                D[17,106] = (-1)*var(112); // [ var(106) , var(17) ]
+                D[17,109] = var(115); // [ var(109) , var(17) ]
+                D[17,111] = (-1)*var(116); // [ var(111) , var(17) ]
+                D[18,22] = var(42); // [ var(22) , var(18) ]
+                D[18,27] = var(48); // [ var(27) , var(18) ]
+                D[18,31] = var(52); // [ var(31) , var(18) ]
+                D[18,35] = var(55); // [ var(35) , var(18) ]
+                D[18,39] = var(59); // [ var(39) , var(18) ]
+                D[18,43] = var(62); // [ var(43) , var(18) ]
+                D[18,47] = var(67); // [ var(47) , var(18) ]
+                D[18,51] = (-1)*var(69); // [ var(51) , var(18) ]
+                D[18,58] = (-1)*var(75); // [ var(58) , var(18) ]
+                D[18,65] = (-1)*var(81); // [ var(65) , var(18) ]
+                D[18,71] = var(85); // [ var(71) , var(18) ]
+                D[18,76] = var(89); // [ var(76) , var(18) ]
+                D[18,78] = var(90); // [ var(78) , var(18) ]
+                D[18,83] = var(94); // [ var(83) , var(18) ]
+                D[18,84] = var(95); // [ var(84) , var(18) ]
+                D[18,88] = var(99); // [ var(88) , var(18) ]
+                D[18,96] = (-1)*var(106); // [ var(96) , var(18) ]
+                D[18,105] = var(112); // [ var(105) , var(18) ]
+                D[18,107] = var(113); // [ var(107) , var(18) ]
+                D[18,114] = var(117); // [ var(114) , var(18) ]
+                D[19,22] = var(43); // [ var(22) , var(19) ]
+                D[19,23] = var(44); // [ var(23) , var(19) ]
+                D[19,26] = var(48); // [ var(26) , var(19) ]
+                D[19,34] = var(55); // [ var(34) , var(19) ]
+                D[19,38] = (-1)*var(57); // [ var(38) , var(19) ]
+                D[19,42] = var(62); // [ var(42) , var(19) ]
+                D[19,45] = (-1)*var(63); // [ var(45) , var(19) ]
+                D[19,46] = (-1)*var(64); // [ var(46) , var(19) ]
+                D[19,53] = (-1)*var(70); // [ var(53) , var(19) ]
+                D[19,54] = (-1)*var(72); // [ var(54) , var(19) ]
+                D[19,60] = (-1)*var(77); // [ var(60) , var(19) ]
+                D[19,66] = var(82); // [ var(66) , var(19) ]
+                D[19,73] = var(87); // [ var(73) , var(19) ]
+                D[19,79] = var(92); // [ var(79) , var(19) ]
+                D[19,80] = (-1)*var(93); // [ var(80) , var(19) ]
+                D[19,86] = (-1)*var(98); // [ var(86) , var(19) ]
+                D[19,91] = (-1)*var(102); // [ var(91) , var(19) ]
+                D[19,100] = var(108); // [ var(100) , var(19) ]
+                D[19,103] = var(110); // [ var(103) , var(19) ]
+                D[19,107] = (-1)*var(114); // [ var(107) , var(19) ]
+                D[19,113] = (-1)*var(117); // [ var(113) , var(19) ]
+                D[20,23] = var(45); // [ var(23) , var(20) ]
+                D[20,25] = var(48); // [ var(25) , var(20) ]
+                D[20,30] = var(52); // [ var(30) , var(20) ]
+                D[20,41] = (-1)*var(61); // [ var(41) , var(20) ]
+                D[20,44] = (-1)*var(63); // [ var(44) , var(20) ]
+                D[20,46] = (-1)*var(66); // [ var(46) , var(20) ]
+                D[20,50] = (-1)*var(68); // [ var(50) , var(20) ]
+                D[20,54] = (-1)*var(73); // [ var(54) , var(20) ]
+                D[20,58] = var(76); // [ var(58) , var(20) ]
+                D[20,64] = var(82); // [ var(64) , var(20) ]
+                D[20,65] = var(83); // [ var(65) , var(20) ]
+                D[20,72] = var(87); // [ var(72) , var(20) ]
+                D[20,75] = (-1)*var(89); // [ var(75) , var(20) ]
+                D[20,81] = (-1)*var(94); // [ var(81) , var(20) ]
+                D[20,84] = (-1)*var(96); // [ var(84) , var(20) ]
+                D[20,91] = var(103); // [ var(91) , var(20) ]
+                D[20,95] = var(106); // [ var(95) , var(20) ]
+                D[20,102] = (-1)*var(110); // [ var(102) , var(20) ]
+                D[20,104] = (-1)*var(111); // [ var(104) , var(20) ]
+                D[20,115] = var(118); // [ var(115) , var(20) ]
+                D[21,23] = (-1)*var(46); // [ var(23) , var(21) ]
+                D[21,32] = var(55); // [ var(32) , var(21) ]
+                D[21,37] = var(59); // [ var(37) , var(21) ]
+                D[21,40] = var(61); // [ var(40) , var(21) ]
+                D[21,44] = var(64); // [ var(44) , var(21) ]
+                D[21,45] = var(66); // [ var(45) , var(21) ]
+                D[21,51] = var(71); // [ var(51) , var(21) ]
+                D[21,56] = (-1)*var(74); // [ var(56) , var(21) ]
+                D[21,60] = (-1)*var(79); // [ var(60) , var(21) ]
+                D[21,63] = (-1)*var(82); // [ var(63) , var(21) ]
+                D[21,65] = (-1)*var(84); // [ var(65) , var(21) ]
+                D[21,69] = (-1)*var(85); // [ var(69) , var(21) ]
+                D[21,77] = var(92); // [ var(77) , var(21) ]
+                D[21,81] = var(95); // [ var(81) , var(21) ]
+                D[21,83] = var(96); // [ var(83) , var(21) ]
+                D[21,86] = var(100); // [ var(86) , var(21) ]
+                D[21,94] = (-1)*var(106); // [ var(94) , var(21) ]
+                D[21,98] = (-1)*var(108); // [ var(98) , var(21) ]
+                D[21,101] = (-1)*var(109); // [ var(101) , var(21) ]
+                D[21,116] = var(119); // [ var(116) , var(21) ]
+                D[22,24] = (-1)*var(47); // [ var(24) , var(22) ]
+                D[22,25] = (-1)*var(50); // [ var(25) , var(22) ]
+                D[22,30] = (-1)*var(54); // [ var(30) , var(22) ]
+                D[22,32] = (-1)*var(56); // [ var(32) , var(22) ]
+                D[22,37] = (-1)*var(60); // [ var(37) , var(22) ]
+                D[22,44] = (-1)*var(65); // [ var(44) , var(22) ]
+                D[22,48] = var(68); // [ var(48) , var(22) ]
+                D[22,52] = var(73); // [ var(52) , var(22) ]
+                D[22,55] = var(74); // [ var(55) , var(22) ]
+                D[22,57] = var(78); // [ var(57) , var(22) ]
+                D[22,59] = var(79); // [ var(59) , var(22) ]
+                D[22,63] = var(83); // [ var(63) , var(22) ]
+                D[22,64] = var(84); // [ var(64) , var(22) ]
+                D[22,69] = var(86); // [ var(69) , var(22) ]
+                D[22,70] = var(88); // [ var(70) , var(22) ]
+                D[22,75] = var(91); // [ var(75) , var(22) ]
+                D[22,82] = (-1)*var(96); // [ var(82) , var(22) ]
+                D[22,85] = (-1)*var(100); // [ var(85) , var(22) ]
+                D[22,89] = (-1)*var(103); // [ var(89) , var(22) ]
+                D[22,93] = (-1)*var(105); // [ var(93) , var(22) ]
+                D[22,97] = (-1)*var(107); // [ var(97) , var(22) ]
+                D[22,117] = var(120); // [ var(117) , var(22) ]
+                D[23,27] = (-1)*var(51); // [ var(27) , var(23) ]
+                D[23,28] = (-1)*var(53); // [ var(28) , var(23) ]
+                D[23,29] = var(54); // [ var(29) , var(23) ]
+                D[23,35] = (-1)*var(58); // [ var(35) , var(23) ]
+                D[23,36] = (-1)*var(60); // [ var(36) , var(23) ]
+                D[23,43] = (-1)*var(65); // [ var(43) , var(23) ]
+                D[23,48] = var(69); // [ var(48) , var(23) ]
+                D[23,55] = var(75); // [ var(55) , var(23) ]
+                D[23,61] = var(80); // [ var(61) , var(23) ]
+                D[23,62] = var(81); // [ var(62) , var(23) ]
+                D[23,68] = var(86); // [ var(68) , var(23) ]
+                D[23,74] = var(91); // [ var(74) , var(23) ]
+                D[23,82] = (-1)*var(97); // [ var(82) , var(23) ]
+                D[23,87] = (-1)*var(101); // [ var(87) , var(23) ]
+                D[23,92] = (-1)*var(104); // [ var(92) , var(23) ]
+                D[23,96] = (-1)*var(107); // [ var(96) , var(23) ]
+                D[23,106] = var(113); // [ var(106) , var(23) ]
+                D[23,108] = var(115); // [ var(108) , var(23) ]
+                D[23,110] = (-1)*var(116); // [ var(110) , var(23) ]
+                D[24,26] = var(52); // [ var(26) , var(24) ]
+                D[24,33] = var(57); // [ var(33) , var(24) ]
+                D[24,34] = var(59); // [ var(34) , var(24) ]
+                D[24,40] = var(63); // [ var(40) , var(24) ]
+                D[24,41] = var(64); // [ var(41) , var(24) ]
+                D[24,42] = var(67); // [ var(42) , var(24) ]
+                D[24,49] = var(70); // [ var(49) , var(24) ]
+                D[24,50] = var(72); // [ var(50) , var(24) ]
+                D[24,56] = var(77); // [ var(56) , var(24) ]
+                D[24,61] = (-1)*var(82); // [ var(61) , var(24) ]
+                D[24,68] = (-1)*var(87); // [ var(68) , var(24) ]
+                D[24,74] = (-1)*var(92); // [ var(74) , var(24) ]
+                D[24,80] = var(97); // [ var(80) , var(24) ]
+                D[24,86] = var(101); // [ var(86) , var(24) ]
+                D[24,91] = var(104); // [ var(91) , var(24) ]
+                D[24,100] = (-1)*var(109); // [ var(100) , var(24) ]
+                D[24,103] = (-1)*var(111); // [ var(103) , var(24) ]
+                D[24,105] = (-1)*var(114); // [ var(105) , var(24) ]
+                D[24,112] = (-1)*var(117); // [ var(112) , var(24) ]
+                D[25,28] = (-1)*var(55); // [ var(28) , var(25) ]
+                D[25,31] = var(57); // [ var(31) , var(25) ]
+                D[25,36] = (-1)*var(62); // [ var(36) , var(25) ]
+                D[25,39] = var(64); // [ var(39) , var(25) ]
+                D[25,45] = var(69); // [ var(45) , var(25) ]
+                D[25,47] = var(72); // [ var(47) , var(25) ]
+                D[25,53] = var(75); // [ var(53) , var(25) ]
+                D[25,60] = var(81); // [ var(60) , var(25) ]
+                D[25,66] = (-1)*var(85); // [ var(66) , var(25) ]
+                D[25,73] = (-1)*var(90); // [ var(73) , var(25) ]
+                D[25,76] = (-1)*var(93); // [ var(76) , var(25) ]
+                D[25,79] = (-1)*var(95); // [ var(79) , var(25) ]
+                D[25,83] = (-1)*var(98); // [ var(83) , var(25) ]
+                D[25,88] = (-1)*var(102); // [ var(88) , var(25) ]
+                D[25,96] = var(108); // [ var(96) , var(25) ]
+                D[25,103] = var(112); // [ var(103) , var(25) ]
+                D[25,107] = (-1)*var(115); // [ var(107) , var(25) ]
+                D[25,111] = var(117); // [ var(111) , var(25) ]
+                D[26,35] = var(61); // [ var(35) , var(26) ]
+                D[26,39] = var(66); // [ var(39) , var(26) ]
+                D[26,43] = var(68); // [ var(43) , var(26) ]
+                D[26,44] = var(69); // [ var(44) , var(26) ]
+                D[26,47] = var(73); // [ var(47) , var(26) ]
+                D[26,58] = (-1)*var(80); // [ var(58) , var(26) ]
+                D[26,64] = (-1)*var(85); // [ var(64) , var(26) ]
+                D[26,65] = (-1)*var(86); // [ var(65) , var(26) ]
+                D[26,70] = (-1)*var(89); // [ var(70) , var(26) ]
+                D[26,72] = (-1)*var(90); // [ var(72) , var(26) ]
+                D[26,77] = (-1)*var(94); // [ var(77) , var(26) ]
+                D[26,84] = var(100); // [ var(84) , var(26) ]
+                D[26,88] = var(103); // [ var(88) , var(26) ]
+                D[26,92] = var(106); // [ var(92) , var(26) ]
+                D[26,102] = (-1)*var(112); // [ var(102) , var(26) ]
+                D[26,104] = (-1)*var(113); // [ var(104) , var(26) ]
+                D[26,114] = (-1)*var(118); // [ var(114) , var(26) ]
+                D[27,30] = var(57); // [ var(30) , var(27) ]
+                D[27,34] = var(61); // [ var(34) , var(27) ]
+                D[27,37] = var(63); // [ var(37) , var(27) ]
+                D[27,42] = var(68); // [ var(42) , var(27) ]
+                D[27,46] = (-1)*var(71); // [ var(46) , var(27) ]
+                D[27,53] = (-1)*var(76); // [ var(53) , var(27) ]
+                D[27,54] = (-1)*var(78); // [ var(54) , var(27) ]
+                D[27,59] = (-1)*var(82); // [ var(59) , var(27) ]
+                D[27,60] = (-1)*var(83); // [ var(60) , var(27) ]
+                D[27,67] = (-1)*var(87); // [ var(67) , var(27) ]
+                D[27,75] = var(93); // [ var(75) , var(27) ]
+                D[27,79] = var(96); // [ var(79) , var(27) ]
+                D[27,81] = var(98); // [ var(81) , var(27) ]
+                D[27,91] = (-1)*var(105); // [ var(91) , var(27) ]
+                D[27,95] = (-1)*var(108); // [ var(95) , var(27) ]
+                D[27,99] = (-1)*var(110); // [ var(99) , var(27) ]
+                D[27,104] = var(114); // [ var(104) , var(27) ]
+                D[27,113] = var(118); // [ var(113) , var(27) ]
+                D[28,30] = var(59); // [ var(30) , var(28) ]
+                D[28,33] = var(61); // [ var(33) , var(28) ]
+                D[28,38] = var(66); // [ var(38) , var(28) ]
+                D[28,44] = (-1)*var(70); // [ var(44) , var(28) ]
+                D[28,50] = (-1)*var(74); // [ var(50) , var(28) ]
+                D[28,51] = (-1)*var(76); // [ var(51) , var(28) ]
+                D[28,54] = (-1)*var(79); // [ var(54) , var(28) ]
+                D[28,57] = (-1)*var(82); // [ var(57) , var(28) ]
+                D[28,65] = var(88); // [ var(65) , var(28) ]
+                D[28,69] = var(89); // [ var(69) , var(28) ]
+                D[28,72] = var(92); // [ var(72) , var(28) ]
+                D[28,78] = var(96); // [ var(78) , var(28) ]
+                D[28,81] = (-1)*var(99); // [ var(81) , var(28) ]
+                D[28,86] = (-1)*var(103); // [ var(86) , var(28) ]
+                D[28,90] = (-1)*var(106); // [ var(90) , var(28) ]
+                D[28,98] = var(110); // [ var(98) , var(28) ]
+                D[28,101] = var(111); // [ var(101) , var(28) ]
+                D[28,115] = (-1)*var(119); // [ var(115) , var(28) ]
+                D[29,32] = var(62); // [ var(32) , var(29) ]
+                D[29,37] = var(67); // [ var(37) , var(29) ]
+                D[29,40] = var(68); // [ var(40) , var(29) ]
+                D[29,44] = var(72); // [ var(44) , var(29) ]
+                D[29,45] = var(73); // [ var(45) , var(29) ]
+                D[29,49] = var(74); // [ var(49) , var(29) ]
+                D[29,51] = var(78); // [ var(51) , var(29) ]
+                D[29,53] = var(79); // [ var(53) , var(29) ]
+                D[29,58] = var(84); // [ var(58) , var(29) ]
+                D[29,63] = (-1)*var(87); // [ var(63) , var(29) ]
+                D[29,69] = (-1)*var(90); // [ var(69) , var(29) ]
+                D[29,70] = (-1)*var(92); // [ var(70) , var(29) ]
+                D[29,75] = (-1)*var(95); // [ var(75) , var(29) ]
+                D[29,76] = (-1)*var(96); // [ var(76) , var(29) ]
+                D[29,80] = (-1)*var(100); // [ var(80) , var(29) ]
+                D[29,89] = var(106); // [ var(89) , var(29) ]
+                D[29,93] = var(108); // [ var(93) , var(29) ]
+                D[29,97] = var(109); // [ var(97) , var(29) ]
+                D[29,116] = (-1)*var(120); // [ var(116) , var(29) ]
+                D[30,35] = (-1)*var(64); // [ var(35) , var(30) ]
+                D[30,36] = (-1)*var(67); // [ var(36) , var(30) ]
+                D[30,40] = (-1)*var(69); // [ var(40) , var(30) ]
+                D[30,43] = (-1)*var(72); // [ var(43) , var(30) ]
+                D[30,49] = (-1)*var(75); // [ var(49) , var(30) ]
+                D[30,56] = (-1)*var(81); // [ var(56) , var(30) ]
+                D[30,61] = var(85); // [ var(61) , var(30) ]
+                D[30,68] = var(90); // [ var(68) , var(30) ]
+                D[30,74] = var(95); // [ var(74) , var(30) ]
+                D[30,76] = var(97); // [ var(76) , var(30) ]
+                D[30,83] = var(101); // [ var(83) , var(30) ]
+                D[30,88] = var(104); // [ var(88) , var(30) ]
+                D[30,96] = (-1)*var(109); // [ var(96) , var(30) ]
+                D[30,103] = (-1)*var(113); // [ var(103) , var(30) ]
+                D[30,105] = (-1)*var(115); // [ var(105) , var(30) ]
+                D[30,110] = var(117); // [ var(110) , var(30) ]
+                D[31,32] = (-1)*var(63); // [ var(32) , var(31) ]
+                D[31,34] = var(66); // [ var(34) , var(31) ]
+                D[31,41] = var(71); // [ var(41) , var(31) ]
+                D[31,42] = var(73); // [ var(42) , var(31) ]
+                D[31,49] = var(76); // [ var(49) , var(31) ]
+                D[31,50] = var(78); // [ var(50) , var(31) ]
+                D[31,55] = var(82); // [ var(55) , var(31) ]
+                D[31,56] = var(83); // [ var(56) , var(31) ]
+                D[31,62] = var(87); // [ var(62) , var(31) ]
+                D[31,74] = (-1)*var(96); // [ var(74) , var(31) ]
+                D[31,75] = (-1)*var(97); // [ var(75) , var(31) ]
+                D[31,81] = (-1)*var(101); // [ var(81) , var(31) ]
+                D[31,91] = var(107); // [ var(91) , var(31) ]
+                D[31,95] = var(109); // [ var(95) , var(31) ]
+                D[31,99] = var(111); // [ var(99) , var(31) ]
+                D[31,102] = var(114); // [ var(102) , var(31) ]
+                D[31,112] = var(118); // [ var(112) , var(31) ]
+                D[32,38] = (-1)*var(69); // [ var(38) , var(32) ]
+                D[32,39] = var(70); // [ var(39) , var(32) ]
+                D[32,46] = (-1)*var(75); // [ var(46) , var(32) ]
+                D[32,47] = var(77); // [ var(47) , var(32) ]
+                D[32,54] = (-1)*var(81); // [ var(54) , var(32) ]
+                D[32,66] = (-1)*var(89); // [ var(66) , var(32) ]
+                D[32,71] = var(93); // [ var(71) , var(32) ]
+                D[32,73] = (-1)*var(94); // [ var(73) , var(32) ]
+                D[32,78] = var(98); // [ var(78) , var(32) ]
+                D[32,79] = (-1)*var(99); // [ var(79) , var(32) ]
+                D[32,84] = var(102); // [ var(84) , var(32) ]
+                D[32,96] = var(110); // [ var(96) , var(32) ]
+                D[32,100] = (-1)*var(112); // [ var(100) , var(32) ]
+                D[32,107] = var(116); // [ var(107) , var(32) ]
+                D[32,109] = (-1)*var(117); // [ var(109) , var(32) ]
+                D[33,36] = (-1)*var(68); // [ var(36) , var(33) ]
+                D[33,37] = (-1)*var(69); // [ var(37) , var(33) ]
+                D[33,39] = var(71); // [ var(39) , var(33) ]
+                D[33,47] = var(78); // [ var(47) , var(33) ]
+                D[33,53] = var(80); // [ var(53) , var(33) ]
+                D[33,59] = var(85); // [ var(59) , var(33) ]
+                D[33,60] = var(86); // [ var(60) , var(33) ]
+                D[33,67] = var(90); // [ var(67) , var(33) ]
+                D[33,70] = var(93); // [ var(70) , var(33) ]
+                D[33,77] = var(98); // [ var(77) , var(33) ]
+                D[33,79] = (-1)*var(100); // [ var(79) , var(33) ]
+                D[33,88] = (-1)*var(105); // [ var(88) , var(33) ]
+                D[33,92] = (-1)*var(108); // [ var(92) , var(33) ]
+                D[33,99] = (-1)*var(112); // [ var(99) , var(33) ]
+                D[33,104] = var(115); // [ var(104) , var(33) ]
+                D[33,111] = (-1)*var(118); // [ var(111) , var(33) ]
+                D[34,43] = var(74); // [ var(43) , var(34) ]
+                D[34,44] = var(75); // [ var(44) , var(34) ]
+                D[34,47] = var(79); // [ var(47) , var(34) ]
+                D[34,51] = var(80); // [ var(51) , var(34) ]
+                D[34,57] = var(85); // [ var(57) , var(34) ]
+                D[34,63] = var(89); // [ var(63) , var(34) ]
+                D[34,65] = (-1)*var(91); // [ var(65) , var(34) ]
+                D[34,72] = (-1)*var(95); // [ var(72) , var(34) ]
+                D[34,77] = (-1)*var(99); // [ var(77) , var(34) ]
+                D[34,78] = (-1)*var(100); // [ var(78) , var(34) ]
+                D[34,83] = (-1)*var(103); // [ var(83) , var(34) ]
+                D[34,87] = (-1)*var(106); // [ var(87) , var(34) ]
+                D[34,98] = var(112); // [ var(98) , var(34) ]
+                D[34,101] = var(113); // [ var(101) , var(34) ]
+                D[34,114] = var(119); // [ var(114) , var(34) ]
+                D[35,37] = var(70); // [ var(37) , var(35) ]
+                D[35,38] = var(71); // [ var(38) , var(35) ]
+                D[35,42] = var(74); // [ var(42) , var(35) ]
+                D[35,45] = var(76); // [ var(45) , var(35) ]
+                D[35,52] = var(82); // [ var(52) , var(35) ]
+                D[35,54] = (-1)*var(84); // [ var(54) , var(35) ]
+                D[35,60] = (-1)*var(88); // [ var(60) , var(35) ]
+                D[35,67] = (-1)*var(92); // [ var(67) , var(35) ]
+                D[35,69] = (-1)*var(93); // [ var(69) , var(35) ]
+                D[35,73] = (-1)*var(96); // [ var(73) , var(35) ]
+                D[35,81] = var(102); // [ var(81) , var(35) ]
+                D[35,86] = var(105); // [ var(86) , var(35) ]
+                D[35,90] = var(108); // [ var(90) , var(35) ]
+                D[35,94] = var(110); // [ var(94) , var(35) ]
+                D[35,101] = (-1)*var(114); // [ var(101) , var(35) ]
+                D[35,113] = (-1)*var(119); // [ var(113) , var(35) ]
+                D[36,38] = var(73); // [ var(38) , var(36) ]
+                D[36,41] = var(74); // [ var(41) , var(36) ]
+                D[36,44] = (-1)*var(77); // [ var(44) , var(36) ]
+                D[36,46] = var(79); // [ var(46) , var(36) ]
+                D[36,51] = (-1)*var(83); // [ var(51) , var(36) ]
+                D[36,57] = (-1)*var(87); // [ var(57) , var(36) ]
+                D[36,58] = (-1)*var(88); // [ var(58) , var(36) ]
+                D[36,64] = (-1)*var(92); // [ var(64) , var(36) ]
+                D[36,69] = var(94); // [ var(69) , var(36) ]
+                D[36,71] = (-1)*var(96); // [ var(71) , var(36) ]
+                D[36,75] = var(99); // [ var(75) , var(36) ]
+                D[36,80] = var(103); // [ var(80) , var(36) ]
+                D[36,85] = var(106); // [ var(85) , var(36) ]
+                D[36,93] = (-1)*var(110); // [ var(93) , var(36) ]
+                D[36,97] = (-1)*var(111); // [ var(97) , var(36) ]
+                D[36,115] = var(120); // [ var(115) , var(36) ]
+                D[37,41] = var(75); // [ var(41) , var(37) ]
+                D[37,43] = (-1)*var(77); // [ var(43) , var(37) ]
+                D[37,50] = var(81); // [ var(50) , var(37) ]
+                D[37,61] = var(89); // [ var(61) , var(37) ]
+                D[37,68] = var(94); // [ var(68) , var(37) ]
+                D[37,71] = (-1)*var(97); // [ var(71) , var(37) ]
+                D[37,74] = var(99); // [ var(74) , var(37) ]
+                D[37,78] = (-1)*var(101); // [ var(78) , var(37) ]
+                D[37,84] = (-1)*var(104); // [ var(84) , var(37) ]
+                D[37,96] = (-1)*var(111); // [ var(96) , var(37) ]
+                D[37,100] = var(113); // [ var(100) , var(37) ]
+                D[37,105] = var(116); // [ var(105) , var(37) ]
+                D[37,108] = (-1)*var(117); // [ var(108) , var(37) ]
+                D[38,43] = (-1)*var(78); // [ var(43) , var(38) ]
+                D[38,49] = (-1)*var(80); // [ var(49) , var(38) ]
+                D[38,55] = (-1)*var(85); // [ var(55) , var(38) ]
+                D[38,56] = (-1)*var(86); // [ var(56) , var(38) ]
+                D[38,62] = (-1)*var(90); // [ var(62) , var(38) ]
+                D[38,70] = (-1)*var(97); // [ var(70) , var(38) ]
+                D[38,74] = var(100); // [ var(74) , var(38) ]
+                D[38,77] = (-1)*var(101); // [ var(77) , var(38) ]
+                D[38,88] = var(107); // [ var(88) , var(38) ]
+                D[38,92] = var(109); // [ var(92) , var(38) ]
+                D[38,99] = var(113); // [ var(99) , var(38) ]
+                D[38,102] = var(115); // [ var(102) , var(38) ]
+                D[38,110] = (-1)*var(118); // [ var(110) , var(38) ]
+                D[39,40] = (-1)*var(76); // [ var(40) , var(39) ]
+                D[39,42] = var(79); // [ var(42) , var(39) ]
+                D[39,48] = (-1)*var(82); // [ var(48) , var(39) ]
+                D[39,50] = var(84); // [ var(50) , var(39) ]
+                D[39,56] = var(88); // [ var(56) , var(39) ]
+                D[39,62] = var(92); // [ var(62) , var(39) ]
+                D[39,68] = var(96); // [ var(68) , var(39) ]
+                D[39,69] = var(97); // [ var(69) , var(39) ]
+                D[39,81] = (-1)*var(104); // [ var(81) , var(39) ]
+                D[39,86] = (-1)*var(107); // [ var(86) , var(39) ]
+                D[39,90] = (-1)*var(109); // [ var(90) , var(39) ]
+                D[39,94] = (-1)*var(111); // [ var(94) , var(39) ]
+                D[39,98] = (-1)*var(114); // [ var(98) , var(39) ]
+                D[39,112] = (-1)*var(119); // [ var(112) , var(39) ]
+                D[40,46] = (-1)*var(80); // [ var(46) , var(40) ]
+                D[40,47] = var(83); // [ var(47) , var(40) ]
+                D[40,54] = (-1)*var(86); // [ var(54) , var(40) ]
+                D[40,59] = var(89); // [ var(59) , var(40) ]
+                D[40,64] = (-1)*var(93); // [ var(64) , var(40) ]
+                D[40,67] = var(94); // [ var(67) , var(40) ]
+                D[40,72] = (-1)*var(98); // [ var(72) , var(40) ]
+                D[40,79] = (-1)*var(103); // [ var(79) , var(40) ]
+                D[40,84] = var(105); // [ var(84) , var(40) ]
+                D[40,92] = (-1)*var(110); // [ var(92) , var(40) ]
+                D[40,95] = var(112); // [ var(95) , var(40) ]
+                D[40,104] = (-1)*var(116); // [ var(104) , var(40) ]
+                D[40,109] = var(118); // [ var(109) , var(40) ]
+                D[41,45] = (-1)*var(80); // [ var(45) , var(41) ]
+                D[41,47] = var(84); // [ var(47) , var(41) ]
+                D[41,52] = (-1)*var(85); // [ var(52) , var(41) ]
+                D[41,60] = var(91); // [ var(60) , var(41) ]
+                D[41,63] = (-1)*var(93); // [ var(63) , var(41) ]
+                D[41,67] = var(95); // [ var(67) , var(41) ]
+                D[41,73] = var(100); // [ var(73) , var(41) ]
+                D[41,77] = var(102); // [ var(77) , var(41) ]
+                D[41,83] = var(105); // [ var(83) , var(41) ]
+                D[41,87] = var(108); // [ var(87) , var(41) ]
+                D[41,94] = var(112); // [ var(94) , var(41) ]
+                D[41,101] = (-1)*var(115); // [ var(101) , var(41) ]
+                D[41,111] = var(119); // [ var(111) , var(41) ]
+                D[42,44] = var(81); // [ var(44) , var(42) ]
+                D[42,51] = var(86); // [ var(51) , var(42) ]
+                D[42,57] = var(90); // [ var(57) , var(42) ]
+                D[42,58] = var(91); // [ var(58) , var(42) ]
+                D[42,63] = var(94); // [ var(63) , var(42) ]
+                D[42,64] = var(95); // [ var(64) , var(42) ]
+                D[42,70] = var(99); // [ var(70) , var(42) ]
+                D[42,71] = var(100); // [ var(71) , var(42) ]
+                D[42,76] = var(103); // [ var(76) , var(42) ]
+                D[42,82] = var(106); // [ var(82) , var(42) ]
+                D[42,93] = (-1)*var(112); // [ var(93) , var(42) ]
+                D[42,97] = (-1)*var(113); // [ var(97) , var(42) ]
+                D[42,114] = (-1)*var(120); // [ var(114) , var(42) ]
+                D[43,45] = var(83); // [ var(45) , var(43) ]
+                D[43,46] = var(84); // [ var(46) , var(43) ]
+                D[43,52] = var(87); // [ var(52) , var(43) ]
+                D[43,53] = var(88); // [ var(53) , var(43) ]
+                D[43,59] = var(92); // [ var(59) , var(43) ]
+                D[43,66] = var(96); // [ var(66) , var(43) ]
+                D[43,69] = (-1)*var(98); // [ var(69) , var(43) ]
+                D[43,75] = (-1)*var(102); // [ var(75) , var(43) ]
+                D[43,80] = (-1)*var(105); // [ var(80) , var(43) ]
+                D[43,85] = (-1)*var(108); // [ var(85) , var(43) ]
+                D[43,89] = (-1)*var(110); // [ var(89) , var(43) ]
+                D[43,97] = var(114); // [ var(97) , var(43) ]
+                D[43,113] = var(120); // [ var(113) , var(43) ]
+                D[44,61] = (-1)*var(93); // [ var(61) , var(44) ]
+                D[44,66] = var(97); // [ var(66) , var(44) ]
+                D[44,68] = (-1)*var(98); // [ var(68) , var(44) ]
+                D[44,73] = var(101); // [ var(73) , var(44) ]
+                D[44,74] = (-1)*var(102); // [ var(74) , var(44) ]
+                D[44,79] = var(104); // [ var(79) , var(44) ]
+                D[44,96] = var(114); // [ var(96) , var(44) ]
+                D[44,100] = (-1)*var(115); // [ var(100) , var(44) ]
+                D[44,103] = var(116); // [ var(103) , var(44) ]
+                D[44,106] = (-1)*var(117); // [ var(106) , var(44) ]
+                D[45,50] = var(86); // [ var(50) , var(45) ]
+                D[45,55] = (-1)*var(89); // [ var(55) , var(45) ]
+                D[45,62] = (-1)*var(94); // [ var(62) , var(45) ]
+                D[45,64] = var(97); // [ var(64) , var(45) ]
+                D[45,72] = var(101); // [ var(72) , var(45) ]
+                D[45,74] = var(103); // [ var(74) , var(45) ]
+                D[45,84] = (-1)*var(107); // [ var(84) , var(45) ]
+                D[45,92] = var(111); // [ var(92) , var(45) ]
+                D[45,95] = (-1)*var(113); // [ var(95) , var(45) ]
+                D[45,102] = (-1)*var(116); // [ var(102) , var(45) ]
+                D[45,108] = var(118); // [ var(108) , var(45) ]
+                D[46,48] = var(85); // [ var(48) , var(46) ]
+                D[46,56] = (-1)*var(91); // [ var(56) , var(46) ]
+                D[46,62] = (-1)*var(95); // [ var(62) , var(46) ]
+                D[46,63] = var(97); // [ var(63) , var(46) ]
+                D[46,68] = (-1)*var(100); // [ var(68) , var(46) ]
+                D[46,77] = (-1)*var(104); // [ var(77) , var(46) ]
+                D[46,83] = (-1)*var(107); // [ var(83) , var(46) ]
+                D[46,87] = (-1)*var(109); // [ var(87) , var(46) ]
+                D[46,94] = (-1)*var(113); // [ var(94) , var(46) ]
+                D[46,98] = (-1)*var(115); // [ var(98) , var(46) ]
+                D[46,110] = var(119); // [ var(110) , var(46) ]
+                D[47,48] = (-1)*var(87); // [ var(48) , var(47) ]
+                D[47,49] = (-1)*var(88); // [ var(49) , var(47) ]
+                D[47,55] = (-1)*var(92); // [ var(55) , var(47) ]
+                D[47,61] = (-1)*var(96); // [ var(61) , var(47) ]
+                D[47,69] = var(101); // [ var(69) , var(47) ]
+                D[47,75] = var(104); // [ var(75) , var(47) ]
+                D[47,80] = var(107); // [ var(80) , var(47) ]
+                D[47,85] = var(109); // [ var(85) , var(47) ]
+                D[47,89] = var(111); // [ var(89) , var(47) ]
+                D[47,93] = var(114); // [ var(93) , var(47) ]
+                D[47,112] = var(120); // [ var(112) , var(47) ]
+                D[48,53] = (-1)*var(89); // [ var(53) , var(48) ]
+                D[48,54] = (-1)*var(90); // [ var(54) , var(48) ]
+                D[48,58] = var(93); // [ var(58) , var(48) ]
+                D[48,60] = (-1)*var(94); // [ var(60) , var(48) ]
+                D[48,65] = var(98); // [ var(65) , var(48) ]
+                D[48,79] = (-1)*var(106); // [ var(79) , var(48) ]
+                D[48,84] = var(108); // [ var(84) , var(48) ]
+                D[48,88] = var(110); // [ var(88) , var(48) ]
+                D[48,91] = (-1)*var(112); // [ var(91) , var(48) ]
+                D[48,104] = var(117); // [ var(104) , var(48) ]
+                D[48,107] = (-1)*var(118); // [ var(107) , var(48) ]
+                D[49,52] = (-1)*var(89); // [ var(52) , var(49) ]
+                D[49,54] = (-1)*var(91); // [ var(54) , var(49) ]
+                D[49,57] = var(93); // [ var(57) , var(49) ]
+                D[49,67] = var(99); // [ var(67) , var(49) ]
+                D[49,72] = (-1)*var(102); // [ var(72) , var(49) ]
+                D[49,73] = var(103); // [ var(73) , var(49) ]
+                D[49,78] = (-1)*var(105); // [ var(78) , var(49) ]
+                D[49,87] = var(110); // [ var(87) , var(49) ]
+                D[49,90] = (-1)*var(112); // [ var(90) , var(49) ]
+                D[49,101] = var(116); // [ var(101) , var(49) ]
+                D[49,109] = (-1)*var(119); // [ var(109) , var(49) ]
+                D[50,52] = (-1)*var(90); // [ var(52) , var(50) ]
+                D[50,53] = (-1)*var(91); // [ var(53) , var(50) ]
+                D[50,59] = (-1)*var(95); // [ var(59) , var(50) ]
+                D[50,63] = (-1)*var(98); // [ var(63) , var(50) ]
+                D[50,66] = (-1)*var(100); // [ var(66) , var(50) ]
+                D[50,70] = (-1)*var(102); // [ var(70) , var(50) ]
+                D[50,76] = (-1)*var(105); // [ var(76) , var(50) ]
+                D[50,82] = (-1)*var(108); // [ var(82) , var(50) ]
+                D[50,89] = (-1)*var(112); // [ var(89) , var(50) ]
+                D[50,97] = var(115); // [ var(97) , var(50) ]
+                D[50,111] = (-1)*var(120); // [ var(111) , var(50) ]
+                D[51,55] = var(93); // [ var(55) , var(51) ]
+                D[51,59] = (-1)*var(97); // [ var(59) , var(51) ]
+                D[51,62] = var(98); // [ var(62) , var(51) ]
+                D[51,67] = (-1)*var(101); // [ var(67) , var(51) ]
+                D[51,74] = (-1)*var(105); // [ var(74) , var(51) ]
+                D[51,79] = var(107); // [ var(79) , var(51) ]
+                D[51,92] = (-1)*var(114); // [ var(92) , var(51) ]
+                D[51,95] = var(115); // [ var(95) , var(51) ]
+                D[51,99] = (-1)*var(116); // [ var(99) , var(51) ]
+                D[51,106] = var(118); // [ var(106) , var(51) ]
+                D[52,56] = var(94); // [ var(56) , var(52) ]
+                D[52,58] = (-1)*var(97); // [ var(58) , var(52) ]
+                D[52,65] = (-1)*var(101); // [ var(65) , var(52) ]
+                D[52,74] = var(106); // [ var(74) , var(52) ]
+                D[52,84] = (-1)*var(109); // [ var(84) , var(52) ]
+                D[52,88] = (-1)*var(111); // [ var(88) , var(52) ]
+                D[52,91] = var(113); // [ var(91) , var(52) ]
+                D[52,102] = var(117); // [ var(102) , var(52) ]
+                D[52,105] = (-1)*var(118); // [ var(105) , var(52) ]
+                D[53,57] = (-1)*var(97); // [ var(57) , var(53) ]
+                D[53,62] = (-1)*var(99); // [ var(62) , var(53) ]
+                D[53,68] = (-1)*var(103); // [ var(68) , var(53) ]
+                D[53,72] = var(104); // [ var(72) , var(53) ]
+                D[53,78] = var(107); // [ var(78) , var(53) ]
+                D[53,87] = (-1)*var(111); // [ var(87) , var(53) ]
+                D[53,90] = var(113); // [ var(90) , var(53) ]
+                D[53,98] = var(116); // [ var(98) , var(53) ]
+                D[53,108] = (-1)*var(119); // [ var(108) , var(53) ]
+                D[54,55] = var(95); // [ var(55) , var(54) ]
+                D[54,61] = var(100); // [ var(61) , var(54) ]
+                D[54,63] = var(101); // [ var(63) , var(54) ]
+                D[54,70] = var(104); // [ var(70) , var(54) ]
+                D[54,76] = var(107); // [ var(76) , var(54) ]
+                D[54,82] = var(109); // [ var(82) , var(54) ]
+                D[54,89] = var(113); // [ var(89) , var(54) ]
+                D[54,93] = var(115); // [ var(93) , var(54) ]
+                D[54,110] = (-1)*var(120); // [ var(110) , var(54) ]
+                D[55,60] = (-1)*var(99); // [ var(60) , var(55) ]
+                D[55,65] = var(102); // [ var(65) , var(55) ]
+                D[55,73] = var(106); // [ var(73) , var(55) ]
+                D[55,78] = (-1)*var(108); // [ var(78) , var(55) ]
+                D[55,83] = (-1)*var(110); // [ var(83) , var(55) ]
+                D[55,86] = var(112); // [ var(86) , var(55) ]
+                D[55,101] = (-1)*var(117); // [ var(101) , var(55) ]
+                D[55,107] = var(119); // [ var(107) , var(55) ]
+                D[56,57] = var(98); // [ var(57) , var(56) ]
+                D[56,59] = (-1)*var(99); // [ var(59) , var(56) ]
+                D[56,64] = var(102); // [ var(64) , var(56) ]
+                D[56,66] = (-1)*var(103); // [ var(66) , var(56) ]
+                D[56,71] = var(105); // [ var(71) , var(56) ]
+                D[56,82] = (-1)*var(110); // [ var(82) , var(56) ]
+                D[56,85] = var(112); // [ var(85) , var(56) ]
+                D[56,97] = (-1)*var(116); // [ var(97) , var(56) ]
+                D[56,109] = var(120); // [ var(109) , var(56) ]
+                D[57,60] = var(101); // [ var(60) , var(57) ]
+                D[57,74] = (-1)*var(108); // [ var(74) , var(57) ]
+                D[57,79] = var(109); // [ var(79) , var(57) ]
+                D[57,88] = var(114); // [ var(88) , var(57) ]
+                D[57,91] = (-1)*var(115); // [ var(91) , var(57) ]
+                D[57,99] = var(117); // [ var(99) , var(57) ]
+                D[57,103] = (-1)*var(118); // [ var(103) , var(57) ]
+                D[58,62] = var(102); // [ var(62) , var(58) ]
+                D[58,67] = (-1)*var(104); // [ var(67) , var(58) ]
+                D[58,68] = var(105); // [ var(68) , var(58) ]
+                D[58,73] = (-1)*var(107); // [ var(73) , var(58) ]
+                D[58,87] = var(114); // [ var(87) , var(58) ]
+                D[58,90] = (-1)*var(115); // [ var(90) , var(58) ]
+                D[58,94] = var(116); // [ var(94) , var(58) ]
+                D[58,106] = (-1)*var(119); // [ var(106) , var(58) ]
+                D[59,65] = (-1)*var(104); // [ var(65) , var(59) ]
+                D[59,68] = (-1)*var(106); // [ var(68) , var(59) ]
+                D[59,78] = var(109); // [ var(78) , var(59) ]
+                D[59,83] = var(111); // [ var(83) , var(59) ]
+                D[59,86] = (-1)*var(113); // [ var(86) , var(59) ]
+                D[59,98] = (-1)*var(117); // [ var(98) , var(59) ]
+                D[59,105] = var(119); // [ var(105) , var(59) ]
+                D[60,61] = var(103); // [ var(61) , var(60) ]
+                D[60,64] = (-1)*var(104); // [ var(64) , var(60) ]
+                D[60,71] = (-1)*var(107); // [ var(71) , var(60) ]
+                D[60,82] = var(111); // [ var(82) , var(60) ]
+                D[60,85] = (-1)*var(113); // [ var(85) , var(60) ]
+                D[60,93] = (-1)*var(116); // [ var(93) , var(60) ]
+                D[60,108] = var(120); // [ var(108) , var(60) ]
+                D[61,65] = var(105); // [ var(65) , var(61) ]
+                D[61,67] = (-1)*var(106); // [ var(67) , var(61) ]
+                D[61,72] = var(108); // [ var(72) , var(61) ]
+                D[61,77] = var(110); // [ var(77) , var(61) ]
+                D[61,81] = (-1)*var(112); // [ var(81) , var(61) ]
+                D[61,101] = var(118); // [ var(101) , var(61) ]
+                D[61,104] = (-1)*var(119); // [ var(104) , var(61) ]
+                D[62,66] = (-1)*var(106); // [ var(66) , var(62) ]
+                D[62,71] = var(108); // [ var(71) , var(62) ]
+                D[62,76] = var(110); // [ var(76) , var(62) ]
+                D[62,80] = (-1)*var(112); // [ var(80) , var(62) ]
+                D[62,97] = var(117); // [ var(97) , var(62) ]
+                D[62,107] = (-1)*var(120); // [ var(107) , var(62) ]
+                D[63,74] = (-1)*var(110); // [ var(74) , var(63) ]
+                D[63,79] = var(111); // [ var(79) , var(63) ]
+                D[63,84] = (-1)*var(114); // [ var(84) , var(63) ]
+                D[63,91] = var(116); // [ var(91) , var(63) ]
+                D[63,95] = (-1)*var(117); // [ var(95) , var(63) ]
+                D[63,100] = var(118); // [ var(100) , var(63) ]
+                D[64,68] = var(108); // [ var(68) , var(64) ]
+                D[64,73] = (-1)*var(109); // [ var(73) , var(64) ]
+                D[64,83] = (-1)*var(114); // [ var(83) , var(64) ]
+                D[64,86] = var(115); // [ var(86) , var(64) ]
+                D[64,94] = (-1)*var(117); // [ var(94) , var(64) ]
+                D[64,103] = var(119); // [ var(103) , var(64) ]
+                D[65,66] = var(107); // [ var(66) , var(65) ]
+                D[65,82] = (-1)*var(114); // [ var(82) , var(65) ]
+                D[65,85] = var(115); // [ var(85) , var(65) ]
+                D[65,89] = (-1)*var(116); // [ var(89) , var(65) ]
+                D[65,106] = var(120); // [ var(106) , var(65) ]
+                D[66,72] = (-1)*var(109); // [ var(72) , var(66) ]
+                D[66,77] = (-1)*var(111); // [ var(77) , var(66) ]
+                D[66,81] = var(113); // [ var(81) , var(66) ]
+                D[66,98] = var(118); // [ var(98) , var(66) ]
+                D[66,102] = (-1)*var(119); // [ var(102) , var(66) ]
+                D[67,71] = (-1)*var(109); // [ var(71) , var(67) ]
+                D[67,76] = (-1)*var(111); // [ var(76) , var(67) ]
+                D[67,80] = var(113); // [ var(80) , var(67) ]
+                D[67,93] = var(117); // [ var(93) , var(67) ]
+                D[67,105] = (-1)*var(120); // [ var(105) , var(67) ]
+                D[68,70] = (-1)*var(110); // [ var(70) , var(68) ]
+                D[68,75] = var(112); // [ var(75) , var(68) ]
+                D[68,97] = (-1)*var(118); // [ var(97) , var(68) ]
+                D[68,104] = var(120); // [ var(104) , var(68) ]
+                D[69,74] = var(112); // [ var(74) , var(69) ]
+                D[69,79] = (-1)*var(113); // [ var(79) , var(69) ]
+                D[69,84] = var(115); // [ var(84) , var(69) ]
+                D[69,88] = (-1)*var(116); // [ var(88) , var(69) ]
+                D[69,92] = var(117); // [ var(92) , var(69) ]
+                D[69,96] = (-1)*var(118); // [ var(96) , var(69) ]
+                D[70,73] = (-1)*var(111); // [ var(73) , var(70) ]
+                D[70,78] = var(114); // [ var(78) , var(70) ]
+                D[70,86] = (-1)*var(116); // [ var(86) , var(70) ]
+                D[70,90] = var(117); // [ var(90) , var(70) ]
+                D[70,100] = (-1)*var(119); // [ var(100) , var(70) ]
+                D[71,77] = var(114); // [ var(77) , var(71) ]
+                D[71,81] = (-1)*var(115); // [ var(81) , var(71) ]
+                D[71,94] = var(118); // [ var(94) , var(71) ]
+                D[71,99] = (-1)*var(119); // [ var(99) , var(71) ]
+                D[72,76] = var(114); // [ var(76) , var(72) ]
+                D[72,80] = (-1)*var(115); // [ var(80) , var(72) ]
+                D[72,89] = var(117); // [ var(89) , var(72) ]
+                D[72,103] = (-1)*var(120); // [ var(103) , var(72) ]
+                D[73,75] = (-1)*var(113); // [ var(75) , var(73) ]
+                D[73,93] = (-1)*var(118); // [ var(93) , var(73) ]
+                D[73,102] = var(120); // [ var(102) , var(73) ]
+                D[74,97] = var(119); // [ var(97) , var(74) ]
+                D[74,101] = (-1)*var(120); // [ var(101) , var(74) ]
+                D[75,78] = (-1)*var(115); // [ var(78) , var(75) ]
+                D[75,83] = var(116); // [ var(83) , var(75) ]
+                D[75,87] = (-1)*var(117); // [ var(87) , var(75) ]
+                D[75,96] = var(119); // [ var(96) , var(75) ]
+                D[76,81] = var(116); // [ var(81) , var(76) ]
+                D[76,90] = (-1)*var(118); // [ var(90) , var(76) ]
+                D[76,95] = var(119); // [ var(95) , var(76) ]
+                D[77,80] = var(116); // [ var(80) , var(77) ]
+                D[77,85] = (-1)*var(117); // [ var(85) , var(77) ]
+                D[77,100] = var(120); // [ var(100) , var(77) ]
+                D[78,89] = (-1)*var(118); // [ var(89) , var(78) ]
+                D[78,99] = var(120); // [ var(99) , var(78) ]
+                D[79,93] = var(119); // [ var(93) , var(79) ]
+                D[79,98] = (-1)*var(120); // [ var(98) , var(79) ]
+                D[80,87] = var(118); // [ var(87) , var(80) ]
+                D[80,92] = (-1)*var(119); // [ var(92) , var(80) ]
+                D[81,82] = var(117); // [ var(82) , var(81) ]
+                D[81,96] = (-1)*var(120); // [ var(96) , var(81) ]
+                D[82,86] = var(118); // [ var(86) , var(82) ]
+                D[82,91] = (-1)*var(119); // [ var(91) , var(82) ]
+                D[83,85] = var(118); // [ var(85) , var(83) ]
+                D[83,95] = (-1)*var(120); // [ var(95) , var(83) ]
+                D[84,89] = var(119); // [ var(89) , var(84) ]
+                D[84,94] = (-1)*var(120); // [ var(94) , var(84) ]
+                D[85,88] = var(119); // [ var(88) , var(85) ]
+                D[86,92] = var(120); // [ var(92) , var(86) ]
+                D[87,91] = var(120); // [ var(91) , var(87) ]
+                D[88,90] = var(120); // [ var(90) , var(88) ]
+        // Y(i) * Y(j):
+                D[121,123] = (-1)*var(129); // [ var(123) , var(121) ]
+                D[121,131] = (-1)*var(136); // [ var(131) , var(121) ]
+                D[121,137] = (-1)*var(143); // [ var(137) , var(121) ]
+                D[121,139] = (-1)*var(144); // [ var(139) , var(121) ]
+                D[121,145] = (-1)*var(150); // [ var(145) , var(121) ]
+                D[121,147] = (-1)*var(151); // [ var(147) , var(121) ]
+                D[121,152] = (-1)*var(157); // [ var(152) , var(121) ]
+                D[121,153] = (-1)*var(158); // [ var(153) , var(121) ]
+                D[121,155] = (-1)*var(159); // [ var(155) , var(121) ]
+                D[121,160] = (-1)*var(165); // [ var(160) , var(121) ]
+                D[121,161] = (-1)*var(166); // [ var(161) , var(121) ]
+                D[121,163] = (-1)*var(167); // [ var(163) , var(121) ]
+                D[121,168] = (-1)*var(172); // [ var(168) , var(121) ]
+                D[121,169] = (-1)*var(173); // [ var(169) , var(121) ]
+                D[121,170] = (-1)*var(174); // [ var(170) , var(121) ]
+                D[121,175] = (-1)*var(179); // [ var(175) , var(121) ]
+                D[121,176] = (-1)*var(180); // [ var(176) , var(121) ]
+                D[121,181] = (-1)*var(186); // [ var(181) , var(121) ]
+                D[121,182] = (-1)*var(187); // [ var(182) , var(121) ]
+                D[121,188] = (-1)*var(193); // [ var(188) , var(121) ]
+                D[121,194] = (-1)*var(199); // [ var(194) , var(121) ]
+                D[121,213] = var(217); // [ var(213) , var(121) ]
+                D[121,218] = var(221); // [ var(218) , var(121) ]
+                D[121,222] = var(224); // [ var(222) , var(121) ]
+                D[121,225] = var(227); // [ var(225) , var(121) ]
+                D[121,228] = var(229); // [ var(228) , var(121) ]
+                D[121,230] = var(231); // [ var(230) , var(121) ]
+                D[121,232] = var(233); // [ var(232) , var(121) ]
+                D[122,124] = (-1)*var(130); // [ var(124) , var(122) ]
+                D[122,131] = (-1)*var(137); // [ var(131) , var(122) ]
+                D[122,132] = (-1)*var(138); // [ var(132) , var(122) ]
+                D[122,136] = (-1)*var(143); // [ var(136) , var(122) ]
+                D[122,139] = (-1)*var(145); // [ var(139) , var(122) ]
+                D[122,140] = (-1)*var(146); // [ var(140) , var(122) ]
+                D[122,144] = (-1)*var(150); // [ var(144) , var(122) ]
+                D[122,147] = (-1)*var(153); // [ var(147) , var(122) ]
+                D[122,148] = (-1)*var(154); // [ var(148) , var(122) ]
+                D[122,151] = (-1)*var(158); // [ var(151) , var(122) ]
+                D[122,155] = (-1)*var(161); // [ var(155) , var(122) ]
+                D[122,156] = (-1)*var(162); // [ var(156) , var(122) ]
+                D[122,159] = (-1)*var(166); // [ var(159) , var(122) ]
+                D[122,163] = (-1)*var(170); // [ var(163) , var(122) ]
+                D[122,167] = (-1)*var(174); // [ var(167) , var(122) ]
+                D[122,183] = var(189); // [ var(183) , var(122) ]
+                D[122,190] = var(195); // [ var(190) , var(122) ]
+                D[122,196] = var(200); // [ var(196) , var(122) ]
+                D[122,197] = var(201); // [ var(197) , var(122) ]
+                D[122,202] = var(205); // [ var(202) , var(122) ]
+                D[122,203] = var(206); // [ var(203) , var(122) ]
+                D[122,207] = var(210); // [ var(207) , var(122) ]
+                D[122,208] = var(211); // [ var(208) , var(122) ]
+                D[122,212] = var(215); // [ var(212) , var(122) ]
+                D[122,216] = var(220); // [ var(216) , var(122) ]
+                D[122,230] = (-1)*var(232); // [ var(230) , var(122) ]
+                D[122,231] = (-1)*var(233); // [ var(231) , var(122) ]
+                D[122,234] = (-1)*var(235); // [ var(234) , var(122) ]
+                D[123,124] = (-1)*var(131); // [ var(124) , var(123) ]
+                D[123,130] = (-1)*var(137); // [ var(130) , var(123) ]
+                D[123,132] = (-1)*var(139); // [ var(132) , var(123) ]
+                D[123,138] = (-1)*var(145); // [ var(138) , var(123) ]
+                D[123,140] = (-1)*var(147); // [ var(140) , var(123) ]
+                D[123,146] = (-1)*var(153); // [ var(146) , var(123) ]
+                D[123,148] = (-1)*var(155); // [ var(148) , var(123) ]
+                D[123,154] = (-1)*var(161); // [ var(154) , var(123) ]
+                D[123,156] = (-1)*var(163); // [ var(156) , var(123) ]
+                D[123,157] = (-1)*var(164); // [ var(157) , var(123) ]
+                D[123,162] = (-1)*var(170); // [ var(162) , var(123) ]
+                D[123,165] = (-1)*var(171); // [ var(165) , var(123) ]
+                D[123,172] = (-1)*var(177); // [ var(172) , var(123) ]
+                D[123,173] = (-1)*var(178); // [ var(173) , var(123) ]
+                D[123,179] = (-1)*var(184); // [ var(179) , var(123) ]
+                D[123,180] = (-1)*var(185); // [ var(180) , var(123) ]
+                D[123,186] = (-1)*var(191); // [ var(186) , var(123) ]
+                D[123,187] = (-1)*var(192); // [ var(187) , var(123) ]
+                D[123,193] = (-1)*var(198); // [ var(193) , var(123) ]
+                D[123,199] = (-1)*var(204); // [ var(199) , var(123) ]
+                D[123,209] = var(213); // [ var(209) , var(123) ]
+                D[123,214] = var(218); // [ var(214) , var(123) ]
+                D[123,219] = var(222); // [ var(219) , var(123) ]
+                D[123,223] = var(225); // [ var(223) , var(123) ]
+                D[123,226] = var(228); // [ var(226) , var(123) ]
+                D[123,231] = var(234); // [ var(231) , var(123) ]
+                D[123,233] = var(235); // [ var(233) , var(123) ]
+                D[124,125] = (-1)*var(132); // [ var(125) , var(124) ]
+                D[124,129] = var(136); // [ var(129) , var(124) ]
+                D[124,133] = (-1)*var(140); // [ var(133) , var(124) ]
+                D[124,141] = (-1)*var(148); // [ var(141) , var(124) ]
+                D[124,145] = var(152); // [ var(145) , var(124) ]
+                D[124,149] = (-1)*var(156); // [ var(149) , var(124) ]
+                D[124,150] = var(157); // [ var(150) , var(124) ]
+                D[124,153] = var(160); // [ var(153) , var(124) ]
+                D[124,158] = var(165); // [ var(158) , var(124) ]
+                D[124,161] = var(169); // [ var(161) , var(124) ]
+                D[124,166] = var(173); // [ var(166) , var(124) ]
+                D[124,170] = var(176); // [ var(170) , var(124) ]
+                D[124,174] = var(180); // [ var(174) , var(124) ]
+                D[124,177] = var(183); // [ var(177) , var(124) ]
+                D[124,184] = var(190); // [ var(184) , var(124) ]
+                D[124,191] = var(196); // [ var(191) , var(124) ]
+                D[124,192] = var(197); // [ var(192) , var(124) ]
+                D[124,198] = var(203); // [ var(198) , var(124) ]
+                D[124,204] = var(208); // [ var(204) , var(124) ]
+                D[124,205] = var(209); // [ var(205) , var(124) ]
+                D[124,210] = var(214); // [ var(210) , var(124) ]
+                D[124,215] = var(219); // [ var(215) , var(124) ]
+                D[124,220] = var(223); // [ var(220) , var(124) ]
+                D[124,228] = var(230); // [ var(228) , var(124) ]
+                D[124,229] = var(231); // [ var(229) , var(124) ]
+                D[124,235] = (-1)*var(236); // [ var(235) , var(124) ]
+                D[125,126] = (-1)*var(133); // [ var(126) , var(125) ]
+                D[125,130] = var(138); // [ var(130) , var(125) ]
+                D[125,131] = var(139); // [ var(131) , var(125) ]
+                D[125,134] = (-1)*var(141); // [ var(134) , var(125) ]
+                D[125,136] = var(144); // [ var(136) , var(125) ]
+                D[125,137] = var(145); // [ var(137) , var(125) ]
+                D[125,142] = (-1)*var(149); // [ var(142) , var(125) ]
+                D[125,143] = var(150); // [ var(143) , var(125) ]
+                D[125,160] = var(168); // [ var(160) , var(125) ]
+                D[125,165] = var(172); // [ var(165) , var(125) ]
+                D[125,169] = var(175); // [ var(169) , var(125) ]
+                D[125,171] = var(177); // [ var(171) , var(125) ]
+                D[125,173] = var(179); // [ var(173) , var(125) ]
+                D[125,176] = var(182); // [ var(176) , var(125) ]
+                D[125,178] = var(184); // [ var(178) , var(125) ]
+                D[125,180] = var(187); // [ var(180) , var(125) ]
+                D[125,185] = var(192); // [ var(185) , var(125) ]
+                D[125,196] = var(202); // [ var(196) , var(125) ]
+                D[125,200] = var(205); // [ var(200) , var(125) ]
+                D[125,203] = var(207); // [ var(203) , var(125) ]
+                D[125,206] = var(210); // [ var(206) , var(125) ]
+                D[125,208] = var(212); // [ var(208) , var(125) ]
+                D[125,211] = var(215); // [ var(211) , var(125) ]
+                D[125,223] = var(226); // [ var(223) , var(125) ]
+                D[125,225] = var(228); // [ var(225) , var(125) ]
+                D[125,227] = var(229); // [ var(227) , var(125) ]
+                D[125,236] = (-1)*var(237); // [ var(236) , var(125) ]
+                D[126,127] = (-1)*var(134); // [ var(127) , var(126) ]
+                D[126,132] = var(140); // [ var(132) , var(126) ]
+                D[126,135] = (-1)*var(142); // [ var(135) , var(126) ]
+                D[126,138] = var(146); // [ var(138) , var(126) ]
+                D[126,139] = var(147); // [ var(139) , var(126) ]
+                D[126,144] = var(151); // [ var(144) , var(126) ]
+                D[126,145] = var(153); // [ var(145) , var(126) ]
+                D[126,150] = var(158); // [ var(150) , var(126) ]
+                D[126,152] = var(160); // [ var(152) , var(126) ]
+                D[126,157] = var(165); // [ var(157) , var(126) ]
+                D[126,164] = var(171); // [ var(164) , var(126) ]
+                D[126,175] = var(181); // [ var(175) , var(126) ]
+                D[126,179] = var(186); // [ var(179) , var(126) ]
+                D[126,182] = var(188); // [ var(182) , var(126) ]
+                D[126,184] = var(191); // [ var(184) , var(126) ]
+                D[126,187] = var(193); // [ var(187) , var(126) ]
+                D[126,190] = var(196); // [ var(190) , var(126) ]
+                D[126,192] = var(198); // [ var(192) , var(126) ]
+                D[126,195] = var(200); // [ var(195) , var(126) ]
+                D[126,197] = var(203); // [ var(197) , var(126) ]
+                D[126,201] = var(206); // [ var(201) , var(126) ]
+                D[126,212] = var(216); // [ var(212) , var(126) ]
+                D[126,215] = var(220); // [ var(215) , var(126) ]
+                D[126,219] = var(223); // [ var(219) , var(126) ]
+                D[126,222] = var(225); // [ var(222) , var(126) ]
+                D[126,224] = var(227); // [ var(224) , var(126) ]
+                D[126,237] = (-1)*var(238); // [ var(237) , var(126) ]
+                D[127,128] = (-1)*var(135); // [ var(128) , var(127) ]
+                D[127,133] = var(141); // [ var(133) , var(127) ]
+                D[127,140] = var(148); // [ var(140) , var(127) ]
+                D[127,146] = var(154); // [ var(146) , var(127) ]
+                D[127,147] = var(155); // [ var(147) , var(127) ]
+                D[127,151] = var(159); // [ var(151) , var(127) ]
+                D[127,153] = var(161); // [ var(153) , var(127) ]
+                D[127,158] = var(166); // [ var(158) , var(127) ]
+                D[127,160] = var(169); // [ var(160) , var(127) ]
+                D[127,165] = var(173); // [ var(165) , var(127) ]
+                D[127,168] = var(175); // [ var(168) , var(127) ]
+                D[127,171] = var(178); // [ var(171) , var(127) ]
+                D[127,172] = var(179); // [ var(172) , var(127) ]
+                D[127,177] = var(184); // [ var(177) , var(127) ]
+                D[127,183] = var(190); // [ var(183) , var(127) ]
+                D[127,188] = var(194); // [ var(188) , var(127) ]
+                D[127,189] = var(195); // [ var(189) , var(127) ]
+                D[127,193] = var(199); // [ var(193) , var(127) ]
+                D[127,198] = var(204); // [ var(198) , var(127) ]
+                D[127,203] = var(208); // [ var(203) , var(127) ]
+                D[127,206] = var(211); // [ var(206) , var(127) ]
+                D[127,207] = var(212); // [ var(207) , var(127) ]
+                D[127,210] = var(215); // [ var(210) , var(127) ]
+                D[127,214] = var(219); // [ var(214) , var(127) ]
+                D[127,218] = var(222); // [ var(218) , var(127) ]
+                D[127,221] = var(224); // [ var(221) , var(127) ]
+                D[127,238] = (-1)*var(239); // [ var(238) , var(127) ]
+                D[128,134] = var(142); // [ var(134) , var(128) ]
+                D[128,141] = var(149); // [ var(141) , var(128) ]
+                D[128,148] = var(156); // [ var(148) , var(128) ]
+                D[128,154] = var(162); // [ var(154) , var(128) ]
+                D[128,155] = var(163); // [ var(155) , var(128) ]
+                D[128,159] = var(167); // [ var(159) , var(128) ]
+                D[128,161] = var(170); // [ var(161) , var(128) ]
+                D[128,166] = var(174); // [ var(166) , var(128) ]
+                D[128,169] = var(176); // [ var(169) , var(128) ]
+                D[128,173] = var(180); // [ var(173) , var(128) ]
+                D[128,175] = var(182); // [ var(175) , var(128) ]
+                D[128,178] = var(185); // [ var(178) , var(128) ]
+                D[128,179] = var(187); // [ var(179) , var(128) ]
+                D[128,181] = var(188); // [ var(181) , var(128) ]
+                D[128,184] = var(192); // [ var(184) , var(128) ]
+                D[128,186] = var(193); // [ var(186) , var(128) ]
+                D[128,190] = var(197); // [ var(190) , var(128) ]
+                D[128,191] = var(198); // [ var(191) , var(128) ]
+                D[128,195] = var(201); // [ var(195) , var(128) ]
+                D[128,196] = var(203); // [ var(196) , var(128) ]
+                D[128,200] = var(206); // [ var(200) , var(128) ]
+                D[128,202] = var(207); // [ var(202) , var(128) ]
+                D[128,205] = var(210); // [ var(205) , var(128) ]
+                D[128,209] = var(214); // [ var(209) , var(128) ]
+                D[128,213] = var(218); // [ var(213) , var(128) ]
+                D[128,217] = var(221); // [ var(217) , var(128) ]
+                D[128,239] = (-1)*var(240); // [ var(239) , var(128) ]
+                D[129,130] = (-1)*var(143); // [ var(130) , var(129) ]
+                D[129,132] = (-1)*var(144); // [ var(132) , var(129) ]
+                D[129,138] = (-1)*var(150); // [ var(138) , var(129) ]
+                D[129,140] = (-1)*var(151); // [ var(140) , var(129) ]
+                D[129,146] = (-1)*var(158); // [ var(146) , var(129) ]
+                D[129,148] = (-1)*var(159); // [ var(148) , var(129) ]
+                D[129,152] = var(164); // [ var(152) , var(129) ]
+                D[129,154] = (-1)*var(166); // [ var(154) , var(129) ]
+                D[129,156] = (-1)*var(167); // [ var(156) , var(129) ]
+                D[129,160] = var(171); // [ var(160) , var(129) ]
+                D[129,162] = (-1)*var(174); // [ var(162) , var(129) ]
+                D[129,168] = var(177); // [ var(168) , var(129) ]
+                D[129,169] = var(178); // [ var(169) , var(129) ]
+                D[129,175] = var(184); // [ var(175) , var(129) ]
+                D[129,176] = var(185); // [ var(176) , var(129) ]
+                D[129,181] = var(191); // [ var(181) , var(129) ]
+                D[129,182] = var(192); // [ var(182) , var(129) ]
+                D[129,188] = var(198); // [ var(188) , var(129) ]
+                D[129,194] = var(204); // [ var(194) , var(129) ]
+                D[129,209] = (-1)*var(217); // [ var(209) , var(129) ]
+                D[129,214] = (-1)*var(221); // [ var(214) , var(129) ]
+                D[129,219] = (-1)*var(224); // [ var(219) , var(129) ]
+                D[129,223] = (-1)*var(227); // [ var(223) , var(129) ]
+                D[129,226] = (-1)*var(229); // [ var(226) , var(129) ]
+                D[129,230] = var(234); // [ var(230) , var(129) ]
+                D[129,232] = var(235); // [ var(232) , var(129) ]
+                D[130,133] = (-1)*var(146); // [ var(133) , var(130) ]
+                D[130,139] = (-1)*var(152); // [ var(139) , var(130) ]
+                D[130,141] = (-1)*var(154); // [ var(141) , var(130) ]
+                D[130,144] = (-1)*var(157); // [ var(144) , var(130) ]
+                D[130,147] = (-1)*var(160); // [ var(147) , var(130) ]
+                D[130,149] = (-1)*var(162); // [ var(149) , var(130) ]
+                D[130,151] = (-1)*var(165); // [ var(151) , var(130) ]
+                D[130,155] = (-1)*var(169); // [ var(155) , var(130) ]
+                D[130,159] = (-1)*var(173); // [ var(159) , var(130) ]
+                D[130,163] = (-1)*var(176); // [ var(163) , var(130) ]
+                D[130,167] = (-1)*var(180); // [ var(167) , var(130) ]
+                D[130,177] = (-1)*var(189); // [ var(177) , var(130) ]
+                D[130,184] = (-1)*var(195); // [ var(184) , var(130) ]
+                D[130,191] = (-1)*var(200); // [ var(191) , var(130) ]
+                D[130,192] = (-1)*var(201); // [ var(192) , var(130) ]
+                D[130,198] = (-1)*var(206); // [ var(198) , var(130) ]
+                D[130,202] = var(209); // [ var(202) , var(130) ]
+                D[130,204] = (-1)*var(211); // [ var(204) , var(130) ]
+                D[130,207] = var(214); // [ var(207) , var(130) ]
+                D[130,212] = var(219); // [ var(212) , var(130) ]
+                D[130,216] = var(223); // [ var(216) , var(130) ]
+                D[130,228] = var(232); // [ var(228) , var(130) ]
+                D[130,229] = var(233); // [ var(229) , var(130) ]
+                D[130,234] = var(236); // [ var(234) , var(130) ]
+                D[131,133] = (-1)*var(147); // [ var(133) , var(131) ]
+                D[131,138] = (-1)*var(152); // [ var(138) , var(131) ]
+                D[131,141] = (-1)*var(155); // [ var(141) , var(131) ]
+                D[131,146] = (-1)*var(160); // [ var(146) , var(131) ]
+                D[131,149] = (-1)*var(163); // [ var(149) , var(131) ]
+                D[131,150] = var(164); // [ var(150) , var(131) ]
+                D[131,154] = (-1)*var(169); // [ var(154) , var(131) ]
+                D[131,158] = var(171); // [ var(158) , var(131) ]
+                D[131,162] = (-1)*var(176); // [ var(162) , var(131) ]
+                D[131,166] = var(178); // [ var(166) , var(131) ]
+                D[131,172] = (-1)*var(183); // [ var(172) , var(131) ]
+                D[131,174] = var(185); // [ var(174) , var(131) ]
+                D[131,179] = (-1)*var(190); // [ var(179) , var(131) ]
+                D[131,186] = (-1)*var(196); // [ var(186) , var(131) ]
+                D[131,187] = (-1)*var(197); // [ var(187) , var(131) ]
+                D[131,193] = (-1)*var(203); // [ var(193) , var(131) ]
+                D[131,199] = (-1)*var(208); // [ var(199) , var(131) ]
+                D[131,205] = (-1)*var(213); // [ var(205) , var(131) ]
+                D[131,210] = (-1)*var(218); // [ var(210) , var(131) ]
+                D[131,215] = (-1)*var(222); // [ var(215) , var(131) ]
+                D[131,220] = (-1)*var(225); // [ var(220) , var(131) ]
+                D[131,226] = var(230); // [ var(226) , var(131) ]
+                D[131,229] = (-1)*var(234); // [ var(229) , var(131) ]
+                D[131,233] = (-1)*var(236); // [ var(233) , var(131) ]
+                D[132,134] = (-1)*var(148); // [ var(134) , var(132) ]
+                D[132,137] = (-1)*var(152); // [ var(137) , var(132) ]
+                D[132,142] = (-1)*var(156); // [ var(142) , var(132) ]
+                D[132,143] = (-1)*var(157); // [ var(143) , var(132) ]
+                D[132,153] = var(168); // [ var(153) , var(132) ]
+                D[132,158] = var(172); // [ var(158) , var(132) ]
+                D[132,161] = var(175); // [ var(161) , var(132) ]
+                D[132,166] = var(179); // [ var(166) , var(132) ]
+                D[132,170] = var(182); // [ var(170) , var(132) ]
+                D[132,171] = (-1)*var(183); // [ var(171) , var(132) ]
+                D[132,174] = var(187); // [ var(174) , var(132) ]
+                D[132,178] = (-1)*var(190); // [ var(178) , var(132) ]
+                D[132,185] = (-1)*var(197); // [ var(185) , var(132) ]
+                D[132,191] = var(202); // [ var(191) , var(132) ]
+                D[132,198] = var(207); // [ var(198) , var(132) ]
+                D[132,200] = (-1)*var(209); // [ var(200) , var(132) ]
+                D[132,204] = var(212); // [ var(204) , var(132) ]
+                D[132,206] = (-1)*var(214); // [ var(206) , var(132) ]
+                D[132,211] = (-1)*var(219); // [ var(211) , var(132) ]
+                D[132,220] = var(226); // [ var(220) , var(132) ]
+                D[132,225] = (-1)*var(230); // [ var(225) , var(132) ]
+                D[132,227] = (-1)*var(231); // [ var(227) , var(132) ]
+                D[132,235] = var(237); // [ var(235) , var(132) ]
+                D[133,135] = (-1)*var(149); // [ var(135) , var(133) ]
+                D[133,136] = var(151); // [ var(136) , var(133) ]
+                D[133,137] = var(153); // [ var(137) , var(133) ]
+                D[133,143] = var(158); // [ var(143) , var(133) ]
+                D[133,152] = (-1)*var(168); // [ var(152) , var(133) ]
+                D[133,157] = (-1)*var(172); // [ var(157) , var(133) ]
+                D[133,164] = (-1)*var(177); // [ var(164) , var(133) ]
+                D[133,169] = var(181); // [ var(169) , var(133) ]
+                D[133,173] = var(186); // [ var(173) , var(133) ]
+                D[133,176] = var(188); // [ var(176) , var(133) ]
+                D[133,178] = var(191); // [ var(178) , var(133) ]
+                D[133,180] = var(193); // [ var(180) , var(133) ]
+                D[133,185] = var(198); // [ var(185) , var(133) ]
+                D[133,190] = (-1)*var(202); // [ var(190) , var(133) ]
+                D[133,195] = (-1)*var(205); // [ var(195) , var(133) ]
+                D[133,197] = (-1)*var(207); // [ var(197) , var(133) ]
+                D[133,201] = (-1)*var(210); // [ var(201) , var(133) ]
+                D[133,208] = var(216); // [ var(208) , var(133) ]
+                D[133,211] = var(220); // [ var(211) , var(133) ]
+                D[133,219] = (-1)*var(226); // [ var(219) , var(133) ]
+                D[133,222] = (-1)*var(228); // [ var(222) , var(133) ]
+                D[133,224] = (-1)*var(229); // [ var(224) , var(133) ]
+                D[133,236] = var(238); // [ var(236) , var(133) ]
+                D[134,138] = var(154); // [ var(138) , var(134) ]
+                D[134,139] = var(155); // [ var(139) , var(134) ]
+                D[134,144] = var(159); // [ var(144) , var(134) ]
+                D[134,145] = var(161); // [ var(145) , var(134) ]
+                D[134,150] = var(166); // [ var(150) , var(134) ]
+                D[134,152] = var(169); // [ var(152) , var(134) ]
+                D[134,157] = var(173); // [ var(157) , var(134) ]
+                D[134,164] = var(178); // [ var(164) , var(134) ]
+                D[134,168] = (-1)*var(181); // [ var(168) , var(134) ]
+                D[134,172] = (-1)*var(186); // [ var(172) , var(134) ]
+                D[134,177] = (-1)*var(191); // [ var(177) , var(134) ]
+                D[134,182] = var(194); // [ var(182) , var(134) ]
+                D[134,183] = (-1)*var(196); // [ var(183) , var(134) ]
+                D[134,187] = var(199); // [ var(187) , var(134) ]
+                D[134,189] = (-1)*var(200); // [ var(189) , var(134) ]
+                D[134,192] = var(204); // [ var(192) , var(134) ]
+                D[134,197] = var(208); // [ var(197) , var(134) ]
+                D[134,201] = var(211); // [ var(201) , var(134) ]
+                D[134,207] = (-1)*var(216); // [ var(207) , var(134) ]
+                D[134,210] = (-1)*var(220); // [ var(210) , var(134) ]
+                D[134,214] = (-1)*var(223); // [ var(214) , var(134) ]
+                D[134,218] = (-1)*var(225); // [ var(218) , var(134) ]
+                D[134,221] = (-1)*var(227); // [ var(221) , var(134) ]
+                D[134,237] = var(239); // [ var(237) , var(134) ]
+                D[135,140] = var(156); // [ var(140) , var(135) ]
+                D[135,146] = var(162); // [ var(146) , var(135) ]
+                D[135,147] = var(163); // [ var(147) , var(135) ]
+                D[135,151] = var(167); // [ var(151) , var(135) ]
+                D[135,153] = var(170); // [ var(153) , var(135) ]
+                D[135,158] = var(174); // [ var(158) , var(135) ]
+                D[135,160] = var(176); // [ var(160) , var(135) ]
+                D[135,165] = var(180); // [ var(165) , var(135) ]
+                D[135,168] = var(182); // [ var(168) , var(135) ]
+                D[135,171] = var(185); // [ var(171) , var(135) ]
+                D[135,172] = var(187); // [ var(172) , var(135) ]
+                D[135,177] = var(192); // [ var(177) , var(135) ]
+                D[135,181] = (-1)*var(194); // [ var(181) , var(135) ]
+                D[135,183] = var(197); // [ var(183) , var(135) ]
+                D[135,186] = (-1)*var(199); // [ var(186) , var(135) ]
+                D[135,189] = var(201); // [ var(189) , var(135) ]
+                D[135,191] = (-1)*var(204); // [ var(191) , var(135) ]
+                D[135,196] = (-1)*var(208); // [ var(196) , var(135) ]
+                D[135,200] = (-1)*var(211); // [ var(200) , var(135) ]
+                D[135,202] = (-1)*var(212); // [ var(202) , var(135) ]
+                D[135,205] = (-1)*var(215); // [ var(205) , var(135) ]
+                D[135,209] = (-1)*var(219); // [ var(209) , var(135) ]
+                D[135,213] = (-1)*var(222); // [ var(213) , var(135) ]
+                D[135,217] = (-1)*var(224); // [ var(217) , var(135) ]
+                D[135,238] = var(240); // [ var(238) , var(135) ]
+                D[136,138] = (-1)*var(157); // [ var(138) , var(136) ]
+                D[136,141] = (-1)*var(159); // [ var(141) , var(136) ]
+                D[136,145] = (-1)*var(164); // [ var(145) , var(136) ]
+                D[136,146] = (-1)*var(165); // [ var(146) , var(136) ]
+                D[136,149] = (-1)*var(167); // [ var(149) , var(136) ]
+                D[136,153] = (-1)*var(171); // [ var(153) , var(136) ]
+                D[136,154] = (-1)*var(173); // [ var(154) , var(136) ]
+                D[136,161] = (-1)*var(178); // [ var(161) , var(136) ]
+                D[136,162] = (-1)*var(180); // [ var(162) , var(136) ]
+                D[136,168] = var(183); // [ var(168) , var(136) ]
+                D[136,170] = (-1)*var(185); // [ var(170) , var(136) ]
+                D[136,175] = var(190); // [ var(175) , var(136) ]
+                D[136,181] = var(196); // [ var(181) , var(136) ]
+                D[136,182] = var(197); // [ var(182) , var(136) ]
+                D[136,188] = var(203); // [ var(188) , var(136) ]
+                D[136,194] = var(208); // [ var(194) , var(136) ]
+                D[136,205] = var(217); // [ var(205) , var(136) ]
+                D[136,210] = var(221); // [ var(210) , var(136) ]
+                D[136,215] = var(224); // [ var(215) , var(136) ]
+                D[136,220] = var(227); // [ var(220) , var(136) ]
+                D[136,226] = (-1)*var(231); // [ var(226) , var(136) ]
+                D[136,228] = (-1)*var(234); // [ var(228) , var(136) ]
+                D[136,232] = (-1)*var(236); // [ var(232) , var(136) ]
+                D[137,140] = var(160); // [ var(140) , var(137) ]
+                D[137,141] = (-1)*var(161); // [ var(141) , var(137) ]
+                D[137,144] = (-1)*var(164); // [ var(144) , var(137) ]
+                D[137,148] = var(169); // [ var(148) , var(137) ]
+                D[137,149] = (-1)*var(170); // [ var(149) , var(137) ]
+                D[137,151] = (-1)*var(171); // [ var(151) , var(137) ]
+                D[137,156] = var(176); // [ var(156) , var(137) ]
+                D[137,159] = (-1)*var(178); // [ var(159) , var(137) ]
+                D[137,167] = (-1)*var(185); // [ var(167) , var(137) ]
+                D[137,172] = var(189); // [ var(172) , var(137) ]
+                D[137,179] = var(195); // [ var(179) , var(137) ]
+                D[137,186] = var(200); // [ var(186) , var(137) ]
+                D[137,187] = var(201); // [ var(187) , var(137) ]
+                D[137,193] = var(206); // [ var(193) , var(137) ]
+                D[137,199] = var(211); // [ var(199) , var(137) ]
+                D[137,202] = (-1)*var(213); // [ var(202) , var(137) ]
+                D[137,207] = (-1)*var(218); // [ var(207) , var(137) ]
+                D[137,212] = (-1)*var(222); // [ var(212) , var(137) ]
+                D[137,216] = (-1)*var(225); // [ var(216) , var(137) ]
+                D[137,226] = var(232); // [ var(226) , var(137) ]
+                D[137,229] = (-1)*var(235); // [ var(229) , var(137) ]
+                D[137,231] = var(236); // [ var(231) , var(137) ]
+                D[138,142] = (-1)*var(162); // [ var(142) , var(138) ]
+                D[138,147] = (-1)*var(168); // [ var(147) , var(138) ]
+                D[138,151] = (-1)*var(172); // [ var(151) , var(138) ]
+                D[138,155] = (-1)*var(175); // [ var(155) , var(138) ]
+                D[138,159] = (-1)*var(179); // [ var(159) , var(138) ]
+                D[138,163] = (-1)*var(182); // [ var(163) , var(138) ]
+                D[138,167] = (-1)*var(187); // [ var(167) , var(138) ]
+                D[138,171] = var(189); // [ var(171) , var(138) ]
+                D[138,178] = var(195); // [ var(178) , var(138) ]
+                D[138,185] = var(201); // [ var(185) , var(138) ]
+                D[138,191] = (-1)*var(205); // [ var(191) , var(138) ]
+                D[138,196] = (-1)*var(209); // [ var(196) , var(138) ]
+                D[138,198] = (-1)*var(210); // [ var(198) , var(138) ]
+                D[138,203] = (-1)*var(214); // [ var(203) , var(138) ]
+                D[138,204] = (-1)*var(215); // [ var(204) , var(138) ]
+                D[138,208] = (-1)*var(219); // [ var(208) , var(138) ]
+                D[138,216] = var(226); // [ var(216) , var(138) ]
+                D[138,225] = (-1)*var(232); // [ var(225) , var(138) ]
+                D[138,227] = (-1)*var(233); // [ var(227) , var(138) ]
+                D[138,234] = (-1)*var(237); // [ var(234) , var(138) ]
+                D[139,142] = (-1)*var(163); // [ var(142) , var(139) ]
+                D[139,143] = (-1)*var(164); // [ var(143) , var(139) ]
+                D[139,146] = (-1)*var(168); // [ var(146) , var(139) ]
+                D[139,154] = (-1)*var(175); // [ var(154) , var(139) ]
+                D[139,158] = var(177); // [ var(158) , var(139) ]
+                D[139,162] = (-1)*var(182); // [ var(162) , var(139) ]
+                D[139,165] = var(183); // [ var(165) , var(139) ]
+                D[139,166] = var(184); // [ var(166) , var(139) ]
+                D[139,173] = var(190); // [ var(173) , var(139) ]
+                D[139,174] = var(192); // [ var(174) , var(139) ]
+                D[139,180] = var(197); // [ var(180) , var(139) ]
+                D[139,186] = (-1)*var(202); // [ var(186) , var(139) ]
+                D[139,193] = (-1)*var(207); // [ var(193) , var(139) ]
+                D[139,199] = (-1)*var(212); // [ var(199) , var(139) ]
+                D[139,200] = var(213); // [ var(200) , var(139) ]
+                D[139,206] = var(218); // [ var(206) , var(139) ]
+                D[139,211] = var(222); // [ var(211) , var(139) ]
+                D[139,220] = (-1)*var(228); // [ var(220) , var(139) ]
+                D[139,223] = (-1)*var(230); // [ var(223) , var(139) ]
+                D[139,227] = var(234); // [ var(227) , var(139) ]
+                D[139,233] = var(237); // [ var(233) , var(139) ]
+                D[140,143] = (-1)*var(165); // [ var(143) , var(140) ]
+                D[140,145] = (-1)*var(168); // [ var(145) , var(140) ]
+                D[140,150] = (-1)*var(172); // [ var(150) , var(140) ]
+                D[140,161] = var(181); // [ var(161) , var(140) ]
+                D[140,164] = var(183); // [ var(164) , var(140) ]
+                D[140,166] = var(186); // [ var(166) , var(140) ]
+                D[140,170] = var(188); // [ var(170) , var(140) ]
+                D[140,174] = var(193); // [ var(174) , var(140) ]
+                D[140,178] = (-1)*var(196); // [ var(178) , var(140) ]
+                D[140,184] = (-1)*var(202); // [ var(184) , var(140) ]
+                D[140,185] = (-1)*var(203); // [ var(185) , var(140) ]
+                D[140,192] = (-1)*var(207); // [ var(192) , var(140) ]
+                D[140,195] = var(209); // [ var(195) , var(140) ]
+                D[140,201] = var(214); // [ var(201) , var(140) ]
+                D[140,204] = var(216); // [ var(204) , var(140) ]
+                D[140,211] = (-1)*var(223); // [ var(211) , var(140) ]
+                D[140,215] = (-1)*var(226); // [ var(215) , var(140) ]
+                D[140,222] = var(230); // [ var(222) , var(140) ]
+                D[140,224] = var(231); // [ var(224) , var(140) ]
+                D[140,235] = (-1)*var(238); // [ var(235) , var(140) ]
+                D[141,143] = var(166); // [ var(143) , var(141) ]
+                D[141,152] = (-1)*var(175); // [ var(152) , var(141) ]
+                D[141,157] = (-1)*var(179); // [ var(157) , var(141) ]
+                D[141,160] = (-1)*var(181); // [ var(160) , var(141) ]
+                D[141,164] = (-1)*var(184); // [ var(164) , var(141) ]
+                D[141,165] = (-1)*var(186); // [ var(165) , var(141) ]
+                D[141,171] = (-1)*var(191); // [ var(171) , var(141) ]
+                D[141,176] = var(194); // [ var(176) , var(141) ]
+                D[141,180] = var(199); // [ var(180) , var(141) ]
+                D[141,183] = var(202); // [ var(183) , var(141) ]
+                D[141,185] = var(204); // [ var(185) , var(141) ]
+                D[141,189] = var(205); // [ var(189) , var(141) ]
+                D[141,197] = (-1)*var(212); // [ var(197) , var(141) ]
+                D[141,201] = (-1)*var(215); // [ var(201) , var(141) ]
+                D[141,203] = (-1)*var(216); // [ var(203) , var(141) ]
+                D[141,206] = (-1)*var(220); // [ var(206) , var(141) ]
+                D[141,214] = var(226); // [ var(214) , var(141) ]
+                D[141,218] = var(228); // [ var(218) , var(141) ]
+                D[141,221] = var(229); // [ var(221) , var(141) ]
+                D[141,236] = (-1)*var(239); // [ var(236) , var(141) ]
+                D[142,144] = var(167); // [ var(144) , var(142) ]
+                D[142,145] = var(170); // [ var(145) , var(142) ]
+                D[142,150] = var(174); // [ var(150) , var(142) ]
+                D[142,152] = var(176); // [ var(152) , var(142) ]
+                D[142,157] = var(180); // [ var(157) , var(142) ]
+                D[142,164] = var(185); // [ var(164) , var(142) ]
+                D[142,168] = (-1)*var(188); // [ var(168) , var(142) ]
+                D[142,172] = (-1)*var(193); // [ var(172) , var(142) ]
+                D[142,175] = (-1)*var(194); // [ var(175) , var(142) ]
+                D[142,177] = (-1)*var(198); // [ var(177) , var(142) ]
+                D[142,179] = (-1)*var(199); // [ var(179) , var(142) ]
+                D[142,183] = (-1)*var(203); // [ var(183) , var(142) ]
+                D[142,184] = (-1)*var(204); // [ var(184) , var(142) ]
+                D[142,189] = (-1)*var(206); // [ var(189) , var(142) ]
+                D[142,190] = (-1)*var(208); // [ var(190) , var(142) ]
+                D[142,195] = (-1)*var(211); // [ var(195) , var(142) ]
+                D[142,202] = var(216); // [ var(202) , var(142) ]
+                D[142,205] = var(220); // [ var(205) , var(142) ]
+                D[142,209] = var(223); // [ var(209) , var(142) ]
+                D[142,213] = var(225); // [ var(213) , var(142) ]
+                D[142,217] = var(227); // [ var(217) , var(142) ]
+                D[142,237] = (-1)*var(240); // [ var(237) , var(142) ]
+                D[143,147] = var(171); // [ var(147) , var(143) ]
+                D[143,148] = var(173); // [ var(148) , var(143) ]
+                D[143,149] = (-1)*var(174); // [ var(149) , var(143) ]
+                D[143,155] = var(178); // [ var(155) , var(143) ]
+                D[143,156] = var(180); // [ var(156) , var(143) ]
+                D[143,163] = var(185); // [ var(163) , var(143) ]
+                D[143,168] = (-1)*var(189); // [ var(168) , var(143) ]
+                D[143,175] = (-1)*var(195); // [ var(175) , var(143) ]
+                D[143,181] = (-1)*var(200); // [ var(181) , var(143) ]
+                D[143,182] = (-1)*var(201); // [ var(182) , var(143) ]
+                D[143,188] = (-1)*var(206); // [ var(188) , var(143) ]
+                D[143,194] = (-1)*var(211); // [ var(194) , var(143) ]
+                D[143,202] = var(217); // [ var(202) , var(143) ]
+                D[143,207] = var(221); // [ var(207) , var(143) ]
+                D[143,212] = var(224); // [ var(212) , var(143) ]
+                D[143,216] = var(227); // [ var(216) , var(143) ]
+                D[143,226] = (-1)*var(233); // [ var(226) , var(143) ]
+                D[143,228] = (-1)*var(235); // [ var(228) , var(143) ]
+                D[143,230] = var(236); // [ var(230) , var(143) ]
+                D[144,146] = (-1)*var(172); // [ var(146) , var(144) ]
+                D[144,153] = (-1)*var(177); // [ var(153) , var(144) ]
+                D[144,154] = (-1)*var(179); // [ var(154) , var(144) ]
+                D[144,160] = (-1)*var(183); // [ var(160) , var(144) ]
+                D[144,161] = (-1)*var(184); // [ var(161) , var(144) ]
+                D[144,162] = (-1)*var(187); // [ var(162) , var(144) ]
+                D[144,169] = (-1)*var(190); // [ var(169) , var(144) ]
+                D[144,170] = (-1)*var(192); // [ var(170) , var(144) ]
+                D[144,176] = (-1)*var(197); // [ var(176) , var(144) ]
+                D[144,181] = var(202); // [ var(181) , var(144) ]
+                D[144,188] = var(207); // [ var(188) , var(144) ]
+                D[144,194] = var(212); // [ var(194) , var(144) ]
+                D[144,200] = (-1)*var(217); // [ var(200) , var(144) ]
+                D[144,206] = (-1)*var(221); // [ var(206) , var(144) ]
+                D[144,211] = (-1)*var(224); // [ var(211) , var(144) ]
+                D[144,220] = var(229); // [ var(220) , var(144) ]
+                D[144,223] = var(231); // [ var(223) , var(144) ]
+                D[144,225] = var(234); // [ var(225) , var(144) ]
+                D[144,232] = var(237); // [ var(232) , var(144) ]
+                D[145,148] = var(175); // [ var(148) , var(145) ]
+                D[145,151] = (-1)*var(177); // [ var(151) , var(145) ]
+                D[145,156] = var(182); // [ var(156) , var(145) ]
+                D[145,159] = (-1)*var(184); // [ var(159) , var(145) ]
+                D[145,165] = (-1)*var(189); // [ var(165) , var(145) ]
+                D[145,167] = (-1)*var(192); // [ var(167) , var(145) ]
+                D[145,173] = (-1)*var(195); // [ var(173) , var(145) ]
+                D[145,180] = (-1)*var(201); // [ var(180) , var(145) ]
+                D[145,186] = var(205); // [ var(186) , var(145) ]
+                D[145,193] = var(210); // [ var(193) , var(145) ]
+                D[145,196] = var(213); // [ var(196) , var(145) ]
+                D[145,199] = var(215); // [ var(199) , var(145) ]
+                D[145,203] = var(218); // [ var(203) , var(145) ]
+                D[145,208] = var(222); // [ var(208) , var(145) ]
+                D[145,216] = (-1)*var(228); // [ var(216) , var(145) ]
+                D[145,223] = (-1)*var(232); // [ var(223) , var(145) ]
+                D[145,227] = var(235); // [ var(227) , var(145) ]
+                D[145,231] = (-1)*var(237); // [ var(231) , var(145) ]
+                D[146,155] = (-1)*var(181); // [ var(155) , var(146) ]
+                D[146,159] = (-1)*var(186); // [ var(159) , var(146) ]
+                D[146,163] = (-1)*var(188); // [ var(163) , var(146) ]
+                D[146,164] = (-1)*var(189); // [ var(164) , var(146) ]
+                D[146,167] = (-1)*var(193); // [ var(167) , var(146) ]
+                D[146,178] = var(200); // [ var(178) , var(146) ]
+                D[146,184] = var(205); // [ var(184) , var(146) ]
+                D[146,185] = var(206); // [ var(185) , var(146) ]
+                D[146,190] = var(209); // [ var(190) , var(146) ]
+                D[146,192] = var(210); // [ var(192) , var(146) ]
+                D[146,197] = var(214); // [ var(197) , var(146) ]
+                D[146,204] = (-1)*var(220); // [ var(204) , var(146) ]
+                D[146,208] = (-1)*var(223); // [ var(208) , var(146) ]
+                D[146,212] = (-1)*var(226); // [ var(212) , var(146) ]
+                D[146,222] = var(232); // [ var(222) , var(146) ]
+                D[146,224] = var(233); // [ var(224) , var(146) ]
+                D[146,234] = var(238); // [ var(234) , var(146) ]
+                D[147,150] = (-1)*var(177); // [ var(150) , var(147) ]
+                D[147,154] = (-1)*var(181); // [ var(154) , var(147) ]
+                D[147,157] = (-1)*var(183); // [ var(157) , var(147) ]
+                D[147,162] = (-1)*var(188); // [ var(162) , var(147) ]
+                D[147,166] = var(191); // [ var(166) , var(147) ]
+                D[147,173] = var(196); // [ var(173) , var(147) ]
+                D[147,174] = var(198); // [ var(174) , var(147) ]
+                D[147,179] = var(202); // [ var(179) , var(147) ]
+                D[147,180] = var(203); // [ var(180) , var(147) ]
+                D[147,187] = var(207); // [ var(187) , var(147) ]
+                D[147,195] = (-1)*var(213); // [ var(195) , var(147) ]
+                D[147,199] = (-1)*var(216); // [ var(199) , var(147) ]
+                D[147,201] = (-1)*var(218); // [ var(201) , var(147) ]
+                D[147,211] = var(225); // [ var(211) , var(147) ]
+                D[147,215] = var(228); // [ var(215) , var(147) ]
+                D[147,219] = var(230); // [ var(219) , var(147) ]
+                D[147,224] = (-1)*var(234); // [ var(224) , var(147) ]
+                D[147,233] = (-1)*var(238); // [ var(233) , var(147) ]
+                D[148,150] = (-1)*var(179); // [ var(150) , var(148) ]
+                D[148,153] = (-1)*var(181); // [ var(153) , var(148) ]
+                D[148,158] = (-1)*var(186); // [ var(158) , var(148) ]
+                D[148,164] = var(190); // [ var(164) , var(148) ]
+                D[148,170] = var(194); // [ var(170) , var(148) ]
+                D[148,171] = var(196); // [ var(171) , var(148) ]
+                D[148,174] = var(199); // [ var(174) , var(148) ]
+                D[148,177] = var(202); // [ var(177) , var(148) ]
+                D[148,185] = (-1)*var(208); // [ var(185) , var(148) ]
+                D[148,189] = (-1)*var(209); // [ var(189) , var(148) ]
+                D[148,192] = (-1)*var(212); // [ var(192) , var(148) ]
+                D[148,198] = (-1)*var(216); // [ var(198) , var(148) ]
+                D[148,201] = var(219); // [ var(201) , var(148) ]
+                D[148,206] = var(223); // [ var(206) , var(148) ]
+                D[148,210] = var(226); // [ var(210) , var(148) ]
+                D[148,218] = (-1)*var(230); // [ var(218) , var(148) ]
+                D[148,221] = (-1)*var(231); // [ var(221) , var(148) ]
+                D[148,235] = var(239); // [ var(235) , var(148) ]
+                D[149,152] = (-1)*var(182); // [ var(152) , var(149) ]
+                D[149,157] = (-1)*var(187); // [ var(157) , var(149) ]
+                D[149,160] = (-1)*var(188); // [ var(160) , var(149) ]
+                D[149,164] = (-1)*var(192); // [ var(164) , var(149) ]
+                D[149,165] = (-1)*var(193); // [ var(165) , var(149) ]
+                D[149,169] = (-1)*var(194); // [ var(169) , var(149) ]
+                D[149,171] = (-1)*var(198); // [ var(171) , var(149) ]
+                D[149,173] = (-1)*var(199); // [ var(173) , var(149) ]
+                D[149,178] = (-1)*var(204); // [ var(178) , var(149) ]
+                D[149,183] = var(207); // [ var(183) , var(149) ]
+                D[149,189] = var(210); // [ var(189) , var(149) ]
+                D[149,190] = var(212); // [ var(190) , var(149) ]
+                D[149,195] = var(215); // [ var(195) , var(149) ]
+                D[149,196] = var(216); // [ var(196) , var(149) ]
+                D[149,200] = var(220); // [ var(200) , var(149) ]
+                D[149,209] = (-1)*var(226); // [ var(209) , var(149) ]
+                D[149,213] = (-1)*var(228); // [ var(213) , var(149) ]
+                D[149,217] = (-1)*var(229); // [ var(217) , var(149) ]
+                D[149,236] = var(240); // [ var(236) , var(149) ]
+                D[150,155] = var(184); // [ var(155) , var(150) ]
+                D[150,156] = var(187); // [ var(156) , var(150) ]
+                D[150,160] = var(189); // [ var(160) , var(150) ]
+                D[150,163] = var(192); // [ var(163) , var(150) ]
+                D[150,169] = var(195); // [ var(169) , var(150) ]
+                D[150,176] = var(201); // [ var(176) , var(150) ]
+                D[150,181] = (-1)*var(205); // [ var(181) , var(150) ]
+                D[150,188] = (-1)*var(210); // [ var(188) , var(150) ]
+                D[150,194] = (-1)*var(215); // [ var(194) , var(150) ]
+                D[150,196] = (-1)*var(217); // [ var(196) , var(150) ]
+                D[150,203] = (-1)*var(221); // [ var(203) , var(150) ]
+                D[150,208] = (-1)*var(224); // [ var(208) , var(150) ]
+                D[150,216] = var(229); // [ var(216) , var(150) ]
+                D[150,223] = var(233); // [ var(223) , var(150) ]
+                D[150,225] = var(235); // [ var(225) , var(150) ]
+                D[150,230] = (-1)*var(237); // [ var(230) , var(150) ]
+                D[151,152] = var(183); // [ var(152) , var(151) ]
+                D[151,154] = (-1)*var(186); // [ var(154) , var(151) ]
+                D[151,161] = (-1)*var(191); // [ var(161) , var(151) ]
+                D[151,162] = (-1)*var(193); // [ var(162) , var(151) ]
+                D[151,169] = (-1)*var(196); // [ var(169) , var(151) ]
+                D[151,170] = (-1)*var(198); // [ var(170) , var(151) ]
+                D[151,175] = (-1)*var(202); // [ var(175) , var(151) ]
+                D[151,176] = (-1)*var(203); // [ var(176) , var(151) ]
+                D[151,182] = (-1)*var(207); // [ var(182) , var(151) ]
+                D[151,194] = var(216); // [ var(194) , var(151) ]
+                D[151,195] = var(217); // [ var(195) , var(151) ]
+                D[151,201] = var(221); // [ var(201) , var(151) ]
+                D[151,211] = (-1)*var(227); // [ var(211) , var(151) ]
+                D[151,215] = (-1)*var(229); // [ var(215) , var(151) ]
+                D[151,219] = (-1)*var(231); // [ var(219) , var(151) ]
+                D[151,222] = (-1)*var(234); // [ var(222) , var(151) ]
+                D[151,232] = (-1)*var(238); // [ var(232) , var(151) ]
+                D[152,158] = var(189); // [ var(158) , var(152) ]
+                D[152,159] = (-1)*var(190); // [ var(159) , var(152) ]
+                D[152,166] = var(195); // [ var(166) , var(152) ]
+                D[152,167] = (-1)*var(197); // [ var(167) , var(152) ]
+                D[152,174] = var(201); // [ var(174) , var(152) ]
+                D[152,186] = var(209); // [ var(186) , var(152) ]
+                D[152,191] = (-1)*var(213); // [ var(191) , var(152) ]
+                D[152,193] = var(214); // [ var(193) , var(152) ]
+                D[152,198] = (-1)*var(218); // [ var(198) , var(152) ]
+                D[152,199] = var(219); // [ var(199) , var(152) ]
+                D[152,204] = (-1)*var(222); // [ var(204) , var(152) ]
+                D[152,216] = (-1)*var(230); // [ var(216) , var(152) ]
+                D[152,220] = var(232); // [ var(220) , var(152) ]
+                D[152,227] = (-1)*var(236); // [ var(227) , var(152) ]
+                D[152,229] = var(237); // [ var(229) , var(152) ]
+                D[153,156] = var(188); // [ var(156) , var(153) ]
+                D[153,157] = var(189); // [ var(157) , var(153) ]
+                D[153,159] = (-1)*var(191); // [ var(159) , var(153) ]
+                D[153,167] = (-1)*var(198); // [ var(167) , var(153) ]
+                D[153,173] = (-1)*var(200); // [ var(173) , var(153) ]
+                D[153,179] = (-1)*var(205); // [ var(179) , var(153) ]
+                D[153,180] = (-1)*var(206); // [ var(180) , var(153) ]
+                D[153,187] = (-1)*var(210); // [ var(187) , var(153) ]
+                D[153,190] = (-1)*var(213); // [ var(190) , var(153) ]
+                D[153,197] = (-1)*var(218); // [ var(197) , var(153) ]
+                D[153,199] = var(220); // [ var(199) , var(153) ]
+                D[153,208] = var(225); // [ var(208) , var(153) ]
+                D[153,212] = var(228); // [ var(212) , var(153) ]
+                D[153,219] = var(232); // [ var(219) , var(153) ]
+                D[153,224] = (-1)*var(235); // [ var(224) , var(153) ]
+                D[153,231] = var(238); // [ var(231) , var(153) ]
+                D[154,163] = (-1)*var(194); // [ var(163) , var(154) ]
+                D[154,164] = (-1)*var(195); // [ var(164) , var(154) ]
+                D[154,167] = (-1)*var(199); // [ var(167) , var(154) ]
+                D[154,171] = (-1)*var(200); // [ var(171) , var(154) ]
+                D[154,177] = (-1)*var(205); // [ var(177) , var(154) ]
+                D[154,183] = (-1)*var(209); // [ var(183) , var(154) ]
+                D[154,185] = var(211); // [ var(185) , var(154) ]
+                D[154,192] = var(215); // [ var(192) , var(154) ]
+                D[154,197] = var(219); // [ var(197) , var(154) ]
+                D[154,198] = var(220); // [ var(198) , var(154) ]
+                D[154,203] = var(223); // [ var(203) , var(154) ]
+                D[154,207] = var(226); // [ var(207) , var(154) ]
+                D[154,218] = (-1)*var(232); // [ var(218) , var(154) ]
+                D[154,221] = (-1)*var(233); // [ var(221) , var(154) ]
+                D[154,234] = (-1)*var(239); // [ var(234) , var(154) ]
+                D[155,157] = (-1)*var(190); // [ var(157) , var(155) ]
+                D[155,158] = (-1)*var(191); // [ var(158) , var(155) ]
+                D[155,162] = (-1)*var(194); // [ var(162) , var(155) ]
+                D[155,165] = (-1)*var(196); // [ var(165) , var(155) ]
+                D[155,172] = (-1)*var(202); // [ var(172) , var(155) ]
+                D[155,174] = var(204); // [ var(174) , var(155) ]
+                D[155,180] = var(208); // [ var(180) , var(155) ]
+                D[155,187] = var(212); // [ var(187) , var(155) ]
+                D[155,189] = var(213); // [ var(189) , var(155) ]
+                D[155,193] = var(216); // [ var(193) , var(155) ]
+                D[155,201] = (-1)*var(222); // [ var(201) , var(155) ]
+                D[155,206] = (-1)*var(225); // [ var(206) , var(155) ]
+                D[155,210] = (-1)*var(228); // [ var(210) , var(155) ]
+                D[155,214] = (-1)*var(230); // [ var(214) , var(155) ]
+                D[155,221] = var(234); // [ var(221) , var(155) ]
+                D[155,233] = var(239); // [ var(233) , var(155) ]
+                D[156,158] = (-1)*var(193); // [ var(158) , var(156) ]
+                D[156,161] = (-1)*var(194); // [ var(161) , var(156) ]
+                D[156,164] = var(197); // [ var(164) , var(156) ]
+                D[156,166] = (-1)*var(199); // [ var(166) , var(156) ]
+                D[156,171] = var(203); // [ var(171) , var(156) ]
+                D[156,177] = var(207); // [ var(177) , var(156) ]
+                D[156,178] = var(208); // [ var(178) , var(156) ]
+                D[156,184] = var(212); // [ var(184) , var(156) ]
+                D[156,189] = (-1)*var(214); // [ var(189) , var(156) ]
+                D[156,191] = var(216); // [ var(191) , var(156) ]
+                D[156,195] = (-1)*var(219); // [ var(195) , var(156) ]
+                D[156,200] = (-1)*var(223); // [ var(200) , var(156) ]
+                D[156,205] = (-1)*var(226); // [ var(205) , var(156) ]
+                D[156,213] = var(230); // [ var(213) , var(156) ]
+                D[156,217] = var(231); // [ var(217) , var(156) ]
+                D[156,235] = (-1)*var(240); // [ var(235) , var(156) ]
+                D[157,161] = (-1)*var(195); // [ var(161) , var(157) ]
+                D[157,163] = var(197); // [ var(163) , var(157) ]
+                D[157,170] = (-1)*var(201); // [ var(170) , var(157) ]
+                D[157,181] = (-1)*var(209); // [ var(181) , var(157) ]
+                D[157,188] = (-1)*var(214); // [ var(188) , var(157) ]
+                D[157,191] = var(217); // [ var(191) , var(157) ]
+                D[157,194] = (-1)*var(219); // [ var(194) , var(157) ]
+                D[157,198] = var(221); // [ var(198) , var(157) ]
+                D[157,204] = var(224); // [ var(204) , var(157) ]
+                D[157,216] = var(231); // [ var(216) , var(157) ]
+                D[157,220] = (-1)*var(233); // [ var(220) , var(157) ]
+                D[157,225] = (-1)*var(236); // [ var(225) , var(157) ]
+                D[157,228] = var(237); // [ var(228) , var(157) ]
+                D[158,163] = var(198); // [ var(163) , var(158) ]
+                D[158,169] = var(200); // [ var(169) , var(158) ]
+                D[158,175] = var(205); // [ var(175) , var(158) ]
+                D[158,176] = var(206); // [ var(176) , var(158) ]
+                D[158,182] = var(210); // [ var(182) , var(158) ]
+                D[158,190] = var(217); // [ var(190) , var(158) ]
+                D[158,194] = (-1)*var(220); // [ var(194) , var(158) ]
+                D[158,197] = var(221); // [ var(197) , var(158) ]
+                D[158,208] = (-1)*var(227); // [ var(208) , var(158) ]
+                D[158,212] = (-1)*var(229); // [ var(212) , var(158) ]
+                D[158,219] = (-1)*var(233); // [ var(219) , var(158) ]
+                D[158,222] = (-1)*var(235); // [ var(222) , var(158) ]
+                D[158,230] = var(238); // [ var(230) , var(158) ]
+                D[159,160] = var(196); // [ var(160) , var(159) ]
+                D[159,162] = (-1)*var(199); // [ var(162) , var(159) ]
+                D[159,168] = var(202); // [ var(168) , var(159) ]
+                D[159,170] = (-1)*var(204); // [ var(170) , var(159) ]
+                D[159,176] = (-1)*var(208); // [ var(176) , var(159) ]
+                D[159,182] = (-1)*var(212); // [ var(182) , var(159) ]
+                D[159,188] = (-1)*var(216); // [ var(188) , var(159) ]
+                D[159,189] = (-1)*var(217); // [ var(189) , var(159) ]
+                D[159,201] = var(224); // [ var(201) , var(159) ]
+                D[159,206] = var(227); // [ var(206) , var(159) ]
+                D[159,210] = var(229); // [ var(210) , var(159) ]
+                D[159,214] = var(231); // [ var(214) , var(159) ]
+                D[159,218] = var(234); // [ var(218) , var(159) ]
+                D[159,232] = var(239); // [ var(232) , var(159) ]
+                D[160,166] = var(200); // [ var(166) , var(160) ]
+                D[160,167] = (-1)*var(203); // [ var(167) , var(160) ]
+                D[160,174] = var(206); // [ var(174) , var(160) ]
+                D[160,179] = (-1)*var(209); // [ var(179) , var(160) ]
+                D[160,184] = var(213); // [ var(184) , var(160) ]
+                D[160,187] = (-1)*var(214); // [ var(187) , var(160) ]
+                D[160,192] = var(218); // [ var(192) , var(160) ]
+                D[160,199] = var(223); // [ var(199) , var(160) ]
+                D[160,204] = (-1)*var(225); // [ var(204) , var(160) ]
+                D[160,212] = var(230); // [ var(212) , var(160) ]
+                D[160,215] = (-1)*var(232); // [ var(215) , var(160) ]
+                D[160,224] = var(236); // [ var(224) , var(160) ]
+                D[160,229] = (-1)*var(238); // [ var(229) , var(160) ]
+                D[161,165] = var(200); // [ var(165) , var(161) ]
+                D[161,167] = (-1)*var(204); // [ var(167) , var(161) ]
+                D[161,172] = var(205); // [ var(172) , var(161) ]
+                D[161,180] = (-1)*var(211); // [ var(180) , var(161) ]
+                D[161,183] = var(213); // [ var(183) , var(161) ]
+                D[161,187] = (-1)*var(215); // [ var(187) , var(161) ]
+                D[161,193] = (-1)*var(220); // [ var(193) , var(161) ]
+                D[161,197] = (-1)*var(222); // [ var(197) , var(161) ]
+                D[161,203] = (-1)*var(225); // [ var(203) , var(161) ]
+                D[161,207] = (-1)*var(228); // [ var(207) , var(161) ]
+                D[161,214] = (-1)*var(232); // [ var(214) , var(161) ]
+                D[161,221] = var(235); // [ var(221) , var(161) ]
+                D[161,231] = (-1)*var(239); // [ var(231) , var(161) ]
+                D[162,164] = (-1)*var(201); // [ var(164) , var(162) ]
+                D[162,171] = (-1)*var(206); // [ var(171) , var(162) ]
+                D[162,177] = (-1)*var(210); // [ var(177) , var(162) ]
+                D[162,178] = (-1)*var(211); // [ var(178) , var(162) ]
+                D[162,183] = (-1)*var(214); // [ var(183) , var(162) ]
+                D[162,184] = (-1)*var(215); // [ var(184) , var(162) ]
+                D[162,190] = (-1)*var(219); // [ var(190) , var(162) ]
+                D[162,191] = (-1)*var(220); // [ var(191) , var(162) ]
+                D[162,196] = (-1)*var(223); // [ var(196) , var(162) ]
+                D[162,202] = (-1)*var(226); // [ var(202) , var(162) ]
+                D[162,213] = var(232); // [ var(213) , var(162) ]
+                D[162,217] = var(233); // [ var(217) , var(162) ]
+                D[162,234] = var(240); // [ var(234) , var(162) ]
+                D[163,165] = (-1)*var(203); // [ var(165) , var(163) ]
+                D[163,166] = (-1)*var(204); // [ var(166) , var(163) ]
+                D[163,172] = (-1)*var(207); // [ var(172) , var(163) ]
+                D[163,173] = (-1)*var(208); // [ var(173) , var(163) ]
+                D[163,179] = (-1)*var(212); // [ var(179) , var(163) ]
+                D[163,186] = (-1)*var(216); // [ var(186) , var(163) ]
+                D[163,189] = var(218); // [ var(189) , var(163) ]
+                D[163,195] = var(222); // [ var(195) , var(163) ]
+                D[163,200] = var(225); // [ var(200) , var(163) ]
+                D[163,205] = var(228); // [ var(205) , var(163) ]
+                D[163,209] = var(230); // [ var(209) , var(163) ]
+                D[163,217] = (-1)*var(234); // [ var(217) , var(163) ]
+                D[163,233] = (-1)*var(240); // [ var(233) , var(163) ]
+                D[164,181] = var(213); // [ var(181) , var(164) ]
+                D[164,186] = (-1)*var(217); // [ var(186) , var(164) ]
+                D[164,188] = var(218); // [ var(188) , var(164) ]
+                D[164,193] = (-1)*var(221); // [ var(193) , var(164) ]
+                D[164,194] = var(222); // [ var(194) , var(164) ]
+                D[164,199] = (-1)*var(224); // [ var(199) , var(164) ]
+                D[164,216] = (-1)*var(234); // [ var(216) , var(164) ]
+                D[164,220] = var(235); // [ var(220) , var(164) ]
+                D[164,223] = (-1)*var(236); // [ var(223) , var(164) ]
+                D[164,226] = var(237); // [ var(226) , var(164) ]
+                D[165,170] = (-1)*var(206); // [ var(170) , var(165) ]
+                D[165,175] = var(209); // [ var(175) , var(165) ]
+                D[165,182] = var(214); // [ var(182) , var(165) ]
+                D[165,184] = (-1)*var(217); // [ var(184) , var(165) ]
+                D[165,192] = (-1)*var(221); // [ var(192) , var(165) ]
+                D[165,194] = (-1)*var(223); // [ var(194) , var(165) ]
+                D[165,204] = var(227); // [ var(204) , var(165) ]
+                D[165,212] = (-1)*var(231); // [ var(212) , var(165) ]
+                D[165,215] = var(233); // [ var(215) , var(165) ]
+                D[165,222] = var(236); // [ var(222) , var(165) ]
+                D[165,228] = (-1)*var(238); // [ var(228) , var(165) ]
+                D[166,168] = (-1)*var(205); // [ var(168) , var(166) ]
+                D[166,176] = var(211); // [ var(176) , var(166) ]
+                D[166,182] = var(215); // [ var(182) , var(166) ]
+                D[166,183] = (-1)*var(217); // [ var(183) , var(166) ]
+                D[166,188] = var(220); // [ var(188) , var(166) ]
+                D[166,197] = var(224); // [ var(197) , var(166) ]
+                D[166,203] = var(227); // [ var(203) , var(166) ]
+                D[166,207] = var(229); // [ var(207) , var(166) ]
+                D[166,214] = var(233); // [ var(214) , var(166) ]
+                D[166,218] = var(235); // [ var(218) , var(166) ]
+                D[166,230] = (-1)*var(239); // [ var(230) , var(166) ]
+                D[167,168] = var(207); // [ var(168) , var(167) ]
+                D[167,169] = var(208); // [ var(169) , var(167) ]
+                D[167,175] = var(212); // [ var(175) , var(167) ]
+                D[167,181] = var(216); // [ var(181) , var(167) ]
+                D[167,189] = (-1)*var(221); // [ var(189) , var(167) ]
+                D[167,195] = (-1)*var(224); // [ var(195) , var(167) ]
+                D[167,200] = (-1)*var(227); // [ var(200) , var(167) ]
+                D[167,205] = (-1)*var(229); // [ var(205) , var(167) ]
+                D[167,209] = (-1)*var(231); // [ var(209) , var(167) ]
+                D[167,213] = (-1)*var(234); // [ var(213) , var(167) ]
+                D[167,232] = (-1)*var(240); // [ var(232) , var(167) ]
+                D[168,173] = var(209); // [ var(173) , var(168) ]
+                D[168,174] = var(210); // [ var(174) , var(168) ]
+                D[168,178] = (-1)*var(213); // [ var(178) , var(168) ]
+                D[168,180] = var(214); // [ var(180) , var(168) ]
+                D[168,185] = (-1)*var(218); // [ var(185) , var(168) ]
+                D[168,199] = var(226); // [ var(199) , var(168) ]
+                D[168,204] = (-1)*var(228); // [ var(204) , var(168) ]
+                D[168,208] = (-1)*var(230); // [ var(208) , var(168) ]
+                D[168,211] = var(232); // [ var(211) , var(168) ]
+                D[168,224] = (-1)*var(237); // [ var(224) , var(168) ]
+                D[168,227] = var(238); // [ var(227) , var(168) ]
+                D[169,172] = var(209); // [ var(172) , var(169) ]
+                D[169,174] = var(211); // [ var(174) , var(169) ]
+                D[169,177] = (-1)*var(213); // [ var(177) , var(169) ]
+                D[169,187] = (-1)*var(219); // [ var(187) , var(169) ]
+                D[169,192] = var(222); // [ var(192) , var(169) ]
+                D[169,193] = (-1)*var(223); // [ var(193) , var(169) ]
+                D[169,198] = var(225); // [ var(198) , var(169) ]
+                D[169,207] = (-1)*var(230); // [ var(207) , var(169) ]
+                D[169,210] = var(232); // [ var(210) , var(169) ]
+                D[169,221] = (-1)*var(236); // [ var(221) , var(169) ]
+                D[169,229] = var(239); // [ var(229) , var(169) ]
+                D[170,172] = var(210); // [ var(172) , var(170) ]
+                D[170,173] = var(211); // [ var(173) , var(170) ]
+                D[170,179] = var(215); // [ var(179) , var(170) ]
+                D[170,183] = var(218); // [ var(183) , var(170) ]
+                D[170,186] = var(220); // [ var(186) , var(170) ]
+                D[170,190] = var(222); // [ var(190) , var(170) ]
+                D[170,196] = var(225); // [ var(196) , var(170) ]
+                D[170,202] = var(228); // [ var(202) , var(170) ]
+                D[170,209] = var(232); // [ var(209) , var(170) ]
+                D[170,217] = (-1)*var(235); // [ var(217) , var(170) ]
+                D[170,231] = var(240); // [ var(231) , var(170) ]
+                D[171,175] = (-1)*var(213); // [ var(175) , var(171) ]
+                D[171,179] = var(217); // [ var(179) , var(171) ]
+                D[171,182] = (-1)*var(218); // [ var(182) , var(171) ]
+                D[171,187] = var(221); // [ var(187) , var(171) ]
+                D[171,194] = var(225); // [ var(194) , var(171) ]
+                D[171,199] = (-1)*var(227); // [ var(199) , var(171) ]
+                D[171,212] = var(234); // [ var(212) , var(171) ]
+                D[171,215] = (-1)*var(235); // [ var(215) , var(171) ]
+                D[171,219] = var(236); // [ var(219) , var(171) ]
+                D[171,226] = (-1)*var(238); // [ var(226) , var(171) ]
+                D[172,176] = (-1)*var(214); // [ var(176) , var(172) ]
+                D[172,178] = var(217); // [ var(178) , var(172) ]
+                D[172,185] = var(221); // [ var(185) , var(172) ]
+                D[172,194] = (-1)*var(226); // [ var(194) , var(172) ]
+                D[172,204] = var(229); // [ var(204) , var(172) ]
+                D[172,208] = var(231); // [ var(208) , var(172) ]
+                D[172,211] = (-1)*var(233); // [ var(211) , var(172) ]
+                D[172,222] = (-1)*var(237); // [ var(222) , var(172) ]
+                D[172,225] = var(238); // [ var(225) , var(172) ]
+                D[173,177] = var(217); // [ var(177) , var(173) ]
+                D[173,182] = var(219); // [ var(182) , var(173) ]
+                D[173,188] = var(223); // [ var(188) , var(173) ]
+                D[173,192] = (-1)*var(224); // [ var(192) , var(173) ]
+                D[173,198] = (-1)*var(227); // [ var(198) , var(173) ]
+                D[173,207] = var(231); // [ var(207) , var(173) ]
+                D[173,210] = (-1)*var(233); // [ var(210) , var(173) ]
+                D[173,218] = (-1)*var(236); // [ var(218) , var(173) ]
+                D[173,228] = var(239); // [ var(228) , var(173) ]
+                D[174,175] = (-1)*var(215); // [ var(175) , var(174) ]
+                D[174,181] = (-1)*var(220); // [ var(181) , var(174) ]
+                D[174,183] = (-1)*var(221); // [ var(183) , var(174) ]
+                D[174,190] = (-1)*var(224); // [ var(190) , var(174) ]
+                D[174,196] = (-1)*var(227); // [ var(196) , var(174) ]
+                D[174,202] = (-1)*var(229); // [ var(202) , var(174) ]
+                D[174,209] = (-1)*var(233); // [ var(209) , var(174) ]
+                D[174,213] = (-1)*var(235); // [ var(213) , var(174) ]
+                D[174,230] = var(240); // [ var(230) , var(174) ]
+                D[175,180] = var(219); // [ var(180) , var(175) ]
+                D[175,185] = (-1)*var(222); // [ var(185) , var(175) ]
+                D[175,193] = (-1)*var(226); // [ var(193) , var(175) ]
+                D[175,198] = var(228); // [ var(198) , var(175) ]
+                D[175,203] = var(230); // [ var(203) , var(175) ]
+                D[175,206] = (-1)*var(232); // [ var(206) , var(175) ]
+                D[175,221] = var(237); // [ var(221) , var(175) ]
+                D[175,227] = (-1)*var(239); // [ var(227) , var(175) ]
+                D[176,177] = (-1)*var(218); // [ var(177) , var(176) ]
+                D[176,179] = var(219); // [ var(179) , var(176) ]
+                D[176,184] = (-1)*var(222); // [ var(184) , var(176) ]
+                D[176,186] = var(223); // [ var(186) , var(176) ]
+                D[176,191] = (-1)*var(225); // [ var(191) , var(176) ]
+                D[176,202] = var(230); // [ var(202) , var(176) ]
+                D[176,205] = (-1)*var(232); // [ var(205) , var(176) ]
+                D[176,217] = var(236); // [ var(217) , var(176) ]
+                D[176,229] = (-1)*var(240); // [ var(229) , var(176) ]
+                D[177,180] = (-1)*var(221); // [ var(180) , var(177) ]
+                D[177,194] = var(228); // [ var(194) , var(177) ]
+                D[177,199] = (-1)*var(229); // [ var(199) , var(177) ]
+                D[177,208] = (-1)*var(234); // [ var(208) , var(177) ]
+                D[177,211] = var(235); // [ var(211) , var(177) ]
+                D[177,219] = (-1)*var(237); // [ var(219) , var(177) ]
+                D[177,223] = var(238); // [ var(223) , var(177) ]
+                D[178,182] = (-1)*var(222); // [ var(182) , var(178) ]
+                D[178,187] = var(224); // [ var(187) , var(178) ]
+                D[178,188] = (-1)*var(225); // [ var(188) , var(178) ]
+                D[178,193] = var(227); // [ var(193) , var(178) ]
+                D[178,207] = (-1)*var(234); // [ var(207) , var(178) ]
+                D[178,210] = var(235); // [ var(210) , var(178) ]
+                D[178,214] = (-1)*var(236); // [ var(214) , var(178) ]
+                D[178,226] = var(239); // [ var(226) , var(178) ]
+                D[179,185] = var(224); // [ var(185) , var(179) ]
+                D[179,188] = var(226); // [ var(188) , var(179) ]
+                D[179,198] = (-1)*var(229); // [ var(198) , var(179) ]
+                D[179,203] = (-1)*var(231); // [ var(203) , var(179) ]
+                D[179,206] = var(233); // [ var(206) , var(179) ]
+                D[179,218] = var(237); // [ var(218) , var(179) ]
+                D[179,225] = (-1)*var(239); // [ var(225) , var(179) ]
+                D[180,181] = (-1)*var(223); // [ var(181) , var(180) ]
+                D[180,184] = var(224); // [ var(184) , var(180) ]
+                D[180,191] = var(227); // [ var(191) , var(180) ]
+                D[180,202] = (-1)*var(231); // [ var(202) , var(180) ]
+                D[180,205] = var(233); // [ var(205) , var(180) ]
+                D[180,213] = var(236); // [ var(213) , var(180) ]
+                D[180,228] = (-1)*var(240); // [ var(228) , var(180) ]
+                D[181,185] = (-1)*var(225); // [ var(185) , var(181) ]
+                D[181,187] = var(226); // [ var(187) , var(181) ]
+                D[181,192] = (-1)*var(228); // [ var(192) , var(181) ]
+                D[181,197] = (-1)*var(230); // [ var(197) , var(181) ]
+                D[181,201] = var(232); // [ var(201) , var(181) ]
+                D[181,221] = (-1)*var(238); // [ var(221) , var(181) ]
+                D[181,224] = var(239); // [ var(224) , var(181) ]
+                D[182,186] = var(226); // [ var(186) , var(182) ]
+                D[182,191] = (-1)*var(228); // [ var(191) , var(182) ]
+                D[182,196] = (-1)*var(230); // [ var(196) , var(182) ]
+                D[182,200] = var(232); // [ var(200) , var(182) ]
+                D[182,217] = (-1)*var(237); // [ var(217) , var(182) ]
+                D[182,227] = var(240); // [ var(227) , var(182) ]
+                D[183,194] = var(230); // [ var(194) , var(183) ]
+                D[183,199] = (-1)*var(231); // [ var(199) , var(183) ]
+                D[183,204] = var(234); // [ var(204) , var(183) ]
+                D[183,211] = (-1)*var(236); // [ var(211) , var(183) ]
+                D[183,215] = var(237); // [ var(215) , var(183) ]
+                D[183,220] = (-1)*var(238); // [ var(220) , var(183) ]
+                D[184,188] = (-1)*var(228); // [ var(188) , var(184) ]
+                D[184,193] = var(229); // [ var(193) , var(184) ]
+                D[184,203] = var(234); // [ var(203) , var(184) ]
+                D[184,206] = (-1)*var(235); // [ var(206) , var(184) ]
+                D[184,214] = var(237); // [ var(214) , var(184) ]
+                D[184,223] = (-1)*var(239); // [ var(223) , var(184) ]
+                D[185,186] = (-1)*var(227); // [ var(186) , var(185) ]
+                D[185,202] = var(234); // [ var(202) , var(185) ]
+                D[185,205] = (-1)*var(235); // [ var(205) , var(185) ]
+                D[185,209] = var(236); // [ var(209) , var(185) ]
+                D[185,226] = (-1)*var(240); // [ var(226) , var(185) ]
+                D[186,192] = var(229); // [ var(192) , var(186) ]
+                D[186,197] = var(231); // [ var(197) , var(186) ]
+                D[186,201] = (-1)*var(233); // [ var(201) , var(186) ]
+                D[186,218] = (-1)*var(238); // [ var(218) , var(186) ]
+                D[186,222] = var(239); // [ var(222) , var(186) ]
+                D[187,191] = var(229); // [ var(191) , var(187) ]
+                D[187,196] = var(231); // [ var(196) , var(187) ]
+                D[187,200] = (-1)*var(233); // [ var(200) , var(187) ]
+                D[187,213] = (-1)*var(237); // [ var(213) , var(187) ]
+                D[187,225] = var(240); // [ var(225) , var(187) ]
+                D[188,190] = var(230); // [ var(190) , var(188) ]
+                D[188,195] = (-1)*var(232); // [ var(195) , var(188) ]
+                D[188,217] = var(238); // [ var(217) , var(188) ]
+                D[188,224] = (-1)*var(240); // [ var(224) , var(188) ]
+                D[189,194] = (-1)*var(232); // [ var(194) , var(189) ]
+                D[189,199] = var(233); // [ var(199) , var(189) ]
+                D[189,204] = (-1)*var(235); // [ var(204) , var(189) ]
+                D[189,208] = var(236); // [ var(208) , var(189) ]
+                D[189,212] = (-1)*var(237); // [ var(212) , var(189) ]
+                D[189,216] = var(238); // [ var(216) , var(189) ]
+                D[190,193] = var(231); // [ var(193) , var(190) ]
+                D[190,198] = (-1)*var(234); // [ var(198) , var(190) ]
+                D[190,206] = var(236); // [ var(206) , var(190) ]
+                D[190,210] = (-1)*var(237); // [ var(210) , var(190) ]
+                D[190,220] = var(239); // [ var(220) , var(190) ]
+                D[191,197] = (-1)*var(234); // [ var(197) , var(191) ]
+                D[191,201] = var(235); // [ var(201) , var(191) ]
+                D[191,214] = (-1)*var(238); // [ var(214) , var(191) ]
+                D[191,219] = var(239); // [ var(219) , var(191) ]
+                D[192,196] = (-1)*var(234); // [ var(196) , var(192) ]
+                D[192,200] = var(235); // [ var(200) , var(192) ]
+                D[192,209] = (-1)*var(237); // [ var(209) , var(192) ]
+                D[192,223] = var(240); // [ var(223) , var(192) ]
+                D[193,195] = var(233); // [ var(195) , var(193) ]
+                D[193,213] = var(238); // [ var(213) , var(193) ]
+                D[193,222] = (-1)*var(240); // [ var(222) , var(193) ]
+                D[194,217] = (-1)*var(239); // [ var(217) , var(194) ]
+                D[194,221] = var(240); // [ var(221) , var(194) ]
+                D[195,198] = var(235); // [ var(198) , var(195) ]
+                D[195,203] = (-1)*var(236); // [ var(203) , var(195) ]
+                D[195,207] = var(237); // [ var(207) , var(195) ]
+                D[195,216] = (-1)*var(239); // [ var(216) , var(195) ]
+                D[196,201] = (-1)*var(236); // [ var(201) , var(196) ]
+                D[196,210] = var(238); // [ var(210) , var(196) ]
+                D[196,215] = (-1)*var(239); // [ var(215) , var(196) ]
+                D[197,200] = (-1)*var(236); // [ var(200) , var(197) ]
+                D[197,205] = var(237); // [ var(205) , var(197) ]
+                D[197,220] = (-1)*var(240); // [ var(220) , var(197) ]
+                D[198,209] = var(238); // [ var(209) , var(198) ]
+                D[198,219] = (-1)*var(240); // [ var(219) , var(198) ]
+                D[199,213] = (-1)*var(239); // [ var(213) , var(199) ]
+                D[199,218] = var(240); // [ var(218) , var(199) ]
+                D[200,207] = (-1)*var(238); // [ var(207) , var(200) ]
+                D[200,212] = var(239); // [ var(212) , var(200) ]
+                D[201,202] = (-1)*var(237); // [ var(202) , var(201) ]
+                D[201,216] = var(240); // [ var(216) , var(201) ]
+                D[202,206] = (-1)*var(238); // [ var(206) , var(202) ]
+                D[202,211] = var(239); // [ var(211) , var(202) ]
+                D[203,205] = (-1)*var(238); // [ var(205) , var(203) ]
+                D[203,215] = var(240); // [ var(215) , var(203) ]
+                D[204,209] = (-1)*var(239); // [ var(209) , var(204) ]
+                D[204,214] = var(240); // [ var(214) , var(204) ]
+                D[205,208] = (-1)*var(239); // [ var(208) , var(205) ]
+                D[206,212] = (-1)*var(240); // [ var(212) , var(206) ]
+                D[207,211] = (-1)*var(240); // [ var(211) , var(207) ]
+                D[208,210] = (-1)*var(240); // [ var(210) , var(208) ]
+   def @@RR=nc_algebra(1,D);
+   return(@@RR);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   def ncAlgebra = makeUe8();
+   ncAlgebra;
+   setring ncAlgebra;
+   // ...  7752  noncommutative relations
+}
+////////////////////////////////////////////////////////////////////
diff --git a/Singular/LIB/ncall.lib b/Singular/LIB/ncall.lib
new file mode 100644
index 0000000..28ff6dc
--- /dev/null
+++ b/Singular/LIB/ncall.lib
@@ -0,0 +1,31 @@
+//////////////////////////////////////////////////////////////////////////////
+version="version ncall.lib 4.0.0.0 Jun_2013 "; // $Id: 378f3411e490f1857e026a7d4bf01854b9e16c29 $
+category = "Noncommutative";
+info="
+LIBRARY:  ncall.lib   Load all noncommutative libraries
+
+ at format
+  central.lib:     Computation of central elements of G- and GR-algebras
+  ncalg.lib:       Definitions of important GR-algebras
+  ncdecomp.lib:    Central character decomposition of a module
+  nctools.lib:     General tools for noncommutative algebras
+  gkdim.lib:       Procedures for calculating the Gelfand-Kirillov dimension
+  qmatrix.lib:     Quantum matrices, quantum minors and symmetric groups
+  involut.lib:     Computations and operations with involutions
+  perron.lib:      Computation of algebraic dependences
+ at end format
+";
+
+//  nchomolog.lib:   Noncommutative homological algebra
+///////////////////////////////////////////////////////////////////////////////
+
+LIB "central.lib";
+LIB "ncalg.lib";
+LIB "ncdecomp.lib";
+LIB "nctools.lib";
+LIB "gkdim.lib";
+LIB "qmatrix.lib";
+LIB "involut.lib";
+LIB "dmod.lib";
+LIB "perron.lib";
+//LIB "nchomolog.lib";
diff --git a/Singular/LIB/ncdecomp.lib b/Singular/LIB/ncdecomp.lib
new file mode 100644
index 0000000..4682f14
--- /dev/null
+++ b/Singular/LIB/ncdecomp.lib
@@ -0,0 +1,464 @@
+//////////////////////////////////////////////////////////////////////////////
+version="version ncdecomp.lib 4.0.0.0 Jun_2013 "; // $Id: cdb78216d4cb2c0f8aa563e5e67052fb5e228be2 $
+category="Noncommutative";
+info="
+LIBRARY:  ncdecomp.lib     Decomposition of a module into its central characters
+AUTHORS:  Viktor Levandovskyy,     levandov at mathematik.uni-kl.de.
+
+OVERVIEW:
+@* This library presents algorithms for the central character decomposition of a module,
+@* i.e. a decomposition into generalized weight modules with respect to the center.
+@* Based on ideas of O. Khomenko and V. Levandovskyy (see the article [L2] in the
+@* References for details).
+
+PROCEDURES:
+CentralQuot(M,G);       central quotient M:G,
+CentralSaturation(M,T); central saturation ((M:T):...):T) ( = M:T^infinity),
+CenCharDec(I,C);        decomposition of I into central characters w.r.t. C
+IntersectWithSub(M,Z);  intersection of M with the subalgebra, generated by pairwise commutative elements of Z.
+";
+
+  LIB "ncalg.lib";
+  LIB "primdec.lib";
+  LIB "central.lib";
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc testncdecomplib()
+{
+  example CentralQuot;
+  example CentralSaturation;
+  example CenCharDec;
+  example IntersectWithSub;
+}
+
+static proc CharKernel(list L, int i)
+{
+ // todo: think on more effective way of doing it...
+// compute \cup L[j], j!=i
+  int sL = size(L);
+  if ( (i<=0) || (i>sL))  { return(0); }
+  int j;
+  list Li;
+  if (i ==1 )
+  {
+    Li = L[2..sL];
+  }
+  if (i ==sL )
+  {
+    Li = L[1..sL-1];
+  }
+  if ( (i>1) && (i < sL))
+  {
+    Li = L[1..i-1];
+    for (j=i+1; j<=sL; j++)
+    {
+      Li[j-1] = L[j];
+    }
+  }
+//  print("intersecting kernels...");
+  module Cres = intersect(Li[1..size(Li)]); // uses std, try modulo!
+  return(Cres);
+}
+///////////////////////////////////////////////////////////////////////////////
+static proc CentralQuotPoly(module M, poly g)
+{
+// here an elimination of components should be used !
+  int N=nrows(M); // M = A^N /I_M
+  module @M;
+  int i,j;
+  for(i=1; i<=N; i++)
+  {
+   @M=@M,g*gen(i);
+  }
+  @M = simplify(@M,2);
+  @M = @M,M;
+  module S = syz(@M);
+  matrix s = S;
+  module T;
+  vector t;
+  for(i=1; i<=ncols(s); i++)
+  {
+    t = 0*gen(N);
+    for(j=1; j<=N; j++)
+    {
+      t = t + s[j,i]*gen(j);
+    }
+    T[i] = t;
+  }
+  T = simplify(T,2);
+  return(T);
+}
+///////////////////////////////////////////////////////////////////////////////
+static proc MyIsEqual(module A, module B)
+{
+// both A and B are submodules of free module
+  option(redSB);
+  option(redTail);
+  if (attrib(A,"isSB")!=1)
+  {
+    A = slimgb(A);
+  }
+  if (attrib(B,"isSB")!=1)
+  {
+    B = slimgb(B);
+  }
+  int ANSWER = 1;
+  if ( ( ncols(A) == ncols(B) ) && ( nrows(A) == nrows(B) ) )
+  {
+    module @AB = module(matrix(A)-matrix(B));
+    @AB = simplify(@AB,2);
+    if (@AB[1]!=0) { ANSWER = 0; }
+  }
+  else { ANSWER = 0; }
+  return(ANSWER);
+}
+///////////////////////////////////////////////////////////////////////////////
+proc CentralQuot(module I, ideal G)
+"USAGE:  CentralQuot(M, G), M a module, G an ideal
+ASSUME: G is an ideal in the center of the base ring
+RETURN:  module
+PURPOSE: compute the central quotient M:G
+THEORY:  for an ideal G of the center of an algebra and a submodule M of A^n,
+@* the central quotient of M by G is defined to be
+@* M:G  :=  { v in A^n | z*v in M, for all z in G }.
+NOTE:    the output module is not necessarily given in a Groebner basis
+SEE ALSO: CentralSaturation, CenCharDec
+EXAMPLE: example CentralQuot; shows examples
+"{
+/* check assupmtion. Elt's of G must be central */
+  if (! inCenter(G) )
+  {
+    ERROR("ideal in the 2nd argument is not in the center of the base ring!");
+  }
+  int i;
+  list @L;
+  for(i=1; i<=size(G); i++)
+  {
+    @L[i] = CentralQuotPoly(I,G[i]);
+  }
+  module @I = intersect(@L[1..size(G)]);
+  if (nrows(@I)==1)
+  {
+    @I = ideal(@I);
+  }
+  return(@I);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   option(returnSB);
+   def a = makeUsl2();
+   setring a;
+   ideal I = e3,f3,h3-4*h;
+   I = std(I);
+   poly C=4*e*f+h^2-2*h;  // C in Z(U(sl2)), the central element
+   ideal G = (C-8)*(C-24);  // G normal factor in Z(U(sl2)) as an ideal in the center
+   ideal R = CentralQuot(I,G);  // same as I:G
+   R;
+}
+///////////////////////////////////////////////////////////////////////////////
+proc CentralSaturation(module M, ideal T)
+"USAGE:  CentralSaturation(M, T), for a module M and an ideal T
+ASSUME: T is an ideal in the center of the base ring
+RETURN:  module
+PURPOSE: compute the central saturation of M by T, that is M:T^{\infty}, by repititive application of @code{CentralQuot}
+NOTE:    the output module is not necessarily a Groebner basis
+SEE ALSO: CentralQuot, CenCharDec
+EXAMPLE: example CentralSaturation; shows examples
+"{
+/* check assupmtion. Elt's of T must be central */
+  if (! inCenter(T) )
+  {
+    ERROR("ideal in the 2nd argument is not in the center of the base ring!");
+  }
+  option(redSB);
+  option(redTail);
+  option(returnSB);
+  module Q=0;
+  module S=M;
+  while ( !MyIsEqual(Q,S) )
+  {
+    Q = CentralQuot(S, T);
+    S = CentralQuot(Q, T);
+  }
+  if (nrows(Q)==1)
+  {
+    Q = ideal(Q);
+  }
+//  Q = std(Q);
+  return(Q);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   option(returnSB);
+   def a = makeUsl2();
+   setring a;
+   ideal I = e3,f3,h3-4*h;
+   I = std(I);
+   poly C=4*e*f+h^2-2*h;
+   ideal G = C*(C-8);
+   ideal R = CentralSaturation(I,G);
+   R=std(R);
+   vdim(R);
+   R;
+}
+///////////////////////////////////////////////////////////////////////////////
+proc CenCharDec(module I, def #)
+"USAGE:  CenCharDec(I, C);  I a module, C an ideal
+ASSUME: C consists of generators of the center of the base ring
+RETURN:  a list L, where each entry consists of three records (if a finite decomposition exists)
+@*       L[*][1] ('ideal' type), the central character as a maximal ideal in the center,
+@*       L[*][2] ('module' type), the Groebner basis of the weight module, corresponding to the character in  L[*][1],
+@*       L[*][3] ('int' type) is the vector space dimension of the weight module (-1 in case of infinite dimension);
+PURPOSE: compute a finite decomposition of C into central characters or determine that there is no finite decomposition
+NOTE:     actual decomposition is the sum of L[i][2] above;
+@*        some modules have no finite decomposition (in such case one gets warning message)
+@*        The function @code{central} in @code{central.lib} may be used to obtain C, when needed.
+SEE ALSO: CentralQuot, CentralSaturation
+EXAMPLE: example CenCharDec; shows examples
+"
+{
+  list Center;
+  if (typeof(#) == "ideal")
+  {
+    int cc;
+    ideal tmp = ideal(#);
+    for (cc=1; cc<=size(tmp); cc++)
+    {
+      Center[cc] = tmp[cc];
+    }
+    kill tmp;
+  }
+  if (typeof(#) == "list")
+  {
+    Center = #;
+  }
+
+/* check assupmtion. Elt's of G must be central */
+  if (! inCenter(Center) )
+  {
+    ERROR("ideal in the 2nd argument is not in the center of the base ring!");
+  }
+  int ppl = printlevel-voice+2;
+// M = A/I
+//1. Find the Zariski closure of Supp_Z M
+// J = Ann_M 1 == I
+// J \cap Z:
+  option(redSB);
+  option(redTail);
+  option(returnSB);
+  def @A = basering;
+  setring @A;
+  int sZ=size(Center);
+  int i,j;
+  poly t=1;
+  for(i=1; i<=nvars(@A); i++)
+  {
+    t=t*var(i);
+  }
+  ring @Z=0,(@z(1..sZ)),dp;
+//  @Z;
+  def @ZplusA = @A+ at Z;
+  setring @ZplusA;
+//  @ZplusA;
+  ideal I     = imap(@A,I);
+  list Center = imap(@A,Center);
+  poly t      = imap(@A,t);
+  ideal @Ker;
+  for(i=1; i<=sZ; i++)
+  {
+    @Ker[i]=@z(i) - Center[i];
+  }
+  @Ker = @Ker,I;
+  //  ideal @JcapZ = eliminate(@Ker,t);
+  dbprint(ppl,"// -1-1- starting the computation of preimage in Z");
+  dbprint(ppl-1, @Ker);
+  ideal @JcapZ = slimgb(@Ker);
+  @JcapZ = nselect(@JcapZ,intvec(1..nvars(@A)));
+  dbprint(ppl,"// -1-2- finished the computation of preimage in Z");
+  dbprint(ppl-1, @JcapZ);
+// do not forget parameters of a basering!
+// hmmm: todo ringlist
+  string strZ="ring @@Z=("+charstr(@A)+"),(@z(1.."+string(sZ)+")),dp;";
+//  print(strZ);
+  execute(strZ);
+  setring @@Z;
+  ideal @JcapZ = imap(@ZplusA, at JcapZ);
+  dbprint(ppl,"// -1-3- starting the cosmetic Groebner basis in Z");
+  @JcapZ = slimgb(@JcapZ); // evtl. groebner?
+//  @JcapZ;
+  dbprint(ppl,"// -1-4- finished the cosmetic Groebner basis in Z");
+  dbprint(ppl-1, @JcapZ);
+  int sJ = vdim(@JcapZ);
+  dbprint(ppl,"// -1-5- the K-dimension of support is "+string(sJ));
+  if (sJ==-1)
+  {
+    "There is no finite decomposition";
+    return(0);
+  }
+//  print(@JcapZ);
+// 2. compute the min.ass.primes of the ideal in the center
+  dbprint(ppl,"// -2-1- starting the computation of minimal primes in Z");
+  list @L = minAssGTZ(@JcapZ);
+  int sL = size(@L);
+  dbprint(ppl,"// -2-2- finished the computation of " + string(sL)+ " minimal primes in Z");
+//  print("etL:");
+//  @L;
+// exception: is sL==1, the whole ideal has unique cen.char
+  if (sL ==1)
+  {
+    dbprint(ppl-1,"// -2-3- the whole module is gen. weight module itself");
+    setring @A;
+    map @M = @@Z,Center[1..size(Center)];
+    list L = @M(@L);
+    list @R;
+    @R[1] = L[1];
+    if (nrows(@R[1])==1)
+    {
+      @R[1] = ideal(@R[1]);
+    }
+    @R[2] = I;
+    if (nrows(@R[2])==1)
+    {
+      @R[2] = ideal(@R[2]);
+    }
+    dbprint(ppl-1,"// -2-4- final cosmetic Groebner basis");
+    @R[2] = slimgb(@R[2]);
+    @R[3] = vdim(@R[2]);
+    return(list(@R)); // for compliance with output a list
+  }
+  dbprint(ppl-1,"// -2-3- there are several characters");
+  dbprint(ppl,"// -*- computing Groebner bases of components (commutative)");
+  list @CharKer;
+  for(i=1; i<=sL; i++)
+  {
+    @L[i] = slimgb(@L[i]);
+  }
+  dbprint(ppl,"// -*- finished computing Groebner bases of components");
+// 3. compute the intersections of characters
+  dbprint(ppl,"// -3- compute the intersections of characters");
+  for(i=1; i<=sL; i++)
+  {
+    @CharKer[i] = CharKernel(@L,i);
+  }
+  dbprint(ppl,"// -3- the intersections of characters is done");
+  //  dbprint(ppl-1, at CharKer);
+// 4. Go back to the algebra and compute central saturations
+  setring @A;
+  map @M = @@Z,Center[1..size(Center)];
+  list L = @M(@CharKer);
+  list R, at R;
+  dbprint(ppl,"// -4- compute the central saturations");
+  dbprint(ppl-1,L);
+  for(i=1; i<=sL; i++)
+  {
+    @R[1] = L[i];
+    if (nrows(@R[1])==1)
+    {
+      @R[1] = ideal(@R[1]);
+    }
+    @R[2] = CentralSaturation(I,L[i]);
+    if (nrows(@R[2])==1)
+    {
+      @R[2] = ideal(@R[2]);
+    }
+    @R[2] = slimgb(@R[2]);
+    @R[3] = vdim(@R[2]);
+     R[i] = @R;
+  }
+  dbprint(ppl,"// -4- central saturations are done");
+  return(R);
+}
+example
+{ "EXAMPLE:"; echo = 2; printlevel=0;
+   option(returnSB);
+   def a = makeUsl2(); // U(sl_2) in characteristic 0
+   setring a;
+   ideal I = e3,f3,h3-4*h;
+   I = twostd(I);           // two-sided ideal generated by I
+   vdim(I);                 // it is finite-dimensional
+   ideal Cn = 4*e*f+h^2-2*h; // the only central element
+   list T = CenCharDec(I,Cn);
+   T;
+   // consider another example
+   ideal J = e*f*h;
+   CenCharDec(J,Cn);
+}
+///////////////////////////////////////////////////////////////////////////////
+proc IntersectWithSub (ideal M, def #)
+"USAGE:  IntersectWithSub(M,Z),  M an ideal, Z an ideal
+ASSUME: Z consists of pairwise commutative elements
+RETURN:  ideal of two-sided generators, not a Groebner basis
+PURPOSE: computes the intersection of M with the subalgebra, generated by Z
+NOTE:    usually Z consists of generators of the center
+@* The function @code{central} from @code{central.lib} may be used to obtain the center Z, if needed.
+EXAMPLE: example IntersectWithSub; shows an example
+"
+{
+  ideal Z;
+  if (typeof(#) == "list")
+  {
+    int cc;
+    list tmp = #;
+    for (cc=1; cc<=size(tmp); cc++)
+    {
+      Z[cc] = tmp[cc];
+    }
+    kill tmp;
+  }
+  if (typeof(#) == "ideal")
+  {
+    Z = #;
+  }
+  // returns a submodule of M, equal to M \cap Z
+  // assume/correctness: Z should consists of pairwise
+  // commutative elements
+  int nz = size(Z);
+  int i,j;
+  poly p;
+  for (i=1; i<nz; i++)
+  {
+    for (j=i+1; j<=nz; j++)
+    {
+      p = bracket(Z[i],Z[j]);
+      if (p!=0)
+      {
+        ERROR("generators of the subalgebra do not commute.");
+        //        return(ideal(0));
+      }
+    }
+  }
+  // main action
+  def B = basering;
+  setring B;
+  string s1,s2;
+  // todo: make ringlist from it!
+  s1 = "ring @Z = (";
+  s2 = s1 + charstr(basering) + "),(z(1.." + string(nz)+")),Dp";
+  //  s2;
+  execute(s2);
+  setring B;
+  map F = @Z,Z;
+  setring @Z;
+  ideal PreM = preimage(B,F,M); // reformulate using gb engine? todo?
+  PreM = slimgb(PreM);
+  setring B;
+  ideal T = F(PreM);
+  return(T);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring R=(0,a),(e,f,h),Dp;
+  matrix @d[3][3];
+  @d[1,2]=-h;   @d[1,3]=2e;   @d[2,3]=-2f;
+  def r = nc_algebra(1, at d); setring r; // parametric U(sl_2)
+  ideal I = e,h-a;
+  ideal C;
+  C[1] = h^2-2*h+4*e*f; // the center of U(sl_2)
+  ideal X = IntersectWithSub(I,C);
+  X;
+  ideal G = e*f, h; // the biggest comm. subalgebra of U(sl_2)
+  ideal Y = IntersectWithSub(I,G);
+  Y;
+}
diff --git a/Singular/LIB/ncfactor.lib b/Singular/LIB/ncfactor.lib
new file mode 100644
index 0000000..db02724
--- /dev/null
+++ b/Singular/LIB/ncfactor.lib
@@ -0,0 +1,9071 @@
+///////////////////////////////////////////////////////////
+version="version ncfactor.lib 4.0.0.0 Jun_2014 "; // $Id: 10450903cf0b34cf0c3ff0a90166426f8b60de1b $
+category="Noncommutative";
+info="
+LIBRARY: ncfactor.lib  Tools for factorization in some noncommutative algebras
+AUTHORS: Albert Heinle,     aheinle at uwaterloo.ca
+@*       Viktor Levandovskyy,     levandov at math.rwth-aachen.de
+
+OVERVIEW: In this library, new methods for factorization on polynomials
+  are implemented for three types of algebras, all generated by
+   2*n, n in NN, generators (n'th Weyl, n'th shift and graded polynomials in n'th q-Weyl algebras)
+   over a field K.
+@* More detailled description of the algorithms and related publications can be found at
+ at url{https://cs.uwaterloo.ca/\~aheinle/}.
+
+PROCEDURES:
+  facWeyl(h);                Factorization in the n'th Weyl algebra
+  facFirstWeyl(h);           Factorization in the first Weyl algebra
+  testNCfac(l[,h[,1]]);      Tests factorizations from a given list for correctness
+  facSubWeyl(h,X,D);         Factorization in the first Weyl algebra as a subalgebra
+  facShift(h);               Factorization in the n'th shift algebra
+  facFirstShift(h);          Factorization in the first shift algebra
+  homogfacNthQWeyl(h);       Homogeneous factorization in the n'th Q-Weyl algebra
+  homogfacFirstQWeyl(h);     Homogeneous factorization in the first Q-Weyl algebra
+  homogfacNthQWeyl_all(h);   Homogeneous factorization (complete) in the n'th Q-Weyl algebra
+  homogfacFirstQWeyl_all(h); Homogeneous factorization (complete) in the first Q-Weyl algebra
+  tst_ncfactor();            Runs the examples of all contained not static functions. Test thing.
+";
+
+LIB "rootsur.lib";
+LIB "general.lib";
+LIB "nctools.lib";
+LIB "involut.lib";
+LIB "freegb.lib"; // for isVar
+LIB "crypto.lib"; //for introot
+LIB "matrix.lib"; //for submatrix
+LIB "solve.lib"; //for solve
+LIB "poly.lib"; //for content
+
+proc tst_ncfactor()
+"
+A little test if the library works correct.
+Runs simply all examples of non-static functions.
+"
+{
+  example facWeyl;
+  example facShift;
+  example facSubWeyl;
+  example testNCfac;
+  example homogfacFirstQWeyl;
+  example homogfacFirstQWeyl_all;
+}
+example
+{
+  "EXAMPLE:";echo=2;
+   tst_ncfactor();
+}
+
+/////////////////////////////////////////////////////
+//==================================================*
+//deletes double-entries in a list of factorization
+//without evaluating the product.
+static proc delete_dublicates_noteval(list l)
+"
+INPUT: A list of lists; Output same as e.g. FacFirstWeyl. Containing different factorizations
+       of a polynomial
+OUTPUT: If there are dublicates in this list, this procedure deletes them and returns the list
+ without double entries
+"
+{//proc delete_dublicates_noteval
+  list result= l;
+  int j; int k; int i;
+  int deleted = 0;
+  int is_equal;
+  for (i = 1; i<= size(l); i++)
+  {//Iterate over the different factorizations
+    for (j = i+1; j<= size(l); j++)
+    {//Compare the i'th factorization to the j'th
+      if (size(l[i])!= size(l[j]))
+      {//different sizes => not equal
+        j++;
+        continue;
+      }//different sizes => not equal
+      is_equal = 1;
+      for (k = 1; k <= size(l[i]);k++)
+      {//Compare every entry
+        if (l[i][k]!=l[j][k])
+        {
+          is_equal = 0;
+          break;
+        }
+      }//Compare every entry
+      if (is_equal == 1)
+      {//Delete this entry, because there is another equal one int the list
+        result = delete(result, i-deleted);
+        deleted = deleted+1;
+        break;
+      }//Delete this entry, because there is another equal one int the list
+    }//Compare the i'th factorization to the j'th
+  }//Iterate over the different factorizations
+  return(result);
+}//proc delete_dublicates_noteval
+
+//==================================================
+static proc ncfactor_isWeyl()
+"
+INPUT: None
+OUTPUT: Returns 1 if the basering is a Weyl algebra,
+        0 otherwise.
+"
+{//ncfactor_isWeyl
+  if (nvars(basering) % 2 != 0)
+  {//Ring cannot be a Weyl algebra, as we need an even number of vars
+    return(0);
+  }//Ring cannot be a Weyl algebra, as we need an even number of vars
+  list tempRingList = ringlist(basering);
+  if (size(tempRingList)<=4)
+  {//Given ring is commutative
+    return(0);
+  }//Given ring is commutative
+  matrix C = tempRingList[5];
+  matrix D = tempRingList[6];
+  int i; int j;
+
+  //Checking if C is okay.
+  for (i = 1; i<ncols(C); i++)
+  {//Iterating the diagonal
+    for (j = i+1; j<=ncols(C); j++)
+    {//Iterating the off-diagonal
+      if (C[i,j] != 1)
+      { return(0); }
+    }//Iterating the off-diagonal
+  }//Iterating the diagonal
+
+  //Checking if D is okay
+  int countOnes;
+  for (i = 1; i<=ncols(D); i++)
+  {//Iterating the diagonal
+    countOnes = 0;
+    for (j = i+1; j<=ncols(D); j++)
+    {//Checking whether there is at most one nontrivial entry in each row.
+      if (D[i,j] == 1 or D[i,j]==-1)
+      {countOnes++;}
+    }//Checking whether there is at most one nontrivial entry in each row.
+    if (countOnes > 1)
+    {return(0);}
+    countOnes = 0;
+    for (j = i-1; j>=1; j--)
+    {//Checking whether there is at most one nontrivial entry in each col
+      if (D[j,i] == 1 or D[j,i]==-1)
+      {countOnes++;}
+    }//Checking whether there is at most one nontrivial entry in each col
+    if (countOnes > 1)
+    {return(0);}
+  }//Iterating the diagonal
+
+  //Now check if all variables are paired up.
+  list the_vars;
+  for (i = 1; i<=nvars(basering); i++)
+  {
+    the_vars[i] = var(i);
+  }
+  int noPairForFirstOne;
+  while(size(the_vars)>0)
+  {//We did not pair up all variables yet
+    noPairForFirstOne = 1;
+    for (i = 2; i<=size(the_vars); i++)
+    {//Compare the commutation relations of the jth variable to the first one
+      if (the_vars[1]*the_vars[i] - the_vars[i]*the_vars[1] == 1 or
+          the_vars[1]*the_vars[i] - the_vars[i]*the_vars[1] == -1)
+      {//Found a counter matching one
+        noPairForFirstOne = 0;
+        the_vars = delete(the_vars,i);
+        the_vars = delete(the_vars,1);
+        break;
+      }//Found a counter matching one
+    }//Compare the commutation relations of the jth variable to the first one
+    if(noPairForFirstOne)
+    {return(0);}
+  }//We did not pair up all variables yet
+  return(1);
+}//ncfactor_isWeyl
+
+//==================================================
+static proc ncfactor_isQWeyl()
+"
+INPUT: None
+OUTPUT: Returns 1 if the basering is a Weyl algebra,
+        0 otherwise.
+"
+{//ncfactor_isqWeyl
+  if (nvars(basering) % 2 != 0)
+  {//Ring cannot be a Weyl algebra, as we need an even number of vars
+    return(0);
+  }//Ring cannot be a Weyl algebra, as we need an even number of vars
+  /* if (npars(basering)!=nvars(basering) div 2) */
+  /* {//Ring must have enough parameters */
+  /*   return(0); */
+  /* }//Ring must have enough parameters */
+  list tempRingList = ringlist(basering);
+  if (size(tempRingList)<=4)
+  {//Given ring is commutative
+    return(0);
+  }//Given ring is commutative
+  matrix C = tempRingList[5];
+  matrix D = tempRingList[6];
+  int i; int j; int k;
+  int validentry;
+  //Checking if C is okay.
+  for (i = 1; i<ncols(C); i++)
+  {//Iterating the diagonal
+    for (j = i+1; j<=ncols(C); j++)
+    {//Iterating the off-diagonal
+      if (C[i,j] != 1)
+      {
+        validentry = 0;
+        for (k = 1; k<=npars(r); k++)
+        {
+          if (C[i,j]==par(k))
+          {
+            validentry = 1;
+            break;
+          }
+        }
+        if (!validentry)
+        {
+          return(0);
+        }
+      }
+    }//Iterating the off-diagonal
+  }//Iterating the diagonal
+  //Checking if D is okay
+  int countOnes;
+  for (i = 1; i<=ncols(D); i++)
+  {//Iterating the diagonal
+    countOnes = 0;
+    for (j = i+1; j<=ncols(D); j++)
+    {//Checking whether there is at most one nontrivial entry in each row.
+      if (D[i,j] == 1 or D[i,j]==-1)
+      {countOnes++;}
+    }//Checking whether there is at most one nontrivial entry in each row.
+    if (countOnes > 1)
+    {return(0);}
+    countOnes = 0;
+    for (j = i-1; j>=1; j--)
+    {//Checking whether there is at most one nontrivial entry in each col
+      if (D[j,i] == 1 or D[j,i]==-1)
+      {countOnes++;}
+    }//Checking whether there is at most one nontrivial entry in each col
+    if (countOnes > 1)
+    {return(0);}
+  }//Iterating the diagonal
+
+  //Now check if all variables are paired up.
+  list the_vars;
+  for (i = 1; i<=nvars(basering); i++)
+  {
+    the_vars[i] = var(i);
+  }
+  int noPairForFirstOne;
+  while(size(the_vars)>0)
+  {//We did not pair up all variables yet
+    noPairForFirstOne = 1;
+    for (i = 2; i<=size(the_vars); i++)
+    {//Compare the commutation relations of the jth variable to the first one
+      for (j = 1; j<=npars(basering);j++)
+      {
+        for (k = 1; k<= npars(basering); k++)
+        {
+          if (the_vars[1]*the_vars[i] - par(k)*the_vars[i]*the_vars[1] == 1 or
+              par(k)*the_vars[1]*the_vars[i] - the_vars[i]*the_vars[1] == -1)
+          {//Found a counter matching one
+            noPairForFirstOne = 0;
+            break;
+          }//Found a counter matching one
+        }
+        if (noPairForFirstOne == 0)
+        {
+          break;
+        }
+      }
+      if(noPairForFirstOne==0)
+      {
+        the_vars = delete(the_vars,i);
+        the_vars = delete(the_vars,1);
+        break;
+      }
+    }//Compare the commutation relations of the jth variable to the first one
+    if(noPairForFirstOne)
+    {return(0);}
+  }//We did not pair up all variables yet
+  return(1);
+}//ncfactor_isqWeyl
+
+////////////////////////////////////////////////////
+//==================================================
+////////////////////////////////////////////////////
+
+static proc ncfactor_isShift()
+"
+INPUT: None
+OUTPUT: Returns 1 if the basering is a Shift algebra,
+        0 otherwise.
+"
+{//ncfactor_isShift
+  if (nvars(basering) % 2 != 0)
+  {//Ring cannot be a Shift algebra, as we need an even number of vars
+    return(0);
+  }//Ring cannot be a Shift algebra, as we need an even number of vars
+  list tempRingList = ringlist(basering);
+  if (size(tempRingList)<=4)
+  {//Given ring is commutative
+    return(0);
+  }//Given ring is commutative
+  matrix C = tempRingList[5];
+  matrix D = tempRingList[6];
+  int i; int j; int k;
+
+  //Checking if C is okay.
+  for (i = 1; i<ncols(C); i++)
+  {//Iterating the diagonal
+    for (j = i+1; j<=ncols(C); j++)
+    {//Iterating the off-diagonal
+      if (C[i,j] != 1)
+      { return(0); }
+    }//Iterating the off-diagonal
+  }//Iterating the diagonal
+
+  //Checking if D is okay
+  int countOperators;
+  int isValidNCRelation;
+  for (i = 1; i<=ncols(D); i++)
+  {//Iterating the diagonal
+    countOperators = 0;
+    for (j = i+1; j<=ncols(D); j++)
+    {//Checking whether there is at most one nontrivial entry in each row.
+      if (D[i,j]!= 0)
+      {//Nontrivial relation detected
+        isValidNCRelation = 0;
+        for (k =1; k<= nvars(basering); k++)
+        {//checking validity for each ring element
+          if (D[i,j] == var(k) or D[i,j]==-var(k))
+          {//valid relation
+            isValidNCRelation = 1;
+            break;
+          }//valid relation
+        }//checking validity for each ring element
+        if (!isValidNCRelation)
+        {//We have not a valid nc-relation at hand
+          return(0);
+        }//We have not a valid nc-relation at hand
+        else
+        {//Increase the numbers of operators occurring in that row
+          countOperators++;
+        }//Increase the numbers of operators occurring in that row
+      }//Nontrivial relation detected
+    }//Checking whether there is at most one nontrivial entry in each row.
+    if (countOperators > 1)
+    {return(0);}
+    countOperators = 0;
+    for (j = i-1; j>=1; j--)
+    {//Checking whether there is at most one nontrivial entry in each col
+     if (D[j,i]!= 0)
+      {//Nontrivial relation detected
+        isValidNCRelation = 0;
+        for (k =1; k<= nvars(basering); k++)
+        {//checking validity for each ring element
+          if (D[j,i] == var(k) or D[j,i]==-var(k))
+          {//valid relation
+            isValidNCRelation = 1;
+            break;
+          }//valid relation
+        }//checking validity for each ring element
+        if (!isValidNCRelation)
+        {//We have not a valid nc-relation at hand
+          return(0);
+        }//We have not a valid nc-relation at hand
+        else
+        {//Increase the numbers of operators occurring in that row
+          countOperators++;
+        }//Increase the numbers of operators occurring in that row
+      }//Nontrivial relation detected
+    }//Checking whether there is at most one nontrivial entry in each col
+    if (countOperators > 1)
+    {return(0);}
+  }//Iterating the diagonal
+
+  //Now check if all variables are paired up.
+  list the_vars;
+  for (i = 1; i<=nvars(basering); i++)
+  {
+    the_vars[i] = var(i);
+  }
+  int noPairForFirstOne;
+  while(size(the_vars)>0)
+  {//We did not pair up all variables yet
+    noPairForFirstOne = 1;
+    for (i = 2; i<=size(the_vars); i++)
+    {//Compare the commutation relations of the jth variable to the first one
+      if (the_vars[1]*the_vars[i] - the_vars[i]*the_vars[1] == the_vars[1] or
+          the_vars[1]*the_vars[i] - the_vars[i]*the_vars[1] == -the_vars[1] or
+          the_vars[1]*the_vars[i] - the_vars[i]*the_vars[1] == the_vars[i] or
+        the_vars[1]*the_vars[i] - the_vars[i]*the_vars[1] == -the_vars[i])
+      {//Found a counter matching one
+        noPairForFirstOne = 0;
+        the_vars = delete(the_vars,i);
+        the_vars = delete(the_vars,1);
+        break;
+      }//Found a counter matching one
+    }//Compare the commutation relations of the jth variable to the first one
+    if(noPairForFirstOne)
+    {return(0);}
+  }//We did not pair up all variables yet
+  return(1);
+}//ncfactor_isShift
+
+//==================================================
+static proc isInCommutativeSubRing(poly h)
+"
+INPUT: A polynomial h in an arbitrary polynomial ring.
+OUTPUT: 1, if all variables that appear at least in 1 monomial in h
+        are all commuting, 0 else.
+"
+{//isInCommutativeSubRing
+  list tempRingList = ringlist(basering);
+  if (size(tempRingList)<=4)
+  {//In this case, the given ring was commutative
+    return(1);
+  }//In this case, the given ring was commutative
+  list appearing_variables;
+  int i; int j;
+  intvec degreeIntVec;
+  for (i = 1; i<=nvars(basering);i++)
+  {//checking for variables that appear
+    degreeIntVec = 0:nvars(basering);
+    degreeIntVec[i] = 1;
+    if (deg(h, degreeIntVec) >0)
+    {//Variable does appear in h
+      appearing_variables = appearing_variables + list(var(i));
+    }//Variable does appear in h
+  }//checking for variables that appear
+  for (i = 1; i<size(appearing_variables); i++)
+  {
+    for (j = i+1; j<=size(appearing_variables); j++)
+    {
+      if (appearing_variables[i]*appearing_variables[j] -
+          appearing_variables[j]*appearing_variables[i] != 0)
+      {
+        return(0)
+      }
+    }
+  }
+  return(1);
+}//isInCommutativeSubRing
+
+//==================================================
+//deletes the double-entries in a list with
+//evaluating the products
+static proc delete_dublicates_eval(list l)
+"
+DEPRECATED
+"
+{//proc delete_dublicates_eval
+  list result=l;
+  int j; int k; int i;
+  int deleted = 0;
+  int is_equal;
+  for (i = 1; i<= size(result); i++)
+  {//Iterating over all elements in result
+    for (j = i+1; j<= size(result); j++)
+    {//comparing with the other elements
+      if (product(result[i]) == product(result[j]))
+      {//There are two equal results; throw away that one with the smaller size
+        if (size(result[i])>=size(result[j]))
+        {//result[i] has more entries
+          result = delete(result,j);
+          continue;
+        }//result[i] has more entries
+        else
+        {//result[j] has more entries
+          result = delete(result,i);
+          i--;
+          break;
+        }//result[j] has more entries
+      }//There are two equal results; throw away that one with the smaller size
+    }//comparing with the other elements
+  }//Iterating over all elements in result
+  return(result);
+}//proc delete_dublicates_eval
+
+
+//==================================================*
+
+static proc combinekfinlf(list g, int nof) //nof stands for "number of factors"
+"
+given a list of factors g and a desired size nof, this
+procedure combines the factors, such that we recieve a
+list of the length nof.
+INPUT: A list of containing polynomials or any type where the *-operator is existent
+OUTPUT: All possibilities (without permutation of the given list) to combine the polynomials
+ into nof polynomials given by the user.
+"
+{//Procedure combinekfinlf
+  list result;
+  int i; int j; int k; //iteration variables
+  list fc; //fc stands for "factors combined"
+  list temp; //a temporary store for factors
+  def nofgl = size(g); //nofgl stands for "number of factors of the given list"
+  if (nofgl == 0)
+  {//g was the empty list
+    return(result);
+  }//g was the empty list
+  if (nof <= 0)
+  {//The user wants to recieve a negative number or no element as a result
+    return(result);
+  }//The user wants to recieve a negative number or no element as a result
+  if (nofgl == nof)
+  {//There are no factors to combine
+    result = result + list(g);
+    return(result);
+  }//There are no factors to combine
+  if (nof == 1)
+  {//User wants to get just one factor
+    result = result + list(list(product(g)));
+    return(result);
+  }//User wants to get just one factor
+  for (i = nof; i > 1; i--)
+  {//computing the possibilities that have at least one original factor from g
+    for (j = i; j>=1; j--)
+    {//shifting the window of combinable factors to the left
+      //fc below stands for "factors combined"
+      fc = combinekfinlf(list(g[(j)..(j+nofgl - i)]),nof - i + 1);
+      for (k = 1; k<=size(fc); k++)
+      {//iterating over the different solutions of the smaller problem
+        if (j>1)
+        {//There are g_i before the combination
+          if (j+nofgl -i < nofgl)
+          {//There are g_i after the combination
+            temp = list(g[1..(j-1)]) + fc[k] + list(g[(j+nofgl-i+1)..nofgl]);
+          }//There are g_i after the combination
+          else
+          {//There are no g_i after the combination
+            temp = list(g[1..(j-1)]) + fc[k];
+          }//There are no g_i after the combination
+        }//There are g_i before the combination
+        if (j==1)
+        {//There are no g_i before the combination
+          if (j+ nofgl -i <nofgl)
+          {//There are g_i after the combination
+            temp = fc[k]+ list(g[(j + nofgl - i +1)..nofgl]);
+          }//There are g_i after the combination
+        }//There are no g_i before the combination
+        result = result + list(temp);
+      }//iterating over the different solutions of the smaller problem
+    }//shifting the window of combinable factors to the left
+  }//computing the possibilities that have at least one original factor from g
+  for (i = 2; i<=nofgl div nof;i++)
+  {//getting the other possible results
+    result = result + combinekfinlf(list(product(list(g[1..i])))+list(g[(i+1)..nofgl]),nof);
+  }//getting the other possible results
+  result = delete_dublicates_noteval(result);
+  return(result);
+}//Procedure combinekfinlf
+
+
+//==================================================*
+//merges two sets of factors ignoring common
+//factors
+static proc merge_icf(list l1, list l2, intvec limits)
+"
+DEPRECATED
+"
+{//proc merge_icf
+  list g;
+  list f;
+  int i; int j;
+  if (size(l1)==0)
+  {
+    return(list());
+  }
+  if (size(l2)==0)
+  {
+    return(list());
+  }
+  if (size(l2)<=size(l1))
+  {//l1 will be our g, l2 our f
+    g = l1;
+    f = l2;
+  }//l1 will be our g, l2 our f
+  else
+  {//l1 will be our f, l2 our g
+    g = l2;
+    f = l1;
+  }//l1 will be our f, l2 our g
+  def result = combinekfinlf(g,size(f),limits);
+  for (i = 1 ; i<= size(result); i++)
+  {//Adding the factors of f to every possibility listed in temp
+    for (j = 1; j<= size(f); j++)
+    {
+      result[i][j] = result[i][j]+f[j];
+    }
+    if(!limitcheck(result[i],limits))
+    {
+      result = delete(result,i);
+      continue;
+    }
+    for (j = 1; j<=size(f);j++)
+    {//Delete entry if there is a zero or an integer as a factor
+      if (deg(result[i][j]) <= 0)
+      {//found one
+        result = delete(result,i);
+        i--;
+        break;
+      }//found one
+    }//Delete entry if there is a zero as factor
+  }//Adding the factors of f to every possibility listed in temp
+  return(result);
+}//proc merge_icf
+
+//==================================================*
+//merges two sets of factors with respect to the occurrence
+//of common factors
+static proc merge_cf(list l1, list l2, intvec limits)
+"
+DEPRECATED
+"
+{//proc merge_cf
+  list g;
+  list f;
+  int i; int j;
+  list pre;
+  list post;
+  list candidate;
+  list temp;
+  int temppos;
+  if (size(l1)==0)
+  {//the first list is empty
+    return(list());
+  }//the first list is empty
+  if(size(l2)==0)
+  {//the second list is empty
+    return(list());
+  }//the second list is empty
+  if (size(l2)<=size(l1))
+  {//l1 will be our g, l2 our f
+    g = l1;
+    f = l2;
+  }//l1 will be our g, l2 our f
+  else
+  {//l1 will be our f, l2 our g
+    g = l2;
+    f = l1;
+  }//l1 will be our f, l2 our g
+  list M;
+  for (i = 2; i<size(f); i++)
+  {//finding common factors of f and g...
+    for (j=2; j<size(g);j++)
+    {//... with g
+      if (f[i] == g[j])
+      {//we have an equal pair
+        M = M + list(list(i,j));
+      }//we have an equal pair
+    }//... with g
+  }//finding common factors of f and g...
+  if (g[1]==f[1])
+  {//Checking for the first elements to be equal
+    M = M + list(list(1,1));
+  }//Checking for the first elements to be equal
+  if (g[size(g)]==f[size(f)])
+  {//Checking for the last elements to be equal
+    M = M + list(list(size(f),size(g)));
+  }//Checking for the last elements to be equal
+  list result;//= list(list());
+  while(size(M)>0)
+  {//set of equal pairs is not empty
+    temp = M[1];
+    temppos = 1;
+    for (i = 2; i<=size(M); i++)
+    {//finding the minimal element of M
+      if (M[i][1]<=temp[1])
+      {//a possible candidate that is smaller than temp could have been found
+        if (M[i][1]==temp[1])
+        {//In this case we must look at the second number
+          if (M[i][2]< temp[2])
+          {//the candidate is smaller
+            temp = M[i];
+            temppos = i;
+          }//the candidate is smaller
+        }//In this case we must look at the second number
+        else
+        {//The candidate is definately smaller
+          temp = M[i];
+          temppos = i;
+        }//The candidate is definately smaller
+      }//a possible candidate that is smaller than temp could have been found
+    }//finding the minimal element of M
+    M = delete(M, temppos);
+    if(temp[1]>1)
+    {//There are factors to combine before the equal factor
+      if (temp[1]<size(f))
+      {//The most common case
+        //first the combinations ignoring common factors
+        pre = merge_icf(list(f[1..(temp[1]-1)]),list(g[1..(temp[2]-1)]),limits);
+        post = merge_icf(list(f[(temp[1]+1)..size(f)]),list(g[(temp[2]+1..size(g))]),limits);
+        for (i = 1; i <= size(pre); i++)
+        {//all possible pre's...
+          for (j = 1; j<= size(post); j++)
+          {//...combined with all possible post's
+            candidate = pre[i]+list(f[temp[1]])+post[j];
+            if (limitcheck(candidate,limits))
+            {
+              result = result + list(candidate);
+            }
+          }//...combined with all possible post's
+        }//all possible pre's...
+        //Now the combinations with respect to common factors
+        post = merge_cf(list(f[(temp[1]+1)..size(f)]),list(g[(temp[2]+1..size(g))]),limits);
+        if (size(post)>0)
+        {//There are factors to combine
+          for (i = 1; i <= size(pre); i++)
+          {//all possible pre's...
+            for (j = 1; j<= size(post); j++)
+            {//...combined with all possible post's
+              candidate= pre[i]+list(f[temp[1]])+post[j];
+              if (limitcheck(candidate,limits))
+              {
+                result = result + list(candidate);
+              }
+            }//...combined with all possible post's
+          }//all possible pre's...
+        }//There are factors to combine
+      }//The most common case
+      else
+      {//the last factor is the common one
+        pre = merge_icf(list(f[1..(temp[1]-1)]),list(g[1..(temp[2]-1)]),limits);
+        for (i = 1; i<= size(pre); i++)
+        {//iterating over the possible pre-factors
+          candidate = pre[i]+list(f[temp[1]]);
+          if (limitcheck(candidate,limits))
+          {
+            result = result + list(candidate);
+          }
+        }//iterating over the possible pre-factors
+      }//the last factor is the common one
+    }//There are factors to combine before the equal factor
+    else
+    {//There are no factors to combine before the equal factor
+      if (temp[1]<size(f))
+      {//Just a check for security
+        //first without common factors
+        post=merge_icf(list(f[(temp[1]+1)..size(f)]),list(g[(temp[2]+1..size(g))]),limits);
+        for (i = 1; i<=size(post); i++)
+        {
+          candidate = list(f[temp[1]])+post[i];
+          if (limitcheck(candidate,limits))
+          {
+            result = result + list(candidate);
+          }
+        }
+        //Now with common factors
+        post = merge_cf(list(f[(temp[1]+1)..size(f)]),list(g[(temp[2]+1..size(g))]),limits);
+        if(size(post)>0)
+        {//we could find other combinations
+          for (i = 1; i<=size(post); i++)
+          {
+            candidate = list(f[temp[1]])+post[i];
+            if (limitcheck(candidate,limits))
+            {
+              result = result + list(candidate);
+            }
+          }
+        }//we could find other combinations
+      }//Just a check for security
+    }//There are no factors to combine before the equal factor
+  }//set of equal pairs is not empty
+  for (i = 1; i <= size(result); i++)
+  {//delete those combinations, who have an entry with degree less or equal 0
+    for (j = 1; j<=size(result[i]);j++)
+    {//Delete entry if there is a zero or an integer as a factor
+      if (deg(result[i][j]) <= 0)
+      {//found one
+        result = delete(result,i);
+        i--;
+        break;
+      }//found one
+    }//Delete entry if there is a zero as factor
+  }//delete those combinations, who have an entry with degree less or equal 0
+  return(result);
+}//proc merge_cf
+
+
+//==================================================*
+//merges two sets of factors
+
+static proc mergence(list l1, list l2, intvec limits)
+"
+DEPRECATED
+"
+{//Procedure mergence
+  list g;
+  list f;
+  int k; int i; int j;
+  list F = list();
+  list G = list();
+  list tempEntry;
+  list comb;
+  if (size(l2)<=size(l1))
+  {//l1 will be our g, l2 our f
+    g = l1;
+    f = l2;
+  }//l1 will be our g, l2 our f
+  else
+  {//l1 will be our f, l2 our g
+    g = l2;
+    f = l1;
+  }//l1 will be our f, l2 our g
+  if (size(f)==1 or size(g)==1)
+  {//One of them just has one entry
+    if (size(f)== 1) {f = list(1) + f;}
+    if (size(g) == 1) {g = list(1) + g;}
+  }//One of them just has one entry
+  //first, we need to add some latent -1's to the list f and to the list g in order
+  //to get really all possibilities of combinations later
+  for (i=1;i<=size(f)-1;i++)
+  {//first iterator
+    for (j=i+1;j<=size(f);j++)
+    {//second iterator
+      tempEntry = f;
+      tempEntry[i] = (-1)*tempEntry[i];
+      tempEntry[j] = (-1)*tempEntry[j];
+      F = F + list(tempEntry);
+    }//secont iterator
+  }//first iterator
+  F = F + list(f);
+  //And now same game with g
+  for (i=1;i<=size(g)-1;i++)
+  {//first iterator
+    for (j=i+1;j<=size(g);j++)
+    {//second iterator
+      tempEntry = g;
+      tempEntry[i] = (-1)*tempEntry[i];
+      tempEntry[j] = (-1)*tempEntry[j];
+      G = G + list(tempEntry);
+    }//secont iterator
+  }//first iterator
+  G = G + list(g);
+  //Done with that
+
+  list result;
+  for (i = 1; i<=size(F); i++)
+  {//Iterate over all entries in F
+    for (j = 1;j<=size(G);j++)
+    {//Same with G
+      comb = combinekfinlf(F[i],2,limits);
+      for (k = 1; k<= size(comb);k++)
+      {//for all possibilities of combinations of the factors of f
+        result = result + merge_cf(comb[k],G[j],limits);
+        result = result + merge_icf(comb[k],G[j],limits);
+        result = delete_dublicates_noteval(result);
+      }//for all possibilities of combinations of the factors of f
+    }//Same with G
+  }//Iterate over all entries in F
+  return(result);
+}//Procedure mergence
+
+
+//==================================================
+//Checks, whether a list of factors doesn't exceed the given limits
+static proc limitcheck(list g, intvec limits)
+"
+DEPRECATED
+"
+{//proc limitcheck
+  int i;
+  if (size(limits)!=3)
+  {//check the input
+    return(0);
+  }//check the input
+  if(size(g)==0)
+  {
+    return(0);
+  }
+  def prod = product(g);
+  intvec iv11 = intvec(1,1);
+  intvec iv10 = intvec(1,0);
+  intvec iv01 = intvec(0,1);
+  def limg = intvec(deg(prod,iv11) ,deg(prod,iv10),deg(prod,iv01));
+  for (i = 1; i<=size(limg);i++)
+  {//the final check
+    if(limg[i]>limits[i])
+    {
+      return(0);
+    }
+  }//the final check
+  return(1);
+}//proc limitcheck
+
+
+//==================================================*
+//one factorization of a homogeneous polynomial
+//in the first Weyl Algebra
+static proc homogfacFirstWeyl(poly h)
+"USAGE: homogfacFirstWeyl(h); h is a homogeneous polynomial in the
+ first Weyl algebra with respect to the weight vector [-1,1]
+RETURN: list
+PURPOSE: Computes a factorization of a homogeneous polynomial h with
+  respect to the weight vector [-1,1] in the first Weyl algebra
+THEORY: @code{homogfacFirstWeyl} returns a list with a factorization of the given,
+ [-1,1]-homogeneous polynomial. If the degree of the polynomial is k with
+ k positive, the last k entries in the output list are the second
+ variable. If k is positive, the last k entries will be x. The other
+ entries will be irreducible polynomials of degree zero or 1 resp. -1.
+SEE ALSO: homogfacFirstWeyl_all
+"{//proc homogfacFirstWeyl
+  int p = printlevel-voice+2;//for dbprint
+  def r = basering;
+  poly hath;
+  int i; int j;
+  string dbprintWhitespace = "";
+  for (i = 1; i<=voice;i++)
+  {dbprintWhitespace = dbprintWhitespace + " ";}
+  intvec ivm11 = intvec(-1,1);
+  if (!homogwithorder(h,ivm11))
+  {//The given polynomial is not homogeneous
+    ERROR("Given polynomial was not [-1,1]-homogeneous");
+    return(list());
+  }//The given polynomial is not homogeneous
+  if (h==0)
+  {
+    return(list(0));
+  }
+  list result;
+  int m = deg(h,ivm11);
+  dbprint(p,dbprintWhitespace +" Splitting the polynomial in A_0 and A_k-Part");
+  if (m!=0)
+  {//The degree is not zero
+    if (m <0)
+    {//There are more x than y
+      hath = lift(var(1)^(-m),h)[1,1];
+      for (i = 1; i<=-m; i++)
+      {
+        result = result + list(var(1));
+      }
+    }//There are more x than y
+    else
+    {//There are more y than x
+      hath = lift(var(2)^m,h)[1,1];
+      for (i = 1; i<=m;i++)
+      {
+        result = result + list(var(2));
+      }
+    }//There are more y than x
+  }//The degree is not zero
+  else
+  {//The degree is zero
+    hath = h;
+  }//The degree is zero
+  dbprint(p,dbprintWhitespace+" Done");
+  //beginning to transform x^i*y^i in theta(theta-1)...(theta-i+1)
+  list mons;
+  dbprint(p,dbprintWhitespace+" Putting the monomials in the A_0-part in a list.");
+  for(i = 1; i<=size(hath);i++)
+  {//Putting the monomials in a list
+    mons = mons+list(hath[i]);
+  }//Putting the monomials in a list
+  dbprint(p,dbprintWhitespace+" Done");
+  dbprint(p,dbprintWhitespace+" Mapping this monomials to K[theta]");
+  ring tempRing = 0,(x,y,theta),dp;
+  setring tempRing;
+  map thetamap = r,x,y;
+  list mons = thetamap(mons);
+  poly entry;
+  for (i = 1; i<=size(mons);i++)
+  {//transforming the monomials as monomials in theta
+    entry = leadcoef(mons[i]);
+    for (j = 0; j<leadexp(mons[i])[2];j++)
+    {
+      entry = entry * (theta-j);
+    }
+    mons[i] = entry;
+  }//transforming the monomials as monomials in theta
+  dbprint(p,dbprintWhitespace+" Done");
+  dbprint(p,dbprintWhitespace+" Factorize the A_0-Part in K[theta]");
+  list azeroresult = factorize(sum(mons));
+  dbprint(p,dbprintWhitespace+" Successful");
+  list azeroresult_return_form;
+  for (i = 1; i<=size(azeroresult[1]);i++)
+  {//rewrite the result of the commutative factorization
+    for (j = 1; j <= azeroresult[2][i];j++)
+    {
+      azeroresult_return_form = azeroresult_return_form + list(azeroresult[1][i]);
+    }
+  }//rewrite the result of the commutative factorization
+  dbprint(p,dbprintWhitespace+" Mapping back to A_0.");
+  setring(r);
+  map finalmap = tempRing,var(1),var(2),var(1)*var(2);
+  list tempresult = finalmap(azeroresult_return_form);
+  dbprint(p,dbprintWhitespace+"Successful.");
+  for (i = 1; i<=size(tempresult);i++)
+  {//factorizations of theta resp. theta +1
+    if(tempresult[i]==var(1)*var(2))
+    {
+      tempresult = insert(tempresult,var(1),i-1);
+      i++;
+      tempresult[i]=var(2);
+    }
+    if(tempresult[i]==var(2)*var(1))
+    {
+      tempresult = insert(tempresult,var(2),i-1);
+      i++;
+      tempresult[i]=var(1);
+    }
+  }//factorizations of theta resp. theta +1
+  result = tempresult+result;
+  return(result);
+}//proc homogfacFirstWeyl
+/* example */
+/* { */
+/*      "EXAMPLE:";echo=2; */
+/*      ring R = 0,(x,y),Ws(-1,1); */
+/*      def r = nc_algebra(1,1); */
+/*      setring(r); */
+/*      poly h = (x^2*y^2+1)*(x^4); */
+/*      homogfacFirstWeyl(h); */
+/* } */
+
+
+static proc homogfacNthWeyl(poly h)
+"USAGE: homogfacNthWeyl(h); h is a homogeneous polynomial in the
+ nth Weyl algebra with respect to the -1,1-grading
+RETURN: list
+PURPOSE: Computes a factorization of a homogeneous polynomial h with
+  respect to the ZZ-grading on the n-th Weyl algebra.
+THEORY: @code{homogfacFirstWeyl} returns a list with a factorization of the given,
+ [-1,1]-homogeneous polynomial. For every i in 1..n: If the degree of the polynomial
+ in [d_i,x_i] is k with k positive, the last k entries in the output list are the second
+ variable. If k is positive, the last k entries will be x_i. The other
+ entries will be irreducible polynomials of degree zero or 1 resp. -1. resp. other variables
+
+GENERAL ASSUMPTIONS:
+ - The basering is the nth Weyl algebra and has the form, that the first n variables represent
+   x1, ..., xn, and the second n variables do represent the d1, ..., dn.
+
+SEE ALSO: homogfacFirstWeyl_all
+"
+{//proc homogfacNthWeyl
+  int p = printlevel-voice+2;//for dbprint
+  poly hath = h;
+  def r = basering;
+  int i; int j; int k;
+  string dbprintWhitespace = "";
+  for (i = 1; i<=voice;i++)
+  {dbprintWhitespace = dbprintWhitespace + " ";}
+  intvec ivm11 = intvec(-1,1);
+  if (!homogwithorderNthWeyl(h))
+  {//The given polynomial is not homogeneous
+    ERROR("Given polynomial was not [-1,1]-homogeneous");
+    return(list());
+  }//The given polynomial is not homogeneous
+  if (h==0)
+  {
+    return(list(0));
+  }
+  list result;
+  intvec m = degreeOfNthWeylPoly(h);
+  dbprint(p,dbprintWhitespace +" Splitting the polynomial in A_0 and A_k-Part");
+  dbprint(p,dbprintWhitespace + "Its [-1,1] degree is "+string(m));
+  for (j = 1; j<=nvars(basering) div 2; j++)
+  {//extracting the respective variable for every position
+    dbprint(p,dbprintWhitespace + "Considering variables x_"+string(j)+" and d" + string(j));
+    if (m[j]!=0)
+    {//The degree is not zero
+      if (m[j] <0)
+      {//There are more x than y
+        hath = lift(var(j)^(-m[j]),hath)[1,1];
+        for (i = 1; i<=-m[j]; i++)
+        {
+          result = result + list(var(j));
+        }
+      }//There are more x than y
+      else
+      {//There are more y than x
+        hath = lift(var(nvars(basering) div 2 + j)^m[j],hath)[1,1];
+        for (i = 1; i<=m[j];i++)
+        {
+          result = result + list(var(nvars(basering) div 2 + j));
+        }
+      }//There are more y than x
+    }//The degree is not zero
+  }//extracting the respective variable for every position
+  dbprint(p,dbprintWhitespace+" Done");
+  //beginning to factor the zero-homogeneous part
+  list mons;
+  dbprint(p,dbprintWhitespace+" Putting the monomials in the A_0-part in a list.");
+  for(i = 1; i<=size(hath);i++)
+  {//Putting the monomials in a list
+    mons = mons+list(hath[i]);
+  }//Putting the monomials in a list
+  dbprint(p,dbprintWhitespace+" Done");
+  dbprint(p,dbprintWhitespace+" Mapping this monomials to K[theta_1, ... , theta_n]");
+  ring tempRing = 0,(x(1..(nvars(basering) div 2)),
+                     y(1..(nvars(basering) div 2)),
+                     theta(1..(nvars(basering) div 2))),dp;
+  setring tempRing;
+  ideal mapList;
+  for (i = 1; i<=nvars(r) ; i++)
+  {//filling the list of elements we want to map
+    mapList[i] = var(i);
+  }//filling the list of elements we want to map
+  map thetamap = r,mapList;
+  list mons = thetamap(mons);
+  poly entry;
+  intvec lExp;
+  for (i = 1; i<=size(mons);i++)
+  {//transforming the monomials as monomials in theta
+    entry = leadcoef(mons[i]);
+    lExp  = leadexp(mons[i]);
+    for (k = 1; k<=nvars(r) div 2; k++)
+    {//iterating over the pairs x_kd_k
+      for (j = 0; j<lExp[k];j++)
+      {
+        entry = entry * (theta(k)-j);
+      }
+    }//iterating over the pairs x_kd_k
+    mons[i] = entry;
+  }//transforming the monomials as monomials in theta
+  dbprint(p,dbprintWhitespace+" Done");
+  dbprint(p,dbprintWhitespace+" Factorize the A_0-Part in K[theta]");
+  list azeroresult = factorize(sum(mons));
+  dbprint(p,dbprintWhitespace+" Successful");
+  list azeroresult_return_form;
+  for (i = 1; i<=size(azeroresult[1]);i++)
+  {//rewrite the result of the commutative factorization
+    for (j = 1; j <= azeroresult[2][i];j++)
+    {
+      azeroresult_return_form = azeroresult_return_form + list(azeroresult[1][i]);
+    }
+  }//rewrite the result of the commutative factorization
+  dbprint(p,dbprintWhitespace+" Mapping back to A_0.");
+  setring(r);
+  ideal finalMapList;
+  for(i = 1; i<=nvars(r);i++)
+  {
+    finalMapList[i] = var(i);
+  }
+  for (i = 1; i<=nvars(r) div 2; i++)
+  {
+    finalMapList[i + nvars(r)] = var(i)*var(i + (nvars(r) div 2));
+  }
+  map finalmap = tempRing,finalMapList;
+  list tempresult = finalmap(azeroresult_return_form);
+  dbprint(p,dbprintWhitespace+"Successful.");
+  for (k = 1; k<=nvars(r) div 2; k++)
+  {
+    for (i = 1; i<=size(tempresult);i++)
+    {//factorizations of theta resp. theta +1
+      if(tempresult[i]==var(k)*var(k + nvars(r) div 2))
+      {
+        tempresult = insert(tempresult,var(k),i-1);
+        i++;
+        tempresult[i]=var(k +nvars(r) div 2);
+      }
+      if(tempresult[i]==var(k + nvars(r) div 2)*var(k))
+      {
+        tempresult = insert(tempresult,var(k + nvars(r) div 2),i-1);
+        i++;
+        tempresult[i]=var(k);
+      }
+    }//factorizations of theta resp. theta +1
+  }
+  result = tempresult+result;
+  return(result);
+}//proc homogfacNthWeyl
+
+
+
+//==================================================
+//Computes all possible homogeneous factorizations
+static proc homogfacFirstWeyl_all(poly h)
+"USAGE: homogfacFirstWeyl_all(h); h is a homogeneous polynomial in the first Weyl algebra
+ with respect to the weight vector [-1,1]
+RETURN: list
+PURPOSE: Computes all factorizations of a homogeneous polynomial h with respect
+  to the weight vector [-1,1] in the first Weyl algebra
+THEORY: @code{homogfacFirstWeyl} returns a list with all factorization of the given,
+ homogeneous polynomial. It uses the output of homogfacFirstWeyl and permutes
+ its entries with respect to the commutation rule. Furthermore, if a
+ factor of degree zero is irreducible in K[  heta], but reducible in
+ the first Weyl algebra, the permutations of this element with the other
+ entries will also be computed.
+SEE ALSO: homogfacFirstWeyl
+"{//proc HomogfacFirstWeylAll
+  int p=printlevel-voice+2;//for dbprint
+  intvec iv11= intvec(1,1);
+  if (deg(h,iv11) <= 0 )
+  {//h is a constant
+    dbprint(p,"Given polynomial was not homogeneous");
+    return(list(list(h)));
+  }//h is a constant
+  def r = basering;
+  list one_hom_fac; //stands for one homogeneous factorization
+  int i; int j; int k;
+  string dbprintWhitespace = "";
+  for (i = 1; i<=voice;i++)
+  {dbprintWhitespace = dbprintWhitespace + " ";}
+  intvec ivm11 = intvec(-1,1);
+  dbprint(p,dbprintWhitespace +" Calculate one homogeneous factorization using homogfacFirstWeyl");
+  //Compute again a homogeneous factorization
+  one_hom_fac = homogfacFirstWeyl(h);
+  dbprint(p,dbprintWhitespace +"Successful");
+  if (size(one_hom_fac) == 0)
+  {//there is no homogeneous factorization or the polynomial was not homogeneous
+    return(list());
+  }//there is no homogeneous factorization or the polynomial was not homogeneous
+  //divide list in A0-Part and a list of x's resp. y's
+  list list_not_azero = list();
+  list list_azero;
+  list k_factor;
+  int is_list_not_azero_empty = 1;
+  int is_list_azero_empty = 1;
+  k_factor = list(one_hom_fac[1]);
+  if (absValue(deg(h,ivm11))<size(one_hom_fac)-1)
+  {//There is a nontrivial A_0-part
+    list_azero = one_hom_fac[2..(size(one_hom_fac)-absValue(deg(h,ivm11)))];
+    is_list_azero_empty = 0;
+  }//There is a nontrivial A_0 part
+  dbprint(p,dbprintWhitespace +" Combine x,y to xy in the factorization again.");
+  for (i = 1; i<=size(list_azero)-1;i++)
+  {//in homogfacFirstWeyl, we factorized theta, and this will be made undone
+    if (list_azero[i] == var(1))
+    {
+      if (list_azero[i+1]==var(2))
+      {
+        list_azero[i] = var(1)*var(2);
+        list_azero = delete(list_azero,i+1);
+      }
+    }
+    if (list_azero[i] == var(2))
+    {
+      if (list_azero[i+1]==var(1))
+      {
+        list_azero[i] = var(2)*var(1);
+        list_azero = delete(list_azero,i+1);
+      }
+    }
+  }//in homogfacFirstWeyl, we factorized theta, and this will be made undone
+  dbprint(p,dbprintWhitespace +" Done");
+  if(deg(h,ivm11)!=0)
+  {//list_not_azero is not empty
+    list_not_azero =
+      one_hom_fac[(size(one_hom_fac)-absValue(deg(h,ivm11))+1)..size(one_hom_fac)];
+    is_list_not_azero_empty = 0;
+  }//list_not_azero is not empty
+  //Map list_azero in K[theta]
+  dbprint(p,dbprintWhitespace +" Map list_azero to K[theta]");
+  ring tempRing = 0,(x,y,theta), dp;
+  setring(tempRing);
+  poly entry;
+  map thetamap = r,x,y;
+  if(!is_list_not_azero_empty)
+  {//Mapping in Singular is only possible, if the list before
+    //contained at least one element of the other ring
+    list list_not_azero = thetamap(list_not_azero);
+  }//Mapping in Singular is only possible, if the list before
+  //contained at least one element of the other ring
+  if(!is_list_azero_empty)
+  {//Mapping in Singular is only possible, if the list before
+    //contained at least one element of the other ring
+    list list_azero= thetamap(list_azero);
+  }//Mapping in Singular is only possible, if the list before
+  //contained at least one element of the other ring
+  list k_factor = thetamap(k_factor);
+  list tempmons;
+  dbprint(p,dbprintWhitespace +" Done");
+  for(i = 1; i<=size(list_azero);i++)
+  {//rewrite the polynomials in A1 as polynomials in K[theta]
+    tempmons = list();
+    for (j = 1; j<=size(list_azero[i]);j++)
+    {
+      tempmons = tempmons + list(list_azero[i][j]);
+    }
+    for (j = 1 ; j<=size(tempmons);j++)
+    {
+      entry = leadcoef(tempmons[j]);
+      for (k = 0; k < leadexp(tempmons[j])[2];k++)
+      {
+        entry = entry*(theta-k);
+      }
+      tempmons[j] = entry;
+    }
+    list_azero[i] = sum(tempmons);
+  }//rewrite the polynomials in A1 as polynomials in K[theta]
+  //Compute all permutations of the A0-part
+  dbprint(p,dbprintWhitespace +" Compute all permutations of the A_0-part with the first resp.
+the snd. variable");
+  list result;
+  int shift_sign;
+  int shift;
+  poly shiftvar;
+  if (size(list_not_azero)!=0)
+  {//Compute all possibilities to permute the x's resp. the y's in the list
+    if (list_not_azero[1] == x)
+    {//h had a negative weighted degree
+      shift_sign = 1;
+      shiftvar = x;
+    }//h had a negative weighted degree
+    else
+    {//h had a positive weighted degree
+      shift_sign = -1;
+      shiftvar = y;
+    }//h had a positive weighted degree
+    result = permpp(list_azero + list_not_azero);
+    for (i = 1; i<= size(result); i++)
+    {//adjust the a_0-parts
+      shift = 0;
+      for (j=1; j<=size(result[i]);j++)
+      {
+        if (result[i][j]==shiftvar)
+        {
+          shift = shift + shift_sign;
+        }
+        else
+        {
+          result[i][j] = subst(result[i][j],theta,theta + shift);
+        }
+      }
+    }//adjust the a_0-parts
+  }//Compute all possibilities to permute the x's resp. the y's in the list
+  else
+  {//The result is just all the permutations of the a_0-part
+    result = permpp(list_azero);
+  }//The result is just all the permutations of the a_0 part
+  if (size(result)==0)
+  {
+    return(result);
+  }
+  dbprint(p,dbprintWhitespace +" Done");
+  dbprint(p,dbprintWhitespace +" Searching for theta resp. theta+1 in the list and fact. them");
+  //Now we are going deeper and search for theta resp. theta + 1, substitute
+  //them by xy resp. yx and go on permuting
+  int found_theta;
+  int thetapos;
+  list leftpart;
+  list rightpart;
+  list lparts;
+  list rparts;
+  list tempadd;
+  for (i = 1; i<=size(result) ; i++)
+  {//checking every entry of result for theta or theta +1
+    found_theta = 0;
+    for(j=1;j<=size(result[i]);j++)
+    {
+      if (result[i][j]==theta)
+      {//the jth entry is theta and can be written as x*y
+        thetapos = j;
+        result[i]= insert(result[i],x,j-1);
+        j++;
+        result[i][j] = y;
+        found_theta = 1;
+        break;
+      }//the jth entry is theta and can be written as x*y
+      if(result[i][j] == theta +1)
+      {
+        thetapos = j;
+        result[i] = insert(result[i],y,j-1);
+        j++;
+        result[i][j] = x;
+        found_theta = 1;
+        break;
+      }
+    }
+    if (found_theta)
+    {//One entry was theta resp. theta +1
+      leftpart = result[i];
+      leftpart = leftpart[1..thetapos];
+      rightpart = result[i];
+      rightpart = rightpart[(thetapos+1)..size(rightpart)];
+      lparts = list(leftpart);
+      rparts = list(rightpart);
+      //first deal with the left part
+      if (leftpart[thetapos] == x)
+      {
+        shift_sign = 1;
+        shiftvar = x;
+      }
+      else
+      {
+        shift_sign = -1;
+        shiftvar = y;
+      }
+      for (j = size(leftpart); j>1;j--)
+      {//drip x resp. y
+        if (leftpart[j-1]==shiftvar)
+        {//commutative
+          j--;
+          continue;
+        }//commutative
+        if (deg(leftpart[j-1],intvec(-1,1,0))!=0)
+        {//stop here
+          break;
+        }//stop here
+        //Here, we can only have a a0- part
+        leftpart[j] = subst(leftpart[j-1],theta, theta + shift_sign);
+        leftpart[j-1] = shiftvar;
+        lparts = lparts + list(leftpart);
+      }//drip x resp. y
+      //and now deal with the right part
+      if (rightpart[1] == x)
+      {
+        shift_sign = 1;
+        shiftvar = x;
+      }
+      else
+      {
+        shift_sign = -1;
+        shiftvar = y;
+      }
+      for (j = 1 ; j < size(rightpart); j++)
+      {
+        if (rightpart[j+1] == shiftvar)
+        {
+          j++;
+          continue;
+        }
+        if (deg(rightpart[j+1],intvec(-1,1,0))!=0)
+        {
+          break;
+        }
+        rightpart[j] = subst(rightpart[j+1], theta, theta - shift_sign);
+        rightpart[j+1] = shiftvar;
+        rparts = rparts + list(rightpart);
+      }
+      //And now, we put all possibilities together
+      tempadd = list();
+      for (j = 1; j<=size(lparts); j++)
+      {
+        for (k = 1; k<=size(rparts);k++)
+        {
+          tempadd = tempadd + list(lparts[j]+rparts[k]);
+        }
+      }
+      tempadd = delete(tempadd,1); // The first entry is already in the list
+      result = result + tempadd;
+      continue; //We can may be not be done already with the ith entry
+    }//One entry was theta resp. theta +1
+  }//checking every entry of result for theta or theta +1
+  dbprint(p,dbprintWhitespace +" Done");
+  //map back to the basering
+  dbprint(p,dbprintWhitespace +" Mapping back everything to the basering");
+  setring(r);
+  map finalmap = tempRing, var(1), var(2),var(1)*var(2);
+  list result = finalmap(result);
+  for (i=1; i<=size(result);i++)
+  {//adding the K factor
+    result[i] = k_factor + result[i];
+  }//adding the k-factor
+  dbprint(p,dbprintWhitespace +" Done");
+  dbprint(p,dbprintWhitespace +" Delete double entries in the list.");
+  result = delete_dublicates_noteval(result);
+  dbprint(p,dbprintWhitespace +" Done");
+  return(result);
+}//proc HomogfacFirstWeylAll
+/* example */
+/* { */
+/*      "EXAMPLE:";echo=2; */
+/*      ring R = 0,(x,y),Ws(-1,1); */
+/*      def r = nc_algebra(1,1); */
+/*      setring(r); */
+/*      poly h = (x^2*y^2+1)*(x^4); */
+/*      homogfacFirstWeyl_all(h); */
+/* } */
+
+
+static proc homogfacNthWeyl_all(poly h)
+"USAGE: homogfacNthWeyl_all(h); h is a homogeneous polynomial in the nth Weyl algebra
+ with respect to the ZZ-grading on the nth Weyl algebra.
+RETURN: list
+PURPOSE: Computes all factorizations of a homogeneous polynomial h with respect
+  to the ZZ-grading on the nth Weyl algebra
+THEORY: @code{homogfacFirstWeyl} returns a list with all factorization of the given,
+ homogeneous polynomial. It uses the output of homogfacNthWeyl and permutes
+ its entries with respect to the commutation rule. Furthermore, if a
+ factor of degree zero is irreducible in K[theta_1, ..., theta_n], but reducible in
+ the nth Weyl algebra, the permutations of this element with the other
+ entries will also be computed.
+SEE ALSO: homogfacFirstWeyl
+"{//proc HomogfacNthWeylAll
+  int p=printlevel-voice+2;//for dbprint
+  intvec iv11= 1:nvars(basering);
+  if (deg(h,iv11) <= 0 )
+  {//h is a constant
+    dbprint(p,"Given polynomial was not homogeneous");
+    return(list(list(h)));
+  }//h is a constant
+  def r = basering;
+  list one_hom_fac; //stands for one homogeneous factorization
+  int i; int j; int k; int l;
+  string dbprintWhitespace = "";
+  for (i = 1; i<=voice;i++)
+  {dbprintWhitespace = dbprintWhitespace + " ";}
+  dbprint(p,dbprintWhitespace +" Calculate one homogeneous factorization using homogfacNthWeyl");
+  //Compute again a homogeneous factorization
+  one_hom_fac = homogfacNthWeyl(h);
+  dbprint(p,dbprintWhitespace +"Successful");
+  if (size(one_hom_fac) == 0)
+  {//there is no homogeneous factorization or the polynomial was not homogeneous
+    return(list());
+  }//there is no homogeneous factorization or the polynomial was not homogeneous
+  //divide list in A0-Part and a list of x_i's resp. y_i's
+  list list_not_azero = list();
+  list list_azero;
+  list k_factor;
+  int is_list_not_azero_empty = 1;
+  int is_list_azero_empty = 1;
+  k_factor = list(number(one_hom_fac[1]));
+  dbprint(p, dbprintWhitespace + "Determine whether there is an A0
+part or not.");
+  int absValueOfDegree = 0;
+  intvec degVecH = degreeOfNthWeylPoly(h);
+  intvec lExp;
+  for (i = 1; i<=size(degVecH); i++)
+  {//adding up the absolute values of the degrees of the respective variables
+    absValueOfDegree = absValueOfDegree + absValue(degVecH[i]);
+  }//adding up the absolute values of the degrees of the respective variables
+  if (absValueOfDegree < size(one_hom_fac) - 1)
+  {//There is a nontrivial A0 part
+    list_azero = one_hom_fac[2..(size(one_hom_fac)-absValueOfDegree)];
+    is_list_azero_empty = 0;
+  }//There is a nontrivial A0 part
+  dbprint(p,dbprintWhitespace +" Combine x_i,d_i to x_id_i in the
+factorization again.");
+  dbprint(p,dbprintWhitespace + " The corresponding list of A0
+    factors is: " + string(list_azero));
+  for (i = 1; i<size(list_azero);i++)
+  {//in homogfacFirstWeyl, we factorized the theta_i, and this will be
+   //made undone
+    for (j = 1; j<=nvars(basering) div 2; j++)
+    {//iterating through the variables
+      if (list_azero[i] == var(j))
+      {
+        if (list_azero[i+1]==var(j + nvars(basering) div 2))
+        {
+          list_azero[i] = var(j)*var(j + nvars(basering) div 2);
+          list_azero = delete(list_azero,i+1);
+        }
+      }
+      if (list_azero[i] == var(j + nvars(basering) div 2))
+      {
+        if (list_azero[i+1]==var(j))
+        {
+          list_azero[i] = var(j + nvars(basering) div 2)*var(j);
+          list_azero = delete(list_azero,i+1);
+        }
+      }
+    }//iterating through the variables
+  }//in homogfacFirstWeyl, we factorized theta_i, and this will be
+   //made undone
+  dbprint(p,dbprintWhitespace +" Done");
+  dbprint(p, dbprintWhitespace + "The new list is: " +
+          string(list_azero));
+  if (degVecH != 0:(nvars(basering) div 2))
+  {//list_not_azero is not empty
+    list_not_azero = one_hom_fac[(size(one_hom_fac) -
+                                  absValueOfDegree +1)..size(one_hom_fac)];
+    is_list_not_azero_empty = 0;
+  }//list_not_azero is not empty
+  dbprint(p,dbprintWhitespace+" Mapping list_azero to K[theta_1, ... , theta_n]");
+  ring tempRing = 0,(x(1..(nvars(basering) div 2)),
+                     y(1..(nvars(basering) div 2)),
+                     theta(1..(nvars(basering) div 2))),dp;
+  setring tempRing;
+  poly entry;
+  ideal mapList;
+  for (i = 1; i<=nvars(r) ; i++)
+  {//filling the list of elements we want to map
+    mapList[i] = var(i);
+  }//filling the list of elements we want to map
+  map thetamap = r,mapList;
+  if(!is_list_not_azero_empty)
+  {//Mapping in Singular is only possible, if the list before
+    //contained at least one element of the other ring
+    list list_not_azero = thetamap(list_not_azero);
+  }//Mapping in Singular is only possible, if the list before
+  //contained at least one element of the other ring
+  if(!is_list_azero_empty)
+  {//Mapping in Singular is only possible, if the list before
+    //contained at least one element of the other ring
+    list list_azero= thetamap(list_azero);
+  }//Mapping in Singular is only possible, if the list before
+  //contained at least one element of the other ring
+  list k_factor = thetamap(k_factor);
+  list tempmons;
+  dbprint(p,dbprintWhitespace +" Done");
+  for(i = 1; i<=size(list_azero);i++)
+  {//rewrite the polynomials in A1 as polynomials in K[theta]
+    tempmons = list();
+    for (j = 1; j<=size(list_azero[i]);j++)
+    {
+      tempmons = tempmons + list(list_azero[i][j]);
+    }
+    for (j = 1 ; j<=size(tempmons);j++)
+    {
+      entry = leadcoef(tempmons[j]);
+      lExp  = leadexp(tempmons[j]);
+      for (l = 1; l<=nvars(r) div 2; l++)
+      {
+        for (k = 0; k < lExp[l];k++)
+        {
+          entry = entry*(theta(l)-k);
+        }
+      }
+      tempmons[j] = entry;
+    }
+    list_azero[i] = sum(tempmons);
+  }//rewrite the polynomials in A1 as polynomials in K[theta]
+  //Compute all permutations of the A0-part
+  dbprint(p, dbprintWhitespace + "The polynomials rewritten in
+K[theta_1, ... , theta_n] look like:");
+  dbprint(p,list_azero);
+  dbprint(p,dbprintWhitespace +" Compute all permutations of the A_0-part with the first resp.
+the snd. variable");
+  list result;
+  intvec shift = 0:(nvars(r) div 2);
+  if (size(list_not_azero)!=0)
+  {//Compute all possibilities to permute the x's resp. the y's in the list
+    result = permpp(list_azero + list_not_azero);
+    for (i = 1; i<= size(result); i++)
+    {//adjust the a_0-parts
+      shift = 0:(nvars(r) div 2);
+      for (j=1; j<=size(result[i]);j++)
+      {//iterating through each factor
+        if (deg(result[i][j],(1:nvars(r),0:(nvars(r) div 2))) !=0)
+        {//the factor is a single variable
+          for(k = 1; k<=nvars(r); k++)
+          {//Iterating through the variables to find the variable
+            if (result[i][j]==var(k))
+            {//found it!
+              if (k<=nvars(r) div 2)
+              {shift[k] = shift[k] + 1;}
+              else
+              {shift[k -(nvars(r) div 2)] = shift[k -(nvars(r) div
+                                                      2)] -1;
+              }
+              break;
+            }//found it!
+          }//Iterating through the variables to find the variable
+        }//the factor is a single variable
+        else
+        {//factor was a theta poly
+          for (k= 1; k <= nvars(r) div 2;k++)
+          {result[i][j] = subst(result[i][j],theta(k),theta(k)
+                                + shift[k]);}
+        }//factor was a theta poly
+      }//iterating through each factor
+    }//adjust the a_0-parts
+  }//Compute all possibilities to permute the x's resp. the y's in the list
+  else
+  {//The result is just all the permutations of the a_0-part
+    result = permpp(list_azero);
+  }//The result is just all the permutations of the a_0 part
+  if (size(result)==0)
+  {
+    return(result);
+  }
+  dbprint(p,dbprintWhitespace +" Done");
+  dbprint(p, dbprintWhitespace + "The factorization list is now:");
+  dbprint(p,result);
+  dbprint(p, dbprintWhitespace + "Checking whether the
+        intermediate result is correct or not");
+  dbprint(p,testNCfac(result));
+  dbprint(p,dbprintWhitespace +" Searching for theta resp. theta+1 in
+  the list and fact. them");
+  //Now we are going deeper and search for theta resp. theta + 1, substitute
+  //them by xy resp. yx and go on permuting
+  int found_theta;
+  int thetapos;
+  int shift_sign;
+  int thetaIndex;
+  poly shiftvar;
+  list leftpart;
+  list rightpart;
+  list lparts;
+  list rparts;
+  list tempadd;
+  for (i = 1; i<=size(result) ; i++)
+  {//checking every entry of result for theta or theta +1
+    found_theta = 0;
+    for(j=1;j<=size(result[i]);j++)
+    {//iterating through all factors
+      for (k = 1; k<=nvars(r) div 2; k++)
+      {//iterating through the variables
+        if (result[i][j]==theta(k))
+        {//the jth entry is theta and can be written as x*y
+          thetapos = j;
+          thetaIndex = k;
+          result[i]= insert(result[i],x(k),j-1);
+          j++;
+          result[i][j] = y(k);
+          found_theta = 1;
+          break;
+        }//the jth entry is theta and can be written as x*y
+        if(result[i][j] == theta(k) +1)
+        {
+          thetapos = j;
+          thetaIndex = k;
+          result[i] = insert(result[i],y(k),j-1);
+          j++;
+          result[i][j] = x(k);
+          found_theta = 1;
+          break;
+        }
+      }//iterating through the variables
+      if(found_theta)
+      {break;}
+    }//iterating through all factors
+    if (found_theta)
+    {//One entry was theta resp. theta +1
+      leftpart = result[i];
+      leftpart = leftpart[1..thetapos];
+      rightpart = result[i];
+      rightpart = rightpart[(thetapos+1)..size(rightpart)];
+      lparts = list(leftpart);
+      rparts = list(rightpart);
+      //first deal with the left part
+      if (leftpart[thetapos] == x(thetaIndex))
+      {
+        shift_sign = 1;
+        shiftvar = x(thetaIndex);
+      }
+      else
+      {
+        shift_sign = -1;
+        shiftvar = y(thetaIndex);
+      }
+      for (j = size(leftpart); j>1;j--)
+      {//drip x resp. y
+        if (leftpart[j-1]==shiftvar)
+        {//commutative
+          j--;
+          continue;
+        }//commutative
+        if (leadexp(leftpart[j-1])[thetaIndex + nvars(r) div 2]
+            - leadexp(leftpart[j-1])[thetaIndex]!=0)
+        {//stop here
+          break;
+        }//stop here
+        //Here, we can only have a a0- part
+        leftpart[j] = subst(leftpart[j-1],theta(thetaIndex), theta(thetaIndex) + shift_sign);
+        leftpart[j-1] = shiftvar;
+        lparts = lparts + list(leftpart);
+      }//drip x resp. y
+      //and now deal with the right part
+      if (rightpart[1] == x(thetaIndex))
+      {
+        shift_sign = 1;
+        shiftvar = x(thetaIndex);
+      }
+      else
+      {
+        shift_sign = -1;
+        shiftvar = y(thetaIndex);
+      }
+      for (j = 1 ; j < size(rightpart); j++)
+      {
+        if (rightpart[j+1] == shiftvar)
+        {
+          j++;
+          continue;
+        }
+        if (leadexp(rightpart[j+1])[thetaIndex + nvars(r) div 2]
+            - leadexp(rightpart[j+1])[thetaIndex]!=0)
+        {
+          break;
+        }
+        rightpart[j] = subst(rightpart[j+1], theta(thetaIndex), theta(thetaIndex) - shift_sign);
+        rightpart[j+1] = shiftvar;
+        rparts = rparts + list(rightpart);
+      }
+      //And now, we put all possibilities together
+      tempadd = list();
+      for (j = 1; j<=size(lparts); j++)
+      {
+        for (k = 1; k<=size(rparts);k++)
+        {
+          tempadd = tempadd + list(lparts[j]+rparts[k]);
+        }
+      }
+      tempadd = delete(tempadd,1); // The first entry is already in the list
+      result = result + tempadd;
+      continue; //We can may be not be done already with the ith entry
+    }//One entry was theta resp. theta +1
+  }//checking every entry of result for theta or theta +1
+  dbprint(p,dbprintWhitespace +" Done");
+  dbprint(p,dbprintWhitespace + "The new result list is:");
+  dbprint(result);
+  setring(r);
+  ideal finalMapList;
+  for(i = 1; i<=nvars(r);i++)
+  {
+    finalMapList[i] = var(i);
+  }
+  for (i = 1; i<=nvars(r) div 2; i++)
+  {
+    finalMapList[i + nvars(r)] = var(i)*var(i + (nvars(r) div 2));
+  }
+  map finalmap = tempRing,finalMapList;
+  list result = finalmap(result);
+  for (i=1; i<=size(result);i++)
+  {//adding the K factor
+    result[i] = k_factor + result[i];
+  }//adding the k-factor
+  dbprint(p,dbprintWhitespace +" Done");
+  dbprint(p,dbprintWhitespace +" Delete double entries in the list.");
+  result = delete_dublicates_noteval(result);
+  dbprint(p,dbprintWhitespace +" Done");
+  return(result);
+}//proc HomogfacNthWeylAll
+/*
+  Interesting Test-Polys:
+ring R = 0,(x1,x2,x3,d1,d2,d3),dp;
+matrix C[6][6] = 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;
+matrix D[6][6] = 0,0,0,1,0,0,
+                 0,0,0,0,1,0,
+                 0,0,0,0,0,1,
+                 -1,0,0,0,0,0,
+                 0,-1,0,0,0,0,
+                 0,0,-1,0,0,0;
+def r = nc_algebra(C,D);
+setring(r);
+poly h =x1*x2^2*x3^3*d1*d2^2+x2*x3^3*d2;
+h = (x1*x2^2*x3 + d1^2*d2*d3^3*x1^3*x2^3*x3^4)*(x1*d1 + x2*d2 + x3*d3);
+h = x1^2*d1+x1*x2*d2;
+
+ */
+
+//==================================================*
+//Computes all permutations of a given list
+static proc perm(list l)
+"
+DEPRECATED
+"
+{//proc perm
+  int i; int j;
+  list tempresult;
+  list result;
+  if (size(l)==0)
+  {
+    return(list());
+  }
+  if (size(l)==1)
+  {
+    return(list(l));
+  }
+  for (i = 1; i<=size(l); i++ )
+  {
+    tempresult = perm(delete(l,i));
+    for (j = 1; j<=size(tempresult);j++)
+    {
+      tempresult[j] = list(l[i])+tempresult[j];
+    }
+    result = result+tempresult;
+  }
+  return(result);
+}//proc perm
+
+//==================================================
+//computes all permutations of a given list by
+//ignoring equal entries (faster than perm)
+static proc permpp(list l)
+"
+INPUT: A list with entries of a type, where the ==-operator is defined
+OUTPUT: A list with all permutations of this given list.
+"
+{//proc permpp
+  int i; int j;
+  list tempresult;
+  list l_without_double;
+  list l_without_double_pos;
+  int double_entry;
+  list result;
+  if (size(l)==0)
+  {
+    return(list());
+  }
+  if (size(l)==1)
+  {
+    return(list(l));
+  }
+  for (i = 1; i<=size(l);i++)
+  {//Filling the list with unique entries
+    double_entry = 0;
+    for (j = 1; j<=size(l_without_double);j++)
+    {
+      if (l_without_double[j] == l[i])
+      {
+        double_entry = 1;
+        break;
+      }
+    }
+    if (!double_entry)
+    {
+      l_without_double = l_without_double + list(l[i]);
+      l_without_double_pos = l_without_double_pos + list(i);
+    }
+  }//Filling the list with unique entries
+  for (i = 1; i<=size(l_without_double); i++ )
+  {
+    tempresult = permpp(delete(l,l_without_double_pos[i]));
+    for (j = 1; j<=size(tempresult);j++)
+    {
+      tempresult[j] = list(l_without_double[i])+tempresult[j];
+    }
+    result = result+tempresult;
+  }
+  return(result);
+}//proc permpp
+
+//==================================================
+static proc checkIfProperNthWeyl()
+"
+INPUT: None
+OUTPUT: Checks whether the given basering is a proper Weyl algebra.
+        Proper means in the sense of our algorithms, i.e. fulfilling
+        the assumption that o ur basering is the Nth Weyl algebra and
+        that the xs are the first n variables, the differential
+        operators are the last n. Returns 1 if proper, 0 otherwise.
+"
+{//checkIfProperNthWeyl
+  if (!ncfactor_isWeyl())
+  {return(0);}
+  int i;
+  for (i = 1; i<=nvars(basering) div 2; i++)
+  {
+    if (var(i + nvars(basering) div 2)*var(i)
+        - var(i)*var(i+nvars(basering) div 2)!=1)
+    {
+      return(0);
+    }
+  }
+  return(1);
+}//checkIfProperNthWeyl
+//==================================================
+static proc checkIfProperNthQWeyl()
+"
+INPUT: None
+OUTPUT: Checks whether the given basering is a proper q-Weyl algebra.
+        Proper means in the sense of our algorithms, i.e. fulfilling
+        the assumption that o ur basering is the Nth Weyl algebra and
+        that the xs are the first n variables, the differential
+        operators are the last n. Returns 1 if proper, 0 otherwise.
+"
+{//checkIfProperNthQWeyl
+  if (!ncfactor_isQWeyl())
+  {return(0);}
+  int i;
+  for (i = 1; i<=nvars(basering) div 2; i++)
+  {
+    if (var(i + nvars(basering) div 2)*var(i)
+        - par(i)*var(i)*var(i+nvars(basering) div 2)!=1)
+    {
+      return(0);
+    }
+  }
+  return(1);
+}//checkIfProperNthQWeyl
+//==================================================
+static proc checkIfProperNthShift()
+"
+INPUT: None
+OUTPUT: Checks whether the given basering is a proper shift algebra.
+        Proper means in the sense of our algorithms, i.e. fulfilling
+        the assumption that our basering is the Nth shift algebra and
+        that the xs are the first n variables, the shift
+        operators are the last n. Returns 1 if proper, 0 otherwise.
+"
+{//checkIfProperNthShift
+  if (!ncfactor_isShift())
+  {return(0);}
+  int i;
+  for (i = 1; i<=nvars(basering) div 2; i++)
+  {
+    if (var(i + nvars(basering) div 2)*var(i)
+        - var(i)*var(i+nvars(basering) div 2)!=var(i+nvars(basering) div 2))
+    {
+      return(0);
+    }
+  }
+  return(1);
+}//checkIfProperNthShift
+
+//==================================================
+proc facWeyl(poly h)
+"USAGE: facWeyl(h); h a polynomial in the nth Weyl algebra
+RETURN: list
+PURPOSE: compute all factorizations of a polynomial in the first Weyl algebra
+THEORY: Implements the new algorithm by A. Heinle and V. Levandovskyy, see the thesis of A. Heinle
+ASSUME: basering is the nth Weyl algebra, where n in NN.
+NOTE: Every entry of the output list is a list with factors for one possible factorization.
+The first factor is always a constant (1, if no nontrivial constant could be excluded).
+EXAMPLE: example facFirstWeyl; shows examples
+SEE ALSO: facSubWeyl, testNCfac, facFirstShift, facFirstWeyl
+"{//proc facWeyl
+  //Definition of printlevel variable
+  int p = printlevel-voice+2;
+  int i;
+  string dbprintWhitespace = "";
+  for (i = 1; i<=voice;i++)
+  {dbprintWhitespace = dbprintWhitespace + " ";}
+  dbprint(p,dbprintWhitespace +" Checking if the given algebra is a Weyl algebra");
+  //Redefine the ring in my standard form
+  if (!ncfactor_isWeyl())
+  {//Our basering is not the Weyl algebra
+    ERROR("Ring was not a Weyl algebra");
+    return(list());
+  }//Our basering is not the Weyl algebra
+  dbprint(p,dbprintWhitespace +" Successful");
+
+  //A last check before we start the real business: Is h maybe just
+  //dependable on commutative variables?
+  if (isInCommutativeSubRing(h))
+  {//h is in a commutative subring
+    list hdepvars;
+    intvec tempIntVec;
+    for (i = 1; i<=nvars(basering) ; i++)
+    {
+      tempIntVec = 0:nvars(basering);
+      tempIntVec[i] = 1;
+      if (deg(h,tempIntVec)>0)
+      {
+        hdepvars = hdepvars + list(var(i));
+      }
+    }
+    if (size(hdepvars) ==0)
+    {//We just have a constant
+      return(list(list(h)));
+    }//We just have a constant
+    dbprint(p,dbprintWhitespace+"Polynomial was given commutative subring.
+Performing commutative factorization.");
+    def r = basering;
+    def rList = ringlist(basering);
+    rList = delete(rList,5);
+    rList = delete(rList,5);
+    def tempRing = ring(rList);
+    setring(tempRing);
+    poly h = imap(r,h);
+    list tempResult = factorize(h);
+    list result = list(list());
+    int j;
+    for (i = 1; i<=size(tempResult[1]); i++)
+    {
+      for (j = 1; j<=tempResult[2][i]; j++)
+      {
+        result[1] = result[1] + list(tempResult[1][i]);
+      }
+    }
+    //mapping back
+    setring(r);
+    def result = imap(tempRing,result);
+    dbprint(p,dbprintWhitespace+"result:");
+    dbprint(p,result);
+    dbprint(p,dbprintWhitespace+"Computing all permutations of this factorization");
+    poly constantFactor = result[1][1];
+    result[1] = delete(result[1],1);//Deleting the constant factor
+    result=permpp(result[1]);
+    for (i = 1; i<=size(result);i++)
+    {//Insert constant factor
+      result[i] = insert(result[i],constantFactor);
+    }//Insert constant factor
+    dbprint(p,dbprintWhitespace+"Done.");
+    return(result);
+  }//h is in a commutative subring
+  dbprint(p,dbprintWhitespace +" Successful");
+  list result = list();
+  int j; int k; int l; //counter
+  if (!checkIfProperNthWeyl())
+  {//The given ring was not a proper nth Weyl algebra
+    dbprint(p,dbprintWhitespace +" positions of the variables have to be switched");
+    dbprint(p,dbprintWhitespace + "Constructing the the proper ring.");
+    def r = basering;
+    list tempRingList = ringlist(r);
+    tempRingList = delete(tempRingList,6);
+
+    list the_vars;
+    for (i = 1; i<=nvars(r); i++)
+    {the_vars[i] = var(i);}
+    int maybeDInWrongPos;
+    poly tempVariable;
+    for (i = 1; i<=size(the_vars) div 2; i++)
+    {//Swapping the variables as needed
+      maybeDInWrongPos = 1;
+      if (the_vars[i + size(the_vars) div 2]*the_vars[i]
+          -the_vars[i]*the_vars[i + size(the_vars) div 2] == 1)
+      {
+        i++; continue;
+      }
+      //If we enter this line, there is a break with our property
+      //condition
+      for (j = i+1; j<=size(the_vars); j++)
+      {
+        if (the_vars[j]*the_vars[i]-the_vars[i]*the_vars[j]==1)
+        {//In this case, we matched a var x to a repective d
+          tempVariable = the_vars[i + size(the_vars) div 2];
+          the_vars[i + size(the_vars) div 2] = the_vars[j];
+          the_vars[j] = tempVariable;
+          maybeDInWrongPos = 0;
+          break;
+        }//In this case, we matched a var x to a repective d
+      }
+      if (maybeDInWrongPos)
+      {//var(i) is actually a d, not an x
+        print("i has to be pushed to the end.");
+        tempVariable = the_vars[i];
+        the_vars = delete(the_vars, i);
+        the_vars = the_vars + list(tempVariable);
+        continue;
+      }//var(i) is actually a d, not an x
+    }//Swapping the variables as needed
+    for (i = 1; i<=size(the_vars); i++)
+    {tempRingList[2][i] = string(the_vars[i]);}
+    matrix DTemp[nvars(r)][nvars(r)];
+    for (i = 1; i<=ncols(DTemp) div 2; i++)
+    {
+      DTemp[i,i + nvars(r) div 2] = 1;
+    }
+    tempRingList = tempRingList + list(DTemp);
+    def tempRing = ring(tempRingList);
+    dbprint(p,dbprintWhitespace + "Done. The altered ring is the following:");
+    dbprint(p,tempRing);
+    setring(tempRing);
+    poly h = imap(r,h);
+    dbprint(p,dbprintWhitespace +" Successful");
+    list resulttemp = facWeyl(h);
+    setring(r);
+    result = imap(tempRing,resulttemp);
+    return (result);
+  }//The given ring was not a proper nth Weyl algebra
+
+  dbprint(p, dbprintWhitespace +" factorization of the polynomial with the routine sfacwaNthWeyl");
+  result = sfacwaNthWeyl(h);
+  dbprint(p,dbprintWhitespace +" Done");
+  if (homogwithorderNthWeyl(h))
+  {
+    dbprint(p, dbprintWhitespace + " Polynomial was homogeneous, therefore we have
+already a complete factorization and do not have to go through the factors recursively.");
+    return(result);
+  }
+  result = normalizeFactors(result);
+  result = delete_dublicates_noteval(result);
+  dbprint(p,dbprintWhitespace + "We have the following intermediate list of inhomogeneous
+factorizations:");
+  dbprint(p,result);
+  dbprint(p,dbprintWhitespace +" recursively check factors for irreducibility");
+  list recursivetemp;
+  int changedSomething;
+  for(i = 1; i<=size(result);i++)
+  {//recursively factorize factors
+    if(size(result[i])>2)
+    {//Nontrivial factorization
+      for (j=2;j<=size(result[i]);j++)
+      {//Factorize every factor
+        recursivetemp = facWeyl(result[i][j]);
+        //if(size(recursivetemp)>1)
+        //{//we have a nontrivial factorization
+        changedSomething = 0;
+        for(k=1; k<=size(recursivetemp);k++)
+        {//insert factorized factors
+          if(size(recursivetemp[k])>2)
+          {//nontrivial
+            changedSomething = 1;
+            result = insert(result,result[i],i);
+            for(l = size(recursivetemp[k]);l>=2;l--)
+            {
+              result[i+1] = insert(result[i+1],recursivetemp[k][l],j);
+            }
+            result[i+1] = delete(result[i+1],j);
+          }//nontrivial
+        }//insert factorized factors
+        if (changedSomething)
+        {
+          result = delete(result,i);
+        }
+        //}//we have a nontrivial factorization
+      }//Factorize every factor
+    }//Nontrivial factorization
+  }//recursively factorize factors
+  dbprint(p,dbprintWhitespace +" Done");
+  if (size(result)==0)
+  {//only the trivial factorization could be found
+    result = list(list(1,h));
+  }//only the trivial factorization could be found
+  list resultWithInterchanges;
+  dbprint(p,dbprintWhitespace+ "And the result without interchanges with homogeneous factors is:");
+  dbprint(p,result);
+  for (i = 1; i <= size(result) ; i++)
+  {//applying the interchanges to result
+    resultWithInterchanges = resultWithInterchanges +
+                             checkForHomogInhomogInterchangabilityNthWeyl(result[i],
+                                                                          2,
+                                                                          size(result[i]));
+  }//applying the interchanges to result
+  dbprint(p,dbprintWhitespace + "With interchanges, the result is:");
+  dbprint(p,resultWithInterchanges);
+  //now, refine the possible redundant list
+  return( delete_dublicates_noteval(resultWithInterchanges) );
+}//proc facWeyl
+example
+{
+  "EXAMPLE:";echo=2;
+  ring R = 0,(x1,x2,d1,d2),dp;
+  matrix C[4][4] = 1,1,1,1,
+                  1,1,1,1,
+                  1,1,1,1,
+                  1,1,1,1;
+  matrix D[4][4] = 0,0,1,0,
+                  0,0,0,1,
+                  -1,0,0,0,
+                  0,-1,0,0;
+  def r = nc_algebra(C,D);
+  setring(r);
+  poly h = (d1+1)^2*(d1 + x1*d2);
+  facWeyl(h);
+}
+
+//==================================================
+static proc normalizeFactors(list factList)
+"INPUT: A list of factorizations, as outputted e.g. by facWeyl
+OUTPUT: If any entry  in a factorization is not primitive, this function
+        divides the common divisor out and multiplies the first entry with it.
+"
+{//normalizeFactors
+  int i; int j;
+  list result = factList;
+  for (i = 1; i<=size(result); i++)
+  {//iterating through every different factorization
+    for (j=2; j<=size(result[i]); j++)
+    {//Iterating through all respective factors
+      if (content(result[i][j])!=number(1))
+      {//Got one where the content is not equal to 1
+        result[i][1] = result[i][1] * content(result[i][j]);
+        result[i][j] = result[i][j] / content(result[i][j]);
+      }//Got one where the content is not equal to 1
+    }//Iterating through all respective factors
+  }//iterating through every different factorization
+  return(result);
+}//normalizeFactors
+
+//==================================================
+//factorization of the first Weyl Algebra
+
+//The following procedure just serves the purpose to
+//transform the input into an appropriate input for
+//the procedure sfacwa, where the ring must contain the
+//variables in a certain order.
+static proc facFirstWeyl_old(poly h)
+"USAGE: facFirstWeyl(h); h a polynomial in the first Weyl algebra
+RETURN: list
+PURPOSE: compute all factorizations of a polynomial in the first Weyl algebra
+THEORY: Implements the new algorithm by A. Heinle and V. Levandovskyy, see the thesis of A. Heinle
+ASSUME: basering is the first Weyl algebra
+NOTE: Every entry of the output list is a list with factors for one possible factorization.
+The first factor is always a constant (1, if no nontrivial constant could be excluded).
+EXAMPLE: example facFirstWeyl; shows examples
+SEE ALSO: facSubWeyl, testNCfac, facFirstShift
+"{//proc facFirstWeyl_old
+  //Definition of printlevel variable
+  int p = printlevel-voice+2;
+  int i;
+  string dbprintWhitespace = "";
+  for (i = 1; i<=voice;i++)
+  {dbprintWhitespace = dbprintWhitespace + " ";}
+  dbprint(p,dbprintWhitespace +" Checking if the given algebra is a Weyl algebra");
+  //Redefine the ring in my standard form
+  if (!isWeyl())
+  {//Our basering is not the Weyl algebra
+    ERROR("Ring was not the first Weyl algebra");
+    return(list());
+  }//Our basering is not the Weyl algebra
+  dbprint(p,dbprintWhitespace +" Successful");
+  dbprint(p,dbprintWhitespace +" Checking, if the given ring is the first Weyl algebra");
+  if(nvars(basering)!=2)
+  {//Our basering is the Weyl algebra, but not the first
+    ERROR("Ring is not the first Weyl algebra");
+    return(list());
+  }//Our basering is the Weyl algebra, but not the first
+
+  //A last check before we start the real business: Is h already given as a polynomial just
+  //in one variable?
+  if (deg(h,intvec(1,0))== 0 or deg(h,intvec(0,1)) == 0)
+  {//h is in K[x] or in K[d]
+    if (deg(h,intvec(1,0))== 0 and deg(h,intvec(0,1)) == 0)
+    {//We just have a constant
+      return(list(list(h)));
+    }//We just have a constant
+    dbprint(p,dbprintWhitespace+"Polynomial was given in one variable.
+Performing commutative factorization.");
+    int theCommVar;
+    if (deg(h,intvec(1,0)) == 0)
+    {//The second variable is the variable to factorize
+      theCommVar = 2;
+    }//The second variable is the variable to factorize
+    else{theCommVar = 1;}
+    def r = basering;
+    ring tempRing = 0,(var(theCommVar)),dp;
+    if (theCommVar == 1){map mapToCommutative = r,var(1),1;}
+    else {map mapToCommutative = r,1,var(1);}
+    poly h = mapToCommutative(h);
+    list tempResult = factorize(h);
+    list result = list(list());
+    int j;
+    for (i = 1; i<=size(tempResult[1]); i++)
+    {
+      for (j = 1; j<=tempResult[2][i]; j++)
+      {
+        result[1] = result[1] + list(tempResult[1][i]);
+      }
+    }
+    //mapping back
+    setring(r);
+    map mapBackFromCommutative = tempRing,var(theCommVar);
+    def result = mapBackFromCommutative(result);
+    dbprint(p,dbprintWhitespace+"result:");
+    dbprint(p,result);
+    dbprint(p,dbprintWhitespace+"Computing all permutations of this factorization");
+    poly constantFactor = result[1][1];
+    result[1] = delete(result[1],1);//Deleting the constant factor
+    result=permpp(result[1]);
+    for (i = 1; i<=size(result);i++)
+    {//Insert constant factor
+      result[i] = insert(result[i],constantFactor);
+    }//Insert constant factor
+    dbprint(p,dbprintWhitespace+"Done.");
+    return(result);
+  }//h is in K[x] or in K[d]
+  dbprint(p,dbprintWhitespace +" Successful");
+  list result = list();
+  int j; int k; int l; //counter
+  if (ringlist(basering)[6][1,2] == -1) //manual of ringlist will tell you why
+  {
+    dbprint(p,dbprintWhitespace +" positions of the variables have to be switched");
+    def r = basering;
+    ring tempRing = ringlist(r)[1][1],(x,y),Ws(-1,1); // very strange:
+    // setting Wp(-1,1) leads to SegFault; to clarify why!!!
+    def NTR = nc_algebra(1,1);
+    setring NTR ;
+    map transf = r, var(2), var(1);
+    dbprint(p,dbprintWhitespace +" Successful");
+    list resulttemp = sfacwa(h);
+    setring(r);
+    map transfback = NTR, var(2),var(1);
+    result = transfback(resulttemp);
+  }
+  else
+  {
+    dbprint(p, dbprintWhitespace +" factorization of the polynomial with the routine sfacwa");
+    result = sfacwa(h);
+    dbprint(p,dbprintWhitespace +" Done");
+  }
+  if (homogwithorder(h,intvec(-1,1)))
+  {
+    dbprint(p, dbprintWhitespace + " Polynomial was homogeneous, therefore we have
+already a complete factorization and do not have to go through the factors recursively.");
+    return(result);
+  }
+  result = normalizeFactors(result);
+  result = delete_dublicates_noteval(result);
+  dbprint(p,dbprintWhitespace + "We have the following intermediate list of inhomogeneous
+factorizations:");
+  dbprint(p,result);
+  dbprint(p,dbprintWhitespace +" recursively check factors for irreducibility");
+  list recursivetemp;
+  int changedSomething;
+  for(i = 1; i<=size(result);i++)
+  {//recursively factorize factors
+    if(size(result[i])>2)
+    {//Nontrivial factorization
+      for (j=2;j<=size(result[i]);j++)
+      {//Factorize every factor
+        recursivetemp = facFirstWeyl(result[i][j]);
+        //if(size(recursivetemp)>1)
+        //{//we have a nontrivial factorization
+        changedSomething = 0;
+        for(k=1; k<=size(recursivetemp);k++)
+        {//insert factorized factors
+          if(size(recursivetemp[k])>2)
+          {//nontrivial
+            changedSomething = 1;
+            result = insert(result,result[i],i);
+            for(l = size(recursivetemp[k]);l>=2;l--)
+            {
+              result[i+1] = insert(result[i+1],recursivetemp[k][l],j);
+            }
+            result[i+1] = delete(result[i+1],j);
+          }//nontrivial
+        }//insert factorized factors
+        if (changedSomething)
+        {
+          result = delete(result,i);
+        }
+        //}//we have a nontrivial factorization
+      }//Factorize every factor
+    }//Nontrivial factorization
+  }//recursively factorize factors
+  dbprint(p,dbprintWhitespace +" Done");
+  if (size(result)==0)
+  {//only the trivial factorization could be found
+    result = list(list(1,h));
+  }//only the trivial factorization could be found
+  list resultWithInterchanges;
+  dbprint(p,dbprintWhitespace+ "And the result without interchanges with homogeneous factors is:");
+  dbprint(p,result);
+  for (i = 1; i <= size(result) ; i++)
+  {//applying the interchanges to result
+    resultWithInterchanges = resultWithInterchanges +
+                             checkForHomogInhomogInterchangability(result[i],2,size(result[i]));
+  }//applying the interchanges to result
+  dbprint(p,dbprintWhitespace + "With interchanges, the result is:");
+  dbprint(p,resultWithInterchanges);
+  //now, refine the possible redundant list
+  return( delete_dublicates_noteval(resultWithInterchanges) );
+}//proc facFirstWeyl_old
+
+proc facFirstWeyl(poly h)
+"USAGE: facFirstWeyl(h); h a polynomial in the first Weyl algebra
+RETURN: list
+PURPOSE: compute all factorizations of a polynomial in the first Weyl algebra
+THEORY: This function is a wrapper for facWeyl. It exists to make this library downward-compatible
+        with older versions.
+ASSUME: basering is the first Weyl algebra
+NOTE: Every entry of the output list is a list with factors for one possible factorization.
+The first factor is always a constant (1, if no nontrivial constant could be excluded).
+EXAMPLE: example facFirstWeyl; shows examples
+SEE ALSO: facSubWeyl, testNCfac, facShift"
+{//facFirstWeyl
+  return(facWeyl(h));
+}//facFirstWeyl
+example
+{
+  "EXAMPLE:";echo=2;
+  ring R = 0,(x,y),dp;
+  def r = nc_algebra(1,1);
+  setring(r);
+  poly h = (x^2*y^2+x)*(x+1);
+  facFirstWeyl(h);
+}
+
+static proc checkForHomogInhomogInterchangabilityNthWeyl(list factors, int posLeft, int posRight)
+"
+INPUT:  A list consisting of factors of a certain polynomial in the nth Weyl
+        algebra, factors, and a position from the left and the right, where the last swap was done.
+OUTPUT: A list containing lists consisting of factors of a certain polynomial in the nth Weyl
+        algebra.
+The purpose of this function is to check whether we can interchange certain inhomogeneous factors
+with homogeneous ones. If it is possible, this function returns a list of lists
+of possible interchanges.
+
+The idea came because of an example, where we need an extra swap in the end, otherwise we would
+not capture all factorizations. The example was
+h = x4d7+11x3d6+x2d7+x2d6+x3d4+29x2d5+xd6+8xd5+d6+5x2d3+14xd4+13d4+5xd2+d3+d;
+
+ASSUMPTIONS:
+
+- All factors are irreducible
+- Our basering is the Nth Weyl algebra; the xs are the first n variables,
+  the differential operators are the last n.
+- No entry in the list factors is 0.
+"
+{//checkForHomogInhomogInterchangabilityNthWeyl
+  int p = printlevel-voice+2;
+  string dbprintWhitespace = "";
+  int i; int j; int k; int l;
+  for (i = 1; i<=voice;i++)
+  {dbprintWhitespace = dbprintWhitespace + " ";}
+  if (size(factors) <= 2 || posLeft >= posRight - 1)
+  {//easiest case: There is nothing to swap
+    return (list(factors));
+  }//easiest case: There is nothing to swap
+  list result = list(factors);
+  list tempResultEntries;
+  list tempSwaps;
+  list tempSwapsTempEntry;
+  list attemptToSwap;
+  int posHomogBegin;
+  int posHomogEnd;
+  poly leftHomogFactorProduct;
+  poly rightHomogFactorProduct;
+  dbprint(p, dbprintWhitespace+"We try to swap elements in the following list:");
+  dbprint(p, factors);
+  dbprint(p, "The left border is at position: "+string(posLeft));
+  dbprint(p, "The right border is at position: " + string(posRight));
+  for (i = posLeft; i < posRight; i++)
+  {//checking within the window posLeft <--> posRight, if there are interchanges possible
+    leftHomogFactorProduct = 1;
+    while (homogwithorderNthWeyl(factors[i]))
+    {//We have a homogeneous polynomial somewhere on the left
+      if (leftHomogFactorProduct == 1)
+      {posHomogBegin = i;}
+      leftHomogFactorProduct = leftHomogFactorProduct * factors[i];
+      i = i+1;
+      if (i>=posRight)
+      {break;}
+    }//We have a homogeneous polynomial somewhere on the left
+    if ((leftHomogFactorProduct !=1) && (!homogwithorderNthWeyl(factors[i])))
+    {//We have a group of homogeneous polynomials and an inhomogeneous one that we can try to swap.
+      attemptToSwap = extractHomogeneousDivisorsRightNthWeyl(leftHomogFactorProduct*factors[i]);
+      for (l = 1; l<=size(attemptToSwap); l++)
+      {
+        if (size(attemptToSwap[l])>1)
+        {//Bingo, we were able to swap this one element
+          dbprint(p,dbprintWhitespace+"We can swap entry "+string(i)+" with its predecessors");
+          dbprint(p,dbprintWhitespace+"The elements look like the following after the swap:");
+          dbprint(p,attemptToSwap);
+          tempSwapsTempEntry = list();
+          for (j = size(factors); j >=1; j--)
+          {//creating a new entry for the resulting list, replacing the swap in factors
+            if (j==i)
+            {
+              for (k = size(attemptToSwap[l]); k >=1 ; k--)
+              {
+                tempSwapsTempEntry = insert(tempSwapsTempEntry, attemptToSwap[l][k]);
+              }
+              j=posHomogBegin;//Because of the change
+            }
+            else
+            {
+              tempSwapsTempEntry = insert(tempSwapsTempEntry,factors[j]);
+            }
+          }//creating a new entry for the resulting list, replacing the swap in factors
+          if (posRight <= size(tempSwapsTempEntry))
+          {
+            tempSwaps = insert(tempSwaps,list(list(posHomogBegin+1,posRight),tempSwapsTempEntry));
+          }
+          else
+          {
+            tempSwaps =
+              insert(tempSwaps,list(list(posHomogBegin+1,size(tempSwapsTempEntry)),
+                                         tempSwapsTempEntry));
+          }
+        }//Bingo, we were able to swap this one element
+      }
+    }//We have a group of homogeneous polynomials and an inhomogeneous one that we can try to swap.
+    else
+    {
+      if (i<posRight)
+      {
+        rightHomogFactorProduct =1;
+        if(!homogwithorderNthWeyl(factors[i]) && homogwithorderNthWeyl(factors[i+1]))
+        {//position i+1 is homogeneous, position i is not ==> trying to swap
+          j = i+1;
+          // print(j);
+          // print(size(factors));
+          // print(posRight);
+          // print("===");
+          while (homogwithorderNthWeyl(factors[j]))
+          {
+            rightHomogFactorProduct = rightHomogFactorProduct * factors[j];
+            posHomogEnd = j;
+            j = j+1;
+            if (j > posRight)
+            {break;}
+          }
+          attemptToSwap =
+            extractHomogeneousDivisorsLeftNthWeyl(factors[i]*rightHomogFactorProduct);
+          for (l =1; l<=size(attemptToSwap);l++)
+          {
+            if (size(attemptToSwap[l])>1)
+            {//Bingo, we were able to swap this one element
+              dbprint(p,dbprintWhitespace+"We can swap entry "+string(i)+" and its successors");
+              dbprint(p,dbprintWhitespace+"The elements look like the following after the swap:");
+              dbprint(p,attemptToSwap);
+              tempSwapsTempEntry = list();
+              for (j = size(factors); j >=1; j--)
+              {//creating a new entry for the resulting list, replacing the swap in factors
+                if (j==posHomogEnd)
+                {
+                  for (k = size(attemptToSwap[l]); k >=1 ; k--)
+                  {
+                    tempSwapsTempEntry = insert(tempSwapsTempEntry, attemptToSwap[l][k]);
+                  }
+                  j = i; //Because we changed entry i+1 and i
+                }
+                else
+                {
+                  tempSwapsTempEntry = insert(tempSwapsTempEntry,factors[j]);
+                }
+              }//creating a new entry for the resulting list, replacing the swap in factors
+              tempSwaps=insert(tempSwaps,
+                               list(list(posLeft,i+size(attemptToSwap[l])-1),tempSwapsTempEntry));
+            }//Bingo, we were able to swap this one element
+          }
+        }//position i+1 is homogeneous, position i is not ==> trying to swap
+      }
+    }
+  }//checking within the window posLeft <--> posRight, if there are - interchanges possible
+  //Now we will recursively call the function for all swapped entries.
+  dbprint(p,dbprintWhitespace+ "Our list of different factorizations is now:");
+  dbprint(p,tempSwaps);
+  for (i = 1; i<=size(tempSwaps);i++)
+  {//recursive call to all formerly attempted swaps.
+    dbprint(p, "Calling checkForHomogInterchangabilityNthWeyl recursively with values:");
+    dbprint(p, tempSwaps);
+    tempResultEntries=checkForHomogInhomogInterchangabilityNthWeyl(tempSwaps[i][2],
+                                                            tempSwaps[i][1][1],tempSwaps[i][1][2]);
+    result = result + tempResultEntries;
+  }//recursive call to all formerly attempted swaps.
+  result = delete_dublicates_noteval(result);
+  return(result);
+}//checkForHomogInhomogInterchangabilityNthWeyl
+
+static proc checkForHomogInhomogInterchangability(list factors, posLeft, posRight)
+"
+INPUT:  A list consisting of factors of a certain polynomial in the first Weyl
+        algebra, factors, and a position from the left and the right, where the last swap was done.
+OUTPUT: A list containing lists consisting of factors of a certain polynomial in the first Weyl
+        algebra.
+The purpose of this function is to check whether we can interchange certain inhomogeneous factors
+with homogeneous ones. If it is possible, this function returns a list of lists
+of possible interchanges.
+
+The idea came because of an example, where we need an extra swap in the end, otherwise we would
+not capture all factorizations. The example was
+h = x4d7+11x3d6+x2d7+x2d6+x3d4+29x2d5+xd6+8xd5+d6+5x2d3+14xd4+13d4+5xd2+d3+d;
+
+ASSUMPTIONS:
+
+- All factors are irreducible
+"
+{//checkForHomogInhomogInterchangability
+  int p = printlevel-voice+2;
+  string dbprintWhitespace = "";
+  int i; int j; int k;
+  for (i = 1; i<=voice;i++)
+  {dbprintWhitespace = dbprintWhitespace + " ";}
+  if (size(factors) <= 2 || posLeft >= posRight - 1)
+  {//easiest case: There is nothing to swap
+    return (list(factors));
+  }//easiest case: There is nothing to swap
+  list result = list(factors);
+  list tempResultEntries;
+  list tempSwaps;
+  list tempSwapsTempEntry;
+  list attemptToSwap;
+  intvec ivm11 = intvec(-1,1);
+  dbprint(p, dbprintWhitespace+"We try to swap elements in the following list:");
+  dbprint(p, factors);
+  for (i = posLeft; i < posRight; i++)
+  {//checking within the window posLeft <--> posRight, if there are interchanges possible
+    if (homogwithorder(factors[i],ivm11) && !homogwithorder(factors[i+1],ivm11))
+    {//position i is homogeneous, position i+1 is not ==> trying to swap
+      attemptToSwap = extractHomogeneousDivisorsRight(factors[i]*factors[i+1]);
+      if (size(attemptToSwap[1])>1)
+      {//Bingo, we were able to swap this one element
+        dbprint(p,dbprintWhitespace+"We can swap entry "+string(i)+" and "+ string(i+1));
+        dbprint(p,dbprintWhitespace+"The elements look like the following after the swap:");
+        dbprint(p,attemptToSwap);
+        tempSwapsTempEntry = list();
+        for (j = size(factors); j >=1; j--)
+        {//creating a new entry for the resulting list, replacing the swap in factors
+          if (j==i+1)
+          {
+            for (k = size(attemptToSwap[1]); k >=1 ; k--)
+            {
+              tempSwapsTempEntry = insert(tempSwapsTempEntry, attemptToSwap[1][k]);
+            }
+            j--; //Because we changed entry i+1 and i
+          }
+          else
+          {
+            tempSwapsTempEntry = insert(tempSwapsTempEntry,factors[j]);
+          }
+        }//creating a new entry for the resulting list, replacing the swap in factors
+        tempSwaps = insert(tempSwaps,list(list(i+1,posRight),tempSwapsTempEntry));
+      }//Bingo, we were able to swap this one element
+    }//position i is homogeneous, position i+1 is not ==> trying to swap
+    else
+    {
+      if(!homogwithorder(factors[i],ivm11) && homogwithorder(factors[i+1],ivm11))
+      {//position i+1 is homogeneous, position i is not ==> trying to swap
+        attemptToSwap = extractHomogeneousDivisorsLeft(factors[i]*factors[i+1]);
+        if (size(attemptToSwap[1])>1)
+        {//Bingo, we were able to swap this one element
+          dbprint(p,dbprintWhitespace+"We can swap entry "+string(i)+" and "+ string(i+1));
+          dbprint(p,dbprintWhitespace+"The elements look like the following after the swap:");
+          dbprint(p,attemptToSwap);
+          tempSwapsTempEntry = list();
+          for (j = size(factors); j >=1; j--)
+          {//creating a new entry for the resulting list, replacing the swap in factors
+            if (j==i+1)
+            {
+              for (k = size(attemptToSwap[1]); k >=1 ; k--)
+              {
+                tempSwapsTempEntry = insert(tempSwapsTempEntry, attemptToSwap[1][k]);
+              }
+              j--; //Because we changed entry i+1 and i
+            }
+            else
+            {
+              tempSwapsTempEntry = insert(tempSwapsTempEntry,factors[j]);
+            }
+          }//creating a new entry for the resulting list, replacing the swap in factors
+          tempSwaps = insert(tempSwaps,list(list(posLeft,i),tempSwapsTempEntry));
+        }//Bingo, we were able to swap this one element
+      }//position i+1 is homogeneous, position i is not ==> trying to swap
+    }
+  }//checking within the window posLeft <--> posRight, if there are interchanges possible
+  //Now we will recursively call the function for all swapped entries.
+  dbprint(p,dbprintWhitespace+ "Our list of different factorizations is now:");
+  dbprint(p,tempSwaps);
+  for (i = 1; i<=size(tempSwaps);i++)
+  {//recursive call to all formerly attempted swaps.
+    tempResultEntries=checkForHomogInhomogInterchangability(tempSwaps[i][2],
+                                                            tempSwaps[i][1][1],tempSwaps[i][1][2]);
+    result = result + tempResultEntries;
+  }//recursive call to all formerly attempted swaps.
+  result = delete_dublicates_noteval(result);
+  return(result);
+}//checkForHomogInhomogInterchangability
+
+static proc sfacwa(poly h)
+"INPUT: A polynomial h in the first Weyl algebra
+OUTPUT: A list of factorizations, where the factors might still be reducible.
+ASSUMPTIONS:
+- Our basering is the first Weyl algebra; the x is the first variable,
+  the differential operator the second.
+"
+{//proc sfacwa
+  int i; int j; int k;
+  int p = printlevel-voice+2;
+  string dbprintWhitespace = "";
+  number commonCoefficient = content(h);
+  for (i = 1; i<=voice;i++)
+  {dbprintWhitespace = dbprintWhitespace + " ";}
+  dbprint(p,dbprintWhitespace + " Extracting homogeneous left and right factors");
+  if(homogwithorder(h,intvec(-1,1)))
+  {//we are already dealing with a -1,1 homogeneous poly
+    dbprint(p,dbprintWhitespace+" Given polynomial is -1,1 homogeneous. Start homog.
+fac. and ret. its result");
+    return(homogfacFirstWeyl_all(h));
+  }//we are already dealing with a -1,1 homogeneous poly
+  list resulttemp = extractHomogeneousDivisors(h/commonCoefficient);
+  //resulttemp = resulttemp + list(list(h/commonCoefficient));
+  list inhomogeneousFactorsToFactorize;
+  int isAlreadyInInhomogList;
+  dbprint(p,dbprintWhitespace +" Done");
+  dbprint(p,dbprintWhitespace +" Making Set of inhomogeneous polynomials we have to factorize.");
+  for (i = 1; i<=size(resulttemp); i++)
+  {//Going through all different kinds of factorizations where we extracted homogeneous factors
+    for (j = 1;j<=size(resulttemp[i]);j++)
+    {//searching for the inhomogeneous factor
+      if (!homogwithorder(resulttemp[i][j],intvec(-1,1)))
+      {//We have found our candidate
+        isAlreadyInInhomogList = 0;
+        for (k = 1; k<=size(inhomogeneousFactorsToFactorize);k++)
+        {//Checking if our candidate is already in our tofactorize-list
+          if (inhomogeneousFactorsToFactorize[k]==resulttemp[i][j])
+          {//The candidate was already in the list
+            isAlreadyInInhomogList = 1;
+            break;
+          }//The candidate was already in the list
+        }//Checking if our candidate is already in our tofactorize-list
+        if (!isAlreadyInInhomogList)
+        {
+          inhomogeneousFactorsToFactorize=inhomogeneousFactorsToFactorize + list(resulttemp[i][j]);
+        }
+      }//We have found our candidate
+    }//searching for the inhomogeneous factor
+  }//Going through all different kinds of factorizations where we extracted homogeneous factors
+  dbprint(p,dbprintWhitespace +" Done");
+  dbprint(p,dbprintWhitespace + "The set is:");
+  dbprint(p,inhomogeneousFactorsToFactorize);
+  dbprint(p,dbprintWhitespace+ "Factorizing the different occuring inhomogeneous factors");
+  for (i = 1; i<= size(inhomogeneousFactorsToFactorize); i++)
+  {//Factorizing all kinds of inhomogeneous factors
+    inhomogeneousFactorsToFactorize[i] = sfacwa2(inhomogeneousFactorsToFactorize[i]);
+    for (j = 1; j<=size(inhomogeneousFactorsToFactorize[i]);j++)
+    {//Deleting the leading coefficient since we don't need him
+      if (deg(inhomogeneousFactorsToFactorize[i][j][1],intvec(1,1))==0)
+      {
+        inhomogeneousFactorsToFactorize[i][j] = delete(inhomogeneousFactorsToFactorize[i][j],1);
+      }
+    }//Deleting the leading coefficient since we don't need him
+  }//Factorizing all kinds of inhomogeneous factors
+  dbprint(p,dbprintWhitespace +" Done");
+  dbprint(p,dbprintWhitespace +" Putting the factorizations in the lists");
+  list result;
+  int posInhomogPoly;
+  int posInhomogFac;
+  for (i = 1; i<=size(resulttemp); i++)
+  {//going through all by now calculated factorizations
+    for (j = 1;j<=size(resulttemp[i]); j++)
+    {//Finding the inhomogeneous factor
+      if (!homogwithorder(resulttemp[i][j],intvec(-1,1)))
+      {//Found it
+        posInhomogPoly = j;
+        break;
+      }//Found it
+    }//Finding the inhomogeneous factor
+    for (k = 1; k<=size(inhomogeneousFactorsToFactorize);k++)
+    {//Finding the matching inhomogeneous factorization we already determined
+      if(product(inhomogeneousFactorsToFactorize[k][1]) == resulttemp[i][j])
+      {//found it
+        posInhomogFac = k;
+        break;
+      }//Found it
+    }//Finding the matching inhomogeneous factorization we already determined
+    for (j = 1; j <= size(inhomogeneousFactorsToFactorize[posInhomogFac]); j++)
+    {
+      result = insert(result, resulttemp[i]);
+      result[1] = delete(result[1],posInhomogPoly);
+      for (k =size(inhomogeneousFactorsToFactorize[posInhomogFac][j]);k>=1; k--)
+      {//Inserting factorizations
+        result[1] = insert(result[1],inhomogeneousFactorsToFactorize[posInhomogFac][j][k],
+                           posInhomogPoly-1);
+      }//Inserting factorizations
+      dbprint(p,dbprintWhitespace + "Added a factorization to result, namely:");
+      dbprint(p, result[1]);
+    }
+  }//going through all by now calculated factorizations
+  dbprint(p,dbprintWhitespace +" Done");
+  result = delete_dublicates_noteval(result);
+  for (i = 1; i<=size(result);i++)
+  {//Putting the content everywhere
+    result[i] = insert(result[i],commonCoefficient);
+  }//Putting the content everywhere
+  return(result);
+}//proc sfacwa
+
+static proc sfacwaNthWeyl(poly h)
+"INPUT: A polynomial h in the Nth Weyl algebra
+OUTPUT: A list of factorizations, where the factors might still be reducible.
+ASSUMPTIONS:
+- Our basering is the Nth Weyl algebra; the xs are the first n variables,
+  the differential operators are the last n.
+"
+{//proc sfacwaNthWeyl
+  int i; int j; int k;
+  int p = printlevel-voice+2;
+  string dbprintWhitespace = "";
+  number commonCoefficient = content(h);
+  for (i = 1; i<=voice;i++)
+  {dbprintWhitespace = dbprintWhitespace + " ";}
+  dbprint(p,dbprintWhitespace + " Extracting homogeneous left and right factors");
+  if(homogwithorderNthWeyl(h))
+  {//we are already dealing with a -1,1 homogeneous poly
+    dbprint(p,dbprintWhitespace+" Given polynomial is -1,1 homogeneous. Start homog.
+fac. and ret. its result");
+    return(homogfacNthWeyl_all(h));
+  }//we are already dealing with a -1,1 homogeneous poly
+  list resulttemp = extractHomogeneousDivisorsNthWeyl(h/commonCoefficient);
+  //resulttemp = resulttemp + list(list(h/commonCoefficient));
+  list inhomogeneousFactorsToFactorize;
+  int isAlreadyInInhomogList;
+  dbprint(p,dbprintWhitespace +" Done");
+  dbprint(p,dbprintWhitespace +" Making Set of inhomogeneous polynomials we have to factorize.");
+  for (i = 1; i<=size(resulttemp); i++)
+  {//Going through all different kinds of factorizations where we extracted homogeneous factors
+    for (j = 1;j<=size(resulttemp[i]);j++)
+    {//searching for the inhomogeneous factor
+      if (!homogwithorderNthWeyl(resulttemp[i][j]))
+      {//We have found our candidate
+        isAlreadyInInhomogList = 0;
+        for (k = 1; k<=size(inhomogeneousFactorsToFactorize);k++)
+        {//Checking if our candidate is already in our tofactorize-list
+          if (inhomogeneousFactorsToFactorize[k]==resulttemp[i][j])
+          {//The candidate was already in the list
+            isAlreadyInInhomogList = 1;
+            break;
+          }//The candidate was already in the list
+        }//Checking if our candidate is already in our tofactorize-list
+        if (!isAlreadyInInhomogList)
+        {
+          inhomogeneousFactorsToFactorize=inhomogeneousFactorsToFactorize + list(resulttemp[i][j]);
+        }
+      }//We have found our candidate
+    }//searching for the inhomogeneous factor
+  }//Going through all different kinds of factorizations where we extracted homogeneous factors
+  dbprint(p,dbprintWhitespace +" Done");
+  dbprint(p,dbprintWhitespace + "The set is:");
+  dbprint(p,inhomogeneousFactorsToFactorize);
+  dbprint(p,dbprintWhitespace+ "Factorizing the different occuring inhomogeneous factors");
+  for (i = 1; i<= size(inhomogeneousFactorsToFactorize); i++)
+  {//Factorizing all kinds of inhomogeneous factors
+    inhomogeneousFactorsToFactorize[i] = sfacwa2NthWeyl(inhomogeneousFactorsToFactorize[i]);
+    for (j = 1; j<=size(inhomogeneousFactorsToFactorize[i]);j++)
+    {//Deleting the leading coefficient since we don't need him
+      if (deg(inhomogeneousFactorsToFactorize[i][j][1],intvec(1,1))==0)
+      {
+        inhomogeneousFactorsToFactorize[i][j] = delete(inhomogeneousFactorsToFactorize[i][j],1);
+      }
+    }//Deleting the leading coefficient since we don't need him
+  }//Factorizing all kinds of inhomogeneous factors
+  dbprint(p,dbprintWhitespace +" Done");
+  dbprint(p,dbprintWhitespace +" Putting the factorizations in the lists");
+  list result;
+  int posInhomogPoly;
+  int posInhomogFac;
+  for (i = 1; i<=size(resulttemp); i++)
+  {//going through all by now calculated factorizations
+    for (j = 1;j<=size(resulttemp[i]); j++)
+    {//Finding the inhomogeneous factor
+      if (!homogwithorderNthWeyl(resulttemp[i][j]))
+      {//Found it
+        posInhomogPoly = j;
+        break;
+      }//Found it
+    }//Finding the inhomogeneous factor
+    for (k = 1; k<=size(inhomogeneousFactorsToFactorize);k++)
+    {//Finding the matching inhomogeneous factorization we already determined
+      if(product(inhomogeneousFactorsToFactorize[k][1]) == resulttemp[i][j])
+      {//found it
+        posInhomogFac = k;
+        break;
+      }//Found it
+    }//Finding the matching inhomogeneous factorization we already determined
+    for (j = 1; j <= size(inhomogeneousFactorsToFactorize[posInhomogFac]); j++)
+    {
+      result = insert(result, resulttemp[i]);
+      result[1] = delete(result[1],posInhomogPoly);
+      for (k =size(inhomogeneousFactorsToFactorize[posInhomogFac][j]);k>=1; k--)
+      {//Inserting factorizations
+        result[1] = insert(result[1],inhomogeneousFactorsToFactorize[posInhomogFac][j][k],
+                           posInhomogPoly-1);
+      }//Inserting factorizations
+      dbprint(p,dbprintWhitespace + "Added a factorization to result, namely:");
+      dbprint(p, result[1]);
+    }
+  }//going through all by now calculated factorizations
+  dbprint(p,dbprintWhitespace +" Done");
+  result = delete_dublicates_noteval(result);
+  for (i = 1; i<=size(result);i++)
+  {//Putting the content everywhere
+    result[i] = insert(result[i],commonCoefficient);
+  }//Putting the content everywhere
+  return(result);
+}//proc sfacwaNthWeyl
+
+static proc sfacwa2(poly h)
+"
+Subprocedure of sfacwa
+Assumptions:
+- h is not in K[x] or in K[d], or even in K. These cases are caught by the input
+- The coefficients are integer values and the gcd of the coefficients is 1
+"
+{//proc sfacwa2
+  int p=printlevel-voice+2; // for dbprint
+  int i;
+  string dbprintWhitespace = "";
+  for (i = 1; i<=voice;i++)
+  {dbprintWhitespace = dbprintWhitespace + " ";}
+  intvec ivm11 = intvec(-1,1);
+  intvec iv11 = intvec(1,1);
+  intvec iv10 = intvec(1,0);
+  intvec iv01 = intvec(0,1);
+  intvec iv1m1 = intvec(1,-1);
+  poly p_max; poly p_min; poly q_max; poly q_min;
+  map invo = basering,-var(1),var(2);
+  list calculatedRightFactors;
+  if(homogwithorder(h,ivm11))
+  {//Unnecessary how we are using it, but if one wants to use it on its own, we are stating it here
+    dbprint(p,dbprintWhitespace+" Given polynomial is -1,1 homogeneous.
+Start homog. fac. and ret. its result");
+    return(homogfacFirstWeyl_all(h));
+  }//Unnecessary how we are using it, but if one wants to use it on its own, we are stating it here
+  list result = list();
+  int j; int k; int l;
+  dbprint(p,dbprintWhitespace+" Computing the degree-limits of the factorization");
+  //end finding the limits
+  dbprint(p,dbprintWhitespace+" Computing the maximal and the minimal
+homogeneous part of the given polynomial");
+  list M = computeCombinationsMinMaxHomog(h);
+  dbprint(p,dbprintWhitespace+" Done.");
+  dbprint(p,dbprintWhitespace+" Filtering invalid combinations in M.");
+  for (i = 1 ; i<= size(M); i++)
+  {//filter valid combinations
+    if (product(M[i]) == h)
+    {//We have one factorization
+      result = result + divides(M[i][1],h,invo,1);
+      dbprint(p,dbprintWhitespace+"Result list updated:");
+      dbprint(p,dbprintWhitespace+string(result));
+      M = delete(M,i);
+      continue;
+    }//We have one factorization
+  }//filter valid combinations
+  dbprint(p,dbprintWhitespace+"Done.");
+  dbprint(p,dbprintWhitespace+"The size of M is "+string(size(M)));
+  for (i = 1; i<=size(M); i++)
+  {//Iterate over all first combinations (p_max + p_min)(q_max + q_min)
+    dbprint(p,dbprintWhitespace+" Combination No. "+string(i)+" in M:" );
+    p_max = jet(M[i][1],deg(M[i][1],ivm11),ivm11)-jet(M[i][1],deg(M[i][1],ivm11)-1,ivm11);
+    p_min = jet(M[i][1],deg(M[i][1],iv1m1),iv1m1)-jet(M[i][1],deg(M[i][1],iv1m1)-1,iv1m1);
+    q_max = jet(M[i][2],deg(M[i][2],ivm11),ivm11)-jet(M[i][2],deg(M[i][2],ivm11)-1,ivm11);
+    q_min = jet(M[i][2],deg(M[i][2],iv1m1),iv1m1)-jet(M[i][2],deg(M[i][2],iv1m1)-1,iv1m1);
+    dbprint(p,dbprintWhitespace+" pmax = "+string(p_max));
+    dbprint(p,dbprintWhitespace+" pmin = "+string(p_min));
+    dbprint(p,dbprintWhitespace+" qmax = "+string(q_max));
+    dbprint(p,dbprintWhitespace+" qmin = "+string(q_min));
+    //Check, whether p_max + p_min or q_max and q_min are already left or right divisors.
+    if (divides(p_min + p_max,h,invo))
+    {
+      dbprint(p,dbprintWhitespace+" Got one result.");
+      result = result + divides(p_min + p_max,h,invo,1);
+    }
+    else
+    {
+      if (divides(q_min + q_max,h,invo))
+      {
+        dbprint(p,dbprintWhitespace+" Got one result.");
+        result = result + divides(q_min + q_max, h , invo, 1);
+      }
+    }
+    //Now the check, if deg(p_max) = deg(p_min)+1 (and the same with q_max and q_min)
+
+    if (deg(p_max, ivm11) == deg(p_min, ivm11) +1 or  deg(q_max, ivm11) == deg(q_min, ivm11) +1 )
+    {//Therefore, p_max + p_min must be a left factor or we can dismiss the combination
+      dbprint(p,dbprintWhitespace+" There are no homogeneous parts we can put between
+pmax and pmin resp. qmax and qmin.");
+      //TODO: Prove, that then also a valid right factor is not possible
+      M = delete(M,i);
+      continue;
+    }//Therefore, p_max + p_min must be a left factor or we can dismiss the combination
+
+    //Done with the Check
+
+    //If we come here, there are still homogeneous parts to be added to p_max + p_min
+    //AND to q_max and q_min in
+    //order to obtain a real factor
+    //We use the procedure determineRestOfHomogParts to find our q.
+    dbprint(p,dbprintWhitespace+" Solving for the other homogeneous parts in q");
+    calculatedRightFactors = determineRestOfHomogParts(p_max,p_min,q_max,q_min,h);
+    dbprint(p,dbprintWhitespace+" Done with it. Found "+string(size(calculatedRightFactors))
+            +" solutions.");
+    for (j = 1; j<=size(calculatedRightFactors);j++)
+    {//Check out whether we really have right factors of h in calculatedRightFactors
+      if (divides(calculatedRightFactors[j],h,invo))
+      {
+        result = result + divides(calculatedRightFactors[j],h,invo,1);
+      }
+      else
+      {
+        dbprint(p,"Solution for max and min homog found, but not a divisor of h");
+        //TODO: Proof, why this can happen.
+      }
+    }//Check out whether we really have right factors of h in calculatedRightFactors
+  }//Iterate over all first combinations (p_max + p_min)(q_max + q_min)
+
+
+  result = delete_dublicates_noteval(result);
+  //print(M);
+  if (size(result) == 0)
+  {//no factorization found
+    result = list(list(h));
+  }//no factorization found
+  return(result);
+}//proc sfacwa2
+
+static proc sfacwa2NthWeyl(poly h)
+"
+Subprocedure of sfacwa
+Assumptions:
+- h is not part of a commutative subalgebra of the nth Weyl algebra
+- The coefficients are integer values and the gcd of the coefficients is 1
+"
+{//proc sfacwa2NthWeyl
+  int p=printlevel-voice+2; // for dbprint
+  int i;
+  string dbprintWhitespace = "";
+  for (i = 1; i<=voice;i++)
+  {dbprintWhitespace = dbprintWhitespace + " ";}
+  poly p_max; poly p_min; poly q_max; poly q_min;
+  ideal invoIdeal;
+  intvec maxDegrees;
+  intvec tempIntVec1;
+  for (i = 1; i <= nvars(basering); i++)
+  {//filling maxDegrees
+    tempIntVec1 = 0:nvars(basering);
+    tempIntVec1[i] = 1;
+    maxDegrees[i] = deg(h,tempIntVec1);
+  }//filling maxDegrees
+  for (i = 1; i <= nvars(basering); i++)
+  {//Filling the mapping rules for the involution map
+    if (i <= nvars(basering) div 2)
+    {invoIdeal[i] = -var(i);}
+    else
+    {invoIdeal[i] = var(i);}
+  }//Filling the mapping rules for the involution map
+  map invo = basering,invoIdeal;
+  list calculatedRightFactors;
+  if(homogwithorderNthWeyl(h))
+  {//Unnecessary how we are using it, but if one wants to use it on its own, we are stating it here
+    dbprint(p,dbprintWhitespace+" Given polynomial is -1,1 homogeneous.
+Start homog. fac. and ret. its result");
+    return(homogfacNthWeyl_all(h));
+  }//Unnecessary how we are using it, but if one wants to use it on its own, we are stating it here
+  list result = list();
+  int j; int k; int l;
+  list tempBetweenDegreesP;
+  list tempBetweenDegreesQ;
+  dbprint(p,dbprintWhitespace+" Computing the degree-limits of the factorization");
+  //end finding the limits
+  dbprint(p,dbprintWhitespace+" Computing the maximal and the minimal
+homogeneous part of the given polynomial");
+  list M = computeCombinationsMinMaxHomogNthWeyl(h);
+  dbprint(p,dbprintWhitespace+" Done.");
+  dbprint(p,dbprintWhitespace+" Filtering invalid combinations in M.");
+  for (i = 1 ; i<= size(M); i++)
+  {//filter valid combinations
+    if (product(M[i]) == h)
+    {//We have one factorization
+      result = result + divides(M[i][1],h,invo,1);
+      dbprint(p,dbprintWhitespace+"Result list updated:");
+      dbprint(p,dbprintWhitespace+string(result));
+      M = delete(M,i);
+      continue;
+    }//We have one factorization
+  }//filter valid combinations
+  dbprint(p,dbprintWhitespace+"Done.");
+  dbprint(p,dbprintWhitespace+"The size of M is "+string(size(M)));
+  for (i = 1; i<=size(M); i++)
+  {//Iterate over all first combinations (p_max + p_min)(q_max + q_min)
+    dbprint(p,dbprintWhitespace+" Combination No. "+string(i)+" in M:" );
+    p_max = homogDistributionNthWeyl(M[i][1])[2][2];
+    p_min = homogDistributionNthWeyl(M[i][1])[1][2];
+    q_max = homogDistributionNthWeyl(M[i][2])[2][2];
+    q_min = homogDistributionNthWeyl(M[i][2])[1][2];
+    dbprint(p,dbprintWhitespace+" pmax = "+string(p_max));
+    dbprint(p,dbprintWhitespace+" pmin = "+string(p_min));
+    dbprint(p,dbprintWhitespace+" qmax = "+string(q_max));
+    dbprint(p,dbprintWhitespace+" qmin = "+string(q_min));
+    //Check, whether p_max + p_min or q_max and q_min are already left or right divisors.
+    if (divides(p_min + p_max,h,invo))
+    {
+      dbprint(p,dbprintWhitespace+" Got one result.");
+      result = result + divides(p_min + p_max,h,invo,1);
+    }
+    else
+    {
+      if (divides(q_min + q_max,h,invo))
+      {
+        dbprint(p,dbprintWhitespace+" Got one result.");
+        result = result + divides(q_min + q_max, h , invo, 1);
+      }
+    }
+    //Now the check, if deg(p_max) = deg(p_min)+1 (and the same with q_max and q_min)
+
+    tempBetweenDegreesP = possibleHomogPartsInBetween(degreeOfNthWeylPoly(p_max),
+                                                      degreeOfNthWeylPoly(p_min), maxDegrees);
+    tempBetweenDegreesQ = possibleHomogPartsInBetween(degreeOfNthWeylPoly(q_max),
+                                                      degreeOfNthWeylPoly(q_min), maxDegrees);
+    if (size(tempBetweenDegreesQ)==2 or  size(tempBetweenDegreesP)==2 )
+    {//Therefore, p_max + p_min must be a left factor or we can dismiss the combination
+      dbprint(p,dbprintWhitespace+" There are no homogeneous parts we can put between
+pmax and pmin resp. qmax and qmin.");
+      //TODO: Prove, that then also a valid right factor is not possible
+      M = delete(M,i);
+      continue;
+    }//Therefore, p_max + p_min must be a left factor or we can dismiss the combination
+
+    //Done with the Check
+
+    //If we come here, there are still homogeneous parts to be added to p_max + p_min
+    //AND to q_max and q_min in
+    //order to obtain a real factor
+    //We use the procedure determineRestOfHomogParts to find our q.
+    dbprint(p,dbprintWhitespace+" Solving for the other homogeneous parts in q");
+    calculatedRightFactors = determineRestOfHomogPartsNthWeyl(p_max,p_min,q_max,q_min,h);
+    dbprint(p,dbprintWhitespace+" Done with it. Found "+string(size(calculatedRightFactors))
+            +" solutions.");
+    for (j = 1; j<=size(calculatedRightFactors);j++)
+    {//Check out whether we really have right factors of h in calculatedRightFactors
+      if (divides(calculatedRightFactors[j],h,invo))
+      {
+        result = result + divides(calculatedRightFactors[j],h,invo,1);
+      }
+      else
+      {
+        dbprint(p,"Solution for max and min homog found, but not a divisor of h");
+        //TODO: Proof, why this can happen.
+      }
+    }//Check out whether we really have right factors of h in calculatedRightFactors
+  }//Iterate over all first combinations (p_max + p_min)(q_max + q_min)
+
+  result = delete_dublicates_noteval(result);
+  //print(M);
+  if (size(result) == 0)
+  {//no factorization found
+    result = list(list(h));
+  }//no factorization found
+  return(result);
+}//proc sfacwa2NthWeyl
+
+static proc determineRestOfHomogParts(poly pmax, poly pmin, poly qmax, poly qmin, poly h)
+"INPUT: Polynomials p_max, p_min, q_max, q_min and h. The maximum homogeneous part h_max of h is
+ given by p_max*pmin, the minimum homogeneous part h_min of h is given by p_min*q_min.
+OUTPUT: A list of right factors q of h that have q_max and q_min as their maximum respectively
+ minimum homogeneous part. Empty list, if those elements are not existent
+ASSUMPTIONS:
+ - deg(p_max,intvec(-1,1))>deg(p_min,intvec(-1,1)) +1
+ - deg(q_max,intvec(-1,1))>deg(q_min,intvec(-1,1)) +1
+ - p_max*q_max = h_max
+ - p_min*q_min = h_min
+ - The basering is the first Weyl algebra
+"
+{//proc determineRestOfHomogParts
+  int p=printlevel-voice+2; // for dbprint
+  string dbprintWhitespace = "";
+  int i;
+  for (i = 1; i<=voice;i++)
+  {dbprintWhitespace = dbprintWhitespace + " ";}
+  int kappa = Min(intvec(deg(h,intvec(1,0)), deg(h,intvec(0,1))));
+  def R = basering;
+  int n1 = deg(pmax,intvec(-1,1));
+  int nk = -deg(pmin,intvec(1,-1));
+  int m1 = deg(qmax,intvec(-1,1));
+  int ml = -deg(qmin,intvec(1,-1));
+  int j; int k;
+  ideal mons;
+
+  dbprint(p,dbprintWhitespace+" Extracting zero homog. parts of pmax, qmax, pmin, qmin and h.");
+  //Extracting the zero homogeneous part of the given polynomials
+  ideal pandqZero = pmax,pmin,qmax,qmin;
+  if (n1 > 0){pandqZero[1] = lift(var(2)^n1,pmax)[1,1];}
+  else{if (n1 < 0){pandqZero[1] = lift(var(1)^(-n1),pmax)[1,1];}
+    else{pandqZero[1] = pmax;}}
+  if (nk > 0){pandqZero[2] = lift(var(2)^nk,pmin)[1,1];}
+  else{if (nk < 0){pandqZero[2] = lift(var(1)^(-nk),pmin)[1,1];}
+    else{pandqZero[2] = pmin;}}
+  if (m1 > 0){pandqZero[3] = lift(var(2)^m1,qmax)[1,1];}
+  else{if (m1 < 0){pandqZero[3] = lift(var(1)^(-m1),qmax)[1,1];}
+    else{pandqZero[3] = qmax;}}
+  if (ml > 0){pandqZero[4] = lift(var(2)^ml,qmin)[1,1];}
+  else{if (ml < 0){pandqZero[4] = lift(var(1)^(-ml),qmin)[1,1];}
+    else{pandqZero[4] = qmin;}}
+  list hZeroinR = homogDistribution(h);
+  for (i = 1; i<=size(hZeroinR);i++)
+  {//Extracting the zero homogeneous parts of the homogeneous summands of h
+    if (hZeroinR[i][1] > 0){hZeroinR[i][2] = lift(var(2)^hZeroinR[i][1],hZeroinR[i][2])[1,1];}
+    if (hZeroinR[i][1] < 0){hZeroinR[i][2] = lift(var(1)^(-hZeroinR[i][1]),hZeroinR[i][2])[1,1];}
+  }//Extracting the zero homogeneous parts of the homogeneous summands of h
+  dbprint(p,dbprintWhitespace+" Done!");
+  //Moving everything into the ring K[theta]
+  dbprint(p,dbprintWhitespace+" Moving everything into the ring K[theta]");
+  ring KTheta = 0,(x,d,theta),dp;
+  map thetamap = R, x, d;
+  poly entry;
+  ideal mons;
+  ideal pandqZero;
+  list hZeroinKTheta;
+  setring(R);
+
+  //Starting with p and q
+  for (k=1; k<=4; k++)
+  {//Transforming pmax(0),qmax(0),pmin(0),qmin(0) in theta-polys
+    mons = ideal();
+    for(i = 1; i<=size(pandqZero[k]);i++)
+    {//Putting the monomials in a list
+      mons[size(mons)+1] = pandqZero[k][i];
+    }//Putting the monomials in a list
+    setring(KTheta);
+    mons = thetamap(mons);
+    for (i = 1; i<=size(mons);i++)
+    {//transforming the monomials as monomials in theta
+      entry = leadcoef(mons[i]);
+      for (j = 0; j<leadexp(mons[i])[2];j++)
+      {
+        entry = entry * (theta-j);
+      }
+      mons[i] = entry;
+    }//transforming the monomials as monomials in theta
+    pandqZero[size(pandqZero)+1] = sum(mons);
+    setring(R);
+  }//Transforming pmax(0),qmax(0),pmin(0),qmin(0) in theta-polys
+
+  //Now hZero
+  for (k = size(hZeroinR); k>= 1;k--)
+  {//Transforming the different homogeneous parts of h into polys in K[theta]
+    mons = ideal();
+    for(i = 1; i<=size(hZeroinR[k][2]);i++)
+    {//Putting the monomials in a list
+      mons[size(mons)+1] = hZeroinR[k][2][i];
+    }//Putting the monomials in a list
+    setring(KTheta);
+    mons = thetamap(mons);
+    for (i = 1; i<=size(mons);i++)
+    {//transforming the monomials as monomials in theta
+      entry = leadcoef(mons[i]);
+      for (j = 0; j<leadexp(mons[i])[2];j++)
+      {
+        entry = entry * (theta-j);
+      }
+      mons[i] = entry;
+    }//transforming the monomials as monomials in theta
+    hZeroinKTheta = hZeroinKTheta + list(sum(mons));
+    setring(R);
+  }//Transforming the different homogeneous parts of h into polys in K[theta]
+  dbprint(p,dbprintWhitespace+" Done!");
+  //Making the solutionRing
+  ring solutionRing = 0,(theta,q(0..(kappa+1)*(m1-ml-1)-1)),lp;
+  dbprint(p,dbprintWhitespace+" Our solution ring is given by "+ string(solutionRing));
+  //mapping the different ps and qs and HZeros
+  dbprint(p,dbprintWhitespace+" Setting up our solution system.");
+  list ps;
+  ideal pandqZero = imap(KTheta,pandqZero);
+  ps[1] = list(n1,pandqZero[1]);
+  ps[n1-nk+1] = list(nk,pandqZero[2]);
+  for (i = 2; i<=n1-nk; i++)
+  {
+    ps[i] = list(n1-i+1,0);
+  }
+  list qs;
+  qs[1] = list(m1,pandqZero[3]);
+  qs[m1-ml+1] = list(ml,pandqZero[4]);
+  for (i = 2; i<=m1-ml; i++)
+  {
+    qs[i] = list(m1-i+1,0);
+    for (j = 0; j<=kappa; j++)
+    {
+      qs[i][2] = qs[i][2] + q((i-2)*(kappa+1)+j)*theta^j;
+    }
+  }
+  list hZero = imap(KTheta,hZeroinKTheta);
+  for (i = 1; i<=size(hZero); i++)
+  {
+    hZero[i] = list(n1+m1-i+1,hZero[i]);
+  }
+
+  //writing and solving the system
+  list lhs;
+  lhs[1] = list(ps[1][2],1);
+  list rhs;
+  rhs[n1-nk+1] = list(ps[size(ps)][2],1);
+  for (i = 2; i<= n1-nk+1;i++)
+  {
+    lhs[i] = list(hZero[i][2],subst(qs[1][2],theta,theta+n1-i+1)*gammaForTheta(ps[i][1],qs[1][1]));
+    rhs[n1-nk-i+2] = list(hZero[size(hZero)-i+1][2],subst(qs[m1-ml+1][2],theta,
+                          theta+nk+i-1)*gammaForTheta(ps[n1-nk-i+2][1],qs[m1-ml+1][1]));
+    for (j = 1; j<i; j++)
+    {
+      for (k = 1; k<=size(qs);k++)
+      {
+        if(ps[j][1]+qs[k][1] == hZero[i][1])
+        {
+          lhs[i][1] = lhs[i][1]*lhs[j][2];
+          lhs[i][2] = lhs[i][2]*lhs[j][2];
+          lhs[i][1] = lhs[i][1]-lhs[j][1]*subst(qs[k][2],theta, theta + n1- j +1)
+            *gammaForTheta(ps[j][1],qs[k][1]);
+        }
+        if(ps[n1-nk+2-j][1] + qs[m1-ml+2-k][1] ==hZero[size(hZero)-i+1][1])
+        {
+          rhs[n1-nk-i+2][1] = rhs[n1-nk-i+2][1]*rhs[n1-nk+2-j][2];
+          rhs[n1-nk-i+2][2] = rhs[n1-nk-i+2][2]*rhs[n1-nk+2-j][2];
+          rhs[n1-nk-i+2][1] = rhs[n1-nk-i+2][1]-rhs[n1-nk+2-j][1]*subst(qs[m1-ml+2-k][2],theta,
+                             theta + nk -j+1)*gammaForTheta(ps[n1-nk+2-j][1],qs[m1-ml+2-k][1]);
+        }
+      }
+    }
+  }
+  list eqs;
+  poly tempgcd;
+  poly templhscoeff;
+  poly temprhscoeff;
+  for (i = 2; i<=n1-nk;i++)
+  {
+    if (gcd(rhs[i][2],lhs[i][2]) == 1)
+    {
+      eqs = eqs + list(lhs[i][1]*rhs[i][2] -rhs[i][1]*lhs[i][2]);
+    }
+    else
+    {
+      tempgcd = gcd(rhs[i][2],lhs[i][2]);
+      templhscoeff = quotient(rhs[i][2],tempgcd)[1];
+      temprhscoeff = quotient(lhs[i][2],tempgcd)[1];
+      eqs = eqs + list(lhs[i][1]*templhscoeff -rhs[i][1]*temprhscoeff);
+    }
+  }
+  matrix tempCoefMatrix;
+  ideal solutionSystemforqs;
+  for (i= 1; i<=size(eqs); i++)
+  {
+    tempCoefMatrix = coef(eqs[i],theta);
+    solutionSystemforqs = solutionSystemforqs + ideal(submat(tempCoefMatrix,intvec(2),
+                                                             intvec(1..ncols(tempCoefMatrix))));
+  }
+  dbprint(p,dbprintWhitespace+" Solution system for the coefficients of q is given by:");
+  dbprint(p,solutionSystemforqs);
+  option(redSB);
+  dbprint(p,dbprintWhitespace+" Calculating reduced Groebner Basis of that system.");
+  solutionSystemforqs = slimgb(solutionSystemforqs);
+  dbprint(p,dbprintWhitespace+" Done!, the solution for the system is:");
+  dbprint(p,dbprintWhitespace+string(solutionSystemforqs));
+  if(vdim(slimgb(solutionSystemforqs+theta))==0)
+  {//No solution in this case. Return the empty list
+    dbprint(p,dbprintWhitespace+"The Groebner Basis of the solution system was <1>.");
+    setring(R);
+    return(list());
+  }//No solution in this case. Return the empty list
+  if(vdim(slimgb(solutionSystemforqs+theta))==-1)
+  {//My conjecture is that this would never happen
+    //ERROR("This is an counterexample to your conjecture. We have infinitely many solutions");
+    //TODO: See, what we would do here
+    dbprint(p,dbprintWhitespace+"There are infinitely many solution to this system.
+We will return the empty list.");
+    setring(R);
+    return(list());
+  }//My conjecture is that this would never happen
+  else
+  {//We have finitely many solutions
+    if(vdim(slimgb(solutionSystemforqs+theta))==1)
+    {//exactly one solution
+      for (i = 2; i<= size(qs)-1;i++)
+      {
+        qs[i][2] = NF(qs[i][2],solutionSystemforqs);
+      }
+      setring(R);
+      map backFromSolutionRing = solutionRing,var(1)*var(2);
+      list qs = backFromSolutionRing(qs);
+      list result = list(0);
+      for (i = 1; i<=size(qs); i++)
+      {
+        if (qs[i][1]>0){qs[i][2] = qs[i][2]*var(2)^qs[i][1];}
+        if (qs[i][1]<0){qs[i][2] = qs[i][2]*var(1)^(-qs[i][1]);}
+        result[1] = result[1] + qs[i][2];
+      }
+      dbprint(p,dbprintWhitespace+"Found one unique solution. Returning the result.");
+      return(result);
+    }//exactly one solution
+    else
+    {//We have more than one solution, but finitely many
+      def ringForSolveLib = solve(solutionSystemforqs+theta, "nodisplay");
+      setring ringForSolveLib;
+      list valuesForQs = list();
+      list tempValues;
+      int validSol;
+      for (i = 1; i<=size(SOL); i++)
+      {//filtering integer solutions
+        validSol = 1;
+        for (j =1; j<=size(SOL[i]); j++)
+        {//Checking every entry if it is integer or not
+          if (SOL[i][j] - int(SOL[i][j])!=0)
+          {//No integer solution
+            validSol = 0;
+            break;
+          }//No integer solution
+        }//Checking every entry if it is integer or not
+        if (validSol)
+        {
+          tempValues = list();
+          for (j = 1; j<=size(SOL[i]); j++)
+          {//filling the valuesforQs
+            tempValues[j]= int(SOL[i][j]);
+          }//filling the valuesforQs
+          valuesForQs = valuesForQs + list(tempValues);
+        }
+      }//filtering integer solutions
+      print(valuesForQs);
+      setring solutionRing;
+      list differentQs = list();
+      ideal tempSolutionForQ;
+      for (i = 1; i<=size(valuesForQs); i++)
+      {
+        differentQs[i] = qs;
+        tempSolutionForQ = ideal();
+        for (j=2; j<=nvars(solutionRing);j++)
+        {//filling solution ideal
+          tempSolutionForQ[j-1] = var(j) - valuesForQs[i][j];
+        }//filling solution ideal
+        for (j=2; j<size(differentQs[i]); j++)
+        {
+          differentQs[i][j][2] = NF(differentQs[i][j][2],slimgb(tempSolutionForQ));
+        }
+      }
+      setring(R);
+      map backFromSolutionRing = solutionRing,var(1)*var(2);
+      list differentQs = backFromSolutionRing(differentQs);
+      list result = list();
+      for (k = 1; k<=size(differentQs); k++)
+      {
+        result[k] = 0;
+        for (i = 1; i<=size(differentQs[k]); i++)
+        {
+          if (differentQs[k][i][1]>0){differentQs[k][i][2] =
+              differentQs[k][i][2]*var(2)^differentQs[k][i][1];}
+          if (differentQs[k][i][1]<0){differentQs[k][i][2] =
+              differentQs[k][i][2]*var(1)^(-differentQs[k][i][1]);}
+          result[k] = result[k] + differentQs[k][i][2];
+        }
+      }
+      dbprint(p,dbprintWhitespace+"Found multiple solutions. Returning the result.");
+      return(result);
+    }//We have more than one solution, but finitely many
+  }//We have finitely many solutions
+}//proc determineRestOfHomogParts
+
+static proc determineRestOfHomogPartsNthWeyl(poly pmax, poly pmin, poly qmax, poly qmin, poly h)
+"INPUT: Polynomials p_max, p_min, q_max, q_min and h. The maximum homogeneous part h_max of h is
+ given by p_max*pmin, the minimum homogeneous part h_min of h is given by p_min*q_min.
+OUTPUT: A list of right factors q of h that have q_max and q_min as their maximum respectively
+ minimum homogeneous part. Empty list, if those elements are not existent
+ASSUMPTIONS:
+ - deg(p_max) >_lex deg(p_min) +1
+ - deg(q_max) >_lex deg(q_min) +1
+ - p_max*q_max = h_max
+ - p_min*q_min = h_min
+ - The basering is the nth Weyl algebra and has the form, that the first n variables represent
+   x1, ..., xn, and the second n variables do represent the d1, ..., dn.
+"
+{//proc determineRestOfHomogPartsNthWeyl
+  int p=printlevel-voice+2; // for dbprint
+  string dbprintWhitespace = "";
+  int i;  int j; int k; int l;
+  for (i = 1; i<=voice;i++)
+  {dbprintWhitespace = dbprintWhitespace + " ";}
+  intvec kappa = 0:(nvars(basering) div 2);
+  intvec maxDegrees;
+  intvec tempIntVec1;
+  intvec tempIntVec2;
+  for (i = 1; i <= nvars(basering) div 2; i++)
+  {//filling kappa
+    tempIntVec1 = 0:nvars(basering);
+    tempIntVec2 = 0:nvars(basering);
+    tempIntVec1[i] = 1;
+    tempIntVec2[i + nvars(basering) div 2] = 1;
+    kappa[i] = Min(intvec(deg(h,tempIntVec1), deg(h,tempIntVec2)));
+  }//filling kappa
+  dbprint(p, dbprintWhitespace + "The Kappas for the respective variables are:");
+  dbprint(p,kappa);
+  for (i = 1; i <= nvars(basering); i++)
+  {//filling maxDegrees
+    tempIntVec1 = 0:nvars(basering);
+    tempIntVec1[i] = 1;
+    maxDegrees[i] = deg(h,tempIntVec1);
+  }//filling maxDegrees
+  def R = basering;
+  intvec n1 = degreeOfNthWeylPoly(pmax);
+  intvec nk = degreeOfNthWeylPoly(pmin);
+  list pBetweenDegrees = possibleHomogPartsInBetween(degreeOfNthWeylPoly(pmax),
+                                                     degreeOfNthWeylPoly(pmin),
+                                                     maxDegrees);
+  int numberHomogPartsP = size(pBetweenDegrees);
+  dbprint(p,dbprintWhitespace + "Possible degrees between pmax and pmin:");
+  dbprint(p,pBetweenDegrees);
+  intvec m1 = degreeOfNthWeylPoly(qmax);
+  intvec ml = degreeOfNthWeylPoly(qmin);
+  list qBetweenDegrees = possibleHomogPartsInBetween(degreeOfNthWeylPoly(qmax),
+                                                     degreeOfNthWeylPoly(qmin),
+                                                     maxDegrees);
+  int numberHomogPartsQ = size(qBetweenDegrees);
+  dbprint(p,dbprintWhitespace + "Possible degrees between qmax and qmin:");
+  dbprint(p,qBetweenDegrees);
+  ideal mons;
+
+  list hBetweenDegrees = produceHomogListForProduct(pBetweenDegrees,qBetweenDegrees);
+  int numberOfHomogPartsH = size(hBetweenDegrees);
+  dbprint(p,dbprintWhitespace + "Possible degrees between hmax and hmin:");
+  dbprint(p,hBetweenDegrees);
+
+  dbprint(p,dbprintWhitespace+" Extracting zero homog. parts of pmax, qmax, pmin, qmin and h.");
+  //Extracting the zero homogeneous part of the given polynomials
+  ideal pandqZero = pmax,pmin,qmax,qmin;
+  for (i = 1; i<=nvars(basering) div 2; i++)
+  {//Extracting zero homogeneous part variable for variable
+    if (n1[i] > 0){pandqZero[1] = lift(var(i + nvars(basering) div 2)^n1[i],pandqZero[1])[1,1];}
+    else{if (n1[i] < 0){pandqZero[1] = lift(var(i)^(-n1[i]),pandqZero[1])[1,1];}
+      /* else{pandqZero[1] = pmax;} */}
+    if (nk[i] > 0){pandqZero[2] = lift(var(i + nvars(basering) div 2)^nk[i],pandqZero[2])[1,1];}
+    else{if (nk[i] < 0){pandqZero[2] = lift(var(i)^(-nk[i]),pandqZero[2])[1,1];}
+      /* else{pandqZero[2] = pmin;} */}
+    if (m1[i] > 0){pandqZero[3] = lift(var(i + nvars(basering) div 2)^m1[i],pandqZero[3])[1,1];}
+    else{if (m1[i] < 0){pandqZero[3] = lift(var(i)^(-m1[i]),pandqZero[3])[1,1];}
+      /* else{pandqZero[3] = qmax;} */}
+    if (ml[i] > 0){pandqZero[4] = lift(var(i + nvars(basering) div 2)^ml[i],pandqZero[4])[1,1];}
+    else{if (ml < 0){pandqZero[4] = lift(var(i)^(-ml[i]),pandqZero[4])[1,1];}
+      /* else{pandqZero[4] = qmin;} */}
+  }//Extracting zero homogeneous part variable for variable
+  list hZeroinR = homogDistributionNthWeyl(h);
+  for (i = 1; i<=size(hZeroinR);i++)
+  {//Extracting the zero homogeneous parts of the homogeneous summands of h
+    for (j = 1; j<=size(hZeroinR[i][1]); j++)
+    {//Iterating through the different variables
+      if (hZeroinR[i][1][j] > 0)
+      {
+        hZeroinR[i][2] =
+          lift(var(j + nvars(basering) div 2)^hZeroinR[i][1][j],hZeroinR[i][2])[1,1];
+      }
+      if (hZeroinR[i][1][j] < 0)
+      {
+        hZeroinR[i][2] = lift(var(j)^(-hZeroinR[i][1][j]),hZeroinR[i][2])[1,1];
+      }
+    }//Iterating through the different variables
+  }//Extracting the zero homogeneous parts of the homogeneous summands of h
+  //Now we need to fill up the space between the h-parts:
+  j = size(hZeroinR);
+  hBetweenDegrees = reverse(hBetweenDegrees);
+  list tempHList;
+  /* for (i = size(hBetweenDegrees); i>0 ;i--) */
+  /* {//Filling up hzero with 0s in between */
+  /*   ~; */
+  /*   while (hBetweenDegrees[i] < hZeroinR[j][1]) */
+  /*   { */
+  /*     tempHList[i] = list(hBetweenDegrees[i],0); */
+  /*     i--; */
+  /*   } */
+  /*   tempHList[i] = hZeroinR[j]; */
+  /*   j--; */
+  /* }//Filling up hzero with 0s in between */
+  for (i = size(hBetweenDegrees); i>0 ;i--)
+  {
+    tempHList[i] = list(hBetweenDegrees[i],0);
+  }
+  for (i = 1; i <= size(hZeroinR); i++)
+  {
+    for (j = 1; j<=size(tempHList);j++)
+    {
+      if (hZeroinR[i][1] == tempHList[j][1])
+      {
+        tempHList[j][2] = hZeroinR[i][2];
+      }
+    }
+  }
+  hZeroinR = tempHList;
+  //hBetweenDegrees = reverse(hBetweenDegrees);
+  dbprint(p,dbprintWhitespace+" Done!");
+  dbprint(p,dbprintWhitespace+" Moving everything into the ring K[theta]");
+  ring KTheta = 0,(x(1..(nvars(basering) div 2)),
+                   d(1..(nvars(basering) div 2)),
+                   theta(1..(nvars(basering) div 2))),dp;
+  setring(KTheta);
+  ideal mapList;
+  for (i = 1; i<=nvars(R) ; i++)
+  {//filling the list of elements we want to map
+    mapList[i] = var(i);
+  }//filling the list of elements we want to map
+  map thetamap = R, mapList;
+  poly entry;
+  ideal mons;
+  ideal pandqZero;
+  list hZeroinKTheta;
+  intvec lExp;
+  setring(R);
+  //Starting with p and q
+  for (k=1; k<=4; k++)
+  {//Transforming pmax(0),qmax(0),pmin(0),qmin(0) in theta-polys
+    mons = ideal();
+    for(i = 1; i<=size(pandqZero[k]);i++)
+    {//Putting the monomials in a list
+      mons[size(mons)+1] = pandqZero[k][i];
+    }//Putting the monomials in a list
+    setring(KTheta);
+    mons = thetamap(mons);
+    for (i = 1; i<=size(mons);i++)
+    {//transforming the monomials as monomials in the theta_i
+      entry = leadcoef(mons[i]);
+      lExp  = leadexp(mons[i]);
+      for (l = 1; l <=nvars(R) div 2; l++)
+      {
+        for (j = 0; j<lExp[l];j++)
+        {
+          entry = entry * (theta(l)-j);
+        }
+      }
+      mons[i] = entry;
+    }//transforming the monomials as monomials in the theta_i
+    pandqZero[size(pandqZero)+1] = sum(mons);
+    setring(R);
+  }//Transforming pmax(0),qmax(0),pmin(0),qmin(0) in theta-polys
+
+  //Now hZero
+  for (k = size(hZeroinR); k>= 1;k--)
+  {//Transforming the different homogeneous parts of h into polys in K[theta]
+    mons = ideal();
+    for(i = 1; i<=size(hZeroinR[k][2]);i++)
+    {//Putting the monomials in a list
+      mons[size(mons)+1] = hZeroinR[k][2][i];
+    }//Putting the monomials in a list
+    setring(KTheta);
+    mons = thetamap(mons);
+    for (i = 1; i<=size(mons);i++)
+    {//transforming the monomials as monomials in theta
+      entry = leadcoef(mons[i]);
+      lExp  = leadexp(mons[i]);
+      for (l = 1; l <=nvars(R) div 2; l++)
+      {
+        for (j = 0; j<lExp[l];j++)
+        {
+          entry = entry * (theta(l)-j);
+        }
+      }
+      mons[i] = entry;
+    }//transforming the monomials as monomials in theta
+    hZeroinKTheta = hZeroinKTheta + list(list(hBetweenDegrees[k],sum(mons)));
+    setring(R);
+  }//Transforming the different homogeneous parts of h into polys in K[theta]
+  dbprint(p,dbprintWhitespace+" Done!");
+  //Making the solutionRing
+  ring solutionRing = 0,(theta(1..nvars(R) div 2),
+                         q(0..(product(kappa+1))*(numberHomogPartsQ -2)-1)),lp;
+  dbprint(p,dbprintWhitespace+" Our solution ring is given by "+ string(solutionRing));
+  //mapping the different ps and qs and HZeros
+  dbprint(p,dbprintWhitespace+" Setting up our solution system.");
+  list ps;
+  ideal pandqZero = imap(KTheta,pandqZero);
+  for (i =numberHomogPartsP; i>=1; i--)
+  {
+    ps[i] = list(pBetweenDegrees[i],0);
+  }
+  ps[1][2] = pandqZero[2];
+  ps[numberHomogPartsP][2] = pandqZero[1];
+  list qs;
+  for (i = numberHomogPartsQ; i>=1 ; i--)
+  {
+    qs[i] = list(qBetweenDegrees[i],0);
+  }
+  qs[1][2] = pandqZero[4];
+  qs[numberHomogPartsQ][2] = pandqZero[3];
+  qs = reverse(qs);
+  ps = reverse(ps);
+  pBetweenDegrees = reverse(pBetweenDegrees);
+  qBetweenDegrees = reverse(qBetweenDegrees);
+  tempIntVec2 = 0:nvars(R);
+  for (i = 1; i<=size(kappa); i++)
+  {tempIntVec2[i + size(kappa)] = kappa[i];}
+  list coefficientIndices = possibleHomogPartsInBetween(kappa,
+                                              0:size(kappa),
+                                              tempIntVec2);
+  poly tempPoly;
+  for (i = 2; i<numberHomogPartsQ; i++)
+  {
+    for (j = 1; j<=size(coefficientIndices); j++)
+    {
+      tempPoly = 1;
+      for (k=1; k <= size(coefficientIndices[j]); k++)
+      {tempPoly = tempPoly*theta(k)^coefficientIndices[j][k];}
+      qs[i][2] = qs[i][2] + q((i-2)*product(kappa+1)+(j-1))*tempPoly;
+    }
+  }
+  dbprint(p,dbprintWhitespace + "The abstraction for the qs looks like:");
+  dbprint(p,qs);
+  list hZero = imap(KTheta,hZeroinKTheta);
+  //writing and solving the system
+  list lhs;
+  lhs[1] = list(ps[1][2],1);
+  list rhs;
+  rhs[numberHomogPartsP] = list(ps[size(ps)][2],1);
+  for (i = 2; i<= numberHomogPartsP;i++)
+  {
+    tempPoly = qs[1][2];
+    for (j = 1; j <= nvars(R) div 2; j++)
+    {
+      tempPoly = subst(tempPoly, theta(j), theta(j) + pBetweenDegrees[i][j]);
+    }
+    tempPoly = tempPoly * gammaForThetaNthWeyl(ps[i][1],qs[1][1]);
+    lhs[i] = list(hZero[i][2],tempPoly);
+    tempPoly = qs[size(qs)][2];
+    for (j = 1; j <= nvars(R) div 2; j++)
+    {
+      tempPoly = subst(tempPoly, theta(j), theta(j) + pBetweenDegrees[numberHomogPartsP -i +1][j]);
+    }
+    tempPoly = tempPoly * gammaForThetaNthWeyl(ps[numberHomogPartsP
+                                                  - i +1][1],qs[size(qs)][1]);
+    rhs[numberHomogPartsP-i+1] =
+      list(hZero[size(hZero)-i+1][2],tempPoly);
+    for (j = 1; j<i; j++)
+    {
+      for (k = 1; k<=size(qs);k++)
+      {
+        if(ps[j][1]+qs[k][1] == hZero[i][1])
+        {
+          lhs[i][1] = lhs[i][1]*lhs[j][2];
+          lhs[i][2] = lhs[i][2]*lhs[j][2];
+          tempPoly = qs[k][2];
+          for (l = 1; l <= nvars(R) div 2; l++)
+          {
+            tempPoly = subst(tempPoly, theta(l), theta(l) + pBetweenDegrees[j][l]);
+          }
+          tempPoly = tempPoly *
+    gammaForThetaNthWeyl(ps[j][1],qs[k][1]);
+          lhs[i][1] = lhs[i][1]-lhs[j][1]*tempPoly;
+        }
+        if(ps[size(ps)-j+1][1] + qs[size(qs) - k +1][1] ==hZero[size(hZero)-i+1][1])
+        {
+          rhs[size(ps) - i+1][1] = rhs[size(ps)-i+1][1]*rhs[size(ps)- j+1][2];
+          rhs[size(ps) - i + 1][2] =
+            rhs[size(ps)-i+1][2]*rhs[size(ps)-j+1][2];
+          tempPoly = qs[size(qs) - k + 1][2];
+          for (l = 1; l <= nvars(R) div 2; l++)
+          {
+            tempPoly = subst(tempPoly, theta(l), theta(l) +
+                             pBetweenDegrees[size(ps)-j + 1][l]);
+          }
+          tempPoly = tempPoly * gammaForThetaNthWeyl(ps[size(ps) -j
+                                                        +1][1],qs[size(qs)-k+1][1]);
+          rhs[size(ps) -i+1][1] =
+            rhs[size(ps)-i+1][1]-rhs[size(ps)-j+1][1]*tempPoly;
+        }
+      }
+    }
+  }
+  list eqs;
+  poly tempgcd;
+  poly templhscoeff;
+  poly temprhscoeff;
+  for (i = 2; i<=size(rhs);i++)
+  {
+    if (gcd(rhs[i][2],lhs[i][2]) == 1)
+    {
+      eqs = eqs + list(lhs[i][1]*rhs[i][2] -rhs[i][1]*lhs[i][2]);
+    }
+    else
+    {
+      tempgcd = gcd(rhs[i][2],lhs[i][2]);
+      templhscoeff = quotient(rhs[i][2],tempgcd)[1];
+      temprhscoeff = quotient(lhs[i][2],tempgcd)[1];
+      eqs = eqs + list(lhs[i][1]*templhscoeff -rhs[i][1]*temprhscoeff);
+    }
+  }
+  list newEntries;
+  list newEntriesTemp;
+  matrix tempCoefMatrix;
+  ideal solutionSystemforqs;
+  for (i = 1; i<= size(eqs); i++)
+  {//filling the ideal solutionSystemforqs
+    j = 1;
+    tempCoefMatrix = coef(eqs[i],theta(j));
+    for (l = 1; l<=ncols(tempCoefMatrix);l++)
+    {
+      newEntries = newEntries + list(tempCoefMatrix[2,l]);
+    }
+    while (j< nvars(R) div 2)
+    {
+      j++;
+      newEntriesTemp = list();
+      for (k = 1; k<=size(newEntries); k++)
+      {
+        tempCoefMatrix = coef(newEntries[k],theta(j));
+        for (l = 1; l<=ncols(tempCoefMatrix);l++)
+        {
+          newEntriesTemp = newEntriesTemp + list(tempCoefMatrix[2,l]);
+        }
+      }
+      newEntries = newEntriesTemp;
+    }
+    for (j = 1; j<=size(newEntries); j++)
+    {
+      solutionSystemforqs = solutionSystemforqs + newEntries[j];
+    }
+  }//filling the ideal solutionSystemforqs
+  dbprint(p,dbprintWhitespace+" Solution system for the coefficients of q is given by:");
+  dbprint(p,solutionSystemforqs);
+  option(redSB);
+  dbprint(p,dbprintWhitespace+" Calculating reduced Groebner Basis of that system.");
+  solutionSystemforqs = slimgb(solutionSystemforqs);
+  dbprint(p,dbprintWhitespace+" Done!, the solution for the system is:");
+  dbprint(p,dbprintWhitespace+string(solutionSystemforqs));
+  ideal theThetas;
+  for (i = 1; i<=nvars(R) div 2; i++)
+  {//Adding the theta_i to solutionSystemforqs to get vdim neq infty
+    theThetas = theThetas + theta(i);
+  }//Adding the theta_i to solutionSystemforqs to get vdim neq infty
+  if(vdim(slimgb(solutionSystemforqs + theThetas))==0)
+  {//No solution in this case. Return the empty list
+    dbprint(p,dbprintWhitespace+"The Groebner Basis of the solution system was <1>.");
+    setring(R);
+    return(list());
+  }//No solution in this case. Return the empty list
+  if(vdim(slimgb(solutionSystemforqs + theThetas))==-1)
+  {//My conjecture is that this would never happen
+    //ERROR("This is an counterexample to your conjecture. We have infinitely many solutions");
+    //TODO: See, what we would do here
+    dbprint(p,dbprintWhitespace+"There are infinitely many solution to this system.
+We will return the empty list.");
+    setring(R);
+    return(list());
+  }//My conjecture is that this would never happen
+  else
+  {//We have finitely many solutions
+    if(vdim(slimgb(solutionSystemforqs+theThetas))==1)
+    {//exactly one solution
+      for (i = 2; i<= size(qs)-1;i++)
+      {
+        qs[i][2] = NF(qs[i][2],slimgb(solutionSystemforqs));
+      }
+      setring(R);
+      ideal finalMapList;
+      for (i = 1; i<=nvars(R) div 2; i++)
+      {
+        finalMapList[i] = var(i)*var(i + (nvars(R) div 2));
+      }
+      map backFromSolutionRing = solutionRing,finalMapList;
+      list qs = backFromSolutionRing(qs);
+      list result = list(0);
+      for (i = 1; i<=size(qs); i++)
+      {
+        for (j= 1; j<=size(qs[i][1]); j++)
+        {
+          if (qs[i][1][j]>0){qs[i][2] = qs[i][2]*var(j + nvars(R) div 2)^qs[i][1][j];}
+          if (qs[i][1][j]<0){qs[i][2] = qs[i][2]*var(j)^(-qs[i][1][j]);}
+        }
+        result[1] = result[1] + qs[i][2];
+      }
+      dbprint(p,dbprintWhitespace+"Found one unique solution. Returning the result.");
+      return(result);
+    }//exactly one solution
+    else
+    {//We have more than one solution, but finitely many
+      def ringForSolveLib = solve(solutionSystemforqs+theThetas, "nodisplay");
+      setring ringForSolveLib;
+      list valuesForQs = list();
+      list tempValues;
+      int validSol;
+      for (i = 1; i<=size(SOL); i++)
+      {//filtering integer solutions
+        validSol = 1;
+        for (j =1; j<=size(SOL[i]); j++)
+        {//Checking every entry if it is integer or not
+          if (SOL[i][j] - int(SOL[i][j])!=0)
+          {//No integer solution
+            validSol = 0;
+            break;
+          }//No integer solution
+        }//Checking every entry if it is integer or not
+        if (validSol)
+        {
+          tempValues = list();
+          for (j = 1; j<=size(SOL[i]); j++)
+          {//filling the valuesforQs
+            tempValues[j]= int(SOL[i][j]);
+          }//filling the valuesforQs
+          valuesForQs = valuesForQs + list(tempValues);
+        }
+      }//filtering integer solutions
+      setring solutionRing;
+      list differentQs = list();
+      ideal tempSolutionForQ;
+      for (i = 1; i<=size(valuesForQs); i++)
+      {
+        differentQs[i] = qs;
+        tempSolutionForQ = ideal();
+        for (j=(nvars(R) div 2)+1; j<=nvars(solutionRing);j++)
+        {//filling solution ideal
+          tempSolutionForQ[j-(nvars(R) div 2)] = var(j) - valuesForQs[i][j];
+        }//filling solution ideal
+        for (j=2; j<size(differentQs[i]); j++)
+        {
+          differentQs[i][j][2] = NF(differentQs[i][j][2],slimgb(tempSolutionForQ));
+        }
+      }
+      setring(R);
+      ideal finalMapList;
+      for (i = 1; i<=nvars(R) div 2; i++)
+      {
+        finalMapList[i] = var(i)*var(i + (nvars(R) div 2));
+      }
+      map backFromSolutionRing = solutionRing,finalMapList;
+      list differentQs = backFromSolutionRing(differentQs);
+      list result = list();
+      for (k = 1; k<=size(differentQs); k++)
+      {
+        result[k] = 0;
+        for (i = 1; i<=size(differentQs[k]); i++)
+        {
+          for (j= 1; j<=size(differentQs[k][i][1]); j++)
+          {
+            if (differentQs[k][i][1][j]>0)
+            {differentQs[k][i][2] =
+                differentQs[k][i][2]*var(j + nvars(R) div 2)^differentQs[k][i][1][j];}
+            if (differentQs[k][i][1][j]<0)
+            {differentQs[k][i][2] = differentQs[k][i][2]*var(j)^(-differentQs[k][i][1][j]);}
+          }
+          result[k] = result[k] + differentQs[k][i][2];
+        }
+      }
+      dbprint(p,dbprintWhitespace+"Found multiple solutions. Returning the result.");
+      return(result);
+    }//We have more than one solution, but finitely many
+  }//We have finitely many solutions
+}//proc determineRestOfHomogPartsNthWeyl
+
+static proc produceHomogListForProduct(list homogParts1, list homogParts2)
+"
+INPUT: Two lists of integer vectors, homogParts1 and homogParts2,
+       where the contained integer vectors all have the same size n.
+OUTPUT: One list of integer vectors, which have size n respectively.
+        The entries are the set of possible integer vectors which result
+        of a sum of an entry y in homogParts1 and an entry x in homogParts2.
+"
+{//produceHomogListForProduct
+  int i; int j; int k;
+  list p = reverse(sort(homogParts1)[1]);
+  list q = reverse(sort(homogParts2)[1]);
+  list result;
+  intvec tempIntVec;
+  for (i = 1; i<= size(homogParts1); i++)
+  {
+    for (j = 1; j<= size(homogParts2); j++)
+    {
+      tempIntVec = homogParts1[i] + homogParts2[j];
+      if (binarySearch(result,tempIntVec)==0)
+      {//Element was not yet in result, add it
+        result = result + list(tempIntVec);
+        result = sort(result)[1];
+      }//Element was not yet in result, add it
+    }
+  }
+  result = reverse(result);
+  //Till here, we have a complete list with entries that are between hmax and hmin
+  //Now, we need to filter this list.
+
+  int isIn;
+  for(i = 1; i<=size(p); i++)
+  {//Checking, if homogparts[i] has a counterpart in homogparts2
+    isIn = 0;
+    for (j = 1; j<=size(q); j++)
+    {//iterating through the counterparts
+      if(p[i] + q[j] == result[i])
+      {
+        isIn = 1;
+        break;
+      }
+    }//iterating through the counterparts
+    if(!isIn)
+    {
+      result = delete(result,i);
+      continue;
+    }
+  }//Checking, if homogparts[i] has a counterpart in homogparts2
+  for (i = 0; i<size(p); i++)
+  {//The same from the top
+    isIn = 0;
+    for (j = 1; j<=size(q); j++)
+    {//iterating through the counterparts
+      if(p[size(p)-i] + q[j] == result[size(result) - i])
+      {
+        isIn = 1;
+        break;
+      }
+    }//iterating through the counterparts
+    if(!isIn)
+    {
+      result = delete(result,size(result)-i);
+      continue;
+    }
+  }//The same from the top
+  return(result);
+}//produceHomogListForProduct
+
+static proc binarySearch(list inputList, intvec inputElem)
+"
+INPUT: A list with integer vectors. The list has to be sorted.
+OUTPUT: If the entry was found, it returns its position, otherwise it returns 0.
+"
+{//binarySearch
+  int first = 1;
+  int last = size(inputList);
+  int middle;
+  while (first <= last)
+  {
+    middle = first + ((last - first) div 2);
+    if (inputList[middle] < inputElem)
+    {
+      first = middle + 1;
+    }
+    else
+    {
+      if (inputList[middle] > inputElem)
+      {
+        last = middle -1;
+      }
+      else
+      {
+        return(middle);
+      }
+    }
+  }
+  return(0);
+}//binarySearch
+
+static proc possibleHomogPartsInBetween(intvec pmax, intvec pmin, intvec maxDegrees)
+"
+INPUT: Integer vectors pmax, pmin and maxDegrees. All but maxDegrees are of the same size,
+       except from maxDegrees, which is double of the size of the rest.
+OUTPUT: A list of possible points in Z^n that can lie between pmax and
+        pmin, sorted with respect to the lexicographic order from
+        biggest to smallest (leftmost entry in the intvec is the biggest),
+        represented as list of intvecs.
+"
+{//possibleHomogPartsInBetween
+  if (size(pmax) != size(pmin) || 2*size(pmax)!=size(maxDegrees) || pmax<=pmin)
+  {
+    ERROR("pmax and pmin shall have the same size, and maxDegrees
+    shall be double the size of both. Furhtermore, it must hold that pmax>pmin. The
+    Input was: " + string(pmax) + ", " + string(pmin) + ", " + string(maxDegrees));
+  }
+  list result;
+  intvec tempIntVec = pmax;
+  while(tempIntVec > pmin)
+  {
+    result = result + list(tempIntVec);
+    tempIntVec = nextSmallerEntry(tempIntVec,pmin,maxDegrees);
+  }
+  result = result + list(pmin);
+  return (sort(result)[1]);
+}//possibleHomogPartsInBetween
+
+static proc nextSmallerEntry(intvec pmax, intvec pmin, intvec maxDegrees)
+"INPUT: Integer vectors pmax, pmin and maxDegrees. maxDegrees has to have size 2*size(pmax),
+        where pmin has to have the same size as pmax.
+OUTPUT: Counting down by lexicographical ordering, this function returns the next smaller
+entry after pmax, which is still bigger than pmin.
+"
+{//nextSmallerEntry
+  if (pmax == pmin)
+  {return (pmin);}
+  if (size(pmax) == 1)
+  {
+    if (pmax <= pmin)
+    {return(pmin);}
+    else
+    {return(pmax -1);}
+  }
+  int i;
+  intvec recPmax = pmax[1..(size(pmax)-1)];
+  intvec recPmin = pmin[1..(size(pmin)-1)];
+  intvec recMaxDegrees = intvec(maxDegrees[1]);
+  for (i = 2; i<=size(maxDegrees); i++)
+  {
+    if (i!=size(pmax) && i!= size(2*size(pmax)))
+    {
+      recMaxDegrees = recMaxDegrees,maxDegrees[i];
+    }
+  }
+  if (recPmax == recPmin)
+  {//In this case, we can only possibly count down at our current position
+    if (pmax[size(pmax)] > pmin[size(pmin)])
+    {return (recPmax,(pmax[size(pmax)]-1));}
+    else
+    {return(pmin);}
+  }//In this case, we can only possibly count down at our current position
+  else
+  {//In this case, we can go down to the bounds given by maxDegrees
+    if (pmax[size(pmax)] > -maxDegrees[size(pmax)])
+    {
+      return (recPmax,(pmax[size(pmax)]-1));
+    }
+    else
+    {
+      return(nextSmallerEntry(recPmax,recPmin,recMaxDegrees),maxDegrees[2*size(pmax)]);
+    }
+  }//In this case, we can go down to the bounds given by maxDegrees
+}//nextSmallerEntry
+
+static proc possibleHomogPartsInBetweenNonRecursive(intvec pmax, intvec pmin, intvec maxDegrees)
+"
+INPUT: Integer vectors pmax and maxDegrees. All but maxDegrees are of the same size,
+       except from maxDegrees, which is double of the size of the rest.
+OUTPUT: A list of possible points in Z^n that can lie between pmax and
+        pmin, sorted with respect to the lexicographic order from
+        biggest to smallest (leftmost entry in the intvec is the biggest),
+        represented as list of intvecs.
+"
+{//possibleHomogPartsInBetween
+  if (size(pmax) != size(pmin) || 2*size(pmax)!=size(maxDegrees) || pmax<=pmin)
+  {
+    ERROR("pmax and pmin shall have the same size, and maxDegrees
+    shall be double the size of both. Furhtermore, it must hold that pmax>pmin. The
+    Input was: " + string(pmax) + ", " + string(pmin) + ", " + string(maxDegrees));
+  }
+  list result = list(pmax);
+  int pos; int i; int j; int k;
+  list leftPart;
+  int leftPartIsMaxAndMin;
+  list possibleMiddles;
+  list possibleRightParts = list(list());
+  list tempRightParts;
+  intvec tempentry;
+  for (pos = size(pmax); pos >=1 ; pos--)
+  {
+    leftPart = list();
+    leftPartIsMaxAndMin = 1;
+    possibleMiddles = list();
+    for (i = 1; i < pos; i++)
+    {//filling the left part
+      leftPart[i] = pmax[i];
+      if(pmax[i]!=pmin[i])
+      {leftPartIsMaxAndMin = 0;}
+    }//filling the left part
+    if (leftPartIsMaxAndMin)
+    {
+      for (i = pmax[pos]-1; i>pmin[pos]; i--)
+      {//possible entries for position pos
+        possibleMiddles = possibleMiddles + list(i);
+      }//possible entries for position pos
+    }
+    else
+    {
+      for (i = pmax[pos]-1; i>=-maxDegrees[pos]; i--)
+      {//possible entries for position pos
+        possibleMiddles = possibleMiddles + list(i);
+      }//possible entries for position pos
+    }
+    for (i = 1; i<=size(possibleMiddles); i++)
+    {//Adding possibilities to result
+      for (j = 1; j<=size(possibleRightParts); j++)
+      {//going through the right parts
+        tempentry = intvec(0);
+        for (k = 1; k<=size(leftPart);k++)
+        {
+          tempentry[k] = leftPart[k];
+        }
+        if (size(leftPart)==0)
+        {tempentry = possibleMiddles[i];}
+        else
+        {tempentry = tempentry,possibleMiddles[i];}
+        for (k = 1; k<=size(possibleRightParts[j]) ; k++)
+        {
+          tempentry = tempentry, possibleRightParts[j][k];
+        }
+        result = result + list(tempentry);
+      }//going through the right parts
+    }//Adding possibilities to result
+    tempRightParts = list();
+    for (i = 1; i<=size(possibleRightParts);i++)
+    {
+      for (j = -maxDegrees[pos]; j <= maxDegrees[pos + size(pmax)];
+           j++)
+      {
+        tempRightParts = tempRightParts + list(list(j) + possibleRightParts[i]);
+      }
+    }
+    possibleRightParts = tempRightParts;
+  }
+  //Now the last possible guys
+  result = result + list(pmin);
+  leftPart = list();
+  int positionWhereDifference = 1;
+  for (i = 1; i<= size(pmin); i++)
+  {
+    if(pmax[i] != pmin[i])
+    {
+      positionWhereDifference = i;
+      break;
+    }
+  }
+  possibleRightParts = list(list());
+  for (pos = size(pmin); pos > positionWhereDifference; pos--)
+  {//Dealing with the minimal parts that we left out in the loop above
+    leftPart = list();
+    possibleMiddles = list();
+    for (i = 1; i < pos; i++)
+    {//filling up the left part
+      leftPart[i] = pmin[i];
+    }//filling up the left part
+    for (i = pmin[pos] +1 ; i<=maxDegrees[pos + size(pmin)] ; i++)
+    {
+      possibleMiddles = possibleMiddles + list(i);
+    }
+    for (i = 1; i<=size(possibleMiddles); i++)
+    {//Adding possibilities to result
+      for (j = 1; j<=size(possibleRightParts); j++)
+      {//going through the right parts
+        tempentry = intvec(0);
+        for (k = 1; k<=size(leftPart);k++)
+        {
+          tempentry[k] = leftPart[k];
+        }
+        if (size(leftPart)==0)
+        {tempentry = possibleMiddles[i];}
+        else
+        {tempentry = tempentry,possibleMiddles[i];}
+        for (k = 1; k<=size(possibleRightParts[j]) ; k++)
+        {
+          tempentry = tempentry, possibleRightParts[j][k];
+        }
+        result = result + list(tempentry);
+      }//going through the right parts
+    }//Adding possibilities to result
+    tempRightParts = list();
+    for (i = 1; i<=size(possibleRightParts);i++)
+    {
+      for (j = -maxDegrees[pos]; j <= maxDegrees[pos + size(pmax)];
+           j++)
+      {
+        tempRightParts = tempRightParts + list(list(j) + possibleRightParts[i]);
+      }
+    }
+    possibleRightParts = tempRightParts;
+  }//Dealing with the minimal parts that we left out in the loop above
+  result = sort(result)[1];
+   if (result[1] != pmin)
+  {result = insert(result,pmin);}
+  return(result);
+}//possibleHomogPartsInBetween
+
+static proc gammaForTheta(int j1,int j2)
+"
+INPUT: Two integers j1 and j2
+OUTPUT: A polynomial in the first variable of the given ring. It calculates the following function:
+   / 1,                                                if j1,j2>0 or j1,j2 <= 0
+   | prod_{kappa = 0}^{|j1|-1}(var(1)-kappa),          if j1<0, j2>0, |j1|<=|j2|
+gamma_{j1,j2}:= <  prod_{kappa = 0}^{j2-1}(var(1)-kappa-|j1|+|j2|),  if j1<0, j2>0, |j1|>|j2|
+   | prod_{kappa = 1}^{j1}(var(1)+kappa),              if j1>0, j2<0, |j1|<=|j2|
+   \ prod_{kappa = 1}^{|j2|}(\var(1)+kappa+|j1|-|j2|), if j1>0, j2<0, |j1|>|j2|
+ASSUMPTION:
+- Ring has at least one variable
+"
+{//gammaForTheta
+  if (j1<=0 && j2 <=0) {return(1);}
+  if (j1>=0 && j2 >=0){return(1);}
+  poly result;
+  int i;
+  if (j1<0 && j2>0)
+  {//case 2 or 3 from description above
+    if (absValue(j1)<=absValue(j2))
+    {//Case 2 holds here
+      result = 1;
+      for (i = 0;i<absValue(j1);i++)
+      {
+        result = result*(var(1)-i);
+      }
+      return(result);
+    }//Case 2 holds here
+    else
+    {//Case 3 holds here
+      result = 1;
+      for (i = 0; i<j2; i++)
+      {
+        result = result*(var(1)-i-absValue(j1)+absValue(j2));
+      }
+      return(result);
+    }//Case 3 holds here
+  }//case 2 or 3 from description above
+  else
+  {//Case 4 or 5 from description above hold
+    if (absValue(j1)<=absValue(j2))
+    {//Case 4 holds
+      result = 1;
+      for (i = 1; i<=j1; i++)
+      {
+        result = result*(var(1)+i);
+      }
+      return(result);
+    }//Case 4 holds
+    else
+    {//Case 5 holds
+      result = 1;
+      for (i = 1; i<=absValue(j2); i++)
+      {
+        result = result*(var(1)+i+absValue(j1)-absValue(j2));
+      }
+      return(result);
+    }//Case 5 holds
+  }//Case 4 or 5 from description above hold
+}//gammaForTheta
+
+static proc gammaForThetaNthWeyl(intvec j1,intvec j2)
+"
+INPUT: Two integer vectors j1 and j2
+OUTPUT: A polynomial in \theta_1,...,\theta_n. It calculates the following function:
+The product for i = 1 to n of gamma_{j1_i,j2_i}, where gamma is defined as in the function
+gammaForTheta.
+
+ASSUMPTION:
+- Ring has at least the variables \theta_1,...,\theta_n, being in position 1,...,n
+- both intvectors have length at least n
+"
+{//gammaForThetaNthWeyl
+  //Some stability tests in advance:
+  if (size(j1) != size(j2))
+  {ERROR("The size of the input vectors does not coincide.");}
+  if (size(j1) > nvars(basering))
+  {ERROR("The size of the input vectors is bigger than the number of variables.");}
+  int i; int j;
+  ideal separateGammas;
+  poly polyForPositionJ;
+  for (j = 1; j <= size(j1); j++)
+  {//Iterate through the \theta_j
+    if (j1[j]<=0 && j2[j] <=0)
+    {
+      separateGammas[j] = 1;
+      j++; continue;
+    }
+    if (j1[j]>=0 && j2[j] >=0)
+    {
+      separateGammas[j] = 1;
+      j++; continue;
+    }
+    if (j1[j]<0 && j2[j]>0)
+    {//case 2 or 3 from description above
+      if (absValue(j1[j])<=absValue(j2[j]))
+      {//Case 2 holds here
+        polyForPositionJ = 1;
+        for (i = 0;i<absValue(j1[j]);i++)
+        {
+          polyForPositionJ = polyForPositionJ*(var(j)-i);
+        }
+        separateGammas[j] = polyForPositionJ;
+        j++; continue;
+      }//Case 2 holds here
+      else
+      {//Case 3 holds here
+        polyForPositionJ = 1;
+        for (i = 0; i<j2; i++)
+        {
+          polyForPositionJ = polyForPositionJ*(var(1)-i-absValue(j1[j])+absValue(j2[j]));
+        }
+        separateGammas[j] = polyForPositionJ;
+        j++; continue;
+      }//Case 3 holds here
+    }//case 2 or 3 from description above
+    else
+    {//Case 4 or 5 from description above hold
+      if (absValue(j1[j])<=absValue(j2[j]))
+      {//Case 4 holds
+        polyForPositionJ = 1;
+        for (i = 1; i<=j1[j]; i++)
+        {
+          polyForPositionJ = polyForPositionJ*(var(j)+i);
+        }
+        separateGammas[j] = polyForPositionJ;
+        j++; continue;
+      }//Case 4 holds
+      else
+      {//Case 5 holds
+        polyForPositionJ = 1;
+        for (i = 1; i<=absValue(j2[j]); i++)
+        {
+          polyForPositionJ = polyForPositionJ*(var(j)+i+absValue(j1[j])-absValue(j2[j]));
+        }
+        separateGammas[j] = polyForPositionJ;
+        j++; continue;
+      }//Case 5 holds
+    }//Case 4 or 5 from description above hold
+  }//Iterate through the \theta_j
+  return(product(separateGammas));
+}//gammaForThetaNthWeyl
+
+static proc extractHomogeneousDivisors(poly h)
+"INPUT: A polynomial h in the first Weyl algebra
+OUTPUT: If h is homogeneous, then all factorizations of h are returned.
+ If h is inhomogeneous, then a list l is returned whose entries
+ are again lists k = [k_1,...,k_n], where k_1*...*k_n = h and there
+ exists an i in {1,...,n}, such that k_i is inhomogeneous and there
+ is no homogeneous polynomial that divides this k_i neither from the
+ left nor from the right. All the other entries in k are homogeneous
+ polynomials.
+"
+{//extractHomogeneousDivisors
+  int p=printlevel-voice+2; // for dbprint
+  string dbprintWhitespace = "";
+  int i; int j; int k; int l;
+  list result;
+  for (i = 1; i<=voice;i++)
+  {dbprintWhitespace = dbprintWhitespace + " ";}
+  if (homogwithorder(h,intvec(-1,1)))
+  {//given polynomial was homogeneous already
+    dbprint(p,dbprintWhitespace+"Polynomial was homogeneous. Just returning all factorizations.");
+    result = homogfacFirstWeyl_all(h);
+    for (i = 1; i<=size(result);i++)
+    {//removing the first entry (coefficient) from the list result
+      result[i] = delete(result[i],1);
+    }//removing the first entry (coefficient) from the list result
+    return(result);
+  }//given polynomial was homogeneous already
+  dbprint(p,dbprintWhitespace+"Calculating list with all homogeneous left divisors extracted");
+  list leftDivisionPossibilities = extractHomogeneousDivisorsLeft(h);
+  dbprint(p,dbprintWhitespace+"Done. The result is:");
+  dbprint(p,leftDivisionPossibilities);
+  dbprint(p,dbprintWhitespace+"Calculating list with all homogeneous Right divisors extracted");
+  list rightDivisionPossibilities = extractHomogeneousDivisorsRight(h);
+  dbprint(p,dbprintWhitespace+"Done. The result is:");
+  dbprint(p,rightDivisionPossibilities);
+  list tempList;
+  dbprint(p,dbprintWhitespace+"Calculating remaining right and left homogeneous divisors");
+  for (i = 1; i<=size(leftDivisionPossibilities); i++)
+  {//iterating through the list with extracted left divisors
+    tempList = extractHomogeneousDivisorsRight
+      (leftDivisionPossibilities[i][size(leftDivisionPossibilities[i])]);
+    leftDivisionPossibilities[i] = delete(leftDivisionPossibilities[i],
+                                          size(leftDivisionPossibilities[i]));
+    for (j=1;j<=size(tempList);j++)
+    {//Updating the list for Result
+      tempList[j] = leftDivisionPossibilities[i] + tempList[j];
+    }//Updating the list for Result
+    result = result + tempList;
+  }//iterating through the list with extracted left divisors
+  for (i = 1; i<=size(rightDivisionPossibilities); i++)
+  {//iterating through the list with extracted left divisors
+    tempList = extractHomogeneousDivisorsLeft(rightDivisionPossibilities[i][1]);
+    rightDivisionPossibilities[i] = delete(rightDivisionPossibilities[i],1);
+    for (j=1;j<=size(tempList);j++)
+    {//Updating the list for Result
+      tempList[j] =  tempList[j]+rightDivisionPossibilities[i];
+    }//Updating the list for Result
+    result = result + tempList;
+  }//iterating through the list with extracted left divisors
+  dbprint(p,dbprintWhitespace+"Done");
+  int posInhomog;
+  poly hath = 1;
+  list tempResult;
+  dbprint(p,dbprintWhitespace+"Checking if we can swap left resp. right
+divisors and updating result.");
+  for (i = 1; i<= size(result); i++)
+  {//Checking if we can swap left resp. right divisors
+    for (j = 1; j<=size(result[i]);j++)
+    {//finding the position of the inhomogeneous element in the list
+      if(!homogwithorder(result[i][j],intvec(-1,1)))
+      {
+        posInhomog = j;
+        break;
+      }
+    }//finding the position of the inhomogeneous element in the list
+    hath = result[i][posInhomog];
+    for(j=posInhomog-1;j>=1;j--)
+    {
+      hath = result[i][j]*hath;
+      tempList = extractHomogeneousDivisorsRight(hath);
+      if(size(tempList[1])==1)
+      {//We could not swap this element to the right
+        break;
+      }//We could not swap this element to the right
+      dbprint(p,dbprintWhitespace+"A swapping (left) of an element was possible");
+      for(k = 1; k<=size(tempList);k++)
+      {
+        tempResult = insert(tempResult,result[i]);
+        for (l = j;l<=posInhomog;l++)
+        {
+          tempResult[1] = delete(tempResult[1],j);
+        }
+        for (l = size(tempList[k]);l>=1;l--)
+        {
+          tempResult[1] = insert(tempResult[1],tempList[k][l],j-1);
+        }
+      }
+    }
+    hath = result[i][posInhomog];
+    for(j=posInhomog+1;j<=size(result[i]);j++)
+    {
+      hath = hath*result[i][j];
+      tempList = extractHomogeneousDivisorsLeft(hath);
+      if(size(tempList[1])==1)
+      {//We could not swap this element to the right
+        break;
+      }//We could not swap this element to the right
+      dbprint(p,dbprintWhitespace+"A swapping (right) of an element was possible");
+      for(k = 1; k<=size(tempList);k++)
+      {
+        tempResult = insert(tempResult,result[i]);
+        for (l=posInhomog; l<=j;l++)
+        {
+          tempResult[1] = delete(tempResult[1],posInhomog);
+        }
+        for (l = size(tempList[k]);l>=1;l--)
+        {
+          tempResult[1] = insert(tempResult[1],tempList[k][l],posInhomog-1);
+        }
+      }
+    }
+  }//Checking if we can swap left resp. right divisors
+  result = result + tempResult;
+  result = delete_dublicates_noteval(result);
+  return(result);
+}//extractHomogeneousDivisors
+
+static proc extractHomogeneousDivisorsNthWeyl(poly h)
+"INPUT: A polynomial h in the nth Weyl algebra
+OUTPUT: If h is homogeneous with respect to the ZZ-grading on the nth Weyl algebra,
+ then all factorizations of h are returned.
+ If h is inhomogeneous, then a list l is returned whose entries
+ are again lists k = [k_1,...,k_n], where k_1*...*k_n = h and there
+ exists an i in {1,...,n}, such that k_i is inhomogeneous and there
+ is no homogeneous polynomial that divides this k_i neither from the
+ left nor from the right. All the other entries in k are homogeneous
+ polynomials.
+
+GENERAL ASSUMPTIONS:
+ - The basering is the nth Weyl algebra and has the form, that the first n variables represent
+   x1, ..., xn, and the second n variables do represent the d1, ..., dn.
+"
+{//extractHomogeneousDivisorsNthWeyl
+  int p=printlevel-voice+2; // for dbprint
+  string dbprintWhitespace = "";
+  int i; int j; int k; int l;
+  list result;
+  for (i = 1; i<=voice;i++)
+  {dbprintWhitespace = dbprintWhitespace + " ";}
+  if (homogwithorderNthWeyl(h))
+  {//given polynomial was homogeneous already
+    dbprint(p,dbprintWhitespace+"Polynomial was homogeneous. Just returning all factorizations.");
+    result = homogfacNthWeyl_all(h);
+    for (i = 1; i<=size(result);i++)
+    {//removing the first entry (coefficient) from the list result
+      result[i] = delete(result[i],1);
+    }//removing the first entry (coefficient) from the list result
+    return(result);
+  }//given polynomial was homogeneous already
+  dbprint(p,dbprintWhitespace+"Calculating list with all homogeneous left divisors extracted");
+  list leftDivisionPossibilities = extractHomogeneousDivisorsLeftNthWeyl(h);
+  dbprint(p,dbprintWhitespace+"Done. The result is:");
+  dbprint(p,leftDivisionPossibilities);
+  dbprint(p,dbprintWhitespace+"Calculating list with all homogeneous Right divisors extracted");
+  list rightDivisionPossibilities = extractHomogeneousDivisorsRightNthWeyl(h);
+  dbprint(p,dbprintWhitespace+"Done. The result is:");
+  dbprint(p,rightDivisionPossibilities);
+  list tempList;
+  dbprint(p,dbprintWhitespace+"Calculating remaining right and left homogeneous divisors");
+  for (i = 1; i<=size(leftDivisionPossibilities); i++)
+  {//iterating through the list with extracted left divisors
+    tempList = extractHomogeneousDivisorsRightNthWeyl
+      (leftDivisionPossibilities[i][size(leftDivisionPossibilities[i])]);
+    leftDivisionPossibilities[i] = delete(leftDivisionPossibilities[i],
+                                          size(leftDivisionPossibilities[i]));
+    for (j=1;j<=size(tempList);j++)
+    {//Updating the list for Result
+      tempList[j] = leftDivisionPossibilities[i] + tempList[j];
+    }//Updating the list for Result
+    result = result + tempList;
+  }//iterating through the list with extracted left divisors
+  for (i = 1; i<=size(rightDivisionPossibilities); i++)
+  {//iterating through the list with extracted right divisors
+    tempList = extractHomogeneousDivisorsLeftNthWeyl(rightDivisionPossibilities[i][1]);
+    rightDivisionPossibilities[i] = delete(rightDivisionPossibilities[i],1);
+    for (j=1;j<=size(tempList);j++)
+    {//Updating the list for Result
+      tempList[j] =  tempList[j]+rightDivisionPossibilities[i];
+    }//Updating the list for Result
+    result = result + tempList;
+  }//iterating through the list with extracted right divisors
+  dbprint(p,dbprintWhitespace+"Done");
+  int posInhomog;
+  poly hath = 1;
+  list tempResult;
+  dbprint(p,dbprintWhitespace+"Checking if we can swap left resp. right
+divisors and updating result.");
+  for (i = 1; i<= size(result); i++)
+  {//Checking if we can swap left resp. right divisors
+    for (j = 1; j<=size(result[i]);j++)
+    {//finding the position of the inhomogeneous element in the list
+      if(!homogwithorderNthWeyl(result[i][j]))
+      {
+        posInhomog = j;
+        break;
+      }
+    }//finding the position of the inhomogeneous element in the list
+    hath = result[i][posInhomog];
+    for(j=posInhomog-1;j>=1;j--)
+    {
+      hath = result[i][j]*hath;
+      tempList = extractHomogeneousDivisorsRightNthWeyl(hath);
+      if(size(tempList[1])==1)
+      {//We could not swap this element to the right
+        break;
+      }//We could not swap this element to the right
+      dbprint(p,dbprintWhitespace+"A swapping (left) of an element was possible");
+      for(k = 1; k<=size(tempList);k++)
+      {
+        tempResult = insert(tempResult,result[i]);
+        for (l = j;l<=posInhomog;l++)
+        {
+          tempResult[1] = delete(tempResult[1],j);
+        }
+        for (l = size(tempList[k]);l>=1;l--)
+        {
+          tempResult[1] = insert(tempResult[1],tempList[k][l],j-1);
+        }
+      }
+    }
+    hath = result[i][posInhomog];
+    for(j=posInhomog+1;j<=size(result[i]);j++)
+    {
+      hath = hath*result[i][j];
+      tempList = extractHomogeneousDivisorsLeftNthWeyl(hath);
+      if(size(tempList[1])==1)
+      {//We could not swap this element to the right
+        break;
+      }//We could not swap this element to the right
+      dbprint(p,dbprintWhitespace+"A swapping (right) of an element was possible");
+      for(k = 1; k<=size(tempList);k++)
+      {
+        tempResult = insert(tempResult,result[i]);
+        for (l=posInhomog; l<=j;l++)
+        {
+          tempResult[1] = delete(tempResult[1],posInhomog);
+        }
+        for (l = size(tempList[k]);l>=1;l--)
+        {
+          tempResult[1] = insert(tempResult[1],tempList[k][l],posInhomog-1);
+        }
+      }
+    }
+  }//Checking if we can swap left resp. right divisors
+  result = result + tempResult;
+  result = delete_dublicates_noteval(result);
+  return(result);
+}//extractHomogeneousDivisorsNthWeyl
+
+static proc extractHomogeneousDivisorsLeft(poly h)
+"INPUT: A polynomial h in the first Weyl algebra
+OUTPUT: If h is homogeneous, then all factorizations of h are returned.
+ If h is inhomogeneous, then a list l is returned whose entries
+ are again lists k = [k_1,...,k_n], where k_1*...*k_n = h.
+ The entry k_n is inhomogeneous and has no other homogeneous
+ left divisors any more.
+ All the other entries in k are homogeneous
+ polynomials.
+"
+{//extractHomogeneousDivisorsLeft
+  int p=printlevel-voice+2; // for dbprint
+  string dbprintWhitespace = "";
+  int i;int j; int k;
+  list result;
+  poly hath;
+  list recResult;
+  map invo = basering,-var(1),var(2);
+  for (i = 1; i<=voice;i++)
+  {dbprintWhitespace = dbprintWhitespace + " ";}
+  if (homogwithorder(h,intvec(-1,1)))
+  {//given polynomial was homogeneous already
+    dbprint(p,dbprintWhitespace+"Polynomial was homogeneous. Just returning all factorizations.");
+    result = homogfacFirstWeyl_all(h);
+    for (i = 1; i<=size(result);i++)
+    {//removing the first entry (coefficient) from the list result
+      result[i] = delete(result[i],1);
+    }//removing the first entry (coefficient) from the list result
+    return(result);
+  }//given polynomial was homogeneous already
+  list hlist = homogDistribution(h);
+  dbprint(p,dbprintWhitespace+ " Computing factorizations of all homogeneous summands.");
+  for (i = 1; i<= size(hlist); i++)
+  {
+    hlist[i] = homogfacFirstWeyl_all(hlist[i][2]);
+    if (size(hlist[i][1])==1)
+    {//One homogeneous part just has a trivial factorization
+      if(hlist[i][1][1] == 0)
+      {
+        hlist = delete(hlist,i);
+        continue;
+      }
+      else
+      {
+        return(list(list(h)));
+      }
+    }//One homogeneous part just has a trivial factorization
+  }
+  dbprint(p,dbprintWhitespace+ " Done.");
+  dbprint(p,dbprintWhitespace+ " Trying to find Left divisors");
+  list alreadyConsideredCandidates;
+  poly candidate;
+  int isCandidate;
+  for (i = 1; i<=size(hlist[1]);i++)
+  {//Finding candidates for homogeneous left divisors of h
+    candidate = hlist[1][i][2];
+    isCandidate = 0;
+    for (j=1;j<=size(alreadyConsideredCandidates);j++)
+    {
+      if(alreadyConsideredCandidates[j] == candidate)
+      {
+        isCandidate =1;
+        break;
+      }
+    }
+    if(isCandidate)
+    {
+      i++;
+      continue;
+    }
+    else
+    {
+      alreadyConsideredCandidates = alreadyConsideredCandidates + list(candidate);
+    }
+    dbprint(p,dbprintWhitespace+"Checking if "+string(candidate)+" is a homogeneous left divisor");
+    for (j = 2; j<=size(hlist);j++)
+    {//Iterating through the other homogeneous parts
+      isCandidate = 0;
+      for(k=1; k<=size(hlist[j]);k++)
+      {
+        if(hlist[j][k][2]==candidate)
+        {
+          isCandidate = 1;
+          break;
+        }
+      }
+      if(!isCandidate)
+      {
+        break;
+      }
+    }//Iterating through the other homogeneous parts
+    if(isCandidate)
+    {//candidate was really a left divisor
+      dbprint(p,dbprintWhitespace+string(candidate)+" is a homogeneous left divisor");
+      hath = involution(lift(involution(candidate,invo),involution(h,invo))[1,1],invo);
+      recResult = extractHomogeneousDivisorsLeft(hath);
+      for (j = 1; j<=size(recResult); j++)
+      {
+        recResult[j] = insert(recResult[j],candidate);
+      }
+      result = result + recResult;
+    }//Candidate was really a left divisor
+  }//Finding candidates for homogeneous left divisors of h
+  if (size(result)==0)
+  {
+    return(list(list(h)));
+  }
+  return(result);
+}//extractHomogeneousDivisorsLeft
+
+static proc extractHomogeneousDivisorsLeftNthWeyl(poly h)
+"INPUT: A polynomial h in the nth Weyl algebra
+OUTPUT: If h is homogeneous with respect to the ZZ grading on the nth Weyl algebra,
+ then all factorizations of h are returned.
+ If h is inhomogeneous, then a list l is returned whose entries
+ are again lists k = [k_1,...,k_n], where k_1*...*k_n = h.
+ The entry k_n is inhomogeneous and has no other homogeneous
+ left divisors any more.
+ All the other entries in k are homogeneous
+ polynomials.
+
+GENERAL ASSUMPTIONS:
+ - The basering is the nth Weyl algebra and has the form, that the first n variables represent
+   x1, ..., xn, and the second n variables do represent the d1, ..., dn.
+"
+{//extractHomogeneousDivisorsLeftNthWeyl
+  int p=printlevel-voice+2; // for dbprint
+  string dbprintWhitespace = "";
+  int i;int j; int k;
+  list result;
+  poly hath;
+  list recResult;
+  ideal invoIdeal;
+  for (i = 1; i <= nvars(basering); i++)
+  {//Filling the mapping rules for the involution map
+    if (i <= nvars(basering) div 2)
+    {invoIdeal[i] = -var(i);}
+    else
+    {invoIdeal[i] = var(i);}
+  }//Filling the mapping rules for the involution map
+  map invo = basering,invoIdeal;
+  for (i = 1; i<=voice;i++)
+  {dbprintWhitespace = dbprintWhitespace + " ";}
+  if (homogwithorderNthWeyl(h))
+  {//given polynomial was homogeneous already
+    dbprint(p,dbprintWhitespace+"Polynomial was homogeneous. Just returning all factorizations.");
+    result = homogfacNthWeyl_all(h);
+    for (i = 1; i<=size(result);i++)
+    {//removing the first entry (coefficient) from the list result
+      result[i] = delete(result[i],1);
+    }//removing the first entry (coefficient) from the list result
+    return(result);
+  }//given polynomial was homogeneous already
+  list hlist = homogDistributionNthWeyl(h);
+  dbprint(p,dbprintWhitespace+ " Computing factorizations of all homogeneous summands.");
+  for (i = 1; i<= size(hlist); i++)
+  {
+    hlist[i] = homogfacNthWeyl_all(hlist[i][2]);
+    if (size(hlist[i][1])==1)
+    {//One homogeneous part just has a trivial factorization
+      if(hlist[i][1][1] == 0)
+      {
+        hlist = delete(hlist,i);
+        continue;
+      }
+      else
+      {
+        return(list(list(h)));
+      }
+    }//One homogeneous part just has a trivial factorization
+  }
+  dbprint(p,dbprintWhitespace+ " Done.");
+  dbprint(p,dbprintWhitespace+ " Trying to find Left divisors");
+  list alreadyConsideredCandidates;
+  poly candidate;
+  int isCandidate;
+  for (i = 1; i<=size(hlist[1]);i++)
+  {//Finding candidates for homogeneous left divisors of h
+    candidate = hlist[1][i][2];
+    isCandidate = 0;
+    for (j=1;j<=size(alreadyConsideredCandidates);j++)
+    {
+      if(alreadyConsideredCandidates[j] == candidate)
+      {
+        isCandidate =1;
+        break;
+      }
+    }
+    if(isCandidate)
+    {
+      i++;
+      continue;
+    }
+    else
+    {
+      alreadyConsideredCandidates = alreadyConsideredCandidates + list(candidate);
+    }
+    dbprint(p,dbprintWhitespace+"Checking if "+string(candidate)+" is a homogeneous left divisor");
+    for (j = 2; j<=size(hlist);j++)
+    {//Iterating through the other homogeneous parts
+      isCandidate = 0;
+      for(k=1; k<=size(hlist[j]);k++)
+      {
+        if(hlist[j][k][2]==candidate)
+        {
+          isCandidate = 1;
+          break;
+        }
+      }
+      if(!isCandidate)
+      {
+        break;
+      }
+    }//Iterating through the other homogeneous parts
+    if(isCandidate)
+    {//candidate was really a left divisor
+      dbprint(p,dbprintWhitespace+string(candidate)+" is a homogeneous left divisor");
+      hath = involution(lift(involution(candidate,invo),involution(h,invo))[1,1],invo);
+      recResult = extractHomogeneousDivisorsLeftNthWeyl(hath);
+      for (j = 1; j<=size(recResult); j++)
+      {
+        recResult[j] = insert(recResult[j],candidate);
+      }
+      result = result + recResult;
+    }//Candidate was really a left divisor
+  }//Finding candidates for homogeneous left divisors of h
+  if (size(result)==0)
+  {
+    return(list(list(h)));
+  }
+  return(result);
+}//extractHomogeneousDivisorsLeftNthWeyl
+/*
+  Interesting test cases:
+
+  h=x1^2*x2*x3*d1*d2*d3+x1*x2^2*x3*d1*d2*d3+x1*x2*x3*d1^2*d2*d3+x1*x2*x3*d1*d3+x1*x2*x3*d2*d3
+  h = x1*(d1+x1);
+  h = x1*d2 + x3*d3;
+  h = x1*x2*d2^2+x2^2*d2*d3+x1*d2+2*x2*d3
+ */
+
+static proc extractHomogeneousDivisorsRight(poly h)
+"INPUT: A polynomial h in the first Weyl algebra
+OUTPUT: If h is homogeneous, then all factorizations of h are returned.
+ If h is inhomogeneous, then a list l is returned whose entries
+ are again lists k = [k_1,...,k_n], where k_1*...*k_n = h.
+ The entry k_1 is inhomogeneous and has no other homogeneous
+ right divisors any more.
+ All the other entries in k are homogeneous
+ polynomials.
+"
+{//extractHomogeneousDivisorsRight
+  int p=printlevel-voice+2; // for dbprint
+  string dbprintWhitespace = "";
+  int i;int j; int k;
+  list result;
+  poly hath;
+  list recResult;
+  for (i = 1; i<=voice;i++)
+  {dbprintWhitespace = dbprintWhitespace + " ";}
+  if (homogwithorder(h,intvec(-1,1)))
+  {//given polynomial was homogeneous already
+    dbprint(p,dbprintWhitespace+"Polynomial was homogeneous. Just returning all factorizations.");
+    result = homogfacFirstWeyl_all(h);
+    for (i = 1; i<=size(result);i++)
+    {//removing the first entry (coefficient) from the list result
+      result[i] = delete(result[i],1);
+    }//removing the first entry (coefficient) from the list result
+    return(result);
+  }//given polynomial was homogeneous already
+  list hlist = homogDistribution(h);
+  dbprint(p,dbprintWhitespace+ " Computing factorizations of all homogeneous summands.");
+  for (i = 1; i<= size(hlist); i++)
+  {
+    hlist[i] = homogfacFirstWeyl_all(hlist[i][2]);
+    if (size(hlist[i][1])==1)
+    {//One homogeneous part just has a trivial factorization
+      if(hlist[i][1][1] == 0)
+      {
+        hlist = delete(hlist,i);
+        continue;
+      }
+      else
+      {
+        return(list(list(h)));
+      }
+    }//One homogeneous part just has a trivial factorization
+  }
+  dbprint(p,dbprintWhitespace+ " Done.");
+  dbprint(p,dbprintWhitespace+ " Trying to find right divisors");
+  list alreadyConsideredCandidates;
+  poly candidate;
+  int isCandidate;
+  for (i = 1; i<=size(hlist[1]);i++)
+  {//Finding candidates for homogeneous left divisors of h
+    candidate = hlist[1][i][size(hlist[1][i])];
+    isCandidate = 0;
+    for (j=1;j<=size(alreadyConsideredCandidates);j++)
+    {
+      if(alreadyConsideredCandidates[j] == candidate)
+      {
+        isCandidate =1;
+        break;
+      }
+    }
+    if(isCandidate)
+    {
+      i++;
+      continue;
+    }
+    else
+    {
+      alreadyConsideredCandidates = alreadyConsideredCandidates + list(candidate);
+    }
+    dbprint(p,dbprintWhitespace+"Checking if "+string(candidate)+" is a homogeneous r-divisor");
+    for (j = 2; j<=size(hlist);j++)
+    {//Iterating through the other homogeneous parts
+      isCandidate = 0;
+      for(k=1; k<=size(hlist[j]);k++)
+      {
+        if(hlist[j][k][size(hlist[j][k])]==candidate)
+        {
+          isCandidate = 1;
+          break;
+        }
+      }
+      if(!isCandidate)
+      {
+        break;
+      }
+    }//Iterating through the other homogeneous parts
+    if(isCandidate)
+    {//candidate was really a left divisor
+      dbprint(p,dbprintWhitespace+string(candidate)+" is a homogeneous right divisor");
+      hath = lift(candidate,h)[1,1];
+      recResult = extractHomogeneousDivisorsRight(hath);
+      for (j = 1; j<=size(recResult); j++)
+      {
+        recResult[j] = insert(recResult[j],candidate,size(recResult[j]));
+      }
+      result = result + recResult;
+    }//Candidate was really a left divisor
+  }//Finding candidates for homogeneous left divisors of h
+  if (size(result)==0)
+  {
+    result = list(list(h));
+  }
+  return(result);
+}//extractHomogeneousDivisorsRight
+
+static proc extractHomogeneousDivisorsRightNthWeyl(poly h)
+"INPUT: A polynomial h in the nth Weyl algebra
+OUTPUT: If h is homogeneous with respect to the ZZ grading on the nth Weyl algebra,
+ then all factorizations of h are returned.
+ If h is inhomogeneous, then a list l is returned whose entries
+ are again lists k = [k_1,...,k_n], where k_1*...*k_n = h.
+ The entry k_1 is inhomogeneous and has no other homogeneous
+ right divisors any more.
+ All the other entries in k are homogeneous
+ polynomials.
+GENERAL ASSUMPTIONS:
+ - The basering is the nth Weyl algebra and has the form, that the first n variables represent
+   x1, ..., xn, and the second n variables do represent the d1, ..., dn.
+"
+{//extractHomogeneousDivisorsRightNthWeyl
+  int p=printlevel-voice+2; // for dbprint
+  string dbprintWhitespace = "";
+  int i;int j; int k;
+  list result;
+  poly hath;
+  list recResult;
+  for (i = 1; i<=voice;i++)
+  {dbprintWhitespace = dbprintWhitespace + " ";}
+  if (homogwithorderNthWeyl(h))
+  {//given polynomial was homogeneous already
+    dbprint(p,dbprintWhitespace+"Polynomial was homogeneous. Just returning all factorizations.");
+    result = homogfacNthWeyl_all(h);
+    for (i = 1; i<=size(result);i++)
+    {//removing the first entry (coefficient) from the list result
+      result[i] = delete(result[i],1);
+    }//removing the first entry (coefficient) from the list result
+    return(result);
+  }//given polynomial was homogeneous already
+  list hlist = homogDistributionNthWeyl(h);
+  dbprint(p,dbprintWhitespace+ " Computing factorizations of all homogeneous summands.");
+  for (i = 1; i<= size(hlist); i++)
+  {
+    hlist[i] = homogfacNthWeyl_all(hlist[i][2]);
+    if (size(hlist[i][1])==1)
+    {//One homogeneous part just has a trivial factorization
+      if(hlist[i][1][1] == 0)
+      {
+        hlist = delete(hlist,i);
+        continue;
+      }
+      else
+      {
+        return(list(list(h)));
+      }
+    }//One homogeneous part just has a trivial factorization
+  }
+  dbprint(p,dbprintWhitespace+ " Done.");
+  dbprint(p,dbprintWhitespace+ " Trying to find right divisors");
+  list alreadyConsideredCandidates;
+  poly candidate;
+  int isCandidate;
+  for (i = 1; i<=size(hlist[1]);i++)
+  {//Finding candidates for homogeneous left divisors of h
+    candidate = hlist[1][i][size(hlist[1][i])];
+    isCandidate = 0;
+    for (j=1;j<=size(alreadyConsideredCandidates);j++)
+    {
+      if(alreadyConsideredCandidates[j] == candidate)
+      {
+        isCandidate =1;
+        break;
+      }
+    }
+    if(isCandidate)
+    {
+      i++;
+      continue;
+    }
+    else
+    {
+      alreadyConsideredCandidates = alreadyConsideredCandidates + list(candidate);
+    }
+    dbprint(p,dbprintWhitespace+"Checking if "+string(candidate)+" is a homogeneous r-divisor");
+    for (j = 2; j<=size(hlist);j++)
+    {//Iterating through the other homogeneous parts
+      isCandidate = 0;
+      for(k=1; k<=size(hlist[j]);k++)
+      {
+        if(hlist[j][k][size(hlist[j][k])]==candidate)
+        {
+          isCandidate = 1;
+          break;
+        }
+      }
+      if(!isCandidate)
+      {
+        break;
+      }
+    }//Iterating through the other homogeneous parts
+    if(isCandidate)
+    {//candidate was really a left divisor
+      dbprint(p,dbprintWhitespace+string(candidate)+" is a homogeneous right divisor");
+      hath = lift(candidate,h)[1,1];
+      recResult = extractHomogeneousDivisorsRightNthWeyl(hath);
+      for (j = 1; j<=size(recResult); j++)
+      {
+        recResult[j] = insert(recResult[j],candidate,size(recResult[j]));
+      }
+      result = result + recResult;
+    }//Candidate was really a left divisor
+  }//Finding candidates for homogeneous left divisors of h
+  if (size(result)==0)
+  {
+    result = list(list(h));
+  }
+  return(result);
+}//extractHomogeneousDivisorsRightNthWeyl
+
+static proc fromZeroHomogToThetaPoly(poly h)
+"
+//DEPRECATED
+INPUT: A polynomial h in the first Weyl algebra, homogeneous of degree 0
+ OUTPUT: The ring Ktheta with a polynomial result representing h as polynomial in
+  theta
+ ASSUMPTIONS:
+- h is homogeneous of degree 0 with respect to the [-1,1] weight vector
+- The basering is the first Weyl algebra
+"
+{//proc fromZeroHomogToThetaPoly
+  int i; int j;
+  list mons;
+  if(!homogwithorder(h,intvec(-1,1)))
+  {//Input not a homogeneous polynomial causes an error
+    ERROR("The input was not a homogeneous polynomial");
+  }//Input not a homogeneous polynomial causes an error
+  if(deg(h,intvec(-1,1))!=0)
+  {//Input does not have degree 0
+    ERROR("The input did not have degree 0");
+  }//Input does not have degree 0
+  for(i = 1; i<=size(h);i++)
+  {//Putting the monomials in a list
+    mons = mons+list(h[i]);
+  }//Putting the monomials in a list
+  ring KTheta = 0,(x,y,theta),dp;
+  setring KTheta;
+  map thetamap = r,x,y;
+  list mons = thetamap(mons);
+  poly entry;
+  for (i = 1; i<=size(mons);i++)
+  {//transforming the monomials as monomials in theta
+    entry = leadcoef(mons[i]);
+    for (j = 0; j<leadexp(mons[i])[2];j++)
+    {
+      entry = entry * (theta-j);
+    }
+    mons[i] = entry;
+  }//transforming the monomials as monomials in theta
+  poly result = sum(mons);
+  keepring KTheta;
+}//proc fromZeroHomogToThetaPoly
+
+static proc fromHomogDistributionListToPoly(list l)
+"returns the corresponding polynomial to a given output of homogDistribution"
+{//proc fromHomogDistributionListToPoly
+  poly result = 0;
+  int i;
+  for (i = 1; i<=size(l);i++)
+  {
+    result = result + l[i][2];
+  }
+  return(result);
+}//proc fromHomogDistributionListToPoly
+
+static proc divides(poly p1, poly p2,map invo, list #)
+  "Tests, whether p1 divides p2 either from left or from right. The involution invo is needed
+for checking both sides. The optional argument is needed in order to also return the other factor.
+RETURN: If no optional argument is given, it will just return 1 or 0.
+ Otherwise a list with at least one element
+ Case 1: p1 does not divide p2 from any side. Then the output will be the empty list.
+ Case 2: p2 does divide p2 from one side at least.
+  Then it returns a list with tuples p,q, such that p or q equals p1 and
+  pq = p2.
+ASSUMPTIONS: - The map invo is an involution on the basering."
+{//proc divides
+  list result = list();
+  poly tempfactor;
+  if (involution(reduce(involution(p2,invo),std(involution(ideal(p1),invo))),invo)==0)
+  {//p1 is a left divisor
+    if(size(#)==0){return(1);}
+    tempfactor = involution(lift(involution(p1,invo),involution(p2,invo))[1,1],invo);
+    if (leadcoef(p1)<0 && leadcoef(tempfactor)<0)
+    {//both have a negative leading coefficient
+      result = result +list(list(1,-p1, -tempfactor));
+    }//both have a negative leading coefficient
+    else
+    {
+      if (leadcoef(p1)*leadcoef(tempfactor)<0)
+      {//One of them has a negative leading coefficient
+        if (leadcoef(p1)<0)
+        {
+          result = result + list(list(-1,-p1,tempfactor));
+        }
+        else
+        {
+          result = result + list(list(-1,p1,-tempfactor));
+        }
+      }//One of them has a negative leading coefficient
+      else
+      {//no negative coefficient at all
+        result = result + list(list(1,p1,tempfactor));
+      }//no negative coefficient at all
+    }
+  }//p1 is a left divisor
+
+  if (reduce(p2,std(ideal(p1))) == 0)
+  {//p1 is  a right divisor
+    if(size(#)==0){return(1);}
+    tempfactor = lift(p1, p2)[1,1];
+    if (leadcoef(p1)<0 && leadcoef(tempfactor)<0)
+    {//both have a negative leading coefficient
+      result = result +list(list(1, -tempfactor,-p1));
+    }//both have a negative leading coefficient
+    else
+    {
+      if (leadcoef(p1)*leadcoef(tempfactor)<0)
+      {//One of them has a negative leading coefficient
+        if (leadcoef(p1)<0)
+        {
+          result = result + list(list(-1,tempfactor,-p1));
+        }
+        else
+        {
+          result = result + list(list(-1,-tempfactor,p1));
+        }
+      }//One of them has a negative leading coefficient
+      else
+      {//no negative coefficient at all
+        result = result + list(list(1,tempfactor,p1));
+      }//no negative coefficient at all
+    }
+  }//p1 is already a right divisor
+  if (size(#)==0){return(0);}
+  return(result);
+}//proc divides
+
+static proc computeCombinationsMinMaxHomog(poly h)
+"Input: A polynomial h in the first Weyl Algebra
+Output: Combinations of the form (p_max + p_min)(q_max + q_min), such that p_max, p_min,
+ q_max and q_min are homogeneous and p_max*q_max equals the maximal homogeneous
+ part in h, and p_max * q_max equals the minimal homogeneous part in h.
+ h is not homogeneous.
+"{//proc computeCombinationsMinMaxHomog
+  intvec ivm11 = intvec(-1,1);
+  intvec iv11 = intvec(1,1);
+  intvec iv10 = intvec(1,0);
+  intvec iv01 = intvec(0,1);
+  intvec iv1m1 = intvec(1,-1);
+  poly maxh = jet(h,deg(h,ivm11),ivm11)-jet(h,deg(h,ivm11)-1,ivm11);
+  poly minh = jet(h,deg(h,iv1m1),iv1m1)-jet(h,deg(h,iv1m1)-1,iv1m1);
+  list f1 = homogfacFirstWeyl_all(maxh);
+  list f2 = homogfacFirstWeyl_all(minh);
+  list result = list();
+  int i;
+  int j;
+  //TODOs: Nur die kombinieren, die auch wirklich eine brauchbare Kombination sind.
+  //Also, wir duerfen nicht aus den Geraden herausfliegen
+  list pqmax = list();
+  list pqmin = list();
+  list tempList = list();
+
+  //First, we are going to deal with our most hated guys: The Coefficients.
+  //
+  list coeffTuplesMax = getAllCoeffTuplesComb(factorizeInt(number(f1[1][1])));
+  //We can assume without loss of generality, that p_max has a
+  //nonnegative leading coefficient
+  for (i = 1; i<=size(coeffTuplesMax);i++)
+  {//Deleting all tuples with negative entries for p_max
+    if (coeffTuplesMax[i][1]<0)
+    {
+      coeffTuplesMax = delete(coeffTuplesMax,i);
+      continue;
+    }
+  }//Deleting all tuples with negative entries for p_max
+  list coeffTuplesMin = getAllCoeffTuplesComb(factorizeInt(number(f2[1][1])));
+
+  //Now, we will be actally dealing with the Combinations.
+  //Let's start with the pqmax
+  if (size(f1[1]) == 1)
+  {//the maximal homogeneous factor is a constant
+    pqmax = coeffTuplesMax;
+  }//the maximal homogeneous factor is a constant
+  else
+  {//the maximal homogeneous factor is not a constant
+    for (i = 1; i<=size(f1); i++)
+    {//We can forget about the first coefficient now. Therefore we will delete him from the list.
+      f1[i] = delete(f1[i],1);
+      if(size(f1[i])==1)
+      {//trivial thing
+        for (j = 1; j<=size(coeffTuplesMax); j++)
+        {
+          pqmax = pqmax + list(list(coeffTuplesMax[j][1],coeffTuplesMax[j][2]*f1[i][1]));
+          pqmax = pqmax + list(list(coeffTuplesMax[j][1]*f1[i][1],coeffTuplesMax[j][2]));
+        }
+        f1 = delete(f1,i);
+        continue;
+      }//trivial thing
+    }//We can forget about the first coefficient now. Therefore we will delete him from the list.
+    if (size(f1)>0)
+    {
+      tempList = getAllCombOfHomogFact(f1);
+      for (i = 1; i<=size(tempList); i++)
+      {//Every combination combined with the coefficient possibilities
+        for (j = 1; j<=size(coeffTuplesMax); j++)
+        {//iterating through the possible coefficient choices
+          pqmax = pqmax + list(list(coeffTuplesMax[j][1]*tempList[i][1],
+                                    coeffTuplesMax[j][2]*tempList[i][2]));
+        }//iterating through the possible coefficient choices
+      }//Every combination combined with the coefficient possibilities
+      for (i = 1; i<=size(coeffTuplesMax); i++)
+      {
+        pqmax = pqmax + list(list(coeffTuplesMax[i][1],maxh/coeffTuplesMax[i][1]));
+        pqmax = pqmax + list(list(maxh/coeffTuplesMax[i][2],coeffTuplesMax[i][2]));
+      }
+    }
+  }//the maximal homogeneous factor is not a constant
+  //Now we go to pqmin
+  if (size(f2[1]) == 1)
+  {//the minimal homogeneous factor is a constant
+    pqmin = coeffTuplesMin;
+  }//the minimal homogeneous factor is a constant
+  else
+  {//the minimal homogeneous factor is not a constant
+    for (i = 1; i<=size(f2); i++)
+    {//We can forget about the first coefficient now. Therefore we will delete him from the list.
+      f2[i] = delete(f2[i],1);
+      if(size(f2[i])==1)
+      {//trivial thing
+        for (j = 1; j<=size(coeffTuplesMin); j++)
+        {
+          pqmin = pqmin + list(list(coeffTuplesMin[j][1],coeffTuplesMin[j][2]*f2[i][1]));
+          pqmin = pqmin + list(list(coeffTuplesMin[j][1]*f2[i][1],coeffTuplesMin[j][2]));
+        }
+        f2 = delete(f2,i);
+        continue;
+      }
+    }//We can forget about the first coefficient now. Therefore we will delete him from the list.
+    if(size(f2)>0)
+    {
+      tempList = getAllCombOfHomogFact(f2);
+      for (i = 1; i<=size(tempList); i++)
+      {//Every combination combined with the coefficient possibilities
+        for (j = 1; j<=size(coeffTuplesMin); j++)
+        {//iterating through the possible coefficient choices
+          pqmin = pqmin + list(list(coeffTuplesMin[j][1]*tempList[i][1],
+                                    coeffTuplesMin[j][2]*tempList[i][2]));
+        }//iterating through the possible coefficient choices
+      }//Every combination combined with the coefficient possibilities
+      for (i = 1; i<=size(coeffTuplesMin); i++)
+      {
+        pqmin = pqmin + list(list(coeffTuplesMin[i][1],minh/coeffTuplesMin[i][1]));
+        pqmin = pqmin + list(list(minh/coeffTuplesMin[i][2],coeffTuplesMin[i][2]));
+      }
+    }
+  }//the minimal homogeneous factor is not a constant
+  //and now we combine them together to obtain all possibilities.
+  for (i = 1; i<=size(pqmax); i++)
+  {//iterate over the maximal homogeneous combination possibilities
+    for (j = 1; j<=size(pqmin); j++)
+    {//iterate over the minimal homogeneous combiniation possibilities
+      if (deg(pqmax[i][1], ivm11)>=deg(pqmin[j][1],ivm11) and deg(pqmax[i][2],
+                                                                  ivm11)>=deg(pqmin[j][2],ivm11))
+      {
+        if (pqmax[i][1]+pqmin[j][1]!=0 and pqmax[i][2]+pqmin[j][2]!=0)
+        {
+          if (deg(h,ivm11)<=deg(h-(pqmax[i][1]+pqmin[j][1])*(pqmax[i][2]+pqmin[j][2]),ivm11))
+          {
+            j++;
+            continue;
+          }
+          if (deg(h,iv1m1)<=deg(h-(pqmax[i][1]+pqmin[j][1])*(pqmax[i][2]+pqmin[j][2]),iv1m1))
+          {
+            j++;
+            continue;
+          }
+          result = result +list(list(pqmax[i][1]+pqmin[j][1],pqmax[i][2]+pqmin[j][2]));
+        }
+      }
+    }//iterate over the minimal homogeneous combiniation possibilities
+  }//iterate over the maximal homogeneous combination possibilities
+  //Now deleting double entries
+  result = delete_dublicates_noteval(result);
+  return(result);
+}//proc computeCombinationsMinMaxHomog
+
+static proc computeCombinationsMinMaxHomogNthWeyl(poly h)
+"Input: A polynomial h in the nth Weyl Algebra
+Output: Combinations of the form (p_max + p_min)(q_max + q_min), such that p_max, p_min,
+ q_max and q_min are homogeneous and p_max*q_max equals the maximal homogeneous
+ part in h, and p_max * q_max equals the minimal homogeneous part in h.
+
+GENERAL ASSUMPTIONS:
+- h is not homogeneous.
+"{//proc computeCombinationsMinMaxHomogNthWeyl
+  int p=printlevel-voice+2; // for dbprint
+  string dbprintWhitespace = "";
+  int i;
+  int j;
+  for (i = 1; i<=voice;i++)
+  {dbprintWhitespace = dbprintWhitespace + " ";}
+  list hList = homogDistributionNthWeyl(h);
+  dbprint(p,dbprintWhitespace + "Computing maximal and minimal homogeneous part of h");
+  poly maxh = hList[size(hList)][2];
+  poly minh = hList[1][2];
+  dbprint(p,dbprintWhitespace + "Done. They are:");
+  dbprint(p,string(maxh) + ", " + string(minh));
+  dbprint(p, dbprintWhitespace + "Computing their respective homogeneous factorizations");
+  list f1 = homogfacNthWeyl_all(maxh);
+  list f2 = homogfacNthWeyl_all(minh);
+  dbprint(p,dbprintWhitespace + "Done.");
+  list result = list();
+  list pqmax = list();
+  list pqmin = list();
+  list tempList = list();
+  //First, we are going to deal with our most hated guys: The Coefficients.
+  //
+  dbprint(p,dbprintWhitespace + "We get all combinations for the coefficient of the
+maximal homogeneous part");
+  list coeffTuplesMax = getAllCoeffTuplesComb(factorizeInt(number(f1[1][1])));
+  //We can assume without loss of generality, that p_max has a
+  //nonnegative leading coefficient
+  for (i = 1; i<=size(coeffTuplesMax);i++)
+  {//Deleting all tuples with negative entries for p_max
+    if (coeffTuplesMax[i][1]<0)
+    {
+      coeffTuplesMax = delete(coeffTuplesMax,i);
+      continue;
+    }
+  }//Deleting all tuples with negative entries for p_max
+  dbprint(p,dbprintWhitespace + "Done. The Combinations are:");
+  dbprint(p,coeffTuplesMax);
+  dbprint(p,dbprintWhitespace + "We get all combinations for the coefficient of the
+minimal homogeneous part");
+  list coeffTuplesMin = getAllCoeffTuplesComb(factorizeInt(number(f2[1][1])));
+  dbprint(p,dbprintWhitespace + "Done. The Combinations are:");
+  dbprint(p,coeffTuplesMin);
+  //Now, we will be actally dealing with the Combinations.
+  //Let's start with the pqmax
+  if (size(f1[1]) == 1)
+  {//the maximal homogeneous factor is a constant
+    dbprint(p,dbprintWhitespace + "the maximal homogeneous factor is a constant.");
+    pqmax = coeffTuplesMax;
+  }//the maximal homogeneous factor is a constant
+  else
+  {//the maximal homogeneous factor is not a constant
+    dbprint(p,dbprintWhitespace + "Deleting the first list entry in each list (constant factor).");
+    for (i = 1; i<=size(f1); i++)
+    {//We can forget about the first coefficient now. Therefore we will delete him from the list.
+      f1[i] = delete(f1[i],1);
+      if(size(f1[i])==1)
+      {//trivial thing
+        for (j = 1; j<=size(coeffTuplesMax); j++)
+        {
+          pqmax = pqmax + list(list(coeffTuplesMax[j][1],coeffTuplesMax[j][2]*f1[i][1]));
+          pqmax = pqmax + list(list(coeffTuplesMax[j][1]*f1[i][1],coeffTuplesMax[j][2]));
+        }
+        f1 = delete(f1,i);
+        continue;
+      }//trivial thing
+    }//We can forget about the first coefficient now. Therefore we will delete him from the list.
+    dbprint(p,dbprintWhitespace + "Done.");
+    dbprint(p,dbprintWhitespace + "Putting all possible pre-coefficients
+ besides the entries in pqmax.");
+    if (size(f1)>0)
+    {
+      tempList = getAllCombOfHomogFact(f1);
+      for (i = 1; i<=size(tempList); i++)
+      {//Every combination combined with the coefficient possibilities
+        for (j = 1; j<=size(coeffTuplesMax); j++)
+        {//iterating through the possible coefficient choices
+          pqmax = pqmax + list(list(coeffTuplesMax[j][1]*tempList[i][1],
+                                    coeffTuplesMax[j][2]*tempList[i][2]));
+        }//iterating through the possible coefficient choices
+      }//Every combination combined with the coefficient possibilities
+      for (i = 1; i<=size(coeffTuplesMax); i++)
+      {
+        pqmax = pqmax + list(list(coeffTuplesMax[i][1],maxh/coeffTuplesMax[i][1]));
+        pqmax = pqmax + list(list(maxh/coeffTuplesMax[i][2],coeffTuplesMax[i][2]));
+      }
+    }
+    dbprint(p,dbprintWhitespace + "Done.");
+  }//the maximal homogeneous factor is not a constant
+  dbprint(p, dbprintWhitespace + "Doing the same for f2");
+  //Now we go to pqmin
+  if (size(f2[1]) == 1)
+  {//the minimal homogeneous factor is a constant
+    pqmin = coeffTuplesMin;
+  }//the minimal homogeneous factor is a constant
+  else
+  {//the minimal homogeneous factor is not a constant
+    for (i = 1; i<=size(f2); i++)
+    {//We can forget about the first coefficient now. Therefore we will delete him from the list.
+      f2[i] = delete(f2[i],1);
+      if(size(f2[i])==1)
+      {//trivial thing
+        for (j = 1; j<=size(coeffTuplesMin); j++)
+        {
+          pqmin = pqmin + list(list(coeffTuplesMin[j][1],coeffTuplesMin[j][2]*f2[i][1]));
+          pqmin = pqmin + list(list(coeffTuplesMin[j][1]*f2[i][1],coeffTuplesMin[j][2]));
+        }
+        f2 = delete(f2,i);
+        continue;
+      }
+    }//We can forget about the first coefficient now. Therefore we will delete him from the list.
+    if(size(f2)>0)
+    {
+      tempList = getAllCombOfHomogFact(f2);
+      for (i = 1; i<=size(tempList); i++)
+      {//Every combination combined with the coefficient possibilities
+        for (j = 1; j<=size(coeffTuplesMin); j++)
+        {//iterating through the possible coefficient choices
+          pqmin = pqmin + list(list(coeffTuplesMin[j][1]*tempList[i][1],
+                                    coeffTuplesMin[j][2]*tempList[i][2]));
+        }//iterating through the possible coefficient choices
+      }//Every combination combined with the coefficient possibilities
+      for (i = 1; i<=size(coeffTuplesMin); i++)
+      {
+        pqmin = pqmin + list(list(coeffTuplesMin[i][1],minh/coeffTuplesMin[i][1]));
+        pqmin = pqmin + list(list(minh/coeffTuplesMin[i][2],coeffTuplesMin[i][2]));
+      }
+    }
+  }//the minimal homogeneous factor is not a constant
+  dbprint(p,dbprintWhitespace + "Done.");
+  //and now we combine them together to obtain all possibilities.
+  for (i = 1; i<=size(pqmax); i++)
+  {//iterate over the maximal homogeneous combination possibilities
+    for (j = 1; j<=size(pqmin); j++)
+    {//iterate over the minimal homogeneous combiniation possibilities
+      if (degreeOfNthWeylPoly(pqmax[i][1])>=degreeOfNthWeylPoly(pqmin[j][1])
+          and degreeOfNthWeylPoly(pqmax[i][2])>=degreeOfNthWeylPoly(pqmin[j][2]))
+      {
+        if (pqmax[i][1]+pqmin[j][1]!=0 and pqmax[i][2]+pqmin[j][2]!=0)
+        {
+          if (h-(pqmax[i][1]+pqmin[j][1])*(pqmax[i][2]+pqmin[j][2])==0)
+          {
+            /*REMARK:
+              This part here is different from factoring the first Weyl algebra. As the output of
+              degreeOfNthWeylPoly is in general an intvec instead of an int, we cannot say
+              deg(0)=-1; Therefore, we need to catch the 0-case at this point, i.e.
+              min and max homog are combined equal to h.
+             */
+            result = result +list(list(pqmax[i][1]+pqmin[j][1],pqmax[i][2]+pqmin[j][2]));
+            j++;continue;
+          }
+          if (degreeOfNthWeylPoly(h)<=
+              degreeOfNthWeylPoly(h-(pqmax[i][1]+pqmin[j][1])*(pqmax[i][2]+pqmin[j][2])))
+          {
+            j++;
+            continue;
+          }
+          if (degreeOfNthWeylPolyInverted(h)<=
+              degreeOfNthWeylPolyInverted(h-(pqmax[i][1]+pqmin[j][1])*(pqmax[i][2]+pqmin[j][2])))
+          {
+            j++;
+            continue;
+          }
+          result = result +list(list(pqmax[i][1]+pqmin[j][1],pqmax[i][2]+pqmin[j][2]));
+        }
+      }
+    }//iterate over the minimal homogeneous combiniation possibilities
+  }//iterate over the maximal homogeneous combination possibilities
+  //Now deleting double entries
+  result = delete_dublicates_noteval(result);
+  return(result);
+}//proc computeCombinationsMinMaxHomogNthWeyl
+
+static proc getAllCombOfHomogFact(list l)
+"Gets called in computeCombinationsMinMaxHomog. It gets a list of different homogeneous
+factorizations of
+one homogeneous polynomial and returns the possibilities to combine them into two factors.
+Assumptions:
+- The list does not contain the first coefficient.
+- The list contains at least one list with two elements."
+{//proc getAllCombOfHomogFact
+  list result;
+  list leftAndRightHandSides;
+  int i; int j;
+  list tempset;
+  if (size(l)==1 and size(l[1])==2)
+  {
+    result = result + list(list(l[1][1],l[1][2]));
+    return(result);
+  }
+  leftAndRightHandSides = getPossibilitiesForRightSides(l);
+  for (i = 1; i<=size(leftAndRightHandSides); i++)
+  {
+    result =result+list(list(leftAndRightHandSides[i][1],product(leftAndRightHandSides[i][2][1])));
+    //tidy up the right hand sides, because, if it is just one irreducible factor, we are done
+    for (j = 1; j<=size(leftAndRightHandSides[i][2]);j++)
+    {//Tidy up right hand sides
+      if (size(leftAndRightHandSides[i][2][j])<2)
+      {//Element can be dismissed
+        leftAndRightHandSides[i][2] = delete(leftAndRightHandSides[i][2],j);
+        continue;
+      }//Element can be dismissed
+    }//Tidy up right hand sides
+    if (size(leftAndRightHandSides[i][2])>0)
+    {
+      tempset = getAllCombOfHomogFact(leftAndRightHandSides[i][2]);
+      for (j = 1; j<=size(tempset);j++)
+      {//multiplying the first factor with the left hand side
+        result = result + list(list(leftAndRightHandSides[i][1]*tempset[j][1],tempset[j][2]));
+      }//multiplying the first factor with the left hand side
+    }
+  }
+  return(result);
+}//proc getAllCombOfHomogFact
+
+static proc getPossibilitiesForRightSides(list l)
+"Given a list of different factorizations l, this function returns a list of the form
+(a,{(a_2,...,a_n)| (a,a_2,...,a_n) in A})"
+{//getPossibilitiesForRightSide
+  list templ = l;
+  list result;
+  poly firstElement;
+  list rightSides;
+  list tempRightSide;
+  int i; int j;
+  while (size(templ)>0)
+  {
+    firstElement = templ[1][1];
+    rightSides = list();
+    for (i = 1; i<= size(templ); i++)
+    {
+      if (templ[i][1] == firstElement)
+      {//save the right sides
+        tempRightSide = list();
+        for (j = 2; j<=size(templ[i]);j++)
+        {
+          tempRightSide = tempRightSide + list(templ[i][j]);
+        }
+        if (size(tempRightSide)!=0)
+        {
+          rightSides = rightSides + list(tempRightSide);
+        }
+        templ = delete(templ,i);
+        continue;
+      }//save the right sides
+    }
+    result = result + list(list(firstElement,rightSides));
+  }
+  return(result);
+}//getPossibilitiesForRightSide
+
+static proc getAllCoeffTuplesComb(list l)"
+Given the output of factorizeInt ((a_1,...,a_n),(i_1,...,i_n)) , it returns all possible tuples
+of the set {(a,b) | There exists an real N!=emptyset subset of {1,...,n}, such that
+a = prod_{i \in N}a_i, b=prod_{i \not\in N} a_i}
+Assumption: The list is sorted from smallest integer to highest.
+- it is not the factorization of 0.
+"
+{//proc getAllCoeffTuplesComb
+  list result;
+  if (l[1][1] == 0)
+  {
+    ERROR("getAllCoeffTuplesComb: Zero Coefficients as leading and Tail Coeffs?
+That is not possible. Something went wrong.");
+  }
+  if (size(l[1]) == 1)
+  {//Trivial Factorization, just 1
+    if (l[1][1] == 1)
+    {
+      return(list(list(1,1),list(-1,-1)));
+    }
+    else
+    {
+      return(list(list(-1,1),list(1,-1)));
+    }
+  }//Trivial Factorization, just 1
+  if (size(l[1]) == 2 and l[2][2]==1)
+  {//Just a prime number
+    if (l[1][1] == 1)
+    {
+      result = list(list(l[1][2],1),list(1,l[1][2]));
+      result = result + list(list(-l[1][2],-1),list(-1,-l[1][2]));
+      return(result);
+    }
+    else
+    {
+      result = list(list(l[1][2],-1),list(1,-l[1][2]));
+      result = result + list(list(-l[1][2],1),list(-1,l[1][2]));
+      return(result);
+    }
+  }//Just a prime number
+  //Now comes the interesting case: a product of primes
+  list tempPrimeFactors;
+  list tempPowersOfThem;
+  int i;
+  for (i = 2; i<=size(l[1]);i++)
+  {//Removing the starting 1 or -1 to get the N's
+    tempPrimeFactors[i-1] = l[1][i];
+    tempPowersOfThem[i-1] = l[2][i];
+  }//Removing the starting 1 or -1 to get the N's
+  list Ns = getAllSubsetsN(list(tempPrimeFactors,tempPowersOfThem));
+  list tempTuples;
+  number productOfl = multiplyFactIntOutput(l);
+  if (productOfl<0){productOfl = -productOfl;}
+  tempTuples = tempTuples + list(list(1,productOfl),list(productOfl,1));
+  for (i = 1; i<=size(Ns); i++)
+  {
+    if (productOfl/Ns[i]>Ns[i])
+    {//TODO: BEWEISEN, dass das die einzigen Combos sind
+      tempTuples = tempTuples + list(list(Ns[i],productOfl/Ns[i]),list(productOfl/Ns[i],Ns[i]));
+    }//TODO: BEWEISEN, dass das die einzigen Combos sind
+    if (productOfl/Ns[i]==Ns[i])
+    {
+      tempTuples = tempTuples + list(list(Ns[i],Ns[i]));
+    }
+  }
+  //And now, it just remains to get the -1s and 1-s correctly to the tuples
+  list tempEntry;
+  if (l[1][1] == 1)
+  {
+    for (i = 1; i<=size(tempTuples);i++)
+    {//Adding everything to result
+      tempEntry = tempTuples[i];
+      result = result + list(tempEntry);
+      result = result + list(list(-tempEntry[1], -tempEntry[2]));
+    }//Adding everyThing to Result
+  }
+  else
+  {
+    for (i = 1; i<=size(tempTuples);i++)
+    {//Adding everything to result
+      tempEntry = tempTuples[i];
+      result = result + list(list(tempEntry[1],-tempEntry[2]));
+      result = result + list(list(-tempEntry[1], tempEntry[2]));
+    }//Adding everyThing to Result
+  }
+  return(result);
+}//proc getAllCoeffTuplesComb
+
+static proc contains(list l, int elem)
+"Assumption: l is sorted"
+{//Binary Search in list
+  if (size(l)<=1)
+  {
+    if(size(l) == 0){return(0);}
+    if (l[1]!=elem){return(0);}
+    else{return(1);}
+  }
+  int imax = size(l);
+  int imin = 1;
+  int imid;
+  while(imax >= imin)
+  {
+    imid = (imin + imax)/2;
+    if (l[imid] == elem){return(1);}
+    if (l[imid] <elem) {imin = imid +1;}
+    else{imax = imid -1;}
+  }
+  return(0)
+    }//Binary Search in list
+
+static proc getAllSubsetsN(list l)
+"
+Assumptions:
+- The list is containing two lists. They can be assumed to be outputs of the function
+factorizeInt. They have at least one entry. If it is exactly one entry, the second intvec should
+contain a value at least 2.
+  "
+{
+  list primeFactors=l[1];
+  list powersOfThem = l[2];
+  int i;int j;
+  //Casting the entries to be numbers
+  for (i=1; i<=size(primeFactors); i++)
+  {
+    primeFactors[i] = number(primeFactors[i]);
+    powersOfThem[i] = number(powersOfThem[i]);
+  }
+
+  //Done
+  list result;
+  list tempPrimeFactors;
+  list tempPowersOfThem;
+  list tempset;
+  if (sum(powersOfThem) <=2)
+  {//Easy Case
+    return(list(primeFactors[1]));
+  }//Easy Case
+  if (size(primeFactors)==1)
+  {//Also Easy Case
+    for (j = 1; j<powersOfThem[1]; j++)
+    {
+      result = result + list(primeFactors[1]^j);
+    }
+    return(result);
+  }//Also Easy Case
+  for (i = 1; i<= size(primeFactors); i++)
+  {//Going through every entry
+    result = result + list(primeFactors[i]);
+    if (i == size(primeFactors))
+    {
+      for (j = 1;j<powersOfThem[i];j++)
+      {
+        result = result + list (primeFactors[i]^j);
+      }
+      break;
+    }
+    if (powersOfThem[i]==1)
+    {
+      for (j = i+1;j<=size(primeFactors);j++)
+      {
+        tempPrimeFactors[j-i] = primeFactors[j];
+        tempPowersOfThem[j-i] = powersOfThem[j];
+      }
+    }
+    else
+    {
+      for (j = i; j<=size(primeFactors);j++)
+      {
+        tempPrimeFactors[j-i+1] = primeFactors[j];
+        tempPowersOfThem[j-i+1] = powersOfThem[j];
+        tempPowersOfThem[1] = tempPowersOfThem[1]-1;
+      }
+    }
+    tempset = getAllSubsetsN(list(tempPrimeFactors,tempPowersOfThem));
+    for (j = 1; j<=size(tempset); j++)
+    {
+      result = result +list((tempset[j])*(primeFactors[i]));
+    }
+  }//Going through every entry
+  result = sort(result)[1];
+  result = delete_dublicates_noteval(result);
+  return(result);
+}
+
+static proc multiplyFactIntOutput(list l)
+"Given the output of factorizeInt, this method computes the product of it."
+{//proc multiplyFactIntOutput
+  int i;
+  number result = 1;
+  for (i = 1; i<=size(l[1]); i++)
+  {
+    result = result*(l[1][i])^(l[2][i]);
+  }
+  return(result);
+}//proc multiplyFactIntOutput
+
+static proc fromListToIntvec(list l)
+"Converter from List to intvec"
+{
+  intvec result; int i;
+  for (i = 1; i<=size(l); i++)
+  {
+    result[i] = l[i];
+  }
+  return(result);
+}
+
+static proc fromIntvecToList(intvec l)"
+Converter from intvec to list"
+{//proc fromIntvecToList
+  list result = list();
+  int i;
+  for (i = size(l); i>=1; i--)
+  {
+    result = insert(result, l[i]);
+  }
+  return(result);
+}//proc fromIntvecToList
+
+
+static proc factorizeInt(number n)
+"Given an integer n, factorizeInt computes its factorization. The output is a list
+containing two intvecs. The first contains the prime factors, the second its powers.
+ASSUMPTIONS:
+- n is given as integer number
+"{
+  if (n==0)
+  {return(list(list(0),list(1)));}
+  int i;
+  list temp = primefactors(n);
+  if (n<0)
+  {list result = list(list(-1),list(1));}
+  else
+  {list result = list(list(1),list(1));}
+  result[1] = result[1] + temp[1];
+  result[2] = result[2] + temp[2];
+  return(result);
+}
+
+
+static proc homogDistribution(poly h)
+"Input: A polynomial in the first Weyl Algebra.
+  Output: A two-dimensional list of the following form. Every sublist contains exactly two entries.
+   One for the Z-degree of the corresponding homogeneous part (integer), and the homogeneous
+   polynomial itself, and those sublists are oredered by ascending degree.
+   For example a call of homogDistribution(x+d+1) would have the output
+   [1]:
+     [1]:
+       -1
+     [2]:
+       x
+   [2]:
+     [1]:
+       0
+     [2]:
+       1
+   [3]:
+     [1]:
+       1
+     [2]:
+       d
+"{//homogDistribution
+  if (h == 0)
+  {//trivial case where input is 0
+    return(list(list(0,0)));
+  }//trivial case where input is 0
+  if (!isWeyl())
+  {//Our basering is not the Weyl algebra
+    ERROR("Ring was not the first Weyl algebra");
+    return(list());
+  }//Our basering is not the Weyl algebra
+  if(nvars(basering)!=2)
+  {//Our basering is the Weyl algebra, but not the first
+    ERROR("Ring is not the first Weyl algebra");
+    return(list());
+  }//Our basering is the Weyl algebra, but not the first
+  intvec ivm11 = intvec(-1,1);
+  intvec iv1m1 = intvec(1,-1);
+  poly tempH = h;
+  poly minh;
+  list result = list();
+  int nextExpectedDegree = -deg(tempH,iv1m1);
+  while (tempH != 0)
+  {
+    minh = jet(tempH,deg(tempH,iv1m1),iv1m1)-jet(tempH,deg(tempH,iv1m1)-1,iv1m1);
+    while (deg(minh,ivm11)>nextExpectedDegree)
+    {//filling empty homogeneous spaces with 0
+      result = result + list(list(nextExpectedDegree,0));
+      nextExpectedDegree = nextExpectedDegree +1;
+    }//filling empty homogeneous spaces with 0
+    result = result + list(list(deg(minh,ivm11),minh));
+    tempH = tempH - minh;
+    nextExpectedDegree = nextExpectedDegree +1;
+  }
+  return(result);
+}//homogDistribution
+
+static proc homogDistributionNthWeyl(poly h)
+"
+INPUT: A polynomial in the n-th Weyl algebra
+OUTPUT: A two-dimensional list of the following form. Every sublist contains exactly two entries.
+   One for the Z^n-degree of the corresponding homogeneous part (intvec), and the homogeneous
+   polynomial itself, and those sublists are oredered by ascending degree using lexicographical
+   ordering on Z^n. Different from homogDistribution, the 0-summands between the maximum and
+   minimum homogeneous degree are not displayed.
+   For example a call of homogDistribution(x1+d2+1) would have the output (ring is the second
+   weyl algebra with variables x1,x2,d1,d2).
+     [1]:
+       [1]:
+         [0,1]
+       [2]:
+         d2
+     [2]:
+       [1]:
+         [0,0]
+       [2]:
+         1
+     [3]:
+       [1]:
+         [-1,0]
+       [2]:
+         x1
+
+GENERAL ASSUMPTIONS:
+ - The basering is the nth Weyl algebra and has the form, that the first n variables represent
+   x1, ..., xn, and the second n variables do represent the d1, ..., dn.
+"
+{//proc homogDistributionNthWeyl
+  if (h == 0)
+  {//trivial case where input is 0
+    return(list(list(0,0)));
+  }//trivial case where input is 0
+  //TODO: BUG in nctools?
+  /* if (!isWeyl()) */
+  /* {//Our basering is not the Weyl algebra */
+  /*   ERROR("Ring was not a Weyl algebra"); */
+  /*   return(list()); */
+  /* }//Our basering is not the Weyl algebra */
+  list result;
+  poly tempH = h;
+  intvec degVec;
+  poly leadPoly;
+  while(tempH != 0)
+  {//tempH is not equal to zero ==> We have still unconsidered homogeneous summands
+    leadPoly = extractLeadingTermOfNthWeylPoly(tempH);
+    degVec   = degreeOfNthWeylPoly(tempH);
+    result = insert(result,list(degVec,leadPoly));
+    tempH = tempH - leadPoly;
+  }//tempH is not equal to zero ==> We have still unconsidered homogeneous summands
+  return(result);
+}//proc homogDistributionNthWeyl
+
+static proc extractLeadingTermOfNthWeylPoly(poly h)
+"
+INPUT:  A polynomial h in the nth Weyl algebra.
+OUTPUT: A polynomial p representing the homogeneous leading polynomial of h with respect
+        to the -1,1 grading on the polynomial nth weyl algebra.
+
+GENERAL ASSUMPTIONS:
+ - The ring given is the nth Weyl algebra and has the form, that the first n variables represent
+   x1, ..., xn, and the second n variables do represent the d1, ..., dn.
+"
+{//extractLeadingTermOfNthWeylPoly
+  poly result = 0;
+  intvec leadDeg = degreeOfNthWeylPoly(h);
+  int i; int j;
+  int isPart = 0;
+  intvec lExp;
+  for (i = 1; i <=size(h); i++)
+  {//iterating through the terms of h
+    isPart = 1;
+    lExp = leadexp(h[i]);
+    for (j = 1; j<=nvars(basering) div 2; j++)
+    {//checking if the term is part of the leading polynomial
+      if(lExp[j + nvars(basering) div 2] - lExp[j] != leadDeg[j])
+      {//Summand was not part of leading polynomial
+        isPart = 0;
+        break;
+      }//Summand was not part of leading polynomial
+    }//checking if the term is part of the leading degree
+    if (!isPart)
+    {i++; continue;}
+    else
+    {//In this case, h[i] was part of the leading polynomial
+      result = result + h[i];
+    }//In this case, h[i] was part of the leading polynomial
+  }//iterating through the terms of h
+  return(result);
+}//extractLeadingTermOfNthWeylPoly
+/*
+Test cases for this:
+ring R = 0,(x1,x2,x3,d1,d2,d3),dp;
+matrix C[6][6] = 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;
+matrix D[6][6] = 0,0,0,1,0,0,
+                 0,0,0,0,1,0,
+                 0,0,0,0,0,1,
+                 -1,0,0,0,0,0,
+                 0,-1,0,0,0,0,
+                 0,0,-1,0,0,0;
+def r = nc_algebra(C,D);
+setring(r);
+poly h = 0;
+extractLeadingTermOfNthWeylPoly(h);
+==> 0
+h = x3;
+extractLeadingTermOfNthWeylPoly(h);
+==> x3
+h = x1*x2*d1*d2 + x1^4*x2^2*x3^3*d1^4*d2^2*d3^3 + 1 + x1 + x2 + x3;
+extractLeadingTermOfNthWeylPoly(h);
+==> x1^4*x2^2*x3^3*d1^4*d2^2*d3^3+x1*x2*d1*d2+1
+h = (x1*d1)^5;
+extractLeadingTermOfNthWeylPoly(h);
+==>x1^5*d1^5+10*x1^4*d1^4+25*x1^3*d1^3+15*x1^2*d1^2+x1*d1
+ */
+
+static proc degreeOfNthWeylPoly(poly h)
+"
+INPUT: A polynomial h in the nth Weyl algebra
+OUTPUT: An intvector of size n, representing the degree of h with respect to
+        the lexicographical ordering on ZZ^n by considering the -1,1 grading
+        on the nth Weyl algebra.
+
+GENERAL ASSUMPTIONS:
+ - The ring given is the nth Weyl algebra and has the form, that the first n variables represent
+   x1, ..., xn, and the second n variables do represent the d1, ..., dn.
+"
+{//degreeOfNthWeylPoly
+  intvec result = 0:(nvars(basering) div 2);
+  int i; int j; int k;
+  int alreadySmaller;
+  intvec expVec;
+  intvec posUpdated= 0:(nvars(basering) div 2);
+  for(i = 1; i<=nvars(basering) div 2; i++)
+  {//Going through every variable to determine the max. term
+    for (j = 1; j <= size(h); j++)
+    {//Iterating over every term in h
+      alreadySmaller = 0;
+      for (k = 1; k<i; k++)
+      {//checking if h[j] is already smaller considering the higher order variables
+        expVec = leadexp(h[j]);
+        if (expVec[k+nvars(basering) div 2] - expVec[k] < result[k])
+        {//This monomial has no chance to be part of the leading monomial
+          alreadySmaller = 1;
+          break;
+        }//This monomial has no chance to be part of the leading monomial
+      }//checking if h[j] is already smaller considering the higher order variables
+      if (alreadySmaller)
+      {j++; continue;}
+      expVec = leadexp(h[j]);
+      k = expVec[nvars(basering) div 2 + i] - expVec[i];
+      if(!posUpdated[i])
+      {//update of result
+        result[i] = k;
+        posUpdated[i] = 1;
+      }//update of result
+      else
+      {//update the result only if position is smaller
+        if (result[i]<k)
+        {//We have a new maximal entry
+          result[i] = k;
+        }//We have a new maximal entry
+      }//update the result only if position is smaller
+    }//Iterating over every term in h
+  }//Going through every variable to determine the max. term
+  return(result);
+}//degreeOfNthWeylPoly
+/*
+Test sets for this:
+ring R = 0,(x1,x2,x3,d1,d2,d3),dp;
+matrix C[6][6] = 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;
+matrix D[6][6] = 0,0,0,1,0,0,
+                 0,0,0,0,1,0,
+                 0,0,0,0,0,1,
+                 -1,0,0,0,0,0,
+                 0,-1,0,0,0,0,
+                 0,0,-1,0,0,0;
+def r = nc_algebra(C,D);
+setring(r);
+poly h = 0;
+degreeOfNthWeylPoly(h);
+==> 0,0,0
+h = x1 + d1 + x1*d2 + d1*d2;
+degreeOfNthWeylPoly(h);
+==> 1,1,0
+h = x1^5 + d1 + x1*d2 + d1*d2;
+degreeOfNthWeylPoly(h);
+==> 1,1,0
+h = 1;
+degreeOfNthWeylPoly(h);
+==> 0,0,0
+h = x1*d1;
+degreeOfNthWeylPoly(h);
+==> 0,0,0
+h = x2*d2;
+degreeOfNthWeylPoly(h);
+==> 0,0,0
+h = x3*d3;
+degreeOfNthWeylPoly(h);
+==> 0,0,0
+ */
+
+static proc degreeOfNthWeylPolyInverted(poly h)
+"
+INPUT: A polynomial h in the nth Weyl algebra
+OUTPUT: An intvector of size n, representing the degree of h with respect to
+        the lexicographical ordering on ZZ^n by considering the 1,-1 grading
+        on the nth Weyl algebra.
+
+GENERAL ASSUMPTIONS:
+ - The ring given is the nth Weyl algebra and has the form, that the first n variables represent
+   x1, ..., xn, and the second n variables do represent the d1, ..., dn.
+"
+{//degreeOfNthWeylPoly
+  intvec result = 0:(nvars(basering) div 2);
+  int i; int j; int k;
+  int alreadySmaller;
+  intvec expVec;
+  intvec posUpdated= 0:(nvars(basering) div 2);
+  for(i = 1; i<=nvars(basering) div 2; i++)
+  {//Going through every variable to determine the max. term
+    for (j = 1; j <= size(h); j++)
+    {//Iterating over every term in h
+      alreadySmaller = 0;
+      for (k = 1; k<i; k++)
+      {//checking if h[j] is already smaller considering the higher order variables
+        expVec = leadexp(h[j]);
+        if (-expVec[k+nvars(basering) div 2] + expVec[k] < result[k])
+        {//This monomial has no chance to be part of the leading monomial
+          alreadySmaller = 1;
+          break;
+        }//This monomial has no chance to be part of the leading monomial
+      }//checking if h[j] is already smaller considering the higher order variables
+      if (alreadySmaller)
+      {j++; continue;}
+      expVec = leadexp(h[j]);
+      k = -expVec[nvars(basering) div 2 + i] + expVec[i];
+      if(!posUpdated[i])
+      {//update of result
+        result[i] = k;
+        posUpdated[i] = 1;
+      }//update of result
+      else
+      {//update the result only if position is smaller
+        if (result[i]<k)
+        {//We have a new maximal entry
+          result[i] = k;
+        }//We have a new maximal entry
+      }//update the result only if position is smaller
+    }//Iterating over every term in h
+  }//Going through every variable to determine the max. term
+  return(result);
+}//degreeOfNthWeylPoly
+
+static proc countHomogParts(poly h)
+"Counts the homogeneous parts of a given polynomial h"
+{
+  int i;
+  list outPutHD = homogDistribution(h);
+  int result = 0;
+  for (i = 1; i <=size(outPutHD); i++)
+  {
+    if (outPutHD[i][2] != 0){result++;}
+  }
+  return(result);
+}
+
+
+//==================================================
+/*Singular has no way implemented to test polynomials
+  for homogenity with respect to a weight vector.
+  The following procedure does exactly this*/
+static proc homogwithorder(poly h, intvec weights)
+{//proc homogwithorder
+  if(size(weights) != nvars(basering))
+  {//The user does not know how many variables the current ring has
+    return(0);
+  }//The user does not know how many variables the current ring has
+  int i;
+  int dofp = deg(h,weights); //degree of polynomial
+  for (i = 1; i<=size(h);i++)
+  {
+    if (deg(h[i],weights)!=dofp)
+    {
+      return(0);
+    }
+  }
+  return(1);
+}//proc homogwithorder
+
+static proc homogwithorderNthWeyl(poly h)
+"
+INPUT: A polynomial h in the nth Weyl algebra
+OUTPUT: Determines whether the given polynomial is homogeneous with respect to
+        the -1,1 order on the nth Weyl algebra. If so, the function returns 1,
+        if not, it returns 0.
+
+GENERAL ASSUMPTIONS:
+ - The basering is the nth Weyl algebra and has the form, that the first n variables represent
+   x1, ..., xn, and the second n variables do represent the d1, ..., dn.
+"
+{//homogwithorderNthWeyl
+  poly temp = extractLeadingTermOfNthWeylPoly(h);
+  if (h!=temp)
+  {//In this case, h has more than one homogeneous summand
+    return(0);
+  }//In this case, h has more than one homogeneous summand
+  else
+  {//Our polynomial was homogeneous
+    return(1);
+  }//Our polynomial was homogeneous
+}//homogwithorderNthWeyl
+
+//==================================================
+//Testfac: Given a list with different factorizations of
+// one polynomial, the following procedure checks
+// whether they all refer to the same polynomial.
+// If they do, the output will be a list, that contains
+// the product of each factorization. If not, the empty
+// list will be returned.
+// If the optional argument # is given (i.e. the polynomial
+// which is factorized by the elements of the given list),
+// then we look, if the entries are factorizations of p
+// and if not, a list with the products subtracted by p
+// will be returned
+proc testNCfac(list l, list #)
+"USAGE: testNCfac(l[,p,b]); l is a list, p is an optional poly, b is 1 or 0
+RETURN: Case 1: No optional argument. In this case the output is 1, if the
+  entries in the given list represent the same polynomial or 0
+  otherwise.
+ Case 2: One optional argument p is given. In this case it returns 1,
+  if all the entries in l are factorizations of p, otherwise 0.
+ Case 3: Second optional b is given. In this case a list is returned
+  containing the difference between the product of each entry in
+  l and p.
+ASSUME: basering is the first Weyl algebra, the entries of l are polynomials
+PURPOSE: Checks whether a list of factorizations contains factorizations of
+  the same element in the first Weyl algebra
+THEORY: @code{testNCfac} multiplies out each factorization and checks whether
+ each factorization was a factorization of the same element.
+@* - if there is only a list given, the output will be 0, if it
+     does not contain factorizations of the same element. Otherwise the output
+     will be 1.
+@* - if there is a polynomial in the second argument, then the procedure checks
+     whether the given list contains factorizations of this polynomial. If it
+     does, then the output depends on the third argument. If it is not given,
+     the procedure will check whether the factorizations in the list
+     l are associated to this polynomial and return either 1 or 0, respectively.
+     If the third argument is given, the output will be a list with
+     the length of the given one and in each entry is the product of one
+     entry in l subtracted by the polynomial.
+EXAMPLE: example testNCfac; shows examples
+SEE ALSO: facFirstWeyl, facSubWeyl, facFirstShift
+"{//proc testfac
+  int p = printlevel - voice + 2;
+  int i;
+  string dbprintWhitespace = "";
+  for (i = 1; i<=voice;i++)
+  {dbprintWhitespace = dbprintWhitespace + " ";}
+  dbprint(p,dbprintWhitespace + " Checking the input");
+  if (size(l)==0)
+  {//The empty list is given
+    dbprint(p,dbprintWhitespace + " Given list was empty");
+    return(list());
+  }//The empty list is given
+  if (size(#)>2)
+  {//We want max. two optional arguments
+    dbprint(p,dbprintWhitespace + " More than two optional arguments");
+    return(list());
+  }//We want max. two optional arguments
+  dbprint(p,dbprintWhitespace + " Done");
+  list result;
+  int j;
+  if (size(#)==0)
+  {//No optional argument is given
+    dbprint(p,dbprintWhitespace + " No optional arguments");
+    int valid = 1;
+    for (i = size(l);i>=1;i--)
+    {//iterate over the elements of the given list
+      if (size(result)>0)
+      {
+        if (product(l[i])!=result[size(l)-i])
+        {
+          valid = 0;
+          break;
+        }
+      }
+      result = insert(result, product(l[i]));
+    }//iterate over the elements of the given list
+    return(valid);
+  }//No optional argument is given
+  else
+  {
+    dbprint(p,dbprintWhitespace + " Optional arguments are given.");
+    int valid = 1;
+    for (i = size(l);i>=1;i--)
+    {//iterate over the elements of the given list
+      if (product(l[i])!=#[1])
+      {
+        valid = 0;
+      }
+      result = insert(result, product(l[i])-#[1]);
+    }//iterate over the elements of the given list
+    if(size(#)==2)
+    {
+      dbprint(p,dbprintWhitespace + " A third argument is given. Output is a list now.");
+      return(result);
+    }
+    return(valid);
+  }
+}//proc testfac
+example
+{
+  "EXAMPLE:";echo=2;
+  ring r = 0,(x,y),dp;
+  def R = nc_algebra(1,1);
+  setring R;
+  poly h = (x^2*y^2+1)*(x^2);
+  def t1 = facFirstWeyl(h);
+  //fist a correct list
+  testNCfac(t1);
+  //now a correct list with the factorized polynomial
+  testNCfac(t1,h);
+  //now we put in an incorrect list without a polynomial
+  t1[3][3] = y;
+  testNCfac(t1);
+  // take h as additional input
+  testNCfac(t1,h);
+  // take h as additional input and output list of differences
+  testNCfac(t1,h,1);
+}
+//==================================================
+//Procedure facSubWeyl:
+//This procedure serves the purpose to compute a
+//factorization of a given polynomial in a ring, whose subring
+//is the first Weyl algebra. The polynomial must only contain
+//the two arguments, which are also given by the user.
+
+proc facSubWeyl(poly h, poly X, poly D)
+"USAGE:  facSubWeyl(h,x,y); h, X, D polynomials
+RETURN: list
+ASSUME: X and D are variables of a basering, which satisfy DX = XD +1.
+@* That is,  they generate the copy of the first Weyl algebra in a basering.
+@* Moreover, h is a polynomial in X and D only.
+PURPOSE: compute factorizations of the polynomial, which depends on X and D.
+EXAMPLE: example facSubWeyl; shows examples
+SEE ALSO: facFirstWeyl, testNCfac, facFirstShift
+"{
+  int p = printlevel - voice + 2;
+  dbprint(p," Start initial Checks of the input.");
+  // basering can be anything having a Weyl algebra as subalgebra
+  def @r = basering;
+  //We begin to check the input for assumptions
+  // which are: X,D are vars of the basering,
+  if ( (isVar(X)!=1) || (isVar(D)!=1) || (size(X)>1) || (size(D)>1) ||
+       (leadcoef(X) != number(1)) || (leadcoef(D) != number(1)) )
+  {
+    ERROR("expected pure variables as generators of a subalgebra");
+  }
+  // Weyl algebra:
+  poly w = D*X-X*D-1; // [D,X]=1
+  poly u = D*X-X*D+1; // [X,D]=1
+  if (u*w!=0)
+  {
+    // that is no combination gives Weyl
+    ERROR("2nd and 3rd argument do not generate a Weyl algebra");
+  }
+  // one of two is correct
+  int isReverted = 0; // Reverted Weyl if dx=xd-1 holds
+  if (u==0)
+  {
+    isReverted = 1;
+  }
+  // else: do nothing
+  // DONE with assumptions, Input successfully checked
+  dbprint(p," Successful");
+  intvec lexpofX = leadexp(X);
+  intvec lexpofD = leadexp(D);
+  int varnumX=1;
+  int varnumD=1;
+  while(lexpofX[varnumX] != 1)
+  {
+    varnumX++;
+  }
+  while(lexpofD[varnumD] != 1)
+  {
+    varnumD++;
+  }
+  /* VL : to add printlevel stuff */
+  dbprint(p," Change positions of the two variables in the list, if needed");
+  if (isReverted)
+  {
+    ring firstweyl = 0,(var(varnumD),var(varnumX)),dp;
+    def Firstweyl = nc_algebra(1,1);
+    setring Firstweyl;
+    ideal M = 0:nvars(@r);
+    M[varnumX]=var(2);
+    M[varnumD]=var(1);
+    map Q = @r,M;
+    poly h= Q(h);
+  }
+  else
+  { // that is unReverted
+    ring firstweyl = 0,(var(varnumX),var(varnumD)),dp;
+    def Firstweyl = nc_algebra(1,1);
+    setring Firstweyl;
+    poly h= imap(@r,h);
+  }
+  dbprint(p," Done!");
+  list result = facFirstWeyl(h);
+  setring @r;
+  list result;
+  if (isReverted)
+  {
+    // map swap back
+    ideal M; M[1] = var(varnumD); M[2] = var(varnumX);
+    map S = Firstweyl, M;
+    result = S(result);
+  }
+  else
+  {
+    // that is unReverted
+    result = imap(Firstweyl,result);
+  }
+  return(result);
+}//proc facSubWeyl
+example
+{
+  "EXAMPLE:";echo=2;
+  ring r = 0,(x,y,z),dp;
+  matrix D[3][3]; D[1,3]=-1;
+  def R = nc_algebra(1,D); // x,z generate Weyl subalgebra
+  setring R;
+  poly h = (x^2*z^2+x)*x;
+  list fact1 = facSubWeyl(h,x,z);
+  // compare with facFirstWeyl:
+  ring s = 0,(z,x),dp;
+  def S = nc_algebra(1,1); setring S;
+  poly h = (x^2*z^2+x)*x;
+  list fact2 = facFirstWeyl(h);
+  map F = R,x,0,z;
+  list fact1 = F(fact1); // it is identical to list fact2
+  testNCfac(fact1); // check the correctness again
+}
+//==================================================
+
+//==================================================
+//************From here: Shift-Algebra**************
+//==================================================
+//==================================================*
+//one factorization of a homogeneous polynomial
+//in the first Shift Algebra
+static proc homogfacFirstShift(poly h)
+{//proc homogfacFirstShift
+  int p=printlevel-voice+2; //for dbprint
+  def r = basering;
+  poly hath;
+  intvec iv01 = intvec(0,1);
+  int i; int j;
+  string dbprintWhitespace = "";
+  for (i = 1; i<=voice;i++)
+  {dbprintWhitespace = dbprintWhitespace + " ";}
+  if (!homogwithorder(h,iv01))
+  {//The given polynomial is not homogeneous
+    ERROR("The given polynomial is not homogeneous.");
+    return(list());
+  }//The given polynomial is not homogeneous
+  if (h==0)
+  {
+    return(list(0));
+  }
+  list result;
+  int m = deg(h,iv01);
+  dbprint(p,dbprintWhitespace+" exclude the homogeneous part of deg. 0");
+  if (m>0)
+  {//The degree is not zero
+    hath = lift(var(2)^m,h)[1,1];
+    for (i = 1; i<=m;i++)
+    {
+      result = result + list(var(2));
+    }
+  }//The degree is not zero
+  else
+  {//The degree is zero
+    hath = h;
+  }//The degree is zero
+  ring tempRing = 0,(x),dp;
+  setring tempRing;
+  map thetamap = r,x,1;
+  poly hath = thetamap(hath);
+  dbprint(p,dbprintWhitespace+" Factorize it using commutative factorization.");
+  list azeroresult = factorize(hath);
+  list azeroresult_return_form;
+  for (i = 1; i<=size(azeroresult[1]);i++)
+  {//rewrite the result of the commutative factorization
+    for (j = 1; j <= azeroresult[2][i];j++)
+    {
+      azeroresult_return_form = azeroresult_return_form + list(azeroresult[1][i]);
+    }
+  }//rewrite the result of the commutative factorization
+  setring(r);
+  map finalmap = tempRing,var(1);
+  list tempresult = finalmap(azeroresult_return_form);
+  result = tempresult+result;
+  return(result);
+}//proc homogfacFirstShift
+
+//==================================================
+//Computes all possible homogeneous factorizations
+static proc homogfacFirstShift_all(poly h)
+{//proc HomogfacFirstShiftAll
+  int p=printlevel-voice+2; //for dbprint
+  intvec iv11 = intvec(1,1);
+  if (deg(h,iv11) <= 0 )
+  {//h is a constant
+    return(list(list(h)));
+  }//h is a constant
+  def r = basering;
+  list one_hom_fac; //stands for one homogeneous factorization
+  int i; int j; int k;
+  string dbprintWhitespace = "";
+  for (i = 1; i<=voice;i++)
+  {dbprintWhitespace = dbprintWhitespace + " ";}
+  int shiftcounter;
+  //Compute again a homogeneous factorization
+  dbprint(p,dbprintWhitespace+" Computing one homog. factorization of the polynomial");
+  one_hom_fac = homogfacFirstShift(h);
+  one_hom_fac = delete(one_hom_fac,1);
+  if (size(one_hom_fac) == 0)
+  {//there is no homogeneous factorization or the polynomial was not homogeneous
+    return(list());
+  }//there is no homogeneous factorization or the polynomial was not homogeneous
+  dbprint(p,dbprintWhitespace+" Permuting the 0-homogeneous part with the s");
+  list result = permpp(one_hom_fac);
+  for (i = 1; i<=size(result);i++)
+  {
+    shiftcounter = 0;
+    for (j = 1; j<=size(result[i]); j++)
+    {
+      if (result[i][j]==var(2))
+      {
+        shiftcounter++;
+      }
+      else
+      {
+        result[i][j] = subst(result[i][j], var(1), var(1)-shiftcounter);
+      }
+    }
+    result[i] = insert(result[i],1);
+  }
+  dbprint(p,dbprintWhitespace+" Deleting double entries in the resulting list");
+  result = delete_dublicates_noteval(result);
+  return(result);
+}//proc HomogfacFirstShiftAll
+
+//==================================================
+//factorization of the first Shift Algebra
+static proc facFirstShift_old(poly h)
+"USAGE: facFirstShift(h); h a polynomial in the first shift algebra
+RETURN: list
+PURPOSE: compute all factorizations of a polynomial in the first shift algebra
+THEORY: Implements the new algorithm by A. Heinle and V. Levandovskyy, see the thesis of A. Heinle
+ASSUME: basering is the first shift algebra
+NOTE: Every entry of the output list is a list with factors for one possible factorization.
+EXAMPLE: example facFirstShift; shows examples
+SEE ALSO: testNCfac, facFirstWeyl, facSubWeyl
+"{//facFirstShift_old
+  int p = printlevel - voice + 2;
+  int i;
+  string dbprintWhitespace = "";
+  for (i = 1; i<=voice;i++)
+  {dbprintWhitespace = dbprintWhitespace + " ";}
+  dbprint(p,dbprintWhitespace +" Checking the input.");
+  if(nvars(basering)!=2)
+  {//Our basering is the Shift algebra, but not the first
+    ERROR("Basering is not the first shift algebra");
+    return(list());
+  }//Our basering is the Shift algebra, but not the first
+  def r = basering;
+  setring r;
+  list LR = ringlist(r);
+  number @n = leadcoef(LR[5][1,2]);
+  poly @p = LR[6][1,2];
+  if  ( @n!=number(1) )
+  {
+    ERROR("Basering is not the first shift algebra");
+    return(list());
+  }
+  dbprint(p,dbprintWhitespace +" Done");
+  list result = list();
+  int j; int k; int l; //counter
+  // create a ring with the ordering which makes shift algebra
+  // graded
+  // def r = basering; // done before
+  ring tempRing = LR[1][1],(x,s),(a(0,1),Dp);
+  def tempRingnc = nc_algebra(1,s);
+  setring r;
+  // information on relations
+  if (@p == -var(1)) // reverted shift algebra
+  {
+    dbprint(p,dbprintWhitespace +" Reverted shift algebra. Swaping variables in Ringlist");
+    setring(tempRingnc);
+    map transf = r, var(2), var(1);
+    setring(r);
+    map transfback = tempRingnc, var(2),var(1);
+    //    result = transfback(resulttemp);
+  }
+  else
+  {
+    if ( @p == var(2)) // usual shift algebra
+    {
+      setring(tempRingnc);
+      map transf = r, var(1), var(2);
+      //    result = facshift(h);
+      setring(r);
+      map transfback = tempRingnc, var(1),var(2);
+    }
+    else
+    {
+      ERROR("Basering is not the first shift algebra");
+      return(list());
+    }
+  }
+  // main calls
+  setring(tempRingnc);
+  dbprint(p,dbprintWhitespace +" Factorize the given polynomial with the subroutine sFacShift");
+  list resulttemp = sFacShift(transf(h));
+  dbprint(p,dbprintWhitespace +" Successful");
+  setring(r);
+  result = transfback(resulttemp);
+  return( delete_dublicates_noteval(result) );
+}//facFirstShift_old
+
+
+proc facFirstShift(poly h)
+"USAGE: facFirstShift(h); h a polynomial in the first shift algebra
+RETURN: list
+PURPOSE: compute all factorizations of a polynomial in the first shift algebra
+THEORY: This function is a wrapper for facShift. It exists to make this library downward-compatible
+        with older versions.
+ASSUME: basering is the first shift algebra
+NOTE: Every entry of the output list is a list with factors for one possible factorization.
+EXAMPLE: example facFirstShift; shows examples
+SEE ALSO: testNCfac, facFirstWeyl, facSubWeyl
+"{//facFirstShift
+  return(facShift(h));
+}//facFirstShift
+example
+{
+  "EXAMPLE:";echo=2;
+  ring R = 0,(x,s),dp;
+  def r = nc_algebra(1,s);
+  setring(r);
+  poly h = (s^2*x+x)*s;
+  facFirstShift(h);
+}
+
+proc facShift(poly h)
+"USAGE: facShift(h); h a polynomial in the n'th shift algebra
+RETURN: list
+PURPOSE: compute all factorizations of a polynomial in the nth shift
+         algebra
+THEORY: h is mapped to the $n$th Weyl algebra and then factorized
+        there. The factorizations are mapped back (S_n in subalgebra
+        of Weyl algebra).
+ASSUME: basering is the nth shift algebra
+NOTE: Every entry of the output list is a list with factors for one possible factorization.
+EXAMPLE: example facFirstShift; shows examples
+SEE ALSO: testNCfac, facFirstWeyl, facSubWeyl
+"{//facShift
+  //Definition of printlevel variable
+  int p = printlevel-voice+2;
+  int i;
+  string dbprintWhitespace = "";
+  for (i = 1; i<=voice;i++)
+  {dbprintWhitespace = dbprintWhitespace + " ";}
+  dbprint(p,dbprintWhitespace +" Checking if the given algebra is a Shift algebra");
+  //Redefine the ring in my standard form
+  if (!ncfactor_isShift())
+  {//Our basering is not the shift algebra
+    ERROR("Ring was not a Shift algebra");
+    return(list());
+  }//Our basering is not the Shift algebra
+  dbprint(p,dbprintWhitespace +" Successful");
+  //A last check before we start the real business: Is h maybe just
+  //dependable on commutative variables?
+  if (isInCommutativeSubRing(h))
+  {//h is in a commutative subring
+    list hdepvars;
+    intvec tempIntVec;
+    for (i = 1; i<=nvars(basering) ; i++)
+    {
+      tempIntVec = 0:nvars(basering);
+      tempIntVec[i] = 1;
+      if (deg(h,tempIntVec)>0)
+      {
+        hdepvars = hdepvars + list(var(i));
+      }
+    }
+    if (size(hdepvars) ==0)
+    {//We just have a constant
+      return(list(list(h)));
+    }//We just have a constant
+    dbprint(p,dbprintWhitespace+"Polynomial was given commutative subring.
+Performing commutative factorization.");
+    def r = basering;
+    def rList = ringlist(basering);
+    rList = delete(rList,5);
+    rList = delete(rList,5);
+    def tempRing = ring(rList);
+    setring(tempRing);
+    poly h = imap(r,h);
+    list tempResult = factorize(h);
+    list result = list(list());
+    int j;
+    for (i = 1; i<=size(tempResult[1]); i++)
+    {
+      for (j = 1; j<=tempResult[2][i]; j++)
+      {
+        result[1] = result[1] + list(tempResult[1][i]);
+      }
+    }
+    //mapping back
+    setring(r);
+    def result = imap(tempRing,result);
+    dbprint(p,dbprintWhitespace+"result:");
+    dbprint(p,result);
+    dbprint(p,dbprintWhitespace+"Computing all permutations of this factorization");
+    poly constantFactor = result[1][1];
+    result[1] = delete(result[1],1);//Deleting the constant factor
+    result=permpp(result[1]);
+    for (i = 1; i<=size(result);i++)
+    {//Insert constant factor
+      result[i] = insert(result[i],constantFactor);
+    }//Insert constant factor
+    dbprint(p,dbprintWhitespace+"Done.");
+    return(result);
+  }//h is in a commutative subring
+  dbprint(p,dbprintWhitespace +" Successful");
+  list result = list();
+  int j; int k; int l; //counter
+  if (!checkIfProperNthShift())
+  {//The given ring was not a proper nth shift algebra
+    dbprint(p,dbprintWhitespace +" positions of the variables have to be switched");
+    dbprint(p,dbprintWhitespace + "Constructing the proper ring.");
+    def r = basering;
+    list tempRingList = ringlist(r);
+    tempRingList = delete(tempRingList,6);
+
+    list the_vars;
+    for (i = 1; i<=nvars(r); i++)
+    {the_vars[i] = var(i);}
+    int maybeDInWrongPos;
+    poly tempVariable;
+    for (i = 1; i<=size(the_vars) div 2; i++)
+    {//Swapping the variables as needed
+      maybeDInWrongPos = 1;
+      if (the_vars[i + size(the_vars) div 2]*the_vars[i]
+          -the_vars[i]*the_vars[i + size(the_vars) div 2]
+          == the_vars[i + size(the_vars) div 2])
+      {
+        i++; continue;
+      }
+      //If we enter this line, there is a break with our property
+      //condition
+      for (j = i+1; j<=size(the_vars); j++)
+      {
+        if (the_vars[j]*the_vars[i]-the_vars[i]*the_vars[j]==the_vars[j])
+        {//In this case, we matched a var x to a repective s
+          tempVariable = the_vars[i + size(the_vars) div 2];
+          the_vars[i + size(the_vars) div 2] = the_vars[j];
+          the_vars[j] = tempVariable;
+          maybeDInWrongPos = 0;
+          break;
+        }//In this case, we matched a var x to a repective s
+      }
+      if (maybeDInWrongPos)
+      {//var(i) is actually a s, not an x
+        print("i has to be pushed to the end.");
+        tempVariable = the_vars[i];
+        the_vars = delete(the_vars, i);
+        the_vars = the_vars + list(tempVariable);
+        continue;
+      }//var(i) is actually a s, not an x
+    }//Swapping the variables as needed
+    for (i = 1; i<=size(the_vars); i++)
+    {tempRingList[2][i] = string(the_vars[i]);}
+    matrix DTemp[nvars(r)][nvars(r)];
+    for (i = 1; i<=ncols(DTemp) div 2; i++)
+    {
+      DTemp[i,i + nvars(r) div 2] = the_vars[i + nvars(r) div 2];
+    }
+    tempRingList = tempRingList + list(DTemp);
+    def tempRing = ring(tempRingList);
+    dbprint(p,dbprintWhitespace + "Done. The altered ring is the following:");
+    dbprint(p,tempRing);
+    setring(tempRing);
+    //We have to go through an intermediate ring, as there is some strange
+    //behaviour in Singular concerning the correctness of the matrix D.
+    // See http://www.singular.uni-kl.de:8002/trac/ticket/542 for details.
+    matrix DTemp = imap(r, DTemp);
+    list tempRingList2 = ringlist(tempRing);
+    tempRingList2[6]= DTemp;
+    def tempRing2 = ring(tempRingList2);
+    setring(tempRing2);
+    poly h = imap(r,h);
+    dbprint(p,dbprintWhitespace +" Successful");
+    list resulttemp = facShift(h);
+    setring(r);
+    result = imap(tempRing2,resulttemp);
+    return (result);
+  }//The given ring was not a proper nth Shift algebra
+
+  dbprint(p, dbprintWhitespace +" factorization of the polynomial with the routine sfacNthShift");
+  result = sFacNthShift(h);
+  dbprint(p,dbprintWhitespace +" Done");
+  return(result);
+}//facShift
+example
+{
+  "EXAMPLE:";echo=2;
+  ring R = 0,(x1,x2,s1,s2),dp;
+  matrix C[4][4] = 1,1,1,1,
+    1,1,1,1,
+    1,1,1,1,
+    1,1,1,1;
+  matrix D[4][4] = 0,0,s1,0,
+    0,0,0,s2,
+    -s1,0,0,0,
+    0,-s2,0,0;
+  def r = nc_algebra(C,D);
+  setring(r);
+  poly h = x1*(x1+1)*s1^2-2*x1*(x1+100)*s1+(x1+99)*(x1+100);
+  facShift(h);
+}
+
+static proc sFacShift(poly h)
+"
+USAGE: A static procedure to factorize a polynomial in the first Shift algebra, where all the
+       validity checks were made in advance.
+INPUT:  A polynomial h in the first Shift Algebra.
+OUTPUT: A list of different factorizations of h, where the factors are irreducible
+ASSUMPTIONS:
+ - The basering is the first Shift algebra and has n as first, and s as second variable, i.e. we
+   have var(2)*var(1) = var(1)*var(2)+1
+THEORY: If the given polynomial h is [0,1]-homogeneous, the routines for homogeneous factorizations
+ are called. Otherwise we map the polynomial into the first Weyl algebra (the first shift
+ algebra is a subring of the first Weyl algebra), and use facFirstWeyl to factorize it. Later
+ we map the factors back, if possible.
+"
+{//proc sFacShift
+  int p = printlevel - voice + 2;
+  int i; int j ;
+  string dbprintWhitespace = "";
+  number commonCoefficient = content(h);
+  for (i = 1; i<=voice;i++)
+  {dbprintWhitespace = dbprintWhitespace + " ";}
+  //Checking if given polynomial is homogeneous
+  if(homogwithorder(h,intvec(0,1)))
+  {//The given polynomial is [0,1]-homogeneous
+    dbprint(p,dbprintWhitespace+"The polynomial is [0,1]-homogeneous. Returning the
+homogeneous factorization");
+    return(homogfacFirstShift_all(h));
+  }//The given polynomial is [0,1]-homogeneous
+
+  //---------- Start of interesting part ----------
+
+  dbprint(p,dbprintWhitespace+"Mapping the polynomial h into the first Weyl algebra.");
+  poly temph = h/commonCoefficient;
+  def ourBaseRing = basering;
+  ring tempWeylAlgebraComm = 0,(x,d),dp;
+  def tempWeylAlgebra = nc_algebra(1,1);
+  setring(tempWeylAlgebra);
+  map shiftMap = ourBaseRing, x*d, d;
+  poly h = shiftMap(temph);
+  dbprint(p,dbprintWhitespace+"Successful! The polynomial in the Weyl algebra is "+string(h));
+  dbprint(p,dbprintWhitespace+"Factorizing the polynomial in the first Weyl algebra");
+  list factorizationInWeyl = facFirstWeyl(h);
+  dbprint(p,dbprintWhitespace+"Successful! The factorization is given by:");
+  dbprint(p,factorizationInWeyl);
+  list validCombinations;
+  dbprint(p,dbprintWhitespace+"Now we will map this back to the shift algebra and filter
+valid results");
+  //-Now we map the results back to the shift algebra. But first, we need to combine them properly.
+  for (i = 1; i<=size(factorizationInWeyl); i++)
+  {//Deleting the first Coefficient factor
+    factorizationInWeyl[i] = delete(factorizationInWeyl[i],1);
+    validCombinations = validCombinations + combineNonnegative(factorizationInWeyl[i]);
+  }//Deleting the first Coefficient factor
+  if (size(validCombinations) == 0)
+  {//There are no valid combinations, therefore we can directly say, that h is irreducible
+    setring(ourBaseRing);
+    return(list(list(commonCoefficient, h/commonCoefficient)));
+  }//There are no valid combinations, therefore we can directly say, that h is irreducible
+  validCombinations = delete_dublicates_noteval(validCombinations);
+  setring(ourBaseRing);
+  map backFromWeyl = tempWeylAlgebra, var(1),var(2);
+  list validCombinations = backFromWeyl(validCombinations);
+  for (i = 1; i<=size(validCombinations); i++)
+  {
+    for (j = 1; j<=size(validCombinations[i]);j++)
+    {
+      setring(tempWeylAlgebra);
+      fromWeylToShiftPoly(validCombinations[i][j],ourBaseRing);
+      validCombinations[i][j] = result;
+      kill result;
+      kill tempResult;
+      kill zeroPoly;
+      kill fromWeyl;
+    }
+  }
+  for (i = 1; i<=size(validCombinations); i++)
+  {//Adding the common factor in the first position of the list
+    validCombinations[i] = insert(validCombinations[i],commonCoefficient);
+  }//Adding the common factor in the first position of the list
+  dbprint(dbprintWhitespace+"Done.");
+  //mapping
+  return(validCombinations);
+}//proc sFacShift
+
+static proc sFacNthShift(poly h)
+"
+USAGE: A static procedure to factorize a polynomial in the nth Shift algebra, where all the
+       validity checks were made in advance.
+INPUT:  A polynomial h in the nth Shift Algebra.
+OUTPUT: A list of different factorizations of h, where the factors are irreducible
+ASSUMPTIONS:
+ - The basering is the nth Shift algebra and the variables are given
+ in the order (x_1, ... , x_n, s_1, ..., s_n), where s_i*x_i = (x_i+1)*s_i
+THEORY: We map the polynomial into the nth Weyl algebra (the nth shift
+ algebra is a subring of the nth Weyl algebra), and use facWeyl to factorize it. Later
+ we map the factors back, if possible.
+"
+{//proc sFacNthShift
+  int p = printlevel - voice + 2;
+  int i; int j ;
+  string dbprintWhitespace = "";
+  number commonCoefficient = content(h);
+  for (i = 1; i<=voice;i++)
+  {dbprintWhitespace = dbprintWhitespace + " ";}
+
+  //---------- Start of interesting part ----------
+
+  dbprint(p,dbprintWhitespace+"Mapping the polynomial h into the nth Weyl algebra.");
+  poly temph = h/commonCoefficient;
+  def ourBaseRing = basering;
+  ring tempWeylAlgebraComm = 0,(x(1..(nvars(ourBaseRing) div 2)),
+                                d(1..(nvars(ourBaseRing) div 2))),dp;
+  matrix C[nvars(ourBaseRing)][nvars(ourBaseRing)];
+  matrix D[nvars(ourBaseRing)][nvars(ourBaseRing)];
+  for (i = 1; i<= nvars(ourBaseRing); i++)
+  {//Filling the matrices D and C
+    for (j = 1; j<= nvars(ourBaseRing); j++)
+    {
+      C[i,j] = 1;
+      if (j == (nvars(ourBaseRing) div 2) + i)
+      {
+        D[i,j] = 1;
+      }
+      else
+      {
+        D[i,j] = 0;
+      }
+    }
+  }//Filling the matrices D and C
+  def tempWeylAlgebra = nc_algebra(C,D);
+  setring(tempWeylAlgebra);
+  ideal shiftMapIdeal;
+  for (i = 1; i<= nvars(tempWeylAlgebra) div 2; i++)
+  {
+    shiftMapIdeal[i] = x(i)*d(i);
+    shiftMapIdeal[i + (nvars(tempWeylAlgebra) div 2)] = d(i);
+  }
+  map shiftMap = ourBaseRing, shiftMapIdeal;
+  poly h = shiftMap(temph);
+  dbprint(p,dbprintWhitespace+"Successful! The polynomial in the Weyl algebra is "+string(h));
+  dbprint(p,dbprintWhitespace+"Factorizing the polynomial in the nth Weyl algebra");
+  list factorizationInWeyl = facWeyl(h);
+  dbprint(p,dbprintWhitespace+"Successful! The factorization is given by:");
+  dbprint(p,factorizationInWeyl);
+  list validCombinations;
+
+  dbprint(p,dbprintWhitespace+"Now we will map this back to the shift algebra and filter
+valid results");
+  //-Now we map the results back to the shift algebra. But first, we need to combine them properly.
+  for (i = 1; i<=size(factorizationInWeyl); i++)
+  {//Deleting the first Coefficient factor
+    factorizationInWeyl[i] = delete(factorizationInWeyl[i],1);
+    validCombinations = validCombinations + combineNonnegativeNthShift(factorizationInWeyl[i]);
+  }//Deleting the first Coefficient factor
+  if (size(validCombinations) == 0)
+  {//There are no valid combinations, therefore we can directly say, that h is irreducible
+    setring(ourBaseRing);
+    return(list(list(commonCoefficient, h/commonCoefficient)));
+  }//There are no valid combinations, therefore we can directly say, that h is irreducible
+  validCombinations = delete_dublicates_noteval(validCombinations);
+  setring(ourBaseRing);
+  ideal backFromWeylIdeal;
+  for (i = 1; i<=nvars(ourBaseRing); i++)
+  {
+    backFromWeylIdeal[i] = var(i);
+  }
+  map backFromWeyl = tempWeylAlgebra, backFromWeylIdeal;
+  list validCombinations = backFromWeyl(validCombinations);
+  for (i = 1; i<=size(validCombinations); i++)
+  {
+    for (j = 1; j<=size(validCombinations[i]);j++)
+    {
+      setring(tempWeylAlgebra);
+      fromNthWeylToNthShiftPoly(validCombinations[i][j],ourBaseRing);
+      validCombinations[i][j] = result;
+      kill result;
+      kill tempResult;
+      kill zeroPoly;
+      kill fromWeyl;
+    }
+  }
+  for (i = 1; i<=size(validCombinations); i++)
+  {//Adding the common factor in the first position of the list
+    validCombinations[i] = insert(validCombinations[i],commonCoefficient);
+  }//Adding the common factor in the first position of the list
+  dbprint(dbprintWhitespace+"Done.");
+  //mapping
+  return(validCombinations);
+}//proc sFacNthShift
+//Tests:
+//(x1^2*s1 + s2)*(x2*s1+1);
+//(x1^2 + x2)*s1*s2;
+//(x2*x1 + s1)*(x2^2 + s2*s1)
+
+static proc combineNonnegative(list l)
+"
+USAGE: In sFacShift, when we want to map back the results of the factorization of the polynomial in
+       the first Weyl algebra to the shift algebra. We need to recombine the factors such that
+       we can map it back to the shift algebra without any problems.
+INPUT: A list l containing one factorization of a polynomial in the first Weyl algebra. For example
+       for the polynomial (1+x)*(1+x+d) we would have the list [1,x+1,x+d+1].
+OUTPUT:If we can map every factor without a problem back to the shift algebra (i.e. if the smallest
+ homogeneous summand of every factor is of nonnegative degree), a list containing the same
+ list as given in the input is returned.
+ If otherwise some factors cause problems, we consider every possible combination (i.e.
+ products of the factors) and extract those where all factors have a smallest homogeneous
+ summand of nonnegative degree.
+ASSUMPTIONS:
+ - Weyl algebra is given, and we have var(2)*var(1)=var(1)*var(2) +1
+"
+{//combineNonnegative
+  int p = printlevel - voice + 2;
+  int i;
+  string dbprintWhitespace = "";
+  for (i = 1; i<=voice;i++)
+  {dbprintWhitespace = dbprintWhitespace + " ";}
+  //First the easy case: all of the factors fulfill the condition of mapping to shift:
+  dbprint(p,dbprintWhitespace+"Checking, if the given factors
+can already be mapped without a problem.");
+  int isValid = 1;
+  for (i = 1; i<=size(l);i++)
+  {//Checking for every entry if the condition is fulfilled.
+    if (deg(l[i],intvec(1,-1))>0)
+    {//Found one, where it is not fulfilled
+      isValid = 0;
+      break;
+    }//Found one, where it is not fulfilled
+  }//Checking for every entry if the condition is fulfilled.
+  dbprint(p,dbprintWhitespace+"Done.");
+  if (isValid)
+  {//We can map every factor to the shift algebra and do not need to combine anything
+    dbprint(p,dbprintWhitespace+"They can be mapped. Therefore we return them directly.");
+    return(list(l));
+  }//We can map every factor to the shift algebra and do not need to combine anything
+  dbprint(p,dbprintWhitespace+"They cannot be mapped. Looking for valid combinations.");
+  //Starting with the case, where l only consists of 1 or two elements.
+  if(size(l)<=2)
+  {//The case where we won't call the function a second time
+    if (deg(product(l),intvec(1,-1))>0)
+    {//No way of a valid combination
+      return(list());
+    }//No way of a valid combination
+    else
+    {//The product is the only possible and valid combination
+      return(list(list(product(l))));
+    }//The product is the only possible and valid combination
+  }//The case where we won't call the function a second time
+  //---------- Easy pre-stuff done. now we combine the factors.----------
+  int pos;
+  int j; int k;
+  dbprint(p,dbprintWhitespace+"Making combinations of two.");
+  list combinationsOfTwo = combinekfinlf(l,2);
+  dbprint(p,dbprintWhitespace+"Done. Now checking, if there are valid ones in between.");
+  list result;
+  list validLHS;
+  list validRHS;
+  for (i = 1; i<=size(combinationsOfTwo); i++)
+  {//go through all combinations and detect the valid ones
+    if(deg(combinationsOfTwo[i][1],intvec(1,-1))>0 or deg(combinationsOfTwo[i][2],intvec(1,-1))>0)
+    {//No chance, so no further treatment needed
+      i++;
+      continue;
+    }//No chance, so no further treatment needed
+    for (pos = 1; pos<=size(l);pos++)
+    {//find the position where the combination splits
+      if (product(l[1..pos]) == combinationsOfTwo[i][1])
+      {//Found the position
+        break;
+      }//Found the position
+    }//find the position where the combination splits
+    dbprint(p,dbprintWhitespace+"Calling combineNonnegative recursively with argument " +
+            string(list(l[1..pos])));
+    validLHS = combineNonnegative(list(l[1..pos]));
+    dbprint(p,dbprintWhitespace+"Calling combineNonnegative recursively with argument " +
+            string(list(l[pos+1..size(l)])));
+    validRHS = combineNonnegative(list(l[pos+1..size(l)]));
+    for (j = 1; j<=size(validLHS); j++)
+    {//Combining the left hand side valid combnations...
+      for (k = 1; k<=size(validRHS); k++)
+      {//... with the right hand side valid combinations
+        result = insert(result, validLHS[j]+validRHS[k]);
+      }//... with the right hand side valid combinations
+    }//Combining the left hand side valid combnations...
+  }//go through all combinations and detect the valid ones
+  result = delete_dublicates_noteval(result);
+  dbprint(p,dbprintWhitespace+"Done.");
+  return(result);
+}//combineNonnegative
+
+static proc combineNonnegativeNthShift(list l)
+"
+USAGE: In sFacNthShift, when we want to map back the results of the factorization of the polynomial
+ in the nth Weyl algebra to the shift algebra. We need to recombine the factors such that
+       we can map it back to the shift algebra without any problems.
+INPUT: A list l containing one factorization of a polynomial in the nth Weyl algebra. For example
+       for the polynomial (1+x)*(1+x+d) we would have the list [1,x+1,x+d+1].
+OUTPUT:If we can map every factor without a problem back to the shift algebra (i.e. if the smallest
+ homogeneous summand of every factor is of nonnegative degree), a list containing the same
+ list as given in the input is returned.
+ If otherwise some factors cause problems, we consider every possible combination (i.e.
+ products of the factors) and extract those where all factors have a smallest homogeneous
+ summand of nonnegative degree.
+ASSUMPTIONS:
+ - The nth Weyl algebra is given, and the variables are ordered in the form
+   (x_1, ... , x_n, d_1, ..., d_n), with d_i*x_i = x_i * d_i + 1;
+"
+{//combineNonnegative
+  int p = printlevel - voice + 2;
+  int i; int j;
+  intvec degreeOfInputPoly;
+  string dbprintWhitespace = "";
+  for (i = 1; i<=voice;i++)
+  {dbprintWhitespace = dbprintWhitespace + " ";}
+  //First the easy case: all of the factors fulfill the condition of mapping to shift:
+  dbprint(p,dbprintWhitespace+"Checking, if the given factors
+can already be mapped without a problem.");
+  int isValid = 1;
+  for (i = 1; i<=size(l);i++)
+  {//Checking for every entry if the condition is fulfilled.
+    degreeOfInputPoly = degreeOfNthWeylPolyInverted(l[i]);
+    for (j = 1; j<=size(degreeOfInputPoly); j++)
+    {//checking if each entry has positive degree
+      if (degreeOfInputPoly[j] > 0)
+      {
+        isValid = 0;
+        break;
+      }
+    }//Found one, where it is not fulfilled
+  }//Checking for every entry if the condition is fulfilled.
+  dbprint(p,dbprintWhitespace+"Done.");
+  if (isValid)
+  {//We can map every factor to the shift algebra and do not need to combine anything
+    dbprint(p,dbprintWhitespace+"They can be mapped. Therefore we return them directly.");
+    return(list(l));
+  }//We can map every factor to the shift algebra and do not need to combine anything
+  dbprint(p,dbprintWhitespace+"They cannot be mapped. Looking for valid combinations.");
+  //Starting with the case, where l only consists of 1 or two elements.
+  if(size(l)<=2)
+  {//The case where we won't call the function a second time
+    degreeOfInputPoly = degreeOfNthWeylPolyInverted(product(l));
+    for (j =1; j <= size(degreeOfInputPoly);  j++)
+    {//Checking if each entry has degree greater than zero or not
+      if (degreeOfInputPoly[j] > 0)
+      {//in this case, we can return false
+        return(list());
+      }//in this case, we can return false
+    }//Checking if each entry has degree greater than zero or not
+
+    //If we encounter this line of code, we have two or less factors,
+    //and they can be combined such that we can map it back to the nth
+    //shift algebra
+    return(list(list(product(l))));
+  }//The case where we won't call the function a second time
+  //---------- Easy pre-stuff done. now we combine the factors.----------
+  int pos;
+  int k;
+  dbprint(p,dbprintWhitespace+"Making combinations of two.");
+  list combinationsOfTwo = combinekfinlf(l,2);
+  dbprint(p,dbprintWhitespace+"Done. Now checking, if there are valid ones in between.");
+  list result;
+  list validLHS;
+  list validRHS;
+  intvec degOfInpPoly1;
+  intvec degOfInpPoly2;
+  int noChance;
+  for (i = 1; i<=size(combinationsOfTwo); i++)
+  {//go through all combinations and detect the valid ones
+    degOfInpPoly1 = degreeOfNthWeylPolyInverted(combinationsOfTwo[i][1]);
+    degOfInpPoly2 = degreeOfNthWeylPolyInverted(combinationsOfTwo[i][2]);
+    noChance = 0;
+    for (j = 1; j<=size(degOfInpPoly1); j++)
+    {
+      if (degOfInpPoly1[j] > 0 or degOfInpPoly2[j] >0)
+      {//No chance, so no further treatment needed
+        noChance = 1;
+        break;
+      }//No chance, so no further treatment needed
+    }
+    if (noChance)
+    {
+      i++;
+      continue;
+    }
+    for (pos = 1; pos<=size(l);pos++)
+    {//find the position where the combination splits
+      if (product(l[1..pos]) == combinationsOfTwo[i][1])
+      {//Found the position
+        break;
+      }//Found the position
+    }//find the position where the combination splits
+    dbprint(p,dbprintWhitespace+"Calling combineNonnegative recursively with argument " +
+            string(list(l[1..pos])));
+    validLHS = combineNonnegativeNthShift(list(l[1..pos]));
+    dbprint(p,dbprintWhitespace+"Calling combineNonnegative recursively with argument " +
+            string(list(l[pos+1..size(l)])));
+    validRHS = combineNonnegativeNthShift(list(l[pos+1..size(l)]));
+    for (j = 1; j<=size(validLHS); j++)
+    {//Combining the left hand side valid combnations...
+      for (k = 1; k<=size(validRHS); k++)
+      {//... with the right hand side valid combinations
+        result = insert(result, validLHS[j]+validRHS[k]);
+      }//... with the right hand side valid combinations
+    }//Combining the left hand side valid combnations...
+  }//go through all combinations and detect the valid ones
+  result = delete_dublicates_noteval(result);
+  dbprint(p,dbprintWhitespace+"Done.");
+  return(result);
+}//combineNonnegativeNthShift
+
+static proc fromWeylToShiftPoly(poly h, sAlgebra)
+"
+USAGE: Given a polynomial in the first Weyl algebra, this method returns it -- if possible --
+       as an element in the first shift algebra, which is given in the method header.
+INPUT: A polynomial h, and the first shift algebra as a ring
+OUTPUT: The correct mapping in the shift Algebra
+ASSUMPTIONS:
+ - The lowest [-1,1]-homogeneous summand of h is of nonnegative degree
+ - The shift algebra is given in the way that var(2)*var(1) = (var(1)+1)*var(2)
+"
+{//fromWeylToShiftPoly
+  int p = printlevel - voice + 2;
+  int i;
+  string dbprintWhitespace = "";
+  for (i = 1; i<=voice;i++)
+  {dbprintWhitespace = dbprintWhitespace + " ";}
+  if (deg(h,intvec(1,-1))>0)
+  {//Wrong input polynomial
+    ERROR("The lowest [-1,1] homogeneous summand of "+string(h)+" is of negative degree.");
+  }//Wrong input polynomial
+  def ourHomeBase = basering;
+  list hDist = homogDistribution(h);
+  setring(sAlgebra);
+  poly result = 0;
+  poly tempResult;
+  poly zeroPoly;
+  map fromWeyl = ourHomeBase, var(1), var(2);
+  setring(ourHomeBase);
+  poly zeroPoly;
+  poly tempZeroPoly;
+  int j; int k;
+  int derDeg;
+  for (i = 1; i<=size(hDist);i++)
+  {
+    derDeg = hDist[i][1];
+    setring(sAlgebra);
+    tempResult = 1;
+    setring(ourHomeBase);
+    zeroPoly = lift(d^derDeg, hDist[i][2])[1,1];
+    for (j = 1; j<=size(zeroPoly); j++)
+    {
+      tempZeroPoly = zeroPoly[j];
+      setring(sAlgebra);
+      zeroPoly = fromWeyl(tempZeroPoly);
+      tempResult = tempResult * leadcoef(zeroPoly);
+      setring(ourHomeBase);
+      for (k = 1; k<=deg(zeroPoly[j],intvec(0,1));k++)
+      {
+        setring(sAlgebra);
+        tempResult = tempResult*(var(1)-(k-1));
+        setring(ourHomeBase);
+      }
+      setring(sAlgebra);
+      result = result + tempResult*var(2)^derDeg;
+      tempResult = 1;
+      setring(ourHomeBase);
+    }
+  }
+  setring(sAlgebra);
+  keepring(sAlgebra);
+}//fromWeylToShiftPoly
+
+static proc fromNthWeylToNthShiftPoly(poly h, def sAlgebra)
+"
+USAGE: Given a polynomial in the nth Weyl algebra, this method returns it -- if possible --
+       as an element in the nth shift algebra, which is given in the method header.
+INPUT: A polynomial h, and the nth shift algebra as a ring
+OUTPUT: The correct mapping in the nth shift Algebra
+ASSUMPTIONS:
+ - The lowest [-1,1]-homogeneous summand of h is of nonnegative degree
+ - The shift algebra is given in the way, that the variables are
+   sorted by (x_1, ... , x_n, s_1, ..., s_n) with s_i x_i = (x_i + 1) s_i
+"
+{//fromNthWeylToNthShiftPoly
+  int p = printlevel - voice + 2;
+  int i;
+  string dbprintWhitespace = "";
+  intvec degOfh;
+  for (i = 1; i<=voice;i++)
+  {dbprintWhitespace = dbprintWhitespace + " ";}
+  degOfh = degreeOfNthWeylPolyInverted(h);
+  for (i = 1; i<=size(degOfh); i++)
+  {
+    if (degOfh[i]>0)
+    {//Wrong input polynomial
+      ERROR("The lowest [-1,1] homogeneous summand of "+string(h)+" is of negative degree.");
+    }//Wrong input polynomial
+  }
+  def ourHomeBase = basering;
+  list hDist = homogDistributionNthWeyl(h);
+  setring(sAlgebra);
+  poly result = 0;
+  poly tempResult;
+  poly zeroPoly;
+  ideal fromWeylMapideal;
+  for (i = 1; i<=nvars(sAlgebra); i++)
+  {
+    fromWeylMapideal[i] = var(i);
+  }
+  map fromWeyl = ourHomeBase, fromWeylMapideal;
+  setring(ourHomeBase);
+  poly zeroPoly;
+  poly tempZeroPoly;
+  int j; int k; int l;
+  intvec derDeg;
+  intvec tempIntVec;
+  for (i = 1; i<=size(hDist);i++)
+  {
+    derDeg = hDist[i][1];
+    setring(sAlgebra);
+    tempResult = 1;
+    setring(ourHomeBase);
+    zeroPoly = hDist[i][2];
+    for (j = 1; j<=nvars(ourHomeBase) div 2; j++)
+    {//lifting all the powers of the different ds away
+      zeroPoly = lift(var((nvars(ourHomeBase) div 2) + j)^derDeg[j],zeroPoly)[1,1];
+    }//lifting all the powers of the different ds away
+    for (j = 1; j<=size(zeroPoly); j++)
+    {
+      tempZeroPoly = zeroPoly[j];
+      setring(sAlgebra);
+      zeroPoly = fromWeyl(tempZeroPoly);
+      tempResult = tempResult * leadcoef(zeroPoly);
+      setring(ourHomeBase);
+      for (l = 1; l <= nvars(ourHomeBase) div 2; l++)
+      {//iterating through all the d's
+        tempIntVec = 0:nvars(ourHomeBase);
+        tempIntVec[(nvars(ourHomeBase) div 2) + l] = 1;
+        for (k = 1; k<=deg(zeroPoly[j],tempIntVec);k++)
+        {
+          setring(sAlgebra);
+          tempResult = tempResult*(var(l)-(k-1));
+          setring(ourHomeBase);
+        }
+      }//iterating through all the d's
+      setring(sAlgebra);
+      for (l = 1; l<=nvars(sAlgebra) div 2; l++)
+      {
+        tempResult = tempResult*var((nvars(sAlgebra) div 2) + l)^derDeg[l];
+      }
+      result = result + tempResult;
+      tempResult = 1;
+      setring(ourHomeBase);
+    }
+  }
+  setring(sAlgebra);
+  kill fromWeylMapideal;
+  keepring(sAlgebra);
+}//fromNthWeylToNthShiftPoly
+
+static proc refineFactList(list L)
+{
+  // assume: list L is an output of factorization proc
+  // doing: remove doubled entries
+  int s = size(L); int sm;
+  int i,j,k,cnt;
+  list M, U, A, B;
+  A = L;
+  k = 0;
+  cnt  = 1;
+  for (i=1; i<=s; i++)
+  {
+    if (size(A[i]) != 0)
+    {
+      M = A[i];
+      //      "probing with"; M; i;
+      B[cnt] = M; cnt++;
+      for (j=i+1; j<=s; j++)
+      {
+        if ( isEqualList(M,A[j]) )
+        {
+          k++;
+          // U consists of intvecs with equal pairs
+          U[k] = intvec(i,j);
+          A[j] = 0;
+        }
+      }
+    }
+  }
+  kill A,U,M;
+  return(B);
+}
+example
+{
+  "EXAMPLE:";echo=2;
+  ring R = 0,(x,s),dp;
+  def r = nc_algebra(1,1);
+  setring(r);
+  list l,m;
+  l = list(1,s2+1,x,s,x+s);
+  m = l,list(1,s,x,s,x),l;
+  refineFactList(m);
+}
+
+static proc isEqualList(list L, list M)
+{
+  // int boolean: 1=yes, 0 =no : test whether two lists are identical
+  int s = size(L);
+  if (size(M)!=s) { return(0); }
+  int j=1;
+  while ( (L[j]==M[j]) && (j<s) )
+  {
+    j++;
+  }
+  if (L[j]==M[j])
+  {
+    return(1);
+  }
+  return(0);
+}
+example
+{
+  "EXAMPLE:";echo=2;
+  ring R = 0,(x,s),dp;
+  def r = nc_algebra(1,1);
+  setring(r);
+  list l,m;
+  l = list(1,s2+1,x,s,x+s);
+  m = l;
+  isEqualList(m,l);
+}
+
+
+//////////////////////////////////////////////////
+// Q-WEYL-SECTION
+//////////////////////////////////////////////////
+
+//==================================================
+//A function to get the i'th triangular number
+static proc triangNum(int n)
+{
+  if (n == 0)
+  {
+    return(0);
+  }
+  return (n*(n+1) div 2);
+}
+
+//==================================================*
+//one factorization of a homogeneous polynomial
+//in the first Q Weyl Algebra
+static proc homogfacFirstQWeyl_old(poly h)
+"USAGE: homogfacFirstQWeyl(h); h is a homogeneous polynomial in the
+ first q-Weyl algebra with respect to the weight vector [-1,1]
+RETURN: list
+PURPOSE: Computes a factorization of a homogeneous polynomial h with
+  respect to the weight vector [-1,1] in the first q-Weyl algebra
+THEORY: @code{homogfacFirstQWeyl} returns a list with a factorization of the given,
+ [-1,1]-homogeneous polynomial. If the degree of the polynomial is k with
+ k positive, the last k entries in the output list are the second
+ variable. If k is positive, the last k entries will be x. The other
+ entries will be irreducible polynomials of degree zero or 1 resp. -1.
+SEE ALSO: homogfacFirstQWeyl_all
+"{//proc homogfacFirstQWeyl_old
+  int p = printlevel-voice+2;//for dbprint
+  def r = basering;
+  poly hath;
+  int i; int j;
+  string dbprintWhitespace = "";
+  for (i = 1; i<=voice;i++)
+  {dbprintWhitespace = dbprintWhitespace + " ";}
+  intvec ivm11 = intvec(-1,1);
+  if (!homogwithorder(h,ivm11))
+  {//The given polynomial is not homogeneous
+    ERROR("Given polynomial was not [-1,1]-homogeneous");
+    return(list());
+  }//The given polynomial is not homogeneous
+  if (h==0)
+  {
+    return(list(0));
+  }
+  list result;
+  int m = deg(h,ivm11);
+  dbprint(p,dbprintWhitespace+" Splitting the polynomial in A_0 and A_k-Part");
+  if (m!=0)
+  {//The degree is not zero
+    if (m <0)
+    {//There are more x than y
+      hath = lift(var(1)^(-m),h)[1,1];
+      for (i = 1; i<=-m; i++)
+      {
+        result = result + list(var(1));
+      }
+    }//There are more x than y
+    else
+    {//There are more y than x
+      hath = lift(var(2)^m,h)[1,1];
+      for (i = 1; i<=m;i++)
+      {
+        result = result + list(var(2));
+      }
+    }//There are more y than x
+  }//The degree is not zero
+  else
+  {//The degree is zero
+    hath = h;
+  }//The degree is zero
+  dbprint(p," Done");
+  //beginning to transform x^i*y^i in theta(theta-1)...(theta-i+1)
+  list mons;
+  dbprint(p," Putting the monomials in the A_0-part in a list.");
+  for(i = 1; i<=size(hath);i++)
+  {//Putting the monomials in a list
+    mons = mons+list(hath[i]);
+  }//Putting the monomials in a list
+  dbprint(p," Done");
+  dbprint(p," Mapping this monomials to K(q)[theta]");
+  //Now, map to the commutative ring with theta:
+  list tempRingList = ringlist(r);
+  tempRingList[2] = insert(tempRingList[2],"theta",2); //New variable theta = x*d
+  tempRingList = delete(tempRingList,5);
+  tempRingList = delete(tempRingList,5); //The ring should now be commutative
+  def tempRing = ring(tempRingList);
+  setring tempRing;
+  map thetamap = r,var(1),var(2);
+  list mons = thetamap(mons);
+  poly entry;
+  poly tempSummand;
+  for (i = 1; i<=size(mons);i++)
+  {//transforming the monomials as monomials in theta
+    entry = 1;//leadcoef(mons[i]) * q^(-triangNum(leadexp(mons[i])[2]-1));
+    for (j = 0; j<leadexp(mons[i])[2];j++)
+    {
+      tempSummand = (par(1)^j-1)/(par(1)-1);
+      entry = entry * theta-tempSummand*entry;
+    }
+    //entry;
+    //leadcoef(mons[i]) * q^(-triangNum(leadexp(mons[i])[2]-1));
+    mons[i] = entry*leadcoef(mons[i]) * par(1)^(-triangNum(leadexp(mons[i])[2]-1));
+  }//transforming the monomials as monomials in theta
+  dbprint(p," Done");
+  dbprint(p," Factorize the A_0-Part in K[theta]");
+  list azeroresult = factorize(sum(mons));
+  dbprint(p," Successful");
+  list azeroresult_return_form;
+  for (i = 1; i<=size(azeroresult[1]);i++)
+  {//rewrite the result of the commutative factorization
+    for (j = 1; j <= azeroresult[2][i];j++)
+    {
+      azeroresult_return_form = azeroresult_return_form + list(azeroresult[1][i]);
+    }
+  }//rewrite the result of the commutative factorization
+  dbprint(p," Mapping back to A_0.");
+  setring(r);
+  map finalmap = tempRing,var(1),var(2),var(1)*var(2);
+  list tempresult = finalmap(azeroresult_return_form);
+  dbprint(p,"Successful.");
+  for (i = 1; i<=size(tempresult);i++)
+  {//factorizations of theta resp. theta +1
+    if(tempresult[i]==var(1)*var(2))
+    {
+      tempresult = insert(tempresult,var(1),i-1);
+      i++;
+      tempresult[i]=var(2);
+    }
+    if(tempresult[i]==var(2)*var(1))
+    {
+      tempresult = insert(tempresult,var(2),i-1);
+      i++;
+      tempresult[i]=var(1);
+    }
+  }//factorizations of theta resp. theta +1
+  result = tempresult+result;
+  //Correction of the result in the special q-Case:
+  for (j = 2 ; j<= size(result);j++)
+  {//Div the whole Term by the leading coefficient and multiply it to the first entry in result[i]
+    result[1] = result[1] * leadcoef(result[j]);
+    result[j] = 1/leadcoef(result[j]) * result[j];
+  }//Div the whole Term by the leading coefficient and multiply it to the first entry in result[i]
+  return(result);
+}//proc homogfacFirstQWeyl_old
+
+
+proc homogfacFirstQWeyl(poly h)
+"USAGE: homogfacFirstQWeyl(h); h is a homogeneous polynomial in the
+ first q-Weyl algebra with respect to the weight vector [-1,1]
+RETURN: list
+PURPOSE: Computes a factorization of a homogeneous polynomial h with
+  respect to the weight vector [-1,1] in the first q-Weyl algebra
+THEORY: This function is a wrapper for homogfacNthQWeyl. It exists to make this
+        library downward-compatible with older versions.
+SEE ALSO: homogfacFirstQWeyl_all
+"{//proc homogfacFirstQWeyl
+  return(homogfacNthQWeyl(h));
+}//proc homogfacFirstQWeyl
+example
+{
+  "EXAMPLE:";echo=2;
+  ring R = (0,q),(x,d),dp;
+  def r = nc_algebra (q,1);
+  setring(r);
+  poly h = q^25*x^10*d^10+q^16*(q^4+q^3+q^2+q+1)^2*x^9*d^9+
+    q^9*(q^13+3*q^12+7*q^11+13*q^10+20*q^9+26*q^8+30*q^7+
+    31*q^6+26*q^5+20*q^4+13*q^3+7*q^2+3*q+1)*x^8*d^8+
+    q^4*(q^9+2*q^8+4*q^7+6*q^6+7*q^5+8*q^4+6*q^3+
+     4*q^2+2q+1)*(q^4+q^3+q^2+q+1)*(q^2+q+1)*x^7*d^7+
+    q*(q^2+q+1)*(q^5+2*q^4+2*q^3+3*q^2+2*q+1)*(q^4+q^3+q^2+q+1)*(q^2+1)*(q+1)*x^6*d^6+
+    (q^10+5*q^9+12*q^8+21*q^7+29*q^6+33*q^5+31*q^4+24*q^3+15*q^2+7*q+12)*x^5*d^5+
+    6*x^3*d^3+24;
+  homogfacFirstQWeyl(h);
+}
+
+//==================================================
+//Computes all possible homogeneous factorizations for an element in the first Q-Weyl Algebra
+static proc homogfacFirstQWeyl_all_old(poly h)
+"USAGE: homogfacFirstQWeyl_all(h); h is a homogeneous polynomial in the first q-Weyl algebra
+ with respect to the weight vector [-1,1]
+RETURN: list
+PURPOSE: Computes all factorizations of a homogeneous polynomial h with respect
+  to the weight vector [-1,1] in the first q-Weyl algebra
+THEORY: @code{homogfacFirstQWeyl} returns a list with all factorization of the given,
+ homogeneous polynomial. It uses the output of homogfacFirstQWeyl and permutes
+ its entries with respect to the commutation rule. Furthermore, if a
+ factor of degree zero is irreducible in K[  heta], but reducible in
+ the first q-Weyl algebra, the permutations of this element with the other
+ entries will also be computed.
+SEE ALSO: homogfacFirstQWeyl
+"{//proc HomogfacFirstQWeylAll_old
+  int p=printlevel-voice+2;//for dbprint
+  intvec iv11= intvec(1,1);
+  if (deg(h,iv11) <= 0 )
+  {//h is a constant
+    dbprint(p,"Given polynomial was not homogeneous");
+    return(list(list(h)));
+  }//h is a constant
+  def r = basering;
+  list one_hom_fac; //stands for one homogeneous factorization
+  int i; int j; int k;
+  intvec ivm11 = intvec(-1,1);
+  dbprint(p," Calculate one homogeneous factorization using homogfacFirstQWeyl");
+  //Compute again a homogeneous factorization
+  one_hom_fac = homogfacFirstQWeyl(h);
+  dbprint(p,"Successful");
+  if (size(one_hom_fac) == 0)
+  {//there is no homogeneous factorization or the polynomial was not homogeneous
+    return(list());
+  }//there is no homogeneous factorization or the polynomial was not homogeneous
+  //divide list in A0-Part and a list of x's resp. y's
+  list list_not_azero = list();
+  list list_azero;
+  list k_factor;
+  int is_list_not_azero_empty = 1;
+  int is_list_azero_empty = 1;
+  k_factor = list(one_hom_fac[1]);
+  if (absValue(deg(h,ivm11))<size(one_hom_fac)-1)
+  {//There is a nontrivial A_0-part
+    list_azero = one_hom_fac[2..(size(one_hom_fac)-absValue(deg(h,ivm11)))];
+    is_list_azero_empty = 0;
+  }//There is a nontrivial A_0 part
+  dbprint(p," Combine x,y to xy in the factorization again.");
+  for (i = 1; i<=size(list_azero)-1;i++)
+  {//in homogfacFirstQWeyl, we factorized theta, and this will be made undone
+    if (list_azero[i] == var(1))
+    {
+      if (list_azero[i+1]==var(2))
+      {
+        list_azero[i] = var(1)*var(2);
+        list_azero = delete(list_azero,i+1);
+      }
+    }
+    if (list_azero[i] == var(2))
+    {
+      if (list_azero[i+1]==var(1))
+      {
+        list_azero[i] = var(2)*var(1);
+        list_azero = delete(list_azero,i+1);
+      }
+    }
+  }//in homogfacFirstQWeyl, we factorized theta, and this will be made undone
+  dbprint(p," Done");
+  if(deg(h,ivm11)!=0)
+  {//list_not_azero is not empty
+    list_not_azero =
+      one_hom_fac[(size(one_hom_fac)-absValue(deg(h,ivm11))+1)..size(one_hom_fac)];
+    is_list_not_azero_empty = 0;
+  }//list_not_azero is not empty
+  //Map list_azero in K[theta]
+  dbprint(p," Map list_azero to K[theta]");
+  //Now, map to the commutative ring with theta:
+  list tempRingList = ringlist(r);
+  tempRingList[2] = insert(tempRingList[2],"theta",2); //New variable theta = x*d
+  tempRingList = delete(tempRingList,5);
+  tempRingList = delete(tempRingList,5); //The ring should now be commutative
+  def tempRing = ring(tempRingList);
+  setring(tempRing);
+  poly entry;
+  map thetamap = r,var(1),var(2);
+  if(!is_list_not_azero_empty)
+  {//Mapping in Singular is only possible, if the list before
+    //contained at least one element of the other ring
+    list list_not_azero = thetamap(list_not_azero);
+  }//Mapping in Singular is only possible, if the list before
+  //contained at least one element of the other ring
+  if(!is_list_azero_empty)
+  {//Mapping in Singular is only possible, if the list before
+    //contained at least one element of the other ring
+    list list_azero= thetamap(list_azero);
+  }//Mapping in Singular is only possible, if the list before
+  //contained at least one element of the other ring
+  list k_factor = thetamap(k_factor);
+  list tempmons;
+  dbprint(p," Done");
+  for(i = 1; i<=size(list_azero);i++)
+  {//rewrite the polynomials in A1 as polynomials in K[theta]
+    tempmons = list();
+    for (j = 1; j<=size(list_azero[i]);j++)
+    {
+      tempmons = tempmons + list(list_azero[i][j]);
+    }
+    for (j = 1 ; j<=size(tempmons);j++)
+    {
+      //entry = leadcoef(tempmons[j]);
+      entry = leadcoef(tempmons[j]) * par(1)^(-triangNum(leadexp(tempmons[j])[2]-1));
+      for (k = 0; k < leadexp(tempmons[j])[2];k++)
+      {
+        entry = entry*(theta-(par(1)^k-1)/(par(1)-1));
+      }
+      tempmons[j] = entry;
+    }
+    list_azero[i] = sum(tempmons);
+  }//rewrite the polynomials in A1 as polynomials in K[theta]
+  //Compute all permutations of the A0-part
+  dbprint(p," Compute all permutations of the A_0-part with the first resp. the snd. variable");
+  list result;
+  int shift_sign;
+  int shift;
+  poly shiftvar;
+  if (size(list_not_azero)!=0)
+  {//Compute all possibilities to permute the x's resp. the y's in the list
+    if (list_not_azero[1] == var(1))
+    {//h had a negative weighted degree
+      shift_sign = 1;
+      shiftvar = var(1);
+    }//h had a negative weighted degree
+    else
+    {//h had a positive weighted degree
+      shift_sign = -1;
+      shiftvar = var(2);
+    }//h had a positive weighted degree
+    result = permpp(list_azero + list_not_azero);
+    for (i = 1; i<= size(result); i++)
+    {//adjust the a_0-parts
+      shift = 0;
+      for (j=1; j<=size(result[i]);j++)
+      {
+        if (result[i][j]==shiftvar)
+        {
+          shift = shift + shift_sign;
+        }
+        else
+        {
+          if (shift < 0)
+          {//We have two distict formulas for x and y. In this case use formula for y
+            if (shift == -1)
+            {
+              result[i][j] = subst(result[i][j],theta,1/par(1)*(theta - 1));
+            }
+            else
+            {
+              result[i][j] =
+                subst(result[i][j],
+                      theta,
+                      1/par(1)*((theta - 1)/par(1)^(absValue(shift)-1)
+                                - (par(1)^(shift +2)-par(1))/(1-par(1))));
+            }
+          }//We have two distict formulas for x and y. In this case use formula for y
+          if (shift > 0)
+          {//We have two distict formulas for x and y. In this case use formula for x
+            if (shift == 1)
+            {
+              result[i][j] = subst(result[i][j],theta,par(1)*theta + 1);
+            }
+            else
+            {
+              result[i][j] =
+                subst(result[i][j],
+                      theta,par(1)^shift*theta+(par(1)^shift-1)/(par(1)-1));
+            }
+          }//We have two distict formulas for x and y. In this case use formula for x
+        }
+      }
+    }//adjust the a_0-parts
+  }//Compute all possibilities to permute the x's resp. the y's in the list
+  else
+  {//The result is just all the permutations of the a_0-part
+    result = permpp(list_azero);
+  }//The result is just all the permutations of the a_0 part
+  if (size(result)==0)
+  {
+    return(result);
+  }
+  dbprint(p," Done");
+  dbprint(p," Searching for theta resp. theta + 1 in the list and factorize them");
+  //Now we are going deeper and search for theta resp. theta + 1, substitute
+  //them by xy resp. yx and go on permuting
+  int found_theta;
+  int thetapos;
+  list leftpart;
+  list rightpart;
+  list lparts;
+  list rparts;
+  list tempadd;
+  for (i = 1; i<=size(result) ; i++)
+  {//checking every entry of result for theta or theta +1
+    found_theta = 0;
+    for(j=1;j<=size(result[i]);j++)
+    {
+      if (result[i][j]==theta)
+      {//the jth entry is theta and can be written as x*y
+        thetapos = j;
+        result[i]= insert(result[i],var(1),j-1);
+        j++;
+        result[i][j] = var(2);
+        found_theta = 1;
+        break;
+      }//the jth entry is theta and can be written as x*y
+      if(result[i][j] == par(1)*theta +1)
+      {
+        thetapos = j;
+        result[i] = insert(result[i],var(2),j-1);
+        j++;
+        result[i][j] = var(1);
+        found_theta = 1;
+        break;
+      }
+    }
+    if (found_theta)
+    {//One entry was theta resp. theta +1
+      leftpart = result[i];
+      leftpart = leftpart[1..thetapos];
+      rightpart = result[i];
+      rightpart = rightpart[(thetapos+1)..size(rightpart)];
+      lparts = list(leftpart);
+      rparts = list(rightpart);
+      //first deal with the left part
+      if (leftpart[thetapos] == var(1))
+      {
+        shift_sign = 1;
+        shiftvar = var(1);
+      }
+      else
+      {
+        shift_sign = -1;
+        shiftvar = var(2);
+      }
+      for (j = size(leftpart); j>1;j--)
+      {//drip x resp. y
+        if (leftpart[j-1]==shiftvar)
+        {//commutative
+          j--;
+          continue;
+        }//commutative
+        if (deg(leftpart[j-1],intvec(-1,1,0))!=0)
+        {//stop here
+          break;
+        }//stop here
+        //Here, we can only have a a0- part
+        if (shift_sign<0)
+        {
+          leftpart[j] = subst(leftpart[j-1],theta, 1/par(1)*(theta +shift_sign));
+        }
+        if (shift_sign>0)
+        {
+          leftpart[j] = subst(leftpart[j-1],theta, par(1)*theta + shift_sign);
+        }
+        leftpart[j-1] = shiftvar;
+        lparts = lparts + list(leftpart);
+      }//drip x resp. y
+      //and now deal with the right part
+      if (rightpart[1] == var(1))
+      {
+        shift_sign = 1;
+        shiftvar = var(1);
+      }
+      else
+      {
+        shift_sign = -1;
+        shiftvar = var(2);
+      }
+      for (j = 1 ; j < size(rightpart); j++)
+      {
+        if (rightpart[j+1] == shiftvar)
+        {
+          j++;
+          continue;
+        }
+        if (deg(rightpart[j+1],intvec(-1,1,0))!=0)
+        {
+          break;
+        }
+        if (shift_sign<0)
+        {
+          rightpart[j] = subst(rightpart[j+1], theta, par(1)*theta - shift_sign);
+        }
+        if (shift_sign>0)
+        {
+          rightpart[j] = subst(rightpart[j+1], theta, 1/par(1)*(theta - shift_sign));
+        }
+        rightpart[j+1] = shiftvar;
+        rparts = rparts + list(rightpart);
+      }
+      //And now, we put all possibilities together
+      tempadd = list();
+      for (j = 1; j<=size(lparts); j++)
+      {
+        for (k = 1; k<=size(rparts);k++)
+        {
+          tempadd = tempadd + list(lparts[j]+rparts[k]);
+        }
+      }
+      tempadd = delete(tempadd,1); // The first entry is already in the list
+      result = result + tempadd;
+      continue; //We can may be not be done already with the ith entry
+    }//One entry was theta resp. theta +1
+  }//checking every entry of result for theta or theta +1
+  dbprint(p," Done");
+  //map back to the basering
+  dbprint(p," Mapping back everything to the basering");
+  setring(r);
+  map finalmap = tempRing, var(1), var(2),var(1)*var(2);
+  list result = finalmap(result);
+  for (i=1; i<=size(result);i++)
+  {//adding the K factor
+    result[i] = k_factor + result[i];
+  }//adding the k-factor
+  dbprint(p," Done");
+  dbprint(p," Delete double entries in the list.");
+  result = delete_dublicates_noteval(result);
+  dbprint(p," Done");
+  return(result);
+}//proc HomogfacFirstQWeylAll_old
+
+
+proc homogfacFirstQWeyl_all(poly h)
+"USAGE: homogfacFirstQWeyl_all(h); h is a homogeneous polynomial in the first q-Weyl algebra
+ with respect to the weight vector [-1,1]
+RETURN: list
+PURPOSE: Computes all factorizations of a homogeneous polynomial h with respect
+  to the weight vector [-1,1] in the first q-Weyl algebra
+THEORY: This function is a wrapper for homogFacNthQWeyl_all. It exists to make this library
+        downward-compatible with older versions.
+SEE ALSO: homogfacFirstQWeyl
+"{//proc HomogfacFirstQWeylAll_old
+  return(homogfacNthQWeyl_all(h));
+}//proc HomogfacFirstQWeylAll_old
+example
+{
+  "EXAMPLE:";echo=2;
+  ring R = (0,q),(x,d),dp;
+  def r = nc_algebra (q,1);
+  setring(r);
+  poly h = q^25*x^10*d^10+q^16*(q^4+q^3+q^2+q+1)^2*x^9*d^9+
+    q^9*(q^13+3*q^12+7*q^11+13*q^10+20*q^9+26*q^8+30*q^7+
+    31*q^6+26*q^5+20*q^4+13*q^3+7*q^2+3*q+1)*x^8*d^8+
+    q^4*(q^9+2*q^8+4*q^7+6*q^6+7*q^5+8*q^4+6*q^3+
+    4*q^2+2q+1)*(q^4+q^3+q^2+q+1)*(q^2+q+1)*x^7*d^7+
+    q*(q^2+q+1)*(q^5+2*q^4+2*q^3+3*q^2+2*q+1)*(q^4+q^3+q^2+q+1)*(q^2+1)*(q+1)*x^6*d^6+
+    (q^10+5*q^9+12*q^8+21*q^7+29*q^6+33*q^5+31*q^4+24*q^3+15*q^2+7*q+12)*x^5*d^5+
+    6*x^3*d^3+24;
+  homogfacFirstQWeyl_all(h);
+}
+
+//==================================================
+// Homogeneous factorization of the nth q-Weyl algebra
+//==================================================
+
+proc homogfacNthQWeyl(poly h)
+"USAGE: homogfacNthQWeyl(h); h is a homogeneous polynomial in the
+ n'th q-Weyl algebra with respect to the weight vector
+ [-1,...,-1,1,...,1].
+  \__  __/  \__  __/
+     \/        \/
+     n/2       n/2
+RETURN: list
+PURPOSE: Computes a factorization of a homogeneous polynomial h
+in the n'th q-Weyl algebra
+THEORY:@code{homogfacNthQWeyl} returns a list with a factorization of the given,
+ [-1,1]-homogeneous polynomial. For every i in 1..n: If the degree of the polynomial
+ in [d_i,x_i] is k with k positive, the last entries in the output list are the second
+ variable. If k is positive, the last k entries will be x_i. The other
+ entries will be irreducible polynomials of degree zero or 1 resp. -1. resp. other variables
+
+GENERAL ASSUMPTIONS:
+ - The basering is the nth Weyl algebra and has the form, that the first n variables represent
+   x1, ..., xn, and the second n variables do represent the d1, ...,
+   dn.
+ - We have n parameters q_1,..., q_n given.
+
+SEE ALSO: homogfacFirstQWeyl, homogfacFirstQWeyl_all, homogfacNthQWeyl_all
+"
+{//proc homogfacNthQWeyl
+  int p = printlevel-voice+2;//for dbprint
+  poly hath = h;
+  def r = basering;
+  int i; int j; int k;
+  string dbprintWhitespace = "";
+  for (i = 1; i<=voice;i++)
+  {dbprintWhitespace = dbprintWhitespace + " ";}
+  intvec ivm11 = intvec(-1,1);
+  if(!checkIfProperNthQWeyl())
+  {//checking whether the given ring is proper q-Weyl
+    ERROR("Assumptions on the ring structure not met.");
+    return(list());
+  }//checking whether the given ring is proper q-Weyl
+  if (!homogwithorderNthWeyl(h))
+  {//The given polynomial is not homogeneous
+    ERROR("Given polynomial was not [-1,...,-1,1,...,1]-homogeneous");
+    return(list());
+  }//The given polynomial is not homogeneous
+  if (h==0)
+  {
+    return(list(0));
+  }
+  list result;
+  intvec m = degreeOfNthWeylPoly(h);
+  dbprint(p,dbprintWhitespace +" Splitting the polynomial in Q_0 and Q_k-Part");
+  dbprint(p,dbprintWhitespace + "Its [-1,...,-1,1,...,1] degree is "+string(m));
+  for (j = 1; j<=nvars(basering) div 2; j++)
+  {//extracting the respective variable for every position
+    dbprint(p,dbprintWhitespace + "Considering variables x_"+string(j)+" and d" + string(j));
+    if (m[j]!=0)
+    {//The degree is not zero
+      if (m[j] <0)
+      {//There are more x than d
+        hath = lift(var(j)^(-m[j]),hath)[1,1];
+        for (i = 1; i<=-m[j]; i++)
+        {
+          result = result + list(var(j));
+        }
+      }//There are more x than d
+      else
+      {//There are more d than x
+        hath = lift(var(nvars(basering) div 2 + j)^m[j],hath)[1,1];
+        for (i = 1; i<=m[j];i++)
+        {
+          result = result + list(var(nvars(basering) div 2 + j));
+        }
+      }//There are more d than x
+    }//The degree is not zero
+  }//extracting the respective variable for every position
+  dbprint(p,dbprintWhitespace+" Done");
+  //beginning to factor the zero-homogeneous part
+  list mons;
+  dbprint(p,dbprintWhitespace+" Putting the monomials in the Q_0-part in a list.");
+  for(i = 1; i<=size(hath);i++)
+  {//Putting the monomials in a list
+    mons = mons+list(hath[i]);
+  }//Putting the monomials in a list
+  dbprint(p,dbprintWhitespace+" Done");
+  dbprint(p,dbprintWhitespace+" Mapping these monomials to K[theta_1,... , theta_n]");
+  list parameterNames;
+  for (i = 1; i<=(nvars(basering) div 2); i++)
+  {//saving the names of the parameters
+    parameterNames[i] = ringlist(basering)[1][2][i];
+  }//saving the names of the parameters
+  ring tempRingPre = (0,q(1..(nvars(basering) div 2))),
+                    (x(1..(nvars(basering) div 2)),
+                     d(1..(nvars(basering) div 2)),
+                     theta(1..(nvars(basering) div 2))),dp;
+  list ringListTempRingPre = ringlist(tempRingPre);
+  for (i = 1; i<=size(ringListTempRingPre[1][2]); i++)
+  {//setting the same name for the parameters
+    ringListTempRingPre[1][2][i] = parameterNames[i];
+  }//setting the same name for the parameters
+  def tempRing = ring(ringListTempRingPre);
+  setring(tempRing);
+  ideal mapList;
+  for (i = 1; i<=nvars(r) ; i++)
+  {//filling the list of elements we want to map
+    mapList[i] = var(i);
+  }//filling the list of elements we want to map
+  map thetamap = r,mapList;
+  list mons = thetamap(mons);
+  poly entry;
+  intvec lExp;
+  poly tempSummand;
+  for (i = 1; i<=size(mons);i++)
+  {//transforming the monomials as monomials in theta
+    entry = leadcoef(mons[i]);
+    lExp  = leadexp(mons[i]);
+    for (k = 1; k<=nvars(r) div 2; k++)
+    {//iterating over the pairs x_kd_k
+      for (j = 0; j<lExp[k];j++)
+      {
+        tempSummand = (par(k)^j-1)/(par(k)-1);
+        entry = entry * (theta(k)-tempSummand);
+      }
+      entry = entry* par(k)^(-triangNum(leadexp(mons[i])[k]-1));
+    }//iterating over the pairs x_kd_k
+    mons[i] = entry;
+  }//transforming the monomials as monomials in theta
+  dbprint(p,dbprintWhitespace+" Done");
+  dbprint(p,dbprintWhitespace+" Factorize the Q_0-Part in K[theta]");
+  list azeroresult = factorize(sum(mons));
+  dbprint(p,dbprintWhitespace+" Successful");
+  list azeroresult_return_form;
+  for (i = 1; i<=size(azeroresult[1]);i++)
+  {//rewrite the result of the commutative factorization
+    for (j = 1; j <= azeroresult[2][i];j++)
+    {
+      azeroresult_return_form = azeroresult_return_form + list(azeroresult[1][i]);
+    }
+  }//rewrite the result of the commutative factorization
+  dbprint(p,dbprintWhitespace+" Mapping back to Q_0.");
+  setring(r);
+  ideal finalMapList;
+  for(i = 1; i<=nvars(r);i++)
+  {
+    finalMapList[i] = var(i);
+  }
+  for (i = 1; i<=nvars(r) div 2; i++)
+  {
+    finalMapList[i + nvars(r)] = var(i)*var(i + (nvars(r) div 2));
+  }
+  map finalmap = tempRing,finalMapList;
+  list tempresult = finalmap(azeroresult_return_form);
+  dbprint(p,dbprintWhitespace+"Successful.");
+  for (k = 1; k<=nvars(r) div 2; k++)
+  {
+    for (i = 1; i<=size(tempresult);i++)
+    {//factorizations of theta resp. theta +1
+      if(tempresult[i]==var(k)*var(k + nvars(r) div 2))
+      {
+        tempresult = insert(tempresult,var(k),i-1);
+        i++;
+        tempresult[i]=var(k +nvars(r) div 2);
+      }
+      if(tempresult[i]==var(k + nvars(r) div 2)*var(k))
+      {
+        tempresult = insert(tempresult,var(k + nvars(r) div 2),i-1);
+        i++;
+        tempresult[i]=var(k);
+      }
+    }//factorizations of theta resp. theta +1
+  }
+  result = tempresult+result;
+  //normalization of factors
+  for (i=2; i<=size(result); i++)
+  {//Iterating through all respective factors
+    if (content(result[i])!=number(1))
+    {//Got one where the content is not equal to 1
+      result[1] = result[1] * content(result[i]);
+      result[i] = result[i] / content(result[i]);
+    }//Got one where the content is not equal to 1
+  }//Iterating through all respective factors
+  return(result);
+}//proc homogfacNthQWeyl
+example
+{
+  "EXAMPLE:";echo=2;
+  ring R = (0,q1,q2,q3),(x1,x2,x3,d1,d2,d3),dp;
+  matrix C[6][6] = 1,1,1,q1,1,1,
+    1,1,1,1,q2,1,
+    1,1,1,1,1,q3,
+    1,1,1,1,1,1,
+    1,1,1,1,1,1,
+    1,1,1,1,1,1;
+  matrix D[6][6] = 0,0,0,1,0,0,
+    0,0,0,0,1,0,
+    0,0,0,0,0,1,
+    -1,0,0,0,0,0,
+    0,-1,0,0,0,0,
+    0,0,-1,0,0,0;
+  def r = nc_algebra(C,D);
+  setring(r);
+  poly h =x1*x2^2*x3^3*d1*d2^2+x2*x3^3*d2;
+  homogfacNthQWeyl(h);
+}
+
+
+proc homogfacNthQWeyl_all(poly h)
+"USAGE: homogfacNthQWeyl_all(h); h is a homogeneous polynomial in the
+ n'th q-Weyl algebra with respect to the weight vector
+ [-1,...,-1,1,...,1].
+  \__  __/  \__  __/
+     \/        \/
+     n/2       n/2
+RETURN: list
+PURPOSE: Computes all factorizations of a homogeneous polynomial h
+in the n'th q-Weyl algebra
+THEORY: @code{homogfacNthQWeyl} returns a list with lists representing
+each a factorization of the given,
+ [-1,...,-1,1,...,1]-homogeneous polynomial.
+
+GENERAL ASSUMPTIONS:
+ - The basering is the nth Weyl algebra and has the form, that the first n variables represent
+   x1, ..., xn, and the second n variables do represent the d1, ..., dn.
+ - We have n parameters q_1,..., q_n given.
+
+SEE ALSO: homogfacFirstQWeyl, homogfacFirstQWeyl_all
+"
+{//proc homogfacNthQWeyl_all
+  int p=printlevel-voice+2;//for dbprint
+  intvec iv11= 1:nvars(basering);
+  if (deg(h,iv11) <= 0 )
+  {//h is a constant
+    dbprint(p,"Given polynomial was not homogeneous");
+    return(list(list(1,h)));
+  }//h is a constant
+  def r = basering;
+  list one_hom_fac; //stands for one homogeneous factorization
+  int i; int j; int k; int l;
+  string dbprintWhitespace = "";
+  for (i = 1; i<=voice;i++)
+  {dbprintWhitespace = dbprintWhitespace + " ";}
+  dbprint(p,dbprintWhitespace +" Calculate one homogeneous factorization using homogfacNthWeyl");
+  //Compute again a homogeneous factorization
+  one_hom_fac = homogfacNthQWeyl(h);
+  dbprint(p,dbprintWhitespace +"Successful");
+  if (size(one_hom_fac) == 0)
+  {//there is no homogeneous factorization or the polynomial was not homogeneous
+    return(list());
+  }//there is no homogeneous factorization or the polynomial was not homogeneous
+  //divide list in A0-Part and a list of x_i's resp. y_i's
+  list list_not_azero = list();
+  list list_azero;
+  list k_factor;
+  int is_list_not_azero_empty = 1;
+  int is_list_azero_empty = 1;
+  k_factor = list(number(one_hom_fac[1]));
+  dbprint(p, dbprintWhitespace + "Determine whether there is an A0
+part or not.");
+  int absValueOfDegree = 0;
+  intvec degVecH = degreeOfNthWeylPoly(h);
+  intvec lExp;
+  for (i = 1; i<=size(degVecH); i++)
+  {//adding up the absolute values of the degrees of the respective variables
+    absValueOfDegree = absValueOfDegree + absValue(degVecH[i]);
+  }//adding up the absolute values of the degrees of the respective variables
+  if (absValueOfDegree < size(one_hom_fac) - 1)
+  {//There is a nontrivial A0 part
+    list_azero = one_hom_fac[2..(size(one_hom_fac)-absValueOfDegree)];
+    is_list_azero_empty = 0;
+  }//There is a nontrivial A0 part
+  dbprint(p,dbprintWhitespace +" Combine x_i,d_i to x_id_i in the
+factorization again.");
+  dbprint(p,dbprintWhitespace + " The corresponding list of A0
+    factors is: " + string(list_azero));
+  for (i = 1; i<size(list_azero);i++)
+  {//in homogfacFirstWeyl, we factorized the theta_i, and this will be
+   //made undone
+    for (j = 1; j<=nvars(basering) div 2; j++)
+    {//iterating through the variables
+      if (list_azero[i] == var(j))
+      {
+        if (list_azero[i+1]==var(j + nvars(basering) div 2))
+        {
+          list_azero[i] = var(j)*var(j + nvars(basering) div 2);
+          list_azero = delete(list_azero,i+1);
+        }
+      }
+      if (list_azero[i] == var(j + nvars(basering) div 2))
+      {
+        if (list_azero[i+1]==var(j))
+        {
+          list_azero[i] = var(j + nvars(basering) div 2)*var(j);
+          list_azero = delete(list_azero,i+1);
+        }
+      }
+    }//iterating through the variables
+  }//in homogfacFirstWeyl, we factorized theta_i, and this will be
+   //made undone
+  dbprint(p,dbprintWhitespace +" Done");
+  dbprint(p, dbprintWhitespace + "The new list is: " +
+          string(list_azero));
+  if (degVecH != 0:(nvars(basering) div 2))
+  {//list_not_azero is not empty
+    list_not_azero = one_hom_fac[(size(one_hom_fac) -
+                                  absValueOfDegree +1)..size(one_hom_fac)];
+    is_list_not_azero_empty = 0;
+  }//list_not_azero is not empty
+  dbprint(p,dbprintWhitespace+" Mapping list_azero to K[theta_1, ... ,theta_n]");
+  list parameterNames;
+  for (i = 1; i<=(nvars(basering) div 2); i++)
+  {//saving the names of the parameters
+    parameterNames[i] = ringlist(basering)[1][2][i];
+  }//saving the names of the parameters
+  ring tempRingPre = (0,q(1..(nvars(basering) div 2))),
+                    (x(1..(nvars(basering) div 2)),
+                     d(1..(nvars(basering) div 2)),
+                     theta(1..(nvars(basering) div 2))),dp;
+  list ringListTempRingPre = ringlist(tempRingPre);
+  for (i = 1; i<=size(ringListTempRingPre[1][2]); i++)
+  {//setting the same name for the parameters
+    ringListTempRingPre[1][2][i] = parameterNames[i];
+  }//setting the same name for the parameters
+  def tempRing = ring(ringListTempRingPre);
+  setring tempRing;
+  poly entry;
+  ideal mapList;
+  for (i = 1; i<=nvars(r) ; i++)
+  {//filling the list of elements we want to map
+    mapList[i] = var(i);
+  }//filling the list of elements we want to map
+  map thetamap = r,mapList;
+  if(!is_list_not_azero_empty)
+  {//Mapping in Singular is only possible, if the list before
+    //contained at least one element of the other ring
+    list list_not_azero = thetamap(list_not_azero);
+  }//Mapping in Singular is only possible, if the list before
+  //contained at least one element of the other ring
+  if(!is_list_azero_empty)
+  {//Mapping in Singular is only possible, if the list before
+    //contained at least one element of the other ring
+    list list_azero= thetamap(list_azero);
+  }//Mapping in Singular is only possible, if the list before
+  //contained at least one element of the other ring
+  list k_factor = thetamap(k_factor);
+  list tempmons;
+  dbprint(p,dbprintWhitespace +" Done");
+  poly tempSummand;
+  for(i = 1; i<=size(list_azero);i++)
+  {//rewrite the polynomials in A1 as polynomials in K[theta]
+    tempmons = list();
+    for (j = 1; j<=size(list_azero[i]);j++)
+    {
+      tempmons = tempmons + list(list_azero[i][j]);
+    }
+    for (j = 1 ; j<=size(tempmons);j++)
+    {
+      entry = leadcoef(tempmons[j]);
+      lExp  = leadexp(tempmons[j]);
+      for (l = 1; l<=nvars(r) div 2; l++)
+      {
+        for (k = 0; k < lExp[l];k++)
+        {
+          tempSummand = (par(l)^k-1)/(par(l)-1);
+          entry = entry*(theta(l)-tempSummand);
+        }
+        entry =  entry* par(l)^(-triangNum(lExp[l]-1));
+      }
+      tempmons[j] = entry;
+    }
+    list_azero[i] = sum(tempmons);
+  }//rewrite the polynomials in A1 as polynomials in K[theta]
+  //Compute all permutations of the A0-part
+  dbprint(p, dbprintWhitespace + "The polynomials rewritten in
+K[theta_1, ... , theta_n] look like:");
+  dbprint(p,list_azero);
+  dbprint(p,dbprintWhitespace +" Compute all permutations of the A_0-part with the first resp.
+the snd. variable");
+  list result;
+  intvec shift = 0:(nvars(r) div 2);
+  if (size(list_not_azero)!=0)
+  {//Compute all possibilities to permute the x's resp. the y's in the list
+    result = permpp(list_azero + list_not_azero);
+    for (i = 1; i<= size(result); i++)
+    {//adjust the a_0-parts
+      shift = 0:(nvars(r) div 2);
+      for (j=1; j<=size(result[i]);j++)
+      {//iterating through each factor
+        if (deg(result[i][j],(1:nvars(r),0:(nvars(r) div 2))) !=0)
+        {//the factor is a single variable
+          for(k = 1; k<=nvars(r); k++)
+          {//Iterating through the variables to find the variable
+            if (result[i][j]==var(k))
+            {//found it!
+              if (k<=nvars(r) div 2)
+              {shift[k] = shift[k] + 1;}
+              else
+              {shift[k -(nvars(r) div 2)] = shift[k -(nvars(r) div
+                                                      2)] -1;
+              }
+              break;
+            }//found it!
+          }//Iterating through the variables to find the variable
+        }//the factor is a single variable
+        else
+        {//factor was a theta poly
+          for (k= 1; k <= nvars(r) div 2;k++)
+          {
+            if (shift[k]<0)
+            {
+              result[i][j] = subst(result[i][j],theta(k),
+                                   1/par(k)*((theta(k)-1)/(par(k)^(absValue(shift[k])-1))
+                                             - (par(k)^(shift[k]+2)-par(k))/(1-par(k))));
+            }
+            else
+            {
+              if (shift[k]>0)
+              {
+                result[i][j] =
+                  subst(result[i][j],theta(k),par(k)^(shift[k])*theta(k)
+                        +(1-par(k)^(shift[k]))/(1-par(k)));
+              }
+            }
+          }
+        }//factor was a theta poly
+      }//iterating through each factor
+    }//adjust the a_0-parts
+  }//Compute all possibilities to permute the x's resp. the y's in the list
+  else
+  {//The result is just all the permutations of the a_0-part
+    result = permpp(list_azero);
+  }//The result is just all the permutations of the a_0 part
+  if (size(result)==0)
+  {
+    return(normalizeFactors(result));
+  }
+  dbprint(p,dbprintWhitespace +" Done");
+  dbprint(p, dbprintWhitespace + "The factorization list is now:");
+  dbprint(p,result);
+  dbprint(p, dbprintWhitespace + "Checking whether the
+        intermediate result is correct or not");
+  dbprint(p,testNCfac(result));
+  dbprint(p,dbprintWhitespace +" Searching for theta resp. theta+1 in
+  the list and fact. them");
+  //Now we are going deeper and search for theta resp. theta + 1, substitute
+  //them by xy resp. yx and go on permuting
+  int found_theta;
+  int thetapos;
+  int shift_sign;
+  int thetaIndex;
+  poly shiftvar;
+  list leftpart;
+  list rightpart;
+  list lparts;
+  list rparts;
+  list tempadd;
+  for (i = 1; i<=size(result) ; i++)
+  {//checking every entry of result for theta or theta +1
+    found_theta = 0;
+    for(j=1;j<=size(result[i]);j++)
+    {//iterating through all factors
+      for (k = 1; k<=nvars(r) div 2; k++)
+      {//iterating through the variables
+        if (result[i][j]==theta(k))
+        {//the jth entry is theta and can be written as x*y
+          thetapos = j;
+          thetaIndex = k;
+          result[i]= insert(result[i],x(k),j-1);
+          j++;
+          result[i][j] = d(k);
+          found_theta = 1;
+          break;
+        }//the jth entry is theta and can be written as x*y
+        if(result[i][j] == theta(k) +1/par(k))
+        {
+          thetapos = j;
+          thetaIndex = k;
+          result[i] = insert(result[i],d(k),j-1);
+          j++;
+          result[i][j] = x(k);
+          found_theta = 1;
+          break;
+        }
+      }//iterating through the variables
+      if(found_theta)
+      {break;}
+    }//iterating through all factors
+    if (found_theta)
+    {//One entry was theta resp. theta +1
+      leftpart = result[i];
+      leftpart = leftpart[1..thetapos];
+      rightpart = result[i];
+      rightpart = rightpart[(thetapos+1)..size(rightpart)];
+      lparts = list(leftpart);
+      rparts = list(rightpart);
+      //first deal with the left part
+      if (leftpart[thetapos] == x(thetaIndex))
+      {
+        shift_sign = 1;
+        shiftvar = x(thetaIndex);
+      }
+      else
+      {
+        shift_sign = -1;
+        shiftvar = d(thetaIndex);
+      }
+      for (j = size(leftpart); j>1;j--)
+      {//drip x resp. y
+        if (leftpart[j-1]==shiftvar)
+        {//commutative
+          j--;
+          continue;
+        }//commutative
+        if (leadexp(leftpart[j-1])[thetaIndex + nvars(r) div 2]
+            - leadexp(leftpart[j-1])[thetaIndex]!=0)
+        {//stop here
+          break;
+        }//stop here
+        //Here, we can only have a a0- part
+        if (shift_sign<0)
+        {
+          leftpart[j] = subst(leftpart[j-1],theta(thetaIndex),
+                              1/par(thetaIndex)*(theta(thetaIndex)+shift_sign));
+        }
+        else
+        {
+          if (shift_sign>0)
+          {
+            leftpart[j] = subst(leftpart[j-1],theta(thetaIndex),
+                                par(thetaIndex)*theta(thetaIndex)+shift_sign);
+          }
+        }
+        leftpart[j-1] = shiftvar;
+        lparts = lparts + list(leftpart);
+      }//drip x resp. y
+      //and now deal with the right part
+      if (rightpart[1] == x(thetaIndex))
+      {
+        shift_sign = 1;
+        shiftvar = x(thetaIndex);
+      }
+      else
+      {
+        shift_sign = -1;
+        shiftvar = d(thetaIndex);
+      }
+      for (j = 1 ; j < size(rightpart); j++)
+      {
+        if (rightpart[j+1] == shiftvar)
+        {
+          j++;
+          continue;
+        }
+        if (leadexp(rightpart[j+1])[thetaIndex + nvars(r) div 2]
+            - leadexp(rightpart[j+1])[thetaIndex]!=0)
+        {
+          break;
+        }
+        if (shift_sign<0)
+        {
+          rightpart[j] = subst(rightpart[j+1], theta(thetaIndex),
+                               par(thetaIndex)*theta(thetaIndex)+1);
+        }
+        else
+        {
+          if (shift_sign > 0)
+          {
+            rightpart[j] = subst(rightpart[j+1], theta(thetaIndex),
+                                 1/par(thetaIndex)*(theta(thetaIndex)-1));
+          }
+        }
+        rightpart[j+1] = shiftvar;
+        rparts = rparts + list(rightpart);
+      }
+      //And now, we put all possibilities together
+      tempadd = list();
+      for (j = 1; j<=size(lparts); j++)
+      {
+        for (k = 1; k<=size(rparts);k++)
+        {
+          tempadd = tempadd + list(lparts[j]+rparts[k]);
+        }
+      }
+      tempadd = delete(tempadd,1); // The first entry is already in the list
+      result = result + tempadd;
+      continue; //We can may be not be done already with the ith entry
+    }//One entry was theta resp. theta +1
+  }//checking every entry of result for theta or theta +1
+  dbprint(p,dbprintWhitespace +" Done");
+  dbprint(p,dbprintWhitespace + "The new result list is:");
+  dbprint(result);
+  setring(r);
+  ideal finalMapList;
+  for(i = 1; i<=nvars(r);i++)
+  {
+    finalMapList[i] = var(i);
+  }
+  for (i = 1; i<=nvars(r) div 2; i++)
+  {
+    finalMapList[i + nvars(r)] = var(i)*var(i + (nvars(r) div 2));
+  }
+  map finalmap = tempRing,finalMapList;
+  list result = finalmap(result);
+  for (i=1; i<=size(result);i++)
+  {//adding the K factor
+    result[i] = k_factor + result[i];
+  }//adding the k-factor
+  dbprint(p,dbprintWhitespace +" Done");
+  dbprint(p,dbprintWhitespace +" Delete double entries in the list.");
+  result = delete_dublicates_noteval(result);
+  dbprint(p,dbprintWhitespace +" Done");
+  return(normalizeFactors(result));
+}//proc homogfacNthQWeyl_all
+example
+{
+  "EXAMPLE:";echo=2;
+  ring R = (0,q1,q2,q3),(x1,x2,x3,d1,d2,d3),dp;
+  matrix C[6][6] = 1,1,1,q1,1,1,
+    1,1,1,1,q2,1,
+    1,1,1,1,1,q3,
+    1,1,1,1,1,1,
+    1,1,1,1,1,1,
+    1,1,1,1,1,1;
+  matrix D[6][6] = 0,0,0,1,0,0,
+    0,0,0,0,1,0,
+    0,0,0,0,0,1,
+    -1,0,0,0,0,0,
+    0,-1,0,0,0,0,
+    0,0,-1,0,0,0;
+  def r = nc_algebra(C,D);
+  setring(r);
+  poly h =x1*x2^2*x3^3*d1*d2^2+x2*x3^3*d2;
+  homogfacNthQWeyl_all(h);
+}
+
+//==================================================
+// EASY EXAMPLES FOR WEYL ALGEBRA
+//==================================================
+/*
+  Easy and fast example polynomials where one can find factorizations: K<x,d |dx=xd+1>
+  (x^2+d)*(x^2+d);
+  (x^2+x)*(x^2+d);
+  (x^3+x+1)*(x^4+d*x+2);
+  (x^2*d+d)*(d+x*d);
+  d^3+x*d^3+2*d^2+2*(x+1)*d^2+d+(x+2)*d; //Example 5 Grigoriev-Schwarz.
+  (d+1)*(d+1)*(d+x*d); //Landau Example projected to the first dimension.
+*/
+
+//==================================================
+//Some Bugs(fixed)/hard examples from Martin Lee:
+//==================================================
+// ex1, ex2
+/*
+ring s = 0,(x,d),Ws(-1,1);
+def S = nc_algebra(1,1); setring S;
+poly a = 10x5d4+26x4d5+47x5d2-97x4d3; //Not so hard any more... Done in around 4 minutes
+def l= facFirstWeyl (a); l;
+kill l;
+poly b = -5328x8d5-5328x7d6+720x9d2+720x8d3-16976x7d4-38880x6d5
+-5184x7d3-5184x6d4-3774x5d5+2080x8d+5760x7d2-6144x6d3-59616x5d4
++3108x3d6-4098x6d2-25704x5d3-21186x4d4+8640x6d-17916x4d3+22680x2d5
++2040x5d-4848x4d2-9792x3d3+3024x2d4-10704x3d2-3519x2d3+34776xd4
++12096xd3+2898d4-5040x2d+8064d3+6048d2; //Still very hard... But it seems to be only because of the
+//combinatorial explosion
+def l= facFirstWeyl (b); l;
+
+// ex3: there was difference in answers => fixed
+LIB "ncfactor.lib";
+ring r = 0,(x,y,z),dp;
+matrix D[3][3]; D[1,3]=-1;
+def R = nc_algebra(1,D);
+setring R;
+poly g= 7*z4*x+62*z3+26*z;
+def l1= facSubWeyl (g, x, z);
+l1;
+//---- other ring
+ring s = 0,(x,z),dp;
+def S = nc_algebra(1,-1); setring S;
+poly g= 7*z4*x+62*z3+26*z;
+def l2= facFirstWeyl (g);
+l2;
+map F = R,x,0,z;
+list l1 = F(l1);
+l1;
+//---- so the answers look different, check them!
+testNCfac(l2); // ok
+testNCfac(l1); // was not ok, but now it's been fixed!!!
+
+// selbst D und X so vertauschen dass sie erfuellt ist : ist gemacht
+
+*/
+
+/*
+// bug from M Lee
+LIB "ncfactor.lib";
+ring s = 0,(z,x),dp;
+def S = nc_algebra(1,1); setring S;
+poly f= -60z4x2-54z4-56zx3-59z2x-64;
+def l= facFirstWeyl (f);
+l; // before: empty list; after fix: 1 entry, f is irreducible
+poly g = 75z3x2+92z3+24;
+def l= facFirstWeyl (g);
+l; //before: empty list, now: correct
+*/
+
+/* more things from Martin Lee; fixed
+ring R = 0,(x,s),dp;
+def r = nc_algebra(1,s);
+setring(r);
+poly h = (s2*x+x)*s;
+h= h* (x+s);
+def l= facFirstShift(h);
+l; // contained doubled entries: not anymore, fixed!
+
+ring R = 0,(x,s),dp;
+def r = nc_algebra(1,-1);
+setring(r);
+poly h = (s2*x+x)*s;
+h= h* (x+s);
+def l= facFirstWeyl(h);
+l; // contained doubled entries: not anymore, fixed!
+
+*/
+
+//======================================================================
+//Examples from TestSuite that are terminating in a reasonable time.
+//======================================================================
+
+//Counter example for old Algorithm, but now working:
+/*
+ring R = 0,(x,d),dp;
+def r = nc_algebra(1,1);
+setring(r);
+LIB "ncfactor.lib";
+poly h = (1+x^2*d)^4;
+list lsng = facFirstWeyl(h);
+print(lsng);
+*/
+
+//Example 2.7. from Master thesis
+/*
+ring R = 0,(x,d),dp;
+def r = nc_algebra(1,1);
+setring(r);
+LIB "ncfactor.lib";
+poly h = (xdd + xd+1+ (xd+5)*x)*(((x*d)^2+1)*d + xd+3+ (xd+7)*x);
+list lsng = facFirstWeyl(h);
+print(lsng);
+ */
+
+//Example with high combinatorial income
+/*
+ring R = 0,(x,d),dp;
+def r = nc_algebra(1,1);
+setring(r);
+LIB "ncfactor.lib";
+poly h = (xdddd + (xd+1)*d*d+ (xd+5)*x*d*d)*(((x*d)^2+1)*d*x*x + (xd+3)*x*x+ (xd+7)*x*x*x);
+list lsng = facFirstWeyl(h);
+print(lsng);
+ */
+
+//Once a bug, now working
+/*
+ring R = 0,(x,d),dp;
+def r = nc_algebra(1,1);
+setring(r);
+LIB "ncfactor.lib";
+poly h = (x^2*d^2+x)*(x+1);
+list lsng = facFirstWeyl(h);
+print(lsng);
+*/
+
+//Another one of that kind
+/*
+ring R = 0,(x,d),dp;
+def r = nc_algebra(1,1);
+setring(r);
+LIB "ncfactor.lib";
+poly h = (x*d*d + (x*d)^5 +x)*((x*d+1)*d-(x*d-1)^5+x);
+list lsng = facFirstWeyl(h);
+print(lsng);
+ */
+
+//Example of Victor for Shift Algebra
+/*
+ring s = 0,(n,Sn),dp;
+def S = nc_algebra(1,Sn); setring S;
+LIB "ncfactor.lib";
+list lsng = facFirstShift(n^2*Sn^2+3*n*Sn^2-n^2+2*Sn^2-3*n-2);
+print(lsng);
+ */
+
+//Interesting example, as there are actually also some complex solutions to it:
+/*
+ring R = 0,(x,d),dp;
+def r = nc_algebra(1,1);
+setring(r);
+LIB "/Users/albertheinle/Studium/forschung/ncfactor/versionen/ncfactor.lib";
+poly h =(x^3+x+1)*(x^4+d*x+2);//Example for finitely many, but more than one solution in between.
+list lsng = facFirstWeyl(h);
+print(lsng);
+ */
+
+//Another one of that kind:
+/*
+ring R = 0,(x,d),dp;
+def r = nc_algebra(1,1);
+setring(r);
+LIB "ncfactor.lib";
+poly h =(x^2+d)*(x^2+d);//Example for finitely many, but more than one solution in between.
+list lsng = facFirstWeyl(h);
+print(lsng);
+*/
+
+//Example by W. Koepf:
+/*
+ring R = 0,(x,d),dp;
+def r = nc_algebra(1,1);
+setring(r);
+LIB "ncfactor.lib";
+poly h = (x^4-1)*x*d^2+(1+7*x^4)*d+8*x^3;
+list lsng = facFirstWeyl(h);
+print(lsng);
+ */
+
+//Shift Example from W. Koepf
+/*
+ring R = 0,(n,s),dp;
+def r = nc_algebra(1,s);
+setring(r);
+LIB "ncfactor.lib";
+poly h = n*(n+1)*s^2-2*n*(n+100)*s+(n+99)*(n+100);
+list lsng = facFirstShift(h);
+print(lsng);
+ */
+
+//Tsai Example... Once hard, now easy...
+/*
+ring R = 0,(x,d),dp;
+def r = nc_algebra(1,1);
+setring(r);
+LIB "ncfactor.lib";
+poly h = (x^6+2*x^4-3*x^2)*d^2-(4*x^5-4*x^4-12*x^2-12*x)*d + (6*x^4-12*x^3-6*x^2-24*x-12);
+list lsng =facFirstWeyl(h);
+print(lsng);
+ */
+
+//======================================================================
+// Hard examples not yet calculatable in feasible amount of time
+//======================================================================
+
+//Also a counterexample for REDUCE. Very long Groebner basis computation in between.
+/*
+ring R = 0,(x,d),dp;
+def r = nc_algebra(1,1);
+setring(r);
+LIB "ncfactor.lib";
+poly h = (d^4+x^2+dx+x)*(d^2+x^4+xd+d);
+list lsng = facFirstWeyl(h);
+print(lsng);
+*/
+
+//Example from the Mainz-Group
+/*
+ring R = 0,(x,d),dp;
+def r = nc_algebra(1,1);
+setring(r);
+poly dop6 = 1/35*x^4*(27-70*x+35*x^2)+ 1/35*x*(32+152*x+100*x^2-59*x^3+210*x^4+105*x^5)*d+
+(-10368/35-67056/35*x-35512/7*x^2-50328/7*x^3-40240/7*x^4-2400*x^5-400*x^6)*d^2+
+(-144/35*(x+1)*(1225*x^5+11025*x^4+37485*x^3+61335*x^2+50138*x+16584)-6912/35*(x+2)*
+(x+1)*(105*x^4+1155*x^3+4456*x^2+7150*x+4212) -27648/35*(x+3)*(x+1)*(35*x^2+350*x+867)*
+(x+2)^2)*d^3;
+LIB "ncfactor.lib";
+printlevel = 5;
+facFirstWeyl(dop6);
+$;*/
+
+//Another Mainz Example:
+/*
+LIB "ncfactor.lib";
+ring R = 0,(x,d),dp;
+def r = nc_algebra(1,1);
+setring(r);
+poly dopp = 82547*x^4*d^4+60237*x^3*d^3+26772*x^5*d^5+2231*x^6*d^6+x*(1140138*
+x^2*d^2-55872*x*d-3959658*x^3*d^3-8381805*x^4*d^4-3089576*x^5*d^5-274786*
+x^6*d^6)+x^2*(-16658622*x*d-83427714*x^2*d^2-19715033*x^3*d^3+78915395*x^4
+*d^4+35337930*x^5*d^5+3354194*x^6*d^6)+x^3*(-99752472-1164881352*x*d+
+4408536996*x^2*d^2+11774185985*x^3*d^3+5262196786*x^4*d^4+1046030561/2*x^5*
+d^5-10564451/2*x^6*d^6)+x^4*(-1925782272+21995375398*x*d+123415803356*x^2*
+d^2+302465300831/2*x^3*d^3+34140803907/2*x^4*d^4-15535653409*x^5*d^5-\
+2277687768*x^6*d^6)+x^5*(71273525520+691398212366*x*d+901772633569*x^2*d^2+
+2281275427069*x^3*d^3+2944352819911/2*x^4*d^4+836872370039/4*x^5*d^5+
+9066399237/4*x^6*d^6)+x^6*(2365174430376+9596715855542*x*d+29459572469704*x^
+2*d^2+92502197003786*x^3*d^3+65712473180525*x^4*d^4+13829360193674*x^5*d^5
++3231449477251/4*x^6*d^6)+x^7*(26771079436836+117709870166226*x*d+
+821686455179082*x^2*d^2+1803972139232179*x^3*d^3+1083654460691481*x^4*d^4+
+858903621851785/4*x^5*d^5+50096565802957/4*x^6*d^6)+x^8*(179341727601960+
+2144653944040630*x*d+13123246960284302*x^2*d^2+41138357917778169/2*x^3*d^3+
+20605819587976401/2*x^4*d^4+3677396642905423/2*x^5*d^5+402688260229369/4*x^6
+*d^6)+x^9*(2579190935961288+43587063726809764*x*d+157045086382352387*x^2*d^
+2+172175668477370223*x^3*d^3+138636285385875407/2*x^4*d^4+10707836398626232*
+x^5*d^5+529435530567584*x^6*d^6)+x^10*(41501953525903392+558336731465626084*
+x*d+1407267553543222268*x^2*d^2+1153046693323226808*x^3*d^3+
+372331468563656085*x^4*d^4+48654019090240214*x^5*d^5+2114661191282167*x^6*d
+^6)+x^11*(364526077273381884+4158060401095928464*x*d+8646807662899324262*x^2*
+d^2+5914675753405705400*x^3*d^3+1631934058875116005*x^4*d^4+
+187371894330537204*x^5*d^5+7366806367019734*x^6*d^6)+x^12*(
+1759850321214603648+18265471270535733520*x*d+34201910114871110912*x^2*d^2+
+21265221434709398152*x^3*d^3+5437363546219595036*x^4*d^4+594029113431041060*
+x^5*d^5+22881659624561644*x^6*d^6)+x^13*(4648382639403200688+
+45699084277107816096*x*d+81049061578449009384*x^2*d^2+48858488665016574368*x
+^3*d^3+12515362110098721444*x^4*d^4+1412152747420021048*x^5*d^5+
+57196947123984972*x^6*d^6)+x^14*(5459369397960020544+55837825300341621824*x*
+d+105671876924055409696*x^2*d^2+71551727420848766624*x^3*d^3+
+21094786205096577808*x^4*d^4+2695663190297032192*x^5*d^5+118791751565613264*
+x^6*d^6)+x^15*(1023333653580043776+47171127937488813824*x*d+
+157258351906685700352*x^2*d^2+145765192195300531840*x^3*d^3+
+49876215785510342176*x^4*d^4+6647374188802036864*x^5*d^5+287310278455067312*
+x^6*d^6)+x^16*(11960091747366236160+250326608568269289472*x*d+
+677587171115580981248*x^2*d^2+538246374825683603456*x^3*d^3+
+161380433451548754048*x^4*d^4+19149099315354950144*x^5*d^5+
+746433247985092544*x^6*d^6)+x^17*(42246252365448668160+657220532737851248640*
+x*d+1531751689216283911680*x^2*d^2+1090829514212206064640*x^3*d^3+
+299280728709430851840*x^4*d^4+32932767387222323200*x^5*d^5+
+1202281367574179840*x^6*d^6)+x^18*(6239106101942784000+320638742839606579200*
+x*d+873857213570556364800*x^2*d^2+645649080101933721600*x^3*d^3+
+177008238160627276800*x^4*d^4+19165088507111475200*x^5*d^5+
+683600826675660800*x^6*d^6)+x^19*(-60440251454613504000-476055211197689856000
+*x*d-733497382597635072000*x^2*d^2-386038662982742016000*x^3*d^3-\
+83361486778142976000*x^4*d^4-7524999543181824000*x^5*d^5-232189492987008000*
+x^6*d^6)+x^20*(1578562930483200000+12628503443865600000*x*d+
+19732036631040000000*x^2*d^2+10523752869888000000*x^3*d^3+
+2302070940288000000*x^4*d^4+210475057397760000*x^5*d^5+6577345543680000*x^6*
+d^6);
+printlevel = 3;
+facFirstWeyl(dopp);
+*/
+
+
+
+//Hard Example by Viktor:
+/*
+  ring r = 0,(x,d), (dp);
+def R = nc_algebra(1,1);
+setring R;
+LIB "ncfactor.lib";
+poly t = x; poly D =d;
+poly p = 2*t^2*D^8-6*t*D^8+2*t^2*D^7+8*t*D^7+12*D^7-2*t^4*D^6+6*t^3*D^6+12*t*D^6-20*D^6
+-2*t^4*D^5-8*t^3*D^5-4*t^2*D^5+12*t*D^5-28*D^5-12*t^3*D^4-4*t^2*D^4-4*t*D^4-24*D^4+4*t^4*D^3
+-12*t^3*D^3+2*t^2*D^3-18*t*D^3+16*D^3+6*t^4*D^2-2*t^3*D^2+2*t^2*D^2-2*t*D^2+44*D^2+2*t^4*D
++12*t^3*D+2*t*D+4*t^3-8;
+list lsng = facFirstWeyl(p);
+print(lsng);
+*/
+
+/*later hard example From Beals-Kartashova paper
+  ring R = 0, (x1,x2,d1,d2),dp;def r = Weyl();setring(r);
+  poly h = d1^2 -d2^2 + x1*d2 + x2*d1 + 1/4*(x2^2 - x1^2) +1;
+ */
diff --git a/Singular/LIB/nchomolog.lib b/Singular/LIB/nchomolog.lib
new file mode 100644
index 0000000..7e0d917
--- /dev/null
+++ b/Singular/LIB/nchomolog.lib
@@ -0,0 +1,760 @@
+////////////////////////////////////////////////////////////////////////////
+version="version nchomolog.lib 4.0.0.0 Jun_2013 "; // $Id: 4d7c72c150b707e8f0f10ce0382d235c8015a98e $
+category="Noncommutative";
+info="
+LIBRARY:  nchomolog.lib   Procedures for Noncommutative Homological Algebra
+AUTHORS:  Viktor Levandovskyy  levandov at math.rwth-aachen.de,
+@*        Christian Schilli, christian.schilli at rwth-aachen.de,
+@*        Gerhard Pfister, pfister at mathematik.uni-kl.de
+
+OVERVIEW: In this library we present tools of homological algebra for
+finitely presented modules over GR-algebras.
+
+PROCEDURES:
+ ncExt_R(k,M);      computes presentation of Ext^k(M',R), M module, R basering, M'=coker(M)
+ ncHom(M,N);        computes presentation of Hom(M',N'), M,N modules, M'=coker(M), N'=coker(N)
+ coHom(A,k);        computes presentation of Hom(R^k,A), A matrix over basering R
+ contraHom(A,k);    computes presentation of Hom(A,R^k),     A matrix over basering R
+ dmodoublext(M, l); computes presentation of Ext_D^i(Ext_D^i(M,D),D), where D is a basering
+ is_cenBimodule(M); checks whether a module presented by M is Artin-centralizing
+ is_cenSubbimodule(M); checks whether a subbimodule M is Artin-centralizing
+";
+
+LIB "dmod.lib";
+LIB "gkdim.lib";
+LIB "involut.lib";
+LIB "nctools.lib";
+LIB "ncalg.lib";
+LIB "central.lib";
+
+//  ncExt(k,M,N);            Ext^k(M',N'),   M,N modules, M'=coker(M), N'=coker(N)
+//  ncTensorMod(M,N);        Tensor product of modules M'=coker(M), N'=coker(N)
+//  ncTor(k,M,N);            Tor_k(M',N'),   M,N modules, M'=coker(M), N'=coker(N)
+//  tensorMaps(M,N);       tensor product of  matrices
+
+
+/* LOG:
+5.12.2012, VL: cleanup, is_cenSubbimodule and is_cenBimodule are added for assume checks;
+added doc for contraHom and coHom; assume check for ncHom etc.
+ */
+
+/* TODO:
+add noncomm examples to important precedures ncHom,
+ */
+
+proc contraHom(matrix M, int s)
+"USAGE:  contraHom(A,k); A matrix, k int
+RETURN:  matrix
+PURPOSE: compute the matrix of a homomorphism Hom(A,R^k), where R is the basering. Let A be a matrix defining a map F1-->F2 of free R-modules, then the matrix of Hom(F2,R^k)-->Hom(F1,R^k) is computed.
+NOTE: if A is matrix of a left (resp. right) R-module homomorphism, then Hom(A,R^k) is a right (resp. left) R-module R-module homomorphism
+EXAMPLE: example contraHom; shows an example.
+SEE ALSO:
+"
+{
+  // also possible: compute with kontrahom from homolog_lib
+  // and warn that the module changes its side
+   int n,m=ncols(M),nrows(M);
+   int a,b,c;
+   matrix R[s*n][s*m];
+   for(b=1; b<=m; b++)
+   {
+      for(a=1; a<=s; a++)
+      {
+         for(c=1; c<=n; c++)
+         {
+            R[(a-1)*n+c,(a-1)*m+b] = M[b,c];
+         }
+      }
+   }
+   return(R);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring A=0,(x,y,z),dp;
+  matrix M[3][3]=1,2,3,
+               4,5,6,
+               7,8,9;
+  module cM = contraHom(M,2);
+  print(cM);
+}
+
+proc coHom(matrix M, int s)
+"USAGE:  coHom(A,k); A matrix, k int
+PURPOSE: compute the matrix of a homomorphism Hom(R^k,A), where R is the basering. Let A be a matrix defining a map F1-->F2 of free R-modules, then the matrix of Hom(R^k,F1)-->Hom(R^k,F2) is computed.
+NOTE: Both A and Hom(A,R^k) are matrices for either left or right R-module homomorphisms
+EXAMPLE: example coHom; shows an example.
+"
+{
+   int n,m=ncols(M),nrows(M);
+   int a,b,c;
+   matrix R[s*m][s*n];
+   for(b=1; b<=s; b++)
+   {
+      for(a=1; a<=m; a++)
+      {
+         for(c=1; c<=n; c++)
+         {
+            R[(a-1)*s+b,(c-1)*s+b] = M[a,c];
+         }
+      }
+   }
+   return(R);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring A=0,(x,y,z),dp;
+  matrix M[3][3]=1,2,3,
+                 4,5,6,
+                 7,8,9;
+  module cM = coHom(M,2);
+  print(cM);
+}
+
+
+proc ncHom(matrix M, matrix N)
+"USAGE:   ncHom(M,N);  M,N modules
+COMPUTE: A presentation of Hom(M',N'), M'=coker(M), N'=coker(N)
+ASSUME: M' is a left module, N' is a centralizing bimodule
+NOTE: ncHom(M,N) is a right module, hence a right presentation matrix
+is returned
+EXAMPLE: example ncHom; shows examples
+"
+{
+  // assume: M is left module; nothing to check
+  // assume: N is centralizing bimodule: to check
+  if ( !is_cenBimodule(N) )
+  {
+    ERROR("Second module in not centralizing.");
+  }
+  // returns a right presentation matrix (for a right module)
+  matrix F  = contraHom(M,nrows(N));
+  matrix B  = coHom(N,ncols(M));
+  matrix C  = coHom(N,nrows(M));
+  def Rbase = basering;
+  def Rop   = opposite(Rbase);
+  setring Rop;
+  matrix Bop = oppose(Rbase, B);
+  matrix Cop = oppose(Rbase, C);
+  matrix Fop = oppose(Rbase, F);
+  matrix Dop = modulo(Fop, Bop);
+  matrix Eop = modulo(Dop, Cop);
+  setring Rbase;
+  matrix E   = oppose(Rop, Eop);
+  kill Rop;
+  return(E);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring A=0,(x,y,z),dp;
+  matrix M[3][3]=1,2,3,
+                 4,5,6,
+                 7,8,9;
+  matrix N[2][2]=x,y,
+                 z,0;
+  module H = ncHom(M,N);
+  print(H);
+}
+
+proc ncHom_alt(matrix M, matrix N)
+{
+  // shorter but potentially slower
+  matrix F = contraHom(M,nrows(N)); // \varphi^*
+  matrix B = coHom(N,ncols(M));     // i
+  matrix C = coHom(N,nrows(M));     // j
+  matrix D = rightModulo(F,B);      // D
+  matrix E = rightModulo(D,C);      // Hom(M,N)
+  return(E);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring A=0,(x,y,z),dp;
+  matrix M[3][3]=1,2,3,
+                 4,5,6,
+                 7,8,9;
+  matrix N[2][2]=x,y,
+                 z,0;
+  module H = ncHom_alt(M,N);
+  print(H);
+}
+
+proc ncHom_R(matrix M)
+"USAGE:   ncHom_R(M);  M a module
+COMPUTE: A presentation of Hom_R(M',R), M'=coker(M)
+ASSUME: M' is a left module
+NOTE: ncHom_R(M) is a right module, hence a right presentation matrix is returned
+EXAMPLE: example ncHom_R;  shows examples
+"
+{
+  // assume: M is left module
+  // returns a right presentation matrix
+  // for a right module
+  matrix F  = transpose(M);
+  def Rbase = basering;
+  def Rop   = opposite(Rbase);
+  setring Rop;
+  matrix Fop = oppose(Rbase, F);
+  matrix Dop = modulo(Fop, std(0)); //ker Hom(A^n,A) -> Hom(A^m,A)
+  matrix Eop = modulo(Dop, std(0)); // its presentation
+  setring Rbase;
+  matrix E   = oppose(Rop, Eop);
+  kill Rop;
+  return(E);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring A=0,(x,t,dx,dt),dp;
+  def W = Weyl(); setring W;
+  matrix M[2][2] =
+    dt,  dx,
+    t*dx,x*dt;
+  module H = ncHom_R(M);
+  print(H);
+  matrix N[2][1] = x,dx;
+  H = ncHom_R(N);
+  print(H);
+}
+
+
+proc is_cenBimodule(module M)
+"USAGE: is_cenBimodule(M);  M module
+COMPUTE: 1, if a module, presented by M can be centralizing in the sense of Artin and 0 otherwise
+NOTE: only one condition for centralizing factor module can be checked algorithmically
+EXAMPLE: example is_cenBimodule;  shows examples
+"
+{
+  // define in a ring R, for a module R: cen(M) ={ m in M: mr = rm for all r in R}
+  // according to the definition, M is a centralizing bimodule <=> M is generated by cen(M)
+  // if basering R is a G-algebra, then prop 6.4 of BGV indicates it's enough to provide
+  // commutation of elements of M with the generators x_i of R
+  // prop 6.4 verbatim generalizes to  R = R'/I for a twosided I.
+  // is M generates submodule, see the proc is_cenSubbimodule
+  // let M be a presentation matrix for P=R*/R*M, then [e_i + M]x_j=x_j[e_i+M]
+  // <=> Mx_j - x_jM in M must hold; thus forall j: Mx_j in M; thus M has to be
+  // closed from the right, that is to be a two-sided submodule indeed
+  // the rest of checks are complicated by now, so do the check only
+  // *the algorithm *//
+  if (isCommutative() ) { return(int(1));}
+  int n = nvars(basering);
+  int ans = 0;
+  int i,j;
+  vector P;
+  module N;
+  if ( attrib(M,"isSB") != 1)
+  {
+    N = std(M);
+  }
+  else
+  {
+    N = M;
+  }
+  // N is std(M) now
+  for(i=1; i<=ncols(M); i++)
+  {
+    P = M[i];
+    if (P!=0)
+    {
+      for(j=1; j<=n; j++)
+      {
+        if ( NF(P*var(j) - var(j)*P, N) != 0)
+        {
+          return(ans);
+        }
+      }
+    }
+  }
+  ans = 1;
+  return(ans);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  def A = makeUsl2(); setring A;
+  poly p = 4*e*f + h^2-2*h; // generator of the center
+  matrix M[2][2] = p, p^2-7,0,p*(p+1);
+  is_cenBimodule(M); // M is centralizing
+  matrix N[2][2] = p, e*f,h,p*(p+1);
+  is_cenBimodule(N); // N is not centralizing
+}
+
+proc is_cenSubbimodule(module M)
+"USAGE: is_cenSubbimodule(M); M module
+COMPUTE: 1, if a subbimodule, generated by the columns of M is
+centralizing in the sense of Artin and 0 otherwise
+EXAMPLE: example is_cenSubbimodule;  shows examples
+"
+{
+  // note: M in R^m is centralizing subbimodule iff it is generated by vectors,
+  // each nonconstant component of which is central; 2 check: every entry of the
+  // matrix M is central
+  if (isCommutative()) { return(int(1));}
+  return( inCenter(ideal(matrix(M))) );
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  def A = makeUsl2(); setring A;
+  poly p = 4*e*f + h^2-2*h; // generator of the center
+  matrix M[2][2] = p, p^2-7,0,p*(p+1);
+  is_cenSubbimodule(M); // M is centralizing subbimodule
+  matrix N[2][2] = p, e*f,h,p*(p+1);
+  is_cenSubbimodule(N); // N is not centralizing subbimodule
+}
+
+
+proc ncExt(int i, matrix Ps, matrix Ph)
+"USAGE:   Ext(i,M,N);  i int, M,N matrices
+COMPUTE: A presentation of Ext^i(M',N');  for M'=coker(M) and N'=coker(N).
+ASSUME: M' is a left  module, N' is a centralizing bimodule
+NOTE: ncExt(M,N) is a right module, hence a right presentation matrix
+is returned
+EXAMPLE: example ncExt;  shows examples
+"
+{
+  if ( !is_cenBimodule(Ph) )
+  {
+    ERROR("Second module in not centralizing.");
+  }
+
+  if(i==0) { return(module(ncHom(Ps,Ph))); }
+  list Phi   = mres(Ps,i+1);
+  module Im  = coHom(Ph,ncols(Phi[i+1]));
+  module f   = contraHom(matrix(Phi[i+1]),nrows(Ph));
+  module Im1 = coHom(Ph,ncols(Phi[i]));
+  module Im2 = contraHom(matrix(Phi[i]),nrows(Ph));
+  def Rbase = basering;
+  def Rop   = opposite(Rbase);
+  setring Rop;
+  module fop    = oppose(Rbase,f);
+  module Imop   = oppose(Rbase,Im);
+  module Im1op  = oppose(Rbase,Im1);
+  module Im2op  = oppose(Rbase,Im2);
+  module ker_op = modulo(fop,Imop);
+  module ext_op = modulo(ker_op,Im1op+Im2op);
+  //  ext        = prune(ext);
+ // to be discussed and done prune_from_the_left
+  setring Rbase;
+  module ext = oppose(Rop,ext_op);
+  kill Rop;
+  return(ext);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring R     = 0,(x,y),dp;
+  ideal I    = x2-y3;
+  qring S    = std(I);
+  module M   = [-x,y],[-y2,x];
+  module E1  = ncExt(1,M,M);
+  E1;
+}
+
+proc ncExt_R(int i, matrix Ps)
+"USAGE:   ncExt_R(i, M);  i int, M module
+COMPUTE:  a presentation of Ext^i(M',R); for M'=coker(M).
+RETURN:   right module Ext, a presentation of Ext^i(M',R)
+EXAMPLE: example ncExt_R; shows an example
+"{
+  if (i==0)
+  {
+    return(ncHom_R(Ps)); // the rest is not needed
+  }
+  list Phi   = nres(Ps,i+1); // left resolution
+  module f   = transpose(matrix(Phi[i+1])); // transp. because of Hom_R
+  module Im2 = transpose(matrix(Phi[i]));
+  def Rbase = basering;
+  def Rop   = opposite(Rbase);
+  setring Rop;
+  module fop    = oppose(Rbase,f);
+  module Im2op  = oppose(Rbase,Im2);
+  module ker_op = modulo(fop,std(0));
+  module ext_op = modulo(ker_op,Im2op);
+  //  ext        = prune(ext);
+  // to be discussed and done prune_from_the_left
+  // necessary: compute SB!
+  // "Computing SB of Ext";
+//   option(redSB);
+//   option(redTail);
+//   ext_op = std(ext_op);
+//   int dimop = GKdim(ext_op);
+//   printf("Ext has dimension %s",dimop);
+//   if (dimop==0)
+//   {
+//       printf("of K-dimension %s",vdim(ext_op));
+//   }
+  setring Rbase;
+  module ext = oppose(Rop,ext_op); // a right module!
+  kill Rop;
+  return(ext);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring R     = 0,(x,y),dp;
+  poly F    = x2-y2;
+  def A = annfs(F);  setring A; // A is the 2nd Weyl algebra
+  matrix M[1][size(LD)] = LD; // ideal
+  print(M);
+  print(ncExt_R(1,M)); // hence the Ext^1 is zero
+  module E  = ncExt_R(2,M); // define the right module E
+  print(E); // E is in the opposite algebra
+  def Aop = opposite(A);  setring Aop;
+  module Eop = oppose(A,E);
+  module T1  = ncExt_R(2,Eop);
+  setring A;
+  module T1 = oppose(Aop,T1);
+  print(T1); // this is a left module Ext^2(Ext^2(M,A),A)
+  print(M); // it is known that M holonomic implies Ext^2(Ext^2(M,A),A) iso to M
+}
+
+proc nctors(matrix M)
+{
+  // ext^1_A(adj(M),A)
+  def save = basering;
+  matrix MM = M;  // left
+  def sop = opposite(save);
+  setring sop;
+  matrix MM  = oppose(save,MM); // right
+  MM = transpose(MM); // transposed
+  list Phi = nres(MM,2); // i=1
+  module f   = transpose(matrix(Phi[2])); // transp. because of Hom_R
+  module Im2 = transpose(matrix(Phi[1]));
+  setring save;
+  module fop    = oppose(sop,f);
+  module Im2op  = oppose(sop,Im2);
+  module ker_op = modulo(fop,std(0));
+  module ext_op = modulo(ker_op,Im2op);
+  //  matrix E = ncExt_R(1,MM);
+  //  setring save;
+  //  matrix E = oppose(sop,E);
+  return(ext_op);
+}
+
+proc altExt_R(int i, matrix Ps, map Invo)
+  // TODO!!!!!!!!
+  // matrix Ph
+  // work thru Involutions;
+{
+  if(i==0)
+  { // return the formal adjoint
+    matrix Ret   = transpose(Ps);
+    matrix Retop = involution(Ret, Invo);
+    //    "Computing prune of Hom";
+    //    Retop = prune(Retop);
+    //    Retop = std(Retop);
+    return(Retop);
+  }
+  list Phi   = mres(Ps,i+1);
+  //  module Im  = coHom(Ph,ncols(Phi[i+1]));
+  module f   = transpose(matrix(Phi[i+1]));
+  f = involution(f, Invo);
+  //= contraHom(matrix(Phi[i+1]),nrows(Ph));
+  //  module Im1 = coHom(Ph,ncols(Phi[i]));
+  module Im2 = transpose(matrix(Phi[i]));
+  Im2 = involution(Im2, Invo);
+  //contraHom(matrix(Phi[i]),nrows(Ph));
+  module ker_op = modulo(f,std(0));
+  module ext_op = modulo(ker_op,Im2);
+  //  ext        = prune(ext);
+ // to be discussed and done prune_from_the_left
+  // optionally: compute SB!
+  //  "Computing prune of Ext";
+  ext_op = std(ext_op);
+  int dimop = GKdim(ext_op);
+  printf("Ext has dimension %s",dimop);
+  if (dimop==0)
+  {
+      printf("of K-dimension %s",vdim(ext_op));
+  }
+  module ext = involution(ext_op, Invo); // what about transpose?
+  return(ext);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring R     = 0,(x,y),dp;
+  ideal I    = x2-y3;
+  qring S    = std(I);
+  module M   = [-x,y],[-y2,x];
+  module E1  = ncExt(2,M,M);
+  E1;
+}
+
+proc tensorMaps(matrix M, matrix N)
+{
+   int r = ncols(M);
+   int s = nrows(M);
+   int p = ncols(N);
+   int q = nrows(N);
+   int a,b,c,d;
+   matrix R[s*q][r*p];
+   for(b=1;b<=p;b++)
+   {
+      for(d=1;d<=q;d++)
+      {
+         for(a=1;a<=r;a++)
+         {
+            for(c=1;c<=s;c++)
+            {
+               R[(c-1)*q+d,(a-1)*p+b]=M[c,a]*N[d,b];
+            }
+         }
+      }
+   }
+   return(R);
+}
+
+proc ncTensorMod(matrix Phi, matrix Psi)
+{
+   int s=nrows(Phi);
+   int q=nrows(Psi);
+   matrix A=tensorMaps(unitmat(s),Psi);  //I_s tensor Psi
+   matrix B=tensorMaps(Phi,unitmat(q));  //Phi tensor I_q
+   matrix R=concat(A,B);                 //sum of A and B
+   return(R);
+}
+
+
+proc ncTor(int i, matrix Ps, matrix Ph)
+{
+  if(i==0) { return(module(ncTensorMod(Ps,Ph))); }
+                               // the tensor product
+  list Phi   = mres(Ph,i+1);     // a resolution of Ph
+  module Im  = tensorMaps(unitmat(nrows(Phi[i])),Ps);
+  module f   = tensorMaps(matrix(Phi[i]),unitmat(nrows(Ps)));
+  module Im1 = tensorMaps(unitmat(ncols(Phi[i])),Ps);
+  module Im2 = tensorMaps(matrix(Phi[i+1]),unitmat(nrows(Ps)));
+  module ker = modulo(f,Im);
+  module tor = modulo(ker,Im1+Im2);
+  //  tor        = prune(tor);
+  return(tor);
+}
+
+
+static proc Hochschild()
+{
+  ring A    = 0,(x,y),dp;
+  ideal I   = x2-y3;
+  qring B   = std(I);
+  module M  = [-x,y],[-y2,x];
+  ring C    = 0,(x,y,z,w),dp; // x->z, y->w
+  ideal I   = x2-y3,z3-w2;
+  qring Be  = std(I);   //the enveloping algebra
+  matrix AA[1][2]  = x-z,y-w;  //the presentation of the algebra B as Be-module
+  module MM = imap(B,M);
+  module E = ncExt(1,AA,MM);
+  print(E);  //the presentation of the H^1(A,M)
+
+ring A          = 0,(x,y),dp;
+ideal I         = x2-y3;
+qring B         = std(I);
+ring C          = 0,(x,y,z,w),dp;
+ideal I         = x2-y3,z3-w2;
+qring Be        = std(I);   //the enveloping algebra
+matrix AA[1][2] = x-z,y-w;  //the presentation of B as Be-module
+matrix AAA[1][2] = z,w; // equivalent? pres. of B
+print(ncExt(1,AA,AA));  //the presentation of the H^1(A,A)
+print(ncExt(1,AAA,AAA));
+}
+
+static proc Lie()
+{
+// consider U(sl2)* U(sl2)^opp;
+LIB "ncalg.lib";
+ring A = 0,(e,f,h,H,F,E),Dp; // any degree ordering
+int N = 6; // nvars(A);
+matrix @D[N][N];
+ at D[1,2] = -h;
+ at D[1,3] = 2*e;
+ at D[2,3] = -2*f;
+ at D[4,5] = 2*F;
+ at D[4,6] = -2*E;
+ at D[5,6] = H;
+ def AA = nc_algebra(1, at D); setring AA;
+ideal Q = E,F,H;
+poly Z = 4*e*f+h^2-2*h; // center
+poly Zo = 4*F*E+H^2+2*H;  // center opposed
+ideal Qe = Z,Zo;
+//qring B = twostd(Qe);
+//ideal T = e-E,f-F,h-H;
+//ideal T2 = e-H,f-F,h-E;
+//Q = twostd(Q); // U is U(sl2) as left U(sl2)* U(sl2)^opp -- module
+matrix M[1][3] = E,F,H;
+module X0 = ncExt(0,M,M);
+print(X0);
+
+module X1 = ncExt(1,M,M);
+print(X1);
+module X2 = ncExt(2,M,M); // equal to Tor^Z_1(K,K)
+print(X2);
+
+// compute  Tor^Z_1(K,K)
+ring r = 0,(z),dp;
+ideal i = z;
+matrix I[1][1]=z;
+Tor(1,I,I);
+}
+
+
+proc AllExts(module N, list #)
+  // computes and shows everything
+  // assumes we are in the opposite
+  // and N is dual of some M
+  // if # is given, map Invo and Ext_Invo are used
+{
+  int UseInvo = 0;
+  int sl = size(#);
+  if (sl >0)
+  {
+    ideal I = ideal(#[1]);
+    map Invo = basering, I;
+    UseInvo  = 1;
+    "Using the involution";
+  }
+  int nv = nvars(basering);
+  int i,d;
+  module E;
+  list EE;
+  print("--- module:"); print(matrix(N));
+  for (i=1; i<=nv; i++)
+  {
+    if (UseInvo)
+    {
+      E = altExt_R(i,N,Invo);
+    }
+    else
+    {
+      E = ncExt_R(i,N);
+    }
+    printf("--- Ext %s",i);
+    print(matrix(E));
+    EE[i] = E;
+  }
+  return(E);
+}
+
+proc dmodualtest(module M, int n)
+{
+  // computes the "dual" of the "dual" of a d-mod M
+  // where n is the half-number of vars of Weyl algebra
+  // assumed to be basering
+  // returns the difference between M and Ext^n_D(Ext^n_D(M,D),D)
+  def save = basering;
+  setring save;
+  module Md = ncExt_R(n,M); // right module
+  // would be nice to use "prune"!
+  // NO! prune performs left sided operations!!!
+  //  Md = prune(Md);
+  //  print(Md);
+  def saveop = opposite(save);
+  setring saveop;
+  module Mdop = oppose(save,Md); // left module
+  // here we're eligible to use prune
+  Mdop = prune(Mdop);
+  module Mopd = ncExt_R(n,Mdop); // right module
+  setring save;
+  module M2 = oppose(saveop,Mopd);  // left module
+  M2 = prune(M2); // eligible since M2 is a left mod
+  M2 = groebner(M2);
+  ideal tst = M2 - M;
+  tst = groebner(tst);
+  return(tst);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring R   = 0,(x,y),dp;
+  poly F   = x3-y2;
+  def A    = annfs(F);
+  setring A;
+  dmodualtest(LD,2);
+}
+
+
+proc dmodoublext(module M, list #)
+"USAGE:   dmodoublext(M [,i]);  M module, i optional int
+COMPUTE:  a presentation of Ext^i(Ext^i(M,D),D) for basering D
+RETURN:   left module
+NOTE: by default, i is set to the integer part of the half of number of variables of D
+@* for holonomic modules over Weyl algebra, the double ext is known to be holonomic left module
+EXAMPLE: example dmodoublext; shows an example
+"
+{
+  // assume: basering is a Weyl algebra?
+  def save = basering;
+  setring save;
+  // if a list is nonempty and contains an integer N, n = N; otherwise n = nvars/2
+  int n;
+  if (size(#) > 0)
+  {
+    //    if (typeof(#) == "int")
+    //    {
+      n = int(#[1]);
+      //    }
+//     else
+//     {
+//       ERROR("the optional argument expected to have type int");
+//     }
+  }
+  else
+  {
+    n = nvars(save); n = n div 2;
+  }
+  // returns Ext^i_D(Ext^i_D(M,D),D), that is
+  // computes the "dual" of the "dual" of a d-mod M (for n = nvars/2)
+  module Md = ncExt_R(n,M); // right module
+  // no prune yet!
+  def saveop = opposite(save);
+  setring saveop;
+  module Mdop = oppose(save,Md); // left module
+  // here we're eligible to use prune
+  Mdop = prune(Mdop);
+  module Mopd = ncExt_R(n,Mdop); // right module
+  setring save;
+  module M2 = oppose(saveop,Mopd);  // left module
+  kill saveop;
+  M2 = prune(M2); // eligible since M2 is a left mod
+  def M3;
+  if (nrows(M2)==1)
+  {
+    M3 = ideal(M2);
+  }
+  else
+  {
+    M3 = M2;
+  }
+  M3 = groebner(M3);
+  return(M3);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring R   = 0,(x,y),dp;
+  poly F   = x3-y2;
+  def A    = annfs(F);
+  setring A;
+  dmodoublext(LD);
+  LD;
+  // fancier example:
+  setring A;
+  ideal I = Dx*(x2-y3),Dy*(x2-y3);
+  I = groebner(I);
+  print(dmodoublext(I,1));
+  print(dmodoublext(I,2));
+}
+
+static proc part_Ext_R(matrix M)
+{
+  // if i==0
+    matrix Ret = transpose(Ps);
+    def Rbase = basering;
+    def Rop   = opposite(Rbase);
+    setring Rop;
+    module Retop = oppose(Rbase,Ret);
+    module Hm = modulo(Retop,std(0)); // right kernel of transposed
+    //    "Computing prune of Hom";
+    //    Retop = prune(Retop);
+    //    Retop = std(Retop);
+    setring Rbase;
+    Ret = oppose(Rop, Hm);
+    kill Rop;
+    return(Ret);
+// some checkz:
+//  setring Rbase;
+  // ker_op is the right Kernel of f^t:
+  //  module ker = oppose(Rop,ker_op);
+  //  print(f*ker);
+//  module ext = oppose(Rop,ext_op);
+}
diff --git a/Singular/LIB/ncpreim.lib b/Singular/LIB/ncpreim.lib
new file mode 100644
index 0000000..3827699
--- /dev/null
+++ b/Singular/LIB/ncpreim.lib
@@ -0,0 +1,796 @@
+/////////////////////////////////////////////////////////////////////
+version="version ncpreim.lib 4.0.0.0 Jun_2013 "; // $Id: fcca2c37ec1caedea6c6ad3cd032dcf4bedf44e7 $
+category="Noncommutative";
+info="
+LIBRARY: ncpreim.lib    Non-commutative elimination and preimage computations
+AUTHOR:  Daniel Andres, daniel.andres at math.rwth-aachen.de
+
+Support: DFG Graduiertenkolleg 1632 `Experimentelle und konstruktive Algebra'
+
+
+OVERVIEW:
+In G-algebras, elimination of variables is more involved than in the
+commutative case.
+One, not every subset of variables generates an algebra, which is again a
+G-algebra.
+Two, even if the subset of variables in question generates an admissible
+subalgebra, there might be no admissible elimination ordering, i.e. an
+elimination ordering which also satisfies the ordering condition for
+G-algebras.
+
+The difference between the procedure @code{eliminateNC} provided in this
+library and the procedure @code{eliminate (plural)} from the kernel is that
+eliminateNC will always find an admissible elimination if such one exists.
+Moreover, the use of @code{slimgb} for performing Groebner basis computations
+is possible.
+
+As an application of the theory of elimination, the procedure @code{preimageNC}
+is provided, which computes the preimage of an ideal under a homomorphism
+f: A -> B between G-algebras A and B. In contrast to the kernel procedure
+ at code{preimage (plural)}, the assumption that A is commutative is not required.
+
+
+REFERENCES:
+   (BGL) J.L. Bueso, J. Gomez-Torrecillas, F.J. Lobillo:
+         `Re-filtering and exactness of the Gelfand-Kirillov dimension',
+         Bull. Sci. math. 125, 8, 689-715, 2001.
+@* (GML) J.I. Garcia Garcia, J. Garcia Miranda, F.J. Lobillo:
+         `Elimination orderings and localization in PBW algebras',
+         Linear Algebra and its Applications 430(8-9), 2133-2148, 2009.
+@* (Lev) V. Levandovskyy: `Intersection of ideals with non-commutative
+         subalgebras', ISSAC'06, 212-219, ACM, 2006.
+
+
+PROCEDURES:
+eliminateNC(I,v,eng);      elimination in G-algebras
+preimageNC(A,f,J[,P,eng]); preimage of ideals under homomorphisms of G-algebras
+admissibleSub(v);          checks whether subalgebra is admissible
+isUpperTriangular(M,k);    checks whether matrix is (strictly) upper triangular
+appendWeight2Ord(w);       appends weight to ordering
+elimWeight(v);             computes elimination weight
+extendedTensor(A,I);       tensor product of rings with additional relations
+
+
+KEYWORDS: preimage; elimination
+
+
+SEE ALSO: elim_lib, preimage (plural)
+";
+
+
+LIB "elim.lib";    // for nselect
+LIB "nctools.lib"; // for makeWeyl etc.
+LIB "dmodapp.lib"; // for sortIntvec
+LIB "ncalg.lib";   // for makeUgl
+LIB "dmodloc.lib"; // for commRing
+
+
+/*
+CHANGELOG
+11.12.12: docu, typos, fixed variable names in extendedTensor,
+ moved commRing to dmodloc.lib
+12.12.12: typos
+17.12.12: docu
+24.09.13: bugfix preimageNC naming conflict if f is map from ring called 'B'
+*/
+
+
+// -- Testing for consistency of the library ---------------
+
+static proc testncpreimlib()
+{
+  example admissibleSub;
+  example isUpperTriangular;
+  example appendWeight2Ord;
+  example elimWeight;
+  example eliminateNC;
+  example extendedTensor;
+  example preimageNC;
+}
+
+
+// -- Tools ------------------------------------------------
+
+
+proc admissibleSub (intvec v)
+"
+USAGE:    admissibleSub(v);  v intvec
+ASSUME:   The entries of v are in the range 1..nvars(basering).
+RETURN:   int, 1 if the variables indexed by the entries of v form an
+          admissible subalgebra, 0 otherwise
+EXAMPLE:  example admissibleSub; shows examples
+"
+{
+  v = checkIntvec(v);
+  int i,j;
+  list RL = ringlist(basering);
+  if (size(RL) == 4)
+  {
+    return(int(1));
+  }
+  matrix D = RL[6];
+  ideal I;
+  for (i=1; i<=size(v); i++)
+  {
+    for (j=i+1; j<=size(v); j++)
+    {
+      I[size(I)+1] = D[v[j],v[i]];
+    }
+  }
+  ideal M = maxideal(1);
+  ideal J = M[v];
+  attrib(J,"isSB",1);
+  M = NF(M,J);
+  M = simplify(M,2); // get rid of double entries in v
+  intvec opt = option(get);
+  attrib(M,"isSB",1);
+  option("redSB");
+  J = NF(I,M);
+  option(set,opt);
+  for (i=1; i<=ncols(I); i++)
+  {
+    if (J[i]<>I[i])
+    {
+      return(int(0));
+    }
+  }
+  return(int(1));
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(e,f,h),dp;
+  matrix d[3][3];
+  d[1,2] = -h; d[1,3] = 2*e; d[2,3] = -2*f;
+  def A = nc_algebra(1,d);
+  setring A; A; // A is U(sl_2)
+  // the subalgebra generated by e,f is not admissible since [e,f]=h
+  admissibleSub(1..2);
+  // but the subalgebra generated by f,h is admissible since [f,h]=2f
+  admissibleSub(2..3);
+}
+
+
+proc isUpperTriangular(matrix M, list #)
+"
+USAGE:    isUpperTriangular(M[,k]);  M a matrix, k an optional int
+RETURN:   int, 1 if the given matrix is upper triangular,
+          0 otherwise.
+NOTE:     If k<>0 is given, it is checked whether M is strictly upper
+          triangular.
+EXAMPLE:  example isUpperTriangular; shows examples
+"
+{
+  int strict;
+  if (size(#)>0)
+  {
+    if ((typeof(#[1])=="int") || (typeof(#[1])=="number"))
+    {
+      strict = (0<>int(#[1]));
+    }
+  }
+  int m = Min(intvec(nrows(M),ncols(M)));
+  int j;
+  ideal I;
+  for (j=1; j<=m; j++)
+  {
+    I = M[j..nrows(M),j];
+    if (!strict)
+    {
+      I[1] = 0;
+    }
+    if (size(I)>0)
+    {
+      return(int(0));
+    }
+  }
+  return(int(1));
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,x,dp;
+  matrix M[2][3] =
+    0,1,2,
+    0,0,3;
+  isUpperTriangular(M);
+  isUpperTriangular(M,1);
+  M[2,2] = 4;
+  isUpperTriangular(M);
+  isUpperTriangular(M,1);
+}
+
+
+proc appendWeight2Ord (intvec w)
+"
+USAGE:    appendWeight2Ord(w);  w an intvec
+RETURN:   ring, the basering equipped with the ordering (a(w),<), where < is
+          the ordering of the basering.
+EXAMPLE:  example appendWeight2Ord; shows examples
+"
+{
+  list RL = ringlist(basering);
+  RL[3] = insert(RL[3],list("a",w),0);
+  def A = ring(RL);
+  return(A);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(a,b,x,d),Dp;
+  intvec w = 1,2,3,4;
+  def r2 = appendWeight2Ord(w); // for a commutative ring
+  r2;
+  matrix D[4][4];
+  D[1,2] = 3*a;  D[1,4] = 3*x^2;  D[2,3] = -x;
+  D[2,4] = d;    D[3,4] = 1;
+  def A = nc_algebra(1,D);
+  setring A; A;
+  w = 2,1,1,1;
+  def B = appendWeight2Ord(w);  // for a non-commutative ring
+  setring B; B;
+}
+
+
+static proc checkIntvec (intvec v)
+"
+USAGE:    checkIntvec(v);  v intvec
+RETURN:   intvec consisting of entries of v in ascending order
+NOTE:     Purpose of this proc: check if all entries of v are in the range
+          1..nvars(basering).
+"
+{
+  if (size(v)>1)
+  {
+    v = sortIntvec(v)[1];
+  }
+  int n = nvars(basering);
+  if ( (v[1]<1) || v[size(v)]>n)
+  {
+    ERROR("Entries of intvec must be in the range 1.." + string(n));
+  }
+  return(v);
+}
+
+
+
+// -- Elimination ------------------------------------------
+
+
+/*
+// this is the same as Gweights at nctools.lib
+//
+// proc orderingCondition (matrix D)
+// "
+// USAGE:    orderingCondition(D);  D a matrix
+// ASSUME:   The matrix D is a strictly upper triangular square matrix.
+// RETURN:   intvec, say w, such that the ordering (a(w),<), where < is
+//           any global ordering, satisfies the ordering condition for
+//           all G-algebras induced by D.
+// NOTE:     If no such ordering exists, the zero intvec is returned.
+// REMARK:   Reference: (BGL)
+// EXAMPLE:  example orderingCondition; shows examples
+// "
+// {
+//   if (ncols(D) <> nrows(D))
+//   {
+//     ERROR("Expected square matrix.");
+//   }
+//   if (isUpperTriangular(D,1)==0)
+//   {
+//     ERROR("Expected strictly upper triangular matrix.");
+//   }
+//   intvec v = 1..nvars(basering);
+//   intvec w = orderingConditionEngine(D,v,0);
+//   return(w);
+// }
+// example
+// {
+//   "EXAMPLE:"; echo = 2;
+//   // (Lev): Example 2
+//   ring r = 0,(a,b,x,d),dp;
+//   matrix D[4][4];
+//   D[1,2] = 3*a;  D[1,4] = 3*x^2;  D[2,3] = -x;
+//   D[2,4] = d;    D[3,4] = 1;
+//   // To create a G-algebra, the ordering condition implies
+//   // that x^2<a*d must hold (see D[1,4]), which is not fulfilled:
+//   x^2 < a*d;
+//   // Hence, we look for an appropriate weight vector
+//   intwec w = orderingCondition(D); w;
+//   // and use it accordingly.
+//   ring r2 = 0,(a,b,x,d),(a(w),dp);
+//   x^2 < a*d;
+//   matrix D = imap(r,D);
+//   def A = nc_algebra(1,D);
+//   setring A; A;
+// }
+*/
+
+
+proc elimWeight (intvec v)
+"
+USAGE:    elimWeight(v);  v an intvec
+ASSUME:   The basering is a G-algebra.
+@*        The entries of v are in the range 1..nvars(basering) and the
+          corresponding variables generate an admissible subalgebra.
+RETURN:   intvec, say w, such that the ordering (a(w),<), where < is
+          any admissible global ordering, is an elimination ordering
+          for the subalgebra generated by the variables indexed by the
+          entries of the given intvec.
+NOTE:     If no such ordering exists, the zero intvec is returned.
+REMARK:   Reference: (BGL), (GML)
+EXAMPLE:  example elimWeight; shows examples
+"
+{
+  list RL = ringlist(basering);
+  if (size(RL)==4)
+  {
+    ERROR("Expected non-commutative basering.");
+  }
+  matrix D = RL[6];
+  intvec w = orderingConditionEngine(D,v,1);
+  return(w);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  // (Lev): Example 2
+  ring r = 0,(a,b,x,d),Dp;
+  matrix D[4][4];
+  D[1,2] = 3*a;  D[1,4] = 3*x^2;  D[2,3] = -x;
+  D[2,4] = d;    D[3,4] = 1;
+  def A = nc_algebra(1,D);
+  setring A; A;
+  // Since d*a-a*d = 3*x^2, any admissible ordering has to satisfy
+  // x^2 < a*d, while any elimination ordering for {x,d} additionally
+  // has to fulfil a << x and a << d.
+  // Hence neither a block ordering with weights
+  // (1,1,1,1) nor a weighted ordering with weight (0,0,1,1) will do.
+  intvec v = 3,4;
+  elimWeight(v);
+}
+
+
+static proc orderingConditionEngine (matrix D, intvec v, int elimweight)
+{
+  // algorithm from (BGL) and (GML), respectively
+  // solving an LPP via simplex
+  int ppl = printlevel - voice + 1;
+  def save = basering;
+  int n = nvars(save);
+  ideal EV = maxideal(1);
+  EV = EV[v]; // also assumption check for v
+  attrib(EV,"isSB",1);
+  ideal NEV = maxideal(1);
+  NEV = NF(NEV,EV);
+  intmat V1[n-size(NEV)][n+1];
+  if (elimweight)
+  {
+    intmat V2[size(NEV)][n+1];
+  }
+  int rowV1,rowV2;
+  intmat M[1][n];
+  intmat M2,oldM;
+  int i,j,k;
+  for (i=1; i<=n; i++)
+  {
+    if (elimweight)
+    {
+      if (NEV[i]<>0)
+      {
+        V2[rowV2+1,i+1] = 1; // xj == 0
+        rowV2++;
+      }
+      else
+      {
+        V1[rowV1+1,1] = 1; // 1-xi <= 0
+        V1[rowV1+1,i+1] = -1;
+        rowV1++;
+      }
+    }
+    else
+    {
+      V1[i,1] = 1; // 1-xi <= 0
+      V1[i,i+1] = -1;
+      rowV1++;
+    }
+    for (j=i+1; j<=n; j++)
+    {
+      if (deg(D[i,j])>0)
+      {
+        M2 = newtonDiag(D[i,j]);
+        for (k=1; k<=nrows(M2); k++)
+        {
+          M2[k,i] = M2[k,i] - 1; // <beta,x> >= 0
+          M2[k,j] = M2[k,j] - 1;
+        }
+        oldM = M;
+        M = intmat(M,nrows(M)+nrows(M2),n);
+        M = oldM,M2;
+      }
+    }
+  }
+  intvec eq = 0,(-1:n);
+  ring r = 0,x,dp; // to avoid problems with pars or char>0
+  module MM = module(transpose(matrix(M)));
+  MM = simplify(MM,2+4);
+  matrix A;
+  if (MM[1]<>0)
+  {
+    if (elimweight)
+    {
+      MM = 0,transpose(MM);
+    }
+    else
+    {
+      MM = module(matrix(1:ncols(MM)))[1],transpose(MM);
+    }
+    A = transpose(concat(matrix(eq),transpose(-MM)));
+  }
+  else
+  {
+    A = transpose(eq);
+  }
+  A = transpose(concat(transpose(A),matrix(transpose(V1))));
+  if (elimweight)
+  {
+    A = transpose(concat(transpose(A),matrix(transpose(V2))));
+  }
+  int m = nrows(A)-1;
+  ring realr = (real,10),x,lp;
+  matrix A = imap(r,A);
+  dbprint(ppl,"// Calling simplex...");
+  dbprint(ppl-1,"// with the matrix " + print(A));
+  dbprint(ppl-1,"// and parameters "
+          + string(intvec(m,n,m-rowV1-rowV2,rowV1,rowV2)));
+  list L = simplex(A,m,n,m-rowV1-rowV2,rowV1,rowV2);
+  int se = L[2];
+  if (se==-2)
+  {
+    ERROR("simplex yielded an error. Please inform the authors.");
+  }
+  intvec w = 0:n;
+  if (se==0)
+  {
+    matrix S = L[1];
+    intvec s = L[3];
+    for (i=2; i<=nrows(S); i++)
+    {
+      if (s[i-1]<=n)
+      {
+        w[s[i-1]] = int(S[i,1]);
+      }
+    }
+  }
+  setring save;
+  return(w);
+}
+
+
+proc eliminateNC (ideal I, intvec v, list #)
+"
+USAGE:    eliminateNC(I,v,eng);  I ideal, v intvec, eng optional int
+RETURN:   ideal, I intersected with the subring defined by the variables not
+          index by the entries of v
+ASSUME:   The entries of v are in the range 1..nvars(basering) and the
+          corresponding variables generate an admissible subalgebra.
+REMARKS:  In order to determine the required elimination ordering, a linear
+          programming problem is solved with the simplex algorithm.
+@*        Reference: (GML)
+@*        Unlike eliminate, this procedure will always find an elimination
+          ordering, if such exists.
+NOTE:     If eng<>0, @code{std} is used for Groebner basis computations,
+          otherwise (and by default) @code{slimgb} is used.
+@*        If printlevel=1, progress debug messages will be printed,
+          if printlevel>=2, all the debug messages will be printed.
+SEE ALSO: eliminate (plural)
+EXAMPLE:  example eliminateNC; shows examples
+"
+{
+  int ppl = printlevel - voice + 2;
+  v = checkIntvec(v);
+  if (!admissibleSub(v))
+  {
+    ERROR("Subalgebra is not admissible: no elimination is possible.");
+  }
+  dbprint(ppl,"// Subalgebra is admissible.");
+  int eng;
+  if (size(#)>0)
+  {
+    if (typeof(#[1])=="int" || typeof(#[1])=="number")
+    {
+      eng = int(#[1]);
+    }
+  }
+  def save = basering;
+  int n = nvars(save);
+  dbprint(ppl,"// Computing elimination weight...");
+  intvec w = elimWeight(v);
+  if (w==(0:n))
+  {
+    ERROR("No elimination ordering exists.");
+  }
+  dbprint(ppl,"// ...done.");
+  dbprint(ppl-1,"// Using elimination weight " + string(w) + ".");
+  def r = appendWeight2Ord(w);
+  setring r;
+  ideal I = imap(save,I);
+  dbprint(ppl,"// Computing Groebner basis with engine " + string(eng)+"...");
+  I = engine(I,eng);
+  dbprint(ppl,"// ...done.");
+  dbprint(ppl-1,string(I));
+  I = nselect(I,v);
+  setring save;
+  I = imap(r,I);
+  return(I);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  // (Lev): Example 2
+  ring r = 0,(a,b,x,d),Dp;
+  matrix D[4][4];
+  D[1,2] = 3*a; D[1,4] = 3*x^2;
+  D[2,3] = -x;  D[2,4] = d;     D[3,4] = 1;
+  def A = nc_algebra(1,D);
+  setring A; A;
+  ideal I = a,x;
+  // Since d*a-a*d = 3*x^2, any admissible ordering has to satisfy
+  // x^2 < a*d, while any elimination ordering for {x,d} additionally
+  // has to fulfil a << x and a << d.
+  // Hence, the weight (0,0,1,1) is not an elimination weight for
+  // (x,d) and the call eliminate(I,x*d); will produce an error.
+  eliminateNC(I,3..4);
+  // This call uses the elimination weight (0,0,1,2), which works.
+}
+
+
+
+// -- Preimages ------------------------------------------------
+
+// TODO A or B commutative
+proc extendedTensor(def A, ideal I)
+"
+USAGE:    extendedTensor(A,I);  A ring, I ideal
+RETURN:   ring, A+B (where B denotes the basering) extended with non-
+          commutative relations between the vars of A and B, which arise from
+          the homomorphism A -> B induced by I in the usual sense, i.e. if the
+          vars of A are named x(i) and the vars of B y(j), then putting
+          q(i)(j) = leadcoef(y(j)*I[i])/leadcoef(I[i]*y(j)) and
+          r(i)(j) = y(j)*I[i] - q(i)(j)*I[i]*y(j) yields the relation
+          y(j)*x(i) = q(i)(j)*x(i)*y(j)+r(i)(j).
+REMARK:   Reference: (Lev)
+EXAMPLE:  example extendedTensor; shows examples
+"
+{
+  def B = basering;
+  setring A;
+  int nA = nvars(A);
+  string varA = "," + charstr(A) + "," + varstr(A) + ",";
+  setring B;
+  int nB = nvars(B);
+  list RL = ringlist(B);
+  list L = RL[2];
+  string vB;
+  int i,j;
+  for (i=1; i<=nB; i++)
+  {
+    vB = "," + L[i] + ",";
+    while (find(varA,vB)<>0)
+    {
+      vB[1] = "@";
+      vB = "," + vB;
+    }
+    vB = vB[2..size(vB)-1];
+    L[i] = vB;
+  }
+  RL[2] = L;
+  def @B = ring(RL);
+  kill L,RL;
+  setring @B;
+  ideal I = fetch(B,I);
+  def E = A+ at B;
+  setring E;
+  ideal I = imap(@B,I);
+  matrix C = ringlist(E)[5];
+  matrix D = ringlist(E)[6];
+  poly p,q;
+  for (i=1; i<=nA; i++)
+  {
+    for (j=nA+1; j<=nA+nB; j++)
+    {
+      // upper right block: new relations
+      p = var(j)*I[i];
+      q = I[i]*var(j);
+      C[i,j] = leadcoef(p)/leadcoef(q);
+      D[i,j] = p - C[i,j]*q;
+    }
+  }
+  def @EE = commRing();
+  setring @EE;
+  matrix C = imap(E,C);
+  matrix D = imap(E,D);
+  def EE = nc_algebra(C,D);
+  setring B;
+  return(EE);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  def A = makeWeyl(2);
+  setring A; A;
+  def B = makeUgl(2);
+  setring B; B;
+  ideal I = var(1)*var(3), var(1)*var(4), var(2)*var(3), var(2)*var(4);
+  I;
+  def C = extendedTensor(A,I);
+  setring C; C;
+}
+
+
+proc preimageNC (list #)
+"
+USAGE:    preimageNC(A,f,J[,P,eng]);  A ring, f map or ideal, J ideal,
+                                      P optional string, eng optional int
+ASSUME:   f defines a map from A to the basering.
+RETURN:   nothing, instead exports an object `preim' of type ideal to ring A,
+          being the preimage of J under f.
+NOTE:     If P is given and not equal to the empty string, the preimage is
+          exported to A under the name specified by P.
+          Otherwise (and by default), P is set to `preim'.
+@*        If eng<>0, @code{std} is used for Groebner basis computations,
+          otherwise (and by default) @code{slimgb} is used.
+@*        If printlevel=1, progress debug messages will be printed,
+          if printlevel>=2, all the debug messages will be printed.
+REMARK:   Reference: (Lev)
+SEE ALSO: preimage (plural)
+EXAMPLE:  example preimageNC; shows examples
+"
+{
+  int ppl = printlevel - voice + 2;
+  if (size(#) <3)
+  {
+    ERROR("Expected 3 arguments.")
+  }
+  def B = basering;
+  if (typeof(#[1])<>"ring")
+  {
+    ERROR("First argument must be a ring.");
+  }
+  def A = #[1];
+  setring A;
+  ideal mm = maxideal(1);
+  setring B;
+  if (typeof(#[2])=="map" || typeof(#[2])=="ideal")
+  {
+    map phi = A,ideal(#[2]);
+  }
+  else
+  {
+    ERROR("Second argument must define a map from the specified ring to the basering.");
+  }
+  if (typeof(#[3])<>"ideal")
+  {
+    ERROR("Third argument must be an ideal in the specified ring");
+  }
+  ideal J = #[3];
+  string str = "preim";
+  int eng;
+  if (size(#)>3)
+  {
+    if (typeof(#[4])=="string")
+    {
+      if (#[4]<>"")
+      {
+        str = #[4];
+      }
+    }
+    if (size(#)>4)
+    {
+      if (typeof(#[5])=="int")
+      {
+        eng = #[5];
+      }
+    }
+  }
+  setring B;
+  ideal I = phi(mm);
+  def E = extendedTensor(A,I);
+  setring E;
+  dbprint(ppl,"// Computing in ring");
+  dbprint(ppl,E);
+  int nA = nvars(A);
+  int nB = nvars(B);
+  ideal @B2E = maxideal(1);
+  @B2E = @B2E[(nA+1)..(nA+nB)];
+  map B2E = B, at B2E;
+  ideal I = B2E(I);
+  ideal Iphi;
+  int i,j;
+  for (i=1; i<=nA; i++)
+  {
+    Iphi[size(Iphi)+1] = var(i) - I[i];
+  }
+  dbprint(ppl,"// I_{phi} is  " + string(Iphi));
+  ideal J = imap(B,J);
+  J = J + Iphi;
+  intvec v = (nA+1)..(nA+nB);
+  dbprint(ppl,"// Starting elimination...");
+  dbprint(ppl-1,string(J));
+  J = eliminateNC(J,v,eng);
+  dbprint(ppl,"// ...done.");
+  dbprint(ppl-1,string(J));
+  J = nselect(J,v);
+  attrib(J,"isSB",1);
+  setring A;
+  dbprint(ppl,"// Writing output to specified ring under the name `"
+          + str + "'.");
+  str = "ideal " + str + " = imap(E,J); export(" + str + ");";
+  execute(str);
+  setring B;
+  return();
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  def A = makeUgl(3); setring A; A; // universal enveloping algebra of gl_3
+  ring r3 = 0,(x,y,z,Dx,Dy,Dz),dp;
+  def B = Weyl(); setring B; B;     // third Weyl algebra
+  ideal ff = x*Dx,x*Dy,x*Dz,y*Dx,y*Dy,y*Dz,z*Dx,z*Dy,z*Dz;
+  map f = A,ff;                     // f: A -> B, e(i,j) |-> x(i)D(j)
+  ideal J = 0;
+  preimageNC(A,f,J,"K");            // compute K := ker(f)
+  setring A;
+  K;
+}
+
+
+// -- Examples ---------------------------------------------
+
+static proc ex1 ()
+{
+  ring r1 = 0,(a,b),dp;
+  int t = 7;
+  def St = nc_algebra(1,t*a);
+  ring r2 = 0,(x,D),dp;
+  def W = nc_algebra(1,1); // W is the first Weyl algebra
+  setring W;
+  map psit = St, x^t,x*D+t;
+  int p = 3;
+  ideal Ip = x^p, x*D+p;
+  preimageNC(St,psit,Ip);
+  setring St; preim;
+}
+
+
+static proc ex2 ()
+{
+  ring r1 = 0,(e,f,h),dp;
+  matrix D1[3][3]; D1[1,2] = -h; D1[1,3] = 2*e; D1[2,3] = -2*f;
+  def U = nc_algebra(1,D1); // D is U(sl_2)
+  ring r2 = 0,(x,D),dp;
+  def W = nc_algebra(1,1); // W is the first Weyl algebra
+  setring W;
+  ideal tau = x,-x*D^2,2*x*D;
+  def E = extendedTensor(U,tau);
+  setring E; E;
+  elimWeight(4..5);
+  // zero, since there is no elimination ordering for x,D in E
+}
+
+
+static proc ex3 ()
+{
+  ring r1 = 0,(x,d,s),dp;
+  matrix D1[3][3]; D1[1,2] = 1;
+  def A = nc_algebra(1,D1);
+  ring r2 = 0,(X,DX,T,DT),dp;
+  matrix D2[4][4]; D2[1,2] = 1; D2[3,4] = 1;
+  def B = nc_algebra(1,D2);
+  setring B;
+  map phi = A, X,DX,-DT*T;
+  ideal J = T-X^2, DX+2*X*DT;
+  preimageNC(A,phi,J);
+  setring A;
+  preim;
+}
diff --git a/Singular/LIB/nctools.lib b/Singular/LIB/nctools.lib
new file mode 100644
index 0000000..682f661
--- /dev/null
+++ b/Singular/LIB/nctools.lib
@@ -0,0 +1,1905 @@
+//////////////////////////////////////////////////////////////////////////////
+version="version nctools.lib 4.0.0.0 Jun_2013 "; // $Id: ea6978528731c3afa634872f248d8cb16868421b $
+category="Noncommutative";
+info="
+LIBRARY: nctools.lib     General tools for noncommutative algebras
+AUTHORS:   Levandovskyy V.,     levandov at mathematik.uni-kl.de,
+@*         Lobillo, F.J.,       jlobillo at ugr.es,
+@*         Rabelo, C.,          crabelo at ugr.es,
+@*         Motsak, O.,          U at D, where U={motsak}, D={mathematik.uni-kl.de}
+
+
+OVERVIEW:
+Support: DFG (Deutsche Forschungsgesellschaft) and Metodos algebraicos y efectivos
+en grupos cuanticos, BFM2001-3141, MCYT, Jose Gomez-Torrecillas (Main researcher).
+
+PROCEDURES:
+Gweights(r);              compute weights for a compatible ordering in a G-algebra,
+weightedRing(r);          change the ordering of a ring to a weighted one,
+ndcond();                 the ideal of non-degeneracy conditions in G-algebra,
+Weyl([p]);                create Weyl algebra structure in a basering (two different realizations),
+makeWeyl(n, [p]);         return n-th Weyl algebra in (x(i),D(i)) presentation,
+makeHeisenberg(N, [p,d]); return n-th Heisenberg algebra in (x(i),y(i),h) realization,
+Exterior();               return qring, the exterior algebra of a basering,
+findimAlgebra(M,[r]);     create finite dimensional algebra structure from the basering and the multiplication matrix M,
+superCommutative([b,e,Q]);  return qring, a super-commutative algebra over a basering,
+rightStd(I);              compute right Groebner basis of an ideal,
+rightNF(f,I);             compute right normal form wrt a submodule,
+rightModulo(M,N);         compute kernel of a homomorphism of right modules,
+moduloSlim(A,B);     compute modulo command via slimgb
+ncRelations(r);      recover the non-commutative relations of a G-algebra,
+isCentral(p);        check for the commutativity of a polynomial in the G-algebra,
+isNC();              check whether basering is noncommutative,
+isCommutative();     check whether basering is commutative
+isWeyl();            check whether basering is a Weyl algebra
+UpOneMatrix();       return NxN matrix with 1's in the whole upper triagle,
+AltVarStart();       return first alternating variable of a super-commutative algebra,
+AltVarEnd();         return last alternating variable of a super-commutative algebra,
+IsSCA();             check whether current ring is a super-commutative algebra,
+makeModElimRing(R);  equip a ring with module elimination ordering,
+embedMat(M,m,n);     embeds matrix M in a left upper corner of m times n matrix
+";
+
+
+LIB "ring.lib"; // for rootofUnity
+LIB "poly.lib"; // for newtonDiag
+LIB "matrix.lib"; // for submat
+
+///////////////////////////////////////////////////////////////////////////////
+
+// This procedure computes a weights vector for a G-algebra r
+
+proc Gweights(def r)
+"USAGE:   Gweights(r); r a ring or a square matrix
+RETURN:   intvec
+PURPOSE: compute an appropriate weight int vector for a G-algebra, i.e., such that
+\foral\;i<j\;\;lm_w(d_{ij}) <_w x_i x_j.
+@*       the polynomials d_{ij} are taken from r itself, if it is of the type ring
+@*       or defined by the given square polynomial matrix
+THEORY:   @code{Gweights} returns an integer vector, whose weighting should be used to redefine the G-algebra in order
+to get the same non-commutative structure w.r.t. a weighted ordering. If the input is a matrix and the output is the zero
+vector then there is not a G-algebra structure associated to these relations with respect to the given variables.
+@*Another possibility is to use @code{weightedRing} to obtain directly a G-algebra with the new appropriate (weighted) ordering.
+EXAMPLE: example Gweights; shows examples
+SEE ALSO: weightedRing
+"{
+  int novalid=0;
+  if (typeof(r)=="ring") //a ring is admissible as input
+  {
+    setring r;
+    matrix tails;
+    def l = ncRelations(r);
+    tails = l[2]; // l=C,D we need D, the tails of the relations
+  }
+  else
+  {
+    matrix tails;
+    if ( (typeof(r)=="matrix") || (typeof(r)=="intmat") )
+    {
+      if ( nrows(r)==ncols(r) ) //the input is a square matrix
+      {
+        tails = matrix(r);
+      }
+      else
+      {
+        novalid = 1;
+      }
+    }
+    else
+    {
+      novalid=1;
+    }
+  }
+  if (novalid==0)
+  {
+    intmat IM = SimplMat(tails);
+    if ( size(IM)>1 )
+    {
+      int n  = ncols(tails);
+      int m  = nrows(IM)-1;
+      int m1 = 0;
+      int m2 = m;
+      int m3 = 0;
+      ring simplexring=(real,10),(x),lp;// The simplex procedure requires a basering of this type
+      matrix M = IM;
+      list sol = simplex (M,m,n,m1,m2,m3);
+      return(weightvector(sol));
+    }
+    else
+    {
+      "Invalid input"; //usually because the input is a one variable ring
+      return();
+    }
+  }
+  else
+  {
+    "The input must be a ring or a square matrix";
+    return();
+  }
+}
+example
+{
+  "EXAMPLE:";echo=2;
+  ring r = (0,q),(a,b,c,d),lp;
+  matrix C[4][4];
+  C[1,2]=q; C[1,3]=q; C[1,4]=1; C[2,3]=1; C[2,4]=q; C[3,4]=q;
+  matrix D[4][4];
+  D[1,4]=(q-1/q)*b*c;
+  def S = nc_algebra(C,D); setring S; S;
+  Gweights(S);
+  def D=fetch(r,D);
+  Gweights(D);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+// This procedure take a ring r, call to Gweights(r) and use the output
+// of Gweights(r) to make a change of order in r
+// The output is a new ring, equal to r but the order
+// r must be a G-algebra
+
+proc weightedRing(def r)
+"USAGE:   weightedRing(r); r a ring
+RETURN:  ring
+PURPOSE:  equip the variables of the given ring with weights such that the relations of new ring (with weighted variables) satisfies the ordering condition for G-algebras:
+e.g. \forall\;i<j\;\;lm_w(d_{ij})<_w x_i x_j.
+NOTE:    activate this ring with the \"setring\" command
+EXAMPLE: example weightedRing; shows examples
+SEE ALSO: Gweights
+"{
+  def wv=Gweights(r);
+  if (typeof(wv)=="intvec")
+  {
+    setring r;
+    int n=nvars(r);
+    // Generating an nxn-intmat order
+    intmat m[n][n];
+    m[1,1]=wv[1];
+    int i;
+    for (i=2; i<=n; i++)
+    {
+      m[1,i]=wv[i];
+      m[i,n+2-i]=1;
+    }
+    // End of generation.
+    def lr=ncRelations(r);
+    string newringstring="ring newring=("+charstr(r)+"),("+varstr(r)+"),M("+string(m)+")";
+    execute (newringstring);
+    def lnewring=imap(r,lr);
+    return( nc_algebra(lnewring[1],lnewring[2]) );
+  }
+  else
+  {
+    "Invalid input.";//usually because the input is a one variable ring
+    return();
+  }
+}
+example
+{
+  "EXAMPLE:";echo=2;
+  ring r = (0,q),(a,b,c,d),lp;
+  matrix C[4][4];
+  C[1,2]=q; C[1,3]=q; C[1,4]=1; C[2,3]=1; C[2,4]=q; C[3,4]=q;
+  matrix D[4][4];
+  D[1,4]=(q-1/q)*b*c;
+  def S = nc_algebra(C,D); setring S; S;
+  def t=weightedRing(S);
+  setring t; t;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+// This procedure computes ei+ej-f with f running in Newton(pij) and deletes the zero rows
+
+static proc Cij(intmat M, int i,int j)
+{
+  M=(-1)*M;
+  int nc=ncols(M);
+  intvec N;
+  int k;
+  for (k=1; k<=nrows(M); k++)
+  {
+    M[k,i]=M[k,i]+1;
+    M[k,j]=M[k,j]+1;
+    if (intvec(M[k,1..nc])!=0)
+    {
+      N=N,intvec(M[k,1..nc]);
+    } // we only want non-zero rows
+  }
+  if (size(N)>1)
+  {
+    N=N[2..size(N)]; // Deleting the zero added in the definition of N
+    M=intmat(N,size(N) div nc,nc); // Conversion from vector to matrix
+  }
+  else
+  {
+    intmat M[1][1]=0;
+  }
+  return (M);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+// This procedure run over the matrix of pij calculating Cij
+
+static proc Ct(matrix P)
+{
+  int    k = ncols(P);
+  intvec T = 0;
+  int    i,j;
+//  int notails=1;
+  def S;
+  for (j=2; j<=k; j++)
+  {
+    for (i=1; i<j; i++)
+    {
+      if ( P[i,j] != 0 )
+      {
+//        notails=0;
+        S = newtonDiag(P[i,j]);
+        S = Cij(S,i,j);
+        if ( size(S)>1 )
+        {
+          T = T,S;
+        }
+      }
+    }
+  }
+  if ( size(T)==1 )
+  {
+    intmat C[1][1] = 0;
+  }
+  else
+  {
+    T=T[2..size(T)]; // Deleting the zero added in the definition of T
+    intmat C = intmat(T,size(T) div k,k); // Conversion from vector to matrix
+  }
+  return (C);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+// The purpose of this procedure is to produce the input matrix required by simplex procedure
+
+static proc SimplMat(matrix P)
+{
+  intmat C=Ct(P);
+  if (size(C)>1)
+  {
+    int r = nrows(C);
+    int n = ncols(C);
+    int f = 1+n+r;
+    intmat M[f][n+1]=0;
+    int i;
+    for (i=2; i<=(n+1); i++)
+    {
+      M[1,i]=-1; // (0,-1,-1,-1,...) objective function in the first row
+    }
+    for (i=2; i<=f; i++) {M[i,1]=1;} // All the independent terms are 1
+    for (i=2; i<=(n+1); i++) {M[i,i]=-1;} // wi>=1 is an identity matrix
+    M[(n+2)..f,2..(n+1)]=(-1)*intvec(C); // <wi,a> >= 1, a in C ...
+  }
+  else
+  {
+    int n = ncols(P);
+    int f = 1+n;
+    intmat M[f][n+1]=0;
+    int i;
+    for (i=2; i<=(n+1); i++) {M[1,i]=-1;} // (0,-1,-1,-1,...) objective function in the first row
+    for (i=2; i<=f; i++) {M[i,1]=1;} // All the independent terms are 1
+    for (i=2; i<=(n+1); i++) {M[i,i]=-1;} // wi>=1 is an identity matrix
+  }
+  return (M);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+// This procedure generates a nice output of the simplex method consisting of a vector
+// with the solutions. The vector is ordered.
+
+static proc weightvector(list l)
+"ASSUME:  l is the output of simplex.
+RETURN: if there is a solution, an intvec with it will be returned"
+{
+  matrix m=l[1];
+  intvec nv=l[3];
+  int sol=l[2];
+  int rows=nrows(m);
+  int N=l[6];
+  intmat wv[1][N]=0;
+  int i;
+  if (sol)
+  {
+    "no solution satisfies the given constraints";
+  }
+  else
+  {
+    for ( i = 2; i <= rows; i++ )
+    {
+      if ( nv[i-1] <= N )
+      {
+        wv[1,nv[i-1]]=int(m[i,1]);
+      }
+    }
+  }
+  return (intvec(wv));
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+
+// This procedure recover the non-conmutative relations (matrices C and D)
+
+proc ncRelations(def r)
+"USAGE:   ncRelations(r); r a ring
+RETURN:  list L with two elements, both elements are of type matrix:
+@*         L[1] = matrix of coefficients C,
+@*         L[2] = matrix of polynomials D
+PURPOSE: recover the noncommutative relations via matrices C and D from
+a noncommutative ring
+SEE ALSO: ringlist, G-algebras
+EXAMPLE: example ncRelations; shows examples
+"{
+  list l;
+  if (typeof(r)=="ring")
+  {
+    int n=nvars(r);
+    matrix C[n][n]=0;
+    matrix D[n][n]=0;
+    poly f; poly g;
+    if (n>1)
+    {
+      int i,j;
+      for (i=2; i<=n; i++)
+      {
+        for (j=1; j<i; j++)
+        {
+          f=var(i)*var(j); // yx=c*xy+...
+          g=var(j)*var(i); // xy
+          while (C[j,i]==0)
+          {
+            if (leadmonom(f)==leadmonom(g))
+            {
+              C[j,i]=leadcoef(f);
+              D[j,i]=D[j,i]+f-lead(f);
+            }
+            else
+            {
+              D[j,i]=D[j,i]+lead(f);
+              f=f-lead(f);
+            }
+          }
+        }
+      }
+      l=C,D;
+    }
+    else { "The ring must have two or more variables"; }
+  }
+  else { "The input must be of a type ring";}
+  return (l);
+}
+example
+{
+  "EXAMPLE:";echo=2;
+  ring r = 0,(x,y,z),dp;
+  matrix C[3][3]=0,1,2,0,0,-1,0,0,0;
+  print(C);
+  matrix D[3][3]=0,1,2y,0,0,-2x+y+1;
+  print(D);
+  def S=nc_algebra(C,D);setring S; S;
+  def l=ncRelations(S);
+  print (l[1]);
+  print (l[2]);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc findimAlgebra(matrix M, list #)
+"USAGE:   findimAlgebra(M,[r]); M a matrix, r an optional ring
+RETURN:  ring
+PURPOSE: define a finite dimensional algebra structure on a ring
+NOTE:  the matrix M is used to define the relations x(i)*x(j) = M[i,j] in the
+basering (by default) or in the optional ring r.
+@* The procedure equips the ring with the noncommutative structure.
+@* The procedure exports the ideal (not a two-sided Groebner basis!), called @code{fdQuot}, for further qring definition.
+THEORY: finite dimensional algebra can be represented as a factor algebra
+of a G-algebra modulo certain two-sided ideal. The relations of a f.d. algebra are thus naturally divided into two groups: firstly, the relations
+on the variables of the ring, making it into G-algebra and the rest of them, which constitute the ideal which will be factored out.
+EXAMPLE: example findimAlgebra; shows examples
+"
+{
+  if (size(#) >0)
+  {
+    if ( typeof(#[1])!="ring" ) { return();}
+    else
+    {
+      def @R1 = #[1];
+      setring @R1;
+    }
+  }
+  int i,j;
+  int n=nvars(basering);
+  poly p;
+  ideal I;
+  number c;
+  matrix C[n][n];
+  matrix D[n][n];
+  for (i=1; i<=n; i++)
+  {
+    for (j=i; j<=n; j++)
+    {
+      p=var(i)*var(j)-M[i,j];
+      if ( (ncols(I)==1) && (I[1]==0) )   { I=p; }
+      else { I=I,p; }
+      if (j>i)
+      {
+        if ((M[i,j]!=0) && (M[j,i]!=0))
+        {
+          c = leadcoef(M[j,i])/leadcoef(M[i,j]);
+        }
+        else
+        {
+          c = 1;
+        }
+        C[i,j]=c;
+        D[i,j]= M[j,i] -c*M[i,j];
+      }
+    }
+  }
+  def save = basering;
+  def S = nc_algebra(C,D); setring S;
+  ideal fdQuot = fetch(save,I);
+  export fdQuot;
+  return(S);
+}
+example
+{
+  "EXAMPLE:";echo=2;
+  ring r=(0,a,b),(x(1..3)),dp;
+  matrix S[3][3];
+  S[2,3]=a*x(1); S[3,2]=-b*x(1);
+  def A=findimAlgebra(S); setring A;
+  fdQuot = twostd(fdQuot);
+  qring Qr = fdQuot;
+  Qr;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc isCentral(poly p, list #)
+"USAGE:   isCentral(p); p poly
+RETURN:  int, 1 if p commutes with all variables and 0 otherwise
+PURPOSE: check whether p is central in a basering (that is, commutes with every generator of the ring)
+NOTE: if @code{printlevel} > 0, the procedure displays intermediate information (by default, @code{printlevel}=0 )
+EXAMPLE: example isCentral; shows examples
+"{
+  //v an integer (with v!=0, procedure will be verbose)
+  int N = nvars(basering);
+  int in;
+  int flag = 1;
+  poly   q = 0;
+  for (in=1; in<=N; in++)
+  {
+    q = p*var(in)-var(in)*p;
+    if (q!=0)
+    {
+      if ( (size(#) >0 ) || (printlevel>0) )
+      {
+        "Non-central at:", var(in);
+      }
+      flag = 0;
+    }
+  }
+  return(flag);
+}
+example
+{
+  "EXAMPLE:";echo=2;
+  ring r=0,(x,y,z),dp;
+  matrix D[3][3]=0;
+  D[1,2]=-z;
+  D[1,3]=2*x;
+  D[2,3]=-2*y;
+  def S = nc_algebra(1,D); setring S;
+  S; // this is U(sl_2)
+  poly c = 4*x*y+z^2-2*z;
+  printlevel = 0;
+  isCentral(c);
+  poly h = x*c;
+  printlevel = 1;
+  isCentral(h);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc UpOneMatrix(int N)
+"USAGE:   UpOneMatrix(n); n an integer
+RETURN:  intmat
+PURPOSE: compute an  n x n matrix with 1's in the whole upper triangle
+NOTE: helpful for setting noncommutative algebras with complicated
+coefficient matrices
+EXAMPLE: example UpOneMatrix; shows examples
+"{
+  int ii,jj;
+  intmat U[N][N]=0;
+  for (ii=1;ii<N;ii++)
+  {
+    for (jj=ii+1;jj<=N;jj++)
+    {
+      U[ii,jj]=1;
+    }
+  }
+  return(U);
+}
+example
+{
+  "EXAMPLE:";echo=2;
+  ring   r = (0,q),(x,y,z),dp;
+  matrix C = UpOneMatrix(3);
+  C[1,3]   = q;
+  print(C);
+  def S = nc_algebra(C,0); setring S;
+  S;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+proc ndcond(list #)
+"USAGE:   ndcond();
+RETURN:  ideal
+PURPOSE: compute the non-degeneracy conditions of the basering
+NOTE: if @code{printlevel} > 0, the procedure displays intermediate information (by default, @code{printlevel}=0 )
+EXAMPLE: example ndcond; shows examples
+"
+{
+  // internal documentation, for tests etc
+  // 1st arg: v an optional integer (if v!=0, will be verbose)
+  // if the second argument is given, produces ndc w.r.t. powers x^N
+  int N = 1;
+  int Verbose = 0;
+  if ( size(#)>=1 ) { Verbose = int(#[1]); }
+  if ( size(#)>=2 ) { N = int(#[2]); }
+  Verbose = ((Verbose) || (printlevel>0));
+  int cnt = 1;
+  int numvars = nvars(basering);
+  int a,b,c;
+  poly p = 1;
+  ideal res = 0;
+  for (cnt=1; cnt<=N; cnt++)
+  {
+    if (Verbose) { "Processing degree :",cnt;}
+    for (a=1; a<=numvars-2; a++)
+    {
+      for (b=a+1; b<=numvars-1; b++)
+      {
+        for(c=b+1; c<=numvars; c++)
+        {
+          p = (var(c)^cnt)*(var(b)^cnt);
+          p = p*(var(a)^cnt);
+          p = p-(var(c)^cnt)*((var(b)^cnt)*(var(a)^cnt));
+          if (Verbose) {a,".",b,".",c,".";}
+          if (p!=0)
+          {
+            if ( res==0 )
+            {
+              res[1] = p;
+            }
+            else
+            {
+              res = res,p;
+            }
+            if (Verbose) { "failed:",p; }
+          }
+        }
+      }
+    }
+    if (Verbose) { "done"; }
+  }
+  return(res);
+}
+example
+{
+  "EXAMPLE:";echo=2;
+  ring r = (0,q1,q2),(x,y,z),dp;
+  matrix C[3][3];
+  C[1,2]=q2; C[1,3]=q1; C[2,3]=1;
+  matrix D[3][3];
+  D[1,2]=x; D[1,3]=z;
+  def S = nc_algebra(C,D); setring S;
+  S;
+  ideal j=ndcond(); // the silent version
+  j;
+  printlevel=1;
+  ideal i=ndcond(); // the verbose version
+  i;
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+proc Weyl(list #)
+"USAGE:   Weyl()
+RETURN:  ring
+PURPOSE: create a Weyl algebra structure on the basering
+NOTE: Activate this ring using the command @code{setring}.
+@*Assume the number of variables of a basering is 2k.
+(if the number of variables is odd, an error message will be returned)
+@*    by default, the procedure treats first k variables as coordinates x_i and the last k as differentials d_i
+@*    if a non-zero optional argument is given, the procedure treats 2k variables of a basering as k pairs (x_i,d_i), i.e. variables with odd numbers are treated as coordinates and with even numbers as differentials
+SEE ALSO: makeWeyl
+EXAMPLE: example Weyl; shows examples
+"
+{
+  //there are two possibilities for choosing the PBW basis.
+  //The variables have names x(i) for coordinates and d(i) for partial
+  // differentiations. By default, the procedure
+  //creates a ring, where the variables are ordered as x(1..n),d(1..n).  the
+  // tensor product-like realization x(1),d(1),x(2),d(2),... is used.
+  string rname=nameof(basering);
+  if ( rname == "basering") // i.e. no ring has been set yet
+  {
+    "You have to call the procedure from the ring";
+    return();
+  }
+  int @chr = 0;
+  if ( size(#) > 0 )
+  {
+    if ( typeof( #[1] ) == "int" )
+    {
+      @chr = #[1];
+    }
+  }
+  int nv = nvars(basering);
+  int N = nv div 2;
+  if ((nv % 2) != 0)
+  {
+    "Cannot create Weyl structure for an odd number of generators";
+    return();
+  }
+  matrix @D[nv][nv];
+  int i;
+  for ( i=1; i<=N; i++ )
+  {
+    if ( @chr==0 ) // default
+    {
+      @D[i,N+i]=1;
+    }
+    else
+    {
+      @D[2*i-1,2*i]=1;
+    }
+  }
+  def @R = nc_algebra(1, at D);
+  return(@R);
+}
+example
+{
+  "EXAMPLE:";echo=2;
+  ring A1=0,(x(1..2),d(1..2)),dp;
+  def S=Weyl();
+  setring S;  S;
+  kill A1,S;
+  ring B1=0,(x1,d1,x2,d2),dp;
+  def S=Weyl(1);
+  setring S;  S;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+proc makeHeisenberg(int N, list #)
+"USAGE:  makeHeisenberg(n, [p,d]); int n (setting 2n+1 variables), optional int p (field characteristic), optional int d (power of h in the commutator)
+RETURN: ring
+PURPOSE: create the n-th Heisenberg algebra in the variables x(1),y(1),...,x(n),y(n),h over the rationals Q or F_p with the relations
+\forall\;i\in\{1,2,\ldots,n\}\;\;y(j)x(i) = x(i)y(j)+h^d.
+SEE ALSO: makeWeyl
+NOTE: activate this ring with the @code{setring} command
+@*       If p is not prime, the next larger prime number will be used.
+EXAMPLE: example makeHeisenberg; shows examples
+"
+{
+  int @chr = 0;
+  int @deg = 1;
+  if ( size(#) > 0 )
+  {
+    if ( typeof( #[1] ) == "int" )
+    {
+      @chr = #[1];
+    }
+  }
+  if ( size(#) > 1 )
+  {
+    if ( typeof( #[2] ) == "int" )
+    {
+      @deg = #[2];
+      if (@deg <1) { @deg = 1; }
+    }
+  }
+  ring @@r=@chr,(x(1..N),y(1..N),h),lp;
+  matrix D[2*N+1][2*N+1];
+  int i;
+  for (i=1;i<=N;i++)
+  {
+    D[i,N+i]=h^@deg;
+  }
+  return(nc_algebra(1,D));
+}
+example
+{
+  "EXAMPLE:";echo=2;
+  def a = makeHeisenberg(2);
+  setring a;   a;
+  def H3 = makeHeisenberg(3, 7, 2);
+  setring H3;  H3;
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+proc superCommutative(list #)
+"USAGE:   superCommutative([b,[e, [Q]]]);
+RETURN:  qring
+PURPOSE:  create a super-commutative algebra (as a GR-algebra) over a basering,
+NOTE: activate this qring with the \"setring\" command.
+NOTE: if b==e then the resulting ring is commutative.
+@* By default, @code{b=1, e=nvars(basering), Q=0}.
+THEORY: given a basering, this procedure introduces the anti-commutative relations
+@* var(j)var(i)=-var(i)var(j) for all e>=j>i>=b and creates the quotient
+@* of the anti-commutative algebra modulo the two-sided ideal, generated by
+@* x(b)^2, ..., x(e)^2[ + Q]
+DISPLAY: If @code{printlevel} > 1, warning debug messages will be printed
+EXAMPLE: example superCommutative; shows examples
+"
+{
+  int fprot = (printlevel > 1); // (find(option(),"prot") != 0);
+
+  string rname=nameof(basering);
+
+  if ( rname == "basering") // i.e. no ring has been set yet
+  {
+    ERROR("You have to call the procedure from the ring");
+    return();
+  }
+
+  def saveRing = basering;
+
+  int N = nvars(saveRing);
+  int b = 1;
+  int e = N;
+  int flag = 0;
+
+  ideal Q = 0;
+
+  if(size(#)>0)
+  {
+    if(typeof(#[1]) != "int")
+    {
+      ERROR("The argument 'b' must be an integer!");
+      return();
+    }
+    b = #[1];
+
+    if((b < 1)||(b > N))
+    {
+      ERROR("The argument 'b' must within [1..nvars(basering)]!");
+      return();
+    }
+
+  }
+
+  if(size(#)>1)
+  {
+    if(typeof(#[2]) != "int")
+    {
+      ERROR("The argument 'e' must be an integer!");
+      return();
+    }
+    e = #[2];
+
+    if((e < 1)||(e > N))
+    {
+      ERROR("The argument 'e' must within [1..nvars(basering)]!");
+      return();
+    }
+
+    if(e < b)
+    {
+      ERROR("The argument 'e' must be bigger or equal to 'b'!");
+      return();
+    }
+  }
+
+  if(size(#)>2)
+  {
+    if(typeof(#[3]) != "ideal")
+    {
+      ERROR("The argument 'Q' must be an ideal!");
+      return();
+    }
+    Q = #[3];
+  }
+
+/*  if(size(#)>3)
+  {
+    if(typeof(#[4]) != "int")
+    {
+      ERROR("The argument 'flag' must be an integer!");
+      return();
+    }
+    flag = #[4];
+  }
+*/
+
+  int iSavedDegBoung = degBound;
+
+  if( (b == e) && (flag == 0) ) // commutative ring!!!
+  {
+    if( fprot == 1)
+    {
+      print("Warning: (b==e) means that the resulting ring will be commutative!");
+    }
+
+    degBound=0;
+    Q = std(Q + (var(b)^2));
+    degBound = iSavedDegBoung;
+
+    qring @EA = Q; // and it will be internally commutative as well!!!
+
+    return(@EA);
+  }
+
+/*
+  // Singular'(H.S.) politics: no ring copies!
+  // in future nc_algebra() should return a new ring!!!
+  list CurrRing = ringlist(basering);
+  def @R = ring(CurrRing);
+  setring @R; // @R;
+*/
+  int i, j;
+
+  if( (char(basering)==2) && (flag == 0) )// commutative ring!!!
+  {
+    if( fprot == 1)
+    {
+      print("Warning: (char == 2) means that the resulting ring will be commutative!");
+    }
+
+    ideal I;
+
+    for (i = e - b + 1; i > 0; i--)
+    {
+      I[i] = var(i + b - 1)^2;
+    }
+
+    degBound=0;
+    Q = std(I + Q);
+    degBound = iSavedDegBoung;
+
+    qring @EA = Q; // and it will be internally commutative as well!!!
+    return(@EA);
+  }
+
+
+
+  if( (b == 1) && (e == N) ) // just an exterior algebra?
+  {
+    def S = nc_algebra(-1, 0); // define ground G-algebra!
+    setring S;
+  } else
+  {
+    matrix @E = UpOneMatrix(N);
+
+    for ( i = b; i < e; i++ )
+    {
+      for ( j = i+1; j <= e; j++ )
+      {
+        @E[i, j] = -1;
+      }
+    }
+    def S = nc_algebra(@E, 0); // define ground G-algebra!
+    setring S;
+  }
+
+  ideal @I;
+
+  for (i = e - b + 1; i > 0; i--)
+  {
+    @I[i] = var(i + b - 1)^2;
+  }
+
+
+  degBound=0;
+  @I = twostd(@I); // must be computed within the ground G-algebra => problems with local orderings!
+  degBound = iSavedDegBoung;
+
+  qring @EA = @I;
+
+  ideal @Q = twostd(fetch(saveRing, Q));
+
+  if( size(@Q) > 0 )
+  {
+    qring @EA2 = @Q;
+  }
+
+  attrib(basering, "isSCA", 1==1);
+  attrib(basering, "iAltVarStart", b);
+  attrib(basering, "iAltVarEnd", e);
+
+//   "Alternating variables: [", AltVarStart(), ",", AltVarEnd(), "].";
+  return(basering);
+}
+example
+{
+  "EXAMPLE:";echo=2;
+  ring R = 0,(x(1..4)),dp; // global!
+  def ER = superCommutative(); // the same as Exterior (b = 1, e = N)
+  setring ER; ER;
+  "Alternating variables: [", AltVarStart(), ",", AltVarEnd(), "].";
+  kill R; kill ER;
+  ring R = 0,(x(1..4)),(lp(1), dp(3)); // global!
+  def ER = superCommutative(2); // b = 2, e = N
+  setring ER; ER;
+  "Alternating variables: [", AltVarStart(), ",", AltVarEnd(), "].";
+  kill R; kill ER;
+  ring R = 0,(x, y, z),(ds(1), dp(2)); // mixed!
+  def ER = superCommutative(2,3); // b = 2, e = 3
+  setring ER; ER;
+  "Alternating variables: [", AltVarStart(), ",", AltVarEnd(), "].";
+  x + 1 + z + y; // ordering on variables: y > z > 1 > x
+  std(x - x*x*x);
+  std(ideal(x - x*x*x, x*x*z + y, z + y*x*x));
+  kill R; kill ER;
+  ring R = 0,(x, y, z),(ds(1), dp(2)); // mixed!
+  def ER = superCommutative(2, 3, ideal(x - x*x, x*x*z + y, z + y*x*x )); // b = 2, e = 3
+  setring ER; ER;
+  "Alternating variables: [", AltVarStart(), ",", AltVarEnd(), "].";
+}
+
+// Please, don't throw this away!!! Needed for backward compatibility.
+proc SuperCommutative(list #)
+"USAGE:   please use @code{superCommutative} instead
+"
+{
+  "// This procedure is deprecated. Please use superCommutative instead";
+  return( superCommutative(#) );
+}
+example
+{
+  "EXAMPLE:";
+  "Procedure is deprecated. Please use superCommutative instead";
+}
+
+static proc ParseSCA()
+"
+RETURN: list {AltVarStart, AltVarEnd} is currRing is SCA, returns undef otherwise.
+NOTE: rings with only one non-commutative variable are commutative rings which are super-sommutative itself!
+"
+{
+  if(typeof(attrib(basering, "isSCA"))=="int") // workaround, if(defined()) doesn't work!!!!
+  {
+    if(typeof(attrib(basering, "iAltVarStart"))=="int")
+    {
+      if(typeof(attrib(basering, "iAltVarEnd"))=="int")
+      {
+        if(attrib(basering, "isSCA"))
+        {
+          return(list(
+            attrib(basering, "iAltVarStart"),
+            attrib(basering, "iAltVarEnd")
+                 ));
+        }
+      }
+    }
+  }
+
+  def saveRing = basering;
+
+  int i, j;
+  int N = nvars(saveRing);
+
+  int b = N+1;
+  int e =  -1;
+
+  int fprot = 0; // (find(option(),"prot") != 0);
+
+
+  if( size(ideal(saveRing)) == 0 )
+  {
+    return("SCA rings are factors by (at least) squares!"); // no squares in the factor ideal!
+  }
+
+  list L = ringlist(saveRing);
+
+  if( size(L)!=6 )
+  {
+    if(fprot)
+    {
+      print("// Warning: The current ring is internally commutative!");
+    }
+
+    for( i = N; i > 0; i-- )
+    {
+      if( NF(var(i)^2, std(0)) == 0 )
+      {
+        if( (fprot == 1) and (i > 1) )
+        {
+          print("// Warning: the SCA representation of the current commutative factor ring may be ambiguous!");
+        }
+
+        return( list(i, i) ); // this is not unique in this case! there may be other squares in the factor ideal!
+      }
+    }
+
+    return("The current commutative ring is not SCA! (Wrong quotient ideal)"); // no squares in the factor ideal!
+  }
+
+  module D = simplify(L[6], 2 + 4);
+
+  if( size(D)>0 )
+  {
+    return("The current ring is not SCA! (D!=0)");
+  }
+
+  matrix C = L[5];
+  poly c;
+
+  for( i = 1; i < N; i++ )
+  {
+    for( j = i+1; j <= N; j++ )
+    {
+      c = C[i, j];
+
+      if( c == -1 )
+      {
+        if(i < b)
+        {
+          b = i;
+        }
+
+        if(j > e)
+        {
+          e = j;
+        }
+      } else
+      { // should commute
+        if( c!=1 )
+        {
+          return("The current ring is not SCA! (C["+ string(i)+"," + string(j)+"]!=1)");
+        }
+      }
+    }
+  }
+
+  if( (b > N) || (e < 1))
+  {
+    if(fprot)
+    {
+      print("Warning: The current ring is a commutative GR-algebra!");
+    }
+
+    for( i = N; i > 0; i-- )
+    {
+      if( NF(var(i)^2, std(0)) == 0 )
+      {
+        if( (fprot == 1) and (i > 1) )
+        {
+          print("Warning: the SCA representation of the current factor ring may be ambiguous!");
+        }
+
+        return( list(i, i) ); // this is not unique in this case! there may be other squares in the factor ideal!
+      }
+    }
+
+    return("The current commutative GR-algebra is not SCA! (Wrong quotient ideal)"); // no squares in the factor ideal!
+  }
+
+  for( i = 1; i < N; i++ )
+  {
+    for( j = i+1; j <= N; j++ )
+    {
+      c = C[i, j];
+
+      if( (b <= i) && (j <= e) ) // S <= i < j <= E
+      { // anticommutative part
+        if( c!= -1 )
+        {
+          return("The current ring is not SCA! (C["+ string(i)+"," + string(j)+"]!=-1)");
+        }
+      } else
+      { // should commute
+        if( c!=1 )
+        {
+          return("The current ring is not SCA! (C["+ string(i)+"," + string(j)+"]!=1)");
+        }
+      }
+    }
+  }
+
+  for( i = b; i <= e; i++ )
+  {
+    if( NF(var(i)^2, std(0)) != 0 )
+    {
+      return("The current ring is not SCA! (Wrong quotient ideal)");
+    }
+  }
+
+  ////////////////////////////////////////////////////////////////////////
+  // ok. this is a SCA!!!
+
+  return(list(b, e));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+proc AltVarStart()
+"USAGE:   AltVarStart();
+RETURN:  int
+PURPOSE:  returns the number of the first alternating variable of basering
+NOTE:  basering should be a super-commutative algebra constructed by
+@*     the procedure @code{superCommutative}, emits an error otherwise
+EXAMPLE: example AltVarStart; shows examples
+"
+{
+  def l = ParseSCA();
+
+  if( typeof(l) != "string" )
+  {
+    return(l[1]);
+  }
+
+  ERROR(l);
+  return();
+}
+example
+{
+  "EXAMPLE:";echo=2;
+  ring R = 0,(x(1..4)),dp; // global!
+  def ER = superCommutative(2); // (b = 2, e = N)
+  setring ER; ER;
+  "Alternating variables: [", AltVarStart(), ",", AltVarEnd(), "].";
+  setring R;
+  "Alternating variables: [", AltVarStart(), ",", AltVarEnd(), "].";
+  kill R, ER;
+  //////////////////////////////////////////////////////////////////
+  ring R = 2,(x(1..4)),dp; // the same in char. = 2!
+  def ER = superCommutative(2); // (b = 2, e = N)
+  setring ER; ER;
+  "Alternating variables: [", AltVarStart(), ",", AltVarEnd(), "].";
+  setring R;
+  "Alternating variables: [", AltVarStart(), ",", AltVarEnd(), "].";
+}
+
+///////////////////////////////////////////////////////////////////////////////
+proc AltVarEnd()
+"USAGE:   AltVarStart();
+RETURN:  int
+PURPOSE:  returns the number of the last alternating variable of basering
+NOTE:  basering should be a super-commutative algebra constructed by
+@*     the procedure @code{superCommutative}, emits an error otherwise
+EXAMPLE: example AltVarEnd; shows examples
+"
+{
+  def l = ParseSCA();
+
+  if( typeof(l) != "string" )
+  {
+    return(l[2]);
+  }
+
+  ERROR(l);
+  return();
+}
+example
+{
+  "EXAMPLE:";echo=2;
+  ring R = 0,(x(1..4)),dp; // global!
+  def ER = superCommutative(2); // (b = 2, e = N)
+  setring ER; ER;
+  "Alternating variables: [", AltVarStart(), ",", AltVarEnd(), "].";
+  setring R;
+  "Alternating variables: [", AltVarStart(), ",", AltVarEnd(), "].";
+  kill R, ER;
+  //////////////////////////////////////////////////////////////////
+  ring R = 2,(x(1..4)),dp; // the same in char. = 2!
+  def ER = superCommutative(2); // (b = 2, e = N)
+  setring ER; ER;
+  "Alternating variables: [", AltVarStart(), ",", AltVarEnd(), "].";
+  setring R;
+  "Alternating variables: [", AltVarStart(), ",", AltVarEnd(), "].";
+}
+
+///////////////////////////////////////////////////////////////////////////////
+proc IsSCA()
+"USAGE:   IsSCA();
+RETURN:  int
+PURPOSE:  returns 1 if basering is a super-commutative algebra and 0 otherwise
+EXAMPLE: example IsSCA; shows examples
+"
+{
+  def l = ParseSCA();
+
+  if( typeof(l) != "string" )
+  {
+    return(1);
+  }
+
+  if( find(option(),"prot") != 0 )
+  {
+    print(l);
+  }
+
+  return(0);
+}
+example
+{
+  "EXAMPLE:";echo=2;
+/////////////////////////////////////////////////////////////////////
+  ring R = 0,(x(1..4)),dp; // commutative
+  if(IsSCA())
+    { "Alternating variables: [", AltVarStart(), ",", AltVarEnd(), "]."; }
+  else
+    { "Not a super-commutative algebra!!!"; }
+  kill R;
+/////////////////////////////////////////////////////////////////////
+  ring R = 0,(x(1..4)),dp;
+  def S = nc_algebra(1, 0); setring S; S; // still commutative!
+  if(IsSCA())
+    { "Alternating variables: [", AltVarStart(), ",", AltVarEnd(), "]."; }
+  else
+    { "Not a super-commutative algebra!!!"; }
+  kill R, S;
+/////////////////////////////////////////////////////////////////////
+  ring R = 0,(x(1..4)),dp;
+  list CurrRing = ringlist(R);
+  def ER = ring(CurrRing);
+  setring ER; // R;
+
+  matrix E = UpOneMatrix(nvars(R));
+
+  int i, j; int b = 2; int e = 3;
+
+  for ( i = b; i < e; i++ )
+  {
+    for ( j = i+1; j <= e; j++ )
+    {
+      E[i, j] = -1;
+    }
+  }
+
+  def S = nc_algebra(E,0); setring S; S;
+
+  if(IsSCA())
+    { "Alternating variables: [", AltVarStart(), ",", AltVarEnd(), "]."; }
+  else
+    { "Not a super-commutative algebra!!!"; }
+  kill R, ER, S;
+/////////////////////////////////////////////////////////////////////
+  ring R = 0,(x(1..4)),dp;
+  def ER = superCommutative(2); // (b = 2, e = N)
+  setring ER; ER;
+  if(IsSCA())
+    { "This is a SCA! Alternating variables: [", AltVarStart(), ",", AltVarEnd(), "]."; }
+  else
+    { "Not a super-commutative algebra!!!"; }
+  kill R, ER;
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+proc Exterior(list #)
+"USAGE:   Exterior();
+RETURN:  qring
+PURPOSE:  create the exterior algebra of a basering
+NOTE:  activate this qring with the \"setring\" command
+THEORY: given a basering, this procedure introduces the anticommutative relations x(j)x(i)=-x(i)x(j) for all j>i,
+@* moreover, creates a factor algebra modulo the two-sided ideal, generated by x(i)^2 for all i
+EXAMPLE: example Exterior; shows examples
+"
+{
+  string rname=nameof(basering);
+  if ( rname == "basering") // i.e. no ring has been set yet
+  {
+    "You have to call the procedure from the ring";
+    return();
+  }
+  int N = nvars(basering);
+  string NewRing = "ring @R=("+charstr(basering)+"),("+varstr(basering)+"),("+ordstr(basering)+");";
+  execute(NewRing);
+  matrix @E = UpOneMatrix(N);
+  @E = -1*(@E);
+  def @@RR = nc_algebra(@E,0); setring @@RR;
+  int i;
+  ideal Q;
+  for ( i=1; i<=N; i++ )
+  {
+    Q[i] = var(i)^2;
+  }
+  Q = twostd(Q);
+  qring @EA = Q;
+  return(@EA);
+}
+example
+{
+  "EXAMPLE:";echo=2;
+  ring R = 0,(x(1..3)),dp;
+  def ER = Exterior();
+  setring ER;
+  ER;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+proc makeWeyl(int n, list #)
+"USAGE:  makeWeyl(n,[p]); n an integer, n>0; p an optional integer (field characteristic)
+RETURN:  ring
+PURPOSE: create the n-th Weyl algebra over the rationals Q or F_p
+NOTE:    activate this ring with the \"setring\" command.
+@*       The presentation of an n-th Weyl algebra is classical: D(i)x(i)=x(i)D(i)+1,
+@*       where x(i) correspond to coordinates and D(i) to partial differentiations, i=1,...,n.
+@*       If p is not prime, the next larger prime number will be used.
+SEE ALSO: Weyl
+EXAMPLE: example makeWeyl; shows examples
+"{
+  if (n<1)
+  {
+    print("Incorrect input");
+    return();
+  }
+  int @p = 0;
+  if ( size(#) > 0 )
+  {
+    if ( typeof( #[1] ) == "int" )
+    {
+      @p = #[1];
+    }
+  }
+  if (n ==1)
+  {
+    ring @rr = @p,(x,D),dp;
+  }
+  else
+  {
+    ring @rr = @p,(x(1..n),D(1..n)),dp;
+  }
+  setring @rr;
+  def @rrr = Weyl();
+  return(@rrr);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   def a = makeWeyl(3);
+   setring a;
+   a;
+}
+
+//////////////////////////////////////////////////////////////////////
+proc isNC()
+"USAGE:   isNC();
+PURPOSE: check whether a basering is commutative or not
+RETURN:   int, 1 if basering is noncommutative and 0 otherwise
+EXAMPLE: example isNC; shows examples
+"{
+  string rname=nameof(basering);
+  if ( rname == "basering") // i.e. no ring has been set yet
+  {
+    "You have to call the procedure from the ring";
+    return();
+  }
+  int n = nvars(basering);
+  int i,j;
+  poly p;
+  for (i=1; i<n; i++)
+  {
+    for (j=i+1; j<=n; j++)
+    {
+      p = var(j)*var(i) - var(i)*var(j);
+      if (p!=0) { return(1);}
+    }
+  }
+  return(0);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   def a = makeWeyl(2);
+   setring a;
+   isNC();
+   kill a;
+   ring r = 17,(x(1..7)),dp;
+   isNC();
+   kill r;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+proc rightStd(def I)
+"USAGE:  rightStd(I); I an ideal/ module
+PURPOSE: compute a right Groebner basis of I
+RETURN:  the same type as input
+EXAMPLE: example rightStd; shows examples
+"
+{
+  def A = basering;
+  def Aopp = opposite(A);
+  setring Aopp;
+  def Iopp = oppose(A,I);
+  def Jopp = groebner(Iopp);
+  setring A;
+  def J = oppose(Aopp,Jopp);
+  return(J);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  LIB "ncalg.lib";
+  def A = makeUsl(2);
+  setring A;
+  ideal I = e2,f;
+  option(redSB);
+  option(redTail);
+  ideal LI = std(I);
+  LI;
+  ideal RI = rightStd(I);
+  RI;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+proc rightSyz(def I)
+"USAGE:  rightSyz(I); I an ideal/ module
+PURPOSE: compute a right syzygy module of I
+RETURN:  the same type as input
+EXAMPLE: example rightSyz; shows examples
+"
+{
+  def A = basering;
+  def Aopp = opposite(A);
+  setring Aopp;
+  def Iopp = oppose(A,I);
+  def Jopp = syz(Iopp);
+  setring A;
+  def J = oppose(Aopp,Jopp);
+  return(J);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,d),dp;
+  def S = nc_algebra(1,1); setring S; // the first Weyl algebra
+  ideal I = x,d;
+  module LS = syz(I);
+  print(LS);
+  module RS = rightSyz(I);
+  print(RS);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+proc rightNF(def v, def M)
+"USAGE:  rightNF(I); v a poly/vector, M an ideal/module
+PURPOSE: compute a right normal form of v w.r.t. M
+RETURN:  poly/vector (as of the 1st argument)
+EXAMPLE: example rightNF; shows examples
+"
+{
+  def A = basering;
+  def Aopp = opposite(A);
+  setring Aopp;
+  def vopp = oppose(A,v);
+  def Mopp = oppose(A,M);
+  Mopp = std(Mopp);
+  def wopp = NF(vopp,Mopp);
+  setring A;
+  def w    = oppose(Aopp,wopp);
+  w = simplify(w,2); // skip zeros in ideal/module
+  return(w);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  LIB "ncalg.lib";
+  ring r = 0,(x,d),dp;
+  def S = nc_algebra(1,1); setring S; // Weyl algebra
+  ideal I = x; I = std(I);
+  poly  p = x*d+1;
+  NF(p,I); // left normal form
+  rightNF(p,I); // right normal form
+}
+
+// **********************************
+// * NF: Example for vector/module: *
+// **********************************
+// module M = [x,0],[0,d]; M = std(M);
+// vector v = (x*d+1)*[1,1];
+// print(NF(v,M));
+// print(rightNF(v,M));
+
+///////////////////////////////////////////////////////////////////////////////
+proc rightModulo(def M, def N)
+"USAGE:  rightModulo(M,N); M,N are ideals/modules
+PURPOSE: compute a right representation of the module (M+N)/N
+RETURN:  module
+ASSUME:  M,N are presentation matrices for right modules
+EXAMPLE: example rightModulo; shows examples
+"
+{
+  def A = basering;
+  def Aopp = opposite(A);
+  setring Aopp;
+  def Mopp = oppose(A,M);
+  def Nopp = oppose(A,N);
+  def Kopp = modulo(Mopp,Nopp);
+  setring A;
+  def K = oppose(Aopp,Kopp);
+  return(K);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  LIB "ncalg.lib";
+  def A = makeUsl(2);
+  setring A;
+  option(redSB);
+  option(redTail);
+  ideal I = e2,f2,h2-1;
+  I = twostd(I);
+  print(matrix(I));
+  ideal E  = std(e);
+  ideal TL = e,h-1; // the result of left modulo
+  TL;
+  ideal T = rightModulo(E,I);
+  T = rightStd(T+I);
+  T = rightStd(rightNF(T,I)); // make the output canonic
+  T;
+}
+
+//////////////////////////////////////////////////////////////////////
+
+proc isCommutative ()
+"USAGE:  isCommutative();
+RETURN:  int, 1 if basering is commutative, or 0 otherwise
+PURPOSE: check whether basering is commutative
+EXAMPLE: example isCommutative; shows an example
+"
+{
+  int iscom = 1;
+  list L = ringlist(basering);
+  if (size(L) > 4) // basering is nc_algebra
+  {
+    matrix C = L[5];
+    matrix D = L[6];
+    if (size(module(D)) <> 0) { iscom = 0; }
+    else
+    {
+      matrix U = UpOneMatrix(nvars(basering));
+      if (size(module(C-U)) <> 0) { iscom = 0; }
+    }
+  }
+  return(iscom);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y),dp;
+  isCommutative();
+  def D = Weyl(); setring D;
+  isCommutative();
+  setring r;
+  def R = nc_algebra(1,0); setring R;
+  isCommutative();
+}
+
+//////////////////////////////////////////////////////////////////////
+
+proc isWeyl ()
+"USAGE:  isWeyl();
+RETURN:  int, 1 if basering is a Weyl algebra, or 0 otherwise
+PURPOSE: check whether basering is a Weyl algebra
+EXAMPLE: example isWeyl; shows an example
+"
+{
+  int i,j;
+  int notW = 0;
+  int N = nvars(basering);
+  if (N mod 2 <> 0) { return(notW); } // odd number of generators
+  int n = N div 2;
+  list L = ringlist(basering);
+  if (size(L) < 6) { return(notW); } // basering is commutative
+  matrix C = L[5];
+  matrix D = L[6];
+  matrix U = UpOneMatrix(N);
+  if (size(ideal(C-U)) <> 0) { return(notW); } // lt(xy)<>lt(yx)
+  ideal I = D;
+  if (size(I) <> n) { return(notW); } // not n entries<>0
+  I = simplify(I,4+2);
+  int sI = size(I);
+  if (sI > 2) { return(notW); }  // more than 2 distinct entries
+  for (i=1; i<=sI; i++)
+  {
+    if (I[i]<>1 && I[i]<>-1) { return (notW); } // other values apart from 1,-1
+  }
+  ideal Ro,Co;
+  for (i=1; i<=N; i++)
+  {
+    Ro = D[1..N,i];
+    Co = D[i,1..N];
+    if (size(Ro)>1 || size(Co)>1)
+    {
+      return(int(0)); // var(i) doesn't commute with more than 1 other vars
+    }
+  }
+  return(int(1)); // all tests passed: basering is Weyl algebra
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(a,b,c,d),dp;
+  isWeyl();
+  def D = Weyl(1); setring D; //make from r a Weyl algebra
+  b*a;
+  isWeyl();
+  ring t = 0,(Dx,x,y,Dy),dp;
+  matrix M[4][4]; M[1,2]=-1; M[3,4]=1;
+  def T = nc_algebra(1,M); setring T;
+  isWeyl();
+}
+
+//////////////////////////////////////////////////////////////////////
+
+proc embedMat(matrix A, int m, int n)
+"USAGE:  embedMat(A,m,n); A,B matrix/module
+RETURN:  matrix
+PURPOSE: embed A in the left upper corner of mxn matrix
+EXAMPLE: example embedMat; shows an example
+"
+{
+  // returns A embedded in the left upper corner of mxn matrix
+  int rA = nrows(A);
+  int cA = ncols(A);
+  if ((rA >m) || (cA>n))
+  {
+    ERROR("wrong dimensions of the new matrix");
+  }
+  matrix @M[m][n];
+  int i,j;
+  for(i=1;i<=rA; i++)
+  {
+    for(j=1;j<=cA; j++)
+    {
+      @M[i,j]=A[i,j];
+    }
+  }
+  return(@M);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(a,b,c,d),dp;
+  matrix M[2][3]; M[1,1]=a; M[1,2]=b;M[2,2]=d;M[1,3]=c;
+  print(M);
+  print(embedMat(M,3,4));
+  matrix N = M; N[2,2]=0;
+  print(embedMat(N,3,4));
+}
+
+//proc moduloSlim (matrix A, matrix B)
+proc moduloSlim (module A, module B)
+"USAGE:  moduloSlim(A,B); A,B module/matrix/ideal
+RETURN:  module
+PURPOSE: compute @code{modulo} with slimgb as engine
+EXAMPLE: example moduloSlim; shows an example
+"
+{
+  def save  = basering;
+  int rA = nrows(A);  int rB = nrows(B);
+  int cA = ncols(A);  int cB = ncols(B);
+  int j;
+  int dab; // difference a,b
+  dab = rA - rB;
+  if (dab <0)
+  {
+    // rA<rB: add zero rows to A
+    dab = -dab;
+    A = embedMat(A,rB,cA);
+  }
+  else
+  {
+    // rA>rB: add zero rows to B
+    B = embedMat(B,rA,cB);
+  }
+  def mering = makeModElimRing(save);
+  setring mering;
+  module A = imap(save, A);
+  module B = imap(save, B);
+  // create matrix C
+  //  matrix C[2*rA][cA+cB];
+  module C;
+  int i;
+  for(i=1; i<= cA; i++)
+  {
+    C = C, A[i] + gen(rA + i);
+  }
+  C = C,B;
+//   for(i=1; i<=cB; i++)
+//   {
+//     C = C, B[i];
+//   }
+  C = C[2..ncols(C)];
+//  print(C);
+  matrix D = slimgb(C);
+  module E; int k;
+  // TODO: why only first row? need smth like rA rows...
+  for(i=1; i<= ncols(D); i++)
+  {
+    k=1;
+    // determine first zero in the column
+    while ( (D[k,i]==0) && (k<= cA+rA) )
+    {
+      k++;
+    }
+    // what can that be: k = cA+rA+1=> zero column
+    // k<=rA => column not in ker
+    // rA+1 <= k <= rA+cA => column in ker
+    if ( ( k>=rA+1) && (k<=rA+cA) )
+    {
+      E = E,D[i];
+    }
+  }
+//   for(i=1; i<= ncols(D); i++)
+//   {
+//     if (D[1,i]==0)
+//     {
+//       E = E,D[i];
+//     }
+//   }
+//  // this E has 1st column and 1st row zero
+  // use submat at matrix.lib
+  //  E = submat(E,intvec(2..nrows(E)),intvec(2..ncols(E)));
+  E = submat(E,intvec(rA+1..nrows(E)),intvec(2..ncols(E)));
+  setring save;
+  module E = imap(mering,E);
+  kill mering;
+  // TODO: clean components!
+  return(E);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  LIB "ncalg.lib";
+  ring r; // first classical example for modulo
+  ideal h1=x,y,z;    ideal h2=x;
+  module m=moduloSlim(h1,h2);
+  print(m);
+  // now, a noncommutative example
+  def A = makeUsl2(); setring A; // this algebra is U(sl_2)
+  ideal H2 = e2,f2,h2-1; H2 = twostd(H2);
+  print(matrix(H2)); // print H2 in a compact form
+  ideal H1 = std(e);
+  ideal T = moduloSlim(H1,H2);
+  T = std( NF(std(H2+T),H2) );
+  T;
+  // now, a matrix example:
+  ring r2 = 0,(x,d), (dp);
+  def R = nc_algebra(1,1); setring R;
+  matrix M[2][2] = d, 0, 0, d*(x*d);
+  matrix P[2][1] = (8x+7)*d+9x, (x2+1)*d + 5*x;
+  module X = moduloSlim(P,M);
+  print(X);
+}
+
+//////////////////////////////////////////////////////////////////////
+
+proc makeModElimRing(list #)
+"USAGE:  makeModElimRing(L); L a list
+RETURN:  ring
+PURPOSE: create a copy of a given ring equipped with the
+@* elimination ordering for module components @code{(c,<)}
+NOTE: usually the list argument contains a ring to work with
+EXAMPLE: example makeModElimRing; shows an example
+"
+{
+  // supports qring;
+  // can be extended to handle C istead of c
+  /* input/basering business */
+  def save; int Noinput = 0;
+  if ( size(#)>0 )
+  {
+    if ( (typeof(#[1]) == "ring" ) || (typeof(#[1]) == "qring" ) )
+    {
+      save = #[1];
+    }
+    else
+    {
+      print("unsupported input type, proceeding with basering");
+      Noinput = 1;
+    }
+  }
+  if (Noinput)
+  {
+    if (nameof(basering)=="basering")
+    {
+      ERROR("no rings are given");
+    }
+    else
+    {
+      save = basering;
+    }
+  }
+  /* END input/basering business */
+  list L = ringlist(save);
+  list Ord = L[3];
+  int s = size(Ord); int done;
+  // detect where module ordering is located: either 1st or last entry
+  int i,j;
+  for(i=1; i<=s; i++)
+  {
+    if ( (Ord[i][1] == "C") || (Ord[i][1] == "c") )
+    {
+      Ord[i][1] = "c";
+      j = i; i=s;
+    }
+  }
+  if (j==0) { ERROR("no component entry found in the ringlist"); }
+  list N;
+  N[1] = Ord[j];
+  for(i=2; i<=j; i++)
+  {
+    N[i] = Ord[i-1];
+  }
+  for(i=j+1; i<=s; i++)
+  {
+    N[i] = Ord[i];
+  }
+  L[3] = N; def NR = ring(L);
+  return(NR);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r1 = 0,(x,y,z),(C,Dp);
+  def r2 = makeModElimRing(r1); setring r2; r2;   kill r2;
+  ring r3 = 0,(z,t),(wp(2,3),c);
+  def r2 = makeModElimRing(r3); setring r2; r2; kill r2;
+  ring r4 = 0,(z,t,u,w),(a(1,2),C,wp(2,3,4,5));
+  def r2 = makeModElimRing(r4); setring r2; r2;
+}
+
+proc isLieType()
+"USAGE:  isLieType();
+RETURN:  int, 1 if basering is a G-algebra of Lie type, 0 otherwise
+PURPOSE: G-algebra of Lie type has relations of the kind Y*X=X*Y+D
+EXAMPLE: example isLieType; shows an example
+"
+{
+  def @B    = basering; //save the name of basering
+  int NVars = nvars(@B); //number of variables in basering
+  int i, j;
+
+  int answer = 1;
+
+  // check basering is of Lie type:
+  matrix @@CC[NVars][NVars];
+  for(i=1; i<NVars; i++)
+  {
+    for(j=i+1; j<=NVars; j++)
+    {
+      @@CC[i,j]=leadcoef(var(j)*var(i));
+    }
+  }
+  ideal @C@ = simplify(ideal(@@CC),2+4);// skip zeroes and repeated entries
+  if (  (size(@C@) >1 ) || ( (size(@C@)==1) && (@C@[1]!=1) )  )
+  {
+    answer = 0;
+  }
+  return(answer);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0,(x,y),dp;
+  y*x;
+  isLieType(); //yes
+  def D = Weyl(); setring D;
+  y*x;
+  isLieType(); //yes
+  setring r;
+  def R = nc_algebra(-3,0); setring R;
+  y*x;
+  isLieType(); // no
+  kill R; kill r;
+  ring s = (0,q),(x,y),dp;
+  def S = nc_algebra(q,0); setring S;
+  y*x;
+  isLieType(); //no
+  kill S; setring s;
+  def S = nc_algebra(q,y^2); setring S;
+  y*x;
+  isLieType(); //no
+}
diff --git a/Singular/LIB/noether.lib b/Singular/LIB/noether.lib
new file mode 100644
index 0000000..07c6408
--- /dev/null
+++ b/Singular/LIB/noether.lib
@@ -0,0 +1,995 @@
+/////////////////////////////////////////////////////////////////////////////
+version="version noether.lib 4.0.0.0 Jun_2013 "; // $Id: a125fd69fe1ef3188e64d223ff48e5846f4b7250 $
+category="Commutative Algebra";
+info="
+LIBRARY: noether.lib   Noether normalization of an ideal (not nessecary
+                       homogeneous)
+AUTHORS: A. Hashemi,  Amir.Hashemi at lip6.fr
+
+
+OVERVIEW:
+A library for computing the Noether normalization of an ideal that DOES NOT
+require the computation of the dimension of the ideal.
+It checks whether an ideal is in Noether position.  A modular version of
+these algorithms is also provided.
+The procedures are based on a paper of Amir Hashemi 'Efficient Algorithms for
+Computing Noether Normalization' (presented in ASCM 2007)
+
+This library computes also Castelnuovo-Mumford regularity and satiety of an
+ideal.  A modular version of these algorithms is also provided.
+The procedures are based on a paper of Amir Hashemi 'Computation of
+Castelnuovo-Mumford regularity and satiety' (preprint 2008)
+
+
+PROCEDURES:
+ NPos_test(id);  checks whether monomial ideal id is in Noether position
+ modNpos_test(id); the same as above using modular methods
+ NPos(id);       Noether normalization of ideal id
+ modNPos(id);      Noether normalization of ideal id by modular methods
+ nsatiety(id); Satiety of ideal id
+ modsatiety(id)  Satiety of ideal id by modular methods
+ regCM(id);    Castelnuovo-Mumford regularity of ideal id
+ modregCM(id); Castelnuovo-Mumford regularity of ideal id by modular methods
+";
+LIB "elim.lib";
+LIB "algebra.lib";
+LIB "poly.lib";
+LIB "ring.lib";
+LIB "presolve.lib";
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc NPos_test (ideal I)
+"
+USAGE:  NPos_test (I); I monomial ideal
+RETURN: A list whose first element is 1, if i is in Noether position,
+        0 otherwise. The second element of this list is a list of variables ordered
+        such that those variables are listed first, of which a power belongs to the
+        initial ideal of i. If i is in Noether position, the method returns furthermore
+        the dimension of i.
+ASSUME: i is a nonzero monomial ideal.
+"
+{
+//--------------------------- initialisation ---------------------------------
+   int  time,ii,j,k,l,d,t,jj;
+   intvec v;
+   def r0 = basering;
+   int n = nvars(r0)-1;
+   list L,Y,P1,P2,P3;
+   if (I[1]==1)
+   {
+     print("The ideal is 1");return(1);
+   }
+   for ( ii = 1; ii <= n+1; ii++ )
+   {
+     L[ii]=0;
+   }
+   for ( ii = 1; ii <= size(I); ii++ )
+   {
+     Y=findvars(I[ii],1)[1];
+     l=rvar(Y[1][1]);
+     if (size(Y[1])==1)
+     {
+       L[l]=1;
+       P1=insert(P1,Y[1][1]);
+     }
+     if (L[l]==0)
+     {
+       L[l]=-1;
+     }
+   }
+   t=size(P1);
+   if (t==0)
+   {
+     for ( jj = 1; jj <= n+1; jj++ )
+     {
+       P3=insert(P3,varstr(jj));
+     }
+   }
+   else
+   {
+     P2=findvars(ideal(P1[1..t]),1)[3];
+     for ( jj = 1; jj <= size(P2[1]); jj++ )
+     {
+       P3=insert(P3,P2[1][jj]);
+     }
+   }
+   if (L[n+1]==-1)
+   {
+     return(list(0,P1+P3));
+   }
+   for ( ii = 1; ii <= n; ii++ )
+   {
+     if (L[ii]==-1)
+     {
+       return(list(0,P1+P3));
+     }
+     if (L[ii]==0 and L[ii+1]==1)
+     {
+       return(list(0,P1+P3));
+     }
+   }
+   d=n+1-sum(L);
+   print("The dimension of the ideal is:");print(d);
+   return(list(1,P1+P3));
+}
+//////////////////////////////////////////
+proc modNpos_test (ideal i)
+"USAGE: modNpos_test(i); i an ideal
+RETURN: 1 if i is in Noether position 0  otherwise.
+NOTE:   This test is a probabilistic test, and it computes the initial of the ideal modulo the prime number 2147483647 (the biggest prime less than 2^31).
+"
+{
+  "// WARNING:
+// The procedure is probabilistic and  it computes the initial of the ideal modulo the prime number 2147483647";
+  int p;
+  def br=basering;
+  setring br;
+  ideal I;
+  list #;
+  option(redSB);
+  p=2147483647;
+  #=ringlist(br);
+  #[1]=p;
+  def oro=ring(#);
+  setring oro;
+  ideal sbi,lsbi;
+  sbi=fetch(br,i);
+  lsbi=lead(std(sbi));
+  setring br;
+  I=fetch(oro,lsbi);
+  I=simplify(I,1);
+  attrib(I,"isSB",1);
+  return(NPos_test(I));
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+proc NPos (ideal i)
+"USAGE:  NPos(i); i ideal
+RETURN:  A linear map phi such that  phi(i) is in Noether position
+"
+{
+//--------------------------- initialisation ---------------------------------
+  int ii,jj,d,time,n,nl;
+  intmat ran;
+  def r0 = basering;
+  ideal K,chcoord;
+  n = nvars(r0)-1;
+  string s = "ring r1 = ",charstr(r0),",x(0..n),dp;";
+  execute(s);
+  ideal i,sbi,I,K,chcoord,m,L;
+  list #;
+  poly P;
+  map phi;
+  i = fetch(r0,i);
+  time=rtimer;
+  system("--ticks-per-sec",10);
+  i=std(i);
+  sbi=sort(lead(i))[1];
+  #=NPos_test(sbi);
+  if ( #[1]== 1 )
+  {
+    return ("The ideal is in Noether position and the time of this computation is:",rtimer-time,"/10 sec.");
+  }
+  else
+  {
+    L=maxideal(1);
+    chcoord=maxideal(1);
+    for ( ii = 1; ii<=n+1; ii++ )
+    {
+      chcoord[rvar(#[2][ii])]=L[ii];
+    }
+    phi=r1,chcoord;
+    sbi=phi(sbi);
+    if ( NPos_test(sbi)[1] == 1 )
+    {
+      setring r0;
+      chcoord=fetch(r1,chcoord);
+      return (chcoord,"and the time of this computation is:",rtimer-time,"/10 sec.");
+    }
+  }
+  while ( nl < 30 )
+  {
+    nl=nl+1;
+    I=i;
+    L=maxideal(1);
+    for ( ii = n; ii>=0; ii-- )
+    {
+      chcoord=select1(maxideal(1),1..ii);
+      ran=random(100,1,ii);
+      ran=intmat(ran,1,ii+1);
+      ran[1,ii+1]=1;
+      m=select1(maxideal(1),1..(ii+1));
+      for ( jj = 1; jj<=ii+1; jj++ )
+      {
+        P=P+ran[1,jj]*m[jj];
+      }
+      chcoord[ii+1]=P;
+      L[ii+1]=P;
+      P=0;
+      phi=r1,chcoord;
+      I=phi(I);
+      if ( NPos_test(sort(lead(std(I)))[1])[1] == 1 )
+      {
+        K=x(ii..n);
+        setring r0;
+        K=fetch(r1,K);
+        ideal L=fetch(r1,L);
+        return (L,"and the time of this computation is:",rtimer-time,"/10 sec.");
+      }
+    }
+  }
+  "// WARNING:
+// The procedure has entered in more than 30 loops: in your example
+// the method may enter an infinite loop over a finite field!";
+  return (-1);
+}
+///////////////////////////////////////////////////////////////////////////////
+proc modNPos (ideal i)
+"USAGE:  modNPos(i); i ideal
+RETURN:  A linear map phi such that  phi(i) is in Noether position
+NOTE:    It uses the procedure  modNPos_test to test Noether position.
+"
+{
+//--------------------------- initialisation ---------------------------------
+   int ii,jj,d,time,n,nl;
+   intmat ran;
+   def r0 = basering;
+   ideal K,chcoord;
+   n = nvars(r0)-1;
+   string s = "ring r1 = ",charstr(r0),",x(0..n),dp;";
+   execute(s);
+   ideal i,sbi,I,K,chcoord,m,L;
+   poly P;
+   list #;
+   map phi;
+   i = fetch(r0,i);
+   time=rtimer;
+   system("--ticks-per-sec",10);
+   #=modNPos_test(i);
+   if ( #[1]== 1 )
+   {
+     return ("The ideal is in Noether position and the time of this computation is:",rtimer-time,"/10 sec.");
+   }
+   else
+   {
+     L=maxideal(1);
+     chcoord=maxideal(1);
+     for ( ii = 1; ii<=n+1; ii++ )
+     {
+       chcoord[rvar(#[2][ii])]=L[ii];
+     }
+     phi=r1,chcoord;
+     I=phi(i);
+     if ( modNPos_test(I)[1] == 1 )
+     {
+       setring r0;
+       chcoord=fetch(r1,chcoord);
+       return (chcoord,"and the time of this computation is:",rtimer-time,"/10 sec.");
+     }
+   }
+   while ( nl < 30 )
+   {
+     nl=nl+1;
+     I=i;
+     L=maxideal(1);
+     for ( ii = n; ii>=0; ii-- )
+     {
+       chcoord=select1(maxideal(1),1..ii);
+       ran=random(100,1,ii);
+       ran=intmat(ran,1,ii+1);
+       ran[1,ii+1]=1;
+       m=select1(maxideal(1),1..(ii+1));
+       for ( jj = 1; jj<=ii+1; jj++ )
+       {
+         P=P+ran[1,jj]*m[jj];
+       }
+       chcoord[ii+1]=P;
+       L[ii+1]=P;
+       P=0;
+       phi=r1,chcoord;
+       I=phi(I);
+       if ( modNPos_test(I)[1] == 1 )
+       {
+         K=x(ii..n);
+         setring r0;
+         K=fetch(r1,K);
+         ideal L=fetch(r1,L);
+         return (L,"and the time of this computation is:",rtimer-time,"/10 sec.");
+       }
+     }
+   }
+   "// WARNING:
+// The procedure has entered in more than 30 loops: in your example
+// the method may enter an infinite loop over a finite field!";
+   return (-1);
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+static proc TestLastVarIsInGenericPos (ideal i)
+"USAGE:   TestLastVarIsInGenericPos (i); i a monomial ideal,
+RETURN:  1 if the last variable is in generic position for i and 0 otherwise.
+THEORY:  The last variable is in generic position if the quotient of the ideal
+         with respect to this variable is equal to the quotient of the ideal with respect to the maximal ideal.
+"
+{
+//--------------------------- initialisation ---------------------------------
+  int n,ret;
+  def r0 = basering;
+  n = nvars(r0)-1;
+  string s = "ring r1 = ",charstr(r0),",x(0..n),dp;";
+  execute(s);
+  ideal I,i;
+  i = fetch(r0,i);
+  attrib(i,"isSB",1);
+  I=quotient(select(i,n+1),x(n));
+  I=I*maxideal(1);
+  ret=1;
+  if (size(reduce(I,i)) <> 0)
+  {
+    ret=0;
+  }
+  return(ret);
+}
+
+
+////////////////////////////////////////////////////////////////////////////////////
+proc nsatiety (ideal i)
+"USAGE:   nsatiety (i); i ideal,
+RETURN:  an integer, the satiety of i.
+         (returns -1 if i is not homogeneous)
+ASSUME:  i is a homogeneous ideal of the basering R=K[x(0)..x(n)].
+THEORY:  The satiety, or saturation index, of a homogeneous ideal i is the
+         least integer s such that, for all d>=s, the degree d part of the
+         ideals i and isat=sat(i,maxideal(1))[1] coincide.
+"
+{
+//--------------------------- initialisation ---------------------------------
+  int e,ii,jj,h,d,time,lastv,nl,ret;
+  intmat ran;
+  def r0 = basering;
+  int n = nvars(r0)-1;
+  string s = "ring r1 = ",charstr(r0),",x(0..n),dp;";
+  execute(s);
+  ideal i,sbi,I,K,chcoord,m,L;
+  poly P;
+  map phi;
+  i = fetch(r0,i);
+  time=rtimer;
+  system("--ticks-per-sec",100);
+  sbi=std(i);
+//----- Check ideal homogeneous
+  if ( homog(sbi) == 0 )
+  {
+    dbprint(2,"The ideal is not homogeneous, and time for this test is: " + string(rtimer-time) + "/100sec.");
+    return ();
+  }
+  I=simplify(lead(sbi),1);
+  attrib(I,"isSB",1);
+  K=select(I,n+1);
+  if (size(K) == 0)
+  {
+    dbprint(2,"sat(i)=0 and the time of this computation: " + string(rtimer-time) + "/100sec.");
+    return();
+  }
+  if (TestLastVarIsInGenericPos(I) == 1 )
+  {
+    dbprint(2,"sat(i)=" + string(maxdeg1(K)) + " and the time of this computation: " + string(rtimer-time) + "/100sec.");
+    return();
+  }
+  while ( nl < 5 )
+  {
+    nl=nl+1;
+    chcoord=select1(maxideal(1),1..n);
+    ran=random(100,1,n);
+    ran=intmat(ran,1,n+1);
+    ran[1,n+1]=1;
+    m=select1(maxideal(1),1..(n+1));
+    for ( jj = 1; jj<=n+1; jj++ )
+    {
+      P=P+ran[1,jj]*m[jj];
+    }
+    chcoord[n+1]=P;
+    P=0;
+    phi=r1,chcoord;
+    L=std(phi(i));
+    I=simplify(lead(L),1);
+    attrib(I,"isSB",1);
+    K=select(I,n+1);
+    if (size(K) == 0)
+    {
+      dbprint(2,"sat(i)=0 and the time of this computation: " + string(rtimer-time) + "/100sec.");
+      return();
+    }
+    if (TestLastVarIsInGenericPos(I) == 1 )
+    {
+      dbprint(2,"sat(i)=" + string(maxdeg1(K)) + " and the time of this computation: " + string(rtimer-time) + "/100sec.");
+      return();
+    }
+  }
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+proc modsatiety (ideal i)
+"USAGE:   modsatiety(i); i ideal,
+RETURN:  an integer, the satiety of i.
+         (returns -1 if i is not homogeneous)
+ASSUME:  i is a homogeneous ideal of the basering R=K[x(0)..x(n)].
+THEORY:  The satiety, or saturation index, of a homogeneous ideal i is the
+         least integer s such that, for all d>=s, the degree d part of the
+         ideals i and isat=sat(i,maxideal(1))[1] coincide.
+NOTE:    This is a probabilistic procedure, and it computes the initial of the ideal modulo the prime number 2147483647 (the biggest prime less than 2^31).
+"
+{
+//--------------------------- initialisation ---------------------------------
+  "// WARNING: The characteristic of base field must be zero.
+// The procedure is probabilistic and  it computes the
+//initial ideals modulo the prime number 2147483647.";
+  int e,ii,jj,h,d,time,lastv,nl,ret,s1,d1,siz,j,si,u,k,p;
+  intvec v1;
+  intmat ran;
+  def r0 = basering;
+  int n = nvars(r0)-1;
+  string s = "ring r1 = ",charstr(r0),",x(0..n),dp;";
+  execute(s);
+  ideal i,sbi,I,K,chcoord,m,L,sbi1,lsbi1,id1;
+  vector V1;
+  list #,LL,PL,Gb1,VGb1,Gb2,VGb2,Res1,Res2;
+  poly P;
+  map phi;
+  time=rtimer;
+  system("--ticks-per-sec",100);
+  i = fetch(r0,i);
+//----- Check ideal homogeneous
+  if ( homog(i) == 0 )
+  {
+    "// WARNING: The ideal is not homogeneous.";
+    dbprint(2,"Time for this test is: " + string(rtimer-time) + "/100sec.");
+    return ();
+  }
+  option(redSB);
+  p=2147483647;
+  list r2=ringlist(r1);
+  r2[1]=p;
+  def oro=ring(r2);
+  setring oro;
+  ideal sbi=fetch(r1,i);
+  sbi=std(sbi);
+  setring r1;
+  sbi=fetch(oro,sbi);
+  kill oro;
+  I=simplify(lead(sbi),1);
+  attrib(I,"isSB",1);
+  K=select(I,n+1);
+  if (size(K) == 0)
+  {
+    dbprint(2,"msat(i)=0 and the time of this computation: " + string(rtimer-time) + "/100sec.");
+    return();
+  }
+  if (TestLastVarIsInGenericPos(I) == 1 )
+  {
+    dbprint(2,"msat(i)=" + string(maxdeg1(K)) + " and the time of this computation: " + string(rtimer-time) + "/100sec.");
+    return();
+  }
+  while ( nl < 30 )
+  {
+    nl=nl+1;
+    chcoord=select1(maxideal(1),1..n);
+    ran=random(100,1,n);
+    ran=intmat(ran,1,n+1);
+    ran[1,n+1]=1;
+    m=select1(maxideal(1),1..(n+1));
+    for ( jj = 1; jj<=n+1; jj++ )
+    {
+      P=P+ran[1,jj]*m[jj];
+    }
+    chcoord[n+1]=P;
+    P=0;
+    phi=r1,chcoord;
+    sbi=phi(i);
+    list r2=ringlist(r1);
+    r2[1]=p;
+    def oro=ring(r2);
+    setring oro;
+    ideal sbi=fetch(r1,sbi);
+    sbi=std(sbi);
+    setring r1;
+    sbi=fetch(oro,sbi);
+    kill oro;
+    lsbi1=lead(sbi);
+    attrib(lsbi1,"isSB",1);
+    K=select(lsbi1,n+1);
+    if (size(K) == 0)
+    {
+      dbprint(2,"msat(i)=0 and the time of this computation: " + string(rtimer-time) + "/100sec.");
+      return();
+    }
+    if (TestLastVarIsInGenericPos(lsbi1) == 1 )
+    {
+      dbprint(2,"msat(i)=" + string(maxdeg1(K)) + " and the time of this computation: " + string(rtimer-time) + "/100sec.");
+      return();
+    }
+  }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//
+proc regCM (ideal i)
+"USAGE:  regCM (i); i ideal
+RETURN:  the Castelnuovo-Mumford regularity of i.
+         (returns -1 if i is not homogeneous)
+ASSUME:  i is a homogeneous ideal.
+"
+{
+//--------------------------- initialisation ---------------------------------
+  int e,ii,jj,H,h,d,time,nl;
+  def r0 = basering;
+  int n = nvars(r0)-1;
+  string s = "ring r1 = ",charstr(r0),",x(0..n),dp;";
+  execute(s);
+  ideal i,sbi,I,J,K,L;
+  list #;
+  poly P;
+  map phi;
+  i = fetch(r0,i);
+  time=rtimer;
+  system("--ticks-per-sec",100);
+  sbi=std(i);
+//----- Check ideal homogeneous
+  if ( homog(sbi) == 0 )
+  {
+    "// The ideal is not homogeneous!";
+    return (-1);
+  }
+  I=simplify(lead(sbi),1);
+  attrib(I,"isSB",1);
+  d=dim(I);
+  if (char(r1) > 0 and d == 0)
+  {
+    def r2=changechar(0,r1);
+    setring r2;
+    ideal sbi,I,i,K,T;
+    map phi;
+    I = fetch(r1,I);
+    i=I;
+    attrib(I,"isSB",1);
+  }
+  else
+  {
+    def r2=changechar(ringlist(r1),r1);
+    setring r2;
+    ideal sbi,I,i,K,T,ic,Ic;
+    map phi;
+    I = imap(r1,I);
+    Ic=I;
+    attrib(I,"isSB",1);
+    i = imap(r1,i);
+    ic=i;
+  }
+  K=select(I,n+1);
+  if (size(K) == 0)
+  {
+    h=0;
+  }
+  else
+  {
+    if (TestLastVarIsInGenericPos(I) == 1)
+    {
+      h=maxdeg1(K);
+    }
+    else
+    {
+      while ( nl < 30 )
+      {
+        nl=nl+1;
+        phi=r2,randomLast(100);
+        T=phi(i);
+        I=simplify(lead(std(T)),1);
+        attrib(I,"isSB",1);
+        K=select(I,n+1);
+        if (size(K) == 0)
+        {
+          h=0;break;
+        }
+        if (TestLastVarIsInGenericPos(I) == 1 )
+        {
+          h=maxdeg1(K);break;
+        }
+      }
+      i=T;
+    }
+  }
+  for ( ii = n; ii>=n-d+1; ii-- )
+  {
+    i=subst(i,x(ii),0);
+    s = "ring mr = ",charstr(r1),",x(0..ii-1),dp;";
+    execute(s);
+    ideal i,sbi,I,J,K,L,T;
+    poly P;
+    map phi;
+    i=imap(r2,i);
+    I=simplify(lead(std(i)),1);
+    attrib(I,"isSB",1);
+    K=select(I,ii);
+    if (size(K) == 0)
+    {
+      H=0;
+    }
+    else
+    {
+      if (TestLastVarIsInGenericPos(I) == 1)
+      {
+        H=maxdeg1(K);
+      }
+      else
+      {
+        while ( nl < 30 )
+        {
+          nl=nl+1;
+          phi=mr,randomLast(100);
+          T=phi(i);
+          I=simplify(lead(std(T)),1);
+          attrib(I,"isSB",1);
+          K=select(I,ii);
+          if (size(K) == 0)
+          {
+            H=0;break;
+          }
+          if (TestLastVarIsInGenericPos(I) == 1 )
+          {
+            H=maxdeg1(K);break;
+          }
+        }
+        setring r2;
+        i=imap(mr,T);
+        kill mr;
+      }
+    }
+    if (H > h)
+    {
+      h=H;
+    }
+  }
+  if (nl < 30)
+  {
+    dbprint(2,"reg(i)=" + string(h) + " and the time of this computation: " + string(rtimer-time) + " sec./100");
+    return();
+  }
+  else
+  {
+    I=Ic;
+    attrib(I,"isSB",1);
+    i=ic;
+    K=subst(select(I,n+1),x(n),1);
+    K=K*maxideal(maxdeg1(I));
+    if (size(reduce(K,I)) <> 0)
+    {
+      nl=0;
+      while ( nl < 30 )
+      {
+        nl=nl+1;
+        phi=r1,randomLast(100);
+        sbi=phi(i);
+        I=simplify(lead(std(sbi)),1);
+        attrib(I,"isSB",1);
+        K=subst(select(I,n+1),x(n),1);
+        K=K*maxideal(maxdeg1(I));
+        if (size(reduce(K,I)) == 0)
+        {
+          break;
+        }
+      }
+    }
+    h=maxdeg1(simplify(reduce(quotient(I,maxideal(1)),I),2))+1;
+    for ( ii = n; ii> n-d+1; ii-- )
+    {
+      sbi=subst(sbi,x(ii),0);
+      s = "ring mr = ",charstr(r0),",x(0..ii-1),dp;";
+      execute(s);
+      ideal sbi,I,L,K,T;
+      map phi;
+      sbi=imap(r1,sbi);
+      I=simplify(lead(std(sbi)),1);
+      attrib(I,"isSB",1);
+      K=subst(select(I,ii),x(ii-1),1);
+      K=K*maxideal(maxdeg1(I));
+      if (size(reduce(K,I)) <> 0)
+      {
+        nl=0;
+        while ( nl < 30 )
+        {
+          nl=nl+1;
+          L=randomLast(100);
+          phi=mr,L;
+          T=phi(sbi);
+          I=simplify(lead(std(T)),1);
+          attrib(I,"isSB",1);
+          K=subst(select(I,ii),x(ii-1),1);
+          K=K*maxideal(maxdeg1(I));
+          if (size(reduce(K,I)) == 0)
+          {
+            sbi=T;
+            break;
+          }
+        }
+      }
+      H=maxdeg1(simplify(reduce(quotient(I,maxideal(1)),I),2))+1;
+      if (H > h)
+      {
+        h=H;
+      }
+      setring r1;
+      sbi=fetch(mr,sbi);
+      kill mr;
+    }
+    sbi=subst(sbi,x(n-d+1),0);
+    s = "ring mr = ",charstr(r0),",x(0..n-d),dp;";
+    execute(s);
+    ideal sbi,I,L,K,T;
+    map phi;
+    sbi=imap(r1,sbi);
+    I=simplify(lead(std(sbi)),1);
+    attrib(I,"isSB",1);
+    H=maxdeg1(simplify(reduce(quotient(I,maxideal(1)),I),2))+1;
+    if (H > h)
+    {
+      h=H;
+    }
+    dbprint(2,"reg(i)=" + string(h) + " and the time of this computation: " + string(rtimer-time) + " sec./100");
+    return();
+  }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//
+proc modregCM(ideal i)
+"USAGE:  modregCM(i); i ideal
+RETURN:  an integer, the Castelnuovo-Mumford regularity of i.
+         (returns -1 if i is not homogeneous)
+ASSUME:  i is a homogeneous ideal and the characteristic of base field is zero..
+NOTE:    This is a probabilistic procedure, and it computes the initial of the ideal modulo the prime number 2147483647 (the biggest prime less than 2^31).
+"
+{
+//--------------------------- initialisation ---------------------------------
+  "// WARNING: The characteristic of base field must be zero.
+// This procedure is probabilistic and  it computes the initial
+//ideals modulo the prime number 2147483647";
+  int e,ii,jj,H,h,d,time,p,nl;
+  def r0 = basering;
+  int n = nvars(r0)-1;
+  string s = "ring r1 = ",charstr(r0),",x(0..n),dp;";
+  execute(s);
+  ideal i,sbi,I,J,K,L,lsbi1,lsbi2;
+  list #;
+  poly P;
+  map phi;
+  i = fetch(r0,i);
+  time=rtimer;
+  system("--ticks-per-sec",100);
+//----- Check ideal homogeneous
+  if ( homog(i) == 0 )
+  {
+    "// The ideal is not homogeneous!";
+    return (-1);
+  }
+  option(redSB);
+  p=2147483647;
+  #=ringlist(r1);
+  #[1]=p;
+  def oro=ring(#);
+  setring oro;
+  ideal sbi,lsbi;
+  sbi=fetch(r1,i);
+  lsbi=lead(std(sbi));
+  setring r1;
+  lsbi1=fetch(oro,lsbi);
+  lsbi1=simplify(lsbi1,1);
+  attrib(lsbi1,"isSB",1);
+  kill oro;
+  I=lsbi1;
+  d=dim(I);
+  K=select(I,n+1);
+  if (size(K) == 0)
+  {
+    h=0;
+  }
+  else
+  {
+    if (TestLastVarIsInGenericPos(I) == 1)
+    {
+      h=maxdeg1(K);
+    }
+    else
+    {
+      while ( nl < 30 )
+      {
+        nl=nl+1;
+        phi=r1,randomLast(100);
+        sbi=phi(i);
+        #=ringlist(r1);
+        #[1]=p;
+        def oro=ring(#);
+        setring oro;
+        ideal sbi,lsbi;
+        sbi=fetch(r1,sbi);
+        lsbi=lead(std(sbi));
+        setring r1;
+        lsbi1=fetch(oro,lsbi);
+        lsbi1=simplify(lsbi1,1);
+        attrib(lsbi1,"isSB",1);
+        kill oro;
+        I=lsbi1;
+        K=select(I,n+1);
+        if (size(K) == 0)
+        {
+          h=0;break;
+        }
+        if (TestLastVarIsInGenericPos(I) == 1 )
+        {
+          h=maxdeg1(K);break;
+        }
+      }
+      i=sbi;
+    }
+  }
+  for ( ii = n; ii>=n-d+1; ii-- )
+  {
+    i=subst(i,x(ii),0);
+    s = "ring mr = ","0",",x(0..ii-1),dp;";
+    execute(s);
+    ideal i,sbi,I,J,K,L,lsbi1;
+    poly P;
+    list #;
+    map phi;
+    i=imap(r1,i);
+    #=ringlist(mr);
+    #[1]=p;
+    def oro=ring(#);
+    setring oro;
+    ideal sbi,lsbi;
+    sbi=fetch(mr,i);
+    lsbi=lead(std(sbi));
+    setring mr;
+    lsbi1=fetch(oro,lsbi);
+    lsbi1=simplify(lsbi1,1);
+    attrib(lsbi1,"isSB",1);
+    kill oro;
+    I=lsbi1;
+    K=select(I,ii);
+    if (size(K) == 0)
+    {
+      H=0;
+    }
+    else
+    {
+      if (TestLastVarIsInGenericPos(I) == 1)
+      {
+        H=maxdeg1(K);
+      }
+      else
+      {
+        nl=0;
+        while ( nl < 30 )
+        {
+          nl=nl+1;
+          phi=mr,randomLast(100);
+          sbi=phi(i);
+          #=ringlist(mr);
+          #[1]=p;
+          def oro=ring(#);
+          setring oro;
+          ideal sbi,lsbi;
+          sbi=fetch(mr,sbi);
+          lsbi=lead(std(sbi));
+          setring mr;
+          lsbi1=fetch(oro,lsbi);
+          lsbi1=simplify(lsbi1,1);
+          kill oro;
+          I=lsbi1;
+          attrib(I,"isSB",1);
+          K=select(I,ii);
+          if (size(K) == 0)
+          {
+            H=0;break;
+          }
+          if (TestLastVarIsInGenericPos(I) == 1 )
+          {
+            H=maxdeg1(K);break;
+          }
+        }
+        setring r1;
+        i=imap(mr,sbi);
+        kill mr;
+      }
+    }
+    if (H > h)
+    {
+      h=H;
+    }
+  }
+  dbprint(2,"mreg(i)=" + string(h) + " and the time of this computation: " + string(rtimer-time) + "sec./100");
+  return();
+}
+/*
+//////////////////////////////////////////////////////////////
+example
+{ "EXAMPLE:"; echo = 2;
+ring r=0,(X,Y,a,b),dp;
+poly f=X^8+a*Y^4-Y;
+poly g=Y^8+b*X^4-X;
+poly h=diff(f,X)*diff(g,Y)-diff(f,Y)*diff(g,X);
+ideal i=f,g,h;
+}
+example
+{ "EXAMPLE:"; echo = 2;
+ring r=0,(x,y,z,a,b),dp;
+ideal i=2*y^2*(y^2+x^2)+(b^2-3*a^2)*y^2-2*b*y^2*(x+y)+2*a^2*b*(y+x)-a^2*x^2+a^2*(a^2-b^2),4*y^3+4*y*(y^2+x^2)-2*b*y^2-4*b*y*(y+x)+2*(b^2-3*a^2)*y+2*a^2*b,4*x*y^2-2*b*y^2-2*a^2*x+2*a^2*b;
+}
+example
+{ "EXAMPLE:"; echo = 2;
+ring r=0,(t,a,b,c,d),dp;
+ideal i=b4-a3d, ab3-a3c, bc4-ac3d-bcd3+ad4, c6-bc3d2-c3d3+bd5, ac5-b2c3d-ac2d3+b2d4, a2c4-a3d3+b3d3-a2cd3, b3c3-a3d3, ab2c3-a3cd2+b3cd2-ab2d3, a2bc3-a3c2d+b3c2d-a2bd3, a3c3-a3bd2, a4c2-a3b2d;
+}
+example
+{ "EXAMPLE:"; echo = 2;
+ring r=0,(a,b,c,d,e),dp;
+ideal i=6*b4*c3+21*b4*c2*d+15b4cd2+9b4d3-8b2c2e-28b2cde+36b2d2e-144b2c-648b2d-120, 9b4c4+30b4c3d+39b4c2d2+18b4cd3-24b2c3e-16b2c2de+16b2cd2e+24b2d3e-432b2c2-720b2cd-432b2d2+16c2e2-32cde2+16d2e2+576ce-576de-240c+5184,-15b2c3e+15b2c2de-81b2c2+216b2cd-162b2d2+40c2e2-80cde2+40d2e2+1008ce-1008de+5184, -4b2c2+4b2cd-3b2d2+22ce-22de+261;
+}
+example
+{ "EXAMPLE:"; echo = 2;
+ring r=0,(c,b,d,p,q),dp;
+ideal i=2*(b-1)^2+2*(q-p*q+p^2)+c^2*(q-1)^2-2*b*q+2*c*d*(1-q)*(q-p)+2*b*p*q*d*(d-c)+b^2*d^2*(1-2*p)+2*b*d^2*(p-q)+2*b*d*c*(p-1)+2*b*p*q*(c+1)+(b^2-2*b)*p^2*d^2+2*b^2*p^2+4*b*(1-b)*p+d^2*(p-q)^2,d*(2*p+1)*(q-p)+c*(p+2)*(1-q)+b*(b-2)*d+b*(1-2*b)*p*d+b*c*(q+p-p*q-1)+b*(b+1)*p^2*d, -b^2*(p-1)^2+2*p*(p-q)-2*(q-1),b^2+4*(p-q*q)+3*c^2*(q-1)*(q-1)-3*d^2*(p-q)^2+3*b^2*d^2*(p-1)^2+b^2*p*(p-2)+6*b*d*c*(p+q+q*p-1);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+ring r=0,(a,b,c,d,e,f),dp;
+ideal i=2adef+3be2f-cef2,4ad2f+5bdef+cdf2,2abdf+3b2ef-bcf2,4a2df+5abef+acf2,4ad2e+3bde2+7cdef, 2acde+3bce2-c2ef, 4abde+3b2e2-4acdf+2bcef-c2f2, 4a2de+3abe2+7acef, 4acd2+5bcde+c2df, 4abd2+3b2de+7bcdf, 16a2d2-9b2e2+32acdf-18bcef+7c2f2, 2abcd+3b2ce-bc2f, 4a2cd+5abce+ac2f, 4a2bd+3ab2e+7abcf, abc2f-cdef2, ab2cf-bdef2, 2a2bcf+3be2f2-cef3, ab3f-3bdf3, 2a2b2f-4adf3+3bef3-cf4, a3bf+4aef3, 3ac3e-cde3, 3b2c2e-bc3f+2cd2ef, abc2e-cde2f, 6a2c2e-4ade3-3be4+ce3f, 3b3ce-b2c2f+2bd2ef, 2a2bce+3be3f-ce2f2, 3 [...]
+}
+example
+{ "EXAMPLE:"; echo = 2;
+ring r=0,(x,y,z,t,u,v,w),dp;
+ideal i=2tw+2wy-wz,2uw2-10vw2+20w3-7tu+35tv-70tw, 6tw2+2w2y-2w2z-21t2-7ty+7tz, 2v3-4uvw-5v2w+6uw2+7vw2-15w3-42vy, 6tw+9wy+2vz-3wz-21x, 9uw3-45vw3+135w4+14tv2-70tuw+196tvw-602tw2-14v2z+28uwz+14vwz-28w2z+147ux-735vx+2205wx-294ty+98tz+294yz-98z2, 36tw3+6w3y-9w3z-168t2w-14v2x+28uwx+14vwx-28w2x-28twy+42twz+588tx+392xy-245xz, 2uvw-6v2w-uw2+13vw2-5w3-28tw+14wy, u2w-3uvw+5uw2-28tw+14wy, tuw+tvw-11tw2-2vwy+8w2y+uwz-3vwz+5w2z-21wx, 5tuw-17tvw+33tw2-7uwy+22vwy-39w2y-2uwz+6vwz-10w2z+63wx, 20t2w-12uw [...]
+}
+example
+{ "EXAMPLE:"; echo = 2;
+ring r=0,(a,b,c,d,x,w,u,v),dp;
+ideal i=a+b+c+d,u+v+w+x, 3ab+3ac+3bc+3ad+3bd+3cd+2,bu+cu+du+av+cv+dv+aw+bw+dw+ax+bx+cx,bcu+bdu+cdu+acv+adv+cdv+abw+adw+bdw+abx+acx+bcx,abc+abd+acd+bcd,bcdu+acdv+abdw+abcx;
+}
+example
+{ "EXAMPLE:"; echo = 2;
+ring r=0,(b,x,y,z,s,t,u,v,w),dp;
+ideal i=su+bv, tu+bw,tv+sw,sx+by,tx+bz,ty+sz,vx+uy,wx+uz,wy+vz;
+}
+example
+{ "EXAMPLE:"; echo = 2;
+ring r=0,(t,a,b,c,d,e,f,g,h),dp;
+ideal i=a+c+d-e-h,2df+2cg+2eh-2h2-h-1,3df2+3cg2-3eh2+3h3+3h2-e+4h, 6bdg-6eh2+6h3-3eh+6h2-e+4h, 4df3+4cg3+4eh3-4h4-6h3+4eh-10h2-h-1, 8bdfg+8eh3-8h4+4eh2-12h3+4eh-14h2-3h-1, 12bdg2+12eh3-12h4+12eh2-18h3+8eh-14h2-h-1, -24eh3+24h4-24eh2+36h3-8eh+26h2+7h+1;
+}
+example
+{ "EXAMPLE:"; echo = 2;
+ring r=0,(a,b,c,d,e,f,g,h,k,l),dp;
+ideal i=f2h-1,ek2-1,g2l-1, 2ef2g2hk2+f2g2h2k2+2ef2g2k2l+2f2g2hk2l+f2g2k2l2+ck2, 2e2fg2hk2+2efg2h2k2+2e2fg2k2l+4efg2hk2l+2fg2h2k2l+2efg2k2l2+2fg2hk2l2+2bfh, 2e2f2ghk2+2ef2gh2k2+2e2f2gk2l+4ef2ghk2l+2f2gh2k2l+2ef2gk2l2+2f2ghk2l2+2dgl, e2f2g2k2+2ef2g2hk2+2ef2g2k2l+2f2g2hk2l+f2g2k2l2+bf2, 2e2f2g2hk+2ef2g2h2k+2e2f2g2kl+4ef2g2hkl+2f2g2h2kl+2ef2g2kl2+2f2g2hkl2+2cek, e2f2g2k2+2ef2g2hk2+f2g2h2k2+2ef2g2k2l+2f2g2hk2l+dg2, -e2f2g2hk2-ef2g2h2k2-e2f2g2k2l-2ef2g2hk2l-f2g2h2k2l-ef2g2k2l2-f2g2hk2l2+a2;
+}
+example
+{ "EXAMPLE:"; echo = 2;
+ring r=0,(b,c,d,e,f,g,h,j,k,l),dp;
+ideal i=-k9+9k8l-36k7l2+84k6l3-126k5l4+126k4l5-84k3l6+36k2l7-9kl8+l9, -bk8+8bk7l+k8l-28bk6l2-8k7l2+56bk5l3+28k6l3-70bk4l4-56k5l4+56bk3l5+70k4l5-28bk2l6-56k3l6+8bkl7+28k2l7-bl8-8kl8+l9, ck7-7ck6l-k7l+21ck5l2+7k6l2-35ck4l3-21k5l3+35ck3l4+35k4l4-21ck2l5-35k3l5+7ckl6+21k2l6-cl7-7kl7+l8, -dk6+6dk5l+k6l-15dk4l2-6k5l2+20dk3l3+15k4l3-15dk2l4-20k3l4+6dkl5+15k2l5-dl6-6kl6+l7, ek5-5ek4l-k5l+10ek3l2+5k4l2-10ek2l3-10k3l3+5ekl4+10k2l4-el5-5kl5+l6, -fk4+4fk3l+k4l-6fk2l2-4k3l2+4fkl3+6k2l3-fl4-4kl4+l5, g [...]
+}
+example
+{ "EXAMPLE:"; echo = 2;
+ring r=0,x(0..10),dp;
+ideal i=x(1)*x(0),x(1)*x(2),x(2)*x(3),x(3)*x(4),x(4)*x(5),x(5)*x(6),x(6)*x(7),x(7)*x(8),x(8)*x(9),x(9)*x(10),x(10)*x(0);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+ring r=0,(a,b,c,d,e,f,g,h,j,k,l,m,n,o,p,q,s),dp;
+ideal i=ag,gj+am+np+q,bl,nq,bg+bk+al+lo+lp+b+c,ag+ak+jl+bm+bn+go+ko+gp+kp+lq+a+d+f+h+o+p,gj+jk+am+an+mo+no+mp+np+gq+kq+e+j+q+s-1,jm+jn+mq+nq,jn+mq+2nq,gj+am+2an+no+np+2gq+kq+q+s,2ag+ak+bn+go+gp+lq+a+d,bg+al, an+gq, 2jm+jn+mq, gj+jk+am+mo+2mp+np+e+2j+q, jl+bm+gp+kp+a+f+o+2p,lp+b,jn+mq,gp+a;
+}
+example
+{ "EXAMPLE:"; echo = 2;
+ring r=0,(a,b,c,d,e,f,g,h,v,w,k,l,m,n,o,p,q,s,t,u),dp;
+ideal i=af+bg+ch+dv+ew-1/2, a2f+b2g+c2h+d2v+e2w-1/3,tdw+agk+ahl+bhm+avn+bvo+cvp+awq+bwu+cws-1/6, a3f+b3g+c3h+d3v+e3w-1/4, tdew+abgk+achl+bchm+advn+bdvo+cdvp+aewq+bewu+cews-1/8, td2w+a2gk+a2hl+b2hm+a2vn+b2vo+c2vp+a2wq+b2wu+c2ws-1/12, ahkm+tawn+tbwo+avko+tcwp+avlp+bvmp+awku+awls+bwms-1/24, a4f+b4g+c4h+d4v+e4w-1/5, tde2w+ab2gk+ac2hl+bc2hm+ad2vn+bd2vo+cd2vp+ae2wq+be2wu+ce2ws-1/10, td2ew+a2bgk+a2chl+b2chm+a2dvn+b2dvo+c2dvp+a2ewq+b2ewu+c2ews-1/15,achkm+taewn+tbewo+advko+tcewp+advlp+bdvmp+aewku [...]
+}
+*/
diff --git a/Singular/LIB/normal.lib b/Singular/LIB/normal.lib
new file mode 100644
index 0000000..3264b3d
--- /dev/null
+++ b/Singular/LIB/normal.lib
@@ -0,0 +1,7428 @@
+//////////////////////////////////////////////////////////////////////////////
+version="version normal.lib 4.0.1.1 Dec_2014 "; // $Id: e34b871dfe50e25888b74e4f5f251c708dacb060 $
+category="Commutative Algebra";
+info="
+LIBRARY:  normal.lib     Normalization of Affine Rings
+AUTHORS:  G.-M. Greuel,  greuel at mathematik.uni-kl.de,
+@*        S. Laplagne,   slaplagn at dm.uba.ar,
+@*        G. Pfister,    pfister at mathematik.uni-kl.de
+
+
+PROCEDURES:
+ normal(I,[...]);    normalization of an affine ring
+ normalP(I,[...]);   normalization of an affine ring in positive characteristic
+ normalC(I,[...]);   normalization of an affine ring through a chain of rings
+ HomJJ(L);           presentation of End_R(J) as affine ring, J an ideal
+ genus(I);           computes the geometric genus of a projective curve
+ primeClosure(L);    integral closure of R/p, p a prime ideal
+ closureFrac(L);     writes a poly in integral closure as element of Quot(R/p)
+ iMult(L);           intersection multiplicity of the ideals of the list L
+
+ deltaLoc(f,S);      sum of delta invariants at conjugated singular points
+ locAtZero(I);       checks whether the zero set of I is located at 0
+ norTest(I,nor);     checks the output of normal, normalP, normalC
+ getSmallest(J);     computes the polynomial of smallest degree of J
+ getOneVar(J, vari); computes a polynomial of J in the variable vari
+ changeDenominator(U1, c1, c2, I); computes ideal U2 such that 1/c1*U1=1/c2*U2
+
+SEE ALSO: locnormal_lib;modnormal_lib
+";
+
+LIB "general.lib";
+LIB "poly.lib";
+LIB "sing.lib";
+LIB "primdec.lib";
+LIB "elim.lib";
+LIB "presolve.lib";
+LIB "inout.lib";
+LIB "ring.lib";
+LIB "hnoether.lib";
+LIB "reesclos.lib";
+LIB "algebra.lib";
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc normal(ideal id, list #)
+"USAGE:  normal(id [,choose]); id = radical ideal, choose = list of options. @*
+         Optional parameters in list choose (can be entered in any order):@*
+         Decomposition:@*
+         - \"equidim\" -> computes first an equidimensional decomposition of the
+         input ideal, and then the normalization of each component (default).@*
+         - \"prim\" -> computes first the minimal associated primes of the input
+         ideal, and then the normalization of each prime. (When the input ideal
+         is not prime and the minimal associated primes are easy to compute,
+         this method is usually faster than \"equidim\".)@*
+         - \"noDeco\" -> no preliminary decomposition is done. If the ideal is
+         not equidimensional radical, output might be wrong.@*
+         - \"isPrim\" -> assumes that the ideal is prime. If this assumption
+         does not hold, the output might be wrong.@*
+         - \"noFac\" -> factorization is avoided in the computation of the
+         minimal associated primes;
+         Other:@*
+         - \"useRing\" -> uses the original ring ordering.@*
+         If this option is set and if the ring ordering is not global, normal
+         will change to a global ordering only for computing radicals and prime
+         or equidimensional decompositions.@*
+         If this option is not set, normal changes to dp ordering and performs
+         all computations with respect to this ordering.@*
+         - \"withDelta\" (or \"wd\") -> returns also the delta invariants.@*
+         If the optional parameter choose is not given or empty, only
+         \"equidim\" but no other option is used.@*
+         - list(\"inputJ\", ideal inputJ) -> takes as initial test ideal the
+         ideal inputJ. This option is only for use in other procedures. Using
+         this option, the result might not be the normalization.@*
+         (Option only valid for global algorithm.)@*
+         - list(\"inputC\", ideal inputC) -> takes as initial conductor the
+         ideal inputC. This option is only for use in other procedures. Using
+         this option, the result might not be the normalization.@*
+         (Option only valid for global algorithm.)@*
+         Options used for computing integral basis (over rings of two
+         variables):@*
+         - \"var1\" -> uses a polynomial in the first variable as
+         universal denominator.@*
+         - \"var2\" -> uses a polynomial in the second variable as universal
+         denominator.@*
+         If the optional parameter choose is not given or empty, only
+         \"equidim\" but no other option is used.@*
+ASSUME:  The ideal must be radical, for non-radical ideals the output may
+         be wrong (id=radical(id); makes id radical). However, when using the
+         \"prim\" option the minimal associated primes of id are computed first
+         and hence normal computes the normalization of the radical of id.@*
+NOTE:    \"isPrim\" should only be used if id is known to be prime.
+RETURN:  a list, say nor, of size 2 (resp. 3 with option \"withDelta\").
+ at format  Let R denote the basering and id the input ideal.
+         * nor[1] is a list of r rings, where r is the number of associated
+         primes P_i with option \"prim\" (resp. >= no of equidimenensional
+         components P_i with option \"equidim\").@*
+         Each ring Ri := nor[1][i], i=1..r, contains two ideals with given
+         names @code{norid} and @code{normap} such that: @*
+         - Ri/norid is the normalization of the i-th component, i.e. the
+          integral closure of R/P_i in its field of fractions (as affine ring);
+         - @code{normap} gives the normalization map from R/id to
+           Ri/norid for each i.@*
+         - the direct sum of the rings Ri/norid, i=1,..r, is the normalization
+           of R/id as affine algebra; @*
+         * nor[2] is a list of size r with information on the normalization of
+         the i-th component as module over the basering R:@*
+         nor[2][i] is an ideal, say U, in R such that the integral closure
+         of basering/P_i is generated as module over R by 1/c * U, with c
+         the last element U[size(U)] of U.@*
+         * nor[3] (if option \"withDelta\" is set) is a list of an intvec
+         of size r, the delta invariants of the r components, and an integer,
+         the total delta invariant of basering/id (-1 means infinite, and 0
+         that R/P_i resp. R/id is normal).
+ at end format
+THEORY:  We use here a general algorithm described in [G.-M.Greuel, S.Laplagne,
+         F.Seelisch: Normalization of Rings (2009)].@*
+         The procedure computes the R-module structure, the algebra structure
+         and the delta invariant of the normalization of R/id:@*
+         The normalization of R/id is the integral closure of R/id in its total
+         ring of fractions. It is a finitely generated R-module and nor[2]
+         computes R-module generators of it. More precisely: If U:=nor[2][i]
+         and c:=U[size(U)], then c is a non-zero divisor and U/c is an R-module
+         in the total ring of fractions, the integral closure of R/P_i. Since
+         U[size(U)]/c is equal to 1, R/P_i resp. R/id is contained in the
+         integral closure.@*
+         The normalization is also an affine algebra over the ground field
+         and nor[1] presents it as such. For geometric considerations nor[1] is
+         relevant since the variety of the ideal norid in Ri is the
+         normalization of the variety of the ideal P_i in R.@*
+         The delta invariant of a reduced ring A is dim_K(normalization(A)/A).
+         For A=K[x1,...,xn]/id we call this number also the delta invariant of
+         id. nor[3] returns the delta invariants of the components P_i and of
+         id.
+NOTE:    To use the i-th ring type e.g.: @code{def R=nor[1][i]; setring R;}.
+@*       Increasing/decreasing printlevel displays more/less comments
+         (default: printlevel=0).
+@*       Implementation works also for local rings.
+@*       Not implemented for quotient rings.
+@*       If the input ideal id is weighted homogeneous a weighted ordering may
+         be used together with the useRing-option (qhweight(id); computes
+         weights).
+KEYWORDS: normalization; integral closure; delta invariant.
+SEE ALSO: normalC, normalP.
+EXAMPLE: example normal; shows an example
+"
+{
+  ASSUME(0, not isQuotientRing(basering) );
+
+  intvec opt = option(get);     // Save current options
+
+  int i,j;
+  int decomp;   // Preliminary decomposition:
+                // 0 -> no decomposition (id is assumed to be prime)
+                // 1 -> no decomposition
+                //      (id is assumed to be equidimensional radical)
+                // 2 -> equidimensional decomposition
+                // 3 -> minimal associated primes
+  int noFac, useRing, withDelta;
+  int dbg = printlevel - voice + 2;
+  int nvar = nvars(basering);
+  int chara  = char(basering);
+  int denomOption;   // Method for choosing the conductor
+
+  ideal inputJ = 0;      // Test ideal given in the input (if any).
+  ideal inputC = 0;      // Conductor ideal given in the input (if any).
+
+  list result, resultNew;
+  list keepresult;
+  list ringStruc;
+  ideal U;
+  poly c;
+  int sp;            // Number of components.
+
+  // Default methods:
+  noFac = 0;         // Use facSTD when computing minimal associated primes
+  decomp = 2;        // Equidimensional decomposition
+  useRing = 0;       // Change first to dp ordering, and perform all
+                     // computations there.
+  withDelta = 0;     // Do not compute the delta invariant.
+  denomOption = 0;   // The default universal denominator is the smallest
+                     // degree polynomial.
+
+//--------------------------- define the method ---------------------------
+  for ( i=1; i <= size(#); i++ )
+  {
+    if ( typeof(#[i]) == "string" )
+    {
+//--------------------------- choosen methods -----------------------
+      if ( (#[i]=="isprim") or (#[i]=="isPrim") )
+      {decomp = 0;}
+
+      if ( (#[i]=="nodeco") or (#[i]=="noDeco") )
+      {decomp = 1;}
+
+      if (#[i]=="prim")
+      {decomp = 3;}
+
+      if (#[i]=="equidim")
+      {decomp = 2;}
+
+      if ( (#[i]=="nofac") or (#[i]=="noFac") )
+      {noFac=1;}
+
+      if ( ((#[i]=="useRing") or (#[i]=="usering")) and (ordstr(basering) != "dp("+string(nvars(basering))+"),C"))
+      {useRing = 1;}
+
+      if ( (#[i]=="withDelta") or (#[i]=="wd") or (#[i]=="withdelta"))
+      {
+        if((decomp == 0) or (decomp == 3))
+        {
+          withDelta = 1;
+        }
+        else
+        {
+          decomp = 3;
+          withDelta = 1;
+          //Note: the delta invariants cannot be computed with an equidimensional
+          //decomposition, hence we compute first the minimal primes
+        }
+      }
+      if (#[i]=="var1")
+      {denomOption = 1;}
+      if (#[i]=="var2")
+      {denomOption = 2;}
+    }
+    if(typeof(#[i]) == "list"){
+      if(size(#[i]) == 2){
+        if (#[i][1]=="inputJ"){
+          if(typeof(#[i][2]) == "ideal"){
+            inputJ = #[i][2];
+          }
+        }
+      }
+      if (#[i][1]=="inputC"){
+        if(size(#[i]) == 2){
+          if(typeof(#[i][2]) == "ideal"){
+            inputC = #[i][2];
+          }
+        }
+      }
+    }
+  }
+  kill #;
+
+//------------------------ change ring if required ------------------------
+// If the ordering is not global, we change to dp ordering for computing the
+// min ass primes.
+// If the ordering is global, but not dp, and useRing = 0, we also change to
+// dp ordering.
+
+  int isGlobal = attrib(basering,"global");// Checks if the original ring has
+                                          // global ordering.
+
+  def origR = basering;   // origR is the original ring
+                          // R is the ring where computations will be done
+
+  if((useRing  == 1) and (isGlobal == 1))
+  {
+    def globR = basering;
+  }
+  else
+  {
+    // We change to dp ordering.
+    list rl = ringlist(origR);
+    list origOrd = rl[3];
+    list newOrd = list("dp", intvec(1:nvars(origR))), list("C", 0);
+    rl[3] = newOrd;
+    def globR = ring(rl);
+    setring globR;
+    ideal id = fetch(origR, id);
+  }
+
+//------------------------ trivial checkings ------------------------
+  id = groebner(id);
+  if((size(id) == 0) or (id[1] == 1))
+  {
+    // The original ring R/I was normal. Nothing to do.
+    // We define anyway a new ring, equal to R, to be able to return it.
+    setring origR;
+    list lR = ringlist(origR);
+    def ROut = ring(lR);
+    setring ROut;
+    ideal norid = fetch(origR, id);
+    ideal normap = maxideal(1);
+    export norid;
+    export normap;
+    setring origR;
+    if(withDelta)
+    {
+      result = list(list(ROut), list(ideal(1)), list(intvec(0), 0));
+    }
+    else
+    {
+      result = list(list(ROut), list(ideal(1)));
+    }
+    sp = 1;      // number of rings in the output
+    option(set, opt);
+    normalOutputText(dbg, withDelta, sp);
+    return(result);
+  }
+//------------------------ preliminary decomposition-----------------------
+  list prim;
+  if(decomp == 2)
+  {
+    dbprint(dbg, "// Computing the equidimensional decomposition...");
+    prim = equidim(id);
+  }
+  if((decomp == 0) or (decomp == 1))
+  {
+    prim = id;
+  }
+  if(decomp == 3)
+  {
+    dbprint(dbg, "// Computing the minimal associated primes...");
+    if( noFac )
+    { prim = minAssGTZ(id,1); }
+    else
+    { prim = minAssGTZ(id); }
+  }
+  sp = size(prim);
+  if(dbg>=1)
+  {
+    prim; "";
+    "// number of components is", sp;
+    "";
+  }
+
+
+//----------------- back to the original ring if required ------------------
+// if ring was not global and useRing is on, we go back to the original ring
+  if((useRing == 1) and (isGlobal != 1))
+  {
+    setring origR;
+    def R = basering;
+    list prim = fetch(globR, prim);
+  }
+  else
+  {
+    def R = basering;
+    ideal inputJ = fetch(origR, inputJ);
+    ideal inputC = fetch(origR, inputC);
+    if(useRing == 0)
+    {
+      ideal U;
+      poly c;
+    }
+  }
+
+// ---------------- normalization of the components-------------------------
+// calls normalM to compute the normalization of each component.
+
+  list norComp;       // The normalization of each component.
+  int delt;
+  int deltI = 0;
+  int totalComps = 0;
+
+  setring origR;
+  def newROrigOrd;
+  list newRListO;
+  setring R;
+  def newR;
+  list newRList;
+
+  for(i=1; i<=size(prim); i++)
+  {
+    if(dbg>=2){pause();}
+    if(dbg>=1)
+    {
+      "// start computation of component",i;
+      "   --------------------------------";
+    }
+    if(groebner(prim[i])[1] != 1)
+    {
+      if(dbg>=2)
+      {
+        "We compute the normalization in the ring"; basering;
+      }
+      printlevel = printlevel + 1;
+      norComp = normalM(prim[i], decomp, withDelta, denomOption, inputJ, inputC);
+      printlevel = printlevel - 1;
+      for(j = 1; j <= size(norComp); j++)
+      {
+        newR = norComp[j][3];
+        if(!defined(savebasering)) { def savebasering;}
+        savebasering=basering;
+        setring newR; // must be in a compatible ring to newR
+                      // as ringlist may produce ring-dep. stuff
+        if(!defined(newRList)) { list newRList;}
+        newRList = ringlist(newR);
+        setring savebasering;
+        U = norComp[j][1];
+        c = norComp[j][2];
+        if(withDelta)
+        {
+          delt = norComp[j][4];
+          if((delt >= 0) and (deltI >= 0))
+          {
+            deltI = deltI + delt;
+          }
+          else
+          {
+            deltI = -1;
+          }
+        }
+        // -- incorporate result for this component to the list of results ---
+        if(useRing == 0)
+        {
+          // We go back to the original ring.
+          setring origR;
+          U = fetch(R, U);
+          c = fetch(R, c);
+          newRListO = imap(newR, newRList);
+          // We change the ordering in the new ring.
+          if(nvars(newR) > nvars(origR))
+          {
+            newRListO[3]=insert(origOrd, newRListO[3][1]);
+          }
+          else
+          {
+            newRListO[3] = origOrd;
+          }
+          newROrigOrd = ring(newRListO);
+          setring newROrigOrd;
+          ideal norid = imap(newR, norid);
+          ideal normap = imap(newR, normap);
+          export norid;
+          export normap;
+          setring origR;
+          totalComps++;
+          result[totalComps] = list(U, c, newROrigOrd);
+          if(withDelta)
+          {
+            result[totalComps] = insert(result[totalComps], delt, 3);
+          }
+          setring R;
+        }
+        else
+        {
+          setring R;
+          totalComps++;
+          result[totalComps] = norComp[j];
+        }
+      }
+    }
+  }
+
+// -------------------------- delta computation ----------------------------
+  if(withDelta == 1)
+  {
+    // Intersection multiplicities of list prim, sp=size(prim).
+    if ( dbg >= 1 )
+    {
+      "// Sum of delta for all components: ", deltI;
+    }
+    if(size(prim) > 1)
+    {
+      dbprint(dbg, "// Computing the sum of the intersection multiplicities of the components...");
+      int mul = iMult(prim);
+      if ( mul < 0 )
+      {
+        deltI = -1;
+      }
+      else
+      {
+        deltI = deltI + mul;
+      }
+      if ( dbg >= 1 )
+      {
+        "// Intersection multiplicity is : ", mul;
+      }
+    }
+  }
+
+// -------------------------- prepare output ------------------------------
+  setring origR;
+
+  list RL;      // List of rings
+  list MG;      // Module generators
+  intvec DV;    // Vector of delta's of each component
+  for(i = 1; i <= size(result); i++)
+  {
+    RL[i] = result[i][3];
+    MG[i] = lineUpLast(result[i][1], result[i][2]);
+    if(withDelta)
+    {
+      DV[i] = result[i][4];
+    }
+  }
+  if(withDelta)
+  {
+    resultNew = list(RL, MG, list(DV, deltI));
+  }
+  else
+  {
+    resultNew = list(RL, MG);
+  }
+  sp = size(RL);              //RL = list of rings
+
+  option(set, opt);
+  normalOutputText(dbg, withDelta, sp);
+  return(resultNew);
+}
+
+example
+{ "EXAMPLE:";
+  printlevel = printlevel+1;
+  echo = 2;
+  ring s = 0,(x,y),dp;
+  ideal i = (x2-y3)*(x2+y2)*x;
+  list nor = normal(i, "withDelta", "prim");
+  nor;
+
+  // 2 branches have delta = 1, and 1 branch has delta = 0
+  // the total delta invariant is 13
+
+  def R2 = nor[1][2];  setring R2;
+  norid; normap;
+
+  echo = 0;
+  printlevel = printlevel-1;
+  pause("   hit return to continue"); echo=2;
+
+  ring r = 2,(x,y,z),dp;
+  ideal i = z3-xy4;
+  list nor = normal(i, "withDelta", "prim");  nor;
+  // the delta invariant is infinite
+  // xy2z/z2 and xy3/z2 generate the integral closure of r/i as r/i-module
+  // in its quotient field Quot(r/i)
+
+  // the normalization as affine algebra over the ground field:
+  def R = nor[1][1]; setring R;
+  norid; normap;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Prints the output text in proc normal.
+//
+static proc normalOutputText(int dbg, int withDelta, int sp)
+// int dbg: printlevel
+// int withDelta: output contains information about the delta invariant
+// int sp: number of output rings.
+{
+  if ( dbg >= 0 )
+  {
+    "";
+    if(!withDelta)
+    {
+      "// 'normal' created a list, say nor, of two elements.";
+    }
+    else
+    {
+      "// 'normal' created a list, say nor, of three elements.";
+    }
+    "// To see the list type";
+    "      nor;";
+    "";
+    "// * nor[1] is a list of", sp, "ring(s).";
+    "// To access the i-th ring nor[1][i], give it a name, say Ri, and type";
+    "     def R1 = nor[1][1]; setring R1; norid; normap;";
+    "// For the other rings type first (if R is the name of your base ring)";
+    "     setring R;";
+    "// and then continue as for R1.";
+    "// Ri/norid is the affine algebra of the normalization of R/P_i where";
+    "// P_i is the i-th component of a decomposition of the input ideal id";
+    "// and normap the normalization map from R to Ri/norid.";
+    "";
+    "// * nor[2] is a list of", sp, "ideal(s). Let ci be the last generator";
+    "// of the ideal nor[2][i]. Then the integral closure of R/P_i is";
+    "// generated as R-submodule of the total ring of fractions by";
+    "// 1/ci * nor[2][i].";
+
+    if(withDelta)
+    { "";
+      "// * nor[3] is a list of an intvec of size", sp, "the delta invariants ";
+      "// of the components, and an integer, the total delta invariant ";
+      "// of R/id (-1 means infinite, and 0 that R/P_i resp. R/id is normal).";
+    }
+  }
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc HomJJ (list Li)
+"USAGE:   HomJJ (Li);  Li = list: ideal SBid, ideal id, ideal J, poly p
+ASSUME:  R    = P/id,  P = basering, a polynomial ring, id an ideal of P,
+@*       SBid = standard basis of id,
+@*       J    = ideal of P containing the polynomial p,
+@*       p    = nonzero divisor of R
+COMPUTE: Endomorphism ring End_R(J)=Hom_R(J,J) with its ring structure as
+         affine ring, together with the map R --> Hom_R(J,J) of affine rings,
+         where R is the quotient ring of P modulo the standard basis SBid.
+RETURN:  a list l of three objects
+ at format
+         l[1] : a polynomial ring, containing two ideals, 'endid' and 'endphi'
+               such that l[1]/endid = Hom_R(J,J) and
+               endphi describes the canonical map R -> Hom_R(J,J)
+         l[2] : an integer which is 1 if phi is an isomorphism, 0 if not
+         l[3] : an integer, = dim_K(Hom_R(J,J)/R) (the contribution to delta)
+                if the dimension is finite, -1 otherwise
+ at end format
+NOTE:    printlevel >=1: display comments (default: printlevel=0)
+EXAMPLE: example HomJJ;  shows an example
+"
+{
+   ASSUME(0, not isQuotientRing(basering) );
+
+//---------- initialisation ---------------------------------------------------
+   int isIso,isPr,isHy,isCo,isRe,isEq,oSAZ,ii,jj,q,y;
+   intvec rw,rw1;
+   list L;
+   y = printlevel-voice+2;  // y=printlevel (default: y=0)
+   def P = basering;
+   ideal SBid, id, J = Li[1], Li[2], Li[3];
+   poly p = Li[4];
+   int noRed = 0;
+   if(size(Li) > 4)
+   {
+     if(Li[5] == 1) { noRed = 1; }
+   }
+
+   attrib(SBid,"isSB",1);
+   int homo = homog(Li[2]);               //is 1 if id is homogeneous, 0 if not
+
+//---- set attributes for special cases where algorithm can be simplified -----
+   if( homo==1 )
+   {
+      rw = ringweights(P);
+   }
+   if( typeof(attrib(id,"isPrim"))=="int" )
+   {
+      if(attrib(id,"isPrim")==1)  { isPr=1; }
+   }
+   if( typeof(attrib(id,"onlySingularAtZero"))=="int" )
+   {
+      if(attrib(id,"onlySingularAtZero")==1){oSAZ=1; }
+   }
+   if( typeof(attrib(id,"isIsolatedSingularity"))=="int" )
+   {
+      if(attrib(id,"isIsolatedSingularity")==1) { isIso=1; }
+   }
+   if( typeof(attrib(id,"isCohenMacaulay"))=="int" )
+   {
+      if(attrib(id,"isCohenMacaulay")==1) { isCo=1; }
+   }
+   if( typeof(attrib(id,"isRegInCodim2"))=="int" )
+   {
+      if(attrib(id,"isRegInCodim2")==1) { isRe=1; }
+   }
+   if( typeof(attrib(id,"isEquidimensional"))=="int" )
+   {
+      if(attrib(id,"isEquidimensional")==1) { isEq=1; }
+   }
+//-------------------------- go to quotient ring ------------------------------
+   qring R  = SBid;
+   ideal id = fetch(P,id);
+   ideal J  = fetch(P,J);
+   poly p   = fetch(P,p);
+   ideal f,rf,f2;
+   module syzf;
+//---------- computation of p*Hom(J,J) as R-ideal -----------------------------
+   if ( y>=1 )
+   {
+     "// compute p*Hom(J,J) = p*J:J";
+     "//   the ideal J:";J;
+   }
+   f  = quotient(p*J,J);
+
+   //### (neu GMG 4.10.08) divide by the greatest common divisor:
+   poly gg = gcd( f[1],p );
+   for(ii=2; ii <=ncols(f); ii++)
+   {
+      gg=gcd(gg,f[ii]);
+   }
+   for(ii=1; ii<=ncols(f); ii++)
+   {
+      f[ii]=f[ii]/gg;
+   }
+   p = p/gg;
+
+   if ( y>=1 )
+   {
+      "//   the non-zerodivisor p:"; p;
+      "//   the module p*Hom(J,J) = p*J:J :"; f;
+      "";
+   }
+   f2 = std(p);
+
+//---------- Test: Hom(J,J) == R ?, if yes, go home ---------------------------
+
+   //rf = interred(reduce(f,f2));
+   //### interred hier weggelassen, unten zugefuegt
+   rf = reduce(f,f2);       //represents p*Hom(J,J)/p*R = Hom(J,J)/R
+   if ( size(rf) == 0 )
+   {
+      if ( homog(f) && find(ordstr(basering),"s")==0 )
+      {
+         ring newR1 = char(P),(X(1..nvars(P))),(a(rw),dp);
+      }
+      else
+      {
+         ring newR1 = char(P),(X(1..nvars(P))),dp;
+      }
+      ideal endphi = maxideal(1);
+      ideal endid = fetch(P,id);
+      endid = simplify(endid,2);
+      L = substpart(endid,endphi,homo,rw);   //## hier substpart
+      def lastRing = L[1];
+      setring lastRing;
+
+      attrib(endid,"onlySingularAtZero",oSAZ);
+      attrib(endid,"isCohenMacaulay",isCo);
+      attrib(endid,"isPrim",isPr);
+      attrib(endid,"isIsolatedSingularity",isIso);
+      attrib(endid,"isRegInCodim2",isRe);
+      attrib(endid,"isEqudimensional",isEq);
+      attrib(endid,"isHypersurface",0);
+      attrib(endid,"isCompleteIntersection",0);
+      attrib(endid,"isRadical",0);
+      L=lastRing;
+      L = insert(L,1,1);
+      dbprint(y,"// case R = Hom(J,J)");
+      if(y>=1)
+      {
+         "//   R=Hom(J,J)";
+         lastRing;
+         "//   the new ideal";
+         endid;
+         "   ";
+         "//   the old ring";
+         P;
+         "//   the old ideal";
+         setring P;
+         id;
+         "   ";
+         setring lastRing;
+         "//   the map to the new ring";
+         endphi;
+         "   ";
+         pause();
+         "";
+      }
+      setring P;
+      L[3]=0;
+      return(L);
+   }
+   if(y>=1)
+   {
+      "// R is not equal to Hom(J,J), we have to try again";
+      pause();
+      "";
+   }
+//---------- Hom(J,J) != R: create new ring and map from old ring -------------
+// the ring newR1/SBid+syzf will be isomorphic to Hom(J,J) as R-module
+// f2=p (i.e. ideal generated by p)
+
+   //f = mstd(f)[2];              //### geaendert GMG 04.10.08
+   //ideal ann = quotient(f2,f);  //### f durch rf ersetzt
+   rf = mstd(rf)[2];              //rf = NF(f,p), hence <p,rf> = <p,f>
+   ideal ann = quotient(f2,rf);   //p:f = p:rf
+
+   //------------- compute the contribution to delta ----------
+   //delt=dim_K(Hom(JJ)/R (or -1 if infinite)
+
+   int delt=vdim(std(modulo(f,ideal(p))));
+
+   f = p,rf;          // generates pJ:J mod(p), i.e. p*Hom(J,J)/p*R as R-module
+   q = size(f);
+   syzf = syz(f);
+
+   if ( homo==1 )
+   {
+      rw1 = rw,0;
+      for ( ii=2; ii<=q; ii++ )
+      {
+         rw  = rw, deg(f[ii])-deg(f[1]);
+         rw1 = rw1, deg(f[ii])-deg(f[1]);
+      }
+      ring newR1 = char(R),(X(1..nvars(R)),T(1..q)),(a(rw1),dp);
+   }
+   else
+   {
+      ring newR1 = char(R),(X(1..nvars(R)),T(1..q)),dp;
+   }
+
+   //map psi1 = P,maxideal(1);          //### psi1 durch fetch ersetzt
+   //ideal SBid = psi1(SBid);
+   ideal SBid = fetch(P,SBid);
+   attrib(SBid,"isSB",1);
+
+   qring newR = std(SBid);
+
+   //map psi = R,ideal(X(1..nvars(R)));  //### psi durch fetch ersetzt
+   //ideal id = psi(id);
+   //ideal f = psi(f);
+   //module syzf = psi(syzf);
+   ideal id = fetch(R,id);
+   ideal f = fetch(R,f);
+   module syzf = fetch(R,syzf);
+   ideal pf,Lin,Quad,Q;
+   matrix T,A;
+   list L1;
+
+//---------- computation of Hom(J,J) as affine ring ---------------------------
+// determine kernel of: R[T1,...,Tq] -> J:J >-> R[1/p]=R[t]/(t*p-1),
+// Ti -> fi/p -> t*fi (p=f1=f[1]), to get ring structure. This is of course
+// the same as the kernel of R[T1,...,Tq] -> pJ:J >-> R, Ti -> fi.
+// It is a fact, that the kernel is generated by the linear and the quadratic
+// relations
+// f=p,rf, rf=reduce(f,p), generates pJ:J mod(p),
+// i.e. p*Hom(J,J)/p*R as R-module
+
+   pf = f[1]*f;
+   T = matrix(ideal(T(1..q)),1,q);
+   Lin = ideal(T*syzf);
+   if(y>=1)
+   {
+      "// the ring structure of Hom(J,J) as R-algebra";
+      "//   the linear relations:";
+      Lin;
+   }
+
+   poly ff;
+   for (ii=2; ii<=q; ii++ )
+   {
+      for ( jj=2; jj<=ii; jj++ )
+      {
+         ff = NF(f[ii]*f[jj],std(0));       //this makes lift much faster
+         A = lift(pf,ff);                   //ff lin. comb. of elts of pf mod I
+         Quad = Quad, ideal(T(jj)*T(ii) - T*A);  //quadratic relations
+      }
+   }
+
+   if(y>=1)
+   {
+      "//   the quadratic relations";
+      Quad;
+      pause();
+      newline;
+   }
+   Q = Lin,Quad;
+   Q = subst(Q,T(1),1);
+   //Q = mstd(Q)[2];            //### sehr aufwendig, daher weggelassen (GMG)
+   //### ev das neue interred
+   //mstd dient nur zum verkleinern, die SB-Eigenschaft geht spaeter verloren
+   //da in neuen Ring abgebildet und mit id vereinigt
+
+//---------- reduce number of variables by substitution, if possible ----------
+   if (homo==1)
+   {
+      ring newRing = char(R),(X(1..nvars(R)),T(2..q)),(a(rw),dp);
+   }
+   else
+   {
+      ring newRing = char(R),(X(1..nvars(R)),T(2..q)),dp;
+   }
+
+   ideal endid  = imap(newR,id),imap(newR,Q);
+   //hier wird Q weiterverwendet, die SB-Eigenschaft wird nicht verwendet.
+   endid = simplify(endid,2);
+   ideal endphi = ideal(X(1..nvars(R)));
+
+
+  if(noRed == 0)
+  {
+    L = substpart(endid,endphi,homo,rw);
+    def lastRing=L[1];
+    setring lastRing;
+    //return(lastRing);
+  }
+  else
+  {
+    list RL = ringlist(newRing);
+    def lastRing = ring(RL);
+    setring lastRing;
+    ideal endid = fetch(newRing, endid);
+    ideal endphi = fetch(newRing, endphi);
+    export(endid);
+    export(endphi);
+    //def lastRing = newRing;
+    //setring R;
+    //return(newR);
+  }
+
+
+//   L = substpart(endid,endphi,homo,rw);
+
+//   def lastRing=L[1];
+//   setring lastRing;
+
+   attrib(endid,"onlySingularAtZero",0);
+   map sigma=R,endphi;
+   ideal an=sigma(ann);
+   export(an);  //noetig?
+   //ideal te=an,endid;
+   //if(isIso && (size(reduce(te,std(maxideal(1))))==0))   //#### ok???
+   // {
+   //    attrib(endid,"onlySingularAtZero",oSAZ);
+   // }
+   //kill te;
+   attrib(endid,"isCohenMacaulay",isCo);                //#### ok???
+   attrib(endid,"isPrim",isPr);
+   attrib(endid,"isIsolatedSingularity",isIso);
+   attrib(endid,"isRegInCodim2",isRe);
+   attrib(endid,"isEquidimensional",isEq);
+   attrib(endid,"isHypersurface",0);
+   attrib(endid,"isCompleteIntersection",0);
+   attrib(endid,"isRadical",0);
+   if(y>=1)
+   {
+      "// the new ring after reduction of the number of variables";
+      lastRing;
+      "//   the new ideal";
+      endid;  "";
+      "// the old ring";
+      P;
+      "//   the old ideal";
+      setring P;
+      id;
+      "   ";
+      setring lastRing;
+      "//   the map to the new ring";
+      endphi;
+      "   ";
+      pause();
+      "";
+   }
+   L = lastRing;
+   L = insert(L,0,1);
+   L[3] = delt;
+   setring(P);
+   return(L);
+}
+example
+{"EXAMPLE:";  echo = 2;
+  ring r   = 0,(x,y),wp(2,3);
+  ideal id = y^2-x^3;
+  ideal J  = x,y;
+  poly p   = x;
+  list Li  = std(id),id,J,p;
+  list L   = HomJJ(Li);
+  def end = L[1];    // defines ring L[1], containing ideals endid, endphi
+  setring end;       // makes end the basering
+  end;
+  endid;             // end/endid is isomorphic to End(r/id) as ring
+  map psi = r,endphi;// defines the canonical map r/id -> End(r/id)
+  psi;
+  L[3];              // contribution to delta
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+//compute intersection multiplicities as needed for delta(I) in
+//normalizationPrimes and normalP:
+
+proc iMult (list prim)
+"USAGE:   iMult(L);  L a list of ideals
+RETURN:  int, the intersection multiplicity of the ideals of L;
+         if iMult(L) is infinite, -1 is returned.
+THEORY:  If r=size(L)=2 then iMult(L) = vdim(std(L[1]+L[2])) and in general
+         iMult(L) = sum{ iMult(L[j],Lj) | j=1..r-1 } with Lj the intersection
+         of L[j+1],...,L[r]. If I is the intersection of all ideals in L then
+         we have delta(I) = delta(L[1])+...+delta(L[r]) + iMult(L) where
+         delta(I) = vdim (normalisation(R/I)/(R/I)), R the basering.
+EXAMPLE: example iMult; shows an example
+"
+{
+     ASSUME(0, not isQuotientRing(basering) );
+
+     int i,mul,mu;
+     int sp = size(prim);
+     int y = printlevel-voice+2;
+     if ( sp > 1 )
+     {
+        ideal I(sp-1) = prim[sp];
+        mu = vdim(std(I(sp-1)+prim[sp-1]));
+        mul = mu;
+        if ( y>=1 )
+        {
+          "// intersection multiplicity of component",sp,"with",sp-1,":"; mu;
+        }
+        if ( mu >= 0 )
+        {
+           for (i=sp-2; i>=1 ; i--)
+           {
+              ideal I(i) = intersect(I(i+1),prim[i+1]);
+              mu = vdim(std(I(i)+prim[i]));
+              if ( mu < 0 )
+              {
+                break;
+              }
+              mul = mul + mu;
+              if ( y>=1 )
+              {
+                "// intersection multiplicity of components",sp,"...",i+1,"with",i; mu;
+              }
+           }
+        }
+     }
+     return(mul);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring s  = 23,(x,y),dp;
+   list L = (x-y),(x3+y2);
+   iMult(L);
+   L = (x-y),(x3+y2),(x3-y4);
+   iMult(L);
+}
+///////////////////////////////////////////////////////////////////////////////
+//check if I has a singularity only at zero, as needed in normalizationPrimes
+
+proc locAtZero (ideal I)
+"USAGE:   locAtZero(I);  I = ideal
+RETURN:  int, 1 if I has only one point which is located at zero, 0 otherwise
+ASSUME:  I is given as a standard bases in the basering
+NOTE:    only useful in affine rings, in local rings vdim does the check
+EXAMPLE: example locAtZero; shows an example
+"
+{
+   ASSUME(0, not isQuotientRing(basering) );
+
+   int ii,jj, caz;                   //caz: conzentrated at zero
+   int dbp = printlevel-voice+2;
+   int nva = nvars(basering);
+   int vdi = vdim(I);
+   if ( vdi < 0 )
+   {
+      if (dbp >=1)
+      { "// non-isolated singularitiy";""; }
+      return(caz);
+   }
+
+   //Now the ideal is 0-dim
+   //First an easy test
+   //If I is homogenous and not constant it is concentrated at 0
+   if( homog(I)==1 && size(jet(I,0))==0)
+   {
+      caz=1;
+      if (dbp >=1)
+      { "// isolated singularity and homogeneous";""; }
+      return(caz);
+   }
+
+   //Now the general case with I 0-dim. Choose an appropriate power pot,
+   //and check each variable x whether x^pot is in I.
+   int mi1 = mindeg1(lead(I));
+   int pot = vdi;
+   if ( (mi1+(mi1==1))^2 < vdi )
+   {
+      pot = (mi1+(mi1==1))^2;      //### alternativ: pot = vdi lassen
+   }
+
+   while ( 1 )
+   {
+      caz = 1;
+      for ( ii=1; ii<= nva; ii++ )
+      {
+        if ( NF(var(ii)^pot,I) != 0 )
+        {
+           caz = 0; break;
+        }
+      }
+      if ( caz == 1 || pot >= vdi )
+      {
+        if (dbp >=1)
+        {
+          "// mindeg, exponent, vdim used in 'locAtZero':", mi1,pot,vdi; "";
+        }
+        return(caz);
+      }
+      else
+      {
+        if ( pot^2 < vdi )
+        { pot = pot^2; }
+        else
+        { pot = vdi; }
+      }
+   }
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r = 0,(x,y,z),dp;
+   poly f = z5+y4+x3+xyz;
+   ideal i = jacob(f),f;
+   i=std(i);
+   locAtZero(i);
+   i= std(i*ideal(x-1,y,z));
+   locAtZero(i);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+//The next procedure normalizationPrimes computes the normalization of an
+//irreducible or an equidimensional ideal i.
+//- If i is irreducuble, then the returned list, say nor, has size 2
+//with nor[1] the normalization ring and nor[2] the delta invariant.
+//- If i is equidimensional, than the "splitting tools" can create a
+//decomposition of i and nor can have more than 1 ring.
+
+static proc normalizationPrimes(ideal i,ideal ihp,int delt,intvec delti,list #)
+"USAGE:   normalizationPrimes(i,ihp,delt[,si]);  i = equidimensional ideal,
+         ihp = map (partial normalization), delt = partial delta-invariant,
+         si = ideal s.t. V(si) contains singular locus (optional)
+RETURN:   a list of rings, say nor, and an integer, the delta-invariant
+          at the end of the list.
+          each ring nor[j], j = 1..size(nor)-1, contains two ideals
+          with given names norid and normap such that
+           - the direct sum of the rings nor[j]/norid is
+             the normalization of basering/i;
+           - normap gives the normalization map from basering/id
+             to nor[j]/norid (for each j)
+          nor[size(nor)] = dim_K(normalisation(P/i) / (P/i)) is the
+          delta-invariant, where P is the basering.
+EXAMPLE: example normalizationPrimes; shows an example
+"
+{
+   ASSUME(1, not isQuotientRing(basering) );
+   //Note: this procedure calls itself as long as the test for
+   //normality, i.e if R==Hom(J,J), is negative.
+
+   int printlev = printlevel;   //store printlevel in order to reset it later
+   int y = printlevel-voice+2;  // y=printlevel (default: y=0)
+   if(y>=1)
+   {
+     "";
+     "// START a normalization loop with the ideal";
+     i;  "";
+     "// in the ring:";
+     basering;  "";
+     pause();
+     "";
+   }
+
+   def BAS=basering;
+   list result,keepresult1,keepresult2,JM,gnirlist;
+   ideal J,SB,MB;
+   int depth,lauf,prdim,osaz;
+   int ti=timer;
+
+   gnirlist = ringlist(BAS);
+
+//----------- the trivial case of a zero ideal as input, RETURN ------------
+   if(size(i)==0)
+   {
+      if(y>=1)
+      {
+          "// the ideal was the zero-ideal";
+      }
+     // execute("ring newR7="+charstr(basering)+",("+varstr(basering)+"),("
+     //                 +ordstr(basering)+");");
+         def newR7 = ring(gnirlist);
+         setring newR7;
+         ideal norid=ideal(0);
+         ideal normap=fetch(BAS,ihp);
+         export norid;
+         export normap;
+         result=newR7;
+         result[size(result)+1]=list(delt,delti);
+         setring BAS;
+         return(result);
+   }
+
+//--------------- General NOTATION, compute SB of input -----------------
+// SM is a list, the result of mstd(i)
+// SM[1] = SB of input ideal i,
+// SM[2] = (minimal) generators for i.
+// We work with SM and will copy the attributes from i to SM[2]
+// JM will be a list, either JM[1]=maxideal(1),JM[2]=maxideal(1)
+// in case i has onlySingularAtZero, or JM = mstd(si) where si = #[1],
+// or JM = mstd(J) where J is the ideal of the singular locus
+// JM[2] must be (made) radical
+
+   if(y>=1)
+   {
+     "// SB-computation of the ideal";
+   }
+
+   list SM = mstd(i);              //Now the work starts
+   int dimSM =  dim(SM[1]);        //dimension of variety to normalize
+   if(y>=1)
+   {
+      "// the dimension is:";  dimSM;
+   }
+//----------------- the general case, set attributes ----------------
+   //Note: onlySingularAtZero is NOT preserved under the ring extension
+   //basering --> Hom(J,J) (in contrast to isIsolatedSingularity),
+   //therefore we reset it:
+
+   attrib(i,"onlySingularAtZero",0);
+
+   if(attrib(i,"isPrim")==1)
+   {
+      attrib(SM[2],"isPrim",1);
+   }
+   else
+   {
+      attrib(SM[2],"isPrim",0);
+   }
+   if(attrib(i,"isIsolatedSingularity")==1)
+   {
+      attrib(SM[2],"isIsolatedSingularity",1);
+   }
+   else
+   {
+      attrib(SM[2],"isIsolatedSingularity",0);
+   }
+   if(attrib(i,"isCohenMacaulay")==1)
+   {
+      attrib(SM[2],"isCohenMacaulay",1);
+   }
+   else
+   {
+      attrib(SM[2],"isCohenMacaulay",0);
+   }
+   if(attrib(i,"isRegInCodim2")==1)
+   {
+      attrib(SM[2],"isRegInCodim2",1);
+   }
+   else
+   {
+      attrib(SM[2],"isRegInCodim2",0);
+   }
+   if(attrib(i,"isEquidimensional")==1)
+   {
+      attrib(SM[2],"isEquidimensional",1);
+   }
+   else
+   {
+      attrib(SM[2],"isEquidimensional",0);
+   }
+   if(attrib(i,"isCompleteIntersection")==1)
+   {
+     attrib(SM[2],"isCompleteIntersection",1);
+   }
+   else
+   {
+      attrib(SM[2],"isCompleteIntersection",0);
+   }
+   if(attrib(i,"isHypersurface")==1)
+   {
+     attrib(SM[2],"isHypersurface",1);
+   }
+   else
+   {
+      attrib(SM[2],"isHypersurface",0);
+   }
+
+   if(attrib(i,"onlySingularAtZero")==1)
+   {
+      attrib(SM[2],"onlySingularAtZero",1);
+   }
+   else
+   {
+      attrib(SM[2],"onlySingularAtZero",0);
+   }
+
+   //------- an easy and cheap test for onlySingularAtZero ---------
+   if( (attrib(SM[2],"isIsolatedSingularity")==1) && (homog(SM[2])==1) )
+   {
+      attrib(SM[2],"onlySingularAtZero",1);
+   }
+
+//-------------------- Trivial cases, in each case RETURN ------------------
+// input ideal is the ideal of a partial normalization
+
+   // ------------ Trivial case: input ideal contains a unit ---------------
+   if( dimSM == -1)
+   {  "";
+      "      // A unit ideal was found.";
+      "      // Stop with partial result computed so far";"";
+
+         MB=SM[2];
+         intvec rw;
+         list LL=substpart(MB,ihp,0,rw);
+         def newR6=LL[1];
+         setring newR6;
+         ideal norid=endid;
+         ideal normap=endphi;
+         kill endid,endphi;
+         export norid;
+         export normap;
+         result=newR6;
+         result[size(result)+1]=list(delt,delti);
+         setring BAS;
+         return(result);
+   }
+
+   // --- Trivial case: input ideal is zero-dimensional and homog ---
+   if( (dim(SM[1])==0) && (homog(SM[2])==1) )
+   {
+      if(y>=1)
+      {
+         "// the ideal was zero-dimensional and homogeneous";
+      }
+      MB=maxideal(1);
+      intvec rw;
+      list LL=substpart(MB,ihp,0,rw);
+      def newR5=LL[1];
+      setring newR5;
+      ideal norid=endid;
+      ideal normap=endphi;
+      kill endid,endphi;
+      export norid;
+      export normap;
+      result=newR5;
+      result[size(result)+1]=list(delt,delti);
+      setring BAS;
+      return(result);
+   }
+
+   // --- Trivial case: input ideal defines a line ---
+   //the one-dimensional, homogeneous case and degree 1 case
+   if( (dim(SM[1])==1) && (maxdeg1(SM[2])==1) && (homog(SM[2])==1) )
+   {
+      if(y>=1)
+      {
+         "// the ideal defines a line";
+      }
+      MB=SM[2];
+      intvec rw;
+      list LL=substpart(MB,ihp,0,rw);
+      def newR4=LL[1];
+      setring newR4;
+      ideal norid=endid;
+      ideal normap=endphi;
+      kill endid,endphi;
+      export norid;
+      export normap;
+      result=newR4;
+      result[size(result)+1]=list(delt,delti);
+      setring BAS;
+      return(result);
+   }
+
+//---------------------- The non-trivial cases start -------------------
+   //the higher dimensional case
+   //we test first hypersurface, CohenMacaulay and complete intersection
+
+   if( ((size(SM[2])+dim(SM[1])) == nvars(basering)) )
+   {
+      //the test for complete intersection
+      attrib(SM[2],"isCohenMacaulay",1);
+      attrib(SM[2],"isCompleteIntersection",1);
+      attrib(SM[2],"isEquidimensional",1);
+      if(y>=1)
+      {
+         "// the ideal is a complete intersection";
+      }
+   }
+   if( size(SM[2]) == 1 )
+   {
+      attrib(SM[2],"isHypersurface",1);
+      if(y>=1)
+      {
+         "// the ideal is a hypersurface";
+      }
+   }
+
+   //------------------- compute the singular locus -------------------
+   // Computation if singular locus is critical
+   // Notation: J ideal of singular locus or (if given) containing it
+   // JM = mstd(J) or maxideal(1),maxideal(1)
+   // JM[1] SB of singular locus, JM[2] minbasis, dimJ = dim(JM[1])
+   // SM[1] SB of the input ideal i, SM[2] minbasis
+   // Computation if singular locus is critical, because it determines the
+   // size of the ring Hom_R(J,J). We only need a test ideal contained in J.
+
+   //----------------------- onlySingularAtZero -------------------------
+   if( attrib(SM[2],"onlySingularAtZero") )
+   {
+       JM = maxideal(1),maxideal(1);
+       attrib(JM[1],"isSB",1);
+       attrib(JM[2],"isRadical",1);
+       if( dim(SM[1]) >=2 )
+       {
+         attrib(SM[2],"isRegInCodim2",1);
+       }
+   }
+
+   //-------------------- not onlySingularAtZero -------------------------
+   if( attrib(SM[2],"onlySingularAtZero") == 0 )
+   {
+      //--- the case where an ideal #[1] is given:
+      if( size(#)>0 )
+      {
+         J = #[1],SM[2];
+         JM = mstd(J);
+         if( typeof(attrib(#[1],"isRadical"))!="int" )
+         {
+            attrib(JM[2],"isRadical",0);
+         }
+      }
+
+      //--- the case where an ideal #[1] is not given:
+      if( (size(#)==0) )
+      {
+         if(y >=1 )
+         {
+            "// singular locus will be computed";
+         }
+
+         J = SM[1],minor(jacob(SM[2]),nvars(basering)-dim(SM[1]),SM[1]);
+         if( y >=1 )
+         {
+            "// SB of singular locus will be computed";
+         }
+         JM = mstd(J);
+      }
+
+      int dimJ = dim(JM[1]);
+      attrib(JM[1],"isSB",1);
+      if( y>=1 )
+      {
+         "// the dimension of the singular locus is";  dimJ ; "";
+      }
+
+      if(dim(JM[1]) <= dim(SM[1])-2)
+      {
+         attrib(SM[2],"isRegInCodim2",1);
+      }
+
+      //------------------ the smooth case, RETURN -------------------
+      if( dimJ == -1 )
+      {
+         if(y>=1)
+         {
+            "// the ideal is smooth";
+         }
+         MB=SM[2];
+         intvec rw;
+         list LL=substpart(MB,ihp,0,rw);
+         def newR3=LL[1];
+         setring newR3;
+         ideal norid=endid;
+         ideal normap=endphi;
+         kill endid,endphi;
+         export norid;
+         export normap;
+         result=newR3;
+         result[size(result)+1]=list(delt,delti);
+         setring BAS;
+         return(result);
+      }
+
+      //------- extra check for onlySingularAtZero, relatively cheap ----------
+      //it uses the procedure 'locAtZero' from for testing
+      //if an ideal is concentrated at 0
+       if(y>=1)
+       {
+         "// extra test for onlySingularAtZero:";
+       }
+       if ( locAtZero(JM[1]) )
+       {
+           attrib(SM[2],"onlySingularAtZero",1);
+           JM = maxideal(1),maxideal(1);
+           attrib(JM[1],"isSB",1);
+           attrib(JM[2],"isRadical",1);
+       }
+       else
+       {
+            attrib(SM[2],"onlySingularAtZero",0);
+       }
+   }
+
+  //displaying the attributes:
+   if(y>=2)
+   {
+      "// the attributes of the ideal are:";
+      "// isCohenMacaulay:", attrib(SM[2],"isCohenMacaulay");
+      "// isCompleteIntersection:", attrib(SM[2],"isCompleteIntersection");
+      "// isHypersurface:", attrib(SM[2],"isHypersurface");
+      "// isEquidimensional:", attrib(SM[2],"isEquidimensional");
+      "// isPrim:", attrib(SM[2],"isPrim");
+      "// isRegInCodim2:", attrib(SM[2],"isRegInCodim2");
+      "// isIsolatedSingularity:", attrib(SM[2],"isIsolatedSingularity");
+      "// onlySingularAtZero:", attrib(SM[2],"onlySingularAtZero");
+      "// isRad:", attrib(SM[2],"isRad");"";
+   }
+
+   //------------- case: CohenMacaulay in codim 2, RETURN ---------------
+   if( (attrib(SM[2],"isRegInCodim2")==1) &&
+       (attrib(SM[2],"isCohenMacaulay")==1) )
+   {
+      if(y>=1)
+      {
+         "// the ideal was CohenMacaulay and regular in codim 2, hence normal";
+      }
+      MB=SM[2];
+      intvec rw;
+      list LL=substpart(MB,ihp,0,rw);
+      def newR6=LL[1];
+      setring newR6;
+      ideal norid=endid;
+      ideal normap=endphi;
+      kill endid,endphi;
+      export norid;
+      export normap;
+      result=newR6;
+      result[size(result)+1]=list(delt,delti);
+      setring BAS;
+      return(result);
+   }
+
+//---------- case: isolated singularity only at 0, RETURN ------------
+   // In this case things are easier, we can use the maximal ideal as radical
+   // of the singular locus;
+   // JM mstd of ideal of singular locus, SM mstd of input ideal
+
+   if( attrib(SM[2],"onlySingularAtZero") )
+   {
+   //------ check variables for being a non zero-divizor ------
+   // SL = ideal of vars not contained in ideal SM[1]:
+
+      attrib(SM[2],"isIsolatedSingularity",1);
+      ideal SL = simplify(reduce(maxideal(1),SM[1]),2);
+      ideal Ann = quotient(SM[2],SL[1]);
+      ideal qAnn = simplify(reduce(Ann,SM[1]),2);
+      //NOTE: qAnn=0 if and only if first var (=SL[1]) not in SM is a nzd of R/SM
+
+   //------------- We found a non-zerodivisor of R/SM -----------------------
+   // here the enlarging of the ring via Hom_R(J,J) starts
+
+      if( size(qAnn)==0 )
+      {
+         if(y>=1)
+         {
+            "";
+            "// the ideal rad(J):"; maxideal(1);
+            "";
+         }
+
+      // ------------- test for normality, compute Hom_R(J,J) -------------
+      // Note:
+      // HomJJ (ideal SBid, ideal id, ideal J, poly p) with
+      //        SBid = SB of id, J = radical ideal of basering  P with:
+      //        nonNormal(R) is in V(J), J contains the nonzero divisor p
+      //        of R = P/id (J = test ideal)
+      // returns a list l of three objects
+      // l[1] : a polynomial ring, containing two ideals, 'endid' and 'endphi'
+      //        s.t. l[1]/endid = Hom_R(J,J) and endphi= map R -> Hom_R(J,J)
+      // l[2] : an integer which is 1 if phi is an isomorphism, 0 if not
+      // l[3] : an integer, = dim_K(Hom_R(J,J)/R) if finite, -1 otherwise
+
+         list RR;
+         RR = SM[1],SM[2],maxideal(1),SL[1];
+         RR = HomJJ(RR,y);
+         // --------------------- non-normal case ------------------
+         //RR[2]==0 means that the test for normality is negative
+         if( RR[2]==0 )
+         {
+            def newR=RR[1];
+            setring newR;
+            map psi=BAS,endphi;
+            list JM = psi(JM); //###
+            ideal J = JM[2];
+            if ( delt>=0 && RR[3]>=0 )
+            {
+               delt = delt+RR[3];
+            }
+            else
+            { delt = -1; }
+            delti[size(delti)]=delt;
+
+            // ---------- recursive call of normalizationPrimes -----------
+        //normalizationPrimes(ideal i,ideal ihp,int delt,intvec delti,list #)
+        //ihp = (partial) normalisation map from basering
+        //#[1] ideal s.t. V(#[1]) contains singular locus of i (test ideal)
+
+            if ( y>=1 )
+            {
+            "// case: onlySingularAtZero, non-zerodivisor found";
+            "// contribution of delta in ringextension R -> Hom_R(J,J):"; delt;
+            }
+
+            //intvec atr=getAttrib(endid);
+            //"//### case: isolated singularity only at 0, recursive";
+            //"size endid:", size(endid), size(string(endid));
+            //"interred:";
+            //endid = interred(endid);
+            //endid = setAttrib(endid,atr);
+            //"size endid:", size(endid), size(string(endid));
+
+           printlevel=printlevel+1;
+           list tluser =
+                normalizationPrimes(endid,psi(ihp),delt,delti);
+           //list tluser =
+           //     normalizationPrimes(endid,psi(ihp),delt,delti,J);
+           //#### ??? improvement: give also the old ideal of sing locus???
+
+           printlevel = printlev;             //reset printlevel
+           setring BAS;
+           return(tluser);
+         }
+
+         // ------------------ the normal case, RETURN -----------------
+         // Now RR[2] must be 1, hence the test for normality was positive
+         MB=SM[2];
+         //execute("ring newR7="+charstr(basering)+",("+varstr(basering)+"),("
+         //             +ordstr(basering)+");");
+         def newR7 = ring(gnirlist);
+         setring newR7;
+         ideal norid=fetch(BAS,MB);
+         ideal normap=fetch(BAS,ihp);
+         if ( delt>=0 && RR[3]>=0 )
+         {
+               delt = delt+RR[3];
+         }
+         else
+         { delt = -1; }
+         delti[size(delti)]=delt;
+
+         intvec atr = getAttrib(norid);
+
+         //"//### case: isolated singularity only at 0, final";
+         //"size norid:", size(norid), size(string(norid));
+         //"interred:";
+         //norid = interred(norid);
+         //norid = setAttrib(norid,atr);
+         //"size norid:", size(norid), size(string(norid));
+
+         export norid;
+         export normap;
+         result=newR7;
+         result[size(result)+1]=list(delt,delti);
+         setring BAS;
+         return(result);
+      }
+
+   //------ zerodivisor of R/SM was found, gives a splitting ------------
+   //Now the case where qAnn!=0, i.e. SL[1] is a zero divisor of R/SM
+   //and we have found a splitting: id and id1
+   //id = Ann defines components of R/SM in the complement of V(SL[1])
+   //id1 defines components of R/SM in the complement of V(id)
+
+      else
+       {
+          ideal id = Ann;
+          attrib(id,"isCohenMacaulay",0);
+          attrib(id,"isPrim",0);
+          attrib(id,"isIsolatedSingularity",1);
+          attrib(id,"isRegInCodim2",0);
+          attrib(id,"isHypersurface",0);
+          attrib(id,"isCompleteIntersection",0);
+          attrib(id,"isEquidimensional",0);
+          attrib(id,"onlySingularAtZero",1);
+
+          ideal id1 = quotient(SM[2],Ann);
+          attrib(id1,"isCohenMacaulay",0);
+          attrib(id1,"isPrim",0);
+          attrib(id1,"isIsolatedSingularity",1);
+          attrib(id1,"isRegInCodim2",0);
+          attrib(id1,"isHypersurface",0);
+          attrib(id1,"isCompleteIntersection",0);
+          attrib(id1,"isEquidimensional",0);
+          attrib(id1,"onlySingularAtZero",1);
+
+          // ---------- recursive call of normalizationPrimes -----------
+          if ( y>=1 )
+          {
+            "// case: onlySingularAtZero, zerodivisor found, splitting:";
+            "// total delta before splitting:", delt;
+            "// splitting in two components:";
+          }
+
+          printlevel = printlevel+1;  //to see comments in normalizationPrimes
+          keepresult1 = normalizationPrimes(id,ihp,0,0);   //1st split factor
+          keepresult2 = normalizationPrimes(id1,ihp,0,0);  //2nd split factor
+          printlevel = printlev;                           //reset printlevel
+
+          int delt1 = keepresult1[size(keepresult1)][1];
+          int delt2 = keepresult2[size(keepresult2)][1];
+          intvec delti1 = keepresult1[size(keepresult1)][2];
+          intvec delti2 = keepresult2[size(keepresult2)][2];
+
+          if( delt>=0 && delt1>=0 && delt2>=0 )
+          {  ideal idid1=id,id1;
+             int mul = vdim(std(idid1));
+             if ( mul>=0 )
+             {
+               delt = delt+mul+delt1+delt2;
+             }
+             else
+             {
+               delt = -1;
+             }
+          }
+         if ( y>=1 )
+         {
+           "// delta of first component:", delt1;
+           "// delta of second componenet:", delt2;
+           "// intersection multiplicity of both components:", mul;
+           "// total delta after splitting:", delt;
+         }
+
+          else
+          {
+            delt = -1;
+          }
+          for(lauf=1;lauf<=size(keepresult2)-1;lauf++)
+          {
+             keepresult1=insert(keepresult1,keepresult2[lauf]);
+          }
+          keepresult1[size(keepresult1)]=list(delt,delti);
+
+          return(keepresult1);
+       }
+   }
+   // Case "onlySingularAtZero" has finished and returned result
+
+//-------------- General case, not onlySingularAtZero, RETURN ---------------
+   //test for non-normality, i.e. if Hom(I,I)<>R
+   //we can use Hom(I,I) to continue
+
+   //------ check variables for being a non zero-divizor ------
+   // SL = ideal of vars not contained in ideal SM[1]:
+
+   ideal SL = simplify(reduce(JM[2],SM[1]),2);
+   ideal Ann = quotient(SM[2],SL[1]);
+   ideal qAnn = simplify(reduce(Ann,SM[1]),2);
+   //NOTE: qAnn=0 <==> first var (=SL[1]) not contained in SM is a nzd of R/SM
+
+   //------------- We found a non-zerodivisor of R/SM -----------------------
+   //SM = mstd of ideal of variety, JM = mstd of ideal of singular locus
+
+   if( size(qAnn)==0 )
+   {
+      list RR;
+      list RS;
+      // ----------------- Computation of the radical -----------------
+      if(y>=1)
+      {
+         "// radical computation of singular locus";
+      }
+      J = radical(JM[2]);   //the radical of singular locus
+      JM = mstd(J);
+
+      if(y>=1)
+      {
+        "// radical is equal to:";"";  JM[2];
+        "";
+      }
+      // ------------ choose non-zerodivisor of smaller degree ----------
+      //### evtl. fuer SL[1] anderen Nichtnullteiler aus J waehlen ?
+      if( deg(SL[1]) > deg(J[1]) )
+      {
+         Ann=quotient(SM[2],J[1]);
+         qAnn=simplify(reduce(Ann,SM[1]),2);
+         if(size(qAnn)==0)
+         {
+           SL[1]=J[1];
+         }
+      }
+
+      // --------------- computation of Hom(rad(J),rad(J)) --------------
+      RR=SM[1],SM[2],JM[2],SL[1];
+
+     if(y>=1)
+     {
+        "// compute Hom(rad(J),rad(J))";
+     }
+
+     RS=HomJJ(RR,y);               //most important subprocedure
+
+     // ------------------ the normal case, RETURN -----------------
+     // RS[2]==1 means that the test for normality was positive
+     if(RS[2]==1)
+     {
+         def lastR=RS[1];
+         setring lastR;
+         map psi1=BAS,endphi;
+         ideal norid=endid;
+         ideal normap=psi1(ihp);
+         kill endid,endphi;
+
+        intvec atr=getAttrib(norid);
+
+        //"//### general case: not isolated singularity only at 0, final";
+        //"size norid:", size(norid), size(string(norid));
+        //"interred:";
+        //norid = interred(norid);
+        //norid = setAttrib(norid,atr);
+        //"size norid:", size(norid), size(string(norid));
+
+         export norid;
+         export normap;
+         result=lastR;
+         if ( y>=1 )
+         {
+            "// case: not onlySingularAtZero, last ring Hom_R(J,J) computed";
+            "// delta before last ring:", delt;
+         }
+
+         if ( delt>=0 && RS[3]>=0 )
+         {
+            delt = delt+RS[3];
+         }
+         else
+         { delt = -1; }
+
+        // delti = delti,delt;
+         delti[size(delti)]=delt;
+
+         if ( y>=1 )
+         {
+           "// delta of last ring:", delt;
+         }
+
+         result[size(result)+1]=list(delt,delti);
+         setring BAS;
+         return(result);
+     }
+
+    // ----- the non-normal case, recursive call of normalizationPrimes -------
+    // RS=HomJJ(RR,y) was computed above, RS[1] contains endid and endphi
+    // RS[1] = new ring Hom_R(J,J), RS[2]= 0 or 1, RS[2]=contribution to delta
+    // now RS[2]must be 0, i.e. the test for normality was negative
+
+      int n = nvars(basering);
+      ideal MJ = JM[2];
+
+      def newR=RS[1];
+      setring newR;
+      map psi=BAS,endphi;
+      if ( y>=1 )
+      {
+        "// case: not onlySingularAtZero, compute new ring = Hom_R(J,J)";
+        "// delta of old ring:", delt;
+      }
+      if ( delt>=0 && RS[3]>=0 )
+      {
+         delt = delt+RS[3];
+      }
+      else
+      { delt = -1; }
+      if ( y>=1 )
+      {
+        "// delta of new ring:", delt;
+      }
+
+      delti[size(delti)]=delt;
+      intvec atr=getAttrib(endid);
+
+      //"//### general case: not isolated singularity only at 0, recursive";
+      //"size endid:", size(endid), size(string(endid));
+      //"interred:";
+      //endid = interred(endid);
+      //endid = setAttrib(endid,atr);
+      //"size endid:", size(endid), size(string(endid));
+
+      printlevel = printlevel+1;
+      list tluser=
+          normalizationPrimes(endid,psi(ihp),delt,delti,psi(MJ));
+      printlevel = printlev;                //reset printlevel
+      setring BAS;
+      return(tluser);
+   }
+
+   //---- A whole singular component was found, RETURN -----
+   if( Ann == 1)
+   {
+      "// Input appeared not to be a radical ideal!";
+      "// A (everywhere singular) component with ideal";
+      "// equal to its Jacobian ideal was found";
+      "// Procedure will stop with partial result computed so far";"";
+
+         MB=SM[2];
+         intvec rw;
+         list LL=substpart(MB,ihp,0,rw);
+         def newR6=LL[1];
+         setring newR6;
+         ideal norid=endid;
+         ideal normap=endphi;
+         kill endid,endphi;
+         export norid;
+         export normap;
+         result=newR6;
+         result[size(result)+1]=lst(delt,delti);
+         setring BAS;
+         return(result);
+   }
+
+   //------ zerodivisor of R/SM was found, gives a splitting ------------
+   //Now the case where qAnn!=0, i.e. SL[1] is a zero divisor of R/SM
+   //and we have found a splitting: new1 and new2
+   //id = Ann defines components of R/SM in the complement of V(SL[1])
+   //id1 defines components of R/SM in the complement of V(id)
+
+   else
+   {
+      if(y>=1)
+      {
+         "// zero-divisor found";
+      }
+      int equi = attrib(SM[2],"isEquidimensional");
+      int oSAZ = attrib(SM[2],"onlySingularAtZero");
+      int isIs = attrib(SM[2],"isIsolatedSingularity");
+
+      ideal new1 = Ann;
+      ideal new2 = quotient(SM[2],Ann);
+      //ideal new2=SL[1],SM[2];
+
+      //execute("ring newR1="+charstr(basering)+",("+varstr(basering)+"),("
+      //                +ordstr(basering)+");");
+      def newR1 = ring(gnirlist);
+      setring newR1;
+
+      ideal vid = fetch(BAS,new1);
+      ideal ihp = fetch(BAS,ihp);
+      attrib(vid,"isCohenMacaulay",0);
+      attrib(vid,"isPrim",0);
+      attrib(vid,"isIsolatedSingularity",isIs);
+      attrib(vid,"isRegInCodim2",0);
+      attrib(vid,"onlySingularAtZero",oSAZ);
+      attrib(vid,"isEquidimensional",equi);
+      attrib(vid,"isHypersurface",0);
+      attrib(vid,"isCompleteIntersection",0);
+
+      // ---------- recursive call of normalizationPrimes -----------
+      if ( y>=1 )
+      {
+        "// total delta before splitting:", delt;
+        "// splitting in two components:";
+      }
+      printlevel = printlevel+1;
+      keepresult1 =
+                  normalizationPrimes(vid,ihp,0,0);  //1st split factor
+
+      list delta1 = keepresult1[size(keepresult1)];
+
+      setring BAS;
+      //execute("ring newR2="+charstr(basering)+",("+varstr(basering)+"),("
+      //                +ordstr(basering)+");");
+      def newR2 = ring(gnirlist);
+      setring newR2;
+
+      ideal vid = fetch(BAS,new2);
+      ideal ihp = fetch(BAS,ihp);
+      attrib(vid,"isCohenMacaulay",0);
+      attrib(vid,"isPrim",0);
+      attrib(vid,"isIsolatedSingularity",isIs);
+      attrib(vid,"isRegInCodim2",0);
+      attrib(vid,"isEquidimensional",equi);
+      attrib(vid,"isHypersurface",0);
+      attrib(vid,"isCompleteIntersection",0);
+      attrib(vid,"onlySingularAtZero",oSAZ);
+
+      keepresult2 =
+                    normalizationPrimes(vid,ihp,0,0);
+      list delta2 = keepresult2[size(keepresult2)];   //2nd split factor
+      printlevel = printlev;                          //reset printlevel
+
+      setring BAS;
+
+      //compute intersection multiplicity of both components:
+      new1 = new1,new2;
+      int mul=vdim(std(new1));
+
+     // ----- normalizationPrimes finished, add up results, RETURN --------
+      for(lauf=1;lauf<=size(keepresult2)-1;lauf++)
+      {
+         keepresult1 = insert(keepresult1,keepresult2[lauf]);
+      }
+      if ( delt >=0 && delta1[1] >=0 && delta2[1] >=0 && mul >=0 )
+      {
+         delt = delt+mul+delta1[1]+delta2[1];
+      }
+      else
+      {  delt = -1; }
+      delti = -2;
+
+      if ( y>=1 )
+      {
+        "// zero divisor produced a splitting into two components";
+        "// delta of first component:", delta1;
+        "// delta of second componenet:", delta2;
+        "// intersection multiplicity of both components:", mul;
+        "// total delta after splitting:", delt;
+      }
+      keepresult1[size(keepresult1)] = list(delt,delti);
+      return(keepresult1);
+   }
+}
+example
+{ "EXAMPLE:";echo = 2;
+   // Huneke
+   ring qr=31991,(a,b,c,d,e),dp;
+   ideal i=
+   5abcde-a5-b5-c5-d5-e5,
+   ab3c+bc3d+a3be+cd3e+ade3,
+   a2bc2+b2cd2+a2d2e+ab2e2+c2de2,
+   abc5-b4c2d-2a2b2cde+ac3d2e-a4de2+bcd2e3+abe5,
+   ab2c4-b5cd-a2b3de+2abc2d2e+ad4e2-a2bce3-cde5,
+   a3b2cd-bc2d4+ab2c3e-b5de-d6e+3abcd2e2-a2be4-de6,
+   a4b2c-abc2d3-ab5e-b3c2de-ad5e+2a2bcde2+cd2e4,
+   b6c+bc6+a2b4e-3ab2c2de+c4d2e-a3cde2-abd3e2+bce5;
+
+   list pr=normalizationPrimes(i);
+   def r1 = pr[1];
+   setring r1;
+   norid;
+   normap;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static proc substpart(ideal endid, ideal endphi, int homo, intvec rw)
+
+"//Repeated application of elimpart to endid, until no variables can be
+//directy substituded. homo=1 if input is homogeneous, rw contains
+//original weights, endphi (partial) normalization map";
+
+//NOTE concerning iteration of maps: Let phi: x->f(y,z), y->g(x,z) then
+//phi: x+y+z->f(y,z)+g(x,z)+z, phi(phi):x+y+z->f(g(x,z),z)+g(f(y,z),z)+z
+//and so on: none of the x or y will be eliminated
+//Now subst: first x and then y: x+y+z->f(g(x,z),z)+g(x,z)+z eliminates y
+//further subst replaces x by y, makes no sense (objects more compicated).
+//Subst first y and then x eliminates x
+//In our situation we have triangular form: x->f(y,z), y->g(z).
+//phi: x+y+z->f(y,z)+g(z)+z, phi(phi):x+y+z->f(g(z),z)+g(z)+z eliminates x,y
+//subst x,y: x+y+z->f(g(z),z)+g(z)+z, eliminates x,y
+//subst y,x: x+y+z->f(y,z)+g(z)+z eliminates only x
+//HENCE: substitute vars depending on most other vars first
+//However, if the sytem xi-fi is reduced then xi does not appear in any of the
+//fj and hence the order does'nt matter when substitutinp xi by fi
+
+{
+   ASSUME(1, not isQuotientRing(basering) );
+
+   def newRing = basering;
+   int ii,jj;
+   map phi = newRing,maxideal(1);    //identity map
+   list Le = elimpart(endid);
+   //this proc and the next loop try to substitute as many variables as
+   //possible indices of substituted variables
+
+   int q = size(Le[2]);    //q vars, stored in Le[2], have been substitutet
+   intvec rw1 = 0;         //will become indices of substituted variables
+   rw1[nvars(basering)] = 0;
+   rw1 = rw1+1;            //rw1=1,..,1 (as many 1 as nvars(basering))
+
+   while( size(Le[2]) != 0 )
+   {
+      endid = Le[1];
+      if ( defined(ps) )
+      { kill ps; }
+      map ps = newRing,Le[5];
+      phi = ps(phi);
+      for(ii=1;ii<=size(Le[2]);ii++)
+      {
+         phi=phi(phi);
+      }
+      //eingefuegt wegen x2-y2z2+z3
+
+      for( ii=1; ii<=size(rw1); ii++ )
+      {
+         if( Le[4][ii]==0 )        //ii = index of var which was substituted
+         {
+            rw1[ii]=0;             //substituted vars have entry 0 in rw1
+         }
+      }
+      Le=elimpart(endid);          //repeated application of elimpart
+      q = q + size(Le[2]);
+   }
+   endphi = phi(endphi);
+//---------- return -----------------------------------------------------------
+// first the trivial case, where all variable have been eliminated
+   if( nvars(newRing) == q )
+   {
+     ring lastRing = char(basering),T(1),dp;
+     ideal endid = T(1);
+     ideal endphi = T(1);
+     for(ii=2; ii<=q; ii++ )
+     {
+        endphi[ii] = 0;
+     }
+     export(endid,endphi);
+     list L = lastRing;
+     setring newRing;
+     return(L);
+   }
+
+// in the homogeneous case put weights for the remaining vars correctly, i.e.
+// delete from rw those weights for which the corresponding entry of rw1 is 0
+
+   if (homo==1 && nvars(newRing)-q >1 && size(endid) >0 )
+   {
+      jj=1;
+      for( ii=2; ii<size(rw1); ii++)
+      {
+         jj++;
+         if( rw1[ii]==0 )
+         {
+            rw=rw[1..jj-1],rw[jj+1..size(rw)];
+            jj=jj-1;
+         }
+      }
+      if( rw1[1]==0 ) { rw=rw[2..size(rw)]; }
+      if( rw1[size(rw1)]==0 ){ rw=rw[1..size(rw)-1]; }
+
+      ring lastRing = char(basering),(T(1..nvars(newRing)-q)),(a(rw),dp);
+   }
+   else
+   {
+      ring lastRing = char(basering),(T(1..nvars(newRing)-q)),dp;
+   }
+   ideal lastmap;
+   jj = 1;
+
+   for(ii=1; ii<=size(rw1); ii++ )
+   {
+      if ( rw1[ii]==1 ) { lastmap[ii] = T(jj); jj=jj+1; }
+      if ( rw1[ii]==0 ) { lastmap[ii] = 0; }
+   }
+   map phi1 = newRing,lastmap;
+   ideal endid  = phi1(endid);      //### bottelneck
+   ideal endphi = phi1(endphi);
+
+/*
+Versuch: subst statt phi
+   for(ii=1; ii<=size(rw1); ii++ )
+   {
+      if ( rw1[ii]==1 ) { endid = subst(endid,var(ii),T(jj)); }
+      if ( rw1[ii]==0 ) { endid = subst(endid,var(ii),0); }
+   }
+*/
+   export(endid);
+   export(endphi);
+   list L = lastRing;
+   setring newRing;
+   return(L);
+}
+///////////////////////////////////////////////////////////////////////////////
+static proc deltaP(ideal I)
+{
+   ASSUME(1, not isQuotientRing(basering) );
+   def R=basering;
+   int c,d,i;
+   int n=nvars(R);
+   list nor;
+   if(size(I)>1){ERROR("no hypersurface");}
+   ideal J=std(slocus(I));
+   if(dim(J)<=0){return(0);}
+   poly h;
+   d=1;
+   while((d)&&(i<n))
+   {
+      i++;
+      h=var(i);
+      d=dim(std(J+ideal(h)));
+   }
+   i=0;
+   while(d)
+   {
+      i++;
+      if(i>10){ERROR("delta not found, please inform the authors")};
+      h=randomLast(100)[n];
+      d=dim(std(J+ideal(h)));
+   }
+   I=I,h-1;
+   if(char(R)<=19)
+   {
+      nor=normalP(I);
+   }
+   else
+   {
+      nor=normal(I);
+   }
+   return(nor[2][2]);
+}
+
+proc genus(ideal I,list #)
+"USAGE:   genus(I) or genus(I,<option>); I a 1-dimensional ideal over a perfect field
+RETURN:  an integer, the geometric genus p_g = p_a - delta of the projective
+         curve defined by i, where p_a is the arithmetic genus.
+NOTE:    genus always treats projective curves and takes projective closure if input is affine 1-dim variety.
+         delta is the sum of all local delta-invariants of the singularities,
+         i.e. dim(R'/R), R' the normalization of the local ring R of the
+         singularity. @*
+         genus(I,"nor") uses the normalization to compute delta. Usually genus(I,"nor")
+         is slower than genus(I) but sometimes not. @*
+         genus(I,"pri") starts with a primary decompsition.
+EXAMPLE: example genus; shows an example
+"
+{
+   ASSUME(0, not isQuotientRing(basering) );
+   if ( string(minpoly) !="0" )
+   {
+      ERROR("genus does not yet support extension fields");
+   }
+
+   int w = printlevel-voice+2;  // w=printlevel (default: w=0)
+
+   int ono,rpr,ll;
+   if(size(#)>0)
+   {
+     if(typeof(#[1])=="string")
+     {
+        if(#[1]=="nor"){ono=1;}
+        if(#[1]=="pri"){rpr=1;}
+     }
+     else { ERROR("invalid option for genus");}
+   }
+   def R0=basering;
+   if((char(basering)>0)||(ono))
+   {
+     def R1=changeord(list(list("dp",1:nvars(basering))));
+     setring R1;
+     ideal I=imap(R0,I);
+     I=radical(I);
+     I=std(I);
+     if(dim(I)!=1)
+     {
+       if(((homog(I))&&(dim(I)!=2))||(!homog(I)))
+       {
+         ERROR("This is not a curve");
+       }
+     }
+     if(homog(I)&&(dim(I)==2))
+     {
+       def S=R0;
+       setring S;
+       ideal J=I;
+     }
+     else
+     {
+       def S=changevar(varstr(R0)+", at t");
+       setring S;
+       ideal J=imap(R1,I);
+       J=homog(J, at t);
+       J=std(J);
+     }
+
+     list LL=normal(J,"prim");
+     int pa,i;
+     for(i=1;i<=size(LL[1]);i++)
+     {
+        def T=LL[1][i];
+        setring T;
+        pa=pa-hilbPoly(std(norid))[1];
+        setring S;
+        kill T;
+     }
+     pa=pa+1;
+     setring R0;
+     return(pa);
+   }
+   if(rpr)
+   {
+      list LZ=minAssGTZ(I);
+      if(size(LZ)>1)
+      {
+         int p_g;
+         for(ll=1;ll<=size(LZ);ll++)
+         {
+            p_g=p_g+genus(LZ[ll],"pri")-1;
+         }
+         return(p_g+1);
+      }
+      else
+      {
+         I=LZ[1];
+      }
+   }
+   else
+   {
+     I=radical(I);
+   }
+   I=std(I);
+   if(dim(I)!=1)
+   {
+      if(((homog(I))&&(dim(I)!=2))||(!homog(I)))
+      {
+        // ERROR("This is not a curve");
+        if(w==1){"** WARNING: Input does not define a curve **"; "";}
+      }
+   }
+   list L=elimpart(I);
+   if(size(L[2])!=0)
+   {
+      map psi=R0,L[5];
+      I=std(psi(I));
+   }
+   if(size(I)==0)
+   {
+      return(0);
+   }
+   list N=findvars(I,0);
+   if(size(N[1])==1)
+   {
+      poly p=I[1];
+     // if(deg(squarefree(p))<deg(p)){ERROR("Curve is not reduced");}
+      return(-deg(p)+1);
+   }
+   if(size(N[1]) < nvars(R0))
+   {
+     string newvar=string(N[1]);
+     execute("ring R=("+charstr(R0)+"),("+newvar+"),dp;");
+     ideal I =imap(R0,I);
+     if((ringlist(R0)[3][1][1]=="dp")&&(size(ringlist(R0)[3])==2))
+     {
+       attrib(I,"isSB",1);
+     }
+     else
+     {
+       I=std(I);
+     }
+   }
+   else
+   {
+     def R=changeord(list(list("dp",1:nvars(basering))));
+     setring R;
+     ideal I=imap(R0,I);
+     I=std(I);
+   }
+   if(dim(I)==2)
+   {
+      def newR=basering;
+   }
+   else
+   {
+      short=0;
+      string smp = string(minpoly);
+      if(dim(I)==0)
+      {
+         execute("ring Rhelp=("+charstr(R0)+"),(@s, at t),dp;");
+      }
+      else
+      {
+         execute("ring Rhelp=("+charstr(R0)+"),(@s),dp;");
+      }
+      if (smp!="0")
+      { execute("minpoly = "+smp+";");}
+      def newR=R+Rhelp;
+      setring newR;
+      ideal I=imap(R,I);
+      I=homog(I, at s);
+      attrib(I,"isSB",1);
+   }
+
+   if((nvars(basering)<=3)&&(size(I)>1))
+   {
+       ERROR("This is not equidimensional");
+   }
+
+   intvec hp=hilbPoly(I);
+   int p_a=1-hp[1];
+   int d=hp[2];
+
+   if(w>=1)
+   {
+      "";"The ideal of the projective curve:";"";I;"";
+      "The coefficients of the Hilbert polynomial";hp;
+      "arithmetic genus:";p_a;
+      "degree:";d;"";
+   }
+
+   intvec v = hilb(I,1);
+   int i,o;
+   if(nvars(basering)>3)
+   {
+      map phi=newR,maxideal(1);
+      int de;
+      ideal K,L1;
+      matrix M;
+      poly m=var(4);
+      poly he;
+      for(i=5;i<=nvars(basering);i++){m=m*var(i);}
+      K=eliminate(I,m,v);
+      if(size(K)==1){de=deg(K[1]);}
+      m=var(1);
+      for(i=2;i<=nvars(basering)-3;i++){m=m*var(i);}
+      i=0;
+      while(d!=de)
+      {
+         o=1;
+         i++;
+         K=phi(I);
+         K=eliminate(K,m,v);
+         if(size(K)==1){de=deg(K[1]);}
+         if((i==5)&&(d!=de))
+         {
+            K=reduce(equidimMax(I),I);
+            if(size(K)!=0){ERROR("This is not equidimensional");}
+         }
+         if(i==10)
+         {
+            J;K;
+            ERROR("genus: did not find a good projection for to
+                           the plain");
+         }
+         if(i<5)
+         {
+            M=sparsetriag(nvars(newR),nvars(newR),80-5*i,i);
+         }
+         else
+         {
+            if(i<8)
+            {
+               M=transpose(sparsetriag(nvars(newR),nvars(newR),80-5*i,i));
+            }
+            else
+            {
+               he=0;
+               while(he==0)
+               {
+                  M=randommat(nvars(newR),nvars(newR),ideal(1),20);
+                  he=det(M);
+               }
+            }
+         }
+         L1=M*transpose(maxideal(1));
+         phi=newR,L1;
+      }
+      I=K;
+   }
+   poly p=I[1];
+
+   execute("ring S=("+charstr(R)+"),(x,y,t),dp;");
+   ideal L=maxideal(1);
+   execute("ring C=("+charstr(R)+"),(x,y),ds;");
+   ideal I;
+   execute("ring A=("+charstr(R)+"),(x,t),dp;");
+   map phi=S,1,x,t;
+   map psi=S,x,1,t;
+   poly g,h;
+   ideal I,I1;
+   execute("ring B=("+charstr(R)+"),(x,t),ds;");
+
+   setring S;
+   if(o)
+   {
+     for(i=1;i<=nvars(newR)-3;i++){L[i]=0;}
+     L=L,maxideal(1);
+   }
+   map sigma=newR,L;
+   poly F=sigma(p);
+   if(w>=1){"the projected curve:";"";F;"";}
+
+   kill newR;
+
+   int genus=(d-1)*(d-2) div 2;
+   if(w>=1){"the arithmetic genus of the plane curve:";genus;pause();}
+
+   int delt,deltaloc,deltainf,tau,tauinf,cusps,iloc,iglob,l,nsing,
+       tauloc,tausing,k,rat,nbranchinf,nbranch,nodes,cuspsinf,nodesinf;
+   list inv;
+
+   if(w>=1)
+     {"";"analyse the singularities at oo";"";"singular locus at (1,x,0):";"";}
+   setring A;
+   g=phi(F);
+   h=psi(F);
+   I=g,jacob(g),var(2);
+   I=std(I);
+   if(deg(I[1])>0)
+   {
+      list qr=minAssGTZ(I);
+      if(w>=1){qr;"";}
+
+      for(k=1;k<=size(qr);k++)
+      {
+         if(w>=1){ nsing=nsing+vdim(std(qr[k]));}
+         inv=deltaLoc(g,qr[k]);
+         deltainf=deltainf+inv[1];
+         tauinf=tauinf+inv[2];
+         l=vdim(std(qr[k]));
+         if(inv[2]==l){nodesinf=nodesinf+l;}
+         if(inv[2]==2*l){cuspsinf=cuspsinf+l;}
+         nbranchinf=nbranchinf+inv[3];
+      }
+   }
+   else
+   {
+     if(w>=1){"            the curve is smooth at (1,x,0)";"";}
+   }
+   if(w>=1){"singular locus at (0,1,0):";"";}
+   inv=deltaLoc(h,maxideal(1));
+   if((w>=1)&&(inv[2]!=0)){ nsing++;}
+   deltainf=deltainf+inv[1];
+   tauinf=tauinf+inv[2];
+   if(inv[2]==1){nodesinf++;}
+   if(inv[2]==2){cuspsinf++;}
+
+   if((w>=1)&&(inv[2]==0)){"            the curve is smooth at (0,1,0)";"";}
+   if(inv[2]>0){nbranchinf=nbranchinf+inv[3];}
+
+   if(w>=1)
+   {
+      if(tauinf==0)
+      {
+        "            the curve is smooth at oo";"";
+      }
+      else
+      {
+         "number of singularities at oo:";nsing;
+         "nodes at oo:";nodesinf;
+         "cusps at oo:";cuspsinf;
+         "branches at oo:";nbranchinf;
+         "Tjurina number at oo:";tauinf;
+         "delta at oo:";deltainf;
+         "Milnor number at oo:";2*deltainf-nbranchinf+nsing;
+         pause();
+      }
+      "singularities at (x,y,1):";"";
+   }
+   execute("ring newR=("+charstr(R)+"),(x,y),dp;");
+   //the singularities at the affine part
+   map sigma=S,var(1),var(2),1;
+   ideal I=sigma(F);
+
+   ideal I1=jacob(I);
+   matrix Hess[2][2]=jacob(I1);
+   ideal ID=I+I1+ideal(det(Hess));//singular locus of I+I1
+
+   ideal radID=std(radical(ID));//the non-nodal locus
+   if(w>=1){"the non-nodal locus:";"";radID;pause();"";}
+   if(deg(radID[1])==0)
+   {
+     ideal IDsing=1;
+   }
+   else
+   {
+     ideal IDsing=minor(jacob(ID),2)+radID;//singular locus of ID
+   }
+
+   iglob=vdim(std(IDsing));
+
+   if(iglob!=0)//computation of the radical of IDsing
+   {
+      ideal radIDsing=reduce(IDsing,radID);
+      if(size(radIDsing)==0)
+      {
+         radIDsing=radID;
+         attrib(radIDsing,"isSB",1);
+      }
+      else
+      {
+         radIDsing=std(radical(IDsing));
+      }
+      iglob=vdim(radIDsing);
+      if((w>=1)&&(iglob))
+          {"the non-nodal-cuspidal locus:";radIDsing;pause();"";}
+   }
+   cusps=vdim(radID)-iglob;
+   nsing=nsing+cusps;
+
+   if(iglob==0)
+   {
+      if(w>=1){"             there are only cusps and nodes";"";}
+      tau=vdim(std(I+jacob(I)));
+      tauinf=tauinf+tau;
+      nodes=tau-2*cusps;
+      delt=nodes+cusps;
+      nbranch=2*tau-3*cusps;
+      nsing=nsing+nodes;
+   }
+   else
+   {
+       if(w>=1){"the non-nodal-cuspidal singularities";"";}
+       setring C;
+       ideal I1=imap(newR,radIDsing);
+       iloc=vdim(std(I1));
+       if(iglob==iloc)
+       {
+          if(w>=1){"only cusps and nodes outside (0,0,1)";}
+          setring newR;
+          tau=vdim(std(I+jacob(I)));
+          tauinf=tauinf+tau;
+          inv=deltaLoc(I[1],maxideal(1));
+          delt=inv[1];
+          tauloc=inv[2];
+          nodes=tau-tauloc-2*cusps;
+          nsing=nsing+nodes;
+          if (inv[2]!=0) { nsing++; }
+          nbranch=inv[3]+ 2*nodes+cusps;
+          delt=delt+nodes+cusps;
+          if((w>=1)&&(inv[2]==0)){"smooth at (0,0,1)";}
+        }
+        else
+        {
+           setring newR;
+           list pr=minAssGTZ(radIDsing);
+           if(w>=1){pr;}
+
+           for(k=1;k<=size(pr);k++)
+           {
+              if(w>=1){nsing=nsing+vdim(std(pr[k]));}
+              inv=deltaLoc(I[1],pr[k]);
+              delt=delt+inv[1];
+              tausing=tausing+inv[2];
+              nbranch=nbranch+inv[3];
+           }
+           tau=vdim(std(I+jacob(I)));
+           tauinf=tauinf+tau;
+           nodes=tau-tausing-2*cusps;
+           nsing=nsing+nodes;
+           delt=delt+nodes+cusps;
+           nbranch=nbranch+2*nodes+cusps;
+        }
+   }
+   genus=genus-delt-deltainf;
+   if(w>=1)
+   {
+      "The projected plane curve has locally:";"";
+      "singularities:";nsing;
+      "branches:";nbranch+nbranchinf;
+      "nodes:"; nodes+nodesinf;
+      "cusps:";cusps+cuspsinf;
+      "Tjurina number:";tauinf;
+      "Milnor number:";2*(delt+deltainf)-nbranch-nbranchinf+nsing;
+      "delta of the projected curve:";delt+deltainf;
+      "delta of the curve:";p_a-genus;
+      "genus:";genus;
+      "====================================================";
+      "";
+   }
+   setring R0;
+   return(genus);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r=0,(x,y),dp;
+   ideal i=y^9 - x^2*(x - 1)^9;
+   genus(i);
+   ring r7=7,(x,y),dp;
+   ideal i=y^9 - x^2*(x - 1)^9;
+   genus(i);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+proc deltaLoc(poly f,ideal singL)
+"USAGE:  deltaLoc(f,J);  f poly, J ideal
+ASSUME: f is reduced bivariate polynomial; basering has exactly two variables;
+        J is irreducible prime component of the singular locus of f (e.g., one
+        entry of the output of @code{minAssGTZ(I);}, I = <f,jacob(f)>).
+RETURN:  list L:
+ at texinfo
+ at table @asis
+ at item @code{L[1]}; int:
+         the sum of (local) delta invariants of f at the (conjugated) singular
+         points given by J.
+ at item @code{L[2]}; int:
+         the sum of (local) Tjurina numbers of f at the (conjugated) singular
+         points given by J.
+ at item @code{L[3]}; int:
+         the sum of (local) number of branches of f at the (conjugated)
+         singular points given by J.
+ at end table
+ at end texinfo
+NOTE:    procedure makes use of @code{execute}; increasing printlevel displays
+         more comments (default: printlevel=0).
+SEE ALSO: delta, tjurina
+KEYWORDS: delta invariant; Tjurina number
+EXAMPLE: example deltaLoc;  shows an example
+"
+{
+   ASSUME(0, not isQuotientRing(basering) );
+
+   intvec save_opt=option(get);
+   option(redSB);
+   def R=basering;
+   execute("ring S=("+charstr(R)+"),(x,y),lp;");
+   map phi=R,x,y;
+   ideal singL=phi(singL);
+   singL=simplify(std(singL),1);
+   attrib(singL,"isSB",1);
+   int d=vdim(singL);
+   poly f=phi(f);
+   int i;
+   int w = printlevel-voice+2;  // w=printlevel (default: w=0)
+   if(d==1)
+   {
+      map alpha=S,var(1)-singL[2][2],var(2)-singL[1][2];
+      f=alpha(f);
+      execute("ring C=("+charstr(S)+"),("+varstr(S)+"),ds;");
+      poly f=imap(S,f);
+      ideal singL=imap(S,singL);
+      if((w>=1)&&(ord(f)>=2))
+      {
+        "local analysis of the singularities";"";
+        basering;
+        singL;
+        f;
+        pause();
+      }
+   }
+   else
+   {
+      poly p;
+      poly c;
+      map psi;
+      number co;
+
+      while((deg(lead(singL[1]))>1)&&(deg(lead(singL[2]))>1))
+      {
+         psi=S,x,y+random(-100,100)*x;
+         singL=psi(singL);
+         singL=std(singL);
+          f=psi(f);
+      }
+
+      if(deg(lead(singL[2]))==1)
+      {
+         p=singL[1];
+         c=singL[2]-lead(singL[2]);
+         co=leadcoef(singL[2]);
+      }
+      if(deg(lead(singL[1]))==1)
+      {
+         psi=S,y,x;
+         f=psi(f);
+         singL=psi(singL);
+         p=singL[2];
+         c=singL[1]-lead(singL[1]);
+         co=leadcoef(singL[1]);
+      }
+
+      execute("ring B=("+charstr(S)+"),a,dp;");
+      map beta=S,a,a;
+      poly p=beta(p);
+
+      execute("ring C=("+charstr(S)+",a),("+varstr(S)+"),ds;");
+      number p=number(imap(B,p));
+
+      minpoly=p;
+      map iota=S,a,a;
+      number c=number(iota(c));
+      number co=iota(co);
+
+      map alpha=S,x-c/co,y+a;
+      poly f=alpha(f);
+      f=cleardenom(f);
+      if((w>=1)&&(ord(f)>=2))
+      {
+        "local analysis of the singularities";"";
+        basering;
+        alpha;
+        f;
+        pause();
+        "";
+      }
+   }
+   option(noredSB);
+   ideal fstd=std(ideal(f)+jacob(f));
+   poly hc=highcorner(fstd);
+   int tau=vdim(fstd);
+   int o=ord(f);
+   int delt,nb;
+
+   if(tau==0)                 //smooth case
+   {
+      setring R;
+      option(set,save_opt);
+      return(list(0,0,1));
+   }
+   if((char(basering)>=181)||(char(basering)==0))
+   {
+      if(o==2)                //A_k-singularity
+      {
+        if(w>=1){"A_k-singularity";"";}
+         setring R;
+         delt=(tau+1) div 2;
+         option(set,save_opt);
+         return(list(d*delt,d*tau,d*(2*delt-tau+1)));
+      }
+      if((lead(f)==var(1)*var(2)^2)||(lead(f)==var(1)^2*var(2)))
+      {
+        if(w>=1){"D_k- singularity";"";}
+
+         setring R;
+         delt=(tau+2) div 2;
+         option(set,save_opt);
+         return(list(d*delt,d*tau,d*(2*delt-tau+1)));
+      }
+
+      int mu=vdim(std(jacob(f)));
+
+      poly g=f+var(1)^mu+var(2)^mu;  //to obtain a convenient Newton-polygon
+
+      list NP=newtonpoly(g);
+      if(w>=1){"Newton-Polygon:";NP;"";}
+      int s=size(NP);
+
+      if(is_NND(f,mu,NP))
+      { // the Newton-polygon is non-degenerate
+        // compute nb, the number of branches
+        for(i=1;i<=s-1;i++)
+        {
+          nb=nb+gcd(NP[i][2]-NP[i+1][2],NP[i][1]-NP[i+1][1]);
+        }
+        if(w>=1){"Newton-Polygon is non-degenerated";"";}
+        setring R;
+        option(set,save_opt);
+        return(list(d*(mu+nb-1) div 2,d*tau,d*nb));
+      }
+
+      if(w>=1){"Newton-Polygon is degenerated";"";}
+/* need to re-consider the degree bound (de):
+      // the following can certainly be made more efficient when replacing
+      // 'hnexpansion' (used only for computing number of branches) by
+      // successive blowing-up + test if Newton polygon degenerate:
+      if(s>2)    //  splitting of f
+      {
+         if(w>=1){"Newton polygon can be used for splitting";"";}
+         intvec v=NP[1][2]-NP[2][2],NP[2][1];
+         int de=w_deg(g,v);
+         //int st=w_deg(hc,v)+v[1]+v[2];
+         int st=w_deg(var(1)^NP[size(NP)][1],v)+1;
+         poly f1=var(2)^NP[2][2];
+         poly f2=jet(g,de,v)/var(2)^NP[2][2];
+         poly h=g-f1*f2;
+         de=w_deg(h,v);
+         poly k;
+         ideal wi=var(2)^NP[2][2],f2;
+         matrix li;
+         while(de<st)
+         {
+           k=jet(h,de,v);
+           li=lift(wi,k);
+           f1=f1+li[2,1];
+           f2=f2+li[1,1];
+           h=g-f1*f2;
+           de=w_deg(h,v);
+         }
+         nb=deltaLoc(f1,maxideal(1))[3]+deltaLoc(f2,maxideal(1))[3];
+
+         setring R;
+         option(set,save_opt);
+         return(list(d*(mu+nb-1) div 2,d*tau,d*nb));
+      }
+*/
+      f=jet(f,deg(hc)+2);
+      if(w>=1){"now we have to use Hamburger-Noether (Puiseux) expansion";}
+      ideal fac=factorize(f,1);
+      if(size(fac)>1)
+      {
+         nb=0;
+         for(i=1;i<=size(fac);i++)
+         {
+            nb=nb+deltaLoc(fac[i],maxideal(1))[3];
+         }
+         setring R;
+         option(set,save_opt);
+         return(list(d*(mu+nb-1) div 2,d*tau,d*nb));
+      }
+      list HNEXP=hnexpansion(f);
+      if (typeof(HNEXP[1])=="ring")
+      {
+        def altring = basering;
+        def HNEring = HNEXP[1]; setring HNEring;
+        nb=size(hne);
+        setring R;
+        kill HNEring;
+      }
+      else
+      {
+        nb=size(HNEXP);
+      }
+      setring R;
+      option(set,save_opt);
+      return(list(d*(mu+nb-1) div 2,d*tau,d*nb));
+   }
+   else             //the case of small characteristic
+   {
+      f=jet(f,deg(hc)+2);
+      if(w>=1){"now we have to use Hamburger-Noether (Puiseux) expansion";}
+      delt=delta(f);
+      setring R;
+      option(set,save_opt);
+      return(list(d*delt,d*tau,d));
+   }
+   option(set,save_opt);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring r=0,(x,y),dp;
+  poly f=(x2+y^2-1)^3 +27x2y2;
+  ideal I=f,jacob(f);
+  I=std(I);
+  list qr=minAssGTZ(I);
+  size(qr);
+  // each component of the singular locus either describes a cusp or a pair
+  // of conjugated nodes:
+  deltaLoc(f,qr[1]);
+  deltaLoc(f,qr[2]);
+  deltaLoc(f,qr[3]);
+  deltaLoc(f,qr[4]);
+  deltaLoc(f,qr[5]);
+  deltaLoc(f,qr[6]);
+}
+///////////////////////////////////////////////////////////////////////////////
+// compute the weighted degree of p;
+// this code is an exact copy of the proc in paraplanecurves.lib
+// (since we do not want to make it non-static)
+static proc w_deg(poly p, intvec v)
+{
+   if(p==0){return(-1);}
+   int d=0;
+   while(jet(p,d,v)==0){d++;}
+   d=(transpose(leadexp(jet(p,d,v)))*v)[1];
+   return(d);
+}
+
+//proc hilbPoly(ideal J)
+//{
+//   poly hp;
+//   int i;
+//   if(!attrib(J,"isSB")){J=std(J);}
+//   intvec v = hilb(J,2);
+//   for(i=1; i<=size(v); i++){ hp=hp+v[i]*(var(1)-i+2);}
+//   return(hp);
+//}
+
+
+//////////////////////////////////////////////////////////////////////////////
+
+proc primeClosure (list L, list #)
+"USAGE:    primeClosure(L [,c]); L a list of a ring containing a prime ideal
+          ker, c an optional integer
+RETURN:   a list L (of size n+1) consisting of rings L[1],...,L[n] such that
+          - L[1] is a copy of (not a reference to!) the input ring L[1]
+          - all rings L[i] contain ideals ker, L[2],...,L[n] contain ideals phi
+            such that
+                    L[1]/ker --> ... --> L[n]/ker
+            are injections given by the corresponding ideals phi, and L[n]/ker
+            is the integral closure of L[1]/ker in its quotient field.
+          - all rings L[i] contain a polynomial nzd such that elements of
+            L[i]/ker are quotients of elements of L[i-1]/ker with denominator
+            nzd via the injection phi.
+            L[n+1] is the delta invariant
+NOTE:     - L is constructed by recursive calls of primeClosure itself.
+          - c determines the choice of nzd:
+               - c not given or equal to 0: first generator of the ideal SL,
+                 the singular locus of Spec(L[i]/ker)
+               - c<>0: the generator of SL with least number of monomials.
+EXAMPLE:  example primeClosure; shows an example
+"
+{
+  //---- Start with a consistency check:
+
+  if (!(typeof(L[1])=="ring"))
+  {
+      "// Parameter must be a ring or a list containing a ring!";
+      return(-1);
+  }
+
+  int dblvl = printlevel-voice+2;
+  list gnirlist = ringlist(basering);
+
+  //---- Some auxiliary variables:
+  int delt;                      //finally the delta invariant
+  if ( size(L) == 1 )
+  {
+      L[2] = delt;              //set delta to 0
+  }
+  int n = size(L)-1;            //L without delta invariant
+
+  //---- How to choose the non-zerodivisor later on?
+
+  int nzdoption=0;
+  if (size(#)>0)
+  {
+      nzdoption=#[1];
+  }
+
+// R0 below is the ring to work with, if we are in step one, make a copy of the
+// input ring, so that all objects are created in the copy, not in the original
+// ring (therefore a copy, not a reference is defined).
+
+  if (n==1)
+  {
+      def R = L[1];
+      list Rlist = ringlist(R);
+      def BAS = basering;
+      setring R;
+      if (!(typeof(ker)=="ideal"))
+      {
+          "// No ideal ker in the input ring!";
+          return (-1);
+      }
+      ker=simplify(interred(ker),15);
+      //execute ("ring R0="+charstr(R)+",("+varstr(R)+"),("+ordstr(R)+");");
+      // Rlist may be not defined in this new ring, so we define it again.
+      list Rlist2 = ringlist(R);
+      def R0 = ring(Rlist2);
+      setring R0;
+      ideal ker=fetch(R,ker);
+      // check whether we compute the normalization of the blow up of
+      // an isolated singularity at the origin (checked in normalI)
+
+      if (typeof(attrib(L[1],"iso_sing_Rees"))=="int")
+      {
+        attrib(R0,"iso_sing_Rees",attrib(L[1],"iso_sing_Rees"));
+      }
+      L[1]=R0;
+  }
+  else
+  {
+      def R0 = L[n];
+      setring R0;
+  }
+
+// In order to apply HomJJ from normal.lib, we need the radical of the singular
+// locus of ker, J:=rad(ker):
+
+   list SM=mstd(ker);
+
+// In the first iteration, we have to compute the singular locus "from
+// scratch".
+// In further iterations, we can fetch it from the previous one but
+// have to compute its radical
+// the next rings R1 contain already the (fetched) ideal
+
+  if (n==1)                              //we are in R0=L[1]
+  {
+      if (typeof(attrib(R0,"iso_sing_Rees"))=="int")
+      {
+        ideal J;
+        for (int s=1;s<=attrib(R0,"iso_sing_Rees");s++)
+        {
+          J=J,var(s);
+        }
+        J = J,SM[2];
+        list JM = mstd(J);
+      }
+      else
+      {
+        if ( dblvl >= 1 )
+        {"";
+           "// compute the singular locus";
+        }
+        //### Berechnung des singulaeren Orts geaendert (ist so schneller)
+        ideal J = minor(jacob(SM[2]),nvars(basering)-dim(SM[1]),SM[1]);
+        J = J,SM[2];
+        list JM = mstd(J);
+      }
+
+      if ( dblvl >= 1 )
+      {"";
+         "// dimension of singular locus is", dim(JM[1]);
+         if (  dblvl >= 2 )
+         {"";
+            "// the singular locus is:"; JM[2];
+         }
+      }
+
+      if ( dblvl >= 1 )
+      {"";
+         "// compute radical of singular locus";
+      }
+
+      J = simplify(radical(JM[2]),2);
+      if ( dblvl >= 1 )
+      {"";
+         "// radical of singular locus is:"; J;
+         pause();
+      }
+  }
+  else
+  {
+      if ( dblvl >= 1 )
+      {"";
+         "// compute radical of test ideal in ideal of singular locus";
+      }
+      J = simplify(radical(J),2);
+      if ( dblvl >= 1 )
+      {"";
+         "// radical of test ideal is:"; J;
+         pause();
+      }
+  }
+
+  // having computed the radical J of/in the ideal of the singular locus,
+  // we now need to pick an element nzd of J;
+  // NOTE: nzd must be a non-zero divisor mod ker, i.e. not contained in ker
+
+  poly nzd = J[1];
+  poly nzd1 = NF(nzd,SM[1]);
+  if (nzd1 != 0)
+  {
+     if ( deg(nzd)>=deg(nzd1) && size(nzd)>size(nzd1) )
+     {
+        nzd = nzd1;
+     }
+  }
+
+  if (nzdoption || nzd1==0)
+  {
+    for (int ii=2;ii<=ncols(J);ii++)
+    {
+      nzd1 = NF(J[ii],SM[1]);
+      if ( nzd1 != 0 )
+      {
+        if ( (deg(nzd)>=deg(J[ii])) && (size(nzd)>size(J[ii])) )
+        {
+          nzd=J[ii];
+        }
+        if ( deg(nzd)>=deg(nzd1) && size(nzd)>size(nzd1) )
+        {
+          nzd = nzd1;
+        }
+      }
+    }
+  }
+
+  export nzd;
+  // In this case we do not eliminate variables, so that the maps
+  // are well defined.
+  list RR = SM[1],SM[2],J,nzd,1;
+
+  if ( dblvl >= 1 )
+  {"";
+     "// compute the first ring extension:";
+     "RR: ";
+     RR;
+  }
+
+  list RS = HomJJ(RR);
+  //NOTE: HomJJ creates new ring with variables X(i) and T(j)
+//-------------------------------------------------------------------------
+// If we've reached the integral closure (as determined by the result of
+// HomJJ), then we are done, otherwise we have to prepare the next iteration.
+
+  if (RS[2]==1)     // we've reached the integral closure, we are still in R0
+    {
+      kill J;
+      if ( n== 1)
+      {
+        def R1 = RS[1];
+        setring R1;
+        ideal norid, normap = endid, endphi;
+        kill endid,  endphi;
+
+        //"//### case: primeClosure, final";
+        //"size norid:", size(norid), size(string(norid));
+        //"interred:";
+        //norid = interred(norid);
+        //"size norid:", size(norid), size(string(norid));
+
+        export (norid, normap);
+        L[1] = R1;
+      }
+      return(L);
+    }
+  else                        // prepare the next iteration
+    {
+      if (n==1)               // In the first iteration: keep only the data
+      {                       // needed later on.
+         kill RR,SM;
+         export(ker);
+      }
+      if ( dblvl >= 1 )
+      {"";
+         "// computing the next ring extension, we are in loop"; n+1;
+      }
+
+      def R1 = RS[1];         // The data of the next ring R1:
+      delt = RS[3];           // the delta invariant of the ring extension
+      setring R1;             // keep only what is necessary and kill
+      ideal ker=endid;        // everything else.
+      export(ker);
+      ideal norid=endid;
+
+      //"//### case: primeClosure, loop", n+1;
+      //"size norid:", size(norid), size(string(norid));
+      //"interred:";
+      //norid = interred(norid);        //????
+      //"size norid:", size(norid), size(string(norid));
+
+      export(norid);
+      kill endid;
+
+      map phi = R0,endphi;                        // fetch the singular locus
+      ideal J = mstd(simplify(phi(J)+ker,4))[2];  // ideal J in R1
+      export(J);
+      if(n>1)
+      {
+         ideal normap=phi(normap);
+      }
+      else
+      {
+         ideal normap=endphi;
+      }
+      export(normap);
+      kill phi;              // we save phi as ideal, not as map, so that
+      ideal phi=endphi;      // we have more flexibility in the ring names
+      kill endphi;           // later on.
+      export(phi);
+      L=insert(L,R1,n);       // Add the new ring R1 and go on with the
+                              // next iteration
+      if ( L[size(L)] >= 0 && delt >= 0 )
+      {
+         delt = L[size(L)] + delt;
+      }
+      else
+      {
+         delt = -1;
+      }
+      L[size(L)] = delt;
+
+      if (size(#)>0)
+      {
+          return (primeClosure(L,#));
+      }
+      else
+      {
+          return(primeClosure(L));         // next iteration.
+      }
+    }
+}
+example
+{
+  "EXAMPLE:"; echo=2;
+  ring R=0,(x,y),dp;
+  ideal I=x4,y4;
+  def K=ReesAlgebra(I)[1];        // K contains ker such that K/ker=R[It]
+  list L=primeClosure(K);
+  def R(1)=L[1];                  // L[4] contains ker, L[4]/ker is the
+  def R(4)=L[4];                  // integral closure of L[1]/ker
+  setring R(1);
+  R(1);
+  ker;
+  setring R(4);
+  R(4);
+  ker;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc closureFrac(list L)
+"USAGE:    closureFrac (L); L a list of size n+1 as in the result of
+          primeClosure, L[n] contains an additional polynomial f
+CREATE:   a list fraction of two elements of L[1], such that
+          f=fraction[1]/fraction[2] via the injections phi L[i]-->L[i+1].
+EXAMPLE:  example closureFrac; shows an example
+"
+{
+// Define some auxiliary variables:
+
+  int n=size(L)-1;
+  int i,j,k,l,n2,n3;
+  intvec V;
+  string mapstr;
+  for (i=1; i<=n; i++)
+  {
+    ASSUME(0, not isQuotientRing( L[i] ) );
+    def R(i) = L[i];
+  }
+
+// The quotient representing f is computed as in 'closureGenerators' with
+// the differences that
+//   - the loop is done twice: for the numerator and for the denominator;
+//   - the result is stored in the list fraction and
+//   - we have to make sure that no more objects of the rings R(i) survive.
+
+  for (j=1; j<=2; j++)
+    {
+      setring R(n);
+      if (j==1)
+      {
+         poly p=f;
+      }
+      else
+      {
+         p=1;
+      }
+
+      for (k=n; k>1; k--)
+      {
+          if (j==1)
+          {
+             map phimap=R(k-1),phi;
+          }
+
+          p=p*phimap(nzd);
+
+          if (j==2)
+          {
+            kill phimap;
+          }
+
+          if (j==1)
+          {
+             //### noch abfragen ob Z(i) definiert ist
+             list gnirlist = ringlist(R(k));
+             n2 = size(gnirlist[2]);
+             n3 = size(gnirlist[3]);
+             for( i=1; i<=ncols(phi); i++)
+             {
+               gnirlist[2][n2+i] = "Z("+string(i)+")";
+             }
+             V=0;
+             V[ncols(phi)]=0; V=V+1;
+             gnirlist[3] = insert(gnirlist[3],list("dp",V),n3-1);
+             def S(k) = ring(gnirlist);
+             setring S(k);
+
+             //execute ("ring S(k) = "+charstr(R(k))+",("+varstr(R(k))+",
+             //          Z(1.."+string(ncols(phi))+")),(dp("+string(nvars(R(k)))
+             //          +"),dp("+string(ncols(phi))+"));");
+
+              ideal phi = imap(R(k),phi);
+              ideal J = imap (R(k),ker);
+              for (l=1;l<=ncols(phi);l++)
+              {
+                  J=J+(Z(l)-phi[l]);
+              }
+              J=groebner(J);
+              poly h=NF(imap(R(k),p),J);
+          }
+          else
+          {
+              setring S(k);
+              h=NF(imap(R(k),p),J);
+              setring R(k);
+              kill p;
+          }
+
+          setring R(k-1);
+
+          if (j==1)
+          {
+              ideal maxi;
+              maxi[nvars(R(k))] = 0;
+              maxi = maxi,maxideal(1);
+              map backmap = S(k),maxi;
+
+              //mapstr=" map backmap = S(k),";
+              //for (l=1;l<=nvars(R(k));l++)
+              //{
+              //  mapstr=mapstr+"0,";
+              //}
+              //execute (mapstr+"maxideal(1);");
+              poly p;
+          }
+          p=NF(backmap(h),std(ker));
+          if (j==2)
+          {
+            kill backmap;
+          }
+        }
+
+      if (j==1)
+        {
+          if (defined(fraction))
+            {
+              kill fraction;
+              list fraction=p;
+            }
+          else
+            {
+              list fraction=p;
+            }
+        }
+      else
+        {
+          fraction=insert(fraction,p,1);
+        }
+    }
+  export(fraction);
+  return ();
+}
+example
+{
+  "EXAMPLE:"; echo=2;
+  ring R=0,(x,y),dp;
+  ideal ker=x2+y2;
+  export ker;
+  list L=primeClosure(R);          // We normalize R/ker
+  for (int i=1;i<=size(L);i++) { def R(i)=L[i]; }
+  setring R(2);
+  kill R;
+  phi;                             // The map R(1)-->R(2)
+  poly f=T(2);                     // We will get a representation of f
+  export f;
+  L[2]=R(2);
+  closureFrac(L);
+  setring R(1);
+  kill R(2);
+  fraction;                        // f=fraction[1]/fraction[2] via phi
+  kill R(1);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// closureGenerators is called inside proc normal (option "withGens" )
+//
+
+// INPUT is the output of proc primeClosure (except for the last element, the
+// delta invariant) : hence input is a list L consisting of rings
+// L[1],...,L[n] (denoted R(1)...R(n) below) such that
+// - L[1] is a copy of (not a reference to!) the input ring L[1]
+// - all rings L[i] contain ideals ker, L[2],...,L[n] contain ideals phi
+// such that
+//                L[1]/ker --> ... --> L[n]/ker
+// are injections given by the corresponding ideals phi, and L[n]/ker
+// is the integral closure of L[1]/ker in its quotient field.
+// - all rings L[i] contain a polynomial nzd such that elements of
+// L[i]/ker are quotients of elements of L[i-1]/ker with denominator
+// nzd via the injection phi.
+
+// COMPUTE: In the list L of rings R(1),...,R(n), compute representations of
+// the ring variables of the last ring R(n) as fractions of elements of R(1):
+// The proc returns an ideal preim s.t. preim[i]/preim[size(preim)] expresses
+// the ith variable of R(n) as fraction of elements of the basering R(1)
+// preim[size(preim)] is a non-zero divisor of basering/i.
+
+proc closureGenerators(list L);
+{
+  def Rees=basering;         // when called inside normalI (in reesclos.lib)
+                             // the Rees Algebra is the current basering
+
+  // ------- First of all we need some variable declarations -----------
+  int n = size(L);                // the number of rings R(1)-->...-->R(n)
+  int length = nvars(L[n]);       // the number of variables of the last ring
+  int j,k,l,n2,n3;
+  intvec V;
+  string mapstr;
+  list preimages;
+  //Note: the empty list belongs to no ring, hence preimages can be used
+  //later in R(1)
+  //this is not possible for ideals (belong always to some ring)
+
+  for (int i=1; i<=n; i++)
+  {
+     ASSUME(0, not isQuotientRing(L[i]) );
+     def R(i) = L[i];          //give the rings from L a name
+  }
+
+  // For each variable (counter j) and for each intermediate ring (counter k):
+  // Find a preimage of var_j*phi(nzd(k-1)) in R(k-1).
+  // Finally, do the same for nzd.
+
+  for (j=1; j <= length+1; j++ )
+  {
+      setring R(n);
+
+      if (j==1)
+      {
+        poly p;
+      }
+      if (j <= length )
+      {
+        p=var(j);
+      }
+      else
+      {
+        p=1;
+      }
+      //i.e. p=j-th var of R(n) for j<=length and p=1 for j=length+1
+
+      for (k=n; k>1; k--)
+      {
+
+        if (j==1)
+        {
+          map phimap=R(k-1),phi;   //phimap:R(k-1)-->R(n), k=2..n, is the map
+                                   //belonging to phi in R(n)
+        }
+
+        p = p*phimap(nzd);
+
+          // Compute the preimage of [p mod ker(k)] under phi in R(k-1):
+          // As p is an element of Image(phi), there is a polynomial h such
+          // that h is mapped to [p mod ker(k)], and h can be computed as the
+          // normal form of p w.r.t. a Groebner basis of
+          // J(k) := <ker(k),Z(l)-phi(k)(l)> in R(k)[Z]=:S(k)
+
+        if (j==1)   // In the first iteration: Create S(k), fetch phi and
+                    // ker(k) and construct the ideal J(k).
+        {
+         //### noch abfragen ob Z(i) definiert ist
+         list gnirlist = ringlist(R(k));
+         n2 = size(gnirlist[2]);
+         n3 = size(gnirlist[3]);
+         for( i=1; i<=ncols(phi); i++)
+         {
+            gnirlist[2][n2+i] = "Z("+string(i)+")";
+         }
+         V=0;
+         V[ncols(phi)]=0;
+         V=V+1;
+         gnirlist[3] = insert(gnirlist[3],list("dp",V),n3-1);
+         def S(k) = ring(gnirlist);
+         setring S(k);
+
+        // execute ("ring S(k) = "+charstr(R(k))+",("+varstr(R(k))+",
+        //           Z(1.."+string(ncols(phi))+")),(dp("+string(nvars(R(k)))
+        //           +"),dp("+string(ncols(phi))+"));");
+
+          ideal phi = imap(R(k),phi);
+          ideal J = imap (R(k),ker);
+          for ( l=1; l<=ncols(phi); l++ )
+          {
+             J=J+(Z(l)-phi[l]);
+          }
+          J = groebner(J);
+          poly h = NF(imap(R(k),p),J);
+        }
+        else
+        {
+           setring S(k);
+           h = NF(imap(R(k),p),J);
+        }
+
+        setring R(k-1);
+
+        if (j==1)  // In the first iteration: Compute backmap:S(k)-->R(k-1)
+        {
+           ideal maxi;
+           maxi[nvars(R(k))] = 0;
+           maxi = maxi,maxideal(1);
+           map backmap = S(k),maxi;
+
+           //mapstr=" map backmap = S(k),";
+           //for (l=1;l<=nvars(R(k));l++)
+           //{
+           //  mapstr=mapstr+"0,";
+           //}
+           //execute (mapstr+"maxideal(1);");
+
+           poly p;
+        }
+        p = NF(backmap(h),std(ker));
+     }
+     // Whe are down to R(1), store here the result in the list preimages
+     preimages = insert(preimages,p,j-1);
+  }
+  ideal preim;                  //make the list preimages to an ideal preim
+  for ( i=1; i<=size(preimages); i++ )
+  {
+     preim[i] = preimages[i];
+  }
+  // R(1) was a copy of Rees, so we have to get back to the basering Rees from
+  // the beginning and fetch the result (the ideal preim) to this ring.
+  setring Rees;
+  return (fetch(R(1),preim));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//                From here: procedures for char p with Frobenius
+///////////////////////////////////////////////////////////////////////////////
+
+proc normalP(ideal id,list #)
+"USAGE:  normalP(id [,choose]); id = radical ideal, choose = optional list of
+         strings.
+         Optional parameters in list choose (can be entered in any order):@*
+         \"withRing\", \"isPrim\", \"noFac\", \"noRed\", where@*
+         - \"noFac\" -> factorization is avoided during the computation
+         of the minimal associated primes.@*
+         - \"isPrim\" -> assumes that the ideal is prime. If the assumption
+         does not hold, output might be wrong.@*
+         - \"withRing\" -> the ring structure of the normalization is
+         computed. The number of variables in the new ring is reduced as much
+         as possible.@*
+         - \"noRed\" -> when computing the ring structure, no reduction on the
+         number of variables is done, it creates one new variable for every
+         new module generator of the integral closure in the quotient field.@*
+ASSUME:  The characteristic of the ground field must be positive. If the
+         option \"isPrim\" is not set, the minimal associated primes of id
+         are computed first and hence normalP computes the normalization of
+         the radical of id. If option \"isPrim\" is set, the ideal must be
+         a prime ideal otherwise the result may be wrong.
+RETURN:  a list, say 'nor' of size 2 (resp. 3 if \"withRing\" is set).@*
+         ** If option \"withRing\" is not set: @*
+         Only the module structure is computed: @*
+         * nor[1] is a list of ideals Ii, i=1..r, in the basering R where r
+         is the number of minimal associated prime ideals P_i of the input
+         ideal id, describing the module structure:@*
+         If Ii is given by polynomials g_1,...,g_k in R, then c:=g_k is
+         non-zero in the ring R/P_i and g_1/c,...,g_k/c generate the integral
+         closure of R/P_i as R-module in the quotient field of R/P_i.@*
+         * nor[2] shows the delta invariants: it is a list of an intvec
+         of size r, the delta invariants of the r components, and an integer,
+         the total delta invariant of R/id
+         (-1 means infinite, and 0 that R/P_i resp. R/id is normal). @*
+         ** If option \"withRing\" is set: @*
+         The ring structure is also computed, and in this case:@*
+         * nor[1] is a list of r rings.@*
+         Each ring Ri = nor[1][i], i=1..r, contains two ideals with given
+         names @code{norid} and @code{normap} such that @*
+         - Ri/norid is the normalization of R/P_i, i.e. isomorphic as
+           K-algebra (K the ground field) to the integral closure of R/P_i in
+           the field of fractions of R/P_i; @*
+         - the direct sum of the rings Ri/norid is the normalization
+           of R/id; @*
+         - @code{normap} gives the normalization map from R to Ri/norid.@*
+         * nor[2] gives the module generators of the normalization of R/P_i,
+         it is the same as nor[1] if \"withRing\" is not set.@*
+         * nor[3] shows the delta invariants, it is the same as nor[2] if
+         \"withRing\" is not set.
+THEORY:  normalP uses the Leonard-Pellikaan-Singh-Swanson algorithm (using the
+         Frobenius) cf. [A. K. Singh, I. Swanson: An algorithm for computing
+         the integral closure, arXiv:0901.0871].
+         The delta invariant of a reduced ring A is dim_K(normalization(A)/A).
+         For A=K[x1,...,xn]/id we call this number also the delta invariant of
+         id. The procedure returns the delta invariants of the components P_i
+         and of id.
+NOTE:    To use the i-th ring type: @code{def R=nor[1][i]; setring R;}.
+@*       Increasing/decreasing printlevel displays more/less comments
+         (default: printlevel = 0).
+@*       Not implemented for local or mixed orderings or quotient rings.
+         For local or mixed orderings use proc 'normal'.
+@*       If the input ideal id is weighted homogeneous a weighted ordering may
+         be used (qhweight(id); computes weights).
+@*       Works only in characteristic p > 0; use proc normal in char 0.
+KEYWORDS: normalization; integral closure; delta invariant.
+SEE ALSO: normal, normalC
+EXAMPLE: example normalP; shows an example
+"
+{
+   ASSUME(0, not isQuotientRing(basering) );
+
+   int i,j,y, sr, del, co;
+   intvec deli;
+   list resu, Resu, prim, Gens, mstdid;
+   ideal gens;
+
+   // Default options
+   int wring = 0;           // The ring structure is not computed.
+   int noRed = 0;           // No reduction is done in the ring structure
+   int isPrim = 0;          // Ideal is not assumed to be prime
+   int noFac = 0;           // Use facstd when computing the decomposition
+
+
+   y = printlevel-voice+2;
+
+   if ( attrib(basering,"global") != 1)
+   {
+     "";
+     "// Not implemented for this ordering,";
+     "// please change to global ordering!";
+     return(resu);
+   }
+   if ( char(basering) <= 0)
+   {
+     "";
+     "// Algorithm works only in positive characteristic,";
+     "// use procedure 'normal' if the characteristic is 0";
+     return(resu);
+   }
+
+//--------------------------- define the method ---------------------------
+   string method;                //make all options one string in order to use
+                                 //all combinations of options simultaneously
+   for ( i=1; i<= size(#); i++ )
+   {
+     if ( typeof(#[i]) == "string" )
+     {
+       method = method + #[i];
+     }
+   }
+
+   if ( find(method,"withring") or find(method,"withRing") )
+   {
+     wring=1;
+   }
+   if ( find(method,"noRed") or find(method,"nored") )
+   {
+     noRed=1;
+   }
+   if ( find(method,"isPrim") or find(method,"isprim") )
+   {
+     isPrim=1;
+   }
+   if ( find(method,"noFac") or find(method,"nofac"))
+   {
+     noFac=1;
+   }
+
+   kill #;
+   list #;
+//--------------------------- start computation ---------------------------
+   ideal II,K1,K2;
+
+   //----------- check first (or ignore) if input id is prime -------------
+
+   if ( isPrim )
+   {
+      prim[1] = id;
+      if( y >= 0 )
+      { "";
+    "// ** WARNING: result is correct if ideal is prime (not checked) **";
+    "// disable option \"isPrim\" to decompose ideal into prime components";"";
+      }
+   }
+   else
+   {
+      if(y>=1)
+      {  "// compute minimal associated primes"; }
+
+      if( noFac )
+      { prim = minAssGTZ(id,1); }
+      else
+      { prim = minAssGTZ(id); }
+
+      if(y>=1)
+      {
+         prim;"";
+         "// number of irreducible components is", size(prim);
+      }
+   }
+
+   //----------- compute integral closure for every component -------------
+
+      for(i=1; i<=size(prim); i++)
+      {
+         if(y>=1)
+         {
+            ""; pause(); "";
+            "// start computation of component",i;
+            "   --------------------------------";
+         }
+         if(y>=1)
+         {  "// compute SB of ideal";
+         }
+         mstdid = mstd(prim[i]);
+         if(y>=1)
+         {  "// dimension of component is", dim(mstdid[1]);"";}
+
+      //------- 1-st main subprocedure: compute module generators ----------
+         printlevel = printlevel+1;
+         II = normalityTest(mstdid);
+
+      //------ compute also the ringstructure if "withRing" is given -------
+         if ( wring )
+         {
+         //------ 2-nd main subprocedure: compute ring structure -----------
+           if(noRed == 0){
+             resu = list(computeRing(II,prim[i])) + resu;
+           }
+           else
+           {
+             resu = list(computeRing(II,prim[i], "noRed")) + resu;
+           }
+         }
+         printlevel = printlevel-1;
+
+      //----- rearrange module generators s.t. denominator comes last ------
+         gens=0;
+         for( j=2; j<=size(II); j++ )
+         {
+            gens[j-1]=II[j];
+         }
+         gens[size(gens)+1]=II[1];
+         Gens = list(gens) + Gens;
+      //------------------------------ compute delta -----------------------
+         K1 = mstdid[1]+II;
+         K1 = std(K1);
+         K2 = mstdid[1]+II[1];
+         K2 = std(K2);
+         // K1 = std(mstdid[1],II);      //### besser
+         // K2 = std(mstdid[1],II[1]);   //### besser: Hannes, fixen!
+         co = codim(K1,K2);
+         deli = co,deli;
+         if ( co >= 0 && del >= 0 )
+         {
+            del = del + co;
+         }
+         else
+         { del = -1; }
+      }
+
+      if ( del >= 0 )
+      {
+         int mul = iMult(prim);
+         del = del + mul;
+      }
+      else
+      { del = -1; }
+
+      deli = deli[1..size(deli)-1];
+      if ( wring )
+      { Resu = resu,Gens,list(deli,del); }
+      else
+      { Resu = Gens,list(deli,del); }
+
+   sr = size(prim);
+
+//-------------------- Finally print comments and return --------------------
+   if(y >= 0)
+   {"";
+     if ( wring )
+     {
+"// 'normalP' created a list, say nor, of three lists:
+// To see the result, type
+     nor;
+
+// * nor[1] is a list of",sr,"ring(s):
+// To access the i-th ring nor[1][i] give it a name, say Ri, and type e.g.
+     def R1 = nor[1][1]; setring R1;  norid; normap;
+// for the other rings type first setring R; (if R is the name of your
+// original basering) and then continue as for R1;
+// Ri/norid is the affine algebra of the normalization of the i-th
+// component R/P_i (where P_i is a min. associated prime of the input ideal)
+// and normap the normalization map from R to Ri/norid;
+
+// * nor[2] is a list of",sr,"ideal(s), each ideal nor[2][i] consists of
+// elements g1..gk of r such that the gj/gk generate the integral
+// closure of R/P_i as R-module in the quotient field of R/P_i.
+
+// * nor[3] shows the delta-invariant of each component and of the input
+// ideal (-1 means infinite, and 0 that r/P_i is normal).";
+     }
+     else
+     {
+"// 'normalP' computed a list, say nor, of two lists:
+// To see the result, type
+     nor;
+
+// * nor[1] is a list of",sr,"ideal(s), where each ideal nor[1][i] consists
+// of elements g1..gk of the basering R such that gj/gk generate the integral
+// closure of R/P_i (where P_i is a min. associated prime of the input ideal)
+// as R-module in the quotient field of R/P_i;
+
+// * nor[2] shows the delta-invariant of each component and of the input ideal
+// (-1 means infinite, and 0 that R/P_i is normal).";
+     }
+   }
+
+   return(Resu);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r  = 11,(x,y,z),wp(2,1,2);
+   ideal i = x*(z3 - xy4 + x2);
+   list nor= normalP(i); nor;
+   //the result says that both components of i are normal, but i itself
+   //has infinite delta
+   pause("hit return to continue");
+
+   ring s = 2,(x,y),dp;
+   ideal i = y*((x-y^2)^2 - x^3);
+   list nor = normalP(i,"withRing"); nor;
+
+   def R2  = nor[1][2]; setring R2;
+   norid; normap;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Assume: mstdid is the result of mstd(prim[i]), prim[i] a prime component of
+// the input ideal id of normalP.
+// Output is an ideal U s.t. U[i]/U[1] are module generators.
+
+static proc normalityTest(list mstdid)
+{
+   ASSUME(1, not isQuotientRing(basering) );
+
+   int y = printlevel-voice+2;
+   intvec op = option(get);
+   option(redSB);
+   def R = basering;
+   int n, p = nvars(R), char(R);
+   int ii;
+
+   ideal J = mstdid[1];         //J is the SB of I
+   ideal I = mstdid[2];
+   int h = n-dim(J);            //codimension of V(I), I is a prime ideal
+
+   //-------------------------- compute singular locus ----------------------
+   qring Q = J;                 //pass to quotient ring
+   ideal I = imap(R,I);
+   ideal J = imap(R,J);
+   attrib(J,"isSB",1);
+   if ( y >= 1)
+   { "start normality test";  "compute singular locus";}
+
+   ideal M = minor(jacob(I),h,J); //use the command minor modulo J (hence J=0)
+   M = std(M);                    //this makes M much smaller
+   //keep only minors which are not 0 mod I (!) this is important since we
+   //need a nzd mod I
+
+   //---------------- choose nzd from ideal of singular locus --------------
+   ideal D = M[1];
+   for( ii=2; ii<=size(M); ii++ )            //look for the shortest one
+   {
+      if( size(M[ii]) < size(D[1]) )
+      {
+          D = M[ii];
+      }
+   }
+
+   //--------------- start p-th power algorithm and return ----------------
+   ideal F = var(1)^p;
+   for(ii=2; ii<=n; ii++)
+   {
+      F=F,var(ii)^p;
+   }
+
+   ideal Dp=D^(p-1);
+   ideal U=1;
+   ideal K,L;
+   map phi=Q,F;
+   if ( y >= 1)
+   {  "compute module generators of integral closure";
+      "denominator D is:";  D;
+      pause();
+   }
+
+   ii=0;
+   list LK;
+   while(1)
+   {
+      ii=ii+1;
+      if ( y >= 1)
+      { "iteration", ii; }
+      L = U*Dp + I;
+      //### L=interred(L) oder mstd(L)[2]?
+      //Wird dadurch kleiner aber string(L) wird groesser
+      K = preimage(Q,phi,L);    //### Improvement by block ordering?
+      option(returnSB);
+      K = intersect(U,K);          //K is the new U, it is a SB
+      LK = mstd(K);
+      K = LK[2];
+
+   //---------------------------- simplify output --------------------------
+      if(size(reduce(U,LK[1]))==0)  //previous U coincides with new U
+      {                             //i.e. we reached the integral closure
+         U=simplify(reduce(U,groebner(D)),2);
+         U = D,U;
+         poly gg = gcd(U[1],U[size(U)]);
+         for(ii=2; ii<=size(U)-1 ;ii++)
+         {
+            gg = gcd(gg,U[ii]);
+         }
+         for(ii=1; ii<=size(U); ii++)
+         {
+            U[ii]=U[ii]/gg;
+         }
+         U = simplify(U,6);
+         //if ( y >= 1)
+         //{ "module generators are U[i]/U[1], with U:"; U;
+         //  ""; pause(); }
+         setring R;
+         option(set,op);
+         ideal U = imap(Q,U);
+         return(U);
+      }
+      U=K;
+   }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static proc substpartSpecial(ideal endid, ideal endphi)
+{
+   ASSUME(1, not isQuotientRing(basering) );
+
+   //Note: newRing is of the form (R the original basering):
+   //char(R),(T(1..N),X(1..nvars(R))),(dp(N),...);
+
+   int ii,jj,kk;
+   def BAS = basering;
+   int n = nvars(basering);
+
+   list Le = elimpart(endid);
+   int q = size(Le[2]);                   //q variables have been substituted
+//Le;"";
+   if ( q == 0 )
+   {
+      ideal normap = endphi;
+      ideal norid = endid;
+      export(norid);
+      export(normap);
+      list L = BAS;
+      return(L);
+   }
+
+      list gnirlist = ringlist(basering);
+      endid = Le[1];
+//endphi;"";
+      for( ii=1; ii<=n; ii++)
+      {
+         if( Le[4][ii] == 0 )            //ii=index of substituted var
+         {
+            endphi = subst(endphi,var(ii),Le[5][ii]);
+         }
+      }
+//endphi;"";
+      list g2 = gnirlist[2];             //the varlist
+      list g3 = gnirlist[3];             //contains blocks of orderings
+      int n3 = size(g3);
+
+   //----------------- first identify module ordering ------------------
+      if ( g3[n3][1]== "c" or g3[n3][1] == "C" )
+      {
+         list gm = g3[n3];              //last blockis module ordering
+         g3 = delete(g3,n3);
+         int m = 0;
+      }
+      else
+      {
+         list gm = g3[1];              //first block is module ordering
+         g3 = delete(g3,1);
+         int m = 1;
+      }
+   //---- delete variables which were substituted and weights  --------
+      intvec V;
+      int n(0);
+      list newg2;
+      list newg3;
+      for ( ii=1; ii<=n3-1; ii++ )
+      {
+        // If order is a matrix ordering, it is replaced by dp ordering.
+        // TODO: replace it only when some of the original
+        //       variables are eliminated.
+        if(g3[ii][1] == "M"){
+          g3[ii][1] = "dp";
+          g3[ii][2] = (1..sqroot(size(g3[ii][2])))*0+1;
+        }
+        V = V,g3[ii][2];           //copy weights for ordering in each block
+        if ( ii==1 )               //into one intvector
+        {
+           V = V[2..size(V)];
+        }
+        // int n(ii) = size(g3[ii][2]);
+        int n(ii) = size(V);
+        intvec V(ii);
+
+        for ( jj = n(ii-1)+1; jj<=n(ii); jj++)
+        {
+          if(  Le[4][jj] !=0 or                                             // jj=index of var which was not substituted
+               (  (ii==n3-1) and ( jj==n(ii) ) and  (size(newg2)==0) )      // or we have no variables yet in the new ring and
+                                                                            // want to keep at least the last one!
+            )
+          {
+            kk=kk+1;
+            newg2[kk] = g2[jj];   //not substituted var from varlist
+            V(ii)=V(ii),V[jj];    //weight of not substituted variable
+          }
+        }
+        if ( size(V(ii)) >= 2 )
+        {
+           V(ii) = V(ii)[2..size(V(ii))];
+           list g3(ii)=g3[ii][1],V(ii);
+           newg3 = insert(newg3,g3(ii),size(newg3));
+//"newg3"; newg3;
+        }
+      }
+//"newg3"; newg3;
+      //newg3 = delete(newg3,1);    //delete empty list
+
+/*
+//### neue Ordnung, 1 Block fuer alle vars, aber Gewichte erhalten;
+//vorerst nicht realisiert, da bei leonhard1 alte Version (neue Variable T(i)
+//ein neuer Block) ein kuerzeres Ergebnis liefert
+      kill g3;
+      list g3;
+      V=0;
+      for ( ii= 1; ii<=n3-1; ii++ )
+      {
+        V=V,V(ii);
+      }
+      V = V[2..size(V)];
+
+      if ( V==1 )
+      {
+         g3[1] = list("dp",V);
+      }
+      else
+      {
+         g3[1] = lis("wp",V);
+      }
+      newg3 = g3;
+
+//"newg3";newg3;"";
+//### Ende neue Ordnung
+*/
+
+      if ( m == 0 )
+      {
+         newg3 = insert(newg3,gm,size(newg3));
+      }
+      else
+      {
+         newg3 = insert(newg3,gm);
+      }
+      gnirlist[2] = newg2;
+      gnirlist[3] = newg3;
+
+//gnirlist;
+      def newBAS = ring(gnirlist);            //change of ring to less vars
+      setring newBAS;
+      ideal normap = imap(BAS,endphi);
+      //normap = simplify(normap,2);
+      ideal norid =  imap(BAS,endid);
+      export(norid);
+      export(normap);
+      list L = newBAS;
+      setring BAS;
+      return(L);
+
+   //Hier scheint interred gut zu sein, da es Ergebnis relativ schnell
+   //verkleinert. Hier wird z.B. bei leonard1 size(norid) verkleinert aber
+   //size(string(norid)) stark vergroessert, aber es hat keine Auswirkungen
+   //da keine map mehr folgt.
+   //### Bei Leonard2 haengt interred (BUG)
+   //mstd[2] verkleinert norid nocheinmal um die Haelfte, dauert aber 3.71 sec
+   //### Ev. Hinweis auf mstd in der Hilfe?
+
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Computes the ring structure of a ring given by module generators.
+// Assume: J[i]/J[1] are the module generators in the quotient field
+// with J[1] as universal denominator.
+// If option "noRed" is not given, a reduction in the number of variables is
+// attempted.
+static proc computeRing(ideal J, ideal I, list #)
+{
+  ASSUME(1, not isQuotientRing(basering) );
+
+  int i, ii,jj;
+  intvec V;                          // to be used for variable weights
+  int y = printlevel-voice+2;
+  def R = basering;
+  poly c = J[1];                     // the denominator
+  list gnirlist = ringlist(basering);
+  string svars = varstr(basering);
+  int nva = nvars(basering);
+  string svar;
+  ideal maxid = maxideal(1);
+
+  int noRed = 0;     // By default, we try to reduce the number of generators.
+  if(size(#) > 0){
+    if ( typeof(#[1]) == "string" )
+    {
+      if (#[1] == "noRed"){noRed = 1;}
+    }
+  }
+
+  if ( y >= 1){"// computing the ring structure...";}
+
+  if(c==1)
+  {
+/*    if( defined(norid) )  { kill norid; }
+      if( defined(normap) ) { kill normap; }
+      ideal norid = I;
+      ideal normap =  maxid;  */
+
+    def R1 = ring(gnirlist);
+    setring R1;
+    ideal norid = imap(R, I);
+    ideal normap = imap(R, maxid);
+    export norid;
+    export normap;
+
+    if(noRed == 1){
+      setring R;
+      return(R1);
+    }
+    else
+    {
+      list L = substpartSpecial(norid,normap);
+      def lastRing = L[1];
+      setring R;
+      return(lastRing);
+    }
+  }
+
+
+  //-------------- Enlarge ring by creating new variables ------------------
+  //check first whether variables T(i) and then whether Z(i),...,A(i) exist
+  //old variable names are not touched
+
+  if ( find(svars,"T(") == 0 )
+  {
+    svar = "T";
+  }
+  else
+  {
+    for (ii=90; ii>=65; ii--)
+    {
+      if ( find(svars,ASCII(ii)+"(") == 0 )
+      {
+        svar = ASCII(ii);  break;
+      }
+    }
+  }
+
+  int q = size(J)-1;
+  if ( size(svar) != 0 )
+  {
+    for ( ii=q; ii>=1; ii-- )
+    {
+      gnirlist[2] = insert(gnirlist[2],svar+"("+string(ii)+")");
+    }
+  }
+  else
+  {
+    for ( ii=q; ii>=1; ii-- )
+    {
+      gnirlist[2] = insert(gnirlist[2],"T("+string(100*nva+ii)+")");
+    }
+  }
+
+  V[q]=0;                        //create intvec of variable weights
+  V=V+1;
+  gnirlist[3] = insert(gnirlist[3],list("dp",V));
+
+  //this is a block ordering with one dp-block (1st block) for new vars
+  //the remaining weights and blocks for old vars are kept
+  //### perhaps better to make only one block, keeping weights ?
+  //this might effect syz below
+  //alt: ring newR = char(R),(X(1..nvars(R)),T(1..q)),dp;
+  //Reihenfolge geaendert:neue Variablen kommen zuerst, Namen ev. nicht T(i)
+
+  def newR = ring(gnirlist);
+  setring newR;                //new extended ring
+  ideal I = imap(R,I);
+
+  //------------- Compute linear and quadratic relations ---------------
+  if(y>=1)
+  {
+     "// compute linear relations:";
+  }
+  qring newQ = std(I);
+
+  ideal f = imap(R,J);
+  module syzf = syz(f);
+  ideal pf = f[1]*f;
+  //f[1] is the denominator D from normalityTest, a non zero divisor of R/I
+
+  ideal newT = maxideal(1);
+  newT = 1,newT[1..q];
+  //matrix T = matrix(ideal(1,T(1..q)),1,q+1);   //alt
+  matrix T = matrix(newT,1,q+1);
+  ideal Lin = ideal(T*syzf);
+  //Lin=interred(Lin);
+  //### interred reduziert ev size aber size(string(LIN)) wird groesser
+
+  if(y>=1)
+  {
+    if(y>=3)
+    {
+      "//   the linear relations:";  Lin; pause();"";
+    }
+      "// the ring structure of the normalization as affine algebra";
+      "//   number of linear relations:", size(Lin);
+  }
+
+  if(y>=1)
+  {
+    "// compute quadratic relations:";
+  }
+  matrix A;
+  ideal Quad;
+  poly ff;
+  newT = newT[2..size(newT)];
+  matrix u;  // The units for non-global orderings.
+
+  // Quadratic relations
+  for (ii=2; ii<=q+1; ii++ )
+  {
+    for ( jj=2; jj<=ii; jj++ )
+    {
+      ff = NF(f[ii]*f[jj],std(0));     // this makes lift much faster
+      // For non-global orderings, we have to take care of the units.
+      if(attrib(basering,"global") != 1)
+      {
+        A = lift(pf, ff, u);
+        Quad = Quad,ideal(newT[jj-1]*newT[ii-1] * u[1, 1]- T*A);
+      }
+      else
+      {
+        A = lift(pf,ff);              // ff lin. comb. of elts of pf mod I
+        Quad = Quad,ideal(newT[jj-1]*newT[ii-1] - T*A);
+      }
+      //A = lift(pf, f[ii]*f[jj]);
+      //Quad = Quad, ideal(T(jj-1)*T(ii-1) - T*A);
+    }
+  }
+  Quad = Quad[2..ncols(Quad)];
+
+  if(y>=1)
+  {
+    if(y>=3)
+    {
+      "//   the quadratic relations"; Quad; pause();"";
+    }
+      "//   number of quadratic relations:", size(Quad);
+  }
+  ideal Q1 = Lin,Quad;     //elements of Q1 are in NF w.r.t. I
+
+  //Q1 = mstd(Q1)[2];
+  //### weglassen, ist sehr zeitaufwendig.
+  //Ebenso interred, z.B. bei Leonard1 (1. Komponente von Leonard):
+  //"size Q1:", size(Q1), size(string(Q1));   //75 60083
+  //Q1 = interred(Q1);
+  //"size Q1:", size(Q1), size(string(Q1));   //73 231956 (!)
+  //### Speicherueberlauf bei substpartSpecial bei 'ideal norid  = phi1(endid)'
+  //Beispiel fuer Hans um map zu testen!
+
+  setring newR;
+  ideal endid  = imap(newQ,Q1),I;
+  ideal endphi = imap(R,maxid);
+
+  if(noRed == 0){
+    list L=substpartSpecial(endid,endphi);
+    def lastRing=L[1];
+    if(y>=1)
+    {
+      "//   number of substituted variables:", nvars(newR)-nvars(lastRing);
+      pause();"";
+    }
+    setring R;
+    return(lastRing);
+  }
+  else
+  {
+    ideal norid = endid;
+    ideal normap = endphi;
+    export(norid);
+    export(normap);
+    setring R;
+    return(newR);
+  }
+}
+
+//                Up to here: procedures for char p with Frobenius
+///////////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////////
+//                From here: subprocedures for normal
+
+// inputJ is used in parametrization of rational curves algorithms, to specify
+// a different test ideal.
+
+static proc normalM(ideal I, int decomp, int withDelta, int denomOption, ideal inputJ, ideal inputC){
+// Computes the normalization of a ring R / I using the module structure as far
+// as possible.
+// The ring R is the basering.
+// Input: ideal I
+// Output: a list of 3 elements (resp 4 if withDelta = 1), say nor.
+// - nor[1] = U, an ideal of R.
+// - nor[2] = c, an element of R.
+// U and c satisfy that 1/c * U is the normalization of R / I in the
+// quotient field Q(R/I).
+// - nor[3] = ring say T, containing two ideals norid and normap such that
+// normap gives the normalization map from R / I to T / norid.
+// - nor[4] = the delta invariant, if withDelta = 1.
+
+// Details:
+// --------
+// Computes the ideal of the minors in the first step and then reuses it in all
+// steps.
+// In step s, the denominator is D^s, where D is a nzd of the original quotient
+// ring, contained in the radical of the singular locus.
+// This denominator is used except when the degree of D^i is greater than the
+// degree of a universal denominator.
+// The nzd is taken as the smallest degree polynomial in the radical of the
+// singular locus.
+
+// It assumes that the ideal I is equidimensional radical. This is not checked
+// in the procedure!
+// If decomp = 0 or decomp = 3 it assumes further that I is prime. Therefore
+// any non-zero element in the jacobian ideal is assumed to be a
+// non-zerodivisor.
+
+// It works over the given basering.
+// If it has a non-global ordering, it changes it to dp global only for
+// computing radical.
+
+// The delta invariant is only computed if withDelta = 1, and decomp = 0 or
+// decomp = 3 (meaning that the ideal is prime).
+
+// denomOption = 0      -> Uses the smallest degree polynomial
+// denomOption = i > 0  -> Uses a polynomial in the i-th variable
+
+  ASSUME(1, not isQuotientRing(basering) );
+
+  intvec save_opt=option(get);
+  option(redSB);
+  option(returnSB);
+  int step = 0;                       // Number of steps. (for debugging)
+  int dbg = printlevel - voice + 2;   // dbg = printlevel (default: dbg = 0)
+  int i;                              // counter
+  int isGlobal = attrib(basering,"global");
+
+  poly c;                     // The common denominator.
+
+  def R = basering;
+
+//------------------------ Groebner bases and dimension of I-----------------
+  if(isGlobal == 1)
+  {
+    list IM = mstd(I);
+    I = IM[1];
+    ideal IMin = IM[2];   // A minimal set of generators in the groebner basis.
+  }
+  else
+  {
+    // The minimal set of generators is not computed by mstd for
+    // non-global orderings.
+    I = groebner(I);
+    ideal IMin = I;
+  }
+  int d = dim(I);
+
+  // ---------------- computation of the singular locus ---------------------
+  // We compute the radical of the ideal of minors modulo the original ideal.
+  // This is done only in the first step.
+  qring Q = I;   // We work in the quotient by the groebner base of the ideal I
+  option(redSB);
+  option(returnSB);
+
+  // If a conductor ideal was given as input, we use it instead of the
+  // singular locus. If a test ideal was given as input, we do not compute the
+  // singular locus.
+  ideal inputC = fetch(R, inputC);
+  ideal inputJ = fetch(R, inputJ);
+  if((inputC == 0) && (inputJ == 0))
+  {
+    // We compute the radical of the ideal of minors modulo the original ideal.
+    // This is done only in the first step.
+    ideal I = fetch(R, I);
+    attrib(I, "isSB", 1);
+    ideal IMin = fetch(R, IMin);
+
+    dbprint(dbg, "Computing the jacobian ideal...");
+
+    // If a given conductor ideal is given, we use it.
+    // If a given test ideal is given, we don't need to compute the jacobian
+
+    // reduction mod I in 'minor' is not working for local orderings!
+    if(attrib(basering,"global"))
+    {
+      ideal J = minor(jacob(IMin), nvars(basering) - d, I);
+    }
+    else
+    {
+      ideal J = minor(jacob(IMin), nvars(basering) - d);
+      J = reduce(J, groebner(I));
+    }
+    J = groebner(J);
+  }
+  else
+  {
+    ideal J = fetch(R, inputC);
+    J = groebner(J);
+  }
+
+  //------------------ We check if the singular locus is empty -------------
+  if(J[1] == 1)
+  {
+    // The original ring R/I was normal. Nothing to do.
+    // We define anyway a new ring, equal to R, to be able to return it.
+    setring R;
+    list lR = ringlist(R);
+    def ROut = ring(lR);
+    setring ROut;
+    ideal norid = fetch(R, I);
+    ideal normap = maxideal(1);
+    export norid;
+    export normap;
+    setring R;
+    if(withDelta)
+    {
+      list output = ideal(1), poly(1), ROut, 0;
+    }
+    else
+    {
+      list output = ideal(1), poly(1), ROut;
+    }
+    option(set,save_opt);
+    return(list(output));
+  }
+
+
+  // -------------------- election of the universal denominator----------------
+  // We first check if a conductor ideal was computed. If not, we don't
+  // compute a universal denominator.
+  ideal Id1;
+  if(J != 0)
+  {
+    if(denomOption == 0)
+    {
+      poly condu = getSmallest(J);   // Choses the polynomial of smallest degree
+                                     // of J as universal denominator.
+    }
+    else
+    {
+      poly condu = getOneVar(J, denomOption);
+    }
+    if(dbg >= 1)
+    {
+      "";
+      "The universal denominator is ", condu;
+    }
+
+    // ----- splitting the ideal by the universal denominator (if possible) -----
+    // If the ideal is equidimensional, but not necessarily prime, we check if
+    // the universal denominator is a non-zerodivisor of R/I.
+    // If not, we split I.
+    if((decomp == 1) or (decomp == 2))
+    {
+      Id1 = quotient(0, condu);
+      if(size(Id1) > 0)
+      {
+        // We have to split.
+        if(dbg >= 1)
+        {
+          "A zerodivisor was found. We split the ideal. The zerodivisor is ", condu;
+        }
+        setring R;
+        ideal Id1 = fetch(Q, Id1), I;
+        Id1 = groebner(Id1);
+        ideal Id2 = quotient(I, Id1);
+        // I = I1 \cap I2
+        printlevel = printlevel + 1;
+        ideal JDefault = 0; // Now it uses the default J;
+        list nor1 = normalM(Id1, decomp, withDelta, denomOption, JDefault, JDefault);
+        list nor2 = normalM(Id2, decomp, withDelta, denomOption, JDefault, JDefault);
+        printlevel = printlevel - 1;
+        option(set,save_opt);
+        list res = nor1 + nor2;
+        return(res);
+      }
+    }
+  }
+  else
+  {
+    poly condu = 0;
+  }
+
+  // --------------- computation of the first test ideal ---------------------
+  // To compute the radical we go back to the original ring.
+  // If we are using a non-global ordering, we must change to the global
+  // ordering.
+  setring R;
+  // If a test ideal is given at the input, we use it.
+  if(inputJ == 0)
+  {
+    if(isGlobal == 1)
+    {
+      ideal J = fetch(Q, J);
+      J = J, I;
+      if(dbg >= 1)
+      {
+        "The original singular locus is";
+        groebner(J);
+        if(dbg >= 2){pause();}
+        "";
+      }
+      // We check if the only singular point is the origin.
+      // If so, the radical is the maximal ideal at the origin.
+      J = groebner(J);
+      if(locAtZero(J))
+      {
+        J = maxideal(1);
+      }
+      else
+      {
+        J = radical(J);
+      }
+    }
+    else
+    {
+      // We change to global dp ordering.
+      list rl = ringlist(R);
+      list origOrd = rl[3];
+      list newOrd = list("dp", intvec(1:nvars(R))), list("C", 0);
+      rl[3] = newOrd;
+      def globR = ring(rl);
+      setring globR;
+      ideal J = fetch(Q, J);
+      ideal I = fetch(R, I);
+      J = J, I;
+      if(dbg >= 1)
+      {
+        "The original singular locus is";
+        groebner(J);
+        if(dbg>=2){pause();}
+        "";
+      }
+      J = radical(J);
+      setring R;
+      ideal J = fetch(globR, J);
+    }
+  }
+  else
+  {
+    ideal J = inputJ;
+  }
+
+  if(dbg >= 1)
+  {
+    "The radical of the original singular locus is";
+    J;
+    if(dbg>=2){pause();}
+  }
+
+  // ---------------- election of the non zero divisor ---------------------
+  setring Q;
+  J = fetch(R, J);
+  J = interred(J);
+  if(denomOption == 0)
+  {
+    poly D = getSmallest(J);    // Chooses the polynomial of smallest degree as
+                                // non-zerodivisor.
+  }
+  else
+  {
+    poly D = getOneVar(J, denomOption);
+  }
+  if(dbg >= 1)
+  {
+    "The non zero divisor is ", D;
+    "";
+  }
+
+  // ------- splitting the ideal by the non-zerodivisor (if possible) --------
+  // If the ideal is equidimensional, but not necessarily prime, we check if D
+  // is actually a non-zerodivisor of R/I.
+  // If not, we split I.
+  if((decomp == 1) or (decomp == 2))
+  {
+    // We check if D is actually a non-zerodivisor of R/I.
+    // If not, we split I.
+    Id1 = quotient(0, D);
+    if(size(Id1) > 0)
+    {
+      // We have to split.
+      if(dbg >= 1)
+      {
+        "A zerodivisor was found. We split the ideal. The zerodivisor is ", D;
+      }
+      setring R;
+      ideal Id1 = fetch(Q, Id1), I;
+      Id1 = groebner(Id1);
+      ideal Id2 = quotient(I, Id1);
+      // I = Id1 \cap Id2
+      printlevel = printlevel + 1;
+
+      ideal JDefault = 0;  // Now it uses the default J;
+      list nor1 = normalM(Id1, decomp, withDelta, denomOption, JDefault, JDefault);
+      list nor2 = normalM(Id2, decomp, withDelta, denomOption, JDefault, JDefault);
+      printlevel = printlevel - 1;
+      option(set,save_opt);
+      list res = nor1 + nor2;
+      return(res);
+    }
+  }
+
+  // --------------------- normalization ------------------------------------
+  // We call normalMEqui to compute the normalization.
+  setring R;
+  poly D = fetch(Q, D);
+  poly condu = fetch(Q, condu);
+  J = fetch(Q, J);
+  printlevel = printlevel + 1;
+  list result = normalMEqui(I, J, condu, D, withDelta, denomOption);
+  printlevel = printlevel - 1;
+  option(set,save_opt);
+  return(list(result));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static proc normalMEqui(ideal I, ideal origJ, poly condu, poly D, int withDelta)
+// Here is where the normalization is actually computed.
+
+// Computes the normalization of R/I. (basering is R)
+// I is assumed to be radical and equidimensional.
+// origJ is the first test ideal.
+// D is a non-zerodivisor of R/I.
+// condu is a non-zerodivisor in the conductor or 0 if it was not computed.
+// If withDelta = 1, computes the delta invariant.
+{
+  ASSUME(1, not isQuotientRing(basering) );
+  int step = 0;                       // Number of steps. (for debugging)
+  int dbg = printlevel - voice + 2;   // dbg = printlevel (default: dbg = 0)
+  int i;                              // counter
+  int isNormal = 0;                   // check for exiting the loop
+  int isGlobal = attrib(basering,"global");
+  int delt;
+
+  def R = basering;
+  poly c = D;
+  ideal U;
+  ideal cJ;
+  list testOut;                 // Output of proc testIdeal
+                                // (the test ideal and the ring structure)
+
+  qring Q = groebner(I);
+  intvec save_opt=option(get);
+  option(redSB);
+  option(returnSB);
+  ideal J = imap(R, origJ);
+  poly c = imap(R, c);
+  poly D = imap(R, D);
+  poly condu = imap(R, condu);
+  ideal cJ;
+  ideal cJMod;
+
+  dbprint(dbg, "Preliminar step begins.");
+
+  // --------------------- computation of A1 -------------------------------
+  dbprint(dbg, "Computing the quotient (DJ : J)...");
+  ideal U = groebner(quotient(D*J, J));
+  ideal oldU = 1;
+
+  if(dbg >= 2) { "The quotient is"; U; }
+
+  // ----------------- Grauer-Remmert criterion check -----------------------
+  // We check if the equality in Grauert - Remmert criterion is satisfied.
+  isNormal = checkInclusions(D*oldU, U);
+  if(isNormal == 0)
+  {
+    if(dbg >= 1)
+    {
+      "In this step, we have the ring 1/c * U, with c =", c;
+      "and U = "; U;
+    }
+  }
+  else
+  {
+    // The original ring R/I was normal. Nothing to do.
+    // We define anyway a new ring, equal to R, to be able to return it.
+    setring R;
+    list lR = ringlist(R);
+    def ROut = ring(lR);
+    setring ROut;
+    ideal norid = fetch(R, I);
+    ideal normap = maxideal(1);
+    export norid;
+    export normap;
+    setring R;
+    if(withDelta)
+    {
+      list output = ideal(1), poly(1), ROut, 0;
+    }
+    else
+    {
+      list output = ideal(1), poly(1), ROut;
+    }
+    option(set,save_opt);
+    return(output);
+  }
+
+  // ----- computation of the chain of ideals A1 c A2 c ... c An ------------
+  while(isNormal == 0)
+  {
+    step++;
+    if(dbg >= 1) { ""; "Step ", step, " begins."; }
+    dbprint(dbg, "Computing the test ideal...");
+
+    // --------------- computation of the test ideal ------------------------
+    // Computes a test ideal for the new ring.
+    // The test ideal will be the radical in the new ring of the original
+    // test ideal.
+    setring R;
+    U = imap(Q, U);
+    c = imap(Q, c);
+    testOut = testIdeal(I, U, origJ, c, D);
+    cJ = testOut[1];
+
+    setring Q;
+    cJ = imap(R, cJ);
+    cJ = groebner(cJ);
+
+    // cJ / c is now the ideal mapped back.
+    // We have the generators as an ideal in the new ring,
+    // but we want the generators as an ideal in the original ring.
+    cJMod = getGenerators(cJ, U, c);
+
+    if(dbg >= 2) { "The test ideal in this step is "; cJMod; }
+
+    cJ = cJMod;
+
+    // ------------- computation of the quotient (DJ : J)--------------------
+    oldU = U;
+    dbprint(dbg, "Computing the quotient (c*D*cJ : cJ)...");
+    U = quotient(c*D*cJ, cJ);
+    if(dbg >= 2){"The quotient is "; U;}
+
+    // ------------- Grauert - Remmert criterion check ----------------------
+    // We check if the equality in Grauert - Remmert criterion is satisfied.
+    isNormal = checkInclusions(D*oldU, U);
+
+    if(isNormal == 1)
+    {
+      // We go one step back. In the last step we didnt get antyhing new,
+      // we just verified that the ring was already normal.
+      dbprint(dbg, "The ring in the previous step was already normal.");
+      dbprint(dbg, "");
+      U = oldU;
+    }
+    else
+    {
+      // ------------- preparation for next iteration ----------------------
+      // We have to go on.
+      // The new denominator is chosen.
+      c = D * c;
+
+      // If we have a universal denominator of smaller degree than c,
+      // we replace c by it.
+      if(condu != 0)
+      {
+        if(deg(c) > deg(condu))
+        {
+          U = changeDenominatorQ(U, c, condu);
+          c = condu;
+        }
+      }
+      if(dbg >= 1)
+      {
+        "In this step, we have the ring 1/c * U, with c =", c;
+        "and U = ";
+        U;
+        if(dbg>=2){pause();}
+      }
+    }
+  }
+
+  // ------------------------- delta computation ----------------------------
+  if(withDelta)
+  {
+    ideal UD = groebner(U);
+    delt = vdim(std(modulo(UD, c)));
+  }
+
+  // -------------------------- prepare output -----------------------------
+  setring R;
+  U = fetch(Q, U);
+  c = fetch(Q, c);
+
+  // Ring structure of the new ring
+  def ere = testOut[2];
+  if(withDelta)
+  {
+    list output = U, c, ere, delt;
+  }
+  else
+  {
+    list output = U, c, ere;
+  }
+  option(set,save_opt);
+  return(output);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static proc lineUpLast(ideal U, poly c)
+// Sets c as the last generator of U.
+{
+  int i;
+  ideal newU;
+  for (i = 1; i <= ncols(U); i++)
+  {
+    if(U[i] != c)
+    {
+      if(size(newU) == 0)
+      { newU = U[i]; }
+      else
+      { newU = newU, U[i]; }
+    }
+  }
+  if(size(newU) == 0)
+  { newU = c; }
+  else
+  { newU = newU, c; }
+  return(newU);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static proc lineUp(ideal U, poly c)
+// Sets c as the first generator of U.
+{
+  int i;
+  ideal newU = c;
+  for (i = 1; i <= ncols(U); i++)
+  {
+    if(U[i] != c)
+    {
+      newU = newU, U[i];
+    }
+  }
+  return(newU);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+//WARNING - elim is not working here!! Check!!
+//It is now replaced by computing an eliminating groebner basis.
+proc getOneVar(ideal J, int vari)
+"USAGE:   getOneVar(J, vari); J is a 0-dimensional ideal, vari is an integer.
+RETURN:  a polynomial of J in the variable indicated by vari of smallest
+         degree.@*
+NOTE:    Works only over rings of two variables.@*
+         It is intended mainly as an auxiliary procedure for computing
+         integral bases. @*
+EXAMPLE: example getOneVar; shows an example
+"
+{
+  ASSUME(0, nvars(basering)==2 );
+  ASSUME(0, (vari==2) || (vari==1) );
+
+  def R = basering;
+  list RL = ringlist(R);
+  // We keep everything from R but we change the ordering to lp, and we
+  // order the variables as needed.
+  RL[3] = list(list("lp", 1:2), list("C", 0:1));
+  RL[2] = list(var(3-vari), var(vari));
+  RL[4]=ideal(0); // does not work with qrings: Ex.7 of paraplanecurves
+  def RR = ring(RL);
+  setring RR;
+  ideal J = imap(R, J);
+  J = groebner(J);
+  poly g = J[1];
+  setring R;
+  poly g = imap(RR, g);
+  return(g);
+}
+example
+{ "EXAMPLE:";
+  printlevel = printlevel+1;
+  echo = 2;
+  ring s = 0,(x,y),dp;
+  ideal J = x3-y, y3;
+  getOneVar(J, 1);
+
+  echo = 0;
+  printlevel = printlevel-1;
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc getSmallest(ideal J)
+"USAGE:   getSmallest(J); J is an ideal.
+RETURN:  the generator of J of smallest degree. If there are more than one, it
+         chooses the one with smallest number of monomials.@*
+NOTE:    It looks only at the generator of J, not at all the polynomials in
+         the ideal.@*
+         It is intended maninly to compute a good universal denominator in the
+         normalization algorithms.@*
+EXAMPLE: example getSmallest; shows an example
+"
+{
+
+// Computes the polynomial of smallest degree of J.
+//
+  int i;
+  poly p = J[1];
+  int d = deg(p);
+  int di;
+  for(i = 2; i <= ncols(J); i++)
+  {
+    if(J[i] != 0)
+    {
+      di = deg(J[i]);
+      if(di < d)
+      {
+        p = J[i];
+        d = di;
+      }
+      else
+      {
+        if(di == d)
+        {
+          if(size(J[i]) < size(p))
+          {
+            p = J[i];
+          }
+        }
+      }
+    }
+  }
+  return(p);
+}
+example
+{ "EXAMPLE:";
+  printlevel = printlevel+1;
+  echo = 2;
+  ring s = 0,(x,y),dp;
+  ideal J = x3-y, y5, x2-y2+1;
+  getSmallest(J);
+
+  echo = 0;
+  printlevel = printlevel-1;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static proc getGenerators(ideal J, ideal U, poly c)
+{
+
+// Computes the generators of J as an ideal in the original ring,
+// where J is given by generators in the new ring.
+
+// The new ring is given by 1/c * U in the total ring of fractions.
+
+  int i, j;                             // counters;
+  int dbg = printlevel - voice + 2;     // dbg = printlevel (default: dbg = 0)
+  poly p;                               // The lifted polynomial
+  ideal JGr = groebner(J);              // Groebner base of J
+
+  if(dbg>1){"Checking for new generators...";}
+  for(i = 1; i <= ncols(J); i++)
+  {
+    for(j = 1; j <= ncols(U); j++)
+    {
+      p = lift(c, J[i]*U[j])[1,1];
+      p = reduce(p, JGr);
+      if(p != 0)
+      {
+        if(dbg>1)
+        {
+          "New polynoial added:", p;
+          if(dbg>4) {pause();}
+        }
+        JGr = JGr, p;
+        JGr = groebner(JGr);
+        J = J, p;
+      }
+    }
+  }
+  return(J);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static proc testIdeal(ideal I, ideal U, ideal origJ, poly c, poly D)
+{
+
+  ASSUME(1, not isQuotientRing(basering) );
+
+// Internal procedure, used in normalM.
+// Computes the test ideal in the new ring.
+// It takes the original test ideal and computes the radical of it in the
+// new ring.
+
+// The new ring is 1/c * U.
+// The original test ideal is origJ.
+// The original ring is R / I, where R is the basering.
+  intvec save_opt=option(get);
+  int i;                                // counter
+  int dbg = printlevel - voice + 2;     // dbg = printlevel (default: dbg = 0)
+  def R = basering;                      // We dont work in the quo
+  ideal J = origJ;
+
+  // ---------- computation of the ring structure of 1/c * U ----------------
+  U = lineUp(U, c);
+
+  if(dbg > 1){"Computing the new ring structure...";}
+  list ele = computeRing(U, I, "noRed");
+
+  def origEre = ele[1];
+  setring origEre;
+  if(dbg > 1){"The relations are"; norid;}
+
+  // ---------------- setting the ring to work in  --------------------------
+  int isGlobal = attrib(origEre,"global");      // Checks if the original ring has
+                                         // global ordering.
+  if(isGlobal != 1)
+  {
+    list rl = ringlist(origEre);
+    list origOrd = rl[3];
+    list newOrd = list("dp", intvec(1:nvars(origEre))), list("C", 0);
+    rl[3] = newOrd;
+    def ere = ring(rl);     // globR is the original ring but
+                            // with a global ordering.
+    setring ere;
+    ideal norid = imap(origEre, norid);
+  }
+  else
+  {
+    def ere = origEre;
+  }
+
+  ideal I = imap(R, I);
+  ideal J = imap(R, J);
+  J = J, norid, I;
+
+
+  // ----- computation of the test ideal using the ring structure of Ai -----
+
+  option(redSB);
+  option(returnSB);
+
+  if(dbg > 1){"Computing the radical of J...";}
+  J = radical(J);
+  if(dbg > 1){"Computing the interreduction of the radical...";}
+  J = groebner(J);
+  //J = interred(J);
+  if(dbg > 1)
+  {
+    "The radical in the generated ring is";
+    J;
+    if(dbg>4){pause();}
+  }
+
+  setring ere;
+
+  // -------------- map from Ai to the total ring of fractions ---------------
+  // Now we must map back this ideal J to U_i / c in the total ring of
+  // fractions.
+  // The map sends T_j -> u_j / c.
+  // The map is built by the following steps:
+  // 1) We compute the degree of the generators of J with respect to the
+  //    new variables T_j.
+  // 2) For each generator, we multiply each term by a power of c, as if
+  //    taking c^n as a common denominator (considering the new variables as
+  //    a polynomial in the old variables divided by c).
+  // 3) We replace the new variables T_j by the corresponding numerator u_j.
+  // 4) We lift the resulting polynomial to change the denominator
+  //    from c^n to c.
+  int nNewVars = nvars(ere) - nvars(R);      // Number of new variables
+  poly c = imap(R, c);
+  intvec @v = 1..nNewVars;    // Vector of the new variables.
+                              // They must be the first ones.
+  if(dbg > 1){"The indices of the new variables are", @v;}
+
+  // ---------------------- step 1 of the mapping ---------------------------
+  intvec degs;
+  for(i = 1; i<=ncols(J); i++)
+  {
+    degs[i] = degSubring(J[i], @v);
+  }
+  if(dbg > 1)
+  {
+    "The degrees with respect to the new variables are";
+    degs;
+  }
+
+  // ---------------------- step 2 of the mapping ---------------------------
+  ideal mapJ = mapBackIdeal(J, c, @v);
+
+  setring R;
+
+  // ---------------------- step 3 of the mapping ---------------------------
+  ideal z;                    // The variables of the original ring in order.
+  for(i = 1; i<=nvars(R); i++)
+  {
+    z[i] = var(i);
+  }
+
+  map f = ere, U[2..ncols(U)], z[1..ncols(z)]; // The map to the original ring.
+  if(dbg > 1)
+  {
+    "The map is ";
+    f;
+    if(dbg>4){pause();}
+  }
+
+  if(dbg > 1){ "Computing the map..."; }
+
+  J = f(mapJ);
+  if(dbg > 1)
+  {
+    "The ideal J mapped back (before lifting) is";
+    J;
+    if(dbg>4){pause();}
+  }
+
+  // ---------------------- step 4 of the mapping ---------------------------
+  qring Q = groebner(I);
+  ideal J = imap(R, J);
+  poly c = imap(R, c);
+  for(i = 1; i<=ncols(J); i++)
+  {
+    if(degs[i]>1)
+    {
+      J[i] = lift(c^(degs[i]-1), J[i])[1,1];
+    }
+    else
+    {
+      if(degs[i]==0) { J[i] = c*J[i]; }
+    }
+  }
+
+  if(dbg > 1)
+  {
+    "The ideal J lifted is";
+    J;
+    if(dbg>4){pause();}
+  }
+
+  // --------------------------- prepare output ----------------------------
+  J = groebner(J);
+
+  setring R;
+  J = imap(Q, J);
+
+  option(set,save_opt);
+  return(list(J, ele[1]));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc changeDenominator(ideal U1, poly c1, poly c2, ideal I)
+"USAGE:   changeDenominator(U1, c1, c2, I); U1 and I ideals, c1 and c2
+         polynomials.@*
+RETURN:  an ideal U2 such that the A-modules 1/c1 * U1 and 1/c2 * U2 are equal,
+         where A = R/I and R is the basering.@*
+NOTE:    It assumes that such U2 exists. It is intended maninly as an auxiliary
+         procedure in the normalization algorithms.@*
+EXAMPLE: example changeDenominator; shows an example
+"
+{
+  ASSUME(0, not isQuotientRing(basering) );
+// Let A = R / I. Given an A-module in the form 1/c1 * U1 (U1 ideal of A), it
+// computes a new ideal U2 such that the the A-module is 1/c2 * U2.
+// The base ring is R, but the computations are to be done in R / I.
+  int a;      // counter
+  def R = basering;
+  qring Q = I;
+  ideal U1 = fetch(R, U1);
+  poly c1 = fetch(R, c1);
+  poly c2 = fetch(R, c2);
+  ideal U2 = changeDenominatorQ(U1, c1, c2);
+  setring R;
+  ideal U2 = fetch(Q, U2);
+  return(U2);
+}
+example
+{
+  "EXAMPLE:";
+  echo = 2;
+  ring s = 0,(x,y),dp;
+  ideal I = y5-y4x+4y2x2-x4;
+  ideal U1 = normal(I)[2][1];
+  poly c1 = U1[4];
+  U1;c1;
+  // 1/c1 * U1 is the normalization of I.
+  ideal U2 = changeDenominator(U1, c1, x3, I);
+  U2;
+  // 1/x3 * U2 is also the normalization of I, but with a different denominator.
+  echo = 0;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static proc changeDenominatorQ(ideal U1, poly c1, poly c2)
+{
+// Given a ring in the form 1/c1 * U, it computes a new U2 st the ring
+// is 1/c2 * U2.
+// The base ring is already a quotient ring R / I.
+  int a;      // counter
+  ideal U2;
+  poly p;
+  for(a = 1; a <= ncols(U1); a++)
+  {
+    p = lift(c1, c2*U1[a])[1,1];
+    U2[a] = p;
+  }
+  return(U2);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static proc checkInclusions(ideal U1, ideal U2)
+{
+// Checks if the identity A = Hom(J, J) of Grauert-Remmert criterion is
+// satisfied.
+  int dbg = printlevel - voice + 2;     // dbg = printlevel (default: dbg = 0)
+  list reduction1;
+  list reduction2;
+
+  // ---------------------- inclusion Hom(J, J) c A -------------------------
+  if(dbg > 1){"Checking the inclusion Hom(J, J) c A:";}
+  // This interred is used only because a bug in groebner!
+  U1 = groebner(U1);
+  reduction1 = reduce(U2, U1);
+  if(dbg > 1){reduction1[1];}
+
+  // ---------------------- inclusion A c Hom(J, J) -------------------------
+  // The following check should always be satisfied.
+  // This is only used for debugging.
+  if(dbg > 1)
+  {
+    "and the inclusion A c Hom(J, J): (this should always be satisfied)";
+    // This interred is used only because a bug in groebner!
+    U2 = groebner(U2);
+    reduction2 = reduce(U1, groebner(U2));
+    reduction2[1];
+    if(size(reduction2[1]) > 0)
+    {
+      "Something went wrong... (this inclusion should always be satisfied)";
+      ~;
+    }
+    else
+    {
+      if(dbg>4){pause();}
+    }
+  }
+
+  if(size(reduction1[1]) == 0)
+  {
+    // We are done! The ring computed in the last step was normal.
+    return(1);
+  }
+  else
+  {
+    return(0);
+  }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static proc degSubring(poly p, intvec @v)
+{
+  ASSUME(1, not isQuotientRing(basering) );
+// Computes the degree of a polynomial taking only some variables as variables
+// and the others as parameters.
+
+// The degree is taken w.r.t. the variables indicated in v.
+  int i;      // Counter
+  int d = 0;  // The degree
+  int e;      // Degree (auxiliar variable)
+  for(i = 1; i <= size(p); i++)
+  {
+    e = sum(leadexp(p[i]), @v);
+    if(e > d){d = e;}
+  }
+  return(d);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static proc mapBackIdeal(ideal I, poly c, intvec @v)
+{
+   ASSUME(1, not isQuotientRing(basering) );
+
+// Modifies all polynomials in I so that a map x(i) -> y(i)/c can be
+// carried out.
+
+// v indicates wicih variables x(i) of the ring will be mapped to y(i)/c.
+
+  int i;  // counter
+  for(i = 1; i <= ncols(I); i++)
+  {
+    I[i] = mapBackPoly(I[i], c, @v);
+  }
+  return(I);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static proc mapBackPoly(poly p, poly c, intvec @v)
+{
+  ASSUME(1, not isQuotientRing(basering) );
+
+// Multiplies each monomial of p by a power of c so that a map x(i) -> y(i)/c
+// can be carried out.
+
+// v indicates wicih variables x(i) of the ring will be mapped to y(i)/c.
+  int i;  // counter
+  int e;  // exponent
+  int d = degSubring(p, @v);
+  poly g = 0;
+  int size_p=size(p);
+  for(i = 1; i <= size_p; i++)
+  {
+    e = sum(leadexp(p[i]), @v);
+    g = g + p[i] * c^(d-e);
+  }
+  return(g);
+}
+
+//                    End procedures for normal
+///////////////////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////////////////
+//                  Begin procedures for normalC
+
+// We first define resp. copy some attributes to be used in proc normal and
+// static proc normalizationPrimes, and ..., to speed up computation in
+// special cases
+//NOTE:  We use the following attributes:
+// 1     attrib(id,"isCohenMacaulay");         //--- Cohen Macaulay
+// 2     attrib(id,"isCompleteIntersection");  //--- complete intersection
+// 3     attrib(id,"isHypersurface");          //--- hypersurface
+// 4     attrib(id,"isEquidimensional");       //--- equidimensional ideal
+// 5     attrib(id,"isPrim");                  //--- prime ideal
+// 6     attrib(id,"isRegInCodim2");           //--- regular in codimension 2
+// 7     attrib(id,"isIsolatedSingularity");   //--- isolated singularities
+// 8     attrib(id,"onlySingularAtZero");      //--- only singular at 0
+// 9     attrib(id,"isRadical");               //--- radical ideal
+//Recall: (attrib(id,"xy"),1) sets attrib xy to TRUE and
+//        (attrib(id,"xy"),0) to FALSE
+
+static proc getAttrib (ideal id)
+"USAGE:   getAttrib(id);  id=ideal
+COMPUTE: check attributes for id. If the attributes above are defined,
+         take its value, otherwise define it and set it to 0
+RETURN:  intvec of size 9, with entries 0 or 1,  values of attributes defined
+         above (in this order)
+EXAMPLE: no example
+"
+{
+  int isCoM,isCoI,isHy,isEq,isPr,isReg,isIso,oSAZ,isRad;
+
+  if( typeof(attrib(id,"isCohenMacaulay"))=="int" )
+  {
+    if( attrib(id,"isCohenMacaulay")==1 )
+    { isCoM=1; isEq=1; }
+  }
+
+  if( typeof(attrib(id,"isCompleteIntersection"))=="int" )
+  {
+    if(attrib(id,"isCompleteIntersection")==1)
+    { isCoI=1; isCoM=1; isEq=1; }
+  }
+
+  if( typeof(attrib(id,"isHypersurface"))=="int" )
+  {
+    if(attrib(id,"isHypersurface")==1)
+    { isHy=1; isCoI=1; isCoM=1; isEq=1; }
+  }
+
+  if( typeof(attrib(id,"isEquidimensional"))=="int" )
+  {
+    if(attrib(id,"isEquidimensional")==1)
+    { isEq=1; }
+  }
+
+  if( typeof(attrib(id,"isPrim"))=="int" )
+  {
+    if(attrib(id,"isPrim")==1)
+    { isPr=1; }
+  }
+
+  if( typeof(attrib(id,"isRegInCodim2"))=="int" )
+  {
+    if(attrib(id,"isRegInCodim2")==1)
+    { isReg=1; }
+  }
+
+  if( typeof(attrib(id,"isIsolatedSingularity"))=="int" )
+  {
+    if(attrib(id,"isIsolatedSingularity")==1)
+    { isIso=1; }
+  }
+
+  if( typeof(attrib(id,"onlySingularAtZero"))=="int" )
+  {
+    if(attrib(id,"onlySingularAtZero")==1)
+    { oSAZ=1; }
+  }
+
+  if( typeof(attrib(id,"isRad"))=="int" )
+  {
+    if(attrib(id,"isRad")==1)
+    { isRad=1; }
+  }
+
+  intvec atr = isCoM,isCoI,isHy,isEq,isPr,isReg,isIso,oSAZ,isRad;
+  return(atr);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static proc setAttrib (ideal id, intvec atr)
+"USAGE:   setAttrib(id,atr);  id ideal, atr intvec
+COMPUTE: set attributes to id specified by atr
+RETURN:  id, with assigned attributes from atr
+EXAMPLE: no example
+"
+{
+  attrib(id,"isCohenMacaulay",atr[1]);         //--- Cohen Macaulay
+  attrib(id,"isCompleteIntersection",atr[2]);  //--- complete intersection
+  attrib(id,"isHypersurface",atr[3]);          //--- hypersurface
+  attrib(id,"isEquidimensional",atr[4]);       //--- equidimensional ideal
+  attrib(id,"isPrim",atr[5]);                  //--- prime ideal
+  attrib(id,"isRegInCodim2",atr[6]);           //--- regular in codimension 2
+  attrib(id,"isIsolatedSingularity",atr[7]);   //--- isolated singularities
+  attrib(id,"onlySingularAtZero",atr[8]);      //--- only singular at 0
+  attrib(id,"isRadical",atr[9]);               //--- radical ideal
+
+  return(id);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// copyAttribs is not used anywhere so far
+
+static proc copyAttribs (ideal id1, ideal id)
+"USAGE:   copyAttribs(id1,id);  id1, id ideals
+COMPUTE: copy attributes from id1 to id
+RETURN:  id, with assigned attributes from id1
+EXAMPLE: no example
+"
+{
+  if( typeof(attrib(id1,"isCohenMacaulay"))=="int" )
+  {
+    if( attrib(id1,"isCohenMacaulay")==1 )
+    {
+      attrib(id,"isEquidimensional",1);
+    }
+  }
+  else
+  {
+    attrib(id,"isCohenMacaulay",0);
+  }
+
+  if( typeof(attrib(id1,"isCompleteIntersection"))=="int" )
+  {
+    if(attrib(id1,"isCompleteIntersection")==1)
+    {
+      attrib(id,"isCohenMacaulay",1);
+      attrib(id,"isEquidimensional",1);
+    }
+  }
+  else
+  {
+    attrib(id,"isCompleteIntersection",0);
+  }
+
+  if( typeof(attrib(id1,"isHypersurface"))=="int" )
+  {
+    if(attrib(id1,"isHypersurface")==1)
+    {
+      attrib(id,"isCompleteIntersection",1);
+      attrib(id,"isCohenMacaulay",1);
+      attrib(id,"isEquidimensional",1);
+    }
+  }
+  else
+  {
+    attrib(id,"isHypersurface",0);
+  }
+
+  if( (typeof(attrib(id1,"isEquidimensional"))=="int") )
+  {
+    if(attrib(id1,"isEquidimensional")==1)
+    {
+      attrib(id,"isEquidimensional",1);
+    }
+  }
+  else
+  {
+    attrib(id,"isEquidimensional",0);
+  }
+
+  if( typeof(attrib(id1,"isPrim"))=="int" )
+  {
+    if(attrib(id1,"isPrim")==1)
+    {
+      attrib(id,"isEquidimensional",1);
+    }
+  }
+  else
+  {
+    attrib(id,"isPrim",0);
+  }
+
+  if( (typeof(attrib(id1,"isRegInCodim2"))=="int") )
+  {
+    if(attrib(id1,"isRegInCodim2")==1)
+    {
+      attrib(id,"isRegInCodim2",1);
+    }
+  }
+  else
+  {
+    attrib(id,"isRegInCodim2",0);
+  }
+
+  if( (typeof(attrib(id1,"isIsolatedSingularity"))=="int") )
+  {
+    if(attrib(id1,"isIsolatedSingularity")==1)
+    {
+      attrib(id,"isIsolatedSingularity",1);
+    }
+  }
+  else
+  {
+    attrib(id,"isIsolatedSingularity",0);
+  }
+
+  if( typeof(attrib(id1,"onlySingularAtZero"))=="int" )
+  {
+    if(attrib(id1,"onlySingularAtZero")==1)
+    {
+      attrib(id,"isIsolatedSingularity",1);
+    }
+  }
+  else
+  {
+    attrib(id,"onlySingularAtZero",0);
+  }
+
+  if( typeof(attrib(id1,"isRad"))=="int" )
+  {
+    if(attrib(id1,"isRad")==1)
+    {
+      attrib(id,"isRad",1);
+    }
+  }
+  else
+  {
+    attrib(id,"isRad",0);
+  }
+  return(id);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc normalC(ideal id, list #)
+"USAGE:  normalC(id [,choose]);  id = radical ideal, choose = optional list
+         of string.
+         Optional parameters in list choose (can be entered in any order):@*
+         Decomposition:@*
+         - \"equidim\" -> computes first an equidimensional decomposition,
+         and then the normalization of each component (default).@*
+         - \"prim\" -> computes first the minimal associated primes, and then
+         the normalization of each prime. @*
+         - \"noDeco\" -> no preliminary decomposition is done. If the ideal is
+         not equidimensional radical, output might be wrong.@*
+         - \"isPrim\" -> assumes that the ideal is prime. If the assumption does
+         not hold, output might be wrong.@*
+         - \"noFac\" -> factorization is avoided in the computation of the
+         minimal associated primes;
+         Other:@*
+         - \"withGens\" -> the minimal associated primes P_i of id are
+         computed and for each P_i, algebra generators of the integral closure
+         of basering/P_i are computed as elements of its quotient field;@*
+         If choose is not given or empty, the default options are used.@*
+ASSUME:  The ideal must be radical, for non-radical ideals the output may
+         be wrong (id=radical(id); makes id radical). However, if option
+         \"prim\" is set the minimal associated primes are computed first
+         and hence normalC computes the normalization of the radical of id.
+         \"isPrim\" should only be used if id is known to be irreducible.
+RETURN:  a list, say nor, of size 2 (resp. 3 if option \"withGens\" is set).@*
+         * nor[1] is always a of r rings, where r is the number of associated
+         primes with option \"prim\" (resp. >= no of equidimenensional
+         components with option  \"equidim\").@*
+         Each ring Ri=nor[1][i], i=1..r, contains two ideals with given
+         names @code{norid} and @code{normap} such that @*
+         - Ri/norid is the normalization of the i-th component, i.e. the
+          integral closure in its field of fractions as affine ring, i.e. Ri is
+          given in the form K[X(1..p),T(1..q)], where K is the ground field;
+         - normap gives the normalization map from basering/id to
+           Ri/norid for each i (the j-th element of normap is mapped to the
+           j-th variable of R).@*
+         - the direct sum of the rings Ri/norid is the normalization
+           of basering/id; @*
+         ** If option \"withGens\" is not set: @*
+         * nor[2] shows the delta invariants: nor[2] is a list of an intvec of
+         size r, the delta invariants of the r components, and an integer, the
+         delta invariant of basering/id. (-1 means infinite, 0 that basering/P_i
+         resp. basering/input is normal, -2 means that delta resp. delta of one
+         of the components is not computed (which may happen if \"equidim\" is
+         given). @*
+         ** If option \"withGens\" is set:
+         * nor[2] is a list of ideals Ii=nor[2][i], i=1..r, in the basering,
+         generating the integral closure of basering/P_i in its quotient field
+         as K-algebra (K the ground field):@*
+         If Ii is given by polynomials g_1,...,g_k, then c:=g_k is a non-zero
+         divisor and the j-th variables of the ring Ri satisfies var(j)=g_j/c,
+         j=1..k-1, as element in the quotient field of basering/P_i. The
+         g_j/g_k+1 are K-algebra generators  of the integral closure of
+         basering/P_i.@*
+         * nor[3] shows the delta invariant as above.
+THEORY:  We use the Grauert-Remmert-de Jong algorithm [c.f. G.-M. Greuel,
+         G. Pfister: A SINGULAR Introduction to Commutative Algebra, 2nd Edition.
+         Springer Verlag (2007)].
+         The procedure computes the algebra structure and the delta invariant of
+         the normalization of R/id:@*
+         The normalization is an affine algebra over the ground field K
+         and nor[1] presents it as such: Ri = K[X(1..p),T(1..q)] and Ri/norid
+         is the integral closure of R/P_i; if option \"withGens\" is set the
+         X(j) and T(j) are expressed as quotients in the total ring of
+         fractions. Note that the X(j) and T(j) generate the integral closure
+         as K-algebra, but not necessarily as R-module (since relations of the
+         form X(1)=T(1)*T(2) may have been eliminated). Geometrically the
+         algebra structure is relevant since the variety of the ideal norid in
+         Ri is the normalization of the variety of the ideal P_i in R.@*
+         The delta invariant of a reduced ring A is dim_K(normalization(A)/A).
+         For A=K[x1,...,xn]/id we call this number also the delta invariant of
+         id. nor[3] returns the delta invariants of the components P_i and of
+         id.
+NOTE:    To use the i-th ring type: @code{def R=nor[1][i]; setring R;}.
+@*       Increasing/decreasing printlevel displays more/less comments
+         (default: printlevel=0).
+@*       Not implemented for local or mixed orderings or quotient rings.
+         For local or mixed orderings use proc 'normal'.
+@*       If the input ideal id is weighted homogeneous a weighted ordering may
+         be used (qhweight(id); computes weights).
+KEYWORDS: normalization; integral closure; delta invariant.
+SEE ALSO: normal, normalP.
+EXAMPLE: example normalC; shows an example
+"
+{
+   ASSUME(0, not isQuotientRing(basering) );
+
+   int i,j;
+   int withGens, withEqui, withPrim, isPrim, noFac;
+   int dbg = printlevel-voice+2;
+   int nvar = nvars(basering);
+   int chara  = char(basering);
+   list result, prim, keepresult;
+
+  int decomp;   // Preliminar decomposition:
+                // 0 -> no decomposition (id is assumed to be prime)
+                // 1 -> no decomposition
+                //      (id is assumed to be equidimensional radical)
+                // 2 -> equidimensional decomposition
+                // 3 -> minimal associated primes
+
+   // Default methods:
+   noFac = 0;         // Use facstd when computing minimal associated primes
+   decomp = 2;        // Equidimensional decomposition for nvar > 2
+   if (nvar <= 2)
+   { decomp = 3; }    // Compute minimal associated primes if nvar <= 2
+
+   if ( attrib(basering,"global") != 1 )
+   {
+     "";
+     "// Not implemented for this ordering,";
+     "// please change to global ordering or use proc normal";
+     return(result);
+   }
+
+//--------------------------- define the method ---------------------------
+   string method;                //make all options one string in order to use
+                                 //all combinations of options simultaneously
+   for ( i=1; i <= size(#); i++ )
+   {
+     if ( typeof(#[i]) == "string" )
+     {
+       method = method + #[i];
+     }
+   }
+
+   //--------------------------- choosen methods -----------------------
+   // "withGens": computes algebra generators for each irreducible component
+   // ### the extra code for withGens should be incorporated in the general case
+
+   if ( find(method,"withgens") or find(method,"withGens"))
+   {
+     withGens = 1;
+   }
+
+   // the general case: either equidim or minAssGTZ or no decomposition
+
+   if ( find(method,"isprim") or find(method,"isPrim") )
+   {decomp = 0; isPrim=1;}
+
+   if ( find(method,"nodeco") or find(method,"noDeco") )
+   {decomp = 1;}
+
+   if ( find(method,"equidim") )
+   { decomp = 2; }
+
+   if ( find(method,"prim") )
+   { decomp = 3; }
+
+   if ( find(method,"nofac") or find(method,"noFac") )
+   { noFac = 1; }
+
+   kill #;
+   list #;
+
+//------- Special algorithm with computation of the generators, RETURN -------
+   //--------------------- method "withGens" ----------------------------------
+   //the integral closure is computed in proc primeClosure. In the general case
+   //it is computed in normalizationPrimes. The main difference is that in
+   //primeClosure the singular locus is only computed in the first iteration,
+   //that no attributes are used, and that the generators are computed.
+   //In primeClosure the (algebra) generators for each irreducible component
+   //are computed in the static proc closureGenerators
+
+   if( withGens )
+   {
+      if( dbg >= 1 )
+      {  "";
+         "// We use method 'withGens'";
+      }
+      if ( decomp == 0 or decomp == 1 )
+      {
+         prim[1] = id;
+         if( dbg >= 0 )
+         {
+           "";
+           "// ** WARNING: result is correct if ideal is prime (not checked) **";
+           "// if procedure is called with string \"prim\", primality is checked";
+         }
+      }
+      else
+      {
+         if(dbg >= 1)
+         {  "// Computing minimal associated primes..."; }
+
+         if( noFac )
+         { prim = minAssGTZ(id,1); }
+         else
+         { prim = minAssGTZ(id); }
+
+         if(dbg >= 2)
+         {  prim;""; }
+         if(dbg >= 1)
+         {
+            "// number of irreducible components is", size(prim);
+         }
+      }
+   //----------- compute integral closure for every component -------------
+      int del;
+      intvec deli;
+      list Gens,l,resu,Resu;
+      ideal gens;
+      def R = basering;
+      poly gg;
+
+      for(i=1; i<=size(prim); i++)
+      {
+         if(dbg>=1)
+         {
+            ""; pause(); "";
+            "// Computing normalization of component",i;
+            "   ---------------------------------------";
+         }
+
+         if( defined(ker) ) { kill ker; }
+         ideal ker = prim[i];
+         export(ker);
+         l = R;
+         l = primeClosure(l,1);              //here the work is done
+         // primeClosure is called with list l consisting of the basering
+         //### ausprobieren ob primeClosure(l,1) schneller als primeClosure(l)
+         // 1 bedeutet: kuerzester nzd
+         // l[size(l)] is the delta invariant
+
+         if ( l[size(l)] >= 0 && del >= 0 )
+         {
+            del = del + l[size(l)];
+         }
+         else
+         { del = -1; }
+         deli = l[size(l)],deli;
+
+         l = l[1..size(l)-1];
+         resu = list(l[size(l)]) + resu;
+         gens = closureGenerators(l);         //computes algebra(!) generators
+
+         //NOTE: gens[i]/gens[size(gens)] expresses the ith variable of resu[1]
+         //(the normalization) as fraction of elements of the basering;
+         //the variables of resu[1] are algebra generators.
+         //gens[size(gens)] is a non-zero divisor of basering/i
+
+         //divide by the greatest common divisor:
+         gg = gcd( gens[1],gens[size(gens)] );
+         for(j=2; j<=size(gens)-1; j++)
+         {
+            gg=gcd(gg,gens[j]);
+         }
+         for(j=1; j<=size(gens); j++)
+         {
+            gens[j]=gens[j]/gg;
+         }
+         Gens = list(gens) + Gens;
+
+/*       ### Da die gens Algebra-Erzeuger sind, ist reduce nach Bestimmung
+         der Algebra-Variablen T(i) nicht zulaessig!
+         for(i=1;i<=size(gens)-1;i++)
+         {
+            gens[i]= reduce(gens[i],std(gens[size(gens)]));
+         }
+         for(i=size(gens)-1; i>=1; i--)
+         {
+            if(gens[i]==0)
+            { gens = delete(gens,i); }
+         }
+*/
+         if( defined(ker) ) { kill ker; }
+      }
+
+      if ( del >= 0 )
+      {
+         int mul = iMult(prim);
+         del = del + mul;
+      }
+      else
+      { del = -1; }
+      deli = deli[1..size(deli)-1];
+      Resu = resu,Gens,list(deli,del);
+      int sr = size(resu);
+
+      if ( dbg >= 0 )
+      {"";
+"// 'normalC' created a list, say nor, of three lists:
+// To see the list type
+      nor;
+
+// * nor[1] is a list of",sr,"ring(s)
+// To access the i-th ring nor[1][i] give it a name, say Ri, and type e.g.
+     def R1 = nor[1][1]; setring R1;  norid; normap;
+// For the other rings type first (if R is the name of your original basering)
+     setring R;
+// and then continue as for R1.
+// Ri/norid is the affine algebra of the normalization of the i-th
+// component R/P_i (where P_i is an associated prime of the input ideal id)
+// and normap the normalization map from R to Ri/norid.
+
+// * nor[2] is a list of",sr,"ideal(s), each ideal nor[2][i] consists of
+// elements g1..gk of R such that the gj/gk generate the integral
+// closure of R/P_i as sub-algebra in the quotient field of R/P_i, with
+// gj/gk being mapped by normap to the j-th variable of Ri;
+
+// * nor[3] shows the delta-invariant of each component and of id
+// (-1 means infinite, and 0 that R/P_i resp. R/id is normal).";
+      }
+      return(Resu);
+   }
+   //----------------- end method "withGens" --------------------------------
+
+//-------- The general case without computation of the generators -----------
+// (attrib(id,"xy"),1) sets attrib xy to TRUE and (attrib(id,"xy"),0) to FALSE
+// We use the following attributes:
+//   attrib(id,"isCohenMacaulay");         //--- Cohen Macaulay
+//   attrib(id,"isCompleteIntersection");  //--- complete intersection
+//   attrib(id,"isHypersurface");          //--- hypersurface
+//   attrib(id,"isEquidimensional",-1);    //--- equidimensional ideal
+//   attrib(id,"isPrim");                  //--- prime ideal
+//   attrib(id,"isRegInCodim2");           //--- regular in codimension 2
+//   attrib(id,"isIsolatedSingularity";    //--- isolated singularities
+//   attrib(id,"onlySingularAtZero");      //--- only singular at 0
+
+ //------------------- first set the attributes ----------------------
+   if( typeof(attrib(id,"isCohenMacaulay"))=="int" )
+   {
+      if( attrib(id,"isCohenMacaulay")==1 )
+      {
+         attrib(id,"isEquidimensional",1);
+      }
+   }
+   else
+   {
+      attrib(id,"isCohenMacaulay",0);
+   }
+
+   if( typeof(attrib(id,"isCompleteIntersection"))=="int" )
+   {
+      if(attrib(id,"isCompleteIntersection")==1)
+      {
+         attrib(id,"isCohenMacaulay",1);
+         attrib(id,"isEquidimensional",1);
+      }
+   }
+   else
+   {
+      attrib(id,"isCompleteIntersection",0);
+   }
+
+   if( typeof(attrib(id,"isHypersurface"))=="int" )
+   {
+      if(attrib(id,"isHypersurface")==1)
+      {
+         attrib(id,"isCompleteIntersection",1);
+         attrib(id,"isCohenMacaulay",1);
+         attrib(id,"isEquidimensional",1);
+      }
+   }
+   else
+   {
+      attrib(id,"isHypersurface",0);
+   }
+
+   if( ! (typeof(attrib(id,"isEquidimensional"))=="int") )
+   {
+         attrib(id,"isEquidimensional",0);
+   }
+
+   if( typeof(attrib(id,"isPrim"))=="int" )
+   {
+      if(attrib(id,"isPrim")==1)
+      {
+         attrib(id,"isEquidimensional",1);
+      }
+   }
+   else
+   {
+      attrib(id,"isPrim",0);
+   }
+
+   if( ! (typeof(attrib(id,"isRegInCodim2"))=="int") )
+   {
+         attrib(id,"isRegInCodim2",0);
+   }
+
+   if( ! (typeof(attrib(id,"isIsolatedSingularity"))=="int") )
+   {
+         attrib(id,"isIsolatedSingularity",0);
+   }
+
+   if( typeof(attrib(id,"onlySingularAtZero"))=="int" )
+   {
+      if(attrib(id,"onlySingularAtZero")==1)
+      {
+         attrib(id,"isIsolatedSingularity",1);
+      }
+   }
+   else
+   {
+      attrib(id,"onlySingularAtZero",0);
+   }
+
+   //-------------- compute equidimensional decomposition --------------------
+   //If the method "equidim" is given, compute the equidim decomposition
+   //and goto the next step (no normalization
+   //ACHTUNG: equidim berechnet bei nicht reduzierten id die eingebetteten
+   //Komponenten als niederdim Komponenten, waehrend diese bei primdecGTZ
+   //nicht auftauchen: ideal(x,y)*xy
+   //this is default for nvars > 2
+
+   if( decomp == 2 )
+   {
+      withPrim = 0;                 //this is used to check later that prim
+                                    //contains equidim but not prime components
+      if( dbg >= 1 )
+      {
+         "// We use method 'equidim'";
+      }
+      if( typeof(attrib(id,"isEquidimensional"))=="int" )
+      {
+         if(attrib(id,"isEquidimensional")==1)
+         {
+            prim[1] = id;
+         }
+         else
+         {
+            prim = equidim(id);
+         }
+      }
+      else
+      {
+         prim = equidim(id);
+      }
+      if(dbg>=1)
+      {  "";
+         "// number of equidimensional components:", size(prim);
+      }
+      if ( !noFac )
+      {
+        intvec opt = option(get);
+        option(redSB);
+        for(j=1; j<=size(prim); j++)
+        {
+           keepresult = keepresult+facstd(prim[j]);
+        }
+        prim = keepresult;
+        if ( size(prim) == 0 )
+        {
+          prim=ideal(0);     //Bug in facstd, liefert leere Liste bei 0-Ideal
+        }
+
+        if(dbg>=1)
+        {  "";
+         "// number of components after application of facstd:", size(prim);
+        }
+        option(set,opt);
+      }
+   }
+
+   //------------------- compute associated primes -------------------------
+   //the case where withEqui = 0, here the min. ass. primes are computed
+   //start with the computation of the minimal associated primes:
+
+   else
+   {
+    if( isPrim )
+    {
+      if( dbg >= 0 )
+      {
+         "// ** WARNING: result is correct if ideal is prime";
+         "// or equidimensional (not checked) **";
+         "// disable option \"isPrim\" to decompose ideal into prime";
+         "// or equidimensional components";"";
+      }
+      if( dbg >= 1 )
+      {
+        "// We use method 'isPrim'";"";
+      }
+      prim[1]=id;
+    }
+    else
+    {
+      withPrim = 1;                 //this is used to check later that prim
+                                    //contains prime but not equidim components
+      if( dbg >= 1 )
+      {
+         "// We use method 'prim'";
+      }
+
+      if( typeof(attrib(id,"isPrim"))=="int" )
+      {
+         if(attrib(id,"isPrim")==1)
+         {
+            prim[1]=id;
+         }
+         else
+         {
+            if( noFac )
+            { prim=minAssGTZ(id,1); }     //does not use factorizing groebner
+            else
+            { prim=minAssGTZ(id); }       //uses factorizing groebner
+         }
+      }
+      else
+      {
+            if( noFac )
+            { prim=minAssGTZ(id,1); }
+            else
+            { prim=minAssGTZ(id); }
+      }
+      if(dbg>=1)
+      {  "";
+         "// number of irreducible components:", size(prim);
+      }
+    }
+   }
+
+   //----- for each component (equidim or irred) compute normalization -----
+   int sr, skr, del;
+   intvec deli;
+   int sp = size(prim);     //size of list prim (# irred or equidim comp)
+
+   for(i=1; i<=sp; i++)
+   {
+      if(dbg>=1)
+      {  "";
+         "// computing the normalization of component",i;
+         "   ----------------------------------------";
+      }
+      //-------------- first set attributes for components ------------------
+      attrib(prim[i],"isEquidimensional",1);
+      if( withPrim )
+      {
+         attrib(prim[i],"isPrim",1);
+      }
+      else
+      { attrib(prim[i],"isPrim",0); }
+
+      if(attrib(id,"onlySingularAtZero")==1)
+      { attrib(prim[i],"onlySingularAtZero",1); }
+      else
+      { attrib(prim[i],"onlySingularAtZero",0); }
+
+      if(attrib(id,"isIsolatedSingularity")==1)
+      { attrib(prim[i],"isIsolatedSingularity",1); }
+      else
+      { attrib(prim[i],"isIsolatedSingularity",0); }
+
+      if( attrib(id,"isHypersurface")==1 )
+      {
+         attrib(prim[i],"isHypersurface",1);
+         attrib(prim[i],"isCompleteIntersection",1);
+         attrib(prim[i],"isCohenMacaulay",1);
+      }
+      else
+      { attrib(prim[i],"isHypersurface",0); }
+
+      if ( sp == 1)         //the case of one component: copy attribs from id
+      {
+        if(attrib(id,"isRegInCodim2")==1)
+        {attrib(prim[i],"isRegInCodim2",1); }
+        else
+        {attrib(prim[i],"isRegInCodim2",0); }
+
+        if(attrib(id,"isCohenMacaulay")==1)
+        {attrib(prim[i],"isCohenMacaulay",1); }
+        else
+        {attrib(prim[i],"isCohenMacaulay",0); }
+
+        if(attrib(id,"isCompleteIntersection")==1)
+        {attrib(prim[i],"isCompleteIntersection",1); }
+        else
+        {attrib(prim[i],"isCompleteIntersection",0); }
+      }
+      else
+      {
+        attrib(prim[i],"isRegInCodim2",0);
+        attrib(prim[i],"isCohenMacaulay",0);
+        attrib(prim[i],"isCompleteIntersection",0);
+      }
+
+      //------ Now compute the normalization of each component ---------
+      //note: for equidimensional components the "splitting tools" can
+      //create further decomposition
+      //We now start normalizationPrimes with
+      //ihp = partial normalisation map = identity map = maxideal(1)
+      //del = partial delta invariant = 0
+      //deli= intvec of partial delta invariants of components
+      //in normalizationPrimes all the work is done:
+
+      keepresult = normalizationPrimes(prim[i],maxideal(1),0,0);
+
+      for(j=1; j<=size(keepresult)-1; j++)
+      {
+         result=insert(result,keepresult[j]);
+      }
+      skr = size(keepresult);
+
+      //compute delta:
+      if( del >= 0 && keepresult[skr][1] >=0 )
+      {
+         del = del + keepresult[skr][1];
+      }
+      else
+      {
+         del = -1;
+      }
+      deli = keepresult[skr][2],deli;
+
+      if ( dbg>=1 )
+      {
+           "// delta of component",i; keepresult[skr][1];
+      }
+   }
+   sr = size(result);
+
+   // -------------- Now compute intersection multiplicities -------------
+   //intersection multiplicities of list prim, sp=size(prim).
+      if ( dbg>=1 )
+      {
+        "// Sum of delta for all components"; del;
+        if ( sp>1 )
+        {
+           "// Compute intersection multiplicities of the components";
+        }
+      }
+
+      if ( sp > 1 )
+      {
+        int mul = iMult(prim);
+        if ( mul < 0 )
+        {
+           del = -1;
+        }
+        else
+        {
+           del = del + mul;
+        }
+      }
+   deli = deli[1..size(deli)-1];
+   result = result,list(deli,del);
+
+//--------------- Finally print comments and return ------------------
+   if ( dbg >= 0)
+   {"";
+"// 'normalC' created a list, say nor, of two lists:
+// To see the result, type
+      nor;
+
+// * nor[1] is a list of",sr,"ring(s).
+// To access the i-th ring nor[1][i] give it a name, say Ri, and type e.g.
+      def R1 = nor[1][1];  setring R1;  norid;  normap;
+// and similair for the other rings nor[1][i];
+// Ri/norid is the affine algebra of the normalization of r/P_i  (where P_i
+// is an associated prime or an equidimensional part of the input ideal id)
+// and normap the normalization map from the basering to Ri/norid;
+
+// * nor[2] shows the delta-invariant of each component and of id
+// (-1 means infinite, 0 that r/P_i resp. r/id is normal, and -2 that delta
+// of a component was not computed).";
+   }
+   return(result);
+}
+
+example
+{ "EXAMPLE:";
+   printlevel = printlevel+1;
+   echo = 2;
+   ring s = 0,(x,y),dp;
+   ideal i = (x2-y3)*(x2+y2)*x;
+
+   list nor = normalC(i);
+
+   nor;
+   // 2 branches have delta = 1, and 1 branch has delta = 0
+   // the total delta invariant is 13
+
+   def R2 = nor[1][2];  setring R2;
+   norid; normap;
+
+   echo = 0;
+   printlevel = printlevel-1;
+   pause("   hit return to continue"); echo=2;
+
+   ring r = 2,(x,y,z),dp;
+   ideal i = z3-xy4;
+   nor = normalC(i);  nor;
+   // the delta invariant is infinite
+   // xy2z/z2 and xy3/z2 generate the integral closure of r/i as r/i-module
+   // in its quotient field Quot(r/i)
+
+   // the normalization as affine algebra over the ground field:
+   def R = nor[1][1]; setring R;
+   norid; normap;
+
+   echo = 0;
+   pause("   hit return to continue");echo = 2;
+
+   setring r;
+   nor = normalC(i, "withGens", "prim");    // a different algorithm
+   nor;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//closureRingtower seems not to be used anywhere
+static proc closureRingtower(list L)
+"USAGE:    closureRingtower(list L); L a list of rings
+CREATE:   rings R(1),...,R(n) such that R(i)=L[i] for all i
+EXAMPLE:  example closureRingtower; shows an example
+"
+{
+  int n=size(L);
+  for (int i=1;i<=n;i++)
+    {
+      if (defined(R(i)))
+      {
+        string s="Fixed name R("+string(i)+") leads to conflict with existing "
+              +"object having this name";
+        ERROR(s);
+      }
+      def R(i)=L[i];
+      export R(i);
+    }
+
+  return();
+}
+example
+{
+  "EXAMPLE:"; echo=2;
+  ring R=0,(x,y),dp;
+  ideal I=x4,y4;
+  list L=primeClosure(ReesAlgebra(I)[1]);
+  L=delete(L,size(L));
+  L;
+  closureRingtower(L);
+  R(1);
+  R(4);
+  kill R(1),R(2),R(3),R(4);
+}
+
+//                Up to here: procedures for normalC
+///////////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////////
+//                From here: miscellaneous procedures
+
+// Used for timing and comparing the different normalization procedures.
+// Option (can be entered in any order)
+// "normal"   -> uses the new algortihm (normal)
+// "normalP"  -> uses normalP
+// "normalC"  -> uses normalC, without "withGens" option
+// "primCl"   -> uses normalC, with option "withGens".
+// "111"      -> checks the output of normalM using norTest.
+// "p"        -> compares the output of norM with the output of normalP
+//               ("normalP" option must also be set).
+// "pc"       -> compares the output of norM with the output of normalC with
+//               option "withGens"
+//               ("primCl" option must also be set).
+
+proc timeNormal(ideal I, list #)
+{
+  ASSUME(0, not isQuotientRing(basering) );
+
+  def r = basering;
+
+  //--------------------------- define the method ---------------------------
+  int isPrim, useRing;
+  int decomp = -1;
+  int norM, norC, norP, primCl;
+  int checkP, check111, checkPC;
+  int i;
+  ideal U1, U2, W;
+  poly c1, c2;
+  int ch;
+  string check;
+  string method;                //make all options one string in order to use
+                                //all combinations of options simultaneously
+  for ( i=1; i <= size(#); i++ )
+  {
+    if ( typeof(#[i]) == "string" )
+    {
+      method = method + #[i];
+    }
+  }
+  if ( find(method, "normal"))
+  {norM = 1;}
+  if ( find(method, "normalP") and (char(basering) > 0))
+  {norP = 1;}
+  if ( find(method, "normalC"))
+  {norC = 1;}
+  if ( find(method, "primCl"))
+  {primCl = 1;}
+  if ( find(method, "isprim") or find(method,"isPrim") )
+  {decomp = 0;}
+  if ( find(method, "p") )
+  {checkP = 1;}
+  if ( find(method, "pc") )
+  {checkPC = 1;}
+  if ( find(method, "111") )
+  {check111 = 1;}
+
+  int tt;
+  if(norM)
+  {
+    tt = timer;
+    if(decomp == 0)
+    {
+      "Running normal(useRing, isPrim)...";
+      list a1 = normal(I, "useRing", "isPrim");
+      "Time normal(useRing, isPrim): ", timer - tt;
+    }
+    else
+    {
+      "Running normal(useRing)...";
+      list a1 = normal(I, "useRing");
+      "Time normal(useRing): ", timer - tt;
+    }
+    "";
+  }
+  if(norP)
+  {
+    tt = timer;
+    if(decomp == 0)
+    {
+      "Running normalP(isPrim)...";
+      list a2 = normalP(I, "isPrim");
+      "Time normalP(isPrim): ", timer - tt;
+    }
+    else
+    {
+      "Running normalP()...";
+      list a2 = normalP(I);
+      "Time normalP(): ", timer - tt;
+    }
+    "";
+  }
+
+  if(norC)
+  {
+    tt = timer;
+    if(decomp == 0)
+    {
+      "Running normalC(isPrim)...";
+      list a3 = normalC(I, "isPrim");
+      "Time normalC(isPrim): ", timer - tt;
+    }
+    else
+    {
+      "Running normalC()...";
+      list a3 = normalC(I);
+      "Time normalC(): ", timer - tt;
+    }
+    "";
+  }
+
+  if(primCl)
+  {
+    tt = timer;
+    if(decomp == 0)
+    {
+      "Running normalC(withGens, isPrim)...";
+      list a4 = normalC(I, "isPrim", "withGens");
+      "Time normalC(withGens, isPrim): ", timer - tt;
+    }
+    else
+    {
+      "Running normalC(withGens)...";
+      list a4 = normalC(I, "withGens");
+      "Time normalC(withGens): ", timer - tt;
+    }
+    "";
+  }
+
+  if(check111 and norM)
+  {
+    "Checking output with norTest...";
+    "WARNING: this checking only works if the original ideal was prime.";
+    norTest(I, a1);
+    "";
+  }
+
+  if(checkP and norP and norM)
+  {
+    "Comparing with normalP output...";
+    if(size(a2) > 0)
+    {
+      "WARNING: this checking only works if the original ideal was prime.";
+      U1 = a1[2][1];
+      c1 = U1[size(U1)];
+      U2 = a2[1][1];
+      c2 = a2[1][1][size(a2[1][1])];
+      W = changeDenominator(U1, c1, c2, groebner(I));
+      qring q = groebner(I);
+      ideal U2 = fetch(r, U2);
+      ideal W = fetch(r, W);
+      ch = 0;
+      if(size(reduce(U2, groebner(W))) == 0)
+      {
+        "U2 c U1";
+        ch = 1;
+      }
+      if(size(reduce(W, groebner(U2))) == 0)
+      {
+        "U1 c U2";
+        ch = ch + 1;
+      }
+      if(ch == 2)
+      {
+        "Output of normalP is equal.";
+      }
+      else
+      {
+        "ERROR: Output of normalP is different.";
+      }
+      setring r;
+      kill q;
+    }
+    else
+    {
+      "normalP returned no output. Comparison is not possible.";
+    }
+    "";
+  }
+
+  if(checkPC and norM and primCl)
+  {
+    "Comparing with primeClosure output...";
+    if(size(a4) > 0)
+    {
+      "WARNING: this checking only works if the original ideal was prime.";
+      // primeClosure check
+      U1 = a1[2][1];
+      c1 = U1[size(U1)];
+      U2 = a4[2][1];
+      c2 = a4[2][1][size(a4[2][1])];
+      W = changeDenominator(U1, c1, c2, groebner(I));
+      qring q = groebner(I);
+      ideal U2 = fetch(r, U2);
+      ideal W = fetch(r, W);
+      ch = 0;
+      if(size(reduce(U2, groebner(W))) == 0)
+      {
+        "U2 c U1";
+        ch = 1;
+      }
+      if(size(reduce(W, groebner(U2))) == 0)
+      {
+        "U1 c U2";
+        ch = ch + 1;
+      }
+      if(ch == 2)
+      {
+        "Output of normalC(withGens) is equal.";
+      }
+      else
+      {
+        "ERROR: Output of normalC(withGens) is different.";
+      }
+      setring r;
+      kill q;
+    }
+    else
+    {
+      "normalC(withGens) returned no output. Comparison is not possible.";
+    }
+    "";
+  }
+}
+
+///////////////////////////////////////////////////////////////////////////
+static proc sqroot(int n);
+{
+  int s = 1;
+  while(s*s < n) { s++; }
+  return(s);
+}
+
+///////////////////////////////////////////////////////////////////////////
+proc norTest (ideal i, list nor, list #)
+"USAGE:   norTest(i,nor,[n]); i=prime ideal, nor=list, n=optional integer
+ASSUME:  nor is the output of normal(i) (any options) or
+         normalP(i,"withRing") or normalC(i) (any options).
+         In particular, the ring nor[1][1] contains the ideal norid
+         and the map normap: basering/i --> nor[1][1]/norid.
+RETURN:  an intvec v such that:
+ at format
+         v[1] = 1 if the normap is injective and 0 otherwise
+         v[2] = 1 if the normap is finite and 0 otherwise
+         v[3] = 1 if nor[1][1]/norid is normal and 0 otherwise
+ at end format
+         If n=1 (resp n=2) only v[1] (resp. v[2]) is computed and returned
+THEORY:  The procedure can be used to test whether the computation of the
+         normalization was correct: basering/i --> nor[1][1]/norid is the
+         normalization of basering/i if and only if v=1,1,0.
+NOTE:    For big examples it can be hard to fully test correctness; the
+         partial test norTest(i,nor,2) is usually fast
+EXAMPLE: example norTest; shows an example
+"
+{
+   ASSUME(0, not isQuotientRing(basering) );
+//### Sollte erweitert werden auf den reduziblen Fall: einen neuen affinen
+// Ring nor[1][1]+...+nor[1][r] (direkte Summe) erzeugen, map dorthin
+// definieren und dann testen.
+
+    int prl = printlevel - voice + 2;
+    int a,b,d;
+    int n,ii;
+    if (size(#) > 0) {  n = #[1];  }
+
+    def BAS = basering;
+
+    //### make a copy of nor to have a cpoy of nor[1][1]  (not a reference to)
+    // in order not to override norid and normap.
+    // delete nor[2] (if it contains the module generators, which are not used)
+    // s.t. newnor does not belong to a ring.
+
+    list newnor = nor;
+    if ( size(newnor) == 3 )
+    {
+       newnor = delete(newnor,2);
+    }
+    def R = newnor[1][1];
+    qring QAS = std(i);
+
+
+    setring R;
+    int nva = nvars(R);
+    string svars = varstr(R);
+    string svar;
+
+    norid = interred(norid);
+
+    //--------- create new ring with one dp block keeping weights ------------
+    list LR = ringlist(R);
+    list g3 = LR[3];
+    int n3 = size(g3);
+    list newg3;
+    intvec V;
+
+    //--------- check first whether variables Z(i),...,A(i) exist -----------
+    for (ii=90; ii>=65; ii--)
+    {
+       if ( find(svars,ASCII(ii)+"(") == 0 )
+       {
+          svar = ASCII(ii);  break;
+       }
+    }
+    if ( size(svar) != 0 )
+    {
+        for ( ii = 1; ii <= nva; ii++ )
+        {
+            LR[2][ii] = svar+"("+string(ii)+")";
+            V[ii] = 1;
+        }
+    }
+    else
+    {
+        for ( ii = 1; ii <= nva; ii++ )
+        {
+           LR[2][ii] = "Z("+string(100*nva+ii)+")";
+           V[ii] = 1;
+        }
+    }
+
+    if ( g3[n3][1]== "c" or g3[n3][1] == "C" )
+    {
+       list gm = g3[n3];       //last blockis module ordering
+       newg3[1] = list("dp",V);
+       newg3 = insert(newg3,gm,size(newg3));
+    }
+    else
+    {
+       list gm = g3[1];              //first block is module ordering
+       newg3[1] = list("dp",V);
+       newg3 = insert(newg3,gm);
+    }
+    LR[3] = newg3;
+//LR;"";
+    def newR = ring(LR);
+
+    setring newR;
+    ideal norid = fetch(R,norid);
+    ideal normap = fetch(R,normap);
+    if( defined(lnorid) )  { kill lnorid; }     //um ** redefinig zu beheben
+    if( defined(snorid) )  { kill snorid; }     //sollte nicht noetig sein
+
+    //----------- go to quotient ring for checking injectivity -------------
+//"mstd";
+    list lnorid = mstd(norid);
+    ideal snorid = lnorid[1];
+//"size mstdnorid:", size(snorid),size(lnorid[2]);
+//"size string mstdnorid:", size(string(snorid)),size(string(lnorid[2]));
+    qring QR = snorid;
+    ideal qnormap = fetch(newR,normap);
+    //ideal qnormap = imap(newR,normap);
+    //ideal qnormap = imap(R,normap);
+    map Qnormap = QAS,qnormap;    //r/id --> R/norid
+
+    //------------------------ check injectivity ---------------------------
+//"injective:";
+    a = is_injective(Qnormap,QAS);          //a. Test for injectivity of Qnormap
+    dbprint ( prl, "injective: "+string(a) );
+    if ( n==1 )
+    {
+     intvec result = intvec(a);
+     setring BAS;
+     return (result);
+   }
+   a;
+
+    //------------------------ check finiteness ---------------------------
+    setring newR;
+    b = mapIsFinite(normap,BAS,lnorid[2]);  //b. Test for finiteness of normap
+    dbprint ( prl, "finite: "+string(b) );
+    if ( n==2 )
+    {
+       intvec result = intvec(a,b);
+       setring BAS;
+       return (result);
+    }
+   b;
+
+    //------------------------ check normality ---------------------------
+    list testnor = normal(lnorid[2],"isPrim","noFac", "withDelta");
+    //### Problem: bei mehrfachem Aufruf von norTest gibt es
+    // ** redefining norid & ** redefining normap
+    //Dies produziert Fehler, da alte norid und normap ueberschrieben werden
+    //norid und normap werden innnerhalb von proc computeRing ueberschrieben
+    //Die Kopie newR scheint das Problem zu loesen
+
+
+    d = testnor[3][2];             //d = delta
+    kill testnor;                              //### sollte ueberfluessig sein
+    int d1 = (d==0);                           //d1=1 if delta=0
+    dbprint ( prl, "delta: "+string(d) );
+    intvec result = intvec(a,b,d1);
+    setring BAS;
+    return(result);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   int prl = printlevel;
+   printlevel = -1;
+   ring r = 0,(x,y),dp;
+   ideal i = (x-y^2)^2 - y*x^3;
+   list nor = normal(i);
+   norTest(i,nor);                //1,1,1 means that normal was correct
+
+   nor = normalC(i);
+   norTest(i,nor);                //1,1,1 means that normal was correct
+
+   ring s = 2,(x,y),dp;
+   ideal i = (x-y^2)^2 - y*x^3;
+   nor = normalP(i,"withRing");
+   norTest(i,nor);               //1,1,1 means that normalP was correct
+   printlevel = prl;
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+//                            EXAMPLES
+//
+///////////////////////////////////////////////////////////////////////////
+/*
+//commands for computing the normalization:
+// options for normal:  "equidim", "prim"
+//                      "noDeco", "isPrim", "noFac"
+//                       (prim by default)
+// options for normalP: "withRing", "isPrim" or "noFac"
+// options for normalC: "equidim", "prim", "withGens",
+//                      "noDeco", "isPrim", "noFac"
+
+//Commands for testing 'normal'
+ list nor = normal(i); nor;
+ list nor = normal(i,"isPrim");nor;
+ list nor = normal(i,"equidim");nor;
+ list nor = normal(i,"prim");nor;
+ list nor = normal(i,"equidim","noFac");nor;
+ list nor = normal(i,"prim","noFac");nor;
+
+//Commands for testing 'normalP' in positive char
+ list nor = normalP(i);nor;              //withGens but no ringstructure
+ list nor = normalP(i,"withRing"); nor;  //compute the ringstructure
+ list nor = normalP(i,"isPrim"); nor;    //if i is known to be prime
+
+//Commands for testing 'normalC'
+ list nor = normal(i); nor;
+ list nor = normal(i,"withGens");nor;
+ list nor = normal(i,"isPrim");nor;
+ list nor = normal(i,"equidim");nor;
+ list nor = normal(i,"prim");nor;
+ list nor = normal(i,"equidim","noFac");nor;
+ list nor = normal(i,"prim","noFac");nor;
+
+//Commands for testing correctness (i must be prime):
+list nor = normalP(i,"withRing","isPrim");
+list nor = normal(i,"isPrim");
+norTest(i,nor);       //full test for not too big examples (1,1,1 => ok)
+norTest(i,nor,2);     //partial test for big examples (1,1 => ok)
+factorize(i[1]);      //checks for irreducibility
+
+/////////////////////////////////////////////////////////////////////////////
+
+//----------------------Examples for normal (new algorithm)------------------
+// Timings with Computeserver Dual AMD Opteron 242 1.60GHz.
+// Examples from "Normalization of Rings" paper.
+
+// Example 1
+// char 0 : normal = 0 secs (7 steps) - normalC = 75 secs
+// char 2 : normal = 0 secs (7 steps) - normalP = 0 secs - normalC = 0 secs
+// char 5 : normal = 1 secs (7 steps) - normalP = 71 - normalC = 1 secs
+// char 11 : normal = 2 secs (7 steps) - normalP = 12 secs - normalC doesn't finish
+// char 32003 : normal = 1 secs (7 steps) - normalP doesn't finish - normalC = 1 sec
+LIB"normal.lib";
+ring r = 2, (x, y), dp;
+ideal i = (x-y)*x*(y+x^2)^3-y^3*(x^3+x*y-y^2);
+timeNormal(i, "normal", "normalC", "normalP", "isPrim", "p");
+
+// Example 2
+// char 0  : normal = 1 sec (7 steps) - normalC doesn't finish
+// char 3 : normal = 1 secs (8 steps) - normalP = 0 secs - normalC = 4 secs
+// char 13 : normal = 1 sec (7 steps) - normalP doesn't finish - normalC = 13 secs
+// char 32003 : normal = 1 secs (7 steps) - normalP doesn't finish - normalC = 10 sec
+//Example is reducible in char 5 and 7
+LIB"normal.lib";
+ring r = 3, (x, y), dp;
+ideal i = 55*x^8+66*y^2*x^9+837*x^2*y^6-75*y^4*x^2-70*y^6-97*y^7*x^2;
+timeNormal(i, "normal", "normalC", "normalP", "p", "isPrim");
+
+// Example 3
+// char 0 : normal = 3 secs (6 steps) - normalC doesn't finish
+// char 2 : normal = 1 secs (13 steps) - normalP = 0 secs - normalC doesn't finish
+// char 5 : normal = 0 secs (6 steps) - normalP = 8 secs - normalC doesn't finish
+LIB"normal.lib";
+ring r=5,(x, y),dp;
+ideal i=y9+y8x+y8+y5+y4x+y3x2+y2x3+yx8+x9;
+timeNormal(i, "normal", "normalC", "normalP", "isPrim");
+
+// Example 4
+// char 0 : normal = 0 secs (1 step) - normalC = 0 secs
+// char 5 : normal = 0 secs (1 step) - normalP = 3 secs - normalC = 0 secs
+// char 11 : normal = 0 secs (1 step) - normalP doesn't finish - normalC = 0 secs
+// char 32003 : normal = 0 secs (1 step) - normalP doesn't finish - normalC = 0 secs
+LIB"normal.lib";
+ring r=5,(x,y),dp;   // genus 0 4 nodes and 6 cusps im P2
+ideal i=(x2+y^2-1)^3 +27x2y2;
+timeNormal(i, "normal", "normalC", "normalP", "isPrim");
+
+// Example 5
+// char 0 : normal = 0 secs (1 step) - normalC = 0 secs
+// char 5 : normal = 1 secs (3 step) - normalP doesn't finish - normalC doesn't finish
+// char 11 : normal = 0 secs (1 step) - normalP 0 secs - normalC = 0 secs
+// char 32003 : normal = 0 secs (1 step) - normalP doesn't finish - normalC = 0 secs
+LIB"normal.lib";
+ring r=11,(x,y),dp;    //24 sing, delta 24
+ideal i=-x10+x8y2-x6y4-x2y8+2y10-x8+2x6y2+x4y4-x2y6-y8+2x6-x4y2+x2y4+2x4+2x2y2-y4-x2+y2-1;
+timeNormal(i, "normal", "normalC", "normalP", "isPrim", "p");
+
+// Example 6
+// char 2 : normal = 5 secs (2 steps) - normalP = 25 secs - normalC = 166 secs
+LIB"normal.lib";
+ring r=2,(v,u,z,y,x),dp;
+ideal i = z3+zyx+y3x2+y2x3, uyx+z2,uz+z+y2x+yx2, u2+u+zy+zx, v3+vux+vz2+vzyx+vzx+uz3+uz2y+z3+z2yx2;
+timeNormal(i, "normal", "normalC", "normalP", "isPrim", "p");
+
+// Example 7
+// char 0 : normal = 11 secs (6 steps) - normalC = 11 secs
+// char 2 : normal = 11 secs (6 steps) - normalP = 0 secs - normalC = 11 secs
+// char 5 : normal = 11 secs (6 steps) - normalP = 3 secs - normalC = 11 secs
+// char 11 : normal = 11 secs (6 steps) - normalP = 43 secs - normalC = 11 secs
+// char 32003 : normal = 11 secs (6 steps) - normalP doesn't finish - normalC = 11 secs
+LIB"normal.lib";
+ring r=11,(x,y,z,w,t),dp;   //dim 2, dim s_locus 1
+ideal i= x2+zw, y3+xwt, xw3+z3t+ywt2, y2w4-xy2z2t-w3t3;
+timeNormal(i, "normal", "normalC", "normalP", "isPrim");
+
+////////////////////////////////////////////////////////////////////////////////
+
+// Other examples with new algorithm
+
+// Example 1
+// char 0 : normal = 1 secs (13 steps) - normalC doesn't finish
+// char 2 : normal = 1 secs (13 steps) - normalP = 0 secs - normalC doesn't finish
+// char 5 : normal = 1 secs (13 steps) - normalP = 29 secs - normalC doesn't finish
+ring r=2,(x,y),dp;  //genus 35
+ideal i=y30+y13x+x4y5+x3*(x+1)^2;
+timeNormal(i, "normal", "normalC", "normalP");
+
+// Example 2
+// char 0 : normal = 1 secs (13 steps) - normalC doesn't finish
+// char 3 : normal = 2 secs (13 steps) - normalP = 0 secs - normalC doesn't finish
+ring r=3,(x,y),dp;  //genus 19, delta 21
+ideal i=y20+y13x+x4y5+x3*(x+1)^2;
+timeNormal(i, "normal", "normalC", "normalP");
+
+// Example 3
+// Very fast with all algorithms
+ring r = 3, (x, y), dp;
+ideal I = (x-y^2)^2-x*y^3;
+timeNormal(I, "normal", "normalC", "normalP", "primCl", "111", "p", "pc");
+
+
+
+//----------------------Test Example for charp -------------------
+//Zu tun:
+//### nach minor nur std statt mstd verwenden
+//***hat bei keinem Beisp etwas gebracht -> wieder zurueck
+//### wenn interred ok, dann wieder einsetzen (am Schluss)
+//### bottelnecks bei maps beheben
+//### minor verbessern
+//### preimage verbessern (Ist imm Kern map oder imap verwendet?)
+//### Gleich in Ordnung dp wechseln, ringlist verwenden
+//### interred ev nur zum Schluss
+//    (z.B. wenn nacher std; wenn nacher minor: testen )
+
+//Zeiten mit normalV5.lib (mstd aktiv, interred inaktiv)
+
+//SWANSON EXAMPLES: (Macaulay2, icFracP=normalP, icFractions<->normal)
+//---------------------------------------------------------------------
+//1. Series Fp[x,y,u,v]/(x2v-y2u)
+//-------------------------------
+//characteristic p   2   3    5    7    11   13   17   37   97
+//icFracP          0.04 0.03 0.04 0.04 0.04 0.05 0.05 0.13 0.59  Mac
+//normalP           0   0    0    0     0    0    0    0   1    Sing
+//icFractions      0.08 0.09 0.09 0.09 0.14 0.15 0.15 0.15 0.15  Mac
+//normal             0   0    0    0     0    0    0    0    0   Sing
+
+2. Series Fp[u, v, w, x, y, z]/u2x4+uvy4+v2z4
+//--------------------------------------------
+//characteristic p 2    3    5    7   11
+//icFracP         0.07 0.22 9.67 143 12543
+//normalP          0    0    5   42  1566
+//icFractions     1.16   *    *   *    *       *: > 6h
+//normal            0    0    0   0    0
+
+//3. Series Fp[u, v, w, x, y, z]/(u2xp+uvyp+v2zp)
+//-----------------------------------------------
+//characteristic p  2    3    5    7    11   13  17 19 23
+//icFracP          0.06 0.07 0.09 0.27 1.81 4.89 26 56 225
+//normalP          0     0    0    0    1    2  6  10  27
+//icFractions      0.16 1.49 75.00 4009 *    *   *  *  *
+//normal            0     0    2   836
+//normal(neu)       0     0    1   2    10  155
+//### p=7 normal braucht 807 sec in:
+// ideal endid  = phi1(endid);      //### bottelneck'
+
+//1.
+int p = 2;  ring r = p,(u,v,x,y,z),dp; ideal i = x2v-y2u;
+//2.
+int p = 7; ring r=p,(u,v,w,x,y,z),dp; ideal i=u2x4+uvy4+v2z4;
+//3.
+int p=11; ring r=p,(u,v,w,x,y,z),dp; ideal i=u2*x^p+uv*y^p+v2*z^p;
+
+//IRREDUCIBLE EXAMPLES:
+//---------------------
+//timing for MacBookPro 2.2GHz Intel Core 2 Duo, 4GB Ram
+//Sing. ix86Mac-darwin version 3-1-0 (3100-2008101314)  Oct 13 2008 14:46:59
+//if no time is given: < 1  sec
+
+//Apply:
+list nor = normal(i,"isPrim"); nor;
+list nor = normalP(i,"withRing","isPrim"); nor;
+def R=nor[1][1]; setring R; norid; normap;
+setring r;
+norTest(i,nor);
+
+int tt = timer;
+list nor = normalP(i,"withRing","isPrim"); nor;
+timer-tt;
+int tt = timer;
+list nor = normal(i,"isPrim");
+timer-tt;
+
+ring r=19,(x,y,u,v),dp;    //delta -1
+ideal i=x2v-y2u;
+//norTest 2 sec
+
+ring r=2,(y,x2,x1),lp;     //delta -1
+ideal i=y^4+y^2*x2*x1+x2^3*x1^2+x2^2*x1^3;
+//### norid hat 1 Element nach interred
+
+ring r  = 11,(x,y,z),wp(2,1,2); //alles < 1 sec
+ideal i=z3 - xy4 + x2;          //not reduced, delta =0 ok
+ideal i=y4+x5+y2x;              //not reduced, delta -1
+//interred verkleinert norid
+
+ring r=3,(u,v,x,y,z),dp;   //delta -1
+ideal i=u2x3+uvy3+v2z3;
+
+ring r=3,(u,v,x,y,z),dp;   //delta -1
+ideal i=u2x4+uvy4+v2z4;
+//norTest(i,nor);  0 sec, norTest(i,nor) haengt!
+
+ring r=5,(u,v,x,y,z),dp;   //delta -1
+ideal i=u2x6+uvy6+v2z6;
+//normalP 5sec, normalC 1sec
+//V5: norTest(i,nor); 45 sec bei normalP, V6 12 sec
+//28 sec bei normal
+
+ring r=5,(u,v,x,y,z),dp;   //delta -1
+ideal i=u2x5+uvy5+v2z5;
+//normalP 1sec, normalC 1 sec,
+//norTest lange: minor(jacob(I),h,J) 193 (308)sec, haengt dann bei M = std(M);
+//norTest(i,nor,2); verwenden!
+//Sing 3.0-4 orig  >9h! haengt bei Q = mstd(Q)[2];
+
+ring r=2,(y,x),wp(12,5);  //delta 3
+ideal i=y5+y2x4+y2x+yx2+x12;
+//normalP 0 sec (Test 0 sec), normalC 2 sec (Test 2 sec)
+//normalC withGens (ohne interred) 0sec
+
+ring r=2,(y,x),dp;       //delta= 22
+ideal i=y9+y8x+y8+y5+y4x+y3x2+y2x3+yx8+x9;
+//normalP 1sec, interred verkleinert norid betraechtlich
+//normalC haengt bei minor, ideal im loop wird zu gross ###
+//interred bei normalC vergroeesert string um Faktor 4000!
+//withGens haengt bei interred in loop 4 (> 10 h) oder
+//(nach Ausschalten von interred) bei
+//int delt=vdim(std(modulo(f,ideal(p)))); (>?h)
+
+//Leonard1: (1. Komponente von Leonard),  delta -1
+ring r=2,(v,u,z,y,x),dp;
+ideal i = z3+zyx+y3x2+y2x3, uyx+z2,uz+z+y2x+yx2, u2+u+zy+zx,
+          v3+vux+vz2+vzyx+vzx+uz3+uz2y+z3+z2yx2;
+//normalP 5 sec (withRing 9 sec), norTest(i,nor,2); 45 sec
+//normalC 102sec, 99sec
+//### Zeit wird bei ideal Ann = quotient(SM[2],SL[1]); und bei
+// f  = quotient(p*J,J); verbraucht
+//withGens (ohne interred) 131sec, norTest(i,nor,2); 2min25sec
+//norTest(i,nor,2);  45 sec
+
+ ring r=2,(y,x),wp(25,21); //Leonard2, delta 232
+ ring r=2,(y,x),dp;
+ ideal i=
+ y^21+y^20*x +y^18*(x^3+x+1) +y^17*(x^3+1) +y^16*(x^4+x)
+ +y^15*(x^7+x^6+x^3+x+1) +y^14*x^7 +y^13*(x^8+x^7+x^6+x^4+x^3+1)
+ +y^12*(x^9+x^8+x^4+1) +y^11*(x^11+x^9+x^8+x^5+x^4+x^3+x^2)
+ +y^10*(x^12+x^9+x^8+x^7+x^5+x^3+x+1)
+ +y^9*(x^14+x^13+x^10+x^9+x^8+x^7+x^6+x^3+x^2+1)
+ +y^8*(x^13+x^9+x^8+x^6+x^4+x^3+x) +y^7*(x^16+x^15+x^13+x^12+x^11+x^7+x^3+x)
+ +y^6*(x^17+x^16+x^13+x^9+x^8+x) +y^5*(x^17+x^16+x^12+x^7+x^5+x^2+x+1)
+ +y^4*(x^19+x^16+x^15+x^12+x^6+x^5+x^3+1)
+ +y^3*(x^18+x^15+x^12+x^10+x^9+x^7+x^4+x)
+ +y^2*(x^22+x^21+x^20+x^18+x^13+x^12+x^9+x^8+x^7+x^5+x^4+x^3)
+ +y*(x^23+x^22+x^20+x^17+x^15+x^14+x^12+x^9)
+ +(x^25+x^23+x^19+x^17+x^15+x^13+x^11+x^5);
+//normalP: dp 2sec withRing 8sec,
+//wp 4sec, withRing:51sec Zeit in lin = subst(lin, var(ii), vip); in elimpart ),
+//norTest(i,nor,2): haengt bei mstd(norid);
+//### normalC: (m. interred): haengt bei endid = interred(endid);
+//GEFIXTES INTERRED ABWARTEN. Dann interred aktivieren
+//interred(norid) haengt u. mst(norid) zu lange
+//(o.interred): haengt bei  haengt bei list SM = mstd(i);
+//ideal in der Mitte zu gross
+//i = Ideal (size 118, 13 var) fuer die neue Normalisierung
+//normal(neu) haengt bei return(std(i)) (offensichtlich in eineranderen lib)
+
+REDUCIBLE EXAMPLES:
+------------------
+//Apply:
+int tt = timer;
+list nor=normalP(i,"isPrim","withRing");
+timer-tt;
+
+list nor = normal(i); nor;
+list nor = normalC(i); nor;
+list nor = normalC(i, "withGens"); nor;
+list nor = normalP(i,"withRing"); nor;
+list nor = normalP(i); nor;
+def R=nor[1][1]; setring R; norid; normap;
+
+//Leonhard 4 Komponenten, dim=2, delta: 0,0,0,-1
+ring r=2,(v,u,z,y,x),dp;      //lp zu lange
+ideal i=z3+zyx+y3x2+y2x3, uyx+z2, v3+vuyx+vux+vzyx+vzx+uy3x2+uy2x+zy3x+zy2x2;
+//normalP: 19 sec, withRing: 22 sec
+//normalC ohne (mit) interred: 112 (113)sec, equidim: 99sec
+//normalC 1. mal 111 sec, (2.mal) 450sec!! 3.mal 172 sec
+//(unterschiedlich lange primdec, mit Auswirkungen)
+//char 19: normalC: 15sec , withGens: 14sec (o.interr.)
+
+//----------------------Test Example for special cases -------------------
+int tt = timer;
+list nor=normalP(i,"withRing");nor;
+//list nor=normalP(i,"withRing", "isPrim");nor;
+timer-tt;
+def R1 = nor[1][1]; setring R1;  norid; normap; interred(norid);
+setring r;
+
+int tt = timer;
+list nor=normal(i,"isPrim");nor;
+timer-tt;
+
+ring r = 29,(x,y,z),dp;
+ideal i = x2y2,x2z2;       //Nicht equidimensional, equidim reduziert nicht, ok
+ideal i  = xyz*(z3-xy4);   //### interred(norid) verkuerzt
+//je 0 sec
+
+ideal j = x,y;
+ideal i = j*xy;
+equidim(i);
+//hat eingebettete Komponente, equidim rechnet wie in Beschreibung (ok)
+
+ring r  = 19,(x,y),dp;
+   ideal i = x3-y4;                   //delta = 3
+   ideal i = y*x*(x3-y4);             //delta = 11; 0,0,3
+   ideal i = (x2-y3)*(x3-y4);         //delta = 13; 1,3
+   ideal i = (x-y)*(x3+y2)*(x3-y4);   //delta = 23; 0,1,3
+   ideal i = (x-1)*(x3+y2)*(x2-y3);   //delta = 16; 0,1,1
+   ideal i = (x-y^2)^2 - y*x^3;       //delta = 3
+   //singularities at not only at 0, hier rechnet equidim falsch
+
+// -------------------------- General Examples  ---------------------------//Huneke, irred., delta=2 (Version 3-0-4: < 1sec)
+//Version 3-0-6 default: 1sec, mit gens 2sec, mit delta 5 sec
+//(prim,noFac):ca 7 Min, prim:ca 10 min(wg facstd)
+//
+// "equidim" < 1sec irred. 5sec
+// ring r=31991,(a,b,c,d,e),dp;
+ring r=2,(a,b,c,d,e),dp;                    //delta=2
+ideal i=
+5abcde-a5-b5-c5-d5-e5,
+ab3c+bc3d+a3be+cd3e+ade3,
+a2bc2+b2cd2+a2d2e+ab2e2+c2de2,
+abc5-b4c2d-2a2b2cde+ac3d2e-a4de2+bcd2e3+abe5,
+ab2c4-b5cd-a2b3de+2abc2d2e+ad4e2-a2bce3-cde5,
+a3b2cd-bc2d4+ab2c3e-b5de-d6e+3abcd2e2-a2be4-de6,
+a4b2c-abc2d3-ab5e-b3c2de-ad5e+2a2bcde2+cd2e4,
+b6c+bc6+a2b4e-3ab2c2de+c4d2e-a3cde2-abd3e2+bce5;
+//normalC: char 2, 31991: 0 sec (isPrim); char 2, equidim: 7 sec
+//norTest(i,nor,2); 1sec
+//normalP char 2: 1sec (isPrim)
+//size(norid); size(string(norid));21 1219 interred(norid): 21 1245 (0 sec)
+
+int tt = timer;
+list nor=normalC(i);nor;
+timer-tt;
+
+list nor = normalP(i,"isPrim");
+
+//Vasconcelos irred., delta -1 (dauert laenger)
+//auf macbook pro = 20 sec mit alter Version,
+//Sing 3-0-6:
+// Char 32003: "equidim" 30 sec, "noFac": 30sec
+//gens: nach 9 min abgebr (haengt in Lin = ideal(T*syzf);) !!!! Hans zu tun
+//Char 2: default (charp) 2 sec, normalC ca 30 sec
+//ring r=32003,(x,y,z,w,t),dp;   //dim 2, dim s_locus 1
+ring r=2,(x,y,z,w,t),dp;   //dim 2, dim s_locus 1
+ideal i= x2+zw, y3+xwt, xw3+z3t+ywt2, y2w4-xy2z2t-w3t3;
+//normalC: char 2: 22,  sec (mit und ohne isPrim)
+//normalP char 2: 0sec (isPrim)      o. interred
+//char 32003: ### haengt in ideal endid  = phi1(endid);
+
+//-------------------------------------------------------
+//kleine Beispiele:
+
+//Theo1, irred, delta=-1
+//normalC: 1sec, normalP: 3 sec
+ring r=32003,(x,y,z),wp(2,3,6); //dim 2,dim slocus 1
+ideal i=zy2-zx3-x6;
+//normalC: char 2,19,32003: 0  sec (isPrim)
+//normalP (isPrim) char 2,19: 0sec, char 29: 1sec
+
+//Theo1a, CohenMacaulay regular in codim 2, dim slocus=1, delta=0
+//normalC: 0 sec, normalP: haegt in K=preimage(R,phi,L);
+ring r=32003,(x,y,z,u),dp;
+ideal i=zy2-zx3-x6+u2;
+//normalC: char 2,32003: 0  sec (isPrim)
+//normalP (isPrim) char 2: 0sec, char 19: haengt in K = preimage(Q,phi,L);
+
+//Theo2, irreduzibel, reduziert, < 1sec, delta -1
+ring r=0,(x,y,z),wp(3,4,12);
+ideal i=z*(y3-x4)+x8;
+//normalC: char 2,32003,0: 0  sec (isPrim)
+//normalP (isPrim) char 2: 0 1sec, char 19: 1sec char 29: 7 sec
+
+//Theo2a, reduiziert, 2-dim, dim_slocus=1, alte Version 3 sec,
+//normalP ca 30 sec, normalC ca 4sec, delta -1
+//ring r=32003,(T(1..4)),wp(3,4,12,17);
+//ring r=11,(T(1..4)),dp;
+ring r=11,(T(1..4)),wp(3,4,12,17);
+ideal i=
+T(1)^8-T(1)^4*T(3)+T(2)^3*T(3),
+T(1)^4*T(2)^2-T(2)^2*T(3)+T(1)*T(4),
+T(1)^7+T(1)^3*T(2)^3-T(1)^3*T(3)+T(2)*T(4),
+T(1)^6*T(2)*T(3)+T(1)^2*T(2)^4*T(3)+T(1)^3*T(2)^2*T(4)-T(1)^2*T(2)*T(3)^2+T(4)^2;
+//normalC: char 2,32003: 0  sec (isPrim)
+//normalP (isPrim) char 2: 0sec, char 11 2se, char 19: 13sec
+//norTest 48sec in char11
+//### interred verkuerzt
+//char 29: haengt in K = preimage(Q,phi,L);
+
+//Theo3, irred, 2-dim, 1-dim sing, < 1sec
+ring r=11,(x,y,z),wp(3,5,15);
+ideal i=z*(y3-x5)+x10;
+//normalC: char 2,0: 0  sec (withRing)
+//normalP (withRing) char 2,11: 0sec, char 19: 13sec norTest 12sec(char 11)
+
+//Theo4 reducible, delta (0,0,0) -1
+ring r=29,(x,y,z),dp;
+ideal i=(x-y)*(x-z)*(y-z);
+//normalC: char 2,32003: 0  sec
+//normalP char withRing 2, 29: 0sec, 6sec
+
+//Theo6
+ring r=32003,(x,y,z),dp;
+ideal i=x2y2+x2z2+y2z2;
+//normalC: char 2,32003: 0  sec
+//normalP char withRing 2, 29: 0sec, 4sec
+
+//Sturmfels, CM, 15 componenten, alle glatt
+ring r=0,(b,s,t,u,v,w,x,y,z),dp;
+ideal i= bv+su, bw+tu, sw+tv, by+sx, bz+tx, sz+ty,uy+vx,uz+wx,vz+wy,bvz;
+//normalC car 11, 0: 1sec, normalP 0 sec
+
+//riemenschneider, , dim 3, 5 Komp. delta (0,0,0,0,0), -1
+ring r=2,(p,q,s,t,u,v,w,x,y,z),wp(1,1,1,1,1,1,2,1,1,1);
+ideal i=xz,vx,ux,su,qu,txy,stx,qtx,uv2z-uwz,uv3-uvw,puv2-puw;
+//alles 0 sec in char 2
+
+//4 Komponenten, alle glatt, 0sec
+ring r=11,(x,y,z,t),dp;
+ideal i=x2z+xzt,xyz,xy2-xyt,x2y+xyt;
+
+//dim 3, 2 Komponenten delta (-1,0), -1
+ring r=2,(u,v,w,x,y,z),wp(1,1,1,3,2,1);
+ideal i=wx,wy,wz,vx,vy,vz,ux,uy,uz,y3-x2;
+//alles 0 sec in char 2
+//---------------------------------------------------------
+int tt = timer;
+list nor=normalP(i,"normalC","withRing");nor;
+timer-tt;
+
+//St_S/Y, 3 Komponenten, 2 glatt, 1 normal
+//charp haengt (in char 20) in K=preimage(R,phi,L);
+//ring r=32003,(b,s,t,u,v,w,x,y,z),dp;
+ring r=11,(b,s,t,u,v,w,x,y,z),dp;
+ideal i=wy-vz,vx-uy,tv-sw,su-bv,tuy-bvz;
+//normalC: char 2,32003: 0  sec
+//normalP char withRing 2: 1sec, char 11: 40sec
+
+//Horrocks: cahr 0: 17 (8 in char 11) Komponenten alle normal, delta 1
+//char 11: 8 Komponenten alle normal, delta -1
+ring r=0,(a,b,c,d,e,f),dp;
+//ring r=11,(a,b,c,d,e,f),dp; //Charp bis p = 200 ca 3sec
+ideal i=
+adef-16000be2f+16001cef2, ad2f+8002bdef+8001cdf2, abdf-16000b2ef+16001bcf2,
+a2df+8002abef+8001acf2, ad2e-8000bde2-7999cdef, acde-16000bce2+16001c2ef,
+a2de-8000abe2-7999acef, acd2+8002bcde+8001c2df, abd2-8000b2de-7999bcdf,
+a2d2+9603abde-10800b2e2-9601acdf+800bcef+11601c2f2,
+abde-8000b2e2-acdf-16001bcef-8001c2f2, abcd-16000b2ce+16001bc2f,
+a2cd+8002abce+8001ac2f, a2bd-8000ab2e-7999abcf, ab3f-3bdf3,
+a2b2f-2adf3-16000bef3+16001cf4, a3bf+4aef3, ac3e-10668cde3,
+a2c2e+10667ade3+16001be4+5334ce3f, a3ce+10669ae3f, bc3d+8001cd3e,
+ac3d+8000bc3e+16001cd2e2+8001c4f, b2c2d+16001ad4+4000bd3e+12001cd3f,
+b2c2e-10668bc3f-10667cd2ef, abc2e-cde2f, b3cd-8000bd3f, b3ce-10668b2c2f-10667bd2ef, abc2f-cdef2, a2bce-16000be3f+16001ce2f2,
+ab3d-8000b4e-8001b3cf+16000bd2f2, ab2cf-bdef2,
+a2bcf-16000be2f2+16001cef3, a4d-8000a3be+8001a3cf-2ae2f2;
+//normalC: char 0: 1sec char 11: 0sec
+//normalP: char 11: 0sec
+
+//2sec mit normalC, in char 2 ebenfalls (char 20 mit charp >1 min)
+//4 Komp. in char 2, delta (0,0,0,0) -1, char 11:delta (-1,0,0,0) -1
+ring r=32003,(b,s,t,u,v,w,x,y,z),dp;
+ideal i=
+wx2y3-vx2y2z+wx2yz2+wy3z2-vx2z3-vy2z3,
+vx3y2-ux2y3+vx3z2-ux2yz2+vxy2z2-uy3z2,
+tvx2y2-swx2y2+tvx2z2-swx2z2+tvy2z2-swy2z2,
+sux2y2-bvx2y2+sux2z2-bvx2z2+suy2z2-bvy2z2,
+tux2y3-bvx2y2z+tux2yz2+tuy3z2-bvx2z3-bvy2z3;
+//normalC: char 2,32003: 1 sec
+//normalP char withRing 2: 1sec, char 11: 40sec
+
+//---------------------------------------------------------
+//genus:
+int tt = timer;
+list nor=normal(i, "noFac");nor;
+timer-tt;
+
+//Yoshihiko Sakai, irred, 0sec, delta = 8
+ring r=0,(x,y),dp;                    //genus 0 4 nodes and 6 cusps im P2
+//ring r=7,(x,y),dp;                  //charp haengt in K = preimage(Q,phi,L)
+ideal i=(x2+y^2-1)^3 +27x2y2;
+
+ring r=0,(x,y),dp;   //genus 0
+ideal i=(x-y^2)^2 - y*x^3;
+
+ring r=0,(x,y),dp;  //genus 4
+ideal i=y3-x6+1;
+
+int m=9;           // q=9: genus 0
+int p=2;
+int q=9;//2,...,9
+ring r=0,(x,y),dp;
+ideal i=y^m - x^p*(x - 1)^q;
+
+ring r=0,(x,y),dp;  //genus 19
+ideal i=55*x^8+66*y^2*x^9+837*x^2*y^6-75*y^4*x^2-70*y^6-97*y^7*x^2;
+
+ring r=23,(x,y),dp;  //genus 34, delta 2
+ideal i=y10+(-2494x2+474)*y8+(84366+2042158x4-660492)*y6
+        +(128361096x4-47970216x2+6697080-761328152x6)*y4
+        +(-12024807786x4-506101284x2+15052058268x6+202172841-3212x8)*y2
+        +34263110700x4-228715574724x6+5431439286x2+201803238
+        -9127158539954x10-3212722859346x8;
+//normalC, normalP 0 sec
+
+//Rob Koelman
+//ring r=0,(x,y,z),dp;      //dim sing = 1 (nach ca 15 min abgebrochen)
+ring r=32003,(x,y,z),dp;
+ideal i=
+761328152*x^6*z^4-5431439286*x^2*y^8+2494*x^2*z^8+228715574724*x^6*y^4+
+ 9127158539954*x^10-15052058268*x^6*y^2*z^2+3212722859346*x^8*y^2-
+ 134266087241*x^8*z^2-202172841*y^8*z^2-34263110700*x^4*y^6-6697080*y^6*z^4-
+ 2042158*x^4*z^6-201803238*y^10+12024807786*x^4*y^4*z^2-128361096*x^4*y^2*z^4+
+ 506101284*x^2*z^2*y^6+47970216*x^2*z^4*y^4+660492*x^2*z^6*y^2-
+ z^10-474*z^8*y^2-84366*z^6*y^4;
+//normalC char 32003: 10 sec, char 0 :
+
+//ring r=0,(x,y),dp;//genus 10  with 26 cusps (nach ca 4 min abgebrochen)
+ring r=32003,(x,y),dp;    //24 sing, delta 24
+ideal i=9127158539954x10+3212722859346x8y2+228715574724x6y4-34263110700x4y6
+-5431439286x2y8-201803238y10-134266087241x8-15052058268x6y2+12024807786x4y4
++506101284x2y6-202172841y8+761328152x6-128361096x4y2+47970216x2y4-6697080y6
+-2042158x4+660492x2y2-84366y4+2494x2-474y2-1;
+//normalC 32003: 4 sec, char 0: abgebrochen bei pr = facstd(i); ###
+
+ring r=0,(x,y),dp;   //irred, genus 1  with 5 cusps, delta 5
+ideal i=57y5+516x4y-320x4+66y4-340x2y3+73y3+128x2-84x2y2-96x2y;
+//normalC 0 sec
+
+ring r=2,(x,y),dp;  //genus 4, 2 Zweige, delta (13,9) 89
+ideal i=((x2+y3)^2+xy6)*((x3+y2)^2+x10y);
+//normalC: char 2 : 1sec, char 0: lange
+//normalP char 2 withRing: 0sec
+
+ring r=2,(y,z,w,u),dp; //2 Komp. genus -5
+ideal i=y2+z2+w2+u2,w4-u4;
+//normalC: char 2 : 0sec, char 0: 1sec
+//normalP char 2 withRing: 0sec
+
+ring r=0,(y,z,w,u),dp; //irred. genus 9
+ideal i=y2+z2+w2+u2,z4+w4+u4;
+//char 0: 0sec
+
+ring r=0,(x,y,t),dp;  //irred, delta -1
+ideal i= 25x8+200x7y+720x6y2+1520x5y3+2064x4y4+1856x3y5+1088x2y6+384xy7+64y8-12x6t2-72x5yt2-184x4y2t2-256x3y3t2-192x2y4t2-64xy5t2-2x4t4-8x3yt4+16xy3t4+16y4t4+4x2t6+8xyt6+8y2t6+t8;
+//char 0: 0sec
+
+ring r=0,(x,y,z,w,u),dp;
+ideal i=x2+y2+z2+w2+u2,x3+y3+z3,z4+w4+u4;
+//char 0: 0sec
+
+//---------------------------------------------------------
+//Probleme mit normalC in char 2 und char 0
+
+int tt = timer;
+list nor=normalC(i,"withRing");nor;
+timer-tt;
+
+//Mark van Hoeij
+ring r=3,(x,y),dp;  //genus 19, delta 21
+ideal i=y20+y13x+x4y5+x3*(x+1)^2;
+//normalC: char 2 > 10 min   bei list SM = mstd(i);###
+//normalP char 2 withRing: 0sec, char 11: haengt bei K = preimage(Q,phi,L);
+
+ring r=2,(x,y),dp;  //genus 35
+ideal i=y30+y13x+x4y5+x3*(x+1)^2;
+//char 0 abgebrochen bei list SM = mstd(i); ###
+//char 2 nach ca 30 min
+//normalC: char 2: abgebr. bei list SM = mstd(i);  //Now the work starts'
+//normalC, withGens, char 2: abgebrochen bei Q=mstd(Q)[2];
+//normalP char 2 withRing: 0sec
+
+ring r=0,(x,y),dp;   //irred, genus 55, delta 21
+ideal i=y40+y13x+x4y5+x3*(x+1)^2;
+//normalC: char 2 lange
+//normalP char 2 withRing: 0sec
+
+ring r=29,(x,y,t),dp; //char 0: genus -5, 4 Komp, delta (-1,-1,0,0), -1
+ideal i=x8+8x7y+32x6y2+80x5y3+136x4y4+160x3y5+128x2y6+64xy7+16y8+4x6t2+24x5yt2+72x4y2t2+128x3y3t2+144x2y4t2+96xy5t2+32y6t2+14x4t4+56x3yt4+112x2y2t4+112xy3t4+40y4t4+20x2t6+40xyt6+8y2t6+9t8;
+//normalC: char 29 : 0sec, char 0: 0sec  //char 29 6 Komponenten
+//normalP char 29 withRing: 1sec
+
+//-------------------------- problematic examples ------------------------
+//ring r=0,(x,y,t),dp;
+ring r=32003,(x,y,t),dp;
+ideal i=
+32761x8+786264x7y+8314416x6y2+50590224x5y3+193727376x4y4+478146240x3y5+742996800x2y6+664848000xy7+262440000y8+524176x7t+11007696x6yt+99772992x5y2t+505902240x4y3t+1549819008x3y4t+2868877440x2y5t+2971987200xy6t+1329696000y7t+3674308x6t2+66137544x5yt2+499561128x4y2t2+2026480896x3y3t2+4656222144x2y4t2+5746386240xy5t2+2976652800y6t2+14737840x5t3+221067600x4yt3+1335875904x3y2t3+4064449536x2y3t3+6226336512xy4t3+3842432640y5t3+36997422x4t4+443969064x3yt4+2012198112x2y2t4+4081745520xy3t4+31267516 [...]
+//char 0: lange (es liegt an den grossen Zahlen), char 32003: 0 sec
+
+//dasselbe Beipiel in char 19: irred
+ring r=0,(x,y,t),dp;
+ideal i=
+5x8+6x7y-3x6y2+7x5y3-6x4y4-8x3y5-5x2y6-8y8+4x7t+8x6yt+2x5y2t-6x4y3t+9x3y4t+9x2y5t-xy6t-7x6t2+7x5yt2-x4y2t2+5x3y3t2+7x2y4t2+xy5t2-3y6t2-4x5t3 -3x4yt3+2x3y2t3-7x2y3t3-6xy4t3-3y5t3-5x4t4-3x3yt4-4x2y2t4-8xy3t4 +7y4t4+x3t5+9x2yt5+9xy2t5-8y3t5-2y2t6+4xt7-7yt7-9t8;
+//normalP: char 2,3: 0sec, norTest 0,2 sec, char 11 haengt bei peimage
+//normalC: char 3: 0 sec, char 0: 1sec
+
+//ring r=0,(x,y),dp;
+ring r=32003,(x,y),dp;
+ideal i=
+x30y21+21x29y20+210x28y19+10x27y19+1330x27y18+190x26y18+5985x26y17
++1710x25y17+20349x25y16+45x24y17+9690x24y16+54264x24y15+765x23y16
++38760x23y15+116280x23y14+6120x22y15+116280x22y14+120x21y15
++203490x22y13+30600x21y14+271320x21y13+1799x20y14+293930x21y12+107100x20y13
++503880x20y12+12586x19y13+352716x20y11+278460x19y12+210x18y13+755820x19y11
++54509x18y12+352716x19y10+556920x18y11+2723x17y12+923780x18y10+163436x17y11
++293930x18y9+875160x17y10+16296x16y11+923780x17y9+359359x16y10+252x15y11
++203490x17y8+1093950x16y9+59598x15y10+755820x16y8+598598x15y9+2751x14y10
++116280x16y7+1093950x15y8+148610x14y9+503880x15y7+769197x14y8+13650x13y9
++54264x15y6+875160x14y7+266805x13y8+210x12y9+271320x14y6+768768x13y7
++40635x12y8+20349x14y5+556920x13y6+354816x12y7+1855x11y8+116280x13y5
++597597x12y6+80640x11y7+5985x13y4+278460x12y5+353892x11y6+7280x10y7+38760x12y4
++358358x11y5+112014x10y6+120x9y7+1330x12y3+107100x11y4+264726x10y5+16660x9y6
++9690x11y3+162799x10y4+111132x9y5+805x8y6+210x11y2+30600x10y3+146685x9y4
++24500x8y5+1710x10y2+54236x9y3+78750x8y4+2310x7y5+21x10y+6120x9y2+58520x8y3
++24010x7y4+45x6y5+190x9y+12509x8y2+39060x7y3+3675x6y4+x9+765x8y+15918x7y2
++15680x6y3+204x5y4+10x8+1786x7y+12915x6y2+3500x5y3+45x7+2646x6y+6580x5y2
++366x4y3+119x6+2562x5y+1995x4y2+10x3y3+203x5+1610x4y+324x3y2+231x4+630x3y
++23x2y2+175x3+141x2y+85x2+16xy+24x+y+4;
+list nor = normal(i);
+//normalC: char 0: ### haengt in SB of singular locus JM = mstd(J);
+//normalC: char 32003,"noFac","equidim": 0sec, "noFac": 1sec
+// ev neues interred
+genus(i);         // haengt bei int mu=vdim(std(jacob(f)));
+                  //### ist das noetig?
+
+//Singular rechnet genus richtig, auch im Fall, dass Kurve irreduzibel,
+//aber nicht absolut irreduzibel ist:
+ring r = 0,(x,y),dp;
+ideal i = x2+y2;      //irreduzibel /Q aber reduzibel /C (x-iy)*(x+iy)
+factorize( x2+y2);    //liefert irreduzibel
+genus(i);             //sollte 0+0-2+1= -1 sein
+genus(i,1);           //beides ist korrekt in Singular
+
+*/
diff --git a/Singular/LIB/normaliz.lib b/Singular/LIB/normaliz.lib
new file mode 100644
index 0000000..113b4d6
--- /dev/null
+++ b/Singular/LIB/normaliz.lib
@@ -0,0 +1,1684 @@
+//// Singular library normaliz.lib
+
+version="version normaliz.lib 4.0.0.0 Jun_2013 "; // $Id: 834af90f9535c61eaa27f93a6aaa915ac1b155b2 $
+category="Commutative Algebra";
+info="
+LIBRARY: normaliz.lib  Provides an interface for the use of Normaliz 2.7
+         within SINGULAR.
+AUTHORS:  Winfried Bruns, Winfried.Bruns at Uni-Osnabrueck.de
+          Christof Soeger, Christof.Soeger at Uni-Osnabrueck.de
+
+OVERVIEW:
+The library normaliz.lib provides an interface for the use of Normaliz 2.7
+within SINGULAR. The exchange of data is via files.
+In addition to the top level
+functions that aim at objects of type ideal or ring, several other auxiliary
+functions allow the user to apply Normaliz to data of type intmat. Therefore
+SINGULAR can be used as a comfortable environment for the work with Normaliz.
+@* Please see the @code{Normaliz2.7Documentation.pdf} (included in the Normaliz
+distribution) for a more extensive documentation of Normaliz.
+ at code{nmz_sing.pdf} describes this library version 2.2, but most points are
+still valid.
+
+@*Singular and Normaliz exchange data via files. These files are automatically
+created and erased behind the scenes. As long as one wants to use only the
+ring-theoretic functions there is no need for file management.
+
+@*Note that the numerical invariants computed by Normaliz can be
+accessed in this \"automatic file mode\".
+
+@*However, if Singular is used as a frontend for Normaliz or the user
+wants to inspect data not automatically returned to Singular, then
+an explicit filename and a path can be specified for the exchange of
+data. Moreover, the library provides functions for access to these files.
+Deletion of the files is left to the user.
+
+@* Use of this library requires the program Normaliz to be installed.
+You can download it from
+ at uref{http://www.mathematik.uni-osnabrueck.de/normaliz/}. Please make sure
+that the executables are in the search path or use setNmzExecPath
+(@ref{setNmzExecPath}).
+
+KEYWORDS: integral closure; normalization
+
+PROCEDURES:
+ intclToricRing(ideal I)      computes the integral closure of the toric ring
+                              generated by the leading monomials of the
+                              elements of I in the basering
+ normalToricRing(ideal I)     computes the normalization of the toric ring
+                              generated by the leading monomials of the
+                              elements of I
+ normalToricRingFromBinomials(ideal I)  computes the normalization of the
+                              polynomial ring modulo the unique minimal prime
+                              ideal of the binomial ideal I
+ ehrhartRing(ideal I)         computes the monomials representing the lattice
+                              points of the polytop generated leading monomials
+                              of the elements of I
+ intclMonIdeal(ideal I)       the exponent vectors of the leading monomials of
+                              the elements of I are considered as generators of
+                              a monomial ideal whose Rees algebra is computed
+
+ torusInvariants(intmat T)    computes the ring of invariants of a torus action
+ finiteDiagInvariants(intmat C)  computes the ring of invariants of a finite
+                                 abelian group acting diagonally on a polynomial
+                                 ring
+ diagInvariants(intmat C)     computes the ring of invariants of a
+                              diagonalizable group
+ intersectionValRings(intmat V)   computes the intersection of the polynomial
+                                  ring with the valuation rings of monomial
+                                  valuations
+ intersectionValRingIdeals(intmat V)       computes ideals of monomial valuations
+
+ showNuminvs()                prints the numerical invariants
+ exportNuminvs()              exports the numerical invariants
+
+ setNmzOption(string s, int onoff) sets the option s to onoff
+ showNmzOptions()             prints the enabled options to the standard output
+
+ normaliz(intmat sgr,int nmz_mode) applies Normaliz
+ setNmzExecPath(string nmz_exec_path_name) sets the path to the Normaliz
+                                           executable
+
+ writeNmzData(intmat sgr, int n_mode) creates an input file for Normaliz
+ readNmzData(string nmz_suffix) reads the Normaliz output file with the
+                                specified suffix
+
+ setNmzFilename(string nmz_filename_name) sets the filename for the exchange
+                                          of data
+ setNmzDataPath(string nmz_data_path_name) sets the directory for the exchange
+                                           of data
+ writeNmzPaths()              writes the path names into two files
+ startNmz()                   retrieves the path names written by writeNmzPaths
+ rmNmzFiles()                 removes the files created for and by Normaliz
+
+ mons2intmat(ideal I)         returns the intmat whose rows represent the
+                              leading exponents of the elements of I
+ intmat2mons(intmat expo_vecs) returns the ideal generated by the monomials
+                               which have the rows of expo_vecs as
+                               exponent vector
+ binomials2intmat(ideal I)    returns the intmat whose rows represent the
+                              exponents of the elements of the binomial ideal I
+";
+
+
+// helpers
+
+static proc desInt(string intname, int value)
+// define, export and set an integer
+{
+    int exists;
+    if(defined(`intname`)){exists=1;}
+    if(!exists)
+    {
+        int `intname`=value;export(`intname`);
+    }
+    `intname`=value;
+}
+
+static proc desString(string stringname, string value)
+// define, export and set a string
+{
+    int exists;
+    if(defined(`stringname`)){exists=1;}
+    if(!exists)
+    {
+        string `stringname`=value;export(`stringname`);
+    }
+    `stringname`=value;
+}
+
+static proc queryInt(string intname)
+// if intname is defined, return(intname), else return(0)
+{
+    int exists,value;
+    if(defined(`intname`)){exists=1;}
+    if(!exists)
+    {
+        return(0);
+    }
+    return(`intname`);
+}
+
+static proc queryString(string stringname)
+// if stringname is defined, return(stringname), else return("")
+{
+    int exists;
+    string value;
+    if(defined(`stringname`)){exists=1;}
+    if(!exists)
+    {
+        return("");
+    }
+    return(`stringname`);
+}
+
+static proc fileExists(string f)
+{
+    return(status (f,"exists")=="yes");
+}
+
+static proc appendSlash(string s)
+// if nonempty and / is not the terminating char
+{
+    if(size(s)>0)
+    {
+        if(s[size(s)]!="/")
+        {
+            s=s+"/";
+            return(s);
+        }
+    }
+    return(s);
+}
+
+// filenames and paths
+
+proc setNmzExecPath(string nmz_exec_path_name)
+"USAGE:   setNmzExecPath(string s);   @code{s} path to the Normaliz executable
+CREATE:   @code{Normaliz::nmz_exec_path} to save the given path @code{s}
+NOTE:     It is not necessary to use this function if the Normaliz executable
+          is in the search path of the system.
+SEE ALSO: setNmzOption
+EXAMPLE:  example setNmzExecPath; shows an example"
+{
+    desString("nmz_exec_path",nmz_exec_path_name);
+    nmz_exec_path=appendSlash(nmz_exec_path);
+}
+example
+{ "EXAMPLE:";echo = 2;
+  setNmzExecPath("../Normaliz/");
+}
+
+proc setNmzFilename(string nmz_filename_name)
+"USAGE:   setNmzFilename(string s);
+CREATE:   @code{Normaliz::nmz_filename} to save the given filename @code{s}
+NOTE:     The function sets the filename for the exchange of data. Unless a
+          path is set by setNmzDataPath, files will be created in the current
+          directory.
+          @* If a non-empty filename is set, the files created for and by
+             Normaliz are kept. This is mandatory for the data access functions
+             (see @ref{writeNmzData} and @ref{readNmzData}).
+          @* Resetting the filename by setNmzFilename(\"\") forces the library
+             to return to deletion of temporary files, but the files created
+             while the filename had been set will not be erased.
+SEE ALSO: writeNmzData, readNmzData, setNmzDataPath, rmNmzFiles
+EXAMPLE:  example setNmzFilename; shows an example"
+{
+    desString("nmz_filename",nmz_filename_name);
+    if(nmz_filename_name!="")
+    {
+        desInt("nmz_files_keep_switch",1);
+    }
+    else
+    {
+        desInt("nmz_files_keep_switch",0);
+    }
+}
+example
+{ "EXAMPLE:";echo = 2;
+  setNmzDataPath("examples/");
+  setNmzFilename("example1");
+  //now the files for the exchange with Normaliz are examples/example1.SUFFIX
+}
+
+proc setNmzDataPath(string nmz_data_path_name)
+"USAGE:   setNmzDataPath(string s);
+CREATE:   @code{Normaliz::nmz_data_path} to save the given path @code{s}
+NOTE:     The function sets the path for the exchange of data. By default the
+          files will be created in the current directory.
+          @* It seems that Singular cannot use filenames starting with @code{~}
+             or @code{$HOME} in its input/output functions.
+          @* You must also avoid path names starting with @code{/} if you work
+             under Cygwin, since Singular and Normaliz interpret them in
+             different ways.
+SEE ALSO: writeNmzData, readNmzData, rmNmzFiles, setNmzFilename
+EXAMPLE:  example setNmzDataPath; shows an example"
+{
+    desString("nmz_data_path",nmz_data_path_name);
+    nmz_data_path=appendSlash(nmz_data_path);
+}example
+{ "EXAMPLE:";echo = 2;
+  setNmzDataPath("examples/");
+  setNmzFilename("example1");
+  //now the files for the exchange with Normalize are examples/example1.SUFFIX
+}
+
+proc writeNmzPaths();
+"USAGE:   writeNmzPaths();
+CREATE:   the file nmz_sing_exec.path where the path to the Normaliz executable
+          is saved
+          @* the file nmz_sing_data.path where the directory for the exchange
+          of data is saved
+NOTE:     Both files are saved in the current directory. If one of the names
+          has not been defined, the corresponding file is created, but
+          contains nothing.
+SEE ALSO: setNmzDataPath, setNmzExecPath, startNmz
+EXAMPLE:  example writeNmzPaths; shows an example
+"{
+    link outf=":w nmz_sing_exec.path";
+    write(outf, queryString("nmz_exec_path"));
+    close(outf);
+
+    outf=":w nmz_sing_data.path";
+    write(outf, queryString("nmz_data_path"));
+    close(outf);
+}
+example
+{ "EXAMPLE:";echo = 2;
+  setNmzExecPath("../Normaliz/");
+  writeNmzPaths();
+  int dummy=system("sh","cat nmz_sing_exec.path");
+  dummy=system("sh","cat nmz_sing_data.path");
+}
+
+proc startNmz()
+"USAGE:   startNmz();
+PURPOSE:  This function reads the files written by @code{writeNmzPaths()},
+          retrieves the path names, and types them on the standard output
+          (as far as they have been set). Thus, once the path names have been
+          stored, a Normaliz session can simply be opened by this function.
+SEE ALSO: setNmzDataPath, setNmzExecPath, writeNmzPaths
+EXAMPLE:  example startNmz; shows an example
+"
+{
+    link inf=":r nmz_sing_exec.path";
+    string s=read(inf);
+    int i,p;
+    p=findWord("/",s,1);
+    if(p!=-1)
+    {
+        for(i=size(s);i>=1;i--)
+        {
+            if(s[i]=="/")
+            {
+                s=s[1..i];
+                break;
+            }
+        }
+        desString("nmz_exec_path",s);
+        "nmz_exec_path is",nmz_exec_path;
+    }
+    else
+    {
+        "nmz_exec_path not set";
+    }
+
+    inf=":r nmz_sing_data.path";
+    s=read(inf);
+    p=findWord("/",s,1);
+    if(p!=-1)
+    {
+        for(i=size(s);i>=1;i--)
+        {
+            if(s[i]=="/")
+            {
+                s=s[1..i];
+                break;
+            }
+        }
+        desString("nmz_data_path",s);
+        "nmz_data_path is",nmz_data_path;
+    }
+    else
+    {
+        "nmz_data_path not set";
+    }
+}
+example
+{ "EXAMPLE:"; echo=2;
+  startNmz();
+}
+
+static proc getNmzFile()
+{
+    if(queryInt("nmz_files_keep_switch"))
+    {
+        return(queryString("nmz_data_path")+queryString("nmz_filename"));
+    }
+    else
+    {
+        return(queryString("nmz_filename"));
+    }
+}
+
+static proc makeTempNmzDataPath()
+{
+    string testdir, testdir1;
+    int i,dummy;
+
+    testdir1="/tmp/nmz_sing_"+string(system("pid"));
+    testdir=testdir1;
+    while(fileExists(testdir))
+    {
+        i++;
+        testdir=testdir1+string(i);
+    }
+    dummy=system("sh","mkdir "+ testdir);
+    desString("nmz_filename",testdir+"/nmz"); //files are nmz+suffix in testdir
+}
+
+static proc eraseTempNmzDataPath();
+{
+    int dummy;
+
+    string tmpdir=getNmzFile();
+    tmpdir=tmpdir[1..size(tmpdir)-4]; // remove "/nmz"
+    dummy=system("sh","rm -r "+tmpdir);
+    setNmzFilename("");
+}
+
+static proc setNmzExec()
+{
+    return(queryString("nmz_exec_path")+"normaliz");
+}
+
+proc rmNmzFiles()
+"USAGE:  rmNmzFiles();
+PURPOSE: This function removes the files created for and by Normaliz, using
+         the last filename specified.
+         It needs an explicit filename set (see @ref{setNmzFilename}).
+SEE ALSO: writeNmzData, readNmzData, setNmzFilename, setNmzDataPath
+EXAMPLE:  example rmNmzFiles; shows an example
+"{
+
+    if(!queryInt("nmz_files_keep_switch"))
+    {
+        ERROR("rmNmzFiles: no filename specified");
+    }
+
+    list suffixes="in","gen","out","cst","typ","egn","esp","inv","tri","ht1",
+                  "ext";
+    int i,dummy;
+    string f;
+
+    for(i=1;i<=size(suffixes);i++)
+    {
+        f=getNmzFile()+"."+suffixes[i];
+        if (fileExists(f)) { dummy=system("sh","rm "+f+ "&> /dev/null"); }
+    }
+}
+example
+{ "EXAMPLE:"; echo=2;
+  setNmzFilename("VeryInteresting");
+  rmNmzFiles();
+}
+
+
+
+// parsing normaliz output
+
+static proc digit(string s)
+{
+    if(s==" ") // skip blanks quickly
+    {
+        return(0);
+    }
+
+    if((s[1]>="0" && s[1]<="9")||s[1]=="-")
+    {
+        return(1);
+    }
+    return(0);
+}
+
+static proc nextWord(string s, int p)
+{
+    int j,sw,ew;
+
+    for(;p<=size(s);p++) // must start with a letter
+    {
+
+        if((s[p]>="a" && s[p]<="z")||
+             (s[p]>="A" && s[p]<="Z"))
+        {
+            sw=p; break;
+        }
+    }
+    if(p>size(s))
+    {
+        return(-1,-1); // no word found
+    }
+
+    for(;p<=size(s);p++) // now numerals and -_ allowed
+    {
+        if(!((s[p]>="a" && s[p]<="z")||
+             (s[p]>="A" && s[p]<="Z")||
+             (s[p]>="0" && s[p]<="9")||
+              s[p]=="_"||s[p]=="-"))
+        {
+            break;
+        }
+    }
+    return(sw,p);
+}
+
+static proc getInt(string s, int p)
+{
+    string nst;
+    int i,j,en,sn;
+
+    for(;p<=size(s);p++)
+    {
+
+        if(digit(s[p]))
+        {
+            sn=p; break;
+        }
+    }
+    if(not(sn))
+    {
+        return(0,-1); // -1 indicates: no number found
+    }
+    p++;
+    for(;p<=size(s);p++)
+    {
+        if(!digit(s[p]))
+        {
+            en=p-1; break;
+        }
+    }
+    if(p>size(s))
+    {
+        en=size(s);
+    }
+    nst="i="+s[sn,en-sn+1];
+    execute(nst);
+    return(i,p);
+}
+
+
+static proc getRational(string s, int p)
+{
+    string nst;
+    int i,j,en,sn;
+
+    for(;p<=size(s);p++)
+    {
+        if(digit(s[p]))
+        {
+            sn=p; break;
+        }
+    }
+    if(not(sn))
+    {
+        return(0,-1); // -1 indicates: no number found
+    }
+    p++;
+    int slash_at;
+    for(;p<=size(s);p++)
+    {
+        if(s[p]=="/")
+        {
+            slash_at=p;
+            p++;
+            continue;
+        }
+        if(!digit(s[p]))
+        {
+            en=p-1; break;
+        }
+    }
+    if(p>size(s))
+    {
+        en=size(s);
+    }
+    if(slash_at)
+    {
+        nst="i="+s[sn,slash_at-sn];
+        execute(nst);
+        nst="j="+s[slash_at+1,en-slash_at];
+        execute(nst);
+        return(i,p,j);
+    }
+    nst="i="+s[sn,en-sn+1];
+    execute(nst);
+    return(i,p);
+}
+
+
+static proc findWord(string s, string t, int p)
+{
+    for(;p<=size(t)-size(s)+1;p++)
+    {
+        if(t[p]==s[1])
+        {
+            if(t[p,size(s)]==s)
+            {
+                 return(p+size(s));
+            }
+        }
+    }
+    return(-1);
+}
+
+
+static proc skipEqualsign(string s,int p)
+{
+    for(;p<=size(s);p++)
+    {
+        if(s[p]=="=")
+        {
+            break;
+        }
+    }
+    return(p+1);
+}
+
+
+// input and output to/from normaliz
+
+//list must have pairs of intmat, nmz_mode
+static proc doWriteNmzData(list #)
+{
+    string s;
+    int i,j;
+    link outf=":w "+ getNmzFile() +".in";  // also sets the filename
+
+    intmat sgr;
+    int num_rows, num_cols, n_mode;
+
+    for (int k=1; k+1<=size(#); k=k+2) {
+    //get data from the parameter list
+      sgr   = #[k];
+      num_rows = nrows(sgr);
+      num_cols = ncols(sgr);
+                n_mode   = #[k+1];
+
+      write(outf,num_rows);
+      write(outf,num_cols);
+
+      for(i=1;i<=nrows(sgr);i++)
+      {
+        s="";
+        for(j=1;j<=num_cols;j++)
+        {
+           s=s+string(sgr[i,j])+" ";
+        }
+        write(outf,s);
+      }
+      write(outf,n_mode);
+      write(outf,"");
+    }
+    close(outf);
+}
+
+
+proc writeNmzData(intmat sgr, int n_mode, list #)
+"USAGE:   writeNmzData(intmat M, int mode);
+          writeNmzData(intmat M, int mode, intmat M2, int mode2, ...);
+CREATE:   Creates an input file for Normaliz from the matrix M. The second
+          parameter sets the mode. How the matrix is interpreted depends on the
+          mode. See the Normaliz documentation for more information.
+
+                         It is also possible to give more than one pair of matrix and mode. In
+                         this case all matrices and modes are written. This can be used to
+                         combine modes 4,5,6.
+NOTE:     Needs an explicit filename set. The filename is created from the
+          current filename.
+   @*     Note that all functions in normaliz.lib write and read their data
+          automatically to and from the hard disk so that writeNmzData will
+          hardly ever be used explicitly.
+SEE ALSO: readNmzData, rmNmzFiles, setNmzFilename, setNmzDataPath
+EXAMPLE:  example writeNmzData; shows an example"
+{
+    if(queryString("nmz_filename")=="")
+    {
+        ERROR("writeNmzData: no filename specified");
+    }
+    doWriteNmzData(list(sgr, n_mode) + #);
+}
+example
+{ "EXAMPLE:"; echo=2;
+  setNmzFilename("VeryInteresting");
+  intmat sgr[3][3]=1,2,3,4,5,6,7,8,10;
+  writeNmzData(sgr,1);
+  int dummy=system("sh","cat VeryInteresting.in");
+
+  intmat Hyperplanes[2][3] = 2,-1,0, // 2x-y >= 0
+                             1, 1,0; //  x+y >= 0
+  intmat Equation[1][3] = 0,1,-1;    // y = z
+  intmat Congruence[1][4] = 1,0,0,3;  // x = 0 (3)
+  writeNmzData(Hyperplanes,4,Equation,5,Congruence,6);
+  dummy=system("sh","cat VeryInteresting.in");
+}
+
+
+proc readNmzData(string nmz_suffix)
+"USAGE:  readNmzData(string suffix);
+RETURN:  Reads an output file of Normaliz containing an integer matrix and
+         returns it as an intmat. For example, this function is useful if one
+         wants to inspect the support hyperplanes. The filename is created
+         from the current  filename and the suffix given to the function.
+NOTE:    Needs an explicit filename set by setNmzFilename.
+   @*    Note that all functions in normaliz.lib write and read their data
+         automatically so that readNmzData will usually not be used explicitly.
+   @*    This function reads only the first matrix in a file!
+SEE ALSO: writeNmzData, rmNmzFiles, setNmzFilename, setNmzDataPath
+EXAMPLE:  example readNmzData; shows an example"
+{
+    if(queryString("nmz_filename")=="")
+    {
+        ERROR("readNmzData: no filename specified");
+    }
+
+    string s;
+    int n_rows,n_cols;            //number of rows/columns
+    int p;                     //position
+    int i,j;
+    int returnvalue;
+
+    string filename = getNmzFile() + "."+ nmz_suffix;
+    link in_f=":r "+ filename;
+    s=read(in_f);
+    close(in_f);
+
+    p=1;
+    (n_rows,p)=getInt(s,p);
+    (n_cols,p)=getInt(s,p);
+    if (n_rows <= 0 || n_cols <= 0) {
+             intmat empty;
+             return(empty);
+    }
+         intmat nmz_gen[n_rows][n_cols];
+    for(i=1;i<=n_rows;i++)
+    {
+        for(j=1;j<=n_cols;j++)
+        {
+            (nmz_gen[i,j],p) = getInt(s,p);
+        }
+    }
+    return(nmz_gen);
+}
+example
+{ "EXAMPLE:"; echo=2;
+  setNmzFilename("VeryInteresting");
+  intmat sgr[3][3]=1,2,3,4,5,6,7,8,10;
+  intmat sgrnormal=normaliz(sgr,0);
+  readNmzData("cst");
+  readNmzData("typ");
+}
+
+
+// running normaliz (with options)
+
+// component 1 is name of option
+// 2 is default value
+// 3 is command line option to be passed to Normaliz
+// 4 indictes whether file "gen" is generated
+// value 2 of 4 indicates "no influence"
+
+static proc defNmzOptions()
+{
+    if(!defined(nmz_options)) // can be defined only once
+    {
+        list nmz_options=
+        list("supp",0,"-s",0),
+        list("triang",0,"-v",0),
+        list("volume",0,"-V",0),
+        list("hvect",0,"-p",0),
+        list("hvect_l",0,"-P",0),
+        list("height1",0,"-1",0),
+        list("normal",0,"-n",1),
+        list("normal_l",0,"-N",1),
+        list("hilb",0,"-h",1),
+        list("hilb_l",0,"-H",1),
+        list("dual",0,"-d",1),
+        list("control",0,"-c",2),
+        list("allf",0,"-a",2),
+        list("errorcheck",0,"-e",2),
+        list("bigint",0,"-B",2),
+        list("threads",0,"-x=",2);
+        export(nmz_options);
+    }
+}
+
+proc setNmzOption(string s, int onoff)
+"USAGE:   setNmzOption(string s, int onoff);
+PURPOSE:  If @code{onoff=1} the option @code{s} is activated, and
+          if @code{onoff=0} it is deactivated.
+The Normaliz options are accessible via the following names:
+@* @code{-s:  supp}
+@* @code{-v:  triang}
+@* @code{-V:  volume}
+@* @code{-p:  hvect}
+@* @code{-P:  hvect_l}
+@* @code{-1:  height1}
+@* @code{-n:  normal}
+@* @code{-N:  normal_l}
+@* @code{-h:  hilb}
+@* @code{-H:  hilb_l}
+@* @code{-d:  dual}
+@* @code{-a:  allf}
+@* @code{-c:  control}
+@* @code{-e:  errorcheck}
+@* @code{-B:  bigint} Use GMP for arbitrary precision integers
+@* @code{-x=N:  threads} In this case the int parameter is used to set the
+                         number of threads N, 0 means no explicit limiting.
+
+SEE ALSO: showNmzOptions
+EXAMPLE:  example setNmzOption; shows an example
+"
+{
+    defNmzOptions();
+    for(int i=1;i<=size(nmz_options);i++)
+    {
+        if(s==nmz_options[i][1])
+        {
+            nmz_options[i][2]=onoff;
+            return(1);
+        }
+    }
+    "Invalid option ", s;
+    return(0);
+}
+example
+{ "EXAMPLE:"; echo=2;
+  setNmzOption("hilb",1);
+  showNmzOptions();
+}
+
+static proc collectNmzOptions()
+{
+    defNmzOptions();
+    string run_options=" -f ";
+    desInt("GenGen",1); // indicates whether "gen" is generated
+    for(int i=1;i<=size(nmz_options);i++)
+    {
+        if(nmz_options[i][2])
+        {
+            run_options=run_options+nmz_options[i][3];
+                                if (nmz_options[i][1]=="threads") {
+                                        run_options=run_options+string(nmz_options[i][2]);
+                                }
+                                run_options=run_options+" ";
+            if(nmz_options[i][4]!=2)
+            {
+                GenGen=nmz_options[i][4];
+            }
+        }
+    }
+    return(run_options+" ");
+}
+
+proc showNmzOptions()
+"USAGE:   showNmzOptions();
+RETURN:   Returns the string of activated options.
+NOTE:     This string is used as parameter when calling Normaliz.
+SEE ALSO: setNmzOption
+EXAMPLE:  example showNmzOption; shows an example
+"
+{
+    return(collectNmzOptions());
+}
+example
+{ "EXAMPLE:"; echo=2;
+  setNmzOption("hilb",1);
+  showNmzOptions();
+}
+
+
+static proc runNormaliz(intmat sgr,def nmz_mode, list #)
+{
+    if(!queryInt("nmz_files_keep_switch"))
+    {
+        makeTempNmzDataPath();
+    }
+
+    doWriteNmzData(list(sgr, nmz_mode) + #);
+
+    if(queryInt("nmz_files_keep_switch"))
+    {
+       int dummy=system("sh",setNmzExec()+ collectNmzOptions() + getNmzFile());
+    }
+    else
+    {
+        string gotodir="/tmp";
+        string fname=getNmzFile();
+        fname=fname[6..size(fname)];
+        string exec="cd "+gotodir+" ; ";
+        exec=exec+setNmzExec()+ collectNmzOptions()+" ";
+        exec=exec+fname+" ;";
+        int dummy=system("sh",exec);
+    }
+
+    if(!GenGen) // return input matrix if "gen" has not been generated
+    {
+        if(!queryInt("nmz_files_keep_switch"))
+        {
+            eraseTempNmzDataPath();
+        }
+        return(sgr);
+    }
+    intmat Gen=readNmzData("gen");
+
+    if(!defined(Num_Invs))
+    {
+        list Num_Invs;
+        export Num_Invs;
+    }
+    Num_Invs=getNuminvs();
+
+    if(!queryInt("nmz_files_keep_switch"))
+    {
+        eraseTempNmzDataPath();
+    }
+
+    return(Gen);
+
+}
+
+proc normaliz(intmat sgr,int nmz_mode, list #)
+"USAGE:   normaliz(intmat sgr,int nmz_mode);
+          normaliz(intmat sgr, int nmz_mode, intmat sgr2, int nmz_mode2, ...);
+RETURN:   The function applies Normaliz to the parameter sgr in the mode set
+          by nmz_mode. The function returns the intmat defined by the file
+          with suffix gen.
+
+          It is also possible to give more than one pair of matrix and mode. In
+                         this case all matrices and modes are used. This can be used to
+                         combine modes 4,5,6.
+NOTE:     You will find procedures for many applications of Normaliz in this
+          library, so the explicit call of this procedure may not be necessary.
+SEE ALSO: intclToricRing, normalToricRing, ehrhartRing, intclMonIdeal,
+          torusInvariants, diagInvariants, finiteDiagInvariants, intersectionValRings,
+                         intersectionValRingIdeals
+EXAMPLE:  example normaliz; shows an example
+"
+{
+    return(runNormaliz(sgr,nmz_mode,#));
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring R=0,(x,y,z),dp;
+  intmat M[3][2]=3,1,
+                 3,2,
+                 1,3;
+  normaliz(M,1);
+
+  intmat Hyperplanes[2][3] = 2,-1,0, // 2x-y >= 0
+                             1, 1,0; //  x+y >= 0
+  intmat Equation[1][3] = 0,1,-1;    // y = z
+  intmat Congruence[1][4] = 1,0,0,3;  // x = 0 (3)
+  normaliz(Hyperplanes,4,Equation,5,Congruence,6);
+}
+
+
+// retrieving normaliz numerical invariants
+
+static proc getNuminvs()
+{
+    string s;
+    list num_invs;
+    int p,sw,v_length,i,dummy_int;
+    intvec dummy_vec;
+    string type_inv,name_inv,dummy_bool;
+
+    link in_f=":r "+ getNmzFile() + "."+"inv";
+    s=read(in_f);
+
+    p=1;
+    while(p<size(s))
+    {
+        (sw,p)=nextWord(s,p);
+        if(sw==-1)
+        {
+            break;
+        }
+        type_inv=s[sw..p-1];
+        if(type_inv=="vector")
+        {
+            (v_length,p)=getInt(s,p);
+            (sw,p)=nextWord(s,p);
+            name_inv=s[sw..p-1];
+            if(name_inv=="h-vector")
+            {
+                name_inv="h_vector";
+            }
+            if(name_inv!="hilbert_polynomial")
+            {
+                for(i=1;i<=v_length;i++)
+                {
+                    if(i==1)
+                    {
+                        (dummy_int,p)=getInt(s,p);
+                        dummy_vec=dummy_int;
+                    }
+                    else
+                    {
+                        (dummy_int,p)=getInt(s,p);
+                        dummy_vec=dummy_vec,dummy_int;
+                    }
+                }
+                num_invs=num_invs+list(list(name_inv,dummy_vec,"intvec"));
+            }
+            else
+            {
+                p=skipEqualsign(s,p);
+            }
+        }
+        if(type_inv=="integer")
+        {
+            (sw,p)=nextWord(s,p);
+            name_inv=s[sw..p-1];
+            (dummy_int,p)=getInt(s,p);
+            num_invs=num_invs+list(list(name_inv,dummy_int,"int"));
+        }
+        if(type_inv=="boolean")
+        {
+            (sw,p)=nextWord(s,p);
+            name_inv=s[sw..p-1];
+            p=skipEqualsign(s,p);
+            (sw,p)=nextWord(s,p);
+            dummy_bool=s[sw..p-1];
+            dummy_int=0;
+            if(dummy_bool=="true")
+            {
+                dummy_int=1;
+            }
+            num_invs=num_invs+list(list(name_inv,dummy_int,"int"));
+        }
+    }
+    return(num_invs);
+}
+
+proc showNuminvs()
+"USAGE:   showNuminvs();
+PURPOSE:  prints the numerical invariants
+SEE ALSO: exportNuminvs
+EXAMPLE:  example showNuminvs(); shows an example
+"
+{
+    list dummy;
+    int i;
+    for(i=1;i<=size(Num_Invs);i++)
+    {
+        dummy=Num_Invs[i];
+        dummy[1],":", dummy[2];
+    }
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring R=0,(x,y,z,t),dp;
+  ideal I=x^2,y^2,z^3;
+  list l=intclMonIdeal(I);
+  showNuminvs();
+}
+
+
+proc exportNuminvs()
+"USAGE:   exportNuminvs();
+CREATE:   Creates top-level variables which contain the numerical invariants.
+          Depending on the options of normaliz different invariants are
+          calculated. Use showNuminvs (@ref{showNuminvs}) to see which
+          invariants are available.
+SEE ALSO: showNuminvs
+EXAMPLE:  example exportNuminvs; shows an example
+"
+{
+    list dummy;
+    int i;
+    string s;
+    for(i=1;i<=size(Num_Invs);i++)
+    {
+        dummy=Num_Invs[i];
+        s=dummy[3]+" nmz_" + dummy[1] + "=dummy[2]; exportto(Top," + "nmz_" + dummy[1] + ");";
+        execute(s);
+    }
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring R=0,(x,y,z,t),dp;
+  ideal I=x^2,y^2,z^3;
+  list l=intclMonIdeal(I);
+  exportNuminvs();
+  // now the following variables are set:
+  nmz_hilbert_basis_elements;
+  nmz_number_extreme_rays;
+  nmz_rank;
+  nmz_index;
+  nmz_number_support_hyperplanes;
+  nmz_homogeneous;
+  nmz_primary;
+  nmz_ideal_multiplicity;
+}
+
+
+// intmats to/from monomials
+
+proc mons2intmat(ideal I)
+"USAGE:   mons2intmat(ideal I);
+RETURN:   Returns the intmat whose rows represent the leading exponents of the
+          (non-zero) elements of I. The length of each row is nvars(basering).
+SEE ALSO: intmat2mons
+EXAMPLE:  example mons2intmat; shows an example"
+{
+    int i,j,k;
+    intmat expo_vecs[size(I)][nvars(basering)];
+    intvec expo_v;
+
+    k=0;
+    for(i=1;i<=ncols(I);i++)
+    {
+        if(I[i]!=0)
+        {
+            k++;
+            expo_v=leadexp(I[i]);
+            for(j=1;j<=nvars(basering);j++)
+            {
+                expo_vecs[k,j]=expo_v[j];
+            }
+        }
+    }
+    return(expo_vecs);
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring R=0,(x,y,z),dp;
+  ideal I=x2,y2,x2yz3;
+  mons2intmat(I);
+}
+
+proc intmat2mons(intmat expo_vecs)
+"USAGE:   intmat2mons(intmat M);
+RETURN:   an ideal generated by the monomials which correspond to the exponent
+          vectors given by the rows of @code{M}
+NOTE:     The number of variables in the basering @code{nvars(basering)} has to
+          be at least the number of columns @code{ncols(M)}, otherwise the
+          function exits with an error.
+          is thrown (see @ref{ERROR}).
+SEE ALSO: mons2intmat
+EXAMPLE:  example intmat2mons; shows an example
+"
+{
+    int i,j;
+    poly m;
+    ideal mons;
+
+    if(nvars(basering)<ncols(expo_vecs))
+    {
+        ERROR("intmat2mons: not enough variables in ring");
+    }
+
+    for(i=1;i<=nrows(expo_vecs);i++)
+    {
+        m=1;
+        for(j=1;j<=ncols(expo_vecs);j++)
+        {
+            m=m*var(j)^expo_vecs[i,j];
+        }
+        mons=mons,m;
+    }
+     mons=simplify(mons,2);    // get rid of starting 0
+     return(mons);
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring R=0,(x,y,z),dp;
+  intmat expo_vecs[3][3] =
+  2,0,0,
+  0,2,0,
+  2,1,3;
+  intmat2mons(expo_vecs);
+}
+
+static proc intmat2monsSel(intmat expo_vecs, int d)
+{
+    int i,j;
+    poly m;
+    ideal mons;
+
+    if(nvars(basering)<ncols(expo_vecs)-1)
+    {
+        ERROR("intmat2monsSel: not enough variables in ring");
+    }
+
+    for(i=1;i<=nrows(expo_vecs);i++)
+    {
+        if(expo_vecs[i,ncols(expo_vecs)]==d)
+        {
+
+            m=1;
+            for(j=1;j<=ncols(expo_vecs)-1;j++)
+            {
+                m=m*var(j)^expo_vecs[i,j];
+            }
+            mons=mons,m;
+        }
+    }
+     mons=simplify(mons,2);    // get rid of starting 0
+     return(mons);
+}
+
+
+proc binomials2intmat(ideal I)
+"USAGE:   binomials2intmat(ideal I);
+RETURN:   Returns the intmat whose rows represent the exponents of the
+          (non-zero) elements of I which have to be binomials.
+                         The length of each row is nvars(basering).
+SEE ALSO: mons2intmat, intmat2mons
+EXAMPLE:  example binomials2intmat; shows an example"
+{
+  int i,j,k;
+  intmat expo_vecs[size(I)][nvars(basering)];
+  intvec expo_v;
+
+  k=0;
+  poly f;
+
+  for(i=1; i<=ncols(I); i++)
+  {
+    if( I[i] != 0 )
+    {
+      k++;
+      f = I[i];
+      if (leadcoef(f) != 1) {f = -f};  //works in all characteristics
+      if (size(f)!=2 || leadcoef(f)!=1 || leadcoef(f[2])!=-1)
+      {
+        ERROR(string("normalToricRing: binomial ideal expected: generator ",i,": ",I[i]));
+      }
+      expo_v = leadexp(f)-leadexp(f[2]);
+      for(j=1;j<=nvars(basering);j++)
+      {
+        expo_vecs[k,j]=expo_v[j];
+      }
+    }
+  }
+  return(expo_vecs);
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring S = 37,(u,v,w,x,y,z),dp;
+  ideal I = u2v-xyz, ux2-vyz, uvw-y2z;
+  binomials2intmat(I);
+}
+
+
+// integral closure of rings and ideals
+
+static proc runIntclToricRing(ideal I, int nmz_mode)
+{
+    intmat expo_vecs=mons2intmat(I);
+
+    string dummy=collectNmzOptions(); // only to set GenGen
+
+    return( intmat2mons( runNormaliz(expo_vecs,nmz_mode) ) );
+}
+
+proc intclToricRing(ideal I)
+"USAGE:   intclToricRing(ideal I);
+RETURN:   The toric ring S is the subalgebra of the basering generated by the
+          leading monomials of the elements of I. The function computes the
+          integral closure T of S in the basering and returns an ideal listing
+          the algebra generators of T over the coefficient field.
+@*        The function returns the input ideal I if one of the options
+          @code{supp}, @code{triang}, or @code{hvect} has been activated.
+          However, in this case some numerical invariants are computed, and
+          some other data may be contained in files that you can read into
+          Singular (see @ref{showNuminvs}, @ref{exportNuminvs}).
+NOTE:     A mathematical remark: the toric ring depends on the list of
+          monomials given, and not only on the ideal they generate!
+SEE ALSO:  normalToricRing, ehrhartRing, intclMonIdeal
+EXAMPLE:   example intclToricRing; shows an example
+"
+{
+    return(runIntclToricRing(I,0));
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring R=37,(x,y,t),dp;
+  ideal I=x3,x2y,y3;
+  intclToricRing(I);
+}
+
+proc normalToricRing(ideal I)
+"USAGE:   normalToricRing(ideal I);
+RETURN:   The toric ring S is the subalgebra of the basering generated by the
+          leading monomials of the elements of I. The function computes the
+          normalisation T of S and returns an ideal listing the algebra
+          generators of T over the coefficient field.
+@*        The function returns the input ideal I if one of the options
+          @code{supp}, @code{triang}, or @code{hvect} has been activated.
+          However, in this case some numerical invariants are computed, and
+          some other data may be contained in files that you can read into
+          Singular (see @ref{showNuminvs}, @ref{exportNuminvs}).
+NOTE:     A mathematical remark: the toric ring depends on the list of
+          monomials given, and not only on the ideal they generate!
+SEE ALSO: intclToricRing, ehrhartRing, intclMonIdeal, normalToricRingFromBinomials
+EXAMPLE:  example normalToricRing; shows an example
+"
+{
+    return(runIntclToricRing(I,1));
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring  R = 37,(x,y,t),dp;
+  ideal I = x3,x2y,y3;
+  normalToricRing(I);
+}
+
+
+proc normalToricRingFromBinomials(ideal I)
+"USAGE:   normalToricRingFromBinomials(ideal I);
+RETURN:
+ at tex
+The ideal $I$ is generated by binomials of type $X^a-X^b$ (multiindex notation)
+in the surrounding polynomial ring $K[X]=K[X_1,...,X_n]$. The binomials
+represent a congruence on the monoid ${Z}^n$ with residue monoid $M$.
+Let $N$ be the image of $M$ in gp($M$)/torsion. Then $N$ is universal in the
+sense that every homomorphism from $M$ to an affine monoid factors through $N$.
+If $I$ is a prime ideal, then $K[N]= K[X]/I$. In general, $K[N]=K[X]/P$ where
+$P$ is the unique minimal prime ideal of $I$ generated by binomials of type
+$X^a-X^b$.
+
+The function computes the normalization of $K[N]$ and returns a newly created
+polynomial ring of the same Krull dimension, whose variables are
+$x(1),...,x(n-r)$, where $r$ is the rank of the matrix with rows $a-b$.
+(In general there is no canonical choice for such an embedding.)
+Inside this polynomial ring there is an ideal $I$ which lists the algebra
+generators of the normalization of $K[N]$.
+ at end tex
+@*        The function returns the input ideal I if one of the options
+          @code{supp}, @code{triang}, or @code{hvect} has been activated.
+          However, in this case some numerical invariants are computed, and
+          some other data may be contained in files that you can read into
+          Singular.
+SEE ALSO: intclToricRing, normalToricRing, ehrhartRing, intclMonIdeal
+EXAMPLE:  example normalToricRing; shows an example
+"
+{
+        intmat expo_vecs = binomials2intmat(I);
+        string dummy=collectNmzOptions(); // only to set GenGen
+        intmat result = runNormaliz(expo_vecs,10);
+
+        list baseringlist = ringlist(basering);
+        ring S = (baseringlist[1]),(x(1..ncols(result))),dp;
+        ideal I = intmat2mons(result);
+        export(I);
+        return (S);
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring R = 37,(u,v,w,x,y,z),dp;
+  ideal I = u2v-xyz, ux2-wyz, uvw-y2z;
+  def S = normalToricRingFromBinomials(I);
+  setring S;
+  I;
+}
+
+static proc runIntclMonIdeal(ideal I, int nmz_mode)
+{
+    intmat expo_vecs=mons2intmat(I);
+    int i,last_comp;
+
+    // we test if there is room for the Rees algebra
+
+    for(i=1;i<=nrows(expo_vecs);i++)
+    {
+        if(expo_vecs[i,ncols(expo_vecs)]!=0)
+        {
+            last_comp=1;  break; // no
+        }
+    }
+
+    string dummy=collectNmzOptions(); // only to set GenGen
+
+    //adjust size of input matrix
+         if (!last_comp) { // remove last component
+             intmat tmp[nrows(expo_vecs)][ncols(expo_vecs)-1] = expo_vecs[1..nrows(expo_vecs),1..(ncols(expo_vecs)-1)];
+                  expo_vecs = tmp;
+         }
+    intmat nmz_data=runNormaliz(expo_vecs,nmz_mode);
+
+    if(last_comp)
+    {
+        ideal I1=intmat2monsSel(nmz_data,1);
+        return(list(I1));
+    }
+    else
+    {
+        ideal I1=intmat2monsSel(nmz_data,1);
+        ideal I2=intmat2mons(nmz_data);
+        return(list(I1,I2));
+    }
+}
+
+proc ehrhartRing(ideal I)
+"USAGE:    ehrhartRing(ideal I);
+RETURN:    The exponent vectors of the leading monomials of the elements of I
+           are considered as vertices of a lattice polytope P.
+           The Ehrhart ring of a (lattice) polytope P is the monoid algebra
+           defined by the monoid of lattice points in the cone over the
+           polytope P; see Bruns and Gubeladze, Polytopes, Rings, and K-theory,
+           Springer 2009, pp. 228, 229.
+           The function returns a list of ideals:
+@*         (i) If the last ring variable is not used by the monomials, it is
+               treated as the auxiliary variable of the Ehrhart ring. The
+               function returns two ideals, the first containing the monomials
+               representing the lattice points of the polytope, the second
+               containing the algebra generators of the Ehrhart ring over the
+                    coefficient field.
+@*         (ii) If the last ring variable is used by the monomials, the list
+                returned contains only one ideal, namely the monomials
+                representing the lattice points of the polytope.
+@*
+@*        The function returns the a list containing the input ideal I if one
+          of the options @code{supp}, @code{triang}, or @code{hvect} has been
+                         activated.
+          However, in this case some numerical invariants are computed, and
+          some other data may be contained in files that you can read into
+          Singular.
+NOTE:      A mathematical remark: the Ehrhart ring depends on the list of
+           monomials given, and not only on the ideal they generate!
+SEE ALSO: intclToricRing, normalToricRing, intclMonIdeal
+EXAMPLE:  example ehrhartRing; shows an example
+"
+{
+    return(runIntclMonIdeal(I,2));
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring R=37,(x,y,t),dp;
+  ideal J=x3,x2y,y3,xy2t7;
+  ehrhartRing(J);
+}
+
+proc intclMonIdeal(ideal I)
+"USAGE:   intclMonIdeal(ideal I);
+RETURN:   The exponent vectors of the leading monomials of the elements of I
+          are considered as generators of a monomial ideal for which the
+          normalization of its Rees algebra is computed. For a Definiton of the
+          Rees algebra (or Rees ring) see Bruns and Herzog, Cohen-Macaulay
+          rings, Cambridge University Press 1998, p. 182.
+          The function returns a list of ideals:
+@* (i) If the last ring variable is not used by the monomials, it is treated
+       as the auxiliary variable of the Rees algebra. The function returns two
+       ideals, the first containing the monomials generating the integral
+       closure of the monomial ideal, the second containing the algebra
+         generators of the normalization of the Rees algebra.
+@* (ii) If the last ring variable is used by the monomials, the list returned
+        contains only one ideal, namely the monomials generating the integral
+        closure of the ideal.
+@*        The function returns the a list containing the input ideal I if one
+          of the options @code{supp}, @code{triang}, or @code{hvect} has been
+                         activated.
+          However, in this case some numerical invariants are computed, and
+          some other data may be contained in files that you can read into
+          Singular (see @ref{showNuminvs}, @ref{exportNuminvs}).
+SEE ALSO: intclToricRing, normalToricRing, ehrhartRing
+EXAMPLE:  example intclMonIdeal; shows an example
+"
+{
+    return(runIntclMonIdeal(I,3));
+}
+example
+{ "EXAMPLE"; echo=2;
+    ring R=0,(x,y,z,t),dp;
+    ideal I=x^2,y^2,z^3;
+    list l=intclMonIdeal(I);
+    l[1]; // integral closure of I
+    l[2];  // monomials generating the integral closure of the Rees algebra
+}
+
+// torus invariants and valuation rings and ideals
+
+proc torusInvariants(intmat E)
+"USAGE:   torusInvariants(intmat A);
+RETURN:
+Returns an ideal representing the list of monomials generating the ring of
+invariants as an algebra over the coefficient field.
+ at tex
+$R^T$.
+ at end tex
+@*The function returns the ideal given by the input matrix A if one of
+the options @code{supp}, @code{triang}, or @code{hvect} has been
+activated.
+However, in this case some numerical invariants are computed, and
+some other data may be contained in files that you can read into
+Singular.
+BACKGROUND:
+ at tex
+ Let $T = (K^*)^r$ be the $r$-dimensional torus acting on the polynomial ring
+ $R = K[X_1 ,\ldots,X_n]$ diagonally. Such an action can be described as
+ follows: there are integers $a_{i,j}$, $i=1,\ldots,r$, $j=1,\ldots,n$, such
+ that $(\lambda_1,\ldots,\lambda_r)\in T$ acts by the substitution
+$$ X_j \mapsto \lambda_1^{a_{1,j}} \cdots \lambda_r^{a_{r,j}}X_j,
+   \quad j=1,\ldots,n.$$
+In order to compute the ring of invariants $R^T$ one must specify the matrix
+$A=(a_{i,j})$.
+ at end tex
+SEE ALSO: diagInvariants, finiteDiagInvariants, intersectionValRings,
+          intersectionValRingIdeals
+EXAMPLE:  example torusInvariants; shows an example
+"
+{
+    if(nvars(basering)!=ncols(E))
+    {
+        ERROR("torusInvariants: wrong number of columns in matrix");
+    }
+
+    string dummy=collectNmzOptions();  // only to set GenGen
+
+    return( intmat2mons( runNormaliz(E,5) ) );
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring R=0,(x,y,z,w),dp;
+  intmat E[2][4] = -1,-1,2,0, 1,1,-2,-1;
+  torusInvariants(E);
+}
+
+proc finiteDiagInvariants(intmat C)
+"USAGE:   finiteDiagInvariants(intmat U);
+RETURN:
+ at tex
+This function computes the ring of invariants of a finite abelian group $G$
+acting diagonally on the surrounding polynomial ring $K[X_1,...,X_n]$. The
+group is the direct product of cyclic groups generated by finitely many
+elements $g_1,...,g_w$. The element $g_i$ acts on the indeterminate $X_j$ by
+$g_i(X_j)=\lambda_i^{u_{ij}}X_j$ where $\lambda_i$ is a primitive root of
+unity of order equal to $ord(g_i)$. The ring of invariants is generated by all
+monomials satisfying the system
+$u_{i1}a_1+\ldots+u_{in} a_n \equiv 0$ mod ord$(g_i)$, $i=1,\ldots,w$.
+The input to the function is the $w\times(n+1)$ matrix $U$ with rows
+$u_{i1}\ldots u_{in}$ ord$(gi)$, $i=1,\ldots,w$. The output is a monomial ideal
+listing the algebra generators of the subalgebra of invariants
+{$R^G=\{f\in R : g_i f = f$ for all $i=1,\ldots,w\}$}.
+ at end tex
+@*The function returns the ideal given by the input matrix C if one of
+the options @code{supp}, @code{triang}, or @code{hvect} has been
+activated.
+However, in this case some numerical invariants are computed, and
+some other data may be contained in files that you can read into
+Singular.
+NOTE:
+SEE ALSO: torusInvariants, diagInvariants, intersectionValRings,
+          intersectionValRingIdeals,showNuminvs,exportNuminvs
+EXAMPLE:  example finiteDiagInvariants; shows an example
+"
+{
+    if(nvars(basering)!=ncols(C)-1)
+    {
+        ERROR("finiteDiagInvariants: wrong number of columns in matrix");
+    }
+
+    string dummy=collectNmzOptions();  // only to set GenGen
+
+    return( intmat2mons( runNormaliz(C,6) ) );
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring R = 0,(x,y,z,w),dp;
+  intmat C[2][5] = 1,1,1,1,5, 1,0,2,0,7;
+  finiteDiagInvariants(C);
+}
+
+proc diagInvariants(intmat E, intmat C)
+"USAGE:   diagInvariants(intmat A, intmat U);
+RETURN:
+ at tex
+This function computes the ring of invariants of a diagonalizable group
+$D = T\times G$ where $T$ is a torus and $G$ is a finite abelian group, both
+acting diagonally on the polynomial ring $K[X_1,\ldots,X_n]$. The group
+actions are specified by the input matrices A and U. The first matrix specifies
+the torus action, the second the action of the finite group. See
+torusInvariants and finiteDiagInvariants for more detail. The output is a
+monomial ideal listing the algebra generators of the subalgebra of invariants.
+ at end tex
+@*The function returns the ideal given by the input matrix A if one of
+the options @code{supp}, @code{triang}, or @code{hvect} has been
+activated.
+However, in this case some numerical invariants are computed, and
+some other data may be contained in files that you can read into
+Singular.
+SEE ALSO: torusInvariants, finiteDiagInvariants, intersectionValRings, intersectionValRingIdeals,showNuminvs,exportNuminvs
+EXAMPLE:  example diagInvariants; shows an example
+"
+{
+    if(nvars(basering)!=ncols(E) || nvars(basering)!=ncols(C)-1)
+    {
+        ERROR("diagInvariants: wrong number of columns in matrix");
+    }
+
+    string dummy=collectNmzOptions();  // only to set GenGen
+
+    return( intmat2mons( runNormaliz(E,5,C,6) ) );
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring R=0,(x,y,z,w),dp;
+  intmat E[2][4] = -1,-1,2,0, 1,1,-2,-1;
+  intmat C[2][5] = 1,1,1,1,5, 1,0,2,0,7;
+  diagInvariants(E,C);
+}
+
+proc intersectionValRings(intmat V)
+"USAGE:   intersectionValRings(intmat V);
+RETURN:   The function returns a monomial ideal, to be considered as the list
+          of monomials generating @math{S} as an algebra over the coefficient
+          field.
+BACKGROUND:
+ at tex
+A discrete monomial valuation $v$ on $R = K[X_1 ,\ldots,X_n]$ is determined by
+the values $v(X_j)$ of the indeterminates. This function computes the
+subalgebra $S = \{ f \in R : v_i ( f ) \geq 0,\ i = 1,\ldots,r\}$ for several
+such valuations $v_i$, $i=1,\ldots,r$. It needs the matrix $V = (v_i(X_j))$ as
+its input.
+ at end tex
+@*The function returns the ideal given by the input matrix V if one of
+the options @code{supp}, @code{triang}, or @code{hvect} has been
+activated.
+However, in this case some numerical invariants are computed, and
+some other data may be contained in files that you can read into
+Singular.
+SEE ALSO: torusInvariants, diagInvariants, finiteDiagInvariants, intersectionValRingIdeals,showNuminvs,exportNuminvs
+EXAMPLE:  example intersectionValRings; shows an example
+"
+{
+
+    if(nvars(basering)!=ncols(V))
+    {
+        ERROR("intersectionValRings: wrong number of columns in matrix");
+    }
+
+    intmat V1[nrows(V)+ncols(V)][ncols(V)];
+    int i,j;
+
+    for(i=1;i<=ncols(V);i++)
+    {
+        V1[i,i]=1;
+    }
+    for(i=1;i<=nrows(V);i++)
+    {
+        for(j=1;j<=ncols(V);j++)
+        {
+            V1[i+ncols(V),j]=V[i,j];
+        }
+    }
+
+
+    string dummy=collectNmzOptions();  // only to set GenGen
+
+/*    if(!GenGen) // return V
+    {
+        runNormaliz(V1,4);
+        return(V);
+    }
+*/
+    return(intmat2mons(runNormaliz(V1,4)));
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring R=0,(x,y,z,w),dp;
+  intmat V0[2][4]=0,1,2,3, -1,1,2,1;
+  intersectionValRings(V0);
+}
+
+proc intersectionValRingIdeals(intmat V)
+"USAGE:   intersectionValRingIdeals(intmat V);
+RETURN:   The function returns two ideals, both to be considered as lists of
+          monomials which generate an algebra over the coefficient field. The
+          first is the system of monomial generators of @math{S}, the second
+          the system of generators of @math{M}.
+@*        The function returns a list consisting of the ideal given by the
+          input matrix T if one of the options @code{supp}, @code{triang}, or
+          @code{hvect} has been activated.
+          However, in this case some numerical invariants are computed, and
+          some other data may be contained in files that you can read into
+          Singular (see @ref{showNuminvs}, @ref{exportNuminvs}).
+BACKGROUND:
+ at tex
+A discrete monomial valuation $v$ on $R = K[X_1 ,\ldots,X_n]$ is determined by
+the values $v(X_j)$ of the indeterminates. This function computes the
+subalgebra $S = \{ f \in R : v_i ( f ) \geq 0,\ i = 1,\ldots,r\}$ for several
+such valuations $v_i$, $i=1,\ldots,r$. It needs the matrix $V = (v_i(X_j))$ as
+its input.
+
+This function simultaneously determines the $S$-submodule
+$M = \{ f \in R : v_i(f) \geq w_i ,\ i = 1,\ldots,r\}$ for integers
+$w_1,\ldots\,w_r$. (If $w_i \geq 0$ for all $i$, $M$ is an ideal of $S$.)
+The numbers $w_i$ form the $(n+1)$th column of the input matrix.
+ at end tex
+NOTE:   The function also gives an error message if the matrix V has the
+        wrong number of columns.
+SEE ALSO: torusInvariants, diagInvariants, finiteDiagInvariants, intersectionValRings
+EXAMPLE:  example intersectionValRingIdeals; shows an example
+"
+{
+    if(nvars(basering)!=ncols(V)-1)
+    {
+        ERROR("intersectionValRingIdeals: wrong number of columns in matrix");
+    }
+
+    intmat V1[nrows(V)+ncols(V)][ncols(V)];
+    int i,j;
+
+    for(i=1;i<=ncols(V);i++)
+    {
+        V1[i,i]=1;
+    }
+    for(i=1;i<=nrows(V);i++)
+    {
+        for(j=1;j<=ncols(V);j++)
+        {
+            V1[i+ncols(V),j]=V[i,j];
+        }
+    }
+    for(i=1;i<=nrows(V);i++)
+    {
+        V1[i+ncols(V),ncols(V)]=-V1[i+ncols(V),ncols(V)];
+    }
+
+    string dummy=collectNmzOptions();  // only to set GenGen
+
+    intmat nmz_data=runNormaliz(V1,4);
+
+    ideal I1=intmat2monsSel(nmz_data,0);
+    ideal I2=intmat2monsSel(nmz_data,1);
+    return(list(I1,I2));
+}
+example
+{ "EXAMPLE:"; echo=2;
+ ring R=0,(x,y,z,w),dp;
+ intmat V[2][5]=0,1,2,3,4, -1,1,2,1,3;
+ intersectionValRingIdeals(V);
+}
diff --git a/Singular/LIB/ntsolve.lib b/Singular/LIB/ntsolve.lib
new file mode 100644
index 0000000..e86a194
--- /dev/null
+++ b/Singular/LIB/ntsolve.lib
@@ -0,0 +1,364 @@
+//////////////////////////////////////////////////////////////////////////////
+version="version ntsolve.lib 4.0.0.0 Jun_2013 "; // $Id: db288a21f5e6b13c10c1226596c661ff6d0e7d03 $
+category="Symbolic-numerical solving";
+info="
+LIBRARY:  ntsolve.lib     Real Newton Solving of Polynomial Systems
+AUTHORS:  Wilfred Pohl, email: pohl at mathematik.uni-kl.de
+          Dietmar Hillebrand
+
+PROCEDURES:
+ nt_solve(G,ini,[..]);        find one real root of 0-dimensional ideal G
+ triMNewton(G,a,[..]);      find one real root for 0-dim triangular system G
+";
+
+LIB "general.lib";
+///////////////////////////////////////////////////////////////////////////////
+
+proc nt_solve (ideal gls, ideal ini, list #)
+"USAGE:   nt_solve(gls,ini[,ipar]); gls,ini= ideals, ipar=list/intvec,@*
+  gls: contains the equations, for which a solution will be computed@*
+  ini: ideal of initial values (approximate solutions to start with),@*
+  ipar: control integers (default: ipar = [100, 10])
+  @format
+ ipar[1]: max. number of iterations
+ ipar[2]: accuracy (we have the l_2-norm ||.||): accepts solution @code{sol}
+          if ||gls(sol)|| < eps0*(0.1^ipar[2])
+          where eps0 = ||gls(ini)|| is the initial error
+  @end format
+ASSUME:  gls is a zerodimensional ideal with nvars(basering) = size(gls) (>1)
+RETURN:  ideal, coordinates of one solution (if found), 0 else
+NOTE:    if printlevel >0: displays comments (default =0)
+EXAMPLE: example nt_solve; shows an example
+"
+{
+    def rn = basering;
+    int di = size(gls);
+    if (nvars(basering) != di){
+      ERROR("// wrong number of equations");}
+    if (size(ini) != di){
+      ERROR("// wrong number of initial values");}
+    int prec = system("getPrecDigits"); // precision
+
+    int i1,i2,i3;
+    int itmax, acc;
+    intvec ipar;
+    if ( size(#)>0 ){
+       i1=1;
+       if (typeof(#[1])=="intvec") {ipar=#[1];}
+       if (typeof(#[1])=="int") {ipar[1]=#[1];}
+       if ( size(#)>1 ){
+          i1=2;
+          if (typeof(#[2])=="int") {ipar[2]=#[2];}
+       }
+    }
+
+    int prot = printlevel-voice+2;  // prot=printlevel (default:prot=0)
+    if (i1 < 1){itmax = 100;}else{itmax = ipar[1];}
+    if (i1 < 2){acc = prec div 2;}else{acc = ipar[2];}
+    if ((acc <= 0)||(acc > prec-1)){acc = prec-1;}
+
+    int dpl = di+1;
+    string out;
+    out = "ring rnewton=(real,prec),("+varstr(basering)+"),(c,dp);";
+    execute(out);
+
+    ideal gls1=imap(rn,gls);
+    module nt,sub;
+    sub = transpose(jacob(gls1));
+    for (i1=di;i1>0;i1--){
+      if(sub[i1]==0){break;}}
+    if (i1>0){
+      setring rn; kill rnewton;
+      ERROR("// one var not in equation");}
+
+    list direction;
+    ideal ini1;
+    ini1 = imap(rn,ini);
+    number dum,y1,y2,y3,genau;
+    genau = 0.1;
+    dum = genau;
+    genau = genau^acc;
+
+    for (i1=di;i1>0;i1--){
+      sub[i1]=sub[i1]+gls1[i1]*gen(dpl);}
+    nt = sub;
+    for (i1=di;i1>0;i1--){
+      nt = subst(nt,var(i1),ini1[i1]);}
+
+    // now we have in sub the general structure
+    // and in nt the structure with subst. vars
+
+    // compute initial error
+    y1 = ml2norm(nt,genau);
+    dbprint(prot,"// initial error = "+string(y1));
+    y2 = genau*y1;
+
+  // begin of iteration
+  for(i3=1;i3<=itmax;i3++){
+     dbprint(prot,"// iteration: "+string(i3));
+
+    // find newton direction
+    direction=bareiss(nt,1,-1);
+
+    // find dumping
+    dum = linesearch(gls1,ini1,direction[1],y1,dum,genau);
+    if (i3%5 == 0)
+    {
+      if (dum <= 0.000001)
+      {
+        dum = 1.0;
+      }
+    }
+    dbprint(prot,"// dumping = "+string(dum));
+
+    // new value
+    for(i1=di;i1>0;i1--){
+      ini1[i1]=ini1[i1]-dum*direction[1][i1];}
+    nt = sub;
+    for (i1=di;i1>0;i1--){
+      nt = subst(nt,var(i1),ini1[i1]);}
+    y1 = ml2norm(nt,genau);
+    dbprint(prot,"// error = "+string(y1));
+    if(y1<y2){break;} // we are ready
+  }
+
+    if (y1>y2){
+      "// ** WARNING: iteration bound reached with error > error bound!";}
+    setring rn;
+    ini = imap(rnewton,ini1);
+    kill rnewton;
+    return(ini);
+}
+example
+{
+    "EXAMPLE:";echo=2;
+    ring rsq = (real,40),(x,y,z,w),lp;
+    ideal gls =  x2+y2+z2-10, y2+z3+w-8, xy+yz+xz+w5 - 1,w3+y;
+    ideal ini = 3.1,2.9,1.1,0.5;
+    intvec ipar = 200,0;
+    ideal sol = nt_solve(gls,ini,ipar);
+    sol;
+}
+///////////////////////////////////////////////////////////////////////////////
+
+static proc sqrt (number wr, number wa, number wg)
+{
+  number es,we;
+  number wb=wa;
+  number wf=wb*wb-wr;
+  if(wf>0){
+    es=wf;}
+  else{
+    es=-wf;}
+  we=wg*es;
+  while (es>we)
+  {
+    wf=wf/(wb+wb);
+    wb=wb-wf;
+    wf=wb*wb-wr;
+    if(wf>0){
+      es=wf;}
+    else{
+      es=-wf;}
+  }
+  return(wb);
+}
+
+static proc il2norm (ideal H, number wg)
+{
+  number wa,wb;
+  int wi,dpl;
+  wa = leadcoef(H[1]);
+  wa = wa*wa;
+  for(wi=size(H);wi>1;wi--)
+  {
+    wb=leadcoef(H[wi]);
+    wa=wa+wb*wb;
+  }
+  return(sqrt(wa,wa,wg));
+}
+
+static proc ml2norm (module H, number wg)
+{
+  number wa,wb;
+  int wi,dpl;
+  dpl = size(H)+1;
+  wa = leadcoef(H[1][dpl]);
+  wa = wa*wa;
+  for(wi=size(H);wi>1;wi--)
+  {
+    wb=leadcoef(H[wi][dpl]);
+    wa=wa+wb*wb;
+  }
+  return(sqrt(wa,wa,wg));
+}
+
+static
+proc linesearch(ideal nl, ideal aa, ideal bb,
+number z1, number tt, number gg)
+{
+  int ii,d;
+  ideal cc,jn;
+  number ss,z2,z3,mm;
+
+  mm=0.000001;
+  ss=tt;
+  d=size(nl);
+  cc=aa;
+  for(ii=d;ii>0;ii--){cc[ii]=cc[ii]-ss*bb[ii];}
+  jn=nl;
+  for(ii=d;ii>0;ii--){jn=subst(jn,var(ii),cc[ii]);}
+  z2=il2norm(jn,gg);
+  z3=-1;
+  while(z2>=z1)
+  {
+    ss=0.5*ss;
+    if(ss<mm){return (mm);}
+    cc=aa;
+    for(ii=d;ii>0;ii--)
+    {
+      cc[ii]=cc[ii]-ss*bb[ii];
+    }
+    jn=nl;
+    for(ii=d;ii>0;ii--){jn=subst(jn,var(ii),cc[ii]);}
+    z3=z2;
+    z2=il2norm(jn,gg);
+  }
+  if(z3<0)
+  {
+    while(z3<z2)
+    {
+      ss=ss+ss;
+      cc=aa;
+      for(ii=d;ii>0;ii--)
+      {
+        cc[ii]=cc[ii]-ss*bb[ii];
+      }
+      jn=nl;
+      for(ii=d;ii>0;ii--){jn=subst(jn,var(ii),cc[ii]);}
+      if(z3>0){z2=z3;}
+      z3=il2norm(jn,gg);
+    }
+  }
+  z2=z2-z1;
+  z3=z3-z1;
+  ss=0.25*ss*(z3-4*z2)/(z3-2*z2);
+  if(ss>1.0){return (1.0);}
+  if(ss<mm){return (mm);}
+  return(ss);
+}
+///////////////////////////////////////////////////////////////////////////////
+//
+//   Multivariate Newton for triangular systems
+//   algorithms for solving algebraic system of dimension zero
+//   written by Dietmar Hillebrand
+///////////////////////////////////////////////////////////////////////////////
+
+proc triMNewton (ideal G, ideal a, list #)
+"USAGE:  triMNewton(G,a[,ipar]); G,a= ideals, ipar=list/intvec
+ASSUME:  G:   g1,..,gn, a triangular system of n equations in n vars, i.e.
+  gi=gi(var(n-i+1),..,var(n)),@*
+  a:   ideal of numbers, coordinates of an approximation of a common
+       zero of G to start with (with a[i] to be substituted in var(i)),@*
+  ipar: control integer vector (default: ipar = [100, 10])
+  @format
+  ipar[1]: max. number of iterations
+  ipar[2]: accuracy (we have as norm |.| absolute value ):
+           accepts solution @code{sol} if |G(sol)| < |G(a)|*(0.1^ipar[2]).
+  @end format
+RETURN:  an ideal, coordinates of a better approximation of a zero of G
+EXAMPLE: example triMNewton; shows an example
+"
+{
+    int prot = printlevel;
+    int i1,i2,i3;
+    intvec ipar;
+    if ( size(#)>0 ){
+       i1=1;
+       if (typeof(#[1])=="intvec") {ipar=#[1];}
+       if (typeof(#[1])=="int") {ipar[1]=#[1];}
+       if ( size(#)>1 ){
+          i1=2;
+          if (typeof(#[2])=="int") {ipar[2]=#[2];}
+       }
+    }
+    int itb, err;
+    if (i1 < 1) {itb = 100;} else {itb = ipar[1];}
+    if (i1 < 2) {err = 10;} else {err = ipar[2];}
+
+    if (itb == 0)
+    {
+       dbprint(prot,"// ** iteration bound reached with error > error bound!");
+       return(a);
+    }
+
+    int i,j,k;
+    ideal p=G;
+    matrix J=jacob(G);
+    list h;
+    poly hh;
+    int fertig=1;
+    int n=nvars(basering);
+
+    for (i = 1; i <= n; i++)
+    {
+        for (j = n; j >= n-i+1; j--)
+        {
+            p[i] = subst(p[i],var(j),a[j]);
+            for (k = n; k >= n-i+1; k--)
+            {
+                J[i,k] = subst(J[i,k],var(j),a[j]);
+            }
+        }
+        if (J[i,n-i+1] == 0)
+        {
+            ERROR("// ideal not radical");
+            return();
+        }
+
+        // solve linear equations
+        hh = -p[i];
+        for (j = n; j >= n-i+2; j--)
+        {
+            hh = hh - J[i,j]*h[j];
+        }
+        h[n-i+1] = number(hh/J[i,n-i+1]);
+    }
+
+    for (i = 1; i <= n; i++)
+    {
+        if ( absValue(h[i]) > (1/10)^err)
+        {
+            fertig = 0;
+            break;
+        }
+    }
+    if ( not fertig )
+    {
+        if (prot > 0)
+        {
+           "// error:"; print(absValue(h[i]));
+           "// iterations to be performed: "+string(itb);
+        }
+        for (i = 1; i <= n; i++)
+        {
+            a[i] = a[i] + h[i];
+        }
+        ipar = itb-1,err;
+        return(triMNewton(G,a,ipar));
+    }
+    else
+    {
+        return(a);
+    }
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r = (real,30),(z,y,x),(lp);
+   ideal i = x^2-1,y^2+x4-3,z2-y4+x-1;
+   ideal a = 2,3,4;
+   intvec e = 20,10;
+   ideal l = triMNewton(i,a,e);
+   l;
+}
+///////////////////////////////////////////////////////////////////////////////
diff --git a/Singular/LIB/numerAlg.lib b/Singular/LIB/numerAlg.lib
new file mode 100644
index 0000000..cdec65f
--- /dev/null
+++ b/Singular/LIB/numerAlg.lib
@@ -0,0 +1,559 @@
+//////////////////////////////////////////////////////////////////////////////
+version="version numerAlg.lib 4.0.0.0 Jun_2013 "; // $Id: 4716f01278c13d50c18b86bdb64f744c32d62980 $
+category="Algebraic Geometry";
+info="
+LIBRARY:  NumerAlg.lib    Numerical Algebraic Algorithm
+OVERVIEW:
+        The library contains procedures to
+        test the inclusion, the equality of two ideals defined by polynomial systems,
+        compute the degree of a pure i-dimensional component of an algebraic variety
+         defined by a polynomial system,
+        compute the local dimension of an algebraic variety defined by a polynomial
+         system at a point computed as an approximate value. The use of the library
+         requires to install Bertini (http://www.nd.edu/~sommese/bertini).
+
+AUTHOR: Shawki AlRashed, rashed at mathematik.uni-kl.de; sh.shawki at yahoo.de
+PROCEDURES:
+
+ Incl(ideal I, ideal J);   test if I containes J
+
+ Equal(ideal I, ideal J);  test if I equals to J
+
+ Degree(ideal I, int i);   computes the degree of a pure i-dimensional
+
+ NumLocalDim(ideal I, p);  numerical local dimension at a point computed as
+                                  an approximate value
+";
+
+LIB "numerDecom.lib";
+
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+proc Degree(ideal I,int i)
+"USAGE:  Degree(ideal I,int i); I ideal,  i positive integer
+RETURN:  the degree of the pure i-dimensional component of the algebraic
+          variety defined by I
+EXAMPLE: example Degree; shows an example
+"
+{
+ def S=basering;
+ def W=WitSet(I);
+ setring W;
+ int j;
+ if(size(W(i)[1])>1)
+ {
+  j=size(W(i));
+ }
+ else
+ {
+  j=-1; // no component of dimension i
+ }
+ "The Degree of Component";
+ j;
+ setring S;
+ return (W);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r=0,(x,y,z),dp;
+   poly f1=(x2+y2+z2-6)*(x-y)*(x-1);
+   poly f2=(x2+y2+z2-6)*(x-z)*(y-2);
+   poly f3=(x2+y2+z2-6)*(x-y)*(x-z)*(z-3);
+   ideal I=f1,f2,f3;
+   def W=Degree(I,1);
+        ==>
+           The Degree of Component
+           3
+   def W=Degree(I,2);
+        ==>
+           The Degree of Component
+           2
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc Incl(ideal I, ideal J)
+"USAGE:  Incl(ideal I, ideal J); I, J ideals
+RETURN:  t=1 if the algebraic variety defined by I contains the algebraic
+           variety defined by J, otherwise t=0
+EXAMPLE: example Incl; shows an example
+"
+{
+ def S=basering;
+ int n=nvars(basering);
+ int i,j,ii,k,z,zi,dd;
+ if(dim(std(I))==0)
+ {
+  def W=solve(I,"nodisplay");
+  setring W;
+  ideal J=imap(S,J);
+  ideal I=imap(S,I);
+  list w;
+  poly tj;
+  number al,ar,ai,ri,jj;
+  zi=size(SOL);
+  for(j=1;j<=zi;j++)
+  {
+   w=SOL[j];
+   for(k=1;k<=size(J);k++)
+   {
+    tj=J[k];
+    for(ii=1;ii<=n;ii++)
+    {
+     tj=subst(tj,var(ii),w[ii]);
+    }
+    al=leadcoef(tj);
+    ar=repart(al);
+    ai=impart(al);
+    ri=ar^2+ai^2;
+    if(ri>0.000000000000001)
+    {
+     jj=0;
+     k=size(I)+1;
+     j=zi+1;
+    }
+    else
+    {
+     jj=1;
+     ri=0;
+    }
+   }
+  }
+ }
+ else
+ {
+  def W=WitSupSet(I);
+  setring W;
+  ideal J=imap(S,J);
+  ideal I=imap(S,I);
+  list w;
+  number al,ar,ai,ri,jj;
+  poly tj;
+  dd=size(L);
+  for(i=0;i<=dd;i++)
+  {
+   z=size(W(i)[1]);
+   zi=size(W(i));
+   if(z>1)
+   {
+    for(j=1;j<=zi;j++)
+    {
+     w=W(i)[j];
+     for(k=1;k<=size(J);k++)
+     {
+      tj=J[k];
+      for(ii=1;ii<=n;ii++)
+      {
+       tj=subst(tj,var(ii),w[ii]);
+      }
+      al=leadcoef(tj);
+      ar=repart(al);
+      ai=impart(al);
+      ri=ar^2+ai^2;
+      if(ri>0.000000000000001)
+      {
+       jj=-1;
+       k=size(J)+1;
+       j=zi+1;
+       z=0;
+       i=dd+1;
+      }
+      else
+      {
+       jj=1;
+       ri=0;
+      }
+     }
+    }
+   }
+  }
+ }
+ if(ri>0.000000000000001)
+ {
+  jj=0;
+ }
+ else
+ {
+  jj=1;
+ }
+"================================================";
+ "Inclusion:";
+ jj;
+"================================================";
+ export(jj);
+ export(J);
+ export(I);
+   system("sh","rm singular_solutions");
+   system("sh","rm nonsingular_solutions");
+   system("sh","rm real_solutions");
+   system("sh","rm raw_solutions");
+   system("sh","rm raw_data");
+   system("sh","rm output");
+   system("sh","rm midpath_data");
+   system("sh","rm main_data");
+   system("sh","rm input");
+   system("sh","rm failed_paths");
+ setring S;
+ return (W);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r=0,(x,y,z),dp;
+   poly f1=(x2+y2+z2-6)*(x-y)*(x-1);
+   poly f2=(x2+y2+z2-6)*(x-z)*(y-2);
+   poly f3=(x2+y2+z2-6)*(x-y)*(x-z)*(z-3);
+   ideal I=f1,f2,f3;
+   poly g1=(x2+y2+z2-6)*(x-1);
+   poly g2=(x2+y2+z2-6)*(y-2);
+   poly g3=(x2+y2+z2-6)*(z-3);
+   ideal J=g1,g2,g3;
+   def W=Incl(I,J);
+      ==>
+         Inclusion:
+         0
+ def W=Incl(J,I);
+      ==>
+         Inclusion:
+         1
+}
+///////////////////////////////////////////////////////////////////////////////
+proc Equal(ideal I, ideal J)
+"USAGE:  Equal(ideal I, ideal J); I, J ideals
+RETURN:  t=1 if the algebraic variety defined by I equals to the algebraic
+           variety defined by J, otherwise t=0
+EXAMPLE: example Equal; shows an example
+"
+{
+ def S=basering;
+ int n=nvars(basering);
+ def W1=Incl(J,I);
+ setring W1;
+ number j1=jj;
+ execute("ring q=(real,0),("+varstr(S)+"),dp;");
+ ideal I=imap(W1,I);
+ ideal J=imap(W1,J);
+ execute("ring qq=0,("+varstr(S)+"),dp;");
+ ideal I=imap(S,I);
+ ideal J=imap(S,J);
+ def W2=Incl(I,J);
+ setring W2;
+ number j2=jj;
+ number j;
+ number j1=imap(W1,j1);
+ if(j2==1)
+ {
+  if(j1==1)
+  {
+   j=1/1;
+  }
+  else
+  {
+   j=0/1;
+  }
+ }
+ else
+ {
+  j=0/1;
+ }
+"================================================";
+ "Equality:";
+ j;
+"================================================";
+ setring S;
+ return (W2);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r=0,(x,y,z),dp;
+   poly f1=(x2+y2+z2-6)*(x-y)*(x-1);
+   poly f2=(x2+y2+z2-6)*(x-z)*(y-2);
+   poly f3=(x2+y2+z2-6)*(x-y)*(x-z)*(z-3);
+   ideal I=f1,f2,f3;
+   poly g1=(x2+y2+z2-6)*(x-1);
+   poly g2=(x2+y2+z2-6)*(y-2);
+   poly g3=(x2+y2+z2-6)*(z-3);
+   ideal J=g1,g2,g3;
+   def W=Equal(I,J);
+        ==>
+           Equality:
+           0
+
+
+  def W=Equal(J,J);
+        ==>
+           Equality:
+           1
+}
+///////////////////////////////////////////////////////////////////////////////
+proc NumLocalDim(ideal J, list w, int e)
+"USAGE:  NumLocalDim(ideal J, list w, int e); J ideal,
+           w list of an approximate value of a point v in the algebraic variety defined by J,
+               e integer
+RETURN: the local dimension of the algebraic variety defined by J at v
+EXAMPLE: example NumLocalDim; shows an example
+"
+{
+ def S=basering;
+ int n=nvars(basering);
+ int sI=size(J);
+ int i,j,jj,t,tt,sz1,sz2,ii,ph,ci,k;
+ poly p,pp;
+ list rw,iw;
+ for(i=1;i<=sI;i++)
+ {
+  p=J[i];
+  for(j=1;j<=n;j++)
+  {
+   w[j]=w[j]+I*0;
+   rw[j]=repart(w[j]);
+   iw[j]=impart(w[j]);
+   p=subst(p,var(j),w[j]);
+  }
+  pp=pp+p;
+ }
+ number u=leadcoef(pp);
+ if((u^2)==0)
+ {
+  execute("ring A=(real,e-1),("+varstr(S)+",I),ds;");
+  ideal II=imap(S,J);
+  list rw=imap(S,rw);
+  list iw=imap(S,iw);
+  poly p(1..n);
+  for(j=1;j<=n;j++)
+  {
+   p(j)=var(j)+rw[j]+I*iw[j];
+  }
+  map f=A,p(1..n);
+  ideal T=f(II);
+  tt=dim(std(T));
+  t=tt-1;
+ }
+ else
+ {
+  int d=dim(std(J));
+  execute("ring R=(complex,e-1,I),("+varstr(S)+"),ds;");
+  list w=imap(S,w);
+  ideal II=imap(S,J);
+  ideal JJ;
+  poly p, p(1..n);
+  for(i=1;i<=sI;i++)
+  {
+   p=II[i];
+   for(j=1;j<=n;j++)
+   {
+    p=subst(p,var(j),w[j]);
+   }
+   JJ[i]=II[i]-p;
+  }
+  for(j=1;j<=n;j++)
+  {
+   p(j)=var(j)+w[j];
+  }
+  map f=R,p(1..n);
+  ideal T=f(JJ);
+  tt=dim(std(T));
+  if(tt==d)
+  {
+   execute("ring A=(complex,e,I),("+varstr(S)+"),dp;");
+   t=tt;
+  }
+  else
+  {
+   execute("ring RR=(real,e-2),("+varstr(S)+",I),dp;");
+   ideal II=imap(S,J);
+   list rw=imap(S,rw);
+   list iw=imap(S,iw);
+   ideal L,LL,H,HH;
+   poly l(1..d),ll(1..d);
+   int c;
+   for(i=1;i<=d;i++)
+   {
+    for(j=1;j<=n;j++)
+    {
+     c=random(1,100);
+     l(i)=l(i)+c*(var(j));
+     ll(i)=ll(i)+c*(var(j)-rw[j]-I*iw[j]);
+    }
+    l(i)=l(i)+random(101,200);
+    L[i]=l(i);
+    LL[i]=ll(i);
+   }
+   poly pi=I^2+1;
+   H=L,II,pi;
+   ideal JJ;
+   poly p, p(1..n);
+   for(i=1;i<=sI;i++)
+   {
+    p=II[i];
+    for(j=1;j<=n;j++)
+    {
+     p=subst(p,var(j),rw[j]+I*iw[j]);
+    }
+    JJ[i]=II[i]-p;
+   }
+   HH=LL,JJ,pi;
+   if(dim(std(H))==0)
+   {
+    def M=solve(H,100,"nodisplay");
+    setring M;
+    sz1=size(SOL);
+    execute("ring RRRQ=(real,e-1),("+varstr(S)+",I),dp;");
+    ideal HH=imap(RR,HH);
+    if(dim(std(HH))==0)
+    {
+     def MM=solve(HH,100,"nodisplay");
+     setring MM;
+     sz2=size(SOL);
+    }
+   }
+   else
+   {
+    sz1=1;
+   }
+   if(sz1==sz2)
+   {
+    execute("ring A=(complex,e,I),("+varstr(S)+"),dp;");
+    t=d;
+   }
+   else
+   {
+    execute("ring RQ=(real,e-1),("+varstr(S)+"),dp;");
+    ideal II=imap(S,J);
+    def RW=WitSet(II);
+    setring RW;
+    list v;
+    list w=imap(S,w);
+    number nr,ni;
+    if(tt<0)
+    {
+     tt=0;
+    }
+    for(ii=tt;ii<=d;ii++)
+    {
+     list W(ii)=imap(RW,W(ii));
+     if(size(W(ii)[1])>1)
+     {
+      if(ii==0)
+      {
+       for(i=1;i<=size(W(0));i++)
+       {
+        v=W(ii)[i];
+        nr=0;
+        ni=0;
+        for(j=1;j<=n;j++)
+        {
+         nr=nr+(repart(v[j])-repart(w[j]))^2;
+         ni=ni+(impart(v[j])-impart(w[j]))^2;
+        }
+        if((ni+nr)<1/10^(2*e-3))
+        {
+         execute("ring A=(complex,e,I),("+varstr(S)+"),dp;");
+         list W(ii)=imap(RW,W(ii));
+         t=0;
+         i=size(W(ii))+1;
+         ii=d+1;
+        }
+       }
+      }
+      else
+      {
+       def SS=Singular2bertini(W(ii));
+       execute("ring D=(complex,e,I),("+varstr(S)+",s,gamma),dp;");
+       string nonsin;
+       ideal H,L;
+       ideal J=imap(RW,N(0));
+       ideal LL=imap(RW,L);
+       list w=imap(S,w);
+       poly p;
+       for(j=1;j<=ii;j++)
+       {
+        p=0;
+        for(jj=1;jj<=n;jj++)
+        {
+         p=p+random(1,100)*(var(jj)-w[jj]);
+        }
+        L[j]=p;
+       }
+       for(jj=1;jj<=size(J);jj++)
+       {
+        H[jj]=s*gamma*J[jj]+(1-s)*J[jj];
+       }
+       for(jj=1;jj<=ii;jj++)
+       {
+        H[size(J)+jj]=s*gamma*LL[jj]+(1-s)*L[jj];
+       }
+       string sv=varstr(S);
+       def Q(ii)=UseBertini(H,sv);
+       system("sh","rm start");
+       nonsin=read("nonsingular_solutions");
+       if(size(nonsin)>=52)
+       {
+        def T(ii)=bertini2Singular("nonsingular_solutions",nvars(basering)-2);
+        setring T(ii);
+        list C=re;
+        ci=size(C);
+        number tr;
+        list w=imap(S,w);
+        for(jj=1;jj<=ci;jj++)
+        {
+         tr=0;
+         for(k=1;k<=n;k++)
+         {
+          tr=tr+(repart(w[k])-repart(C[jj][k]))^2+(impart(w[k])-impart(C[jj][k]))^2;
+         }
+         if(tr<=1/10^(2*e-3))
+         {
+          execute("ring A=(complex,e,I),("+varstr(S)+"),dp;");
+          t=ii;
+          ii=d+1;
+          jj=ci+1;
+         }
+        }
+       }
+      }
+     }
+    }
+    system("sh","rm singular_solutions");
+    system("sh","rm nonsingular_solutions");
+    system("sh","rm real_solutions");
+    system("sh","rm raw_solutions");
+    system("sh","rm raw_data");
+    system("sh","rm output");
+    system("sh","rm midpath_data");
+    system("sh","rm main_data");
+    system("sh","rm input");
+    system("sh","rm failed_paths");
+   }
+  }
+ }
+ "=============================================";
+ "The Local Dimension:";
+ t;
+ setring S;
+ return(A);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   int e=14;
+   ring r=(complex,e,I),(x,y,z),dp;
+   poly f1=(x2+y2+z2-6)*(x-y)*(x-1);
+   poly f2=(x2+y2+z2-6)*(x-z)*(y-2);
+   poly f3=(x2+y2+z2-6)*(x-y)*(x-z)*(z-3);
+   ideal J=f1,f2,f3;
+   list p0=0.99999999999999+I*0.00000000000001,2,3+I*0.00000000000001;
+   list p2=1,0.99999999999998,2;
+   list p1=5+I,4.999999999999998+I,5+I;
+   def D=NumLocalDim(J,p0,e);
+             ==>
+               The Local Dimension:
+                0
+   def D=NumLocalDim(J,p1,e);
+             ==>
+               The Local Dimension:
+                1
+   def D=NumLocalDim(J,p2,e);
+             ==>
+               The Local Dimension:
+                2
+}
+
+///////////////////////////////////////////////////////////////////////////////
diff --git a/Singular/LIB/numerDecom.lib b/Singular/LIB/numerDecom.lib
new file mode 100644
index 0000000..a130011
--- /dev/null
+++ b/Singular/LIB/numerDecom.lib
@@ -0,0 +1,2223 @@
+//////////////////////////////////////////////////////////////////////////////
+version="version numerDecom.lib 4.0.0.0 Jun_2013 "; // $Id: f3007f2844083adbc4eb701888d0be57954ab5a3 $
+category="Algebraic Geometry";
+info="
+LIBRARY:  NumDecom.lib    Numerical Decomposition of Ideals
+OVERVIEW:
+     The library contains procedures to compute
+      numerical irreducible decomposition, and
+      numerical primary decomposition of an algebraic variety defined by a
+      polynomial system. The use of the library requires to install Bertini
+           (http://www.nd.edu/~sommese/bertini).
+AUTHOR: Shawki AlRashed, rashed at mathematik.uni-kl.de; sh.shawki at yahoo.de
+
+PROCEDURES:
+
+ re2squ(ideal I);               reduction to square system
+
+ UseBertini(ideal H,string sv); use Bertini to compute the solutions of the homotopy function
+
+ Singular2bertini(list L); adopt the list to be a read file in Bertini as a start solution set
+
+ bertini2Singular(string snp, int q); adopt the file of solutions of the homotopy function to be a list in SINGULAR
+
+ ReJunkUseHomo(ideal I, ideal L, list W, list w); remove junk points using the homotopy function
+
+ JuReTopDim(ideal J,list w,int tt, int d); remove junk points that are on top-dimensional component
+
+ JuReZeroDim(ideal J,list w, int d); remove junk points from 0-dimensional component
+
+ WitSupSet(ideal I);                 witness point super set
+
+ WitSet(ideal I);                    witness point set
+
+ NumIrrDecom(ideal I);               numerical irreducible decomposition
+
+ defl(ideal I, int d);               deflation of ideal I
+
+ NumPrimDecom(ideal I, int d);       numerical primary decomposition
+";
+
+
+LIB "solve.lib";
+LIB "matrix.lib";
+
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+proc re2squ(ideal I)
+"USAGE:   re2squ(ideal I);I ideal
+RETURN:   ideal J defined by the polynomial system of the same number of polynomials and unknowns
+EXAMPLE: example re2squ;shows an example
+"
+{
+ def S=basering;
+ int n=nvars(basering);
+ ideal J;
+ poly p;
+ int N=size(I);
+ int i,j;
+ if(n==N)
+ {
+  J=I;
+ }
+ else
+ {
+  if(N<n)
+  {
+   for(i=1;i<=n;i++)
+   {
+    if(i<=N)
+    {
+     J[i]=I[i];
+    }
+    else
+    {
+     J[i]=0;
+    }
+   }
+  }
+  else
+  {
+   for(i=1;i<=n;i++)
+   {
+    p=0;
+    for(j=N-n;j<=N;j++)
+    {
+     p=p+random(1,101)*I[j];
+    }
+    J[i]=I[i]+p;
+   }
+  }
+ }
+ export(J);
+ setring S;
+ return(S);
+ }
+example
+{ "EXAMPLE:";echo = 2;
+   ring r=0,(x,y,z),dp;
+   ideal I= x3+y4,z4+yx,xz+3x,x2y+z;
+   def D=re2squ(I);
+   setring D;
+   J;
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc Singular2bertini(list L)
+"USAGE:   Singular2bertini(list L);L a list
+RETURN:  text file called start
+NOTE:    adopting the list L to be as a start solution of the homptopy function in Bertini
+EXAMPLE: Singular2bertini;shows an example
+"
+{
+ write("start",string(size(L)));
+ int i,j;
+ number a,b;
+ string s;
+ list LLL;
+ for(i=1;i<=size(L);i++)
+ {
+  LLL=L[i];
+  for(j=1;j<=size(LLL);j++)
+  {
+   a=repart(LLL[j]);
+   b=impart(LLL[j]);
+   s=string(a)+" "+string(b)+";";
+  write("start",s);
+  }
+ }
+ return(0);
+}
+example
+{ "EXAMPLE:";echo = 2;
+   ring r=(complex,16,I),(x,y,z),dp;
+   list L=list(1,2,3),list(4,5,6+I*2);
+   def D=Singular2bertini(L);
+}
+///////////////////////////////////////////////////////////////////////////////
+proc UseBertini(ideal H,string sv)
+"USAGE:   UseBertini(ideal H,string sv);
+          H ideal, sv string of the variable of ring
+RETURN:   text file called input used in Bertini to compute the solution of
+          the homotopy function H that existed in file input.text
+NOTE:     Need to define a start solution of H
+EXAMPLE:  example Use;shows an example
+"
+{
+ int ii,j,k, ph;
+ ph=size(H);
+ string sff,sf;
+ link l=":w ./input";
+ write(l,"");
+ write(l,"CONFIG");
+ write(l,"");
+ write(l,"USERHOMOTOPY: 1;");
+ write(l,"");
+ write(l,"END;");
+ write(l,"");
+ write(l,"INPUT");
+ write(l,"");
+ for( ii=1;ii<=size(sv);ii++)
+ {
+  if((sv[ii]=="(")||(sv[ii]==")"))
+  {
+   sv=sv[1,ii-1]+sv[ii+1,size(sv)];
+  }
+ }
+ write(l,"variable "+sv+";");
+  sff="function";
+ if(ph!=1)
+ {
+  for( ii=1;ii<=ph-1;ii++)
+  {
+   sff=sff+" f"+string(ii)+",";
+  }
+  sff=sff+"f"+string(ph)+";";
+ }
+ else
+ {
+  sff=sff+" f"+string(1)+",";
+ }
+ write(l,sff);
+ write(l,"pathvariable t;");
+ write(l,"parameter s;");
+ write(l,"constant gamma;");
+ write(l,"");
+ write(l,"gamma = 0.8 + 1.1*I;");
+ write(l,"");
+ write(l,"s=t;");
+ write(l,"");
+ short=0;
+ for( ii=1;ii<=ph;ii++)
+ {
+   sf=string(H[ii]);
+   k=find(sf,newline);
+  for( j=1;j<=size(sf);j++)
+  {
+   if(sf[j]=="(")
+   {
+    if(sf[j+2]==")")
+    {
+     sf[j]=" ";
+     sf=sf[1,j-1]+sf[j+1,size(sf)];
+     sf[j+1]=" ";
+     sf=sf[1,j]+sf[j+2,size(sf)];
+    }
+   }
+  }
+  write(l,"f"+string(ii)+"="+sf+";");
+ }
+ write(l,"END;");
+ system(("sh","bertini<./input"));
+ return(0);
+}
+example
+{ "EXAMPLE:";echo = 2;
+   ring r=0,(x,y,z),dp;
+   ideal I= x3+y4,z4+yx,xz+3x,x2y+z;
+   string sv=varstr(basering);
+   def A=UseBertini(I,sv);
+}
+///////////////////////////////////////////////////////////////////////////////
+proc bertini2Singular(string snp, int q)
+"USAGE:   bertini2Singular(string snp, int q);
+         snp string, q=nvars(basering) integer
+RETURN:  re list of the solutions of the homotopy function computed by Bertini
+EXAMPLE: example bertini2Singular;shows an example
+"
+{
+ def S=basering;
+ int nn=nvars(basering);
+ int n=q;
+ execute("ring R=(complex,18,I),("+varstr(S)+"),dp;");
+ number r1,r2;
+ list re,ru;
+ string sss=read(snp);
+ sss=sss+"";
+ int i,j,k,m,p;
+ string ss;
+ ss=sss[1];
+ i=2;
+ while(sss[i]!=" ")
+ {
+  ss=ss+sss[i];
+  i++;
+ }
+ execute("m="+ss+";");
+ for(i=1;i<=size(sss);i++)
+ {
+  if(sss[i]=="e")
+  {
+   if(!((sss[i+1]=="+")||(sss[i+1]=="-")))
+   {
+    ss=sss[i+1,size(sss)];
+    sss=sss[1,i];
+    sss=sss+"+"+ss;
+   }
+  }
+ }
+ j=1;
+ j=find(sss,newline,j)+1;
+ while(sss[j]==newline){j++;}
+ for(q=1;q<=m;q++)
+ {
+  for(p=1;p<=n;p++)
+  {
+   k=find(sss,newline,j);
+   ss=sss[j,k-j];
+   i=find (ss," ");
+   execute("r1="+ss[1,i-1]+";");
+   execute("r2="+ss[i+1,size(ss)-i+1]+";");
+   ru[p]=r1+I*r2;
+   j=k+1;
+  }
+  j=j+1;
+  re[size(re)+1]=ru;
+ }
+ export(re);
+ setring S;
+ return(R);
+}
+example
+{ "EXAMPLE:";echo = 2;
+   ring r = 0,(a,b,c),ds;
+   int q=nvars(basering);
+   def T=bertini2Singular("nonsingular_solutions",q);
+   re;
+}
+///////////////////////////////////////////////////////////////////////////////
+proc   WitSupSet(ideal I)
+"USAGE:  WitSupSet(ideal I);I ideal
+RETURN:  list of Witness point Super Sets W(i) for i=1,...,dim(V(I)),
+          L list of generic linear polynomials and N(0) list of a polynomial system of the same number of
+          polynomials and unknowns. // if W(i) = x, then V(I) has no component of dimension i
+EXAMPLE: example WitSupSet;shows an example
+"
+{
+ def S=basering;
+ int n=nvars(basering);
+ ideal II=I;
+ int dd=dim(std(I));
+ if(n==1)
+ {
+   ERROR("n=1");
+ }
+ else
+ {
+  if(dd==0)
+  {
+   execute("ring R=0,("+varstr(S)+"),dp;");
+   int i,j;
+   ideal I=imap(S,I);
+   list V(dd),W(dd);
+   def T(dd+1)=solve(I,"nodisplay");
+   setring T(dd+1);
+   W(dd)=SOL;
+   ideal N(dd)=imap(S,I);
+   export(N(dd));
+   ideal LL;
+   export(LL);
+   int c(0);
+   c(0)=0;
+   export(c(0));
+   export(dd);
+   list w(1..size(W(dd)));
+   for(i=1;i<=size(W(dd));i++)
+   {
+    w(i)=W(dd)[i];
+    export(w(i));
+   }
+  "===========================================";
+  "===========================================";
+   "Dimension";
+    dd;
+   "Number of Components";
+   size(W(dd));
+   setring S;
+   return(T(dd+1));
+  }
+  else
+  {
+   matrix MJJ=jacob(I);
+   int rn=rank(MJJ);
+   I=imap(S,II);
+   def rs=re2squ(I);
+   setring rs;
+   I=J;
+   if((n-rn)!=dd)
+   {
+    execute("ring R=0,("+varstr(S)+",z(1..dd)),dp;");
+    ideal I=imap(rs,I);
+    ideal H(0..n),L,LL,L(1..dd),LL(1..dd),h(1..dd),N(0..dd);
+    poly p,p(0..n),e;
+   int i,j,k,kk,q,qq,t,m,d,jj,rii,c(0),ii;
+   for(i=1;i<=dd;i++)
+   {
+    p=0;
+    for(j=1;j<=n;j++)
+    {
+     p=p+random(1,2*n+7)*var(j);
+    }
+    if(i<dd)
+    {
+     LL[i]=random(2*n+7,4*n+1)+p;
+    }
+    else
+    {
+     c(0)=random(4*n+1,5*n+13);
+     LL[i]=c(0)+p;
+    }
+   }
+   export(c(0));
+   p(0)=0;
+   for(t=1;t<=n;t++)
+   {
+    for(j=1;j<=dd;j++)
+    {
+     p(j)=p(j-1)+random(1,2*n+10)*var(n+j);
+     h(j)[t]=I[t]+p(j);
+    }
+   }
+   for(q=1;q<=dd;q++)
+   {
+    for(i=1;i<=q;i++)
+    {
+     L(q)[i]=LL[i]+var(n+i);
+    }
+   }
+   for(i=1;i<=dd;i++)
+   {
+    N(i)=h(i),L(i);
+   }
+   for(i=1;i<=n;i++)
+   {
+    N(0)[i]=I[i];
+   }
+   ideal JJ=N(0);
+   if(dim(std(N(dd)))!=0)
+   {
+    "Try Again";
+   }
+   else
+   {
+    def T=solve(N(dd),100,"nodisplay");
+    setring T;
+    execute("ring T(dd+1)=(complex,16,I),("+varstr(S)+"),dp;");
+    list M,Y;
+    list W(dd),V(dd);
+    list SOL=imap(T,SOL);
+    Y=SOL;
+    number rp,ip,rip;
+    for( i=1;i<=size(SOL);i++)
+    {
+     M=Y[i];
+     for(j=dd;j>=1;j--)
+     {
+      rp=repart(M[n+j]);
+      ip=impart(M[n+j]);
+      rip=rp^2 + ip^2;
+      if(rip<0.0000000000000001)
+      {
+       M=delete(M,n+j);
+       Y[i]=M;
+      }
+     }
+    }
+    k=1;
+    kk=1;
+    for( i=1;i<=size(Y);i++)
+    {
+     if(size(Y[i])==n)
+     {
+      W(dd)[k]=Y[i];
+      k=k+1;
+     }
+     else
+     {
+      V(dd)[kk]=Y[i];
+      kk=kk+1;
+     }
+    }
+    ideal JJ=imap(S,II);
+    k=1;
+    number al,ar,ai,ri;
+    for(j=1;j<=size(W(dd));j++)
+    {
+     ri=0;
+     al=0;
+     ai=0;
+     ar=0;
+     for(ii=1;ii<=size(JJ);ii++)
+     {
+      for(i=1;i<=n;i++)
+      {
+       JJ[ii]=subst(JJ[ii],var(i),W(dd)[j][i]);
+      }
+      al=leadcoef(JJ[ii]);
+      ar=repart(al);
+      ai=impart(al);
+      ri=ar^2+ai^2+ri;
+     }
+     if(ri<=0.000000000000000001)
+     {
+      W(dd)[k]=W(dd)[j];
+      k=k+1;
+     }
+    }
+    ideal L(dd)=imap(R,L(dd));
+    export(L(dd));
+    export(W(dd));
+    export(V(dd));
+    string sff,sf,sv;
+    int nv(dd)=size(V(dd));
+    int nv(0..dd-1);
+    if(size(W(dd))<size(Y))
+    {
+     def SB(dd)=Singular2bertini(V(dd));
+    }
+    for( q=dd;q>=n-rn+1;q--)
+    {
+     if(nv(q)!=0)
+     {
+      int w(q-1)=0;
+      execute("ring D(q)=(0,s,gamma),("+varstr(S)+",z(1..q)),dp;");
+      string nonsin(q),stnonsin(q);
+      ideal H(1..q);
+      ideal N(q)=imap(R,N(q));
+      ideal N(q-1)=imap(R,N(q-1));
+      for(j=1;j<=n+q-1;j++)
+      {
+       H(q)[j]=s*gamma*N(q)[j]+(1-s)*N(q-1)[j];
+      }
+      H(q)[n+q]=s*gamma*N(q)[n+q]+(1-s)*var(n+q);
+      ideal H=H(q);
+      export(H(q));
+      string sv(q)=varstr(basering);
+      sv=sv(q);
+      def Q(q)=UseBertini(H,sv);
+      system("sh","rm start");
+      nonsin(q)=read("nonsingular_solutions");
+      if(size(nonsin(q))>=52)
+      {
+       def T(q)=bertini2Singular("nonsingular_solutions",nvars(basering));
+       setring T(q);
+       list C=re;
+       list B,X,A,G;
+       for(i=1;i<=size(C);i++)
+       {
+        B=re[i];
+        B=delete(B,n+q);
+        C[i]=B;
+       }
+       X=C;
+       if(q>=2)
+       {
+        for(j=q-1;j>=1;j--)
+        {
+         for(i=1;i<=size(X);i++)
+         {
+          A[i]=X[i];
+          G=A[i];
+          G=delete(G,n+j);
+          A[i]=G;
+         }
+         X=A;
+        }
+       }
+       else
+       {
+        X=C;
+       }
+       list W(q-1),V(q-1);
+       ideal JJ=imap(S,II);
+       k=1;
+       poly tj;
+       number al,ar,ai,ri;
+       for(j=1;j<=size(C);j++)
+       {
+        ri=0;
+        al=0;
+        ai=0;
+        ar=0;
+        for(i=1;i<=size(JJ);i++)
+        {
+         tj=JJ[i];
+         for(i=1;i<=n;i++)
+         {
+          tj=subst(tj,var(i),X[j][i]);
+         }
+         al=leadcoef(tj);
+         ar=repart(al);
+         ai=impart(al);
+         ri=ar^2+ai^2+ri;
+        }
+        if(ri<=0.000000000000000001)
+        {
+          W(q-1)[k]=X[j];
+          k=k+1;
+        }
+        else
+        {
+         nv(q-1)=nv(q-1)+1;
+         V(q-1)[nv(q-1)]=C[j];
+        }
+       }
+       if(nv(q-1)==size(C))
+       {
+        list W(q-1)=var(1);
+       }
+       if(q>=2)
+       {
+        if(nv(q-1)!=0)
+        {
+         def SB(qq-1)=Singular2bertini(V(q-1));
+        }
+        else
+        {
+         for(qq=q-1;qq>=1;qq--)
+         {
+          execute("ring T(qq)=(complex,16,I),("+varstr(S)+",z(1..qq)),dp;");
+          list W(qq-1)=var(1);
+         }
+         q=1;
+        }
+       }
+      }
+      else
+      {
+       for(qq=q;qq>=1;qq--)
+       {
+        int w(qq-1);
+        execute("ring T(qq)=(complex,16,I),("+varstr(S)+",z(1..qq)),dp;");
+        list W(qq-1)=var(1);
+       }
+      }
+     }
+     else
+     {
+      for(qq=q;qq>=1;qq--)
+      {
+       execute("ring T(qq)=(complex,16,I),("+varstr(S)+",z(1..qq)),dp;");
+       list W(qq-1)=var(1);
+      }
+     }
+    }
+    execute("ring D=(complex,16,I),("+varstr(S)+"),dp;");
+    for(i=0;i<=dd;i++)
+    {
+     list W(i)=imap(T(i+1),W(i));
+     export(W(i));
+    }
+     ideal L=imap(R,LL);
+     export(L);
+     ideal N(0)=imap(R,N(0));
+     export(N(0));
+     setring S;
+     return(D);
+    }
+   }
+   else
+   {
+    execute("ring R=0,("+varstr(S)+"),dp;");
+    int i,j,c(0);
+    poly p;
+    ideal LL;
+    for(i=1;i<=dd;i++)
+    {
+     p=0;
+     for(j=1;j<=n;j++)
+     {
+      p=p+random(1,100)*var(j);
+     }
+     if(i<dd)
+     {
+      LL[i]=random(101,200)+p;
+     }
+     else
+     {
+      c(0)=random(201,300);
+      LL[i]=c(0)+p;
+     }
+    }
+    ideal I=imap(S,I);
+    ideal N(dd)=I,LL;
+    def T=solve(N(dd),100,"nodisplay");
+    setring T;
+    list W(0..dd);
+    W(dd)=SOL;
+    export(W(dd));
+    for(i=0;i<=dd-1;i++)
+    {
+     W(i)=var(1);
+     export(W(i));
+    }
+    ideal L=imap(R,LL);
+    export(L);
+    ideal N(0)=imap(S,I);
+    export(N(0));
+    setring S;
+    return(T);
+   }
+  }
+ }
+}
+example
+{ "EXAMPLE:";echo = 2;
+    ring r=0,(x,y,z),dp;
+    poly f1=(x2+y2+z2-6)*(x-y)*(x-1);
+    poly f2=(x2+y2+z2-6)*(x-z)*(y-2);
+    poly f3=(x2+y2+z2-6)*(x-y)*(x-z)*(z-3);
+    ideal I=f1,f2,f3;
+    def W=WitSupSet(I);
+    setring W;
+    W(2);
+        // witness point super set of a pure 2-dimensional component of V(I)
+    W(1);
+        // witness point super set of a pure 1-dimensional component of V(I)
+    W(0);
+        // witness point super set of a pure 0-dimensional component of V(I)
+    L;
+        // list of generic linear polynomials
+}
+///////////////////////////////////////////////////////////////////////////////
+proc ReJunkUseHomo(ideal I, ideal L, list W, list w)
+"USAGE:   ReJunkUseHomo(ideal I, ideal L, list W, list w);
+          I ideal, L list of generic linear polynomials {l_1,...,l_i},
+          W list of a subset of the solution set of the generic slicing V(L) with V(J),
+          w list of a point in V(J)
+RETURN:  t=1 if w on an i-dimensional component of V(I),
+         otherwise t=0. Where i=size(L)
+EXAMPLE: example ReJunkUseHomo;shows an example
+"
+{
+ def S=basering;
+ int n=nvars(basering);
+ int ii,i,in,j,jjj,jj,k,zi,a,kk,kkk;
+ string sf,sff,sv;
+ i=size(W);
+ in=size(w);
+ ideal LL;
+ jjj=size(L);
+ poly pp;
+ for(jj=1;jj<=jjj;jj++)
+ {
+  for(ii=1;ii<=in;ii++)
+  {
+   pp=random(1,3*n+1)*(var(ii)-w[ii])+pp;
+  }
+  LL[jj]=pp;
+ }
+ export(LL);
+ execute("ring R=(complex,16,I),("+varstr(S)+",gamma,s),dp;");
+ ideal L=imap(S,L);
+ ideal LL=imap(S,LL);
+ ideal I=imap(S,I);
+ list w=imap(S,w);
+ zi=size(I);
+ ideal H;
+ for(a=1;a<=zi;a++)
+ {
+  H[a]=s*gamma*I[a]+(1-s)*I[a];
+ }
+ for(kk=1;kk<=jjj;kk++)
+ {
+  H[kk+zi]=s*gamma*L[kk]+(1-s)*LL[kk];
+ }
+ list W=imap(S,W);
+ def SB1=Singular2bertini(W);
+ sv=varstr(S);
+ def Q=UseBertini(H,sv);
+ system("sh","rm start");
+ string nonsin=read("nonsingular_solutions");
+ if(size(nonsin)>=52)
+ {
+  def TT=bertini2Singular("nonsingular_solutions",nvars(basering)-2);
+  setring TT;
+  list w=imap(S,w);
+  list C=re;
+  list ww,v;
+  number rp,ip,rp(1..size(w)),ip(1..size(w)),irp,t;
+  for(k=1;k<=size(C);k++)
+  {
+   ww=re[k];
+   for(jj=1;jj<=size(w);jj++)
+   {
+    rp(jj)=(repart(ww[jj])-repart(w[jj]))^2;
+    ip(jj)=(impart(ww[jj])-impart(w[jj]))^2;
+    rp=rp+rp(jj);
+    ip=ip+ip(jj);
+   }
+   irp=ip+rp;
+   if(irp<=0.000000000000000000000001)
+   {
+    t=1.0;
+   }
+   else
+   {
+    t=0.0;
+   }
+  }
+ }
+ else
+ {
+ execute("ring TT=(complex,16,I),("+varstr(S)+"),dp;");
+ list w=imap(S,w);
+ number t=1.0;
+ }
+ export(t);
+ setring S;
+ return(TT);
+}
+example
+{ "EXAMPLE:";echo = 2;
+    ring r=(complex,16,I),(x,y,z),dp;
+    poly f1=(x2+y2+z2-6)*(x-y)*(x-1);
+    poly f2=(x2+y2+z2-6)*(x-z)*(y-2);
+    poly f3=(x2+y2+z2-6)*(x-y)*(x-z)*(z-3);
+    ideal J=f1,f2,f3;
+    poly l1=15x+16y+6z+17;
+    poly l2=2x+14y+4z+18;
+    ideal L=l1,l2;
+    list W1=list(0.5372775295412116,-0.7105339291010922,-2.2817700129167831+I*0),list(0.09201175741935605,-1.7791717821935455,1.6810953589677311);
+    list w=list(2,2,-131666666/10000000);
+    def D=ReJunkUseHomo(J,L,W1,w);
+    setring D;
+    t;
+}
+///////////////////////////////////////////////////////////////////////////////
+proc JuReTopDim(ideal J,list w,int tt, int d);
+"USAGE:  JuReTopDim(ideal J,list w,int tt, int d);J ideal, w list of a point in V(J),
+         tt the degree of d-dimensional component of V(J), d dimension of V(J)
+RETURN:  t=1 if w on a d-dimensional component of V(I), otherwise t=0.
+EXAMPLE: example JuReTopDim;shows an example
+"
+{
+ def S=basering;
+ int n=nvars(basering);
+ int i,j,k;
+ list iw,rw;
+ for(k=1;k<=n;k++)
+ {
+  rw[k]=repart(w[k]);
+  iw[k]=impart(w[k]);
+ }
+ execute("ring R=real,("+varstr(S)+",I),dp;");
+ list iw=imap(S,iw);
+ list rw=imap(S,rw);
+ ideal J=imap(S,J);
+ execute("ring RR=0,("+varstr(S)+",I),dp;");
+ ideal J=imap(R,J);
+ list iw=imap(R,iw);
+ list rw=imap(R,rw);
+ ideal L;
+ poly p;
+ for(i=1;i<=d;i++)
+ {
+  p=0;
+  for(j=1;j<=n;j++)
+  {
+   p=p+random(1,100)*(var(j)-rw[j]-I*iw[j]);
+  }
+  L[i]=p;
+ }
+ ideal JJ;
+ for(i=1;i<=size(J);i++)
+ {
+  p=J[i];
+  for(j=1;j<=n;j++)
+  {
+   p=subst(p,var(j),rw[j]+I*iw[j]);
+  }
+  JJ[i]=p;
+ }
+ poly pp;
+ pp=I^2 +1;
+ ideal T=L,J,pp;
+ int di=dim(std(T));
+ if(di==0)
+ {
+  def T(d)=solve(T,10,"nodisplay");
+  setring T(d);
+  number t,ie,re,rt;
+  int zi=size(SOL);
+  list iw=imap(S,iw);
+  list rw=imap(S,rw);
+  if(zi==2*tt)
+  {
+   t=1.0/1;
+  }
+  else
+  {
+   t=0.0/1;
+  }
+ }
+ else
+ {
+  execute("ring T(d)=(complex,16,I),("+varstr(S)+"),dp;");
+  "Try Again";
+   -----
+ }
+ export(t);
+ setring S;
+ return(T(d));
+}
+example
+{ "EXAMPLE:";echo = 2;
+    ring r=(complex,16,I),(x,y,z),dp;
+    poly f1=(x2+y2+z2-6)*(x-y)*(x-1);
+    poly f2=(x2+y2+z2-6)*(x-z)*(y-2);
+    poly f3=(x2+y2+z2-6)*(x-y)*(x-z)*(z-3);
+    ideal J=f1,f2,f3;
+    list w=list(0.5372775295412116,-0.7105339291010922,-2.2817700129167831);
+    def D=JuReTopDim(J,w,2,2);
+    setring D;
+    t;
+}
+///////////////////////////////////////////////////////////////////////////////
+proc JuReZeroDim(ideal J,list w, int d);
+"USAGE:  JuReZeroDim(ideal J,list w, int d);J ideal,
+         w list of a point in V(J), d dimension of V(J)
+RETURN:  t=1 if w on a positive-dimensional component of V(I),
+         i.e w is not isolated point in V(J)
+EXAMPLE: example JuReZeroDim;shows an example
+"
+{
+ def S=basering;
+ int n=nvars(basering);
+ int i,j,k;
+ list iw,rw;
+ for(k=1;k<=n;k++)
+ {
+  rw[k]=repart(w[k]);
+  iw[k]=impart(w[k]);
+ }
+ execute("ring R=real,("+varstr(S)+",I),dp;");
+ list iw=imap(S,iw);
+ ideal J=imap(S,J);
+ list rw=imap(S,rw);
+ execute("ring RR=0,("+varstr(S)+",I),dp;");
+ list iw=imap(R,iw);
+ ideal J=imap(R,J);
+ list rw=imap(R,rw);
+ ideal LL;
+ poly p;
+ for(i=1;i<=d;i++)
+ {
+  p=0;
+  for(j=1;j<=n;j++)
+  {
+   p=p+random(1,100)*(var(j)-rw[j]-I*iw[j]);
+  }
+  LL[i]=p;
+ }
+ poly pp;
+ pp=I^2 +1;
+ ideal TT=LL,J,pp;
+ def TT(d)=solve(TT,16,"nodisplay");
+ setring TT(d);
+ int zii=size(SOL);
+ execute("ring RR1=0,("+varstr(S)+",I),dp;");
+ list iw=imap(R,iw);
+ ideal J=imap(R,J);
+ list rw=imap(R,rw);
+ ideal L;
+ poly p;
+ for(i=1;i<=d;i++)
+ {
+  p=0;
+  for(j=1;j<=n;j++)
+  {
+   p=p+random(1,100)*(var(j)-rw[j]-I*iw[j]-1/100000000000000);
+  }
+  L[i]=p;
+ }
+ poly pp;
+ pp=I^2 +1;
+ ideal T=L,J,pp;
+ int di=dim(std(T));
+ if(di==0)
+ {
+  def T(d)=solve(T,16,"nodisplay");
+  setring T(d);
+  number t;
+  int zi=size(SOL);
+  list iw=imap(S,iw);
+  list rw=imap(S,rw);
+  if(zi==zii)
+  {
+   t=1.0/1;
+  }
+  else
+  {
+   t=0.0/1;
+  }
+ }
+ else
+ {
+  execute("ring T(d)=(complex,16,I),("+varstr(S)+"),dp;");
+  "Try Again";
+   -----
+ }
+ export(t);
+ setring S;
+ return(T(d));
+}
+example
+{ "EXAMPLE:";echo = 2;
+    ring r=(complex,16,I),(x,y,z),dp;
+    poly f1=(x2+y2+z2-6)*(x-y)*(x-1);
+    poly f2=(x2+y2+z2-6)*(x-z)*(y-2);
+    poly f3=(x2+y2+z2-6)*(x-y)*(x-z)*(z-3);
+    ideal J=f1,f2,f3;
+    list w1=list(0.5372775295412116,-0.7105339291010922,-2.2817700129167831);
+    def D1=JuReZeroDim(J,w1,2);
+    setring D1;
+    t;
+}
+///////////////////////////////////////////////////////////////////////////////
+proc    WitSet(ideal I)
+"USAGE:   WitSet(ideal I); I ideal
+RETURN:  lists W(0..d) of witness point sets of i-dimensional components
+          of V(J) for i=0,...d respectively, where d the dimension of V(J),
+          L list of generic linear polynomials
+NOTE:    if W(i)=x, then V(J) has no component of dimension i
+EXAMPLE: example WitSet;shows an example
+"
+{
+ def S=basering;
+ int n=nvars(basering);
+ int ii,i,j,b,bb,k,kk,dt;
+ def TJ(0)=WitSupSet(I);
+ setring TJ(0);
+ ideal LL=L;
+ int d=size(LL);
+ if(d==0)
+ {
+  setring S;
+  return(TJ(0));
+ }
+ else
+ {
+  for( i=0;i<=d;i++)
+  {
+   list Ww(i)=W(i);
+   int z(i)=size(W(i));
+   export(Ww(i));
+  }
+  for(i=d-1;i>=0;i--)
+  {
+   list W(i)=imap(TJ(0),Ww(i));
+   if(size(W(i)[1])>1)
+   {
+    for(j=1;j<=z(i);j++)
+    {
+     execute("ring Rr(j+i)=(complex,106,I),("+varstr(S)+"),ds;");
+     list W(i)=imap(TJ(0),Ww(i));
+     list w=W(i)[j];
+     ideal J=imap(TJ(0),N(0));
+     ideal J(j),K(j);
+     for(k=1;k<=size(J);k++)
+     {
+      J(j)[k]=J[k];
+      for(kk=1;kk<=n;kk++)
+      {
+       J(j)[k]=subst(J(j)[k],var(kk),w[kk]);
+      }
+      K(j)[k]=J[k]-J(j)[k];
+     }
+     poly p(1..n);
+     for(k=1;k<=n;k++)
+     {
+      p(k)=var(k)+w[k];
+     }
+     map f(j)=Rr(j+i),p(1..n);
+     ideal JJ=f(j)(K(j));
+     if(dim(std(JJ))>i)
+     {
+      execute("ring A(j)=(complex,16,I),("+varstr(S)+"),dp;");
+      list W(i)=imap(TJ(0),Ww(i));
+      list w(j)=var(1);
+     }
+     else
+     {
+      if(i==0)
+      {
+       execute("ring RR(j)=(complex,16,I),("+varstr(S)+"),dp;");
+       list W(i)=imap(TJ(0),Ww(i));
+       list w=W(i)[j];
+       ideal J=imap(TJ(0),N(0));
+       def AA(j)=JuReZeroDim( J,w,d);
+       setring AA(j);
+       list W(i)=imap(TJ(0),Ww(i));
+       if(t<1)
+       {
+        execute("ring A(j)=(complex,16,I),("+varstr(S)+"),dp;");
+        list W(i)=imap(TJ(0),Ww(i));
+        list w(j)=W(i)[j];
+       }
+       else
+       {
+        execute("ring RRR(j)=(complex,106,I),("+varstr(S)+"),dp;");
+        list W(i)=imap(TJ(0),Ww(i));
+        list w=W(i)[j];
+        ideal J=imap(TJ(0),N(0));
+        def AAA(j)=JuReTopDim( J,w, z(d),d);
+        setring AAA(j);
+        number ts=t;
+        list W(i)=imap(TJ(0),Ww(i));
+        if(ts<1)
+        {
+         dt=d-1;
+        }
+        else
+        {
+         dt=d;
+        }
+        if(dt>i)
+        {
+         for(ii=i+1;ii<=dt;ii++)
+         {
+          execute("ring RRRR(ii+j)=(complex,106,I),("+varstr(S)+"),ds;");
+          list Ww(ii)=imap(TJ(0),Ww(ii));
+          if(size(Ww(ii)[1])>1)
+          {
+           execute("ring RRRRR(ii+j)=(complex,16,I),("+varstr(S)+"),dp;");
+           list W(i)=imap(TJ(0),Ww(i));
+           list w=W(i)[j];
+           list Ww(ii)=imap(TJ(0),Ww(ii));
+           ideal J=imap(TJ(0),N(0));
+           ideal L=imap(TJ(0),LL);
+           ideal L(ii);
+           for(k=1;k<=ii;k++)
+           {
+           L(ii)[k]=L[k];
+           }
+           def AAA(ii+j)=ReJunkUseHomo(J,L(ii),Ww(ii),w);
+           setring AAA(ii+j);
+           number ts=t;
+           list W(i)=imap(TJ(0),Ww(i));
+           if(ts>0)
+           {
+           execute("ring A(j)=(complex,16,I),("+varstr(S)+"),dp;");
+           list W(i)=imap(TJ(0),Ww(i));
+           list w(j)=var(1);
+           ii=d+1;
+           }
+           else
+           {
+            if(ii==dt)
+            {
+             execute("ring A(j)=(complex,16,I),("+varstr(S)+"),dp;");
+             list W(i)=imap(TJ(0),Ww(i));
+            }
+            list w(j)=W(i)[j];
+           }
+          }
+         }
+        }
+        else
+        {
+         execute("ring A(j)=(complex,16,I),("+varstr(S)+"),dp;");
+         list W(i)=imap(TJ(0),Ww(i));
+         list w(j)=W(i)[j];
+        }
+       }
+      }
+      else
+      {
+       execute("ring RRRRRRR(j)=(complex,106,I),("+varstr(S)+"),dp;");
+       list W(i)=imap(TJ(0),Ww(i));
+       list w=W(i)[j];
+       ideal J=imap(TJ(0),N(0));
+       def Aaa(j)=JuReTopDim( J,w,z(d),d);
+       setring Aaa(j);
+       list W(i)=imap(TJ(0),Ww(i));
+       number ts =t;
+       if(ts<1)
+       {
+        dt=d-1;
+       }
+       else
+       {
+        dt=d;
+       }
+       if(dt>i)
+       {
+        for(ii=i+1;ii<=dt;ii++)
+        {
+         execute("ring RRRRRRRR(ii+j)=(complex,106,I),("+varstr(S)+"),ds;");
+         list Ww(ii)=imap(TJ(0),Ww(ii));
+         if(size(Ww(ii)[1])>1)
+         {
+          execute("ring R1(ii+j)=(complex,16,I),("+varstr(S)+"),dp;");
+          list W(i)=imap(TJ(0),Ww(i));
+          list w=W(i)[j];
+          list Ww(ii)=imap(TJ(0),Ww(ii));
+          ideal J=imap(TJ(0),N(0));
+          ideal L=imap(TJ(0),LL);
+          ideal L(ii);
+          for(k=1;k<=ii;k++)
+          {
+           L(ii)[k]=L[k];
+          }
+          def AA(ii+j)=ReJunkUseHomo(J,L(ii),Ww(ii),w);
+          setring AA(ii+j);
+          number ts=t;
+          list W(i)=imap(TJ(0),Ww(i));
+          if(ts>0)
+          {
+           execute("ring A(j)=(complex,16,I),("+varstr(S)+"),dp;");
+           list W(i)=imap(TJ(0),Ww(i));
+           list w(j)=var(1);
+           ii=d+1;
+          }
+          else
+          {
+           if(ii==dt)
+           {
+           execute("ring A(j)=(complex,16,I),("+varstr(S)+"),dp;");
+           list W(i)=imap(TJ(0),Ww(i));
+           }
+           list w(j)=W(i)[j];
+          }
+         }
+        }
+       }
+       else
+       {
+        execute("ring A(j)=(complex,16,I),("+varstr(S)+"),dp;");
+        list W(i)=imap(TJ(0),Ww(i));
+        list w(j)=W(i)[j];
+       }
+      }
+     }
+     if(j==z(i))
+     {
+      execute("ring R(i)=(complex,16,I),("+varstr(S)+"),dp;");
+      list W(i),w;
+      int k(i)=0;
+      for(k=1;k<=z(i);k++)
+      {
+       w=imap(A(k),w(k));
+       if(size(w)>1)
+       {
+        k(i)=k(i)+1;
+        W(i)[k(i)]=w;
+       }
+      }
+      if(k(i)==0)
+      {
+       W(i)=var(1);
+      }
+     }
+    }
+   }
+  }
+  execute("ring T=(complex,16,I),("+varstr(S)+"),dp;");
+  int bt=0;
+  for(i=0;i<=d-1;i++)
+  {
+   list Ww(i)=imap(TJ(0),W(i));
+   if(size(Ww(i)[1])>1)
+   {
+    list W(i)=imap(R(i),W(i));
+   }
+   else
+   {
+    list W(i)=Ww(i);
+   }
+   export(W(i));
+  }
+  list W(d)=imap(TJ(0),W(d));
+  export(W(d));
+  ideal L=imap(TJ(0),LL);
+  export(L);
+  ideal N(0)=imap(TJ(0),N(0));
+  export(N(0));
+  setring S;
+  return(T);
+ }
+}
+example
+{ "EXAMPLE:";echo = 2;
+    ring r=0,(x,y,z),dp;
+    poly f1=(x3+z)*(x2-y);
+    poly f2=(x3+y)*(x2-z);
+    poly f3=(x3+y)*(x3+z)*(z2-y);
+    ideal I=f1,f2,f3;
+    def W=WitSet(I);
+    setring W;
+    W(1);
+         // witness point  set of a pure 1-dimensional component of V(I)
+    W(0);
+         // witness point  set of a pure 0-dimensional component of V(I)
+    L;
+         // list of generic linear polynomials
+}
+///////////////////////////////////////////////////////////////////////////////
+static proc ZSR1(ideal I, ideal L, list W )
+"USAGE:  ZSR1(ideal I, ideal L, list W );I ideal,
+         L ideal defined by generic linear polynomials,
+         W list of a point in the generic slicing of V(I) and V(L)
+RETURN:  ts number;zero sum relation of W
+EXAMPLE: example ZSR1;shows an example
+"
+{
+ def S=basering;
+ int n=nvars(basering);
+ int c(1)=5*n;
+ int c(2)=23*n;
+ int iii=size(L);
+ execute("ring R=(complex,16,I),("+varstr(S)+"),ds;");
+ number c(0);
+ ideal LL=imap(S,L);
+ c(0)=leadcoef(LL[iii]);
+ string sv=varstr(S);
+ int j,ii,jj,k,a,b,te,zi,si;
+ string sf,sff;
+ list VV;
+ list W=imap(S,W);
+ VV[1]=W;
+ def SB1=Singular2bertini(VV);
+ execute("ring R=(complex,16,I),("+varstr(S)+",gamma,s),dp;");
+ ideal I=imap(S,I);
+ zi=size(I);
+ ideal LL=imap(S,L);
+ ideal H, ll;
+ for(a=1;a<=zi;a++)
+ {
+  H[a]=s*gamma*I[a]+(1-s)*I[a];
+ }
+ if(iii>1)
+ {
+  for(k=1;k<=iii-1;k++)
+  {
+   ll[k]=LL[k];
+   H[k+zi]=s*gamma*LL[k]+(1-s)*ll[k];
+  }
+  ll[iii]=LL[iii]+c(1)-c(0);
+  H[iii+zi]=s*gamma*LL[iii]+(1-s)*ll[iii];
+ }
+ else
+ {
+  ll[iii]=LL[iii]+c(1)-c(0);
+   H[iii+zi]=s*gamma*LL[iii]+(1-s)*ll[iii];
+ }
+ def Q(1)=UseBertini(H,sv);
+ string siaa=read("singular_solutions");
+ string saa=read("nonsingular_solutions");
+ def TT(1)=bertini2Singular("nonsingular_solutions",nvars(basering)-2);
+ setring TT(1);
+ list wr=re;
+ if(size(wr)==0)
+ {
+  execute("ring TT(2)=(complex,16,I),("+varstr(S)+"),dp;");
+  number tte, ts;
+  tte=11;
+  ts=0;
+  export(ts);
+  export(tte);
+ }
+ else
+ {
+  execute("ring R1=(complex,16,I),("+varstr(S)+",gamma,s),dp;");
+  ideal I=imap(S,I);
+  si=size(I);
+  ideal LL=imap(S,L);
+  ideal H, ll;
+  for(a=1;a<=si;a++)
+  {
+   H[a]=s*gamma*I[a]+(1-s)*I[a];
+  }
+  if(iii>1)
+  {
+   for(k=1;k<=iii-1;k++)
+   {
+    ll[k]=LL[k];
+    H[k+si]=s*gamma*LL[k]+(1-s)*ll[k];
+   }
+   ll[iii]=LL[iii]+c(2)-c(0);
+   H[iii+si]=s*gamma*LL[iii]+(1-s)*ll[iii];
+  }
+  else
+  {
+   ll[iii]=LL[iii]+c(2)-c(0);
+   H[iii+si]=s*gamma*LL[iii]+(1-s)*ll[iii];
+  }
+  def Q(2)=UseBertini(H,sv);
+  string saaa=read("nonsingular_solutions");
+  string siaaa=read("singular_solutions");
+  if(size(saaa)<52)
+  {
+   if(size(siaaa)<52)
+   {
+    "ERROR( Try again try);";
+   }
+  }
+  if(size(saaa)>=52)
+  {
+   def TT(2)=bertini2Singular("nonsingular_solutions",nvars(basering)-2);
+   setring TT(2);
+   list wwr=re;
+   list wr=imap(TT(1),wr);
+   list W=imap(S,W);
+   list w,ww,www;
+   number s(0),s(1),s(2),ts;
+   zi=size(W)/n;
+   for(jj=1;jj<=zi;jj++)
+   {
+    s(0)=0;
+    s(1)=0;
+    s(2)=0;
+    w=W;
+    ww=wr[jj];
+    www=wwr[jj];
+    for(j=1;j<=n;j++)
+    {
+     s(0)=s(0)+j*w[j];
+    }
+    for(j=1;j<=n;j++)
+    {
+     s(1)=s(1)+j*ww[j];
+    }
+    for(j=1;j<=n;j++)
+    {
+     s(2)=s(2)+j*www[j];
+    }
+   }
+   ts=s(0)*(c(1)-c(2))+s(1)*(c(2)-c(0))+s(2)*(c(0)-c(1));
+  }
+  else
+  {
+   def TT(2)=bertini2Singular("singular_solutions",nvars(basering)-2);
+   setring TT(2);
+   list wwr=re;
+   list wr=imap(TT(1),wr);
+   list W=imap(S,W);
+   list w,ww,www;
+   number s(0),s(1),s(2),ts;
+   zi=size(W)/n;
+   for(jj=1;jj<=zi;jj++)
+   {
+    s(0)=0;
+    s(1)=0;
+    s(2)=0;
+    w=W;
+    ww=wr[jj];
+    www=wwr[jj];
+    for(j=1;j<=n;j++)
+    {
+     s(0)=s(0)+j*w[j];
+    }
+    for(j=1;j<=n;j++)
+    {
+     s(1)=s(1)+j*ww[j];
+    }
+    for(j=1;j<=n;j++)
+    {
+     s(2)=s(2)+j*www[j];
+    }
+   }
+   ts=s(0)*(c(1)-c(2))+s(1)*(c(2)-c(0))+s(2)*(c(0)-c(1));
+  }
+ }
+ execute("ring e=(complex,16,I),("+varstr(S)+"),dp;");
+ number ts=imap(TT(2),ts);
+ export(ts);
+ number tte;
+ tte=11;
+ export(tte);
+ system("sh","rm start");
+ setring S;
+ return (e);
+}
+example
+{ "EXAMPLE:";echo = 2;
+    ring r=(complex,16,I),(x,y,z),dp;
+    poly f1=(x2+y2+z2-6)*(x-y)*(x-1);
+    poly f2=(x2+y2+z2-6)*(x-z)*(y-2);
+    poly f3=(x2+y2+z2-6)*(x-y)*(x-z)*(z-3);
+    ideal J=f1,f2,f3;
+    ideal L=2*x+7*y+3*z+29;
+    list W=2,1.999999999999999,-15.6666666666664;
+    def D=ZSR1(J,L,W );
+    setring D;
+    ts;
+}
+///////////////////////////////////////////////////////////////////////////////
+static proc perSumZ(list A)
+"USAGE:  perSumZ(list A);A list of different complex numbers
+RETURN:  all subsets of A, whose sum of their elements is zero
+EXAMPLE: example perSumZ;shows an example
+"
+{
+ list B, C;
+ int i, j;
+ number t,tr;
+ if(size(A)==0)
+ {
+  B[1]=A;
+ }
+ if(size(A)==1)
+ {
+  if(((repart(A[1]))^2+(impart(A[1]))^2)<=0.000000000000001)
+  {
+   B[1]=A;
+  }
+ }
+ for(i=1;i<=size(A);i++)
+ {
+  t=t+A[i];
+ }
+ if(((repart(t))^2+(impart(t))^2)<=0.000000000000001)
+ {
+  B[1]=A;
+ }
+ for(i=1;i<=size(A);i++)
+ {
+  C=delete(A,i);
+  C=perSumZ(C);
+  for(j=1;j<=size(C);j++)
+  {
+   if(size(C[j])>0)
+   {
+    B[size(B)+1]=C[j];
+   }
+  }
+ }
+ return(B);
+}
+example
+{ "EXAMPLE:";echo = 2;
+   ring r=(complex,16,I),x,lp;
+   list A=1,-1,2-I,I,-2;
+   def D=perSumZ(A);
+   D;
+}
+///////////////////////////////////////////////////////////////////////////////
+static proc  ZSROFWitSet(ideal I)
+"USAGE:  ZSROFWitSet(ideal I);I ideal
+RETURN:  ZSR(i) lists of the zero sum relation of witness point
+          sets W(i) for i=1,...dim(V(I))
+EXAMPLE: example ZSROFWitSet;shows an example
+"
+{
+ def S=basering;
+ int n=nvars(basering);
+ def T(0)=WitSet(I);
+ setring T(0);
+ ideal LL=L;
+ int dd=size(LL);
+ int a=c(0);
+ if(a==0)
+ {
+  return(T(0));
+ }
+ else
+ {
+  int i,j,ii,jj,k,sv(0..dd),j(0..dd),kk;
+  string sv;
+  for(i=1;i<=dd;i++)
+  {
+   jj=0;
+   list V(i)=imap(T(0),W(i));
+   if(size(V(i)[1])>1)
+   {
+    if(size(V(i))==1)
+    {
+     execute("ring L(i)(1)=(complex,16,I),("+varstr(S)+"),dp;");
+     list W(i),ZSR(i);
+     list V(i)=imap(T(0),W(i));
+     W(i)=V(i);
+     ZSR(i)[1]=0.000;
+    }
+    else
+    {
+     if(i>1)
+     {
+      execute("ring ee(i)=(complex,16,I),("+varstr(S)+"),dp;");
+      list V(i)=imap(T(0),W(i));
+     }
+     sv(i)=size(V(i));
+     for(j=1;j<=sv(i);j++)
+     {
+      ideal N=imap(T(0),N(0));
+      ideal LLL=imap(T(0),LL);
+      ideal L;
+      for(kk=1;kk<=i;kk++)
+      {
+       L[kk]=LLL[kk];
+      }
+      def L(i)(j)=ZSR1(N,L,V(i)[j]);
+      setring L(i)(j);
+      if(j==1)
+      {
+       list W(i),ZSR(i);
+      }
+      else
+      {
+       list W(i)=imap(L(i)(j-1),W(i));
+       list ZSR(i)=imap(L(i)(j-1),ZSR(i));
+       export(ZSR(i));
+      }
+      list V(i)=imap(T(0),W(i));
+      jj=jj+1;
+      ZSR(i)[jj]=ts;
+      W(i)[jj]=V(i)[j];
+     }
+    }
+   }
+  }
+  execute("ring Q=(complex,12,I),("+varstr(S)+"),dp;");
+  list W(0)=imap(T(0),W(0));
+  export(W(0));
+  for(jj=1;jj<=dd;jj++)
+  {
+   number pt(jj);
+   list V(jj)=imap(T(0),W(jj));
+   if(size(V(jj)[1])>1)
+   {
+    sv(jj)=size(V(jj));
+    if(jj>0)
+    {
+     list ZSR(jj)=imap(L(jj)(sv(jj)),ZSR(jj));
+     export(ZSR(jj));
+     list W(jj)=imap(L(jj)(sv(jj)),W(jj));
+     export(W(jj));
+    }
+   }
+   else
+   {
+    list ZSR(jj)=var(1);
+    export(ZSR(jj));
+    list W(jj)=var(1);
+    export(W(jj));
+    }
+   }
+   ideal L=imap(T(0),LL);
+   export(L);
+   export(dd);
+   system("sh","rm singular_solutions");
+   system("sh","rm nonsingular_solutions");
+   system("sh","rm real_solutions");
+   system("sh","rm raw_solutions");
+   system("sh","rm raw_data");
+   system("sh","rm output");
+   system("sh","rm midpath_data");
+   system("sh","rm main_data");
+   system("sh","rm input");
+   system("sh","rm failed_paths");
+   setring S;
+   return(Q);
+  }
+}
+example
+{ "EXAMPLE:";echo = 2;
+    ring  r = 0,(x,y,z),dp;
+    poly f1=(x2+y2+z2-6)*(x-y)*(x-1);
+    poly f2=(x2+y2+z2-6)*(x-z)*(y-2);
+    poly f3=(x2+y2+z2-6)*(x-y)*(x-z)*(z-3);
+    ideal J=f1,f2,f3;
+    def D=ZSROFWitSet(J);
+    setring D;
+    ZSR(1);
+    W(1);
+    ZSR(2);
+    W(2);
+}
+///////////////////////////////////////////////////////////////////////////////
+static proc ReWitZSR(list A, list W, int di)
+"USAGE:  ReWitZSR(list A, list W, int di);A ideal of complex numbers,
+          W list of points on di-dimensional component,
+         di integer
+RETURN:  tw(di) integer, list Z(size(Z));
+        if tw(di)>0, else Z(0), list Z1(tw1(di))
+EXAMPLE: example ReWitZSR;shows an example
+"
+{
+ def S=basering;
+ execute("ring e=(complex,16,I),("+varstr(S)+"),dp;");
+ list A=imap(S,A);
+ list W=imap(S,W);
+ list  D, B(1..size(A)),C(1..size(A)),D(1..size(A)),Z1(1..size(A)),Z(1..size(A)),Z,Y,ZY;
+ int i,j,k,tw(di),tw1(di),tw2(di),tw3(di),tr,tc;
+ list AA;
+ list WW;
+ for(i=1;i<=size(A);i++)
+ {
+  if(((repart(A[i]))^2+(impart(A[i]))^2)<=0.0000000000000001)
+  {
+   tc=tc+1;
+   tw1(di)=tw1(di)+1;
+   ZY[i]=A[i];
+   Z1(tw1(di))=W[i];
+   export(Z1(tw1(di)));
+  }
+  else
+  {
+   tr=tr+1;
+   tw2(di)=tw2(di)+1;
+   AA[tr]=A[i];
+   WW[tr]=W[i];
+  }
+ }
+ A=AA;
+ W=WW;
+ if(size(A)>0)
+ {
+  def B=perSumZ(A);
+  for(i=1;i<=size(A);i++)
+  {
+   tc=0;
+   B(i)=A[i];
+   for(j=1;j<=size(B);j++)
+   {
+    tr=0;
+    for(k=1;k<=size(B[j]);k++)
+    {
+     if(B(i)[1]==B[j][k])
+     {
+      tr=tr+1;
+     }
+    }
+    if(tr>0)
+    {
+     tc=tc+1;
+     C(i)[tc]=B[j];
+    }
+   }
+   for(j=1;j<=size(C(i));j++)
+   {
+    D(i)=C(i)[j];
+    for(k=1;k<=size(C(i));k++)
+    {
+     if(size(D(i))<size(C(i)[k]))
+     {
+      D(i)=D(i);
+     }
+     else
+     {
+      D(i)=C(i)[k];
+     }
+    }
+   }
+  }
+  for(i=1;i<=size(A);i++)
+  {
+   Z[i]=D(i);
+  }
+  for(i=1;i<=size(Z);i++)
+  {
+   if(size(Z[i])>0)
+   {
+    D=Z[i];
+    for(k=size(Z);k>0;k--)
+    {
+     if(size(Z[k])>0)
+     {
+      B=Z[k];
+      if(i!=k)
+      {
+       if(D[1]==B[1])
+       {
+        Z=delete(Z,k);
+       }
+      }
+     }
+    }
+   }
+  }
+  for(j=1;j<=size(Z);j++)
+  {
+    tr=0;
+    D=Z[j];
+    for(i=1;i<=size(A);i++)
+    {
+     for(k=1;k<=size(D);k++)
+     {
+      if(A[i]==D[k])
+      {
+       tr=tr+1;
+       tw(di)=tw(di)+1;
+       Z(j)[tr]=W[i];
+      }
+     }
+    }
+    export(Z(j));
+  }
+ export(Z);
+ }
+ if(tw1(di)==0)
+ {
+  list Z1(0);
+  Z1(0)="Empty set";
+  export(Z1(0));
+ }
+ if(tw(di)==0)
+ {
+  list Z(0);
+  Z(0)="Empty set";
+  export(Z(0));
+ }
+ export(tw1(di));
+ export(tw(di));
+  setring S;
+  return (e);
+}
+example
+{ "EXAMPLE:";echo = 2;
+    ring r=(complex,16,I),(x,y,z),dp;
+    list A= 3.7794571034732007+I*21.1724850800421247,
+           -3.7794571034752664-I*21.1724850800419908;
+    list W=list(-2.0738016397747976,1.29520655909919,-0.1476032795495952),
+           list(-1.354769788796631,-1.5809208448134761,1.2904604224067381);
+    int di=1;
+    def D=ReWitZSR(A,W,di);
+    setring D;
+    tw(di);
+    Z(size(Z));// if tw(di)>0, else Z(0);
+    Z1(tw1(di));
+}
+///////////////////////////////////////////////////////////////////////////////
+proc NumIrrDecom(ideal I) Numerical Irreducible Decomposition
+"USAGE:  NumIrrDecom(ideal I);I ideal
+RETURN:  w(1),..., w(t) lists of irreducible witness point sets of
+         irreducible components of V(J)
+EXAMPLE: example NumIrrDecom;shows an example
+"
+{
+ def S=basering;
+ int i,ii;
+ def WW=ZSROFWitSet(I);
+ setring WW;
+ if(c(0)==0)
+ {
+  setring S;
+  return(WW);
+ }
+ else
+ {
+  int d=size(L);
+  for(i=0;i<=d;i++)
+  {
+   int co(i)=0;
+   if(i==0)
+   {
+    execute("ring q(i)=(complex,16,I),("+varstr(S)+"),dp;");
+    list V(i)=imap(WW,W(i));
+    list W(0..size(V(i)));
+    if(size(V(i)[1])>1)
+    {
+     co(i)=size(V(i));
+     for(ii=1;ii<=size(V(i));ii++)
+     {
+      list w(ii)=V(i)[ii];
+      export(w(ii));
+     }
+    }
+    else
+    {
+     W(1)[1]="Empty Set";
+    }
+   }
+   else
+   {
+    list WW(i);
+    list V(i)=imap(WW,W(i));
+    list a(i)=imap(WW,ZSR(i));
+    if(size(V(i)[1])>1)
+    {
+     def q(i)=ReWitZSR(a(i),V(i),i);
+     setring q(i);
+     if(tw1(i)>0)
+     {
+      for(ii=1;ii<=tw1(i);ii++)
+      {
+       WW(i)[ii]=Z1(ii);
+      }
+      co(i)=tw1(i);
+     }
+     if(tw(i)>0)
+     {
+      for(ii=1;ii<=size(Z);ii++)
+      {
+       if(size(Z[ii])>1)
+       {
+        co(i)=co(i)+1;
+        WW(i)[ii+tw1(i)]=Z(ii);
+       }
+      }
+     }
+     for(ii=1;ii<=size(WW(i));ii++)
+     {
+      list w(ii);
+      w(ii)=WW(i)[ii];
+     }
+    }
+    else
+    {
+     execute("ring q(i)=(complex,16,I),("+varstr(S)+"),dp;");
+     WW(i)[1]="Empty Set";
+    }
+   }
+  }
+  for(i=0;i<=d;i++)
+  {
+   execute("ring qq(i)=(complex,16,I),("+varstr(S)+"),dp;");
+   for(ii=1;ii<=co(i);ii++)
+   {
+    list w(ii)=imap(q(i),w(ii));
+    export w(ii);
+   }
+  "===========================================";
+  "===========================================";
+   "Dimension";
+    i;
+   "Number of Components";
+    co(i);
+   number cco(i)=co(i)/1;
+   export(cco(i));
+  }
+  ideal L=imap(WW,L);
+  export(L);
+  "The generic Linear Space L";
+  L;
+  return(qq(0..d));
+ }
+}
+example
+{ "EXAMPLE:";echo = 2;
+    ring r=0,(x,y,z),dp;
+    poly f1=(x2+y2+z2-6)*(x-y)*(x-1);
+    poly f2=(x2+y2+z2-6)*(x-z)*(y-2);
+    poly f3=(x2+y2+z2-6)*(x-y)*(x-z)*(z-3);
+    ideal I=f1,f2,f3;
+    list W=NumIrrDecom(I);
+      ==>
+         Dimension
+         0
+         Number of Components
+         1
+         Dimension
+         1
+         Number of Components
+         3
+         Dimension
+         2
+         Number of Components
+         1
+    def A(0)=W[1];
+       // corresponding 0-dimensional components
+    setring A(0);
+    w(1);
+        // corresponding 0-dimensional irreducible component
+         ==> 0-Witness point set (one point)
+    def A(1)=W[2];
+           // corresponding 1-dimensional components
+    setring A(1);
+    w(1);
+         // corresponding 1-dimensional irreducible component
+         ==> 1-Witness point set (one point)
+    w(2);
+       // corresponding 1-dimensional irreducible component
+         ==> 1-Witness point set (one point)
+    w(3);
+      // corresponding 1-dimensional irreducible component
+        ==> 1-Witness point set (one point)
+    def A(2)=W[3];
+    // corresponding 2-dimensional components
+    setring A(2);
+    w(1);
+      // corresponding 2-dimensional irreducible component
+        ==> 1-Witness point set (two points)
+}
+///////////////////////////////////////////////////////////////////////////////
+proc defl(ideal I, int d)
+"USAGE:   defl(ideal I, int d);  I ideal, int d order of the deflation
+RETURN:   deflation ideal DI of I
+EXAMPLE:  example defl; shows an example
+"
+{
+ def S=basering;
+ int n=nvars(basering);
+ int i,j;
+ for(i=1;i<=d;i++)
+ {
+  def R(i)=symmetricBasis(n,i,"x");
+  setring R(i);
+  ideal J(i)=symBasis;
+  export(J(i));
+ }
+ execute("ring RR=0,(x(1..n),"+varstr(S)+"),dp;");
+ for(i=1;i<=d;i++)
+ {
+  ideal J(i)=imap(R(i),J(i));
+  for(j=1;j<=n;j++)
+  {
+   J(i)=subst(J(i),x(j),var(n+j));
+  }
+ }
+ execute("ring R=0,("+varstr(S)+"),dp;");
+ ideal I=imap(S,I);
+ if(d>1)
+ {
+  for(i=1;i<=d-1;i++)
+  {
+   ideal J(i)=imap(RR,J(i));
+   for(j=1;j<=size(I);j++)
+   {
+    ideal I(j);
+    for(k=1;k<=size(J(i));k++)
+    {
+     I(j)[k]=J(i)[k]*I[j];
+    }
+     export(I(j));
+   }
+  }
+  ideal J(d)=imap(RR,J(d));
+  ideal D(d)=J(1..d);
+  ideal II(d)=I,I(1..size(I));
+  matrix T(d)=diff(D(d),II(d));
+  matrix TT(d)=transpose(T(d));
+  export(TT(d));
+ }
+ else
+ {
+  ideal J(d)=imap(RR,J(d));
+  ideal D(d)=J(d);
+  ideal II(d)=I;
+  matrix T(d)=diff(D(d),II(d));
+  matrix TT(d)=transpose(T(d));
+  export(TT(d));
+ }
+ int zc=size(D(d));
+ export(zc);
+ execute("ring DR=0,("+varstr(S)+",x(1..zc)),dp;");
+ matrix TT(d)=imap(R,TT(d));
+ ideal I=imap(S,I);
+ vector v=[x(1..zc)];
+ ideal DI=I,TT(d)*v;
+ export(DI);
+ export(I);
+ setring S;
+ return(DR);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r=0,(x,y,z),dp;
+   poly f1=z^2;
+   poly f2=z*(x^2+y);
+   ideal I=f1,f2;
+   def D=defl(I,1);
+   setring D;
+   DI;
+}
+///////////////////////////////////////////////////////////////////////////////
+static proc     NIDofDI(ideal I)
+"USAGE:  NIDofDI(ideal I);  I ideal
+RETURN:  numerical irreducible decomposition of I
+EXAMPLE: NIDofDI; shows an example
+"
+{
+ def S=basering;
+ int i,ii;
+ def WW=ZSROFWitSet(I);
+ setring WW;
+ if(c(0)==0)
+ {
+  setring S;
+  return(WW);
+ }
+ else
+ {
+  int d=size(L);
+  for(i=0;i<=d;i++)
+  {
+   int co(i)=0;
+   if(i==0)
+   {
+    execute("ring q(i)=(complex,16,I),("+varstr(S)+"),dp;");
+    list V(i)=imap(WW,W(i));
+    list W(0..size(V(i)));
+    if(size(V(i)[1])>1)
+    {
+     co(i)=size(V(i));
+     for(ii=1;ii<=size(V(i));ii++)
+     {
+      list w(ii)=V(i)[ii];
+      export(w(ii));
+     }
+    }
+    else
+    {
+     W(1)[1]="Empty Set";
+    }
+   }
+   else
+   {
+    list WW(i);
+    list V(i)=imap(WW,W(i));
+    list a(i)=imap(WW,ZSR(i));
+    if(size(V(i)[1])>1)
+    {
+     def q(i)=ReWitZSR(a(i),V(i),i);
+     setring q(i);
+     if(tw1(i)>0)
+     {
+      for(ii=1;ii<=tw1(i);ii++)
+      {
+       WW(i)[ii]=Z1(ii);
+      }
+      co(i)=tw1(i);
+     }
+     if(tw(i)>0)
+     {
+      for(ii=1;ii<=size(Z);ii++)
+      {
+       if(size(Z[ii])>1)
+       {
+        co(i)=co(i)+1;
+        WW(i)[ii+tw1(i)]=Z(ii);
+       }
+      }
+     }
+     for(ii=1;ii<=size(WW(i));ii++)
+     {
+      list w(ii);
+      w(ii)=WW(i)[ii];
+     }
+    }
+    else
+    {
+     execute("ring q(i)=(complex,16,I),("+varstr(S)+"),dp;");
+     WW(i)[1]="Empty Set";
+    }
+   }
+  }
+  for(i=0;i<=d;i++)
+  {
+   execute("ring qq(i)=(complex,16,I),("+varstr(S)+"),dp;");
+   list ww(i);
+   if(co(i)>0)
+   {
+    for(ii=1;ii<=co(i);ii++)
+    {
+     list v(ii)=imap(q(i),w(ii));
+     ww(i)=v(ii)[1];
+     if(size(ww(i))==1)
+     {
+      list w(ii);
+      w(ii)[1]=v(ii);
+     }
+     else
+     {
+      list w(ii)=v(ii);
+     }
+     export(w(ii));
+    }
+   }
+   else
+   {
+    list w(1);
+    w(1)[1]=var(1);
+    export(w(1));
+   }
+   number cco(i)=co(i)/1;
+   export(cco(i));
+  }
+  ideal L=imap(WW,L);
+  export(L);
+  return(qq(0..d));
+ }
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r=0,(x,y,z),dp;
+   poly f1=z^2;
+   poly f2=z*(x^2+y);
+   ideal I=f1,f2;
+   list DD=NIDofDI(I);
+   def D(0)=DD[1];
+   setring D(0);
+   w(1);          // w(1)= x, i.e. no components
+   def D(1)=DD[2];
+   setring D(1);
+   w(1);
+   def D(2)=DD[3];
+   setring D(2);
+   w(1);
+}
+///////////////////////////////////////////////////////////////////////////////
+proc NumPrimDecom(ideal I,int d)
+"USAGE:   NumPrimDecom(ideal I,int d);  I ideal, d order of the deflation
+RETURN:   lists of the numerical primary decomposition
+EXAMPLE:  example NumPrimDecom; shows an example
+"
+{
+ def S=basering;
+ int n=nvars(basering);
+ int i,Dd,j,k,jj;
+ def D=defl(I,d);
+ setring D;
+ ideal J=DI;
+ Dd=dim(std(DI));
+ list W=NIDofDI(J);
+ for(i=0;i<=Dd;i++)
+ {
+  def A(i+1)=W[i+1];
+  setring A(i+1);
+  if(cco(i)>0)
+  {
+   for(j=1;j<=cco(i);j++)
+   {
+    list W(j)=w(j);
+    for(k=1;k<=size(w(j));k++)
+    {
+     for(jj=size(W(j)[k]);jj>=n+1;jj--)
+     {
+      W(j)[k]=delete(W(j)[k],jj);
+     }
+     W(j)[k]=W(j)[k];
+    }
+   }
+  }
+  else
+  {
+   list W(1)=var(1);
+  }
+ }
+ execute("ring R=(complex,16,I),("+varstr(S)+"),dp;");
+ jj=0;
+ for(i=0;i<=Dd;i++)
+ {
+  number cco(i)=imap(A(i+1),cco(i));
+  if(cco(i)>0)
+  {
+   for(j=1;j<=cco(i);j++)
+   {
+    jj=jj+1;
+    list w(jj)=imap(A(i+1),W(j));
+    export(w(jj));
+  "===========================================";
+  "===========================================";
+    "Numerical Primary Component";
+     w(jj);
+   }
+  }
+ }
+ return(R);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r=0,(x,y),dp;
+   poly f1=yx;
+   poly f2=x2;
+   ideal I=f1,f2;
+   def W=NumPrimDecom(I,1);
+   setring W;
+   w(1);
+      ==> 1-Witness point set (one point)
+   w(2);
+      ==> 1-Witness point set (one point)
+}
+///////////////////////////////////////////////////////////////////////////////
diff --git a/Singular/LIB/orbitparam.lib b/Singular/LIB/orbitparam.lib
new file mode 100644
index 0000000..3ff5939
--- /dev/null
+++ b/Singular/LIB/orbitparam.lib
@@ -0,0 +1,351 @@
+//////////////////////////////////////////////////////////////////////////////
+version="version orbitparam.lib 4.0.0.0 Jun_2013 "; // $Id: 2a70b849edce334cdbd91fa607309aed542e1023 $
+category="Algebraic Geometry";
+info="
+LIBRARY:  orbitparam.lib   Parametrizing orbits of unipotent actions
+
+AUTHORS:  J. Boehm, boehm at mathematik.uni-kl.de @*
+          S. Papadakis, papadak at math.ist.utl.pt @*
+
+OVERVIEW:
+
+This library implements the theorem of Chevalley-Rosenlicht as stated in Theorem 3.1.4 of [Corwin, Greenleaf].
+Given a set of strictly upper triangular n x n matrices L_1,...,L_c which generate
+a Lie algebra as a vector space, and a vector v of size n, the
+function @code{parametrizeOrbit} constructs a parametrization of the orbit of v under
+the action of exp(<L_1,...,L_c>).
+
+To compute exp of the Lie algebra elements corresponding
+to the parameters we require that the characteristic of the base field is zero or larger than n.
+
+By determining the parameters from bottom to top
+this allows you to find an element in the orbit with (at least) as many zeros as the dimension of the
+orbit.
+
+Note: Theorem 3.1.4 of [Corwin, Greenleaf] uses strictly lower triangular matrices.
+
+REFERENCES:
+
+Laurence Corwin, Frederick P. Greenleaf: Representations of Nilpotent Lie Groups and their Applications: Volume 1, Part 1, Basic Theory and Examples, Cambridge University Press (2004).
+
+PROCEDURES:
+
+tangentGens(list,matrix);         Returns elements in the Lie algebra, which form a basis of the tangent space of the parametrization.
+matrixExp(matrix);                Matrix exp for nilpotent matrices.
+matrixLog(matrix);                Matrix log for unipotent matrices.
+parametrizeOrbit(list,matrix);    Returns parametrization of the orbit.
+maxZeros(list,matrix);            Determine an element in the orbit with the maximum number of zeroes.
+
+KEYWORDS: nilpotent Lie algebras; unipotent groups; orbit; parametrization; Chevalley-Rosenlicht theorem
+";
+
+LIB "general.lib";
+LIB "matrix.lib";
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////////
+proc tangentGens(list L, matrix v)
+"USAGE:  tangentGens(L,v); L list, v matrix.
+ASSUME:  L is a list of strictly upper triangular n x n matrices of same size.
+         The vector space <L> genererated by the elements of L should be closed
+         under the Lie bracket.
+
+         v is matrix of constants of size n x 1.
+
+RETURN:  list, with four entries
+@*       - first entry is the dimension of the orbit of under the action of exp(<L>)
+@*       - second entry is a list generators of the tangent space of the orbit of v at v
+           under the action of exp(<L>). If the characteristic p of the ground field is positive, then n has to be smaller than p. The generators are elements of <L>.
+@*       - third entry is the list of matrices with the coefficient to obtain the generators
+           as a linear combination of the elements of L
+@*       - fourth entry is list of integers with entries in v which can be made zero by the
+           action of exp(<L>)
+
+THEORY:  We apply the theorem of Chevalley-Rosenlicht.
+
+KEYWORDS: Lie algebra; orbit; Chevalley-Rosenlicht theorem
+
+EXAMPLE: example tangentGens; shows an example
+
+"
+{
+list T;
+list M;
+int i;
+int s;
+int t;
+list Z;
+int d=size(L);
+int n=nrows(v);
+  if (d<1){ERROR("expected nonempty list of generators");}
+  if (n<>nrows(L[1])){ERROR("vector should be same dimension as size of matrix");}
+  matrix A= L[1]*v;
+  for ( i=2; i <= d; i++ )
+  {
+    A=concat(A,L[i]*v);
+  }
+  matrix B;
+  for ( i=n-1; i >=1; i=i-1 )
+  {
+    B=submat(A,i..n,1..d);
+    matrix E[n-i+1][1];
+    E[1,1]=1;
+    list LU=ludecomp(B);
+    list Q=lusolve(LU[1],LU[2],LU[3],E);
+    if (Q[1]<>0){
+       s++;
+       T[s]=Q[2];
+       matrix C = Q[2][1,1]*L[1];
+       for ( t=2; t <= d; t++ )
+       {
+          C=C+Q[2][t,1]*L[t];
+       }
+       M[s]=C;
+       Z[s]=i;
+       kill C;
+    }
+    kill E,LU,Q;
+  }
+return(list(s,M,T,Z));
+}
+
+example
+{ "EXAMPLE:";
+  ring R = 0,(x),dp;
+  matrix L1[3][3] = 0,1,0, 0,0,0, 0,0,0;
+  matrix L2[3][3] = 0,0,1, 0,0,0, 0,0,0;
+  matrix L3[3][3] = 0,1,1, 0,0,1, 0,0,0;
+  list L = L1,L2,L3;
+  matrix v[3][1] = 1,2,3;
+  tangentGens(L,v);
+}
+
+
+proc matrixExp(matrix A)
+"USAGE:  matrixExp(A); A matrix.
+ASSUME:  A is a nilpotent n x n matrix.
+         If the characteristic p of the ground field is positive, then n has to be
+         smaller than p.
+
+RETURN:  matrix, exp(A)
+
+THEORY:  We compute the power series, which terminates since A is nilpotent.
+
+KEYWORDS: Exp for matrices
+
+EXAMPLE: example matrixExp; shows an example
+
+"
+{
+int i;
+int n = nrows(A);
+if (n<>ncols(A)){
+   ERROR("expected square matrix");
+}
+matrix Z[n][n];
+matrix B[n][n];
+B=B+1;
+matrix D[n][n];
+D=D+1;
+number j=1;
+for (i=1; i <= n; i++ )
+  {
+      j=j*i;
+      D=D*A;
+      if (D==Z){break;}
+      B=B+(1/j)*D;
+  }
+return(B);}
+example
+{ "EXAMPLE:";
+  ring R = 0,(x),dp;
+  matrix A[4][4] = 0,0,1,0, 0,0,1,0, 0,0,0,0;
+  matrixExp(A);
+}
+
+
+proc matrixLog(matrix A)
+"USAGE:  matrixLog(A); A matrix.
+ASSUME:  A-E is a nilpotent n x n matrix.
+         If the characteristic p of the ground field is positive, then n has to be
+         smaller than p.
+
+RETURN:  matrix, log(A)
+
+THEORY:  We compute the power series, which terminates since A-E is nilpotent.
+
+KEYWORDS: Log for matrices
+
+EXAMPLE: example matrixLog; shows an example
+
+"
+{
+int i;
+int n = nrows(A);
+if (n<>ncols(A)){
+   ERROR("expected square matrix");
+}
+matrix Z[n][n];
+matrix B[n][n];
+matrix D[n][n];
+matrix N[n][n]= A-1;
+D=D+1;
+number j;
+for (i=1; i <= n; i++ )
+  {
+      j=j+1;
+      D=D*N;
+      if (D==Z){break;}
+      B=B+(1/j)*(-1)^(i+1)*D;
+  }
+return(B);}
+example
+{ "EXAMPLE:";
+  ring R = 0,(s,t),dp;
+  matrix A[3][3] = 1,s,st/2, 0,1,t, 0,0,1;
+  matrixLog(A);
+}
+
+
+
+proc parametrizeOrbit(list L, matrix v)
+"USAGE:  parametrizeOrbit(L,v); L list, v matrix.
+ASSUME:  L is a list of strictly upper triangular n x n matrices of same size.
+         The vector space <L> genererated by the elements of L should be closed
+         under the Lie bracket.
+@*       v is matrix of constants of size n x 1.
+@*       The basering has at least size(L) variables. However we will only use
+         tangentGens(L,v)[1] many of them.
+
+RETURN:  list, with four entries
+@*       - int, dimension of the orbit
+@*       - matrix A over the basering giving a parametrization of the orbit of v under the action of exp(<L>).
+@*       - list of integers, with the (row)-indices of entries which can be deleted by the action
+@*       - the variables of the parametrization to solve for
+
+THEORY:  We apply the theorem of Chevalley-Rosenlicht. First we determine tangent space generators,
+         then apply @code{matrixExp} to the generators, and finally take the product
+         to obtain the parametrization.
+
+KEYWORDS: Lie group; orbit; parametrization
+
+EXAMPLE: example parametrizeOrbit; shows an example
+"
+{
+list T = tangentGens(L,v);
+list T2 = T[2];
+int i;
+int d=size(L);
+list vL;
+if (nvars(basering)<d)
+{
+   ERROR("expected basering with at least generators many variables");
+}
+for (i=1; i <= size(T2); i++ )
+  {
+    v = matrixExp(T2[size(T2)-i+1]*var(size(T2)-i+1))*v;
+    vL[i]=var(i);
+  }
+return(list(T[1],v,T[4],vL));
+}
+
+example
+{ "EXAMPLE:";
+  ring R = 0,(t(1..3)),dp;
+  matrix L1[3][3] = 0,1,0, 0,0,0, 0,0,0;
+  matrix L2[3][3] = 0,0,1, 0,0,0, 0,0,0;
+  matrix L3[3][3] = 0,1,1, 0,0,1, 0,0,0;
+  list L = L1,L2,L3;
+  matrix v[3][1] = 1,2,3;
+  parametrizeOrbit(L,v);
+
+  ring R1 = 0,(t(1..2)),dp;
+  matrix L1[4][4] = 0,1,0,0, 0,0,0,0, 0,0,0,1, 0,0,0,0;
+  matrix L2[4][4] = 0,0,1,0, 0,0,0,1, 0,0,0,0, 0,0,0,0;
+  list L = L1,L2;
+  matrix v[4][1] = 1,2,3,4;
+  parametrizeOrbit(L,v);
+}
+
+
+proc maxZeros(list L, matrix v)
+"USAGE:  maxZeros(L,v); L list, v matrix.
+ASSUME:  L is a list of strictly upper triangular n x n matrices of same size.
+         The vector space <L> genererated by the elements of L should be closed
+         under the Lie bracket.
+
+         v is matrix of constants of size n x 1.
+
+         The basering has at least size(L) variables. However we will only use
+         tangentGens(L,v)[1] many of them.
+
+RETURN:  matrix of constants over the basering giving an element in the orbit of v
+         under the action of exp(<L>)  with (at least) as many zeros as the dimension of the
+         orbit.
+
+THEORY:  We apply @code{parametrizeOrbit} to obtain a parametrization of the orbit
+         according to the theorem of Chevalley-Rosenlicht. By determining the parameters from bottom to top
+         we find an element in the orbit with (at least) as many zeros as the dimension of the
+         orbit.
+
+KEYWORDS: Lie group; orbit; maximum number of zeroes
+
+EXAMPLE: example parametrizeOrbit; shows an example
+"
+{
+  int d = size(L);
+  def Roriginal = basering;
+  list rl = ringlist(Roriginal);
+  int k;
+  for(k = 1; k <= d; k++)
+     {
+        rl[2][k] = "x("+string(k)+")";
+     }
+  rl[3]= list(list("dp",1:(d)),list("C",0));
+  def R = ring(rl);
+  setring R;
+  list L = fetch(Roriginal,L);
+  matrix v = fetch(Roriginal,v);
+  list P = parametrizeOrbit(L,v);
+  matrix p = P[2];
+  int n = P[1];
+  list idx = P[3];
+  list va = P[4];
+  poly equ,rhs;
+  number de;
+  list parval;
+  for(k = 1; k <= n; k++)
+     {
+        equ = p[idx[k],1];
+        rhs=-number(subst(equ,va[k],0));
+        de = number(diff (equ, va[k]));
+        parval[k] = rhs/de;
+        p = subst(p,va[k],rhs/de);
+     }
+  setring(Roriginal);
+  matrix p=fetch(R,p);
+  return(p);
+}
+
+example
+{ "EXAMPLE:";
+  ring R = 0,(x),dp;
+  matrix L1[3][3] = 0,1,0, 0,0,0, 0,0,0;
+  matrix L2[3][3] = 0,0,1, 0,0,0, 0,0,0;
+  matrix L3[3][3] = 0,1,1, 0,0,1, 0,0,0;
+  list L = L1,L2,L3;
+  matrix v[3][1] = 1,2,3;
+  maxZeros(L,v);
+
+  ring R1 = 0,(x),dp;
+  matrix L1[4][4] = 0,1,0,0, 0,0,0,0, 0,0,0,1, 0,0,0,0;
+  matrix L2[4][4] = 0,0,1,0, 0,0,0,1, 0,0,0,0, 0,0,0,0;
+  list L = L1,L2;
+  matrix v[4][1] = 1,2,3,4;
+  maxZeros(L,v);
+}
+
+
diff --git a/Singular/LIB/parallel.lib b/Singular/LIB/parallel.lib
new file mode 100644
index 0000000..cd695d1
--- /dev/null
+++ b/Singular/LIB/parallel.lib
@@ -0,0 +1,305 @@
+////////////////////////////////////////////////////////////////////
+version="version parallel.lib 4.0.0.0 Dec_2013 "; // $Id: 5dda47e865ae9dc5c26dc51a2711f0e768fb1523 $
+category="General purpose";
+info="
+LIBRARY:   parallel.lib  An abstraction layer for parallel skeletons
+
+AUTHOR:    Andreas Steenpass, e-mail: steenpass at mathematik.uni-kl.de
+
+OVERVIEW:
+This library provides implementations of several parallel 'skeletons' (i.e.
+ways in which parallel tasks rely upon and interact with each other). It is
+based on the library tasks.lib and aims at both ordinary Singular users as well
+as authors of Singular libraries.
+
+KEYWORDS:  parallelization; parallel skeletons; distributed computing
+
+SEE ALSO:  resources_lib, tasks_lib, modstd_lib, modnormal_lib
+
+PROCEDURES:
+  parallelWaitN();      execute several jobs in parallel
+                        and wait for N of them to finish
+  parallelWaitFirst();  execute several jobs in parallel
+                        and wait for the first to finish
+  parallelWaitAll();    execute several jobs in parallel
+                        and wait for all of them to finish
+  parallelTestAND();    run several tests in parallel
+                        and determine if they all succeed
+  parallelTestOR();     run several tests in parallel
+                        and determine if any of them succeeds
+";
+
+LIB "tasks.lib";
+
+proc parallelWaitN(alias list commands, alias list args, int N, list #)
+"USAGE:   parallelWaitN(commands, arguments, N[, timeout]); commands list,
+          arguments list, N int, timeout int
+RETURN:   a list, containing the results of commands[i] applied to
+          arguments[i], i = 1, ..., size(arguments).
+       @* The procedure waits for N jobs to finish.
+       @* An optional timeout in ms can be provided. Default is 0 which
+          disables the timeout.
+NOTE:     The entries of the list commands must be strings. The entries of the
+          list arguments must be lists.
+       @* The type of any entry of the returned list whose corresponding task
+          did not finish (due to timeout or error) is \"none\".
+       @* The returned list may contain more than N results if several jobs
+          finished \"at the same time\". It may contain less than N results in
+          the case of timeout or errors occurring.
+SEE ALSO: parallelWaitAll, parallelWaitFirst, tasks_lib
+EXAMPLE:  example parallelWaitN; shows an example"
+{
+    // auxiliary variables
+    int i;
+
+    // read optional parameters
+    int timeout;
+    int ncores;   // obsolete, but kept for compatibility with old libraries
+    if (size(#) > 0) {
+        if (typeof(#[1]) != "int") {
+            ERROR("wrong optional parameters");
+        }
+        timeout = #[1];
+        if (size(#) > 1) {
+            if (size(#) > 2 || typeof(#[2]) != "int") {
+                ERROR("wrong optional parameters");
+            }
+            ncores = #[2];
+        }
+    }
+
+    // apply wrapper for obsolete optional parameter ncores
+    if (ncores) {
+        list semaphore_save = Resources::setcores_subtree(ncores);
+    }
+
+    // error checking
+    int njobs = size(commands);
+    if (njobs != size(args)) {
+        ERROR("The number of commands does not match the number of lists"
+            +newline+"of arguments.");
+    }
+    if (njobs == 0) {
+        ERROR("no commands specified");
+    }
+    for (i = 1; i <= njobs; i++) {
+        if (typeof(commands[i]) != "string") {
+            ERROR("The first argument is not a list of strings.");
+        }
+        if (typeof(args[i]) != "list") {
+            ERROR("The second argument is not a list of lists.");
+        }
+    }
+
+    // compute the tasks
+    for (i = 1; i <= njobs; i++) {
+        task t(i) = commands[i], args[i];
+    }
+    startTasks(t(1..njobs));
+    list indices = waitTasks(list(t(1..njobs)), N, timeout);
+
+    // wrap back to saved semaphore
+    if (ncores) {
+        Resources::resetcores_subtree(semaphore_save);
+    }
+
+    // return results
+    list results;
+    for (i = size(indices); i > 0; i--) {
+        results[indices[i]] = getResult(t(indices[i]));
+    }
+    for (i = 1; i <= njobs; i++) {
+        killTask(t(i));
+    }
+    return(results);
+}
+example
+{
+    "EXAMPLE:";
+    echo = 2;
+    ring R = 0, (x,y,z), lp;
+    ideal I = 3x3y+x3+xy3+y2z2, 2x3z-xy-xz3-y4-z2, 2x2yz-2xy2+xz2-y4;
+    ideal J = x10+x9y2, x2y7-y8;
+    list commands = list("std", "std");
+    list arguments = list(list(I), list(J));
+    parallelWaitN(commands, arguments, 1);
+}
+
+proc parallelWaitFirst(alias list commands, alias list args, list #)
+"USAGE:   parallelWaitFirst(commands, args[, timeout]); commands list,
+          arguments list, timeout int
+RETURN:   a list, containing at least one (if no timeout occurs) of the results
+          of commands[i] applied to arguments[i], i = 1, ..., size(arguments).
+       @* The command @code{parallelWaitFirst(commands, arguments[, timeout])}
+          is synonymous to
+          @code{parallelWaitN(commands, arguments, 1[, timeout])}. See
+          @ref{parallelWaitN} for details on optional arguments and other
+          remarks.
+SEE ALSO: parallelWaitN, parallelWaitAll, tasks_lib
+EXAMPLE:  example parallelWaitFirst; shows an example"
+{
+    return(parallelWaitN(commands, args, 1, #));
+}
+example
+{
+    "EXAMPLE:";
+    echo = 2;
+    ring R = 0, (x,y,z), lp;
+    ideal I = 3x3y+x3+xy3+y2z2, 2x3z-xy-xz3-y4-z2, 2x2yz-2xy2+xz2-y4;
+    ideal J = x10+x9y2, x2y7-y8;
+    list commands = list("std", "std");
+    list arguments = list(list(I), list(J));
+    parallelWaitFirst(commands, arguments);
+}
+
+proc parallelWaitAll(def commands, alias list args, list #)
+"USAGE:   parallelWaitAll(commands, arguments[, timeout]); commands list or
+          string, arguments list, timeout int
+RETURN:   a list, containing the results of commands[i] applied to
+          arguments[i], i = 1, ..., size(arguments).
+       @* The command @code{parallelWaitAll(commands, arguments[, timeout])} is
+          synonymous to @code{parallelWaitN(commands, arguments,
+          size(arguments)[, timeout])}. See @ref{parallelWaitN} for details on
+          optional arguments and other remarks.
+NOTE:     As a shortcut, @code{commands} can be a string. This is synonymous to
+          providing a list of @code{size(arguments)} copies of this string.
+SEE ALSO: parallelWaitFirst, parallelWaitN, tasks_lib
+EXAMPLE:  example parallelWaitAll; shows an example"
+{
+    if (typeof(commands) != "list" && typeof(commands) != "string") {
+        ERROR("invalid type of first argument");
+    }
+    if (typeof(commands) == "list") {
+        return(parallelWaitN(commands, args, size(args), #));
+    }
+    else {
+        list cmds;
+        for (int i = size(args); i > 0; i--) {
+            cmds[i] = commands;
+        }
+        return(parallelWaitN(cmds, args, size(args), #));
+    }
+}
+example
+{
+    "EXAMPLE:";
+    echo = 2;
+    ring R = 0, (x,y,z), dp;
+    ideal I1 = z8+z6+4z5+4z3+4z2+4, -z2+y;
+    ideal I2 = x9y2+x10, x2y7-y8;
+    ideal I3 = x3-2xy, x2y-2y2+x;
+    string command = "std";
+    list arguments = list(list(I1), list(I2), list(I3));
+    parallelWaitAll(command, arguments);
+}
+
+proc parallelTestAND(def commands, alias list args, list #)
+"USAGE:   parallelTestAND(commands, arguments[, timeout]); commands list or
+          string, arguments list, timeout int
+RETURN:   1, if commands[i] applied to arguments[i] is not equal to zero for
+          all i = 1, ..., size(arguments);
+          0, otherwise.
+       @* An optional timeout in ms can be provided. Default is 0 which
+          disables the timeout. In case of timeout, -1 is returned.
+NOTE:     The entries of the list commands must be strings. The entries of the
+          list arguments must be lists.
+       @* commands[i] applied to arguments[i] must evaluate to an integer for
+          i = 1, ..., size(arguments).
+       @* As a shortcut, @code{commands} can be a string. This is synonymous to
+          providing a list of @code{size(arguments)} copies of this string.
+SEE ALSO: parallelTestOR, tasks_lib
+EXAMPLE:  example parallelTestAND; shows an example"
+{
+    // note: this can be improved
+    list results = parallelWaitAll(commands, args, #);
+    int i;
+    for (i = size(args); i > 0; i--) {
+        if (typeof(results[i]) != "int" && typeof(results[i]) != "none") {
+            ERROR("result no. "+string(i)+" not of type int");
+        }
+    }
+    for (i = size(args); i > 0; i--) {
+        if (typeof(results[i]) == "none") {   // timeout
+            return(-1);
+        }
+    }
+    for (i = size(results); i > 0; i--) {
+        if (!results[i]) {
+            return(0);
+        }
+    }
+    return(1);
+}
+example
+{
+    "EXAMPLE:";
+    echo = 2;
+    ring R = 0, (x,y,z), dp;
+    ideal I = x, y, z;
+    intvec v = 0:3;
+    list l = list(I, v);
+    module m1 = x*gen(1);
+    module m2;
+    string command = "size";
+    list arguments1 = list(list(I), list(v), list(l), list(m1));
+    list arguments2 = list(list(I), list(v), list(l), list(m2));
+    // test if all the arguments have non-zero size
+    parallelTestAND(command, arguments1);
+    parallelTestAND(command, arguments2);
+}
+
+proc parallelTestOR(def commands, alias list args, list #)
+"USAGE:   parallelTestOR(commands, arguments[, timeout]); commands list or
+          string, arguments list, timeout int
+RETURN:   1, if commands[i] applied to arguments[i] is not equal to zero for
+          any i = 1, ..., size(arguments);
+          0, otherwise.
+       @* An optional timeout in ms can be provided. Default is 0 which
+          disables the timeout. In case of timeout, -1 is returned.
+NOTE:     The entries of the list commands must be strings. The entries of the
+          list arguments must be lists.
+       @* commands[i] applied to arguments[i] must evaluate to an integer for
+          i = 1, ..., size(arguments).
+       @* As a shortcut, @code{commands} can be a string. This is synonymous to
+          providing a list of @code{size(arguments)} copies of this string.
+SEE ALSO: parallelTestAND, tasks_lib
+EXAMPLE:  example parallelTestAND; shows an example"
+{
+    // note: this can be improved
+    list results = parallelWaitAll(commands, args, #);
+    int i;
+    for (i = size(args); i > 0; i--) {
+        if (typeof(results[i]) != "int" && typeof(results[i]) != "none") {
+            ERROR("result no. "+string(i)+" not of type int");
+        }
+    }
+    for (i = size(args); i > 0; i--) {
+        if (typeof(results[i]) == "none") {   // timeout
+            return(-1);
+        }
+    }
+    for (i = size(results); i > 0; i--) {
+        if (results[i]) {
+            return(1);
+        }
+    }
+    return(0);
+}
+example
+{
+    "EXAMPLE:";
+    echo = 2;
+    ring R = 0, (x,y,z), dp;
+    ideal I;
+    string s;
+    list l;
+    module m1 = x*gen(1);
+    module m2;
+    string command = "size";
+    list arguments1 = list(list(I), list(s), list(l), list(m1));
+    list arguments2 = list(list(I), list(s), list(l), list(m2));
+    // test if any of the arguments has non-zero size
+    parallelTestOR(command, arguments1);
+    parallelTestOR(command, arguments2);
+}
+
diff --git a/Singular/LIB/paraplanecurves.lib b/Singular/LIB/paraplanecurves.lib
new file mode 100644
index 0000000..dcb1051
--- /dev/null
+++ b/Singular/LIB/paraplanecurves.lib
@@ -0,0 +1,3070 @@
+//////////////////////////////////////////////////////////////////////////////
+version="version paraplanecurves.lib 4.0.0.0 Jun_2014 "; // $Id: 3d364f9861657f46bbded7d3c97914c549b7531a $
+category="Algebraic Geometry";
+info="
+LIBRARY:  paraplanecurves.lib Rational parametrization of rational plane curves
+
+AUTHORS:  J. Boehm, j.boehm at mx.uni-saarland.de @*
+          W. Decker, decker at mathematik.uni-kl.de> @*
+          S. Laplagne, slaplagn at dm.uba.ar @*
+          F. Seelisch, seelisch at mathematik.uni-kl.de
+
+OVERVIEW:
+
+Suppose C = {f(x,y,z)=0} is a rational plane curve, where f is homogeneous
+of degree n with coefficients in Q and absolutely irreducible (these
+conditions are checked automatically.) @*
+After a first step, realized by a projective automorphism in the procedure
+adjointIdeal, C satisfies: @*
+- C does not have singularities at infinity z=0. @*
+- C does not contain the point (0:1:0) (that is, the dehomogenization of f
+  with respect to z is monic as a polynomial in y). @*
+Considering C in the chart z<>0, the algorithm regards x as transcendental
+and y as algebraic and computes an integral basis in C(x)[y] of the integral
+closure of C[x] in C(x,y) using the  normalization algorithm from
+ at ref{normal_lib}: see @ref{integralbasis_lib}. In a future edition of the
+library, also van Hoeij's algorithm for computing the integral basis will
+be available. @*
+From the integral basis, the adjoint ideal is obtained by linear algebra.
+Alternatively, the algorithm starts with a local analysis of the singular
+locus of C. Then, for each  primary component of the singular locus which
+does not correspond to ordinary multiple points or cusps, the integral
+basis algorithm is applied separately. The ordinary multiple points and
+cusps, in turn, are addressed by a straightforward direct algorithm. The
+adjoint ideal is obtained by intersecting all ideals obtained locally.
+The local variant of the algorithm is used by default. @*
+The linear system corresponding to the adjoint ideal maps the curve
+birationally to a rational normal curve in P^(n-2). @*
+Iterating the anticanonical map, the algorithm projects the rational normal
+curve to PP1 for n odd resp. to a conic C2 in PP2 for n even. @*
+In case n is even, the algorithm tests whether there is a rational point on
+C2 and if so gives a parametrization of C2 which is defined over Q. Otherwise,
+the parametrization given is defined over a quadratic field extension of Q. @*
+By inverting the birational map of C to PP1 resp. to C2, a parametrization
+of C is obtained (defined over Q or the quadratic field extension).
+
+REFERENCES:
+
+Janko Boehm: Parametrisierung rationaler Kurven, Diploma Thesis,
+http://www.math.uni-sb.de/ag/schreyer/jb/diplom%20janko%20boehm.pdf
+
+Theo de Jong: An algorithm for computing the integral closure,
+Journal of Symbolic Computation 26 (3) (1998), p. 273-277
+
+Gert-Martin Greuel, Santiago Laplagne, Frank Seelisch: Normalization of Rings,
+Journal of Symbolic Computation 9 (2010), p. 887-901
+
+Mark van Hoeij: An Algorithm for Computing an Integral Basis in an Algebraic
+Function Field, Journal of Symbolic Computation 18 (1994), p. 353-363,
+http://www.math.fsu.edu/~hoeij/papers/comments/jsc1994.html
+
+KEYWORDS:
+Curves; Parametrization; Rational curves; Adjoint ideal; Geometric genus
+
+
+PROCEDURES:
+
+adjointIdeal(poly, [...]);        Adjoint ideal of a plane curve
+invertBirMap(ideal,ideal);        Invert a birational map of algebraic
+                                  varieties
+paraPlaneCurve(poly, [...]);      Compute a rational parametrization of a
+                                  rational plane curve
+rncAntiCanonicalMap(ideal);       Anticanonical map of a rational normal curve
+rationalPointConic(poly);         Finds a point on the conic. This point has
+                                  either coefficients in Q or in a quadratic
+                                  extension field of Q
+mapToRatNormCurve(poly,ideal);    Map a plane rational curve to a rational
+                                  normal curve (RNC)
+rncItProjOdd(ideal);              Map a RNC via successive anticanonical maps
+                                  to PP1
+rncItProjEven(ideal);             Map a RNC via successive anticanonical maps
+                                  to a conic in PP2
+paraConic(poly);                  Compute a rational parametrization of a conic
+testParametrization(poly,ring);   Checks whether a given curve is parametrized
+                                  by a given rational map (defined in the
+                                  given ring)
+testPointConic(poly,ring);        Checks whether a given point (defined in the
+                                  given ring) lies on the given conic.
+";
+
+LIB "elim.lib";
+LIB "general.lib";
+LIB "primdec.lib";
+LIB "absfact.lib";
+LIB "matrix.lib";
+LIB "random.lib";
+LIB "homolog.lib";
+LIB "integralbasis.lib";
+LIB "normal.lib";
+
+
+///////////////////////////////////////////////////////////////////////////////
+proc invertBirMap(ideal phi, ideal I)
+"USAGE: invertBirMap(phi, I); phi ideal, I ideal
+ASSUME: The ideal phi in the basering R represents a birational map of the
+        variety given by the ideal I in R to its image in projective space
+        P = PP^(size(phi)-1).
+NOTE:   The procedure might fail or give a wrong output if phi does
+        not define a birational map.
+RETURN: ring, the coordinate ring of P, with an ideal named J and an ideal
+        named psi.@*
+        The ideal J defines the image of phi.@*
+        The ideal psi gives the inverse of phi.@*
+        Note that the entries of psi should be considered as representatives
+        of classes in the quotient ring R/J.@*
+THEORY: We compute the ideal I(G) in R**S of the graph G of phi.@*
+        The ideal J is given by the intersection of I(G) with S.@*
+        The map psi is given by a relation mod J of those relations
+        in I(G) which are linear in the variables of R.@*
+KEYWORDS: birational map, image, inverse.
+EXAMPLE: example invertBirMap; shows an example
+"
+{
+   def Roriginal = basering;
+   int n = nvars(Roriginal);
+   int m = size(phi);
+   /*phi: P^(n-1) --> P^(m-1)*/
+   list rl = ringlist(Roriginal);
+   int k;
+   for(k = 1; k <= n; k++)
+     {
+        rl[2][k] = "x("+string(k)+")";
+     }
+   for(k = 1; k <= m; k++)
+     {
+        rl[2][k+n] = "y("+string(k)+")";
+     }
+   rl[3]= list(list("dp",1:(n+m)),list("C",0));
+   /*Use Hilbert driven Buchberger*/
+   def Rbig0 = ring(rl);
+   setring Rbig0;
+   ideal I = fetch(Roriginal,I);
+   ideal phi = fetch(Roriginal,phi);
+   ideal mi = maxideal(1);
+   ideal xv = mi[1..n];
+   ideal yv  = mi[n+1..n+m];
+   matrix HM[2][m] = concat(transpose(yv),transpose(phi));
+   ideal graph = sat(I+minor(HM,2),phi)[1];
+   graph = sat(graph,xv)[1];
+   intvec Hgraph = hilb(graph,1);
+   setring Roriginal;
+   rl[3]= list(list("dp",1:n),list("dp",1:m),list("C",0));
+   def Rbig = ring(rl);
+   setring Rbig;
+   ideal graph = imap(Rbig0,graph);
+   graph = std(graph,Hgraph);
+   ideal xv = imap(Rbig0,xv);
+   /*The ideal J defines the image of phi*/
+   ideal J = graph;
+   for(k = 1; k <= n; k++)
+     {
+        J = subst(J,xv[k],0);
+     }
+   J = compress(J);
+   /*now we start inverting phi to psi*/
+   matrix relpsi = diff(xv,graph);
+   for(k = 1; k <= n; k++)
+     {
+        relpsi = subst(relpsi,xv[k],0);
+     }
+    relpsi = compress(relpsi);
+    list rl = ringlist(Rbig);
+    list rl2 = rl[2];
+    rl[2] = list(rl2[n+1..n+m]);
+    rl[3]= list(list("dp",1:m),list("C",0));
+    def Rtarget = ring(rl);
+    setring Rtarget;
+    ideal J = imap(Rbig,J);
+    qring RtargetmodJ = std(J);
+    matrix relpsi = imap(Rbig,relpsi);
+    relpsi = syz(transpose(relpsi));
+    ideal psi = submat(relpsi,1..nrows(relpsi),1);
+    setring Rtarget;
+    ideal psi = imap(RtargetmodJ,psi);
+    export(J,psi);
+    int p = printlevel - voice + 3;
+    dbprint(p,"// 'invertBirMap' created a ring together with two ideals J and psi.");
+    dbprint(p,"// Supposing you typed, say,  def RPn = invertBirMap(phi,I);");
+    dbprint(p,"// you may access the ideals by typing");
+    dbprint(p,"//      setring RPn; J; psi;");
+    return(Rtarget);
+ }
+
+example
+{ "EXAMPLE:"; echo=2;
+  ring R = 0,(x,y,z),dp;
+  poly f = y^8-x^3*(z+x)^5;
+  ideal adj = adjointIdeal(f);
+  def Rn = invertBirMap(adj,ideal(f));
+  setring(Rn);
+  J;
+  psi;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static proc checkAssumptions(poly f)
+"USAGE:  checkAssumptions(f); f poly
+RETURN:  1 if assumptions are satisfied, 0 otherwise.@*
+         Assumptions checked are: basering is polynomial ring in 3 variables
+         with coefficients in Q, f is homogeneous and absolutely irreducible
+"
+{
+  def Roriginal = basering;
+  list rl = ringlist(Roriginal);
+  rl[3] = list(list("dp",1:3),list("C",0));
+  if(size(rl[1])>1){ERROR("ground field is not Q");}
+  if(rl[1]!=0){ERROR("ground field is not Q");}
+  if(nvars(Roriginal)!=3)
+  { ERROR("not a projective plane curve: wrong number of variables"); }
+  if(homog(f)==0)
+  { ERROR("not a projective plane curve: polynomial is not homogeneous"); }
+  def RP2 = ring(rl);
+  setring RP2;
+  poly f = fetch(Roriginal,f);
+  if(isIrreducible(f)==0){ERROR("curve is not absolutely irreducible");}
+  setring Roriginal;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+proc paraPlaneCurve(poly f, list #)
+"USAGE:  paraPlaneCurve(f [, s]); f poly , s optional string@*
+         optional string s can be: @*
+         'normal': compute integral basis via normalization. @*
+         'local':  make local analysis of singularities first and apply
+                   normalization separately. @*
+         The default is 2. @*
+ASSUME:  The basering must be a polynomial ring in three variables, say x,y,z,
+         with coefficients in Q. @*
+         The polynomial f must be homogeneous and absolutely irreducible. @*
+         The curve C = {f = 0} must be rational, i.e., have geometric genus 0
+         (see @ref{genus}). @*
+         These conditions will be checked automatically.
+RETURN:  ring with an ideal PARA which contains a rational parametrization of
+         the rational plane curve given by f; the ground field of the returned
+         polynomial ring is either Q or some algebraic extension Q(a); PARA
+         consists of three generators that parametrize the three coordinates
+         of the rational curve
+THEORY:  After a first step, realized by a projective automorphism in the
+         procedure adjointIdeal, C satisfies: @*
+- C does not have singularities at infinity z=0. @*
+- C does not contain the point (0:1:0) (that is, the dehomogenization of f
+  with respect to z is monic as a polynomial in y). @*
+Considering C in the chart z<>0, the algorithm regards x as transcendental
+and y as algebraic and computes an integral basis in C(x)[y] of the integral
+closure of C[x] in C(x,y) using the normalization algorithm from @ref{normal_lib}:
+see @ref{integralbasis_lib}. In a future edition of the library, also van Hoeij's
+algorithm for computing the integral basis will be available. @*
+From the integral basis, the adjoint ideal is obtained by linear algebra.
+Alternatively, the algorithm starts with a local analysis of the singular
+locus of C. Then, for each  primary component of the singular locus which
+does not correspond to ordinary multiple points or cusps, the integral
+basis algorithm is applied separately. The ordinary multiple points and
+cusps, in turn, are addressed by a straightforward direct algorithm. The
+adjoint ideal is obtained by intersecting all ideals obtained locally.
+The local variant of the algorithm is used by default. @*
+The linear system corresponding to the adjoint ideal maps the curve
+birationally to a rational normal curve in P^(n-2). @*
+Iterating the anticanonical map, the algorithm projects the rational normal
+curve to PP1 for n odd resp. to a conic C2 in PP2 for n even. @*
+In case n is even, the algorithm tests whether there is a rational point on C2
+and if so gives a parametrization of C2 which is defined over Q. Otherwise the
+parametrization is defined over a quadratic field extension of Q. @*
+By inverting the birational map of C to PP1 resp. to C2, a parametrization of
+C is obtained (defined over Q or the quadratic field extension).
+KEYWORDS: rational curves, rational parametrization of rational curves.
+EXAMPLE:  example paraPlaneCurve; shows an example
+"
+{
+  int choice = 2;
+  if (size(#) != 0)
+  {
+    if (typeof(#[1]) == "string")
+    {
+      string s = string(#[1]);
+      if (s == "normal") { choice = 1; }
+      else
+      {
+        if (s == "local") { choice = 2; }
+        else { ERROR("expected optional argument to be either"
+                   + " 'local' or 'normal'"); }
+      }
+    }
+    else { ERROR("expected optional argument to be a string"); }
+  }
+  def Roriginal = basering;
+  /*checking assumptions and handling the conic case*/
+  checkAssumptions(f);
+  list rl = ringlist(Roriginal);
+  rl[2] = list("x","y","z");
+  rl[3] = list(list("dp",1:3),list("C",0));
+  def RP2 = ring(rl);
+  setring RP2;
+  poly f = fetch(Roriginal,f);
+  int d = deg(f);
+  if(d==2)
+    {
+      def RP1 = paraConic(f); // (ring, PARACONIC)
+      setring RP1;
+      ideal PARA = PARACONIC;
+      export(PARA);
+      "// 'paraPlaneCurve' created a ring together with an ideal PARA.";
+      "// Supposing you typed, say,  def RP1 = paraPlaneCurve(f);";
+      "// you may access the ideal by typing";
+      "//      setring RP1; PARA;";
+      return(RP1);
+    }
+  int k;
+  /*the adjoint ideal*/
+  ideal AI = adjointIdeal(f,list(choice,"rattestyes/firstchecksdone"));
+  /*rattestyes -> causes error message if curve is not rational*/
+  /*firstchecksdone -> prevents that check of assumptions will be done again*/
+  /*mapping the curve to a rational normal curve V(RNC) in Proj(Rrnc) via AI*/
+  def Rrnc = mapToRatNormCurve(f, AI);  // ring containing ideal RNC
+  setring Rrnc;
+  int m = d-1;  // the size of AI
+  /*the odd dimensional case*/
+  if((d mod 2) == 1)
+    {
+      /*mapping the rational normal curve to P^1 creating PHI*/
+      ideal PHI = rncItProjOdd(RNC);
+      /*composing the maps AI and PHI*/
+      def Rbig = Rrnc + RP2;
+      setring Rbig;
+      ideal AI = imap(RP2,AI);
+      ideal PROJ = imap(Rrnc,PHI);
+      for(k = 1; k <= m; k++)
+        {
+          PROJ = subst(PROJ,var(k),AI[k]);
+        }
+      setring RP2;
+      ideal If = ideal(fetch(Roriginal,f));
+      ideal PROJ = imap(Rbig,PROJ);
+      /*inverting the composed map to psi*/
+      def rp1 = invertBirMap(PROJ,If); // ring containing ideal psi
+      setring rp1;
+      list rl1 = ringlist(rp1);
+      rl1[2] = list("s","t");
+      def RP1 = ring(rl1);
+      setring RP1;
+      ideal PARA = fetch(rp1,psi);
+      export(PARA);
+      "// 'paraPlaneCurve' created a ring together with an ideal PARA.";
+      "// Supposing you typed, say,  def RP1 = paraPlaneCurve(f);";
+      "// you may access the ideal by typing";
+      "//      setring RP1; PARA;";
+      return(RP1);
+    }
+  /*the even dimensional case*/
+  /*mapping the rational normal curve to a CONIC in P^2* creating PHI*/
+  def RP2conic = rncItProjEven(RNC);  // exports PHI, returns ring
+                                      // containing CONIC
+  setring RP2conic;
+  /*mapping the conic to P^1 via pencil defined by Ipoint*/
+  def RP2conicNew = projConic(CONIC);  // ring containing ideal Ipoint
+                               // possibly defined over algebraic number field
+                               // variables u,v,w
+  /*composing the maps AI and PHI and Ipoint in two steps*/
+  def Rbig = RP2conicNew + Rrnc;
+  setring Rbig;
+  ideal PHI = imap(Rrnc,PHI);
+  ideal PROJ = imap(RP2conicNew,Ipoint);
+  for(k = 1; k <= 3; k++)
+    {
+      PROJ = subst(PROJ,var(k),PHI[k]);
+    }
+  ideal AI = fetch(RP2,AI);
+  for(k = 1; k <= m; k++)
+    {
+       PROJ = subst(PROJ,var(k+3),AI[k]);
+    }
+  setring RP2conicNew;
+  ideal If = ideal(fetch(Roriginal,f));
+  ideal PROJ = imap(Rbig,PROJ);
+  /*inverting the composed map to psi*/
+  def rp1 = invertBirMap(PROJ,If); // (ring, (J,psi))
+  setring rp1;
+  list rl1 = ringlist(rp1);
+  rl1[2] = list("s","t");
+  def RP1 = ring(rl1);
+  setring RP1;
+  ideal PARA = fetch(rp1,psi);
+  export(PARA);
+  "// 'paraPlaneCurve' created a ring together with an ideal PARA.";
+  "// Supposing you typed, say,  def RP1 = paraPlaneCurve(f);";
+  "// you may access the ideal by typing";
+  "//      setring RP1; PARA;";
+  return(RP1);
+}
+
+example
+{ "EXAMPLE:"; echo=2;
+  ring R = 0,(x,y,z),dp;
+  poly f1 = 1/2*x^5+x^2*y*z^2+x^3*y*z+1/2*x*y^2*z^2-2*x*y^3*z+y^5;
+  def Rp1 = paraPlaneCurve(f1);
+  setring Rp1;
+  PARA;
+  setring R;
+  poly f2 = x6+3x4y2+3x2y4+y6-4x4z2-34x3yz2-7x2y2z2+12xy3z2+6y4z2;
+  f2 = f2+36x2z4+36xyz4+9y2z4;
+  def Rp2 = paraPlaneCurve(f2);
+  setring Rp2;
+  PARA;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// compute the weighted degree of p;
+// this code is an exact copy of the proc in paraplanecurves.lib
+// (since we do not want to make it non-static)
+static proc w_deg(poly p, intvec v)
+{
+   if(p==0){return(-1);}
+   int d=0;
+   while(jet(p,d,v)==0){d++;}
+   d=(transpose(leadexp(jet(p,d,v)))*v)[1];
+   return(d);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static proc findCoordChange(poly f, ideal JAC)
+"USAGE:  findCoordChange(f, JAC); f poly, JAC ideal.
+ASSUME:  The polynomial f is homogeneous in three variables, JAC is
+         the Jacobi ideal of f.
+RETURN:  intvec, say a,b,c. After the coordinate change
+         var(3) --> a*var(1)+b*var(2)+c*var(3), the curve {f=0}
+         has no singularities at infinity {var(3)=0}.
+"
+{
+  int h = 2;
+  int a,b,c;
+  ideal Jfinfty;
+  while(h)
+    {
+      c = 1;
+      while(c<=h)
+         {
+           b = 0;
+           while(b<=(h-c))
+              {
+                a = h-b-c;
+                Jfinfty = JAC,a*var(1)+b*var(2)+c*var(3);
+                if(dim(std(Jfinfty)) == 0)
+                  {
+                    return(a,b,c);
+                  }
+                b = b+1;
+              }
+            c = c+1;
+          }
+       h = h+1;
+    }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+proc adjointIdeal(poly f, list #)
+"USAGE:  adjointIdeal(f [, choices]); f polynomial in three variables, choices
+         optional list consisting of one integer or of one string or of one
+         integer followed by one string. @*
+         Optional integer can be: @*
+         1: compute integral basis via normalization. @*
+         2: make local analysis of singularities first and apply normalization
+            separately. @*
+         3: normalization via ideal quotient. @*
+         4: normalization via local ideal quotient. @*
+         The default is 2. @*
+         Optional string may contain substrings: @*
+         - rattestyes -> causes error message if curve is not rational. @*
+         - firstchecksdone -> prevents that check of assumptions will be done
+           more than once.
+ASSUME:  The basering must be a polynomial ring in three variables, say x,y,z,
+         with coefficients in Q. @*
+         The polynomial f must be homogeneous and absolutely irreducible.@*
+         All these conditions will be checked automatically.@*
+RETURN:  ideal, the adjoint ideal of the curve defined by f.
+THEORY:  Considering C in the chart z<>0, the algorithm regards x as
+transcendental and y as algebraic and computes an integral basis in C(x)[y] of
+the integral closure of C[x] in C(x,y) using the normalization algorithm
+from @ref{normal_lib}: see @ref{integralbasis_lib}. In a future edition of the library,
+also van Hoeij's algorithm for computing the integral basis will be available.@*
+From the integral basis, the adjoint ideal is obtained by linear algebra.
+Alternatively, the algorithm starts with a local analysis of the singular
+locus of C. Then, for each  primary component of the singular locus which
+does not correspond to ordinary multiple points or cusps, the integral
+basis algorithm is applied separately. The ordinary multiple points and
+cusps, in turn, are addressed by a straightforward direct algorithm. The
+adjoint ideal is obtained by intersecting all ideals obtained locally.
+The local variant of the algorithm is used by default. @*
+KEYWORDS: integral basis; normalization.
+EXAMPLE: example adjointIdeal; shows an example
+"
+{
+  list choices = #;
+  if(size(#)==0)
+    {
+      checkAssumptions(f);
+      choices = list(2, "rattestno");
+    }
+  if(size(#)==1)
+    {
+      if(typeof(choices[1])=="int")
+        {
+          checkAssumptions(f);
+          choices = list(choices[1], "rattestno");
+        }
+      else
+         {
+           if(not(find(choices[1], "firstchecksdone")))
+             {
+               checkAssumptions(f);
+             }
+           else
+             {
+               choices = list(2, choices[1]);
+             }
+        }
+    }
+  if(size(#) == 2)
+    {
+      if(not(find(choices[2],"firstchecksdone")))
+        {
+          checkAssumptions(f);
+        }
+    }
+  ideal JAC = diff(maxideal(1),ideal(f));
+  ideal Jfinfty = JAC,var(3);
+  /*applying a change of coordinates if (f=0) has singularities at infinity*/
+  int bb1;
+  if(dim(std(Jfinfty)) >= 1)
+    {
+       bb1 = 1;
+       int a,b,c  = findCoordChange(f,JAC);
+       f = subst(f,var(3),var(3)-number(a)/c*var(1)-number(b)/c*var(2));
+    }
+  /*applying a change of coordinates if the point (0:1:0) lies on the curve*/
+  matrix co = coeffs(f,var(2));
+  int bb2 = ((size(co)-1) != deg(f));
+  if(bb2)
+    {
+       co = coeffs(f,var(1));
+       int bb2x = ((size(co)-1) == deg(f));
+       if(bb2x)
+         {
+           map perm = basering, var(2), var(1), var(3);
+           f = perm(f);
+         }
+       else
+         {
+           f = subst(f,var(1),var(1)+var(2));
+         }
+    }
+  co = coeffs(f,var(2));
+  f = f/co[size(co),1];
+  /*the actual computation*/
+  ideal AI = adjointIdealAtWork(f,choices);
+  /*reversing the changes of coordinates if needed*/
+  if(bb2)
+    {
+       if(bb2x)
+         {
+           map perm = basering, var(2), var(1), var(3);
+           AI = mstd(perm(AI))[2];
+         }
+       else
+         {
+           AI = mstd(substitute(AI,var(1),var(1)-var(2)))[2];
+         }
+
+    }
+  if(bb1==1)
+   {
+      AI = mstd(substitute(AI,var(3),var(3)+number(a)/c*var(1)+number(b)/c*var(2)))[2];
+    }
+  return(AI);
+}
+
+example
+{ "EXAMPLE:"; echo=2;
+  ring R = 0,(x,y,z),dp;
+  poly f = y^8-x^3*(z+x)^5;
+  adjointIdeal(f);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static proc adjointIdealAtWork(poly f, list choices)
+"USAGE:  adjointIdealAtWork(f, choices); f polynomial in three variables,
+         choices list consisting of one integer followed by one string. @*
+         integer can be: @*
+         1: compute integral basis via normalization. @*
+         2: make local analysis of singularities first and apply normalization
+            separately. @*
+         3: normalization via ideal quotient. @*
+         4: normalization via local ideal quotient. @*
+         The default is 2. @*
+         string  may contain substring: @*
+         - rattestyes -> causes error message if curve is not rational. @*
+ASSUME:  The basering must be a polynomial ring in three variables, say x,y,z,
+         with coefficients in Q. @*
+         The polynomial f must be homogeneous and absolutely irreducible. @*
+         Its dehomogenization with respect to the third variable must be monic
+         as a polynomial in the second variable (that is, C does not contain
+         the point (0:1:0)).@*
+         The curve C is not allowed to have singularities
+         at infinity (z = 0). @*
+RETURN:  ideal, the adjoint ideal of the curve defined by f.
+"
+{
+  def Roriginal = basering;
+  list rl = ringlist(Roriginal);
+  rl[3] = list(list("dp",1:nvars(Roriginal)),list("C",0));
+  def RP2 = ring(rl);
+  setring RP2;
+  poly f = imap(Roriginal,f);
+  poly dhf = subst(f,var(3),1);
+  int n = deg(f);
+  if((choices[1]==1) || (choices[1]==3)) // no local analysis of singularities
+    {
+      ideal AI;
+      if (choices[1]==1)
+      { AI = adjointIdealIB(f,insert(choices,ideal(0),size(choices))); }
+      else
+      { AI = adjointIdealIQ(f,insert(choices,ideal(0),size(choices))); }
+      AI = homog(std(AI),var(3));
+      AI = sat(AI, maxideal(1))[1];
+      AI = minbase(AI);
+      setring Roriginal;
+      return(imap(RP2,AI));
+    }
+  list LL = geomGenusLA(f);  // local analysis of singularities
+  int sizeLL2 = size(LL[2]);
+  int sizeLL3 = size(LL[3]);
+  list LL3 = LL[3];
+  ideal LL4 = LL[4];
+  if((LL[1]!=0) && (find(choices[2],"rattestyes")))
+  { ERROR("not a rational curve"); }
+  if((LL[2]==0) && (sizeLL3==0)  && (LL4==1))  // smooth case
+    {
+      setring Roriginal;
+      return(ideal(1));
+    }
+  int j,k;
+  list rl = ringlist(RP2);
+  rl[2] = list(var(1), var(2));
+  rl[3] = list(list("dp",1:2),list("C",0));
+  def Rdummy = ring(rl);
+  ideal B;
+  if(sizeLL3==0){B = 1;} // no ordinary multiple points
+                               // (except possibly nodes)
+  else                         // there are ordinary multiple points
+                               // (other than nodes)
+    {
+      setring Rdummy;
+      list OMP = imap(RP2,LL3);
+      int ub;
+      for(k=1;k<=size(OMP);k++)
+        {
+          if(OMP[k][1]>ub)
+            {
+              ub = OMP[k][1];
+            }
+        }
+     int lb = ub;
+     for(k=1;k<=size(OMP);k++)
+        {
+          if(OMP[k][1]<lb)
+            {
+              lb = OMP[k][1];
+            }
+        }
+     for(k=lb;k<=ub;k++)
+       {
+         ideal A(k) = 1;
+       }
+     for(k=1;k<=size(OMP);k++)
+       {
+         A(OMP[k][1]) = intersect(A(OMP[k][1]), OMP[k][2]);
+       }
+     int i = ub;
+     setring RP2;
+     for(k=lb;k<=ub;k++)
+       {
+         ideal A(k) = homog(std(fetch(Rdummy,A(k))),var(3));
+       }
+     B = maxideal(n-i);
+     ideal A;
+     while(i>=lb)
+        {
+          A = A(i)**(i-1);
+          j=1;
+          while(j<=ncols(A))
+            {
+              if(deg(A[j]>(n-2)))
+                {
+                  A = sat(A, maxideal(1))[1];
+                  break;
+                 }
+              j = j+1;
+            }
+          B = intersect(B,A);
+          i = i-1;
+       }
+    }  //end else
+  B = intersect(B,homog(std(LL4),var(3)));  // add nodes and cusps
+  if(sizeLL2==0)  // ordinary multiple points plus cusps only
+    {
+      ideal AI = sat(B, maxideal(1))[1];
+      AI = minbase(AI);
+      setring Roriginal;
+      return(imap(RP2,AI));
+    }
+  setring Rdummy;
+  poly f = imap(RP2,dhf);
+  ideal SL = jacob(f),f;
+  SL = sat(SL, fetch(RP2,LL4))[1];
+  if(sizeLL3!=0)
+    {
+      for(k=lb;k<=ub;k++)
+        {
+          SL = sat(SL, A(k))[1];
+        }
+    }
+  list PD = primdecGTZ(SL);  // could be made faster -- see minAssGTZ
+                             // in deltaLocMod -- only one PD needed
+  int pd = size(PD);
+  setring RP2;
+  list PD = imap(Rdummy,PD);
+  ideal AI = 1;
+  for(k=1;k<=pd;k++)
+    {
+      if (choices[1]==2)
+      { AI = intersect(AI,adjointIdealIB(f,insert(choices,PD[k][1],
+                                                 size(choices)))); }
+      else
+      { AI = intersect(AI,adjointIdealIQ(f,insert(choices,PD[k][1],
+                                                 size(choices)))); }
+    }
+  AI = homog(std(AI),var(3));
+  AI = intersect(AI,B);
+  AI = sat(AI, maxideal(1))[1];
+  AI = minbase(AI);
+  setring Roriginal;
+  return(imap(RP2,AI));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static proc adjointIdealIB(poly f, list choices)
+"USAGE:  adjointIdealIB(f, choices); f polynomial in three variables, choices
+         list consisting of one integer followed by one string followed by one
+         ideal. @*
+         integer can be: @*
+         1, 2 : compute integral basis via normalization @*
+         The default is 2. @*
+         string  may contain substring: @*
+         - rattestyes -> causes error message if curve is not rational. @*
+         ideal serves as input for @ref integralBasis.
+ASSUME:  The basering must be a polynomial ring in three variables, say x,y,z,
+         with coefficients in Q. @*
+         The polynomial f must be homogeneous and absolutely irreducible.@*
+         Its dehomogenization with respect to the third variable must be monic
+         as a polynomial in the second variable (that is, C does not contain
+         the point (0:1:0)).@*
+         The curve C is not allowed to have singularities
+         at infinity (z = 0). @*
+RETURN:  ideal containing the adjoint ideal of the curve defined by f. @*
+"
+{
+  poly dhf = subst(f,var(3),1);
+  def Roriginal = basering;
+  list rl = ringlist(Roriginal);
+  rl[2] = list(var(1), var(2));
+  rl[3] = list(list("dp",1:2),list("C",0));
+  def Rdummy = ring(rl);
+  setring Rdummy;
+  poly f = imap(Roriginal,dhf);
+  poly d2f = diff(f,var(2));
+  list DATA = imap(Roriginal,choices);
+  /* Creating rings for later use */
+  list rl = ringlist(Rdummy);
+  rl[2] = list(var(2), var(1));
+  rl[3] = list(list("lp",1:2),list("C",0));
+  def Rred = ring(rl);   // make var(2) > var(1)
+  rl = ringlist(Rdummy);
+  rl[1] = list(0,list(var(1)),list(list("dp",1)),ideal(0));
+  rl[2] = list(var(2));
+  rl[3] = list(list("dp",1),list("C",0));
+  def QF = ring(rl);   // make var(1) transcendental
+  list LIntB;
+  if(DATA[1] <= 4)  // use normalization algorithm
+    {
+      LIntB = integralBasis(f, 2, list(list("inputC", DATA[3]),"isIrred"));
+    }
+  else                                 // use van Hoeij's algorithm
+    {
+      LIntB = integralBasisVH(f,DATA[3],2);  // van Hoeij in future version
+                                             // used when DATA[1] = 5
+    }
+  if(find(DATA[2],"rattestyes") && (DATA[3]==0))
+    {
+      setring Roriginal;
+      int gg = geomGenusIB(f,imap(Rdummy, LIntB));
+      if(gg!=0){ERROR("not a rational curve");}
+      setring Rdummy;
+    }
+  int i,j,k,l;
+  ideal IB = LIntB[1];
+  poly d = LIntB[2];
+  int sL=size(IB);
+  setring Rred;
+  ideal IB = imap(Rdummy,IB);
+  ideal fred = std(imap(Rdummy,f));
+  IB = reduce(IB,fred);
+  matrix M = coeffs(IB,var(1));
+  setring QF;
+  matrix M = imap(Rred,M);
+  poly d = imap(Rdummy,d);
+  M=1/d*M;
+  list LUM = ludecomp(M);
+  list LS;
+  matrix dummyvector[sL][1];
+  matrix Gij[sL][sL];
+  matrix Tr[sL][sL];
+  setring Rred;
+  poly eiej;
+  list Iij, empty;
+  matrix Gij[sL][sL];
+  for(i = 1; i <= sL; i++)
+     {
+       for(j = i; j <= sL; j++)
+          {
+            setring Rred;
+            Gij = 0;
+            eiej = IB[i]*IB[j];
+            Iij=empty;
+            for(k = 1; k <= sL; k++)
+               {
+                  Iij[k] = reduce(eiej*IB[k],fred);
+               }
+            Gij = coeffs(ideal(Iij[1..sL]),var(1));
+            setring QF;
+            Gij = imap (Rred, Gij);
+            for(k = 1; k <= sL; k++)
+               {
+                  dummyvector = Gij[1..sL,k];
+                  LS = lusolve(LUM[1], LUM[2], LUM[3], dummyvector);
+                  Tr[i,j] = Tr[i,j] + 1/d^3*LS[2][k,1];
+               }
+          }
+     }
+  for(i = 1; i <= sL; i++)
+     {
+       for(j = 1; j < i; j++)
+          {
+             Tr[i,j] = Tr[j,i];
+          }
+     }
+  LUM = ludecomp(Tr);
+  setring Rred;
+  poly d2f = imap(Rdummy,d2f);
+  IB = d2f*IB;
+  IB = reduce(IB,fred);
+  setring QF;
+  matrix IB = transpose(matrix(imap(Rred,IB)));
+  IB = 1/d*IB;
+  LS = lusolve(LUM[1], LUM[2], LUM[3], IB);
+  ideal LL = ideal(LS[2]);
+  setring Roriginal;
+  ideal AI = imap(QF,LL);
+  return(AI);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static proc adjointIdealIQ(poly f, list choices)
+{
+  poly dhf = subst(f,var(3),1);
+  def Roriginal = basering;
+  list rl = ringlist(Roriginal);
+  rl[2] = list(var(1), var(2));
+  rl[3] = list(list("dp",1:2),list("C",0));
+  def Rdummy = ring(rl);
+  setring Rdummy;
+  list DATA = imap(Roriginal,choices);
+  poly f = imap(Roriginal,dhf);
+  list LIntB;
+  if(DATA[1] <= 4)  // use normalization algorithm
+    {
+      LIntB = integralBasis(f, 2, list(list("inputC", DATA[3]),"isIrred"));
+    }
+  else                                 // use van Hoeij's algorithm
+    {
+      LIntB = integralBasisVH(f,DATA[3],2);  // van Hoeij in future version
+                                             // used when DATA[1] = 5
+    }
+  if(find(DATA[2],"rattestyes") && (DATA[3]==0))
+    {
+      setring Roriginal;
+      int gg = geomGenusIB(f,imap(Rdummy, LIntB));
+      if(gg!=0){ERROR("not a rational curve");}
+      setring Rdummy;
+    }
+  int i,j,k,l;
+  ideal IB = LIntB[1];
+  poly d = LIntB[2];
+  ideal fd = f, d;
+  ideal IBf = IB, f;
+  ideal AI = quotient(fd, IBf);
+//"#### IB:"; IB;
+//"#### d:", d;
+  setring Roriginal;
+  ideal AI = imap(Rdummy,AI);
+//"#### AI:"; AI;
+  return(AI);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+proc mapToRatNormCurve(poly f, ideal AI)
+"USAGE:  mapToRatNormCurve(f, AI); f polynomial, AI ideal
+ASSUME:  The polynomial f is homogeneous in three variables and absolutely
+         irreducible.
+         The plane curve C defined by f is rational.
+         The ideal AI is the adjoint ideal of C.
+RETURN:  ring with an ideal RNC.
+EXAMPLE: example mapToRatNormCurve; shows an example
+"
+{
+   int n = size(AI);
+   int k;
+   //if(n!=deg(f)-1){ERROR("not a rational curve");}
+   def Roriginal = basering;
+   ideal IC = f;
+   list rl = ringlist(Roriginal);
+   /* begin workaround elimination*/
+   for(k = 1; k <= 3; k++)
+     {
+        rl[2][k] = "x("+string(k)+")";
+     }
+   for(k = 1; k <= n; k++)
+     {
+        rl[2][k+3] = "y("+string(k)+")";
+     }
+   rl[3]= list(list("dp",1:(3+n)),list("C",0));
+   def Relim = ring(rl);
+   setring Relim;
+   ideal IC = fetch(Roriginal,IC);
+   ideal AI = fetch(Roriginal,AI);
+   ideal J;
+   J = IC;
+   for(k=1;k<=n;k++)
+     {
+       J=J,var(k+3)-AI[k];
+     }
+   ideal SJ = std(J);
+   intvec HJ = hilb(SJ,1);
+   ideal RNC = eliminate(J,x(1)*x(2)*x(3),HJ);
+   list rl = ringlist(Relim);
+   list rl2 = rl[2];
+   rl[2] = list(rl2[4..n+3]);
+   rl[3]= list(list("dp",1:n),list("C",0));
+   def Rtarget = ring(rl);
+   setring Rtarget;
+   ideal RNC = imap(Relim,RNC);
+   /* end workaround elimination*/
+   export(RNC);
+   int p = printlevel - voice + 3;
+   dbprint(p,"//'mapToRatNorm' created a ring together with an ideal RNC.");
+   dbprint(p,"// Supposing you typed, say,  def RPn = mapToRatNorm(f,AI);");
+   dbprint(p,"// you may access the ideal by typing");
+   dbprint(p,"//      setring RPn; RNC;");
+   return(Rtarget);
+}
+
+example
+{ "EXAMPLE:"; echo=2;
+  ring R = 0,(x,y,z),dp;
+  poly f = y^8-x^3*(z+x)^5;
+  ideal adj = adjointIdeal(f);
+  def Rn = mapToRatNormCurve(f,adj);
+  setring(Rn);
+  RNC;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+proc rncAntiCanonicalMap(ideal I)
+"USAGE:  rncAntiCanonicalMap(I); I ideal
+ASSUME:  I is a homogeneous ideal in the basering
+         defining a rational normal curve C in PP^n.
+NOTE:   The procedure will fail or give a wrong output if I is not the
+        ideal of a rational normal curve.
+RETURN:  ideal defining the anticanonical map  C --> PP^(n-2). @*
+         Note that the entries of the ideal should be considered as
+         representatives of elements in R/I, where R is the basering.
+THEORY:  The anti-canonical map of a rational normal curve
+         maps C isomorpically to a rational normal curve in PP^(n-2).
+KEYWORDS: rational normal curve, projection.
+EXAMPLE: example rncAntiCanonicalMap; shows an example
+"
+{
+  def Roriginal = basering;
+  list rl = ringlist(Roriginal);
+  rl[3] = list(list("dp",1:nvars(Roriginal)),list("C",0));
+  def RoriginalDP = ring(rl);
+  setring RoriginalDP;
+  ideal I = imap(Roriginal,I);
+  int cc = nvars(RoriginalDP)-2;
+  module AKD = Ext_R(cc,I);
+  qring qI = std(I);
+  matrix AKD = imap(RoriginalDP,AKD);
+  AKD = syz(transpose(AKD));
+  ideal PR = submat(AKD,1..nrows(AKD),1);
+  setring Roriginal;
+  return(imap(qI,PR));
+}
+
+example
+{ "EXAMPLE:"; echo=2;
+  ring R = 0,(x,y,z),dp;
+  poly f = y^8-x^3*(z+x)^5;
+  ideal adj = adjointIdeal(f);
+  def Rn = mapToRatNormCurve(f,adj);
+  setring(Rn);
+  RNC;
+  rncAntiCanonicalMap(RNC);
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+proc rncItProjOdd(ideal I)
+"USAGE:  rncItProjOdd(I); I ideal
+ASSUME:  I is a homogeneous ideal in the basering with n+1 variables
+         defining a rational normal curve C in PP^n with n odd.
+NOTE:    The procedure will fail or give a wrong output if I is not the
+         ideal of a rational normal curve. It will test whether n is odd.
+RETURN:  ideal PHI defining an isomorphic projection of C to PP^1.@*
+         Note that the entries of PHI should be considered as
+         representatives of elements in R/I, where R is the basering.
+THEORY:  We iterate the procedure @ref{rncAntiCanonicalMap} to obtain PHI.
+KEYWORDS: rational normal curve, projection.
+SEE ALSO: rncItProjEven.
+EXAMPLE: example rncItProjOdd; shows an example
+"
+{
+  int n = nvars(basering);
+  if((n mod 2) == 1){ERROR("Pn has even dimension");}
+  def Roriginal = basering;
+  list rlo = ringlist(Roriginal);
+  rlo[3]= list(list("dp",1:n),list("C",0));
+  int k;
+  for(k = 1; k <= n; k++)
+    {
+      rlo[2][k] = "z("+string(k)+")";
+    }
+  def RoriginalCopy = ring(rlo);
+  for(k = 1; k <= n; k++)
+    {
+      rlo[2][k] = "y("+string(k)+")";
+    }
+  def Rold = ring(rlo);
+  setring RoriginalCopy;
+  ideal PHI  = maxideal(1);
+  setring Rold;
+  ideal J = fetch(Roriginal,I);
+  list rl2;
+  def Rnew;
+  def Rbig;
+  def Relim;
+  intvec HJJ;
+  while(n>2)
+     {
+        ideal PR = rncAntiCanonicalMap(J);
+        list rl = ringlist(Rold);
+        Rbig = Rold + RoriginalCopy;
+        setring Rbig;
+        ideal PHI = imap(RoriginalCopy,PHI);
+        ideal dummy = imap(Rold,PR);
+        for(k = 1; k <= n; k++)
+          {
+             dummy = subst(dummy,var(k),PHI[k]);
+          }
+        setring RoriginalCopy;
+        PHI = imap(Rbig,dummy);
+        /* begin workaround elimination*/
+        setring Rold;
+        for(k = 1; k <= n; k++)
+          {
+            rl[2][k] = "x("+string(k)+")";
+          }
+        for(k = 1; k <= n-2; k++)
+          {
+            rl[2][k+n] = "y("+string(k)+")";
+          }
+        rl[3]= list(list("dp",1:(2*n-2)),list("C",0));
+        Relim = ring(rl);
+        setring Relim;
+        ideal J = fetch(Rold,J);
+        ideal PR = fetch(Rold,PR);
+        ideal JJ = J;
+        poly pvar=1;
+        for(k = 1; k <= n; k++)
+          {
+            pvar = pvar*var(k);
+          }
+        for(k=1;k<=n-2;k++)
+          {
+            JJ=JJ,var(k+n)-PR[k];
+          }
+        ideal SJJ = std(JJ);
+        HJJ = hilb(SJJ,1);
+        J = eliminate(JJ,pvar,HJJ);
+        list rl = ringlist(Relim);
+        rl2 = rl[2];
+        rl[2] = list(rl2[n+1..2*n-2]);
+        rl[3]= list(list("dp",1:(n-2)),list("C",0));
+        Rnew = ring(rl);
+        setring Rnew;
+        ideal J = imap(Relim,J);
+        /* end workaround elimination*/
+        Rold = Rnew;
+        setring Rold;
+        n = n-2;
+     }
+  setring Roriginal;
+  return(fetch(RoriginalCopy,PHI));
+}
+
+example
+{ "EXAMPLE:"; echo=2;
+  ring R = 0,(x,y,z),dp;
+  poly f = -x7-10x5y2-10x4y3-3x3y4+8x2y5+7xy6+11y7+3x6+10x5y +30x4y2
+           +26x3y3-13x2y4-29xy5-33y6-3x5-20x4y-33x3y2-8x2y3+37xy4+33y5
+           +x4+10x3y+13x2y2-15xy3-11y4;
+  f = homog(f,z);
+  ideal adj = adjointIdeal(f);
+  def Rn = mapToRatNormCurve(f,adj);
+  setring(Rn);
+  RNC;
+  rncItProjOdd(RNC);
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+proc rncItProjEven(ideal I)
+"USAGE:  rncItProjEven(I); I ideal
+ASSUME:  I is a homogeneous ideal in the basering with n+1 variables
+         defining a rational normal curve C in PP^n with n even.
+NOTE:    The procedure will fail or give a wrong output if I is not the
+         ideal of a rational normal curve. It will test whether n is odd.
+RETURN:  ring with an ideal CONIC defining a conic C2 in PP^2.@*
+         In addition, an ideal PHI in the basering defining an isomorphic
+         projection of C to C2 will be exported.@*
+         Note that the entries of PHI should be considered as
+         representatives of elements in R/I, where R is the basering.
+THEORY:  We iterate the procedure @ref{rncAntiCanonicalMap} to obtain PHI.
+KEYWORDS: rational normal curve, projection.
+SEE ALSO: rncItProjOdd.
+EXAMPLE: example rncItProjEven; shows an example
+"
+{
+  int n = nvars(basering);
+  if((n mod 2) == 0){ERROR("Pn has odd dimension");}
+  def Roriginal = basering;
+  list rlo = ringlist(Roriginal);
+  rlo[3]= list(list("dp",1:n),list("C",0));
+  int k;
+  for(k = 1; k <= n; k++)
+    {
+      rlo[2][k] = "z("+string(k)+")";
+    }
+  def RoriginalCopy = ring(rlo);
+  for(k = 1; k <= n; k++)
+    {
+      rlo[2][k] = "y("+string(k)+")";
+    }
+  def Rold = ring(rlo);
+  setring RoriginalCopy;
+  ideal PHI  = maxideal(1);
+  setring Rold;
+  ideal J = fetch(Roriginal,I);
+  list rl2;
+  def Rnew;
+  def Rbig;
+  def Relim;
+  intvec HJJ;
+  while(n>3)
+     {
+        ideal PR = rncAntiCanonicalMap(J);
+        list rl = ringlist(Rold);
+        Rbig = Rold + RoriginalCopy;
+        setring Rbig;
+        ideal PHI = imap(RoriginalCopy,PHI);
+        ideal dummy = imap(Rold,PR);
+        for(k = 1; k <= n; k++)
+          {
+             dummy = subst(dummy,var(k),PHI[k]);
+          }
+        setring RoriginalCopy;
+        PHI = imap(Rbig,dummy);
+        /* begin workaround elimination*/
+        setring Rold;
+        for(k = 1; k <= n; k++)
+          {
+            rl[2][k] = "x("+string(k)+")";
+          }
+        for(k = 1; k <= n-2; k++)
+          {
+            rl[2][k+n] = "y("+string(k)+")";
+          }
+        rl[3]= list(list("dp",1:(2*n-2)),list("C",0));
+        Relim = ring(rl);
+        setring Relim;
+        ideal J = fetch(Rold,J);
+        ideal PR = fetch(Rold,PR);
+        ideal JJ = J;
+        poly pvar=1;
+        for(k = 1; k <= n; k++)
+          {
+            pvar = pvar*var(k);
+          }
+        for(k=1;k<=n-2;k++)
+          {
+            JJ=JJ,var(k+n)-PR[k];
+          }
+        ideal SJJ = std(JJ);
+        HJJ = hilb(SJJ,1);
+        J = eliminate(JJ,pvar,HJJ);
+        list rl = ringlist(Relim);
+        rl2 = rl[2];
+        rl[2] = list(rl2[n+1..2*n-2]);
+        rl[3]= list(list("dp",1:(n-2)),list("C",0));
+        Rnew = ring(rl);
+        setring Rnew;
+        ideal J = imap(Relim,J);
+        /* end workaround elimination*/
+        Rold = Rnew;
+        setring Rold;
+        n = n-2;
+     }
+  poly CONIC = J[1];
+  export(CONIC);
+  setring Roriginal;
+  ideal PHI = fetch(RoriginalCopy,PHI);
+  export(PHI);
+  return(Rold);
+}
+
+example
+{ "EXAMPLE:"; echo=2;
+  ring R = 0,(x,y,z),dp;
+  poly f = y^8-x^3*(z+x)^5;
+  ideal adj = adjointIdeal(f);
+  def Rn = mapToRatNormCurve(f,adj);
+  setring(Rn);
+  RNC;
+  def Rc = rncItProjEven(RNC);
+  PHI;
+  setring Rc;
+  CONIC;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static proc geomGenusIB(poly f, list #)
+"USAGE:  geomGenusIB(f [, L]); f poly, L optional list representing the
+         integral basis as returned by @ref integralBasisJ.
+ASSUME:  The basering must be a polynomial ring in three variables, say x,y,z,
+         with coefficients in Q. @*
+         The polynomial f must be homogeneous and absolutely irreducible.@*
+         Its dehomogenization with respect to the third variable must be monic
+         as a polynomial in the second variable (that is, the curve C = {f = 0}
+         does not contain the point (0:1:0)).@*
+         The curve C is not allowed to have singularities
+         at infinity (z = 0). @*
+NOTE:    The last two conditions can be met by a suitable change of coordinates in PGL(3)
+         as applied in the procedure @ref adjointIdeal. The other conditions
+         can be tested using @ref checkAssumptions.@*
+RETURN:  int, the geometric genus of C.
+THEORY:  We compute an integral basis of the integral closure of the coordinate
+         ring of C and from that the geometric genus.@*
+KEYWORDS: geometric genus, plane curves.
+SEE ALSO: genus.
+"
+{
+  int bb = size(#);
+  poly dhf = subst(f,var(3),1);
+  def Roriginal = basering;
+  list rl = ringlist(Roriginal);
+  rl[2] = list(var(1), var(2));
+  rl[3] = list(list("dp",1:2),list("C",0));
+  def Rdummy = ring(rl);
+  setring Rdummy;
+  poly f = imap(Roriginal,dhf);
+  list LIntB;
+  if(bb == 0)
+    {
+      LIntB = integralBasis(f,2,"isIrred");
+    }
+  else
+    {
+      LIntB = imap(Roriginal,#);
+    }
+  ideal IB = LIntB[1];
+  poly d = LIntB[2];
+  int ud = deg(d);
+  int sL = size(IB);
+  int k;
+  int gg = (sL-1)*(sL-2) div 2-sL*ud;
+  for(k = 1; k <= sL; k++)
+     {
+        gg = gg + deg(gcd(d,IB[k]));
+     }
+  setring Roriginal;
+  return(gg);
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+static proc geomGenusLA(poly F)
+"USAGE:  geomGenusLA(F); F polynomial
+ASSUME:  The basering must be a polynomial ring in three variables. @*
+         The polynomial F must be homogeneous.@*
+RETURN:  list L:
+ at texinfo
+ at table @asis
+ at item @code{L[1]}; int:
+         the geometric genus p_g = p_a - delta of the projective
+         curve C defined by F, where p_a is the arithmetic genus.
+ at item @code{L[2]}; int:
+         is positive if C has singularities other
+         than ordinary multiple points.@*
+ at item @code{L[3]}; list:
+         consists of one list for each primary component
+         of the singular locus of C which correponds to a set of conjugated
+         ordinary multiple points. Each list consists of an int, the
+         multiplicity of the points, and an ideal, the primary component.
+ at end table
+ at end texinfo
+NOTE:    delta is the sum of all local delta-invariants of the singularities,
+         i.e. dim(R'/R), R' the normalization of the local ring R of the
+         singularity. @*
+SEE ALSO: genus
+"
+{
+   int w = printlevel-voice+2;  // w=printlevel (default: w=0)
+   int d = deg(F);
+   def R = basering;
+   execute("ring S=("+charstr(R)+"),(x,y,t),dp;");
+   execute("ring C=("+charstr(R)+"),(x,y),ds;");
+   int genus=(d-1)*(d-2) div 2;
+   if(w>=1){"the arithmetic genus of the plane curve:";genus;pause();}
+
+   int delt,deltaloc,deltainf,tau,tauinf,cusps,iloc,iglob,l,nsing,
+       tauloc,tausing,k,rat,nbranchinf,nbranch,nodes,cuspsinf,nodesinf;
+   list inv;
+   execute("ring newR=("+charstr(R)+"),(x,y),dp;");
+   //the singularities at the affine part
+   map sigma=R,var(1),var(2),1;
+   ideal I=sigma(F);
+
+   list OMPButNodes;
+   int sizeOMPButNodes;
+   int NotOnlyOMPPlusCusps;
+
+   ideal I1=jacob(I);
+   matrix Hess[2][2]=jacob(I1);
+   ideal ID=I+I1+ideal(det(Hess));//singular locus of I+I1
+   ideal radID=std(radical(ID));//the non-nodal locus
+   if(w>=1){"the non-nodal locus:";"";radID;pause();"";}
+   if(deg(radID[1])==0)
+   {
+     ideal IDsing=1;
+   }
+   else
+   {
+     ideal IDsing=minor(jacob(ID),2)+radID;//singular locus of ID
+   }
+
+   iglob=vdim(std(IDsing));
+
+   ideal radIDsing = 1;
+
+   if(iglob!=0)//computation of the radical of IDsing
+   {
+      radIDsing=reduce(IDsing,radID);
+      if(size(radIDsing)==0)
+      {
+         radIDsing=radID;
+         attrib(radIDsing,"isSB",1);
+      }
+      else
+      {
+         radIDsing=std(radical(IDsing));
+      }
+      iglob=vdim(radIDsing);
+      if((w>=1)&&(iglob))
+          {"the non-nodal-cuspidal locus:";radIDsing;pause();"";}
+   }
+   cusps=vdim(radID)-iglob;
+
+   ideal NodesPlusCusps  = radical(sat(I+I1, radIDsing)[1]);
+
+   nsing=nsing+cusps;
+
+   if(iglob==0)
+   {
+      if(w>=1){"             there are only cusps and nodes";"";}
+      tau=vdim(std(I+jacob(I)));
+      tauinf=tauinf+tau;
+      nodes=tau-2*cusps;
+      delt=nodes+cusps;
+      nbranch=2*tau-3*cusps;
+      nsing=nsing+nodes;
+   }
+   else
+   {
+       if(w>=1){"the non-nodal-cuspidal singularities";"";}
+       setring C;
+       ideal I1=imap(newR,radIDsing);
+       iloc=vdim(std(I1));
+       if(iglob==iloc)
+       {
+          if(w>=1){"only cusps and nodes outside (0,0,1)";}
+          setring newR;
+          tau=vdim(std(I+jacob(I)));
+          tauinf=tauinf+tau;
+          inv=deltaLocMod(I[1],maxideal(1));
+          delt=inv[1];
+          tauloc=inv[2];
+          nodes=tau-tauloc-2*cusps;
+          nsing=nsing+nodes;
+          if(inv[2]!=0)
+            {
+              nsing=nsing+1;
+            }
+          nbranch=inv[3]+ 2*nodes+cusps;
+          delt=delt+nodes+cusps;
+          if((w>=1)&&(inv[2]==0)){"smooth at (0,0,1)";}
+          if(inv[4]!=0)
+            {
+              OMPButNodes = insert(OMPButNodes,list(inv[4],maxideal(1)),
+                                   sizeOMPButNodes);
+              sizeOMPButNodes = size(OMPButNodes); // new
+            }
+          else
+            {
+              NotOnlyOMPPlusCusps = NotOnlyOMPPlusCusps + 1;
+            }
+        }
+        else
+        {
+           setring newR;
+           list pr=minAssGTZ(radIDsing);
+           if(w>=1){pr;}
+
+           for(k=1;k<=size(pr);k++)
+           {
+              if(w>=1){nsing=nsing+vdim(std(pr[k]));}
+              inv=deltaLocMod(I[1],pr[k]);
+              delt=delt+inv[1];
+              tausing=tausing+inv[2];
+              nbranch=nbranch+inv[3];
+              if(inv[4]!=0)
+                {
+                  OMPButNodes = insert(OMPButNodes,list(inv[4],pr[k]),
+                                       sizeOMPButNodes);
+                  sizeOMPButNodes = size(OMPButNodes);
+                }
+              else
+                {
+                  NotOnlyOMPPlusCusps = NotOnlyOMPPlusCusps + 1;
+                }
+           }
+           tau=vdim(std(I+jacob(I)));
+           tauinf=tauinf+tau;
+           nodes=tau-tausing-2*cusps;
+           nsing=nsing+nodes;
+           delt=delt+nodes+cusps;
+           nbranch=nbranch+2*nodes+cusps;
+        }
+   }
+   genus=genus-delt-deltainf;
+   if(w>=1)
+   {
+      "The projected plane curve has locally:";"";
+      "singularities:";nsing;
+      "branches:";nbranch+nbranchinf;
+      "nodes:"; nodes+nodesinf;
+      "cusps:";cusps+cuspsinf;
+      "Tjurina number:";tauinf;
+      "Milnor number:";2*(delt+deltainf)-nbranch-nbranchinf+nsing;
+      "delta of the projected curve:";delt+deltainf;
+      //"delta of the curve:";p_a-genus;
+      "genus:";genus;
+      "====================================================";
+      "";
+   }
+   setring R;
+   if(sizeOMPButNodes>0)
+     {
+       list OMPButNodes = fetch(newR,OMPButNodes);
+     }
+   return(list(genus,NotOnlyOMPPlusCusps,OMPButNodes,
+               fetch(newR,NodesPlusCusps)));
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+static proc deltaLocMod(poly f,ideal singL)
+"USAGE:  deltaLoc(f,J);  f poly, J ideal
+ASSUME: f is reduced bivariate polynomial; basering has exactly two variables;
+        J is irreducible prime component of the singular locus of f (e.g., one
+        entry of the output of @code{minAssGTZ(I);}, I = <f,jacob(f)>).
+RETURN:  list L:
+ at texinfo
+ at table @asis
+ at item @code{L[1]}; int:
+         the sum of (local) delta invariants of f at the (conjugated) singular
+         points given by J.
+ at item @code{L[2]}; int:
+         the sum of (local) Tjurina numbers of f at the (conjugated) singular
+         points given by J.
+ at item @code{L[3]}; int:
+         the sum of (local) number of branches of f at the (conjugated)
+         singular points given by J.
+ at item @code{L[3]}; int:
+         the multiplicity of f at the (conjugated) singular points given by J,
+         if these are ordinary multiple points, and 0 otherwise.
+ at end table
+ at end texinfo
+NOTE:    procedure makes use of @code{execute}; increasing printlevel displays
+         more comments (default: printlevel=0).
+SEE ALSO: deltaLoc, delta, tjurina
+KEYWORDS: delta invariant; Tjurina number
+"
+{
+   option(redSB);
+   def R=basering;
+   execute("ring S=("+charstr(R)+"),(x,y),lp;");
+   map phi=R,x,y;
+   ideal singL=phi(singL);
+   singL=simplify(std(singL),1);
+   attrib(singL,"isSB",1);
+   int d=vdim(singL);
+   poly f=phi(f);
+   int i;
+   int w = printlevel-voice+2;  // w=printlevel (default: w=0)
+   if(d==1)
+   {
+      map alpha=S,var(1)-singL[2][2],var(2)-singL[1][2];
+      f=alpha(f);
+      execute("ring C=("+charstr(S)+"),("+varstr(S)+"),ds;");
+      poly f=imap(S,f);
+      ideal singL=imap(S,singL);
+      if((w>=1)&&(ord(f)>=2))
+      {
+        "local analysis of the singularities";"";
+        basering;
+        singL;
+        f;
+        pause();
+      }
+   }
+   else
+   {
+      poly p;
+      poly c;
+      map psi;
+      number co;
+
+      while((deg(lead(singL[1]))>1)&&(deg(lead(singL[2]))>1))
+      {
+         psi=S,x,y+random(-100,100)*x;
+         singL=psi(singL);
+         singL=std(singL);
+          f=psi(f);
+      }
+
+      if(deg(lead(singL[2]))==1)
+      {
+         p=singL[1];
+         c=singL[2]-lead(singL[2]);
+         co=leadcoef(singL[2]);
+      }
+      if(deg(lead(singL[1]))==1)
+      {
+         psi=S,y,x;
+         f=psi(f);
+         singL=psi(singL);
+         p=singL[2];
+         c=singL[1]-lead(singL[1]);
+         co=leadcoef(singL[1]);
+      }
+
+      execute("ring B=("+charstr(S)+"),a,dp;");
+      map beta=S,a,a;
+      poly p=beta(p);
+
+      execute("ring C=("+charstr(S)+",a),("+varstr(S)+"),ds;");
+      number p=number(imap(B,p));
+      minpoly=p;
+
+      map iota=S,a,a;
+      number c=number(iota(c));
+      number co=iota(co);
+
+      map alpha=S,x-c/co,y+a;
+      poly f=alpha(f);
+      f=cleardenom(f);
+      if((w>=1)&&(ord(f)>=2))
+      {
+        "local analysis of the singularities";"";
+        basering;
+        alpha;
+        f;
+        pause();
+        "";
+      }
+   }
+   int intMult = deg(lead(f));
+   poly fdummy = f;
+   poly gdummy = lead(f);
+   int ivr = 1;
+   while(ivr)
+      {
+        fdummy = fdummy - lead(fdummy);
+        if((fdummy ==0) || (deg(lead(fdummy))>intMult)){break;}
+        gdummy = gdummy + lead(fdummy);
+      }
+   poly SQRpart = sqrfree(gdummy, 3);
+   int IntForRet;
+   if(deg(SQRpart)==intMult)
+     {
+        IntForRet = intMult;
+     }
+   option(noredSB);
+   ideal fstd=std(ideal(f)+jacob(f));
+   poly hc=highcorner(fstd);
+   int tau=vdim(fstd);
+   int o=ord(f);
+   int delt,nb;
+
+   if(tau==0)                 //smooth case
+   {
+      setring R;
+      return(list(0,0,1,0));
+   }
+   if((char(basering)>=181)||(char(basering)==0))
+   {
+      if(o==2)                //A_k-singularity
+      {
+        if(w>=1){"A_k-singularity";"";}
+         setring R;
+         delt=(tau+1) div 2;
+         return(list(d*delt,d*tau,d*(2*delt-tau+1),IntForRet));
+      }
+      if((lead(f)==var(1)*var(2)^2)||(lead(f)==var(1)^2*var(2)))
+      {
+        if(w>=1){"D_k- singularity";"";}
+
+         setring R;
+         delt=(tau+2) div 2;
+         return(list(d*delt,d*tau,d*(2*delt-tau+1),IntForRet));
+      }
+
+      int mu=vdim(std(jacob(f)));
+      poly g=f+var(1)^mu+var(2)^mu;  //to obtain a convenient Newton-polygon
+
+      list NP=newtonpoly(g);
+      if(w>=1){"Newton-Polygon:";NP;"";}
+      int s=size(NP);
+
+      if(is_NND(f,mu,NP))
+      { // the Newton-polygon is non-degenerate
+        // compute nb, the number of branches
+        for(i=1;i<=s-1;i++)
+        {
+          nb=nb+gcd(NP[i][2]-NP[i+1][2],NP[i][1]-NP[i+1][1]);
+        }
+        if(w>=1){"Newton-Polygon is non-degenerated";"";}
+        return(list(d*(mu+nb-1) div 2,d*tau,d*nb,IntForRet));
+      }
+
+      if(w>=1){"Newton-Polygon is degenerated";"";}
+
+      // the following can certainly be made more efficient when replacing
+      // 'hnexpansion' (used only for computing number of branches) by
+      // successive blowing-up + test if Newton polygon degenerate:
+      if(s>2)    //  splitting of f
+      {
+         if(w>=1){"Newton polygon can be used for splitting";"";}
+         intvec v=NP[1][2]-NP[2][2],NP[2][1];
+         int de=w_deg(g,v);
+         int st=w_deg(hc,v)+v[1]+v[2];
+         poly f1=var(2)^NP[2][2];
+         poly f2=jet(g,de,v)/var(2)^NP[2][2];
+         poly h=g-f1*f2;
+         de=w_deg(h,v);
+         poly k;
+         ideal wi=var(2)^NP[2][2],f2;
+         matrix li;
+         while(de<st)
+         {
+           k=jet(h,de,v);
+           li=lift(wi,k);
+           f1=f1+li[2,1];
+           f2=f2+li[1,1];
+           h=g-f1*f2;
+           de=w_deg(h,v);
+         }
+         nb=deltaLocMod(f1,maxideal(1))[3]+deltaLocMod(f2,maxideal(1))[3];
+         setring R;
+         return(list(d*(mu+nb-1) div 2,d*tau,d*nb,IntForRet));
+      }
+
+      f=jet(f,deg(hc)+2);
+      if(w>=1){"now we have to use Hamburger-Noether (Puiseux) expansion";}
+      ideal fac=factorize(f,1);
+      if(size(fac)>1)
+      {
+         nb=0;
+         for(i=1;i<=size(fac);i++)
+         {
+            nb=nb+deltaLocMod(fac[i],maxideal(1))[3];
+         }
+         setring R;
+         return(list(d*(mu+nb-1) div 2,d*tau,d*nb,IntForRet));
+      }
+      list HNEXP=hnexpansion(f);
+      if (typeof(HNEXP[1])=="ring") {
+        def altring = basering;
+        def HNEring = HNEXP[1]; setring HNEring;
+        nb=size(hne);
+        setring R;
+        kill HNEring;
+      }
+      else
+      {
+        nb=size(HNEXP);
+      }
+      return(list(d*(mu+nb-1) div 2,d*tau,d*nb,IntForRet));
+   }
+   else             //the case of small characteristic
+   {
+      f=jet(f,deg(hc)+2);
+      if(w>=1){"now we have to use Hamburger-Noether (Puiseux) expansion";}
+      delt=delta(f);
+      return(list(d*delt,d*tau,d,IntForRet));
+   }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+proc paraConic(poly q)
+"USAGE:  paraConic(q); q poly
+ASSUME:  The basering must be a polynomial ring in three variables with
+         coefficients in Q. @*
+         The polynomial q must be homogeneous of degree 2 and absolutely
+         irreducible. @*
+NOTE:    The procedure might fail or give a wrong output if the assumptions
+         do not hold.
+
+RETURN:  ring with an ideal PARACONIC. The ring should be considered as the
+         homogeneous coordinate ring of PP^1, the ideal defines a rational
+         parametrization PP^1 --> C2 = {q=0}.
+
+THEORY:  We compute a point on C2 via @ref{rationalPointConic}. The pencil of
+         lines through this point projects C2 birationally to PP^1. Inverting
+         the projection gives the result.
+KEYWORDS: conic, parametrization, rational point.
+SEE ALSO: rationalPointConic.
+EXAMPLE: example paraConic; shows an example
+"
+{
+  def Roriginal = basering;
+  def RP2 = projConic(q);  // ring with ideal Ipoint
+                           // possibly defined over algebraic number field
+  setring RP2;
+  def rp1 = invertBirMap(Ipoint, ideal(fetch(Roriginal,q)));
+  setring rp1;
+  list rl = ringlist(rp1);
+  rl[2] = list("s","t");
+  def RP1 = ring(rl);
+  setring RP1;
+  ideal PARACONIC = fetch(rp1,psi);
+  export(PARACONIC);
+  "// 'paraConic' created a ring together with an ideal RNC.";
+  "// Supposing you typed, say,  def RP1 = paraConic(q);";
+  "// you may access the ideal by typing";
+  "//      setring RP1; PARACONIC;";
+  return(RP1);
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring R = 0,(x,y,z),dp;
+  poly f = y^8-x^3*(z+x)^5;
+  ideal adj = adjointIdeal(f);
+  def Rn = invertBirMap(adj,ideal(f));
+  setring(Rn);
+  J;
+  def Rc = rncItProjEven(J);
+  PHI;
+  setring Rc;
+  CONIC;
+  def RPc = paraConic(CONIC);
+  setring RPc;
+  PARACONIC;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static proc projConic(poly q)
+"USAGE:  projConic(q); q poly
+ASSUME:  The basering must be a polynomial ring in three variables with
+         coefficients in Q. @*
+         The polynomial q must be homogeneous of degree 2 and absolutely
+         irreducible. @*
+NOTE:    The procedure might fail or give a wrong output if the assumptions
+         do not hold.
+RETURN:  ring with an ideal Ipoint defining a pencil of lines through a point
+         on the conic C2 = {q=0}. This point has either coefficients in Q or
+         in a quadratic extension field of Q.
+THEORY:  We compute the point on C2 via @ref rationalPointConic.
+KEYWORDS: conic, parametrization, rational point.
+SEE ALSO: rationalPointConic.
+"
+{
+  def Roriginal = basering;
+  list rl = ringlist(Roriginal);
+  rl[3] = list(list("dp",1:3),list("C",0));
+  def RP20 = ring(rl);
+  setring RP20;
+  poly q = imap(Roriginal,q);
+  def RP21 = rationalPointConic(q);  //  ring with ideal point representing
+                                     //  point on conic
+                                     //  possibly defined over algebraic number
+                                     //  field
+  setring RP21;
+  list rl1 = ringlist(RP21);
+  rl1[2] = list("u","v","w");
+  rl1[3] = list(list("dp",1:3),list("C",0));
+  def RP2 = ring(rl1);
+  setring RP2;
+  ideal point = fetch(RP21,point);
+  matrix bP = syz(point);
+  ideal Ipoint = matrix(maxideal(1))*bP;  // defines pencil of lines through
+                                          // point
+  export(Ipoint);
+  return(RP2);
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+static proc isIrreducible(poly f)
+"USAGE:  isIrreducible(f); f poly
+RETURN:  1 iff the given polynomial f is irreducible; 0 otherwise.
+THEORY:  This test is performed by computing the absolute factorization of f.
+KEYWORDS: irreducible.
+"
+{
+  def r = basering;
+  def s = absFactorize(f);
+  setring s;
+  list L = absolute_factors;
+  int result = 0;
+  if (L[4] == 1){result = 1;}
+  setring r;
+  kill s;
+  return (result);
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+static proc isQuadratic(poly p)
+"USAGE:  isQuadratic(p); p poly
+RETURN:  checks whether p is a homogeneous, quadratic polynomial in the
+         first three ring variables, x, y, z say;
+         If so, the method extracs the coefficients a, b, ..., f such that
+         p = a*x2 + b*xy + c * y2 + d * xz + e * yz + f * z2
+         and returns them as a list of seven entries, [1, a, b, c, d, e, f];
+         otherwise, a list with the single entry [0] is returned
+"
+{
+  bigint a = bigint(leadcoef(subst(p, var(2), 0, var(3), 0)));
+  bigint c = bigint(leadcoef(subst(p, var(1), 0, var(3), 0)));
+  bigint f = bigint(leadcoef(subst(p, var(1), 0, var(2), 0)));
+  poly h = p - a * var(1)^2 - c * var(2)^2 - f * var(3)^2;
+  bigint b = bigint(leadcoef(subst(h, var(3), 0)));
+  bigint d = bigint(leadcoef(subst(h, var(2), 0)));
+  bigint e = bigint(leadcoef(subst(h, var(1), 0)));
+  list L = 0;
+  if (h - b * var(1) * var(2) - d * var(1) * var(3)
+        - e * var(2) * var(3) != 0) { return (L); }
+  L = 1, a, b, c, d, e, f;
+  return (L);
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+static proc largestSquare(bigint n)
+"USAGE:  largestSquare(n); n bigint
+ASSUME:  n <> 0
+RETURN:  returns the largest positive number m (as bigint) such that m^2
+         divides n.
+THEORY:  This computation is done by prime factorization of n.
+KEYWORDS: prime factorization.
+"
+{
+  if (n == 0) { "ERROR: largestSquare(0) had been invoked"; }
+
+  bigint nn = n; if (nn < 0) { nn = -n; }
+  list L = primefactors(nn);
+  if (L[3] != 1)
+  { "WARNING: command 'primefactors(.)' did not find all prime factors"; }
+  int i; bigint m = bigint(1); int e; int j;
+  for (i = 1; i <= size(L[1]); i++)
+  {
+    e = L[2][i] div 2;
+    for (j = 1; j <= e; j++) { m = m * bigint(L[1][i]); }
+  }
+  return (m);
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+static proc jIndex(bigint a, bigint b, bigint c)
+"USAGE:  jIndex(a, b, c); a, b, c bigint's
+RETURN:  returns the middle of the three numbers |ab|, |bc|, and |ca|.
+"
+{
+  bigint n1 = a*b; if (n1 < 0) { n1 = -n1; }
+  bigint n2 = b*c; if (n2 < 0) { n2 = -n2; }
+  bigint n3 = c*a; if (n3 < 0) { n3 = -n3; }
+  if ((n1 <= n2) && (n2 <= n3)) { return (n2); }
+  if ((n1 >= n2) && (n2 >= n3)) { return (n2); }
+  if ((n2 <= n1) && (n1 <= n3)) { return (n1); }
+  if ((n2 >= n1) && (n1 >= n3)) { return (n1); }
+  return (n3);
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+static proc aMod(bigint a, bigint b)
+"USAGE:  aMod(a,b); a, b bigint
+RETURN:  r bigint
+THEORY:  The asymmetric residue r of the division with remainder a mod b.
+"
+{
+  bigint c = a mod b;
+  if (c<0)
+  {
+    return(c+b);
+  }
+return(c);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static proc aDiv(bigint a, bigint b)
+"USAGE:  aDiv(a,b); a, b bigint
+RETURN:  q bigint
+THEORY:  Quotient with remainder q = a div b with asymmetric residue.
+"
+{
+  bigint q = a div b;
+  if ((a mod b)<0)
+  {
+    return(q-1);
+  }
+return(q);
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+static proc polyModP(poly q, bigint p)
+"USAGE:  polyModP(q, p); q poly, p bigint
+RETURN:  takes each coefficient of q modulo p and returns the resulting poly
+"
+{
+  poly qq = q; poly res = 0;
+  bigint c;
+  while (qq != 0)
+  {
+    c = bigint(leadcoef(qq)) mod p;
+    res = res + c * leadmonom(qq);
+    qq = qq - lead(qq);
+  }
+  return (res);
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+static proc rootModP(bigint r, bigint p)
+"USAGE:  rootModP(r, p); r, p bigint's
+ASSUME:  0 <= r < p, and p prime;
+         Furthermore it is assumes that there is some x in {0, 1, ..., p-1}
+         such that x^2 = r mod p;
+RETURN:  an x in {0, 1, ..., p-1} such that x^2 = r mod p;
+THEORY:  For p larger than 32003, this computation is done using Cantor-
+         Zassenhaus' algorithm. Otherwise a brute force approach is used.
+KEYWORDS: Cantor-Zassenhaus algorithm.
+"
+{
+  if (r == 0) { return (0); }
+  if (r == 1) { return (1); }
+  if (p <= 32003)
+  {
+    /* For small p, we use a brute force approach: */
+    int i;
+    for (i = 2; i < p; i++)
+    {
+      if (((i*i) mod p) == r) { return (i); }
+    }
+    /* should never be reached: */
+    return (-1);
+  }
+
+  /* For p > 32003, we use Cantor-Zassenhaus' algorithm: */
+  def br = basering;
+  ring rTemp = 0, x, dp;
+  bigint b; bigint exponent; poly factor;
+  poly h = x^2 - r;
+  ideal redI = h; redI = std(redI);
+  poly q = x^2; bigint root = 0;
+  while (root == 0)
+  {
+    b = bigint(random(1, 2^30));
+    exponent = bigint((p - 1) div 2);
+    /* We need to compute q^exponent mod (x^2 - a) and mod p: */
+    factor = x + b; q = 1;
+    while (exponent > 0)
+    {
+      if ((exponent mod 2) == 1)
+      {
+        q = q * factor;
+        q = reduce(q, redI);
+        q = polyModP(q, p);
+      }
+      exponent = bigint(exponent div 2);
+      factor = factor * factor;
+      factor = reduce(factor, redI);
+      factor = polyModP(factor, p);
+    }
+    if (deg(q) == 1)
+    {
+      q = q - 1;
+      b = inverseModP(bigint(leadcoef(q)), p);
+      q = q - lead(q);
+      root = aMod((bigint(q) * b),p);
+      if (((root * root - r) mod p) != 0) { root = 0; }
+    }
+  }
+  setring br; kill rTemp;
+  return (root);
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+static proc inverseModP(bigint r, bigint p)
+"USAGE:  inverseModP(r, p); r, p bigint's
+ASSUME:  0 <= r < p, and r and p coprime;
+RETURN:  returns the inverse of r in Z/p represented by an element in
+         {1, 2, ..., p-1}
+THEORY:  This uses Euclid's extended gcd algorithm.
+"
+{
+  list L = extgcd(r, p);
+  if (L[1] != 1) { ERROR("GCD of", r, "and", p, "should be 1."); }
+  L[2] = aMod(L[2],p);
+  return (L[2]);
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+static proc squareRoot(bigint r, bigint m, int justCheck)
+"USAGE:  squareRoot(r, m, j); r, m bigint's, j int
+RETURN:  checks whether r is a square modulo m, i.e., checks whether there is
+         some x such that x^2 = r mod m;
+         If justCheck is 1, then the method will terminate after the check
+         and return 1 if r is a square and -1 otherwise.
+         If justCheck is 0 and r is a square, then the method continues and
+         computes a solution x in {0, 1, m-1} with x^2 = r mod m, which will
+         then be returned
+THEORY:  This algorithm checks solvability by computing the Legendre symbols
+         modulo all primes in m. Then, individual roots will be computed and
+         lifted to the desired square root modulo m using Chinese
+         remaindering.
+"
+{
+  if (m == 0) { "ERROR: squareRoot had been invoked with m = 0"; }
+
+  list L = primefactors(m);
+  if ((L[3] != 1) && (L[3] != -1))
+  { "WARNING: command 'primefactors(.)' did not find all prime factors"; }
+  int i;
+  for (i = 1; i <= size(L[2]); i++)
+  {
+    if (legendreSymbol(r, L[1][i]) == -1) { return (-1); }
+  }
+  /* now we know that there is some x in {0, 1, m-1} with
+     x^2 = r mod m */
+  if (justCheck == 1) { return (1); }
+  else
+  {
+    // now we need to compute x; this works in two stages:
+    // 1) write m = p1^e1 * ... * pk^ek (we already have that),
+    // 2) for each i in {1, 2, ..., k}
+    //    2.1) compute a yi such that yi^2 = r mod pi,
+    //    2.2) lift yi to an xi such that xi^2 = r mod (pi^ei),
+    // 3) lift (x1, x2, ..., xk) in Z/p1^e1 * ... * Z/pk^ek
+    //    to x in Z/m via Chinese remainder theorem
+
+    list roots;
+    // 2.1):
+    for (i = 1; i <= size(L[1]); i++)
+    {
+      roots = insert(roots, rootModP(aMod(r,L[1][i]), L[1][i]), size(roots));
+    }
+
+    // 2.2):
+    bigint c; bigint l; bigint temp; bigint pPower; int e;
+    for (i = 1; i <= size(roots); i++)
+    {
+      pPower = bigint(L[1][i]);
+      for (e = 2; e <= L[2][i]; e++)
+      {
+        c = bigint(roots[i]); l = pPower;
+        temp = r - c * c; l = bigint(2) * c * l; c = temp;
+        c = aDiv(c,pPower); l = aDiv(l,pPower);
+        c = aMod(c,L[1][i]); l = aMod(l,L[1][i]);
+        c = aMod((c * bigint(inverseModP(l, L[1][i]))), L[1][i]);
+        c = bigint(roots[i]) + c * pPower;
+        pPower = pPower * L[1][i]; roots[i] = c;
+      }
+    }
+
+    // 2.3):
+    list mm; bigint z; int j;
+    for (i = 1; i <= size(L[1]); i++)
+    {
+      z = bigint(L[1][i]);
+      for (j = 2; j <= L[2][i]; j++)
+      {
+        z = z * bigint(L[1][i]);
+      }
+      mm = insert(mm, z, size(mm));
+    }
+    return (aMod(chinrem(roots, mm) , m));
+  }
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+static proc chineseRemainder(list rr, list mm)
+"USAGE:  chineseRemainder(rr, mm); rr, mm lists of bigint's
+ASSUME:  lists rr and mm must have same sizes;
+         Furthermore the entries of mm must be mutually coprime.
+RETURN:  an x which fulfills the simultaneous remainder conditions
+         x = rr[i] mod mm[i], 1 <= i <= size(rr)
+KEYWORDS: Chinese remainder.
+"
+{
+  bigint x = bigint(0); int i; bigint N; list l;
+  bigint M = bigint(mm[1]);
+  for (i = 2; i <= size(mm); i++) { M = M * bigint(mm[i]); }
+  for (i = 1; i <= size(mm); i++)
+  {
+    N = aDiv(M,mm[i]);
+    l = extgcd(mm[i], N);
+    x = x + rr[i]*l[3]*N;
+  }
+  return (x);
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+static proc rationalPointSpecial(bigint b1, bigint c1)
+"USAGE:  rationalPointSpecial(b1, c1); b1, c1 bigint's
+ASSUME:  b1 <> 0 and c1 <> 0;
+RETURN:  with poly p = var(1)^2 + b1 * var(2)^2 + c1 * var(3)^2, the method
+         returns a list L with either one entry or four entries:
+         case 'three entries':
+           L[1] = 0 signaling that there is no rational point on V(p),
+           L[2] the largest number b such that b^2 divides b1
+                (for subsequent use by the caller of this method),
+           L[3] the largest number c such that c^2 divides c1
+                (for subsequent use by the caller of this method);
+         case 'four entries':
+           L[1] = 1 signaling that there is a rational point on V(p),
+           L[2], L[3], L[4] rational numbers such that the tuple
+                (L[2], L[3], L[4]) is on V(p)
+"
+{
+  if (b1 == 0) { "ERROR: rationalPointSpecial(0, c1) had been invoked"; }
+  if (c1 == 0) { "ERROR: rationalPointSpecial(b1, 0) had been invoked"; }
+
+  bigint b_s = largestSquare(b1); bigint b_r = b1/b_s/b_s;
+  bigint c_s = largestSquare(c1); bigint c_r = c1/c_s/c_s;
+  bigint g = gcd(b_r, c_r);
+  def S=basering;
+  ideal mi = maxideal(1);
+  map mm = basering, mi; map mTemp;
+  mm[1] = var(1); mm[2] = var(2)/b_s/g; mm[3] = var(3)/c_s/g;
+  bigint a = g;     bigint aa = a; if (aa <= 0) { aa = -aa; }
+  bigint b = b_r/g; bigint bb = b; if (bb <= 0) { bb = -bb; }
+  bigint c = c_r/g; bigint cc = c; if (cc <= 0) { cc = -cc; }
+  bigint R1 = squareRoot(-a*b, cc, 1);
+  if (R1 == -1) { list L = 0, b_s, c_s; return (L); }
+  bigint R2 = squareRoot(-a*c, bb, 1);
+  if (R2 == -1) { list L = 0, b_s, c_s; return (L); }
+  bigint R3 = squareRoot(-b*c, aa, 1);
+  if (R3 == -1) { list L = 0, b_s, c_s; return (L); }
+  bigint t; bigint r1; bigint Q; bigint A; bigint B; bigint C;
+  bigint alpha; bigint beta; bigint gamma;
+  while (jIndex(a, b, c) > 1)
+  {
+    mTemp = basering, mi;
+    if (aa > cc)
+    {
+      t = a; a = c; c = t;
+      t = aa; aa = cc; cc = t;
+      mTemp = basering, mi;
+      mTemp[1] = var(3); mTemp[3] = var(1); mm = mTemp(mm);
+    }
+    if (bb > cc)
+    {
+      t = b; b = c; c = t;
+      t = bb; bb = cc; cc = t;
+      mTemp = basering, mi;
+      mTemp[2] = var(3); mTemp[3] = var(2); mm = mTemp(mm);
+    }
+    if (bb < aa)
+    {
+      t = b; b = a; a = t;
+      t = bb; bb = aa; aa = t;
+      mTemp = basering, mi;
+      mTemp[1] = var(2); mTemp[2] = var(1); mm = mTemp(mm);
+    }
+    /* now, we have established |a| <= |b| <= |c|; and permuted
+       the map mm, accordingly */
+    cc = c; if (cc <= 0) { cc = -cc; }
+    R1 = squareRoot(-a*b, cc, 0);
+    r1 = aMod((R1 * inverseModP(a, cc)), cc);
+    if (r1*bigint(2) > cc) { r1 = r1 - cc; }
+    Q = (a*r1*r1 + b)/c;
+    if (Q == 0)
+    {
+      list L = 1, subst(mm[1], var(1), 1, var(2), 1, var(3), 0),
+                  subst(mm[2], var(1), 1, var(2), 1, var(3), 0),
+                  subst(mm[3], var(1), 1, var(2), 1, var(3), 0);
+      return (L);
+    }
+    A = gcd(gcd(a*r1*r1, b), c*Q);
+    alpha = r1/A; beta = b/A;
+    B = a*beta;
+    gamma = largestSquare(Q/A);
+    C = Q/A/gamma/gamma;
+    mTemp = basering, mi;
+    mTemp[1] = A*alpha*var(1) - beta*var(2);
+    mTemp[2] = var(1) + a*alpha*var(2);
+    mTemp[3] = C*gamma*var(3);
+    mm = mTemp(mm);
+    a = A; b = B; c = C;
+    aa = a; if (aa <= 0) { aa = -aa; }
+    bb = b; if (bb <= 0) { bb = -bb; }
+    cc = c; if (cc <= 0) { cc = -cc; }
+  }
+  if (a*b < 0)
+  {
+    list L = 1, subst(mm[1], var(1), 1, var(2), 1, var(3), 0),
+                subst(mm[2], var(1), 1, var(2), 1, var(3), 0),
+                subst(mm[3], var(1), 1, var(2), 1, var(3), 0);
+    return (L);
+  }
+  if (a*c < 0)
+  {
+    list L = 1, subst(mm[1], var(1), 1, var(2), 0, var(3), 1),
+                subst(mm[2], var(1), 1, var(2), 0, var(3), 1),
+                subst(mm[3], var(1), 1, var(2), 0, var(3), 1);
+    return (L);
+  }
+  if (b*c < 0)
+  {
+    list L = 1, subst(mm[1], var(1), 0, var(2), 1, var(3), 1),
+                subst(mm[2], var(1), 0, var(2), 1, var(3), 1),
+                subst(mm[3], var(1), 0, var(2), 1, var(3), 1);
+    return (L);
+  }
+  list L = 0, b_s, c_s; return (L);
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+static proc extendedEuclid(bigint a, bigint b)
+"USAGE:  extendedEuclid(a, b); a, b bigint's
+ASSUME:  a <> 0 or b <> 0;
+RETURN:  returns a list with three entries:
+         _[1]: gcd(a,b) > 0,
+         _[2], _[3]: s, t, such that s*a + t*b = gcd(a,b)
+KEYWORDS: extended Euclidean algorithm.
+"
+{
+  list l = 0; bigint temp;
+  if (a == 0)         { l = b, 0, 1; if (b < 0) { l = -b, 0, -1; } }
+  if (b == 0)         { l = a, 1, 0; if (a < 0) { l = -a, -1, 0; } }
+  if (aMod(a , b) == 0) { l = b, 0, 1; if (b < 0) { l = -b, 0, -1; } }
+  if (aMod(b , a) == 0) { l = a, 1, 0; if (a < 0) { l = -a, -1, 0; } }
+  if (size(l) > 1) { return (l); }
+
+  temp = aMod(a , b);
+  l = extendedEuclid(b, temp);
+  temp = (a - temp) / b;
+  temp = bigint(l[2]) - temp * bigint(l[3]);
+  l = l[1], l[3], temp;
+  return (l);
+}
+
+static proc legendreSymbol(bigint r, bigint p)
+"assumes p prime;
+returns the Legendre symbol (r/p), that is
+ 1 if r appears as residue modulo p of a square,
+-1 if not,
+ 0 if r is a multiple of p
+"
+{
+  bigint rr = aMod(r , p);
+  if (rr == 0) { return (0) }
+  if (rr == 1) { return (1) }
+  /* now, p must be at least 3 */
+  bigint e = (p - 1) / bigint(2);
+  bigint result = 1;
+  bigint power = rr;
+  while (e > 0)
+  {
+    if ((e mod 2) == 1) { result = aMod((result * power), p); }
+    e = e / bigint(2);
+    power = aMod((power * power), p);
+  }
+  if (result > 1) { result = result - p; /* should be -1 */ }
+  return (result);
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+static proc buildExtension(bigint b, bigint c, bigint bs, bigint cs)
+"USAGE:  buildExtension(b, c, bs, cs); b, c, bs, cs bigint's
+ASSUME:  assumes that bs is the largest positive number such that bs^2
+         divides b; analogously for cs regarding c;
+         Assumes furthermore that there is no rational point on the conic
+         X^2 + b*Y^2 + c*Z^2 = 0.
+         Assumes that the ground field of the basering is Q.
+RETURN:  builds an appropriate quadratic field extension Q(a) in which a
+         point exists that lies on the given conic. This point is stored in
+         a newly defined and exported (1x3) matrix named 'point'.
+         The method returns the resulting polynomial ring over Q(a).
+"
+{
+  bigint br = b/bs/bs;
+  bigint cr = c/cs/cs;
+  /* X^2 + br*bs^2*Y^2 + cr*cs^2*Z^2 = 0 */
+  def bRing = basering;
+  list L = ringlist(bRing);
+
+  if (b != 0)
+  {
+    L[1] = list(0, list("a"), list(list("lp", 1)), ideal(0));
+    def RTemp = ring(L);
+    setring RTemp; list L = ringlist(RTemp);
+    L[1][4] = ideal(a^2 + br);
+    def R = ring(L);
+    setring R; kill RTemp;
+    matrix point[1][3];
+    point[1, 1] = a * bs; point[1, 2] = 1; point[1, 3] = 0;
+    export point;
+    setring bRing;
+    return (R);
+  }
+  if (c != 0)
+  {
+    L[1] = list(0, list("a"), list(list("lp", 1)), ideal(0));
+    def RTemp = ring(L);
+    setring RTemp; list L = ringlist(RTemp);
+    L[1][4] = ideal(a^2 + cr);
+    def R = ring(L);
+    setring R; kill RTemp;
+    matrix point[1][3];
+    point[1, 1] = a * cs; point[1, 2] = 0; point[1, 3] = 1;
+    export point;
+    setring bRing;
+    return (R);
+  }
+
+  "ERROR: unexpectedly encountered conic X^2 + 0*Y^2 + 0*Z^2 = 0";
+  return (bRing);
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+static proc testRationalPointConic(poly pp)
+"USAGE:  testRationalPointConic(pp); pp poly
+RETURN:  returns 0 in case of unexpected input (e.g. non-quadratic,
+         reducible); 1 otherwise
+NOTE:    This method calles rationalPointConic, measures time consumption
+         and checks whether the computed point lies indeed on the conic pp.
+         The results will be printed to standard output.
+"
+{
+  "testing rationalPointConic(poly) for poly p:";
+  "p =", pp;
+  if (isQuadratic(pp)[1] == 1) { "p is quadratic."; }
+  else                         { "p is not quadratic.";   return (0); }
+  if (isIrreducible(pp) == 1)  { "p is irreducible."; }
+  else                         { "p is not irreducible."; return (0); }
+  def rOrig = basering;
+  int t = rtimer;
+  def rNew = rationalPointConic(pp);
+  t = rtimer - t;
+  "time for finding a point on the conic [sec] =", t;
+  setring rNew;
+  poly ff = fetch(rOrig, pp);
+  if (minpoly == 0)
+  { "there is a rational point on the conic p";
+    "x =", point[1,1], "  y =", point[1,2], "  z =", point[1,3];
+    "check (should be zero):", subst(ff, var(1), point[1,1],
+                                         var(2), point[1,2],
+                                         var(3), point[1,3]);
+  }
+  else
+  {
+    "there is no rational point on the conic p";
+    "but there is a point on the conic in the field extension Q(a),";
+    "with minpoly =", minpoly;
+    "x =", point[1,1], "  y =", point[1,2], "  z =", point[1,3];
+    "check (should be zero):", subst(ff, var(1), point[1,1],
+                                         var(2), point[1,2],
+                                         var(3), point[1,3]);
+  }
+  setring rOrig;
+}
+
+example
+{ "EXAMPLE:"; echo=2;
+  ring r = 0, (x,y,z, u, v, w), dp;
+  poly p = x^2 + 2*y^2 + 5*z^2 - 4*x*y + 3*x*z + 17*y*z;
+  testRationalPointConic(p);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+proc rationalPointConic(poly p)
+"USAGE:  rationalPointConic(p); p poly
+ASSUME:  assumes that p is an irreducible quadratic polynomial in the first
+         three ring variables;
+         ground field is expected to be Q.
+RETURN:  The method finds a point on the given conic. There are two
+         possibilities:
+         1) There is a rational point on the curve.
+         2) There is no rational point on the curve.
+         In the second case, the method creates a modification of the current
+         basering which is a polynomial ring over some quadratic field
+         extension Q(a) of Q. Apart from the replacement of Q by Q(a), the
+         new polynomial ring, R say, is the same as the original basering.
+         (In the first case, R is identical with the basering.)
+         In both cases, the method will then define a (1x3) matrix named
+         'point' which lives in R and which contains the coordinates of the
+         desired point on q.
+         Finally, the method returns the ring R (which will in the 1st case
+         be the original base ring).
+EXAMPLE: example rationalPointConic; shows an example
+"
+{
+  list L = isQuadratic(p);
+  bigint a = bigint(L[2]); bigint b = bigint(L[3]); bigint c = bigint(L[4]);
+  bigint d = bigint(L[5]); bigint e = bigint(L[6]); bigint f = bigint(L[7]);
+  bigint x; bigint y; bigint z; bigint nn;
+  def R = basering;
+
+  if (b^2 == 4*a*c)
+  {
+    if (c == 0)
+    {
+      x = -2*d*e; y = d^2-4*a*f; z = e*4*a;
+      nn = gcd(gcd(absValue(x), absValue(y)), absValue(z));
+      matrix point[1][3];
+      point[1, 1] = x/nn; point[1, 2] = y/nn; point[1, 3] = z/nn;
+      export point; return (R);
+    }
+    else
+    {
+      bigint fs = 4*c*f - e^2;
+      bigint ds = 4*c*d - 2*b*e;
+      x = -fs*2*c; y = b*fs-e*ds; z = ds*2*c;
+      nn = gcd(gcd(absValue(x), absValue(y)), absValue(z));
+      matrix point[1][3];
+      point[1, 1] = x/nn; point[1, 2] = y/nn; point[1, 3] = z/nn;
+      export point; return (R);
+    }
+  }
+
+  if (d^2 == 4*a*f)
+  {
+    if (f == 0)
+    {
+      x = -b*e*2; y = e*4*a; z = b^2-4*a*c;
+      nn = gcd(gcd(absValue(x), absValue(y)), absValue(z));
+      matrix point[1][3];
+      point[1, 1] = x/nn; point[1, 2] = y/nn; point[1, 3] = z/nn;
+      export point; return (R);
+    }
+    else
+    {
+      bigint c_s = 4*c*f - e^2;
+      bigint b_s = 4*f*b - 2*d*e;
+      x = -c_s*2*f; y = b_s*2*f; z = d*c_s-e*b_s;
+      nn = gcd(gcd(absValue(x), absValue(y)), absValue(z));
+      matrix point[1][3];
+      point[1, 1] = x/nn; point[1, 2] = y/nn; point[1, 3] = z/nn;
+      export point; return (R);
+    }
+  }
+
+  if (e^2 == 4*c*f)
+  {
+    if (c == 0)
+    {
+      x = b*4*f; y = d^2-4*a*f; z = -b*d*2;
+      nn = gcd(gcd(absValue(x), absValue(y)), absValue(z));
+      matrix point[1][3];
+      point[1, 1] = x/nn; point[1, 2] = y/nn; point[1, 3] = z/nn;
+      export point; return (R);
+    }
+    else
+    {
+      bigint as = 4*c*a - b^2;
+      bigint ds = 4*c*d - 2*b*e;
+      x = ds*2*c; y = e*as-b*ds; z = -as*2*c;
+      nn = gcd(gcd(absValue(x), absValue(y)), absValue(z));
+      matrix point[1][3];
+      point[1, 1] = x/nn; point[1, 2] = y/nn; point[1, 3] = z/nn;
+      export point; return (R);
+    }
+  }
+
+  ideal mi = maxideal(1);
+  map mm = R, mi;
+  bigint B; bigint C; bigint D;
+
+  if ((a == 0) && (c == 0))
+  {
+    B = -1; C = 4*b*f - 4*d*e;
+    /* now, b <> 0 since otherwise p would have the factor z,
+       and hence not be irreducible */
+    mm[1] = (var(1)+var(2)-2*e*var(3))/(2*b);
+    mm[2] = (var(1)-var(2)-2*d*var(3))/(2*b);
+  }
+  if ((a != 0) && (c == 0))
+  {
+    mm[1] = var(2);
+    mm[2] = var(1);
+    bigint t = a; a = c; c = t;
+    t = e; e = d; d = t;
+  }
+  if (c != 0)
+  {
+    D = 4*a*c-b^2;
+    mm[2] = (var(2)-e*var(3)-b*var(1))/(2*c);
+    map mTemp = basering, mi;
+    mTemp[1] = (var(1)-2*d*c*var(3)+b*e*var(3))/D;
+    mm = mTemp(mm);
+    B = D;
+    C = 16*a*c^2*f-4*a*c*e^2-4*b^2*c*f+4*b*c*d*e-4*c^2*d^2;
+  }
+  list K;
+  if ((B > 0) && (C >= 0)) { K = 0; }
+  if ((B >= 0) && (C > 0)) { K = 0; }
+  if (B == 0)
+  {
+    /* looking for a point on X^2 = |C| * Z^2 */
+    bigint root = largestSquare(absValue(C));
+    if (absValue(C)/root/root == 1) { K = 1, root, 0, 1; }
+    else                            { K = 0; }
+  }
+  if (C == 0)
+  {
+    /* looking for a point on X^2 = |B| * Y^2 */
+    bigint root = largestSquare(absValue(B));
+    if (absValue(B)/root/root == 1) { K = 1, root, 1, 0; }
+    else                            { K = 0; }
+  }
+  else { K = rationalPointSpecial(B, C); }
+  if (K[1] == 0)
+  {
+    /* no rational point on conic;
+       we need to move to an appropriate field extension Q(a) */
+    poly h1 = mm[1]; poly h2 = mm[2]; poly h3 = mm[3];
+    def extendedR = buildExtension(B, C, K[2], K[3]);
+    setring extendedR;
+    poly g1 = fetch(R, h1);
+    poly g2 = fetch(R, h2);
+    poly g3 = fetch(R, h3);
+    matrix temp[1][3];
+    temp[1, 1] = subst(g1, var(1), point[1, 1], var(2), point[1, 2],
+                           var(3), point[1, 3]);
+    temp[1, 2] = subst(g2, var(1), point[1, 1], var(2), point[1, 2],
+                           var(3), point[1, 3]);
+    temp[1, 3] = subst(g3, var(1), point[1, 1], var(2), point[1, 2],
+                           var(3), point[1, 3]);
+    point[1, 1] = temp[1, 1]; point[1, 2] = temp[1, 2];
+    point[1, 3] = temp[1, 3];
+    setring R;
+    return (extendedR);
+  }
+  else
+  {
+    string dummyString = string(K); // without this useless line, we
+                                    // sometimes get a seg fault because
+                                    // mm is corrupted; strange!?!?!?!?
+    number nx = number(subst(mm[1], var(1), K[2], var(2), K[3], var(3), K[4]));
+    number ny = number(subst(mm[2], var(1), K[2], var(2), K[3], var(3), K[4]));
+    number nz = number(subst(mm[3], var(1), K[2], var(2), K[3], var(3), K[4]));
+    /* the point (nx, ny, nz) is already a solution;
+       the following lines will just remove denominators and reduce
+       numerators in order to return a nice tuple from Z^3 */
+    bigint nxd = bigint(denominator(absValue(nx)));
+    bigint nyd = bigint(denominator(absValue(ny)));
+    bigint nzd = bigint(denominator(absValue(nz)));
+    nn = nxd * nyd / gcd(nxd, nyd);
+    nn =  nn * nzd / gcd(nn, nzd);
+    x = bigint(nx*nn); y = bigint(ny*nn); z = bigint(nz*nn);
+    nn = gcd(gcd(absValue(x), absValue(y)), absValue(z));
+    matrix point[1][3];
+    point[1, 1] = x/nn; point[1, 2] = y/nn; point[1, 3] = z/nn;
+    export point;
+    return (R);
+  }
+}
+
+example
+{ "EXAMPLE:"; echo=2;
+ring R = 0, (x,y,z), dp;
+system("random", 4711);
+poly p = x^2 + 2*y^2 + 5*z^2 - 4*x*y + 3*x*z + 17*y*z;
+def S = rationalPointConic(p); // quadratic field extension,
+                               // minpoly = a^2 - 2
+testPointConic(p, S);
+setring R;
+p = x^2 - 1857669520 * y^2 + 86709575222179747132487270400 * z^2;
+S = rationalPointConic(p); // same as current basering,
+                           // no extension needed
+testPointConic(p, S);
+}
+///////////////////////////////////////////////////////////////////////////////
+proc testParametrization(poly f, def rTT)
+"USAGE:  testParametrization(f, rTT); f poly, rTT ring
+ASSUME:  The assumptions on the basering and the polynomial f are as required
+         by @ref{paraPlaneCurve}. The ring rTT has two variables and contains
+         an ideal PARA (such as the ring obtained by applying
+         @ref{paraPlaneCurve} to f).
+RETURN: int which is 1 if PARA defines a parametrization of the curve
+        {f=0} and 0, otherwise.
+THEORY: We compute the polynomial defining the image of PARA
+        and compare it with f.
+KEYWORDS: Parametrization, image.
+EXAMPLE: example testParametrization; shows an example
+"
+{
+  def Roriginal = basering;
+  setring rTT;
+  /* begin workaround elimination*/
+  int k;
+  list rl = ringlist(rTT);
+  rl[2] = list("s","t","x","y","z");
+  rl[3]= list(list("dp",1:5),list("C",0));
+  def Relim = ring(rl);
+  setring Relim;
+  ideal PARA = fetch(rTT,PARA);
+  ideal JJ;
+  for(k=1;k<=3;k++)
+     {
+       JJ=JJ,var(k+2)-PARA[k];
+     }
+  ideal SJJ = std(JJ);
+  intvec HJJ = hilb(SJJ,1);
+  ideal J = eliminate(JJ,var(1)*var(2),HJJ);
+  setring rTT;
+  /*end workaround elimination*/
+  rl[2] = list("x","y","z");
+  rl[3] = list(list("dp",1:3),list("C",0));
+  def RP2 = ring(rl);
+  setring RP2;
+  ideal f = fetch(Roriginal,f);
+  ideal ftest = imap(Relim,J);
+  poly g = reduce(f[1],std(ftest));
+  if(g!=0){return(0)}
+  g = reduce(ftest[1],std(ideal(f)));
+  if(g!=0){return(0)}
+  return (1);
+}
+
+example
+{ "EXAMPLE:"; echo=2;
+  ring R = 0,(x,y,z),dp;
+  poly f = y^8-x^3*(z+x)^5;
+  def RP1 = paraPlaneCurve(f);
+  testParametrization(f, RP1);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+proc testPointConic(poly p, def r)
+"USAGE:  testPointConic(p, r); p poly, r ring
+ASSUME:  assumes that p is a homogeneous quadratic polynomial in the
+        first three ring variables of the current basering;
+        Assumes that there is a (1x3) matrix named 'point' in r with
+        entries from the ground field of r.
+RETURN:  returns 1 iff the point named 'point', residing in r, lies on
+        the conic given by p; 0 otherwise
+NOTE:    This method temporarily changes the basering to r. Afterwards,
+        the basering will be the same as before.
+EXAMPLE: example testPointConic; shows an example
+"
+{
+ def rOrig = basering;
+ "conic:", p;
+ setring r;
+ string s = "point: " + string(point[1,1]) + ", " + string(point[1,2]);
+ s = s + ", " + string(point[1,3]);
+ s;
+ if (minpoly != 0) { "minpoly:", minpoly; }
+ poly f = fetch(rOrig, p);
+ poly g = subst(f, var(1), point[1,1],
+                   var(2), point[1,2],
+                   var(3), point[1,3]);
+ int result = 0; if (g == 0) { result = 1; }
+ setring rOrig;
+ return (result);
+}
+
+example
+{ "EXAMPLE:"; echo=2;
+ ring R = 0, (x,y,z), dp;
+ system("random", 4711);
+ poly p = x^2 + 2*y^2 + 5*z^2 - 4*x*y + 3*x*z + 17*y*z;
+ def S = rationalPointConic(p);
+ if (testPointConic(p, S) == 1)
+ { "point lies on conic"; }
+ else
+ { "point does not lie on conic"; }
+}
+
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+/*
+/////////////////////////////////////////////////////////////////////////////
+/// Further examples for testing the main procedures
+/// Timings on wawa Sept 29
+/////////////////////////////////////////////////////////////////////////////
+LIB"paraplanecurves.lib";
+// -------------------------------------------------------
+// Example 1
+// -------------------------------------------------------
+ring RR = 0, (x,y,z), dp;
+poly f = 7*z2+11*y2+13*z*y+17*x2+19*x*y; // conic
+def RP1 = paraConic(f);
+setring RP1; PARACONIC;
+setring RR;
+RP1 = paraPlaneCurve(f);
+testParametrization(f,RP1);
+setring RP1; PARA;
+kill RR;kill RP1;
+// -------------------------------------------------------
+// Example 2
+// -------------------------------------------------------
+ring RR = 0, (x,y,z), dp;
+poly f = y3-x2z;  // cusp at origin
+adjointIdeal(f,1);
+adjointIdeal(f,2);
+def RP1 = paraPlaneCurve(f);  // time 0
+testParametrization(f,RP1);
+setring RP1; PARA;
+kill RR;kill RP1;
+// -------------------------------------------------------
+// Example 3
+// -------------------------------------------------------
+ring RR = 0, (x,y,z), dp;
+poly f=(xz-y^2)^2-x*y^3; // 1 sing at origin, 1 cusp, no OMPs
+adjointIdeal(f,1);
+adjointIdeal(f,2);
+def RP1 = paraPlaneCurve(f); // time 0
+testParametrization(f,RP1);
+setring RP1; PARA;
+kill RR;kill RP1;
+// -------------------------------------------------------
+// Example 4
+// -------------------------------------------------------
+ring RR = 0, (x,y,z), dp;
+poly f = y5-y4x+4y2x2z-x4z;  // 1 sing at origin, no OMPs, no cusps
+adjointIdeal(f,1);
+adjointIdeal(f,2);
+def RP1 = paraPlaneCurve(f);  // time 0
+testParametrization(f,RP1);
+setring RP1; PARA;
+kill RR;kill RP1;
+// -------------------------------------------------------
+// Example 5
+// -------------------------------------------------------
+ring RR = 0, (x,y,z), dp;
+poly f = 259x5-31913x4y+939551x3y2+2871542x2y3+2845801xy4;
+f = f+914489y5+32068x4z-1884547x3yz-8472623x2y2z-11118524xy3z;
+f = f-4589347y4z+944585x3z2+8563304x2yz2+16549772xy2z2+9033035y3z2;
+f = f-2962425x2z3-11214315xyz3-8951744y2z3+2937420xz4+4547571yz4-953955z5;
+// 6 nodes
+adjointIdeal(f,1);
+adjointIdeal(f,2);
+def RP1 = paraPlaneCurve(f);  // time 0
+testParametrization(f,RP1);
+setring RP1; PARA;
+kill RR;kill RP1;
+// -------------------------------------------------------
+// Example 7
+// -------------------------------------------------------
+ring RR = 0, (x,y,z), dp;
+poly f = y^8-x^3*(z+x)^5;  // 1 sing at origin, 1 further sing, no OMPs,
+                           // no cusps
+adjointIdeal(f,1);
+adjointIdeal(f,2);
+def RP1 = paraPlaneCurve(f);  // time 0
+testParametrization(f,RP1);
+setring RP1; PARA;
+kill RR;kill RP1;
+// -------------------------------------------------------
+// Example 8
+// -------------------------------------------------------
+ring RR = 0, (x,y,z), dp;
+poly f = 11y7+7y6x+8y5x2-3y4x3-10y3x4-10y2x5-x7-33y6-29y5x-13y4x2+26y3x3;
+f = f+30y2x4+10yx5+3x6+33y5+37y4x-8y3x2-33y2x3-20yx4-3x5-11y4-15y3x;
+f = f+13y2x2+10yx3+x4; // 3 OMPs of mult 3, 1 OMP of mult 4
+f = homog(f,z);
+adjointIdeal(f,1);
+adjointIdeal(f,2);
+def RP1 = paraPlaneCurve(f);  // time 0
+testParametrization(f,RP1);
+setring RP1; PARA;
+kill RR;kill RP1;
+// -------------------------------------------------------
+// Example 9
+// -------------------------------------------------------
+ring RR = 0, (x,y,z), dp;
+poly f = y^8-x^3*(z+x)^5;  // 1 sing at origin, 1 further sing, no OMPs,
+                           // no cusps
+adjointIdeal(f,1);
+adjointIdeal(f,2);
+def RP1 = paraPlaneCurve(f);  // time 0
+testParametrization(f,RP1);
+setring RP1; PARA;
+kill RR;kill RP1;
+// -------------------------------------------------------
+// Example 10
+// -------------------------------------------------------
+ring SS = 0, (u,v,z), dp;
+poly f = u^4-14*u^2*v^2+v^4+8*u^2*v*z+8*v^3*z; // 1 OMP of mult 3 at orgin
+adjointIdeal(f,1);
+adjointIdeal(f,2);
+def RP1 = paraPlaneCurve(f);  // time 0
+testParametrization(f,RP1);
+setring RP1; PARA;
+kill SS;kill RP1;
+// -------------------------------------------------------
+// Example 11
+// -------------------------------------------------------
+ring SS = 0, (u,v,z), dp;
+poly f = 14440*u^5-16227*u^4*v+10812*u^3*v^2-13533*u^2*v^3+3610*u*v^4;
+f = f+1805*v^5+14440*u^4*z-18032*u^3*v*z+16218*u^2*v^2*z-12626*u*v^3*z;
+f = f+3610*v^4*z+3610*u^3*z^2-4508*u^2*v*z^2+5406*u*v^2*z^2-2703*v^3*z^2;
+// 1 OMP of mult 3 at origin, 2 nodes
+adjointIdeal(f,1);
+adjointIdeal(f,2);
+def RP1 = paraPlaneCurve(f);  // time 0
+testParametrization(f,RP1);
+setring RP1; PARA;
+kill SS;kill RP1;
+// -------------------------------------------------------
+// Example 12
+// -------------------------------------------------------
+ring SS = 0, (u,v,z), dp;
+poly f = u^6+3*u^4*v^2+3*u^2*v^4+v^6-4*u^4*z^2-34*u^3*v*z^2-7*u^2*v^2*z^2;
+f = f+12*u*v^3*z^2+6*v^4*z^2+36*u^2*z^4+36*u*v*z^4+9*v^2*z^4;
+// needs field extension *** 6 nodes, 2 cusps, 1 sing at 0
+adjointIdeal(f,1);
+adjointIdeal(f,2);
+def RP1 = paraPlaneCurve(f);  // time 0
+testParametrization(f,RP1);
+setring RP1; PARA;
+kill SS;kill RP1;
+// -------------------------------------------------------
+// Example 13
+// -------------------------------------------------------
+ring SS = 0, (u,v,z), dp;
+poly f = -24135/322*u^6-532037/6440*u^5*v+139459/560*u^4*v^2;
+f = f-1464887/12880*u^3*v^3+72187/25760*u^2*v^4+9/8*u*v^5+1/8*v^6;
+f = f-403511/3220*u^5*z-40817/920*u^4*v*z+10059/80*u^3*v^2*z;
+f = f-35445/1288*u^2*v^3*z+19/4*u*v^4*z+3/4*v^5*z-20743/805*u^4*z^2;
+f = f+126379/3220*u^3*v*z^2-423417/6440*u^2*v^2*z^2+11/2*u*v^3*z^2;
+f = f+3/2*v^4*z^2+3443/140*u^3*z^3+u^2*v*z^3+u*v^2*z^3+v^3*z^3;
+// 2 OMPs of mult 3 (1 at origin), 4 nodes
+adjointIdeal(f,1);
+adjointIdeal(f,2);
+def RP1 = paraPlaneCurve(f);  // time 14
+testParametrization(f,RP1);
+setring RP1; PARA;
+kill SS;kill RP1;
+// -------------------------------------------------------
+// Example 14
+// -------------------------------------------------------
+ring SS = 0, (u,v,z), dp;
+poly f =
+2*u^7+u^6*v+3*u^5*v^2+u^4*v^3+2*u^3*v^4+u^2*v^5+2*u*v^6+v^7
+-7780247/995328*u^6*z-78641/9216*u^5*v*z-10892131/995328*u^4*v^2*z
+-329821/31104*u^3*v^3*z-953807/331776*u^2*v^4*z-712429/248832*u*v^5*z
++1537741/331776*v^6*z+2340431/248832*u^5*z^2+5154337/248832*u^4*v*z^2
++658981/41472*u^3*v^2*z^2+1737757/124416*u^2*v^3*z^2
+-1234733/248832*u*v^4*z^2-1328329/82944*v^5*z^2-818747/248832*u^4*z^3
+-1822879/124416*u^3*v*z^3-415337/31104*u^2*v^2*z^3
++1002655/124416*u*v^3*z^3+849025/82944*v^4*z^3;
+// 3 OMPs of mult 3, 1 OMP of mult 4 at origin
+adjointIdeal(f,2);
+def RP1 = paraPlaneCurve(f);  // time 1
+testParametrization(f,RP1);
+setring RP1; PARA;
+kill SS;kill RP1;
+// -------------------------------------------------------
+// Example 15
+// -------------------------------------------------------
+ring SS = 0, (u,v,z), dp;
+poly f = 590819418867856650536224u7-147693905508217596067968u6v;
+f = f+229117518934972047619978u5v2-174050799674982973889542u4v3;
+f = f-92645796479789150855110u3v4-65477418713685583062704u2v5;
+f = f+4529961835917468460168uv6+7715404057796585983136v7;
+f = f-413640780091141905428104u6z+571836835577486968144618u5vz;
+f = f-551807810327826605739444u4v2z-488556410340789283359926u3v3z;
+f = f-473466023008413178155962u2v4z+48556741573432247323608uv5z;
+f = f+77647371229172269259528v6z+340450118906560552282893u5z2;
+f = f-433598825064368371610344u4vz2-937281070591684636591672u3v2z2;
+f = f-1388949843915129934647751u2v3z2+204081793110898617103998uv4z2;
+f = f+335789953068251652554308v5z2+6485661002496681852577u4z3;
+f = f-772700266516318390630202u3vz3-2068348417248100329533330u2v2z3;
+f = f+440320154612359641806108uv3z3+808932515589210854581618v4z3;
+f = f-229384307132237615286548u3z4-1564303565658228216055227u2vz4;
+f = f+520778334468674798322974uv2z4+1172483905704993294097655v3z4;
+f = f-480789741398016816562100u2z5+322662751598958620410786uvz5;
+f = f+1022525576391791616258310v2z5+82293493608853837667471uz6;
+f = f+496839109904761426785889vz6+103766136235628614937587z7; // 15 nodes
+adjointIdeal(f,2);
+def RP1 = paraPlaneCurve(f);  // time 72
+testParametrization(f,RP1);
+setring RP1; PARA;
+kill SS;kill RP1;
+
+// -------------------------------------------------------
+// Example 16
+// -------------------------------------------------------
+ring SS = 0, (u,v,z), dp;
+poly f = 25*u^8+184*u^7*v+518*u^6*v^2+720*u^5*v^3+576*u^4*v^4+282*u^3*v^5;
+f = f+84*u^2*v^6+14*u*v^7+v^8+244*u^7*z+1326*u^6*v*z+2646*u^5*v^2*z;
+f = f+2706*u^4*v^3*z+1590*u^3*v^4*z+546*u^2*v^5*z+102*u*v^6*z+8*v^7*z;
+f = f+854*u^6*z^2+3252*u^5*v*z^2+4770*u^4*v^2*z^2+3582*u^3*v^3*z^2;
+f = f+1476*u^2*v^4*z^2+318*u*v^5*z^2+28*v^6*z^2+1338*u^5*z^3+3740*u^4*v*z^3;
+f = f+4030*u^3*v^2*z^3+2124*u^2*v^3*z^3+550*u*v^4*z^3+56*v^5*z^3+1101*u^4*z^4;
+f = f+2264*u^3*v*z^4+1716*u^2*v^2*z^4+570*u*v^3*z^4+70*v^4*z^4+508*u^3*z^5;
+f = f+738*u^2*v*z^5+354*u*v^2*z^5+56*v^3*z^5+132*u^2*z^6+122*u*v*z^6;
+f = f+28*v^2*z^6+18*u*z^7+8*v*z^7+z^8; // 3 nodes, 1 sing
+adjointIdeal(f,1);
+adjointIdeal(f,2);
+def RP1 = paraPlaneCurve(f);  // time 20
+testParametrization(f,RP1);
+setring RP1; PARA;
+kill SS;kill RP1;
+// -------------------------------------------------------
+// Example 17
+// -------------------------------------------------------
+ring SS = 0, (u,v,z), dp;
+poly f = -2*u*v^4*z^4+u^4*v^5+12*u^4*v^3*z^2+12*u^2*v^4*z^3-u^3*v*z^5;
+f = f+11*u^3*v^2*z^4-21*u^3*v^3*z^3-4*u^4*v*z^4+2*u^4*v^2*z^3-6*u^4*v^4*z;
+f = f+u^5*z^4-3*u^5*v^2*z^2+u^5*v^3*z-3*u*v^5*z^3-2*u^2*v^3*z^4+u^3*v^4*z^2;
+f = f+v^5*z^4; // 2 OMPs of mult 4, 1 OMP of mult 5, 1 sing at origin
+f = subst(f,z,u+v+z);
+adjointIdeal(f,2);
+def RP1 = paraPlaneCurve(f);  // time 5
+testParametrization(f,RP1);
+setring RP1; PARA;
+kill SS;kill RP1;
+// -------------------------------------------------------
+// Example 18
+// -------------------------------------------------------
+ring SS = 0, (u,v,z), dp;
+poly f = u^5*v^5+21*u^5*v^4*z-36*u^4*v^5*z-19*u^5*v^3*z^2+12*u^4*v^4*z^2;
+f = f+57*u^3*v^5*z^2+u^5*v^2*z^3+u^4*v^3*z^3-53*u^3*v^4*z^3-19*u^2*v^5*z^3;
+f = f+u^5*v*z^4+43*u^3*v^3*z^4+u*v^5*z^4+u^5*z^5-15*u^3*v^2*z^5+u^2*v^3*z^5;
+f = f+u*v^4*z^5+v^5*z^5; // 1 OMP of mult 4, 3 OMPs of mult 5 (1 at origin)
+adjointIdeal(f,2);
+def RP1 = paraPlaneCurve(f);  // time 8
+testParametrization(f,RP1);
+setring RP1; PARA;
+kill SS;kill RP1;
+// -------------------------------------------------------
+// Example 19
+// -------------------------------------------------------
+ring SS = 0, (u,v,z), dp;
+poly f = u^10+6*u^9*v-30*u^7*v^3-15*u^6*v^4+u^5*v^5+u^4*v^6+6*u^3*v^7;
+f = f+u^2*v^8+7*u*v^9+v^10+5*u^9*z+24*u^8*v*z-30*u^7*v^2*z-120*u^6*v^3*z;
+f = f-43*u^5*v^4*z+5*u^4*v^5*z+20*u^3*v^6*z+10*u^2*v^7*z+29*u*v^8*z+5*v^9*z;
+f = f+10*u^8*z^2+36*u^7*v*z^2-105*u^6*v^2*z^2-179*u^5*v^3*z^2-38*u^4*v^4*z^2;
+f = f+25*u^3*v^5*z^2+25*u^2*v^6*z^2+46*u*v^7*z^2+10*v^8*z^2+10*u^7*z^3;
+f = f+24*u^6*v*z^3-135*u^5*v^2*z^3-117*u^4*v^3*z^3-u^3*v^4*z^3+25*u^2*v^5*z^3;
+f = f+34*u*v^6*z^3+10*v^7*z^3+5*u^6*z^4+6*u^5*v*z^4-75*u^4*v^2*z^4;
+f = f-27*u^3*v^3*z^4+10*u^2*v^4*z^4+11*u*v^5*z^4+5*v^6*z^4+u^5*z^5;
+f = f-15*u^3*v^2*z^5+u^2*v^3*z^5+u*v^4*z^5+v^5*z^5;
+// 1 OMP of mult 4, 3 OMPs of mult 5 (1 at origin)
+adjointIdeal(f,2);
+def RP1 = paraPlaneCurve(f);  // time 2 // see Ex. 18
+testParametrization(f,RP1);
+setring RP1; PARA;
+kill SS;kill RP1;
+// -------------------------------------------------------
+// Example 20
+// -------------------------------------------------------
+ring R = 0, (x,y,z), dp;
+system("random", 4711);
+poly p = x^2 + 2*y^2 + 5*z^2 - 4*x*y + 3*x*z + 17*y*z;
+def S = rationalPointConic(p); // quadratic field extension,
+                              // minpoly = a^2 - 2
+if (testPointConic(p, S) == 1)
+{ "point lies on conic"; }
+else
+{ "point does not lie on conic"; }
+kill R;kill S;
+// -------------------------------------------------------
+// Example 21
+// -------------------------------------------------------
+ring R = 0, (x,y,z), dp;
+system("random", 4711);
+poly p = x^2 - 1857669520 * y^2 + 86709575222179747132487270400 * z^2;
+def S = rationalPointConic(p); // same as current basering,
+                              // no extension needed
+if (testPointConic(p, S) == 1)
+{ "point lies on conic"; }
+else
+{ "point does not lie on conic"; }
+kill R;kill S;
+// -------------------------------------------------------
+// Example 21
+// -------------------------------------------------------
+ring RR = 0, (x,y,z), dp;
+poly f = -1965466244509920x5y+34871245546721380061760x4y2;
+f = f+104613747941595046117320x3y3+113331564241941002407560x2y4;
+f = f+52306876673313609259800xy5+8717812860780028397880y6;
+f = f+1040297748510024x5z+4468147845634872x4yz;
+f = f-22398508728211453743258x3y2z-33223996581074443306854x2y3z;
+f = f-10638598235041298082366xy4z+186886189971594356382y5z;
+f = f-1385078844909312x4z2-34893092731637052532683x3yz2;
+f = f-98591463214095439056609x2y2z2-92339459334829609336485xy3z2;
+f = f-24923289542522905755711y4z2+472440640471377x3z3;
+f = f+33821511925664516716011x2yz3+49745237303968344397437xy2z3;
+f = f+11040465960074786720475y3z3+8728735735878837099404x2z4;
+f = f+17676785754519678518537xyz4+17935885079051421934609y2z4;
+f = f-11314701999743172607075xz5-16164284825803158969425yz5;
+f = f+3666695988537425618750z6;
+// 4 nodes, 1 OMP of mult 4
+adjointIdeal(f,2);
+kill RR;
+*/
diff --git a/Singular/LIB/perron.lib b/Singular/LIB/perron.lib
new file mode 100644
index 0000000..2f63b9b
--- /dev/null
+++ b/Singular/LIB/perron.lib
@@ -0,0 +1,202 @@
+//////////////////////////////////////////////////////////////////////////////
+version="version perron.lib 4.0.0.0 Jun_2013 "; // $Id: bd7cde64b139f9376272b52f8102d69ba8af6397 $
+category="Noncommutative";
+info="
+LIBRARY:  perron.lib         computation of algebraic dependences
+AUTHOR:   Oleksandr Motsak   U at D, where U={motsak}, D={mathematik.uni-kl.de}
+
+PROCEDURES:
+perron(L[, D]);  relations between pairwise commuting polynomials
+
+KEYWORDS:  algebraic dependence; relations
+";
+
+LIB "central.lib";
+
+//////////////////////////////////////////////////////////////////////////////
+proc perron( ideal L, list # )
+"USAGE:  perron( L [, D] )
+RETURN:  commutative ring with ideal `Relations`
+PURPOSE: computes polynomial relations ('Relations') between pairwise
+         commuting polynomials of L [, up to a given degree bound D]
+NOTE:    the implementation was partially inspired by the Perron's theorem.
+EXAMPLE: example perron; shows an example
+"
+{
+  int N, D, i;
+  N = size(L);
+  if( N == 0 )
+  {
+    ERROR( "Input ideal must be non-zero!" );
+  }
+  intvec W; // weights
+  for ( i = N; i > 0; i-- )
+  {
+    W[i] = deg(L[i]);
+  }
+  ////////////////////////////////////////////////////////////////////////
+  D = -1;
+  // Check whether the degree bound 'D' is given:
+  if( size(#)>0 )
+  {
+    if ( typeof(#[1]) == typeof(D) )
+    {
+      D = #[1];
+      if( D <= 0 )
+      {
+        ERROR( "An optional parameter D must be positive!" );
+      }
+    }
+  }
+
+  // , otherwise we try to estimate it according to Perron's Th:
+  if( D < 0 )
+  {
+    D = 1;
+    int d;
+    int min = -1;
+
+    for ( i = size(L); i > 0 ; i-- )
+    {
+      d = W[i];
+      D = D * d;
+      if( min == -1)
+      {
+        min = d;
+      }
+      else
+      {
+        if( min > d )
+        {
+          min = d;
+        }
+      }
+    }
+    if( (D == 0) or (min <= 0) )
+    {
+      ERROR( "Wrong set of polynomials!" );
+    }
+    D = D div min;
+  }
+  ////////////////////////////////////////////////////////////////////////
+  def NCRING = basering;
+  def CurrentField = ringlist( NCRING )[1];
+
+  // We are going to construct a commutative ring in N variables F(i),
+  // with the field specified by 'CurrentField':
+
+  ring TEMPRING = 0, ( F(1..N) ), dp;
+  list RingList = ringlist( TEMPRING );
+  setring NCRING;
+
+  if( !defined(RingList) )
+  {
+    list RingList = imap( TEMPRING, RingList );
+  }
+  RingList[1] = CurrentField;
+
+  // New Commutative Ring with correct field!
+  def COMMUTATIVERING = ring( RingList );
+
+  ////////////////////////////////////////////////////////////////////////
+
+  setring COMMUTATIVERING; // we are in COMMUTATIVERING now
+
+  ideal PBWBasis = PBW_maxDeg( D ); // All monomials of degree(!) <= D.
+
+  // TODO: it would be better to compute weighted monomials of weight
+  // <= W[1] \cdots W[N].
+
+  setring NCRING; // and back to NCRING
+
+  map Psi = COMMUTATIVERING, L; // F(i) \mapsto L[i]
+
+  ideal Images = Psi( PBWBasis ); // Corresponding products of polynomials
+                                  // from L
+
+  // ::MAIN STEP:: // Compute relations in NC ring:
+  def T = linearMapKernel( Images );
+
+  ////////////////////////////////////////////////////////////////////////
+
+  // check the output of 'linearMapKernel':
+  int t = 0;
+
+  if( (typeof(T) != "module") and (typeof(T) != "int" ) )
+  {
+    ERROR( "Wrong output from function 'linearMapKernel'!" );
+  }
+
+  if( typeof(T) == "int" )
+  {
+    t = 1;
+    if( T != 0 )
+    {
+      ERROR( "Wrong output from function 'linearMapKernel'!" );
+    }
+  }
+
+  ////////////////////////////////////////////////////////////////////////
+
+  // Go back to commutative case in both cases:
+  setring COMMUTATIVERING;
+
+  ideal Relations; // And generate Relations:
+
+  if( t == 0 ) // T is a module
+  {
+    module KER = imap( NCRING, T );
+    Relations = linearCombinations( PBWBasis, KER );
+  }
+  else
+  { // T == int(0) => all images are zero =>
+    Relations = PBWBasis;
+  }
+
+  ////////////////////////////////////////////////////////////////////////
+
+  // we compute an std basis of the relations:
+
+  // save options
+  intvec v = option( get );
+
+  // set right options
+  option( redSB );
+  option( redTail );
+
+  // reduce everything in as far as possible
+  Relations = simplify( groebner( Relations ), 1 + 2 + 8 );
+
+  // restore options
+  option( set, v );
+
+  //    Relations;
+  export Relations;
+
+  return( COMMUTATIVERING );
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  int p = 3;
+  ring AA = p,(x,y,z),dp;
+  matrix D[3][3]=0;
+  D[1,2]=-z; D[1,3]=2*x; D[2,3]=-2*y;
+  def A = nc_algebra(1,D); setring A; // this algebra is U(sl_2)
+  ideal I = x^p, y^p, z^p-z, 4*x*y+z^2-2*z; // the center
+  def RA = perron( I, p );
+  setring RA;
+  RA;
+  Relations; // it was exported from perron to be in the returned ring.
+
+  // perron can be also used in a commutative case, for example:
+  ring B = 0,(x,y,z),dp;
+  ideal J = xy+z2, z2+y2, x2y2-2xy3+y4;
+  def RB = perron(J);
+  setring RB;
+  Relations;
+  // one more test:
+  setring A;
+  map T=RA,I;
+  T(Relations);  // should be zero
+}
+
diff --git a/Singular/LIB/phindex.lib b/Singular/LIB/phindex.lib
new file mode 100644
index 0000000..ed8b3c1
--- /dev/null
+++ b/Singular/LIB/phindex.lib
@@ -0,0 +1,642 @@
+//////////////////////////////////////////////////////////////////////////
+version="version phindex.lib 4.0.0.0 Jun_2013 "; // $Id: eda795cc37258ffdc1cfc71971e6814ac18bd9dd $
+category=" ";
+info="
+LIBRARY : phindex.lib Procedures to compute the index of real analytic vector fields
+AUTHOR: Victor Castellanos
+
+NOTE: To compute the Poincare-Hopf index of a real analytic vector field
+      with an algebraically isolated singularity at 0 (w. an a. i. s),
+      we use the algebraic formula for the degree of the real analytic map
+      germ  found by Eisenbud-Levine in 1997. This result was also proved by
+      Khimshiashvili. If the isolated singularity is non algebraically
+      isolated  and the vector field has similar reduced complex zeroes of
+      codimension 1, we use a formula as the Eisenbud-Levine found by Victor
+      Castellanos, in both cases is necessary to use a local order (ds,...).
+      To compute the signature of a quadratic form (or symmetric matrix)
+      we use the method of Lagrange.
+
+PROCEDURES:
+ signatureL(M[,n]);   signature of symmetric matrix M, method of Lagrange.
+ signatureLqf(h[,n]); signature of quadratic form h, method of Lagrange.
+ PH_ais(I)            P-H index of real analytic vector field I w. an a. i. s.
+ PH_nais(I)           P-H index of real analytic vector field I w. a non a. i. s
+";
+
+LIB "primdec.lib";
+LIB "zeroset.lib";
+
+/////////////////////////////////////////////////////////////////////////////
+proc signatureL(matrix M,int #)
+"USAGE:    signatureL(M[,r]); M symmetric matrix, r int (optional).
+RETURN:   the signature of M of type int or if r is given and !=0 then
+          intvec with (signature, nr. of +, nr. of -) is returned.
+THEORY:   Given the matrix M, we construct the quadratic form associated. Afterwards
+          we use the method of Lagrange to compute the signature. The law of
+          inertia for a real quadratic form A(x,x) says that in a
+          representation of A(x,x) as a sum of independent squares
+                            A(x,x)=sum_{i=1}^r a_iX_i^2.
+          The number of positive and the number of negative squares are
+          independent of the choice of representation. The signature -s- of
+          A(x,x) is the difference between the number -pi- of positive squares
+          and the number -nu- of negative squares in the representation of
+          A(x,x). The rank -r- of M (or A(x,x)) and the signature -s-
+          determine the numbers -pi- and -nu- uniquely, since
+                            r=pi+nu,   s=pi-nu.
+          The method of Lagrange is a procedure to reduce any real quadratic
+          form to a sum of squares.
+          Ref. Gantmacher, The theory of matrices, Vol. I, Chelsea Publishing
+               Company, NY 1960, page 299.
+EXAMPLE:  example signatureL; shows an example
+"
+{
+  if(typeof(M)!="matrix")
+  {
+    ERROR("** The argument is not a matrix type");
+  }
+  option(noprot);
+  option(noredefine);
+  int nv1=ncols(M);
+  matrix zero[nv1][nv1]=0;
+  if (transpose(M)!=M)
+    {
+      ERROR("** The matrix is non symmetric");
+    }
+  if (M==0)
+    {
+      ERROR("** The matrix is zero");
+    }
+  option(noprot);
+  option(noredefine);
+  def h=basering;
+  int chr=char(h);
+  ring signLagrange=chr,(x(1..nv1)), lp; //ring to compute the quadratic form associated to M
+  matrix Ma=fetch(h,M);
+  int nv=ncols(Ma);
+  matrix X[1][nv]=maxideal(1);
+  matrix Ax=X*Ma*transpose(X);
+  poly Axx=Ax[1,1]; //quadratic form associated to matrix M
+  if (size(#)==0)
+    {
+      def sal=SigntL(Axx);
+      return(sal[1]);
+    }
+  else
+    {
+      return(SigntL(Axx));
+    }
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring r=0,(x),ds;
+  matrix M[5][5]=0,0,0,1,0,0,1,0,0,-1,0,0,1,0,0,1,0,0,3,0,0,-1,0,0,1;
+  signatureL(M,1); //The rank of M is 3+1=4
+  matrix H[5][5]=0,-7,0,1,0,-7,1,0,0,-1,0,0,1,0,0,1,0,0,-3,5,0,-1,0,5,1;
+  signatureL(H);
+}
+////////////////////////////////////////////////////////////////////////
+proc signatureLqf(poly h,int #)
+"USAGE:    signatureLqf(h); h quadratic form (poly type).
+RETURN:   the signature of h of type int or if r is given and !=0 then
+          intvec with (signature, nr. of +, nr. of -) is returned.
+THEORY:   To compute the signature we use the method of Lagrange. The law of
+          inertia for a real quadratic form h(x,x) says that in a
+          representation  of h(x,x) as a sum of independent squares
+          h(x,x)=sum_{i=1}^r a_i*X_i^2 the number of positive and the number of negative squares are
+          independent of the choice of representation. The signature -s- of
+          h(x,x) is the difference between the number -pi- of positive squares
+          and the number -nu- of negative squares in the representation of
+          h(x,x). The rank -r- of h(x,x) and the signature -s- determine the
+          numbers -pi- and -nu- uniquely, since
+                             r=pi+nu,   s=pi-nu.
+          The method of Lagrange is a procedure to reduce any real quadratic
+          form to a sum of squares.
+          Ref. Gantmacher, The theory of matrices, Vol. I, Chelsea Publishing
+               Company, NY 1960, page 299.
+EXAMPLE:  example signatureLqf; shows an example
+"
+{
+  if(typeof(h)!="poly")
+  {
+    ERROR("** The argument is not a poly type");
+  }
+  option(noprot);
+  option(noredefine);
+  poly M=h;
+  int nv1=nvars(basering);
+  if (M==0)
+   {
+     ERROR("** The quadratic form is zero");
+   }
+  poly Axx=M;
+  poly Bxx;
+  poly bxx1;
+  poly bxx2;
+  def coe1;
+  int i;
+  int jb;
+  int k;
+  int haycuadrados;
+  int haycruzados;
+  int positivo=0;
+  int negativo=0;
+  int lAxx;
+  while (Axx<>0) //Lagrange method to compute the signature
+    {
+      haycruzados=1;
+      haycuadrados=1;
+      lAxx=size(Axx);
+      i=1;
+      while (i<=lAxx and haycuadrados)
+    {
+      jb=1;
+      while (jb<=nv1 and haycuadrados)
+        {
+          if (leadmonom(Axx[i])/(x(jb)^2)==1) //there is squares
+        {
+          Bxx=Axx;
+          if (leadcoef(Axx[i])>0)
+            {
+              positivo=positivo+1;
+            }
+          else
+            {
+              negativo=negativo+1;
+            }
+          coe1=1/(4*leadcoef(Bxx[i]));
+          Axx=Bxx-coe1*(diff(Bxx,x(jb)))^2;
+          haycuadrados=0;
+        }
+          jb=jb+1;
+        }
+      i=i+1;
+    }
+      if (haycruzados) //there is no squares
+    {
+      int ia=1;
+      int ja=1;
+      int ka=1;
+      while (ia<=nv1 and haycruzados)
+        {
+          while (ja<=nv1 and haycruzados)
+        {
+          ka=ja+1;
+          while (ka<=nv1 and haycruzados)
+            {
+              if (leadmonom(Axx[ia])/leadmonom(x(ja)*x(ka))==1)
+            {
+              Bxx=Axx;
+              bxx1=diff(Bxx,x(ja))+diff(Bxx,x(ka));
+              bxx2=diff(Bxx,x(ja))-diff(Bxx,x(ka));
+              coe1=1/(4*leadcoef(Bxx[ia]));
+              Axx=Bxx-coe1*(bxx1^2-bxx2^2);
+              positivo=positivo+1;
+              negativo=negativo+1;
+              haycruzados=0;
+            }
+              ka=ka+1;
+            }
+          ja=ja+1;
+        }
+          ia=ia+1;
+        }
+    }
+    }
+ if (size(#)==0)
+    {
+      def sal=positivo-negativo;
+      return(sal);
+    }
+  else
+    {
+      int sig=positivo-negativo;
+      intvec dat=sig,positivo,negativo;
+      return(dat);
+    }
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring r=0,(x(1..4)),ds;
+  poly Ax=4*x(1)^2+x(2)^2+x(3)^2+x(4)^2-4*x(1)*x(2)-4*x(1)*x(3)+4*x(1)*x(4)+4*x(2)*x(3)-4*x(2)*x(4);
+  signatureLqf(Ax,1); //The rank of Ax is 3+1=4
+  poly Bx=2*x(1)*x(4)+x(2)^2+x(3)^2;
+  signatureLqf(Bx);
+}
+/////////////////////////////////////////////////////////////////////////////
+proc PH_ais(def I)
+"USAGE:    PH_ais(I); I ideal of coordinates of the vector field.
+RETURN:   the Poincare-Hopf index of type int.
+NOTE:     the isolated singularity must be algebraically isolated.
+THEORY:   The Poincare-Hopf index of a real vector field X at the isolated
+          singularity 0 is the degree of the map (X/|X|) : S_epsilon ---> S,
+          where S is the unit sphere, and the spheres are oriented as
+          (n-1)-spheres in R^n. The degree depends only on the germ, X, of X
+          at 0. If the vector field X is real analytic, then an invariant of
+          the germ is its local ring
+                            Qx=R[[x1..xn]]/Ix
+          where R[[x1,..,xn]] is the ring of germs at 0 of real-valued analytic
+          functions on R^n, and Ix is the ideal generated by the components
+          of X. The isolated singularity of X is algebraically isolated if the
+          algebra Qx is finite dimensional as real vector space, geometrically
+          this mean that 0 is also an isolated singularity for the
+          complexified vector field. In this case the Poincare-Hopf index is
+          the signature of the non degenerate bilinear form <,> obtained by
+          composition of the product in the algebra Qx with a linear
+          functional map
+                       <,> : (Qx)x(Qx) ---(.)--> Qx ---(L)--> R
+          with L(Jo)>0, where Jo is the residue class of the Jacobian
+          determinant in Qx. Here, we use a natural linear functional defined
+          as follows. Suppose that E={E_1,..E_r} is a basis of Qx, then Jo can
+          be written as
+                      Jo=a_1E_{j1}+...+a_kE_{jk},  js\in {1...r}, s=1..k, k<=r,
+          where a_s are constant. The linear functional L:Qx--->R is defined as
+                                  L(E_{j1})=(a_1)/|a_1|=sign of a_1,
+          the other elements of the base are sent to 0.
+          Refs. -Eisenbud & Levine, An algebraic formula for the degree of
+                 a C^\infty map germ, Ann. Math., 106, (1977), 19-38.
+                -Khimshiashvili, On a local degree of a smooth map, trudi
+                 Tbilisi Math. Inst., (1980), 105-124.
+EXAMPLE:  example  PH_ais; shows an example.
+"
+{
+  if(typeof(I)!="ideal")
+  {
+    ERROR("** The argument is not of ideal type");
+  }
+  ideal A=I;
+  ideal qI=std(A);
+  int siono=vdim(qI);
+  int l;
+  if (siono==-1)
+    {
+      ERROR("** The vector field does not have an algebraically isolated singularity");
+    }
+  if (siono!=0)
+    {
+      option(noredefine);
+      option(noprot);
+      def oldr=basering;
+      def chr1=char(oldr);
+      int n=nvars(oldr);
+      ideal E=kbase(qI);
+      int m=size(E);
+      poly Jx=det(jacob(A));
+      poly Jo=reduce(Jx,qI);
+      ring newr=chr1,(x(1..m)),ds; //ring to compute the quadratic form
+      int nv=nvars(basering);
+      ideal E=fetch(oldr,E);
+      ideal qI=fetch(oldr,qI);
+      poly Jo=fetch(oldr,Jo);
+      attrib(qI,"isSB",1);
+      int scoef=1;
+      int multby;
+      poly Eik;
+      poly Axx=0;
+      int tEik;
+      int stEik;
+      def lcEik;
+      if (leadcoef(Jo[1])<0)
+    {
+      scoef=-1;
+    }
+      for (int si=1; si<=nv; si++)
+        {
+          for (int sk=si; sk<=nv; sk++)
+        {
+          Eik=reduce(E[si]*E[sk],qI);
+          tEik=size(Eik);
+          for(int stEik=1; stEik<=tEik; stEik++)
+        {
+          if (leadmonom(Eik[stEik])==leadmonom(Jo[1]))
+            {
+              if (si==sk)
+            {
+              multby=1;
+            }
+              else
+            {
+              multby=2;
+            }
+              lcEik=leadcoef(Eik[stEik]);
+              if (lcEik<0)
+            {
+              Axx=Axx-multby*scoef*lcEik*x(si)*x(sk);
+            }
+              else
+            {
+              Axx=Axx+multby*scoef*lcEik*x(si)*x(sk);
+            }
+            }
+        }
+        }
+        }
+      l=SignatLalt(Axx); //signature of billinear form
+      kill newr;
+    }
+  else
+    {
+      l=0;
+    }
+  return(l);
+}
+example
+{ "EXAMPLE"; echo = 2;
+  ring r=0,(x,y,z),ds;
+  ideal I=x3-3xy2,-y3+3yx2,z3;
+  PH_ais(I);
+}
+///////////////////////////////////////////////////////////////////////////
+proc PH_nais(def I)
+"USAGE:    PH_nais(I); I ideal of coordinates of the vector field.
+RETURN:   the Poincare-Hopf index of type int.
+NOTE:     the vector field must be a non algebraically isolated singularity
+          at 0, with reduced complex zeros of codimension 1.
+THEORY:   Suppose that 0 is an algebraically isolated singularity of the real
+          analytic vector field X, geometrically this corresponds to the fact that the
+          complexified vector field has positive dimension singular locus,
+          algebraically this mean that the local ring Qx=R[[x1..xn]]/Ix
+          where R[[x1,..,xn]] is the ring of germs at 0 of real-valued analytic
+          functions on R^n, and Ix is the ideal generated by the components
+          of X is infinite dimensional as real vector space. In the case that
+          X has a reduced hypersurface as complex zeros we have the next.
+          There exist a real analytic function f:R^n-->R, and a real analytic
+          vector field Y s. t. X=fY. The function f does not change of sign
+          out of 0 and
+                      Mx=R[[x1..xn]]/(Ix : radical(Ix))
+          is a finite dimensional sub-algebra of Qx. The Poincare-Hopf index
+          of X at 0 is the sign of f times the signature of the non degenerate
+          bilinear form <,> obtained by composition of the product in the
+          algebra Mx with a linear functional map
+                       <,> : (Mx)x(Mx) ---(.)--> Mx ---(L)--> R
+          with L(Jp)>0, where Jp is the residue class of the Jacobian
+          determinant of X, JX, over f^n, JX/(f^n) in Mx. Here, we use a
+          natural linear functional defined as follows. Suppose that
+          E={E_1,..E_r} is a basis of Mx, then Jp is writing as
+                      Jp=a_1E_{j1}+...+a_kE_{jk},  js\in {1...r}, s=1..k, k<=r,
+          where a_s are constant. The linear functional L:M--->R is defined as
+                                  L(E_{j1})=(a_1)/|a_1|=sign of a_1,
+          the other elements of the base are sent to 0.
+          Refs. -Castellanos-Vargas, V., Una formula algebraica del indice de
+                 Poincare-Hopf para campos vectoriales reales con una variedad
+                 de ceros complejos, Ph. D. thesis CIMAT (2000), chapther 1,
+                 Guanajuato Mexico.
+                -Castellanos -Vargas, V. The index of non algebraically
+                 isolated singularity, Bol. Soc. Mat. Mexicana, (3)
+                 Vol. 8, 2002, 141-147.
+
+EXAMPLE:  example  PH_nais; shows an example.
+"
+{
+  if(typeof(I)!="ideal")
+  {
+    ERROR("** The argument is not of ideal type");
+  }
+  ideal A=I;
+  int siono=vdim(std(A));
+  int l;
+  if (siono!=0)
+    {
+      if (siono!=-1)
+    {
+      ERROR("** The vector field has an algebraically isolated singularity, USE: PH_ais ");
+    }
+      option(noprot);
+      option(noredefine);
+      int n=nvars(basering);
+      def oldr=basering;
+      int chr1=char(oldr);
+      ring newring=chr1,(x(1..n)), dp; //ring to compute the radical
+      ideal A= fetch(oldr,A);
+      ideal rI=radical(A);
+      setring oldr;
+      ideal rI=fetch(newring,rI);
+      if (size(rI)!=1)
+    {
+      ERROR("** The vector field does not have a non algebraically isolated singularity of codimension 1");
+    }
+      ideal qI=std(quotient(A,rI));
+      ideal E=kbase(qI);
+      int m=size(E);
+      poly Jx=det(jacob(A));
+      poly Jy=Quotient(Jx,rI[1]^n)[1];
+      poly Jo=reduce(Jy,qI);
+      ring newr=chr1,(x(1..m)),ds; //ring to compute the quadratic form
+      int nv=nvars(basering);
+      ideal E=fetch(oldr,E);
+      ideal qI=fetch(oldr,qI);
+      poly Jo=fetch(oldr,Jo);
+      attrib(qI,"isSB",1);
+      int scoef=1;
+      if (leadcoef(Jo[1])<0)
+    {
+      scoef=-1;
+    }
+      int multby;
+      def lcEik;
+      poly Eik;
+      poly Axx=0;
+      int si=1;
+      int sk;
+      int tEik;
+      int stEik;
+      while (si<=nv)
+    {
+      sk=si;
+      while (sk<=nv)
+        {
+          Eik=reduce(E[si]*E[sk],qI);
+          tEik=size(Eik);
+          for(int stEik=1; stEik<=tEik; stEik++)
+        {
+          if (leadmonom(Eik[stEik])==leadmonom(Jo[1]))
+            {
+              if (si==sk)
+            {
+              multby=1;
+            }
+              else
+            {
+              multby=2;
+            }
+              lcEik=leadcoef(Eik[stEik]);
+              if (lcEik<0)
+            {
+              Axx=Axx-multby*lcEik*scoef*x(si)*x(sk);
+            }
+              else
+            {
+              Axx=Axx+multby*lcEik*scoef*x(si)*x(sk);
+            }
+            }
+        }
+          sk=sk+1;
+        }
+      si=si+1;
+    }
+      l=SignatLalt(Axx); //signature of bilinear form
+      return(l);
+    }
+  else
+    {
+      return(0);
+    }
+}
+example
+{"EXAMPLE:"; echo = 2;
+  ring r=0,(x,y,z),ds;
+  ideal I=x5-2x3y2-3xy4+x3z2-3xy2z2,-3x4y-2x2y3+y5-3x2yz2+y3z2,x2z3+y2z3+z5;
+  PH_nais(I);
+}
+//////////////////////////////////////////////////////////////////////
+static proc SigntL(poly M)  //static procedure to compute the signature of any quadratic form.
+"USAGE:    SigntL(M); M is a quadratic form.
+RETURN:   The signature of M of type int.
+ASSUME:   M is a quadratic form (ply type).
+"
+{
+  int nv1=nvars(basering);
+  poly Axx=M;
+  poly Bxx;
+  poly bxx1;
+  poly bxx2;
+  def coe1;
+  int i;
+  int jb;
+  int k;
+  int haycuadrados;
+  int haycruzados;
+  int positivo=0;
+  int negativo=0;
+  int lAxx;
+  while (Axx<>0)
+    {
+      haycruzados=1;
+      haycuadrados=1;
+      lAxx=size(Axx);
+      i=1;
+      while (i<=lAxx and haycuadrados)
+    {
+      jb=1;
+      while (jb<=nv1 and haycuadrados)
+        {
+          if (leadmonom(Axx[i])/(x(jb)^2)==1)
+        {
+          Bxx=Axx;
+          if (leadcoef(Axx[i])>0)
+            {
+              positivo=positivo+1;
+            }
+          else
+            {
+              negativo=negativo+1;
+            }
+          coe1=1/(4*leadcoef(Bxx[i]));
+          Axx=Bxx-coe1*(diff(Bxx,x(jb)))^2;
+          haycuadrados=0;
+          haycruzados=0;
+        }
+          jb=jb+1;
+        }
+      i=i+1;
+    }
+      if (haycruzados)
+    {
+      int ia=1;
+      int ja=1;
+      int ka=1;
+      while (ia<=nv1 and haycruzados)
+        {
+          while (ja<=nv1 and haycruzados)
+        {
+          ka=ja+1;
+          while (ka<=nv1 and haycruzados)
+            {
+              if (leadmonom(Axx[ia])/leadmonom(x(ja)*x(ka))==1)
+            {
+              Bxx=Axx;
+              bxx1=diff(Bxx,x(ja))+diff(Bxx,x(ka));
+              bxx2=diff(Bxx,x(ja))-diff(Bxx,x(ka));
+              coe1=1/(4*leadcoef(Bxx[ia]));
+              Axx=Bxx-coe1*(bxx1^2-bxx2^2);
+              positivo=positivo+1;
+              negativo=negativo+1;
+              haycruzados=0;
+            }
+              ka=ka+1;
+            }
+          ja=ja+1;
+        }
+          ia=ia+1;
+        }
+    }
+    }
+  int dat1=positivo-negativo;
+  intvec dat=dat1,positivo,negativo;
+  return(dat);
+}
+////////////////////////////////////////////////////////////////////////////
+//NOTE: SignatLalt is a procedure to compute the signature of a special
+//      bilinear form that is necessary to compute the Poincare-Hopf index.
+static proc SignatLalt(poly M)
+"USAGE:    SignatLalt(M); M is a quadratic form (a polynomial).
+RETURN:   The signature of type int.
+"
+{
+ int nv1=nvars(basering);
+ if (M==0)
+   {
+     ERROR("** The quadratic form is zero");
+   }
+ poly Axx=M;
+ poly Bxx;
+ poly bxx1;
+ poly bxx2;
+ def coe1;
+ int i;
+ int jb;
+ int k;
+ int haycuadrados;
+ int sihay=1;
+ int positivo=0;
+ int negativo=0;
+ int variableactual=0;
+ int posicion=1;
+ int lAxx;
+ while (Axx<>0 and sihay)
+   {
+     haycuadrados=1;
+     lAxx=size(Axx);
+     i=posicion;
+     while (i<=lAxx and haycuadrados)
+       {
+     jb=variableactual+1;
+     while (jb<=nv1 and haycuadrados)
+       {
+         if (leadmonom(Axx[i])/(x(jb)^2)==1)
+           {
+         Bxx=Axx;
+         if (leadcoef(Axx[i])>0)
+           {
+             positivo=positivo+1;
+           }
+         else
+           {
+             negativo=negativo+1;
+           }
+         coe1=1/(4*leadcoef(Bxx[i]));
+         Axx=Bxx-coe1*(diff(Bxx,x(jb)))^2;
+         haycuadrados=0;
+         variableactual=jb;
+         posicion=i;
+           }
+         jb=jb+1;
+       }
+     if (i==lAxx and haycuadrados)
+       {
+         sihay=0;
+       }
+     i=i+1;
+       }
+   }
+ return(positivo-negativo);
+}
diff --git a/Singular/LIB/pointid.lib b/Singular/LIB/pointid.lib
new file mode 100644
index 0000000..7ddde95
--- /dev/null
+++ b/Singular/LIB/pointid.lib
@@ -0,0 +1,673 @@
+/////////////////////////////////////////////////////////////////////////////
+version="version pointid.lib 4.0.0.0 Jun_2013 "; // $Id: c3ac481ef5385e97c5d43e80c74caccbf1d2745c $
+category="Commutative Algebra";
+info="
+LIBRARY:  pointid.lib     Procedures for computing a factorized lex GB of
+                          the vanishing ideal of a set of points via the
+                          Axis-of-Evil Theorem (M.G. Marinari, T. Mora)
+
+AUTHOR:   Stefan Steidel, steidel at mathematik.uni-kl.de
+
+OVERVIEW:
+    The algorithm of Cerlienco-Mureddu [Marinari M.G., Mora T., A remark on a
+    remark by Macaulay or Enhancing Lazard Structural Theorem. Bull. of the
+    Iranian Math. Soc., 29 (2003), 103-145] associates to each ordered set of
+    points A:={a1,...,as} in K^n, ai:=(ai1,...,ain)@*
+          - a set of monomials N and@*
+          - a bijection phi: A --> N.
+    Here I(A):={f in K[x(1),...,x(n)] | f(ai)=0, for all 1<=i<=s} denotes the
+    vanishing ideal of A and N = Mon(x(1),...,x(n)) \ {LM(f)|f in I(A)} is the
+    set of monomials which do not lie in the leading ideal of I(A) (w.r.t. the
+    lexicographical ordering with x(n)>...>x(1)). N is also called the set of
+    non-monomials of I(A). NOTE: #A = #N and N is a monomial basis of
+    K[x(1..n)]/I(A). In particular, this allows to deduce the set of
+    corner-monomials, i.e. the minimal basis M:={m1,...,mr}, m1<...<mr, of its
+    associated monomial ideal M(I(A)), such that@*
+    M(I(A))= {k*mi | k in Mon(x(1),...,x(n)), mi in M},@*
+    and (by interpolation) the unique reduced lexicographical Groebner basis
+    G := {f1,...,fr} such that LM(fi)=mi for each i, that is, I(A)=<G>.
+    Moreover, a variation of this algorithm allows to deduce a canonical linear
+    factorization of each element of such a Groebner basis in the sense ot the
+    Axis-of-Evil Theorem by M.G. Marinari and T. Mora. More precisely, a
+    combinatorial algorithm and interpolation allow to deduce polynomials
+@*
+@*                y_mdi = x(m) - g_mdi(x(1),...,x(m-1)),
+@*
+    i=1,...,r; m=1,...,n; d in a finite index-set F, satisfying
+@*
+@*                 fi = (product of y_mdi) modulo (f1,...,f(i-1))
+@*
+    where the product runs over all m=1,...,n; and all d in F.
+
+PROCEDURES:
+ nonMonomials(id);   non-monomials of the vanishing ideal id of a set of points
+ cornerMonomials(N); corner-monomials of the set of non-monomials N
+ facGBIdeal(id);     GB G of id and linear factors of each element of G
+";
+
+LIB "poly.lib";
+
+////////////////////////////////////////////////////////////////////////////////
+
+static proc subst1(def id, int m)
+{
+//id = poly/ideal/list, substitute the first m variables occuring in id by 1
+
+  int i,j;
+  def I = id;
+  if(typeof(I) == "list")
+  {
+    for(j = 1; j <= size(I); j++)
+    {
+      for(i = 1; i <= m; i++)
+      {
+        I[j] = subst(I[j],var(i),1);
+      }
+    }
+    return(I);
+  }
+  else
+  {
+    for(i = 1; i <= m; i++)
+    {
+      I = subst(I,var(i),1);
+    }
+    return(I);
+  }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+proc nonMonomials(def id)
+"USAGE:  nonMonomials(id); id = <list of vectors> or <list of lists> or <module>
+         or <matrix>.@*
+         Let A= {a1,...,as} be a set of points in K^n, ai:=(ai1,...,ain), then
+         A can be given as@*
+          - a list of vectors (the ai are vectors) or@*
+          - a list of lists (the ai are lists of numbers) or@*
+          - a module s.t. the ai are generators or@*
+          - a matrix s.t. the ai are columns
+ASSUME:  basering must have ordering rp, i.e., be of the form 0,x(1..n),rp;
+         (the first entry of a point belongs to the lex-smallest variable, etc.)
+RETURN:  ideal, the non-monomials of the vanishing ideal I(A) of A
+PURPOSE: compute the set of non-monomials Mon(x(1),...,x(n)) \ {LM(f)|f in I(A)}
+         of the vanishing ideal I(A) of the given set of points A in K^n, where
+         K[x(1),...,x(n)] is equipped with the lexicographical ordering induced
+         by x(1)<...<x(n) by using the algorithm of Cerlienco-Mureddu
+EXAMPLE: example nonMonomials; shows an example
+"
+{
+  list A;
+  int i,j;
+  if(typeof(id) == "list")
+  {
+    for(i = 1; i <= size(id); i++)
+    {
+      if(typeof(id[i]) == "list")
+      {
+        vector a;
+        for(j = 1; j <= size(id[i]); j++)
+        {
+          a = a+id[i][j]*gen(j);
+        }
+        A[size(A)+1] = a;
+        kill a;
+      }
+      if(typeof(id[i]) == "vector")
+      {
+        A[size(A)+1] = id[i];
+      }
+    }
+  }
+  else
+  {
+    if(typeof(id) == "module")
+    {
+      for(i = 1; i <= size(id); i++)
+      {
+        A[size(A)+1] = id[i];
+      }
+    }
+    else
+    {
+      if(typeof(id) == "matrix")
+      {
+        for(i = 1; i <= ncols(id); i++)
+        {
+          A[size(A)+1] = id[i];
+        }
+      }
+      else
+      {
+        ERROR("Wrong type of input!!");
+      }
+    }
+  }
+
+  int n = nvars(basering);
+  int s;
+  int m,d;
+  ideal N = 1;
+  ideal N1,N2;
+  list Y,D,W,Z;
+  poly my,t;
+  for(s = 2; s <= size(A); s++)
+  {
+
+//-- compute m = max{ j | ex. i<s: pr_j(a_i) = pr_j(a_s)} ---------------------
+//-- compute d = |{ a_i | i<s: pr_m(a_i) = pr_m(a_s), phi(a_i) in T[1,m+1]}| --
+    m = 0;
+    Y = A[1..s-1];
+    N2 = N[1..s-1];
+    while(size(Y) > 0)      //assume all points different (m <= size(basering))
+    {
+      D = Y;
+      N1 = N2;
+      Y = list();
+      N2 = ideal();
+      m++;
+      for(i = 1; i <= size(D); i++)
+      {
+        if(A[s][m] == D[i][m])
+        {
+          Y[size(Y)+1] = D[i];
+          N2[size(N2)+1] = N1[i];
+        }
+      }
+    }
+    m = m - 1;
+    d = size(D);
+    if(m < n-1)
+    {
+      for(i = 1; i <= size(N1); i++)
+      {
+        if(N1[i] >= var(m+2))
+        {
+          d = d - 1;
+        }
+      }
+    }
+
+//------- compute t = my * x(m+1)^d where my is obtained recursively --------
+    if(m == 0)
+    {
+      my = 1;
+    }
+    else
+    {
+      Z = list();
+      for(i = 2; i <= s-1; i++)
+      {
+        if((leadexp(N[i])[m+1] == d) && (coeffs(N[i],var(m+1))[nrows(coeffs(N[i],var(m+1))),1] < var(m+1)))
+        {
+          Z[size(Z)+1] = A[i][1..m];
+        }
+      }
+      Z[size(Z)+1] = A[s][1..m];
+
+      my = nonMonomials(Z)[size(Z)];
+    }
+
+    t = my * var(m+1)^d;
+
+//---------------------------- t is added to N --------------------------------
+    N[size(N)+1] = t;
+  }
+  return(N);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring R1 = 0,x(1..3),rp;
+   vector a1 = [4,0,0];
+   vector a2 = [2,1,4];
+   vector a3 = [2,4,0];
+   vector a4 = [3,0,1];
+   vector a5 = [2,1,3];
+   vector a6 = [1,3,4];
+   vector a7 = [2,4,3];
+   vector a8 = [2,4,2];
+   vector a9 = [1,0,2];
+   list A = a1,a2,a3,a4,a5,a6,a7,a8,a9;
+   nonMonomials(A);
+
+   matrix MAT[9][3] = 4,0,0,2,1,4,2,4,0,3,0,1,2,1,3,1,3,4,2,4,3,2,4,2,1,0,2;
+   MAT = transpose(MAT);
+   print(MAT);
+   nonMonomials(MAT);
+
+   module MOD = gen(3),gen(2)-2*gen(3),2*gen(1)+2*gen(3),2*gen(2)-2*gen(3),gen(1)+3*gen(3),gen(1)+gen(2)+3*gen(3),gen(1)+gen(2)+gen(3);
+   print(MOD);
+   nonMonomials(MOD);
+
+   ring R2 = 0,x(1..2),rp;
+   list l1 = 0,0;
+   list l2 = 0,1;
+   list l3 = 2,0;
+   list l4 = 0,2;
+   list l5 = 1,0;
+   list l6 = 1,1;
+   list L = l1,l2,l3,l4,l5,l6;
+   nonMonomials(L);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+proc cornerMonomials(ideal N)
+"USAGE:  cornerMonomials(N); N ideal
+ASSUME:  N is given by monomials satisfying the condition that if a monomial is
+         in N then any of its factors is in N (N is then called an order ideal)
+RETURN:  ideal, the corner-monomials of the order ideal N @*
+         The corner-monomials are the leading monomials of an ideal I s.t. N is
+         a basis of basering/I.
+NOTE:    In our applications, I is the vanishing ideal of a finte set of points.
+EXAMPLE: example cornerMonomials; shows an example
+"
+{
+  int n = nvars(basering);
+  int i,j,h;
+  list C;
+  poly m,p;
+  int Z;
+  int vars;
+  intvec v;
+  ideal M;
+
+//-------------------- Test: Is 1 in N ?, if no, return <1> ----------------------
+  for(i = 1; i <= size(N); i++)
+  {
+    if(1 == N[i])
+    {
+      h = 1;
+      break;
+    }
+  }
+  if(h == 0)
+  {
+    return(ideal(1));
+  }
+
+//----------------------------- compute the set M -----------------------------
+  for(i = 1; i <= n; i++)
+  {
+    C[size(C)+1] = list(var(i),1);
+  }
+  while(size(C) > 0)
+  {
+    m = C[1][1];
+    Z = C[1][2];
+    C = delete(C,1);
+    vars = 0;
+    v = leadexp(m);
+    for(i = 1; i <= n; i++)
+    {
+      vars = vars + (v[i] != 0);
+    }
+
+    if(vars == Z)
+    {
+      h = 0;
+      for(i = 1; i <= size(N); i++)
+      {
+        if(m == N[i])
+        {
+          h = 1;
+          break;
+        }
+      }
+
+      if(h == 0)
+      {
+        M[size(M)+1] = m;
+      }
+      else
+      {
+        for(i = 1; i <= n; i++)
+        {
+          p = m * var(i);
+          if(size(C) == 0)
+          {
+            C[1] = list(p,1);
+          }
+          else
+          {
+            for(j = 1; j <= size(C); j++)
+            {
+              if(p <= C[j][1] || j == size(C))
+              {
+                if(p == C[j][1])
+                {
+                  C[j][2] = C[j][2] + 1;
+                }
+                else
+                {
+                  if(p < C[j][1])
+                  {
+                    C = insert(C,list(p,1),j-1);
+                  }
+                  else
+                  {
+                    C[size(C)+1] = list(p,1);
+                  }
+                }
+                break;
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  return(M);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring R = 0,x(1..3),rp;
+   poly n1 = 1;
+   poly n2 = x(1);
+   poly n3 = x(2);
+   poly n4 = x(1)^2;
+   poly n5 = x(3);
+   poly n6 = x(1)^3;
+   poly n7 = x(2)*x(3);
+   poly n8 = x(3)^2;
+   poly n9 = x(1)*x(2);
+   ideal N = n1,n2,n3,n4,n5,n6,n7,n8,n9;
+   cornerMonomials(N);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+proc facGBIdeal(def id)
+"USAGE:  facGBIdeal(id); id = <list of vectors> or <list of lists> or <module>
+         or <matrix>.@*
+         Let A= {a1,...,as} be a set of points in K^n, ai:=(ai1,...,ain), then
+         A can be given as@*
+          - a list of vectors (the ai are vectors) or@*
+          - a list of lists (the ai are lists of numbers) or@*
+          - a module s.t. the ai are generators or@*
+          - a matrix s.t. the ai are columns
+ASSUME:  basering must have ordering rp, i.e., be of the form 0,x(1..n),rp;
+         (the first entry of a point belongs to the lex-smallest variable, etc.)
+RETURN:  a list where the first entry contains the Groebner basis G of I(A)
+         and the second entry contains the linear factors of each element of G
+NOTE:    combinatorial algorithm due to the Axis-of-Evil Theorem of M.G.
+         Marinari, T. Mora
+EXAMPLE: example facGBIdeal; shows an example
+"
+{
+  list A;
+  int i,j;
+  if(typeof(id) == "list")
+  {
+    for(i = 1; i <= size(id); i++)
+    {
+      if(typeof(id[i]) == "list")
+      {
+        vector a;
+        for(j = 1; j <= size(id[i]); j++)
+        {
+          a = a+id[i][j]*gen(j);
+        }
+        A[size(A)+1] = a;
+        kill a;
+      }
+      if(typeof(id[i]) == "vector")
+      {
+        A[size(A)+1] = id[i];
+      }
+    }
+  }
+  else
+  {
+    if(typeof(id) == "module")
+    {
+      for(i = 1; i <= size(id); i++)
+      {
+        A[size(A)+1] = id[i];
+      }
+    }
+    else
+    {
+      if(typeof(id) == "matrix")
+      {
+        for(i = 1; i <= ncols(id); i++)
+        {
+          A[size(A)+1] = id[i];
+        }
+      }
+      else
+      {
+        ERROR("Wrong type of input!!");
+      }
+    }
+  }
+
+  int n = nvars(basering);
+  def S = basering;
+  def R;
+
+  ideal N = nonMonomials(A);
+  ideal eN;
+  ideal M = cornerMonomials(N);
+  poly my, emy;
+
+  int d,k,l,m;
+
+  int d1;
+  poly y(1);
+
+  list N2,D,H;
+  poly z,h;
+
+  int dm;
+  list Am,Z;
+  ideal E;
+  list V,eV;
+  poly p;
+  poly y(2..n),y;
+  poly xi;
+
+  poly f;
+  ideal G1;          // stores the elements of G, i.e. G1 = G the GB of I(A)
+  ideal Y;           // stores the linear factors of GB-elements in each loop
+  list G2;           // contains the linear factors of each element of G
+
+  for(j = 1; j <= size(M); j++)
+  {
+    my = M[j];
+    emy = subst(my,var(1),1);         // auxiliary polynomial
+    eN = subst(N,var(1),1);           // auxiliary monomial ideal
+    Y = ideal();
+
+    d1 = leadexp(my)[1];
+    y(1) = 1;
+    i = 0;
+    k = 1;
+    while(i < d1)
+    {
+//---------- searching for phi^{-1}(x_1^i*x_2^d_2*...*x_n^d_n) ----------------
+      while(my*var(1)^i/var(1)^d1 != N[k])
+      {
+        k++;
+      }
+      y(1) = y(1)*(var(1)-A[k][1]);
+      Y[size(Y)+1] = cleardenom(var(1)-A[k][1]);
+      i++;
+    }
+    f = y(1);                             // gamma_1my
+
+//--------------- Recursion over number of variables --------------------------
+    z = 1;                                // zeta_mmy
+    for(m = 2; m <= n; m++)
+    {
+      z = z * y(m-1);
+
+      D = list();
+      H = list();
+      for(i = 1; i <= size(A); i++)
+      {
+        h = z;
+        for(k = 1; k <= n; k++)
+        {
+          h = subst(h,var(k),A[i][k]);
+        }
+        if(h != 0)
+        {
+          D[size(D)+1] = A[i];
+          H[size(H)+1] = i;
+        }
+      }
+
+      if(size(D) == 0)
+      {
+        break;
+      }
+
+      dm = leadexp(my)[m];
+      while(dm == 0)
+      {
+        m = m + 1;
+        dm = leadexp(my)[m];
+      }
+
+      N2 = list();                        // N2 = N_m
+      emy = subst(emy,var(m),1);
+      eN = subst(eN,var(m),1);
+      for(i = 1; i <= size(N); i++)
+      {
+        if((emy == eN[i]) && (my > N[i]))
+        {
+          N2[size(N2)+1] = N[i];
+        }
+      }
+
+      y(m) = 1;
+      xi = z;
+      for(d = 1; d <= dm; d++)
+      {
+        Am = list();
+        Z = list();                       // Z = pr_m(Am)
+
+//------- V contains all ny*x_m^{d_m-d}*x_m+1^d_m+1*...+x_n^d_n in N_m --------
+        eV = subst1(N2,m-1);
+        V = list();
+        for(i = 1; i <= size(eV); i++)
+        {
+          if(eV[i] == subst1(my,m-1)/var(m)^d)
+          {
+            V[size(V)+1] = eV[i];
+          }
+        }
+
+//------- A_m = phi^{-1}(V) intersect D_md-1 ----------------------------------
+        for(i = 1; i <= size(D); i++)
+        {
+          p = N[H[i]];
+          p = subst1(p,m-1);
+          for(l = 1; l <= size(V); l++)
+          {
+            if(p == V[l])
+            {
+              Am[size(Am)+1] = D[i];
+              Z[size(Z)+1] = D[i][1..m];
+              break;
+            }
+          }
+        }
+
+        E = nonMonomials(Z);
+
+        R = extendring(size(E), "c(", "lp");
+        setring R;
+        ideal E = imap(S,E);
+        list Am = imap(S,Am);
+        poly g = var(size(E)+m);
+        for(i = 1; i <= size(E); i++)
+        {
+          g = g + c(i)*E[i];
+        }
+
+        ideal I = ideal();
+        poly h;
+        for (i = 1; i <= size(Am); i++)
+        {
+          h = g;
+          for(k = 1; k <= n; k++)
+          {
+            h = subst(h,var(size(E)+k),Am[i][k]);
+          }
+          I[size(I)+1] = h;
+        }
+
+        ideal sI = std(I);
+        g = reduce(g,sI);
+
+        setring S;
+        y = imap(R,g);
+        Y[size(Y)+1] = cleardenom(y);
+        xi = xi * y;
+
+        D = list();
+        H = list();
+        for(i = 1; i <= size(A); i++)
+        {
+          h = xi;
+          for(k = 1; k <= n; k++)
+          {
+            h = subst(h,var(k),A[i][k]);
+          }
+          if(h != 0)
+          {
+            D[size(D)+1] = A[i];
+            H[size(H)+1] = i;
+          }
+        }
+
+        y(m) = y(m) * y;
+
+        if(size(D) == 0)
+        {
+          break;
+        }
+      }
+
+      f = f * y(m);
+    }
+    G1[size(G1)+1] = f;
+    G2[size(G2)+1] = Y;
+  }
+  return(list(G1,G2));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring R = 0,x(1..3),rp;
+   vector a1 = [4,0,0];
+   vector a2 = [2,1,4];
+   vector a3 = [2,4,0];
+   vector a4 = [3,0,1];
+   vector a5 = [2,1,3];
+   vector a6 = [1,3,4];
+   vector a7 = [2,4,3];
+   vector a8 = [2,4,2];
+   vector a9 = [1,0,2];
+   list A = a1,a2,a3,a4,a5,a6,a7,a8,a9;
+   facGBIdeal(A);
+
+   matrix MAT[9][3] = 4,0,0,2,1,4,2,4,0,3,0,1,2,1,3,1,3,4,2,4,3,2,4,2,1,0,2;
+   MAT = transpose(MAT);
+   print(MAT);
+   facGBIdeal(MAT);
+
+   module MOD = gen(3),gen(2)-2*gen(3),2*gen(1)+2*gen(3),2*gen(2)-2*gen(3),gen(1)+3*gen(3),gen(1)+gen(2)+3*gen(3),gen(1)+gen(2)+gen(3);
+   print(MOD);
+   facGBIdeal(MOD);
+
+   list l1 = 0,0,1;
+   list l2 = 0,1,-2;
+   list l3 = 2,0,2;
+   list l4 = 0,2,-2;
+   list l5 = 1,0,3;
+   list l6 = 1,1,3;
+   list L = l1,l2,l3,l4,l5,l6;
+   facGBIdeal(L);
+}
diff --git a/Singular/LIB/poly.lib b/Singular/LIB/poly.lib
new file mode 100644
index 0000000..d58bed2
--- /dev/null
+++ b/Singular/LIB/poly.lib
@@ -0,0 +1,1165 @@
+////////////////////////////////////////////////////////////////////////////
+version="version poly.lib 4.0.0.0 Jun_2013 "; // $Id: b8d784bd08cf3ce08a16ba9c8c7a531b489eb012 $
+category="General purpose";
+info="
+LIBRARY:  poly.lib      Procedures for Manipulating Polys, Ideals, Modules
+AUTHORS:  O. Bachmann, G.-M. Greuel, A. Fruehbis
+
+PROCEDURES:
+ cyclic(int);           ideal of cyclic n-roots
+ elemSymmId(int);       ideal of elementary symmetric polynomials
+ katsura([i]);          katsura [i] ideal
+ freerank(poly/...)     rank of coker(input) if coker is free else -1
+ is_zero(poly/...);     int, =1 resp. =0 if coker(input) is 0 resp. not
+ lcm(ideal);            lcm of given generators of ideal
+ maxcoef(poly/...);     maximal length of coefficient occurring in poly/...
+ maxdeg(poly/...);      int/intmat = degree/s of terms of maximal order
+ maxdeg1(poly/...);     int = [weighted] maximal degree of input
+ mindeg(poly/...);      int/intmat = degree/s of terms of minimal order
+ mindeg1(poly/...);     int = [weighted] minimal degree of input
+ normalize(poly/...);   normalize poly/... such that leading coefficient is 1
+ rad_con(p,I);          check radical containment of polynomial p in ideal I
+ content(f);            content of polynomial/vector f
+ mod2id(M,iv);          conversion of a module M to an ideal
+ id2mod(i,iv);          conversion inverse to mod2id
+ substitute(I,...)      substitute in I variables by polynomials
+ subrInterred(i1,i2,iv);interred w.r.t. a subset of variables
+ newtonDiag(f);         Newton diagram of a polynomial
+ hilbPoly(I);           Hilbert polynomial of basering/I
+          (parameters in square brackets [] are optional)
+
+";
+
+LIB "general.lib";
+LIB "ring.lib";
+///////////////////////////////////////////////////////////////////////////////
+static proc bino(int a, int b)
+{
+//computes binomial var(1)+a over b
+   int i;
+   if(b==0){return(1);}
+   poly p=(var(1)+a)/b;
+   for(i=1;i<=b-1;i++)
+   {
+      p=p*(var(1)+a-i)/i;
+   }
+   return(p);
+}
+
+proc hilbPoly(ideal I)
+"USAGE: hilbPoly(I); I a homogeneous ideal
+RETURN: the Hilbert polynomial of basering/I as an intvec v=v_0,...,v_r
+        such that the Hilbert polynomial is (v_0+v_1*t+...v_r*t^r)/r!
+EXAMPLE: example hilbPoly; shows an example
+"
+{
+   def R=basering;
+   if(!attrib(I,"isSB")){I=std(I);}
+   intvec v=hilb(I,2);
+   int s=dim(I);
+   intvec hp;
+   if(s==0){return(hp);}
+   int d=size(v)-2;
+   ring S=0,t,dp;
+   poly p=v[1+d]*bino(s-1-d,s-1);
+   int i;
+   for(i=1;i<=d;i++)
+   {
+      p=p+v[d-i+1]*bino(s-1-d+i,s-1);
+   }
+   int n=1;
+   for(i=2;i<=s-1;i++){n=n*i;}
+   p=n*p;
+   hp[s]=int(leadcoef(p));
+   for(i=2;i<=size(p);i++)
+   {
+      hp[leadexp(p[i])+1]=int(leadcoef(p[i]));
+   }
+   setring R;
+   return(hp);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r = 0,(b,c,t,h),dp;
+   ideal I=
+   bct-t2h+2th2+h3,
+   bt3-ct3-t4+b2th+c2th-2bt2h+2ct2h+2t3h-bch2-2bth2+2cth2+2th3,
+   b2c2+bt2h-ct2h-t3h+b2h2+2bch2+c2h2-2bth2+2cth2+t2h2-2bh3+2ch3+2th3+3h4,
+   c2t3+ct4-c3th-2c2t2h-2ct3h-t4h+bc2h2-2c2th2-bt2h2+4t3h2+2bth3-2cth3-t2h3
+   +bh4-6th4-2h5;
+   hilbPoly(I);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+proc substitute (def I,list #)
+"USAGE:  - case 1: typeof(#[1])==poly:
+           substitute (I,v,f[,v1,f1,v2,f2,...]); I object of basering which
+           can be mapped, v,v1,v2,.. ring variables, f,f1,f2,... poly
+@*       - case 2: typeof(#[1])==ideal:
+           substitute (I,v,f); I object of basering which can be mapped,
+           v ideal of ring variables, f ideal
+RETURN:  object of same type as I,
+@*       - case 1: ring variable v,v1,v2,... substituted by polynomials
+           f,f1,f2,..., in this order
+@*       - case 2: ring variables in v substituted by polynomials in f:
+           v[i] is substituted by f[i], i=1,...,i=min(size(v),ncols(f))
+NOTE:    this procedure extends the built-in command subst via maps
+EXAMPLE: example substitute; shows an example
+"
+{
+  def bas = basering;
+  ideal m = maxideal(1);
+  int i,ii;
+  if(typeof(#[1])=="poly")
+  {
+    poly v = #[1];
+    poly f = #[2];
+    map phi = bas,m;
+    def J = I;
+    for (ii=1; ii<=size(#) - 1; ii=ii+2)
+    {
+      m = maxideal(1);
+      i=rvar(#[ii]);
+      m[i] = #[ii+1];
+      phi = bas,m;
+      J = phi(J);
+    }
+    return(J);
+  }
+  if(typeof(#[1])=="ideal")
+  {
+    ideal v = #[1];
+    ideal f = #[2];
+    int mi = ncols(v);
+    if(ncols(f)<mi)
+    {
+      mi = ncols(f);
+    }
+    def J = I;
+    for (ii=1; ii<=mi; ii++)
+    {
+      m[rvar(v[ii])]=f[ii];
+    }
+    map phi = bas,m;
+    J = phi(I);
+    return(J);
+  }
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r = 0,(b,c,t),dp;
+   ideal I = -bc+4b2c2t,bc2t-5b2c;
+   substitute(I,c,b+c,t,0,b,b-1);
+   ideal v = c,t,b;
+   ideal f = b+c,0,b-1;
+   substitute(I,v,f);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+proc cyclic (int n)
+"USAGE:   cyclic(n);  n integer
+RETURN:  ideal of cyclic n-roots from 1-st n variables of basering
+EXAMPLE: example cyclic; shows examples
+"
+{
+//----------------------------- procedure body --------------------------------
+   ideal m = maxideal(1);
+   m = m[1..n],m[1..n];
+   int i,j;
+   ideal s; poly t;
+   for ( j=0; j<=n-2; j++ )
+   {
+      t=0;
+      for( i=1;i<=n;i++ ) { t=t+product(m,i..i+j); }
+      s=s+t;
+   }
+   s=s,product(m,1..n)-1;
+   return (s);
+}
+//-------------------------------- examples -----------------------------------
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r=0,(u,v,w,x,y,z),lp;
+   cyclic(nvars(basering));
+   homog(cyclic(5),z);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+proc elemSymmPoly(int d, int lindex, int hindex)
+"USAGE:  elemSymmPoly(d,lindex,hindex); d,lindex,hindex integers
+RETURN:  elementary symmetric polynomial of degree d for variables
+@*       var(lindex),...,var(hindex) of basering
+EXAMPLE: example elemSymmPoly; shows an example
+"
+{
+ if(hindex - lindex + 1 < d)
+ {
+   int i = hindex - lindex + 1;
+   "========================================================";
+   "There is no elementary symmetric polynomial of degree "+string(d);
+   "for just "+string(i)+" variables.";
+   "========================================================";
+   return(poly(0));
+ }
+ if(d == 0)
+ {
+   return(poly(1));
+ }
+ else
+ {
+   int i;
+   poly p;
+   for (i = lindex; i <=  hindex - d + 1; i++)
+   {
+     p = p + var(i) * elemSymmPoly(d - 1, i + 1, hindex);
+   }
+   return(p);
+ }
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring R = 0, (u,v,w,x,y,z), lp;
+  elemSymmPoly(3,2,5);
+  elemSymmPoly(6,1,6);
+}
+
+//////////////////////////////////////////////////////////////////////////
+proc elemSymmId(int n)
+"USAGE:  elemSymmId(n); n integer
+RETURN:  ideal of elementary symmetric polynomials for 1-st n
+@*       variables of basering
+EXAMPLE: example elemSymmId; shows an example
+{
+ int i;
+ ideal symm;
+ for(i = 1; i <= n; i++)
+ {
+   symm = symm + elemSymmPoly(i, 1, n);
+ }
+ return(symm);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring R = 0, (v,w,x,y,z), lp;
+  elemSymmId(3);
+  elemSymmId(nvars(basering));
+}
+
+//////////////////////////////////////////////////////////////////////////
+proc katsura
+"USAGE: katsura([n]); n integer
+RETURN: katsura(n) : n-th katsura ideal of
+         (1) newly created and set ring (32003, x(0..n), dp), if
+             nvars(basering) < n
+         (2) basering, if nvars(basering) >= n
+        katsura()  : katsura ideal of basering
+EXAMPLE: example katsura; shows examples
+"
+{
+  int n;
+  if ( size(#) == 1 && typeof(#[1]) == "int")
+  {
+    n = #[1] - 1;
+    while (1)
+    {
+      if (defined(basering))
+      {
+        if (nvars(basering) >= #[1]) {break;}
+      }
+      ring katsura_ring = 32003, x(0..#[1]), dp;
+      keepring katsura_ring;
+      break;
+    }
+  }
+  else
+  {
+    n = nvars(basering) -1;
+  }
+
+  ideal s;
+  int i, j;
+  poly p;
+
+  p = -1;
+  for (i = -n; i <= n; i++)
+  {
+    p = p + kat_var(i, n);
+  }
+  s[1] = p;
+
+  for (i = 0; i < n; i++)
+  {
+    p = -1 * kat_var(i,n);
+    for (j = -n; j <= n; j++)
+    {
+      p = p + kat_var(j,n) * kat_var(i-j, n);
+    }
+    s = s,p;
+  }
+  return (s);
+}
+//-------------------------------- examples -----------------------------------
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r; basering;
+  katsura();
+  katsura(4); basering;
+}
+
+proc kat_var(int i, int n)
+{
+  poly p;
+  if (i < 0)  { i = -i;}
+  if (i <= n) { p = var(i+1); }
+  return (p);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc freerank
+"USAGE:   freerank(M[,any]);  M=poly/ideal/vector/module/matrix
+COMPUTE: rank of module presented by M in case it is free.
+         By definition this is vdim(coker(M)/m*coker(M)) if coker(M)
+         is free, where m is the maximal ideal of the variables of the
+         basering and M is considered to be a matrix.
+         (the 0-module is free of rank 0)
+RETURN:  rank of coker(M) if coker(M) is free and -1 else;
+         in case of a second argument return a list:
+                L[1] = rank of coker(M) or -1
+                L[2] = minbase(M)
+NOTE:    freerank(syz(M)); computes the rank of M if M is free (and -1 else)
+EXAMPLE: example freerank; shows examples
+"
+{
+  int rk;
+  def M = simplify(#[1],10);
+  resolution mre = res(M,2);
+  intmat B = betti(mre);
+  if ( ncols(B)>1 ) { rk = -1; }
+  else { rk = sum(B[1..nrows(B),1]); }
+  if (size(#) == 2) { list L=rk,mre[1]; return(L);}
+  return(rk);
+}
+example
+{"EXAMPLE";   echo=2;
+  ring r;
+  ideal i=x;
+  module M=[x,0,1],[-x,0,-1];
+  freerank(M);          // should be 2, coker(M) is not free
+  freerank(syz (M),"");
+  // [1] should be 1, coker(syz(M))=M is free of rank 1
+  // [2] should be gen(2)+gen(1) (minimal relation of M)
+  freerank(i);
+  freerank(syz(i));     // should be 1, coker(syz(i))=i is free of rank 1
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc is_zero
+"USAGE:   is_zero(M[,any]); M=poly/ideal/vector/module/matrix
+RETURN:  integer, 1 if coker(M)=0 resp. 0 if coker(M)!=0, where M is
+         considered as matrix.
+         If a second argument is given, return a list:
+                L[1] = 1 if coker(M)=0 resp. 0 if coker(M)!=0
+                L[2] = dim(M)
+EXAMPLE: example is_zero; shows examples
+"
+{
+  int d=dim(std(#[1]));
+  int a = ( d==-1 );
+  if( size(#) >1 ) { return(list(a,d)); }
+  return(a);
+}
+example
+{ "EXAMPLE:";   echo=2;
+  ring r;
+  module m = [x],[y],[1,z];
+  is_zero(m,1);
+  qring q = std(ideal(x2+y3+z2));
+  ideal j = x2+y3+z2-37;
+  is_zero(j);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc maxcoef (def f)
+"USAGE:   maxcoef(f);  f  poly/ideal/vector/module/matrix
+RETURN:  maximal length of coefficient of f of type int (by measuring the
+         length of the string of each coefficient)
+EXAMPLE: example maxcoef; shows examples
+"
+{
+//----------------------------- procedure body --------------------------------
+   int max,s,ii,jj; string t;
+   ideal i = ideal(matrix(f));
+   i = simplify(i,6);            // delete 0's and keep first of equal elements
+   poly m = var(1); matrix C;
+   for (ii=2;ii<=nvars(basering);ii++) { m = m*var(ii); }
+   for (ii=1; ii<=size(i); ii++)
+   {
+      C = coef(i[ii],m);
+      for (jj=1; jj<=ncols(C); jj++)
+      {
+         t = string(C[2,jj]);  s = size(t);
+         if ( t[1] == "-" ) { s = s - 1; }
+         if ( s > max ) { max = s; }
+      }
+   }
+   return(max);
+}
+//-------------------------------- examples -----------------------------------
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r= 0,(x,y,z),ds;
+   poly g = 345x2-1234567890y+7/4z;
+   maxcoef(g);
+   ideal i = g,10/1234567890;
+   maxcoef(i);
+   // since i[2]=1/123456789
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc maxdeg (def id)
+"USAGE:   maxdeg(id);  id  poly/ideal/vector/module/matrix
+RETURN:  int/intmat, each component equals maximal degree of monomials in the
+         corresponding component of id, independent of ring ordering
+         (maxdeg of each var is 1).
+         Of type int, if id is of type poly; of type intmat otherwise
+SEE ALSO: maxdeg1
+EXAMPLE: example maxdeg; shows examples
+"
+{
+   //-------- subprocedure to find maximal degree of given component ----------
+   proc findmaxdeg
+   {
+      poly c = #[1];
+      if (c==0) { return(-1); }
+   //--- guess upper 'o' and lower 'u' bound, in case of negative weights -----
+      int d = (deg(c)>=0)*deg(c)-(deg(c)<0)*deg(c);
+      int i = d;
+      while ( c-jet(c,i) != 0 ) { i = 2*(i+1); }
+      int o = i-1;
+      int u = (d != i)*((i div  2)-1);
+   //----------------------- "quick search" for maxdeg ------------------------
+      while ( (c-jet(c,i)==0)*(c-jet(c,i-1)!=0) == 0)
+      {
+         i = (o+1+u) div  2;
+         if (c-jet(c,i)!=0) { u = i+1; }
+         else { o = i-1; }
+      }
+      return(i);
+   }
+//------------------------------ main program ---------------------------------
+   matrix M = matrix(id);
+   int r,c = nrows(M), ncols(M); int i,j;
+   intmat m[r][c];
+   for (i=r; i>0; i--)
+   {
+      for (j=c; j>0; j--) { m[i,j] = findmaxdeg(M[i,j]); }
+   }
+   if (typeof(id)=="poly") { return(m[1,1]); }
+   return(m);
+}
+//-------------------------------- examples -----------------------------------
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r = 0,(x,y,z),wp(1,2,3);
+   poly f = x+y2+z3;
+   deg(f);             //deg; returns weighted degree (in case of 1 block)!
+   maxdeg(f);
+   matrix m[2][2]=f+x10,1,0,f^2;
+   maxdeg(m);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc maxdeg1 (def id,list #)
+"USAGE:   maxdeg1(id[,v]);  id=poly/ideal/vector/module/matrix, v=intvec
+RETURN:  integer, maximal [weighted] degree of monomials of id independent of
+         ring ordering, maxdeg1 of i-th variable is v[i] (default: v=1..1).
+NOTE:    This proc returns one integer while maxdeg returns, in general,
+         a matrix of integers. For one polynomial and if no intvec v is given
+         maxdeg is faster
+EXAMPLE: example maxdeg1; shows examples
+"
+{
+   //-------- subprocedure to find maximal degree of given component ----------
+   proc findmaxdeg
+   {
+      poly c = #[1];
+      if (c==0) { return(-1); }
+      intvec v = #[2];
+   //--- guess upper 'o' and lower 'u' bound, in case of negative weights -----
+      int d = (deg(c)>=0)*deg(c)-(deg(c)<0)*deg(c);
+      int i = d;
+      if ( c == jet(c,-1,v))      //case: maxdeg is negative
+      {
+         i = -d;
+         while ( c == jet(c,i,v) ) { i = 2*(i-1); }
+         int o = (d != -i)*((i div  2)+2) - 1;
+         int u = i+1;
+         int e = -1;
+      }
+      else                        //case: maxdeg is nonnegative
+      {
+         while ( c != jet(c,i,v) ) { i = 2*(i+1); }
+         int o = i-1;
+         int u = (d != i)*((i div  2)-1);
+         int e = 1;
+      }
+   //----------------------- "quick search" for maxdeg ------------------------
+      while ( ( c==jet(c,i,v) )*( c!=jet(c,i-1,v) ) == 0 )
+      {
+         i = (o+e+u) div  2;
+         if ( c!=jet(c,i,v) ) { u = i+1; }
+         else { o = i-1; }
+      }
+      return(i);
+   }
+//------------------------------ main program ---------------------------------
+   ideal M = simplify(ideal(matrix(id)),8);   //delete scalar multiples from id
+   int c = ncols(M);
+   int i,n;
+   if( size(#)==0 )
+   {
+      int m = maxdeg(M[c]);
+      for (i=c-1; i>0; i--)
+      {
+          n = maxdeg(M[i]);
+          m = (m>=n)*m + (m<n)*n;             //let m be the maximum of m and n
+      }
+   }
+   else
+   {
+      intvec v=#[1];                          //weight vector for the variables
+      int m = findmaxdeg(M[c],v);
+      for (i=c-1; i>0; i--)
+      {
+         n = findmaxdeg(M[i],v);
+         if( n>m ) { m=n; }
+      }
+   }
+   return(m);
+}
+//-------------------------------- examples -----------------------------------
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r = 0,(x,y,z),wp(1,2,3);
+   poly f = x+y2+z3;
+   deg(f);            //deg returns weighted degree (in case of 1 block)!
+   maxdeg1(f);
+   intvec v = ringweights(r);
+   maxdeg1(f,v);                        //weighted maximal degree
+   matrix m[2][2]=f+x10,1,0,f^2;
+   maxdeg1(m,v);                        //absolute weighted maximal degree
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc mindeg (def id)
+"USAGE:   mindeg(id);  id  poly/ideal/vector/module/matrix
+RETURN:  minimal degree/s of monomials of id, independent of ring ordering
+         (mindeg of each variable is 1) of type int if id of type poly, else
+         of type intmat.
+SEE ALSO: mindeg1
+EXAMPLE: example mindeg; shows examples
+"
+{
+   //--------- subprocedure to find minimal degree of given component ---------
+   proc findmindeg
+   {
+      poly c = #[1];
+      if (c==0) { return(-1); }
+   //--- guess upper 'o' and lower 'u' bound, in case of negative weights -----
+      int d = (ord(c)>=0)*ord(c)-(ord(c)<0)*ord(c);
+      int i = d;
+      while ( jet(c,i) == 0 ) { i = 2*(i+1); }
+      int o = i-1;
+      int u = (d != i)*((i div  2)-1);
+   //----------------------- "quick search" for mindeg ------------------------
+      while ( (jet(c,u)==0)*(jet(c,o)!=0) )
+      {
+         i = (o+u) div 2;
+         if (jet(c,i)==0) { u = i+1; }
+         else { o = i-1; }
+      }
+      if (jet(c,u)!=0) { return(u); }
+      else { return(o+1); }
+   }
+//------------------------------ main program ---------------------------------
+   matrix M = matrix(id);
+   int r,c = nrows(M), ncols(M); int i,j;
+   intmat m[r][c];
+   for (i=r; i>0; i--)
+   {
+      for (j=c; j>0; j--) { m[i,j] = findmindeg(M[i,j]); }
+   }
+   if (typeof(id)=="poly") { return(m[1,1]); }
+   return(m);
+}
+//-------------------------------- examples -----------------------------------
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r = 0,(x,y,z),ls;
+   poly f = x5+y2+z3;
+   ord(f);                  // ord returns weighted order of leading term!
+   mindeg(f);               // computes minimal degree
+   matrix m[2][2]=x10,1,0,f^2;
+   mindeg(m);               // computes matrix of minimum degrees
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc mindeg1 (def id, list #)
+"USAGE:   mindeg1(id[,v]);  id=poly/ideal/vector/module/matrix, v=intvec
+RETURN:  integer, minimal [weighted] degree of monomials of id independent of
+         ring ordering, mindeg1 of i-th variable is v[i] (default v=1..1).
+NOTE:    This proc returns one integer while mindeg returns, in general,
+         a matrix of integers. For one polynomial and if no intvec v is given
+         mindeg is faster.
+EXAMPLE: example mindeg1; shows examples
+"
+{
+   //--------- subprocedure to find minimal degree of given component ---------
+   proc findmindeg
+   {
+      poly c = #[1];
+      intvec v = #[2];
+      if (c==0) { return(-1); }
+   //--- guess upper 'o' and lower 'u' bound, in case of negative weights -----
+      int d = (ord(c)>=0)*ord(c)-(ord(c)<0)*ord(c);
+      int i = d;
+      if ( jet(c,-1,v) !=0 )      //case: mindeg is negative
+      {
+         i = -d;
+         while ( jet(c,i,v) != 0 ) { i = 2*(i-1); }
+         int o = (d != -i)*((i div  2)+2) - 1;
+         int u = i+1;
+         int e = -1; i=u;
+      }
+      else                        //case: inded is nonnegative
+      {
+         while ( jet(c,i,v) == 0 ) { i = 2*(i+1); }
+         int o = i-1;
+         int u = (d != i)*((i div  2)-1);
+         int e = 1; i=u;
+      }
+   //----------------------- "quick search" for mindeg ------------------------
+      while ( (jet(c,i-1,v)==0)*(jet(c,i,v)!=0) == 0 )
+      {
+         i = (o+e+u) div  2;
+         if (jet(c,i,v)==0) { u = i+1; }
+         else { o = i-1; }
+      }
+      return(i);
+   }
+//------------------------------ main program ---------------------------------
+   ideal M = simplify(ideal(matrix(id)),8);   //delete scalar multiples from id
+   int c = ncols(M);
+   int i,n;
+   if( size(#)==0 )
+   {
+      int m = mindeg(M[c]);
+      for (i=c-1; i>0; i--)
+      {
+          n = mindeg(M[i]);
+          m = (m<=n)*m + (m>n)*n;             //let m be the maximum of m and n
+      }
+   }
+   else
+   {
+      intvec v=#[1];                          //weight vector for the variables
+      int m = findmindeg(M[c],v);
+      for (i=c-1; i>0; i--)
+      {
+         n = findmindeg(M[i],v);
+         m = (m<=n)*m + (m>n)*n;              //let m be the maximum of m and n
+      }
+   }
+   return(m);
+}
+//-------------------------------- examples -----------------------------------
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r = 0,(x,y,z),ls;
+   poly f = x5+y2+z3;
+   ord(f);                  // ord returns weighted order of leading term!
+   intvec v = 1,-3,2;
+   mindeg1(f,v);            // computes minimal weighted degree
+   matrix m[2][2]=x10,1,0,f^2;
+   mindeg1(m,1..3);         // computes absolute minimum of weighted degrees
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc normalize (def id)
+"USAGE:   normalize(id);  id=poly/vector/ideal/module
+RETURN:  object of same type
+         each element is normalized with leading coefficient equal to 1
+EXAMPLE: example normalize; shows an example
+"
+{
+   return(simplify(id,1));
+}
+//-------------------------------- examples -----------------------------------
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r = 0,(x,y,z),ls;
+   poly f = 2x5+3y2+4z3;
+   normalize(f);
+   module m=[9xy,0,3z3],[4z,6y,2x];
+   normalize(m);
+   ring s = 0,(x,y,z),(c,ls);
+   module m=[9xy,0,3z3],[4z,6y,2x];
+   normalize(m);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////////
+// Input: <ideal>=<f1,f2,...,fm> and <polynomial> g
+// Question: Does g lie in the radical of <ideal>?
+// Solution: Compute a standard basis G for <f1,f2,...,fm,gz-1> where z is a
+//           new variable. Then g is contained in the radical of <ideal> <=>
+//           1 is generator in G.
+///////////////////////////////////////////////////////////////////////////////
+proc rad_con (poly g,ideal I)
+"USAGE:   rad_con(g,I); g polynomial, I ideal
+RETURN:  1 (TRUE) (type int) if g is contained in the radical of I
+@*       0 (FALSE) (type int) otherwise
+EXAMPLE: example rad_con; shows an example
+"
+{ def br=basering;
+  int n=nvars(br);
+  int dB=degBound;
+  degBound=0;
+  string mp=string(minpoly);
+  if (attrib(br,"global")==1)
+  {
+    execute("ring R=("+charstr(br)+"),(@x(1..n), at z),dp;");
+  }
+  else
+  {
+    execute("ring R=("+charstr(br)+"),(@z, at x(1..n)),(dp(1),"+ordstr(br)+");");
+  }
+  if (mp!="0")
+  {
+    execute("minpoly=number("+mp+");");
+  }
+  ideal irrel=@x(1..n);
+  map f=br,irrel;
+  poly p=f(g);
+  ideal J=f(I),ideal(p*@z-1);
+  J=std(J);
+  degBound=dB;
+  if (J[1]==1)
+  {
+     setring br;
+     return(1);
+  }
+  else
+  {
+     setring br;
+     return(0);
+  }
+}
+example
+{ "EXAMPLE:"; echo=2;
+   ring R=0,(x,y,z),dp;
+   ideal I=x2+y2,z2;
+   poly f=x4+y4;
+   rad_con(f,I);
+   ideal J=x2+y2,z2,x4+y4;
+   poly g=z;
+   rad_con(g,I);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc lcm (def id, list #)
+"USAGE:   lcm(p[,q]); p int/intvec q a list of integers or
+          p poly/ideal q a list of polynomials
+RETURN:  the least common multiple of p and q:
+@*         - of type int if p is an int/intvec
+@*         - of type poly if p is a poly/ideal
+EXAMPLE: example lcm; shows an example
+"
+{
+  int k,j;
+//------------------------------ integer case --------------------------------
+  if( typeof(id) == "int" or typeof(id) == "intvec" )
+  {
+     intvec i = id;
+     if (size(#)!=0)
+     {
+        for (j = 1; j<=size(#); j++)
+        {
+           if (typeof(#[j]) !="int" and typeof(#[j]) !="intvec")
+           { ERROR("// ** list element must be an integer");}
+           else
+           { i = i,#[j]; }
+        }
+     }
+     int p,q;
+     if( i == 0 )
+     {
+        return(0);
+     }
+     for(j=1;j<=size(i);j++)
+     {
+       if( i[j] != 0 )
+       {
+         p=i[j];
+         break;
+       }
+     }
+     for (k=j+1;k<=size(i);k++)
+     {
+        if( i[k] !=0)
+        {
+           q=gcd(p,i[k]);
+           p=p div q;
+           p=p*i[k];
+        }
+     }
+     if(p <0 )
+     {return(-p);}
+     return(p);
+   }
+
+//----------------------------- polynomial case ------------------------------
+  if( typeof(id) == "poly" or typeof(id) == "ideal" )
+  {
+     ideal i = id;
+     if (size(#)!=0)
+     {
+        for (j = 1; j<=size(#); j++)
+        {
+           if (typeof(#[j]) !="poly" and typeof(#[j]) !="ideal"
+              and typeof(#[j]) !="int" and typeof(#[j]) !="intvec")
+           { ERROR("// ** list element must be a polynomial");}
+           else
+           { i = i,#[j]; }
+        }
+     }
+     poly p,q;
+     i=simplify(i,10);
+     if(size(i) == 0)
+     {
+        return(0);
+     }
+     for(j=1;j<=size(i);j++)
+     {
+       if(maxdeg(i[j])!= 0)
+       {
+         p=i[j];
+         break;
+       }
+     }
+     if(p==0)
+     {
+       return(1);
+     }
+     for (k=j+1;k<=size(i);k++)
+     {
+        if(maxdeg(i[k])!=0)
+        {
+           q=gcd(p,i[k]);
+           if(maxdeg(q)==0)
+           {
+             p=p*i[k];
+           }
+           else
+           {
+             p=p/q;
+             p=p*i[k];
+           }
+        }
+     }
+     return(p);
+   }
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring  r = 0,(x,y,z),lp;
+   poly  p = (x+y)*(y+z);
+   poly  q = (z4+2)*(y+z);
+   lcm(p,q);
+   ideal i=p,q,y+z;
+   lcm(i,p);
+   lcm(2,3,6);
+   lcm(2..6);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc content(def f)
+"USAGE:   content(f); f polynomial/vector
+RETURN:  number, the content (greatest common factor of coefficients)
+         of the polynomial/vector f
+SEE ALSO: cleardenom
+EXAMPLE: example content; shows an example
+"
+{
+  if (f==0) { return(number(1)); }
+  return(leadcoef(f)/leadcoef(cleardenom(f)));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r=0,(x,y,z),(c,lp);
+   content(3x2+18xy-27xyz);
+   vector v=[3x2+18xy-27xyz,15x2+12y4,3];
+   content(v);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+// The idea of the procedures mod2id, id2mod and subrInterred is, to
+// perform standard basis computation or interreduction of a submodule
+// of a free module with generators gen(1),...,gen(n) over a ring R
+// in a ring R[t1,...,tn]/<ti*tj> with gen(i) maped to ti
+////////////////////////////////////////////////////////////////////////
+
+proc mod2id(matrix M,intvec vpos)
+"USAGE:   mod2id(M,vpos); M matrix, vpos intvec
+ASSUME:  vpos is an integer vector such that gen(i) corresponds
+         to var(vpos[i]).
+         The basering contains variables var(vpos[i]) which do not occur
+         in M.
+RETURN:  ideal I in which each gen(i) from the module is replaced by
+         var(vpos[i]) and all monomials var(vpos[i])*var(vpos[j]) have
+         been added to the generating set of I.
+NOTE:    This procedure should be used in the following situation:
+         one wants to pass to a ring with new variables, say e(1),..,e(s),
+         which correspond to the components gen(1),..,gen(s) of the
+         module M such that e(i)*e(j)=0 for all i,j.
+         The new ring should already exist and be the current ring
+EXAMPLE: example mod2id; shows an example"
+{
+  int p = printlevel-voice+3;  // p=printlevel+1 (default: p=1)
+//----------------------------------------------------------------------
+// define the ideal generated by the var(vpos[i]) and set up the matrix
+// for the multiplication
+//----------------------------------------------------------------------
+  ideal vars=var(vpos[1]);
+  for(int i=2;i<=size(vpos);i++)
+  {
+    vars=vars,var(vpos[i]);
+  }
+  matrix varm[1][size(vpos)]=vars;
+  if (size(vpos) > nrows(M))
+  {
+    matrix Mt[size(vpos)][ncols(M)];
+    Mt[1..nrows(M),1..ncols(M)]=M;
+    kill M;
+    matrix M=Mt;
+  }
+//----------------------------------------------------------------------
+// define the desired ideal
+//----------------------------------------------------------------------
+  ideal ret=vars^2,varm*M;
+  return(ret);
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring r=0,(e(1),e(2),x,y,z),(dp(2),ds(3));
+  module mo=x*gen(1)+y*gen(2);
+  intvec iv=2,1;
+  mod2id(mo,iv);
+}
+////////////////////////////////////////////////////////////////////////
+
+proc id2mod(ideal i,intvec vpos)
+"USAGE:   id2mod(I,vpos); I ideal, vpos intvec
+RETURN:  module corresponding to the ideal by replacing var(vpos[i]) by
+         gen(i) and omitting all generators var(vpos[i])*var(vpos[j])
+NOTE:    * This procedure only makes sense if the ideal contains
+           all var(vpos[i])*var(vpos[j]) as monomial generators and
+           all other generators of I are linear combinations of the
+           var(vpos[i]) over the ring in the other variables.
+         * This is the inverse procedure to mod2id and should be applied
+           only to ideals created by mod2id using the same intvec vpos
+           (possibly after a standard basis computation)
+EXAMPLE: example id2mod; shows an example"
+{
+  int p = printlevel-voice+3;  // p=printlevel+1 (default: p=1)
+//---------------------------------------------------------------------
+// Initialization
+//---------------------------------------------------------------------
+  int n=size(i);
+  int v=size(vpos);
+  matrix tempmat;
+  matrix mm[v][n];
+//---------------------------------------------------------------------
+// Conversion
+//---------------------------------------------------------------------
+  for(int j=1;j<=v;j++)
+  {
+    tempmat=coeffs(i,var(vpos[j]));
+    mm[j,1..n]=tempmat[2,1..n];
+  }
+  for(j=1;j<=v;j++)
+  {
+    mm=subst(mm,var(vpos[j]),0);
+  }
+  module ret=simplify(mm,10);
+  return(ret);
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring r=0,(e(1),e(2),x,y,z),(dp(2),ds(3));
+  ideal i=e(2)^2,e(1)*e(2),e(1)^2,e(1)*y+e(2)*x;
+  intvec iv=2,1;
+  id2mod(i,iv);
+}
+///////////////////////////////////////////////////////////////////////
+
+proc subrInterred(ideal mon, ideal sm, intvec iv)
+"USAGE:   subrInterred(mon,sm,iv);
+         sm:   ideal in a ring r with n + s variables,
+               e.g. x_1,..,x_n and t_1,..,t_s
+         mon:  ideal with monomial generators (not divisible by
+               any of the t_i) such that sm is contained in the module
+               k[t_1,..,t_s]*mon[1]+..+k[t_1,..,t_s]*mon[size(mon)]
+         iv:   intvec listing the variables which are supposed to be used
+               as x_i
+RETURN:  list l:
+          l[1]=the monomials from mon in the order used
+          l[2]=their coefficients after interreduction
+          l[3]=l[1]*l[2]
+PURPOSE:  Do interred only w.r.t. a subset of variables.
+         The procedure returns an interreduced system of generators of
+         sm considered as a k[t_1,..,t_s]-submodule of the free module
+         k[t_1,..,t_s]*mon[1]+..+k[t_1,..,t_s]*mon[size(mon)]).
+EXAMPLE: example subrInterred; shows an example
+"
+{
+  int p = printlevel-voice+3;  // p=printlevel+1 (default: p=1)
+//-----------------------------------------------------------------------
+// check that mon is really generated by monomials
+// and sort its generators with respect to the monomial ordering
+//-----------------------------------------------------------------------
+  int err;
+  for(int i=1;i<=ncols(mon);i++)
+  {
+    if ( size(mon[i]) > 1 )
+    {
+      err=1;
+    }
+  }
+  if (err==1)
+  {
+    ERROR("mon has to be generated by monomials");
+  }
+  intvec sv=sortvec(mon);
+  ideal mons;
+  for(i=1;i<=size(sv);i++)
+  {
+    mons[i]=mon[sv[i]];
+  }
+  ideal itemp=maxideal(1);
+  for(i=1;i<=size(iv);i++)
+  {
+    itemp=subst(itemp,var(iv[i]),0);
+  }
+  itemp=simplify(itemp,10);
+  def r=basering;
+  string tempstr="ring rtemp=" + charstr(basering) + ",(" + string(itemp)
+                               + "),(C,dp);";
+//-----------------------------------------------------------------------
+// express m in terms of the generators of mon and check whether m
+// can be considered as a submodule of k[t_1,..,t_n]*mon
+//-----------------------------------------------------------------------
+  module motemp;
+  motemp[ncols(sm)]=0;
+  poly ptemp;
+  int j;
+  for(i=1;i<=ncols(mons);i++)
+  {
+    for(j=1;j<=ncols(sm);j++)
+    {
+      ptemp=sm[j]/mons[i];
+      motemp[j]=motemp[j]+ptemp*gen(i);
+    }
+  }
+  for(i=1;i<=size(iv);i++)
+  {
+    motemp=subst(motemp,var(iv[i]),0);
+  }
+  matrix monmat[1][ncols(mons)]=mons;
+  ideal dummy=monmat*motemp;
+  for(i=1;i<=size(sm);i++)
+  {
+    if(sm[i]-dummy[i]!=0)
+    {
+      ERROR("the second argument is not a submodule of the assumed structure");
+    }
+  }
+//----------------------------------------------------------------------
+// do the interreduction and convert back
+//----------------------------------------------------------------------
+  execute(tempstr);
+  def motemp=imap(r,motemp);
+  intvec save=option(get);
+  option(redSB);
+  motemp=interred(motemp);
+  option(set,save);
+  setring r;
+  kill motemp;
+  def motemp=imap(rtemp,motemp);
+  //list ret=monmat,motemp,monmat*motemp;
+  module motemp2=motemp;
+  for(i=1;i<=ncols(motemp2);i++)
+  {
+    motemp2[i]=cleardenom(motemp2[i]);
+  }
+  module motemp3=monmat*motemp;
+  for(i=1;i<=ncols(motemp3);i++)
+  {
+    motemp3[i]=cleardenom(motemp3[i]);
+  }
+  list ret=monmat,motemp2,matrix(motemp3);
+  return(ret);
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring r=0,(x,y,z),dp;
+  ideal i=x^2+x*y^2,x*y+x^2*y,z;
+  ideal j=x^2+x*y^2,x*y,z;
+  ideal mon=x^2,z,x*y;
+  intvec iv=1,3;
+  subrInterred(mon,i,iv);
+  subrInterred(mon,j,iv);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// moved here from nctools.lib
+// This procedure calculates the Newton diagram of the polynomial f
+// The output is a intmat M, each row of M is the exp of a monomial in f
+////////////////////////////////////////////////////////////////////////
+proc newtonDiag(poly f)
+"USAGE:  newtonDiag(f); f a poly
+RETURN:  intmat
+PURPOSE: compute the Newton diagram of f
+NOTE:    each row is the exponent of a monomial of f
+EXAMPLE: example newtonDiag; shows examples
+"{
+  int n = nvars(basering);
+  intvec N=0;
+  if ( f != 0 )
+  {
+    while ( f != 0 )
+    {
+      N = N, leadexp(f);
+      f = f-lead(f);
+    }
+  }
+  else
+  {
+    N=N, leadexp(f);
+  }
+  N = N[2..size(N)]; // Deletes the zero added in the definition of T
+  intmat M=intmat(N,(size(N) div n),n); // Conversion from vector to matrix
+  return (M);
+}
+example
+{
+  "EXAMPLE:";echo=2;
+  ring r = 0,(x,y,z),lp;
+  poly f = x2y+3xz-5y+3;
+  newtonDiag(f);
+}
+
+////////////////////////////////////////////////////////////////////////
diff --git a/Singular/LIB/polybori.lib b/Singular/LIB/polybori.lib
new file mode 100644
index 0000000..2bc400f
--- /dev/null
+++ b/Singular/LIB/polybori.lib
@@ -0,0 +1,1432 @@
+////////////////////////////////////////////////////////////////
+version="version polybori.lib 4.0.0.0 Jun_2013 "; // $Id: 557f82d8d583de1d4d4c32149e58ce86f4cccaee $
+category="Miscellaneous";
+
+// summary description of the library
+
+info="
+LIBRARY:   polybori.lib A Singular Library Interface for PolyBoRi
+AUTHORS:   Maximilian Kammermeier: Max0791 at gmx.de
+           Susanne Scherer: sscherer90 at yahoo.de
+
+SEE ALSO:  Libraries, pyobject, User defined types
+
+
+@*
+
+OVERVIEW:  A library for using @code{PolyBoRi} in the SINGULAR interface, with
+procedures that convert structures (polynomials, rings, ideals) in both
+directions. Therefore, it is possible to compute boolean groebner basis
+via @ref{boolean_std}. Polynomials can be converted to zero-supressed decision
+diagrams (zdd) and vice versa.
+
+For usability it defines the @code{PolyBoRi} types @code{bideal}, @code{bpoly},
+and @code{bring} which are equivalent to Singular's @code{ideal}, @code{poly},
+and @code{ring}, as well as @code{bset} which corresponds to the type @code{zdd}
+introduced here. In addition @code{bvar(i)} constructs the Boolean variable corresponding
+to @code{var(i)} from current @code{ring};
+
+For convenience, the corresponding types can be converted explictely or implicitely
+while assigning.
+Also several SINGULAR operators were overloaded: @code{bring} comes with @code{nvars},
+ at code{bpoly} implements @code{lead}, @code{leadmonom} and @code{leadcoef}.
+Objects of this type  may be added and multiplied, too.
+Finally, @code{bideal} yields @code{std} and @code{size} as well as addition and element access.
+
+
+Hence, by using these types @code{PolyBoRi} functionality
+can be carried out seamlessly in SINGULAR:
+
+ at code{> LIB \"polybori.lib\";} @*
+ at code{> ring r0=2,x(1..4),lp;} @*
+ at code{> def x=bvar; // enforce Boolean variables} @*
+
+ at code{> bpoly f1=x(1)+x(4);} @*
+ at code{> bpoly f2=x(1)+x(3)*x(1);} @*
+ at code{> bideal bI=list(f1,f2);} @*
+
+ at code{> std(bI);} @*
+ at code{_[1] = x(1) + x(4)} @*
+ at code{_[2] = x(3)*x(4) + x(4)} @*
+
+
+NOTE: For using this library SINGULAR's @code{python} interface must be available
+ on your system.
+ Please @code{./configure --with-python} when building SINGULAR for this purpose.
+
+ There are prebuilt binary packages for @code{PolyBoRi} available
+ from @code{http://polybori.sf.net/}.
+
+ For building your own @code{PolyBoRi} please ensure that you have @code{scons} and a
+ development version of the boost libaries installed on you system.
+ Then you may execute the following commands in a @code{bash}-style shell
+ to build @code{PolyBoRi} available to @code{python}:
+
+ at code{PBDIR=/path/to/custom/polybori} @*
+ at code{wget http://downloads.sf.net/project/polybori/polybori/\\}@*
+ at code{0.8.2/polybori-0.8.2.tar.gz} @*
+ at code{tar -xvzf polybori-0.8.2.tar.gz} @*
+ at code{cd polybori-0.8.2} @*
+ at code{scons install PREFIX=$PBDIR PYINSTALLPREFIX=$PBDIR/python} @*
+ at code{export PYTHONPATH=$PBDIR/python:$PYTHONPATH} @*
+
+
+REFERENCES:
+See @code{http://polybori.sf.net} for details about @code{PolyBoRi}.
+
+PROCEDURES:
+  boolean_std(bideal);                            Singular ideal of boolean groebner basis of I
+
+  boolean_poly_ring(ring);                       convert ring
+  boolean_constant(int[, bring]);                convert constant
+  boolean_poly(poly[, int, bring])               convert polynomial
+  direct_boolean_poly(poly[, bring]);            convert polynomial direct
+  recursive_boolean_poly(poly[, bring]);         convert polynomial recursively
+  boolean_ideal(ideal[, bring]);                 convert ideal
+  boolean_set(zdd[, bring]);                     convert zdd
+
+
+  from_boolean_constant(bpoly);                  convert boolean constant
+  from_boolean_poly(bpoly[, int]);               convert boolean polynomial
+  direct_from_boolean_poly(bpoly);               convert boolean polynomial direct
+  recursive_from_boolean_poly(bpoly);            convert boolean polynomial recursively
+  from_boolean_ideal(bpoly);                     convert to ideal
+  from_boolean_set(bset);                        convert to zdd
+
+
+  bvar(i);                                       return i-th Boolean variable
+  poly2zdd(poly);                                return zdd of a given polynomial
+  zdd2poly(zdd);                                 return polynomial representation of a given zdd
+  disp_zdd(zdd);                                 return string with a visualization of a given
+
+KEYWORDS: library, polybori.lib; polybori; polybori.lib; library; pyobject; newstruct; zdd
+
+";
+
+///////////////////////////////////////////////////////////////////////
+// initialization of datatypes and constant structures
+
+static proc mod_init()
+"USAGE: mod_init()
+RETURN: none
+NOTE: load PolyBoRi and introduce the structures zdd and bpoly
+SEE ALSO: boolean_ideal, boolean_std
+KEYWORDS: PolyBoRi, Boolean Groebner Basis
+"
+{
+  if (typeof(Pyobject)!="package")
+  {
+    LIB("pyobject.so");
+  }
+  if (typeof(zdd_one)=="?unknown type?")
+  {
+    python_import("polybori");
+
+ // install new types
+
+    newstruct("zdd","int idx,def thenBranch,def elseBranch");
+    newstruct("bpoly","pyobject boolpoly");
+    newstruct("bideal","pyobject pylist");
+    newstruct("bring", "pyobject pyring");
+    newstruct("bset", "pyobject pyset");
+
+ // install type operations
+
+    system("install", "zdd",      "==",      zdd_check,2);
+    system("install", "bpoly",    "==",      bpoly_check,2);
+    system("install", "bpoly",    "*",       bpoly_mult,2);
+    system("install", "bpoly",    "+",       bpoly_add,2);
+    system("install", "zdd",      "print",   print_zdd, 1);
+    system("install", "bpoly",    "print",   print_bpoly,1);
+    system("install", "bideal",   "print",   print_bideal,1);
+    system("install", "bideal",   "size",    size_bideal,1);
+    system("install", "bpoly",    "lead",     lead_bpoly, 1);
+    system("install", "bpoly",    "leadmonom",lead_monom_bpoly, 1);
+    system("install", "bpoly",    "leadcoef", lead_coef_bpoly, 1);
+    system("install", "bideal",   "[",        op_getitem, 2);
+    system("install", "bideal",   "+",        bideal_add, 2);
+    system("install", "bideal",   "std",      boolean_std, 4);
+
+ // install type conversions
+
+//    implemented typecasts (both directions)
+//    SINGULAR             BOOLEAN OBJECTS
+//    ring                 bring
+//    poly                 bpoly
+//    zdd                  bset
+//    ideal                bideal
+//
+// furthermore, it is possible to switch between poly <-> zdd and bpoly <-> bset
+
+    system("install", "bring",    "=",        ring2bring, 1);
+    system("install", "bring",    "nvars",    nvars_bring, 1);
+
+    system("install", "pyobject", "poly",     from_boolean_poly, 1);
+    system("install", "pyobject", "size",     size_pyobject, 1);
+
+    system("install", "pyobject", "bideal",   pyobject2bideal,1);
+    system("install", "bideal",   "pyobject", bideal2pyobject,1);
+
+    system("install", "bideal",   "ideal",    bideal2ideal, 4);
+    system("install", "bideal",   "=",        type2bideal, 1);
+
+
+
+    system("install", "zdd",      "poly",     zdd2poly, 1);
+    system("install", "zdd",      "=",        poly2zdd, 1);
+
+    system("install", "zdd",      "pyobject", boolean_set, 1);
+    system("install", "pyobject", "zdd",      from_boolean_set, 1);
+
+    system("install", "bset",     "zdd",      bset2zdd, 1);
+    system("install", "zdd",      "bset",     zdd2bset, 1);
+
+    system("install", "bpoly",    "bset",     bpoly2bset, 1);
+    system("install", "bset",     "bpoly",    bset2bpoly, 1);
+
+    system("install", "pyobject", "bpoly",    pyobject2bpoly,1);
+    system("install", "bpoly",    "pyobject", bpoly2pyobject,1);
+
+    system("install", "bpoly",     "poly",    bpoly2poly,1);
+    system("install", "bpoly",     "bideal",  bpoly2bideal,1);
+    system("install", "bpoly",     "=",       poly2bpoly,1);
+
+
+
+ // initialize constant zdds
+
+    zdd zdd_one;
+    zdd_one.idx=0;
+    zdd_one.thenBranch=int(1);
+    zdd_one.elseBranch=int(0);
+    zdd zdd_zero;
+    zdd_zero.idx=0;
+    zdd_zero.thenBranch=int(0);
+    zdd_zero.elseBranch=int(0);
+    export(zdd_one);
+    export(zdd_zero);
+
+    python_run("def if_then_else_idx(idx,b,c): return b.set().change(idx).union(c)");
+    python_run("_SINGULAR_RINGS = dict()");
+    python_run("_SINGULAR_RINGS_ACCESSED = 0");
+    python_run("def _SINGULAR_DECACHE_RING(arg): val = arg(); return 0 if val is None else val");
+  }
+}
+
+///////////////////////////////////////////////////////////////////////
+// computes the leading term of a bpoly
+
+proc lead_bpoly(bpoly pp)
+{
+  pyobject zero=0;
+  bpoly zero2;
+  zero2.boolpoly=zero;
+  if (pp==zero2)
+  {
+    return(0);
+  }
+  else
+  {
+    pyobject ppb=pp.boolpoly."lead"();
+    return(ppb);
+  }
+}
+
+///////////////////////////////////////////////////////////////////////
+// computes the leading monomial of a bpoly
+
+proc lead_monom_bpoly(bpoly pp)
+{
+  if (pp.boolpoly == 0) {  return(0); }
+
+  pyobject ppb=pp.boolpoly."lead"();
+  return(ppb);
+}
+
+///////////////////////////////////////////////////////////////////////
+// computes the leading coefficient of a bpoly
+
+proc lead_coef_bpoly(bpoly pp)
+{
+  if (int(pp.is_zero())) {  return(0); }
+  return(1);
+}
+
+///////////////////////////////////////////////////////////////////////
+// converts a Singular ring into a Boolean ring
+
+proc ring2bring(def r)
+{
+  bring rb;
+  rb.pyring = boolean_poly_ring(r);
+  return(rb);
+}
+///////////////////////////////////////////////////////////////////////
+// Generate an ideal from one constructor
+proc bpoly2bideal(bpoly bp)
+{
+  pyobject obj = list(bp);
+  bideal bI = obj;
+  return (bI);
+}
+
+///////////////////////////////////////////////////////////////////////
+// get number of variables of a Boolean ring
+
+proc nvars_bring(bring rb)
+{
+  return (int(rb.pyring.n_variables()));
+}
+
+///////////////////////////////////////////////////////////////////////
+// get variable of Boolean ring corresponding to current basering
+
+proc bvar(int i)
+"USAGE: bvar(i); int i
+RETURN: i-th variable of Boolean ring corresponding to current basering
+SEE ALSO: boolean_poly_ring, var
+KEYWORDS: PolyBoRi, Boolean Groebner Basis
+EXAMPLE: example bvar; shows an example"
+{
+  bpoly re = var(i);
+  return (re);
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring r = 2,(x,y,z),Dp;
+  bvar(1); // -> x
+}
+
+///////////////////////////////////////////////////////////////////////
+// Internal functions for caching converted ring
+///////////////////////////////////////////////////////////////////////
+
+
+// Mark cache as accessed and clear garbage every 100 accesses
+static proc bring_mark_cache(list #)
+{
+  if (int(python_eval("_SINGULAR_RINGS_ACCESSED >= 100"))) {
+    python_run("_SINGULAR_RINGS_ACCESSED = 0");
+    def erased = python_eval("[_k for (_k,_v) in _SINGULAR_RINGS.items() if _v() is None]");
+    erased = python_eval("(lambda _keys: [_SINGULAR_RINGS.pop(_k) for _k in _keys])")(erased);
+  }
+  python_run("_SINGULAR_RINGS_ACCESSED += 1");
+}
+
+// look up whether we cached this conversion before
+static proc bring_from_cache(def r)
+{
+  bring_mark_cache();
+  def result1 = python_eval("_SINGULAR_RINGS.get('" + string(r) + "', (lambda: None))");
+  def result = python_eval("_SINGULAR_DECACHE_RING")(result1);
+  return (result);
+}
+
+// insert computed result into cache
+static proc bring_to_cache(def r, pyobject newring)
+{
+  def value = WeakRingRef(newring);
+  python_eval("_SINGULAR_RINGS")."__setitem__"(string(r), value);
+}
+
+///////////////////////////////////////////////////////////////////////
+// converts a Singular ring into a python ring
+
+proc boolean_poly_ring(def r)
+{
+  def cached = bring_from_cache(r);
+  if (int(cached != int(0))) { return (cached); }
+
+  def rl = ringlist(r);
+  list blocks;
+  string ordering;
+  pyobject orders = python_eval("dict(lp=OrderCode.lp)");
+  if (size(rl[3]) >2)
+  {
+    orders.update(python_eval("dict(Dp=OrderCode.block_dlex)"));
+  }
+  else
+  {
+    orders.update(python_eval("dict(Dp=OrderCode.dlex)"));
+  }
+
+  int i;
+  int counter=0;
+  for (i=1; i<=size(ringlist(r)[3]); i++)
+  {
+    if (rl[3][i][1]<>"C")
+    {
+      ordering=rl[3][i][1];
+      if (counter) { blocks = blocks + list(counter) };
+      counter = counter + size(rl[3][i][2]);
+    }
+  }
+  if(int(orders.has_key(ordering)==0))
+  {
+     "// Warning: Unsupported ordering, using 'lp`!";
+  }
+
+  def result = Ring(nvars(r), orders.get(ordering, 0), rl[2], blocks);
+  bring_to_cache(r, result);
+  return (result);
+}
+
+///////////////////////////////////////////////////////////////////////
+// returns ith entry of a bideal
+
+proc op_getitem(bideal arg, def idx)
+{
+  if (typeof(idx) == "int") { return (arg.pylist[idx-1]); }
+
+  bideal re = (python_eval("lambda ll, idx: [ll[i] for i in idx]")(arg.pylist, idx-1));
+  return (re);
+}
+
+///////////////////////////////////////////////////////////////////////
+// concatenate generators of bideals
+
+proc bideal_add(bideal arg1, bideal arg2)
+{
+  pyobject tmp = python_eval("lambda x, y: list(sorted(set(x).union(set(y))))");
+  bideal re = tmp(arg1.pylist,arg2.pylist);
+  return (re);
+}
+
+///////////////////////////////////////////////////////////////////////
+// checks the equality of two bpolys
+
+proc bpoly_check(bpoly pb1,bpoly pb2)
+{
+  return(pb1.boolpoly==pb2.boolpoly);
+}
+
+///////////////////////////////////////////////////////////////////////
+// computes the multiplication of two bpolys
+
+proc bpoly_mult(bpoly pb1,bpoly pb2)
+{
+  bpoly bpol;
+  bpol.boolpoly=pb1.boolpoly*pb2.boolpoly;
+  return(bpol);
+}
+
+///////////////////////////////////////////////////////////////////////
+// computes the addition of two bpolys
+
+proc bpoly_add(bpoly pb1, bpoly pb2)
+{
+  bpoly bpol;
+  bpol.boolpoly=pb1.boolpoly+pb2.boolpoly;
+  return(bpol);
+}
+
+///////////////////////////////////////////////////////////////////////
+// convert bpoly to pyobject
+
+proc bpoly2pyobject(bpoly pb)
+{
+  return(pb.boolpoly);
+}
+
+///////////////////////////////////////////////////////////////////////
+// convert bideal to pyobject
+
+proc bideal2pyobject(bideal Ib)
+{
+  return(Ib.pylist);
+}
+
+///////////////////////////////////////////////////////////////////////
+// convert poly to bpoly
+
+proc poly2bpoly(poly p)
+{
+  bpoly bpol;
+  bpol.boolpoly=boolean_poly(p);
+  return(bpol);
+}
+
+///////////////////////////////////////////////////////////////////////
+// convert zdd to bset
+
+proc zdd2bset(zdd ss)
+{
+  bset bs;
+  bs.pyset=boolean_set(ss);
+  return(bs);
+}
+
+///////////////////////////////////////////////////////////////////////
+// convert bpoly to bset
+
+proc bpoly2bset(bpoly ss)
+{
+  bset bs;
+  bs.pyset=ss.boolpoly.set();
+  return(bs);
+}
+
+///////////////////////////////////////////////////////////////////////
+// convert bset to zdd
+
+proc bset2zdd(bset ss)
+{
+  zdd bs;
+  bs=from_boolean_set(ss.pyset);
+  return(bs);
+}
+
+///////////////////////////////////////////////////////////////////////
+// convert bset to bpoly
+
+proc bset2bpoly(bset ss)
+{
+  bpoly pb;
+  pb.boolpoly=python_eval("Polynomial")(ss.pyset);
+  return(pb);
+}
+
+///////////////////////////////////////////////////////////////////////
+// convert type (ideal or list) to bideal
+
+proc type2bideal(def I)
+{
+  if (typeof(I) == "ideal") { return (boolean_ideal(I)); }
+
+  bideal bid;
+  pyobject pylist;
+
+  if (typeof(I) == "list")
+  {
+    pylist = python_eval("list()");
+    int i; int nlen=size(I); bpoly elt;
+    for (i=1; i <= nlen; i++) {
+      elt = I[i];
+      pylist.append(pyobject(elt));
+    }
+  }
+  else { pylist = I; }
+  bid.pylist = pylist;
+  return (bid);
+}
+
+///////////////////////////////////////////////////////////////////////
+// convert bpoly to poly
+
+proc bpoly2poly(bpoly pb)
+{
+  poly h=poly(pb.boolpoly);
+  return(h);
+}
+
+
+///////////////////////////////////////////////////////////////////////
+// convert bideal to ideal
+
+proc bideal2ideal(bideal Ib)
+{
+  ideal I;
+  I=from_boolean_ideal(Ib);
+  return(I);
+}
+
+///////////////////////////////////////////////////////////////////////
+// convert pyobject to bpoly
+
+proc pyobject2bpoly(pyobject pb)
+{
+  bpoly bpol;
+  bpol.boolpoly=pb;
+  return(bpol);
+}
+
+///////////////////////////////////////////////////////////////////////
+// convert pyobject to bideal
+
+proc pyobject2bideal(pyobject Ib)
+{
+  bideal bid;
+  bid.pylist=Ib;
+  return(bid);
+}
+
+///////////////////////////////////////////////////////////////////////
+// print bpoly
+
+proc print_bpoly(bpoly pb)
+{
+  pb.boolpoly;
+}
+
+///////////////////////////////////////////////////////////////////////
+// print bideal
+
+proc print_bideal(bideal Ib)
+{
+  int nlen = size(Ib);
+  for (int i = 1; i <= nlen; i++)
+  {
+    "_[" + string(i)+"] = " + string(Ib[i]);
+  }
+}
+
+///////////////////////////////////////////////////////////////////////
+// get size of pyobject
+
+proc size_pyobject(pyobject obj)
+{
+  return (int(python_eval("len")(obj)));
+}
+
+///////////////////////////////////////////////////////////////////////
+// get size of bideal
+
+proc size_bideal(bideal Ib)
+{
+  return (size(Ib.pylist));
+}
+
+
+///////////////////////////////////////////////////////////////////////
+// print zdd
+
+proc print_zdd(zdd ss)
+{
+  "zdd: ";
+  disp_zdd(ss);
+}
+
+///////////////////////////////////////////////////////////////////////
+// check equality
+
+proc zdd_check(zdd zdd1,zdd zdd2)
+"USAGE: zdd_check(zdd1,zdd2); zdd zdd1, zdd zdd2
+RETURN: 0 or 1 "
+{
+  if (zdd1.idx != zdd2.idx) { return (int(0)); }
+
+  if (zdd1.idx == 0) {  return (int(zdd1.thenBranch == zdd2.thenBranch)); }
+
+  return (zdd_check(zdd1.thenBranch,zdd2.thenBranch)*zdd_check(zdd1.elseBranch,zdd2.elseBranch));
+}
+
+///////////////////////////////////////////////////////////////////////
+
+proc boolean_set(zdd ss,list #)
+"USAGE: boolean_set(ss[, rb]); ss zdd, rb boolean ring
+RETURN: default: boolean set ss in the representation of a Polybori boolean set
+in the ring rb==boolean_poly_ring(basering); optional input: boolean ring rb
+SEE ALSO: boolean_ideal, boolean_std
+KEYWORDS: PolyBoRi, Boolean Groebner Basis
+EXAMPLE: example boolean_set; shows an example"
+{
+  pyobject rb;
+  rb=check_additional_ring(#);
+  pyobject newthen,newelse,unbek,outp;
+  if (ss.idx==0)
+  {
+    if (zdd_check(ss,zdd_one)==1) { return (boolean_constant(1,rb)); }
+    return (boolean_constant(0,rb));
+  }
+  newthen=(boolean_set(ss.thenBranch,rb));
+  newelse=(boolean_set(ss.elseBranch,rb));
+  outp=if_then_else_idx(ss.idx-1,newthen,newelse);
+  return (outp);
+}
+
+example
+{ "EXAMPLE:"; echo=2;
+  ring rs=0,(x,y,z),Dp;
+  poly ps=(x+1)*(y+1)*(z+1);
+  zdd fz=ps;
+  boolean_set(fz);
+
+  poly g=x*y*z+1;
+  zdd gz=g;
+  boolean_set(gz);
+
+  ring R=0,(x(1..4)),Dp;
+  def Rb=boolean_poly_ring(R);
+  poly h=(x(1)+1)*(x(2)+1)*(x(3)+1)*(x(4)+1);
+  zdd hz=h;
+  boolean_set(hz);
+}
+
+///////////////////////////////////////////////////////////////////////
+
+proc from_boolean_set(def s)
+"USAGE: from_boolean_set(sb); sb boolean set
+RETURN: Boolean set sb in the representation of a zdd
+SEE ALSO: boolean_ideal, boolean_std
+KEYWORDS: PolyBoRi, Boolean Groebner Basis
+EXAMPLE: example from_boolean_set; shows an example"
+{
+  bpoly bp = s;
+  pyobject sb = bp;
+  def rb=boolean_poly_ring(basering);
+  zdd result;
+  def nav=sb.navigation();
+  int ind=int(nav.value());
+  def navout_then=nav.then_branch();
+  def navout_else=nav.else_branch();
+  def pb=Polynomial(sb);
+
+  if (int(nav.constant()))
+  {
+    if (pb==1) { return(zdd_one); }
+    return(zdd_zero);
+  }
+
+  result.idx=ind+1;
+  pyobject one=1;
+  def substpoly=one*rb.variable(ind);
+
+  if (int(navout_then.constant()))
+  {
+      result.thenBranch=zdd_one;
+  }
+  else
+  {
+    result.thenBranch=from_boolean_set(BooleSet(navout_then,rb));
+  }
+  if (int(navout_else.constant()))
+  {
+    if (subst(from_boolean_poly(pb),from_boolean_poly(substpoly),0)==1)
+    {
+      result.elseBranch=zdd_one;
+    }
+    else
+    {
+      result.elseBranch=zdd_zero;
+    }
+  }
+  else
+  {
+    result.elseBranch=from_boolean_set(BooleSet(navout_else,rb));
+  }
+  return(result);
+}
+
+example
+{ "EXAMPLE:"; echo=2;
+  ring r=0,(x,y,z),Dp;
+  poly f=(x+1)*(y+1)*(z+1);
+  bpoly fb=f;
+  bset fs=fb;
+  from_boolean_set(fs);
+
+  poly g=x*y*z+1;
+  bpoly gb=g;
+  bset gs=gb;
+  from_boolean_set(gs);
+
+  ring R=0,(x(1..4)),Dp;
+  poly h=(x(1)+1)*(x(2)+1)*(x(3)+1)*(x(4)+1);
+  pyobject hb=boolean_poly(h);
+  def hs=hb.set();
+  from_boolean_set(hs);
+}
+
+//////////////////////////////////////////////////////////////////////
+
+proc direct_from_boolean_poly(def p)
+"USAGE:   from_boolean_poly(pb); pb boolean polynomial
+RETURN:   polynomial in Singular
+SEE ALSO: from_boolean_ideal, boolean_ideal, boolean_poly, boolean_poly_ring,
+boolean_std
+KEYWORDS: PolyBoRi, Boolean Groebner Basis
+EXAMPLE:  example from_boolean_poly; shows an example"
+{
+  pyobject pb = p;
+  poly result = 0;
+  def terms = python_eval("list")(pb.terms());
+  int nlen = size(terms);
+  for (int i = 0; i < nlen; i++)
+  {
+    result=from_boolean_poly_update(result,terms[i]);
+  }
+  return (result);
+}
+
+example
+{ "EXAMPLE:"; echo=2;
+  ring r=0,(x,y,z),Dp;
+  pyobject rb=boolean_poly_ring(r);
+  poly f=x^2+2*y^3+3*z^3;
+  bpoly pp=f;
+  direct_from_boolean_poly(pp);
+
+  poly g=0;
+  bpoly pp=g;
+  direct_from_boolean_poly(pp);
+}
+
+///////////////////////////////////////////////////////////////////////
+// one iteration in direct_from_boolean_poly
+
+static proc from_boolean_poly_update(poly ps, pyobject pb)
+"USAGE: from_boolean_poly_update(ps,pb); ps polynomial, pb boolean polynomial,
+RETURN: update of the Singular polynomial in from_boolean_poly in one iteration
+SEE ALSO: from_boolean_poly
+{
+  pyobject current = pb."variables"();
+  pyobject vars = python_eval("list")(current);
+  int j, index;
+  poly term = 1;
+  pyobject currentvar;
+  int tlen = size(vars);
+  for (j = 0; j < tlen; j++)
+  {
+    currentvar = vars[j];
+    index = int(currentvar.index());
+    term = term * var(index+1);
+  }
+  return(ps + term);
+}
+
+///////////////////////////////////////////////////////////////////////
+// return 1, iff int is 1 modulo 2 and 0 else
+
+static proc coeff_check(int const)
+"USAGE: coeff_check(const); const int
+RETURN: 1 iff the coefficient equals 1 modulo 2 and 0 else
+NOTE: helps to handle leading coefficients of rings in arbitrary characteristic
+SEE ALSO: recursive_boolean_poly, boolean_poly
+KEYWORDS: PolyBoRi, Boolean Groebner Basis
+EXAMPLE: example coeff_check; shows an example"
+{
+  if (char(basering)==2) { return (const); }
+
+  return ((const%2)*(const%2));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring R1=5,x(1..4),lp;
+  poly f=3*x(1)+x(2)^2;
+  coeff_check(int(leadcoef(f)));
+}
+
+///////////////////////////////////////////////////////////////////////
+
+static proc check_additional_ring(list #)
+"USAGE: check_additional_ring(#);
+NOTE: Help function to check whether an additional ring exists and if it is a
+bring or a ring in python."
+{
+  pyobject rb;
+  bring rbhelp;
+  if (size(#)==0)
+  {
+    rb=boolean_poly_ring(basering);
+  }
+  else
+  {
+    if (typeof(#[1])=="bring")
+    {
+      rbhelp=#[1];
+      rb=rbhelp.pyring;
+    }
+    else
+    {
+      rb=#[1];
+    }
+  }
+  return(rb);
+}
+///////////////////////////////////////////////////////////////////////
+
+proc boolean_constant(int const, list #)
+"USAGE: boolean_constant(const[, rb]); const constant and rb boolean ring
+RETURN: default: constant const in the representation of the boolean ring
+rb==boolean_poly_ring(basering); optional input: rb=boolean ring rb
+SEE ALSO: boolean_ideal, boolean_std
+KEYWORDS: PolyBoRi, Boolean Groebner Basis
+EXAMPLE: example boolean_constant; shows an example"
+{
+  pyobject rb = check_additional_ring(#);
+  if (coeff_check(const)==0) { return (rb.zero()); }
+
+  return (rb.one());
+}
+
+example
+{ "EXAMPLE:"; echo = 2;
+  ring r=7,(x,y),Dp;
+  pyobject rb=boolean_poly_ring(r);
+  boolean_constant(int(3));
+  typeof(boolean_constant(int(3)));
+  boolean_constant(int(0));
+  typeof(boolean_constant(int(0)));
+}
+
+///////////////////////////////////////////////////////////////////////
+
+proc boolean_poly(poly ps, list #)
+"USAGE: boolean_poly(ps[, dir, rb]); ps polynomial, dir integer zero or one, rb
+boolean ring
+RETURN: default: polynomial ps in the representation of the boolean ring
+rb==boolean_poly_ring(basering); optional input: boolean ring rb
+NOTE: via the optional input dir, one can choose the computation method (either
+direct[dir==0] or recursive[dir==1]). default: recursive
+SEE ALSO: boolean_ideal, boolean_std
+KEYWORDS: PolyBoRi, Boolean Groebner Basis
+EXAMPLE: example boolean_poly; shows an example"
+{
+  if (size(#)==0)
+  {
+    return(recursive_boolean_poly(ps));
+  }
+  if (size(#)==1)
+  {
+    if (typeof(#[1])=="int")
+    {
+      if (#[1]==0) { return(direct_boolean_poly(ps)); }
+
+      return(recursive_boolean_poly(ps));
+    }
+    return(direct_boolean_poly(ps,#[1]));
+  }
+  if (#[1]==0) { return(direct_boolean_poly(ps,#[2])); }
+
+  return(recursive_boolean_poly(ps,#[2]));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring r=0,x(1..5),Dp;
+  poly f=x(2)*(x(3)-x(1))+x(4)*x(5);
+  bring rb=r;
+  boolean_poly(f);
+  boolean_poly(f,0);
+  boolean_poly(f,0,boolean_poly_ring(r));
+  boolean_poly(f,0,rb);
+
+
+  poly g=0;
+  boolean_poly(g);
+
+  poly g=1;
+  boolean_poly(g);
+}
+
+///////////////////////////////////////////////////////////////////////
+
+proc from_boolean_poly(def p, list #)
+"USAGE: from_boolean_poly(ps[, dir]); ps polynomial, dir integer zero or one
+RETURN: default: polynomial ps in the representation of the boolean ring
+NOTE: via the optional input dir, one can choose the computation method (either
+direct[dir==0] or recursive[dir==1]). default: direct
+SEE ALSO: boolean_ideal, boolean_std
+KEYWORDS: PolyBoRi, Boolean Groebner Basis
+EXAMPLE: example from_boolean_poly; shows an example"
+{
+  pyobject pb = pyobject(p);
+
+  if (size(#)==0) { return(direct_from_boolean_poly(pb)); }
+  if (#[1]==0) { return(direct_from_boolean_poly(pb)); }
+
+  return(recursive_from_boolean_poly(pb));
+}
+
+example
+{ "EXAMPLE:"; echo = 2;
+  ring r=0,(x,y,z),Dp;
+  def rb=boolean_poly_ring(r);
+  poly f=x^2+2*y+5*z^4;
+  bpoly pp=f;
+  from_boolean_poly(pp);
+  from_boolean_poly(pp,1);
+
+  ring r2=5,(x,y,z),Dp;
+  def rb2=boolean_poly_ring(r2);
+  poly f2=x+y+z;
+  bpoly pp2=f2;
+  from_boolean_poly(pp);
+  from_boolean_poly(pp,1);
+}
+
+///////////////////////////////////////////////////////////////////////
+
+proc direct_boolean_poly(poly ps, list #)
+"USAGE: boolean_poly(ps[, rb]); ps polynomial, rb boolean ring
+RETURN: default: polynomial ps in the representation of the boolean ring
+rb==boolean_poly_ring(basering); optional input: boolean ring rb
+SEE ALSO: boolean_ideal, boolean_std
+KEYWORDS: PolyBoRi, Boolean Groebner Basis
+EXAMPLE: example boolean_poly; shows an example"
+{
+  pyobject resultbool,rb;
+  rb=check_additional_ring(#);
+
+  int nmax= size(ps);
+  resultbool = Polynomial(rb.zero());
+  for (int i = 1; i <= nmax; i++)
+  {
+    if ( coeff_check(int(leadcoef(ps[i]))) == 1 )
+    {
+      resultbool=boolean_poly_update(resultbool,ps[i],rb);
+    }
+  }
+  return (resultbool);
+}
+
+example
+{ "EXAMPLE:"; echo = 2;
+  ring r0=2,x(1..4),lp;
+  bring rb=r0;
+  poly f=x(1)^2+2*x(2)*(x(3))-x(4)^3;
+  direct_boolean_poly(f);
+  direct_boolean_poly(f,rb);
+
+  ring r1=0,x,Dp;
+  poly f=x3+2x+1;
+  direct_boolean_poly(f);
+
+  ring r2=32003,(x,y,z),Dp;
+  poly f=xyz+20*x^2*y-3*xz+15;
+  direct_boolean_poly(f);
+}
+
+///////////////////////////////////////////////////////////////////////
+// one iteration in direct_boolean_poly
+
+static proc boolean_poly_update(def pb, poly ps, pyobject rb)
+"USAGE: boolean_poly_update(pb,ps,rb); pb boolean polynomial, ps polynomial,
+rb boolean ring
+RETURN: update of the boolean polynomial in boolean_poly in one iteration
+SEE ALSO: boolean_poly
+{
+  intvec current = leadexp(ps);
+  int j;
+  pyobject term, var_rb;
+  term = python_eval("Monomial")(rb);
+  for (j = 1; j <= size(current); j=j+1)
+  {
+    var_rb = rb.variable(j-1);
+    if (current[j] > 0) { term = term * var_rb; }
+  }
+  return (pb + term);
+}
+
+///////////////////////////////////////////////////////////////////////
+
+proc recursive_boolean_poly(poly ps, list #)
+"USAGE: boolean_poly(ps[, rb]); ps polynomial, rb boolean ring
+RETURN: default: polynomial ps in the representation of the boolean ring
+rb==boolean_poly_ring(basering); optional input: rb boolean ring
+SEE ALSO: boolean_ideal, boolean_std
+KEYWORDS: PolyBoRi, Boolean Groebner Basis
+EXAMPLE: example recursive_boolean_poly; shows an example"
+{
+  pyobject rb;
+  if (size(#)==0)
+  {
+    #[1]=boolean_poly_ring(basering);
+    #[2]=0;
+  }
+  if (size(#)==1)
+  {
+    #[2]=0;
+  }
+  rb=check_additional_ring(#[1]);
+  if (#[2]==int(rb.n_variables()))
+  {
+    return (boolean_constant(int(leadcoef(ps)),rb));
+  }
+  else
+  {
+    def xsu=var(#[2]+1);
+    poly p0=subst(ps,xsu,0);
+    poly p1=subst(ps-p0,xsu,1);
+    def ahelp=recursive_boolean_poly(p1,rb,#[2]+1);
+    def bhelp=recursive_boolean_poly(p0,rb,#[2]+1);
+    return (rb.variable(#[2])*ahelp+bhelp);
+  }
+}
+
+example
+{ "EXAMPLE:"; echo = 2;
+  ring r0=2,x(1..4),lp;
+  poly f=x(1)^2+2*x(2)*(x(3))-x(4)^3;
+  recursive_boolean_poly(f);
+
+  ring r1=0,x,Dp;
+  poly f=x3+2x+1;
+  recursive_boolean_poly(f);
+
+  ring r2=32003,(x,y,z),Dp;
+  def br2=boolean_poly_ring(r2);
+  bring bbr2=r2;
+  poly f=xyz+20*x^2*y-3*xz+15;
+  recursive_boolean_poly(f,br2);
+  recursive_boolean_poly(f,bbr2);
+}
+
+///////////////////////////////////////////////////////////////////////
+
+proc boolean_ideal(ideal Is, list #)
+"USAGE: boolean_ideal(Is[, rb]); Is Ideal, rb boolean ring
+RETURN: default: ideal Is in the representation of the boolean ring
+rb==boolean_poly_ring(basering); optional input: rb boolean ring
+SEE ALSO: boolean_std
+KEYWORDS: PolyBoRi, Boolean Groebner Basis
+EXAMPLE: example boolean_ideal; shows an example"
+{
+  pyobject rb;
+  rb=check_additional_ring(#);
+  int len=size(Is);
+  pyobject Ib = python_eval("list()");
+  for (int i=1; i<=len; i++)
+  {
+    Ib.append(boolean_poly(Is[i],rb));
+  }
+  bideal re;
+  re.pylist = Ib;
+
+  return(re);
+}
+
+example
+{ "EXAMPLE:"; echo = 2;
+  ring r0=2,x(1..4),lp;
+  poly f1=x(1)^2+2*x(2)*(x(3))-x(4)^3;
+  poly f2=x(1)^2-x(3)*x(1);
+  poly f3=x(2)+5-2*x(1);
+  poly f4=x(1)*x(2)-x(3);
+  ideal I=f1,f2,f3,f4;
+  boolean_ideal(I);
+
+  ring r1=0,x,Dp;
+  poly f1=x3+2*x+1;
+  poly f2=x10-x5+2x;
+  poly f3=19;
+  ideal I=f1,f2,f3;
+  boolean_ideal(I);
+
+  ring r2=32003,(x,y,z),Dp;
+  bring bbr2=r2;
+  poly f1=xyz+20*x^2*y-3*xz+15;
+  poly f2=32002*xy+z2;
+  poly f3=19;
+  ideal I=f1,f2,f3;
+  boolean_ideal(I);
+  boolean_ideal(I,bbr2);
+}
+
+////////////////////////////////////////////////////////////////
+
+proc from_boolean_ideal(bideal I)
+"USAGE: from_boolean_ideal(I); I boolean ideal
+RETURN: ideal in Singular
+SEE ALSO: from_boolean_poly, boolean_ideal, boolean_poly, boolean_std,
+boolean_poly_ring
+KEYWORDS: PolyBoRi, Boolean Groebner Basis
+EXAMPLE: example from_boolean_ideal; shows an example"
+{
+  ideal re;
+  int i;
+  int nlen = size(I);
+  for (i = 1; i <= nlen; i++)
+  {
+    re[i] = from_boolean_poly(I[i]);
+  }
+  return (re);
+}
+
+example
+{ "EXAMPLE:"; echo=2;
+  ring rs=0,(x,y,z),Dp;
+  def rb3=boolean_poly_ring(rs);
+  poly f1=x+y;
+  poly f2=x+z;
+  bpoly pp =f1;
+  bpoly p = f2;
+  bideal Ib;
+  list K=(p,pp);
+  Ib=K;
+  from_boolean_ideal(Ib);
+
+  ring rs2=5,(x,y,z),Dp;
+  def rb4=boolean_poly_ring(rs2);
+  poly p1=x+y;
+  poly p2=x+z;
+  poly p3=y+z;
+  bpoly p = p1;
+  bpoly pp = p2;
+  bpoly ppp = p3;
+  bideal Ib;
+  list K=(p,pp,ppp);
+  Ib=K;
+  from_boolean_ideal(Ib);
+}
+
+///////////////////////////////////////////////////////////////////////
+
+proc boolean_std(bideal Is)
+"USAGE: boolean_std(Is); Is ideal
+RETURN: Singular ideal of the boolean groebner basis of Is
+SEE ALSO: from_boolean_poly, boolean_ideal, boolean_poly, from_boolean_ideal,
+boolean_poly_ring
+KEYWORDS: PolyBoRi, Boolean Groebner Basis
+EXAMPLE: example boolean_std; shows an example"
+{
+  pyobject Ib = Is;
+
+  def redIb=groebner_basis(Ib);
+  bideal result = redIb;
+  return(result);
+}
+
+example
+{ "EXAMPLE:"; echo = 2;
+  ring r0=2,x(1..4),lp;
+  poly f1=x(1)^2+2*x(2)*(x(3))-x(4)^3;
+  poly f2=x(1)^2-x(3)*x(1);
+  poly f3=x(2)+5-2*x(1);
+  poly f4=x(1)*x(2)-x(3);
+  ideal I=f1,f2,f3,f4;
+
+  boolean_std(I);        // implicitely add x(i)^2-x(i)
+
+  bideal bI=I;           // alternative syntax
+  bideal re = std(bI);  // Continue PolyBoRi computations
+  std(re[1..2]);
+
+  ring r1=0,x,Dp;
+  poly f1=x3+2*x+1;
+  poly f2=x10-x5+2x;
+  poly f3=19;
+  ideal I=f1,f2,f3;
+  boolean_std(I);
+
+  ring r2=32003,(x,y,z),Dp;
+  poly f1=xz+y+20*x^2*y;
+  poly f2=32002*xy+xz2+y;
+  ideal I=f1,f2;
+  boolean_std(I);
+
+  ring r2=32003,(x,y,z),Dp;
+  poly f1=xyz+20*x^2*y-3*xz+15;
+  poly f2=32002*xy+z2;
+  poly f3=19*x5y;
+  ideal I=f1,f2,f3;
+  boolean_std(I);
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+proc from_boolean_constant(def p)
+"USAGE: from_boolean_constant(pb); pb pyobject
+RETURN: constant polynomial
+SEE ALSO: boolean_ideal, boolean_std
+KEYWORDS: PolyBoRi, Boolean Groebner Basis
+EXAMPLE: example from_boolean_constant; shows an example"
+{
+  pyobject pb = p;
+  if (pb==0) { return (poly(0)); }
+
+  return (poly(1));
+}
+
+example
+{ "EXAMPLE:"; echo = 2;
+  ring rs=0,(x,y,z),Dp;
+  def rsb=boolean_poly_ring(rs);
+  poly f=(x+y)*x+z;
+  bpoly pp=f;
+  from_boolean_constant(0);
+  from_boolean_constant(1);
+  from_boolean_constant(pp);
+}
+
+///////////////////////////////////////////////////////////////////////
+
+proc recursive_from_boolean_poly(def p)
+"USAGE: recursive_from_boolean_poly(pb); pb boolean polynomial
+RETURN: polynomial in Singular
+SEE ALSO: from_boolean_poly, boolean_ideal, boolean_poly, from_boolean_ideal,
+boolean_poly_ring
+KEYWORDS: PolyBoRi, Boolean Groebner Basis
+EXAMPLE: example recursive_from_boolean_poly; shows an example"
+{
+  pyobject pb = p;
+
+  if (pb==0) { return(0); }
+  if (pb==1) { return(1); }
+
+  int idx = int(pb.navigation().value());
+  def p0=Polynomial(pb.set().subset0(idx));
+  def p1 = Polynomial(pb.set().subset1(idx));
+
+  return (var(idx+1)*recursive_from_boolean_poly(p1)+recursive_from_boolean_poly(p0));
+}
+
+example
+{ "EXAMPLE:"; echo = 2;
+  ring rs=0,(x,y,z),Dp;
+  def rsb=boolean_poly_ring(rs);
+  poly f=(x+y)*x+z;
+  bpoly pp=f;
+  recursive_from_boolean_poly(pp);
+
+  ring rs2=2,(x,y,z),Dp;
+  def rsb2=boolean_poly_ring(rs2);
+  poly f2=(x+y)*x+x;
+  bpoly pp2=f2;
+  recursive_from_boolean_poly(pp);
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+proc poly2zdd(poly ps)
+"USAGE: poly2zdd(poly ps); polynomial ps
+RETURN: polynomial ps in zdd representation
+SEE ALSO: boolean_poly, from_boolean_set
+KEYWORDS: PolyBoRi, zero-supressed decision diagram
+EXAMPLE: example poly2zdd; shows an example"
+{
+  pyobject pp=boolean_poly(ps);
+  pyobject pset = pp.set();
+  zdd result = from_boolean_set(pset);
+  return(result);
+}
+
+example
+{ "EXAMPLE:"; echo = 2;
+  ring r=0,x(1..5),Dp;
+  poly f=(x(1)+1)*(x(2)+1)*(x(3)+1)*x(4)*x(5);
+  poly2zdd(f);
+
+  poly g=x(3);
+  poly2zdd(g);
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+proc zdd2poly(zdd ss)
+"USAGE: zdd2poly(ss); zero-supressed decision diagram ss
+RETURN: zdd ss in polynomial representation
+SEE ALSO:from_boolean_poly, boolean_set
+KEYWORDS: PolyBoRi, Boolean Groebner Basis
+EXAMPLE: example poly2zdd; shows an example"
+{
+  def ps=boolean_set(ss);
+  return(from_boolean_poly(Polynomial(ps)));
+}
+
+example
+{ "EXAMPLE:"; echo = 2;
+  ring r=0,x(1..5),Dp;
+  poly f=(x(1)+1)*(x(2)+1)*(x(3)+1)*x(4)*x(5);
+  zdd2poly(poly2zdd(f));
+
+  poly g=x(3);
+  zdd2poly(poly2zdd(g));
+
+  poly g=0;
+  zdd2poly(poly2zdd(0));
+
+  poly g=1;
+  zdd2poly(poly2zdd(01));
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+proc disp_zdd(zdd ss, list #)
+"USAGE: disp_zdd(ss); zero-supressed decision diagram ss
+RETURN: string containing visualization of ss
+NOTE: the resulting string is the visualization of the polynomial that corresponds
+to ss, but with a additional structure that comes from the zdd. Every reached else-
+Branch induces a new line in the string.
+SEE ALSO:zdd2poly, poly2zdd
+KEYWORDS: Polybori, Boolean Groebner Basis
+EXAMPLE: example disp_zdd; shows an example"
+{
+  int dist,i;
+  string str,space;
+  if (size(#)==0)
+  {
+    dist=1;
+    str=" ";
+  }
+  else
+  {
+    dist=#[1];
+    str=#[2];
+  }
+  for (i=1;i<=dist+3;i++)
+  {
+    space=space+" ";
+  }
+  if (ss.idx==0)
+  {
+    if (size(space)>5)
+    {
+      return(str);
+    }
+    else
+    {
+      if (ss==zdd_one)
+      {
+        return (1);
+      }
+      else
+      {
+      return (0);
+      }
+    }
+  }
+  else
+  {
+    str=str,"x",string(ss.idx);
+    if (ss.thenBranch.idx!=0)
+    {
+      str=str,"(";
+      str=disp_zdd(ss.thenBranch,dist+3,str);
+      str=str,")";
+    }
+    if ((ss.elseBranch.idx!=0)||(ss.elseBranch==zdd_one))
+    {
+      if (ss.elseBranch==zdd_one)
+      {
+        str=str+"+1";
+      }
+      else
+      {
+        str=str,"+"+newline+space;
+        str=disp_zdd(ss.elseBranch,dist+3,str);
+      }
+    }
+    return(str);
+  }
+}
+
+example
+{ "EXAMPLE:"; echo = 2;
+  ring r1=0,(x,y,z),Dp;
+  poly f1=xyz+xy+xz+yz+y+z+x+1;
+  zdd s1=f1;
+  disp_zdd(s1);
+
+  ring r2=0,x(1..6),Dp;
+  poly f2=x(1)+x(2)+x(3)+x(5)^2+x(6);
+  zdd s2=f2;
+  disp_zdd(s2);
+
+  ring r4=0,x(1..6),Dp;
+  poly f2=x(1)+1;
+  zdd s2=f2;
+  disp_zdd(s2);
+
+  ring r2=0,x(1..6),Dp;
+  poly f2=x(1)*x(2)*(x(3)-x(5)^2*x(6))+3*x(4)*x(5)-3;
+  zdd s2=f2;
+  disp_zdd(s2);
+
+  poly f4=0;
+  zdd s4=f4;
+  disp_zdd(s4);
+
+  poly f5=1;
+  zdd s5=f5;
+  disp_zdd(s5);
+}
diff --git a/Singular/LIB/polymake.lib b/Singular/LIB/polymake.lib
new file mode 100644
index 0000000..6941fac
--- /dev/null
+++ b/Singular/LIB/polymake.lib
@@ -0,0 +1,2483 @@
+version="version polymake.lib 4.0.0.0 Jun_2013 ";
+category="Tropical Geometry";
+info="
+LIBRARY:   polymake.lib    Computations with polytopes and fans,
+                           interface to polymake and TOPCOM
+AUTHOR:    Thomas Markwig,  email: keilen at mathematik.uni-kl.de
+
+WARNING:
+   Most procedures will not work unless polymake or topcom is installed and
+   if so, they will only work with the operating system LINUX!
+   For more detailed information see IMPORTANT NOTE respectively consult the
+   help string of the procedures.
+
+   The conventions used in this library for polytopes and fans, e.g. the
+   length and labeling of their vertices resp. rays, differs from the conventions
+   used in polymake and thus from the conventions used in the polymake
+   extension polymake.so of Singular. We recommend to use the newer polymake.so
+   whenever possible.
+
+IMPORTANT NOTE:
+   Even though this is a Singular library for computing polytopes and fans
+   such as the Newton polytope or the Groebner fan of a polynomial, most of
+   the hard computations are NOT done by Singular but by the program
+@* - polymake by Ewgenij Gawrilow, TU Berlin and Michael Joswig, TU Darmstadt
+@*   (see http://www.math.tu-berlin.de/polymake/),
+@* respectively (only in the procedure triangulations) by the program
+@* - topcom by Joerg Rambau, Universitaet Bayreuth (see
+@*   http://www.uni-bayreuth.de/departments/wirtschaftsmathematik/rambau/TOPCOM);
+@*   this library should rather be seen as an interface which allows to use a
+     (very limited) number of options which polymake respectively topcom offers
+     to compute with polytopes and fans and to make the results available in
+     Singular for further computations;
+     moreover, the user familiar with Singular does not have to learn the syntax
+     of polymake or topcom, if the options offered here are sufficient for his
+     purposes.
+@*   Note, though, that the procedures concerned with planar polygons are
+     independent of both, polymake and topcom.
+
+PROCEDURES USING POLYMAKE:
+  polymakePolytope()  computes the vertices of a polytope using polymake
+  newtonPolytopeP()    computes the Newton polytope of a polynomial
+  newtonPolytopeLP()  computes the lattice points of the Newton polytope
+  normalFanL()         computes the normal fan of a polytope
+  groebnerFan()       computes the Groebner fan of a polynomial
+
+PROCEDURES USING TOPCOM:
+  triangulations()    computes all triangulations of a marked polytope
+  secondaryPolytope() computes the secondary polytope of a marked polytope
+
+PROCEDURES USING POLYMAKE AND TOPCOM:
+  secondaryFan()      computes the secondary fan of a marked polytope
+
+PROCEDURES CONERNED WITH PLANAR POLYGONS:
+  cycleLength()    computes the cycleLength of cycle
+  splitPolygon()   splits a marked polygon into vertices, facets, interior points
+  eta()            computes the eta-vector of a triangulation
+  findOrientedBoundary()  computes the boundary of a convex hull
+  cyclePoints()    computes lattice points connected to some lattice point
+  latticeArea()    computes the lattice area of a polygon
+  picksFormula()   computes the ingrediants of Pick's formula for a polygon
+  ellipticNF()     computes the normal form of an elliptic polygon
+  ellipticNFDB()   displays the 16 normal forms of elliptic polygons
+
+KEYWORDS:    polytope; fan; secondary fan; secondary polytope; polymake;
+             Newton polytope; Groebner fan
+";
+
+////////////////////////////////////////////////////////////////////////////////
+/// Auxilary Static Procedures in this Library
+////////////////////////////////////////////////////////////////////////////////
+/// - scalarproduct
+/// - intmatcoldelete
+/// - intmatconcat
+/// - sortlist
+/// - minInList
+/// - stringdelete
+/// - abs
+/// - commondenominator
+/// - maxPosInIntvec
+/// - maxPosInIntmat
+/// - sortintvec
+/// - matrixtointmat
+////////////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////////////
+LIB "poly.lib";
+LIB "linalg.lib";
+LIB "random.lib";
+////////////////////////////////////////////////////////////////////////////////
+
+static proc mod_init ()
+{
+  LIB "gfanlib.so";
+  LIB "polymake.so";
+}
+
+/////////////////////////////////////////////////////////////////////////////
+/// PROCEDURES USING POLYMAKE
+/////////////////////////////////////////////////////////////////////////////
+
+proc polymakePolytope (intmat points)
+"USAGE:  polymakePolytope(points);   polytope intmat
+ASSUME:  each row of points gives the coordinates of a lattice point of a
+         polytope with their affine coordinates as given by the output of
+         secondaryPolytope
+PURPOSE: the procedure calls polymake to compute the vertices of the polytope
+         as well as its dimension and information on its facets
+RETURN:  list, L with four entries
+@*            L[1] : an integer matrix whose rows are the coordinates of vertices
+                     of the polytope
+@*            L[2] : the dimension of the polytope
+@*            L[3] : a list whose ith entry explains to which vertices the
+                     ith vertex of the Newton polytope is connected
+                     -- i.e. L[3][i] is an integer vector and an entry k in
+                        there means that the vertex L[1][i] is connected to the
+                        vertex L[1][k]
+@*            L[4] : an matrix of type bigintmat whose rows mulitplied by
+                     (1,var(1),...,var(nvar)) give a linear system of equations
+                     describing the affine hull of the polytope,
+                     i.e. the smallest affine space containing the polytope
+NOTE: -  for its computations the procedure calls the program polymake by
+         Ewgenij Gawrilow, TU Berlin and Michael Joswig, TU Darmstadt;
+         it therefore is necessary that this program is installed in order
+         to use this procedure;
+         see http://www.math.tu-berlin.de/polymake/
+@*    -  note that in the vertex edge graph we have changed the polymake
+         convention which starts indexing its vertices by zero while we start
+         with one !
+EXAMPLE: example polymakePolytope;   shows an example"
+{
+  // add a first column to polytope as homogenising coordinate
+  points=intmatAddFirstColumn(points,"points");
+  polytope polytop=polytopeViaPoints(points);
+  list graph=vertexAdjacencyGraph(polytop)[2];
+  int i,j;
+  for (i=1;i<=size(graph);i++)
+  {
+    for (j=1;j<=size(graph[i]);j++)
+    {
+      graph[i][j]=graph[i][j]+1;
+    }
+  }
+  return(list(intmatcoldelete(vertices(polytop),1),dimension(polytop),graph,equations(polytop)));
+}
+example
+{
+   "EXAMPLE:";
+   echo=2;
+   // the lattice points of the unit square in the plane
+   list points=intvec(0,0),intvec(0,1),intvec(1,0),intvec(1,1);
+   // the secondary polytope of this lattice point configuration is computed
+   intmat secpoly=secondaryPolytope(points)[1];
+   list np=polymakePolytope(secpoly);
+   // the vertices of the secondary polytope are:
+   np[1];
+   // its dimension is
+   np[2];
+   // np[3] contains information how the vertices are connected to each other,
+   // e.g. the first vertex (number 0) is connected to the second one
+   np[3][1];
+   // the affine hull has the equation
+   ring r=0,x(1..4),dp;
+   matrix M[5][1]=1,x(1),x(2),x(3),x(4);
+   intmat(np[4])*M;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+proc newtonPolytopeP (poly f)
+"USAGE: newtonPolytopeP(f);  f poly
+RETURN: list, L with four entries
+@*            L[1] : an integer matrix whose rows are the coordinates of vertices
+                     of the Newton polytope of f
+@*            L[2] : the dimension of the Newton polytope of f
+@*            L[3] : a list whose ith entry explains to which vertices the
+                     ith vertex of the Newton polytope is connected
+                     -- i.e. L[3][i] is an integer vector and an entry k in
+                        there means that the vertex L[1][i] is
+                        connected to the vertex L[1][k]
+@*            L[4] : an matrix of type bigintmat whose rows mulitplied by
+                     (1,var(1),...,var(nvar)) give a linear system of equations
+                     describing the affine hull of the Newton polytope, i.e. the
+                     smallest affine space containing the Newton polytope
+NOTE: -  if we replace the first column of L[4] by zeros, i.e. if we move
+         the affine hull to the origin, then we get the equations for the
+         orthogonal complement of the linearity space of the normal fan dual
+         to the Newton polytope, i.e. we get the EQUATIONS that
+         we need as input for polymake when computing the normal fan
+@*    -  the procedure calls for its computation polymake by Ewgenij Gawrilow,
+         TU Berlin and Michael Joswig, so it only works if polymake is installed;
+         see http://www.math.tu-berlin.de/polymake/
+EXAMPLE: example newtonPolytopeP;   shows an example"
+{
+  int i,j;
+  // compute the list of exponent vectors of the polynomial,
+  // which are the lattice points
+  // whose convex hull is the Newton polytope of f
+  intmat exponents[size(f)][nvars(basering)];
+  while (f!=0)
+  {
+    i++;
+    exponents[i,1..nvars(basering)]=leadexp(f);
+    f=f-lead(f);
+  }
+  // call polymakePolytope with exponents
+  return(polymakePolytope(exponents));
+}
+example
+{
+   "EXAMPLE:";
+   echo=2;
+   ring r=0,(x,y,z),dp;
+   matrix M[4][1]=1,x,y,z;
+   poly f=y3+x2+xy+2xz+yz+z2+1;
+   // the Newton polytope of f is
+   list np=newtonPolytopeP(f);
+   // the vertices of the Newton polytope are:
+   np[1];
+   // its dimension is
+   np[2];
+   // np[3] contains information how the vertices are connected to each other,
+   // e.g. the first vertex (number 0) is connected to the second, third and
+   //      fourth vertex
+   np[3][1];
+   //////////////////////////
+   f=x2-y3;
+   // the Newton polytope of f is
+   np=newtonPolytopeP(f);
+   // the vertices of the Newton polytope are:
+   np[1];
+   // its dimension is
+   np[2];
+   // the Newton polytope is contained in the affine space given
+   //     by the equations
+   intmat(np[4])*M;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+proc newtonPolytopeLP (poly f)
+"USAGE:  newtonPolytopeLP(f);  f poly
+RETURN: list, the exponent vectors of the monomials occuring in f,
+              i.e. the lattice points of the Newton polytope of f
+EXAMPLE: example newtonPolytopeLP;   shows an example"
+{
+  list np;
+  int i=1;
+  while (f!=0)
+  {
+    np[i]=leadexp(f);
+    f=f-lead(f);
+    i++;
+  }
+  return(np);
+}
+example
+{
+   "EXAMPLE:";
+   echo=2;
+   ring r=0,(x,y,z),dp;
+   poly f=y3+x2+xy+2xz+yz+z2+1;
+   // the lattice points of the Newton polytope of f are
+   newtonPolytopeLP(f);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+proc normalFanL (def vertices, def affinehull,list graph,int er,list #)
+"USAGE:  normalFanL (vert,aff,graph,rays,[,#]);   vert,aff intmat,  graph list, rays int, # string
+ASSUME:  - vert is an integer matrix whose rows are the coordinate of
+           the vertices of a convex lattice polytope;
+@*       - aff describes the affine hull of this polytope, i.e.
+           the smallest affine space containing it, in the following sense:
+           denote by n the number of columns of vert, then multiply aff by
+           (1,x(1),...,x(n)) and set the resulting terms to zero in order to
+           get the equations for the affine hull;
+@*       - the ith entry of graph is an integer vector describing to which
+           vertices the ith vertex is connected, i.e. a k as entry means that
+           the vertex vert[i] is connected to vert[k];
+@*       - the integer rays is either one (if the extreme rays should be
+           computed) or zero (otherwise)
+RETURN:  list, the ith entry of L[1] contains information about the cone in the
+               normal fan dual to the ith vertex of the polytope
+@*             L[1][i][1] = integer matrix representing the inequalities which
+                            describe the cone dual to the ith vertex
+@*             L[1][i][2] = a list which contains the inequalities represented
+                            by L[i][1] as a list of strings, where we use the
+                            variables x(1),...,x(n)
+@*             L[1][i][3] = only present if 'er' is set to 1; in that case it is
+                            an interger matrix whose rows are the extreme rays
+                            of the cone
+@*             L[2] = is an integer matrix whose rows span the linearity space
+                      of the fan, i.e. the linear space which is contained in
+                      each cone
+NOTE:    - the procedure calls for its computation polymake by Ewgenij Gawrilow,
+           TU Berlin and Michael Joswig, so it only works if polymake is
+           installed;
+           see http://www.math.tu-berlin.de/polymake/
+@*       - in the optional argument # it is possible to hand over other names
+           for the variables to be used -- be careful, the format must be correct
+           and that is not tested, e.g. if you want the variable names to be
+           u00,u10,u01,u11 then you must hand over the string u11,u10,u01,u11
+EXAMPLE: example normalFanL;   shows an example"
+{
+  if (typeof(affinehull) != "intmat" && typeof (affinehull) != "bigintmat")
+  {
+    ERROR("normalFanL: input affinehull has to be either intmat or bigintmat");
+    list L;
+    return (L);
+  }
+  list ineq; // stores the inequalities of the cones
+  int i,j,k;
+  // we work over the following ring
+  execute("ring ineqring=0,x(1.."+string(ncols(vertices))+"),lp;");
+  string greatersign=">";
+  // create the variable names
+  if (size(#)>0)
+  {
+    if (typeof(#[1])=="string")
+    {
+      kill ineqring;
+      execute("ring ineqring=0,("+#[1]+"),lp;");
+    }
+    if (size(#)>1)
+    {
+      greatersign="<";
+    }
+  }
+  //////////////////////////////////////////////////////////////////
+  // Compute first the inequalities of the cones
+  //////////////////////////////////////////////////////////////////
+  matrix VAR[1][ncols(vertices)]=maxideal(1);
+  matrix EXP[ncols(vertices)][1];
+  poly p,pl,pr;
+  // consider all vertices of the polytope
+  for (i=1;i<=nrows(vertices);i++)
+  {
+    // first we produce for each vertex in the polytope
+    // the inequalities describing the dual cone in the normal fan
+    list pp;  // contain strings representing the inequalities
+              // describing the normal cone
+    if (typeof (vertices) == "intmat")
+    {
+      intmat ie[size(graph[i])][ncols(vertices)]; // contains the inequalities
+    }                                             // as rows
+    if (typeof (vertices) == "bigintmat")
+    {
+      bigintmat ie[size(graph[i])][ncols(vertices)]; // contains the inequalities
+    }                                                // as rows
+    // consider all the vertices to which the ith vertex in the
+    // polytope is connected by an edge
+    for (j=1;j<=size(graph[i]);j++)
+    {
+      // produce the vector ie_j pointing from the jth vertex to the ith vertex;
+      // this will be the jth inequality for the cone in the normal fan dual to
+      // the ith vertex
+      ie[j,1..ncols(vertices)]=vertices[i,1..ncols(vertices)]-vertices[graph[i][j],1..ncols(vertices)];
+      EXP=ie[j,1..ncols(vertices)];
+      // build a linear polynomial with the entries of ie_j as coefficients
+      p=(VAR*EXP)[1,1];
+      pl,pr=0,0;
+      // separate the terms with positive coefficients in p from
+      // those with negative coefficients
+      for (k=1;k<=size(p);k++)
+      {
+        if (leadcoef(p[k])<0)
+        {
+          pr=pr-p[k];
+        }
+        else
+        {
+          pl=pl+p[k];
+        }
+      }
+      // build the string which represents the jth inequality
+      // for the cone dual to the ith vertex
+      // as polynomial inequality of type string, and store this
+      // in the list pp as jth entry
+      pp[j]=string(pl)+" "+greatersign+" "+string(pr);
+    }
+    // all inequalities for the ith vertex are stored in the list ineq
+    ineq[i]=list(ie,pp);
+    kill ie,pp; // kill certain lists
+  }
+  // remove the first column of affine hull to compute the linearity space
+  bigintmat linearity[1][ncols(vertices)];
+  if (nrows(affinehull)>0)
+  {
+    linearity=intmatcoldelete(affinehull,1);
+  }
+  //////////////////////////////////////////////////////////////////
+  // Compute next the extreme rays of the cones
+  //////////////////////////////////////////////////////////////////
+  if (er==1)
+  {
+    list extremerays; // keeps the result
+    cone kegel;
+    bigintmat linearspan=intmatAddFirstColumn(linearity,"rays");
+    intmat M; // the matrix keeping the inequalities
+    for (i=1;i<=size(ineq);i++)
+    {
+      kegel=coneViaInequalities(intmatAddFirstColumn(ineq[i][1],"rays"),linearspan);
+      extremerays[i]=intmatcoldelete(rays(kegel),1);
+    }
+    for (i=1;i<=size(ineq);i++)
+    {
+      ineq[i]=ineq[i]+list(extremerays[i]);
+    }
+  }
+  // get the linearity space
+  return(list(ineq,linearity));
+}
+example
+{
+   "EXAMPLE:";
+   echo=2;
+   ring r=0,(x,y,z),dp;
+   matrix M[4][1]=1,x,y,z;
+   poly f=y3+x2+xy+2xz+yz+z2+1;
+   // the Newton polytope of f is
+   list np=newtonPolytopeP(f);
+   // the Groebner fan of f, i.e. the normal fan of the Newton polytope
+   list gf=normalFanL(np[1],np[4],np[3],1,"x,y,z");
+   // the number of cones in the Groebner fan of f is:
+   size(gf[1]);
+   // the inequalities of the first cone as matrix are:
+   print(gf[1][1][1]);
+   // the inequalities of the first cone as string are:
+   print(gf[1][1][2]);
+   // the rows of the following matrix are the extreme rays of the first cone:
+   print(gf[1][1][3]);
+   // each cone contains the linearity space spanned by:
+   print(gf[2]);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+proc groebnerFan (poly f)
+"USAGE:  groebnerFan(f);  f poly
+RETURN:  list, the ith entry of L[1] contains information about the ith cone
+               in the Groebner fan dual to the ith vertex in the Newton
+               polytope of the f
+@*             L[1][i][1] = integer matrix representing the inequalities
+                            which describe the cone
+@*             L[1][i][2] = a list which contains the inequalities represented
+                            by L[1][i][1] as a list of strings
+@*             L[1][i][3] = an interger matrix whose rows are the extreme rays
+                            of the cone
+@*             L[2] = is an integer matrix whose rows span the linearity space
+                      of the fan, i.e. the linear space which is contained
+                      in each cone
+@*             L[3] = the Newton polytope of f in the format of the procedure
+                      newtonPolytopeP
+@*             L[4] = integer matrix where each row represents the exponent
+                      vector of one monomial occuring in the input polynomial
+NOTE: - if you have already computed the Newton polytope of f then you might want
+        to use the procedure normalFanL instead in order to avoid doing costly
+        computation twice
+@*    - the procedure calls for its computation polymake by Ewgenij Gawrilow,
+        TU Berlin and Michael Joswig, so it only works if polymake is installed;
+        see http://www.math.tu-berlin.de/polymake/
+EXAMPLE: example groebnerFan;   shows an example"
+{
+  int i,j;
+  // compute the list of exponent vectors of the polynomial, which are
+  // the lattice points whose convex hull is the Newton polytope of f
+  intmat exponents[size(f)][nvars(basering)];
+  while (f!=0)
+  {
+    i++;
+    exponents[i,1..nvars(basering)]=leadexp(f);
+    f=f-lead(f);
+  }
+  // call polymakePolytope with exponents
+  list newtonp=polymakePolytope(exponents);
+  // get the variables as string
+  string variablen;
+  for (i=1;i<=nvars(basering);i++)
+  {
+    variablen=variablen+string(var(i))+",";
+  }
+  variablen=variablen[1,size(variablen)-1];
+  // call normalFanL in order to compute the Groebner fan
+  list gf=normalFanL(newtonp[1],newtonp[4],newtonp[3],1,variablen);
+  // append newtonp to gf
+  gf[3]=newtonp;
+  // append the exponent vectors to gf
+  gf[4]=exponents;
+  return(gf);
+}
+example
+{
+   "EXAMPLE:";
+   echo=2;
+   ring r=0,(x,y,z),dp;
+   matrix M[4][1]=1,x,y,z;
+   poly f=y3+x2+xy+2xz+yz+z2+1;
+   // the Newton polytope of f is
+   list gf=groebnerFan(f);
+   // the exponent vectors of f are ordered as follows
+   gf[4];
+   // the first cone of the groebner fan has the inequalities
+   gf[1][1][1];
+   // as a string they look like
+   gf[1][1][2];
+   // and it has the extreme rays
+   print(gf[1][1][3]);
+   // the linearity space is spanned by
+   print(gf[2]);
+   // the vertices of the Newton polytope are:
+   gf[3][1];
+   // its dimension is
+   gf[3][2];
+   // np[3] contains information how the vertices are connected to each other,
+   // e.g. the 1st vertex is connected to the 2nd, 3rd and 4th vertex
+   gf[3][3][1];
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+/// PROCEDURES USING TOPCOM
+///////////////////////////////////////////////////////////////////////////////
+
+proc triangulations (list polygon,list #)
+"USAGE:  triangulations(polygon[,#]); list polygon, list #
+ASSUME:  polygon is a list of integer vectors of the same size representing
+         the affine coordinates of the lattice points
+PURPOSE: the procedure considers the marked polytope given as the convex hull of
+         the lattice points and with these lattice points as markings; it then
+         computes all possible triangulations of this marked polytope
+RETURN:  list, each entry corresponds to one triangulation and the ith entry is
+               itself a list of integer vectors of size three, where each integer
+               vector defines one triangle in the triangulation by telling which
+               points of the input are the vertices of the triangle
+NOTE:- the procedure calls for its computations the program points2triangs
+       from the program topcom by Joerg Rambau, Universitaet Bayreuth; it
+       therefore is necessary that this program is installed in order to use
+       this  procedure; see
+@*     http://www.uni-bayreuth.de/departments/wirtschaftsmathematik/rambau/TOPCOM
+@*   - if you only want to have the regular triangulations the procedure should
+       be called with the string 'regular' as optional argument
+@*   - the procedure creates the files /tmp/triangulationsinput and
+       /tmp/triangulationsoutput;
+       the former is used as input for points2triangs and the latter is its
+       output containing the triangulations of corresponding to points in the
+       format of points2triangs; if you wish to use this for further
+       computations with topcom, you have to call the procedure with the
+       string 'keepfiles' as optional argument
+@*   - note that an integer i in an integer vector representing a triangle
+       refers to the ith lattice point, i.e. polygon[i]; this convention is
+       different from TOPCOM's convention, where i would refer to the i-1st
+       lattice point
+EXAMPLE: example triangulations;   shows an example"
+{
+  int i,j;
+  // check for optional arguments
+  int regular,keepfiles;
+  if (size(#)>0)
+  {
+    for (i=1;i<=size(#);i++)
+    {
+      if (typeof(#[i])=="string")
+      {
+        if (#[i]=="keepfiles")
+        {
+          keepfiles=1;
+        }
+        if (#[i]=="regular")
+        {
+          regular=1;
+        }
+      }
+    }
+  }
+  // prepare the input for points2triangs by writing the input polygon in the
+  // necessary format
+  string spi="[";
+  for (i=1;i<=size(polygon);i++)
+  {
+    polygon[i][size(polygon[i])+1]=1;
+    spi=spi+"["+string(polygon[i])+"]";
+    if (i<size(polygon))
+    {
+      spi=spi+",";
+    }
+  }
+  spi=spi+"]";
+  write(":w /tmp/triangulationsinput",spi);
+  // call points2triangs
+  if (regular==1) // compute only regular triangulations
+  {
+    system("sh","cd /tmp; points2triangs --regular < triangulationsinput > triangulationsoutput");
+  }
+  else // compute all triangulations
+  {
+    system("sh","cd /tmp; points2triangs < triangulationsinput > triangulationsoutput");
+  }
+  string p2t=read("/tmp/triangulationsoutput"); // takes result of points2triangs
+  // delete the tmp-files, if no second argument is given
+  if (keepfiles==0)
+  {
+    system("sh","cd /tmp; rm -f triangulationsinput; rm -f triangulationsoutput");
+  }
+  // preprocessing of p2t if points2triangs is version >= 0.15
+  // brings p2t to the format of version 0.14
+  string np2t; // takes the triangulations in Singular format
+  for (i=1;i<=size(p2t)-2;i++)
+  {
+    if ((p2t[i]==":") and (p2t[i+1]=="=") and (p2t[i+2]=="["))
+    {
+      np2t=np2t+p2t[i]+p2t[i+1];
+      i=i+3;
+      while (p2t[i]!=":")
+      {
+        i=i+1;
+      }
+    }
+    else
+    {
+      if ((p2t[i]=="]") and (p2t[i+1]==";"))
+      {
+        np2t=np2t+p2t[i+1];
+        i=i+1;
+      }
+      else
+      {
+        np2t=np2t+p2t[i];
+      }
+    }
+  }
+  if (p2t[size(p2t)-1]=="]")
+  {
+    np2t=np2t+p2t[size(p2t)];
+  }
+  else
+  {
+    if (np2t[size(np2t)]!=";")
+    {
+      np2t=np2t+p2t[size(p2t)-1]+p2t[size(p2t)];
+    }
+  }
+  p2t=np2t;
+  np2t="";
+  // transform the points2triangs output of version 0.14 into Singular format
+  for (i=1;i<=size(p2t);i++)
+  {
+    if (p2t[i]=="=")
+    {
+      np2t=np2t+p2t[i]+"list(";
+      i++;
+    }
+    else
+    {
+      if (p2t[i]!=":")
+      {
+        if ((p2t[i]=="}") and (p2t[i+1]=="}"))
+        {
+          np2t=np2t+"))";
+          i++;
+        }
+        else
+        {
+          if (p2t[i]=="{")
+          {
+            np2t=np2t+"intvec(";
+          }
+          else
+          {
+            if (p2t[i]=="}")
+            {
+              np2t=np2t+")";
+            }
+            else
+            {
+              if (p2t[i]=="[")
+              {
+                // in Topcom version 17.4 (and maybe also in earlier versions) the list
+                // of triangulations is indexed starting with index 0, in Singular
+                // we have to start with index 1
+                np2t=np2t+p2t[i]+"1+";
+              }
+              else
+              {
+                np2t=np2t+p2t[i];
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  list T;
+  execute(np2t);
+  // depending on the version of Topcom, the list T has or has not an entry T[1]
+  // if it has none, the entry should be removed
+  while (typeof(T[1])=="none")
+  {
+    T=delete(T,1);
+  }
+  // raise each index by one
+  for (i=1;i<=size(T);i++)
+  {
+    for (j=1;j<=size(T[i]);j++)
+    {
+      T[i][j]=T[i][j]+1;
+    }
+  }
+  return(T);
+}
+example
+{
+   "EXAMPLE:";
+   echo=2;
+   // the lattice points of the unit square in the plane
+   list polygon=intvec(0,0),intvec(0,1),intvec(1,0),intvec(1,1);
+   // the triangulations of this lattice point configuration are computed
+   list triang=triangulations(polygon);
+   triang;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+proc secondaryPolytope (list polygon,list #)
+"USAGE:  secondaryPolytope(polygon[,#]); list polygon, list #
+ASSUME:  - polygon is a list of integer vectors of the same size representing
+           the affine coordinates of lattice points
+@*       - if the triangulations of the corresponding polygon have already been
+           computed with the procedure triangulations then these can be given as
+           a second (optional) argument in order to avoid doing this computation
+           again
+PURPOSE: the procedure considers the marked polytope given as the convex hull of
+         the lattice points and with these lattice points as markings; it then
+         computes the lattice points of the secondary polytope given by this
+         marked polytope which correspond to the triangulations computed by
+         the procedure triangulations
+RETURN:  list, say L, such that:
+@*             L[1] = intmat, each row gives the affine coordinates of a lattice
+                      point in the secondary polytope given by the marked
+                      polytope corresponding to polygon
+@*             L[2] = the list of corresponding triangulations
+NOTE: if the triangluations are not handed over as optional argument the
+      procedure calls for its computation of these triangulations the program
+      points2triangs from the program topcom by Joerg Rambau, Universitaet
+      Bayreuth; it therefore is necessary that this program is installed in
+      order to use this procedure; see
+@*    http://www.uni-bayreuth.de/departments/wirtschaftsmathematik/rambau/TOPCOM
+EXAMPLE: example secondaryPolytope;   shows an example"
+{
+  // compute the triangulations of the point configuration with points2triangs
+  if (size(#)==0)
+  {
+    list triangs=triangulations(polygon);
+  }
+  else
+  {
+    list triangs=#;
+  }
+  int i,j,k,l;
+  intmat N[2][2]; // is used to compute areas of triangles
+  intvec vertex;  // stores a point in the secondary polytope as
+                  // intermediate result
+  int eintrag;
+  int halt;
+  intmat secpoly[size(triangs)][size(polygon)];   // stores all lattice points
+                                                  // of the secondary polytope
+  // consider each triangulation and compute the corresponding point
+  // in the secondary polytope
+  for (i=1;i<=size(triangs);i++)
+  {
+    // for each triangulation we have to compute the coordinates
+    // corresponding to each marked point
+    for (j=1;j<=size(polygon);j++)
+    {
+      eintrag=0;
+      // for each marked point we have to consider all triangles in the
+      // triangulation which involve this particular point
+      for (k=1;k<=size(triangs[i]);k++)
+      {
+        halt=0;
+        for (l=1;(l<=3) and (halt==0);l++)
+        {
+          if (triangs[i][k][l]==j)
+          {
+            halt=1;
+            N[1,1]=polygon[triangs[i][k][3]][1]-polygon[triangs[i][k][1]][1];
+            N[1,2]=polygon[triangs[i][k][2]][1]-polygon[triangs[i][k][1]][1];
+            N[2,1]=polygon[triangs[i][k][3]][2]-polygon[triangs[i][k][1]][2];
+            N[2,2]=polygon[triangs[i][k][2]][2]-polygon[triangs[i][k][1]][2];
+            eintrag=eintrag+abs(det(N));
+          }
+        }
+      }
+      vertex[j]=eintrag;
+    }
+    secpoly[i,1..size(polygon)]=vertex;
+  }
+  return(list(secpoly,triangs));
+}
+example
+{
+   "EXAMPLE:";
+   echo=2;
+   // the lattice points of the unit square in the plane
+   list polygon=intvec(0,0),intvec(0,1),intvec(1,0),intvec(1,1);
+   // the secondary polytope of this lattice point configuration is computed
+   list secpoly=secondaryPolytope(polygon);
+   // the points in the secondary polytope
+   print(secpoly[1]);
+   // the corresponding triangulations
+   secpoly[2];
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// PROCEDURES USING POLYMAKE AND TOPCOM
+///////////////////////////////////////////////////////////////////////////////
+
+proc secondaryFan (list polygon,list #)
+"USAGE:  secondaryFan(polygon[,#]); list polygon, list #
+ASSUME:  - polygon is a list of integer vectors of the same size representing
+           the affine coordinates of lattice points
+@*       - if the triangulations of the corresponding polygon have already been
+           computed with the procedure triangulations then these can be given
+           as a second (optional) argument in order to avoid doing this
+           computation again
+PURPOSE: the procedure considers the marked polytope given as the convex hull of
+         the lattice points and with these lattice points as markings; it then
+         computes the lattice points of the secondary polytope given by this
+         marked polytope which correspond to the triangulations computed by
+         the procedure triangulations
+RETURN:  list, the ith entry of L[1] contains information about the ith cone in
+               the secondary fan of the polygon, i.e. the cone dual to the
+               ith vertex of the secondary polytope
+@*             L[1][i][1] = integer matrix representing the inequalities which
+                            describe the cone dual to the ith vertex
+@*             L[1][i][2] = a list which contains the inequalities represented
+                            by L[1][i][1] as a list of strings, where we use the
+                            variables x(1),...,x(n)
+@*             L[1][i][3] = only present if 'er' is set to 1; in that case it is
+                            an interger matrix whose rows are the extreme rays
+                            of the cone
+@*             L[2] = is an integer matrix whose rows span the linearity space
+                      of the fan, i.e. the linear space which is contained in
+                      each cone
+@*             L[3] = the secondary polytope in the format of the procedure
+                      polymakePolytope
+@*             L[4] = the list of triangulations corresponding to the vertices
+                      of the secondary polytope
+NOTE:- the procedure calls for its computation polymake by Ewgenij Gawrilow,
+       TU Berlin and Michael Joswig, so it only works if polymake is installed;
+       see http://www.math.tu-berlin.de/polymake/
+@*   - in the optional argument # it is possible to hand over other names for
+       the variables to be used -- be careful, the format must be correct and
+       that is not tested, e.g. if you want the variable names to be
+       u00,u10,u01,u11 then you must hand over the string 'u11,u10,u01,u11'
+@*   - if the triangluations are not handed over as optional argument the
+       procedure calls for its computation of these triangulations the program
+       points2triangs from the program topcom by Joerg Rambau, Universitaet
+       Bayreuth; it therefore is necessary that this program is installed in
+       order to use this procedure; see
+@*     http://www.uni-bayreuth.de/departments/wirtschaftsmathematik/rambau/TOPCOM
+EXAMPLE: example secondaryFan;   shows an example"
+{
+  if (size(#)==0)
+  {
+    list triang=triangulations(polygon);
+  }
+  else
+  {
+    list triang=#[1];
+  }
+  list sp=secondaryPolytope(polygon,triang);
+  list spp=polymakePolytope(sp[1]);
+  list sf=normalFanL(spp[1],spp[4],spp[3],1);
+  return(list(sf[1],sf[2],spp,triang));
+}
+example
+{
+   "EXAMPLE:";
+   echo=2;
+   // the lattice points of the unit square in the plane
+   list polygon=intvec(0,0),intvec(0,1),intvec(1,0),intvec(1,1);
+   // the secondary polytope of this lattice point configuration is computed
+   list secfan=secondaryFan(polygon);
+   // the number of cones in the secondary fan of the polygon
+   size(secfan[1]);
+   // the inequalities of the first cone as matrix are:
+   print(secfan[1][1][1]);
+   // the inequalities of the first cone as string are:
+   print(secfan[1][1][2]);
+   // the rows of the following matrix are the extreme rays of the first cone:
+   print(secfan[1][1][3]);
+   // each cone contains the linearity space spanned by:
+   print(secfan[2]);
+   // the points in the secondary polytope
+   print(secfan[3][1]);
+   // the corresponding triangulations
+   secfan[4];
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+/// PROCEDURES CONCERNED WITH PLANAR POLYGONS
+////////////////////////////////////////////////////////////////////////////////
+
+proc cycleLength (list boundary,intvec interior)
+"USAGE:  cycleLength(boundary,interior); list boundary, intvec interior
+ASSUME:  boundary is a list of integer vectors describing a cycle in some
+         convex lattice polygon around the lattice point interior ordered
+         clock wise
+RETURN:  string, the cycle length of the corresponding cycle in the dual
+                 tropical curve
+EXAMPLE: example cycleLength;   shows an example"
+{
+  int j;
+  // create a ring whose variables are indexed by the points in
+  // boundary resp. by interior
+  string rst="ring cyclering=0,(u"+string(interior[1])+string(interior[2]);
+  for (j=1;j<=size(boundary);j++)
+  {
+    rst=rst+",u"+string(boundary[j][1])+string(boundary[j][2]);
+  }
+  rst=rst+"),lp;";
+  execute(rst);
+  // add the first and second point at the end of boundary
+  boundary[size(boundary)+1]=boundary[1];
+  boundary[size(boundary)+1]=boundary[2];
+  poly cl,summand; // takes the cycle length
+  matrix N1[2][2]; // used to compute the area of a triangle
+  matrix N2[2][2]; // used to compute the area of a triangle
+  matrix N3[2][2]; // used to compute the area of a triangle
+  // for each original point in boundary compute its contribution to the cycle
+  for (j=2;j<=size(boundary)-1;j++)
+  {
+    N1=boundary[j-1]-interior,boundary[j]-interior;
+    N2=boundary[j]-interior,boundary[j+1]-interior;
+    N3=boundary[j+1]-interior,boundary[j-1]-interior;
+    execute("summand=-u"+string(boundary[j][1])+string(boundary[j][2])+"+u"+string(interior[1])+string(interior[2])+";");
+    summand=summand*(det(N1)+det(N2)+det(N3))/(det(N1)*det(N2));
+    cl=cl+summand;
+  }
+  return(string(cl));
+}
+example
+{
+   "EXAMPLE:";
+   echo=2;
+   // the integer vectors in boundary are lattice points on the boundary
+   // of a convex lattice polygon in the plane
+   list boundary=intvec(0,0),intvec(0,1),intvec(0,2),intvec(2,2),
+                 intvec(2,1),intvec(2,0);
+   // interior is a lattice point in the interior of this lattice polygon
+   intvec interior=1,1;
+   // compute the general cycle length of a cycle of the corresponding cycle
+   // in the dual tropical curve, note that (0,1) and (2,1) do not contribute
+   cycleLength(boundary,interior);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+proc splitPolygon (list markings)
+"USAGE:  splitPolygon (markings);  markings list
+ASSUME:  markings is a list of integer vectors representing lattice points in
+         the plane which we consider as the marked points of the convex lattice
+         polytope spanned by them
+PURPOSE: split the marked points in the vertices, the points on the facets
+         which are not vertices, and the interior points
+RETURN:  list, L consisting of three lists
+@*             L[1]    : represents the vertices the polygon ordered clockwise
+@*                       L[1][i][1] = intvec, the coordinates of the ith vertex
+@*                       L[1][i][2] = int, the position of L[1][i][1] in markings
+@*             L[2][i] : represents the lattice points on the facet of the
+                         polygon with endpoints L[1][i] and L[1][i+1]
+                         (i considered modulo size(L[1]))
+@*                       L[2][i][j][1] = intvec, the coordinates of the jth
+                                                 lattice point on that facet
+@*                       L[2][i][j][2] = int, the position of L[2][i][j][1]
+                                              in markings
+@*             L[3]    : represents the interior lattice points of the polygon
+@*                       L[3][i][1] = intvec, coordinates of ith interior point
+@*                       L[3][i][2] = int, the position of L[3][i][1] in markings
+EXAMPLE: example splitPolygon;   shows an example"
+{
+  list vert; // stores the result
+  // compute the boundary of the polygon in an oriented way
+  list pb=findOrientedBoundary(markings);
+  // the vertices are just the second entry of pb
+  vert[1]=pb[2];
+  int i,j,k;      // indices
+  list boundary;  // stores the points on the facets of the
+                  // polygon which are not vertices
+  // append to the boundary points as well as to the vertices
+  // the first vertex a second time
+  pb[1]=pb[1]+list(pb[1][1]);
+  pb[2]=pb[2]+list(pb[2][1]);
+  // for each vertex find all points on the facet of the polygon with this vertex
+  // and the next vertex as endpoints
+  int z=2;
+  for (i=1;i<=size(vert[1]);i++)
+  {
+    j=1;
+    list facet; // stores the points on this facet which are not vertices
+    // while the next vertex is not reached, store the boundary lattice point
+    while (pb[1][z]!=pb[2][i+1])
+    {
+      facet[j]=pb[1][z];
+      j++;
+      z++;
+    }
+    // store the points on the ith facet as boundary[i]
+    boundary[i]=facet;
+    kill facet;
+    z++;
+  }
+  // store the information on the boundary in vert[2]
+  vert[2]=boundary;
+  // find the remaining points in the input which are not on
+  // the boundary by checking
+  // for each point in markings if it is contained in pb[1]
+  list interior=markings;
+  for (i=size(interior);i>=1;i--)
+  {
+    for (j=1;j<=size(pb[1])-1;j++)
+    {
+      if (interior[i]==pb[1][j])
+      {
+        interior=delete(interior,i);
+        j=size(pb[1]);
+      }
+    }
+  }
+  // store the interior points in vert[3]
+  vert[3]=interior;
+  // add to each point in vert the index which it gets from
+  // its position in the input markings;
+  // do so for ver[1]
+  for (i=1;i<=size(vert[1]);i++)
+  {
+    j=1;
+    while (markings[j]!=vert[1][i])
+    {
+      j++;
+    }
+    vert[1][i]=list(vert[1][i],j);
+  }
+  // do so for ver[2]
+  for (i=1;i<=size(vert[2]);i++)
+  {
+    for (k=1;k<=size(vert[2][i]);k++)
+    {
+      j=1;
+      while (markings[j]!=vert[2][i][k])
+      {
+        j++;
+      }
+      vert[2][i][k]=list(vert[2][i][k],j);
+    }
+  }
+  // do so for ver[3]
+  for (i=1;i<=size(vert[3]);i++)
+  {
+    j=1;
+    while (markings[j]!=vert[3][i])
+    {
+      j++;
+    }
+    vert[3][i]=list(vert[3][i],j);
+  }
+  return(vert);
+}
+example
+{
+   "EXAMPLE:";
+   echo=2;
+   // the lattice polygon spanned by the points (0,0), (3,0) and (0,3)
+   // with all integer points as markings
+   list polygon=intvec(1,1),intvec(3,0),intvec(2,0),intvec(1,0),
+                intvec(0,0),intvec(2,1),intvec(0,1),intvec(1,2),
+                intvec(0,2),intvec(0,3);
+   // split the polygon in its vertices, its facets and its interior points
+   list sp=splitPolygon(polygon);
+   // the vertices
+   sp[1];
+   // the points on facets which are not vertices
+   sp[2];
+   // the interior points
+   sp[3];
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+
+proc eta (list triang,list polygon)
+"USAGE:  eta(triang,polygon);  triang, polygon list
+ASSUME:  polygon has the format of the output of splitPolygon, i.e. it is a
+         list with three entries describing a convex lattice polygon in the
+         following way:
+@*       polygon[1] : is a list of lists; for each i the entry polygon[1][i][1]
+                      is a lattice point which is a vertex of the lattice
+                      polygon, and polygon[1][i][2] is an integer assigned to
+                      this lattice point as identifying index
+@*       polygon[2] : is a list of lists; for each vertex of the polygon,
+                      i.e. for each entry in polygon[1], it contains a list
+                      polygon[2][i], which contains the lattice points on the
+                      facet with endpoints polygon[1][i] and polygon[1][i+1]
+                      - i considered mod size(polygon[1]);
+                      each such lattice point contributes an entry
+                      polygon[2][i][j][1] which is an integer
+                      vector giving the coordinate of the lattice point and an
+                      entry polygon[2][i][j][2] which is the identifying index
+@*       polygon[3] : is a list of lists, where each entry corresponds to a
+                      lattice point in the interior of the polygon, with
+                      polygon[3][j][1] being the coordinates of the point
+                      and polygon[3][j][2] being the identifying index;
+@*       triang is a list of integer vectors all of size three describing a
+         triangulation of the polygon described by polygon; if an entry of
+         triang is the vector (i,j,k) then the triangle is built by the vertices
+         with indices i, j and k
+RETURN:  intvec, the integer vector eta describing that vertex of the Newton
+                 polytope discriminant of the polygone whose dual cone in the
+                 Groebner fan contains the cone of the secondary fan of the
+                 polygon corresponding to the given triangulation
+NOTE:  for a better description of eta see Gelfand, Kapranov,
+       Zelevinski: Discriminants, Resultants and multidimensional Determinants.
+       Chapter 10.
+EXAMPLE: example eta;   shows an example"
+{
+  int i,j,k,l,m,n; // index variables
+  list ordpolygon;   // stores the lattice points in the order
+                     // used in the triangulation
+  list triangarea; // stores the areas of the triangulations
+  intmat N[2][2];  // used to compute triangle areas
+  // 1) store the lattice points in the order used in the triangulation
+  // go first through all vertices of the polytope
+  for (j=1;j<=size(polygon[1]);j++)
+  {
+    ordpolygon[polygon[1][j][2]]=polygon[1][j][1];
+  }
+  // then consider all inner points
+  for (j=1;j<=size(polygon[3]);j++)
+  {
+    ordpolygon[polygon[3][j][2]]=polygon[3][j][1];
+  }
+  // finally consider all lattice points on the boundary which are not vertices
+  for (j=1;j<=size(polygon[2]);j++)
+  {
+    for (i=1;i<=size(polygon[2][j]);i++)
+    {
+      ordpolygon[polygon[2][j][i][2]]=polygon[2][j][i][1];
+    }
+  }
+  // 2) compute for each triangle in the triangulation the area of the triangle
+  for (i=1;i<=size(triang);i++)
+  {
+    // Note that the ith lattice point in orderedpolygon has the
+    // number i-1 in the triangulation!
+    N=ordpolygon[triang[i][1]]-ordpolygon[triang[i][2]],ordpolygon[triang[i][1]]-ordpolygon[triang[i][3]];
+    triangarea[i]=abs(det(N));
+  }
+  intvec ETA;        // stores the eta_ij
+  int etaij;         // stores the part of eta_ij during computations
+                     // which comes from triangle areas
+  int seitenlaenge;  // stores the part of eta_ij during computations
+                     // which comes from boundary facets
+  list seiten;       // stores the lattice points on facets of the polygon
+  intvec v;          // used to compute a facet length
+  // 3) store first in seiten[i] all lattice points on the facet
+  //    connecting the ith vertex,
+  //    i.e. polygon[1][i], with the i+1st vertex, i.e. polygon[1][i+1],
+  //    where we replace i+1
+  //    1 if i=size(polygon[1]);
+  //    then append the last entry of seiten once more at the very
+  //    beginning of seiten, so
+  //    that the index is shifted by one
+  for (i=1;i<=size(polygon[1]);i++)
+  {
+    if (i<size(polygon[1]))
+    {
+      seiten[i]=list(polygon[1][i])+polygon[2][i]+list(polygon[1][i+1]);
+    }
+    else
+    {
+      seiten[i]=list(polygon[1][i])+polygon[2][i]+list(polygon[1][1]);
+    }
+  }
+  seiten=insert(seiten,seiten[size(seiten)],0);
+  // 4) compute the eta_ij for all vertices of the polygon
+  for (j=1;j<=size(polygon[1]);j++)
+  {
+    // the vertex itself contributes a 1
+    etaij=1;
+    // check for each triangle in the triangulation ...
+    for (k=1;k<=size(triang);k++)
+    {
+      // ... if the vertex is actually a vertex of the triangle ...
+      if ((polygon[1][j][2]==triang[k][1]) or (polygon[1][j][2]==triang[k][2]) or (polygon[1][j][2]==triang[k][3]))
+      {
+        // ... if so, add the area of the triangle to etaij
+        etaij=etaij+triangarea[k];
+        // then check if that triangle has a facet which is contained
+        // in one of the
+        // two facets of the polygon which are adjecent to the given vertex ...
+        // these two facets are seiten[j] and seiten[j+1]
+        for (n=j;n<=j+1;n++)
+        {
+          // check for each lattice point in the facet of the polygon ...
+          for (l=1;l<=size(seiten[n]);l++)
+          {
+            // ... and for each lattice point in the triangle ...
+            for (m=1;m<=size(triang[k]);m++)
+            {
+              // ... if they coincide and are not the vertex itself ...
+              if ((seiten[n][l][2]==triang[k][m]) and (seiten[n][l][2]!=polygon[1][j][2]))
+              {
+                // if so, then compute the vector pointing from this
+                // lattice point to the vertex
+                v=polygon[1][j][1]-seiten[n][l][1];
+                // and the lattice length of this vector has to be
+                // subtracted from etaij
+                etaij=etaij-abs(gcd(v[1],v[2]));
+              }
+            }
+          }
+        }
+      }
+    }
+    // store etaij in the list
+    ETA[polygon[1][j][2]]=etaij;
+  }
+  // 5) compute the eta_ij for all lattice points on the facets
+  //    of the polygon which are not vertices, these are the
+  //    lattice points in polygon[2][1] to polygon[2][size(polygon[1])]
+  for (i=1;i<=size(polygon[2]);i++)
+  {
+    for (j=1;j<=size(polygon[2][i]);j++)
+    {
+      // initialise etaij
+      etaij=0;
+      // initialise seitenlaenge
+      seitenlaenge=0;
+      // check for each triangle in the triangulation ...
+      for (k=1;k<=size(triang);k++)
+      {
+        // ... if the vertex is actually a vertex of the triangle ...
+        if ((polygon[2][i][j][2]==triang[k][1]) or (polygon[2][i][j][2]==triang[k][2]) or (polygon[2][i][j][2]==triang[k][3]))
+        {
+          // ... if so, add the area of the triangle to etaij
+          etaij=etaij+triangarea[k];
+          // then check if that triangle has a facet which is contained in the
+          // facet of the polygon which contains the lattice point in question,
+          // this is the facet seiten[i+1];
+          // check for each lattice point in the facet of the polygon ...
+          for (l=1;l<=size(seiten[i+1]);l++)
+          {
+            // ... and for each lattice point in the triangle ...
+            for (m=1;m<=size(triang[k]);m++)
+            {
+              // ... if they coincide and are not the vertex itself ...
+              if ((seiten[i+1][l][2]==triang[k][m]) and (seiten[i+1][l][2]!=polygon[2][i][j][2]))
+              {
+                // if so, then compute the vector pointing from
+                // this lattice point to the vertex
+                v=polygon[2][i][j][1]-seiten[i+1][l][1];
+                // and the lattice length of this vector contributes
+                // to seitenlaenge
+                seitenlaenge=seitenlaenge+abs(gcd(v[1],v[2]));
+              }
+            }
+          }
+        }
+      }
+      // if the lattice point was a vertex of any triangle
+      // in the triangulation ...
+      if (etaij!=0)
+      {
+        // then eta_ij is the sum of the triangle areas minus seitenlaenge
+        ETA[polygon[2][i][j][2]]=etaij-seitenlaenge;
+      }
+      else
+      {
+        // otherwise it is just zero
+        ETA[polygon[2][i][j][2]]=0;
+      }
+    }
+  }
+  // 4) compute the eta_ij for all inner lattice points of the polygon
+  for (j=1;j<=size(polygon[3]);j++)
+  {
+    // initialise etaij
+    etaij=0;
+    // check for each triangle in the triangulation ...
+    for (k=1;k<=size(triang);k++)
+    {
+      // ... if the vertex is actually a vertex of the triangle ...
+      if ((polygon[3][j][2]==triang[k][1]) or (polygon[3][j][2]==triang[k][2]) or (polygon[3][j][2]==triang[k][3]))
+      {
+        // ... if so, add the area of the triangle to etaij
+        etaij=etaij+triangarea[k];
+      }
+    }
+    // store etaij in ETA
+    ETA[polygon[3][j][2]]=etaij;
+  }
+  return(ETA);
+}
+example
+{
+   "EXAMPLE:";
+   echo=2;
+   // the lattice polygon spanned by the points (0,0), (3,0) and (0,3)
+   // with all integer points as markings
+   list polygon=intvec(1,1),intvec(3,0),intvec(2,0),intvec(1,0),
+                intvec(0,0),intvec(2,1),intvec(0,1),intvec(1,2),
+                intvec(0,2),intvec(0,3);
+   // split the polygon in its vertices, its facets and its interior points
+   list sp=splitPolygon(polygon);
+   // define a triangulation by connecting the only interior point
+   //        with the vertices
+   list triang=intvec(1,2,5),intvec(1,5,10),intvec(1,5,10);
+   // compute the eta-vector of this triangulation
+   eta(triang,sp);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+proc findOrientedBoundary (list polygon)
+"USAGE: findOrientedBoundary(polygon); polygon list
+ASSUME: polygon is a list of integer vectors defining integer lattice points
+        in the plane
+RETURN: list l with the following interpretation
+@*            l[1] = list of integer vectors such that the polygonal path
+                     defined by these is the boundary of the convex hull of
+                     the lattice points in polygon
+@*            l[2] = list, the redundant points in l[1] have been removed
+EXAMPLE:     example findOrientedBoundary;   shows an example"
+{
+  // Order the vertices such that passing from one to the next we travel along
+  // the boundary of the convex hull of the vertices clock wise
+  int d,k,i,j;
+  intmat D[2][2];
+  /////////////////////////////////////
+  // Treat first the pathological cases that the polygon is not two-dimensional:
+  /////////////////////////////////////
+  // if the polygon is empty or only one point or a line segment of two points
+  if (size(polygon)<=2)
+  {
+    return(list(polygon,polygon));
+  }
+  // check is the polygon is only a line segment given by more than two points;
+  // for this first compute sum of the absolute values of the determinants
+  // of the matrices whose
+  // rows are the vectors pointing from the first to the second point
+  // and from the
+  // the first point to the ith point for i=3,...,size(polygon);
+  // if this sum is zero
+  // then the polygon is a line segment and we have to find its end points
+  d=0;
+  for (i=3;i<=size(polygon);i++)
+  {
+    D=polygon[2]-polygon[1],polygon[i]-polygon[1];
+    d=d+abs(det(D));
+  }
+  if (d==0) // then polygon is a line segment
+  {
+    intmat laenge[size(polygon)][size(polygon)];
+    intvec mp;
+    //   for this collect first all vectors pointing from one lattice
+    //   point to the next,
+    //   compute their pairwise angles and their lengths
+    for (i=1;i<=size(polygon)-1;i++)
+    {
+      for (j=i+1;j<=size(polygon);j++)
+      {
+        mp=polygon[i]-polygon[j];
+        laenge[i,j]=abs(gcd(mp[1],mp[2]));
+      }
+    }
+    mp=maxPosInIntmat(laenge);
+    list endpoints=polygon[mp[1]],polygon[mp[2]];
+    intvec abstand;
+    for (i=1;i<=size(polygon);i++)
+    {
+      abstand[i]=0;
+      if (i<mp[1])
+      {
+        abstand[i]=laenge[i,mp[1]];
+      }
+      if (i>mp[1])
+      {
+        abstand[i]=laenge[mp[1],i];
+      }
+    }
+    polygon=sortlistbyintvec(polygon,abstand);
+    return(list(polygon,endpoints));
+  }
+  ///////////////////////////////////////////////////////////////
+  list orderedvertices;  // stores the vertices in an ordered way
+  list minimisedorderedvertices;  // stores the vertices in an ordered way;
+                                  // redundant ones removed
+  list comparevertices; // stores vertices which should be compared to
+                        // the testvertex
+  orderedvertices[1]=polygon[1]; // set the starting vertex
+  minimisedorderedvertices[1]=polygon[1]; // set the starting vertex
+  intvec testvertex=polygon[1];  //vertex to which the others have to be compared
+  intvec startvertex=polygon[1]; // keep the starting vertex to test,
+                                 // when the end is reached
+  int endtest;                   // is set to one, when the end is reached
+  int startvertexfound;// is 1, once for some testvertex a candidate
+                       // for the next vertex has been found
+  polygon=delete(polygon,1);    // delete the testvertex
+  intvec v,w;
+  int l=1;  // counts the vertices
+  // the basic idea is that a vertex can be
+  // the next one on the boundary if all other vertices
+  // lie to the right of the vector v pointing
+  // from the testvertex to this one; this can be tested
+  // by checking if the determinant of the 2x2-matrix
+  // with first column v and second column the vector w,
+  // pointing from the testvertex to the new vertex,
+  // is non-positive; if this is the case for all
+  // new vertices, then the one in consideration is
+  // a possible choice for the next vertex on the boundary
+  // and it is stored in naechste; we can then order
+  // the candidates according to their distance from
+  // the testvertex; then they occur on the boundary in that order!
+  while (endtest==0)
+  {
+    list naechste;  // stores the possible choices for the next vertex
+    k=1;
+    for (i=1;i<=size(polygon);i++)
+    {
+      d=0;  // stores the value of the determinant of (v,w)
+      v=polygon[i]-testvertex; // points from the testvertex to the ith vertex
+      comparevertices=delete(polygon,i); // we needn't compare v to itself
+      // we should compare v to the startvertex-testvertex;
+      // in the first calling of the loop
+      // this is irrelevant since the difference will be zero;
+      // however, later on it will
+      // be vital, since we delete the vertices
+      // which we have already tested from the list
+      // of all vertices, and when all vertices
+      // on the boundary have been found we would
+      // therefore find a vertex in the interior
+      // as candidate; but always testing against
+      // the starting vertex, this cannot happen
+      comparevertices[size(comparevertices)+1]=startvertex;
+      for (j=1;(j<=size(comparevertices)) and (d<=0);j++)
+      {
+        w=comparevertices[j]-testvertex; // points form the testvertex
+                                         // to the jth vertex
+        D=v,w;
+        d=det(D);
+      }
+      if (d<=0) // if all determinants are non-positive,
+      { // then the ith vertex is a candidate
+        naechste[k]=list(polygon[i],i,scalarproduct(v,v));// we store the vertex,
+                                                          //its position, and its
+        k++; // distance from the testvertex
+      }
+    }
+    if (size(naechste)>0) // then a candidate for the next vertex has been found
+    {
+      startvertexfound=1; // at least once a candidate has been found
+      naechste=sortlist(naechste,3);  // we order the candidates according
+                                      // to their distance from testvertex;
+      for (j=1;j<=size(naechste);j++) // then we store them in this
+      { // order in orderedvertices
+        l++;
+        orderedvertices[l]=naechste[j][1];
+      }
+      testvertex=naechste[size(naechste)][1];  // we store the last one as
+                                               // next testvertex;
+      // store the next corner of NSD
+      minimisedorderedvertices[size(minimisedorderedvertices)+1]=testvertex;
+      naechste=sortlist(naechste,2); // then we reorder the vertices
+                                     // according to their position
+      for (j=size(naechste);j>=1;j--) // and we delete them from the vertices
+      {
+        polygon=delete(polygon,naechste[j][2]);
+      }
+    }
+    else // that means either that the vertex was inside the polygon,
+    {    // or that we have reached the last vertex on the boundary
+         // of the polytope
+      if (startvertexfound==0) // the vertex was in the interior;
+      { // we delete it and start all over again
+        orderedvertices[1]=polygon[1];
+        minimisedorderedvertices[1]=polygon[1];
+        testvertex=polygon[1];
+        startvertex=polygon[1];
+        polygon=delete(polygon,1);
+      }
+      else // we have reached the last vertex on the boundary of
+      { // the polytope and can stop
+        endtest=1;
+      }
+    }
+    kill naechste;
+  }
+  // test if the first vertex in minimisedorderedvertices
+  // is on the same line with the second and
+  // the last, i.e. if we started our search in the
+  // middle of a face; if so, delete it
+  v=minimisedorderedvertices[2]-minimisedorderedvertices[1];
+  w=minimisedorderedvertices[size(minimisedorderedvertices)]-minimisedorderedvertices[1];
+  D=v,w;
+  if (det(D)==0)
+  {
+    minimisedorderedvertices=delete(minimisedorderedvertices,1);
+  }
+  // test if the first vertex in minimisedorderedvertices
+  // is on the same line with the two
+  // last ones, i.e. if we started our search at the end of a face;
+  // if so, delete it
+  v=minimisedorderedvertices[size(minimisedorderedvertices)-1]-minimisedorderedvertices[1];
+  w=minimisedorderedvertices[size(minimisedorderedvertices)]-minimisedorderedvertices[1];
+  D=v,w;
+  if (det(D)==0)
+  {
+    minimisedorderedvertices=delete(minimisedorderedvertices,size(minimisedorderedvertices));
+  }
+  return(list(orderedvertices,minimisedorderedvertices));
+}
+example
+{
+   "EXAMPLE:";
+   echo=2;
+// the following lattice points in the plane define a polygon
+   list polygon=intvec(0,0),intvec(3,1),intvec(1,0),intvec(2,0),
+                intvec(1,1),intvec(3,2),intvec(1,2),intvec(2,3),
+                intvec(2,4);
+// we compute its boundary
+   list boundarypolygon=findOrientedBoundary(polygon);
+// the points on the boundary ordered clockwise are boundarypolygon[1]
+   boundarypolygon[1];
+// the vertices of the boundary are boundarypolygon[2]
+   boundarypolygon[2];
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+
+proc cyclePoints (list triang,list points,int pt)
+"USAGE:      cyclePoints(triang,points,pt)  triang,points list, pt int
+ASSUME:      - points is a list of integer vectors describing the lattice
+               points of a marked polygon;
+@*           - triang is a list of integer vectors describing a triangulation
+               of the marked polygon in the sense that an integer vector of
+               the form (i,j,k) describes the triangle formed by polygon[i],
+               polygon[j] and polygon[k];
+@*           - pt is an integer between 1 and size(points), singling out a
+               lattice point among the marked points
+PURPOSE:     consider the convex lattice polygon, say P, spanned by all lattice
+             points in points which in the triangulation triang are connected
+             to the point points[pt]; the procedure computes all marked points
+             in points which lie on the boundary of that polygon, ordered
+             clockwise
+RETURN:      list, of integer vectors which are the coordinates of the lattice
+                   points on the boundary of the above mentioned polygon P, if
+                   this polygon is not the empty set (that would be the case if
+                   points[pt] is not a vertex of any triangle in the
+                   triangulation); otherwise return the empty list
+EXAMPLE:     example cyclePoints;   shows an example"
+{
+  int i,j; // indices
+  list v;  // saves the indices of lattice points connected to the
+           // interior point in the triangulation
+  // save all points in triangulations containing pt in v
+  for (i=1;i<=size(triang);i++)
+  {
+    if ((triang[i][1]==pt) or (triang[i][2]==pt) or (triang[i][3]==pt))
+    {
+      j++;
+      v[3*j-2]=triang[i][1];
+      v[3*j-1]=triang[i][2];
+      v[3*j]=triang[i][3];
+    }
+  }
+  if (size(v)==0)
+  {
+    return(list());
+  }
+  // remove pt itself and redundancies in v
+  for (i=size(v);i>=1;i--)
+  {
+    j=1;
+    while ((j<i) and (v[i]!=v[j]))
+    {
+      j++;
+    }
+    if ((j<i) or (v[i]==pt))
+    {
+      v=delete(v,i);
+    }
+  }
+  // save in pts the coordinates of the points with indices in v
+  list pts;
+  for (i=1;i<=size(v);i++)
+  {
+    pts[i]=points[v[i]];
+  }
+  // consider the convex polytope spanned by the points in pts,
+  // find the points on the
+  // boundary and order them clockwise
+  return(findOrientedBoundary(pts)[1]);
+}
+example
+{
+   "EXAMPLE:";
+   echo=2;
+   // the lattice polygon spanned by the points (0,0), (3,0) and (0,3)
+   // with all integer points as markings
+   list points=intvec(1,1),intvec(3,0),intvec(2,0),intvec(1,0),
+               intvec(0,0),intvec(2,1),intvec(0,1),intvec(1,2),
+               intvec(0,2),intvec(0,3);
+   // define a triangulation
+   list triang=intvec(1,2,5),intvec(1,5,7),intvec(1,7,9),intvec(8,9,10),
+               intvec(1,8,9),intvec(1,2,8);
+   // compute the points connected to (1,1) in triang
+   cyclePoints(triang,points,1);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+proc latticeArea (list polygon)
+"USAGE:  latticeArea(polygon);   polygon list
+ASSUME:  polygon is a list of integer vectors in the plane
+RETURN:  int, the lattice area of the convex hull of the lattice points in
+              polygon, i.e. twice the Euclidean area
+EXAMPLE: example polygonlatticeArea;   shows an example"
+{
+  list pg=findOrientedBoundary(polygon)[2];
+  int area;
+  intmat M[2][2];
+  for (int i=2;i<=size(pg)-1;i++)
+  {
+    M[1,1..2]=pg[i]-pg[1];
+    M[2,1..2]=pg[i+1]-pg[1];
+    area=area+abs(det(M));
+  }
+  return(area);
+}
+example
+{
+   "EXAMPLE:";
+   echo=2;
+   // define a polygon with lattice area 5
+   list polygon=intvec(1,2),intvec(1,0),intvec(2,0),intvec(1,1),
+                intvec(2,1),intvec(0,0);
+   latticeArea(polygon);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+proc picksFormula (list polygon)
+"USAGE:  picksFormula(polygon);   polygon list
+ASSUME:  polygon is a list of integer vectors in the plane and consider their
+         convex hull C
+RETURN:  list, L of three integersthe
+@*             L[1] : the lattice area of C, i.e. twice the Euclidean area
+@*             L[2] : the number of lattice points on the boundary of C
+@*             L[3] : the number of interior lattice points of C
+NOTE: the integers in L are related by Pick's formula, namely: L[1]=L[2]+2*L[3]-2
+EXAMPLE: example picksFormula;   shows an example"
+{
+  list pg=findOrientedBoundary(polygon)[2];
+  int area,bdpts,i;
+  intmat M[2][2];
+  // compute the lattice area of the polygon, i.e. twice the Euclidean area
+  for (i=2;i<=size(pg)-1;i++)
+  {
+    M[1,1..2]=pg[i]-pg[1];
+    M[2,1..2]=pg[i+1]-pg[1];
+    area=area+abs(det(M));
+  }
+  // compute the number of lattice points on the boundary
+  intvec edge;
+  pg[size(pg)+1]=pg[1];
+  for (i=1;i<=size(pg)-1;i++)
+  {
+    edge=pg[i]-pg[i+1];
+    bdpts=bdpts+abs(gcd(edge[1],edge[2]));
+  }
+  // Pick's formula says that the lattice area A, the number g of interior
+  // points and
+  // the number b of boundary points are connected by the formula: A=b+2g-2
+  return(list(area,bdpts,(area-bdpts+2) div 2));
+}
+example
+{
+   "EXAMPLE:";
+   echo=2;
+   // define a polygon with lattice area 5
+   list polygon=intvec(1,2),intvec(1,0),intvec(2,0),intvec(1,1),
+                intvec(2,1),intvec(0,0);
+   list pick=picksFormula(polygon);
+   // the lattice area of the polygon is:
+   pick[1];
+   // the number of lattice points on the boundary is:
+   pick[2];
+   // the number of interior lattice points is:
+   pick[3];
+   // the number's are related by Pick's formula:
+   pick[1]-pick[2]-2*pick[3]+2;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+proc ellipticNF (list polygon)
+"USAGE:  ellipticNF(polygon);   polygon list
+ASSUME:  polygon is a list of integer vectors in the plane such that their
+         convex hull C has precisely one interior lattice point; i.e. C is the
+         Newton polygon of an elliptic curve
+PURPOSE: compute the normal form of the polygon with respect to the unimodular
+         affine transformations T=A*x+v; there are sixteen different normal forms
+         (see e.g. Bjorn Poonen, Fernando Rodriguez-Villegas: Lattice Polygons
+                   and the number 12.  Amer. Math. Monthly  107  (2000),  no. 3,
+                   238--250.)
+RETURN:  list, L such that
+@*             L[1] : list whose entries are the vertices of the normal form of
+                      the polygon
+@*             L[2] : the matrix A of the unimodular transformation
+@*             L[3] : the translation vector v of the unimodular transformation
+@*             L[4] : list such that the ith entry is the image of polygon[i]
+                      under the unimodular transformation T
+EXAMPLE: example ellipticNF;   shows an example"
+{
+  int i;            // index
+  intvec edge;      // stores the vector of an edge
+  intvec boundary;  // stores lattice lengths of the edges of the Newton cycle
+  // find the vertices of the Newton cycle and order it clockwise
+  list pg=findOrientedBoundary(polygon)[2];
+  // check if there is precisely one interior point in the Newton polygon
+  if (picksFormula(pg)[3]!=1)
+  {
+    ERROR("The polygon has not precisely one interior point!");
+  }
+  // insert the first vertex at the end once again
+  pg[size(pg)+1]=pg[1];
+  // compute the number of lattice points on each edge
+  for (i=1;i<=size(pg)-1;i++)
+  {
+    edge=pg[i]-pg[i+1];
+    boundary[i]=1+abs(gcd(edge[1],edge[2]));
+  }
+  // store the values of boundary once more adding the first two at the end
+  intvec tboundary=boundary,boundary[1],boundary[2];
+  // sort boundary in an asecending way
+  intvec sbd=sortintvec(boundary);
+  // find the first edge having the maximal number of lattice points
+  int max=maxPosInIntvec(boundary);
+  // some computations have to be done over the rationals
+  ring transformationring=0,x,lp;
+  intvec trans;    // stores the vector by which we have to translate the polygon
+  intmat A[2][2];  // stores the matrix by which we have to transform the polygon
+  matrix M[3][3];  // stores the projective coordinates of the points
+                   // which are to be transformed
+  matrix N[3][3];  // stores the projective coordinates of the points to
+                   // which M is to be transformed
+  intmat T[3][3];  // stores the unimodular affine transformation in
+                   // projective form
+  // add the second point of pg once again at the end
+  pg=insert(pg,pg[2],size(pg));
+  // if there is only one edge which has the maximal number of lattice points,
+  // then M should be:
+  M=pg[max],1,pg[max+1],1,pg[max+2],1;
+  // consider the 16 different cases which can occur:
+  // Case 1:
+  if (sbd==intvec(2,2,2))
+  {
+    N=0,1,1,1,2,1,2,0,1;
+  }
+  // Case 2:
+  if (sbd==intvec(2,2,3))
+  {
+    N=2,0,1,0,0,1,1,2,1;
+  }
+  // Case 3:
+  if (sbd==intvec(2,3,4))
+  {
+    // here the orientation of the Newton polygon is important !
+    if (tboundary[max+1]==3)
+    {
+      N=3,0,1,0,0,1,0,2,1;
+    }
+    else
+    {
+      N=0,0,1,3,0,1,0,2,1;
+    }
+  }
+  // Case 4:
+  if (sbd==intvec(3,3,5))
+  {
+    N=4,0,1,0,0,1,0,2,1;
+  }
+  // Case 5:
+  if (sbd==intvec(4,4,4))
+  {
+    N=3,0,1,0,0,1,0,3,1;
+  }
+  // Case 6+7:
+  if (sbd==intvec(2,2,2,2))
+  {
+    // there are two different polygons which has four edges all of length 2,
+    // but only one of them has two edges whose direction vectors form a matrix
+    // of determinant 3
+    A=pg[1]-pg[2],pg[3]-pg[2];
+    while ((max<4) and (det(A)!=3))
+    {
+      max++;
+      A=pg[max]-pg[max+1],pg[max+2]-pg[max+1];
+    }
+    // Case 6:
+    if (det(A)==3)
+    {
+      M=pg[max],1,pg[max+1],1,pg[max+2],1;
+      N=1,0,1,0,2,1,2,1,1;
+    }
+    // Case 7:
+    else
+    {
+      N=2,1,1,1,0,1,0,1,1;
+    }
+  }
+  // Case 8:
+  if (sbd==intvec(2,2,2,3))
+  {
+    // the orientation of the polygon is important
+    A=pg[max]-pg[max+1],pg[max+2]-pg[max+1];
+    if (det(A)==2)
+    {
+      N=2,0,1,0,0,1,0,1,1;
+    }
+    else
+    {
+      N=0,0,1,2,0,1,1,2,1;
+    }
+  }
+  // Case 9:
+  if (sbd==intvec(2,2,3,3))
+  {
+    // if max==1, then the 5th entry in tboundary is the same as the first
+    if (max==1)
+    {
+      max=5;
+    }
+    // if boundary=3,2,2,3 then set max=4
+    if (tboundary[max+1]!=3)
+    {
+      max=4;
+    }
+    M=pg[max],1,pg[max+1],1,pg[max+2],1;
+    // the orientation of the polygon matters
+    A=pg[max-1]-pg[max],pg[max+1]-pg[max];
+    if (det(A)==4)
+    {
+      N=2,0,1,0,0,1,0,2,1;
+    }
+    else
+    {
+      N=0,2,1,0,0,1,2,0,1;
+    }
+  }
+  // Case 10:
+  if (sbd==intvec(2,2,3,4))
+  {
+    // the orientation of the polygon matters
+    if (tboundary[max+1]==3)
+    {
+      N=3,0,1,0,0,1,0,2,1;
+    }
+    else
+    {
+      N=0,0,1,3,0,1,2,1,1;
+    }
+  }
+  // Case 11:
+  if (sbd==intvec(2,3,3,4))
+  {
+    N=3,0,1,0,0,1,0,2,1;
+  }
+  // Case 12:
+  if (sbd==intvec(3,3,3,3))
+  {
+    N=2,0,1,0,0,1,0,2,1;
+  }
+  // Case 13:
+  if (sbd==intvec(2,2,2,2,2))
+  {
+    // compute the angles of the polygon vertices
+    intvec dt;
+    for (i=1;i<=5;i++)
+    {
+      A=pg[i]-pg[i+1],pg[i+2]-pg[i+1];
+      dt[i]=det(A);
+    }
+    dt[6]=dt[1];
+    // find the vertex to be mapped to (0,1)
+    max=1;
+    while ((dt[max]!=2) or (dt[max+1]!=2))
+    {
+      max++;
+    }
+    M=pg[max],1,pg[max+1],1,pg[max+2],1;
+    N=0,1,1,1,2,1,2,1,1;
+  }
+  // Case 14:
+  if (sbd==intvec(2,2,2,2,3))
+  {
+    N=2,0,1,0,0,1,0,1,1;
+  }
+  // Case 15:
+  if (sbd==intvec(2,2,2,3,3))
+  {
+    // find the vertix to be mapped to (2,0)
+    if (tboundary[max+1]!=3)
+    {
+      max=5;
+      M=pg[max],1,pg[max+1],1,pg[max+2],1;
+    }
+    N=2,0,1,0,0,1,0,2,1;
+  }
+  // Case 16:
+  if (sbd==intvec(2,2,2,2,2,2))
+  {
+    N=2,0,1,1,0,1,0,1,1;
+  }
+  // we have to transpose the matrices M and N
+  M=transpose(M);
+  N=transpose(N);
+  // compute the unimodular affine transformation, which is of the form
+  // A11 A12 | T1
+  // A21 A22 | T2
+  //  0   0  | 1
+  T=matrixtointmat(N*inverse(M));
+  // the upper-left 2x2-block is A
+  A=T[1..2,1..2];
+  // the upper-right 2x1-block is the translation vector
+  trans=T[1,3],T[2,3];
+  // transform now the lattice points of the polygon with respect to A and T
+  list nf;
+  for (i=1;i<=size(polygon);i++)
+  {
+    intmat V[2][1]=polygon[i];
+    V=A*V;
+    nf[i]=intvec(V[1,1]+trans[1],V[2,1]+trans[2]);
+    kill V;
+  }
+  return(list(findOrientedBoundary(nf)[2],A,trans,nf));
+}
+example
+{
+   "EXAMPLE:";
+   echo=2;
+   ring r=0,(x,y),dp;
+   // the Newton polygon of the following polynomial
+   //     has precisely one interior point
+   poly f=x22y11+x19y10+x17y9+x16y9+x12y7+x9y6+x7y5+x2y3;
+   list polygon=newtonPolytopeLP(f);
+   // its lattice points are
+   polygon;
+   // find its normal form
+   list nf=ellipticNF(polygon);
+   // the vertices of the normal form are
+   nf[1];
+   // it has been transformed by the unimodular affine transformation A*x+v
+   // with matrix A
+   nf[2];
+   // and translation vector v
+   nf[3];
+   // the 3rd lattice point ...
+   polygon[3];
+   // ... has been transformed to
+   nf[4][3];
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+
+proc ellipticNFDB (int n,list #)
+"USAGE:  ellipticNFDB(n[,#]);   n int, # list
+ASSUME:  n is an integer between 1 and 16
+PURPOSE: this is a database storing the 16 normal forms of planar polygons with
+         precisely one interior point up to unimodular affine transformations
+@*       (see e.g. Bjorn Poonen, Fernando Rodriguez-Villegas: Lattice Polygons
+                   and the number 12.  Amer. Math. Monthly  107  (2000),  no. 3,
+                   238--250.)
+RETURN:  list, L such that
+@*             L[1] : list whose entries are the vertices of the nth normal form
+@*             L[2] : list whose entries are all the lattice points of the
+                      nth normal form
+@*             L[3] : only present if the optional parameter # is present, and
+                      then it is a polynomial in the variables (x,y) whose
+                      Newton polygon is the nth normal form
+NOTE:    the optional parameter is only allowed if the basering has the
+         variables x and y
+EXAMPLE: example ellipticNFDB;   shows an example"
+{
+  if ((n<1) or (n>16))
+  {
+    ERROR("n is not between 1 and 16.");
+  }
+  if (size(#)>0)
+  {
+    if ((defined(x)==0) or (defined(y)==0))
+    {
+      ERROR("The variables x and y are not defined.");
+    }
+  }
+  if ((defined(x)==0) or (defined(y)==0))
+  {
+    ring nfring=0,(x,y),dp;
+  }
+  // store the normal forms as polynomials
+  list nf=x2+y+xy2,x2+x+1+xy2,x3+x2+x+1+y2+y,x4+x3+x2+x+1+y2+y+x2y,x3+x2+x+1+x2y+y+xy2+y2+y3,
+    x2+x+x2y+y2,x2y+x+y+xy2,x2+x+1+y+xy2,x2+x+1+y+xy2+y2,x3+x2+x+1+x2y+y+y2,x3+x2+x+1+x2y+y+xy2+y2,
+    x2+x+1+x2y+y+x2y2+xy2+y2,x+1+x2y+y+xy2,x2+x+1+x2y+y+xy2,x2+x+1+x2y+y+xy2+y2,x2+x+x2y+y+xy2+y2;
+  list pg=newtonPolytopeLP(nf[n]);
+  if (size(#)==0)
+  {
+    return(list(findOrientedBoundary(pg)[2],pg));
+  }
+  else
+  {
+    return(list(findOrientedBoundary(pg)[2],pg,nf[n]));
+  }
+}
+example
+{
+   "EXAMPLE:";
+   echo=2;
+   list nf=ellipticNFDB(5);
+   // the vertices of the 5th normal form are
+   nf[1];
+   // its lattice points are
+   nf[2];
+}
+
+
+/////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////
+/// AUXILARY PROCEDURES, WHICH ARE DECLARED STATIC
+/////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////
+/// - scalarproduct
+/// - intmatcoldelete
+/// - intmatconcat
+/// - sortlist
+/// - minInList
+/// - stringdelete
+/// - abs
+/// - commondenominator
+/// - maxPosInIntvec
+/// - maxPosInIntmat
+/// - sortintvec
+/// - matrixtointmat
+/////////////////////////////////////////////////////////////////////////////////
+
+static proc scalarproduct (intvec w,intvec v)
+"USAGE:      scalarproduct(w,v); w,v intvec
+ASSUME:      w and v are integer vectors of the same length
+RETURN:      int, the scalarproduct of v and w
+NOTE:        the procedure is called by findOrientedBoundary"
+{
+  int sp;
+  for (int i=1;i<=size(w);i++)
+  {
+    sp=sp+v[i]*w[i];
+  }
+  return(sp);
+}
+
+static proc intmatcoldelete (def w,int i)
+"USAGE:      intmatcoldelete(w,i); w intmat, i int
+RETURN:      intmat, the integer matrix w with the ith comlumn deleted
+NOTE:        the procedure is called by intmatsort and normalFanL"
+{
+  if (typeof(w)=="intmat")
+  {
+    if ((i<1) or (i>ncols(w)) or (ncols(w)==1))
+    {
+      return(w);
+    }
+    if (i==1)
+    {
+      intmat M[nrows(w)][ncols(w)-1]=w[1..nrows(w),2..ncols(w)];
+      return(M);
+    }
+    if (i==ncols(w))
+    {
+      intmat M[nrows(w)][ncols(w)-1]=w[1..nrows(w),1..ncols(w)-1];
+      return(M);
+    }
+    else
+    {
+      intmat M[nrows(w)][i-1]=w[1..nrows(w),1..i-1];
+      intmat N[nrows(w)][ncols(w)-i]=w[1..nrows(w),i+1..ncols(w)];
+      return(intmatconcat(M,N));
+    }
+  }
+  if (typeof(w)=="bigintmat")
+  {
+    if ((i<1) or (i>ncols(w)) or (ncols(w)==1))
+    {
+      return(w);
+    }
+    if (i==1)
+    {
+      bigintmat M[nrows(w)][ncols(w)-1]=w[1..nrows(w),2..ncols(w)];
+      return(M);
+    }
+    if (i==ncols(w))
+    {
+      bigintmat M[nrows(w)][ncols(w)-1]=w[1..nrows(w),1..ncols(w)-1];
+      return(M);
+    }
+    else
+    {
+      bigintmat MN[nrows(w)][ncols(w)-1];
+      MN[1..nrows(w),1..i-1]=w[1..nrows(w),1..i-1];
+      MN[1..nrows(w),i..ncols(w)-1]=w[1..nrows(w),i+1..ncols(w)];
+      return(MN);
+    }
+  } else
+  {
+    ERROR("intmatcoldelete: input matrix has to be of type intmat or bigintmat");
+    intmat M; return(M);
+  }
+}
+
+static proc intmatconcat (intmat M,intmat N)
+"USAGE:      intmatconcat(M,N); M,N intmat
+RETURN:      intmat, M and N concatenated
+NOTE:        the procedure is called by intmatcoldelete and sortintmat"
+{
+  if (nrows(M)>=nrows(N))
+  {
+    int m=nrows(M);
+
+  }
+  else
+  {
+    int m=nrows(N);
+  }
+  intmat P[m][ncols(M)+ncols(N)];
+  P[1..nrows(M),1..ncols(M)]=M[1..nrows(M),1..ncols(M)];
+  P[1..nrows(N),ncols(M)+1..ncols(M)+ncols(N)]=N[1..nrows(N),1..ncols(N)];
+  return(P);
+}
+
+static proc sortlist (list v,int pos)
+"USAGE:      sortlist(v,pos); v list, pos int
+RETURN:      list, the list L ordered in an ascending way according to the pos-th entries
+NOTE:        called by tropicalCurve"
+{
+  if(size(v)==1)
+  {
+    return(v);
+  }
+  list w=minInList(v,pos);
+  v=delete(v,w[2]);
+  v=sortlist(v,pos);
+  v=list(w[1])+v;
+  return(v);
+}
+
+static proc minInList (list v,int pos)
+"USAGE:      minInList(v,pos); v list, pos int
+RETURN:      list, (v[i],i) such that v[i][pos] is minimal
+NOTE:        called by sortlist"
+{
+  int min=v[1][pos];
+  int minpos=1;
+  for (int i=2;i<=size(v);i++)
+  {
+    if (v[i][pos]<min)
+    {
+      min=v[i][pos];
+      minpos=i;
+    }
+  }
+  return(list(v[minpos],minpos));
+}
+
+static proc stringdelete (string w,int i)
+"USAGE:      stringdelete(w,i); w string, i int
+RETURN:      string, the string w with the ith component deleted
+NOTE:        the procedure is called by texnumber and choosegfanvector"
+{
+  if ((i>size(w)) or (i<=0))
+  {
+    return(w);
+  }
+  if ((size(w)==1) and (i==1))
+  {
+    return("");
+
+  }
+  if (i==1)
+  {
+    return(w[2..size(w)]);
+  }
+  if (i==size(w))
+  {
+    return(w[1..size(w)-1]);
+  }
+  else
+  {
+    string erg=w[1..i-1],w[i+1..size(w)];
+    return(erg);
+  }
+}
+
+static proc abs (def n)
+"USAGE:      abs(n); n poly or int
+RETURN:      poly or int, the absolute value of n"
+{
+  if (n>=0)
+  {
+    return(n);
+  }
+  else
+  {
+    return(-n);
+  }
+}
+
+static proc commondenominator (matrix M)
+"USAGE:   commondenominator(M);  M matrix
+ASSUME:   the base ring has characteristic zero
+RETURN:   int, the lowest common multiple of the denominators of the leading coefficients
+               of the entries in M
+NOTE:        the procedure is called from polymakeToIntmat"
+{
+  int i,j;
+  int kgV=1;
+  // successively build the lowest common multiple of the denominators of the leading coefficients
+  // of the entries in M
+  for (i=1;i<=nrows(M);i++)
+  {
+    for (j=1;j<=ncols(M);j++)
+    {
+      kgV=lcm(kgV,int(denominator(leadcoef(M[i,j]))));
+    }
+  }
+  return(kgV);
+}
+
+static proc maxPosInIntvec (intvec v)
+"USAGE:      maxPosInIntvec(v); v intvec
+RETURN:      int, the first position of a maximal entry in v
+NOTE:        called by sortintmat"
+{
+  int max=v[1];
+  int maxpos=1;
+  for (int i=2;i<=size(v);i++)
+  {
+    if (v[i]>max)
+    {
+      max=v[i];
+      maxpos=i;
+    }
+  }
+  return(maxpos);
+}
+
+static proc maxPosInIntmat (intmat v)
+"USAGE:      maxPosInIntmat(v); v intmat
+ASSUME:      v has a unique maximal entry
+RETURN:      intvec, the position (i,j) of the maximal entry in v
+NOTE:        called by findOrientedBoundary"
+{
+  int max=v[1,1];
+  intvec maxpos=1,1;
+  int i,j;
+  for (i=1;i<=nrows(v);i++)
+  {
+    for (j=1;j<=ncols(v);j++)
+    {
+      if (v[i,j]>max)
+      {
+        max=v[i,j];
+        maxpos=i,j;
+      }
+    }
+  }
+  return(maxpos);
+}
+
+static proc sortintvec (intvec w)
+"USAGE:      sortintvec(v); v intvec
+RETURN:      intvec, the entries of v are ordered in an ascending way
+NOTE:        called from ellipticNF"
+{
+  int j,k,stop;
+  intvec v=w[1];
+  for (j=2;j<=size(w);j++)
+  {
+    k=1;
+    stop=0;
+    while ((k<=size(v)) and (stop==0))
+    {
+      if (v[k]<w[j])
+      {
+        k++;
+      }
+      else
+      {
+        stop=1;
+      }
+    }
+    if (k==size(v)+1)
+    {
+      v=v,w[j];
+    }
+    else
+    {
+      if (k==1)
+      {
+        v=w[j],v;
+      }
+      else
+      {
+        v=v[1..k-1],w[j],v[k..size(v)];
+      }
+    }
+  }
+  return(v);
+}
+
+static proc sortlistbyintvec (list L,intvec w)
+"USAGE:      sortlistbyintvec(L,w); L list, w intvec
+RETURN:      list, the entries of L are ordered such that the corresponding reordering of
+                   w would order w in an ascending way
+NOTE:        called from ellipticNF"
+{
+  int j,k,stop;
+  intvec v=w[1];
+  list LL=L[1];
+  for (j=2;j<=size(w);j++)
+  {
+    k=1;
+    stop=0;
+    while ((k<=size(v)) and (stop==0))
+    {
+      if (v[k]<w[j])
+      {
+        k++;
+      }
+      else
+      {
+        stop=1;
+      }
+    }
+    if (k==size(v)+1)
+    {
+      v=v,w[j];
+      LL=insert(LL,L[j],size(LL));
+    }
+    else
+    {
+      if (k==1)
+      {
+        v=w[j],v;
+        LL=insert(LL,L[j]);
+      }
+      else
+      {
+        v=v[1..k-1],w[j],v[k..size(v)];
+        LL=insert(LL,L[j],k-1);
+      }
+    }
+  }
+  return(LL);
+}
+
+static proc matrixtointmat (matrix MM)
+"USAGE:      matrixtointmat(v); MM matrix
+ASSUME:      MM is a matrix with only integers as entries
+RETURN:      intmat, the matrix MM has been transformed to type intmat
+NOTE:        called from ellipticNF"
+{
+  intmat M[nrows(MM)][ncols(MM)]=M;
+  int i,j;
+  for (i=1;i<=nrows(M);i++)
+  {
+    for (j=1;j<=ncols(M);j++)
+    {
+      execute("M["+string(i)+","+string(j)+"]="+string(MM[i,j])+";");
+    }
+  }
+  return(M);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+static proc polygonToCoordinates (list points)
+"USAGE:      polygonToCoordinates(points);   points list
+ASSUME:      points is a list of integer vectors each of size two describing the
+             marked points of a convex lattice polygon like the output of
+             polygonDB
+RETURN:      list, the first entry is a string representing the coordinates
+                   corresponding to the latticpoints seperated by commata
+                   the second entry is a list where the ith entry is a string
+                   representing the coordinate of corresponding to the ith
+                   lattice point the third entry is the latex format of the
+                   first entry
+NOTE:        the procedure is called by fan"
+{
+  string coord;
+  list coords;
+  string latex;
+  for (int i=1;i<=size(points);i++)
+  {
+    coords[i]="u"+string(points[i][1])+string(points[i][2]);
+    coord=coord+coords[i]+",";
+    latex=latex+"u_{"+string(points[i][1])+string(points[i][2])+"},";
+  }
+  coord=coord[1,size(coord)-1];
+  latex=latex[1,size(latex)-1];
+  return(list(coord,coords,latex));
+}
+
+static proc intmatAddFirstColumn (def M,string art)
+"USAGE:  intmatAddFirstColumn(M,art);  M intmat, art string
+ASSUME:  - M is an integer matrix where a first column of 0's or 1's should be added
+@*       - art is one of the following strings:
+@*         + 'rays'   : indicating that a first column of 0's should be added
+@*         + 'points' : indicating that a first column of 1's should be added
+RETURN:  intmat, a first column has been added to the matrix"
+{
+  if (typeof (M) == "intmat")
+  {
+    intmat N[nrows(M)][ncols(M)+1];
+    int i,j;
+    for (i=1;i<=nrows(M);i++)
+    {
+      if (art=="rays")
+      {
+        N[i,1]=0;
+      }
+      else
+      {
+        N[i,1]=1;
+      }
+      for (j=1;j<=ncols(M);j++)
+      {
+        N[i,j+1]=M[i,j];
+      }
+    }
+    return(N);
+  }
+  if (typeof (M) == "bigintmat")
+  {
+    bigintmat N[nrows(M)][ncols(M)+1];
+    int i,j;
+    for (i=1;i<=nrows(M);i++)
+    {
+      if (art=="rays")
+      {
+        N[i,1]=0;
+      }
+      else
+      {
+        N[i,1]=1;
+      }
+      for (j=1;j<=ncols(M);j++)
+      {
+        N[i,j+1]=M[i,j];
+      }
+    }
+    return(N);
+  }
+  else
+  {
+    ERROR ("intmatAddFirstColumn: input matrix has to be either intmat or bigintmat");
+    intmat N;
+    return (N);
+  }
+}
+
+
+
diff --git a/Singular/LIB/presolve.lib b/Singular/LIB/presolve.lib
new file mode 100644
index 0000000..ee90f18
--- /dev/null
+++ b/Singular/LIB/presolve.lib
@@ -0,0 +1,1538 @@
+////////////////////////////////////////////////////////////////////////////
+version="version presolve.lib 4.0.0.0 Jun_2013 "; // $Id: a821b3744d10d830fa7a311addca1920f2c00fcd $
+category="Symbolic-numerical solving";
+info="
+LIBRARY:  presolve.lib     Pre-Solving of Polynomial Equations
+AUTHOR:   Gert-Martin Greuel, email: greuel at mathematik.uni-kl.de,
+
+PROCEDURES:
+ degreepart(id,d1,d2);  elements of id of total degree >= d1 and <= d2, and rest
+ elimlinearpart(id);    linear part eliminated from id
+ elimpart(id[,n]);      partial elimination of vars [among first n vars]
+ elimpartanyr(i,p);     factors of p partially eliminated from i in any ring
+ fastelim(i,p[..]);     fast elimination of factors of p from i [options]
+ findvars(id[..]);      ideal of variables occuring in id [more information]
+ hilbvec(id[,c,o]);     intvec of Hilberseries of id [in char c and ord o]
+ linearpart(id);        elements of id of total degree <=1
+ tolessvars(id[,]);     maps id to new basering having only vars occuring in id
+ solvelinearpart(id);   reduced std-basis of linear part of id
+ sortandmap(id[..]);    map to new basering with vars sorted w.r.t. complexity
+ sortvars(id[n1,p1..]); sort vars w.r.t. complexity in id [different blocks]
+ valvars(id[..]);       valuation of vars w.r.t. to their complexity in id
+ idealSplit(id,tF,fS);  a list of ideals such that their intersection
+                        has the same radical as id
+                       ( parameters in square brackets [] are optional)
+";
+
+LIB "inout.lib";
+LIB "general.lib";
+LIB "matrix.lib";
+LIB "ring.lib";
+LIB "elim.lib";
+///////////////////////////////////////////////////////////////////////////////
+proc shortid (def id,int n,list #)
+"USAGE:   shortid(id,n[,e]); id= ideal/module, n,e=integers
+RETURN:  - if called with two arguments or e=0:
+@*       same type as id, containing generators of id having <= n terms.
+@*       - if called with three arguments and e!=0:
+@*       a list L:
+@*       L[1]: same type as id, containing generators of id having <= n terms.
+@*       L[2]: number of corresponding generator of id
+NOTE:    May be used to compute partial standard basis in case id is to hard
+EXAMPLE: example shortid; shows an example
+"
+{
+  intvec v;
+  int ii;
+  for(ii=1; ii<=ncols(id); ii++)
+  {
+   if (size(id[ii]) <=n and id[ii]!=0 )
+   {
+     v=v,ii;
+   }
+   if (size(id[ii]) > n )
+   {
+       id[ii]=0;
+   }
+  }
+  if( size(v)>1 )
+  {
+    v = v[2..size(v)];
+  }
+  id = simplify(id,2);
+  list L = id,v;
+  if ( size(#)==0 )
+  {
+    return(id);
+  }
+  if ( size(#)!=0 )
+  {
+    if(#[1]==0)
+    {
+      return(id);
+    }
+    if(#[1]!=0)
+    {
+      return(L);
+    }
+  }
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring s=0,(x,y,z,w),dp;
+   ideal i = (x3+y2+yw2)^2,(xz+z2)^2,xyz-w2-xzw;
+   shortid(i,3);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc degreepart (def id,int d1,int d2,list #)
+"USAGE:   degreepart(id,d1,d2[,v]);  id=ideal/module, d1,d1=integers, v=intvec
+RETURN:  list of size 2,
+         _[1]: generators of id of [v-weighted] total degree >= d1 and <= d2
+          (default: v = 1,...,1)
+         _[2]: remaining generators of id
+NOTE:    if id is of type int/number/poly it is converted to ideal, if id is
+         of type intmat/matrix/vector to module and then the corresponding
+         generators are computed
+EXAMPLE: example degreepart; shows an example
+"
+{
+   if( typeof(id)=="int" or typeof(id)=="number"
+       or typeof(id)=="ideal" or typeof(id)=="poly" )
+   {
+      ideal dpart = ideal(id);
+   }
+   if( typeof(id)=="intmat" or typeof(id)=="matrix"
+       or typeof(id)=="module" or typeof(id)=="vector")
+   {
+      module dpart = module(id);
+   }
+
+   def epart = dpart;
+   int s,ii = ncols(id),0;
+   if ( size(#)==0 )
+   {
+      for ( ii=1; ii<=s; ii++ )
+      {
+         dpart[ii] = (jet(id[ii],d1-1)==0)*(id[ii]==jet(id[ii],d2))*id[ii];
+         epart[ii] = (size(dpart[ii])==0) * id[ii];
+      }
+   }
+   else
+   {
+      for ( ii=1; ii<=s; ii=ii+1 )
+      {
+      dpart[ii]=(jet(id[ii],d1-1,#[1])==0)*(id[ii]==jet(id[ii],d2,#[1]))*id[ii];
+       epart[ii] = (size(dpart[ii])==0)*id[ii];
+      }
+   }
+   list L = simplify(dpart,2),simplify(epart,2);
+   return(L);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r=0,(x,y,z),dp;
+   ideal i=1+x+x2+x3+x4,3,xz+y3+z8;
+   degreepart(i,0,4);
+
+   module m=[x,y,z],x*[x3,y2,z],[1,x2,z3,0,1];
+   intvec v=2,3,6;
+   show(degreepart(m,8,8,v));
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc linearpart (def id)
+"USAGE:   linearpart(id);  id=ideal/module
+RETURN:  list of size 2,
+         _[1]: generators of id of total degree <= 1
+         _[2]: remaining generators of id
+NOTE:    all variables have degree 1 (independent of ordering of basering)
+EXAMPLE: example linearpart; shows an example
+"
+{
+   return(degreepart(id,0,1));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r=0,(x,y,z),dp;
+   ideal i=1+x+x2+x3,3,x+3y+5z;
+   linearpart(i);
+
+   module m=[x,y,z],x*[x3,y2,z],[1,x2,z3,0,1];
+   show(linearpart(m));
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc elimlinearpart (ideal i,list #)
+"USAGE:   elimlinearpart(i[,n]);  i=ideal, n=integer,@*
+          default: n=nvars(basering)
+RETURN:   list L with 5 entries:
+  @format
+  L[1]: ideal obtained from i by substituting from the first n variables those
+        which appear in a linear part of i, by putting this part into triangular
+        form
+  L[2]: ideal of variables which have been substituted
+  L[3]: ideal, j-th element defines substitution of j-th var in [2]
+  L[4]: ideal of variables of basering, eliminated ones are set to 0
+  L[5]: ideal, describing the map from the basering to itself such that
+        L[1] is the image of i
+  @end format
+NOTE:    the procedure always interreduces the ideal i internally w.r.t.
+         ordering dp.
+EXAMPLE: example elimlinearpart; shows an example
+"
+{
+   int ii,n,k,ringchange;
+   string o;
+   intvec getoption = option(get);
+   option(redSB);
+   def BAS = basering;
+   n = nvars(BAS);
+   list gnirlist = ringlist(basering);
+   list g3 = gnirlist[3];
+   list g32 = g3[size(g3)];
+
+//---------------------------------- start ------------------------------------
+   if ( size(#)!=0 ) {  n=#[1]; }
+   ideal maxi,rest = maxideal(1),0;
+   if ( n < nvars(BAS) )
+   {
+      rest = maxi[n+1..nvars(BAS)];     //variables which are not substituted
+   }
+   attrib(rest,"isSB",1);
+
+//-------------------- find linear part and reduce rest ----------------------
+// Perhaps for big systems, check only those generators of id
+// which do not contain elements not to be eliminated
+
+   //ideal id = interred(i);
+   //## gmg, geaendert 9/2008: interred sehr lange z.B. bei Leonard1 in normal,
+   //daher interred ersetzt durch: std nur auf linearpart angewendet
+   //Wechsel zu dp Ordnung (da Lin affin linear)
+
+//--------------- replace ordering different from dp by dp -------------------
+   o = "dp("+string(n)+")";
+   if( ! find(ordstr(BAS),o) or find(ordstr(BAS),"a") )
+   {
+      ringchange = 1;                         //remember change of ring
+      intvec V;
+      V[n]=0; V=V+1;                          //weights for dp ordering
+      gnirlist[3] = list("dp",V), g32;
+      def newBAS = ring(gnirlist);            //change of ring to dp ordering
+      setring newBAS;
+      ideal rest = imap(BAS,rest);
+      attrib(rest,"isSB",1);
+      ideal i = imap(BAS,i);
+   }
+
+   list  Lin = linearpart(i);
+   ideal lin = std(Lin[1]);          //SB of ideal generated by polys of i
+                                     //having at most degree 1
+   ideal id = Lin[2];                //remaining polys from i, of deg > 1
+   id = simplify(NF(id,lin),2);      //instead of subst
+   ideal id1 = linearpart(id)[1];
+   while( size(id1) != 0 )           //repeat to find linear parts
+   {
+      lin = lin,id1;
+      lin = std(lin);
+      id = simplify(NF(id,lin),2);   //instead of subst, (### is faster)
+      id1 = linearpart(id)[1];
+   }
+//------------- check for special case of unit ideal and return ---------------
+   int check;
+   if( lin[1] == 1 )
+   {
+     check = 1;
+   }
+   else
+   {
+     for (ii=1; ii<=size(id); ii++ )
+     {
+       if ( id[ii] == 1 )
+       {
+         check = 1; break;
+        }
+      }
+    }
+
+   if (check == 1)        //case of a unit ideal
+   {
+     setring BAS;
+     list L = ideal(1), ideal(0), ideal(0), maxideal(1), maxideal(1);
+     option(set,getoption);
+     return(L);
+   }
+//----- remove generators from lin containing vars not to be eliminated  ------
+   if ( n < nvars(BAS) )
+   {
+      for ( ii=1; ii<=size(lin); ii++ )
+      {
+         if ( reduce(lead(lin[ii]),rest) == 0 )
+         {
+            id=lin[ii],id;
+            lin[ii] = 0;
+         }
+      }
+   }
+   lin = simplify(lin,1);
+   ideal eva = lead(lin);               //vars to be eliminated
+   attrib(eva,"isSB",1);
+   ideal neva = NF(maxideal(1),eva);    //vars not to be eliminated
+//------------------ go back to original ring end return  ---------------------
+
+   if ( ringchange  )                   //i.e there was a ring change
+   {
+      setring BAS;
+      ideal id = imap(newBAS,id);
+      ideal eva = imap(newBAS,eva);
+      ideal lin = imap(newBAS,lin);
+      ideal neva = imap(newBAS,neva);
+   }
+
+   eva = eva[ncols(eva)..1];  // sorting according to variables in basering
+   lin = lin[ncols(lin)..1];
+   ideal phi = neva;
+   k = 1;
+   for( ii=1; ii<=n; ii++ )
+   {
+      if( neva[ii] == 0 )
+      {
+         phi[ii] = eva[k]-lin[k];
+         k=k+1;
+      }
+   }
+
+   list L = id, eva, lin, neva, phi;
+   option(set,getoption);
+   return(L);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring s=0,(u,x,y,z),dp;
+   ideal i = u3+y3+z-x,x2y2+z3,y+z+1,y+u;
+   elimlinearpart(i);
+}
+///////////////////////////////////////////////////////////////////////////////
+proc elimpart (ideal i,list #)
+"USAGE:   elimpart(i [,n,e] );  i=ideal, n,e=integers
+         n   : only the first n vars are considered for substitution,@*
+         e =0: substitute from linear part of i (same as elimlinearpart)@*
+         e!=0: eliminate also by direct substitution@*
+         (default: n = nvars(basering), e = 1)
+RETURN:  list of 5 objects:
+  @format
+  [1]: ideal obtained by substituting from the first n variables those
+       from i, which appear in the linear part of i (or, if e!=0, which
+       can be expressed directly in the remaining vars)
+  [2]: ideal, variables which have been substituted
+  [3]: ideal, i-th element defines substitution of i-th var in [2]
+  [4]: ideal of variables of basering, substituted ones are set to 0
+  [5]: ideal, describing the map from the basering, say k[x(1..m)], to
+       itself onto k[..variables from [4]..] and [1] is the image of i
+  @end format
+  The ideal i is generated by [1] and [3] in k[x(1..m)], the map [5]
+  maps [3] to 0, hence induces an isomorphism
+  @format
+            k[x(1..m)]/i -> k[..variables from [4]..]/[1]
+  @end format
+NOTE:    Applying elimpart to interred(i) may result in more substitutions.
+         However, interred may be more expansive than elimpart for big ideals
+EXAMPLE: example elimpart; shows an example
+"
+{
+   def BAS = basering;
+   int n,e = nvars(BAS),1;
+   if ( size(#)==1 ) {  n=#[1]; }
+   if ( size(#)==2 ) {  n=#[1]; e=#[2];}
+//----------- interreduce linear part with proc elimlinearpart ----------------
+// lin = ideal i after interreduction with linear part
+// eva = eliminated (substituted) variables
+// sub = polynomials defining substitution
+// neva= not eliminated variables
+// phi = map describing substitution
+
+   list L = elimlinearpart(i,n);
+   ideal lin, eva, sub, neva, phi = L[1], L[2], L[3], L[4], L[5];
+   if ( e == 0 )
+   {
+       return(L);
+   }
+
+//-------- direct substitution of variables if possible and if e!=0 -----------
+// first find terms lin1 in lin of pure degree 1 in each polynomial of lin
+// k1 = pure degree 1 part, i.e. nonzero elts of lin1, renumbered
+// k2 = lin2 (=matrix(lin) - matrix(lin2)), renumbered
+// kin = matrix(k1)+matrix(k2) = those polys of lin which contained a pure
+// degree 1 part.
+/*
+Alte Version mit interred:
+// Then go to ring newBAS with ordering c,dp(n) and create a matrix with
+// size(k1) colums and 2 rows, such that if [f1,f2] is a column of M then f1+f2
+// is one of the polys of lin containing a pure degree 1 part and f1 is this
+// part interreduce this matrix (i.e. Gauss elimination on linear part, with
+// rest transformed accordingly).
+//Ist jetzt durch direkte Substitution gemacht (schneller!)
+         //Variante falls wieder interred angewendet werden soll:
+         //ideal k12 = k1,k2;
+         //matrix M = matrix(k12,2,kk);     //degree 1 part is now in row 1
+         //M = interred(M);
+         //### interred zu teuer, muss nicht sein. Wenn interred angewendet
+         //werden soll, vorher in Ring mit Ordnung (c,dp) wechseln!
+         //Abfrage:  if( ordstr(BAS) != "c,dp("+string(n)+")" )
+         //auf KEINEN Fall std (wird zu gross)
+         //l = ncols(M);
+         //k1 = M[1,1..l];
+         //k2 = M[2,1..l];
+Interred ist jetzt ganz weggelassen. Aber es gibt Beispiele wo interred polys
+mit Grad 1 Teilen produziert, die vorher nicht da waren (aus polys, die einen konstanten Term haben).
+z.B. i=xy2-xu4-x+y2,x2y2+z3+zy,y+z2+1,y+u2;, interred(i)=z2+y+1,y2-x,u2+y,x3-z
+-z ergibt ich auch i[2]-z*i[3] mit option(redThrough)
+statt interred kann man hier auch NF(i,i[3])+i[3] verwenden
+hier lifert elimpart(i) 2 Substitutionen (x,y) elimpart(interred(i))
+aber 3 (x,y,z)
+Da interred oder NF aber die Laenge der polys vergroessern kann, nicht gemacht
+*/
+   int ii, kk;
+   ideal k1, k2, lin2;
+   int l = ncols(lin);                  // lin=i after applying elimlinearpart
+   ideal lin1 = ideal(matrix(jet(lin,1))-matrix(jet(lin,0)));  // part of pure degree 1
+   //Note: If i,i1,i2 are ideals, then i = i1 - i2 is equivalent to
+   //i = ideal(matrix(i1) - matrix(i2))
+
+   if (size(lin1) == 0 )
+   {
+       return(L);
+   }
+
+   //-------- check candidates for direct substitution of variables ----------
+   //since lin1 != 0 there are candidates for substituting variables
+
+   lin2 = matrix(lin) - matrix(lin1);      //difference as matrix
+   // rest of lin, part of pure degree 1 substracted from each generator of lin
+
+   for( ii=1; ii<=l; ii++ )
+   {
+      if( lin1[ii] != 0 )
+      {
+         kk = kk+1;
+         k1[kk] = lin1[ii];  // part of pure degree 1, renumbered
+         k2[kk] = lin2[ii];  // rest of those polys which had a degree 1 part
+         lin2[ii] = 0;
+      }
+   }
+   //Now each !=0 generator of lin2 contains only constant terms or terms of
+   //degree >= 2, hence lin 2 can never be used for further substitutions
+   //We have: lin = ideal(matrix(k1)+matrix(k2)), lin2
+
+   ideal kin = matrix(k1)+matrix(k2);
+   //kin = polys of lin which contained a pure degree 1 part.
+   kin = simplify(kin,2);
+   l = size(kin);                      //l != 0 since lin1 != 0
+   poly p,kip,vip, cand;
+   int count=1;
+   while ( count != 0 )
+   {
+         count = 0;
+         for ( ii=1; ii<=n; ii++  )    //start direct substitution of var(ii)
+         {
+            for (kk=1; kk<=l; kk++ )
+            {
+               p = kin[kk]/var(ii);
+               //if ( deg(p) == 0 )
+               //old test, does not work if some var has deg 0
+               //geaendert Mai 09 gmg
+
+               if( p!=0 & p == jet(p,0) )
+                   //this means that kin[kk]= p*var(ii) + h,
+                   //with p=const !=0 and h not depending on var(ii)
+               {
+                  //we look for the shortest candidate to substitute var(ii)
+                  if ( cand == 0 )
+                  {
+                     cand = kin[kk];  //candidate for substituting var(ii)
+                  }
+                  else
+                  {
+                     if ( size(kin[kk]) < size(cand) )
+                     {
+                        cand = kin[kk];
+                     }
+                  }
+                }
+            }
+            if ( cand != 0 )
+            {
+                  p = cand/var(ii);
+                  kip = cand/p;     //normalized polynomial of kin w.r.t var(ii)
+                  eva = eva+var(ii); //var(ii) added to list of elimin. vars
+                  neva[ii] = 0;
+                  sub = sub+kip;     //polynomial defining substituion
+                  //## gmg: geaendert 08/2008, map durch subst ersetzt
+                  //(viel schneller)
+                  vip = var(ii) - kip;  //polynomial to be substituted
+                  lin = subst(lin, var(ii), vip);  //subst in rest
+                  lin = simplify(lin,2);
+                  kin = subst(kin, var(ii), vip);  //subst in pure dgree 1 part
+                  kin = simplify(kin,2);
+                  l = size(kin);
+                  count = 1;
+            }
+            cand=0;
+         }
+   }
+
+   lin = kin+lin;
+
+   for( ii=1; ii<=size(lin); ii++ )
+   {
+      lin[ii] = cleardenom(lin[ii]);
+   }
+
+   for( ii=1; ii<=n; ii++ )
+   {
+      for( kk=1; kk<=size(eva); kk++ )
+      {
+         if (phi[ii] == eva[kk] )
+         {  phi[ii] = eva[kk]-sub[kk]; break; }
+      }
+   }
+   map psi = BAS,phi;
+   ideal phi1 = maxideal(1);
+   for(ii=1; ii<=size(eva); ii++)
+   {
+      phi1=psi(phi1);
+   }
+   L = lin, eva, sub, neva, phi1;
+   return(L);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring s=0,(u,x,y,z),dp;
+   ideal i = xy2-xu4-x+y2,x2y2+z3+zy,y+z2+1,y+u2;
+   elimpart(i);
+
+   i = interred(i); i;
+   elimpart(i);
+
+   elimpart(i,2);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc elimpartanyr (ideal i, list #)
+"USAGE:   elimpartanyr(i [,p,e] );  i=ideal, p=polynomial, e=integer@*
+         p: product of vars to be eliminated,@*
+         e =0: substitute from linear part of i (same as elimlinearpart)@*
+         e!=0: eliminate also by direct substitution@*
+         (default: p=product of all vars, e=1)
+RETURN:  list of 6 objects:
+  @format
+  [1]: (interreduced) ideal obtained by substituting from i those vars
+       appearing in p, which occur in the linear part of i (or which can
+       be expressed directly in the remaining variables, if e!=0)
+  [2]: ideal, variables which have been substituted
+  [3]: ideal, i-th element defines substitution of i-th var in [2]
+  [4]: ideal of variables of basering, substituted ones are set to 0
+  [5]: ideal, describing the map from the basering, say k[x(1..m)], to
+       itself onto k[..variables fom [4]..] and [1] is the image of i
+  [6]: int, # of vars considered for substitution (= # of factors of p)
+  @end format
+  The ideal i is generated by [1] and [3] in k[x(1..m)], the map [5]
+  maps [3] to 0, hence induces an isomorphism
+  @format
+            k[x(1..m)]/i -> k[..variables fom [4]..]/[1]
+  @end format
+NOTE:    the procedure uses @code{execute} to create a ring with ordering dp
+         and vars placed correctly and then applies @code{elimpart}.
+EXAMPLE: example elimpartanyr; shows an example
+"
+{
+   def P = basering;
+   int j,n,e = 0,0,1;
+   poly p = product(maxideal(1));
+   if ( size(#)==1 ) { p=#[1]; }
+   if ( size(#)==2 ) { p=#[1]; e=#[2]; }
+   string a,b;
+   for ( j=1; j<=nvars(P); j++ )
+   {
+      if (deg(p/var(j))>=0) { a = a+varstr(j)+","; n = n+1; }
+      else { b = b+varstr(j)+","; }
+   }
+   if ( size(b) != 0 ) { b = b[1,size(b)-1]; }
+   else { a = a[1,size(a)-1]; }
+   execute("ring gnir ="+charstr(P)+",("+a+b+"),dp;");
+   ideal i = imap(P,i);
+   list L = elimpart(i,n,e)+list(n);
+   setring P;
+   list L = imap(gnir,L);
+   return(L);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring s=0,(x,y,z),dp;
+   ideal i = x3+y2+z,x2y2+z3,y+z+1;
+   elimpartanyr(i,z);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc fastelim (ideal i, poly p, list #)
+"USAGE:   fastelim(i,p[h,o,a,b,e,m]); i=ideal, p=polynomial; h,o,a,b,e=integers@*
+          p: product of variables to be eliminated;@*
+  Optional parameters:
+  @format
+  - h !=0: use Hilbert-series driven std-basis computation
+  - o !=0: use proc @code{valvars} for a - hopefully - optimal ordering of vars
+  - a !=0: order vars to be eliminated w.r.t. increasing complexity
+  - b !=0: order vars not to be eliminated w.r.t. increasing complexity
+  - e !=0: use @code{elimpart} first to eliminate easy part
+  - m !=0: compute a minimal system of generators
+  @end format
+  (default: h,o,a,b,e,m = 0,1,0,0,0,0)
+RETURN:  ideal obtained from i by eliminating those variables, which occur in p
+EXAMPLE: example fastelim; shows an example.
+"
+{
+   def P = basering;
+   int h,o,a,b,e,m = 0,1,0,0,0,0;
+   if ( size(#) == 1 ) { h=#[1]; }
+   if ( size(#) == 2 ) { h=#[1]; o=#[2]; }
+   if ( size(#) == 3 ) { h=#[1]; o=#[2]; a=#[3]; }
+   if ( size(#) == 4 ) { h=#[1]; o=#[2]; a=#[3]; b=#[4];}
+   if ( size(#) == 5 ) { h=#[1]; o=#[2]; a=#[3]; b=#[4]; e=#[5]; }
+   if ( size(#) == 6 ) { h=#[1]; o=#[2]; a=#[3]; b=#[4]; e=#[5]; m=#[6]; }
+   list L = elimpartanyr(i,p,e);
+   poly q = product(L[2]);     //product of vars which are already eliminated
+   if ( q==0 ) { q=1; }
+   p = p/q;                    //product of vars which must still be eliminated
+   int nu = size(L[5])-size(L[2]);   //number of vars which must still be eliminated
+   if ( p==1 )                 //ready if no vars are left
+   {                           //compute minbase if 3-rd argument !=0
+      if ( m != 0 ) { L[1]=minbase(L[1]); }
+      return(L);
+   }
+//---------------- create new ring with remaining variables -------------------
+   string newvar = string(L[4]);
+   L = L[1],p;
+   execute("ring r1=("+charstr(P)+"),("+newvar+"),"+"dp;");
+   list L = imap(P,L);
+//------------------- find "best" ordering of variables  ----------------------
+   newvar = string(maxideal(1));
+   if ( o != 0 )
+   {
+      list ordevar = valvars(L[1],a,L[2],b);
+      intvec v = ordevar[1];
+      newvar=string(sort(maxideal(1),v)[1]);
+//------------ create new ring with "best" ordering of variables --------------
+      def r0=changevar(newvar);
+      setring r0;
+      list L = imap(r1,L);
+      kill r1;
+      def r1 = r0;
+      kill r0;
+   }
+//----------------- h==0: eliminate remaining vars directly -------------------
+   if ( h == 0 )
+   {
+      L[1] = eliminate(L[1],L[2]);
+      def r2 = r1;
+   }
+   else
+//------- h!=0: homogenize and compute Hilbert series using hilbvec ----------
+   {
+      intvec hi = hilbvec(L[1]);         // Hilbert series of i
+      execute("ring r2=("+charstr(P)+"),("+varstr(basering)+", at homo),dp;");
+      list L = imap(r1,L);
+      L[1] = homog(L[1], at homo);          // @homo = homogenizing var
+//---- use Hilbert-series to eliminate variables with Hilbert-driven std -----
+      L[1] = eliminate(L[1],L[2],hi);
+      L[1]=subst(L[1], at homo,1);          // dehomogenize by setting @homo=1
+   }
+   if ( m != 0 )                         // compute minbase
+   {
+      if ( #[1] != 0 ) { L[1] = minbase(L[1]); }
+   }
+   def id = L[1];
+   setring P;
+   return(imap(r2,id));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring s=31991,(e,f,x,y,z,t,u,v,w,a,b,c,d),dp;
+   ideal i = w2+f2-1, x2+t2+a2-1,  y2+u2+b2-1, z2+v2+c2-1,
+            d2+e2-1, f4+2u, wa+tf, xy+tu+ab;
+   fastelim(i,xytua,1,1);       //with hilb,valvars
+   fastelim(i,xytua,1,0,1);     //with hilb,minbase
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc faststd (def @id, list #)
+"USAGE:   faststd(id [,\"hilb\",\"sort\",\"dec\",o,\"blocks\"]);
+         id=ideal/module, o=string (allowed:\"lp\",\"dp\",\"Dp\",\"ls\",
+         \"ds\",\"Ds\"),  \"hilb\",\"sort\",\"dec\",\"block\" options for
+         Hilbert-driven std, and the procedure sortandmap
+RETURN:  a ring R, in which an ideal STD_id is stored: @*
+         - the ring R differs from the active basering only in the choice
+         of monomial ordering and in the sorting of the variables.
+         - STD_id is a standard basis for the image (under imap) of the input
+         ideal/module id with respect to the new monomial ordering. @*
+NOTE:    Using the optional input parameters, we may modify the computations
+         performed: @*
+         - \"hilb\"  : use Hilbert-driven standard basis computation@*
+         - \"sort\"  : use 'sortandmap' for a best sorting of the variables@*
+         - \"dec\"   : order vars w.r.t. decreasing complexity (with \"sort\")@*
+         - \"block\" : create block ordering, each block having ordstr=o, s.t.
+                     vars of same complexity are in one block (with \"sort\")@*
+         - o       : defines the basic ordering of the resulting ring@*
+         [default: o=ordering of 1st block of basering (if allowed, else o=\"dp\"],
+                  \"sort\", if none of the optional parameters is given @*
+         This procedure is only useful for hard problems where other methods fail.@*
+         \"hilb\" is useful for hard orderings (as \"lp\") or for characteristic 0,@*
+         it is correct for \"lp\",\"dp\",\"Dp\" (and for block orderings combining
+         these) but not for s-orderings or if the vars have different weights.@*
+         There seem to be only few cases in which \"dec\" is fast.
+SEE ALSO: groebner
+EXAMPLE: example faststd; shows an example.
+"
+{
+   def @P = basering;
+   int @h, at s, at n, at m, at ii = 0,0,0,0,0;
+   string @o, at va, at c = ordstr(basering),"","";
+//-------------------- prepare ordering and set options -----------------------
+   if ( @o[1]=="c" or @o[1]=="C")
+      {  @o = @o[3,2]; }
+   else
+      { @o = @o[1,2]; }
+   if( @o[1]!="d" and @o[1]!="D" and @o[1]!="l")
+      { @o="dp"; }
+
+   if (size(#) == 0 )
+      { @s = 1; }
+   for ( @ii=1; @ii<=size(#); @ii++ )
+   {
+      if ( typeof(#[@ii]) != "string" )
+      {
+         "// wrong syntax! type: help faststd";
+         return();
+      }
+      else
+      {
+         if ( #[@ii] == "hilb"  ) { @h = 1; }
+         if ( #[@ii] == "dec"   ) { @n = 1; }
+         if ( #[@ii] == "block" ) { @m = 1; }
+         if ( #[@ii] == "sort"  ) { @s = 1; }
+         if ( #[@ii]=="lp" or #[@ii]=="dp" or #[@ii]=="Dp" or #[@ii]=="ls"
+              or #[@ii]=="ds" or #[@ii]=="Ds" ) { @o = #[@ii]; }
+      }
+   }
+   if( voice==2 ) { "// chosen options, hilb sort dec block:", at h, at s, at n, at m; }
+
+//-------------------- nosort: create ring with new name ----------------------
+   if ( @s==0 )
+   {
+      execute("ring @S1 =("+charstr(@P)+"),("+varstr(@P)+"),("+ at o+");");
+      def STD_id = imap(@P, at id);
+      if ( @h==0 ) { STD_id = std(STD_id); }
+   }
+
+//---------------------- no hilb: compute SB directly -------------------------
+   if ( @s != 0 and @h == 0 )
+   {
+      intvec getoption = option(get);
+      option(redSB);
+      @id = interred(sort(@id)[1]);
+      poly @p = product(maxideal(1),1..nvars(@P));
+      def @S1=sortandmap(@id, at n, at p,0, at o, at m);
+      setring @S1;
+      option(set,getoption);
+      def STD_id=imap(@S1,IMAG);
+      STD_id = std(STD_id);
+   }
+//------- hilb: homogenize and compute Hilbert-series using hilbvec -----------
+// this uses another standardbasis computation
+   if ( @h != 0 )
+   {
+      execute("ring @Q=("+charstr(@P)+"),("+varstr(@P)+", at homo),("+ at o+");");
+      def @id = imap(@P, at id);
+      @id = homog(@id, at homo);               // @homo = homogenizing var
+      if ( @s != 0 )
+      {
+        intvec getoption = option(get);
+        option(redSB);
+        @id = interred(sort(@id)[1]);
+        poly @p = product(maxideal(1),1..(nvars(@Q)-1));
+        def @S1=sortandmap(@id, at n, at p,0, at o, at m);
+        setring @S1;
+        option(set,getoption);
+        kill @Q;
+        def @Q= basering;
+        def @id = IMAG;
+      }
+      intvec @hi;                     // encoding of Hilbert-series of i
+      @hi = hilbvec(@id);
+      //if ( @s!=0 ) { @hi = hilbvec(@id,"32003",ordstr(@Q)); }
+      //else { @hi = hilbvec(@id); }
+//-------------------------- use Hilbert-driven std --------------------------
+      @id = std(@id, at hi);
+      @id = subst(@id, at homo,1);             // dehomogenize by setting @homo=1
+      @va = varstr(@Q)[1,size(varstr(@Q))-6];
+      if ( @s!=0 )
+      {
+         @o = ordstr(@Q);
+         if ( @o[1]=="c" or @o[1]=="C") { @o = @o[1,size(@o)-6]; }
+         else { @o = @o[1,size(@o)-8] + @o[size(@o)-1,2]; }
+      }
+      kill @S1;
+      execute("ring @S1=("+charstr(@Q)+"),("+ at va+"),("+ at o+");");
+      def STD_id = imap(@Q, at id);
+   }
+   attrib(STD_id,"isSB",1);
+   export STD_id;
+   if (defined(IMAG)) { kill IMAG; }
+   setring @P;
+   dbprint(printlevel-voice+3,"
+// 'faststd' created a ring, in which an object STD_id is stored.
+// To access the object, type (if the name R was assigned to the return value):
+        setring R; STD_id; ");
+   return(@S1);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   system("--ticks-per-sec",100); // show time in 1/100 sec
+   ring s = 0,(e,f,x,y,z,t,u,v,w,a,b,c,d),(c,lp);
+   ideal i = w2+f2-1, x2+t2+a2-1,  y2+u2+b2-1, z2+v2+c2-1,
+            d2+e2-1, f4+2u, wa+tf, xy+tu+ab;
+   option(prot); timer=1;
+   int time = timer;
+   ideal j=std(i);
+   timer-time;
+   dim(j),mult(j);
+
+   time = timer;
+   def R=faststd(i);                      // use "best" ordering of vars
+   timer-time;
+   show(R);setring R;dim(STD_id),mult(STD_id);
+
+   setring s;kill R;time = timer;
+   def R=faststd(i,"hilb");                // hilb-std only
+   timer-time;
+   show(R);setring R;dim(STD_id),mult(STD_id);
+
+   setring s;kill R;time = timer;
+   def R=faststd(i,"hilb","sort");         // hilb-std,"best" ordering
+   timer-time;
+   show(R);setring R;dim(STD_id),mult(STD_id);
+
+   setring s;kill R;time = timer;
+   def R=faststd(i,"hilb","sort","block","dec"); // hilb-std,"best",blocks
+   timer-time;
+   show(R);setring R;dim(STD_id),mult(STD_id);
+
+   setring s;kill R;time = timer;
+   timer-time;time = timer;
+   def R=faststd(i,"sort","block","Dp"); //"best",decreasing,Dp-blocks
+   timer-time;
+   show(R);setring R;dim(STD_id),mult(STD_id);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc findvars(def id, list #)
+"USAGE:   findvars(id [,any] ); id=poly/ideal/vector/module/matrix, any=any type
+RETURN:  if no second argument is present: ideal of variables occuring in id,@*
+         if a second argument is given (of any type): list L with 4 entries:
+  @format
+  L[1]: ideal of variables occuring in id
+  L[2]: intvec of variables occuring in id
+  L[3]: ideal of variables not occuring in id
+  L[4]: intvec of variables not occuring in id
+  @end format
+EXAMPLE: example findvars; shows an example
+"
+{
+   int ii,n;
+   ideal found, notfound;
+   intvec f,nf;
+   n = nvars(basering);
+   ideal i = simplify(ideal(matrix(id)),10);
+   matrix M[ncols(i)][1] = i;
+   vector v = module(M)[1];
+   ideal max = maxideal(1);
+
+   for (ii=1; ii<=n; ii++)
+   {
+      if ( v != subst(v,var(ii),0) )
+      {
+         found = found+var(ii);
+         f = f,ii;
+      }
+      else
+      {
+         notfound = notfound+var(ii);
+         nf = nf,ii;
+      }
+   }
+   if ( size(f)>1 ) { f = f[2..size(f)]; }      //intvec of found vars
+   if ( size(nf)>1 ) { nf = nf[2..size(nf)]; }  //intvec of vars not found
+   if( size(#)==0 )  { return(found); }
+   if( size(#)!=0 )  { list L = found,f,notfound,nf; return(L); }
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring s  = 0,(e,f,x,y,t,u,v,w,a,d),dp;
+   ideal i = w2+f2-1, x2+t2+a2-1;
+   findvars(i);
+   findvars(i,1);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc hilbvec (def @id, list #)
+"USAGE:   hilbvec(id[,c,o]); id=poly/ideal/vector/module/matrix, c,o=strings,@*
+          c=char, o=ordering used by @code{hilb} (default: c=\"32003\", o=\"dp\")
+RETURN:  intvec of 1st Hilbert-series of id, computed in char c and ordering o
+NOTE:    id must be homogeneous (i.e. all vars have weight 1)
+EXAMPLE: example hilbvec; shows an example
+"
+{
+   def @P = basering;
+   string @c, at o = "32003", "dp";
+   if ( size(#) == 1 ) {  @c = #[1]; }
+   if ( size(#) == 2 ) {  @c = #[1]; @o = #[2]; }
+   string @si = typeof(@id)+" @i = "+string(@id)+";";  //** weg
+   execute("ring @r=("+ at c+"),("+varstr(basering)+"),("+ at o+");");
+   //**def i = imap(P, at id);
+   execute(@si);                   //** weg
+   //show(basering);
+   @i = std(@i);
+   intvec @hi = hilb(@i,1);         // intvec of 1-st Hilbert-series of id
+   return(@hi);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring s   = 0,(e,f,x,y,z,t,u,v,w,a,b,c,d,H),dp;
+   ideal id = w2+f2-1, x2+t2+a2-1,  y2+u2+b2-1, z2+v2+c2-1,
+              d2+e2-1, f4+2u, wa+tf, xy+tu+ab;
+   id = homog(id,H);
+   hilbvec(id);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc tolessvars (def id ,list #)
+"USAGE:   tolessvars(id [,s1,s2] ); id poly/ideal/vector/module/matrix,
+          s1=string (new ordering)@*
+          [default: s1=\"dp\" or \"ds\" depending on whether the first block
+          of the old ordering is a p- or an s-ordering, respectively]
+RETURN:  If id contains all vars of the basering: empty list. @*
+         Else: ring R with the same char as the basering, but possibly less
+         variables (only those variables which actually occur in id). In R
+         an object IMAG (image of id under imap) is stored.
+DISPLAY: If printlevel >=0, display ideal of vars, which have been omitted
+         from the old ring.
+EXAMPLE: example tolessvars; shows an example
+"
+{
+//---------------- initialisation and check occurence of vars -----------------
+   int s,ii,n,fp,fs;
+   string s2,newvar;
+   int pr = printlevel-voice+3;  // p = printlevel+1 (default: p=1)
+   def P = basering;
+   s2 = ordstr(P);
+
+   list L = findvars(id,1);
+   newvar = string(L[1]);    // string of new variables
+   n = size(L[1]);           // number of new variables
+   if( n == 0 )
+   {
+      dbprint( pr,"","// no variable occured in "+typeof(id)+", no change of ring!");
+      return(id);
+   }
+   if( n == nvars(P) )
+   {
+     dbprint(printlevel-voice+3,"
+// All variables appear in input object.
+// empty list returned. ");
+     return(list());
+   }
+//----------------- prepare new ring, map to it and return --------------------
+   if ( size(#) == 0 )
+   {
+       fp = find(s2,"p");
+       fs = find(s2,"s");
+       if( fs==0 or (fs>=fp && fp!=0) ) { s2="dp"; }
+       else {  s2="ds"; }
+   }
+   if ( size(#) ==1 ) { s2=#[1]; }
+   dbprint( pr,"","// variables which did not occur:",L[3] );
+   execute("ring S1=("+charstr(P)+"),("+newvar+"),("+s2+");");
+   def IMAG = imap(P,id);
+   export IMAG;
+   dbprint(printlevel-voice+3,"
+// 'tolessvars' created a ring, in which an object IMAG is stored.
+// To access the object, type (if the name R was assigned to the return value):
+        setring R; IMAG; ");
+   return(S1);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r  = 0,(x,y,z),dp;
+   ideal i = y2-x3,x-3,y-2x;
+   def R_r = tolessvars(i,"lp");
+   setring R_r;
+   show(basering);
+   IMAG;
+   kill R_r;
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc solvelinearpart (def id,list #)
+"USAGE:   solvelinearpart(id [,n] );  id=ideal/module, n=integer (default: n=0)
+RETURN:  (interreduced) generators of id of degree <=1 in reduced triangular
+         form if n=0 [non-reduced triangular form if n!=0]
+ASSUME:  monomial ordering is a global ordering (p-ordering)
+NOTE:    may be used to solve a system of linear equations,
+         see @code{gauss_row} from 'matrix.lib' for a different method
+WARNING: the result is very likely to be false for 'real' coefficients, use
+         char 0 instead!
+EXAMPLE: example solvelinearpart; shows an example
+"
+{
+   intvec getoption = option(get);
+   option(redSB);
+   if ( size(#)!=0 )
+   {
+      if(#[1]!=0) { option(noredSB); }
+   }
+   def lin = interred(degreepart(id,0,1)[1]);
+   if ( size(#)!=0 )
+   {
+      if(#[1]!=0)
+      {
+         return(lin);
+      }
+   }
+   option(set,getoption);
+   return(simplify(lin,1));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   // Solve the system of linear equations:
+   //         3x +   y +  z -  u = 2
+   //         3x +  8y + 6z - 7u = 1
+   //        14x + 10y + 6z - 7u = 0
+   //         7x +  4y + 3z - 3u = 3
+   ring r = 0,(x,y,z,u),lp;
+   ideal i= 3x +   y +  z -  u,
+           13x +  8y + 6z - 7u,
+           14x + 10y + 6z - 7u,
+            7x +  4y + 3z - 3u;
+   ideal j= 2,1,0,3;
+   j = matrix(i)-matrix(j);        // difference of 1x4 matrices
+                                   // compute reduced triangular form, setting
+   solvelinearpart(j);             // the RHS equal 0 gives the solutions!
+   solvelinearpart(j,1); "";       // triangular form, not reduced
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc sortandmap (def @id, list #)
+"USAGE:   sortandmap(id [,n1,p1,n2,p2...,o1,m1,o2,m2...]);@*
+         id=poly/ideal/vector/module,@*
+         p1,p2,...= polynomials (product of variables),@*
+         n1,n2,...= integers,@*
+         o1,o2,...= strings,@*
+         m1,m2,...= integers@*
+         (default: p1=product of all vars, n1=0, o1=\"dp\",m1=0)
+         the last pi (containing the remaining vars) may be omitted
+RETURN:  a ring R, in which a poly/ideal/vector/module IMAG is stored: @*
+         - the ring R differs from the active basering only in the choice
+         of monomial ordering and in the sorting of the variables.@*
+         - IMAG is the image (under imap) of the input ideal/module id @*
+         The new monomial ordering and sorting of vars is as follows:
+  @format
+  - each block of vars occuring in pi is sorted w.r.t. its complexity in id,
+  - ni controls the sorting in i-th block (= vars occuring in pi):
+    ni=0 (resp. ni!=0) means that least complex (resp. most complex) vars come
+    first
+  - oi and mi define the monomial ordering of the i-th block:
+    if mi =0, oi=ordstr(i-th block)
+    if mi!=0, the ordering of the i-th block itself is a blockordering,
+      each subblock having ordstr=oi, such that vars of same complexity are
+      in one block
+  @end format
+         Note that only simple ordstrings oi are allowed: \"lp\",\"dp\",\"Dp\",
+         \"ls\",\"ds\",\"Ds\". @*
+NOTE:    We define a variable x to be more complex than y (with respect to id)
+         if val(x) > val(y) lexicographically, where val(x) denotes the
+         valuation vector of x:@*
+         consider id as list of polynomials in x with coefficients in the
+         remaining variables. Then:@*
+         val(x) = (maximal occuring power of x,  # of all monomials in leading
+         coefficient, # of all monomials in coefficient of next smaller power
+         of x,...).
+EXAMPLE: example sortandmap; shows an example
+"
+{
+   def @P = basering;
+   int @ii, at jj;
+   intvec @v;
+   string @o;
+//----------------- find o in # and split # into 2 lists ---------------------
+   # = # +list("dp",0);
+   for ( @ii=1; @ii<=size(#); @ii++)
+   {
+      if ( typeof(#[@ii])=="string" )  break;
+   }
+   if ( @ii==1 ) { list @L1 = list(); }
+   else { list @L1 = #[1.. at ii-1]; }
+   list @L2 = #[@ii..size(#)];
+   list @L = sortvars(@id, at L1);
+   string @va = string(@L[1]);
+   list @l = @L[2];   //e.g. @l[4]=intvec describing permutation of 1-st block
+//----------------- construct correct ordering with oi and mi ----------------
+   for ( @ii=4; @ii<=size(@l); @ii=@ii+4 )
+   {
+      @L2=@L2+list("dp",0);
+      if ( @L2[@ii div 2] != 0)
+      {
+         @v = @l[@ii];
+         for ( @jj=1; @jj<=size(@v); @jj++ )
+         {
+           @o = @o+ at L2[@ii div 2 -1]+"("+string(@v[@jj])+"),";
+         }
+      }
+      else
+      {
+         @o = @o+ at L2[@ii div 2 -1]+"("+string(size(@l[@ii div 2]))+"),";
+      }
+   }
+   @o=@o[1..size(@o)-1];
+   execute("ring @S1 =("+charstr(@P)+"),("+ at va+"),("+ at o+");");
+   def IMAG = imap(@P, at id);
+   export IMAG;
+   dbprint(printlevel-voice+3,"
+// 'sortandmap' created a ring, in which an object IMAG is stored.
+// To access the object, type (if the name R was assigned to the return value):
+        setring R; IMAG; ");
+   return(@S1);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring s = 32003,(x,y,z),dp;
+   ideal i=x3+y2,xz+z2;
+   def R_r=sortandmap(i);
+   show(R_r);
+   setring R_r; IMAG;
+   kill R_r; setring s;
+   def R_r=sortandmap(i,1,xy,0,z,0,"ds",0,"lp",0);
+   show(R_r);
+   setring R_r; IMAG;
+   kill R_r;
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc sortvars (def id, list #)
+"USAGE:   sortvars(id[,n1,p1,n2,p2,...]);@*
+         id=poly/ideal/vector/module,@*
+         p1,p2,...= polynomials (product of vars),@*
+         n1,n2,...= integers@*
+         (default: p1=product of all vars, n1=0)
+         the last pi (containing the remaining vars) may be omitted
+COMPUTE: sort variables with respect to their complexity in id
+RETURN:  list of two elements, an ideal and a list:
+  @format
+  [1]: ideal, variables of basering sorted w.r.t their complexity in id
+       ni controls the ordering in i-th block (= vars occuring in pi):
+       ni=0 (resp. ni!=0) means that less (resp. more) complex vars come first
+  [2]: a list with 4 entries for each pi:
+       _[1]: ideal ai : vars of pi in correct order,
+       _[2]: intvec vi: permutation vector describing the ordering in ai,
+       _[3]: intmat Mi: valuation matrix of ai, the columns of Mi being the
+                  valuation vectors of the vars in ai
+       _[4]: intvec wi: size of 1-st, 2-nd,... block of identical columns of Mi
+                  (vars with same valuation)
+  @end format
+NOTE:    We define a variable x to be more complex than y (with respect to id)
+         if val(x) > val(y) lexicographically, where val(x) denotes the
+         valuation vector of x:@*
+         consider id as list of polynomials in x with coefficients in the
+         remaining variables. Then:@*
+         val(x) = (maximal occuring power of x,  # of all monomials in leading
+         coefficient, # of all monomials in coefficient of next smaller power
+         of x,...).
+EXAMPLE: example sortvars; shows an example
+"
+{
+   int ii,jj,n,s;
+   list L = valvars(id,#);
+   list L2, L3 = L[2], L[3];
+   list K; intmat M; intvec v1,v2,w;
+   ideal i = sort(maxideal(1),L[1])[1];
+   for ( ii=1; ii<=size(L2); ii++ )
+   {
+      M = transpose(L3[2*ii]);
+      M = M[L2[ii],1..nrows(L3[2*ii])];
+      w = 0; s = 0;
+      for ( jj=1; jj<=nrows(M)-1; jj++ )
+      {
+         v1 = M[jj,1..ncols(M)];
+         v2 = M[jj+1,1..ncols(M)];
+         if ( v1 != v2 ) { n=jj-s; s=s+n; w = w,n; }
+      }
+      w=w,nrows(M)-s; w=w[2..size(w)];
+      K = K+sort(L3[2*ii-1],L2[ii])+list(transpose(M))+list(w);
+   }
+   L = i,K;
+   return(L);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring s=0,(x,y,z,w),dp;
+   ideal i = x3+y2+yw2,xz+z2,xyz-w2;
+   sortvars(i,0,xy,1,zw);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc valvars (def id, list #)
+"USAGE:   valvars(id[,n1,p1,n2,p2,...]);@*
+         id=poly/ideal/vector/module,@*
+         p1,p2,...= polynomials (product of vars),@*
+         n1,n2,...= integers,
+
+         ni controls the ordering of vars occuring in pi: ni=0 (resp. ni!=0)
+         means that less (resp. more) complex vars come first (default: p1=product of all vars, n1=0),@*
+         the last pi (containing the remaining vars) may be omitted
+COMPUTE: valuation (complexity) of variables with respect to id.@*
+         ni controls the ordering of vars occuring in pi:@*
+         ni=0 (resp. ni!=0) means that less (resp. more) complex vars come first.
+RETURN:  list with 3 entries:
+  @format
+  [1]: intvec, say v, describing the permutation such that the permuted
+       ring variables are ordered with respect to their complexity in id
+  [2]: list of intvecs, i-th intvec, say v(i) describing permutation
+       of vars in a(i) such that v=v(1),v(2),...
+  [3]: list of ideals and intmat's, say a(i) and M(i), where
+       a(i): factors of pi,
+       M(i): valuation matrix of a(i), such that the j-th column of M(i)
+             is the valuation vector of j-th generator of a(i)
+         @end format
+NOTE:    Use @code{sortvars} in order to actually sort the variables!
+         We define a variable x to be more complex than y (with respect to id)
+         if val(x) > val(y) lexicographically, where val(x) denotes the
+         valuation vector of x:@*
+         consider id as list of polynomials in x with coefficients in the
+         remaining variables. Then:@*
+         val(x) = (maximal occuring power of x,  # of all monomials in leading
+         coefficient, # of all monomials in coefficient of next smaller power
+         of x,...).
+EXAMPLE: example valvars; shows an example
+"
+{
+//---------------------------- initialization ---------------------------------
+   int ii,jj,kk,n;
+   list L;                    // list of valuation vectors in one block
+   intvec vec;                // describes permutation of vars (in one block)
+   list blockvec;             // i-th element = vec of i-th block
+   intvec varvec;             // result intvector
+   list Li;                   // result list of ideals
+   list LM;                   // result list of intmat's
+   intvec v,w,s;              // w valuation vector for one variable
+   matrix C;                  // coefficient matrix for different variables
+   ideal i = simplify(ideal(matrix(id)),10);
+
+//---- for each pii in # create ideal a(ii) intvec v(ii) and list L(ii) -------
+// a(ii) = ideal of vars in product, v(ii)[j]=k <=> a(ii)[j]=var(k)
+
+   v = 1..nvars(basering);
+   int l = size(#);
+   if ( l >= 2 )
+   {
+      ideal m=maxideal(1);
+      for ( ii=2; ii<=l; ii=ii+2 )
+      {
+         int n(ii) = #[ii-1];
+         ideal a(ii);
+         intvec v(ii);
+         for ( jj=1; jj<=nvars(basering); jj++ )
+         {
+            if ( #[ii]/var(jj) != 0)
+            {
+               a(ii) = a(ii) + var(jj);
+               v(ii)=v(ii),jj;
+               m[jj]=0;
+               v[jj]=0;
+            }
+         }
+         v(ii)=v(ii)[2..size(v(ii))];
+      }
+      if ( size(m)!=0 )
+      {
+         l = 2*(l div 2)+2;
+         ideal a(l) = simplify(m,2);
+         intvec v(l) = compress(v);
+         int n(l);
+         if ( size(#)==l-1 ) { n(l) = #[l-1]; }
+      }
+   }
+   else
+   {
+      l = 2;
+      ideal a(2) = maxideal(1);
+      intvec v(2) = v;
+      int n(2);
+      if ( size(#)==1 ) { n(2) = #[1]; }
+   }
+//------------- start loop to order variables in each a(ii) -------------------
+
+   for ( kk=2; kk<=l; kk=kk+2 )
+   {
+      L = list();
+      n = 0;
+//---------------- get valuation of all variables in a(kk) --------------------
+      for ( ii=1; ii<=size(a(kk)); ii++ )
+      {
+         C = coeffs(i,a(kk)[ii]);
+         w = nrows(C); // =(maximal occuring power of a(kk)[ii])+1
+         for ( jj=w[1]; jj>1; jj-- )
+         {
+            s = size(C[jj,1..ncols(C)]);
+            w[w[1]-jj+2] = sum(s);
+         }
+         // w[1] should represent the maximal occuring power of a(kk)[ii] so it
+         // has to be decreased by 1 since otherwise the constant term is also
+         // counted
+         w[1]=w[1]-1;
+
+         L[ii]=w;
+         n = size(w)*(size(w) > n) + n*(size(w) <= n);
+      }
+      intmat M(kk)[size(a(kk))][n];
+      for ( ii=1; ii<=size(a(kk)); ii++ )
+      {
+         if ( n==1 ) { w = L[ii]; M(kk)[ii,1] = w[1]; }
+         else  { M(kk)[ii,1..n] = L[ii]; }
+      }
+      LM[kk-1] = a(kk);
+      LM[kk] = transpose(compress(M(kk)));
+//------------------- compare valuation and insert in vec ---------------------
+      vec = sort(L)[2];
+      if ( n(kk) != 0 ) { vec = vec[size(vec)..1]; }
+      blockvec[kk div 2] = vec;
+      vec = sort(v(kk),vec)[1];
+      varvec = varvec,vec;
+   }
+   varvec = varvec[2..size(varvec)];
+   list result = varvec,blockvec,LM;
+   return(result);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring s=0,(x,y,z,a,b),dp;
+   ideal i=ax2+ay3-b2x,abz+by2;
+   valvars (i,0,xyz);
+}
+///////////////////////////////////////////////////////////////////////////////
+proc idealSplit(ideal I,list #)
+"USAGE:  idealSplit(id,timeF,timeS);  id ideal and optional
+         timeF, timeS integers to bound the time which can be used
+         for factorization resp. standard basis computation
+RETURN:  a list of ideals such that their intersection
+         has the same radical as id
+EXAMPLE: example idealSplit; shows an example
+"
+{
+   option(redSB);
+   int j,k,e;
+   int i=1;
+   int l=attrib(I,"isSB");
+   ideal J;
+   int timeF;
+   int timeS;
+   list re,fac,te;
+
+   if(size(#)==1)
+   {
+     if(typeof(#[1])=="ideal")
+     {
+        re=#;
+     }
+     else
+     {
+       timeF=#[1];
+     }
+   }
+   if(size(#)==2)
+   {
+     if(typeof(#[1])=="list")
+     {
+        re=#[1];
+        timeF=#[2];
+     }
+     else
+     {
+       timeF=#[1];
+       timeS=#[2];
+     }
+   }
+   if(size(#)==3){re=#[1];timeF=#[2];timeS=#[3];}
+
+   fac=timeFactorize(I[1],timeF);
+
+   while((size(fac[1])==2)&&(i<size(I)))
+   {
+      i++;
+      fac=timeFactorize(I[i],timeF);
+   }
+   if(size(fac[1])>2)
+   {
+      for(j=2;j<=size(fac[1]);j++)
+      {
+         I[i]=fac[1][j];
+         attrib(I,"isSB",1);
+         e=1;
+         k=0;
+         while(k<size(re))
+         {
+            k++;
+            if(size(reduce(re[k],I))==0){e=0;break;}
+            attrib(re[k],"isSB",1);
+            if(size(reduce(I,re[k]))==0){re=delete(re,k);k--;}
+         }
+         if(e)
+         {
+            if(l)
+            {
+               J=I;
+               J[i]=0;
+               J=simplify(J,2);
+               attrib(J,"isSB",1);
+               re=idealSplit(std(J,fac[1][j]),re,timeF,timeS);
+            }
+            else
+            {
+               re=idealSplit(timeStd(I,timeS),re,timeF,timeS);
+            }
+         }
+      }
+      return(re);
+   }
+   J=timeStd(I,timeS);
+   attrib(I,"isSB",1);
+   if(size(reduce(J,I))==0){return(re+list(I));}
+   return(re+idealSplit(J,re,timeF,timeS));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r=32003,(b,s,t,u,v,w,x,y,z),dp;
+   ideal i=
+   bv+su,
+   bw+tu,
+   sw+tv,
+   by+sx,
+   bz+tx,
+   sz+ty,
+   uy+vx,
+   uz+wx,
+   vz+wy,
+   bvz;
+   idealSplit(i);
+}
+///////////////////////////////////////////////////////////////////////////////
+proc idealSimplify(ideal J,list #)
+"USAGE:  idealSimplify(id);  id ideal
+RETURN:  ideal I = eliminate(Id,m) m is a product of variables
+         which are only linearly involved in the generators of id
+EXAMPLE: example idealSimplify; shows an example
+"
+{
+   ideal I=J;
+   if(size(#)!=0){I=#[1];}
+   def R=basering;
+   matrix M=jacob(I);
+   ideal ma=maxideal(1);
+   int i,j,k;
+   map phi;
+
+   for(i=1;i<=nrows(M);i++)
+   {
+      for(j=1;j<=ncols(M);j++)
+      {
+         if(deg(M[i,j])==0)
+         {
+            ma[j]=(-1/M[i,j])*(I[i]-M[i,j]*var(j));
+            phi=R,ma;
+            I=phi(I);
+            J=phi(J);
+            for(k=1;k<=ncols(I);k++){I[k]=cleardenom(I[k]);}
+            M=jacob(I);
+         }
+      }
+   }
+   J=simplify(J,2);
+   for(i=1;i<=size(J);i++){J[i]=cleardenom(J[i]);}
+   return(J);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r=0,(x,y,z,w,t),dp;
+   ideal i=
+   t,
+   x3+y2+2z,
+   x2+3y,
+   x2+y2+z2,
+   w2+z;
+   ideal j=idealSimplify(i);
+   ideal k=eliminate(i,zyt);
+   reduce(k,std(j));
+   reduce(j,std(k));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+/*
+
+ ring s=31991,(e,f,x,y,z,t,u,v,w,a,b,c,d),dp;
+ ring s=31991,(x,y,z,t,u,v,w,a,b,c,d,f,e,h),dp; //standard
+ ring s1=31991,(y,u,b,c,a,z,t,x,v,d,w,e,f,h),dp; //gut
+v;
+13,12,11,10,8,7,6,5,4,3,2,1,9,14
+print(matrix(sort(maxideal(1),v)));
+f,e,w,d,x,t,z,a,c,b,u,y,v,h
+print(matrix(maxideal(1)));
+y,u,b,c,a,z,t,x,v,d,w,e,f,h
+v0;
+14,9,12,11,10,8,7,6,5,4,3,2,1,13
+print(matrix(sort(maxideal(1),v0)));
+h,v,e,w,d,x,t,z,a,c,b,u,y,f
+v1;v2;
+9,12,11,10,8,7,6,5,4,3,2,1,13,14
+13,12,11,10,8,7,6,5,4,3,2,1,9,14
+
+Ev. Gute Ordnung fuer i:
+========================
+i=ad*x^d+ad-1*x^(d-1)+...+a1*x+a0, ad!=0
+mit ar=(ar1,...,ark), k=size(i)
+    arj in K[..x^..]
+d=deg_x(i) := max{deg_x(i[k]) | k=1..size(i)}
+size_x(i,deg_x(i)..0) := size(ad),...,size(a0)
+x>y  <==
+  1. deg_x(i)>deg_y(i)
+  2. "=" in 1. und size_x lexikographisch
+
+hier im Beispiel:
+f: 5,1,0,1,2
+
+u: 3,1,4
+
+y: 3,1,3
+b: 3,1,3
+c: 3,1,3
+a: 3,1,3
+z: 3,1,3
+t: 3,1,3
+
+x: 3,1,2
+v: 3,1,2
+d: 3,1,2
+w: 3,1,2
+e: 3,1,2
+probier mal:
+ ring s=31991,(f,u,y,z,t,a,b,c,v,w,d,e,h),dp; //standard
+
+*/
diff --git a/Singular/LIB/primdec.lib b/Singular/LIB/primdec.lib
new file mode 100644
index 0000000..2fc524c
--- /dev/null
+++ b/Singular/LIB/primdec.lib
@@ -0,0 +1,9004 @@
+////////////////////////////////////////////////////////////////////////////
+version="version primdec.lib 4.0.1.1 Nov_2014 "; // $Id: 703f68062c32c476b2d4bcf1a7b7dbc22ddf9007 $
+category="Commutative Algebra";
+info="
+LIBRARY: primdec.lib   Primary Decomposition and Radical of Ideals
+AUTHORS:  Gerhard Pfister, pfister at mathematik.uni-kl.de (GTZ)@*
+          Wolfram Decker, decker at math.uni-sb.de         (SY)@*
+          Hans Schoenemann, hannes at mathematik.uni-kl.de (SY)@*
+          Santiago Laplagne, slaplagn at dm.uba.ar         (GTZ)
+
+OVERVIEW:
+    Algorithms for primary decomposition based on the ideas of
+    Gianni, Trager and Zacharias (implementation by Gerhard Pfister),
+    respectively based on the ideas of Shimoyama and Yokoyama (implementation
+    by Wolfram Decker and Hans Schoenemann).@*
+    The procedures are implemented to be used in characteristic 0.@*
+    They also work in positive characteristic >> 0.@*
+    In small characteristic and for algebraic extensions, primdecGTZ
+    may not terminate.@*
+    Algorithms for the computation of the radical based on the ideas of
+    Krick, Logar, Laplagne and Kemper (implementation by Gerhard Pfister and Santiago Laplagne).
+    They work in any characteristic.@*
+    Baserings must have a global ordering and no quotient ideal.
+    Exceptions: primdecGTZ, absPrimdecGTZ, minAssGTZ, primdecSY, minAssChar, radical accept non-global ordering.
+
+
+PROCEDURES:
+ Ann(M);           annihilator of R^n/M, R=basering, M in R^n
+ primdecGTZ(I);    complete primary decomposition via Gianni,Trager,Zacharias
+ primdecSY(I...);  complete primary decomposition via Shimoyama-Yokoyama
+ minAssGTZ(I);     the minimal associated primes via Gianni,Trager,Zacharias (with modifications by Laplagne)
+ minAssChar(I...); the minimal associated primes using characteristic sets
+ testPrimary(L,k); tests the result of the primary decomposition
+ radical(I);       computes the radical of I via Krick/Logar (with modifications by Laplagne) and Kemper
+ radicalEHV(I);    computes the radical of I via Eisenbud,Huneke,Vasconcelos
+ equiRadical(I);   the radical of the equidimensional part of the ideal I
+ prepareAss(I);    list of radicals of the equidimensional components of I
+ equidim(I);       weak equidimensional decomposition of I
+ equidimMax(I);    equidimensional locus of I
+ equidimMaxEHV(I); equidimensional locus of I via Eisenbud,Huneke,Vasconcelos
+ zerodec(I);       zerodimensional decomposition via Monico
+ absPrimdecGTZ(I); the absolute prime components of I
+ sep(f,k);         the separabel part of f as polynomial in Fp(t1,...,tm)
+";
+
+LIB "general.lib";
+LIB "elim.lib";
+LIB "poly.lib";
+LIB "random.lib";
+LIB "inout.lib";
+LIB "matrix.lib";
+LIB "triang.lib";
+LIB "absfact.lib";
+LIB "ring.lib";
+///////////////////////////////////////////////////////////////////////////////
+//
+//                      Gianni/Trager/Zacharias
+//
+///////////////////////////////////////////////////////////////////////////////
+
+static proc sat1 (ideal id, poly p)
+"USAGE:   sat1(id,j);  id ideal, j polynomial
+RETURN:  saturation of id with respect to j (= union_(k=1...) of id:j^k)
+NOTE:    result is a std basis in the basering
+"
+{
+  ASSUME(1, hasFieldCoefficient(basering) );
+  ASSUME(1, not isQuotientRing(basering) ) ;
+  ASSUME(1, hasGlobalOrdering(basering) ) ;
+
+  int @k;
+  ideal inew=std(id);
+  ideal iold;
+  intvec op=option(get);
+  option(returnSB);
+  while(specialIdealsEqual(iold,inew)==0 )
+  {
+    iold=inew;
+    inew=quotient(iold,p);
+    @k++;
+  }
+  @k--;
+  option(set,op);
+  list L =inew,p^@k;
+  return (L);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static proc sat2 (ideal id, ideal h)
+"USAGE:   sat2(id,j);  id ideal, j polynomial
+RETURN:  saturation of id with respect to j (= union_(k=1...) of id:j^k)
+NOTE:    result is a std basis in the basering
+"
+{
+  ASSUME(1, hasFieldCoefficient(basering) );
+  ASSUME(1, not isQuotientRing(basering) ) ;
+  ASSUME(1, hasGlobalOrdering(basering) ) ;
+  int @k, at i;
+  def @P= basering;
+  if(ordstr(basering)[1,2]!="dp")
+  {
+    def @Phelp=changeordTo(basering,"dp");
+    setring @Phelp;
+    ideal inew=std(imap(@P,id));
+    ideal  @h=imap(@P,h);
+  }
+  else
+  {
+    ideal @h=h;
+    ideal inew=std(id);
+  }
+  ideal fac;
+
+  for(@i=1;@i<=ncols(@h);@i++)
+  {
+    if(deg(@h[@i])>0)
+    {
+      fac=fac+factorize(@h[@i],1);
+    }
+  }
+  fac=simplify(fac,6);
+  poly @f=1;
+  if(deg(fac[1])>0)
+  {
+    ideal iold;
+    for(@i=1;@i<=size(fac);@i++)
+    {
+      @f=@f*fac[@i];
+    }
+    intvec op = option(get);
+    option(returnSB);
+    while(specialIdealsEqual(iold,inew)==0 )
+    {
+      iold=inew;
+      if(deg(iold[size(iold)])!=1)
+      {
+        inew=quotient(iold, at f);
+      }
+      else
+      {
+        inew=iold;
+      }
+      @k++;
+    }
+    option(set,op);
+    @k--;
+  }
+
+  if(ordstr(@P)[1,2]!="dp")
+  {
+    setring @P;
+    ideal inew=std(imap(@Phelp,inew));
+    poly @f=imap(@Phelp, at f);
+  }
+  list L =inew, at f^@k;
+  return (L);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+
+proc minSat(ideal inew, ideal h)
+{
+  ASSUME(0, hasFieldCoefficient(basering) );
+  ASSUME(0, not isQuotientRing(basering) ) ;
+  ASSUME(0, hasGlobalOrdering(basering) ) ;
+  int i,k;
+  poly f=1;
+  ideal iold,fac;
+  list quotM,l;
+
+  for(i=1;i<=ncols(h);i++)
+  {
+    if(deg(h[i])>0)
+    {
+      fac=fac+factorize(h[i],1);
+    }
+  }
+  fac=simplify(fac,6);
+  if(size(fac)==0)
+  {
+    l=inew,1;
+    return(l);
+  }
+  fac=sort(fac)[1];
+  for(i=1;i<=size(fac);i++)
+  {
+    f=f*fac[i];
+  }
+  quotM[1]=inew;
+  quotM[2]=fac;
+  quotM[3]=f;
+  f=1;
+  intvec op = option(get);
+  option(returnSB);
+  while(specialIdealsEqual(iold,quotM[1])==0)
+  {
+    if(k>0)
+    {
+      f=f*quotM[3];
+    }
+    iold=quotM[1];
+    quotM=quotMin(quotM);
+    k++;
+  }
+  option(set,op);
+  l=quotM[1],f;
+  return(l);
+}
+
+static proc quotMin(list tsil)
+{
+  ASSUME(1, hasFieldCoefficient(basering) );
+  ASSUME(1, not isQuotientRing(basering) ) ;
+  ASSUME(1, hasGlobalOrdering(basering) ) ;
+  int i,j,k,action;
+  ideal verg;
+  list l;
+  poly g;
+
+  ideal laedi=tsil[1];
+  ideal fac=tsil[2];
+  poly f=tsil[3];
+
+  ideal star=quotient(laedi,f);
+
+  if(specialIdealsEqual(star,laedi))
+  {
+    l=star,fac,f;
+    return(l);
+  }
+
+  action=1;
+
+  while(action==1)
+  {
+    if(size(fac)==1)
+    {
+      action=0;
+      break;
+    }
+    for(i=1;i<=size(fac);i++)
+    {
+      g=1;
+      verg=laedi;
+      for(j=1;j<=size(fac);j++)
+      {
+        if(i!=j)
+        {
+          g=g*fac[j];
+        }
+      }
+      verg=quotient(laedi,g);
+
+      if(specialIdealsEqual(verg,star)==1)
+      {
+        f=g;
+        fac[i]=0;
+        fac=simplify(fac,2);
+        break;
+      }
+      if(i==size(fac))
+      {
+        action=0;
+      }
+    }
+  }
+  l=star,fac,f;
+  return(l);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static proc testFactor(list act,poly p)
+{
+  ASSUME(1, hasFieldCoefficient(basering) );
+  ASSUME(1, not isQuotientRing(basering) ) ;
+  ASSUME(1, hasGlobalOrdering(basering) ) ;
+  poly keep=p;
+
+  int i;
+  poly q=act[1][1]^act[2][1];
+  for(i=2;i<=size(act[1]);i++)
+  {
+    q=q*act[1][i]^act[2][i];
+  }
+  q=1/leadcoef(q)*q;
+  p=1/leadcoef(p)*p;
+  if(p-q!=0)
+  {
+    "ERROR IN FACTOR, please inform the authors";
+  }
+}
+///////////////////////////////////////////////////////////////////////////////
+
+static proc factor(poly p)
+"USAGE:   factor(p) p poly
+RETURN:  list=;
+NOTE:
+EXAMPLE: example factor; shows an example
+"
+{
+  ASSUME(1, not isQuotientRing(basering) ) ;
+  ASSUME(1, hasGlobalOrdering(basering) ) ;
+  ideal @i;
+  list @l;
+  intvec @v, at w;
+  int @j, at k, at n;
+
+  @l=factorize(p);
+    for(@j=1;@j<=size(@l[1]);@j++)
+    {
+      if(leadcoef(@l[1][@j])==@l[1][@j])
+      {
+        @n++;
+      }
+    }
+    if(@n>0)
+    {
+      if(@n==size(@l[1]))
+      {
+        @l[1]=ideal(1);
+        @v=1;
+        @l[2]=@v;
+      }
+      else
+      {
+        @k=0;
+        int pleh;
+        for(@j=1;@j<=size(@l[1]);@j++)
+        {
+          if(leadcoef(@l[1][@j])!=@l[1][@j])
+          {
+            @k++;
+            @i=@i+ideal(@l[1][@j]);
+            if(size(@i)==pleh)
+            {
+              "//factorization error";
+              @l;
+              @k--;
+              @v[@k]=@v[@k]+ at l[2][@j];
+            }
+            else
+            {
+              pleh++;
+              @v[@k]=@l[2][@j];
+            }
+          }
+        }
+        @l[1]=@i;
+        @l[2]=@v;
+      }
+    }
+    // }
+  return(@l);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring  r = 0,(x,y,z),lp;
+   poly  p = (x+y)^2*(y-z)^3;
+   list  l = factor(p);
+   l;
+   ring r1 =(0,b,d,f,g),(a,c,e),lp;
+   poly p  =(1*d)*e^2+(1*d*f^2*g);
+   list  l = factor(p);
+   l;
+   ring r2 =(0,b,f,g),(a,c,e,d),lp;
+   poly p  =(1*d)*e^2+(1*d*f^2*g);
+   list  l = factor(p);
+   l;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc idealsEqual( ideal k, ideal j)
+{
+  return(stdIdealsEqual(std(k),std(j)));
+}
+
+static proc specialIdealsEqual( ideal k1, ideal k2)
+{
+  int j;
+
+  if(size(k1)==size(k2))
+  {
+    for(j=1;j<=size(k1);j++)
+    {
+      if(leadexp(k1[j])!=leadexp(k2[j]))
+      {
+        return(0);
+      }
+    }
+    return(1);
+  }
+  return(0);
+}
+
+static proc stdIdealsEqual( ideal k1, ideal k2)
+{
+  int j;
+  if(size(k1)==size(k2))
+  {
+    for(j=1;j<=size(k1);j++)
+    {
+      if(leadexp(k1[j])!=leadexp(k2[j]))
+      {
+        return(0);
+      }
+    }
+    attrib(k2,"isSB",1);
+    if(size(reduce(k1,k2,1))==0)
+    {
+      return(1);
+    }
+  }
+  return(0);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc primaryTest (ideal i, poly p)
+{
+  ASSUME(0, hasFieldCoefficient(basering) );
+  ASSUME(0, not isQuotientRing(basering) ) ;
+  ASSUME(0, hasGlobalOrdering(basering) ) ;
+  if(i[1]==1){return(ideal(1));}
+  int m=1;
+  int n=nvars(basering);
+  int e,f;
+  poly t;
+  ideal h;
+  list act;
+
+  ideal prm=p;
+  attrib(prm,"isSB",1);
+
+  while (n>1)
+  {
+    n--;
+    m++;
+
+    //search for i[m] which has a power of var(n) as leading term
+    if (n==1)
+    {
+      m=size(i);
+    }
+    else
+    {
+      while (lead(i[m])/var(n-1)==0)
+      {
+        m++;
+      }
+      m--;
+    }
+    //check whether i[m] =(c*var(n)+h)^e modulo prm for some
+    //h in K[var(n+1),...,var(nvars(basering))], c in K
+    //if not (0) is returned, else var(n)+h is added to prm
+
+    e=deg(lead(i[m]));
+    if(char(basering)!=0)
+    {
+      f=1;
+      if(e mod char(basering)==0)
+      {
+        if ( voice >=15 )
+        {
+          "// WARNING: The characteristic is perhaps too small to use";
+          "// the algorithm of Gianni/Trager/Zacharias.";
+          "// This may result in an infinte loop";
+          "// loop in primaryTest, voice:",voice;"";
+        }
+        while(e mod char(basering)==0)
+        {
+          f=f*char(basering);
+          e=e div char(basering);
+        }
+      }
+      t=leadcoef(i[m])*e*var(n)^f+(i[m]-lead(i[m]))/var(n)^((e-1)*f);
+      i[m]=poly(e)^e*leadcoef(i[m])^(e-1)*i[m];
+      if (reduce(i[m]-t^e,prm,1) !=0)
+      {
+        return(ideal(0));
+      }
+      if(f>1)
+      {
+        act=factorize(t);
+        if(size(act[1])>2)
+        {
+          return(ideal(0));
+        }
+        if(deg(act[1][2])>1)
+        {
+          return(ideal(0));
+        }
+        t=act[1][2];
+      }
+    }
+    else
+    {
+      t=leadcoef(i[m])*e*var(n)+(i[m]-lead(i[m]))/var(n)^(e-1);
+      i[m]=poly(e)^e*leadcoef(i[m])^(e-1)*i[m];
+      if (reduce(i[m]-t^e,prm,1) !=0)
+      {
+        return(ideal(0));
+      }
+    }
+
+    h=interred(t);
+    t=h[1];
+
+    prm = prm,t;
+    attrib(prm,"isSB",1);
+  }
+  return(prm);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+proc gcdTest(ideal act)
+{
+  ASSUME(0, not isQuotientRing(basering) ) ;
+  ASSUME(0, hasGlobalOrdering(basering) ) ;
+  int i,j;
+  if(size(act)<=1)
+  {
+    return(0);
+  }
+  for (i=1;i<size(act);i++)
+  {
+    for(j=i+1;j<=size(act);j++)
+    {
+      if(deg(std(ideal(act[i],act[j]))[1])>0)
+      {
+        return(0);
+      }
+    }
+  }
+  return(1);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static proc splitPrimary(list l,ideal ser,int @wr,list sact)
+{
+  ASSUME(1, hasFieldCoefficient(basering) );
+  ASSUME(1, not isQuotientRing(basering) ) ;
+  ASSUME(1, hasGlobalOrdering(basering) ) ;
+  int i,j,k,s,r,w;
+  list keepresult,act,keepprime;
+  poly @f;
+  int sl=size(l);
+  for(i=sl div 2;i>=1;i--)
+  {
+    if(sact[2][i]>1)
+    {
+      keepprime[i]=l[2*i-1]+ideal(sact[1][i]);
+    }
+    else
+    {
+      keepprime[i]=l[2*i-1];
+    }
+  }
+  i=0;
+  while(i<size(l) div 2)
+  {
+    i++;
+    if((size(ser)>0)&&(size(reduce(ser,l[2*i-1],1))==0))
+    {
+      l[2*i-1]=ideal(1);
+      l[2*i]=ideal(1);
+      continue;
+    }
+
+    if(size(l[2*i])==0)
+    {
+      if(homog(l[2*i-1])==1)
+      {
+        l[2*i]=maxideal(1);
+        continue;
+      }
+      j=0;
+/*
+      if(i<=sl div 2)
+      {
+        j=1;
+      }
+*/
+      while(j<size(l[2*i-1]))
+      {
+        j++;
+        act=factor(l[2*i-1][j]);
+        r=size(act[1]);
+        attrib(l[2*i-1],"isSB",1);
+        if((r==1)&&(vdim(l[2*i-1])==deg(l[2*i-1][j])))
+        {
+          l[2*i]=std(l[2*i-1],act[1][1]);
+          break;
+        }
+        if((r==1)&&(act[2][1]>1))
+        {
+          keepprime[i]=interred(keepprime[i]+ideal(act[1][1]));
+          if(homog(keepprime[i])==1)
+          {
+            l[2*i]=maxideal(1);
+            break;
+          }
+        }
+        if(gcdTest(act[1])==1)
+        {
+          for(k=2;k<=r;k++)
+          {
+            keepprime[size(l) div 2+k-1]=interred(keepprime[i]+ideal(act[1][k]));
+          }
+          keepprime[i]=interred(keepprime[i]+ideal(act[1][1]));
+          for(k=1;k<=r;k++)
+          {
+            if(@wr==0)
+            {
+              keepresult[k]=std(l[2*i-1],act[1][k]^act[2][k]);
+            }
+            else
+            {
+              keepresult[k]=std(l[2*i-1],act[1][k]);
+            }
+          }
+          l[2*i-1]=keepresult[1];
+          if(vdim(keepresult[1])==deg(act[1][1]))
+          {
+            l[2*i]=keepresult[1];
+          }
+          if((homog(keepresult[1])==1)||(homog(keepprime[i])==1))
+          {
+            l[2*i]=maxideal(1);
+          }
+          s=size(l)-2;
+          for(k=2;k<=r;k++)
+          {
+            l[s+2*k-1]=keepresult[k];
+            keepprime[s div 2+k]=interred(keepresult[k]+ideal(act[1][k]));
+            if(vdim(keepresult[k])==deg(act[1][k]))
+            {
+              l[s+2*k]=keepresult[k];
+            }
+            else
+            {
+              l[s+2*k]=ideal(0);
+            }
+            if((homog(keepresult[k])==1)||(homog(keepprime[s div 2+k])==1))
+            {
+              l[s+2*k]=maxideal(1);
+            }
+          }
+          i--;
+          break;
+        }
+        if(r>=2)
+        {
+          s=size(l);
+          @f=act[1][1];
+          act=sat1(l[2*i-1],act[1][1]);
+          if(deg(act[1][1])>0)
+          {
+            l[s+1]=std(l[2*i-1],act[2]);
+            if(homog(l[s+1])==1)
+            {
+              l[s+2]=maxideal(1);
+            }
+            else
+            {
+              l[s+2]=ideal(0);
+            }
+            keepprime[s div 2+1]=interred(keepprime[i]+ideal(@f));
+            if(homog(keepprime[s div 2+1])==1)
+            {
+              l[s+2]=maxideal(1);
+            }
+            keepprime[i]=act[1];
+            l[2*i-1]=act[1];
+            attrib(l[2*i-1],"isSB",1);
+            if(homog(l[2*i-1])==1)
+            {
+              l[2*i]=maxideal(1);
+            }
+            i--;
+            break;
+          }
+        }
+      }
+    }
+  }
+  if(sl==size(l))
+  {
+    return(l);
+  }
+  for(i=1;i<=size(l) div 2;i++)
+  {
+    attrib(l[2*i-1],"isSB",1);
+
+    if((size(ser)>0)&&(size(reduce(ser,l[2*i-1],1))==0)&&(deg(l[2*i-1][1])>0))
+    {
+      "Achtung in split";
+
+      l[2*i-1]=ideal(1);
+      l[2*i]=ideal(1);
+    }
+    if((size(l[2*i])==0)&&(specialIdealsEqual(keepprime[i],l[2*i-1])!=1))
+    {
+      keepprime[i]=std(keepprime[i]);
+      if(homog(keepprime[i])==1)
+      {
+        l[2*i]=maxideal(1);
+      }
+      else
+      {
+        act=zero_decomp(keepprime[i],ideal(0), at wr,1);
+        if(size(act)==2)
+        {
+          l[2*i]=act[2];
+        }
+      }
+    }
+  }
+  return(l);
+}
+example
+{ "EXAMPLE:"; echo=2;
+   ring  r = 32003,(x,y,z),lp;
+   ideal i1=x*(x+1),yz,(z+1)*(z-1);
+   ideal i2=xy,yz,(x-2)*(x+3);
+   list l=i1,ideal(0),i2,ideal(0),i2,ideal(1);
+   list l1=splitPrimary(l,ideal(0),0);
+   l1;
+}
+///////////////////////////////////////////////////////////////////////////////
+static proc splitCharp(list l)
+{
+  ASSUME(1, hasFieldCoefficient(basering) );
+  ASSUME(1, not isQuotientRing(basering) ) ;
+  ASSUME(1, hasGlobalOrdering(basering) ) ;
+  if((char(basering)==0)||(npars(basering)>0))
+  {
+    return(l);
+  }
+  def op = option(get);
+  def P=basering;
+  int i,j,k,m,q,d,o;
+  int n = nvars(basering);
+  ideal s,t,u,sact;
+  poly ni;
+  string minp,gnir,va;
+  list sa,keep,rp,keep1;
+  for(i=1;i<=size(l) div 2;i++)
+  {
+    if(size(l[2*i])==0)
+    {
+      if(deg(l[2*i-1][1])==vdim(l[2*i-1]))
+      {
+        l[2*i]=l[2*i-1];
+      }
+    }
+  }
+  for(i=1;i<=size(l) div 2;i++)
+  {
+    if(size(l[2*i])==0)
+    {
+      s=factorize(l[2*i-1][1],1);   //vermeiden!!!
+      t=l[2*i-1];
+      m=size(t);
+      ni=s[1];
+      if(deg(ni)>1)
+      {
+        va=varstr(P);
+        j=size(va);
+        while(va[j]!=","){j--;}
+        va=va[1..j-1];
+        gnir="ring RL=("+string(char(P))+","+string(var(n))+"),("+va+"),lp;";
+        execute(gnir);
+        minpoly=leadcoef(imap(P,ni));
+        ideal act;
+        ideal t=imap(P,t);
+
+        for(k=2;k<=m;k++)
+        {
+          act=factorize(t[k],1);
+          if(size(act)>1){break;}
+        }
+        setring P;
+        sact=imap(RL,act);
+
+        if(size(sact)>1)
+        {
+          sa=sat1(l[2*i-1],sact[1]);
+          keep[size(keep)+1]=std(l[2*i-1],sa[2]);
+          if(sa[1][1]==l[2*i-1][1])
+          {
+             l[2*i-1]=std(sa[1]);
+             l[2*i]=primaryTest(sa[1],s[1]);
+          }
+          else
+          {
+             l[2*i-1]=std(sa[1]);
+             l[2*i]=primaryTest(sa[1],factorize(sa[1][1],1)[1]);
+          }
+        }
+        if((size(sact)==1)&&(m==2))
+        {
+          l[2*i]=l[2*i-1];
+          attrib(l[2*i],"isSB",1);
+        }
+        if((size(sact)==1)&&(m>2))
+        {
+          setring RL;
+
+          option(redSB);
+          t=std(t);
+
+          list sp=zero_decomp(t,0,0);
+
+          setring P;
+          rp=imap(RL,sp);
+          for(o=1;o<=size(rp);o++)
+          {
+            rp[o]=interred(simplify(rp[o],1)+ideal(ni));
+          }
+          l[2*i-1]=rp[1];
+          l[2*i]=rp[2];
+          rp=delete(rp,1);
+          rp=delete(rp,1);
+          keep1=keep1+rp;
+
+          option(set,op);
+        }
+        kill RL;
+      }
+    }
+  }
+  if(size(keep)>0)
+  {
+    for(i=1;i<=size(keep);i++)
+    {
+      if(deg(keep[i][1])>0)
+      {
+        l[size(l)+1]=keep[i];
+        l[size(l)+1]=primaryTest(keep[i],factorize(keep[i][1],1)[1]);
+      }
+    }
+  }
+  l=l+keep1;
+  option(set,op);
+  return(l);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc zero_decomp (ideal j,ideal ser,int @wr,list #)
+"USAGE:   zero_decomp(j,ser, at wr); j,ser ideals, @wr=0 or 1
+         (@wr=0 for primary decomposition, @wr=1 for computation of associated
+         primes)
+RETURN:  list = list of primary ideals and their radicals (at even positions
+         in the list) if the input is zero-dimensional and a standardbases
+         with respect to lex-ordering
+         If ser!=(0) and ser is contained in j or if j is not zero-dimen-
+         sional then ideal(1),ideal(1) is returned
+NOTE:    Algorithm of Gianni/Trager/Zacharias
+EXAMPLE: example zero_decomp; shows an example
+"
+{
+  ASSUME(0, hasFieldCoefficient(basering) );
+  ASSUME(0, not isQuotientRing(basering) ) ;
+  ASSUME(0, hasGlobalOrdering(basering) ) ;
+
+  def   @P = basering;
+  int uytrewq;
+  int nva = nvars(basering);
+  int @k, at s, at n, at k1,zz;
+  list primary,lres0,lres1,act, at lh, at wh;
+  map phi,psi,phi1,psi1;
+  ideal jmap,jmap1,jmap2,helpprim, at qh, at qht,ser1;
+  intvec @vh, at hilb;
+  string @ri;
+  poly @f;
+  if (dim(j)>0)
+  {
+    primary[1]=ideal(1);
+    primary[2]=ideal(1);
+    return(primary);
+  }
+  intvec save=option(get);
+  option(redSB);
+  j=interred(j);
+
+  attrib(j,"isSB",1);
+
+  if(vdim(j)==deg(j[1]))
+  {
+    act=factor(j[1]);
+    for(@k=1;@k<=size(act[1]);@k++)
+    {
+      @qh=j;
+      if(@wr==0)
+      {
+        @qh[1]=act[1][@k]^act[2][@k];
+      }
+      else
+      {
+        @qh[1]=act[1][@k];
+      }
+      primary[2*@k-1]=interred(@qh);
+      @qh=j;
+      @qh[1]=act[1][@k];
+      primary[2*@k]=interred(@qh);
+      attrib( primary[2*@k-1],"isSB",1);
+
+      if((size(ser)>0)&&(size(reduce(ser,primary[2*@k-1],1))==0))
+      {
+        primary[2*@k-1]=ideal(1);
+        primary[2*@k]=ideal(1);
+      }
+    }
+    option(set,save);
+    return(primary);
+  }
+
+  option(set,save);
+  if(homog(j)==1)
+  {
+    primary[1]=j;
+    if((size(ser)>0)&&(size(reduce(ser,j,1))==0))
+    {
+      primary[1]=ideal(1);
+      primary[2]=ideal(1);
+      return(primary);
+    }
+    if(dim(j)==-1)
+    {
+      primary[1]=ideal(1);
+      primary[2]=ideal(1);
+    }
+    else
+    {
+      primary[2]=maxideal(1);
+    }
+    return(primary);
+  }
+
+//the first element in the standardbase is factorized
+  if(deg(j[1])>0)
+  {
+    act=factor(j[1]);
+    testFactor(act,j[1]);
+  }
+  else
+  {
+    primary[1]=ideal(1);
+    primary[2]=ideal(1);
+    return(primary);
+  }
+
+//with the factors new ideals (hopefully the primary decomposition)
+//are created
+  if(size(act[1])>1)
+  {
+    if(size(#)>1)
+    {
+      primary[1]=ideal(1);
+      primary[2]=ideal(1);
+      primary[3]=ideal(1);
+      primary[4]=ideal(1);
+      return(primary);
+    }
+    for(@k=1;@k<=size(act[1]);@k++)
+    {
+      if(@wr==0)
+      {
+        primary[2*@k-1]=std(j,act[1][@k]^act[2][@k]);
+      }
+      else
+      {
+        primary[2*@k-1]=std(j,act[1][@k]);
+      }
+      if((act[2][@k]==1)&&(vdim(primary[2*@k-1])==deg(act[1][@k])))
+      {
+        primary[2*@k]   = primary[2*@k-1];
+      }
+      else
+      {
+        primary[2*@k]   = primaryTest(primary[2*@k-1],act[1][@k]);
+      }
+    }
+  }
+  else
+  {
+    primary[1]=j;
+    if((size(#)>0)&&(act[2][1]>1))
+    {
+      act[2]=1;
+      primary[1]=std(primary[1],act[1][1]);
+    }
+    if(@wr!=0)
+    {
+      primary[1]=std(j,act[1][1]);
+    }
+    if((act[2][1]==1)&&(vdim(primary[1])==deg(act[1][1])))
+    {
+      primary[2]=primary[1];
+    }
+    else
+    {
+      primary[2]=primaryTest(primary[1],act[1][1]);
+    }
+  }
+
+  if(size(#)==0)
+  {
+    primary=splitPrimary(primary,ser, at wr,act);
+  }
+
+  if((voice>=6)&&(char(basering)<=181))
+  {
+    primary=splitCharp(primary);
+  }
+
+  if((@wr==2)&&(npars(basering)>0)&&(voice>=6)&&(char(basering)>0))
+  {
+  //the prime decomposition of Yokoyama in characteristic p
+    list ke,ek;
+    @k=0;
+    while(@k<size(primary) div 2)
+    {
+      @k++;
+      if(size(primary[2*@k])==0)
+      {
+        ek=insepDecomp(primary[2*@k-1]);
+        primary=delete(primary,2*@k);
+        primary=delete(primary,2*@k-1);
+        @k--;
+      }
+      ke=ke+ek;
+    }
+    for(@k=1;@k<=size(ke);@k++)
+    {
+      primary[size(primary)+1]=ke[@k];
+      primary[size(primary)+1]=ke[@k];
+    }
+  }
+
+  if(voice>=8){primary=extF(primary);};
+
+//test whether all ideals in the decomposition are primary and
+//in general position
+//if not after a random coordinate transformation of the last
+//variable the corresponding ideal is decomposed again.
+  if((npars(basering)>0)&&(voice>=8))
+  {
+    poly randp;
+    for(zz=1;zz<nvars(basering);zz++)
+    {
+      randp=randp
+              +(random(0,5)*par(1)^2+random(0,5)*par(1)+random(0,5))*var(zz);
+    }
+    randp=randp+var(nvars(basering));
+  }
+  @k=0;
+  while(@k<(size(primary) div 2))
+  {
+    @k++;
+    if (size(primary[2*@k])==0)
+    {
+      for(zz=1;zz<size(primary[2*@k-1])-1;zz++)
+      {
+        attrib(primary[2*@k-1],"isSB",1);
+        if(vdim(primary[2*@k-1])==deg(primary[2*@k-1][zz]))
+        {
+          primary[2*@k]=primary[2*@k-1];
+        }
+      }
+    }
+  }
+
+  @k=0;
+  ideal keep;
+  while(@k<(size(primary) div 2))
+  {
+    @k++;
+    if (size(primary[2*@k])==0)
+    {
+      jmap=randomLast(100);
+      jmap1=maxideal(1);
+      jmap2=maxideal(1);
+      @qht=primary[2*@k-1];
+      if((npars(basering)>0)&&(voice>=10))
+      {
+        jmap[size(jmap)]=randp;
+      }
+
+      for(@n=2;@n<=size(primary[2*@k-1]);@n++)
+      {
+        if(deg(lead(primary[2*@k-1][@n]))==1)
+        {
+          for(zz=1;zz<=nva;zz++)
+          {
+            if(lead(primary[2*@k-1][@n])/var(zz)!=0)
+            {
+              jmap1[zz]=-1/leadcoef(primary[2*@k-1][@n])*primary[2*@k-1][@n]
+                   +2/leadcoef(primary[2*@k-1][@n])*lead(primary[2*@k-1][@n]);
+              jmap2[zz]=primary[2*@k-1][@n];
+              @qht[@n]=var(zz);
+            }
+          }
+          jmap[nva]=subst(jmap[nva],lead(primary[2*@k-1][@n]),0);
+        }
+      }
+      if(size(subst(jmap[nva],var(1),0)-var(nva))!=0)
+      {
+        // jmap[nva]=subst(jmap[nva],var(1),0);
+        //hier geaendert +untersuchen!!!!!!!!!!!!!!
+      }
+      phi1=@P,jmap1;
+      phi=@P,jmap;
+      for(@n=1;@n<=nva;@n++)
+      {
+        jmap[@n]=-(jmap[@n]-2*var(@n));
+      }
+      psi=@P,jmap;
+      psi1=@P,jmap2;
+      @qh=phi(@qht);
+
+//=================== the new part ============================
+
+      if (npars(basering)>1) { @qh=groebner(@qh,"par2var"); }
+      else                   { @qh=groebner(@qh); }
+
+//=============================================================
+//       if(npars(@P)>0)
+//       {
+//          @ri= "ring @Phelp ="
+//                  +string(char(@P))+",
+//                   ("+varstr(@P)+","+parstr(@P)+", at t),(C,dp);";
+//       }
+//       else
+//       {
+//          @ri= "ring @Phelp ="
+//                  +string(char(@P))+",("+varstr(@P)+", at t),(C,dp);";
+//       }
+//       execute(@ri);
+//       ideal @qh=homog(imap(@P, at qht), at t);
+//
+//       ideal @qh1=std(@qh);
+//       @hilb=hilb(@qh1,1);
+//       @ri= "ring @Phelp1 ="
+//                  +string(char(@P))+",("+varstr(@Phelp)+"),(C,lp);";
+//       execute(@ri);
+//       ideal @qh=homog(imap(@P, at qh), at t);
+//       kill @Phelp;
+//       @qh=std(@qh, at hilb);
+//       @qh=subst(@qh, at t,1);
+//       setring @P;
+//       @qh=imap(@Phelp1, at qh);
+//       kill @Phelp1;
+//       @qh=clearSB(@qh);
+//       attrib(@qh,"isSB",1);
+//=============================================================
+
+      ser1=phi1(ser);
+      @lh=zero_decomp (@qh,phi(ser1), at wr);
+
+      kill lres0;
+      list lres0;
+      if((size(@lh)==2)&&(@lh[1]!=1))
+      {
+        helpprim=@lh[2];
+        lres0[1]=primary[2*@k-1];
+        attrib(lres0[1],"isSB",1);
+        ser1=psi(helpprim);
+        lres0[2]=psi1(ser1);
+        if(size(reduce(lres0[2],lres0[1],1))==0)
+        {
+          primary[2*@k]=primary[2*@k-1];
+          continue;
+        }
+      }
+      else
+      {
+        lres1=psi(@lh);
+        lres0=psi1(lres1);
+      }
+
+//=================== the new part ============================
+
+      primary=delete(primary,2*@k-1);
+      primary=delete(primary,2*@k-1);
+      @k--;
+      if(size(lres0)==2)
+      {
+        lres0[2]=groebner(lres0[2]);
+      }
+      else
+      {
+        for(@n=1;@n<=size(lres0) div 2;@n++)
+        {
+          if(specialIdealsEqual(lres0[2*@n-1],lres0[2*@n])==1)
+          {
+            lres0[2*@n-1]=groebner(lres0[2*@n-1]);
+            lres0[2*@n]=lres0[2*@n-1];
+            attrib(lres0[2*@n],"isSB",1);
+          }
+          else
+          {
+            lres0[2*@n-1]=groebner(lres0[2*@n-1]);
+            lres0[2*@n]=groebner(lres0[2*@n]);
+          }
+        }
+      }
+      primary=primary+lres0;
+
+//=============================================================
+//       if(npars(@P)>0)
+//       {
+//          @ri= "ring @Phelp ="
+//                  +string(char(@P))+",
+//                   ("+varstr(@P)+","+parstr(@P)+", at t),(C,dp);";
+//       }
+//       else
+//       {
+//          @ri= "ring @Phelp ="
+//                  +string(char(@P))+",("+varstr(@P)+", at t),(C,dp);";
+//       }
+//       execute(@ri);
+//       list @lvec;
+//       list @lr=imap(@P,lres0);
+//       ideal @lr1;
+//
+//       if(size(@lr)==2)
+//       {
+//          @lr[2]=homog(@lr[2], at t);
+//          @lr1=std(@lr[2]);
+//          @lvec[2]=hilb(@lr1,1);
+//       }
+//       else
+//       {
+//          for(@n=1;@n<=size(@lr) div 2;@n++)
+//          {
+//             if(specialIdealsEqual(@lr[2*@n-1], at lr[2*@n])==1)
+//             {
+//                @lr[2*@n-1]=homog(@lr[2*@n-1], at t);
+//                @lr1=std(@lr[2*@n-1]);
+//                @lvec[2*@n-1]=hilb(@lr1,1);
+//                @lvec[2*@n]=@lvec[2*@n-1];
+//             }
+//             else
+//             {
+//                @lr[2*@n-1]=homog(@lr[2*@n-1], at t);
+//                @lr1=std(@lr[2*@n-1]);
+//                @lvec[2*@n-1]=hilb(@lr1,1);
+//                @lr[2*@n]=homog(@lr[2*@n], at t);
+//                @lr1=std(@lr[2*@n]);
+//                @lvec[2*@n]=hilb(@lr1,1);
+//
+//             }
+//         }
+//       }
+//       @ri= "ring @Phelp1 ="
+//                  +string(char(@P))+",("+varstr(@Phelp)+"),(C,lp);";
+//       execute(@ri);
+//       list @lr=imap(@Phelp, at lr);
+//
+//       kill @Phelp;
+//       if(size(@lr)==2)
+//      {
+//          @lr[2]=std(@lr[2], at lvec[2]);
+//          @lr[2]=subst(@lr[2], at t,1);
+//       }
+//       else
+//       {
+//          for(@n=1;@n<=size(@lr) div 2;@n++)
+//          {
+//             if(specialIdealsEqual(@lr[2*@n-1], at lr[2*@n])==1)
+//             {
+//                @lr[2*@n-1]=std(@lr[2*@n-1], at lvec[2*@n-1]);
+//                @lr[2*@n-1]=subst(@lr[2*@n-1], at t,1);
+//                @lr[2*@n]=@lr[2*@n-1];
+//                attrib(@lr[2*@n],"isSB",1);
+//             }
+//             else
+//             {
+//                @lr[2*@n-1]=std(@lr[2*@n-1], at lvec[2*@n-1]);
+//                @lr[2*@n-1]=subst(@lr[2*@n-1], at t,1);
+//                @lr[2*@n]=std(@lr[2*@n], at lvec[2*@n]);
+//                @lr[2*@n]=subst(@lr[2*@n], at t,1);
+//             }
+//          }
+//       }
+//       kill @lvec;
+//       setring @P;
+//       lres0=imap(@Phelp1, at lr);
+//       kill @Phelp1;
+//       for(@n=1;@n<=size(lres0);@n++)
+//       {
+//          lres0[@n]=clearSB(lres0[@n]);
+//          attrib(lres0[@n],"isSB",1);
+//       }
+//
+//       primary[2*@k-1]=lres0[1];
+//       primary[2*@k]=lres0[2];
+//       @s=size(primary) div 2;
+//       for(@n=1;@n<=size(lres0) div 2-1;@n++)
+//       {
+//         primary[2*@s+2*@n-1]=lres0[2*@n+1];
+//         primary[2*@s+2*@n]=lres0[2*@n+2];
+//       }
+//       @k--;
+//=============================================================
+    }
+  }
+  return(primary);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring  r = 0,(x,y,z),lp;
+   poly  p = z2+1;
+   poly  q = z4+2;
+   ideal i = p^2*q^3,(y-z3)^3,(x-yz+z4)^4;
+   i=std(i);
+   list  pr= zero_decomp(i,ideal(0),0);
+   pr;
+}
+///////////////////////////////////////////////////////////////////////////////
+proc extF(list l,list #)
+{
+  ASSUME(0, hasFieldCoefficient(basering) );
+  ASSUME(0, not isQuotientRing(basering) ) ;
+  ASSUME(0, hasGlobalOrdering(basering) ) ;
+//zero_dimensional primary decomposition after finite field extension
+  def R=basering;
+  int p=char(R);
+
+  if((p==0)||(p>13)||(npars(R)>0)){return(l);}
+
+  int ex=3;
+  if(size(#)>0){ex=#[1];}
+
+  list peek,peek1;
+  while(size(l)>0)
+  {
+    if(size(l[2])==0)
+    {
+      peek[size(peek)+1]=l[1];
+    }
+    else
+    {
+      peek1[size(peek1)+1]=l[1];
+      peek1[size(peek1)+1]=l[2];
+    }
+    l=delete(l,1);
+    l=delete(l,1);
+  }
+  if(size(peek)==0){return(peek1);}
+
+  string gnir="ring RH=("+string(p)+"^"+string(ex)+",a),("+varstr(R)+"),lp;";
+  execute(gnir);
+  string mp="minpoly="+string(minpoly)+";";
+  gnir="ring RL=("+string(p)+",a),("+varstr(R)+"),lp;";
+  execute(gnir);
+  execute(mp);
+  list L=imap(R,peek);
+  list pr, keep;
+  int i;
+  for(i=1;i<=size(L);i++)
+  {
+    attrib(L[i],"isSB",1);
+    pr=zero_decomp(L[i],0,0);
+    keep=keep+pr;
+  }
+  for(i=1;i<=size(keep);i++)
+  {
+    keep[i]=simplify(keep[i],1);
+  }
+  mp="poly pp="+string(minpoly)+";";
+
+  string gnir1="ring RS="+string(p)+",("+varstr(R)+",a),lp;";
+  execute(gnir1);
+  execute(mp);
+  list L=imap(RL,keep);
+
+  for(i=1;i<=size(L);i++)
+  {
+    L[i]=eliminate(L[i]+ideal(pp),a);
+  }
+  i=0;
+  int j;
+  while(i<size(L) div 2-1)
+  {
+    i++;
+    j=i;
+    while(j<size(L) div 2)
+    {
+      j++;
+      if(idealsEqual(L[2*i-1],L[2*j-1]))
+      {
+        L=delete(L,2*j-1);
+        L=delete(L,2*j-1);
+        j--;
+      }
+    }
+  }
+  setring R;
+  list re=imap(RS,L);
+  re=re+peek1;
+
+  return(extF(re,ex+1));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+proc zeroSp(ideal i)
+{
+//preparation for the separable closure
+//decomposition into ideals of special type
+//i.e. the minimal polynomials of every variable mod i are irreducible
+//returns a list of 2 lists: rr=pe,qe
+//the ideals in pe[l] are special, their special elements are in qe[l]
+//pe[l] is a dp-Groebnerbasis
+//the radical of the intersection of the pe[l] is equal to the radical of i
+
+  ASSUME(0, hasFieldCoefficient(basering) );
+  ASSUME(0, not isQuotientRing(basering) ) ;
+  ASSUME(0, hasGlobalOrdering(basering) ) ;
+  def R=basering;
+
+  //i has to be a reduced groebner basis
+  ASSUME(1, dim(i)==0);
+  ideal F=finduni(i);
+
+  int j,k,l,ready;
+  list fa;
+  fa[1]=factorize(F[1],1);
+  poly te,ti;
+  ideal tj;
+  //avoid factorization of the same polynomial
+  for(j=2;j<=size(F);j++)
+  {
+    for(k=1;k<j;k++)
+    {
+      ti=F[k];
+      te=subst(ti,var(k),var(j));
+      if(te==F[j])
+      {
+        tj=fa[k];
+        fa[j]=subst(tj,var(k),var(j));
+        ready=1;
+        break;
+      }
+    }
+    if(!ready)
+    {
+      fa[j]=factorize(F[j],1);
+    }
+    ready=0;
+  }
+  def P=changeordTo(R,"dp");
+  setring P;
+  ideal i=imap(R,i);
+  if(npars(basering)==0)
+  {
+    ideal J=fglm(R,i);
+  }
+  else
+  {
+    ideal J=groebner(i);
+  }
+  list fa=imap(R,fa);
+  list qe=J;          //collects a dp-Groebnerbasis of the special ideals
+  list keep=ideal(0); //collects the special elements
+
+  list re,em,ke;
+  ideal K,L;
+
+  for(j=1;j<=nvars(basering);j++)
+  {
+    for(l=1;l<=size(qe);l++)
+    {
+      for(k=1;k<=size(fa[j]);k++)
+      {
+        L=std(qe[l],fa[j][k]);
+        K=keep[l],fa[j][k];
+        if(deg(L[1])>0)
+        {
+          re[size(re)+1]=L;
+          ke[size(ke)+1]=K;
+        }
+      }
+    }
+    qe=re;
+    re=em;
+    keep=ke;
+    ke=em;
+  }
+
+  setring R;
+  list qe=imap(P,keep);
+  list pe=imap(P,qe);
+  for(l=1;l<=size(qe);l++)
+  {
+    qe[l]=simplify(qe[l],2);
+  }
+  list rr=pe,qe;
+  return(rr);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc zeroSepClos(ideal I,ideal F)
+{
+//computes the separable closure of the special ideal I
+//F is the set of special elements of I
+//returns the separable closure sc(I) of I and an intvec v
+//such that sc(I)=preimage(frobenius definde by v)
+//i.e. var(i)----->var(i)^(p^v[i])
+
+  ASSUME(0, hasFieldCoefficient(basering) );
+  ASSUME(0, not isQuotientRing(basering) ) ;
+  ASSUME(0, hasGlobalOrdering(basering) ) ;
+
+  if(homog(I)==1){return(maxideal(1));}
+
+  //assume F[i] irreducible in I and depending only on var(i)
+
+  def R=basering;
+  int n=nvars(R);
+  int p=char(R);
+  intvec v;
+  v[n]=0;
+  int i,k;
+  list l;
+
+  for(i=1;i<=n;i++)
+  {
+    l[i]=sep(F[i],i);
+    F[i]=l[i][1];
+    if(l[i][2]>k){k=l[i][2];}
+  }
+
+  if(k==0){return(list(I,v));}        //the separable case
+  ideal m;
+
+  for(i=1;i<=n;i++)
+  {
+    m[i]=var(i)^(p^l[i][2]);
+    v[i]=l[i][2];
+  }
+  map phi=R,m;
+  ideal J=preimage(R,phi,I);
+  return(list(J,v));
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc insepDecomp(ideal i)
+{
+//decomposes i into special ideals
+//computes the prime decomposition of the special ideals
+//and transforms it back to a decomposition of i
+
+  ASSUME(0, hasFieldCoefficient(basering) );
+  ASSUME(0, not isQuotientRing(basering) ) ;
+  ASSUME(0, hasGlobalOrdering(basering) ) ;
+  def R=basering;
+  list pr=zeroSp(i);
+  int l,k;
+  list re,wo,qr;
+  ideal m=maxideal(1);
+  ideal K;
+  map phi=R,m;
+  int p=char(R);
+  intvec op=option(get);
+
+  for(l=1;l<=size(pr[1]);l++)
+  {
+    wo=zeroSepClos(pr[1][l],pr[2][l]);
+    for(k=1;k<=nvars(basering);k++)
+    {
+      m[k]=var(k)^(p^wo[2][k]);
+    }
+    phi=R,m;
+    qr=decomp(wo[1],2);
+
+    option(redSB);
+    for(k=1;k<=size(qr) div 2;k++)
+    {
+      K=qr[2*k];
+      K=phi(K);
+      K=groebner(K);
+      re[size(re)+1]=zeroRad(K);
+    }
+    option(noredSB);
+  }
+  option(set,op);
+  return(re);
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+
+static proc clearSB (ideal i,list #)
+"USAGE:   clearSB(i); i ideal which is SB ordered by monomial ordering
+RETURN:  ideal = minimal SB
+NOTE:
+EXAMPLE: example clearSB; shows an example
+"
+{
+  ASSUME(1, hasFieldCoefficient(basering) );
+  ASSUME(1, not isQuotientRing(basering) ) ;
+  ASSUME(1, hasGlobalOrdering(basering) ) ;
+  int k,j;
+  poly m;
+  int c=size(i);
+
+  if(size(#)==0)
+  {
+    for(j=1;j<c;j++)
+    {
+      if(deg(i[j])==0)
+      {
+        i=ideal(1);
+        return(i);
+      }
+      if(deg(i[j])>0)
+      {
+        m=lead(i[j]);
+        for(k=j+1;k<=c;k++)
+        {
+          if(size(lead(i[k])/m)>0)
+          {
+            i[k]=0;
+          }
+        }
+      }
+    }
+  }
+  else
+  {
+    j=0;
+    while(j<c-1)
+    {
+      j++;
+      if(deg(i[j])==0)
+      {
+        i=ideal(1);
+        return(i);
+      }
+      if(deg(i[j])>0)
+      {
+        m=lead(i[j]);
+        for(k=j+1;k<=c;k++)
+        {
+          if(size(lead(i[k])/m)>0)
+          {
+            if((leadexp(m)!=leadexp(i[k]))||(#[j]<=#[k]))
+            {
+              i[k]=0;
+            }
+            else
+            {
+              i[j]=0;
+              break;
+            }
+          }
+        }
+      }
+    }
+  }
+  return(simplify(i,2));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring  r = (0,a,b),(x,y,z),dp;
+   ideal i=ax2+y,a2x+y,bx;
+   list l=1,2,1;
+   ideal j=clearSB(i,l);
+   j;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static proc clearSBNeu (ideal i,list #)
+"USAGE:   clearSB(i); i ideal which is SB ordered by monomial ordering
+RETURN:  ideal = minimal SB
+NOTE:
+EXAMPLE: example clearSB; shows an example
+"
+{
+ ASSUME(1, hasFieldCoefficient(basering) );
+ ASSUME(1, not isQuotientRing(basering) ) ;
+ ASSUME(1, hasGlobalOrdering(basering) ) ;
+ int k,j;
+ intvec m,n,v,w;
+ int c=size(i);
+ w=leadexp(0);
+ v[size(i)]=0;
+
+ j=0;
+ while(j<c-1)
+ {
+   j++;
+   if(deg(i[j])>=0)
+   {
+      m=leadexp(i[j]);
+      for(k=j+1;k<=c;k++)
+      {
+        n=leadexp(i[k]);
+        if(n!=w)
+        {
+           if(((m==n)&&(#[j]>#[k]))||((teilt(n,m))&&(n!=m)))
+           {
+             i[j]=0;
+             v[j]=1;
+             break;
+           }
+           if(((m==n)&&(#[j]<=#[k]))||((teilt(m,n))&&(n!=m)))
+           {
+             i[k]=0;
+             v[k]=1;
+           }
+        }
+      }
+    }
+  }
+  return(v);
+}
+
+static proc teilt(intvec a, intvec b)
+{
+  int i;
+  for(i=1;i<=size(a);i++)
+  {
+    if(a[i]>b[i]){return(0);}
+  }
+  return(1);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+static proc independSet (ideal j)
+"USAGE:   independentSet(i); i ideal
+RETURN:  list = new varstring with the independent set at the end,
+                ordstring with the corresponding block ordering,
+                the integer where the independent set starts in the varstring
+NOTE:
+EXAMPLE: example independentSet; shows an example
+"
+{
+  int n,k,di;
+  list resu,hilf;
+  string var1,var2;
+  list v=indepSet(j,1);
+
+  for(n=1;n<=size(v);n++)
+  {
+    di=0;
+    var1="";
+    var2="";
+    for(k=1;k<=size(v[n]);k++)
+    {
+      if(v[n][k]!=0)
+      {
+        di++;
+        var2=var2+"var("+string(k)+"),";
+      }
+      else
+      {
+        var1=var1+"var("+string(k)+"),";
+      }
+    }
+    if(di>0)
+    {
+      var1=var1+var2;
+      var1=var1[1..size(var1)-1];
+      hilf[1]=var1;
+      hilf[2]="lp";
+      //"lp("+string(nvars(basering)-di)+"),dp("+string(di)+")";
+      hilf[3]=di;
+      resu[n]=hilf;
+    }
+    else
+    {
+      resu[n]=varstr(basering),ordstr(basering),0;
+    }
+  }
+  return(resu);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring s1=(0,x,y),(a,b,c,d,e,f,g),lp;
+   ideal i=ea-fbg,fa+be,ec-fdg,fc+de;
+   i=std(i);
+   list  l=independSet(i);
+   l;
+   i=i,g;
+   l=independSet(i);
+   l;
+
+   ring s=0,(x,y,z),lp;
+   ideal i=z,yx;
+   list l=independSet(i);
+   l;
+
+
+}
+///////////////////////////////////////////////////////////////////////////////
+
+static proc maxIndependSet (ideal j)
+"USAGE:   maxIndependentSet(i); i ideal
+RETURN:  list = new varstring with the maximal independent set at the end,
+                ordstring with the corresponding block ordering,
+                the integer where the independent set starts in the varstring
+NOTE:
+EXAMPLE: example maxIndependentSet; shows an example
+"
+{
+  ASSUME(1, hasFieldCoefficient(basering) );
+  ASSUME(1, not isQuotientRing(basering) ) ;
+  ASSUME(1, hasGlobalOrdering(basering) ) ;
+  int n,k,di;
+  list resu,hilf;
+  string var1,var2;
+  list v=indepSet(j,0);
+
+  for(n=1;n<=size(v);n++)
+  {
+    di=0;
+    var1="";
+    var2="";
+    for(k=1;k<=size(v[n]);k++)
+    {
+      if(v[n][k]!=0)
+      {
+        di++;
+        var2=var2+"var("+string(k)+"),";
+      }
+      else
+      {
+        var1=var1+"var("+string(k)+"),";
+      }
+    }
+    if(di>0)
+    {
+      var1=var1+var2;
+      var1=var1[1..size(var1)-1];
+      hilf[1]=var1;
+      hilf[2]="lp";
+      hilf[3]=di;
+      resu[n]=hilf;
+    }
+    else
+    {
+      resu[n]=varstr(basering),ordstr(basering),0;
+    }
+  }
+  return(resu);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring s1=(0,x,y),(a,b,c,d,e,f,g),lp;
+   ideal i=ea-fbg,fa+be,ec-fdg,fc+de;
+   i=std(i);
+   list  l=maxIndependSet(i);
+   l;
+   i=i,g;
+   l=maxIndependSet(i);
+   l;
+
+   ring s=0,(x,y,z),lp;
+   ideal i=z,yx;
+   list l=maxIndependSet(i);
+   l;
+
+
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static proc prepareQuotientring (int nnp,string order)
+"USAGE:   prepareQuotientring(nnp, order); nnp int, order string
+RETURN:  Kvar(nnp+1),...,var(nvars)[..rest ]
+EXAMPLE: example prepareQuotientring; shows an example
+"
+{
+  ASSUME(1, hasFieldCoefficient(basering) );
+  ASSUME(1, not isQuotientRing(basering) ) ;
+  ASSUME(1, hasGlobalOrdering(basering) ) ;
+  list rl=ringlist(basering);
+  if (typeof(rl[1])=="int")
+  {
+    int p=rl[1];
+    list rl2=rl[2];
+    rl[1]=list(p,
+            list(rl2[nnp+1..nvars(basering)]),
+            list(list("lp",1:(nvars(basering)-nnp))),
+            ideal(0));
+    rl[2]=list(rl2[1..nnp]);
+    rl[3]=list(list(order,1:nnp),list("C",0));
+  }
+  else
+  {
+    if (typeof(rl[1])=="list")
+    {
+        list rl1=rl[1];
+        list rl2=rl[2];
+        rl1=list(rl1[1][1],
+                rl[1][2]+list(rl2[nnp+1..nvars(basering)]),
+                list(list("lp",1:(size(rl[1][2])+nvars(basering)-nnp))),
+                ideal(0));
+        rl[1]=rl1;
+        rl[2]=list(rl2[1..nnp]);
+        rl[3]=list(list(order,1:nnp),list("C",0));
+    }
+    else
+    {
+        ERROR("Unexpected case in prepareQuotientring. Please inform the authors");
+    }
+  }
+
+  def quotring=ring(rl);
+  return(quotring);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring s1=(0,x),(a,b,c,d,e,f,g),lp;
+   def Q= prepareQuotientring(3,"lp");
+   Q;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static proc cleanPrimary(list l)
+{
+   int i,j;
+   list lh;
+   for(i=1;i<=size(l) div 2;i++)
+   {
+      if(deg(l[2*i-1][1])>0)
+      {
+         j++;
+         lh[j]=l[2*i-1];
+         j++;
+         lh[j]=l[2*i];
+      }
+   }
+   return(lh);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+
+proc minAssPrimesold(ideal i, list #)
+"USAGE:   minAssPrimes(i); i ideal
+         minAssPrimes(i,1); i ideal  (to use also the factorizing Groebner)
+RETURN:  list = the minimal associated prime ideals of i
+EXAMPLE: example minAssPrimes; shows an example
+"
+{
+   ASSUME(1, hasFieldCoefficient(basering) );
+   ASSUME(0, not isQuotientRing(basering) ) ;
+   ASSUME(0, hasGlobalOrdering(basering) ) ;
+   def @P=basering;
+   if(size(i)==0){return(list(ideal(0)));}
+   list qr=simplifyIdeal(i);
+   map phi=@P,qr[2];
+   i=qr[1];
+
+   def gnir=ring(ringlist(@P));
+   setring gnir;
+
+   ideal i=fetch(@P,i);
+   if(size(#)==0)
+   {
+      int @wr;
+      list tluser, at res;
+      list primary=decomp(i,2);
+
+      @res[1]=primary;
+
+      tluser=union(@res);
+      setring @P;
+      list @res=imap(gnir,tluser);
+      return(phi(@res));
+   }
+   list @res,empty;
+   ideal ser;
+   def op = option( get );
+   option( redSB );
+   list @pr=facstd(i);
+   //if(size(@pr)==1)
+//   {
+//      attrib(@pr[1],"isSB",1);
+//      if((dim(@pr[1])==0)&&(homog(@pr[1])==1))
+//      {
+//         setring @P;
+//         list @res=maxideal(1);
+//         return(phi(@res));
+//      }
+//      if(dim(@pr[1])>1)
+//      {
+//         setring @P;
+//        // kill gnir;
+//         execute ("ring gnir1 = ("+charstr(basering)+"),
+//                              ("+varstr(basering)+"),(C,lp);");
+//         ideal i=fetch(@P,i);
+//         list @pr=facstd(i);
+//        // ideal ser;
+//         setring gnir;
+//         @pr=fetch(gnir1, at pr);
+//         kill gnir1;
+//      }
+//   }
+   // option( noredSB );
+   option( set, op );
+   int j,k,odim,ndim,count;
+   attrib(@pr[1],"isSB",1);
+   if(#[1]==77)
+   {
+     odim=dim(@pr[1]);
+     count=1;
+     intvec pos;
+     pos[size(@pr)]=0;
+     for(j=2;j<=size(@pr);j++)
+     {
+        attrib(@pr[j],"isSB",1);
+        ndim=dim(@pr[j]);
+        if(ndim>odim)
+        {
+           for(k=count;k<j;k++)
+           {
+              pos[k]=1;
+           }
+           count=j;
+           odim=ndim;
+        }
+        if(ndim<odim)
+        {
+           pos[j]=1;
+        }
+     }
+     for(j=1;j<=size(@pr);j++)
+     {
+        if(pos[j]!=1)
+        {
+            @res[j]=decomp(@pr[j],2);
+        }
+        else
+        {
+           @res[j]=empty;
+        }
+     }
+   }
+   else
+   {
+     ser=ideal(1);
+     for(j=1;j<=size(@pr);j++)
+     {
+//@pr[j];
+//pause();
+        @res[j]=decomp(@pr[j],2);
+//       @res[j]=decomp(@pr[j],2, at pr[j],ser);
+//       for(k=1;k<=size(@res[j]);k++)
+//       {
+//          ser=intersect(ser, at res[j][k]);
+//       }
+     }
+   }
+
+   @res=union(@res);
+   setring @P;
+   list @res=imap(gnir, at res);
+   return(phi(@res));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring  r = 32003,(x,y,z),lp;
+   poly  p = z2+1;
+   poly  q = z4+2;
+   ideal i = p^2*q^3,(y-z3)^3,(x-yz+z4)^4;
+   list pr= minAssPrimes(i);  pr;
+
+   minAssPrimes(i,1);
+}
+
+static proc primT(ideal i)
+{
+   ASSUME(1, hasFieldCoefficient(basering) );
+   ASSUME(1, not isQuotientRing(basering) ) ;
+   ASSUME(1, hasGlobalOrdering(basering) ) ;
+
+   //assumes that all generators of i are irreducible
+   //i is standard basis
+
+   attrib(i,"isSB",1);
+   int j=size(i);
+   int k;
+   while(j>0)
+   {
+     if(deg(i[j])>1){break;}
+     j--;
+   }
+   if(j==0){return(1);}
+   if(deg(i[j])==vdim(i)){return(1);}
+   return(0);
+}
+
+static proc minAssPrimes(ideal i, list #)
+"USAGE:   minAssPrimes(i); i ideal
+      Optional parameters in list #: (can be entered in any order)
+      0, "facstd"   ->   uses facstd to first decompose the ideal
+      1, "noFacstd" ->  does not use facstd (default)
+      "SL" ->     the new algorithm is used (default)
+      "GTZ" ->     the old algorithm is used
+RETURN:  list = the minimal associated prime ideals of i
+EXAMPLE: example minAssPrimes; shows an example
+"
+{
+  ASSUME(1, hasFieldCoefficient(basering) );
+  ASSUME(1, not isQuotientRing(basering) ) ;
+  ASSUME(1, hasGlobalOrdering(basering) ) ;
+
+  if(size(i) == 0){return(list(ideal(0)));}
+  string algorithm;    // Algorithm to be used
+  string facstdOption;    // To uses proc facstd
+  int j;          // Counter
+  def P0 = basering;
+  list Pl=ringlist(P0);
+  intvec dp_w;
+  for(j=nvars(P0);j>0;j--) {dp_w[j]=1;}
+  Pl[3]=list(list("dp",dp_w),list("C",0));
+  def P=ring(Pl);
+  setring P;
+  ideal i=imap(P0,i);
+
+  // Set input parameters
+  algorithm = "SL";         // Default: SL algorithm
+  facstdOption = "Facstd";    // Default: facstd is not used
+  if(size(#) > 0)
+  {
+    int valid;
+    for(j = 1; j <= size(#); j++)
+    {
+      valid = 0;
+      if((typeof(#[j]) == "int") or (typeof(#[j]) == "number"))
+      {
+        if (#[j] == 0) {facstdOption = "noFacstd"; valid = 1;}    // If #[j] == 0, facstd is not used.
+        if (#[j] == 1) {facstdOption = "facstd";   valid = 1;}    // If #[j] == 1, facstd is used.
+      }
+      if(typeof(#[j]) == "string")
+      {
+        if(#[j] == "GTZ" || #[j] == "SL")
+        {
+          algorithm = #[j];
+          valid = 1;
+        }
+        if(#[j] == "noFacstd" || #[j] == "facstd")
+        {
+          facstdOption = #[j];
+          valid = 1;
+        }
+      }
+      if(valid == 0)
+      {
+        dbprint(1, "Warning! The following input parameter was not recognized:", #[j]);
+      }
+    }
+  }
+
+  list q = simplifyIdeal(i);
+  list re = maxideal(1);
+  int a, k;
+  intvec op = option(get);
+  map phi = P,q[2];
+
+  list result;
+
+  if(npars(P) == 0){option(redSB);}
+
+  if(attrib(i,"isSB")!=1)
+  {
+    i=groebner(q[1]);
+  }
+  else
+  {
+    for(j=1;j<=nvars(basering);j++)
+    {
+      if(q[2][j]!=var(j)){k=1;break;}
+    }
+    if(k)
+    {
+      i=groebner(q[1]);
+    }
+  }
+
+  if( dim(i) == -1 )
+  {
+    option( set,op );
+    setring P0;
+    return( ideal(1) );
+  }
+  if( (dim(i) == 0 ) && ( npars(P) == 0) )
+  {
+    int di = vdim(i);
+    def gnir=changeordTo(P,"lp");
+    setring gnir;
+    ideal J = std(imap(P,i));
+    attrib(J, "isSB", 1);
+    if(vdim(J) != di)
+    {
+      J = fglm(P, i);
+    }
+//    list pr = triangMH(J,2); HIER KOENNEN verschiedene Mengen zu gleichen
+//                             asoziierten Primidealen fuehren
+// Aenderung
+    list pr = triangMH(J,2);
+    list qr, re;
+    for(k = 1; k <= size(pr); k++)
+    {
+      if(primT(pr[k])&&(0))
+      {
+        re[size(re) + 1] = pr[k];
+      }
+      else
+      {
+        attrib(pr[k], "isSB", 1);
+        // Lines changed
+        if (algorithm == "GTZ")
+        {
+          qr = decomp(pr[k], 2);
+        }
+        else
+        {
+          qr = minAssSL(pr[k]);
+        }
+        for(j = 1; j <= size(qr) div 2; j++)
+        {
+          re[size(re) + 1] = std(qr[2 * j]);
+        }
+      }
+    }
+    setring P;
+    re = imap(gnir, re);
+    re=phi(re);
+    option(set, op);
+    setring(P0);
+    list re=imap(P,re);
+    return(re);
+  }
+
+  // Lines changed
+  if ((facstdOption == "noFacstd") || (dim(i) == 0))
+  {
+    if (algorithm == "GTZ")
+    {
+      re[1] = decomp(i, 2);
+    }
+    else
+    {
+      re[1] = minAssSL(i);
+    }
+    re = union(re);
+    option(set, op);
+    re=phi(re);
+    setring(P0);
+    list re=imap(P,re);
+    return(re);
+  }
+  q = facstd(i);
+
+/*
+  if((size(q) == 1) && (dim(i) > 1))
+  {
+    execute ("ring gnir=("+charstr(P)+"),("+varstr(P)+"),lp;");
+    list p = facstd(fetch(P, i));
+    if(size(p) > 1)
+    {
+      a = 1;
+      setring P;
+      q = fetch(gnir,p);
+    }
+    else
+    {
+      setring P;
+    }
+    kill gnir;
+  }
+*/
+  option(set,op);
+  // Debug
+  dbprint(printlevel - voice, "Components returned by facstd", size(q), q);
+  for(j = 1; j <= size(q); j++)
+  {
+    if(a == 0){attrib(q[j], "isSB", 1);}
+    // Debug
+    dbprint(printlevel - voice, "We compute the decomp of component", j);
+    // Lines changed
+    if (algorithm == "GTZ")
+    {
+      re[j] = decomp(q[j], 2);
+    }
+    else
+    {
+      re[j] = minAssSL(q[j]);
+    }
+    // Debug
+    dbprint(printlevel - voice, "Number of components obtained for this component:", size(re[j]) div 2);
+    dbprint(printlevel - voice, "re[j]:", re[j]);
+  }
+  re = union(re);
+  re=phi(re);
+  setring(P0);
+  list re=imap(P,re);
+  return(re);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring  r = 32003,(x,y,z),lp;
+   poly  p = z2+1;
+   poly  q = z4+2;
+   ideal i = p^2*q^3,(y-z3)^3,(x-yz+z4)^4;
+   list pr= minAssPrimes(i);  pr;
+
+   minAssPrimes(i,1);
+}
+
+static proc union(list li)
+{
+  int i,j,k;
+
+  def P=basering;
+
+  def ir=changeordTo(basering,"lp");
+  setring ir;
+  list l=fetch(P,li);
+  list @erg;
+
+  for(k=1;k<=size(l);k++)
+  {
+     for(j=1;j<=size(l[k]) div 2;j++)
+     {
+        if(deg(l[k][2*j][1])!=0)
+        {
+           i++;
+           @erg[i]=l[k][2*j];
+        }
+     }
+  }
+
+  list @wos;
+  i=0;
+  ideal i1,i2;
+  while(i<size(@erg)-1)
+  {
+     i++;
+     k=i+1;
+     i1=lead(@erg[i]);
+      attrib(i1,"isSB",1);
+      attrib(@erg[i],"isSB",1);
+
+     while(k<=size(@erg))
+     {
+        if(deg(@erg[i][1])==0)
+        {
+           break;
+        }
+        i2=lead(@erg[k]);
+        attrib(@erg[k],"isSB",1);
+        attrib(i2,"isSB",1);
+
+        if(size(reduce(i1,i2,1))==0)
+        {
+           if(size(reduce(@erg[i], at erg[k],1))==0)
+           {
+              @erg[k]=ideal(1);
+              i2=ideal(1);
+           }
+        }
+        if(size(reduce(i2,i1,1))==0)
+        {
+           if(size(reduce(@erg[k], at erg[i],1))==0)
+           {
+              break;
+           }
+        }
+        k++;
+        if(k>size(@erg))
+        {
+           @wos[size(@wos)+1]=@erg[i];
+        }
+     }
+  }
+  if(deg(@erg[size(@erg)][1])!=0)
+  {
+     @wos[size(@wos)+1]=@erg[size(@erg)];
+  }
+  setring P;
+  list @ser=fetch(ir, at wos);
+  return(@ser);
+}
+///////////////////////////////////////////////////////////////////////////////
+proc equidim(ideal i,list #)
+"USAGE:  equidim(i) or equidim(i,1) ; i ideal
+RETURN: list of equidimensional ideals a[1],...,a[s] with:
+        - a[s] the equidimensional locus of i, i.e. the intersection
+          of the primary ideals of dimension of i
+        - a[1],...,a[s-1] the lower dimensional equidimensional loci.
+NOTE:    An embedded component q (primary ideal) of i can be replaced in the
+         decomposition by a primary ideal q1 with the same radical as q. @*
+         @code{equidim(i,1)} uses the algorithm of Eisenbud/Huneke/Vasconcelos.
+
+EXAMPLE:example equidim; shows an example
+"
+{
+  ASSUME(0, hasFieldCoefficient(basering) );
+  ASSUME(0, not isQuotientRing(basering) ) ;
+  if(attrib(basering,"global")!=1)
+  {
+      ERROR(
+      "// Not implemented for this ordering, please change to global ordering."
+      );
+  }
+
+  intvec op ;
+  def  P = basering;
+  list eq;
+  intvec w;
+  int n,m;
+  int g=size(i);
+  int a=attrib(i,"isSB");
+  int homo=homog(i);
+  if(size(#)!=0)
+  {
+     m=1;
+  }
+
+  if(((homo==1)||(a==1))&&(find(ordstr(basering),"l")==0)
+                                &&(find(ordstr(basering),"s")==0))
+  {
+     def gnir=ring(ringlist(basering));
+     setring gnir;
+     ideal i=imap(P,i);
+     ideal j=i;
+     if(a==1)
+     {
+       attrib(j,"isSB",1);
+     }
+     else
+     {
+       j=groebner(i);
+     }
+  }
+  else
+  {
+     def gnir=changeordTo(basering,"dp");
+     setring gnir;
+     ideal i=imap(P,i);
+     ideal j=groebner(i);
+  }
+  if(homo==1)
+  {
+     for(n=1;n<=nvars(basering);n++)
+     {
+        w[n]=ord(var(n));
+     }
+     intvec hil=hilb(j,1,w);
+  }
+
+  if ((dim(j)==-1)||(size(j)==0)||(nvars(basering)==1)
+                  ||(dim(j)==0)||(dim(j)+g==nvars(basering)))
+  {
+    setring P;
+    eq[1]=i;
+    return(eq);
+  }
+
+  if(m==0)
+  {
+     ideal k=equidimMax(j);
+  }
+  else
+  {
+     ideal k=equidimMaxEHV(j);
+  }
+  if(size(reduce(k,j,1))==0)
+  {
+    setring P;
+    eq[1]=i;
+    kill gnir;
+    return(eq);
+  }
+  op=option(get);
+  option(returnSB);
+  j=quotient(j,k);
+  option(set,op);
+
+  list equi=equidim(j);
+  if(deg(equi[size(equi)][1])<=0)
+  {
+      equi[size(equi)]=k;
+  }
+  else
+  {
+    equi[size(equi)+1]=k;
+  }
+  setring P;
+  eq=imap(gnir,equi);
+  kill gnir;
+  return(eq);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring  r = 32003,(x,y,z),dp;
+   ideal i = intersect(ideal(z),ideal(x,y),ideal(x2,z2),ideal(x5,y5,z5));
+   equidim(i);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+proc equidimMax(ideal i)
+"USAGE:  equidimMax(i); i ideal
+RETURN:  ideal of equidimensional locus (of maximal dimension) of i.
+EXAMPLE: example equidimMax; shows an example
+"
+{
+  ASSUME(0, hasFieldCoefficient(basering) );
+  ASSUME(0, not isQuotientRing(basering) ) ;
+  if(attrib(basering,"global")!=1)
+  {
+      ERROR(
+      "Not implemented for this ordering, please change to a global ordering."
+      );
+  }
+
+  def  P = basering;
+  ideal eq;
+  intvec w;
+  int n;
+  int g=size(i);
+  int a=attrib(i,"isSB");
+  int homo=homog(i);
+
+  if(((homo==1)||(a==1))&&(find(ordstr(basering),"l")==0)
+                                &&(find(ordstr(basering),"s")==0))
+  {
+     def gnir=ring(ringlist(basering));
+     setring gnir;
+     ideal i=imap(P,i);
+     ideal j=i;
+     if(a==1)
+     {
+       attrib(j,"isSB",1);
+     }
+     else
+     {
+       j=groebner(i);
+     }
+  }
+  else
+  {
+     def gnir=changeordTo(basering,"dp");
+     setring gnir;
+     ideal i=imap(P,i);
+     ideal j=groebner(i);
+  }
+  list indep;
+  ideal equ,equi;
+  if(homo==1)
+  {
+     for(n=1;n<=nvars(basering);n++)
+     {
+        w[n]=ord(var(n));
+     }
+     intvec hil=hilb(j,1,w);
+  }
+  if ((dim(j)==-1)||(size(j)==0)||(nvars(basering)==1)
+                  ||(dim(j)==0)||(dim(j)+g==nvars(basering)))
+  {
+    setring P;
+    return(i);
+  }
+
+  indep=maxIndependSet(j);
+
+  execute("ring gnir1 = ("+charstr(basering)+"),("+indep[1][1]+"),("
+                              +indep[1][2]+");");
+  if(homo==1)
+  {
+     ideal j=std(imap(gnir,j),hil,w);
+  }
+  else
+  {
+     ideal j=groebner(imap(gnir,j));
+  }
+  def quotring=prepareQuotientring(nvars(basering)-indep[1][3],"lp");
+  setring quotring;
+  ideal j=imap(gnir1,j);
+  kill gnir1;
+  j=clearSB(j);
+  ideal h;
+  for(n=1;n<=size(j);n++)
+  {
+     h[n]=leadcoef(j[n]);
+  }
+  setring gnir;
+  ideal h=imap(quotring,h);
+  kill quotring;
+
+  list l=minSat(j,h);
+
+  if(deg(l[2])>0)
+  {
+    equ=l[1];
+    attrib(equ,"isSB",1);
+    j=std(j,l[2]);
+
+    if(dim(equ)==dim(j))
+    {
+      equi=equidimMax(j);
+      equ=interred(intersect(equ,equi));
+    }
+  }
+  else
+  {
+    equ=i;
+  }
+
+  setring P;
+  eq=imap(gnir,equ);
+  kill gnir;
+  return(eq);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring  r = 32003,(x,y,z),dp;
+   ideal i = intersect(ideal(z),ideal(x,y),ideal(x2,z2),ideal(x5,y5,z5));
+   equidimMax(i);
+}
+///////////////////////////////////////////////////////////////////////////////
+static proc islp()
+{
+   string s=ordstr(basering);
+   int n=find(s,"lp");
+   if(!n){return(0);}
+   int k=find(s,",");
+   string t=s[k+1..size(s)];
+   int l=find(t,",");
+   t=s[1..k-1];
+   int m=find(t,",");
+   if(l+m){return(0);}
+   return(1);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc algeDeco(ideal i, int w)
+{
+   ASSUME(0, hasFieldCoefficient(basering) );
+   ASSUME(0, not isQuotientRing(basering) ) ;
+   ASSUME(0, hasGlobalOrdering(basering) ) ;
+
+// the really needed things:
+   ASSUME(1, typeof(ringlist(basering)[1])=="list"); // in alg. extension
+
+//reduces primery decomposition over algebraic extensions to
+//the other cases
+   def R=basering;
+   int n=nvars(R);
+
+   def op = option(get);
+
+//---Anfang Provisorium
+   if((size(i)==2) && (w==2))
+   {
+      option( redSB );
+      ideal J = std(i);
+      option( noredSB );
+      if ((size(J)==2)&&(deg(J[1])==1))
+      {
+         ideal keep;
+         poly f;
+         int j;
+         for(j=1;j<=nvars(basering);j++)
+         {
+           f=J[2];
+           while((f/var(j))*var(j)-f==0)
+           {
+             f=f/var(j);
+             keep=keep,var(j);
+           }
+           J[2]=f;
+         }
+         ideal K=factorize(J[2],1);
+         if(deg(K[1])==0){K=0;}
+         K=K+std(keep);
+         ideal L;
+         list resu;
+         for(j=1;j<=size(K);j++)
+         {
+            L=J[1],K[j];
+            resu[j]=L;
+         }
+         option( set, op );
+         return(resu);
+      }
+   }
+//---Ende Provisorium
+   list R_l=ringlist(R);
+   ideal @p=R_l[1][4]; // minpoly
+   R_l[2]=R_l[2]+R_l[1][2]; // vars
+   R_l[1]=R_l[1][1];  // char
+   R_l[3]=list(list("dp",1:size(R_l[2])),list("C",0)); // ord
+   def RH=ring(R_l); kill R_l;setring RH;
+   ideal @pp=imap(R, at p); poly @p=@pp[1];
+   ideal i=imap(R,i);
+   ideal I=subst(i,var(nvars(basering)),0);
+   int j;
+   for(j=1;j<=ncols(i);j++)
+   {
+     if(i[j]!=I[j]){break;}
+   }
+   if((j>ncols(i))&&(deg(@p)==1))
+   {
+     setring R;
+     kill RH;
+     // remove extension, set order to dp:
+     list R_l=ringlist(R);
+     R_l[1]=R_l[1][1]; // char
+     R_l[3]=list(list("dp",1:nvars(R)),list("C",0)); // ord
+     def RH=ring(R_l); kill R_l; setring RH;
+     ideal i=imap(R,i);
+     ideal J;
+   }
+   else
+   {
+      i=i, at p;
+   }
+   list pr;
+
+   if(w==0)
+   {
+      pr=decomp(i);
+   }
+   if(w==1)
+   {
+      pr=prim_dec(i,1);
+      pr=reconvList(pr);
+   }
+   if(w==2)
+   {
+      pr=minAssPrimes(i);
+   }
+
+   if(n<nvars(basering))
+   {
+      // remove extension, set order to dp(n),lp:
+      list R_l=ringlist(basering);
+      if (typeof(R_l[1])=="list") { R_l[1]=R_l[1][1]; }
+      R_l[3]=list(list("dp",1:n),list("lp",1:(nvars(basering)-n)),list("C",0));
+      def RS=ring(R_l); kill R_l; setring RS;
+      list pr=imap(RH,pr);
+      ideal K;
+      for(j=1;j<=size(pr);j++)
+      {
+         K=groebner(pr[j]);
+         K=K[2..size(K)];
+         pr[j]=K;
+      }
+      setring R;
+      list pr=imap(RS,pr);
+   }
+   else
+   {
+      setring R;
+      list pr=imap(RH,pr);
+   }
+
+   list re;
+   if(w==2)
+   {
+      re=pr;
+   }
+   else
+   {
+      re=convList(pr);
+   }
+   option( set, op );
+   return( re );
+}
+///////////////////////////////////////////////////////////////////////////////
+static proc prepare_absprimdec(list primary)
+{
+  ASSUME(1, not isQuotientRing(basering) ) ;
+  ASSUME(1, hasGlobalOrdering(basering) ) ;
+
+  list resu,tempo;
+  string absotto;
+  resu[size(primary) div 2]=list();
+  for(int ab=1;ab<=size(primary) div 2;ab++)
+  {
+    absotto= absFactorize(primary[2*ab][1],77);
+    tempo=primary[2*ab-1],primary[2*ab],absotto,string(var(nvars(basering)));
+    resu[ab]=tempo;
+  }
+  return(resu);
+}
+///////////////////////////////////////////////////////////////////////////////
+static proc decomp(ideal i,list #)
+"USAGE:  decomp(i); i ideal  (for primary decomposition)   (resp.
+         decomp(i,1);        (for the associated primes of dimension of i) )
+         decomp(i,2);        (for the minimal associated primes) )
+         decomp(i,3);        (for the absolute primary decomposition) )
+RETURN:  list = list of primary ideals and their associated primes
+         (at even positions in the list)
+         (resp. a list of the minimal associated primes)
+NOTE:    Algorithm of Gianni/Trager/Zacharias
+EXAMPLE: example decomp; shows an example
+"
+{
+  ASSUME(1, hasFieldCoefficient(basering) );
+  ASSUME(1, not isQuotientRing(basering) ) ;
+  ASSUME(1, hasGlobalOrdering(basering) ) ;
+
+  intvec op, at vv;
+  def  @P = basering;
+  list primary,indep,ltras;
+  intvec @vh,isat, at w;
+  int @wr, at k, at n, at m, at n1, at n2, at n3,homo,seri,keepdi,abspri,ab,nn;
+  ideal peek=i;
+  ideal ser,tras;
+  int isS=(attrib(i,"isSB")==1);
+
+
+  if(size(#)>0)
+  {
+    if((#[1]==1)||(#[1]==2)||(#[1]==3))
+    {
+      @wr=#[1];
+      if(@wr==3){abspri=1;@wr=0;}
+      if(size(#)>1)
+      {
+        seri=1;
+        peek=#[2];
+        ser=#[3];
+      }
+    }
+    else
+    {
+      seri=1;
+      peek=#[1];
+      ser=#[2];
+    }
+  }
+  if(abspri)
+  {
+    list absprimary,abskeep,absprimarytmp,abskeeptmp;
+  }
+  homo=homog(i);
+  if(homo)
+  {
+    if(attrib(i,"isSB")!=1)
+    {
+      //ltras=mstd(i);
+      tras=groebner(i);
+      ltras=tras,tras;
+      attrib(ltras[1],"isSB",1);
+    }
+    else
+    {
+      ltras=i,i;
+      attrib(ltras[1],"isSB",1);
+    }
+    tras=ltras[1];
+    attrib(tras,"isSB",1);
+    if((dim(tras)==0) && (!abspri))
+    {
+      primary[1]=ltras[2];
+      primary[2]=maxideal(1);
+      if(@wr>0)
+      {
+        list l;
+        l[1]=maxideal(1);
+        l[2]=maxideal(1);
+        return(l);
+      }
+      return(primary);
+    }
+    for(@n=1;@n<=nvars(basering);@n++)
+    {
+      @w[@n]=ord(var(@n));
+    }
+    intvec @hilb=hilb(tras,1, at w);
+    intvec keephilb=@hilb;
+  }
+
+  //----------------------------------------------------------------
+  //i is the zero-ideal
+  //----------------------------------------------------------------
+
+  if(size(i)==0)
+  {
+    primary=ideal(0),ideal(0);
+    if (abspri) { return(prepare_absprimdec(primary));}
+    return(primary);
+  }
+
+  //----------------------------------------------------------------
+  //pass to the lexicographical ordering and compute a standardbasis
+  //----------------------------------------------------------------
+
+  int lp=islp();
+
+  def gnir=changeordTo(basering,"lp");
+  setring gnir;
+  op=option(get);
+  option(redSB);
+
+  ideal ser=fetch(@P,ser);
+
+  if(homo==1)
+  {
+    if(!lp)
+    {
+      ideal @j=std(fetch(@P,i), at hilb, at w);
+    }
+    else
+    {
+      ideal @j=fetch(@P,tras);
+      attrib(@j,"isSB",1);
+    }
+  }
+  else
+  {
+    if(lp&&isS)
+    {
+      ideal @j=fetch(@P,i);
+      attrib(@j,"isSB",1);
+    }
+    else
+    {
+      ideal @j=groebner(fetch(@P,i));
+    }
+  }
+  option(set,op);
+  if(seri==1)
+  {
+    ideal peek=fetch(@P,peek);
+    attrib(peek,"isSB",1);
+  }
+  else
+  {
+    ideal peek=@j;
+  }
+  if((size(ser)==0)&&(!abspri))
+  {
+    ideal fried;
+    @n=size(@j);
+    for(@k=1;@k<=@n;@k++)
+    {
+      if(deg(lead(@j[@k]))==1)
+      {
+        fried[size(fried)+1]=@j[@k];
+        @j[@k]=0;
+      }
+    }
+    if(size(fried)==nvars(basering))
+    {
+      setring @P;
+      primary[1]=i;
+      primary[2]=i;
+      if (abspri) { return(prepare_absprimdec(primary));}
+      return(primary);
+    }
+    if(size(fried)>0)
+    {
+      string newva;
+      string newma;
+      poly f;
+      for(@k=1;@k<=nvars(basering);@k++)
+      {
+        @n1=0;
+        for(@n=1;@n<=size(fried);@n++)
+        {
+          if(leadmonom(fried[@n])==var(@k))
+          {
+            @n1=1;
+            break;
+          }
+        }
+        if(@n1==0)
+        {
+          newva=newva+string(var(@k))+",";
+          newma=newma+string(var(@k))+",";
+        }
+        else
+        {
+          newma=newma+string(0)+",";
+          fried[@n]=fried[@n]/leadcoef(fried[@n]);
+          f=fried[@n]-lead(fried[@n]);
+          @j=subst(@j,var(@k),-f);
+        }
+      }
+      newva[size(newva)]=")";
+      newma[size(newma)]=";";
+      execute("ring @deirf=("+charstr(gnir)+"),("+newva+",lp;");
+      execute("map @kappa=gnir,"+newma);
+      ideal @j= @kappa(@j);
+      @j=std(@j);
+
+      list pr=decomp(@j);
+      setring gnir;
+      list pr=imap(@deirf,pr);
+      for(@k=1;@k<=size(pr);@k++)
+      {
+        @j=pr[@k]+fried;
+        pr[@k]=@j;
+      }
+      setring @P;
+      primary=imap(gnir,pr);
+      if (abspri) { return(prepare_absprimdec(primary));}
+      return(primary);
+    }
+  }
+  //----------------------------------------------------------------
+  //j is the ring
+  //----------------------------------------------------------------
+
+  if (dim(@j)==-1)
+  {
+    setring @P;
+    primary=ideal(1),ideal(1);
+    if (abspri) { return(prepare_absprimdec(primary));}
+    return(primary);
+  }
+
+  //----------------------------------------------------------------
+  //  the case of one variable
+  //----------------------------------------------------------------
+
+  if(nvars(basering)==1)
+  {
+    list fac=factor(@j[1]);
+    list gprimary;
+    for(@k=1;@k<=size(fac[1]);@k++)
+    {
+      if(@wr==0)
+      {
+        gprimary[2*@k-1]=ideal(fac[1][@k]^fac[2][@k]);
+        gprimary[2*@k]=ideal(fac[1][@k]);
+      }
+      else
+      {
+        gprimary[2*@k-1]=ideal(fac[1][@k]);
+        gprimary[2*@k]=ideal(fac[1][@k]);
+      }
+    }
+    setring @P;
+    primary=fetch(gnir,gprimary);
+
+//HIER
+    if (abspri) { return(prepare_absprimdec(primary));}
+    return(primary);
+  }
+
+ //------------------------------------------------------------------
+ //the zero-dimensional case
+ //------------------------------------------------------------------
+  if (dim(@j)==0)
+  {
+    op=option(get);
+    option(redSB);
+    list gprimary= zero_decomp(@j,ser, at wr);
+
+    setring @P;
+    primary=fetch(gnir,gprimary);
+
+    if(size(ser)>0)
+    {
+      primary=cleanPrimary(primary);
+    }
+//HIER
+    if(abspri)
+    {
+      setring gnir;
+      list primary=imap(@P,primary);
+      list resu,tempo;
+      string absotto;
+      map sigma,invsigma;
+      ideal II,jmap;
+      nn=nvars(basering);
+      for(ab=1;ab<=size(primary) div 2;ab++)
+      {
+        II=primary[2*ab];
+        attrib(II,"isSB",1);
+        if(deg(II[1])==vdim(II))
+        {
+          absotto= absFactorize(primary[2*ab][1],77);
+          tempo=
+            primary[2*ab-1],primary[2*ab],absotto,string(var(nvars(basering)));
+        }
+        else
+        {
+          invsigma=basering,maxideal(1);
+          jmap=randomLast(50);
+          sigma=basering,jmap;
+          jmap[nn]=2*var(nn)-jmap[nn];
+          invsigma=basering,jmap;
+          II=groebner(sigma(II));
+          absotto = absFactorize(II[1],77);
+          II=var(nn);
+          tempo= primary[2*ab-1],primary[2*ab],absotto,string(invsigma(II));
+        }
+        resu[ab]=tempo;
+      }
+      primary=resu;
+      setring @P;
+      primary=imap(gnir,primary);
+    }
+    option(set,op);
+    return(primary);
+  }
+
+  poly @gs, at gh, at p;
+  string @va;
+  def quotring;
+  list quprimary,htprimary,collectprimary,lsau,lnew,allindep,restindep;
+  ideal @h;
+  int jdim=dim(@j);
+  list fett;
+  int lauf,di,newtest;
+  //------------------------------------------------------------------
+  //search for a maximal independent set indep,i.e.
+  //look for subring such that the intersection with the ideal is zero
+  //j intersected with K[var(indep[3]+1),...,var(nvar] is zero,
+  //indep[1] is the new varstring and indep[2] the string for block-ordering
+  //------------------------------------------------------------------
+  if(@wr!=1)
+  {
+    allindep=independSet(@j);
+    for(@m=1;@m<=size(allindep);@m++)
+    {
+      if(allindep[@m][3]==jdim)
+      {
+        di++;
+        indep[di]=allindep[@m];
+      }
+      else
+      {
+        lauf++;
+        restindep[lauf]=allindep[@m];
+      }
+    }
+  }
+  else
+  {
+    indep=maxIndependSet(@j);
+  }
+
+  ideal jkeep=@j;
+  if(ordstr(@P)[1]=="w")
+  {
+    list gnir_l=ringlist(gnir);
+    list @P_l=ringlist(@P);
+    gnir_l[3]=@P_l[3]; // ord
+    def @Phelp=ring(gnir_l);
+    setring @Phelp;
+    kill gnir_l, at P_l;
+  }
+  else
+  {
+    def @Phelp=changeordTo(gnir,"dp");
+    setring @Phelp;
+  }
+
+  if(homo==1)
+  {
+    if(((ordstr(@P)[3]=="d")||(ordstr(@P)[1]=="d")||(ordstr(@P)[1]=="w")
+       ||(ordstr(@P)[3]=="w"))&&(size(ringlist(@P)[3])==2))
+    {
+      ideal jwork=imap(@P,tras);
+      attrib(jwork,"isSB",1);
+    }
+    else
+    {
+      ideal jwork=std(imap(gnir, at j), at hilb, at w);
+    }
+  }
+  else
+  {
+    ideal jwork=groebner(imap(gnir, at j));
+  }
+  list hquprimary;
+  poly @p, at q;
+  ideal @h,fac,ser;
+  ideal @Ptest=1;
+  di=dim(jwork);
+  keepdi=di;
+
+  setring gnir;
+  for(@m=1;@m<=size(indep);@m++)
+  {
+    isat=0;
+    @n2=0;
+    if((indep[@m][1]==varstr(basering))&&(@m==1))
+    //this is the good case, nothing to do, just to have the same notations
+    //change the ring
+    {
+      def gnir1=ring(ringlist(basering));
+      setring gnir1;
+      ideal @j=fetch(gnir, at j);
+      attrib(@j,"isSB",1);
+      ideal ser=fetch(gnir,ser);
+    }
+    else
+    {
+      @va=string(maxideal(1));
+      if(@m==1)
+      {
+        @j=fetch(@P,i);
+      }
+      execute("ring gnir1 = ("+charstr(basering)+"),("+indep[@m][1]+"),("
+                              +indep[@m][2]+");");
+      execute("map phi=gnir,"+ at va+";");
+      op=option(get);
+      option(redSB);
+      ideal @j=groebner(phi(@j));
+      ideal ser=phi(ser);
+
+      option(set,op);
+    }
+    if((deg(@j[1])==0)||(dim(@j)<jdim))
+    {
+      setring gnir;
+      kill gnir1;
+      break;
+    }
+    for (lauf=1;lauf<=size(@j);lauf++)
+    {
+      fett[lauf]=size(@j[lauf]);
+    }
+    //------------------------------------------------------------------------
+    //we have now the following situation:
+    //j intersected with K[var(nnp+1),..,var(nva)] is zero so we may pass
+    //to this quotientring, j is their still a standardbasis, the
+    //leading coefficients of the polynomials  there (polynomials in
+    //K[var(nnp+1),..,var(nva)]) are collected in the list h,
+    //we need their ggt, gh, because of the following: let
+    //(j:gh^n)=(j:gh^infinity) then j*K(var(nnp+1),..,var(nva))[..the rest..]
+    //intersected with K[var(1),...,var(nva)] is (j:gh^n)
+    //on the other hand j=(j,gh^n) intersected with (j:gh^n)
+
+    //------------------------------------------------------------------------
+
+    //arrangement for quotientring K(var(nnp+1),..,var(nva))[..the rest..] and
+    //map phi:K[var(1),...,var(nva)] --->K(var(nnpr+1),..,var(nva))[..rest..]
+    //------------------------------------------------------------------------
+
+    quotring=prepareQuotientring(nvars(basering)-indep[@m][3],"lp");
+
+    //---------------------------------------------------------------------
+    //we pass to the quotientring   K(var(nnp+1),..,var(nva))[..the rest..]
+    //---------------------------------------------------------------------
+
+    ideal @jj=lead(@j);               //!! vorn vereinbaren
+    setring quotring;
+
+    ideal @jj=imap(gnir1, at jj);
+    @vv=clearSBNeu(@jj,fett);  //!! vorn vereinbaren
+    setring gnir1;
+    @k=size(@j);
+    for (lauf=1;lauf<=@k;lauf++)
+    {
+      if(@vv[lauf]==1)
+      {
+        @j[lauf]=0;
+      }
+    }
+    @j=simplify(@j,2);
+    setring quotring;
+    // @j considered in the quotientring
+    ideal @j=imap(gnir1, at j);
+
+    ideal ser=imap(gnir1,ser);
+
+    kill gnir1;
+
+    //j is a standardbasis in the quotientring but usually not minimal
+    //here it becomes minimal
+
+    attrib(@j,"isSB",1);
+
+    //we need later ggt(h[1],...)=gh for saturation
+    ideal @h;
+    if(deg(@j[1])>0)
+    {
+      for(@n=1;@n<=size(@j);@n++)
+      {
+        @h[@n]=leadcoef(@j[@n]);
+      }
+      //the primary decomposition of j*K(var(nnp+1),..,var(nva))[..the rest..]
+      op=option(get);
+      option(redSB);
+
+      list uprimary= zero_decomp(@j,ser, at wr);
+//HIER
+      if(abspri)
+      {
+        ideal II;
+        ideal jmap;
+        map sigma;
+        nn=nvars(basering);
+        map invsigma=basering,maxideal(1);
+        for(ab=1;ab<=size(uprimary) div 2;ab++)
+        {
+          II=uprimary[2*ab];
+          attrib(II,"isSB",1);
+          if(deg(II[1])!=vdim(II))
+          {
+            jmap=randomLast(50);
+            sigma=basering,jmap;
+            jmap[nn]=2*var(nn)-jmap[nn];
+            invsigma=basering,jmap;
+            II=groebner(sigma(II));
+          }
+          absprimarytmp[ab]= absFactorize(II[1],77);
+          II=var(nn);
+          abskeeptmp[ab]=string(invsigma(II));
+          invsigma=basering,maxideal(1);
+        }
+      }
+      option(set,op);
+    }
+    else
+    {
+      list uprimary;
+      uprimary[1]=ideal(1);
+      uprimary[2]=ideal(1);
+    }
+    //we need the intersection of the ideals in the list quprimary with the
+    //polynomialring, i.e. let q=(f1,...,fr) in the quotientring such an ideal
+    //but fi polynomials, then the intersection of q with the polynomialring
+    //is the saturation of the ideal generated by f1,...,fr with respect to
+    //h which is the lcm of the leading coefficients of the fi considered in
+    //in the quotientring: this is coded in saturn
+
+    list saturn;
+    ideal hpl;
+
+    for(@n=1;@n<=size(uprimary);@n++)
+    {
+      uprimary[@n]=interred(uprimary[@n]); // temporary fix
+      hpl=0;
+      for(@n1=1;@n1<=size(uprimary[@n]);@n1++)
+      {
+        hpl=hpl,leadcoef(uprimary[@n][@n1]);
+      }
+      saturn[@n]=hpl;
+    }
+
+    //--------------------------------------------------------------------
+    //we leave  the quotientring   K(var(nnp+1),..,var(nva))[..the rest..]
+    //back to the polynomialring
+    //---------------------------------------------------------------------
+    setring gnir;
+
+    collectprimary=imap(quotring,uprimary);
+    lsau=imap(quotring,saturn);
+    @h=imap(quotring, at h);
+
+    kill quotring;
+    def quotring;
+
+    @n2=size(quprimary);
+    @n3=@n2;
+
+    for(@n1=1;@n1<=size(collectprimary) div 2;@n1++)
+    {
+      if(deg(collectprimary[2*@n1][1])>0)
+      {
+        @n2++;
+        quprimary[@n2]=collectprimary[2*@n1-1];
+        lnew[@n2]=lsau[2*@n1-1];
+        @n2++;
+        lnew[@n2]=lsau[2*@n1];
+        quprimary[@n2]=collectprimary[2*@n1];
+        if(abspri)
+        {
+          absprimary[@n2 div 2]=absprimarytmp[@n1];
+          abskeep[@n2 div 2]=abskeeptmp[@n1];
+        }
+      }
+    }
+    //here the intersection with the polynomialring
+    //mentioned above is really computed
+    for(@n=@n3 div 2+1;@n<=@n2 div 2;@n++)
+    {
+      if(specialIdealsEqual(quprimary[2*@n-1],quprimary[2*@n]))
+      {
+        quprimary[2*@n-1]=sat2(quprimary[2*@n-1],lnew[2*@n-1])[1];
+        quprimary[2*@n]=quprimary[2*@n-1];
+      }
+      else
+      {
+        if(@wr==0)
+        {
+          quprimary[2*@n-1]=sat2(quprimary[2*@n-1],lnew[2*@n-1])[1];
+        }
+        quprimary[2*@n]=sat2(quprimary[2*@n],lnew[2*@n])[1];
+      }
+    }
+
+    if(size(@h)>0)
+    {
+      //---------------------------------------------------------------
+      //we change to @Phelp to have the ordering dp for saturation
+      //---------------------------------------------------------------
+      setring @Phelp;
+      @h=imap(gnir, at h);
+      if(@wr!=1)
+      {
+        if(defined(@LL)){kill @LL;}
+        list @LL=minSat(jwork, at h);
+        @Ptest=intersect(@Ptest, at LL[1]);
+        @q=@LL[2];
+      }
+      else
+      {
+        fac=ideal(0);
+        for(lauf=1;lauf<=ncols(@h);lauf++)
+        {
+          if(deg(@h[lauf])>0)
+          {
+            fac=fac+factorize(@h[lauf],1);
+          }
+        }
+        fac=simplify(fac,6);
+        @q=1;
+        for(lauf=1;lauf<=size(fac);lauf++)
+        {
+          @q=@q*fac[lauf];
+        }
+      }
+      jwork=std(jwork, at q);
+      keepdi=dim(jwork);
+      if(keepdi<di)
+      {
+        setring gnir;
+        @j=imap(@Phelp,jwork);
+        break;
+      }
+      if(homo==1)
+      {
+        @hilb=hilb(jwork,1, at w);
+      }
+
+      setring gnir;
+      @j=imap(@Phelp,jwork);
+    }
+  }
+
+  if((size(quprimary)==0)&&(@wr==1))
+  {
+    @j=ideal(1);
+    quprimary[1]=ideal(1);
+    quprimary[2]=ideal(1);
+  }
+  if((size(quprimary)==0))
+  {
+    keepdi=di-1;
+    quprimary[1]=ideal(1);
+    quprimary[2]=ideal(1);
+  }
+  //---------------------------------------------------------------
+  //notice that j=sat(j,gh) intersected with (j,gh^n)
+  //we finished with sat(j,gh) and have to start with (j,gh^n)
+  //---------------------------------------------------------------
+  if((deg(@j[1])!=0)&&(@wr!=1))
+  {
+    if(size(quprimary)>0)
+    {
+      setring @Phelp;
+      ser=imap(gnir,ser);
+      hquprimary=imap(gnir,quprimary);
+      if(@wr==0)
+      {
+        //HIER STATT DURCHSCHNITT SATURIEREN!
+        ideal htest=@Ptest;
+      }
+      else
+      {
+        ideal htest=hquprimary[2];
+
+        for (@n1=2;@n1<=size(hquprimary) div 2;@n1++)
+        {
+          htest=intersect(htest,hquprimary[2*@n1]);
+        }
+      }
+
+      if(size(ser)>0)
+      {
+        ser=intersect(htest,ser);
+      }
+      else
+      {
+        ser=htest;
+      }
+      setring gnir;
+      ser=imap(@Phelp,ser);
+    }
+    if(size(reduce(ser,peek,1))!=0)
+    {
+      for(@m=1;@m<=size(restindep);@m++)
+      {
+        // if(restindep[@m][3]>=keepdi)
+        // {
+        isat=0;
+        @n2=0;
+
+        if(restindep[@m][1]==varstr(basering))
+           //the good case, nothing to do, just to have the same notations
+           //change the ring
+        {
+          def gnir1=ring(ringlist(basering));
+          setring gnir1;
+          ideal @j=fetch(gnir,jkeep);
+          attrib(@j,"isSB",1);
+        }
+        else
+        {
+          @va=string(maxideal(1));
+          execute("ring gnir1 = ("+charstr(basering)+"),("+
+                      restindep[@m][1]+"),(" +restindep[@m][2]+");");
+          execute("map phi=gnir,"+ at va+";");
+          op=option(get);
+          option(redSB);
+          if(homo==1)
+          {
+            ideal @j=std(phi(jkeep),keephilb, at w);
+          }
+          else
+          {
+            ideal @j=groebner(phi(jkeep));
+          }
+          ideal ser=phi(ser);
+          option(set,op);
+        }
+
+        for (lauf=1;lauf<=size(@j);lauf++)
+        {
+          fett[lauf]=size(@j[lauf]);
+        }
+        //------------------------------------------------------------------
+        //we have now the following situation:
+        //j intersected with K[var(nnp+1),..,var(nva)] is zero so we may
+        //pass to this quotientring, j is their still a standardbasis, the
+        //leading coefficients of the polynomials  there (polynomials in
+        //K[var(nnp+1),..,var(nva)]) are collected in the list h,
+        //we need their ggt, gh, because of the following:
+        //let (j:gh^n)=(j:gh^infinity) then
+        //j*K(var(nnp+1),..,var(nva))[..the rest..]
+        //intersected with K[var(1),...,var(nva)] is (j:gh^n)
+        //on the other hand j=(j,gh^n) intersected with (j:gh^n)
+
+        //------------------------------------------------------------------
+
+        //the arrangement for the quotientring
+        // K(var(nnp+1),..,var(nva))[..the rest..]
+        //and the map phi:K[var(1),...,var(nva)] ---->
+        //--->K(var(nnpr+1),..,var(nva))[..the rest..]
+        //------------------------------------------------------------------
+        if (defined(quotring)==voice) {kill quotring;}
+        def quotring=prepareQuotientring(nvars(basering)-restindep[@m][3],"lp");
+
+        //------------------------------------------------------------------
+        //we pass to the quotientring  K(var(nnp+1),..,var(nva))[..rest..]
+        //------------------------------------------------------------------
+
+        setring quotring;
+
+        // @j considered in the quotientring
+        ideal @j=imap(gnir1, at j);
+        ideal ser=imap(gnir1,ser);
+
+        kill gnir1;
+
+        //j is a standardbasis in the quotientring but usually not minimal
+        //here it becomes minimal
+        @j=clearSB(@j,fett);
+        attrib(@j,"isSB",1);
+
+        //we need later ggt(h[1],...)=gh for saturation
+        ideal @h;
+
+        for(@n=1;@n<=size(@j);@n++)
+        {
+          @h[@n]=leadcoef(@j[@n]);
+        }
+        //the primary decomposition of j*K(var(nnp+1),..,var(nva))[..rest..]
+
+        op=option(get);
+        option(redSB);
+        list uprimary= zero_decomp(@j,ser, at wr);
+//HIER
+        if(abspri)
+        {
+          ideal II;
+          ideal jmap;
+          map sigma;
+          nn=nvars(basering);
+          map invsigma=basering,maxideal(1);
+          for(ab=1;ab<=size(uprimary) div 2;ab++)
+          {
+            II=uprimary[2*ab];
+            attrib(II,"isSB",1);
+            if(deg(II[1])!=vdim(II))
+            {
+              jmap=randomLast(50);
+              sigma=basering,jmap;
+              jmap[nn]=2*var(nn)-jmap[nn];
+              invsigma=basering,jmap;
+              II=groebner(sigma(II));
+            }
+            absprimarytmp[ab]= absFactorize(II[1],77);
+            II=var(nn);
+            abskeeptmp[ab]=string(invsigma(II));
+            invsigma=basering,maxideal(1);
+          }
+        }
+        option(set,op);
+
+        //we need the intersection of the ideals in the list quprimary with
+        //the polynomialring, i.e. let q=(f1,...,fr) in the quotientring
+        //such an ideal but fi polynomials, then the intersection of q with
+        //the polynomialring is the saturation of the ideal generated by
+        //f1,...,fr with respect toh which is the lcm of the leading
+        //coefficients of the fi considered in the quotientring:
+        //this is coded in saturn
+
+        list saturn;
+        ideal hpl;
+
+        for(@n=1;@n<=size(uprimary);@n++)
+        {
+          hpl=0;
+          for(@n1=1;@n1<=size(uprimary[@n]);@n1++)
+          {
+            hpl=hpl,leadcoef(uprimary[@n][@n1]);
+          }
+          saturn[@n]=hpl;
+        }
+        //------------------------------------------------------------------
+        //we leave  the quotientring   K(var(nnp+1),..,var(nva))[..rest..]
+        //back to the polynomialring
+        //------------------------------------------------------------------
+        setring gnir;
+        collectprimary=imap(quotring,uprimary);
+        lsau=imap(quotring,saturn);
+        @h=imap(quotring, at h);
+
+        kill quotring;
+
+        @n2=size(quprimary);
+        @n3=@n2;
+
+        for(@n1=1;@n1<=size(collectprimary) div 2;@n1++)
+        {
+          if(deg(collectprimary[2*@n1][1])>0)
+          {
+            @n2++;
+            quprimary[@n2]=collectprimary[2*@n1-1];
+            lnew[@n2]=lsau[2*@n1-1];
+            @n2++;
+            lnew[@n2]=lsau[2*@n1];
+            quprimary[@n2]=collectprimary[2*@n1];
+            if(abspri)
+            {
+              absprimary[@n2 div 2]=absprimarytmp[@n1];
+              abskeep[@n2 div 2]=abskeeptmp[@n1];
+            }
+          }
+        }
+
+
+        //here the intersection with the polynomialring
+        //mentioned above is really computed
+
+        for(@n=@n3 div 2+1;@n<=@n2 div 2;@n++)
+        {
+          if(specialIdealsEqual(quprimary[2*@n-1],quprimary[2*@n]))
+          {
+            quprimary[2*@n-1]=sat2(quprimary[2*@n-1],lnew[2*@n-1])[1];
+            quprimary[2*@n]=quprimary[2*@n-1];
+          }
+          else
+          {
+            if(@wr==0)
+            {
+              quprimary[2*@n-1]=sat2(quprimary[2*@n-1],lnew[2*@n-1])[1];
+            }
+            quprimary[2*@n]=sat2(quprimary[2*@n],lnew[2*@n])[1];
+          }
+        }
+        if(@n2>=@n3+2)
+        {
+          setring @Phelp;
+          ser=imap(gnir,ser);
+          hquprimary=imap(gnir,quprimary);
+          for(@n=@n3 div 2+1;@n<=@n2 div 2;@n++)
+          {
+            if(@wr==0)
+            {
+              ser=intersect(ser,hquprimary[2*@n-1]);
+            }
+            else
+            {
+              ser=intersect(ser,hquprimary[2*@n]);
+            }
+          }
+          setring gnir;
+          ser=imap(@Phelp,ser);
+        }
+
+         // }
+      }
+//HIER
+      if(abspri)
+      {
+        list resu,tempo;
+        for(ab=1;ab<=size(quprimary) div 2;ab++)
+        {
+          if (deg(quprimary[2*ab][1])!=0)
+          {
+            tempo=quprimary[2*ab-1],quprimary[2*ab],
+                         absprimary[ab],abskeep[ab];
+            resu[ab]=tempo;
+          }
+        }
+        quprimary=resu;
+        @wr=3;
+      }
+      if(size(reduce(ser,peek,1))!=0)
+      {
+        if(@wr>0)
+        {
+          htprimary=decomp(@j, at wr,peek,ser);
+        }
+        else
+        {
+          htprimary=decomp(@j,peek,ser);
+        }
+        // here we collect now both results primary(sat(j,gh))
+        // and primary(j,gh^n)
+        @n=size(quprimary);
+        for (@k=1;@k<=size(htprimary);@k++)
+        {
+          quprimary[@n+ at k]=htprimary[@k];
+        }
+      }
+    }
+  }
+  else
+  {
+    if(abspri)
+    {
+      list resu,tempo;
+      for(ab=1;ab<=size(quprimary) div 2;ab++)
+      {
+        tempo=quprimary[2*ab-1],quprimary[2*ab],
+                   absprimary[ab],abskeep[ab];
+        resu[ab]=tempo;
+      }
+      quprimary=resu;
+    }
+  }
+  //---------------------------------------------------------------------------
+  //back to the ring we started with
+  //the final result: primary
+  //---------------------------------------------------------------------------
+  setring @P;
+  primary=imap(gnir,quprimary);
+  if(!abspri)
+  {
+    primary=cleanPrimary(primary);
+  }
+  if (size(primary)>0)
+  {
+    if (abspri && (typeof(primary[1][1])=="poly"))
+    { return(prepare_absprimdec(primary));}
+  }
+  return(primary);
+}
+
+
+example
+{ "EXAMPLE:"; echo = 2;
+   ring  r = 32003,(x,y,z),lp;
+   poly  p = z2+1;
+   poly  q = z4+2;
+   ideal i = p^2*q^3,(y-z3)^3,(x-yz+z4)^4;
+   list pr= decomp(i);
+   pr;
+   testPrimary( pr, i);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static proc powerCoeffs(poly f,int e)
+//computes a polynomial with the same monomials as f but coefficients
+//the p^e th power of the coefficients of f
+{
+   ASSUME(1, hasFieldCoefficient(basering) );
+   ASSUME(1, not isQuotientRing(basering) ) ;
+   ASSUME(1, hasGlobalOrdering(basering) ) ;
+
+   int i;
+   poly g;
+   int ex=char(basering)^e;
+   for(i=1;i<=size(f);i++)
+   {
+      g=g+leadcoef(f[i])^ex*leadmonom(f[i]);
+   }
+   return(g);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc sep(poly f,int i, list #)
+"USAGE:  input: a polynomial f depending on the i-th variable and optional
+         an integer k considering the polynomial f defined over Fp(t1,...,tm)
+         as polynomial over Fp(t(1)^(p^-k),...,t(m)^(p^-k))
+ RETURN: the separabel part of f as polynomial in Fp(t1,...,tm)
+        and an integer k to indicate that f should be considerd
+        as polynomial over Fp(t(1)^(p^-k),...,t(m)^(p^-k))
+ EXAMPLE: example sep; shows an example
+{
+   ASSUME(0, hasFieldCoefficient(basering) );
+   ASSUME(0, not isQuotientRing(basering) ) ;
+   ASSUME(0, hasGlobalOrdering(basering) ) ;
+
+   def R=basering;
+   int k;
+   if(size(#)>0){k=#[1];}
+
+
+   poly h=gcd(f,diff(f,var(i)));
+   if((reduce(f,std(h))!=0)||(reduce(diff(f,var(i)),std(h))!=0))
+   {
+      ERROR("FEHLER IN GCD");
+   }
+   poly g1=lift(h,f)[1][1];    //  f/h
+   poly h1;
+
+   while(h!=h1)
+   {
+      h1=h;
+      h=gcd(h,diff(h,var(i)));
+   }
+
+   if(deg(h1)==0){return(list(g1,k));} //in characteristic 0 we return here
+
+   k++;
+
+   ideal ma=maxideal(1);
+   ma[i]=var(i)^char(R);
+   map phi=R,ma;
+   ideal hh=h;    //this is technical because preimage works only for ideals
+
+   poly u=preimage(R,phi,hh)[1]; //h=u(x(i)^p)
+
+   list g2=sep(u,i,k);           //we consider u(t(1)^(p^-1),...,t(m)^(p^-1))
+   g1=powerCoeffs(g1,g2[2]-k+1); //to have g1 over the same field as g2[1]
+
+   list g3=sep(g1*g2[1],i,g2[2]);
+   return(g3);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring R=(5,t,s),(x,y,z),dp;
+   poly f=(x^25-t*x^5+t)*(x^3+s);
+   sep(f,1);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+proc zeroRad(ideal I,list #)
+"USAGE:  zeroRad(I) , I a zero-dimensional ideal
+RETURN: the radical of I
+NOTE:  Algorithm of Kemper
+EXAMPLE: example zeroRad; shows an example"
+{
+   ASSUME(0, hasFieldCoefficient(basering) );
+   ASSUME(0, not isQuotientRing(basering) ) ;
+   ASSUME(0, hasGlobalOrdering(basering) ) ;
+
+   if(homog(I)==1){return(maxideal(1));}
+   //I needs to be a reduced standard basis
+   def R=basering;
+   int m=npars(R);
+   int n=nvars(R);
+   int p=char(R);
+   int d=vdim(I);
+   int i,k;
+   list l;
+   if(((p==0)||(p>d))&&(d==deg(I[1])))
+   {
+     intvec e=leadexp(I[1]);
+     for(i=1;i<=nvars(basering);i++)
+     {
+       if(e[i]!=0) break;
+     }
+     I[1]=sep(I[1],i)[1];
+     return(interred(I));
+   }
+   intvec op=option(get);
+
+   option(redSB);
+   ASSUME(1, dim(I)==0);
+   ideal F=finduni(I);//F[i] generates I intersected with K[var(i)]
+
+   option(set,op);
+   if(size(#)>0){I=#[1];}
+
+   for(i=1;i<=n;i++)
+   {
+     l[i]=sep(F[i],i);
+     F[i]=l[i][1];
+     if(l[i][2]>k){k=l[i][2];}  //computation of the maximal k
+   }
+
+   if((k==0)||(m==0)) //the separable case
+   {
+     intvec save=option(get);
+     option(redSB);
+     I=interred(I+F);
+     option(set,save);
+     return(I);
+   }
+   //I=simplify(I,1);
+
+   for(i=1;i<=n;i++)             //consider all polynomials over
+   {                             //Fp(t(1)^(p^-k),...,t(m)^(p^-k))
+      F[i]=powerCoeffs(F[i],k-l[i][2]);
+   }
+
+   string cR="ring @R="+string(p)+",("+parstr(R)+","+varstr(R)+"),dp;";
+   execute(cR);
+   ideal F=imap(R,F);
+
+   string nR1="ring @S1="+string(p)+",("+varstr(R)+","+parstr(R)+", at y(1..m)),dp;";
+   execute(nR1);
+   list lR=ringlist(@S1)[2];
+   lR=lR[(size(lR)-m+1)..(size(lR))];
+
+   string nR="ring @S="+string(p)+",("+string(lR)+","+varstr(R)+","+parstr(R)+"),dp;";
+   execute(nR);
+
+   ideal G=fetch(@R,F);    //G[i](t(1)^(p^-k),...,t(m)^(p^-k),x(i))=sep(F[i])
+
+   ideal I=imap(R,I);
+   ideal J=I+G;
+   poly el=1;
+   k=p^k;
+   for(i=1;i<=m;i++)
+   {
+     J=J,var(i)^k-var(m+n+i);
+     el=el*var(i);
+   }
+
+   J=eliminate(J,el);
+   setring R;
+   ideal J=imap(@S,J);
+   return(J);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring R=(5,t),(x,y),dp;
+   ideal I=x^5-t,y^5-t;
+   zeroRad(I);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc radicalEHV(ideal i)
+"USAGE:   radicalEHV(i); i ideal.
+RETURN:  ideal, the radical of i.
+NOTE:    Uses the algorithm of Eisenbud/Huneke/Vasconcelos, which
+         reduces the computation to the complete intersection case,
+         by taking, in the general case, a generic linear combination
+         of the input.
+         Works only in characteristic 0 or p large.
+EXAMPLE: example radicalEHV; shows an example
+"
+{
+   ASSUME(0, hasFieldCoefficient(basering) );
+   ASSUME(0, not isQuotientRing(basering) ) ;
+   if(attrib(basering,"global")!=1)
+   {
+      ERROR(
+      "// Not implemented for this ordering, please change to global ordering."
+      );
+   }
+
+   if((char(basering)<100)&&(char(basering)!=0))
+   {
+      "WARNING: The characteristic is too small, the result may be wrong";
+   }
+   if ( size(i)==0 ) { return(ideal(0)); }
+
+   ideal J,I,I0,radI0,L,radI1,I2,radI2;
+   int l,n;
+   intvec op=option(get);
+   matrix M;
+
+   option(redSB);
+   list m=mstd(i);
+        I=m[2];
+   option(set,op);
+
+   if ( dim(m[1])<0 ) { return(ideal(1)); }
+
+   int cod=nvars(basering)-dim(m[1]);
+   //-------------------complete intersection case:----------------------
+   if(cod==size(m[2]))
+   {
+     J=minor(jacob(I),cod);
+     return(quotient(I,J));
+   }
+   //-----first codim elements of I are a complete intersection:---------
+   for(l=1;l<=cod;l++)
+   {
+      I0[l]=I[l];
+   }
+   n=dim(std(I0))+cod-nvars(basering);
+   //-----last codim elements of I are a complete intersection:----------
+   if(n!=0)
+   {
+      for(l=1;l<=cod;l++)
+      {
+         I0[l]=I[size(I)-l+1];
+      }
+      n=dim(std(I0))+cod-nvars(basering);
+   }
+   //-----taking a generic linear combination of the input:--------------
+   if(n!=0)
+   {
+      M=transpose(sparsetriag(size(m[2]),cod,95,1));
+      I0=ideal(M*transpose(I));
+      n=dim(std(I0))+cod-nvars(basering);
+   }
+   //-----taking a more generic linear combination of the input:---------
+   if(n!=0)
+   {
+      M=transpose(sparsetriag(size(m[2]),cod,0,100));
+      I0=ideal(M*transpose(I));
+      n=dim(std(I0))+cod-nvars(basering);
+   }
+   if(n==0)
+   {
+      J=minor(jacob(I0),cod);
+      radI0=quotient(I0,J);
+      L=quotient(radI0,I);
+      radI1=quotient(radI0,L);
+
+      if(size(reduce(radI1,m[1],1))==0)
+      {
+         return(I);
+      }
+
+      I2=sat(I,radI1)[1];
+
+      if(deg(I2[1])<=0)
+      {
+         return(radI1);
+      }
+      return(intersect(radI1,radicalEHV(I2)));
+   }
+   //---------------------general case-------------------------------------
+   return(radical(I));
+}
+example
+{ "EXAMPLE:";  echo = 2;
+   ring  r = 0,(x,y,z),dp;
+   poly  p = z2+1;
+   poly  q = z3+2;
+   ideal i = p*q^2,y-z2;
+   ideal pr= radicalEHV(i);
+   pr;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc Ann(module M)
+"USAGE:   Ann(M);  M module
+RETURN:  ideal, the annihilator of coker(M)
+NOTE:    The output is the ideal of all elements a of the basering R such that
+         a * R^m is contained in M  (m=number of rows of M).
+EXAMPLE: example Ann; shows an example
+"
+{
+
+  M=prune(M);  //to obtain a small embedding
+  ideal ann=quotient1(M,freemodule(nrows(M)));
+  return(ann);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring  r = 0,(x,y,z),lp;
+   module M = x2-y2,z3;
+   Ann(M);
+   M = [1,x2],[y,x];
+   Ann(M);
+   qring Q=std(xy-1);
+   module M=imap(r,M);
+   Ann(M);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+//computes the equidimensional part of the ideal i of codimension e
+static proc int_ass_primary_e(ideal i, int e)
+{
+  ASSUME(1, hasFieldCoefficient(basering) );
+  ASSUME(1, not isQuotientRing(basering) ) ;
+  ASSUME(1, hasGlobalOrdering(basering) ) ;
+
+  if(homog(i)!=1)
+  {
+     i=std(i);
+  }
+  list re=sres(i,0);                   //the resolution
+  re=minres(re);                       //minimized resolution
+  ideal ann = AnnExt_R(e,re);
+  if ( nvars(basering)-dim(std(ann)) != e )
+  {
+    return( ideal(1) );
+  }
+  return(ann);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+//computes the annihilator of Ext^n(R/i,R) with given resolution re
+//n is not necessarily the number of variables
+// !! borrowed correct code from 'ehv.lib::AnnExtEHV' by Kai Dehmann !! duplicate code!! (jk)
+
+static proc AnnExt_R(int n,list re)
+"USAGE:   AnnExt_R(n,re); n integer, re resolution
+RETURN:  ideal, the annihilator of Ext^n(R/I,R) with given
+         resolution re of I
+"
+{
+
+  if(n < 0)
+  {
+    return(ideal(1));
+  }
+  int l = size(re);
+
+  if(n < l)
+  {
+    matrix f = transpose(re[n+1]);
+    if(n == 0)
+    {
+      matrix g = matrix(0,1,ncols(f));
+    }
+    else
+    {
+      matrix g = transpose(re[n]);
+    }
+    module k = syz(f);
+    return(quotient1(g,k));
+  }
+
+  if(n == l)
+  {
+    return(Ann(transpose(re[n])));
+  }
+
+  return(ideal(1));
+}
+///////////////////////////////////////////////////////////////////////////////
+
+static proc analyze(list pr)
+{
+   ASSUME(1, hasFieldCoefficient(basering) );
+   ASSUME(1, not isQuotientRing(basering) ) ;
+   ASSUME(1, hasGlobalOrdering(basering) ) ;
+
+   int ii,jj;
+   for(ii=1;ii<=size(pr) div 2;ii++)
+   {
+      dim(std(pr[2*ii]));
+      idealsEqual(pr[2*ii-1],pr[2*ii]);
+      "===========================";
+   }
+
+   for(ii=size(pr) div 2;ii>1;ii--)
+   {
+      for(jj=1;jj<ii;jj++)
+      {
+         if(size(reduce(pr[2*jj],std(pr[2*ii],1)))==0)
+         {
+            "eingebette Komponente";
+            jj;
+            ii;
+         }
+      }
+   }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//                  Shimoyama-Yokoyama
+//
+///////////////////////////////////////////////////////////////////////////////
+static proc simplifyIdeal(ideal i)
+{
+  ASSUME(1, hasFieldCoefficient(basering) );
+  ASSUME(1, hasGlobalOrdering(basering) ) ;
+
+  def r=basering;
+
+  ideal iwork=i;
+  ideal imap2=maxideal(1);
+
+  int j,k;
+  map phi;
+  poly p;
+  ideal imap1=maxideal(1);
+  // first try: very simple substitutions
+  intvec tested=0:nvars(r);
+  for(j=1;j<=nvars(r);j++)
+  {
+    for(k=1;k<=ncols(i);k++)
+    {
+      if(deg(iwork[k]/var(j))==0)
+      {
+        p=-1/leadcoef(iwork[k]/var(j))*iwork[k];
+        if(size(p)<=2)
+        {
+          tested[j]=1;
+          imap1[j]=p+2*var(j);
+          phi=r,imap1;
+          iwork=phi(iwork);
+          iwork=subst(iwork,var(j),0);
+          iwork[k]=var(j);
+          imap1=maxideal(1);
+          imap2[j]=-p;
+          break;
+        }
+      }
+    }
+  }
+  // second try: substitutions not so simple
+  for(j=1;j<=nvars(r);j++)
+  {
+    if (tested[j]==0)
+    {
+      for(k=1;k<=ncols(i);k++)
+      {
+        if(deg(iwork[k]/var(j))==0)
+        {
+          p=-1/leadcoef(iwork[k]/var(j))*iwork[k];
+          imap1[j]=p+2*var(j);
+          phi=r,imap1;
+          iwork=phi(iwork);
+          iwork=subst(iwork,var(j),0);
+          iwork[k]=var(j);
+          imap1=maxideal(1);
+          imap2[j]=-p;
+          break;
+        }
+      }
+    }
+  }
+  return(iwork,imap2);
+}
+
+
+///////////////////////////////////////////////////////
+// ini_mod
+// input: a polynomial p
+// output: the initial term of p as needed
+// in the context of characteristic sets
+//////////////////////////////////////////////////////
+
+static proc ini_mod(poly p)
+{
+  if (p==0)
+  {
+    return(0);
+  }
+  int n; matrix m;
+  for( n=nvars(basering); n>0; n--)
+  {
+    m=coef(p,var(n));
+    if(m[1,1]!=1)
+    {
+      p=m[2,1];
+      break;
+    }
+  }
+  if(deg(p)==0)
+  {
+    p=0;
+  }
+  return(p);
+}
+///////////////////////////////////////////////////////
+// min_ass_prim_charsets
+// input: generators of an ideal PS and an integer cho
+// If cho=0, the given ordering of the variables is used.
+// Otherwise, the system tries to find an "optimal ordering",
+// which in some cases may considerably speed up the algorithm
+// output: the minimal associated primes of PS
+// algorithm: via characteriostic sets
+//////////////////////////////////////////////////////
+
+
+static proc min_ass_prim_charsets (ideal PS, int cho)
+{
+  if((cho<0) and (cho>1))
+  {
+    ERROR("<int> must be 0 or 1");
+  }
+  intvec saveopt=option(get);
+  option(notWarnSB);
+  list L;
+  if(cho==0)
+  {
+    L=min_ass_prim_charsets0(PS);
+  }
+  else
+  {
+    L=min_ass_prim_charsets1(PS);
+  }
+  option(set,saveopt);
+  return(L);
+}
+///////////////////////////////////////////////////////
+// min_ass_prim_charsets0
+// input: generators of an ideal PS
+// output: the minimal associated primes of PS
+// algorithm: via characteristic sets
+// the given ordering of the variables is used
+//////////////////////////////////////////////////////
+
+
+static proc min_ass_prim_charsets0 (ideal PS)
+{
+  ASSUME(1, hasFieldCoefficient(basering) );
+  ASSUME(1, not isQuotientRing(basering) ) ;
+  ASSUME(1, hasGlobalOrdering(basering) ) ;
+
+  intvec op;
+  matrix m=char_series(PS);  // We compute an irreducible
+                             // characteristic series
+  if ((nrows(m)==1)
+  && (ncols(m)==1)
+  && (m[1,1]==1)) // in case of an empty series: min_ass_prim_charsets1
+  {
+    return min_ass_prim_charsets1(PS);
+  }
+  int i,j,k;
+  list PSI;
+  list PHI;  // the ideals given by the characteristic series
+  for(i=nrows(m);i>=1; i--)
+  {
+    PHI[i]=ideal(m[i,1..ncols(m)]);
+  }
+  // We compute the radical of each ideal in PHI
+  ideal I,JS,II;
+  int sizeJS, sizeII;
+  for(i=size(PHI);i>=1; i--)
+  {
+    I=0;
+    for(j=size(PHI[i]);j>0;j--)
+    {
+      I=I+ini_mod(PHI[i][j]);
+    }
+    JS=std(PHI[i]);
+    sizeJS=size(JS);
+    for(j=size(I);j>0;j--)
+    {
+      II=0;
+      sizeII=0;
+      k=0;
+      while(k<=sizeII)                  // successive saturation
+      {
+        op=option(get);
+        option(returnSB);
+        II=quotient(JS,I[j]);
+        option(set,op);
+        sizeII=size(II);
+        if(sizeII==sizeJS)
+        {
+          for(k=1;k<=sizeII;k++)
+          {
+            if(leadexp(II[k])!=leadexp(JS[k])) break;
+          }
+        }
+        JS=II;
+        sizeJS=sizeII;
+      }
+    }
+    PSI=insert(PSI,JS);
+  }
+  int sizePSI=size(PSI);
+  // We eliminate redundant ideals
+  for(i=1;i<sizePSI;i++)
+  {
+    for(j=i+1;j<=sizePSI;j++)
+    {
+      if(size(PSI[i])!=0)
+      {
+        if(size(PSI[j])!=0)
+        {
+          if(size(NF(PSI[i],PSI[j],1))==0)
+          {
+            PSI[j]=ideal(0);
+          }
+          else
+          {
+            if(size(NF(PSI[j],PSI[i],1))==0)
+            {
+              PSI[i]=ideal(0);
+            }
+          }
+        }
+      }
+    }
+  }
+  for(i=sizePSI;i>=1;i--)
+  {
+    if(size(PSI[i])==0)
+    {
+      PSI=delete(PSI,i);
+    }
+  }
+  return (PSI);
+}
+
+///////////////////////////////////////////////////////
+// min_ass_prim_charsets1
+// input: generators of an ideal PS
+// output: the minimal associated primes of PS
+// algorithm: via characteristic sets
+// input: generators of an ideal PS and an integer i
+// The system tries to find an "optimal ordering" of
+// the variables
+//////////////////////////////////////////////////////
+
+
+static proc min_ass_prim_charsets1 (ideal PS)
+{
+  ASSUME(1, hasFieldCoefficient(basering) );
+  ASSUME(1, not isQuotientRing(basering) ) ;
+  ASSUME(1, hasGlobalOrdering(basering) ) ;
+
+  intvec op;
+  def oldring=basering;
+  string n=system("neworder",PS);
+  execute("ring r=("+charstr(oldring)+"),("+n+"),dp;");
+  ideal PS=imap(oldring,PS);
+  matrix m=char_series(PS);  // We compute an irreducible
+                             // characteristic series
+                             // this series may be empty (1x1: 1)
+  int i,j,k,cnt;
+  while ((cnt<nvars(oldring))
+  && (nrows(m)==1)
+  && (ncols(m)==1)
+  && (m[1,1]==1)) // in case of an empty series: permute the variables
+  {
+    cnt++;
+    n=string(var(nvars(oldring)));
+    for(i=1;i<nvars(oldring);i++) { n=n+","+string(var(i)); }
+    kill r;
+    execute("ring r=("+charstr(oldring)+"),("+n+"),dp;");
+    ideal PS=imap(oldring,PS);
+    matrix m=char_series(PS);
+  }
+  ideal I;
+  list PSI;
+  list PHI;    // the ideals given by the characteristic series
+  list ITPHI;  // their initial terms
+  for(i=nrows(m);i>=1; i--)
+  {
+    PHI[i]=simplify(ideal(m[i,1..ncols(m)]),2);
+    I=0;
+    for(j=ncols(PHI[i]);j>0;j--)
+    {
+      I=I,ini_mod(PHI[i][j]);
+    }
+    I=I[2..ncols(I)];
+    ITPHI[i]=I;
+  }
+  setring oldring;
+  matrix m=imap(r,m);
+  list PHI=imap(r,PHI);
+  list ITPHI=imap(r,ITPHI);
+  // We compute the radical of each ideal in PHI
+  ideal I,JS,II;
+  int sizeJS, sizeII;
+  for(i=size(PHI);i>=1; i--)
+  {
+    I=0;
+    for(j=size(PHI[i]);j>0;j--)
+    {
+      I=I+ITPHI[i][j];
+    }
+    JS=std(PHI[i]);
+    sizeJS=size(JS);
+    for(j=size(I);j>0;j--)
+    {
+      II=0;
+      sizeII=0;
+      k=0;
+      while(k<=sizeII)                  // successive iteration
+      {
+        op=option(get);
+        option(returnSB);
+        II=quotient(JS,I[j]);
+        option(set,op);
+//std
+//         II=std(II);
+        sizeII=size(II);
+        if(sizeII==sizeJS)
+        {
+          for(k=1;k<=sizeII;k++)
+          {
+            if(leadexp(II[k])!=leadexp(JS[k])) break;
+          }
+        }
+        JS=II;
+        sizeJS=sizeII;
+      }
+    }
+    PSI=insert(PSI,JS);
+  }
+  int sizePSI=size(PSI);
+  // We eliminate redundant ideals
+  for(i=1;i<sizePSI;i++)
+  {
+    for(j=i+1;j<=sizePSI;j++)
+    {
+      if(size(PSI[i])!=0)
+      {
+        if(size(PSI[j])!=0)
+        {
+          if(size(NF(PSI[i],PSI[j],1))==0)
+          {
+            PSI[j]=ideal(0);
+          }
+          else
+          {
+            if(size(NF(PSI[j],PSI[i],1))==0)
+            {
+              PSI[i]=ideal(0);
+            }
+          }
+        }
+      }
+    }
+  }
+  for(i=sizePSI;i>=1;i--)
+  {
+    if(size(PSI[i])==0)
+    {
+      PSI=delete(PSI,i);
+    }
+  }
+  return (PSI);
+}
+
+
+/////////////////////////////////////////////////////
+// proc prim_dec
+// input:  generators of an ideal I and an integer choose
+// If choose=0, min_ass_prim_charsets with the given
+// ordering of the variables is used.
+// If choose=1, min_ass_prim_charsets with the "optimized"
+// ordering of the variables is used.
+// If choose=2, minAssPrimes from primdec.lib is used
+// If choose=3, minAssPrimes+factorizing Buchberger from primdec.lib is used
+// output: a primary decomposition of I, i.e., a list
+// of pairs consisting of a standard basis of a primary component
+// of I and a standard basis of the corresponding associated prime.
+// To compute the minimal associated primes of a given ideal
+// min_ass_prim_l is called, i.e., the minimal associated primes
+// are computed via characteristic sets.
+// In the homogeneous case, the performance of the procedure
+// will be improved if I is already given by a minimal set of
+// generators. Apply minbase if necessary.
+//////////////////////////////////////////////////////////
+
+
+static proc prim_dec(ideal I, int choose)
+{
+  ASSUME(1, hasFieldCoefficient(basering) );
+  ASSUME(1, not isQuotientRing(basering) ) ;
+  ASSUME(1, hasGlobalOrdering(basering) ) ;
+
+  if((choose<0) or (choose>3))
+  {
+    ERROR("ERROR: <int> must be 0 or 1 or 2 or 3");
+  }
+  ideal H=1; // The intersection of the primary components
+  list U;    // the leaves of the decomposition tree, i.e.,
+             // pairs consisting of a primary component of I
+             // and the corresponding associated prime
+  list W;    // the non-leaf vertices in the decomposition tree.
+             // every entry has 6 components:
+                // 1- the vertex itself , i.e., a standard bais of the
+                //    given ideal I (type 1), or a standard basis of a
+                //    pseudo-primary component arising from
+                //    pseudo-primary decomposition (type 2), or a
+                //    standard basis of a remaining component arising from
+                //    pseudo-primary decomposition or extraction (type 3)
+                // 2- the type of the vertex as indicated above
+                // 3- the weighted_tree_depth of the vertex
+                // 4- the tester of the vertex
+                // 5- a standard basis of the associated prime
+                //    of a vertex of type 2, or 0 otherwise
+                // 6- a list of pairs consisting of a standard
+                //    basis of a minimal associated prime ideal
+                //    of the father of the vertex and the
+                //    irreducible factors of the "minimal
+                //    divisor" of the seperator or extractor
+                //    corresponding to the prime ideal
+                //    as computed by the procedure minsat,
+                //    if the vertex is of type 3, or
+                //    the empty list otherwise
+  ideal SI=std(I);
+  if(SI[1]==1)  // primdecSY(ideal(1))
+  {
+    return(list());
+  }
+  intvec save=option(get);
+  option(notWarnSB);
+  int ncolsSI=ncols(SI);
+  int ncolsH=1;
+  W[1]=list(I,1,0,poly(1),ideal(0),list()); // The root of the tree
+  int weighted_tree_depth;
+  int i,j;
+  int check;
+  list V;  // current vertex
+  list VV; // new vertex
+  list QQ;
+  list WI;
+  ideal Qi,SQ,SRest,fac;
+  poly tester;
+
+  while(1)
+  {
+    i=1;
+    while(1)
+    {
+      while(i<=size(W)) // find vertex V of smallest weighted tree-depth
+      {
+        if (W[i][3]<=weighted_tree_depth) break;
+        i++;
+      }
+      if (i<=size(W)) break;
+      i=1;
+      weighted_tree_depth++;
+    }
+    V=W[i];
+    W=delete(W,i); // delete V from W
+
+    // now proceed by type of vertex V
+
+    if (V[2]==2)  // extraction needed
+    {
+      SQ,SRest,fac=extraction(V[1],V[5]);
+                        // standard basis of primary component,
+                        // standard basis of remaining component,
+                        // irreducible factors of
+                        // the "minimal divisor" of the extractor
+                        // as computed by the procedure minsat,
+      check=0;
+      for(j=1;j<=ncolsH;j++)
+      {
+        if (NF(H[j],SQ,1)!=0) // Q is not redundant
+        {
+          check=1;
+          break;
+        }
+      }
+      if(check==1)             // Q is not redundant
+      {
+        QQ=list();
+        QQ[1]=list(SQ,V[5]);  // primary component, associated prime,
+                              // i.e., standard bases thereof
+        U=U+QQ;
+        H=intersect(H,SQ);
+        H=std(H);
+        ncolsH=ncols(H);
+        check=0;
+        if(ncolsH==ncolsSI)
+        {
+          for(j=1;j<=ncolsSI;j++)
+          {
+            if(leadexp(H[j])!=leadexp(SI[j]))
+            {
+              check=1;
+              break;
+            }
+          }
+        }
+        else
+        {
+          check=1;
+        }
+        if(check==0) // H==I => U is a primary decomposition
+        {
+          option(set,save);
+          return(U);
+        }
+      }
+      if (SRest[1]!=1)        // the remaining component is not
+                              // the whole ring
+      {
+        if (rad_con(V[4],SRest)==0) // the new vertex is not the
+                                    // root of a redundant subtree
+        {
+          VV[1]=SRest;     // remaining component
+          VV[2]=3;         // pseudoprimdec_special
+          VV[3]=V[3]+1;    // weighted depth
+          VV[4]=V[4];      // the tester did not change
+          VV[5]=ideal(0);
+          VV[6]=list(list(V[5],fac));
+          W=insert(W,VV,size(W));
+        }
+      }
+    }
+    else
+    {
+      if (V[2]==3) // pseudo_prim_dec_special is needed
+      {
+        QQ,SRest=pseudo_prim_dec_special_charsets(V[1],V[6],choose);
+                         // QQ = quadruples:
+                         // standard basis of pseudo-primary component,
+                         // standard basis of corresponding prime,
+                         // seperator, irreducible factors of
+                         // the "minimal divisor" of the seperator
+                         // as computed by the procedure minsat,
+                         // SRest=standard basis of remaining component
+      }
+      else     // V is the root, pseudo_prim_dec is needed
+      {
+        QQ,SRest=pseudo_prim_dec_charsets(I,SI,choose);
+                         // QQ = quadruples:
+                         // standard basis of pseudo-primary component,
+                         // standard basis of corresponding prime,
+                         // seperator, irreducible factors of
+                         // the "minimal divisor" of the seperator
+                         // as computed by the procedure minsat,
+                         // SRest=standard basis of remaining component
+      }
+      //check
+      for(i=size(QQ);i>=1;i--)
+      //for(i=1;i<=size(QQ);i++)
+      {
+        tester=QQ[i][3]*V[4];
+        Qi=QQ[i][2];
+        if(NF(tester,Qi,1)!=0)  // the new vertex is not the
+                                // root of a redundant subtree
+        {
+          VV[1]=QQ[i][1];
+          VV[2]=2;
+          VV[3]=V[3]+1;
+          VV[4]=tester;      // the new tester as computed above
+          VV[5]=Qi;          // QQ[i][2];
+          VV[6]=list();
+          W=insert(W,VV,size(W));
+        }
+      }
+      if (SRest[1]!=1)        // the remaining component is not
+                              // the whole ring
+      {
+        if (rad_con(V[4],SRest)==0) // the vertex is not the root
+                                    // of a redundant subtree
+        {
+          VV[1]=SRest;
+          VV[2]=3;
+          VV[3]=V[3]+2;
+          VV[4]=V[4];      // the tester did not change
+          VV[5]=ideal(0);
+          WI=list();
+          for(i=1;i<=size(QQ);i++)
+          {
+            WI=insert(WI,list(QQ[i][2],QQ[i][4]));
+          }
+          VV[6]=WI;
+          W=insert(W,VV,size(W));
+        }
+      }
+    }
+  }
+  option(set,save);
+}
+
+//////////////////////////////////////////////////////////////////////////
+// proc pseudo_prim_dec_charsets
+// input: Generators of an arbitrary ideal I, a standard basis SI of I,
+// and an integer choo
+// If choo=0, min_ass_prim_charsets with the given
+// ordering of the variables is used.
+// If choo=1, min_ass_prim_charsets with the "optimized"
+// ordering of the variables is used.
+// If choo=2, minAssPrimes from primdec.lib is used
+// If choo=3, minAssPrimes+factorizing Buchberger from primdec.lib is used
+// output: a pseudo primary decomposition of I, i.e., a list
+// of pseudo primary components together with a standard basis of the
+// remaining component. Each pseudo primary component is
+// represented by a quadrupel: A standard basis of the component,
+// a standard basis of the corresponding associated prime, the
+// seperator of the component, and the irreducible factors of the
+// "minimal divisor" of the seperator as computed by the procedure minsat,
+// calls  proc pseudo_prim_dec_i
+//////////////////////////////////////////////////////////////////////////
+
+
+static proc pseudo_prim_dec_charsets (ideal I, ideal SI, int choo)
+{
+  ASSUME(1, hasFieldCoefficient(basering) );
+  ASSUME(1, not isQuotientRing(basering) ) ;
+  ASSUME(1, hasGlobalOrdering(basering) ) ;
+
+  list L;          // The list of minimal associated primes,
+                   // each one given by a standard basis
+  if((choo==0) or (choo==1))
+  {
+    L=min_ass_prim_charsets(I,choo);
+  }
+  else
+  {
+    if(choo==2)
+    {
+      L=minAssPrimes(I);
+    }
+    else
+    {
+      L=minAssPrimes(I,1);
+    }
+    for(int i=size(L);i>=1;i--)
+    {
+      L[i]=std(L[i]);
+    }
+  }
+  return (pseudo_prim_dec_i(SI,L));
+}
+
+////////////////////////////////////////////////////////////////
+// proc pseudo_prim_dec_special_charsets
+// input: a standard basis of an ideal I whose radical is the
+// intersection of the radicals of ideals generated by one prime ideal
+// P_i together with one polynomial f_i, the list V6 must be the list of
+// pairs (standard basis of P_i, irreducible factors of f_i),
+// and an integer choo
+// If choo=0, min_ass_prim_charsets with the given
+// ordering of the variables is used.
+// If choo=1, min_ass_prim_charsets with the "optimized"
+// ordering of the variables is used.
+// If choo=2, minAssPrimes from primdec.lib is used
+// If choo=3, minAssPrimes+factorizing Buchberger from primdec.lib is used
+// output: a pseudo primary decomposition of I, i.e., a list
+// of pseudo primary components together with a standard basis of the
+// remaining component. Each pseudo primary component is
+// represented by a quadrupel: A standard basis of the component,
+// a standard basis of the corresponding associated prime, the
+// seperator of the component, and the irreducible factors of the
+// "minimal divisor" of the seperator as computed by the procedure minsat,
+// calls  proc pseudo_prim_dec_i
+////////////////////////////////////////////////////////////////
+
+
+static proc pseudo_prim_dec_special_charsets (ideal SI,list V6, int choo)
+{
+  ASSUME(1, hasFieldCoefficient(basering) );
+  ASSUME(1, not isQuotientRing(basering) ) ;
+  ASSUME(1, hasGlobalOrdering(basering) ) ;
+
+  int i,j,l;
+  list m;
+  list L;
+  int sizeL;
+  ideal P,SP; ideal fac;
+  int dimSP;
+  for(l=size(V6);l>=1;l--)   // creates a list of associated primes
+                             // of I, possibly redundant
+  {
+    P=V6[l][1];
+    fac=V6[l][2];
+    for(i=ncols(fac);i>=1;i--)
+    {
+      SP=P+fac[i];
+      SP=std(SP);
+      if(SP[1]!=1)
+      {
+        if((choo==0) or (choo==1))
+        {
+          m=min_ass_prim_charsets(SP,choo);  // a list of SB
+        }
+        else
+        {
+          if(choo==2)
+          {
+            m=minAssPrimes(SP);
+          }
+          else
+          {
+            m=minAssPrimes(SP,1);
+          }
+          for(j=size(m);j>=1;j--)
+            {
+              m[j]=std(m[j]);
+            }
+        }
+        dimSP=dim(SP);
+        for(j=size(m);j>=1; j--)
+        {
+          if(dim(m[j])==dimSP)
+          {
+            L=insert(L,m[j],size(L));
+          }
+        }
+      }
+    }
+  }
+  sizeL=size(L);
+  for(i=1;i<sizeL;i++)     // get rid of redundant primes
+  {
+    for(j=i+1;j<=sizeL;j++)
+    {
+      if(size(L[i])!=0)
+      {
+        if(size(L[j])!=0)
+        {
+          if(size(NF(L[i],L[j],1))==0)
+          {
+            L[j]=ideal(0);
+          }
+          else
+          {
+            if(size(NF(L[j],L[i],1))==0)
+            {
+              L[i]=ideal(0);
+            }
+          }
+        }
+      }
+    }
+  }
+  for(i=sizeL;i>=1;i--)
+  {
+    if(size(L[i])==0)
+    {
+      L=delete(L,i);
+    }
+  }
+  return (pseudo_prim_dec_i(SI,L));
+}
+
+
+////////////////////////////////////////////////////////////////
+// proc pseudo_prim_dec_i
+// input: A standard basis of an arbitrary ideal I, and standard bases
+// of the minimal associated primes of I
+// output: a pseudo primary decomposition of I, i.e., a list
+// of pseudo primary components together with a standard basis of the
+// remaining component. Each pseudo primary component is
+// represented by a quadrupel: A standard basis of the component Q_i,
+// a standard basis of the corresponding associated prime P_i, the
+// seperator of the component, and the irreducible factors of the
+// "minimal divisor" of the seperator as computed by the procedure minsat,
+////////////////////////////////////////////////////////////////
+
+
+static proc pseudo_prim_dec_i (ideal SI, list L)
+{
+  ASSUME(1, hasFieldCoefficient(basering) );
+  ASSUME(1, not isQuotientRing(basering) ) ;
+  ASSUME(1, hasGlobalOrdering(basering) ) ;
+
+  list Q;
+  if (size(L)==1)               // one minimal associated prime only
+                                // the ideal is already pseudo primary
+  {
+    Q=SI,L[1],1;
+    list QQ;
+    QQ[1]=Q;
+    return (QQ,ideal(1));
+  }
+
+  poly f0,f,g;
+  ideal fac;
+  int i,j,k,l;
+  ideal SQi;
+  ideal I'=SI;
+  list QP;
+  int sizeL=size(L);
+  for(i=1;i<=sizeL;i++)
+  {
+    fac=0;
+    for(j=1;j<=sizeL;j++)           // compute the seperator sep_i
+                                    // of the i-th component
+    {
+      if (i!=j)                       // search g not in L[i], but L[j]
+      {
+        for(k=1;k<=ncols(L[j]);k++)
+        {
+          if(NF(L[j][k],L[i],1)!=0)
+          {
+            break;
+          }
+        }
+        fac=fac+L[j][k];
+      }
+    }
+    // delete superfluous polynomials
+    fac=simplify(fac,8+2);
+    // saturation
+    SQi,f0,f,fac=minsat_ppd(SI,fac);
+    I'=I',f;
+    QP=SQi,L[i],f0,fac;
+             // the quadrupel:
+             // a standard basis of Q_i,
+             // a standard basis of P_i,
+             // sep_i,
+             // irreducible factors of
+             // the "minimal divisor" of the seperator
+             //  as computed by the procedure minsat,
+    Q[i]=QP;
+  }
+  I'=std(I');
+  return (Q, I');
+                   // I' = remaining component
+}
+
+
+////////////////////////////////////////////////////////////////
+// proc extraction
+// input: A standard basis of a pseudo primary ideal I, and a standard
+// basis of the unique minimal associated prime P of I
+// output: an extraction of I, i.e., a standard basis of the primary
+// component Q of I with associated prime P, a standard basis of the
+// remaining component, and the irreducible factors of the
+// "minimal divisor" of the extractor as computed by the procedure minsat
+////////////////////////////////////////////////////////////////
+
+
+static proc extraction (ideal SI, ideal SP)
+{
+  ASSUME(1, hasFieldCoefficient(basering) );
+  ASSUME(1, not isQuotientRing(basering) ) ;
+  ASSUME(1, hasGlobalOrdering(basering) ) ;
+
+  list indsets=indepSet(SP,0);
+  poly f;
+  if(size(indsets)!=0)      //check, whether dim P != 0
+  {
+    intvec v;               // a maximal independent set of variables
+                            // modulo P
+    string U;               // the independent variables
+    string A;               // the dependent variables
+    int j,k;
+    int a;                  //  the size of A
+    int degf;
+    ideal g;
+    list polys;
+    int sizepolys;
+    list newpoly;
+    def R=basering;
+    //intvec hv=hilb(SI,1);
+    for (k=1;k<=size(indsets);k++)
+    {
+      v=indsets[k];
+      for (j=1;j<=nvars(R);j++)
+      {
+        if (v[j]==1)
+        {
+          U=U+varstr(j)+",";
+        }
+        else
+        {
+          A=A+varstr(j)+",";
+          a++;
+        }
+      }
+
+      U[size(U)]=")";           // we compute the extractor of I (w.r.t. U)
+      execute("ring RAU=("+charstr(basering)+"),("+A+U+",(dp("+string(a)+"),dp);");
+      ideal I=imap(R,SI);
+      //I=std(I,hv);            // the standard basis in (R[U])[A]
+      I=std(I);            // the standard basis in (R[U])[A]
+      A[size(A)]=")";
+      execute("ring Rloc=("+charstr(basering)+","+U+",("+A+",dp;");
+      ideal I=imap(RAU,I);
+      //"std in lokalisierung:"+newline,I;
+      ideal h;
+      for(j=ncols(I);j>=1;j--)
+      {
+        h[j]=leadcoef(I[j]);  // consider I in (R(U))[A]
+      }
+      setring R;
+      g=imap(Rloc,h);
+      kill RAU,Rloc;
+      U="";
+      A="";
+      a=0;
+      f=lcm(g);
+      newpoly[1]=f;
+      polys=polys+newpoly;
+      newpoly=list();
+    }
+    f=polys[1];
+    degf=deg(f);
+    sizepolys=size(polys);
+    for (k=2;k<=sizepolys;k++)
+    {
+      if (deg(polys[k])<degf)
+      {
+        f=polys[k];
+        degf=deg(f);
+      }
+    }
+  }
+  else
+  {
+    f=1;
+  }
+  poly f0,h0; ideal SQ; ideal fac;
+  if(f!=1)
+  {
+    SQ,f0,h0,fac=minsat(SI,f);
+    return(SQ,std(SI+h0),fac);
+             // the tripel
+             // a standard basis of Q,
+             // a standard basis of remaining component,
+             // irreducible factors of
+             // the "minimal divisor" of the extractor
+             // as computed by the procedure minsat
+  }
+  else
+  {
+    return(SI,ideal(1),ideal(1));
+  }
+}
+
+/////////////////////////////////////////////////////
+// proc minsat
+// input:  a standard basis of an ideal I and a polynomial p
+// output: a standard basis IS of the saturation of I w.r. to p,
+// the maximal squarefree factor f0 of p,
+// the "minimal divisor" f of f0 such that the saturation of
+// I w.r. to f equals the saturation of I w.r. to f0 (which is IS),
+// the irreducible factors of f
+//////////////////////////////////////////////////////////
+
+
+static proc minsat(ideal SI, poly p)
+{
+  ASSUME(1, hasFieldCoefficient(basering) );
+  ASSUME(1, not isQuotientRing(basering) ) ;
+  ASSUME(1, hasGlobalOrdering(basering) ) ;
+
+  ideal fac=factorize(p,1);       //the irreducible factors of p
+  fac=sort(fac)[1];
+  int i,k;
+  poly f0=1;
+  for(i=ncols(fac);i>=1;i--)
+  {
+    f0=f0*fac[i];
+  }
+  poly f=1;
+  ideal iold;
+  list quotM;
+  quotM[1]=SI;
+  quotM[2]=fac;
+  quotM[3]=f0;
+  // we deal seperately with the first quotient;
+  // factors, which do not contribute to this one,
+  // are omitted
+  iold=quotM[1];
+  quotM=minquot(quotM);
+  fac=quotM[2];
+  if(quotM[3]==1)
+    {
+      return(quotM[1],f0,f,fac);
+    }
+  while(special_ideals_equal(iold,quotM[1])==0)
+    {
+      f=f*quotM[3];
+      iold=quotM[1];
+      quotM=minquot(quotM);
+    }
+  return(quotM[1],f0,f,fac);           // the quadrupel ((I:p),f0,f, irr. factors of f)
+}
+
+/////////////////////////////////////////////////////
+// proc minsat_ppd
+// input:  a standard basis of an ideal I and a polynomial p
+// output: a standard basis IS of the saturation of I w.r. to p,
+// the maximal squarefree factor f0 of p,
+// the "minimal divisor" f of f0 such that the saturation of
+// I w.r. to f equals the saturation of I w.r. to f0 (which is IS),
+// the irreducible factors of f
+//////////////////////////////////////////////////////////
+
+
+static proc minsat_ppd(ideal SI, ideal fac)
+{
+  ASSUME(1, hasFieldCoefficient(basering) );
+  ASSUME(1, not isQuotientRing(basering) ) ;
+  ASSUME(1, hasGlobalOrdering(basering) ) ;
+
+  fac=sort(fac)[1];
+  int i,k;
+  poly f0=1;
+  for(i=ncols(fac);i>=1;i--)
+  {
+    f0=f0*fac[i];
+  }
+  poly f=1;
+  ideal iold;
+  list quotM;
+  quotM[1]=SI;
+  quotM[2]=fac;
+  quotM[3]=f0;
+  // we deal seperately with the first quotient;
+  // factors, which do not contribute to this one,
+  // are omitted
+  iold=quotM[1];
+  quotM=minquot(quotM);
+  fac=quotM[2];
+  if(quotM[3]==1)
+    {
+      return(quotM[1],f0,f,fac);
+    }
+  while(special_ideals_equal(iold,quotM[1])==0)
+  {
+    f=f*quotM[3];
+    iold=quotM[1];
+    quotM=minquot(quotM);
+    k++;
+  }
+  return(quotM[1],f0,f,fac);           // the quadrupel ((I:p),f0,f, irr. factors of f)
+}
+/////////////////////////////////////////////////////////////////
+// proc minquot
+// input: a list with 3 components: a standard basis
+// of an ideal I, a set of irreducible polynomials, and
+// there product f0
+// output: a standard basis of the ideal (I:f0), the irreducible
+// factors of the "minimal divisor" f of f0 with (I:f0) = (I:f),
+// the "minimal divisor" f
+/////////////////////////////////////////////////////////////////
+
+static proc minquot(list tsil)
+{
+   ASSUME(1, hasFieldCoefficient(basering) );
+   ASSUME(1, not isQuotientRing(basering) ) ;
+   ASSUME(1, hasGlobalOrdering(basering) ) ;
+
+   intvec op;
+   int i,j,k,action;
+   ideal verg;
+   list l;
+   poly g;
+   ideal laedi=tsil[1];
+   ideal fac=tsil[2];
+   poly f=tsil[3];
+
+//std
+//   ideal star=quotient(laedi,f);
+//   star=std(star);
+   op=option(get);
+   option(returnSB);
+   ideal star=quotient(laedi,f);
+   option(set,op);
+   if(special_ideals_equal(laedi,star)==1)
+     {
+       return(laedi,ideal(1),1);
+     }
+   action=1;
+   while(action==1)
+   {
+      if(size(fac)==1)
+      {
+         action=0;
+         break;
+      }
+      for(i=1;i<=size(fac);i++)
+      {
+        g=1;
+         for(j=1;j<=size(fac);j++)
+         {
+            if(i!=j)
+            {
+               g=g*fac[j];
+            }
+         }
+//std
+//         verg=quotient(laedi,g);
+//         verg=std(verg);
+         op=option(get);
+         option(returnSB);
+         verg=quotient(laedi,g);
+         option(set,op);
+         if(special_ideals_equal(verg,star)==1)
+         {
+            f=g;
+            fac[i]=0;
+            fac=simplify(fac,2);
+            break;
+         }
+         if(i==size(fac))
+         {
+            action=0;
+         }
+      }
+   }
+   l=star,fac,f;
+   return(l);
+}
+/////////////////////////////////////////////////
+// proc special_ideals_equal
+// input: standard bases of ideal k1 and k2 such that
+// k1 is contained in k2, or k2 is contained ink1
+// output: 1, if k1 equals k2, 0 otherwise
+//////////////////////////////////////////////////
+
+static proc special_ideals_equal( ideal k1, ideal k2)
+{
+   int j;
+   if(size(k1)==size(k2))
+   {
+      for(j=1;j<=size(k1);j++)
+      {
+         if(leadexp(k1[j])!=leadexp(k2[j]))
+         {
+            return(0);
+         }
+      }
+      return(1);
+   }
+   return(0);
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+
+static proc convList(list l)
+{
+   int i;
+   list re,he;
+   for(i=1;i<=size(l) div 2;i++)
+   {
+      he=l[2*i-1],l[2*i];
+      re[i]=he;
+   }
+   return(re);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+static proc reconvList(list l)
+{
+   int i;
+   list re;
+   for(i=size(l);i>0;i--)
+   {
+      re[2*i-1]=l[i][1];
+      re[2*i]=l[i][2];
+   }
+   return(re);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//     The main procedures
+//
+///////////////////////////////////////////////////////////////////////////////
+
+proc primdecGTZ(ideal i, list #)
+"USAGE:   primdecGTZ(i); i ideal
+RETURN:  a list pr of primary ideals and their associated primes:
+ at format
+   pr[i][1]   the i-th primary component,
+   pr[i][2]   the i-th prime component.
+ at end format
+NOTE:    - Algorithm of Gianni/Trager/Zacharias.
+         - Designed for characteristic 0, works also in char k > 0, if it
+           terminates (may result in an infinite loop in small characteristic!)
+         - For local orderings, the result is considered in the localization
+           of the polynomial ring, not in the power series ring
+         - For local and mixed orderings, the decomposition in the
+           corresponding global ring is returned if the string 'global'
+           is specified as second argument
+EXAMPLE: example primdecGTZ; shows an example
+"
+{
+   ASSUME(0, hasFieldCoefficient(basering) );
+   ASSUME(0, not isQuotientRing(basering) ) ;
+   if(size(#)>0)
+   {
+      int keep_comp=1;
+   }
+   if(attrib(basering,"global")!=1)
+   {
+// algorithms only work in global case!
+// pass to appropriate global ring
+      def r=basering;
+      def s=changeord(list(list("dp",1:nvars(basering))));
+      setring s;
+      ideal i=imap(r,i);
+// decompose and go back
+      list li=primdecGTZ(i);
+      setring r;
+      def li=imap(s,li);
+// clean up
+      if(!defined(keep_comp))
+      {
+         for(int k=size(li);k>=1;k--)
+         {
+            if(mindeg(std(lead(li[k][2]))[1])==0)
+            {
+// 1 contained in ideal, i.e. component does not meet origin in local ordering
+               li=delete(li,k);
+            }
+         }
+      }
+      return(li);
+   }
+
+   if(minpoly!=0)
+   {
+      return(algeDeco(i,0));
+      ERROR(
+      "// Not implemented yet for algebraic extensions.Simulate the ring extension by adding the minpoly to the ideal"
+      );
+   }
+  return(convList(decomp(i)));
+}
+example
+{ "EXAMPLE:";  echo = 2;
+   ring  r = 0,(x,y,z),lp;
+   poly  p = z2+1;
+   poly  q = z3+2;
+   ideal i = p*q^2,y-z2;
+   list pr = primdecGTZ(i);
+   pr;
+}
+///////////////////////////////////////////////////////////////////////////////
+proc absPrimdecGTZ(ideal I, list #)
+"USAGE:   absPrimdecGTZ(I); I ideal
+ASSUME:  Ground field has characteristic 0.
+RETURN:  a ring containing two lists: @code{absolute_primes}, the absolute
+         prime components of I, and @code{primary_decomp}, the output of
+         @code{primdecGTZ(I)}.
+         The list absolute_primes has to be interpreted as follows:
+         each entry describes a class of conjugated absolute primes,
+ at format
+   absolute_primes[i][1]   the absolute prime component,
+   absolute_primes[i][2]   the number of conjugates.
+ at end format
+         The first entry of @code{absolute_primes[i][1]} is the minimal
+         polynomial of a minimal finite field extension over which the
+         absolute prime component is defined.
+         For local orderings, the result is considered in the localization
+         of the polynomial ring, not in the power series ring.
+         For local and mixed orderings, the decomposition in the
+         corresponding global ring is returned if the string 'global'
+         is specified as second argument
+NOTE:    Algorithm of Gianni/Trager/Zacharias combined with the
+         @code{absFactorize} command.
+SEE ALSO: primdecGTZ; absFactorize
+EXAMPLE: example absPrimdecGTZ; shows an example
+"
+{
+  ASSUME(0, hasFieldCoefficient(basering) );
+  ASSUME(0, not isQuotientRing(basering) ) ;
+  if (char(basering) != 0)
+  {
+    ERROR("primdec.lib::absPrimdecGTZ is only implemented for "+
+           +"characteristic 0");
+  }
+
+  if(size(#)>0)
+  {
+     int keep_comp=1;
+  }
+
+  if(attrib(basering,"global")!=1)
+  {
+// algorithm automatically passes to the global case
+// hence prepare to go back to an appropriate new ring
+      def r=basering;
+      ideal max_of_r=maxideal(1);
+      def s=changeord(list(list("dp",1:nvars(basering))));
+      setring s;
+      def I=imap(r,I);
+      def S=absPrimdecGTZ(I);
+      setring S;
+      ring r1=char(basering),var(nvars(r)+1),dp;
+      def rS=r+r1;
+// move objects to appropriate ring and clean up
+      setring rS;
+      def max_of_r=imap(r,max_of_r);
+      attrib(max_of_r,"isSB",1);
+      def absolute_primes=imap(S,absolute_primes);
+      def primary_decomp=imap(S,primary_decomp);
+      if(!defined(keep_comp))
+      {
+         ideal tempid;
+         for(int k=size(absolute_primes);k>=1;k--)
+         {
+            tempid=absolute_primes[k][1];
+            tempid[1]=0;                  // ignore minimal polynomial
+            if(size(reduce(lead(tempid),max_of_r))!=0)
+            {
+// 1 contained in ideal, i.e. component does not meet origin in local ordering
+               absolute_primes=delete(absolute_primes,k);
+            }
+         }
+         for(k=size(primary_decomp);k>=1;k--)
+         {
+            if(mindeg(std(lead(primary_decomp[k][2]))[1])==0)
+            {
+// 1 contained in ideal, i.e. component does not meet origin in local ordering
+               primary_decomp=delete(primary_decomp,k);
+            }
+         }
+         kill tempid;
+      }
+      export(primary_decomp);
+      export(absolute_primes);
+      return(rS);
+  }
+  if(minpoly!=0)
+  {
+    //return(algeDeco(i,0));
+    ERROR(
+      "// Not implemented yet for algebraic extensions.Simulate the ring extension by adding the minpoly to the ideal"
+    );
+  }
+  def R=basering;
+  int n=nvars(R);
+  list L=decomp(I,3);
+  string newvar=L[1][3];
+  int k=find(newvar,",",find(newvar,",")+1);
+  newvar=newvar[k+1..size(newvar)];
+  list lR=ringlist(R);
+  int i,de,ii;
+  intvec vv=1:n;
+  //for(i=1;i<=n;i++){vv[i]=1;}
+
+  list orst;
+  orst[1]=list("dp",vv);
+  orst[2]=list("dp",intvec(1));
+  orst[3]=list("C",0);
+  lR[3]=orst;
+  lR[2][n+1] = newvar;
+  def Rz = ring(lR);
+  setring Rz;
+  list L=imap(R,L);
+  list absolute_primes,primary_decomp;
+  ideal I,M,N,K;
+  M=maxideal(1);
+  N=maxideal(1);
+  poly p,q,f,g;
+  map phi,psi;
+  string tvar;
+  for(i=1;i<=size(L);i++)
+  {
+    tvar=L[i][4];
+    ii=find(tvar,"+");
+    while(ii)
+    {
+      tvar=tvar[ii+1..size(tvar)];
+      ii=find(tvar,"+");
+    }
+    for(ii=1;ii<=nvars(basering);ii++)
+    {
+      if(tvar==string(var(ii))) break;
+    }
+    I=L[i][2];
+    execute("K="+L[i][3]+";");
+    p=K[1];
+    q=K[2];
+    execute("f="+L[i][4]+";");
+    g=2*var(ii)-f;
+    M[ii]=f;
+    N[ii]=g;
+    de=deg(p);
+    psi=Rz,M;
+    phi=Rz,N;
+    I=phi(I),p,q;
+    I=std(I);
+    absolute_primes[i]=list(psi(I),de);
+    primary_decomp[i]=list(L[i][1],L[i][2]);
+  }
+  export(primary_decomp);
+  export(absolute_primes);
+  setring R;
+  dbprint( printlevel-voice+3,"
+// 'absPrimdecGTZ' created a ring, in which two lists absolute_primes (the
+// absolute prime components) and primary_decomp (the primary and prime
+// components over the current basering) are stored.
+// To access the list of absolute prime components, type (if the name S was
+// assigned to the return value):
+        setring S; absolute_primes; ");
+
+  return(Rz);
+}
+example
+{ "EXAMPLE:";  echo = 2;
+   ring  r = 0,(x,y,z),lp;
+   poly  p = z2+1;
+   poly  q = z3+2;
+   ideal i = p*q^2,y-z2;
+   def S = absPrimdecGTZ(i);
+   setring S;
+   absolute_primes;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc primdecSY(ideal i, list #)
+"USAGE:   primdecSY(I, c); I ideal, c int (optional)
+RETURN:  a list pr of primary ideals and their associated primes:
+ at format
+   pr[i][1]   the i-th primary component,
+   pr[i][2]   the i-th prime component.
+ at end format
+NOTE:    Algorithm of Shimoyama/Yokoyama.
+ at format
+   if c=0,  the given ordering of the variables is used,
+   if c=1,  minAssChar tries to use an optimal ordering (default),
+   if c=2,  minAssGTZ is used,
+   if c=3,  minAssGTZ and facstd are used.
+ at end format
+         For local orderings, the result is considered in the localization
+         of the polynomial ring, not in the power series ring.
+         For local and mixed orderings, the decomposition in the
+         corresponding global ring is returned if the string 'global'
+         is specified as third argument
+EXAMPLE: example primdecSY; shows an example
+"
+{
+   ASSUME(0, hasFieldCoefficient(basering) );
+   ASSUME(0, not isQuotientRing(basering) ) ;
+   if(size(#)>1)
+   {
+      int keep_comp=1;
+   }
+   if(attrib(basering,"global")!=1)
+   {
+// algorithms only work in global case!
+// pass to appropriate global ring
+      def r=basering;
+      def s=changeord(list(list("dp",1:nvars(basering))));
+      setring s;
+      ideal i=imap(r,i);
+// decompose and go back
+      list li=primdecSY(i);
+      setring r;
+      def li=imap(s,li);
+// clean up
+      if(!defined(keep_comp))
+      {
+         for(int k=size(li);k>=1;k--)
+         {
+            if(mindeg(std(lead(li[k][2]))[1])==0)
+            {
+// 1 contained in ideal, i.e. component does not meet origin in local ordering
+               li=delete(li,k);
+            }
+         }
+      }
+      return(li);
+   }
+   i=simplify(i,2);
+   if ((i[1]==0)||(i[1]==1))
+   {
+     list L=list(ideal(i[1]),ideal(i[1]));
+     return(list(L));
+   }
+
+   if(minpoly!=0)
+   {
+      return(algeDeco(i,1));
+   }
+   if (size(#)!=0)
+   { return(prim_dec(i,#[1])); }
+   else
+   { return(prim_dec(i,1)); }
+}
+example
+{ "EXAMPLE:";  echo = 2;
+   ring  r = 0,(x,y,z),lp;
+   poly  p = z2+1;
+   poly  q = z3+2;
+   ideal i = p*q^2,y-z2;
+   list pr = primdecSY(i);
+   pr;
+}
+///////////////////////////////////////////////////////////////////////////////
+proc minAssGTZ(ideal i,list #)
+"USAGE:    minAssGTZ(I[, l]); I ideal, l list (optional)
+   @* Optional parameters in list l (can be entered in any order):
+   @* 0, \"facstd\" -> uses facstd to first decompose the ideal (default)
+   @* 1, \"noFacstd\" -> does not use facstd
+   @* \"GTZ\" -> the original algorithm by Gianni, Trager and Zacharias is used
+   @* \"SL\" -> GTZ algorithm with modificiations by Laplagne is used (default)
+
+RETURN:  a list, the minimal associated prime ideals of I.
+NOTE:    - Designed for characteristic 0, works also in char k > 0 based
+           on an algorithm of Yokoyama
+         - For local orderings, the result is considered in the localization
+           of the polynomial ring, not in the power series ring
+         - For local and mixed orderings, the decomposition in the
+           corresponding global ring is returned if the string 'global'
+           is specified as second argument
+EXAMPLE: example minAssGTZ; shows an example
+"
+{
+   ASSUME(0, hasFieldCoefficient(basering) );
+   ASSUME(0, not isQuotientRing(basering) ) ;
+   if(size(#)>0)
+   {
+      int keep_comp=1;
+   }
+
+  if(attrib(basering,"global")!=1)
+  {
+  // algorithms only work in global case!
+// pass to appropriate global ring
+      def r=basering;
+      def s=changeord(list(list("dp",1:nvars(basering))));
+      setring s;
+      ideal i=imap(r,i);
+// decompose and go back
+      list li=minAssGTZ(i);
+      setring r;
+      def li=imap(s,li);
+// clean up
+      if(!defined(keep_comp))
+      {
+         for(int k=size(li);k>=1;k--)
+         {
+            if(mindeg(std(lead(li[k]))[1])==0)
+            {
+// 1 contained in ideal, i.e. component does not meet origin in local ordering
+               li=delete(li,k);
+            }
+         }
+      }
+      return(li);
+  }
+
+  int j;
+  string algorithm;
+  string facstdOption;
+  int useFac;
+
+  // Set input parameters
+  algorithm = "SL";         // Default: SL algorithm
+  facstdOption = "facstd";
+  if(size(#) > 0)
+  {
+    int valid;
+    for(j = 1; j <= size(#); j++)
+    {
+      valid = 0;
+      if((typeof(#[j]) == "int") or (typeof(#[j]) == "number"))
+      {
+        if (#[j] == 1) {facstdOption = "noFacstd"; valid = 1;}    // If #[j] == 1, facstd is not used.
+        if (#[j] == 0) {facstdOption = "facstd";   valid = 1;}    // If #[j] == 0, facstd is used.
+      }
+      if(typeof(#[j]) == "string")
+      {
+        if((#[j] == "GTZ") || (#[j] == "SL"))
+        {
+          algorithm = #[j];
+          valid = 1;
+        }
+        if((#[j] == "noFacstd") || (#[j] == "facstd"))
+        {
+          facstdOption = #[j];
+          valid = 1;
+        }
+      }
+      if(valid == 0)
+      {
+        dbprint(1, "Warning! The following input parameter was not recognized:", #[j]);
+      }
+    }
+  }
+
+  if(minpoly!=0)
+  {
+    return(algeDeco(i,2));
+  }
+
+  list result = minAssPrimes(i, facstdOption, algorithm);
+  return(result);
+}
+example
+{ "EXAMPLE:";  echo = 2;
+   ring  r = 0,(x,y,z),dp;
+   poly  p = z2+1;
+   poly  q = z3+2;
+   ideal i = p*q^2,y-z2;
+   list pr = minAssGTZ(i);
+   pr;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+proc minAssChar(ideal i, list #)
+"USAGE:   minAssChar(I[,c]); i ideal, c int (optional).
+RETURN:  list, the minimal associated prime ideals of i.
+NOTE:    If c=0, the given ordering of the variables is used. @*
+         Otherwise, the system tries to find an optimal ordering,
+         which in some cases may considerably speed up the algorithm. @*
+         For local orderings, the result is considered in the localization
+         of the polynomial ring, not in the power series ring
+         For local and mixed orderings, the decomposition in the
+         corresponding global ring is returned if the string 'global'
+         is specified as third argument
+EXAMPLE: example minAssChar; shows an example
+"
+{
+   ASSUME(0, hasFieldCoefficient(basering) );
+   ASSUME(0, not isQuotientRing(basering) ) ;
+   if(size(#)>1)
+   {
+      int keep_comp=1;
+   }
+   if(attrib(basering,"global")!=1)
+   {
+// algorithms only work in global case!
+// pass to appropriate global ring
+      def r=basering;
+      def s=changeord(list(list("dp",1:nvars(basering))));
+      setring s;
+      ideal i=imap(r,i);
+// decompose and go back
+      list li=minAssChar(i);
+      setring r;
+      def li=imap(s,li);
+// clean up
+      if(!defined(keep_comp))
+      {
+         for(int k=size(li);k>=1;k--)
+         {
+            if(mindeg(std(lead(li[k]))[1])==0)
+            {
+// 1 contained in ideal, i.e. component does not meet origin in local ordering
+               li=delete(li,k);
+            }
+         }
+      }
+      return(li);
+   }
+   if (size(#)>0)
+   { return(min_ass_prim_charsets(i,#[1])); }
+   else
+   { return(min_ass_prim_charsets(i,1)); }
+}
+example
+{ "EXAMPLE:";  echo = 2;
+   ring  r = 0,(x,y,z),dp;
+   poly  p = z2+1;
+   poly  q = z3+2;
+   ideal i = p*q^2,y-z2;
+   list pr = minAssChar(i);
+   pr;
+}
+///////////////////////////////////////////////////////////////////////////////
+proc equiRadical(ideal i)
+"USAGE:   equiRadical(I); I ideal
+RETURN:  ideal, intersection of associated primes of I of maximal dimension.
+NOTE:    A combination of the algorithms of Krick/Logar (with modifications by Laplagne) and Kemper is used.
+         Works also in positive characteristic (Kempers algorithm).
+EXAMPLE: example equiRadical; shows an example
+"
+{
+  ASSUME(0, hasFieldCoefficient(basering) );
+  ASSUME(0, not isQuotientRing(basering) ) ;
+  if(attrib(basering,"global")!=1)
+  {
+     ERROR(
+     "// Not implemented for this ordering, please change to global ordering."
+     );
+  }
+
+  return(radical(i, 1));
+}
+example
+{ "EXAMPLE:";  echo = 2;
+   ring  r = 0,(x,y,z),dp;
+   poly  p = z2+1;
+   poly  q = z3+2;
+   ideal i = p*q^2,y-z2;
+   ideal pr= equiRadical(i);
+   pr;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+proc radical(ideal i, list #)
+"USAGE: radical(I[, l]); I ideal, l list (optional)
+ @*  Optional parameters in list l (can be entered in any order):
+ @*  0, \"fullRad\" -> full radical is computed (default)
+ @*  1, \"equiRad\" -> equiRadical is computed
+ @*  \"KL\" -> Krick/Logar algorithm is used
+ @*  \"SL\" -> modifications by Laplagne are used (default)
+ @*  \"facstd\" -> uses facstd to first decompose the ideal (default for non homogeneous ideals)
+ @*  \"noFacstd\" -> does not use facstd (default for homogeneous ideals)
+RETURN:  ideal, the radical of I (or the equiradical if required in the input parameters)
+NOTE:    A combination of the algorithms of Krick/Logar (with modifications by Laplagne) and Kemper is used.
+         Works also in positive characteristic (Kempers algorithm).
+EXAMPLE: example radical; shows an example
+"
+{
+  ASSUME(0, hasFieldCoefficient(basering) );
+  ASSUME(0, not isQuotientRing(basering) ) ;
+  dbprint(printlevel - voice, "Radical, version 2006.05.08");
+  if(size(i) == 0){return(ideal(0));}
+  if(attrib(basering,"global")!=1)
+  {
+// algorithms only work in global case!
+// pass to appropriate global ring
+      def r=basering;
+      def s=changeord(list(list("dp",1:nvars(basering))));
+      setring s;
+      ideal i=imap(r,i);
+// compute radical and go back
+      def j=radical(i);
+      setring r;
+      def j=imap(s,j);
+      return(j);
+  }
+  int j;
+  def P0 = basering;
+  list Pl=ringlist(P0);
+  intvec dp_w;
+  for(j=nvars(P0);j>0;j--) {dp_w[j]=1;}
+  Pl[3]=list(list("dp",dp_w),list("C",0));
+  def @P=ring(Pl);
+  setring @P;
+  ideal i=imap(P0,i);
+
+  int il;
+  string algorithm;
+  int useFac;
+
+  // Set input parameters
+  algorithm = "SL";                                 // Default: SL algorithm
+  il = 0;                                           // Default: Full radical (not only equiRadical)
+  if (homog(i) == 1)
+  {   // Default: facStd is used, except if the ideal is homogeneous.
+    useFac = 0;
+  }
+  else
+  {
+    useFac = 1;
+  }
+  if(size(#) > 0)
+  {
+    int valid;
+    for(j = 1; j <= size(#); j++)
+    {
+      valid = 0;
+      if((typeof(#[j]) == "int") or (typeof(#[j]) == "number"))
+      {
+        il = #[j];          // If il == 1, equiRadical is computed
+        valid = 1;
+      }
+      if(typeof(#[j]) == "string")
+      {
+        if(#[j] == "KL")
+        {
+          algorithm = "KL";
+          valid = 1;
+        }
+        if(#[j] == "SL")
+        {
+          algorithm = "SL";
+          valid = 1;
+        }
+        if(#[j] == "noFacstd")
+        {
+          useFac = 0;
+          valid = 1;
+        }
+        if(#[j] == "facstd")
+        {
+          useFac = 1;
+          valid = 1;
+        }
+        if(#[j] == "equiRad")
+        {
+          il = 1;
+          valid = 1;
+        }
+        if(#[j] == "fullRad")
+        {
+          il = 0;
+          valid = 1;
+        }
+      }
+      if(valid == 0)
+      {
+        dbprint(1, "Warning! The following input parameter was not recognized:", #[j]);
+      }
+    }
+  }
+
+  ideal rad = 1;
+  intvec op = option(get);
+  list qr = simplifyIdeal(i);
+  map phi = @P, qr[2];
+
+  option(redSB);
+  i = groebner(qr[1]);
+  option(set, op);
+  int di = dim(i);
+
+  if(di == 0)
+  {
+    i = zeroRad(i, qr[1]);
+    option(redSB);
+    i=interred(phi(i));
+    option(set, op);
+    setring(P0);
+    i=imap(@P,i);
+    return(i);
+  }
+
+  option(redSB);
+  list pr;
+  if(useFac == 1)
+  {
+    pr = facstd(i);
+  }
+  else
+  {
+    pr = i;
+  }
+  option(set, op);
+  int s = size(pr);
+  if(useFac == 1)
+  {
+    dbprint(printlevel - voice, "Number of components returned by facstd: ", s);
+  }
+  for(j = 1; j <= s; j++)
+  {
+    attrib(pr[s + 1 - j], "isSB", 1);
+    if((size(reduce(rad, pr[s + 1 - j], 1)) != 0) && ((dim(pr[s + 1 - j]) == di) || !il))
+    {
+      // SL Debug messages
+      dbprint(printlevel-voice, "We shall compute the radical of ", pr[s + 1 - j]);
+      dbprint(printlevel-voice, "The dimension is: ", dim(pr[s+1-j]));
+
+      if(algorithm == "KL")
+      {
+        rad = intersect(rad, radicalKL(pr[s + 1 - j], rad, il));
+      }
+      if(algorithm == "SL")
+      {
+        rad = intersect(rad, radicalSL(pr[s + 1 - j], il));
+      }
+    }
+    else
+    {
+      // SL Debug
+      dbprint(printlevel-voice, "The radical of this component is not needed.");
+      dbprint(printlevel-voice, "size(reduce(rad, pr[s + 1 - j], 1))",
+              size(reduce(rad, pr[s + 1 - j], 1)));
+      dbprint(printlevel-voice, "dim(pr[s + 1 - j])", dim(pr[s + 1 - j]));
+      dbprint(printlevel-voice, "il", il);
+    }
+  }
+  rad=interred(phi(rad));
+  setring(P0);
+  i=imap(@P,rad);
+  return(i);
+}
+example
+{ "EXAMPLE:";  echo = 2;
+   ring  r = 0,(x,y,z),dp;
+   poly  p = z2+1;
+   poly  q = z3+2;
+   ideal i = p*q^2,y-z2;
+   ideal pr = radical(i);
+   pr;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Computes the radical of I using KL algorithm.
+// The only difference with the previous implementation of KL algorithm is
+// that now it uses block dp instead of lp ordering for the reduction to the
+// zerodimensional case.
+// The reduction step has been moved to the new routine radicalReduction, so that it can be
+// used also by radicalSL procedure.
+//
+static proc radicalKL(ideal I, ideal ser, list #)
+{
+  ASSUME(1, hasFieldCoefficient(basering) );
+  ASSUME(1, not isQuotientRing(basering) ) ;
+  ASSUME(1, hasGlobalOrdering(basering) ) ;
+
+// ideal I     The ideal for which the radical is computed
+// ideal ser   Used to reduce components already obtained
+// list #      If #[1] = 1, equiradical is computed.
+
+  // I needs to be a Groebner basis.
+  if (attrib(I, "isSB") != 1)
+  {
+    I = groebner(I);
+  }
+
+  ideal rad;                                // The radical
+  int allIndep = 1;                // All max independent sets are used
+
+  list result = radicalReduction(I, ser, allIndep, #);
+  int done = result[3];
+  rad = result[1];
+  if (done == 0)
+  {
+    rad = intersect(rad, radicalKL(result[2], ideal(1), #));
+  }
+  return(rad);
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Computes the radical of I via Laplagne algorithm, using zerodimensional radical in
+// the zero dimensional case.
+// For the reduction to the zerodimensional case, it uses the procedure
+// radical, with some modifications to avoid the recursion.
+//
+static proc radicalSL(ideal I, list #)
+// Input = I, ideal
+//         #, list. If #[1] = 1, then computes only the equiradical.
+// Output = (P, primaryDec) where P = rad(I) and primaryDec is the list of the radicals
+// obtained in intermediate steps.
+{
+  ASSUME(1, hasFieldCoefficient(basering) );
+  ASSUME(1, not isQuotientRing(basering) ) ;
+  ASSUME(1, hasGlobalOrdering(basering) ) ;
+
+  ideal rad = 1;
+  ideal equiRad = 1;
+  list primes;
+  int k;                        // Counter
+  int il;                 // If il = 1, only the equiradical is required.
+  int iDim;                // The dimension of I
+  int stop = 0;   // Checks if the radical has been obtained
+
+  if (attrib(I, "isSB") != 1)
+  {
+    I = groebner(I);
+  }
+  iDim = dim(I);
+
+  // Checks if only equiradical is required
+  if (size(#) > 0)
+  {
+    il = #[1];
+  }
+
+  while(stop == 0)
+  {
+    dbprint (printlevel-voice, "// We call radLoopR to find new prime ideals.");
+    primes = radicalSLIteration(I, rad);                         // A list of primes or intersections of primes, not included in P
+    dbprint (printlevel - voice, "// Output of Iteration Step:");
+    dbprint (printlevel - voice, primes);
+    if (size(primes) > 0)
+    {
+      dbprint (printlevel - voice, "// We intersect P with the ideal just obtained.");
+      for(k = 1; k <= size(primes); k++)
+      {
+        rad = intersect(rad, primes[k]);
+        if (il == 1)
+        {
+          if (attrib(primes[k], "isSB") != 1)
+          {
+            primes[k] = groebner(primes[k]);
+          }
+          if (iDim == dim(primes[k]))
+          {
+            equiRad = intersect(equiRad, primes[k]);
+          }
+        }
+      }
+    }
+    else
+    {
+      stop = 1;
+    }
+  }
+  if (il == 0)
+  {
+    return(rad);
+  }
+  else
+  {
+    return(equiRad);
+  }
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Based on radicalKL.
+// It contains all of old version of proc radicalKL except the recursion call.
+//
+// Output:
+// #1 -> output ideal, the part of the radical that has been computed
+// #2 -> complementary ideal, the part of the ideal I whose radical remains to be computed
+//       = (I, h) in KL algorithm
+//       This is not used in the new algorithm. It is part of KL algorithm
+// #3 -> done, 1: output = radical, there is no need to continue
+//                   0: radical = output \cap \sqrt{complementary ideal}
+//       This is not used in the new algorithm. It is part of KL algorithm
+
+static proc radicalReduction(ideal I, ideal ser, int allIndep, list #)
+{
+// allMaximal      1 -> Indicates that the reduction to the zerodim case
+//                    must be done for all indep set of the leading terms ideal
+//                 0 -> Otherwise
+// ideal ser       Only for radicalKL. (Same as in radicalKL)
+// list #          Only for radicalKL (If #[1] = 1,
+//                    only equiradical is required.
+//                    It is used to set the value of done.)
+  ASSUME(1, hasFieldCoefficient(basering) );
+  ASSUME(1, not isQuotientRing(basering) ) ;
+  ASSUME(1, hasGlobalOrdering(basering) ) ;
+
+  attrib(I, "isSB", 1);   // I needs to be a reduced standard basis
+  list indep, fett;
+  intvec @w, @hilb, op;
+  int @wr, @n, @m, lauf, di;
+  ideal fac, @h, collectrad, lsau;
+  poly @q;
+  string @va; def quotring;
+
+  def @P = basering;
+  int jdim = dim(I);               // Computes the dimension of I
+  int  homo = homog(I);            // Finds out if I is homogeneous
+  ideal rad = ideal(1);            // The unit ideal
+  ideal te = ser;
+  if(size(#) > 0)
+  {
+    @wr = #[1];
+  }
+  if(homo == 1)
+  {
+    for(@n = 1; @n <= nvars(basering); @n++)
+    {
+      @w[@n] = ord(var(@n));
+    }
+    @hilb = hilb(I, 1, @w);
+  }
+
+  // SL 2006.04.11 1 Debug messages
+  dbprint(printlevel-voice, "//Computes the radical of the ideal:", I);
+  // SL 2006.04.11 2 Debug messages
+
+  //---------------------------------------------------------------------------
+  //j is the ring
+  //---------------------------------------------------------------------------
+
+  if (jdim==-1)
+  {
+    return(ideal(1), ideal(1), 1);
+  }
+
+  //---------------------------------------------------------------------------
+  //the zero-dimensional case
+  //---------------------------------------------------------------------------
+
+  if (jdim==0)
+  {
+    return(zeroRad(I), ideal(1), 1);
+  }
+
+  //-------------------------------------------------------------------------
+  //search for a maximal independent set indep,i.e.
+  //look for subring such that the intersection with the ideal is zero
+  //j intersected with K[var(indep[3]+1),...,var(nvar)] is zero,
+  //indep[1] is the new varstring, indep[2] the string for the block-ordering
+  //-------------------------------------------------------------------------
+
+  // SL 2006-04-24 1   If allIndep = 0, then it only computes one maximal
+  //                     independent set.
+  //                     This looks better for the new algorithm but not for KL
+  //                     algorithm
+  list parameters = allIndep;
+  indep = newMaxIndependSetDp(I, parameters);
+  // SL 2006-04-24 2
+
+  for(@m = 1; @m <= size(indep); @m++)
+  {
+    if((indep[@m][1] == varstr(basering)) && (@m == 1))
+    //this is the good case, nothing to do, just to have the same notations
+    //change the ring
+    {
+      def gnir1=ring(ringlist(basering));
+      setring gnir1;
+      ideal @j = fetch(@P, I);
+      attrib(@j, "isSB", 1);
+    }
+    else
+    {
+      @va = string(maxideal(1));
+
+      execute("ring gnir1 = (" + charstr(basering) + "), (" + indep[@m][1] + "),("
+                              + indep[@m][2] + ");");
+      execute("map phi = @P," + @va + ";");
+      if(homo == 1)
+      {
+        ideal @j = std(phi(I), @hilb, @w);
+      }
+      else
+      {
+        ideal @j = groebner(phi(I));
+      }
+    }
+    if((deg(@j[1]) == 0) || (dim(@j) < jdim))
+    {
+      setring @P;
+      break;
+    }
+    for (lauf = 1; lauf <= size(@j); lauf++)
+    {
+      fett[lauf] = size(@j[lauf]);
+    }
+    //------------------------------------------------------------------------
+    // We have now the following situation:
+    // j intersected with K[var(nnp+1),..,var(nva)] is zero so we may pass
+    // to this quotientring, j is there still a standardbasis, the
+    // leading coefficients of the polynomials there (polynomials in
+    // K[var(nnp+1),..,var(nva)]) are collected in the list h,
+    // we need their LCM, gh, because of the following:
+    // let (j:gh^n)=(j:gh^infinity) then j*K(var(nnp+1),..,var(nva))[..rest..]
+    // intersected with K[var(1),...,var(nva)] is (j:gh^n)
+    // on the other hand j = ((j, gh^n) intersected with (j : gh^n))
+
+    //------------------------------------------------------------------------
+    // The arrangement for the quotientring K(var(nnp+1),..,var(nva))[..rest..]
+    // and the map phi:K[var(1),...,var(nva)] ----->
+    // K(var(nnpr+1),..,var(nva))[..the rest..]
+    //------------------------------------------------------------------------
+    quotring = prepareQuotientring(nvars(basering) - indep[@m][3],"dp");
+    //------------------------------------------------------------------------
+    // We pass to the quotientring   K(var(nnp+1),..,var(nva))[..the rest..]
+    //------------------------------------------------------------------------
+
+    setring quotring;
+
+    // @j considered in the quotientring
+    ideal @j = imap(gnir1, @j);
+
+    kill gnir1;
+
+    // j is a standardbasis in the quotientring but usually not minimal
+    // here it becomes minimal
+
+    @j = clearSB(@j, fett);
+
+    // We need later LCM(h[1],...) = gh for saturation
+    ideal @h;
+    if(deg(@j[1]) > 0)
+    {
+      for(@n = 1; @n <= size(@j); @n++)
+      {
+        @h[@n] = leadcoef(@j[@n]);
+      }
+      op = option(get);
+      option(redSB);
+      @j = std(@j);  //to obtain a reduced standardbasis
+      option(set, op);
+
+      // SL 1 Debug messages
+      dbprint(printlevel - voice, "zero_rad", basering, @j, dim(groebner(@j)));
+      ideal zero_rad = zeroRad(@j);
+      dbprint(printlevel - voice, "zero_rad passed");
+      // SL 2
+    }
+    else
+    {
+      ideal zero_rad = ideal(1);
+    }
+
+    // We need the intersection of the ideals in the list quprimary with the
+    // polynomialring, i.e. let q=(f1,...,fr) in the quotientring such an ideal
+    // but fi polynomials, then the intersection of q with the polynomialring
+    // is the saturation of the ideal generated by f1,...,fr with respect to
+    // h which is the lcm of the leading coefficients of the fi considered in
+    // the quotientring: this is coded in saturn
+
+    zero_rad = std(zero_rad);
+
+    ideal hpl;
+
+    for(@n = 1; @n <= size(zero_rad); @n++)
+    {
+      hpl = hpl, leadcoef(zero_rad[@n]);
+    }
+
+    //------------------------------------------------------------------------
+    // We leave  the quotientring   K(var(nnp+1),..,var(nva))[..the rest..]
+    // back to the polynomialring
+    //------------------------------------------------------------------------
+    setring @P;
+
+    collectrad = imap(quotring, zero_rad);
+    lsau = simplify(imap(quotring, hpl), 2);
+    @h = imap(quotring, @h);
+
+    kill quotring;
+
+    // Here the intersection with the polynomialring
+    // mentioned above is really computed
+
+    collectrad = sat2(collectrad, lsau)[1];
+    if(deg(@h[1])>=0)
+    {
+      fac = ideal(0);
+      for(lauf = 1; lauf <= ncols(@h); lauf++)
+      {
+        if(deg(@h[lauf]) > 0)
+        {
+          fac = fac + factorize(@h[lauf], 1);
+        }
+      }
+      fac = simplify(fac, 6);
+      @q = 1;
+      for(lauf = 1; lauf <= size(fac); lauf++)
+      {
+        @q = @q * fac[lauf];
+      }
+      op = option(get);
+      option(returnSB);
+      option(redSB);
+      I = quotient(I + ideal(@q), rad);
+      attrib(I, "isSB", 1);
+      option(set, op);
+    }
+    if((deg(rad[1]) > 0) && (deg(collectrad[1]) > 0))
+    {
+      rad = intersect(rad, collectrad);
+      te = intersect(te, collectrad);
+      te = simplify(reduce(te, I, 1), 2);
+    }
+    else
+    {
+      if(deg(collectrad[1]) > 0)
+      {
+        rad = collectrad;
+        te = intersect(te, collectrad);
+        te = simplify(reduce(te, I, 1), 2);
+      }
+    }
+
+    if((dim(I) < jdim)||(size(te) == 0))
+    {
+      break;
+    }
+    if(homo==1)
+    {
+      @hilb = hilb(I, 1, @w);
+    }
+  }
+
+  // SL 2006.04.11 1 Debug messages
+  dbprint (printlevel-voice, "// Part of the Radical already computed:", rad);
+  dbprint (printlevel-voice, "// Dimension:", dim(groebner(rad)));
+  // SL 2006.04.11 2 Debug messages
+
+  // SL 2006.04.21 1    New variable "done".
+  //                      It tells if the radical is already computed or
+  //                      if it still has to be computed the radical of the new ideal I
+  int done;
+  if(((@wr == 1) && (dim(I)<jdim)) || (deg(I[1])==0) || (size(te) == 0))
+  {
+    done = 1;
+  }
+  else
+  {
+    done = 0;
+  }
+  // SL 2006.04.21 2
+
+  // SL 2006.04.21 1     See details of the output at the beginning of this proc.
+  list result = rad, I, done;
+  return(result);
+  // SL 2006.04.21 2
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Given an ideal I and an ideal P (intersection of some minimal prime ideals
+// associated to I), it calculates the intersection of new minimal prime ideals
+// associated to I which where not used to calculate P.
+// This version uses ZD Radical in the zerodimensional case.
+static proc radicalSLIteration (ideal I, ideal P);
+// Input: I, ideal. The ideal from which new prime components will be obtained.
+//        P, ideal. Intersection of some prime ideals of I.
+// Output: ideal. Intersection of some primes of I different from the ones in P.
+{
+  ASSUME(1, hasFieldCoefficient(basering) );
+  ASSUME(1, not isQuotientRing(basering) ) ;
+  ASSUME(1, hasGlobalOrdering(basering) ) ;
+
+  int k = 1;                     // Counter
+  int good  = 0;                 // Checks if an element of P is in rad(I)
+
+  dbprint (printlevel-voice, "// We search for an element in P - sqrt(I).");
+  while ((k <= size(P)) and (good == 0))
+  {
+    dbprint (printlevel-voice, "// We try with:", P[k]);
+    good = 1 - rad_con(P[k], I);
+    k++;
+  }
+  k--;
+  if (good == 0)
+  {
+    dbprint (printlevel-voice, "// No element was found, P = sqrt(I).");
+    list emptyList = list();
+    return (emptyList);
+  }
+  dbprint(printlevel - voice, "// That one was good!");
+  dbprint(printlevel - voice, "// We saturate I with respect to this element.");
+  if (P[k] != 1)
+  {
+    intvec oo=option(get);
+    option(redSB);
+    ideal J = sat(I, P[k])[1];
+    option(set,oo);
+
+  }
+  else
+  {
+    dbprint(printlevel - voice, "// The polynomial is 1, the saturation in not actually computed.");
+    ideal J = I;
+  }
+
+  // We now call proc radicalNew;
+  dbprint(printlevel - voice, "// We do the reduction to the zerodimensional case, via radical.");
+  dbprint(printlevel - voice, "// The ideal is ", J);
+  dbprint(printlevel - voice, "// The dimension is ", dim(groebner(J)));
+
+  int allMaximal = 0;   // Compute the zerodim reduction for only one indep set.
+  ideal re = 1;         // No reduction is need,
+                        //    there are not redundant components.
+  list emptyList = list();   // Look for primes of any dimension,
+                             //   not only of max dimension.
+  list result = radicalReduction(J, re, allMaximal, emptyList);
+
+  return(result[1]);
+}
+
+///////////////////////////////////////////////////////////////////////////////////
+// Based on maxIndependSet
+// Added list # as parameter
+// If the first element of # is 0, the output is only 1 max indep set.
+// If no list is specified or #[1] = 1, the output is all the max indep set of the
+// leading terms ideal. This is the original output of maxIndependSet
+
+// The ordering given in the output has been changed to block dp instead of lp.
+
+proc newMaxIndependSetDp(ideal j, list #)
+"USAGE:   newMaxIndependentSetDp(I); I ideal (returns all maximal independent sets of the corresponding leading terms ideal)
+          newMaxIndependentSetDp(I, 0); I ideal (returns only one maximal independent set)
+RETURN:  list = #1. new varstring with the maximal independent set at the end,
+                #2. ordstring with the corresponding dp block ordering,
+                #3. the number of independent variables
+NOTE:
+EXAMPLE: example newMaxIndependentSetDp; shows an example
+"
+{
+  ASSUME(0, hasFieldCoefficient(basering) );
+  ASSUME(0, not isQuotientRing(basering) ) ;
+  ASSUME(0, hasGlobalOrdering(basering) ) ;
+
+  int n, k, di;
+  list resu, hilf;
+  string var1, var2;
+  list v = indepSet(j, 0);
+
+  // SL 2006.04.21 1 Lines modified to use only one independent Set
+  int allMaximal;
+  if (size(#) > 0)
+  {
+    allMaximal = #[1];
+  }
+  else
+  {
+    allMaximal = 1;
+  }
+
+  int nMax;
+  if (allMaximal == 1)
+  {
+    nMax = size(v);
+  }
+  else
+  {
+    nMax = 1;
+  }
+
+  for(n = 1; n <= nMax; n++)
+  // SL 2006.04.21 2
+  {
+    di = 0;
+    var1 = "";
+    var2 = "";
+    for(k = 1; k <= size(v[n]); k++)
+    {
+     if(v[n][k] != 0)
+      {
+        di++;
+        var2 = var2 + "var(" + string(k) + "), ";
+      }
+      else
+      {
+        var1 = var1 + "var(" + string(k) + "), ";
+      }
+    }
+    if(di > 0)
+    {
+      var1 = var1 + var2;
+      var1 = var1[1..size(var1) - 2];                         // The "- 2" removes the trailer comma
+      hilf[1] = var1;
+      // SL 2006.21.04 1 The order is now block dp instead of lp
+      hilf[2] = "dp(" + string(nvars(basering) - di) + "), dp(" + string(di) + ")";
+      // SL 2006.21.04 2
+      hilf[3] = di;
+      resu[n] = hilf;
+    }
+    else
+    {
+      resu[n] = varstr(basering), ordstr(basering), 0;
+    }
+  }
+  return(resu);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring s1 = (0, x, y), (a, b, c, d, e, f, g), lp;
+   ideal i = ea - fbg, fa + be, ec - fdg, fc + de;
+   i = std(i);
+   list l = newMaxIndependSetDp(i);
+   l;
+   i = i, g;
+   l = newMaxIndependSetDp(i);
+   l;
+
+   ring s = 0, (x, y, z), lp;
+   ideal i = z, yx;
+   list l = newMaxIndependSetDp(i);
+   l;
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+proc prepareAss(ideal i)
+"USAGE:   prepareAss(I); I ideal
+RETURN:  list, the radicals of the maximal dimensional components of I.
+NOTE:    Uses algorithm of Eisenbud/Huneke/Vasconcelos.
+EXAMPLE: example prepareAss; shows an example
+"
+{
+  ASSUME(0, hasFieldCoefficient(basering) );
+  ASSUME(0, not isQuotientRing(basering) ) ;
+  if(attrib(basering,"global")!=1)
+  {
+      ERROR(
+      "// Not implemented for this ordering, please change to global ordering."
+      );
+  }
+
+  ideal j=std(i);
+  int cod=nvars(basering)-dim(j);
+  int e;
+  list er;
+  ideal ann;
+  if(homog(i)==1)
+  {
+     resolution re=sres(j,0);                   //the resolution
+     re=minres(re);                       //minimized resolution
+  }
+  else
+  {
+    list re=mres(i,0);
+  }
+  for(e=cod;e<=nvars(basering);e++)
+  {
+     ann=AnnExt_R(e,re);
+
+     if(nvars(basering)-dim(std(ann))==e)
+     {
+        er[size(er)+1]=equiRadical(ann);
+     }
+  }
+  return(er);
+}
+example
+{ "EXAMPLE:";  echo = 2;
+   ring  r = 0,(x,y,z),dp;
+   poly  p = z2+1;
+   poly  q = z3+2;
+   ideal i = p*q^2,y-z2;
+   list pr = prepareAss(i);
+   pr;
+}
+///////////////////////////////////////////////////////////////////////////////
+proc equidimMaxEHV(ideal i)
+"USAGE:  equidimMaxEHV(I); I ideal
+RETURN:  ideal, the equidimensional component (of maximal dimension) of I.
+NOTE:    Uses algorithm of Eisenbud, Huneke and Vasconcelos.
+EXAMPLE: example equidimMaxEHV; shows an example
+"
+{
+  ASSUME(0, hasFieldCoefficient(basering) );
+  ASSUME(0, not isQuotientRing(basering) ) ;
+  if(attrib(basering,"global")!=1)
+  {
+      ERROR(
+      "// Not implemented for this ordering, please change to global ordering."
+      );
+  }
+
+  ideal j=groebner(i);
+  int cod=nvars(basering)-dim(j);
+
+
+  if(cod > nvars(basering))
+    {
+      dbprint(printlevel,"//If I is the entire ring...");
+      dbprint(printlevel,"//...then return the ideal generated by 1.");
+      return(ideal(1));
+    }
+
+  int e;
+  ideal ann;
+  if(homog(i)==1)
+  {
+     resolution re=sres(j,0);                   //the resolution
+     re=minres(re);                       //minimized resolution
+  }
+  else
+  {
+    resolution re=mres(j,0);
+  }
+  ann = AnnExt_R(cod,re);
+  if( nvars(basering)-dim(std(ann) ) != cod)
+  {
+     return( ideal(1) );
+  }
+
+  return(ann);
+}
+example
+{ "EXAMPLE:";  echo = 2;
+   ring  r = 0,(x,y,z),dp;
+   ideal i=intersect(ideal(z),ideal(x,y),ideal(x2,z2),ideal(x5,y5,z5));
+   equidimMaxEHV(i);
+}
+
+proc testPrimary(list pr, ideal k)
+"USAGE:   testPrimary(pr,k); pr a list, k an ideal.
+ASSUME:  pr is the result of primdecGTZ(k) or primdecSY(k).
+RETURN:  int, 1 if the intersection of the ideals in pr is k, 0 if not
+EXAMPLE: example testPrimary; shows an example
+"
+{
+   ASSUME(0, hasFieldCoefficient(basering) );
+   ASSUME(0, not isQuotientRing(basering) ) ;
+
+   int i;
+   pr=reconvList(pr);
+   ideal j=pr[1];
+   for (i=2;i<=size(pr) div 2;i++)
+   {
+       j=intersect(j,pr[2*i-1]);
+   }
+   return(idealsEqual(j,k));
+}
+example
+{ "EXAMPLE:";  echo = 2;
+   ring  r = 32003,(x,y,z),dp;
+   poly  p = z2+1;
+   poly  q = z4+2;
+   ideal i = p^2*q^3,(y-z3)^3,(x-yz+z4)^4;
+   list pr = primdecGTZ(i);
+   testPrimary(pr,i);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+proc zerodec(ideal I)
+"USAGE:   zerodec(I); I ideal
+ASSUME:  I is zero-dimensional, the characteristic of the ground field is 0
+RETURN:  list of primary ideals, the zero-dimensional decomposition of I
+NOTE:    The algorithm (of Monico), works well only for a small total number
+         of solutions (@code{vdim(std(I))} should be < 100) and without
+         parameters. In practice, it works also in large characteristic p>0
+         but may fail for small p.
+@*       If printlevel > 0 (default = 0) additional information is displayed.
+EXAMPLE: example zerodec; shows an example
+"
+{
+  ASSUME(0, hasFieldCoefficient(basering) );
+  ASSUME(0, not isQuotientRing(basering) ) ;
+  if(attrib(basering,"global")!=1)
+  {
+    ERROR(
+    "// Not implemented for this ordering, please change to global ordering."
+    );
+  }
+
+  def R=basering;
+  poly q;
+  int j,time;
+  matrix m;
+  list re;
+  poly va=var(1);
+  ideal J=groebner(I);
+  ideal ba=kbase(J);
+  int d=vdim(J);
+  dbprint(printlevel-voice+2,"// multiplicity of ideal : "+ string(d));
+//------ compute matrix of multiplication on R/I with generic element p -----
+  int e=nvars(basering);
+  poly p=randomLast(100)[e]+random(-50,50);     //the generic element
+  matrix n[d][d];
+  time = timer;
+  for(j=2;j<=e;j++)
+  {
+    va=va*var(j);
+  }
+  for(j=1;j<=d;j++)
+  {
+    q=reduce(p*ba[j],J);
+    m=coeffs(q,ba,va);
+    n[j,1..d]=m[1..d,1];
+  }
+  dbprint(printlevel-voice+2,
+    "// time for computing multiplication matrix (with generic element) : "+
+    string(timer-time));
+//---------------- compute characteristic polynomial of matrix --------------
+  execute("ring P1=("+charstr(R)+"),T,dp;");
+  matrix n=imap(R,n);
+  time = timer;
+  poly charpol=det(n-var(1)*freemodule(d));
+  dbprint(printlevel-voice+2,"// time for computing char poly: "+
+         string(timer-time));
+//------------------- factorize characteristic polynomial -------------------
+//check first if constant term of charpoly is != 0 (which is true for
+//sufficiently generic element)
+  if(charpol[size(charpol)]!=0)
+  {
+    time = timer;
+    list fac=factor(charpol);
+    testFactor(fac,charpol);
+    dbprint(printlevel-voice+2,"// time for factorizing char poly: "+
+            string(timer-time));
+    int f=size(fac[1]);
+//--------------------------- the irreducible case --------------------------
+    if(f==1)
+    {
+      setring R;
+      re=I;
+      return(re);
+    }
+//---------------------------- the reducible case ---------------------------
+//if f_i are the irreducible factors of charpoly, mult=ri, then <I,g_i^ri>
+//are the primary components where g_i = f_i(p). However, substituting p in
+//f_i may result in a huge object although the final result may be small.
+//Hence it is better to simultaneously reduce with I. For this we need a new
+//ring.
+    execute("ring P=("+charstr(R)+"),(T,"+varstr(R)+"),(dp(1),dp);");
+    list rfac=imap(P1,fac);
+    intvec ov=option(get);;
+    option(redSB);
+    list re1;
+    ideal new = var(1)-imap(R,p),imap(R,J);
+    attrib(new, "isSB",1);    //we know that new is a standard basis
+    for(j=1;j<=f;j++)
+    {
+      re1[j]=reduce(rfac[1][j]^rfac[2][j],new);
+    }
+    setring R;
+    re = imap(P,re1);
+    for(j=1;j<=f;j++)
+    {
+      J=I,re[j];
+      re[j]=interred(J);
+    }
+    option(set,ov);
+    return(re);
+  }
+  else
+//------------------- choice of generic element failed -------------------
+  {
+    dbprint(printlevel-voice+2,"// try new generic element!");
+    setring R;
+    return(zerodec(I));
+  }
+}
+example
+{ "EXAMPLE:";  echo = 2;
+   ring r  = 0,(x,y),dp;
+   ideal i = x2-2,y2-2;
+   list pr = zerodec(i);
+   pr;
+}
+///////////////////////////////////////////////////////////////////////////////
+static proc newDecompStep(ideal i, list #)
+"USAGE:  newDecompStep(i); i ideal  (for primary decomposition)
+         newDecompStep(i,1);        (for the associated primes of dimension of i)
+         newDecompStep(i,2);        (for the minimal associated primes)
+         newDecompStep(i,3);        (for the absolute primary decomposition (not tested!))
+         "oneIndep";        (for using only one max indep set)
+         "intersect";        (returns alse the intersection of the components founded)
+
+RETURN:  list = list of primary ideals and their associated primes
+         (at even positions in the list)
+         (resp. a list of the minimal associated primes)
+NOTE:    Algorithm of Gianni/Trager/Zacharias
+EXAMPLE: example newDecompStep; shows an example
+"
+{
+  ASSUME(1, hasFieldCoefficient(basering) );
+  ASSUME(1, not isQuotientRing(basering) ) ;
+  ASSUME(1, hasGlobalOrdering(basering) ) ;
+
+  intvec op at P, op, at vv;
+  def  @P = basering;
+  list primary,indep,ltras;
+  intvec @vh,isat, at w;
+  int @wr, at k, at n, at m, at n1, at n2, at n3,homo,seri,keepdi,abspri,ab,nn;
+  ideal peek=i;
+  ideal ser,tras;
+  list data;
+  list result;
+  intvec @hilb;
+  int isS=(attrib(i,"isSB")==1);
+
+  // Debug
+  dbprint(printlevel - voice, "newDecompStep, v2.0");
+
+  string indepOption = "allIndep";
+  string intersectOption = "noIntersect";
+
+  if(size(#)>0)
+  {
+    int count = 1;
+    if(typeof(#[count]) == "string")
+    {
+      if ((#[count] == "oneIndep") or (#[count] == "allIndep"))
+      {
+        indepOption = #[count];
+        count++;
+      }
+    }
+    if(typeof(#[count]) == "string")
+    {
+      if ((#[count] == "intersect") or (#[count] == "noIntersect"))
+      {
+        intersectOption = #[count];
+        count++;
+      }
+    }
+    if((typeof(#[count]) == "int") or (typeof(#[count]) == "number"))
+    {
+      if ((#[count]==1)||(#[count]==2)||(#[count]==3))
+      {
+        @wr=#[count];
+        if(@wr==3){abspri = 1; @wr = 0;}
+        count++;
+      }
+    }
+    if(size(#)>count)
+    {
+      seri=1;
+      peek=#[count + 1];
+      ser=#[count + 2];
+    }
+  }
+  if(abspri)
+  {
+    list absprimary,abskeep,absprimarytmp,abskeeptmp;
+  }
+  homo=homog(i);
+  if(homo==1)
+  {
+    if(attrib(i,"isSB")!=1)
+    {
+      //ltras=mstd(i);
+      tras=groebner(i);
+      ltras=tras,tras;
+      attrib(ltras[1],"isSB",1);
+    }
+    else
+    {
+      ltras=i,i;
+      attrib(ltras[1],"isSB",1);
+    }
+    tras = ltras[1];
+    attrib(tras,"isSB",1);
+    if(dim(tras)==0)
+    {
+      primary[1]=ltras[2];
+      primary[2]=maxideal(1);
+      if(@wr>0)
+      {
+        list l;
+        l[2]=maxideal(1);
+        l[1]=maxideal(1);
+        if (intersectOption == "intersect")
+        {
+          return(list(l, maxideal(1)));
+        }
+        else
+        {
+          return(l);
+        }
+      }
+      if (intersectOption == "intersect")
+      {
+        return(list(primary, primary[1]));
+      }
+      else
+      {
+        return(primary);
+      }
+    }
+    for(@n=1;@n<=nvars(basering);@n++)
+    {
+      @w[@n]=ord(var(@n));
+    }
+    @hilb=hilb(tras,1, at w);
+    intvec keephilb=@hilb;
+  }
+
+  //----------------------------------------------------------------
+  //i is the zero-ideal
+  //----------------------------------------------------------------
+
+  if(size(i)==0)
+  {
+    primary=i,i;
+    if (intersectOption == "intersect")
+    {
+      return(list(primary, i));
+    }
+    else
+    {
+      return(primary);
+    }
+  }
+
+  //----------------------------------------------------------------
+  //pass to the lexicographical ordering and compute a standardbasis
+  //----------------------------------------------------------------
+
+  int lp=islp();
+
+  op at P = option(get);
+  def gnir=changeordTo(basering,"lp");
+  setring gnir;
+
+  op=option(get);
+  option(redSB);
+
+  ideal ser=fetch(@P,ser);
+  if(homo==1)
+  {
+    if(!lp)
+    {
+      ideal @j=std(fetch(@P,i), at hilb, at w);
+    }
+    else
+    {
+      ideal @j=fetch(@P,tras);
+      attrib(@j,"isSB",1);
+    }
+  }
+  else
+  {
+    if(lp&&isS)
+    {
+      ideal @j=fetch(@P,i);
+      attrib(@j,"isSB",1);
+    }
+    else
+    {
+      ideal @j=groebner(fetch(@P,i));
+    }
+  }
+  option(set,op);
+  if(seri==1)
+  {
+    ideal peek=fetch(@P,peek);
+    attrib(peek,"isSB",1);
+  }
+  else
+  {
+    ideal peek=@j;
+  }
+  if((size(ser)==0)&&(!abspri))
+  {
+    ideal fried;
+    @n=size(@j);
+    for(@k=1;@k<=@n;@k++)
+    {
+      if(deg(lead(@j[@k]))==1)
+      {
+        fried[size(fried)+1]=@j[@k];
+        @j[@k]=0;
+      }
+    }
+    if(size(fried)==nvars(basering))
+    {
+      setring @P;
+      option(set,op at P);
+      primary[1]=i;
+      primary[2]=i;
+      if (intersectOption == "intersect")
+      {
+        return(list(primary, i));
+      }
+      else
+      {
+        return(primary);
+      }
+    }
+    if(size(fried)>0)
+    {
+      string newva;
+      string newma;
+      for(@k=1;@k<=nvars(basering);@k++)
+      {
+        @n1=0;
+        for(@n=1;@n<=size(fried);@n++)
+        {
+          if(leadmonom(fried[@n])==var(@k))
+          {
+            @n1=1;
+            break;
+          }
+        }
+        if(@n1==0)
+        {
+          newva=newva+string(var(@k))+",";
+          newma=newma+string(var(@k))+",";
+        }
+        else
+        {
+          newma=newma+string(0)+",";
+        }
+      }
+      newva[size(newva)]=")";
+      newma[size(newma)]=";";
+      execute("ring @deirf=("+charstr(gnir)+"),("+newva+",lp;");
+      execute("map @kappa=gnir,"+newma);
+      ideal @j= @kappa(@j);
+      @j=simplify(@j, 2);
+      attrib(@j,"isSB",1);
+      result = newDecompStep(@j, indepOption, intersectOption, @wr);
+      if (intersectOption == "intersect")
+      {
+        list pr = result[1];
+        ideal intersection = result[2];
+      }
+      else
+      {
+        list pr = result;
+      }
+
+      setring gnir;
+      list pr=imap(@deirf,pr);
+      for(@k=1;@k<=size(pr);@k++)
+      {
+        @j=pr[@k]+fried;
+        pr[@k]=@j;
+      }
+      if (intersectOption == "intersect")
+      {
+        ideal intersection = imap(@deirf, intersection);
+        @j = intersection + fried;
+        intersection = @j;
+      }
+      setring @P;
+      option(set,op at P);
+      if (intersectOption == "intersect")
+      {
+        return(list(imap(gnir,pr), imap(gnir,intersection)));
+      }
+      else
+      {
+        return(imap(gnir,pr));
+      }
+    }
+  }
+  //----------------------------------------------------------------
+  //j is the ring
+  //----------------------------------------------------------------
+
+  if (dim(@j)==-1)
+  {
+    setring @P;
+    option(set,op at P);
+    primary=ideal(1),ideal(1);
+    if (intersectOption == "intersect")
+    {
+      return(list(primary, ideal(1)));
+    }
+    else
+    {
+      return(primary);
+    }
+  }
+
+  //----------------------------------------------------------------
+  //  the case of one variable
+  //----------------------------------------------------------------
+
+  if(nvars(basering)==1)
+  {
+    list fac=factor(@j[1]);
+    list gprimary;
+    poly generator;
+    ideal gIntersection;
+    for(@k=1;@k<=size(fac[1]);@k++)
+    {
+      if(@wr==0)
+      {
+        gprimary[2*@k-1]=ideal(fac[1][@k]^fac[2][@k]);
+        gprimary[2*@k]=ideal(fac[1][@k]);
+      }
+      else
+      {
+        gprimary[2*@k-1]=ideal(fac[1][@k]);
+        gprimary[2*@k]=ideal(fac[1][@k]);
+      }
+      if (intersectOption == "intersect")
+      {
+        generator = generator * fac[1][@k];
+      }
+    }
+    if (intersectOption == "intersect")
+    {
+      gIntersection = generator;
+    }
+    setring @P;
+    primary=fetch(gnir,gprimary);
+    if (intersectOption == "intersect")
+    {
+      ideal intersection = fetch(gnir,gIntersection);
+    }
+
+//HIER
+    if(abspri)
+    {
+      list resu,tempo;
+      string absotto;
+      for(ab=1;ab<=size(primary) div 2;ab++)
+      {
+        absotto= absFactorize(primary[2*ab][1],77);
+        tempo=primary[2*ab-1],primary[2*ab],absotto,string(var(nvars(basering)));
+        resu[ab]=tempo;
+      }
+      primary=resu;
+      intersection = 1;
+      for(ab=1;ab<=size(primary);ab++)
+      {
+        intersection = intersect(intersection, primary[ab][2]);
+      }
+    }
+    if (intersectOption == "intersect")
+    {
+      return(list(primary, intersection));
+    }
+    else
+    {
+      return(primary);
+    }
+  }
+
+ //------------------------------------------------------------------
+ //the zero-dimensional case
+ //------------------------------------------------------------------
+  if (dim(@j)==0)
+  {
+    op=option(get);
+    option(redSB);
+    list gprimary= newZero_decomp(@j,ser, at wr);
+
+    setring @P;
+    primary=fetch(gnir,gprimary);
+
+    if(size(ser)>0)
+    {
+      primary=cleanPrimary(primary);
+    }
+//HIER
+    if(abspri)
+    {
+      list resu,tempo;
+      string absotto;
+      for(ab=1;ab<=size(primary) div 2;ab++)
+      {
+        absotto= absFactorize(primary[2*ab][1],77);
+        tempo=primary[2*ab-1],primary[2*ab],absotto,string(var(nvars(basering)));
+        resu[ab]=tempo;
+      }
+      primary=resu;
+    }
+    option(set,op at P);
+    if (intersectOption == "intersect")
+    {
+      return(list(primary, fetch(gnir, at j)));
+    }
+    else
+    {
+      return(primary);
+    }
+  }
+
+  poly @gs, at gh, at p;
+  string @va;
+  list quprimary,htprimary,collectprimary,lsau,lnew,allindep,restindep;
+  ideal @h;
+  int jdim=dim(@j);
+  list fett;
+  int lauf,di,newtest;
+  //------------------------------------------------------------------
+  //search for a maximal independent set indep,i.e.
+  //look for subring such that the intersection with the ideal is zero
+  //j intersected with K[var(indep[3]+1),...,var(nvar] is zero,
+  //indep[1] is the new varstring and indep[2] the string for block-ordering
+  //------------------------------------------------------------------
+  if(@wr!=1)
+  {
+    allindep = newMaxIndependSetLp(@j, indepOption);
+    for(@m=1;@m<=size(allindep);@m++)
+    {
+      if(allindep[@m][3]==jdim)
+      {
+        di++;
+        indep[di]=allindep[@m];
+      }
+      else
+      {
+        lauf++;
+        restindep[lauf]=allindep[@m];
+      }
+    }
+  }
+  else
+  {
+    indep = newMaxIndependSetLp(@j, indepOption);
+  }
+
+  ideal jkeep=@j;
+  if(ordstr(@P)[1]=="w")
+  {
+    def @Phelp=ring(ringlist(gnir));
+    setring @Phelp;
+  }
+  else
+  {
+    def @Phelp=changeordTo(gnir,"dp");
+    setring @Phelp;
+  }
+
+  if(homo==1)
+  {
+    if((ordstr(@P)[3]=="d")||(ordstr(@P)[1]=="d")||(ordstr(@P)[1]=="w")
+       ||(ordstr(@P)[3]=="w"))
+    {
+      ideal jwork=imap(@P,tras);
+      attrib(jwork,"isSB",1);
+    }
+    else
+    {
+      ideal jwork=std(imap(gnir, at j), at hilb, at w);
+    }
+  }
+  else
+  {
+    ideal jwork=groebner(imap(gnir, at j));
+  }
+  list hquprimary;
+  poly @p, at q;
+  ideal @h,fac,ser;
+//Aenderung================
+  ideal @Ptest=1;
+//=========================
+  di=dim(jwork);
+  keepdi=di;
+
+  ser = 1;
+
+  setring gnir;
+  for(@m=1; @m<=size(indep); @m++)
+  {
+    data[1] = indep[@m];
+    result = newReduction(@j, ser, @hilb, @w, jdim, abspri, @wr, data);
+    quprimary = quprimary + result[1];
+    if(abspri)
+    {
+      absprimary = absprimary + result[2];
+      abskeep = abskeep + result[3];
+    }
+    @h = result[5];
+    ser = result[4];
+    if(size(@h)>0)
+    {
+      //---------------------------------------------------------------
+      //we change to @Phelp to have the ordering dp for saturation
+      //---------------------------------------------------------------
+
+      setring @Phelp;
+      @h=imap(gnir, at h);
+//Aenderung==================================
+      if(defined(@LL)){kill @LL;}
+      list @LL=minSat(jwork, at h);
+      @Ptest=intersect(@Ptest, at LL[1]);
+      ser = intersect(ser, @LL[1]);
+//===========================================
+
+      if(@wr!=1)
+      {
+//Aenderung==================================
+        @q=@LL[2];
+//===========================================
+        //@q=minSat(jwork, at h)[2];
+      }
+      else
+      {
+        fac=ideal(0);
+        for(lauf=1;lauf<=ncols(@h);lauf++)
+        {
+          if(deg(@h[lauf])>0)
+          {
+            fac=fac+factorize(@h[lauf],1);
+          }
+        }
+        fac=simplify(fac,6);
+        @q=1;
+        for(lauf=1;lauf<=size(fac);lauf++)
+        {
+          @q=@q*fac[lauf];
+        }
+      }
+      jwork = std(jwork, at q);
+      keepdi = dim(jwork);
+      if(keepdi < di)
+      {
+        setring gnir;
+        @j = imap(@Phelp, jwork);
+        ser = imap(@Phelp, ser);
+        break;
+      }
+      if(homo == 1)
+      {
+        @hilb = hilb(jwork, 1, @w);
+      }
+
+      setring gnir;
+      ser = imap(@Phelp, ser);
+      @j = imap(@Phelp, jwork);
+    }
+  }
+
+  if((size(quprimary)==0)&&(@wr==1))
+  {
+     @j=ideal(1);
+     quprimary[1]=ideal(1);
+     quprimary[2]=ideal(1);
+  }
+  if((size(quprimary)==0))
+  {
+    keepdi = di - 1;
+    quprimary[1]=ideal(1);
+    quprimary[2]=ideal(1);
+  }
+  //---------------------------------------------------------------
+  //notice that j=sat(j,gh) intersected with (j,gh^n)
+  //we finished with sat(j,gh) and have to start with (j,gh^n)
+  //---------------------------------------------------------------
+  if((deg(@j[1])!=0)&&(@wr!=1))
+  {
+     if(size(quprimary)>0)
+     {
+        setring @Phelp;
+        ser=imap(gnir,ser);
+
+        hquprimary=imap(gnir,quprimary);
+        if(@wr==0)
+        {
+//Aenderung====================================================
+//HIER STATT DURCHSCHNITT SATURIEREN!
+           ideal htest=@Ptest;
+/*
+           ideal htest=hquprimary[1];
+           for (@n1=2;@n1<=size(hquprimary) div 2;@n1++)
+           {
+              htest=intersect(htest,hquprimary[2*@n1-1]);
+           }
+*/
+//=============================================================
+        }
+        else
+        {
+           ideal htest=hquprimary[2];
+
+           for (@n1=2;@n1<=size(hquprimary) div 2;@n1++)
+           {
+              htest=intersect(htest,hquprimary[2*@n1]);
+           }
+        }
+
+        if(size(ser)>0)
+        {
+           ser=intersect(htest,ser);
+        }
+        else
+        {
+          ser=htest;
+        }
+        setring gnir;
+        ser=imap(@Phelp,ser);
+     }
+     if(size(reduce(ser,peek,1))!=0)
+     {
+        for(@m=1;@m<=size(restindep);@m++)
+        {
+         // if(restindep[@m][3]>=keepdi)
+         // {
+           isat=0;
+           @n2=0;
+
+           if(restindep[@m][1]==varstr(basering))
+           //the good case, nothing to do, just to have the same notations
+           //change the ring
+           {
+              def gnir1=ring(ringlist(basering));
+              setring gnir1;
+              ideal @j=fetch(gnir,jkeep);
+              attrib(@j,"isSB",1);
+           }
+           else
+           {
+              @va=string(maxideal(1));
+              execute("ring gnir1 = ("+charstr(basering)+"),("+
+                      restindep[@m][1]+"),(" +restindep[@m][2]+");");
+              execute("map phi=gnir,"+ at va+";");
+              op=option(get);
+              option(redSB);
+              if(homo==1)
+              {
+                 ideal @j=std(phi(jkeep),keephilb, at w);
+              }
+              else
+              {
+                ideal @j=groebner(phi(jkeep));
+              }
+              ideal ser=phi(ser);
+              option(set,op);
+           }
+
+           for (lauf=1;lauf<=size(@j);lauf++)
+           {
+              fett[lauf]=size(@j[lauf]);
+           }
+           //------------------------------------------------------------------
+           //we have now the following situation:
+           //j intersected with K[var(nnp+1),..,var(nva)] is zero so we may
+           //pass to this quotientring, j is their still a standardbasis, the
+           //leading coefficients of the polynomials  there (polynomials in
+           //K[var(nnp+1),..,var(nva)]) are collected in the list h,
+           //we need their ggt, gh, because of the following:
+           //let (j:gh^n)=(j:gh^infinity) then
+           //j*K(var(nnp+1),..,var(nva))[..the rest..]
+           //intersected with K[var(1),...,var(nva)] is (j:gh^n)
+           //on the other hand j=(j,gh^n) intersected with (j:gh^n)
+
+           //------------------------------------------------------------------
+
+           //the arrangement for the quotientring
+           // K(var(nnp+1),..,var(nva))[..the rest..]
+           //and the map phi:K[var(1),...,var(nva)] ---->
+           //--->K(var(nnpr+1),..,var(nva))[..the rest..]
+           //------------------------------------------------------------------
+
+           quotring=prepareQuotientring(nvars(basering)-restindep[@m][3],"lp");
+
+           //------------------------------------------------------------------
+           //we pass to the quotientring  K(var(nnp+1),..,var(nva))[..rest..]
+           //------------------------------------------------------------------
+
+           setring quotring;
+
+           // @j considered in the quotientring
+           ideal @j=imap(gnir1, at j);
+           ideal ser=imap(gnir1,ser);
+
+           kill gnir1;
+
+           //j is a standardbasis in the quotientring but usually not minimal
+           //here it becomes minimal
+           @j=clearSB(@j,fett);
+           attrib(@j,"isSB",1);
+
+           //we need later ggt(h[1],...)=gh for saturation
+           ideal @h;
+
+           for(@n=1;@n<=size(@j);@n++)
+           {
+              @h[@n]=leadcoef(@j[@n]);
+           }
+           //the primary decomposition of j*K(var(nnp+1),..,var(nva))[..rest..]
+
+           op=option(get);
+           option(redSB);
+           list uprimary= newZero_decomp(@j,ser, at wr);
+//HIER
+           if(abspri)
+           {
+              ideal II;
+              ideal jmap;
+              map sigma;
+              nn=nvars(basering);
+              map invsigma=basering,maxideal(1);
+              for(ab=1;ab<=size(uprimary) div 2;ab++)
+              {
+                 II=uprimary[2*ab];
+                 attrib(II,"isSB",1);
+                 if(deg(II[1])!=vdim(II))
+                 {
+                    jmap=randomLast(50);
+                    sigma=basering,jmap;
+                    jmap[nn]=2*var(nn)-jmap[nn];
+                    invsigma=basering,jmap;
+                    II=groebner(sigma(II));
+                  }
+                  absprimarytmp[ab]= absFactorize(II[1],77);
+                  II=var(nn);
+                  abskeeptmp[ab]=string(invsigma(II));
+                  invsigma=basering,maxideal(1);
+              }
+           }
+           option(set,op);
+
+           //we need the intersection of the ideals in the list quprimary with
+           //the polynomialring, i.e. let q=(f1,...,fr) in the quotientring
+           //such an ideal but fi polynomials, then the intersection of q with
+           //the polynomialring is the saturation of the ideal generated by
+           //f1,...,fr with respect toh which is the lcm of the leading
+           //coefficients of the fi considered in the quotientring:
+           //this is coded in saturn
+
+           list saturn;
+           ideal hpl;
+
+           for(@n=1;@n<=size(uprimary);@n++)
+           {
+              hpl=0;
+              for(@n1=1;@n1<=size(uprimary[@n]);@n1++)
+              {
+                 hpl=hpl,leadcoef(uprimary[@n][@n1]);
+              }
+              saturn[@n]=hpl;
+           }
+           //------------------------------------------------------------------
+           //we leave  the quotientring   K(var(nnp+1),..,var(nva))[..rest..]
+           //back to the polynomialring
+           //------------------------------------------------------------------
+           setring gnir;
+           collectprimary=imap(quotring,uprimary);
+           lsau=imap(quotring,saturn);
+           @h=imap(quotring, at h);
+
+           kill quotring;
+
+
+           @n2=size(quprimary);
+//================NEU=========================================
+           if(deg(quprimary[1][1])<=0){ @n2=0; }
+//============================================================
+
+           @n3=@n2;
+
+           for(@n1=1;@n1<=size(collectprimary) div 2;@n1++)
+           {
+              if(deg(collectprimary[2*@n1][1])>0)
+              {
+                 @n2++;
+                 quprimary[@n2]=collectprimary[2*@n1-1];
+                 lnew[@n2]=lsau[2*@n1-1];
+                 @n2++;
+                 lnew[@n2]=lsau[2*@n1];
+                 quprimary[@n2]=collectprimary[2*@n1];
+                 if(abspri)
+                 {
+                   absprimary[@n2 div 2]=absprimarytmp[@n1];
+                   abskeep[@n2 div 2]=abskeeptmp[@n1];
+                 }
+              }
+           }
+
+
+           //here the intersection with the polynomialring
+           //mentioned above is really computed
+
+           for(@n=@n3 div 2+1;@n<=@n2 div 2;@n++)
+           {
+              if(specialIdealsEqual(quprimary[2*@n-1],quprimary[2*@n]))
+              {
+                 quprimary[2*@n-1]=sat2(quprimary[2*@n-1],lnew[2*@n-1])[1];
+                 quprimary[2*@n]=quprimary[2*@n-1];
+              }
+              else
+              {
+                 if(@wr==0)
+                 {
+                    quprimary[2*@n-1]=sat2(quprimary[2*@n-1],lnew[2*@n-1])[1];
+                 }
+                 quprimary[2*@n]=sat2(quprimary[2*@n],lnew[2*@n])[1];
+              }
+           }
+           if(@n2>=@n3+2)
+           {
+              setring @Phelp;
+              ser=imap(gnir,ser);
+              hquprimary=imap(gnir,quprimary);
+              for(@n=@n3 div 2+1;@n<=@n2 div 2;@n++)
+              {
+                if(@wr==0)
+                {
+                   ser=intersect(ser,hquprimary[2*@n-1]);
+                }
+                else
+                {
+                   ser=intersect(ser,hquprimary[2*@n]);
+                }
+              }
+              setring gnir;
+              ser=imap(@Phelp,ser);
+           }
+
+         // }
+        }
+//HIER
+        if(abspri)
+        {
+          list resu,tempo;
+          for(ab=1;ab<=size(quprimary) div 2;ab++)
+          {
+             if (deg(quprimary[2*ab][1])!=0)
+             {
+               tempo=quprimary[2*ab-1],quprimary[2*ab],
+                         absprimary[ab],abskeep[ab];
+               resu[ab]=tempo;
+             }
+          }
+          quprimary=resu;
+          @wr=3;
+        }
+        if(size(reduce(ser,peek,1))!=0)
+        {
+           if(@wr>0)
+           {
+              // The following line was dropped to avoid the recursion step:
+              //htprimary=newDecompStep(@j, at wr,peek,ser);
+              htprimary = list();
+           }
+           else
+           {
+              // The following line was dropped to avoid the recursion step:
+              //htprimary=newDecompStep(@j,peek,ser);
+              htprimary = list();
+           }
+           // here we collect now both results primary(sat(j,gh))
+           // and primary(j,gh^n)
+           @n=size(quprimary);
+           if (deg(quprimary[1][1])<=0) { @n=0; }
+           for (@k=1;@k<=size(htprimary);@k++)
+           {
+              quprimary[@n+ at k]=htprimary[@k];
+           }
+        }
+     }
+   }
+   else
+   {
+      if(abspri)
+      {
+        list resu,tempo;
+        for(ab=1;ab<=size(quprimary) div 2;ab++)
+        {
+           tempo=quprimary[2*ab-1],quprimary[2*ab],
+                   absprimary[ab],abskeep[ab];
+           resu[ab]=tempo;
+        }
+        quprimary=resu;
+      }
+   }
+  //---------------------------------------------------------------------------
+  //back to the ring we started with
+  //the final result: primary
+  //---------------------------------------------------------------------------
+
+  setring @P;
+  option(set,op at P);
+  primary=imap(gnir,quprimary);
+
+  if (intersectOption == "intersect")
+  {
+     return(list(primary, imap(gnir, ser)));
+  }
+  else
+  {
+    return(primary);
+  }
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring  r = 32003,(x,y,z),lp;
+   poly  p = z2+1;
+   poly  q = z4+2;
+   ideal i = p^2*q^3,(y-z3)^3,(x-yz+z4)^4;
+   list pr= newDecompStep(i);
+   pr;
+   testPrimary( pr, i);
+}
+
+// This was part of proc decomp.
+// In proc newDecompStep, used for the computation of the minimal associated primes,
+// this part was separated as a soubrutine to make the code more clear.
+// Also, since the reduction is performed twice in proc newDecompStep, it should use both times this routine.
+// This is not yet implemented, since the reduction is not exactly the same and some changes should be made.
+static proc newReduction(ideal @j, ideal ser, intvec @hilb, intvec @w, int jdim, int abspri, int @wr, list data)
+{
+   ASSUME(1, hasFieldCoefficient(basering) );
+   ASSUME(1, not isQuotientRing(basering) ) ;
+   ASSUME(1, hasGlobalOrdering(basering) ) ;
+
+
+   string @va;
+   def quotring;
+   intvec op;
+   intvec @vv;
+   def gnir = basering;
+   ideal isat=0;
+   int @n;
+   int @n1 = 0;
+   int @n2 = 0;
+   int @n3 = 0;
+   int homo = homog(@j);
+   int lauf;
+   int @k;
+   list fett;
+   int keepdi;
+   list collectprimary;
+   list lsau;
+   list lnew;
+   ideal @h;
+
+   list indepInfo = data[1];
+   list quprimary = list();
+
+   //if(abspri)
+   //{
+     int ab;
+     list absprimarytmp,abskeeptmp;
+     list absprimary, abskeep;
+   //}
+   // Debug
+   dbprint(printlevel - voice, "newReduction, v2.0");
+
+   if((indepInfo[1]==varstr(basering)))  // &&(@m==1)
+   //this is the good case, nothing to do, just to have the same notations
+   //change the ring
+   {
+     def gnir1=ring(ringlist(basering));
+     setring gnir1;
+     ideal @j = fetch(gnir, @j);
+     attrib(@j,"isSB",1);
+     ideal ser = fetch(gnir, ser);
+   }
+   else
+   {
+     @va=string(maxideal(1));
+//Aenderung==============
+     //if(@m==1)
+     //{
+     //  @j=fetch(@P,i);
+     //}
+//=======================
+     execute("ring gnir1 = ("+charstr(basering)+"),("+indepInfo[1]+"),("
+                              +indepInfo[2]+");");
+     execute("map phi=gnir,"+ at va+";");
+     op=option(get);
+     option(redSB);
+     if(homo==1)
+     {
+       ideal @j=std(phi(@j), at hilb, at w);
+     }
+     else
+     {
+       ideal @j=groebner(phi(@j));
+     }
+     ideal ser=phi(ser);
+
+     option(set,op);
+   }
+   if((deg(@j[1])==0)||(dim(@j)<jdim))
+   {
+     setring gnir;
+     break;
+   }
+   for (lauf=1;lauf<=size(@j);lauf++)
+   {
+     fett[lauf]=size(@j[lauf]);
+   }
+   //------------------------------------------------------------------------
+   //we have now the following situation:
+   //j intersected with K[var(nnp+1),..,var(nva)] is zero so we may pass
+   //to this quotientring, j is their still a standardbasis, the
+   //leading coefficients of the polynomials  there (polynomials in
+   //K[var(nnp+1),..,var(nva)]) are collected in the list h,
+   //we need their ggt, gh, because of the following: let
+   //(j:gh^n)=(j:gh^infinity) then j*K(var(nnp+1),..,var(nva))[..the rest..]
+   //intersected with K[var(1),...,var(nva)] is (j:gh^n)
+   //on the other hand j=(j,gh^n) intersected with (j:gh^n)
+
+   //------------------------------------------------------------------------
+
+   //arrangement for quotientring K(var(nnp+1),..,var(nva))[..the rest..] and
+   //map phi:K[var(1),...,var(nva)] --->K(var(nnpr+1),..,var(nva))[..rest..]
+   //------------------------------------------------------------------------
+
+   quotring=prepareQuotientring(nvars(basering)-indepInfo[3],"lp");
+
+   //---------------------------------------------------------------------
+   //we pass to the quotientring   K(var(nnp+1),..,var(nva))[..the rest..]
+   //---------------------------------------------------------------------
+
+   ideal @jj=lead(@j);               //!! vorn vereinbaren
+   setring quotring;
+
+   ideal @jj=imap(gnir1, at jj);
+   @vv=clearSBNeu(@jj,fett);  //!! vorn vereinbaren
+   setring gnir1;
+   @k=size(@j);
+   for (lauf=1;lauf<=@k;lauf++)
+   {
+     if(@vv[lauf]==1)
+     {
+       @j[lauf]=0;
+     }
+   }
+   @j=simplify(@j,2);
+   setring quotring;
+   // @j considered in the quotientring
+   ideal @j=imap(gnir1, at j);
+
+   ideal ser=imap(gnir1,ser);
+
+   kill gnir1;
+
+   //j is a standardbasis in the quotientring but usually not minimal
+   //here it becomes minimal
+
+   attrib(@j,"isSB",1);
+
+   //we need later ggt(h[1],...)=gh for saturation
+   ideal @h;
+   if(deg(@j[1])>0)
+   {
+     for(@n=1;@n<=size(@j);@n++)
+     {
+       @h[@n]=leadcoef(@j[@n]);
+     }
+     //the primary decomposition of j*K(var(nnp+1),..,var(nva))[..the rest..]
+     op=option(get);
+     option(redSB);
+
+     int zeroMinAss = @wr;
+     if (@wr == 2) {zeroMinAss = 1;}
+     list uprimary= newZero_decomp(@j, ser, zeroMinAss);
+
+//HIER
+     if(abspri)
+     {
+       ideal II;
+       ideal jmap;
+       map sigma;
+       nn=nvars(basering);
+       map invsigma=basering,maxideal(1);
+       for(ab=1;ab<=size(uprimary) div 2;ab++)
+       {
+         II=uprimary[2*ab];
+         attrib(II,"isSB",1);
+         if(deg(II[1])!=vdim(II))
+         {
+           jmap=randomLast(50);
+           sigma=basering,jmap;
+           jmap[nn]=2*var(nn)-jmap[nn];
+           invsigma=basering,jmap;
+           II=groebner(sigma(II));
+         }
+         absprimarytmp[ab]= absFactorize(II[1],77);
+         II=var(nn);
+         abskeeptmp[ab]=string(invsigma(II));
+         invsigma=basering,maxideal(1);
+       }
+     }
+     option(set,op);
+   }
+   else
+   {
+     list uprimary;
+     uprimary[1]=ideal(1);
+     uprimary[2]=ideal(1);
+   }
+   //we need the intersection of the ideals in the list quprimary with the
+   //polynomialring, i.e. let q=(f1,...,fr) in the quotientring such an ideal
+   //but fi polynomials, then the intersection of q with the polynomialring
+   //is the saturation of the ideal generated by f1,...,fr with respect to
+   //h which is the lcm of the leading coefficients of the fi considered in
+   //in the quotientring: this is coded in saturn
+
+   list saturn;
+   ideal hpl;
+
+   for(@n=1;@n<=size(uprimary);@n++)
+   {
+     uprimary[@n]=interred(uprimary[@n]); // temporary fix
+     hpl=0;
+     for(@n1=1;@n1<=size(uprimary[@n]);@n1++)
+     {
+       hpl=hpl,leadcoef(uprimary[@n][@n1]);
+     }
+     saturn[@n]=hpl;
+   }
+
+   //--------------------------------------------------------------------
+   //we leave  the quotientring   K(var(nnp+1),..,var(nva))[..the rest..]
+   //back to the polynomialring
+   //---------------------------------------------------------------------
+   setring gnir;
+
+   collectprimary=imap(quotring,uprimary);
+   lsau=imap(quotring,saturn);
+   @h=imap(quotring, at h);
+
+   kill quotring;
+
+   @n2=size(quprimary);
+   @n3=@n2;
+
+   for(@n1=1;@n1<=size(collectprimary) div 2;@n1++)
+   {
+     if(deg(collectprimary[2*@n1][1])>0)
+     {
+       @n2++;
+       quprimary[@n2]=collectprimary[2*@n1-1];
+       lnew[@n2]=lsau[2*@n1-1];
+       @n2++;
+       lnew[@n2]=lsau[2*@n1];
+       quprimary[@n2]=collectprimary[2*@n1];
+       if(abspri)
+       {
+         absprimary[@n2 div 2]=absprimarytmp[@n1];
+         abskeep[@n2 div 2]=abskeeptmp[@n1];
+       }
+     }
+   }
+
+   //here the intersection with the polynomialring
+   //mentioned above is really computed
+   for(@n=@n3 div 2+1;@n<=@n2 div 2;@n++)
+   {
+     if(specialIdealsEqual(quprimary[2*@n-1],quprimary[2*@n]))
+     {
+       quprimary[2*@n-1]=sat2(quprimary[2*@n-1],lnew[2*@n-1])[1];
+       quprimary[2*@n]=quprimary[2*@n-1];
+     }
+     else
+     {
+       if(@wr==0)
+       {
+         quprimary[2*@n-1]=sat2(quprimary[2*@n-1],lnew[2*@n-1])[1];
+       }
+       quprimary[2*@n]=sat2(quprimary[2*@n],lnew[2*@n])[1];
+     }
+   }
+
+   return(quprimary, absprimary, abskeep, ser, @h);
+}
+
+
+////////////////////////////////////////////////////////////////////////////
+
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+// Based on minAssGTZ
+
+proc minAss(ideal i,list #)
+"USAGE:   minAss(I[, l]); i ideal, l list (optional) of parameters, same as minAssGTZ
+RETURN:  a list, the minimal associated prime ideals of I.
+NOTE:    Designed for characteristic 0, works also in char k > 0 based
+         on an algorithm of Yokoyama
+EXAMPLE: example minAss; shows an example
+"
+{
+  return(minAssGTZ(i,#));
+}
+example
+{ "EXAMPLE:";  echo = 2;
+   ring  r = 0, (x, y, z), dp;
+   poly  p = z2 + 1;
+   poly  q = z3 + 2;
+   ideal i = p * q^2, y - z2;
+   list pr = minAss(i);
+   pr;
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Computes the minimal associated primes of I via Laplagne algorithm,
+// using primary decomposition in the zero dimensional case.
+// For reduction to the zerodimensional case, it uses the procedure
+// decomp, with some modifications to avoid the recursion.
+//
+
+static proc minAssSL(ideal I)
+// Input = I, ideal
+// Output = primaryDec where primaryDec is the list of the minimal
+// associated primes and the primary components corresponding to these primes.
+{
+  ASSUME(1, hasFieldCoefficient(basering) );
+  ASSUME(1, not isQuotientRing(basering) ) ;
+  ASSUME(1, hasGlobalOrdering(basering) ) ;
+
+  ideal P = 1;
+  list pd = list();
+  int k;
+  int stop = 0;
+  list primaryDec = list();
+
+  while (stop == 0)
+  {
+    // Debug
+    dbprint(printlevel - voice, "// We call minAssSLIteration to find new prime ideals!");
+    pd = minAssSLIteration(I, P);
+    // Debug
+    dbprint(printlevel - voice, "// Output of minAssSLIteration:");
+    dbprint(printlevel - voice, pd);
+    if (size(pd[1]) > 0)
+    {
+      primaryDec = primaryDec + pd[1];
+      // Debug
+      dbprint(printlevel - voice, "// We intersect the prime ideals obtained.");
+      P = intersect(P, pd[2]);
+      // Debug
+      dbprint(printlevel - voice, "// Intersection finished.");
+    }
+    else
+    {
+      stop = 1;
+    }
+  }
+
+  // Returns only the primary components, not the radical.
+  return(primaryDec);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Given an ideal I and an ideal P (intersection of some minimal prime ideals
+// associated to I), it calculates new minimal prime ideals associated to I
+// which were not used to calculate P.
+// This version uses Primary Decomposition in the zerodimensional case.
+static proc minAssSLIteration(ideal I, ideal P);
+{
+  ASSUME(1, hasFieldCoefficient(basering) );
+  ASSUME(1, not isQuotientRing(basering) ) ;
+  ASSUME(1, hasGlobalOrdering(basering) ) ;
+
+  int k = 1;
+  int good  = 0;
+  list primaryDec = list();
+  // Debug
+  dbprint (printlevel-voice, "// We search for an element in P - sqrt(I).");
+  while ((k <= size(P)) and (good == 0))
+  {
+    good = 1 - rad_con(P[k], I);
+    k++;
+  }
+  k--;
+  if (good == 0)
+  {
+    // Debug
+    dbprint (printlevel - voice, "// No element was found, P = sqrt(I).");
+    return (list(primaryDec, ideal(0)));
+  }
+  // Debug
+  dbprint (printlevel - voice, "// We found h = ", P[k]);
+  dbprint (printlevel - voice, "// We calculate the saturation of I with respect to the element just founded.");
+  ideal J = sat(I, P[k])[1];
+
+  // Uses decomp from primdec, modified to avoid the recursion.
+  // Debug
+  dbprint(printlevel - voice, "// We do the reduction to the zerodimensional case, via decomp.");
+
+  primaryDec = newDecompStep(J, "oneIndep", "intersect", 2);
+  // Debug
+  dbprint(printlevel - voice, "// Proc decomp has found", size(primaryDec) div 2, "new primary components.");
+
+  return(primaryDec);
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////////////
+// Based on maxIndependSet
+// Added list # as parameter
+// If the first element of # is 0, the output is only 1 max indep set.
+// If no list is specified or #[1] = 1, the output is all the max indep set of the
+// leading terms ideal. This is the original output of maxIndependSet
+
+proc newMaxIndependSetLp(ideal j, list #)
+"USAGE:   newMaxIndependentSetLp(i); i ideal (returns all maximal independent sets of the corresponding leading terms ideal)
+          newMaxIndependentSetLp(i, 0); i ideal (returns only one maximal independent set)
+RETURN:  list = #1. new varstring with the maximal independent set at the end,
+                #2. ordstring with the lp ordering,
+                #3. the number of independent variables
+NOTE:
+EXAMPLE: example newMaxIndependentSetLp; shows an example
+"
+{
+  ASSUME(0, hasFieldCoefficient(basering) );
+  ASSUME(0, not isQuotientRing(basering) ) ;
+  ASSUME(0, hasGlobalOrdering(basering) ) ;
+
+  int n, k, di;
+  list resu, hilf;
+  string var1, var2;
+  list v = indepSet(j, 0);
+
+  // SL 2006.04.21 1 Lines modified to use only one independent Set
+  string indepOption;
+  if (size(#) > 0)
+  {
+    indepOption = #[1];
+  }
+  else
+  {
+    indepOption = "allIndep";
+  }
+
+  int nMax;
+  if (indepOption == "allIndep")
+  {
+    nMax = size(v);
+  }
+  else
+  {
+    nMax = 1;
+  }
+
+  for(n = 1; n <= nMax; n++)
+  // SL 2006.04.21 2
+  {
+    di = 0;
+    var1 = "";
+    var2 = "";
+    for(k = 1; k <= size(v[n]); k++)
+    {
+      if(v[n][k] != 0)
+      {
+        di++;
+        var2 = var2 + "var(" + string(k) + "), ";
+      }
+      else
+      {
+        var1 = var1 + "var(" + string(k) + "), ";
+      }
+    }
+    if(di > 0)
+    {
+      var1 = var1 + var2;
+      var1 = var1[1..size(var1) - 2];       // The "- 2" removes the trailer comma
+      hilf[1] = var1;
+      // SL 2006.21.04 1 The order is now block dp instead of lp
+      //hilf[2] = "dp(" + string(nvars(basering) - di) + "), dp(" + string(di) + ")";
+      // SL 2006.21.04 2
+      // For decomp, lp ordering is needed. Nothing is changed.
+      hilf[2] = "lp";
+      hilf[3] = di;
+      resu[n] = hilf;
+    }
+    else
+    {
+      resu[n] = varstr(basering), ordstr(basering), 0;
+    }
+  }
+  return(resu);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring s1 = (0, x, y), (a, b, c, d, e, f, g), lp;
+   ideal i = ea - fbg, fa + be, ec - fdg, fc + de;
+   i = std(i);
+   list l = newMaxIndependSetLp(i);
+   l;
+   i = i, g;
+   l = newMaxIndependSetLp(i);
+   l;
+
+   ring s = 0, (x, y, z), lp;
+   ideal i = z, yx;
+   list l = newMaxIndependSetLp(i);
+   l;
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc newZero_decomp (ideal j, ideal ser, int @wr, list #)
+"USAGE:   newZero_decomp(j,ser, at wr); j,ser ideals, @wr=0 or 1
+         (@wr=0 for primary decomposition, @wr=1 for computation of associated
+         primes)
+         if #[1] = "nest", then #[2] indicates the nest level (number of recursive calls)
+         When the nest level is high it indicates that the computation is difficult,
+         and different methods are applied.
+RETURN:  list = list of primary ideals and their radicals (at even positions
+         in the list) if the input is zero-dimensional and a standardbases
+         with respect to lex-ordering
+         If ser!=(0) and ser is contained in j or if j is not zero-dimen-
+         sional then ideal(1),ideal(1) is returned
+NOTE:    Algorithm of Gianni/Trager/Zacharias
+EXAMPLE: example newZero_decomp; shows an example
+"
+{
+  ASSUME(0, hasFieldCoefficient(basering) );
+  ASSUME(0, not isQuotientRing(basering) ) ;
+  ASSUME(0, hasGlobalOrdering(basering) ) ;
+
+  def   @P = basering;
+  int uytrewq;
+  int nva = nvars(basering);
+  int @k, at s, at n, at k1,zz;
+  list primary,lres0,lres1,act, at lh, at wh;
+  map phi,psi,phi1,psi1;
+  ideal jmap,jmap1,jmap2,helpprim, at qh, at qht,ser1;
+  intvec @vh, at hilb;
+  string @ri;
+  poly @f;
+
+  // Debug
+  dbprint(printlevel - voice, "proc newZero_decomp");
+
+  if (dim(j)>0)
+  {
+    primary[1]=ideal(1);
+    primary[2]=ideal(1);
+    return(primary);
+  }
+  j=interred(j);
+
+  attrib(j,"isSB",1);
+
+  int nestLevel = 0;
+  if (size(#) > 0)
+  {
+    if (typeof(#[1]) == "string")
+    {
+      if (#[1] == "nest")
+      {
+        nestLevel = #[2];
+      }
+      # = list();
+    }
+  }
+
+  if(vdim(j)==deg(j[1]))
+  {
+    act=factor(j[1]);
+    for(@k=1;@k<=size(act[1]);@k++)
+    {
+      @qh=j;
+      if(@wr==0)
+      {
+        @qh[1]=act[1][@k]^act[2][@k];
+      }
+      else
+      {
+        @qh[1]=act[1][@k];
+      }
+      primary[2*@k-1]=interred(@qh);
+      @qh=j;
+      @qh[1]=act[1][@k];
+      primary[2*@k]=interred(@qh);
+      attrib( primary[2*@k-1],"isSB",1);
+
+      if((size(ser)>0)&&(size(reduce(ser,primary[2*@k-1],1))==0))
+      {
+        primary[2*@k-1]=ideal(1);
+        primary[2*@k]=ideal(1);
+      }
+    }
+    return(primary);
+  }
+
+  if(homog(j)==1)
+  {
+    primary[1]=j;
+    if((size(ser)>0)&&(size(reduce(ser,j,1))==0))
+    {
+      primary[1]=ideal(1);
+      primary[2]=ideal(1);
+      return(primary);
+    }
+    if(dim(j)==-1)
+    {
+      primary[1]=ideal(1);
+      primary[2]=ideal(1);
+    }
+    else
+    {
+      primary[2]=maxideal(1);
+    }
+    return(primary);
+  }
+
+//the first element in the standardbase is factorized
+  if(deg(j[1])>0)
+  {
+    act=factor(j[1]);
+    testFactor(act,j[1]);
+  }
+  else
+  {
+    primary[1]=ideal(1);
+    primary[2]=ideal(1);
+    return(primary);
+  }
+
+//with the factors new ideals (hopefully the primary decomposition)
+//are created
+  if(size(act[1])>1)
+  {
+    if(size(#)>1)
+    {
+      primary[1]=ideal(1);
+      primary[2]=ideal(1);
+      primary[3]=ideal(1);
+      primary[4]=ideal(1);
+      return(primary);
+    }
+    for(@k=1;@k<=size(act[1]);@k++)
+    {
+      if(@wr==0)
+      {
+        primary[2*@k-1]=std(j,act[1][@k]^act[2][@k]);
+      }
+      else
+      {
+        primary[2*@k-1]=std(j,act[1][@k]);
+      }
+      if((act[2][@k]==1)&&(vdim(primary[2*@k-1])==deg(act[1][@k])))
+      {
+        primary[2*@k]   = primary[2*@k-1];
+      }
+      else
+      {
+        primary[2*@k]   = primaryTest(primary[2*@k-1],act[1][@k]);
+      }
+    }
+  }
+  else
+  {
+    primary[1]=j;
+    if((size(#)>0)&&(act[2][1]>1))
+    {
+      act[2]=1;
+      primary[1]=std(primary[1],act[1][1]);
+    }
+    if(@wr!=0)
+    {
+      primary[1]=std(j,act[1][1]);
+    }
+    if((act[2][1]==1)&&(vdim(primary[1])==deg(act[1][1])))
+    {
+      primary[2]=primary[1];
+    }
+    else
+    {
+      primary[2]=primaryTest(primary[1],act[1][1]);
+    }
+  }
+
+  if(size(#)==0)
+  {
+    primary=splitPrimary(primary,ser, at wr,act);
+  }
+
+  if((voice>=6)&&(char(basering)<=181))
+  {
+    primary=splitCharp(primary);
+  }
+
+  if((@wr==2)&&(npars(basering)>0)&&(voice>=6)&&(char(basering)>0))
+  {
+  //the prime decomposition of Yokoyama in characteristic p
+    list ke,ek;
+    @k=0;
+    while(@k<size(primary) div 2)
+    {
+      @k++;
+      if(size(primary[2*@k])==0)
+      {
+        ek=insepDecomp(primary[2*@k-1]);
+        primary=delete(primary,2*@k);
+        primary=delete(primary,2*@k-1);
+        @k--;
+      }
+      ke=ke+ek;
+    }
+    for(@k=1;@k<=size(ke);@k++)
+    {
+      primary[size(primary)+1]=ke[@k];
+      primary[size(primary)+1]=ke[@k];
+    }
+  }
+
+  if(nestLevel > 1){primary=extF(primary);}
+
+//test whether all ideals in the decomposition are primary and
+//in general position
+//if not after a random coordinate transformation of the last
+//variable the corresponding ideal is decomposed again.
+  if((npars(basering)>0)&&(nestLevel > 1))
+  {
+    poly randp;
+    for(zz=1;zz<nvars(basering);zz++)
+    {
+      randp=randp
+              +(random(0,5)*par(1)^2+random(0,5)*par(1)+random(0,5))*var(zz);
+    }
+    randp=randp+var(nvars(basering));
+  }
+  @k=0;
+  while(@k<(size(primary) div 2))
+  {
+    @k++;
+    if (size(primary[2*@k])==0)
+    {
+      for(zz=1;zz<size(primary[2*@k-1])-1;zz++)
+      {
+        attrib(primary[2*@k-1],"isSB",1);
+        if(vdim(primary[2*@k-1])==deg(primary[2*@k-1][zz]))
+        {
+          primary[2*@k]=primary[2*@k-1];
+        }
+      }
+    }
+  }
+
+  @k=0;
+  ideal keep;
+  while(@k<(size(primary) div 2))
+  {
+    @k++;
+    if (size(primary[2*@k])==0)
+    {
+      jmap=randomLast(100);
+      jmap1=maxideal(1);
+      jmap2=maxideal(1);
+      @qht=primary[2*@k-1];
+      if((npars(basering)>0)&&(nestLevel > 1))
+      {
+        jmap[size(jmap)]=randp;
+      }
+
+      for(@n=2;@n<=size(primary[2*@k-1]);@n++)
+      {
+        if(deg(lead(primary[2*@k-1][@n]))==1)
+        {
+          for(zz=1;zz<=nva;zz++)
+          {
+            if(lead(primary[2*@k-1][@n])/var(zz)!=0)
+            {
+              jmap1[zz]=-1/leadcoef(primary[2*@k-1][@n])*primary[2*@k-1][@n]
+                   +2/leadcoef(primary[2*@k-1][@n])*lead(primary[2*@k-1][@n]);
+              jmap2[zz]=primary[2*@k-1][@n];
+              @qht[@n]=var(zz);
+            }
+          }
+          jmap[nva]=subst(jmap[nva],lead(primary[2*@k-1][@n]),0);
+        }
+      }
+      if(size(subst(jmap[nva],var(1),0)-var(nva))!=0)
+      {
+        // jmap[nva]=subst(jmap[nva],var(1),0);
+        //hier geaendert +untersuchen!!!!!!!!!!!!!!
+      }
+      phi1=@P,jmap1;
+      phi=@P,jmap;
+      for(@n=1;@n<=nva;@n++)
+      {
+        jmap[@n]=-(jmap[@n]-2*var(@n));
+      }
+      psi=@P,jmap;
+      psi1=@P,jmap2;
+      @qh=phi(@qht);
+
+//=================== the new part ============================
+
+      if (npars(basering)>1) { @qh=groebner(@qh,"par2var"); }
+      else                   { @qh=groebner(@qh); }
+
+//=============================================================
+//       if(npars(@P)>0)
+//       {
+//          @ri= "ring @Phelp ="
+//                  +string(char(@P))+",
+//                   ("+varstr(@P)+","+parstr(@P)+", at t),(C,dp);";
+//       }
+//       else
+//       {
+//          @ri= "ring @Phelp ="
+//                  +string(char(@P))+",("+varstr(@P)+", at t),(C,dp);";
+//       }
+//       execute(@ri);
+//       ideal @qh=homog(imap(@P, at qht), at t);
+//
+//       ideal @qh1=std(@qh);
+//       @hilb=hilb(@qh1,1);
+//       @ri= "ring @Phelp1 ="
+//                  +string(char(@P))+",("+varstr(@Phelp)+"),(C,lp);";
+//       execute(@ri);
+//       ideal @qh=homog(imap(@P, at qh), at t);
+//       kill @Phelp;
+//       @qh=std(@qh, at hilb);
+//       @qh=subst(@qh, at t,1);
+//       setring @P;
+//       @qh=imap(@Phelp1, at qh);
+//       kill @Phelp1;
+//       @qh=clearSB(@qh);
+//       attrib(@qh,"isSB",1);
+//=============================================================
+
+      ser1=phi1(ser);
+      @lh=newZero_decomp (@qh,phi(ser1), at wr, list("nest", nestLevel + 1));
+
+      kill lres0;
+      list lres0;
+      if(size(@lh)==2)
+      {
+        helpprim=@lh[2];
+        lres0[1]=primary[2*@k-1];
+        attrib(lres0[1],"isSB",1);
+        ser1=psi(helpprim);
+        lres0[2]=psi1(ser1);
+        if(size(reduce(lres0[2],lres0[1],1))==0)
+        {
+          primary[2*@k]=primary[2*@k-1];
+          continue;
+        }
+      }
+      else
+      {
+        lres1=psi(@lh);
+        lres0=psi1(lres1);
+      }
+
+//=================== the new part ============================
+
+      primary=delete(primary,2*@k-1);
+      primary=delete(primary,2*@k-1);
+      @k--;
+      if(size(lres0)==2)
+      {
+        if (npars(basering)>1) { lres0[2]=groebner(lres0[2],"par2var"); }
+        else                   { lres0[2]=groebner(lres0[2]); }
+      }
+      else
+      {
+        for(@n=1;@n<=size(lres0) div 2;@n++)
+        {
+          if(specialIdealsEqual(lres0[2*@n-1],lres0[2*@n])==1)
+          {
+            lres0[2*@n-1]=groebner(lres0[2*@n-1]);
+            lres0[2*@n]=lres0[2*@n-1];
+            attrib(lres0[2*@n],"isSB",1);
+          }
+          else
+          {
+            lres0[2*@n-1]=groebner(lres0[2*@n-1]);
+            lres0[2*@n]=groebner(lres0[2*@n]);
+          }
+        }
+      }
+      primary=primary+lres0;
+
+//=============================================================
+//       if(npars(@P)>0)
+//       {
+//          @ri= "ring @Phelp ="
+//                  +string(char(@P))+",
+//                   ("+varstr(@P)+","+parstr(@P)+", at t),(C,dp);";
+//       }
+//       else
+//       {
+//          @ri= "ring @Phelp ="
+//                  +string(char(@P))+",("+varstr(@P)+", at t),(C,dp);";
+//       }
+//       execute(@ri);
+//       list @lvec;
+//       list @lr=imap(@P,lres0);
+//       ideal @lr1;
+//
+//       if(size(@lr)==2)
+//       {
+//          @lr[2]=homog(@lr[2], at t);
+//          @lr1=std(@lr[2]);
+//          @lvec[2]=hilb(@lr1,1);
+//       }
+//       else
+//       {
+//          for(@n=1;@n<=size(@lr) div 2;@n++)
+//          {
+//             if(specialIdealsEqual(@lr[2*@n-1], at lr[2*@n])==1)
+//             {
+//                @lr[2*@n-1]=homog(@lr[2*@n-1], at t);
+//                @lr1=std(@lr[2*@n-1]);
+//                @lvec[2*@n-1]=hilb(@lr1,1);
+//                @lvec[2*@n]=@lvec[2*@n-1];
+//             }
+//             else
+//             {
+//                @lr[2*@n-1]=homog(@lr[2*@n-1], at t);
+//                @lr1=std(@lr[2*@n-1]);
+//                @lvec[2*@n-1]=hilb(@lr1,1);
+//                @lr[2*@n]=homog(@lr[2*@n], at t);
+//                @lr1=std(@lr[2*@n]);
+//                @lvec[2*@n]=hilb(@lr1,1);
+//
+//             }
+//         }
+//       }
+//       @ri= "ring @Phelp1 ="
+//                  +string(char(@P))+",("+varstr(@Phelp)+"),(C,lp);";
+//       execute(@ri);
+//       list @lr=imap(@Phelp, at lr);
+//
+//       kill @Phelp;
+//       if(size(@lr)==2)
+//      {
+//          @lr[2]=std(@lr[2], at lvec[2]);
+//          @lr[2]=subst(@lr[2], at t,1);
+//
+//       }
+//       else
+//       {
+//          for(@n=1;@n<=size(@lr) div 2;@n++)
+//          {
+//             if(specialIdealsEqual(@lr[2*@n-1], at lr[2*@n])==1)
+//             {
+//                @lr[2*@n-1]=std(@lr[2*@n-1], at lvec[2*@n-1]);
+//                @lr[2*@n-1]=subst(@lr[2*@n-1], at t,1);
+//                @lr[2*@n]=@lr[2*@n-1];
+//                attrib(@lr[2*@n],"isSB",1);
+//             }
+//             else
+//             {
+//                @lr[2*@n-1]=std(@lr[2*@n-1], at lvec[2*@n-1]);
+//                @lr[2*@n-1]=subst(@lr[2*@n-1], at t,1);
+//                @lr[2*@n]=std(@lr[2*@n], at lvec[2*@n]);
+//                @lr[2*@n]=subst(@lr[2*@n], at t,1);
+//             }
+//          }
+//       }
+//       kill @lvec;
+//       setring @P;
+//       lres0=imap(@Phelp1, at lr);
+//       kill @Phelp1;
+//       for(@n=1;@n<=size(lres0);@n++)
+//       {
+//          lres0[@n]=clearSB(lres0[@n]);
+//          attrib(lres0[@n],"isSB",1);
+//       }
+//
+//       primary[2*@k-1]=lres0[1];
+//       primary[2*@k]=lres0[2];
+//       @s=size(primary) div 2;
+//       for(@n=1;@n<=size(lres0) div 2-1;@n++)
+//       {
+//         primary[2*@s+2*@n-1]=lres0[2*@n+1];
+//         primary[2*@s+2*@n]=lres0[2*@n+2];
+//       }
+//       @k--;
+//=============================================================
+    }
+  }
+  return(primary);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring  r = 0,(x,y,z),lp;
+   poly  p = z2+1;
+   poly  q = z4+2;
+   ideal i = p^2*q^3,(y-z3)^3,(x-yz+z4)^4;
+   i=std(i);
+   list  pr= newZero_decomp(i,ideal(0),0);
+   pr;
+}
+///////////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////////
+/*
+//Beispiele Wenk-Dipl (in ~/Texfiles/Diplom/Wenk/Examples/)
+//Zeiten: Singular/Singular/Singular -r123456789 -v :wilde13 (PentiumPro200)
+//Singular for HPUX-9 version 1-3-8  (2000060214)  Jun  2 2000 15:31:26
+//(wilde13)
+
+//1. vdim=20, 3  Komponenten
+//zerodec-time:2(1)  (matrix:1 charpoly:0 factor:1)
+//primdecGTZ-time: 1(0)
+ring rs= 0,(a,b,c),dp;
+poly f1= a^2*b*c + a*b^2*c + a*b*c^2 + a*b*c + a*b + a*c + b*c;
+poly f2= a^2*b^2*c + a*b^2*c^2 + a^2*b*c + a*b*c + b*c + a + c;
+poly f3= a^2*b^2*c^2 + a^2*b^2*c + a*b^2*c + a*b*c + a*c + c + 1;
+ideal gls=f1,f2,f3;
+int time=timer;
+printlevel =1;
+time=timer; list pr1=zerodec(gls); timer-time;size(pr1);
+time=timer; list pr =primdecGTZ(gls); timer-time;size(pr);
+time=timer; ideal ra =radical(gls); timer-time;size(pr);
+
+//2.cyclic5  vdim=70, 20 Komponenten
+//zerodec-time:36(28)  (matrix:1(0) charpoly:18(19) factor:17(9)
+//primdecGTZ-time: 28(5)
+//radical : 0
+ring rs= 0,(a,b,c,d,e),dp;
+poly f0= a + b + c + d + e + 1;
+poly f1= a + b + c + d + e;
+poly f2= a*b + b*c + c*d + a*e + d*e;
+poly f3= a*b*c + b*c*d + a*b*e + a*d*e + c*d*e;
+poly f4= a*b*c*d + a*b*c*e + a*b*d*e + a*c*d*e + b*c*d*e;
+poly f5= a*b*c*d*e - 1;
+ideal gls= f1,f2,f3,f4,f5;
+
+//3. random vdim=40, 1 Komponente
+//zerodec-time:126(304)  (matrix:1 charpoly:115(298) factor:10(5))
+//primdecGTZ-time:17 (11)
+ring rs=0,(x,y,z),dp;
+poly f1=2*x^2 + 4*x + 3*y^2 + 7*x*z + 9*y*z + 5*z^2;
+poly f2=7*x^3 + 8*x*y + 12*y^2 + 18*x*z + 3*y^4*z + 10*z^3 + 12;
+poly f3=3*x^4 + 1*x*y*z + 6*y^3 + 3*x*z^2 + 2*y*z^2 + 4*z^2 + 5;
+ideal gls=f1,f2,f3;
+
+//4. introduction into resultants, sturmfels, vdim=28, 1 Komponente
+//zerodec-time:4  (matrix:0 charpoly:0 factor:4)
+//primdecGTZ-time:1
+ring rs=0,(x,y),dp;
+poly f1= x4+y4-1;
+poly f2= x5y2-4x3y3+x2y5-1;
+ideal gls=f1,f2;
+
+//5. 3 quadratic equations with random coeffs, vdim=8, 1 Komponente
+//zerodec-time:0(0)  (matrix:0 charpoly:0 factor:0)
+//primdecGTZ-time:1(0)
+ring rs=0,(x,y,z),dp;
+poly f1=2*x^2 + 4*x*y + 3*y^2 + 7*x*z + 9*y*z + 5*z^2 + 2;
+poly f2=7*x^2 + 8*x*y + 12*y^2 + 18*x*z + 3*y*z + 10*z^2 + 12;
+poly f3=3*x^2 + 1*x*y + 6*y^2 + 3*x*z + 2*y*z + 4*z^2 + 5;
+ideal gls=f1,f2,f3;
+
+//6. 3 polys    vdim=24, 1 Komponente
+// run("ex14",2);
+//zerodec-time:5(4)  (matrix:0 charpoly:3(3) factor:2(1))
+//primdecGTZ-time:4 (2)
+ring rs=0,(x1,x2,x3,x4),dp;
+poly f1=16*x1^2 + 3*x2^2 + 5*x3^4 - 1 - 4*x4 + x4^3;
+poly f2=5*x1^3 + 3*x2^2 + 4*x3^2*x4 + 2*x1*x4 - 1 + x4 + 4*x1 + x2 + x3 + x4;
+poly f3=-4*x1^2 + x2^2 + x3^2 - 3 + x4^2 + 4*x1 + x2 + x3 + x4;
+poly f4=-4*x1 + x2 + x3 + x4;
+ideal gls=f1,f2,f3,f4;
+
+//7. ex43, PoSSo, caprasse   vdim=56, 16 Komponenten
+//zerodec-time:23(15)  (matrix:0 charpoly:16(13) factor:3(2))
+//primdecGTZ-time:3 (2)
+ring rs= 0,(y,z,x,t),dp;
+ideal gls=y^2*z+2*y*x*t-z-2*x,
+4*y^2*z*x-z*x^3+2*y^3*t+4*y*x^2*t-10*y^2+4*z*x+4*x^2-10*y*t+2,
+2*y*z*t+x*t^2-2*z-x,
+-z^3*x+4*y*z^2*t+4*z*x*t^2+2*y*t^3+4*z^2+4*z*x-10*y*t-10*t^2+2;
+
+//8. Arnborg-System, n=6 (II),    vdim=156, 90 Komponenten
+//zerodec-time (char32003):127(45)(matrix:2(0) charpoly:106(37) factor:16(7))
+//primdecGTZ-time(char32003) :81 (18)
+//ring rs= 0,(a,b,c,d,x,f),dp;
+ring rs= 32003,(a,b,c,d,x,f),dp;
+ideal gls=a+b+c+d+x+f, ab+bc+cd+dx+xf+af, abc+bcd+cdx+d*xf+axf+abf,
+abcd+bcdx+cd*xf+ad*xf+abxf+abcf, abcdx+bcd*xf+acd*xf+abd*xf+abcxf+abcdf,
+abcd*xf-1;
+
+//9. ex42, PoSSo, Methan6_1, vdim=27, 2 Komponenten
+//zerodec-time:610  (matrix:10 charpoly:557 factor:26)
+//primdecGTZ-time: 118
+//zerodec-time(char32003):2
+//primdecGTZ-time(char32003):4
+//ring rs= 0,(x1,x2,x3,x4,x5,x6,x7,x8,x9,x10),dp;
+ring rs= 32003,(x1,x2,x3,x4,x5,x6,x7,x8,x9,x10),dp;
+ideal gls=64*x2*x7-10*x1*x8+10*x7*x9+11*x7*x10-320000*x1,
+-32*x2*x7-5*x2*x8-5*x2*x10+160000*x1-5000*x2,
+-x3*x8+x6*x8+x9*x10+210*x6+1300000,
+-x4*x8+700000,
+x10^2-2*x5,
+-x6*x8+x7*x9-210*x6,
+-64*x2*x7-10*x7*x9-11*x7*x10+320000*x1-16*x7+7000000,
+-10*x1*x8-10*x2*x8-10*x3*x8-10*x4*x8-10*x6*x8+10*x2*x10+11*x7*x10
+    +20000*x2+14*x5,
+x4*x8-x7*x9-x9*x10-410*x9,
+10*x2*x8+10*x3*x8+10*x6*x8+10*x7*x9-10*x2*x10-11*x7*x10-10*x9*x10
+    -10*x10^2+1400*x6-4200*x10;
+
+//10. ex33, walk-s7, Diplomarbeit von Tim, vdim=114
+//zerfaellt in unterschiedlich viele Komponenten in versch. Charkteristiken:
+//char32003:30, char0:3(2xdeg1,1xdeg112!), char181:4(2xdeg1,1xdeg28,1xdeg84)
+//char 0: zerodec-time:10075 (ca 3h) (matrix:3 charpoly:9367, factor:680
+//        + 24 sec fuer Normalform (anstatt einsetzen), total [29623k])
+//        primdecGTZ-time: 214
+//char 32003:zerodec-time:197(68) (matrix:2(1) charpoly:173(60) factor:15(6))
+//        primdecGTZ-time:14 (5)
+//char 181:zerodec-time:(87) (matrix:(1) charpoly:(58) factor:(25))
+//        primdecGTZ-time:(2)
+//in char181 stimmen Ergebnisse von zerodec und primdecGTZ ueberein (gecheckt)
+
+//ring rs= 0,(a,b,c,d,e,f,g),dp;
+ring rs= 32003,(a,b,c,d,e,f,g),dp;
+poly f1= 2gb + 2fc + 2ed + a2 + a;
+poly f2= 2gc + 2fd + e2 + 2ba + b;
+poly f3= 2gd + 2fe + 2ca + c + b2;
+poly f4= 2ge + f2 + 2da + d + 2cb;
+poly f5= 2fg + 2ea + e + 2db + c2;
+poly f6= g2 + 2fa + f + 2eb + 2dc;
+poly f7= 2ga + g + 2fb + 2ec + d2;
+ideal gls= f1,f2,f3,f4,f5,f6,f7;
+
+~/Singular/Singular/Singular -r123456789 -v
+LIB"./primdec.lib";
+timer=1;
+int time=timer;
+printlevel =1;
+option(prot,mem);
+time=timer; list pr1=zerodec(gls); timer-time;
+
+time=timer; list pr =primdecGTZ(gls); timer-time;
+time=timer; list pr =primdecSY(gls); timer-time;
+time=timer; ideal ra =radical(gls); timer-time;size(pr);
+LIB"all.lib";
+
+ring R=0,(a,b,c,d,e,f),dp;
+ideal I=cyclic(6);
+minAssGTZ(I);
+
+
+ring S=(2,a,b),(x,y),lp;
+ideal I=x8-b,y4+a;
+minAssGTZ(I);
+
+ring S1=2,(x,y,a,b),lp;
+ideal I=x8-b,y4+a;
+minAssGTZ(I);
+
+
+ring S2=(2,z),(x,y),dp;
+minpoly=z2+z+1;
+ideal I=y3+y+1,x4+x+1;
+primdecGTZ(I);
+minAssGTZ(I);
+
+ring S3=2,(x,y,z),dp;
+ideal I=y3+y+1,x4+x+1,z2+z+1;
+primdecGTZ(I);
+minAssGTZ(I);
+
+
+ring R1=2,(x,y,z),lp;
+ideal I=y6+y5+y3+y2+1,x4+x+1,z2+z+1;
+primdecGTZ(I);
+minAssGTZ(I);
+
+
+ring R2=(2,z),(x,y),lp;
+minpoly=z3+z+1;
+ideal I=y2+y+(z2+z+1),x4+x+1;
+primdecGTZ(I);
+minAssGTZ(I);
+
+*/
diff --git a/Singular/LIB/primdecint.lib b/Singular/LIB/primdecint.lib
new file mode 100644
index 0000000..3743cda
--- /dev/null
+++ b/Singular/LIB/primdecint.lib
@@ -0,0 +1,1764 @@
+//////////////////////////////////////////////////////////////////////////////
+version="version primdecint.lib 4.0.0.0 Jun_2013 "; // $Id: 18a6d3ea0b2cce56ffa6bfdc846413c25138cee4 $
+category = "Commutative Algebra";
+info="
+LIBRARY:  primdecint.lib   primary decomposition of an ideal in the polynomial
+                           ring over the integers
+
+AUTHORS:  G. Pfister       pfister at mathematik.uni-kl.de
+@*        A. Sadiq         afshanatiq at gmail.com
+@*        S. Steidel       steidel at mathematik.uni-kl.de
+
+OVERVIEW:
+
+  A library for computing the primary decomposition of an ideal in the
+  polynomial ring over the integers, Z[x_1,...,x_n].
+  The first procedure 'primdecZ' can be used in parallel.
+
+  Reference: Pfister,   Sadiq, Steidel , \"An Algorithm for primary decomposition in polynomial rings over the integers\" , arXiv:1008.2074
+
+PROCEDURES:
+ primdecZ(I);       compute the primary decomposition of ideal I
+ primdecZM(I);      compute the primary decomposition of module I
+ minAssZ(I);        compute the minimal associated primes of I
+ radicalZ(I);       compute the radical of I
+ heightZ(I);        compute the height of I
+ equidimZ(I);       compute the equidimensional part of I
+ intersectZ(I,J)    compute the intersection of I and J
+";
+
+LIB "primdec.lib";
+
+////////////////////////////////////////////////////////////////////////////////
+
+proc primdecZ(ideal I, list #)
+"USAGE:  primdecZ(I[, n]); I ideal, n integer (number of processors)
+NOTE:    If size(#) > 0, then #[1] is the number of available processors for
+         the computation.
+RETURN:  a list pr of primary ideals and their associated primes:
+ at format
+   pr[i][1]   the i-th primary component,
+   pr[i][2]   the i-th prime component.
+ at end format
+EXAMPLE: example primdecZ; shows an example
+"
+{
+   if(size(I)==0){return(list(list(ideal(0),ideal(0))));}
+
+//--------------------  Initialize optional parameters  ------------------------
+   if(size(#) > 0)
+   {
+      if(size(#) == 1)
+      {
+         int n = #[1];
+         ideal TES = 1;
+      }
+      if(size(#) == 2)
+      {
+         int n = #[1];
+         ideal TES = #[2];
+      }
+   }
+   else
+   {
+      int n = 1;
+      ideal TES = 1;
+   }
+
+
+   if(size(I)==1 && deg(I[1]) == 0)
+   {
+      ideal J = I;
+   }
+   else
+   {
+      ideal J = stdZ(I);
+   }
+
+   ideal K,N;
+   def R=basering;
+   number s;
+   list rl=ringlist(R);
+   int i,j,p,m,ex,nu,k_link;
+   list P,B,IS;
+   ideal Q,JJ;
+   ideal TQ=1;
+   if(deg(J[1])==0)
+   {
+      //=== I intersected with Z is not zero
+      list rp=rl;
+      rp[1]=0;
+      //=== q is generator of I intersect Z
+      number q=leadcoef(J[1]);
+      def Rhelp=ring(rp);
+      setring Rhelp;
+      number q=imap(R,q);
+      //=== computes the primes occuring in a generator of I intersect Z
+      list L = primefactors(q);
+
+      list A;
+      A[1]= ideal(0);
+      ideal J = imap(R,J);
+
+      for(j=1;j<=size(L[2]);j++)
+      {
+         if(L[2][j] > 1){ ex = 1; break; }
+      }
+
+      if(printlevel >= 10)
+      {
+         "n = "+string(n);
+         "size(L[2]) = "+string(size(L[2]));
+      }
+
+      int RT = rtimer;
+      if((n > 1) && (n < size(L[2])))
+      {
+
+//-----  Create n1 links l(1),...,l(n1), open all of them and compute  ---------
+//-----  standard basis for the primes L[1][2],...,L[1][n + 1].        ---------
+
+         for(i = 1; i <= n; i++)
+         {
+            p=int(L[1][i + 1]);
+            nu=int(L[2][i + 1]);
+            //link l(i) = "MPtcp:fork";
+            link l(i) = "ssi:fork";
+            open(l(i));
+            write(l(i), quote(modp(eval(J), eval(p), eval(nu))));
+         }
+
+         p = int(L[1][1]);
+         nu = int(L[2][1]);
+         int t = timer;
+         A[size(A)+1] = modp(J, p, nu);
+         t = timer - t;
+         if(t > 60) { t = 60; }
+         int i_sleep = system("sh", "sleep "+string(t));
+
+         j = n + 2;
+
+         while(j <= size(L[2]) + 1)
+         {
+            for(i = 1; i <= n; i++)
+            {
+               //=== ask if link l(i) is ready otherwise sleep for t seconds
+               if(status(l(i), "read", "ready"))
+               {
+                  //=== read the result from l(i)
+                  A[size(A)+1] = read(l(i));
+
+                  if(j <= size(L[2]))
+                  {
+                     p=int(L[1][j]);
+                     nu=int(L[2][j]);
+                     write(l(i), quote(modp(eval(J), eval(p), eval(nu))));
+                     j++;
+                  }
+                  else
+                  {
+                     k_link++;
+                     close(l(i));
+                  }
+               }
+            }
+            //=== k_link describes the number of closed links
+            if(k_link == n)
+            {
+               j++;
+            }
+            i_sleep = system("sh", "sleep "+string(t));
+         }
+      }
+      else
+      {
+         for(j=1;j<=size(L[2]);j++)
+         {
+            p=int(L[1][j]);
+            nu=int(L[2][j]);
+            A[size(A)+1] = modp(J, p,nu );
+         }
+      }
+
+      setring R;
+      list A = imap(Rhelp,A);
+      if(printlevel >= 10)
+      {
+         "A is computed in "+string(rtimer - RT)+" seconds.";
+      }
+      for(i=2;i<=size(A);i++)
+      {
+      //=== computes for all p in L the minimal associated primes of
+      //=== IZ/p[variables]
+         p = int(A[i][2]);
+         if(printlevel >= 10)
+         {
+            "p = "+string(p);
+            RT = rtimer;
+         }
+         nu = int(A[i][3]);
+         //=== maximal power of p dividing q, generator of I intersect Z
+         s = p^nu;
+
+         rp[1] = p;
+         def S = ring(rp);
+         setring S;
+         ideal J = imap(R,J);
+         setring R;
+
+         if(nu>1)
+         {
+            //=== p is of multiplicity > 1 in q
+
+            B = A[i][1];
+            for(j=1;j<=size(B);j++)
+            {
+               //=== the minimal associated primes of I
+               K=B[j],p;
+               K=stdZ(K);
+               B[j]=K;
+            }
+            for(j=1;j<=size(B);j++)
+            {
+               K=B[j];
+               //=== compute maximal independent set for KZ/p[variables]
+
+               setring S;
+               J=imap(R,K);
+               J=simplify(J,2);
+               attrib(J,"isSB",1);
+               IS=Primdec::maxIndependSet(J);
+               setring R;
+               //=== computing the pseudo primary and extract it
+               N=J,s;
+               N=stdZ(N);
+               Q=extractZ(N,j,IS,B);
+               //=== test for useless primaries
+               if(size(reduce(TES,Q))>0)
+               {
+                  TQ=intersectZ(TQ,Q);
+                  //TQ=intersect(TQ,Q);
+                  P[size(P)+1]=list(Q,K);
+               }
+            }
+         }
+         else
+         {
+            //=== p is of multiplicity 1 in q we can compute the
+            //=== primary decomposition directly
+
+            B = A[i][1];
+            for(j=1;j<=size(B);j++)
+            {
+               K=B[j][2],p;
+               K=stdZ(K);
+               Q=B[j][1],p;
+               Q=stdZ(Q);
+               if(size(reduce(TES,Q))>0)
+               {
+                  //TQ=intersectZ(TQ,Q);
+                  P[size(P)+1]=list(Q,K);
+               }
+            }
+            if(ex)
+            {
+               JJ=imap(S,J);
+               JJ=JJ,p;
+               JJ=stdZ(JJ);
+               TQ=intersectZ(TQ,JJ);
+               //TQ=intersect(TQ,JJ);
+            }
+         }
+         kill S;
+         if(printlevel >= 10)
+         {
+            string(p)+" done in "+string(rtimer - RT)+" seconds.";
+         }
+      }
+
+      setring R;
+      if(!ex){return(P);}
+      J=stdZ(J);
+      TQ=intersectZ(TQ,TES);
+      //TQ=intersect(TQ,TES);
+      if(size(reduce(TQ,J))!=0)
+      {
+         //=== taking care about embedded components
+         K=stdZ(quotientZ(J,TQ));
+         ideal W=K;
+         m++;
+         while(size(reduce(intersectZ(W,TQ),J))!=0)
+         //while(size(reduce(intersect(W,TQ),J))!=0)
+         {
+            W=stdZ(I+specialPowerZ(K,m));
+            m++;
+         }
+         list E=primdecZ(W,n,TQ);
+         for(i=1;i<=size(E);i++)
+         {
+            P[size(P)+1]=E[i];
+         }
+      }
+      return(P);
+   }
+
+   //==== the ideal intersected with Z is zero
+   rl[1]=0;
+   def Rhelp=ring(rl);
+   setring Rhelp;
+   ideal J=imap(R,J);
+   J=std(J);
+   //=== the primary decomposition over Q which gives the primary
+   //=== decomposition of I:h for a suitable integer h
+   list pr=primdecGTZ(J);
+   for(i=1;i<=size(pr);i++)
+   {
+      pr[i]=list(std(pr[i][1]),std(pr[i][2]));
+   }
+   setring R;
+   list pr=imap(Rhelp,pr);
+   //=== intersection with Z[variables]
+   for(i=1;i<=size(pr);i++)
+   {
+      pr[i]=list(coefZ(pr[i][1])[1],coefZ(pr[i][2])[1]);
+   }
+   //=== find h in Z such that I is the intersection of I:h and <I,h>
+   //=== and I:h = IQ[variables] intersected with Z[varables]
+   list H =coefZ(J);
+   ideal Y=H[1];
+   int h=H[2];
+   J=J,h;
+   //=== call primary decomposition over Z for <I,h>
+   ideal testid = 1;
+   for(i = 1; i<=size(pr); i++)
+   {
+      testid = intersect(testid, pr[i][1]);
+   }
+   list M;
+   if(h!=1)
+   {
+       M=primdecZ(J,n,Y);
+       j=0;
+       //=== remove useless primary ideals
+       while(j<size(M))
+       {
+          j++;
+          M[j][1]=stdZ(M[j][1]);
+          testid = intersect(testid, M[j][1]);
+          if((reduce(testid, std(I))+0 == 0) && (reduce(I, std(testid))+0 == 0))
+          {
+            for(i=1;i<=j;i++)
+            {
+              pr[size(pr)+1]=M[i];
+            }
+            return(pr);
+          }
+          for(i=1;i<=size(pr);i++)
+          {
+             if(size(reduce(pr[i][1],M[j][1]))==0)
+             {
+                M=delete(M,j);
+                j--;
+                break;
+             }
+          }
+      }
+      for(i=1;i<=size(M);i++)
+      {
+         pr[size(pr)+1]=M[i];
+      }
+   }
+   return(pr);
+}
+example
+{ "EXAMPLE:";  echo = 2;
+   ring R=integer,(a,b,c,d),dp;
+   ideal I1=9,a,b;
+   ideal I2=3,c;
+   ideal I3=11,2a,7b;
+   ideal I4=13a2,17b4;
+   ideal I5=9c5,6d5;
+   ideal I6=17,a15,b15,c15,d15;
+   ideal I=intersectZ(I1,I2);
+   I=intersectZ(I,I3);
+   I=intersectZ(I,I4);
+   I=intersectZ(I,I5);
+   I=intersectZ(I,I6);
+   primdecZ(I);
+   ideal J=intersectZ(ideal(17,a),ideal(17,a2,b));
+   primdecZ(J);
+   ideal K=intersectZ(ideal(9,a+3),ideal(9,b+3));
+   primdecZ(K);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+proc minAssZ(ideal I)
+"USAGE:  minAssZ(I); I ideal
+RETURN:  a list pr of associated primes:
+EXAMPLE: example minAssZ; shows an example
+"
+{
+   if(size(I)==0){return(list(ideal(0)));}
+   if(deg(I[1])==0)
+   {
+      ideal J=I;
+   }
+   else
+   {
+      ideal J=stdZ(I);
+   }
+   ideal K;
+   def R=basering;
+   list rl=ringlist(R);
+   int i,j,p,m;
+   list P,B;
+   if(deg(J[1])==0)
+   {
+      //=== I intersected with Z is not zero
+      list rp=rl;
+      rp[1]=0;
+      number q=leadcoef(J[1]);
+      def Rhelp=ring(rp);
+      setring Rhelp;
+      number q=imap(R,q);
+      //=== computes the primes occuring in a generator of I intersect Z
+      //list L=PollardRho(q,5000,1);
+      list L=primefactors(q)[1];
+      for(i=1;i<=size(L);i++)
+      {
+      //=== computes for all p in L the minimal associated primes of
+      //=== IZ/p[variables]
+         p=int(L[i]);
+         setring R;
+         rp[1]=p;
+         def S=ring(rp);
+         setring S;
+         ideal J=imap(R,J);
+         list A=minAssGTZ(J);
+         setring R;
+         B=imap(S,A);
+         kill S;
+         for(j=1;j<=size(B);j++)
+         {
+            //=== the minimal associated primes of I
+            if(B[j][1]!=1)
+            {
+               K=B[j],p;
+               K=stdZ(K);
+               P[size(P)+1]=K;
+            }
+         }
+         setring Rhelp;
+      }
+      setring R;
+      return(P);
+   }
+   //==== the ideal intersected with Z is zero
+   rl[1]=0;
+   def Rhelp=ring(rl);
+   setring Rhelp;
+   ideal J=imap(R,J);
+   J=std(J);
+   //=== the primary decomposition over Q which gives the primary
+   //=== decomposition of I:h for a suitable integer h
+   list pr=minAssGTZ(J);
+   for(i=1;i<=size(pr);i++)
+   {
+      pr[i]=std(pr[i]);
+   }
+   setring R;
+   list pr=imap(Rhelp,pr);
+   //=== intersection with Z[variables]
+   for(i=1;i<=size(pr);i++)
+   {
+      pr[i]=coefZ(pr[i])[1];
+   }
+   //=== find h in Z such that I is the intersection of I:h and I,h
+   //=== and I:h =IQ[variables] intersected with Z[varables]
+   list H=coefZ(J);
+   int h=H[2];
+   J=J,h;
+   //=== call associated primes over Z for I,h
+   list M;
+   if(h!=1)
+   {
+       M=minAssZ(J);
+       //=== remove non-minimal primes
+       j=0;
+       while(j<size(M))
+       {
+          j++;
+          M[j]=stdZ(M[j]);
+          for(i=1;i<=size(pr);i++)
+          {
+             if(size(reduce(pr[i],M[j]))==0)
+             {
+                M=delete(M,j);
+                j--;
+                break;
+             }
+          }
+      }
+      for(i=1;i<=size(M);i++)
+      {
+         pr[size(pr)+1]=M[i];
+      }
+   }
+   return(pr);
+}
+example
+{ "EXAMPLE:";  echo = 2;
+   ring R=integer,(a,b,c,d),dp;
+   ideal I1=9,a,b;
+   ideal I2=3,c;
+   ideal I3=11,2a,7b;
+   ideal I4=13a2,17b4;
+   ideal I5=9c5,6d5;
+   ideal I6=17,a15,b15,c15,d15;
+   ideal I=intersectZ(I1,I2);
+   I=intersectZ(I,I3);
+   I=intersectZ(I,I4);
+   I=intersectZ(I,I5);
+   I=intersectZ(I,I6);
+   minAssZ(I);
+   ideal J=intersectZ(ideal(17,a),ideal(17,a2,b));
+   minAssZ(J);
+   ideal K=intersectZ(ideal(9,a+3),ideal(9,b+3));
+   minAssZ(K);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+proc heightZ(ideal I)
+"USAGE:  heightZ(I); I ideal
+RETURN:  the height of the input ideal
+EXAMPLE: example heightZ; shows an example
+"
+{
+   if(size(I)==0){return(0);}
+   if(deg(I[1])==0)
+   {
+      ideal J=I;
+   }
+   else
+   {
+      ideal J=stdZ(I);
+   }
+   ideal K=1;
+   def R=basering;
+   list rl=ringlist(R);
+   int i,j,p,m;
+   list P;
+   ideal B;
+   if(deg(J[1])==0)
+   {
+      //=== I intersected with Z is not zero
+      m=nvars(R);
+      list rp=rl;
+      rp[1]=0;
+      number q=leadcoef(J[1]);
+      def Rhelp=ring(rp);
+      setring Rhelp;
+      number q=imap(R,q);
+      //=== computes the primes occuring in a generator of I intersect Z
+      //list L=PollardRho(q,5000,1);
+      list L=primefactors(q)[1];
+      for(i=1;i<=size(L);i++)
+      {
+      //=== computes for all p in L the std of IZ/p[variables]
+         p=int(L[i]);
+         setring R;
+         rp[1]=p;
+         def S=ring(rp);
+         setring S;
+         ideal J=imap(R,J);
+         j=nvars(R)-dim(std(J));
+         if(j<m){m=j;}
+         setring Rhelp;
+         kill S;
+      }
+      setring R;
+      return(m+1);
+   }
+   //==== the ideal intersected with Z is zero
+   rl[1]=0;
+   def Rhelp=ring(rl);
+   setring Rhelp;
+   ideal J=imap(R,J);
+   J=std(J);
+   m=nvars(R)-dim(J);
+   //=== the height over Q
+   //=== of I:h for a suitable integer h
+   setring R;
+   //=== find h in Z such that I is the intersection of I:h and I,h
+   //=== and I:h =IQ[variables] intersected with Z[varables]
+   list H=coefZ(J);
+   int h=H[2];
+   J=J,h;
+   //=== call height over Z for I,h
+   if(h!=1)
+   {
+      j=heightZ(J);
+      if(j<m){m=j;}
+   }
+   return(m);
+}
+example
+{ "EXAMPLE:";  echo = 2;
+   ring R=integer,(a,b,c,d),dp;
+   ideal I1=9,a,b;
+   ideal I2=3,c;
+   ideal I3=11,2a,7b;
+   ideal I4=13a2,17b4;
+   ideal I5=9c5,6d5;
+   ideal I6=17,a15,b15,c15,d15;
+   ideal I=intersectZ(I1,I2);
+   I=intersectZ(I,I3);
+   I=intersectZ(I,I4);
+   I=intersectZ(I,I5);
+   I=intersectZ(I,I6);
+   heightZ(I);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+proc radicalZ(ideal I)
+"USAGE:  radicalZ(I); I ideal
+RETURN:  the radcal of the input ideal
+EXAMPLE: example radicalZ; shows an example
+"
+{
+   if(size(I)==0){return(ideal(0));}
+   if(deg(I[1])==0)
+   {
+      ideal J=I;
+   }
+   else
+   {
+      ideal J=stdZ(I);
+   }
+   ideal K=1;
+   def R=basering;
+   list rl=ringlist(R);
+   int i,j,p,m;
+   list P;
+   ideal B;
+   if(deg(J[1])==0)
+   {
+      //=== I intersected with Z is not zero
+      list rp=rl;
+      rp[1]=0;
+      number q=leadcoef(J[1]);
+      def Rhelp=ring(rp);
+      setring Rhelp;
+      number q=imap(R,q);
+      //=== computes the primes occuring in a generator of I intersect Z
+      //list L=PollardRho(q,5000,1);
+      list L=primefactors(q)[1];
+      for(i=1;i<=size(L);i++)
+      {
+      //=== computes for all p in L the radical of IZ/p[variables]
+         p=int(L[i]);
+         setring R;
+         rp[1]=p;
+         def S=ring(rp);
+         setring S;
+         ideal J=imap(R,J);
+         ideal A=radical(J);
+         setring R;
+         B=imap(S,A);
+         kill S;
+         B=B,p;
+         B=stdZ(B);
+         K=stdZ(intersectZ(K,B));
+         //K=stdZ(intersect(K,B));
+         setring Rhelp;
+      }
+      setring R;
+      return(K);
+   }
+   //==== the ideal intersected with Z is zero
+   rl[1]=0;
+   def Rhelp=ring(rl);
+   setring Rhelp;
+   ideal J=imap(R,J);
+   J=std(J);
+   //=== the radical over Q which gives the radical
+   //=== of I:h for a suitable integer h
+   ideal K=std(radical(J));
+   setring R;
+   K=imap(Rhelp,K);
+   //=== intersection with Z[variables]
+   K=coefZ(K)[1];
+   //=== find h in Z such that I is the intersection of I:h and I,h
+   //=== and I:h =IQ[variables] intersected with Z[varables]
+   list H=coefZ(J);
+   int h=H[2];
+   J=J,h;
+   //=== call radical over Z for I,h
+   if(h!=1)
+   {
+      ideal M=radicalZ(J);
+      K=intersectZ(K,M);
+      //K=intersect(K,M);
+   }
+   return(K);
+}
+example
+{ "EXAMPLE:";  echo = 2;
+   ring R=integer,(a,b,c,d),dp;
+   ideal I1=9,a,b;
+   ideal I2=3,c;
+   ideal I3=11,2a,7b;
+   ideal I4=13a2,17b4;
+   ideal I5=9c5,6d5;
+   ideal I6=17,a15,b15,c15,d15;
+   ideal I=intersectZ(I1,I2);
+   I=intersectZ(I,I3);
+   I=intersectZ(I,I4);
+   I=intersectZ(I,I5);
+   I=intersectZ(I,I6);
+   radicalZ(I);
+   ideal J=intersectZ(ideal(17,a),ideal(17,a2,b));
+   radicalZ(J);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+proc equidimZ(ideal I)
+"USAGE:  equidimZ(I); I ideal
+RETURN:  the part of minimal height
+EXAMPLE: example equidimZ; shows an example
+"
+{
+   if(size(I)==0){return(ideal(0));}
+   if(deg(I[1])==0)
+   {
+      ideal J=I;
+   }
+   else
+   {
+      ideal J=stdZ(I);
+   }
+   int he=heightZ(J);
+   ideal K,N;
+   def R=basering;
+   bigint s;
+   list rl=ringlist(R);
+   int i,j,p,m,ex;
+   list P,IS,B;
+   ideal Q,JJ,E;
+   ideal TQ=1;
+   if(deg(J[1])==0)
+   {
+      //=== I intersected with Z is not zero
+      list rp=rl;
+      rp[1]=0;
+      //=== generator of I intersect Z
+      number q=leadcoef(J[1]);
+      def Rhelp=ring(rp);
+      setring Rhelp;
+      number q=imap(R,q);
+      //=== computes the primes occuring in a generator of I intersect Z
+      //list L=PollardRho(q,5000,1);
+      list L=primefactors(q)[1];
+      list Le;
+      for(i=1;i<=size(L);i++)
+      {
+         L[i]=int(L[i]);
+         p=int(L[i]);
+         j=0;
+         s=bigint(q);
+         while((s mod p)==0)
+         {
+            j++;
+            s=s div p;
+         }
+         Le[i]=j;
+      }
+      for(i=1;i<=size(L);i++)
+      {
+      //=== computes for all p in L the minimal associated primes of
+      //=== IZ/p[variables]
+         p=int(L[i]);
+         j=Le[i];
+         setring R;
+         //=== maximal power of p dividing q, generator of I intersect Z
+         s=p^j;
+         rp[1]=p;
+         def S=ring(rp);
+         setring S;
+         ideal J=imap(R,J);
+         J=std(J);
+         if(nvars(R)-dim(J)+1==he)
+         {
+            if(j>1)
+            {
+               //=== p is of multiplicity >1 in q
+               list A=minAssGTZ(J);
+               j=0;
+               while(j<size(A))
+               {
+                  j++;
+                  if(dim(std(A[j]))!=nvars(R)-he+1)
+                  {
+                     A=delete(A,j);
+                     j--;
+                  }
+               }
+               setring R;
+               B=imap(S,A);
+               for(j=1;j<=size(B);j++)
+               {
+                  //=== the minimal associated primes of I
+                  K=B[j],p;
+                  K=stdZ(K);
+                  B[j]=K;
+               }
+               for(j=1;j<=size(B);j++)
+               {
+                  K=B[j];
+                  //=== compute maximal independent set for KZ/p[variables]
+                  setring S;
+                  J=imap(R,K);
+                  J=simplify(J,2);
+                  attrib(J,"isSB",1);
+                  IS=Primdec::maxIndependSet(J);
+                  setring R;
+                  //=== computing the pseudo primary and extract it
+                  N=J,s;
+                  N=stdZ(N);
+                  Q=extractZ(N,j,IS,B);
+                  TQ=intersectZ(TQ,Q);
+                  //TQ=intersect(TQ,Q);
+               }
+               setring Rhelp;
+            }
+            else
+            {
+               //=== p is of multiplicity 1 in q we can compute the
+               //=== equidimensional part directly
+               ideal E=equidimMax(J);
+               setring R;
+               E=imap(S,E);
+               E=E,p;
+               E=stdZ(E);
+               TQ=intersectZ(TQ,E);
+               //TQ=intersect(TQ,E);
+            }
+         }
+         kill S;
+         setring Rhelp;
+      }
+      setring R;
+      return(TQ);
+   }
+   //==== the ideal intersected with Z is zero
+   rl[1]=0;
+   def Rhelp=ring(rl);
+   setring Rhelp;
+   ideal J=imap(R,J);
+   J=std(J);
+   //=== the equidimensional part over Q which gives the equdimensional
+   //=== part of I:h for a suitable integer h
+   ideal E=1;
+   if(nvars(R)-he==dim(J))
+   {
+      E=std(equidimMax(J));
+   }
+   setring R;
+   E =imap(Rhelp,E);
+   //=== intersection with Z[variables]
+   E=coefZ(E)[1];
+   //=== find h in Z such that I is the intersection of I:h and I,h
+   //=== and I:h =IQ[variables] intersected with Z[varables]
+   int h =coefZ(J)[2];
+   J=J,h;
+   //=== call equidimensional part over Z for I,h
+   ideal M;
+   if(h!=1)
+   {
+       M=equidimZ(J);
+       if(he==heightZ(M))
+       {
+          E=intersectZ(M,E);
+          //E=intersect(M,E);
+       }
+   }
+   return(E);
+}
+example
+{ "EXAMPLE:";  echo = 2;
+   ring R=integer,(a,b,c,d),dp;
+   ideal I1=9,a,b;
+   ideal I2=3,c;
+   ideal I3=11,2a,7b;
+   ideal I4=13a2,17b4;
+   ideal I5=9c5,6d5;
+   ideal I6=17,a15,b15,c15,d15;
+   ideal I=intersectZ(I1,I2);
+   I=intersectZ(I,I3);
+   I=intersectZ(I,I4);
+   I=intersectZ(I,I5);
+   I=intersectZ(I,I6);
+   equidimZ(I);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+proc intersectZ(ideal I, ideal J)
+"USAGE:  intersectZ(I,J); I,J ideals
+RETURN:  the intersection of the input ideals
+NOTE:    this is an alternative to intersect(I,J) over integers,
+         is faster for some examples and should be kept for debug purposes.
+EXAMPLE: example intersectZ; shows an example
+{
+   def R = basering;
+   execute("ring S=integer,( X(1..nvars(R)) ), ( dp(nvars(R)) );");
+   ideal I = fetch(R,I);
+   ideal J = fetch(R,J);
+   execute("ring St=integer, ( t, X(1..nvars(R))  ), ( dp(1), dp(nvars(R)) );");
+   ideal I = imap(S,I);
+   ideal J = imap(S,J);
+   ideal K =  var(1)*I+(1-var(1))*J;
+   K = stdZ(K);
+   int i;
+   ideal L;
+   for(i=1; i<=size(K); i++)
+   {
+      if ( lead(K[i])/var(1)==0 ) { L[size(L)+1] = K[i]; }
+   }
+   setring S;
+   ideal L = imap(St, L);
+   setring R;
+   ideal L = fetch(S, L);
+   return(L);
+}
+example
+{ "EXAMPLE:";  echo = 2;
+   ring R=integer,(a,b,c,d),dp;
+   ideal I1=9,a,b;
+   ideal I2=3,c;
+   ideal I3=11,2a,7b;
+   ideal I4=13a2,17b4;
+   ideal I5=9c5,6d5;
+   ideal I6=17,a15,b15,c15,d15;
+   ideal I=intersectZ(I1,I2); I;
+   I=intersectZ(I,I3); I;
+   I=intersectZ(I,I4); I;
+   I=intersectZ(I,I5); I;
+   I=intersectZ(I,I6); I;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+static proc modp(ideal J, int p, int nu)
+{
+//=== computes the minimal associated primes (if nu > 1) resp. the primary
+//=== decomposition (else) of J in Z/p and maps the result back to the basering
+   def R = basering;
+   list rp = ringlist(R);
+   rp[1] = p;
+   def Rp = ring(rp);
+   setring Rp;
+   ideal J = imap(R,J);
+   int sizeA;
+   if(nu > 1)
+   {
+      //=== p is of multiplicity > 1 in q
+      list A = minAssGTZ(J);
+   }
+   else
+   {
+      list A = primdecGTZ(J);
+   }
+   sizeA = size(A);
+   setring R;
+   list A;
+   if (sizeA>0)   {  A = imap(Rp,A);    }
+   return(list(A,p,nu));
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+static proc coefPrimeZ(ideal I)
+{
+//=== computes the primes occuring in the product of the leading coefficients
+//=== of I
+   number h=1;
+   int i;
+   I = simplify(I,2); // del zero generators
+   for(i=1;i<=size(I);i++)
+   {
+      h=h*leadcoef(I[i]);  // besser machen (gleich zerlegen,
+                           // nicht ausmultiplizieren)
+   }
+   def R=basering;
+   ring Rhelp=0,x,dp;
+   number h=imap(R,h);
+   //list L=PollardRho(h,5000,1);
+   list L=primefactors(h)[1];
+   for(i=1;i<=size(L);i++){L[i]=int(L[i]);}
+   setring R;
+   return(L);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+static proc coefZ(ideal I)
+{
+//=== assume IQ[variables]=<g_1,...,g_s>, Groebner basis, g_i in Z[variables]
+//=== computes an integer h such that
+//===   <g_1,...,g_s>Z[variables]:h^infinity = IQ[variables] intersected
+//===                                          with Z[variables]
+//=== returns a list with IQ[variables] intersected with Z[variables] and h
+   int h=1;
+   int i,e;
+   ideal K=1;
+   attrib(I,"isSB",1);
+   list L=coefPrimeZ(I);
+   if(size(L)==0){return(list(I,1));}
+   int d=1;
+   while(d!=0)
+   {
+      i++;
+      K=quotientOneZ(I,L[i]);
+      if(size(reduce(K,I))!=0)
+      {
+         h=h*L[i];
+         I=stdZ(K);
+         e=1;
+      }
+      if(i==size(L))
+      {
+         i=0;
+         if(e)
+         {
+            e=0;
+         }
+         else
+         {
+           d=0;
+         }
+      }
+   }
+   if(h<0){h=-h;}
+   return(list(K,h));
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+static proc specialPowerZ(ideal I, int m)
+{
+//=== computes the ideal generated by the m-th power of the generators of I
+   int i;
+   for(i=1;i<=ncols(I);i++)  // use ncols to allow zero generators in I
+   {
+      I[i]=I[i]^m;
+   }
+   return(I);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+static proc separatorsZ(int j, list B)
+{
+//=== computes s such that s is not in B[j] but s is in B[i] for all i!=j
+   int i,k;
+   poly s=1;
+   for(i=1;i<=size(B);i++)
+   {
+      if(i!=j)
+      {
+         for(k=1;k<=size(B[i]);k++)
+         {
+            if(reduce(B[i][k],B[j])!=0)
+            {
+               s=s*B[i][k];
+               break;
+            }
+         }
+      }
+   }
+   return(s);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+static proc extractZ(ideal J, int j, list L, list B)
+{
+   //=== P is an associated prime of J, the corresponding primary ideal is
+   //=== computed,
+   //=== L is a list of maximal independent sets for P in Z/p[variables]
+   def R=basering;
+   ideal P=B[j];
+
+   //=== first compute a pseudo primary ideal I, radical of I is P
+   //=== method of Eisenbud
+   //ideal I=J+specialPowerZ(P,20);
+
+   //=== method of Shimoyama-Yokoyama
+   poly s=separatorsZ(j,B);
+   ideal I=satZ(J,s);
+   //=== size(L)=0 means P is maximal ideal and I is primary
+   if(size(L)>0)
+   {
+      if(L[1][3]!=0)
+      {
+         //=== if u in x is an independent set of L then we compute a Groebner
+         //=== Basis in Z[u][x-u]
+         execute("ring S=integer,("+L[1][1]+"),lp;");
+         ideal I=imap(R,I);
+         I=stdZ(I);
+         list rl=ringlist(S);
+         rl[1]=0;
+         def Shelp =ring(rl);
+         setring Shelp;
+         ideal I=imap(S,I);
+         I[1]=0;
+         I=simplify(I,2);
+         if(L[1][3]==nvars(basering))
+         {
+            list C;
+            C[1]= ideal(0); //add dummy entry to tie C to current ring
+            int i;
+            ASSUME(1, size(I)==ncols(I) || size(I)==0);
+            for(i=1;i<=size(I);i++)
+            {
+               C[i+1]=I[i];
+            }
+         }
+         else
+         {
+            //=== this is our way to obtain the coefficients in Z[u] of the
+            //=== leading terms of the Groebner basis above
+            def quring=Primdec::prepareQuotientring(nvars(basering)-L[1][3],"lp");
+	    setring quring;
+            ideal I=imap(Shelp,I);
+            list C;
+            C[1]= ideal(0); //add dummy entry to tie C to current ring
+            int i;
+            ASSUME(1, size(I)==ncols(I) || size(I)==0);
+            for(i=1;i<=size(I);i++)
+            {
+               C[i+1]=leadcoef(I[i]);
+            }
+            setring Shelp;
+            list C=imap(quring,C);
+         }
+         setring R;
+         list C=imap(Shelp,C);
+      }
+      else
+      {
+         I=stdZ(I);
+         list C;
+         C[1]= ideal(0); //add dummy entry to tie C to current ring
+         int i;
+         ASSUME(1, size(I)==ncols(I) || size(I)==0);
+         for(i=1;i<=size(I);i++)
+         {
+            C[i+1]=I[i];
+         }
+         list rl=ringlist(R);
+         rl[1]=0;
+         def Shelp =ring(rl);
+      }
+      poly h=1;
+      for(i=2;i<=size(C);i++) // leave out first dummy entry in C.
+      {
+         if(deg(C[i])>0){h=h*C[i];}  // das muss noch besser gemacht werden,
+                                     // nicht ausmultiplizieren!
+      }
+      setring Shelp;
+      poly h=imap(R,h);
+      ideal fac=factorize(h,1);
+      setring R;
+      ideal fac=imap(Shelp,fac);
+      ASSUME(1, size(fac)==ncols(fac) || size(fac)==0);
+      for(i=1;i<=size(fac);i++)
+      {
+         I=satZ(I,fac[i]);
+      }
+   }
+   I=stdZ(I);
+   return(I);
+}
+////////////////////////////////////////////////////////////////////////////////
+
+static proc normalizeZ(ideal I)
+{
+//=== if I[1]=q in Z, it replaces all other coeffs of polys in I by there value
+//=== mod q, std should do this automatically and then this procedure should be
+//=== removed
+   if(deg(I[1])>0){return(I);}
+   int i,j;
+   number n;
+   poly p;
+   for(i=2;i<=ncols(I);i++)
+   {
+      j=1;
+      while(j<=size(I[i]))
+      {
+         n=leadcoef(I[i][j]) mod leadcoef(I[1]);
+         p=n*leadmonom(I[i][j]);
+         I[i]=I[i]-I[i][j]+p;
+         if(p!=0){j++;}
+      }
+   }
+   return(I);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+static proc satZ(ideal I,poly h)
+{
+//=== saturates I by h
+   ideal J=quotientOneZ(I,h);
+   while(size(reduce(J,stdZ(I)))!=0)
+   {
+      I=J;
+      J=quotientOneZ(I,h);
+      J=normalizeZ(J);
+   }
+   return(J);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+static proc quotientOneZ(ideal I, poly f)
+{
+//=== this is needed because quotient(I,f) does not work properly, should be
+//=== replaced by quotient later
+   if ( f==0 ) { return( ideal(1) ); }
+   def R=basering;
+   int i;
+   ideal K=intersectZ(I,ideal(f));
+   //ideal K=intersect(I,ideal(f));
+   //=== K[i]/f; does not work in rings with integer! This should be replaced
+   //=== later
+   execute("ring Rhelp=0,("+varstr(R)+"),dp;");
+   ideal K=imap(R,K);
+   poly f=imap(R,f);
+   ASSUME(1, ncols(K)==size(K) || size(K)==0 ); // postcondition intersectZ
+   for(i=1;i<=ncols(K);i++)
+   {
+      K[i]=K[i]/f;
+   }
+   setring R;
+   K=imap(Rhelp,K);
+   return(K);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+static proc quotientZ(ideal I, ideal J)
+{
+//=== this is needed because quotient(I,J) does not work properly, should be
+//=== replaced by quotient later
+   if ( size(J)==0 ) { return( ideal(1) ); }
+   J = simplify(J, 2); // del zero generators
+   int i;
+   ideal K=quotientOneZ(I,J[1]);
+   // we had a bug here: either it is mandatory to kick out zero generators  of J(done) or to use ncols(J)
+   for(i=2;i<=ncols(J);i++)
+   {
+      K=intersectZ(K,quotientOneZ(I,J[i]));
+      //K=intersect(K,quotientOneZ(I,J[i]));
+   }
+   return(K);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+static proc reduceZ(poly f, ideal I)
+{
+//=== this is needed because reduce(f,I) does not work properly, should be
+//=== replaced by reduce later
+   if(f==0){return(f);}
+   if (not attrib(I,"isSB") ) { print ("// ** I is no standard basis"); }
+   def R=basering;
+   execute("ring Rhelp=0,("+varstr(R)+"),dp;");
+   ideal I=imap(R,I);
+   poly f=imap(R,f);
+   int i,j;
+   poly m;
+   number n;
+   I = simplify(I, 2); // del zero gens (otherwise the following loop may fail with an error (div by 0))
+   while(!i)
+   {
+      i=1;
+      j=0;
+      while(j<size(I))
+      {
+         j++;
+         m=leadmonom(f)/leadmonom(I[j]);
+         if(m!=0)
+         {
+            n=leadcoef(f) mod leadcoef(I[j]);
+            if(n==0)
+            {
+               f=f-leadcoef(f)/leadcoef(I[j])*m*I[j];
+               if(f==0){setring R;return(poly(0));}
+               i=0;
+               break;
+            }
+            if(n!=leadcoef(f))
+            {
+               f=f+(n-leadcoef(f))/leadcoef(I[j])*m*I[j];
+               i=0;
+               break;
+            }
+         }
+      }
+   }
+   setring R;
+   f=imap(Rhelp,f);
+   return(lead(f)+reduceZ(f-lead(f),I));
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+static proc stdZ(ideal I)
+{
+//=== this is needed because we want the leading coefficients to be positive
+//=== otherwhise reduce gives wrong results! should be replaced later by std
+   I=simplify(I,2);
+   I=normalizeZ(I);  // why is this done before std() call?
+                     // normalizeZ works only if I[1] == ( std(I) )[1]
+   ideal J=std(I);
+   int i;
+   for(i=1;i<=size(J);i++)
+   {
+      if(leadcoef(J[i])<0){J[i]=-J[i];}
+   }
+   J=normalizeZ(J);
+   attrib(J,"isSB",1);
+   return(J);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+static proc testPrimaryZ(ideal I, list L)
+{
+//=== test whether I is the intersection of the primary ideals in L
+   int i;
+   ideal K=L[1][1];
+   for(i=2;i<=size(L);i++)
+   {
+      K=intersectZ(K,L[i][1]);
+      //K=intersect(K,L[i][1]);
+   }
+   i=size(reduce(K,stdZ(I)))+size(reduce(I,stdZ(K)));
+   if(!i){return(1);}
+   return(0);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+static proc pseudo_primdecZM(module N)
+{
+   ideal I=quotient(N,freemodule(nrows(N)));
+   if(size(I)==0){return(list(list(N,I)));}
+
+   list B=minAssZ(I);
+   list S,R,L;
+   ideal K;
+   if(size(B)==0){return(S);}
+   for(int i=1;i<=size(B);i++)
+   {
+      S[i]=separatorsZ(i,B);
+   }
+   for(i=1;i<=size(B);i++)
+   {
+      L=sat(N,S[i]);
+      K[i]=S[i]^L[2];
+      R[i]=list(L[1],B[i]);
+   }
+   L=pseudo_primdecZM(N+K*freemodule(nrows(N)));
+   for(i=1;i<=size(L);i++)
+   {
+      R[size(R)+1]=L[i];
+   }
+   return(R);
+}
+
+
+
+static proc prepare_extractZM(list L)
+{
+   def R=basering;
+   module N=L[1];
+   ideal I=quotient(N,freemodule(nrows(N)));
+   list B=primdecZ(I);
+   list M;
+   if(size(B)==1){return(M);}
+   I=std(I);
+   list rl=ringlist(R);
+   if(deg(I[1])==0)
+   {
+      execute("int p="+string(I[1])+";");
+      rl[1]=p;
+   }
+   else
+   {
+      rl[1]=0;
+   }
+   def Shelp =ring(rl);
+   setring Shelp;
+   ideal I=imap(R,I);
+   I=std(I);
+   M=Primdec::maxIndependSet(I);
+   setring R;
+   return(M);
+}
+
+
+static proc extractZM(list M, list L)
+{
+   //=== M is a list of a pseudo primary module and the corresponding prime
+   //=== L is a list of maximal independent sets for P
+   def R=basering;
+   ideal P=M[2];
+   module I=M[1];
+   poly h=1;
+
+   //=== size(L)=0 means P is maximal ideal and I is primary
+   if(size(L)>0)
+   {
+      if(L[1][3]!=0)
+      {
+         //=== if u in x is an independent set of L then we compute a Groebner
+         //=== Basis in Z[u][x-u]
+         execute("ring S=integer,("+L[1][1]+"),lp;");
+         module I=imap(R,I);
+         I=std(I);
+         list rl=ringlist(S);
+         rl[1]=0;
+         def Shelp =ring(rl);
+         setring Shelp;
+         module I=imap(S,I);
+         //=== this is our way to obtain the coefficients in Z[u] of the
+         //=== leading terms of the Groebner basis above
+         def quring=Primdec::prepareQuotientring(nvars(basering)-L[1][3],"lp");
+         setring quring;
+         module I=imap(Shelp,I);
+         list C;
+         int i;
+         for(i=1;i<=size(I);i++)
+         {
+            C[i]=leadcoef(I[i]);
+         }
+         setring Shelp;
+         list C=imap(quring,C);
+         setring R;
+         list C=imap(Shelp,C);
+      }
+      else
+      {
+         // this is the case that P=<p>, p prime
+         I=std(I);
+         ideal IC=simplify(flatten(lead(I)),2);
+         list C;
+         int i;
+         for(i=1;i<=size(IC);i++)
+         {
+            C[i]=I[i];
+         }
+         list rl=ringlist(R);
+         rl[1]=0;
+         def Shelp =ring(rl);
+      }
+      for(i=1;i<=size(C);i++)
+      {
+         if(deg(C[i])>0){h=h*C[i];}  // das muss noch besser gemacht werden,
+                                     // nicht ausmultiplizieren!
+      }
+      setring Shelp;
+      poly h=imap(R,h);
+      ideal fac=factorize(h,1);
+      setring R;
+      list II;
+      h=1;
+      ideal fac=imap(Shelp,fac);
+      ASSUME(1, size(fac)==ncols(fac) || size(fac)==0);
+      for(i=1;i<=size(fac);i++)
+      {
+         II=sat(I,fac[i]);
+          I=II[1];
+          h=h*fac[i]^II[2];
+      }
+   }
+   I=std(I);
+   return(list(I,h));
+}
+
+
+proc primdecZM(module N)
+"USAGE:  primdecZM(N); N module
+RETURN:  a list pr of primary modules and their associated primes:
+ at format
+   pr[i][1]   the i-th primary component,
+   pr[i][2]   the i-th prime component.
+ at end format
+EXAMPLE: example primdecZM; shows an example
+"
+{
+  list P,K,S;
+  int i,j;
+  list L=pseudo_primdecZM(N);
+  list M,O;
+  for(i=1;i<=size(L);i++)
+  {
+     if(size(L[i][2])!=0)
+     {
+        M=prepare_extractZM(L[i]);
+        O=extractZM(L[i],M);
+        P[size(P)+1]=list(O[1],L[i][2]);
+        K[size(K)+1]=L[i][1]+O[2]*freemodule(nrows(L[i][1]));
+     }
+     else
+     {
+        P[size(P)+1]=L[i];
+     }
+  }
+  for(j=1;j<=size(K);j++)
+  {
+     S=primdecZM(K[j]);
+     for(i=1;i<=size(S);i++)
+     {
+        P[size(P)+1]=S[i];
+     }
+  }
+  return(P);
+}
+example
+{ "EXAMPLE:";  echo = 2;
+   ring R=integer,(x,y),(c,lp);
+   module N=[0,0,xy2-x2-xy],[0,y,x],[0,x,2xy-x],[x,0,-xy],[0,0,18x];
+   primdecZM(N);
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+
+/*
+Examples:
+
+//=== IQ[a,b,c,d,e,f,g] intersect Z[a,b,c,d,e,f,g] = I  (takes some time)
+ring R1=integer,(a,b,c,d,e,f,g),dp;
+ideal I=a2+2de+2cf+2bg+a,
+        2ab+e2+2df+2cg+b,
+        b2+2ac+2ef+2dg+c,
+        2bc+2ad+f2+2eg+d,
+        c2+2bd+2ae+2fg+e,
+        2cd+2be+2af+g2+f,
+        d2+2ce+2bf+2ag+g;
+
+ring R2=integer,(a,b,c,d,e,f,g),dp;
+ideal I=181*32003,
+        a2+2de+2cf+2bg+a,
+        2ab+e2+2df+2cg+b,
+        b2+2ac+2ef+2dg+c,
+        2bc+2ad+f2+2eg+d,
+        c2+2bd+2ae+2fg+e,
+        2cd+2be+2af+g2+f,
+        d2+2ce+2bf+2ag+g;
+
+ring R3=integer,(w,z,y,x),dp;
+ideal I=xzw+(-y^2+y)*z^2,
+        (-x^2+x)*w^2+yzw,
+        ((y^4-2*y^3+y^2)*x-y^4+y^3)*z^3,
+        y2z2w+(-y*4+2*y^3-y^2)*z3;
+
+ring R4=integer,(w,z,y,x),dp;
+ideal I=-2*yxzw+(-yx-y^2+y)*z^2,
+        xw^2-yz^2,
+        (yx^2-(2*y^2+2*y)*x+y^3-2*y^2+y)*z^3,
+        (-2*y^2+2*y)*z^2*w+(yx-3*y^2-y)*z^3;
+
+ring R5=integer,(x,y,z),dp;
+ideal I=x2-y2-z2,
+        xy-z2,
+        y3+xz2-yz2+2z3+xy-z2,
+        -y2z2+2z4+x2-y2+z2,
+        y3z9+3y2z10+3yz11+z12-y2z2+2z4;
+
+ring R6=integer,(h, l, s, x, y, z),dp;  //takes some time
+ideal I=hl-l2-4ls+hy,
+        h2s-6ls3+h2z,
+        xh2-l2s-h3;
+
+ring R7=integer,(x,y,z),dp;
+ideal I=x2-y2-(z+2)^2,
+        xy-(z+2)^2,
+        y3+x*(z+2)^2-y*(z+2)^2+2*(z+2)^3+xy-(z+2)^2,
+        -y^2*(z+2)^2+2*(z+2)^4+x2-y2+(z+2)^2,
+        y3z9+3y2z10+3yz11+z12-y2z2+2z4;
+
+ring R8=integer,(x,y,z),dp;
+ideal I=x2-y2-(z+2)^2,
+        xy-(z+2)^2,
+        y3+x*(z+2)^2-y*(z+2)^2+2*(z+2)^3+xy-(z+2)^2,
+        -y^2*(z+2)^2+2*(z+2)^4+x2-y2+(z+2)^2,
+        y3z9+3y2z10+3yz11+z12-y2z2+2z4;
+
+ring R9=integer,(w,z,y,x),dp;
+ideal I=630,
+        ((y^2-y)*x-y^3+y^2)*z^2,
+        (x-y)*zw,
+        (x-y^2)*zw+(-y^2+y)*z^2,
+        (-x^2+x)*w^2+(-yx+y)*zw;
+
+ring R10=integer,(w,z,y,x),dp;
+ideal I=1260,
+        -yxzw+(-y^2+y)*z^2,
+        (-x^2+x)*w^2-yxzw,
+        ((-y^2+y)*x-y^3+2*y^2-y)*z^3,
+        (y^2-y)*z^2*w+(-y^2+y)*z^2*w+(-y^2+y)*z^3;
+
+ring R11=integer,(w,z,y,x),dp;
+ideal I=(4*y^2*x^2+(4*y^3+4*y^2-y)*x-y^2-y)*z^2,
+        (x+y+1)*zw+(-4*y^2*x-4*y^3-4*y^2)*z^2,
+        (-x-2*y^2 - 2*y - 1)*zw + (8*y^3*x + 8*y^4 + 8*y^3 + 2*y^2+y)*z^2,
+        ((y^3 + y^2)*x - y^2 - y)*z^2,
+        (y +1)*zw + (-y^3 -y^2)*z^2,
+        (x + 1)*zw +(- y^2 -y)*z^2,
+        (x^2 +x)*w^2 + (-yx - y)*zw;
+
+ring R12=integer,(w,z,y,x),dp;
+ideal I=72,
+        ((y^3 + y^2)*x - y^2 - y)*z^2,
+        (y + 1)*zw + (-y^3 -y^2)*z^2,
+        (x + 1)*zw + (-y^2 -y)*z^2, (x^2 + x)*w^2 + (-yx - y)*zw;
+
+ring R13=integer,(w,z,y,x),dp;
+ideal I=(((12*y+8)*x^2 +(2*y+2)*x)*zw +((-15*y^2 -4*y)*x-4*y^2 -y)*z^2,
+        -x*w^2 +((-12*y -8)*x+2*y)*zw +(15*y^2+4*y)*z^2,
+        (81*y^4*x^2 +(-54*y^3 -12*y^2)*x-12*y^3 -3*y^2)*z^3,
+        (-24*yx+6*y^2-6*y)*z^2*w + (-81*y^4*x + 81*y^3 + 24*y^2)*z^3,
+        (48*x^2 + (-30*y + 12)*x - 6*y)*z^2*w + ((81*y^3 -54*y^2 -24*y)*x
+        -21*y^2 -6*y)*z^3,
+        (-96*yx-18*y^3 +18*y^2-24*y)*z^2*w +(243*y^5*x-243*y^4 +72*y^3
+        +48*y^2)*z^3,
+        6*y*z^2*w^2 +((576*y+384)*x^2 + (-81*y^3 -306*y^2 -168*y+96)*x+81*y^2
+        -18*y)*z^3*w +((-720*y^2 - 192*y)*x + 450*y^3 - 60*y^2 - 48*y)*z^4);
+
+ring R14=integer,(x(1),x(2),x(3),x(4)),dp;
+ideal I=181*49^2,
+        x(4)^4,
+        x(1)*x(4)^3,
+        x(1)*x(2)*x(4)^2,
+        x(2)^2*x(4)^2,
+        x(2)^2*x(3)*x(4),
+        x(1)*x(2)*x(3)*x(4),
+        x(1)*x(3)^2*x(4),
+        x(3)^3*x(4);
+
+
+ring R15=integer,(x,y,z),dp;
+ideal I=32003*181*64,
+        ((z^2-z)*y^2 + (z^2 -z)*y)*x; (z*y^3 + z*y^2)*x,
+        (y^4 - y^2)*x, (z^2 - z)*y*x^2, (y^3 - y^2)*x^2,
+        (z^3 - z^2)*x^4 + (2*z^3 -2*z^2)*x^3 + (z^3 -z^2)*x^2,
+        z*y^2*x^2, z*y*x^4 +z*y*x^3,
+        2*y^2*x^4 +6*y^2*x^3 +6*y^2*x^2 + (y^3 +y^2)*x, z*x^5 + (z^2 +z)*x^4
+        + (2*z^2 -z)*x^3 + (z^2 -z)*x^2,
+        y*x^6 + 3*y*x^5 + 3*y*x^4 + y*x^3;
+
+
+ring R16=integer,(x(1),x(2),x(3),x(4),x(5)),dp;
+ideal I=x(5)^5,
+        x(1)*x(5)^4,
+        x(1)*x(2)*x(5)^3,
+        x(2)^2*x(5)^3,
+        x(2)^2*x(3)*x(5)^2,
+        x(1)*x(2)*x(3)*x(5)^2,
+        x(1)*x(3)^2*x(5)^2,
+        x(3)^3*x(5)^2,
+        x(3)^3*x(4)*x(5),
+        x(1)*x(3)^2*x(4)*x(5),
+        x(1)*x(2)*x(3)*x(4)*x(5),
+        x(2)^2*x(3)*x(4)*x(5),
+        x(2)^2*x(4)^2*x(5),
+        x(1)*x(2)*x(4)^2*x(5),
+        x(1)*x(4)^3*x(5),
+        x(4)^4*x(5);
+      I=intersectZ(I,ideal(64*181,x(1)^2));
+
+ring R17=integer,(x,y,z),dp;
+ideal I=374,
+        (z+2)^8-140z6+2622*(z+2)^4-1820*(z+2)^2+169,
+        17y*(z+2)^4-374*y*(z+2)^2+221y+2z7-281z5+5240z3-3081z,
+        204y2+136yz3-3128yz+z6-149z4+2739z2+117,
+        17xz4-374xz2+221x+2z7-281z5+5240z3-3081z,
+        136xy-136xz-136yz+2z6-281z4+5376z2-3081,
+        204x2+136xz3-3128xz+z6-149z4+2739z2+117;
+
+ring R18=integer,(B,D,F,b,d,f),dp;
+ideal I=6,
+        (b-d)*(B-D)-2*F+2,
+        (b-d)*(B+D-2*F)+2*(B-D),
+        (b-d)^2-2*(b+d)+f+1,
+        B^2*b^3-1,
+        D^2*d^3-1,
+        F^2*f^3-1;
+
+ring R19=integer,(a,b,c,d,e,f),dp;
+ideal I=24,
+        2*(f+2)*b+2ec+d2+a2+a,
+        2*(f+2)*c+2ed+2ba+b,
+        2*(f+2)*d+e2+2ca+c+b2,
+        2*(f+2)*e+2da+d+2cb,
+        (f+2)^2+2ea+e+2db+c2,
+        2*(f+2)*a+f+2eb+2dc;
+
+ring R20=integer,(x,y,z,w,u),dp;
+ideal I=24,
+         2x2-2y2+2z2-2w2+2u2-1,
+         2x3-2y3+2z3-2w3+2u3-1,
+         2x4-2y4+2z4-2w4+2u4-1,
+         2x5-2y5+2z5-2w5+2u5-1,
+         2x6-2y6+2z6-2w6+2u6-1;
+
+ring R21=integer,(x,y,z,t,u,v,h),dp;
+ideal I=66,
+        2x2+2y2+2z2+2t2+2u2+v2-vh,
+        xy+yz+2zt+2tu+2uv-uh,
+        2xz+2yt+2zu+u2+2tv-th,
+        2xt+2yu+2tu+2zv-zh,
+        t2+2xv+2yv+2zv-yh,
+        2x+2y+2z+2t+2u+v-h,
+        x3+y3+z3+t3+u3+v3;
+
+ring R22=integer,(s,p,S,P,T,F,f),dp;
+ideal I=35,
+        2*T-S*s-2*F+2,
+        8*F*p-4*p*S-2*F*s^2+S*s^2+4*T-2*S*s,
+        -2*s-4*p+s^2+f+1,
+        s*T^2-p*s*P-p*S*T-2,
+        p^3*P^2-1,
+        F^2*f^3-1;
+
+ring R=integer,(x,y),(c,lp);
+module N=[0,0,xy2-x2-xy],[0,y,x],[0,x,2xy-x],[x,0,-xy],[0,0,18x];
+
+ring R=integer,(x,y),(c,lp);
+module N=[0,0,xy2-x2-xy],[0,y,x],[0,x,2xy-x],[x,0,-xy],[0,0,18];
+
+ring R=integer,(x,y),(c,lp);
+module N=[-y,7,0],[2y3-y2],[3x,y2],[2y-y2,x],[4,5x3];
+
+ring r=integer,(x,y),(c,lp);
+module N=[0,0,xy2-x2-xy],[0,y,x],[0,x,xy-x],[x,0,-xy],[5x,0,0];
+
+ring R2=integer,(a(1),a(2),a(3),b(1),b(2),b(3)),(c,lp);
+module N=[a(1)*b(1),a(2)*b(1),a(3)*b(1)],[a(1)*b(2),a(2)*b(2),a(3)*b(2)],[a(1)*b(3),a(2)*b(3),a(3)*b(3)];
+
+ring R3=integer,(x,y,z),(c,lp);
+module N=[y2+z2,xy,xz],[xy,x2+z2,yz],[xz,yz,x2+y2];
+
+ring R4=integer,(x,y,z,a,b,c),(c,lp);
+module N=[x3y2z2c,x2y3z2c,x2y2z3c],[x3y2z2b,x2y3z2b,x2y2z3b],[x3y2z2a,x2y3z2a,x2y2z3a];
+
+*/
diff --git a/Singular/LIB/primitiv.lib b/Singular/LIB/primitiv.lib
new file mode 100644
index 0000000..6f059d0
--- /dev/null
+++ b/Singular/LIB/primitiv.lib
@@ -0,0 +1,402 @@
+///////////////////////////////////////////////////////////////////////////////
+version="version primitiv.lib 4.0.0.0 Jun_2013 "; // $Id: e55b398883c429e476b0c6a8e56119ffb792643a $
+category="Commutative Algebra";
+info="
+LIBRARY:    primitiv.lib    Computing a Primitive Element
+AUTHOR:     Martin Lamm,    email: lamm at mathematik.uni-kl.de
+
+PROCEDURES:
+ primitive(ideal i);   find minimal polynomial for a primitive element
+ primitive_extra(i);   find primitive element for two generators
+ splitring(f,R[,L]);   define ring extension with name R and switch to it
+";
+
+LIB "random.lib";
+///////////////////////////////////////////////////////////////////////////////
+
+proc primitive(ideal i)
+"USAGE:   primitive(i); i ideal
+ASSUME:   i is given by generators m[1],...,m[n] such that for j=1,...,n @*
+          -  m[j] is a polynomial in k[x(1),...,x(j)] @*
+          -  m[j](a[1],...,a[j-1],x(j)) is the minimal polynomial for a[j] over
+             k(a[1],...,a[j-1]) @*
+          (k the ground field of the current basering and x(1),...,x(n)
+          the ring variables).
+RETURN:   ideal j in k[x(n)] with
+          - j[1] a minimal polynomial for a primitive element b of
+                 k(a[1],...,a[n]) over k,
+          - j[2],...,j[n+1] polynomials in k[x(n)] such that j[i+1](b)=a[i]
+                 for i=1,...,n.
+NOTE:     the number of variables in the basering has to be exactly n,
+          the number of given generators (i.e., minimal polynomials).@*
+          If the ground field k has only a few elements it may happen that no
+          linear combination of a[1],...,a[n] is a primitive element. In this
+          case @code{primitive(i)} returns the zero ideal, and one should use
+          @code{primitive_extra(i)} instead.
+SEE ALSO: primitive_extra
+KEYWORDS: primitive element
+EXAMPLE:  example primitive;  shows an example
+"
+{
+ def altring=basering;
+ execute("ring deglexring=("+charstr(altring)+"),("+varstr(altring)+"),dp;");
+ ideal j;
+ execute("ring lexring=("+charstr(altring)+"),("+varstr(altring)+"),lp;");
+ ideal i=fetch(altring,i);
+
+ int k,schlecht,Fehlversuche,maxtry;
+ int nva = nvars(basering);
+ int p=char(basering);
+ if (p==0) {
+   p=100000;
+   if (nva<3) { maxtry= 100000000; }
+   else       { maxtry=2147483647; }
+ }
+ else {
+   if ((nva<4) || (p<60)) {
+     maxtry=p^(nva-1); }
+   else {
+     maxtry=2147483647;          // int overflow(^)  vermeiden
+   }
+ }
+ ideal jmap,j;
+ map phi;
+ option(redSB);
+
+ //-------- Mache so lange Random-Koord.wechsel, bis letztes Polynom -------------
+ //--------------- das Minpoly eines primitiven Elements ist : ----------------
+ for (Fehlversuche=0; Fehlversuche<maxtry; Fehlversuche++) {
+   schlecht=0;
+   if ((p<60) && (nva==2)) {  // systematische Suche statt random
+      jmap=ideal(var(1),var(2)+Fehlversuche*var(1));
+   }
+   else {
+    if (Fehlversuche==0) { jmap=maxideal(1);}
+    else {
+      if (Fehlversuche<5) { jmap=randomLast(10);}
+      else {
+       if (Fehlversuche<20) { jmap=randomLast(100);}
+       else                 { jmap=randomLast(100000000);}
+    }}                        // groessere Werte machen keinen Sinn
+   }
+   phi=lexring,jmap;
+   j=phi(i);
+   setring deglexring;
+ //--------------- Berechne reduzierte Standardbasis mit fglm: ----------------
+   j=std(fetch(lexring,j));
+   setring lexring;
+   j=fglm(deglexring,j);
+ //-- teste, ob SB n Elemente enthaelt (falls ja, ob lead(Fi)=xi i=1... n-1): -
+   if (size(j)==nva) {
+     for (k=1; k<nva; k++) {
+       j[k+1]=j[k+1]/leadcoef(j[k+1]);        // normiere die Erzeuger
+       if (lead(j[k+1]) != var(nva-k)) { schlecht=1;}
+     }
+     if (schlecht==0) {
+ //--- Random-Koord.wechsel war gut: Berechne das zurueckzugebende Ideal: -----
+       ideal erg;
+       for (k=1; k<nva; k++) { erg[k]=var(k)-j[nva-k+1]; }
+                               // =g_k(x_n) mit a_k=g_k(a_n)
+       erg[nva]=var(nva);
+       map chi=lexring,erg;
+       ideal extra=maxideal(1);extra=phi(extra);
+                               // sonst: "argument of a map must have a name"
+       erg=j[1],chi(extra);    // j[1] = Minimalpolynom
+       setring altring;
+       return(fetch(lexring,erg));
+     }
+   }
+   dbprint("The random coordinate change was bad!");
+ }
+ if (voice==2) {
+   "// ** Warning: No primitive element could be found.";
+   "//    If the given ideal really describes the minimal polynomials of";
+   "//    a series of algebraic elements (cf. `help primitive;') then";
+   "//    try `primitive_extra'.";
+ }
+ setring altring;
+ return(ideal(0));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+ ring exring=0,(x,y),dp;
+ ideal i=x2+1,y2-x;                  // compute Q(i,i^(1/2))=:L
+ ideal j=primitive(i);
+ j[1];                               // L=Q(a) with a=(-1)^(1/4)
+ j[2];                               // i=a^2
+ j[3];                               // i^(1/2)=a
+ // the 2nd element was already primitive!
+ j=primitive(ideal(x2-2,y2-3));      // compute Q(sqrt(2),sqrt(3))
+ j[1];
+ j[2];
+ j[3];
+ // no element was primitive -- the calculation of primitive elements
+ // is based on a random choice.
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc primitive_extra(ideal i)
+"USAGE:   primitive_extra(i); i ideal
+ASSUME:  The ground field of the basering is k=Q or k=Z/pZ and the ideal
+         i is given by 2 generators f,g with the following properties:
+ at format
+   f is the minimal polynomial of a in k[x],
+   g is a polynomial in k[x,y] s.th. g(a,y) is the minpoly of b in k(a)[y].
+ at end format
+          Here, x is the name of the first ring variable, y the name of the
+          second.
+RETURN:  ideal j in k[y] such that
+ at format
+   j[1] is the minimal polynomial for a primitive element c of k(a,b) over k,
+   j[2] is a polynomial s.th. j[2](c)=a.
+ at end format
+NOTE:    While @code{primitive(i)} may fail for finite fields,
+         @code{primitive_extra(i)} tries all elements of k(a,b) and, hence,
+         always finds a primitive element. @*
+         In order to do this (try all elements), field extensions like Z/pZ(a)
+         are not allowed for the ground field k. @*
+         @code{primitive_extra(i)} assumes that the second generator, g, is
+         monic as polynomial in (k[x])[y].
+EXAMPLE: example primitive_extra;  shows an example
+"
+{
+ def altring=basering;
+ int grad1=deg(i[1]);
+ int grad2=deg(jet(i[2],0,intvec(1,0)));
+ if (grad2==0) { ERROR("i[2] is not monic"); }
+ int countx,countz;
+  if (size(variables(i[1]))!=1) { ERROR("i[1] must be poly in x"); }
+  if (size(variables(i[2]))>2) { ERROR("i[2] must be poly in x,a"); }
+  //if (variables(i[2])[2]!=a) { ERROR("i[2] must be poly in x,a"); }
+ ring deglexring=char(altring),(x,y,z),dp;
+ map transfer=altring,x,z;
+ ideal i=transfer(i);
+ if (size(i)!=2)
+ {
+   ERROR("either wrong number of given minimal polynomials"+newline+
+   "or wrong choice of ring variables (must use the first two)");
+ }
+ matrix mat;
+ ring lexring=char(altring),(x,y),lp;
+ ideal j;
+ ring deglex2ring=char(altring),(x,y),dp;
+ ideal j;
+ setring deglexring;
+ ideal j;
+ option(redSB);
+ poly g=z;
+ int found=0;
+
+ //---------------- Schleife zum Finden des primitiven Elements ---------------
+ //--- Schleife ist so angordnet, dass g in Charakteristik 0 linear bleibt ----
+ while (found==0)
+ {
+   j=eliminate(i+ideal(g-y),z);
+   setring deglex2ring;
+   j=std(imap(deglexring,j));
+   setring lexring;
+   j=fglm(deglex2ring,j);
+   if (size(j)==2)
+   {
+     if (deg(j[1])==grad1*grad2)
+     {
+       j[2]=j[2]/leadcoef(j[2]);    // Normierung
+       if (lead(j[2])==x)
+       {         // Alles ok
+          found=1;
+       }
+     }
+   }
+   setring deglexring;
+   if (found==0)
+   {
+ //------------------ waehle ein neues Polynom g ------------------------------
+     dbprint("Still searching for primitive element...");
+     countx=0;
+     countz=0;
+     while (found==0)
+     {
+      countx++;
+      if (countx>=grad1)
+      {
+        countx=0;
+        countz++;
+        if (countz>=grad2)
+        { ERROR("No primitive element found!! This should NEVER happen!"); }
+      }
+      g = g +x^countx *z^countz;
+      mat=coeffs(g,z);
+      if (size(mat)>countz)
+      {
+        mat=coeffs(mat[countz+1,1],x);
+        if (size(mat)>countx)
+        {
+          if (mat[countx+1,1] != 0)
+          {
+            found=1;         // d.h. hier: neues g gefunden
+      }}}
+     }
+     found=0;
+   }
+ }
+ //------------------- primitives Element gefunden; Rueckgabe -----------------
+ setring lexring;
+ j[2]=x-j[2];
+ setring altring;
+ map transfer=lexring,var(1),var(2);
+ return(transfer(j));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+ ring exring=3,(x,y),dp;
+ ideal i=x2+1,y3+y2-1;
+ primitive_extra(i);
+ ring extension=(3,y),x,dp;
+ minpoly=y6-y5+y4-y3-y-1;
+ number a=y5+y4+y2+y+1;
+ a^2;
+ factorize(x2+1);
+ factorize(x3+x2-1);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc splitring(poly f,list #)
+"USAGE:   splitring(f[,L]); f poly, L list of polys and/or ideals
+         (optional)
+ASSUME:  f is univariate and irreducible over the active ring. @*
+         The active ring must allow an algebraic extension (e.g., it cannot
+         be a transcendent ring extension of Q or Z/p).
+RETURN:  ring; @*
+           if called with a nonempty second parameter L, then in the output
+           ring there is defined a list erg ( =L mapped to the new ring);
+           if the minpoly of the active ring is non-zero, then the image of
+           the primitive root of f in the output ring is appended as last
+           entry of the list erg.
+NOTE:    If the old ring has no parameter, the name @code{a} is chosen for the
+         parameter of R (if @code{a} is no ring variable; if it is, @code{b} is
+         chosen, etc.; if @code{a,b,c,o} are ring variables,
+         @code{splitring(f[,L])} produces an error message), otherwise the
+         name of the parameter is kept and only the minimal polynomial is
+         changed. @*
+         The names of the ring variables and the orderings are not affected. @*
+KEYWORDS: algebraic field extension; extension of rings
+EXAMPLE: example splitring;  shows an example
+"
+{
+ //----------------- split ist bereits eine proc in 'inout.lib' ! -------------
+ if (size(#)>=1) {
+    list L=#;
+    int L_groesse=size(L);
+ }
+ else { int L_groesse=-1; }
+ //-------------- ermittle das Minimalpolynom des aktuellen Rings: ------------
+ string minp=string(minpoly);
+
+ def altring=basering;
+ string charakt=string(char(altring));
+ string varnames=varstr(altring);
+ string algname;
+ int i;
+ int anzvar=size(maxideal(1));
+ //--------------- Fall 1: Bisheriger Ring hatte kein Minimalpolynom ----------
+ if (minp=="0") { // only possible without parameters (by assumption)
+  if (find(varnames,"a")==0)        { algname="a";}
+  else { if (find(varnames,"b")==0) { algname="b";}
+         else { if (find(varnames,"c")==0)
+                                    { algname="c";}
+         else { if (find(varnames,"o")==0)
+                                    { algname="o";}
+         else {
+           "** Sorry -- could not find a free name for the primitive element.";
+           "** Try e.g. a ring without 'a' or 'b' as variable.";
+           return();
+         }}
+       }
+  }
+  //-- erzeuge einen String, der das Minimalpolynom des neuen Rings enthaelt: -
+  execute("ring splt1="+charakt+","+algname+",dp;");
+  ideal abbnach=var(1);
+  for (i=1; i<anzvar; i++) { abbnach=abbnach,var(1); }
+  map nach_splt1=altring,abbnach;
+  execute("poly mipol="+string(nach_splt1(f))+";");
+  string Rminp=string(mipol);
+
+  //--------------------- definiere den neuen Ring: ---------------------------
+  execute("ring neuring = ("+charakt+","+algname+"),("+varnames+"),("
+           +ordstr(altring)+");");
+  execute("minpoly="+Rminp+";");
+
+  //---------------------- Berechne die zurueckzugebende Liste: ---------------
+  if (L_groesse>0) {
+   list erg;
+   map take=altring,maxideal(1);
+   erg=take(L);
+  }
+ }
+ else {
+
+  //------------- Fall 2: Bisheriger Ring hatte ein Minimalpolynom: -----------
+  algname=parstr(altring);           // Name des algebraischen Elements
+  if (npars(altring)>1) {"only one Parameter is allowed!!"; return(altring);}
+
+  //---------------- Minimalpolynom in ein Polynom umwandeln: -----------------
+  execute("ring splt2="+charakt+","+algname+",dp;");
+  execute("poly mipol="+minp+";");
+  // f ist Polynom in algname und einer weiteren Variablen -> mache f bivariat:
+  execute("ring splt3="+charakt+",("+algname+","+varnames+"),dp;");
+  poly f=imap(altring,f);
+
+  //-------------- Vorbereitung des Aufrufes von primitive: -------------------
+  execute("ring splt1="+charakt+",(x,y),dp;");
+  ideal abbnach=x;
+  for (i=1; i<=anzvar; i++) { abbnach=abbnach,y; }
+  map nach_splt1_3=splt3,abbnach;
+  map nach_splt1_2=splt2,x;
+  ideal maxid=nach_splt1_2(mipol),nach_splt1_3(f);
+  ideal primit=primitive(maxid);
+  if (size(primit)==0) {             // Suche mit 1. Proc erfolglos
+    primit=primitive_extra(maxid);
+  }
+  //-- erzeuge einen String, der das Minimalpolynom des neuen Rings enthaelt: -
+  setring splt2;
+  map nach_splt2=splt1,0,var(1);     // x->0, y->a
+  minp=string(nach_splt2(primit)[1]);
+  if (printlevel > -1) { "// new minimal polynomial:",minp; }
+  //--------------------- definiere den neuen Ring: ---------------------------
+  execute("ring neuring = ("+charakt+","+algname+"),("+varnames+"),("
+          +ordstr(altring)+");");
+  execute("minpoly="+minp+";");
+
+  if (L_groesse>0) {
+    //---------------------- Berechne die zurueckzugebende Liste: -------------
+    list erg;
+    setring splt3;
+    list zwi=imap(altring,L);
+    map nach_splt3_1=splt1,0,var(1);  // x->0, y->a
+    //----- rechne das primitive Element von altring in das von neuring um: ---
+    ideal convid=maxideal(1);
+    convid[1]=nach_splt3_1(primit)[2];
+    poly new_b=nach_splt3_1(primit)[3];
+    map convert=splt3,convid;
+    zwi=convert(zwi);
+    setring neuring;
+    erg=imap(splt3,zwi);
+    erg[size(erg)+1]=imap(splt3,new_b);
+  }
+ }
+ if (defined(erg)){export erg;}
+ return(neuring);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+ ring r=0,(x,y),dp;
+ def r1=splitring(x2-2);
+ setring r1; basering;    // change to Q(sqrt(2))
+ // change to Q(sqrt(2),sqrt(sqrt(2)))=Q(a) and return the transformed
+ // old parameter:
+ def r2=splitring(x2-a,a);
+ setring r2; basering; erg;
+ // the result is (a)^2 = (sqrt(sqrt(2)))^2
+ kill r1; kill r2;
+}
+///////////////////////////////////////////////////////////////////////////////
diff --git a/Singular/LIB/purityfiltration.lib b/Singular/LIB/purityfiltration.lib
new file mode 100644
index 0000000..11c9140
--- /dev/null
+++ b/Singular/LIB/purityfiltration.lib
@@ -0,0 +1,961 @@
+//////////////////////////////////////////////////////////////////////////
+//procedures examples comments
+version="version purityfiltration.lib 4.0.0.0 Jun_2013 "; // $Id: d6b6e3acf8119392f5ff8e096b32f5f1a647e0f4 $
+category="Noncommutative";
+info="
+LIBRARY: purityfiltration.lib     Algorithms for computing a purity filtration of a given module
+
+AUTHORS: Christian Schilli,        christian.schilli at rwth-aachen.de
+@*          Viktor Levandovskyy,   levandov at math.rwth-aachen.de
+
+
+OVERVIEW:
+Purity is a notion with several meanings. In our context it is equidimensionality
+@* of a module (that is all M is pure iff any nonzero submodule of N has the same dimension as N).
+@* Notably, one should define purity with respect to a given dimension function. In the context
+@* of this library the corresponding function is the homological grade number j_A(M) of a module M over
+@* an K-algebra A. j_A(M) is the minimal integer k, such that Ext^k_A(M,A) != 0.
+
+REFERENCES: [AQ] Alban Quadrat: Grade filtration of linear functional systems, INRIA Report 7769 (2010), to appear in Acta Applicanda Mathematica.
+@* [B93] Jan-Erik Bjoerk: Analytic D-modules and applications, Kluwer Acad. Publ., 1993.
+@* [MB10] Mohamed Barakat: Purity Filtration and the Fine Structure of Autonomy. Proc. MTNS, 2010.
+
+PROCEDURES:
+projectiveDimension(matrix T,int i);        compute a shortest resolution of coker(T) and its projective dimension
+purityFiltration(matrix R);                    compute the purity filtration of coker(R)
+purityTriang(matrix R)                        compute a triangular blockmatrix T, such that coker(R) isomorphic to coker(T)
+gradeNumber(matrix R);                              gives the grade number of the module coker(R)
+showgrades(list T);                           gives all grade numbers of the modules represented by the elements of T
+allExtOfLeft(matrix R);                              computes all right ext-modules ext^i(M,D) of a left module M=coker(R) over the ring D
+allExtOfRight(matrix R);                      computes all left ext-modules ext^i(M,D) of a right module M=coker(R) over the ring D
+doubleExt(matrix R, int i);                 computes the left module ext^i(ext^i(M,D),D) over the ring D, M=coker(R)
+allDoubleExt(matrix R);                              computes all double ext modules ext^i(ext^j(M,D),D) of the left module coker(R) over the ring D
+is_pure(matrix R);                              checks whether the module coker(R) is pure
+purelist(list T);                              checks whether all the modules represented by the elements of T are pure
+
+KEYWORDS: D-module; ext-module; filtration; projective dimension; resolution; purity
+";
+
+LIB "nctools.lib";
+LIB "matrix.lib";
+LIB "poly.lib";
+LIB "general.lib";
+LIB "control.lib";
+LIB "nchomolog.lib";
+
+//------------------- auxiliary procedures --------------------------
+
+proc testPurityfiltrationLib()
+{
+example projectiveDimension;
+example purityFiltration;
+example purityTriang;
+example gradeNumber;
+example showgrades;
+example allExtOfLeft;
+example allExtOfRight;
+example doubleExt;
+example allDoubleExt;
+example is_pure;
+example purelist;
+}
+
+static proc iszero (matrix R)
+"USAGE:  iszero(R); R a matrix
+RETURN:  int, 1, if R is zero,
+@*              or 0, if it's not
+PURPOSE: checks, if the matrix R is zero or not
+"
+{
+  ideal i=R;
+  i=std(i);
+  if (i==0)
+  {
+    return (1);
+  }
+  return (0);
+}
+
+proc lsyz (matrix R)
+"USAGE:  lsyz(R), R a matrix
+RETURN:         matrix, a left syzygy of R
+PURPOSE: computes the left syzygy module of the module, generated by the rows of R, i.e.
+@*         a matrix X with X*R=0
+"
+{
+  matrix L=transpose(syz(transpose(R)));
+  return(L);
+}
+
+proc rsyz (matrix R)
+"USAGE:  rsyz(R), R a matrix
+RETURN:         matrix, a rightsyzygy of R
+PURPOSE: computes the right syzygy module of the module, generated by the rows of R, i.e.
+@*         a matrix X with R*X=0
+EXAMPLE: example rsyz; shows example
+"
+{
+  def save = basering;            // with respect to non-commutative rings,
+  def saveop = opposite(save);    // we have to switch to the oppose ring for a rightsyzygy
+  setring saveop;
+  matrix Rop = oppose(save,R);
+  matrix Bop = syz(Rop);
+  setring save;
+  matrix B =oppose(saveop,Bop);
+  kill saveop;
+  return(B);
+}
+example
+{"EXAMPLE:";echo = 2;
+  ring D = 0,(x,y,z),dp;
+  matrix R[3][2]=x,0,0,x,y,-z;
+  matrix X=rsyz(R);
+  print(X);
+  // check
+  print(R*X);
+}
+
+
+static proc rinv (matrix R)
+"USAGE:  rinv(R), R a matrix
+RETURN:         matrix, a right inverse of R
+PURPOSE: computes a right inverse matrix of R, if it exists
+@*         if not, it returns the zero matrix
+"
+{
+  return(rightInverse(R));
+}
+
+static proc linv (matrix R)
+"USAGE:  linv(R), R a matrix
+RETURN:         matrix, a left inverse of R
+PURPOSE: computes a left inverse matrix of R, if it exists
+@*         if not, it returns the zero matrix
+"
+{
+  return (leftInverse(R));
+}
+
+proc rlift(matrix M, matrix N)
+"USAGE:  rlift(M,N), M and N matrices, so that the module, generated by the columns of N
+@*         is a submodule of the one, generated by the columns of M
+RETURN:         matrix, a right lift of N in M
+PURPOSE: computes a right lift matrix X of N in M,
+@*         i.e. N=M*X
+"
+{
+  def save = basering;           // with respect to non-commutative rings,
+  def saveop = opposite(save);   // we have to change the ring for a rightlift
+  setring saveop;
+  matrix Mop = oppose(save,M);
+  matrix Nop = oppose(save,N);
+  matrix Bop = lift(Mop,Nop);
+  setring save;
+  matrix B =oppose(saveop,Bop);
+  kill saveop;
+  return(B);
+}
+
+proc llift(matrix M, matrix N)
+"USAGE:  llift(M,N), M and N matrices, so that the module, generated by the rows of N
+@*         is a submodule of the one, generated by the rows of M
+RETURN:         matrix, a left lift of N in M
+PURPOSE: computes a left lift matrix X of N in M,
+@*         i.e. N=X*M
+"
+{
+  matrix X=transpose(lift(transpose(M),transpose(N)));
+  return(X);
+}
+
+static proc concatz(matrix M, matrix N)
+"USAGE:  concatz(M,N), M and N matrices
+RETURN:         matrix
+PURPOSE: adds the rows of N under the rows of M, i.e. build the matrix (M^Tr,N^Tr)^Tr
+"
+{
+  matrix X=transpose(concat(transpose(M),transpose(N)));
+  return (X);
+}
+
+//------------------------- main procedures --------------------------
+
+proc purityFiltration(matrix R)
+"USAGE:  purityFiltration(S), S matrix with entries of an Auslander regular ring D
+RETURN:         a list T of two lists, purity filtration of the module M=D^q/D^p(S^t)
+PURPOSE: the first list T[1] gives a filtration {M_i} of M,
+@*         where the i-th entry of T[1] gives the representation matrix of M_(i-1).
+@*         the second list T[2] gives representations of the factor Modules,
+@*         i.e. T[2][i] gives the repr. matrix for M_(i-1)/M_i
+EXAMPLE: example purityFiltration; shows example
+"
+{
+  int i,j;
+  list re=projectiveDimension(R,0);
+  list T=re[1];
+  int di=re[2];
+  list reres;             // Rji=reres[i][j+1], i=1,..,n+1; j=0,..,i
+  for( i=1; i<=di+1; i++ )
+  {
+    list zw;
+    zw[i+1]=T[i];
+    for( j=i; j >= 1; j--)
+    {
+      zw[j]=rsyz(zw[j+1]);
+    }
+    reres[i]=zw;
+    kill zw;
+  }
+  list F;    // Fij=F[j][i+1], j=2,..,n+1; i=0,..,j-1
+  for(i=2;i<=di;i++)
+  {
+    list ehm;
+    matrix I[nrows(T[i-1])][nrows(T[i-1])];
+    I=I+1;
+    ehm[i]=I;
+    kill I;
+    for (j=1; j<=i-1; j++)
+    {
+      ehm[i-j]=rlift(reres[i][i-j+1],ehm[i-j+1]*reres[i-1][i-j+1]);
+    }
+    F[i]=ehm;
+    kill ehm;
+  }
+//  list M;       // Mi=M[i+1], i=0,...,n+1
+//  M[1]=R1;
+//  matrix Ti=lsyz(reres[1][1]);
+//  matrix P[ncols(Ti)][ncols(Ti)];
+//  P=P+1;
+//  for (i=1;i<=di; i++)
+//  {
+//    M[i+1]=transpose(modulo(transpose(Ti*P),transpose(reres[i][2])));
+//    P=F[i+1][1]*P;
+//    Ti=lsyz(reres[i+1][1]);
+//  }
+//  M[di+2]=transpose(modulo(transpose(Ti*P),transpose(reres[di+1][2])));
+//  list I;
+//  for (i=1;i<=di+1;i++)
+//  {
+//    I[i]=transpose(modulo(transpose(M[i]),transpose(M[i+1])));
+//  }
+  list Rs,Rss;
+  for(i=1; i<=di; i++)
+  {
+    list zw;
+    zw[1]=lsyz(reres[i][1]);
+    zw[2]=lsyz(zw[1]);
+    Rss[i]=llift(zw[1],reres[i][2]);
+    Rs[i]=zw;
+    kill zw;
+  }
+  list Fs;
+  for(i=2;i<=di;i++)
+  {
+    Fs[i]=llift(Rs[i-1][1],Rs[i][1]*F[i][1]);
+  }
+  list K,U;
+  K[1]=transpose(R);
+  U[1]=Rs[1][1];
+  for(i=2;i<=di;i++)
+  {
+    K[i]=transpose(std(transpose(concatz(Rss[i-1], Rs[i-1][2]))));
+    U[i]=transpose(std(transpose(concatz(concatz(Fs[i],Rss[i-1]),Rs[i-1][2]))));
+  }
+  K[di+1]=transpose(std(transpose(concatz(Rss[di], Rs[di][2]))));
+  U[di+1]=K[di+1];
+  list erg=(K,U);
+  return (erg);
+}
+example
+{"EXAMPLE:";echo = 2;
+  ring D = 0,(x1,x2,d1,d2),dp;
+  def S=Weyl();
+  setring S;
+  int i;
+  matrix R[3][3]=0,d2-d1,d2-d1,d2,-d1,-d1-d2,d1,-d1,-2*d1;
+  print(R);
+  list T=purityFiltration(transpose(R));
+  // the purity filtration of coker(M)
+  print(T[1][1]);
+  print(T[1][2]);
+  print(T[1][3]);
+  // factor modules of the filtration
+  print(T[2][1]);
+  print(T[2][2]);
+  print(T[2][3]);
+}
+
+
+proc purityTriang(matrix R)
+"USAGE:  purityTriang(S), S matrix with entries of an Auslander regular ring D
+RETURN:         a matrix T
+PURPOSE: compute a triangular block matrix T, such that M=D^p/D^q(S^t) is isomorphic to M'=D^p'/D^q(T^t)
+EXAMPLE: example purityTriang; shows example
+"
+{
+  int i,j;
+  list re=projectiveDimension(R,0);
+  list T=re[1];
+  int di=re[2];
+  list reres;             // Rji=reres[i][j+1], i=1,..,n+1; j=0,..,i
+  for( i=1; i<=di+1; i++ )
+  {
+    list zw;
+    zw[i+1]=T[i];
+    for( j=i; j >= 1; j--)
+    {
+      zw[j]=rsyz(zw[j+1]);
+    }
+    reres[i]=zw;
+    kill zw;
+  }
+  list F;    // Fij=F[j][i+1], j=2,..,n+1; i=0,..,j-1
+  for(i=2;i<=di;i++)
+  {
+    list ehm;
+    matrix I[nrows(T[i-1])][nrows(T[i-1])];
+    I=I+1;
+    ehm[i]=I;
+    kill I;
+    for (j=1; j<=i-1; j++)
+    {
+      ehm[i-j]=rlift(reres[i][i-j+1],ehm[i-j+1]*reres[i-1][i-j+1]);
+    }
+    F[i]=ehm;
+    kill ehm;
+  }
+
+  list Rs,Rss;
+  for(i=1; i<=di; i++)
+  {
+    list zw;
+    zw[1]=lsyz(reres[i][1]);
+    zw[2]=lsyz(zw[1]);
+    Rss[i]=llift(zw[1],reres[i][2]);
+    Rs[i]=zw;
+    kill zw;
+  }
+  list Fs;
+  for(i=2;i<=di;i++)
+  {
+    Fs[i]=llift(Rs[i-1][1],Rs[i][1]*F[i][1]);
+  }
+
+
+  int sp; list spnr;
+  spnr[1]=ncols(Rs[1][1]);
+  for (i=2;i<=di;i++)
+    {
+      spnr[i]=ncols(Fs[i]);
+    }
+  spnr[di+1]=ncols(Rss[di]);
+  sp=sum(spnr);
+
+  matrix E[nrows(Rs[1][1])][nrows(Rs[1][1])]; E=E-1;
+  list Z; int sumh;
+  Z[1]=concat(Rs[1][1],E);
+  sumh=ncols(Rs[1][1]);
+  kill E;
+
+  for(i=2;i<=di;i++)
+  {
+    matrix A;
+    matrix B[1][sumh];
+    matrix E[nrows(Fs[i])][nrows(Fs[i])]; E=E-1;
+
+    A=Fs[i];
+    if (i>2)
+    {
+      if (iszero(Rss[i-1])==0)
+      {
+        A=concatz(A,Rss[i-1]);
+      }
+    }
+    if (iszero(Rs[i-1][2])==0)
+    {
+      A=concatz(A,Rs[i-1][2]);
+    }
+    A=concat(B,A,E);
+    Z[i]=A;
+    sumh=sumh+spnr[i];
+    kill A,B,E;
+  }
+
+
+  matrix hi,his;
+  matrix N[1][sumh];
+
+  if (iszero(Rss[di])==0)
+  {
+    hi=concat(N,Rss[di]);
+  }
+
+  if (iszero(Rs[di][2])==0)
+  {
+    his=concat(N,Rs[di][2]);
+    if (iszero(hi)==1)
+    {
+      hi=his;
+    }
+    if (iszero(hi)==0)
+    {
+    hi=concatz(hi,his);
+    }
+  }
+
+  kill his;
+
+  matrix ges=Z[1];
+  for (i=2;i<=di;i++)
+  {
+    ges = concatz(ges,Z[i]);
+  }
+
+  if (iszero(hi)==0)
+  {
+    ges=concatz(ges,hi);
+  }
+return (ges);
+}
+example
+{"EXAMPLE:";echo = 2;
+  ring D = 0,(x1,x2,d1,d2),dp;
+  def S=Weyl();
+  setring S;
+  int i;
+  matrix R[3][3]=0,d2-d1,d2-d1,d2,-d1,-d1-d2,d1,-d1,-2*d1;
+  print(R);
+  matrix T=purityTriang(transpose(R));
+  // a triangular blockmatrix representing the module coker(R)
+  print(T);
+}
+
+
+proc gradeNumber(matrix R)
+"USAGE:  gradeNumber(R), R matrix, representing M=D^p/D^q(R^t) over a ring D
+RETURN:         int, grade number of M
+PURPOSE: computes the grade number of M, i.e. the first i, with ext^i(M,D) !=0
+@*         returns -1 if M=0
+EXAMPLE: example gradeNumber; shows examples
+"
+{
+  matrix M=transpose(R);
+  if (is_zero(transpose(M))==1)
+  {
+    return (-1);
+  }
+  list ext = allExtOfLeft(transpose(M));
+  int i=1;
+  matrix L=ext[i];
+  while (is_zero(transpose(L))==1)
+  {
+    i=i+1;
+    L=ext[i];
+  }
+  return (i-1);
+}
+example
+{"EXAMPLE:";echo = 2;
+  // trivial example
+  ring D=0,(x,y,z),dp;
+  matrix R[2][1]=1,x;
+  gradeNumber(R);
+  // R has left inverse, so M=D/D^2R=0
+  gradeNumber(transpose(R));
+  print(ncExt_R(0,R));
+  // so, ext^0(coker(R),D) =! 0)
+  //
+  // a little bit more complex
+  matrix R1[3][1]=x,-y,z;
+  gradeNumber(transpose(R1));
+  print(ncExt_R(0,transpose(R1)));
+  print(ncExt_R(1,transpose(R1)));
+  print(ncExt_R(2,transpose(R1)));
+  // ext^i are zero for i=0,1,2
+  matrix ext3=ncExt_R(3,transpose(R1));
+  print(ext3);
+  // not zero
+  is_zero(ext3);
+}
+
+proc allExtOfLeft(matrix Ps)
+"USAGE:  allExtOfLeft(M),
+RETURN:         list, entries are ext-modules
+ASSUME: M presents a left module of finite left projective dimension n
+PURPOSE: For a left module presented by M over the basering D,
+@*           compute a list T, whose entry T[i+1] is a matrix, presenting the right module Ext^i_D(M,D) for i=0..n
+EXAMPLE: example allExtOfLeft; shows example
+"
+{
+  // old doc: ... T[i] gives the repr. matrix of ext^(i-1)(M,D), i=1,.., n+1
+  list ext, Phi;
+  ext[1]=ncHom_R(Ps);
+  Phi = mres(Ps,0);
+  int di = size(Phi);
+  Phi[di+1]= transpose(lsyz(transpose(Phi[di])));
+  int i;
+  def Rbase = basering;
+  for(i=1;i<=di;i++)
+  {
+    module f   = transpose(matrix(Phi[i+1]));
+    module Im2 = transpose(matrix(Phi[i]));
+    def Rop   = opposite(Rbase);
+    setring Rop;
+    module fop    = oppose(Rbase,f);
+    module Im2op  = oppose(Rbase,Im2);
+    module ker_op = modulo(fop,std(0));
+    module ext_op = modulo(ker_op,Im2op);
+    setring Rbase;
+    ext[i+1] = oppose(Rop,ext_op); // a right module!
+    kill f, Im2, Rop;
+  }
+  return(ext);
+}
+example
+{"EXAMPLE:";echo = 2;
+  ring D = 0,(x,y,z),dp;
+  matrix R[6][4]=
+  0,-2*x,z-2*y-x,-1,
+  0,z-2*x,2*y-3*x,1,
+  z,-6*x,-2*y-5*x,-1,
+  0,y-x,y-x,0,
+  y,-x,-y-x,0,
+  x,-x,-2*x,0;
+  // coker(R) consider the left module M=D^6/D^4R
+  list T=allExtOfLeft(transpose(R));
+  print(T[1]);
+  print(T[2]);
+  print(T[3]);
+  print(T[4]);
+  // right modules coker(T[i].)!!
+}
+
+proc allExtOfRight(matrix Ps)
+"USAGE:  allExtOfRight(R), R matrix representing the right Module M=D^q/RD^p over a ring D
+@*           M module with finite right projective dimension n
+RETURN:         list, entries are ext-modules
+PURPOSE: computes a list T, which entries are representations of the left modules ext^i(M,D)
+@*         T[i] gives the repr. matrix of ext^(i-1)(M,D), i=1,..,n+1
+EXAMPLE: example allExtOfRight; shows example
+"
+{
+  // matrix Ps=transpose(Y);
+  list ext, Phi;
+  def Rbase = basering;
+  def Rop   = opposite(Rbase);
+  setring Rop;
+  matrix Psop=oppose(Rbase,Ps);
+  matrix ext1_op = ncHom_R(Psop);
+  setring Rbase;
+  ext[1]=oppose(Rop,ext1_op);
+  kill Rop;
+  list zw = rightreso(transpose(Ps)); // right resolution
+  int di = size(zw);
+  zw[di+1]=lsyz(zw[di]);
+  Phi = zw;
+  kill zw;
+  int i;
+  for(i=1;i<=di;i++)
+  {
+    module f   = Phi[i+1];
+    module Im2 = Phi[i];
+    module ker = modulo(f,std(0));
+    ext[i+1] = modulo(ker,Im2);  // a left module!
+    kill f, Im2, ker;
+  }
+  return(ext);
+}
+example
+{"EXAMPLE:";echo = 2;
+  ring D = 0,(x,y,z),dp;
+  matrix R[6][4]=
+  0,-2*x,z-2*y-x,-1,
+  0,z-2*x,2*y-3*x,1,
+  z,-6*x,-2*y-5*x,-1,
+  0,y-x,y-x,0,
+  y,-x,-y-x,0,
+  x,-x,-2*x,0;
+  // coker(R) considered as right module
+  projectiveDimension(R,1)[2];
+  list T=allExtOfRight(R);
+  print(T[1]);
+  print(T[2]);
+  // left modules coker(.T[i])!!
+}
+
+static proc rightreso(matrix T)
+"USAGE:  rightreso(T), T matrix representing the right module M=D*/TD*
+RETURN:         list L, a right resolution of M
+PURPOSE: computes a right resolution of M, using mres
+@*         the i-th entry of L gives the (i-1)th right syzygy module of M
+"
+{
+  int j;
+  matrix M=transpose(T);
+  list res;
+  def save = basering;            // with respect to non-commutative rings,
+  def saveop = opposite(save);    // we have to change the ring for a rightresolution
+  setring saveop;
+  matrix Mop=oppose(save,M);
+  list aufl=mres(Mop,0);
+  list resop=aufl;
+  kill aufl;
+  for (j=1; j<=size(resop); j++)
+  {
+    matrix zw=resop[j];
+    setring save;
+    res[j]=transpose(oppose(saveop,zw));
+    setring saveop;
+    kill zw;
+  }
+  setring save;
+  kill saveop;
+  return(res);
+}
+
+proc showgrades(list T)
+"USAGE:  showgrades(T), T list, which includes representation matrices of modules
+RETURN:         list, gradenumbers of the entries in T
+PURPOSE: computes a list L with L[i]=gradenumber(M), M=D^p/D^qT[i]
+EXAMPLE: example showgrades; shows example
+"
+{
+  list grades;
+  int gr=size(T);
+  int i;
+  for (i=1;i<=gr;i++)
+  {
+    grades[i]=gradeNumber(transpose(T[i]));
+  }
+  return (grades);
+}
+example
+{"EXAMPLE:";echo = 2;
+  ring D = 0,(x,y,z),dp;
+  matrix R[6][4]=
+  0,-2*x,z-2*y-x,-1,
+  0,z-2*x,2*y-3*x,1,
+  z,-6*x,-2*y-5*x,-1,
+  0,y-x,y-x,0,
+  y,-x,-y-x,0,
+  x,-x,-2*x,0;
+  list T=purityFiltration(transpose(R))[2];
+  showgrades(T);
+  // T[i] are i-1 pure (i=1,3,4) or zero (i=2)
+}
+
+proc doubleExt(matrix R, int i)
+"USAGE:  doubleExt(R,i), R matrix representing the left Module M=D^p/D^q(R^t) over a ring D
+@*         int i, less or equal the left projective dimension of M
+RETURN:         matrix P, representing the double ext module
+PURPOSE: computes a matrix P, which represents the left module ext^i(ext^i(M,D))
+EXAMPLE: example doubleExt; shows example
+"
+{
+  return (allExtOfRight(   allExtOfLeft(R)[i+1]   )[i+1]);
+}
+example
+{"EXAMPLE:";echo = 2;
+  ring D = 0,(x,y,z),dp;
+  matrix R[7][3]=
+  0 ,0,1,
+  1 ,-4*x+z,-z,
+  -1,8*x-2*z,z,
+  1 ,0  ,0,
+  0 ,x-y,0,
+  0 ,x-y,y,
+  0 ,0  ,x;
+  // coker(R) is 2-pure, so all doubleExt are zero
+  print(doubleExt(transpose(R),0));
+  print(doubleExt(transpose(R),1));
+  print(doubleExt(transpose(R),3));
+  // except of the second
+  print(doubleExt(transpose(R),2));
+}
+
+proc allDoubleExt(matrix R)
+"USAGE:  allDoubleExt(R), R matrix representing the left Module M=D^p/D^q(R^t) over a ring D
+RETURN:         list T, double indexed, which include all double-ext modules
+PURPOSE: computes all double ext-modules
+@*         T[i][j] gives a representation matrix of ext^(j-1)(ext(i-1)(M,D))
+EXAMPLE: example allDoubleExt; shows example
+"
+{
+list ext=allExtOfLeft(transpose(R));
+list extext;
+int i;
+for(i=1;i<=size(ext);i++)
+  {
+    extext[i]=allExtOfRight(ext[i]);
+  }
+kill ext;
+return (extext);
+}
+example
+{"EXAMPLE:";echo = 2;
+  ring D = 0,(x1,x2,x3,d1,d2,d3),dp;
+  def S=Weyl();
+  setring S;
+  matrix R[6][4]=
+  0,-2*d1,d3-2*d2-d1,-1,
+  0,d3-2*d1,2*d2-3*d1,1,
+  d3,-6*d1,-2*d2-5*d1,-1,
+  0,d2-d1,d2-d1,0,
+  d2,-d1,-d2-d1,0,
+  d1,-d1,-2*d1,0;
+  list T=allDoubleExt(transpose(R));
+  // left projective dimension of M=coker(R) is 3
+  // ext^i(ext^0(M,D)), i=0,1,2,3
+  print(T[1][1]);
+  print(T[1][2]);
+  print(T[1][3]);
+  print(T[1][4]);
+  // ext^i(ext^1(M,D)), i=0,1,2,3
+  print(T[2][1]);
+  print(T[2][2]);
+  print(T[2][3]);
+  print(T[2][4]);
+  // ext^i(ext^2(M,D)), i=0,1,2,3  (all zero)
+  print(T[3][1]);
+  print(T[3][2]);
+  print(T[3][3]);
+  print(T[3][4]);
+  // ext^i(ext^3(M,D)), i=0,1,2,3  (all zero)
+  print(T[4][1]);
+  print(T[4][2]);
+  print(T[4][3]);
+  print(T[4][4]);
+}
+
+proc is_pure(matrix R)
+"USAGE:  is_pure(R), R representing the module M=D^p/D^q(R^t)
+RETURN:         int, 0 or 1
+PURPOSE: checks pureness of M.
+@*         returns 1, if M is pure, or 0, if it's not
+@*         remark: if M is zero, is_pure returns 1
+EXAMPLE: example is_pure; shows example
+"
+{
+  matrix M=transpose(R);
+  int gr=gradeNumber(transpose(M));
+  int di=projectiveDimension(transpose(M),0)[2];
+  int i=0;
+  while(i<=di)
+  {
+    if (i!=gr)
+    {
+      if (  is_zero( doubleExt(transpose(M),i) ) == 0 )
+      {
+        return (0);
+      }
+    }
+    i=i+1;
+  }
+  return (1);
+}
+example
+{"EXAMPLE:";echo = 2;
+  ring D = 0,(x,y,z),dp;
+  matrix R[3][2]=y,-z,x,0,0,x;
+  list T=purityFiltration(transpose(R));
+  print(transpose(std(transpose(T[2][2]))));
+  // so the purity filtration of coker(R) is trivial,
+  // i.e. coker(R) is already pure
+  is_pure(transpose(R));
+  // we can also have non-pure modules:
+  matrix R2[6][4]=
+  0,-2*x,z-2*y-x,-1,
+  0,z-2*x,2*y-3*x,1,
+  z,-6*x,-2*y-5*x,-1,
+  0,y-x,y-x,0,
+  y,-x,-y-x,0,
+  x,-x,-2*x,0;
+  is_pure(transpose(R2));
+}
+
+proc purelist(list T)
+"USAGE:  purelist(T), T list, in which the i-th entry R=T[i] represents M=D^p/D^q(R^t)
+RETURN:         list M, entries of M are 0 or 1
+PURPOSE: if T[i] is pure, M[i] is 1, else M[i] is 0
+EXAMPLE: example purelist; shows example
+"
+{
+  int i;
+  list erg;
+  for(i=1;i<=size(T);i++)
+  {
+    erg[i]=is_pure(transpose(T[i]));
+  }
+  return (erg);
+}
+example
+{"EXAMPLE:";echo = 2;
+  ring D = 0,(x,y,z),dp;
+  matrix R[6][4]=
+  0,-2*x,z-2*y-x,-1,
+  0,z-2*x,2*y-3*x,1,
+  z,-6*x,-2*y-5*x,-1,
+  0,y-x,y-x,0,
+  y,-x,-y-x,0,
+  x,-x,-2*x,0;
+  is_pure(transpose(R));
+  // R is not pure, so we do the purity filtration
+  list T=purityFiltration(transpose(R));
+  // all Elements of T[2] are either zero or pure
+  purelist(T[2]);
+}
+
+
+proc projectiveDimension(matrix T, list #)
+"USAGE:  projectiveDimension(R,i,j), R matrix representing the Modul M=coker(R)
+@*       int i, with i=0 or i=1, j a natural number
+RETURN:  list T, a projective resolution of M and its projective dimension
+PURPOSE: if i=0 (and by default), T[1] gives a shortest left resolution of M=D^p/D^q(R^t) and T[2] the left projective dimension of M
+@*         if i=1, T[1] gives a shortest right resolution of M=D^p/RD^q and T[2] the right projective dimension of M
+@*          in both cases T[1][j] is the (j-1)-th syzygy module of M
+NOTE: The algorithm is due to A. Quadrat, D. Robertz, Computation of bases of free modules over the Weyl algebras, J.Symb.Comp. 42, 2007.
+EXAMPLE: example projectiveDimension; shows examples
+"
+{
+  int i = 0; // default
+  if (size(#) >0)
+  {
+    i = int(#[1]);
+    if ( (i!=0) and (i!=1) )
+    {
+      printf("Unaccepted second argument. Use 0 to get a left resolution, 1 for a right one.");
+    }
+  }
+  if (i==0)
+  {
+    return(prodim(T));
+  }
+    int j;
+    matrix M=T;
+    list res;
+    def save = basering;            // with respect to non-commutative rings,
+    def saveop = opposite(save);    // we have to change the ring for a rightresolution
+    setring saveop;
+    matrix Mop=oppose(save,M);
+    list aufl=prodim(Mop);
+    int k=aufl[2];
+    list resop=aufl[1];
+    kill aufl;
+    for (j=1; j<=size(resop); j++)
+    {
+      matrix zw=resop[j];
+      setring save;
+      res[j]=transpose(oppose(saveop,zw));
+      setring saveop;
+      kill zw;
+    }
+    setring save;
+    list Y;
+    Y[1]=res;
+    Y[2]=k;
+    kill saveop;
+    kill res;
+    return(Y);
+
+}
+example
+{"EXAMPLE:";echo = 2;
+  // commutative example
+  ring D = 0,(x,y,z),dp;
+  matrix R[6][4]=
+  0,-2*x,z-2*y-x,-1,
+  0,z-2*x,2*y-3*x,1,
+  z,-6*x,-2*y-5*x,-1,
+  0,y-x,y-x,0,
+  y,-x,-y-x,0,
+  x,-x,-2*x,0;
+  // compute a left resolution of M=D^4/D^6*R
+  list T=projectiveDimension(transpose(R),0);
+  // so we have the left projective dimension
+  T[2];
+  //we could also compute a right resolution of M=D^6/RD^4
+  list T1=projectiveDimension(R,1);
+  // and we have right projective dimension
+  T1[2];
+  // check, that a syzygy matrix of R has left inverse:
+  print(leftInverse(syz(R)));
+  // so lpd(M) must be 1.
+  // Non-commutative example
+  ring D1 = 0,(x1,x2,x3,d1,d2,d3),dp;
+  def S=Weyl();  setring S;
+  matrix R[3][3]=
+  1/2*x2*d1, x2*d2+1, x2*d3+1/2*d1,
+  -1/2*x2*d2-3/2,0,1/2*d2,
+  -d1-1/2*x2*d3,-d2,-1/2*d3;
+  list T=projectiveDimension(R,0);
+  // left projective dimension of coker(R) is
+  T[2];
+  list T1=projectiveDimension(R,1);
+  // both modules have the same projective dimension, but different resolutions, because D is non-commutative
+  print(T[1][1]);
+  // not the same as
+  print(transpose(T1[1][1]));
+}
+
+static proc prodim(matrix M)
+"USAGE:  prodim(R), R matrix representing the Modul M=coker(R)
+RETURN:  list T, a left projective resolution of M and its left projective dimension
+PURPOSE: T[1] gives a shortest left resolution of M and T[2] the left projective dimension of M
+@*         it is T[1][j] the (j-1)-th syzygy module of M
+"
+{
+  matrix T=transpose(M);
+  list R,zw;
+  R[1]=T;
+  if (rinv(R[1])==0)
+  {
+    R[2]=transpose(std(transpose(lsyz(R[1]))));
+  }
+  else
+  {
+    matrix S[1][ncols(T)];
+    R[1]=S;
+    zw[1]=R;
+    zw[2]=0;
+    return (zw);
+  }
+  if (iszero(R[2])==1)
+  {
+    zw[1]=R;
+    zw[2]=1;
+    return (zw);
+  }
+  int i=1;
+  matrix N;
+  while (iszero(R[i+1])==0)
+  {
+    i=i+1;
+    N=rinv(R[i]);
+    if (iszero(N)==0)
+    {
+      if (i==2)
+      {
+        R[i-1]=concat(R[i-1],N);
+        matrix K[1][nrows(R[1])];
+        R[2]=K;
+        zw[1]=R;
+        zw[2]=i-1;
+        return (zw);
+      }
+      if (i>2)
+      {
+        R[i-1]=concat(R[i-1],N);
+        matrix K[ncols(N)][1];
+        R[i-2]=concatz(R[i-2],K);
+        R[i]=0;
+        zw[1]=R;
+        zw[2]=i-1;
+        return(zw);
+      }
+    }
+    R[i+1]=transpose(std(transpose(lsyz(R[i]))));
+  }
+  zw[1]=R;
+  zw[2]=i;
+  return (zw);
+}
diff --git a/Singular/LIB/qhmoduli.lib b/Singular/LIB/qhmoduli.lib
new file mode 100644
index 0000000..6a13bec
--- /dev/null
+++ b/Singular/LIB/qhmoduli.lib
@@ -0,0 +1,1531 @@
+/////////////////////////////////////////////////////////////////////////////
+version="version qhmoduli.lib 4.0.0.0 Jun_2013 "; // $Id: 71f5e7db9350906433306fe5c7d3d304c0d3f859 $
+category="Singularities";
+info="
+LIBRARY:  qhmoduli.lib    Moduli Spaces of Semi-Quasihomogeneous Singularities
+AUTHOR:   Thomas Bayer, email: bayert at in.tum.de
+
+PROCEDURES:
+ ArnoldAction(f, [G, w])  Induced action of G_f on T_.
+ ModEqn(f)                Equations of the moduli space for principal part f
+ QuotientEquations(G,A,I) Equations of Variety(I)/G w.r.t. action 'A'
+ StabEqn(f)               Equations of the stabilizer of f.
+ StabEqnId(I, w)          Equations of the stabilizer of the qhom. ideal I.
+ StabOrder(f)             Order of the stabilizer of f.
+ UpperMonomials(f, [w])   Upper basis of the Milnor algebra of f.
+
+ Max(data)                maximal integer contained in 'data'
+ Min(data)                minimal integer contained in  'data'
+";
+
+// NOTE: This library has been written in the frame of the diploma thesis
+// 'Computing moduli spaces of semiquasihomogeneous singularities and an
+//  implementation in Singular', Arbeitsgruppe Algebraische Geometrie,
+// Fachbereich Mathematik, University Kaiserslautern,
+// Advisor: Prof. Gert-Martin Greuel
+
+LIB "rinvar.lib";
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc ModEqn(poly f, list #)
+"USAGE:   ModEqn(f [, opt]); poly f; int opt;
+PURPOSE: compute equations of the moduli space of semiquasihomogenos hypersurface         singularity with principal part f w.r.t. right equivalence
+ASSUME:  f quasihomogeneous polynomial with an isolated singularity at 0
+RETURN:  polynomial ring, possibly a simple extension of the ground field of
+         the basering, containing the ideal 'modid'
+         - 'modid' is the ideal of the moduli space  if opt is even (> 0).
+           otherwise it contains generators of the coordinate ring R of the
+           moduli space (note : Spec(R) is the moduli space)
+OPTIONS: 1 compute equations of the mod. space,
+         2 use a primary decomposition,
+         4 compute E_f0, i.e., the image of G_f0,
+         to combine options, add their value, default: opt =7
+EXAMPLE: example ModEqn; shows an example
+"
+{
+  int sizeOfAction, i, dimT, nonLinearQ, milnorNr, dbPrt;
+  int imageQ, opt;
+  intvec wt;
+  ideal B;
+  list Gf, tIndex, sList;
+  string ringSTR;
+
+  dbPrt = printlevel-voice+2;
+  if(size(#) > 0) { opt = #[1]; }
+  else { opt = 7; }
+  if(opt div 4 > 0) { imageQ = 1; opt = opt - 4;}
+  else { imageQ = 0; }
+
+  wt = weight(f);
+  milnorNr = vdim(std(jacob(f)));
+  if(milnorNr == -1) {
+                ERROR("the polynomial " + string(f) + " has a nonisolated singularity at 0");
+        }       // singularity not isolated
+
+  // 1st step : compute a basis of T_
+
+  B = UpperMonomials(f, wt);
+  dimT = size(B);
+  dbprint(dbPrt, "moduli equations of f = " + string(f) + ", f has Milnor number = " + string(milnorNr));
+  dbprint(dbPrt, " upper basis = " + string(B));
+  if(size(B) > 1) {
+
+    // 2nd step : compute the stabilizer G_f of f
+
+    dbprint(dbPrt, " compute equations of the stabilizer of f, called G_f");
+    Gf = StabEqn(f);
+    dbprint(dbPrt, " order of the stabilizer = " + string(StabOrder(Gf)));
+
+    // 3rd step : compute the induced action of G_f on T_ by means of a theorem of Arnold
+
+    dbprint(dbPrt, " compute the induced action");
+    def RME1 = ArnoldAction(f, Gf, B);
+    setring(RME1);
+    export(RME1);
+    dbprint(dbPrt, " G_f = " + string(stabid));
+    dbprint(dbPrt, " action of G_f : " + string(actionid));
+
+    // 4th step : linearize the action of G_f
+
+    sizeOfAction = size(actionid);
+    def RME2 = LinearizeAction(stabid, actionid, nvars(Gf[1]));
+    setring RME2;
+    export(RME2);
+    kill RME1;
+
+    if(size(actionid) == sizeOfAction) { nonLinearQ = 0;}
+    else  {
+      nonLinearQ = 1;
+      dbprint(dbPrt, " linearized action = " + string(actionid));
+      dbprint(dbPrt, " embedding of T_ = " + string(embedid));
+    }
+
+
+
+    if(!imageQ) {        // do not compute the image of Gf
+      // 5th step : set E_f = G_f,
+      dbprint(dbPrt, " compute equations of the quotient T_/G_f");
+      def RME3 = basering;
+    }
+    else {
+
+      // 5th step : compute the ideal and the action of E_f
+
+      dbprint(dbPrt, " compute E_f");
+      def RME3 = ImageGroup(groupid, actionid);
+      setring(RME3);
+      ideal embedid = imap(RME2, embedid);
+      dbprint(dbPrt, " E_f  = (" + string(groupid) + ")");
+      dbprint(dbPrt, " action of E'f = " + string(actionid));
+      dbprint(dbPrt, " compute equations of the quotient T_/E_f");
+    }
+    export(RME3);
+    kill RME2;
+
+    // 6th step : compute the equations of the quotient T_/E_f
+
+                ideal G = groupid; ideal variety = embedid;
+                kill groupid,embedid;
+    def RME4 = QuotientEquations(G, actionid, variety, opt);
+    setring RME4;
+    string @mPoly = string(minpoly);
+    kill RME3;
+    export(RME4);
+
+    // simplify the ideal and create a new ring with propably less variables
+
+    if(opt == 1 || opt == 3) {      // equations computed ?
+      sList = SimplifyIdeal(id, 0, "Y");
+      ideal newid = sList[1];
+      dbprint(dbPrt, " number of equations = " + string(size(sList[1])));
+      dbprint(dbPrt, " number of variables = " + string(size(sList[3])));
+      ringSTR = "ring RME5 = (" + charstr(basering) + "), (Y(1.." + string(size(sList[3])) + ")),dp;";
+      execute(ringSTR);
+      execute("minpoly = number(" + @mPoly + ");");
+      ideal modid = imap(RME4, newid);
+    }
+    else {
+      def RME5 = RME4;
+      setring(RME5);
+      ideal modid = imap(RME4, id);
+    }
+    export(modid);
+    kill RME4;
+  }
+  else {
+                def RME5 = basering;
+                ideal modid = maxideal(1);
+                if(size(B) == 1) {                      // 1-dimensional
+                        modid[size(modid)] = 0;
+                        modid = simplify(modid,2);
+                }
+                export(modid);
+        }
+dbprint(dbPrt, "
+// 'ModEqn' created a new ring.
+// To see the ring, type (if the name of the ring is R):
+     show(R);
+// To access the ideal of the moduli space of semiquasihomogeneous singularities
+// with principal part f, type
+     def R = ModEqn(f); setring R;  modid;
+// 'modid' is the ideal of the moduli space.
+// if 'opt' = 0 or even, then 'modid' contains algebra generators of S s.t.
+// spec(S) = moduli space of f.
+");
+  return(RME5);
+}
+example
+{"EXAMPLE:";  echo = 2;
+  ring B   = 0,(x,y), ls;
+  poly f = -x4 + xy5;
+  def R = ModEqn(f);
+  setring R;
+  modid;
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc QuotientEquations(ideal G, ideal Gaction, ideal embedding, list#)
+"USAGE:   QuotientEquations(G,action,emb [, opt]); ideal G,action,emb;int opt
+PURPOSE: compute the quotient of the variety given by the parameterization
+         'emb'  by the linear action 'action' of the algebraic group G.
+ASSUME:  'action' is linear, G must be finite if the Reynolds operator is
+         needed (i.e., NullCone(G,action) returns some non-invariant polys)
+RETURN:   polynomial ring over a simple extension of the ground field of the
+          basering, containing the ideals 'id' and 'embedid'.
+          - 'id' contains the equations of the quotient, if opt = 1;
+            if opt = 0, 2, 'id' contains generators of the coordinate ring R
+            of the quotient (Spec(R) is the quotient)
+          - 'embedid' = 0, if opt = 1;
+            if opt = 0, 2, it is the ideal defining the equivariant embedding
+OPTIONS: 1 compute equations of the quotient,
+         2 use a primary decomposition when computing the Reynolds operator,@*
+         to combine options, add their value, default: opt =3.
+EXAMPLE: example QuotientEquations; shows an example
+"
+{
+  int i, opt, primaryDec, relationsQ, dbPrt;
+  ideal Gf, variety;
+  intvec wt;
+
+  dbPrt = printlevel-voice+3;
+  if(size(#) > 0) { opt = #[1]; }
+  else { opt = 3; }
+
+  if(opt div 2 > 0) { primaryDec = 1; opt = opt - 2; }
+  else { primaryDec = 0; }
+  if(opt > 0) { relationsQ = 1;}
+  else { relationsQ = 0; }
+
+  Gf = std(G);
+  variety = EquationsOfEmbedding(embedding, nvars(basering) - size(Gaction));
+
+  if(size(variety) == 0) {    // use Hilbert function !
+    //for(i = 1; i <= ncols(Gaction); i ++) { wt[i] = 1;}
+    for(i = 1; i <= nvars(basering); i ++) { wt[i] = 1;}
+  }
+  def RQER = InvariantRing(Gf, Gaction, primaryDec);    // compute the nullcone of the linear action
+
+  def RQEB = basering;
+  setring(RQER);
+  export(RQER);
+
+  if(relationsQ > 0) {
+    dbprint(dbPrt, " compute equations of the variety (" + string(size(imap(RQER, invars))) + " invariants) ");
+    if(!defined(variety)) { ideal variety = imap(RQEB, variety); }
+    if(wt[1] > 0) {
+      def RQES = ImageVariety(variety, imap(RQER, invars), wt);
+    }
+    else {
+      def RQES = ImageVariety(variety, imap(RQER, invars));  // forget imap
+    }
+    setring(RQES);
+    ideal id = imageid;
+    ideal embedid = 0;
+  }
+  else {
+    def RQES = basering;
+    ideal id =  imap(RQER, invars);
+    ideal embedid = imap(RQEB, variety);
+  }
+  kill RQER;
+  export(id);
+  export(embedid);
+  return(RQES);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc UpperMonomials(poly f, list #)
+"USAGE:   UpperMonomials(poly f, [intvec w])
+PURPOSE: compute the upper monomials of the milnor algebra of f.
+ASSUME:  f is quasihomogeneous (w.r.t. w)
+RETURN:  ideal
+EXAMPLE: example UpperMonomials; shows an example
+"
+{
+  int i,d;
+  intvec wt;
+  ideal I, J;
+
+  if(size(#) == 0) { wt = weight(f);}
+  else { wt = #[1];}
+   J = kbase(std(jacob(f)));
+  d = deg(f, wt);
+  for(i = 1; i <= size(J); i++) { if(deg(J[i], wt) > d) {I = I, J[i];} }
+  return(simplify(I, 2));
+}
+example
+{"EXAMPLE:";  echo = 2;
+  ring B   = 0,(x,y,z), ls;
+  poly f = -z5+y5+x2z+x2y;
+  UpperMonomials(f);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc ArnoldAction(poly f, list #)
+"USAGE:   ArnoldAction(f, [Gf, B]); poly f; list Gf, B;
+         'Gf' is a list of two rings (coming from 'StabEqn')
+PURPOSE: compute the induced action of the stabilizer G of f on T_, where
+         T_ is given by the upper monomials B of the Milnor algebra of f.
+ASSUME:  f is quasihomogeneous
+RETURN:  polynomial ring over the same ground field, containing the ideals
+         'actionid' and 'stabid'.
+         - 'actionid' is the ideal defining the induced action of Gf on T_ @*
+         - 'stabid' is the ideal of the stabilizer Gf in the new ring
+EXAMPLE: example ArnoldAction; shows an example
+"
+{
+  int i, offset, ub, pos, nrStabVars, dbPrt;
+  intvec wt = weight(f);
+  ideal B;
+  list Gf, parts, baseDeg;
+  string ringSTR1, ringSTR2, parName, namesSTR, varSTR;
+
+  dbPrt = printlevel-voice+2;
+  if(size(#) == 0) {
+    Gf = StabEqn(f);
+    B = UpperMonomials(f, wt);
+  }
+  else {
+    Gf = #[1];
+    if(size(#) > 1) { B = #[2];}
+    else {B = UpperMonomials(f, wt);}
+  }
+  if(size(B) == 0) { ERROR("the principal part " + string(f) + " has no upper monomials");}
+  for(i = 1; i <= size(B); i = i + 1) {
+    baseDeg[i] = deg(B[i], wt);
+  }
+  ub = Max(baseDeg) + 1;          // max degree of an upper mono.
+  def RAAB = basering;
+  def STR1 = Gf[1];
+  def STR2 = Gf[2];
+  nrStabVars = nvars(STR1);
+
+  dbprint(dbPrt, "ArnoldAction of f = ", f, ", upper base = " + string(B));
+
+  setring STR1;
+  string @mPoly = string(minpoly);
+  setring RAAB;
+
+  // setup new ring with s(..) and t(..) as parameters
+
+  varSTR = string(maxideal(1));
+  ringSTR2 = "ring RAAS = ";
+  if(npars(basering) == 1) {
+    parName = parstr(basering);
+    ringSTR2 = ringSTR2 + "(0, " + parstr(1) + "), ";
+  }
+  else {
+    parName = "a";
+    ringSTR2 = ringSTR2 + "0, ";
+  }
+  offset = 1 + nrStabVars;
+  namesSTR = "s(1.." + string(nrStabVars) + "), t(1.." + string(size(B)) + ")";
+  ringSTR2 = ringSTR2 + "(" + namesSTR + "), lp;";
+  ringSTR1 = "ring RAAR = (0, " + parName + "," + namesSTR + "), (" + varSTR + "), ls;";  // lp ?
+
+  execute(ringSTR1);
+  export(RAAR);
+  ideal upperBasis, stabaction, action, reduceIdeal;
+  poly f, F, monos, h;
+
+  execute("reduceIdeal = " + @mPoly + ";"); reduceIdeal = reduceIdeal, imap(STR1, stabid);
+  f = imap(RAAB, f);
+  F = f;
+  upperBasis = imap(RAAB, B);
+  for(i = 1; i <= size(upperBasis); i = i + 1) {
+    F = F + par(i + offset)*upperBasis[i];
+  }
+  monos = F - f;
+  stabaction = imap(STR2, actionid);
+
+  // action of the stabilizer on the semiuniversal unfolding of f
+
+  F = f + APSubstitution(monos, stabaction, reduceIdeal, wt, ub, nrStabVars, size(upperBasis));
+
+  // apply the theorem of Arnold
+
+  h = ArnoldFormMain(f, upperBasis, F, reduceIdeal, nrStabVars, size(upperBasis)) - f;
+
+  // extract the polynomials of the action of the stabilizer on T_
+
+  parts = MonosAndTerms(h, wt, ub);
+  for(i = 1; i <= size(parts[1]); i = i + 1)
+  {
+    pos = FirstEntryQHM(upperBasis, parts[1][i]);
+    if (pos!=0) { action[pos] = parts[2][i]/parts[1][i];}
+  }
+  execute(ringSTR2);
+  execute("minpoly = number(" + @mPoly + ");");
+  ideal actionid = imap(RAAR, action);
+  ideal stabid = imap(STR1, stabid);
+  export(actionid);
+  export(stabid);
+  kill RAAR;
+dbprint(dbPrt, "
+// 'ArnoldAction' created a new ring.
+// To see the ring, type (if the name of the ring is R):
+     show(R);
+// To access the ideal of the stabilizer G of f and its group action,
+// where f is the quasihomogeneous principal part, type
+     def R = ArnoldAction(f); setring R;  stabid; actionid;
+// 'stabid' is the ideal of the group G and 'actionid' is the ideal defining
+// the group action of the group G on T_. Note: this action might be nonlinear
+");
+  return(RAAS);
+}
+example
+{"EXAMPLE:";  echo = 2;
+  ring B   = 0,(x,y,z), ls;
+  poly f = -z5+y5+x2z+x2y;
+  def R = ArnoldAction(f);
+  setring R;
+  actionid;
+  stabid;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc StabOrder(list #)
+"USAGE:   StabOrder(f); poly f
+PURPOSE: compute the order of the stabilizer group of f.
+ASSUME:  f quasihomogeneous polynomial with an isolated singularity at 0
+RETURN:  int
+GLOBAL: varSubsList
+"
+{
+  list stab;
+
+  if(size(#) == 1) { stab = StabEqn(#[1]); }
+  else {  stab = #;}
+
+  def RSTO = stab[1];
+  setring(RSTO);
+  return(vdim(std(stabid)));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc StabEqn(poly f)
+"USAGE:   StabEqn(f); f polynomial
+PURPOSE: compute the equations of the isometry group of f.
+ASSUME:  f semiquasihomogeneous polynomial with an isolated singularity at 0
+RETURN:  list of two rings 'S1', 'S2'
+         - 'S1' contians the equations of the stabilizer (ideal 'stabid') @*
+         - 'S2' contains the action of the stabilizer (ideal 'actionid')
+EXAMPLE: example StabEqn; shows an example
+GLOBAL: varSubsList, contains the index j s.t. x(i) -> x(i)t(j) ...
+"
+{
+dbprint(dbPrt, "
+// 'StabEqn' created a list of 2 rings.
+// To see the rings, type (if the name of your list is stab):
+     show(stab);
+// To access the 1-st ring and map (and similair for the others), type:
+     def S1 = stab[1]; setring S1;  stabid;
+// S1/stabid is the coordinate ring of the variety of the
+// stabilizer, say G. If G x K^n --> K^n is the action of G on
+// K^n, then the ideal 'actionid' in the second ring describes
+// the dual map on the ring level.
+// To access the 2-nd ring and map (and similair for the others), type:
+     def S2 = stab[2]; setring S2;  actionid;
+");
+
+        return(StabEqnId(ideal(f), qhweight(f)));
+}
+example
+{"EXAMPLE:";  echo = 2;
+  ring B = 0,(x,y,z), ls;
+  poly f = -z5+y5+x2z+x2y;
+  list stab = StabEqn(f);
+  def S1 = stab[1]; setring S1;  stabid;
+  def S2 = stab[2]; setring S2;  actionid;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc StabEqnId(ideal data, intvec wt)
+"USAGE:   StabEqn(I, w); I ideal, w intvec
+PURPOSE: compute the equations of the isometry group of the ideal I,
+         each generator of I is fixed by the stabilizer.
+ASSUME:  I semiquasihomogeneous ideal w.r.t. 'w' with an isolated singularity at 0
+RETURN:  list of two rings 'S1', 'S2'
+         - 'S1' contians the equations of the stabilizer (ideal 'stabid') @*
+         - 'S2' contains the action of the stabilizer (ideal 'actionid')
+EXAMPLE: example StabEqnId; shows an example
+GLOBAL: varSubsList, contains the index j s.t. t(i) -> t(i)t(j) ...
+"
+{
+  int i, j, c, k, r, nrVars, offset, n, sln, dbPrt;
+  list Variables, rd, temp, sList, varSubsList;
+  string ringSTR, ringSTR1, varString, parString;
+
+  dbPrt = printlevel-voice+2;
+  dbprint(dbPrt, "StabilizerEquations of " + string(data));
+
+  export(varSubsList);
+  n = nvars(basering);
+  Variables = StabVar(wt);    // possible quasihomogeneous substitutions
+  nrVars = 0;
+  for(i = 1; i <= size(wt); i++)
+  {
+    nrVars = nrVars + size(Variables[i]);
+  }
+
+  // set the new basering needed for the substitutions
+
+  varString = "s(1.." + string(nrVars) + ")";
+  if(npars(basering) == 1)
+  {
+    parString = "(0, " + parstr(basering) + ")";
+  }
+  else { parString = "0"; }
+
+  def RSTB = basering;
+  string @mPoly = string(minpoly);
+  ringSTR = "ring RSTR = " + parString + ", (" + varstr(basering) + ", " + varString + "), dp;";  // dp
+        ringSTR1 = "ring RSTT = " + parString + ", (" + varString + ", " + varstr(basering) + "), dp;";
+
+  if(defined(RSTR)) { kill RSTR;}
+        if(defined(RSTT)) { kill RSTT;}
+        execute(ringSTR1);      // this ring is only used for the result, where the variables
+  export(RSTT);           // are s(1..m),t(1..n), as needed for Derksens algorithm (NullCone)
+  execute("minpoly = number(" + @mPoly + ");");
+
+  execute(ringSTR);
+  export(RSTR);
+  execute("minpoly = number(" + @mPoly + ");");
+  poly f, f1, g, h, vars, pp;      // f1 is the polynomial after subs,
+  ideal allEqns, qhsubs, actionid, stabid, J;
+  list ringList;          // all t(i)`s which do not appear in f1
+  ideal data = simplify(imap(RSTB, data), 2);
+
+  // generate the quasihomogeneous substitution map F
+
+  nrVars = 0;
+  offset = 0;
+  for(i = 1; i <= size(wt); i++)
+  {    // build the substitution t(i) -> ...
+    if(i > 1) { offset = offset + size(Variables[i - 1]); }
+    g = 0;
+    for(j = 1; j <= size(Variables[i]); j++)
+    {
+      pp = 1;
+      for(k = 2; k <= size(Variables[i][j]); k++)
+      {
+        pp = pp * var(Variables[i][j][k]);
+        if(Variables[i][j][k] == i) { varSubsList[i] = offset + j;}
+      }
+      g = g + s(offset + j) * pp;
+    }
+    qhsubs[i] = g;
+  }
+  dbprint(dbPrt, "  qhasihomogenous substituion =" + string(qhsubs));
+  map F = RSTR, qhsubs;
+  kill varSubsList;
+
+  // get the equations of the stabilizer by comparing coefficients
+  // in the equation f = F(f).
+
+  vars = RingVarProduct(Table("i", "i", 1, size(wt)));
+
+  allEqns = 0;
+
+  matrix newcoMx, coMx;
+  int d;
+  for(r = 1; r <= ncols(data); r++)
+  {
+
+  f = data[r];
+  f1 = F(f);
+  d = deg(f);
+  newcoMx = coef(f1, vars);        // coefficients of F(f)
+  coMx = coef(f, vars);          // coefficients of f
+
+  for(i = 1; i <= ncols(newcoMx); i++)
+  {      // build the system of eqns via coeff. comp.
+    j = 1;
+    h = 0;
+    while(j <= ncols(coMx))
+    {        // all monomials in f
+      if(coMx[j][1] == newcoMx[i][1]) { h = coMx[j][2]; j = ncols(coMx) + 1;}
+      else {j = j + 1;}
+    }
+    J = J, newcoMx[i][2] - h;        // add equation
+  }
+  allEqns =  allEqns, J;
+
+  }
+  allEqns = std(allEqns);
+
+  // simplify the equations, i.e., if s(i) in J then remove s(i) from J
+  // and from the basering
+
+  sList = SimplifyIdeal(allEqns, n, "s");
+  stabid = sList[1];
+  map phi = basering, sList[2];
+        sln = size(sList[3]) - n;
+
+  // change the substitution
+
+  actionid = phi(qhsubs);
+
+        // change to new ring, auxillary construction
+
+        setring(RSTT);
+        ideal actionid, stabid;
+
+        actionid = imap(RSTR, actionid);
+        stabid = imap(RSTR, stabid);
+        export(stabid);
+  export(actionid);
+  ringList[2] = RSTT;
+
+  dbprint(dbPrt, "  substitution = " + string(actionid));
+  dbprint(dbPrt, "  equations of stabilizer = " + string(stabid));
+
+  varString = "s(1.." + string(sln) + ")";
+  ringSTR = "ring RSTS = " + parString + ", (" + varString + "), dp;";
+  execute(ringSTR);
+  execute("minpoly = number(" + @mPoly + ");");
+  ideal stabid = std(imap(RSTR, stabid));
+  export(stabid);
+  ringList[1] = RSTS;
+dbprint(dbPrt, "
+// 'StabEqnId' created a list of 2 rings.
+// To see the rings, type (if the name of your list is stab):
+     show(stab);
+// To access the 1-st ring and map (and similair for the others), type:
+     def S1 = stab[1]; setring S1;  stabid;
+// S1/stabid is the coordinate ring of the variety of the
+// stabilizer, say G. If G x K^n --> K^n is the action of G on
+// K^n, then the ideal 'actionid' in the second ring describes
+// the dual map on the ring level.
+// To access the 2-nd ring and map (and similair for the others), type:
+     def S2 = stab[2]; setring S2;  actionid;
+");
+  return(ringList);
+}
+example
+{"EXAMPLE:";  echo = 2;
+  ring B   = 0,(x,y,z), ls;
+  ideal I = x2,y3,z6;
+  intvec w = 3,2,1;
+  list stab = StabEqnId(I, w);
+  def S1 = stab[1]; setring S1;  stabid;
+  def S2 = stab[2]; setring S2;  actionid;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static
+proc ArnoldFormMain(poly f,def B, poly Fs, ideal reduceIdeal, int nrs, int nrt)
+"USAGE:   ArnoldFormMain(f, B, Fs, rI, nrs, nrt);
+   poly f,Fs; ideal B, rI; int nrs, nrt
+PURPOSE: compute the induced action of 'G_f' on T_, where f is the principal
+         part and 'Fs' is the semiuniversal unfolding of 'f' with x_i
+         substituted by actionid[i], 'B' is a list of upper basis monomials
+         for the milnor algebra of 'f', 'nrs' = number of variables for 'G_f'
+         and 'nrt' = dimension of T_
+ASSUME:  f is quasihomogeneous with an isolated singularity at 0,
+         s(1..r), t(1..m) are parameters of the basering
+RETURN:  poly
+EXAMPLE: example ArnoldAction; shows an example
+"
+{
+  int i, j, d, ub, dbPrt;
+  list upperBasis, basisDegList, gmonos, common, parts;
+  ideal jacobianId, jacobIdstd, mapId;    // needed for phi
+  intvec wt = weight(f);
+  matrix gCoeffMx;        // for lift command
+  poly newFs, g, gred, tt;        // g = sum of all monomials of degree d, gred is needed for lift
+  map phi;          // the map from Arnold's Theorem
+
+  dbPrt = printlevel-voice+2;
+  jacobianId = jacob(f);
+  jacobIdstd = std(jacobianId);
+  newFs = Fs;
+  for(i = 1; i <= size(B); i++)
+  {
+    basisDegList[i] = deg(B[i], wt);
+  }
+  ub = Max(basisDegList) + 1;          // max degree of an upper monomial
+
+  parts = MonosAndTerms(newFs - f, wt, ub);
+  gmonos = parts[1];
+  d = deg(f, wt);
+
+  for(i = d + 1; i < ub; i++)
+  {    // base[1] = monomials of degree i
+    upperBasis[i] = SelectMonos(list(B, B), wt, i);    // B must not contain 0's
+  }
+
+  // test if each monomial of Fs is contained in B, if not,
+  // compute a substitution via Arnold's theorem and substitutite
+  // it into newFs
+
+  for(i = d + 1; i < ub; i = i + 1)
+  {  // ub instead of @UB
+    dbprint(dbPrt, "-- degree = " + string(i) + " of " + string(ub - 1) + " ---------------------------");
+    if(size(newFs) < 80) { dbprint(dbPrt, "  polynomial = " + string(newFs - f));}
+    else {  dbprint(dbPrt, "  poly has deg (not weighted) " + string(deg(newFs)) + " and contains " + string(size(newFs)) + " monos");}
+
+    // select monomials of degree i and intersect them with upperBasis[i]
+
+    gmonos = SelectMonos(parts, wt, i);
+    common = IntersectionQHM(upperBasis[i][1], gmonos[1]);
+    if(size(common) == size(gmonos[1]))
+    {
+      dbprint(dbPrt, " no additional monomials ");
+    }
+
+    // other monomials than those in upperBasis occur, compute
+    // the map constructed in the proof of Arnold's theorem
+    // write g = c[i] * jacobianId[i]
+
+    else
+    {
+      dbprint(dbPrt, "  additional Monomials found, compute the map ");
+      g = PSum(gmonos[2]);      // sum of all monomials in g of degree i
+      dbprint(dbPrt, "  sum of degree " + string(i) + " is " + string(g));
+
+      gred = reduce(g, jacobIdstd);
+      gCoeffMx = lift(jacobianId, g - gred);    // compute c[i]
+      mapId = var(1) - gCoeffMx[1][1];    // generate the map
+      for(j = 2; j <= size(gCoeffMx); j++)
+      {
+        mapId[j] = var(j) - gCoeffMx[1][j];
+      }
+      dbprint(dbPrt, "  map = " + string(mapId));
+      // apply the map to newFs
+      newFs = APSubstitution(newFs, mapId, reduceIdeal, wt, ub, nrs, nrt);
+      parts = MonosAndTerms(newFs - f, wt, ub);  // monos and terms of deg < ub
+      newFs = PSum(parts[2]) + f;      // result of APS... is already reduced
+      dbprint(dbPrt, "  monomials of degree " + string(i));
+    }
+  }
+  return(newFs);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static proc MonosAndTerms(poly f,def wt, int ub)
+"USAGE:   MonosAndTerms(f, w, ub); poly f, intvec w, int ub
+PURPOSE: returns a list of all monomials and terms occuring in f of
+         weighted degree < ub
+RETURN:  list
+         _[1]  list of monomials
+         _[2]  list of terms
+EXAMPLE: example MonosAndTerms shows an example
+"
+{
+  int i, k;
+  list monomials, terms;
+  poly mono, lcInv, data;
+
+  data = jet(f, ub - 1, wt);
+  k = 0;
+  for(i = 1; i <= size(data); i++)
+  {
+    mono = lead(data[i]);
+    if(deg(mono, wt) < ub)
+    {
+      k = k + 1;
+      lcInv = 1/leadcoef(mono);
+      monomials[k] = mono * lcInv;
+      terms[k] = mono;
+    }
+  }
+  return(list(monomials, terms));
+}
+example
+{"EXAMPLE:";  echo = 2;
+  ring B = 0,(x,y,z), lp;
+  poly f = 6*x2 + 2*x3 + 9*x*y2 + z*y + x*z6;
+  MonosAndTerms(f, intvec(2,1,1), 5);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static proc SelectMonos(def parts, intvec wt, int d)
+"USAGE:   SelectMonos(parts, w, d); list/ideal parts, intvec w, int d
+PURPOSE: returns a list of all monomials and terms occuring in f of
+         weighted degree = d
+RETURN:  list
+         _[1]  list of monomials
+         _[2]  list of terms
+EXAMPLE: example SelectMonos; shows an example
+"
+{
+  int i, k;
+  list monomials, terms;
+  poly mono;
+
+  k = 0;
+  for(i = 1; i <= size(parts[1]); i++)
+  {
+    mono = parts[1][i];
+    if(deg(mono, wt) == d)
+    {
+      k++;
+      monomials[k] = mono;
+      terms[k] = parts[2][i];
+    }
+  }
+  return(list(monomials, terms));
+}
+example
+{"EXAMPLE:";  echo = 2;
+  ring B = 0,(x,y,z), lp;
+  poly f = 6*x2 + 2*x3 + 9*x*y2 + z*y + x*z6;
+  list mt =  MonosAndTerms(f, intvec(2,1,1), 5);
+  SelectMonos(mt, intvec(2,1,1), 4);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static proc Expand(def substitution,def degVec, ideal reduceI, intvec w1, int ub, list truncated)
+"USAGE:   Expand(substitution, degVec, reduceI, w, ub, truncated);
+         ideal/list substitution, list/intvec degVec, ideal reduceI, intvec w,
+         int ub, list truncated
+PURPOSE: substitute 'substitution' in the monomial given by the list of
+         exponents 'degVec', omit all terms of weighted degree > ub and reduce
+         the result w.r.t. 'reduceI'. If truncated[i] = 0 then the result is
+         stored for later use.
+RETURN:  poly
+NOTE:    used by APSubstitution
+GLOBAL:  computedPowers
+"
+{
+  int i, minDeg;
+  list powerList;
+  poly g, h;
+
+  // compute substitution[1]^degVec[1],...,subs[n]^degVec[n]
+
+  for(i = 1; i <= ncols(substitution); i++)
+  {
+    if(size(substitution[i]) < 3 || degVec[i] < 4)
+    {
+      powerList[i] = reduce(substitution[i]^degVec[i], reduceI); // new
+    }  // directly for small exponents
+    else
+    {
+      powerList[i] = PolyPower1(i, substitution[i], degVec[i], reduceI, w1, truncated[i], ub);
+    }
+  }
+  // multiply the terms obtained by using PolyProduct();
+  g = powerList[1];
+  minDeg = w1[1] * degVec[1];
+  for(i = 2; i <= ncols(substitution); i++)
+  {
+    g = jet(g, ub - w1[i] * degVec[i] - 1, w1);
+    h = jet(powerList[i], ub - minDeg - 1, w1);
+    g = PolyProduct(g, h, reduceI, w1, ub);
+    if(g == 0) { Print(" g = 0 "); break;}
+    minDeg = minDeg + w1[i] * degVec[i];
+  }
+  return(g);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static proc PolyProduct(poly g1, poly h1, ideal reduceI, intvec wt, int ub)
+"USAGE:   PolyProduct(g, h, reduceI, wt, ub); poly g, h; ideal reduceI,
+          intvec wt, int ub.
+PURPOSE: compute g*h and reduce it w.r.t 'reduceI' and omit terms of weighted
+         degree > ub.
+RETURN:  poly
+NOTE:    used by 'Expand'
+"
+{
+  int SUBSMAXSIZE = 3000;
+  int i, nrParts, sizeOfPart, currentPos, partSize, maxSIZE;
+  poly g, h, gxh, prodComp, @g2;    // replace @g2 by subst.
+
+  g = g1;
+  h = h1;
+
+  if(size(g)*size(h) > SUBSMAXSIZE)
+  {
+    // divide the polynomials with more terms in parts s.t.
+    // the product of each part with the other polynomial
+    // has at most SUBMAXSIZE terms
+
+    if(size(g) < size(h)) { poly @h = h; h = g; g = @h;@h = 0; }
+    maxSIZE = SUBSMAXSIZE / size(h);
+    //print(" SUBSMAXSIZE = "+string(SUBSMAXSIZE)+" exceeded by "+string(size(g)*size(h)) + ", maxSIZE = ", string(maxSIZE));
+    nrParts = size(g) div maxSIZE + 1;
+    partSize = size(g) div nrParts;
+    gxh = 0;  // 'g times h'
+    for(i = 1; i <= nrParts; i++)
+    {
+      //print(" loop #" + string(i) + " of " + string(nrParts));
+      currentPos = (i - 1) * partSize;
+      if(i < nrParts) {sizeOfPart = partSize;}
+      else { sizeOfPart = size(g) - (nrParts - 1) * partSize; print(" last #" + string(sizeOfPart) + " terms ");}
+      prodComp = g[currentPos + 1..sizeOfPart + currentPos] * h;  // multiply a part
+      @g2 = jet(prodComp, ub - 1, wt);  // eventual reduce ...
+      if(size(@g2) < size(prodComp)) { print(" killed " + string(size(prodComp) - size(@g2)) + " terms ");}
+      gxh =  reduce(gxh + @g2, reduceI);
+    }
+  }
+  else
+  {
+    gxh = reduce(jet(g * h,ub - 1, wt), reduceI);
+  }  // compute directly
+  return(gxh);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static proc PolyPower1(int varIndex, poly f, int e, ideal reduceI, intvec wt,
+                       int truncated, int ub)
+"USAGE:   PolyPower1(i, f, e, reduceI, wt, truncated, ub);int i, e, ub;poly f;
+         ideal reduceI; intvec wt; list truncated;
+PURPOSE: compute f^e, use previous computations if possible, and reduce it
+         w.r.t reudecI and omit terms of weighted degree > ub.
+RETURN:  poly
+NOTE:    used by 'Expand'
+GLOBAL:  'computedPowers'
+"
+{
+  int i, ordOfg, lb, maxPrecomputedPower;
+  poly g, fn;
+
+  if(e == 0) { return(1);}
+  if(e == 1) { return(f);}
+  if(f == 0) { return(1); }
+  else
+  {
+    // test if f has been computed to some power
+    if(computedPowers[varIndex][1] > 0)
+    {
+      maxPrecomputedPower = computedPowers[varIndex][1];
+      if(maxPrecomputedPower >= e)
+      {
+        // no computation necessary, f^e has already benn computed
+        g = computedPowers[varIndex][2][e - 1];
+        //Print("No computation, from list : g = elem [", varIndex, ", 2, ", e - 1, "]");
+        lb = e + 1;
+      }
+      else {  // f^d computed, where d < e
+        g = computedPowers[varIndex][2][maxPrecomputedPower - 1];
+        ordOfg = maxPrecomputedPower * wt[varIndex];
+        lb = maxPrecomputedPower + 1;
+      }
+    }
+    else
+    {    // no precomputed data
+      lb = 2;
+      ordOfg = wt[varIndex];
+      g = f;
+    }
+    for(i = lb; i <= e; i++)
+    {
+      fn = jet(f, ub - ordOfg - 1, wt); // reduce w.r.t. reduceI
+      g = PolyProduct(g, fn, reduceI, wt, ub);
+      ordOfg = ordOfg + wt[varIndex];
+      if(g == 0) { break; }
+      if((i > maxPrecomputedPower) && !truncated)
+      {
+        if(maxPrecomputedPower == 0)
+        {  // init computedPowers
+          computedPowers[varIndex] = list(i, list(g));
+        }
+        computedPowers[varIndex][1] = i;  // new degree
+        computedPowers[varIndex][2][i - 1] = g;
+        maxPrecomputedPower = i;
+      }
+    }
+  }
+  return(g);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static proc RingVarsToList(list @index)
+{
+  int i;
+  list temp;
+
+  for(i = 1; i <= size(@index); i++) { temp[i] = string(var(@index[i])); }
+  return(temp);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static
+proc APSubstitution(poly f, ideal substitution, ideal reduceIdeal, intvec wt, int ub, int nrs, int nrt)
+"USAGE:   APSubstitution(f, subs, reduceI, w, ub, int nrs, int nrt); poly f
+         ideal subs, reduceI, intvec w, int ub, nrs, nrt;
+         nrs = number of parameters s(1..nrs),
+         nrt = number of parameters t(1..nrt)
+PURPOSE: substitute 'subs' in f, omit all terms with weighted degree > ub and
+         reduce the result w.r.t. 'reduceI'.
+RETURN:  poly
+GLOBAL:  'computedPowers'
+"
+{
+  int i, j, k, d, offset;
+  int n = nvars(basering);
+  list  coeffList, parts, degVecList, degOfMonos;
+  list computedPowers, truncatedQ, degOfSubs, @temp;
+  string ringSTR, @ringVars;
+
+  export(computedPowers);
+
+  // store arguments in strings
+
+  def RASB = basering;
+
+  parts = MonosAndTerms(f, wt, ub);
+  for(i = 1; i <= size(parts[1]); i = i + 1)
+  {
+    coeffList[i] = parts[2][i]/parts[1][i];
+    degVecList[i] = leadexp(parts[1][i]);
+    degOfMonos[i] = deg(parts[1][i], wt);
+  }
+
+  // built new basering with no parameters and order dp !
+  // the parameters of the basering are appended to
+  // the variables of the basering !
+  // set ideal mpoly = minpoly for reduction !
+
+  @ringVars = "(" + varstr(basering) + ", " + parstr(1) + ",";  // precondition
+  if(nrs > 0)
+  {
+    @ringVars = @ringVars + "s(1.." + string(nrs) + "), ";
+  }
+  @ringVars = @ringVars + "t(1.." + string(nrt) + "))";
+  ringSTR = "ring RASR = 0, " + @ringVars + ", dp;";    // new basering
+
+  // built the "reduction" ring with the reduction ideal
+
+  execute(ringSTR);
+  export(RASR);
+  ideal reduceIdeal, substitution, newSubs;
+  intvec w1, degVec;
+  list minDeg, coeffList, degList;
+  poly f, g, h, subsPoly;
+
+  w1 = wt;            // new weights
+  offset = nrs + nrt + 1;
+  for(i = n + 1; i <= offset + n; i = i + 1) { w1[i] = 0; }
+
+  reduceIdeal = std(imap(RASB, reduceIdeal)); // omit later !
+  coeffList = imap(RASB, coeffList);
+  substitution = imap(RASB, substitution);
+
+  f = imap(RASB, f);
+
+  for(i = 1; i <= n; i++)
+  {      // all "base" variables
+    computedPowers[i] = list(0);
+    for(j = 1; j <= size(substitution[i]); j++) { degList[j] = deg(substitution[i][j], w1);}
+    degOfSubs[i] = degList;
+  }
+
+  // substitute in each monomial seperately
+
+  g = 0;
+  for(i = 1; i <= size(degVecList); i++)
+  {
+    truncatedQ = Table("0", "i", 1, n);
+    newSubs = 0;
+    degVec = degVecList[i];
+    d = degOfMonos[i];
+
+    // check if some terms in the substitution can be omitted
+    // degVec = list of exponents of the monomial m
+    // minDeg[j] denotes the weighted degree of the monomial m'
+    // where m' is the monomial m without the j-th variable
+
+    for(j = 1; j <= size(degVec); j++) { minDeg[j] = d - degVec[j] * wt[j]; }
+
+    for(j = 1; j <= size(degVec); j++)
+    {
+      subsPoly = 0;      // set substitution to 0
+      if(degVec[j] > 0)
+      {
+        // if variable occurs then check if
+        // substitution[j][k] * (linear part)^(degVec[j]-1) + minDeg[j] < ub
+        // i.e. look for the smallest possible combination in subs[j]^degVec[j]
+        // which comes from the term substitution[j][k]. This term is multiplied
+        // with the rest of the monomial, which has at least degree minDeg[j].
+        // If the degree of this product is < ub then substitution[j][k] contributes
+        // to the result and cannot be omitted
+
+        for(k = 1; k <= size(substitution[j]); k++)
+        {
+          if(degOfSubs[j][k] + (degVec[j] - 1) * wt[j] + minDeg[j]  < ub)
+          {
+            subsPoly = subsPoly + substitution[j][k];
+          }
+        }
+      }
+      newSubs[j] = subsPoly;        // set substitution
+      if(substitution[j] - subsPoly != 0) { truncatedQ[j] = 1;}  // mark that substitution[j] is truncated
+    }
+    h = Expand(newSubs, degVec, reduceIdeal, w1, ub, truncatedQ) * coeffList[i];  // already reduced
+    g = reduce(g + h, reduceIdeal);
+  }
+  kill computedPowers;
+  setring RASB;
+  poly fnew = imap(RASR, g);
+  kill RASR;
+  return(fnew);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static proc StabVar(intvec wt)
+"USAGE:   StabVar(w); intvec w
+PURPOSE: compute the indicies for quasihomogeneous substitutions of each
+         variable.
+ASSUME:  f semiquasihomogeneous polynomial with an isolated singularity at 0
+RETURN:  list
+         _[i]  list of combinations for var(i) (i must be appended
+         to each comb)
+GLOBAL:  'varSubsList', contains the index j s.t. x(i) -> x(i)t(j) ...
+"
+{
+  int i, j, k, uw, ic;
+  list varList, Variables, subs;
+  string str, varString;
+
+  varList = StabVarComb(wt);
+  for(i = 1; i <= size(wt); i = i + 1)
+  {
+    subs = 0;
+    // built linear substituitons
+    for(j = 1; j <= size(varList[1][i]); j++)
+    {
+      subs[j] = list(i) + list(varList[1][i][j]);
+    }
+    Variables[i] = subs;
+    if(size(varList[2][i]) > 0)
+    {
+      // built nonlinear substituitons
+      subs = 0;
+      for(j = 1; j <= size(varList[2][i]); j++)
+      {
+        subs[j] = list(i) + varList[2][i][j];
+      }
+      Variables[i] = Variables[i] + subs;
+    }
+  }
+  return(Variables);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static proc StabVarComb(intvec wt)
+"USAGE:   StabVarComb(w); intvec w
+PURPOSE: list all possible indices of indeterminates for a quasihom. subs.
+RETURN:  list
+         _[1] linear substitutions
+         _[2] nonlinear substiutions
+GLOBAL: 'varSubsList', contains the index j s.t. x(i) -> x(i)t(j) ...
+"
+{
+  int mmi, mma, ii, j, k, uw, ic;
+  list index, indices, usedWeights, combList, combinations;
+  list linearSubs, nonlinearSubs;
+  list partitions, subs, temp;        // subs[i] = substitution for var(i)
+
+  linearSubs = Table("0", "i", 1, size(wt));
+  nonlinearSubs = Table("0", "i", 1, size(wt));
+
+  uw = 0;
+  ic = 0;
+  mmi = Min(wt);
+  mma = Max(wt);
+
+  for(ii = mmi; ii <= mma; ii++)
+  {
+    if(containedQ(wt, ii))
+    {    // find variables of weight ii
+      k = 0;
+      index = 0;
+      // collect the indices of all variables of weight i
+      for(j = 1; j <= size(wt); j++)
+      {
+        if(wt[j] == ii)
+        {
+          k++;
+          index[k] = j;
+        }
+      }
+      uw++;
+      usedWeights[uw] = ii;
+      ic++;
+      indices[ii] = index;
+
+      // linear part of the substitution
+
+      for(j = 1; j <= size(index); j++)
+      {
+        linearSubs[index[j]] = index;
+      }
+
+      // nonlinear part of the substitution
+
+      if(uw > 1)
+      {    // variables of least weight do not allow nonlinear subs.
+
+        partitions = Partitions(ii, delete(usedWeights, uw));
+        for(j = 1; j <= size(partitions); j++)
+        {
+          combinations[j] = AllCombinations(partitions[j], indices);
+        }
+        for(j = 1; j <= size(index); j++)
+        {
+          nonlinearSubs[index[j]] = FlattenQHM(combinations);   // flatten one level !
+        }
+      }
+    }
+  }
+  combList[1] = linearSubs;
+  combList[2] = nonlinearSubs;
+  return(combList);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static proc AllCombinations(list partition, list indices)
+"USAGE:   AllCombinations(partition,indices); list partition, indices)
+PURPOSE: all combinations for a given partititon
+RETURN:  list
+GLOBAL: varSubsList, contains the index j s.t. x(i) -> x(i)t(j) ...
+"
+{
+  int i, k, m, ok, p, offset;
+  list nrList, indexList;
+
+  k = 0;
+  offset = 0;
+  i = 1;
+  ok = 1;
+  m = partition[1];
+  while(ok)
+  {
+    if(i > size(partition))
+    {
+      ok = 0;
+      p = 0;
+    }
+    else { p = partition[i];}
+    if(p == m) { i = i + 1;}
+    else
+    {
+      k = k + 1;
+      nrList[k] = i - 1 - offset;
+      offset = offset + i - 1;
+      indexList[k] = indices[m];
+      if(ok) { m = partition[i];}
+    }
+  }
+  return(AllCombinationsAux(nrList, indexList));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static proc AllSingleCombinations(int n, list index)
+"USAGE:   AllSingleCombinations(n index); int n, list index
+PURPOSE: all combinations for var(n)
+RETURN:  list
+"
+{
+  int i, j, k;
+  list comb, newC, temp, newIndex;
+
+  if(n == 1)
+  {
+    for(i = 1; i <= size(index); i++)
+    {
+      temp = index[i];
+      comb[i] = temp;
+    }
+    return(comb);
+  }
+  if(size(index) == 1)
+  {
+    temp = Table(string(index[1]), "i", 1, n);
+    comb[1] = temp;
+    return(comb);
+  }
+  newIndex = index;
+  for(i = 1; i <= size(index); i = i + 1)
+  {
+    if(i > 1) { newIndex = delete(newIndex, 1); }
+    newC = AllSingleCombinations(n - 1, newIndex);
+    k = size(comb);
+    temp = 0;
+    for(j = 1; j <= size(newC); j++)
+    {
+      temp[1] = index[i];
+      temp = temp + newC[j];
+      comb[k + j] = temp;
+      temp = 0;
+    }
+  }
+  return(comb);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static proc AllCombinationsAux(list parts, list index)
+"USAGE:  AllCombinationsAux(parts ,index); list parts, index
+PURPOSE: all compbinations for nonlinear substituiton
+RETURN:  list
+"
+{
+  int i, j, k;
+  list comb, firstC, restC;
+
+  if(size(parts) == 0 || size(index) == 0) { return(comb);}
+
+  firstC = AllSingleCombinations(parts[1], index[1]);
+  restC = AllCombinationsAux(delete(parts, 1), delete(index, 1));
+
+  if(size(restC) == 0) { comb = firstC;}
+  else
+  {
+    for(i = 1; i <= size(firstC); i++)
+    {
+      k = size(comb);
+      for(j = 1; j <= size(restC); j++)
+      {
+        //elem = firstC[i] + restC[j];
+        // comb[k + j] = elem;
+        comb[k + j] = firstC[i] + restC[j];
+      }
+    }
+  }
+  return(comb);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static proc Partitions(int n, list nr)
+"USAGE:   Partitions(n, nr); int n, list nr
+PURPOSE: partitions of n consisting of elements from nr
+RETURN:  list
+"
+{
+  int i, j, k;
+  list parts, temp, restP, newP, decP;
+
+  if(size(nr) == 0) { return(list());}
+  if(size(nr) == 1)
+  {
+    if(NumFactor(nr[1], n) > 0)
+    {
+      parts[1] = Table(string(nr[1]), "i", 1, NumFactor(nr[1], n));
+    }
+    return(parts);
+  }
+  else
+  {
+    parts =  Partitions(n, nr[1]);
+    restP = Partitions(n, delete(nr, 1));
+
+    parts = parts + restP;
+    for(i = 1; i <= n div nr[1]; i = i + 1)
+    {
+      temp = Table(string(nr[1]), "i", 1, i);
+      decP = Partitions(n - i*nr[1], delete(nr, 1));
+      k = size(parts);
+      for(j = 1; j <= size(decP); j++)
+      {
+        newP = temp + decP[j];        // new partition
+        if(!containedQ(parts, newP, 1))
+        {
+          k = k + 1;
+          parts[k] = newP;
+        }
+      }
+    }
+  }
+  return(parts);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static proc NumFactor(int a, int b)
+" USAGE: NumFactor(a, b); int a, b
+PURPOSE: if b divides a then return b/a, else return 0
+RETURN:  int
+"
+{
+  int c = b div a;
+  if(c*a == b) { return(c); }
+  else {return(0)}
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static proc Table(string cmd, string iterator, int lb, int ub)
+" USAGE: Table(cmd,i, lb, ub); string cmd, i; int lb, ub
+PURPOSE: generate a list of size ub - lb + 1 s.t. _[i] = cmd(i)
+RETURN:  list
+"
+{
+  list data;
+  execute("int " + iterator + ";");
+
+  for(int @i = lb; @i <= ub; @i++)
+  {
+    execute(iterator + " = " + string(@i));
+    execute("data[" + string(@i) + "] = " + cmd + ";");
+  }
+  return(data);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static proc FlattenQHM(list data)
+" USAGE: FlattenQHM(n, nr); list data
+PURPOSE: flatten the list (one level) 'data', which is a list of lists
+RETURN:  list
+"
+{
+  int i, j, c;
+  list fList, temp;
+
+  c = 1;
+
+  for(i = 1; i <= size(data); i++)
+  {
+    for(j = 1; j <= size(data[i]); j++)
+    {
+      fList[c] = data[i][j];
+      c = c + 1;
+    }
+  }
+  return(fList);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static proc IntersectionQHM(list l1, list l2)
+// Type : list
+// Purpose : Intersection of l1 and l2
+{
+  list l;
+  int b, c;
+
+  c = 1;
+
+  for(int i = 1; i <= size(l1); i++)
+  {
+    b = containedQ(l2, l1[i]);
+    if(b == 1)
+    {
+      l[c] = l1[i];
+      c++;
+    }
+  }
+  return(l);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static proc FirstEntryQHM(def data,def elem)
+// Type : int
+// Purpose : position of first entry equal to elem in data (from left to right)
+{
+  int i, pos;
+
+  i = 0;
+  pos = 0;
+  while(i < size(data))
+  {
+    i++;
+    if(data[i] == elem) { pos = i; break;}
+  }
+  return(pos);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static proc PSum(def e)
+{
+  poly f;
+  for(int i = size(e);i>=1;i--)
+  {
+    f = f + e[i];
+  }
+  return(f);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc Max(def data)
+"USAGE:   Max(data); intvec/list of integers
+PURPOSE: find the maximal integer contained in 'data'
+RETURN:  list
+ASSUME:  'data' contains only integers and is not empty
+"
+{
+  int i;
+  int max = data[1];
+
+  for(i = size(data); i>1;i--)
+  {
+    if(data[i] > max) { max = data[i]; }
+  }
+  return(max);
+}
+example
+{"EXAMPLE:";  echo = 2;
+  Max(list(1,2,3));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc Min(def data)
+"USAGE:   Min(data); intvec/list of integers
+PURPOSE: find the minimal integer contained in 'data'
+RETURN:  list
+ASSUME:  'data' contians only integers and is not empty
+"
+{
+  int i;
+  int min = data[1];
+
+  for(i = size(data);i>1; i--)
+  {
+    if(data[i] < min) { min = data[i]; }
+  }
+  return(min);
+}
+example
+{"EXAMPLE:";  echo = 2;
+  Min(intvec(1,2,3));
+}
+
+///////////////////////////////////////////////////////////////////////////////
diff --git a/Singular/LIB/qmatrix.lib b/Singular/LIB/qmatrix.lib
new file mode 100644
index 0000000..8cf24a3
--- /dev/null
+++ b/Singular/LIB/qmatrix.lib
@@ -0,0 +1,293 @@
+/////////////////////////////////////
+version="version qmatrix.lib 4.0.0.0 Jun_2013 "; // $Id: 0ff9b9f42c3021528e3920ce6700195dc3d55673 $
+category="Noncommutative";
+info="
+LIBRARY: qmatrix.lib     Quantum matrices, quantum minors and symmetric groups
+AUTHORS: Lobillo, F.J.,  jlobillo at ugr.es
+@*       Rabelo, C.,     crabelo at ugr.es
+
+SUPPORT: 'Metodos algebraicos y efectivos en grupos cuanticos', BFM2001-3141, MCYT, Jose Gomez-Torrecillas (Main researcher).
+
+PROCEDURES:
+quantMat(n, [p]);          generates the quantum matrix ring of order n;
+qminor(u, v, nr);          calculate a quantum minor of a quantum matrix
+
+SymGroup(n);                generates an intmat containing S(n), each row is an element of S(n)
+LengthSymElement(v);        calculates the length of the element v of S(n)
+LengthSym(M);               calculates the length of each element of M, being M a subset of S(n)
+";
+
+LIB "ncalg.lib";
+LIB "nctools.lib";  // for rootofUnity
+///////////////////////////////////////////////////////////////////////////////
+
+proc SymGroup(int n)
+"USAGE:   SymGroup(n); n an integer (positive)
+RETURN:  intmat
+PURPOSE: represent the symmetric group S(n) via integer vectors (permutations)
+NOTE:    each row of the output integer matrix is an element of S(n)
+SEE ALSO: LengthSym, LengthSymElement
+EXAMPLE: example SymGroup; shows examples
+"{
+  if (n<=0)
+  {
+    "n must be positive";
+    intmat M[1][1]=0;
+  }
+  else
+  {
+    if (n==1)
+    {
+      intmat M[1][1]=1;
+    }
+    else
+    {
+      def N=SymGroup(n-1); // N is the symmetric group S(n-1)
+      int m=nrows(N); // The order of S(n-1)=(n-1)!
+      intmat M[m*n][n]; // Matrix to save S(n), m*n=n*(n-1)!=n!=#S(n)
+      int i,j,k;
+      for (i=1; i<=m; i++)
+      { // fixed an element i of S(n-1)
+        for (j=n; j>0; j--)
+        { // and fixed a position j to introduce an "n"
+          for (k=1; k<j; k++)
+          { // we want to copy the i-th element until position j-1
+            M[n*(i-1)+(n-j+1),k]=N[i,k];
+          }
+          M[n*(i-1)+(n-j+1),j]=n; // we write the "n" in the position j
+          for (k=j+1; k<=n; k++)
+          {
+            M[n*(i-1)+(n-j+1),k]=N[i,k-1]; // and we run until the end of copying
+          }
+        }
+      }
+    }
+  }
+  return (M);
+}
+example
+{
+  "EXAMPLE:";echo=2;
+  //  "S(3)={(1,2,3),(1,3,2),(3,1,2),(2,1,3),(2,3,1),(3,2,1)}";
+  SymGroup(3);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+// This procedure calculates the length of an element v of a symmetric group
+// If size(v)=n, the group is S(n). The permutation is i->v[i].
+
+proc LengthSymElement(intvec v)
+"USAGE:  LengthSymElement(v); v intvec
+RETURN:  int
+PURPOSE: determine the length of the permutation given by v in some S(n)
+ASSUME:  v represents an element of S(n); otherwise the output may have no sense
+SEE ALSO: SymGroup, LengthSym
+EXAMPLE: example LengthSymElement; shows examples
+"{
+  int n=size(v);
+  int l=0;
+  int i,j;
+  for (i=1; i<n; i++)
+  {
+    for (j=i+1; j<=n; j++)
+    {
+      if (v[j]<v[i]) {l++;}
+    }
+  }
+  return (l);
+}
+example
+{
+  "EXAMPLE:";echo=2;
+  intvec v=1,3,4,2,8,9,6,5,7,10;
+  LengthSymElement(v);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc LengthSym(intmat M)
+"USAGE:   LengthSym(M); M an intmat
+RETURN:  intvec
+PURPOSE: determine a vector, where the i-th element is the length of the permutation of S(n) given by the i-th row of M
+ASSUME: M represents a subset of S(n) (each row must be an element of S(n)); otherwise, the output may have no sense
+SEE ALSO: SymGroup, LengthSymElement
+EXAMPLE: example LengthSym; shows examples
+"{
+  int n=ncols(M); // this n is the n of S(n)
+  int m=nrows(M); // m=num of element of S(n) in M, if M=S(n) m=n!
+  intvec L=0;
+  int i;
+  for (i=1; i<=m; i++)
+  {
+    L=L,LengthSymElement(intvec(M[i,1..n]));
+  }
+  L=L[2..size(L)];
+  return (L);
+}
+example
+{
+  "EXAMPLE:";echo=2;
+  def M = SymGroup(3); M;
+  LengthSym(M);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc quantMat(int n, list #)
+"USAGE:   quantMat(n [, p]); n integer (n>1), p an optional integer
+RETURN:  ring (of quantum matrices). If p is specified, the quantum parameter q
+@*       will be specialized at the p-th root of unity
+PURPOSE: compute the quantum matrix ring of order n
+NOTE:    activate this ring with the \"setring\" command.
+@*       The usual representation of the variables in this quantum
+@*       algebra is not used because double indexes are not allowed
+@*       in the variables. Instead the variables are listed by reading
+@*       the rows of the usual matrix representation, that is, there
+@*       will be n*n variables (one for each entry an n*N generic matrix),
+@*       listed row-wise
+SEE ALSO: qminor
+EXAMPLE: example quantMat; shows examples
+"{
+  if (n>1)
+  {
+    int nv=n^2;
+    intmat m[nv][nv];
+    int i,j;
+    for (i=1; i<=nv; i++)
+    {
+      m[i,nv+1-i]=1;
+    }
+    int chr = 0;
+    if ( size(#) > 0 )
+    {
+      if ( typeof( #[1] ) == "int" )
+      {
+        chr = #[1];
+      }
+    }
+    ring @rrr=(0,q),(y(1..nv)),Dp;
+    minpoly = rootofUnity(chr);
+    matrix C[nv][nv]=0;
+    matrix D[nv][nv]=0;
+    intvec idyi, idyj;
+    for (i=1; i<nv; i++)
+    {
+      for (j=i+1; j<=nv; j++)
+      {
+        idyi=itoij(i,n);
+        idyj=itoij(j,n);
+        if (idyi[1]==idyj[1] || idyi[2]==idyj[2])
+        {
+          C[i,j]=1/q;
+        }
+        else
+        {
+          if (idyi[2]<idyj[2])
+          {
+            C[i,j]=1;
+            D[i,j]=(1/q - q)*y(ijtoi(idyi[1],idyj[2],n))*y(ijtoi(idyj[1],idyi[2],n));
+          }
+          else
+          {
+            C[i,j]=1;
+          }
+        }
+      }
+    }
+    def @@rrr=nc_algebra(C,D);
+    return (@@rrr);
+  }
+  else
+  {
+    "ERROR: n must be greater than 1";
+    return();
+  }
+}
+example
+{
+  "EXAMPLE:"; echo=2;
+  def r = quantMat(2); // generate O_q(M_2) at q generic
+  setring r;   r;
+  kill r;
+  def r = quantMat(2,5); // generate O_q(M_2) at q^5=1
+  setring r;   r;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc qminor(intvec I, intvec J, int nr)
+"USAGE:        qminor(I,J,n); I,J intvec, n int
+RETURN: poly, the quantum minor of a generic n*n quantum matrix
+ASSUME: I is the ordered list of the rows to consider in the minor,
+@*      J is the ordered list of the columns to consider in the minor,
+@*      I and J must have the same number of elements,
+@*      n is the order of the quantum matrix algebra you are working with (quantMat(n)).
+@*      The base ring should be constructed using @code{quantMat}.
+SEE ALSO: quantMat
+EXAMPLE: example qminor; shows examples
+"{
+  poly d=0;
+  poly f=0;
+  int k=0;
+  int n=size(I);
+  if ( size(I)!=size(J) )
+  {
+    "#I must be equal to #J";
+  }
+  else
+  {
+    def Sn=SymGroup(n);
+    def L=LengthSym(Sn);
+    int m=size(L); // m is the order of S(n)
+    int i,j;
+    for (i=1; i<=m; i++)
+    {
+      f=(-q)^(L[i]);
+      for (j=1; j<=n; j++)
+      {
+        k=ijtoi(I[j],J[Sn[i,j]],nr);
+        f=f*y(k);
+      }
+      d=d+f;
+    }
+  }
+  return (d);
+}
+example
+{
+  "EXAMPLE:";
+  echo=2;
+  def r = quantMat(3); // let r be a quantum matrix of order 3
+  setring r;
+  intvec u = 1,2;
+  intvec v = 2,3;
+  intvec w = 1,2,3;
+  qminor(w,w,3);
+  qminor(u,v,3);
+  qminor(v,u,3);
+  qminor(u,u,3);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+// For tecnical reasons we work with a list of variables {y(1)...y(n^2)}.
+// In quantum matrices the usual is to work with a square matrix of variables {y(ij)}.
+// The formulas are easier if we use matricial notation.
+// The following two procedures change the index of a list to a matrix and viceversa in order
+// to use matricial notation in the calculus but use list notation in input and output.
+// n is the order of the quantum matrix algebra where we are working.
+
+static proc itoij(int i,int n)
+{
+  intvec ij=0,0;
+  ij[1]=((i-1) div n)+1;
+  ij[2]=((i-1) mod n)+1;
+  return(ij);
+}
+
+static proc ijtoi(int i,int j,int n)
+{
+  return((j-1)+n*(i-1)+1);
+}
+///////////////////////////////////////////////////////////////////////////////
diff --git a/Singular/LIB/random.lib b/Singular/LIB/random.lib
new file mode 100644
index 0000000..549c007
--- /dev/null
+++ b/Singular/LIB/random.lib
@@ -0,0 +1,455 @@
+///////////////////////////////////////////////////////////////////////////
+version="version random.lib 4.0.0.0 Jun_2013 "; // $Id: 9f9b7db9c658deb04a5d368847264ad29af5405f $
+category="General purpose";
+info="
+LIBRARY:  random.lib    Creating Random and Sparse Matrices, Ideals, Polys
+
+PROCEDURES:
+ genericid(i[,p,b]);     generic sparse linear combinations of generators of i
+ randomid(id,[k,b]);     random linear combinations of generators of id
+ randommat(n,m[,id,b]);  nxm matrix of random linear combinations of id
+ sparseid(k,u[,o,p,b]);  ideal of k random sparse poly's of degree d [u<=d<=o]
+ sparsematrix(n,m,o[,.]);nxm sparse matrix of polynomials of degree<=o
+ sparsemat(n,m[,p,b]);   nxm sparse integer matrix with random coefficients
+ sparsepoly(u[,o,p,b]);  random sparse polynomial with terms of degree in [u,o]
+ sparsetriag(n,m[,.]);   nxm sparse lower-triag intmat with random coefficients
+ sparseHomogIdeal(k,u,[,.]); ideal with k sparse homogeneous generators of degree in [u, o]
+ triagmatrix(n,m,o[,.]); nxm sparse lower-triag matrix of poly's of degree<=o
+ randomLast(b);          random transformation of the last variable
+ randomBinomial(k,u,..); binomial ideal, k random generators of degree >=u
+           (parameters in square brackets [] are optional)
+";
+
+LIB "inout.lib";
+LIB "general.lib";
+LIB "matrix.lib";
+///////////////////////////////////////////////////////////////////////////////
+
+proc genericid (def id, list #)
+"USAGE:   genericid(id[,p,b]);  id ideal/module, p,b integers
+RETURN:  system of generators of id which are generic, sparse, triagonal linear
+         combinations of given generators with coefficients in [1,b] and
+         sparsety p percent, bigger p being sparser (default: p=75, b=30000)
+NOTE:    For performance reasons try small bound b in characteristic 0
+EXAMPLE: example genericid; shows an example
+"
+{
+//----------------------------- set defaults ----------------------------------
+   if( size(#)>=2 ) { int p=#[1]; int b=#[2];}
+   if( size(#)==1 ) { int p=#[1]; int b=30000;}
+   if( size(#)==0 ) { int p=75; int b=30000;}
+//---------------- use sparsetriag for creation of genericid ------------------
+   def i = simplify(id,10);
+   i = i*sparsetriag(ncols(i),ncols(i),p,b);
+   return(i);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r=0,(t,x,y,z),ds;
+   ideal i= x3+y4,z4+yx,t+x+y+z;
+   genericid(i,0,10);
+   module m=[x,0,0,0],[0,y2,0,0],[0,0,z3,0],[0,0,0,t4];
+   print(genericid(m));
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc randomid (def id, list #)
+"USAGE:   randomid(id[,k,b]);  id ideal/module, b,k integers
+RETURN:  ideal/module having k generators which are random linear combinations
+         of generators of id with coefficients in the interval [-b,b]
+         (default: b=30000, k=size(id))
+NOTE:    For performance reasons try small bound b in characteristic 0
+EXAMPLE: example randomid; shows an example
+"
+{
+//----------------------------- set defaults ----------------------------------
+   if( size(#)>=2 ) { int k=#[1]; int b=#[2]; }
+   if( size(#)==1 ) { int k=#[1]; int b=30000; }
+   if( size(#)==0 ) { int k=size(id); int b=30000; }
+//--------------------------- create randomid ---------------------------------
+   def i = id;
+   i = matrix(id)*random(b,ncols(id),k);
+   return(i);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r=0,(x,y,z),dp;
+   randomid(maxideal(2),2,9);
+   module m=[x,0,1],[0,y2,0],[y,0,z3];
+   show(randomid(m));
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc randommat (int n, int m, list #)
+"USAGE:   randommat(n,m[,id,b]);  n,m,b integers, id ideal
+RETURN:  nxm matrix, entries are random linear combinations of elements
+         of id and coefficients in [-b,b]
+         [default: (id,b) = (maxideal(1),30000)]
+NOTE:    For performance reasons try small bound b in char 0
+EXAMPLE:  example randommat; shows an example
+"
+{
+//----------------------------- set defaults ----------------------------------
+   if( size(#)>=2 ) { ideal id=#[1]; int b=#[2]; }
+   if( size(#)==1 ) { ideal id=#[1]; int b=30000; }
+   if( size(#)==0 ) { ideal id=maxideal(1); int b=30000; }
+//--------------------------- create randommat --------------------------------
+   id=simplify(id,2);
+   int g=ncols(id);
+   matrix rand[n][m]; matrix ra[1][m];
+   for (int k=1; k<=n; k=k+1)
+   {
+      ra = id*random(b,g,m);
+      rand[k,1..m]=ra[1,1..m];
+   }
+   return(rand);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r=0,(x,y,z),dp;
+   matrix A=randommat(3,3,maxideal(2),9);
+   print(A);
+   A=randommat(2,3);
+   print(A);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc sparseid (int k, int u, list #)
+"USAGE:   sparseid(k,u[,o,p,b]);  k,u,o,p,b integers
+RETURN:  ideal having k generators, each of degree d, u<=d<=o, p percent of
+         terms in degree d are 0, the remaining have random coefficients
+         in the interval [1,b], (default: o=u, p=75, b=30000)
+EXAMPLE: example sparseid; shows an example
+"
+{
+//----------------------------- set defaults ----------------------------------
+   if( size(#)>=3 ) { int o=#[1]; int p=#[2]; int b=#[3]; }
+   else {if( size(#)==2 ) { int o=#[1]; int p=#[2]; int b=30000; }
+   else {if( size(#)==1 ) { int o=#[1]; int p=75; int b=30000; }
+   else {if( size(#)==0 ) { int o=u; int p=75; int b=30000; }}}}
+//------------------ use sparsemat for creation of sparseid -------------------
+   int ii; matrix i[1][k]; intmat m;
+   if( u <=0 )
+   {
+      m = sparsemat(1,k,p,b);
+      i = m;
+      u=1;
+   }
+   for ( ii=u; ii<=o; ii++)
+   {
+       m = sparsemat(size(maxideal(ii)),k,p,b);
+       i = i+matrix(maxideal(ii))*m;
+   }
+   return(ideal(i));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r = 0,(a,b,c,d),ds;
+   sparseid(2,3);"";
+   sparseid(3,0,4,90,9);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+proc sparseHomogIdeal (int k, int u, list #)
+"USAGE:   sparseid(k,u[,o,p,b]);  k,u,o,p,b integers
+RETURN:  ideal having k homogeneous generators, each of random degree in the
+         interval [u,o], p percent of terms in degree d are 0, the remaining
+         have random coefficients in the interval [1,b], (default: o=u, p=75,
+         b=30000)
+EXAMPLE: example sparseid; shows an example
+"
+{
+//----------------------------- set defaults ----------------------------------
+   if( size(#)>=3 ) { int o=#[1]; int p=#[2]; int b=#[3]; }
+   if( size(#)==2 ) { int o=#[1]; int p=#[2]; int b=30000; }
+   if( size(#)==1 ) { int o=#[1]; int p=75; int b=30000; }
+   if( size(#)==0 ) { int o=u; int p=75; int b=30000; }
+//------------------ use sparsemat for creation of sparseid -------------------
+   int ii; ideal i; intmat m; ideal id;
+
+   for ( ii=k; ii>0; ii--)
+   {
+       id = maxideal(random(u, o)); // monomial basis of some degree
+       m = sparsemat(size(id),1,p,b); // random coefficients
+       i[ii] = (matrix(id)*m)[1,1];
+   }
+   return(i);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r = 0,(a,b,c,d),dp;
+   sparseHomogIdeal(2,3);"";
+   sparseHomogIdeal(3,0,4,90,9);
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc sparsemat (int n, int m, list #)
+"USAGE:   sparsemat(n,m[,p,b]);  n,m,p,b integers
+RETURN:  nxm integer matrix, p percent of the entries are 0, the remaining
+         are random coefficients >=1 and <= b; [defaults: (p,b) = (75,1)]
+EXAMPLE: example sparsemat; shows an example
+"
+{
+   int r,h,ii;
+   int t = n*m;
+   intmat v[1][t];
+//----------------------------- set defaults ----------------------------------
+   if( size(#)>=2 ) { int p=#[1]; int b=#[2]; }
+   if( size(#)==1 ) { int p=#[1]; int b=1; }
+   if( size(#)==0 ) { int p=75; int b=1; }
+//------------------------- check trivial cases ------------------------------
+   if( p<0 ) { p = 0; }
+   if(p>100) { p=100; }
+//--------------- this is faster for not very sparse matrices ----------------
+   if( p<40 )
+   {
+      for( ii=1; ii<=t; ii++ )
+      { r=( random(1,100)>p ); v[1,ii]=r*random(1,b); h=h+r; }
+   }
+  int bb = t*(100-p);
+  if( 100*h > bb )
+  {
+     while( 100*h > bb )
+     { r=random(1,t); h=h-( v[1,r]>0 ); v[1,r]=0; }
+  }
+  else
+  {
+//------------------- this is faster for sparse matrices ---------------------
+     while ( 100*h < bb )
+     { r=random(1,t); h=h+(v[1,r]==0); v[1,r]=random(1,b); }
+  }
+  intmat M[n][m] = v[1,1..t];
+  return(M);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   sparsemat(5,5);"";
+   sparsemat(5,5,95);"";
+   sparsemat(5,5,5);"";
+   sparsemat(5,5,50,100);
+}
+///////////////////////////////////////////////////////////////////////////////
+proc sparsematrix (int n, int m, int o, list #)
+"USAGE:   sparsematrix(n,m,o[,u,pe,pp,b]);  n,m,o,u,pe,pp,b integers
+RETURN:  nxm matrix, about pe percent of the entries are 0, the remaining
+         are random polynomials of degree d, u<=d<=o, with  pp percent of
+         the terms being 0, the remaining have random coefficients
+         in the interval [1,b] [default: (pe,u,pp,b) = (0,50,75,100)]
+EXAMPLE: example sparsematrix; shows an example
+"
+{
+   int ii,jj;
+   ideal id;
+   matrix M[n][m];
+//----------------------------- set defaults ----------------------------------
+   int pe=50;int u=0;int pp=75;int b=100;
+   if( size(#)==4 ) { u=#[1]; pe=#[2]; pp=#[3]; b=#[4]; }
+   else { if( size(#)==3 ) { u=#[1]; pe=#[2]; pp=#[3]; }
+   else { if( size(#)==2 ) { u=#[1]; pe=#[2]; }
+   else {if( size(#)==1 ) { u=#[1]; }}}}
+//------------------- use sparsemat and sparseid  -----------------------------
+   intmat I = sparsemat(n,m,pe,1);
+   for(ii=n; ii>0;ii--)
+   {
+     id = sparseid(m,u,o,pp,b);
+     for(jj=m; jj>0; jj--)
+     {
+        if( I[ii,jj] !=0)
+        {
+          M[ii,jj]=id[jj];
+        }
+     }
+   }
+   return(M);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r = 0,(a,b,c,d),dp;
+   // sparse matrix of sparse polys of degree <=2:
+   print(sparsematrix(3,4,2));"";
+   // dense matrix of sparse linear forms:
+   print(sparsematrix(3,3,1,1,0,55,9));
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc sparsepoly (int u, list #)
+"USAGE:   sparsepoly(u[,o,p,b]);  u,o,p,b integers
+RETURN:  poly having only terms in degree d, u<=d<=o, p percentage of the terms
+         in degree d are 0, the remaining have random coefficients in [1,b),
+         (defaults: o=u, p=75, b=30000)
+EXAMPLE:  example sparsepoly; shows an example
+"
+{
+//----------------------------- set defaults ----------------------------------
+   if( size(#)>=3 ) { int o=#[1]; int p=#[2]; int b=#[3]; }
+   else {if( size(#)==2 ) { int o=#[1]; int p=#[2]; int b=30000; }
+   else {if( size(#)==1 ) { int o=#[1]; int p=75; int b=30000; }
+   else {if( size(#)==0 ) { int o=u; int p=75; int b=30000; }}}}
+   int ii; poly f;
+//----------------- use sparseid for creation of sparsepoly -------------------
+   for( ii=u; ii<=o; ii++ ) { f=f+sparseid(1,ii,ii,p,b)[1]; }
+   return(f);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r=0,(x,y,z),dp;
+   sparsepoly(5);"";
+   sparsepoly(3,5,90,9);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc sparsetriag (int n, int m, list #)
+"USAGE:   sparsetriag(n,m[,p,b]);  n,m,p,b integers
+RETURN:  nxm lower triagonal integer matrix, diagonal entries equal to 1, about
+         p percent of lower diagonal entries are 0, the remaining are random
+         integers >=1 and <= b; [defaults: (p,b) = (75,1)]
+EXAMPLE: example sparsetriag; shows an example
+"
+{
+   int ii,min,l,r; intmat M[n][m];
+   int t=(n*(n-1)) div 2;
+//----------------------------- set defaults ----------------------------------
+   if( size(#)>=2 ) { int p=#[1]; int b=#[2]; }
+   if( size(#)==1 ) { int p=#[1]; int b=1; }
+   if( size(#)==0 ) { int p=75; int b=1; }
+//---------------- use sparsemat for creation of sparsetriag ------------------
+   intmat v[1][t]=sparsemat(1,t,p,b);
+   if( n<=m ) { min=n-1; M[n,n]=1; }
+   else { min=m; }
+   for( ii=1; ii<=min; ii++ )
+   {
+      l=r+1; r=r+n-ii;
+      M[ii..n,ii]=1,v[1,l..r];
+   }
+   return(M);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   sparsetriag(5,7);"";
+   sparsetriag(7,5,90);"";
+   sparsetriag(5,5,0);"";
+   sparsetriag(5,5,50,100);
+}
+///////////////////////////////////////////////////////////////////////////////
+proc triagmatrix (int n, int m, int o, list #)
+"USAGE:   triagmatrix(n,m,o[,u,pe,pp,b]);  n,m,o,u,pe,pp,b integers
+RETURN:  nxm lower triagonal matrix, diagonal entries equal to 1, about
+         p percent of lower diagonal entries are 0, the remaining
+         are random polynomials of degree d, u<=d<=o, with  pp percent of
+         the terms being 0, the remaining have random coefficients
+         in the interval [1,b] [default: (pe,u,pp,b) = (0,50,75,100)]
+EXAMPLE: example triagmatrix; shows an example
+"
+{
+   int ii,jj;
+   ideal id;
+   matrix M[n][m];
+//----------------------------- set defaults ----------------------------------
+   int pe=50;int u=0;int pp=75;int b=100;
+   if( size(#)==4 ) { u=#[1]; pe=#[2]; pp=#[3]; b=#[4]; }
+   if( size(#)==3 ) { u=#[1]; pe=#[2]; pp=#[3]; }
+   if( size(#)==2 ) { u=#[1]; pe=#[2]; }
+   if( size(#)==1 ) { u=#[1]; }
+//------------------- use sparsemat and sparseid  -----------------------------
+   intmat I = sparsetriag(n,m,pe,1);
+   for(ii=1; ii<=n;ii++)
+   {
+     id = sparseid(m,u,o,pp,b);
+     for(jj=1; jj<ii; jj++)
+     {
+        if( I[ii,jj] !=0)
+        {
+          M[ii,jj]=id[jj];
+        }
+     }
+   }
+   for(ii=1; ii<=n;ii++)
+   {
+      M[ii,ii]=1;
+   }
+   return(M);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r = 0,(a,b,c,d),dp;
+   // sparse triagonal matrix of sparse polys of degree <=2:
+   print(triagmatrix(3,4,2));"";
+   // dense triagonal matrix of sparse linear forms:
+   print(triagmatrix(3,3,1,1,0,55,9));
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc randomLast(int b)
+"USAGE:   randomLast(b);  b int
+RETURN:  ideal = maxideal(1), but the last variable is exchanged by a random
+         linear combination of all variables, with coefficients in the
+         interval [-b,b], except for the last variable which always has
+         coefficient 1
+EXAMPLE: example randomLast; shows an example
+"
+{
+  ideal i=maxideal(1);
+  int k=size(i);
+  if (k<=1) { return(i);}
+  i[k]=0;
+  i=randomid(i,size(i),b);
+  ideal ires=maxideal(1);
+  ires[k]=i[1]+var(k);
+  return(ires);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring  r = 0,(x,y,z),lp;
+   ideal i = randomLast(10);
+   i;
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc randomBinomial(int k, int u, list #)
+"USAGE:   randomBinomial(k,u[,o,b]);  k,u,o,b integers
+RETURN:  binomial ideal, k homogeneous generators of degree d, u<=d<=o, with
+         randomly chosen monomials and coefficients in the interval [-b,b]
+         (default: u=o, b=10).
+EXAMPLE: example randomBinomial; shows an example
+"
+{
+//----------------------------- set defaults ----------------------------------
+   if( size(#)>=2 ) { int o=#[1]; int b=#[2]; }
+   if( size(#)==1 ) { int o=#[1]; int b=10; }
+   if( size(#)==0 ) { int o=u; int b=10; }
+//------------------ use sparsemat for creation of sparseid -------------------
+   ideal i,m;
+   int ii,jj,s,r1,r2;
+   if ( o<u ) { o=u; }
+   int a = k div (o-u+1);
+   int c = k mod (o-u+1);
+   for ( ii = u; ii<=o; ii++ )
+   { m = maxideal(ii);
+     s = size(m);
+     for ( jj=1; jj<=a; jj++ )
+     { r1 = random(-b,b);
+       r1 = r1 + (r1==0)*random(1,b);
+       r2 = random(-b,b);
+       r2 = r2 + (r2==0)*random(-b,-1);
+       i = i,r1*m[random(1,s div 2)] + r1*m[random(s div 2+1,s)];
+       if ( ii < c+u )
+       {  r1 = random(-b,b);
+          r1 = r1 + (r1==0)*random(1,b);
+          r2 = random(-b,b);
+          r2 = r2 + (r2==0)*random(-b,-1);
+          i = i,r1*m[random(1,s div 2)] + r2*m[random(s div 2+1,s)];
+       }
+     }
+   }
+   i = i[2..k+1];
+   return(i);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring  r = 0,(x,y,z),lp;
+   ideal i = randomBinomial(4,5,6);
+   i;
+}
+///////////////////////////////////////////////////////////////////////////////
diff --git a/Singular/LIB/ratgb.lib b/Singular/LIB/ratgb.lib
new file mode 100644
index 0000000..e21c214
--- /dev/null
+++ b/Singular/LIB/ratgb.lib
@@ -0,0 +1,493 @@
+/////////////////////////////////////////////////////////////////////////
+version="version ratgb.lib 4.0.0.0 Jun_2013 "; // $Id: 108489c4d1cb89f45eada9101344ee6e76fa6e67 $
+category="Noncommutative";
+info="
+LIBRARY: ratgb.lib  Groebner bases in Ore localizations of noncommutative G-algebras
+AUTHOR: Viktor Levandovskyy,     levandov at risc.uni-linz.ac.at
+
+OVERVIEW:
+Theory: Let A be an operator algebra with @code{R = K[x1,.,xN]} as subring.
+The operators are usually denoted by @code{d1,..,dM}.
+
+Assume, that A is a @code{G}-algebra, then the set @code{S=R-0} is multiplicatively
+closed Ore set in A.
+That is, for any s in S and a in A, there exist t in S and b in A, such that @code{sa=bt}.
+In other words, one can transform any left fraction into a right fraction.
+The algebra @code{A_S} is called an Ore localization of A with respect to S.
+
+This library provides Groebner basis procedure for A_S, performing polynomial (that is
+fraction-free) computations only. Note, that there is ongoing development of the
+subsystem called Singular:Locapal, which will provide yet another approach to Groebner
+bases over such Ore localizations.
+
+Assumptions: in order to treat such localizations constructively, some care need to be taken.
+We will assume that the variables @code{x1,...,xN} from above (which will become invertible
+in the localization) come as the first block among the variables of the basering.
+Moreover, the ordering on the basering must be an antiblock ordering, that is its
+matrix form has the left upper @code{NxN} block zero. Here is a recipe to create such
+an ordering easily: use 'a(w)' definitions of the ordering N times with intvecs @code{w_i}
+of the following form: @code{w_i} has first N components zero. The rest entries need to
+be positive and such, that @code{w1,..,wN} are linearly independent (see an example below).
+
+Guide: with this library, it is possible
+- to compute a Groebner basis of an ideal or a submodule in the 'rational'
+  Ore localization D = A_S
+- to compute a dimension of associated graded submodule (called D-dimension)
+- to compute a vector space dimension over Quot(R) of a submodule of
+  D-dimension 0 (so called D-finite submodule)
+- to compute a basis over Quot(R) of a D-finite submodule
+
+PROCEDURES:
+ratstd(I, n); compute Groebner basis and dimensions in Ore localization of the basering
+
+Support: SpezialForschungsBereich F1301 of the Austrian FWF and
+Transnational Access Program of RISC Linz, Austria
+
+SEE ALSO: jacobson_lib
+";
+
+LIB "poly.lib";
+LIB "dmodapp.lib"; // for Appel1, Appel2, Appel4
+
+
+static proc rm_content_id(def J)
+"USAGE:  rm_content_id(I);  I an ideal/module
+RETURN:  the same type as input
+PURPOSE: remove the content of every generator of I
+EXAMPLE: example rm_content_id; shows examples
+"
+{
+  def  I = J;
+  int i;
+  int s = ncols(I);
+  for (i=1; i<=s; i++)
+  {
+    if (I[i]!=0)
+    {
+      I[i] = I[i]/content(I[i]);
+    }
+  }
+  return(I);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = (0,k,n),(K,N),dp;
+  ideal I = n*((k+1)*K - (n-k)), k*((n-k+1)*N - (n+1));
+  I;
+  rm_content_id(I);
+  module M = I[1]*gen(1), I[2]*gen(2);
+  print(rm_content_id(M));
+}
+
+proc ratstd(def I, int is, list #)
+"USAGE:  ratstd(I, n [,eng]);  I an ideal/module, n an integer, eng an optional integer
+RETURN:  ring
+PURPOSE: compute the Groebner basis of I in the Ore localization of
+the basering with respect to the subalgebra, generated by first n variables
+ASSUME: the variables of basering are organized in two blocks and
+- the first block of length n contains the elements with respect to which one localizes,
+- the basering is equipped with the elimination block ordering for the variables
+  in the second block
+NOTE: the output ring C is commutative. The ideal @code{rGBid} in C
+represents the rational form of the output ideal @code{pGBid} in the basering.
+- During the computation, the D-dimension of I and the corresponding
+dimension as K(x)-vector space of I are computed and printed out.
+- Setting optional integer eng to 1, slimgb is taken as Groebner engine
+DISPLAY: In order to see the steps of the computation, set printlevel to >=2
+EXAMPLE: example ratstd; shows examples
+"
+{
+  int ppl = printlevel-voice+1;
+  int eng = 0;
+  // optional arguments
+  if (size(#)>0)
+  {
+    if (typeof(#[1]) == "int")
+    {
+      eng = int(#[1]);
+    }
+  }
+
+  dbprint(ppl,"engine chosen to be");
+  dbprint(ppl,eng);
+
+  // 0. do the subst's /reformulations
+  // for the time being, ASSUME
+  // the ord. is an elim. ord. for D
+  // and the block of X's is on the left
+  // its length is 'is'
+
+  int i,j,k;
+  dbprint(ppl,"// -1- creating K(x)[D]");
+
+  // 1. create K(x)[D], commutative
+  def save = basering;
+  list L = ringlist(save);
+  list RL, tmp1,tmp2,tmp3,tmp4;
+  intvec iv;
+  // copy: field, enlarge it with Xs
+
+  if ( size(L[1]) == 0)
+  {
+    // i.e. the field with char only
+    tmp2[1] = L[1];
+    //    tmp1 = L[2];
+    j    = size(L[2]);
+    iv   = 1;
+    for (i=1; i<=is; i++)
+    {
+      tmp1[i] = L[2][i];
+      iv = iv,1;
+    }
+    iv = iv[1..size(iv)-1]; //extra 1
+    tmp2[2]       = tmp1;
+    tmp3[1] = "lp";
+    tmp3[2] = iv;
+    //    tmp2[3] = 0;
+    tmp4[1] = tmp3;
+    tmp2[3] = tmp4;
+    //[1] = "lp";
+    //    tmp2[3][2] = iv;
+    tmp2[4]       = ideal(0);
+    RL[1] = tmp2;
+  }
+
+  if ( size(L[1]) >0 )
+  {
+    // TODO!!!!!
+    tmp2[1] = L[1][1]; //char K
+    // there are parameters
+    // add to them X's, IGNORE alg.extension
+    // the ordering on pars
+    tmp1 = L[1][2]; // param names
+    j    = size(tmp1);
+    iv = L[1][3][1][2];
+    for (i=1; i<=is; i++)
+    {
+      tmp1[j+i] = L[2][i];
+      iv = iv,1;
+    }
+    tmp2[2] = tmp1;
+    tmp2[3] = L[1][3];
+    tmp2[3][1][2] = iv;
+    tmp2[4] = ideal(0);
+    RL[1] = tmp2;
+  }
+
+  // vars: leave only D's
+  kill tmp1; list tmp1;
+  //  tmp1 = L[2];
+  for (i=is+1; i<= size(L[2]); i++)
+  {
+    tmp1[i-is] = L[2][i];
+  }
+  RL[2] = tmp1;
+
+  // old: assume the ordering is the block with (a(0:is),ORD)
+  // old :set up ORD as the ordering
+  //  L; "RL:"; RL;
+  if (size(L[3]) != 3)
+  {
+    //"note: strange ordering";
+    // NEW assume: ordering is the antiblock with (a(0:is),a(*1),a(*), ORD)
+    // get the a() parts after is => they should form a complete D-ordering
+    list L3 = L[3]; list NL3; kill tmp3; list tmp3;
+    int @sl = size(L3);
+    int w=1; int z; intvec va,vb;
+    while(L3[w][1] == "a")
+    {
+      va = L3[w][2];
+      for(z=1;z<=nvars(save)-is;z++)
+      {
+        vb[z] = va[is+z];
+      }
+      tmp3[1] = "a";
+      tmp3[2] = vb;
+      NL3[w] = tmp3; tmp3=0;
+      w++;
+    }
+    // check for completeness: must be >= nvars(save)-is rows
+    if (w < nvars(save)-is)
+    {
+      "note: ordering is incomplete on D. Adding lower Dp block";
+      // adding: positive things like Dp
+      tmp3[1]= "Dp";
+      for (z=1; z<=nvars(save)-is; z++)
+      {
+        va[is+z] = 1;
+      }
+      tmp3[2] = va;
+      NL3[w] = tmp3; tmp3 = 0;
+      w++;
+    }
+    NL3[w] = L3[@sl]; // module ord?
+    RL[3] = NL3;
+  }
+  else
+  {
+    kill tmp2; list tmp2;
+    tmp2[1] = L[3][2];
+    tmp2[2] = L[3][3];
+    RL[3]   = tmp2;
+  }
+  // factor ideal is ignored
+  RL[4] = ideal(0);
+
+  //  "ringlist:"; RL;
+
+  def @RAT = ring(RL);
+
+  dbprint(ppl,"// -2- preprocessing with content");
+  // 2. preprocess input with rm_content_id
+  setring @RAT;
+  dbprint(ppl-1, @RAT);
+  //  ideal CI = imap(save,I);
+  def CI = imap(save,I);
+  CI = rm_content_id(CI);
+  dbprint(ppl-1, CI);
+
+  dbprint(ppl,"// -3- running groebner");
+  // 3. compute G = GB(I) w.r.t. the elim. ord. for D
+  setring save;
+  //  ideal CI = imap(@RAT,CI);
+  def CI = imap(@RAT,CI);
+  option(redSB);
+  option(redTail);
+  if (eng)
+  {
+    def G = slimgb(CI);
+  }
+  else
+  {
+    def G = groebner(CI);
+  }
+  //  ideal G = groebner(CI); // although slimgb looks better
+  // def G = slimgb(CI);
+  G = simplify(G,2); // to be sure there are no 0's
+  dbprint(ppl-1, G);
+
+  dbprint(ppl,"// -4- postprocessing with content");
+  // 4. postprocess the output with 1) rm_content_id,  2) lm-minimization;
+  setring @RAT;
+  // ideal CG = imap(save,G);
+  def CG = imap(save,G);
+  CG = rm_content_id(CG);
+  CG = simplify(CG,2);
+  dbprint(ppl-1, CG);
+
+  // warning: a bugfarm! in this ring, the ordering might change!!! (see appelF4)
+  // so, simplify(32) should take place in the orig. ring! and NOT here
+  //  CG = simplify(CG,2+32);
+
+  // 4b. create L(G) with X's as coeffs (for minimization)
+  setring save;
+  G = imap(@RAT,CG);
+  int sG  = ncols(G);
+  //  ideal LG;
+  def LG = G;
+   for (i=1; i<= sG; i++)
+   {
+     LG[i] = lead(G[i]);
+   }
+  // compute the D-dimension of the ideal in the ring @RAT
+  setring @RAT;
+  //  ideal LG = imap(save,LG);
+  def LG = imap(save,LG);
+  //  ideal LGG = groebner(LG); // cosmetics
+  def LGG = groebner(LG); // cosmetics
+  int d = dim(LGG);
+  int Ddim = d;
+  printf("the D-dimension is %s",d);
+  if (d==0)
+  {
+    d = vdim(LGG);
+    int Dvdim = d;
+    printf("the K-dimension is %s",d);
+  }
+  //  ideal SLG = simplify(LG,8+32); //contains zeros
+  def SLG = simplify(LG,8+32); //contains zeros
+  setring save;
+  //  ideal SLG = imap(@RAT,SLG);
+  def SLG = imap(@RAT,SLG);
+  // simplify(LG,8+32); //contains zeros
+  intvec islg;
+  if (SLG[1] == 0)
+  {  islg = 0;  }
+  else
+  {    islg = 1;  }
+  for (i=2; i<= ncols(SLG); i++)
+  {
+    if (SLG[i] == 0)
+    {
+      islg = islg, 0;
+    }
+    else
+    {
+      islg = islg, 1;
+    }
+  }
+  for (i=1; i<= ncols(LG); i++)
+  {
+    if (islg[i] == 0)
+    {
+      G[i] = 0;
+    }
+  }
+  G = simplify(G,2); // ready!
+  //  G = imap(@RAT,CG);
+  // return the result
+  //  ideal pGBid = G;
+  def pGBid = G;
+  export pGBid;
+  //  export Ddim;
+  //  export Dvdim;
+  setring @RAT;
+  //  ideal rGBid = imap(save,G);
+  def rGBid = imap(save,G);
+  // CG;
+  export rGBid;
+  setring save;
+  return(@RAT);
+  //  kill @RAT;
+  //  return(G);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = (0,c),(x,y,Dx,Dy),(a(0,0,1,1),a(0,0,1,0),dp);
+  // this ordering is an antiblock ordering, as it must be
+  def S = Weyl(); setring S;
+  // the ideal I below annihilates parametric Appel F4 function
+  // where we set parameters to a=-2, b=-1 and d=0
+  ideal I =
+    x*Dx*(x*Dx+c-1) - x*(x*Dx+y*Dy-2)*(x*Dx+y*Dy-1),
+    y*Dy*(y*Dy-1) - y*(x*Dx+y*Dy-2)*(x*Dx+y*Dy-1);
+  int is = 2; // hence 1st and 2nd variables, that is x and y
+  // will become invertible in the localization
+  def A = ratstd(I,2); // main call
+  pGBid; // polynomial form of the basis in the localized ring
+  setring A; // A is a commutative ring used for presentation
+  rGBid; // "rational" or "localized" form of the basis
+  //--- Now, let us compute a K(x,y) basis explicitly
+  print(matrix(kbase(rGBid)));
+}
+
+/*
+oldExampleForDoc()
+{
+  // VL: removed since it's too easy
+  ring r = 0,(k,n,K,N),(a(0,0,1,1),a(0,0,1,0),dp);
+  // note, that the ordering must be an antiblock ordering
+  matrix D[4][4]; D[1,3] = K; D[2,4] = N;
+  def S = nc_algebra(1,D);
+  setring S; // S is the 2nd shift algebra
+  ideal I = (k+1)*K - (n-k), (n-k+1)*N - (n+1);
+  int is = 2; // hence 1..2 variables will be treated as invertible
+  def A  = ratstd(I,is);
+  pGBid; // polynomial form
+  setring A;
+  rGBid; // rational form
+}
+*/
+
+/*
+exParamAppelF4()
+{
+  // Appel F4
+  LIB "ratgb.lib";
+  ring r = (0,a,b,c,d),(x,y,Dx,Dy),(a(0,0,1,1),a(0,0,1,0),dp);
+  matrix @D[4][4];
+  @D[1,3]=1; @D[2,4]=1;
+  def S=nc_algebra(1, at D);
+  setring S;
+  ideal I =
+    x*Dx*(x*Dx+c-1) - x*(x*Dx+y*Dy+a)*(x*Dx+y*Dy+b),
+    y*Dy*(y*Dy+d-1) - y*(x*Dx+y*Dy+a)*(x*Dx+y*Dy+b);
+  def A = ratstd(I,2);
+  pGBid; // polynomial form
+  setring A;
+  rGBid; // rational form
+  // hence, the K(x,y) basis is {1,Dx,Dy,Dy^2}
+}
+
+// more examples:
+
+// F1 is hard
+appel F1
+{
+  LIB "dmodapp.lib";
+  LIB "ratgb.lib";
+  def A = appelF1();
+  setring A;
+  IAppel1;
+  def F1 = ratstd(IAppel1,2);
+  lead(pGBid);
+  setring F1; rGBid;
+}
+
+// F2 is much easier
+appel F2
+{
+  LIB "dmodapp.lib";
+  LIB "ratgb.lib";
+  def A = appelF2();
+  setring A;
+  IAppel2;
+  def F1 = ratstd(IAppel2,2);
+  lead(pGBid);
+  setring F1; rGBid;
+}
+
+// F4 is feasible
+appel F4
+{
+  LIB "dmodapp.lib";
+  LIB "ratgb.lib";
+  def A = appelF4();
+  setring A;
+  IAppel4;
+  def F1 = ratstd(IAppel4,2);
+  lead(pGBid);
+  setring F1; rGBid;
+}
+
+
+*/
+
+// Important: example for treating modules
+// take two annihilators in 2 components
+
+/*
+  LIB "nctools.lib";
+  ring r = (0,c),(x,y,Dx,Dy),(a(0,0,1,1),a(0,0,1,0),dp);
+  // this ordering is an antiblock ordering, as it must be
+  def S = Weyl(); setring S;
+  // the ideal I below annihilates parametric Appel F4 function
+  // where we set parameters to a=-2, b=-1 and d=0
+  ideal I =
+    x*Dx*(x*Dx+c-1) - x*(x*Dx+y*Dy-2)*(x*Dx+y*Dy-1),
+    y*Dy*(y*Dy-1) - y*(x*Dx+y*Dy-2)*(x*Dx+y*Dy-1);
+
+  // the ideal J below annihilates parametric Appel F4 function
+  // where we set parameters to a=0, b=-1, c=0, d=0
+
+  ideal J =
+    x*Dx*(x*Dx-1) - x*(x*Dx+y*Dy)*(x*Dx+y*Dy-1),
+    y*Dy*(y*Dy-1) - y*(x*Dx+y*Dy)*(x*Dx+y*Dy-1);
+
+  module M = I*gen(1), J*gen(2);
+
+// harder modification: M = M, Dx*gen(1) + Dy*gen(2);
+// gives K(x,y)-dim 3
+
+  int is = 2; // hence 1st and 2nd variables, that is x and y
+  // will become invertible in the localization
+  def A = ratstd(M,2); // main call
+  pGBid; // polynomial form of the basis in the localized ring
+  setring A;
+  // we see from computations, that the K(x,y) dimension is 8
+  rGBid; // "rational" or "localized" form of the basis
+  print(matrix(kbase(rGBid)));// we see  the K(x,y) basis of the corr. module
+
+*/
diff --git a/Singular/LIB/realclassify.lib b/Singular/LIB/realclassify.lib
new file mode 100644
index 0000000..3d6a795
--- /dev/null
+++ b/Singular/LIB/realclassify.lib
@@ -0,0 +1,817 @@
+////////////////////////////////////////////////////////////////////////////
+version="version realclassify.lib 4.0.0.0 Jun_2013 "; // $Id: 304c900973a128db7524e71def15982bf895ee09 $
+category="Singularities";
+info="
+LIBRARY:  realclassify.lib   Classification of real singularities
+AUTHOR:   Magdaleen Marais,  magdaleen at aims.ac.za
+          Andreas Steenpass, steenpass at mathematik.uni-kl.de
+
+OVERVIEW:
+   A library for classifying isolated hypersurface singularities over the reals
+   w.r.t. right equivalence, based on the determinator of singularities by
+   V.I. Arnold. This library is based on classify.lib by Kai Krueger, but
+   handles the real case, while classify.lib does the complex classification.
+
+REFERENCES:
+Arnold, Varchenko, Gusein-Zade: Singularities of Differentiable Maps.
+Vol. 1: The classification of critical points caustics and wave fronts.
+Birkh\"auser, Boston 1985
+
+Greuel, Lossen, Shustin: Introduction to singularities and deformations.
+Springer, Berlin 2007
+
+PROCEDURES:
+ realclassify(f);    real classification of singularities of modality 0 and 1
+ realmorsesplit(f);  splitting lemma in the real case
+ milnornumber(f);    Milnor number
+ determinacy(f);     an upper bound for the determinacy
+";
+
+LIB "linalg.lib";
+LIB "elim.lib";
+LIB "primdec.lib";
+LIB "classify.lib";
+LIB "rootsur.lib";
+LIB "rootsmr.lib";
+LIB "atkins.lib";
+LIB "solve.lib";
+///////////////////////////////////////////////////////////////////////////////
+proc realclassify(poly f, list #)
+"
+USAGE:    realclassify(f[, format]); f poly, format string
+RETURN:   A list containing (in this order)
+          @* - the type of the singularity as a string,
+          @* - the normal form,
+          @* - the corank, the Milnor number, the inertia index and
+               a bound for the determinacy as integers.
+          @* The normal form involves parameters for singularities of modality
+             greater than 0. The actual value of the parameters is not computed
+             in most of the cases. If the value of the parameter is unknown,
+             the normal form is given as a string with an \"a\" as the
+             parameter. Otherwise, it is given as a polynomial.
+          @* An optional string @code{format} can be provided. Its default
+             value is \"short\" in which case the return value is the list
+             described above. If set to \"nice\", a string is added at the end
+             of this list, containing the result in a more readable form.
+NOTE:     The classification is done over the real numbers, so in contrast to
+          classify.lib, the signs of coefficients of monomials where even
+          exponents occur matter.
+          @* The ground field must be Q (the rational numbers). No field
+             extensions of any kind nor floating point numbers are allowed.
+          @* The monomial order must be local.
+          @* The input polynomial must be contained in maxideal(2) and must be
+             an isolated singularity of modality 0 or 1. The Milnor number is
+             checked for being finite.
+SEE ALSO: classify
+KEYWORDS: Classification of singularities
+EXAMPLE:  example realclassify; shows an example"
+{
+  /* auxiliary variables */
+  int i, j;
+
+  /* name for the basering */
+  def br = basering;
+
+  /* read optional parameters */
+  int printcomments;
+  if(size(#) > 0)
+  {
+    if(size(#) > 1 || typeof(#[1]) != "string")
+    {
+      ERROR("Wrong optional parameters.");
+    }
+    if(#[1] != "short" && #[1] != "nice")
+    {
+      ERROR("Wrong optional parameters.");
+    }
+    if(#[1] == "nice")
+    {
+      printcomments = 1;
+    }
+  }
+
+  /* error check */
+  if(charstr(br) != "0")
+  {
+    ERROR("The ground field must be Q (the rational numbers).");
+  }
+  int n = nvars(br);
+  for(i = 1; i <= n; i++)
+  {
+    if(var(i) > 1)
+    {
+      ERROR("The monomial order must be local.");
+    }
+  }
+  if(jet(f, 1) != 0)
+  {
+    ERROR("The input polynomial must be contained in maxideal(2).");
+  }
+
+  /* compute Milnor number before continuing the error check */
+  int mu = milnornumber(f);
+
+  /* continue error check */
+  if(mu < 1)
+  {
+    ERROR("The Milnor number of the input polynomial must be"+newline
+      +"positive and finite.");
+  }
+
+  /* call classify before continuing the error check */
+  list dataFromClassify = prepRealclassify(f);
+  int m = dataFromClassify[1];                // the modality of f
+  string complextype = dataFromClassify[2];   // the complex type of f
+
+  /* continue error check */
+  if(m > 1)
+  {
+    ERROR("The input polynomial must be a singularity of modality 0 or 1.");
+  }
+
+  /* apply splitting lemma */
+  list morse = realmorsesplit(f, mu);
+  int cr = morse[1];
+  int lambda = morse[2];
+  int d = morse[3];
+  poly rf = morse[4];
+
+  /* determine the type */
+  string typeofsing;
+  poly nf;
+  poly monparam;   // the monomial whose coefficient is the parameter
+                   // in the modality 1 cases, 0 otherwise
+  string morecomments = newline;
+
+  if(cr == 0)   // case A[1]
+  {
+    typeofsing, nf = caseA1(rf, lambda, n);
+  }
+  if(cr == 1)   // case A[k], k > 1
+  {
+    typeofsing, nf = caseAk(rf, n);
+  }
+  if(cr == 2)
+  {
+    if(complextype[1,2] == "D[")   // case D[k]
+    {
+      if(mu == 4)   // case D[4]
+      {
+        typeofsing, nf = caseD4(rf);
+      }
+      else   // case D[k], k > 4
+      {
+        typeofsing, nf = caseDk(rf, mu);
+      }
+    }
+    if(complextype == "E[6]")   // case E[6]
+    {
+      typeofsing, nf = caseE6(rf);
+    }
+    if(complextype == "E[7]")   // case E[7]
+    {
+      typeofsing, nf = caseE7();
+    }
+    if(complextype == "E[8]")   // case E[8]
+    {
+      typeofsing, nf = caseE8();
+    }
+    if(typeofsing == "")
+    {
+      ERROR("This case is not yet implemented.");
+    }
+  }
+  if(cr > 2)
+  {
+    ERROR("This case is not yet implemented.");
+  }
+
+  /* add the non-corank variables to the normal forms */
+  nf = addnondegeneratevariables(nf, lambda, cr);
+
+  /* write normal form as a string in the cases with modality greater than 0 */
+  if(monparam != 0)
+  {
+    poly nf_tmp = nf;
+    kill nf;
+    def nf = modality1NF(nf_tmp, monparam);
+  }
+
+  /* write comments */
+  if(printcomments)
+  {
+    string comments = newline;
+    comments = comments+"Type of singularity: "   +typeofsing    +newline
+                       +"Normal form:         "   +string(nf)    +newline
+                       +"Corank:              "   +string(cr)    +newline
+                       +"Milnor number:       "   +string(mu)    +newline
+                       +"Inertia index:       "   +string(lambda)+newline
+                       +"Determinacy:         <= "+string(d)     +newline;
+    if(morecomments != newline)
+    {
+      comments = comments+morecomments;
+    }
+  }
+
+  /* return results */
+  if(printcomments)
+  {
+    return(list(typeofsing, nf, cr, mu, lambda, d, comments));
+  }
+  else
+  {
+    return(list(typeofsing, nf, cr, mu, lambda, d));
+  }
+}
+example
+{
+  "EXAMPLE:";
+  echo = 2;
+  ring r = 0, (x,y,z), ds;
+  poly f = (x2+3y-2z)^2+xyz-(x-y3+x2z3)^3;
+  realclassify(f, "nice");
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static proc caseA1(poly rf, int lambda, int n)
+{
+  string typeofsing = "A[1]";
+  poly nf = 0;
+  return(typeofsing, nf);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static proc caseAk(poly rf, int n)
+{
+  /* preliminaries */
+  string typeofsing;
+  poly nf;
+
+  int k = deg(lead(rf), 1:n)-1;
+  if(k%2 == 0)
+  {
+    nf = var(1)^(k+1);
+    typeofsing = "A["+string(k)+"]";
+  }
+  else
+  {
+    if(leadcoef(rf) > 0)
+    {
+      nf = var(1)^(k+1);
+      typeofsing = "A["+string(k)+"]+";
+    }
+    else
+    {
+      nf = -var(1)^(k+1);
+      typeofsing = "A["+string(k)+"]-";
+    }
+  }
+  return(typeofsing, nf);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static proc caseD4(poly rf)
+{
+  /* preliminaries */
+  string typeofsing;
+  poly nf;
+  def br = basering;
+  map phi;
+
+  rf = jet(rf, 3);
+  number s1 = number(rf/(var(1)^3));
+  number s2 = number(rf/(var(2)^3));
+  if(s2 == 0 && s1 != 0)
+  {
+    phi = br, var(2), var(1);
+    rf = phi(rf);
+  }
+  if(s1 == 0 && s2 == 0)
+  {
+    number t1 = number(rf/(var(1)^2*var(2)));
+    number t2 = number(rf/(var(2)^2*var(1)));
+    if(t1+t2 == 0)
+    {
+      phi = br, var(1)+2*var(2), var(2);
+      rf = phi(rf);
+    }
+    else
+    {
+      phi = br, var(1)+var(2), var(2);
+      rf = phi(rf);
+    }
+  }
+  ring R = 0, y, dp;
+  map phi = br, 1, y;
+  poly rf = phi(rf);
+  int k = nrroots(rf);
+  setring(br);
+  if(k == 3)
+  {
+    nf = var(1)^2*var(2)-var(2)^3;
+    typeofsing = "D[4]-";
+  }
+  else
+  {
+    nf = var(1)^2*var(2)+var(2)^3;
+    typeofsing = "D[4]+";
+  }
+  return(typeofsing, nf);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static proc caseDk(poly rf, int mu)
+{
+  /* preliminaries */
+  string typeofsing;
+  poly nf;
+  def br = basering;
+  map phi;
+
+  rf = jet(rf, mu-1);
+  list factorization = factorize(jet(rf, 3));
+  list factors = factorization[1][2];
+  if(factorization[2][2] == 2)
+  {
+    factors = insert(factors, factorization[1][3], 1);
+  }
+  else
+  {
+    factors = insert(factors, factorization[1][3]);
+  }
+  factors[2] = factorization[1][1]*factors[2];
+  matrix T[2][2] = factors[1]/var(1), factors[1]/var(2),
+         factors[2]/var(1), factors[2]/var(2);
+  phi = br, luinverse(T)[2]*matrix(ideal(var(1), var(2)), 2, 1);
+  rf = phi(rf);
+  rf = jet(rf, mu-1);
+  poly g;
+  int i;
+  for(i = 4; i < mu; i++)
+  {
+    g = jet(rf, i) - var(1)^2*var(2);
+    if(g != 0)
+    {
+      phi = br, var(1)-(g/(var(1)*var(2)))/2,
+          var(2)-(g/var(1)^i)*var(1)^(i-2);
+      rf = phi(rf);
+      rf = jet(rf, mu-1);
+    }
+  }
+  number a = number(rf/var(2)^(mu-1));
+  if(a > 0)
+  {
+    typeofsing = "D["+string(mu)+"]+";
+    nf = var(1)^2*var(2)+var(2)^(mu-1);
+  }
+  else
+  {
+    typeofsing = "D["+string(mu)+"]-";
+    nf = var(1)^2*var(2)-var(2)^(mu-1);
+  }
+  return(typeofsing, nf);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static proc caseE6(poly rf)
+{
+  /* preliminaries */
+  string typeofsing;
+  poly nf;
+  def br = basering;
+  map phi;
+
+  poly g = jet(rf,3);
+  number s = number(g/(var(1)^3));
+  if(s == 0)
+  {
+    phi = br, var(2), var(1);
+    rf = phi(rf);
+    g = jet(rf,3);
+  }
+  list Factors = factorize(g);
+  poly g1 = Factors[1][2];
+  phi = br, (var(1)-(g1/var(2))*var(2))/(g1/var(1)), var(2);
+  rf = phi(rf);
+  rf = jet(rf,4);
+  number w = number(rf/(var(2)^4));
+  if(w > 0)
+  {
+    typeofsing = "E[6]+";
+    nf = var(1)^3+var(2)^4;
+  }
+  else
+  {
+    typeofsing = "E[6]-";
+    nf = var(1)^3-var(2)^4;
+  }
+  return(typeofsing, nf);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static proc caseE7()
+{
+  string typeofsing = "E[7]";
+  poly nf = var(1)^3+var(1)*var(2)^3;
+  return(typeofsing, nf);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static proc caseE8()
+{
+  string typeofsing = "E[8]";
+  poly nf = var(1)^3+var(2)^5;
+  return(typeofsing, nf);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/*
+  print the normal form as a string for the modality 1 cases.
+  The first argument is the normalform with parameter = 1,
+  the second argument is the monomial whose coefficient is the parameter.
+*/
+static proc modality1NF(poly nf, poly monparam)
+{
+  def br = basering;
+  list lbr = ringlist(br);
+  ring r = (0,a), x, dp;
+  list lr = ringlist(r);
+  setring(br);
+  list lr = fetch(r, lr);
+  lbr[1] = lr[1];
+  def s = ring(lbr);
+  setring(s);
+  poly nf = fetch(br, nf);
+  poly monparam = fetch(br, monparam);
+  nf = nf+(a-1)*monparam;
+  string result = string(nf);
+  setring(br);
+  return(result);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/*
+  add squares of the non-degenerate variables (i.e. var(cr+1), ...,
+  var(nvars(basering)) for corank cr) to the normalform nf,
+  with signs according to the inertia index lambda
+*/
+static proc addnondegeneratevariables(poly nf, int lambda, int cr)
+{
+  int n = nvars(basering);
+  int i;
+  for(i = cr+1; i <= n-lambda; i++)
+  {
+    nf = nf+var(i)^2;
+  }
+  for(i = n-lambda+1; i <= n ; i++)
+  {
+    nf = nf-var(i)^2;
+  }
+  return(nf);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+proc realmorsesplit(poly f, list #)
+"
+USAGE:    realmorsesplit(f[, mu]); f poly, mu int
+RETURN:   a list consisting of the corank of f, the inertia index, an upper
+          bound for the determinacy, and the residual form of f
+NOTE:     The characteristic of the basering must be zero, the monomial order
+          must be local, f must be contained in maxideal(2) and the Milnor
+          number of f must be finite.
+          @* The Milnor number of f can be provided as an optional parameter in
+             order to avoid that it is computed again.
+SEE ALSO: morsesplit
+KEYWORDS: Morse lemma; Splitting lemma
+EXAMPLE:  example morsesplit; shows an example"
+{
+  int i;
+
+  /* error check */
+  if(char(basering) != 0)
+  {
+    ERROR("The characteristic must be zero.");
+  }
+  int n = nvars(basering);
+  for(i = 1; i <= n; i++)
+  {
+    if(var(i) > 1)
+    {
+      ERROR("The monomial order must be local.");
+    }
+  }
+  if(jet(f, 1) != 0)
+  {
+    ERROR("The input polynomial must be contained in maxideal(2).");
+  }
+
+  /* get Milnor number before continuing error check */
+  int mu;
+  if(size(#) > 0)   // read optional parameter
+  {
+    if(size(#) > 1 || typeof(#[1]) != "int")
+    {
+      ERROR("Wrong optional parameters.");
+    }
+    else
+    {
+      mu = #[1];
+    }
+  }
+  else              // compute Milnor number
+  {
+    mu = milnornumber(f);
+  }
+
+  /* continue error check */
+  if(mu < 0)
+  {
+    ERROR("The Milnor number of the input polynomial must be"+newline
+      +"non-negative and finite.");
+  }
+
+  /* compute the determinacy */
+  int k = determinacy(f, mu);
+  f = jet(f, k);
+
+  /* get jet(f, 2) right */
+  matrix H = concat(jet(jacob(jacob(f)), 0)/2, unitmat(n));
+  H = sym_reduce(H);
+  intvec perm_zero;
+  intvec perm_neg;
+  intvec perm_pos;
+  int c;
+  int lambda;
+  for(i = 1; i <= n; i++)
+  {
+    if(H[i, i] == 0)
+    {
+      perm_zero = perm_zero, i;
+      c++;
+    }
+    if(H[i, i] < 0)
+    {
+      perm_neg = perm_neg, i;
+      lambda++;
+    }
+    if(H[i, i] > 0)
+    {
+      perm_pos = perm_pos, i;
+    }
+  }
+  intvec perm;
+  if(size(perm_zero) > 1)
+  {
+    perm = perm, perm_zero[2..size(perm_zero)];
+  }
+  if(size(perm_neg) > 1)
+  {
+    perm = perm, perm_neg[2..size(perm_neg)];
+  }
+  if(size(perm_pos) > 1)
+  {
+    perm = perm, perm_pos[2..size(perm_pos)];
+  }
+  perm = perm[2..size(perm)];
+  matrix T[n][n];
+  matrix D[1][n];
+  for(i = 1; i <= n; i++)
+  {
+    T[1..n, i] = H[perm[i], (n+1)..(2*n)];
+    D[1, i] = H[perm[i], perm[i]];
+  }
+  map phi = basering, matrix(maxideal(1))*transpose(T);
+  f = phi(f);
+  f = jet(f, k);
+
+  /* separate the variables */
+  phi = basering, maxideal(1);
+  map corank_part = basering, maxideal(1);
+  for(i = c+1; i <= n; i++)
+  {
+    corank_part[i] = 0;
+  }
+  poly h = f-jet(f, 2)-corank_part(f);
+  poly hi;
+  while(h != 0)
+  {
+    for(i = c+1; i <= n; i++)
+    {
+      hi = h/var(i);
+      phi[i] = var(i)-hi/(2*D[1, i]);
+      h = h-hi*var(i);
+    }
+    f = phi(f);
+    f = jet(f, k);
+    h = f-jet(f, 2)-corank_part(f);
+  }
+  poly g = f-jet(f, 2);
+  poly lead_g = leadcoef(g);
+  if(lead_g > 0)
+  {
+    g = g/lead_g;
+  }
+  if(lead_g < 0)
+  {
+    g = -g/lead_g;
+  }
+
+  return(list(c, lambda, k, g));
+}
+example
+{
+  "EXAMPLE:";
+  echo = 2;
+  ring r = 0, (x,y,z), ds;
+  poly f = (x2+3y-2z)^2+xyz-(x-y3+x2z3)^3;
+  realmorsesplit(f);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/*
+   symmetric Gauss algorithm
+
+   If A is not a square matrix, then the largest upper or left submatrix
+   is assumed to be symmetric.
+*/
+proc sym_reduce(matrix A)
+{
+  int r = nrows(A);
+  int c = ncols(A);
+  int n = r;
+  if(n > c)
+  {
+    n = c;
+  }
+  poly q;
+  int i, j;
+  for(i = 1; i <= n; i++)
+  {
+    for(j = i+1; j <= n; j++)
+    {
+      if(A[i, j] != 0)
+      {
+        while(A[i, i] == 0)
+        {
+          A[1..r, i] = A[1..r, i]+A[1..r, j];
+          A[i, 1..c] = A[i, 1..c]+A[j, 1..c];
+        }
+        q = A[i, j]/A[i, i];
+        A[1..r, j] = A[1..r, j]-q*A[1..r, i];
+        A[j, 1..c] = A[j, 1..c]-q*A[i, 1..c];
+      }
+    }
+  }
+  return(A);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/*
+   - apply jet(f, k)
+   - rewrite f as f = a*var(i)^2+p*var(i)+r with
+     var(i)-free p and r
+*/
+static proc rewriteformorsesplit(poly f, int k, int i)
+{
+  f = jet(f, k);
+  matrix C = coeffs(f, var(i));
+  poly r = C[1,1];
+  poly p = C[2,1];
+  poly a = (f-r-p*var(i))/var(i)^2;
+  return(f, a, p, r);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+proc milnornumber(poly f)
+"
+USAGE:    milnornumber(f); f poly
+RETURN:   Milnor number of f, or -1 if the Milnor number is not finite
+KEYWORDS: Milnor number
+NOTE:     The monomial order must be local.
+EXAMPLE:  example milnornumber; shows an example"
+{
+  /* error check */
+  int i;
+  for(i = nvars(basering); i > 0; i--)
+  {
+    if(var(i) > 1)
+    {
+      ERROR("The monomial order must be local.");
+    }
+  }
+
+  return(vdim(std(jacob(f))));
+}
+example
+{
+  "EXAMPLE:";
+  echo = 2;
+  ring r = 0, (x,y), ds;
+  poly f = x3+y4;
+  milnornumber(f);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+proc determinacy(poly f, list #)
+"
+USAGE:    determinacy(f[, mu]); f poly, mu int
+RETURN:   an upper bound for the determinacy of f
+NOTE:     The characteristic of the basering must be zero, the monomial order
+          must be local, f must be contained in maxideal(1) and the Milnor
+          number of f must be finite.
+          @* The Milnor number of f can be provided as an optional parameter in
+             order to avoid that it is computed again.
+SEE ALSO: milnornumber, highcorner
+KEYWORDS: Determinacy
+EXAMPLE:  example determinacy; shows an example"
+{
+  /* auxiliary variables */
+  int i;
+  def br = basering;
+
+  /* error check */
+  if(char(br) != 0)
+  {
+    ERROR("The characteristic must be zero.");
+  }
+  int n = nvars(br);
+  for(i = 1; i <= n; i++)
+  {
+    if(var(i) > 1)
+    {
+      ERROR("The monomial order must be local.");
+    }
+  }
+  if(jet(f, 0) != 0)
+  {
+    ERROR("The input polynomial must be contained in maxideal(1).");
+  }
+
+  /* get Milnor number before continuing error check */
+  int mu;
+  if(size(#) > 0)   // read optional parameter
+  {
+    if(size(#) > 1 || typeof(#[1]) != "int")
+    {
+      ERROR("Wrong optional parameters.");
+    }
+    else
+    {
+      mu = #[1];
+    }
+  }
+  else              // compute Milnor number
+  {
+    mu = milnornumber(f);
+  }
+
+  /* continue error check */
+  if(mu < 0)
+  {
+    ERROR("The Milnor number of the input polynomial must be"+newline
+      +"non-negative and finite.");
+  }
+
+  int k;   // an upper bound for the determinacy,
+           // we use several methods:
+
+  /* Milnor number */
+  k = mu+1;
+  f = jet(f, k);
+
+  /* highest corner */
+  int hc;
+  if(ordstr(br) != "ds")
+  {
+    list lbr = ringlist(br);
+    lbr[3] = list(list("ds", 1:nvars(br)), list("C", 0));
+    def br_ds = ring(lbr);
+    setring(br_ds);
+    poly f = fetch(br, f);
+  }
+  for(i = 0; i < 3; i++)
+  {
+    hc = deg(highcorner(std(maxideal(i)*jacob(f))));
+    hc = hc+2-i;
+    if(hc < k)
+    {
+      k = hc;
+      f = jet(f, k);
+    }
+  }
+  if(ordstr(br) != "ds")
+  {
+    setring(br);
+  }
+
+  return(k);
+}
+example
+{
+  "EXAMPLE:";
+  echo = 2;
+  ring r = 0, (x,y), ds;
+  poly f = x3+xy3;
+  determinacy(f);
+}
+
diff --git a/Singular/LIB/realizationMatroids.lib b/Singular/LIB/realizationMatroids.lib
new file mode 100644
index 0000000..a472d3e
--- /dev/null
+++ b/Singular/LIB/realizationMatroids.lib
@@ -0,0 +1,772 @@
+//////////////////////////////////////////////////////////////////////////
+version="version realizationMatroids.lib 4.0.0.0 Jun_2013 "; // $Id: 7c61e151b8c5acb9a757122ac09105728e170fb5 $
+category="Tropical Geometry";
+info="
+LIBRARY:  realizationMatroids.lib   Deciding Relative Realizability for Tropical Fan Curves in 2-Dimensional Matroidal Fans
+AUTHORS:  Anna Lena Winstel, winstel at mathematik.uni-kl.de
+OVERVIEW: In tropical geometry, one question to ask is the following: given a one-dimensional balanced polyhedral fan C which is set theoretically contained in the tropicalization trop(Y) of an algebraic variety Y, does there exist a curve X in Y such that trop(X) = C? This equality of C and trop(X) denotes an equality of both, the fans trop(X) and C and their weights on the maximal cones. The relative realization space of C with respect to Y is the space of all algebraic curves in Y whi [...]
+
+This library provides procedures deciding relative realizability for tropical fan curves, i.e. one-dimensional weighted balanced polyhedral fans, contained in two-dimensional matroidal fans trop(Y) where Y is a projective plane.
+
+NOTATION: If Y is a projective plane in (n-1)-dimensional projective space, we consider trop(Y) in R^n/<1>. Moreover, for the relative realization space of C with respect to Y we only consider algebraic curves of degree deg(C) in Y which tropicalize to C.
+
+PROCEDURES:
+
+realizationDim(I,C);          For a given tropical fan curve C in trop(Y), where Y = V(I) is a projective plane, this routine returns the dimension of the relative realization space of C with respect to Y, that is the space of all algebraic curves of degree deg(C) in Y which tropicalize to C. If the realization space is empty, the output is set to -1.
+
+irrRealizationDim(I,C);       This routine returns the dimension of the irreducible relative realization space of the tropical fan curve C with respect to Y = V(I), that is the space of all irreducible algebraic curves of degree deg(C) in Y which tropicalize to C. If the irreducible relative realization space is empty, the output is set to -1.
+
+realizationDimPoly(I,C);      If C is a tropical fan curve contained in the tropicalization trop(Y) of the projective plane Y = V(I) such that the relative realization space M of C is non-empty, this routine returns the tuple (dim(M),f) where f is an example of a homogeneous polynomial of degree deg(C) cutting out a curve X in Y which tropicalizes to C. If M is empty, the output is set to -1.
+
+";
+
+LIB "control.lib";
+LIB "qhmoduli.lib";
+
+static proc gcdvector(intvec v)
+{
+  int i;
+  int ggt = 0;
+  for(i=1;i<=size(v);i++)
+  {
+    ggt = gcd(ggt,v[i]);
+    if( ggt == 1 )
+    {
+      return(ggt);
+    }
+  }
+  return(ggt);
+}
+
+static proc balanced(list lInput)
+{
+  list ba;
+  int i;
+  int j;
+  if(size(lInput)>0)
+  {
+    for(i=1;i<=size(lInput[1]);i++)
+    {
+      ba[i] = 0;
+      for(j=1;j<=size(lInput);j++)
+      {
+        ba[i] = ba[i] + lInput[j][i];
+      }
+    }
+    int boolean = 1;
+    for(i=2;i<=size(ba);i++)
+    {
+      if(ba[i] != ba[1])
+      {
+        boolean = 0;
+      }
+    }
+    if(boolean == 1)
+    {
+      return(ba[1]);
+    }
+    else
+    {
+      return(0);
+    }
+  }
+  else
+  {
+    return(0);
+  }
+}
+
+static proc genPoly(int d, int i, int j, int k)
+{
+  int ii;
+  int ij;
+  int ik = 1;
+  poly f = 0;
+  for(ii=0;ii<=d;ii++)
+  {
+    for(ij=0;ij<=d-ii;ij++)
+    {
+       f = f + a(ik)*x(i)^(d-ii-ij)*x(j)^ij*x(k)^ii;
+       ik = ik + 1;
+    }
+  }
+  return(f);
+}
+
+static proc prodvar(int n)
+{
+  int i;
+  poly f = 1;
+  for(i=1;i<=n;i++)
+  {
+    f = f * x(i);
+  }
+  return(f);
+}
+
+static proc lessThan(int i, int j, intvec v, intvec w)
+{
+  number a = v[i];
+  number b = v[j];
+  number c = w[i];
+  number d = w[j];
+  if((a/b)<(c/d))
+  { return(1); }
+  else
+  { return(0); }
+}
+
+static proc sortSlope(int i, int j, list lInput)
+{
+  int k;
+  int l;
+  intvec v;
+  for(k=1;k<size(lInput);k++)
+  {
+    for(l=1;l<=size(lInput)-k;l++)
+    {
+      if(lessThan(i,j,lInput[l+1],lInput[l]))
+      {
+        v = lInput[l];
+        lInput[l] = lInput[l+1];
+        lInput[l+1] = v;
+      }
+    }
+  }
+  return(lInput);
+}
+
+static proc coefMonomial(poly f, poly g, int n)
+{
+  matrix m = coef(f,prodvar(n));
+  poly h;
+  for(int i=1;i<=ncols(m);i++)
+  {
+    if(m[1,i] == g)
+    {
+      h = m[2,i];
+    }
+  }
+  return(h);
+}
+
+static proc ismultiple(intvec v, intvec w)
+{
+  int boolean = 1;
+  if(v[1] != 0)
+  {
+    if((number(w[2]) == number(v[2])*number(w[1])/number(v[1])) and (number(w[3]) == number(v[3])*number(w[1])/number(v[1])))
+    {
+      return(1);
+    }
+    else
+    {
+      return(0);
+    }
+  }
+  else
+  {
+    if(v[2] != 0)
+    {
+      if((number(w[1]) == number(v[1])*number(w[2])/number(v[2])) and (number(w[3]) == number(v[3])*number(w[2])/number(v[2])))
+      {
+        return(1);
+      }
+      else
+      {
+        return(0);
+      }
+    }
+    else
+    {
+      if((w[2] == 0) and (w[1] == 0))
+      {
+        return(1);
+      }
+      else
+      {
+        return(0);
+      }
+    }
+  }
+}
+
+static proc simplifyList(list lInput);
+{
+  int i;
+  int k = size(lInput);
+  for(i=1;i<=k;i++)
+  {
+    if(lInput[i] == intvec(0,0,0))
+    {
+      lInput = delete(lInput,i);
+      k = k-1;
+      i = i-1;
+    }
+  }
+  k = size(lInput);
+  int j;
+  for(i=1;i<k;i++)
+  {
+    for(j=i+1;j<=k;j++)
+    {
+      if(ismultiple(lInput[i],lInput[j]))
+      {
+        lInput[i] = lInput[i] + lInput[j];
+        lInput = delete(lInput,j);
+        j = j-1;
+        k = k-1;
+      }
+    }
+  }
+  return(lInput);
+}
+
+static proc realizationDimIdeal(ideal iInput, list lInput)
+{
+  //normalize the vectors
+  intvec helpintvec = 1;
+  int i;
+  int c;
+  for(i=1;i<size(lInput[1]);i++)
+  {
+    helpintvec = helpintvec,1;
+  }
+  for(i=1;i<=size(lInput);i++)
+  {
+    lInput[i] = lInput[i] - Min(lInput[i])*helpintvec;
+  }
+
+  //check if the curve is balanced and compute its degree
+  int d = balanced(lInput);
+  if(d == 0)
+  {
+    printf("The curve is not balanced.");
+    return(-2);
+  }
+
+  //change basering, store the actual basering in a variable
+  def save = basering;
+  int n = size(lInput[1]);
+  int N = (d+2)*(d+1) div 2;
+  ring r1;
+  ring r = 0,(x(1..n),a(1..N),t),dp;
+  setring r;
+  ideal I = fetch(save,iInput);
+  I = std(I);
+
+  if(dim(I) != (4+N))
+  {
+    printf("The ideal is not defining a projective plane.");
+    return(-2);
+  }
+
+  //for any three variables, compute the projection
+  int i2;
+  int i3;
+  int i4;
+  int j;
+  int k;
+  int l;
+  int i_w;
+  int good;
+  int i_good = 0;
+  list P;
+  intvec v;
+  intvec w;
+  ideal E;
+  list NE;
+  list S1;
+  list S2;
+  list S3;
+  poly h;
+  poly g;
+  poly coefMon;
+  matrix F;
+  matrix G;
+  list listunitvec;
+  v = 1;
+  for(i=2;i<=n+N+1;i++)
+  {
+    v = v,0;
+  }
+  listunitvec = list(v);
+  for(i=2;i<=n;i++)
+  {
+    v = 0;
+    for(j=2;j<=n+N+1;j++)
+    {
+      if(i != j)
+      {
+        v = v,0;
+      }
+      else
+      {
+        v = v,1;
+      }
+    }
+    listunitvec = listunitvec + list(v);
+  }
+  intmat M[n+N+1][n+N+1];
+  for(i=n+1;i<=n+N+1;i++)
+  {
+    M[i,i] = 1;
+  }
+  int i_start;
+  list luv1;
+  intmat M1[n+N+1][n+N+1];
+  for(i=1;i<=n-2;i++)
+  {
+    for(j=i+1;j<=n-1;j++)
+    {
+      for(k=j+1;k<=n;k++)
+      {
+        //compute the algebraic projection
+        luv1 = listunitvec;
+        luv1 = delete(luv1,k);
+        luv1 = delete(luv1,j);
+        luv1 = delete(luv1,i);
+        luv1 = luv1 + list(listunitvec[i],listunitvec[j],listunitvec[k]);
+        M1 = M;
+        for(l=1;l<=size(luv1);l++)
+        {
+          M1[l,1..(n+N+1)] = luv1[l];
+        }
+        r1 = ring(0,(x(1..n),a(1..N),t),M(M1));
+        setring r1;
+        ideal Ir1 = fetch(r,I);
+        Ir1 = std(Ir1);
+        //check if this projection is "good"
+        good = 1;
+        ideal Ii = x(i);
+        ideal Ij = x(j);
+        ideal Ik = x(k);
+        for(l=1;l<=size(Ir1);l++)
+        {
+          if((reduce(lead(Ir1[l]),Ii) == 0) or (reduce(lead(Ir1[l]),Ij) == 0) or (reduce(lead(Ir1[l]),Ik) == 0))
+          {
+            good = 0;
+          }
+        }
+        if(good == 1)
+        {
+          //for the first "good" projection, initialise the general polynomial f
+          if(i_good == 0)
+          {
+            setring r;
+            poly f = genPoly(d,i,j,k);
+            setring r1;
+            i_good = 1;
+            intvec vgood = i,j,k;
+          }
+          poly fr1 = fetch(r,f);
+          poly hr1 = reduce(fr1,Ir1);
+          setring r;
+          h = fetch(r1,hr1);
+          //compute the tropical projection
+          P = list();
+          for(l=1;l<=size(lInput);l++)
+          {
+            v = lInput[l][i],lInput[l][j],lInput[l][k];
+            P[l] = v;
+          }
+          P = simplifyList(P);
+          //collect the conditions coming from the Newton polytopes
+          S1 = list();
+          S2 = list();
+          S3 = list();
+          for(l=1;l<=size(P);l++)
+          {
+            if((P[l][1] != 0) and (P[l][2] != 0))
+            { S3 = S3 + list(P[l]); }
+            if((P[l][2] != 0) and (P[l][3] != 0))
+            { S1 = S1 + list(P[l]); }
+            if((P[l][1] != 0) and (P[l][3] != 0))
+            { S2 = S2 + list(P[l]); }
+          }
+          //sort the lists
+          S1 = sortSlope(3,2,S1);
+          S2 = sortSlope(1,3,S2);
+          S3 = sortSlope(2,1,S3);
+          //find conditions from S1
+          i_start = 0;
+          for(l=1;l<=size(S1);l++)
+          {
+            i_start = i_start + S1[l][2];
+          }
+          //find starting point
+          w = intvec(0,i_start);
+          coefMon = coefMonomial(h,x(k)^(w[2])*x(i)^(d-w[2]),n);
+          NE = NE + list(coefMon);
+          for(i2=1;i2<=size(S1);i2++)
+          {
+            w[1] = w[1] + S1[i2][3];
+            w[2] = w[2] - S1[i2][2];
+            coefMon = coefMonomial(h,x(k)^(w[2])*x(j)^(w[1])*x(i)^(d-w[1]-w[2]),n);
+            NE = NE + list(coefMon);
+            g = subst(h,x(j),x(j)*t^(S1[i2][2]),x(k),x(k)*t^(S1[i2][3]));
+            i_w = S1[i2][2]*w[1] + S1[i2][3]*w[2];
+            F = coeffs(g,t);
+            for(i3=1;i3<=i_w;i3++)
+            {
+              G = coef(F[i3,1],prodvar(n));
+              for(i4=1;i4<=ncols(G);i4++)
+              {
+                E = E + ideal(G[2,i4]);
+              }
+            }
+          }
+          //find conditions from S2
+          i_start = 0;
+          for(l=1;l<=size(S2);l++)
+          {
+            i_start = i_start + S2[l][3];
+          }
+          //find starting point
+          w = intvec(i_start,0);
+          coefMon = coefMonomial(h,x(i)^(w[1])*x(j)^(d-w[1]),n);
+          NE = NE + list(coefMon);
+          for(i2=1;i2<=size(S2);i2++)
+          {
+            w[1] = w[1] - S2[i2][3];
+            w[2] = w[2] + S2[i2][1];
+            coefMon = coefMonomial(h,x(i)^(w[1])*x(k)^(w[2])*x(j)^(d-w[1]-w[2]),n);
+            NE = NE + list(coefMon);
+            g = subst(h,x(i),x(i)*t^(S2[i2][1]),x(k),x(k)*t^(S2[i2][3]));
+            i_w = S2[i2][3]*w[2] + S2[i2][1]*w[1];
+            F = coeffs(g,t);
+            for(i3=1;i3<=i_w;i3++)
+            {
+              G = coef(F[i3,1],prodvar(n));
+              for(i4=1;i4<=ncols(G);i4++)
+              {
+                E = E + ideal(G[2,i4]);
+              }
+            }
+          }
+          //find conditions from S3
+          i_start = 0;
+          for(l=1;l<=size(S3);l++)
+          {
+            i_start = i_start + S3[l][1];
+          }
+          //find starting point
+          w = intvec(0,i_start);
+          coefMon = coefMonomial(h,x(j)^(w[2])*x(k)^(d-w[2]),n);
+          NE = NE + list(coefMon);
+          for(i2=1;i2<=size(S3);i2++)
+          {
+            w[1] = w[1] + S3[i2][2];
+            w[2] = w[2] - S3[i2][1];
+            coefMon = coefMonomial(h,x(i)^(w[1])*x(j)^(w[2])*x(k)^(d-w[1]-w[2]),n);
+            NE = NE + list(coefMon);
+            g = subst(h,x(i),x(i)*t^(S3[i2][1]),x(j),x(j)*t^(S3[i2][2]));
+            i_w = S3[i2][2]*w[2] + S3[i2][1]*w[1];
+            F = coeffs(g,t);
+            for(i3=1;i3<=i_w;i3++)
+            {
+              G = coef(F[i3,1],prodvar(n));
+              for(i4=1;i4<=ncols(G);i4++)
+              {
+                E = E + ideal(G[2,i4]);
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+
+  //check whether or not there is a common solution
+  setring r;
+  int isRealizable = 1;
+  E = std(E);
+  int i_dim = dim(E)-n-2;
+  for(i=1;i<=size(NE);i++)
+  {
+    if(reduce(NE[i],E) == 0)
+    {
+      isRealizable = 0;
+    }
+  }
+
+  if(isRealizable == 1)
+  {
+    setring save;
+    return(i_dim,fetch(r,E),fetch(r,NE),vgood);
+  }
+  else
+  {
+    return(-1);
+  }
+}
+
+proc realizationDim(ideal iInput, list lInput)
+"USAGE:   realizationDim(I,C); where I is a homogeneous linear ideal defining the projective plane Y = V(I) and C is a list of intvectors such that each intvector represents a one-dimensional cone in the tropical fan curve whose relative realizability should be checked. This representation is done in the following way: the one-dimensional cone K is represented by a vector w whose equivalence class [w] in R^n/<1> can be written as [w] = m*[v] where [v] is the primitive generator of K and  [...]
+RETURNS:  the dimension of the relative realization space of the tropical curve C with respect to Y, and -1 if the relative realization space is empty.
+EXAMPLE:  realizationDim; shows an example"
+{
+  int ret = list(realizationDimIdeal(iInput,lInput))[1];
+  if(ret[1] == -2)
+  {
+    printf("WARNING: no computation possible, return value is not meaningful!");
+    return(-2);
+  }
+  else
+  {
+    return(ret);
+  }
+}
+example
+{
+  "EXAMPLE:"; echo=2;
+  ring r = 0,(x(1..4)),dp;
+  ideal I = x(1)+x(2)+x(3)+x(4);
+  list C = list(intvec(2,2,0,0),intvec(0,0,2,1),intvec(0,0,0,1));
+  //C represents the tropical fan curve which consists of the cones
+  //cone([(1,1,0,0)]) (with weight 2), cone([(0,0,2,1)]) (with weight 1)
+  //and cone([(0,0,0,1)]) (with weight 1)
+  realizationDim(I,C);
+}
+
+proc irrRealizationDim(ideal iInput, list lInput)
+"USAGE:   irrRealizationDim(I,C); where I is a homogeneous linear ideal defining the projective plane Y = V(I) and C is a list of intvectors such that each intvector represents a one-dimensional cone in the tropical fan curve whose irreducible relative realizability should be checked. This representation is done in the following way: a one-dimensional cone K is represented by a vector w whose equivalence class [w] in R^n/<1> can be written as [w] = m*[v] where [v] is the primitive genera [...]
+RETURNS:  the dimension of the irreducible relative realization space of C with respect to Y, and -1 if the irreducible realization space is empty.
+EXAMPLE:  irrRealizationDim; shows an example"
+{
+  int i;
+  int i_dim = realizationDim(iInput,lInput);
+  if(i_dim > -1)
+  {
+    //check if also realizable by an irreducible curve
+    list lweight;
+    int i_rdim = -1;
+    //substitute the vectors by a primitve one and store the multiplicities
+    for(i=1;i<=size(lInput);i++)
+    {
+      lweight[i] = gcdvector(lInput[i]);
+      lInput[i] = lInput[i] div lweight[i];
+    }
+    //find all decompositions into two tropical curves
+    intvec tm;
+    for(i=1;i<=size(lInput);i++)
+    {
+      tm[i] = 0;
+    }
+    int na;
+    list C1;
+    list C2;
+    int dimC1;
+    int dimC2;
+    while(na==0)
+    {
+      na = 1;
+      for(i=1;i<=size(lInput);i++)
+      {
+        if(tm[i] < lweight[i])
+        {
+          tm[i] = tm[i]+1;
+          na = 0;
+          i = size(lInput);
+        }
+        else
+        {
+          tm[i] = 0;
+        }
+      }
+      if(na == 0)
+      {
+        C1 = list();
+        C2 = list();
+        for(i=1;i<=size(lInput);i++)
+        {
+          if(tm[i] > 0)
+          {
+            C1 = C1 + list(tm[i]*lInput[i]);
+            if(tm[i] < lweight[i])
+            {
+              C2 = C2 + list((lweight[i]-tm[i])*lInput[i]);
+            }
+          }
+          else
+          {
+            C2 = C2 + list(lweight[i]*lInput[i]);
+          }
+        }
+        if((balanced(C2) != 0) and (balanced(C2) <= balanced(C1)))
+        {
+          dimC1 = realizationDim(iInput,C1);
+          dimC2 = realizationDim(iInput,C2);
+          if((dimC1 >= 0) and (dimC2 >= 0))
+          {
+            i_rdim = Max(intvec(i_rdim,dimC1 + dimC2));
+          }
+        }
+      }
+    }
+    if(i_rdim < i_dim)
+    {
+      return(i_dim);
+    }
+    else
+    {
+      return(-1);
+    }
+  }
+  else
+  {
+    return(-1);
+  }
+}
+example
+{
+  "EXAMPLE:"; echo=2;
+  ring r = 0,(x(1..4)),dp;
+  ideal I = x(1)+x(2)+x(3)+x(4);
+  list C = list(intvec(2,2,0,0),intvec(0,0,2,2));
+  //C represents the tropical fan curve which consists of the cones
+  //cone([(1,1,0,0)]) and cone([(1,1,0,0)]), both with weight 2
+  realizationDim(I,C);
+  irrRealizationDim(I,C);
+}
+
+proc realizationDimPoly(ideal iInput, list lInput)
+"USAGE:   realizationDimPoly(I,C); where I is a homogeneous linear ideal defining the projective plane Y = V(I) and C is a list of intvectors such that each intvector represents a one-dimensional cone in the tropical fan curve whose relative realizability should be checked. This representation is done in the following way: the one-dimensional cone K is represented by a vector w whose equivalence class [w] in R^n/<1> can be written as [w] = m*[v] where [v] is the primitive generator of K  [...]
+RETURNS:  If the relative realization space of the tropical fan curve C is non-empty, this routine returns the tuple (r,f), where r is the dimension of the relative realization space and f is an example of a homogeneous polynomial of degree deg(C) cutting out a curve X in Y which tropicalizes to C. In case the relative realization space is empty, the output is set to -1.
+EXAMPLE:  realizationDimPoly; shows an example"
+{
+  def save = basering;
+  int d = balanced(lInput);
+  int n = size(lInput[1]);
+  int N = (d+2)*(d+1) div 2;
+  int i;
+  ring r = 0,(x(1..n),a(1..N)),dp;
+  list ret = realizationDimIdeal(fetch(save,iInput),lInput);
+  int realdim = ret[1];
+  if(realdim != -1)
+  {
+    ideal E = ret[2];
+    list NE = ret[3];
+    E = std(E);
+    //find variables which are free to choose
+    intvec v;
+    for(i=1;i<=size(E);i++)
+    {
+      v = v + leadexp(E[i]);
+    }
+    int j;
+    int k;
+    int boolean;
+    ideal E1;
+    list NE1;
+    poly f;
+    poly g;
+    //initialize the list of the free variables
+    list lValues;
+    if(size(v) > 1)
+    {
+      for(j=1;j<=N;j++)
+      {
+        if(v[j+n] == 0)
+        {
+          lValues = lValues + list(list(a(j),0));
+        }
+      }
+    }
+    else
+    {
+      for(j=1;j<=N;j++)
+      {
+        lValues = lValues + list(list(a(j),0));
+      }
+    }
+    //try to find an easy solution
+    boolean = 1;
+    for(j=1;j<=size(lValues);j++)
+    {
+      if(boolean == 1)
+      {
+        lValues[j][2] = 0;
+      }
+      else
+      {
+        lValues[j][2] = lValues[j][2] + 1;
+      }
+      boolean = 1;
+      E1 = E;
+      for(i=1;i<=size(E1);i++)
+      {
+        for(k=1;k<=j;k++)
+        {
+          E1[i] = subst(E1[i],lValues[k][1],lValues[k][2]);
+        }
+      }
+      NE1 = NE;
+      for(i=1;i<=size(NE);i++)
+      {
+        for(k=1;k<=j;k++)
+        {
+          NE1[i] = subst(NE1[i],lValues[k][1],lValues[k][2]);
+        }
+      }
+      E1 = std(E1);
+      for(i=1;i<=size(NE1);i++)
+      {
+        if(reduce(NE1[i],E1) == 0)
+        {
+          boolean = 0;
+        }
+      }
+      if(boolean == 0)
+      {
+        j = j-1;
+      }
+    }
+    //compute the values of the dependent variables
+    for(j=1;j<=size(E);j++)
+    {
+      f = E[j];
+      for(k=1;k<=size(lValues);k++)
+      {
+        f = subst(f,lValues[k][1],lValues[k][2]);
+      }
+      if(leadcoef(f) != 1)
+      {
+        for(k=1;k<=size(lValues);k++)
+        {
+          lValues[k][2] = lValues[k][2] * leadcoef(f);
+        }
+      }
+      f = subst(f,leadmonom(f),0);
+      lValues = lValues + list(list(leadmonom(E[j]),-f));
+    }
+    g = genPoly(d,ret[4][1],ret[4][2],ret[4][3]);
+    for(j=1;j<=N;j++)
+    {
+      g = subst(g,lValues[j][1],lValues[j][2]);
+    }
+    setring save;
+    return(realdim,fetch(r,g));
+  }
+  else
+  {
+    return(-1);
+  }
+}
+example
+{
+  "EXAMPLE:"; echo=2;
+  ring r = 0,(x(1..4)),dp;
+  ideal I = x(1)+x(2)+x(3)+x(4);
+  list C = list(intvec(2,2,0,0),intvec(0,0,2,2));
+  //C represents the tropical fan curve which consists of the cones
+  //cone([(1,1,0,0)]) and cone([(1,1,0,0)]), both with weight 2
+  realizationDimPoly(I,C);
+  C = list(intvec(0,0,0,4),intvec(0,1,3,0),intvec(1,0,1,0),intvec(0,2,0,0),intvec(3,1,0,0));
+  //C represents the tropical fan curve which consists of the cones
+  //cone([(0,0,0,1)]) with weight 4,
+  //cone([(0,1,3,0)]), cone([(1,0,1,0)]) both with weight 1,
+  //cone([(0,1,0,0)]) with weight 2, and
+  //cone([(3,1,0,0)]) with weight 1
+  realizationDimPoly(I,C);
+}
diff --git a/Singular/LIB/realrad.lib b/Singular/LIB/realrad.lib
new file mode 100644
index 0000000..9965efb
--- /dev/null
+++ b/Singular/LIB/realrad.lib
@@ -0,0 +1,1211 @@
+////////////////////////////////////////////////////////////////////////////
+version="version realrad.lib 4.0.0.0 Jun_2013 "; // $Id: b275d949fd627253e5d17a85b63c4ebd815a42ed $
+category="real algebra";
+info="
+LIBRARY:  realrad.lib   Computation of real radicals
+AUTHOR :  Silke Spang
+
+OVERVIEW:
+   Algorithms about the computation of the real
+   radical of an arbitary ideal over the rational numbers
+   and transcendetal extensions thereof
+
+PROCEDURES:
+ realpoly(f);     Computes the real part of the univariate polynomial f
+ realzero(j);     Computes the real radical of the zerodimensional ideal j
+ realrad(j);      Computes the real radical of an arbitary ideal over
+                  transcendental extension of the rational numbers
+";
+
+LIB "inout.lib";
+LIB "poly.lib";
+LIB "matrix.lib";
+LIB "general.lib";
+LIB "rootsur.lib";
+LIB "algebra.lib";
+LIB "standard.lib";
+LIB "primdec.lib";
+LIB "elim.lib";
+
+///////////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+//// the main procedure //////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+proc realrad(ideal id)
+"USAGE: realrad(id), id an ideal of arbitary dimension
+RETURN: the real radical of id
+EXAMPE: example realrad; shows an example"
+{
+
+  def r=basering;
+  int n=nvars(basering);
+  // for faster Groebner basis and dimension compuations
+  string neuring ="ring schnell=("+charstr(r)+"),("+varstr(r)+"),dp;";
+  execute(neuring);
+  def ri=basering;
+
+  list reddim;//reduct dimension to 0
+  list lpar,lvar,sub;//for the ringchange
+  string pari,vari;
+  int i,siz,l,j;
+  string less="list lessvar="+varstr(r)+";";
+  execute(less);
+  ideal id=imap(r,id);
+  l=size(id);
+  for (i=1;i<=l;i++)
+  {
+    id[i]=simplify_gen(id[i]);
+  }
+  id=groebner(id);
+  if (dim(id)<=0)
+  {
+    id=realzero(id);
+    setring r;
+    id=imap(ri,id);
+    return(id);
+  }
+  //sub are the subsets of {x_1,...,x_n}
+  sub=subsets(n);
+  siz=size(sub)-1;//we dont want to localize on all variables
+
+  //for the empty set
+  reddim[1]=zeroreduct(id);
+  reddim[1]=realzero(reddim[1]);
+  for (i=1;i<=siz;i++)
+  {
+
+    lvar=lessvar;
+    lpar=list();
+    l=size(sub[i]);
+    for (j=1;j<=l;j++)
+    {
+      lpar=lpar+list(lvar[sub[i][j]-j+1]);
+      lvar=delete(lvar,sub[i][j]-j+1);
+    }
+    for(j=1;j<=l;j++)//there are l entries in lpar
+    {
+      pari=pari+","+string(lpar[j]);
+    }
+    l=n-l;//there are the remaining n-l entries in lvar
+    for(j=1;j<=l;j++)//there are l entries in lpar
+    {
+      vari=vari+","+string(lvar[j]);
+    }
+    vari=vari[2..size(vari)];
+    neuring="ring neu=("+charstr(r)+pari+"),("+vari+"),dp;";
+    execute(neuring);
+    ideal id=imap(r,id);
+    ideal buffer=zeroreduct(id);
+    buffer=realzero(buffer);
+    setring ri;
+    reddim[i+1]=imap(neu,buffer);
+    kill neu;
+    //compute the intersection of buffer with r
+    reddim[i+1]=contnonloc(reddim[i+1],pari,vari);
+    vari="";
+    pari="";
+  }
+  id=intersect(reddim[1..(siz+1)]);
+  //id=timeStd(id,301);//simplify the output
+  id=interred(id); // timeStd does not work yet
+  setring r;
+  id=imap(ri,id);
+  return(id);
+
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring r1=0,(x,y,z),lp;
+  //dimension 0
+  ideal i0=(x2+1)*(x3-2),(y3-2)*(y2+y+1),z3+2;
+  //dimension 1
+  ideal i1=(y3+3y2+y+1)*(y2+4y+4)*(x2+1),(x2+y)*(x2-y2)*(x2+2xy+y2)*(y2+y+1);
+  ideal i=intersect(i0,i1);
+  realrad(i);
+}
+
+
+/*static*/ proc zeroreduct(ideal i)
+"USAGE:zeroreduct(i), i an arbitary ideal
+RETURN: an ideal j of dimension <=0 s.th. i is contained in
+        j and j is contained in i_{Iso} which is the zariski closure
+        of all real isolated points of i
+"
+{
+ list equi;
+ int d,n,di;
+ n=nvars(basering);
+ def r=basering;
+
+ //chance ring to get faster groebner bases computation for dimensions
+
+ string rneu="ring neu=("+charstr(r)+"),("+varstr(r)+"),dp;";
+ execute(rneu);
+ ideal i=imap(r,i);
+
+ i=groebner(i);
+ while (dim(i)> 0)
+ {
+   equi=equidim(i);
+   d=size(equi);
+   equi[d]=radical(equi[d]);
+   di=dim(std(equi[d]));
+   equi[d]=equi[d],minor(jacob(equi[d]),n-di);
+   equi[d]=radical(equi[d]);
+   i=intersect(equi[1..d]);
+   i=groebner(i);
+ }
+
+ setring r;
+ i=imap(neu,i);
+ //i=timeStd(i,301);
+ i=interred(i); // timeStd does not work yet
+ return(i);
+}
+//////////////////////////////////////////////////////////////////////////////
+///////the zero-dimensional case /////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+proc realzero(ideal j)
+"USAGE:    realzero(j); a zero-dimensional ideal j
+RETURN:    j: a zero dimensional ideal, which is the real radical
+              of i, if dim(i)=0
+           0: otherwise
+           this acts via
+           primary decomposition (i=1)
+           listdecomp (i=2) or facstd (i=3)
+EXAMPLE:   example realzero; shows an example"
+
+
+{
+ list prim,prepared,nonshape,realu;
+ int r;//counter
+ int l;//number of first polynomial with degree >1 or even
+ l=size(j);
+ for (r=1;r<=l;r++)
+ {
+   j[r]=simplify_gen(j[r]);
+   if (j[r]==1)
+   {
+     return(ideal(1));
+   }
+ }
+ option(redSB);
+ //j=groebner(j);
+ //special case
+ //if (j==1)
+ //{
+ //  return(j);
+ //}
+ if (nvars(basering)==1)
+ {
+   j=groebner(j);
+   j=realpoly(j[1]);
+   return(j);
+ }
+
+
+ //if (dim(j)>0) {return(0);}
+
+ def r_alt=basering;
+ //store the ring
+ //for a ring chance to the ordering lp;
+ execute("ring r_neu =("+charstr(basering)+"),("+varstr(basering)+"),lp;");
+ setring r_neu;
+ ideal boeser,max;
+ prepared[1]=ideal(1);
+ ideal j=imap(r_alt,j);
+ //ideal j=fglm(r_alt,j);
+ prim=primdecGTZ(j);
+ for (r=1;r<=size(prim);r++)
+ {
+   max=prim[r][2];
+   max=groebner(max);
+   realu=prepare_max(max);
+   max=realu[1];
+   if (max!=1)
+   {
+     if (realu[2]==1)
+     {
+       prepared=insert(prepared,max);
+     }
+     else
+     {
+       nonshape=insert(nonshape,max);
+     }
+   }
+ }
+ j=intersect(prepared[1..size(prepared)]);
+
+ //use a variable change into general position to obtain
+ //the shape via radzero
+ if (size(nonshape)>0)
+ {
+   boeser=GeneralPos(nonshape);
+   j=intersect(j,boeser);
+ }
+ //j=timeStd(j,301);
+ j=interred(j); // timeStd does not work yet
+ setring r_alt;
+ j=fetch(r_neu,j);
+ return(j);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  //in non parametric fields
+  ring r=0,(x,y),dp;
+  ideal i=(y3+3y2+y+1)*(y2+4y+4)*(x2+1),(x2+y)*(x2-y2)*(x2+2xy+y2)*(y2+y+1);
+  realzero(i);
+  ideal j=(y3+3y2+y+1)*(y2-2y+1),(x2+y)*(x2-y2);
+  realzero(j);
+
+  //to get every path
+  ring r1=(0,t),(x,y),lp;
+  ideal m1=x2+1-t,y3+t2;
+  ideal m2=x2+t2+1,y2+t;
+  ideal m3=x2+1-t,y2-t;
+  ideal m4=x^2+1+t,y2-t;
+  ideal i=intersect(m1,m2,m3,m4);
+  realzero(i);
+
+}
+
+static proc GeneralPos(list buffer)
+"USAGE:    GeneralPos(buffer);
+           buffer a list of maximal ideals which failed the prepare_max-test
+RETURN:    j: the intersection of their realradicals
+EXAMPLE:   example radzero; shows no example"
+{
+ def r=basering;
+ int n,ll;
+ //for the mapping in general position
+ map phi,psi;
+ ideal j;
+ ideal jmap=randomLast(20);
+ string ri;
+ intvec @hilb;
+ ideal trans,transprep;// the transformation ideals
+ int nva=nvars(r);
+ int zz,k,l;//counter
+ poly randp;
+ for (zz=1;zz<nva;zz++)
+ {
+   if (npars(basering)>0)
+   {
+     randp=randp+(random(0,5)*par(1)+random(0,5)*par(1)^2+random(0,5))*var(zz);
+   }
+   else
+   {
+     randp=randp+random(0,5)*var(zz);
+   }
+ }
+ randp=randp+var(nva);
+
+ //now they are all irreducible in the non univariate case and
+ //real in the univariate case
+
+ int m=size(buffer);
+ for (l=1;l<=m;l++)
+ {
+   //searching first non univariate polynomial with an even degree
+   //for odd degree we could use the fundamental theorem of algebra and
+   //get real zeros
+
+   //this will act via a coordinate chance into general position
+   //denote that this random chance doesn't work allways
+   //the ideas for the transformation into general position are
+   //used from the primdec.lib
+   transprep=buffer[l];
+   if (voice>=10)
+   {
+     jmap[size(jmap)]=randp;
+   }
+
+
+   for (k=2;k<=n;k++)
+   {
+     if (ord(buffer[l][k])==1)
+     {
+       for (zz=1;zz<=nva;zz++)
+       {
+         if (lead(buffer[l][k])/var(zz)!=0)
+         {
+           transprep[k]=var(zz);
+         }
+       }
+       jmap[nva]=subst(jmap[nva],lead(buffer[l][k]),0);
+     }
+   }
+   phi =r,jmap;
+   for (k=1;k<=nva;k++)
+   {
+     jmap[k]=-(jmap[k]-2*var(k));
+   }
+   psi =r,jmap;
+
+   //coordinate chance
+   trans=phi(transprep);
+
+   //acting with the chanced ideal
+
+   trans=groebner(trans);
+   trans[1]=realpoly(trans[1]);
+
+   //special case
+   if (trans==1)
+   {
+     buffer[l]=trans;
+   }
+   else
+   {
+     ri="ring rhelp=("+charstr(r)+ "),(" +varstr(r)+ ", at t),dp;";
+     execute(ri);
+     ideal trans=homog(imap(r,trans), at t);
+
+     ideal trans1=std(trans);
+     @hilb=hilb(trans1,1);
+     ri= "ring rhelp1=("
+                   +charstr(r)+ "),(" +varstr(rhelp)+ "),lp;";
+     execute(ri);
+     ideal trans=homog(imap(r,trans), at t);
+     kill rhelp;
+     trans=std(trans, at hilb);
+     trans=subst(trans, at t,1);//dehomogenising
+     setring r;
+     trans=imap(rhelp1,trans);
+     kill rhelp1;
+     trans=std(trans);
+     attrib(trans,"isSB",1);
+
+     trans=realzero(trans);
+
+     //going back
+     buffer[l]=psi(trans);
+     //buffer[l]=timeStd(buffer[l],301);//timelimit for std computation
+     buffer[l]=interred(buffer[l]);//timeStd does not work yet
+   }
+ }
+ //option(returnSB);
+ j=intersect(buffer[1..m]);
+ return(j);
+
+}
+
+/*proc minAssReal(ideal i, int erg)
+{
+  int l,m,d,e,r,fac;
+  ideal buffer,factor;
+  list minreal;
+  l=size(i);
+  for (r=1;r<=l;r++)
+  {
+    i[r]=simplify_gen(i[r]);
+
+  }
+
+  list pr=primdecGTZ(i);
+  m=size(pr);
+  for (l=1;l<=m;l++)
+  {
+     d=dim(std(pr[l][2]));
+     buffer=realrad(pr[l][2]);
+     buffer=std(buffer);
+     e=dim(buffer);
+     if (d==e)
+     {
+         minreal=minreal+list(pr[l]);
+     }
+  }
+  if (erg==0)
+  {
+   return(minreal);
+  }
+  else
+  {
+     pr=list();
+     m=size(minreal);
+     for (l=1;l<=m;l++)
+     {
+       pr=insert(pr,minreal[l][2]);
+     }
+     i=intersect(pr[1..m]);
+     //i=timeStd(i,301);
+     i=interred(i);//timeStd does not work yet
+     list realmin=minreal+list(i);
+     return(realmin);
+  }
+}*/
+//////////////////////////////////////////////////////////////////////////////
+///////the univariate case ///////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+proc realpoly(poly f)
+"USAGE:    realpoly(f); a univariate polynomial f;
+RETURN:    poly f, where f is the real part of the input f
+EXAMPLE:   example realpoly; shows an example"
+{
+ def r=basering;
+ int tester;
+ if (size(parstr(r))!=0)
+ {
+   string changering="ring rneu=0,("+parstr(r)+","+varstr(r)+"),lp";
+   execute(changering);
+   poly f=imap(r,f);
+   tester=1;
+ }
+ f=simplify(f,1);//wlog f is monic
+ if (f==1)
+ {
+   setring r;
+   return(f);
+ }
+ ideal j=factorize(f,1);//for getting the squarefree factorization
+ poly erg=1;
+ for (int i=1;i<=size(j);i=i+1)
+ {
+  if (is_real(j[i])==1) {erg=erg*j[i];}
+  //we only need real primes
+ }
+ if (tester==1)
+ {
+   setring(r);
+   poly erg=imap(rneu,erg);
+ }
+ return(erg);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r1 = 0,x,dp;
+   poly f=x5+16x2+x+1;
+   realpoly(f);
+   realpoly(f*(x4+2));
+   ring r2=0,(x,y),dp;
+   poly f=x6-3x4y2 + y6 + x2y2 -6y+5;
+   realpoly(f);
+   ring r3=0,(x,y,z),dp;
+   poly f=x4y4-2x5y3z2+x6y2z4+2x2y3z-4x3y2z3+2x4yz5+z2y2-2z4yx+z6x2;
+   realpoly(f);
+   realpoly(f*(x2+y2+1));
+}
+
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+//// for semi-definiteness/////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+proc decision(poly f)
+" USAGE: decission(f); a multivariate polynomial f in Q[x_1,..,x_n] and lc f=0
+ RETURN: assume that the basering has a lexicographical ordering,
+         1 if f is positive semidefinite  0 if f is indefinite
+EXAMPLE: decision shows an example
+{
+   string ri,lessvar,parvar,perm;
+   ideal jac;
+   list varlist,buffer,isol, at s,lhelp,lhelp1,lfac,worklist;
+   poly p,g;
+   def rbuffer;
+   def r=basering;
+   //diverse zaehler
+   int @z,zz,count,tester;
+   int n=nvars(r);
+   //specialcases
+
+   if (leadcoef(f)<0)
+   {
+     return(0);
+   }
+   lfac=factorize(f,2);
+   ideal factor=lfac[1];
+   intvec @ex=lfac[2];
+   factor=factor[1];
+   zz=size(factor);
+   f=1;
+   for (@z=1;@z<=zz;@z++)
+   {
+     if ((@ex[@z] mod 2)==1)
+     {
+        f=f*factor[@z];
+     }
+   }
+   if (deg(f)<=0)
+   {
+     if (leadcoef(f)>=0)
+     {
+       return(1);
+     }
+     return(0);
+   }
+   //for recursion
+   if (n==1)
+   {
+    if (sturm(f,-length(f),length(f))==0)
+    {
+      return(1);
+    }
+    return(0);
+   }
+   //search for a p in Q[x_n] such that f is pos. sem. definite
+   //if and only if for every isolating setting S={a_1,...,a_r} holds that
+   //every f(x_1,..,x_n-1, a_i) is positiv semidefinite
+   //recursion of variables
+   ///////////////////////////////////////////////////////////////////////////
+   ///////////////////////////////////////////////////////////////////////////
+   ideal II = maxideal(1);
+   varlist = II[1..n-1];
+   lessvar=string(varlist);
+
+   parvar=string(var(n));
+   ri="ring r_neu="+charstr(r)+",(@t,"+parvar+","+lessvar+"),dp;";
+   execute(ri);
+   poly f=imap(r,f);
+   list varlist=imap(r,varlist);
+   ideal jac=jacob(@t+f);
+   jac=jac[3..(n+1)];
+   ideal eins=std(jac);
+   ideal i=@t+f,jac;
+   //use Wu method
+   if (eins==1)
+   {
+     zz=0;
+   }
+   else
+   {
+     matrix m=char_series(i);
+     zz=nrows(m);//number of rows
+   }
+   poly p=1;
+   for (@z=1;@z<=zz;@z++)
+   {
+     p=p*m[@z,1];
+   }
+   //trailing coefficient of p
+   p=subst(p, at t,0);
+   p=realpoly(p);
+   @s=subsets(n-1);
+   ideal jacs;
+   for (@z=1;@z<=size(@s);@z++)
+   {
+     perm="";
+     lhelp=list();
+
+     worklist=varlist;
+     buffer=jac[1..(n-1)];
+     //vorbereitungen fuer den Ringwechsel
+     //setze worklist=x_1,..,x_(n-1)
+
+     for (zz=1;zz<=size(@s[@z]);zz++)
+     {
+      buffer =delete(buffer , at s[@z][zz]-zz+1);
+      worklist=delete(worklist, at s[@z][zz]-zz+1);
+      lhelp=lhelp+list(string(var(@s[@z][zz]+2)));
+      lhelp1=insert(lhelp,string(var(@s[@z][zz]+2)));
+     }
+     //worklist=(x_1,...,x_n-1)\(x_i1,...,x_ik)
+     //lhelp =(x_i1,...,x_ik)
+     //buffer=diff(f,x_i) i not in (i1,..,ik);
+
+     worklist=list("@t",string(var(2)))+lhelp+worklist;
+     for (zz=1;zz<=n+1;zz++)
+     {
+       perm=perm+","+string(worklist[zz]);
+     }
+     perm=perm[2..size(perm)];
+     if (size(buffer)!=0)
+     {
+      jacs=buffer[1..size(buffer)];
+      jacs=@t+f,jacs;
+     }
+     else
+     {
+      jacs=@t+f;
+     }
+     rbuffer=basering;
+     //perm=@t,x_n,x_1,..,x_ik,x\(x_i1,..,x_ik)
+     ri="ring rh=0,("+perm+"),dp;";
+     execute(ri);
+     ideal jacs=imap(rbuffer,jacs);
+     poly p=imap(rbuffer,p);
+     matrix m=char_series(jacs);
+     poly e=1;
+     for (count=1;count<=nrows(m);count++)
+     {
+       e=e*m[count,1];
+     }
+     //search for the leading coefficient of e in
+     //Q(@t,x_n)[x_ at s[@z][1],..,x_ at s[@z][size(@s[@z])]
+     intmat l[n-1][n-1];
+     for (zz=1;zz<n;zz++)
+     {
+       l[zz,n-zz]=1;
+     }
+     ri="ring rcoef="+"(0, at t,"+parvar+"),
+     ("+lessvar+"),M(l);";
+     execute(ri);
+     kill l;
+     poly e=imap(rh,e);
+     e=leadcoef(e);
+     setring rh;
+     e=imap(rcoef,e);
+     e=subst(e, at t,0);
+     e=realpoly(e);
+     p=p*e;
+     setring r_neu;
+     p=imap(rh,p);
+     kill rh,rcoef;
+   }
+   setring r;
+   p=imap(r_neu,p);
+   ///////////////////////////////////////////////////////////////////////////
+   ///////////found polynomial p /////////////////////////////////////////////
+   ///////////////////////////////////////////////////////////////////////////
+   //Compute an isolating set for p
+   ri="ring iso="+charstr(r)+","+parvar+",lp;";
+   execute(ri);
+   poly p=imap(r,p);
+   isol=isolset(p);
+   setring r;
+   list isol=imap(iso,isol);
+   tester=1;
+   for (@z=1;@z<=size(isol);@z++)
+   {
+     ri="ring rless="+charstr(r)+",("+lessvar+"),lp;";
+     g=subst(f,var(n),isol[@z]);
+     execute(ri);
+     poly g=imap(r,g);
+     tester=tester*decision(g);
+     setring r;
+     kill rless;
+   }
+   return(tester);
+}
+
+
+proc isolset(poly f)
+"USAGE:  isolset(f); f a univariate polynomial over the rational numbers
+RETURN: An isolating set of f
+NOTE: algorithm can be found in M-F. Roy,R: Pollack, S. Basu page 373
+EXAMPLE: example isolset; shows an example"
+{
+ int i,case;
+ number m;
+ list buffer;
+ //only real roots count
+ f=realpoly(f);
+ poly seppart=f;
+ seppart=simplify(seppart,1);
+ //int N=binlog(length(seppart));
+ //number zweihochN=exp(2,N+1);
+ number zweihochN=length(f);
+ //a special case
+ if (deg(seppart)==0)
+ {
+   return(list(number(0)));
+ }
+ if (sturm(seppart,-zweihochN,zweihochN)==1)
+ {
+  return(list(-zweihochN,zweihochN));
+ }
+ //getting bernstein coeffs
+ ideal id=isuni(f)-zweihochN;
+ map jmap=basering,id;
+ seppart=jmap(seppart);
+
+ id=2*zweihochN*var(1);
+ jmap=basering,id;
+ seppart=jmap(seppart);
+
+ matrix c=coeffs(seppart,var(1));
+ int s=size(c);
+ poly recproc;
+ //Reciprocal polynomial
+ for (i=1;i<=s;i++)
+ {
+  recproc=recproc+c[s+1-i,1]*(var(1)^(i-1));
+ }
+ jmap=basering,var(1)+1;
+ seppart=jmap(recproc);
+ list bernsteincoeffs,bern;
+ c=coeffs(seppart,var(1));
+ for (i=1;i<=s;i++)
+ {
+   bern[i]=number(c[s+1-i,1])/binomial(s-1,i-1);
+ }
+ bernsteincoeffs=bern,list(-zweihochN,zweihochN);
+ list POS;
+ POS[1]=bernsteincoeffs;
+ list L;
+ while (size(POS)!=0)
+ {
+  if (varsigns(POS[1][1])<2)
+  {
+    case=varsigns(POS[1][1]);
+  }
+  else
+  {
+    case=2;
+  }
+  //case Anweisung
+  buffer=POS[1];
+  POS=delete(POS,1);
+  while(1)
+  {
+   if (case==1)
+   {
+    L=L+buffer[2];
+    break;
+   }
+
+   if (case==2)
+   {
+    m=number(buffer[2][1]+buffer[2][2])/2;
+    bern=BernsteinCoefficients(buffer[1],buffer[2],m);
+    POS=bern+POS;
+    if (leadcoef(sign(leadcoef(subst(f,isuni(f),m))))==0)
+    {
+      number epsilon=1/10;
+      while (sturm(f,m-epsilon,m+epsilon)!=1)
+      {
+        epsilon=epsilon/10;
+      }
+      L=L+list(m-epsilon,m+epsilon);
+    }
+    break;
+   }
+  break;
+  }
+ }
+ i=1;
+ while (i<size(L))
+ {
+   if (L[i]==L[i+1])
+   {
+     L=delete(L,i);
+   }
+   else
+   {
+     i=i+1;
+   }
+ }
+ return(L);
+}
+
+static proc BernsteinCoefficients(list bern,list lr,number m)
+"USAGE :BernsteinCoefficients(bern,lr,m);
+        a list bern=b_0,...,b_p representing a polynomial P of degree <=p
+        in the Bernstein basis pf lr=(l,r) an a number m in Q
+ RETURN:a list erg=erg1,erg2 s.th. erg1=erg1[1],erg[2] and erg1[1] are
+        the bernstein coefficients of P w.r.t. to erg1[2]=(l,m) and erg2[1]
+        is one for erg2[2]=(m,r)
+ EXAMPLE: Bernsteincoefficients shows no example
+"
+{
+ //Zaehler
+ int i,j;
+ list erg,erg1,erg2;
+ number a=(lr[2]-m)/(lr[2]-lr[1]);
+ number b=(m-lr[1])/(lr[2]-lr[1]);
+ int p=size(bern);
+ list berns,buffer,buffer2;
+ berns[1]=bern;
+ for (i=2;i<=p;i++)
+ {
+  for (j=1;j<=p+1-i;j++)
+  {
+   buffer[j]=a*berns[i-1][j]+b*berns[i-1][j+1];
+  }
+  berns[i]=buffer;
+  buffer=list();
+ }
+
+ for (i=1;i<=p;i++)
+ {
+  buffer[i]=berns[i][1];
+  buffer2[i]=berns[p+1-i][i];
+ }
+ erg1=buffer,list(lr[1],m);
+ erg2=buffer2,list(m,lr[2]);
+ erg=erg1,erg2;
+ return(erg);
+}
+
+static proc binlog(number i)
+{
+ int erg;
+ if (i<2) {return(0);}
+ else
+ {
+  erg=1+binlog(i/2);
+  return(erg);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+///////diverse Hilfsprozeduren ///////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+/////wichtig fuers Verstaendnis//////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+static proc is_real(poly f)
+"USAGE:     is_real(f);a univariate irreducible polynomial f;
+RETURN:    1: if f is real
+           0: is f is not real
+EXAMPLE:   example is_real; shows an example"
+
+{
+  int d,anz,i;
+  def r=basering;
+
+  if (f==1) {return(1);}
+  if (isuniv(f)==0)
+  {
+   for (i=1;i<=nvars(r);i++)
+   {
+     d=size(coeffs(f,var(i)))+1;
+     if ((d mod 2)==1)
+     {
+       return(1);
+     }
+   }
+   d=1-decision(f);
+   return(d);
+  }
+  d=deg(f) mod 2;
+  if (d==1)
+  {
+     return(1);//because of fundamental theorem of algebra
+  }
+  else
+  {
+   f=simplify(f,1);//wlog we can assume that f is monic
+   number a=leadcoef(sign(leadcoef(subst(f,isuni(f),-length(f)))));
+   number b=leadcoef(sign(leadcoef(subst(f,isuni(f),length(f)))));
+   if
+   (a*b!=1)
+   //polynomials are contineous so the image is an interval
+   //referres to analysis
+   {
+      return(1);
+   }
+   else
+   {
+      anz=sturm(f,-length(f),length(f));
+      if (anz==0) {return(0);}
+      else {return(1);}
+   }
+  }
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r1 = 0,x,dp;
+   poly f=x2+1;
+   is_real(f);
+
+}
+
+
+static proc prepare_max(ideal m)
+"USAGE: prepare_max(m); m a maximal ideal in Q(y_1,...,y_m)[x_1,...,x_n]
+RETURN: a list erg=(id,j); where id is the real radical of m if j=1 (i.e. m
+        satisfies the shape lemma in one variable x_i) else id=m and j=0;
+EXAMPLE: is_in_shape shows an exmaple;
+"
+
+{
+  int j,k,i,l,fakul;
+  def r=basering;
+  int n=nvars(r);
+  list erg,varlist,perm;
+  string wechsler,vari;
+  //option(redSB);
+
+  for (i=1;i<=n;i++)
+  {
+   varlist=varlist+list(var(i));
+  }
+  perm=permutation(varlist);
+  fakul=size(perm);
+  for (i=1;i<=fakul;i++)
+  {
+    for (j=1;j<=n;j++)
+    {
+      vari=vari+","+string(perm[i][j]);
+    }
+    vari=vari[2..size(vari)];
+    wechsler="ring r_neu=("+charstr(r)+"),("+vari+"),lp;";
+    execute(wechsler);
+    ideal id=imap(r,m);
+    id=groebner(id);
+    k=search_first(id,2,2);
+    setring r;
+    m=imap(r_neu,id);
+    m[1]=realpoly(m[1]);
+    if (m[1]==1)
+    {
+      erg[1]=ideal(1);
+      erg[2]=1;
+      return(erg);
+    }
+    if (k>n)
+    {
+      erg[1]=m;
+      erg[2]=1;
+      return(erg);
+    }
+    else
+    {
+      for (l=k;l<=n;l++)
+      {
+        if (realpoly(m[l])==1)
+        {
+          erg[1]=ideal(1);
+          erg[2]=1;
+          return(erg);
+        }
+      }
+    }
+    vari="";
+    kill r_neu;
+  }
+  if (size(parstr(r))==0)
+  {
+    erg[1]=m;
+    j=1;
+    for (i=1;i<=n;i++)
+    {
+      j=j*isuniv(m[i]);
+    }
+    erg[2]=j;
+    return(erg);
+  }
+  erg[1]=m;
+  erg[2]=0;
+  return(erg);
+}
+
+static proc length(poly f)
+"USAGE:    length(f); poly f;
+RETURN:    sum of the absolute Value of all coeffients of an irreducible
+           poly nomial f
+EXAMPLE:   example length; shows an example"
+
+{
+ number erg,buffer;
+ f=simplify(f,1);//wlog f is monic
+ int n=size(f);
+ for (int i=1;i<=n;i=i+1)
+ {
+   buffer= leadcoef(f[i]);
+   erg=erg + absValue(buffer);
+ }
+
+ return(erg);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r1 = 0,x,dp;
+   poly f=x4-6x3+x2+1;
+   norm(f);
+
+   ring r2=0,(x,y),dp;
+   poly g=x2-y3;
+   length(g);
+
+}
+//////////////////////////////////////////////////////////////////////////////
+//////////////weniger wichtig fuers Verstaendnis//////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+static proc isuniv(poly f)
+{
+  int erg;
+  if (f==0)
+  {
+    erg=1;
+  }
+  else
+  {
+  erg=(isuni(f)!=0);
+  }
+  return(erg);
+}
+static proc search_first(ideal j,int start, int i)
+"USAGE:    searchfirst(j, start, i);
+           id a reduced groebner basis w.r.t. lex
+RETURN:    if i=1 then turns the number of the first non univariate entry
+           with order >1 in its leading term after start
+           else the first non univariate of even order
+EXAMPLE:   example norm; shows no example"
+{
+  int n=size(j);
+  int k=start;//counter
+  j=j,0;
+  if (i==1)
+  {
+    while
+    ((k<=n)&&(ord(j[k])==1))
+    {
+      k=k+1;
+    }
+  }
+  else
+  {
+    while
+    ((k<=n)&&(ord(j[k]) mod 2==1))
+    {
+      k=k+1;
+    }
+
+  }
+ return(k);
+}
+
+static proc subsets(int n)
+"USAGE :subsets(n); n>=0 in Z
+RETURN :l a list of all non-empty subsets of {1,..,n}
+EXAMPLE:subsets(n) shows an example;
+"
+{
+ list l,buffer;
+ int i,j,binzahl;
+ if (n<=0)
+ {
+   return(l);
+ }
+ int grenze=2**n-1;
+ for (i=1;i<=grenze;i++)
+ {
+  binzahl=i;
+  for (j=1;j<=n;j++)
+  {
+   if ((binzahl mod 2)==1)
+   {
+     buffer=buffer+list(j);
+   }
+   binzahl=binzahl div 2;
+  }
+  l[i]=buffer;
+  buffer=list();
+ }
+ return(l);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  subsets(3);
+  subsets(4);
+}
+
+proc permutation(list L)
+" USAGE: permutation(L); L a list
+ OUTPUT: a list of all permutation lists of L
+EXAMPLE: permutation(L) gives an example"
+{
+  list erg,buffer,permi,einfueger;
+  int i,j,l;
+  int n=size(L);
+  if (n==0)
+  {
+    return(erg);
+  }
+  if (n==1)
+  {
+    erg=list(L);
+    return(erg);
+  }
+  for (i=1;i<=n;i++)
+  {
+    buffer=delete(L,i);
+    einfueger=permutation(buffer);
+    l=size(einfueger);
+    for (j=1;j<=l;j++)
+    {
+      permi=list(L[i])+einfueger[j];
+      erg=insert(erg,permi);
+    }
+  }
+  return(erg);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  list L1="Just","an","example";
+  permutation(L1);
+  list L2=1,2,3,4;
+  permutation(L2);
+}
+static proc simplify_gen(poly f)
+"USAGE : simplify_gen(f); f a polymimial in Q(y_1,..,y_m)[x_1,..,x_n]
+RETURN : a polynomial g such that g is the square-free part of f  and
+        every real univariate factor of f is cancelled out
+EXAMPLE:simplify_gen gives no example"
+{
+  int i,l;
+  ideal factor;
+  poly g=1;
+  factor=factorize(f,2)[1];
+  l=size(factor);
+  for (i=1;i<=l;i++)
+  {
+    if (isuniv(factor[i]))
+    {
+        g=g*realpoly(factor[i]);
+    }
+    else
+    {
+      g=g*factor[i];
+    }
+  }
+  return(g);
+}
+static proc contnonloc(ideal id,string pari, string vari)
+"INPUT : a radical ideal id in in F[pari+vari] which is radical in
+         F(pari)[vari), pari and vari strings of variables
+OUTPUT : the contraction ideal of id, i.e. idF(pari)[vari]\cap F[pari+vari]
+EXAMPLE: contnonloc shows an example
+"
+{
+  list pr;
+  list contractpr;
+  int i,l,tester;
+  ideal primcomp;
+  def r=basering;
+  string neu="ring r_neu=("+charstr(r)+pari+"),("+vari+"),dp;";
+  execute(neu);
+  def r1=basering;
+  ideal buffer;
+  setring r;
+  pr=primdecGTZ(id);
+  l=size(pr);
+  contractpr[1]=ideal(1);
+  for (i=1;i<=l;i++)
+  {
+    primcomp=pr[i][2];
+    setring r1;
+    buffer=imap(r,primcomp);
+    buffer=groebner(buffer);
+    if (buffer==1)
+    {
+     tester=0;
+    }
+    else
+    {
+     tester=1;
+    }
+    setring r;
+
+    //id only consits of non units in F(pari)
+    if (tester==1)
+    {
+     contractpr=insert(contractpr,primcomp);
+    }
+  }
+  l=size(contractpr);
+  id=intersect(contractpr[1..l]);
+  return(id);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring  r = 0,(a,b,c),lp;
+   ideal i=b3+c5,ab2+c3;
+   ideal j=contnonloc(i,",b","a,c");
+   j;
+}
diff --git a/Singular/LIB/reesclos.lib b/Singular/LIB/reesclos.lib
new file mode 100644
index 0000000..a6ba844
--- /dev/null
+++ b/Singular/LIB/reesclos.lib
@@ -0,0 +1,465 @@
+////////////////////////////////////////////////////////////////////////////
+version="version reesclos.lib 4.0.0.0 Jun_2013 "; // $Id: 53ae3f0d9c887447ca52755d6ebd614cced1b9bb $
+category="Commutative Algebra";
+
+info="
+LIBRARY:     reesclos.lib   PROCEDURES TO COMPUTE THE INT. CLOSURE OF AN IDEAL
+AUTHOR:      Tobias Hirsch, email: hirsch at math.tu-cottbus.de
+             Janko Boehm, email: boehm at mathematik.uni-kl.de
+             Magdaleen Marais, email: magdaleen at aims.ac.za
+
+OVERVIEW:
+ A library to compute the integral closure of an ideal I in a polynomial ring
+ R=k[x(1),...,x(n)] using the Rees Algebra R[It] of I. It computes the integral
+ closure of R[It],
+ which is a graded subalgebra of R[t]. The degree-k-component is the integral
+ closure of the k-th power of I.
+
+ In contrast to the previous version, the library uses 'normal.lib' to compute the
+ integral closure of R[It]. This improves the performance considerably.
+
+PROCEDURES:
+ ReesAlgebra(I);        computes the Rees Algebra of an ideal I
+ normalI(I[,p[,r]]);    computes the integral closure of an ideal I using R[It]
+";
+
+LIB "locnormal.lib";       // for HomJJ
+LIB "standard.lib";     // for groebner
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc ReesAlgebra (ideal I)
+"USAGE:    ReesAlgebra (I); I = ideal
+RETURN:   The Rees algebra R[It] as an affine ring, where I is an ideal in R.
+          The procedure returns a list containing two rings:
+          [1]: a ring, say RR; in the ring an ideal ker such that R[It]=RR/ker
+
+          [2]: a ring, say Kxt; the basering with additional variable t
+               containing an ideal mapI that defines the map RR-->Kxt
+EXAMPLE:  example ReesAlgebra; shows an example
+"
+{
+  // remember the data of the basering
+
+  def oldring = basering;
+  string oldchar = charstr(basering);
+  string oldvar  = varstr(basering);
+  string oldord  = ordstr(basering);
+  int n = ncols(I);
+  ideal m = maxideal(1);
+
+
+  // Create a new ring with variables for each generator of I
+
+  execute ("ring Rees = "+oldchar+",("+oldvar+",U(1.."+string(n)+")),dp");
+
+
+  // Kxt is the old ring with additional variable t
+  // Here I -> t*I, so the generators of I generate the subalgebra R[It] in Kxt
+
+  execute ("ring Kxt = "+oldchar+",("+oldvar+",t),dp");
+  ideal I = fetch(oldring,I);
+  ideal m = fetch(oldring,m);
+  int k;
+  for (k=1;k<=n;k++)
+  {
+    I[k]=t*I[k];
+  }
+
+
+  // Now we map from Rees to Kxt, identity on the original variables, and
+  // U(k) -> I[k]
+
+  ideal mapI = m,I;
+  map phi = Rees,mapI;
+  ideal zero = 0;
+  export (mapI);
+
+  // Now the Rees-Algebra is Rees/ker(phi)
+
+  setring Rees;
+  ideal ker = preimage(Kxt,phi,zero);
+  export (ker);
+
+  list result = Rees,Kxt;
+
+  return(result);
+
+}
+example
+{
+  "EXAMPLE:"; echo=2;
+  ring R = 0,(x,y),dp;
+  ideal I = x2,xy4,y5;
+  list L = ReesAlgebra(I);
+  def Rees = L[1];       // defines the ring Rees, containing the ideal ker
+  setring Rees;          // passes to the ring Rees
+  Rees;
+  ker;                   // R[It] is isomorphic to Rees/ker
+}
+
+
+////////////////////////////////////////////////////////////////////////////
+
+static
+proc ClosureRees (list L, int useLocNormal)
+"USAGE:    ClosureRees (L,useLocNormal); L a list, useLocNormal an integer
+ASSUME:   L is a list containing
+          - a ring L[1], inside L[1] an ideal ker such that L[1]/ker is
+            isomorphic to the Rees Algebra R[It] of an ideal I in k[x]
+          - a ring L[2]=k[x,t], inside L[1] an ideal mapI defining the
+            map L[1] --> L[2] with image R[It]
+RETURN:   quotients of elements of k[x,t] representing generators of the
+          integral closure of R[It]. The result of ClosureRees is a list
+          images, the first size(images)-1 entries are the numerators of the
+          generators, the last one is the universal denominator
+"
+{
+  int dblvl=printlevel-voice+2;   // toggles how much data is printed
+                                  // during the procedure
+
+  def Kxt = basering;
+  def R(1) = L[1];
+  setring R(1);                   // declaration of variables used later
+  ideal ker(1)=ker;               // in STEP 2
+  if (useLocNormal==1) {
+      list preimages1 = locNormal(ker);
+      ideal preimagesI=preimages1[1];
+      list preimagesL = list(preimagesI[2..size(preimagesI)])+list(preimagesI[1]);
+      ideal preimages = ideal(preimagesL[1..size(preimagesL)]);
+  } else {
+      list nor = normal(ker);
+      ideal preimages=nor[2][1];
+  }
+  setring Kxt;
+  map psi=R(1),mapI;              // from ReesAlgebra: the map Rees->Kxt
+  ideal images=psi(preimages);
+  ideal psii = images[size(images)]*ideal(psi);
+  list imagesl = images[1..size(images)];
+  list psil =psii[1..size(psii)];
+  imagesl=psil+imagesl;
+  return(imagesl);
+}
+
+
+////////////////////////////////////////////////////////////////////////////
+
+static
+proc ClosurePower(list images, list #)
+"USAGE:    ClosurePower (L [,#]); L a list, # an optional list containing an
+          integer
+ASSUME:   - L is a list containing generators of the closure of R[It] in k[x,t]
+            (the first size(L)-1 elements are the numerators, the last one
+            is the denominator)
+          - if # is given: #[1] is an integer, compute generators for the
+                           closure of I, I^2, ..., I^#[1]
+RETURN:   the integral closure of I, ... I^#[1]. If # is not given, compute
+          the closure of all powers up to the maximum degree in t occurring
+          in the closure of R[It] (so this is the last power whose closure is
+          not just the sum/product of the smaller powers). The returned
+          result is a list of elements of k[x,t] containing generators of the
+          closure of the desired powers of I. "
+{
+  int dblvl=printlevel-voice+2;   // toggles how much data is printed
+                                  // during the procedure
+
+  int j,k,d,computepow;                    // some counters
+  int pow=0;
+  int length = size(images)-1;             // the number of generators
+  poly image;
+  poly @denominator = images[length+1];     // the universal denominator
+
+  if (size(#)>0)
+  {
+    pow=#[1];
+  }
+  computepow=pow;
+
+  if (dblvl>0)
+  {
+    "";
+    "// The generators of the closure of R[It]:";
+  }
+
+  intmat m[nvars(basering)-1][1];  // an intvec used for jet and maxdeg1
+  intvec tw=m,1;                   // such that t has weight 1 and all
+                                   // other variables have weight 0
+
+  // Construct the generators of the closure of R[It] as elements of k[x,t]
+  // If # is not given, determine the highest degree pow in t that occurs.
+
+  for (j=1;j<=length;j++)
+  {
+    images[j] = (images[j]/@denominator); // construct the fraction
+    image = images[j];
+    if (dblvl>0)
+    {
+      "generator",j,":",image;
+    }
+
+    if (computepow==0)              // #[1] not given or ==0 => compute pow
+    {
+      if (maxdeg1(image,tw)>pow)    // from poly.lib
+      {
+        pow=maxdeg1(image,tw);
+      }
+    }
+  }
+
+  if (dblvl>0)
+  {
+    "";
+    if (computepow==0)
+    {
+      "// Compute the closure up to the given powers of I";
+    }
+    else
+    {
+     "// Compute the closure up to the maximal power of t that occured:",pow;
+    }
+  }
+
+  // Construct a list consisting of #[1] resp. pow times the zero ideal
+
+  ideal CurrentPower=0;
+  list result;
+  for (k=1;k<=pow;k++)
+  {
+    result=insert(result,CurrentPower);
+  }
+
+  // For each generator and each k, add its degree-k-coefficient to the #
+  // closure of I^k
+
+  for (j=1;j<=length;j++)
+  {
+    for (k=1;k<=pow;k++)
+    {
+      image=images[j]-jet(images[j],k-1,tw);
+      if (image<>0)
+      {
+        image=subst(image/t^k,t,0);
+        if (image<>0)
+        {
+          result[k]=result[k]+image;
+        }
+      }
+    }
+  }
+
+  if (dblvl>0)
+  {
+    "";
+    "// The 'pure' parts of degrees 1..pow:";
+    result;
+    "";
+  }
+
+  // finally, add the suitable products of generators in lower degrees
+
+  for (k=2;k<=pow;k++)
+  {
+    for (j=1;j<=(k div 2);j++)
+    {
+      result[k]=result[k]+result[j]*result[k-j];
+    }
+  }
+
+  return(result);
+}
+
+////////////////////////////////////////////////////////////////////////////
+
+proc normalI(ideal I, list #)
+"USAGE:    normalI (I [,p [,r [,l]]]); I an ideal, p, r, and l optional integers
+RETURN:   the integral closure of I, ..., I^p, where I is an ideal in the
+          polynomial ring R=k[x(1),...x(n)]. If p is not given, or p==0,
+          compute the closure of all powers up to the maximum degree in t
+          occurring in the closure of R[It] (so this is the last power whose
+          closure is not just the sum/product of the smaller). If r
+          is given and r==1, normalI starts with a check whether I is already a
+          radical ideal.
+          If l==1 then locNormal instead of normal is used to compute normalization.
+          The result is a list containing the closure of the desired powers of
+          I as ideals of the basering.
+DISPLAY:  The procedure displays more comments for higher printlevel.
+EXAMPLE:  example normalI; shows an example
+"
+{
+  int dblvl=printlevel-voice+2;   // toggles how much data is printed
+                                  // during the procedure
+
+  def BAS=basering;               // remember the basering
+
+  // two simple cases: principal ideals and radical ideals are always
+  // integrally closed
+
+  if (size(I)<=1)        // includes the case I=(0)
+  {
+    if (dblvl>0)
+    {
+      "// Trivial case: I is a principal ideal";
+    }
+    list result=I;
+    if (size(#)>0)
+    {
+      for (int k=1;k<=#[1]-1;k++)
+      {
+        result=insert(result,I*result[k],k);
+      }
+    }
+    return(result);
+  }
+
+  int testrad=0;      // do the radical check?
+  int uselocNormal=0;
+  if (size(#)>1)
+  {
+    testrad=#[2];
+    if (size(#)==3) {
+                 uselocNormal=#[3];
+    }
+  }
+
+  if (testrad==1)
+  {
+    if (dblvl>0)
+    {
+      "//Check whether I is radical";
+    }
+
+    if (size(reduce(radical(I),std(I)))==0)
+    {
+      if (dblvl>0)
+      {
+        "//Trivial case: I is a radical ideal";
+      }
+      list result=I;
+      if (size(#)>0)
+      {
+        for (int k=1;k<=#[1]-1;k++)
+        {
+          result=insert(result,I*result[k],k);
+        }
+      }
+      return(result);
+    }
+  }
+
+  // start with the computation of the Rees Algebra R[It] of I
+
+  if (dblvl>0)
+  {
+    "// We start with the Rees Algebra of I:";
+  }
+
+  list Rees = ReesAlgebra(I);
+  def R(1)=Rees[1];
+  def Kxt=Rees[2];
+  setring R(1);
+
+  if (dblvl>0)
+  {
+    R(1);
+    ker;
+    "";
+    "// Now ClosureRees computes generators for the integral closure";
+    "// of R[It] step by step";
+  }
+
+  // ClosureRees computes fractions in R[x,t] representing the generators
+  // of the closure of R[It] in k[x,t], which is the same as the closure
+  // in Q(R[It]).
+  // the first size(images)-1 entries are the numerators of the gene-
+  // rators, the last entry is the 'universal' denominator
+
+  setring Kxt;
+  list images = ClosureRees(Rees,uselocNormal);
+
+  // ClosureRees was done after the first HomJJ-call
+  // ==> I is integrally closed, and images consists of the only entry "closed"
+
+  if ((size(images)==1) && (typeof(images[1])=="string"))
+  {
+    if (dblvl>0)
+    {
+      "//I is integrally closed!";
+    }
+
+    setring BAS;
+    list result=I;
+    if (size(#)>0)
+    {
+      for (int k=1;k<=#[1]-1;k++)
+      {
+        result=insert(result,I*result[k],k);
+      }
+    }
+    return(result);
+  }
+
+  // construct the fractions corresponding to the generators of the
+  // closure of I and its powers, depending on # (in fact, they will
+  // not be real fractions, of course). This is done in ClosurePower.
+  list result = ClosurePower(images,#);
+
+  // finally fetch the result to the old basering
+
+  setring BAS;
+  list result=fetch(Kxt,result);
+  return(result);
+}
+example
+{
+  "EXAMPLE:"; echo=2;
+  ring R=0,(x,y),dp;
+  ideal I = x2,xy4,y5;
+  list J = normalI(I);
+  I;
+  J;                             // J[1] is the integral closure of I
+}
+
+/*
+LIB"reesclos.lib";
+
+
+// 1.  x^i,y^i in k[x,y]
+//     geht bis i = 19 (800sec), bis i=10 wenige Sekunden,
+//     bei i = 20 ueber 1GB Hauptspeicher, in der 9. Iteration no memory
+//     (braucht 20 Iterationen)
+
+  ring r = 0,(x,y),dp;
+  int i = 6;
+  ideal I = x^i,y^i;
+  list J = normalI(I);
+  I;
+  J;
+
+
+//================================================================
+
+
+// 2. x^i,y^i,z^i in k[x,y,z]
+//    aehnlich wie 1., funktioniert aber nur bis i=5 und dauert dort
+//    >1 h
+
+
+//================================================================
+
+
+// 3. scheitert in der ersten Iteration beim Radikal
+//    Standardbasis des singulaeren Ortes: 7h (in char0),
+//    in char(p) viel schneller, obwohl kleine Koeffizienten
+//    schon bei Radikal -Test braucht er zu lang (>1h)
+
+  ring r = 0,(x,y,z),dp;
+  //ring r = 32003,(x,y,z),dp;
+
+  ideal I = x2+xy3-5z,z3+y2-xzy,x2y3z5+y3-y5;
+  list l= ReesAlgebra(I);
+  list J = normalI(I);
+  I;
+  J;
+
+*/
+
diff --git a/Singular/LIB/resbinomial.lib b/Singular/LIB/resbinomial.lib
new file mode 100644
index 0000000..6c33111
--- /dev/null
+++ b/Singular/LIB/resbinomial.lib
@@ -0,0 +1,2802 @@
+/////////////////////////////////////////////////////////////////////////
+version="version resbinomial.lib 4.0.0.0 Jun_2013 "; // $Id: 7f5e8f0a7c702784ef3334266f3d767725a1f457 $
+category="Resolution of singularities";
+info="
+LIBRARY: resbinomial.lib  Combinatorial algorithm of resolution of singularities
+                        of binomial ideals in arbitrary characteristic.
+                        Binomial resolution algorithm of Blanco
+
+AUTHORS:  R. Blanco,            mariarocio.blanco at uclm.es,
+@*        G. Pfister,           pfister at mathematik.uni-kl.de
+
+PROCEDURES:
+ BINresol(J);      computes a E-resolution of singularities of (J) (THE SECOND PART IS NOT IMPLEMENTED YET)
+
+ Eresol(J);                         computes a E-resolution of singularities of (J) in char 0
+ determinecenter(L1,L2,c,n,Y,a,mb,flag,control3);    computes the next blowing-up center
+ Blowupcenter(L1,id,m,L2,c,n,h);    makes the blowing-up
+ Nonhyp(Coef,expJ,sJ,n,flag,sums);  computes the ideal generated by the non hyperbolic generators of expJ
+
+ identifyvar();                     identifies status of variables
+ Edatalist(Coef,Exp,k,n,flag);      gives the E-order of each term in Exp
+ EOrdlist(Coef,Exp,k,n,flag);       computes the E-order of an ideal (giving in the language of lists)
+ maxEord(Coef,Exp,k,n,flag);        computes de maximum E-order of an ideal given by Coef and Exp
+ ECoef(Coef,expP,sP,V,auxc,n,flag); Computes a simplified version of the E-Coeff ideal. The E-orders are correct,
+                                    but tranformations of coefficients of the generators and powers of binomials
+                                    cannot be computed easily in terms of lists.
+ elimrep(L);                        removes repeated terms from a list
+ Emaxcont(Coef,Exp,k,n,flag);       computes a list of hypersurfaces of E-maximal contact
+ cleanunit(mon,n,flag);             clean the units in a monomial mon
+ resfunction(t,auxinv,nchart,n);    composes the E-resolution function
+ calculateI(Coef,J,c,n,Y,a,b,D);    computes the order of the non monomial part of an ideal J
+ Maxord(L,n);                       computes the maximum exponent of an exceptional monomial ideal
+ Gamma(L,c,n);                      computes the Gamma function for an exceptional monomial ideal given by L
+
+ convertdata(C,L,n,flag);           computes the ideal corresponding to C,L
+ lcmofall(nchart,mobile);           computes the lcm of the denominators of the E-orders for all the charts
+ computemcm(Eolist);                computes the lcm of the denominators of the E-orders for one chart
+
+ constructH(Hhist,n,flag);                construct the list of exceptional divisors accumulated at this chart
+ constructblwup(blwhist,n,chy,flag);      construct the ideal defining the map K[W] --> K[Wi],
+                                          which gives the composition map of all the blowing up leading to this chart
+ constructlastblwup(blwhist,n,chy,flag);  construct the ideal defining the last blowup leading to this chart
+
+ genoutput(chart,mobile,nchart,nsons,n,q,p);             generates the output for visualization
+ salida(idchart,chart,mobile,numson,previousa,n,q);      generates the output for one chart
+
+ iniD(n);                           creates a list of lists of zeros of size n
+ sumlist(L1,L2);                    sums two lists component to component
+ reslist(L1,L2);                    subtracts two lists component to component
+ multiplylist(L,a);                 multiplies a list by a number, component to component
+ dividelist(L1,L2);                 divides two lists component to component
+ createlist(L1,L2);                 creates a list of lists of two elements
+";
+// inidata(K,k);                      verifies input data, a binomial ideal K of k generators
+// data(K,k,n);                       transforms data on lists of length n
+// list0(n);                          creates a list of zeros of size n
+
+LIB "general.lib";
+LIB "qhmoduli.lib";
+LIB "inout.lib";
+LIB "poly.lib";
+LIB "resolve.lib";
+LIB "reszeta.lib";
+LIB "resgraph.lib";
+////////////////////////////////////////////////////////////////////////////
+
+static proc inidata(ideal K,int k)
+"USAGE: inidata(K,k); K any ideal, k integer (!=0)
+COMPUTE: Verifies the input data
+RETURN: flag indicating if the ideal is binomial or not
+EXAMPLE: example inidata; shows an example
+"
+{
+ int i;
+ for (i=1;i<=k; i++)
+ { if (size(K[i])>2){return(0);}
+ }
+return(1);
+}
+example
+{"EXAMPLE:"; echo = 2;
+  ring r = 0,(x(1..3)),dp;
+  ideal J1=x(1)^4*x(2)^2, x(1)^2+x(3)^3;
+  inidata(J1,2);
+
+  ideal J2=x(1)^4*x(2)^2, x(1)^2+x(2)^3+x(3)^5;
+  inidata(J2,2);
+}
+/////////////////////////////////////////////////////////////////////////////////
+
+proc changeoriginalvar()
+"USAGE: changeoriginalvar();
+COMPUTE: Change the name of the variables to x(1...n), only necessary at the beginning
+RETURN: the new ring with the suitable names
+EXAMPLE: example changeoriginalvar; shows an example
+"
+{
+int i,n,cont;
+
+n=nvars(basering);
+cont=0;
+def r=basering;
+
+// check the name of the variables
+
+for (i=1;i<=n; i++){if (varstr(i)[1]=="x" or varstr(i)[1]=="y"){cont=cont+1;}}
+
+// change them if there exists some variable different from x(i) or y(i)
+
+if (cont!=n or n<=2){
+             // making the change
+              def Rnew=changevar ("x()");
+              setring Rnew;
+                // print("INVERTIBLE VARIABLES NOT CONSIDERED AT THE BEGINNING");
+              return(Rnew,1);
+             }
+else{          // print("INVERTIBLE VARIABLES ALREADY CONSIDERED AT THE BEGINNING");
+     return(r,0);
+    }
+}
+example
+{"EXAMPLE:"; echo = 2;
+  ring r = 0,(x(1),y(2),x(3),y(4),x(5..7),y(8)),dp;
+  changeoriginalvar();
+
+  ring r = 0,(x,y,z,w),dp;
+  changeoriginalvar();
+}
+
+/////////////////////////////////////////////////////////////////////////////////
+
+proc identifyvar()
+"USAGE: identifyvar();
+COMPUTE: Asign 0 to variables x and 1 to variables y, only necessary at the beginning
+RETURN: list, say l, of size the dimension of the basering
+        l[i] is: 0 if the i-th variable is x(i),
+                 1 if the i-th variable is y(i)
+EXAMPLE: example identifyvar; shows an example
+"
+{
+int i,n;
+list flaglist;
+
+n=nvars(basering);
+flaglist=list0(n);
+
+for (i=1;i<=n; i++){if (varstr(i)[1]=="y"){flaglist[i]=1;}}
+
+return(flaglist);
+}
+example
+{"EXAMPLE:"; echo = 2;
+  ring r = 0,(x(1),y(2),x(3),y(4),x(5..7),y(8)),dp;
+  identifyvar();
+}
+/////////////////////////////////////////////////////////////////////////////////
+
+proc data(ideal K,int k,int n)
+"USAGE: data(K,k,n); K any ideal, k integer (!=0), n integer (!=0)
+COMPUTE: Construcs a list with the coefficients and exponents of one ideal
+RETURN: lists of coefficients and exponents of K
+EXAMPLE: example data; shows an example
+"
+{int i,j,lon;
+ number aa;
+ intvec cc;
+ list bb,dd,aux,ddaux,Coef,Exp;
+
+ for (i=1;i<=k; i++)
+ { lon=size(K[i]);
+
+// binomial
+if (lon==2){aa=leadcoef(K[i][1]);
+                   bb=aa;
+                   Coef[i]=bb;              // coefficients
+                   cc=leadexp(K[i][1]);     // exponents
+
+// cc is an intvec, transform cc in dd, a list of lists
+                   dd=cc[1..n];
+                   aux[1]=dd;
+// the same for the second term
+
+                   aa=leadcoef(K[i][2]);
+                   bb=aa;
+                   Coef[i]=Coef[i] + bb;  // all the coefficients of i-th generator of K
+                   cc=leadexp(K[i][2]);
+
+                   dd=cc[1..n];
+                   aux[2]=dd;
+                   Exp[i]=aux;}
+
+// monomial
+if (lon==1){aux=list();
+            aa=leadcoef(K[i][1]);
+            bb=aa;
+            Coef[i]=bb;
+            cc=leadexp(K[i][1]);
+            dd=cc[1..n];
+            aux[1]=dd;
+            Exp[i]=aux;}
+} //end for
+return(Coef,Exp);
+}
+example
+{"EXAMPLE:"; echo = 2;
+  ring r = 0,(x(1..3)),dp;
+  ideal J=x(1)^4*x(2)^2, x(1)^2-x(3)^3;
+  data(J,2,3);
+}
+//////////////////////////////////////////////////////
+
+proc Edatalist(list Coef,list Exp,int k,int n,list flaglist)
+"USAGE: Edatalist(Coef,Exp,k,n,flaglist);
+        Coef,Exp,flaglist lists, k,n, integers
+        Exp is a list of lists of exponents, k=size(Exp)
+COMPUTE: computes a list with the E-order of each term
+RETURN: a list with the E-order of each term
+EXAMPLE: example Edatalist; shows an example
+"
+{int i,j,lon,mm;
+ list dd,ss,sums;
+ number aux,aux1,aux2;
+
+ for (i=1;i<=k;i++){lon=size(Coef[i]);
+                    if (lon==1) { for (j=1;j<=n;j++){if (flaglist[j]==0){aux=aux+Exp[i][1][j];}}
+                                  ss=aux; aux=0;}            // monomial
+                    else { for (j=1;j<=n;j++){if (flaglist[j]==0){ aux1=aux1+Exp[i][1][j];
+                                                                   aux2=aux2+Exp[i][2][j];}}
+                           ss=aux1,aux2; aux1=0; aux2=0; }   // binomial
+                    sums[i]=ss;}
+return(sums);
+}
+example
+{"EXAMPLE:"; echo = 2;
+  ring r = 0,(x(1),y(2),x(3),y(4),x(5..7),y(8)),dp;
+  list flag=identifyvar();
+  ideal J=x(1)^3*x(3)-y(2)*y(4)^2,x(5)*y(2)-x(7)*y(4)^2,x(6)^2*(1-y(4)*y(8)^5);
+  list L=data(J,3,8);
+  list EL=Edatalist(L[1],L[2],3,8,flag);
+  EL; // E-order of each term
+
+
+  ring r = 2,(x(1),y(2),x(3),y(4),x(5..7),y(8)),dp;
+  list flag=identifyvar();
+  ideal J=x(1)^3*x(3)-y(2)*y(4)^2,x(5)*y(2)-x(7)*y(4)^2,x(6)^2*(1-y(4)*y(8)^5);
+  list L=data(J,3,8);
+  list EL=Edatalist(L[1],L[2],3,8,flag);
+  EL; // E-order of each term IN CHAR 2, COMPUTATIONS NEED TO BE DONE IN CHAR 0
+
+
+  ring r = 0,(x(1..3)),dp;
+  list flag=identifyvar();
+  ideal J=x(1)^4*x(2)^2, x(1)^2-x(3)^3;
+  list L=data(J,2,3);
+  list EL=Edatalist(L[1],L[2],2,3,flag);
+  EL; // E-order of each term
+}
+///////////////////////////////////////////////////////////////////////////////////
+
+proc EOrdlist(list Coef,list Exp,int k,int n,list flaglist)
+"USAGE: EOrdlist(Coef,Exp,k,n,flaglist);
+        Coef,Exp,flaglist lists, k,n, integers
+        Exp is a list of lists of exponents, k=size(Exp)
+COMPUTE: computes de E-order of an ideal given by a list (Coef,Exp) and extra information
+RETURN: maximal E-order, and its position=number of generator and term
+EXAMPLE: example EOrdlist; shows an example
+"
+{int i,can,canpost,lon;
+ number canmin;
+ list sums;
+
+sums=Edatalist(Coef,Exp,k,n,flaglist);
+
+ canmin=sums[1][1];                            // inicializating, works also with a monomial
+for (i=1;i<=k; i++){lon=size(sums[i]);         // this is 2 for binomial and 1 for monomial generators
+                    if (sums[i][1]<=canmin and Coef[i][1]!=0){canmin=sums[i][1];
+                                                               can=i; canpost=1;}
+
+// if the generator is a binomial we check the second term
+
+                   if (lon==2) {if (sums[i][2]<canmin and Coef[i][2]!=0){canmin=sums[i][2];
+                                                                          can=i; canpost=2;}}
+}
+return(canmin,can,canpost);
+}
+example
+{"EXAMPLE:"; echo = 2;
+  ring r = 0,(x(1),y(2),x(3),y(4),x(5..7),y(8)),dp;
+  list flag=identifyvar();
+  ideal J=x(1)^3*x(3)-y(2)*y(4)^2,x(5)*y(2)-x(7)*y(4)^2,x(6)^2*(1-y(4)*y(8)^5),x(7)^4*y(8)^2;
+  list L=data(J,4,8);
+  list Eo=EOrdlist(L[1],L[2],4,8,flag);
+  Eo[1]; // E-order
+  Eo[2]; // generator giving the E-order
+  Eo[3]; // term giving the E-order
+}
+
+//////////////////////////////////////////////////////
+
+proc maxEord(list Coef,list Exp,int k,int n,list flaglist)
+"USAGE: maxEord(Coef,Exp,k,n,flaglist);
+        Coef,Exp,flaglist lists, k,n, integers
+        Exp is a list of lists of exponents, k=size(Exp)
+RETURN: computes de maximal E-order of an ideal given by Coef,Exp
+EXAMPLE: example maxEord; shows an example
+"
+{
+int i,lon;
+number canmin;  // THE ASSIGNMENT IS NOT OK BECAUSE IT IS OF TYPE NUMBER
+list sums;
+
+sums=Edatalist(Coef,Exp,k,n,flaglist);
+
+canmin=sums[1][1];                             // inicializating, works also with a monomial
+for (i=1;i<=k; i++){lon=size(sums[i]);         // this is 2 for binomial and 1 for monomial generators
+                    if (sums[i][1]<=canmin and Coef[i][1]!=0){canmin=sums[i][1];}
+
+// if the generator is a binomial we check the second term
+
+                   if (lon==2) {if (sums[i][2]<canmin and Coef[i][2]!=0){canmin=sums[i][2];}}
+}
+return(canmin,sums);
+}
+example
+{"EXAMPLE:"; echo = 2;
+  ring r = 0,(x(1),y(2),x(3),y(4),x(5..7),y(8)),dp;
+  list flag=identifyvar();
+  ideal J=x(1)^3*x(3)-y(2)*y(4)^2*x(3),x(5)*y(2)-x(7)*y(4)^2,x(6)^2*(1-y(4)*y(8)^5),x(7)^4*y(8)^2;
+  list L=data(J,4,8);
+  list M=maxEord(L[1],L[2],4,8,flag);
+  M[1];    // E-order
+}
+//////////////////////////////////////////////////////
+
+proc elimrep(list maxvar)
+"USAGE: elimrep(L); L is a list
+COMPUTE: Eliminate repeated terms from a list
+RETURN: the same list without repeated terms
+EXAMPLE: example elimrep; shows an example
+"
+{
+int i,j;
+list aux2;
+
+aux2=maxvar;
+for (i=1;i<=size(aux2); i++)
+{ for (j=i+1;j<=size(aux2); j++){if (aux2[i]==aux2[j] and i!=j){aux2=delete(aux2,j);}}
+}
+maxvar=aux2;
+return(maxvar);
+}
+example
+{"EXAMPLE:"; echo = 2;
+  ring r = 0,(x(1..3)),dp;
+  list L=4,5,2,5,7,8,6,3,2;
+  elimrep(L);
+}
+//////////////////////////////////////////////////////
+
+proc Emaxcont(list Coef,list Exp,int k,int n,list flag)
+"USAGE: Emaxcont(Coef,Exp,k,n,flag);
+        Coef,Exp,flag lists, k,n, integers
+        Exp is a list of lists of exponents, k=size(Exp)
+COMPUTE: Identify ALL the variables of E-maximal contact
+RETURN: a list with the indexes of the variables of E-maximal contact
+EXAMPLE: example Emaxcont; shows an example
+"
+{
+int i,j,lon;
+number maxEo;
+list L,sums,bx,maxvar;
+
+L=maxEord(Coef,Exp,k,n,flag);
+
+maxEo=L[1];
+sums=L[2];
+
+if (maxEo>0){
+
+for (i=1;i<=k; i++){lon=size(sums[i]);
+                   if (lon==2){if (sums[i][1]==maxEo)        // variables of the first term
+                              {for (j=1;j<=n; j++){if(Exp[i][1][j]!=0 and flag[j]==0){bx=j; maxvar=maxvar + bx;}}}
+
+                              if (sums[i][2]==maxEo)         // variables of the second term
+                              {for (j=1;j<=n; j++){if(Exp[i][2][j]!=0 and flag[j]==0){bx=j; maxvar=maxvar + bx;}}}}
+                   else {if (sums[i][1]==maxEo)
+                        {for (j=1;j<=n; j++){if(Exp[i][1][j]!=0 and flag[j]==0){bx=j; maxvar=maxvar + bx;}}}}
+
+                   }}
+else {maxvar=list();}
+
+// eliminating repeated terms
+maxvar=elimrep(maxvar);
+
+// It is necessary to check if flag[j]==0 in order to avoid the selection of y variables
+
+return(maxEo,maxvar);
+}
+example
+{"EXAMPLE:"; echo = 2;
+  ring r = 0,(x(1),y(2),x(3),y(4),x(5..7),y(8)),dp;
+  list flag=identifyvar();
+  ideal J=x(1)^3*x(3)-y(2)*y(4)^2,x(5)*y(2)-x(7)*y(4)^2,x(6)^2*(1-y(4)*y(8)^5),x(7)^4*y(8)^2;
+  list L=data(J,4,8);
+  list hyp=Emaxcont(L[1],L[2],4,8,flag);
+  hyp[1]; // max E-order=0
+  hyp[2]; // There are no hypersurfaces of E-maximal contact
+
+  ring r = 0,(x(1),y(2),x(3),y(4),x(5..7),y(8)),dp;
+  list flag=identifyvar();
+  ideal J=x(1)^3*x(3)-y(2)*y(4)^2*x(3),x(5)*y(2)-x(7)*y(4)^2,x(6)^2*(1-y(4)*y(8)^5),x(7)^4*y(8)^2;
+  list L=data(J,4,8);
+  list hyp=Emaxcont(L[1],L[2],4,8,flag);
+  hyp[1]; // the E-order is 1
+  hyp[2]; // {x(3)=0},{x(5)=0},{x(7)=0} are hypersurfaces of E-maximal contact
+
+ }
+///////////////////////////////////////////////////////
+
+proc cleanunit(list mon,int n,list flaglist)
+"USAGE: cleanunit(mon,n,flaglist);
+        mon, flaglist lists, n integer
+COMPUTE: We clean (or forget) the units in a monomial, given by "y" variables
+RETURN: The list defining the monomial ideal already cleaned
+EXAMPLE: example cleanunit; shows an example
+"
+{
+int i;
+
+for (i=1;i<=n;i++){if (flaglist[i]==1){mon[i]=0;}}
+
+// coef[1]=coef[1]*y(i)^mon[i]; IS NOT ALLOWED because mon[i] can be a number
+// therefore, the coefficients remain constant
+
+return(mon);
+}
+example
+{"EXAMPLE:"; echo = 2;
+ring r = 0,(x(1),y(2),x(3),y(4)),dp;
+list flag=identifyvar();
+ideal J=x(1)^3*y(2)*x(3)^5*y(4)^8;
+list L=data(J,1,4);
+L[2][1][1];  // list of exponents of the monomial J
+list M=cleanunit(L[2][1][1],4,flag);
+M;           // new list without units
+}
+//////////////////////////////////////////////////////
+// Classification of the ideal E-Coeff_V(P):
+// ccase=1,    E-Coeff_V(P)=0
+//       2,3   Bold regular case
+//       4     P=1 monomial case (detected before)
+//       0     Otherwise
+
+proc ECoef(list Coef,list expP,int sP,int V,number auxc,int n,list flaglist)
+"USAGE: ECoef(Coef,expP,sP,V,auxc,n,flaglist);
+        Coef, expP, flaglist lists, sP, V, n integers, auxc number
+COMPUTE: The ideal E-Coeff_V(P), where V is a permissible hypersurface which belongs to the center
+RETURN: list of exponents, list of coefficients and classification of the ideal E-Coeff_V(P)
+EXAMPLE: example ECoef; shows an example
+"
+{
+int i,j,k,l,numg,ccase,cont2,cont3,val;
+number aa;
+list Eco,newcoef,auxexp,newL,rs,rs2,aux,aux2,aux3,aux4,L;
+
+auxexp=expP;
+
+l=1;
+for (i=1;i<=sP;i++)
+{rs[i]=size(Coef[i]);
+ if (rs[i]==2){                                   // binomials
+               if (auxexp[i][1][V]!=auxexp[i][2][V])  // no common factors for the variable in V
+
+                  {for (j=1;j<=2;j++){if (auxexp[i][j][V]<auxc){aa=auxc/(auxc-auxexp[i][j][V]);
+                                                              auxexp[i][j][V]=0;
+                                                              aux4[1]=multiplylist(auxexp[i][j],aa);
+                                                              Eco[l]=aux4;
+                                                            // newcoef[l]=Coef[i][j]^aa; IT IS NO ALLOWED!!!
+                                                              newcoef[l]=Coef[i][j]; // we leave it constant
+                                                              l=l+1;}}}
+
+               else                               // common factors for the variable in V, of zero in both terms
+
+                 {if (auxexp[i][1][V]<auxc){aa=auxc/(auxc-auxexp[i][1][V]);
+                                          auxexp[i][1][V]=0; auxexp[i][2][V]=0;
+
+                 // this generator is a power of a binomial
+                 // one possibility is Eco[l]=auxexp[i]; we leave it constant and add some extra number aa, or
+                 // define a binomial again. The E-order coincides!!!
+
+                                          aux=multiplylist(auxexp[i][1],aa);
+                                          aux2=multiplylist(auxexp[i][2],aa);
+                                          aux3[1]=aux;
+                                          aux3[2]=aux2;
+                                          Eco[l]=aux3;
+                                          newcoef[l]=Coef[i];
+                                          l=l+1;}}
+              }
+
+else                                               // monomials
+    {if (auxexp[i][1][V]<auxc){aa=auxc/(auxc-auxexp[i][1][V]);
+                             auxexp[i][1][V]=0;
+                             aux4=list();
+                             aux4[1]=multiplylist(auxexp[i][1],aa);
+                             Eco[l]=aux4;
+                             newcoef[l]=Coef[i];
+                             l=l+1;}}
+}
+
+// cleaning units from the monomial generators of Eco
+// If there are hyperbolic equations in Eco, such that Eco=1, we detect it later, computing the E-order
+
+ numg=size(Eco);
+ for (k=1;k<=numg;k++){ if (size(newcoef[k])==1){Eco[k][1]=cleanunit(Eco[k][1],n,flaglist);}}
+
+// checking Eco
+
+ccase=0;
+cont2=0;
+cont3=0;
+val=0;
+
+// CASE Eco=0: If Eco=empty list then as ideal Eco=0
+
+if (numg==0){ccase=1;}
+else
+{
+for (i=1;i<=numg;i++) {rs2[i]=size(newcoef[i]);
+                       if (rs2[i]==1){val=val+n;                                               // monomials
+                                      for (l=1;l<=n; l++) {if (Eco[i][1][l]==0) {cont2=cont2+1;}}
+                                      }
+                       else{val=val+(2*n);                                                     // binomials
+                            for (l=1;l<=n; l++) {if (Eco[i][1][l]==0) {cont2=cont2+1;}
+                                                 if (Eco[i][2][l]==0) {cont2=cont2+1;}}
+                            }
+                       }
+
+// If cont2=val then all the entries of Eco are zero!! As ideal Eco=1
+
+for (i=1;i<=sP;i++){if (rs[i]==2){                                                           // binomials
+                                  for (l=1;l<=n;l++) {if (expP[i][1][l]!=0) {cont3=cont3+1;}
+                                                      if (expP[i][2][l]!=0) {cont3=cont3+1;}}
+                                 }
+                    else{                                                                    // monomials
+                         for (l=1;l<=n;l++) {if (expP[i][1][l]!=0) {cont3=cont3+1;}}
+                        }
+                   }
+
+// If cont3=0 all the entries of expP are zero!! As ideal P=1 this is detected before
+// If cont3=1 then P is bold regular
+
+
+// CASE Eco=1
+
+if (cont2==val and cont3==1){ccase=2;}    // BOLD REGULAR CASE
+if (cont2==val and cont3>1){ccase=3;}     // CASE P=x^{\alpha},x^{\beta}, IN FACT, BOLD REGULAR
+if (cont2==val and cont3==0){ccase=4;}    // P=1, then I=1 monomial case
+
+// Case BOLD REGULAR P=x^{\alpha}*(1-\mu y^{\delta})
+// IT IS NON NECESSARY TO CHECK IT, Eco=empty list, already done!
+
+ L=maxEord(newcoef,Eco,numg,n,flaglist);         // L[1] is the E-order of Eco
+ if (L[1]==0){ccase=2; print("E-order zero!");}  // BOLD REGULAR CASE
+
+// we leave it to check the computations
+
+} // close else
+
+return(Eco,newcoef,ccase);
+}
+example
+{"EXAMPLE:"; echo = 2;
+ring r = 0,(x(1),y(2),x(3),y(4),x(5..7)),dp;
+list flag=identifyvar();
+ideal P=x(1)^2*x(3)^5-x(5)^7*y(4),x(6)^3*y(2)^5-x(7)^5,x(5)^3*x(6)-y(4)^3*x(1)^5;
+list L=data(P,3,7);
+list L2=ECoef(L[1],L[2],3,1,3,7,flag);
+L2[1];  // exponents of the E-Coefficient ideal respect to x(1)
+L2[2];  // its coefficients
+L2[3];  // classify the type of ideal obtained
+
+ring r = 0,(x(1),y(2),x(3),y(4)),dp;
+list flag=identifyvar();
+ideal J=x(1)^3*(1-2*y(2)*y(4)^2);  // Bold regular case
+list L=data(J,1,4);
+list L2=ECoef(L[1],L[2],1,1,3,4,flag);
+L2;
+
+ring r = 0,(x(1),y(2),x(3),y(4),x(5..7)),dp;
+list flag=identifyvar();
+ideal J=x(1)^3-x(3)^2*y(4)^2,x(1)*x(7)*y(2)-x(6)^3*x(5)*y(4)^3,x(5)^3-x(5)^3*y(2)^2;
+list L=data(J,3,7);
+list L2=ECoef(L[1],L[2],3,1,2,7,flag);
+L2;
+
+ring r = 3,(x(1),y(2),x(3),y(4),x(5..7)),dp;
+list flag=identifyvar();
+ideal J=x(1)^3-x(3)^2*y(4)^2,x(1)*x(7)*y(2)-x(6)^3*x(5)*y(4)^3,x(5)^3-x(5)^3*y(2)^2;
+list L=data(J,3,7);
+list L2=ECoef(L[1],L[2],3,1,2,7,flag);
+L2; // THE COMPUTATIONS ARE NOT CORRECT IN CHARACTERISTIC p>0
+    // because numbers are treated as 0 in assignments
+
+}
+////////////////////////////////////////////////////////////////////////////
+// The intvec a indicates the previous center
+// Hhist = intvec of exceptional divisors of the parent chart
+
+proc determinecenter(list Coef,list expJ,number c,int n,int Y,intvec a,list listmb,list flag,int control3,intvec Hhist)
+"USAGE: determinecenter(Coef,expJ,c,n,Y,a,listmb,flag,control3,Hhist);
+        Coef, expJ, listmb, flag lists, c number, n, Y, control3 integers, a, Hhist intvec
+COMPUTE: next center of blowing up and related information, see example
+RETURN: several lists defining the center and related information
+EXAMPLE: example determinecenter; shows an example
+"
+{int i,j,rstep,l,mm,cont,cont1,cont2,cont3,a4,sI,sP,V,V2,ccase,b,Mindx,tip,mval;
+ number auxc,a1,a2,ex,maxEo,aux;
+
+ list D,H,auxJ; // lists of D_n,D_n-1,...,D_1; H_n,H_n-1,...,H_1; J_n,J_n-1,...,J_1
+
+ list oldOlist,oldC,oldt,oldD,oldH,allH;  // information of the previous step
+
+ list Olist,C,t,Dstar,center,expI,expP,newJ,maxset;
+
+ list maxvar,auxlist,aux3,auxD,auxolist,auxdiv,auxaux,L,rs,auxgamma,auxg2,aux1;   // auxiliary lists
+ list auxinvlist,newcoef,EL,Ecoaux,Hplus,transH,Hsum,auxset,sumnewH;              // auxiliary lists
+ list auxcoefI,auxcent,center2;
+
+ intvec oldinfobo7,infobo7;
+ int infaux,leh,leh2,leh3;
+
+tip=listmb[1];   // It is not used in this procedure, it is used to compute the lcm of the denominators
+oldOlist=listmb[2];
+oldC=listmb[3];
+oldt=listmb[4];  // t= resolution function
+oldD=listmb[5];
+
+oldH=listmb[6];
+allH=listmb[7];
+
+oldinfobo7=listmb[8];  // auxiliary intvec, it is used to define BO[7]
+
+// inicializating lists
+ Olist=list();
+ C=list();
+ auxinvlist=list();
+
+ auxJ[1]=expJ;
+ rstep=n;             // we are in dimension rstep
+ auxc=c;
+ cont=1;
+
+if (Y==0) {D=iniD(n); H=iniD(n); infobo7=-1;} // first center, inicializate previous information
+
+ if (Y!=0 and rstep==n)           // In dimension n, D'_n is always of this form
+   { auxdiv=list0(n);
+     Dstar[1]=oldD[1];
+
+     b=size(a);
+     for (i=1;i<=n;i++) {for (j=1;j<=b;j++) {if (a[j]==i) {aux=aux+oldD[1][i];}}}
+     Dstar[1][Y]=aux;
+     aux=0;
+
+     auxdiv[Y]=oldOlist[1]-oldC[1];
+     D[1]=sumlist(Dstar[1],auxdiv);}  // list defining D_n
+
+// computing strict transforms of the exceptional divisors H
+
+if (Y!=0){transH=iniD(n);
+          for (i=1;i<=size(oldH);i++){transH[i]=oldH[i]; transH[i][Y]=0;}         // Note: size(oldH)<=n
+          allH[Y]=1;}                                                             // transform of |H|=H_nU...UH_1
+
+// We put here size(oldH) instead of n because maybe we have not
+// calculated all the dimensions in the previous step
+
+// STARTING THE LOOP
+
+ while (rstep>=1)
+  {
+    if (Y!=0 and rstep!=n) // transformation law of D_i for i<n
+    {
+      if (cont!=0)      // the resolution function did not drop in higher dimensions
+      {
+       if (oldt[n-rstep]==a1/a2 and c==oldC[1] and control3==0)
+        {auxD=list0(n);
+         auxD[Y]=oldOlist[n-rstep+1]-oldC[n-rstep+1];
+          Dstar[n-rstep+1]=oldD[n-rstep+1];
+
+           for (i=1;i<=n;i++) {for (j=1;j<=b;j++) {if (a[j]==i) {aux=aux+oldD[n-rstep+1][i];}}}
+           Dstar[n-rstep+1][Y]=aux;
+           aux=0;
+
+           D[n-rstep+1]=sumlist(Dstar[n-rstep+1],auxD);
+
+        }
+       else
+           {cont=0;
+            for (j=n-rstep+1;j<=n; j++){D[j]=list0(n);}
+           }
+      }
+    }
+
+// Factorizing J=M*I
+
+   cont1=0;
+   for (i=1;i<=n;i++) {if (D[n-rstep+1][i]==0) {cont1=cont1+1;}}  // if it fails write: listO(n)[i]
+
+   if (cont1==n) {expI=expJ;}    // D[n-rstep+1]=0 (is a list of zeros)
+   else {
+         for (i=1;i<=size(expJ);i++)
+         {rs[i]=size(Coef[i]);
+          if (rs[i]==2){ aux1=list();
+                         aux1[1]=reslist(expJ[i][1],D[n-rstep+1]);
+                         aux1[2]=reslist(expJ[i][2],D[n-rstep+1]);
+                         expI[i]=aux1;}                             // binomial
+          else {aux1=list();
+                aux1[1]=reslist(expJ[i][1],D[n-rstep+1]);
+                expI[i]=aux1;}}                                     // monomial
+        }
+
+// NOTE: coeficients of I = coeficients of J, because I and J differ in a monomial
+
+// Detecting errors, negative exponents in expI
+
+sI=size(expI);
+
+for (i=1;i<=sI;i++)
+{rs[i]=size(Coef[i]);
+ if (rs[i]==2){for (j=1;j<=2;j++){for (l=1;l<=n; l++)
+             {if (expI[i][j][l]<0) {print("ERROR, the BINOMIAL ideal I has negative components");
+        //   print("M ideal"); print(D[n-rstep+1]); print(expI); print("dimension"); print(rstep);
+        //                print("previous chart"); print(size(finalchart)); ~;
+ }}}}
+  else {for (l=1;l<=n; l++)
+  {if (expI[i][1][l]<0) {print("ERROR, the MONOMIAL ideal I has negative components");
+        //  print("M ideal"); print(D[n-rstep+1]); print(expI); print("dimension"); print(rstep);
+        //  print("previous chart"); print(size(finalchart)); ~;
+  }}}
+}
+
+// Compute the maximal E-order of I
+
+L=maxEord(Coef,expI,sI,n,flag);
+maxEo=L[1]; // E-order of I
+
+// Inicializating information
+
+   auxolist=maxEo;
+   a1=maxEo;
+   a2=auxc;
+   Olist=Olist+auxolist;  // list of new maximal E-orders o_n,o_{n-1},...o_1
+   aux3=auxc;
+   C=C+aux3;              // list of new critical values c=c_{n+1},c_{n},...c_2
+
+// It is necessary to check if the first coordinate of the invariant has dropped or not
+// NOTE: By construction, the first coordinate is always 1 !!
+// It has dropped is equivalent to: CURRENT C<c of the previous step
+
+// Calculate new H, this is done for every dimension
+
+if (Y!=0){a4=size(oldt);
+          if (n-rstep+1>a4){cont=0; oldt[n-rstep+1]=0; }            // VERIFICAR!!!!
+
+          if (cont!=0 and oldt[n-rstep+1]==a1/a2 and c==oldC[1] and control3==0){H[n-rstep+1]=transH[n-rstep+1];
+
+              // we fill now the value for BO[7]
+                    if (oldinfobo7[n-rstep+1]==-1){leh=size(Hhist);
+                                                   infobo7[n-rstep+1]=Hhist[leh];} // suitable index !!!
+                    else{ infaux=oldinfobo7[n-rstep+1];
+                          infobo7[n-rstep+1]=infaux;}      // the same as the previous step
+
+                                                                                }
+          else {
+                if (rstep<n) {sumnewH=list0(n);
+                              for (i=1;i<n-rstep+1;i++){sumnewH=sumlist(sumnewH,H[i]);}
+                              H[n-rstep+1]=reslist(allH,sumnewH);}
+                else {H[n-rstep+1]=allH;}
+
+                 // we fill the value for BO[7] too, we complete it at the end if necessary
+                infobo7[n-rstep+1]=-1;
+               }
+          }
+
+// It is necessary to detect the monomial case AFTER inicializate the information
+// OTHERWISE WE WILL HAVE EMPTY COMPONENTS IN THE RESOLUTION FUNCTION
+
+// If maxEo=0 but maxo!=0 MONOMIAL CASE (because E-Sing(J,c) still !=emptyset)
+// If maxEo=0 and maxo=0 then I=1, (real) monomial case, the same case for us
+// NOTE THAT IT DOESN'T MATTER IF THERE IS A p-TH POWER OF A HYPERBOLIC EQ, THE E-ORDER IS ZERO ANYWAY
+
+if (maxEo==0){auxgamma=Gamma(D[n-rstep+1],auxc,n); // Gamma gives (maxlist,gamma,center)
+              auxg2=auxgamma[3];
+              center=center+auxg2;
+              center=elimrep(center);
+              auxinvlist=auxgamma[2];
+
+// print("gamma"); print(auxg2);
+
+              break;}
+
+// Calculate P    // P=I+M^{o/(c-o)} with weight o
+
+if (maxEo>=auxc) {expP=expI; Mindx=0;}                 // The coefficients also remain constant
+   else {ex=maxEo/(auxc-maxEo);
+         auxlist=list();
+         Mindx=1;
+         auxlist[1]=multiplylist(D[n-rstep+1],ex);     // weighted monomial part: D[n-rstep+1]^ex;
+         expP=insert(expI,auxlist);                    // P=I+D[n-rstep+1]^ex;
+         auxcoefI=Coef;
+         Coef=insert(Coef,list(1));}                   // Adding the coefficient for M
+
+// NOTE: IT IS NECESSARY TO ADD COEFFICIENT 1 TO THE MONOMIAL PART M
+// E-ord(P_i)=E-ord(I_i) so to compute the E-order of P_i we can compute E-ord(I_i)
+
+// Calculate variables of E-maximal contact, ALWAYS WITH RESPECT TO THE IDEAL I !!
+
+sP=size(expP);     // Can be different from size(expI)
+
+if (Mindx==1){ maxvar=Emaxcont(auxcoefI,expI,sI,n,flag);}
+else{ maxvar=Emaxcont(Coef,expP,sP,n,flag);}
+
+auxc=maxvar[1];     // E-order of P, critical value for the next step, ALSO VALID auxc=maxEo;
+if (auxc!=maxEo){print("ERROR, the E-order is not well computed");}
+
+maxset=maxvar[2];
+
+// center=center + maxset;  // HACER DESPUES Y A?ADIR SOLO V!!!!!!
+// Cleaning the center: eliminating repeated variables
+// center=elimrep(center);
+
+// if (rstep==1) {break;}   // Induction finished, is not necessary to compute the rest
+
+// Calculate Hplus=set of non permissible hypersurfaces
+// RESET Hplus if c has dropped or we have eliminated hyperbolic generators
+
+// ES NECESARIO PONER CONDICION DE SI INVARIANTE BAJA O NO??? SI BAJA HPLUS NO SE USA...
+
+if (Y==0 or c<oldC[1] or control3==1) {Hplus=list0(n);}
+else {Hsum=list0(n);
+      Hplus=allH;
+      for (i=1;i<=n-rstep+1;i++){Hsum=sumlist(Hsum,H[i]);}
+      Hplus=reslist(Hplus,Hsum);                             // CHEQUEAR QUE NO SALEN -1'S
+     }
+
+// Taking into account variables of maxset outside of Hplus (so inside Hminus)
+
+if (Y==0 or c<oldC[1] or control3==1){V=maxset[1];                  // Hplus=0 so any variable is permissible
+                                      maxset=delete(maxset,1);}     // eliminating this variable V from maxset
+else{
+     // If the invariant remains constant V comes from the previous step
+
+    if (cont!=0 and oldt[n-rstep+1]==a1/a2 and c==oldC[1]){
+                                                           if (Mindx==1){
+//----------------------------USING HPLUS----------------------------------------
+// REMIND THAT IN THIS CASE maxset=HYPERSURFACES OF E-MAXIMAL CONTACT FOR I, INSTEAD OF P
+
+      V2=a[n-rstep+1];           // V can be different from the variable coming from the previous step
+// check that V2 belongs to maxset
+
+for (i=1;i<=size(maxset);i++){
+                              if (V2==maxset[i]){mval=1; break;}
+                              else{mval=0;}
+                             }
+
+      if (Hplus[V2]==0 and mval==1){V=V2;}   // V2 is permissible
+      else{
+                                                      cont2=1;
+                                                      cont3=1;
+                                                      auxset=maxset;
+                                                        while (cont2!=0){mm=auxset[1];
+                                                          if (Hplus[mm]!=0) {auxset=delete(auxset,1); cont3=cont3+1;}
+                                                               // eliminating non permissible variables from maxset
+                                                          else {cont2=0;}}
+                                                      V=maxset[cont3];        // first permissible variable
+                                                      maxset=delete(maxset,cont3);
+           }
+                                                                         }
+
+//-------------------------------------------------------------------------------
+                                                           else{ V=a[n-rstep+1];}
+                                                          }
+    else {V=maxset[1];     // Hplus=0 so any variable is permissible
+          maxset=delete(maxset,1);
+         }
+
+     }
+
+
+// if (V!=V2 and V2!=0){print(a); print(rstep); print(V); print(V2); print("num cartas"); print(size(finalchart)); ~;}
+
+V2=0;
+
+// Adding the new hypersurface of E-maximal contact to the center
+
+auxcent[1]=V;
+
+center=center + auxcent; // print("num cartas"); print(size(finalchart)); print(center); if (size(finalchart)==2){~~;}
+
+auxcent=list();
+
+// Cleaning the center: eliminating repeated variables CREO QUE NO HACE FALTA
+
+center2=elimrep(center);  // print(center2); print("-----------");
+
+// if (size(center2)!=size(center)){print("MAL");}
+
+// for (i=1;i<=size(center);i++){if (center2[i]!=center[i]){print("cambia");}}
+
+
+if (rstep==1) {break;}   // Induction finished, is not necessary to compute the rest
+
+
+// Calculate Eco=E-Coeff_V(P) where V is a permissible hypersurface which belongs to the center
+// Eco can have rational exponents
+
+Ecoaux=ECoef(Coef,expP,sP,V,auxc,n,flag);
+
+// SPECIAL CASES: BOLD REGULAR CASE
+//--------------------------------------------------------------------
+
+if (Ecoaux[3]==1){                      // Eco=EMPTY LIST, Eco=0 AS IDEAL
+                  aux1[1]=list0(n);
+                  newJ[1]=aux1;         // monomial with zero entries, newJ=1 as ideal
+                  newcoef[1]=list(1);   // the new coefficient is only 1
+                  auxaux=list();
+                  auxaux[1]=newJ;
+                  auxJ=auxJ+auxaux;     // auxJ list of ideals J_i
+                  auxinvlist=1;
+                  break;}
+
+//-----------------------------------------------------------
+// THIS CASE IS NOT GOING TO APPEAR, BUT WE LEAVE IT TO CHECK COMPUTATIONS
+
+if (Ecoaux[3]==2 or Ecoaux[3]==3){                     // Eco=0 LIST, Eco=1 AS IDEAL
+                                  aux1[1]=list0(n);
+                                  newJ[1]=aux1;
+                                  newcoef[1]=list(1); // print("Strange case happens"); ~;
+                                  auxaux=list();
+                                  auxaux[1]=newJ;
+                                  auxJ=auxJ + auxaux;  // auxJ list of ideals J_i
+                                  auxinvlist=1;
+                                  break;}
+//-----------------------------------------------------------
+// THIS CASE IS NOT GOING TO APPEAR, BUT WE LEAVE IT TO CHECK COMPUTATIONS
+
+// P=1 THIS CANNOT HAPPEN SINCE P=1 IFF I=1 (or I is equivalent to 1)
+// and this is the monomial case, already checked
+
+if (Ecoaux[3]==4){print("ERROR in ECoef"); break;}
+//-----------------------------------------------------------
+
+// If we are here Ecoaux[3]=0, then continue
+
+// Filling the list of "ideals", auxJ=J_n,J_{n-1},...
+
+ newJ=Ecoaux[1];
+ newcoef=Ecoaux[2];
+
+ auxJ=insert(auxJ,newJ,n-rstep+1); // newJ is inserted after n-rstep+1 position, so in position n-rstep+2
+
+// New input for the loop, if we are here newJ is different from 0
+
+   expJ=newJ;
+   Coef=newcoef;
+
+   newJ=list();
+   expI=list();
+   expP=list();
+   rstep=rstep-1;  // print(size(auxJ));
+}
+
+// EXIT LOOP "while"
+// we do NOT construct the center as an ideal because WE USE LISTS
+
+t=dividelist(Olist,C);    // resolution function t
+
+// Complete the intvec infobo7 if necessary
+
+if (control3==1){infobo7=-1;} // We reset the value after clean hyperbolic equations
+leh2=size(Olist);
+leh3=size(infobo7);
+if (leh3<leh2){for (j=leh3+1;j<=leh2; j++){infobo7[j]=-1;}}
+
+// Auxiliary list to complete the resolution function in special cases
+if (size(auxinvlist)==0) {auxinvlist[1]=0;}
+
+return(center,auxJ,Olist,C,t,D,H,allH,auxinvlist,infobo7);
+}
+example
+{"EXAMPLE:"; echo = 2;
+  ring r = 0,(x(1..4)),dp;
+  list flag=identifyvar();
+  ideal J=x(1)^2-x(2)^2*x(3)^5, x(1)*x(3)^3+x(4)^6;
+  list Lmb=1,list(0,0,0,0),list(0,0,0,0),list(0,0,0,0),iniD(4),iniD(4),list(0,0,0,0),-1;
+  list L=data(J,2,4);
+  list LL=determinecenter(L[1],L[2],2,4,0,0,Lmb,flag,0,-1); // Compute the first center
+  LL[1];  // index of variables in the center
+  LL[2];  // exponents of ideals J_4,J_3,J_2,J_1
+  LL[3];  // list of orders of J_4,J_3,J_2,J_1
+  LL[4];  // list of critical values
+  LL[5];  // components of the resolution function t
+  LL[6];  // list of D_4,D_3,D_2,D_1
+  LL[7];  // list of H_4,H_3,H_2,H_1 (exceptional divisors)
+  LL[8];  // list of all exceptional divisors acumulated
+  LL[9];  // auxiliary invariant
+  LL[10]; // intvec pointing out the last step where the function t has dropped
+
+  ring r= 0,(x(1..4)),dp;
+  list flag=identifyvar();
+  ideal J=x(1)^3-x(2)^2*x(3)^5, x(1)*x(3)^3+x(4)^5;
+  list Lmb=2,list(0,0,0,0),list(0,0,0,0),list(0,0,0,0),iniD(4),iniD(4),list(0,0,0,0),-1;
+  list L2=data(J,2,4);
+  list L3=determinecenter(L2[1],L2[2],2,4,0,0,Lmb,flag,0,-1); // Example with rational exponents in E-Coeff
+  L3[1]; // index of variables in the center
+  L3[2]; // exponents of ideals J_4,J_3,J_2,J_1
+  L3[3]; // list of orders of J_4,J_3,J_2,J_1
+  L3[4]; // list of critical values
+  L3[5]; // components of the resolution function
+}
+////////////////////////////////////////////////////////
+// idchart= identity number of the current chart
+// infochart=chart[idchart] information related to the chart to blow up
+// infochart= int parent,int Y,intvec a,list expJ,list Coef, list flag,                // NEEDED FOR THE RESOLUTION
+//            intvec Hhist, list blwhist, module path, list hipercoef, list hiperexp   // NEEDED FOR THE OUTPUT
+
+// NOTE: IT IS NOT NECESSARY TAKE INTO ACCOUNT "y" VARIABLES BECAUSE THE CENTER IS ALREADY GIVEN
+
+proc Blowupcenter(list center,int idchart,int nchart,list infochart,number c,int n,int currentstep)
+"USAGE: Blowupcenter(center,id,nchart,infochart,c,n,cstep);
+        center, infochart lists, id, nchart, n, cstep integers, c number
+COMPUTE: The blowing up at the chart IDCHART along the given center
+RETURN:  new affine charts and related information, see example
+EXAMPLE: example Blowupcenter; shows an example
+"
+{int num,i,j,k,l,parent,Y,lon,m,m2;
+ intvec a,Hhist,auxHhist;
+ number auxsum, auxsum2;
+ list sons,aux,expJ,blexpJ,blD;
+ list auxstep,Coef;
+ list auxchart,auxchart1,info,flaglist;
+ list auxblwhist,blwhist,hipercoef,hiperexp;
+module auxpath,auxp2;
+
+parent=idchart;
+num=size(center);
+
+// Transform to intvec the list of variables defining the center
+  a=center[1];
+  for (i=2;i<=num;i++){a=a,center[i];}
+
+expJ=infochart[4];
+Coef=infochart[5];
+flaglist=infochart[6];
+Hhist=infochart[7];
+blwhist=infochart[8];
+auxpath=infochart[9];
+hipercoef=infochart[10];
+hiperexp=infochart[11];
+
+l=size(expJ);
+
+// input for the loop
+blexpJ=expJ;
+
+// making the blowing up in the i-th chart
+for (i=1;i<=num;i++)
+{
+// we assign the current number of charts +1 to the i-th chart
+idchart=nchart+1;
+nchart=nchart+1;
+aux=idchart;
+sons=sons+aux;
+
+auxstep[i]=currentstep+1;
+
+Y=center[i];
+
+// The blowing up
+
+ for (j=1;j<=l;j++){lon=size(Coef[j]);
+                   if (lon==1){for (m=1;m<=n;m++){for (m2=1;m2<=num;m2++){
+                                                    if (m==center[m2]){auxsum=auxsum+ expJ[j][1][m];}}}
+                               blexpJ[j][1][Y]=auxsum-c;
+                               auxsum=0;}                   // monomial
+                   else {for (m=1;m<=n;m++){for (m2=1;m2<=num;m2++){
+                                              if (m==center[m2]){auxsum=auxsum+expJ[j][1][m];
+                                                                auxsum2=auxsum2+expJ[j][2][m];}}}
+                         blexpJ[j][1][Y]=auxsum-c;
+                         blexpJ[j][2][Y]=auxsum2-c;
+                         auxsum=0; auxsum2=0;}               // binomial
+                  }
+
+
+auxHhist=Hhist,Y;                        // history of the exceptional divisors in this chart
+auxblwhist=tradblwup(blwhist,n,Y,a,num); // history of the blow ups in this chart
+
+auxp2=auxpath,[parent,i];
+
+auxchart1=parent,Y,a,blexpJ,Coef,flaglist,auxHhist,auxblwhist,auxp2,hipercoef,hiperexp;
+
+// Coef, flaglist are not modified after the blowing-up, the hyperbolic information is the same as in the parent chart
+
+auxchart[i]=auxchart1;
+
+// Inicializating the exponents of J for the next chart
+
+blexpJ=expJ;
+}
+// end of the loop
+
+// we add its sons to the current chart
+infochart=infochart+sons;
+info[1]=infochart;
+
+return(info,auxchart,nchart,auxstep,num);
+}
+example
+{"EXAMPLE:"; echo = 2;
+ring r = 0,(x(1),y(2),x(3),y(4),x(5..7)),dp;
+list flag=identifyvar();
+ideal J=x(1)^3-x(3)^2*y(4)^2,x(1)*x(7)*y(2)-x(6)^3*x(5)*y(4)^3,x(5)^3-x(5)^3*y(2)^2;
+list Lmb=2,list(0,0,0,0,0,0,0),list(0,0,0,0,0,0,0),list(0,0,0,0,0,0,0),iniD(7),iniD(7),list(0,0,0,0,0,0,0),-1;
+list L=data(J,3,7);
+list L2=determinecenter(L[1],L[2],2,7,0,0,Lmb,flag,0,-1); // Computing the center
+module auxpath=[0,-1];
+list infochart=0,0,0,L[2],L[1],flag,0,list(0,0,0,0,0,0,0),auxpath,list(),list();
+list L3=Blowupcenter(L2[1],1,1,infochart,2,7,0);
+L3[1]; // current chart (parent,Y,center,expJ,Coef,flag,Hhist,blwhist,path,hipercoef,hiperexp) with sons: [12],...,[16]
+L3[2][1]; // information of its first son, write L3[2][2],...,L3[2][5] to see the other sons
+L3[3];    // current number of charts
+L3[4];    // step/level associated to each son
+L3[5];    // number of variables in the center
+}
+//////////////////////////////////////////////////////////////
+
+proc tradblwup(list blwhist,int n,int Y,intvec a,int num)
+"Internal procedure - no help and no example available
+"
+{
+int i,j,blwnew;
+intvec aux,aux2;
+
+for (j=1;j<=n;j++){
+                   for (i=1;i<=num;i++){
+                                       if (j==a[i] and a[i]!=Y){blwnew=Y; break;}
+                                       else {blwnew=0;}
+                                       }
+                   aux=blwhist[j];
+                   aux2=aux,blwnew;
+                   blwhist[j]=aux2;
+                  }
+return(blwhist);
+}
+//////////////////////////////////////////////////////////////
+// It is called only when Eord(J)=0, and J!=1 it is checked inside
+// SO IT IS CALLED AFTER: maxEord(Coef,expJ,sJ,n,flaglist); --> gives (max E-order,sums)
+
+proc Nonhyp(list Coef,list expJ,int sJ,int n,list flaglist,list sums)
+"USAGE: Nonhyp(Coef,expJ,sJ,n,flaglist,sums);
+        Coef, expJ, flaglist, sums lists, sJ, n integers
+COMPUTE: The "ideal" generated by the non hyperbolic generators of J
+RETURN: lists with the following information
+        newcoef,newJ: coefficients and exponents of the non hyperbolic generators
+        totalhyp,totalgen: coefficients and exponents of the hyperbolic generators
+        flaglist: new list saying status of variables
+NOTE: the basering r is supposed to be a polynomial ring K[x,y],
+      in fact, we work in a localization of K[x,y], of type K[x,y]_y with y invertible variables.
+EXAMPLE: example Nonhyp; shows an example
+"
+{
+int i,j,k,h,lon,lon2,cont;
+number eordcontrol;
+list genhyp,listgen,listid,posnumJ,newJ,newcoef,hypcoef,hyp,aux1,aux2,aux3,aux,midlist;
+list totalhyp,totalgen;
+
+eordcontrol=0;
+
+while (eordcontrol==0 and sJ!=0)
+{
+
+// Give a positional number/flag to each generator of expJ
+
+for (i=1;i<=sJ; i++){listgen=expJ[i]; listid=i; posnumJ[i]=listgen+listid; }
+
+// Select the non hyperbolic and hyperbolic generators
+
+for (j=1;j<=sJ; j++){lon=size(Coef[j]);
+                     if (lon==1){
+
+// IS NOT NECESSARY TO CHECK IF THERE EXIST A MONOMIAL WITH ONLY UNITS, ALREADY DONE!!
+
+                                     aux1=aux1+posnumJ[j];
+                                     aux3=list();
+                                     aux3[1]=expJ[j];
+                                     newJ=newJ+aux3;
+                                     aux3[1]=Coef[j];
+                                     newcoef=newcoef+aux3;
+                                }
+
+                     else{   // CHECKING BINOMIALS, ONE TERM WITH E-ORDER ZERO GIVES HYPERBOLIC EQ
+
+                          if (sums[j][1]==0 or sums[j][2]==0){aux2=aux2+posnumJ[j];
+                                                              aux3=list();
+                                                              aux3[1]=expJ[j];
+                                                              genhyp=genhyp+aux3;
+                                                              aux3[1]=Coef[j];
+                                                              hypcoef=hypcoef+aux3;
+                                                              if (sums[j][1]==0){aux3[1]=expJ[j][2]; hyp=hyp+aux3;}
+                                                              if (sums[j][2]==0){aux3[1]=expJ[j][1]; hyp=hyp+aux3;}
+                                                             }
+                          else {aux1=aux1+posnumJ[j];
+                                aux3=list();
+                                aux3[1]=expJ[j];
+                                newJ=newJ+aux3;
+                                aux3[1]=Coef[j];
+                                newcoef=newcoef+aux3;}
+
+                          }
+                    }
+
+// NOTE: aux1 and aux2 are no needed right now!
+
+// Identify new y variables, that is, x variables in the monomials contained in hyp
+
+h=size(hyp);
+
+for (k=1;k<=h; k++){ for(i=1;i<=n; i++){ if (hyp[k][i]!=0 and flaglist[i]==0) {flaglist[i]=1;}}}
+
+// To replace x by y IT IS NECESSARY TO CHANGE THE BASERING!!! We change only the list flaglist
+
+// CHECK IF THE IDEAL IS ALREADY GENERATED BY MONOMIALS, in this case
+// WE HAVE FINISHED THE E-RESOLUTION PART, J GENERATED BY MONOMIALS AND HYPERBOLIC EQS
+
+cont=0;
+lon2=size(newJ);
+for (j=1;j<=lon2; j++){if (size(newJ[j])==1){cont=cont+1;}}
+
+if (cont==lon2){newcoef=list();
+                newJ=list();
+                totalgen=totalgen+genhyp;
+                totalhyp=totalhyp+hypcoef;
+                break;}
+
+// CHECK IF THERE ARE MORE HYPERBOLIC EQUATIONS AFTER UPDATE THE FLAG LIST
+// CHECK THE MAXIMAL E-ORDER AGAIN
+
+if (lon2==0){   // we are in the previous case, newJ=empty list, save values and exit
+
+             totalgen=totalgen+genhyp;
+             totalhyp=totalhyp+hypcoef;
+             break;
+             }
+
+midlist=maxEord(newcoef,newJ,lon2,n,flaglist);
+
+eordcontrol=midlist[1];
+
+  if (eordcontrol==0){                  // new input for the loop
+                      Coef=newcoef;
+                      expJ=newJ;
+                      sJ=lon2;
+                      sums=midlist[2]; // flaglist is already updated
+
+                      totalgen=totalgen+genhyp;
+                      totalhyp=totalhyp+hypcoef;
+
+                      hypcoef=list();
+                      genhyp=list();
+
+                      newJ=list();
+                      newcoef=list();
+                    }
+else{  // If the process is already finished we save the values and exit
+
+     totalgen=totalgen+genhyp;
+     totalhyp=totalhyp+hypcoef;
+    }
+
+} // closing while
+
+return(newcoef,newJ,totalhyp,totalgen,flaglist);
+}
+example
+{"EXAMPLE:"; echo = 2;
+ring r = 0,(x(1),y(2),x(3),y(4),x(5..7)),dp;
+list flag=identifyvar();  // List giving flag=1 to invertible variables: y(2),y(4)
+ideal J=x(1)^3-x(3)^2*y(4)^2,x(1)*x(7)*y(2)-x(6)^3*x(5)*y(4)^3,1-x(5)^2*y(2)^2;
+list L=data(J,3,7);
+list L2=maxEord(L[1],L[2],3,7,flag);
+L2[1];     // Maximum E-order
+list New=Nonhyp(L[1],L[2],3,7,flag,L2[2]);
+New[1];    // Coefficients of the non hyperbolic part
+New[2];    // Exponents of the non hyperbolic part
+New[3];    // Coefficients of the hyperbolic part
+New[4];    // New hyperbolic equations
+New[5];    // New list giving flag=1 to invertible variables: y(2),y(4),y(5)
+
+ring r = 0,(x(1..4)),dp;
+list flag=identifyvar();
+ideal J=1-x(1)^5*x(2)^2*x(3)^5, x(1)^2*x(3)^3+x(1)^4*x(4)^6;
+list L=data(J,2,4);
+list L2=maxEord(L[1],L[2],2,4,flag);
+L2[1];     // Maximum E-order
+list New=Nonhyp(L[1],L[2],2,4,flag,L2[2]);
+New;
+
+}
+//////////////////////////////////////////////////////////////
+
+proc calculateI(list Coef,list expJ,number c,int n,int Y,intvec a,number oldordI,list oldD)
+"USAGE: calculateI(Coef,expJ,c,n,Y,a,b,D);
+        Coef, expJ, D lists, c, b numbers, n,Y integers, a intvec
+RETURN: ideal I, non monomial part of J
+EXAMPLE: example calculateI; shows an example
+"
+{
+ int i,cont1,b,j;
+ number EordI,aux;
+ list D,L,expI;
+ list auxdiv,Dstar,aux1,rs;
+
+// WE NEED THE MONOMIAL PART, BUT ONLY IN DIMENSION n
+
+     auxdiv=list0(n);
+     auxdiv[Y]=oldordI-c;
+     Dstar[1]=oldD[1];
+
+     b=size(a);
+     for (i=1;i<=n;i++) {for (j=1;j<=b;j++) {if (a[j]==i) {aux=aux+oldD[1][i];}}}
+     Dstar[1][Y]=aux;
+     aux=0;
+
+     D[1]=sumlist(Dstar[1],auxdiv);
+
+   cont1=0;
+   for (i=1;i<=n;i++) {if (D[1][i]==0) {cont1=cont1+1;}}   // if it fails write listO(n)[i]
+
+   if (cont1==n) {expI=expJ;}
+   else {
+         for (i=1;i<=size(expJ);i++)
+         {rs[i]=size(Coef[i]);
+          if (rs[i]==2){ aux1=list();
+                         aux1[1]=reslist(expJ[i][1],D[1]);
+                         aux1[2]=reslist(expJ[i][2],D[1]);
+                         expI[i]=aux1;}                            // binomial
+          else {aux1=list();
+                aux1[1]=reslist(expJ[i][1],D[1]);
+                expI[i]=aux1;}}                                    // monomial
+        }
+
+return(expI);
+}
+example
+{"EXAMPLE:"; echo = 2;
+  ring r = 0,(x(1..3)),dp;
+  list flag=identifyvar();
+  ideal J=x(1)^4*x(2)^2, x(3)^3;
+  list Lmb=1,list(0,0,0),list(0,0,0),list(3),iniD(3),iniD(3),list(0,0,0),-1;
+  list L=data(J,2,3);
+  list LL=determinecenter(L[1],L[2],3,3,0,0,Lmb,flag,0,-1); // Calculate the center
+  module auxpath=[0,-1];
+  list infochart=0,0,0,L[2],L[1],flag,0,list(0,0,0),auxpath,list(),list();
+  list L3=Blowupcenter(LL[1],1,1,infochart,3,3,0); // blowing-up and looking to the x(3) chart
+  calculateI(L3[2][1][5],L3[2][1][4],3,3,3,L3[2][1][3],3,iniD(3)); //  (I_3)
+  // looking to the x(1) chart
+  calculateI(L3[2][2][5],L3[2][2][4],3,3,1,L3[2][2][3],3,iniD(3)); //  (I_3)
+}
+//////////////////////////////////////////////////////////////////////////////////////
+//                                                                                  //
+//  E-RESOLUTION: Eresol(J) subroutine computing the E-resolution of J, char 0      //
+//                                                                                  //
+//////////////////////////////////////////////////////////////////////////////////////
+
+proc Eresol(ideal J)
+"USAGE: Eresol(J); J ideal
+RETURN: The E-resolution of singularities of J in terms of the affine charts, see example
+EXAMPLE: example Eresol; shows an example
+"
+{int i,n,k,idchart,nchart,parent,Y,oldid,tnum,s,cont,control,control2,control3,cont2,val,rs2,l,cont3,tip;
+ intvec a,Hhist;
+ number c,EordJ,EordI,oldordI;
+ list L,LL,oldD,t,auxL,finalchart,chart,auxchart,newL,auxp,auxfchart,L2;
+ list Coef,expJ,expI,sons,oldOlist,oldC,oldt,oldH,allH,auxordJ,auxordI,auxmb,mobile,invariant;
+ list step,nsons,auxinv,extraL,totalinv,auxsum;
+ string empstring;
+ module auxpath;
+
+// ADDED LATER
+
+ list flag,newflag,blwhist,hipercoef,hiperexp,hipercoefson,hiperexpson;
+ intvec infobo7;
+
+export finalchart;
+// export nsons;
+// export tnum;
+// export nchart;
+// export step;
+export invariant;
+ export auxinv;
+export mobile;
+
+ n=nvars(basering);
+ flag=identifyvar();
+
+ k=size(J);
+// Checking input data
+ if (inidata(J,k)==0){return("This library only works for binomial ideals.");}
+
+idchart=1;
+nchart=1;
+parent=0;
+step=0;
+control=0;
+control2=0;
+control3=0;
+
+// Translate the input ideal to a list
+ auxL=data(J,k,n);                       // data gives (Coef,Exp)
+
+// THEREAFTER WE WORK ALL THE TIME WITH LISTS
+
+L=maxEord(auxL[1],auxL[2],k,n,flag);   // gives (max E-ord, sums)
+EordJ=L[1];
+
+// before the first blow up I=J
+EordI=EordJ;
+
+//  main loop AT EACH CHART WE MUST INICIALIZATE ALL THE VALUES AND
+// CONSTRUCT THE FIRST CHART chart[1] BEFORE THE LOOP
+
+// at the first step, before the blow up, there are no exceptional divisors, Y=0
+Y=0;
+expJ=auxL[2];
+Coef=auxL[1];
+Hhist=0;
+blwhist=list0(n);
+auxpath=[0,-1];
+hipercoef=list();   // this is for the first chart
+hiperexp=list();
+auxp=parent,Y,a,expJ,Coef,flag,Hhist,blwhist,auxpath,hipercoef,hiperexp;
+chart[1]=auxp;      // information of the first chart
+
+tip=1;
+oldOlist=list0(n);
+oldC=list0(n);
+oldC[1]=EordJ;    // non necessary here
+c=EordJ;          // the value c is given by the previous step
+oldt=list0(n);
+oldD=iniD(n);
+oldH=iniD(n);
+allH=list0(n);
+
+for (i=1;i<=n;i++){infobo7[i]=-1;}
+
+auxmb=tip,oldOlist,oldC,oldt,oldD,oldH,allH,infobo7;
+mobile[1]=auxmb;           // mobile corresponding to the first chart
+auxinv[1]=list(0);
+
+// NOTE: oldC[1] is the value c to classify the chart in one of the next cases
+
+// HERE BEGIN THE LOOP
+
+while (idchart<=nchart)   // WE PROCEED WHILE THERE EXIST UNSOLVED CHARTS
+{
+if (idchart!=1)           // WE ARE NOT IN THE FIRST CHART, INICIALIZATE ALL THE VALUES
+{
+
+parent=chart[idchart][1];
+Y=chart[idchart][2];
+a=chart[idchart][3];
+expJ=chart[idchart][4];
+Coef=chart[idchart][5];
+flag=chart[idchart][6];
+Hhist=chart[idchart][7]; // it is not necessary for the computations
+blwhist=chart[idchart][8];
+auxpath=chart[idchart][9];
+hipercoef=chart[idchart][10];
+hiperexp=chart[idchart][11];
+
+k=size(Coef);   // IT IS NECESSARY TO COMPUTE IT BECAUSE IT DECREASES IF THERE ARE HYPERBOLIC EQS
+
+auxordJ=maxEord(Coef,expJ,k,n,flag);
+EordJ=auxordJ[1];
+
+if (control==0){c=mobile[parent+1][3][1];}  // we keep c from the last step
+else {c=EordJ; control=0; }                  // we reset the value of c
+
+ if (control2==1){c=EordJ; control2=0; control3=1;}    // we reset the value of c
+
+// NOTE: oldC[1] is the value c to classify the chart in one of the next cases
+
+}
+
+// The E-order must be computed here
+
+oldid=idchart;
+
+if (EordJ<0) {print("ERROR in J in chart"); print(idchart); ~; break;}
+
+
+//-------------------------------------------------------------
+// CASE J=1, if we reset c, can happen Eord=c=0
+
+// or if there are hyperbolic equations at the beginning!!! A?ADIR!!!!
+
+// if (EordJ==0){auxfchart[1]=chart[idchart];       // WE HAVE FINISHED
+//              finalchart=finalchart+auxfchart;
+//              empstring="#";                   print("reset c and Eord=c=0"); print(idchart);
+//              invariant[idchart]=empstring;
+//              auxinv[idchart]=list(0);
+//              nsons[idchart]=0;
+//              idchart=idchart+1;}
+
+
+//----------------------------------------------------------------------
+if (EordJ>=c and EordJ!=0)      // subroutine: E-RESOLUTION OF PAIRS
+{
+  if (parent>0)
+  { LL=determinecenter(Coef,expJ,c,n,Y,a,mobile[parent+1],flag,control3,chart[parent][7]); }
+  else { LL=determinecenter(Coef,expJ,c,n,Y,a,mobile[parent+1],flag,control3,Hhist); }
+
+// determinecenter gives (center,auxJ,Olist,C,t,D,H,allH,auxinvlist,infobo7)
+
+// save current values, before the blow up
+oldOlist=LL[3];
+tip=computemcm(oldOlist);
+oldC=LL[4];
+oldt=LL[5];
+oldD=LL[6];
+oldH=LL[7];
+allH=LL[8];
+auxinv[idchart]=LL[9];
+infobo7=LL[10];
+
+auxmb=tip,oldOlist,oldC,oldt,oldD,oldH,allH,infobo7;
+mobile[idchart+1]=auxmb;
+invariant[idchart]=oldt;
+
+newL=Blowupcenter(LL[1],idchart,nchart,chart[idchart],c,n,step[idchart]);
+
+// Blowupcenter gives (info,auxchart,nchart,auxstep,num)
+
+// IMPORTANT: ADD THE NEW CHARTS AFTER EACH BLOW UP, IN ORDER TO KEEP THEM CORRECTLY
+
+step=step+newL[4];
+nsons[idchart]=newL[5];
+
+chart=chart+newL[2];
+finalchart=finalchart+newL[1];
+
+// new input for the loop
+
+idchart=idchart+1;
+nchart=newL[3];
+
+control3=0;
+
+} // END OF CASE EordJ>=c
+//---------------------------------------------------------------------
+
+else{
+
+// compute EordI=max E-order(I)
+
+expI=calculateI(Coef,expJ,c,n,Y,a,mobile[parent+1][2][1],mobile[parent+1][5]);
+k=size(expJ);                     // probably non necessary
+auxordI=maxEord(Coef,expI,k,n,flag);
+EordI=auxordI[1];
+auxsum=auxordI[2];
+
+// CASE EordI>0  DROP c AND CONTINUE
+
+if (EordI>0){idchart=idchart;  // keep the chart and back to the main loop while, dropping the value of c
+             control=1;}
+else{                          // EordI=0, so check if I=1 or not
+
+cont2=0;                       // If cont2=val then all the entries of expI are zero!!
+val=0;
+
+for (i=1;i<=k;i++) {rs2=size(Coef[i]);
+                    if (rs2==1){if (auxsum[i][1]==0){cont2=val; break;} // THERE EXIST A MONOMIAL WITH ONLY UNITS
+
+                                val=val+n;                                               // monomials
+                                for (l=1;l<=n; l++) {if (expI[i][1][l]==0) {cont2=cont2+1;}}
+                               }
+                    else{val=val+(2*n);                                                     // binomials
+                         for (l=1;l<=n; l++) {if (expI[i][1][l]==0) {cont2=cont2+1;}
+                                              if (expI[i][2][l]==0) {cont2=cont2+1;}}
+                        }
+                    }
+
+
+// CASE EordI==0 AND I=1 THIS CHART IS DONE, FINISH
+
+// NOTE: THIS CASE IS NOT MONOMIAL BECAUSE E-Sing(J,c) is empty
+
+if (cont2==val){auxfchart[1]=chart[idchart];
+                finalchart=finalchart+auxfchart;
+                empstring="#";
+                invariant[idchart]=empstring;
+                auxinv[idchart]=list(0);
+                nsons[idchart]=0;
+
+// information for the mobile
+                tip=1;
+                oldOlist=list(0);
+                oldC=list(0);
+                oldt=list(0);
+                oldD=list(0);
+                oldH=list(0);
+                allH=list(0);  // the value of the parent + the new one
+                infobo7=-1;
+
+                auxmb=tip,oldOlist,oldC,oldt,oldD,oldH,allH,infobo7;
+                mobile[idchart+1]=auxmb;
+
+                idchart=idchart+1;}
+
+else{         // CASE EordI==0 AND I!=1 --> HYPERBOLIC EQUATIONS
+
+// COMPUTE THE IDEAL OF NON HYPERBOLIC ELEMENTS
+
+extraL=Nonhyp(Coef,expI,k,n,flag,auxordI[2]);    // gives (newcoef,newI,hypcoef,genhyp,flaglist)
+
+// CHECK IF ALL THE VARIABLES ARE ALREADY INVERTIBLE
+
+newflag=extraL[5];
+chart[idchart][6]=extraL[5];          // update the status of variables
+
+cont3=0;
+for (i=1;i<=n;i++){if (newflag[i]==1){cont3=cont3+1;}}
+
+if (cont3==n){    // ALL THE VARIABLES ARE INVERTIBLE
+              auxfchart[1]=chart[idchart];
+              finalchart=finalchart+auxfchart;
+              empstring="@";
+              invariant[idchart]=empstring;
+              auxinv[idchart]=list(0);
+              nsons[idchart]=0;
+
+// information for the mobile
+                tip=1;
+                oldOlist=list(0);
+                oldC=list(0);
+                oldt=list(0);
+                oldD=list(0);
+                oldH=list(0);
+                allH=list(0);
+                infobo7=-1;
+
+                auxmb=tip,oldOlist,oldC,oldt,oldD,oldH,allH,infobo7;
+                mobile[idchart+1]=auxmb;
+
+              idchart=idchart+1;}
+else{     // OTHERWISE, CONTINUE CHEKING IF newI=0 or not
+
+Coef=extraL[1];
+expI=extraL[2];
+
+hipercoefson=extraL[3];  // Information about hyperbolic generators
+hiperexpson=extraL[4];
+
+k=size(expI);
+
+if (k==0){auxfchart[1]=chart[idchart];       // WE HAVE FINISHED
+          finalchart=finalchart+auxfchart;
+          empstring="#";                  //  no more non-hyperbolic generators in this chart
+          invariant[idchart]=empstring;
+          auxinv[idchart]=list(0);
+          nsons[idchart]=0;
+
+// information for the mobile
+                tip=1;
+                oldOlist=list(0);
+                oldC=list(0);
+                oldt=list(0);
+                oldD=list(0);
+                oldH=list(0);
+                allH=list(0);
+                infobo7=-1;
+
+                auxmb=tip,oldOlist,oldC,oldt,oldD,oldH,allH,infobo7;
+                mobile[idchart+1]=auxmb;
+
+          idchart=idchart+1;}
+
+else{           // CONTINUE WITH THE IDEAL OF NON HYPERBOLIC EQS
+
+     chart[idchart][4]=expI;   // new input ideal and coefficients
+     chart[idchart][5]=Coef;
+     chart[idchart][10]=hipercoef+hipercoefson;
+     chart[idchart][11]=hiperexp+hiperexpson;
+
+     idchart=idchart;
+     control2=1;   // it is necessary to reset the value of c
+     control3=1;   // and the previous exceptional divisors
+    }
+
+// PROBABLY IT IS NEC MORE INFORMATION !!!
+
+} // closing else otherwise
+
+    } // closing else case I!=1
+
+} // closing else for EordI=0
+
+if (EordI<0) {print("ERROR in chart"); print(idchart); ~; break;}
+
+//----------------------- guardar de momento--------
+// if (EordI==0) {auxfchart[1]=chart[idchart];
+//         finalchart=finalchart+auxfchart;
+//         L2=Gamma(expJ,c,n); // HAY QUE APLICARLO AL M NO AL J
+//         invariant[idchart]=L2[2];
+//         auxinv[idchart]=list(0);
+//         nsons[idchart]=0;
+//         idchart=idchart+1;}
+//------------------------------------------------
+
+
+} // END ELSE
+//---------------------------------------------------
+
+} // END LOOP WHILE
+
+tnum=step[nchart];
+
+totalinv=resfunction(invariant,auxinv,nchart,n);
+
+return(chart,finalchart,invariant,nchart,step,nsons,auxinv,mobile,totalinv);
+}
+example
+{"EXAMPLE:"; echo = 2;
+  ring r = 0,(x(1..2)),dp;
+  ideal J=x(1)^2-x(2)^3;
+  list L=Eresol(J);
+"Please press return after each break point to see the next element of the output list";
+  L[1][1]; // information of the first chart, L[1] list of charts
+~;
+  L[2]; // list of charts with information about sons
+~;
+  L[3]; // invariant, "#" means solved chart
+~;
+  L[4]; // number of charts, 7 in this example
+~;
+  L[5]; // height corresponding to each chart
+~;
+  L[6]; // number of sons
+~;
+  L[7]; // auxiliary invariant
+~;
+  L[8]; // H exceptional divisors and more information
+~;
+  L[9]; // complete resolution function
+
+"Second example, write L[i] to see the i-th component of the list";
+  ring r = 0,(x(1..3)),dp;
+  ideal J=x(1)^2*x(2),x(3)^3; // SOLVED!
+  list L=Eresol(J);
+  L[4];  // 16 charts
+  L[9]; // complete resolution function
+ ~;
+
+"Third example, write L[i] to see the i-th component of the list";
+  ring r = 0,(x(1..2)),dp;
+  ideal J=x(1)^3-x(1)*x(2)^3;
+  list L=Eresol(J);
+  L[4];  // 8 charts, rational exponents
+  L[9]; // complete resolution function
+~;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////
+
+proc resfunction(list invariant, list auxinv, int nchart,int n)
+"USAGE: resfunction(invariant,auxinv,nchart,n);
+        invariant, auxinv lists, nchart, n integers
+COMPUTE: Patch the resolution function
+RETURN: The complete resolution function
+EXAMPLE: example resfunction; shows an example
+"
+{
+int i,j,l,k;
+list patchfun,aux;
+
+for (i=1;i<=nchart;i++){patchfun[i]=invariant[i];}
+
+for (i=1;i<=nchart;i++){if (auxinv[i][1]!=0 and size(auxinv[i])==3){l=size(invariant[i]);
+                                                                    for (j=1;j<=l;j++){
+                                                                         if (invariant[i][j]==0){aux=auxinv[i];
+                                                                                                 patchfun[i][j]=aux;
+                                                                    if (l<n){for (k=j+1;k<=n;k++){patchfun[i][k]="*";}}}}
+
+                                                                    }
+                        else{
+                        if (auxinv[i][1]==1 and size(auxinv[i])==1){l=size(invariant[i]);
+                                                                    if (l<n){for (k=l+1;k<=n;k++){patchfun[i][k]="*";}}
+                                                                    }
+                            }
+                        }
+
+return(patchfun);
+}
+example
+{"EXAMPLE:"; echo = 2;
+ ring r = 0,(x(1..2)),dp;
+ ideal J=x(1)^2-x(2)^3;
+ list L=Eresol(J);
+ L[3]; // incomplete resolution function
+ resfunction(L[3],L[7],7,2); // complete resolution function
+}
+//////////////////////////////////////////////////////////////////////////////////////
+//                                                                                  //
+//                              MAIN PROCEDURE                                      //
+//                                                                                  //
+//////////////////////////////////////////////////////////////////////////////////////
+
+proc BINresol(ideal J)
+"USAGE: BINresol(J); J ideal
+RETURN: E-resolution of singularities of a binomial ideal J in terms of the affine charts, see example
+EXAMPLE: example BINresol; shows an example
+"
+{
+
+int p,n;
+
+p=char(basering);
+n=nvars(basering);  // already computed in Eresol, it can be improved
+
+ def rr=basering;
+
+// INTERNAL CHANGE: changing the name of the variables, only if it is necessary
+
+list Mout=changeoriginalvar();
+
+if (Mout[2]==1){
+                def r=Mout[1];
+                setring r;
+                ideal chy=maxideal(1);
+                map frr=rr,chy;
+                ideal J=frr(J);
+               }
+// else{def r=basering;}   // CHECK THAT IS NECESSARY !!!
+
+// IF WE ARE IN POSTIVE CHAR
+
+if (p>0){list Lring=ringlist(basering);
+         Lring[1]=0;
+//         def r=basering;
+         def Rnew=ring(Lring);
+         setring Rnew;
+         ideal chy=maxideal(1);
+         map fRnew=r,chy;
+         ideal J=fRnew(J);
+
+// E-RESOLUTION, Computations in char 0
+
+         list L=Eresol(J);
+
+// STEP 2: WRITE THE LOCALLY MONOMIAL IDEAL AS A MONOMIAL IDEAL
+
+// not implemented yet, CHAR p !!!!
+
+// STEP 3: DO THE E-RESOLUTION AGAIN (char 0 again)
+
+
+// generating output in char p
+
+         int q=lcmofall(L[4],L[8]);    // lcm of the denominators
+
+         list B=genoutput(L[1],L[8],L[4],L[6],n,q,p); // generate output needed for visualization
+
+
+//         setring r;                   // Back to the basering
+//         ideal chy=maxideal(1);
+//         map fr=Rnew,chy;
+//         list L=fr(L);
+//         list B=fr(B);
+
+         }
+
+else{
+
+// E-RESOLUTION
+
+ list L=Eresol(J);
+
+// STEP 2: WRITE THE LOCALLY MONOMIAL IDEAL AS A MONOMIAL IDEAL
+
+// not implemented yet
+
+// STEP 3: DO THE E-RESOLUTION AGAIN
+
+
+// generating output
+
+      int q=lcmofall(L[4],L[8]);
+
+      list B=genoutput(L[1],L[8],L[4],L[6],n,q,p);
+
+     }
+
+return(B);
+}
+example
+{"EXAMPLE:"; echo = 2;
+  ring r = 0,(x(1..2)),dp;
+  ideal J=x(1)^2-x(2)^3;
+  list B=BINresol(J);
+  B[1]; // list of final charts
+  B[2]; // list of all charts
+
+  ring r = 2,(x(1..3)),dp;
+  ideal J=x(1)^2-x(2)^2*x(3)^2;
+  list B=BINresol(J);
+  B[2]; // list of all charts
+}
+///////////////////////////////////////////////////////
+
+proc Maxord(list L,int n)
+"USAGE: Maxord(L,n); L list, n integer
+COMPUTE: Find the maximal entry of a list, input is a list defining a monomial
+RETURN: maximum entry of a list and its position
+EXAMPLE: example Maxord; shows an example
+"
+{int i,can;
+ number canmax;
+ list aux;
+
+canmax=1;
+can=1;
+for (i=1;i<=n;i++)
+{ if (L[i]>=canmax and i>=can)
+ {canmax=L[i]; can=i;}}
+
+return(canmax,can);
+}
+example
+{"EXAMPLE:"; echo = 2;
+  ring r = 0,(x(1..3)),dp;
+  ideal J=x(1)^2*x(2)*x(3)^5;
+  list L=data(J,1,3);
+  L[2]; // list of exponents
+  Maxord(L[2][1][1],3);
+}
+///////////////////////////////////////////////////////
+
+proc Gamma(list expM,number c,int n)
+"USAGE: Gamma(L,c,n); L list, c number, n integer
+COMPUTE: The Gamma function, resolution function corresponding to the monomial case
+RETURN: lists of maximum exponents in L, value of Gamma function, center of blow up
+EXAMPLE: example Gamma; shows an example
+"
+{int i,j,k,l,cont,can;
+ intvec upla;
+ number canmax;
+ list expM2,gamma,L,aux,maxlist,center,aux2;
+
+ i=1;
+ cont=0;
+ expM2=expM;
+
+ while (cont==0 and i<=n)
+{
+
+  L=Maxord(expM2,n);
+  aux=L[1];
+  maxlist=maxlist + aux;
+  can=L[2];
+
+if (i==1) {upla=can; center=can;}
+else {upla=upla,can; aux2=can; center=center+aux2;}
+
+  canmax=sum(maxlist);
+  if (canmax>=c)
+  {gamma[1]=-i; gamma[2]=canmax/c; gamma[3]=upla; cont=1;}
+  else {expM2[can]=0;}
+  i=i+1;
+}
+ return(maxlist,gamma,center);
+}
+example
+{"EXAMPLE:"; echo = 2;
+  ring r = 0,(x(1..5)),dp;
+  ideal J=x(1)^2*x(2)*x(3)^5*x(4)^2*x(5)^3;
+  list L=data(J,1,5);
+  list G=Gamma(L[2][1][1],9,5);   // critical value c=9
+  G[1]; // maximum exponents in the ideal
+  G[2]; // maximal value of Gamma function
+  G[3]; // center given by Gamma
+}
+///////////////////////////////////////////////////////
+
+proc convertdata(list C,list L, int n, list flaglist)
+"USAGE: convertdata(C,L,n,flaglist);
+        C, L, flaglist lists, n integer
+COMPUTE: Compute the ideal corresponding to the given lists C,L
+RETURN: an ideal whose coefficients are given by C, exponents given by L
+EXAMPLE: example convertdata; shows an example
+"
+{int i,j,k,a,b,lon;
+ poly aux,aux1,aux2,aux3,f;
+ ideal J;
+
+aux=poly(0);
+aux1=poly(1);
+aux2=poly(0);
+aux3=poly(1);
+
+
+k=size(L);
+for (i=1;i<=k;i++){lon=size(C[i]);
+if (lon==1){                                                // variables in the monomial
+            for (j=1;j<=n;j++){a=int(poly(L[i][1][j]));
+                               if (a!=0){
+                                         if (flaglist[j]==0){aux=poly(x(j)^a);
+                                                             aux1=aux1*aux;}
+                                         else {aux=poly(y(j)^a);
+                                               aux1=aux1*aux;}
+                                        }
+                              }
+            if (C[i][1]!=0){aux1=C[i][1]*aux1;}            // we add the coefficient
+            else {aux1=0;}
+
+            J[i]=aux1;
+            aux1=poly(1);
+           }
+
+else{                                                    // variables in the binomial
+
+     for (j=1;j<=n;j++){a=int(poly(L[i][1][j])); b=int(poly(L[i][2][j]));
+
+                        if (a!=0){
+                                  if (flaglist[j]==0){aux=poly(x(j)^a);
+                                                      aux1=aux1*aux;}
+                                  else {aux=poly(y(j)^a);
+                                        aux1=aux1*aux;}
+                                 }
+
+                        if (b!=0){
+                                  if (flaglist[j]==0){aux2=poly(x(j)^b);
+                                                      aux3=aux3*aux2;}
+                                  else {aux2=poly(y(j)^b);
+                                        aux3=aux3*aux2;}
+                                 }
+                          }
+                                                       // we add the coefficients
+   if (C[i][1]!=0){aux1=C[i][1]*aux1;}
+    else {aux1=0;}
+   if (C[i][2]!=0){aux3=C[i][2]*aux3;}
+    else {aux3=0;}
+
+   f=aux1+aux3;
+   J[i]=f;
+   aux1=poly(1);
+   aux3=poly(1);
+
+     }
+}
+return(J);
+}
+example
+{"EXAMPLE:"; echo = 2;
+  ring r = 0,(x(1..4),y(5)),dp;
+  list M=identifyvar();
+  ideal J=x(1)^2*y(5)^2-x(2)^2*x(3)^2,6*x(4)^2;
+  list L=data(J,2,5);
+  L[1]; // Coefficients
+  L[2]; // Exponents
+  ideal J2=convertdata(L[1],L[2],5,M);
+  J2;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+proc lcmofall(int nchart,list mobile)
+"USAGE: lcmofall(nchart,mobile);
+        nchart integer, mobile list of lists
+COMPUTE: Compute the lcm of the denominators of the E-orders of all the charts
+RETURN: an integer given the lcm
+NOTE: CALL BEFORE salida
+EXAMPLE: example lcmofall; shows an example
+"
+
+{
+int i,m,tip,mcmall;
+intvec numall;
+
+for (i=2;i<=nchart+1;i++){
+                          tip=mobile[i][1];
+                          if (tip!=1){numall=numall,tip;}
+                         }
+m=size(numall);
+
+if (m==1){mcmall=1;}
+else{
+     if (numall[1]==0){numall=numall[2..m];}
+     mcmall=lcm(numall);}
+
+return(mcmall);
+}
+example
+{"EXAMPLE:"; echo = 2;
+  ring r = 0,(x(1..2)),dp;
+  ideal J=x(1)^3-x(1)*x(2)^3;
+  list L=Eresol(J);
+  L[4];  // 8 charts, rational exponents
+  L[8][2][2]; // E-orders at the first chart
+  lcmofall(8,L[8]);
+}
+/////////////////////////////////////////////////////////////////////////////
+
+proc salida(int idchart,list chart,list mobile,int numson,intvec previousa,int n,int q,int p)
+"USAGE: salida(idchart,chart,mobile,numson,previousa,n,q,p);
+        idchart, numson, n, q, p integers, chart, mobile, lists, previousa intvec
+COMPUTE: CONVERT THE OUTPUT OF A CHART IN A RING, WHERE DEFINE A BASIC OBJECT (BO)
+RETURN: the ring corresponding to the chart
+EXAMPLE: example salida; shows an example
+"
+{
+int l,i,m,aux,parent,m4,j;
+intvec Hhist,EOhist,aux7,aux9;
+list expJ,Coef,BO,blwhist,Eolist,hipercoef,hiperexp;
+list flag;
+
+// chart gives: parent,Y,a,expJ,Coef,flag,Hhist,blwhist,path,hipercoef,hiperexp
+// mobile gives: tip,oldOlist,oldC,oldt,oldD,oldH,allH,infobo7;  NOTE: Eolist=mobile[2];
+
+// we need to define the suitable ring at this chart
+
+list Lring=ringlist(basering);
+def RR2=basering;
+
+flag=chart[6];
+string newl;
+
+for (l=1;l<=n; l++){if (flag[l]==1){newl=string(l);
+                                    Lring[2][l]="y("+newl+")";} }
+
+
+         def RRnew=ring(Lring);
+         setring RRnew;
+         ideal chy=maxideal(1);
+         map fRnew=RR2,chy;
+
+         list chart=fRnew(chart);
+
+         list mobile2=fRnew(mobile);
+
+
+flag=chart[6];
+
+// we need to convert expJ and Coef to an ideal
+
+expJ=chart[4];
+Coef=chart[5];
+Hhist=chart[7];
+blwhist=chart[8];
+
+// now the ideal will be correctly defined in the ring Rnew
+
+ideal J2=convertdata(Coef,expJ,n,flag);        // Computations in RRnew
+
+//------------------------------------------------------------------------------
+// START TO CREATE THE BO corresponding to this chart
+
+BO=createBO(J2);
+
+// MODIFY BO WITH THE INFORMATION OF THE CHART
+
+// BO[1] an ideal, say W_i, defining the ambient space of the i-th chart of the blowing up
+// If there are hyperbolic equations, we put them here
+
+hipercoef=chart[10];
+hiperexp=chart[11];
+
+if (size(hipercoef)!=0){
+                        ideal ambJ=convertdata(hipercoef,hiperexp,n,flag);
+                        BO[1]=ambJ;
+                       }
+
+// BO[2] an ideal defining the controlled transform
+
+BO[2]=J2;
+
+// BO[3] intvec, tupla containing the maximal E-order of BO[2]
+
+if (numson==0){BO[3]=1;}    // we write 1 if the chart is a final chart
+else{
+     Eolist=mobile2[2];     // otherwise, convert the list of E-orders in an intvec
+     m=size(Eolist);
+     aux=int(Eolist[1]*q);
+     EOhist=aux;
+
+     if (m>1){for (i=2;i<=m;i++){aux=int(Eolist[i]*q); EOhist=EOhist,aux;}}
+
+     BO[3]=EOhist;
+     }
+
+// BO[4] the list of exceptional divisors given by Hhist
+
+ BO[4]=constructH(Hhist,n,flag);
+
+// BO[5] an ideal defining the map K[W] ----> K[Wi] given by blwhist
+
+BO[5]=constructblwup(blwhist,n,chy,flag);
+
+// BO[6] an intvec, BO[6][j]=1 indicates that <BO[4][j],BO[2]>=1, i.e. the
+//                  strict transform does not meet the j-th exceptional divisor
+
+m4=size(BO[4]);
+ideal auxydeal;
+ideal Jint;
+
+for (j=1;j<=m4;j++){
+
+                    auxydeal=BO[4][j]+J2;
+                    Jint=std(auxydeal);
+
+                    if (size(Jint)==1 and Jint[1]==1){BO[6][j]=1;}
+                    else{BO[6][j]=0;}
+                   }
+
+// BO[7] intvec, the index of the first blown-up object in the resolution process
+//                leading to this object for which the value of b was BO[3]
+//                the subsequent ones are the indices for the Coeff-Objects
+//                of BO[2] used when determining the center
+//   index of last element of H^- in H
+
+
+if (numson!=0){BO[7]=mobile2[8];}  // it is always -1 at the final charts
+
+// BO[8] a matrix indicating that BO[4][i] meets BO[4][j] by BO[8][i,j]=1 for i < j
+
+if (m4>0){
+matrix aux8[m4][m4];
+
+BO[8]=aux8;
+
+ideal auxydeal2;
+ideal Jint2;
+
+for (i=1;i<=m4;i++){
+                    for (j=i+1;j<=m4;j++){
+                                        auxydeal2=BO[4][i]+BO[4][j];
+                                        Jint2=std(auxydeal2);
+
+                                        if (size(Jint2)==1 and Jint2[1]==1){BO[8][i,j]=0;}
+                                        else{ for (l=1;l<j;l++){BO[8][l,j]=1;} }
+                                        }
+
+                    }
+}
+else{ matrix aux8[1][1];
+      BO[8]=aux8;}
+
+
+// BO[9] INTERNAL DATA, second component of Villamayor resolution function,
+// only needed to use the visualization procedures
+
+ int m3=size(BO[3]);
+
+if (m3==1){aux9=intvec(0);}
+else{ aux9[1]=0;
+      for (i=2;i<=m3;i++){aux9=aux9,0;}
+    }
+
+BO[9]=aux9;
+
+//------------------------------------------------------------------------------
+
+// START TO CREATE THE extra information corresponding to this chart
+
+/////////////// Short description of data in a chart ///////////////////
+// All chart data is stored in an object of type ring, the following
+// variables are always present in such a ring:
+
+// BO:      already created
+
+// cent:  ideal, describing the upcoming center determined by the algorithm
+
+   ideal cent=tradtoideal(previousa,J2,flag);
+
+
+// path= module (autoconverted to matrix)
+// path[1][idchart]=parent[idchart] index of the parent-chart in resolution history of this chart
+// path[2][idchart]=index of this chart in relation with its brother-charts
+
+   module path=chart[9];
+
+
+// lastMap: ideal, describing the preceding blow up leading to this chart
+
+   ideal lastMap=constructlastblwup(blwhist,n,chy,flag);
+
+
+//------------------------------------------------------------------------------
+
+// EXTRA INFORMATION NEEDED
+
+  list invSat=ideal(0),aux9;
+
+
+// BACK TO THE CHAR OF THE ORIGINAL RING, IF IT HAD p>0
+
+if (p>0){
+
+         list Lring;
+         Lring=ringlist(RRnew);
+         Lring[1]=p;
+         def auxRnew=ring(Lring);
+
+         kill Lring;
+         setring auxRnew;
+ ideal chy=maxideal(1);
+ map frnew=RRnew,chy;
+ def BO=frnew(BO);
+
+// def chart=frr(chart);
+ def invSat=frnew(invSat);
+ def lastMap=frnew(lastMap);
+ def cent=frnew(cent);
+ def path=frnew(path);
+
+        }
+
+// export everything needed
+
+export BO;
+export(invSat);
+export lastMap;
+export path;
+export cent;
+
+if (p==0){return(RRnew);}
+else{
+     return(auxRnew);}
+}
+example
+{"EXAMPLE:"; echo = 2;
+  ring r = 0,(x(1..2)),dp;
+  ideal J=x(1)^2-x(2)^3;
+  list L=Eresol(J);
+  list B=salida(5,L[1][5],L[8][6],2,L[1][3][3],2,1,0); // chart 5
+  def RR=B[1];
+  setring RR;
+  BO;
+"press return to see next example"; ~;
+
+  ring r = 0,(x(1..2)),dp;
+  ideal J=x(1)^2-x(2)^3;
+  list L=Eresol(J);
+  list B=salida(7,L[1][7],L[8][8],0,L[1][5][3],2,1,0); // chart 7
+  def RR=B[1];
+  setring RR;
+  BO;
+  showBO(BO);
+"press return to see next example"; ~;
+
+  ring r = 0,(x(1..2)),dp;
+  ideal J=x(1)^3-x(1)*x(2)^3;
+  list L=Eresol(J); // 8 charts, rational exponents
+  list B=salida(1,L[1][1],L[8][2],2,0,2,2,0); // CHART 1
+  def RR=B[1];
+  setring RR;
+  BO;
+
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// CONVERT THE OUTPUT OF Eresol IN A LIST OF RINGS, WHERE A BASIC OBJECT (BO) IS DEFINED
+// IN ORDER TO INTEGRATE THIS LIBRARY INSIDE THE LIBRARY resolve.lib
+
+proc genoutput(list chart,list mobile,int nchart,list nsons,int n,int q, int p)
+"USAGE: genoutput(chart,mobile,nchart,nsons,n,q,p);
+        chart, mobile, nsons lists, nchart, n,q, p integers
+RETURN: two lists, the first one gives the rings corresponding to the final charts,
+        the second one is the list of all rings corresponding to the affine charts of the resolution process
+EXAMPLE: example genoutput; shows an example
+"
+{
+  int idchart,parent;
+  list auxlist,solvedrings,totalringlist,previousa;
+  list auxlistenp,solvedringsenp,totalringenp;
+
+// chart gives: parent,Y,a,expJ,Coef,flag,Hhist,blwhist,path,hipercoef,hiperexp
+// mobile gives: tip,oldOlist,oldC,oldt,oldD,oldH,allH,infobo7;  NOTE: Eolist=mobile[2];
+
+  idchart=1;
+
+// first loop, construct list previousa
+
+  while (idchart<=nchart)
+  {
+    if (idchart==1){previousa[1]=chart[2][3];}
+    else
+    {
+// if there are no sons, the next center is nothing
+      if (nsons[idchart]==0){previousa[idchart]=0;}
+// always fill the parent
+      parent=chart[idchart][1];
+      previousa[parent]=chart[idchart][3];
+    }
+    idchart=idchart+1;
+  }
+// HERE BEGIN THE LOOP
+  idchart=1;
+  while (idchart<=nchart)
+  {
+    def auxexit=salida(idchart,chart[idchart],mobile[idchart+1],nsons[idchart],previousa[idchart],n,q,p);
+    if (p>0)
+    { // we need the computations in char 0 too
+      def auxexitenp=salida(idchart,chart[idchart],mobile[idchart+1],nsons[idchart],previousa[idchart],n,q,0);
+    }
+    else{def auxexitenp=auxexit;}
+// we add the ring to the list of all rings
+    auxlist[1]=auxexit;
+    totalringlist=totalringlist+auxlist;
+    auxlistenp[1]=auxexitenp;
+    totalringenp=totalringenp+auxlistenp;
+// if the chart has no sons, add it to the list of final charts
+    if (nsons[idchart]==0)
+    {
+      solvedrings=solvedrings+auxlist;
+      solvedringsenp=solvedringsenp+auxlistenp;
+    }
+    auxlist=list();
+    auxlistenp=list();
+    kill auxexit;
+    kill auxexitenp;
+    idchart=idchart+1;
+  } // EXIT WHILE
+  return(solvedrings,totalringlist,solvedringsenp,totalringenp);
+}
+example
+{"EXAMPLE:"; echo = 2;
+  ring r = 0,(x(1..2)),dp;
+  ideal J=x(1)^3-x(1)*x(2)^3;
+  list L=Eresol(J);         // 8 charts, rational exponents
+  list B=genoutput(L[1],L[8],L[4],L[6],2,2,0); // generates the output
+  presentTree(B);
+  list iden0=collectDiv(B);
+  ResTree(B,iden0[1]);        // generates the resolution tree
+
+// Use presentTree(B); to see the final charts
+// To see the tree type in another shell
+//    dot -Tjpg ResTree.dot -o ResTree.jpg
+//   /usr/bin/X11/xv ResTree.jpg
+
+}
+/////////////////////////////////////////////////////////////////////
+
+proc computemcm(list Eolist)
+"USAGE: computemcm(Eolist); Eolist list
+RETURN: an integer, the least common multiple of the denominators of the E-orders
+NOTE: Make the same as lcmofall but for one chart. NECESSARY BECAUSE THE E-ORDERS ARE OF TYPE NUMBER!!
+EXAMPLE: example computemcm; shows an example
+"
+{
+  int m,i,aux,mcmchart;
+  intvec num;
+  m=size(Eolist);
+  if (m==1){mcmchart=int(denominator(Eolist[1])); return(mcmchart);}
+  if (m>1)
+  {
+    num=int(denominator(Eolist[1]));
+    for (i=2;i<=m;i++)
+    {aux=int(denominator(Eolist[i])); num=num,aux; }
+  }
+  mcmchart=lcm(num);
+  return(mcmchart);
+}
+example
+{"EXAMPLE:"; echo = 2;
+  ring r = 0,(x(1..2)),dp;
+  ideal J=x(1)^3-x(1)*x(2)^3;
+  list L=Eresol(J);   // 8 charts, rational exponents
+  L[8][2][2];         // maximal E-order at the first chart
+  computemcm(L[8][2][2]);
+
+}
+/////////////////////////////////////////////////////////////////////
+
+proc constructH(intvec Hhist,int n,list flag)
+"USAGE: constructH(Hhist,n,flag);
+        Hhist intvec, n integer, flag list
+RETURN: the list of exceptional divisors accumulated at this chart
+EXAMPLE: example constructH; shows an example
+"
+{
+  int i,j,m,l;
+  list exceplist;
+  ideal aux;
+  m=size(Hhist);
+  if (Hhist[1]==0 and m>1)
+  {
+    Hhist=Hhist[2..m]; m=m-1;
+    for (i=1;i<=m;i++)
+    {
+      l=Hhist[i];
+      if (flag[l]==0){aux=ideal(poly(x(l))); }
+      else {aux=ideal(poly(y(l))); }
+      exceplist[i]=aux;
+    }
+// eliminate repeated variables
+    for (i=1;i<=m;i++)
+    {
+      for (j=1;j<=m;j++)
+      {
+        if (Hhist[i]==Hhist[j] and i!=j)
+        {
+          if (i<j){exceplist[i]=ideal(1);}
+          if (i>j){exceplist[j]=ideal(1);}
+        }
+      }
+    }
+  }
+  else  {exceplist=list();}
+// else  {exceplist=list(ideal(0));} // IF IT FAILS USE THIS
+  return(exceplist);
+}
+example
+{"EXAMPLE:"; echo = 2;
+  ring r = 0,(x(1..3)),dp;
+  list flag=identifyvar();
+  ideal J=x(1)^4*x(2)^2, x(1)^2+x(3)^3;
+  list L=Eresol(J);   // 7 charts
+  // history of the exceptional divisors at the 7-th chart
+  L[1][7][7]; // blow ups at x(3)-th, x(1)-th and x(1)-th charts
+  constructH(L[1][7][7],3,flag);
+}
+/////////////////////////////////////////////////////////////////////
+
+proc constructblwup(list blwhist,int n,ideal chy,list flag)
+"USAGE: constructblwup(blwhist,n,chy,flag);
+        blwhist, flag lists, n integer, chy ideal
+RETURN: the ideal defining the map K[W] --> K[Wi],
+        which gives the composition map of all the blowing up leading to this chart
+NOTE: NECESSARY START WITH COLUMNS
+EXAMPLE: example constructblwup; shows an example
+"
+{
+  int i,j,m,m2;
+  poly aux2;
+
+  m=size(blwhist[1]);
+
+  for (j=1;j<=m;j++)
+  {
+    for (i=1;i<=n;i++)
+    {
+      m2=blwhist[i][j];
+// If m2!=0 this variable changes. First decide if the variable to multiply is invertible or not
+      if  (m2!=0)
+      {
+        if (flag[m2]==0){aux2=poly(x(m2));}
+        else {aux2=poly(y(m2));}
+// And then substitute this variable for the corresponding product in the whole ideal
+        if (flag[i]==0){chy=subst(chy,x(i),x(i)*aux2);}
+        else {chy=subst(chy,y(i),y(i)*aux2);}
+      }
+    }
+  }
+  return(chy);
+}
+example
+{"EXAMPLE:"; echo = 2;
+  ring r = 0,(x(1..3)),dp;
+  list flag=identifyvar();
+  ideal chy=maxideal(1);
+  ideal J=x(1)^4*x(2)^2, x(1)^2+x(3)^3;
+  list L=Eresol(J);   // 7 charts
+  // history of the blow ups at the 7-th chart, center {x(1)=x(3)=0} every time
+  L[1][7][8]; // blow ups at x(3)-th, x(1)-th and x(1)-th charts
+  constructblwup(L[1][7][8],3,chy,flag);
+}
+/////////////////////////////////////////////////////////////////////
+
+proc constructlastblwup(list blwhist,int n,ideal chy,list flag)
+"USAGE: constructlastblwup(blwhist,n,chy,flag);
+        blwhist, flag lists, n integer, chy ideal
+RETURN: the ideal defining the last blow up
+NOTE: NECESSARY START WITH COLUMNS
+EXAMPLE: example constructlastblwup; shows an example
+"
+{
+  int i,j,m,m2;
+  poly aux2;
+  m=size(blwhist[1]);
+
+  if (m>0)
+  {
+    for (i=1;i<=n;i++){ m2=blwhist[i][m];
+
+    // If m2!=0 this variable changes. First decide if the variable to multiply is invertible or not
+
+    if  (m2!=0)
+    {
+      if (flag[m2]==0){aux2=poly(x(m2));}
+      else {aux2=poly(y(m2));}
+
+// And then substitute this variable for the corresponding product in the whole ideal
+
+      if (flag[i]==0){chy=subst(chy,x(i),x(i)*aux2);}
+      else {chy=subst(chy,y(i),y(i)*aux2);}
+    }
+  }
+}
+
+return(chy);
+}
+example
+{"EXAMPLE:"; echo = 2;
+  ring r = 0,(x(1..3)),dp;
+  list flag=identifyvar();
+  ideal chy=maxideal(1);
+  ideal J=x(1)^4*x(2)^2, x(1)^2+x(3)^3;
+  list L=Eresol(J);   // 7 charts
+  // history of the blow ups at the 7-th chart, center {x(1)=x(3)=0} every time
+  L[1][7][8]; // blow ups at x(3)-th, x(1)-th and x(1)-th charts
+  constructlastblwup(L[1][7][8],3,chy,flag);
+}
+/////////////////////////////////////////////////////////////////////
+
+proc tradtoideal(intvec a,ideal J2,list flag)
+"USAGE: tradtoideal(a,J2,flag);
+        a intvec, J2 ideal, flag list
+COMPUTE: traslate to an ideal the intvec defining the center
+RETURN: the ideal of the center, given by the intvec a, or J2 if a=0
+EXAMPLE: example tradtoideal; shows an example
+"
+{
+  int i,m;
+  ideal acenter,aux2;
+
+  if (a==0)
+  {acenter=J2;}
+  else
+  {
+    m=size(a);
+    for (i=1;i<=m;i++)
+    {
+      if (flag[a[i]]==0){aux2=poly(x(a[i]));}
+      else {aux2=poly(y(a[i]));}
+
+      acenter=acenter+aux2;
+    }
+  }
+return(acenter);
+}
+example
+{"EXAMPLE:"; echo = 2;
+  ring r = 0,(x(1..3)),dp;
+  list flag=identifyvar();
+  ideal J=x(1)^4*x(2)^2, x(1)^2+x(3)^3;
+  intvec a=1,3; // first center of blowing up
+  tradtoideal(a,J,flag);
+}
+//////////////////////////////////////////////////////////////////////////////////////
+//              OPERATIONS WITH LISTS
+//////////////////////////////////////////////////////////////////////////////////////
+
+proc iniD(int n)
+"USAGE: iniD(n);   n integer
+RETURN: list of lists of zeros of size n
+EXAMPLE: example iniD; shows an example
+"
+ {int i,j;
+  list D,auxD;
+ for (j=1;j<=n; j++) {auxD[j]=0;}
+ for (i=1;i<=n; i++) {D[i]=auxD;}
+ return(D);
+ }
+example
+{"EXAMPLE:"; echo = 2;
+  iniD(3);
+}
+/////////////////////////////////////////////////////////
+
+proc sumlist(list L1,list L2)
+"USAGE: sumlist(L1,L2);   L1,L2 lists, (size(L1)==size(L2))
+RETURN: a list, sum of L1 and L2
+EXAMPLE: example sumlist; shows an example
+"
+{
+ int i,k;
+ list sumL;
+k=size(L1);
+if (size(L2)!=k) {return("ERROR en sumlist, lists must have the same size");}
+for (i=1;i<=k;i++) {sumL[i]=L1[i]+L2[i];}
+return(sumL);
+}
+example
+{"EXAMPLE:"; echo = 2;
+  list L1=1,2,3;
+  list L2=5,9,7;
+  sumlist(L1,L2);
+}
+///////////////////////////////////////////////////////
+
+proc reslist(list L1,list L2)
+"USAGE: reslist(L1,L2);  L1,L2 lists, (size(L1)==size(L2))
+RETURN: a list, subtraction of L1 and L2
+EXAMPLE: example reslist; shows an example
+"
+{
+ int i,k;
+ list resL;
+k=size(L1);
+if (size(L2)!=k) {return("ERROR en reslist, lists must have the same size");}
+for (i=1;i<=k;i++) {resL[i]=L1[i]-L2[i];}
+return(resL);
+}
+example
+{"EXAMPLE:"; echo = 2;
+  list L1=1,2,3;
+  list L2=5,9,7;
+  reslist(L1,L2);
+}
+//////////////////////////////////////////////////////
+
+proc multiplylist(list L,number a)
+"USAGE: multiplylist(L,a); L list, a number
+RETURN: list of elements of type number, multiplication of L times a
+EXAMPLE: example multiplylist; shows an example
+"
+{int i,k;
+ list newL,bb;
+ number b;
+ k=size(L);
+ for (i=1;i<=k;i++) {b=L[i]*a; bb=b; newL=newL+bb;}
+return(newL);
+}
+example
+{"EXAMPLE:"; echo = 2;
+  ring r = 0,(x(1..3)),dp;
+  list L=1,2,3;
+  multiplylist(L,1/5);
+}
+///////////////////////////////////////////////////////
+
+proc dividelist(list L1,list L2)
+"USAGE: dividelist(L1,L2);  L1,L2 lists
+RETURN: list of elements of type number, division of L1 by L2
+EXAMPLE: example dividelist; shows an example
+"
+{int i,k,k1,k2;
+list LL,bb;
+number a1,a2,b;
+k1=size(L1);
+k2=size(L2);
+if (k2!=k1) {print("ERROR en dividelist, lists must have the same size");}
+if (k1<=k2) {k=k1;}
+else {k=k2;}
+ for (i=1;i<=k;i++)
+  {a1=L1[i]; a2=L2[i]; b=a1/a2; bb=b; LL=LL+bb;}
+return(LL);
+}
+example
+{"EXAMPLE:"; echo = 2;
+  ring r = 0,(x(1..3)),dp;
+  list L1=1,2,3;
+  list L2=5,9,7;
+  dividelist(L1,L2);
+}
+///////////////////////////////////////////////////////
+
+proc createlist(list L1,list L2)
+"USAGE: createlist(L1,L2);  L1,L2 lists, (size(L1)==size(L2))
+RETURN: list of lists of two elements, the first one of L1 and the second of L2
+EXAMPLE: example createlist; shows an example
+"
+{int i,k;
+list L,aux;
+k=size(L1);
+if (size(L2)!=k) {return("ERROR en createlist, lists must have the same size");}
+L=list0(k);
+for (i=1;i<=k;i++) {if (L1[i]!=0) {aux=L1[i],L2[i]; L[i]=aux;}
+                    else {L=delete(L,i);}}
+return(L);
+}
+example
+{"EXAMPLE:"; echo = 2;
+  list L1=1,2,3;
+  list L2=5,9,7;
+  createlist(L1,L2);
+}
+///////////////////////////////////////////////////////
+static proc list0(int n)
+"USAGE: list0(n); n integer
+RETURN: list of n zeros
+EXAMPLE: example list0; shows an example
+"
+{int i;
+list L0;
+for (i=1;i<=n;i++) {L0[i]=0;}
+return(L0);
+}
+example
+{"EXAMPLE:"; echo = 2;
+  list0(4);
+}
+////////////////////////////////////////////////////////////
diff --git a/Singular/LIB/resgraph.lib b/Singular/LIB/resgraph.lib
new file mode 100644
index 0000000..3ffb6f4
--- /dev/null
+++ b/Singular/LIB/resgraph.lib
@@ -0,0 +1,791 @@
+////////////////////////////////////////////////////////////////////////////
+version="version resgraph.lib 4.0.0.0 Jun_2013 "; // $Id: 7503d1e2b1fd1c8374129422d89b5bd8b8669b28 $
+category="Visualization";
+info="
+LIBRARY:  resgraph.lib            Visualization of Resolution Data
+
+AUTHOR: A. Fruehbis-Krueger,  anne at mathematik.uni-kl.de,
+
+NOTE: This library uses the external programs surf, graphviz and imagemagick.
+@*    Input data is assumed to originate from resolve.lib and reszeta.lib
+
+PROCEDURES:
+InterDiv(M[,name])   dual graph of resolution of a surface (uses graphviz,imagemagick)
+ResTree(L,M[,name])  tree of charts of resolution (uses graphviz,imagemagick)
+finalCharts(L,...)   pictures of final charts of surface (uses surf)
+";
+
+proc InterDiv(intmat M, list #)
+"USAGE:  InterDiv(M[,name]);
+@*       M = matrix
+@*       name = string
+ASSUME:  - M is first list entry of output of 'intersectionDiv'
+@*         from library reszeta.lib
+@*       - write permission in the current directory or in the
+@*         directory in which the file with name 'name' resides
+CREATE:  file 'name.jpg' containing dual graph of resolution
+@*       if filename is given
+NOTE:    only available on UNIX-type systems and programs
+@*       'display' (imagemagick package) and 'dot' (Graphviz package) need to
+@*       be in the standard search PATH
+RETURN:  nothing, only generating graphics output in separate window
+EXAMPLE: not available (for technical reasons)
+"
+{
+  "Warning: alpha testing version of this procedure";
+  int i,j;
+  string tempstr;
+//---------------------------------------------------------------------------
+//  build up temporary filename and open file for writing
+//---------------------------------------------------------------------------
+  if(size(#)>0)
+  {
+     if((typeof(#[1])=="string") && (goodFilename(#[1])))
+     {
+        string @filename=#[1];
+     }
+     else
+     {
+        ERROR("Second argument should specify a WRITABLE file");
+     }
+  }
+  if(!defined(@filename))
+  {
+     string @filename=buildFilename("InterDiv.dot");
+  }
+  link eing=":w "+ at filename;
+//--------------------------------------------------------------------------
+// write input for external program dot to file
+//--------------------------------------------------------------------------
+  write(eing,"graph G{");
+  for(i=1;i<=ncols(M);i++)
+  {
+     if(M[i,i]!=-2)
+     {
+        tempstr=string(i)+"[shape=circle,label=\""+string(M[i,i])+"\"];";
+     }
+     else
+     {
+        tempstr=string(i)+"[shape=point,label=\" \"];";
+     }
+     write(eing,tempstr);
+  }
+  for(i=1;i<=nrows(M);i++)
+  {
+     for(j=i+1;j<=ncols(M);j++)
+     {
+        if(M[i,j]!=0)
+        {
+           tempstr=string(i) + "--" + string(j) + ";";
+           write(eing,tempstr);
+        }
+     }
+  }
+  write(eing,"}");
+  close(eing);
+//---------------------------------------------------------------------------
+// produce graphics output using the programs dot and display
+//---------------------------------------------------------------------------
+  string outfile=@filename + ".jpg";
+  if(!find(outfile,"/"))
+  {
+//--- display needs fully qualified path to file
+     outfile=system("getenv","PWD") + "/" + outfile;
+  }
+  j=system("sh","dot -Tjpg " + @filename + " -o "+ outfile);
+  j=system("sh","display " + outfile + " &");
+//---------------------------------------------------------------------------
+// clean up if necessary
+//---------------------------------------------------------------------------
+  "Currently showing graphics in separate window";
+  "Press <Return> to continue";
+  pause();
+  if((size(#)==0)&&(find(@filename,"/tmp/")))
+  {
+//--- do not leave any garbage in the public directories
+    j=system("sh","/bin/rm " + outfile + " " + @filename);
+  }
+  return();
+}
+///////////////////////////////////////////////////////////////////////////////
+//static
+proc goodFilename(string datei)
+{
+//--- check whether the specified file datei is writable for us
+  if(!system("sh","touch " + datei + " > /dev/null 2>&1"))
+  {
+     return(1);
+  }
+  else
+  {
+     return(0);
+  }
+}
+//////////////////////////////////////////////////////////////////////////////
+//static
+proc buildFilename(string datei)
+{
+  if(goodFilename(datei))
+  {
+     return(datei);
+  }
+  if(find(datei,"/"))
+  {
+     ERROR("Specified directory/file is not writable");
+  }
+  datei="/tmp/" + datei;
+  if(goodFilename(datei))
+  {
+     return(datei);
+  }
+//--- not reached
+  ERROR("At least /tmp should be writable");
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc ResTree(list re, intmat DivMat, list #)
+"USAGE:  ResTree(L,M[,name][,mark]);
+@*       L = list
+@*       M = matrix
+@*       name = string
+@*       mark = intvec
+ASSUME:  - L is the output of 'resolve' from resolve.lib
+@*       - M is first entry of output of 'collectDiv(L);' from reszeta.lib
+@*       - write permission in the current directory or in the
+@*         directory in which the file with name 'name' resides
+@*       - mark intvec of size size(L[2])
+@*            mark[i]=0 (default) border of box black
+@*            mark[i]=1 border of box red
+CREATE:  file 'name.jpg' containing the tree of charts of L
+@*       if filename is given
+NOTE:    only available on UNIX-type systems and programs
+@*       'display' (imagemagick package) and 'dot' (Graphviz package) need to
+@*       be in the standard search PATH
+RETURN:  nothing, only generating graphics output in separate window
+EXAMPLE: not available (for technical reasons)
+"
+{
+//-----------------------------------------------------------------------------
+// Initialization and definition of the temporary filename
+//-----------------------------------------------------------------------------
+  int i,j,dimC,jsave;
+  string tempstr;
+  def R=basering;
+  if(size(#)>0)
+  {
+     if(typeof(#[1])=="string")
+     {
+        if(goodFilename(#[1]))
+        {
+           string @filename=#[1];
+        }
+        else
+        {
+           ERROR("optional argument of type string "+
+                  "should specify a writable file.");
+        }
+     }
+     if(typeof(#[1])=="intvec")
+     {
+        intvec @rot=#[1];
+     }
+  }
+  if(size(#)>1)
+  {
+     if((typeof(#[2])=="string")&&(!defined(@filename)))
+     {
+        if(goodFilename(#[1]))
+        {
+           string @filename=#[1];
+        }
+        else
+        {
+           ERROR("optional argument of type string "+
+                  "should specify a writable file.");
+        }
+     }
+     if((typeof(#[2])=="intvec")&&(!defined(@rot)))
+     {
+        intvec @rot=#[2];
+     }
+  }
+  if(!defined(@filename))
+  {
+     string @filename=buildFilename("ResTree.dot");
+  }
+  if(!defined(@rot))
+  {
+     intvec @rot;
+     @rot[size(re[2])]=0;
+  }
+  link eing=":w "+ at filename;
+//----------------------------------------------------------------------------
+// writing the input to the program dot into a file
+//----------------------------------------------------------------------------
+  write(eing,"graph G{");
+  tempstr="1[shape=box,label=\"chart 1\"];";
+  write(eing,tempstr);
+  for(i=2;i<=size(re[2]);i++)
+  {
+     tempstr=string(i)+"[shape=box,label=\"chart " + string(i)
+            + "\\nE:"+string(simplify(ideal(DivMat[i,1..ncols(DivMat)]),2))
+            + " \"";
+     if(@rot[i]==1)
+     {
+        tempstr=tempstr + "color=\"red\"];";
+     }
+     else
+     {
+        tempstr=tempstr + "];";
+     }
+     write(eing,tempstr);
+  }
+  for(i=2;i<=size(re[2]);i++)
+  {
+     def S=re[2][i];
+     setring S;
+     j=int(leadcoef(path[1,ncols(path)]));
+     if(j!=jsave)
+     {
+        def T=re[2][j];
+        setring T;
+        dimC=dim(std(BO[1]+cent));
+        setring S;
+        kill T;
+     }
+     setring R;
+     kill S;
+     if(j!=jsave)
+     {
+        tempstr=string(j) + "--" + string(i) +"[label=\"d=" + string(dimC)
+               + "\"];";
+        jsave=j;
+     }
+     else
+     {
+       tempstr=string(j) + "--" + string(i) +";";
+     }
+     write(eing,tempstr);
+  }
+  write(eing,"}");
+  close(eing);
+//---------------------------------------------------------------------------
+// Create the graphics output using the programs dot and display
+//---------------------------------------------------------------------------
+  string outfile=@filename + ".jpg";
+  if(!find(outfile,"/"))
+  {
+//--- display needs fully qualified path to file
+     outfile=system("getenv","PWD") + "/" + outfile;
+  }
+  j=system("sh", "dot -Tjpg " + @filename + " -o "+ outfile);
+  j=system("sh","display " + outfile + "&");
+//---------------------------------------------------------------------------
+// Clean up public directories if necessary
+//---------------------------------------------------------------------------
+  "Currently showing graphics in separate window";
+  "Press <Return> to continue";
+  pause();
+  if(find(@filename,"/tmp/"))
+  {
+//--- do not leave any garbage in the public directories
+    j=system("sh","/bin/rm " + @filename + ".jpg "+ @filename);
+  }
+  return();
+}
+/////////////////////////////////////////////////////////////////////////////
+
+proc finalCharts(list re, list inter, intvec endiv, list #)
+"USAGE:  finalCharts(L1,L2,iv[,name]);
+@*       L1 = list
+@*       L2 = list
+@*       iv = intvec
+@*       name = string
+ASSUME:  - L1 is the output of 'resolve' from resolve.lib
+@*       - L2 is the output of 'intersectionDiv(L1)' from reszeta.lib
+@*       - iv is the first entry of the output of 'abstractR(L1)'
+@*       - write permission in the current directory or in the
+@*         directory in which the file with name 'name' resides
+CREATE:  - new windows in which surf-images of the final charts are presented
+@*       - several '.ras' files in the directory in which 'name' resides
+NOTE:    only available on UNIX-type systems
+@*       external programs 'surf' and 'display' (imagemagick package) need to be
+@*       in the standard search PATH
+RETURN:  nothing, only generating graphics output in separate window
+EXAMPLE: not available (for technical reasons)
+"
+{
+//-----------------------------------------------------------------------------
+// Initialization and Sanity Checks
+//-----------------------------------------------------------------------------
+  int i,j,k,a,b,cnt,whichE,offset,haveDcE8;
+  def R=basering;
+  list endCharts;
+  string fname,tempstr;
+  for(i=1;i<=size(endiv);i++)
+  {
+    if(endiv[i]==1)
+    {
+       endCharts[size(endCharts)+1]=i;
+//--- Sanity checks for the chart i
+       if(nvars(re[2][i])!=3)
+       {
+          ERROR("This chart is not embedded in 3-dimensional space");
+       }
+       if(defined(S)){kill S;}
+       def S=re[2][i];
+       setring S;
+       if(dim(std(BO[1]+BO[2]))!=2)
+       {
+          ERROR("Strict Transform is not a surface");
+       }
+       if(size(equidim(BO[1]+BO[2]))!=1)
+       {
+          ERROR("Strict Transform has lower dimensional components.");
+       }
+//--- put the missing information into dcE, if necessary
+       for(k=1;k<=size(dcE);k++)
+       {
+          for(j=1;j<=size(dcE[k]);j++)
+          {
+             if(deg(std(dcE[k][j][1])[1])!=0)
+             {
+                if(size(dcE[k][j][1]) < 8)
+                {
+                   setring R;
+                   k=prepareDcE(re,inter,endiv);
+                   setring S;
+                }
+                haveDcE8=1;
+                break;
+             }
+          }
+          if(haveDcE8!=0) break;
+       }
+       setring R;
+    }
+  }
+  if(!defined(colorlist))
+  {
+     list colorlist;
+     for(i=1;i<=10;i++)
+     {
+       colorlist[i]="curve_red = "+string((i-1)*25)+"; curve_green = "+
+                     string(255-(i-1)*25)+"; curve_blue = "+
+                     string(((i-1) mod 5)*50)+";";
+     }
+  }
+  else
+  {
+     "Warning!";
+     "Using colors specified in variable colorlist. No syntax checks";
+     "performed on the content of this list.";
+     "If built-in colors should be used, please rename the global";
+     "object colorlist";
+  }
+  if(ncols(inter[1])>size(colorlist))
+  {
+    ERROR("Too many exceptional curves on this surface.....");
+  }
+  if((size(endCharts)>20)&&(size(#)==0))
+  {
+    ERROR("More than 20 final charts...");
+  }
+//-----------------------------------------------------------------------------
+// Determine the basename of the temporary files
+//-----------------------------------------------------------------------------
+  if(size(#)>0)
+  {
+     if((typeof(#[1])=="string") && (goodFilename(#[1])))
+     {
+        string fnamebase=#[1];
+     }
+     else
+     {
+        ERROR("Second argument should specify a WRITABLE file");
+     }
+  }
+  if(!defined(@fnamebase))
+  {
+     string fnamebase=buildFilename("Chart");
+  }
+//-----------------------------------------------------------------------------
+// Go through all final charts and write a separate surf input file for each
+//-----------------------------------------------------------------------------
+  for(i=1;i<=size(endCharts);i++)
+  {
+     fname=fnamebase + string(endCharts[i]) + ".surf";
+     if(defined(eing)){kill eing;}
+     link eing=":w "+fname;
+//--- define surf's root finding algorithm
+     tempstr="root_finder = d_chain_bisection; epsilon = 0.000000001;";
+     write(eing,tempstr);
+//--- define image size
+     tempstr="int wid = 480;width = wid; height = wid;";
+     write(eing,tempstr);
+//--- define ambient lighting
+     tempstr="ambient=50;";
+     write(eing,tempstr);
+//--- define background colour: some shade of gray
+     tempstr="background_red=200; background_green=200; background_blue=200;";
+     write(eing,tempstr);
+//--- define surface colour (one side):
+     tempstr="surface_red=22; surface_green=150; surface_blue=255;";
+     write(eing,tempstr);
+//--- define surface colour (other side):
+     tempstr="inside_red=255; inside_green=192; inside_blue=0;";
+     write(eing,tempstr);
+//--- define scaling factor
+     tempstr="scale_x=0.5; scale_y=0.5; scale_z=0.5;";
+     write(eing,tempstr);
+//--- rotate a little bit
+     tempstr="rot_y=0.9013941717697173; rot_x=-0.5556596516994916; rot_z=0.103062920202253447;";
+     write(eing,tempstr);
+//----------------------------------------------------------------------------
+// change to the chart and extract the equation of the surface
+// then draw the surface
+//----------------------------------------------------------------------------
+     if(defined(S)){kill S;}
+     def S=re[2][endCharts[i]];
+     setring S;
+//--- define equation of strict transform (hypersurface of dim 2)
+     ideal drawJ=simplify(mstd(radical(BO[1]+BO[2]))[2],2);
+     if(size(drawJ)>1)
+     {
+//!!! unnoetig! Da kann man auch surface2,... machen
+        ERROR("Did not find generator of principal ideal " + string(drawJ));
+     }
+     tempstr="poly f = " + map2Surf(string(drawJ[1])) + ";";
+     write(eing,tempstr);
+     tempstr="surface = f;draw_surface;";
+     write(eing,tempstr);
+//----------------------------------------------------------------------------
+// now consider all exceptional curves in this chart separately
+// and draw them
+//---------------------------------------------------------------------------
+     if(!defined(dcE))
+     {
+//--- Oups, exceptional curves not yet decomposed in this chart
+//--- should not happen in practice
+        ERROR("The procedure intersectionDiv has not been used
+               on this tree of charts");
+     }
+     for(j=1;j<=size(dcE);j++)
+     {
+//--- Run through all exceptional divisors (in the embedded sense)
+        for(k=1;k<=size(dcE[j]);k++)
+        {
+//--- Run through all curves corresponding to the current divisor
+           if(deg(std(dcE[j][k][1])[1])==0)
+           {
+//--- This one is empty - skip it
+              k++;
+              if(k>size(dcE[j])) {break;}
+              continue;
+           }
+           for(a=1;a<=size(inter[3]);a++)
+           {
+//--- this curve belongs to which (Q-irred.) divisor in global numbering?
+              if(inIVList(intvec(endCharts[i],j,k),inter[3][a])) break;
+           }
+           if(a>size(inter[3]))
+           {
+//--- curve not found in list
+              ERROR("Inconsistency between data of arguments 1 and 2");
+           }
+           whichE=a;
+           offset=0;
+           for(a=1;a<whichE;a++)
+           {
+//--- count C-irred. divisors up to this (Q-irred. divisor) index
+              offset=offset+inter[4][a];
+           }
+           for(a=1;a<=size(dcE[j][k][7]);a++)
+           {
+//--- run through all C-irred divisors corresponding to this Q-irred. one
+//--- run through all generators of the ideal of the curve
+//--- unfortunately the ideal is encoded in a string,
+//--- and we need to work to find the generators
+              int tempint=find(dcE[j][k][6],",");
+              b=0;
+              cnt=1;
+              while(tempint!=0)
+              {
+                if(!find(dcE[j][k][7][a],"i"))
+                {
+//--- 1) surf can only handle real numbers ==> we ignore the other curves
+//--- 2) we can only form substrings of named strings:
+                  tempstr=dcE[j][k][6];            // give it a name
+                  tempstr=tempstr[b+1..tempint-1]; // find correct substring
+                  tempstr="poly f" + string(offset+dcE[j][k][8][a])+ "_" +
+                       string(b+1) + " = " +
+                       map2Surf(plugInNumZero(tempstr,dcE[j][k][7][a])) + ";";
+                  write(eing,tempstr);
+                  tempstr="cutsurface" + string(cnt) + " = f" +
+                       string(offset+dcE[j][k][8][a]) + "_" +string(b+1) + ";";
+                  write(eing,tempstr);
+                  cnt++;
+                }
+                b=tempint;                          // save end-mark
+                tempint=find(dcE[j][k][6],",",b+1); // next one please
+              }
+              if(!find(dcE[j][k][7][a],"i"))
+              {
+                tempstr=dcE[j][k][6];                 // as before, but for last
+                tempstr=tempstr[b+1..size(tempstr)];  // fragment
+                tempstr="poly f" + string(offset+dcE[j][k][8][a])+ "_" +
+                       string(b+1) + " = " +
+                       map2Surf(plugInNumZero(tempstr,dcE[j][k][7][a])) + ";";
+                write(eing,tempstr);
+                tempstr="cutsurface" + string(cnt)+ " = f" +
+                       string(offset+dcE[j][k][8][a]) + "_" +string(b+1) + ";";
+                write(eing,tempstr);
+                cnt++;
+              }
+//--- draw the curve on the surface
+              if(cnt>1)
+              {
+                 tempstr=colorlist[offset+dcE[j][k][8][a]];
+                 write(eing,tempstr);
+                 write(eing,"cut_with_surface;");
+              }
+              kill tempint;
+           }
+        }
+     }
+     if(!find(fnamebase,"/"))
+     {
+//--- display needs fully qualified path to file
+         if(defined(outfile)) {kill outfile;}
+         string outfile=system("getenv","PWD") + "/" + fnamebase;
+     }
+     if(!defined(outfile))
+     {
+       tempstr="filename = \"" + fnamebase + string(endCharts[i]) + ".ras\";";
+     }
+     else
+     {
+       tempstr="filename = \"" + outfile + string(endCharts[i]) + ".ras\";";
+     }
+     write(eing,tempstr);
+     tempstr="color_file_format = sun;";
+     write(eing,tempstr);
+     tempstr="save_color_image;";
+     write(eing,tempstr);
+     close(eing);
+     j=system("sh", "surf -n " + fnamebase +string(endCharts[i]) + ".surf");
+     if(!defined(outfile))
+     {
+        j=system("sh","display " + fnamebase
+                       + string(endCharts[i]) + ".ras &");
+     }
+     else
+     {
+        j=system("sh","display " + outfile
+                       + string(endCharts[i]) + ".ras &");
+        kill outfile;
+     }
+     "Currently showing graphics for chart "+string(endCharts[i])
+                    +" in separate window";
+     "Press <Return> to continue";
+     pause();
+  }
+  return(0);
+}
+//////////////////////////////////////////////////////////////////////////////
+// static
+proc plugInNumZero(string f,string num)
+{
+  int i;
+  string fStr=f;
+  i=find(fStr,"t");
+  while(i!=0)
+  {
+    fStr = string(fStr[1..i-1]) + "(" + num + ")"
+         + string(fStr[i+1..size(fStr)]);
+    i=find(fStr,"t");
+  }
+  return(fStr);
+}
+//////////////////////////////////////////////////////////////////////////////
+// static
+proc replaceInStr(string alles, string alt, string neu)
+{
+  int i=find(alles,alt);
+  while(i!=0)
+  {
+    if((i-1)<1)
+    {
+       if(size(alt)==size(alles))
+       {
+          alles=neu;
+       }
+       else
+       {
+          alles=neu + string(alles[i+size(alt)..size(alles)]);
+       }
+    }
+    else
+    {
+       if(i+size(alt)>size(alles))
+       {
+          alles=string(alles[1..i-1]) + neu;
+       }
+       else
+       {
+          alles=string(alles[1..i-1]) + neu +
+                string(alles[i+size(alt)..size(alles)]);
+       }
+    }
+    i=find(alles,alt);
+  }
+  return(alles);
+}
+/////////////////////////////////////////////////////////////////////////////
+// static
+proc map2Surf(string str)
+{
+  str=replaceInStr(str,string(var(1)),"x");
+  str=replaceInStr(str,string(var(2)),"y");
+  str=replaceInStr(str,string(var(3)),"z");
+  return(str);
+}
+/////////////////////////////////////////////////////////////////////////////
+// static
+proc prepareDcE(list re, list inter, list endCharts)
+{
+   def R=basering;
+//---Test whether we are in the irreducible surface case
+   def S=re[2][1];
+   setring S;
+   BO[2]=BO[2]+BO[1];              // make sure we are living in the smooth W
+   if(dim(std(BO[2]))!=2)
+   {
+     ERROR("The given original object is not a surface");
+   }
+   if(dim(std(slocus(BO[2])))>0)
+   {
+     ERROR("The given original object has non-isolated singularities.");
+   }
+   setring R;
+//----------------------------------------------------------------------------
+// Compute a non-embedded resolution from the given embedded one by
+// dropping redundant trailing blow-ups
+//----------------------------------------------------------------------------
+//--- compute non-embedded resolution
+   int ii,j,k,a,b,comPa;
+   list abst=abstractR(re);
+   intvec endiv=abst[1];
+   intvec deleted=abst[2];
+//--- identify the divisors in the various final charts
+   list iden0=collectDiv(re,deleted)[2];
+                                    // list of final divisors
+//----------------------------------------------------------------------------
+// For each Q-irred. divisor (specified in inter[3]), run through all
+// occurrences and identify the different C-components
+//----------------------------------------------------------------------------
+   for(ii=1;ii<=size(inter[3]);ii++)
+   {
+//--- run through all Q-irred. curves,
+//--- set up the first occurrence for reference
+      if(defined(S)) {kill S;}
+      def S=re[2][inter[3][ii][1][1]];
+                                    // inter[3] = list of Q-irred div.
+                                    // inter[3][ii] = ii-th thereof
+                                    // inter[3][ii][1] = first occurrence
+                                    // inter[3][ii][1][1] = corr. chart index
+      setring S;
+      dcE[inter[3][ii][1][2]][inter[3][ii][1][3]][8]=
+              intvec(1..ncols(dcE[inter[3][ii][1][2]][inter[3][ii][1][3]][4]));
+//--- prepare the ideal of the divisor for mapping to different chart
+      if(defined(idlist1)){kill idlist1;}
+      list idlist1;
+      idlist1[1]=dcE[inter[3][ii][1][2]][inter[3][ii][1][3]][6];
+      exportto(Top,idlist1);
+      for(j=2;j<=size(inter[3][ii]);j++)
+      {
+//--- now do the comparison with the other occurrences
+//--- 1. find a common parent for inter[3][ii][1][1] and inter[3][ii][j][1]
+         if(defined(S)){kill S;}
+         def S=re[2][inter[3][ii][j][1]];
+         setring S;
+         if(defined(opath)){kill opath;}
+         def opath=imap(re[2][inter[3][ii][1][1]],path);
+         k=1;
+         while(opath[1,k]==path[1,k])
+         {
+            k++;
+            if((k>ncols(opath))||(k>ncols(path))) break;
+         }
+         comPa=int(leadcoef(opath[1,k-1]));
+//--- 2. use fetchInTree to transfer the C-components
+         if(defined(str)) {kill str;}
+         if(defined(il)) {kill il;}
+         if(defined(mpi)) {kill mpi;}
+         if(defined(nulli)) {kill nulli;}
+         string str="idlist1";
+         attrib(str,"algext",imap(re[2][inter[3][ii][1][1]],dcE)[inter[3][ii][1][2]][inter[3][ii][1][3]][5]);
+         list il=fetchInTree(re,inter[3][ii][1][1],comPa,inter[3][ii][j][1],str,iden0,1);
+         list nulli=imap(re[2][inter[3][ii][1][1]],dcE)[inter[3][ii][1][2]][inter[3][ii][1][3]][7];
+         string mpi=imap(re[2][inter[3][ii][1][1]],dcE)[inter[3][ii][1][2]][inter[3][ii][1][3]][5];
+         if(mpi!=dcE[inter[3][ii][j][2]][inter[3][ii][j][3]][5])
+         {
+            ERROR("Problem identifying the appropriate field extension.!");
+         }
+         if(defined(ringt)){kill ringt;}
+         ring ringt=0,(t),dp;
+         if(defined(St)){kill St;}
+         def St=S+ringt;
+         setring St;
+         if(defined(strId)) {kill strId;}
+         string strId="ideal id1=" + il[1] + ";";
+         execute(strId);
+         id1=std(id1);
+         strId="ideal idj="
+                         + imap(S,dcE)[inter[3][ii][j][2]][inter[3][ii][j][3]][6]
+                         +  ";";
+         execute(strId);
+         idj=std(idj);
+         if(defined(nullj)){kill nullj;}
+         list nullj=imap(S,dcE)[inter[3][ii][1][2]][inter[3][ii][1][3]][7];
+         if(defined(rcomp)){kill rcomp;}
+         strId="ring rcomp=complex,(" +varstr(basering) +"),(" +
+                           ordstr(basering) + ");";
+         execute(strId);
+         def id1=imap(St,id1);
+         def idj=imap(St,idj);
+         ideal id10,idj0;
+         if(defined(tintvec)){kill tintvec;}
+         intvec tintvec;
+         tintvec[size(nullj)]=0;
+         for(a=1;a<=size(nullj);a++)
+         {
+            if(defined(numa)) {kill numa;}
+            strId="number numa=" + string(nullj[a]) + ";";
+            execute(strId);
+            idj0=subst(idj,t,numa);
+            for(b=1;b<=size(nulli);b++)
+            {
+               if(defined(numb)) {kill numb;}
+               strId="number numb=" + string(nulli[b]) + ";";
+               execute(strId);
+               id10=subst(id1,t,numb);
+               attrib(id10,"isSB",1);
+               if(size(reduce(idj0,id10))==0)
+               {
+                  tintvec[a]=b;
+                  break;
+               }
+            }
+            if(!find(string(tintvec),string(b)))
+            {
+~;
+               ERROR("Problem identifying C-components in different charts.");
+            }
+         }
+         setring S;
+         dcE[inter[3][ii][1][2]][inter[3][ii][1][3]][8]=tintvec;
+      }
+   }
+   return(0);
+}
diff --git a/Singular/LIB/resjung.lib b/Singular/LIB/resjung.lib
new file mode 100644
index 0000000..021c914
--- /dev/null
+++ b/Singular/LIB/resjung.lib
@@ -0,0 +1,820 @@
+////////////////////////////////////////////////////////////////////////////
+version="version resjung.lib 4.0.1.0 Nov_2014 "; // $Id: 8a7f52632c2869e127981bdafc45667b1efc800c $
+category="Commutative Algebra";
+info="
+LIBRARY:  jung.lib      Resolution of surface singularities (Desingularization)
+                           Algorithm of Jung
+AUTHOR:  Philipp Renner,   philipp_renner at web.de
+
+PROCEDURES:
+ jungresolve(J[,is_noeth])  computes a resolution (!not a strong one) of the
+                            surface given by the ideal J using Jungs Method,
+ jungnormal(J[,is_noeth])   computes a representation of J such that all it's
+                            singularities are of Hirzebruch-Jung type,
+ jungfib(J[,is_noeth])      computes a representation of J such that all it's
+                            singularities are quasi-ordinary
+";
+
+LIB "resolve.lib";
+LIB "mregular.lib";
+LIB "sing.lib";
+LIB "normal.lib";
+LIB "primdec.lib";
+
+
+//-----------------------------------------------------------------------------------------
+//Main procedure
+//-----------------------------------------------------------------------------------------
+
+proc jungfib(ideal id, list #)
+"USAGE:  jungfib(J[,is_noeth]);
+@*       J = ideal
+@*       j = int
+ASSUME:  J  = two dimensional ideal
+RETURN:  a list l of rings
+         l[i] is a ring containing two Ideals: QIdeal and BMap.
+         BMap defines a birational morphism from V(QIdeal)-->V(J), such that
+         V(QIdeal) has only quasi-ordinary singularities.
+         If is_noeth=1 the algorithm assumes J is in noether position with respect to
+         the last two variables. As a default or if is_noeth = 0 the algorithm computes
+         a coordinate change such that J is in noether position.
+         NOTE: since the noether position algorithm is randomized the performance
+         can vary significantly.
+EXAMPLE: example jungfib; shows an example.
+"
+{
+  int noeth = 0;
+  if(size(#) == 0)
+  {
+     #[1]=0;
+     noeth=0;
+  }
+  if(#[1]==1){
+    noeth=1;
+  }
+  ideal I = id;
+  I = radical(id);
+  def A = basering;
+  int n = nvars(A);
+  if(deg(NF(1,groebner(slocus(id)))) == -1){
+    list result;
+    ideal QIdeal = I;
+    ideal BMap = maxideal(1);
+    export(QIdeal);
+    export(BMap);
+    result[1] = A;
+    return(result);
+  }
+  if(char(A) <> 0){ERROR("only works for characterisitc 0");}  //dummy check
+  if(dim(I)<> 2){ERROR("dimension is unequal 2");}  //dummy check
+//Noether Normalization
+  if(noeth == 0){
+    if(n==3){
+      int pos = NoetherP_test(I);
+      if(pos ==0){
+        ideal noethpos = NoetherPosition(I);
+        map phi = A,noethpos;
+        kill noethpos,pos;
+      }
+      else{
+        ideal NoetherPos = var(pos);
+        for(int i = 1;i<=3;i++){
+          if(i<>pos){
+            NoetherPos = NoetherPos + var(i);
+          }
+        }
+        map phi = A,NoetherPos;
+        kill i,pos,NoetherPos;
+      }
+    }
+    else{
+      map phi = A,NoetherPosition(I);
+    }
+    ideal NoetherN = ideal(phi(I));  //image of id under the NoetherN coordinate change
+  }
+  else{
+    ideal NoetherN = I;
+    map phi = A,maxideal(1);
+  }
+  kill I;
+//Critical Locus
+  def C2 = branchlocus(NoetherN);
+  setring C2;
+//dim of critical locus is 0 then the normalization is an resolution
+  if(dim(clocus) == 0){
+    setring A;
+    list nor = normal(NoetherN);
+    list result;
+    int sizeofnor = size(nor[1]);
+    for(int i = 1;i<=sizeofnor;i++){
+      def R = nor[1][i];
+      setring R;
+      ideal QIdeal = norid;
+      ideal BMap = BMap;
+      export(QIdeal);
+      export(BMap);
+      result[size(result)+1] = R;
+      kill R;
+      setring A;
+    }
+    kill sizeofnor;
+    print("This is a resolution.");
+    return(result);
+  }
+
+//dim of critical locus is 1, so compute embedded resolution of the discriminant curve
+  list embresolvee = embresolve(clocus);
+
+//build the fibreproduct
+  setring A;
+  list fibreP = buildFP(embresolvee,NoetherN,phi);
+  //a list of lists, where fibreP[i] contains the information conserning
+  //the i-th chart of the fibrepoduct
+  //fibreP[i] is the ring; QIdeal the quotientideal; BMap is the map from A
+  return(fibreP);
+}
+example{
+ "EXAMPLE:";echo = 2;
+//Computing a resolution of singularities of the variety z2-x3-y3
+ ring r = 0,(x,y,z),dp;
+ ideal I = z2-x3-y3;
+//The ideal is in noether position
+ list l = jungfib(I,1);
+ def R1 = l[1];
+ def R2 = l[2];
+ setring R1;
+ QIdeal;
+ BMap;
+ setring R2;
+ QIdeal;
+ BMap;
+}
+
+proc jungnormal(ideal id,list #)
+"USAGE:  jungnormal(ideal J[,is_noeth]);
+@*       J = ideal
+@*       i = int
+ASSUME:  J  = two dimensional ideal
+RETURN:  a list l of rings
+         l[i] is a ring containing two Ideals: QIdeal and BMap.
+         BMap defines a birational morphism from V(QIdeal)-->V(J), such that
+         V(QIdeal) has only singularities of Hizebuch-Jung type.
+         If is_noeth=1 the algorithm assumes J is in noether position with respect to
+         the last two variables. As a default or if is_noeth = 0 the algorithm computes
+         a coordinate change such that J is in noether position.
+         NOTE: since the noether position algorithm is randomized the performance
+         can vary significantly.
+EXAMPLE: example jungnormal; gives an example.
+"
+{
+  int noeth = 0;
+  if(size(#) == 0)
+  {
+     #[1]=0;
+     noeth=0;
+  }
+  if(#[1]==1){
+    noeth=1;
+  }
+  def A = basering;
+  list fibreP = jungfib(id,noeth);
+  list result;
+  for(int i =1;i<=size(fibreP);i++){
+    def R1 = fibreP[i];
+    setring R1;
+    map f1 = A,BMap;
+    list nor = normal(QIdeal);
+    int sizeofnor = size(nor[1]);
+    for(int j = 1;j<=sizeofnor;j++){
+      def Ri2 = nor[1][j];
+      setring Ri2;
+      map f2 = R1,normap;
+      ideal BMap = ideal(f2(f1));
+      ideal QIdeal = norid;
+      export(BMap);
+      export(QIdeal);
+      result[size(result)+1] = Ri2;
+      kill Ri2,f2;
+      setring R1;
+    }
+    kill j,sizeofnor,R1;
+  }
+  return(result);
+}
+example{
+    "EXAMPLE:";echo = 2;
+//Computing a resolution of singularities of the variety z2-x3-y3
+    ring r = 0,(x,y,z),dp;
+    ideal I = z2-x3-y3;
+//The ideal is in noether position
+    list l = jungnormal(I,1);
+    def R1 = l[1];
+    def R2 = l[2];
+    setring R1;
+    QIdeal;
+    BMap;
+    setring R2;
+    QIdeal;
+    BMap;
+}
+
+proc jungresolve(ideal id,list #)
+"USAGE:  jungresolve(ideal J[,is_noeth]);
+@*       J = ideal
+@*       i = int
+ASSUME:  J  = two dimensional ideal
+RETURN:  a list l of rings
+         l[i] is a ring containing two Ideals: QIdeal and BMap.
+         BMap defines a birational morphism from V(QIdeal)-->V(J), such that
+         V(QIdeal) is smooth. For this the algorithm computes first with
+         jungnormal a representation of V(J) with Hirzebruch-Jung singularities
+         and then it uses Villamayor's algorithm to resolve these singularities
+         If is_noeth=1 the algorithm assumes J is in noether position with respect to
+         the last two variables. As a default or if is_noeth = 0 the algorithm computes
+         a coordinate change such that J is in noether position.
+         NOTE: since the noether position algorithm is randomized the performance
+         can vary significantly.
+EXAMPLE: example jungresolve; shows an example.
+"
+{
+  int noeth = 0;
+  if(size(#) == 0)
+  {
+     #[1]=0;
+     noeth=0;
+  }
+  if(#[1]==1){
+    noeth=1;
+  }
+  def A = basering;
+  list result;
+  list nor = jungnormal(id,noeth);
+  for(int i = 1;i<=size(nor);i++){
+    if(defined(R)==voice){kill R;}
+    def R3 = nor[i];
+    setring R3;
+    def R = changeord(list(list("dp",1:nvars(basering))));
+    setring R;
+    ideal QIdeal = imap(R3,QIdeal);
+    ideal BMap = imap(R3,BMap);
+    map f = A,BMap;
+    if(QIdeal <> 0){
+      list res = resolve(QIdeal);
+      for(int j =1;j<=size(res[1]);j++){
+        def R2 = res[1][j];
+        setring R2;
+        if(defined(QIdeal)==voice){kill QIdeal;}
+        if(defined(BMap)==voice){kill BMap;}
+        if(BO[1]<>0){ideal QIdeal = BO[1]+BO[2];}
+        else{ideal QIdeal = BO[2];}
+        map g = R,BO[5];
+        ideal BMap = ideal(g(f));
+        export(QIdeal);
+        export(BMap);
+        result[size(result)+1] = R2;
+        kill R2;
+      }
+      kill j,res;
+    }
+    else{
+      result[size(result)+1] = nor[i];
+    }
+    setring A;
+    kill R,R3;
+  }
+  return(result);
+}
+example{
+    "EXAMPLE:";echo = 2;
+//Computing a resolution of singularities of the variety z2-x3-y3
+    ring r = 0,(x,y,z),dp;
+    ideal I = z2-x3-y3;
+//The ideal is in noether position
+    list l = jungresolve(I,1);
+    def R1 = l[1];
+    def R2 = l[2];
+    setring R1;
+    QIdeal;
+    BMap;
+    setring R2;
+    QIdeal;
+    BMap;
+}
+
+//---------------------------------------------------------------------------------------
+//Critical locus for the Weierstrass map induced by the noether normalization
+//---------------------------------------------------------------------------------------
+static proc branchlocus(ideal id)
+{
+//"USAGE:  branchlocus(ideal J);
+//       J = ideal
+//ASSUME:  J  = two dimensional ideal in noether position with respect of
+//         the last two variables
+//RETURN:  A ring containing the ideal clocus respresenting the criticallocus
+// of the projection V(J)-->C^2 on the last two coordinates
+//EXAMPLE: none"
+  def A = basering;
+  int n = nvars(A);
+  list l = equidim(id);
+  int k = size(l);
+  ideal LastTwo = var(n-1),var(n);
+  ideal lowdim = 1;           //the components of id with dimension smaller 2
+  if(k>1){
+    for(int j=1;j<k;j++){
+      lowdim = intersect(lowdim,radical(l[j]));
+    }
+  }
+  kill k;
+  lowdim = radical(lowdim);
+  ideal I = radical(l[size(l)]);
+  poly product=1;
+  kill l;
+  for(int i=1; i < n-1; i++){ //elimination of all variables exept var(i),var(n-1),var(n)
+    intvec v;
+    for(int j=1; j < n-1; j++){
+      if(j<>i){
+        v[j]=1;
+      }
+      else{
+        v[j]=0;
+      }
+    }
+    v[size(v)+1]=0;
+    v[size(v)+1]=0;
+    list ringl = ringlist(A);
+    list l;
+    l[1] = "a";
+    l[2] = v;
+    list ll = insert(ringl[3],l);
+    ringl[3]=ll;
+    kill l,ll;
+    def R = ring(ringl); //now x_j > x_i > x_n-1 > x_n forall j <> i,n-1,n
+    setring R;
+    ideal J = groebner(fetch(A,I));//this eliminates the variables
+    setring A;
+    ideal J = fetch(R,J);
+    attrib(J,"isPrincipal",0);
+    if(size(J)==1){
+      attrib(J,"isPrincipal",1);
+    }
+    int index = 1;
+    if(attrib(J,"isPrincipal")==0){
+      setring R;
+      for(int j = 1;j<=size(J);j++){//determines the monic polynomial in var(i) with coefficents in C2
+        intvec w = leadexp(J[j]);
+        attrib(w,"isMonic",1);
+        for(int k = 1;k<=size(w);k++){
+          if(w[k] <> 0 && k <> i){
+            attrib(w,"isMonic",0);
+            break;
+          }
+        }
+        //kill k;
+        if(attrib(w,"isMonic")==1){
+          index = j;
+          break;
+        }
+        kill w;
+      }
+      kill j;
+      setring A;
+    }
+    product = product*resultant(J[index],diff(J[index],var(i)),var(i));
+    //Product of the discriminants, which lies in C2
+    kill index,J,v;
+  }
+  ring C2 = 0,(var(n-1),var(n)),dp;
+  setring C2;
+  ideal clocus= imap(A,product);      //the critical locus is contained in this
+  ideal I = preimage(A,LastTwo,lowdim);
+  clocus= radical(intersect(clocus,I));
+  //radical is necessary since the resultant is in gerneral not reduced
+  export(clocus);
+  return(C2);
+}
+
+//-----------------------------------------------------------------------------------------
+//Build the fibre product of the embedded resolution and the coordinate ring of the variety
+//-----------------------------------------------------------------------------------------
+
+static proc buildFP(list embresolve,ideal NoetherN, map phi){
+  def A = basering;
+  list fibreP;
+  int n = nvars(A);
+  for(int i=1;i<=size(embresolve);i++){
+    def R = embresolve[i];
+    setring R;
+    list temp = ringlist(A);
+    //data for the new ring which is, if A=K[x_1,..,x_n] and
+    //R=K[y_1,..,y_m], K[x_1,..,x_n-2,y_1,..,y_m]
+    for(int j = 1; j<= nvars(R);j++){
+       string st = string(var(j));
+       temp[2][n-2+j] = st;
+       kill st;
+    }
+    temp[4] = BO[1];
+    ideal J = BO[5];             //ideal of the resolution map
+    export(J);
+    int m = size(J);
+    def R2 = ring(temp);
+    kill temp;
+    setring R2;
+    ideal Temp=0;              //defines map from R to R2 which is the inclusion
+    for(int k=n-1;k<n-1+nvars(R);k++){
+      Temp = Temp + ideal(var(k));
+    }
+    map f = R,Temp;
+    kill Temp,k;
+    ideal FibPMI = ideal(0);    //defines the map from A to R2
+    for(int k=1;k<=nvars(A)-m;k++){
+      FibPMI=FibPMI+var(k);
+    }
+    FibPMI= FibPMI+ideal(f(J));
+    map FibMap = A,FibPMI;
+    kill f,FibPMI;
+    ideal TotalT = groebner(FibMap(NoetherN));
+    ideal QIdeal = TotalT;
+    export(QIdeal);
+    ideal FibPMap = ideal(FibMap(phi));
+    ideal BMap = FibPMap;
+    export(BMap);
+    fibreP[i] = R2;
+    setring R;
+    kill J,R,R2,k,j,m;
+  }
+  return(fibreP);
+}
+
+//-------------------------------------------------------------------------------
+//embedded resolution for curves
+//-------------------------------------------------------------------------------
+
+static proc embresolve(ideal C)
+"USAGE:  embresolve(ideal C);
+@*       C = ideal
+ASSUME:  C  = ideal of plane curve
+RETURN:  a list l of rings
+         l[i] is a ring containing a basic object BO, the result of the
+         resolution. Whereas the algorithm does not resolve normal
+         crossings of V(C)
+EXAMPLE: example embresolve shows an example
+"
+{
+  ideal J = 1;
+  attrib(J,"iswholeRing",1);
+  list primdec = equidim(C);
+  if(size(primdec)==2){
+  //zero dimensional components of the discrimiant curve are smooth
+  //an cross normally so they can be ignored in the resolution process
+    ideal Lowdim = radical(primdec[1]);
+  }
+  else{
+    J=radical(C);
+  }
+  kill primdec;
+  list l;
+  list BO = createBO(J,l);
+  kill J,l;
+  list result = resolve2(BO);
+  if(defined(Lowdim)==voice)
+  {
+    for(int i = 1;i<=size(result);i++)
+    {
+    //had zero dimensional components which I add now to the end result
+      def RingforEmbeddedResolution = result[i];
+      setring RingforEmbeddedResolution;
+      map f = R2,BO[5];
+      BO[2]=BO[2]*f(Lowdim);
+      kill RingforEmbeddedResolution,f;
+    }
+  }
+  return(result);
+}
+example
+{
+  "EXAMPLE:";echo=2;
+  //The following curve is the critical locus of the projection z2-x3-y3
+  //onto y,z-coordinates.
+  ring R = 0,(y,z),dp;
+  ideal C = z2-y3;
+  list l = embresolve(C);
+  def R1 = l[1];
+  def R2 = l[2];
+  setring R1;
+  showBO(BO);
+  setring R2;
+  showBO(BO);
+}
+
+static proc resolve2(list BO){
+//computes an embedded resolution for the basic object BO and returns
+//a list of rings with BO
+  def H = basering;
+  setring H;
+  attrib(BO[2],"smoothC",0);
+  export(BO);
+  list result;
+  result[1]=H;
+  attrib(result[1],"isResolved",0);    //has only simple normal crossings
+  attrib(result[1],"smoothC",0);       //has smooth components
+  int safety=0;                        //number of runs restricted to 30
+  while(1){
+    int count2 = 0;         //counts the number of smooth charts
+    int p = size(result);
+    for(int j = 1;j<=p;j++){
+      if(attrib(result[j],"isResolved")==0){
+        if(defined(R)){kill R;}
+        def R = result[j];
+        setring R;
+        if(attrib(result[j],"smoothC")==0){
+        //has possibly singular components so choose a singular point and blow up
+          list primdecPC = primdecGTZ(BO[2]);
+          attrib(result[j],"smoothC",1);
+          for(int i = 1;i<=size(primdecPC);i++){
+            ideal Sl = groebner(slocus(primdecPC[i][2]));
+            if(deg(NF(1,Sl))<>-1){
+              list primdecSL = primdecGTZ(Sl);
+              for(int h =1;h<=size(primdecSL);h++){
+                attrib(primdecSL[h],"isRational",1);
+              }
+              kill h;
+              if(!defined(index)){int index = 1;}
+              if(defined(blowup)){kill blowup;}
+              list blowup = blowUpBO(BO,primdecSL[index][2],3);
+              //if it has a rational singularity blow it up else choose
+              //some arbitary singular point
+              if(attrib(primdecSL[1],"isRational")==0){
+              //if we blow up a non rational singularity the exeptional divisors
+              //are reduzible so we need to separate them
+                for(int k=1;k<=size(blowup);k++){
+                  def R2=blowup[k];
+                  setring R2;
+                  list L;
+                  for(int l = 1;l<=size(BO[4]);l++){
+                    list primdecED=primdecGTZ(BO[4][l]);
+                    L = L + primdecED;
+                    kill primdecED;
+                  }
+                  kill l;
+                  BO[4] = L;
+                  blowup[k]=R2;
+                  kill L,R2;
+                }
+                kill k;
+              }
+              kill primdecSL;
+              list hlp;
+              for(int k = 1;k<j;k++){
+                hlp[k]=result[k];
+                attrib(hlp[k],"isResolved",attrib(result[k],"isResolved"));
+                attrib(hlp[k],"smoothC",attrib(result[k],"smoothC"));
+              }
+              kill k;
+              for(int k =1;k<=size(blowup);k++){
+                hlp[size(hlp)+1]=blowup[k];
+                attrib(hlp[size(hlp)],"isResolved",0);
+                attrib(hlp[size(hlp)],"smoothC",0);
+              }
+              kill k;
+              for(int k = j+1;k<=size(result);k++){
+                hlp[size(hlp)+1]=result[k];
+                attrib(hlp[size(hlp)],"isResolved",attrib(result[k],"isResolved"));
+                attrib(hlp[size(hlp)],"smoothC",attrib(result[k],"smoothC"));
+              }
+              result = hlp;
+              kill hlp,k;
+              i=size(primdecPC);
+            }
+            else{
+              attrib(result[j],"smoothC",1);
+            }
+            kill Sl;
+          }
+          kill i,primdecPC;
+          j=p;
+          break;
+        }
+        else{ //if it has smooth components determine all the intersection
+              //points and check whether they are snc or not
+          int count = 0;
+          ideal Collect = BO[2];
+          for(int i = 1;i<=size(BO[4]);i++){
+            Collect = Collect*BO[4][i];
+          }
+          list primdecSL = primdecGTZ(slocus(Collect));
+          for(int k = 1;k<=size(primdecSL);k++){
+             attrib(primdecSL[k],"isRational",1);
+
+          }
+          kill k;
+          if(defined(blowup)){kill blowup;}
+          list blowup = blowUpBO(BO,primdecSL[1][2],3);
+          if(attrib(primdecSL[1],"isRational")==0){
+            for(int k=1;k<=size(blowup);k++){
+              def R2=blowup[k];
+              setring R2;
+              list L;
+              for(int l = 1;l<=size(BO[4]);l++){
+                list primdecED=primdecGTZ(BO[4][l]);
+                L = L + primdecED;
+                kill primdecED;
+              }
+              kill l;
+              BO[4] = L;
+              blowup[k]=R2;
+              kill L,R2;
+            }
+            kill k;
+          }
+          kill Collect,i;
+          for(int i=1;i<=size(primdecSL);i++){
+            list L = BO[4];
+            L[size(L)+1]=BO[2];
+            for(int l = 1;l<=size(L);l++){
+              if(L[l][1]==1){L=delete(L,l);}
+            }
+            kill l;
+            if(normalCrossing(ideal(0),L,primdecSL[i][2])==0){
+              if(defined(blowup)){kill blowup;}
+              list blowup = blowUpBO(BO,primdecSL[i][2],3);
+              list hlp;
+              for(int k = 1;k<j;k++){
+                hlp[k]=result[k];
+                attrib(hlp[k],"isResolved",attrib(result[k],"isResolved"));
+                attrib(hlp[k],"smoothC",attrib(result[k],"smoothC"));
+              }
+              kill k;
+              for(int k =1;k<=size(blowup);k++){
+                hlp[size(hlp)+1]=blowup[k];
+                attrib(hlp[size(hlp)],"isResolved",0);
+                attrib(hlp[size(hlp)],"smoothC",1);
+              }
+              kill k;
+              for(int k = j+1;k<=size(result);k++){
+                hlp[size(hlp)+1]=result[k];
+                attrib(hlp[size(hlp)],"isResolved",attrib(result[k],"isResolved"));
+                attrib(hlp[size(hlp)],"smoothC",attrib(result[k],"smoothC"));
+              }
+              result = hlp;
+              kill hlp,k;
+              j = p;
+              break;
+            }
+            else{
+              count++;
+            }
+            kill L;
+          }
+          kill i;
+          if(count == size(primdecSL)){
+            attrib(result[j],"isResolved",1);
+          }
+          kill count,primdecSL;
+        }
+        kill R;
+      }
+      else{
+        count2++;
+      }
+    }
+    if(count2==size(result)){
+      break;
+    }
+    kill count2,j,p;
+    safety++;
+  }
+  return(result);
+}
+
+static proc NoetherP_test(ideal id)
+{
+  def A = basering;
+  list ringA=ringlist(A);
+  int index = 0;
+  if(size(id)==1 && nvars(A))
+  {  //test if V(id) = C[x,y,z]/<f>
+    list L;
+    intvec v = 1,1,1;
+    L[1] = "lp";
+    L[2] = v;
+    kill v;
+    poly f = id[1];
+    int j = 0;
+    for(int i = 1;i<=3;i++)
+    {
+      setring A;
+      list l = ringA;  //change ordering to lp and var(i)>var(j) j<>i
+      list vari = ringA[2];
+      string h = vari[1];
+      vari[1] = vari[i];
+      vari[i] = h;
+      l[2] = vari;
+      kill h,vari;
+      l[3][1] = L;
+      def R = ring(l);
+      kill l;
+      setring R;
+      ideal I = imap(A,id);
+      if(defined(v)){kill v;}
+      intvec v = leadexp(I[1]);
+      attrib(v,"isMonic",1);
+      //if(defined(k)==voice){kill k;}
+      for(int k = 2;k<=3;k++)
+      {  //checks whether f is monic in var(i)
+        if(v[k] <> 0 || v[1] == 0)
+        {
+          attrib(v,"isMonic",0);
+          j++;
+          break;
+        }
+      }
+      kill k;
+      if(attrib(v,"isMonic")==1)
+      {
+        index = i;
+        return(index);
+      }
+      kill R;
+    }
+    if(j == 3){ return(0); }
+  }
+  else{     //not yet a test for more variables
+    return(index);
+  }
+}
+
+////copied from resolve.lib/////////////////
+static proc normalCrossing(ideal J,list E,ideal V)
+"Internal procedure - no help and no example available
+"
+{
+   int i,d,j;
+   int n=nvars(basering);
+   list E1,E2;
+   ideal K,M,Estd;
+   intvec v,w;
+
+   for(i=1;i<=size(E);i++)
+   {
+      Estd=std(E[i]+J);
+      if(deg(Estd[1])>0)
+      {
+         E1[size(E1)+1]=Estd;
+      }
+   }
+   E=E1;
+   for(i=1;i<=size(E);i++)
+   {
+      v=i;
+      E1[i]=list(E[i],v);
+   }
+   list ll;
+   int re=1;
+
+   while((size(E1)>0)&&(re==1))
+   {
+      K=E1[1][1];
+      v=E1[1][2];
+      attrib(K,"isSB",1);
+      E1=delete(E1,1);
+      d=n-dim(K);
+      M=minor(jacob(K),d)+K;
+      if(deg(std(M+V)[1])>0)
+      {
+         re=0;
+         break;
+      }
+      for(i=1;i<=size(E);i++)
+      {
+         for(j=1;j<=size(v);j++){if(v[j]==i){break;}}
+         if(j<=size(v)){if(v[j]==i){i++;continue;}}
+         Estd=std(K+E[i]);
+         w=v;
+         if(deg(Estd[1])==0){i++;continue;}
+         if(d==n-dim(Estd))
+         {
+            if(deg(std(Estd+V)[1])>0)
+            {
+               re=0;
+               break;
+            }
+         }
+         w[size(w)+1]=i;
+         E2[size(E2)+1]=list(Estd,w);
+      }
+      if(size(E2)>0)
+      {
+         if(size(E1)>0)
+         {
+            E1[size(E1)+1..size(E1)+size(E2)]=E2[1..size(E2)];
+         }
+         else
+         {
+            E1=E2;
+         }
+      }
+      kill E2;
+      list E2;
+   }
+   return(re);
+}
diff --git a/Singular/LIB/resolve.lib b/Singular/LIB/resolve.lib
new file mode 100644
index 0000000..8b38a3a
--- /dev/null
+++ b/Singular/LIB/resolve.lib
@@ -0,0 +1,5070 @@
+////////////////////////////////////////////////////////////////////////////
+version="version resolve.lib 4.0.0.0 Jun_2013 "; // $Id: 799f5dc330a3415876b7220020faf0849728b275 $
+category="Algebraic Geometry";
+info="
+LIBRARY:  resolve.lib      Resolution of singularities (Desingularization)
+                           Algorithm of Villamayor
+AUTHORS:  A. Fruehbis-Krueger,  anne at mathematik.uni-kl.de,
+@*        G. Pfister,           pfister at mathematik.uni-kl.de
+
+REFERENCES:
+[1] J.Kollar: Lectures on Resolution of Singularities, Princeton University Press (2007)@*
+  (contains large overview over various known methods for curves and surfaces as well as@*
+   a detailed description of the approach in the general case)@*
+[2] A.Bravo, S.Encinas, O.Villamayor: A Simplified Proof of Desingularisation and@*
+  Applications, Rev. Math. Iberoamericana 21 (2005), 349-458@*
+  (description of the algorithmic proof of desingularization in characteristic zero
+    which underlies this implementation)@*
+[3] A.Fruehbis-Krueger: Computational Aspects of Singularities, in J.-P. Brasselet,
+  J.Damon et al.: Singularities in Geometry and Topology, World Scientific
+  Publishing, 253--327 (2007)@*
+  (chapter 4 contains a detailed discussion on algorithmic desingularization and
+  efficiency aspects thereof)
+
+PROCEDURES:
+ blowUp(J,C[,W,E]) computes the blowing up of the variety V(J) (considered
+                   as embedded in V(W)) in the (smooth) center V(C),
+ blowUp2(J,C)      computes the blowing up of the variety V(J) in the
+                   (possibly singular) center V(C)
+ Center(J[,W,E])   computes 'Villamayor'-center for blow up
+ resolve(J)        computes the desingularization of the variety V(J)
+
+ showBO(BO)      prints the content of a BO in more human readable form
+ presentTree(L)  prints the final charts in more human readable form
+ showDataTypes() prints help text for output data types
+
+ blowUpBO(BO,C)  computes the blowing up of the variety V(BO[1]) in the
+                 center V(C). BO is a list (basic object), C is an ideal
+ createBO(J,W,E) creates basic object from input data
+ CenterBO(BO)    computes the center for the next blow-up of the
+                 given basic object
+ Delta(BO)       apply the Delta-operator of [Bravo,Encinas,Villamayor]
+ DeltaList(BO)   list of results of Delta^0 to Delta^bmax
+";
+LIB "elim.lib";
+LIB "primdec.lib";
+LIB "presolve.lib";
+LIB "linalg.lib";
+LIB "sing.lib";
+///////////////////////////////////////////////////////////////////////////////
+//                      Tasks:
+//                     1) optimization of the local case
+//                     2) optimization in Coeff
+//                     3) change invariant to represent coeff=1 case
+///////////////////////////////////////////////////////////////////////////////
+
+proc showDataTypes()
+"USAGE:  showDataTypes();
+RETURN:  nothing, only pretty printing of extended version of help text
+EXAMPLE: none
+"
+{
+"                               ";
+"//////////////// Short description of data type BO ///////////////////";
+"BO[1] an ideal, say Wi, defining the ambient space of the i-th chart";
+"      of the blowing up";
+"BO[2] an ideal defining the strict transform";
+"BO[3] intvec, the first integer b such that in the original object";
+"      (Delta^b(BO[2]))==1";
+"      the subsequent integers have the same property for Coeff-Objects";
+"      of BO[2] used when determining the center";
+"BO[4] the list of exceptional divisors";
+"BO[5] an ideal defining the map K[W] ----> K[Wi]";
+"BO[6] an intvec BO[6][j]=1 indicates that <BO[4][j],BO[2]>=1, i.e. the";
+"      strict transform does not meet the j-th exceptional divisor";
+"BO[7] intvec,";
+"      the index of the first blown-up object in the resolution process";
+"      leading to this object for which the value of b was BO[3]";
+"      the subsequent ones are the indices for the Coeff-Objects";
+"      of BO[2] used when determining the center";
+"BO[i], i>7: internal data";
+"                      ";
+pause();
+"              ";
+"///////////// Short description of data in a chart ///////////////////";
+"All chart data is stored in an object of type ring, the following ";
+"variables are always present in such a ring:";
+"BO:      list of type basic object containing the variety, ambient space,";
+"         exceptional divisors and further data (see previous page)";
+"cent:    ideal, describing the upcoming center determined by the algorithm";
+"path:    module (autoconverted to matrix)";
+"         path[1][i]= (i-1)st chart in resolution history of this chart";
+"         path[2][i]= index of chart of the blow up leading to i-th chart";
+"                     in resolution history";
+"lastMap: ideal, describing the preceding blow up leading to this chart";
+"                      ";
+pause();
+"                  ";
+"///////////// Short description of type resolution data //////////////";
+"list L containing two lists:";
+"L[1]: list of rings, containing the final charts";
+"L[2]: list of rings, containing all charts created in the resolution";
+"      process";
+"The most convenient way to view these data is the procedure presentTree()";
+"from this library. Alternatively, it can be digested using tools from";
+"the libraries reszeta.lib and resgraph.lib";
+"//////////////////////////////////////////////////////////////////////";
+}
+///////////////////////////////////////////////////////////////////////////////
+proc createBO(ideal J,list #)
+"USAGE:  createBO(J[,W][,E]);
+@*       J,W = ideals
+@*       E     = list
+ASSUME:  J  = ideal containing W ( W = 0 if not specified)
+@*       E  = list of smooth hypersurfaces (e.g. exceptional divisors)
+RETURN:  list BO representing a basic object :
+         BO[1] ideal W, if W has been specified; ideal(0) otherwise
+         BO[2] ideal J
+         BO[3] intvec
+         BO[4] the list E of exceptional divisors if specified;
+               empty list otherwise
+         BO[5] an ideal defining the identity map
+         BO[6] an intvec
+         BO[7] intvec
+         BO[8] a matrix
+         entries 3,5,6,7,8 are initialized appropriately for use of CenterBO
+         and blowUpBO
+EXAMPLE: example createBO;  shows an example
+"
+{
+  ideal W;
+  list E;
+  ideal abb=maxideal(1);
+  intvec v;
+  intvec bvec;
+  intvec w=-1;
+  matrix intE;
+  if(size(#)>0)
+  {
+    if(typeof(#[1])=="ideal")
+    {
+      W=#[1];
+    }
+    if(typeof(#[1])=="list")
+    {
+      E=#[1];
+    }
+    if(size(#)>1)
+    {
+      if((typeof(#[2])=="list") && (size(E)==0))
+      {
+        E=#[2];
+      }
+      if((typeof(#[2])=="ideal") && (size(W)==0))
+      {
+        W=#[2];
+      }
+    }
+  }
+  list BO=W,J,bvec,E,abb,v,w,intE;
+  return(BO);
+}
+example
+{"EXAMPLE:";
+   echo = 2;
+   ring R=0,(x,y,z),dp;
+   ideal J=x2-y3;
+   createBO(J,ideal(z));
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc blowUp(ideal J,ideal C,list #)
+"USAGE:  blowUp(J,C[,W][,E]);
+         W,J,C = ideals,
+         E     = list
+ASSUME:  J  = ideal containing W ( W = 0 if not specified)
+@*       C  = ideal containing J
+@*       E  = list of smooth hypersurfaces (e.g. exceptional divisors)
+NOTE:    W the ideal of the ambient space, C the ideal of the center of
+         the blowup and J the ideal of the variety
+         Important difference to blowUp2:
+         - the ambient space V(W) is blown up and V(J) transformed in it
+@*         - V(C) is assumed to be non-singular
+COMPUTE: the blowing up of W in C, the exceptional locus, the strict
+         transform of J and the blowup map
+RETURN:  list, say l, of size at most size(C),
+
+         l[i] is the affine ring corresponding to the i-th chart
+         each l[i] contains the ideals
+         - aS, ideal of the blownup ambient space
+         - sT, ideal of the strict transform
+         - eD, ideal of the exceptional divisor
+         - bM, ideal corresponding to the blowup map
+
+         l[i] also contains a list BO, which can best be viewed with showBO(BO)
+         detailed information on the data type BO can be viewed via the
+         command showDataTypes();
+EXAMPLE: example blowUp;  shows an example
+"
+{
+  def S=basering;
+  ideal W;
+  list E;
+  ideal abb=maxideal(1);
+  intvec v;
+  intvec bvec;
+  intvec w=-1;
+  matrix intE;
+  if(size(#)>0)
+  {
+    if(typeof(#[1])=="ideal")
+    {
+      W=#[1];
+    }
+    if(typeof(#[1])=="list")
+    {
+      E=#[1];
+    }
+    if(size(#)>1)
+    {
+      if((typeof(#[2])=="list") && (size(E)==0))
+      {
+        E=#[2];
+      }
+      if((typeof(#[2])=="ideal") && (size(W)==0))
+      {
+        W=#[2];
+      }
+    }
+  }
+  list BO=W,J,bvec,E,abb,v,w,intE;
+  int locaT;
+  export locaT;
+  list blow=blowUpBO(BO,C,0);
+  kill locaT;
+  int i;
+  for(i=1;i<=size(blow);i++)
+  {
+     def Q=blow[i];
+     setring Q;
+     ideal aS=BO[1];
+     ideal sT=BO[2];
+     ideal eD=BO[4][size(BO[4])];
+     ideal bM=BO[5];
+     kill lastMap;
+     kill thisChart;
+     export(aS);
+     export(sT);
+     export(eD);
+     export(bM);
+     blow[i]=Q;
+     setring S;
+     kill Q;
+  }
+  return(blow);
+}
+example
+{"EXAMPLE:";
+   echo = 2;
+   ring R=0,(x,y),dp;
+   ideal J=x2-y3;
+   ideal C=x,y;
+   list blow=blowUp(J,C);
+   def Q=blow[1];
+   setring Q;
+   aS;
+   sT;
+   eD;
+   bM;
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc blowUp2(ideal J,ideal C)
+"USAGE:  blowUp2(J,C);
+         J,C = ideals,
+ASSUME:  C  = ideal containing J
+NOTE:    C the ideal of the center of the blowup and J the ideal
+         of the variety
+         Important differences to blowUp:
+         - V(J) itself is blown up, not the ambient space
+         - C is not assumed to be non-singular
+COMPUTE: the blowing up of J in C, the exceptional locus and the blow-up
+         map
+RETURN:  list, say l, of size at most size(C),
+
+         l[i] is the affine ring corresponding to the i-th chart
+         each l[i] contains the ideals
+         - Jnew, ideal of the blownup J
+         - eD, ideal of the new exceptional divisor
+         - bM, ideal corresponding to the blowup map
+
+EXAMPLE: example blowUp2;  shows an example
+"
+{
+//----------------------------------------------------------------------------
+// Initialization and basic sanity checks of the input data
+//----------------------------------------------------------------------------
+  int i,j;
+  def S=basering;
+  def laM=maxideal(1);
+//--- number of generators of C should be as small as possible
+  def mstdC=mstd(C);
+  if(ncols(mstdC[1])<ncols(mstdC[2]))
+  {
+     C=mstdC[1];
+  }
+  else
+  {
+     C=mstdC[2];
+  }
+  C=simplify(interred(C),2);
+//--- the empty set is not a good center ;-)
+  if(deg(lead(C[1]))==0)
+  {
+     ERROR("Your chosen center was the empty set. Exiting.");
+  }
+//--- V(C) should be a subset of V(J)
+  if(size(reduce(J,std(C)))>0)
+  {
+     ERROR("V(J) does not contain V(C). Exiting.");
+  }
+//---------------------------------------------------------------------------
+// To compute the blowing up, we need to consider
+//       (K[x_1,\dots,x_n]/J)[t*C[1],...,t*C[m]]
+// which we want to represent as a quotient of K[x_1,...,x_n,y_1,..,y_m]
+// by an ideal obtained by elimination of the extra variable t.
+// (in the comments n=nvars(S) and m=ncols(C))
+//---------------------------------------------------------------------------
+//--- set up rings for the elimination
+  string r1="ring R=("+charstr(basering)+"),(x(1.."+string(nvars(S));
+  r1=r1+"),y(1.."+string(ncols(C))+")),dp;";
+  string r1t="ring Rt=("+charstr(basering)+"),(x(1.."+string(nvars(S));
+  r1t=r1t+"),y(1.."+string(ncols(C))+"),t),(dp,dp(1));";
+  execute(r1);       // ring for describing the transforms
+  execute(r1t);      // like r1, but with additional variable t
+  def J=fetch(S,J);
+  def C=fetch(S,C);
+//--- we need to eliminate t from J,y(1)-t*C[1],...y(m)-t*C[m]
+  ideal elId=J;
+  for(i=1;i<=ncols(C);i++)
+  {
+     elId=elId,y(i)-t*C[i];
+  }
+  elId=eliminate(elId,t);   // ideal describing the transform of J
+  setring R;                // get rid of t
+  def elId=fetch(Rt,elId);
+  def E=fetch(S,C);         // determine exceptional divisor
+  E=E+elId;
+  def laM0=fetch(S,laM);    // the blowup map
+//-----------------------------------------------------------------------------
+// The result is now represented in an A^n \times P^{m-1}, hence
+// involving n+m variables. For further computations we would like
+// to pass to charts to keep the total number of variables as low as
+// possible
+//----------------------------------------------------------------------------
+  list resList;
+  ideal Jsub;
+  ideal Esub;
+  ideal laM;
+  ideal testId;
+  map phi;
+  list templist;
+  for(i=1;i<=nvars(R)-nvars(S);i++)
+  {
+//--- first pass elId and E on to the i-th chart
+      Jsub=std(subst(elId,y(i),1));
+      if(deg(Jsub[1])==0)
+      {
+//--- transform does not meet this chart ==> ignore it
+         i++;
+         continue;
+      }
+      Esub=std(subst(E,y(i),1));
+//--- now get rid of unnecessary variables
+//--- first by appropriate coordinate changes
+      templist=elimpart(Jsub);
+      if(size(templist[2])>0)
+      {
+         phi=R,templist[5];
+         Jsub=phi(Jsub);
+         Jsub=simplify(interred(Jsub),2);
+         Esub=phi(Esub);
+         Esub=simplify(interred(Esub),2);
+         laM=phi(laM0);
+      }
+      else
+      {
+         laM=laM0;
+      }
+//--- then by dropping non-occuring variables
+      testId=Jsub,Esub,laM;
+      templist=findvars(testId,0);
+      if(size(templist[1])<nvars(R))
+      {
+         for(j=1;j<=size(templist[4]);j++)
+         {
+            laM=subst(laM,var(templist[4][j]),0);
+         }
+         execute("ring Rnew=("+charstr(basering)+"),("+string(templist[1])+"),dp;");
+         ideal Jnew=imap(R,Jsub);
+         ideal eD=imap(R,Esub);
+         ideal bM=imap(R,laM);
+      }
+      else
+      {
+         def Rnew=basering;
+         ideal Jnew=Jsub;
+         ideal eD=Esub;
+         ideal bM=laM;
+      }
+//--- export the relevant data of this ring and add the ring to the list
+      export Jnew;
+      export eD;
+      export bM;
+      resList[size(resList)+1]=Rnew;
+      setring R;
+      kill Rnew;
+  }
+  setring S;
+  return(resList);
+}
+example
+{  "EXAMPLE:";
+   echo = 2;
+   ring r=0,(x,y,z),dp;
+   ideal I=z2-x^3*y^2;
+   ideal C=z,xy;
+   list li=blowUp2(I,C);
+   size(li);                  // number of charts
+   def S1=li[1];
+   setring S1;                // chart 1
+   basering;
+   Jnew;
+   eD;
+   bM;
+   def S2=li[2];
+   setring S2;                // chart 2
+   basering;
+   Jnew;
+   eD;
+   bM;
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc Center(ideal J,list #)
+"USAGE:  Center(J[,W][,E])
+@*       J,W = ideals
+@*       E   = list
+ASSUME:  J  = ideal containing W ( W = 0 if not specified)
+@*       E  = list of smooth hypersurfaces (e.g. exceptional divisors)
+COMPUTE: the center of the blow-up of J for the resolution algorithm
+         of [Bravo,Encinas,Villamayor]
+RETURN:  ideal, describing the center
+EXAMPLE: example Center;  shows an example
+"
+{
+  ideal W;
+  list E;
+  ideal abb=maxideal(1);
+  intvec v;
+  intvec bvec;
+  intvec w=-1;
+  matrix intE;
+  if(size(#)>0)
+  {
+    if(typeof(#[1])=="ideal")
+    {
+      W=#[1];
+    }
+    if(typeof(#[1])=="list")
+    {
+      E=#[1];
+    }
+    if(size(#)>1)
+    {
+      if((typeof(#[2])=="list") && (size(E)==0))
+      {
+        E=#[2];
+      }
+      if((typeof(#[2])=="ideal") && (size(W)==0))
+      {
+        W=#[2];
+      }
+      if(size(#)==3){bvec=#[3];}
+    }
+  }
+
+  list BO=W,J,bvec,E,abb,v,w,intE,intvec(0);
+  if(defined(invSat)){kill invSat;}
+  list invSat=ideal(0),intvec(0);
+  export(invSat);
+
+  list re=CenterBO(BO);
+  ideal cent=re[1];
+  return(cent);
+}
+example
+{  "EXAMPLE:";
+   echo = 2;
+   ring R=0,(x,y),dp;
+   ideal J=x2-y3;
+   Center(J);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc blowUpBO(list BO, ideal C,int e)
+"USAGE:  blowUpBO (BO,C,e);
+@*       BO = basic object, a list: ideal W,
+@*                                  ideal J,
+@*                                  intvec b,
+@*                                  list Ex,
+@*                                  ideal ab,
+@*                                  intvec v,
+@*                                  intvec w,
+@*                                  matrix M
+@*       C  = ideal
+@*       e  = integer (0 usual blowing up, 1 deleting extra charts, 2 deleting
+@*            no charts )
+ASSUME:  R  = basering, a polynomial ring, W an ideal of R,
+@*       J  = ideal containing W,
+@*       C  = ideal containing J
+COMPUTE: the blowing up of BO[1] in C, the exeptional locus, the strict
+         transform of BO[2]
+NOTE:    blowUpBO may be applied to basic objects in the sense of
+@*       [Bravo, Encinas, Villamayor] in the following referred to as BO and
+@*       to presentations in the sense of [Bierstone, Milman] in the following
+@*       referred to as BM.
+RETURN:  a list l of length at most size(C),
+         l[i] is a ring containing an object BO resp. BM:
+@*         BO[1]=BM[1] an ideal, say Wi, defining the ambient space of the
+               i-th chart of the blowing up
+@*         BO[2]=BM[2] an ideal defining the strict transform
+@*         BO[3] intvec, the first integer b such that in the original object
+               (Delta^b(BO[2]))==1
+               the subsequent integers have the same property for Coeff-Objects
+               of BO[2] used when determining the center
+@*         BM[3] intvec, BM[3][i] is the assigned multiplicity of BM[2][i]
+@*         BO[4]=BM[4] the list of exceptional divisors
+@*         BO[5]=BM[5] an ideal defining the map K[W] ----> K[Wi]
+@*         BO[6]=BM[6] an intvec BO[6][j]=1 indicates that <BO[4][j],BO[2]>=1,
+               i.e. the strict transform does not meet the j-th exceptional
+               divisor
+@*         BO[7] intvec,
+               the index of the first blown-up object in the resolution process
+               leading to this object for which the value of b was BO[3]
+               the subsequent ones are the indices for the Coeff-Objects
+               of BO[2] used when determining the center
+@*         BM[7] intvec, BM[7][i] is the index at which the (2i-1)st entry
+               of the invariant first reached its current maximal value
+@*         BO[8]=BM[8] a matrix indicating that BO[4][i] meets BO[4][j] by
+               BO[8][i,j]=1 for i < j
+@*         BO[9] empty
+@*         BM[9] the invariant
+
+EXAMPLE: example blowUpBO;  shows an example
+"
+{
+//---------------------------------------------------------------------------
+// Initialization  and sanity checks
+//---------------------------------------------------------------------------
+   def R0=basering;
+   if(!defined(locaT)){int locaT;}
+   if(locaT){poly pp=@p;}
+   intvec v;
+   int shortC=defined(shortcut);
+   int invS=defined(invSat);
+   int eq,hy;
+   int extra,noDel,keepDiv;
+   if(e==1){extra=1;}
+//---keeps all charts
+   if(e==2){noDel=1;}
+//---this is only for curves and surfaces
+//---keeps all charts with relevant informations on the exceptional divisors
+   if(e==3){keepDiv=1;}
+   if( typeof(attrib(BO[2],"isEqui"))=="int" )
+   {
+      eq=attrib(BO[2],"isEqui");
+   }
+   if( typeof(attrib(BO[2],"isHy"))=="int" )
+   {
+      hy=attrib(BO[2],"isHy");
+   }
+   string newvar;
+   int n=nvars(R0);
+   int i,j,l,m,x,jj,ll,haveCenters,co;
+//---the center should neither be the whole space nor empty
+   if((size(C)==0)||(deg(C[1])==0))
+   {
+      list result=R0;
+      return(result);
+   }
+   if(!defined(debugBlowUp))
+   {
+     int debugBlowUp=0;
+   }
+//---------------------------------------------------------------------------
+// Drop unnecessary variables
+//---------------------------------------------------------------------------
+//---step 1: substitution
+   if(!((keepDiv)||(noDel)))
+   {
+//!!! in case keepDiv and noDel:
+//!!! maybe simplify the situation by an appropriate coordinate change
+//!!! of this kind -- without dropping variables?
+      list L=elimpart(BO[1]);
+      if(size(L[2])!=0)
+      {
+         map psi=R0,L[5];
+         C=psi(C);
+         BO=psi(BO);
+      }
+
+      if(size(BO[1])==0)
+      {
+         ideal LL;
+         for(j=1;j<=size(BO[4]);j++)
+         {
+            LL=LL,BO[4][j];
+         }
+         LL=findvars(LL);
+         L=elimpart(BO[2]);
+         if((size(L[2])!=0)&&(size(std(LL+L[2]))==size(L[2])+size(LL)))
+         {
+            map chi=R0,L[5];
+            C=chi(C);
+            BO=chi(BO);
+         }
+      }
+//---step 2: dropping non-occurring variables
+      int s=size(C);
+      ideal K=BO[1],BO[2],C;
+      for(j=1;j<=size(BO[4]);j++)
+      {
+        K=K,BO[4][j];
+      }
+      list N=findvars(K,0);
+      if(size(N[1])<n)
+      {
+         newvar=string(N[1]);
+         v=N[4];
+         for(j=1;j<=size(v);j++){BO[5]=subst(BO[5],var(v[j]),0);}
+         execute("ring R1=("+charstr(R0)+"),("+newvar+"),dp;");
+         list BO=imap(R0,BO);
+         ideal C=imap(R0,C);
+         n=nvars(R1);
+      }
+      else
+      {
+         def R1=basering;
+      }
+   }
+   else
+   {
+     int s=size(C);
+     def R1=basering;
+   }
+   if(debugBlowUp)
+   {
+     "---> In BlowUp: After dropping unnecessary variables";
+     "BO:";
+     BO;
+     "C:";
+     C;
+   }
+//---------------------------------------------------------------------------
+// Do the actual blow-up
+//---------------------------------------------------------------------------
+//--- control the names of the variables
+   execute("ring R=("+charstr(R0)+"),(x(1..n)),dp;");
+   list BO=fetch(R1,BO);
+   ideal C=fetch(R1,C);
+   list Cmstd=mstd(C);
+   C=Cmstd[2];
+   if(size(Cmstd[1])<=size(Cmstd[2]))
+   {
+      C=Cmstd[1];
+   }
+   else
+   {
+      C=interred(C);
+   }
+   list result;
+//--- the blow-up process
+   ideal W  =BO[1];
+   ideal J  =BO[2];
+   intvec bvec  =BO[3];
+   list Ex  =BO[4];
+   ideal abb=BO[5];
+   intvec wvec=BO[7];
+   ideal laM=maxideal(1);
+   if((typeof(BO[9])=="intmat")||(typeof(BO[9])=="intvec"))
+   {
+      def @invmat=BO[9];
+   }
+   if(size(BO)>9)
+   {
+//--- check whether a previous center had been split into connected components
+      if(size(BO[10])>0)
+      {
+         list knownCenters=BO[10];
+         haveCenters=1;
+       }
+   }
+
+   matrix intE=BO[8];
+   Ex[size(Ex)+1]=var(1);
+         //to have the list depending on R in case BO[4] is empty
+
+   execute("ring S=("+charstr(R)+"),("+varstr(R)+",y(0..s-1)),dp;");
+   list resu;
+   list B;
+   execute("ring T=("+charstr(R)+"),("+varstr(R)+",y(0..s-1),t),dp;");
+   ideal C=imap(R,C);
+   ideal W=imap(R,W);
+   execute("map phi=S,"+varstr(R)+",t*C;")
+   setring S;
+
+//--- the ideal describing the blow-up map
+   ideal abb=imap(R,abb);
+   ideal laM0=imap(R,laM);
+//--- the ideal of the blowing up of the ambient space
+   ideal W=preimage(T,phi,W);
+//--- the ideal of the exceptional locus
+   ideal E=imap(R,C);
+
+   list E1=imap(R,Ex);
+   E1[size(E1)]=E;
+   ideal J=imap(R,J)+W;
+
+   if(haveCenters){list kN=imap(R,knownCenters);}
+
+//---  the strict transform of the exceptional divisors
+   for(j=1;j<size(E1);j++){E1[j]=sat(E1[j]+W,E)[1];}
+//---  the intersection matrix of the exceptional divisors
+   matrix intEold=imap(R,intE);
+   matrix intE[size(E1)][size(E1)];
+   ideal U,Jsub,sLstd;
+
+   for(j=1;j<size(E1);j++)
+   {
+       for(l=j+1;l<=size(E1);l++)
+       {
+          if(deg(E1[j][1])==0)
+          {
+             if(l<size(E1)){intE[j,l]=intEold[j,l];}
+             else             {intE[j,l]=0;}
+          }
+          else
+          {
+             if(deg(E1[l][1])==0)
+             {
+                if(l<size(E1)){intE[j,l]=intEold[j,l];}
+             }
+             else
+             {
+                U= std(E1[l]+E1[j]);
+                if(dim(U)>0){intE[j,l]=1;}
+                else        {intE[j,l]=0;}
+             }
+          }
+       }
+   }
+   if(debugBlowUp)
+   {
+     "----> In BlowUp: After Blowing-up, before Clean-Up";
+     "W:";
+     W;
+     "J:";
+     J;
+   }
+//----------------------------------------------------------------------------
+// generating and cleaning up the different charts
+//----------------------------------------------------------------------------
+   list M;
+   map psi;
+   list E2;
+   ideal K,JJ,laM,LL,MM;
+   n=nvars(S);
+   list N;
+   list Bstd;
+   intvec delCharts,extraCharts;
+   delCharts[s]=0;
+   extraCharts[s]=0;
+   ideal MA=y(0..s-1);
+   list ZRes,ZlaM,ZsLstd;
+   for(i=0;i<=s-1;i++)
+   {
+     if(haveCenters)
+     {
+        B[10]=kN;
+        for(j=1;j<=size(kN);j++)
+        {
+           B[10][j][1]=subst(B[10][j][1],y(i),1);
+        }
+     }
+     B[8]=intE;
+     B[1]=std(subst(W,y(i),1));
+     if(deg(B[1][1])==0)
+     {
+//--- subsets of the empty set are not really interesting!
+       delCharts[i+1]=1;
+       ZRes[i+1]=B;
+       ZlaM[i+1]=laM;
+       i++;
+       continue;
+     }
+     Jsub=subst(J,y(i),1);
+     attrib(Jsub,"isEqui",eq);
+     attrib(Jsub,"isHy",hy);
+     B[2]=Jsub;
+     B[3]=bvec;
+     for(j=1;j<size(E1);j++){E2[j]=subst(E1[j],y(i),1);}
+     E2[size(E1)]=E+B[1];
+     B[4]=E2;
+     M=elimpart(B[1]);
+     B[5]=abb;
+     laM=laM0;
+     psi=S,maxideal(1);
+     if(size(M[2])!=0)
+     {
+        psi=S,M[5];
+        B=psi(B);
+        laM=psi(laM);
+     }
+     Jsub=B[2];
+     B[2]=sat(Jsub,std(psi(E)))[1];
+     if(!defined(MAtmp)){ideal MAtmp=MA;}
+     MAtmp[i+1]=0;
+     JJ=std(B[2]+MAtmp);
+     if(deg(JJ[1])==0)
+     {
+        delCharts[i+1]=1;
+//--- the i-th chart will be marked for deleting because all informations
+//--- are already contained in the union of the remaining charts
+     }
+     else
+     {
+        if((eq)&&(dim(JJ)<dim(std(B[2]))))
+        {
+           extraCharts[i+1]=1;
+//---  compute the singular locus
+           if((B[3][1]<=1)&&(hy))
+//--- B[2] is a smooth hypersurface
+           {
+              sLstd=ideal(1);
+           }
+           else
+           {
+              Bstd=mstd(B[2]);
+              if(n-dim(Bstd[1])>4)
+              {
+//--- in this case the singular locus is too complicated
+                 sLstd=ideal(0);
+              }
+              JJ=Bstd[2];
+              attrib(JJ,"isEqui",eq);
+              B[2]=JJ;
+              sLstd=slocusE(B[2]);
+           }
+           m=0;
+           if(deg(std(sLstd+MAtmp)[1])==0)
+           {
+//--- the singular locus of B[2] is in the union of the remaining charts
+              m=1;
+              for(l=1;l<=size(B[4]);l++)
+              {
+                 if(deg(std(B[2]+B[4][l]+MAtmp)[1])!=0)
+                 {
+//--- the exceptional divisor meets B[2] at the locus of MAtmp
+//--- we continue only if the option extra=1 and we have transversal
+//--- intersection
+                    m=0;
+                    break;
+                  }
+              }
+           }
+           if(m)
+           {
+//--- the i-th chart will be marked for deleting because all informations
+//--- are already contained in the union of the remaining charts
+              delCharts[i+1]=1;
+           }
+        }
+     }
+     if(delCharts[i+1]==0)
+     {
+        MAtmp[i+1]=MA[i+1];
+        ZsLstd[i+1]=sLstd;
+     }
+     ZRes[i+1]=B;
+     ZlaM[i+1]=laM;
+   }
+//---------------------------------------------------------------------------
+// extra = ignore uninteresting charts even if there is a normal
+//         crosssing intersection in it
+//---------------------------------------------------------------------------
+   if(extra)
+   {
+      for(i=0;i<=s-1;i++)
+      {
+         if((delCharts[i+1]==0)&&(extraCharts[i+1]))
+         {
+           MAtmp[i+1]=0;
+           B=ZRes[i+1];
+           sLstd=ZsLstd[i+1];
+           m=0;
+           if(deg(std(sLstd+MAtmp)[1])==0)
+           {
+//--- the singular locus of B[2] is in the union of the remaining charts
+              m=1;
+              for(l=1;l<=size(B[4]);l++)
+              {
+                 if(deg(std(B[2]+B[4][l]+MAtmp)[1])!=0)
+                 {
+//--- the exceptional divisor meets B[2] at the locus of MAtmp
+//--- we continue only if the option extra=1 and we have transversal
+//--- intersection
+                    m=2;
+                    if(!transversalTB(B[2],list(B[4][l]),MAtmp))
+                    {
+                       m=0;break;
+                    }
+                  }
+              }
+           }
+           if(m)
+           {
+              if(m==1)
+              {
+//--- the i-th chart will be marked for deleting because all informations
+//--- are already contained in the union of the remaining charts
+                 delCharts[i+1]=1;
+              }
+              else
+              {
+//--- the option extra=1 and we have transversal intersection
+//--- we delete the chart in case of normal crossings
+                 if(normalCrossB(B[2],B[4],MAtmp))
+                 {
+//--- in case of the option extra
+//--- the i-th chart will be marked for deleting because all informations
+//--- are already contained in the union of the remaining charts
+
+                   delCharts[i+1]=1;
+                 }
+              }
+           }
+           if(delCharts[i+1]==0)
+           {
+              MAtmp[i+1]=MA[i+1];
+           }
+         }
+      }
+      for(i=0;i<=s-1;i++)
+      {
+         if(!delCharts[i+1]){break;}
+      }
+      if(i==s){delCharts[s]=0;}
+   }
+   for(i=0;i<=s-1;i++)
+   {
+     B=ZRes[i+1];
+     laM=ZlaM[i+1];
+     if(noDel){delCharts[i+1]=0;}
+//---keeps chart if the exceptional divisor is not in any other chart
+     if((delCharts[i+1])&&(keepDiv))
+     {
+         for(j=1;j<=size(B[4]);j++)
+         {
+            if(deg(std(B[4][j])[1])>0)
+            {
+               x=0;
+               for(l=0;l<=s-1;l++)
+               {
+                  if((l!=i)&&(!delCharts[l+1])&&(deg(std(ZRes[l+1][4][j])[1])>0))
+                  {
+                     x=1;
+                     break;
+                  }
+               }
+               if(!x)
+               {
+                  delCharts[i+1]=0;
+//!!!evtl. diese Karten markieren und nicht weiter aufblasen???
+                  break;
+               }
+            }
+         }
+     }
+//---keeps charts if the intersection of 2 divisors is not in any other chart
+     if((delCharts[i+1])&&(keepDiv))
+     {
+         for(j=1;j<=size(B[4])-1;j++)
+         {
+            for(l=j+1;l<=size(B[4]);l++)
+            {
+               if(deg(std(B[4][j]+B[4][l])[1])>0)
+               {
+                  x=0;
+                  for(ll=0;ll<=s-1;ll++)
+                  {
+                     if((ll!=i)&&(!delCharts[ll+1]))
+                     {
+                        if(deg(std(ZRes[ll+1][4][j]+ZRes[ll+1][4][l])[1])>0)
+                        {
+                           x=1;
+                           break;
+                        }
+                     }
+                  }
+                  if(!x)
+                  {
+                     delCharts[i+1]=0;
+                     break;
+                  }
+               }
+            }
+            if(!delCharts[i+1]){break;}
+         }
+     }
+//---keeps charts if the intersection of 3 divisors is not in any other chart
+     if((delCharts[i+1])&&(keepDiv))
+     {
+         for(j=1;j<=size(B[4])-2;j++)
+         {
+            for(l=j+1;l<=size(B[4])-1;l++)
+            {
+               for(ll=l+1;ll<=size(B[4]);ll++)
+               {
+                  if(deg(std(B[4][j]+B[4][l]+B[4][ll])[1])>0)
+                  {
+                     x=0;
+                     for(jj=0;jj<=s-1;jj++)
+                     {
+                        if((jj!=i)&&(!delCharts[jj+1]))
+                        {
+                           if(deg(std(ZRes[jj+1][4][j]
+                              +ZRes[jj+1][4][l]+ZRes[jj+1][4][ll])[1])>0)
+                           {
+                              x=1;
+                              break;
+                           }
+                        }
+                     }
+                     if(!x)
+                     {
+                       delCharts[i+1]=0;
+                       break;
+                     }
+                  }
+               }
+               if(!delCharts[i+1]){break;}
+            }
+            if(!delCharts[i+1]){break;}
+        }
+     }
+     if(delCharts[i+1]==0)
+     {
+//--- try to decrease the number of variables by substitution
+        if((!keepDiv)&&(!noDel))
+        {
+           list WW=elimpart(B[1]);
+           map phiW=basering,WW[5];
+           B=phiW(B);
+           laM=phiW(laM);
+           kill WW;
+           kill phiW;
+           if(size(B[1])==0)
+           {
+              LL=0;
+              for(j=1;j<=size(B[4]);j++)
+              {
+                 MM=std(B[4][j]);
+                 if(deg(MM[1])>0){LL=LL,MM;}
+              }
+              LL=findvars(LL);
+              M=elimpart(B[2]);
+              if((size(M[2])!=0)&&(size(std(LL+M[2]))==size(M[2])+size(LL)))
+              {
+                psi=S,M[5];
+                B=psi(B);
+                laM=psi(laM);
+              }
+           }
+         }
+//---- interreduce B[1],B[2] and all B[4][j]
+        B[1]=interred(B[1]);
+        B[2]=interred(B[2]);
+        E2=B[4];
+        for(j=1;j<=size(E2);j++){E2[j]=interred(E2[j]);}
+        B[4]=E2;
+        v=0;v[size(E2)]=0;
+//--- mark those j for which B[4] does not meet B[2]
+        for(j=1;j<=size(E2);j++)
+        {
+            K=E2[j],B[2];
+            K=std(K);
+            if(deg(K[1])==0)
+            {
+              v[j]=1;
+            }
+        }
+        B[6]=v;
+        B[7]=wvec;
+//--- throw away variables which do not occur
+        K=B[1],B[2],B[5];          //Aenderung!!!
+        for(j=1;j<=size(B[4]);j++){K=K,B[4][j];}
+        N=findvars(K,0);
+        if(size(N[1])<n)
+        {
+           newvar=string(N[1]);
+           v=N[4];
+           for(j=1;j<=size(v);j++)
+           {
+              B[5]=subst(B[5],var(v[j]),0);
+              laM=subst(laM,var(v[j]),0);
+           }
+           execute("ring R2=("+charstr(S)+"),("+newvar+"),dp;");
+           list BO=imap(S,B);
+           ideal laM=imap(S,laM);
+        }
+        else
+        {
+           def R2=basering;
+           list BO=B;
+        }
+        ideal JJ=BO[2];
+        attrib(JJ,"isEqui",eq);
+        attrib(JJ,"isHy",hy);
+        BO[2]=JJ;
+//--- strict transforms of the known centers
+        if(haveCenters)
+        {
+           ideal tt;
+           list tList;
+           for(j=1;j<=size(BO[10]);j++)
+           {
+              tt=std(BO[10][j][1]);
+              if(deg(tt[1])>0)
+              {
+                tt=sat(tt,BO[4][size(BO[4])])[1];
+              }
+              if((deg(tt[1])>0)&&(deg(std(tt+BO[2]+BO[1])[1])>0))
+              {
+                 tList[size(tList)+1]=
+                            list(tt,BO[10][j][2],BO[10][j][3],BO[10][j][4]);
+              }
+           }
+           BO[10]=tList;
+           kill tList;
+        }
+//--- marking  variables which do not occur in BO[1] and BO[2]
+//--- and occur in exactly one BO[4][j], which is the hyperplane given by
+//--- this variable
+//!!!! not necessarily in exactly one BO[4][j]
+        list N=findvars(BO[1]+BO[2],0);
+        if(size(N[1])<nvars(basering))
+        {
+           v=N[4];
+           if(defined(H)){kill H;}
+           if(defined(EE)){kill EE;}
+           if(defined(vv)){kill vv;}
+           list EE;
+           intvec vv;
+           ideal H=maxideal(1);
+           for(j=1;j<=size(v);j++)
+           {
+             H[v[j]]=0;
+           }
+           H=std(H);
+           for(l=1;l<=size(BO[4]);l++)
+           {
+              if(BO[6][l]==1){l++;continue;}
+              if(size(ideal(matrix(reduce(BO[4][l],H))-BO[4][l]))==0)
+              {
+//!!! need further cleanup:
+//!!! this part of the code is no longer used since it did not glue properly
+//                 BO[6][l]=2;
+                 EE[size(EE)+1]=BO[4][l];
+                 vv[size(vv)+1]=l;
+              }
+           }
+           if((size(vv)>dim(std(BO[2])))&&(deg(BO[2][1])>0))
+           {
+              list BOtemp3=BO;
+              BOtemp3[4]=EE;
+              intvec ivtemp3;
+              ivtemp3[size(BOtemp3[4])]=0;
+              BOtemp3[6]=ivtemp3;
+              BOtemp3[7][1]=-1;
+              list iEtemp3=inters_E(BOtemp3);
+              if(iEtemp3[2]>=dim(std(BOtemp3[2])))
+              {
+                 for(l=2;l<=size(vv);l++)
+                 {
+                    BO[6][vv[l]]=0;
+                 }
+              }
+              kill BOtemp3,ivtemp3,iEtemp3;
+           }
+        }
+        list thisChart=ideal(0),i;
+        export thisChart;
+
+//----------------------------------------------------------------------------
+// export the basic object and append the ring to the list of rings
+//----------------------------------------------------------------------------
+        if(debugBlowUp)
+        {
+           "----> In BlowUp: Adding a single chart";
+           "BO:";
+           BO;
+        }
+        if(locaT)
+        {
+           map locaPhi=R0,laM;
+           poly @p=locaPhi(pp);
+           export(@p);
+        }
+        ideal lastMap=laM;
+        export lastMap;
+        if(invS){list invSat=imap(R0,invSat);export invSat;}
+        if(defined(@invmat)){BO[9]=@invmat;}
+        if(shortC){list shortcut=imap(R0,shortcut);export(shortcut);}
+        export BO;
+        result[size(result)+1]=R2;
+        setring S;
+        kill R2;
+     }
+   }
+   setring R0;
+   return(result);
+}
+example
+{"EXAMPLE:";
+   echo = 2;
+   ring R=0,(x,y),dp;
+
+   ideal W;
+   ideal J=x2-y3;
+   intvec b=1;
+   list E;
+   ideal abb=maxideal(1);
+   intvec v;
+   intvec w=-1;
+   matrix M;
+   intvec ma;
+   list BO=W,J,b,E,abb,v,w,M,ma;
+
+   ideal C=CenterBO(BO)[1];
+
+   list blow=blowUpBO(BO,C,0);
+   def Q=blow[1];
+   setring Q;
+   BO;
+}
+//////////////////////////////////////////////////////////////////////////////
+static proc slocusE(ideal i)
+"Internal procedure - no help and no example available
+"
+{
+//--- do slocus in equidimensional case directly -- speed up
+  if(size(i)==0){return(ideal(1));}
+  if( typeof(attrib(i,"isEqui"))=="int" )
+  {
+     if(attrib(i,"isEqui")==1)
+     {
+        ideal j=std(i);
+        if(deg(j[1])==0){return(j);}
+        int cod  = nvars(basering)-dim(j);
+        i        = i+minor(jacob(i),cod);
+        return(i);
+     }
+  }
+  return(slocus(i));
+}
+///////////////////////////////////////////////////////////////////////////////
+static proc inters_E(list BO)
+"USAGE:  inters_E(BO);
+@*       BO = basic object, a list: ideal W,
+@*                                  ideal J,
+@*                                  intvec b,
+@*                                  list Ex,
+@*                                  ideal ab,
+@*                                  intvec v,
+@*                                  intvec w,
+@*                                  matrix M
+ASSUME:  R  = basering, a polynomial ring, W an ideal of R,
+@*       J  = ideal containing W,
+@*       BO in the setting of case 2 of [Bravo,Encinas,Villamayor]
+@*             BO[4]=E, BO[4][1..count]=E^-
+@*             BO[7][1]=count
+COMPUTE: (W,(P,1),E^+) in the notation of [Bravo,Encinas,Villamayor]
+RETURN:  a list l ,
+         l[1]: P = product of ideals I(H_i1)+..+I(H_in) over all
+                   n-tuples of indices i1..in from 1..count
+         l[2]: n = maximal number of H_i from E^- meeting J simultaneously
+         l[3]: maximal number of H_i from E meeting J simultaneously
+EXAMPLE: internal procedure - no example available
+"
+{
+//---------------------------------------------------------------------
+// Initialization
+//---------------------------------------------------------------------
+  int kk,jj,ii,updated,n,count2,kkdiff;
+  def rb=basering;
+  def W=BO[1];
+  ideal J=BO[1],BO[2];
+  int nonnormal;
+  int maxkk=dim(std(J));
+  int dimJ=maxkk;
+  ideal test2;
+  list merklist1,merklist2;
+  if(size(BO[4])==0)
+  {
+    list retlist=BO[2],n;
+    return(retlist);
+  }
+  def E=BO[4];
+  intvec stoplist=BO[6];
+//--- fill in all known information about exceptional divisors not meeting
+//--- current chart
+  for(ii=1;ii<=size(E);ii++)
+  {
+    if(deg(std(E[ii])[1])==0)
+    {
+      stoplist[ii]=1;
+    }
+  }
+
+  int count=BO[7][1];
+  if(!defined(debug_Inters_E))
+  {
+    int debug_Inters_E=0;
+  }
+//---------------------------------------------------------------------
+// we only want to look at E^-, not at all of E
+//---------------------------------------------------------------------
+  if (count>-1)
+  {
+    if (count>0)
+    {
+      list E_new=E[1..count];
+      count2=size(E);
+    }
+    else
+    {
+      list E_new;
+      count2=size(E);
+    }
+  }
+  else
+  {
+    list E_new=E;
+    count=size(E_new);
+    count2=count;
+  }
+//---------------------------------------------------------------------
+// combinatorics is expensive in an interpreted language,
+// we leave it to the kernel by translating it into monomial
+// ideals in a new ring with variables t(i)
+//---------------------------------------------------------------------
+  string rstr="ring rcomb=0,(t(1.." + string(size(E)) + ")),dp;";
+  execute(rstr);
+  ideal potid,potid2;
+  list monlist,comblist,merkmon;
+  for(kk=1;kk<=count;kk++)
+  {
+    if(stoplist[kk]==0)
+    {
+//**************************************************************************/
+// it does not make sense to intersect twice by the same E_i
+// ===> reduce by t(i)^2
+//**************************************************************************/
+      potid=potid,t(kk)^2;
+    }
+    else
+    {
+//**************************************************************************/
+// it does not make sense to consider E_i with v[i]==1 ===> reduce by t(i)
+//**************************************************************************/
+      potid=potid,t(kk);
+//**************************************************************************/
+// if stoplist[kk]==2 then J and all E_i automatically intersect E_kk
+// hence we need not test it, but we have to lower maxkk by one
+//**************************************************************************/
+      if(stoplist[kk]==2)
+      {
+        maxkk=maxkk-1;
+        kkdiff++;             // count these for dimension check later on
+
+      }
+    }
+  }
+
+  potid2=std(potid);
+  if(count2>count)
+  {
+    potid=potid,t((count+1)..count2);
+    for(kk=max(1,count);kk<=count2;kk++)
+    {
+      potid2=potid2,t(kk)^2;
+    }
+  }
+  potid=std(potid);
+  potid2=std(potid2);
+  for(kk=1;(((kk<=count)||(kk<=maxkk+1))&&(kk<=count2));kk++)
+  {
+//-------------------------------------------------------------------------
+// monlist[kk]=lists of kk entries of E_new, not containing an E_i twice,
+// not containing an E_i where v[i]==1
+//-------------------------------------------------------------------------
+    monlist[kk]=redMax(kk,potid);
+//*************************************************************************/
+// in the case of n<=maxkk we also need to know whether n would still be
+// below this bound if we considered all of E instead of E_new
+// ===> merkmon contains previously ignored tuples E_i1,..,E_im
+//*************************************************************************/
+    if(kk<=maxkk+1)
+    {
+      merkmon[kk]=redMax(kk,potid2);
+      merkmon[kk]=simplify(reduce(merkmon[kk],std(monlist[kk])),2);
+    }
+  }
+  if(debug_Inters_E)
+  {
+    "----> In Inters_E: the tuples";
+    "tuples of E^-:";
+    monlist;
+    "the remaining tuples:";
+    merkmon;
+  }
+//-------------------------------------------------------------------------
+// check whether there is a kk-tuple of E_i intersecting J,
+// kk running from 1 to count
+//-------------------------------------------------------------------------
+  for(kk=1;kk<=count;kk++)
+  {
+    if(size(monlist[kk]==0)) break;
+    kill comblist;
+    list comblist;
+//--- transscribe the tuples from monomial notation to intvec notation
+    for(jj=1;jj<=ncols(monlist[kk]);jj++)
+    {
+      comblist[jj]=leadexp(monlist[kk][jj]);
+    }
+    setring rb;
+    updated=0;
+//------------------------------------------------------------------------
+// Do the intersections
+//------------------------------------------------------------------------
+    for(jj=1;jj<=size(comblist);jj++)
+    {
+//--- jj-th tuple from list of tuples of kk E_i
+      test2=J;
+      for(ii=1;ii<=count;ii++)
+      {
+        if(comblist[jj][ii]==1)
+        {
+          test2=test2,E_new[ii];
+        }
+      }
+      test2=std(test2);
+//--- check whether this intersection is non-empty and store it accordingly
+      if(deg(test2[1])!=0)
+      {
+//--- it is non-empty
+        if(updated!=0)
+        {
+          merklist1[size(merklist1)+1]=comblist[jj];
+        }
+        else
+        {
+          kill merklist1;
+          list merklist1;
+          merklist1[1]=comblist[jj];
+          updated=1;
+          n=kk;
+        }
+        if(dim(test2)!=maxkk-kk+kkdiff)
+        {
+          nonnormal=1;
+        }
+      }
+      else
+      {
+//--- it is empty
+        merklist2[size(merklist2)+1]=jj;
+      }
+    }
+    setring rcomb;
+    ideal redid;
+//---------------------------------------------------------------------
+// update monlist and merkmon by the knowledge what intersections are
+// empty in the kk-th step
+//---------------------------------------------------------------------
+    for(jj=1;jj<=size(merklist2);jj++)
+    {
+      redid=redid,monlist[kk][merklist2[jj]];
+    }
+    for(jj=kk+1;jj<=count;jj++)
+    {
+      monlist[jj]=simplify(reduce(monlist[jj],std(redid)),2);
+      if(jj<=maxkk+1)
+      {
+        merkmon[jj]=simplify(reduce(merkmon[jj],std(redid)),2);
+      }
+    }
+    kill redid;
+    kill merklist2;
+    list merklist2;
+  }
+  if(debug_Inters_E)
+  {
+    "----> In Inters_E: intersections found:";
+    merklist1;
+  }
+//---------------------------------------------------------------------
+// form the union of the intersections of the appropriate E_i
+//---------------------------------------------------------------------
+  setring rb;
+  ideal center,dummy;
+  list centlist;
+  for(kk=1;kk<=size(merklist1);kk++)
+  {
+    for(jj=1;jj<=size(merklist1[kk]);jj++)
+    {
+      if(merklist1[kk][jj]==1)
+      {
+        dummy=dummy,E_new[jj];
+      }
+    }
+    if(size(center)==0)
+    {
+      center=dummy;
+      centlist[1]=dummy;
+    }
+    else
+    {
+      center=intersect(center,dummy);
+      centlist[size(centlist)+1]=dummy;
+    }
+    dummy=0;
+  }
+  if(debug_Inters_E)
+  {
+    "----> In Inters_E: intersection of E_i";
+    "maximal number of E_i encountered in:";
+    center;
+    "the components of this locus:";
+    centlist;
+    "maximal number of E_i from E^- intersecting simultaneously:",n;
+    if(nonnormal)
+    {
+      "flag nonnormal is set";
+    }
+  }
+  list retlist=center,n;
+//-------------------------------------------------------------------------
+// If n<=maxkk, then test if this is the case for all of E not just E_new
+// using the pairs indicated by merkmon
+//-------------------------------------------------------------------------
+  int ntotal=n;
+  if((n<=maxkk)&&(n<count2)&&(!nonnormal))
+  {
+//--- check kk-tuples
+    for(kk=n+1;kk<=maxkk+1;kk++)
+    {
+      setring rcomb;
+//--- check if there are combinations to be checked
+      if(kk>size(merkmon))
+      {
+        setring rb;
+        break;
+      }
+      if(size(merkmon[kk])!=0)
+      {
+        kill comblist;
+        list comblist;
+//--- transscribe tuples from  monomial notation to intvec notation
+        for(jj=1;jj<=size(merkmon[kk]);jj++)
+        {
+          comblist[jj]=leadexp(merkmon[kk][jj]);
+        }
+        setring rb;
+//--- check jj-th tuple from the list of kk-tuples
+        for(jj=1;jj<=size(comblist);jj++)
+        {
+          test2=J;
+          for(ii=1;ii<=nvars(rcomb);ii++)
+          {
+            if(comblist[jj][ii]==1)
+            {
+              test2=test2,E[ii];
+            }
+          }
+          test2=std(test2);
+//--- as soon as we found one we can proceed to the subsequent kk
+          if(deg(test2[1])!=0)
+          {
+            ntotal=kk;
+            if(dim(test2)-kkdiff!=maxkk-kk)
+            {
+              nonnormal=2;
+              break;
+            }
+          }
+        }
+//--- if we already know that too many E_i intersect simultaneously,
+//--- we need not proceed any further
+        if(nonnormal)
+        {
+          break;
+        }
+      }
+      else
+      {
+        setring rb;
+        break;
+      }
+    }
+  }
+//-------------------------------------------------------------------------
+// update the result accordingly and return it
+//-------------------------------------------------------------------------
+  if(maxkk<dimJ)
+  {
+    n=n+dimJ-maxkk;
+    ntotal=ntotal+dimJ-maxkk;
+  }
+  retlist[2]=n;
+  retlist[3]=ntotal;
+  if(n<=dimJ)
+  {
+    retlist[4]=centlist;
+    retlist[5]=merklist1;
+    if(nonnormal)
+    {
+      retlist[6]=nonnormal;
+    }
+  }
+  return(retlist);
+}
+///////////////////////////////////////////////////////////////////////////
+
+proc Delta(list BO)
+"USAGE:  Delta (BO);
+@*       BO = basic object, a list: ideal W,
+@*                                  ideal J,
+@*                                  intvec b,
+@*                                  list Ex,
+@*                                  ideal ab,
+@*                                  intvec v,
+@*                                  intvec w,
+@*                                  matrix M
+ASSUME:  R  = basering, a polynomial ring, W an ideal of R,
+@*       J  = ideal containing W
+COMPUTE: Delta-operator applied to J in the notation of
+         [Bravo,Encinas,Villamayor]
+RETURN:  ideal
+EXAMPLE: example Delta;  shows an example
+"
+{
+//---------------------------------------------------------------------------
+// Initialization  and sanity checks
+//---------------------------------------------------------------------------
+   ideal W=BO[1];
+   ideal J=BO[2];
+   ideal C=simplify(reduce(J,std(W)),2);
+   list LC;
+   int n=nvars(basering);
+//---------------------------------------------------------------------------
+// Simple case: W is the empty set
+//---------------------------------------------------------------------------
+   if(size(W)==0)
+   {
+      C=C,jacob(J);
+      C=std(C);
+      return(C);
+   }
+//---------------------------------------------------------------------------
+// General case: W is non-empty
+// Step 1: Find a minor of the Jacobian of W which is not identically zero
+//         and look at the complement of the zero-set given by this minor;
+//         this leads to the system of local parameters
+// Step 2: Form the derivatives w.r.t. this system of parameters
+//---------------------------------------------------------------------------
+//--- Step 1
+   list re=findMinor(W);
+   list L;
+   int ii,i,j,l,k;
+   J=C;
+   ideal D=ideal(1);
+   intvec v,w;
+   ideal V;
+   poly m;
+
+   for(ii=1;ii<=size(re);ii++)
+   {
+      C=J;
+      L=re[ii];
+      matrix A=L[1];  //(1/m)*A is the inverse matrix of the Jacobian of W
+                      //corresponding to m
+      m=L[2];  //a k- minor of jacob(W), not identically zero
+                      //k=n-dim(W)
+      V=L[3];  //the elements of W corresponding to m
+      v=L[4];  //the indices of variables corresponding to m
+      w=L[5];  //the indices of variables not corresponding to m
+
+//--- Step 2
+//--- first some initialization depending on results of step 1
+      k=size(V);
+      matrix dg[1][k];
+      matrix df[k][1];
+//--- derivatives of the generators of J w.r.t. system of parameters
+      for(i=1;i<=size(J);i++)
+      {
+         for(j=1;j<=n-k;j++)
+         {
+            for(l=1;l<=k;l++)
+            {
+               dg[1,l]=diff(V[l],var(w[j]));
+               df[l,1]=diff(J[i],var(v[l]));
+             }
+             C=C,m*diff(J[i],var(w[j]))-dg*A*df;
+         }
+      }
+//--- everything should live in W, not just in the intersection of
+//--- D(m) with W
+      C=C+W;
+      C=sat(C,m)[1];
+//--- intersect ideal with previously computed ones to make sure that no
+//--- components are lost
+      D=intersect(D,C);
+      kill dg,df,A;
+   }
+//--- return minimal set of generators of the result
+   list li=mstd(D);
+   D=li[2];
+   if(size(li[1])<=size(D)){D=li[1];}
+   return(D);
+}
+example
+{ "EXAMPLE:";
+   echo = 2;
+   ring R=0,(x,y,z),dp;
+
+   ideal W=z^2-x;
+   ideal J=x*y^2+x^3;
+   intvec b=1;
+   list E;
+   ideal abb=maxideal(1);
+   intvec v;
+   intvec w=-1;
+   matrix M;
+
+   list BO=W,J,b,E,abb,v,w,M;
+
+   Delta(BO);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+static proc redMax(int k,ideal J)
+"Internal procedure - no help and no example available
+"
+{
+//--- reduce maxideal(k) by J, more efficient approach
+    int i;
+    ideal K=simplify(reduce(maxideal(1),J),2);
+    for(i=2;i<=k;i++)
+    {
+       K=simplify(reduce(K*maxideal(1),J),2);
+    }
+    return(K);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+static proc findMinor(ideal W)
+"Internal procedure - no help and no example available
+"
+{
+//---------------------------------------------------------------------------
+// Initialization and sanity checks
+//---------------------------------------------------------------------------
+   list L;
+   intvec v,w;
+   ideal Wstd=std(W);
+   int n=nvars(basering);   // total number of columns of Jacobian
+   int k=n-dim(Wstd);       // size of minors of Jacobian
+   int a=size(W);           // total number of rows of Jacobian
+   matrix A[k][k];
+   list LW=indexSet(a,k);   // set of tuples of k rows
+   list LV=indexSet(n,k);   // set of tuples of k columns
+   ideal IW,IV;
+   int i,j,l,e;
+   list re;
+//---------------------------------------------------------------------------
+// We need to know which minor corresponds to which variable and to which
+// generator of W - therefore we cannot use the function minor()!
+//---------------------------------------------------------------------------
+//--- choose the generators which we want to differentiate
+   for(i=1;i<=size(LW);i++)
+   {
+      IW=0;
+      for(l=1;l<=a;l++)
+      {
+         if(LW[i][l]!=0){IW[size(IW)+1]=W[l];}
+      }
+//--- choose the variables by which to differentiate and apply diff
+      for(j=1;j<=size(LV);j++)
+      {
+          IV=0;v=0;w=0;
+          for(l=1;l<=n;l++)
+          {
+             if(LV[j][l]!=0)
+             {
+                v[size(v)+1]=l;
+                IV[size(IV)+1]=var(l);
+             }
+             else
+             {
+                w[size(w)+1]=l;
+
+             }
+          }
+          A=diff(IV,IW);      // appropriate submatrix of Jacobian
+//--- if the minor is non-zero, then it might be the one we need
+//--- ==> put it in the list of candidates
+          if(det(A)!=0)
+          {
+            v=v[2..size(v)];  // first entry is zero for technical reasons
+            w=w[2..size(w)];  // first entry is zero for technical reasons
+            L=inverse_L(A);
+            L[3]=IW;
+            L[4]=v;
+            L[5]=w;
+            re[size(re)+1]=L;
+          }
+      }
+   }
+//---------------------------------------------------------------------------
+// return the result
+//---------------------------------------------------------------------------
+   return(re);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+static proc indexSet(int a, int b)
+"Internal procedure - no help and no example available
+"
+{
+//---------------------------------------------------------------------------
+// Find all tuples of size b containing pairwise distict elements from a
+// list of a elements
+//---------------------------------------------------------------------------
+//**************************************************************************/
+// Combinatorics is expensive in an interpreted language
+// ==> shift it into the kernel
+//**************************************************************************/
+   def R=basering;
+   list L;
+   ring S=2,x(1..a),dp;
+   ideal I=maxideal(b);
+   int i;
+   ideal J=x(1)^2;
+   for(i=2;i<=a;i++){J=J,x(i)^2;}
+   attrib(J,"isSB",1);
+   I=reduce(I,J);
+   I=simplify(I,2);
+   for(i=1;i<=size(I);i++){L[i]=leadexp(I[i]);}
+   setring R;
+   return(L);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+proc DeltaList(list BO)
+"USAGE:  DeltaList (BO);
+@*       BO = basic object, a list: ideal W,
+@*                                  ideal J,
+@*                                  intvec b,
+@*                                  list Ex,
+@*                                  ideal ab,
+@*                                  intvec v,
+@*                                  intvec w,
+@*                                  matrix M
+ASSUME:  R  = basering, a polynomial ring, W an ideal of R,
+@*       J  = ideal containing W
+COMPUTE: Delta-operator iteratively applied to J in the notation of
+         [Bravo,Encinas,Villamayor]
+RETURN:  list l of length ((max w-ord) * b),
+         l[i+1]=Delta^i(J)
+EXAMPLE: example DeltaList;  shows an example
+"
+{
+//----------------------------------------------------------------------------
+// Iteratively apply proc Delta
+//----------------------------------------------------------------------------
+   int i;
+   list L;
+   ideal C=BO[2];
+   while(deg(C[1])!=0)
+   {
+      L[size(L)+1]=C;
+      C=Delta(BO);
+      BO[2]=C;
+   }
+   return(L);
+}
+example
+{
+   "EXAMPLE:";
+   echo = 2;
+   ring R=0,(x,y,z),dp;
+
+   ideal W=z^2-x;
+   ideal J=x*y^2+x^3;
+   intvec b=1;
+   list E;
+   ideal abb=maxideal(1);
+   intvec v;
+   intvec w=-1;
+   matrix M;
+
+   list BO=W,J,b,E,abb,v,w,M;
+
+   DeltaList(BO);
+}
+/////////////////////////////////////////////////////////////////////////////
+proc CenterBM(list BM)
+"USAGE:  CenterBM(BM);
+@*       BM = object related to a presentation,
+                            a list: ideal W,
+@*                                  ideal J,
+@*                                  intvec b,
+@*                                  list Ex,
+@*                                  ideal ab,
+@*                                  intvec v,
+@*                                  intvec w,
+@*                                  matrix M
+ASSUME:  R  = basering, a polynomial ring, W an ideal of R,
+@*       J  = ideal containing W
+COMPUTE: the center of the next blow-up of BM in the resolution algorithm
+         of [Bierstone, Milman]
+RETURN:  list l,
+         l[1]: ideal describing the center
+         l[2]: intvec w obtained in the process of determining l[1]
+         l[3]: intvec b obtained in the process of determining l[1]
+         l[4]: intmat invmat obtained in the process of determining l[1]
+EXAMPLE: example CenterBM;  shows an example
+"
+{
+//!!! NOCH NICHT IN BETRIEB
+ERROR("Not implemented yet");
+   int i,j;
+   intmat tmat[2][1]=0,-1;
+//--- re=center,E^- indices, b vector, n vector
+   list re=ideal(1),BM[7],BM[3],tmat;
+   ideal J=BM[2];
+   if(size(J)==0)
+   {
+     re[1]=ideal(0);
+     return(re);
+   }
+//--- find Delta^(b-1)(J)
+   if(size(reduce(J,std(BM[1])))!=0)
+   {
+     list L=DeltaList(BM);
+   }
+   else
+   {
+     list L;
+     L[1]=J;
+   }
+   if(!defined(debugCenter))
+   {
+     int debugCenter;
+   }
+   if(debugCenter)
+   {
+     "----> In Center: after DeltaList";
+     "W";
+     BM[1];
+     "J";
+     BM[2];
+     "The Delta List:";
+     L;
+   }
+   int b=size(L);
+   if(b==0)
+   {
+//--- if J=W, we do not need to do anything
+//--- returning center=1 marks this chart as completed
+     return(re);
+   }
+//---------------------------------------------------------------------------
+// check whether max ord is constant
+//---------------------------------------------------------------------------
+   if((BM[9][2,1]<0)||(BM[9][1,1]>b))
+   {
+//--- we are either at the beginning or the invariant has dropped
+     intvec tempvec=size(BM[4]);
+     BM[7]=tempvec;
+//!!!! nur fuer hyperflaechen!!!!!!!!
+     tempvec=b;
+     BM[3]=tempvec;
+//!!!! Ende !!!!!!!!!!!!
+     kill tempvec;
+     BM[9][1,1]=b;
+     BM[9][2,1]=1;
+   }
+//---------------------------------------------------------------------------
+// prepare for intersection with E_i
+//---------------------------------------------------------------------------
+   ideal C=L[b];
+   re[2]=BM[7];
+   re[3]=BM[3];
+   BM[2]=C;
+      if(debugCenter)
+   {
+     "----> In Center: before intersection with E_i:";
+     "bmax:",b;
+     "Sing(J,bmax):";
+      C;
+     "E:";
+      BO[4];
+     "list marking a priori known intersection properties:",BO[6];
+     "index of last element of E^- in E:",BO[7][1];
+   }
+   list E=inters_E(BM);
+// !!!!!!!!! Drop Redundant fehlt noch!!!!!!!!
+//---------------------------------------------------------------------------
+// Check whether it is a single point
+//---------------------------------------------------------------------------
+   ideal C1=std(ideal(L[b])+E[1]);
+   if(dim(C1)==0)
+   {
+     if(size(E[4])==1)
+     {
+        tmat[1,1]=BM[9][1,1];
+        tmat[2,1]=BM[9][2,1];
+        re[4]=tmat;
+        re[1]=radical(C1);
+        return(re);
+     }
+   }
+   if(size(BM[9])>2)
+   {
+      BM[9][1,2]=E[2];
+      BM[9][2,2]=1;
+   }
+   else
+   {
+      intmat tempInt[2][1]=E[2],1;
+      BM[9]=concatInt(BM[9],tempInt);
+      kill tempInt;
+   }
+   BM[2]=J;
+   list BM1=dropDim(BM);
+   list BMlist,hilfList;
+   ideal hilf;
+   intvec tempvec;
+
+   if(!attrib(BM1[1],"isSB")){BM1[1]=std(BM1[1]);}
+   for(i=1;i<=size(BM1[4]);i++)
+   {
+      hilf=simplify(reduce(BM1[4][i],BM1[1]),2);
+      if(size(hilf)>1){"Problem with BM1[4]in CenterBM";~;}
+      hilfList[i]=hilf[1];
+   }
+   for(i=1;i<=size(E[4]);i++)
+   {
+      BMlist[i]=BM1;
+      for(j=size(E[5][i]);j>=1;j--)
+      {
+         if(E[5][i][j]!=0)
+         {
+            BMlist[i][2][size(BMlist[i][2])+1]=hilfList[j];
+            BMlist[i][3][size(BMlist[i][3])+1]=1;
+         }
+         BMlist[i][4]=delete(BMlist[i][4],j);
+         BMlist[i][6]=deleteInt(BMlist[i][6],j,0);
+      }
+      BMlist[i][7]=deleteInt(BMlist[i][7],1,-1);
+      if(size(BMlist[i][9])>4)
+      {
+         intmat tempInt[2][ncols(BMlist[i][9])]=BMlist[i][9];
+         intmat tempInt2[2][ncols(BMlist[i][9])-2]=
+                 tempInt[1..2,3..ncols(BMlist[i][9])];
+         BMlist[i][9]=tempInt2;
+         kill tempInt,tempInt2;
+      }
+      else
+      {
+         BMlist[i][9]=tmat;
+      }
+   }
+   kill hilfList;list hilfList;
+   hilfList[1]=CenterTail(BMlist[1],C);
+   intmat maxmat=hilfList[1][9];
+   intvec maxiv=E[4][1];
+   int pos=1;
+   for(i=2;i<=size(E[4]);i++)
+   {
+      hilfList[i]=CenterTail(BMlist[i],C);
+      if(invGreater(hilfList[i][4]),maxmat,E[4][i],maxiv)
+      {
+         maxmat=hilfList[i][4];
+         maxiv=E[4][i];
+         pos=i;
+      }
+   }
+   re[1]=hilfList[pos][1];
+   intmat tempint=BM[9];
+   intmat tempint1[2][2]=tempint[1..2,1..2];
+   re[4]=concatInt(tempint1,maxmat);
+   re[2]=re[2][1],hilfList[pos][2];
+   re[3]=b;
+~;
+   return(re);
+}
+example
+{  "EXAMPLE:";
+   echo = 2;
+   ring R=0,(x,y),dp;
+
+   ideal W;
+   ideal J=x2-y3;
+   intvec b=1;
+   list E;
+   ideal abb=maxideal(1);
+   intvec v;
+   intvec w=-1;
+   matrix M;
+   intmat invmat[2][1]=0,-1;
+
+   list BM=W,J,b,E,abb,v,w,M,invmat;
+
+   CenterBM(BM);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+static proc invGreater(intmat M1, intmat M2, intvec iv1, intvec iv2)
+{
+// Auxilliary procedure, BM-algorithm
+   int i;
+   for(i=1;i<=min(ncols(M1),ncols(M2));i++)
+   {
+      if(M1[2,i]==-1)
+      {
+         if(M1[1,i]==0){ERROR("Invariant not set");}
+         if(M2[2,i]!=-1){return(1);}
+         if(M2[1,i]==0){ERROR("Invariant not set");}
+         break;
+      }
+      else
+      {
+         if(M2[2,i]==-1)
+         {
+            if(M2[1,i]==0){ERROR("Invariant not set");}
+            return(0);
+         }
+         if(M1[1,i]*M2[2,i]!= M2[1,i]*M1[2,i])
+         {
+            return(M1[1,i]*M2[2,i]> M2[1,i]*M1[2,i]);
+         }
+      }
+   }
+   return(iv1>iv2);
+}
+/////////////////////////////////////////////////////////////////////////////
+proc CenterTail(list BM, ideal C)
+{
+//!!! Auxilliary procedure, BM-algorithm
+//!!!!!!!!Rueckgabe im Zentrumsformat
+  int i,j,bmin;
+  int alpha=lcm(BM[3]);
+  vector w;
+  list re;
+  if(size(BM[2])==0)
+  {
+    re[1]=C+BM[1];
+    intvec tvec;
+    re[3]=tvec;
+    intmat tmat[2][1]=-1,-1;
+    re[4]=tmat;
+    tvec=size(BM[4]);
+    re[2]=tvec;
+    return(re);
+  }
+  for(i=1;i<=size(BM[3]);i++)
+  {
+     if(BM[2][i]!=0)
+     {
+       w[size(w)+1]=BM[2][i]^(alpha/BM[3][i]);
+     }
+  }
+  module M=w;
+  intvec satex;
+  list satList;
+  for(i=1;i<=size(BM[4]);i++)
+  {
+     satList=sat(M,BM[4][i]);
+     satex[i]=satList[2];
+     M=satList[1];
+  }
+//!!!!Hilfsobjekt G bilden!!!!!!!!!!!!!!!!
+//!!!!Hilfsobjekt H,codim -1 bilden!!!!!!!!!!!!!!!!
+//!!!! ???? an welcher stelle?????????
+  list deltaL;
+  list BMtemp=BM;
+  for(i=1;i<=nrows(M[1]);i++)
+  {
+     BMtemp[2]=ideal(M[1][i])+BMtemp[1];
+     deltaL[i]=DeltaList(BMtemp);
+     if(i==1)
+     {
+        bmin=size(deltaL[i]);
+     }
+     else
+     {
+        bmin=min(size(deltaL[i]),bmin);
+     }
+  }
+  if(bmin==0)
+  {
+     re[1]=C+BM[1];
+     intvec tvec;
+     re[3]=tvec;
+     if((BM[9][2,1]==-1)||(BM[9][1,1]!=0))
+     {
+        tvec=size(BM[4]);
+        re[2]=tvec;
+        intmat tmat[2][1]=0,1;
+        re[4]=tmat;
+     }
+     else
+     {
+        re[2]=BM[7];
+        re[4]=BM[9];
+     }
+     return(re);
+  }
+  ideal Ctemp=ideal(1);
+  while(deg(Ctemp[1])==0)
+  {
+    Ctemp=C;
+    for(i=1;i<=nrows(M[1]);i++)
+    {
+       Ctemp=Ctemp,deltaL[i][bmin];
+    }
+    Ctemp=std(Ctemp);
+    bmin--;
+    if(bmin==0){ERROR("empty set");}
+  }
+  //!!!!!!!!!!!!!Invariante ist bmin/alpha
+  // naechster Eintrag s_i wie in CenterBM
+  // dann dropDim  ....
+}
+
+/////////////////////////////////////////////////////////////////////////////
+static proc deleteInt(intvec v,int i,int ini)
+{
+//!!! Should be in kernel of Singular
+//--- delete i-th entry in intvec v,
+//--- if necessary reinitializing v with value ini
+   int s=size(v);
+   intvec w;
+   if((i<s)&&(i>1)){w=v[1..i-1],v[i+1..s];}
+   if(s==1){w=ini;return(w);}
+   if(i==1){w=v[2..s];}
+   if(i==s){w=v[1..s-1];}
+   return(w);
+}
+/////////////////////////////////////////////////////////////////////////////
+static proc concatInt(intmat A, intmat B)
+{
+//!!! Should be in kernel of Singular
+//--- concatenate two intmats
+  if(nrows(A)!=nrows(B)){ERROR("could not concat, wrong number of rows");}
+  intmat tempmat[nrows(A)][ncols(A)+ncols(B)];
+  tempmat[1..nrows(A),1..ncols(A)]=A[1..nrows(A),1..ncols(A)];
+  tempmat[1..nrows(A),ncols(A)+1..ncols(tempmat)]=B[1..nrows(A),1..ncols(B)];
+  return(tempmat);
+}
+/////////////////////////////////////////////////////////////////////////////
+proc dropDim(list BM)
+{
+ERROR("Not implemented yet");
+}
+/////////////////////////////////////////////////////////////////////////////
+proc CenterBO(list BO,list #)
+"USAGE:  CenterBO(BO);
+@*       BO = basic object, a list: ideal W,
+@*                                  ideal J,
+@*                                  intvec b,
+@*                                  list Ex,
+@*                                  ideal ab,
+@*                                  intvec v,
+@*                                  intvec w,
+@*                                  matrix M
+ASSUME:  R  = basering, a polynomial ring, W an ideal of R,
+@*       J  = ideal containing W
+COMPUTE: the center of the next blow-up of BO in the resolution algorithm
+         of [Bravo,Encinas,Villamayor]
+RETURN:  list l,
+         l[1]: ideal describing the center@*
+         l[2]: intvec w obtained in the process of determining l[1]@*
+         l[3]: intvec b obtained in the process of determining l[1]@*
+         l[4]: intvec inv obtained in the process of determining l[1]
+EXAMPLE: example CenterBO;  shows an example
+"
+{
+//---------------------------------------------------------------------------
+// Initialization  and sanity checks
+//---------------------------------------------------------------------------
+   int i,bo7save;
+   intvec tvec;
+//--- re=center,E^- indices, b vector, n vector
+   list re=ideal(1),BO[7],BO[3],tvec;
+   ideal J=BO[2];
+   if(size(J)==0)
+   {
+     re[1]=ideal(0);
+     return(re);
+   }
+//--- find Delta^(b-1)(J)
+   if(size(reduce(J,std(BO[1])))!=0)
+   {
+     list L=DeltaList(BO);
+   }
+   else
+   {
+     list L;
+     L[1]=J;
+   }
+   if(!defined(debugCenter))
+   {
+     int debugCenter;
+   }
+   if(debugCenter)
+   {
+     "----> In Center: after DeltaList";
+     "W";
+     BO[1];
+     "J";
+     BO[2];
+     "The Delta List:";
+     L;
+   }
+   int b=size(L);
+   if(b==0)
+   {
+//--- if J=W, we do not need to do anything
+//--- returning center=1 marks this chart as completed
+     return(re);
+   }
+//---------------------------------------------------------------------------
+// check whether max w-ord is constant
+//---------------------------------------------------------------------------
+   if(b==BO[3][1])
+   {
+//--- max w-ord is constant
+     if(BO[7][1]==-1)
+     {
+//--- first got its value in the previous step ==> initialize BO[7]
+       tvec[1]=size(BO[4])-1;
+       for(i=2;i<=size(BO[7]);i++)
+       {
+         tvec[i]=BO[7][i];
+       }
+       re[2]=tvec;
+       BO[7]=tvec;
+     }
+   }
+   else
+   {
+//--- max w-ord changed ==> reset BO[7], correct BO[3]
+     tvec[1]=-1;
+     re[2]=tvec;
+     BO[7]=tvec;
+     tvec[1]=b;
+     BO[3]=tvec;
+     if(defined(invSat))
+     {
+        invSat[2]=intvec(0);
+     }
+   }
+   re[3]=BO[3];
+//---------------------------------------------------------------------------
+// reduce from case 2 to case 1 of [Bravo, Encinas, Villamayor]
+//---------------------------------------------------------------------------
+   ideal C=L[b];
+   BO[2]=C;
+   if(debugCenter)
+   {
+     "----> In Center: before intersection with E_i:";
+     "bmax:",b;
+     "Sing(J,bmax):";
+      C;
+     "E:";
+      BO[4];
+     "list marking a priori known intersection properties:",BO[6];
+     "index of last element of E^- in E:",BO[7][1];
+   }
+//--- is intermediate result in iteration already good?
+//--- return it to calling proc CenterBO
+   if(size(#)>0)
+   {
+     if(#[1]==2)
+     {
+       re[1]=C;
+       kill tvec;
+       intvec tvec=re[2][1];
+       re[2]=tvec;
+       kill tvec;
+       intvec tvec=re[3][1];
+       re[3]=tvec;
+       kill tvec;
+       intvec tvec;
+       re[4]=tvec;
+       return(re);
+     }
+   }
+//--- do the reduction to case 1
+   list E=inters_E(BO);
+//--- if J is smooth and not too many E_i intersect simultaneously, let us
+//--- try to drop redundant components of the candidate for the center
+   if((b==1)&&(size(E)>3))
+   {
+//--- if J is not smooth we do not want to drop any information
+     if((size(E[4])>0) && (dim(std(slocusE(BO[2])))<0))
+     {
+//--- BO[2]==J because b==1
+//--- DropRedundant is the counterpart to DropCoeff
+//--- do not leave out one of them separately!!!
+      E=DropRedundant(BO,E);
+      if(size(E)==1)
+       {
+         kill tvec;
+         intvec tvec=re[2][1];
+         re[2]=tvec;
+         tvec[1]=re[3][1];
+         re[3]=tvec;
+         tvec[1]=re[4][1];
+         re[4]=tvec;
+         re[1]=E[1];
+         return(re);
+       }
+     }
+   }
+//--- set n correctly
+   if(E[2]<BO[9][1])
+   {
+//--- if n dropped, the subsequent Coeff-object will not be the same
+//--- ===> set BO[3][2] to zero to make sure that no previous data is used
+      if(defined(tvec)) {kill tvec;}
+      intvec tvec=BO[7][1],-1;
+      BO[7]=tvec;
+      tvec=BO[3][1],0;
+      BO[3]=tvec;
+      if(defined(invSat))
+      {
+         invSat[2]=intvec(0);
+      }
+   }
+   re[4][1]=E[2];
+   C=E[1]^b+J;
+   C=mstd(C)[2];
+   ideal C1=std(ideal(L[b])+E[1]);
+   if(debugCenter)
+   {
+     "----> In Center: reduction of case 2 to case 1";
+     "Output of inters_E, after dropping redundant components:";
+      E;
+     "result of intersection with E^-, i.e.(E^-)^b+J:";
+     C;
+     "candidate for center:";
+     C1;
+   }
+//---------------------------------------------------------------------------
+// Check whether we have a hypersurface component
+//---------------------------------------------------------------------------
+   if(dim(C1)==dim(std(BO[1]))-1)
+   {
+     if((size(reduce(J,C1))==0)&&(size(reduce(C1,std(J)))==0))
+     {
+//--- C1 equals J and is of codimension 1 in W
+        re[1]=C1;
+     }
+     else
+     {
+//--- C1 has a codimension 1 (in W) component
+        re[1]=std(equiRadical(C1));
+     }
+     kill tvec;
+     intvec tvec=re[2][1];
+     re[2]=tvec;
+     tvec[1]=re[3][1];
+     re[3]=tvec;
+     tvec[1]=re[4][1];
+     re[4]=tvec;
+//--- is the codimension 1 component a good choice or do we need to reset
+//--- the information from the previous steps
+     if(transversalT(re[1],BO[4]))
+     {
+        if(size(E)>2)
+        {
+          if(E[3]>E[2])
+          {
+            if(defined(shortcut)){kill shortcut;}
+            list shortcut=ideal(0),size(BO[4]),BO[7];
+            export(shortcut);
+          }
+        }
+        return(re);
+     }
+
+     ERROR("reset in Center, please send the example to the authors.");
+   }
+//---------------------------------------------------------------------------
+// Check whether it is a single point
+//---------------------------------------------------------------------------
+   if(dim(C1)==0)
+   {
+      C1=std(radical(C1));
+      if(vdim(C1)==1)
+      {
+//--- C1 is one point
+        re[1]=C1;
+        kill tvec;
+        intvec tvec=re[2][1];
+        re[2]=tvec;
+        kill tvec;
+        intvec tvec=re[3][1];
+        re[3]=tvec;
+        return(re);
+      }
+    }
+//---------------------------------------------------------------------------
+// Prepare input for forming the Coeff-Ideal
+//---------------------------------------------------------------------------
+   BO[2]=C;
+   if(size(BO[2])>5)
+   {
+      BO[2]=mstd(BO[2])[2];
+   }
+//--- drop leading entry of BO[3]
+   tvec=BO[3];
+   if(size(tvec)>1)
+   {
+     tvec=tvec[2..size(tvec)];
+     BO[3]=tvec;
+   }
+   else
+   {
+     BO[3][1]=0;
+   }
+   tvec=BO[9];
+   if(size(tvec)>1)
+   {
+     tvec=tvec[2..size(tvec)];
+     BO[9]=tvec;
+   }
+   else
+   {
+     BO[9][1]=0;
+   }
+   bo7save=BO[7][1];          // original value needed for result
+   if(defined(shortcut))
+   {
+     if((bo7save!=shortcut[3][1])&&(size(shortcut[3])!=1))
+     {
+       kill shortcut;
+     }
+     else
+     {
+       shortcut[2]=shortcut[2]-bo7save;
+       tvec=shortcut[3];
+       if(size(tvec)>1)
+       {
+         tvec=tvec[2..size(tvec)];
+         shortcut[3]=tvec;
+       }
+       else
+       {
+         shortcut[3]=intvec(shortcut[2]);
+       }
+     }
+   }
+   if(BO[7][1]>-1)
+   {
+//--- drop E^- and the corresponding information from BO[6]
+     for(i=1;i<=BO[7][1];i++)
+     {
+       BO[4]=delete(BO[4],1);
+       intvec bla1=BO[6];
+       BO[6]=intvec(bla1[2..size(bla1)]);
+       kill bla1;
+     }
+//--- drop leading entry of BO[7]
+     tvec=BO[7];
+     if(size(tvec)>1)
+     {
+       tvec=tvec[2..size(tvec)];
+       BO[7]=tvec;
+     }
+     else
+     {
+       BO[7][1]=-1;
+     }
+   }
+   else
+   {
+     if(BO[7][1]==-1)
+     {
+       list tplist;
+       BO[4]=tplist;
+       kill tplist;
+     }
+   }
+   if(debugCenter)
+   {
+     "----> In Center: Input to Coeff";
+     "b:",b;
+     "BO:";
+     BO;
+   }
+//--- prepare the third entry of the invariant tuple
+   int invSatSave=invSat[2][1];
+   tvec=invSat[2];
+   if(size(tvec)>1)
+   {
+     tvec=tvec[2..size(tvec)];
+     invSat[2]=tvec;
+   }
+   else
+   {
+     invSat[2][1]=0;
+   }
+//---------------------------------------------------------------------------
+// Form the Coeff-ideal, if possible and useful; otherwise use the previous
+// candidate for the center
+//---------------------------------------------------------------------------
+   list BO1=Coeff(BO,b);
+   if(debugCenter)
+   {
+     "----> In Center: Output of Coeff";
+     BO1;
+   }
+//--- Coeff returns int if something went wrong
+   if(typeof(BO1[1])=="int")
+   {
+      if(BO1[1]==0)
+      {
+//--- Coeff ideal was already resolved
+        re[1]=C1;
+        return(re);
+      }
+      else
+      {
+//--- no global hypersurface found
+        re=CoverCenter(BO,b,BO1[2]);
+        kill tvec;
+        intvec tvec=invSatSave;
+        for(i=1;i<=size(invSat[2]);i++)
+        {
+           tvec[i+1]=invSat[2][i];
+        }
+        invSat[2]=tvec;
+        return(re);
+      }
+   }
+   int coeff_invar;
+   ideal Idropped=1;
+//--- if b=1 drop redundant components of the Coeff-ideal
+   if(b==1)
+   {
+//--- Counterpart to DropRedundant -- do not leave out one of them separately
+     Idropped=DropCoeff(BO1);         // blow-up in these components
+                                      // is unnecessary
+   }
+//--- to switch off DropCoeff, set Idropped=1;
+   BO1[2]=sat(BO1[2],Idropped)[1];
+   if(deg(BO1[2][1])==0)
+   {
+//--- Coeff ideal is trivial
+     C1=radical(C1);
+     ideal C2=sat(C1,Idropped)[1];
+     if(deg(std(C2)[1])!=0)
+     {
+        C1=C2;
+     }
+//Aenderung: Strategie: nur im Notfall ganze except. Divisoren
+     if(deg(std(BO1[2])[1])==0)
+     {
+       list BOtemp=BO;
+       int bo17save=BO1[7][1];
+       BOtemp[7]=0;
+       BO1=Coeff(BOtemp,b,int(0));
+       BO1[2]=sat(BO1[2],Idropped)[1];
+       if(deg(std(BO1[2])[1])==0)
+       {
+//--- there is really nothing left to do for the Coeff ideal
+//--- the whole original BO1[2], i.e. Idropped, is the upcoming center
+          re[1]=Idropped;
+          re[2]=intvec(bo7save);
+          re[3]=intvec(b);
+          re[4]=intvec(E[2]);
+          return(re);
+       }
+       if(deg(std(slocus(radical(BO1[2])))[1])==0)
+       {
+          re[1]=BO1[2];
+//          re[2]=intvec(bo7save,BO1[7][1]);
+          re[2]=intvec(bo7save,bo17save);
+          re[3]=intvec(b,1);
+          re[4]=intvec(E[2],1);
+          invSat[2]=intvec(1,0);
+          return(re);
+       }
+//!!! effizienter machen???
+       list pr=primdecGTZ(BO1[2]);
+       ideal Itemp1=1;
+       int aa,bb;
+       for(aa=1;aa<=size(pr);aa++)
+       {
+          if(dim(std(pr[aa][2])) < (dim(std(BO1[1]))-1))
+          {
+//--- drop components which are themselves exceptional diviosrs
+             Itemp1=intersect(Itemp1,pr[aa][1]);
+          }
+       }
+       if(deg(std(Itemp1)[1])!=0)
+       {
+//--- treat the remaining components of the weak Coeff ideal
+          BO1[2]=Itemp1;
+       }
+       BO1[7]=BO[7];
+       for(aa=1;aa<=size(BO1[4]);aa++)
+       {
+         if(deg(std(BO1[4][aa])[1])==0){aa++;continue;}
+         if(defined(satlist)){kill satlist;}
+         list satlist=sat(BO1[2],BO1[4][aa]+BO1[1]);
+         if(deg(std(satlist[1])[1])==0)
+         {
+            coeff_invar++;
+            if(satlist[2]!=0)
+            {
+              for(bb=1;bb<=satlist[2]-1;bb++)
+              {
+                 BO1[2]=quotient(BO1[2],BO1[4][aa]+BO1[1]);
+              }
+            }
+            else
+            {
+              ERROR("J of temporary object had unexpected value;
+                     please send this example to the authors.");
+            }
+         }
+         else
+         {
+            BO1[2]=satlist[1];
+         }
+       }
+       if(deg(std(Itemp1)[1])==0)
+       {
+          re[1]=BO1[2];
+          re[2]=intvec(bo7save,BO1[7][1]);
+          re[3]=intvec(b,1);
+          re[4]=intvec(E[2],1);
+          invSat[2]=intvec(1,0);
+          return(re);
+       }
+       kill aa,bb;
+     }
+   }
+   if(invSatSave<coeff_invar)
+   {
+     invSatSave=coeff_invar;
+   }
+//---------------------------------------------------------------------------
+// Determine Center of Coeff-ideal and use it as the new center
+//---------------------------------------------------------------------------
+   if(!defined(templist))
+   {
+     if(size(BO1[2])>5)
+     {
+        BO1[2]=mstd(BO1[2])[2];
+     }
+     list templist=CenterBO(BO1,2);
+//--- only a sophisticated guess of a good center computed by
+//--- leaving center before intersection with the E_i.
+//--- whether the guess was good, is stored in 'good'.
+//--- (this variant saves charts in cases like the Whitney umbrella)
+     list E0,E1;
+
+     ideal Cstd=std(radical(templist[1]));
+     int good=((deg(std(slocusE(Cstd))[1])==0)&&(dim(std(BO1[2]))<=2));
+//if(defined(satlist)){good=0;}
+     if(good)
+     {
+        for(i=1;i<=size(BO[4]);i++)
+        {
+           if((deg(BO[4][i][1])>0)&&(size(reduce(BO[4][i],Cstd))!=0))
+           {
+              E0[size(E0)+1]=BO[4][i]+Cstd;
+              E1[size(E1)+1]=BO[4][i];
+           }
+        }
+        good=transversalT(Cstd,E1);
+        if(good)
+        {
+           good=normalCross(E0);
+        }
+     }
+     if(good)
+     {
+        list templist2=CenterBO(BO1,1);
+        if(dim(std(templist2[1]))!=dim(Cstd))
+        {
+           templist[1]=Cstd;
+           if(defined(shortcut)){kill shortcut;}
+           list shortcut=ideal(0),size(BO1[4]),templist[2];
+           export(shortcut);
+        }
+        else
+        {
+           templist=templist2;
+        }
+        kill templist2;
+     }
+     else
+     {
+//--- sophisticated guess was wrong, follow Villamayor's approach
+        kill templist;
+        list templist=CenterBO(BO1,1);
+     }
+   }
+   if((dim(std(templist[1]))==dim(std(BO1[1]))-1)
+       &&(size(templist[4])==1))
+   {
+     if(templist[4][1]==0)
+     {
+        for(i=1;i<=size(BO1[4]);i++)
+        {
+           if(size(reduce(templist[1],std(BO1[4][i])))==0)
+           {
+              templist[4][1]=1;
+              break;
+           }
+        }
+     }
+   }
+//!!! subsequent line should be deleted
+//if(defined(satlist)){templist[3][1]=BO[3][1];}
+   if(debugCenter)
+   {
+     "----> In Center: Iterated Center returned:";
+     templist;
+   }
+//--------------------------------------------------------------------------
+// set up the result and return it
+//--------------------------------------------------------------------------
+   re[1]=templist[1];
+   kill tvec;
+   intvec tvec;
+   tvec[1]=bo7save;
+   for(i=1;i<=size(templist[2]);i++)
+   {
+     tvec[i+1]=templist[2][i];
+   }
+   re[2]=tvec;
+   if(defined(shortcut))
+   {
+      shortcut[2]=shortcut[2]+bo7save;
+      shortcut[3]=tvec;
+   }
+   kill tvec;
+   intvec tvec;
+   tvec[1]=invSatSave;
+   for(i=1;i<=size(invSat[2]);i++)
+   {
+      tvec[i+1]=invSat[2][i];
+   }
+   invSat[2]=tvec;
+   kill tvec;
+   intvec tvec;
+   tvec[1]=b;
+   for(i=1;i<=size(templist[3]);i++)
+   {
+     tvec[i+1]=templist[3][i];
+   }
+   re[3]=tvec;
+   kill tvec;
+   intvec tvec;
+   tvec[1]=E[2];
+   for(i=1;i<=size(templist[4]);i++)
+   {
+     tvec[i+1]=templist[4][i];
+   }
+   re[4]=tvec;
+
+   return(re);
+}
+example
+{  "EXAMPLE:";
+   echo = 2;
+   ring R=0,(x,y),dp;
+
+   ideal W;
+   ideal J=x2-y3;
+   intvec b=1;
+   list E;
+   ideal abb=maxideal(1);
+   intvec v;
+   intvec w=-1;
+   matrix M;
+
+   list BO=W,J,b,E,abb,v,w,M,v;
+
+   CenterBO(BO);
+}
+//////////////////////////////////////////////////////////////////////////////
+static proc CoverCenter(list BO,int b, ideal Jb)
+{
+//----------------------------------------------------------------------------
+// Initialization
+//----------------------------------------------------------------------------
+   def R=basering;
+   int i,j,k;
+   intvec merk,merk2,maxv,fvec;
+   list L,ceList,re;
+   ceList[1]=ideal(0);
+   poly @p, at f;
+   ideal K,dummy;
+   if(!attrib(BO[2],"isSB"))
+   {
+     BO[2]=std(BO[2]);
+   }
+   for(i=1;i<=size(Jb);i++)
+   {
+      list tempmstd=mstd(slocus(Jb[i]));
+      if(size(tempmstd[1])>size(tempmstd[2]))
+      {
+         dummy=tempmstd[2];
+      }
+      else
+      {
+         dummy=tempmstd[1];
+      }
+      kill tempmstd;
+      L[i]=dummy;
+      K=K,dummy;
+   }
+   K=simplify(K,2);
+//---------------------------------------------------------------------------
+// The intersection of the singular loci of the L[i] is empty.
+// Find a suitable open covering of the affine chart, such that a global
+// hypersurface can be found in each open set.
+//---------------------------------------------------------------------------
+   matrix M=lift(K,ideal(1));
+   j=1;
+   for(i=1;i<=nrows(M);i++)
+   {
+      if(M[i,1]!=0)
+      {
+         merk[size(merk)+1]=i;
+         fvec[size(merk)]=j;
+      }
+      if((i-k)==size(L[j]))
+      {
+        k=i;
+        j++;
+      }
+   }
+//--------------------------------------------------------------------------
+// Find a candidate for the center in each open set
+//--------------------------------------------------------------------------
+//--- first entry of merk is 0 by construction of merk
+   for(i=2;i<=size(merk);i++)
+   {
+//--- open set is D(@p)
+       @p=K[merk[i]];
+//--- hypersurface is V(@f)
+       @f=Jb[fvec[i]];
+       execute("ring R1=("+charstr(R)+"),(@y,"+varstr(R)+"),dp;");
+       poly p=imap(R, at p);
+       poly f=imap(R, at f);
+       list @ce;
+       list BO=imap(R,BO);
+       BO[1]=BO[1]+ideal(@y*p-1);
+       BO[2]=BO[2]+ideal(@y*p-1);
+       for(j=1;j<=size(BO[4]);j++)
+       {
+          BO[4][j]=BO[4][j]+ideal(@y*p-1);
+       }
+//--- like usual Coeff, but hypersurface is already known
+       list BO1=SpecialCoeff(BO,b,f);
+//--- special situation in SpecialCoeff are marked by an error code of
+//--- type int
+       if(typeof(BO1[1])=="int")
+       {
+         if(BO1[1]==0)
+         {
+//--- Coeff ideal was already resolved
+           @ce[1]=BO[2];
+           @ce[2]=BO[7];
+           @ce[3]=BO[3];
+         }
+         else
+         {
+           if(BO[3]!=0)
+           {
+//--- intersections with E do not meet conditions ==> reset
+              ERROR("reset in Coeff, please send the example to the autors");
+           }
+         }
+       }
+       else
+       {
+//--- now do the recursion as usual
+         @ce=CenterBO(BO1);
+       }
+//---------------------------------------------------------------------------
+// Go back to the whole affine chart and form a suitable union of the
+// candidates
+//---------------------------------------------------------------------------
+//--- pass from open set to the whole affine chart by taking the closure
+       @ce[1]=eliminate(@ce[1], at y);
+       setring R;
+       ceList[i]=imap(R1, at ce);
+//--- set up invariant vector and determine maximum value of it
+       if(size(ceList[i][3])==size(ceList[i][4]))
+       {
+          kill merk2,maxv;
+          intvec merk2,maxv;
+          for(j=1;j<=size(ceList[i][3]);j++)
+          {
+            merk2[2*j-1]=ceList[i][3][j];
+            merk2[2*j]=ceList[i][4][j];
+            ceList[i][5]=merk2;
+            if(maxv<merk2)
+            {
+               maxv=merk2;
+            }
+          }
+       }
+       else
+       {
+          ERROR("This situation should not occur, please send the example
+                 to the authors.");
+       }
+       kill R1;
+   }
+   kill merk2;
+   intvec merk2=-2;
+//--- form the union of the components of the center with maximum invariant
+   for(i=1;i<=size(ceList);i++)
+   {
+     if(size(reduce(ceList[i][1],BO[2]))==0)
+     {
+//--- already resolved ==> ignore
+       i++;
+       continue;
+     }
+     if(ceList[i][5]==maxv)
+     {
+        if(merk2!=ceList[i][2])
+        {
+//--- E^- not of the same size as before resp. initialization
+          if(merk2[1]==-2)
+          {
+//--- initialization: save size of E^-
+            merk2=ceList[i][2];
+            re[1]=ceList[i][1];
+            re[2]=ceList[i][2];
+            re[3]=ceList[i][3];
+            re[4]=ceList[i][4];
+          }
+          else
+          {
+//--- otherwise ignore
+            i++;
+            continue;
+          }
+        }
+        else
+        {
+          re[1]=intersect(re[1],ceList[i][1]);
+        }
+     }
+   }
+//--------------------------------------------------------------------------
+// Perform last checks and return the result
+//--------------------------------------------------------------------------
+   if(size(re)!=4)
+   {
+//--- oops: already resolved in all open sets
+     re[1]=BO[2];
+     re[2]=-1;
+     re[3]=0;
+     re[4]=intvec(0);
+   }
+   return(re);
+}
+//////////////////////////////////////////////////////////////////////////////
+static proc SpecialCoeff(list BO,int b,poly f)
+{
+//----------------------------------------------------------------------------
+// Coeff with given hypersurface -- no checks of the hypersurface performed
+//----------------------------------------------------------------------------
+   int i,ch;
+   int e=int(factorial(b));
+   ideal C;
+   list L=DeltaList(BO);
+   int d=size(L);
+//--- set up ideal
+   for(i=0;i<b;i++)
+   {
+      C=C+L[i+1]^(e/(b-i));
+   }
+//--- move to hypersurface V(Z)
+   ideal Z=f;
+   C=C,Z;
+   BO[1]=BO[1]+Z;
+   BO[2]=C;
+   for(i=1;i<=size(BO[4]);i++)
+   {
+      BO[6][i]=0;             // reset intersection indicator
+      BO[4][i]=BO[4][i]+Z;    // intersect the E_i
+      BO[2]=sat(BO[2],BO[4][i]+BO[1])[1];
+                              // "strict transform" of J w.r.t E, not "total"
+   }
+   return(BO);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+static proc DropCoeff(list BO)
+"Internal procedure - no help and no example available
+"
+{
+//--- Initialization
+  int i,j;
+  list pr=minAssGTZ(BO[2]);
+  ideal I=BO[2];
+  ideal Itemp;
+  ideal Idropped=1;
+//--- Tests
+  for(i=1;i<=size(pr);i++)
+  {
+     if(i>size(pr))
+     {
+//--- the continue statement does not test the loop condition *sigh*
+        break;
+     }
+     if(deg(std(slocus(pr[i]))[1])!=0)
+     {
+//--- this component is singular ===> we still need it
+        i++;
+        continue;
+     }
+     Itemp=sat(I,pr[i])[1];
+     if(deg(std(Itemp+pr[i])[1])!=0)
+     {
+//--- this component is not disjoint from the other ones ===> we still need it
+        i++;
+        continue;
+     }
+     if(!transversalT(pr[i],BO[4]))
+     {
+//--- this component does not meet one of the remaining E_i transversally
+//--- ===> we still need it
+        i++;
+        continue;
+     }
+     if(!normalCross(BO[4],pr[i]))
+     {
+//--- this component is not normal crossing with the remaining E_i
+//--- ===> we still need it
+        i++;
+        continue;
+     }
+     if(defined(EE)){kill EE;}
+     list EE;
+     for(j=1;j<=size(BO[4]);j++)
+     {
+        EE[j]=BO[4][j]+pr[i];
+     }
+     if(!normalCross(EE))
+     {
+//--- we do not have a normal crossing situation for this component after all
+//--- ===> we still need it
+        i++;
+        continue;
+     }
+     Idropped=intersect(Idropped,pr[i]);
+     I=Itemp;
+  }
+  return(Idropped);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+static proc DropRedundant(list BO,list E)
+"Internal procedure - no help and no example available
+"
+{
+//---------------------------------------------------------------------------
+// Initialization and sanity checks
+//---------------------------------------------------------------------------
+  int ii,jj,kkdiff,nonnormal,ok;
+  ideal testid,dummy;
+  ideal center;
+  intvec transverse,dontdrop,zerovec;
+  transverse[size(BO[4])]=0;
+  dontdrop[size(E[4])]=0;
+  zerovec[size(E[4])]=0;
+  ideal J=BO[2];
+  int dimJ=dim(std(BO[2]));
+  list templist;
+  if(size(E)<5)
+  {
+//--- should not occur
+    return(E);
+  }
+  for(ii=1;ii<=BO[7][1];ii++)
+  {
+     if(BO[6][ii]==2)
+     {
+       kkdiff++;
+     }
+  }
+  int expDim=dimJ-E[2]+kkdiff;
+  if(size(E)==6)
+  {
+    nonnormal=E[6];
+  }
+//---------------------------------------------------------------------------
+// if dimJ were smaller than E[2], we would not have more than 3 entries in
+//    in the list E
+// if dimJ is also at least E[3] and nonnormal is 0, we only need to test that
+// * the intersection is of the expected dimension
+// * the intersections of the BO[4][i] and J are normal crossing
+// * the elements of E^+ have no influence (is done below)
+//---------------------------------------------------------------------------
+  if((E[3]<=dimJ)&&(!nonnormal))
+  {
+    ideal bla=E[1]+BO[2]+BO[1];
+    bla=radical(bla);
+    bla=mstd(bla)[2];
+
+    if(dim(std(slocusE(bla)))<0)
+    {
+      if(transversalT(J,BO[4]))
+      {
+        ok=1;
+        if(E[2]==E[3])
+        {
+//--- no further intersection with elements from E^+
+          for(ii=1;ii<=size(E[4]);ii++)
+          {
+            if(dim_slocus(BO[2]+E[4][ii])!=-1)
+            {
+              dontdrop[ii]=1;
+            }
+          }
+          if(dontdrop==zerovec)
+          {
+            list relist;
+            relist[1]=std(J);
+            return(relist);
+          }
+        }
+      }
+    }
+  }
+//---------------------------------------------------------------------------
+// now check whether the E_i actually occurring in the intersections meet
+// J transversally (one by one) and mark those elements of E[4] where it is
+// not the case
+//---------------------------------------------------------------------------
+ if(!ok)
+ {
+     for(ii=1;ii<=size(E[5]);ii++)
+     {
+//--- test the ii-th tuple of E[4] resp. its indices E[5]
+       for(jj=1;jj<=size(E[5][ii]);jj++)
+       {
+//--- if E[5][ii][jj]==1, E_jj is involved in E[4][ii]
+        if(E[5][ii][jj]==1)
+         {
+//--- transversality not yet determined
+           if(transverse[jj]==0)
+           {
+             templist[1]=BO[4][jj];
+             if(transversalT(BO[2],templist))
+             {
+               transverse[jj]=1;
+             }
+             else
+             {
+               transverse[jj]=-1;
+               dontdrop[ii]=1;
+             }
+           }
+           else
+           {
+//--- already computed transversality
+             if(transverse[jj]<0)
+             {
+               dontdrop[ii]=1;
+             }
+           }
+         }
+       }
+     }
+   }
+//---------------------------------------------------------------------------
+// if one of the non-marked tuples from E^- in E[4] has an intersection
+// of the expected dimension and does not meet any E_i from E^+
+// - except the ones which are met trivially - , it should be
+// dropped from the list.
+// it can also be dropped if an intersection occurs and normal crossing has
+// been checked.
+//---------------------------------------------------------------------------
+  for(ii=1;ii<=size(E[4]);ii++)
+  {
+//--- if E[4][ii] does not have transversal intersections, we cannot drop it
+    if(dontdrop[ii]==1)
+    {
+      ii++;
+      continue;
+    }
+//--- testing ii-th tuple from E[4]
+    testid=BO[1]+BO[2]+E[4][ii];
+    if(dim(std(testid))!=expDim)
+    {
+//--- not expected dimension
+      dontdrop[ii]=1;
+      ii++;
+      continue;
+    }
+    testid=mstd(testid)[2];
+
+    if(dim(std(slocusE(testid)))>=0)
+    {
+//--- not smooth, i.e. more than one component which intersect
+      dontdrop[ii]=1;
+      ii++;
+      continue;
+    }
+//--- if E^+ is empty, we are done; otherwise check intersections with E^+
+    if(BO[7][1]!=-1)
+    {
+      if(defined(pluslist)){kill pluslist;}
+      list pluslist;
+      for(jj=BO[7][1]+1;jj<=size(BO[4]);jj++)
+      {
+        dummy=BO[4][jj]+testid;
+        dummy=std(dummy);
+        if(expDim==dim(dummy))
+        {
+//--- intersection has wrong dimension
+          dontdrop[ii]=1;
+          break;
+        }
+        pluslist[jj-BO[7][1]]=BO[4][jj]+testid;
+      }
+      if(dontdrop[ii]==1)
+      {
+        ii++;
+        continue;
+      }
+      if(!normalCross(pluslist))
+      {
+//--- unfortunately, it is not normal crossing
+        dontdrop[ii]=1;
+      }
+    }
+  }
+//---------------------------------------------------------------------------
+// The returned list should look like the truncated output of inters_E
+//---------------------------------------------------------------------------
+  list retlist;
+  for(ii=1;ii<=size(E[4]);ii++)
+  {
+    if(dontdrop[ii]==1)
+    {
+      if(size(center)>0)
+      {
+        center=intersect(center,E[4][ii]);
+      }
+      else
+      {
+        center=E[4][ii];
+      }
+    }
+  }
+  retlist[1]=center;
+  retlist[2]=E[2];
+  retlist[3]=E[3];
+  return(retlist);
+}
+//////////////////////////////////////////////////////////////////////////////
+static proc transversalT(ideal J, list E,list #)
+"Internal procedure - no help and no example available
+"
+{
+//----------------------------------------------------------------------------
+// check whether J and each element of the list E meet transversally
+//----------------------------------------------------------------------------
+   def R=basering;
+   if(size(#)>0)
+   {
+     ideal pp=#[1];
+   }
+   int i;
+   ideal T,M;
+   ideal Jstd=std(J);
+   ideal Tstd;
+   int d=nvars(basering)-dim(Jstd)+1;   // d=n-dim(V(J) \cap hypersurface)
+   for(i=1;i<=size(E);i++)
+   {
+      if(size(reduce(E[i],Jstd))==0)
+      {
+//--- V(J) is contained in E[i]
+        return(0);
+      }
+      T=J,E[i];
+      Tstd=std(T);
+      d=nvars(basering)-dim(Tstd);
+      if(deg(Tstd[1])!=0)
+      {
+//--- intersection is non-empty
+//!!! abgeklemmt, da es doch in der Praxis vorkommt und korrekt sein kann!!!
+//!!! wenn ueberhaupt dann -1 zurueckgeben!!!
+//         if((d>=4)&&(size(T)>=10)){return(0);}
+         M=minor(jacob(T),d,Tstd)+T;
+         M=std(M);
+         if(deg(M[1])>0)
+         {
+//--- intersection is not transversal
+           if(size(#)==0)
+           {
+              return(0);
+           }
+           M=std(radical(M));
+           if(size(reduce(pp,M))>0){return(0);}
+         }
+      }
+   }
+//--- passed all tests
+   return(1);
+}
+///////////////////////////////////////////////////////////////////////////////
+static proc transversalTB(ideal J, list E,ideal V)
+"Internal procedure - no help and no example available
+"
+{
+//----------------------------------------------------------------------------
+// check whether J and each element of the list E meet transversally
+//----------------------------------------------------------------------------
+   def R=basering;
+
+   int i;
+   ideal T,M;
+   ideal Jstd=std(J);
+   ideal Tstd;
+   int d=nvars(basering)-dim(Jstd)+1;   // d=n-dim(V(J) \cap hypersurface)
+   for(i=1;i<=size(E);i++)
+   {
+      if(size(reduce(E[i],Jstd))==0)
+      {
+//--- V(J) is contained in E[i]
+        return(0);
+      }
+      T=J,E[i];
+      Tstd=std(T);
+      d=nvars(basering)-dim(Tstd);
+      if(deg(Tstd[1])!=0)
+      {
+//--- intersection is non-empty
+         if((d>=4)&&(size(T)>=10)){return(0);}
+         M=minor(jacob(T),d,Tstd)+T;
+         M=std(M+V);
+         if(deg(M[1])>0)
+         {
+            return(0);
+         }
+      }
+   }
+//--- passed all tests
+   return(1);
+}
+///////////////////////////////////////////////////////////////////////////////
+static proc powerI(ideal I,int n,int m)
+{
+//--- compute (n!/m)-th power of I, more efficient variant
+   int i;
+   int mon=1;
+   for(i=1;i<=size(I);i++)
+   {
+     if(size(I[i])>1){mon=0;break;}
+   }
+   if(mon)
+   {
+      if(size(reduce(I,std(radical(I[1]))))<size(I)-1){mon=0;}
+   }
+   if((mon)&&(size(I)>3))
+   {
+      int e=int(factorial(n))/m;
+      ideal J=1;
+      poly p=I[1];
+      I=I[2..size(I)];
+      ideal K=p^e;
+      for(i=1;i<=e;i++)
+      {
+         J=interred(J*I);
+         K=K,(p^(e-i))*J;
+      }
+      return(K);
+   }
+   for(i=n;i>1;i--)
+   {
+      if(i!=m)
+      {
+         I=I^i;
+      }
+   }
+   return(I);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static proc Coeff(list BO, int b, list #)
+"USAGE:  Coeff (BO);
+@*       BO = basic object, a list: ideal W,
+@*                                  ideal J,
+@*                                  intvec b (already truncated for Coeff),
+@*                                  list Ex  (already truncated for Coeff),
+@*                                  ideal ab,
+@*                                  intvec v,
+@*                                  intvec w (already truncated for Coeff),
+@*                                  matrix M
+@*       b  = integer indication bmax(BO)
+ASSUME:  R  = basering, a polynomial ring, W an ideal of R,
+@*       J  = ideal containing W
+COMPUTE: Coeff-Ideal of BO as defined in [Bravo,Encinas,Villamayor]
+RETURN:  basic object of the Coeff-Ideal
+EXAMPLE: example Coeff;    shows an example
+"
+{
+//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+//!!! TASK: lower dimension by more than one in a single step if possible !!!
+//!!!       (improve bookkeeping of invariants in Coeff and Center)       !!!
+//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+//---------------------------------------------------------------------------
+// Initialization  and sanity checks
+//---------------------------------------------------------------------------
+   int i,k,dummy,errtype;
+   int ma=size(BO[4]);
+   intvec merk;
+   if(!defined(debugCoeff))
+   {
+     int debugCoeff;
+   }
+   ideal C;
+   list L;
+   if(size(#)!=0)
+   {
+      if(typeof(#[1])=="ideal")
+      {
+        L=#;
+      }
+      else
+      {
+        ma=#[1];
+        L=DeltaList(BO);
+      }
+   }
+   else
+   {
+      L=DeltaList(BO);
+   }
+
+   if(debugCoeff)
+   {
+     "----> In Coeff: result of DeltaList:";
+     L;
+   }
+   int d=size(L);                   // bmax of BO
+   if((debugCoeff)&&(d!=b))
+   {
+      "!!!!!! Length of DeltaList does not equal second argument !!!!!!";
+      "!!!!!! BO might not have been ord ~ 1 or wrong b          !!!!!!";
+   }
+   if(b>=6){return(0);}              // b is too big
+   int e=int(factorial(b));          // b of Coeff-Ideal
+   if(e==0)
+   {
+     ERROR( "// integer size too small for forming b! .");
+   }
+   if(b==0)
+   {
+     ERROR( "// second argument to Coeff should never be zero."  );
+   }
+//----------------------------------------------------------------------------
+// Form the Coeff-Ideal
+// Step 1: choose hypersurface
+// Step 2: sum over correct powers of Delta^i(BO[2])
+// Step 3: do the intersection
+//----------------------------------------------------------------------------
+//--- Step 1
+   ideal Z;
+   poly p;
+   for(i=1;i<=ncols(L[d]);i++)
+   {
+//--- Look for smooth hypersurface in generators of Delta^(bmax-1)(BO[2])
+     dummy=goodChoice(BO,L[d][i]);
+     if(!dummy)
+     {
+       Z= L[d][i];
+       break;
+     }
+     else
+     {
+       if(dummy>1)
+       {
+          merk[size(merk)+1]=i;
+       }
+       if(dummy>errtype)
+       {
+         errtype=dummy;
+       }
+     }
+   }
+   if(size(Z)==0)
+   {
+//--- no suitable element in generators of Delta^(bmax-1)(BO[2])
+//--- try random linear combination
+      for(k=1;k<=10;k++)
+      {
+         for(i=2;i<=size(merk);i++)
+         {
+            p=p+random(-100,100)*L[d][merk[i]];
+         }
+         dummy=goodChoice(BO,p);
+         if(!dummy)
+         {
+            Z=p;
+            break;
+         }
+         else
+         {
+            p=0;
+         }
+      }
+      if(dummy)
+      {
+        for(i=1;i<=size(L[d]);i++)
+        {
+           p=p+random(-100,100)*L[d][i];
+        }
+        dummy=goodChoice(BO,p);
+        if(!dummy)
+        {
+//--- found a suitable one
+           Z=p;
+        }
+      }
+      if(dummy)
+      {
+//--- did not find a suitable random linear combination either
+         if(dummy>errtype)
+         {
+           errtype=dummy;
+         }
+         list retlist=errtype,L[d];
+         return(retlist);
+      }
+   }
+   if(debugCoeff)
+   {
+     "----> In Coeff: Chosen hypersurface";
+     Z;
+   }
+//--- Step 2
+   C=Z;
+   for(i=0;i<b;i++)
+   {
+      C=C,powerI(simplify(reduce(L[i+1],std(Z)),2),b,b-i);
+   }
+   C=interred(C);
+
+   if(debugCoeff)
+   {
+     "----> In Coeff: J before saturation";
+     C;
+   }
+
+//--- Step 3
+   BO[1]=BO[1]+Z;
+   BO[2]=C;
+   for(i=1;i<=size(BO[4]);i++)
+   {
+      BO[6][i]=0;             // reset intersection indicator
+      BO[4][i]=BO[4][i]+Z;    // intersect the E_i
+      if(i<=ma)
+      {
+        BO[2]=sat(BO[2],BO[4][i]+BO[1])[1];
+                       // "strict transform" of J w.r.t E, not "total"
+      }
+   }
+   if(debugCoeff)
+   {
+     "----> In Coeff:";
+     " J after saturation:";
+     BO[2];
+   }
+   return(BO);
+}
+example
+{"EXAMPLE:";
+   echo = 2;
+   ring R=0,(x,y,z),dp;
+
+   ideal W;
+   ideal J=z^2+x^2*y^2;
+   intvec b=0;
+   list E;
+   ideal abb=maxideal(1);
+   intvec v;
+   intvec w=-1;
+   matrix M;
+
+   list BO=W,J,b,E,abb,v,w,M;
+
+   Coeff(BO,2);
+}
+//////////////////////////////////////////////////////////////////////////////
+static proc goodChoice(list BO, poly p)
+"Internal procedure - no help and no example available
+"
+{
+//---------------------------------------------------------------------------
+// test whether new W is smooth
+//---------------------------------------------------------------------------
+   ideal W=BO[1]+ideal(p);
+   if(size(reduce(p,std(BO[1])))==0)
+   {
+//--- p is already in BO[1], i.e. does not define a hypersurface in W
+     return(1);
+   }
+   if(dim(std(slocusE(W)))>=0)
+//   if(dim(timeStd(slocusE(W),20))>=0)
+   {
+//--- new W would not be smooth
+     return(1);
+   }
+   if(size(BO[4])==0)
+   {
+//--- E is empty, no further tests necessary
+     return(0);
+   }
+//--------------------------------------------------------------------------
+// test whether the hypersurface meets the E_i transversally
+//--------------------------------------------------------------------------
+   list E=BO[4];
+   int i,d;
+   ideal T=W;
+   ideal Tstd=std(T);
+   d=nvars(basering)-dim(Tstd)+1;
+   ideal M;
+   for(i=1;i<=size(E);i++)
+   {
+      T=W,E[i];
+      M=minor(jacob(T),d,Tstd)+T;
+      M=std(M);
+      if(deg(M[1])>0)
+      {
+//--- intersection not transversal
+        return(2);
+      }
+   }
+//--------------------------------------------------------------------------
+// test whether the new E_i have normal crossings
+//--------------------------------------------------------------------------
+   for(i=1;i<=size(E);i++)
+   {
+      E[i]=E[i],p;
+   }
+   if(normalCross(E))
+   {
+     return(0);
+   }
+   else
+   {
+     return(2);
+   }
+}
+//////////////////////////////////////////////////////////////////////////////
+
+proc presentTree(list L)
+"USAGE:  presentTree(L);
+         L=list, output of resolve
+RETURN:  nothing, only pretty printing of the output data of resolve()
+EXAMPLE: none
+"
+{
+  def r=basering;
+  int i,j,k;
+  if(size(L[2])==1)
+  {
+     "The object was already resolved or the list L does not";
+     "have required input format. There is just one chart in";
+     "the tree.";
+     return();
+  }
+  for(i=1;i<=size(L[1]);i++)
+  {
+    "                        ";
+    "/////////////////////////// Final Chart",i,"/////////////////////////";
+    def s=L[1][i];
+    setring s;
+    "======================== History of this chart ======================";
+    for(j=2;j<=ncols(path);j++)
+    {
+      "                  ";
+      "Blow Up",j-1,":";
+      "     Center determined in L[2]["+string(path[1,j])+"],";
+      "     Passing to chart ",path[2,j]," in resulting blow up.";
+    }
+    "                 ";
+    "======================== Data of this chart ========================";
+    showBO(BO);
+    setring r;
+    kill s;
+    pause();
+  }
+  "////////////////////////////////////////////////////////////////////";
+  "For identification of exceptional divisors please use the tools";
+  "provided by reszeta.lib, e.g. collectDiv.";
+  "For viewing an illustration of the tree of charts please use the";
+  "procedure ResTree from resgraph.lib.";
+  "////////////////////////////////////////////////////////////////////";
+  return();
+}
+//////////////////////////////////////////////////////////////////////////////
+
+proc showBO(list BO)
+"USAGE:  showBO(BO);
+@*        BO=basic object, a list: ideal W,
+@*                                  ideal J,
+@*                                  intvec b (already truncated for Coeff),
+@*                                  list Ex  (already truncated for Coeff),
+@*                                  ideal ab,
+@*                                  intvec v,
+@*                                  intvec w (already truncated for Coeff),
+@*                                  matrix M
+RETURN:   nothing, only pretty printing
+EXAMPLE:  none
+"
+{
+  "                       ";
+  "==== Ambient Space: ";BO[1];"      ";
+  "==== Ideal of Variety: ";BO[2];"      ";
+  int i;
+  list M;
+  for(i=1;i<=size(BO[4]);i++)
+  {
+    M[i]=ideal(BO[4][i]);
+  }
+  "==== Exceptional Divisors: ";print(M);"   ";
+  "==== Images of variables of original ring:";BO[5];"   ";
+}
+//////////////////////////////////////////////////////////////////////////////
+////////////////////////    main procedure    ////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+proc resolve(ideal J, list #)
+"USAGE:  resolve (J); or resolve (J,i[,k]);
+@*       J ideal
+@*       i,k int
+COMPUTE: a resolution of J,
+@*       if i > 0 debugging is turned on according to the following switches:
+@*       j1: value 0 or 1; turn off or on correctness checks in all steps
+@*       j2: value 0 or 2; turn off or on debugCenter
+@*       j3: value 0 or 4; turn off or on debugBlowUp
+@*       j4: value 0 or 8; turn off or on debugCoeff
+@*       j5: value 0 or 16:turn off or on debugging of Intersection with E^-
+@*       j6: value 0 or 32:turn off or on stop after pass throught the loop
+@*       i=j1+j2+j3+j4+j5+j6
+RETURN:  a list l of 2 lists of rings
+         l[1][i] is a ring containing a basic object BO, the result of the
+         resolution.
+         l[2] contains all rings which occured during the resolution process
+NOTE:    result may be viewed in a human readable form using presentTree()
+EXAMPLE: example resolve;  shows an example
+"
+{
+//----------------------------------------------------------------------------
+// Initialization and sanity checks
+//----------------------------------------------------------------------------
+   def R=basering;
+   list allRings;
+   allRings[1]=R;
+   list endRings;
+   module path=[0,-1];
+   ideal W;
+   list E;
+   ideal abb=maxideal(1);
+   intvec v;
+   intvec bvec;
+   intvec w=-1;
+   matrix intE;
+   int extra,bm;
+   if(defined(BO)){kill BO;}
+   if(defined(cent)){kill cent;}
+
+   ideal Jrad=equiRadical(J);
+   if(size(reduce(Jrad,std(J)))!=0)
+   {
+      "WARNING! The input is not reduced or not equidimensional!";
+      "We will continue with the reduced top-dimensional part of input";
+      J=Jrad;
+   }
+
+   int i,j,debu,loca,locaT,ftemp,debugResolve,smooth;
+//--- switches for local and for debugging may occur in any order
+   i=size(#);
+   extra=3;
+   for(j=1;j<=i;j++)
+   {
+     if(typeof(#[j])=="int")
+     {
+       debugResolve=#[j];
+//--- debu: debug switch for resolve, smallest bit in debugResolve
+       debu=debugResolve mod 2;
+     }
+     else
+     {
+        if(#[j]=="M")
+        {
+           bm=1;
+           ERROR("Not implemented yet");
+        }
+        if(#[j]=="E"){extra=0;}
+        if(#[j]=="A"){extra=2;}
+        if(#[j]=="K"){extra=3;}
+        if(#[j]=="L"){loca=1;}
+     }
+   }
+   if(loca)
+   {
+      list qs=minAssGTZ(J);
+      ideal K=ideal(1);
+      for(j=1;j<=size(qs);j++)
+      {
+         if(size(reduce(qs[j],std(maxideal(1))))==0)
+         {
+            K=intersect(K,qs[j]);
+         }
+      }
+      J=K;
+      list qr=minAssGTZ(slocus(J));
+      K=ideal(1);
+      for(j=1;j<=size(qr);j++)
+      {
+         if(size(reduce(qr[j],std(maxideal(1))))!=0)
+         {
+            K=intersect(K,qr[j]);
+            smooth++;
+         }
+         else
+         {
+            if(dim(std(qr[j]))>0){loca=0;}
+//---- test for isolated singularity at 0
+         }
+      }
+      K=std(K);
+//---- if deg(K[1])==0 the point 0 is on all components of the singular
+//---- locus and we can work globally
+      if(smooth==size(qr)){smooth=-1;}
+//---- the point 0 is not on the singular locus
+      if((deg(K[1])>0)&&(smooth>=0)&&(!loca))
+      {
+         locaT=1;
+         poly @p;
+         for(j=1;j<=size(K);j++)
+         {
+            if(jet(K[j],0)!=0)
+            {
+               @p=K[j];
+               break;
+            }
+         }
+         export(@p);
+      }
+      if((loca)&&(!smooth)){loca=0;}
+//---- the case that 0 is isolated singularity and the only singular point
+   }
+   export(locaT);
+//---In case of option "L" the following holds
+//---loca=0 and locaT=0  we perform the global case
+//---loca !=0: 0 is isolated singular point, but there are other singularities
+//---locaT!=0: O is singular point, but not isolated, and there is a componente//---          of the singular locus not containing 0
+
+//--- if necessary, set the corresponding debugFlags
+   if(defined(debugResolve))
+   {
+//--- 2nd bit from the right
+     int debugCenter=(debugResolve div 2) mod 2;
+     export debugCenter;
+//--- 3rd bit from the right
+     int debugBlowUp=(debugResolve div 4) mod 2;
+     export debugBlowUp;
+//--- 4th bit from the right
+     int debugCoeff=(debugResolve div 8) mod 2;
+     export debugCoeff;
+//--- 5th bit from the right
+     int debug_Inters_E=(debugResolve div 16) mod 2;
+     export debug_Inters_E;
+//--- 6th bit from the right
+     int praes_stop=(debugResolve div 32) mod 2;
+   }
+//--- set the correct attributes to J for speed ups
+   if( typeof(attrib(J,"isEqui"))!="int" )
+   {
+      if(size(J)==1)
+      {
+         attrib(J,"isEqui",1);
+      }
+      else
+      {
+         attrib(J,"isEqui",0);
+      }
+   }
+   if(size(J)==1)
+   {
+      attrib(J,"isHy",1);
+   }
+   else
+   {
+      attrib(J,"isHy",0);
+   }
+//--- create the BO
+   list BO=W,J,bvec,E,abb,v,w,intE;
+   if(defined(invSat)){kill invSat;}
+   list invSat=ideal(0),intvec(0);
+   export(invSat);
+   if(bm)
+   {
+     intmat invmat[2][1]=0,-1;
+     BO[9]=invmat;
+   }
+   else
+   {
+     BO[9]=intvec(0);
+   }
+   export BO;
+   list tmpList;
+   int blo;
+   int k,Ecount,tmpPtr;
+   i=0;
+   if(smooth==-1)
+   {
+      endRings[1]=R;
+      list result=endRings,allRings;
+      if(debu)
+      {
+         "============= result will be tested ==========";
+         "                                              ";
+         "the number of charts obtained:",size(endRings);
+         "=============     result is o.k.    ==========";
+      }
+      kill debugCenter,debugBlowUp,debugCoeff,debug_Inters_E;
+      return(result);
+   }
+//-----------------------------------------------------------------------------
+// While there are rings to be considered, determine center and blow up
+//-----------------------------------------------------------------------------
+   while(i<size(allRings))
+   {
+      i++;
+      def S=allRings[i];
+      setring S;
+      list pr;
+      ideal Jstd=std(BO[2]);
+//-----------------------------------------------------------------------------
+// Determine Center
+//-----------------------------------------------------------------------------
+      if(i==1)
+      {
+         list deltaL=DeltaList(BO);
+         ideal sL=radical(deltaL[size(deltaL)]);
+         if((deg(std(slocus(sL))[1])==0)&&(size(minAssGTZ(sL))==1))
+         {
+            list @ce=sL,intvec(-1),intvec(0),intvec(0);
+            ideal cent=@ce[1];
+         }
+      }
+//--- before computing a center, check whether we have a stored one
+      if(size(BO)>9)
+      {
+         while(size(BO[10])>0)
+         {
+            list @ce=BO[10][1];
+//--- check of the center
+           // @ce=correctC(BO, at ce,bm);
+//--- use stored center
+            BO[10]=delete(BO[10],1);
+            if(size(@ce[1])==0)
+            {
+//--- stored center was not ok
+              continue;
+            }
+            tmpPtr=0;
+            for(Ecount=1;Ecount <= size(@ce[2]); Ecount++)
+            {
+              if(@ce[2][Ecount]>-1)
+              {
+                tmpPtr=tmpPtr+ at ce[2][Ecount];
+              }
+              else
+              {
+                @ce[2][Ecount]=size(BO[4])-tmpPtr-1;
+                for(int cnthlp=1;cnthlp<=size(BO[10]);cnthlp++)
+                {
+                   BO[10][cnthlp][2][Ecount]=@ce[2][Ecount];
+                }
+                kill cnthlp;
+                break;
+              }
+            }
+            if(Ecount<size(@ce[2]))
+            {
+              for(tmpPtr=Ecount+1;tmpPtr<=size(@ce[2]);tmpPtr++)
+              {
+                @ce[2][tmpPtr]=0;
+                for(int cnthlp=1;cnthlp<=size(BO[10]);cnthlp++)
+                {
+                   BO[10][cnthlp][2][tmpPtr]=@ce[2][tmpPtr];
+                }
+                kill cnthlp;
+              }
+            }
+            break;
+         }
+         if(defined(@ce))
+         {
+           if(size(@ce[1])==0)
+           {
+              kill @ce;
+           }
+           else
+           {
+              ideal cent=@ce[1];
+           }
+         }
+         if(size(BO[10])==0)
+         {
+//--- previously had stored centers, all have been used; we need to clean up
+            BO=delete(BO,10);
+         }
+      }
+      if((loca)&&(i==1))
+      {
+//--- local case: initial step is blow-up in origin
+         if(defined(@ce)){kill @ce;}
+         if(defined(cent)){kill cent;}
+         if(size(reduce(slocusE(BO[2]),std(maxideal(1))))==0)
+         {
+            list @ce=maxideal(1),intvec(-1),intvec(0),intvec(0);
+         }
+         else
+         {
+            list @ce=BO[2],intvec(-1),intvec(1),intvec(0);
+         }
+         ideal cent=@ce[1];
+      }
+      if(((loca)||(locaT))&&(i!=1))
+      {
+         int JmeetsE;
+         for(j=1;j<=size(BO[4]);j++)
+         {
+            if(deg(std(BO[2]+BO[4][j])[1])!=0)
+            {
+               JmeetsE=1;
+               break;
+            }
+         }
+         if(!JmeetsE)
+         {
+            list @ce=BO[2],intvec(-1),intvec(1),intvec(0);
+            ideal cent=@ce[1];
+         }
+         kill JmeetsE;
+      }
+      if((locaT)&&(!defined(@ce)))
+      {
+          if(@p!=1)
+          {
+             list tr=minAssGTZ(slocusE(BO[2]));
+             ideal L=ideal(1);
+             for(j=1;j<=size(tr);j++)
+             {
+                if(size(reduce(ideal(@p),std(tr[j])))==0)
+                {
+                   L=intersect(L,tr[j]);
+                }
+             }
+             L=std(L);
+             if(deg(L[1])==0)
+             {
+                @p=1;
+             }
+             else
+             {
+               ideal fac=factorize(@p,1);
+               if(size(fac)==1)
+               {
+                 @p=fac[1];
+               }
+               else
+               {
+                  for(j=1;j<=size(fac);j++)
+                  {
+                     if(reduce(fac[j],L)==0)
+                     {
+                        @p=fac[j];
+                        break;
+                     }
+                  }
+               }
+             }
+             kill tr,L;
+          }
+          execute("ring R1=("+charstr(S)+"),(@z,"+varstr(S)+"),dp;");
+          poly p=imap(S, at p);
+          list BO=imap(S,BO);
+          list invSat=imap(S,invSat);
+          export(invSat);
+          ideal te=std(BO[2]);
+          BO[1]=BO[1]+ideal(@z*p-1);
+          BO[2]=BO[2]+ideal(@z*p-1);
+          for(j=1;j<=size(BO[4]);j++)
+          {
+             BO[4][j]=BO[4][j]+ideal(@z*p-1);
+          }
+//--- for computation of center: drop components not meeting the Ei
+          def BO2=BO;
+          list qs=minAssGTZ(BO2[2]);
+          ideal K=ideal(1);
+          for(j=1;j<=size(qs);j++)
+          {
+             if(CompMeetsE(qs[j],BO2[4]))
+             {
+                K=intersect(K,qs[j]);
+             }
+          }
+          BO2[2]=K;
+//--- check whether we are done
+          if(deg(std(BO2[2])[1])==0)
+          {
+             list @ce=BO[2],intvec(-1),intvec(1),intvec(0);
+          }
+          if(!defined(@ce))
+          {
+             if(bm)
+             {
+                list @ce=CenterBM(BO2);
+             }
+             else
+             {
+                list @ce=CenterBO(BO2);
+             }
+          }
+//--- if computation of center returned BO2[2], we are done
+//--- ==> set @ce to BO[2], because later checks work with BO instead of BO2
+          if((size(reduce(@ce[1],std(BO2[2])))==0)&&
+             (size(reduce(BO2[2],std(@ce[1])))==0))
+          {
+             @ce[1]=BO[2];
+          }
+          if(size(specialReduce(@ce[1],te,p))==0)
+          {
+             BO=imap(S,BO);
+             @ce[1]=BO[2];
+          }
+          else
+          {
+             //@ce=correctC(BO, at ce,bm);
+             @ce[1]=eliminate(@ce[1], at z);
+          }
+          setring S;
+          list @ce=imap(R1, at ce);
+          kill R1;
+
+         if((size(reduce(BO[2],std(@ce[1])))==0)
+             &&(size(reduce(@ce[1],Jstd))==0))
+         {
+//--- J and center coincide
+            pr[1]=@ce[1];
+            ideal cent=@ce[1];
+         }
+         else
+         {
+//--- decompose center and use first component
+            pr=minAssGTZ(@ce[1]);
+               if(size(reduce(@p,std(pr[1])))==0){"Achtung";~;}
+               if(deg(std(slocus(pr[1]))[1])>0){"singulaer";~;}
+            ideal cent=pr[1];
+         }
+         if(size(pr)>1)
+         {
+//--- store the other components
+            for(k=2;k<=size(pr);k++)
+            {
+               if(size(reduce(@p,std(pr[k])))==0){"Achtung";~;}
+               if(deg(std(slocus(pr[k]))[1])>0){"singulaer";~;}
+               if(size(reduce(@p,std(pr[k])))!=0)
+               {
+                  tmpList[size(tmpList)+1]=list(pr[k], at ce[2], at ce[3], at ce[4]);
+               }
+            }
+            BO[10]=tmpList;
+            kill tmpList;
+            list tmpList;
+         }
+      }
+      if(!defined(@ce))
+      {
+//--- no previously determined center, we need to compute one
+         if(loca)
+         {
+//--- local case: center should be inside exceptional locus
+            ideal Ex=ideal(1);
+            k=0;
+            for(j=1;j<=size(BO[4]);j++)
+            {
+               if(deg(BO[4][j][1])!=0)
+               {
+                 Ex=Ex*BO[4][j];   //----!!!!hier evtl. Durchschnitt???
+                 k++;
+               }
+            }
+//--- for computation of center: drop components not meeting the Ei
+            list BOloc=BO;
+            list qs=minAssGTZ(BOloc[2]);
+            ideal K=ideal(1);
+            for(j=1;j<=size(qs);j++)
+            {
+              if(CompMeetsE(qs[j],BOloc[4]))
+              {
+                 K=intersect(K,qs[j]);
+              }
+            }
+            BOloc[2]=K;
+//--- check whether we are done
+            if(deg(std(BOloc[2])[1])==0)
+            {
+               list @ce=BO[2],intvec(-1),intvec(1),intvec(0);
+            }
+            if(!defined(@ce))
+            {
+              if(BO[3][1]!=0)
+              {
+                 BOloc[2]=BO[2]+Ex^((BO[3][1] div k)+1);//!!!!Vereinfachen???
+              }
+              else
+              {
+                 BOloc[2]=BO[2]+Ex^((size(DeltaList(BO)) div k)+1);
+              }
+              if(bm)
+              {
+                 list @ce=CenterBM(BOloc);
+              }
+              else
+              {
+                 list @ce=CenterBO(BOloc);
+              }
+              if(size(reduce(Ex,std(@ce[1])))!=0)
+              {
+                 list tempPr=minAssGTZ(@ce[1]);
+                 for(k=size(tempPr);k>=1;k--)
+                 {
+                    if(size(reduce(Ex,std(tempPr[k])))!=0)
+                    {
+                      tempPr=delete(tempPr,k);
+                    }
+                 }
+                 @ce[1]=1;
+                 for(k=1;k<=size(tempPr);k++)
+                 {
+                    @ce[1]=intersect(@ce[1],tempPr[k]);
+                 }
+                 if(deg(std(@ce[1])[1])==0)
+                 {
+                    @ce[1]=BO[2];
+                 }
+              }
+            }
+//--- test whether we are done
+            if(size(reduce(slocusE(BO[2]),std(@ce[1])))!=0)
+            {
+               if(transversalT(BO[2],BO[4]))
+               {
+                  if(defined(E)){kill E;}
+                  list E=BO[4];
+                  for(j=1;j<=size(E);j++){if(deg(E[j][1])>0){E[j]=E[j]+BO[2];}}
+                  if(normalCross(E))
+                  {
+                     @ce[1]=BO[2];
+                  }
+                  kill E;
+               }
+            }
+         }
+         else
+         {
+//--- non-local
+            if(bm)
+            {
+               list @ce=CenterBM(BO);
+            }
+            else
+            {
+               list @ce=CenterBO(BO);
+            }
+//--- check of the center
+            //@ce=correctC(BO, at ce,bm);
+            if((size(@ce[1])==0)&&(size(@ce[4])<(size(@ce[3])-1)))
+            {
+               intvec xxx=@ce[3];
+               xxx=xxx[1..size(@ce[4])];
+               @ce[3]=xxx;
+               xxx=@ce[2];
+               xxx=xxx[1..size(@ce[4])];
+               @ce[2]=xxx;
+               kill xxx;
+            }
+         }
+         if((size(reduce(BO[2],std(@ce[1])))==0)
+             &&(size(reduce(@ce[1],Jstd))==0))
+         {
+//--- J and center coincide
+            pr[1]=@ce[1];
+            ideal cent=@ce[1];
+         }
+         else
+         {
+//--- decompose center and use first component
+            pr=minAssGTZ(@ce[1]);
+            ideal cent=pr[1];
+         }
+         if(size(pr)>1)
+         {
+//--- store the other components
+            for(k=2;k<=size(pr);k++)
+            {
+               tmpList[k-1]=list(pr[k], at ce[2], at ce[3], at ce[4]);
+            }
+            BO[10]=tmpList;
+            kill tmpList;
+            list tmpList;
+         }
+      }
+//--- do not forget to update BO[7] and BO[3]
+      export cent;
+      BO[7]=@ce[2];
+      BO[3]=@ce[3];
+      if((loca||locaT)&&(size(@ce)<4)){@ce[4]=0;} //Provisorium !!!
+      if((size(@ce[4])<size(@ce[2])-1)||(size(@ce[4])<size(@ce[3])-1))
+      {
+        if((deg(std(@ce[1])[1])==0)&&(deg(std(BO[2])[1])==0))
+        {
+           intvec nullvec;
+           nullvec[size(@ce[2])-1]=0;
+           @ce[4]=nullvec;
+           kill nullvec;
+        }
+        else
+        {
+           "ERROR:@ce[4] hat falsche Laenge - nicht-trivialer Fall";
+           ~;
+        }
+      }
+      if((typeof(@ce[4])=="intvec") || (typeof(@ce[4])=="intmat"))
+      {
+        BO[9]=@ce[4];
+      }
+//---------------------------------------------------------------------------
+// various checks and debug output
+//---------------------------------------------------------------------------
+      if((debu) || (praes_stop))
+      {
+//--- Show BO of this step
+         "++++++++++++++ Overview of Current Chart +++++++++++++++++++++++";
+         "Current number of final charts:",size(endRings);
+         "Total number of charts currently in chart-tree:",size(allRings);
+         "Index of the current chart in chart-tree:",i;
+         "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++";
+         showBO(BO);
+         "-------------------------- Upcoming Center ---------------------";
+         interred(cent);
+         "----------------------------------------------------------------";
+      }
+      if(praes_stop)
+      {
+         ~;
+      }
+      if(debu)
+      {
+//--- various checks, see output for comments
+         if(size(BO[1])>0)
+         {
+            if(deg(BO[1][1])==0)
+            {
+               "!!!  W is empty  !!!";
+               path;
+               setring R;
+               kill S;
+               list result=endRings,allRings;
+               return(result);
+            }
+            if(deg(std(slocusE(BO[1]))[1])>0)
+            {
+               "!!!  W not smooth  !!!";
+               path;
+               setring R;
+               kill S;
+               list result=endRings,allRings;
+               return(result);
+            }
+         }
+         if((!loca)&&(!locaT))
+         {
+            if(deg(std(slocusE(cent+BO[1]))[1])>0)
+            {
+               "!!!  Center not smooth  !!!";
+               path;
+               std(cent+BO[1]);
+               ~;
+               setring R;
+               kill S;
+               list result=endRings,allRings;
+               return(result);
+            }
+         }
+         for(j=1;j<=size(BO[4]);j++)
+         {
+            if(deg(BO[4][j][1])>0)
+            {
+               if(deg(std(slocusE(BO[4][j]+BO[1]))[1])>0)
+               {
+                  "!!!  exceptional divisor is not smooth  !!!";
+                  path;
+                  setring R;
+                  kill S;
+                  list result=endRings,allRings;
+                  return(result);
+               }
+            }
+         }
+         if((!loca)&&(!locaT))
+         {
+            if((norC(BO,cent))&&(size(reduce(cent,Jstd))!=0))
+            {
+               "!!!  this chart is already finished  !!!";
+               cent=BO[2];
+               ~;
+            }
+         }
+      }
+//----------------------------------------------------------------------------
+// Do the blow up
+//----------------------------------------------------------------------------
+//!!!! Change this as soon as there is time!!!
+//!!!! quick and dirty bug fix for old shortcut which has not yet been killed
+if((dim(std(cent))==0)&&defined(shortcut)) {kill shortcut;}
+//!!! end of bugfix
+      if(size(reduce(cent,Jstd))!=0)
+      {
+//--- center does not equal J
+         tmpList=blowUpBO(BO,cent,extra);
+         if((debu)&&(!loca)&&(!locaT))
+         {
+//--- test it, if debu is set
+            if(!testBlowUp(BO,cent,tmpList,i,extra))
+            {
+               "non-redundant chart has been killed!";
+               ~;
+            }
+         }
+//--- extend the list of all rings
+         allRings[size(allRings)+1..size(allRings)+size(tmpList)]=
+                         tmpList[1..size(tmpList)];
+         for(j=1;j<=size(tmpList);j++)
+         {
+            def Q=allRings[size(allRings)-j+1];
+            setring Q;
+            def path=imap(S,path);
+            path=path,[i,size(tmpList)-j+1];
+            export path;
+            setring S;
+            kill Q;
+         }
+         kill tmpList;
+         list tmpList;
+      }
+      else
+      {
+//--- center equals J
+           k=0;
+           for(j=1;j<=size(BO[6]);j++)
+           {
+              if(BO[6][j]!=1)
+              {
+//--- there is an E_i which meets J in this chart
+                k=1;
+                break;
+              }
+           }
+           if((k)||(extra==2))
+           {
+//--- chart finished, non-redundant
+              endRings[size(endRings)+1]=S;
+           }
+      }
+      kill pr;
+      setring R;
+      kill S;
+   }
+//---------------------------------------------------------------------------
+// set up the result, test it (if debu is set) and return it
+//---------------------------------------------------------------------------
+   list result=endRings,allRings;
+   if(debu)
+   {
+      "============= result will be tested ==========";
+      "                                              ";
+      "the number of charts obtained:",size(endRings);
+      if(locaT){loca=2;}
+      int tes=testRes(J,endRings,loca);
+      if(tes)
+      {
+         "=============     result is o.k.    ==========";
+      }
+      else
+      {
+         "============     result is wrong    =========="; ~;
+      }
+   }
+   kill debugCenter,debugBlowUp,debugCoeff,debug_Inters_E;
+   if(locaT){kill @p;}
+   kill locaT;
+   return(result);
+}
+example
+{"EXAMPLE:";
+   echo = 2;
+   ring R=0,(x,y,z),dp;
+   ideal J=x3+y5+yz2+xy4;
+   list L=resolve(J,0);
+   def Q=L[1][7];
+   setring Q;
+   showBO(BO);
+}
+//////////////////////////////////////////////////////////////////////////
+//static
+proc CompMeetsE(ideal J, list E)
+"Internal procedure - no help and no example available
+"
+{
+   int i;
+   for(i=1;i<=size(E);i++)
+   {
+      if(deg(std(E[i])[1])!=0)
+      {
+         if(deg(std(J+E[i])[1])!=0)
+         {
+            return(1);
+         }
+      }
+   }
+   return(0);
+}
+
+//========================================================================
+//--------------  procedures for testing the result ----------------------
+//                (not yet commented)
+//========================================================================
+
+//////////////////////////////////////////////////////////////////////////
+static proc testRes(ideal J,list L,int loca)
+"Internal procedure - no help and no example available
+"
+{
+   int loc;
+   if(defined(locaT)){loc=locaT;}
+   if(loc){loca=0;}
+   def R=basering;
+   ideal M=maxideal(1);
+   int i,j,tr;
+   for(i=1;i<=size(L);i++)
+   {
+      def Q=L[i];
+      setring Q;
+      ideal J=BO[2];
+      list E=BO[4];
+      map phi=R,BO[5];
+      ideal K=phi(J)+BO[1];
+      ideal stTK=std(K);
+
+      if(loca)
+      {
+         ideal M=phi(M)+BO[1];
+         ideal stTM=std(M);
+      }
+      for(j=1;j<=size(E);j++)
+      {
+         if(deg(E[j][1])>0)
+         {
+            stTK=sat(stTK,E[j])[1];
+         }
+         if(loca)
+         {
+            stTM=sat(stTM,E[j])[1];
+         }
+      }
+      ideal sL=slocusE(J);
+      if(loca){sL=sL+stTM;}
+      ideal sLstd=std(sL);
+      if(deg(sLstd[1])>0)
+      {
+         if(!loc)
+         {
+            "J is not smooth";i;
+            setring R;
+            return(0);
+         }
+         if(size(reduce(@p,std(radical(sLstd))))>0)
+         {
+            "J is not smooth";i;
+            setring R;
+            return(0);
+         }
+      }
+      if(!((size(reduce(J,std(stTK)))==0)
+           &&(size(reduce(stTK,std(J)))==0)))
+      {
+         "map is wrong";i;
+         setring R;
+         return(0);
+      }
+      if(loc){tr=transversalT(J,E, at p);}
+      else{tr=transversalT(J,E);}
+      if(!tr)
+      {
+         "E not transversal with J";i;
+         setring R;
+         return(0);
+      }
+      if(!normalCross(E))
+      {
+         "E not normal crossings";i;
+         setring R;
+         return(0);
+      }
+      for(j=1;j<=size(E);j++)
+      {
+         if(deg(E[j][1])>0){E[j]=E[j]+J;}
+      }
+      if(!normalCross(E))
+      {
+         "E not normal crossings with J";i;
+         setring R;
+         return(0);
+      }
+      kill J,E,phi,K,stTK;
+      if(loca){kill M,stTM;}
+      setring R;
+      kill Q;
+   }
+   return(1);
+}
+//////////////////////////////////////////////////////////////////////////////
+static proc testBlowUp(list BO,ideal cent,list tmpList, int j, int extra)
+{
+   def R=basering;
+   int n=nvars(basering);
+   int i;
+   if((extra!=3)&&(extra!=2))
+   {
+      ideal K=BO[1],BO[2],cent;
+      for(i=1;i<=size(BO[4]);i++)
+      {
+        K=K,BO[4][i];
+      }
+      list N=findvars(K,0);
+      //list N=findvars(BO[2],0);
+      if(size(N[1])<n)
+      {
+         string newvar=string(N[1]);
+         execute("ring R1=("+charstr(R)+"),("+newvar+"),dp;");
+         list BO=imap(R,BO);
+         ideal cent=imap(R,cent);
+         n=nvars(R1);
+      }
+      else
+      {
+         def R1=basering;
+      }
+   }
+   else
+   {
+      def R1=basering;
+   }
+
+   i=0;
+   ideal T=cent;
+   ideal TW;
+   for(i=1;i<=size(tmpList);i++)
+   {
+      def Q=tmpList[i];
+      setring Q;
+      map phi=R1,lastMap;
+      ideal TE=radical(slocusE(BO[2]));
+      setring R1;
+      TW=preimage(Q,phi,TE);
+      T=intersect(T,TW);
+      kill Q;
+   }
+   ideal sL=intersect(slocusE(BO[2]),cent);
+   if(size(reduce(sL,std(radical(T))))>0){setring R;return(0);}
+   if(size(reduce(T,std(radical(sL))))>0){setring R;return(0);}
+   setring R;
+   return(1);
+}
+//////////////////////////////////////////////////////////////////////////////
+static proc normalCross(list E,list #)
+"Internal procedure - no help and no example available
+"
+{
+   int loc;
+   if((defined(locaT))&&(defined(@p)))
+   {
+      loc=1;
+      ideal pp=@p;
+   }
+   int i,d,j;
+   int n=nvars(basering);
+   list E1,E2;
+   ideal K,M,Estd,cent;
+   intvec v,w;
+   if(size(#)>0){cent=#[1];}
+
+   for(i=1;i<=size(E);i++)
+   {
+      Estd=std(E[i]);
+      if(deg(Estd[1])>0)
+      {
+         E1[size(E1)+1]=Estd;
+      }
+   }
+   E=E1;
+   for(i=1;i<=size(E);i++)
+   {
+      v=i;
+      E1[i]=list(E[i],v);
+   }
+   list ll;
+   int re=1;
+   int ok;
+   while(size(E1)>0)
+   {
+      K=E1[1][1];
+      v=E1[1][2];
+      attrib(K,"isSB",1);
+      E1=delete(E1,1);
+      d=n-dim(K);
+      M=minor(jacob(K),d)+K;
+      if(deg(std(M)[1])>0)
+      {
+         if(size(#)>0)
+         {
+            if(size(reduce(M,std(cent)))>0)
+            {
+               ll[size(ll)+1]=std(M);
+            }
+            else
+            {
+               ok=1;
+            }
+         }
+         if(!loc)
+         {
+            re=0;
+         }
+         else
+         {
+            if(size(reduce(pp,std(radical(M))))>0){re=0;}
+         }
+      }
+      for(i=1;i<=size(E);i++)
+      {
+         for(j=1;j<=size(v);j++){if(v[j]==i){break;}}
+         if(j<=size(v)){if(v[j]==i){i++;continue;}}
+         Estd=std(K+E[i]);
+         w=v;
+         if(deg(Estd[1])==0){i++;continue;}
+         if(d==n-dim(Estd))
+         {
+            if(size(#)>0)
+            {
+               if(size(reduce(Estd,std(cent)))>0)
+               {
+                  ll[size(ll)+1]=Estd;
+               }
+               else
+               {
+                  ok=1;
+               }
+            }
+            if(!loc)
+            {
+               re=0;
+            }
+            else
+            {
+               if(size(reduce(pp,std(radical(M))))>0){re=0;}
+            }
+         }
+         w[size(w)+1]=i;
+         E2[size(E2)+1]=list(Estd,w);
+      }
+      if(size(E2)>0)
+      {
+         if(size(E1)>0)
+         {
+            E1[size(E1)+1..size(E1)+size(E2)]=E2[1..size(E2)];
+         }
+         else
+         {
+            E1=E2;
+         }
+      }
+      kill E2;
+      list E2;
+   }
+/*
+   if((!ok)&&(!re)&&(size(#)==1))
+   {
+
+      "the center is wrong";
+      "it could be one of the following list";
+      ll;
+       ~;
+   }
+*/
+   if((!ok)&&(!re)&&(size(#)==2))
+   {
+      return(2);   //for Center correction
+   }
+   return(re);
+}
+//////////////////////////////////////////////////////////////////////////////
+static proc normalCrossB(ideal J,list E,ideal V)
+"Internal procedure - no help and no example available
+"
+{
+   int i,d,j;
+   int n=nvars(basering);
+   list E1,E2;
+   ideal K,M,Estd;
+   intvec v,w;
+
+   for(i=1;i<=size(E);i++)
+   {
+      Estd=std(E[i]+J);
+      if(deg(Estd[1])>0)
+      {
+         E1[size(E1)+1]=Estd;
+      }
+   }
+   E=E1;
+   for(i=1;i<=size(E);i++)
+   {
+      v=i;
+      E1[i]=list(E[i],v);
+   }
+   list ll;
+   int re=1;
+
+   while((size(E1)>0)&&(re==1))
+   {
+      K=E1[1][1];
+      v=E1[1][2];
+      attrib(K,"isSB",1);
+      E1=delete(E1,1);
+      d=n-dim(K);
+      M=minor(jacob(K),d)+K;
+      if(deg(std(M+V)[1])>0)
+      {
+         re=0;
+         break;
+      }
+      for(i=1;i<=size(E);i++)
+      {
+         for(j=1;j<=size(v);j++){if(v[j]==i){break;}}
+         if(j<=size(v)){if(v[j]==i){i++;continue;}}
+         Estd=std(K+E[i]);
+         w=v;
+         if(deg(Estd[1])==0){i++;continue;}
+         if(d==n-dim(Estd))
+         {
+            if(deg(std(Estd+V)[1])>0)
+            {
+               re=0;
+               break;
+            }
+         }
+         w[size(w)+1]=i;
+         E2[size(E2)+1]=list(Estd,w);
+      }
+      if(size(E2)>0)
+      {
+         if(size(E1)>0)
+         {
+            E1[size(E1)+1..size(E1)+size(E2)]=E2[1..size(E2)];
+         }
+         else
+         {
+            E1=E2;
+         }
+      }
+      kill E2;
+      list E2;
+   }
+   return(re);
+}
+//////////////////////////////////////////////////////////////////////////////
+static proc norC(list BO,ideal cent)
+"Internal procedure - no help and no example available
+"
+{
+   int j;
+   list  E=BO[4];
+   ideal N=BO[2];
+   if(BO[3][1]>1){return(0);}
+   if(deg(std(slocusE(BO[2]))[1])>0){return(0);}
+   if(!transversalT(N,E)){return(0);}
+   for(j=1;j<=size(E);j++){if(deg(E[j][1])>0){E[j]=E[j]+N;}}
+   if(!normalCross(E,cent)){return(0);}
+   return(1);
+}
+//////////////////////////////////////////////////////////////////////////////
+static proc specialReduce(ideal I,ideal J,poly p)
+{
+   matrix M;
+   int i,j;
+   for(i=1;i<=ncols(I);i++)
+   {
+      M=coeffs(I[i], at z);
+      I[i]=0;
+      for(j=1;j<=nrows(M);j++)
+      {
+         I[i]=I[i]+M[j,1]*p^(nrows(M)-j);
+      }
+      I[i]=reduce(I[i],J);
+   }
+   return(I);
+}
diff --git a/Singular/LIB/resources.lib b/Singular/LIB/resources.lib
new file mode 100644
index 0000000..ea08d27
--- /dev/null
+++ b/Singular/LIB/resources.lib
@@ -0,0 +1,161 @@
+////////////////////////////////////////////////////////////////////
+version="version resources.lib 4.0.0.0 Dec_2013 "; // $Id: 73b112cd1cdb048475ed47444e26850ac5c1154e $
+category="General purpose";
+info="
+LIBRARY:   resources.lib  Tools to manage the computational resources
+
+AUTHOR:    Andreas Steenpass, e-mail: steenpass at mathematik.uni-kl.de
+
+OVERVIEW:
+The purpose of this library is to manage the computational resources of
+a Singular session. The library tasks.lib and any library build upon tasks.lib
+respect these settings, i.e. they will not use more computational resources
+than provided via resources.lib.
+
+The provided procedures and their implementation are currently quite simple.
+The library can be extended later on to support, e.g., distributed computations
+on several servers.
+
+KEYWORDS:  parallelization; distributed computing; semaphores
+
+SEE ALSO:  tasks_lib, parallel_lib
+
+PROCEDURES:
+  addcores();  add an integer to the number of available processor cores
+  setcores();  set the number of available processor cores
+  getcores();  get the number of available processor cores
+  semaphore(); initialize a new semaphore
+";
+
+/* initialize (lib-)global variables */
+static proc mod_init()
+{
+    int sem_cores = semaphore(system("--cpus")-1);
+    exportto(Resources, sem_cores);
+    int NCORES = system("semaphore", "get_value", sem_cores)+1;
+    exportto(Resources, NCORES);
+}
+
+proc addcores(int n)
+"USAGE:   addcores(n), n int
+RETURN:   the adjusted number of available processor cores, after n has been
+          added to it. If n is negative, this number is reduced.
+NOTE:     The number of available processor cores must be at least 1. Reducing
+          this number may take some time.
+       @* This procedure should only be called in the main process of a
+          Singular session and not within any task defined via tasks.lib.
+SEE ALSO: setcores, getcores, tasks_lib, parallel_lib
+EXAMPLE:  example addcores; shows an example"
+{
+    /* check for errors */
+    if (NCORES+n < 1) {
+        ERROR("The number of cores to use must be at least 1.");
+    }
+
+    /* change the value of the semaphore */
+    int i;
+    int tmp;
+    if (n >= 0) {
+        for (i = n; i > 0; i--) {
+            tmp = system("semaphore", "release", sem_cores);
+        }
+    }
+    else {
+        for (i = n; i < 0; i++) {
+            tmp = system("semaphore", "acquire", sem_cores);
+        }
+    }
+
+    /* adjust and return NCORES */
+    NCORES = NCORES+n;
+    return(NCORES);
+}
+example
+{
+    "EXAMPLE:";
+    echo = 2;
+    setcores(4);
+    addcores(-2);
+}
+
+proc setcores(int n)
+"USAGE:   setcores(n), n int
+RETURN:   n. The number of available processor cores is set to n and n is
+          returned.
+NOTE:     The number of available processor cores must be at least 1. Reducing
+          this number may take some time.
+       @* This procedure should only be called in the main process of a
+          Singular session and not within any task defined via tasks.lib.
+SEE ALSO: addcores, getcores, tasks_lib, parallel_lib
+EXAMPLE:  example setcores; shows an example"
+{
+    return(addcores(n-NCORES));
+}
+example
+{
+    "EXAMPLE:";
+    echo = 2;
+    setcores(2);
+    setcores(4);
+}
+
+proc getcores()
+"USAGE:   getcores(n), n int
+RETURN:   the number of available processor cores.
+NOTE:     This procedure should only be called in the main process of
+          a Singular session and not within any task defined via tasks.lib.
+SEE ALSO: addcores, setcores, tasks_lib, parallel_lib
+EXAMPLE:  example getcores; shows an example"
+{
+    return(NCORES);
+}
+example
+{
+    "EXAMPLE:";
+    echo = 2;
+    setcores(4);
+    getcores();
+}
+
+proc semaphore(int n)
+"USAGE:   semaphore(n), n int
+RETURN:   the index of a new semaphore initialized with n.
+EXAMPLE:  example semaphore; shows an example"
+{
+    int i = 0;
+    while (system("semaphore", "exists", i) == 1) {
+        i++;
+    }
+    if (system("semaphore", "init", i, n) != 1) {
+        ERROR("no more semphores");
+    }
+    return(i);
+}
+example
+{
+    "EXAMPLE:";
+    echo = 2;
+    int sem = semaphore(1);
+    system("semaphore", "acquire", sem);
+    system("semaphore", "try_acquire", sem);
+    system("semaphore", "release", sem);
+    system("semaphore", "try_acquire", sem);
+}
+
+/* wrapper for the now obsolete optional parameter in parallel.lib for the
+ * number of processor cores
+ */
+static proc setcores_subtree(int n)
+{
+    list oldvalues = list(sem_cores, NCORES);
+    sem_cores = semaphore(n-1);
+    NCORES = n;
+    return(oldvalues);
+}
+
+static proc resetcores_subtree(list oldvalues)
+{
+    sem_cores = oldvalues[1];
+    NCORES = oldvalues[2];
+}
+
diff --git a/Singular/LIB/reszeta.lib b/Singular/LIB/reszeta.lib
new file mode 100644
index 0000000..a122668
--- /dev/null
+++ b/Singular/LIB/reszeta.lib
@@ -0,0 +1,5479 @@
+///////////////////////////////////////////////////////////////////////////
+version="version reszeta.lib 4.0.0.0 Jun_2013 "; // $Id: 4fa1ee9bbf9e435950ec200786e7b7272e5dfccb $
+category="Algebraic Geometry";
+info="
+LIBRARY:  reszeta.lib       topological Zeta-function and
+                            some other applications of desingularization
+
+AUTHORS:  A. Fruehbis-Krueger,  anne at mathematik.uni-kl.de,
+@*        G. Pfister,           pfister at mathematik.uni-kl.de
+
+REFERENCES:
+[1] Fruehbis-Krueger,A., Pfister,G.: Some Applications of Resolution of
+@*  Singularities from a Practical Point of View, in Computational
+@*  Commutative and Non-commutative Algebraic Geometry,
+@*  NATO Science Series III, Computer and Systems Sciences 196, 104-117 (2005)
+[2] Fruehbis-Krueger: An Application of Resolution of Singularities:
+@*  Computing the topological Zeta-function of isolated surface singularities
+@*  in (C^3,0),  in D.Cheniot, N.Dutertre et al.(Editors): Singularity Theory, @*  World Scientific Publishing (2007)
+
+PROCEDURES:
+intersectionDiv(L)   computes intersection form and genera of exceptional
+                     divisors (isolated singularities of surfaces)
+spectralNeg(L)       computes negative spectral numbers
+                     (isolated hypersurface singularity)
+discrepancy(L)       computes discrepancy of given resolution
+zetaDL(L,d)          computes Denef-Loeser zeta function
+                     (hypersurface singularity of dimension 2)
+collectDiv(L[,iv])   identify exceptional divisors in different charts
+                     (embedded and non-embedded case)
+prepEmbDiv(L[,b])    prepare list of divisors (including components
+                     of strict transform, embedded case)
+abstractR(L)         pass from embedded to non-embedded resolution
+computeV(re,DL)      multiplicities of divisors in pullback of volume form
+computeN(re,DL)      multiplicities of divisors in total transform of resolution
+";
+LIB "resolve.lib";
+LIB "solve.lib";
+LIB "normal.lib";
+///////////////////////////////////////////////////////////////////////////////
+static proc spectral1(poly h,list re, list DL,intvec v, intvec n)
+"Internal procedure - no help and no example available
+"
+{
+//--- compute one spectral number
+//--- DL is output of prepEmbDiv
+   int i;
+   intvec w=computeH(h,re,DL);
+   number gw=number(w[1]+v[1])/number(n[1]);
+   for(i=2;i<=size(v);i++)
+   {
+      if(gw>number(w[i]+v[i])/number(n[i]))
+      {
+         gw=number(w[i]+v[i])/number(n[i]);
+      }
+   }
+   return(gw-1);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc spectralNeg(list re,list #)
+"USAGE:   spectralNeg(L);
+@*        L = list of rings
+ASSUME:   L is output of resolution of singularities
+RETURN:   list of numbers, each a spectral number in (-1,0]
+EXAMPLE:  example spectralNeg;  shows an example
+"
+{
+//-----------------------------------------------------------------------------
+// Initialization and Sanity Checks
+//-----------------------------------------------------------------------------
+   int i,j,l;
+   number bound;
+   list resu;
+   if(size(#)>0)
+   {
+//--- undocumented feature:
+//--- if # is not empty it computes numbers up to this bound,
+//--- not necessarily spectral numbers
+      bound=number(#[1]);
+   }
+//--- get list of embedded divisors
+   list DL=prepEmbDiv(re,1);
+   int k=1;
+   ideal I,delI;
+   number g;
+   int m=nvars(basering);
+//--- prepare the multiplicities of exceptional divisors N and nu
+   intvec v=computeV(re,DL);        // nu
+   intvec n=computeN(re,DL);        // N
+//---------------------------------------------------------------------------
+// start computation, first case separately, then loop
+//---------------------------------------------------------------------------
+   resu[1]=spectral1(1,re,DL,v,n);  // first number, corresponding to
+                                    // volume form itself
+   if(resu[1]>=bound)
+   {
+//--- exceeds bound ==> not a spectral number
+      resu=delete(resu,1);
+      return(resu);
+   }
+   delI=std(ideal(0));
+   while(k)
+   {
+//--- now run through all monomial x volume form, degree by degree
+      j++;
+      k=0;
+      I=maxideal(j);
+      I=reduce(I,delI);
+      for(i=1;i<=size(I);i++)
+      {
+//--- all monomials in degree j
+         g=spectral1(I[i],re,DL,v,n);
+         if(g<bound)
+         {
+//--- otherwise g exceeds bound ==> not a spectral number
+            k=1;
+            l=1;
+            while(resu[l]<g)
+            {
+               l++;
+               if(l==size(resu)+1){break;}
+            }
+            if(l==size(resu)+1){resu[size(resu)+1]=g;}
+            if(resu[l]!=g){resu=insert(resu,g,l-1);}
+         }
+         else
+         {
+            delI[size(delI)+1]=I[i];
+         }
+      }
+      attrib(delI,"isSB",1);
+   }
+   return(resu);
+}
+example
+{"EXAMPLE:";
+   echo = 2;
+   ring R=0,(x,y,z),dp;
+   ideal I=x3+y4+z5;
+   list L=resolve(I,"K");
+   spectralNeg(L);
+   LIB"gmssing.lib";
+   ring r=0,(x,y,z),ds;
+   poly f=x3+y4+z5;
+   spectrum(f);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static proc ordE(ideal J,ideal E,ideal W)
+"Internal procedure - no help and no example available
+"
+{
+//--- compute multiplicity of E in J -- embedded in W
+   int s;
+   if(size(J)==0){~;ERROR("ordE: J=0");}
+   ideal Estd=std(E+W);
+   ideal Epow=1;
+   ideal Jquot=1;
+   while(size(reduce(Jquot,Estd))!=0)
+   {
+      s++;
+      Epow=Epow*E;
+      Jquot=quotient(Epow+W,J);
+   }
+   return(s-1);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+proc computeV(list re, list DL)
+"USAGE:   computeV(L,DL);
+           L = list of rings
+          DL = divisor list
+ASSUME:   L has structure of output of resolve
+          DL has structure of output of prepEmbDiv
+RETURN:   intvec,
+          i-th entry is multiplicity of i-th divisor in
+          pullback of volume form
+EXAMPLE:  example computeV;  shows an example
+"
+{
+//--- computes for every divisor E_i its multiplicity + 1 in pi^*(w)
+//--- w a non-vanishing 1-form
+//--- note: DL is output of prepEmbDiv
+
+//-----------------------------------------------------------------------------
+// Initialization
+//-----------------------------------------------------------------------------
+   def R=basering;
+   int i,j,k,n;
+   intvec v,w;
+   list iden=DL;
+   v[size(iden)]=0;
+
+//----------------------------------------------------------------------------
+// Run through all exceptional divisors
+//----------------------------------------------------------------------------
+   for(k=1;k<=size(iden);k++)
+   {
+      for(i=1;i<=size(iden[k]);i++)
+      {
+         if(defined(S)){kill S;}
+         def S=re[2][iden[k][i][1]];
+         setring S;
+         if((!v[k])&&(defined(EList)))
+         {
+            if(defined(II)){kill II;}
+//--- we might be embedded in a non-trivial BO[1]
+//--- take this into account when forming the jacobi-determinant
+            ideal II=jacobDet(BO[5],BO[1]);
+            if(size(II)!=0)
+            {
+                v[k]=ordE(II,EList[iden[k][i][2]],BO[1])+1;
+            }
+         }
+         setring R;
+      }
+   }
+   return(v);
+}
+example
+{"EXAMPLE:"; echo = 2;
+  ring R=0,(x,y,z),dp;
+  ideal I=(x-y)*(x-z)*(y-z)-z4;
+  list re=resolve(I,1);
+  list iden=prepEmbDiv(re);
+  intvec v=computeV(re, iden);
+  v;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static proc jacobDet(ideal I, ideal J)
+"Internal procedure - no help and no example available
+"
+{
+//--- Returns the Jacobian determinant of the morphism
+//--- K[x_1,...,x_m]--->K[y_1,...,y_n]/J defined by x_i ---> I_i.
+//--- Let basering=K[y_1,...,y_n], l=n-dim(basering/J),
+//--- I=<I_1,...,I_m>, J=<J_1,...,J_r>
+//--- For each subset v in {1,...,n} of l elements and
+//--- w in {1,...,r} of l elements
+//--- let K_v,w be the ideal generated by the n-l-minors of the matrix
+//--- (diff(I_i,y_j)+
+//---  \sum_k diff(I_i,y_v[k])*diff(J_w[k],y_j))_{j not in v  multiplied with
+//---                                 the determinant of (diff(J_w[i],y_v[j]))
+//--- the sum of all such ideals K_v,w plus J is returned.
+
+//----------------------------------------------------------------------------
+// Initialization
+//----------------------------------------------------------------------------
+   int n=nvars(basering);
+   int i,j,k;
+   intvec u,v,w,x;
+   matrix MI[ncols(I)][n]=jacob(I);
+   matrix N=unitmat(n);
+   matrix L;
+   ideal K=J;
+   if(size(J)==0)
+   {
+      K=minor(MI,n);
+   }
+
+//---------------------------------------------------------------------------
+// Do calculation as described above.
+// separately for case size(J)=1
+//---------------------------------------------------------------------------
+   if(size(J)==1)
+   {
+      matrix MJ[ncols(J)][n]=jacob(J);
+      N=concat(N,transpose(MJ));
+      v=1..n;
+      for(i=1;i<=n;i++)
+      {
+         L=transpose(permcol(N,i,n+1));
+         if(i==1){w=2..n;}
+         if(i==n){w=1..n-1;}
+         if((i!=1)&&(i!=n)){w=1..i-1,i+1..n;}
+         L=submat(L,v,w);
+         L=MI*L;
+         K=K+minor(L,n-1)*MJ[1,i];
+      }
+   }
+   if(size(J)>1)
+   {
+      matrix MJ[ncols(J)][n]=jacob(J);
+      matrix SMJ;
+      N=concat(N,transpose(MJ));
+      ideal Jstd=std(J);
+      int l=n-dim(Jstd);
+      int r=ncols(J);
+      list L1=indexSet(n,l);
+      list L2=indexSet(r,l);
+      for(i=1;i<=size(L1);i++)
+      {
+         for(j=1;j<=size(L2);j++)
+         {
+            for(k=1;k<=size(L1[i]);k++)
+            {
+               if(L1[i][k]){v[size(v)+1]=k;}
+            }
+            v=v[2..size(v)];
+            for(k=1;k<=size(L2[j]);k++)
+            {
+               if(L2[j][k]){w[size(w)+1]=k;}
+            }
+            w=w[2..size(w)];
+            SMJ=submat(MJ,w,v);
+            L=N;
+            for(k=1;k<=l;k++)
+            {
+               L=permcol(L,v[k],n+w[k]);
+            }
+            u=1..n;
+            x=1..n;
+            v=sort(v)[1];
+            for(k=l;k>=1;k--)
+            {
+               if(v[k])
+               {
+                  u=deleteInt(u,v[k],1);
+               }
+            }
+            L=transpose(submat(L,u,x));
+            L=MI*L;
+            K=K+minor(L,n-l)*det(SMJ);
+         }
+      }
+   }
+   return(K);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static proc computeH(ideal h,list re,list DL)
+"Internal procedure - no help and no example available
+"
+{
+//--- additional procedure to computeV, allows
+//--- computation for polynomial x volume form
+//--- by computing the contribution of the polynomial h
+//--- Note: DL is output of prepEmbDiv
+
+//----------------------------------------------------------------------------
+// Initialization
+//----------------------------------------------------------------------------
+   def R=basering;
+   ideal II=h;
+   list iden=DL;
+   def T=re[2][1];
+   setring T;
+   int i,k;
+   intvec v;
+   v[size(iden)]=0;
+   if(deg(II[1])==0){return(v);}
+//----------------------------------------------------------------------------
+// Run through all exceptional divisors
+//----------------------------------------------------------------------------
+   for(k=1;k<=size(iden);k++)
+   {
+      for(i=1;i<=size(iden[k]);i++)
+      {
+         if(defined(S)){kill S;}
+         def S=re[2][iden[k][i][1]];
+         setring S;
+         if((!v[k])&&(defined(EList)))
+         {
+            if(defined(JJ)){kill JJ;}
+            if(defined(phi)){kill phi;}
+            map phi=T,BO[5];
+            ideal JJ=phi(II);
+            if(size(JJ)!=0)
+            {
+               v[k]=ordE(JJ,EList[iden[k][i][2]],BO[1]);
+            }
+         }
+         setring R;
+      }
+   }
+   return(v);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+proc computeN(list re,list DL)
+"USAGE:   computeN(L,DL);
+          L = list of rings
+          DL = divisor list
+ASSUME:   L has structure of output of resolve
+          DL has structure of output of prepEmbDiv
+RETURN:   intvec, i-th entry is multiplicity of i-th divisor
+          in total transform under resolution
+EXAMPLE:  example computeN;
+"
+{
+//--- computes for every (Q-irred.) divisor E_i its multiplicity in f \circ pi
+//--- DL is output of prepEmbDiv
+
+//----------------------------------------------------------------------------
+// Initialization
+//----------------------------------------------------------------------------
+   def R=basering;
+   list iden=DL;
+   def T=re[2][1];
+   setring T;
+   ideal J=BO[2];
+   int i,k;
+   intvec v;
+   v[size(iden)]=0;
+//----------------------------------------------------------------------------
+// Run through all exceptional divisors
+//----------------------------------------------------------------------------
+   for(k=1;k<=size(iden);k++)
+   {
+      for(i=1;i<=size(iden[k]);i++)
+      {
+         if(defined(S)){kill S;}
+         def S=re[2][iden[k][i][1]];
+         setring S;
+         if((!v[k])&&(defined(EList)))
+         {
+            if(defined(II)){kill II;}
+            if(defined(phi)){kill phi;}
+            map phi=T,BO[5];
+            ideal II=phi(J);
+            if(size(II)!=0)
+            {
+               v[k]=ordE(II,EList[iden[k][i][2]],BO[1]);
+            }
+         }
+         setring R;
+      }
+   }
+   return(v);
+}
+example
+{"EXAMPLE:";
+   echo = 2;
+   ring R=0,(x,y,z),dp;
+   ideal I=(x-y)*(x-z)*(y-z)-z4;
+   list re=resolve(I,1);
+   list iden=prepEmbDiv(re);
+   intvec v=computeN(re,iden);
+   v;
+}
+//////////////////////////////////////////////////////////////////////////////
+static proc countEijk(list re,list iden,intvec iv,list #)
+"Internal procedure - no help and no example available
+"
+{
+//--- count the number of points in the intersection of 3 exceptional
+//--- hyperplanes (of dimension 2) - one of them is allowed to be a component
+//--- of the strict transform
+
+//----------------------------------------------------------------------------
+// Initialization
+//----------------------------------------------------------------------------
+   int i,j,k,comPa,numPts,localCase;
+   intvec ituple,jtuple,ktuple;
+   list chList,tmpList;
+   def R=basering;
+   if(size(#)>0)
+   {
+      if(string(#[1])=="local")
+      {
+         localCase=1;
+      }
+   }
+//----------------------------------------------------------------------------
+// Find common charts
+//----------------------------------------------------------------------------
+   for(i=1;i<=size(iden[iv[1]]);i++)
+   {
+//--- find common charts - only for final charts
+      if(defined(S)) {kill S;}
+      def S=re[2][iden[iv[1]][i][1]];
+      setring S;
+      if(!defined(EList))
+      {
+        i++;
+        setring R;
+        continue;
+      }
+      setring R;
+      kill ituple,jtuple,ktuple;
+      intvec ituple=iden[iv[1]][i];
+      intvec jtuple=findInIVList(1,ituple[1],iden[iv[2]]);
+      intvec ktuple=findInIVList(1,ituple[1],iden[iv[3]]);
+      if((size(jtuple)!=1)&&(size(ktuple)!=1))
+      {
+//--- chList contains all information about the common charts,
+//--- each entry represents a chart and contains three intvecs from iden
+//--- one for each E_l
+        kill tmpList;
+        list tmpList=ituple,jtuple,ktuple;
+        chList[size(chList)+1]=tmpList;
+        i++;
+        if(i<=size(iden[iv[1]]))
+        {
+           continue;
+        }
+        else
+        {
+           break;
+        }
+      }
+   }
+   if(size(chList)==0)
+   {
+//--- no common chart !!!
+     return(int(0));
+   }
+//----------------------------------------------------------------------------
+// Count points in common charts
+//----------------------------------------------------------------------------
+   for(i=1;i<=size(chList);i++)
+   {
+//--- run through all common charts
+      if(defined(S)) { kill S;}
+      def S=re[2][chList[i][1][1]];
+      setring S;
+//--- intersection in this chart
+      if(defined(interId)){kill interId;}
+      if(localCase==1)
+      {
+//--- in this case we need to intersect with \pi^-1(0)
+         ideal interId=EList[chList[i][1][2]]+EList[chList[i][2][2]]
+                                          +EList[chList[i][3][2]]+BO[5];
+      }
+      else
+      {
+         ideal interId=EList[chList[i][1][2]]+EList[chList[i][2][2]]
+                                          +EList[chList[i][3][2]];
+      }
+      interId=std(interId);
+      if(defined(otherId)) {kill otherId;}
+      ideal otherId=1;
+      for(j=1;j<i;j++)
+      {
+//--- run through the previously computed ones
+        if(defined(opath)){kill opath;}
+        def opath=imap(re[2][chList[j][1][1]],path);
+        comPa=1;
+        while(opath[1,comPa]==path[1,comPa])
+        {
+           comPa++;
+           if((comPa>ncols(path))||(comPa>ncols(opath))) break;
+        }
+        comPa=int(leadcoef(path[1,comPa-1]));
+        otherId=otherId+interId;
+        otherId=intersect(otherId,
+                     fetchInTree(re,chList[j][1][1],
+                                 comPa,chList[i][1][1],"interId",iden));
+      }
+      otherId=std(otherId);
+//--- do not count each point more than once
+      interId=sat(interId,otherId)[1];
+      export(interId);
+      if(dim(interId)>0)
+      {
+         ERROR("CountEijk: intersection not zerodimensional");
+      }
+//--- add the remaining number of points to the total point count numPts
+      numPts=numPts+vdim(interId);
+   }
+   return(numPts);
+}
+//////////////////////////////////////////////////////////////////////////////
+static proc chiEij(list re, list iden, intvec iv)
+"Internal procedure - no help and no example available
+"
+{
+//!!! Copy of chiEij_local adjusted for non-local case
+//!!! changes must be made in both copies
+
+//--- compute the Euler characteristic of the intersection
+//--- curve of two exceptional hypersurfaces (of dimension 2)
+//--- one of which is allowed to be a component of the strict transform
+//--- using the formula chi(Eij)=2-2g(Eij)
+
+//----------------------------------------------------------------------------
+// Initialization
+//----------------------------------------------------------------------------
+  int i,j,k,chi,g;
+  intvec ituple,jtuple,inters;
+  def R=basering;
+//----------------------------------------------------------------------------
+// Find a common chart in which they intersect
+//----------------------------------------------------------------------------
+  for(i=1;i<=size(iden[iv[1]]);i++)
+  {
+//--- find a common chart in which they intersect: only for final charts
+     if(defined(S)) {kill S;}
+     def S=re[2][iden[iv[1]][i][1]];
+     setring S;
+     if(!defined(EList))
+     {
+       i++;
+       setring R;
+       continue;
+     }
+     setring R;
+     kill ituple,jtuple;
+     intvec ituple=iden[iv[1]][i];
+     intvec jtuple=findInIVList(1,ituple[1],iden[iv[2]]);
+     if(size(jtuple)==1)
+     {
+       if(i<size(iden[iv[1]]))
+       {
+//--- not in this chart
+         i++;
+         continue;
+       }
+       else
+       {
+         if(size(inters)==1)
+         {
+//--- E_i and E_j do not meet at all
+            return("leer");
+         }
+         else
+         {
+            return(chi);
+         }
+       }
+     }
+//----------------------------------------------------------------------------
+// Run through common charts and compute the Euler characteristic of
+// each component of Eij.
+// As soon as a component has been treated in a chart, it will not be used in
+// any subsequent charts.
+//----------------------------------------------------------------------------
+     if(defined(S)) {kill S;}
+     def S=re[2][ituple[1]];
+     setring S;
+//--- interId: now all components in this chart,
+//---          but we want only new components
+     if(defined(interId)){kill interId;}
+     ideal interId=EList[ituple[2]]+EList[jtuple[2]];
+     interId=std(interId);
+//--- doneId: already considered components
+     if(defined(doneId)){kill doneId;}
+     ideal doneId=1;
+     for(j=2;j<=size(inters);j++)
+     {
+//--- fetch the components which have already been dealt with via fetchInTree
+        if(defined(opath)) {kill opath;}
+        def opath=imap(re[2][inters[j]],path);
+        k=1;
+        while((k<ncols(opath))&&(k<ncols(path)))
+        {
+           if(path[1,k+1]!=opath[1,k+1]) break;
+           k++;
+        }
+        if(defined(comPa)) {kill comPa;}
+        int comPa=int(leadcoef(path[1,k]));
+        if(defined(tempId)){kill tempId;}
+        ideal tempId=fetchInTree(re,inters[j],comPa,
+                                    iden[iv[1]][i][1],"interId",iden);
+        doneId=intersect(doneId,tempId);
+        kill tempId;
+     }
+//--- only consider new components in interId
+     interId=sat(interId,doneId)[1];
+     if(dim(interId)>1)
+     {
+       ERROR("genus_Eij: higher dimensional intersection");
+     }
+     if(dim(interId)>=0)
+     {
+//--- save the index of the current chart for future use
+        export(interId);
+        inters[size(inters)+1]=iden[iv[1]][i][1];
+     }
+     BO[1]=std(BO[1]);
+     if(((dim(interId)<=0)&&(dim(BO[1])>2))||
+        ((dim(interId)<0)&&(dim(BO[1])==2)))
+     {
+       if(i<size(iden[iv[1]]))
+       {
+//--- not in this chart
+         setring R;
+         i++;
+         continue;
+       }
+       else
+       {
+         if(size(inters)==1)
+         {
+//--- E_i and E_j do not meet at all
+            return("leer");
+         }
+         else
+         {
+            return(chi);
+         }
+       }
+     }
+     g=genus(interId);
+
+//--- chi is the Euler characteristic of the (disjoint !!!) union of the
+//--- considered components
+//--- remark: components are disjoint, because the E_i are normal crossing!!!
+
+     chi=chi+(2-2*g);
+  }
+  return(chi);
+}
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+static proc chiEij_local(list re, list iden, intvec iv)
+"Internal procedure - no help and no example available
+"
+{
+//!!! Copy of chiEij adjusted for local case
+//!!! changes must be made in both copies
+
+//--- we have to consider two different cases:
+//--- case1: E_i \cap E_j \cap \pi^-1(0) is a curve
+//---    compute the Euler characteristic of the intersection
+//---    curve of two exceptional hypersurfaces (of dimension 2)
+//---    one of which is allowed to be a component of the strict transform
+//---    using the formula chi(Eij)=2-2g(Eij)
+//--- case2: E_i \cap E_j \cap \pi^-1(0) is a set of points
+//---    count the points
+
+//----------------------------------------------------------------------------
+// Initialization
+//----------------------------------------------------------------------------
+  int i,j,k,chi,g,points;
+  intvec ituple,jtuple,inters;
+  def R=basering;
+//----------------------------------------------------------------------------
+// Find a common chart in which they intersect
+//----------------------------------------------------------------------------
+  for(i=1;i<=size(iden[iv[1]]);i++)
+  {
+//--- find a common chart in which they intersect: only for final charts
+     if(defined(S)) {kill S;}
+     def S=re[2][iden[iv[1]][i][1]];
+     setring S;
+     if(!defined(EList))
+     {
+       i++;
+       setring R;
+       continue;
+     }
+     setring R;
+     kill ituple,jtuple;
+     intvec ituple=iden[iv[1]][i];
+     intvec jtuple=findInIVList(1,ituple[1],iden[iv[2]]);
+     if(size(jtuple)==1)
+     {
+       if(i<size(iden[iv[1]]))
+       {
+//--- not in this chart
+         i++;
+         continue;
+       }
+       else
+       {
+         if(size(inters)==1)
+         {
+//--- E_i and E_j do not meet at all
+            return("leer");
+         }
+         else
+         {
+            return(chi);
+         }
+       }
+     }
+//----------------------------------------------------------------------------
+// Run through common charts and compute the Euler characteristic of
+// each component of Eij.
+// As soon as a component has been treated in a chart, it will not be used in
+// any subsequent charts.
+//----------------------------------------------------------------------------
+     if(defined(S)) {kill S;}
+     def S=re[2][ituple[1]];
+     setring S;
+//--- interId: now all components in this chart,
+//---          but we want only new components
+     if(defined(interId)){kill interId;}
+     ideal interId=EList[ituple[2]]+EList[jtuple[2]]+BO[5];
+     interId=std(interId);
+//--- doneId: already considered components
+     if(defined(doneId)){kill doneId;}
+     ideal doneId=1;
+     for(j=2;j<=size(inters);j++)
+     {
+//--- fetch the components which have already been dealt with via fetchInTree
+        if(defined(opath)) {kill opath;}
+        def opath=imap(re[2][inters[j]],path);
+        k=1;
+        while((k<ncols(opath))&&(k<ncols(path)))
+        {
+           if(path[1,k+1]!=opath[1,k+1]) break;
+           k++;
+        }
+        if(defined(comPa)) {kill comPa;}
+        int comPa=int(leadcoef(path[1,k]));
+        if(defined(tempId)){kill tempId;}
+        ideal tempId=fetchInTree(re,inters[j],comPa,
+                                    iden[iv[1]][i][1],"interId",iden);
+        doneId=intersect(doneId,tempId);
+        kill tempId;
+     }
+//--- only consider new components in interId
+     interId=sat(interId,doneId)[1];
+     if(dim(interId)>1)
+     {
+       ERROR("genus_Eij: higher dimensional intersection");
+     }
+     if(dim(interId)>=0)
+     {
+//--- save the index of the current chart for future use
+        export(interId);
+        inters[size(inters)+1]=iden[iv[1]][i][1];
+     }
+     BO[1]=std(BO[1]);
+     if(dim(interId)<0)
+     {
+       if(i<size(iden[iv[1]]))
+       {
+//--- not in this chart
+         setring R;
+         i++;
+         continue;
+       }
+       else
+       {
+         if(size(inters)==1)
+         {
+//--- E_i and E_j do not meet at all
+            return("leer");
+         }
+         else
+         {
+            return(chi);
+         }
+       }
+     }
+     if((dim(interId)==0)&&(dim(std(BO[1]))>2))
+     {
+//--- for sets of points the Euler characteristic is just
+//--- the number of points
+//--- fat points are impossible, since everything is smooth and n.c.
+        chi=chi+vdim(interId);
+        points=1;
+     }
+     else
+     {
+        if(points==1)
+        {
+           ERROR("components of intersection do not have same dimension");
+        }
+        g=genus(interId);
+//--- chi is the Euler characteristic of the (disjoint !!!) union of the
+//--- considered components
+//--- remark: components are disjoint, because the E_i are normal crossing!!!
+        chi=chi+(2-2*g);
+     }
+  }
+  return(chi);
+}
+//////////////////////////////////////////////////////////////////////////////
+static proc computeChiE(list re, list iden)
+"Internal procedure - no help and no example available
+"
+{
+//--- compute the Euler characteristic of the exceptional hypersurfaces
+//--- (of dimension 2), not considering the components of the strict
+//--- transform
+
+//----------------------------------------------------------------------------
+// Initialization
+//----------------------------------------------------------------------------
+   int i,j,k,m,thisE,otherE;
+   def R=basering;
+   intvec nulliv,chi_temp,kvec;
+   nulliv[size(iden)]=0;
+   list chi_E;
+   for(i=1;i<=size(iden);i++)
+   {
+      chi_E[i]=list();
+   }
+//---------------------------------------------------------------------------
+// Run through the list of charts and compute the Euler characteristic of
+// the new exceptional hypersurface and change the values for the old ones
+// according to the blow-up which has just been performed
+// For initialization reasons, treat the case of the first blow-up separately
+//---------------------------------------------------------------------------
+   for(i=2;i<=size(re[2]);i++)
+   {
+//--- run through all charts
+      if(defined(S)){kill S;}
+      def S=re[2][i];
+      setring S;
+      m=int(leadcoef(path[1,ncols(path)]));
+      if(defined(Spa)){kill Spa;}
+      def Spa=re[2][m];
+      if(size(BO[4])==1)
+      {
+//--- just one exceptional divisor
+         thisE=1;
+         setring Spa;
+         if(i==2)
+         {
+//--- have not set the initial value of chi(E_1) yet
+           if(dim(std(cent))==0)
+           {
+//--- center was point ==> new except. div. is a P^2
+              list templist=3*vdim(std(BO[1]+cent)),nulliv;
+           }
+           else
+           {
+//--- center was curve ==> new except. div. is curve x P^1
+              list templist=4-4*genus(BO[1]+cent),nulliv;
+           }
+           chi_E[1]=templist;
+           kill templist;
+         }
+         setring S;
+         i++;
+         if(i<size(re[2]))
+         {
+            continue;
+         }
+         else
+         {
+            break;
+         }
+      }
+      for(j=1;j<=size(iden);j++)
+      {
+//--- find out which exceptional divisor has just been born
+        if(inIVList(intvec(i,size(BO[4])),iden[j]))
+        {
+//--- found it
+           thisE=j;
+           break;
+        }
+      }
+//--- now setup new chi and change the previous ones appropriately
+      setring Spa;
+      if(size(chi_E[thisE])==0)
+      {
+//--- have not set the initial value of chi(E_thisE) yet
+        if(dim(std(cent))==0)
+        {
+//--- center was point  ==> new except. div. is a P^2
+           list templist=3*vdim(std(BO[1]+cent)),nulliv;
+        }
+        else
+        {
+//--- center was curve   ==> new except. div. is a C x P^1
+           list templist=4-4*genus(BO[1]+cent),nulliv;
+        }
+        chi_E[thisE]=templist;
+        kill templist;
+      }
+      for(j=1;j<=size(BO[4]);j++)
+      {
+//--- we are in the parent ring ==> thisE is not yet born
+//--- all the other E_i have already been initialized, but the chi
+//--- might change with the current blow-up at cent
+         if(BO[6][j]==1)
+         {
+//--- ignore empty sets
+            j++;
+            if(j<=size(BO[4]))
+            {
+              continue;
+            }
+            else
+            {
+              break;
+            }
+         }
+         for(k=1;k<=size(iden);k++)
+         {
+//--- find global index of BO[4][j]
+            if(inIVList(intvec(m,j),iden[k]))
+            {
+               otherE=k;
+               break;
+            }
+         }
+         if(chi_E[otherE][2][thisE]==1)
+         {
+//--- already considered this one
+            j++;
+            if(j<=size(BO[4]))
+            {
+              continue;
+            }
+            else
+            {
+              break;
+            }
+         }
+//---------------------------------------------------------------------------
+// update chi according to the formula
+// chi(E_k^transf)=chi(E_k) - chi(C \cap E_k) + chi(E_k \cap E_new)
+// for convenience of implementation, we first compute
+//        chi(E_k) - chi(C \cap E_k)
+// and afterwards add the last term chi(E_k \cap E_new)
+//---------------------------------------------------------------------------
+         ideal CinE=std(cent+BO[4][j]+BO[1]);  // this is C \cap E_k
+         if(dim(CinE)==1)
+         {
+//--- center meets E_k in a curve
+            chi_temp[otherE]=chi_E[otherE][1]-(2-2*genus(CinE));
+         }
+         if(dim(CinE)==0)
+         {
+//--- center meets E_k in points
+            chi_temp[otherE]=chi_E[otherE][1]-vdim(std(CinE));
+         }
+         kill CinE;
+         setring S;
+//--- now we are back in the i-th ring in the list
+         ideal CinE=std(BO[4][j]+BO[4][size(BO[4])]+BO[1]);
+                                              // this is E_k \cap E_new
+         if(dim(CinE)==1)
+         {
+//--- if the two divisors meet, they meet in a curve
+            chi_E[otherE][1]=chi_temp[otherE]+(2-2*genus(CinE));
+            chi_E[otherE][2][thisE]=1;         // this blow-up of E_k is done
+         }
+         kill CinE;
+         setring Spa;
+      }
+   }
+   setring R;
+   return(chi_E);
+}
+//////////////////////////////////////////////////////////////////////////////
+static proc computeChiE_local(list re, list iden)
+"Internal procedure - no help and no example available
+"
+{
+//--- compute the Euler characteristic of the intersection of the
+//--- exceptional hypersurfaces with \pi^-1(0) which can be of
+//--- dimension 1 or 2 - not considering the components of the strict
+//--- transform
+
+//----------------------------------------------------------------------------
+// Initialization
+//----------------------------------------------------------------------------
+   int i,j,k,aa,m,n,thisE,otherE;
+   def R=basering;
+   intvec nulliv,chi_temp,kvec,dimEi,endiv;
+   nulliv[size(iden)]=0;
+   dimEi[size(iden)]=0;
+   endiv[size(re[2])]=0;
+   list chi_E;
+   for(i=1;i<=size(iden);i++)
+   {
+      chi_E[i]=list();
+   }
+//---------------------------------------------------------------------------
+// Run through the list of charts and compute the Euler characteristic of
+// the new exceptional hypersurface and change the values for the old ones
+// according to the blow-up which has just been performed
+// For initialization reasons, treat the case of the first blow-up separately
+//---------------------------------------------------------------------------
+   for(i=2;i<=size(re[2]);i++)
+   {
+//--- run through all charts
+      if(defined(S)){kill S;}
+      def S=re[2][i];
+      setring S;
+      if(defined(EList))
+      {
+         endiv[i]=1;
+      }
+      m=int(leadcoef(path[1,ncols(path)]));
+      if(defined(Spa)){kill Spa;}
+      def Spa=re[2][m];
+      if(size(BO[4])==1)
+      {
+//--- just one exceptional divisor
+         thisE=1;
+         setring Spa;
+         if(i==2)
+         {
+//--- have not set the initial value of chi(E_1) yet
+//--- in the local case, we need to know whether the center contains 0
+           if(size(reduce(cent,std(maxideal(1))))!=0)
+           {
+//--- first center does not meet 0
+              list templist=0,nulliv;
+              dimEi[1]=-1;
+           }
+           else
+           {
+              if(dim(std(cent))==0)
+              {
+//--- center was point ==> new except. div. is a P^2
+                 list templist=3*vdim(std(BO[1]+cent)),nulliv;
+                 dimEi[1]=2;
+              }
+              else
+              {
+//--- center was curve ==> intersection of new exceptional divisor
+//---                      with \pi^-1(0) is a curve, namely P^1
+                 setring S;
+                 list templist=2,nulliv;
+                 dimEi[1]=1;
+              }
+           }
+           chi_E[1]=templist;
+           kill templist;
+         }
+         setring S;
+         i++;
+         if(i<size(re[2]))
+         {
+            continue;
+         }
+         else
+         {
+            break;
+         }
+      }
+      for(j=1;j<=size(iden);j++)
+      {
+//--- find out which exceptional divisor has just been born
+        if(inIVList(intvec(i,size(BO[4])),iden[j]))
+        {
+//--- found it
+           thisE=j;
+           break;
+        }
+      }
+//--- now setup new chi and change the previous ones appropriately
+      setring Spa;
+      if(size(chi_E[thisE])==0)
+      {
+//--- have not set the initial value of chi(E_thisE) yet
+        if(deg(std(cent+BO[5])[1])==0)
+        {
+           if(dim(std(cent))==0)
+           {
+//--- \pi^-1(0) does not meet the Q-point cent
+              list templist=0,nulliv;
+              dimEi[thisE]=-1;
+           }
+//--- if cent is a curve, the intersection point might simply be outside
+//--- of this chart!!!
+        }
+        else
+        {
+           if(dim(std(cent))==0)
+           {
+//--- center was point  ==> new except. div. is a P^2
+              list templist=3*vdim(std(BO[1]+cent)),nulliv;
+              dimEi[thisE]=2;
+           }
+           else
+           {
+//--- center was curve   ==> new except. div. is a C x P^1
+              if(dim(std(cent+BO[5]))==1)
+              {
+//--- whole curve is in \pi^-1(0)
+                 list templist=4-4*genus(BO[1]+cent),nulliv;
+                 dimEi[thisE]=2;
+              }
+              else
+              {
+//--- curve meets \pi^-1(0) in points
+//--- in S, the intersection will be a curve!!!
+                 setring S;
+                 list templist=2-2*genus(BO[1]+BO[4][size(BO[4])]+BO[5]),nulliv;
+                 dimEi[thisE]=1;
+                 setring Spa;
+              }
+           }
+        }
+        if(defined(templist))
+        {
+          chi_E[thisE]=templist;
+          kill templist;
+        }
+      }
+      for(j=1;j<=size(BO[4]);j++)
+      {
+//--- we are in the parent ring ==> thisE is not yet born
+//--- all the other E_i have already been initialized, but the chi
+//--- might change with the current blow-up at cent
+         if(BO[6][j]==1)
+         {
+//--- ignore empty sets
+            j++;
+            if(j<=size(BO[4]))
+            {
+              continue;
+            }
+            else
+            {
+              break;
+            }
+         }
+         for(k=1;k<=size(iden);k++)
+         {
+//--- find global index of BO[4][j]
+            if(inIVList(intvec(m,j),iden[k]))
+            {
+               otherE=k;
+               break;
+            }
+         }
+         if(dimEi[otherE]<=1)
+         {
+//--- dimEi[otherE]==-1: center leading to this E does not meet \pi^-1(0)
+//--- dimEi[otherE]== 0: center leading to this E does not meet \pi^-1(0)
+//---                   in any previously visited charts
+//---                   maybe in some other branch later, but has nothing
+//---                   to do with this center
+//--- dimEi[otherE]== 1: E \cap \pi^-1(0) is curve
+//---                   ==> chi is birational invariant
+            j++;
+            if(j<=size(BO[4]))
+            {
+              continue;
+            }
+            break;
+         }
+         if(chi_E[otherE][2][thisE]==1)
+         {
+//--- already considered this one
+            j++;
+            if(j<=size(BO[4]))
+            {
+              continue;
+            }
+            else
+            {
+              break;
+            }
+         }
+//---------------------------------------------------------------------------
+// update chi according to the formula
+// chi(E_k^transf)=chi(E_k) - chi(C \cap E_k) + chi(E_k \cap E_new)
+// for convenience of implementation, we first compute
+//        chi(E_k) - chi(C \cap E_k)
+// and afterwards add the last term chi(E_k \cap E_new)
+//---------------------------------------------------------------------------
+         ideal CinE=std(cent+BO[4][j]+BO[1]);  // this is C \cap E_k
+         if(dim(CinE)==1)
+         {
+//--- center meets E_k in a curve
+            chi_temp[otherE]=chi_E[otherE][1]-(2-2*genus(CinE));
+         }
+         if(dim(CinE)==0)
+         {
+//--- center meets E_k in points
+            chi_temp[otherE]=chi_E[otherE][1]-vdim(std(CinE));
+         }
+         kill CinE;
+         setring S;
+//--- now we are back in the i-th ring in the list
+         ideal CinE=std(BO[4][j]+BO[4][size(BO[4])]+BO[1]);
+                                              // this is E_k \cap E_new
+         if(dim(CinE)==1)
+         {
+//--- if the two divisors meet, they meet in a curve
+            chi_E[otherE][1]=chi_temp[otherE][1]+(2-2*genus(CinE));
+            chi_E[otherE][2][thisE]=1;         // this blow-up of E_k is done
+         }
+         kill CinE;
+         setring Spa;
+      }
+   }
+//--- we still need to clean-up the 1-dimensional E_i \cap \pi^-1(0)
+   for(i=1;i<=size(dimEi);i++)
+   {
+      if(dimEi[i]!=1)
+      {
+//--- not 1-dimensional ==> skip
+         i++;
+         if(i>size(dimEi)) break;
+         continue;
+      }
+      if(defined(myCharts)) {kill myCharts;}
+      intvec myCharts;
+      chi_E[i]=0;
+      for(j=1;j<=size(re[2]);j++)
+      {
+         if(endiv[j]==0)
+         {
+//--- not an endChart ==> skip
+            j++;
+            if(j>size(re[2])) break;
+            continue;
+         }
+         if(defined(mtuple)) {kill mtuple;}
+         intvec mtuple=findInIVList(1,j,iden[i]);
+         if(size(mtuple)==1)
+         {
+//-- nothing to do with this Ei ==> skip
+            j++;
+            if(j>size(re[2])) break;
+            continue;
+         }
+         myCharts[size(myCharts)+1]=j;
+         if(defined(S)){kill S;}
+         def S=re[2][j];
+         setring S;
+         if(defined(interId)){kill interId;}
+//--- all components
+         ideal interId=std(BO[4][mtuple[2]]+BO[5]);
+         if(defined(myPts)){kill myPts;}
+         ideal myPts=1;
+         export(myPts);
+         export(interId);
+         if(defined(doneId)){kill doneId;}
+         if(defined(donePts)){kill donePts;}
+         ideal donePts=1;
+         ideal doneId=1;
+         for(k=2;k<size(myCharts);k++)
+         {
+//--- fetch the components which have already been dealt with via fetchInTree
+            if(defined(opath)) {kill opath;}
+            def opath=imap(re[2][myCharts[k][1]],path);
+            aa=1;
+            while((aa<ncols(opath))&&(aa<ncols(path)))
+            {
+               if(path[1,aa+1]!=opath[1,aa+1]) break;
+               aa++;
+            }
+            if(defined(comPa)) {kill comPa;}
+            int comPa=int(leadcoef(path[1,aa]));
+            if(defined(tempId)){kill tempId;}
+            ideal tempId=fetchInTree(re,myCharts[k][1],comPa,j,"interId",iden);
+            doneId=intersect(doneId,tempId);
+            kill tempId;
+            ideal tempId=fetchInTree(re,myCharts[k][1],comPa,j,"myPts",iden);
+            donePts=intersect(donePts,tempId);
+            kill tempId;
+         }
+//--- drop components which have already been dealt with
+         interId=sat(interId,doneId)[1];
+         list pr=minAssGTZ(interId);
+         myPts=std(interId+doneId);
+         for(k=1;k<=size(pr);k++)
+         {
+           for(n=k+1;n<=size(pr);n++)
+           {
+              myPts=intersect(myPts,std(pr[k]+pr[n]));
+           }
+           if(deg(std(pr[k])[1])>0)
+           {
+              chi_E[i][1]=chi_E[i][1]+(2-2*genus(pr[k]));
+           }
+         }
+         myPts=sat(myPts,donePts)[1];
+         chi_E[i][1]=chi_E[i][1]-vdim(myPts);
+      }
+   }
+   setring R;
+   return(chi_E);
+}
+//////////////////////////////////////////////////////////////////////////////
+static proc chi_ast(list re,list iden,list #)
+"Internal procedure - no help and no example available
+"
+{
+//--- compute the Euler characteristic of the Ei,Eij,Eijk and the
+//--- corresponding Ei^*,Eij^*,Eijk^* by preparing the input to the
+//--- specialized auxilliary procedures and then recombining the results
+
+//----------------------------------------------------------------------------
+// Initialization
+//----------------------------------------------------------------------------
+   int i,j,k,g;
+   intvec tiv;
+   list chi_ijk,chi_ij,chi_i,ast_ijk,ast_ij,ast_i,tmplist,g_ij,emptylist;
+   list leererSchnitt;
+   def R=basering;
+   ring Rhelp=0, at t,dp;
+   setring R;
+//----------------------------------------------------------------------------
+// first compute the chi(Eij) and  at the same time
+// check whether E_i \cap E_j is empty
+// the formula is
+//              chi_ij=2-2*genus(E_i \cap E_j)
+//----------------------------------------------------------------------------
+   if(size(#)>0)
+   {
+      "Entering chi_ast";
+   }
+   for(i=1;i<=size(iden)-1;i++)
+   {
+      for(j=i+1;j<=size(iden);j++)
+      {
+         if(defined(blub)){kill blub;}
+         def blub=chiEij(re,iden,intvec(i,j));
+         if(typeof(blub)=="int")
+         {
+            tmplist=intvec(i,j),blub;
+         }
+         else
+         {
+            leererSchnitt[size(leererSchnitt)+1]=intvec(i,j);
+            tmplist=intvec(i,j),0;
+         }
+         chi_ij[size(chi_ij)+1]=tmplist;
+      }
+   }
+   if(size(#)>0)
+   {
+      "chi_ij computed";
+   }
+//-----------------------------------------------------------------------------
+// compute chi(Eijk)=chi^*(Eijk) by counting the points in the intersection
+//      chi_ijk=#(E_i \cap E_j \cap E_k)
+//      ast_ijk=chi_ijk
+//-----------------------------------------------------------------------------
+   for(i=1;i<=size(iden)-2;i++)
+   {
+      for(j=i+1;j<=size(iden)-1;j++)
+      {
+         for(k=j+1;k<=size(iden);k++)
+         {
+            if(inIVList(intvec(i,j),leererSchnitt))
+            {
+               tmplist=intvec(i,j,k),0;
+            }
+            else
+            {
+               tmplist=intvec(i,j,k),countEijk(re,iden,intvec(i,j,k));
+            }
+            chi_ijk[size(chi_ijk)+1]=tmplist;
+         }
+      }
+   }
+   ast_ijk=chi_ijk;
+   if(size(#)>0)
+   {
+      "chi_ijk computed";
+   }
+//----------------------------------------------------------------------------
+// construct chi(Eij^*) by the formula
+//      ast_ij=chi_ij - sum_ijk chi_ijk,
+// where k runs over all indices != i,j
+//----------------------------------------------------------------------------
+   for(i=1;i<=size(chi_ij);i++)
+   {
+      ast_ij[i]=chi_ij[i];
+      for(k=1;k<=size(chi_ijk);k++)
+      {
+         if(((chi_ijk[k][1][1]==chi_ij[i][1][1])||
+                 (chi_ijk[k][1][2]==chi_ij[i][1][1]))&&
+            ((chi_ijk[k][1][2]==chi_ij[i][1][2])||
+                 (chi_ijk[k][1][3]==chi_ij[i][1][2])))
+         {
+            ast_ij[i][2]=ast_ij[i][2]-chi_ijk[k][2];
+         }
+      }
+   }
+   if(size(#)>0)
+   {
+      "ast_ij computed";
+   }
+//----------------------------------------------------------------------------
+// construct ast_i according to the following formulae
+//      ast_i=0 if E_i is (Q- resp. C-)component of the strict transform
+//      chi_i=3*n if E_i originates from blowing up a Q-point,
+//                which consists of n (different) C-points
+//      chi_i=2-2g(C) if E_i originates from blowing up a (Q-)curve C
+//           (chi_i=n*(2-2g(C_i))=2-2g(C),
+//                 where C=\cup C_i, C_i \cap C_j = \emptyset)
+// if E_i is not a component of the strict transform, then
+//       ast_i=chi_i - sum_{j!=i} ast_ij
+//----------------------------------------------------------------------------
+   for(i=1;i<=size(iden);i++)
+   {
+      if(defined(S)) {kill S;}
+      def S=re[2][iden[i][1][1]];
+      setring S;
+      if(iden[i][1][2]>size(BO[4]))
+      {
+         i--;
+         break;
+      }
+   }
+   list idenE=iden;
+   while(size(idenE)>i)
+   {
+      idenE=delete(idenE,size(idenE));
+   }
+   list cl=computeChiE(re,idenE);
+   for(i=1;i<=size(idenE);i++)
+   {
+      chi_i[i]=list(intvec(i),cl[i][1]);
+   }
+   if(size(#)>0)
+   {
+      "chi_i computed";
+   }
+   for(i=1;i<=size(idenE);i++)
+   {
+      ast_i[i]=chi_i[i];
+      for(j=1;j<=size(ast_ij);j++)
+      {
+         if((ast_ij[j][1][1]==i)||(ast_ij[j][1][2]==i))
+         {
+            ast_i[i][2]=ast_i[i][2]-chi_ij[j][2];
+         }
+      }
+      for(j=1;j<=size(ast_ijk);j++)
+      {
+         if((ast_ijk[j][1][1]==i)||(ast_ijk[j][1][2]==i)
+                                 ||(ast_ijk[j][1][3]==i))
+         {
+            ast_i[i][2]=ast_i[i][2]+chi_ijk[j][2];
+         }
+      }
+   }
+   for(i=size(idenE)+1;i<=size(iden);i++)
+   {
+      ast_i[i]=list(intvec(i),0);
+   }
+//--- results are in ast_i, ast_ij and ast_ijk
+//--- all are of the form intvec(indices),int(value)
+   list result=ast_i,ast_ij,ast_ijk;
+   return(result);
+}
+//////////////////////////////////////////////////////////////////////////////
+static proc chi_ast_local(list re,list iden,list #)
+"Internal procedure - no help and no example available
+"
+{
+//--- compute the Euler characteristic of the Ei,Eij,Eijk and the
+//--- corresponding Ei^*,Eij^*,Eijk^* by preparing the input to the
+//--- specialized auxilliary procedures and then recombining the results
+
+//----------------------------------------------------------------------------
+// Initialization
+//----------------------------------------------------------------------------
+   int i,j,k,g;
+   intvec tiv;
+   list chi_ijk,chi_ij,chi_i,ast_ijk,ast_ij,ast_i,tmplist,g_ij,emptylist;
+   list leererSchnitt;
+   def R=basering;
+   ring Rhelp=0, at t,dp;
+   setring R;
+//----------------------------------------------------------------------------
+// first compute
+// if E_i \cap E_j \cap \pi^-1(0) is a curve:
+//    chi(Eij) and  at the same time
+//    check whether E_i \cap E_j is empty
+//    the formula is
+//              chi_ij=2-2*genus(E_i \cap E_j)
+// otherwise (points):
+//    chi(E_ij) by counting the points
+//----------------------------------------------------------------------------
+   if(size(#)>0)
+   {
+      "Entering chi_ast_local";
+   }
+   for(i=1;i<=size(iden)-1;i++)
+   {
+      for(j=i+1;j<=size(iden);j++)
+      {
+         if(defined(blub)){kill blub;}
+         def blub=chiEij_local(re,iden,intvec(i,j));
+         if(typeof(blub)=="int")
+         {
+            tmplist=intvec(i,j),blub;
+         }
+         else
+         {
+            leererSchnitt[size(leererSchnitt)+1]=intvec(i,j);
+            tmplist=intvec(i,j),0;
+         }
+         chi_ij[size(chi_ij)+1]=tmplist;
+      }
+   }
+   if(size(#)>0)
+   {
+      "chi_ij computed";
+   }
+//-----------------------------------------------------------------------------
+// compute chi(Eijk)=chi^*(Eijk) by counting the points in the intersection
+//      chi_ijk=#(E_i \cap E_j \cap E_k \cap \pi^-1(0))
+//      ast_ijk=chi_ijk
+//-----------------------------------------------------------------------------
+   for(i=1;i<=size(iden)-2;i++)
+   {
+      for(j=i+1;j<=size(iden)-1;j++)
+      {
+         for(k=j+1;k<=size(iden);k++)
+         {
+            if(inIVList(intvec(i,j),leererSchnitt))
+            {
+               tmplist=intvec(i,j,k),0;
+            }
+            else
+            {
+               tmplist=intvec(i,j,k),countEijk(re,iden,intvec(i,j,k),"local");
+            }
+            chi_ijk[size(chi_ijk)+1]=tmplist;
+         }
+      }
+   }
+   ast_ijk=chi_ijk;
+   if(size(#)>0)
+   {
+      "chi_ijk computed";
+   }
+//----------------------------------------------------------------------------
+// construct chi(Eij^*) by the formula
+//      ast_ij=chi_ij - sum_ijk chi_ijk,
+// where k runs over all indices != i,j
+//----------------------------------------------------------------------------
+   for(i=1;i<=size(chi_ij);i++)
+   {
+      ast_ij[i]=chi_ij[i];
+      for(k=1;k<=size(chi_ijk);k++)
+      {
+         if(((chi_ijk[k][1][1]==chi_ij[i][1][1])||
+                 (chi_ijk[k][1][2]==chi_ij[i][1][1]))&&
+            ((chi_ijk[k][1][2]==chi_ij[i][1][2])||
+                 (chi_ijk[k][1][3]==chi_ij[i][1][2])))
+         {
+            ast_ij[i][2]=ast_ij[i][2]-chi_ijk[k][2];
+         }
+      }
+   }
+   if(size(#)>0)
+   {
+      "ast_ij computed";
+   }
+//----------------------------------------------------------------------------
+// construct ast_i according to the following formulae
+//      ast_i=0 if E_i is (Q- resp. C-)component of the strict transform
+// if E_i \cap \pi^-1(0) is of dimension 2:
+//      chi_i=3*n if E_i originates from blowing up a Q-point,
+//                which consists of n (different) C-points
+//      chi_i=2-2g(C) if E_i originates from blowing up a (Q-)curve C
+//           (chi_i=n*(2-2g(C_i))=2-2g(C),
+//                 where C=\cup C_i, C_i \cap C_j = \emptyset)
+// if E_i \cap \pi^-1(0) is a curve:
+//      use the formula chi_i=2-2*genus(E_i \cap \pi^-1(0))
+//
+// for E_i not a component of the strict transform we have
+//       ast_i=chi_i - sum_{j!=i} ast_ij
+//----------------------------------------------------------------------------
+   for(i=1;i<=size(iden);i++)
+   {
+      if(defined(S)) {kill S;}
+      def S=re[2][iden[i][1][1]];
+      setring S;
+      if(iden[i][1][2]>size(BO[4]))
+      {
+         i--;
+         break;
+      }
+   }
+   list idenE=iden;
+   while(size(idenE)>i)
+   {
+      idenE=delete(idenE,size(idenE));
+   }
+   list cl=computeChiE_local(re,idenE);
+   for(i=1;i<=size(cl);i++)
+   {
+      if(size(cl[i])==0)
+      {
+         cl[i][1]=0;
+      }
+   }
+   for(i=1;i<=size(idenE);i++)
+   {
+      chi_i[i]=list(intvec(i),cl[i][1]);
+   }
+   if(size(#)>0)
+   {
+      "chi_i computed";
+   }
+   for(i=1;i<=size(idenE);i++)
+   {
+      ast_i[i]=chi_i[i];
+      for(j=1;j<=size(ast_ij);j++)
+      {
+         if((ast_ij[j][1][1]==i)||(ast_ij[j][1][2]==i))
+         {
+            ast_i[i][2]=ast_i[i][2]-chi_ij[j][2];
+         }
+      }
+      for(j=1;j<=size(ast_ijk);j++)
+      {
+         if((ast_ijk[j][1][1]==i)||(ast_ijk[j][1][2]==i)
+                                 ||(ast_ijk[j][1][3]==i))
+         {
+            ast_i[i][2]=ast_i[i][2]+chi_ijk[j][2];
+         }
+      }
+   }
+   for(i=size(idenE)+1;i<=size(iden);i++)
+   {
+      ast_i[i]=list(intvec(i),0);
+   }
+//--- results are in ast_i, ast_ij and ast_ijk
+//--- all are of the form intvec(indices),int(value)
+//"End of chi_ast_local";
+//~;
+   list result=ast_i,ast_ij,ast_ijk;
+   return(result);
+}
+//////////////////////////////////////////////////////////////////////////////
+
+proc discrepancy(list re)
+"USAGE:   discrepancy(L);
+@*        L    = list of rings
+ASSUME:   L is the output of resolution of singularities
+RETRUN:   discrepancies of the given resolution"
+{
+//----------------------------------------------------------------------------
+// Initialization
+//----------------------------------------------------------------------------
+   def R=basering;
+   int i,j;
+   list iden=prepEmbDiv(re);       //--- identify the E_i
+   intvec Vvec=computeV(re,iden);  //--- nu
+   intvec Nvec=computeN(re,iden);  //--- N
+   intvec Avec;
+//--- only look at exceptional divisors, not at strict transform
+   for(i=1;i<=size(iden);i++)
+   {
+      if(defined(S)) {kill S;}
+      def S=re[2][iden[i][1][1]];
+      setring S;
+      if(iden[i][1][2]>size(BO[4]))
+      {
+         i--;
+         break;
+      }
+   }
+   j=i;
+//--- discrepancies are a_i=nu_i-N_i
+   for(i=1;i<=j;i++)
+   {
+     Avec[i]=Vvec[i]-Nvec[i]-1;
+   }
+   return(Avec);
+}
+example
+{"EXAMPLE:";
+   echo = 2;
+   ring R=0,(x,y,z),dp;
+   ideal I=x2+y2+z3;
+   list re=resolve(I);
+   discrepancy(re);
+}
+//////////////////////////////////////////////////////////////////////////////
+
+proc zetaDL(list re,int d,list #)
+"USAGE:   zetaDL(L,d[,s1][,s2][,a]);
+          L     = list of rings;
+          d     = integer;
+          s1,s2 = string;
+          a     = integer
+ASSUME:   L is the output of resolution of singularities
+COMPUTE:  local Denef-Loeser zeta function, if string s1 is present and
+             has the value 'local'; global Denef-Loeser zeta function
+             otherwise
+          if string s1 or s2 has the value "A", additionally the
+             characteristic polynomial of the monodromy is computed
+RETURN:   list l
+          if a is not present:
+          l[1]: string specifying the top. zeta function
+          l[2]: string specifying characteristic polynomial of monodromy,
+                if "A" was specified
+          if a is present:
+          l[1]: string specifying the top. zeta function
+          l[2]: list ast,
+                     ast[1]=chi(Ei^*)
+                     ast[2]=chi(Eij^*)
+                     ast[3]=chi(Eijk^*)
+          l[3]: intvec nu of multiplicites as needed in computation of zeta
+                function
+          l[4]: intvec N of multiplicities as needed in compuation of zeta
+                function
+          l[5]: string specifying characteristic polynomial of monodromy,
+                if "A" was specified
+EXAMPLE:  example zetaDL;   shows an example
+"
+{
+//----------------------------------------------------------------------------
+// Initialization
+//----------------------------------------------------------------------------
+   def R=basering;
+   int show_all,i;
+   if(size(#)>0)
+   {
+     if((typeof(#[1])=="int")||(size(#)>2))
+     {
+       show_all=1;
+     }
+     if(typeof(#[1])=="string")
+     {
+       if((#[1]=="local")||(#[1]=="lokal"))
+       {
+//          ERROR("Local case not implemented yet");
+          "Local Case: Assuming that no (!) charts were dropped";
+          "during calculation of the resolution (option \"A\")";
+          int localComp=1;
+          if(size(#)>1)
+          {
+             if(#[2]=="A")
+             {
+                int aCampoFormula=1;
+             }
+          }
+       }
+       else
+       {
+          if(#[1]=="A")
+          {
+             int aCampoFormula=1;
+          }
+          "Computing global zeta function";
+       }
+     }
+   }
+//----------------------------------------------------------------------------
+// Identify the embedded divisors and chi(Ei^*), chi(Eij^*) and chi(Eijk^*)
+// as well as the integer vector V(=nu) and N
+//----------------------------------------------------------------------------
+   list iden=prepEmbDiv(re);       //--- identify the E_i
+//!!! TIMING:    E8 takes 520 sec ==> needs speed up
+   if(!defined(localComp))
+   {
+      list ast_list=chi_ast(re,iden); //--- compute chi(E^*)
+   }
+   else
+   {
+      list ast_list=chi_ast_local(re,iden);
+   }
+   intvec Vvec=computeV(re,iden);  //--- nu
+   intvec Nvec=computeN(re,iden);  //--- N
+//----------------------------------------------------------------------------
+// Build a new ring with one parameter s
+// and compute Zeta_top^(d) in its ground field
+//----------------------------------------------------------------------------
+   ring Qs=(0,s),x,dp;
+   number zetaTop=0;
+   number enum,denom;
+   denom=1;
+   for(i=1;i<=size(Nvec);i++)
+   {
+      denom=denom*(Vvec[i]+s*Nvec[i]);
+   }
+//--- factors for which index set J consists of one element
+//--- (do something only if d divides N_j)
+   for(i=1;i<=size(ast_list[1]);i++)
+   {
+      if((((Nvec[ast_list[1][i][1][1]] div d)*d)-Nvec[ast_list[1][i][1][1]]==0)&&
+         (ast_list[1][i][2]!=0))
+      {
+          enum=enum+ast_list[1][i][2]*(denom/(Vvec[ast_list[1][i][1][1]]+s*Nvec[ast_list[1][i][1][1]]));
+      }
+   }
+//--- factors for which index set J consists of two elements
+//--- (do something only if d divides both N_i and N_j)
+//!!! TIMING: E8 takes 690 sec and has 703 elements
+//!!!         ==> need to implement a smarter way to do this
+//!!! e.g. build up enumerator and denominator separately, thus not
+//!!!      searching for common factors in each step
+   for(i=1;i<=size(ast_list[2]);i++)
+   {
+      if((((Nvec[ast_list[2][i][1][1]] div d)*d)-Nvec[ast_list[2][i][1][1]]==0)&&
+         (((Nvec[ast_list[2][i][1][2]] div d)*d)-Nvec[ast_list[2][i][1][2]]==0)&&
+          (ast_list[2][i][2]!=0))
+      {
+         enum=enum+ast_list[2][i][2]*(denom/((Vvec[ast_list[2][i][1][1]]+s*Nvec[ast_list[2][i][1][1]])*(Vvec[ast_list[2][i][1][2]]+s*Nvec[ast_list[2][i][1][2]])));
+      }
+   }
+//--- factors for which index set J consists of three elements
+//--- (do something only if d divides N_i, N_j and N_k)
+//!!! TIMING: E8 takes 490 sec and has 8436 elements
+//!!!         ==> same kind of improvements as in the previous case needed
+   for(i=1;i<=size(ast_list[3]);i++)
+   {
+      if((((Nvec[ast_list[3][i][1][1]] div d)*d)-Nvec[ast_list[3][i][1][1]]==0)&&
+         (((Nvec[ast_list[3][i][1][2]] div d)*d)-Nvec[ast_list[3][i][1][2]]==0)&&
+         (((Nvec[ast_list[3][i][1][3]] div d)*d)-Nvec[ast_list[3][i][1][3]]==0)&&
+         (ast_list[3][i][2]!=0))
+      {
+         enum=enum+ast_list[3][i][2]*(denom/((Vvec[ast_list[3][i][1][1]]+s*Nvec[ast_list[3][i][1][1]])*(Vvec[ast_list[3][i][1][2]]+s*Nvec[ast_list[3][i][1][2]])*(Vvec[ast_list[3][i][1][3]]+s*Nvec[ast_list[3][i][1][3]])));
+      }
+   }
+   zetaTop=enum/denom;
+   zetaTop=numerator(zetaTop)/denominator(zetaTop);
+   string zetaStr=string(zetaTop);
+
+   if(show_all)
+   {
+      list result=zetaStr,ast_list[1],ast_list[2],ast_list[3],Vvec,Nvec;
+   }
+   else
+   {
+      list result=zetaStr;
+   }
+//--- compute characteristic polynomial of the monodromy
+//--- by the A'Campo formula
+   if(defined(aCampoFormula))
+   {
+      poly charP=1;
+      for(i=1;i<=size(ast_list[1]);i++)
+      {
+         charP=charP*((s^Nvec[i]-1)^ast_list[1][i][2]);
+      }
+      string charPStr=string(charP/(s-1));
+      result[size(result)+1]=charPStr;
+   }
+   setring R;
+   return(result);
+}
+example
+{"EXAMPLE:";
+   echo = 2;
+   ring R=0,(x,y,z),dp;
+   ideal I=x2+y2+z3;
+   list re=resolve(I,"K");
+   zetaDL(re,1);
+   I=(xz+y2)*(xz+y2+x2)+z5;
+   list L=resolve(I,"K");
+   zetaDL(L,1);
+
+//===== expected zeta function =========
+// (20s^2+130s+87)/((1+s)*(3+4s)*(29+40s))
+//======================================
+}
+//////////////////////////////////////////////////////////////////////////////
+
+proc abstractR(list re)
+"USAGE:   abstractR(L);
+@*        L = list of rings
+ASSUME:   L is output of resolution of singularities
+NOTE:     currently only implemented for isolated surface singularities
+RETURN:   list l
+          l[1]: intvec, where
+                   l[1][i]=1 if the corresponding ring is a final chart
+                             of non-embedded resolution
+                   l[1][i]=0 otherwise
+          l[2]: intvec, where
+                   l[2][i]=1 if the corresponding ring does not occur
+                             in the non-embedded resolution
+                   l[2][i]=0 otherwise
+          l[3]: list L
+EXAMPLE:  example abstractR;   shows an example
+"
+{
+//---------------------------------------------------------------------------
+// Initialization and sanity checks
+//---------------------------------------------------------------------------
+   def R=basering;
+//---Test whether we are in the irreducible surface case
+   def S=re[2][1];
+   setring S;
+   BO[2]=BO[2]+BO[1];
+   if(dim(std(BO[2]))!=2)
+   {
+       ERROR("NOT A SURFACE");
+   }
+   if(dim(std(slocus(BO[2])))>0)
+   {
+       ERROR("NOT AN ISOLATED SINGULARITY");
+   }
+   setring R;
+   int i,j,k,l,i0;
+   intvec deleted;
+   intvec endiv;
+   endiv[size(re[2])]=0;
+   deleted[size(re[2])]=0;
+//-----------------------------------------------------------------------------
+// run through all rings, only consider final charts
+// for each final chart follow the list of charts leading up to it until
+//     we encounter a chart which is not finished in the non-embedded case
+//-----------------------------------------------------------------------------
+   for(i=1;i<=size(re[2]);i++)
+   {
+      if(defined(S)){kill S;}
+      def S=re[2][i];
+      setring S;
+      if(size(reduce(cent,std(BO[2]+BO[1])))!=0)
+      {
+//--- only consider endrings
+         i++;
+         continue;
+      }
+      i0=i;
+      for(j=ncols(path);j>=2;j--)
+      {
+//--- walk backwards through history
+        if(j==2)
+        {
+          endiv[i0]=1;
+          break;
+        }
+        k=int(leadcoef(path[1,j]));
+        if((deleted[k]==1)||(endiv[k]==1))
+        {
+          deleted[i0]=1;
+          break;
+        }
+        if(defined(SPa)){kill SPa;}
+        def SPa=re[2][k];
+        setring SPa;
+        l=int(leadcoef(path[1,ncols(path)]));
+        if(defined(SPa2)){kill SPa2;}
+        def SPa2=re[2][l];
+        setring SPa2;
+        if((deleted[l]==1)||(endiv[l]==1))
+        {
+//--- parent was already treated via different final chart
+//--- we may safely inherit the data
+          deleted[i0]=1;
+          setring S;
+          i0=k;
+          j--;
+          continue;
+        }
+        setring SPa;
+//!!! Idea of Improvement:
+//!!! BESSER: rueckwaerts gehend nur testen ob glatt
+//!!!         danach vorwaerts bis zum ersten Mal abstractNC
+//!!! ACHTUNG: rueckweg unterwegs notieren - wir haben nur vergangenheit!
+        if((deg(std(slocus(BO[2]))[1])!=0)||(!abstractNC(BO)))
+        {
+//--- not finished in the non-embedded case
+           endiv[i0]=1;
+           break;
+        }
+//--- unnecessary chart in non-embedded case
+        setring S;
+        deleted[i0]=1;
+        i0=k;
+      }
+   }
+//-----------------------------------------------------------------------------
+// Clean up the intvec deleted and return the result
+//-----------------------------------------------------------------------------
+   setring R;
+   for(i=1;i<=size(endiv);i++)
+   {
+     if(endiv[i]==1)
+     {
+        if(defined(S)) {kill S;}
+        def S=re[2][i];
+        setring S;
+        for(j=3;j<ncols(path);j++)
+        {
+           if((endiv[int(leadcoef(path[1,j]))]==1)||
+              (deleted[int(leadcoef(path[1,j]))]==1))
+           {
+              deleted[int(leadcoef(path[1,j+1]))]=1;
+              endiv[int(leadcoef(path[1,j+1]))]=0;
+           }
+        }
+        if((endiv[int(leadcoef(path[1,ncols(path)]))]==1)||
+           (deleted[int(leadcoef(path[1,ncols(path)]))]==1))
+        {
+           deleted[i]=1;
+           endiv[i]=0;
+        }
+     }
+   }
+   list resu=endiv,deleted,re;
+   return(resu);
+}
+example
+{"EXAMPLE:";
+   echo = 2;
+   ring r = 0,(x,y,z),dp;
+   ideal I=x2+y2+z11;
+   list L=resolve(I);
+   list absR=abstractR(L);
+   absR[1];
+   absR[2];
+}
+//////////////////////////////////////////////////////////////////////////////
+static proc decompE(list BO)
+"Internal procedure - no help and no example available
+"
+{
+//--- compute the list of exceptional divisors, including the components
+//--- of the strict transform in the non-embedded case
+//--- (computation over Q !!!)
+   def R=basering;
+   list Elist,prList;
+   int i;
+   for(i=1;i<=size(BO[4]);i++)
+   {
+      Elist[i]=BO[4][i];
+   }
+/* practical speed up (part 1 of 3) -- no theoretical relevance
+   ideal M=maxideal(1);
+   M[1]=var(nvars(basering));
+   M[nvars(basering)]=var(1);
+   map phi=R,M;
+*/
+   ideal KK=BO[2];
+
+/* practical speed up (part 2 of 3)
+   KK=phi(KK);
+*/
+   prList=minAssGTZ(KK);
+
+/* practical speed up (part 3 of 3)
+   prList=phi(prList);
+*/
+
+   for(i=1;i<=size(prList);i++)
+   {
+      Elist[size(BO[4])+i]=prList[i];
+   }
+   return(Elist);
+}
+//////////////////////////////////////////////////////////////////////////////
+
+proc prepEmbDiv(list re, list #)
+"USAGE:   prepEmbDiv(L[,a]);
+@*        L = list of rings
+@*        a = integer
+ASSUME:   L is output of resolution of singularities
+COMPUTE:  if a is not present: exceptional divisors including components
+          of the strict transform
+          otherwise: only exceptional divisors
+RETURN:   list of Q-irreducible exceptional divisors (embedded case)
+EXAMPLE:  example prepEmbDiv;   shows an example
+"
+{
+//--- 1) in each final chart, a list of (decomposed) exceptional divisors
+//---    is created (and exported)
+//--- 2) the strict transform is decomposed
+//--- 3) the exceptional divisors (including the strict transform)
+//---    in the different charts are compared, identified and this
+//---    information collected into a list which is then returned
+//---------------------------------------------------------------------------
+// Initialization
+//---------------------------------------------------------------------------
+   int i,j,k,ncomps,offset,found,a,b,c,d;
+   list tmpList;
+   def R=basering;
+//--- identify identical exceptional divisors
+//--- (note: we are in the embedded case)
+   list iden=collectDiv(re)[2];
+//---------------------------------------------------------------------------
+// Go to each final chart and create the EList
+//---------------------------------------------------------------------------
+   for(i=1;i<=size(iden[size(iden)]);i++)
+   {
+      if(defined(S)){kill S;}
+      def S=re[2][iden[size(iden)][i][1]];
+      setring S;
+      if(defined(EList)){kill EList;}
+      list EList=decompE(BO);
+      export(EList);
+      setring R;
+      kill S;
+   }
+//--- save original iden for further use and then drop
+//--- strict transform from it
+   list iden0=iden;
+   iden=delete(iden,size(iden));
+   if(size(#)>0)
+   {
+//--- we are not interested in the strict transform of X
+      return(iden);
+   }
+//----------------------------------------------------------------------------
+// Run through all final charts and collect and identify all components of
+// the strict transform
+//----------------------------------------------------------------------------
+//--- first final chart - to be used for initialization
+   def S=re[2][iden0[size(iden0)][1][1]];
+   setring S;
+   ncomps=size(EList)-size(BO[4]);
+   if((ncomps==1)&&(deg(std(EList[size(EList)])[1])==0))
+   {
+      ncomps=0;
+   }
+   offset=size(BO[4]);
+   for(i=1;i<=ncomps;i++)
+   {
+//--- add components of strict transform
+      tmpList[1]=intvec(iden0[size(iden0)][1][1],size(BO[4])+i);
+      iden[size(iden)+1]=tmpList;
+   }
+//--- now run through the other final charts
+   for(i=2;i<=size(iden0[size(iden0)]);i++)
+   {
+      if(defined(S2)){kill S2;}
+      def S2=re[2][iden0[size(iden0)][i][1]];
+      setring S2;
+//--- determine common parent of this ring and re[2][iden0[size(iden0)][1][1]]
+      if(defined(opath)){kill opath;}
+      def opath=imap(S,path);
+      j=1;
+      while(opath[1,j]==path[1,j])
+      {
+         j++;
+         if((j>ncols(path))||(j>ncols(opath))) break;
+      }
+      if(defined(li1)){kill li1;}
+      list li1;
+//--- fetch the components we have considered in
+//--- re[2][iden0[size(iden0)][1][1]]
+//--- via the resolution tree
+      for(k=1;k<=ncomps;k++)
+      {
+         if(defined(id1)){kill id1;}
+         string tempstr="EList["+string(eval(k+offset))+"]";
+         ideal id1=fetchInTree(re,iden0[size(iden0)][1][1],
+                               int(leadcoef(path[1,j-1])),
+                               iden0[size(iden0)][i][1],tempstr,iden0,1);
+         kill tempstr;
+         li1[k]=id1;
+         kill id1;
+      }
+//--- do the comparison
+      for(k=size(BO[4])+1;k<=size(EList);k++)
+      {
+//--- only components of the strict transform are interesting
+         if((size(BO[4])+1==size(EList))&&(deg(std(EList[size(EList)])[1])==0))
+         {
+            break;
+         }
+         found=0;
+         for(j=1;j<=size(li1);j++)
+         {
+            if((size(reduce(li1[j],std(EList[k])))==0)&&
+               (size(reduce(EList[k],std(li1[j])))==0))
+            {
+//--- found a match
+               li1[j]=ideal(1);
+               iden[size(iden0)-1+j][size(iden[size(iden0)-1+j])+1]=
+                      intvec(iden0[size(iden0)][i][1],k);
+               found=1;
+               break;
+            }
+         }
+         if(!found)
+         {
+//--- no match yet, maybe there are entries not corresponding to the
+//--- initialization of the list -- collected in list repair
+            if(!defined(repair))
+            {
+//--- no entries in repair, we add the very first one
+               list repair;
+               repair[1]=list(intvec(iden0[size(iden0)][i][1],k));
+            }
+            else
+            {
+//--- compare against repair, and add the item appropriately
+//--- steps of comparison as before
+               for(c=1;c<=size(repair);c++)
+               {
+                  for(d=1;d<=size(repair[c]);d++)
+                  {
+                     if(defined(opath)) {kill opath;}
+                     def opath=imap(re[2][repair[c][d][1]],path);
+                     b=0;
+                     while(path[1,b+1]==opath[1,b+1])
+                     {
+                        b++;
+                        if((b>ncols(path)-1)||(b>ncols(opath)-1)) break;
+                     }
+                     b=int(leadcoef(path[1,b]));
+                     string tempstr="EList["+string(eval(repair[c][d][2]))
+                                     +"]";
+                     if(defined(id1)){kill id1;}
+                     ideal id1=fetchInTree(re,repair[c][d][1],b,
+                               iden0[size(iden0)][i][1],tempstr,iden0,1);
+                     kill tempstr;
+                     if((size(reduce(EList[k],std(id1)))==0)&&
+                        (size(reduce(id1,std(EList[k])))==0))
+                     {
+                        repair[c][size(repair[c])+1]=intvec(iden0[size(iden0)][i][1],k);
+                        break;
+                     }
+                  }
+                  if(d<=size(repair[c]))
+                  {
+                     break;
+                  }
+               }
+               if(c>size(repair))
+               {
+                  repair[size(repair)+1]=list(intvec(iden0[size(iden0)][i][1],k));
+               }
+            }
+         }
+      }
+   }
+   if(defined(repair))
+   {
+//--- there were further components, add them
+      for(c=1;c<=size(repair);c++)
+      {
+         iden[size(iden)+1]=repair[c];
+      }
+      kill repair;
+   }
+//--- up to now only Q-irred components - not C-irred components !!!
+   return(iden);
+}
+example
+{"EXAMPLE:";
+   echo = 2;
+   ring R=0,(x,y,z),dp;
+   ideal I=x2+y2+z11;
+   list L=resolve(I);
+   prepEmbDiv(L);
+}
+///////////////////////////////////////////////////////////////////////////////
+static proc decompEinX(list BO)
+"Internal procedure - no help and no example available
+"
+{
+//--- decomposition of exceptional divisor, non-embedded resolution.
+//--- even a single exceptional divisor may be Q-reducible when considered
+//--- as divisor on the strict transform
+
+//----------------------------------------------------------------------------
+// Initialization
+//----------------------------------------------------------------------------
+   int i,j,k,de,contact;
+   intmat interMat;
+   list dcE,tmpList,prList,sa,nullList;
+   string mpol,compList;
+   def R=basering;
+   ideal I;
+//----------------------------------------------------------------------------
+// pass to divisors on V(J) and throw away components already present as
+// previous exceptional divisors
+//----------------------------------------------------------------------------
+   for(i=1;i<=size(BO[4]);i++)
+   {
+      I=BO[4][i]+BO[2];
+      for(j=i+1;j<=size(BO[4]);j++)
+      {
+         sa=sat(I,BO[4][j]+BO[2]);
+         if(sa[2])
+         {
+           I=sa[1];
+         }
+      }
+//!!! Practical improvement - not yet implemented:
+//!!!hier den Input besser aufbereiten (cf. J. Wahl's example)
+//!!!I[1]=x(2)^15*y(2)^9+3*x(2)^10*y(2)^6+3*x(2)^5*y(2)^3+x(2)+1;
+//!!!I[2]=x(2)^8*y(2)^6+y(0);
+//!!!heuristisch die Ordnung so waehlen, dass y(0) im Prinzip eliminiert
+//!!!wird.
+//-----------------------------------------------------------------------------
+// 1) decompose exceptional divisor (over Q)
+// 2) check whether there are C-reducible Q-components
+// 3) if necessary, find appropriate field extension of Q to decompose
+// 4) in each chart collect information in list dcE and export it
+//-----------------------------------------------------------------------------
+      prList=primdecGTZ(I);
+      for(j=1;j<=size(prList);j++)
+      {
+        tmpList=grad(prList[j][2]);
+        de=tmpList[1];
+        interMat=tmpList[2];
+        mpol=tmpList[3];
+        compList=tmpList[4];
+        nullList=tmpList[5];
+        contact=Kontakt(prList[j][1],BO[2]);
+        tmpList=prList[j][2],de,contact,interMat,mpol,compList,nullList;
+        prList[j]=tmpList;
+      }
+      dcE[i]=prList;
+   }
+   return(dcE);
+}
+//////////////////////////////////////////////////////////////////////////////
+static proc getMinpoly(poly p)
+"Internal procedure - no help and no example available
+"
+{
+//---assume that p is a polynomial in 2 variables and irreducible
+//---over Q. Computes an irreducible polynomial mp in one variable
+//---over Q such that p splits completely over the splitting field of mp
+//---returns mp as a string
+//---use a variant of the algorithm of S. Gao
+  def R=basering;
+  int i,j,k,a,b,m,n;
+  intvec v;
+  string mp="poly p=t-1;";
+  list Li=string(1);
+  list re=mp,Li,1;
+
+//---check which variables occur in p
+  for(i=1;i<=nvars(basering);i++)
+  {
+    if(p!=subst(p,var(i),0)){v[size(v)+1]=i;}
+  }
+
+//---the polynomial is constant
+  if(size(v)==1){return(re);}
+
+//---the polynomial depends only on one variable or is homogeneous
+//---in 2 variables
+  if((size(v)==2)||((size(v)==3)&&(homog(p))))
+  {
+     if((size(v)==3)&&(homog(p)))
+     {
+        p=subst(p,var(v[3]),1);
+     }
+     ring Rhelp=0,var(v[2]),dp;
+     poly p=imap(R,p);
+     ring Shelp=0,t,dp;
+     poly p=fetch(Rhelp,p);
+     int de=deg(p);
+     p=simplifyMinpoly(p);
+     Li=getNumZeros(p);
+     short=0;
+     mp="poly p="+string(p)+";";
+     re=mp,Li,de;
+     setring R;
+     return(re);
+  }
+  v=v[2..size(v)];
+  if(size(v)>2){ERROR("getMinpoly:input depends on more then 2 variables");}
+
+//---the general case, the polynomial is considered as polynomial in x an y now
+  ring T=0,(x,y),lp;
+  ideal M,N;
+  M[nvars(R)]=0;
+  N[nvars(R)]=0;
+  M[v[1]]=x;
+  N[v[1]]=y;
+  M[v[2]]=y;
+  N[v[2]]=x;
+  map phi=R,M;
+  map psi=R,N;
+  poly p=phi(p);
+  poly q=psi(p);
+  ring Thelp=(0,x),y,dp;
+  poly p=imap(T,p);
+  poly q=imap(T,q);
+  n=deg(p);              //---the degree with respect to y
+  m=deg(q);              //---the degree with respect to x
+  setring T;
+  ring A=0,(u(1..m*(n+1)),v(1..(m+1)*n),x,y,t),dp;
+  poly f=imap(T,p);
+  poly g;
+  poly h;
+  for(i=0;i<=m-1;i++)
+  {
+     for(j=0;j<=n;j++)
+     {
+        g=g+u(i*(n+1)+j+1)*x^i*y^j;
+     }
+  }
+  for(i=0;i<=m;i++)
+  {
+     for(j=0;j<=n-1;j++)
+     {
+        h=h+v(i*n+j+1)*x^i*y^j;
+     }
+  }
+  poly L=f*(diff(g,y)-diff(h,x))+h*diff(f,x)-g*diff(f,y);
+//---according to the theory f is absolutely irreducible if and only if
+//---L(g,h)=0 has no non-trivial solution g,h
+//---(g=diff(f,x),h=diff(f,y) is always a solution)
+//---therefore we compute a vector space basis of G
+//---G={g in Q[x,y],deg_x(g)<m,|exist h, such that L(g,h)=0}
+//---dim(G)=a is the number of factors of f in C[x,y]
+  matrix M=coef(L,xy);
+  ideal J=M[2,1..ncols(M)];
+  option(redSB);
+  J=std(J);
+  option(noredSB);
+  poly gred=reduce(g,J);
+  ideal G;
+  for(i=1;i<=m*(n+1);i++)
+  {
+    if(gred!=subst(gred,u(i),0))
+    {
+       G[size(G)+1]=subst(gred,u(i),1);
+    }
+  }
+  for(i=1;i<=n*(m+1);i++)
+  {
+    if(gred!=subst(gred,v(i),0))
+    {
+       G[size(G)+1]=subst(gred,v(i),1);
+    }
+  }
+  for(i=1;i<=m*(n+1);i++)
+  {
+     G=subst(G,u(i),0);
+  }
+  for(i=1;i<=n*(m+1);i++)
+  {
+     G=subst(G,v(i),0);
+  }
+//---the number of factors in C[x,y]
+  a=size(G);
+  for(i=1;i<=a;i++)
+  {
+     G[i]=simplify(G[i],1);
+  }
+  if(a==1)
+  {
+//---f is absolutely irreducible
+    setring R;
+    return(re);
+  }
+//---let g in G be any non-trivial element (g not in <diff(f,x)>)
+//---according to the theory f=product over all c in C of the
+//---gcd(f,g-c*diff(f,x))
+//---let g_1,...,g_a be a basis of G and write
+//---g*g_i=sum a_ij*g_j*diff(f,x)  mod f
+//---let B=(a_ij) and ch=det(t*unitmat(a)-B) the characteristic
+//---polynomial then the number of distinct irreducible factors
+//---of gcd(f,g-c*diff(f,x)) in C[x,y] is equal to the multiplicity
+//---of c as a root of ch.
+//---in our special situation (f is irreducible over Q) ch should
+//---be irreducible and the different roots of ch lead to the
+//---factors of f, i.e. ch is the minpoly we are looking for
+
+  poly fh=homog(f,t);
+//---homogenization is used to obtain a constant matrix using lift
+  ideal Gh=homog(G,t);
+  int dh,df;
+  df=deg(fh);
+  for(i=1;i<=a;i++)
+  {
+    if(deg(Gh[i])>dh){dh=deg(Gh[i]);}
+  }
+  for(i=1;i<=a;i++)
+  {
+    Gh[i]=t^(dh-deg(Gh[i]))*Gh[i];
+  }
+  ideal GF=simplify(diff(fh,x),1)*Gh,fh;
+  poly ch;
+  matrix LI;
+  matrix B[a][a];
+  matrix E=unitmat(a);
+  poly gran;
+  ideal fac;
+  for(i=1;i<=a;i++)
+  {
+     LI=lift(GF,t^(df-1-dh)*Gh[i]*Gh);
+     B=LI[1..a,1..a];
+     ch=det(t*E-B);
+//---irreducibility test
+     fac=factorize(ch,1);
+     if(deg(fac[1])==a)
+     {
+        ch=simplifyMinpoly(ch);
+        Li=getNumZeros(ch);
+        int de=deg(ch);
+        short=0;
+        mp="poly p="+string(ch)+";";
+        re=mp,Li,de;
+        setring R;
+        return(re);
+     }
+  }
+  ERROR("getMinpoly:not found:please send the example to the authors");
+}
+//////////////////////////////////////////////////////////////////////////////
+static proc getNumZeros(poly p)
+"Internal procedure - no help and no example available
+"
+{
+//--- compute numerically (!!!) the zeros of the minimal polynomial
+  def R=basering;
+  ring S=0,t,dp;
+  poly p=imap(R,p);
+  def L=laguerre_solve(p,30);
+//!!! practical improvement:
+//!!! testen ob die Nullstellen signifikant verschieden sind
+//!!! und im Notfall Genauigkeit erhoehen
+  list re;
+  int i;
+  for(i=1;i<=size(L);i++)
+  {
+    re[i]=string(L[i]);
+  }
+  setring R;
+  return(re);
+}
+//////////////////////////////////////////////////////////////////////////////
+static
+proc simplifyMinpoly(poly p)
+"Internal procedure - no help and no example available
+"
+{
+//--- describe field extension in a simple way
+   p=cleardenom(p);
+   int n=int(leadcoef(p));
+   int d=deg(p);
+   int i,k;
+   int re=1;
+   number s=1;
+
+   list L=primefactors(n);
+
+   for(i=1;i<=size(L[1]);i++)
+   {
+      k=L[2][i] mod d;
+      s=1/number((L[1][i])^(L[2][i] div d));
+      if(!k){p=subst(p,t,s*t);}
+   }
+   p=cleardenom(p);
+   n=int(leadcoef(subst(p,t,0)));
+   L=primefactors(n);
+   for(i=1;i<=size(L[1]);i++)
+   {
+      k=L[2][i] mod d;
+      s=(L[1][i])^(L[2][i] div d);
+      if(!k){p=subst(p,t,s*t);}
+   }
+   p=cleardenom(p);
+   return(p);
+}
+///////////////////////////////////////////////////////////////////////////////
+static proc grad(ideal I)
+"Internal procedure - no help and no example available
+"
+{
+//--- computes the number of components over C
+//--- for a prime ideal of height 1 over Q
+  def R=basering;
+  int n=nvars(basering);
+  string mp="poly p=t-1;";
+  string str=string(1);
+  list zeroList=string(1);
+  int i,j,k,l,d,e,c,mi;
+  ideal Istd=std(I);
+  intmat interMat;
+  d=dim(Istd);
+  if(d==-1){return(list(0,0,mp,str,zeroList));}
+  if(d!=1){ERROR("ideal is not one-dimensional");}
+  ideal Sloc=std(slocus(I));
+  if(deg(Sloc[1])>0)
+  {
+//---This is only to test that in case of singularities we have only
+//---one singular point which is a normal crossing
+//---consider the different singular points
+    ideal M;
+    list pr=minAssGTZ(Sloc);
+    if(size(pr)>1){ERROR("grad:more then one singular point");}
+    for(l=1;l<=size(pr);l++)
+    {
+       M=std(pr[l]);
+       d=vdim(M);
+       if(d!=1)
+       {
+//---now we have to extend the field
+          if(defined(S)){kill S;}
+          ring S=0,x(1..n),lp;
+          ideal M=fetch(R,M);
+          ideal I=fetch(R,I);
+          ideal jmap;
+          map phi=S,maxideal(1);;
+          ideal Mstd=std(M);
+//---M has to be in general position with respect to lp, i.e.
+//---vdim(M)=deg(M[1])
+          poly p=Mstd[1];
+          e=vdim(Mstd);
+          while(e!=deg(p))
+          {
+             jmap=randomLast(100);
+             phi=S,jmap;
+             Mstd=std(phi(M));
+             p=Mstd[1];
+          }
+          I=phi(I);
+          kill phi;
+//---now it is in general position an M[1] defines the field extension
+//---Q[x]/M over Q
+          ring Shelp=0,t,dp;
+          ideal helpmap;
+          helpmap[n]=t;
+          map psi=S,helpmap;
+          poly p=psi(p);
+          ring T=(0,t),x(1..n),lp;
+          poly p=imap(Shelp,p);
+//---we are now in the polynomial ring over the field Q[x]/M
+          minpoly=leadcoef(p);
+          ideal M=imap(S,Mstd);
+          M=M,var(n)-t;
+          ideal I=fetch(S,I);
+       }
+//---we construct a map phi which maps M to maxideal(1)
+       option(redSB);
+       ideal Mstd=-simplify(std(M),1);
+       option(noredSB);
+       for(i=1;i<=n;i++)
+       {
+         Mstd=subst(Mstd,var(i),-var(i));
+         M[n-i+1]=Mstd[i];
+       }
+       M=M[1..n];
+//---go to the localization with respect to <x>
+       if(d!=1)
+       {
+          ring Tloc=(0,t),x(1..n),ds;
+          poly p=imap(Shelp,p);
+          minpoly=leadcoef(p);
+          ideal M=fetch(T,M);
+          map phi=T,M;
+       }
+       else
+       {
+          ring Tloc=0,x(1..n),ds;
+          ideal M=fetch(R,M);
+          map phi=R,M;
+       }
+       ideal I=phi(I);
+       ideal Istd=std(I);
+       mi=mi+milnor(Istd);
+       if(mi>l)
+       {
+          ERROR("grad:divisor is really singular");
+       }
+       setring R;
+    }
+  }
+  intvec ind=indepSet(Istd,1)[1];
+  for(i=1;i<=n;i++){if(ind[i]) break;}
+//---the i-th variable is the independent one
+  ring Shelp=0,x(1..n),dp;
+  ideal I=fetch(R,I);
+  if(defined(S)){kill S;}
+  if(i==1){ring S=(0,x(1)),x(2..n),lp;}
+  if(i==n){ring S=(0,x(n)),x(1..n-1),lp;}
+  if((i!=1)&&(i!=n)){ring S=(0,x(i)),(x(1..i-1),x(i+1..n)),lp;}
+//---I is zero-dimensional now
+  ideal I=imap(Shelp,I);
+  ideal Istd=std(I);
+  ideal jmap;
+  map phi;
+  poly p=Istd[1];
+  e=vdim(Istd);
+  if(e==1)
+  {
+     setring R;
+     str=string(I);
+     list resi=1,interMat,mp,str,zeroList;
+     return(resi);
+  }
+//---move I to general position with respect to lp
+  if(e!=deg(p))
+  {
+     jmap=randomLast(5);
+     phi=S,jmap;
+     Istd=std(phi(I));
+     p=Istd[1];
+  }
+  while(e!=deg(p))
+  {
+     jmap=randomLast(100);
+     phi=S,jmap;
+     Istd=std(phi(I));
+     p=Istd[1];
+  }
+  setring Shelp;
+  poly p=imap(S,p);
+  list Q=getMinpoly(p);
+  int de=Q[3];
+  mp=Q[1];
+//!!!diese Stelle effizienter machen
+//!!!minAssGTZ vermeiden durch direkte Betrachtung von
+//!!!p und mp und evtl. Quotientenbildung
+//!!!bisher nicht zeitkritisch
+  string Tesr="ring Tes=(0,t),("+varstr(R)+"),dp;";
+  execute(Tesr);
+  execute(mp);
+  minpoly=leadcoef(p);
+  ideal I=fetch(R,I);
+  list pr=minAssGTZ(I);
+  ideal allgEbene=randomLast(100)[nvars(basering)];
+  int minpts=vdim(std(I+allgEbene));
+  ideal tempi;
+  j=1;
+  for(i=1;i<=size(pr);i++)
+  {
+    tempi=std(pr[i]+allgEbene);
+    if(vdim(tempi)<minpts)
+    {
+      minpts=vdim(tempi);
+      j=i;
+    }
+  }
+  tempi=pr[j];
+  str=string(tempi);
+  kill interMat;
+  setring R;
+  intmat interMat[de][de]=intersComp(str,mp,Q[2],str,mp,Q[2]);
+  list resi=de,interMat,mp,str,Q[2];
+  return(resi);
+}
+////////////////////////////////////////////////////////////////////////////
+static proc Kontakt(ideal I, ideal K)
+"Internal procedure - no help and no example available
+"
+{
+//---Let K be a prime ideal and I an ideal not contained in K
+//---computes a maximalideal M=<x(1)-a1,...,x(n)-an>, ai in a field
+//---extension of Q,  containing I+K and an integer a
+//---such that in the localization of the polynomial ring with
+//---respect to M the ideal I is not contained in K+M^a+1 but in M^a in
+  def R=basering;
+  int n=nvars(basering);
+  int i,j,k,d,e;
+  ideal J=std(I+K);
+  if(dim(J)==-1){return(0);}
+  ideal W;
+//---choice of the maximal ideal M
+  for(i=1;i<=n;i++)
+  {
+     W=std(J,var(i));
+     d=dim(W);
+     if(d==0) break;
+  }
+  i=1;k=2;
+  while((d)&&(i<n))
+  {
+     W=std(J,var(i)+var(k));
+     d=dim(W);
+     if(k==n){i++;k=i;}
+     if(k<n){k++;}
+  }
+  while(d)
+  {
+    W=std(J,randomid(maxideal(1))[1]);
+    d=dim(W);
+  }
+//---now we have a collection om maximalideals and choose one with dim Q[x]/M
+//---minimal
+  list pr=minAssGTZ(W);
+  d=vdim(std(pr[1]));
+  k=1;
+  for(i=2;i<=size(pr);i++)
+  {
+    if(d==1) break;
+    e=vdim(std(pr[i]));
+    if(e<d){k=i;d=e;}
+  }
+//---M is fixed now
+//---if dim Q[x]/M =1 we localize at M
+  ideal M=pr[k];
+  if(d!=1)
+  {
+//---now we have to extend the field
+     if(defined(S)){kill S;}
+     ring S=0,x(1..n),lp;
+     ideal M=fetch(R,M);
+     ideal I=fetch(R,I);
+     ideal K=fetch(R,K);
+     ideal jmap;
+     map phi=S,maxideal(1);;
+     ideal Mstd=std(M);
+//---M has to be in general position with respect to lp, i.e.
+//---vdim(M)=deg(M[1])
+     poly p=Mstd[1];
+     e=vdim(Mstd);
+     while(e!=deg(p))
+     {
+        jmap=randomLast(100);
+        phi=S,jmap;
+        Mstd=std(phi(M));
+        p=Mstd[1];
+     }
+     I=phi(I);
+     K=phi(K);
+     kill phi;
+//---now it is in general position an M[1] defines the field extension
+//---Q[x]/M over Q
+     ring Shelp=0,t,dp;
+     ideal helpmap;
+     helpmap[n]=t;
+     map psi=S,helpmap;
+     poly p=psi(p);
+     ring T=(0,t),x(1..n),lp;
+     poly p=imap(Shelp,p);
+//---we are now in the polynomial ring over the field Q[x]/M
+     minpoly=leadcoef(p);
+     ideal M=imap(S,Mstd);
+     M=M,var(n)-t;
+     ideal I=fetch(S,I);
+     ideal K=fetch(S,K);
+  }
+//---we construct a map phi which maps M to maxideal(1)
+  option(redSB);
+  ideal Mstd=-simplify(std(M),1);
+  option(noredSB);
+  for(i=1;i<=n;i++)
+  {
+    Mstd=subst(Mstd,var(i),-var(i));
+    M[n-i+1]=Mstd[i];
+  }
+  M=M[1..n];
+//---go to the localization with respect to <x>
+  if(d!=1)
+  {
+     ring Tloc=(0,t),x(1..n),ds;
+     poly p=imap(Shelp,p);
+     minpoly=leadcoef(p);
+     ideal M=fetch(T,M);
+     map phi=T,M;
+  }
+  else
+  {
+     ring Tloc=0,x(1..n),ds;
+     ideal M=fetch(R,M);
+     map phi=R,M;
+  }
+  ideal K=phi(K);
+  ideal I=phi(I);
+//---compute the order of I in (Q[x]/M)[[x]]/K
+  k=1;d=0;
+  while(!d)
+  {
+     k++;
+     d=size(reduce(I,std(maxideal(k)+K)));
+  }
+  setring R;
+  return(k-1);
+}
+example
+{"EXAMPLE:";
+   echo = 2;
+   ring r = 0,(x,y,z),dp;
+   ideal I=x4+z4+1;
+   ideal K=x+y2+z2;
+   Kontakt(I,K);
+}
+//////////////////////////////////////////////////////////////////////////////
+static proc abstractNC(list BO)
+"Internal procedure - no help and no example available
+"
+{
+//--- check normal crossing property
+//--- used for passing from embedded to non-embedded resolution
+//----------------------------------------------------------------------------
+// Initialization
+//----------------------------------------------------------------------------
+  int i,k,j,flag;
+  list L;
+  ideal J;
+  if(dim(std(cent))>0){return(1);}
+//----------------------------------------------------------------------------
+// check each exceptional divisor on V(J)
+//----------------------------------------------------------------------------
+  for(i=1;i<=size(BO[4]);i++)
+  {
+    if(dim(std(BO[2]+BO[4][i]))>0)
+    {
+//--- really something to do
+      J=radical(BO[4][i]+BO[2]);
+      if(deg(std(slocus(J))[1])!=0)
+      {
+        if(!nodes(J))
+        {
+//--- really singular, not only nodes ==> not normal crossing
+          return(0);
+        }
+      }
+      for(k=1;k<=size(L);k++)
+      {
+//--- run through previously considered divisors
+//--- we do not want to bother with the same one twice
+         if((size(reduce(J,std(L[k])))==0)&&(size(reduce(L[k],std(J)))==0))
+         {
+//--- already considered this one
+            flag=1;break;
+         }
+//--- drop previously considered exceptional divisors from the current one
+         J=sat(J,L[k])[1];
+         if(deg(std(J)[1])==0)
+         {
+//--- nothing remaining
+            flag=1;break;
+         }
+      }
+      if(flag==0)
+      {
+//--- add exceptional divisor to the list
+         L[size(L)+1]=J;
+      }
+      flag=0;
+    }
+  }
+//---------------------------------------------------------------------------
+// check intersection properties between different exceptional divisors
+//---------------------------------------------------------------------------
+  for(k=1;k<size(L);k++)
+  {
+     for(i=k+1;i<=size(L);i++)
+     {
+        if(!nodes(intersect(L[k],L[i])))
+        {
+//--- divisors Ek and Ei do not meet in a node but in a singularity
+//--- which is not allowed to occur ==> not normal crossing
+           return(0);
+        }
+        for(j=i+1;j<=size(L);j++)
+        {
+           if(deg(std(L[i]+L[j]+L[k])[1])>0)
+           {
+//--- three divisors meet simultaneously ==> not normal crossing
+              return(0);
+           }
+        }
+     }
+   }
+//--- we reached this point ==> normal crossing
+   return(1);
+}
+//////////////////////////////////////////////////////////////////////////////
+static proc nodes(ideal J)
+"Internal procedure - no help and no example available
+"
+{
+//--- check whether at most nodes occur as singularities
+   ideal K=std(slocus(J));
+   if(deg(K[1])==0){return(1);}
+   if(dim(K)>0){return(0);}
+   if(vdim(K)!=vdim(std(radical(K)))){return(0);}
+   return(1);
+}
+//////////////////////////////////////////////////////////////////////////////
+
+proc intersectionDiv(list re)
+"USAGE:   intersectionDiv(L);
+@*        L = list of rings
+ASSUME:   L is output of resolution of singularities
+          (only case of isolated surface singularities)
+COMPUTE:  intersection matrix and genera of the exceptional divisors
+          (considered as curves on the strict transform)
+RETURN:   list l, where
+          l[1]: intersection matrix of exceptional divisors
+          l[2]: intvec, genera of exceptional divisors
+          l[3]: divisorList, encoding the identification of the divisors
+EXAMPLE:  example intersectionDiv;  shows an example
+"
+{
+//----------------------------------------------------------------------------
+//--- Computes in case of surface singularities (non-embedded resolution):
+//--- the intersection of the divisors (on the surface)
+//--- assuming that re=resolve(J)
+//----------------------------------------------------------------------------
+   def R=basering;
+//---Test whether we are in the irreducible surface case
+   def S=re[2][1];
+   setring S;
+   BO[2]=BO[2]+BO[1];              // make sure we are living in the smooth W
+   if(dim(std(BO[2]))!=2)
+   {
+     ERROR("The given original object is not a surface");
+   }
+   if(dim(std(slocus(BO[2])))>0)
+   {
+     ERROR("The given original object has non-isolated singularities.");
+   }
+   setring R;
+//----------------------------------------------------------------------------
+// Compute a non-embedded resolution from the given embedded one by
+// dropping redundant trailing blow-ups
+//----------------------------------------------------------------------------
+   list resu,tmpiden,templist;
+   intvec divcomp;
+   int i,j,k,offset1,offset2,a,b,c,d,q,found;
+//--- compute non-embedded resolution
+   list abst=abstractR(re);
+   intvec endiv=abst[1];
+   intvec deleted=abst[2];
+//--- identify the divisors in the various final charts
+   list iden=collectDiv(re,deleted)[2];
+                                    // list of final divisors
+   list iden0=iden;                 // backup copy of iden for later use
+
+   iden=delete(iden,size(iden));    // drop list of endRings from iden
+//---------------------------------------------------------------------------
+// In iden, only the final charts should be listed, whereas iden0 contains
+// everything.
+//---------------------------------------------------------------------------
+   for(i=1;i<=size(iden);i++)
+   {
+     k=size(iden[i]);
+     tmpiden=iden[i];
+     for(j=k;j>0;j--)
+     {
+        if(!endiv[iden[i][j][1]])
+        {
+//---not a final chart
+           tmpiden=delete(tmpiden,j);
+        }
+     }
+     if(size(tmpiden)==0)
+     {
+//--- oops, this divisor does not appear in final charts
+        iden=delete(iden,i);
+        continue;
+     }
+     else
+     {
+        iden[i]=tmpiden;
+     }
+   }
+//---------------------------------------------------------------------------
+// Even though the exceptional divisors were irreducible in the embedded
+// case, they may very well have become reducible after intersection with
+// the strict transform of the original object.
+// ===> compute a decomposition for each divisor in each of the final charts
+//      and change the entries of iden accordingly
+// In particular, it is important to keep track of the identification of the
+// components of the divisors in each of the charts
+//---------------------------------------------------------------------------
+   int n=size(iden);
+   for(i=1;i<=size(re[2]);i++)
+   {
+     if(endiv[i])
+     {
+        def SN=re[2][i];
+        setring SN;
+        if(defined(dcE)){kill dcE;}
+        list dcE=decompEinX(BO);       // decomposition of exceptional divisors
+        export(dcE);
+        setring R;
+        kill SN;
+     }
+   }
+   if(defined(tmpiden)){kill tmpiden;}
+   list tmpiden=iden;
+   for(i=1;i<=size(iden);i++)
+   {
+      for(j=size(iden[i]);j>0;j--)
+      {
+         def SN=re[2][iden[i][j][1]];
+         setring SN;
+         if(size(dcE[iden[i][j][2]])==1)
+         {
+           if(dcE[iden[i][j][2]][1][2]==0)
+           {
+             tmpiden[i]=delete(tmpiden[i],j);
+           }
+         }
+         setring R;
+         kill SN;
+      }
+   }
+   for(i=size(tmpiden);i>0;i--)
+   {
+      if(size(tmpiden[i])==0)
+      {
+         tmpiden=delete(tmpiden,i);
+      }
+   }
+   iden=tmpiden;
+   kill tmpiden;
+   list tmpiden;
+//--- change entries of iden accordingly
+   for(i=1;i<=size(iden);i++)
+   {
+//--- first set up new entries in iden if necessary - using the first chart
+//--- in which we see the respective exceptional divisor
+     if(defined(S)){kill S;}
+     def S=re[2][iden[i][1][1]];
+//--- considering first entry for i-th divisor
+     setring S;
+     a=size(dcE[iden[i][1][2]]);
+     for(j=1;j<=a;j++)
+     {
+//--- reducible - add to the list considering each component as an exceptional
+//--- divisor in its own right
+        list tl;
+        tl[1]=intvec(iden[i][1][1],iden[i][1][2],j);
+        tmpiden[size(tmpiden)+1]=tl;
+        kill tl;
+     }
+//--- now identify the components in the other charts w.r.t. the ones in the
+//--- first chart which have already been added to the list
+     for(j=2;j<=size(iden[i]);j++)
+     {
+//--- considering remaining entries for the same original divisor
+       if(defined(S2)){kill S2;}
+       def S2=re[2][iden[i][j][1]];
+       setring S2;
+//--- determine common parent of this ring and re[2][iden[i][1][1]]
+       if(defined(opath)){kill opath;}
+       def opath=imap(S,path);
+       b=1;
+       while(opath[1,b]==path[1,b])
+       {
+          b++;
+          if((b>ncols(path))||(b>ncols(opath))) break;
+       }
+       if(defined(li1)){kill li1;}
+       list li1;
+//--- fetch the components we have considered in re[2][iden[i][1][1]]
+//--- via the resolution tree
+       for(k=1;k<=a;k++)
+       {
+          string tempstr="dcE["+string(eval(iden[i][1][2]))+"]["+string(k)+"][1]";
+          if(defined(id1)){kill id1;}
+          ideal id1=fetchInTree(re,iden[i][1][1],int(leadcoef(path[1,b-1])),
+                      iden[i][j][1],tempstr,iden0,1);
+          kill tempstr;
+          li1[k]=radical(id1);        // for comparison only the geometric
+                                      // object matters
+          kill id1;
+       }
+//--- compare the components we have fetched with the components in the
+//--- current ring
+       for(k=1;k<=size(dcE[iden[i][j][2]]);k++)
+       {
+          found=0;
+          for(b=1;b<=size(li1);b++)
+          {
+             if((size(reduce(li1[b],std(dcE[iden[i][j][2]][k][1])))==0)&&
+               (size(reduce(dcE[iden[i][j][2]][k][1],std(li1[b]+BO[2])))==0))
+             {
+                li1[b]=ideal(1);
+                tmpiden[size(tmpiden)-a+b][size(tmpiden[size(tmpiden)-a+b])+1]=
+                       intvec(iden[i][j][1],iden[i][j][2],k);
+                found=1;
+                break;
+             }
+          }
+          if(!found)
+          {
+            if(!defined(repair))
+            {
+               list repair;
+               repair[1]=list(intvec(iden[i][j][1],iden[i][j][2],k));
+            }
+            else
+            {
+               for(c=1;c<=size(repair);c++)
+               {
+                  for(d=1;d<=size(repair[c]);d++)
+                  {
+                     if(defined(opath)) {kill opath;}
+                     def opath=imap(re[2][repair[c][d][1]],path);
+                     q=0;
+                     while(path[1,q+1]==opath[1,q+1])
+                     {
+                        q++;
+                        if((q>ncols(path)-1)||(q>ncols(opath)-1)) break;
+                     }
+                     q=int(leadcoef(path[1,q]));
+                     string tempstr="dcE["+string(eval(repair[c][d][2]))+"]["+string(eval(repair[c][d][3]))+"][1]";
+                     if(defined(id1)){kill id1;}
+                     ideal id1=fetchInTree(re,repair[c][d][1],q,
+                                  iden[i][j][1],tempstr,iden0,1);
+                     kill tempstr;
+//!!! sind die nicht schon radical?
+                     id1=radical(id1);        // for comparison
+                                              // only the geometric
+                                              // object matters
+                     if((size(reduce(dcE[iden[i][j][2]][k][1],std(id1+BO[2])))==0)&&
+                        (size(reduce(id1+BO[2],std(dcE[iden[i][j][2]][k][1])))==0))
+                     {
+                       repair[c][size(repair[c])+1]=intvec(iden[i][j][1],iden[i][j][2],k);
+                       break;
+                     }
+                  }
+                  if(d<=size(repair[c]))
+                  {
+                     break;
+                  }
+               }
+               if(c>size(repair))
+               {
+                  repair[size(repair)+1]=list(intvec(iden[i][j][1],iden[i][j][2],k));
+               }
+            }
+         }
+       }
+     }
+     if(defined(repair))
+     {
+       for(c=1;c<=size(repair);c++)
+       {
+          tmpiden[size(tmpiden)+1]=repair[c];
+       }
+       kill repair;
+     }
+   }
+   setring R;
+   for(i=size(tmpiden);i>0;i--)
+   {
+      if(size(tmpiden[i])==0)
+      {
+        tmpiden=delete(tmpiden,i);
+        continue;
+      }
+   }
+   iden=tmpiden;                      // store the modified divisor list
+   kill tmpiden;                      // and clean up temporary objects
+//---------------------------------------------------------------------------
+// Now we have decomposed everything into irreducible components over Q,
+// but over C there might still be some reducible ones left:
+// Determine the number of components over C.
+//---------------------------------------------------------------------------
+   n=0;
+   for(i=1;i<=size(iden);i++)
+   {
+      if(defined(S)) {kill S;}
+      def S=re[2][iden[i][1][1]];
+      setring S;
+      divcomp[i]=ncols(dcE[iden[i][1][2]][iden[i][1][3]][4]);
+          // number of components of the Q-irreducible curve dcE[iden[i][1][2]]
+      n=n+divcomp[i];
+      setring R;
+   }
+//---------------------------------------------------------------------------
+// set up the entries Inters[i,j] , i!=j, in the intersection matrix:
+// we have to compute the intersection of the exceptional divisors (over C)
+//    i.e. we have to work in over appropriate algebraic extension of Q.
+// (1) plug the intersection matrices of the components of the same Q-irred.
+//     divisor into the correct position in the intersection matrix
+// (2) for comparison of Ei,k and Ej,l move to a chart where both divisors
+//     are present, fetch the components from the very first chart containing
+//     the respective divisor and then compare by using intersComp
+// (4) put the result into the correct position in the integer matrix Inters
+//---------------------------------------------------------------------------
+//--- some initialization
+   int comPai,comPaj;
+   intvec v,w;
+   intmat Inters[n][n];
+//--- run through all Q-irreducible exceptional divisors
+   for(i=1;i<=size(iden);i++)
+   {
+      if(divcomp[i]>1)
+      {
+//--- (1) put the intersection matrix for Ei,k with Ei,l into the correct place
+         for(k=1;k<=size(iden[i]);k++)
+         {
+            if(defined(tempmat)){kill tempmat;}
+            intmat tempmat=imap(re[2][iden[i][k][1]],dcE)[iden[i][k][2]][iden[i][k][3]][4];
+            if(size(ideal(tempmat))!=0)
+            {
+               Inters[i+offset1..(i+offset1+divcomp[i]-1),
+                      i+offset1..(i+offset1+divcomp[i]-1)]=
+                       tempmat[1..nrows(tempmat),1..ncols(tempmat)];
+               break;
+            }
+            kill tempmat;
+         }
+      }
+      offset2=offset1+divcomp[i]-1;
+//--- set up the components over C of the i-th exceptional divisor
+      if(defined(S)){kill S;}
+      def S=re[2][iden[i][1][1]];
+      setring S;
+      if(defined(idlisti)) {kill idlisti;}
+      list idlisti;
+      idlisti[1]=dcE[iden[i][1][2]][iden[i][1][3]][6];
+      export(idlisti);
+      setring R;
+//--- run through the remaining exceptional divisors and check whether they
+//--- have a chart in common with the i-th divisor
+      for(j=i+1;j<=size(iden);j++)
+      {
+         kill templist;
+         list templist;
+         for(k=1;k<=size(iden[i]);k++)
+         {
+            intvec tiv2=findInIVList(1,iden[i][k][1],iden[j]);
+            if(size(tiv2)!=1)
+            {
+//--- tiv2[1] is a common chart for the divisors i and j
+              tiv2[4..6]=iden[i][k];
+              templist[size(templist)+1]=tiv2;
+            }
+            kill tiv2;
+         }
+         if(size(templist)==0)
+         {
+//--- the two (Q-irred) divisors do not appear in any chart simultaneously
+            offset2=offset2+divcomp[j]-1;
+            j++;
+            continue;
+         }
+         for(k=1;k<=size(templist);k++)
+         {
+            if(defined(S)) {kill S;}
+//--- set up the components over C of the j-th exceptional divisor
+            def S=re[2][iden[j][1][1]];
+            setring S;
+            if(defined(idlistj)) {kill idlistj;}
+            list idlistj;
+            idlistj[1]=dcE[iden[j][1][2]][iden[j][1][3]][6];
+            export(idlistj);
+            if(defined(opath)){kill opath;}
+            def opath=imap(re[2][templist[k][1]],path);
+            comPaj=1;
+            while(opath[1,comPaj]==path[1,comPaj])
+            {
+              comPaj++;
+              if((comPaj>ncols(opath))||(comPaj>ncols(path))) break;
+            }
+            comPaj=int(leadcoef(path[1,comPaj-1]));
+            setring R;
+            kill S;
+            def S=re[2][iden[i][1][1]];
+            setring S;
+            if(defined(opath)){kill opath;}
+            def opath=imap(re[2][templist[k][1]],path);
+            comPai=1;
+            while(opath[1,comPai]==path[1,comPai])
+            {
+               comPai++;
+               if((comPai>ncols(opath))||(comPai>ncols(path))) break;
+            }
+            comPai=int(leadcoef(opath[1,comPai-1]));
+            setring R;
+            kill S;
+            def S=re[2][templist[k][1]];
+            setring S;
+            if(defined(il)) {kill il;}
+            if(defined(jl)) {kill jl;}
+            if(defined(str1)) {kill str1;}
+            if(defined(str2)) {kill str2;}
+            string str1="idlisti";
+            string str2="idlistj";
+            attrib(str1,"algext",imap(re[2][iden[i][1][1]],dcE)[iden[i][1][2]][iden[i][1][3]][5]);
+            attrib(str2,"algext",imap(re[2][iden[j][1][1]],dcE)[iden[j][1][2]][iden[j][1][3]][5]);
+            list il=fetchInTree(re,iden[i][1][1],comPai,
+                                templist[k][1],str1,iden0,1);
+            list jl=fetchInTree(re,iden[j][1][1],comPaj,
+                                templist[k][1],str2,iden0,1);
+            list nulli=imap(re[2][iden[i][1][1]],dcE)[iden[i][1][2]][iden[i][1][3]][7];
+            list nullj=imap(re[2][iden[j][1][1]],dcE)[iden[j][1][2]][iden[j][1][3]][7];
+            string mpi=imap(re[2][iden[i][1][1]],dcE)[iden[i][1][2]][iden[i][1][3]][5];
+            string mpj=imap(re[2][iden[j][1][1]],dcE)[iden[j][1][2]][iden[j][1][3]][5];
+            if(defined(tintMat)){kill tintMat;}
+            intmat tintMat=intersComp(il[1],mpi,nulli,jl[1],mpj,nullj);
+            kill mpi;
+            kill mpj;
+            kill nulli;
+            kill nullj;
+            for(a=1;a<=divcomp[i];a++)
+            {
+               for(b=1;b<=divcomp[j];b++)
+               {
+                 if(tintMat[a,b]!=0)
+                 {
+                    Inters[i+offset1+a-1,j+offset2+b-1]=tintMat[a,b];
+                    Inters[j+offset2+b-1,i+offset1+a-1]=tintMat[a,b];
+                 }
+               }
+            }
+         }
+         offset2=offset2+divcomp[j]-1;
+      }
+      offset1=offset1+divcomp[i]-1;
+   }
+   Inters=addSelfInter(re,Inters,iden,iden0,endiv);
+   intvec GenusIden;
+
+   list tl_genus;
+   a=1;
+   for(i=1;i<=size(iden);i++)
+   {
+      tl_genus=genus_E(re,iden0,iden[i][1]);
+      for(j=1;j<=tl_genus[2];j++)
+      {
+        GenusIden[a]=tl_genus[1];
+        a++;
+      }
+   }
+
+   list retlist=Inters,GenusIden,iden,divcomp;
+   return(retlist);
+}
+example
+{"EXAMPLE:";
+   echo = 2;
+   ring r = 0,(x(1..3)),dp(3);
+   ideal J=x(3)^5+x(2)^4+x(1)^3+x(1)*x(2)*x(3);
+   list re=resolve(J);
+   list di=intersectionDiv(re);
+   di;
+
+}
+//////////////////////////////////////////////////////////////////////////////
+static proc intersComp(string str1,
+                string mp1,
+                list null1,
+                string str2,
+                string mp2,
+                list null2)
+"Internal procedure - no help and no example available
+"
+{
+//--- format of input
+//--- str1 : ideal (over field extension 1)
+//--- mp1  : minpoly of field extension 1
+//--- null1: numerical zeros of minpoly
+//--- str2 : ideal (over field extension 2)
+//--- mp2  : minpoly of field extension 2
+//--- null2: numerical zeros of minpoly
+
+//--- determine intersection matrix of the C-components defined by the input
+
+//---------------------------------------------------------------------------
+// Initialization
+//---------------------------------------------------------------------------
+  int ii,jj,same;
+  def R=basering;
+  intmat InterMat[size(null1)][size(null2)];
+  ring ringst=0,(t,s),dp;
+//---------------------------------------------------------------------------
+// Add new variables s and t and compare the minpolys and ideals
+// to find out whether they are identical
+//---------------------------------------------------------------------------
+  def S=R+ringst;
+  setring S;
+  if((mp1==mp2)&&(str1==str2))
+  {
+    same=1;
+  }
+//--- define first Q-component/C-components, substitute t by s
+  string tempstr="ideal id1="+str1+";";
+  execute(tempstr);
+  execute(mp1);
+  id1=subst(id1,t,s);
+  poly q=subst(p,t,s);
+  kill p;
+//--- define second Q-component/C-components
+  tempstr="ideal id2="+str2+";";
+  execute(tempstr);
+  execute(mp2);
+//--- do the intersection
+  ideal interId=id1+id2+ideal(p)+ideal(q);
+  if(same)
+  {
+    interId=quotient(interId,t-s);
+  }
+  interId=std(interId);
+//--- refine the comparison by passing to each of the numerical zeros
+//--- of the two minpolys
+  ideal stid=nselect(interId,1..nvars(R));
+  ring compl_st=complex,(s,t),dp;
+  def stid=imap(S,stid);
+  ideal tempid,tempid2;
+  for(ii=1;ii<=size(null1);ii++)
+  {
+    tempstr="number numi="+null1[ii]+";";
+    execute(tempstr);
+    tempid=subst(stid,s,numi);
+    kill numi;
+    for(jj=1;jj<=size(null2);jj++)
+    {
+       tempstr="number numj="+null2[jj]+";";
+       execute(tempstr);
+       tempid2=subst(tempid,t,numj);
+       kill numj;
+       if(size(tempid2)==0)
+       {
+         InterMat[ii,jj]=1;
+       }
+    }
+  }
+//--- sanity check; as both Q-components were Q-irreducible,
+//--- summation over all entries of a single row must lead to the same
+//--- result, no matter which row is chosen
+//--- dito for the columns
+  int cou,cou1;
+  for(ii=1;ii<=ncols(InterMat);ii++)
+  {
+    cou=0;
+    for(jj=1;jj<=nrows(InterMat);jj++)
+    {
+      cou=cou+InterMat[jj,ii];
+    }
+    if(ii==1){cou1=cou;}
+    if(cou1!=cou){ERROR("intersComp:matrix has wrong entries");}
+  }
+  for(ii=1;ii<=nrows(InterMat);ii++)
+  {
+    cou=0;
+    for(jj=1;jj<=ncols(InterMat);jj++)
+    {
+      cou=cou+InterMat[ii,jj];
+    }
+    if(ii==1){cou1=cou;}
+    if(cou1!=cou){ERROR("intersComp:matrix has wrong entries");}
+  }
+  return(InterMat);
+}
+/////////////////////////////////////////////////////////////////////////////
+static proc addSelfInter(list re,intmat Inters,list iden,list iden0,intvec endiv)
+"Internal procedure - no help and no example available
+"
+{
+//---------------------------------------------------------------------------
+// Initialization
+//---------------------------------------------------------------------------
+   def R=basering;
+   int i,j,k,l,a,b;
+   int n=size(iden);
+   intvec v,w;
+   list satlist;
+   def T=re[2][1];
+   setring T;
+   poly p;
+   p=var(1);  //any linear form will do,
+              //but this one is most convenient
+   ideal F=ideal(p);
+//----------------------------------------------------------------------------
+// lift linear form to every end ring, determine the multiplicity of
+// the exceptional divisors and store it in Flist
+//----------------------------------------------------------------------------
+   list templist;
+   intvec tiv;
+   for(i=1;i<=size(endiv);i++)
+   {
+     if(endiv[i]==1)
+     {
+        kill v;
+        intvec v;
+        a=0;
+        if(defined(S)) {kill S;}
+        def S=re[2][i];
+        setring S;
+        map resi=T,BO[5];
+        ideal F=resi(F)+BO[2];
+        ideal Ftemp=F;
+        list Flist;
+        if(defined(satlist)){kill satlist;}
+        list satlist;
+        for(a=1;a<=size(dcE);a++)
+        {
+           for(b=1;b<=size(dcE[a]);b++)
+           {
+              Ftemp=sat(Ftemp,dcE[a][b][1])[1];
+           }
+        }
+        F=sat(F,Ftemp)[1];
+        Flist[1]=Ftemp;
+        Ftemp=1;
+        list pr=primdecGTZ(F);
+        v[size(pr)]=0;
+        for(j=1;j<=size(pr);j++)
+        {
+          for(a=1;a<=size(dcE);a++)
+          {
+             if(j==1)
+             {
+               kill tiv;
+               intvec tiv;
+               tiv[size(dcE[a])]=0;
+               templist[a]=tiv;
+               if(v[j]==1)
+               {
+                 a++;
+                 continue;
+               }
+             }
+             if(dcE[a][1][2]==0)
+             {
+                a++;
+                continue;
+             }
+             for(b=1;b<=size(dcE[a]);b++)
+             {
+                if((size(reduce(dcE[a][b][1],std(pr[j][2])))==0)&&
+                   (size(reduce(pr[j][2],std(dcE[a][b][1])))==0))
+                {
+                  templist[a][b]=Vielfachheit(pr[j][1],pr[j][2]);
+                  v[j]=1;
+                  break;
+                }
+             }
+             if((v[j]==1)&&(j>1)) break;
+          }
+        }
+        kill v;
+        intvec v;
+        Flist[2]=templist;
+     }
+   }
+//-----------------------------------------------------------------------------
+// Now set up all the data:
+// 1. run through all exceptional divisors in iden and determine the
+//    coefficients c_i of the divisor of F.  ===> civ
+// 2. determine the intersection locus of F^bar and the Ei and from this data
+//    the F^bar.Ei . ===> intF
+//-----------------------------------------------------------------------------
+   intvec civ;
+   intvec intF;
+   intF[ncols(Inters)]=0;
+   int offset,comPa,ncomp,vd;
+   for(i=1;i<=size(iden);i++)
+   {
+      ncomp=0;
+      for(j=1;j<=size(iden[i]);j++)
+      {
+        if(defined(S)) {kill S;}
+        def S=re[2][iden[i][j][1]];
+        setring S;
+        if((size(civ)<i+offset+1)&&
+           (((Flist[2][iden[i][j][2]][iden[i][j][3]])!=0)||(j==size(iden[i]))))
+        {
+           ncomp=ncols(dcE[iden[i][j][2]][iden[i][j][3]][4]);
+           for(k=1;k<=ncomp;k++)
+           {
+              civ[i+offset+k]=Flist[2][iden[i][j][2]][iden[i][j][3]];
+              if(deg(std(slocus(dcE[iden[i][j][2]][iden[i][j][3]][1]))[1])>0)
+              {
+                   civ[i+offset+k]=civ[i+k];
+              }
+           }
+        }
+        if(defined(interId)) {kill interId;}
+        ideal interId=dcE[iden[i][j][2]][iden[i][j][3]][1]+Flist[1];
+        if(defined(interList)) {kill interList;}
+        list interList;
+        interList[1]=string(interId);
+        interList[2]=ideal(0);
+        export(interList);
+        if(defined(doneId)) {kill doneId;}
+        if(defined(tempId)) {kill tempId;}
+        ideal doneId=ideal(1);
+        if(defined(dl)) {kill dl;}
+        list dl;
+        for(k=1;k<j;k++)
+        {
+           if(defined(St)) {kill St;}
+           def St=re[2][iden[i][k][1]];
+           setring St;
+           if(defined(str)){kill str;}
+           string str="interId="+interList[1]+";";
+           execute(str);
+           if(deg(std(interId)[1])==0)
+           {
+             setring S;
+             k++;
+             continue;
+           }
+           setring S;
+           if(defined(opath)) {kill opath;}
+           def opath=imap(re[2][iden[i][k][1]],path);
+           comPa=1;
+           while(opath[1,comPa]==path[1,comPa])
+           {
+              comPa++;
+              if((comPa>ncols(path))||(comPa>ncols(opath))) break;
+           }
+           comPa=int(leadcoef(path[1,comPa-1]));
+           if(defined(str)) {kill str;}
+           string str="interList";
+           attrib(str,"algext","poly p=t-1;");
+           dl=fetchInTree(re,iden[i][k][1],comPa,iden[i][j][1],str,iden0,1);
+           if(defined(tempId)){kill tempId;}
+           str="ideal tempId="+dl[1]+";";
+           execute(str);
+           doneId=intersect(doneId,tempId);
+           str="interId="+interList[1]+";";
+           execute(str);
+           interId=sat(interId,doneId)[1];
+           interList[1]=string(interId);
+        }
+        interId=std(interId);
+        if(dim(interId)>0)
+        {
+           "oops, intersection not a set of points";
+           ~;
+        }
+        vd=vdim(interId);
+        if(vd>0)
+        {
+          for(k=i+offset;k<=i+offset+ncomp-1;k++)
+          {
+             intF[k]=intF[k]+(vd div ncomp);
+          }
+        }
+      }
+      offset=size(civ)-i-1;
+   }
+   if(defined(tiv)){kill tiv;}
+   intvec tiv=civ[2..size(civ)];
+   civ=tiv;
+   kill tiv;
+//-----------------------------------------------------------------------------
+// Using the F_total= sum c_i Ei + F^bar, the intersection matrix Inters and
+// the f^bar.Ei, determine the selfintersection numbers of the Ei from the
+// equation F_total.Ei=0 and store it in the diagonal of Inters.
+//-----------------------------------------------------------------------------
+   intvec diag=Inters*civ+intF;
+   for(i=1;i<=size(diag);i++)
+   {
+      Inters[i,i]=-diag[i] div civ[i];
+   }
+   return(Inters);
+}
+//////////////////////////////////////////////////////////////////////////////
+static proc invSort(list re, list #)
+"Internal procedure - no help and no example available
+"
+{
+  int i,j,k,markier,EZeiger,offset;
+  intvec v,e;
+  intvec deleted;
+  if(size(#)>0)
+  {
+     deleted=#[1];
+  }
+  else
+  {
+    deleted[size(re[2])]=0;
+  }
+  list LE,HI;
+  def R=basering;
+//----------------------------------------------------------------------------
+// Go through all rings
+//----------------------------------------------------------------------------
+  for(i=1;i<=size(re[2]);i++)
+  {
+     if(deleted[i]){i++;continue}
+     def S=re[2][i];
+     setring S;
+//----------------------------------------------------------------------------
+// Determine Invariant
+//----------------------------------------------------------------------------
+     if((size(BO[3])==size(BO[9]))||(size(BO[3])==size(BO[9])+1))
+     {
+        if(defined(merk2)){kill merk2;}
+        intvec merk2;
+        EZeiger=0;
+        for(j=1;j<=size(BO[9]);j++)
+        {
+          offset=0;
+          if(BO[7][j]==-1)
+          {
+             BO[7][j]=size(BO[4])-EZeiger;
+          }
+          for(k=EZeiger+1;(k<=EZeiger+BO[7][j])&&(k<=size(BO[4]));k++)
+          {
+             if(BO[6][k]==2)
+             {
+                offset++;
+             }
+          }
+          EZeiger=EZeiger+BO[7][1];
+          merk2[3*j-2]=BO[3][j];
+          merk2[3*j-1]=BO[9][j]-offset;
+          if(size(invSat[2])>j)
+          {
+            merk2[3*j]=-invSat[2][j];
+          }
+          else
+          {
+            if(j<size(BO[9]))
+            {
+               "!!!!!problem with invSat";~;
+            }
+          }
+        }
+        if((size(BO[3])>size(BO[9])))
+        {
+          merk2[size(merk2)+1]=BO[3][size(BO[3])];
+        }
+        if((size(merk2)%3)==0)
+        {
+          intvec tintvec=merk2[1..size(merk2)-1];
+          merk2=tintvec;
+          kill tintvec;
+        }
+     }
+     else
+     {
+         ERROR("This situation should not occur, please send the example
+                 to the authors.");
+     }
+//----------------------------------------------------------------------------
+// Save invariant describing current center as an object in this ring
+// We also store information on the intersection with the center and the
+// exceptional divisors
+//----------------------------------------------------------------------------
+     cent=std(cent);
+     kill e;
+     intvec e;
+     for(j=1;j<=size(BO[4]);j++)
+     {
+        if(size(reduce(BO[4][j],std(cent+BO[1])))==0)
+        {
+           e[j]=1;
+        }
+        else
+        {
+           e[j]=0;
+        }
+     }
+     if(size(ideal(merk2))==0)
+     {
+        markier=1;
+     }
+     if((size(merk2)%3==0)&&(merk2[size(merk2)]==0))
+     {
+       intvec blabla=merk2[1..size(merk2)-1];
+       merk2=blabla;
+       kill blabla;
+     }
+     if(defined(invCenter)){kill invCenter;}
+     list invCenter=cent,merk2,e;
+     export invCenter;
+//----------------------------------------------------------------------------
+// Insert it into correct place in the list
+//----------------------------------------------------------------------------
+     if(i==1)
+     {
+       if(!markier)
+       {
+         HI=intvec(merk2[1]+1),intvec(1);
+       }
+       else
+       {
+         HI=intvec(778),intvec(1);   // some really large integer
+                                     // will be changed at the end!!!
+       }
+       LE[1]=HI;
+       i++;
+       setring R;
+       kill S;
+       continue;
+     }
+     if(markier==1)
+     {
+       if(i==2)
+       {
+         HI=intvec(777),intvec(2);   // same really large integer-1
+         LE[2]=HI;
+         i++;
+         setring R;
+         kill S;
+         continue;
+       }
+       else
+       {
+         if(ncols(path)==2)
+         {
+           LE[2][2][size(LE[2][2])+1]=i;
+           i++;
+           setring R;
+           kill S;
+           continue;
+         }
+         else
+         {
+           markier=0;
+         }
+       }
+     }
+     j=1;
+     def SOld=re[2][int(leadcoef(path[1,ncols(path)]))];
+     setring SOld;
+     merk2=invCenter[2];
+     setring S;
+     kill SOld;
+     while(merk2<LE[j][1])
+     {
+        j++;
+        if(j>size(LE)) break;
+     }
+     HI=merk2,intvec(i);
+     if(j<=size(LE))
+     {
+        if(merk2>LE[j][1])
+        {
+          LE=insert(LE,HI,j-1);
+        }
+        else
+        {
+           while((merk2==LE[j][1])&&(size(merk2)<size(LE[j][1])))
+           {
+              j++;
+              if(j>size(LE)) break;
+           }
+           if(j<=size(LE))
+           {
+              if((merk2!=LE[j][1])||(size(merk2)!=size(LE[j][1])))
+              {
+                LE=insert(LE,HI,j-1);
+              }
+              else
+              {
+                LE[j][2][size(LE[j][2])+1]=i;
+              }
+           }
+           else
+           {
+              LE[size(LE)+1]=HI;
+           }
+        }
+     }
+     else
+     {
+        LE[size(LE)+1]=HI;
+     }
+     setring R;
+     kill S;
+  }
+  if((LE[1][1]==intvec(778)) && (size(LE)>2))
+  {
+     LE[1][1]=intvec(LE[3][1][1]+2);     // by now we know what 'sufficiently
+     LE[2][1]=intvec(LE[3][1][1]+1);     // large' is
+  }
+  return(LE);
+}
+example
+{"EXAMPLE:";
+   echo = 2;
+   ring r = 0,(x(1..3)),dp(3);
+   ideal J=x(1)^3-x(1)*x(2)^3+x(3)^2;
+   list re=resolve(J,1);
+   list di=invSort(re);
+   di;
+}
+/////////////////////////////////////////////////////////////////////////////
+static proc addToRE(intvec v,int x,list RE)
+"Internal procedure - no help and no example available
+"
+{
+//--- auxilliary procedure for collectDiv,
+//--- inserting an entry at the correct place
+   int i=1;
+   while(i<=size(RE))
+   {
+      if(v==RE[i][1])
+      {
+         RE[i][2][size(RE[i][2])+1]=x;
+         return(RE);
+      }
+      if(v>RE[i][1])
+      {
+         list templist=v,intvec(x);
+         RE=insert(RE,templist,i-1);
+         return(RE);
+      }
+      i++;
+   }
+   list templist=v,intvec(x);
+   RE=insert(RE,templist,size(RE));
+   return(RE);
+}
+////////////////////////////////////////////////////////////////////////////
+
+proc collectDiv(list re,list #)
+"USAGE:   collectDiv(L);
+@*        L = list of rings
+ASSUME:   L is output of resolution of singularities
+COMPUTE:  list representing the identification of the exceptional divisors
+          in the various charts
+RETURN:   list l, where
+          l[1]: intmat, entry k in position i,j implies BO[4][j] of chart i
+                is divisor k (if k!=0)
+                if k==0, no divisor corresponding to i,j
+          l[2]: list ll, where each entry of ll is a list of intvecs
+                entry i,j in list ll[k] implies BO[4][j] of chart i
+                is divisor k
+          l[3]: list L
+EXAMPLE:  example collectDiv;   shows an example
+"
+{
+//------------------------------------------------------------------------
+// Initialization
+//------------------------------------------------------------------------
+  int i,j,k,l,m,maxk,maxj,mPa,oPa,interC,pa,ignoreL,iTotal;
+  int mLast,oLast=1,1;
+  intvec deleted;
+//--- sort the rings by the invariant which controlled the last of the
+//--- exceptional divisors
+  if(size(#)>0)
+  {
+     deleted=#[1];
+  }
+  else
+  {
+    deleted[size(re[2])]=0;
+  }
+  list LE=invSort(re,deleted);
+  list LEtotal=LE;
+  intmat M[size(re[2])][size(re[2])];
+  intvec invar,tempiv;
+  def R=basering;
+  list divList;
+  list RE,SE;
+  intvec myEi,otherEi,tempe;
+  int co=2;
+
+  while(size(LE)>0)
+  {
+//------------------------------------------------------------------------
+// Run through the sorted list LE whose entries are lists containing
+// the invariant and the numbers of all rings corresponding to it
+//------------------------------------------------------------------------
+     for(i=co;i<=size(LE);i++)
+     {
+//--- i==1 in first iteration:
+//--- the original ring which did not arise from a blow-up
+//--- hence there are no exceptional divisors to be identified there ;
+
+//------------------------------------------------------------------------
+// For each fixed value of the invariant, run through all corresponding
+// rings
+//------------------------------------------------------------------------
+        for(l=1;l<=size(LE[i][2]);l++)
+        {
+           if(defined(S)){kill S;}
+           def S=re[2][LE[i][2][l]];
+           setring S;
+           if(size(BO[4])>maxj){maxj=size(BO[4]);}
+//--- all exceptional divisors, except the last one, were previously
+//--- identified - hence we can simply inherit the data from the parent ring
+           for(j=1;j<size(BO[4]);j++)
+           {
+              if(deg(std(BO[4][j])[1])>0)
+              {
+                k=int(leadcoef(path[1,ncols(path)]));
+                k=M[k,j];
+                if(k==0)
+                {
+                   RE=addToRE(LE[i][1],LE[i][2][l],RE);
+                   ignoreL=1;
+                   break;
+                }
+                M[LE[i][2][l],j]=k;
+                tempiv=LE[i][2][l],j;
+                divList[k][size(divList[k])+1]=tempiv;
+              }
+           }
+          if(ignoreL){ignoreL=0;l++;continue;}
+//----------------------------------------------------------------------------
+// In the remaining part of the procedure, the identification of the last
+// exceptional divisor takes place.
+// Step 1: check whether there is a previously considered ring with the
+//         same parent; if this is the case, we can again inherit the data
+// Step 1':check whether the parent had a stored center which it then used
+//         in this case, we are dealing with an additional component of this
+//         divisor: store it in the integer otherComp
+// Step 2: if no appropriate ring was found in step 1, we check whether
+//         there is a previously considered ring, in the parent of which
+//         the center intersects the same exceptional divisors as the center
+//         in our parent.
+//         if such a ring does not exist: new exceptional divisor
+//         if it exists: see below
+//----------------------------------------------------------------------------
+           if(path[1,ncols(path)-1]==0)
+           {
+//--- current ring originated from very first blow-up
+//--- hence exceptional divisor is the first one
+              M[LE[i][2][l],1]=1;
+              if(size(divList)>0)
+              {
+                 divList[1][size(divList[1])+1]=intvec(LE[i][2][l],j);
+              }
+              else
+              {
+                 divList[1]=list(intvec(LE[i][2][l],j));
+              }
+              l++;
+              continue;
+           }
+           if(l==1)
+           {
+              list TE=addToRE(LE[i][1],1,SE);
+              if(size(TE)!=size(SE))
+              {
+//--- new value of invariant hence new exceptional divisor
+                 SE=TE;
+                 divList[size(divList)+1]=list(intvec(LE[i][2][l],j));
+                 M[LE[i][2][l],j]=size(divList);
+              }
+              kill TE;
+           }
+           for(k=1;k<=size(LEtotal);k++)
+           {
+              if(LE[i][1]==LEtotal[k][1])
+              {
+                 iTotal=k;
+                 break;
+              }
+           }
+//--- Step 1
+           k=1;
+           while(LEtotal[iTotal][2][k]<LE[i][2][l])
+           {
+              if(defined(tempPath)){kill tempPath;}
+              def tempPath=imap(re[2][LEtotal[iTotal][2][k]],path);
+              if(tempPath[1,ncols(tempPath)]==path[1,ncols(path)])
+              {
+//--- Same parent, hence we inherit our data
+                 m=size(imap(re[2][LEtotal[iTotal][2][k]],BO)[4]);
+                 m=M[LEtotal[iTotal][2][k],m];
+                 if(m==0)
+                 {
+                    RE=addToRE(LE[i][1],LE[i][2][l],RE);
+                    ignoreL=1;
+                    break;
+                 }
+                 M[LE[i][2][l],j]=m;
+                 tempiv=LE[i][2][l],j;
+                 divList[m][size(divList[m])+1]=tempiv;
+                 break;
+              }
+              k++;
+              if(k>size(LEtotal[iTotal][2])) {break;}
+           }
+           if(ignoreL){ignoreL=0;l++;continue;}
+//--- Step 1', if necessary
+           if(M[LE[i][2][l],j]==0)
+           {
+             int savedCent;
+             def SPa1=re[2][int(leadcoef(path[1,ncols(path)]))];
+                       // parent ring
+             setring SPa1;
+             if(size(BO)>9)
+             {
+                if(size(BO[10])>0)
+                {
+                   savedCent=1;
+                }
+             }
+             if(!savedCent)
+             {
+                def SPa2=re[2][int(leadcoef(path[1,ncols(path)]))];
+                map lMa=SPa2,lastMap;
+                       // map leading from grandparent to parent
+                list transBO=lMa(BO);
+                       // actually we only need BO[10], but this is an
+                       // object not a name
+                list tempsat;
+                if(size(transBO)>9)
+                {
+//--- there were saved centers
+                   while((k<=size(transBO[10])) & (savedCent==0))
+                   {
+                      tempsat=sat(transBO[10][k][1],BO[4][size(BO[4])]);
+                      if(deg(tempsat[1][1])!=0)
+                      {
+//--- saved center can be seen in this affine chart
+                        if((size(reduce(tempsat[1],std(cent)))==0) &&
+                           (size(reduce(cent,tempsat[1]))==0))
+                        {
+//--- this was the saved center which was used
+                           savedCent=1;
+                        }
+                      }
+                      k++;
+                   }
+                }
+                kill lMa;          // clean up temporary objects
+                kill tempsat;
+                kill transBO;
+             }
+             setring S;         // back to the ring which we want to consider
+             if(savedCent==1)
+             {
+               vector otherComp;
+               otherComp[M[int(leadcoef(path[1,ncols(path)])),size(BO[4])-1]]
+                        =1;
+             }
+             kill savedCent;
+             if (defined(SPa2)){kill SPa2;}
+             kill SPa1;
+           }
+//--- Step 2, if necessary
+           if(M[LE[i][2][l],j]==0)
+           {
+//--- we are not done after step 1 and 2
+              pa=int(leadcoef(path[1,ncols(path)]));  // parent ring
+              tempe=imap(re[2][pa],invCenter)[3];     // intersection there
+              kill myEi;
+              intvec myEi;
+              for(k=1;k<=size(tempe);k++)
+              {
+                if(tempe[k]==1)
+                {
+//--- center meets this exceptional divisor
+                   myEi[size(myEi)+1]=M[pa,k];
+                   mLast=k;
+                }
+              }
+//--- ring in which the last divisor we meet is new-born
+              mPa=int(leadcoef(path[1,mLast+2]));
+              k=1;
+              while(LEtotal[iTotal][2][k]<LE[i][2][l])
+              {
+//--- perform the same preparations for the ring we want to compare with
+                 if(defined(tempPath)){kill tempPath;}
+                 def tempPath=imap(re[2][LEtotal[iTotal][2][k]],path);
+                                                          // its ancestors
+                 tempe=imap(re[2][int(leadcoef(tempPath[1,ncols(tempPath)]))],
+                         invCenter)[3];                   // its intersections
+                 kill otherEi;
+                 intvec otherEi;
+                 for(m=1;m<=size(tempe);m++)
+                 {
+                   if(tempe[m]==1)
+                   {
+//--- its center meets this exceptional divisor
+                     otherEi[size(otherEi)+1]
+                          =M[int(leadcoef(tempPath[1,ncols(tempPath)])),m];
+                     oLast=m;
+                   }
+                 }
+                 if(myEi!=otherEi)
+                 {
+//--- not the same center because of intersection properties with the
+//--- exceptional divisor
+                    k++;
+                    if(k>size(LEtotal[iTotal][2]))
+                    {
+                      break;
+                    }
+                    else
+                    {
+                      continue;
+                    }
+                 }
+//----------------------------------------------------------------------------
+// Current situation:
+// 1. the last exceptional divisor could not be identified by simply
+//    considering its parent
+// 2. it could not be proved to be a new one by considering its intersections
+//    with previous exceptional divisors
+//----------------------------------------------------------------------------
+                 if(defined(bool1)) { kill bool1;}
+                 int bool1=
+                       compareE(re,LE[i][2][l],LEtotal[iTotal][2][k],divList);
+                 if(bool1)
+                 {
+//--- found some non-empty intersection
+                    if(bool1==1)
+                    {
+//--- it is really the same exceptional divisor
+                       m=size(imap(re[2][LEtotal[iTotal][2][k]],BO)[4]);
+                       m=M[LEtotal[iTotal][2][k],m];
+                       if(m==0)
+                       {
+                          RE=addToRE(LE[i][1],LE[i][2][l],RE);
+                          ignoreL=1;
+                          break;
+                       }
+                       M[LE[i][2][l],j]=m;
+                       tempiv=LE[i][2][l],j;
+                       divList[m][size(divList[m])+1]=tempiv;
+                       break;
+                    }
+                    else
+                    {
+                       m=size(imap(re[2][LEtotal[iTotal][2][k]],BO)[4]);
+                       m=M[LEtotal[iTotal][2][k],m];
+                       if(m!=0)
+                       {
+                          otherComp[m]=1;
+                       }
+                    }
+                 }
+                 k++;
+                 if(k>size(LEtotal[iTotal][2]))
+                 {
+                   break;
+                 }
+              }
+              if(ignoreL){ignoreL=0;l++;continue;}
+              if( M[LE[i][2][l],j]==0)
+              {
+                 divList[size(divList)+1]=list(intvec(LE[i][2][l],j));
+                 M[LE[i][2][l],j]=size(divList);
+              }
+           }
+           setring R;
+           kill S;
+        }
+     }
+     LE=RE;
+     co=1;
+     kill RE;
+     list RE;
+  }
+//----------------------------------------------------------------------------
+// Add the strict transform to the list of divisors at the last place
+// and clean up M
+//----------------------------------------------------------------------------
+//--- add strict transform
+  for(i=1;i<=size(re[2]);i++)
+  {
+     if(defined(S)){kill S;}
+     def S=re[2][i];
+     setring S;
+     if(size(reduce(cent,std(BO[2])))==0)
+     {
+        tempiv=i,0;
+        RE[size(RE)+1]=tempiv;
+     }
+     setring R;
+  }
+  divList[size(divList)+1]=RE;
+//--- drop trailing zero-columns of M
+  intvec iv0;
+  iv0[nrows(M)]=0;
+  for(i=ncols(M);i>0;i--)
+  {
+    if(intvec(M[1..nrows(M),i])!=iv0) break;
+  }
+  intmat N[nrows(M)][i];
+  for(i=1;i<=ncols(N);i++)
+  {
+    N[1..nrows(M),i]=M[1..nrows(M),i];
+  }
+  kill M;
+  intmat M=N;
+  list retlist=cleanUpDiv(re,M,divList);
+  return(retlist);
+}
+example
+{"EXAMPLE:";
+   echo = 2;
+   ring R=0,(x,y,z),dp;
+   ideal I=xyz+x4+y4+z4;
+//we really need to blow up curves even if the generic point of
+//the curve the total transform is n.c.
+//this occurs here in r[2][5]
+   list re=resolve(I);
+   list di=collectDiv(re);
+   di[1];
+   di[2];
+}
+//////////////////////////////////////////////////////////////////////////////
+static proc cleanUpDiv(list re,intmat M,list divList)
+"Internal procedure - no help and no example available
+"
+{
+//--- It may occur that two different entries of invSort coincide on the
+//--- first part up to the last entry of the shorter one. In this case
+//--- exceptional divisors may appear in both entries of the invSort-list.
+//--- To correct this, we now compare the final collection of Divisors
+//--- for coinciding ones.
+   int i,j,k,a,oPa,mPa,comPa,mdim,odim;
+   def R=basering;
+   for(i=1;i<=size(divList)-2;i++)
+   {
+      if(defined(Sm)){kill Sm;}
+      def Sm=re[2][divList[i][1][1]];
+      setring Sm;
+      mPa=int(leadcoef(path[1,ncols(path)]));
+      if(defined(SmPa)){kill SmPa;}
+      def SmPa=re[2][mPa];
+      setring SmPa;
+      mdim=dim(std(BO[1]+cent));
+      setring Sm;
+      if(mPa==1)
+      {
+//--- very first divisor originates exactly from the first blow-up
+//--- there cannot be any mistake here
+         i++;
+         continue;
+      }
+      for(j=i+1;j<=size(divList)-1;j++)
+      {
+         setring Sm;
+         for(k=1;k<=size(divList[j]);k++)
+         {
+            if(size(findInIVList(1,divList[j][k][1],divList[i]))>1)
+            {
+//--- same divisor cannot appear twice in the same chart
+               k=-1;
+               break;
+            }
+         }
+         if(k==-1)
+         {
+            j++;
+            if(j>size(divList)-1) break;
+            continue;
+         }
+         if(defined(opath)){kill opath;}
+         def opath=imap(re[2][divList[j][1][1]],path);
+         oPa=int(leadcoef(opath[1,ncols(opath)]));
+         if(defined(SoPa)){kill SoPa;}
+         def SoPa=re[2][oPa];
+         setring SoPa;
+         odim=dim(std(BO[1]+cent));
+         setring Sm;
+         if(mdim!=odim)
+         {
+//--- different dimension ==> cannot be same center
+            j++;
+            if(j>size(divList)-1) break;
+            continue;
+         }
+         comPa=1;
+         while(path[1,comPa]==opath[1,comPa])
+         {
+           comPa++;
+           if((comPa>ncols(path))||(comPa>ncols(opath))) break;
+         }
+         comPa=int(leadcoef(path[1,comPa-1]));
+         if(defined(SPa)){kill SPa;}
+         def SPa=re[2][mPa];
+         setring SPa;
+         if(defined(tempIdE)){kill tempIdE;}
+         ideal tempIdE=fetchInTree(re,oPa,comPa,mPa,"cent",divList);
+         if((size(reduce(cent,std(tempIdE)))!=0)||
+            (size(reduce(tempIdE,std(cent)))!=0))
+         {
+//--- it is not the same divisor!
+            j++;
+            if(j>size(divList))
+            {
+               break;
+            }
+            else
+            {
+               continue;
+            }
+         }
+         for(k=1;k<=size(divList[j]);k++)
+         {
+//--- append the entries of the j-th divisor (which is actually also the i-th)
+//--- to the i-th divisor
+            divList[i][size(divList[i])+1]=divList[j][k];
+         }
+         divList=delete(divList,j);  //kill obsolete entry from the list
+         for(k=1;k<=nrows(M);k++)
+         {
+            for(a=1;a<=ncols(M);a++)
+            {
+               if(M[k,a]==j)
+               {
+//--- j-th divisor is actually the i-th one
+                  M[k,a]=i;
+               }
+               if(M[k,a]>j)
+               {
+//--- index j was deleted from the list ==> all subsequent indices dropped by
+//--- one
+                  M[k,a]=M[k,a]-1;
+               }
+            }
+         }
+         j--;                        //do not forget to consider new j-th entry
+      }
+   }
+   setring R;
+   list retlist=M,divList;
+   return(retlist);
+}
+/////////////////////////////////////////////////////////////////////////////
+static proc findTrans(ideal Z, ideal E, list notE, list #)
+"Internal procedure - no help and no example available
+"
+{
+//---Auxilliary procedure for fetchInTree!
+//---Assume E prime ideal, Z+E eqidimensional,
+//---ht(E)+r=ht(Z+E). Compute  P=<p[1],...,p[r]> in Z+E, and polynomial f,
+//---such that radical(Z+E)=radical((E+P):f)
+   int i,j,d,e;
+   ideal Estd=std(E);
+//!!! alternative to subsequent line:
+//!!!           ideal Zstd=std(radical(Z+E));
+   ideal Zstd=std(Z+E);
+   ideal J=1;
+   if(size(#)>0)
+   {
+      J=#[1];
+   }
+   if(deg(Zstd[1])==0){return(list(ideal(1),poly(1)));}
+   for(i=1;i<=size(notE);i++)
+   {
+      notE[i]=std(notE[i]);
+   }
+   ideal Zred=simplify(reduce(Z,Estd),2);
+   if(size(Zred)==0){Z,Estd;~;ERROR("Z is contained in E");}
+   ideal P,Q,Qstd;
+   Q=Estd;
+   attrib(Q,"isSB",1);
+   d=dim(Estd);
+   e=dim(Zstd);
+   for(i=1;i<=size(Zred);i++)
+   {
+      Qstd=std(Q,Zred[i]);
+      if(dim(Qstd)<d)
+      {
+         d=dim(Qstd);
+         P[size(P)+1]=Zred[i];
+         Q=Qstd;
+         attrib(Q,"isSB",1);
+         if(d==e) break;
+      }
+   }
+   list pr=minAssGTZ(E+P);
+   list sr=minAssGTZ(J+P);
+   i=0;
+   Q=1;
+   list qr;
+
+   while(i<size(pr))
+   {
+      i++;
+      Qstd=std(pr[i]);
+      Zred=simplify(reduce(Zstd,Qstd),2);
+      if(size(Zred)==0)
+      {
+        qr[size(qr)+1]=pr[i];
+        pr=delete(pr,i);
+        i--;
+      }
+      else
+      {
+         Q=intersect(Q,pr[i]);
+      }
+   }
+   i=0;
+   while(i<size(sr))
+   {
+      i++;
+      Qstd=std(sr[i]+E);
+      Zred=simplify(reduce(Zstd,Qstd),2);
+      if((size(Zred)!=0)||(dim(Qstd)!=dim(Zstd)))
+      {
+        Q=intersect(Q,sr[i]);
+      }
+   }
+   poly f;
+   for(i=1;i<=size(Q);i++)
+   {
+      f=Q[i];
+      for(e=1;e<=size(qr);e++)
+      {
+         if(reduce(f,std(qr[e]))==0){f=0;break;}
+      }
+      for(j=1;j<=size(notE);j++)
+      {
+         if(reduce(f,notE[j])==0){f=0; break;}
+      }
+      if(f!=0) break;
+   }
+   i=0;
+   while(f==0)
+   {
+      i++;
+      f=randomid(Q)[1];
+      for(e=1;e<=size(qr);e++)
+      {
+         if(reduce(f,std(qr[e]))==0){f=0;break;}
+      }
+      for(j=1;j<=size(notE);j++)
+      {
+         if(reduce(f,notE[j])==0){f=0; break;}
+      }
+      if(f!=0) break;
+      if(i>20)
+      {
+         ~;
+         ERROR("findTrans:Hier ist was faul");
+      }
+   }
+
+   list resu=P,f;
+   return(resu);
+}
+/////////////////////////////////////////////////////////////////////////////
+static proc compareE(list L, int m, int o, list DivL)
+"Internal procedure - no help and no example available
+"
+{
+//----------------------------------------------------------------------------
+// We want to compare the divisors BO[4][size(BO[4])] of the rings
+// L[2][m] and L[2][o].
+// In the initialization step, we collect all necessary data from those
+// those rings. In particular, we determine at what point (in the resolution
+// history) the branches for L[2][m] and L[2][o] were separated, denoting
+// the corresponding ring indices by mPa, oPa and comPa.
+//----------------------------------------------------------------------------
+   def R=basering;
+   int i,j,k,len;
+
+//-- find direct parents and branching point in resolution history
+   matrix tpm=imap(L[2][m],path);
+   matrix tpo=imap(L[2][o],path);
+   int m1,o1=int(leadcoef(tpm[1,ncols(tpm)])),
+             int(leadcoef(tpo[1,ncols(tpo)]));
+   while((i<ncols(tpo)) && (i<ncols(tpm)))
+   {
+     if(tpm[1,i+1]!=tpo[1,i+1]) break;
+     i++;
+   }
+   int branchpos=i;
+   int comPa=int(leadcoef(tpm[1,branchpos]));  // last common ancestor
+//----------------------------------------------------------------------------
+// simple checks to save us some work in obvious cases
+//----------------------------------------------------------------------------
+   if((comPa==m1)||(comPa==o1))
+   {
+//--- one is in the history of the other ==> they cannot give rise
+//---                                        to the same divisor
+      return(0);
+   }
+   def T=L[2][o1];
+   setring T;
+   int dimCo1=dim(std(cent+BO[1]));
+   def S=L[2][m1];
+   setring S;
+   int dimCm1=dim(std(cent+BO[1]));
+   if(dimCm1!=dimCo1)
+   {
+//--- centers do not have same dimension ==> they cannot give rise
+//---                                        to the same divisor
+      return(0);
+   }
+//----------------------------------------------------------------------------
+// fetch the center via the tree for comparison
+//----------------------------------------------------------------------------
+   if(defined(invLocus0)) {kill invLocus0;}
+   ideal invLocus0=fetchInTree(L,o1,comPa,m1,"cent",DivL);
+             // blow down from L[2][o1] to L[2][comPa] and then up to L[2][m1]
+   if(deg(std(invLocus0+invCenter[1]+BO[1])[1])!=0)
+   {
+     setring R;
+     return(int(1));
+   }
+   if(size(BO)>9)
+   {
+     for(i=1;i<=size(BO[10]);i++)
+     {
+       if(deg(std(invLocus0+BO[10][i][1]+BO[1])[1])!=0)
+       {
+         if(dim(std(BO[10][i][1]+BO[1])) >
+              dim(std(invLocus0+BO[10][i][1]+BO[1])))
+         {
+           ERROR("Internal Error: Please send this example to the authors.");
+         }
+         setring R;
+         return(int(2));
+       }
+     }
+   }
+   setring R;
+   return(int(0));
+//----------------------------------------------------------------------------
+// Return-Values:
+//        TRUE (=1) if the exceptional divisors coincide,
+//        TRUE (=2) if the exceptional divisors originate from different
+//                  components of the same center
+//        FALSE (=0) otherwise
+//----------------------------------------------------------------------------
+}
+//////////////////////////////////////////////////////////////////////////////
+
+proc fetchInTree(list L,
+                 int o1,
+                 int comPa,
+                 int m1,
+                 string idname,
+                 list DivL,
+                 list #);
+"Internal procedure - no help and no example available
+"
+{
+//----------------------------------------------------------------------------
+// Initialization and Sanity Checks
+//----------------------------------------------------------------------------
+   int i,j,k,m,branchPos,inJ,exception;
+   string algext;
+//--- we need to be in L[2][m1]
+   def R=basering;
+   ideal test_for_the_same_ring=-77;
+   def Sm1=L[2][m1];
+   setring Sm1;
+   if(!defined(test_for_the_same_ring))
+   {
+//--- we are not in L[2][m1]
+      ERROR("basering has to coincide with L[2][m1]");
+   }
+   else
+   {
+//--- we are in L[2][m1]
+      kill test_for_the_same_ring;
+   }
+//--- non-embedded case?
+   if(size(#)>0)
+   {
+      inJ=1;
+   }
+//--- do parameter values make sense?
+   if(comPa<1)
+   {
+     ERROR("Common Parent should at least be the first ring!");
+   }
+//--- do we need to pass to an algebraic field extension of Q?
+   if(typeof(attrib(idname,"algext"))=="string")
+   {
+      algext=attrib(idname,"algext");
+   }
+//--- check wheter comPa is in the history of m1
+//--- same test for o1 can be done later on (on the fly)
+   if(m1==comPa)
+   {
+      j=1;
+      i=ncols(path)+1;
+   }
+   else
+   {
+      for(i=1;i<=ncols(path);i++)
+      {
+        if(int(leadcoef(path[1,i]))==comPa)
+        {
+//--- comPa occurs in the history
+           j=1;
+           break;
+        }
+      }
+   }
+   branchPos=i;
+   if(j==0)
+   {
+     ERROR("L[2][comPa] not in history of L[2][m1]!");
+   }
+//----------------------------------------------------------------------------
+// Blow down ideal "idname" from L[2][o1] to L[2][comPa], where the latter
+// is assumed to be the common parent of L[2][o1] and L[2][m1]
+//----------------------------------------------------------------------------
+   if(size(algext)>0)
+   {
+//--- size(algext)>0: case of algebraic extension of base field
+      if(defined(tstr)){kill tstr;}
+      string tstr="ring So1=(0,t),("+varstr(L[2][o1])+"),("+ordstr(L[2][o1])+");";
+      execute(tstr);
+      setring So1;
+      execute(algext);
+      minpoly=leadcoef(p);
+      if(defined(id1)) { kill id1; }
+      if(defined(id2)) { kill id2; }
+      if(defined(idlist)) { kill idlist; }
+      execute("int bool2=defined("+idname+");");
+      if(bool2==0)
+      {
+        execute("list ttlist=imap(L[2][o1],"+idname+");");
+      }
+      else
+      {
+        execute("list ttlist="+idname+";");
+      }
+      kill bool2;
+      def BO=imap(L[2][o1],BO);
+      def path=imap(L[2][o1],path);
+      def lastMap=imap(L[2][o1],lastMap);
+      ideal id2=1;
+      if(defined(notE)){kill notE;}
+      list notE;
+      intvec nE;
+      list idlist;
+      for(i=1;i<=size(ttlist);i++)
+      {
+         if((i==size(ttlist))&&(typeof(ttlist[i])!="string")) break;
+         execute("ideal tid="+ttlist[i]+";");
+         idlist[i]=list(tid,ideal(1),nE);
+         kill tid;
+      }
+   }
+   else
+   {
+//--- size(algext)==0: no algebraic extension of base needed
+      def So1=L[2][o1];
+      setring So1;
+      if(defined(id1)) { kill id1; }
+      if(defined(id2)) { kill id2; }
+      if(defined(idlist)) { kill idlist; }
+      execute("ideal id1="+idname+";");
+      if(deg(std(id1)[1])==0)
+      {
+//--- problems with findTrans if id1 is empty set
+//!!! todo: also correct in if branch!!!
+         setring R;
+         return(ideal(1));
+      }
+     // id1=radical(id1);
+      ideal id2=1;
+      list idlist;
+      if(defined(notE)){kill notE;}
+      list notE;
+      intvec nE;
+      idlist[1]=list(id1,id2,nE);
+   }
+   if(defined(tli)){kill tli;}
+   list tli;
+   if(defined(id1)) { kill id1; }
+   if(defined(id2)) { kill id2; }
+   ideal id1;
+   ideal id2;
+   if(defined(Etemp)){kill Etemp;}
+   ideal Etemp;
+   for(m=1;m<=size(idlist);m++)
+   {
+//!!! Duplicate Block!!! All changes also needed below!!!
+//!!! no subprocedure due to large data overhead!!!
+//--- run through all ideals to be fetched
+      id1=idlist[m][1];
+      id2=idlist[m][2];
+      nE=idlist[m][3];
+      for(i=branchPos-1;i<=size(BO[4]);i++)
+      {
+//--- run through all relevant exceptional divisors
+        if(size(reduce(BO[4][i],std(id1+BO[1])))==0)
+        {
+//--- V(id1) is contained in except. div. i in this chart
+           if(size(reduce(id1,std(BO[4][i])))!=0)
+           {
+//--- V(id1) does not equal except. div. i of this chart
+             Etemp=BO[4][i];
+             if(npars(basering)>0)
+             {
+//--- we are in an algebraic extension of the base field
+                if(defined(prtemp)){kill prtemp;}
+                list prtemp=minAssGTZ(BO[4][i]);  // C-comp. of except. div.
+                j=1;
+                if(size(prtemp)>1)
+                {
+//--- more than 1 component
+                  Etemp=ideal(1);
+                  for(j=1;j<=size(prtemp);j++)
+                  {
+//--- find correct component
+                     if(size(reduce(prtemp[j],std(id1)))==0)
+                     {
+                        Etemp=prtemp[j];
+                        break;
+                     }
+                  }
+                  if(deg(std(Etemp)[1])==0)
+                  {
+                    ERROR("fetchInTree:something wrong in field extension");
+                  }
+                }
+                prtemp=delete(prtemp,j); // remove this comp. from list
+                while(size(prtemp)>1)
+                {
+//--- collect all the others into prtemp[1]
+                  prtemp[1]=intersect(prtemp[1],prtemp[size(prtemp)]);
+                  prtemp=delete(prtemp,size(prtemp));
+                }
+             }
+//--- determine tli[1] and tli[2] such that
+//--- V(id1) \cap D(id2) = V(tli[1]) \cap D(tli[2]) \cap BO[4][i]
+//--- inside V(BO[1]) (and if necessary inside V(BO[1]+BO[2]))
+             if(inJ)
+             {
+                tli=findTrans(id1+BO[2]+BO[1],Etemp,notE,BO[2]);
+             }
+             else
+             {
+                tli=findTrans(id1+BO[1],Etemp,notE);
+             }
+             if(npars(basering)>0)
+             {
+//--- in algebraic extension: make sure we stay outside the other components
+                if(size(prtemp)>0)
+                {
+                   for(j=1;j<=ncols(prtemp[1]);j++)
+                   {
+//--- find the (univariate) generator of prtemp[1] which is the remaining
+//--- factor from the factorization over the extension field
+                      if(size(reduce(prtemp[1][j],std(id1)))>0)
+                      {
+                         tli[2]=tli[2]*prtemp[1][j];
+                      }
+                   }
+                }
+             }
+           }
+           else
+           {
+//--- V(id1) equals except. div. i of this chart
+             tli[1]=ideal(0);
+             tli[2]=ideal(1);
+           }
+           id1=tli[1];
+           id2=id2*tli[2];
+           notE[size(notE)+1]=BO[4][i];
+           for(j=1;j<=size(DivL);j++)
+           {
+              if(inIVList(intvec(o1,i),DivL[j]))
+              {
+                 nE[size(nE)+1]=j;
+                 break;
+              }
+           }
+           if(size(nE)<size(notE))
+           {
+              ERROR("fetchInTree: divisor not found in divL");
+           }
+        }
+        idlist[m][1]=id1;
+        idlist[m][2]=id2;
+        idlist[m][3]=nE;
+      }
+//!!! End of Duplicate Block !!!!
+   }
+   if(o1>1)
+   {
+      while(int(leadcoef(path[1,ncols(path)]))>=comPa)
+      {
+         if((int(leadcoef(path[1,ncols(path)]))>comPa)&&
+            (int(leadcoef(path[1,ncols(path)-1]))<comPa))
+         {
+            ERROR("L[2][comPa] not in history of L[2][o1]!");
+         }
+         def S=basering;
+         if(int(leadcoef(path[1,ncols(path)]))==1)
+         {
+//--- that's the very first ring!!!
+           int und_jetzt_raus;
+         }
+         if(defined(T)){kill T;}
+         if(size(algext)>0)
+         {
+           if(defined(T0)){kill T0;}
+           def T0=L[2][int(leadcoef(path[1,ncols(path)]))];
+           if(defined(tstr)){kill tstr;}
+           string tstr="ring T=(0,t),("
+                      +varstr(L[2][int(leadcoef(path[1,ncols(path)]))])+"),("
+                      +ordstr(L[2][int(leadcoef(path[1,ncols(path)]))])+");";
+           execute(tstr);
+           setring T;
+           execute(algext);
+           minpoly=leadcoef(p);
+           kill tstr;
+           def BO=imap(T0,BO);
+           if(!defined(und_jetzt_raus))
+           {
+              def path=imap(T0,path);
+              def lastMap=imap(T0,lastMap);
+           }
+           if(defined(idlist)){kill idlist;}
+           list idlist=list(list(ideal(1),ideal(1)));
+         }
+         else
+         {
+           def T=L[2][int(leadcoef(path[1,ncols(path)]))];
+           setring T;
+           if(defined(id1)) { kill id1; }
+           if(defined(id2)) { kill id2; }
+           if(defined(idlist)){kill idlist;}
+           list idlist=list(list(ideal(1),ideal(1)));
+         }
+         setring S;
+         if(defined(phi)) { kill phi; }
+         map phi=T,lastMap;
+//--- now do the actual blowing down ...
+         for(m=1;m<=size(idlist);m++)
+         {
+//--- ... for each entry of idlist separately
+            if(defined(id1)){kill id1;}
+            if(defined(id2)){kill id2;}
+            ideal id1=idlist[m][1]+BO[1];
+            ideal id2=idlist[m][2];
+            nE=idlist[m][3];
+            if(defined(debug_fetchInTree)>0)
+            {
+               "Blowing down entry",m,"of idlist:";
+               setring S;
+               "Abbildung:";phi;
+               "before preimage";
+               id1;
+               id2;
+            }
+            setring T;
+            ideal id1=preimage(S,phi,id1);
+            ideal id2=preimage(S,phi,id2);
+            if(defined(debug_fetchInTree)>0)
+            {
+               "after preimage";
+               id1;
+               id2;
+            }
+            if(size(id2)==0)
+            {
+//--- preimage of (principal ideal) id2 was zero, i.e.
+//--- generator of previous id2 not in image
+              setring S;
+//--- it might just be one offending factor ==> factorize
+              ideal id2factors=factorize(id2[1])[1];
+              int zzz=size(id2factors);
+              ideal curfactor;
+              setring T;
+              id2=ideal(1);
+              ideal curfactor;
+              for(int mm=1;mm<=zzz;mm++)
+              {
+//--- blow down each factor separately
+                 setring S;
+                 curfactor=id2factors[mm];
+                 setring T;
+                 curfactor=preimage(S,phi,curfactor);
+                 if(size(curfactor)>0)
+                 {
+                    id2[1]=id2[1]*curfactor[1];
+                 }
+              }
+              kill curfactor;
+              setring S;
+              kill curfactor;
+              kill id2factors;
+              setring T;
+              kill mm;
+              kill zzz;
+              if(defined(debug_fetchInTree)>0)
+              {
+                 "corrected id2:";
+                 id2;
+              }
+            }
+            idlist[m]=list(id1,id2,nE);
+            kill id1,id2;
+            setring S;
+         }
+         setring T;
+//--- after blowing down we might again be sitting inside a relevant
+//--- exceptional divisor
+         for(m=1;m<=size(idlist);m++)
+         {
+//!!! Duplicate Block!!! All changes also needed above!!!
+//!!! no subprocedure due to large data overhead!!!
+//--- run through all ideals to be fetched
+            if(defined(id1)) {kill id1;}
+            if(defined(id2)) {kill id2;}
+            if(defined(notE)) {kill notE;}
+            if(defined(notE)) {kill notE;}
+            list notE;
+            ideal id1=idlist[m][1];
+            ideal id2=idlist[m][2];
+            nE=idlist[m][3];
+            for(i=branchPos-1;i<=size(BO[4]);i++)
+            {
+//--- run through all relevant exceptional divisors
+               if(size(reduce(BO[4][i],std(id1)))==0)
+               {
+//--- V(id1) is contained in except. div. i in this chart
+                  if(size(reduce(id1,std(BO[4][i])))!=0)
+                  {
+//--- V(id1) does not equal except. div. i of this chart
+                     if(defined(Etemp)) {kill Etemp;}
+                     ideal Etemp=BO[4][i];
+                     if(npars(basering)>0)
+                     {
+//--- we are in an algebraic extension of the base field
+                        if(defined(prtemp)){kill prtemp;}
+                        list prtemp=minAssGTZ(BO[4][i]); // C-comp.except.div.
+                        if(size(prtemp)>1)
+                        {
+//--- more than 1 component
+                           Etemp=ideal(1);
+                           for(j=1;j<=size(prtemp);j++)
+                           {
+//--- find correct component
+                               if(size(reduce(prtemp[j],std(id1)))==0)
+                               {
+                                  Etemp=prtemp[j];
+                                  break;
+                               }
+                           }
+                           if(deg(std(Etemp)[1])==0)
+                           {
+                              ERROR("fetchInTree:something wrong in field extension");
+                           }
+                        }
+                        prtemp=delete(prtemp,j); // remove this comp. from list
+                        while(size(prtemp)>1)
+                        {
+//--- collect all the others into prtemp[1]
+                           prtemp[1]=intersect(prtemp[1],prtemp[size(prtemp)]);
+                           prtemp=delete(prtemp,size(prtemp));
+                        }
+                     }
+                     if(defined(tli)) {kill tli;}
+//--- determine tli[1] and tli[2] such that
+//--- V(id1) \cap D(id2) = V(tli[1]) \cap D(tli[2]) \cap BO[4][i]
+//--- inside V(BO[1]) (and if necessary inside V(BO[1]+BO[2]))
+                     if(inJ)
+                     {
+                        def tli=findTrans(id1+BO[2]+BO[1],Etemp,notE,BO[2]);
+                     }
+                     else
+                     {
+                        def tli=findTrans(id1+BO[1],Etemp,notE);
+                     }
+                    if(npars(basering)>0)
+                    {
+//--- in algebraic extension: make sure we stay outside the other components
+                      if(size(prtemp)>0)
+                      {
+                         for(j=1;j<=ncols(prtemp[1]);j++)
+                         {
+//--- find the (univariate) generator of prtemp[1] which is the remaining
+//--- factor from the factorization over the extension field
+                           if(size(reduce(prtemp[1][j],std(id1)))>0)
+                           {
+                              tli[2]=tli[2]*prtemp[1][j];
+                           }
+                         }
+                      }
+                    }
+                  }
+                  else
+                  {
+                     tli[1]=ideal(0);
+                     tli[2]=ideal(1);
+                  }
+                  id1=tli[1];
+                  id2=id2*tli[2];
+                  notE[size(notE)+1]=BO[4][i];
+                  for(j=1;j<=size(DivL);j++)
+                  {
+                     if(inIVList(intvec(o1,i),DivL[j]))
+                     {
+                        nE[size(nE)+1]=j;
+                        break;
+                     }
+                  }
+                  if(size(nE)<size(notE))
+                  {
+                     ERROR("fetchInTree: divisor not found in divL");
+                  }
+               }
+               idlist[m][1]=id1;
+               idlist[m][2]=id2;
+               idlist[m][3]=nE;
+            }
+//!!! End of Duplicate Block !!!!
+         }
+         kill S;
+         if(defined(und_jetzt_raus))
+         {
+           kill und_jetzt_raus;
+           break;
+         }
+      }
+      if(defined(debug_fetchInTree)>0)
+      {
+        "idlist after current blow down step:";
+        idlist;
+      }
+   }
+   if(defined(debug_fetchInTree)>0)
+   {
+      "Blowing down ended";
+   }
+//----------------------------------------------------------------------------
+// Blow up ideal id1 from L[2][comPa] to L[2][m1]. To this end, first
+// determine the path to follow and save it in path_togo.
+//----------------------------------------------------------------------------
+   if(m1==comPa)
+   {
+//--- no further blow ups needed
+      if(size(algext)==0)
+      {
+//--- no field extension ==> we are done
+        return(idlist[1][1]);
+      }
+      else
+      {
+//--- field extension ==> we need to encode the result
+        list retlist;
+        for(m=1;m<=size(idlist);m++)
+        {
+          retlist[m]=string(idlist[m][1]);
+        }
+        return(retlist);
+      }
+   }
+//--- we need to blow up
+   if(defined(path_m1)) { kill path_m1; }
+   matrix path_m1=imap(Sm1,path);
+   intvec path_togo;
+   for(i=1;i<=ncols(path_m1);i++)
+   {
+      if(path_m1[1,i]>=comPa)
+      {
+        path_togo=path_togo,int(leadcoef(path_m1[1,i]));
+      }
+   }
+   path_togo=path_togo[2..size(path_togo)],m1;
+   i=1;
+   while(i<size(path_togo))
+   {
+//--- we need to blow up following the path path_togo through the tree
+      def S=basering;
+      if(defined(T)){kill T;}
+      if(size(algext)>0)
+      {
+//--- in an algebraic extension of the base field
+         if(defined(T0)){kill T0;}
+         def T0=L[2][path_togo[i+1]];
+         if(defined(tstr)){kill tstr;}
+         string tstr="ring T=(0,t),(" +varstr(T0)+"),(" +ordstr(T0)+");";
+         execute(tstr);
+         setring T;
+         execute(algext);
+         minpoly=leadcoef(p);
+         kill tstr;
+         def path=imap(T0,path);
+         def BO=imap(T0,BO);
+         def lastMap=imap(T0,lastMap);
+         if(defined(phi)){kill phi;}
+         map phi=S,lastMap;
+         list idlist=phi(idlist);
+         if(defined(debug_fetchInTree)>0)
+         {
+           "in blowing up (algebraic extension case):";
+           phi;
+           idlist;
+         }
+      }
+      else
+      {
+         def T=L[2][path_togo[i+1]];
+         setring T;
+         if(defined(phi)) { kill phi; }
+         map phi=S,lastMap;
+         if(defined(idlist)) {kill idlist;}
+         list idlist=phi(idlist);
+         idlist[1][1]=radical(idlist[1][1]);
+         idlist[1][2]=radical(idlist[1][2]);
+         if(defined(debug_fetchInTree)>0)
+         {
+           "in blowing up (case without field extension):";
+           phi;
+           idlist;
+         }
+      }
+      for(m=1;m<=size(idlist);m++)
+      {
+//--- get rid of new exceptional divisor
+         idlist[m][1]=sat(idlist[m][1]+BO[1],BO[4][size(BO[4])])[1];
+         idlist[m][2]=sat(idlist[m][2],BO[4][size(BO[4])])[1];
+      }
+      if(defined(debug_fetchInTree)>0)
+      {
+        "after saturation:";
+        idlist;
+      }
+      if((size(algext)==0)&&(deg(std(idlist[1][1])[1])==0))
+      {
+//--- strict transform empty in this chart, it will stay empty till the end
+         setring Sm1;
+         return(ideal(1));
+      }
+      kill S;
+      i++;
+   }
+   if(defined(debug_fetchInTree)>0)
+   {
+      "End of blowing up steps";
+   }
+//---------------------------------------------------------------------------
+// prepare results for returning them
+//---------------------------------------------------------------------------
+   ideal E,bla;
+   intvec kv;
+   list retlist;
+   for(m=1;m<=size(idlist);m++)
+   {
+      for(j=2;j<=size(idlist[m][3]);j++)
+      {
+         kv=findInIVList(1,path_togo[size(path_togo)],DivL[idlist[m][3][j]]);
+         if(kv!=intvec(0))
+         {
+           E=E+BO[4][kv[2]];
+         }
+      }
+      bla=quotient(idlist[m][1]+E,idlist[m][2]);
+      retlist[m]=string(bla);
+   }
+   if(size(algext)==0)
+   {
+     return(bla);
+   }
+   return(retlist);
+}
+/////////////////////////////////////////////////////////////////////////////
+static proc findInIVList(int pos, int val, list ivl)
+"Internal procedure - no help and no example available
+"
+{
+//--- find entry with value val at position pos in list of intvecs
+//--- and return the corresponding entry
+   int i;
+   for(i=1;i<=size(ivl);i++)
+   {
+      if(ivl[i][pos]==val)
+      {
+         return(ivl[i]);
+      }
+   }
+   return(intvec(0));
+}
+/////////////////////////////////////////////////////////////////////////////
+//static
+proc inIVList(intvec iv, list li)
+"Internal procedure - no help and no example available
+"
+{
+//--- if intvec iv is contained in list li return 1, 0 otherwise
+  int i;
+  int s=size(iv);
+  for(i=1;i<=size(li);i++)
+  {
+     if(typeof(li[i])!="intvec"){ERROR("Not integer vector in the list");}
+     if(s==size(li[i]))
+     {
+        if(iv==li[i]){return(1);}
+     }
+  }
+  return(0);
+}
+//////////////////////////////////////////////////////////////////////////////
+static proc Vielfachheit(ideal J,ideal I)
+"Internal procedure - no help and no example available
+"
+{
+//--- auxilliary procedure for addSelfInter
+//--- compute multiplicity, suitable for the special situation there
+  int d=1;
+  int vd;
+  int c;
+  poly p;
+  ideal Ip,Jp;
+  while((d>0)||(!vd))
+  {
+     p=randomLast(100)[nvars(basering)];
+     Ip=std(I+ideal(p));
+     c++;
+     if(c>20){ERROR("Vielfachheit: Dimension is wrong");}
+     d=dim(Ip);
+     vd=vdim(Ip);
+  }
+  Jp=std(J+ideal(p));
+  return(vdim(Jp) div vdim(Ip));
+}
+/////////////////////////////////////////////////////////////////////////////
+static proc genus_E(list re, list iden0, intvec Eindex)
+"Internal procedure - no help and no example available
+"
+{
+   int i,ge,gel,num;
+   def R=basering;
+   ring Rhelp=0, at t,dp;
+   def S=re[2][Eindex[1]];
+   setring S;
+   def Sh=S+Rhelp;
+//----------------------------------------------------------------------------
+//--- The Q-component X is reducible over C, decomposes into s=num components
+//--- X_i, we assume they have n.c.
+//---           s*g(X_i)=g(X)+s-1.
+//----------------------------------------------------------------------------
+   if(defined(I2)){kill I2;}
+   ideal I2=dcE[Eindex[2]][Eindex[3]][1];
+   num=ncols(dcE[Eindex[2]][Eindex[3]][4]);
+   setring Sh;
+   if(defined(I2)){kill I2;}
+   ideal I2=imap(S,I2);
+   I2=homog(I2, at t);
+   ge=genus(I2);
+   gel=(ge+(num-1)) div num;
+   if(gel*num-ge-num+1!=0){ERROR("genus_E: not divisible by num");}
+   setring R;
+   return(gel,num);
+}
+
diff --git a/Singular/LIB/ring.lib b/Singular/LIB/ring.lib
new file mode 100644
index 0000000..1719812
--- /dev/null
+++ b/Singular/LIB/ring.lib
@@ -0,0 +1,1127 @@
+/////////////////////////////////////////////////////////////////////////////
+version="version ring.lib 4.0.0.0 Jun_2013 "; // $Id: b79382d36002167ce4e4fb927264d970b1ac2af4 $
+category="General purpose";
+info="
+LIBRARY:  ring.lib      Manipulating Rings and Maps
+AUTHORS: Singular team
+
+PROCEDURES:
+ changechar(c[,r]); make a copy of basering [ring r] with new char c
+ changeord(o[,r]);  make a copy of basering [ring r] with new ord o
+ changevar(v[,r]);  make a copy of basering [ring r] with new vars v
+ defring(\"R\",c,n,v,o);  define a ring R in specified char c, n vars v, ord o
+ defrings(n[,p]);         define ring Sn in n vars, char 32003 [p], ord ds
+ defringp(n[,p]);         define ring Pn in n vars, char 32003 [p], ord dp
+ extendring(\"R\",n,v,o); extend given ring by n vars v, ord o and name it R
+ fetchall(R[,str]);       fetch all objects of ring R to basering
+ imapall(R[,str]);        imap all objects of ring R to basering
+ mapall(R,i[,str]);       map all objects of ring R via ideal i to basering
+ ord_test(R);             test wether ordering of R is global, local or mixed
+ ringtensor(s,t,..);      create ring, tensor product of rings s,t,...
+ ringweights(r);          intvec of weights of ring variables of ring r
+ preimageLoc(R,phi,Q)     computes preimage for non-global orderings
+ rootofUnity(n);          the minimal polynomial for the n-th primitive root of unity
+             (parameters in square brackets [] are optional)
+ optionIsSet(opt)         check if as a string given option is set or not.
+ hasFieldCoefficient      check if the coefficient ring is considered a field
+ hasGFCoefficient         check if the coefficient ring is GF(p,k)
+ hasNumericCoeffs(rng)    check for use of floating point numbers
+ hasCommutativeVars(rng)  non-commutive or commnuative polynomial ring
+ hasGlobalOrdering(rng)   global versus mixed/local monomial ordering
+ hasMixedOrdering()       mixed versus global/local ordering
+ hasFieldCoefficient(rng) coefficients are a field
+ isQuotientRing(rng)      ring is a qotient ring
+ isSubModule(I,J)         check if I is in J as submodule
+";
+
+LIB "inout.lib";
+LIB "general.lib";
+LIB "primdec.lib";
+
+///////////////////////////////////////////////////////////////////////////////
+proc optionIsSet(string optionName)
+"
+USAGE:       optionIsSet( optionName )
+PARAMETERS:  optionName: a name as string of an option of interest
+RETURN:      true, if the by optionName given option is active, false otherwise.
+EXAMPLE:     example optionIsSet;
+"
+{
+   intvec op = option(get);
+   //sanity check, if option is valid. will raise an error if not
+   option(optionName);    option("no" + optionName);
+   option(set,op);
+   // first entry is currently a comment "//options:", which is not an option.
+   int pos = find(option(), optionName, 11 );
+   return(pos>0);
+}
+example
+{
+    // check if the option "warn" is set.
+    optionIsSet("warn");
+    option("warn");
+    // now the option is set
+    optionIsSet("warn");
+
+    option("nowarn");
+    // now the option is unset
+    optionIsSet("warn");
+}
+
+
+static proc testOptionIsSet()
+{
+     option("warn");
+     ASSUME(0, optionIsSet("warn") );
+     option("nowarn");
+     ASSUME(0, 0 == optionIsSet("warn") );
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc changechar (list @L, list #)
+"USAGE:   changechar(c[,r]);  c=list, r=ring
+RETURN:  ring R, obtained from the ring r [default: r=basering], by changing
+         ringlist(r)[1] to c.
+EXAMPLE: example changechar; shows an example
+"
+{
+   def save_ring=basering;
+   if( size(#)==0 ) { def @r=basering; }
+   if(( size(#)==1 ) and (typeof(#[1])=="ring")) { def @r=#[1]; }
+   setring @r;
+   list rl=ringlist(@r);
+   if(defined(@L)!=voice) { def @L=fetch(save_ring, at L); }
+   if (size(@L)==1) { rl[1]=@L[1];} else { rl[1]=@L;}
+   def Rnew=ring(rl);
+   setring save_ring;
+   return(Rnew);
+}
+example
+{  "EXAMPLE:"; echo = 2;
+   ring rr=2,A,dp;
+   ring r=0,(x,y,u,v),(dp(2),ds);
+   def R=changechar(ringlist(rr)); R;"";
+   def R1=changechar(32003,R); setring R1; R1;
+   kill R,R1;
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc changeord (list @o, list #)
+"USAGE:   changeord(neword[,r]);  newordstr=list, r=ring/qring
+RETURN:  ring R, obtained from the ring r [default: r=basering], by changing
+         order(r) to neword.
+         If, say, neword=list(list(\"wp\",intvec(2,3)),list(list(\"dp\",1:(n-2))));
+         and if the ring r exists and has n variables, the ring R will be
+         equipped with the monomial ordering wp(2,3),dp.
+EXAMPLE: example changeord; shows an example
+"
+{
+   def save_ring=basering;
+   if( size(#)==0 ) { def @r=basering; }
+   if( size(#)==1 ) { def @r=#[1]; }
+   setring @r;
+   list rl=ringlist(@r);
+   rl[3]=@o;
+   def Rnew=ring(rl);
+   setring save_ring;
+   return(Rnew);
+}
+example
+{  "EXAMPLE:"; echo = 2;
+   ring r=0,(x,y,u,v),(dp(2),ds);
+   def R=changeord(list(list("wp",intvec(2,3)),list("dp",1:2))); R; "";
+   ideal i = x^2,y^2-u^3,v;
+   qring Q = std(i);
+   def Q'=changeord(list(list("lp",nvars(Q))),Q); setring Q'; Q';
+   kill R,Q,Q';
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc changevar (string vars, list #)
+"USAGE:   changevar(vars[,r]);  vars=string, r=ring/qring
+RETURN:  ring R, obtained from the ring r [default: r=basering], by changing
+         varstr(r) according to the value of vars.
+         If, say, vars = \"t()\" and the ring r exists and has n
+         variables, the new basering will have name R and variables
+         t(1),...,t(n).
+         If vars = \"a,b,c,d\", the new ring will have the variables a,b,c,d.
+NOTE:    This procedure is useful in connection with the procedure ringtensor,
+         when a conflict between variable names must be avoided.
+         This proc uses 'execute' or calls a procedure using 'execute'.
+EXAMPLE: example changevar; shows an example
+"
+{
+   if( size(#)==0 ) { def @r=basering; }
+   if( size(#)==1 ) { def @r=#[1]; }
+   setring @r;
+   ideal i = ideal(@r); int @q = size(i);
+   if( @q!=0 )
+      { string @s = "Rnew1"; }
+   else
+      { string @s = "Rnew"; }
+   string @newring = @s+"=("+charstr(@r)+"),(";
+   if( vars[size(vars)-1]=="(" and vars[size(vars)]==")" )
+   {
+      @newring = @newring+vars[1,size(vars)-2]+"(1.."+string(nvars(@r))+")";
+   }
+   else { @newring = @newring+vars; }
+   @newring = @newring+"),("+ordstr(@r)+");";
+   execute("ring "+ at newring);
+   if( @q!=0 )
+   {
+      map phi = @r,maxideal(1);
+      ideal i = phi(i);
+      attrib(i,"isSB",1);         //*** attrib funktioniert ?
+      qring Rnew=i;
+   }
+   return(Rnew);
+}
+example
+{  "EXAMPLE:"; echo = 2;
+   ring r=0,(x,y,u,v),(dp(2),ds);
+   ideal i = x^2,y^2-u^3,v;
+   qring Q = std(i);
+   setring(r);
+   def R=changevar("A()"); R; "";
+   def Q'=changevar("a,b,c,d",Q); setring Q'; Q';
+   kill R,Q,Q';
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc defring (string s2, int n, string s3, string s4)
+"USAGE:   defring(ch,n,va,or);  ch,va,or=strings, n=integer
+RETURN:  ring R with characteristic 'ch', ordering 'or' and n variables with
+         names derived from va.
+         If va is a single letter, say va=\"a\", and if n<=26 then a and the
+         following n-1 letters from the alphabet (cyclic order) are taken as
+         variables. If n>26 or if va is a single letter followed by a bracket,
+         say va=\"T(\", the variables are T(1),...,T(n).
+NOTE:    This proc is useful for defining a ring in a procedure.
+         This proc uses 'execute' or calls a procedure using 'execute'.
+EXAMPLE: example defring; shows an example
+"
+{
+   string @newring = "ring newring =("+s2+"),(";
+   if( n>26 or s3[2]=="(" ) { string @v = s3[1]+"(1.."+string(n)+")"; }
+   else { string @v = A_Z(s3,n); }
+   @newring=@newring+ at v+"),("+s4+");";
+   execute(@newring);
+   return(newring);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   def r=defring("0",5,"u","ls"); r; setring r;"";
+   def R=defring("2,A",10,"x(","dp(3),ws(1,2,3),ds"); R; setring R;
+   kill R,r;
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc defrings (int n, list #)
+"USAGE:   defrings(n,[p]);  n,p integers
+RETURN:  ring R with characteristic p [default: p=32003], ordering ds and n
+         variables x,y,z,a,b,...if n<=26 (resp. x(1..n) if n>26)
+NOTE:    This proc uses 'execute' or calls a procedure using 'execute'.
+EXAMPLE: example defrings; shows an example
+"
+{
+   int p;
+   if (size(#)==0) { p=32003; }
+   else { p=#[1]; }
+   if (n >26)
+   {
+      string s="ring S ="+string(p)+",x(1.."+string(n)+"),ds;";
+   }
+   else
+   {
+      string s="ring S ="+string(p)+",("+A_Z("x",n)+"),ds;";
+   }
+   execute(s);
+   dbprint(printlevel-voice+2,"
+// 'defrings' created a ring. To see the ring, type (if the name R was
+// assigned to the return value):
+    show R;
+// To make the ring the active basering, type
+    setring R; ");
+   return(S);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   def S5=defrings(5,0); S5; "";
+   def S30=defrings(30); S30;
+   kill S5,S30;
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc defringp (int n,list #)
+"USAGE:   defringp(n,[p]);  n,p=integers
+RETURN:  ring R with characteristic p [default: p=32003], ordering dp and n
+         variables x,y,z,a,b,...if n<=26 (resp. x(1..n) if n>26)
+NOTE:    This proc uses 'execute' or calls a procedure using 'execute'.
+EXAMPLE: example defringp; shows an example
+"
+{
+   int p;
+   if (size(#)==0) { p=32003; }
+   else { p=#[1]; }
+   if (n >26)
+   {
+      string s="ring P="+string(p)+",x(1.."+string(n)+"),dp;";
+   }
+   else
+   {
+     string s="ring P="+string(p)+",("+A_Z("x",n)+"),dp;";
+   }
+   execute(s);
+   dbprint(printlevel-voice+2,"
+// 'defringp' created a ring. To see the ring, type (if the name R was
+// assigned to the return value):
+    show R;
+// To make the ring the active basering, type
+    setring R; ");
+   return(P);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   def P5=defringp(5,0); P5; "";
+   def P30=defringp(30); P30;
+   kill P5,P30;
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc extendring (int n, string va, string o, list #)
+"USAGE:   extendring(n,va,o[,iv,i,r]);  va,o=strings, n,i=integers, r=ring,
+          iv=intvec of positive integers or iv=0
+RETURN:  ring R, which extends the ring r by adding n new variables in front
+         of (resp. after, if i!=0) the old variables.
+         [default: (i,r)=(0,basering)].
+@*       -- The characteristic is the characteristic of r.
+@*       -- The new vars are derived from va. If va is a single letter, say
+            va=\"T\", and if n<=26 then T and the following n-1 letters from
+            T..Z..T (resp. T(1..n) if n>26) are taken as additional variables.
+            If va is a single letter followed by a bracket, say va=\"x(\",
+            the new variables are x(1),...,x(n).
+@*       -- The ordering is the product ordering of the ordering of r and of an
+            ordering derived from `o` [and iv].
+@*        -  If o contains a 'c' or a 'C' in front resp. at the end, this is
+            taken for the whole ordering in front, resp. at the end. If o does
+            not contain a 'c' or a 'C' the same rule applies to ordstr(r).
+@*        -  If no intvec iv is given, or if iv=0, o may be any allowed ordstr,
+            like \"ds\" or \"dp(2),wp(1,2,3),Ds(2)\" or \"ds(a),dp(b),ls\" if
+            a and b are globally (!) defined integers and if a+b+1<=n.
+            If, however, a and b are local to a proc calling extendring, the
+            intvec iv must be used to let extendring know the values of a and b
+@*        -  If a non-zero intvec iv is given, iv[1],iv[2],... are taken for the
+            1st, 2nd,... block of o, if o contains no substring \"w\" or \"W\"
+            i.e. no weighted ordering (in the above case o=\"ds,dp,ls\"
+            and iv=a,b).
+            If o contains a weighted ordering (only one (!) weighted block is
+            allowed) iv[1] is taken as size for the weight-vector, the next
+            iv[1] values of iv are taken as weights and the remaining values of
+            iv as block size for the remaining non-weighted blocks.
+            e.g. o=\"dp,ws,Dp,ds\", iv=3,2,3,4,2,5 creates the ordering
+            dp(2),ws(2,3,4),Dp(5),ds
+NOTE:    This proc is useful for adding deformation parameters.
+         This proc uses 'execute' or calls a procedure using 'execute'.
+         If you use it in your own proc, it may be advisable to let the local
+         names of your proc start with a @
+EXAMPLE: example extendring; shows an example
+"
+{
+//--------------- initialization and place c/C of ordering properly -----------
+   string @o1, at o2, at ro, at wstr, at v, at newring;
+   int @i, at w, at ii, at k;
+   intvec @iv, at iw;
+   if( find(o,"c")+find(o,"C") != 0)
+   {
+      @k=1;
+      if( o[1]=="c" or o[1]=="C" ) { @o1=o[1,2]; o=o[3..size(o)]; }
+      else                         { @o2=o[size(o)-1,2]; o=o[1..size(o)-2]; }
+   }
+   if( size(#)==0 ) { #[1]=0; }
+   if( typeof(#[1])!="intvec" )
+   {
+     if( size(#)==1 ) { @i=#[1]; def @r=basering; }
+     if( size(#)==2 ) { @i=#[1]; def @r=#[2]; }
+     if( o[size(o)]!=")" and find(o,",")==0 ) { o=o+"("+string(n)+")"; }
+   }
+   else
+   {
+     @iv=#[1];
+     if( size(#)==2 ) { @i=#[2]; def @r=basering; }
+     if( size(#)==3 ) { @i=#[2]; def @r=#[3]; }
+     if( @iv==0 && o[size(o)]!=")" && find(o,",")==0 ) {o=o+"("+string(n)+")";}
+   }
+   @ro=ordstr(@r);
+   if( @ro[1]=="c" or @ro[1]=="C" )
+      { @v=@ro[1,2]; @ro=@ro[3..size(@ro)]; }
+   else
+      { @wstr=@ro[size(@ro)-1,2]; @ro=@ro[1..size(@ro)-2]; }
+   if( @k==0) { @o1=@v; @o2=@wstr; }
+//----------------- prepare ordering if an intvec is given --------------------
+   if( typeof(#[1])=="intvec" and #[1]!=0 )
+   {
+      @k=n;                             //@k counts no of vars not yet ordered
+      @w=find(o,"w")+find(o,"W");o=o+" ";
+      if( @w!=0 )
+      {
+         @wstr=o[@w.. at w+1];
+         o=o[1, at w-1]+"@"+o[@w+2,size(o)];
+         @iw=@iv[2.. at iv[1]+1];
+         @wstr=@wstr+"("+string(@iw)+")";
+         @k=@k- at iv[1];
+         @iv=@iv[@iv[1]+2..size(@iv)];
+         @w=0;
+      }
+      for( @ii=1; @ii<=size(@iv); @ii=@ii+1 )
+      {
+         if( find(o,",", at w+1)!=0 )
+         {
+            @w=find(o,",", at w+1);
+            if( o[@w-1]!="@" )
+            {
+               o=o[1, at w-1]+"("+string(@iv[@ii])+")"+o[@w,size(o)];
+               @w=find(o,",", at w+1);
+               @k=@k- at iv[@ii];
+            }
+            else { @ii=@ii-1; }
+         }
+      }
+      @w=find(o,"@");
+      if( @w!=0 ) { o=o[1, at w-1] + @wstr + o[@w+1,size(o)]; }
+      if( @k>0 and o[size(o)]!=")" ) { o=o+"("+string(@k)+")"; }
+   }
+//------------------------ prepare string of new ring -------------------------
+   @newring = "ring na =("+charstr(@r)+"),(";
+   if( n>26 or va[2]=="(" ) { @v = va[1]+"(1.."+string(n)+")"; }
+   else                     { @v = A_Z(va,n); }
+   if( @i==0 )
+   {
+      @v=@v+","+varstr(@r);
+      o=@o1+o+","+ at ro+@o2;
+   }
+   else
+   {
+      @v=varstr(@r)+","+ at v;
+      o=@o1+ at ro+","+o+ at o2;
+   }
+   @newring=@newring+ at v+"),("+o+");";
+//---------------------------- execute and export -----------------------------
+   execute(@newring);
+   dbprint(printlevel-voice+2,"
+// 'extendring' created a new ring.
+// To see the ring, type (if the name 'R' was assigned to the return value):
+     show(R);
+");
+
+   return(na);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r=0,(x,y,z),ds;
+   show(r);"";
+   // blocksize is derived from no of vars:
+   int t=5;
+   def R1=extendring(t,"a","dp");         //t global: "dp" -> "dp(5)"
+   show(R1); setring R1; "";
+   def R2=extendring(4,"T(","c,dp",1,r);    //"dp" -> "c,..,dp(4)"
+   show(R2); setring R2; "";
+
+   // no intvec given, blocksize given: given blocksize is used:
+   def R3=extendring(4,"T(","dp(2)",0,r);   // "dp(2)" -> "dp(2)"
+   show(R3); setring R3; "";
+
+   // intvec given: weights and blocksize is derived from given intvec
+   // (no specification of a blocksize in the given ordstr is allowed!)
+   // if intvec does not cover all given blocks, the last block is used
+   // for the remaining variables, if intvec has too many components,
+   // the last ones are ignored
+   intvec v=3,2,3,4,1,3;
+   def R4=extendring(10,"A","ds,ws,Dp,dp",v,0,r);
+   // v covers 3 blocks: v[1] (=3) : no of components of ws
+   // next v[1] values (=v[2..4]) give weights
+   // remaining components of v are used for the remaining blocks
+   show(R4);
+   kill r,R1,R2,R3,R4;
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc fetchall (def R, list #)
+"USAGE:   fetchall(R[,s]);  R=ring/qring, s=string
+CREATE:  fetch all objects of ring R (of type poly/ideal/vector/module/number/matrix)
+         into the basering.
+         If no 2nd argument is present, the names are the same as in R. If,
+         say, f is a polynomial in R and the 2nd argument is the string \"R\", then f
+         is mapped to f_R etc.
+RETURN:  no return value
+NOTE:    As fetch, this procedure maps the 1st, 2nd, ... variable of R to the
+         1st, 2nd, ... variable of the basering.
+         The 2nd argument is useful in order to avoid conflicts of names, the
+         empty string is allowed
+CAUTION: fetchall does not work for locally defined names.
+         It does not work if R contains a map.
+SEE ALSO: imapall
+EXAMPLE: example fetchall; shows an example
+"
+{
+   list @L@=names(R);
+   int @ii@; string @s@;
+   if( size(#) > 0 ) { @s@=@s at +"_"+#[1]; }
+   for( @ii@=size(@L@); @ii@>0; @ii at -- )
+   {
+      execute("def "+ at L@[@ii@]+ at s@+"=fetch(R,`@L@[@ii@]`);");
+      execute("export "+ at L@[@ii@]+ at s@+";");
+   }
+   return();
+}
+example
+{  "EXAMPLE:"; echo=2;
+// The example is not shown since fetchall does not work in a procedure;
+// (and hence not in the example procedure). Try the following commands:
+//   ring R=0,(x,y,z),dp;
+//   ideal j=x,y2,z2;
+//   matrix M[2][3]=1,2,3,x,y,z;
+//   j; print(M);
+//   ring S=0,(a,b,c),ds;
+//   fetchall(R);       //map from R to S: x->a, y->b, z->c;
+//   names(S);
+//   j; print(M);
+//   fetchall(S,"1");   //identity map of S: copy objects, change names
+//   names(S);
+//   kill R,S;
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc imapall (def R, list #)
+"USAGE:   imapall(R[,s]);  R=ring/qring, s=string
+CREATE:  map all objects of ring R (of type poly/ideal/vector/module/number/matrix)
+         into the basering by applying imap to all objects of R.
+         If no 2nd argument is present, the names are the same as in R. If,
+         say, f is a polynomial in R and the 3rd argument is the string \"R\", then f
+         is mapped to f_R etc.
+RETURN:  no return value
+NOTE:    As imap, this procedure maps the variables of R to the variables with
+         the same name in the basering, the other variables are mapped to 0.
+         The 2nd argument is useful in order to avoid conflicts of names, the
+         empty string is allowed
+CAUTION: imapall does not work for locally defined names.
+         It does not work if R contains a map
+SEE ALSO: fetchall
+EXAMPLE: example imapall; shows an example
+"
+{
+   list @L@=names(R);
+   int @ii@; string @s@;
+   if( size(#) > 0 ) { @s@=@s at +"_"+#[1]; }
+   for( @ii@=size(@L@); @ii@>0; @ii at -- )
+   {
+         execute("def "+ at L@[@ii@]+ at s@+"=imap(R,`@L@[@ii@]`);");
+         execute("export "+ at L@[@ii@]+ at s@+";");
+   }
+   return();
+}
+example
+{  "EXAMPLE:"; echo = 2;
+// The example is not shown since imapall does not work in a procedure
+// (and hence not in the example procedure). Try the following commands:
+//   ring R=0,(x,y,z,u),dp;
+//   ideal j=x,y,z,u2+ux+z;
+//   matrix M[2][3]=1,2,3,x,y,uz;
+//   j; print(M);
+//   ring S=0,(a,b,c,x,z,y),ds;
+//   imapall(R);         //map from R to S: x->x, y->y, z->z, u->0
+//   names(S);
+//   j; print(M);
+//   imapall(S,"1");     //identity map of S: copy objects, change names
+//   names(S);
+//   kill R,S;
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc mapall (def R, ideal i, list #)
+"USAGE:   mapall(R,i[,s]);  R=ring/qring, i=ideal of basering, s=string
+CREATE:  map all objects of ring R (of type poly/ideal/vector/module/number/
+         matrix, map) into the basering by mapping the j-th variable of R to
+         the j-th generator of the ideal i. If no 3rd argument is present, the
+         names are the same as in R. If, say, f is a polynomial in R and the 3rd
+         argument is the string \"R\", then f is mapped to f_R etc.
+RETURN:  no return value.
+NOTE:    This procedure has the same effect as defining a map, say psi, by
+         map psi=R,i; and then applying psi to all objects of R. In particular,
+         maps from R to some ring S are composed with psi, creating thus a map
+         from the basering to S.
+         mapall may be combined with copyring to change vars for all objects.
+         The 3rd argument is useful in order to avoid conflicts of names, the
+         empty string is allowed.
+CAUTION: mapall does not work for locally defined names.
+EXAMPLE: example mapall; shows an example
+"
+{
+   list @L@=names(R); map @psi@ = R,i;
+   int @ii@; string @s@;
+   if( size(#) > 0 ) { @s@=@s at +"_"+#[1]; }
+   for( @ii@=size(@L@); @ii@>0; @ii at -- )
+   {
+      execute("def "+ at L@[@ii@]+ at s@+"=@psi@(`@L@[@ii@]`);");
+      execute("export "+ at L@[@ii@]+ at s@+";");
+   }
+   return();
+}
+example
+{  "EXAMPLE:"; echo = 2;
+// The example is not shown since mapall does not work in a procedure
+// (and hence not in the example procedure). Try the following commands:
+//   ring R=0,(x,y,z),dp;
+//   ideal j=x,y,z;
+//   matrix M[2][3]=1,2,3,x,y,z;
+//   map phi=R,x2,y2,z2;
+//   ring S=0,(a,b,c),ds;
+//   ideal i=c,a,b;
+//   mapall(R,i);         //map from R to S: x->c, y->a, z->b
+//   names(S);
+//   j; print(M); phi;    //phi maps R to S: x->c2, y->a2, z->b2
+//   ideal i1=a2,a+b,1;
+//   mapall(R,i1,\"\");     //map from R to S: x->a2, y->a+b, z->1
+//   names(S);
+//   j_; print(M_); phi_;
+//   changevar(\"T\",\"x()\",R);  //change vars in R and call result T
+//   mapall(R,maxideal(1));   //identity map from R to T
+//   names(T);
+//   j; print(M); phi;
+//   kill R,S,T;
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc ord_test (def r)
+"USAGE:   ord_test(r);  r ring/qring
+RETURN:  int 1 (resp. -1, resp. 0) if ordering of r is global (resp. local,
+         resp. mixed)
+SEE ALSO: attrib
+EXAMPLE: example ord_test; shows an example
+"
+{
+   if ((typeof(r) != "ring") and (typeof(r) != "qring"))
+   {
+      ERROR("ord_test requires a ring/qring as input");
+   }
+   if (attrib(r,"global")==1) { return(1);}
+   def BAS = basering;
+   setring r;
+   poly f;
+   int n,o,u = nvars(r),1,1;
+   int ii;
+   for ( ii=1; ii<=n; ii++ )
+   {
+      f = 1+var(ii);
+      o = o*(lead(f) == var(ii));
+      u = u*(lead(f) == 1);
+   }
+   setring BAS;
+   if ( o==1 ) { return(1); }
+   if ( u==1 ) { return(-1); }
+   else { return(0); }
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring R = 0,(x,y),dp;
+   ring S = 0,(u,v),ls;
+   ord_test(R);
+   ord_test(S);
+   ord_test(R+S);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc ringtensor (list #)
+"USAGE:   ringtensor(r1,r2,...);  r1,r2,...=rings
+RETURN:  ring R whose variables are the variables from all rings r1,r2,...
+         and whose monomial ordering is the block (product) ordering of the
+         respective monomial orderings of r1,r2,... . Hence, R
+         is the tensor product of the rings r1,r2,... with ordering matrix
+         equal to the direct sum of the ordering matrices of r1,r2,...
+NOTE:    The characteristic of the new ring will be p if one ring has
+         characteristic p. The names of variables in the rings r1,r2,...
+         must differ.
+         The procedure works also for quotient rings ri, if the characteristic
+         of ri is compatible with the characteristic of the result
+         (i.e. if imap from ri to the result is implemented)
+SEE ALSO: ring operations
+EXAMPLE: example ringtensor; shows an example
+"
+{
+   int @i;
+   int @n = size(#);
+   if (@n<=1) { ERROR("at least 2 rings required"); }
+   def @s=#[1]+#[2];
+   for (@i=3; @i<=@n;@i++)
+   {
+     def @ss=@s+#[@i];
+     kill @s;
+     def @s=@ss;
+     kill @ss;
+   }
+   dbprint(printlevel-voice+2,"
+// 'ringtensor' created a ring. To see the ring, type (if the name R was
+// assigned to the return value):
+    show(R);
+// To make the ring the active basering, type
+    setring R; ");
+   return(@s);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r=32003,(x,y,u,v),dp;
+   ring s=0,(a,b,c),wp(1,2,3);
+   ring t=0,x(1..5),(c,ls);
+   def R=ringtensor(r,s,t);
+   type R;
+   setring s;
+   ideal i = a2+b3+c5;
+   def S=changevar("x,y,z");       //change vars of s
+   setring S;
+   qring qS =std(fetch(s,i));      //create qring of S mod i (mapped to S)
+   def T=changevar("d,e,f,g,h",t); //change vars of t
+   setring T;
+   qring qT=std(d2+e2-f3);         //create qring of T mod d2+e2-f3
+   def Q=ringtensor(s,qS,t,qT);
+   setring Q; type Q;
+   kill R,S,T,Q;
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc ringweights (def P)
+"USAGE:   ringweights(P); P=name of an existing ring (true name, not a string)
+RETURN:  intvec consisting of the weights of the variables of P, as they
+         appear when typing P;.
+NOTE:    This is useful when enlarging P but keeping the weights of the old
+         variables.
+EXAMPLE: example ringweights; shows an example
+"
+{
+   int i;
+   intvec rw;
+//------------------------- find weights  -------------------------
+   for(i=nvars(P);i>0;i--)
+   { rw[i]=ord(var(i)); }
+   return(rw);
+}
+example
+{"EXAMPLE:";  echo = 2;
+  ring r0 = 0,(x,y,z),dp;
+  ringweights(r0);
+  ring r1 = 0,x(1..5),(ds(3),wp(2,3));
+  ringweights(r1);"";
+  // an example for enlarging the ring, keeping the first weights:
+  intvec v = ringweights(r1),6,2,3,4,5;
+  ring R = 0,x(1..10),(a(v),dp);
+  ordstr(R);
+}
+///////////////////////////////////////////////////////////////////////////////
+proc preimageLoc(string R_name,string phi_name,string Q_name )
+"USAGE: preimageLoc ( ring_name, map_name, ideal_name );
+        all input parameters of type string
+RETURN:  ideal
+PURPOSE: compute the preimage of an ideal under a given map for non-global
+         orderings.
+         The 2nd argument has to be the name of a map from the basering to
+         the given ring (or the name of an ideal defining such a map), and
+         the ideal has to be an ideal in the given ring.
+SEE ALSO: preimage
+KEYWORDS: preimage under a map between local rings, map between local rings, map between local and global rings
+EXAMPLE: example preimageLoc ; shows an example
+"{
+  def S=basering;
+  int i;
+  string newRing,minpoly_string;
+  if(attrib(S,"global")!=1)
+  {
+    if(typeof(S)=="qring")
+    {
+      ideal I=ideal(S);
+      newRing="ring S0=("+charstr(S)+"),("+varstr(S)+"),dp;";
+      minpoly_string=string(minpoly);
+      execute(newRing);
+      execute("minpoly="+minpoly_string+";");
+      ideal I=imap(S,I);
+      list pr=primdecGTZ(I);
+      newRing="ring SL=("+charstr(S)+"),("+varstr(S)+"),("+ordstr(S)+");";
+      execute(newRing);
+      execute("minpoly="+minpoly_string+";");
+      list pr=imap(S0,pr);
+      ideal I0=std(pr[1][1]);
+      for(i=2;i<=size(pr);i++)
+      {
+         I0=intersect(I0,std(pr[i][1]));
+      }
+      setring S0;
+      ideal I0=imap(SL,I0);
+      qring S1=std(I0);
+    }
+    else
+    {
+      def S1=S;
+    }
+  }
+  else
+  {
+    def S1=S;
+  }
+  def @R=`R_name`;
+  setring @R;
+  def @phi=`phi_name`;
+  ideal phiId=ideal(@phi);
+  def Q=`Q_name`;
+  if(attrib(@R,"global")!=1)
+  {
+    if(typeof(@R)=="qring")
+    {
+      ideal J=ideal(@R);
+      newRing="ring R0=("+charstr(@R)+"),("+varstr(@R)+"),dp;";
+      minpoly_string=string(minpoly);
+      execute(newRing);
+      execute("minpoly="+minpoly_string+";");
+      ideal J=imap(@R,J);
+      list pr=primdecGTZ(J);
+      newRing="ring RL=("+charstr(@R)+"),("+varstr(@R)+"),("+ordstr(@R)+");";
+      execute(newRing);
+      execute("minpoly="+minpoly_string+";");
+      list pr=imap(R0,pr);
+      ideal J0=std(pr[1][1]);
+      for(i=2;i<=size(pr);i++)
+      {
+         J0=intersect(J0,std(pr[i][1]));
+      }
+      setring R0;
+      ideal J0=imap(RL,J0);
+      qring R1=std(J0);
+      ideal Q=imap(@R,Q);
+      map @phi=S1,imap(@R,phiId);
+    }
+    else
+    {
+      def R1=@R;
+    }
+  }
+  else
+  {
+    def R1=@R;
+  }
+  setring S1;
+  ideal preQ=preimage(R1, at phi,Q);
+  setring S;
+  ideal prQ=imap(S1,preQ);
+  return(prQ);
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring S =0,(x,y,z),dp;
+  ring R0=0,(x,y,z),ds;
+  qring R=std(x+x2);
+  map psi=S,x,y,z;
+  ideal null;
+  setring S;
+  ideal nu=preimageLoc("R","psi","null");
+  nu;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+/* moved here from the nctools.lib */
+///////////////////////////////////////////////////////////////////////////////
+proc rootofUnity(int n)
+"USAGE:  rootofUnity(n); n an integer
+RETURN:  number
+PURPOSE: compute the minimal polynomial for the n-th primitive root of unity
+NOTE: works only in field extensions by one element
+EXAMPLE: example rootofUnity; shows examples
+"
+{
+  if ( npars(basering) !=1 )
+  {
+    ERROR(" the procedure works only with one ring parameter variable");
+  }
+  if (n<0) {  ERROR(" cannot compute ("+string(n)+")-th primitive root of unity"); }
+  if (n==0) { return(number(0));}
+  number mp = par(1);
+  if (n==1) { return(mp-1); }
+  if (n==2) { return(mp+1); }
+  def OldRing = basering;
+  string CH = charstr(basering);
+  string MCH;
+  int j=1;
+  while ( (CH[j] !=",") && (j<=size(CH)))
+  {
+    MCH=MCH+CH[j]; j++;
+  }
+  string SR = "ring @@rR="+MCH+","+parstr(basering)+",dp;";
+  execute(SR);
+  poly @t=var(1)^n-1; // (x^2i-1)=(x^i-1)(x^i+1)
+  list l=factorize(@t);
+  ideal @l=l[1];
+  list @d;
+  int s=size(@l);
+  int d=deg(@l[s]);
+  int cnt=1;
+  poly res;
+  for (j=s-1; j>=1; j--)
+  {
+    if ( deg(@l[j]) > d) { d=deg(@l[j]); }
+  }
+  for (j=1; j<=s; j++)
+  {
+    if ( deg(@l[j]) == d) { @d[cnt]=@l[j]; cnt++; }
+  }
+
+  j=1;
+  int i;
+  number pw;
+
+  int @sized = size(@d);
+
+  if (@sized==1)
+  {
+       setring OldRing;
+       list @rl = imap(@@rR, at d);
+       mp = number(@rl[1]);
+       kill @@rR;
+       return(mp);
+  }
+  def @rng;
+
+  setring OldRing;
+
+  list rl = ringlist( OldRing);
+  while ( j<=@sized )
+  {
+     ASSUME(0, n%2 ==0);
+     setring OldRing;
+     @rng = ring(rl);
+     setring @rng;
+     list @rl = imap(@@rR, at d);
+     number mp = leadcoef( @rl[j] );
+     minpoly = mp;
+     number mp = minpoly;
+     number pw = par(1)^(n div 2);
+     if ( (pw != 1) || n==1 )  {  break;  }
+     j = j+1;
+  }
+  setring OldRing;
+  list @rl=imap(@@rR, at d);
+  mp = leadcoef( @rl[j] );
+  kill @@rR;
+  return(mp);
+}
+example
+{
+  "EXAMPLE:";echo=2;
+  ring r = (0,q),(x,y,z),dp;
+  rootofUnity(6);
+  rootofUnity(7);
+  minpoly = rootofUnity(8);
+  r;
+}
+
+
+
+
+proc isQuotientRing(def rng )
+"USAGE: isQuotientRing ( rng );
+RETURN:  1 if rng is a quotient ring, 0 otherwise.
+PURPOSE: check if typeof a rng "qring"
+KEYWORDS: qring ring ideal 'factor ring'
+EXAMPLE: example isQuotientRing ; shows an example
+"
+{
+    if ( defined(basering) )  {   def BAS=basering;  }
+
+    //access to quotient ideal will fail, if basering and rng differs.
+    setring rng;
+    int result =  ( size(ideal(rng)) != 0);
+
+    if ( defined(BAS) )   {    setring BAS;   }
+
+    return (result);
+}
+example
+{
+  ring rng = 0,x,dp;
+  isQuotientRing(rng); //no
+  // if a certain method does not support quotient rings,
+  // then a parameter test could be performed:
+   ASSUME( 0, 0==isQuotientRing(basering));
+
+  qring q= ideal(x);  // constructs rng/ideal(x)
+  isQuotientRing(q);  // yes
+}
+
+static proc testIsQuotientRing()
+{
+   ring rng7 = 7, x, dp;
+
+   ring rng = real,x,dp;
+   ASSUME(0, 0== isQuotientRing(rng) ) ;
+   ASSUME(0, 0== isQuotientRing(rng7) ) ;
+   ASSUME(0, char(basering)==0); // check that basering was not changed
+
+   qring qrng = 1;
+   ASSUME(0, isQuotientRing(qrng) ) ;
+
+   ring rng2 = integer,x,dp;
+   ASSUME(0, 0 == isQuotientRing(rng2) ) ;
+
+   qring qrng2=0;
+   ASSUME(0, not isQuotientRing(qrng2) ) ;
+
+   ring rng3 = 0,x,dp;
+   ASSUME(0, 0 == isQuotientRing(rng3) ) ;
+
+   qring qrng3=1;
+   ASSUME(0, isQuotientRing(qrng3) ) ;
+}
+
+proc hasFieldCoefficient(def rng )
+"USAGE: hasFieldCoefficient ( rng );
+RETURN:  1 if the coeffcients form a field, 0 otherwise.
+KEYWORDS: ring coefficients
+EXAMPLE: example hasFieldCoefficient; shows an example
+"
+{
+  return (attrib(rng,"ring_cf")==0);
+}
+example
+{
+  ring rng = integer,x,dp;
+  hasFieldCoefficient(rng); //no
+  // if a certain method supports only rings with integer coefficients,
+  // then a parameter test could be performed:
+  ring rng2 = 0, x, dp;
+  hasFieldCoefficient(rng2);  // yes
+}
+
+proc hasGFCoefficient(def rng )
+"USAGE: hasGFCoefficient ( rng );
+RETURN:  1 if the coeffcients form GF(p,k), 0 otherwise.
+KEYWORDS: ring coefficients
+EXAMPLE: example hasGFCoefficient; shows an example
+"
+{
+  return((charstr(rng)!=string(char(rng))) &&
+  (npars(rng)==1) &&
+  (find(charstr(rng),string(char(rng)))!=1) &&
+  (charstr(basering)<>"real")&&
+  (charstr(basering)<>"complex") );
+}
+example
+{
+  ring r1 = integer,x,dp;
+  hasGF(r1);
+  ring r2 = (4,a),x,dp;
+  hasGF(r2);
+}
+
+proc hasGlobalOrdering (def rng)
+"USAGE: hasGlobalOrdering ( rng );
+RETURN:  1 if rng has a global monomial ordering, 0 otherwise.
+KEYWORDS: monomial ordering
+EXAMPLE: example hasGlobalOrdering; shows an example
+"
+{
+  return (attrib(rng,"global")==1);
+}
+example
+{
+  ring rng = integer,x,dp;
+  hasGlobalOrdering(rng); //yes
+  ring rng2 = 0, x, ds;
+  hasGlobalOrdering(rng2);  // no
+}
+
+proc hasCommutativeVars (def rng)
+"USAGE: hasCommutativeVars ( rng );
+RETURN:  1 if rng is a commutative polynomial ring, 0 otherwise.
+KEYWORDS: plural
+EXAMPLE: example hasCommutativeVars; shows an example
+"
+{
+  list rl=ringlist(rng);
+  return (size(rl)==4);
+}
+example
+{
+ ring r=0,(x,y,z),dp;
+ hasCommutativeVars(r);
+}
+
+proc hasNumericCoeffs(def rng)
+"USAGE: hasNumericCoeffs ( rng );
+RETURN:  1 if rng has inexact coeffcients, 0 otherwise.
+KEYWORDS: floating point
+EXAMPLE: example hasNumericCoeffs; shows an example
+"
+{
+  ERROR("not yet implemented");
+}
+
+proc isSubModule(def I,def J)
+"USAGE: isSubModule(I,J): I, J: ideal or module
+RETURN: 1 if module(I) is in module(J), 0 otherwise
+EXAMPLE: isSubModule; shows an example
+{
+  if (attrib(J,"isSB")==1)
+  { return(size(reduce(I,J,1))==0); }
+  else
+  { return(size(reduce(I,groebner(J),1))==0); }
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r=0,x,dp;
+  ideal I1=x2;
+  ideal I2=x3;
+  isSubModule(I1, I2);
+  isSubModule(I2, I1);
+}
+
+proc hasMixedOrdering()
+"USAGE:  hasMixedOrdering();
+RETURN:  1 if ordering of basering is mixed, 0 else
+EXAMPLE: example hasMixedOrdering(); shows an example
+"
+{
+   int i,p,m;
+   for(i = 1; i <= nvars(basering); i++)
+   {
+      if(var(i) > 1)
+      {
+         p++;
+      }
+      else
+      {
+         m++;
+      }
+   }
+   if((p > 0) && (m > 0)) { return(1); }
+   return(0);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring R1 = 0,(x,y,z),dp;
+   hasMixedOrdering();
+   ring R2 = 31,(x(1..4),y(1..3)),(ds(4),lp(3));
+   hasMixedOrdering();
+   ring R3 = 181,x(1..9),(dp(5),lp(4));
+   hasMixedOrdering();
+}
+
+proc changeordTo(def r,string o)
+{
+  list rl=ringlist(r);
+  rl[3]=list(list("C",0),list(o,1:nvars(r)));
+  def rr=ring(rl);
+  return(rr);
+}
+example
+{
+  ring r=0,(x,y),lp;
+  def rr=changeordToCdp(r,"dp");
+  rr;
+}
+
diff --git a/Singular/LIB/ringgb.lib b/Singular/LIB/ringgb.lib
new file mode 100644
index 0000000..f27186b
--- /dev/null
+++ b/Singular/LIB/ringgb.lib
@@ -0,0 +1,343 @@
+/////////////////////////////////////////////////////////////////////////////
+version="version ringgb.lib 4.0.0.0 Jun_2013 "; // $Id: 4ddabf56c4914ebf04eacb3a180c200e78759fee $
+category="Miscellaneous";
+info="
+LIBRARY:  ringgb.lib     Functions for coefficient rings
+AUTHOR:  Oliver Wienand, email: wienand at mathematik.uni-kl.de
+
+KEYWORDS: vanishing polynomial; zeroreduce; polynomial functions; library, ringgb.lib; ringgb.lib, functions for coefficient rings
+
+PROCEDURES:
+ findZeroPoly(f);        finds a vanishing polynomial for reducing f
+ zeroReduce(f);          normal form of f concerning the ideal of vanishing polynomials
+ testZero(poly f);       tests f defines the constant zero function
+ noElements(def r);      the number of elements of the coefficient ring, if of type (integer, ...)
+";
+
+LIB "general.lib";
+///////////////////////////////////////////////////////////////////////////////
+
+proc findZeroPoly (poly f)
+"USAGE:   findZeroPoly(f); f - a polynomial
+RETURN:  zero polynomial with the same leading term as f if exists, otherwise 0
+EXAMPLE: example findZeroPoly; shows an example
+"
+{
+  list data = getZeroCoef(f);
+  if (data[1] == 0)
+  {
+    return(0);
+  }
+  number q = leadcoef(f) / data[1];
+  if (q == 0)
+  {
+    return(0);
+  }
+  poly g = getZeroPolyRaw(data[2]);
+  g = leadmonom(f) / leadmonom(g) * g;
+  return(q * data[1] * g);
+  //return(system("findZeroPoly", f));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring r = (integer, 65536), (y,x), dp;
+  poly f = 1024*x^8*y^2+11264*x^8*y+28672*x^8+45056*x^7*y^2+36864*x^7*y+16384*x^7+40960*x^6*y^2+57344*x^6*y+32768*x^6+30720*x^5*y^2+10240*x^5*y+8192*x^5+35840*x^4*y^2+1024*x^4*y+20480*x^4+30720*x^3*y^2+10240*x^3*y+8192*x^3+4096*x^2*y^2+45056*x^2*y+49152*x^2+40960*x*y^2+57344*x*y+32768*x;
+  findZeroPoly(f);
+}
+
+proc zeroReduce(poly f, list #)
+"USAGE:   zeroReduce(f, [i = 0]); f - a polynomial, i - noise level (if != 0 prints all steps)
+RETURN:  reduced normal form of f modulo zero polynomials
+EXAMPLE: example zeroReduce; shows an example
+"
+{
+   int i = 0;
+   if (size(#) > 0)
+   {
+     i = #[1];
+   }
+   poly h = f;
+   poly n = 0;
+   poly g = findZeroPoly(h);
+   if (i <> 0) {
+     printf("reducing polyfct  : %s", h);
+   }
+   while ( h <> 0 ) {
+      while ( g <> 0 ) {
+         h = h - g;
+         if (i <> 0) {
+            printf(" reduce with: %s", g);
+            printf(" to: %s", h);
+         }
+         g = findZeroPoly(h);
+      }
+      n = lead(h) + n;
+      if (i <> 0) {
+         printf("head irreducible  : %s", lead(h));
+         printf("irreducible start : %s", n);
+         printf("remains to check  : %s", h - lead(h));
+      }
+      h = h - lead(h);
+      g = findZeroPoly(h);
+   }
+   return(n);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring r = (integer, 65536), (y,x), dp;
+  poly f = 1024*x^8*y^2+11264*x^8*y+28672*x^8+45056*x^7*y^2+36864*x^7*y+16384*x^7+40960*x^6*y^2+57344*x^6*y+32768*x^6+30720*x^5*y^2+10240*x^5*y+8192*x^5+35840*x^4*y^2+1024*x^4*y+20480*x^4+30720*x^3*y^2+10240*x^3*y+8192*x^3+4096*x^2*y^2+45056*x^2*y+49152*x^2+40960*x*y^2+57344*x*y+32768*x;
+  zeroReduce(f);
+  kill r;
+  ring r = (integer, 2, 32), (x,y,z), dp;
+  // Polynomial 1:
+  poly p1 = 3795162112*x^3+587202566*x^2*y+2936012853*x*y*z+2281701376*x+548767119*y^3+16777216*y^2+268435456*y*z+1107296256*y+4244635648*z^3+4244635648*z^2+16777216*z;
+  // Polynomial 2:
+  poly p2 = 1647678464*x^3+587202566*x^2*y+2936012853*x*y*z+134217728*x+548767119*y^3+16777216*y^2+268435456*y*z+1107296256*y+2097152000*z^3+2097152000*z^2+16777216*z;
+  zeroReduce(p1-p2);
+}
+
+proc testZero(poly f)
+"USAGE:   testZero(f); f - a polynomial
+RETURN:  returns 1 if f is zero as a function and otherwise a counterexample as a list [f(x_1, ..., x_n), x_1, ..., x_n]
+EXAMPLE: example testZero; shows an example
+"
+{
+  poly g;
+  int j;
+  bigint i = 0;
+  bigint modul = noElements(basering);
+  printf("Teste %s Belegungen ...", modul^nvars(basering));
+  for (; i < modul^nvars(basering); i = i + 1)
+  {
+    if ((i + 1) % modul^(nvars(basering)/2) == 0)
+    {
+      printf("bisher: %s", i);
+    }
+    g = f;
+    for (j = 1; j <= nvars(basering); j++)
+    {
+      g = subst(g, var(j), number((i / modul^(j-1)) % modul));
+    }
+    if (g != 0)
+    {
+      list counter = g;
+      for (j = 1; j <= nvars(basering); j++)
+      {
+        counter = insert(counter, (i / modul^(j-1)) % modul);
+      }
+      return(counter);
+    }
+  }
+  return(1);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring r = (integer, 12), (y,x), dp;
+  poly f = 1024*x^8*y^2+11264*x^8*y+28672*x^8+45056*x^7*y^2+36864*x^7*y+16384*x^7+40960*x^6*y^2+57344*x^6*y+32768*x^6+30720*x^5*y^2+10240*x^5*y+8192*x^5+35840*x^4*y^2+1024*x^4*y+20480*x^4+30720*x^3*y^2+10240*x^3*y+8192*x^3+4096*x^2*y^2+45056*x^2*y+49152*x^2+40960*x*y^2+57344*x*y+32768*x;
+  zeroReduce(f);
+  testZero(f);
+  poly g = findZeroPoly(x2y3);
+  g;
+  testZero(g);
+}
+
+proc noElements(def r)
+"USAGE:   noElements(r); r - a ring with a finite coefficient ring of type integer
+RETURN:  returns the number of elements of the coefficient ring of r
+EXAMPLE: example noElements; shows an example
+"
+
+{
+  list l = ringlist(basering);
+  return(l[1][2][1]^l[1][2][2]);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring r = (integer, 233,6), (y,x), dp;
+  noElements(r);
+}
+
+static proc getZeroCoef(poly f)
+{
+  if (f == 0)
+  {
+    return(0, leadexp(f))
+  }
+  list data = sort(leadexp(f));
+  intvec exp = data[1];
+  intvec index = data[2];
+  intvec nec = 0:size(exp);
+  int i = 1;
+  int j = 2;
+  bigint g;
+  bigint G = 1;
+  bigint modul = noElements(basering);
+  bigint B = modul;
+
+  for (; exp[i] < 2; i++) {if (i == size(exp)) break;}
+  for (; i <= size(exp); i++)
+  {
+    g = gcd(B, G);
+    G = G * g;
+    B = B / g;
+    if (g != 1)
+    {
+      nec[index[i]] = j - 1;
+    }
+    if (B == 1)
+    {
+      return(B, nec);
+    }
+    for (; j <= exp[i]; j++)
+    {
+      g = gcd(B, bigint(j));
+      G = G * g;
+      B = B / g;
+      if (g != 1)
+      {
+        nec[index[i]] = j;
+      }
+      if (B == 1)
+      {
+        return(B, nec);
+      }
+    }
+  }
+  if (B == modul)
+  {
+    nec = 0;
+    return(0, nec);
+  }
+  return(B, nec);
+}
+
+static proc getZeroPolyRaw(intvec fexp)
+{
+  list data = sort(fexp);
+  intvec exp = data[1];
+  intvec index = data[2];
+  int j = 0;
+  poly res = 1;
+  poly tillnow = 1;
+  int i = 1;
+  for (; exp[i] < 2; i++) {if (i == size(exp)) break;}
+  for (; i <= size(exp); i++)
+  {
+    for (; j < exp[i]; j++)
+    {
+      tillnow = tillnow * (var(1) - j);
+    }
+    res = res * subst(tillnow, var(1), var(index[i]));
+  }
+  return(res);
+}
+
+static proc getZeroPoly(poly f)
+{
+  list data = getZeroCoef(f);
+  poly g = getZeroPolyRaw(data[2]);
+  g = leadmonom(f) / leadmonom(g) * g;
+  return(data[1] * g);
+}
+
+static proc findZeroPolyWrap (poly f)
+"USAGE:   findZeroPolyWrap(f); f - a polynomial
+RETURN:  zero polynomial with the same leading term as f if exists, otherwise 0
+NOTE:    just a wrapper, work only in Z/2^n with n < int_machine_size - 1
+EXAMPLE: example findZeroPoly; shows an example
+"
+{
+  return(system("findZeroPoly", f));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring r = (integer, 2, 16), (y,x), dp;
+  poly f = 1024*x^8*y^2+11264*x^8*y+28672*x^8+45056*x^7*y^2+36864*x^7*y+16384*x^7+40960*x^6*y^2+57344*x^6*y+32768*x^6+30720*x^5*y^2+10240*x^5*y+8192*x^5+35840*x^4*y^2+1024*x^4*y+20480*x^4+30720*x^3*y^2+10240*x^3*y+8192*x^3+4096*x^2*y^2+45056*x^2*y+49152*x^2+40960*x*y^2+57344*x*y+32768*x;
+  findZeroPoly(f);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+/*
+                           Examples:
+
+
+// POLYNOMIAL EXAMPLES (Singular ready)
+// ===================
+//
+// For each of the examples below, there are three equivalent polynomials. 'm' indicates the bit-widths of the
+// input/output variables. For some of the polynomials, I have attached the RTL as well.
+//
+//
+// 1) VOLTERRA MODELS:
+//
+//        A) CUBIC FILTER: (m = 32, 3 Vars)
+
+LIB "ringgb.lib";
+ring r = (integer, 2, 32), (x,y,z), dp;
+poly p1 = 3795162112*x^3+587202566*x^2*y+2936012853*x*y*z+2281701376*x+548767119*y^3+16777216*y^2+268435456*y*z \
+         +1107296256*y+4244635648*z^3+4244635648*z^2+16777216*z;
+poly p2 = 1647678464*x^3+587202566*x^2*y+2936012853*x*y*z+134217728*x+548767119*y^3+16777216*y^2+268435456*y*z \
+         +1107296256*y+2097152000*z^3+2097152000*z^2+16777216*z;
+poly p3 = 1647678464*x^3+587202566*x^2*y+2936012853*x*y*z+134217728*x+548767119*y^3+16777216*y^2+268435456*y*z \
+         +1107296256*y+2097152000*z^3+2097152000*z^2+16777216*z;
+zeroReduce(p1-p2);
+zeroReduce(p1-p3);
+zeroReduce(p2-p3);
+
+//        B) DEGREE-4 FILTER: (m=16 , 3 Vars)
+
+LIB "ringgb.lib";
+ring r = (integer, 2, 16), (x,y,z), dp;
+poly p1 = 16384*x^4+y^4+57344*z^4+64767*x*y^3+16127*y^2*z^2+8965*x^3*z+19275*x^2*y*z+51903*x*y*z+32768*x^2*y  \
+         +40960*z^2+32768*x*y^2+49152*x^2+4869*y;
+poly p2 = 8965*x^3*z+19275*x^2*y*z+31999*x*y^3+51903*x*y*z+32768*x*y+y^4+32768*y^3+16127*y^2*z^2+32768*y^2 \
+         +4869*y+57344*z^4+40960*z^2;
+poly p3 = 8965*x^3*z+19275*x^2*y*z+31999*x*y^3+51903*x*y*z+32768*x*y+y^4+16127*y^2*z^2+4869*y+16384*z^3+16384*z;
+zeroReduce(p1-p2);
+zeroReduce(p1-p3);
+zeroReduce(p2-p3);
+
+
+// 2) Savitzsky Golay filter(m=16,5 Vars)
+
+LIB "ringgb.lib";
+ring r = (integer, 2, 16), (v,w,x,y,z), dp;
+poly p1 = 25000*v^2*y+37322*v^2+22142*v*w*z+50356*w^3+58627*w^2+17797*w+17797*x^3+62500*x^2*z+41667*x \
+         +22142*y^3+23870*y^2+59464*y+41667*z+58627;
+poly p2 = 25000*v^2*y+4554*v^2+22142*v*w*z+32768*v+17588*w^3+25859*w^2+17797*w+17797*x^3+29732*x^2*z+32768*x^2 \
+         +32768*x*z+8899*x+22142*y^3+23870*y^2+59464*y+41667*z+58627;
+poly p3 = 25000*v^2*y+4554*v^2+22142*v*w*z+32768*v+17588*w^3+25859*w^2+17797*w+17797*x^3+29732*x^2*z+32768*x*z \
+         +41667*x+22142*y^3+23870*y^2+59464*y+41667*z+58627;
+zeroReduce(p1-p2);
+zeroReduce(p1-p3);
+zeroReduce(p2-p3);
+
+
+// 3) Anti-alias filter:(m=16, 1 Var)
+
+LIB "ringgb.lib";
+ring r = (integer, 2, 16), c, dp;
+poly p1 = 156*c^6+62724*c^5+17968*c^4+18661*c^3+43593*c^2+40224*c+13281;
+poly p2 = 156*c^6+5380*c^5+1584*c^4+43237*c^3+27209*c^2+40224*c+13281;
+poly p3 = 156*c^6+5380*c^5+1584*c^4+10469*c^3+27209*c^2+7456*c+13281;
+zeroReduce(p1-p2);
+zeroReduce(p1-p3);
+zeroReduce(p2-p3);
+
+
+// 4) PSK:(m=16, 2 Var)
+
+LIB "ringgb.lib";
+ring r = (integer, 2, 16), (x,y), dp;
+poly p1 = 4166*x^4+16666*x^3*y+25000*x^2*y^2+15536*x^2+16666*x*y^4+31072*x*y+4166*y^4+15536*y^2+34464;
+poly p2 = 4166*x^4+16666*x^3*y+8616*x^2*y^2+16384*x^2*y+15536*x^2+282*x*y^4+47456*x*y+53318*y^4+31920*y^2+34464;
+poly p3 = 4166*x^4+16666*x^3*y+8616*x^2*y^2+16384*x^2*y+15536*x^2+282*x*y^4+47456*x*y+4166*y^4+15536*y^2+34464;
+zeroReduce(p1-p2);
+zeroReduce(p1-p3);
+zeroReduce(p2-p3);
+
+// Ref: A. Peymandoust G. De Micheli, �Application of Symbolic Computer Algebra in High-Level Data-Flow
+// Synthesis,� IEEE Transactions on CAD/ICAS, Vol. 22, No. 9, September 2003, pp.1154-1165.
+
+*/
diff --git a/Singular/LIB/rinvar.lib b/Singular/LIB/rinvar.lib
new file mode 100644
index 0000000..ffb91ae
--- /dev/null
+++ b/Singular/LIB/rinvar.lib
@@ -0,0 +1,1116 @@
+/////////////////////////////////////////////////////////////////////////////
+version="version rinvar.lib 4.0.0.0 Jun_2013 "; // $Id: 143e8248a86d04df3bdc9070fbeda733ca84e5ee $
+category="Invariant theory";
+info="
+LIBRARY:  rinvar.lib      Invariant Rings of Reductive Groups
+AUTHOR:   Thomas Bayer,   tbayer at in.tum.de
+          http://wwwmayr.informatik.tu-muenchen.de/personen/bayert/
+          Current Address: Institut fuer Informatik, TU Muenchen
+OVERVIEW:
+ Implementation based on Derksen's algorithm. Written in the scope of the
+ diploma thesis (advisor: Prof. Gert-Martin Greuel) 'Computations of moduli
+ spaces of semiquasihomogenous singularities and an implementation in Singular'
+
+PROCEDURES:
+ HilbertSeries(I, w);           Hilbert series of the ideal I w.r.t. weight w
+ HilbertWeights(I, w);          weighted degrees of the generators of I
+ ImageVariety(I, F);            ideal of the image variety F(variety(I))
+ ImageGroup(G, F);              ideal of G w.r.t. the induced representation
+ InvariantRing(G, Gaction);     generators of the invariant ring of G
+ InvariantQ(f, G, Gaction);     decide if f is invariant w.r.t. G
+ LinearizeAction(G, Gaction);   linearization of the action 'Gaction' of G
+ LinearActionQ(action,s,t);     decide if action is linear in var(s..nvars)
+ LinearCombinationQ(base, f);   decide if f is in the linear hull of 'base'
+ MinimalDecomposition(f,s,t);   minimal decomposition of f (like coef)
+ NullCone(G, act);              ideal of the nullcone of the action 'act' of G
+ ReynoldsImage(RO,f);           image of f under the Reynolds operator 'RO'
+ ReynoldsOperator(G, Gaction);  Reynolds operator of the group G
+ SimplifyIdeal(I[,m,s]);        simplify the ideal I (try to reduce variables)
+
+SEE ALSO: qhmoduli_lib, zeroset_lib
+";
+
+LIB "presolve.lib";
+LIB "elim.lib";
+LIB "zeroset.lib";
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc EquationsOfEmbedding(ideal embedding, int nrs)
+"USAGE:   EquationsOfEmbedding(embedding, s); ideal embedding; int s;
+PURPOSE: compute the ideal of the variety parameterized by 'embedding' by
+         implicitation and change the variables to the old ones.
+RETURN:  ideal
+ASSUME:  nvars(basering) = n, size(embedding) = r and s = n - r.
+         The polynomials of embedding contain only var(s + 1 .. n).
+NOTE:    the result is the Zariski closure of the parameterized variety
+EXAMPLE: example  EquationsOfEmbedding; shows an example
+"
+{
+  ideal tvars;
+
+  for(int i = nrs + 1; i <= nvars(basering); i++) { tvars[i - nrs] = var(i); }
+
+  def RE1 = ImageVariety(ideal(0), embedding);  // implicitation of the parameterization
+  // map F = RE1, tvars;
+        map F = RE1, maxideal(1);
+  return(F(imageid));
+}
+example
+{"EXAMPLE:";  echo = 2;
+  ring R   = 0,(s(1..5), t(1..4)),dp;
+  ideal emb = t(1), t(2), t(3), t(3)^2;
+  ideal I = EquationsOfEmbedding(emb, 5);
+  I;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc ImageGroup(ideal Grp, ideal Gaction)
+"USAGE:   ImageGroup(G, action); ideal G, action;
+PURPOSE: compute the ideal of the image of G in GL(m,K) induced by the linear
+         action 'action', where G is an algebraic group and 'action' defines
+         an action of G on K^m (size(action) = m).
+RETURN:  ring, a polynomial ring over the same ground field as the basering,
+         containing the ideals 'groupid' and 'actionid'.
+         - 'groupid' is the ideal of the image of G (order <= order of G)
+         - 'actionid' defines the linear action of 'groupid' on K^m.
+NOTE:    'action' and 'actionid' have the same orbits
+         all variables which give only rise to 0's in the m x m matrices of G
+         have been omitted.
+ASSUME:  basering K[s(1..r),t(1..m)] has r + m variables, G is the ideal of an
+         algebraic group and F is an action of G on K^m. G contains only the
+         variables s(1)...s(r). The action 'action' is given by polynomials
+         f_1,...,f_m in basering, s.t. on the ring level we have
+         K[t_1,...,t_m] --> K[s_1,...,s_r,t_1,...,t_m]/G
+         t_i   -->  f_i(s_1,...,s_r,t_1,...,t_m)
+EXAMPLE: example ImageGroup; shows an example
+"
+{
+  int i, j, k, newVars, nrt, imageSize, dbPrt;
+  ideal matrixEntries;
+  matrix coMx;
+  poly tVars;
+  string ringSTR1, ringSTR2, order;
+
+  dbPrt = printlevel-voice+2;
+  dbprint(dbPrt, "Image Group of " + string(Grp) + ", action =  "
+                                   + string(Gaction));
+  def RIGB = basering;
+  string @mPoly = string(minpoly);
+  tVars = 1;
+  k = 0;
+
+  // compute the representation of G induced by Gaction, i.e., a matrix
+  // of size(Gaction) x size(Gaction) and polynomials in s(1),...,s(r) as
+  // entries
+  // the matrix is represented as the list 'matrixEntries' where
+  // the entries which are always 0 are omittet.
+
+  for(i = 1; i <= ncols(Gaction); i++) {
+    tVars = tVars * var(i + nvars(basering) - ncols(Gaction));
+  }
+  for(i = 1; i <= ncols(Gaction); i++){
+    coMx = coef(Gaction[i], tVars);
+    for(j = 1; j <= ncols(coMx); j++){
+      k++;
+      matrixEntries[k] = coMx[2, j];
+    }
+  }
+  newVars = size(matrixEntries);
+  nrt = ncols(Gaction);
+
+  // this matrix defines an embedding of G into GL(m, K).
+  // in the next step the ideal of this image is computed
+  // note that we have omitted all variables which give give rise
+  // only to 0's. Note that z(1..newVars) are slack variables
+
+  order = "(dp(" + string(nvars(basering)) + "), dp);";
+  ringSTR1 = "ring RIGR = (" + charstr(basering) + "), (" + varstr(basering)
+                             + ", z(1.." + string(newVars) + "))," + order;
+  execute(ringSTR1);
+  execute("minpoly = number(" + @mPoly + ");");
+  ideal I1, I2, Gn, G, F, mEntries, newGaction;
+  G = imap(RIGB, Grp);
+  F = imap(RIGB, Gaction);
+  mEntries = imap(RIGB, matrixEntries);
+
+  // prepare the ideals needed to compute the image
+  // and compute the new action of the image on K^m
+
+  for(i=1;i<=size(mEntries);i++){ I1[i] = var(i + nvars(RIGB))-mEntries[i]; }
+  I1 = std(I1);
+
+  for(i = 1; i <= ncols(F); i++) { newGaction[i] = reduce(F[i], I1); }
+  I2 = G, I1;
+  I2 = std(I2);
+  Gn = nselect(I2, 1.. nvars(RIGB));
+  imageSize = ncols(Gn);
+
+  // create a new basering which might contain more variables
+  // s(1..newVars) as the original basering and map the ideal
+  // Gn (contians only z(1..newVars)) to this ring
+
+  ringSTR2 = "ring RIGS = (" + charstr(basering) + "), (s(1.."
+                     + string(newVars) + "), t(1.." + string(nrt) + ")), lp;";
+  execute(ringSTR2);
+  execute("minpoly = number(" + @mPoly + ");");
+  ideal mapIdeal, groupid, actionid;
+  int offset;
+
+  // construct the map F : RIGB -> RIGS
+
+  for(i=1;i<=nvars(RIGB)-nrt;i++) { mapIdeal[i] = 0;}            // s(i)-> 0
+  offset = nvars(RIGB) - nrt;
+  for(i=1;i<=nrt;i++) { mapIdeal[i+offset] = var(newVars + i);}  // t(i)->t(i)
+  offset = offset + nrt;
+  for(i=1;i<=newVars;i++) { mapIdeal[i + offset] = var(i);}      // z(i)->s(i)
+
+  // map Gn and newGaction to RIGS
+
+  map F = RIGR, mapIdeal;
+  groupid = F(Gn);
+  actionid = F(newGaction);
+  export groupid, actionid;
+  dbprint(dbPrt+1, "
+// 'ImageGroup' created a new ring.
+// To see the ring, type (if the name 'R' was assigned to the return value):
+     show(R);
+// To access the ideal of the image of the input group and to access the new
+// action of the group, type
+     setring R;  groupid; actionid;
+");
+  setring RIGB;
+  return(RIGS);
+}
+example
+{"EXAMPLE:";  echo = 2;
+  ring B   = 0,(s(1..2), t(1..2)),dp;
+  ideal G = s(1)^3-1, s(2)^10-1;
+  ideal action = s(1)*s(2)^8*t(1), s(1)*s(2)^7*t(2);
+  def R = ImageGroup(G, action);
+  setring R;
+  groupid;
+  actionid;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc HilbertWeights(ideal I,intvec wt)
+"USAGE:   HilbertWeights(I, w); ideal I, intvec wt
+PURPOSE: compute the weights of the "slack" variables needed for the
+         computation of the algebraic relations of the generators of 'I' s.t.
+         the Hilbert driven 'std' can be used.
+RETURN: intvec
+ASSUME: basering = K[t_1,...,t_m,...], 'I' is quasihomogenous w.r.t. 'w' and
+        contains only polynomials in t_1,...,t_m
+"
+{
+  int offset = size(wt);
+  intvec wtn = wt;
+
+  for(int i = 1; i <= size(I); i++) { wtn[offset + i] = deg(I[i], wt); }
+  return(wtn);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc HilbertSeries(ideal I,intvec wt)
+"USAGE:   HilbertSeries(I, w); ideal I, intvec wt
+PURPOSE: compute the polynomial p of the Hilbert Series, represented by p/q, of
+         the ring K[t_1,...,t_m,y_1,...,y_r]/I1 where 'w' are the weights of
+         the variables, computed, e.g., by 'HilbertWeights', 'I1' is of the
+         form I[1] - y_1,...,I[r] - y_r and is quasihomogenous w.r.t. 'w'
+RETURN:  intvec
+NOTE:    the leading 0 of the result does not belong to p, but is needed in
+         the Hilbert driven 'std'.
+"
+{
+  int i;
+  intvec hs1;
+  matrix coMx;
+  poly f = 1;
+
+  for(i = 1; i <= ncols(I); i++) { f = f * (1 - var(1)^deg(I[i], wt));}
+  coMx = coeffs(f, var(1));
+  for(i = 1; i <= deg(f) + 1; i++) {
+    hs1[i] = int(coMx[i, 1]);
+  }
+  hs1[size(hs1) + 1] = 0;
+  return(hs1);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc HilbertSeries1(wt)
+"USAGE:   HilbertSeries1(wt); ideal I, intvec wt
+PURPOSE: compute the polynomial p of the Hilbert Series represented by p/q of
+         the ring K[t_1,...,t_m,y_1,...,y_r]/I where I is a complete inter-
+         section and the generator I[i] has degree wt[i]
+RETURN:  poly
+"
+{
+  int i, j;
+  intvec hs1;
+  matrix ma;
+  poly f = 1;
+
+  for(i = 1; i <= size(wt); i++) { f = f * (1 - var(1)^wt[i]);}
+  ma = coef(f, var(1));
+  j = ncols(ma);
+  for(i = 0; i <= deg(f); i++) {
+    if(var(1)^i == ma[1, j]) {
+      hs1[i + 1] = int(ma[2, j]);
+      j--;
+    }
+    else { hs1[i + 1] = 0; }
+  }
+  hs1[size(hs1) + 1] = 0;
+  return(hs1);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc ImageVariety(ideal I,ideal F, list #)
+"USAGE:   ImageVariety(ideal I, F [, w]);ideal I; F is a list/ideal, intvec w.
+PURPOSE: compute the Zariski closure of the image of the variety of I under
+         the morphism F.
+NOTE:    if 'I' and 'F' are quasihomogenous w.r.t. 'w' then the Hilbert-driven
+         'std' is used.
+RETURN:  polynomial ring over the same ground field, containing the ideal
+         'imageid'. The variables are Y(1),...,Y(k) where k = size(F)
+         - 'imageid' is the ideal of the Zariski closure of F(X) where
+           X is the variety of I.
+EXAMPLE: example ImageVariety; shows an example
+"
+{
+  int i, dbPrt, nrNewVars;
+  intvec wt, wth, hs1;
+  string ringSTR1, ringSTR2, order;
+
+  def RARB = basering;
+  nrNewVars = size(F);
+
+  dbPrt = printlevel-voice+2;
+  dbprint(dbPrt, "ImageVariety of " + string(I) + " under the map " + string(F));
+
+  if(size(#) > 0) { wt = #[1]; }
+
+  // create new ring for elimination, Y(1),...,Y(m) are slack variables.
+
+  string @mPoly = string(minpoly);
+  order = "(dp(" + string(nvars(basering)) + "), dp);";
+  ringSTR1 = "ring RAR1 = (" + charstr(basering) + "), (" + varstr(basering) + ", Y(1.." + string(nrNewVars) + ")), " + order;
+  ringSTR2 = "ring RAR2 = (" + charstr(basering) + "), Y(1.." + string(nrNewVars) + "), dp;";
+  execute(ringSTR1);
+  execute("minpoly = number(" + @mPoly + ");");
+
+  ideal I, J1, J2, Fm;
+
+  I = imap(RARB, I);
+  Fm = imap(RARB, F);
+
+  if(size(wt) > 1) {
+    wth = HilbertWeights(Fm, wt);
+    hs1 = HilbertSeries(Fm, wt);
+  }
+
+  // get the ideal of the graph of F : X -> Y and compute a standard basis
+
+  for(i = 1; i <= nrNewVars; i++) { J1[i] = var(i + nvars(RARB)) - Fm[i];}
+  J1 = J1, I;
+  if(size(wt) > 1) {
+    J1 = std(J1, hs1, wth);  // Hilbert-driven algorithm
+  }
+  else {
+    J1 = std(J1);
+  }
+
+  // forget all elements which contain other than the slack variables
+
+  J2 = nselect(J1, 1.. nvars(RARB));
+
+  execute(ringSTR2);
+  execute("minpoly = number(" + @mPoly + ");");
+  ideal imageid = imap(RAR1, J2);
+  export(imageid);
+     dbprint(dbPrt+1, "
+// 'ImageVariety' created a new ring.
+// To see the ring, type (if the name 'R' was assigned to the return value):
+     show(R);
+// To access the ideal of the image variety, type
+     setring R;  imageid;
+");
+  setring RARB;
+  return(RAR2);
+}
+example
+{"EXAMPLE:";  echo = 2;
+  ring B   = 0,(x,y),dp;
+  ideal I  = x4 - y4;
+  ideal F  = x2, y2, x*y;
+  def R = ImageVariety(I, F);
+  setring R;
+  imageid;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc LinearizeAction(ideal Grp,def Gaction, int nrs)
+"USAGE:   LinearizeAction(G,action,r); ideal G, action; int r
+PURPOSE: linearize the group action 'action' and find an equivariant embedding
+         of K^m where m = size(action).
+ASSUME:  G contains only variables var(1..r) (r = nrs)
+basering = K[s(1..r),t(1..m)], K = Q or K = Q(a) and minpoly != 0.
+RETURN:  polynomial ring containing the ideals 'actionid', 'embedid', 'groupid'
+         - 'actionid' is the ideal defining the linearized action of G
+         - 'embedid' is a parameterization of an equivariant embedding (closed)
+         - 'groupid' is the ideal of G in the new ring
+NOTE:    set printlevel > 0 to see a trace
+EXAMPLE: example LinearizeAction; shows an example
+"
+{
+  def altring = basering;
+  int i, j, k, ok, loop, nrt, sizeOfDecomp, dbPrt;
+  intvec wt;
+  ideal action, basis, G, reduceIdeal;
+  matrix decompMx;
+  poly actCoeff;
+  string str, order;
+
+  dbPrt = printlevel-voice+2;
+  dbprint(dbPrt, "LinearizeAction " + string(Gaction));
+  def RLAR = basering;
+  string @mPoly = string(minpoly);
+  order = ordstr(basering);
+  nrt = ncols(Gaction);
+  for(i = 1; i <= nrs; i++) { wt[i] = 0;}
+  for(i = nrs + 1; i <= nrs + nrt; i++) { basis[i - nrs] = var(i); wt[i] = 1;}
+  dbprint(dbPrt, "  basis = " + string(basis));
+  if(attrib(Grp, "isSB")) { G = Grp; }
+  else { G = std(Grp); }
+  reduceIdeal = G;
+  action = Gaction;
+  loop = 1;
+  i = 1;
+
+  // check if each component of 'action' is linear in t(1),...,t(nrt).
+
+  while(loop){
+    if(deg(action[i], wt) <= 1) {
+      sizeOfDecomp = 0;
+      dbprint(dbPrt, "  " + string(action[i]) + " is linear");
+    }
+    else {   // action[i] is not linear
+
+    // compute the minimal decomposition of action[i]
+    // action[i]=decompMx[1,1]*decompMx[2,1]+ ... +decompMx[1,k]*decompMx[2,k]
+    // decompMx[1,j] contains variables var(1)...var(nrs)
+    // decompMx[2,j] contains variables var(nrs + 1)...var(nvars(basering))
+
+    dbprint(dbPrt, "  " + string(action[i])
+                   + " is not linear, a minimal decomposition is :");
+    decompMx = MinimalDecomposition(action[i], nrs, nrt);
+    sizeOfDecomp = ncols(decompMx);
+    dbprint(dbPrt, decompMx);
+
+    for(j = 1; j <= sizeOfDecomp; j++) {
+      // check if decompMx[2,j] is a linear combination of basis elements
+      actCoeff = decompMx[2, j];
+      ok = LinearCombinationQ(basis, actCoeff, nrt + nrs);
+      if(ok == 0) {
+
+        // nonlinear element, compute new component of the action
+
+        dbprint(dbPrt, "  the polynomial " + string(actCoeff)
+                   + " is not a linear combination of the elements of basis");
+        nrt++;
+        str = charstr(basering) + ", (" + varstr(basering)
+                   + ",t(" + string(nrt) + ")),";
+        if(defined(RLAB)) { kill RLAB;}
+        def RLAB = basering;
+        if(defined(RLAR)) { kill RLAR;}
+        execute("ring RLAR = " + str + "(" + order + ");");
+        execute("minpoly = number(" + @mPoly + ");");
+
+        ideal basis, action, G, reduceIdeal;
+        matrix decompMx;
+        map F;
+        poly actCoeff;
+
+        wt[nrs + nrt] = 1;
+        basis = imap(RLAB, basis), imap(RLAB, actCoeff);
+        action = imap(RLAB, action);
+        decompMx = imap(RLAB, decompMx);
+        actCoeff = imap(RLAB, actCoeff);
+        G = imap(RLAB, G);
+        attrib(G, "isSB", 1);
+        reduceIdeal = imap(RLAB, reduceIdeal), actCoeff - var(nrs + nrt);
+
+        // compute action on the new basis element
+
+        for(k = 1; k <= nrs; k++) { F[k] = 0;}
+        for(k = nrs + 1; k < nrs + nrt; k++) { F[k] = action[k - nrs];}
+        actCoeff = reduce(F(actCoeff), G);
+        action[ncols(action) + 1] = actCoeff;
+        dbprint(dbPrt, "  extend basering by " + string(var(nrs + nrt)));
+        dbprint(dbPrt, "  new basis = " + string(basis));
+        dbprint(dbPrt, "  action of G on new basis element = "
+                    + string(actCoeff));
+        dbprint(dbPrt, "  decomp : " + string(decompMx[2, j]) + " -> "
+                    + string(var(nrs + nrt)));
+      } // end if
+      else {
+        dbprint(dbPrt, "  the polynomial " + string(actCoeff)
+                    + " is a linear combination of the elements of basis");
+      }
+    } // end for
+    reduceIdeal = std(reduceIdeal);
+    action[i] = reduce(action[i], reduceIdeal);
+    } // end else
+    if(i < ncols(action)) { i++;}
+    else {loop = 0;}
+  } // end while
+  if(defined(actionid)) { kill actionid; }
+  ideal actionid, embedid, groupid;
+  actionid = action;
+  embedid = basis;
+  groupid = G;
+  export actionid, embedid, groupid;
+dbprint(dbPrt+1, "
+// 'LinearizeAction' created a new ring.
+// To see the ring, type (if the name 'R' was assigned to the return value):
+     show(R);
+// To access the new action and the equivariant embedding, type
+     setring R; actionid; embedid; groupid
+");
+  setring altring;
+  return(RLAR);
+}
+example
+{"EXAMPLE:";  echo = 2;
+  ring B   = 0,(s(1..5), t(1..3)),dp;
+  ideal G =  s(3)-s(4), s(2)-s(5), s(4)*s(5), s(1)^2*s(4)+s(1)^2*s(5)-1, s(1)^2*s(5)^2-s(5), s(4)^4-s(5)^4+s(1)^2, s(1)^4+s(4)^3-s(5)^3, s(5)^5-s(1)^2*s(5);
+  ideal action = -s(4)*t(1)+s(5)*t(1), -s(4)^2*t(2)+2*s(4)^2*t(3)^2+s(5)^2*t(2), s(4)*t(3)+s(5)*t(3);
+  LinearActionQ(action, 5);
+  def R = LinearizeAction(G, action, 5);
+  setring R;
+  R;
+  actionid;
+  embedid;
+  groupid;
+  LinearActionQ(actionid, 5);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc LinearActionQ(def Gaction, int nrs)
+"USAGE:   LinearActionQ(action,nrs); ideal action, int nrs
+PURPOSE: check whether the action defined by 'action' is linear w.r.t. the
+         variables var(nrs + 1...nvars(basering)).
+RETURN:  0 action not linear
+         1 action is linear
+EXAMPLE: example LinearActionQ; shows an example
+"
+{
+  int i, nrt, loop;
+  intvec wt;
+
+  nrt = ncols(Gaction);
+  for(i = 1; i <= nrs; i++) { wt[i] = 0;}
+  for(i = nrs + 1; i <= nrs + nrt; i++) { wt[i] = 1;}
+  loop = 1;
+  i = 1;
+  while(loop)
+  {
+    if(deg(Gaction[i], wt) > 1) { loop = 0; }
+    else
+    {
+      i++;
+      if(i > ncols(Gaction)) { loop = 0;}
+    }
+  }
+  return(i > ncols(Gaction));
+}
+example
+{"EXAMPLE:";  echo = 2;
+  ring R   = 0,(s(1..5), t(1..3)),dp;
+  ideal G =  s(3)-s(4), s(2)-s(5), s(4)*s(5), s(1)^2*s(4)+s(1)^2*s(5)-1,
+             s(1)^2*s(5)^2-s(5), s(4)^4-s(5)^4+s(1)^2, s(1)^4+s(4)^3-s(5)^3,
+             s(5)^5-s(1)^2*s(5);
+  ideal Gaction = -s(4)*t(1)+s(5)*t(1),
+                  -s(4)^2*t(2)+2*s(4)^2*t(3)^2+s(5)^2*t(2),
+                   s(4)*t(3)+s(5)*t(3);
+  LinearActionQ(Gaction, 5);
+  LinearActionQ(Gaction, 8);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc LinearCombinationQ(ideal I, poly f)
+"USAGE:   LinearCombination(I, f); ideal I, poly f
+PURPOSE: test whether f can be written as a linear combination of the generators of I.
+RETURN:  0 f is not a linear combination
+         1 f is a linear combination
+"
+{
+  int i, loop, sizeJ;
+  ideal J;
+
+  J = I, f;
+  sizeJ = size(J);
+
+  def RLC = ImageVariety(ideal(0), J);   // compute algebraic relations
+  setring RLC;
+  matrix coMx;
+  poly relation = 0;
+
+  loop = 1;
+  i = 1;
+  while(loop)
+  { // look for a linear relation containing Y(nr)
+    if(deg(imageid[i]) == 1)
+    {
+      coMx = coef(imageid[i], var(sizeJ));
+      if(coMx[1,1] == var(sizeJ))
+      {
+        relation = imageid[i];
+        loop = 0;
+      }
+    }
+    else
+    {
+      i++;
+      if(i > ncols(imageid)) { loop = 0;}
+    }
+  }
+  return(i <= ncols(imageid));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc InvariantRing(ideal G, ideal action, list #)
+"USAGE:   InvariantRing(G, Gact [, opt]); ideal G, Gact; int opt
+PURPOSE: compute generators of the invariant ring of G w.r.t. the action 'Gact'
+ASSUME:  G is a finite group and 'Gact' is a linear action.
+RETURN:  ring R; this ring comes with the ideals 'invars' and 'groupid' and
+         with the poly 'newA':
+         - 'invars' contains the algebra generators of the invariant ring
+         - 'groupid' is the ideal of G in the new ring
+         - 'newA' is the new representation of the primitive root of the
+           minimal polynomial of the ring which was active when calling the
+           procedure (if the minpoly did not change, 'newA' is set to 'a').
+NOTE:    the minimal polynomial of the output ring depends on some random
+         choices
+EXAMPLE: example InvariantRing; shows an example
+"
+{
+  int i, ok, dbPrt, noReynolds, primaryDec;
+  ideal invarsGens, groupid;
+
+  dbPrt = printlevel-voice+2;
+
+  if(size(#) > 0) { primaryDec = #[1]; }
+  else { primaryDec = 0; }
+
+  dbprint(dbPrt, "InvariantRing of " + string(G));
+  dbprint(dbPrt, " action  = " + string(action));
+
+  if(!attrib(G, "isSB")) { groupid = std(G);}
+  else { groupid = G; }
+
+  // compute the nullcone of G by means of Derksen's algorithm
+
+  invarsGens = NullCone(groupid, action);  // compute nullcone of linear action
+  dbprint(dbPrt, " generators of zero-fibre ideal are " + string(invarsGens));
+
+  // make all generators of the nullcone invariant
+  // if necessary, compute the Reynolds Operator, i.e., find all elements
+  // of the variety defined by G. It might be necessary to extend the
+  // ground field.
+
+  def IRB = basering;
+  if(defined(RIRR)) { kill RIRR;}
+  def RIRR = basering;
+  setring RIRR;
+//  export(RIRR);
+//  export(invarsGens);
+  noReynolds = 1;
+  dbprint(dbPrt, " nullcone is generated by " + string(size(invarsGens)));
+   dbprint(dbPrt, " degrees = " + string(maxdeg(invarsGens)));
+  for(i = 1; i <= ncols(invarsGens); i++){
+    ok = InvariantQ(invarsGens[i], groupid, action);
+    if(ok) { dbprint(dbPrt, string(i) + ": poly " + string(invarsGens[i])
+                                      + " is invariant");}
+    else {
+      if(noReynolds) {
+
+        // compute the Reynolds operator and change the ring !
+        noReynolds = 0;
+        def RORN = ReynoldsOperator(groupid, action, primaryDec);
+        setring RORN;
+        ideal groupid = std(id);
+        attrib(groupid, "isSB", 1);
+        ideal action = actionid;
+        setring RIRR;
+        string parName, minPoly;
+        if(npars(basering) == 0) {
+          parName = "a";
+          minPoly = "0";
+        }
+        else {
+          parName = parstr(basering);
+          minPoly = string(minpoly);
+        }
+        execute("ring RA1=0,(" + varstr(basering) + "," + parName + "), lp;");
+        if (minPoly!="0") { execute("ideal mpoly = std(" + minPoly + ");"); }
+        ideal I = imap(RIRR,invarsGens);
+        setring RORN;
+        map Phi = RA1, maxideal(1);
+        Phi[nvars(RORN) + 1] = newA;
+        ideal invarsGens = Phi(I);
+        kill Phi,RA1,RIRR;
+// end of ersetzt durch
+
+      }
+      dbprint(dbPrt, string(i) + ": poly " + string(invarsGens[i])
+                               + " is NOT invariant");
+      invarsGens[i] = ReynoldsImage(ROelements, invarsGens[i]);
+      dbprint(dbPrt, " --> " + string(invarsGens[i]));
+    }
+  }
+  for(i = 1; i <= ncols(invarsGens); i++){
+    ok =  InvariantQ(invarsGens[i], groupid, action);
+    if(ok) { dbprint(dbPrt, string(i) + ": poly " + string(invarsGens[i])
+                                      + " is invariant"); }
+    else { print(string(i) + ": Fatal Error with Reynolds ");}
+  }
+  if(noReynolds == 0) {
+    def RIRS = RORN;
+    setring RIRS;
+    kill RORN;
+    export groupid;
+  }
+  else {
+    def RIRS = RIRR;
+    kill RIRR;
+    setring RIRS;
+    export groupid;
+  }
+  ideal invars = invarsGens;
+  kill invarsGens;
+  if (defined(ROelements)) { kill ROelements,actionid,theZeroset,id; }
+  export invars;
+  dbprint(dbPrt+1, "
+// 'InvariantRing' created a new ring.
+// To see the ring, type (if the name 'R' was assigned to the return value):
+     show(R);
+// To access the generators of the invariant ring type
+     setring R; invars;
+// Note that the input group G is stored in R as the ideal 'groupid'; to
+// see it, type
+    groupid;
+// Note that 'InvariantRing' might change the minimal polynomial
+// The representation of the algebraic number is given by 'newA'
+");
+  setring IRB;
+  return(RIRS);
+}
+example
+{"EXAMPLE:";  echo = 2;
+  ring B = 0, (s(1..2), t(1..2)), dp;
+  ideal G = -s(1)+s(2)^3, s(1)^4-1;
+  ideal action = s(1)*t(1), s(2)*t(2);
+
+  def R = InvariantRing(std(G), action);
+  setring R;
+  invars;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc InvariantQ(poly f, ideal G,def action)
+"USAGE:   InvariantQ(f, G, action); poly f; ideal G, action
+PURPOSE: check whether the polynomial f is invariant w.r.t. G, where G acts via
+         'action' on K^m.
+ASSUME:  basering = K[s_1,...,s_m,t_1,...,t_m] where K = Q of K = Q(a) and
+         minpoly != 0, f contains only t_1,...,t_m, G is the ideal of an
+         algebraic group and a standardbasis.
+RETURN:  int;
+         0 if f is not invariant,
+         1 if f is invariant
+NOTE:    G need not be finite
+"
+{
+  def altring=basering;
+  map F;
+  if(deg(f) == 0) { return(1); }
+  for(int i = 1; i <= size(action); i++) {
+    F[nvars(basering) - size(action) + i] = action[i];
+  }
+  return(reduce(f - F(f), G) == 0);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc MinimalDecomposition(poly f, int nrs, int nrt)
+"USAGE:   MinimalDecomposition(f,a,b); poly f; int a, b.
+PURPOSE: decompose f as a sum M[1,1]*M[2,1] + ... + M[1,r]*M[2,r] where M[1,i]
+         contains only s(1..a), M[2,i] contains only t(1...b) s.t. r is minimal
+ASSUME:  f polynomial in K[s(1..a),t(1..b)], K = Q or K = Q(a) and minpoly != 0
+RETURN:  2 x r matrix M s.t.  f = M[1,1]*M[2,1] + ... + M[1,r]*M[2,r]
+EXAMPLE: example MinimalDecomposition;
+"
+{
+  int i, sizeOfMx, changed, loop;
+  list initialTerms;
+  matrix coM1, coM2, coM, decompMx, auxM;
+  matrix m[2][2] = 0,1,1,0;
+  poly vars1, vars2;
+
+  if(f == 0) { return(decompMx); }
+
+  // first decompose f w.r.t. t(1..nrt)
+  // then  decompose f w.r.t. s(1..nrs)
+
+  vars1 = RingVarProduct(nrs+1..nrt+nrs);
+  vars2 = RingVarProduct(1..nrs);
+  coM1 = SimplifyCoefficientMatrix(m*coef(f, vars1));    // exchange rows of decomposition
+  coM2 = SimplifyCoefficientMatrix(coef(f, vars2));
+  if(ncols(coM2) < ncols(coM1)) {
+    auxM = coM1;
+    coM1 = coM2;
+    coM2 = auxM;
+  }
+  decompMx = coM1;        // decompMx is the smaller decomposition
+  if(ncols(decompMx) == 1) { return(decompMx);}      // n = 1 is minimal
+  changed = 0;
+  loop = 1;
+  i = 1;
+
+  // first loop, try coM1
+
+  while(loop) {
+    coM = MinimalDecomposition(f - coM1[1, i]*coM1[2, i], nrs, nrt);
+    if(size(coM) == 1) { sizeOfMx = 0; }    // coM = 0
+    else {sizeOfMx = ncols(coM); }      // number of columns
+    if(sizeOfMx + 1 < ncols(decompMx)) {    // shorter decomposition
+      changed = 1;
+      decompMx = coM;
+      initialTerms[1] =  coM1[1, i];
+      initialTerms[2] =  coM1[2, i];
+    }
+    if(sizeOfMx == 1) { loop = 0;}      // n = 2 is minimal
+    if(i < ncols(coM1)) {i++;}
+    else {loop = 0;}
+  }
+  if(sizeOfMx > 1) {            // n > 2
+    loop = 1;          // coM2 might yield
+    i = 1;            // a smaller decomposition
+  }
+
+  // first loop, try coM2
+
+  while(loop) {
+    coM = MinimalDecomposition(f - coM2[1, i]*coM2[2, i], nrs, nrt);
+    if(size(coM) == 1) { sizeOfMx = 0; }
+    else {sizeOfMx = ncols(coM); }
+    if(sizeOfMx + 1 < ncols(decompMx)) {
+      changed = 1;
+      decompMx = coM;
+      initialTerms[1] =  coM2[1, i];
+      initialTerms[2] =  coM2[2, i];
+    }
+    if(sizeOfMx == 1) { loop = 0;}
+    if(i < ncols(coM2)) {i++;}
+    else {loop = 0;}
+  }
+  if(!changed) { return(decompMx); }
+  if(size(decompMx) == 1) { matrix decompositionM[2][1];}
+  else  { matrix decompositionM[2][ncols(decompMx) + 1];}
+  decompositionM[1, 1] = initialTerms[1];
+  decompositionM[2, 1] = initialTerms[2];
+  if(size(decompMx) > 1) {
+    for(i = 1; i <= ncols(decompMx); i++) {
+      decompositionM[1, i + 1] = decompMx[1, i];
+      decompositionM[2, i + 1] = decompMx[2, i];
+    }
+  }
+  return(decompositionM);
+}
+example
+{"EXAMPLE:"; echo = 2;
+  ring R = 0, (s(1..2), t(1..2)), dp;
+  poly h = s(1)*(t(1) + t(1)^2) +  (t(2) + t(2)^2)*(s(1)^2 + s(2));
+  matrix M = MinimalDecomposition(h, 2, 2);
+  M;
+  M[1,1]*M[2,1] + M[1,2]*M[2,2] - h;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc NullCone(ideal G,def action)
+"USAGE:   NullCone(G, action); ideal G, action
+PURPOSE: compute the ideal of the nullcone of the linear action of G on K^n,
+         given by 'action', by means of Deksen's algorithm
+ASSUME:  basering = K[s(1..r),t(1..n)], K = Q or K = Q(a) and minpoly != 0,
+         G is an ideal of a reductive algebraic group in K[s(1..r)],
+         'action' is a linear group action of G on K^n (n = ncols(action))
+RETURN:  ideal of the nullcone of G.
+NOTE:    the generators of the nullcone are homogenous, but in general not invariant
+EXAMPLE: example NullCone; shows an example
+"
+{
+  int i, nt, dbPrt, offset, groupVars;
+  string ringSTR, vars, order;
+  def RNCB = basering;
+
+  // prepare the ring needed for the computation
+  // s(1...) variables of the group
+  // t(1...) variables of the affine space
+  // y(1...) additional 'slack' variables
+
+  nt = size(action);
+  order = "(dp(" + string(nvars(basering) - nt) + "), dp);";
+  vars = "(s(1.." + string(nvars(basering) - nt);
+  vars = vars +"),t(1.."+string(nt) + "), Y(1.." + string(nt) + "))," + order;
+  ringSTR = "ring RNCR = (" + charstr(basering) +  "),"  + vars;
+  // ring for the computation
+
+  string @minPoly = string(minpoly);
+  offset =  size(G) + nt;
+  execute(ringSTR);
+  execute("poly aaa = number(" + @minPoly + ");");
+  if (aaa!=0) { minpoly = number(aaa); }
+  ideal action, G, I, J, N, generators;
+  map F;
+  poly f;
+
+  // built the ideal of the graph of GxV -> V, (s,v) -> s(v), i.e.
+  // of the image of the map GxV -> GxVxV, (s,v) -> (s,v,s(v))
+
+  G = fetch(RNCB, G);
+  action = fetch(RNCB, action);
+  groupVars = nvars(basering) - 2*nt;
+  offset =  groupVars + nt;
+  I = G;
+  for(i = 1; i <= nt; i = i + 1) {
+    I = I, var(offset + i) - action[i];
+  }
+
+  J = std(I);  // takes long, try to improve
+
+  // eliminate
+
+  N = nselect(J, 1.. groupVars);
+
+  // substitute
+  for(i = 1; i <= nvars(basering); i = i + 1) { F[i] = 0; }
+  for(i = groupVars + 1; i <= offset; i = i + 1) { F[i] = var(i); }
+
+  generators = mstd(F(N))[2];
+  setring RNCB;
+  return(fetch(RNCR, generators));
+}
+example
+{"EXAMPLE:";  echo = 2;
+  ring R = 0, (s(1..2), x, y), dp;
+  ideal G = -s(1)+s(2)^3, s(1)^4-1;
+  ideal action = s(1)*x, s(2)*y;
+
+  ideal inv = NullCone(G, action);
+  inv;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc ReynoldsOperator(ideal Grp, ideal Gaction, list #)
+"USAGE:   ReynoldsOperator(G, action [, opt]); ideal G, action; int opt
+PURPOSE: compute the Reynolds operator of the group G which acts via 'action'
+RETURN:  polynomial ring R over a simple extension of the ground field of the
+         basering (the extension might be trivial), containing a list
+         'ROelements', the ideals 'id', 'actionid' and the polynomial 'newA'.
+         R = K(a)[s(1..r),t(1..n)].
+         - 'ROelements'  is a list of ideals, each ideal represents a
+           substitution map F : R -> R according to the zero-set of G
+         - 'id' is the ideal of G in the new ring
+         - 'newA' is the new representation of a' in terms of a. If the
+           basering does not contain a parameter then 'newA' = 'a'.
+ASSUME:  basering = K[s(1..r),t(1..n)], K = Q or K = Q(a') and minpoly != 0,
+         G is the ideal of a finite group in K[s(1..r)], 'action' is a linear
+         group action of G
+"
+{
+  def ROBR = basering;
+  int i, j, n, ns, primaryDec;
+  ideal G1 = Grp;
+  list solution, saction;
+  string str;
+
+  if(size(#) > 0) { primaryDec = #[1]; }
+  else { primaryDec = 0; }
+  kill #;
+
+  n = nvars(basering);
+  ns = n - size(Gaction);
+  for(i = ns + 1; i <= n; i++) { G1 = G1, var(i);}
+
+  def RORR = zeroSet(G1, primaryDec);
+  setring ROBR;
+  string parName, minPoly;
+  if(npars(basering) == 0) {
+    parName = "a";
+    minPoly = "0";
+  }
+  else {
+    parName = parstr(basering);
+    minPoly = string(minpoly);
+  }
+  execute("ring RA1=0,(" + varstr(basering) + "," + parName + "), lp;");
+  if (minPoly!="0") { execute("ideal mpoly = std(" + minPoly + ");"); }
+  ideal Grp = imap(ROBR,Grp);
+  ideal Gaction = imap(ROBR,Gaction);
+  setring RORR;
+  map Phi = RA1, maxideal(1);
+  Phi[nvars(RORR) + 1] = newA;
+  id = Phi(Grp); // id already defined by zeroSet of level 0
+  ideal actionid = Phi(Gaction);
+  kill parName,minPoly,Phi,RA1;
+// end of ersetzt durch
+  list ROelements;
+  ideal Rf;
+  map groupElem;
+  poly h1, h2;
+
+  for(i = 1; i <= size(theZeroset); i++) {
+    groupElem = theZeroset[i];    // element of G
+    for(j = ns + 1; j<=n; j++) { groupElem[j] = var(j); } //do not change t's
+    for(j = 1; j <= n - ns; j++) {
+      h1 = actionid[j];
+      h2 = groupElem(h1);
+      Rf[ns + j] = h2;
+    }
+    ROelements[i] = Rf;
+  }
+  export actionid, ROelements;
+  setring ROBR;
+  return(RORR);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc ReynoldsImage(list reynoldsOp, poly f)
+"USAGE:   ReynoldsImage(RO, f); list RO, poly f
+PURPOSE: compute the Reynolds image of the polynomial f, where RO represents
+         the Reynolds operator
+RETURN:  poly
+"
+{
+  def RIBR=basering;
+  map F;
+  poly h = 0;
+
+  for(int i = 1; i <= size(reynoldsOp); i++) {
+    F = RIBR, reynoldsOp[i];
+    h = h + F(f);
+  }
+  return(h/size(reynoldsOp));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static proc SimplifyCoefficientMatrix(matrix coefMatrix)
+"USAGE:   SimplifyCoefficientMatrix(M); M matrix coming from coef(...)
+PURPOSE: simplify the matrix, i.e. find linear dependencies among the columns
+RETURN:  matrix M, f = M[1,1]*M[2,1] + ... + M[1,n]*M[2,n]
+"
+{
+  int i, j , loop;
+  intvec columnList;
+  matrix decompMx = coefMatrix;
+
+  loop = 1;
+  i = 1;
+  while(loop) {
+    columnList = 1..i;            // current column
+    for(j = i + 1; j <= ncols(decompMx); j++) {
+      // test if decompMx[2, j] equals const * decompMx[2, i]
+      if(LinearCombinationQ(ideal(decompMx[2, i]), decompMx[2, j])) {    // column not needed
+        decompMx[1, i] = decompMx[1, i] +  decompMx[2, j] / decompMx[2, i] * decompMx[1, j];
+      }
+      else { columnList[size(columnList) + 1] = j; }
+    }
+    if(defined(auxM)) { kill auxM;}
+    matrix auxM[2][size(columnList)];      // built new matrix and omit
+    for(j = 1; j <= size(columnList); j++) {    // the linear dependent colums
+      auxM[1, j] = decompMx[1, columnList[j]];    // found above
+      auxM[2, j] = decompMx[2, columnList[j]];
+    }
+    decompMx = auxM;
+    if(i < ncols(decompMx) - 1) { i++;}
+    else { loop = 0;}
+  }
+  return(decompMx);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc SimplifyIdeal(ideal I, list #)
+"USAGE:   SimplifyIdeal(I [,m, name]); ideal I; int m, string name"
+PURPOSE: simplify ideal I to the ideal I', do not change the names of the
+         first m variables, new ideal I' might contain less variables.
+         I' contains variables var(1..m)
+RETURN: list
+  _[1] ideal I'
+  _[2] ideal representing a map phi to a ring with probably less vars. s.th.
+       phi(I) = I'
+  _[3] list of variables
+  _[4] list from 'elimpart'
+"
+{
+  int i, k, m;
+  string nameCMD;
+  ideal mId, In, mapId;  // ideal for the map
+  list sList, result;
+
+  sList = elimpart(I);
+  In = sList[1];
+  mapId = sList[5];
+
+  if(size(#) > 0)
+  {
+    m = #[1];
+    nameCMD = #[2];
+  }
+  else { m = 0;} // nvars(basering);
+  k = 0;
+  for(i = 1; i <= nvars(basering); i++)
+  {
+    if(sList[4][i] != 0)
+    {
+      k++;
+      if(k <= m) { mId[i] = sList[4][i]; }
+      else { execute("mId["+string(i) +"] = "+nameCMD+"("+string(k-m)+");");}
+    }
+    else { mId[i] = 0;}
+  }
+  map phi = basering, mId;
+  result[1] = phi(In);
+  result[2] = phi(mapId);
+  result[3] = simplify(sList[4], 2);
+  result[4] = sList;
+  return(result);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc RingVarProduct(def index)
+// list of indices
+{
+  poly f = 1;
+  for(int i = 1; i <= size(index); i++)
+  {
+    f = f * var(index[i]);
+  }
+  return(f);
+}
+///////////////////////////////////////////////////////////////////////////////
diff --git a/Singular/LIB/rootsmr.lib b/Singular/LIB/rootsmr.lib
new file mode 100644
index 0000000..7f90069
--- /dev/null
+++ b/Singular/LIB/rootsmr.lib
@@ -0,0 +1,709 @@
+/////////////////////////////////////////////////////////////////////////////
+version="version rootsmr.lib 4.0.0.0 Jun_2013 "; // $Id: 3eed4f761eb11a23a138d4832551936c88ca7d90 $
+category="Teaching";
+info="
+LIBRARY: rootsmr.lib Counting the number of real roots of polynomial systems
+AUTHOR:               Enrique A. Tobis, etobis at dc.uba.ar
+
+OVERVIEW:  Routines for counting the number of real roots of a multivariate
+           polynomial system. Two methods are implemented: deterministic
+           computation of the number of roots, via the signature of a certain
+           bilinear form (nrRootsDeterm); and a rational univariate projection,
+           using a pseudorandom polynomial (nrRootsProbab). It also includes a
+           command to verify the correctness of the pseudorandom answer.
+REFERENCES: Basu, Pollack, Roy, \"Algorithms in Real Algebraic
+           Geometry\", Springer, 2003.
+
+PROCEDURES:
+ nrRootsProbab(I)    Number of real roots of 0-dim ideal (probabilistic)
+ nrRootsDeterm(I)    Number of real roots of 0-dim ideal (deterministic)
+ symsignature(m)     Signature of the symmetric matrix m
+ sturmquery(h,B,I)   Sturm query of h on V(I)
+ matbil(h,B,I)       Matrix of the bilinear form on R/I associated to h
+ matmult(f,B,I)      Matrix of multiplication by f (m_f) on R/I in the basis B
+ tracemult(f,B,I)    Trace of m_f (B is an ordered basis of R/I)
+ coords(f,B,I)       Coordinates of f in the ordered basis B
+ randcharpoly(B,I,n) Pseudorandom charpoly of univ. projection, n optional
+ verify(p,B,i)       Verifies the result of randcharpoly
+ randlinpoly(n)      Pseudorandom linear polynomial, n optional
+ powersums(f,B,I)    Powersums of the roots of a char polynomial
+ symmfunc(S)         Symmetric functions from the powersums S
+ univarpoly(l)       Polynomial with coefficients from l
+ qbase(i)            Like kbase, but the monomials are ordered
+
+KEYWORDS: real roots, univariate projection
+";
+///////////////////////////////////////////////////////////////////
+LIB "linalg.lib";   // We use charpoly
+LIB "rootsur.lib"; // We use varsigns
+
+proc nrRootsProbab(ideal I, list #)
+"USAGE:     nrRootsProbab(I,[n]); ideal I, int n
+RETURN:    int: the number of real roots of the ideal I by a probabilistic
+           algorithm
+ASSUME:    If I is not a Groebner basis, then a Groebner basis will be computed
+           by using std. If I is already a Groebner basis (i.e. if
+           attrib(I,"isSB"); returns 1) then this Groebner basis will be
+           used, hence it must be one w.r.t. (any) global ordering. This may
+           be useful if the ideal is known to be a Groebner basis or if it
+           can be computed faster by a different method.
+NOTE:      If n<10 is given, n is the number of digits being used for
+           constructing a random characteristic polynomial, a bigger n is
+           more safe but slower (default: n=5).
+           If printlevel>0 the number of complex solutions is displayed
+           (default: printlevel=0).
+SEE ALSO:  nrroots, nrRootsDeterm, randcharpoly, solve
+EXAMPLE:   example nrRootsProbab; shows an example"
+{
+  //Note on complexity: Let n = no of complex roots of I (= vdim(std(I)).
+  //Then the algorithm needs:
+  //1 std(I) and ~n NF computations (of randcharpoly w.r.t. I)
+
+  if (isparam(I)) {
+    ERROR("This procedure cannot operate with parametric arguments");
+  }
+  int pr = printlevel-voice+2;
+  int v;
+  int n=5;
+  if (size(#) == 1) {
+    n=#[1];
+  }
+  if (attrib(I,"isSB")!=1) {
+    I = std(I);
+  }
+
+  ideal b = qbase(I);
+  v = size(b);
+  if (v == 0) {
+    ERROR("ideal is not 0-dimensional");
+  }
+  dbprint(pr,"//ideal has " +string(v)+ " complex solutions, counted with multiplicity");
+
+  poly p = randcharpoly(b,I,n);
+
+  return (nrroots(p));
+}
+
+example
+{
+  echo = 2;
+  ring r = 0,(x,y,z),lp;
+  ideal i = (x-1)*(x-2),(y-1)^3*(x-y),(z-1)*(z-2)*(z-3)^2;
+  nrRootsProbab(i);       //no of real roots (using internally std)
+
+  i = groebner(i);        //using the hilbert driven GB computation
+  int pr = printlevel;
+  printlevel = 2;
+  nrRootsProbab(i);
+  printlevel = pr;
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc nrRootsDeterm(ideal I)
+"USAGE:     nrRootsDeterm(I); ideal I
+RETURN:    int: the number of real roots of the ideal I by a deterministic
+           algorithm
+ASSUME:    If I is not a Groebner basis, then a Groebner basis will be computed
+           by using std. If I is already a Groebner basis (i.e. if
+           attrib(I,"isSB"); returns 1) then this Groebner basis will be
+           used, hence it must be one w.r.t. (any) global ordering. This may
+           be useful if the ideal is known to be a Groebner basis or if it
+           can be computed faster by a different method.
+NOTE:      If printlevel>0 the number of complex solutions is displayed
+           (default: printlevel=0). The procedure nrRootsProbab is usually faster.
+SEE ALSO:  nrroots, nrRootsProbab, sturmquery, solve
+EXAMPLE:   example nrRootsDeterm; shows an example"
+{
+  //Note on complexity: Let n = no of complex roots of I (= vdim(std(I)).
+  //Then the algotithm needs:
+  //1 std(I) and (1/2)n*(n+1)^2 ~ 1/2n^3 NF computations (of monomials w.r.t. I)
+
+  if (isparam(I)) {
+    ERROR("This procedure cannot operate with parametric arguments");
+  }
+  int pr = printlevel-voice+2;
+  int v;
+
+  if (attrib(I,"isSB")!=1) {
+    I = std(I);
+  }
+
+  ideal b = qbase(I);
+  v = size(b);
+  if (v == 0) {
+    ERROR("ideal is not 0-dimensional");
+  }
+  dbprint(pr,"//ideal has " +string(v)+ " complex solutions, counted with multiplicity");
+
+  return (sturmquery(1,b,I));
+}
+
+example
+{
+  echo = 2;
+  ring r = 0,(x,y,z),lp;
+  ideal I = (x-1)*(x-2),(y-1),(z-1)*(z-2)*(z-3)^2;
+  nrRootsDeterm(I);       //no of real roots (using internally std)
+
+  I = groebner(I);        //using the hilbert driven GB computation
+  int pr = printlevel;
+  printlevel = 2;
+  nrRootsDeterm(I);
+  printlevel = pr;
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc symsignature(matrix m)
+"USAGE:     symsignature(m); m matrix. m must be symmetric.
+RETURN:    int: the signature of m
+SEE ALSO:  matbil,sturmquery
+EXAMPLE:   example symsignature; shows an example"
+{
+  int positive, negative, i, j;
+  list l;
+  poly variable;
+
+  if (isparam(m)) {
+    ERROR("This procedure cannot operate with parametric arguments");
+  }
+
+  if (!isSquare(m)) {
+    ERROR ("m must be a square matrix");
+  }
+
+  // We check whether m is symmetric
+  for (i = 1;i <= nrows(m);i++) {
+    for (j = i;j <= nrows(m);j++) {
+      if (m[i,j] != m[j,i]) {
+        ERROR ("m must be a symmetric matrix");
+      }
+    }
+  }
+
+  poly f = charpoly(m); // Uses the last variable of the ring
+
+  for (i = size(f);i >= 1;i--) {
+    l[i] = leadcoef(f[i]);
+  }
+  positive = varsigns(l);
+
+  variable = var(nvars(basering)); // charpoly uses the last variable
+  f = subst(f,variable,-variable);
+
+  for (i = size(f);i >= 1;i--) {
+    l[i] = leadcoef(f[i]);
+  }
+
+  negative = varsigns(l);
+  return (positive - negative);
+}
+example
+{
+  echo = 2;
+  ring r = 0,(x,y),dp;
+  ideal i = x4-y2x,y2-13;
+  i = std(i);
+  ideal b = qbase(i);
+
+  matrix m = matbil(1,b,i);
+  symsignature(m);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc sturmquery(poly h,ideal B,ideal I)
+"USAGE:     sturmquery(h,b,i); h poly, b,i ideal
+RETURN:    int: the Sturm query of h in V(i)
+ASSUME:    i is a Groebner basis, b is an ordered monomial basis
+           of r/i, r = basering.
+SEE ALSO:  symsignature,matbil
+EXAMPLE:   example sturmquery; shows an example"
+{
+  if (isparam(h) || isparam(B) || isparam(I)) {
+    ERROR("This procedure cannot operate with parametric arguments");
+  }
+
+  return (mysymmsig(matbil(h,B,I)));
+}
+example
+{
+  echo = 2;
+  ring r = 0,(x,y),dp;
+  ideal i = x4-y2x,y2-13;
+  i = std(i);
+  ideal b = qbase(i);
+
+  sturmquery(1,b,i);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+static proc mysymmsig(matrix m)
+// returns the signature of a square symmetric matrix m
+{
+  int positive, negative, i;
+  list l;
+  poly variable;
+
+  poly f = charpoly(m); // Uses the last variable of the ring
+
+  for (i = size(f);i >= 1;i--) {
+    l[i] = leadcoef(f[i]);
+  }
+  positive = varsigns(l);
+
+  variable = var(nvars(basering)); // charpoly uses the last variable
+  f = subst(f,variable,-variable);
+
+  for (i = size(f);i >= 1;i--) {
+    l[i] = leadcoef(f[i]);
+  }
+
+  negative = varsigns(l);
+  return (positive - negative);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc matbil(poly h,ideal B,ideal I)
+"USAGE:    matbil(h,b,i); h poly, b,i ideal
+RETURN:    matrix: the matrix of the bilinear form (f,g) |-> trace(m_fhg),
+           m_fhg = multiplication with fhg on r/i
+ASSUME:    i is a Groebner basis and b is an ordered monomial basis of r/i,
+           r = basering
+SEE ALSO:  matmult,tracemult
+EXAMPLE:   example matbil; shows an example"
+{
+  matrix m[size(B)][size(B)];
+  poly f;
+  int k,l;
+  //h = reduce(h,I);
+
+  for (k = 1; k <= size(B); k++) {
+    for (l = 1; l <= k; l++) {
+      m[k,l] = tracemult(h*B[k]*B[l],B,I)[1];
+      m[l,k] = m[k,l]; // The matrix we are trying to compute is symmetric
+    }
+   }
+  return(m);
+}
+example
+{
+  echo = 2;
+  ring r = 0,(x,y),dp;
+  ideal i = x4-y2x,y2-13;
+  i = std(i);
+  ideal b = qbase(i);
+  poly f = x3-xy+y-13+x4-y2x;
+
+  matrix m = matbil(f,b,i);
+  print(m);
+
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc tracemult(poly f,ideal B,ideal I)
+"USAGE:     tracemult(f,B,I);f poly, B,I ideal
+RETURN:    number: the trace of the multiplication by f (m_f) on r/I, written in
+           the monomial basis B of r/I, r = basering (faster than matmult + trace)
+ASSUME:    I is given by a Groebner basis and B is an ordered monomial basis of r/I
+SEE ALSO:  matmult,trace
+EXAMPLE:   example tracemult; shows an example"
+{
+  int k; // Iterates over the basis monomials
+  int l; // Iterates over the rows of the matrix
+  list coordinates;
+  number m;
+  poly g;
+
+  //f = reduce(f,I);
+  for (k = 1; k <= size(B); k++) {
+    l=1;
+    g = reduce(f*B[k],I);
+    while (l <= k) {
+      if (leadmonom(g[l]) == B[k]) {
+        m = m + leadcoef(g[l]);
+        break;
+      }
+      l++;
+    }
+  }
+  return (m);
+}
+example
+{
+  echo = 2;
+  ring r = 0,(x,y),dp;
+  ideal i = x4-y2x,y2-13;
+  i = std(i);
+  ideal b = qbase(i);
+
+  poly f = x3-xy+y-13+x4-y2x;
+  matrix m = matmult(f,b,i);
+  print(m);
+
+  tracemult(f,b,i);            //the trace of m
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc matmult(poly f, ideal B, ideal I)
+"USAGE:     matmult(f,b,i); f poly, b,i ideal
+RETURN:    matrix: the matrix of the multiplication map by f (m_f) on r/i
+           w.r.t. to the monomial basis b of r/i (r = basering)
+ASSUME:    i is a Groebner basis and b is an ordered monomial basis of r/i,
+           as given by qbase(i)
+SEE ALSO:  coords,matbil
+EXAMPLE:   example matmult; shows an example"
+{
+  int k; // Iterates over the basis monomials
+  int l; // Iterates over the rows of the matrix
+  list coordinates;
+  matrix m[size(B)][size(B)];
+
+  //f = reduce(f,I);
+  for (k = 1;k <= size(B);k++) {
+    coordinates = coords(f*(B[k]),B,I); // f*x_k written on the basis B
+    for (l = 1;l <= size(B);l++) {
+      m[l,k] = coordinates[l];
+    }
+  }
+  return (m);
+}
+example
+{
+  echo = 2;
+  ring r = 0,(x,y),dp;
+  ideal i = x4-y2x,y2-13;
+  i = std(i);
+  ideal b = qbase(i);
+
+  poly f = x3-xy+y-13+x4-y2x;
+  matrix m = matmult(f,b,i);
+  print(m);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc coords(poly f,ideal B,ideal I)
+"USAGE:     coords(f,b,i), f poly, b,i ideal
+RETURN:    list of numbers: the coordinates of the class of f (mod i)
+           in the monomial basis b
+ASSUME:    i is a Groebner basis and b is an ordered monomial basis of r/i,
+           r = basering
+SEE ALSO:  matmult,matbil
+KEYWORDS:  coordinates
+EXAMPLE:   example coords; shows an example"
+{
+  // We assume the basis is sorted according to the ring order
+  poly g;
+  int k,l=1,1;
+  list coordinates;
+  int N = size(B);
+
+  // We first compute the normal form of f w.r.t. I
+  g = reduce(f,I);
+  int n = size(g);    //allways n <= N
+
+  while (k <= N) {
+    if (leadmonom(g[l]) == B[k]) {
+      coordinates[k] = leadcoef(g[l]);
+      l++;
+    } else {
+      coordinates[k] = number(0);
+    }
+    k++;
+  }
+  return (coordinates);
+}
+example
+{
+  echo = 2;
+  ring r = 0,(x,y),dp;
+  ideal i = x4-y2x,y2-13;
+  poly f = x3-xy+y-13+x4-y2x;
+  i = std(i);
+  ideal b = qbase(i);
+  b;
+  coords(f,b,i);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+static proc isSquare(matrix m)
+// returns 1 if and only if m is a square matrix
+{
+  return (nrows(m)==ncols(m));
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc randcharpoly(ideal B,ideal I,list #)
+"USAGE:     randcharpoly(b,i); randcharpoly(b,i,n); b,i ideal; n int
+RETURN:    poly: the characteristic polynomial of a pseudorandom
+           rational univariate projection having one zero per zero of i.
+           If n<10 is given, it is the number of digits being used for the
+           pseudorandom coefficients (default: n=5)
+ASSUME:    i is a Groebner basis and b is an ordered monomial basis of r/i,
+           r = basering
+NOTE:      shows a warning if printlevel>0 (default: printlevel=0)
+KEYWORDS:  rational univariate projection
+EXAMPLE:   example randcharpoly; shows an example"
+{
+  int pr = printlevel - voice + 2;
+  poly p;
+  poly generic;
+  list l;
+  matrix m;
+  poly q;
+
+  if (size(#) == 1) {
+    generic = randlinpoly(#[1]);
+  } else {
+    generic = randlinpoly();
+  }
+
+  p = reduce(generic,I);
+  m = matmult(p,B,I);
+  q = charpoly(m);
+
+  dbprint(pr,"*********************************************************************");
+  dbprint(pr,"* WARNING: This polynomial was obtained using  pseudorandom numbers.*");
+  dbprint(pr,"* If you want to verify the result, please use the command          *");
+  dbprint(pr,"*                                                                   *");
+  dbprint(pr,"* verify(p,b,i)                                                     *");
+  dbprint(pr,"*                                                                   *");
+  dbprint(pr,"* where p is the polynomial I returned, b is the monomial basis     *");
+  dbprint(pr,"* used, and i the Groebner basis of the ideal                       *");
+  dbprint(pr,"*********************************************************************");
+
+  return(q);
+}
+example
+{
+  echo = 2;
+  ring r = 0,(x,y,z),dp;
+  ideal i = (x-1)*(x-2),(y-1),(z-1)*(z-2)*(z-3)^2;
+  i = std(i);
+  ideal b = qbase(i);
+  poly p = randcharpoly(b,i);
+  p;
+  nrroots(p); // See nrroots in urrcount.lib
+
+  int pr = printlevel;
+  printlevel = pr+2;
+  p = randcharpoly(b,i,5);
+  nrroots(p);
+  printlevel = pr;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc verify(poly p,ideal B,ideal I)
+"USAGE:     verify(p,B,I); p poly, B,I,ideal
+RETURN:    integer: 1 if and only if the polynomial p splits the points of V(I).
+           It's used to check the result of randcharpoly
+ASSUME:    I is given by a Groebner basis and B is an ordered monomial basis of r/I,
+           r = basering
+NOTE:      comments the result if printlevel>0 (default: printlevel=0)
+SEE ALSO:  randcharpoly
+EXAMPLE:   example verify; shows an example"
+{
+  int pr = printlevel - voice + 2;
+  poly sqr_free;
+  int correct;
+  poly variable;
+
+  if (isparam(p) || isparam(B) || isparam(I)) {
+    ERROR("This procedure cannot operate with parametric arguments");
+  }
+
+  variable = isuni(p);
+  sqr_free = p/gcd(p,diff(p,variable));
+  correct = (mat_rk(matbil(1,B,I)) == deg(sqr_free));
+
+  if (correct) {
+    dbprint(pr,"//Verification successful");
+  } else {
+    dbprint(pr,"//The choice of random numbers was not useful");
+    dbprint(pr,"//You might want to try randcharpoly with a larger number of digits");
+  }
+  return (correct);
+}
+example
+{
+  echo = 2;
+  ring r = 0,(x,y),dp;
+  poly f = x3-xy+y-13+x4-y2x;
+  ideal i = x4-y2x,y2-13;
+  i = std(i);
+  ideal b = qbase(i);
+  poly p = randcharpoly(b,i);
+  verify(p,b,i);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc randlinpoly(list #)
+"USAGE:     randlinpoly(); randlinpoly(n); n int
+RETURN:    poly: linear combination  of the variables of the ring, with
+           pseudorandom coefficients. If n<10 is given, it is the number of
+           digits being used for the range of the coefficients (default: n=5)
+SEE ALSO:  randcharpoly;
+EXAMPLE:   example randlinpoly; shows an example"
+{
+  int n,i;
+  poly p = 0;
+  int ndigits = 5;
+
+  if (size(#) == 1) {
+    ndigits = #[1];
+  }
+
+  n = nvars(basering);
+  for (i = 1;i <= n;i++) {
+    p = p + var(i)*random(1,10^ndigits);
+  }
+  return (p);
+}
+example
+{
+  echo = 2;
+  ring r = 0,(x,y,z,w),dp;
+  poly p = randlinpoly();
+  p;
+  randlinpoly(5);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc powersums(poly f,ideal B,ideal I)
+"USAGE:     powersums(f,b,i); f poly; b,i ideal
+RETURN:    list: the powersums of the results of evaluating f at the zeros of I
+ASSUME:    i is a Groebner basis and b is an ordered monomial basis of r/i,
+           r = basering
+SEE ALSO:  symmfunc
+EXAMPLE:   example symmfunc; shows an example"
+{
+  int N,k;
+  list sums;
+
+  N = size(B);
+  for (k = 1;k <= N;k++) {
+    sums = sums + list(leadcoef(trace(matmult(f^k,B,I))));
+  }
+  return (sums);
+}
+example
+{
+  echo = 2;
+  ring r = 0,(x,y,z),dp;
+
+  ideal i = (x-1)*(x-2),(y-1),(z+5); // V(I) = {(1,1,-5),(2,1,-5)}
+  i = std(i);
+
+  ideal b = qbase(i);
+  poly f = x+y+z;
+  list psums = list(-2-3,4+9); // f evaluated at V(I) gives {-3,-2}
+  list l = powersums(f,b,i);
+  psums;
+  l;
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc symmfunc(list S)
+"USAGE:     symmfunc(s); s list
+RETURN:    list: the symmetric functions of the roots of a polynomial, given
+                 the power sums of those roots.
+SEE ALSO:  powersums
+EXAMPLE:   example symmfunc; shows an example"
+{
+  // Takes the list of power sums and returns the symmetric functions
+  list a;
+  int j,l,N;
+  number sum;
+
+  N = size(S);
+  a[N+1] = 1; // We set the length of the list and initialize its last element.
+
+  for (l = N - 1;l >= 0;l--) {
+    sum = 0;
+    for (j = l + 1;j <= N;j++) {
+      sum = sum + ((a[j+1])*(S[j-l]));
+    }
+    sum = -sum;
+    a[l+1] = sum/(N-l);
+  }
+
+  a = reverse(a);
+  return (a);
+}
+example
+{
+  echo = 2;
+  ring r = 0,x,dp;
+  poly p = (x-1)*(x-2)*(x-3);
+  list psums = list(1+2+3,1+4+9,1+8+27);
+  list l = symmfunc(psums);
+  l;
+  p; // Compare p with the elements of l
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc univarpoly(list l)
+"USAGE:     univarpoly(l); l list
+RETURN:    poly: a polynomial p on the first variable of basering, say x,
+           with p = l[1] + l[2]*x + l[3]*x^2 + ...
+EXAMPLE:  example univarpoly; shows an example"
+{
+  poly p;
+  int i,n;
+
+  n = size(l);
+  for (i = 1;i <= n;i++) {
+    p = p + l[i]*var(1)^(n-i);
+  }
+  return (p);
+}
+example
+{
+  echo = 2;
+  ring r = 0,x,dp;
+  list l = list(1,2,3,4,5);
+  poly p = univarpoly(l);
+  p;
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc qbase(ideal i)
+"USAGE:    qbase(I); I zero-dimensional ideal
+RETURN:   ideal: A monomial basis of the quotient between the basering and the
+          ideal I, sorted according to the basering order.
+SEE ALSO: kbase
+KEYWORDS: zero-dimensional
+EXAMPLE:  example qbase; shows an example"
+{
+  ideal b;
+
+  b = kbase(i);
+  b = reverseideal(sort(b)[1]); // sort sorts in ascending order
+  return (b);
+}
+example
+{
+  echo = 2;
+  ring r = 0,(x,y,z),dp;
+
+  ideal i = 2x2,-y2,z3;
+  i = std(i);
+  ideal b = qbase(i);
+  b;
+  b = kbase(i);
+  b; // Compare this with the result of qbase
+}
+///////////////////////////////////////////////////////////////////////////////
+
+static proc reverseideal(ideal b) // Returns b reversed
+{
+  int i;
+  ideal result;
+
+  result = b[1];
+  for (i = 2;i <= size(b);i++) {
+    result = b[i], result;
+  }
+  return (result);
+}
+///////////////////////////////////////////////////////////////////////////////
+
diff --git a/Singular/LIB/rootsur.lib b/Singular/LIB/rootsur.lib
new file mode 100644
index 0000000..1b97727
--- /dev/null
+++ b/Singular/LIB/rootsur.lib
@@ -0,0 +1,958 @@
+/////////////////////////////////////////////////////////////////////////////
+version="version rootsur.lib 4.0.0.0 Jun_2013 "; // $Id: 33d0f5815fa0885e221b058be065073c0e4b4cd8 $
+category="Teaching";
+info="
+LIBRARY: rootsur.lib   Counting number of real roots of univariate polynomial
+AUTHOR:                 Enrique A. Tobis, etobis at dc.uba.ar
+
+OVERVIEW:  Routines for bounding and counting the number of real roots of a
+           univariate polynomial, by means of several different methods, namely
+           Descartes' rule of signs, the Budan-Fourier theorem, Sturm sequences
+           and Sturm-Habicht sequences. The first two give bounds on the number
+           of roots. The other two compute the actual number of roots of the
+           polynomial. There are several wrapper functions, to simplify the
+           application of the aforesaid theorems and some functions
+           to determine whether a given polynomial is univariate.
+REFERENCES: Basu, Pollack, Roy, \"Algorithms in Real Algebraic
+           Geometry\", Springer, 2003.
+
+
+PROCEDURES:
+  isuni(p)         Checks whether a polynomial is univariate
+  whichvariable(p) The only variable of a univariate monomial (or 0)
+  varsigns(p)      Number of sign changes in a list
+  boundBuFou(p,a,b) Bound for number of real roots of polynomial p in interval (a,b)
+  boundposDes(p)   Bound for the number of positive real roots of polynomial p
+  boundDes(p)      Bound for the number of real roots of polynomial p
+  allrealst(p)     Checks whether all the roots of a polynomial are real (via Sturm)
+  maxabs(p)        A bound for the maximum absolute value of a root of a poly
+  allreal(p)       Checks whether all the roots of a polynomial are real (via St-Ha)
+  sturm(p,a,b)     Number of real roots of a polynomial on an interval (via Sturm)
+  sturmseq(p)      Sturm sequence of a polynomial
+  sturmha(p,a,b)   Number of real roots of a polynomial in (a,b) (via Sturm-Habicht)
+  sturmhaseq(p)    A Sturm-Habicht Sequence of a polynomial
+  reverse(l)       Reverses a list
+  nrroots(p)       The number of real roots of p
+  isparam(p)       Returns 0 if and only if the polynomial has non-parametric coefficients
+
+KEYWORDS:         real roots, univariate polynomial
+";
+///////////////////////////////////////////////////////////////////////////////
+
+static proc isparametric(poly p)
+{
+  int ispar;
+  def ba = basering;
+
+  // If the basering has parameters declared
+  if (npars(basering) != 0) {
+    // If we were given just a polynomial
+    list lba = ringlist(ba);
+    lba[1]=0;
+    def rba = ring(lba); setring rba;
+    poly p1 = imap(ba,p);
+    setring ba;
+    poly p1 = imap(rba,p1);
+    ispar = (size(p-p1)!=0);
+  }
+  return (ispar);
+}
+///////////////////////////////////////////////////////////////////////////////
+proc isparam(list #)
+"USAGE:     isparam(ideal/module/poly/list);
+RETURN:    int: 0 if the argument has non-parametric coefficients and 1 if it
+           has parametric coefficients
+EXAMPLE:   example isparam; shows an example"
+{
+  int i;
+  int ispar;
+  def ar = #[1];
+
+  // It we were given only one argument (not a list)
+  if (size(#) == 1) {
+    if (typeof(ar) == "number") {
+      ispar = (pardeg(ar) > 0);
+    } else {
+    if (typeof(ar) == "poly") {
+      ispar = isparametric(ar);
+    } else {
+    if (typeof(ar) == "ideal" || typeof(ar) == "module") {
+      // Ciclo que revisa cada polinomio
+      i = size(ar);
+      while (!ispar && (i >= 1)) {
+        ispar = ispar || (isparametric(ar[i]));
+        i--;
+      }
+    } else {
+    if (typeof(ar) == "matrix" || typeof(ar) == "intmat") {
+      int j;
+      i = nrows(ar);
+      while (!ispar && (i >= 1)) {
+        j = nrows(ar);
+        while (!ispar && (j >= 1)) {
+          ispar = ispar || (isparametric(ar[i,j]));
+          j--;
+        }
+        i--;
+      }
+    }
+  }}}} else {
+  if (size(#) > 1) {
+    i = size(#);
+    while (!ispar && (i >= 1)) {
+      if ((typeof(#[i]) != "poly") && (typeof(#[i]) != "number") &&
+          typeof(#[i]) != "int") {
+              ERROR("This procedure only works with lists of polynomials");
+      }
+      ispar = ispar || (isparametric(#[i]));
+      i--;
+    }
+  }}
+  return (ispar);
+}
+example
+{
+  echo = 2;
+  ring r = 0,x,dp;
+  isparam(2x3-56x+2);
+  ring s = (0,a,b,c),x,dp;
+  isparam(2x3-56x+2);
+  isparam(2x3-56x+abc);
+}
+///////////////////////////////////////////////////////////////////////////////
+proc isuni(poly p)
+"USAGE:     isuni(p); poly p;
+RETURN:    poly: if p is a univariate polynomial, it returns the variable. If
+           not, zero.
+SEE ALSO:  whichvariable
+EXAMPLE:   example isuni; shows an example"
+{
+  int v=univariate(p);
+  if (v== -1) { v=1; }
+  if (v>0) { return(var(v)); }
+  else     { return(0); }
+}
+example
+{
+  echo = 2;
+  ring r = 0,(x,y),dp;
+  poly p = 6x7-3x2+2x-15/7;
+  isuni(p);
+  isuni(p*y);
+}
+///////////////////////////////////////////////////////////////////////////////
+proc whichvariable(poly p)
+"USAGE:     whichvariable(p); poly p
+RETURN:    poly: if p is a univariate monomial, the variable. Otherwise 0.
+ASSUME:    p is a monomial
+SEE ALSO:  isuni
+EXAMPLE:   example whichvariable; shows an example"
+{
+  if (size(p) != 1)
+  { ERROR("p must be a monomial"); }
+  int v=univariate(p);
+  if (v== -1) { v=1; }
+  if (v>0) { return(var(v)); }
+  else     { return(0); }
+}
+example
+{
+  echo = 2;
+  ring r = 0,(x,y),dp;
+  whichvariable(x5);
+  whichvariable(x3y);
+}
+///////////////////////////////////////////////////////////////////////////////
+proc varsigns(list l)
+"USAGE:     varsigns(l); list l.
+RETURN:    int: the number of sign changes in the list l
+SEE ALSO:  boundposDes
+EXAMPLE:   example varsigns; shows an example"
+{
+  int lastsign;
+  int numberofchanges = 0;
+
+  if (isparam(l)) {
+    ERROR("This procedure cannot operate with parametric arguments");
+  }
+
+  lastsign = sign(l[1]);
+
+  for (int i = 1; i <= size(l); i++)
+  {
+    if (sign(l[i]) != lastsign && sign(l[i]) != 0)
+    {
+      numberofchanges++;
+      lastsign = sign(l[i]);
+    }
+  }
+  return (numberofchanges);
+}
+example
+{
+  echo = 2;
+  ring r = 0,x,dp;
+  list l = 1,2,3;
+  varsigns(l);
+  l = 1,-1,2,-2,3,-3;
+  varsigns(l);
+}
+///////////////////////////////////////////////////////////////////////////////
+proc boundBuFou(poly p,number a,number b)
+"USAGE:     boundBuFou(p,a,b); p poly, a,b number
+RETURN:    int: an upper bound for the number of real roots of p in (a,b],
+           with the same parity as the actual number of roots (using the
+           Budan-Fourier Theorem)
+ASSUME:    - p is a univariate polynomial with rational coefficients@*
+           - a, b are rational numbers with a < b
+SEE ALSO:  boundposDes,varsigns
+EXAMPLE:   example boundBuFou; shows an example"
+{
+  int i;
+  poly variable;
+  list Der;
+  list Dera,Derb;
+  int d;
+  number bound;
+
+  variable = isuni(p);
+
+  if (isparam(p) || isparam(a) || isparam(b)) {
+    ERROR("This procedure cannot operate with parametric arguments");
+  }
+
+  // p must be a univariate polynomial
+  if (variable == 0) {
+    ERROR("p must be a univariate polynomial");
+  }
+
+  if (a >= b) {
+    ERROR("a must be smaller than b");
+  }
+
+  d = deg(p);
+
+  // We calculate the list of derivatives
+
+  Der[d+1] = p;
+
+  for (i = 0;i < d;i++) {
+    Der[d-i] = diff(Der[d-i+1],variable);
+  }
+
+  // Then evaluate that list
+
+  for (i = d+1;i >= 1;i--) {
+    Dera [i] = leadcoef(subst(Der[i],variable,a));
+    Derb [i] = leadcoef(subst(Der[i],variable,b));
+  }
+
+  // Finally we calculate the sign variations
+
+  bound = varsigns(Dera) - varsigns(Derb);
+
+  return(bound);
+}
+example
+{
+  echo = 2;
+  ring r = 0,x,dp;
+  poly p = (x+2)*(x-1)*(x-5);
+  boundBuFou(p,-3,5);
+  boundBuFou(p,-2,5);
+}
+///////////////////////////////////////////////////////////////////////////////
+proc boundposDes(poly p)
+"USAGE:     boundposDes(p); poly p
+RETURN:    int: an upper bound for the number of positive roots of p, with
+           the same parity as the actual number of positive roots of p.
+ASSUME:    p is a univariate polynomial with rational coefficients
+SEE ALSO:  boundBuFou
+EXAMPLE:   example boundposDes; shows an example"
+{
+  poly g;
+  number nroots;
+  poly variable;
+  list coefficients;
+  int i;
+
+  variable = isuni(p);
+
+  if (isparam(p)) {
+    ERROR("This procedure cannot operate with parametric arguments");
+  }
+
+  // p must be a univariate polynomial
+  if (variable == 0) {
+    ERROR("p must be a univariate polynomial");
+  }
+
+  g = p; // We will work with g
+
+  // We check whether 0 is a root of g, and if so, remove it
+  if (subst(g,variable,0) == 0) {
+    g = g/variable^(deg(g[size[g]]));
+  }
+
+  // We count the number of positive roots
+  i = size(g);
+  while (i >= 1) {
+    coefficients[i] = leadcoef(g[i]);
+    i--;
+  }
+  nroots = varsigns(coefficients);
+
+  return(nroots);
+}
+example
+{
+  echo = 2;
+  ring r = 0,x,dp;
+  poly p = (x+2)*(x-1)*(x-5);
+  boundposDes(p);
+
+  p = p*(x2+1);
+
+  boundposDes(p);
+}
+///////////////////////////////////////////////////////////////////////////////
+proc boundDes(poly p)
+"USAGE:     boundDes(p); poly p
+RETURN:    int: an upper bound for the number of real roots of p, with
+           the same parity as the actual number of real roots of p.
+ASSUME:    p is a univariate polynomial with rational coefficients
+SEE ALSO:  boundBuFou
+EXAMPLE:   example boundDes; shows an example"
+{
+  poly g;
+  number nroots;
+  poly variable;
+  list coefficients;
+  int i;
+
+  variable = isuni(p);
+
+  if (isparam(p)) {
+    ERROR("This procedure cannot operate with parametric arguments");
+  }
+
+  // p must be a univariate polynomial
+  if (variable == 0) {
+    ERROR("p must be a univariate polynomial");
+  }
+
+  g = p; // We will work with g
+
+  nroots = 0;
+  // We check whether 0 is a root of g, and if so, remove it
+  if (subst(g,variable,0) == 0) {
+    g = g/variable^(deg(g[size[g]]));
+    nroots++;
+  }
+
+  // We count the number of positive roots
+  i = size(g);
+  while (i >= 1) {
+    coefficients[i] = leadcoef(g[i]);
+    i--;
+  }
+  nroots = nroots + varsigns(coefficients);
+
+  // We count the number of negative roots
+  g = subst(g,variable,-variable);
+  i = size(g);
+  while (i >= 1) {
+    coefficients[i] = leadcoef(g[i]);
+    i--;
+  }
+  nroots = nroots + varsigns(coefficients);
+
+  return(nroots);
+}
+example
+{
+  echo = 2;
+  ring r = 0,x,dp;
+  poly p = (x+2)*(x-1)*(x-5);
+  boundDes(p);
+
+  p = p*(x2+1);
+
+  boundDes(p);
+}
+///////////////////////////////////////////////////////////////////////////////
+proc allrealst(poly p)
+"USAGE:     allrealst(p); poly p
+RETURN:    int: 1 if and only if all the roots of p are real, 0 otherwise.
+           Checks by using Sturm's Theorem whether all the roots of p are real
+ASSUME:    p is a univariate polynomial with rational coefficients
+SEE ALSO:  allreal,sturm,sturmha
+EXAMPLE:   example allrealst; shows an example"
+{
+  number upper,lower;
+  poly sqfp; // The square-free part of p
+  poly variable;
+
+  variable = isuni(p);
+
+  if (isparam(p)) {
+    ERROR("This procedure cannot operate with parametric arguments");
+  }
+  if (variable == 0) {
+    ERROR ("p must be a univariate polynomial");
+  }
+
+  sqfp = p/gcd(p,diff(p,variable));
+
+  upper = maxabs(sqfp); // By adding one we ensure that sqfp(upper) != 0
+  lower = -upper;
+
+  return (sturm(sqfp,lower,upper) == deg(sqfp));
+}
+example
+{
+  echo = 2;
+  ring r = 0,x,dp;
+  poly p = (x+2)*(x-1)*(x-5);
+  allrealst(p);
+  p = p*(x2+1);
+  allrealst(p);
+}
+///////////////////////////////////////////////////////////////////////////////
+proc maxabs(poly p)
+"USAGE:     maxabs(p); poly p
+RETURN:    number: an upper bound for the largest absolute value of a root of p
+ASSUME:    p is a univariate polynomial with rational coefficients
+SEE ALSO:  sturm
+EXAMPLE:   example maxabs; shows an example"
+{
+  number maximum;
+  poly monic;
+  int i;
+
+  if (isparam(p)) {
+    ERROR("This procedure cannot operate with parametric arguments");
+  }
+
+  monic =  simplify(p,1);
+
+  maximum = 0;
+
+  for (i = 1; i <= size(monic); i++)
+  {
+    maximum = max(abs(leadcoef(p[i])),maximum);
+  }
+
+  return (maximum + 1);
+}
+example
+{
+  echo = 2;
+  echo = 2;
+  ring r = 0,x,dp;
+  poly p = (x+2)*(x-1)*(x-5);
+  maxabs(p);
+}
+///////////////////////////////////////////////////////////////////////////////
+proc sturm(poly p,number a,number b)
+"USAGE:     sturm(p,a,b); poly p, number a,b
+RETURN:    int: the number of real roots of p in (a,b]
+ASSUME:    p is a univariate polynomial with rational coefficients,@*
+           a, b are rational numbers with a < b
+SEE ALSO:  sturmha,allrealst,allreal
+EXAMPLE:   example sturm; shows an example"
+{
+  list l;
+  list pa;
+  list pb;
+  int signsA,signsB;
+  int i;
+  int nroots;
+  poly variable;
+
+  if (isparam(p)) {
+    ERROR("This procedure cannot operate with parametric arguments");
+  }
+
+  variable = isuni(p);
+
+  if (variable == 0) {
+    ERROR ("p must be a univariate polynomial");
+  }
+
+  if (a >= b) {
+    ERROR("a must be lower than b");
+  }
+
+  if (subst(p,variable,a) == 0 || subst(p,variable,b) == 0) {
+    ERROR ("Neither a nor b can be roots of P");
+  }
+
+  l = sturmseq(p);
+
+  i = size(l);
+
+  while (i >= 1) { // We build the sequences
+    pa[i] = leadcoef(subst(l[i],variable,a));
+    pb[i] = leadcoef(subst(l[i],variable,b));
+    i--;
+  }
+
+  signsA = varsigns(pa);
+  signsB = varsigns(pb);
+
+  nroots = signsA - signsB + nroots;
+
+  return (nroots);
+}
+example
+{
+  echo = 2;
+  ring r = 0,x,dp;
+  poly p = (x+2)*(x-1)*(x-5);
+  sturm(p,-3,6);
+  p = p*(x2+1);
+  sturm(p,-3,6);
+  p = p*(x+2);
+  sturm(p,-3,6);
+}
+///////////////////////////////////////////////////////////////////////////////
+proc sturmseq(poly p)
+"USAGE:     sturmseq(p); p poly
+RETURN:    list: a Sturm sequence of p
+ASSUME:    p is a univariate polynomial with rational coefficients
+THEORY:    The Sturm sequence of p (also called remainder sequence) is the
+           sequence beginning with p, p' and goes on with the negative part of
+           the remainder of the two previous polynomials, until the remainder
+           is zero.
+           See: Basu, Pollack, Roy, Algorithms in Real Algebraic Geometry,
+           Springer, 2003.
+SEE ALSO:  sturm,sturmhaseq
+EXAMPLE:   example sturmseq; shows an example"
+{
+  list stseq;
+  poly variable;
+  int i;
+
+  variable = isuni(p);
+
+  if (isparam(p)) {
+    ERROR("This procedure cannot operate with parametric arguments");
+  }
+
+  if (variable == 0) {
+    ERROR ("p must be a univariate polynomial");
+  }
+
+  // The two first polynomials in Sturm's sequence
+  stseq = list();
+  stseq[1] = p;
+  stseq[2] = diff(p,variable);
+
+  poly q = -reduce(stseq[1],std(stseq[2]));
+  i = 3;
+
+  while (q <> 0) {
+    stseq[i] = q;
+    q = -reduce(stseq[i-1],std(stseq[i]));
+    i++;
+  }
+
+  // Right now, we have gcd(P,P') in stseq[size(stseq)];
+
+  for (i = size(stseq)-1;i >= 1;i--) {
+    stseq[i] = stseq[i]/(sign(leadcoef(stseq[size(stseq)]))*stseq[size(stseq)]);
+    stseq[i] = stseq[i]/abs(leadcoef(stseq[i]));
+  }
+
+  // We divide the gcd by itself
+  stseq[size(stseq)] = sign(leadcoef(stseq[size(stseq)]));
+
+  return (stseq);
+}
+example
+{
+  echo = 2;
+  ring r = 0,(z,x),dp;
+  poly p = x5-3x4+12x3+7x-153;
+  sturmseq(p);
+}
+///////////////////////////////////////////////////////////////////////////////
+proc allreal(poly p)
+"USAGE:     allreal(p);
+RETURN:    int: 1 if and only if all the roots of p are real, 0 otherwise
+SEE ALSO:  allrealst
+EXAMPLE:   example allreal; shows an example"
+{
+  number upper,lower;
+  poly sqfp; // The square-free part of p
+  poly variable;
+
+  if (isparam(p)) {
+    ERROR("This procedure cannot operate with parametric arguments");
+  }
+
+  variable = isuni(p);
+
+  if (variable == 0) {
+    ERROR ("p must be a univariate polynomial");
+  }
+
+  sqfp = p/gcd(p,diff(p,variable));
+
+  return (sturmha(sqfp,-maxabs(p),maxabs(p)) == deg(sqfp));
+}
+example
+{
+  echo = 2;
+  ring r = 0,x,dp;
+  poly p = (x+2)*(x-1)*(x-5);
+  allreal(p);
+  p = p*(x2+1);
+  allreal(p);
+}
+///////////////////////////////////////////////////////////////////////////////
+proc sturmha(poly P,number a,number b)
+"USAGE:     sturmha(p,a,b); poly p, number a,b
+RETURN:    int: the number of real roots of p in (a,b) (using a Sturm-Habicht sequence)
+SEE ALSO:  sturm,allreal
+EXAMPLE:   example sturmha; shows an example"
+{
+  list seq;
+  int i;
+  list seqa,seqb;
+  poly variable;
+  number bound;
+  //number result;
+  int result;
+
+  if (isparam(P) || isparam(a) || isparam(b))
+  { ERROR("This procedure cannot operate with parametric arguments"); }
+  if (!attrib(basering,"global"))
+  { ERROR("This procedure requires a global ordering"); }
+
+  variable = isuni(P);
+
+  if (variable == 0) { ERROR ("P must be a univariate polynomial"); }
+
+  if (a >= b) { ERROR("a must be lower than b"); }
+
+  if (subst(P,variable,a) == 0 || subst(P,variable,b) == 0) {
+    ERROR ("Neither a nor b can be roots of P");
+  }
+
+  seq = sturmhaseq(P);
+
+  bound = maxabs(P);
+
+  if (a < -bound) { a = -bound; }
+
+  if (b > bound) { b = bound; }
+
+//  if (a == -bound && b == bound) {
+//    for (i = size(seq);i >= 1;i--) {
+//      seq[i] = leadcoef(seq[i]);
+//    }
+//    result = D(seq);
+//  } else {
+    for (i = size(seq);i >= 1;i--) {
+      seqa[i] = leadcoef(subst(seq[i],variable,a));
+      seqb[i] = leadcoef(subst(seq[i],variable,b));
+    }
+    result = (W(seqa) - W(seqb));
+//  }
+  return (result);
+}
+example
+{
+  echo = 2;
+  ring r = 0,x,dp;
+  poly p = (x+2)*(x-1)*(x-5);
+  sturmha(p,-3,6);
+  p = p*(x2+1);
+  sturmha(p,-3,6);
+}
+///////////////////////////////////////////////////////////////////////////////
+proc sturmhaseq(poly P)
+"USAGE:     sturmhaseq(P); P poly.
+RETURN:    list: the non-zero polynomials of the Sturm-Habicht sequence of P
+ASSUME:    P is a univariate polynomial.
+THEORY:    The Sturm-Habicht sequence (also subresultant sequence) is closely
+           related to the Sturm sequence, but behaves better with respect to
+           the size of the coefficients. It is defined via subresultants.
+           See: Basu, Pollack, Roy, Algorithms in Real Algebraic Geometry,
+           Springer, 2003.
+SEE ALSO:  sturm,sturmseq,sturmha
+EXAMPLE:   example sturmhaseq; shows an example"
+{
+  poly Q;
+  poly variable;
+  int p,q,i,j,k,l;
+  list SR;
+  list sr;
+  list srbar;
+  list T;
+
+  if (isparam(P)) {
+    ERROR("This procedure cannot operate with parametric arguments");
+  }
+
+  variable = isuni(P);
+
+  if (variable == 0) {
+    ERROR ("P must be a univariate polynomial");
+  }
+
+  p = deg(P);
+  Q = diff(P,variable);
+  q = deg(Q);
+
+  // Initialization
+  SR[p+2] = sign(leadcoef(P)^(p-q-1))*P;
+//  T[p+2] = SR[p+2];
+
+  srbar[p+2] = sign(leadcoef(P)^(p-q));
+  sr[p+2] = srbar[p+2];
+
+  SR[p-1+2] = sign(leadcoef(P)^(p-q+1))*Q;
+//  T[p-1+2] = SR[p-1+2];
+  srbar[p-1+2] = sign(leadcoef(P)^(p-q+1))*leadcoef(Q);
+
+  i = p+1;
+  j = p;
+
+  while (SR[j-1+2] != 0) {
+    k = deg(SR[j-1+2]);
+    if (k == j-1) {
+      sr[j-1+2] = srbar[j-1+2];
+      SR[k-1+2] = -(reduce(sr[j-1+2]^2*SR[i-1+2],
+                    std(SR[j-1+2])))/(sr[j+2]*srbar[i-1+2]);
+
+//      T[k-1+2] = SR[k-1+2];
+      srbar[k-1+2] = leadcoef(SR[k-1+2]);
+    }
+    if (k < j-1) {
+      // Computation of sr[k+2]
+      for (l = 1;l <= j-k-1;l++) {
+        srbar[j-l-1+2] = ((-1)^l)*(srbar[j-1+2]*srbar[j-l+2])/sr[j+2];
+    }
+    sr[k+2] = srbar[k+2];
+
+      // Computation of SR[k-1+2]
+      SR[k-1+2] = -reduce(srbar[j-1+2]*sr[k+2]*SR[i-1+2],
+                  std(SR[j-1+2]))/(sr[j+2]*srbar[i-1+2]);
+
+      srbar[k-1+2] = leadcoef(SR[k-1+2]);
+
+      SR[k+2] = SR[j-1+2] * ( sr[k+2] / leadcoef(SR[j-1+2]));
+    }
+    i = j;
+    j = k;
+  }
+
+  // We build a new list, discarding the undefined and zero elements
+  // Plus, we reverse the elements
+
+  list filtered;
+  i = size(SR);
+  while (i >= 1) {
+    if (typeof(SR[i]) != "none") {
+      if (SR[i] != 0) {
+        filtered = insert(filtered,SR[i]);
+      }
+    }
+    i--;
+  }
+
+  return (filtered);
+}
+example
+{
+  echo = 2;
+  ring r = 0,x,dp;
+  poly p = x5-x4+x-3/2;
+  list l = sturmhaseq(p);
+  l;
+}
+///////////////////////////////////////////////////////////////////////////////
+proc nrroots(poly p)
+"USAGE:     nrroots(p); poly p
+RETURN:    int: the number of real roots of p
+SEE ALSO:  boundposDes, sturm, sturmha
+EXAMPLE:   example nrroots; shows an example"
+{
+  if (isparam(p))
+  { ERROR("This procedure cannot operate with parametric arguments"); }
+
+  number a = maxabs(p);
+
+  return (sturmha(p,-a,a));
+
+}
+example
+{
+  echo = 2;
+  ring r = 0,x,dp;
+  poly p = (x+2)*(x-1)*(x-5);
+  nrroots(p);
+  p = p*(x2+1);
+  nrroots(p);
+}
+///////////////////////////////////////////////////////////////////////////////
+static proc abs(number x)
+  // Returns the absolute value of x
+{
+  number av;
+
+  if (x >= 0) {
+    av = x;
+  } else {
+    av = -x;
+  }
+
+  return (av);
+}
+///////////////////////////////////////////////////////////////////////////////
+proc sign(number x)
+{
+  int sgn;
+
+  if (isparam(x)) {
+    print(x);
+    ERROR("This procedure cannot operate with parameters");
+  }
+
+  if (x > 0) {
+    sgn = 1;
+  } else { if (x < 0) {
+    sgn = -1;
+  } else {
+    sgn = 0;
+  }}
+
+  return (sgn);
+}
+///////////////////////////////////////////////////////////////////////////////
+proc reverse(list l)
+"USAGE:     reverse(l); l list
+RETURN:    list: l reversed.
+EXAMPLE:   example reverse; shows an example"
+{
+  int i;
+  list result;
+
+  for (i = 1;i <= size(l);i++) {
+    result = list(l[i]) + result;
+  }
+  return (result);
+}
+example
+{
+  echo = 2;
+  ring r = 0,x,dp;
+  list l = 1,2,3,4,5;
+  list rev = reverse(l);
+  l;
+  rev;
+}
+///////////////////////////////////////////////////////////////////////////////
+static proc D(list l)
+{
+  int p;
+  int q;
+  int i;
+  int sc; // The modified number of sign changes
+
+  if (l[size(l)] == 0) {
+    ERROR("l[size(l)] cannot be 0");
+  }
+
+  sc = 0;
+
+  // We know that l[size(l)]] != 0
+  p = size(l);
+  q = p - 1;
+
+  while (searchnot(l,q,-1,0)) {
+    q = searchnot(l,q,-1,0);
+    if ((p - q) % 2 == 1) { // if p-q is odd
+      sc = sc + ((-1)^(((p-q)*(p-q-1)) / 2))*sign(l[p]*l[q]);
+    }
+    p = q;
+    q = p - 1;
+  }
+
+  return (sc);
+}
+///////////////////////////////////////////////////////////////////////////////
+static proc search(list l,int from,int dir,number element)
+{
+  int i;
+  int result;
+  i = from;
+
+  result = 0;
+
+  while (i + dir >= 0 && i + dir <= size(l) + 1 && !result)
+  {
+    if (l[i] == element) { result = i; }
+    i = i + dir;
+  }
+
+  return (result);
+}
+///////////////////////////////////////////////////////////////////////////////
+static proc searchnot(list l,int from,int dir,number element)
+{
+  int i;
+  int result;
+  i = from;
+
+  result = 0;
+
+  while (i + dir >= 0 && i + dir <= size(l) + 1 && !result)
+  {
+    if (l[i] != element) { result = i; }
+    i = i + dir;
+  }
+
+  return (result);
+}
+///////////////////////////////////////////////////////////////////////////////
+static proc W(list l)
+{
+  int i,temp,sc,lastsign,nofzeros,n;
+
+  n = size(l);
+  sc = 0;
+  nofzeros = 0;
+  i = 1;
+  lastsign = sign(l[i]);
+
+  i++;
+
+  while (i <= n) {
+    if (l[i] == 0) {
+      nofzeros++;
+    } else {
+      temp = lastsign * sign(l[i]);
+
+      if (temp < 0) {
+        sc++;
+      } else {
+        if (nofzeros == 2) {
+          sc = sc + 2;
+        }
+      }
+      nofzeros = 0;
+      lastsign = temp div lastsign;
+    }
+    i++;
+  }
+  return (sc);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+
+
+
diff --git a/Singular/LIB/sagbi.lib b/Singular/LIB/sagbi.lib
new file mode 100644
index 0000000..6bd7f3f
--- /dev/null
+++ b/Singular/LIB/sagbi.lib
@@ -0,0 +1,1254 @@
+///////////////////////////////////////////////////////////////////////////
+version="version sagbi.lib 4.0.0.0 Jun_2013 "; // $Id: 90b5bf132ba4929bc0aebcdf438de3763af30d12 $
+category="Commutative Algebra";
+info="
+LIBRARY: sagbi.lib  Compute SAGBI basis (subalgebra bases analogous to Groebner bases for ideals) of a subalgebra
+AUTHORS: Jan Hackfeld,     Jan.Hackfeld at rwth-aachen.de
+         Gerhard Pfister,  pfister at mathematik.uni-kl.de
+         Viktor Levandovskyy,     levandov at math.rwth-aachen.de
+
+OVERVIEW:
+SAGBI stands for 'subalgebra bases analogous to Groebner bases for ideals'.
+SAGBI bases provide important tools for working with finitely presented
+subalgebras of a polynomial ring. Note, that in contrast to Groebner
+bases, SAGBI bases may be infinite.
+
+REFERENCES:
+Ana Bravo: Some Facts About Canonical Subalgebra Bases,
+MSRI Publications  51, p. 247-254
+
+PROCEDURES:
+ sagbiSPoly(A [,r,m]); computes SAGBI S-polynomials of A
+ sagbiReduce(I,A [,t,mt]);  performs subalgebra reduction of I by A
+ sagbi(A [,m,t]);      computes SAGBI basis for A
+ sagbiPart(A,k[,m]);   computes partial SAGBI basis for A
+ algebraicDependence(I,it); performs iterations of SAGBI for algebraic dependencies of I
+
+SEE ALSO: algebra_lib
+";
+
+LIB "elim.lib";
+LIB "toric.lib";
+LIB "algebra.lib";
+//////////////////////////////////////////////////////////////////////////////
+
+static proc assumeQring()
+{
+  if (ideal(basering) != 0)
+  {
+    ERROR("This function has not yet been implemented over qrings.");
+  }
+}
+
+
+static proc uniqueVariableName (string variableName)
+{
+  //Adds character "@" at the beginning of variableName until this name ist unique
+  //(not contained in the names of the ring variables or description of the coefficient field)
+  string ringVars = charstr(basering) + "," + varstr(basering);
+  while (find(ringVars,variableName) <> 0)
+  {
+    variableName="@"+variableName;
+  }
+  return(variableName);
+}
+
+static proc extendRing(def r, ideal leadTermsAlgebra, int method) {
+  /* Extends ring r with additional variables. If k=ncols(leadTermsAlgebra) and
+   * r contains already m additional variables @y, the procedure adds k-m variables
+   * @y(m+1)... at y(k) to the ring.
+   * The monomial ordering of the extended ring depends on method.
+   * Important: When calling this function, the basering (where algebra is defined) has to be active
+   */
+  def br=basering;
+  int i;
+  ideal varsBasering=maxideal(1);
+  int numTotalAdditionalVars=ncols(leadTermsAlgebra);
+  string variableName=uniqueVariableName("@y");
+  //get a variable name different from existing variables
+
+  //-------- extend current baserring r with new variables @y,
+  // one for each new element in ideal algebra  -------------
+  setring r;
+  list l = ringlist(r);
+  for (i=nvars(r)-nvars(br)+1; i<=numTotalAdditionalVars;i++)
+  {
+    l[2][i+nvars(br)]=string(variableName,"(",i,")");
+  }
+  if (method>=0 && method<=1)
+  {
+    if (nvars(r)==nvars(br))
+    {        //first run of spolynomialGB in sagbi construction algorithms
+      l[3][size(l[3])+1]=l[3][size(l[3])]; //save module ordering
+      l[3][size(l[3])-1]=list("dp",intvec(1:numTotalAdditionalVars));
+    }
+    else
+    {        //overwrite existing order for @y(i) to only get one block for the @y
+      l[3][size(l[3])-1]=list("dp",intvec(1:numTotalAdditionalVars));
+    }
+  }
+  // VL : todo noncomm case: correctly use l[5] and l[6]
+  // that is update matrices
+  // at the moment this is troublesome, so use nc_algebra call
+  // see how it done in algebraicDependence proc // VL
+  def rNew=ring(l);
+  setring br;
+  return(rNew);
+}
+
+
+static proc stdKernPhi(ideal kernNew, ideal kernOld, ideal leadTermsAlgebra,int method)
+{
+  /* Computes Groebner basis of kernNew+kernOld, where kernOld already is a GB
+   * and kernNew contains elements of the form @y(i)-leadTermsAlgebra[i] added to it.
+   * The techniques chosen is specified by the integer method
+   */
+  ideal kern;
+  attrib(kernOld,"isSB",1);
+  if (method==0)
+  {
+    kernNew=reduce(kernNew,kernOld);
+    kern=kernOld+kernNew;
+    kern=std(kern);
+    //kern=std(kernOld,kernNew); //Found bug using this method.
+    // TODO Change if bug is removed
+    //this call of std return Groebner Basis of ideal kernNew+kernOld
+    // given that kernOld is a Groebner basis
+  }
+  if (method==1)
+  {
+    kernNew=reduce(kernNew,kernOld);
+    kern=slimgb(kernNew+kernOld);
+  }
+  return(kern);
+}
+
+
+static proc spolynomialsGB(ideal algebra,def r,int method)
+{
+  /* This procedure does the actual S-polynomial calculation using Groebner basis methods and is
+   * called by the procedures sagbiSPoly,sagbi and sagbiPart. As this procedure is called
+   * at each step of the SAGBI construction algorithm, we can reuse the information already calculated
+   * which is contained in the ring r. This is done in the following order
+   * 1. If r already contain m additional variables and m'=number of elements in algebra, extend r with variables @y(m+1),..., at y(m')
+   * 2. Transfer all objects to this ring, kernOld=kern is the Groebnerbasis already computed
+   * 3. Define ideal kernNew containing elements of the form leadTermsAlgebra(m+1)- at y(m+1),...,leadTermsAlgebra(m')- at y(m')
+   * 4. Compute Groebnerbasis of kernOld+kernNew
+   * 5. Compute the new algebraic relations
+   */
+  int ppl = printlevel-voice+3; //variable for additional printlevel-dependend information
+  dbprint(ppl,"//Spoly-1- initialisation and precomputation");
+  def br=basering;
+  ideal varsBasering=maxideal(1);
+  ideal leadTermsAlgebra=lead(algebra);
+  //save leading terms as ordering in ring extension
+  //may not be compatible with ordering in basering
+  int numGenerators=ncols(algebra);
+
+  def rNew=extendRing(r,leadTermsAlgebra,method);
+  // important: br has to be active here
+  setring r;
+  if (!defined(kern))
+  //only true for first run of spolynomialGB in sagbi construction algorithms
+  {
+    ideal kern=0;
+    ideal algebraicRelations=0;
+  }
+  setring rNew;
+  //-------------------------- transfer object to new ring rNew ----------------------
+  ideal varsBasering=fetch(br,varsBasering);
+  ideal kernOld,algebraicRelationsOld;
+  kernOld=fetch(r,kern); //kern is Groebner basis of the kernel of the map Phi:r->K[x_1,...,x_n], x(i)->x(i), @y(i)->leadTermsAlgebra(i)
+  algebraicRelationsOld=fetch(r,algebraicRelations);
+  ideal leadTermsAlgebra=fetch(br,leadTermsAlgebra);
+  ideal listOfVariables=maxideal(1);
+  //---------define kernNew containing elements to be added to the ideal kern --------
+  ideal kernNew;
+  for (int i=nvars(r)-nvars(br)+1; i<=numGenerators; i++)
+  {
+    kernNew[i-nvars(r)+nvars(br)]=leadTermsAlgebra[i]-listOfVariables[i+nvars(br)];
+  }
+  //--------------- calculate kernel of Phi depending on method chosen ---------------
+  dbprint(ppl,"//Spoly-2- Groebner basis computation");
+  attrib(kernOld,"isSB",1);
+  ideal kern=stdKernPhi(kernNew,kernOld,leadTermsAlgebra,method);
+  dbprint(ppl-2,"//Spoly-2-1- ideal kern",kern);
+  //-------------------------- calulate algebraic relations -----------------------
+  dbprint(ppl,"//Spoly-3- computing new algebraic relations");
+  ideal algebraicRelations=nselect(kern,1..nvars(br));
+  attrib(algebraicRelationsOld,"isSB",1);
+  ideal algebraicRelationsNew=reduce(algebraicRelations,algebraicRelationsOld);
+  /* canonicalizing: */
+  algebraicRelationsNew=canonicalform(algebraicRelationsNew);
+  dbprint(ppl-2,"//Spoly-3-1- ideal of new algebraic relations",algebraicRelationsNew);
+  /*        algebraicRelationsOld is a groebner basis by construction (as variable
+   *        ordering is
+   *        block ordering we have an elemination ordering for the varsBasering)
+   *        Therefore, to only get the new algebraic relations, calculate
+   *        <algebraicRelations>\<algebraicRelationsOld> using groebner reduction
+   */
+  kill kernOld,kernNew,algebraicRelationsOld,listOfVariables;
+  export algebraicRelationsNew,algebraicRelations,kern;
+  setring br;
+  return(rNew);
+}
+
+static proc spolynomialsToric(ideal algebra) {
+  /* This procedure does the actual S-polynomial calculation using toric.lib for
+   * computation of a Groebner basis for the toric ideal kern(phi), where
+   * phi:K[y_1,...,y_m]->K[x_1,...,x_n], y_i->leadmonom(algebra[i])
+   * By suitable substitutions we obtain the kernel of the map
+   * K[y_1,...,y_m]->K[x_1,...,x_n], x(i)->x(i), @y(i)->leadterm(algebra[i])
+   */
+  int ppl = printlevel-voice+3; //variable for additional printlevel-dependend information
+  dbprint(ppl,"//Spoly-1- initialisation and precomputation");
+  def br=basering;
+  int m=ncols(algebra);
+  int n=nvars(basering);
+  intvec tempVec;
+  int i,j;
+  ideal leadCoefficients;
+  for (i=1;i<=m; i++)
+  {
+    leadCoefficients[i]=leadcoef(algebra[i]);
+  }
+  dbprint(ppl-2,"//Spoly-1-1- Vector of leading coefficients",leadCoefficients);
+  int k=1;
+  for (i=1;i<=n;i++)
+  {
+    for (j=1; j<=m; j++)
+    {
+      tempVec[k]=leadexp(algebra[j])[i];
+      k++;
+    }
+  }
+  //The columns of the matrix A are now the exponent vectors
+  //of the leadings monomials in algebra.
+  intmat A[n][m]=intmat(tempVec,n,m);
+  dbprint(ppl-2,"//Spoly-1-2- Matrix A",A);
+  //Create the preimage ring K[@y(1),..., at y(m)], where m=ncols(algebra).
+  string variableName=uniqueVariableName("@y");
+  list l = ringlist(basering);
+  for (i=1; i<=m;i++)
+  {
+    l[2][i]=string(variableName,"(",i,")");
+  }
+  l[3][2]=l[3][size(l[3])];
+  l[3][1]=list("dp",intvec(1:m));
+  def rNew=ring(l);
+  setring rNew;
+  //Use toric_ideal to compute the kernel
+   dbprint(ppl,"//Spoly-2- call of toric_ideal");
+  ideal algebraicRelations=toric_ideal(A,"ect");
+  //Suitable substitution
+        dbprint(ppl,"//Spoly-3- substitutions");
+  ideal leadCoefficients=fetch(br,leadCoefficients);
+  for (i=1; i<=m; i++)
+  {
+    if (leadCoefficients[i]!=0)
+    {
+      algebraicRelations=subst(algebraicRelations,var(i),1/leadCoefficients[i]*var(i));
+    }
+  }
+        dbprint(ppl-2,"//Spoly-3-1- algebraic relations",algebraicRelations);
+  export algebraicRelations;
+  return(rNew);
+}
+
+
+static proc reductionGB(ideal F, ideal algebra,def r, int tailreduction,int method,int parRed)
+{
+  /* This procedure does the actual SAGBI/subalgebra reduction using GB methods and is
+   * called by the procedures sagbiReduce,sagbi and sagbiPart
+   * If r already is an extension of the basering
+   * and contains the ideal kern needed for the subalgebra reduction,
+   * the reduction can be started directly, at each reduction step using the fact that
+   * p=reduce(leadF,kern) in K[@y(1),..., at y(m)] <=> leadF in K[lead(algebra)]
+   * Otherwise some precomputation has to be done, outlined below.
+   * When using sagbiReduce,sagbi and sagbiPart the integer parRed will always be zero. Only the procedure
+   * algebraicDependence causes this procedure to be called with parRed<>0. The only difference when parRed<>0
+   * is that the reduction algorithms returns the non-zero constants it attains (instead of just returning zero as the
+         * correct remainder), as they will be expressions in parameters for an algebraic dependence.
+   */
+  int ppl = printlevel-voice+3; //variable for additional printlevel-dependend information
+  dbprint(ppl,"//Red-1- initialisation and precomputation");
+  def br=basering;
+  int numVarsBasering=nvars(br);
+  ideal varsBasering=maxideal(1);
+  int i;
+
+  if (numVarsBasering==nvars(r))
+  {
+                dbprint(ppl-1,"//Red-1-1- Groebner basis computation");
+    /* Case that ring r is the same ring as the basering. Using proc extendRing,
+     * stdKernPhi
+     * one construct the extension of the current baserring with new variables @y, one for each element
+     * in ideal algebra and calculates the kernel of Phi, where
+     * Phi: r---->br, x_i-->x_i, y_i-->f_i,
+     * algebra={f_1,...f_m}, br=K[x1,...,x_n] und r=K[x1,...x_n, at y1,... at y_m]
+     * This is similarly dones
+     * (however step by step for each run of the SAGBI construction algorithm)
+     * in the procedure spolynomialsGB
+     */
+    ideal leadTermsAlgebra=lead(algebra);
+    kill r;
+    def r=extendRing(br,leadTermsAlgebra,method);
+    setring r;
+    ideal listOfVariables=maxideal(1);
+    ideal leadTermsAlgebra=fetch(br,leadTermsAlgebra);
+    ideal kern;
+    for (i=1; i<=ncols(leadTermsAlgebra); i++)
+    {
+      kern[i]=leadTermsAlgebra[i]-listOfVariables[numVarsBasering+i];
+    }
+    kern=stdKernPhi(kern,0,leadTermsAlgebra,method);
+    dbprint(ppl-2,"//Red-1-1-1- Ideal kern",kern);
+  }
+  setring r;
+  poly p,leadF;
+  ideal varsBasering=fetch(br,varsBasering);
+  setring br;
+  map phi=r,varsBasering,algebra;
+  poly p,normalform,leadF;
+  intvec tempExp;
+  //-------------algebraic reduction for each polynomial F[i] ------------------------
+  dbprint(ppl,"//Red-2- reduction, polynomial by polynomial");
+  for (i=1; i<=ncols(F);i++)
+  {
+                dbprint(ppl-1,"//Red-2-"+string(i)+"- starting with new polynomial");
+                dbprint(ppl-2,"//Red-2-"+string(i)+"-1- Polynomial before reduction",F[i]);
+    normalform=0;
+    while (F[i]!=0)
+    {
+      leadF=lead(F[i]);
+      if(leadmonom(leadF)==1)
+      {
+      //K is always contained in the subalgebra,
+      //thus the remainder is zero in this case
+        if (parRed)
+        {
+                                //If parRed<>0 save non-zero constants the reduction algorithms attains.
+                                        break;
+                                }
+        else
+        {
+                                        F[i]=0;
+                                        break;
+                                }
+      }
+      //note: as the ordering in br and r might not be compatible
+      //it can be that lead(F[i]) in r is
+      //different from lead(F[i]) in br.
+      //To take the "correct" leading term therefore take lead(F[i])
+      //in br and transfer it to the extension r
+      setring r;
+      leadF=fetch(br,leadF);
+      p=reduce(leadF,kern);
+      if (leadmonom(p)<varsBasering[numVarsBasering])
+      {
+        //as chosen ordering is a block ordering,
+        //lm(p) in K[y_1...y_m] is equivalent to lm(p)<x_n
+        //Needs to be changed, if no block ordering is used!
+        setring br;
+        F[i]=F[i]-phi(p);
+      }
+      else
+      {
+        if (tailreduction)
+        {
+          setring br;
+          normalform=normalform+lead(F[i]);
+          F[i]=F[i]-lead(F[i]);
+        }
+        else
+        {
+          setring br;
+          break;
+        }
+      }
+    }
+    if (tailreduction)
+    {
+      F[i] = normalform;
+    }
+    dbprint(ppl-2,"//Red-2-"+string(i)+"-2- Polynomial after reduction",F[i]);
+  }
+  return(F);
+}
+
+static proc reduceByMonomials(ideal algebra)
+/*This procedures uses the sagbiReduce procedure to reduce all polynomials in algebra,
+ * which are not monomials, by the subset of all monomials.
+ */
+{
+  ideal monomials;
+  int i;
+  for (i=1; i<=ncols(algebra);i++)
+  {
+    if(size(algebra[i])==1)
+    {
+      monomials[i]=algebra[i];
+      algebra[i]=0;
+    }
+    else
+    {
+      monomials[i]=0;
+    }
+  }
+  //Monomials now contains the subset of all monomials in algebra,
+  //algebra contains the non-monomials.
+  if(size(monomials)>0)
+  {
+    algebra=sagbiReduce(algebra,monomials,1);
+    for (i=1; i<=ncols(algebra);i++)
+    {
+      if(size(monomials[i])==1)
+      {
+        //Put back monomials into algebra.
+        algebra[i]=monomials[i];
+      }
+    }
+  }
+  return(algebra);
+}
+
+
+static proc sagbiConstruction(ideal algebra, int iterations, int tailreduction, int method,int parRed)
+/* This procedure is the SAGBI construction algorithm and does the actual computation
+ * both for the procedure sagbi and sagbiPart.
+ * - If the sagbi procedure calls this procedure, iterations==-1
+ *   and this procedure only stops
+ *   if all S-Polynomials reduce to zero
+ *   (criterion for termination of SAGBI construction algorithm).
+ * - If the sagbiPart procedure calls this procedure, iterations>=0
+ *   and iterations specifies the
+ *   number of iterations. A degree boundary is not used here.
+ * When this method is called via the procedures sagbi and sagbiPart the integer parRed
+ * will always be zero. Only the procedure algebraicDependence calls this procedure with
+ * parRed<>0. The only difference when parRed<>0 is that the reduction algorithms returns
+ * the non-zero constants it attains (instead of just returning zero as the correct
+ * remainder), as they will be expressions in parameters for an algebraic dependence.
+ * These constants are saved in the ideal reducedParameters.
+ */
+{
+  int ppl = printlevel-voice+3; //variable for additional printlevel-dependend information
+  dbprint(ppl,"// -0- initialisation and precomputation");
+  def br=basering;
+  int i=1;
+
+  ideal reducedParameters;
+  int numReducedParameters=1; //number of elements plus one in reducedParameters
+  int j;
+  if (parRed==0) //if parRed<>0 the algebra does not contain monomials and normalisation should be avoided
+  {
+    algebra=reduceByMonomials(algebra);
+    algebra=simplify(simplify(algebra,3),4);
+  }
+  // canonicalizing the gen's:
+  algebra = canonicalform(algebra);
+  ideal P=1;
+  //note: P is initialized this way, so that the while loop is entered.
+  //P gets overriden there, anyhow.
+  ideal varsBasering=maxideal(1);
+  map phi;
+  ideal spolynomialsNew;
+  def r=br;
+  while (size(P)>0)
+  {
+    dbprint(ppl,"// -"+string(i)+"- interation of SAGBI construction algorithm");
+    dbprint(ppl-1,"// -"+string(i)+"-1- Computing algebraic relations");
+    def rNew=spolynomialsGB(algebra,r,method); /* canonicalizing inside! */
+    kill r;
+    def r=rNew;
+    kill rNew;
+    phi=r,varsBasering,algebra;
+    dbprint(ppl-1,"// -"+string(i)+"-2- Substituting into algebraic relations");
+    spolynomialsNew=simplify(phi(algebraicRelationsNew),6);
+    //By construction spolynomialsNew only contains the spolynomials,
+    //that have not already
+    //been calculated in the steps before.
+    dbprint(ppl-1,"// -"+string(i)+"-3- SAGBI reduction");
+    dbprint(ppl-2,"// -"+string(i)+"-3-1- new S-polynomials before reduction",spolynomialsNew);
+    P=reductionGB(spolynomialsNew,algebra,r,tailreduction,method,parRed);
+    if (parRed)
+    {
+      for(j=1; j<=ncols(P); j++)
+      {
+        if (leadmonom(P[j])==1)
+        {
+          reducedParameters[numReducedParameters]=P[j];
+          P[j]=0;
+          numReducedParameters++;
+        }
+      }
+    }
+    if (parRed==0)
+    {
+      P=reduceByMonomials(P);
+      //Reducing with monomials is cheap and can only result in less terms
+      P=simplify(simplify(P,3),4);
+      //Avoid that zeros are added to the bases or one element in P more than once
+    }
+    else
+    {
+      P=simplify(P,6);
+    }
+    /* canonicalize ! */
+    P = canonicalform(P);
+    dbprint(ppl-2,"// -"+string(i)+"-3-1- new S-polynomials after reduction",P);
+    algebra=algebra,P;
+    //Note that elements and order of elements must in algebra must not be changed,
+    //otherwise the already calculated
+    //ideal in r will give wrong results. Thus it is important to use a komma here.
+    i=i+1;
+    if (iterations!=-1 && i>iterations) //When iterations==-1 the number of iterations is unlimited
+    {
+      break;
+    }
+  }
+  if (iterations!=-1)
+  { //case that sagbiPart called this procedure
+    if (size(P)==0)
+    {
+      dbprint(4-voice,
+              "//SAGBI construction algorithm terminated after "+string(i-1)
+              +" iterations, as all SAGBI S-polynomials reduced to 0.
+//Returned generators therefore are a SAGBI basis.");
+    }
+    else
+    {
+      dbprint(4-voice,
+              "//SAGBI construction algorithm stopped as it reached the limit of "
+              +string(iterations)+" iterations.
+//In general the returned generators are no SAGBI basis for the given algebra.");
+    }
+  }
+  kill r;
+  if (parRed)
+  {
+    algebra=algebra,reducedParameters;
+  }
+  algebra = simplify(algebra,6);
+  algebra = canonicalform(algebra);
+  return(algebra);
+}
+
+
+proc sagbiSPoly(ideal algebra,list #)
+"USAGE:   sagbiSPoly(A[, returnRing, meth]);  A is an ideal, returnRing and meth are integers.
+RETURN:   ideal or ring
+ASSUME: basering is not a qring
+PURPOSE: Returns SAGBI S-polynomials of the leading terms of a given ideal A if returnRing=0.
+@*       Otherwise returns a new ring containing the ideals algebraicRelations
+@*       and spolynomials, where these objects are explained by their name.
+@*       See the example on how to access these objects.
+ at format     The other optional argument meth determines which method is
+            used for computing the algebraic relations.
+            - If meth=0 (default), the procedure std is used.
+            - If meth=1, the procedure slimgb is used.
+            - If meth=2, the prodecure uses toric_ideal.
+ at end format
+EXAMPLE:  example sagbiSPoly; shows an example"
+{
+  assumeQring();
+  int returnRing;
+  int method=0;
+  def br=basering;
+  ideal spolynomials;
+  if (size(#)>=1)
+  {
+    if (typeof(#[1])=="int")
+    {
+      returnRing=#[1];
+    }
+    else
+    {
+      ERROR("Type of first optional argument needs to be int.");
+    }
+  }
+  if (size(#)==2)
+  {
+    if (typeof(#[2])=="int")
+    {
+      if (#[2]<0 || #[2]>2)
+      {
+        ERROR("Type of second optional argument needs to be 0,1 or 2.");
+      }
+      else
+      {
+        method=#[2];
+      }
+    }
+    else
+    {
+      ERROR("Type of second optional argument needs to be int.");
+    }
+  }
+  if (method>=0 and method<=1)
+  {
+    ideal varsBasering=maxideal(1);
+    def rNew=spolynomialsGB(algebra,br,method);
+    map phi=rNew,varsBasering,algebra;
+    spolynomials=simplify(phi(algebraicRelationsNew),7);
+  }
+  if(method==2)
+  {
+    def r2=spolynomialsToric(algebra);
+    map phi=r2,algebra;
+    spolynomials=simplify(phi(algebraicRelations),7);
+    def rNew=extendRing(br,lead(algebra),0);
+    setring rNew;
+    ideal algebraicRelations=imap(r2,algebraicRelations);
+    export algebraicRelations;
+    setring br;
+  }
+
+  if (returnRing==0)
+  {
+    return(spolynomials);
+  }
+  else
+  {
+    setring rNew;
+    ideal spolynomials=fetch(br,spolynomials);
+    export spolynomials;
+    setring br;
+    return(rNew);
+  }
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring r= 0,(x,y),dp;
+  ideal A=x*y+x,x*y^2,y^2+y,x^2+x;
+  //------------------ Compute the SAGBI S-polynomials only
+  sagbiSPoly(A);
+  //------------------ Extended ring is to be returned, which contains
+  // the ideal of algebraic relations and the ideal of the S-polynomials
+  def rNew=sagbiSPoly(A,1);  setring rNew;
+  spolynomials;
+  algebraicRelations;
+  //----------------- Now we verify that the substitution of A[i] into @y(i)
+  // results in the spolynomials listed above
+  ideal A=fetch(r,A);
+  map phi=rNew,x,y,A;
+  ideal spolynomials2=simplify(phi(algebraicRelations),1);
+  spolynomials2;
+}
+
+
+proc sagbiReduce(def idealORpoly, ideal algebra, list #)
+"USAGE: sagbiReduce(I, A[, tr, mt]); I, A ideals, tr, mt optional integers
+RETURN: ideal of remainders of I after SAGBI reduction by A
+ASSUME: basering is not a qring
+PURPOSE:
+ at format
+    The optional argument tr=tailred determines whether tail reduction will be performed.
+     - If (tailred=0), no tail reduction is done.
+     - If (tailred<>0), tail reduction is done.
+     The other optional argument meth determines which method is
+         used for Groebner basis computations.
+         - If mt=0 (default), the procedure std is used.
+         - If mt=1, the procedure slimgb is used.
+ at end format
+EXAMPLE:  example sagbiReduce; shows an example"
+{
+  assumeQring();
+  int tailreduction=0; //Default
+  int method=0; //Default
+  ideal I;
+  if(typeof(idealORpoly)=="ideal")
+  {
+    I=idealORpoly;
+  }
+  else
+  {
+    if(typeof(idealORpoly)=="poly")
+    {
+      I[1]=idealORpoly;
+    }
+    else
+    {
+      ERROR("Type of first argument needs to be an ideal or polynomial.");
+    }
+  }
+  if (size(#)>=1)
+  {
+    if (typeof(#[1])=="int")
+    {
+      tailreduction=#[1];
+    }
+    else
+    {
+      ERROR("Type of optional argument needs to be int.");
+    }
+  }
+  if (size(#)>=2 )
+  {
+    if (typeof(#[2])=="int")
+    {
+      if (#[2]<0 || #[2]>1)
+      {
+        ERROR("Type of second optional argument needs to be 0 or 1.");
+      }
+      else
+      {
+        method=#[2];
+      }
+    }
+    else
+    {
+      ERROR("Type of optional arguments needs to be int.");
+    }
+  }
+
+  def r=basering;
+  I=simplify(reductionGB(I,algebra,r,tailreduction,method,0),1);
+
+  if(typeof(idealORpoly)=="ideal")
+  {
+    return(I);
+  }
+  else
+  {
+    if(typeof(idealORpoly)=="poly")
+    {
+      return(I[1]);
+    }
+  }
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring r=0,(x,y,z),dp;
+  ideal A=x2,2*x2y+y,x3y2;
+  poly p1=x^5+x2y+y;
+  poly p2=x^16+x^12*y^5+6*x^8*y^4+x^6+y^4+3;
+  ideal P=p1,p2;
+  //---------------------------------------------
+  //SAGBI reduction of polynomial p1 by algebra A.
+  //Default call, that is, no tail-reduction is done.
+  sagbiReduce(p1,A);
+  //---------------------------------------------
+  //SAGBI reduction of set of polynomials P by algebra A,
+  //now tail-reduction is done.
+  sagbiReduce(P,A,1);
+}
+
+proc sagbi(ideal algebra, list #)
+"USAGE:   sagbi(A[, tr, mt]); A ideal, tr, mt optional integers
+RETURN: ideal, a SAGBI basis for A
+ASSUME: basering is not a qring
+PURPOSE: Computes a SAGBI basis for the subalgebra given by the generators in A.
+ at format
+    The optional argument tr=tailred determines whether tail reduction will be performed.
+     - If (tailred=0), no tail reduction is performed,
+     - If (tailred<>0), tail reduction is performed.
+     The other optional argument meth determines which method is
+         used for Groebner basis computations.
+         - If mt=0 (default), the procedure std is used.
+         - If mt=1, the procedure slimgb is used.
+ at end format
+EXAMPLE:  example sagbi; shows an example"
+{
+  assumeQring();
+  int tailreduction=0; //default value
+  int method=0; //default value
+  if (size(#)>=1)
+  {
+    if (typeof(#[1])=="int")
+    {
+      tailreduction=#[1];
+    }
+    else
+    {
+      ERROR("Type of optional argument needs to be int.");
+    }
+  }
+  if (size(#)>=2 )
+  {
+    if (typeof(#[2])=="int")
+    {
+      if (#[2]<0 || #[2]>1)
+      {
+        ERROR("Type of second optional argument needs to be 0 or 1.");
+      }
+      else
+      {
+        method=#[2];
+      }
+    }
+    else
+    {
+      ERROR("Type of optional arguments needs to be int.");
+    }
+  }
+  ideal a;
+  a=sagbiConstruction(algebra,-1,tailreduction,method,0);
+  a=simplify(a,7);
+  //  a=interreduced(a);
+  return(a);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring r= 0,(x,y,z),dp;
+  ideal A=x2,y2,xy+y;
+  //Default call, no tail-reduction is done.
+  sagbi(A);
+  //---------------------------------------------
+  //Call with tail-reduction and method specified.
+  sagbi(A,1,0);
+}
+
+proc sagbiPart(ideal algebra, int iterations, list #)
+"USAGE: sagbiPart(A, k,[tr, mt]); A is an ideal, k, tr and mt are integers
+RETURN: ideal
+ASSUME: basering is not a qring
+PURPOSE: Performs k iterations of the SAGBI construction algorithm for the subalgebra given by the generators given by A.
+ at format
+     The optional argument tr=tailred determines if tail reduction will be performed.
+     - If (tailred=0), no tail reduction is performed,
+     - If (tailred<>0), tail reduction is performed.
+     The other optional argument meth determines which method is
+         used for Groebner basis computations.
+         - If mt=0 (default), the procedure std is used.
+         - If mt=1, the procedure slimgb is used.
+ at end format
+EXAMPLE:  example sagbiPart; shows an example"
+{
+  assumeQring();
+  int tailreduction=0; //default value
+  int method=0; //default value
+  if (size(#)>=1)
+  {
+    if (typeof(#[1])=="int")
+    {
+      tailreduction=#[1];
+    }
+    else
+    {
+      ERROR("Type of optional argument needs to be int.");
+    }
+  }
+  if (size(#)>=2 )
+  {
+    if (typeof(#[2])=="int")
+    {
+      if (#[2]<0 || #[2]>3)
+      {
+        ERROR("Type of second optional argument needs to be 0 or 1.");
+      }
+      else
+      {
+        method=#[2];
+      }
+    }
+    else
+    {
+      ERROR("Type of optional arguments needs to be int.");
+    }
+  }
+  if (iterations<0)
+  {
+    ERROR("Number of iterations needs to be non-negative.");
+  }
+  ideal a;
+  a=sagbiConstruction(algebra,iterations,tailreduction,method,0);
+  a=simplify(a,6);
+  //  a=interreduced(a);
+  return(a);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring r= 0,(x,y,z),dp;
+  //The following algebra does not have a finite SAGBI basis.
+  ideal A=x,xy-y2,xy2;
+  //---------------------------------------------------
+  //Call with two iterations, no tail-reduction is done.
+  sagbiPart(A,2);
+  //---------------------------------------------------
+  //Call with three iterations, tail-reduction and method 0.
+  sagbiPart(A,3,1,0);
+}
+
+
+proc algebraicDependence(ideal I,int iterations)
+"USAGE: algebraicDependence(I,it); I an an ideal, it is an integer
+RETURN: ring
+ASSUME: basering is not a qring
+PURPOSE: Returns a ring containing the ideal @code{algDep}, which contains possibly
+@*                 some algebraic dependencies of the elements of I obtained through @code{it}
+@*                 iterations of the SAGBI construction algorithms. See the example on how
+@*                 to access these objects.
+EXAMPLE: example algebraicDependence; shows an example"
+{
+        assumeQring();
+        int ppl = printlevel-voice+3; //variable for additional printlevel-dependend information
+  dbprint(ppl,"//AlgDep-1- initialisation and precomputation");
+  def br=basering;
+  int i;
+  I=simplify(I,2); //avoid that I contains zeros
+
+        //Create two polynomial rings, which both are extensions of the current basering.
+  //The first ring will contain the additional paramteres @c(1),..., at c(m), the second one
+  //will contain the additional variables @c(1),..., at c(m), where m=ncols(I).
+  string parameterName=uniqueVariableName("@c");
+  list l = ringlist(basering);
+  list parList;
+  for (i=1; i<=ncols(I);i++)
+  {
+    parList[i]=string(parameterName,"(",i,")");
+  }
+  l[1]=list(l[1],parList,list(list("dp",1:ncols(I)))); //add @c(i) to the ring as paramteres
+  ideal temp=0;
+  l[1][4]=temp;
+  // addition VL: noncomm case
+  int isNCcase = 0; // default for comm
+  //         if (size(l)>4)
+  //         {
+  //           // that is we're in the noncomm algebra
+  //           isNCcase = 1; // noncomm
+  //           matrix @C@ = l[5];
+  //           matrix @D@ = l[6];
+  //           l = l[1],l[2],l[3],l[4];
+  //         }
+  def parameterRing=ring(l);
+
+  string extendVarName=uniqueVariableName("@c");
+  list l2 = ringlist(basering);
+  for (i=1; i<=ncols(I);i++)
+  {
+    l2[2][i+nvars(br)]=string(extendVarName,"(",i,")"); //add @c(i) to the rings as variables
+  }
+  l2[3][size(l2[3])+1]=l2[3][size(l2[3])];
+  l2[3][size(l2[3])-1]=list("dp",intvec(1:ncols(I)));
+  //         if (isNCcase)
+  //         {
+  //           // that is we're in the noncomm algebra
+  //           matrix @C at 2 = l2[5];
+  //           matrix @D at 2 = l2[6];
+  //           l2 = l2[1],l2[2],l2[3],l2[4];
+  //         }
+
+  def extendVarRing=ring(l2);
+  setring extendVarRing;
+  // VL : this requires extended matrices
+  // let's forget it for the moment
+  // since this holds only for showing the answer
+  //         if (isNCcase)
+  //         {
+  //           matrix C2=imap(br, at C@2);
+  //           matrix D2=imap(br, at D@2);
+  //           def er2 = nc_algebra(C2,D2);
+  //           setring er2;
+  //           def extendVarRing=er2;
+  //         }
+
+  setring parameterRing;
+
+  //         if (isNCcase)
+  //         {
+  //           matrix C=imap(br, at C@);
+  //           matrix D=imap(br, at D@);
+  //           def pr = nc_algebra(C,D);
+  //           setring pr;
+  //           def parameterRing=pr;
+  //         }
+
+        //Compute a partial SAGBI basis of the algebra generated by I[1]- at c(1),...,I[m]- at c(m),
+  //where the @c(n) are parameters
+  ideal I=fetch(br,I);
+  ideal algebra;
+  for (i=1; i<=ncols(I);i++)
+  {
+    algebra[i]=I[i]-par(i);
+  }
+  dbprint(ppl,"//AlgDep-2- call of SAGBI construction algorithm");
+  algebra=sagbiConstruction(algebra, iterations,0,0,1);
+  dbprint(ppl,"//AlgDep-3- postprocessing of results");
+  int j=1;
+  //If K[x_1,...,x_n] was the basering, then algebra is in K(@c(1),..., at c(m))[x_1,...x_n]. We intersect
+  //elements in algebra with K(@c(1),.., at c(n)) to get algDep. Note that @c(i) can only appear in the numerator,
+  //as the SAGBI construction algorithms just multiplies and substracts polynomials. So actually we have
+  //algDep=algebra intersect K[@c(1),..., at c(m)]
+  ideal algDep;
+  for (i=1; i<= ncols(algebra); i++)
+  {
+    if (leadmonom(algebra[i])==1) //leadmonom(algebra[i])==1 iff algebra[i] in K[@c(1),..., at c(m)]
+    {
+      algDep[j]=algebra[i];
+      j++;
+    }
+  }
+  //Transfer algebraic dependencies to ring where @c(i) are not parameters, but now variables.
+  setring extendVarRing;
+  ideal algDep=imap(parameterRing,algDep);
+  ideal algebra=imap(parameterRing,algebra);
+  //Now get rid of constants in K that may have been added to algDep.
+  for (i=1; i<=ncols(algDep); i++)
+  {
+                if(leadmonom(algDep[i])==1)
+                {
+                                algDep[i]=0;
+                }
+        }
+        algDep=simplify(algDep,2);
+  export algDep,algebra;
+  setring br;
+  return(extendVarRing);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring r= 0,(x,y),dp;
+  //The following algebra does not have a finite SAGBI basis.
+  ideal I=x^2, xy-y2, xy2;
+  //---------------------------------------------------
+  //Call with two iterations
+  def DI = algebraicDependence(I,2);
+  setring DI; algDep;
+  // we see that no dependency has been seen so far
+  //---------------------------------------------------
+  //Call with two iterations
+  setring r; kill DI;
+  def DI = algebraicDependence(I,3);
+  setring DI; algDep;
+  map F = DI,x,y,x^2, xy-y2, xy2;
+  F(algDep); // we see that it is a dependence indeed
+}
+
+static proc interreduced(ideal I)
+{
+  /* performs subalgebra interreduction of a set of subalgebra generators */
+  int ppl = printlevel-voice+3; //variable for additional printlevel-dependend information
+  dbprint(ppl,"//Interred-1- starting interreduction");
+  ideal J,B;
+  int i,j,k;
+  poly f;
+  for(k=1;k<=ncols(I);k++)
+  {
+    dbprint(ppl-1,"//Interred-1-"+string(k)+"- reducing next poly");
+    f=I[k];
+    I[k]=0;
+    f=sagbiReduce(f,I,1);
+    I[k]=f;
+  }
+  I=simplify(I,2);
+  dbprint(ppl,"//Interred-2- interreduction completed");
+  return(I);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc sagbiReduction(poly p,ideal dom,list #)
+"USAGE: sagbiReduction(p,dom[,n]); p poly , dom  ideal
+RETURN: polynomial, after one step of subalgebra reduction
+PURPOSE:
+ at format
+    Three algorithm variants are used to perform subalgebra reduction.
+    The positive interger n determines which variant should be used.
+    n may take the values 0 (default), 1 or 2.
+ at end format
+NOTE: works over both polynomial rings and their quotients
+EXAMPLE: example sagbiReduction; shows an example"
+{
+  def bsr=basering;
+  ideal B=ideal(bsr);//When the basering is quotient ring  this type casting
+                     // gives the quotient ideal.
+  int b=size(B);
+  int n=nvars(bsr);
+
+  //In quotient rings, SINGULAR, usually does not reduce polynomials w.r.t the
+  //quotient ideal,therefore we should first  reduce,
+  //when it is necessary for computations,
+  // to have a uniquely determined representant for each equivalent
+  //class,which is the case of this algorithm.
+
+  if(b !=0) //means that the basering is a quotient ring
+  {
+    p=reduce(p,std(0));
+    dom=reduce(dom,std(0));
+  }
+
+  int i,choose;
+  int z=ncols(dom);
+
+  if((size(#)>0) && (typeof(#[1])=="int"))
+  {
+    choose = #[1];
+  }
+  if (size(#)>1)
+  {
+    choose =#[2];
+  }
+
+  //=======================first algorithm(default)=========================
+  if ( choose == 0 )
+  {
+    list L = algebra_containment(lead(p),lead(dom),1);
+    if( L[1]==1 )
+    {
+      // the ring L[2] = char(bsr),(x(1..nvars(bsr)),y(1..z)),(dp(n),dp(m)),
+      // contains poly check s.t. LT(p) is of the form check(LT(f1),...,LT(fr))
+      def s1 = L[2];
+      map psi = s1,maxideal(1),dom;
+      poly re = p - psi(check);
+      // divide by the maximal power of #[1]
+      if ( (size(#)>0) && (typeof(#[1])=="poly") )
+      {
+        while ((re!=0) && (re!=#[1]) &&(subst(re,#[1],0)==0))
+        {
+          re=re/#[1];
+        }
+      }
+      return(re);
+    }
+    return(p);
+  }
+  //======================2end variant of algorithm=========================
+  //It uses two different commands for elimaination.
+  //if(choose==1):"elimainate"command.
+  //if (choose==2):"nselect" command.
+  else
+  {
+    poly v=product(maxideal(1));
+
+    //------------- change the basering bsr to bsr[@(0),...,@(z)] ----------
+    execute("ring s=("+charstr(basering)+"),("+varstr(basering)+",@(0..z)),dp;");
+    // Ev hier die Reihenfolge der Vars aendern. Dazu muss unten aber entsprechend
+    // geaendert werden:
+    //  execute("ring s="+charstr(basering)+",(@(0..z),"+varstr(basering)+"),dp;");
+
+    //constructs the leading ideal of dom=(p-@(0),dom[1]-@(1),...,dom[z]-@(z))
+    ideal dom=imap(bsr,dom);
+    for (i=1;i<=z;i++)
+    {
+      dom[i]=lead(dom[i])-var(nvars(bsr)+i+1);
+    }
+    dom=lead(imap(bsr,p))-@(0),dom;
+
+    //---------- eliminate the variables of the basering bsr --------------
+    //i.e. computes dom intersected with K[@(0),...,@(z)].
+
+    if(choose==1)
+    {
+      ideal kern=eliminate(dom,imap(bsr,v));//eliminate does not need a
+                                            //standard basis as input.
+    }
+    if(choose==2)
+    {
+      ideal kern= nselect(groebner(dom),1..n);//"nselect" is combinatorial command
+                                         //which uses the internal command
+                                         // "simplify"
+    }
+
+    //---------  test wether @(0)-h(@(1),...,@(z)) is in ker ---------------
+    // for some poly h and divide by maximal power of q=#[1]
+    poly h;
+    z=size(kern);
+    for (i=1;i<=z;i++)
+    {
+      h=kern[i]/@(0);
+      if (deg(h)==0)
+      {
+        h=(1/h)*kern[i];
+        // define the map psi : s ---> bsr defined by @(i) ---> p,dom[i]
+        setring bsr;
+        map psi=s,maxideal(1),p,dom;
+        poly re=psi(h);
+        // divide by the maximal power of #[1]
+        if ((size(#)>0) && (typeof(#[1])== "poly") )
+        {
+          while ((re!=0) && (re!=#[1]) &&(subst(re,#[1],0)==0))
+          {
+            re=re/#[1];
+          }
+        }
+        return(re);
+      }
+    }
+    setring bsr;
+    return(p);
+  }
+}
+example
+{"EXAMPLE:"; echo = 2;
+  ring r= 0,(x,y),dp;
+  ideal dom =x2,y2,xy-y;
+  poly p=x4+x3y+xy2-y2;
+  sagbiReduction(p,dom);
+  sagbiReduction(p,dom,2);
+  // now let us see the action over quotient ring
+  ideal I = xy;
+  qring Q = std(I);
+  ideal dom = imap(r,dom); poly p = imap(r,p);
+  sagbiReduction(p,dom,1);
+}
+
+proc sagbiNF(id,ideal dom,int k,list#)
+"USAGE: sagbiNF(id,dom,k[,n]); id either poly or ideal,dom ideal, k and n positive intergers.
+RETURN: same as type of id; ideal or polynomial.
+PURPOSE:
+ at format
+    The integer k determines what kind of s-reduction is performed:
+    - if (k=0) no tail s-reduction is performed.
+    - if (k=1) tail s-reduction is performed.
+    Three Algorithm variants are used to perform subalgebra reduction.
+    The positive integer n determines which variant should be used.
+    n may take the values (0 or default),1 or 2.
+ at end format
+NOTE: sagbiNF works over both rings and quotient rings
+EXAMPLE: example sagbiNF; show example "
+{
+  ideal rs;
+  if (ideal(basering) == 0)
+  {
+    rs = sagbiReduce(id,dom,k) ;
+  }
+  else
+  {
+    rs = sagbiReduction(id,dom,k) ;
+  }
+  return(rs);
+}
+example
+{"EXAMPLE:"; echo = 2;
+ ring r=0,(x,y),dp;
+ poly p=x4+x2y+y;
+ ideal dom =x2,x2y+y,x3y2;
+ sagbiNF(p,dom,1);
+ ideal I= x2-xy;
+ qring Q=std(I); // we go to the quotient ring
+ poly p=imap(r,p);
+ NF(p,std(0)); // the representative of p has changed
+ ideal dom = imap(r,dom);
+ print(matrix(NF(dom,std(0)))); // dom has changed as well
+ sagbiNF(p,dom,0); // no tail reduction
+ sagbiNF(p,dom,1);// tail subalgebra reduction is performed
+}
+
+static proc canonicalform(ideal I)
+{
+  /* placeholder for the canonical form of a set of gen's */
+  /* for the time being we agree on content(p)=1; that is coeffs with no fractions */
+  int i; ideal J=I;
+  for(i=ncols(I); i>=1; i--)
+  {
+    J[i] = canonicalform_poly(I[i]);
+  }
+  return(J);
+}
+
+static proc canonicalform_poly(poly p)
+{
+  /* placeholder for the canonical form of a poly */
+  /* for the time being we agree on content(p)=1; that is coeffs with no fractions */
+  number n = content(p);
+  return( p/content(p) );
+}
+
+/*
+  ring r= 0,(x,y),dp;
+  //The following algebra does not have a finite SAGBI basis.
+  ideal J=x^2, xy-y2, xy2, x^2*(x*y-y^2)^2 - (x*y^2)^2*x^4 + 11;
+  //---------------------------------------------------
+  //Call with two iterations
+  def DI = algebraicDependence(J,2);
+  setring DI; algDep;
+*/
diff --git a/Singular/LIB/schreyer.lib b/Singular/LIB/schreyer.lib
new file mode 100644
index 0000000..6ea46ff
--- /dev/null
+++ b/Singular/LIB/schreyer.lib
@@ -0,0 +1,3597 @@
+///////////////////////////////////////////////////////////////////////////
+version="version schreyer.lib 4.0.0.0 Jun_2013 "; // $Id: c331c87d4e741d2aac1384319042dd7087361ac1 $
+category="General purpose";
+info="
+LIBRARY: schreyer.lib     Schreyer resolution computations and helpers for @code{derham.lib}
+AUTHOR:  Oleksandr Motsak <U at D>, where U={motsak}, D={mathematik.uni-kl.de}
+KEYWORDS: Schreyer ordering; Schreyer resolution; syzygy
+OVERVIEW:
+@* The library contains several procedures for computing a/part of Schreyer resoltion (cf. [SFO]),
+   and some helpers for @code{derham.lib} (which requires resolutions over the homogenized Weyl algebra) for that purpose.
+@* The input for any resolution computation is a set of vectors @code{M} in form of a module over some basering @code{R}.
+   The helpers works both in the commutative and non-commutative setting (cf. [MO]), that is the ring @code{R} may be non-commutative,
+   in which case the ring ordering over it must be global. They produce/work with partial Schreyer resolutions of @code{(R^rank(M))/M}
+   in form of a specially constructed ring (endowed with a special ring ordering that will be extended in the
+   course of a resolution computation) containing a list of modules @code{RES} and a module @code{MRES}:
+@* @code{RES}: the list of modules contains the images of maps (also called syzygy modules) substituting the
+     computed beginning of a Schreyer resolution, that is, each syzygy module is given by a Groebner basis
+     with respect to the corresponding Schreyer ordering.
+@* @code{RES}: the list of modules which starts with a zero map given by @code{rank(M)} zero generators indicating that the image of
+     the first differential map is zero. The second map @code{RES[2]} is given by @code{M}, which indicates that
+     the resolution of @code{(R^rank(M))/M} is being computed.
+@* @code{MRES}: the module is a direct sum of modules from @code{RES} and thus comprises all computed differentials.
+@* Syzygies are shifted so that @code{gen(i)} is mapped to @code{MRES[i]} under the differential map.
+NOTE:
+@* Here, we call a free resolution a Schreyer resolution if each syzygy module is given by a Groebner basis
+     with respect to the corresponding Schreyer ordering.
+@* A Schreyer resolution can be much bigger than a minimal resolution of the same module, but may be easier to construct.
+@* The Schreyer ordering succesively extends the starting module ordering on @code{M} (defined in Singular by the basering @code{R})
+     and is extended to higher syzygies using the following definition:
+@*        a < b if and only if (d(a) < d(b)) OR ( (d(a) = d(b) AND (comp(a) < comp(b)) ),
+@* where @code{d(a)} is the image of an under the differential (given by @code{MRES}),
+     and @code{comp(a)} is the module component, for any module terms @code{a} and @code{b} from the same higher syzygy module.
+NOTE:
+@* most comutations require the dynamic or built-in module @code{syzextra}, which will be auto-leaded on demand.
+PROCEDURES:
+  Sres(M,len)     helper for computing Schreyer resolution of module M of maximal length len
+  Ssyz(M)         helper for computing Schreyer resolution of module M of length 1
+  Scontinue(len)  helper for extending currently active resolution by (at most) len syszygies
+  s_res(M, len)   compute Schreyer resolution of module M of maximal length len via LiftTree method from [BMSS]
+REFERENCES:
+@*
+[BMSS] Burcin, E., Motsak, O., Schreyer, F.-O., Steenpass, A.: NEW ALGORITHMS TO COMPUTE SYZYGIES, 2014.
+@*
+[SFO]  Schreyer, F.O.: Die Berechnung von Syzygien mit dem verallgemeinerten Weierstrassschen Divisionssatz,
+       Master's thesis, Univ. Hamburg, 1980.
+@*
+[MO]   Motsak, O.: Non-commutative Computer Algebra with applications: Graded commutative algebra and related
+       structures in Singular with applications, Ph.D. thesis, TU Kaiserslautern, 2010.
+";
+
+static proc prepareSyz( module I, list # )
+{
+  int i;
+  int k = 0;
+  int r = nrows(I);
+  int c = ncols(I);
+
+
+  if( size(#) > 0 )
+  {
+    if( typeof(#[1]) == "int" || typeof(#[1]) == "bigint" )
+    {
+      k = #[1];
+    }
+  }
+
+  if( k < r )
+  {
+    "// *** Wrong k: ", k, " < nrows: ", r, " => setting k = r = ", r;
+    k = r;
+  }
+
+//   "k: ", k;  "c: ", c;   "I: ", I;
+
+  for( i = c; i > 0; i-- )
+  {
+    I[i] = I[i] + gen(k + i);
+  }
+
+//   Syzextra::DetailedPrint(I);
+
+  return(I);
+}
+
+static proc separateSyzGB( module J, int c )
+{
+  module II, G; vector v; int i;
+
+  J = simplify(J, 2);
+
+  for( i = ncols(J); i > 0; i-- )
+  {
+    v = J[i];
+    if(   Syzextra::leadcomp(v) > c )
+    {
+      II[i] = v;
+    } else
+    {
+      G[i] = v; // leave only gen(i): i <= c
+    }
+  }
+
+  II = simplify(II, 2);
+  G = simplify(G, 2);
+
+  return (list(G, II));
+}
+
+static proc splitSyzGB( module J, int c )
+{
+  module JJ; vector v, vv; int i;
+
+  for( i = ncols(J); i > 0; i-- )
+  {
+    v = J[i];
+
+    vv = 0;
+
+    while(   Syzextra::leadcomp(v) <= c )
+    {
+      vv = vv + lead(v);
+      v  = v  - lead(v);
+    }
+
+    J[i] = vv;
+    JJ[i] = v;
+  }
+
+  J = simplify(J, 2);
+  JJ = simplify(JJ, 2);
+
+  return (list(J, JJ));
+}
+
+
+static proc Sinit(module M)
+{
+  def @save = basering;
+
+  int @DEBUG = 0; // !system("with", "ndebug");
+  if( @DEBUG )
+  {
+    "Sinit::Input";
+    type(M);
+//      Syzextra::DetailedPrint(M);
+    attrib(M);
+  }
+
+  int @RANK = nrows(M); int @SIZE = ncols(M);
+
+  int @IS_A_SB = attrib(M, "isSB"); // ??? only if all weights were zero?!
+
+  if( !@IS_A_SB )
+  {
+    M = std(M); // this should be faster than computing std in S (later on)
+  }
+
+  def S =   Syzextra::MakeInducedSchreyerOrdering(1); // 1 puts history terms to the back
+  // TODO: NOTE: +1 causes trouble to Singular interpreter!!!???
+  setring S; // a new ring with a Schreyer ordering
+
+  if( @DEBUG )
+  {
+    "Sinit::StartingISRing";
+    basering;
+//      Syzextra::DetailedPrint(basering);
+  }
+
+  // Setup the leading syzygy^{-1} module to zero:
+  module Z = 0; Z[@RANK] = 0; attrib(Z, "isHomog", intvec(0));
+
+  module MRES = Z;
+
+  list RES; RES[1] = Z;
+
+  module F = freemodule(@RANK);
+  intvec @V = deg(F[1.. at RANK]);
+
+  module M = imap(@save, M);
+
+  attrib(M, "isHomog", @V);
+  attrib(M, "isSB", 1);
+
+
+  if( @DEBUG )
+  {
+    "Sinit::SB_Input: ";
+    type(M);
+    attrib(M);
+    attrib(M, "isHomog");
+//      Syzextra::DetailedPrint(M);
+  }
+
+  if( @DEBUG )
+  {
+    // 0^th syz. property
+    if( size(module(transpose( transpose(M) * transpose(MRES) ))) > 0 )
+    {
+      transpose( transpose(M) * transpose(MRES) );
+      "ERROR: transpose( transpose(M) * transpose(MRES) ) != 0!!!";
+        Syzextra::m2_end(666);
+    }
+  }
+
+  RES[size(RES)+1] = M; // list of all syzygy modules
+  MRES = MRES, M;
+
+  attrib(MRES, "isHomog", @V);
+
+  attrib(S, "InducionLeads", lead(M));
+  attrib(S, "InducionStart", @RANK);
+
+  if( @DEBUG )
+  {
+    "Sinit::MRES";
+      Syzextra::DetailedPrint(MRES);
+    attrib(MRES, "isHomog");
+    attrib(S);
+  }
+
+  export RES;
+  export MRES;
+  return (S);
+}
+
+static proc Sstep()
+{
+  int @DEBUG = 0; // !system("with", "ndebug");
+
+  if( @DEBUG )
+  {
+    "Sstep::NextInducedRing";
+      Syzextra::DetailedPrint(basering);
+
+    attrib(basering, "InducionLeads");
+    attrib(basering, "InducionStart");
+
+      Syzextra::GetInducedData();
+  }
+
+  // syzygy step:
+
+/*
+  // is initial weights are all zeroes!
+  def L =  lead(M);
+  intvec @V = deg(M[1..ncols(M)]);  @W;  @V;  @W = @V;  attrib(L, "isHomog", @W);
+    Syzextra::SetInducedReferrence(L, @RANK, 0);
+*/
+
+//  def L =  lead(MRES);
+//  @W = @W, @V;
+//  attrib(L, "isHomog", @W);
+
+
+  // General setting:
+//    Syzextra::SetInducedReferrence(MRES, 0, 0); // limit: 0!
+  int @l = size(RES);
+
+  module M = RES[@l];
+
+  module L = attrib(basering, "InducionLeads");
+  int limit = attrib(basering, "InducionStart");
+
+//  L;  limit;
+
+  int @RANK = ncols(MRES) - ncols(M); // nrows(M); // what if M is zero?!
+
+/*
+  if( @RANK !=  nrows(M) )
+  {
+    type(MRES);
+    @RANK;
+    type(M);
+    pause();
+  }
+*/
+
+  intvec @W = attrib(M, "isHomog");
+  intvec @V = deg(M[1..ncols(M)]);
+  @V = @W, @V;
+
+  if( @DEBUG )
+  {
+    "Sstep::NextInput: ";
+    M;
+    deg(M[1..ncols(M)]); // no use of @W :(?
+    @RANK;
+      Syzextra::DetailedPrint(MRES);
+    attrib(MRES, "isHomog"); @W;
+    deg(MRES[1..ncols(MRES)]);
+  }
+
+
+
+    Syzextra::SetInducedReferrence(L, limit, 0);
+
+  def K = prepareSyz(M, @RANK);
+//  K;
+
+//   attrib(K, "isHomog", @V);     Syzextra::DetailedPrint(K, 1000);
+
+//  pause();
+
+  K =   Syzextra::idPrepare(K, @RANK); // std(K); // ?
+  K = simplify(K, 2);
+
+//  K;
+
+  module N = separateSyzGB(K, @RANK)[2]; // 1^st syz. module: vectors which start in lower part (comp >= @RANK)
+
+// "N_0: "; N;   Syzextra::DetailedPrint(N, 10);
+
+//  basering; print(@V); type(N);
+//  attrib(N, "isHomog", @V);  // TODO: fix "wrong weights"!!!? deg is wrong :(((
+  N = std(N);
+  attrib(N, "isHomog", @V);
+
+//  N;
+
+  if( @DEBUG )
+  {
+    if( size(N) > 0 )
+    {
+      // next syz. property
+      if( size(module(transpose( transpose(N) * transpose(MRES) ))) > 0 )
+      {
+        MRES;
+
+        "N: "; N;   Syzextra::DetailedPrint(N, 10);
+
+        "K:"; K;   Syzextra::DetailedPrint(K, 10);
+
+        "RANKS: ", @RANK;
+
+        "ERROR: transpose( transpose(N) * transpose(MRES) ) != 0!!!";
+        transpose( transpose(N) * transpose(MRES) );
+
+        "transpose(N) * transpose(MRES): ";
+        transpose(N) * transpose(MRES);
+          Syzextra::DetailedPrint(module(_), 2);
+          Syzextra::m2_end(666);
+      }
+    }
+  }
+
+  RES[@l + 1] = N; // list of all syzygy modules
+
+  MRES = MRES, N;
+  attrib(MRES, "isHomog", @V);
+
+
+  L = L, lead(N);
+  attrib(basering, "InducionLeads", L);
+
+  if( @DEBUG )
+  {
+    "Sstep::NextSyzOutput: ";
+      Syzextra::DetailedPrint(N);
+    attrib(N, "isHomog");
+  }
+
+}
+
+proc Scontinue(int l)
+"USAGE:  Scontinue(int len)
+RETURN:  nothing, instead it changes the currently active resolution
+PURPOSE: extends the currently active resolution by at most len syzygies
+ASSUME:  must be used within a ring returned by Sres or Ssyz
+EXAMPLE: example Scontinue; shows an example
+"
+{
+  def data =   Syzextra::GetInducedData();
+
+  if( (!defined(RES)) || (!defined(MRES)) || (typeof(data) != "list") || (size(data) != 2) )
+  {
+    ERROR("Sorry, but basering does not seem to be returned by Sres or Ssyz");
+  }
+  for (;  (l != 0) && (size(RES[size(RES)]) > 0); l-- )
+  {
+    Sstep();
+  }
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring r;
+  module M = maxideal(1); M;
+  def S = Ssyz(M); setring S; S;
+  "Only the first syzygy: ";
+  RES; MRES;
+  "More syzygies: ";
+  Scontinue(10);
+  RES; MRES;
+}
+
+proc Ssyz(module M)
+"USAGE:  Ssyz(module M)
+RETURN:  ring, containing a Schreyer resolution
+PURPOSE: computes a Schreyer resolution of M of length 1 (see the library overview)
+SEE ALSO: Sres
+EXAMPLE: example Ssyz; shows an example
+"
+{
+  def S = Sinit(M); setring S;
+
+  Sstep(); // NOTE: what if M is zero?
+
+  return (S);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring r;
+  module M = maxideal(1); M;
+  def S = Ssyz(M); setring S; S;
+  "Only the first syzygy: ";
+  RES;
+  MRES; // Note gen(i)
+  kill S;
+  setring r; kill M;
+
+  module M = 0;
+  def S = Ssyz(M); setring S; S;
+  "Only the first syzygy: ";
+  RES;
+  MRES;
+}
+
+proc Sres(module M, int l)
+"USAGE:  Sres(module M, int len)
+RETURN:  ring, containing a Schreyer resolution
+PURPOSE: computes a Schreyer resolution of M of length at most len (see the library overview)
+NOTE:    If given len is zero then nvars(basering) + 1 is used instead.
+SEE ALSO: Ssyz
+EXAMPLE: example Sres; shows an example
+"
+{
+  def S = Sinit(M); setring S;
+
+  if (l == 0)
+  {
+    l = nvars(basering) + 1; // not really an estimate...?!
+  }
+
+  Sstep(); l = l - 1;
+
+  Scontinue(l);
+
+  return (S);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring r;
+  module M = maxideal(1); M;
+  def S = Sres(M, 0); setring S; S;
+  RES;
+  MRES;
+  kill S;
+  setring r; kill M;
+
+  def A = nc_algebra(-1,0); setring A;
+  ideal Q = var(1)^2, var(2)^2, var(3)^2;
+  qring SCA = twostd(Q);
+  basering;
+
+  module M = maxideal(1);
+  def S = Sres(M, 2); setring S; S;
+  RES;
+  MRES;
+}
+
+
+
+// ================================================================== //
+
+
+LIB "general.lib"; // for sort
+
+static proc MySort(def M)
+" Sorts the given ideal or module wrt >_{(c, ds)}  (.<.<.<.<) "
+{
+  if( typeof( attrib(basering, "DEBUG") ) == "int" )
+  {
+    int @DEBUG = attrib(basering, "DEBUG");
+  } else
+  {
+    int @DEBUG = 0; // !system("with", "ndebug");
+  }
+
+  if( typeof( attrib(basering, "KERCHECK") ) == "int" )
+  {
+    int @KERCHECK = attrib(basering, "KERCHECK");
+  } else
+  {
+    int @KERCHECK = @DEBUG;
+  }
+
+
+  if( @DEBUG )
+  {
+    "MySort:: Input: "; M;
+  }
+
+  def @N = M;
+
+  if( size(M) > 0 )
+  {
+    Syzextra::Sort_c_ds(@N);
+
+    if( @KERCHECK )
+    {
+      def iv = sort(lead(M), "c,ds", 1)[2]; // ,1 => reversed! // TODO: not needed?
+      def @M = M;
+      @M = M[iv];
+
+      // 0^th syz. property
+      if( (size(@N) + size(@M)) > 0 )
+      {
+        if( size(module( matrix(module(matrix(@N))) - matrix(module(matrix(@M))) )) > 0 )
+        {
+          "ERROR: MySort: wrong sorting in 'MySort': @N != @M!!!";
+
+          "@M:"; @M;
+          "@N:"; @N;
+
+          "module( matrix(module(matrix(@N))) - matrix(module(matrix(@M))) ): ";
+          module( matrix(module(matrix(@N))) - matrix(module(matrix(@M))) );
+
+          "ERROR: MySort: wrong sorting in 'MySort': @N != @M!!!";
+            Syzextra::m2_end(666);
+        }
+      }
+    }
+  }
+
+  if( @DEBUG )
+  {
+    "MySort:: Ouput: "; @N;
+  }
+
+  return (@N);
+}
+
+
+static proc SSinit(def M)
+{
+//  rtimer, "***TIMESNAP0 for SSinit: on level: [",-1,"] :: t: ", timer, ", r: ", rtimer;
+  if( (typeof(M) != "module") && (typeof(M) != "ideal") )
+  {
+    ERROR("Sorry: need an ideal or a module for input");
+  }
+  def @save = basering;
+
+  int @DEBUG = 0; // !system("with", "ndebug");
+
+  if( typeof( attrib(SSinit, "DEBUG") ) == "int" )
+  {
+    @DEBUG = attrib(SSinit, "DEBUG");
+  }
+
+  int @SYZCHECK = 0; // @DEBUG;
+
+  if( typeof( attrib(SSinit, "SYZCHECK") ) == "int" )
+  {
+    @SYZCHECK = attrib(SSinit, "SYZCHECK");
+  }
+
+  int @KERCHECK = 0; // @DEBUG;
+
+  if( typeof( attrib(SSinit, "KERCHECK") ) == "int" )
+  {
+    @KERCHECK = attrib(SSinit, "KERCHECK");
+  }
+
+  int @IGNORETAILS = 0;
+
+  if( typeof( attrib(SSinit, "IGNORETAILS") ) == "int" )
+  {
+    @IGNORETAILS = attrib(SSinit, "IGNORETAILS");
+  }
+
+  int @TREEOUTPUT = 0;
+
+  if( typeof( attrib(SSinit, "TREEOUTPUT") ) == "int" )
+  {
+    @TREEOUTPUT = attrib(SSinit, "TREEOUTPUT");
+  }
+
+  int @RINGCHANGE = 0;
+
+  if( typeof( attrib(SSinit, "RINGCHANGE") ) == "int" )
+  {
+    @RINGCHANGE = attrib(SSinit, "RINGCHANGE");
+  }
+
+
+  if( @DEBUG )
+  {
+    "SSinit::Input";
+    type(M);
+    attrib(M);
+  }
+
+  def opts = option(get); 
+  option(redSB); option(redTail);
+    M = simplify(interred(groebner(M)), 1 + 2 + 4 + 32); // NOTE: we require interreduced GB for input
+  option(set, opts); kill opts;
+  
+//  int @IS_A_SB = attrib(M, "isSB");  if( !@IS_A_SB )  {  } else  {  }
+// attrib(M, "isSB", 1);
+
+  if( @IGNORETAILS )
+  {
+    M = lead(M);
+
+    if( @DEBUG )
+    {
+      "SSinit::Ignorring tails: M: ";
+      type(M);
+    }
+  }
+
+  def @N = MySort(M); // TODO: replace with inplace sorting!!!
+  def LEAD = lead(@N);
+
+  if( @KERCHECK )
+  {
+    def @LEAD = lead(M);
+
+    // sort wrt neg.deg.rev.lex!
+    intvec iv_ds = sort(@LEAD, "c,ds", 1)[2]; // ,1 => reversed!
+
+    M = M[iv_ds]; // sort M wrt ds on current leading terms
+    @LEAD = @LEAD[iv_ds];
+
+    if( size(module( matrix(@N) - matrix(M) )) > 0 )
+    {
+      "M:"; M;
+      "@N:"; @N;
+
+      "module( matrix(@N) - matrix(M) ): ";
+      module( matrix(@N) - matrix(M) );
+
+      "ERROR: wrong sorting (in SSnit): @N != M!!!";
+        Syzextra::m2_end(666);
+    }
+
+    if( size(module( matrix(@LEAD) - matrix(LEAD) )) > 0 )
+    {
+      "LEAD:"; LEAD;
+      "@LEAD:"; @LEAD;
+
+      "module( matrix(@LEAD) - matrix(LEAD) ): ";
+      module( matrix(@LEAD) - matrix(LEAD) );
+
+      "ERROR: wrong sorting (in SSnit): @LEAD != LEAD!!!";
+        Syzextra::m2_end(666);
+    }
+
+  }
+
+  M = @N;
+
+  def TAIL =   Syzextra::Tail(M);
+
+  int @RANK = nrows(M); int @SIZE = ncols(M);
+
+  intvec @DEGS = deg(M[1.. at SIZE]); // store actuall degrees of input elements
+
+  // TODO: what about real modules? weighted ones?
+
+  if( @RINGCHANGE )
+  {
+    list @l = ringlist(@save);
+    int @z = 0; ideal @m = maxideal(1); intvec @wdeg = deg(@m[1..ncols(@m)]);
+    // NOTE: @wdeg will be ignored anyway :(
+    @l[3] = list(list("C", @z), list("lp", @wdeg));
+    kill @z, @m, @wdeg; // since these vars are ring independent!
+    def S = ring(@l); // --  Syzextra::MakeInducedSchreyerOrdering(1);
+    kill @l;
+    setring S; // ring with an easy divisibility test ("C, lex") // or not!???
+    if( @DEBUG )
+    {
+      "SSinit::NewRing(C,lex)?";
+      basering;
+        Syzextra::DetailedPrint(basering);
+    }
+  } else
+  { def S = basering; }
+
+  // Setup the leading syzygy^{-1} module to zero:
+  module Z = 0; Z[@RANK] = 0; attrib(Z, "isHomog", intvec(0));
+
+  if( !@RINGCHANGE )
+  {
+    if( defined(RES) )  { if( @DEBUG ){ "WARN: killing existing object: RES!"; }; kill RES; }
+    if( defined(MRES) ) { if( @DEBUG ){ "WARN: killing existing object: MRES!"; }; kill MRES; }
+    if( defined(LRES) ) { if( @DEBUG ){ "WARN: killing existing object: LRES!"; }; kill LRES; }
+    if( defined(TRES) ) { if( @DEBUG ){ "WARN: killing existing object: TRES!"; }; kill TRES; }
+  }
+
+  module MRES = Z;
+
+  list RES;  RES[1] = Z;
+  list LRES; LRES[1] = Z;
+  list TRES; TRES[1] = Z;
+
+  if( !defined(M) )
+  {
+    def M = imap(@save, M);
+  }
+
+  module F = freemodule(@RANK); intvec @V = deg(F[1.. at RANK]); kill F;
+
+  attrib(M, "isHomog", @V);
+  attrib(M, "isSB", 1);
+  attrib(M, "degrees", @DEGS);
+
+  if( !defined(LEAD) )
+  {
+    def LEAD = imap(@save, LEAD);
+  }
+
+  attrib(LEAD, "isHomog", @V);
+  attrib(LEAD, "isSB", 1);
+
+  if( !defined(TAIL) )
+  {
+    def TAIL = imap(@save, TAIL);
+  }
+
+  if( @DEBUG )
+  {
+    "SSinit::(sorted) SB_Input: ";
+    type(M);
+    attrib(M);
+    attrib(M, "isHomog");
+  }
+
+  if( @SYZCHECK )
+  {
+    // 0^th syz. property
+    if( size(module(transpose( transpose(M) * transpose(MRES) ))) > 0 )
+    {
+      transpose( transpose(M) * transpose(MRES) );
+      "ERROR: transpose( transpose(M) * transpose(MRES) ) != 0!!!";
+        Syzextra::m2_end(666);
+    }
+  }
+
+  RES [size(RES)+1] = M; // list of all syzygy modules
+  LRES[size(LRES)+1] = LEAD; // list of all syzygy modules
+  TRES[size(TRES)+1] = TAIL; // list of all syzygy modules
+
+  MRES = MRES, M; //?
+
+  attrib(MRES, "isHomog", @V);
+
+//  attrib(S, "InducionStart", @RANK);
+
+
+  if( typeof( attrib(SSinit, "LEAD2SYZ") ) == "int" )
+  {
+    attrib(S, "LEAD2SYZ", attrib(SSinit, "LEAD2SYZ") );
+  } else
+  {
+    attrib(S, "LEAD2SYZ", 0);
+  }
+
+  if( typeof( attrib(SSinit, "TAILREDSYZ") ) == "int" )
+  {
+    attrib(S, "TAILREDSYZ", attrib(SSinit, "TAILREDSYZ") );
+  } else
+  {
+    attrib(S, "TAILREDSYZ", 1);
+  }
+
+  if( typeof( attrib(SSinit, "HYBRIDNF") ) == "int" )
+  {
+    attrib(S, "HYBRIDNF", attrib(SSinit, "HYBRIDNF") );
+  } else
+  {
+    attrib(S, "HYBRIDNF", 0);
+  }
+
+  if( typeof( attrib(SSinit, "NOCACHING") ) == "int" )
+  {
+    attrib(S, "NOCACHING", attrib(SSinit, "NOCACHING") );
+  } else
+  {
+    attrib(S, "NOCACHING", 0);
+  }
+  
+
+  // maybe resetting existing ring attributes!
+  attrib(S, "DEBUG", @DEBUG);
+  attrib(S, "SYZCHECK", @SYZCHECK);
+  attrib(S, "KERCHECK", @KERCHECK);
+  attrib(S, "IGNORETAILS", @IGNORETAILS);
+  attrib(S, "TREEOUTPUT", @TREEOUTPUT);
+  attrib(S, "SYZNUMBER", 0);
+
+  if( @DEBUG )
+  {
+    "SSinit::MRES";
+    MRES;
+//      Syzextra::DetailedPrint(MRES);
+    attrib(MRES, "isHomog");
+    attrib(S);
+  }
+
+  export RES;
+  export MRES;
+  export LRES;
+  export TRES;
+
+//  rtimer, "***TIMESNAP1 for SSinit: on level: [",attrib(basering,"SYZNUMBER"),"] :: t: ", timer, ", r: ", rtimer;
+
+  return (S);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring R = 0, (w, x, y, z), dp;
+
+  def M = maxideal(1);
+  def S = SSinit(M); setring S; S;
+
+  "Only the first initialization: ";
+  RES; LRES; TRES;
+  MRES;
+
+  kill S; setring R; kill M;
+
+  ideal M = w^2 - x*z,  w*x - y*z,  x^2 - w*y, x*y - z^2, y^2 - w*z;
+  def S = SSinit(M); setring S; S;
+
+  "Only the first initialization: ";
+  RES; LRES; TRES;
+  MRES;
+
+  kill S; setring R; kill M;
+}
+
+
+LIB "poly.lib"; // for lcm
+
+
+
+/// Compute L(Syz(L))
+static proc SSComputeLeadingSyzygyTerms(def L)
+{
+  if( typeof( attrib(basering, "DEBUG") ) == "int" )
+  {
+    int @DEBUG = attrib(basering, "DEBUG");
+  } else
+  {
+    int @DEBUG = 0; // !system("with", "ndebug");
+  }
+
+  if( typeof( attrib(basering, "SYZCHECK") ) == "int" )
+  {
+    int @SYZCHECK = attrib(basering, "SYZCHECK");
+  } else
+  {
+    int @SYZCHECK = @DEBUG;
+  }
+
+  if( typeof( attrib(basering, "KERCHECK") ) == "int" )
+  {
+    int @KERCHECK = attrib(basering, "KERCHECK");
+  } else
+  {
+    int @KERCHECK = @DEBUG;
+  }
+
+  if( @DEBUG )
+  {
+    "SSComputeLeadingSyzygyTerms::Input: ";
+    L;
+  }
+
+  module SS =   Syzextra::ComputeLeadingSyzygyTerms(L);
+
+  if( @KERCHECK )
+  {
+    int i, j, r;
+    int N = ncols(L);
+    def a, b;
+    poly aa, bb;
+
+    bigint c;
+
+    ideal M;
+
+    module S = 0;
+
+    for(i = 1; i <= N; i++)
+    {
+      a = L[i];
+      c =   Syzextra::leadcomp(a);
+      r = int(c);
+
+      aa =   Syzextra::leadmonomial(a);
+
+      M = 0;
+
+      for(j = i-1; j > 0; j--)
+      {
+        b = L[j];
+
+        if(   Syzextra::leadcomp(b) == c )
+        {
+          bb =   Syzextra::leadmonomial(b);
+
+          M[j] = (lcm(aa, bb) / aa);
+        }
+      }
+
+      // TODO: add quotient relations here...
+
+      M = simplify(M, 1 + 2 + 32);
+
+      M = MySort(M);
+
+      S = S, M * gen(i);
+    }
+
+    S = MySort(simplify(S, 2));
+
+    if( (size(S) + size(SS)) > 0 )
+    {
+      if( size(module(matrix(S) - matrix(SS))) > 0 )
+      {
+        "ERROR: SSComputeLeadingSyzygyTerms: S != SS ";
+
+        "basering: "; basering;
+//          Syzextra::DetailedPrint(basering);
+
+        "S: ";  S;
+//          Syzextra::DetailedPrint(_, 1);
+        "SS: "; SS;
+//          Syzextra::DetailedPrint(_, 1);
+
+        "DIFF: ";
+        module(matrix(S) - matrix(SS));
+//          Syzextra::DetailedPrint(_, 2);
+        print(matrix(S) - matrix(SS));
+          Syzextra::m2_end(666);
+      }
+    }
+  }
+
+
+  if( @DEBUG )
+  {
+    "SSComputeLeadingSyzygyTerms::Output: ";
+    "SS: "; SS;
+  }
+
+  if( size(SS) > 0 )
+  {
+    attrib(SS, "isSB", 1);
+  }
+
+  return (SS);
+}
+
+/// Compute Syz(L), where L is a monomial (leading) module
+static proc SSCompute2LeadingSyzygyTerms(def L)
+{
+  if( typeof( attrib(basering, "DEBUG") ) == "int" )
+  {
+    int @DEBUG = attrib(basering, "DEBUG");
+  } else
+  {
+    int @DEBUG = 0; // !system("with", "ndebug");
+  }
+
+  if( typeof( attrib(basering, "SYZCHECK") ) == "int" )
+  {
+    int @SYZCHECK = attrib(basering, "SYZCHECK");
+  } else
+  {
+    int @SYZCHECK = @DEBUG;
+  }
+
+  if( typeof( attrib(basering, "KERCHECK") ) == "int" )
+  {
+    int @KERCHECK = attrib(basering, "KERCHECK");
+  } else
+  {
+    int @KERCHECK = @DEBUG;
+  }
+
+  if( @DEBUG )
+  {
+    "SSCompute2LeadingSyzygyTerms::Input: ";
+    L;
+  }
+
+  module SS =   Syzextra::Compute2LeadingSyzygyTerms(L);
+
+  if( @DEBUG )
+  {
+    "SSCompute2LeadingSyzygyTerms::Syz(SS): "; SS;
+  }
+
+  if( @SYZCHECK )
+  {
+    if( size(SS) > 0 and size(L) > 0 )
+    {
+      if( size(module(transpose( transpose(SS) * transpose(L) ))) > 0 )
+      {
+        transpose( transpose(SS) * transpose(L) );
+        "ERROR: transpose( transpose(SS) * transpose(L) ) != 0!!!";
+          Syzextra::m2_end(666);
+      }
+    }
+  }
+
+  if( @KERCHECK )
+  {
+    int @TAILREDSYZ = 1;
+    if( typeof( attrib(basering, "TAILREDSYZ") ) == "int" )
+    {
+      @TAILREDSYZ = attrib(basering, "TAILREDSYZ");
+    }
+
+    int i, j, r;
+    int N = ncols(L);
+    def a, b;
+
+    poly aa, bb, @lcm;
+
+    bigint c;
+
+    module M;
+
+    module S = 0;
+
+    for(i = 1; i <= N; i++)
+    {
+      a = L[i];
+  //    "a: ", a;
+      c =   Syzextra::leadcomp(a);
+      r = int(c);
+
+      aa =   Syzextra::leadmonomial(a);
+
+      M = 0;
+
+      for(j = i-1; j > 0; j--)
+      {
+        b = L[j];
+  //      "b: ", b;
+
+        if(   Syzextra::leadcomp(b) == c )
+        {
+          bb =   Syzextra::leadmonomial(b);
+          @lcm = lcm(aa, bb);
+
+          M[j] = (@lcm / aa)* gen(i) - (@lcm / bb)* gen(j);
+        }
+      }
+
+      M = simplify(M, 2);
+
+      // TODO: add quotient relations here...
+      S = S, M;
+    }
+
+    if( @TAILREDSYZ )
+    {
+      // Make sure that 2nd syzygy terms are not reducible by 1st
+      def opts = option(get);
+      option(redSB); option(redTail);
+      S = std(S); // binomial module
+      option(set, opts);
+      //  kill opts;
+    } else
+    {
+      S = simplify(S, 2 + 32);
+    }
+
+    S = MySort(S);
+
+    if( @DEBUG )
+    {
+      "SSCompute2LeadingSyzygyTerms::Syz(S): "; S;
+    }
+
+    if( @SYZCHECK )
+    {
+      if( size(S) > 0 and size(L) > 0 )
+      {
+        if( size(module(transpose( transpose(S) * transpose(L) ))) > 0 )
+        {
+          transpose( transpose(S) * transpose(L) );
+          "ERROR: transpose( transpose(S) * transpose(L) ) != 0!!!";
+            Syzextra::m2_end(666);
+        }
+      }
+    }
+
+    if(size(S) != size(SS))
+    {
+      "ERROR: SSCompute2LeadingSyzygyTerms: size(S) != size(SS)";
+
+      "basering: "; basering; //        Syzextra::DetailedPrint(basering);
+
+      "S: ";  S;
+//        Syzextra::DetailedPrint(S, 2);
+      "SS: "; SS;
+//        Syzextra::DetailedPrint(SS, 2);
+        Syzextra::m2_end(666);
+    }
+
+    if(size(S) > 0 && size(SS) > 0)
+    {
+      if( size(module(matrix(lead(S)) - matrix(lead(SS)))) > 0 )
+      {
+        "ERROR: SSCompute2LeadingSyzygyTerms: lead(S) != lead(SS) ";
+
+        "basering: ";  basering;
+//          Syzextra::DetailedPrint(basering);
+
+        "lead(S ): "; lead(S );
+//          Syzextra::DetailedPrint(_, 2);
+        "lead(SS): "; lead(SS);
+//          Syzextra::DetailedPrint(_, 2);
+
+        "DIFF: ";
+        print( matrix(lead(S)) - matrix(lead(SS))  );
+        module(matrix(lead(S)) - matrix(lead(SS)));
+//          Syzextra::DetailedPrint(_ , 4);
+          Syzextra::m2_end(666);
+      }
+
+
+      if( @TAILREDSYZ )
+      {
+      if( size(module(matrix(  Syzextra::Tail(S)) - matrix(  Syzextra::Tail(SS)))) > 0 )
+      {
+        "ERROR: SSCompute2LeadingSyzygyTerms: Tail(S) != Tail(SS) ";
+
+        "basering: ";  basering;
+//          Syzextra::DetailedPrint(basering);
+
+        "Tail(S ): ";   Syzextra::Tail(S );
+//          Syzextra::DetailedPrint(_, 2);
+        "Tail(SS): ";   Syzextra::Tail(SS);
+//          Syzextra::DetailedPrint(_, 2);
+
+        "DIFF: ";
+        module( matrix(  Syzextra::Tail(S)) - matrix(  Syzextra::Tail(SS)) );
+//          Syzextra::DetailedPrint(_, 4);
+        print( matrix(  Syzextra::Tail(S)) - matrix(  Syzextra::Tail(SS)) );
+          Syzextra::m2_end(666);
+      }
+      }
+    }
+  }
+
+  module S2 =   Syzextra::Tail(SS);
+  SS = lead(SS); // (C,lp) on base ring!
+
+  if( @SYZCHECK )
+  {
+    if( ncols(SS) != ncols(S2) ) // || size(SS) != ncols(SS) || size(S2) != ncols(S2)
+    {
+      "ERROR: SSCompute2LeadingSyzygyTerms: inappropriate S2 / SS: ";
+      type(SS);
+      type(S2);
+      L;
+        Syzextra::m2_end(666);
+    }
+  }
+
+  if( @DEBUG )
+  {
+    "SSCompute2LeadingSyzygyTerms::Output: "; SS; S2;
+  }
+
+  attrib(SS, "isSB", 1);
+
+  return (SS, S2);
+}
+
+// -------------------------------------------------------- //
+
+/// TODO: save shortcut (syz: |-.->) LM(LM(m) * "t") -> syz?
+static proc SSFindReducer(def product, def syzterm, def L, list #)
+{
+  if( typeof( attrib(basering, "DEBUG") ) == "int" )
+  {
+    int @DEBUG = attrib(basering, "DEBUG");
+  } else
+  {
+    int @DEBUG = 0; // !system("with", "ndebug");
+  }
+
+  if( typeof( attrib(basering, "SYZCHECK") ) == "int" )
+  {
+    int @SYZCHECK = attrib(basering, "SYZCHECK");
+  } else
+  {
+    int @SYZCHECK = @DEBUG;
+  }
+
+  if( typeof( attrib(basering, "KERCHECK") ) == "int" )
+  {
+    int @KERCHECK = attrib(basering, "KERCHECK");
+  } else
+  {
+    int @KERCHECK = @DEBUG;
+  }
+
+
+  if( @DEBUG )
+  {
+    "SSFindReducer::Input: ";
+
+    "syzterm: ", syzterm;
+    "product: ", product;
+//    "L: ", L;
+//    "T: ", T;
+    if( size(#) > 0 )
+    {
+//      "LSyz: ", #;
+    }
+  }
+
+
+  if( @DEBUG && (syzterm != 0) )
+  {
+    def @@c =   Syzextra::leadcomp(syzterm); int @@r = int(@@c);
+    def @@product =   Syzextra::leadmonomial(syzterm) * L[@@r];
+
+    if( @@product != product)
+    {
+      "product: ", product, ", @@product: ", @@product;
+      "ERROR: 'syzterm' results in wrong product !!!???";
+        Syzextra::m2_end(666);
+    }
+  }
+
+  if( typeof(#[1]) == "module" )
+  {
+    vector my =   Syzextra::FindReducer(product, syzterm, L/*, T*/, #[1]);
+  } else
+  {
+    vector my =   Syzextra::FindReducer(product, syzterm, L/*, T*/);
+  }
+
+
+  if( @KERCHECK )
+  {
+    bigint c =   Syzextra::leadcomp(product); int r = int(c);
+
+    def a, b, bb;
+
+    vector nf = [0];
+
+    // looking for an appropriate diviser
+    for( int k = ncols(L); k > 0; k-- )
+    {
+      a = L[k];
+      // with the same mod. component
+      if(   Syzextra::leadcomp(a) == c )
+      {
+        b = - (  Syzextra::leadmonomial(product) /   Syzextra::leadmonomial(L[k]));
+
+        // which divides the product: looking for the 1st appropriate one!
+        if( b != 0 )
+        {
+          bb = b * gen(k);
+
+          if (size(bb + syzterm) == 0) // cannot allow something like: a*gen(i) - a*gen(i)
+          {
+            nf = [0];
+          } else
+          {
+            nf = bb;
+          }
+
+          // new syz. term should not be in <LS = #>
+          if( size(#) > 0 )
+          {
+            if( typeof(#[1]) == "module" )
+            {
+              nf = NF(bb, #[1]);
+            }
+          }
+
+          // while the complement (the fraction) is not reducible by leading syzygies
+          if( nf != 0 ) // nf must be == bb!!!
+          {
+            /// TODO: save shortcut LM(m) * T[i] -> ?
+
+            // choose ANY such reduction... (with the biggest index?)
+            break;
+          }
+        }
+      }
+    }
+
+    if( my != nf )
+    {
+      "ERROR in   Syzextra::FindReducer => ", my, " != nf: ", nf;
+        Syzextra::m2_end(666);
+    }
+  }
+
+  if( @DEBUG )
+  {
+    "SSFindReducer::Output: ", my;
+  }
+
+  return (my);
+}
+
+/// TODO: save shortcut (syz: |-.->) LM(m) * "t" -> ?
+static proc SSReduceTerm(poly m, def t, def syzterm, def L, def T, list #)
+{
+  if( typeof( attrib(basering, "DEBUG") ) == "int" )
+  {
+    int @DEBUG = attrib(basering, "DEBUG");
+  } else
+  {
+    int @DEBUG = 0; // !system("with", "ndebug");
+  }
+
+
+  if( @DEBUG )
+  {
+    "SSReduce::Input: ";
+
+    "syzterm: ", syzterm;
+    "mult: ", m;
+    "term: ", t;
+//    "L: ", L;
+//    "T: ", T;
+    if( size(#) > 0 )
+    {
+//      "LSyz: ", #;
+    }
+//    "attrib(LS, 'isSB')", attrib(LS, "isSB");
+  }
+
+  if( typeof( attrib(basering, "KERCHECK") ) == "int" )
+  {
+    int @KERCHECK = attrib(basering, "KERCHECK");
+  } else
+  {
+    int @KERCHECK = @DEBUG;
+  }
+
+  if( typeof( attrib(basering, "SYZCHECK") ) == "int" )
+  {
+    int @SYZCHECK = attrib(basering, "SYZCHECK");
+  } else
+  {
+    int @SYZCHECK = @DEBUG;
+  }
+
+  if( @SYZCHECK && (syzterm != 0) )
+  {
+    def @@c =   Syzextra::leadcomp(syzterm); int @@r = int(@@c);
+    poly @@m =   Syzextra::leadmonomial(syzterm); def @@t = L[@@r];
+
+    if( (@@m != m) || (@@t != t))
+    {
+      "m: ", m, ", t: ", t;
+      "@@m: ", @@m, ", @@t: ", @@t;
+      "ERROR: 'syzterm' results in wrong m * t !!!";
+        Syzextra::m2_end(666);
+    }
+  }
+
+  if( typeof(#[1]) == "module" )
+  {
+    vector ss =   Syzextra::ReduceTerm(m, t, syzterm, L, T, #[1]);
+  } else
+  {
+    vector ss =   Syzextra::ReduceTerm(m, t, syzterm, L, T);
+  }
+
+  if( @KERCHECK )
+  {
+    int @TREEOUTPUT  = attrib(basering, "TREEOUTPUT");
+
+    vector s = 0;
+
+    if( size(t) > 0 )
+    {
+      def product = m * t;
+
+      s = SSFindReducer(product, syzterm, L, #);
+
+      if( size(s) != 0 )
+      {
+        poly @b =   Syzextra::leadmonomial(s);
+
+        def @c =   Syzextra::leadcomp(s); int k = int(@c);
+
+	if( @TREEOUTPUT ){ "\CHILD{", (s), "}{", ( @b*L[k]), "}"; }
+
+        s = s + SSTraverseTail(@b, T[k], L, T, #); // !!!
+      }
+    }
+
+    if( s != ss )
+    {
+      "ERROR in   Syzextra::ReduceTerm => old: ", s, " != ker: ", ss;
+      "m: ", m;
+      "t: ", t;
+      "syzterm: ", syzterm;
+       L; T; #;
+        Syzextra::m2_end(666);
+    }
+  }
+
+  if( @DEBUG )
+  {
+    "SSReduceTerm::Output: ", ss;
+  }
+
+  return (ss);
+}
+
+
+// TODO: store m * @tail -.-^-.-^-.--> ?
+static proc SSTraverseTail(poly m, def @tail, def L, def T, list #)
+{
+  if( typeof( attrib(basering, "DEBUG") ) == "int" )
+  {
+    int @DEBUG = attrib(basering, "DEBUG");
+  } else
+  {
+    int @DEBUG = 0; // !system("with", "ndebug");
+  }
+
+  if( typeof( attrib(basering, "KERCHECK") ) == "int" )
+  {
+    int @KERCHECK = attrib(basering, "KERCHECK");
+  } else
+  {
+    int @KERCHECK = @DEBUG;
+  }
+
+
+  if( @DEBUG )
+  {
+    "SSTraverse::Input: ";
+
+    "mult: ", m;
+    "tail: ", @tail; // T[i];
+
+    if( size(#) > 0 )
+    {
+//      "LSyz: "; #[1];
+    }
+  }
+
+  if( typeof(#[1]) == "module" )
+  {
+    vector ss =   Syzextra::TraverseTail(m, @tail, L, T, #[1]);
+  } else
+  {
+    vector ss =   Syzextra::TraverseTail(m, @tail, L, T);
+  }
+
+  if( @KERCHECK )
+  {
+    vector s = 0;
+
+    def @l, @p;
+    @p = @tail;
+
+  // iterate tail-terms in ANY order!
+    while( size(@p) > 0 )
+    {
+      @l = lead(@p);
+      s = s + SSReduceTerm(m, @l, [0], L, T, #); // :(
+      @p = @p - @l;
+    }
+
+    if( s != ss )
+    {
+      "ERROR in   Syzextra::TraverseTail => old: ", s, " != ker: ", ss;
+      "m: ", m;
+      "@tail: ", @tail;
+      L; T; #;
+        Syzextra::m2_end(666);
+    }
+  }
+
+  if( @DEBUG )
+  {
+    "SSTraverseTail::Output: ", ss;
+  }
+
+  return (ss);
+}
+
+// -------------------------------------------------------- //
+
+static proc SSSchreyerSyzygyNF(vector syz_lead, vector syz_2, def L, def T, list #)
+"  Hybrid Syzygy computation: 'reduce' spoly by eliminating _any_ terms while discurding terms of lower order!
+   Return the tail syzygy (without: syz_lead, starting with: syz_2)"
+{
+  if( typeof( attrib(basering, "DEBUG") ) == "int" )
+  {
+    int @DEBUG = attrib(basering, "DEBUG");
+  } else
+  {
+    int @DEBUG = 0; // !system("with", "ndebug");
+  }
+
+  if( @DEBUG )
+  {
+    "SSSchreyerSyzygyNF::Input: ";
+
+    "syzygy_lead: ", syz_lead;
+    "syzygy 2nd : ", syz_2;
+//    L; T;
+    if( size(#) > 0 )
+    {
+//      "LSyz: "; #[1];
+    }
+  }
+
+  if( typeof( attrib(basering, "KERCHECK") ) == "int" )
+  {
+    int @KERCHECK = attrib(basering, "KERCHECK");
+  } else
+  {
+    int @KERCHECK = @DEBUG;
+  }
+
+  if( typeof(#[1]) == "module" )
+  {
+    def my =   Syzextra::SchreyerSyzygyNF(syz_lead, syz_2, L, T, #[1]);
+  } else
+  {
+    def my =   Syzextra::SchreyerSyzygyNF(syz_lead, syz_2, L, T);
+  }
+
+  if( @KERCHECK )
+  {
+    int @TREEOUTPUT  = attrib(basering, "TREEOUTPUT");
+
+    def spoly =   Syzextra::leadmonomial(syz_lead) * T[int(  Syzextra::leadcomp(syz_lead))]
+              +   Syzextra::leadmonomial(syz_2)    * T[int(  Syzextra::leadcomp(syz_2))];
+
+    vector @tail = syz_2;
+
+    poly @b; int k;
+
+    while (size(spoly) > 0)
+    {
+      syz_2 = SSFindReducer(lead(spoly), 0, L, #); spoly =   Syzextra::Tail(spoly);
+
+      if( size(syz_2) != 0)
+      {
+        @b =   Syzextra::leadmonomial(syz_2);
+	k =  int(  Syzextra::leadcomp(syz_2));
+
+	if( @TREEOUTPUT ){ "\CHILD{", (syz_2), "}{", ( lead(spoly)), "}"; }
+
+        spoly = spoly + @b * T[k];
+        @tail = @tail + syz_2;
+
+      }
+    }
+
+    if( my != @tail )
+    {
+      "ERROR in   Syzextra::SchreyerSyzygyNF => old: ", @tail, " != ker: ", my;
+
+      "syzygy_lead: ", syz_lead;
+      "syzygy 2nd : ", syz_2;
+
+      L; T; #;
+        Syzextra::m2_end(666);
+    }
+  }
+
+  if( @DEBUG )
+  {
+    "SSSchreyerSyzygyNF::Output: ", my;
+  }
+
+  return (my);
+}
+
+
+
+// -------------------------------------------------------- //
+
+// module (N, LL, TT) = SSComputeSyzygy(L, T);
+// Compute Syz(L ++ T) = N = LL ++ TT
+static proc SSComputeSyzygy(def L, def T)
+{
+//  rtimer, "***TIMESNAP0 for   Syzextra::ComputeSyzygy(L,T): on level: [",attrib(basering,"SYZNUMBER"),"] :: t: ", timer, ", r: ", rtimer;
+  int @DEBUG    = attrib(basering, "DEBUG");
+  int @KERCHECK = attrib(basering, "KERCHECK");
+  int @SYZCHECK = attrib(basering, "SYZCHECK");
+
+  if( @DEBUG )
+  {
+    "SSComputeSyzygy::Input";
+    "basering: ", basering; attrib(basering);
+//      Syzextra::DetailedPrint(basering);
+
+//    "iCompShift: ", iCompShift;
+
+    "L: "; L;
+    "T: "; T;
+  }
+
+//  option(prot);
+//  rtimer, "***TIME for   Syzextra::ComputeSyzygy(L,T): on level: [",attrib(basering,"SYZNUMBER"),"] :: t: ", timer, ", r: ", rtimer;
+  list @res=  Syzextra::ComputeSyzygy(L,T);
+//  rtimer, "***TIME for   Syzextra::ComputeSyzygy(L,T): on level: [",attrib(basering,"SYZNUMBER"),"] :: t: ", timer, ", r: ", rtimer;
+//  option(noprot); // TODO: restore!
+
+
+  module @LL = @res[1]; module @TT = @res[2];
+
+  if( @KERCHECK )
+  {
+    int @SYZCHECK    = attrib(basering, "SYZCHECK");
+    int @LEAD2SYZ    = attrib(basering, "LEAD2SYZ");
+    int @TAILREDSYZ  = attrib(basering, "TAILREDSYZ");
+    int @HYBRIDNF    = attrib(basering, "HYBRIDNF");
+    int @IGNORETAILS = attrib(basering, "IGNORETAILS");
+    int @TREEOUTPUT  = attrib(basering, "TREEOUTPUT");
+
+    int @SYZNUMBER   = attrib(basering,"SYZNUMBER");
+
+    if( @HYBRIDNF == 2 )
+    {
+      if( @SYZNUMBER < 3 ){ @HYBRIDNF = 1; } else { @HYBRIDNF = 0; }
+    }
+
+    module LL;
+
+    /// Get the critical leading syzygy terms
+    if( @LEAD2SYZ ) // & 2nd syz. term
+    {
+      module LL2;
+      (LL, LL2) = SSCompute2LeadingSyzygyTerms(L);
+    } else
+    {
+      LL = SSComputeLeadingSyzygyTerms(L);
+    }
+
+    if( ncols(LL) != ncols(@LL) )
+    {
+      "ERROR in SSComputeSyzygy: wrong leading syzygies!?";
+      "";
+      L; T;
+      "";
+      type(LL);
+      type(@LL);
+        Syzextra::m2_end(666);
+    }
+
+    if( size( module( matrix(LL) - matrix(@LL) ) ) != 0 )
+    {
+      "ERROR in SSComputeSyzygy: wrong leading syzygies!?";
+      "";
+      L; T;
+      "";
+      type(LL);
+      type(@LL);
+        Syzextra::m2_end(666);
+    }
+
+    module TT, SYZ;
+
+    vector a, a2; bigint c; int r; poly aa;
+
+    if( size(LL) > 0 )
+    {
+      list LS;
+
+      if( @TAILREDSYZ)
+      {
+        LS = list(LL);
+      }
+
+      vector @tail = 0;
+
+//      for(int k = 1; k <= ncols(LL); k++ )
+      for(int k = ncols(LL); k > 0; k-- )
+      {
+        // leading syz. term:
+        a = LL[k];
+
+        if( !@IGNORETAILS )
+        {
+          c =   Syzextra::leadcomp(a); r = int(c); aa =   Syzextra::leadmonomial(a);
+
+          if( @TREEOUTPUT ){ "\ROOT{", (lead(a)), "}"; }
+
+          // NF reduction:
+          if( @HYBRIDNF == 0 ) // Traverse approach:
+          {
+            @tail = SSTraverseTail(aa, T[r], L, T, LS);
+
+            // get the 2nd syzygy term...
+            if( @LEAD2SYZ ) // with the 2nd syz. term:
+            {
+              a2 = LL2[k]; c =   Syzextra::leadcomp(a2); r = int(c); aa =   Syzextra::leadmonomial(a2);
+
+              if( @TREEOUTPUT ){ "\CHILD{", (lead(a2)), "}{", ( aa*L[r]), "}"; }
+
+              @tail = a2 + @tail + SSTraverseTail(aa, T[r], L, T, LS);
+            } else
+            {
+              @tail = @tail + SSReduceTerm(aa, L[r], a, L, T, LS);
+            }
+
+          } else // Hybrid approach:
+          {
+
+            // get the 2nd syzygy term...
+            if( @LEAD2SYZ )
+            {
+              a2 = LL2[k];
+            } else
+            {
+              a2 = SSFindReducer( aa * L[r], a, L, LS);
+            }
+
+            if ( (@SYZCHECK || @DEBUG) )
+            {
+              if( size(a2) == 0 ) // if syzterm == 0!!!!
+              {
+                "ERROR in SSComputeSyzygy: could not find the 2nd syzygy term during the hybrid NF!!!";
+                  Syzextra::m2_end(666);
+              }
+            }
+
+            if( @TREEOUTPUT ){ "\CHILD{", (a2), "}{", ( aa*L[r]), "}"; }
+
+            @tail = SSSchreyerSyzygyNF(a, a2, L, T, LS);
+          }
+        } // else @tail remains zero!
+
+        TT[k] = @tail;
+        SYZ[k] = a + @tail;
+
+        if ( TT[k] != @TT[k] )
+        {
+          "ERROR in SSComputeSyzygy: wrong tail syzygy!?";
+          "INPUT";
+          L; T;
+          "LEADING SYZYGY TERMS";
+          type(LL);
+
+          "CURRENT TAILS";
+          type(TT);
+          type(@TT);
+
+          "WRONG TAIL [", k, "]:";
+          type(TT[k]);
+          type(@TT[k]);
+
+//          "IMAGES:";
+//              transpose( transpose(N) * transpose(MRES) );
+
+            Syzextra::m2_end(666);
+        }
+
+      } // FOR
+    }
+
+    if( ncols(TT) != ncols(@TT) )
+    {
+      "ERROR in SSComputeSyzygy: wrong tail syzygies!?";
+      "";
+      L; T;
+      "";
+      type(LL);
+      type(@LL);
+      "";
+      type(TT);
+      type(@TT);
+        Syzextra::m2_end(666);
+    }
+
+    if( size( module( matrix(TT) - matrix(@TT) ) ) != 0 )
+    {
+      "ERROR in SSComputeSyzygy: wrong tail syzygies!?";
+      "";
+      TT; @TT;
+      "";
+      L; T;
+      "";
+      type(LL);
+      type(@LL);
+        Syzextra::m2_end(666);
+    }
+
+  }
+
+  module @SYZ;
+
+  for(int @k = ncols(@LL); @k > 0; @k-- )
+  {
+    @SYZ[@k] = @LL[@k] + @TT[@k];
+  }
+
+  if( @DEBUG )
+  {
+    "SSComputeSyzygy::Output";
+
+//    "SYZ: "; @SYZ;
+    "LL: "; @LL;
+    "TT: "; @TT;
+  }
+
+//  rtimer, "***TIMESNAP1 for   Syzextra::ComputeSyzygy(L,T): on level: [",attrib(basering,"SYZNUMBER"),"] :: t: ", timer, ", r: ", rtimer;
+  return (@SYZ, @LL, @TT);
+}
+
+// resolution/syzygy step:
+static proc SSstep()
+{
+//  rtimer, "***TIMESNAP0 for SSstep(): on level: [",attrib(basering,"SYZNUMBER"),"] :: t: ", timer, ", r: ", rtimer;
+
+  int @DEBUG = attrib(basering, "DEBUG");
+  int @SYZCHECK = attrib(basering, "SYZCHECK");
+
+  if( @DEBUG )
+  {
+    "SSstep::NextInducedRing";
+    "basering: ", basering; attrib(basering);
+  }
+
+/*
+  // is initial weights are all zeroes!
+  def L =  lead(M);
+  intvec @V = deg(M[1..ncols(M)]);  @W;  @V;  @W = @V;  attrib(L, "isHomog", @W);
+    Syzextra::SetInducedReferrence(L, @RANK, 0);
+*/
+
+//  def L =  lead(MRES);
+//  @W = @W, @V;
+//  attrib(L, "isHomog", @W);
+
+
+  // General setting:
+//    Syzextra::SetInducedReferrence(MRES, 0, 0); // limit: 0!
+  int @l = size(RES);
+
+  def M =  RES[@l];
+
+  def L = LRES[@l];
+  def T = TRES[@l];
+
+
+  //// TODO: wrong !!!!!
+  int @RANK = ncols(MRES) - ncols(M); // nrows(M); // what if M is zero?!
+
+
+
+/*
+  if( @RANK !=  nrows(M) )
+  {
+    type(MRES);
+    @RANK;
+    type(M);
+    pause();
+  }
+*/
+
+  intvec @W = attrib(M, "isHomog"); intvec @V = attrib(M, "degrees"); @V = @W, @V;
+
+  if( @DEBUG )
+  {
+    "Sstep::NextInput: ";
+    M;
+    L;
+    @V;
+    @RANK;
+//      Syzextra::DetailedPrint(MRES);
+    attrib(MRES, "isHomog");
+  }
+
+
+  // TODO: N  = SYZ( M )!!!
+  module N, LL, TT; (N, LL, TT) = SSComputeSyzygy(/*M, */L, T/*, @RANK*/);
+
+  // shift syz.comp by @RANK:
+  module Z;
+  Z = 0; Z[@RANK] = 0; Z = Z, transpose(LL);   LL = transpose(Z);
+  Z = 0; Z[@RANK] = 0; Z = Z, transpose(TT);   TT = transpose(Z);
+  Z = 0; Z[@RANK] = 0; Z = Z, transpose(N);     N = transpose(Z);
+
+
+  if( @SYZCHECK )
+  {
+    if( size(N) > 0 )
+    {
+      // next syz. property
+      if( size(module(transpose( transpose(N) * transpose(MRES) ))) > 0 )
+      {
+        "MRES", MRES;
+
+        "N: "; N; //   Syzextra::DetailedPrint(N, 2);
+
+        "LL:"; LL; //   Syzextra::DetailedPrint(LL, 1);
+        "TT:"; TT; //   Syzextra::DetailedPrint(TT, 10);
+
+        "RANKS: ", @RANK;
+
+        "transpose( transpose(N) * transpose(MRES) ) != 0!!!";
+        transpose( transpose(N) * transpose(MRES) );
+
+        "transpose(N) * transpose(MRES): ";
+        transpose(N) * transpose(MRES);
+        //   Syzextra::DetailedPrint(module(_), 2);
+          Syzextra::m2_end(666);
+      }
+    }
+  }
+
+  attrib(N, "isHomog", @V);
+
+  // TODO: correct the following:
+  intvec @DEGS = deg(N[1..ncols(N)]); // no mod. comp. weights :(
+
+
+  attrib(N, "degrees", @DEGS);
+
+   RES[@l + 1] = N; // list of all syzygy modules
+  LRES[@l + 1] = LL; // list of all syzygy modules
+  TRES[@l + 1] = TT; // list of all syzygy modules
+
+  MRES = MRES, N;
+
+  attrib(MRES, "isHomog", @V);
+
+//  L = L, lead(N);  attrib(basering, "InducionLeads", L);
+
+  if( @DEBUG )
+  {
+    "SSstep::NextSyzOutput: ";
+    N;
+//      Syzextra::DetailedPrint(N);
+    attrib(N);
+  }
+
+  int ss = attrib(basering, "SYZNUMBER");
+  attrib(basering, "SYZNUMBER", ss + 1 );
+
+//  rtimer, "***TIMESNAP1 for SSstep(): on level: [",attrib(basering,"SYZNUMBER"),"] :: t: ", timer, ", r: ", rtimer;
+}
+
+static proc SScontinue(int l)
+"USAGE:  SScontinue(l)
+RETURN:  nothing, instead it changes RES and MRES variables in the current ring
+PURPOSE: computes further (at most l) syzygies
+NOTE:    must be used within a ring returned by Sres or Ssyz. RES and MRES are
+         explained in Sres
+EXAMPLE: example Scontinue; shows an example
+"
+{
+//  rtimer, "***TIMESNAP0 for SScontinue: on level: [",attrib(basering,"SYZNUMBER"),"] :: t: ", timer, ", r: ", rtimer;
+
+  /// TODO!
+//  def data =   Syzextra::GetInducedData();
+
+  if( (!defined(RES)) || (!defined(MRES)) ) /* || (typeof(data) != "list") || (size(data) != 2) */
+  {
+    ERROR("Sorry, but basering does not seem to be returned by Sres or Ssyz");
+  }
+  for (;  (l != 0) && (size(RES[size(RES)]) > 0); l-- )
+  {
+    SSstep();
+  }
+
+//  rtimer, "***TIMESNAP1 for SScontinue: on level: [",attrib(basering,"SYZNUMBER"),"] :: t: ", timer, ", r: ", rtimer;
+
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring r;
+  module M = maxideal(1); M;
+  def S = SSsyz(M); setring S; S;
+  "Only the first syzygy: ";
+  RES; MRES;
+  "More syzygies: ";
+  SScontinue(10);
+  RES; MRES;
+}
+
+static proc SSsyz(def M)
+"USAGE:  SSsyz(M)
+RETURN:  ring, containing a list of modules RES and a module MRES
+PURPOSE: computes the first syzygy module of M (wrt some Schreyer ordering)?
+NOTE:    The output is explained in Sres
+EXAMPLE: example Ssyz; shows an example
+"
+{
+  if( (typeof(M) != "module") && (typeof(M) != "ideal") )
+  {
+    ERROR("Sorry: need an ideal or a module for input");
+  }
+
+  def SS = SSinit(M); setring SS;
+
+  SSstep(); // NOTE: what if M is zero?
+
+  return (SS);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring r;
+
+/*  ideal M = 0;
+  def S = SSsyz(M); setring S; S;
+  "Only the first syzygy: ";
+  RES; LRES; TRES;
+  MRES;
+
+  kill S; setring r; kill M;
+*/
+
+  ideal M = maxideal(1); M;
+
+  def S = SSres(M, 0); setring S; S;
+  MRES;
+  print(_);
+  RES;
+
+  kill S; setring r; kill M;
+
+  kill r;
+
+  ring R = 0, (w, x, y, z), dp;
+  ideal M = w^2 - x*z,  w*x - y*z,  x^2 - w*y, x*y - z^2, y^2 - w*z;
+
+  def S = SSres(M, 0); setring S; S;
+  "";
+  LRES;
+  "";
+  TRES;
+  "";
+  MRES;
+  print(_);
+  RES;
+}
+
+static proc SSres(def M, int l)
+"USAGE:  SSres(I, l)
+RETURN:  ring, containing a list of modules RES and a module MRES
+PURPOSE: computes (at most l) syzygy modules of M wrt the classical Schreyer
+         induced ordering with gen(i) > gen(j) if i > j, provided both gens
+         are from the same syzygy level.???
+NOTE:    RES contains the images of maps subsituting the beginning of the
+         Schreyer free resolution of baseRing^r/M, while MRES is a sum of
+         these images in a big free sum, containing all the syzygy modules.
+         The syzygy modules are shifted so that gen(i) correspons to MRES[i].
+         The leading zero module RES[0] indicates the fact that coker of the
+         first map is zero. The number of zeroes inducates the rank of input.
+NOTE:    If l == 0 then l is set to be nvars(basering) + 1
+EXAMPLE: example SSres; shows an example
+"
+{
+  if( (typeof(M) != "module") && (typeof(M) != "ideal") )
+  {
+    ERROR("Sorry: need an ideal or a module for input");
+  }
+/*
+  "KERCHECK: ", attrib(SSinit, "KERCHECK");
+  "SYZCHECK: ", attrib(SSinit, "SYZCHECK");
+  "DEBUG: ", attrib(SSinit, "DEBUG");
+  "HYBRIDNF: ", attrib(SSinit, "HYBRIDNF");
+  "TAILREDSYZ: ", attrib(SSinit, "TAILREDSYZ");
+  "LEAD2SYZ: ", attrib(SSinit, "LEAD2SYZ");
+*/
+
+  def SS = SSinit(M); setring SS;
+/*
+  "KERCHECK: ", attrib(SS, "KERCHECK");
+  "SYZCHECK: ", attrib(SS, "SYZCHECK");
+  "DEBUG: ", attrib(SS, "DEBUG");
+  "HYBRIDNF: ", attrib(SS, "HYBRIDNF");
+  "TAILREDSYZ: ", attrib(SS, "TAILREDSYZ");
+  "LEAD2SYZ: ", attrib(SS, "LEAD2SYZ");
+  "";
+  "IGNORETAILS: ", attrib(SS, "IGNORETAILS");
+  "SYZNUMBER: ", attrib(SS, "SYZNUMBER");
+*/
+  if (l == 0)
+  {
+    l = nvars(basering) + 2; // not really an estimate...?!
+  }
+
+  SSstep(); l = l - 1;
+
+  SScontinue(l);
+/*
+  "KERCHECK: ", attrib(SS, "KERCHECK");
+  "SYZCHECK: ", attrib(SS, "SYZCHECK");
+  "DEBUG: ", attrib(SS, "DEBUG");
+  "HYBRIDNF: ", attrib(SS, "HYBRIDNF");
+  "TAILREDSYZ: ", attrib(SS, "TAILREDSYZ");
+  "LEAD2SYZ: ", attrib(SS, "LEAD2SYZ");
+  "";
+  "IGNORETAILS: ", attrib(SS, "IGNORETAILS");
+  "SYZNUMBER: ", attrib(SS, "SYZNUMBER");
+*/
+  return (SS);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring r;
+  module M = maxideal(1); M;
+  def S = SSres(M, 0); setring S; S;
+  RES;
+  MRES;
+}
+
+static proc SRES_betti2(SRES SR, def a)
+{
+  def R = SR.r; setring R;
+  return ( betti(SR.rsltn, a) );
+}
+
+static proc SRES_betti1(SRES SR)
+{
+  def R = SR.r; setring R;
+  return ( betti(SR.rsltn) );
+}
+
+static proc SRES_print(SRES SR)
+{
+  def R = SR.r; setring R;
+  "Schreyer resolution: ";
+  SR.rsltn; //  print ();
+  "over the ring: "; R;
+}
+
+static proc SRES_minres(SRES SR)
+{
+  def save = basering;
+  SRES S;
+  def R = SR.r; S.r = R;
+  setring R;
+  S.rsltn = minres(SR.rsltn); // in target ring :(
+  return (S);
+}
+
+
+// cannot be automatically used via overloading :(
+proc SRES_list(def SR)
+"USAGE:  SRES_list(resolution)
+RETURN:  list
+PURPOSE: convert given resolution to a list
+NOTE:    result is over basering
+SEE ALSO: s_res, resolution
+EXAMPLE: example s_res; shows an example
+"
+{
+  if( typeof(SR) != "SRES" )
+  {
+    list @@@L = SR;
+    return (@@@L);
+  }
+
+  def save = basering;
+  def R = SR.r;
+
+//    if( 0 )  // ( save == R ) // TODO: not implemented :(((
+//    {      list L = SR.rsltn;      return (L);    }
+
+  setring R;
+
+  list @@@L = SR.rsltn;
+  setring save;
+  return (imap( R, @@@L ));
+}
+
+static proc mod_init()
+{
+  int @DEBUG = 0; // !system("with", "ndebug"); //    "om_ndebug?: ", system("with", "om_ndebug");
+
+  if( @DEBUG )  {    listvar(Top);  }
+
+  if( !defined(SRES) )
+  {
+      load("syzextra.so");
+
+      if( @DEBUG ){        listvar(Syzextra);      }
+
+//      exportto(Top,   Syzextra::ClearContent); //      exportto(Top,   Syzextra::ClearDenominators);     exportto(Schreyer,   Syzextra::noop);
+//      exportto(Schreyer,   Syzextra::leadrawexp); //      exportto(Schreyer,   Syzextra::ISUpdateComponents);
+//      exportto(Schreyer,   Syzextra::GetAMData);//      exportto(Schreyer,   Syzextra::SetSyzComp);
+//      exportto(Schreyer,   Syzextra::MakeSyzCompOrdering); //      exportto(Schreyer,   Syzextra::reduce_syz);//      exportto(Schreyer,   Syzextra::p_Content);
+
+//    exportto(Schreyer,   Syzextra::DetailedPrint);
+//    exportto(Schreyer,   Syzextra::m2_end);
+//    exportto(Schreyer,   Syzextra::leadmonomial);
+//    exportto(Schreyer,   Syzextra::leadcomp);
+//    exportto(Schreyer,   Syzextra::SetInducedReferrence);
+//    exportto(Schreyer,   Syzextra::GetInducedData);
+//    exportto(Schreyer,   Syzextra::MakeInducedSchreyerOrdering);
+//    exportto(Schreyer,   Syzextra::idPrepare);
+//    exportto(Schreyer,   Syzextra::ProfilerStart);   exportto(Schreyer,   Syzextra::ProfilerStop);
+//    exportto(Schreyer,   Syzextra::NumberStatsInit); exportto(Schreyer,   Syzextra::NumberStatsPrint);
+//    exportto(Schreyer,   Syzextra::Tail);
+//    exportto(Schreyer,   Syzextra::ComputeLeadingSyzygyTerms);
+//    exportto(Schreyer,   Syzextra::Compute2LeadingSyzygyTerms);
+//    exportto(Schreyer,   Syzextra::Sort_c_ds);
+//    exportto(Schreyer,   Syzextra::FindReducer);
+//    exportto(Schreyer,   Syzextra::ReduceTerm);
+//    exportto(Schreyer,   Syzextra::TraverseTail);
+//    exportto(Schreyer,   Syzextra::SchreyerSyzygyNF);
+//    exportto(Schreyer,   Syzextra::ComputeSyzygy);
+//    exportto(Schreyer,   Syzextra::ComputeResolution);
+
+    // TODO: SSres - return SRESOLUTION?
+    newstruct("SRES","ring r,resolution rsltn"); // http://www.singular.uni-kl.de/Manual/latest/sing_179.htm#SEC218
+//      system("install","SRES","string",SRES_string, 1);
+    system("install","SRES","print",SRES_print, 1);
+    system("install","SRES","betti",SRES_betti1, 1); // http://www.singular.uni-kl.de/Manual/latest/sing_260.htm#SEC299
+    system("install","SRES","betti",SRES_betti2, 2); // http://www.singular.uni-kl.de/Manual/latest/sing_260.htm#SEC299
+    system("install","SRES","minres",SRES_minres, 1); // http://www.singular.uni-kl.de/Manual/latest/sing_344.htm#SEC383
+    system("install","SRES","list", SRES_list, 1); // will never work :(((
+
+//    exportto(Top, s_res); //   Syzextra::GetInducedData);
+
+    if( @DEBUG )    {      listvar(Top);      listvar(Schreyer);    }
+  }
+}
+
+
+static proc testallSexamples()
+{
+  example Ssyz;
+  example Scontinue;
+  example Sres;
+}
+
+static proc testallSSexamples()
+{
+  example SSsyz;
+  example SScontinue;
+  example SSres;
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  testallSexamples();
+  testallSSexamples();
+}
+
+static proc  StartResTesting(list #)
+{
+  int @treeout = attrib(SSinit, "TREEOUTPUT");
+
+  if( defined(@save_res_list) )
+  { ERROR("Sorry: existing global variable @save_res_list - run StopAddResTesting before another Start!!!"); }
+
+  string @save_res_desc = string(#);
+
+  if( !@treeout )
+  {
+    ">>>>>>>>> {{{{{{{{{ STARTING TESTING ('" + @save_res_desc + "') :::::::::::: ";
+  } else
+  {
+    "{ \"Example\": \"" + @save_res_desc + "\", \"computations\": [";
+  }
+
+  list @save_res_list = list();
+  export @save_res_list;
+  export @save_res_desc;
+}
+
+static proc  StopResTesting()
+{
+  int @treeout = attrib(SSinit, "TREEOUTPUT");
+
+  if( defined(@save_opts) || defined(@save_method) || defined(@save_desc) )
+  { ERROR("Sorry: existing global variables - run StopAddResTest before another Start!!!"); }
+
+  if( !defined(@save_res_list) || !defined(@save_res_desc) )
+  { ERROR("Sorry: no global variable - run StartResTesting beforehand!!!"); }
+
+  int i, j;
+  int f = 0;
+  def m, mm;
+
+  if( !@treeout )
+  {
+  for (i = size(@save_res_list); i > 0; i--)
+  {
+    "Total Time: ", @save_res_list[i][5], ", Res: ", @save_res_list[i][6], ", Minimal Betti: ", @save_res_list[i][5] - @save_res_list[i][6], ",        ", @save_res_list[i][1], "   :with:    ", @save_res_list[i][2];
+  }
+
+  }
+
+  for (i = size(@save_res_list); i > 1; i--)
+  {
+    m = @save_res_list[i][4];
+
+    for (j = i-1; j > 0; j--)
+    {
+      mm = @save_res_list[j][4];
+      if( (nrows(m) != nrows(mm)) || (ncols(m) != ncols(mm)) )
+      {
+        "ERROR: SIZE(Betti[j: ", j, "]) != SIZE(Betti[i: ", i, "]):";
+        "j: ", j;
+        print( @save_res_list[j][4], "betti");
+        print(@save_res_list[j]);
+
+        "i: ", i;
+        print( @save_res_list[i][4], "betti");
+        print(@save_res_list[i]);
+
+        f = 1;
+
+      } else
+      {
+        if( m != mm )
+        {
+          "ERROR: Betti[j: ", j, "] != Betti[i: ", i, "]:";
+          "j: ", j;
+          print( @save_res_list[j][4], "betti");
+          print(@save_res_list[j]);
+
+          "i: ", i;
+          print( @save_res_list[i][4], "betti");
+          print(@save_res_list[i]);
+
+          f = 1;
+        };
+      };
+
+    };
+
+  };
+
+  if( f )
+  {
+    print(@save_res_list);
+    "<<<<<<<<< }}}}}}}}}  STOP TESTING (", @save_res_desc,  ") !!!!!!!!!!!! ";
+
+    "ERROR: There were some wrong betti numbers... ";
+//      Syzextra::m2_end(666);
+  } else
+  {
+    if( !@treeout )
+    {
+      "BETTI: "; print( @save_res_list[1][4], "betti");
+    }
+  }
+
+  kill @save_res_list;
+
+  if( !@treeout )
+  {
+    "<<<<<<<<< }}}}}}}}}  STOP TESTING (", @save_res_desc,  ") !!!!!!!!!!!! ";
+  } else
+  {
+//    "{ \"Example\": \"" + @save_res_desc + "\", \"computations\": [";
+    "] },";
+  }
+  kill @save_res_desc;
+}
+
+static proc StartAddResTest(string method, string desc)
+{
+  int @treeout = attrib(SSinit, "TREEOUTPUT");
+
+  if( !defined(@save_res_list) )
+  { ERROR("Sorry: no global variable - run StartResTesting beforehand!!!"); }
+
+  if( defined(@save_opts) || defined(@save_method) || defined(@save_desc) )
+  { ERROR("Sorry: existing global variables - run StopAddResTest before another Start!!!"); }
+
+
+  def @save_opts = option(get); export @save_opts;
+  def @save_method = method; export @save_method;
+  def @save_desc = desc; export @save_desc;
+
+  if( !@treeout )
+  {
+    "< START RES TEST{{{ ", @save_method, ", with:", @save_desc, " ... ";
+  } else
+  {
+//    Print("{ \"RESOLUTION: HYBRIDNF:%d, TAILREDSYZ: %d, LEAD2SYZ: %d, IGNORETAILS: %d\": [\n",
+//       attributes.__HYBRIDNF__, attributes.__TAILREDSYZ__, attributes.__LEAD2SYZ__, attributes.__IGNORETAILS__);
+    " { \"RESOLUTION: " + @save_method + ", with: " + @save_desc + "\": [";
+  }
+}
+
+
+static proc StopAddResTest(def RR, intmat S, int @t, int @m)
+{
+  int @treeout = attrib(SSinit, "TREEOUTPUT");
+
+  if( !(defined(@save_opts) && defined(@save_method) && defined(@save_desc)) )
+  { ERROR("Sorry: no global variables - run StartAddResTest beforehand!!!"); }
+
+  list @l = list(@save_method, @save_desc, option(get), S, @t, @m);
+
+//  RR,
+//  print(S, "betti");
+
+  if( !@treeout )
+  {
+    "> -STOP RES TEST}}} ", @save_method, ", with:", @save_desc, ", Timer:", @t; option();
+  } else
+  {
+    " ] },";
+  }
+
+
+  option(set, @save_opts); kill @save_opts;
+
+  kill @save_method; kill @save_desc;
+
+  @save_res_list[1 + size(@save_res_list)] = @l;
+}
+
+
+static proc SCheck(def S)
+{
+  setring S; // for checking...
+
+  module M = MRES;
+  if( ncols(M) < nrows(M) )
+  {
+    M[nrows(M)] = 0;
+  } else
+  {
+    M = transpose(M);
+    if( ncols(M) < nrows(M) )
+    {
+      M[nrows(M)] = 0;
+    }
+    M = transpose(M);
+  }
+
+  if( nrows(M) != ncols(M) )
+  {
+    "ERROR: non-square M!!!";
+      Syzextra::m2_end(666);
+  }
+
+  if( size(module( M*M )) > 0 )
+  {
+    "ERROR: module( M*M ) != 0!!!";
+    module( M*M );
+
+    "MRES': "; M; print(M);
+
+      Syzextra::m2_end(666);
+  }
+//  "MRES': "; M; print(M);
+
+  if( size(RES[1]) != 0 )
+  {
+    "ERROR: wrong starting zero module!!!";
+      Syzextra::m2_end(666);
+  }
+
+//  RES;
+/*
+  MRES;
+  RES;
+  "";
+  LRES;
+  "";
+  TRES;
+*/
+}
+
+//// TODO: SSres(0) fails..!!!??
+static proc TestSSres(def I)
+{
+  def save = basering;
+  int @t, at m,r,rr,i;
+  string name =
+    "LEAD2SYZ:"  +string(attrib(SSinit,"LEAD2SYZ")) +
+    ",TAILREDSYZ:"+string(attrib(SSinit,"TAILREDSYZ")) +
+    ",HYBRIDNF:"  +string(attrib(SSinit,"HYBRIDNF"));
+
+  int @PROFILE = attrib(SSinit, "PROFILE");
+  if(@PROFILE){ string @prof = "SSres_" + @save_res_desc + "_" + name + ".prof"; }
+
+  StartAddResTest(
+   "SSres",
+   "minres + betti(,1) + mods: {" + name + "}"
+  );
+
+  option(redSB); option(redTail);
+  if(@PROFILE){  Syzextra::ProfilerStart(@prof);}
+  timer=0;rtimer=0;def R=SSres(I,0);@m=rtimer;
+  if(@PROFILE){  Syzextra::ProfilerStop();}
+  setring R;module M;list @l=list();@l[size(RES)-1]=list();r=nrows(RES[1]);for(i=2;i<=size(RES);i++){M=RES[i];rr=nrows(M);if((r>0)&&(size(M)>0)&&(r<rr)){M=transpose(M);M=M[(r+1)..ncols(M)];M=transpose(M);RES[i]=M;};r=rr;@l[i-1] = M;};resolution RR=@l;RR=minres(RR);def S=betti(RR,1);@t=rtimer;
+//    Syzextra::DetailedPrint(RR,0);
+  SCheck(R);
+  StopAddResTest(RR, S, @t, at m);
+  kill S, RR; setring save; kill R;
+}
+
+proc s_res(def I, int l)
+"USAGE:  s_res(ideal/module M, int len)
+RETURN:  resolution object or SRES
+PURPOSE: compute a Schreyer resolution of M of length at most len (see [BMSS])
+NOTE:    If given len is zero then nvars(basering) + 1 is used instead.
+@* This functions is not related to other helpers from this library.
+@* One can switch on computation protocol and statistic (depending on the build) by setting the @code{prot} option.
+@* Further recognized switches are the following attributes of @code{Schreyer::SSinit} procedure:
+LEAD2SYZ, TAILREDSYZ, HYBRIDNF
+DEBUG, ...
+SEE ALSO: sres
+EXAMPLE: example s_res; shows an example
+"
+{
+  int @prot = (find(option(),"prot") != 0) && (defined(  Syzextra::NumberStatsInit)) && (defined(  Syzextra::NumberStatsPrint));
+  def @save = basering;
+
+  int @RINGCHANGE = 0;
+
+  if( typeof( attrib(SSinit, "RINGCHANGE") ) == "int" )
+  {
+    @RINGCHANGE = attrib(SSinit, "RINGCHANGE");
+  }
+
+  def R=SSinit(I);
+  if( @RINGCHANGE ){ setring R; }
+
+  int @l = size(RES);
+  if(@prot){   Syzextra::NumberStatsInit(); }
+  def rsltn =   Syzextra::ComputeResolution(RES[@l], LRES[@l], TRES[@l], l);
+  if(@prot){   Syzextra::NumberStatsPrint("Number statistic for s_res with   Syzextra::ComputeResolution"); }
+
+  if( !@RINGCHANGE )
+  {
+    return (rsltn); // ret
+  }
+
+  SRES ret; ret.r = R; ret.rsltn = rsltn;
+  return (ret);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring R;
+  module M = maxideal(1); M;
+  def  rs = s_res(M, 0);
+  print(rs);
+  print(betti(rs, 0)); // non-minimal betties
+  print(SRES_list(rs));
+  print(betti(rs, 1)); //minimal betties
+  print(minres(rs));
+}
+
+static proc s_res_bm(def I)
+{
+  int @prot = (find(option(),"prot") != 0) && (defined(  Syzextra::NumberStatsInit)) && (defined(  Syzextra::NumberStatsPrint));
+  def @save = basering;
+
+  int @RINGCHANGE = 0;
+
+  if( typeof( attrib(SSinit, "RINGCHANGE") ) == "int" )
+  {
+    @RINGCHANGE = attrib(SSinit, "RINGCHANGE");
+  }
+  int t,tt,sum;
+
+t=rtimer;def R=SSinit(I);tt=rtimer;
+
+  "%% Setup(SSinit) TIME:", tt - t; // if(@prot){ } ?
+  int sum = (tt-t);
+
+  if( @RINGCHANGE ){ setring R; }
+
+  int @l = size(RES);
+  module N, L, T, LL, TT;
+  L = LRES[@l];
+  T = TRES[@l];
+
+
+  int ss = attrib(basering, "SYZNUMBER");
+
+  while ( 1 )
+  {
+    if(@prot){   Syzextra::NumberStatsInit(); }
+
+//  SSstep():
+t=rtimer;(N,LL,TT)=SSComputeSyzygy(L,T);tt=rtimer;
+
+    @l = @l + 1;
+    if(@prot){   Syzextra::NumberStatsPrint("Number statistic for SSComputeSyzygy["+string(@l-2)+"]"); }
+    "%% SSstep[", at l-2, "] TIME:", tt - t;  // if(@prot){ } ?
+    sum = sum + (tt-t);
+
+    if( (size(LL) == 0) || (size(N) == 0) ) { break; }
+    L = LL; T = TT; RES[@l] = N; // LRES[@l] = LL; TRES[@l] = TT;
+
+    ss = ss + 1; attrib(basering, "SYZNUMBER", ss );
+  }
+
+  "%% Whole Resolution (with "+string(@l)+"syzygies) TIME:", sum;  // if(@prot){ } ?
+  resolution rsltn = list(RES[2..size(RES)]);
+
+  if( !@RINGCHANGE )
+  {
+    return (rsltn); // ret
+  }
+
+  SRES ret; ret.r = R; ret.rsltn = rsltn;
+  return (ret);
+}
+
+
+static proc s_syz(def I)
+{
+  def R=SSinit(I); setring R;
+  int @l = size(RES); //   def M =  RES[@l];
+  module N, LL, TT; (N, LL, TT) = SSComputeSyzygy(LRES[@l], TRES[@l]);
+  SSYZ ret; ret.r = R; ret.szg = N; // Schreyer::  Syzextra::ComputeResolution(RES[2], LRES[2], TRES[2], 0);
+  return (ret);
+}
+
+static proc TestSSSres(def I)
+{
+  def save = basering;
+  int @t, at m,r,rr,i;
+  string name =
+    "LEAD2SYZ:"  +string(attrib(SSinit,"LEAD2SYZ")) +
+    ",TAILREDSYZ:"+string(attrib(SSinit,"TAILREDSYZ")) +
+    ",HYBRIDNF:"  +string(attrib(SSinit,"HYBRIDNF"));
+
+  int @PROFILE = attrib(SSinit, "PROFILE");
+  if(@PROFILE){ string @prof = "SSSres_" + @save_res_desc + "_" + name + ".prof"; }
+
+  StartAddResTest(
+   "SSSres",
+   "minres + betti(,1) + mods: {" + name + "}"
+  );
+
+  option(redSB); option(redTail);
+  if(@PROFILE){  Syzextra::ProfilerStart(@prof);}
+  timer=0;rtimer=0;def R=SSinit(I);setring R;def RR=  Syzextra::ComputeResolution(RES[2], LRES[2], TRES[2], 0);
+ at m=rtimer;
+  if(@PROFILE){  Syzextra::ProfilerStop();}
+RR=minres(RR); def S=betti(RR,1);@t=rtimer;
+//    Syzextra::DetailedPrint(RR,0);  print(RR);  print(S, "betti");
+  SCheck(R);
+  StopAddResTest(RR, S, @t, at m);
+  kill S, RR; setring save; kill R;
+}
+
+
+static proc TestSres(def I)
+{
+  def save = basering;
+  int @t,r,rr,i, at m;
+  StartAddResTest(
+  "Sres",
+  "minres + betti(,1)"
+  );
+  option(redSB); option(redTail);
+  timer=0;rtimer=0;def R=Sres(I,0);@m=rtimer;setring R;module M;list @l=list();@l[size(RES)-1]=list();r=nrows(RES[1]);for(i=2;i<=size(RES);i++){M=RES[i];rr=nrows(M);if((r>0)&&(size(M)>0)&&(r<rr)){M=transpose(M);M=M[(r+1)..ncols(M)];M=transpose(M);RES[i]=M;};r=rr;@l[i-1] = M;};resolution RR=@l;RR=minres(RR);def S=betti(RR,1);@t=rtimer;
+  SCheck(R);
+  StopAddResTest(RR, S, @t, at m);
+  kill S, RR; setring save; kill R;
+}
+
+
+static proc Testsres(def M)
+{
+  int @t, at m;
+  StartAddResTest("sres", "no minres + betti(,1)");
+  option(redSB);option(redTail);
+  timer=0;rtimer=0;def RR=sres(groebner(M),0);@m=rtimer;def S=betti(RR,1);@t=rtimer;
+  StopAddResTest(RR, S, @t, at m); kill S, RR;
+}
+
+static proc Testlres(def M)
+{
+  int @t, at m;
+  StartAddResTest("lres", "no minres + betti(,1)");
+  option(redSB);option(redTail);
+  timer=0;rtimer=0;def RR=lres(M,0);@m=rtimer;def S=betti(RR,1);@t=rtimer;
+  StopAddResTest(RR, S, @t, at m); kill S, RR;
+
+  StartAddResTest("lres", "minres + betti()");
+  option(redSB);option(redTail);
+  timer=0;rtimer=0;def RR=lres(M,0);@m=rtimer;def S=betti(minres(RR));@t=rtimer;
+  StopAddResTest(RR, S, @t, at m);
+  kill S, RR;
+}
+
+
+static proc Testnres(def M)
+{
+  int @t, at m;
+  StartAddResTest("nres", "no minres + betti(,1)");
+
+  option(redSB); option(redTail);
+  timer=0;rtimer=0;def RR=nres(M,0);@m=rtimer;def S=betti(RR,1);@t=rtimer;
+
+  StopAddResTest(RR, S, @t, at m); kill S, RR;
+}
+
+static proc TestSSresAttribs(def M, list #)
+{
+  M = groebner(M);
+
+  StartResTesting(#);
+
+  attrib(SSinit, "LEAD2SYZ", 0); attrib(SSinit, "TAILREDSYZ", 1); attrib(SSinit, "HYBRIDNF", 0); TestSSSres(M);
+  attrib(SSinit, "LEAD2SYZ", 0); attrib(SSinit, "TAILREDSYZ", 1); attrib(SSinit, "HYBRIDNF", 1); TestSSSres(M);
+
+ // WRONG???! LEAD2SYZ?
+//  attrib(SSinit, "LEAD2SYZ", 1); attrib(SSinit, "TAILREDSYZ", 1); attrib(SSinit, "HYBRIDNF", 0); TestSSSres(M);
+//  attrib(SSinit, "LEAD2SYZ", 1); attrib(SSinit, "TAILREDSYZ", 1); attrib(SSinit, "HYBRIDNF", 1); TestSSSres(M);
+
+  int @treeout = attrib(SSinit, "TREEOUTPUT");
+  if( !@treeout )
+  {
+   Testlres(M); Testnres(M);
+//   Testsres(M); //   TestSres(M); // too long for the last medium test :(
+  }
+
+  StopResTesting();
+}
+
+static proc TestSSresAttribs2tr(def M, list #)
+{
+  M = groebner(M);
+
+  StartResTesting(#);
+
+  attrib(SSinit, "LEAD2SYZ", 0); attrib(SSinit, "TAILREDSYZ", 1); attrib(SSinit, "HYBRIDNF", 0); TestSSSres(M);
+  Testlres(M);
+
+  StopResTesting();
+}
+
+static proc testSimple(list #)
+{
+  def DEBUG = 0;
+  if(size(#) > 0) { DEBUG = #[1]; }
+
+  def TREE = 0;
+  if(size(#) > 1) { TREE = #[2]; }
+
+  system("--min-time", "0.01");
+  system("--ticks-per-sec", 100);
+
+//  option(prot);
+
+  // TODO: only for now!!
+  attrib(SSinit, "DEBUG", (DEBUG > 0) );
+  attrib(SSinit, "SYZCHECK", (DEBUG > 0) );
+  attrib(SSinit, "KERCHECK", (DEBUG > 0) );
+
+  attrib(SSinit, "TREEOUTPUT", TREE);
+  attrib(SSinit, "PROFILE", 0);
+  attrib(SSinit, "IGNORETAILS", 0); // not only frame
+  
+  attrib(SSinit, "NOCACHING", 0);
+
+  int @treeout = attrib(SSinit, "TREEOUTPUT");
+
+  if( @treeout)
+  {
+    monitor("SimpleTests.json", "o");
+    "{ \"SimpleTests\": [";
+  } else { option(prot); }
+
+
+  ring r; ideal M = maxideal(1);
+  TestSSresAttribs(M, "\\\\GENERATED{" + string(M) + "} in " + string(basering));
+  kill r;
+
+  ring r = 0, (a, b, c, d), lp; ideal M = maxideal(1);
+  TestSSresAttribs(M, "\\\\GENERATED{" + string(M) + "} in " + string(basering));
+  kill r;
+
+  ring R = 0, (w, x, y, z), dp;
+  ideal M = w^2 - x*z,  w*x - y*z,  x^2 - w*y, x*y - z^2, y^2 - w*z;
+  TestSSresAttribs(M, "\\\\GENERATED{" + string(M) + "} in " + string(basering));
+  kill R;
+
+
+  ring r = 0, (a, b, c, d, e, f), dp; ideal M = maxideal(1);
+  TestSSresAttribs(M, "\\\\GENERATED{" + string(M) + "} in " + string(basering));
+  kill r;
+
+
+  ring r = 0, (x, y), lp; ideal M = x2, xy, y2;  // Schreyer conterexample???
+  TestSSresAttribs(M, "\\\\GENERATED{" + string(M) + "} in " + string(basering));
+  kill r;
+
+  ring r = 0, (x, y, z, t), dp; ideal M = homog(xy + y2 +x + 2y -1, t), homog(xz - x -y -z -2, t), homog(yz +1, t);  // TODO: seg. fault?
+  TestSSresAttribs(M, "\\\\GENERATED{" + string(M) + "} in " + string(basering));
+  kill r;
+
+
+  ring AGR = (101), (a, b, c, d), dp;
+  // simple: AGR at 101n3d002s004%1:
+  ideal M = c*d, b*d, a*d, c^2-d^2, b*c, a*c, b^2-d^2, a*b, a^2-d^2;
+  TestSSresAttribs(M, "simple: AGR at 101n3d002s004%1");
+
+  // medium: AGR at 101n3d004s009%1;
+  M = a*b+7*a*c-16*b*c-27*a*d+37*b*d-2*c*d, d^3, c*d^2, b*d^2, a*d^2, c^2*d, b*c*d, a*c*d, b^2*d, a^2*d, c^3, b*c^2, a*c^2, b^2*c, a^2*c, b^3, a^3;
+  TestSSresAttribs(M, "medium: AGR at 101n3d004s009%1");
+
+  kill AGR;
+
+
+  string Name = "bordiga"; int @p=31991; ring R = (@p),(x,y,z,u,v), dp;
+  ideal I = -x2y+26/17xy2+70/17y3+96/121x2z+63/82xyz+115/11y2z-8114xz2-40/79yz2+16/125z3+3023x2u-123/70xyu+3395y2u-81/119xzu-23/66yzu+3626z2u+18/53xu2+111/58yu2-34/39zu2+53/40u3-94/17x2v-10/19xyv+81/88y2v-91/33xzv-9967yzv-103/4z2v-26/109xuv+69/97yuv+92/17zuv-19/96u2v+10/21xv2+6147yv2+32/113zv2-79/82uv2-77/51v3,4347x2y-9017xy2+11327y3+18/79x2z-93/43xyz-35/47y2z+14704xz2+10727yz2-1764z3-612x2u+20/107xyu-103/89y2u-39/2xzu+2345yzu+10251z2u-9984xu2-10299yu2+113/118zu2+37/91u3+2/31x2v+9552xyv- [...]
+  TestSSresAttribs(I, Name);
+  kill @p, Name, R;  
+
+  string Name = "rat.d8.g6"; int @p=31991; ring R = (@p),(x,y,z,u,v), dp;
+  ideal I = -19/125x2y2-87/119xy3-97/21y4+36/53x2yz+2069xy2z-59/50y3z-65/33x2z2-14322xyz2+79/60y2z2-9035xz3-14890yz3+87/47z4-23/48x2yu+45/44xy2u+1972y3u+79/118x2zu-5173xyzu+115/121y2zu+1239xz2u-115/17yz2u-15900z3u-78/95x2u2+67/101xyu2-12757y2u2+12752xzu2+68/21yzu2+103/90z2u2-12917xu3+97/92yu3-24/49zu3-13/79u4-51/61x2yv-3103xy2v+77/117y3v+73/115x2zv-79/33xyzv+123/110y2zv+11969xz2v-31/95yz2v-123/95z3v-105/124x2uv+12624xyuv+2/63y2uv+6579xzuv+13/62yzuv+4388z2uv-12747xu2v-26/105yu2v-78/61zu2v [...]
+  TestSSresAttribs(I, Name);
+  kill R, Name, @p;
+
+
+  if( @treeout)
+  {
+    "] }";
+    monitor("");
+  }
+
+}
+
+static proc testAGR(list #)
+{
+  def DEBUG = 0;
+  if(size(#) > 0) { DEBUG = #[1]; }
+
+  system("--min-time", "0.01");
+  system("--ticks-per-sec", 100);
+
+  attrib(SSinit, "DEBUG", 0);
+  attrib(SSinit, "SYZCHECK", (DEBUG > 0));
+  attrib(SSinit, "KERCHECK", 0);
+  attrib(SSinit, "TREEOUTPUT", 0);
+  attrib(SSinit, "PROFILE", 0);
+  attrib(SSinit, "IGNORETAILS", 0); // not only frame
+
+  option(prot);
+
+  ring AGR = (101), (a, b, c, d), dp; AGR;
+  // lengthy: AGR at 101n3d008s058%3, kernel only!
+  ideal M = c^4*d^2+4*a^3*d^3+29*a^2*b*d^3-2*a*b^2*d^3+2*b^3*d^3-21*a^2*c*d^3+46*a*b*c*d^3+2*b^2*c*d^3-13*a*c^2*d^3+32*b*c^2*d^3+46*c^3*d^3-28*a^2*d^4+4*a*b*d^4+29*b^2*d^4-8*a*c*d^4+33*b*c*d^4-16*c^2*d^4+17*a*d^5-3*b*d^5-42*c*d^5+47*d^6,b*c^3*d^2+35*a^3*d^3+24*a^2*b*d^3+46*a*b^2*d^3-22*b^3*d^3-48*a^2*c*d^3+20*a*b*c*d^3-28*b^2*c*d^3-40*a*c^2*d^3-4*b*c^2*d^3+35*c^3*d^3-21*a^2*d^4+3*a*b*d^4+8*b^2*d^4-2*a*c*d^4-22*b*c*d^4+24*c^2*d^4+44*a*d^5+33*b*d^5+31*c*d^5+26*d^6,a*c^3*d^2-42*a^3*d^3+34*a [...]
+  TestSSresAttribs2tr(M, "AGR at 101n3d008s058%3");
+
+  // AGR at 101n3d010s010%3, a bit slower...
+  M = a^2*b^5-50*a*b^6-26*a^6*c+15*a^5*b*c-42*a^4*b^2*c-2*a^3*b^3*c+40*a^2*b^4*c-20*a*b^5*c+11*b^6*c-17*a^5*c^2-4*a^4*b*c^2+13*a^3*b^2*c^2-7*a^2*b^3*c^2+13*a*b^4*c^2-46*b^5*c^2+38*a^4*c^3+32*a^3*b*c^3-49*a^2*b^2*c^3-41*a*b^3*c^3+9*b^4*c^3+17*a^3*c^4-23*a^2*b*c^4+46*a*b^2*c^4+9*b^3*c^4-20*a^2*c^5-34*a*b*c^5-46*b^2*c^5-3*a*c^6+11*b*c^6-22*a^6*d-5*a^5*b*d-21*a^4*b^2*d-43*a^3*b^3*d-29*a^2*b^4*d+43*a*b^5*d-2*b^6*d+24*a^5*c*d-9*a^4*b*c*d+3*a^3*b^2*c*d+20*a^2*b^3*c*d+47*a*b^4*c*d-41*b^5*c*d+11* [...]
+  TestSSresAttribs2tr(M, "AGR at 101n3d010s010%3");
+  kill AGR;
+
+  ring AGR = (101), (a,b,c,d,e,f,g,h), dp; AGR;
+  // AGR at 101n7d005s010%2, medium: <= 2
+  ideal M =
+f*h-g*h,e*h-g*h,d*h-g*h,c*h-g*h,b*h-g*h,a*h-g*h,e*g+48*f*g-49*g*h,d*g+5*f*g-6*g*h,c*g+49*f*g-50*g*h,b*g-7*f*g+6*g*h,a*g-50*f*g+49*g*h,e*f-20*f*g+19*g*h,d*f+40*f*g-41*g*h,c*f-12*f*g+11*g*h,b*f+45*f*g-46*g*h,a*f+4*f*g-5*g*h,d*e-f*g,c*e-30*f*g+29*g*h,b*e-39*f*g+38*g*h,a*e+10*f*g-11*g*h,c*d-41*f*g+40*g*h,b*d-23*f*g+22*g*h,a*d-20*f*g+19*g*h,b*c+17*f*g-18*g*h,a*c+6*f*g-7*g*h,a*b+28*f*g-29*g*h,g^2*h-g*h^2,f^2*g-8*f*g^2+7*g*h^2,g*h^4+50*h^5,g^5+41*h^5,f*g^4-18*h^5,f^5+29*h^5,e^5+6*h^5,d^5-23*h^5 [...]
+b^5+17*h^5,a^5+17*h^5,h^6;
+  TestSSresAttribs2tr(M, "AGR at 101n7d005s010%2");
+  kill AGR;
+
+// from Andreas...tooo long!?
+
+  ring AGR = (101), (a,b,c,d,e), dp; AGR;
+
+  // AGR101n4d007s021%4
+  ideal M = b^3*c*d-44*a*b*c^2*d-23*b^2*c^2*d-17*a*c^3*d+25*b*c^3*d-28*c^4*d+21*a^3*d^2+28*a^2*b*d^2+45*a*b^2*d^2-45*b^3*d^2+39*a^2*c*d^2+50*a*b*c*d^2-31*b^2*c*d^2+25*a*c^2*d^2-42*b*c^2*d^2-6*c^3*d^2+10*a^2*d^3-18*a*b*d^3-21*b^2*d^3-9*a*c*d^3+37*b*c*d^3-18*c^2*d^3+5*a*d^4+b*d^4-18*c*d^4+23*d^5-5*a^4*e+6*a^3*b*e-21*a^2*b^2*e-28*a*b^3*e+11*b^4*e+19*a^3*c*e+29*a^2*b*c*e-25*a*b^2*c*e-8*b^3*c*e+17*a^2*c^2*e+45*a*b*c^2*e-28*b^2*c^2*e+22*a*c^3*e+33*b*c^3*e+27*c^4*e-50*a^3*d*e+11*a^2*b*d*e-45*a* [...]
+a*b^2*c*d-8*a^2*c^2*d+35*a*b*c^2*d-9*b^2*c^2*d+41*a*c^3*d+11*b*c^3*d+36*c^4*d-36*a^3*d^2-11*a^2*b*d^2-45*a*b^2*d^2+20*b^3*d^2-38*a^2*c*d^2-21*a*b*c*d^2-26*b^2*c*d^2+26*a*c^2*d^2+45*b*c^2*d^2+2*c^3*d^2+35*a^2*d^3-15*a*b*d^3-30*b^2*d^3-37*a*c*d^3+3*b*c*d^3+29*c^2*d^3-39*a*d^4-13*b*d^4+42*c*d^4+50*d^5-47*a^4*e+a^3*b*e-10*a^2*b^2*e+10*a*b^3*e-19*b^4*e+47*a^3*c*e+29*a^2*b*c*e+33*a*b^2*c*e-7*b^3*c*e+29*a^2*c^2*e-2*b^2*c^2*e-19*a*c^3*e+16*b*c^3*e+44*c^4*e+47*a^3*d*e-14*a^2*b*d*e+48*a*b^2*d*e-21 [...]
+a^2*b*c*d+7*a^2*c^2*d-15*a*b*c^2*d+20*b^2*c^2*d+8*a*c^3*d-14*b*c^3*d+34*c^4*d+15*a^3*d^2+37*a^2*b*d^2-11*a*b^2*d^2-8*b^3*d^2-15*a^2*c*d^2-22*a*b*c*d^2-30*b^2*c*d^2+23*a*c^2*d^2+34*b*c^2*d^2+41*c^3*d^2-27*a^2*d^3+24*b^2*d^3-15*a*c*d^3+20*b*c*d^3-16*c^2*d^3-31*a*d^4+18*b*d^4-21*c*d^4+19*d^5+20*a^4*e+38*a^3*b*e-7*a^2*b^2*e+8*a*b^3*e-35*b^4*e+30*a^3*c*e-13*a^2*b*c*e+39*a*b^2*c*e-50*b^3*c*e+50*a^2*c^2*e-21*a*b*c^2*e+17*b^2*c^2*e-23*a*c^3*e+32*b*c^3*e-43*c^4*e-39*a^3*d*e+16*a^2*b*d*e+25*a*b^2* [...]
+a^3*c*d-44*a^2*c^2*d-38*a*b*c^2*d-26*b^2*c^2*d-12*a*c^3*d-21*b*c^3*d+43*c^4*d-22*a^3*d^2-23*a^2*b*d^2+32*a*b^2*d^2+45*b^3*d^2-48*a^2*c*d^2-40*a*b*c*d^2+3*b^2*c*d^2+2*a*c^2*d^2-27*b*c^2*d^2-35*c^3*d^2+33*a^2*d^3-11*a*b*d^3-5*b^2*d^3+8*a*c*d^3-42*b*c*d^3+41*c^2*d^3-41*b*d^4+29*c*d^4+5*d^5+32*a^4*e-46*a^3*b*e-46*a^2*b^2*e+19*a*b^3*e-14*b^4*e-24*a^3*c*e+3*a^2*b*c*e-22*a*b^2*c*e+49*b^3*c*e-47*a^2*c^2*e+27*a*b*c^2*e+48*b^2*c^2*e+20*a*c^3*e-3*b*c^3*e-11*c^4*e-21*a^3*d*e+a^2*b*d*e-13*a*b^2*d*e-3 [...]
+b^4*d+14*a^2*c^2*d+2*a*b*c^2*d+34*b^2*c^2*d-12*a*c^3*d+20*b*c^3*d-20*c^4*d+4*a^3*d^2-47*a^2*b*d^2-34*a*b^2*d^2-22*b^3*d^2+23*a^2*c*d^2-22*a*b*c*d^2-31*b^2*c*d^2-24*a*c^2*d^2+39*b*c^2*d^2-37*c^3*d^2-39*a^2*d^3-49*a*b*d^3-41*b^2*d^3-44*a*c*d^3+33*b*c*d^3-14*c^2*d^3-49*a*d^4+20*b*d^4+37*c*d^4+34*d^5+50*a^4*e-31*a^3*b*e-18*a^2*b^2*e-16*a*b^3*e+45*b^4*e+32*a^3*c*e+43*a^2*b*c*e-27*a*b^2*c*e+5*b^3*c*e+39*a^2*c^2*e+33*a*b*c^2*e-16*b^2*c^2*e-6*a*c^3*e-35*b*c^3*e-4*c^4*e-19*a^3*d*e+25*a^2*b*d*e-20 [...]
+a*b^3*d-32*a^2*c^2*d-43*a*b*c^2*d-38*b^2*c^2*d-33*a*c^3*d-34*b*c^3*d+15*c^4*d-10*a^3*d^2+20*a^2*b*d^2+23*a*b^2*d^2-6*b^3*d^2-46*a^2*c*d^2-29*a*b*c*d^2-20*b^2*c*d^2+17*a*c^2*d^2-42*b*c^2*d^2+27*c^3*d^2-15*a^2*d^3-27*a*b*d^3+43*b^2*d^3-a*c*d^3+45*b*c*d^3+7*c^2*d^3+4*a*d^4-5*b*d^4-13*c*d^4-26*d^5-24*a^4*e-5*a^2*b^2*e-27*a*b^3*e-23*b^4*e+9*a^3*c*e+33*a^2*b*c*e+25*a*b^2*c*e+39*b^3*c*e-30*a^2*c^2*e-33*a*b*c^2*e-37*b^2*c^2*e-13*a*c^3*e+49*b*c^3*e-30*c^4*e+8*a^3*d*e+20*a^2*b*d*e+18*a*b^2*d*e-34* [...]
+a^2*b^2*d-a^2*c^2*d-5*a*b*c^2*d+40*b^2*c^2*d+4*a*c^3*d+35*b*c^3*d+42*c^4*d-23*a^3*d^2-34*a^2*b*d^2+4*a*b^2*d^2+27*b^3*d^2+38*a^2*c*d^2-47*a*b*c*d^2+50*b^2*c*d^2+17*a*c^2*d^2+8*c^3*d^2+26*a^2*d^3-32*a*b*d^3+3*b^2*d^3+16*a*c*d^3-47*b*c*d^3-41*c^2*d^3-22*a*d^4-47*b*d^4-17*c*d^4-43*d^5-49*a^4*e+6*a^3*b*e-46*a^2*b^2*e+30*a*b^3*e-21*b^4*e+30*a^3*c*e+17*a^2*b*c*e+39*a*b^2*c*e+37*b^3*c*e+36*a^2*c^2*e+21*a*b*c^2*e-36*b^2*c^2*e-2*a*c^3*e+18*b*c^3*e-49*c^4*e-47*a^3*d*e+35*a^2*b*d*e+10*a*b^2*d*e+22* [...]
+a^3*b*d-15*a^2*c^2*d-32*a*b*c^2*d+24*b^2*c^2*d+48*a*c^3*d+6*b*c^3*d-40*a^3*d^2+34*a^2*b*d^2+29*a*b^2*d^2+18*b^3*d^2-17*a^2*c*d^2+34*a*b*c*d^2+5*b^2*c*d^2-31*a*c^2*d^2-29*b*c^2*d^2-12*c^3*d^2+11*a^2*d^3+8*a*b*d^3+3*b^2*d^3-33*a*c*d^3-34*b*c*d^3-12*c^2*d^3-48*a*d^4+18*b*d^4+41*c*d^4-45*d^5-22*a^4*e+a^3*b*e-25*a^2*b^2*e+3*a*b^3*e+49*b^4*e-27*a^3*c*e-42*a^2*b*c*e+2*a*b^2*c*e+3*b^3*c*e-40*a^2*c^2*e-30*a*b*c^2*e+2*b^2*c^2*e-14*a*c^3*e-6*b*c^3*e+22*c^4*e-16*a^3*d*e+32*a^2*b*d*e-2*a*b^2*d*e-27*b [...]
+a^4*d+17*a^2*c^2*d-6*a*b*c^2*d-16*b^2*c^2*d-8*a*c^3*d+12*b*c^3*d+31*c^4*d-2*a^3*d^2+45*a^2*b*d^2+29*a*b^2*d^2-47*b^3*d^2+17*a^2*c*d^2-28*a*b*c*d^2-12*b^2*c*d^2-49*a*c^2*d^2-34*b*c^2*d^2-49*c^3*d^2-13*a^2*d^3+12*a*b*d^3-50*b^2*d^3-27*a*c*d^3+17*b*c*d^3+26*c^2*d^3-40*a*d^4+37*b*d^4+31*c*d^4+42*d^5-3*a^4*e+40*a^3*b*e+39*a^2*b^2*e-35*a*b^3*e+2*b^4*e-47*a^3*c*e-45*a^2*b*c*e-24*a*b^2*c*e-20*b^3*c*e+a^2*c^2*e-3*a*b*c^2*e+8*b^2*c^2*e-42*a*c^3*e-49*b*c^3*e-49*c^4*e+42*a^3*d*e+25*a^2*b*d*e+45*a*b^ [...]
+c^5+40*a^2*c^2*d+34*a*b*c^2*d-16*b^2*c^2*d+9*a*c^3*d-13*b*c^3*d+30*c^4*d+18*a^3*d^2+27*a^2*b*d^2+37*a*b^2*d^2-30*b^3*d^2-38*a^2*c*d^2-40*a*b*c*d^2-10*b^2*c*d^2-28*a*c^2*d^2-26*b*c^2*d^2+15*c^3*d^2-7*a^2*d^3+2*a*b*d^3+28*b^2*d^3+27*a*c*d^3+11*b*c*d^3-9*c^2*d^3-18*a*d^4+39*b*d^4+8*c*d^4+20*d^5+34*a^4*e+27*a^3*b*e+10*a^2*b^2*e-10*a*b^3*e+15*b^4*e+a^3*c*e+16*a^2*b*c*e+47*a*b^2*c*e-50*b^3*c*e-45*a^2*c^2*e-47*a*b*c^2*e-38*b^2*c^2*e+49*a*c^3*e+11*b*c^3*e-8*c^4*e-24*a^3*d*e+41*a^2*b*d*e+31*a*b^2 [...]
+b*c^4+9*a^2*c^2*d-47*a*b*c^2*d-29*b^2*c^2*d+24*a*c^3*d-19*b*c^3*d-25*c^4*d+50*a^3*d^2-6*a^2*b*d^2-32*a*b^2*d^2-43*b^3*d^2+42*a^2*c*d^2-16*a*b*c*d^2-40*b^2*c*d^2+3*a*c^2*d^2+9*b*c^2*d^2+34*c^3*d^2-48*a^2*d^3-8*a*b*d^3-22*b^2*d^3+42*a*c*d^3+25*b*c*d^3-31*c^2*d^3-12*a*d^4+25*b*d^4+c*d^4+13*d^5-26*a^4*e+2*a^3*b*e-37*a^2*b^2*e+23*a*b^3*e+25*b^4*e+43*a^3*c*e-10*a^2*b*c*e+16*a*b^2*c*e-24*b^3*c*e+43*a^2*c^2*e-25*a*b*c^2*e+39*b^2*c^2*e+31*a*c^3*e-21*b*c^3*e+16*c^4*e+17*a^3*d*e-33*a^2*b*d*e+34*a*b [...]
+a*c^4-47*a^2*c^2*d+40*a*b*c^2*d-8*b^2*c^2*d+3*a*c^3*d-3*b*c^3*d+38*c^4*d-13*a^3*d^2+3*a^2*b*d^2+19*a*b^2*d^2+24*b^3*d^2-27*a^2*c*d^2-12*a*b*c*d^2-45*b^2*c*d^2+28*a*c^2*d^2+35*b*c^2*d^2-28*c^3*d^2+7*a^2*d^3+3*a*b*d^3-34*b^2*d^3+15*a*c*d^3+36*b*c*d^3-18*c^2*d^3-49*a*d^4+44*b*d^4+c*d^4-10*d^5+31*a^4*e-18*a^3*b*e+7*a^2*b^2*e+38*a*b^3*e+37*b^4*e+18*a^3*c*e-50*a^2*b*c*e+12*a*b^2*c*e+43*b^3*c*e+33*a^2*c^2*e+13*a*b*c^2*e+13*b^2*c^2*e-4*a*c^3*e+13*b*c^3*e+20*c^4*e-32*a^3*d*e-36*a^2*b*d*e+47*a*b^2 [...]
+b^2*c^3+10*a^2*c^2*d+20*a*b*c^2*d+36*b^2*c^2*d-7*a*c^3*d+13*b*c^3*d+42*c^4*d-6*a^3*d^2+13*a^2*b*d^2+31*a*b^2*d^2-29*b^3*d^2+44*a^2*c*d^2-20*a*b*c*d^2+27*b^2*c*d^2+17*a*c^2*d^2-7*b*c^2*d^2-18*c^3*d^2-44*a^2*d^3-35*a*b*d^3-11*b^2*d^3-28*a*c*d^3+b*c*d^3+22*c^2*d^3-13*a*d^4-32*b*d^4-33*c*d^4-48*d^5-16*a^4*e+7*a^3*b*e-40*a^2*b^2*e-47*a*b^3*e+20*b^4*e-41*a^3*c*e+50*a^2*b*c*e-35*a*b^2*c*e+44*b^3*c*e-43*a^2*c^2*e+15*a*b*c^2*e-33*b^2*c^2*e-38*a*c^3*e-16*b*c^3*e+11*c^4*e+46*a^3*d*e+32*a^2*b*d*e+3* [...]
+a*b*c^3-48*a^2*c^2*d-19*a*b*c^2*d+46*b^2*c^2*d-49*a*c^3*d-43*b*c^3*d+c^4*d-12*a^3*d^2+28*a^2*b*d^2+11*a*b^2*d^2+13*b^3*d^2+36*a^2*c*d^2+20*a*b*c*d^2+8*b^2*c*d^2-5*a*c^2*d^2+44*b*c^2*d^2-50*c^3*d^2+34*a^2*d^3+a*b*d^3-25*b^2*d^3+5*a*c*d^3-47*b*c*d^3-4*c^2*d^3-33*a*d^4-29*b*d^4+34*c*d^4+d^5-15*a^4*e+50*a^3*b*e+14*a^2*b^2*e+15*a*b^3*e+34*b^4*e+9*a^3*c*e+38*a^2*b*c*e+12*a*b^2*c*e+21*b^3*c*e+18*a^2*c^2*e+37*a*b*c^2*e-16*b^2*c^2*e+13*a*c^3*e+47*b*c^3*e-41*c^4*e-29*a^3*d*e-45*a^2*b*d*e+3*a*b^2*d [...]
+a^2*c^3-17*a^2*c^2*d-7*a*b*c^2*d+15*b^2*c^2*d+35*a*c^3*d-36*b*c^3*d-19*c^4*d+20*a^3*d^2-39*a^2*b*d^2-3*a*b^2*d^2-2*b^3*d^2+8*a^2*c*d^2+13*a*b*c*d^2-20*b^2*c*d^2+6*a*c^2*d^2-48*b*c^2*d^2-21*c^3*d^2+46*a^2*d^3+39*a*b*d^3+32*b^2*d^3-2*a*c*d^3+47*b*c*d^3+16*c^2*d^3+20*a*d^4-36*b*d^4-12*c*d^4+28*d^5+24*a^4*e+17*a^3*b*e-21*a^2*b^2*e+31*a*b^3*e+24*b^4*e-45*a^3*c*e+34*a^2*b*c*e+3*a*b^2*c*e+34*b^3*c*e+39*a^2*c^2*e+12*a*b*c^2*e+18*b^2*c^2*e+19*a*c^3*e-13*b*c^3*e+7*c^4*e+16*a^3*d*e-4*a^2*b*d*e+35*a [...]
+b^3*c^2+2*a^2*c^2*d-42*a*b*c^2*d-42*b^2*c^2*d+22*a*c^3*d-28*b*c^3*d-24*c^4*d-24*a^3*d^2+40*a^2*b*d^2-7*a*b^2*d^2+31*b^3*d^2+13*a^2*c*d^2+33*a*b*c*d^2+6*b^2*c*d^2+40*a*c^2*d^2+37*b*c^2*d^2+40*c^3*d^2-12*a^2*d^3+26*a*b*d^3+23*b^2*d^3+44*a*c*d^3+13*b*c*d^3-24*c^2*d^3+31*a*d^4+44*b*d^4+32*c*d^4+48*d^5+42*a^4*e+2*a^3*b*e-25*a^2*b^2*e-27*a*b^3*e-21*b^4*e+44*a^3*c*e+50*a^2*b*c*e+42*a*b^2*c*e+28*b^3*c*e+28*a^2*c^2*e+20*a*b*c^2*e+11*b^2*c^2*e-25*a*c^3*e+35*b*c^3*e+11*c^4*e+13*a^3*d*e+13*a^2*b*d*e [...]
+a*b^2*c^2-9*a^2*c^2*d+49*a*b*c^2*d+17*b^2*c^2*d-45*a*c^3*d+27*b*c^3*d-8*c^4*d-25*a^3*d^2-23*a^2*b*d^2+47*a*b^2*d^2+8*b^3*d^2+20*a^2*c*d^2+37*a*b*c*d^2+28*b^2*c*d^2+8*a*c^2*d^2+36*b*c^2*d^2+34*c^3*d^2+37*a^2*d^3+23*a*b*d^3+11*b^2*d^3-46*a*c*d^3+45*b*c*d^3-16*c^2*d^3-27*a*d^4-39*b*d^4+31*c*d^4-24*d^5+42*a^4*e-30*a^3*b*e+12*a^2*b^2*e-18*a*b^3*e+8*b^4*e-33*a^3*c*e+21*a^2*b*c*e-9*a*b^2*c*e+10*b^3*c*e+11*a^2*c^2*e-33*a*b*c^2*e-27*b^2*c^2*e+47*a*c^3*e-35*b*c^3*e+15*c^4*e-19*a^3*d*e+20*a^2*b*d*e [...]
+a^2*b*c^2+25*a^2*c^2*d-27*a*b*c^2*d+43*b^2*c^2*d+3*a*c^3*d+35*b*c^3*d+39*c^4*d+12*a^3*d^2-39*a^2*b*d^2-38*a*b^2*d^2+8*b^3*d^2+14*a^2*c*d^2+42*a*b*c*d^2-16*b^2*c*d^2+32*a*c^2*d^2-26*b*c^2*d^2+31*c^3*d^2-34*a^2*d^3-4*a*b*d^3+40*b^2*d^3+34*a*c*d^3-31*b*c*d^3+11*c^2*d^3+9*a*d^4+27*b*d^4+19*c*d^4-44*d^5-45*a^4*e+43*a^3*b*e-36*a^2*b^2*e+23*a*b^3*e-14*b^4*e-2*a^3*c*e+20*a^2*b*c*e-34*a*b^2*c*e+26*b^3*c*e+2*a^2*c^2*e-32*a*b*c^2*e+35*b^2*c^2*e-44*a*c^3*e-47*b*c^3*e-6*c^4*e+4*a^3*d*e+34*a^2*b*d*e-3 [...]
+a^3*c^2+32*a^2*c^2*d+18*a*b*c^2*d+26*b^2*c^2*d-34*a*c^3*d+29*b*c^3*d+6*c^4*d-46*a^3*d^2-37*a^2*b*d^2-9*a*b^2*d^2+13*b^3*d^2-46*a^2*c*d^2-25*a*b*c*d^2-19*b^2*c*d^2-36*a*c^2*d^2-28*b*c^2*d^2+c^3*d^2-16*a^2*d^3-32*a*b*d^3-39*b^2*d^3-a*c*d^3-44*b*c*d^3-24*c^2*d^3+44*a*d^4-18*b*d^4-11*c*d^4+31*d^5-37*a^4*e+50*a^3*b*e-3*a^2*b^2*e+40*a*b^3*e-19*b^4*e+31*a^3*c*e+49*a^2*b*c*e+14*a*b^2*c*e+22*b^3*c*e-27*a^2*c^2*e-46*a*b*c^2*e+31*b^2*c^2*e+22*a*c^3*e+27*b*c^3*e+25*c^4*e+10*a^3*d*e-21*a^2*b*d*e-13*a [...]
+b^4*c+25*a^2*c^2*d+37*a*b*c^2*d+12*b^2*c^2*d-31*b*c^3*d+40*c^4*d-49*a^3*d^2+8*a^2*b*d^2+36*a*b^2*d^2+48*b^3*d^2-15*a^2*c*d^2+20*a*b*c*d^2-13*b^2*c*d^2-2*a*c^2*d^2+11*b*c^2*d^2+46*c^3*d^2+49*a^2*d^3-3*a*b*d^3-31*b^2*d^3-11*a*c*d^3+4*b*c*d^3+7*c^2*d^3-27*b*d^4+c*d^4+43*d^5+41*a^4*e-28*a^3*b*e+37*a^2*b^2*e-18*a*b^3*e+20*b^4*e-3*a^3*c*e+42*a^2*b*c*e-26*a*b^2*c*e-36*b^3*c*e-32*a^2*c^2*e+33*a*b*c^2*e-18*b^2*c^2*e-45*a*c^3*e+22*b*c^3*e+22*c^4*e+28*a^3*d*e-17*a^2*b*d*e-37*a*b^2*d*e-11*b^3*d*e+44 [...]
+a*b^3*c+7*a^2*c^2*d-37*a*b*c^2*d-27*b^2*c^2*d-a*c^3*d-28*b*c^3*d+32*c^4*d-17*a^3*d^2+30*a^2*b*d^2+7*a*b^2*d^2-32*b^3*d^2-10*a^2*c*d^2+38*a*b*c*d^2-15*b^2*c*d^2+a*c^2*d^2-37*b*c^2*d^2-9*c^3*d^2-13*a^2*d^3+27*a*b*d^3-11*b^2*d^3+6*a*c*d^3+b*c*d^3-9*c^2*d^3+44*a*d^4+3*b*d^4-36*c*d^4+41*d^5-3*a^4*e+10*a^3*b*e-8*a*b^3*e-3*b^4*e-3*a^3*c*e+34*a^2*b*c*e+3*a*b^2*c*e+15*b^3*c*e-22*a^2*c^2*e-33*a*b*c^2*e-4*b^2*c^2*e+48*a*c^3*e+7*b*c^3*e-29*c^4*e+38*a^3*d*e+14*a^2*b*d*e-26*a*b^2*d*e+48*b^3*d*e-3*a^2* [...]
+a^2*b^2*c-22*a^2*c^2*d+2*a*b*c^2*d-39*b^2*c^2*d-32*a*c^3*d-39*b*c^3*d+32*c^4*d+47*a^3*d^2-9*a^2*b*d^2+36*a*b^2*d^2-22*b^3*d^2+a^2*c*d^2+7*a*b*c*d^2+21*b^2*c*d^2+35*a*c^2*d^2+31*b*c^2*d^2+38*c^3*d^2+4*a^2*d^3+50*a*b*d^3-10*b^2*d^3-7*a*c*d^3-8*b*c*d^3-23*c^2*d^3+18*a*d^4+13*b*d^4+5*c*d^4-6*d^5-41*a^4*e+50*a^3*b*e+3*a^2*b^2*e+20*a*b^3*e-26*b^4*e-22*a^3*c*e+9*a^2*b*c*e+5*a*b^2*c*e+38*b^3*c*e-16*a^2*c^2*e-35*a*b*c^2*e-17*b^2*c^2*e-4*a*c^3*e-32*b*c^3*e-19*c^4*e-21*a^3*d*e+23*a^2*b*d*e+37*a*b^2 [...]
+a^3*b*c+40*a^2*c^2*d-47*a*b*c^2*d-27*b^2*c^2*d+41*a*c^3*d-39*b*c^3*d-32*c^4*d+5*a^3*d^2-5*a^2*b*d^2-34*a*b^2*d^2-35*b^3*d^2+29*a^2*c*d^2+4*a*b*c*d^2-6*b^2*c*d^2+25*a*c^2*d^2+6*b*c^2*d^2-44*c^3*d^2-38*a^2*d^3-31*a*b*d^3+37*b^2*d^3-49*a*c*d^3-17*b*c*d^3+9*c^2*d^3+25*a*d^4+4*b*d^4-25*c*d^4-49*d^5-15*a^4*e-11*a^3*b*e+7*a^2*b^2*e+37*a*b^3*e-21*b^4*e+18*a^3*c*e+46*a^2*b*c*e+6*a*b^2*c*e+43*b^3*c*e-5*a^2*c^2*e+49*a*b*c^2*e+44*b^2*c^2*e-18*a*c^3*e+30*b*c^3*e+30*c^4*e+37*a^3*d*e-47*a^2*b*d*e+23*a* [...]
+a^4*c-40*a^2*c^2*d+21*a*b*c^2*d+43*b^2*c^2*d+31*a*c^3*d-4*b*c^3*d+49*c^4*d+24*a^3*d^2-14*a^2*b*d^2+3*a*b^2*d^2-6*b^3*d^2+27*a^2*c*d^2+24*a*b*c*d^2-47*b^2*c*d^2-16*a*c^2*d^2+21*b*c^2*d^2-33*c^3*d^2+39*a^2*d^3-34*a*b*d^3-7*b^2*d^3+3*a*c*d^3+30*b*c*d^3-10*c^2*d^3+17*a*d^4+28*b*d^4+16*c*d^4-19*d^5+16*a^4*e-14*a^3*b*e+19*a^2*b^2*e-12*a*b^3*e-41*b^4*e-28*a^3*c*e+13*a^2*b*c*e+35*a*b^2*c*e-35*b^3*c*e+37*a^2*c^2*e-7*a*b*c^2*e+33*b^2*c^2*e-30*a*c^3*e+36*b*c^3*e-26*c^4*e-27*a^3*d*e+28*a^2*b*d*e+2*a [...]
+b^5-5*a^2*c^2*d-23*a*b*c^2*d+3*b^2*c^2*d-30*a*c^3*d-48*b*c^3*d-40*c^4*d-21*a^3*d^2-13*a^2*b*d^2+36*a*b^2*d^2-35*b^3*d^2-9*a^2*c*d^2+32*a*b*c*d^2-19*b^2*c*d^2+3*a*c^2*d^2-2*b*c^2*d^2+22*c^3*d^2-37*a^2*d^3+46*a*b*d^3-38*b^2*d^3-33*a*c*d^3-7*b*c*d^3+3*c^2*d^3-33*a*d^4+b*d^4+22*c*d^4+50*d^5-33*a^4*e+18*a^3*b*e+11*a^2*b^2*e-19*a*b^3*e+49*b^4*e+3*a^3*c*e-10*a^2*b*c*e-29*a*b^2*c*e-17*b^3*c*e-15*a^2*c^2*e+30*a*b*c^2*e+39*b^2*c^2*e+7*a*c^3*e-46*b*c^3*e+29*c^4*e-17*a^3*d*e+26*a^2*b*d*e+27*a*b^2*d* [...]
+a*b^4-14*a^2*c^2*d+14*b^2*c^2*d+36*a*c^3*d+7*b*c^3*d-14*c^4*d-11*a^3*d^2+40*a^2*b*d^2-29*a*b^2*d^2-45*b^3*d^2+23*a^2*c*d^2+8*a*b*c*d^2+28*b^2*c*d^2+42*a*c^2*d^2+14*b*c^2*d^2+42*c^3*d^2-36*a^2*d^3-4*a*b*d^3+6*a*c*d^3-18*b*c*d^3+40*c^2*d^3-47*a*d^4-19*b*d^4-16*c*d^4+31*d^5-15*a^4*e+46*a^3*b*e+13*a^2*b^2*e-18*a*b^3*e+9*b^4*e+50*a^3*c*e-10*a^2*b*c*e-12*a*b^2*c*e+44*b^3*c*e+7*a^2*c^2*e+39*a*b*c^2*e-36*b^2*c^2*e+29*a*c^3*e-37*b*c^3*e-28*c^4*e-43*a^3*d*e+50*a^2*b*d*e-16*a*b^2*d*e+17*b^3*d*e+23* [...]
+a^2*b^3-25*a^2*c^2*d+26*a*b*c^2*d+32*b^2*c^2*d-48*a*c^3*d-7*b*c^3*d-44*c^4*d+14*a^3*d^2+19*a^2*b*d^2-7*a*b^2*d^2-15*b^3*d^2+50*a^2*c*d^2-11*a*b*c*d^2-13*b^2*c*d^2-33*a*c^2*d^2-46*b*c^2*d^2+12*c^3*d^2-26*a^2*d^3-11*a*b*d^3+22*b^2*d^3+24*a*c*d^3-12*b*c*d^3-22*c^2*d^3+40*a*d^4-23*b*d^4-48*c*d^4-20*d^5+17*a^4*e-41*a^3*b*e-a^2*b^2*e-12*a*b^3*e-9*b^4*e-30*a^3*c*e+50*a^2*b*c*e+31*a*b^2*c*e+5*b^3*c*e+33*a^2*c^2*e+15*a*b*c^2*e-50*b^2*c^2*e+24*a*c^3*e-b*c^3*e-6*c^4*e-31*a^3*d*e-26*a^2*b*d*e+49*a*b [...]
+a^3*b^2-40*a^2*c^2*d+50*a*b*c^2*d+25*b^2*c^2*d+46*a*c^3*d-45*b*c^3*d-6*c^4*d-24*a^3*d^2-9*a^2*b*d^2-15*a*b^2*d^2+5*b^3*d^2+36*a^2*c*d^2-19*a*b*c*d^2+19*b^2*c*d^2+17*a*c^2*d^2+12*b*c^2*d^2-25*c^3*d^2-33*a^2*d^3-27*a*b*d^3+42*b^2*d^3-4*a*c*d^3+33*b*c*d^3+32*c^2*d^3+10*a*d^4+47*c*d^4-3*d^5-23*a^4*e-45*a^3*b*e+41*a^2*b^2*e+47*a*b^3*e+15*b^4*e-2*a^3*c*e+12*a^2*b*c*e+13*a*b^2*c*e-45*b^3*c*e-28*a^2*c^2*e-3*a*b*c^2*e-37*b^2*c^2*e+39*a*c^3*e+37*c^4*e-12*a^3*d*e-48*a^2*b*d*e-5*a*b^2*d*e+47*b^3*d*e [...]
+a^4*b-45*a^2*c^2*d-6*a*b*c^2*d-42*b^2*c^2*d-4*a*c^3*d-49*b*c^3*d+14*c^4*d+35*a^3*d^2-3*a^2*b*d^2+23*a*b^2*d^2+21*b^3*d^2-24*a^2*c*d^2-14*a*b*c*d^2+20*b^2*c*d^2-20*a*c^2*d^2+41*b*c^2*d^2-34*c^3*d^2-13*a^2*d^3-48*a*b*d^3-13*b^2*d^3+38*a*c*d^3+21*b*c*d^3+40*c^2*d^3-28*a*d^4-34*b*d^4+38*c*d^4-24*d^5-48*a^4*e-2*a^3*b*e-35*a^2*b^2*e+2*a*b^3*e-25*b^4*e+47*a^3*c*e-14*a^2*b*c*e+25*a*b^2*c*e-12*b^3*c*e-11*a^2*c^2*e+22*a*b*c^2*e+15*b^2*c^2*e+17*a*c^3*e+47*b*c^3*e-43*c^4*e+28*a^3*d*e+9*a^2*b*d*e+6*a [...]
+a^5-45*a^2*c^2*d-14*a*b*c^2*d-47*b^2*c^2*d-8*a*c^3*d+13*b*c^3*d+50*c^4*d-34*a^3*d^2-5*a^2*b*d^2+36*a*b^2*d^2+11*b^3*d^2+41*a^2*c*d^2-32*a*b*c*d^2+41*b^2*c*d^2-40*a*c^2*d^2+14*b*c^2*d^2+5*c^3*d^2+25*a^2*d^3+10*a*b*d^3-24*b^2*d^3-33*b*c*d^3-21*c^2*d^3+a*d^4+44*b*d^4-46*c*d^4-23*d^5-13*a^4*e+13*a^3*b*e-49*a*b^3*e+18*b^4*e+2*a^3*c*e+15*a^2*b*c*e-14*a*b^2*c*e-38*b^3*c*e+34*a^2*c^2*e+42*a*b*c^2*e-42*b^2*c^2*e-36*a*c^3*e+35*b*c^3*e-11*c^4*e+20*a^3*d*e+41*a*b^2*d*e+40*b^3*d*e-39*a^2*c*d*e-35*a*b [...]
+e^6, d*e^5, c*e^5, b*e^5, a*e^5, d^2*e^4, c*d*e^4, b*d*e^4, a*d*e^4, c^2*e^4,
+b*c*e^4, a*c*e^4, b^2*e^4, a*b*e^4, a^2*e^4, d^3*e^3, c*d^2*e^3, b*d^2*e^3,
+a*d^2*e^3, c^2*d*e^3, b*c*d*e^3, a*c*d*e^3, b^2*d*e^3, a*b*d*e^3, a^2*d*e^3,
+c^3*e^3, b*c^2*e^3, a*c^2*e^3, b^2*c*e^3, a*b*c*e^3, a^2*c*e^3, b^3*e^3,
+a*b^2*e^3, a^2*b*e^3, a^3*e^3, d^4*e^2, c*d^3*e^2, b*d^3*e^2, a*d^3*e^2,
+c^2*d^2*e^2, b*c*d^2*e^2, a*c*d^2*e^2, b^2*d^2*e^2, a*b*d^2*e^2, a^2*d^2*e^2,
+c^3*d*e^2, b*c^2*d*e^2, a*c^2*d*e^2, b^2*c*d*e^2, a*b*c*d*e^2, a^2*c*d*e^2,
+b^3*d*e^2, a*b^2*d*e^2, a^2*b*d*e^2, a^3*d*e^2, c^4*e^2, b*c^3*e^2, a*c^3*e^2,
+b^2*c^2*e^2, a*b*c^2*e^2;
+  TestSSresAttribs2tr(M, "AGR101n4d007s021%4");
+/*
+options:  1 1 0 :  Time:  5/9/10 (35 without LCM)
+options:  1 1 1 :  Time:  6/8/25
+lres  Time:  5
+nres  Time:  5
+sres  Time:  693
+*/
+
+  kill M;
+
+
+
+  // AGR101n4d008s020%1, too big?
+  ideal M =
+c^5*d-49*a^4*d^2-36*a^3*b*d^2-a^2*b^2*d^2-26*a*b^3*d^2+2*b^4*d^2+8*a^3*c*d^2-46*a^2*b*c*d^2-43*a*b^2*c*d^2-46*b^3*c*d^2-3*a^2*c^2*d^2-43*a*b*c^2*d^2+49*b^2*c^2*d^2-10*a*c^3*d^2+35*b*c^3*d^2+20*c^4*d^2-42*a^3*d^3+45*a^2*b*d^3+32*a*b^2*d^3-45*b^3*d^3-27*a^2*c*d^3+13*a*b*c*d^3+25*b^2*c*d^3+8*a*c^2*d^3+9*b*c^2*d^3+9*c^3*d^3+45*a^2*d^4+30*a*b*d^4+39*b^2*d^4-23*a*c*d^4+2*b*c*d^4-16*c^2*d^4+32*a*d^5-34*b*d^5+39*c*d^5+12*d^6-29*a^5*e-23*a^4*b*e-29*a^3*b^2*e-a^2*b^3*e-20*a*b^4*e+42*b^5*e+20*a^4*c [...]
+b*c^4*d-26*a^4*d^2-47*a^3*b*d^2+28*a^2*b^2*d^2+5*a*b^3*d^2+37*b^4*d^2-32*a^3*c*d^2+44*a^2*b*c*d^2+13*a*b^2*c*d^2-45*b^3*c*d^2+35*a^2*c^2*d^2-18*a*b*c^2*d^2-3*b^2*c^2*d^2-4*a*c^3*d^2-27*b*c^3*d^2-37*a^3*d^3-44*a^2*b*d^3-36*a*b^2*d^3+49*b^3*d^3-16*a^2*c*d^3+24*a*b*c*d^3+43*b^2*c*d^3-40*a*c^2*d^3-3*b*c^2*d^3-16*c^3*d^3+6*a^2*d^4+46*a*b*d^4+8*b^2*d^4-11*a*c*d^4-4*b*c*d^4-40*c^2*d^4-31*a*d^5-41*b*d^5-35*c*d^5-35*d^6+5*a^5*e-20*a^4*b*e+48*a^3*b^2*e-42*a^2*b^3*e+46*a*b^4*e-28*b^5*e+42*a^4*c*e+2 [...]
+a*c^4*d+8*a^4*d^2+41*a^3*b*d^2-36*a^2*b^2*d^2+7*a*b^3*d^2+35*b^4*d^2+19*a^3*c*d^2-31*a^2*b*c*d^2+23*a*b^2*c*d^2-18*b^3*c*d^2+14*a*b*c^2*d^2-8*b^2*c^2*d^2+31*a*c^3*d^2-46*b*c^3*d^2-29*c^4*d^2-42*a^3*d^3+46*a^2*b*d^3-24*a*b^2*d^3+46*b^3*d^3-18*a^2*c*d^3-49*a*b*c*d^3-6*b^2*c*d^3+20*a*c^2*d^3+17*b*c^2*d^3+38*c^3*d^3-36*a^2*d^4+16*a*b*d^4+23*b^2*d^4-34*a*c*d^4-9*b*c*d^4-18*c^2*d^4-18*a*d^5+26*b*d^5-9*c*d^5-3*d^6-17*a^5*e+32*a^4*b*e-23*a^3*b^2*e-4*a^2*b^3*e+42*a*b^4*e-43*b^5*e+28*a^4*c*e+5*a^3 [...]
+b^2*c^3*d-49*a^4*d^2+36*a^3*b*d^2-3*a^2*b^2*d^2+12*a*b^3*d^2+11*b^4*d^2+10*a^3*c*d^2+9*a^2*b*c*d^2-13*a*b^2*c*d^2+43*b^3*c*d^2-27*a^2*c^2*d^2-20*a*b*c^2*d^2+34*b^2*c^2*d^2-30*a*c^3*d^2-50*b*c^3*d^2+43*c^4*d^2+17*a^3*d^3+5*a^2*b*d^3+16*a*b^2*d^3+27*b^3*d^3-26*a^2*c*d^3+17*a*b*c*d^3-31*b^2*c*d^3-43*a*c^2*d^3-18*b*c^2*d^3-8*c^3*d^3-8*a^2*d^4+8*a*b*d^4+23*b^2*d^4+7*a*c*d^4-48*b*c*d^4+21*c^2*d^4+5*a*d^5+4*b*d^5+40*c*d^5-22*d^6+3*a^5*e-a^4*b*e+26*a^3*b^2*e+16*a^2*b^3*e-29*a*b^4*e-50*b^5*e-6*a^ [...]
+a*b*c^3*d-20*a^4*d^2+23*a^3*b*d^2-14*a^2*b^2*d^2+29*a*b^3*d^2-36*b^4*d^2-48*a^3*c*d^2+39*a^2*b*c*d^2-34*a*b^2*c*d^2+b^3*c*d^2-25*a^2*c^2*d^2+22*a*b*c^2*d^2-12*b^2*c^2*d^2+48*a*c^3*d^2-41*b*c^3*d^2+13*c^4*d^2-24*a^3*d^3-43*a^2*b*d^3-31*a*b^2*d^3-13*b^3*d^3+10*a^2*c*d^3-16*a*b*c*d^3+48*b^2*c*d^3-18*a*c^2*d^3+7*b*c^2*d^3+8*c^3*d^3-14*a^2*d^4-14*a*b*d^4+49*b^2*d^4+43*a*c*d^4+7*b*c*d^4-50*c^2*d^4-21*a*d^5-33*b*d^5-44*c*d^5-40*d^6-42*a^5*e+39*a^4*b*e-14*a^3*b^2*e+34*a^2*b^3*e+22*a*b^4*e+37*b^5 [...]
+a^2*c^3*d+25*a^4*d^2-40*a^3*b*d^2-49*a^2*b^2*d^2+30*a*b^3*d^2-36*b^4*d^2+41*a^3*c*d^2+23*a^2*b*c*d^2-16*a*b^2*c*d^2-20*b^3*c*d^2-46*a^2*c^2*d^2-29*a*b*c^2*d^2-14*b^2*c^2*d^2-38*a*c^3*d^2+9*b*c^3*d^2+50*c^4*d^2-20*a^3*d^3-14*a^2*b*d^3+13*a*b^2*d^3+5*b^3*d^3+7*a^2*c*d^3+46*a*b*c*d^3+40*b^2*c*d^3-46*a*c^2*d^3+27*b*c^2*d^3-5*c^3*d^3+43*a^2*d^4+5*a*b*d^4+3*b^2*d^4+29*a*c*d^4-43*b*c*d^4-31*c^2*d^4-24*a*d^5-45*b*d^5-26*c*d^5-6*d^6+18*a^5*e+22*a^4*b*e-12*a^3*b^2*e+40*a^2*b^3*e-8*a*b^4*e+36*b^5*e [...]
+b^3*c^2*d+13*a^4*d^2+14*a^3*b*d^2-11*a^2*b^2*d^2-12*a*b^3*d^2-8*b^4*d^2-46*a^3*c*d^2-26*a^2*b*c*d^2+28*a*b^2*c*d^2+13*b^3*c*d^2-36*a^2*c^2*d^2+35*a*b*c^2*d^2+49*b^2*c^2*d^2+32*a*c^3*d^2+17*b*c^3*d^2+34*c^4*d^2-8*a^3*d^3-10*a^2*b*d^3+31*a*b^2*d^3-22*b^3*d^3+a^2*c*d^3+32*a*b*c*d^3+33*b^2*c*d^3+34*a*c^2*d^3-36*b*c^2*d^3-11*c^3*d^3-42*a^2*d^4-15*a*b*d^4-3*b^2*d^4-48*a*c*d^4+12*b*c*d^4+35*c^2*d^4-43*a*d^5+9*b*d^5+47*c*d^5+19*d^6-18*a^5*e+9*a^4*b*e+34*a^3*b^2*e+5*a^2*b^3*e+46*a*b^4*e-34*b^5*e- [...]
+a*b^2*c^2*d-26*a^4*d^2-24*a^3*b*d^2-36*a^2*b^2*d^2+26*a*b^3*d^2+26*b^4*d^2+44*a^3*c*d^2-31*a^2*b*c*d^2-49*a*b^2*c*d^2-30*b^3*c*d^2-13*a^2*c^2*d^2+49*a*b*c^2*d^2-50*b^2*c^2*d^2+27*a*c^3*d^2+24*c^4*d^2-47*a^3*d^3+29*a^2*b*d^3+31*a*b^2*d^3-30*b^3*d^3+39*a^2*c*d^3+23*a*b*c*d^3+5*b^2*c*d^3-30*a*c^2*d^3-20*b*c^2*d^3-27*c^3*d^3-40*a^2*d^4+36*a*b*d^4+28*b^2*d^4+29*a*c*d^4+2*b*c*d^4+14*c^2*d^4-41*a*d^5+22*b*d^5+22*c*d^5+9*d^6-22*a^5*e-33*a^4*b*e-19*a^3*b^2*e+30*a^2*b^3*e+4*a*b^4*e+42*b^5*e-13*a^4 [...]
+a^2*b*c^2*d+14*a^4*d^2+25*a^3*b*d^2-2*a^2*b^2*d^2-32*a*b^3*d^2-31*b^4*d^2-40*a^3*c*d^2-15*a^2*b*c*d^2+50*a*b^2*c*d^2+b^3*c*d^2-7*a^2*c^2*d^2-14*a*b*c^2*d^2+8*b^2*c^2*d^2+25*a*c^3*d^2+6*b*c^3*d^2+25*c^4*d^2-20*a^3*d^3+a^2*b*d^3-27*a*b^2*d^3+24*b^3*d^3+33*a^2*c*d^3-14*a*b*c*d^3-48*b^2*c*d^3+10*a*c^2*d^3+8*b*c^2*d^3+13*c^3*d^3-11*a^2*d^4+41*a*b*d^4+48*b^2*d^4+29*a*c*d^4-29*b*c*d^4+40*c^2*d^4+50*a*d^5+33*b*d^5-35*c*d^5-17*d^6-31*a^5*e+42*a^4*b*e+48*a^3*b^2*e-48*a^2*b^3*e-6*a*b^4*e+27*b^5*e+3 [...]
+a^3*c^2*d+17*a^4*d^2+4*a^3*b*d^2+a^2*b^2*d^2+20*a*b^3*d^2-36*b^4*d^2-13*a^3*c*d^2+40*a^2*b*c*d^2-21*a*b^2*c*d^2-35*b^3*c*d^2-33*a^2*c^2*d^2-a*b*c^2*d^2+12*b^2*c^2*d^2+33*a*c^3*d^2-34*b*c^3*d^2-11*c^4*d^2+9*a^3*d^3-32*a^2*b*d^3+42*a*b^2*d^3-49*b^3*d^3-12*a^2*c*d^3-12*a*b*c*d^3+12*b^2*c*d^3+20*a*c^2*d^3+44*b*c^2*d^3+15*c^3*d^3+16*a^2*d^4+46*a*b*d^4+26*b^2*d^4+2*a*c*d^4-28*b*c*d^4-45*c^2*d^4+17*a*d^5-29*b*d^5+28*c*d^5-39*d^6+16*a^5*e+50*a^4*b*e+5*a^3*b^2*e+5*a^2*b^3*e-30*a*b^4*e-8*b^5*e+29* [...]
+b^4*c*d-16*a^4*d^2-19*a^3*b*d^2+43*a^2*b^2*d^2+18*a*b^3*d^2-14*b^4*d^2-6*a^3*c*d^2-33*a^2*b*c*d^2-38*a*b^2*c*d^2-4*b^3*c*d^2+16*a^2*c^2*d^2-38*a*b*c^2*d^2+40*b^2*c^2*d^2+11*a*c^3*d^2+36*b*c^3*d^2+26*c^4*d^2+a^3*d^3-37*a^2*b*d^3-5*a*b^2*d^3-36*b^3*d^3+38*a^2*c*d^3+32*a*b*c*d^3+12*b^2*c*d^3+24*a*c^2*d^3-40*b*c^2*d^3-9*c^3*d^3+15*a^2*d^4+36*a*b*d^4-50*b^2*d^4-43*a*c*d^4+43*b*c*d^4+33*c^2*d^4-8*a*d^5-28*b*d^5-42*c*d^5-20*d^6+16*a^5*e+4*a^4*b*e+41*a^3*b^2*e+18*a^2*b^3*e+26*a*b^4*e+12*b^5*e+3* [...]
+a*b^3*c*d-15*a^4*d^2-41*a^3*b*d^2-50*a^2*b^2*d^2-45*b^4*d^2+29*a^3*c*d^2+43*a^2*b*c*d^2-7*a*b^2*c*d^2-49*b^3*c*d^2+10*a^2*c^2*d^2+13*a*b*c^2*d^2-8*b^2*c^2*d^2+22*a*c^3*d^2+21*b*c^3*d^2-20*c^4*d^2-25*a^3*d^3+28*a^2*b*d^3+36*a*b^2*d^3+b^3*d^3-38*a^2*c*d^3+34*a*b*c*d^3-33*b^2*c*d^3+11*a*c^2*d^3+48*b*c^2*d^3+33*c^3*d^3+5*a^2*d^4+5*a*b*d^4+4*b^2*d^4+37*a*c*d^4+44*b*c*d^4-35*c^2*d^4+8*a*d^5+38*b*d^5+43*c*d^5-15*d^6+15*a^5*e+31*a^4*b*e-30*a^3*b^2*e+46*a^2*b^3*e-29*a*b^4*e+13*b^5*e-38*a^4*c*e+39 [...]
+a^2*b^2*c*d+30*a^4*d^2-8*a^3*b*d^2-31*a^2*b^2*d^2-48*a*b^3*d^2-8*b^4*d^2-a^3*c*d^2-45*a^2*b*c*d^2+24*a*b^2*c*d^2-50*b^3*c*d^2+26*a^2*c^2*d^2-21*a*b*c^2*d^2+7*b^2*c^2*d^2-23*a*c^3*d^2-3*b*c^3*d^2-37*c^4*d^2+30*a^3*d^3-49*a^2*b*d^3-10*a*b^2*d^3+19*b^3*d^3-a^2*c*d^3-23*a*b*c*d^3+27*b^2*c*d^3+8*a*c^2*d^3+36*b*c^2*d^3+14*c^3*d^3-14*a^2*d^4+11*a*b*d^4+24*b^2*d^4-22*a*c*d^4+14*b*c*d^4-12*c^2*d^4+33*a*d^5-35*b*d^5-20*c*d^5-22*d^6-25*a^5*e-50*a^4*b*e-3*a^3*b^2*e-49*a^2*b^3*e-47*a*b^4*e-12*b^5*e+2 [...]
+a^3*b*c*d+41*a^4*d^2+15*a^3*b*d^2-2*a^2*b^2*d^2-33*a*b^3*d^2+9*b^4*d^2+25*a^3*c*d^2-22*a^2*b*c*d^2-7*a*b^2*c*d^2-14*b^3*c*d^2-34*a^2*c^2*d^2-30*a*b*c^2*d^2+50*b^2*c^2*d^2+12*a*c^3*d^2-6*b*c^3*d^2+25*c^4*d^2-41*a^3*d^3-2*a^2*b*d^3+10*a*b^2*d^3+6*b^3*d^3-26*a^2*c*d^3+17*a*b*c*d^3+24*b^2*c*d^3+42*a*c^2*d^3-28*b*c^2*d^3+9*c^3*d^3+41*a^2*d^4-48*a*b*d^4+18*b^2*d^4-26*a*c*d^4+33*b*c*d^4-8*c^2*d^4+35*a*d^5+14*b*d^5-48*c*d^5-23*d^6+49*a^5*e+16*a^4*b*e+2*a^3*b^2*e+26*a^2*b^3*e+5*a*b^4*e+39*b^5*e-3 [...]
+a^4*c*d-22*a^3*b*d^2+25*a^2*b^2*d^2+46*a*b^3*d^2+4*b^4*d^2-49*a^3*c*d^2+10*a^2*b*c*d^2-18*a*b^2*c*d^2-24*b^3*c*d^2+a^2*c^2*d^2-44*a*b*c^2*d^2+19*b^2*c^2*d^2+2*a*c^3*d^2-16*b*c^3*d^2+23*c^4*d^2-34*a^3*d^3+29*a^2*b*d^3+18*a*b^2*d^3-31*b^3*d^3-26*a^2*c*d^3+35*a*b*c*d^3-2*b^2*c*d^3-3*a*c^2*d^3-8*b*c^2*d^3+50*c^3*d^3-11*a^2*d^4+30*a*b*d^4-41*b^2*d^4+41*a*c*d^4+12*b*c*d^4+2*c^2*d^4+44*a*d^5+5*b*d^5-8*c*d^5-37*d^6+10*a^5*e+20*a^4*b*e-32*a^3*b^2*e-7*a^2*b^3*e-11*a*b^4*e-3*b^5*e+47*a^4*c*e-39*a^3 [...]
+b^5*d-5*a^4*d^2-29*a^3*b*d^2-36*a^2*b^2*d^2-11*a*b^3*d^2+32*b^4*d^2-17*a^3*c*d^2+47*a^2*b*c*d^2+16*a*b^2*c*d^2-24*b^3*c*d^2+12*a^2*c^2*d^2+20*a*b*c^2*d^2-24*b^2*c^2*d^2-10*a*c^3*d^2-26*b*c^3*d^2+22*c^4*d^2-14*a^3*d^3-49*a^2*b*d^3-44*a*b^2*d^3-20*b^3*d^3+11*a^2*c*d^3-45*a*b*c*d^3-5*b^2*c*d^3-19*a*c^2*d^3-10*b*c^2*d^3-35*c^3*d^3-13*a^2*d^4+18*a*b*d^4+10*b^2*d^4+46*a*c*d^4+15*b*c*d^4-13*c^2*d^4-8*a*d^5+50*b*d^5+2*c*d^5-43*d^6-18*a^5*e-2*a^4*b*e-31*a^3*b^2*e-37*a^2*b^3*e+32*a*b^4*e-4*b^5*e+1 [...]
+a*b^4*d+47*a^4*d^2+25*a^3*b*d^2-13*a^2*b^2*d^2+26*a*b^3*d^2-24*b^4*d^2-4*a^3*c*d^2-30*a^2*b*c*d^2+11*a*b^2*c*d^2+49*b^3*c*d^2-11*a^2*c^2*d^2-4*a*b*c^2*d^2+44*b^2*c^2*d^2+46*a*c^3*d^2-3*b*c^3*d^2-30*c^4*d^2+8*a^3*d^3+49*a^2*b*d^3+33*a*b^2*d^3+8*b^3*d^3-34*a^2*c*d^3-29*a*b*c*d^3-35*b^2*c*d^3-10*a*c^2*d^3+13*b*c^2*d^3-22*c^3*d^3+8*a^2*d^4+2*a*b*d^4+7*b^2*d^4-14*a*c*d^4+40*b*c*d^4+41*c^2*d^4-14*a*d^5+10*c*d^5-11*d^6-43*a^5*e-2*a^4*b*e-10*a^3*b^2*e-39*a^2*b^3*e+15*a*b^4*e-8*b^5*e+19*a^4*c*e+3 [...]
+a^2*b^3*d-26*a^4*d^2+24*a^3*b*d^2-21*a^2*b^2*d^2-7*a*b^3*d^2-39*b^4*d^2-47*a^3*c*d^2+37*a^2*b*c*d^2+24*a*b^2*c*d^2-6*b^3*c*d^2+20*a^2*c^2*d^2-4*b^2*c^2*d^2+21*a*c^3*d^2-15*b*c^3*d^2-22*c^4*d^2-23*a^3*d^3+21*a^2*b*d^3-16*a*b^2*d^3-38*b^3*d^3-16*a^2*c*d^3+7*a*b*c*d^3-37*b^2*c*d^3-12*a*c^2*d^3+42*b*c^2*d^3+40*c^3*d^3-35*a^2*d^4+29*a*b*d^4-b^2*d^4+21*a*c*d^4+47*b*c*d^4-22*c^2*d^4-11*a*d^5-44*b*d^5+49*c*d^5+33*d^6-35*a^5*e-41*a^4*b*e+17*a^3*b^2*e-6*a^2*b^3*e-12*a*b^4*e+36*b^5*e-6*a^4*c*e-28*a [...]
+a^3*b^2*d-42*a^4*d^2-17*a^3*b*d^2-23*a^2*b^2*d^2-17*a*b^3*d^2-27*b^4*d^2-50*a^3*c*d^2+27*a^2*b*c*d^2-30*a*b^2*c*d^2-7*b^3*c*d^2+21*a^2*c^2*d^2+13*a*b*c^2*d^2+29*b^2*c^2*d^2-46*a*c^3*d^2+43*b*c^3*d^2-2*c^4*d^2-2*a^3*d^3+45*a^2*b*d^3-15*a*b^2*d^3-47*b^3*d^3-17*a^2*c*d^3-25*a*b*c*d^3+9*b^2*c*d^3-24*a*c^2*d^3+32*b*c^2*d^3+37*c^3*d^3+14*a^2*d^4+23*a*b*d^4+49*b^2*d^4+10*a*c*d^4+19*b*c*d^4-13*c^2*d^4-9*a*d^5+44*b*d^5+39*c*d^5-28*d^6-2*a^5*e+5*a^4*b*e-36*a^3*b^2*e-12*a^2*b^3*e+2*a*b^4*e+15*b^5*e [...]
+a^4*b*d+4*a^4*d^2-24*a^3*b*d^2+8*a^2*b^2*d^2-24*a*b^3*d^2-b^4*d^2+31*a^3*c*d^2-45*a^2*b*c*d^2-12*a*b^2*c*d^2+45*b^3*c*d^2+29*a^2*c^2*d^2+41*a*b*c^2*d^2-2*b^2*c^2*d^2-44*a*c^3*d^2-9*b*c^3*d^2+32*c^4*d^2+50*a^3*d^3-6*a^2*b*d^3+11*a*b^2*d^3-6*b^3*d^3-36*a^2*c*d^3-13*a*b*c*d^3-44*b^2*c*d^3+35*a*c^2*d^3+29*b*c^2*d^3-32*c^3*d^3+45*a^2*d^4-24*a*b*d^4-b^2*d^4+48*a*c*d^4+29*b*c*d^4+43*c^2*d^4+34*a*d^5-b*d^5+14*c*d^5+12*d^6-50*a^5*e-26*a^4*b*e-38*a^3*b^2*e-5*a^2*b^3*e+41*a*b^4*e+38*b^5*e-14*a^4*c* [...]
+a^5*d+14*a^4*d^2-3*a^3*b*d^2+7*a^2*b^2*d^2-31*a*b^3*d^2-42*b^4*d^2-16*a^3*c*d^2+36*a^2*b*c*d^2-17*a*b^2*c*d^2-15*b^3*c*d^2+17*a^2*c^2*d^2+36*a*b*c^2*d^2+12*b^2*c^2*d^2-47*a*c^3*d^2-16*b*c^3*d^2-9*c^4*d^2-38*a^3*d^3-43*a^2*b*d^3+2*a*b^2*d^3-44*b^3*d^3-12*a^2*c*d^3+32*a*b*c*d^3+21*b^2*c*d^3-10*a*c^2*d^3-28*b*c^2*d^3-c^3*d^3+18*a^2*d^4-13*a*b*d^4+13*b^2*d^4+31*a*c*d^4+27*b*c*d^4+34*c^2*d^4-19*a*d^5-36*b*d^5-46*c*d^5+11*d^6-26*a^5*e-24*a^4*b*e-5*a^3*b^2*e+27*a^2*b^3*e-6*a*b^4*e-30*b^5*e+35*a [...]
+c^6+36*a^4*d^2-8*a^3*b*d^2-40*a^2*b^2*d^2-45*a*b^3*d^2+36*b^4*d^2-21*a^3*c*d^2-27*a^2*b*c*d^2+46*a*b^2*c*d^2+30*b^3*c*d^2+4*a*b*c^2*d^2-20*b^2*c^2*d^2+3*a*c^3*d^2-48*b*c^3*d^2-29*c^4*d^2+13*a^3*d^3-3*a^2*b*d^3-13*a*b^2*d^3-38*b^3*d^3+35*a^2*c*d^3-5*a*b*c*d^3-46*b^2*c*d^3-26*a*c^2*d^3-20*b*c^2*d^3-4*c^3*d^3+6*a^2*d^4-14*a*b*d^4+16*b^2*d^4+44*a*c*d^4-10*b*c*d^4+15*c^2*d^4+31*a*d^5-22*b*d^5-36*c*d^5-34*d^6-28*a^5*e+46*a^4*b*e+5*a^3*b^2*e+36*a^2*b^3*e-2*a*b^4*e+13*b^5*e-40*a^4*c*e+31*a^3*b*c [...]
+b*c^5+8*a^4*d^2-16*a^3*b*d^2+26*a^2*b^2*d^2+a*b^3*d^2+40*b^4*d^2-34*a^3*c*d^2+5*a^2*b*c*d^2+18*a*b^2*c*d^2-30*b^3*c*d^2+9*a^2*c^2*d^2+30*a*b*c^2*d^2-17*b^2*c^2*d^2+26*a*c^3*d^2+49*b*c^3*d^2+42*c^4*d^2+2*a^3*d^3+28*a^2*b*d^3-7*a*b^2*d^3-37*b^3*d^3+38*a^2*c*d^3-5*a*b*c*d^3-13*b^2*c*d^3-11*a*c^2*d^3-37*b*c^2*d^3+4*c^3*d^3-8*a^2*d^4-9*a*b*d^4+28*b^2*d^4+4*a*c*d^4+27*b*c*d^4+39*c^2*d^4+9*a*d^5-24*b*d^5+27*c*d^5+13*d^6-23*a^5*e-41*a^4*b*e-23*a^3*b^2*e+28*a^2*b^3*e+29*a*b^4*e-49*b^5*e-4*a^4*c*e [...]
+a*c^5+28*a^4*d^2-23*a^3*b*d^2+10*a^2*b^2*d^2-36*a*b^3*d^2+6*b^4*d^2+25*a^3*c*d^2-47*a^2*b*c*d^2+28*a*b^2*c*d^2-36*b^3*c*d^2-31*a^2*c^2*d^2-35*a*b*c^2*d^2-42*b^2*c^2*d^2+20*a*c^3*d^2-45*b*c^3*d^2+49*c^4*d^2-24*a^3*d^3+25*a^2*b*d^3+27*a*b^2*d^3+49*b^3*d^3-9*a^2*c*d^3-46*a*b*c*d^3-39*b^2*c*d^3-9*a*c^2*d^3-46*b*c^2*d^3+43*c^3*d^3-35*a^2*d^4+11*a*b*d^4+15*b^2*d^4-4*a*c*d^4+42*b*c*d^4+19*c^2*d^4-35*a*d^5-23*b*d^5-45*c*d^5+6*d^6-36*a^5*e-35*a^4*b*e+47*a^3*b^2*e-20*a^2*b^3*e+28*a*b^4*e+37*b^5*e- [...]
+b^2*c^4-39*a^4*d^2+a^3*b*d^2+26*a^2*b^2*d^2+29*a*b^3*d^2-5*b^4*d^2+13*a^3*c*d^2-47*a^2*b*c*d^2+17*a*b^2*c*d^2+22*b^3*c*d^2+25*a^2*c^2*d^2-2*a*b*c^2*d^2+18*b^2*c^2*d^2+43*a*c^3*d^2+48*b*c^3*d^2-24*c^4*d^2-17*a^3*d^3-16*a^2*b*d^3-3*a*b^2*d^3+35*b^3*d^3+8*a^2*c*d^3+30*a*b*c*d^3-6*b^2*c*d^3+17*a*c^2*d^3-25*b*c^2*d^3+34*c^3*d^3+13*a^2*d^4-49*a*b*d^4-48*b^2*d^4-6*a*c*d^4+43*b*c*d^4+31*c^2*d^4+30*a*d^5-12*b*d^5+4*c*d^5+39*d^6+48*a^5*e+15*a^4*b*e-41*a^3*b^2*e+41*a^2*b^3*e-16*a*b^4*e+28*b^5*e-48* [...]
+a*b*c^4+44*a^4*d^2-12*a^3*b*d^2-6*a^2*b^2*d^2-20*a*b^3*d^2+48*b^4*d^2+19*a^3*c*d^2+4*a^2*b*c*d^2+50*a*b^2*c*d^2+34*b^3*c*d^2-a^2*c^2*d^2-24*a*b*c^2*d^2+43*b^2*c^2*d^2-21*a*c^3*d^2-29*b*c^3*d^2+36*c^4*d^2+48*a^3*d^3-26*a^2*b*d^3-16*a*b^2*d^3+29*b^3*d^3-48*a^2*c*d^3-19*a*b*c*d^3-17*b^2*c*d^3-44*a*c^2*d^3+5*b*c^2*d^3-6*c^3*d^3-a^2*d^4-30*a*b*d^4-16*b^2*d^4+20*a*c*d^4+17*b*c*d^4-50*c^2*d^4+36*a*d^5-36*b*d^5-2*c*d^5+46*d^6-10*a^5*e-39*a^4*b*e+20*a^3*b^2*e+45*a^2*b^3*e-35*a*b^4*e+2*b^5*e+23*a^ [...]
+a^2*c^4+45*a^4*d^2-49*a^3*b*d^2-20*a^2*b^2*d^2-12*a*b^3*d^2-21*b^4*d^2-29*a^3*c*d^2+23*a^2*b*c*d^2+6*a*b^2*c*d^2-30*b^3*c*d^2-33*a^2*c^2*d^2+31*a*b*c^2*d^2+12*b^2*c^2*d^2+20*a*c^3*d^2-48*b*c^3*d^2-21*c^4*d^2-23*a^3*d^3-38*a^2*b*d^3-41*a*b^2*d^3-3*b^3*d^3+13*a^2*c*d^3-10*a*b*c*d^3-14*b^2*c*d^3+47*a*c^2*d^3+46*b*c^2*d^3-49*c^3*d^3-a^2*d^4-13*a*b*d^4+34*b^2*d^4+8*a*c*d^4-44*b*c*d^4+c^2*d^4-10*a*d^5-b*d^5-34*c*d^5-8*d^6-28*a^5*e+21*a^4*b*e-44*a^3*b^2*e-3*a^2*b^3*e-7*a*b^4*e+49*b^5*e-25*a^4*c [...]
+b^3*c^3-13*a^4*d^2-41*a^3*b*d^2+27*a^2*b^2*d^2+a*b^3*d^2+33*b^4*d^2+47*a^3*c*d^2-19*a^2*b*c*d^2-27*a*b^2*c*d^2-6*b^3*c*d^2+37*a^2*c^2*d^2+40*a*b*c^2*d^2+12*b^2*c^2*d^2+36*a*c^3*d^2-25*b*c^3*d^2-45*c^4*d^2-12*a^3*d^3-5*a^2*b*d^3+31*a*b^2*d^3-b^3*d^3-37*a^2*c*d^3+26*a*b*c*d^3-48*b^2*c*d^3+36*a*c^2*d^3+16*b*c^2*d^3+44*c^3*d^3+47*a^2*d^4-20*a*b*d^4-13*b^2*d^4+39*a*c*d^4+17*b*c*d^4-32*c^2*d^4-24*a*d^5-41*b*d^5-31*c*d^5+29*a^5*e+26*a^4*b*e+12*a^3*b^2*e-45*a^2*b^3*e+40*a*b^4*e+20*b^5*e-21*a^4*c [...]
+a*b^2*c^3+41*a^4*d^2-33*a^3*b*d^2+21*a^2*b^2*d^2-47*a*b^3*d^2-23*b^4*d^2+9*a^3*c*d^2+49*a^2*b*c*d^2+44*a*b^2*c*d^2-25*b^3*c*d^2-28*a^2*c^2*d^2+37*a*b*c^2*d^2+9*b^2*c^2*d^2-21*a*c^3*d^2+36*b*c^3*d^2+48*c^4*d^2+2*a^3*d^3+15*a^2*b*d^3-3*a*b^2*d^3-40*b^3*d^3-19*a^2*c*d^3+4*a*b*c*d^3-29*b^2*c*d^3-48*a*c^2*d^3+41*b*c^2*d^3+34*c^3*d^3+33*a^2*d^4-13*a*b*d^4-34*b^2*d^4-47*a*c*d^4+36*b*c*d^4+34*c^2*d^4+41*a*d^5+25*b*d^5-28*c*d^5-31*d^6+22*a^5*e+a^4*b*e+27*a^3*b^2*e+5*a^2*b^3*e-33*a*b^4*e+2*b^5*e+2 [...]
+a^2*b*c^3+6*a^4*d^2-4*a^3*b*d^2+37*a^2*b^2*d^2+18*a*b^3*d^2-34*b^4*d^2+23*a^3*c*d^2-9*a^2*b*c*d^2-46*a*b^2*c*d^2+19*b^3*c*d^2+42*a^2*c^2*d^2-34*a*b*c^2*d^2-14*b^2*c^2*d^2-10*a*c^3*d^2+13*b*c^3*d^2+14*c^4*d^2-38*a^3*d^3-13*a^2*b*d^3+47*a*b^2*d^3-9*b^3*d^3-a^2*c*d^3+33*a*b*c*d^3+9*b^2*c*d^3+33*a*c^2*d^3+37*b*c^2*d^3+41*c^3*d^3+12*a^2*d^4-50*a*b*d^4+11*b^2*d^4-48*a*c*d^4+27*b*c*d^4-48*c^2*d^4-48*a*d^5-19*b*d^5+46*c*d^5+5*d^6+43*a^5*e-13*a^4*b*e-16*a^3*b^2*e+34*a^2*b^3*e+25*a*b^4*e+29*b^5*e- [...]
+a^3*c^3-8*a^4*d^2+24*a^3*b*d^2-28*a^2*b^2*d^2+27*a*b^3*d^2-17*b^4*d^2-40*a^3*c*d^2+28*a^2*b*c*d^2+2*a*b^2*c*d^2-18*b^3*c*d^2+45*a^2*c^2*d^2-13*a*b*c^2*d^2-14*b^2*c^2*d^2+35*a*c^3*d^2-32*b*c^3*d^2+2*c^4*d^2-27*a^3*d^3-41*a^2*b*d^3-36*a*b^2*d^3-50*b^3*d^3+23*a^2*c*d^3+25*a*b*c*d^3+22*b^2*c*d^3+15*a*c^2*d^3-36*b*c^2*d^3-43*c^3*d^3-26*a^2*d^4-43*a*b*d^4-25*b^2*d^4-14*a*c*d^4+32*b*c*d^4+25*c^2*d^4+23*a*d^5-32*b*d^5+28*c*d^5-24*d^6+4*a^5*e-15*a^4*b*e-45*a^3*b^2*e-47*a^2*b^3*e+50*a*b^4*e+3*b^5* [...]
+b^4*c^2-14*a^4*d^2-37*a^3*b*d^2+19*a^2*b^2*d^2+4*a*b^3*d^2+20*b^4*d^2+34*a^3*c*d^2+17*a^2*b*c*d^2-35*a*b^2*c*d^2-21*b^3*c*d^2+32*a^2*c^2*d^2-31*a*b*c^2*d^2+18*b^2*c^2*d^2+6*a*c^3*d^2+21*b*c^3*d^2+24*c^4*d^2-4*a^3*d^3+41*a^2*b*d^3-14*a*b^2*d^3+38*b^3*d^3-26*a^2*c*d^3-48*a*b*c*d^3-39*b^2*c*d^3+a*c^2*d^3+50*b*c^2*d^3-13*c^3*d^3+21*a^2*d^4-17*a*b*d^4+47*b^2*d^4+16*a*c*d^4+12*b*c*d^4+30*c^2*d^4+11*a*d^5-5*b*d^5-42*c*d^5-15*d^6+15*a^5*e-15*a^4*b*e+36*a^3*b^2*e-21*a^2*b^3*e-9*a*b^4*e-34*b^5*e-4 [...]
+a*b^3*c^2-37*a^4*d^2-46*a^3*b*d^2+11*a^2*b^2*d^2+21*a*b^3*d^2+21*b^4*d^2-23*a^3*c*d^2-3*a^2*b*c*d^2+3*a*b^2*c*d^2-32*b^3*c*d^2-37*a^2*c^2*d^2-36*a*b*c^2*d^2+37*b^2*c^2*d^2-6*a*c^3*d^2-34*b*c^3*d^2+48*c^4*d^2+28*a^3*d^3+43*a^2*b*d^3+43*a*b^2*d^3+17*b^3*d^3+26*a^2*c*d^3+33*a*b*c*d^3-2*b^2*c*d^3-21*a*c^2*d^3-14*b*c^2*d^3-39*c^3*d^3-a^2*d^4-22*a*b*d^4-39*b^2*d^4-35*a*c*d^4+13*b*c*d^4-24*c^2*d^4-11*a*d^5+16*b*d^5+30*c*d^5-22*d^6-22*a^5*e+19*a^4*b*e-15*a^3*b^2*e-8*a^2*b^3*e+14*a*b^4*e-5*b^5*e+ [...]
+a^2*b^2*c^2+34*a^4*d^2+5*a^3*b*d^2-6*a^2*b^2*d^2-24*a*b^3*d^2+14*b^4*d^2+24*a^3*c*d^2-13*a^2*b*c*d^2+27*a*b^2*c*d^2+10*b^3*c*d^2-38*a^2*c^2*d^2+14*a*b*c^2*d^2+49*b^2*c^2*d^2+42*a*c^3*d^2-4*b*c^3*d^2+32*c^4*d^2+47*a^3*d^3+38*a^2*b*d^3+12*a*b^2*d^3-7*b^3*d^3+30*a^2*c*d^3+2*a*b*c*d^3+23*b^2*c*d^3-42*a*c^2*d^3+19*b*c^2*d^3-19*c^3*d^3-12*a^2*d^4+37*a*b*d^4+47*b^2*d^4+31*a*c*d^4+4*b*c*d^4-36*c^2*d^4-10*a*d^5-7*b*d^5+6*c*d^5-12*d^6-46*a^5*e-47*a^4*b*e+49*a^3*b^2*e+45*a^2*b^3*e+44*a*b^4*e+35*b^5 [...]
+a^3*b*c^2-30*a^4*d^2+28*a^3*b*d^2+41*a^2*b^2*d^2-11*a*b^3*d^2+27*b^4*d^2-36*a^3*c*d^2+27*a^2*b*c*d^2+50*a*b^2*c*d^2-34*b^3*c*d^2-21*a^2*c^2*d^2-6*a*b*c^2*d^2-8*b^2*c^2*d^2-14*a*c^3*d^2-35*b*c^3*d^2+21*c^4*d^2+37*a^3*d^3-14*a^2*b*d^3-41*a*b^2*d^3+30*b^3*d^3+35*a^2*c*d^3-28*a*b*c*d^3+26*b^2*c*d^3+19*a*c^2*d^3+b*c^2*d^3-5*c^3*d^3-29*a^2*d^4+25*a*b*d^4-38*b^2*d^4+50*a*c*d^4+10*b*c*d^4+30*c^2*d^4+31*a*d^5-49*b*d^5+39*c*d^5-40*d^6+16*a^5*e-47*a^4*b*e+39*a^3*b^2*e-41*a^2*b^3*e-27*a*b^4*e+10*b^5 [...]
+a^4*c^2-10*a^4*d^2+38*a^3*b*d^2-a^2*b^2*d^2+6*a*b^3*d^2+39*b^4*d^2-11*a^3*c*d^2+9*a^2*b*c*d^2+21*a*b^2*c*d^2-13*b^3*c*d^2+22*a^2*c^2*d^2+33*a*b*c^2*d^2-19*b^2*c^2*d^2-18*a*c^3*d^2-38*b*c^3*d^2-50*c^4*d^2-11*a^3*d^3-41*a^2*b*d^3-9*a*b^2*d^3-40*b^3*d^3-8*a^2*c*d^3+49*a*b*c*d^3+34*b^2*c*d^3+36*a*c^2*d^3-37*b*c^2*d^3+14*c^3*d^3-2*a^2*d^4+34*a*b*d^4+47*b^2*d^4+47*a*c*d^4-20*b*c*d^4-13*c^2*d^4+6*a*d^5-31*b*d^5+28*c*d^5-31*d^6-3*a^5*e+39*a^4*b*e+16*a^3*b^2*e+16*a^2*b^3*e+9*a*b^4*e+37*b^5*e-39*a [...]
+b^5*c+40*a^4*d^2-47*a^3*b*d^2+16*a^2*b^2*d^2+18*a*b^3*d^2+33*b^4*d^2+9*a^3*c*d^2-38*a^2*b*c*d^2-22*a*b^2*c*d^2+8*b^3*c*d^2-21*a^2*c^2*d^2-2*a*b*c^2*d^2+33*b^2*c^2*d^2+5*a*c^3*d^2-50*b*c^3*d^2-35*c^4*d^2+29*a^3*d^3+25*a^2*b*d^3-38*a*b^2*d^3+17*b^3*d^3-32*a^2*c*d^3-44*a*b*c*d^3-20*b^2*c*d^3-26*a*c^2*d^3-37*b*c^2*d^3+47*c^3*d^3+19*a^2*d^4-34*a*b*d^4-20*b^2*d^4+31*a*c*d^4-14*b*c*d^4-37*c^2*d^4-37*a*d^5+7*b*d^5-42*c*d^5+16*d^6-23*a^5*e-48*a^3*b^2*e-41*a^2*b^3*e+6*a*b^4*e+49*a^4*c*e+34*a^3*b*c [...]
+a*b^4*c+32*a^4*d^2+43*a^3*b*d^2+49*a^2*b^2*d^2+38*a*b^3*d^2+47*b^4*d^2+19*a^3*c*d^2+43*a^2*b*c*d^2-25*a*b^2*c*d^2+25*b^3*c*d^2+26*a^2*c^2*d^2-5*a*b*c^2*d^2-19*b^2*c^2*d^2+33*a*c^3*d^2-3*b*c^3*d^2-37*c^4*d^2+18*a^3*d^3-27*a^2*b*d^3-33*a*b^2*d^3-49*b^3*d^3+48*a^2*c*d^3-12*a*b*c*d^3+17*b^2*c*d^3+6*a*c^2*d^3-36*b*c^2*d^3+36*c^3*d^3+a^2*d^4-12*b^2*d^4-3*a*c*d^4-43*b*c*d^4-24*c^2*d^4-14*a*d^5-43*b*d^5-20*c*d^5+24*d^6-42*a^5*e-48*a^4*b*e+29*a^3*b^2*e-29*a^2*b^3*e-37*a*b^4*e+b^5*e-31*a^4*c*e+35* [...]
+a^2*b^3*c-22*a^4*d^2+38*a^3*b*d^2+10*a^2*b^2*d^2-31*a*b^3*d^2+42*b^4*d^2-7*a^3*c*d^2-47*a^2*b*c*d^2+37*a*b^2*c*d^2-23*b^3*c*d^2-43*a^2*c^2*d^2+38*a*b*c^2*d^2+18*b^2*c^2*d^2+18*a*c^3*d^2+25*b*c^3*d^2+4*c^4*d^2+36*a^3*d^3-21*a^2*b*d^3+35*a*b^2*d^3+28*b^3*d^3+13*a^2*c*d^3+36*a*b*c*d^3-33*b^2*c*d^3+9*a*c^2*d^3+18*b*c^2*d^3-49*c^3*d^3-5*a^2*d^4-8*a*b*d^4-34*b^2*d^4-43*a*c*d^4-47*b*c*d^4-12*c^2*d^4+34*a*d^5+50*b*d^5-13*c*d^5-20*d^6+29*a^5*e-10*a^4*b*e+17*a^3*b^2*e+7*a^2*b^3*e+45*a*b^4*e-23*b^5 [...]
+a^3*b^2*c-24*a^4*d^2+20*a^3*b*d^2+24*a^2*b^2*d^2-29*a*b^3*d^2-24*b^4*d^2+13*a^3*c*d^2+31*a*b^2*c*d^2-26*b^3*c*d^2-29*a^2*c^2*d^2-27*a*b*c^2*d^2+4*b^2*c^2*d^2+23*a*c^3*d^2+42*b*c^3*d^2-47*c^4*d^2+50*a^3*d^3+48*a^2*b*d^3-22*a*b^2*d^3+16*b^3*d^3-46*a^2*c*d^3-43*a*b*c*d^3+50*b^2*c*d^3-35*a*c^2*d^3-29*b*c^2*d^3-12*c^3*d^3+23*a^2*d^4+31*a*b*d^4+22*b^2*d^4-27*a*c*d^4-25*b*c*d^4-41*c^2*d^4+42*a*d^5-50*b*d^5+33*c*d^5+11*d^6+19*a^5*e-22*a^4*b*e+33*a^3*b^2*e+43*a^2*b^3*e+43*a*b^4*e-5*b^5*e-14*a^4*c [...]
+a^4*b*c-38*a^4*d^2+23*a^3*b*d^2-28*a^2*b^2*d^2-49*a*b^3*d^2-37*b^4*d^2+46*a^3*c*d^2-39*a^2*b*c*d^2+31*a*b^2*c*d^2+43*b^3*c*d^2+40*a^2*c^2*d^2-30*a*b*c^2*d^2-7*b^2*c^2*d^2+32*a*c^3*d^2+50*b*c^3*d^2+13*c^4*d^2-9*a^3*d^3+23*a^2*b*d^3-12*a*b^2*d^3-42*b^3*d^3+4*a^2*c*d^3-3*a*b*c*d^3+50*b^2*c*d^3+16*a*c^2*d^3+40*b*c^2*d^3-23*c^3*d^3+39*a^2*d^4+35*a*b*d^4-45*b^2*d^4+45*a*c*d^4-15*b*c*d^4-26*c^2*d^4+29*a*d^5+37*b*d^5+3*c*d^5-22*d^6-8*a^5*e+15*a^4*b*e+19*a^3*b^2*e-12*a^2*b^3*e+22*a*b^4*e-48*b^5*e [...]
+a^5*c-2*a^4*d^2-22*a^3*b*d^2-38*a^2*b^2*d^2+10*a*b^3*d^2+32*b^4*d^2-28*a^3*c*d^2+11*a^2*b*c*d^2-12*a*b^2*c*d^2-39*b^3*c*d^2+43*a^2*c^2*d^2+39*a*b*c^2*d^2-24*b^2*c^2*d^2+27*a*c^3*d^2+47*b*c^3*d^2+9*c^4*d^2+12*a^3*d^3+34*a^2*b*d^3-37*a*b^2*d^3+18*b^3*d^3+45*a^2*c*d^3+21*a*b*c*d^3+29*b^2*c*d^3+31*a*c^2*d^3+23*b*c^2*d^3+44*c^3*d^3-19*a^2*d^4+32*a*b*d^4+46*b^2*d^4+27*a*c*d^4+8*b*c*d^4-20*c^2*d^4-35*a*d^5-21*b*d^5+15*c*d^5-45*d^6-38*a^5*e-35*a^4*b*e-28*a^3*b^2*e-30*a^2*b^3*e-19*a*b^4*e-49*b^5* [...]
+b^6-11*a^4*d^2+23*a^3*b*d^2+41*a^2*b^2*d^2+7*a*b^3*d^2+10*b^4*d^2-31*a^3*c*d^2+10*a^2*b*c*d^2+7*a*b^2*c*d^2+36*b^3*c*d^2-10*a^2*c^2*d^2+9*a*b*c^2*d^2-41*b^2*c^2*d^2-26*a*c^3*d^2+26*b*c^3*d^2+12*c^4*d^2+36*a^3*d^3-35*a^2*b*d^3+12*a*b^2*d^3-8*b^3*d^3+23*a^2*c*d^3+16*a*b*c*d^3-24*b^2*c*d^3+17*a*c^2*d^3-29*b*c^2*d^3-48*c^3*d^3+33*a^2*d^4+30*a*b*d^4-41*b^2*d^4-23*a*c*d^4+8*b*c*d^4-10*c^2*d^4+22*a*d^5+5*b*d^5-32*c*d^5+19*d^6+19*a^5*e+21*a^4*b*e-29*a^3*b^2*e+10*a^2*b^3*e-6*a*b^4*e-10*b^5*e-35*a [...]
+a*b^5+6*a^4*d^2-30*a^3*b*d^2+48*a^2*b^2*d^2+22*a*b^3*d^2+49*b^4*d^2-4*a^3*c*d^2+45*a^2*b*c*d^2-28*a*b^2*c*d^2-12*b^3*c*d^2+12*a^2*c^2*d^2+47*a*b*c^2*d^2-14*b^2*c^2*d^2+35*a*c^3*d^2-b*c^3*d^2-39*c^4*d^2-40*a^3*d^3+7*a^2*b*d^3+16*a*b^2*d^3+45*b^3*d^3-a^2*c*d^3+20*a*b*c*d^3-9*b^2*c*d^3-31*a*c^2*d^3-44*b*c^2*d^3-13*c^3*d^3+36*a^2*d^4+8*a*b*d^4+25*b^2*d^4-4*a*c*d^4-10*b*c*d^4-40*c^2*d^4+39*a*d^5-4*b*d^5-24*c*d^5-11*d^6+33*a^5*e+40*a^4*b*e+21*a^3*b^2*e-7*a^2*b^3*e-22*a*b^4*e-48*b^5*e-2*a^4*c*e [...]
+a^2*b^4-27*a^4*d^2-11*a^3*b*d^2+23*a^2*b^2*d^2+42*a*b^3*d^2+33*b^4*d^2-45*a^2*b*c*d^2+42*a*b^2*c*d^2+30*b^3*c*d^2-a^2*c^2*d^2+41*a*b*c^2*d^2+32*b^2*c^2*d^2-4*a*c^3*d^2-4*b*c^3*d^2+50*c^4*d^2+14*a^3*d^3-17*a^2*b*d^3+20*a*b^2*d^3-31*b^3*d^3+44*a^2*c*d^3+14*a*b*c*d^3+43*b^2*c*d^3+48*a*c^2*d^3-10*b*c^2*d^3-3*c^3*d^3-33*a^2*d^4+9*a*b*d^4+28*b^2*d^4-3*a*c*d^4+15*b*c*d^4+46*c^2*d^4-35*a*d^5-42*b*d^5+44*c*d^5-4*d^6+28*a^5*e+46*a^4*b*e+16*a^3*b^2*e+31*a^2*b^3*e-20*a*b^4*e-15*b^5*e-50*a^4*c*e-8*a^ [...]
+a^3*b^3-15*a^4*d^2-17*a^3*b*d^2-a^2*b^2*d^2+18*a*b^3*d^2-30*b^4*d^2-37*a^3*c*d^2+21*a^2*b*c*d^2-a*b^2*c*d^2+16*b^3*c*d^2-41*a^2*c^2*d^2+39*a*b*c^2*d^2-16*b^2*c^2*d^2-22*a*c^3*d^2+19*b*c^3*d^2+46*c^4*d^2-14*a^3*d^3+2*a^2*b*d^3+45*a*b^2*d^3+12*b^3*d^3-28*a^2*c*d^3-19*a*b*c*d^3-20*b^2*c*d^3-6*a*c^2*d^3+17*b*c^2*d^3-20*c^3*d^3+34*a^2*d^4+15*a*b*d^4-8*b^2*d^4+31*a*c*d^4-5*b*c*d^4+41*c^2*d^4-32*a*d^5-38*b*d^5+35*c*d^5-4*d^6-26*a^5*e-20*a^4*b*e-12*a^3*b^2*e+22*a^2*b^3*e-48*a*b^4*e+39*b^5*e-46*a [...]
+a^4*b^2-31*a^4*d^2+30*a^3*b*d^2-42*a^2*b^2*d^2-32*a*b^3*d^2-38*b^4*d^2-49*a^3*c*d^2-4*a^2*b*c*d^2-45*a*b^2*c*d^2+8*b^3*c*d^2+44*a^2*c^2*d^2+21*a*b*c^2*d^2-13*b^2*c^2*d^2-16*a*c^3*d^2+31*b*c^3*d^2-42*c^4*d^2+49*a^3*d^3+44*a^2*b*d^3+a*b^2*d^3+47*b^3*d^3-31*a^2*c*d^3+42*a*b*c*d^3-34*b^2*c*d^3-44*a*c^2*d^3-3*b*c^2*d^3-14*c^3*d^3+24*a^2*d^4+12*a*b*d^4+14*b^2*d^4-32*a*c*d^4+16*b*c*d^4+40*c^2*d^4+8*a*d^5+5*b*d^5+35*c*d^5+2*d^6+7*a^5*e+a^4*b*e-24*a^3*b^2*e-25*a^2*b^3*e-8*a*b^4*e-46*b^5*e+12*a^4* [...]
+a^5*b-48*a^4*d^2-33*a^3*b*d^2-34*a^2*b^2*d^2-14*a*b^3*d^2-29*b^4*d^2-7*a^3*c*d^2-13*a^2*b*c*d^2+15*a*b^2*c*d^2+27*b^3*c*d^2+49*a^2*c^2*d^2-a*b*c^2*d^2+46*b^2*c^2*d^2+37*a*c^3*d^2+20*b*c^3*d^2-27*c^4*d^2+33*a^3*d^3+30*a^2*b*d^3+32*a*b^2*d^3+b^3*d^3-47*a^2*c*d^3-2*a*b*c*d^3-36*b^2*c*d^3-7*a*c^2*d^3-23*b*c^2*d^3-41*c^3*d^3-43*a^2*d^4-4*a*b*d^4+14*b^2*d^4+38*a*c*d^4+41*b*c*d^4+27*c^2*d^4-33*a*d^5-50*b*d^5+8*c*d^5+42*d^6-21*a^5*e+46*a^4*b*e+6*a^3*b^2*e+22*a^2*b^3*e+2*a*b^4*e-15*b^5*e+50*a^4*c [...]
+a^6-2*a^4*d^2+3*a^3*b*d^2+18*a^2*b^2*d^2-46*a*b^3*d^2-31*b^4*d^2+48*a^3*c*d^2+7*a^2*b*c*d^2+26*a*b^2*c*d^2+17*b^3*c*d^2-30*a^2*c^2*d^2-2*a*b*c^2*d^2+5*b^2*c^2*d^2-43*a*c^3*d^2-33*b*c^3*d^2-28*c^4*d^2-26*a^3*d^3-5*a^2*b*d^3+48*a*b^2*d^3+2*b^3*d^3-15*a^2*c*d^3-18*a*b*c*d^3-16*b^2*c*d^3-12*a*c^2*d^3+21*b*c^2*d^3-31*c^3*d^3+34*a^2*d^4-40*a*b*d^4+41*b^2*d^4+21*a*c*d^4+26*b*c*d^4+50*c^2*d^4-20*a*d^5+8*b*d^5+30*c*d^5+48*d^6-37*a^5*e+28*a^4*b*e+8*a^3*b^2*e+30*a^2*b^3*e-a*b^4*e-49*b^5*e-8*a^4*c*e [...]
+e^7, d*e^6, c*e^6, b*e^6, a*e^6, d^2*e^5, c*d*e^5, b*d*e^5, a*d*e^5, c^2*e^5,
+b*c*e^5, a*c*e^5, b^2*e^5, a*b*e^5, a^2*e^5, d^3*e^4, c*d^2*e^4, b*d^2*e^4,
+a*d^2*e^4, c^2*d*e^4, b*c*d*e^4, a*c*d*e^4, b^2*d*e^4, a*b*d*e^4, a^2*d*e^4,
+c^3*e^4, b*c^2*e^4, a*c^2*e^4, b^2*c*e^4, a*b*c*e^4, a^2*c*e^4, b^3*e^4,
+a*b^2*e^4, a^2*b*e^4, a^3*e^4, d^4*e^3, c*d^3*e^3, b*d^3*e^3, a*d^3*e^3,
+c^2*d^2*e^3, b*c*d^2*e^3, a*c*d^2*e^3, b^2*d^2*e^3, a*b*d^2*e^3, a^2*d^2*e^3,
+c^3*d*e^3, b*c^2*d*e^3, a*c^2*d*e^3, b^2*c*d*e^3, a*b*c*d*e^3, a^2*c*d*e^3,
+b^3*d*e^3, a*b^2*d*e^3, a^2*b*d*e^3, a^3*d*e^3, c^4*e^3, b*c^3*e^3, a*c^3*e^3,
+b^2*c^2*e^3, a*b*c^2*e^3, a^2*c^2*e^3, b^3*c*e^3, a*b^2*c*e^3, a^2*b*c*e^3,
+a^3*c*e^3, b^4*e^3, a*b^3*e^3, a^2*b^2*e^3, a^3*b*e^3, a^4*e^3, d^5*e^2,
+c*d^4*e^2, b*d^4*e^2, a*d^4*e^2, c^2*d^3*e^2, b*c*d^3*e^2, a*c*d^3*e^2,
+b^2*d^3*e^2, a*b*d^3*e^2, a^2*d^3*e^2, c^3*d^2*e^2, b*c^2*d^2*e^2,
+a*c^2*d^2*e^2, b^2*c*d^2*e^2, a*b*c*d^2*e^2;
+//  M;
+  TestSSresAttribs2tr(M, "AGR101n4d008s020%1_big");
+/*
+options:  1 1 0 :  Time:  29/32/73/92 (316 without LCM)
+options:  1 1 1 :  Time:  32/34/43/202
+lres  Time:  24
+nres  Time:  19
+sres  Time:  71
+*/
+  kill M;
+
+  kill AGR;
+
+  ring AGR = (101), (a,b,c,d,e,f), dp; AGR;
+
+  // AGR at 101n5d005s016%1, new, medium difficulty?
+  ideal M =
+b*d-13*c*d+7*a*e-32*b*e+31*c*e+3*d*e+46*a*f-13*b*f+22*c*f-19*d*f-33*e*f, a*d+2*c*d-42*a*e+46*b*e+7*c*e-38*d*e+31*a*f+9*b*f+27*c*f-19*d*f-24*e*f, b*c-35*c*d-34*a*e+4*b*e+33*c*e+23*d*e+4*a*f-43*b*f+43*c*f+17*d*f-13*e*f, a*c+49*c*d-28*a*e+18*b*e-23*c*e+3*d*e-5*a*f-23*b*f+2*c*f+46*d*f-40*e*f, a*b-38*c*d+a*e-49*b*e-20*c*e+32*d*e+13*a*f+25*b*f+37*c*f-27*d*f+25*e*f, f^4, e*f^3, d*f^3, c*f^3, b*f^3, a*f^3, e^2*f^2, d*e*f^2, c*e*f^2, b*e*f^2, a*e*f^2, d^2*f^2, c*d*f^2, c^2*f^2, b^2*f^2, a^2*f^2,  [...]
+  TestSSresAttribs(M, "AGR at 101n5d005s016%1");
+  kill M;
+}
+
+static proc testAGRhard(list #)
+{
+  def DEBUG = 0;
+  if(size(#) > 0) { DEBUG = #[1]; }
+
+  system("--min-time", "0.01");
+  system("--ticks-per-sec", 100);
+
+  attrib(SSinit, "DEBUG", 0);
+  attrib(SSinit, "SYZCHECK", (DEBUG > 0));
+  attrib(SSinit, "KERCHECK", 0);
+  attrib(SSinit, "TREEOUTPUT", 0);
+  attrib(SSinit, "PROFILE", 0);
+
+  option(prot);
+  // AGR at 101n5d006s016%1, new, hard
+  ring AGR = (101), (a,b,c,d,e,f), dp; AGR;
+  ideal M =
+b*d+47*c*d-27*a*e+37*b*e+21*c*e+31*d*e-31*a*f+23*b*f+47*c*f+42*d*f+11*e*f, a*d+7*c*d+19*a*e+28*b*e-33*c*e-28*d*e+15*a*f+28*b*f+47*c*f+3*d*f+14*e*f, b*c+29*c*d-25*a*e+12*b*e+23*c*e-50*d*e-17*a*f+30*b*f-37*c*f+35*d*f-e*f, a*c+46*c*d+12*a*e+27*b*e+39*c*e+23*d*e-45*a*f+39*b*f-35*c*f+4*d*f-10*e*f, a*b+38*c*d-18*a*e-34*b*e-30*c*e+38*d*e+22*a*f+34*b*f+39*c*f+30*d*f-19*e*f, f^5, e*f^4, d*f^4, c*f^4, b*f^4, a*f^4, e^2*f^3, d*e*f^3, c*e*f^3, b*e*f^3, a*e*f^3, d^2*f^3, c*d*f^3, c^2*f^3, b^2*f^3, a^ [...]
+  TestSSresAttribs2tr(M, "AGR at 101n5d006s016%1_hard");
+ kill M;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////
+// . view graded module/map
+// . reorder graded resolution
+// . transpose graded module/map?
+
+// draw helpers
+static proc repeat(int n, string c) { string r = ""; while( n > 0 ){ r = r + c; n--; } return(r); }
+static proc pad(int m, string s, string c){ string r = s; while( size(r) < m ){ r = c + r; } return(r); }
+static proc mstring( int m, string c){ if( m < 0 ) { return (c); }; return (string(m)); }
+// view helper
+static proc draw ( intmat D, int d )
+{
+//  print(D); return ();
+  int nc = ncols(D); int nr = nrows(D);
+  int s, r, c; int max = 0; 
+  // get maximum string-length among all {D[r,c]}
+  for (r = nr; r > 0; r-- ) { for (c = nc; c > 0; c-- ) { s = size( string(D[r, c]) ); if( max < s ) { max = s; } } }
+  max = max + 1;   
+  string head = ""; string foot = ""; string middle = ""; 
+  for ( c = d+1; c < (nc-d); c++ )
+  {
+    head = head + pad(max, string(D[1 , c]), " ") + " ";
+    foot = foot + pad(max, string(D[nr, c]), " ") + " ";
+  }
+  // last head/foot enties:
+  head = head + pad(max, string(D[1 , nc-d]), " ");
+  foot = foot + pad(max, string(D[nr, nc-d]), " ");
+  // head/foot dash lines:
+  string dash  = repeat( (max + 1) * (nc - 2*d) , "-");
+  string dash2 = repeat( (max + 1) * (nc - 2*d) , "=");
+  for ( r = d+1; r <= (nr-d); r++ )
+  {
+    middle = middle + pad(max, string(D[r,1]), " ") + " :"; 
+    for ( c = d+1; c < (nc-d); c++ ) { middle = middle + pad(max, mstring(D[r,c], "."), " ") + " "; }
+    middle = middle + pad(max, mstring(D[r,nc-d], "."), " ") + " |" + pad(max, string(D[r,nc]), " ") + newline;
+  }
+  string corner = repeat(max, " ");
+  // print everything all at once:
+  print                                     (
+      corner + "  " + head  + "  " + corner + newline +
+      corner + "  " + dash  +  " " + corner + newline +
+                      middle                          +
+      corner + "  " + dash2 +  " " + corner + newline +
+      corner + "  " + foot  + "  " + corner );
+}
+
+proc view(def N)
+"
+PURPOSE: print the degree/grading data about the GRADED matrix/module/ideal N
+"
+{
+  if( size(N) == 0 ) { return (); }
+  
+  if( typeof( N ) == "list" )
+  {
+    int i; for( i = 1; i <= size(N); i++ ){ if(size(N[i])==0){break;}; "i:", i; view(N[i]); };
+    return ();
+  }
+
+//  typeof( N ) ;  attrib( N );  attrib(N, "isHomog");
+  
+  ASSUME(0, /* input must be graded! */ typeof(attrib(N, "isHomog")) == "intvec" );
+
+  // input should be graded:
+  intvec gr = attrib(N, "isHomog"); // grading weights?
+  ASSUME(0, /* input must be correctly graded! */ nrows(N) == size(gr) );   
+  
+//  intvec gr = attrib( N, "isHomog" ); //  module(N); "grading: ", gr;
+  
+  matrix M = module(N);
+  int nc = ncols(M); int nr = nrows(M);
+  int r,c;  
+  int d = 1; // number of extra cols/rows for extra info around the central degree(N) block in D
+  intmat D[nr+2*d][nc+2*d];
+  
+  module L = module(N); L = lead(L); vector v;
+  int m = 1 + nvars(basering); 
+  for( c = nc; c > 0; c-- )
+  {
+    D[1, c+d] = c; // top row indeces
+    v = L[c];
+    D[nr+2*d, c+d] = deg(v) + gr[ leadexp(v)[m] ]; // bottom row with computed column induced degrees
+  }
+  
+  for( r = nr; r > 0; r-- )
+  {
+    D[r+d, 1] = gr[r]; // left-most column with grading data
+    for( c = nc; c > 0; c-- )
+    {
+      D[r+d, c+d] = deg(M[r, c]); // central block with degrees
+//      if( D[r+d, c+d] < 0 ) { D[r+d, c+d] = 0; }
+    }
+    D[r+d, nc+2*d] = r; // right-most block with indeces
+  }
+  draw(D, d); // print it nicely!
+}
+
+
+static proc issorted( intvec g, int s )
+{
+  int i = size(g);
+
+  for(; i > 1; i--)
+  {
+    if( s*(g[i] - g[i-1]) < 0 )
+    {
+      return (0);
+    }
+  }
+  
+  return (1);
+}
+
+static proc mysort( intvec gr, int s )
+" get the sortiong permutation p for gr, such that s*gr[p] is ascending sorted
+  NOTE: looks like a bubble sort (was taken from sort) and modified to ensure stability!
+"
+{
+  int m = size(gr);
+
+  intvec pivot; 
+
+  int Bi;
+  // compute reordering permutation pivot such that gr[pivot] is (stably) sorted
+  for(Bi=m; Bi>0; Bi--) { pivot[Bi]=Bi; } // pivot = Id_m for starters
+
+  int Bn,Bb; int P, D;
+
+  int Bj = 0; int flag = 0;
+
+  // Bi == 0
+  while(Bj==0)
+  {
+    Bi++; Bj=1;
+    for(Bn=1; Bn <= (m-Bi); Bn++)
+    {
+      D = s*(gr[pivot[Bn]] - gr[pivot[Bn+1]]); // sort gr 
+      P = (D > 0) or ( (D == 0) && ((pivot[Bn]-pivot[Bn+1]) > 0) ); // stability!?
+      if(P)
+      {
+        Bb=pivot[Bn];
+        pivot[Bn]=pivot[Bn+1];
+        pivot[Bn+1]=Bb;
+
+        Bj=0; flag = 1;
+      }
+    }
+  }
+
+  ASSUME(1, issorted(gr, s));
+
+  if( flag && 0 ) // output details in case of non-identical permutation?
+  {
+    // grades & ordering permutation : gr[pivot] should be sorted:
+    "";
+    "pivot: ",    pivot;
+    "";
+  }
+
+  return (pivot);
+}
+
+static proc grdeg( def M, list # )
+"graded degrees of gens(i.e. columns)"
+
+{
+ // use initial grading if given
+  if( size(#) == 1 )
+  {
+    def w = #[1];
+    if( typeof(w) == "intvec" )
+    {
+      if( nrows(M) == size(w) )
+      {
+        attrib(M, "isHomog", w);
+      }
+    }
+    kill w;
+  }
+
+  // try to homogenize otherwise 
+  if( typeof(attrib( M, "isHomog")) != "intvec" )
+  { // no such attribute? //   ERROR("No grading!");
+    ASSUME(0, /* input must be graded: cannot compute homogenizing grading */ homog(M) ); 
+  }
+
+  
+  ASSUME(0, /* input must be graded! */ typeof(attrib(M, "isHomog")) == "intvec" );
+  // input should be graded:
+  def w = attrib(M, "isHomog"); // grading weights?
+  ASSUME(0, /* input must be correctly graded! */ nrows(M) == size(w) );   
+  
+  int m = ncols(M); // m > 0 in Singular!
+  int n = nvars(basering) + 1; // index of mod. column in the leadexp 
+
+  module L = lead(M[1..m]); // leading module-terms for input column vectors
+  intvec d = deg(L[1..m]); // their degrees
+  intvec c = leadexp(L[1..m])[n]; // their module-components
+  intvec gr = w[c]; // weights
+  
+  gr = gr + d; // finally we compute their graded degrees
+
+  return (gr); // do we need g or w[c] ?
+}
+
+
+static proc order( def M, int s, list #)
+"helper for reorder: compute graded degrees and the permutation to sort them"
+{
+  if( size(#) > 0 ) { intvec gr = grdeg( M, #[1] ); }
+  else              { intvec gr = grdeg( M       ); }
+  
+  
+//  intvec d = deg(M[1..nocls(M)]); // no need to deal with un-weighted degrees??!
+
+  intvec pivot = mysort(gr, s);
+
+  ASSUME(1, issorted(gr[pivot], s));
+  
+  return (gr, pivot);
+}
+
+
+static proc reorder(def M, int s, list #)
+"
+helper for    Reorder gens of M 
+"
+{
+  // use initial grading if given
+  if( size(#) == 1 )
+  {
+    def w = #[1];
+    if( typeof(w) == "intvec" )
+    {
+      if( nrows(M) == size(w) )
+      {
+        attrib(M, "isHomog", w);
+      }
+    }
+    kill w;
+  }
+
+  // try to homogenize otherwise 
+  if( typeof(attrib( M, "isHomog")) != "intvec" )
+  { // no such attribute? //   ERROR("No grading!");
+    ASSUME(0, /* input must be graded: cannot compute homogenizing grading */ homog(M) ); 
+  }
+
+  ASSUME(0, /* input must be graded! */ typeof(attrib(M, "isHomog")) == "intvec" );
+  // input should be graded:
+  def w = attrib(M, "isHomog"); // grading weights?
+  ASSUME(0, /* input must be correctly graded! */ nrows(M) == size(w) );   
+ 
+
+  intvec d, p;
+
+  if( size(#) > 0 ) { (d, p) = order( M, s, #[1] ); }
+  else              { (d, p) = order( M, s       ); }  
+
+  // grades & ordering permutation for N.  d[p] should be sorted!
+
+  def N = module(M[p]);  // reorder the starting ideal/module
+
+  attrib( N, "isHomog", w ); // set the grading
+
+  d = d[p];
+
+//  "reorder: "; view(N);
+  
+  return (N, d);
+}
+
+// only for whole resolutions, please use grorder instead!
+proc ordres( list L, list # )
+"
+reorder a resolution given by the list (and optionnaly a grading for its 1st entry)
+"
+{  
+  int k = 1; // "k: ", k; 
+
+  // check 1st syzygy property?
+//  if( 0 != size( module( matrix(transpose(L[k+1]))*matrix(transpose(L[k-1+1])) ) ) ){L[k];"";L[k+1];module( matrix(transpose(L[k+1]))*matrix(transpose(L[k-1+1])) );ERROR( "Exactness test failed!!!!" );}
+
+
+  // TODO: rewrite with reorder
+  intvec d, p, pp;
+  module N = L[1];
+  (d, p) = order( N, 1, # ); // grades & ordering permutation for N.  d[p] should be sorted!
+  N = module(N[p]);  // reorder the starting ideal/module
+  attrib( N, "isHomog", w ); // set the grading
+  L[1] = N; // put it back into the list of modules
+
+// view(N);
+ kill w, N;
+ 
+ ///////////////////////////////////
+ k++; 
+ while( k <= size(L) )
+ {
+  // "k: ", k;
+  module N = L[k];
+  
+  if( size(N) == 0 ) { break; } // resolution should finish with 0 module?
+  
+  if( typeof(attrib( N, "isHomog")) != "intvec" )  
+  { 
+    attrib( N, "isHomog", d); // ERROR("Non-graded input!");
+  }
+  
+//  view(N);
+
+  intvec w = attrib( N, "isHomog");  
+  (d, pp) = order( N, w, 1 ); // grades & ordering permutation : d[p] should be sorted!
+
+  // reorder k-th syzygy (columns):
+  module T = module(N[pp]);
+  kill N;
+  module N = transpose(T); 
+  kill T;
+
+  // reorder k-th syzygy (rows):
+  module T = module(N[p]);
+  kill N;
+  module N = transpose(T);
+  kill T;
+
+  w = intvec(w[p]); attrib( N, "isHomog", w); // corresponding ordered grading
+
+  L[k] = N; //  view(N);
+
+  // check syz. property?
+//  if( 0 != size( module( matrix(transpose(N))*matrix(transpose(L[k-1])) ) ) ) { N; L[k-1];  module( matrix(transpose(N))*matrix(transpose(L[k-1])) ); ERROR( "Exactness test failed!!!!" );  } 
+  kill N, w;
+  p = pp;
+  k++;
+ }
+
+ return (list( L[1 .. (k-1)] ));
+}
+
+
+
+
+proc grtranspose(def M, list #)
+"
+transpose graded module/map or a chain complex?...
+"
+{ 
+  if( typeof( M ) == "list" )
+  {
+    if( size(M) == 0 ) { return (); }
+    
+    int j = size(M); 
+
+    int i = 1;
+
+    // TODO: extra grading argument??? 
+    while( i < j )
+    {
+     if( size(M[i]) == 0 ){ break; }
+     ASSUME(0, typeof(attrib(M[i], "isHomog")) == "intvec");
+     i++;
+    }
+    
+    if( size(M[i]) == 0 ) { i--; }
+   
+    j = i; i = 1;
+    
+    list L; 
+    while( j > 0 )
+    {
+//      view(M[i]);
+      L[j] = grtranspose(M[i]);
+      if( i > 1 )
+      {
+        ASSUME(2, size( module( matrix(L[j+1])*matrix(L[j]) ) ) == 0 );
+      };
+//      view(L[j]);
+      j--; i++;
+    };
+    return (L); // ?
+  }
+
+//////
+// "a";  view(M);
+
+  // TODO: something is wrong here:
+ 
+ intvec d; module N;  
+
+ if( size(#) > 0 ) { (N,d) = reorder(M, -1, #[1]); }
+ else              { (N,d) = reorder(M, -1); }
+
+ kill M; module M = transpose(N);
+ attrib( M, "isHomog", -d ); // set the grading
+
+// "b";  view(M);
+ 
+ kill N,d; module N; intvec d;
+ // reverse order:
+ (N,d) = reorder(M, 1); kill M;
+
+/*
+ module M = transpose(N); 
+ attrib( M, "isHomog", -d ); // set the grading
+
+// "c";  view(M);
+ 
+ kill N,d; module N; intvec d;
+ // reverse order:
+ (N,d) = reorder(M, -1); kill M;
+ module M = transpose(N); 
+ attrib( M, "isHomog", -d ); // set the grading
+
+// "d";  view(M);
+ 
+ kill N,d; module N; intvec d;
+ // reverse order:
+ (N,d) = reorder(M, 1);
+ 
+ kill M;
+*/
+
+// "e"; view( N );
+ 
+ ASSUME(1, issorted(attrib(N, "isHomog"), 1) );
+ ASSUME(1, issorted(grdeg(N), 1) );
+
+
+ return (N);
+}
+
+
+
+proc grorder(def M, list #)
+"
+reorder graded module/map or a chain complex?...
+"
+{  
+  if( typeof(M) == "list" )
+  { // TODO: extra grading argument??? 
+    if( size(M) == 0 ) { return (); }
+    
+    int j = size(M);  int i = 1;
+    
+    while( i < j )
+    {
+      if( size(M[i]) == 0 ){ break; }
+      ASSUME(0, typeof(attrib(M[i], "isHomog")) == "intvec");
+      i++;
+    }
+    
+    if( size(M[i]) == 0 ) { i--; }
+    
+    list L; module Z = 0; L[i] = Z; j = i;
+    
+    while( i > 0 )
+    {
+//      "i: ", i;      "A"; view(M[i]);
+      L[i] = grorder(M[i]); 
+//      "B"; view(L[i]);
+      if( i < j )
+      {
+        ASSUME(2, size( module( matrix(transpose(L[i+1]))*matrix(transpose(L[i])) ) ) == 0 );
+      };
+      
+      i--;
+    };
+
+    return (L); // ?
+  }
+
+// "a";  view(M);
+  
+  intvec d; module N;
+
+  if( size(#) > 0 ) { (N,d) = reorder(M, 1, #[1]); }
+  else              { (N,d) = reorder(M, 1); }  
+  kill M; module M = transpose(N);
+  attrib( M, "isHomog", -d ); // set the grading
+
+// "b";  view(M);
+ 
+  kill N,d; module N; intvec d;
+  // reverse order:
+  (N,d) = reorder(M, -1); kill M;
+ 
+  module M = transpose(N); 
+  attrib( M, "isHomog", -d ); // set the grading
+
+// "c";  view(M);
+
+  ASSUME(1, issorted(attrib(M, "isHomog"), 1) );
+  ASSUME(1, issorted(grdeg(M), 1) );
+  
+  return (M);
+}
+
+proc TestGRRes(string Name, int version, ideal I )
+"
+test/output reordering res(I) & gr-traspose of res 
+"
+{ 
+  "==============================================";
+  "";
+  "=== Example: [", Name, "]";
+  " = Ring: ", string(basering);
+
+  I = groebner(I); attrib(I, "isHomog", intvec(0));
+//  " = Input degrees: "; view(I);
+
+  " ! Resolution via 'mres': ";
+  def R = mres(I, 0); // sres, lres: no grading! // nres, mres - graded (with attrib(, "isHomog"))
+  
+  " = Non-minimal betti numbers: ";
+  print(betti(R, 0), "betti");
+
+  list L = R ; // SRES_list(R); //  " = Degrees of maps: "; view(L); // MUST BE GRADED!!!
+
+  " = Degrees of (ordered) maps: ";
+  def LL = grorder(L); // MUST BE GRADED
+  
+  // ordres(L, intvec(0)); // ?
+
+  view( LL ); " = TRANSPOSEed complex: %%%%%%%%%%%%%%";
+  list LLL = grtranspose( LL ); //  resolution RR = LLL;  
+  print(betti(LLL, 0), "betti");
+  
+  view( LLL ); ""; //  "==============================================";
+  
+  kill L, R;
+}
+example
+{ "EXAMPLE:"; echo = 2; int assumeLevel = 5;
+
+  string Name = "castelnuovo"; int @p=31991; ring R = (@p),(x,y,z,u,v), dp;ideal I = 5153xy2-98/23y3-101/51xyz+33/41y2z+99/79xz2+7136yz2-106/111z3+119/53xyu+34/57y2u-77/92xzu+84/73yzu-109/78z2u-27/56xu2+10023yu2+82/103zu2-34/25u3+3/2xyv-68/25y2v+12721xzv+4/63yzv-73/21z2v-7291xuv-91/53yuv-4/79zuv-34/91u2v-122/53xv2+123/70yv2-64/73zv2+44/65uv2+14/31v3,xy2-15202y3+10613xyz+13640y2z-107/103xz2+5292yz2+19/119z3-10042xyu+2770y2u+7957xzu+14008yzu+92/121z2u-92/51xu2+1178yu2+1/117zu2-12726u3+82/1 [...]
+  
+  string Name = "ell.d8.g7"; int @p=31991; ring R = (@p),(x,y,z,u,v), dp;ideal I = x2y2-47/69xy3+6059y4+78/85x2yz+55/124xy2z+13641y3z+8/17x2z2+7817xyz2-2746y2z2+85/124xz3+87yz3+13182z4+109/93x2yu-69/17xy2u+12089y3u+8769x2zu-53/36xyzu-14834y2zu+123/23xz2u+103/77yz2u-2344z3u-43/104x2u2-6198xyu2+47/115y2u2-39/19xzu2-29/24yzu2+51/89z2u2-65/37xu3-95/94yu3+11302zu3-53/57u4-2874x2yv+4347xy2v-25/77y3v+13819x2zv+29/34xyzv+474y2zv+33/107xz2v-3517yz2v+10617z3v+1834x2uv+54/113xyuv-8751y2uv+111/70xzu [...]
+  
+  string Name = "ell.d7.g6"; int @p=31991; ring R = (@p),(x,y,z,u,v), dp;ideal I = 4971xy3+3/101y4-12318xy2z-12835y3z+97/98xyz2+63y2z2-8056xz3+23/91yz3-9662z4-7398xy2u+69/71y3u-53/68xyzu-49/67y2zu-113/122xz2u-9/61yz2u+71/88z3u+11358xyu2-38/29y2u2-10232xzu2+14490yzu2+2274z2u2+3501xu3+10427yu3-109/38zu3-99/5u4-6605xy2v-1555y3v-648xyzv-2083y2zv-61/41xz2v+75/17yz2v-69/55z3v-6104xyuv-9582y2uv+69/2xzuv-12551yzuv+47/49z2uv-118/13xu2v+34/105yu2v+105/41zu2v+6533u3v+122/25xyv2+2/43y2v2+16/61xzv2+1 [...]
+  
+  string Name = "k3.d7.g5"; int @p=31991; ring R = (@p),(x,y,z,u,v), dp;ideal I = -97/108x2y-31/118xy2-73/61y3-79/14x2z-15930xyz-2324y2z+1842xz2+656yz2-8852z3-89/38x2u-102/43xyu+14719y2u+70/67xzu+7335yzu+27/56z2u-10744xu2-55/83yu2+120/73zu2+120/61u3-126/125x2v+691xyv-15385y2v+117/16xzv-17/97yzv+80/121z2v-48/119xuv+21/34yuv-103/65zuv-49/32u2v-41/42xv2+11/75yv2-502zv2-7583uv2+26/69v3,97/108x3+77/114x2y+71/21xy2+13679y3-1645x2z-1/33xyz-79/7y2z-52/53xz2+11940yz2-5800z3+109/13x2u-115/64xyu-12 [...]
+  
+  string Name = "rat.d8.g6"; int @p=31991; ring R = (@p),(x,y,z,u,v), dp;ideal I = -19/125x2y2-87/119xy3-97/21y4+36/53x2yz+2069xy2z-59/50y3z-65/33x2z2-14322xyz2+79/60y2z2-9035xz3-14890yz3+87/47z4-23/48x2yu+45/44xy2u+1972y3u+79/118x2zu-5173xyzu+115/121y2zu+1239xz2u-115/17yz2u-15900z3u-78/95x2u2+67/101xyu2-12757y2u2+12752xzu2+68/21yzu2+103/90z2u2-12917xu3+97/92yu3-24/49zu3-13/79u4-51/61x2yv-3103xy2v+77/117y3v+73/115x2zv-79/33xyzv+123/110y2zv+11969xz2v-31/95yz2v-123/95z3v-105/124x2uv+12624x [...]
+
+  string Name = "k3.d14.g19"; int @p=31991; ring R = (@p),(x,y,z,u,v), dp;ideal I = x4y2+52/25x3y3+73/79x2y4+33/83xy5-116/65y6+23/39x4yz-45/11x3y2z-45/16x2y3z+73/8xy4z+107/70y5z+115/8x4z2-4619x3yz2+13504x2y2z2+9/118xy3z2-113/64y4z2+10731x3z3-7/13x2yz3-26/17xy2z3+3/59y3z3-4602x2z4+71/44xyz4-66/43y2z4-37/70xz5-6988yz5-123/29z6-6158x4yu+9171x3y2u+71/122x2y3u-119/73xy4u-15409y5u+85/3x4zu+104/59x3yzu-3336x2y2zu-50/107xy3zu-10232y4zu-8965x3z2u-2736x2yz2u+4/61xy2z2u+49/92y3z2u+13261x2z3u+64/31x [...]
+
+  string Name = "k3.d11.g11.ss0"; int @p=31991; ring R = (@p),(x,y,z,u,v), dp;ideal I = 38/41x4y+116/67x3y2+6547x2y3-50/71xy4+13/89y5+63/22x4z-12151x3yz-3400x2y2z-52/45xy3z+9027y4z+5420x3z2+6983x2yz2-3285xy2z2-47/2y3z2-137x2z3+40/51xyz3+111/40y2z3-97/93xz4+918yz4-7492z5-122/49x4u-123/47x3yu-95/32x2y2u-83/36xy3u-125/77y4u-9824x3zu-51/115x2yzu-83/18xy2zu-19/20y3zu-117/98x2z2u+885xyz2u-20/97y2z2u+69/55xz3u-11/82yz3u+93/47z4u-97/113x3u2-83/48x2yu2+12868xy2u2-4932y3u2-97/114x2zu2-121/116xyzu2 [...]
+
+  string Name = "ell.d10.g9"; int @p=31991; ring R = (@p),(x,y,z,u,v), dp;ideal I = -44/83x3y2-51/22x2y3+104/11xy4+38/119y5+22/87x3yz-27/61x2y2z-49/121xy3z-60/43y4z+124/65x3z2+39/107x2yz2-10379xy2z2-86/125y3z2+33/8x2z3+3501xyz3+53/9y2z3-69/106xz4+441yz4-19/126z5+12584x3yu+21/104x2y2u+12937xy3u-113/108y4u+13758x3zu+4991x2yzu+5360xy2zu-11946y3zu-2442x2z2u-9336xyz2u+9027y2z2u-112/37xz3u+14035yz3u-8230z4u+58/83x3u2+9675x2yu2+29/114xy2u2+10729y3u2+11/23x2zu2+3609xyzu2+7065y2zu2-2477xz2u2+32/3 [...]
+  
+  string Name = "k3.d10.g9.quart2"; int @p=31991; ring R = (@p),(x,y,z,u,v), dp;ideal I = x3yz2+31/15x2y2z2-7231xy3z2+99/37y4z2+28/95x3z3+97/32x2yz3+13247xy2z3+12717y3z3-113/31x2z4-61/30xyz4-6844y2z4+104/3xz5-13849yz5+43/39z6+13061x3yzu-8463x2y2zu+94/69xy3zu-8/61y4zu-13297x3z2u+7217x2yz2u-7830xy2z2u-75/14y3z2u+2839x2z3u-14657xyz3u-52/7y2z3u-6/89xz4u-6169yz4u+44/7z5u-98/33x3yu2+41/30x2y2u2-65/98xy3u2+122/13y4u2+9906x3zu2-11587x2yzu2+17/53xy2zu2+6504y3zu2+49/106x2z2u2+11480xyz2u2+97/71y2z2 [...]
+
+  string Name = "rat.d10.g9.quart2"; int @p=31991; ring R = (@p),(x,y,z,u,v), dp;ideal I = x3yu2-48/11x2y2u2-8356xy3u2+35/121y4u2+31/66x3zu2-54/83x2yzu2-61/18xy2zu2+11526y3zu2+7372x2z2u2-91/60xyz2u2-95/97y2z2u2-45/71xz3u2+71/115yz3u2+25/54z4u2-61/102x3u3-12668x2yu3+6653xy2u3+41/54y3u3+87/50x2zu3-5004xyzu3+13924y2zu3+2310xz2u3-93/14yz2u3-2/93z3u3-97/125x2u4-58/11xyu4+46/73y2u4-4417xzu4+60/101yzu4+56/75z2u4-113/118xu5+115/4yu5-40zu5-8554u6-54/83x3yuv-9770x2y2uv-590xy3uv+15/49y4uv+94/69x3zu [...]
+}
+
diff --git a/Singular/LIB/schubert.lib b/Singular/LIB/schubert.lib
new file mode 100644
index 0000000..bb62755
--- /dev/null
+++ b/Singular/LIB/schubert.lib
@@ -0,0 +1,2561 @@
+////////////////////////////////////////////////////////////////////////////////
+version="version schubert.lib 4.0.0.0 Nov_2013 "; // $Id: 3716882c59cbc1ea84c159503bd3b822962311a4 $
+category="Algebraic Geometry";
+info="
+LIBRARY:    schubert.lib    Proceduces for Intersection Theory
+
+AUTHOR:     Hiep Dang,          email: hiep at mathematik.uni-kl.de
+
+OVERVIEW:
+
+    We implement new classes (variety, sheaf, stack, graph) and methods for
+    computing with them. An abstract variety is represented by a nonnegative
+    integer which is its dimension and a graded ring which is its Chow ring.
+    An abstract sheaf is represented by a variety and a polynomial which is its
+    Chern character. In particular, we implement the concrete varieties such as
+    projective spaces, Grassmannians, and projective bundles.
+
+    An important task of this library is related to the computation of
+    Gromov-Witten invariants. In particular, we implement new tools for the
+    computation in equivariant intersection theory. These tools are based on the
+    localization of moduli spaces of stable maps and Bott's formula. They are
+    useful for the computation of Gromov-Witten invariants. In order to do this,
+    we have to deal with moduli spaces of stable maps, which were introduced by
+    Kontsevich, and the graphs corresponding to the fixed point components of a
+    torus action on the moduli spaces of stable maps.
+
+    As an insightful example, the numbers of rational curves on general complete
+    intersection Calabi-Yau threefolds in projective spaces are computed up to
+    degree 6. The results are all in agreement with predictions made from mirror
+    symmetry computations.
+
+REFERENCES:
+
+    Hiep Dang,  Intersection theory with applications to the computation of
+                Gromov-Witten invariants, Ph.D thesis, TU Kaiserslautern, 2013.
+
+    Sheldon Katz and Stein A. Stromme, Schubert-A Maple package for intersection
+                theory and enumerative geometry, 1992.
+
+    Daniel R. Grayson, Michael E. Stillman, Stein A. Stromme, David Eisenbud and
+    Charley Crissman, Schubert2-A Macaulay2 package for computation in
+                intersection theory, 2010.
+
+    Maxim Kontsevich, Enumeration of rational curves via torus actions, 1995.
+
+PROCEDURES:
+    mod_init()                          create new objects in this library
+    makeVariety(int,ideal)              create a variety
+    printVariety(variety)               print procedure for a variety
+    productVariety(variety,variety)     make the product of two varieties
+    ChowRing(variety)                   create the Chow ring of a variety
+    Grassmannian(int,int)               create a Grassmannian as a variety
+    projectiveSpace(int)                create a projective space as a variety
+    projectiveBundle(sheaf)             create a projective bundle as a variety
+    integral(variety,poly)              degree of a 0-cycle on a variety
+    makeSheaf(variety,poly)             create a sheaf
+    printSheaf(sheaf)                   print procedure for sheaves
+    rankSheaf(sheaf)                    return the rank of a sheaf
+    totalChernClass(sheaf)              compute the total Chern class of a sheaf
+    ChernClass(sheaf,int)               compute the k-th Chern class of a sheaf
+    topChernClass(sheaf)                compute the top Chern class of a sheaf
+    totalSegreClass(sheaf)              compute the total Segre class of a sheaf
+    dualSheaf(sheaf)                    make the dual of a sheaf
+    tensorSheaf(sheaf,sheaf)            make the tensor of two sheaves
+    symmetricPowerSheaf(sheaf,int)      make the k-th symmetric power of a sheaf
+    quotSheaf(sheaf,sheaf)              make the quotient of two sheaves
+    addSheaf(sheaf,sheaf)               make the direct sum of two sheaves
+    makeGraph(list,list)                create a graph from a list of vertices
+                                        and a list of edges
+    printGraph(graph)                   print procedure for graphs
+    moduliSpace(variety,int)            create a moduli space of stable maps as
+                                        an algebraic stack
+    printStack(stack)                   print procedure for stacks
+    dimStack(stack)                     compute the dimension of a stack
+    fixedPoints(stack)                  compute the list of graphs corresponding
+                                        the fixed point components of a torus
+                                        action on the stack
+    contributionBundle(stack,graph)     compute the contribution bundle on a
+                                        stack at a graph
+    normalBundle(stack,graph)           compute the normal bundle on a stack at
+                                        a graph
+    multipleCover(int)                  compute the contribution of multiple
+                                        covers of a smooth rational curve as a
+                                        Gromov-Witten invariant
+    linesHypersurface(int)              compute the number of lines on a general
+                                        hypersurface
+    rationalCurve(int,list)             compute the Gromov-Witten invariant
+                                        corresponding the number of rational
+                                        curves on a general Calabi-Yau threefold
+    sumofquotients(stack,list)          prepare a command for parallel
+                                        computation
+    part(poly,int)                      compute a homogeneous component of a
+                                        polynomial.
+    parts(poly,int,int)                 compute the sum of homogeneous
+                                        components of a polynomial
+    logg(poly,int)                      compute Chern characters from total
+                                        Chern classes.
+    expp(poly,int)                      compute total Chern classes from Chern
+                                        characters
+    SchubertClass(list)                 compute the Schubert classes on a
+                                        Grassmannian
+    dualPartition(list)                 compute the dual of a partition
+
+KEYWORDS:       Intersection theory; Enumerative geometry; Schubert calculus;
+                Bott's formula; Gromov-Witten invariants.
+
+";
+
+////////////////////////////////////////////////////////////////////////////////
+
+LIB "general.lib";
+LIB "homolog.lib";
+LIB "parallel.lib";
+
+////////////////////////////////////////////////////////////////////////////////
+/////////// create new objects in this library  ////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+
+proc mod_init()
+"USAGE:     mod_init();
+THEORY:     This is to create new objects in this library such as variety,
+            sheaf, stack, and graph.
+KEYWORDS:   variety, sheaf, stack, graph
+EXAMPLE:    example mod_init(); shows an example
+"
+{
+    newstruct("variety","int dimension, ring baseRing, ideal relations");
+    newstruct("sheaf","variety currentVariety, poly ChernCharacter");
+    newstruct("graph","list vertices, list edges");
+    newstruct("stack","variety currentVariety, int degreeCurve");
+
+    system("install","variety","print",printVariety,1);
+    system("install","variety","*",productVariety,2);
+    system("install","sheaf","print",printSheaf,1);
+    system("install","sheaf","*",tensorSheaf,2);
+    system("install","sheaf","+",addSheaf,2);
+    system("install","sheaf","-",quotSheaf,2);
+    system("install","sheaf","^",symmetricPowerSheaf,2);
+    system("install","graph","print",printGraph,1);
+    system("install","stack","print",printStack,1);
+}
+example
+{
+    "EXAMPLE:"; echo=2;
+    mod_init();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//////// Procedures concerned with moduli spaces of stable maps ////////////////
+////////////////////////////////////////////////////////////////////////////////
+
+proc printStack(stack M)
+"USAGE:     printStack(M); M stack
+ASSUME:     M is a moduli space of stable maps.
+THEORY:     This is the print function used by Singular to print a stack.
+KEYWORDS:   stack, moduli space of stable maps
+EXAMPLE:    example printStack; shows an example
+"
+{
+    "A moduli space of dimension", dimStack(M);
+}
+example
+{
+    "EXAMPLE:"; echo=2;
+    ring r = 0,(x),dp;
+    variety P = projectiveSpace(4);
+    stack M = moduliSpace(P,2);
+    M;
+}
+
+proc moduliSpace(variety V, int d)
+"USAGE:     moduliSpace(V,d); V variety, d int
+ASSUME:     V is a projective space and d is a positive integer.
+THEORY:     This is the function used by Singular to create a moduli space of
+            stable maps from a genus zero curve to a projective space.
+KEYWORDS:   stack, moduli space of stable maps, rational curves
+EXAMPLE:    example moduliSpace; shows an example
+"
+{
+    stack M;
+    M.currentVariety = V;
+    M.degreeCurve = d;
+    return(M);
+}
+example
+{
+    "EXAMPLE:"; echo=2;
+    ring r = 0,(x),dp;
+    variety P = projectiveSpace(4);
+    stack M = moduliSpace(P,2);
+    M;
+}
+
+proc dimStack(stack M)
+"USAGE:     dimStack(M); M stack
+RETURN:     int
+INPUT:      M is a moduli space of stable maps.
+OUTPUT:     the dimension of moduli space of stable maps.
+KEYWORDS:   dimension, moduli space of stable maps, rational curves
+EXAMPLE:    example dimStack; shows an example
+"
+{
+    variety V = M.currentVariety;
+    int n = V.dimension;
+    int d = M.degreeCurve;
+    return (n*d+n+d-3);
+}
+example
+{
+    "EXAMPLE:"; echo=2;
+    ring r = 0,(x),dp;
+    variety P = projectiveSpace(4);
+    stack M = moduliSpace(P,2);
+    dimStack(M);
+}
+
+proc fixedPoints(stack M)
+"USAGE:     fixedPoints(M); M stack
+RETURN:     list
+INPUT:      M is a moduli space of stable maps.
+OUTPUT:     a list of graphs corresponding the fixed point components of a torus
+            action on a moduli space of stable maps.
+KEYWORDS:   fixed points, moduli space of stable maps, graph
+EXAMPLE:    example fixedPoints; shows an example
+"
+{
+    int i,j,k,h,m,n,p,q;
+    list l;
+    int d = M.degreeCurve;
+    variety V = M.currentVariety;
+    int r = V.dimension;
+    for (i=0;i<=r;i++)
+    {
+        for (j=0;j<=r;j++)
+        {
+            if (i <> j)
+            {
+                l[size(l)+1] = list(graph1(d,i,j),2*d);
+            }
+        }
+    }
+    if (d == 2)
+    {
+        for (i=0;i<=r;i++)
+        {
+            for (j=0;j<=r;j++)
+            {
+                for (k=0;k<=r;k++)
+                {
+                    if (i <> j and j <> k)
+                    {
+                        l[size(l)+1] = list(graph2(list(1,1),i,j,k),2);
+                    }
+                }
+            }
+        }
+    }
+    if (d == 3)
+    {
+        for (i=0;i<=r;i++)
+        {
+            for (j=0;j<=r;j++)
+            {
+                for (k=0;k<=r;k++)
+                {
+                    if (i <> j and j <> k)
+                    {
+                        l[size(l)+1] = list(graph2(list(2,1),i,j,k),2);
+                        for (h=0;h<=r;h++)
+                        {
+                            if (h <> k)
+                            {
+                                l[size(l)+1] = list(graph31(list(1,1,1),i,j,k,h),2);
+                            }
+                            if (h <> j)
+                            {
+                                l[size(l)+1] = list(graph32(list(1,1,1),i,j,k,h),6);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+    if (d == 4)
+    {
+        for (i=0;i<=r;i++)
+        {
+            for (j=0;j<=r;j++)
+            {
+                for (k=0;k<=r;k++)
+                {
+                    if (i <> j and j <> k)
+                    {
+                        l[size(l)+1] = list(graph2(list(3,1),i,j,k),3);
+                        l[size(l)+1] = list(graph2(list(2,2),i,j,k),8);
+                        for (h=0;h<=r;h++)
+                        {
+                            if (h <> k)
+                            {
+                                l[size(l)+1] = list(graph31(list(2,1,1),i,j,k,h),2);
+                                l[size(l)+1] = list(graph31(list(1,2,1),i,j,k,h),4);
+                            }
+                            if (h <> j)
+                            {
+                                l[size(l)+1] = list(graph32(list(2,1,1),i,j,k,h),4);
+                            }
+                            for (m=0;m<=r;m++)
+                            {
+                                if (k <> h and m <> h)
+                                {
+                                    l[size(l)+1] = list(graph41(list(1,1,1,1),i,j,k,h,m),2);
+                                }
+                                if (k <> h and m <> k)
+                                {
+                                    l[size(l)+1] = list(graph42(list(1,1,1,1),i,j,k,h,m),2);
+                                }
+                                if (h <> j and m <> j)
+                                {
+                                    l[size(l)+1] = list(graph43(list(1,1,1,1),i,j,k,h,m),24);
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+    if (d == 5)
+    {
+        for (i=0;i<=r;i++)
+        {
+            for (j=0;j<=r;j++)
+            {
+                for (k=0;k<=r;k++)
+                {
+                    if (i <> j and j <> k)
+                    {
+                        l[size(l)+1] = list(graph2(list(4,1),i,j,k),4);
+                        l[size(l)+1] = list(graph2(list(3,2),i,j,k),6);
+                        for (h=0;h<=r;h++)
+                        {
+                            if (k <> h)
+                            {
+                                l[size(l)+1] = list(graph31(list(3,1,1),i,j,k,h),3);
+                                l[size(l)+1] = list(graph31(list(1,3,1),i,j,k,h),6);
+                                l[size(l)+1] = list(graph31(list(2,2,1),i,j,k,h),4);
+                                l[size(l)+1] = list(graph31(list(2,1,2),i,j,k,h),8);
+                            }
+                            if (j <> h)
+                            {
+                                l[size(l)+1] = list(graph32(list(3,1,1),i,j,k,h),6);
+                                l[size(l)+1] = list(graph32(list(2,2,1),i,j,k,h),8);
+                            }
+                            for (m=0;m<=r;m++)
+                            {
+                                if (k <> h and h <> m)
+                                {
+                                    l[size(l)+1] = list(graph41(list(2,1,1,1),i,j,k,h,m),2);
+                                    l[size(l)+1] = list(graph41(list(1,2,1,1),i,j,k,h,m),2);
+                                }
+                                if (k <> h and k <> m)
+                                {
+                                    l[size(l)+1] = list(graph42(list(2,1,1,1),i,j,k,h,m),4);
+                                    l[size(l)+1] = list(graph42(list(1,2,1,1),i,j,k,h,m),4);
+                                    l[size(l)+1] = list(graph42(list(1,1,2,1),i,j,k,h,m),2);
+                                }
+                                if (j <> h and j <> m)
+                                {
+                                    l[size(l)+1] = list(graph43(list(2,1,1,1),i,j,k,h,m),12);
+                                }
+                                for (n=0;n<=r;n++)
+                                {
+                                    if (k <> h and h <> m and m <> n)
+                                    {
+                                        l[size(l)+1] = list(graph51(list(1,1,1,1,1),i,j,k,h,m,n),2);
+                                    }
+                                    if (k <> h and h <> m and h <> n)
+                                    {
+                                        l[size(l)+1] = list(graph52(list(1,1,1,1,1),i,j,k,h,m,n),2);
+                                    }
+                                    if (k <> h and k <> m and k <> n)
+                                    {
+                                        l[size(l)+1] = list(graph53(list(1,1,1,1,1),i,j,k,h,m,n),6);
+                                    }
+                                    if (j <> h and h <> m and h <> n)
+                                    {
+                                        l[size(l)+1] = list(graph54(list(1,1,1,1,1),i,j,k,h,m,n),8);
+                                    }
+                                    if (k <> h and k <> m and h <> n)
+                                    {
+                                        l[size(l)+1] = list(graph55(list(1,1,1,1,1),i,j,k,h,m,n),2);
+                                    }
+                                    if (j <> h and j <> m and j <> n)
+                                    {
+                                        l[size(l)+1] = list(graph56(list(1,1,1,1,1),i,j,k,h,m,n),120);
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+    if (d == 6)
+    {
+        for (i=0;i<=r;i++)
+        {
+            for (j=0;j<=r;j++)
+            {
+                for (k=0;k<=r;k++)
+                {
+                    if (i <> j and j <> k)
+                    {
+                        l[size(l)+1] = list(graph2(list(5,1),i,j,k),5);
+                        l[size(l)+1] = list(graph2(list(4,2),i,j,k),8);
+                        l[size(l)+1] = list(graph2(list(3,3),i,j,k),18);
+                        for (h=0;h<=r;h++)
+                        {
+                            if (k <> h)
+                            {
+                                l[size(l)+1] = list(graph31(list(4,1,1),i,j,k,h),4);
+                                l[size(l)+1] = list(graph31(list(1,4,1),i,j,k,h),8);
+                                l[size(l)+1] = list(graph31(list(3,2,1),i,j,k,h),6);
+                                l[size(l)+1] = list(graph31(list(3,1,2),i,j,k,h),6);
+                                l[size(l)+1] = list(graph31(list(1,3,2),i,j,k,h),6);
+                                l[size(l)+1] = list(graph31(list(2,2,2),i,j,k,h),16);
+                            }
+                            if (j <> h)
+                            {
+                                l[size(l)+1] = list(graph32(list(4,1,1),i,j,k,h),8);
+                                l[size(l)+1] = list(graph32(list(3,2,1),i,j,k,h),6);
+                                l[size(l)+1] = list(graph32(list(2,2,2),i,j,k,h),48);
+                            }
+                            for (m=0;m<=r;m++)
+                            {
+                                if (k <> h and h <> m)
+                                {
+                                    l[size(l)+1] = list(graph41(list(3,1,1,1),i,j,k,h,m),3);
+                                    l[size(l)+1] = list(graph41(list(1,3,1,1),i,j,k,h,m),3);
+                                    l[size(l)+1] = list(graph41(list(2,2,1,1),i,j,k,h,m),4);
+                                    l[size(l)+1] = list(graph41(list(2,1,2,1),i,j,k,h,m),4);
+                                    l[size(l)+1] = list(graph41(list(2,1,1,2),i,j,k,h,m),8);
+                                    l[size(l)+1] = list(graph41(list(1,2,2,1),i,j,k,h,m),8);
+                                }
+                                if (k <> h and k <> m)
+                                {
+                                    l[size(l)+1] = list(graph42(list(3,1,1,1),i,j,k,h,m),6);
+                                    l[size(l)+1] = list(graph42(list(1,3,1,1),i,j,k,h,m),6);
+                                    l[size(l)+1] = list(graph42(list(1,1,3,1),i,j,k,h,m),3);
+                                    l[size(l)+1] = list(graph42(list(2,2,1,1),i,j,k,h,m),8);
+                                    l[size(l)+1] = list(graph42(list(1,1,2,2),i,j,k,h,m),8);
+                                    l[size(l)+1] = list(graph42(list(2,1,2,1),i,j,k,h,m),4);
+                                    l[size(l)+1] = list(graph42(list(1,2,2,1),i,j,k,h,m),4);
+                                }
+                                if (j <> h and j <> m)
+                                {
+                                    l[size(l)+1] = list(graph43(list(3,1,1,1),i,j,k,h,m),18);
+                                    l[size(l)+1] = list(graph43(list(2,2,1,1),i,j,k,h,m),16);
+                                }
+                                for (n=0;n<=r;n++)
+                                {
+                                    if (k <> h and h <> m and m <> n)
+                                    {
+                                        l[size(l)+1] = list(graph51(list(2,1,1,1,1),i,j,k,h,m,n),2);
+                                        l[size(l)+1] = list(graph51(list(1,2,1,1,1),i,j,k,h,m,n),2);
+                                        l[size(l)+1] = list(graph51(list(1,1,2,1,1),i,j,k,h,m,n),4);
+                                    }
+                                    if (k <> h and h <> m and h <> n)
+                                    {
+                                        l[size(l)+1] = list(graph52(list(2,1,1,1,1),i,j,k,h,m,n),4);
+                                        l[size(l)+1] = list(graph52(list(1,2,1,1,1),i,j,k,h,m,n),4);
+                                        l[size(l)+1] = list(graph52(list(1,1,2,1,1),i,j,k,h,m,n),4);
+                                        l[size(l)+1] = list(graph52(list(1,1,1,2,1),i,j,k,h,m,n),2);
+                                    }
+                                    if (k <> h and k <> m and k <> n)
+                                    {
+                                        l[size(l)+1] = list(graph53(list(2,1,1,1,1),i,j,k,h,m,n),12);
+                                        l[size(l)+1] = list(graph53(list(1,2,1,1,1),i,j,k,h,m,n),12);
+                                        l[size(l)+1] = list(graph53(list(1,1,2,1,1),i,j,k,h,m,n),4);
+                                    }
+                                    if (j <> h and h <> m and h <> n)
+                                    {
+                                        l[size(l)+1] = list(graph54(list(2,1,1,1,1),i,j,k,h,m,n),4);
+                                        l[size(l)+1] = list(graph54(list(1,1,2,1,1),i,j,k,h,m,n),16);
+                                    }
+                                    if (k <> h and k <> m and h <> n)
+                                    {
+                                        l[size(l)+1] = list(graph55(list(2,1,1,1,1),i,j,k,h,m,n),2);
+                                        l[size(l)+1] = list(graph55(list(1,2,1,1,1),i,j,k,h,m,n),2);
+                                        l[size(l)+1] = list(graph55(list(1,1,1,2,1),i,j,k,h,m,n),4);
+                                    }
+                                    if (j <> h and j <> m and j <> n)
+                                    {
+                                        l[size(l)+1] = list(graph56(list(2,1,1,1,1),i,j,k,h,m,n),48);
+                                    }
+                                    for (p=0;p<=r;p++)
+                                    {
+                                        if (k <> h and h <> m and m <> n and n <> p)
+                                        {
+                                            l[size(l)+1] = list(graph61(list(1,1,1,1,1,1),i,j,k,h,m,n,p),2);
+                                        }
+                                        if (k <> h and h <> m and m <> n and m <> p)
+                                        {
+                                            l[size(l)+1] = list(graph62(list(1,1,1,1,1,1),i,j,k,h,m,n,p),2);
+                                        }
+                                        if (k <> h and h <> m and h <> n and n <> p)
+                                        {
+                                            l[size(l)+1] = list(graph63(list(1,1,1,1,1,1),i,j,k,h,m,n,p),1);
+                                        }
+                                        if (k <> h and h <> m and h <> n and h <> p)
+                                        {
+                                            l[size(l)+1] = list(graph64(list(1,1,1,1,1,1),i,j,k,h,m,n,p),6);
+                                        }
+                                        if (k <> h and k <> m and k <> n and n <> p)
+                                        {
+                                            l[size(l)+1] = list(graph65(list(1,1,1,1,1,1),i,j,k,h,m,n,p),4);
+                                        }
+                                        if (k <> h and k <> m and m <> p and h <> n)
+                                        {
+                                            l[size(l)+1] = list(graph66(list(1,1,1,1,1,1),i,j,k,h,m,n,p),6);
+                                        }
+                                        if (j <> h and h <> m and m <> n and m <> p)
+                                        {
+                                            l[size(l)+1] = list(graph67(list(1,1,1,1,1,1),i,j,k,h,m,n,p),8);
+                                        }
+                                        if (j <> h and h <> m and h <> n and h <> p)
+                                        {
+                                            l[size(l)+1] = list(graph68(list(1,1,1,1,1,1),i,j,k,h,m,n,p),12);
+                                        }
+                                        if (j <> h and h <> m and h <> n and n <> p)
+                                        {
+                                            l[size(l)+1] = list(graph69(list(1,1,1,1,1,1),i,j,k,h,m,n,p),2);
+                                        }
+                                        if (k <> h and k <> m and k <> n and k <> p)
+                                        {
+                                            l[size(l)+1] = list(graph610(list(1,1,1,1,1,1),i,j,k,h,m,n,p),24);
+                                        }
+                                        if (j <> h and j <> m and j <> n and j <> p)
+                                        {
+                                            l[size(l)+1] = list(graph611(list(1,1,1,1,1,1),i,j,k,h,m,n,p),720);
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+    return (l);
+}
+example
+{
+    "EXAMPLE:"; echo=2;
+    ring r = 0,x,dp;
+    variety P = projectiveSpace(4);
+    stack M = moduliSpace(P,2);
+    def F = fixedPoints(M);
+    size(F);
+    typeof(F[1]) == "list";
+    typeof(F[1][1]) == "graph";
+    typeof(F[1][2]) == "int";
+}
+
+static proc torusList(variety P)
+"USAGE:     torusList(P); P variety
+RETURN:     list
+INPUT:      P is a projective space
+OUTPUT:     a list of numbers
+THEORY:     This is a procedure concerning the enumeration of rational curves.
+KEYWORDS:   torus action
+EXAMPLE:    example torusList; shows an example
+"
+{
+    int i;
+    int n = P.dimension;
+    list l;
+    for (i=0;i<=n;i++)
+    {
+        l = insert(l,number(10^i),size(l));
+    }
+    return (l);
+}
+example
+{
+    "EXAMPLE:"; echo=2;
+    ring r = 0,x,dp;
+    variety P = projectiveSpace(4);
+    def L = torusList(P);
+    L;
+}
+
+proc contributionBundle(stack M, graph G, list #)
+"USAGE:     contributionBundle(M,G,#); M stack, G graph, # list
+RETURN:     number
+INPUT:      M is a moduli space of stable maps, G is a graph, # is a list.
+OUTPUT:     a number corresponding to the contribution bundle on a moduli space
+            of stable maps at a fixed point component (graph)
+KEYWORDS:   contribution bundle, graph, multiple cover, rational curve,
+SEE ALSO:   normalBundle
+EXAMPLE:    example contributionBundle; shows an example
+"
+{
+    def R = basering;
+    setring R;
+    int i,j,a;
+    variety P = M.currentVariety;
+    def L = torusList(P);
+    int r = P.dimension;
+    int d;
+    if (size(#)==0) {d = 2*r - 3;}
+    else
+    {
+        if (typeof(#[1]) == "int") {d = #[1];}
+        else {Error("invalid optional argument");}
+    }
+    list e = G.edges;
+    list v = G.vertices;
+    number E = 1;
+    number V = 1;
+    if (r == 1)
+    {
+        for (i=1;i<=size(v);i++)
+        {
+            V = V*(-L[v[i][1]+1])^(v[i][2]-1);
+        }
+        for (j=1;j<=size(e);j++)
+        {
+            number f = 1;
+            if (e[j][3]<>1)
+            {
+                for (a=1;a<e[j][3];a++)
+                {
+                    f=f*(-a*L[e[j][1]+1]-(e[j][3]-a)*L[e[j][2]+1])/e[j][3];
+                }
+            }
+            E = E*f;
+            kill f;
+        }
+        return ((E*V)^2);
+    }
+    else
+    {
+        for (i=1;i<=size(v);i++)
+        {
+            V = V*((d*L[v[i][1]+1])^(v[i][2]-1));
+        }
+        for (j=1;j<=size(e);j++)
+        {
+            number f = 1;
+            for (a=0;a<=d*e[j][3];a++)
+            {
+                f = f*((a*L[e[j][1]+1]+(d*e[j][3]-a)*L[e[j][2]+1])/e[j][3]);
+            }
+            E = E*f;
+            kill f;
+        }
+        return (E/V);
+    }
+}
+example
+{
+    "EXAMPLE:"; echo=2;
+    ring r = 0,x,dp;
+    variety P = projectiveSpace(4);
+    stack M = moduliSpace(P,2);
+    def F = fixedPoints(M);
+    graph G = F[1][1];
+    number f = contributionBundle(M,G);
+    number g = contributionBundle(M,G,5);
+    f == g;
+}
+
+proc normalBundle(stack M, graph G)
+"USAGE:     normalBundle(M,G); M stack, G graph
+RETURN:     number
+INPUT:      M is a moduli space of stable maps, G is a graph
+OUTPUT:     a number corresponding to the normal bundle on a moduli space of
+            stable maps at a graph
+KEYWORDS:   normal bundle, graph, rational curves, mutiple covers, lines on
+            hypersurfaces
+SEE ALSO:   contributionBundle
+EXAMPLE:    example normalBundle; shows an example
+{
+    def R = basering;
+    setring R;
+    variety P = M.currentVariety;
+    def L = torusList(P);
+    int n = P.dimension;
+    list e = G.edges;
+    list v = G.vertices;
+    int i,j,k,h,b,m,a;
+    number N = 1;
+    for (j=1;j<=size(e);j++)
+    {
+        int d = e[j][3];
+        number c = (-1)^d*factorial(d)^2;
+        number y = c*(L[e[j][1]+1]-L[e[j][2]+1])^(2*d)/(number(d)^(2*d));
+        for (k=0;k<=n;k++)
+        {
+            if (k <> e[j][1] and k <> e[j][2])
+            {
+                for (a=0;a<=d;a++)
+                {
+                    y=y*((a*L[e[j][1]+1]+(d-a)*L[e[j][2]+1])/d - L[k+1]);
+                }
+            }
+        }
+        N = N*y;
+        kill y,d,c;
+    }
+    for (i=1;i<=size(v);i++)
+    {
+        number F = 1;
+        for (h=3;h<=size(v[i]);h++)
+        {
+            F = F*(L[v[i][h][1]+1]-L[v[i][h][2]+1])/v[i][h][3];
+        }
+        if (v[i][2] == 1)
+        {
+            N = N/F;
+            kill F;
+        }
+        else
+        {
+            number z = 1;
+            for (m=0;m<=n;m++)
+            {
+                if (m<>v[i][1])
+                {
+                    z = z*(L[v[i][1]+1]-L[m+1]);
+                }
+            }
+            if (v[i][2] == 3)
+            {
+                N = N*F/z^2;
+                kill F,z;
+            }
+            else
+            {
+                number g = 0;
+                for (b=3;b<=size(v[i]);b++)
+                {
+                    g = g + v[i][b][3]/(L[v[i][b][1]+1]-L[v[i][b][2]+1]);
+                }
+                N = N*F*g^(3-v[i][2])/(z^(v[i][2]-1));
+                kill g,F,z;
+            }
+        }
+    }
+    return (N);
+}
+example
+{
+    "EXAMPLE:"; echo=2;
+    ring r = 0,x,dp;
+    variety P = projectiveSpace(4);
+    stack M = moduliSpace(P,2);
+    def F = fixedPoints(M);
+    graph G = F[1][1];
+    number f = normalBundle(M,G);
+    f <> 0;
+}
+
+proc multipleCover(int d)
+"USAGE:     multipleCover(d); d int
+RETURN:     number
+THEORY:     This is the contribution of degree d multiple covers of a smooth
+            rational curve as a Gromov-Witten invariant.
+KEYWORDS:   Gromov-Witten invariants, multiple covers
+SEE ALSO:   rationalCurve, linesHypersurface
+EXAMPLE:    example multipleCover; shows an example
+"
+{
+    def R = basering;
+    setring R;
+    variety P = projectiveSpace(1);
+    stack M = moduliSpace(P,d);
+    def F = fixedPoints(M);
+    int i;
+    number r = 0;
+    for (i=1;i<=size(F);i++)
+    {
+        graph G = F[i][1];
+        number s = contributionBundle(M,G);
+        number t = F[i][2]*normalBundle(M,G);
+        r = r + s/t;
+        kill s,t,G;
+    }
+    return (r);
+}
+example
+{
+    "EXAMPLE:"; echo=2;
+    ring r = 0,x,dp;
+    multipleCover(1);
+    multipleCover(2);
+    multipleCover(3);
+    multipleCover(4);
+    multipleCover(5);
+    multipleCover(6);
+}
+
+proc linesHypersurface(int n)
+"USAGE:     linesHypersurface(n); n int
+RETURN:     number
+THEORY:     This is the number of lines on a general hypersurface of degree
+            d = 2n-3 in an n-dimensional projective space.
+KEYWORDS:   Gromov-Witten invariants, lines on hypersurfaces
+SEE ALSO:   linesHypersurface, multipleCover
+EXAMPLE:    example linesHypersurface; shows an example
+"
+{
+    def R = basering;
+    setring R;
+    variety P = projectiveSpace(n);
+    stack M = moduliSpace(P,1);
+    def F = fixedPoints(M);
+    int i;
+    number r = 0;
+    for (i=1;i<=size(F);i++)
+    {
+        graph G = F[i][1];
+        number s = contributionBundle(M,G);
+        number t = F[i][2]*normalBundle(M,G);
+        r = r + s/t;
+        kill s,t,G;
+    }
+    return (r);
+}
+example
+{
+    "EXAMPLE:"; echo=2;
+    ring r = 0,x,dp;
+    linesHypersurface(2);
+    linesHypersurface(3);
+    linesHypersurface(4);
+    linesHypersurface(5);
+    linesHypersurface(6);
+    linesHypersurface(7);
+    linesHypersurface(8);
+    linesHypersurface(9);
+    linesHypersurface(10);
+}
+
+proc sumofquotients(stack M, list F, list #)
+"USAGE:     sumofquotient(M,F,#); M stack, F list, # list
+RETURN:     number
+THEORY:     This is useful for the parallel computation of rationalCurve.
+KEYWORDS:   Gromov-Witten invariants, rational curves on Calabi-Yau threefolds
+EXAMPLE:    example sumofquotients; shows an example
+"
+{
+    if (size(#) == 0) {list l = 5;}
+    else {list l = #;}
+    number sum = 0;
+    number s, t;
+    int i,j;
+    for (i = size(F); i > 0; i--)
+    {
+        s = 1;
+        for (j=1;j<=size(l);j++)
+        {
+            s = s*contributionBundle(M,F[i][1],list(l[j]));
+        }
+        t = F[i][2]*normalBundle(M,F[i][1]);
+        sum = sum + s/t;
+    }
+    return(sum);
+}
+example
+{
+    "EXAMPLE:"; echo=2;
+    ring r = 0,x,dp;
+    variety P = projectiveSpace(4);
+    stack M = moduliSpace(P,2);
+    list F = fixedPoints(M);
+    sumofquotients(M,F);
+    sumofquotients(M,F,list(5));
+}
+
+proc rationalCurve(int d, list #)
+"USAGE:     rationalCurve(d,#); d int, # list
+RETURN:     number
+THEORY:     This is the Gromov-Witten invariant corresponding the number of
+            rational curves on a general Calabi-Yau threefold.
+KEYWORDS:   Gromov-Witten invariants, rational curves on Calabi-Yau threefolds
+SEE ALSO:   linesHypersurface, multipleCover
+EXAMPLE:    example rationalCurve; shows an example
+"
+{
+    def R = basering;
+    setring R;
+    int n,i;
+    if (size(#) == 0) {n = 4; list l = 5;}
+    else {n = size(#)+3; list l = #;}
+    variety P = projectiveSpace(n);
+    stack M = moduliSpace(P,d);
+    def F = fixedPoints(M);
+    int ncpus = system("--cpus");
+    int sizeF = size(F);
+    list args;
+    int from = 1;
+    int to;
+    for (i = 1; i <= ncpus; i++)
+    {
+        to = (sizeF*i) div ncpus;
+        args[i] = list(M, list(F[from..to]), l);
+        from = to+1;
+    }
+    list results = parallelWaitAll("sumofquotients", args);
+    number r = 0;
+    for (i = 1; i <= ncpus; i++)
+    {
+        r = r + results[i];
+    }
+    return (r);
+}
+example
+{
+    "EXAMPLE:"; echo=2;
+    ring r = 0,x,dp;
+    rationalCurve(1);
+    /*
+    rationalCurve(2);
+    rationalCurve(3);
+    rationalCurve(4);
+    rationalCurve(1,list(4,2));
+    rationalCurve(1,list(3,3));
+    rationalCurve(1,list(3,2,2));
+    rationalCurve(1,list(2,2,2,2));
+    rationalCurve(2,list(4,2));
+    rationalCurve(2,list(3,3));
+    rationalCurve(2,list(3,2,2));
+    rationalCurve(2,list(2,2,2,2));
+    rationalCurve(3,list(4,2));
+    rationalCurve(3,list(3,3));
+    rationalCurve(3,list(3,2,2));
+    rationalCurve(3,list(2,2,2,2));
+    rationalCurve(4,list(4,2));
+    rationalCurve(4,list(3,3));
+    rationalCurve(4,list(3,2,2));
+    rationalCurve(4,list(2,2,2,2));
+    */
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/////////// Procedures concerned with graphs ///////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+
+proc printGraph(graph G)
+"USAGE:     printGraph(G); G graph
+ASSUME:     G is a graph.
+THEORY:     This is the print function used by Singular to print a graph.
+KEYWORDS:   graph
+EXAMPLE:    example printGraph; shows an example
+"
+{
+    "A graph with", size(G.vertices), "vertices and", size(G.edges), "edges";
+}
+example
+{
+    "EXAMPLE:"; echo=2;
+    ring r = 0,x,dp;
+    graph G = makeGraph(list(list(0,1,list(0,1,2)),list(1,1,list(1,0,2))),
+    list(list(0,1,2)));
+    G;
+}
+
+proc makeGraph(list v, list e)
+"USAGE:     makeGraph(v,e); v list, e list
+ASSUME:     v is a list of vertices, e is a list of edges.
+RETURN:     graph with vertices v and edges e.
+THEORY:     Creates a graph from a list of vertices and edges.
+KEYWORDS:   graph
+EXAMPLE:    example makeGraph; shows an example
+{
+    graph G;
+    G.vertices = v;
+    G.edges = e;
+    return(G);
+}
+example
+{
+    "EXAMPLE:"; echo=2;
+    ring r = 0,x,dp;
+    graph G = makeGraph(list(list(0,1,list(0,1,2)),list(1,1,list(1,0,2))),
+    list(list(0,1,2)));
+    G;
+}
+
+static proc graph1(int d, int i, int j)
+{
+    graph G;
+    list f1 = i,j,d;
+    list f2 = j,i,d;
+    list v1 = i,1,f1;
+    list v2 = j,1,f2;
+    G.vertices = v1,v2;
+    G.edges = list(f1);
+    return (G);
+}
+
+static proc graph2(list d, int i, int j, int k)
+{
+    graph G;
+    list f1 = i,j,d[1];
+    list f2 = j,i,d[1];
+    list f3 = j,k,d[2];
+    list f4 = k,j,d[2];
+    list v1 = i,1,f1;
+    list v2 = j,2,f2,f3;
+    list v3 = k,1,f4;
+    G.vertices = v1,v2,v3;
+    G.edges = f1,f3;
+    return (G);
+}
+
+static proc graph31(list d, int i, int j, int k, int h)
+{
+    graph G;
+    list f1 = i,j,d[1];
+    list f2 = j,i,d[1];
+    list f3 = j,k,d[2];
+    list f4 = k,j,d[2];
+    list f5 = k,h,d[3];
+    list f6 = h,k,d[3];
+    list v1 = i,1,f1;
+    list v2 = j,2,f2,f3;
+    list v3 = k,2,f4,f5;
+    list v4 = h,1,f6;
+    G.vertices = v1,v2,v3,v4;
+    G.edges = f1,f3,f5;
+    return (G);
+}
+
+static proc graph32(list d, int i, int j, int k, int h)
+{
+    graph G;
+    list f1 = i,j,d[1];
+    list f2 = j,i,d[1];
+    list f3 = j,k,d[2];
+    list f4 = j,h,d[3];
+    list f5 = k,j,d[2];
+    list f6 = h,j,d[3];
+    list v1 = i,1,f1;
+    list v2 = j,3,f2,f3,f4;
+    list v3 = k,1,f5;
+    list v4 = h,1,f6;
+    G.vertices = v1,v2,v3,v4;
+    G.edges = f1,f3,f4;
+    return (G);
+}
+
+static proc graph41(list d, int i, int j, int k, int h, int l)
+{
+    graph G;
+    list f1 = i,j,d[1];
+    list f2 = j,i,d[1];
+    list f3 = j,k,d[2];
+    list f4 = k,j,d[2];
+    list f5 = k,h,d[3];
+    list f6 = h,k,d[3];
+    list f7 = h,l,d[4];
+    list f8 = l,h,d[4];
+    list v1 = i,1,f1;
+    list v2 = j,2,f2,f3;
+    list v3 = k,2,f4,f5;
+    list v4 = h,2,f6,f7;
+    list v5 = l,1,f8;
+    G.vertices = v1,v2,v3,v4,v5;
+    G.edges = f1,f3,f5,f7;
+    return (G);
+}
+
+static proc graph42(list d, int i, int j, int k, int h, int l)
+{
+    graph G;
+    list f1 = i,j,d[1];
+    list f2 = j,i,d[1];
+    list f3 = j,k,d[2];
+    list f4 = k,j,d[2];
+    list f5 = k,h,d[3];
+    list f6 = k,l,d[4];
+    list f7 = h,k,d[3];
+    list f8 = l,k,d[4];
+    list v1 = i,1,f1;
+    list v2 = j,2,f2,f3;
+    list v3 = k,3,f4,f5,f6;
+    list v4 = h,1,f7;
+    list v5 = l,1,f8;
+    G.vertices = v1,v2,v3,v4,v5;
+    G.edges = f1,f3,f5,f6;
+    return (G);
+}
+
+static proc graph43(list d, int i, int j, int k, int h, int l)
+{
+    graph G;
+    list f1 = i,j,d[1];
+    list f2 = j,i,d[1];
+    list f3 = j,k,d[2];
+    list f4 = j,h,d[3];
+    list f5 = j,l,d[4];
+    list f6 = k,j,d[2];
+    list f7 = h,j,d[3];
+    list f8 = l,j,d[4];
+    list v1 = i,1,f1;
+    list v2 = j,4,f2,f3,f4,f5;
+    list v3 = k,1,f6;
+    list v4 = h,1,f7;
+    list v5 = l,1,f8;
+    G.vertices = v1,v2,v3,v4,v5;
+    G.edges = f1,f3,f4,f5;
+    return (G);
+}
+
+static proc graph51(list d, int i, int j, int k, int h, int m, int n)
+{
+    graph G;
+    list f1 = i,j,d[1];
+    list f2 = j,i,d[1];
+    list f3 = j,k,d[2];
+    list f4 = k,j,d[2];
+    list f5 = k,h,d[3];
+    list f6 = h,k,d[3];
+    list f7 = h,m,d[4];
+    list f8 = m,h,d[4];
+    list f9 = m,n,d[5];
+    list f10 = n,m,d[5];
+    list v1 = i,1,f1;
+    list v2 = j,2,f2,f3;
+    list v3 = k,2,f4,f5;
+    list v4 = h,2,f6,f7;
+    list v5 = m,2,f8,f9;
+    list v6 = n,1,f10;
+    G.vertices = v1,v2,v3,v4,v5,v6;
+    G.edges = f1,f3,f5,f7,f9;
+    return (G);
+}
+
+static proc graph52(list d, int i, int j, int k, int h, int m, int n)
+{
+    graph G;
+    list f1 = i,j,d[1];
+    list f2 = j,i,d[1];
+    list f3 = j,k,d[2];
+    list f4 = k,j,d[2];
+    list f5 = k,h,d[3];
+    list f6 = h,k,d[3];
+    list f7 = h,m,d[4];
+    list f8 = m,h,d[4];
+    list f9 = h,n,d[5];
+    list f10 = n,h,d[5];
+    list v1 = i,1,f1;
+    list v2 = j,2,f2,f3;
+    list v3 = k,2,f4,f5;
+    list v4 = h,3,f6,f7,f9;
+    list v5 = m,1,f8;
+    list v6 = n,1,f10;
+    G.vertices = v1,v2,v3,v4,v5,v6;
+    G.edges = f1,f3,f5,f7,f9;
+    return (G);
+}
+
+static proc graph53(list d, int i, int j, int k, int h, int m, int n)
+{
+    graph G;
+    list f1 = i,j,d[1];
+    list f2 = j,i,d[1];
+    list f3 = j,k,d[2];
+    list f4 = k,j,d[2];
+    list f5 = k,h,d[3];
+    list f6 = h,k,d[3];
+    list f7 = k,m,d[4];
+    list f8 = m,k,d[4];
+    list f9 = k,n,d[5];
+    list f10 = n,k,d[5];
+    list v1 = i,1,f1;
+    list v2 = j,2,f2,f3;
+    list v3 = k,4,f4,f5,f7,f9;
+    list v4 = h,1,f6;
+    list v5 = m,1,f8;
+    list v6 = n,1,f10;
+    G.vertices = v1,v2,v3,v4,v5,v6;
+    G.edges = f1,f3,f5,f7,f9;
+    return (G);
+}
+
+static proc graph54(list d, int i, int j, int k, int h, int m, int n)
+{
+    graph G;
+    list f1 = i,j,d[1];
+    list f2 = j,i,d[1];
+    list f3 = j,k,d[2];
+    list f4 = k,j,d[2];
+    list f5 = j,h,d[3];
+    list f6 = h,j,d[3];
+    list f7 = h,m,d[4];
+    list f8 = m,h,d[4];
+    list f9 = h,n,d[5];
+    list f10 = n,h,d[5];
+    list v1 = i,1,f1;
+    list v2 = j,3,f2,f3,f5;
+    list v3 = k,1,f4;
+    list v4 = h,3,f6,f7,f9;
+    list v5 = m,1,f8;
+    list v6 = n,1,f10;
+    G.vertices = v1,v2,v3,v4,v5,v6;
+    G.edges = f1,f3,f5,f7,f9;
+    return (G);
+}
+
+static proc graph55(list d, int i, int j, int k, int h, int m, int n)
+{
+    graph G;
+    list f1 = i,j,d[1];
+    list f2 = j,i,d[1];
+    list f3 = j,k,d[2];
+    list f4 = k,j,d[2];
+    list f5 = k,h,d[3];
+    list f6 = h,k,d[3];
+    list f7 = k,m,d[4];
+    list f8 = m,k,d[4];
+    list f9 = h,n,d[5];
+    list f10 = n,h,d[5];
+    list v1 = i,1,f1;
+    list v2 = j,2,f2,f3;
+    list v3 = k,3,f4,f5,f7;
+    list v4 = h,2,f6,f9;
+    list v5 = m,1,f8;
+    list v6 = n,1,f10;
+    G.vertices = v1,v2,v3,v4,v5,v6;
+    G.edges = f1,f3,f5,f7,f9;
+    return (G);
+}
+
+static proc graph56(list d, int i, int j, int k, int h, int m, int n)
+{
+    graph G;
+    list f1 = i,j,d[1];
+    list f2 = j,i,d[1];
+    list f3 = j,k,d[2];
+    list f4 = k,j,d[2];
+    list f5 = j,h,d[3];
+    list f6 = h,j,d[3];
+    list f7 = j,m,d[4];
+    list f8 = m,j,d[4];
+    list f9 = j,n,d[5];
+    list f10 = n,j,d[5];
+    list v1 = i,1,f1;
+    list v2 = j,5,f2,f3,f5,f7,f9;
+    list v3 = k,1,f4;
+    list v4 = h,1,f6;
+    list v5 = m,1,f8;
+    list v6 = n,1,f10;
+    G.vertices = v1,v2,v3,v4,v5,v6;
+    G.edges = f1,f3,f5,f7,f9;
+    return (G);
+}
+
+static proc graph61(list d, int i, int j, int k, int h, int m, int n, int p)
+{
+    graph G;
+    list f1 = i,j,d[1];
+    list f2 = j,i,d[1];
+    list f3 = j,k,d[2];
+    list f4 = k,j,d[2];
+    list f5 = k,h,d[3];
+    list f6 = h,k,d[3];
+    list f7 = h,m,d[4];
+    list f8 = m,h,d[4];
+    list f9 = m,n,d[5];
+    list f10 = n,m,d[5];
+    list f11 = n,p,d[6];
+    list f12 = p,n,d[6];
+    list v1 = i,1,f1;
+    list v2 = j,2,f2,f3;
+    list v3 = k,2,f4,f5;
+    list v4 = h,2,f6,f7;
+    list v5 = m,2,f8,f9;
+    list v6 = n,2,f10,f11;
+    list v7 = p,1,f12;
+    G.vertices = v1,v2,v3,v4,v5,v6,v7;
+    G.edges = f1,f3,f5,f7,f9,f11;
+    return (G);
+}
+
+static proc graph62(list d, int i, int j, int k, int h, int m, int n, int p)
+{
+    graph G;
+    list f1 = i,j,d[1];
+    list f2 = j,i,d[1];
+    list f3 = j,k,d[2];
+    list f4 = k,j,d[2];
+    list f5 = k,h,d[3];
+    list f6 = h,k,d[3];
+    list f7 = h,m,d[4];
+    list f8 = m,h,d[4];
+    list f9 = m,n,d[5];
+    list f10 = n,m,d[5];
+    list f11 = m,p,d[6];
+    list f12 = p,m,d[6];
+    list v1 = i,1,f1;
+    list v2 = j,2,f2,f3;
+    list v3 = k,2,f4,f5;
+    list v4 = h,2,f6,f7;
+    list v5 = m,3,f8,f9,f11;
+    list v6 = n,1,f10;
+    list v7 = p,1,f12;
+    G.vertices = v1,v2,v3,v4,v5,v6,v7;
+    G.edges = f1,f3,f5,f7,f9,f11;
+    return (G);
+}
+
+static proc graph63(list d, int i, int j, int k, int h, int m, int n, int p)
+{
+    graph G;
+    list f1 = i,j,d[1];
+    list f2 = j,i,d[1];
+    list f3 = j,k,d[2];
+    list f4 = k,j,d[2];
+    list f5 = k,h,d[3];
+    list f6 = h,k,d[3];
+    list f7 = h,m,d[4];
+    list f8 = m,h,d[4];
+    list f9 = h,n,d[5];
+    list f10 = n,h,d[5];
+    list f11 = n,p,d[6];
+    list f12 = p,n,d[6];
+    list v1 = i,1,f1;
+    list v2 = j,2,f2,f3;
+    list v3 = k,2,f4,f5;
+    list v4 = h,3,f6,f7,f9;
+    list v5 = m,1,f8;
+    list v6 = n,2,f10,f11;
+    list v7 = p,1,f12;
+    G.vertices = v1,v2,v3,v4,v5,v6,v7;
+    G.edges = f1,f3,f5,f7,f9,f11;
+    return (G);
+}
+
+static proc graph64(list d, int i, int j, int k, int h, int m, int n, int p)
+{
+    graph G;
+    list f1 = i,j,d[1];
+    list f2 = j,i,d[1];
+    list f3 = j,k,d[2];
+    list f4 = k,j,d[2];
+    list f5 = k,h,d[3];
+    list f6 = h,k,d[3];
+    list f7 = h,m,d[4];
+    list f8 = m,h,d[4];
+    list f9 = h,n,d[5];
+    list f10 = n,h,d[5];
+    list f11 = h,p,d[6];
+    list f12 = p,h,d[6];
+    list v1 = i,1,f1;
+    list v2 = j,2,f2,f3;
+    list v3 = k,2,f4,f5;
+    list v4 = h,4,f6,f7,f9,f11;
+    list v5 = m,1,f8;
+    list v6 = n,1,f10;
+    list v7 = p,1,f12;
+    G.vertices = v1,v2,v3,v4,v5,v6,v7;
+    G.edges = f1,f3,f5,f7,f9,f11;
+    return (G);
+}
+
+static proc graph65(list d, int i, int j, int k, int h, int m, int n, int p)
+{
+    graph G;
+    list f1 = i,j,d[1];
+    list f2 = j,i,d[1];
+    list f3 = j,k,d[2];
+    list f4 = k,j,d[2];
+    list f5 = k,h,d[3];
+    list f6 = h,k,d[3];
+    list f7 = k,m,d[4];
+    list f8 = m,k,d[4];
+    list f9 = k,n,d[5];
+    list f10 = n,k,d[5];
+    list f11 = n,p,d[6];
+    list f12 = p,n,d[6];
+    list v1 = i,1,f1;
+    list v2 = j,2,f2,f3;
+    list v3 = k,4,f4,f5,f7,f9;
+    list v4 = h,1,f6;
+    list v5 = m,1,f8;
+    list v6 = n,2,f10,f11;
+    list v7 = p,1,f12;
+    G.vertices = v1,v2,v3,v4,v5,v6,v7;
+    G.edges = f1,f3,f5,f7,f9,f11;
+    return (G);
+}
+
+static proc graph66(list d, int i, int j, int k, int h, int m, int n, int p)
+{
+    graph G;
+    list f1 = i,j,d[1];
+    list f2 = j,i,d[1];
+    list f3 = j,k,d[2];
+    list f4 = k,j,d[2];
+    list f5 = k,h,d[3];
+    list f6 = h,k,d[3];
+    list f7 = k,m,d[4];
+    list f8 = m,k,d[4];
+    list f9 = h,n,d[5];
+    list f10 = n,h,d[5];
+    list f11 = m,p,d[6];
+    list f12 = p,m,d[6];
+    list v1 = i,1,f1;
+    list v2 = j,2,f2,f3;
+    list v3 = k,3,f4,f5,f7;
+    list v4 = h,2,f6,f9;
+    list v5 = m,2,f8,f11;
+    list v6 = n,1,f10;
+    list v7 = p,1,f12;
+    G.vertices = v1,v2,v3,v4,v5,v6,v7;
+    G.edges = f1,f3,f5,f7,f9,f11;
+    return (G);
+}
+
+static proc graph67(list d, int i, int j, int k, int h, int m, int n, int p)
+{
+    graph G;
+    list f1 = i,j,d[1];
+    list f2 = j,i,d[1];
+    list f3 = j,k,d[2];
+    list f4 = k,j,d[2];
+    list f5 = j,h,d[3];
+    list f6 = h,j,d[3];
+    list f7 = h,m,d[4];
+    list f8 = m,h,d[4];
+    list f9 = m,n,d[5];
+    list f10 = n,m,d[5];
+    list f11 = m,p,d[6];
+    list f12 = p,m,d[6];
+    list v1 = i,1,f1;
+    list v2 = j,3,f2,f3,f5;
+    list v3 = k,1,f4;
+    list v4 = h,2,f6,f7;
+    list v5 = m,3,f8,f9,f11;
+    list v6 = n,1,f10;
+    list v7 = p,1,f12;
+    G.vertices = v1,v2,v3,v4,v5,v6,v7;
+    G.edges = f1,f3,f5,f7,f9,f11;
+    return (G);
+}
+
+static proc graph68(list d, int i, int j, int k, int h, int m, int n, int p)
+{
+    graph G;
+    list f1 = i,j,d[1];
+    list f2 = j,i,d[1];
+    list f3 = j,k,d[2];
+    list f4 = k,j,d[2];
+    list f5 = j,h,d[3];
+    list f6 = h,j,d[3];
+    list f7 = h,m,d[4];
+    list f8 = m,h,d[4];
+    list f9 = h,n,d[5];
+    list f10 = n,h,d[5];
+    list f11 = h,p,d[6];
+    list f12 = p,h,d[6];
+    list v1 = i,1,f1;
+    list v2 = j,3,f2,f3,f5;
+    list v3 = k,1,f4;
+    list v4 = h,4,f6,f7,f9,f11;
+    list v5 = m,1,f8;
+    list v6 = n,1,f10;
+    list v7 = p,1,f12;
+    G.vertices = v1,v2,v3,v4,v5,v6,v7;
+    G.edges = f1,f3,f5,f7,f9,f11;
+    return (G);
+}
+
+static proc graph69(list d, int i, int j, int k, int h, int m, int n, int p)
+{
+    graph G;
+    list f1 = i,j,d[1];
+    list f2 = j,i,d[1];
+    list f3 = j,k,d[2];
+    list f4 = k,j,d[2];
+    list f5 = j,h,d[3];
+    list f6 = h,j,d[3];
+    list f7 = h,m,d[4];
+    list f8 = m,h,d[4];
+    list f9 = h,n,d[5];
+    list f10 = n,h,d[5];
+    list f11 = n,p,d[6];
+    list f12 = p,n,d[6];
+    list v1 = i,1,f1;
+    list v2 = j,3,f2,f3,f5;
+    list v3 = k,1,f4;
+    list v4 = h,3,f6,f7,f9;
+    list v5 = m,1,f8;
+    list v6 = n,2,f10,f11;
+    list v7 = p,1,f12;
+    G.vertices = v1,v2,v3,v4,v5,v6,v7;
+    G.edges = f1,f3,f5,f7,f9,f11;
+    return (G);
+}
+
+static proc graph610(list d, int i, int j, int k, int h, int m, int n, int p)
+{
+    graph G;
+    list f1 = i,j,d[1];
+    list f2 = j,i,d[1];
+    list f3 = j,k,d[2];
+    list f4 = k,j,d[2];
+    list f5 = k,h,d[3];
+    list f6 = h,k,d[3];
+    list f7 = k,m,d[4];
+    list f8 = m,k,d[4];
+    list f9 = k,n,d[5];
+    list f10 = n,k,d[5];
+    list f11 = k,p,d[6];
+    list f12 = p,k,d[6];
+    list v1 = i,1,f1;
+    list v2 = j,2,f2,f3;
+    list v3 = k,5,f4,f5,f7,f9,f11;
+    list v4 = h,1,f6;
+    list v5 = m,1,f8;
+    list v6 = n,1,f10;
+    list v7 = p,1,f12;
+    G.vertices = v1,v2,v3,v4,v5,v6,v7;
+    G.edges = f1,f3,f5,f7,f9,f11;
+    return (G);
+}
+
+static proc graph611(list d, int i, int j, int k, int h, int m, int n, int p)
+{
+    graph G;
+    list f1 = i,j,d[1];
+    list f2 = j,i,d[1];
+    list f3 = j,k,d[2];
+    list f4 = k,j,d[2];
+    list f5 = j,h,d[3];
+    list f6 = h,j,d[3];
+    list f7 = j,m,d[4];
+    list f8 = m,j,d[4];
+    list f9 = j,n,d[5];
+    list f10 = n,j,d[5];
+    list f11 = j,p,d[6];
+    list f12 = p,j,d[6];
+    list v1 = i,1,f1;
+    list v2 = j,6,f2,f3,f5,f7,f9,f11;
+    list v3 = k,1,f4;
+    list v4 = h,1,f6;
+    list v5 = m,1,f8;
+    list v6 = n,1,f10;
+    list v7 = p,1,f12;
+    G.vertices = v1,v2,v3,v4,v5,v6,v7;
+    G.edges = f1,f3,f5,f7,f9,f11;
+    return (G);
+}
+
+proc part(poly f, int n)
+"USAGE:     part(f,n); f poly, n int
+RETURN:     poly
+PURPOSE:    computing the homogeneous component of a polynomial.
+EXAMPLE:    example part; shows examples
+"
+{
+    int i;
+    poly p;
+    for (i=1;i<=size(f);i++)
+    {
+        if (deg(f[i])==n) {p=p+f[i];}
+    }
+    return (p);
+}
+example
+{
+    "EXAMPLE:"; echo=2;
+    ring r = 0,(x,y,z),wp(1,2,3);
+    poly f = 1+x+x2+x3+x4+y+y2+y3+z+z2+xy+xz+yz+xyz;
+    part(f,0);
+    part(f,1);
+    part(f,2);
+    part(f,3);
+    part(f,4);
+    part(f,5);
+    part(f,6);
+}
+
+proc parts(poly f, int i, int j)
+"USAGE:     parts(f,i,j); f poly, i int, j int
+RETURN:     poly
+THEORY:     computing a polynomial which is the sum of the homogeneous
+            components of a polynomial.
+EXAMPLE:    example parts; shows examples
+"
+{
+    int k;
+    poly p;
+    for (k=i;k<=j;k++)
+    {
+        p=p+part(f,k);
+    }
+    return (p);
+}
+example
+{
+    "EXAMPLE:"; echo=2;
+    ring r = 0,(x,y,z),wp(1,2,3);
+    poly f = 1+x+x2+x3+x4+y+y2+y3+z+z2+xy+xz+yz+xyz;
+    parts(f,2,4);
+}
+
+proc logg(poly f, int n)
+"USAGE:     logg(f,n); f poly, n int
+RETURN:     poly
+THEORY:     computing Chern characters from total Chern classes.
+EXAMPLE:    example logg; shows examples
+"
+{
+    poly p;
+    int i,j,k,m;
+    if (n==0) {p=0;}
+    if (n==1) {p=part(f,1);}
+    else
+    {
+        list l=-part(f,1);
+        for (j=2;j<=n;j++)
+        {
+            poly q;
+            for (k=1;k<j;k++)
+            {
+                q=q+part(f,k)*l[j-k];
+            }
+            q=-j*part(f,j)-q;
+            l=insert(l,q,size(l));
+            kill q;
+        }
+        for (m=1;m<=n;m++)
+        {
+            p=p+1/factorial(m)*(-1)^m*l[m];
+        }
+    }
+    return (p);
+}
+example
+{
+    "EXAMPLE:"; echo=2;
+    ring r = 0,(x,y),wp(1,2);
+    poly f = 1+x+y;
+    logg(f,4);
+}
+
+proc expp(poly f, int n)
+"USAGE:     expp(f,n); f poly, n int
+RETURN:     poly
+PURPOSE:    computing total Chern classes from Chern characters.
+EXAMPLE:    example expp; shows examples
+"
+{
+    poly p;
+    int i,j,k;
+    if (deg(f)==0) {p=1;}
+    else
+    {
+        list l=1;
+        for (i=1;i<=n;i++)
+        {
+            poly q;
+            for (j=1;j<=i;j++)
+            {
+                q=q+factorial(j)*(-1)^(j-1)*l[i-j+1]*part(f,j)/i;
+            }
+            l=insert(l,q,size(l));
+            kill q;
+        }
+        for (k=1;k<=size(l);k++)
+        {
+            p=p+l[k];
+        }
+    }
+    return (p);
+}
+example
+{
+    "EXAMPLE:"; echo=2;
+    ring r = 0,x,dp;
+    poly f = 3+x;
+    expp(f,3);
+}
+
+static proc adams(poly f, int n)
+{
+    poly p;
+    int i;
+    for (i=0;i<=deg(f);i++)
+    {
+        p=p+n^i*part(f,i);
+    }
+    return (p);
+}
+
+static proc wedges(int n, poly f, int d)
+{
+    int i,j;
+    list l;
+    if (n==0) {l=1;}
+    if (n==1) {l=1,f;}
+    else
+    {
+        l=1,f;
+        for (i=2;i<=n;i++)
+        {
+            poly q;
+            for (j=1;j<=i;j++)
+            {
+                q=q+((-1)^(i-j))*parts(l[j]*adams(f,i-j+1),0,d)/i;
+            }
+            l=insert(l,q,size(l));
+            kill q;
+        }
+    }
+    return (l);
+}
+
+static proc schur(list p, poly f)
+{
+    int i,j;
+    int n = size(p);
+    matrix M[n][n];
+    for (i=1;i<=n;i++)
+    {
+        for (j=1;j<=n;j++)
+        {
+            M[i,j] = part(f,p[i]+j-i);
+        }
+    }
+    return (det(M));
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//////// Procedures concerned with abstract varieties //////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+
+proc printVariety(variety V)
+"USAGE:     printVariety(V); V variety
+ASSUME:     V is an abstract variety
+THEORY:     This is the print function used by Singular to print an abstract
+            variety.
+KEYWORDS:   abstract variety, projective space, Grassmannian
+EXAMPLE:    example printVariety; shows an example
+"
+{
+    "A variety of dimension", V.dimension;
+}
+example
+{
+    "EXAMPLE:"; echo=2;
+    ring r = 0,(h,e),wp(1,1);
+    ideal rels = he,h2+e2;
+    variety V = makeVariety(2,rels);
+    V;
+}
+
+proc makeVariety(int d, ideal i)
+"USAGE:     makeVariety(d,i); d int, i ideal
+ASSUME:     d is a nonnegative integer, i is an ideal
+RETURN:     variety
+THEORY:     create an abstract variety which has dimension d, and its Chow ring
+            should be a quotient ring
+KEYWORDS:   abstract variety, projective space, Grassmannian
+EXAMPLE:    example makeVariety; shows an example
+"
+{
+    def R = basering;
+    variety V;
+    V.dimension = d;
+    V.baseRing = R;
+    V.relations = i;
+    return(V);
+}
+example
+{
+    "EXAMPLE:"; echo=2;
+    ring r = 0,(h,e),wp(1,1);
+    ideal rels = he,h2+e2;
+    variety V = makeVariety(2,rels);
+    V;
+    V.dimension;
+    V.relations;
+}
+
+proc ChowRing(variety V)
+"USAGE:     ChowRing(V); V variety
+ASSUME:     V is an abstract variety
+RETURN:     qring
+KEYWORDS:   Chow ring, abstract variety, projective space, Grassmannian
+EXAMPLE:    example makeVariety; shows an example
+"
+{
+    def R = V.baseRing;
+    setring R;
+    ideal rels = V.relations;
+    qring CR = std(rels);
+    return (CR);
+}
+example
+{
+    "EXAMPLE:"; echo=2;
+    ring r = 0,(h,e),wp(1,1);
+    ideal rels = he,h2+e2;
+    int d = 2;
+    variety V = makeVariety(2,rels);
+    ChowRing(V);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+proc Grassmannian(int k, int n, list #)
+"USAGE:     Grassmannian(k,n); k int, n int
+RETURN:     variety
+THEORY:     create a Grassmannian G(k,n) as an abstract variety. This abstract
+            variety has diemnsion k(n-k) and its Chow ring is the quotient ring
+            of a polynomial ring in n-k variables q(1),...,q(n-k), which are the
+            Chern classes of tautological quotient bundle on G(k,n), modulo some
+            ideal generated by n-k polynomials which come from the Giambelli
+            formula. The monomial ordering of this Chow ring is 'wp' with vector
+            (1..k,1..n-k). Moreover, we export the Chern characters of
+            tautological subbundle and quotient bundle on G(k,n)
+            (say 'subBundle' and 'quotientBundle').
+KEYWORDS:   Grassmannian, abstract variety, Schubert calculus
+SEE ALSO:   projectiveSpace, projectiveBundle
+EXAMPLE:    example Grassmannian; shows examples
+"
+{
+    string q;
+    if (size(#)==0) {q = "q";}
+    else
+    {
+        if (typeof(#[1]) == "string") {q = #[1];}
+        else {Error("invalid optional argument");}
+    }
+    variety G;
+    G.dimension = k*(n-k);
+    execute("ring r = 0,("+q+"(1..n-k)),wp(1..n-k);");
+    setring r;
+    G.baseRing = r;
+    int i,j;
+    poly v = 1;
+    poly u = 1;
+    for (j=1;j<=n-k;j++) {v=v+q(j);}
+    list l;
+    for (i=1;i<=k;i++)
+    {
+        l=insert(l,1,size(l));
+        u=u+(-1)^i*schur(l,v);
+    }
+    l=insert(l,1,size(l));
+    ideal rels = schur(l,v);
+    int h = k+2;
+    while (h<=n)
+    {
+        l=insert(l,1,size(l));
+        rels = rels,schur(l,v);
+        h++;
+    }
+    G.relations = rels;
+    int d = k*(n-k);
+    poly subBundle = reduce(logg(u,d)+k,std(rels));
+    poly quotientBundle = reduce(logg(v,d)+n-k,std(rels));
+    export (subBundle,quotientBundle);
+    kill u,v,d,l,rels;
+    return (G);
+}
+example
+{
+    "EXAMPLE:"; echo=2;
+    variety G24 = Grassmannian(2,4);
+    G24;
+    def r = G24.baseRing;
+    setring r;
+    subBundle;
+    quotientBundle;
+    G24.dimension;
+    G24.relations;
+    ChowRing(G24);
+}
+
+proc projectiveSpace(int n, list #)
+"USAGE:     projectiveSpace(n); n int
+RETURN:     variety
+THEORY:     create a projective space of dimension n as an abstract variety. Its
+            Chow ring is a quotient ring in one variable h modulo the ideal
+            generated by h^(n+1).
+KEYWORDS:   projective space, abstract variety
+SEE ALSO:   Grassmannian, projectiveBundle
+EXAMPLE:    example projectiveSpace; shows examples
+"
+{
+    string h;
+    if (size(#)==0) {h = "h";}
+    else
+    {
+        if (typeof(#[1]) == "string") {h = #[1];}
+        else {Error("invalid optional argument");}
+    }
+    variety P;
+    P.dimension = n;
+    execute("ring r = 0, ("+h+"), wp(1);");
+    setring r;
+    P.baseRing = r;
+    ideal rels = var(1)^(n+1);
+    P.relations = rels;
+    poly u = 1;
+    poly v = 1 + var(1);
+    list l;
+    int i;
+    for (i=1;i<=n;i++)
+    {
+        l=insert(l,1,size(l));
+        u=u+(-1)^i*schur(l,v);
+    }
+    poly subBundle = reduce(logg(u,n)+n,std(rels));
+    poly quotientBundle = reduce(logg(v,n)+1,std(rels));
+    export(subBundle,quotientBundle);
+    kill rels,u,v,l;
+    return (P);
+}
+example
+{
+    "EXAMPLE:"; echo=2;
+    variety P = projectiveSpace(3);
+    P;
+    P.dimension;
+    def r = P.baseRing;
+    setring r;
+    P.relations;
+    ChowRing(P);
+}
+
+proc projectiveBundle(sheaf S, list #)
+"USAGE:     projectiveBundle(S); S sheaf
+INPUT:      a sheaf on an abstract variety
+RETURN:     variety
+THEORY:     create a projective bundle as an abstract variety. This is related
+            to the enumeration of conics.
+KEYWORDS:   projective bundle, abstract variety, sheaf, enumeration of conics
+SEE ALSO:   projectiveSpace, Grassmannian
+EXAMPLE:    example projectiveBundle; shows examples
+"
+{
+    string z;
+    if (size(#)==0) {z = "z";}
+    else
+    {
+        if (typeof(#[1]) == "string") {z = #[1];}
+        else {Error("invalid optional argument");}
+    }
+    variety A;
+    def B = S.currentVariety;
+    def R = B.baseRing;
+    setring R;
+    ideal rels = B.relations;
+    int r = rankSheaf(S);
+    A.dimension = r - 1 + B.dimension;
+    poly c = totalChernClass(S);
+    execute("ring P = 0, ("+z+"), wp(1);");
+    def CR = P + R;
+    setring CR;
+    A.baseRing = CR;
+    poly c = imap(R,c);
+    ideal rels = imap(R,rels);
+    poly g = var(1)^r;
+    int i;
+    for (i=1;i<=r;i++) {g=g+var(1)^(r-i)*part(c,i);}
+    A.relations = rels,g;
+    poly u = 1 + var(1);
+    poly f = logg(u,A.dimension)+1;
+    poly QuotientBundle = reduce(f,std(A.relations));
+    export (QuotientBundle);
+    kill f,rels;
+    return (A);
+}
+example
+{
+    "EXAMPLE:"; echo=2;
+    variety G = Grassmannian(3,5);
+    def r = G.baseRing;
+    setring r;
+    sheaf S = makeSheaf(G,subBundle);
+    sheaf B = dualSheaf(S)^2;
+    variety PB = projectiveBundle(B);
+    PB;
+    def R = PB.baseRing;
+    setring R;
+    QuotientBundle;
+    ChowRing(PB);
+}
+
+proc productVariety(variety U, variety V)
+"USAGE:     productVariety(U,V); U variety, V variety
+INPUT:      two abstract varieties
+OUTPUT:     a product variety as an abstract variety
+RETURN:     variety
+KEYWORDS:   product variety, abstract variety
+SEE ALSO:   projectiveSpace, Grassmannian, projectiveBundle
+EXAMPLE:    example productVariety; shows examples
+"
+{
+    //def br = basering;
+    def ur = U.baseRing; setring ur;
+    ideal ii1 = U.relations;
+    def vr = V.baseRing; setring vr;
+    ideal ii2 = V.relations;
+    variety W;
+    W.dimension = U.dimension + V.dimension;
+    def temp = ringtensor(ur,vr);
+    setring temp;
+    W.baseRing = temp;
+    ideal i1 = imap(ur,ii1);
+    ideal i2 = imap(vr,ii2);
+    W.relations = i1 + i2;
+    setring ur;
+    kill ii1;
+    setring vr;
+    kill ii2;
+    //setring br;
+    return (W);
+}
+example
+{
+    "EXAMPLE:"; echo=2;
+    variety P = projectiveSpace(3);
+    variety G = Grassmannian(2,4);
+    variety W = productVariety(P,G);
+    W;
+    W.dimension == P.dimension + G.dimension;
+    def r = W.baseRing;
+    setring r;
+    W.relations;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+proc integral(variety V, poly f)
+"USAGE:     integral(V,f); V variety, f poly
+INPUT:      a abstract variety and a polynomial
+RETURN:     int
+PURPOSE:    computing intersection numbers.
+EXAMPLE:    example integral; shows an example
+"
+{
+    def R = V.baseRing;
+    setring R;
+    ideal rels = V.relations;
+    return (leadcoef(reduce(f,std(rels))));
+}
+example
+{
+    "EXAMPLE:"; echo=2;
+    variety G = Grassmannian(2,4);
+    def r = G.baseRing;
+    setring r;
+    integral(G,q(1)^4);
+}
+
+proc SchubertClass(list p)
+"USAGE:     SchubertClass(p); p list
+INPUT:      a list of integers which is a partition
+RETURN:     poly
+PURPOSE:    compute the Schubert classes on a Grassmannian.
+EXAMPLE:    example SchubertClass; shows an example
+"
+{
+    def R = basering;
+    setring R;
+    poly f = 1;
+    if (size(p) == 0) {return (f);}
+    int i;
+    for (i=1;i<=nvars(R);i++)
+    {
+        f = f + var(i);
+    }
+    return (schur(p,f));
+}
+example
+{
+    "EXAMPLE:"; echo=2;
+    variety G = Grassmannian(2,4);
+    def r = G.baseRing;
+    setring r;
+    list p = 1,1;
+    SchubertClass(p);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+proc dualPartition(int k, int n, list p)
+"USAGE:     dualPartition(k,n,p); k int, n int, p list
+INPUT:      two integers and a partition
+RETURN:     list
+PURPOSE:    compute the dual of a partition.
+SEE ALSO:   SchubertClass
+EXAMPLE:    example dualPartition; shows an example
+"
+{
+    while (size(p) < k)
+    {
+        p = insert(p,0,size(p));
+    }
+    int i;
+    list l;
+    for (i=1;i<=size(p);i++)
+    {
+        l[i] = n-k-p[size(p)-i+1];
+    }
+    return (l);
+}
+example
+{
+    "EXAMPLE:"; echo=2;
+    ring r = 0,(x),dp;
+    dualPartition(2,4,list(2,1));
+}
+
+////////////////////////////////////////////////////////////////////////////////
+////////// Procedures concerned with abstract sheaves ///////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+
+proc printSheaf(sheaf S)
+"USAGE:     printSheaf(S); S sheaf
+RETURN:     string
+INPUT:      a sheaf
+THEORY:     This is the print function used by Singular to print a sheaf.
+SEE ALSO:   makeSheaf, rankSheaf
+EXAMPLE:    example printSheaf; shows an example
+"
+{
+    "A sheaf of rank ", rankSheaf(S);
+}
+example
+{
+    "EXAMPLE:"; echo=2;
+    variety X;
+    X.dimension = 4;
+    ring r = 0,(c(1..2),d(1..3)),wp(1..2,1..3);
+    setring r;
+    X.baseRing = r;
+    poly c = 1 + c(1) + c(2);
+    poly ch = 2 + logg(c,4);
+    sheaf S = makeSheaf(X,ch);
+    S;
+}
+
+proc makeSheaf(variety V, poly ch)
+"USAGE:     makeSheaf(V,ch); V variety, ch poly
+RETURN:     sheaf
+THEORY:     create a sheaf on an abstract variety, and its Chern character is
+            the polynomial ch.
+SEE ALSO:   printSheaf, rankSheaf
+EXAMPLE:    example makeSheaf; shows an example
+"
+{
+    def R = basering;
+    sheaf S;
+    S.currentVariety = V;
+    S.ChernCharacter = ch;
+    return(S);
+}
+example
+{
+    "EXAMPLE:"; echo=2;
+    variety X;
+    X.dimension = 4;
+    ring r = 0,(c(1..2),d(1..3)),wp(1..2,1..3);
+    setring r;
+    X.baseRing = r;
+    poly c = 1 + c(1) + c(2);
+    poly ch = 2 + logg(c,4);
+    sheaf S = makeSheaf(X,ch);
+    S;
+}
+
+proc rankSheaf(sheaf S)
+"USAGE:     rankSheaf(S); S sheaf
+RETURN:     int
+INPUT:      S is a sheaf
+OUTPUT:     a positive integer which is the rank of a sheaf.
+SEE ALSO:   makeSheaf, printSheaf
+EXAMPLE:    example rankSheaf; shows an example
+"
+{
+    variety V = S.currentVariety;
+    def R = V.baseRing;
+    setring R;
+    poly f = S.ChernCharacter;
+    return (int(part(f,0)));
+}
+example
+{
+    "EXAMPLE:"; echo=2;
+    variety G = Grassmannian(2,4);
+    def R = G.baseRing;
+    setring R;
+    sheaf S = makeSheaf(G,subBundle);
+    rankSheaf(S);
+}
+
+proc totalChernClass(sheaf S)
+"USAGE:     totalChernClass(S); S sheaf
+RETURN:     poly
+INPUT:      S is a sheaf
+OUTPUT:     a polynomial which is the total Chern class of a sheaf
+SEE ALSO:   totalSegreClass, topChernClass, ChernClass
+EXAMPLE:    example totalChernClass; shows an example
+"
+{
+    variety V = S.currentVariety;
+    int d = V.dimension;
+    def R = V.baseRing;
+    setring R;
+    poly ch = S.ChernCharacter;
+    poly f = expp(ch,d);
+    ideal rels = std(V.relations);
+    return (reduce(f,rels));
+}
+example
+{
+    "EXAMPLE:"; echo=2;
+    variety X;
+    X.dimension = 4;
+    ring r = 0,(c(1..2),d(1..3)),wp(1..2,1..3);
+    setring r;
+    X.baseRing = r;
+    poly c = 1 + c(1) + c(2);
+    poly ch = 2 + logg(c,4);
+    sheaf E = makeSheaf(X,ch);
+    sheaf S = E^3;
+    totalChernClass(S);
+}
+
+proc ChernClass(sheaf S, int i)
+"USAGE:     ChernClass(S,i); S sheaf, i int
+INPUT:      S is a sheaf, i is a nonnegative integer
+RETURN:     poly
+THEORY:     This is the i-th Chern class of a sheaf
+SEE ALSO:   topChernClass, totalChernClass
+EXAMPLE:    example ChernClass; shows an example
+"
+{
+    return (part(totalChernClass(S),i));
+}
+example
+{
+    "EXAMPLE:"; echo=2;
+    variety X;
+    X.dimension = 4;
+    ring r = 0,(c(1..2),d(1..3)),wp(1..2,1..3);
+    setring r;
+    X.baseRing = r;
+    poly c = 1 + c(1) + c(2);
+    poly ch = 2 + logg(c,4);
+    sheaf E = makeSheaf(X,ch);
+    sheaf S = E^3;
+    ChernClass(S,1);
+    ChernClass(S,2);
+    ChernClass(S,3);
+    ChernClass(S,4);
+}
+
+proc topChernClass(sheaf S)
+"USAGE:     topChernClass(S); S sheaf
+RETURN:     poly
+INPUT:      S is a sheaf
+THEORY:     This is the top Chern class of a sheaf
+SEE ALSO:   ChernClass, totalChernClass
+EXAMPLE:    example topChernClass; shows an example
+"
+{
+    return (ChernClass(S,rankSheaf(S)));
+}
+example
+{
+    "EXAMPLE:"; echo=2;
+    variety G = Grassmannian(2,4);
+    def R = G.baseRing;
+    setring R;
+    sheaf S = makeSheaf(G,quotientBundle);
+    sheaf B = S^3;
+    topChernClass(B);
+}
+
+proc totalSegreClass(sheaf S)
+"USAGE:     totalSegreClass(S); S sheaf
+RETURN:     poly
+INPUT:      S is a sheaf
+THEORY:     This is the total Segre class of a sheaf.
+SEE AlSO:   totalChernClass
+EXAMPLE:    example totalSegreClass; shows an example
+"
+{
+    //def D = dualSheaf(S);
+    variety V = S.currentVariety;
+    def R = V.baseRing;
+    setring R;
+    poly f = totalChernClass(S);
+    poly g;
+    int d = V.dimension;
+    ideal rels = std(V.relations);
+    if (f == 1) {return (1);}
+    else
+    {
+        poly t,h;
+        int i,j;
+        for (i=0;i<=d;i++) {t = t + (1-f)^i;}
+        for (j=0;j<=d;j++) {h = h + part(t,j);}
+        return (reduce(h,rels));
+    }
+}
+example
+{
+    "EXAMPLE:"; echo=2;
+    variety G = Grassmannian(2,4);
+    def R = G.baseRing;
+    setring R;
+    sheaf S = makeSheaf(G,subBundle);
+    totalSegreClass(S);
+}
+
+proc dualSheaf(sheaf S)
+"USAGE:     dualSheaf(S); S sheaf
+RETURN:     sheaf
+THEORY:     This is the dual of a sheaf
+SEE ALSO:   addSheaf, symmetricPowerSheaf, tensorSheaf, quotSheaf
+EXAMPLE:    example dualSheaf; shows examples
+"
+{
+    variety V = S.currentVariety;
+    int d = V.dimension;
+    def R = V.baseRing;
+    setring R;
+    poly ch = S.ChernCharacter;
+    poly f = adams(ch,-1);
+    sheaf D;
+    D.currentVariety = V;
+    D.ChernCharacter = f;
+    return (D);
+}
+example
+{
+    "EXAMPLE:"; echo=2;
+    variety G = Grassmannian(2,4);
+    def R = G.baseRing;
+    setring R;
+    sheaf S = makeSheaf(G,subBundle);
+    sheaf D = dualSheaf(S);
+    D;
+}
+
+proc tensorSheaf(sheaf A, sheaf B)
+"USAGE:     tensorSheaf(A,B); A sheaf, B sheaf
+RETURN:     sheaf
+THEORY:     This is the tensor product of two sheaves
+SEE ALSO:   addSheaf, symmetricPowerSheaf, quotSheaf, dualSheaf
+EXAMPLE:    example tensorSheaf; shows examples
+"
+{
+    sheaf S;
+    variety V1 = A.currentVariety;
+    variety V2 = B.currentVariety;
+    def R1 = V1.baseRing;
+    setring R1;
+    poly c1 = A.ChernCharacter;
+    def R2 = V2.baseRing;
+    setring R2;
+    poly c2 = B.ChernCharacter;
+    if (nvars(R1) < nvars(R2))
+    {
+        S.currentVariety = V2;
+        poly c = imap(R1,c1);
+        poly f = parts(c*c2,0,V2.dimension);
+        S.ChernCharacter = f;
+        return (S);
+    }
+    else
+    {
+        setring R1;
+        S.currentVariety = V1;
+        poly c = imap(R2,c2);
+        poly f = parts(c1*c,0,V1.dimension);
+        S.ChernCharacter = f;
+        return (S);
+    }
+}
+example
+{
+    "EXAMPLE:"; echo=2;
+    variety G = Grassmannian(3,4);
+    def R = G.baseRing;
+    setring R;
+    sheaf S = makeSheaf(G,subBundle);
+    sheaf Q = makeSheaf(G,quotientBundle);
+    sheaf T = S*Q;
+    T;
+}
+
+proc symmetricPowerSheaf(sheaf S, int n)
+"USAGE:     symmetricPowerSheaf(S,n); S sheaf, n int
+RETURN:     sheaf
+THEORY:     This is the n-th symmetric power of a sheaf
+SEE ALSO:   quotSheaf, addSheaf, tensorSheaf, dualSheaf
+EXAMPLE:    example symmetricPowerSheaf; shows examples
+"
+{
+    variety V = S.currentVariety;
+    def R = V.baseRing;
+    setring R;
+    int r = rankSheaf(S);
+    int d = V.dimension;
+    int i,j,m;
+    poly f = S.ChernCharacter;
+    poly result;
+    list s,w;
+    if (n==0) {result=1;}
+    if (n==1) {result=f;}
+    else
+    {
+        s = 1,f;
+        w = wedges(n,f,d);
+        for (i=2;i<=n;i++)
+        {
+            if (i<=r) {m=i;}
+            else {m=r;}
+            poly q;
+            for (j=1;j<=m;j++)
+            {
+                q = q + ((-1)^(j+1))*parts(w[j+1]*s[i-j+1],0,d);
+            }
+            s = insert(s,q,size(s));
+            kill q;
+        }
+        result = s[n+1];
+    }
+    sheaf A;
+    A.currentVariety = V;
+    A.ChernCharacter = result;
+    return (A);
+}
+example
+{
+    "EXAMPLE:"; echo=2;
+    variety G = Grassmannian(2,4);
+    def R = G.baseRing;
+    setring R;
+    sheaf S = makeSheaf(G,quotientBundle);
+    sheaf B = symmetricPowerSheaf(S,3);
+    B;
+    sheaf A = S^3;
+    A;
+    A.ChernCharacter == B.ChernCharacter;
+}
+
+proc quotSheaf(sheaf A, sheaf B)
+"USAGE:     quotSheaf(A,B); A sheaf, B sheaf
+RETURN:     sheaf
+THEORY:     This is the quotient of two sheaves
+SEE ALSO:   addSheaf, symmetricPowerSheaf, tensorSheaf, dualSheaf
+EXAMPLE:    example quotSheaf; shows an example
+"
+{
+    sheaf S;
+    variety V1 = A.currentVariety;
+    variety V2 = B.currentVariety;
+    def R1 = V1.baseRing;
+    setring R1;
+    poly c1 = A.ChernCharacter;
+    def R2 = V2.baseRing;
+    setring R2;
+    poly c2 = B.ChernCharacter;
+    if (nvars(R1) < nvars(R2))
+    {
+        S.currentVariety = V2;
+        poly c = imap(R1,c1);
+        S.ChernCharacter = c - c2;
+        return (S);
+    }
+    else
+    {
+        setring R1;
+        S.currentVariety = V1;
+        poly c = imap(R2,c2);
+        S.ChernCharacter = c1 - c;
+        return (S);
+    }
+}
+example
+{
+    "EXAMPLE:"; echo=2;
+    variety G = Grassmannian(3,5);
+    def r = G.baseRing;
+    setring r;
+    sheaf S = makeSheaf(G,subBundle);
+    sheaf B = dualSheaf(S)^2;
+    sheaf B3 = dualSheaf(S)^3;
+    sheaf B5 = dualSheaf(S)^5;
+    variety PB = projectiveBundle(B);
+    def R = PB.baseRing;
+    setring R;
+    sheaf Q = makeSheaf(PB,QuotientBundle);
+    sheaf V = dualSheaf(Q)*B3;
+    sheaf A = B5 - V;
+    A;
+}
+
+proc addSheaf(sheaf A, sheaf B)
+"USAGE:     addSheaf(A,B); A sheaf, B sheaf
+RETURN:     sheaf
+THEORY:     This is the direct sum of two sheaves.
+SEE ALSO:   quotSheaf, symmetricPowerSheaf, tensorSheaf, dualSheaf
+EXAMPLE:    example addSheaf; shows an example
+"
+{
+    sheaf S;
+    variety V1 = A.currentVariety;
+    variety V2 = B.currentVariety;
+    def R1 = V1.baseRing;
+    setring R1;
+    poly c1 = A.ChernCharacter;
+    def R2 = V2.baseRing;
+    setring R2;
+    poly c2 = B.ChernCharacter;
+    if (nvars(R1) < nvars(R2))
+    {
+        S.currentVariety = V2;
+        poly c = imap(R1,c1);
+        S.ChernCharacter = c + c2;
+        return (S);
+    }
+    else
+    {
+        setring R1;
+        S.currentVariety = V1;
+        poly c = imap(R2,c2);
+        S.ChernCharacter = c1 + c;
+        return (S);
+    }
+}
+example
+{
+    "EXAMPLE:"; echo=2;
+    variety G = Grassmannian(3,5);
+    def r = G.baseRing;
+    setring r;
+    sheaf S = makeSheaf(G,subBundle);
+    sheaf Q = makeSheaf(G,quotientBundle);
+    sheaf D = S + Q;
+    D;
+    D.ChernCharacter == rankSheaf(D);
+    totalChernClass(D) == 1;
+}
diff --git a/Singular/LIB/sheafcoh.lib b/Singular/LIB/sheafcoh.lib
new file mode 100644
index 0000000..49369cd
--- /dev/null
+++ b/Singular/LIB/sheafcoh.lib
@@ -0,0 +1,1423 @@
+///////////////////////////////////////////////////////////////////////////
+version="version sheafcoh.lib 4.0.0.0 Jun_2013 "; // $Id: c0577e2b763b7bfef8765736dbf314e8c1b6ed57 $
+category="Commutative Algebra";
+info="
+LIBRARY:  sheafcoh.lib   Procedures for Computing Sheaf Cohomology
+AUTHORS:  Wolfram Decker, decker at mathematik.uni-kl.de
+          Christoph Lossen,  lossen at mathematik.uni-kl.de
+          Gerhard Pfister,  pfister at mathematik.uni-kl.de
+          Oleksandr Motsak, U at D, where U={motsak}, D={mathematik.uni-kl.de}
+
+PROCEDURES:
+ truncate(phi,d);        truncation of coker(phi) at d
+ truncateFast(phi,d);    truncation of coker(phi) at d (fast+ experimental)
+ CM_regularity(M);       Castelnuovo-Mumford regularity of coker(M)
+ sheafCohBGG(M,l,h);     cohomology of sheaf associated to coker(M)
+ sheafCohBGG2(M,l,h);    cohomology of sheaf associated to coker(M), experimental version
+ sheafCoh(M,l,h);        cohomology of sheaf associated to coker(M)
+ dimH(i,M,d);            compute h^i(F(d)), F sheaf associated to coker(M)
+ dimGradedPart()
+
+ displayCohom(B,l,h,n);  display intmat as Betti diagram (with zero rows)
+
+KEYWORDS: sheaf cohomology
+";
+
+///////////////////////////////////////////////////////////////////////////////
+LIB "matrix.lib";
+LIB "nctools.lib";
+LIB "homolog.lib";
+
+
+///////////////////////////////////////////////////////////////////////////////
+static proc jacobM(matrix M)
+{
+   int n=nvars(basering);
+   matrix B=transpose(diff(M,var(1)));
+   int i;
+   for(i=2;i<=n;i++)
+   {
+     B=concat(B,transpose(diff(M,var(i))));
+   }
+   return(transpose(B));
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+/**
+  let M = { w_1, ..., w_k }, k = size(M) == ncols(M), n = nvars(currRing).
+  assuming that nrows(M) <= m*n;
+  computes transpose(M) * transpose( var(1) I_m | ... | var(n) I_m ) :== transpose(module{f_1, ... f_k}),
+  where f_i = \sum_{j=1}^{m} (w_i, v_j) gen(j),  (w_i, v_j) is a `scalar` multiplication.
+  that is, if w_i = (a^1_1, ... a^1_m) | (a^2_1, ..., a^2_m) | ... | (a^n_1, ..., a^n_m) then
+
+  (a^1_1, ... a^1_m) | (a^2_1, ..., a^2_m) | ... | (a^n_1, ..., a^n_m)
+*  var_1  ... var_1  |  var_2  ...  var_2  | ... |  var_n  ...  var(n)
+*  gen_1  ... gen_m  |  gen_1  ...  gen_m  | ... |  gen_1  ...  gen_m
++ =>
+  f_i =
+
+   a^1_1 * var(1) * gen(1) + ... + a^1_m * var(1) * gen(m) +
+   a^2_1 * var(2) * gen(1) + ... + a^2_m * var(2) * gen(m) +
+                             ...
+   a^n_1 * var(n) * gen(1) + ... + a^n_m * var(n) * gen(m);
+
+   NOTE: for every f_i we run only ONCE along w_i saving partial sums into a temporary array of polys of size m
+
+*/
+static proc TensorModuleMult(int m, module M)
+{
+  return( system("tensorModuleMult", m, M) ); // trick!
+
+  int n = nvars(basering);
+  int k = ncols(M);
+
+  int g, cc, vv;
+
+  poly h;
+
+  module Temp; // = {f_1, ..., f_k }
+
+  intvec exp;
+  vector pTempSum, w;
+
+  for( int i = k; i > 0; i-- ) // for every w \in M
+  {
+    pTempSum[m] = 0;
+    w = M[i];
+
+    while(w != 0) // for each term of w...
+    {
+      exp = leadexp(w);
+      g = exp[n+1]; // module component!
+      h = w[g];
+
+      w = w - h * gen(g);
+
+      cc = g % m;
+
+      if( cc == 0)
+      {
+        cc = m;
+      }
+
+      vv = 1 + (g - cc) / m;
+
+      pTempSum = pTempSum + h * var(vv) * gen(cc);
+    }
+
+    Temp[i] = pTempSum;
+  }
+
+  Temp = transpose(Temp);
+
+  return(Temp);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+proc truncate(module phi, int d)
+"USAGE:   truncate(M,d);  M module, d int
+ASSUME:  @code{M} is graded, and it comes assigned with an admissible degree
+         vector as an attribute
+RETURN:  module
+NOTE:    Output is a presentation matrix for the truncation of coker(M)
+         at degree d.
+EXAMPLE: example truncate; shows an example
+KEYWORDS: truncated module
+"
+{
+  if ( typeof(attrib(phi,"isHomog"))=="string" ) {
+    if (size(phi)==0) {
+      // assign weights 0 to generators of R^n (n=nrows(phi))
+      intvec v;
+      v[nrows(phi)]=0;
+      attrib(phi,"isHomog",v);
+    }
+    else {
+      ERROR("No admissible degree vector assigned");
+    }
+  }
+  else {
+   intvec v=attrib(phi,"isHomog");
+  }
+  int i,m,dummy;
+  int s = nrows(phi);
+  module L; // TOO BIG!!!
+  for (i=1; i<=s; i++) {
+    if (d>v[i]) {
+      L = L+maxideal(d-v[i])*gen(i);
+    }
+    else {
+      L = L+gen(i);
+    }
+  }
+  L = modulo(L,phi);
+  L = minbase(prune(L));
+  if (size(L)==0) {return(L);}
+
+  // it only remains to set the degrees for L:
+  // ------------------------------------------
+  m = v[1];
+  for(i=2; i<=size(v); i++) {  if(v[i]<m) { m = v[i]; } }
+  dummy = homog(L);
+  intvec vv = attrib(L,"isHomog");
+  if (d>m) { vv = vv+d; }
+  else     { vv = vv+m; }
+  attrib(L,"isHomog",vv);
+  return(L);
+}
+example
+{"EXAMPLE:";
+   echo = 2;
+   ring R=0,(x,y,z),dp;
+   module M=maxideal(3);
+   homog(M);
+   // compute presentation matrix for truncated module (R/<x,y,z>^3)_(>=2)
+   module M2=truncate(M,2);
+   print(M2);
+   dimGradedPart(M2,1);
+   dimGradedPart(M2,2);
+   // this should coincide with:
+   dimGradedPart(M,2);
+   // shift grading by 1:
+   intvec v=1;
+   attrib(M,"isHomog",v);
+   M2=truncate(M,2);
+   print(M2);
+   dimGradedPart(M2,3);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc truncateFast(module M, int d)
+"USAGE:   truncateFast(M,d);  M module, d int
+ASSUME:  @code{M} is graded, and it comes assigned with an admissible degree
+         vector as an attribute 'isHomog'
+RETURN:  module
+NOTE:    Output is a presentation matrix for the truncation of coker(M)
+         at d.
+         Fast + experimental version. M shoud be a SB!
+DISPLAY: If @code{printlevel}>=1, step-by step timings will be printed.
+         If @code{printlevel}>=2 we add progress debug messages
+         if @code{printlevel}>=3, even all intermediate results...
+EXAMPLE: example truncateFast; shows an example
+KEYWORDS: truncated module
+"
+{
+//  int PL = printlevel + 1;
+  int PL = printlevel - voice + 2;
+
+  dbprint(PL-1, "// truncateFast(M: "+ string(nrows(M)) + " x " + string(ncols(M)) +", " + string(d) + "):");
+  dbprint(PL-2, M);
+
+  intvec save = option(get);
+  if( PL >= 2 )
+  {
+    option(prot);
+    option(mem);
+  }
+
+  int tTruncateBegin=timer;
+
+  if (attrib(M,"isSB")!=1)
+  {
+    ERROR("M must be a standard basis!");
+  }
+
+  dbprint(PL-1, "// M is a SB! ");
+
+  if ( typeof(attrib(M,"isHomog"))=="string" ) {
+    if (size(M)==0) {
+      // assign weights 0 to generators of R^n (n=nrows(M))
+      intvec v;
+      v[nrows(M)]=0;
+      attrib(M,"isHomog",v);
+    }
+    else {
+      ERROR("No admissible degree vector assigned");
+    }
+  }
+  else {
+   intvec v=attrib(M,"isHomog");
+  }
+
+  dbprint(PL-1, "// weighting(M): ["+ string(v) + "]");
+
+  int i,m,dummy;
+  int s = nrows(M);
+
+   int tKBaseBegin = timer;
+    module L = kbase(M, d); // TODO: check whether this is always correct!?!
+
+
+    dbprint(PL-1, "// L = kbase(M,d): "+string(nrows(L)) + " x " + string(ncols(L)) +"");
+    dbprint(PL-2, L);
+    dbprint(PL-1, "// weighting(L): ["+ string(attrib(L, "isHomog")) + "]");
+
+   int tModuloBegin = timer;
+    L = modulo(L,M);
+
+    dbprint(PL-1, "// L = modulo(L,M): "+string(nrows(L)) + " x " + string(ncols(L)) +"");
+    dbprint(PL-2, L);
+    dbprint(PL-1, "// weighting(L): ["+ string(attrib(L, "isHomog")) + "]");
+
+   int tPruneBegin = timer;
+    L = prune(L);
+
+    dbprint(PL-1, "// L = prune(L): "+string(nrows(L)) + " x " + string(ncols(L)) +"");
+    dbprint(PL-2, L);
+    dbprint(PL-1, "// weighting(L): ["+ string(attrib(L, "isHomog")) + "]");
+
+   int tPruneEnd = timer;
+    L = minbase(L);
+   int tMinBaseEnd = timer;
+
+    dbprint(PL-1, "// L = minbase(L): "+string(nrows(L)) + " x " + string(ncols(L)) +"");
+    dbprint(PL-2, L);
+    dbprint(PL-1, "// weighting(L): ["+ string(attrib(L, "isHomog")) + "]");
+
+
+
+
+  if (size(L)!=0)
+  {
+
+    // it only remains to set the degrees for L:
+    // ------------------------------------------
+    m = v[1];
+    for(i=2; i<=size(v); i++) {  if(v[i]<m) { m = v[i]; } }
+    dummy = homog(L);
+    intvec vv = attrib(L,"isHomog");
+    if (d>m) { vv = vv+d; }
+    else     { vv = vv+m; }
+    attrib(L,"isHomog",vv);
+  }
+
+  int tTruncateEnd=timer;
+
+  dbprint(PL-1, "// corrected weighting(L): ["+ string(attrib(L, "isHomog")) + "]");
+
+
+  if(PL > 0)
+  {
+  "
+  -------------- TIMINGS --------------
+  Trunc        Time: ", tTruncateEnd - tTruncateBegin, "
+    :: Before .Time: ", tKBaseBegin - tTruncateBegin, "
+    :: kBase   Time: ", tModuloBegin - tKBaseBegin, "
+    :: Modulo  Time: ", tPruneBegin - tModuloBegin, "
+    :: Prune   Time: ", tPruneEnd - tPruneBegin, "
+    :: Minbase Time: ", tMinBaseEnd - tPruneEnd, "
+    :: After  .Time: ", tTruncateEnd - tMinBaseEnd;
+  }
+
+  option(set, save);
+
+  return(L);
+}
+example
+{"EXAMPLE:";
+   echo = 2;
+   ring R=0,(x,y,z,u,v),dp;
+   module M=maxideal(3);
+   homog(M);
+   // compute presentation matrix for truncated module (R/<x,y,z,u>^3)_(>=2)
+   int t=timer;
+   module M2t=truncate(M,2);
+   t = timer - t;
+   "// Simple truncate: ", t;
+   t=timer;
+   module M2=truncateFast(std(M),2);
+   t = timer - t;
+   "// Fast truncate: ", t;
+   print(M2);
+   "// Check: M2t == M2?: ", size(NF(M2, std(M2t))) + size(NF(M2t, std(M2)));
+
+   dimGradedPart(M2,1);
+   dimGradedPart(M2,2);
+   // this should coincide with:
+   dimGradedPart(M,2);
+   // shift grading by 1:
+   intvec v=1;
+   attrib(M,"isHomog",v);
+   t=timer;
+   M2t=truncate(M,2);
+   t = timer - t;
+   "// Simple truncate: ", t;
+   t=timer;
+   M2=truncateFast(std(M),2);
+   t = timer - t;
+   "// Fast truncate: ", t;
+   print(M2);
+   "// Check: M2t == M2?: ", size(NF(M2, std(M2t))) + size(NF(M2t, std(M2))); //?
+   dimGradedPart(M2,3);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+
+
+
+
+proc dimGradedPart(module phi, int d)
+"USAGE:   dimGradedPart(M,d);  M module, d int
+ASSUME:  @code{M} is graded, and it comes assigned with an admissible degree
+         vector as an attribute
+RETURN:  int
+NOTE:    Output is the vector space dimension of the graded part of degree d
+         of coker(M).
+EXAMPLE: example dimGradedPart; shows an example
+KEYWORDS: graded module, graded piece
+"
+{
+  if ( typeof(attrib(phi,"isHomog"))=="string" ) {
+    if (size(phi)==0) {
+      // assign weights 0 to generators of R^n (n=nrows(phi))
+      intvec v;
+      v[nrows(phi)]=0;
+    }
+    else { ERROR("No admissible degree vector assigned"); }
+  }
+  else {
+    intvec v=attrib(phi,"isHomog");
+  }
+  int s = nrows(phi);
+  int i,m,dummy;
+  module L,LL;
+  for (i=1; i<=s; i++) {
+    if (d>v[i]) {
+      L = L+maxideal(d-v[i])*gen(i);
+      LL = LL+maxideal(d+1-v[i])*gen(i);
+    }
+    else {
+      L = L+gen(i);
+      if (d==v[i]) {
+        LL = LL+maxideal(1)*gen(i);
+      }
+      else {
+        LL = LL+gen(i);
+      }
+    }
+  }
+  LL=LL,phi;
+  L = modulo(L,LL);
+  L = std(prune(L));
+  if (size(L)==0) {return(0);}
+  return(vdim(L));
+}
+example
+{"EXAMPLE:";
+   echo = 2;
+   ring R=0,(x,y,z),dp;
+   module M=maxideal(3);
+   // assign compatible weight vector (here: 0)
+   homog(M);
+   // compute dimension of graded pieces of R/<x,y,z>^3 :
+   dimGradedPart(M,0);
+   dimGradedPart(M,1);
+   dimGradedPart(M,2);
+   dimGradedPart(M,3);
+   // shift grading:
+   attrib(M,"isHomog",intvec(2));
+   dimGradedPart(M,2);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc CM_regularity (module M)
+"USAGE:   CM_regularity(M);    M module
+ASSUME:   @code{M} is graded, and it comes assigned with an admissible degree
+         vector as an attribute
+RETURN:  integer, the Castelnuovo-Mumford regularity of coker(M)
+NOTE:    procedure calls mres
+EXAMPLE: example CM_regularity; shows an example
+KEYWORDS: Castelnuovo-Mumford regularity
+"
+{
+  if ( typeof(attrib(M,"isHomog"))=="string" ) {
+    if (size(M)==0) {
+      // assign weights 0 to generators of R^n (n=nrows(M))
+      intvec v;
+      v[nrows(M)]=0;
+      attrib(M,"isHomog",v);
+    }
+    else {
+      ERROR("No admissible degree vector assigned");
+    }
+  }
+
+  if( attrib(CM_regularity,"Algorithm") == "minres_res" )
+  {
+    def L = minres( res(M,0) ); // let's try it out!
+  } else
+  {
+    def L = mres(M,0);
+  }
+
+  intmat BeL = betti(L);
+  int r = nrows(module(matrix(BeL)));  // last non-zero row
+  if (typeof(attrib(BeL,"rowShift"))!="string") {
+    int shift = attrib(BeL,"rowShift");
+  }
+  return(r+shift-1);
+}
+example
+{"EXAMPLE:";
+   echo = 2;
+   ring R=0,(x,y,z,u),dp;
+   resolution T1=mres(maxideal(1),0);
+   module M=T1[3];
+   intvec v=2,2,2,2,2,2;
+   attrib(M,"isHomog",v);
+   CM_regularity(M);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+proc sheafCohBGG(module M,int l,int h)
+"USAGE:   sheafCohBGG(M,l,h);    M module, l,h int
+ASSUME:  @code{M} is graded, and it comes assigned with an admissible degree
+         vector as an attribute, @code{h>=l}, and the basering has @code{n+1}
+         variables.
+RETURN:  intmat, cohomology of twists of the coherent sheaf F on P^n
+         associated to coker(M). The range of twists is determined by @code{l},
+         @code{h}.
+DISPLAY: The intmat is displayed in a diagram of the following form: @*
+  @format
+                l            l+1                      h
+  ----------------------------------------------------------
+      n:     h^n(F(l))    h^n(F(l+1))   ......    h^n(F(h))
+           ...............................................
+      1:     h^1(F(l))    h^1(F(l+1))   ......    h^1(F(h))
+      0:     h^0(F(l))    h^0(F(l+1))   ......    h^0(F(h))
+  ----------------------------------------------------------
+    chi:     chi(F(l))    chi(F(l+1))   ......    chi(F(h))
+  @end format
+         A @code{'-'} in the diagram refers to a zero entry; a @code{'*'}
+         refers to a negative entry (= dimension not yet determined).
+         refers to a not computed dimension. @*
+NOTE:    This procedure is based on the Bernstein-Gel'fand-Gel'fand
+         correspondence and on Tate resolution ( see [Eisenbud, Floystad,
+         Schreyer: Sheaf cohomology and free resolutions over exterior
+         algebras, Trans AMS 355 (2003)] ).@*
+         @code{sheafCohBGG(M,l,h)} does not compute all values in the above
+         table. To determine all values of @code{h^i(F(d))}, @code{d=l..h},
+         use @code{sheafCohBGG(M,l-n,h+n)}.
+SEE ALSO: sheafCoh, dimH
+EXAMPLE: example sheafCohBGG; shows an example
+"
+{
+  int i,j,k,row,col;
+  if( typeof(attrib(M,"isHomog"))!="intvec" )
+  {
+     if (size(M)==0) { attrib(M,"isHomog",0); }
+     else { ERROR("No admissible degree vector assigned"); }
+  }
+  int n=nvars(basering)-1;
+  int ell=l+n;
+  def R=basering;
+  int reg = CM_regularity(M);
+  int bound=max(reg+1,h-1);
+  module MT=truncate(M,bound);
+  int m=nrows(MT);
+  MT=transpose(jacobM(MT));
+  MT=syz(MT);
+  matrix ML[n+1][1]=maxideal(1);
+  matrix S=transpose(outer(ML,unitmat(m)));
+  matrix SS=transpose(S*MT);
+  //--- to the exterior algebra
+  def AR = Exterior();
+  setring AR;
+  intvec saveopt=option(get);
+  option(redSB);
+  option(redTail);
+  module EM=imap(R,SS);
+  intvec w;
+  //--- here we are with our matrix
+  int bound1=max(1,bound-ell+1);
+  for (i=1; i<=nrows(EM); i++)
+  {
+     w[i]=-bound-1;
+  }
+  attrib(EM,"isHomog",w);
+  resolution RE=mres(EM,bound1);
+  intmat Betti=betti(RE);
+  k=ncols(Betti);
+  row=nrows(Betti);
+  int shift=attrib(Betti,"rowShift")+(k+ell-1);
+  intmat newBetti[n+1][h-l+1];
+  for (j=1; j<=row; j++)
+  {
+    for (i=l; i<=h; i++)
+    {
+      if ((k+1-j-i+ell-shift>0) and (j+i-ell+shift>=1))
+      {
+        newBetti[n+2-shift-j,i-l+1]=Betti[j,k+1-j-i+ell-shift];
+      }
+      else { newBetti[n+2-shift-j,i-l+1]=-1; }
+    }
+  }
+  for (j=2; j<=n+1; j++)
+  {
+    for (i=1; i<j; i++)
+    {
+      newBetti[j,i]=-1;
+    }
+  }
+  int d=k-h+ell-1;
+  for (j=1; j<=n; j++)
+  {
+    for (i=h-l+1; i>=k+j; i--)
+    {
+      newBetti[j,i]=-1;
+    }
+  }
+  displayCohom(newBetti,l,h,n);
+  option(set,saveopt);
+  setring R;
+  return(newBetti);
+}
+example
+{"EXAMPLE:";
+   echo = 2;
+   // cohomology of structure sheaf on P^4:
+   //-------------------------------------------
+   ring r=0,x(1..5),dp;
+   module M=0;
+   def A=sheafCohBGG(M,-9,4);
+   // cohomology of cotangential bundle on P^3:
+   //-------------------------------------------
+   ring R=0,(x,y,z,u),dp;
+   resolution T1=mres(maxideal(1),0);
+   module M=T1[3];
+   intvec v=2,2,2,2,2,2;
+   attrib(M,"isHomog",v);
+   def B=sheafCohBGG(M,-8,4);
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+static proc showResult( def R, int l, int h )
+{
+  int PL = 1; // printlevel - voice + 2;
+// int PL = printlevel + 1;
+
+  intmat Betti;
+  if(typeof(R)=="resolution")
+  {
+    Betti = betti(R);
+  } else
+  {
+    if(typeof(R)!="intmat")
+    {
+      ERROR("Wrong input!!!");
+    }
+
+    Betti = R;
+  }
+
+  int n=nvars(basering)-1;
+  int ell = l + n;
+
+  int k     = ncols(Betti);
+  int row   = nrows(Betti);
+  int shift = attrib(Betti,"rowShift") + (k + ell - 1);
+
+  int iWTH = h-l+1;
+
+  int d = k - h + ell - 1;
+
+  if( PL > 1 )
+  {
+    "// l: ", l;
+    "// h: ", h;
+    "// n: ", n;
+    "// ell: ", ell;
+    "// k: ", k;
+    "// row: ", row;
+    "// shift: ", shift;
+    "// iWTH: ", iWTH;
+    "// d: ", d;
+  }
+
+  intmat newBetti[ n + 1 ][ iWTH ];
+  int i, j;
+
+  for (j=1; j<=row; j++) {
+    for (i=l; i<=h; i++) {
+      if( (n+2-shift-j)>0 ) {
+
+        if (  (k+1-j-i+ell-shift>0) and (j+i-ell+shift>=1)) {
+          newBetti[n+2-shift-j,i-l+1]=Betti[j,k+1-j-i+ell-shift];
+        }
+        else { newBetti[n+2-shift-j,i-l+1]=-1; }
+
+      }
+    }
+  }
+
+  for (j=2; j<=n+1; j++) {
+    for (i=1; i<min(j, iWTH); i++) {
+      newBetti[j,i]= -1;
+    }
+  }
+
+  for (j=1; j<=n; j++) {
+    for (i=iWTH; i>=k+j; i--) {
+      newBetti[j,i]=0; // -1;
+    }
+  }
+
+  if( PL > 0 )
+  {
+    "Cohomology table:";
+    displayCohom(newBetti, l, h, n);
+  }
+
+  return(newBetti);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+proc sheafCohBGG2(module M,int l,int h)
+"USAGE:   sheafCohBGG2(M,l,h);    M module, l,h int
+ASSUME:  @code{M} is graded, and it comes assigned with an admissible degree
+         vector as an attribute, @code{h>=l}, and the basering has @code{n+1}
+         variables.
+RETURN:  intmat, cohomology of twists of the coherent sheaf F on P^n
+         associated to coker(M). The range of twists is determined by @code{l},
+         @code{h}.
+DISPLAY: The intmat is displayed in a diagram of the following form: @*
+  @format
+                l            l+1                      h
+  ----------------------------------------------------------
+      n:     h^n(F(l))    h^n(F(l+1))   ......    h^n(F(h))
+           ...............................................
+      1:     h^1(F(l))    h^1(F(l+1))   ......    h^1(F(h))
+      0:     h^0(F(l))    h^0(F(l+1))   ......    h^0(F(h))
+  ----------------------------------------------------------
+    chi:     chi(F(l))    chi(F(l+1))   ......    chi(F(h))
+  @end format
+         A @code{'-'} in the diagram refers to a zero entry; a @code{'*'}
+         refers to a negative entry (= dimension not yet determined).
+         refers to a not computed dimension. @*
+         If @code{printlevel}>=1, step-by step timings will be printed.
+         If @code{printlevel}>=2 we add progress debug messages
+         if @code{printlevel}>=3, even all intermediate results...
+NOTE:    This procedure is based on the Bernstein-Gel'fand-Gel'fand
+         correspondence and on Tate resolution ( see [Eisenbud, Floystad,
+         Schreyer: Sheaf cohomology and free resolutions over exterior
+         algebras, Trans AMS 355 (2003)] ).@*
+         @code{sheafCohBGG(M,l,h)} does not compute all values in the above
+         table. To determine all values of @code{h^i(F(d))}, @code{d=l..h},
+         use @code{sheafCohBGG(M,l-n,h+n)}.
+         Experimental version. Should require less memory.
+SEE ALSO: sheafCohBGG
+EXAMPLE: example sheafCohBGG2; shows an example
+"
+{
+  int PL = printlevel - voice + 2;
+//  int PL = printlevel;
+
+  dbprint(PL-1, "// sheafCohBGG2(M: "+ string(nrows(M)) + " x " + string(ncols(M)) +", " + string(l) + ", " + string(h) + "):");
+  dbprint(PL-2, M);
+
+  intvec save = option(get);
+
+  if( PL >= 2 )
+  {
+    option(prot);
+    option(mem);
+  }
+
+  def isCoker = attrib(M, "isCoker");
+  if( typeof(isCoker) == "int" )
+  {
+    if( isCoker > 0 )
+    {
+      dbprint(PL-1, "We are going to assume that M is given by coker matrix (that is, M is not a submodule presentation!)");
+    }
+  }
+
+  int i,j,k,row,col;
+
+  if( typeof(attrib(M,"isHomog"))!="intvec" )
+  {
+     if (size(M)==0) { attrib(M,"isHomog",0); }
+     else { ERROR("No admissible degree vector assigned"); }
+  }
+
+  dbprint(PL-1, "// weighting(M): ["+ string(attrib(M, "isHomog")) + "]");
+
+  option(redSB); option(redTail);
+
+  def R=basering;
+
+  int n = nvars(R) - 1;
+  int ell = l + n;
+
+
+/////////////////////////////////////////////////////////////////////////////
+// computations
+
+  int tBegin=timer;
+  int reg   = CM_regularity(M);
+  int tCMEnd = timer;
+
+  dbprint(PL-1, "// CM_reg(M): "+ string(reg));
+
+  int bound = max(reg + 1, h - 1);
+
+  dbprint(PL-1, "// bound: "+ string(bound));
+
+  ///////////////////////////////////////////////////////////////
+  int tSTDBegin=timer;
+  M = std(M); // for kbase! // NOTE: this should be after CM_regularity, since otherwise CM_regularity computes JUST TOOOOOOO LONG sometimes (see Reg_Hard examples!)
+  int tSTDEnd = timer;
+
+  dbprint(PL-1, "// M = std(M: "+string(nrows(M)) + " x " + string(ncols(M))  + ")");
+  dbprint(PL-2, M);
+  dbprint(PL-1, "// weighting(M): ["+ string(attrib(M, "isHomog")) + "]");
+
+
+  printlevel = printlevel + 1;
+  int tTruncateBegin=timer;
+  module MT = truncateFast(M, bound);
+  int tTruncateEnd=timer;
+  printlevel = printlevel - 1;
+
+  dbprint(PL-1, "// MT = truncateFast(M: "+string(nrows(MT)) + " x " + string(ncols(MT)) +", " + string(bound) + ")");
+  dbprint(PL-2, MT);
+  dbprint(PL-1, "// weighting(MT): ["+ string(attrib(MT, "isHomog")) + "]");
+
+  int m=nrows(MT);
+
+  ///////////////////////////////////////////////////////////////
+  int tTransposeJacobBegin=timer;
+  MT = jacob(MT); // ! :(
+  int tTransposeJacobEnd=timer;
+
+  dbprint(PL-1, "// MT = jacob(MT: "+string(nrows(MT)) + " x " + string(ncols(MT))  + ")");
+  dbprint(PL-2, MT);
+  dbprint(PL-1, "// weighting(MT): ["+ string(attrib(MT, "isHomog")) + "]");
+
+  int tSyzBegin=timer;
+  MT = syz(MT);
+  int tSyzEnd=timer;
+
+  dbprint(PL-1, "// MT = syz(MT: "+string(nrows(MT)) + " x " + string(ncols(MT))  + ")");
+  dbprint(PL-2, MT);
+  dbprint(PL-1, "// weighting(MT): ["+ string(attrib(MT, "isHomog")) + "]");
+
+  int tMatrixOppBegin=timer;
+  module SS = TensorModuleMult(m, MT);
+  int tMatrixOppEnd=timer;
+
+  dbprint(PL-1, "// SS = TensorModuleMult("+ string(m)+ ", MT: "+string(nrows(MT)) + " x " + string(ncols(MT))  + ")");
+  dbprint(PL-2, SS);
+  dbprint(PL-1, "// weighting(SS): ["+ string(attrib(SS, "isHomog")) + "]");
+
+  //--- to the exterior algebra
+  def AR = Exterior(); setring AR;
+
+  dbprint(PL-1, "// Test: var(1) * var(1): "+ string(var(1) * var(1)));
+
+  int maxbound = max(1, bound - ell + 1);
+//  int maxbound = max(1, bound - l + 1); // As In M2!!!
+
+  dbprint(PL-1, "// maxbound: "+ string(maxbound));
+
+  //--- here we are with our matrix
+  module EM=imap(R,SS);
+  intvec w;
+  for (i=1; i<=nrows(EM); i++)
+  {
+     w[i]=-bound-1;
+  }
+
+  attrib(EM,"isHomog",w);
+
+  ///////////////////////////////////////////////////////////////
+
+  dbprint(PL-1, "// EM: "+string(nrows(EM)) + " x " + string(ncols(EM))  + ")");
+  dbprint(PL-2, EM);
+  dbprint(PL-1, "// weighting(EM): ["+ string(attrib(EM, "isHomog")) + "]");
+
+  int tResulutionBegin=timer;
+  resolution RE = nres(EM, maxbound); // TODO: Plural computes one too many syzygies...?!
+  int tMinResBegin=timer;
+  RE = minres(RE);
+  int tBettiBegin=timer;
+  intmat Betti = betti(RE); // betti(RE, 1);?
+  int tResulutionEnd=timer;
+
+  int tEnd = tResulutionEnd;
+
+  if( PL > 0 )
+  {
+    //    list L = RE; // TODO: size(L/RE) is wrong!
+    "
+        ----      RESULTS  ----
+        Tate Resolution:
+    ";
+    RE;
+    "Betti numbers for Tate resolution (diagonal cohomology table):";
+    print(Betti, "betti"); // Diagonal form!
+  }
+
+//  printlevel = printlevel + 1;
+  Betti = showResult(Betti, l, h ); // Show usual form of cohomology table
+//  printlevel = printlevel - 1;
+
+  if(PL > 0)
+  {
+  "
+      ----      TIMINGS     -------
+      Trunc      Time: ", tTruncateEnd - tTruncateBegin, "
+      Reg        Time: ", tCMEnd - tBegin, "
+      kStd       Time: ", tSTDEnd - tSTDBegin, "
+      Jacob      Time: ", tTransposeJacobEnd - tTransposeJacobBegin, "
+      Syz        Time: ", tSyzEnd - tSyzBegin, "
+      Mat        Time: ", tMatrixOppEnd - tMatrixOppBegin, "
+      ------------------------------
+      Res        Time: ", tResulutionEnd - tResulutionBegin, "
+      :: NRes    Time: ", tMinResBegin - tResulutionBegin, "
+      :: MinRes .Time: ", tBettiBegin - tMinResBegin, "
+      :: Betti  .Time: ", tResulutionEnd - tBettiBegin, "
+      ---------------------------------------------------------
+      Total Time: ", tEnd - tBegin, "
+      ---------------------------------------------------------
+      ";
+  }
+
+  setring R;
+
+  option(set, save);
+
+  return(Betti);
+}
+example
+{"EXAMPLE:";
+   echo = 2;
+   int pl = printlevel;
+   int l,h, t;
+
+   //-------------------------------------------
+   // cohomology of structure sheaf on P^4:
+   //-------------------------------------------
+   ring r=32001,x(1..5),dp;
+
+   module M= getStructureSheaf(); // OO_P^4
+
+   l = -12; h = 12; // range of twists: l..h
+
+   printlevel = 0;
+   //////////////////////////////////////////////
+   t = timer;
+
+   def A = sheafCoh(M, l, h); // global Ext method:
+
+   "Time: ", timer - t;
+   //////////////////////////////////////////////
+   t = timer;
+
+   A = sheafCohBGG(M, l, h);  // BGG method (without optimization):
+
+   "Time: ", timer - t;
+   //////////////////////////////////////////////
+   t = timer;
+
+   A = sheafCohBGG2(M, l, h); // BGG method (with optimization)
+
+   "Time: ", timer - t;
+   //////////////////////////////////////////////
+   printlevel = pl;
+
+   kill A, r;
+
+   //-------------------------------------------
+   // cohomology of cotangential bundle on P^3:
+   //-------------------------------------------
+   ring R=32001,(x,y,z,u),dp;
+
+   module M = getCotangentialBundle();
+
+   l = -12; h = 11; // range of twists: l..h
+
+
+   //////////////////////////////////////////////
+   printlevel = 0;
+   t = timer;
+
+   def B = sheafCoh(M, l, h); // global Ext method:
+
+   "Time: ", timer - t;
+   //////////////////////////////////////////////
+   t = timer;
+
+   B = sheafCohBGG(M, l, h);  // BGG method (without optimization):
+
+   "Time: ", timer - t;
+   //////////////////////////////////////////////
+   t = timer;
+
+   B = sheafCohBGG2(M, l, h); // BGG method (with optimization)
+
+   "Time: ", timer - t;
+   //////////////////////////////////////////////
+   printlevel = pl;
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc dimH(int i,module M,int d)
+"USAGE:   dimH(i,M,d);    M module, i,d int
+ASSUME:  @code{M} is graded, and it comes assigned with an admissible degree
+         vector as an attribute, @code{h>=l}, and the basering @code{S} has
+         @code{n+1} variables.
+RETURN:  int,  vector space dimension of @math{H^i(F(d))} for F the coherent
+         sheaf on P^n associated to coker(M).
+NOTE:    The procedure is based on local duality as described in [Eisenbud:
+         Computing cohomology. In Vasconcelos: Computational methods in
+         commutative algebra and algebraic geometry. Springer (1998)].
+SEE ALSO: sheafCoh, sheafCohBGG
+EXAMPLE: example dimH; shows an example
+"
+{
+  if( typeof(attrib(M,"isHomog"))=="string" )
+  {
+    if (size(M)==0)
+    {
+      // assign weights 0 to generators of R^n (n=nrows(M))
+      intvec v;
+      v[nrows(M)]=0;
+      attrib(M,"isHomog",v);
+    }
+    else
+    {
+      ERROR("No admissible degree vector assigned");
+    }
+  }
+  int Result;
+  int n=nvars(basering)-1;
+  if ((i>0) and (i<=n)) {
+    list L=Ext_R(n-i,M,1)[2];
+    def N=L[1];
+    return(dimGradedPart(N,-n-1-d));
+  }
+  else
+  {
+    if (i==0)
+    {
+      list L=Ext_R(intvec(n+1,n+2),M,1)[2];
+      def N0=L[2];
+      def N1=L[1];
+      Result=dimGradedPart(M,d) - dimGradedPart(N0,-n-1-d)
+                                - dimGradedPart(N1,-n-1-d);
+      return(Result);
+    }
+    else {
+      return(0);
+    }
+  }
+}
+example
+{"EXAMPLE:";
+   echo = 2;
+   ring R=0,(x,y,z,u),dp;
+   resolution T1=mres(maxideal(1),0);
+   module M=T1[3];
+   intvec v=2,2,2,2,2,2;
+   attrib(M,"isHomog",v);
+   dimH(0,M,2);
+   dimH(1,M,0);
+   dimH(2,M,1);
+   dimH(3,M,-5);
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc sheafCoh(module M,int l,int h,list #)
+"USAGE:   sheafCoh(M,l,h);    M module, l,h int
+ASSUME:  @code{M} is graded, and it comes assigned with an admissible degree
+         vector as an attribute, @code{h>=l}. The basering @code{S} has
+         @code{n+1} variables.
+RETURN:  intmat, cohomology of twists of the coherent sheaf F on P^n
+         associated to coker(M). The range of twists is determined by @code{l},
+         @code{h}.
+DISPLAY: The intmat is displayed in a diagram of the following form: @*
+  @format
+                l            l+1                      h
+  ----------------------------------------------------------
+      n:     h^n(F(l))    h^n(F(l+1))   ......    h^n(F(h))
+           ...............................................
+      1:     h^1(F(l))    h^1(F(l+1))   ......    h^1(F(h))
+      0:     h^0(F(l))    h^0(F(l+1))   ......    h^0(F(h))
+  ----------------------------------------------------------
+    chi:     chi(F(l))    chi(F(l+1))   ......    chi(F(h))
+  @end format
+         A @code{'-'} in the diagram refers to a zero entry.
+NOTE:    The procedure is based on local duality as described in [Eisenbud:
+         Computing cohomology. In Vasconcelos: Computational methods in
+         commutative algebra and algebraic geometry. Springer (1998)].@*
+         By default, the procedure uses @code{mres} to compute the Ext
+         modules. If called with the additional parameter @code{\"sres\"},
+         the @code{sres} command is used instead.
+SEE ALSO: dimH, sheafCohBGG
+EXAMPLE: example sheafCoh; shows an example
+"
+{
+  int use_sres;
+  if( typeof(attrib(M,"isHomog"))!="intvec" )
+  {
+     if (size(M)==0) { attrib(M,"isHomog",0); }
+     else { ERROR("No admissible degree vector assigned"); }
+  }
+  if (size(#)>0)
+  {
+    if (#[1]=="sres") { use_sres=1; }
+  }
+  int i,j;
+  module N,N0,N1;
+  int n=nvars(basering)-1;
+  intvec v=0..n+1;
+  int col=h-l+1;
+  intmat newBetti[n+1][col];
+  if (use_sres) { list L=Ext_R(v,M,1,"sres")[2]; }
+  else          { list L=Ext_R(v,M,1)[2]; }
+  for (i=l; i<=h; i++)
+  {
+    N0=L[n+2];
+    N1=L[n+1];
+    newBetti[n+1,i-l+1]=dimGradedPart(M,i) - dimGradedPart(N0,-n-1-i)
+                             - dimGradedPart(N0,-n-1-i);
+  }
+  for (j=1; j<=n; j++)
+  {
+     N=L[j];
+     attrib(N,"isSB",1);
+     if (dim(N)>=0) {
+       for (i=l; i<=h; i++)
+       {
+         newBetti[j,i-l+1]=dimGradedPart(N,-n-1-i);
+       }
+     }
+  }
+  displayCohom(newBetti,l,h,n);
+  return(newBetti);
+}
+example
+{"EXAMPLE:";
+   echo = 2;
+   //
+   // cohomology of structure sheaf on P^4:
+   //-------------------------------------------
+   ring r=0,x(1..5),dp;
+   module M=0;
+   def A=sheafCoh(0,-7,2);
+   //
+   // cohomology of cotangential bundle on P^3:
+   //-------------------------------------------
+   ring R=0,(x,y,z,u),dp;
+   resolution T1=mres(maxideal(1),0);
+   module M=T1[3];
+   intvec v=2,2,2,2,2,2;
+   attrib(M,"isHomog",v);
+   def B=sheafCoh(M,-6,2);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+proc displayCohom (intmat data, int l, int h, int n)
+"USAGE:   displayCohom(data,l,h,n);  data intmat, l,h,n int
+ASSUME:  @code{h>=l}, @code{data} is the return value of
+         @code{sheafCoh(M,l,h)} or of @code{sheafCohBGG(M,l,h)}, and the
+         basering has @code{n+1} variables.
+RETURN:  none
+NOTE:    The intmat is displayed in a diagram of the following form: @*
+  @format
+                l            l+1                      h
+  ----------------------------------------------------------
+      n:     h^n(F(l))    h^n(F(l+1))   ......    h^n(F(h))
+           ...............................................
+      1:     h^1(F(l))    h^1(F(l+1))   ......    h^1(F(h))
+      0:     h^0(F(l))    h^0(F(l+1))   ......    h^0(F(h))
+  ----------------------------------------------------------
+    chi:     chi(F(l))    chi(F(l+1))   ......    chi(F(h))
+  @end format
+         where @code{F} refers to the associated sheaf of @code{M} on P^n.@*
+         A @code{'-'} in the diagram refers to a zero entry,  a @code{'*'}
+         refers to a negative entry (= dimension not yet determined).
+"
+{
+  int i,j,k,dat,maxL;
+  intvec notSumCol;
+  notSumCol[h-l+1]=0;
+  string s;
+  maxL=4;
+  for (i=1;i<=nrows(data);i++)
+  {
+    for (j=1;j<=ncols(data);j++)
+    {
+      if (size(string(data[i,j]))>=maxL-1)
+      {
+        maxL=size(string(data[i,j]))+2;
+      }
+    }
+  }
+  string Row="    ";
+  string Row1="----";
+  for (i=l; i<=h; i++) {
+    for (j=1; j<=maxL-size(string(i)); j++)
+    {
+      Row=Row+" ";
+    }
+    Row=Row+string(i);
+    for (j=1; j<=maxL; j++) { Row1 = Row1+"-"; }
+  }
+  print(Row);
+  print(Row1);
+  for (j=1; j<=n+1; j++)
+  {
+    s = string(n+1-j);
+    Row = "";
+    for(k=1; k<4-size(s); k++) { Row = Row+" "; }
+    Row = Row + s+":";
+    for (i=0; i<=h-l; i++)
+    {
+      dat = data[j,i+1];
+      if (dat>0) { s = string(dat); }
+      else
+      {
+        if (dat==0) { s="-"; }
+        else        { s="*"; notSumCol[i+1]=1; }
+      }
+      for(k=1; k<=maxL-size(s); k++) { Row = Row+" "; }
+      Row = Row + s;
+    }
+    print(Row);
+  }
+  print(Row1);
+  Row="chi:";
+  for (i=0; i<=h-l; i++)
+  {
+    dat = 0;
+    if (notSumCol[i+1]==0)
+    {
+      for (j=0; j<=n; j++) { dat = dat + (-1)^j * data[n+1-j,i+1]; }
+      s = string(dat);
+    }
+    else { s="*"; }
+    for (k=1; k<=maxL-size(s); k++) { Row = Row+" "; }
+    Row = Row + s;
+  }
+  print(Row);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc getStructureSheaf(list #)
+{
+
+  if( size(#) == 0 )
+  {
+    module M = 0;
+    intvec v = 0;
+    attrib(M,"isHomog",v);
+//    homog(M);
+
+    attrib(M, "isCoker", 1);
+
+//     attrib(M);
+    return(M);
+  }
+
+  if( typeof(#[1]) == "ideal")
+  {
+    ideal I = #[1];
+
+    if( size(#) == 2 )
+    {
+      if( typeof(#[2]) == "int" )
+      {
+        if( #[2] != 0 )
+        {
+          qring @@@@QQ = std(I);
+
+          module M = getStructureSheaf();
+
+          export M;
+
+//          keepring @@@@QQ; // This is a bad idea... :(?
+          return (@@@@QQ);
+        }
+      }
+    }
+
+/*
+    // This seems to be wrong!!!
+    module M = I * gen(1);
+    homog(M);
+
+    M = modulo(gen(1), module(I * gen(1))); // basering^1 / I
+
+    homog(M);
+
+    attrib(M, "isCoker", 1);
+
+    attrib(M);
+    return(M);
+*/
+  }
+
+  ERROR("Wrong argument");
+
+}
+example
+{"EXAMPLE:";
+   echo = 2; int pl = printlevel;
+   printlevel = voice;
+
+
+   ////////////////////////////////////////////////////////////////////////////////
+   ring r;
+   module M = getStructureSheaf();
+   "Basering: ";
+   basering;
+   "Module: ", string(M), ", grading is given by weights: ", attrib(M, "isHomog");
+
+   def A=sheafCohBGG2(M,-9,9);
+   print(A);
+
+   ////////////////////////////////////////////////////////////////////////////////
+   setring r;
+   module M = getStructureSheaf(ideal(var(1)), 0);
+
+   "Basering: ";
+   basering;
+   "Module: ", string(M), ", grading is given by weights: ", attrib(M, "isHomog");
+
+   def A=sheafCohBGG2(M,-9,9);
+   print(A);
+
+   ////////////////////////////////////////////////////////////////////////////////
+   setring r;
+   def Q = getStructureSheaf(ideal(var(1)), 1); // returns a new ring!
+   setring Q; // M was exported in the new ring!
+
+   "Basering: ";
+   basering;
+   "Module: ", string(M), ", grading is given by weights: ", attrib(M, "isHomog");
+
+   def A=sheafCohBGG2(M,-9,9);
+   print(A);
+
+   printlevel = pl;
+}
+
+
+proc getCotangentialBundle()
+{
+  resolution T1=mres(maxideal(1),3);
+  module M=T1[3];
+//  attrib(M,"isHomog");
+//  homog(M);
+  attrib(M, "isCoker", 1);
+  // attrib(M);
+  return (M);
+}
+
+proc getIdealSheafPullback(ideal I, ideal pi)
+{
+  def save = basering;
+  map P = save, pi;
+  return( P(I) );
+}
+
+// TODO: set attributes!
+
+
+proc getIdealSheaf(ideal I)
+{
+  int i = homog(I);
+  resolution FI = mres(I,2); // Syz + grading...
+  module M = FI[2];
+  attrib(M, "isCoker", 1);
+  //  attrib(M);
+  return(M);
+}
+
+
+
+
+
+/*
+Examples:
+---------
+ LIB "sheafcoh.lib";
+
+ ring S = 32003, x(0..4), dp;
+ module MI=maxideal(1);
+ attrib(MI,"isHomog",intvec(-1));
+ resolution kos = nres(MI,0);
+ print(betti(kos),"betti");
+ LIB "random.lib";
+ matrix alpha0 = random(32002,10,3);
+ module pres = module(alpha0)+kos[3];
+ attrib(pres,"isHomog",intvec(1,1,1,1,1,1,1,1,1,1));
+ resolution fcokernel = mres(pres,0);
+ print(betti(fcokernel),"betti");
+ module dir = transpose(pres);
+ attrib(dir,"isHomog",intvec(-1,-1,-1,-2,-2,-2,
+                             -2,-2,-2,-2,-2,-2,-2));
+ resolution fdir = mres(dir,2);
+ print(betti(fdir),"betti");
+ ideal I = groebner(flatten(fdir[2]));
+ resolution FI = mres(I,0);
+ print(betti(FI),"betti");
+ module F=FI[2];
+ int t=timer;
+ def A1=sheafCoh(F,-8,8);
+ timer-t;
+ t=timer;
+ def A2=sheafCohBGG(F,-8,8);
+ timer-t;
+
+ LIB "sheafcoh.lib";
+ LIB "random.lib";
+ ring S = 32003, x(0..4), dp;
+ resolution kos = nres(maxideal(1),0);
+ betti(kos);
+ matrix kos5 = kos[5];
+ matrix tphi = transpose(dsum(kos5,kos5));
+ matrix kos3 = kos[3];
+ matrix psi = dsum(kos3,kos3);
+ matrix beta1 = random(32002,20,2);
+ matrix tbeta1tilde = transpose(psi*beta1);
+ matrix tbeta0 = lift(tphi,tbeta1tilde);
+ matrix kos4 = kos[4];
+ matrix tkos4pluskos4 = transpose(dsum(kos4,kos4));
+ matrix tgammamin1 = random(32002,20,1);
+ matrix tgamma0 = tkos4pluskos4*tgammamin1;
+ matrix talpha0 = concat(tbeta0,tgamma0);
+ matrix zero[20][1];
+ matrix tpsi = transpose(psi);
+ matrix tpresg = concat(tpsi,zero);
+ matrix pres = module(transpose(talpha0))
+                    + module(transpose(tpresg));
+ module dir = transpose(pres);
+ dir = prune(dir);
+ homog(dir);
+ intvec deg_dir = attrib(dir,"isHomog");
+ attrib(dir,"isHomog",deg_dir-2);        // set degrees
+ resolution fdir = mres(prune(dir),2);
+ print(betti(fdir),"betti");
+ ideal I = groebner(flatten(fdir[2]));
+ resolution FI = mres(I,0);
+
+ module F=FI[2];
+ def A1=sheafCoh(F,-5,7);
+ def A2=sheafCohBGG(F,-5,7);
+
+*/
diff --git a/Singular/LIB/signcond.lib b/Singular/LIB/signcond.lib
new file mode 100644
index 0000000..f51e753
--- /dev/null
+++ b/Singular/LIB/signcond.lib
@@ -0,0 +1,437 @@
+///////////////////////////////////////////////////////////////////////////
+version="version signcond.lib 4.0.0.0 Jun_2013 "; // $Id: ee2df407c1229cad9943458a836f9ecce33d5c5d $
+category="Symbolic-numerical solving";
+info="
+LIBRARY: signcond.lib Routines for computing realizable sign conditions
+AUTHOR:               Enrique A. Tobis, etobis at dc.uba.ar
+
+OVERVIEW:  Routines to determine the number of solutions of a multivariate
+           polynomial system which satisfy a given sign configuration.
+REFERENCES: Basu, Pollack, Roy, \"Algorithms in Real Algebraic
+           Geometry\", Springer, 2003.
+
+PROCEDURES:
+  signcnd(P,I)   The sign conditions realized by polynomials of P on a V(I)
+  psigncnd(P,l)  Pretty prints the output of signcnd (l)
+  firstoct(I)    The number of elements of V(I) with every coordinate > 0
+
+KEYWORDS: real roots,sign conditions
+";
+
+LIB "rootsmr.lib";
+LIB "linalg.lib";
+///////////////////////////////////////////////////////////////////////////////
+
+proc firstoct(ideal I)
+"USAGE:    firstoct(I); I ideal
+RETURN:   number: the number of points of V(I) lying in the first octant
+ASSUME:   I is given by a Groebner basis.
+SEE ALSO: signcnd
+EXAMPLE:  example firstoct; shows an example"
+{
+  ideal firstoctant;
+  int j;
+  list result;
+  int n;
+
+  if (isparam(I)) {
+    ERROR("This procedure cannot operate with parametric arguments");
+  }
+
+  for (j = nvars(basering);j > 0;j--) {
+    firstoctant = firstoctant + var(j);
+  }
+
+  result = signcnd(firstoctant,I);
+
+  list fst;
+  for (j = nvars(basering);j > 0;j--) {
+    fst[j] = 1;
+  }
+
+  n = isIn(fst,result[1]);
+
+  if (n != -1) {
+    return (result[2][n]);
+  } else {
+    return (0);
+  }
+}
+example
+{
+  echo = 2;
+  ring r = 0,(x,y),dp;
+  ideal i = (x-2)*(x+3)*x,y*(y-1);
+  firstoct(i);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc signcnd(ideal P,ideal I)
+"USAGE:     signcnd(P,I); ideal P,I
+RETURN:    list: the sign conditions realized by the polynomials of P on V(I).
+           The output of signcnd is a list of two lists. Both lists have the
+           same length. This length is the number of sign conditions realized
+           by the polynomials of P on the set V(i).
+           Each element of the first list indicates a sign condition of the
+           polynomials of P.
+           Each element of the second list indicates how many elements of V(I)
+           give rise to the sign condition expressed by the same position on
+           the first list.
+           See the example for further explanations of the output.
+ASSUME:    I is a Groebner basis.
+NOTE:      The procedure psigncnd performs some pretty printing of this output.
+SEE ALSO:  firstoct, psigncnd
+EXAMPLE:   example signcnd; shows an example"
+{
+  ideal B;
+
+  // Cumulative stuff
+  matrix M;
+  matrix SQs;
+  matrix C;
+  list Signs;
+  list Exponents;
+
+  // Used to store the precalculated SQs
+  list SQvalues;
+  list SQpositions;
+
+  int i;
+
+  // Variables for each step
+  matrix Mi;
+  matrix M3x3[3][3];
+  matrix M3x3inv[3][3]; // Constant matrices
+  matrix c[3][1];
+  matrix sq[3][1];
+  int j;
+  list exponentsi;
+  list signi;
+  int numberOfNonZero;
+
+  if (isparam(P) || isparam(I)) {
+    ERROR("This procedure cannot operate with parametric arguments");
+  }
+
+  M3x3 = matrix(1,3,3);
+  M3x3 = 1,1,1,0,1,-1,0,1,1; // The 3x3 matrix
+  M3x3inv = inverse(M3x3);
+
+  // First, we compute sturmquery(1,V(I))
+  I = groebner(I);
+  B = qbase(I);
+  sq[1,1] = sturmquery(1,B,I); // Number of real roots in V(I)
+  SQvalues = SQvalues + list(sq[1,1]);
+  SQpositions = SQpositions + list(1);
+
+  // We initialize the cumulative variables
+  M = matrix(1,1,1);
+  Exponents = list(list());
+  Signs = list(list());
+
+  i = 1;
+
+  while (i <= size(P)) { // for each poly in P
+
+    sq[2,1] = sturmquery(P[i],B,I);
+    sq[3,1] = sturmquery(P[i]^2,B,I);
+
+
+    c = M3x3inv*sq;
+
+    // We have to eliminate the 0 elements in c
+    exponentsi = list();
+    signi = list();
+
+
+    // We determine the list of signs which correspond to a nonzero
+    // number of roots
+    numberOfNonZero = 3;
+
+    if (c[1,1] != 0) {
+      signi = list(0);
+    } else {
+      numberOfNonZero--;
+    }
+
+    if (c[2,1] != 0) {
+      signi = signi + list(1);
+    } else {
+      numberOfNonZero--;
+    }
+
+    if (c[3,1] != 0) {
+      signi = signi + list(-1);
+    } else {
+      numberOfNonZero--;
+    }
+
+    // We now determine the little matrix we'll work with,
+    // and the list of exponents
+    if (numberOfNonZero == 3) {
+      Mi = M3x3;
+      exponentsi = list(0,1,2);
+    } else {if (numberOfNonZero == 2) {
+      Mi = matrix(1,2,2);
+      Mi[1,2] = 1;
+      if (c[1,1] != 0 && c[2,1] != 0) { // 0,1
+        Mi[2,1] = 0;
+        Mi[2,2] = 1;
+      } else {if (c[1,1] != 0 && c[3,1] != 0) { // 0,-1
+        Mi[2,1] = 0;
+        Mi[2,2] = -1;
+      } else { // 1,-1
+        Mi[2,1] = 1;
+        Mi[2,2] = -1;
+      }}
+      exponentsi = list(0,1);
+    } else {if (numberOfNonZero == 1) {
+      Mi = matrix(1,1,1);
+      exponentsi = list(0);
+    }}}
+
+    // We store the Sturm Queries we'll need later
+    if (numberOfNonZero == 2) {
+      SQvalues = SQvalues + list(sq[2,1]);
+      SQpositions = SQpositions + list(size(Exponents)+1);
+    } else {if (numberOfNonZero == 3) {
+      SQvalues = SQvalues + list(sq[2,1],sq[3,1]);
+      SQpositions = SQpositions + list(size(Exponents)+1,size(Exponents)*2+1);
+    }}
+
+    // Now, we accumulate information
+    M = tensor(Mi,M);
+    Signs = expprod(Signs,signi);
+    Exponents = expprod(Exponents,exponentsi);
+
+    i++;
+  }
+
+  // At this point, we have the cumulative matrix,
+  // the vector of exponents and the matching sign conditions.
+  // We have to solve the big linear system to finish.
+
+  M = inverse(M);
+
+  // We have to compute the constants vector (the Sturm Queries)
+
+  SQs = matrix(1,size(Exponents),1);
+
+  j = 1; // We'll iterate over the presaved SQs
+
+  for (i = 1;i <= size(Exponents);i++) {
+    if (j <= size(SQvalues)) {
+      if (SQpositions[j] == i) {
+        SQs[i,1] = SQvalues[j];
+        j++;
+      } else {
+      SQs[i,1] = sturmquery(evalp(Exponents[i],P),B,I);
+      }
+    } else {
+        SQs[i,1] = sturmquery(evalp(Exponents[i],P),B,I);
+    }
+  }
+
+  C = M*SQs;
+
+  list result;
+  result[2] = list();
+  result[1] = list();
+
+  // We have to filter the 0 elements of C
+  for (i = 1;i <= size(Signs);i++) {
+    if (C[i,1] != 0) {
+      result[1] = result[1] + list(Signs[i]);
+      result[2] = result[2] + list(C[i,1]);
+    }
+  }
+
+  return (result);
+}
+example
+{ echo = 2;
+  ring r = 0,(x,y),dp;
+  ideal i = (x-2)*(x+3)*x,y*(y-1);
+  ideal P = x,y;
+  list l = signcnd(P,i);
+
+  size(l[1]);     // = the number of sign conditions of P on V(i)
+
+  //Each element of l[1] indicates a sign condition of the polynomials of P.
+  //The following means P[1] > 0, P[2] = 0:
+  l[1][2];
+
+  //Each element of l[2] indicates how many elements of V(I) give rise to
+  //the sign condition expressed by the same position on the first list.
+  //The following means that exactly 1 element of V(I) gives rise to the
+  //condition P[1] > 0, P[2] = 0:
+  l[2][2];
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc psigncnd(ideal P,list l)
+"USAGE:     psigncnd(P,l); ideal P, list l
+RETURN:    list: a formatted version of l
+SEE ALSO:  signcnd
+EXAMPLE:   example psigncnd; shows an example"
+{
+  string s;
+  int n = size(l[1]);
+  int i;
+
+  for (i = 1;i <= n;i++) {
+    s = s + string(l[2][i]) + " elements of V(I) satisfy " + psign(P,l[1][i])
+        + sprintf("%n",12);
+  }
+  return(s);
+}
+example
+{
+  echo = 2;
+  ring r = 0,(x,y),dp;
+  ideal i = (x-2)*(x+3)*x,(y-1)*(y+2)*(y+4);
+  ideal P = x,y;
+  list l = signcnd(P,i);
+  psigncnd(P,l);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+static proc psign(ideal P,list s)
+{
+  int i;
+  int n = size(P);
+  string output;
+
+  output = "{P[1]";
+
+  if (s[1] == -1) {
+    output = output + " < 0";
+  }
+  if (s[1] == 0) {
+    output = output + " = 0";
+  }
+  if (s[1] == 1) {
+    output = output + " > 0";
+  }
+
+  for (i = 2;i <= n;i++) {
+    output = output + ",";
+    output = output + "P[" + string(i) + "]";
+    if (s[i] == -1) {
+      output = output + " < 0";
+    }
+    if (s[i] == 0) {
+      output = output + " = 0";
+    }
+    if (s[i] == 1) {
+      output = output + " > 0";
+    }
+
+  }
+  output = output + "}";
+  return (output);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+static proc isIn(list a,list b) //a is a list. b is a list of lists
+{
+  int i,j;
+  int found;
+
+  found = 0;
+  i = 1;
+  while (i <= size(b) && !found) {
+    j = 1;
+    found = 1;
+    if (size(a) != size(b[i])) {
+      found = 0;
+    } else {
+      while(j <= size(a)) {
+        found = found && a[j] == b[i][j];
+        j++;
+      }
+    }
+    i++;
+  }
+
+  if (found) {
+    return (i-1);
+  } else {
+    return (-1);
+  }
+}
+///////////////////////////////////////////////////////////////////////////////
+
+static proc expprod(list A,list B) // Computes the product of the list of lists A and the list B.
+{
+  int i,j;
+  list result;
+  int la,lb;
+
+  if (size(A) == 0) {
+    A = list(list());
+  }
+
+  la = size(A);
+  lb = size(B);
+
+  result[la*lb] = 0;
+
+
+  for (i = 0;i < lb;i++) {
+    for (j = 0;j < la;j++) {
+      result[i*la+j+1] = A[j+1] + list(B[i+1]);
+    }
+  }
+
+  return (result);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+static proc initlist(int n) // Returns an n-element list of 0s.
+{
+  list l;
+  int i;
+  l[n] = 0;
+  for (i = 1;i < n;i++) {
+    l[i] = 0;
+  }
+  return(l);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+static proc evalp(list exp,ideal P) // Elevates each polynomial in P to the appropriate
+{
+  int i;
+  int n;
+  poly result;
+
+  n = size(exp);
+  result = 1;
+
+  for (i = 1;i <= n; i++) {
+    result = result * (P[i]^exp[i]);
+  }
+  return (result);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+static proc incexp(list exp)
+{
+  int k;
+
+  k = 1;
+
+  while (exp[k] == 2) { // We assume exp is not the last exponent (i.e. 2,...,2)
+    exp[k] = 0;
+    k++;
+  }
+
+  // exp[k] < 2
+  exp[k] = exp[k] + 1;
+
+  return (exp);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+
diff --git a/Singular/LIB/sing.lib b/Singular/LIB/sing.lib
new file mode 100644
index 0000000..8d42137
--- /dev/null
+++ b/Singular/LIB/sing.lib
@@ -0,0 +1,1095 @@
+////////////////////////////////////////////////////////////////////////////
+version="version sing.lib 4.0.0.0 Jun_2013 "; // $Id: b7c1096f97775f6fc937b35cee629f6ca92c7638 $
+category="Singularities";
+info="
+LIBRARY:  sing.lib      Invariants of Singularities
+AUTHORS:  Gert-Martin Greuel, email: greuel at mathematik.uni-kl.de @*
+          Bernd Martin, email: martin at math.tu-cottbus.de
+
+PROCEDURES:
+ codim(id1, id2);       vector space dimension of id2/id1 if finite
+ deform(i);             infinitesimal deformations of ideal i
+ dim_slocus(i);         dimension of singular locus of ideal i
+ is_active(f,id);       is polynomial f an active element mod id? (id ideal/module)
+ is_ci(i);              is ideal i a complete intersection?
+ is_is(i);              is ideal i an isolated singularity?
+ is_reg(f,id);          is polynomial f a regular element mod id? (id ideal/module)
+ is_regs(i[,id]);       are gen's of ideal i regular sequence modulo id?
+ locstd(i);             SB for local degree ordering without cancelling units
+ milnor(i);             milnor number of ideal i; (assume i is ICIS in nf)
+ nf_icis(i);            generic combinations of generators; get ICIS in nf
+ slocus(i);             ideal of singular locus of ideal i
+ qhspectrum(f,w);       spectrum numbers of w-homogeneous polynomial f
+ Tjurina(i);            SB of Tjurina module of ideal i (assume i is ICIS)
+ tjurina(i);            Tjurina number of ideal i (assume i is ICIS)
+ T_1(i);                T^1-module of ideal i
+ T_2((i);               T^2-module of ideal i
+ T_12(i);               T^1- and T^2-module of ideal i
+ tangentcone(id);       compute tangent cone of id
+
+";
+
+LIB "inout.lib";
+LIB "random.lib";
+LIB "primdec.lib";
+///////////////////////////////////////////////////////////////////////////////
+
+proc deform (ideal id)
+"USAGE:   deform(id); id=ideal or poly
+RETURN:  matrix, columns are kbase of infinitesimal deformations
+EXAMPLE: example deform; shows an example
+"
+{
+   list L=T_1(id,"");
+   def K=L[1]; attrib(K,"isSB",1);
+   return(L[2]*kbase(K));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r   = 32003,(x,y,z),ds;
+   ideal i  = xy,xz,yz;
+   matrix T = deform(i);
+   print(T);
+   print(deform(x3+y5+z2));
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc dim_slocus (ideal i)
+"USAGE:   dim_slocus(i);  i ideal or poly
+RETURN:  dimension of singular locus of i
+EXAMPLE: example dim_slocus; shows an example
+"
+{
+   return(dim(std(slocus(i))));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r  = 32003,(x,y,z),ds;
+   ideal i = x5+y6+z6,x2+2y2+3z2;
+   dim_slocus(i);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc is_active (poly f,def id)
+"USAGE:   is_active(f,id); f poly, id ideal or module
+RETURN:  1 if f is an active element modulo id (i.e. dim(id)=dim(id+f*R^n)+1,
+         if id is a submodule of R^n) resp. 0 if f is not active.
+         The basering may be a quotient ring
+NOTE:    regular parameters are active but not vice versa (id may have embedded
+         components). proc is_reg tests whether f is a regular parameter
+EXAMPLE: example is_active; shows an example
+"
+{
+   if( size(id)==0 ) { return(1); }
+   if( typeof(id)=="ideal" ) { ideal m=f; }
+   if( typeof(id)=="module" ) { module m=f*freemodule(nrows(id)); }
+   return(dim(std(id))-dim(std(id+m)));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r   =32003,(x,y,z),ds;
+   ideal i  = yx3+y,yz3+y3z;
+   poly f   = x;
+   is_active(f,i);
+   qring q  = std(x4y5);
+   poly f   = x;
+   module m = [yx3+x,yx3+y3x];
+   is_active(f,m);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc is_ci (ideal i)
+"USAGE:   is_ci(i); i ideal
+RETURN:  intvec = sequence of dimensions of ideals (j[1],...,j[k]), for
+         k=1,...,size(j), where j is minimal base of i. i is a complete
+         intersection if last number equals nvars-size(i)
+NOTE:    dim(0-ideal) = -1. You may first apply simplify(i,10); in order to
+         delete zeroes and multiples from set of generators
+         printlevel >=0: display comments (default)
+EXAMPLE: example is_ci; shows an example
+"
+{
+   int n; intvec dimvec; ideal id;
+   i=minbase(i);
+   int s = ncols(i);
+   int p = printlevel-voice+3;  // p=printlevel+1 (default: p=1)
+//--------------------------- compute dimensions ------------------------------
+   for( n=1; n<=s; n=n+1 )
+   {
+      id = i[1..n];
+      dimvec[n] = dim(std(id));
+   }
+   n = dimvec[s];
+//--------------------------- output ------------------------------------------
+   if( n+s != nvars(basering) )
+   { dbprint(p,"// no complete intersection"); }
+   if( n+s == nvars(basering) )
+   { dbprint(p,"// complete intersection of dim "+string(n)); }
+   dbprint(p,"// dim-sequence:");
+   return(dimvec);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   int p      = printlevel;
+   printlevel = 1;                // display comments
+   ring r     = 32003,(x,y,z),ds;
+   ideal i    = x4+y5+z6,xyz,yx2+xz2+zy7;
+   is_ci(i);
+   i          = xy,yz;
+   is_ci(i);
+   printlevel = p;
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc is_is (ideal i)
+"USAGE:   is_is(id);  id ideal or poly
+RETURN:  intvec = sequence of dimensions of singular loci of ideals
+         generated by id[1]..id[i], k = 1..size(id); @*
+         dim(0-ideal) = -1;
+         id defines an isolated singularity if last number is 0
+NOTE:    printlevel >=0: display comments (default)
+EXAMPLE: example is_is; shows an example
+"
+{
+  int l; intvec dims; ideal j;
+  int p = printlevel-voice+3;  // p=printlevel+1 (default: p=1)
+//--------------------------- compute dimensions ------------------------------
+   for( l=1; l<=ncols(i); l=l+1 )
+   {
+     j = i[1..l];
+     dims[l] = dim(std(slocus(j)));
+   }
+   dbprint(p,"// dim of singular locus = "+string(dims[size(dims)]),
+             "// isolated singularity if last number is 0 in dim-sequence:");
+   return(dims);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   int p      = printlevel;
+   printlevel = 1;
+   ring r     = 32003,(x,y,z),ds;
+   ideal i    = x2y,x4+y5+z6,yx2+xz2+zy7;
+   is_is(i);
+   poly f     = xy+yz;
+   is_is(f);
+   printlevel = p;
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc is_reg (poly f,def id)
+"USAGE:   is_reg(f,id); f poly, id ideal or module
+RETURN:  1 if multiplication with f is injective modulo id, 0 otherwise
+NOTE:    Let R be the basering and id a submodule of R^n. The procedure checks
+         injectivity of multiplication with f on R^n/id. The basering may be a
+         quotient ring.
+EXAMPLE: example is_reg; shows an example
+"
+{
+   if( f==0 ) { return(0); }
+   int d,ii;
+   def q = quotient(id,ideal(f));
+   id=std(id);
+   d=size(q);
+   for( ii=1; ii<=d; ii=ii+1 )
+   {
+      if( reduce(q[ii],id)!=0 )
+      { return(0); }
+   }
+   return(1);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r  = 32003,(x,y),ds;
+   ideal i = x8,y8;
+   ideal j = (x+y)^4;
+   i       = intersect(i,j);
+   poly f  = xy;
+   is_reg(f,i);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc is_regs (ideal i, list #)
+"USAGE:   is_regs(i[,id]); i poly, id ideal or module (default: id=0)
+RETURN:  1 if generators of i are a regular sequence modulo id, 0 otherwise
+NOTE:    Let R be the basering and id a submodule of R^n. The procedure checks
+         injectivity of multiplication with i[k] on R^n/id+i[1..k-1].
+         The basering may be a quotient ring.
+         printlevel >=0: display comments (default)
+         printlevel >=1: display comments during computation
+EXAMPLE: example is_regs; shows an example
+"
+{
+   int d,ii,r;
+   int p = printlevel-voice+3;  // p=printlevel+1 (default: p=1)
+   if( size(#)==0 ) { ideal id; }
+   else { def id=#[1]; }
+   if( size(i)==0 ) { return(0); }
+   d=size(i);
+   if( typeof(id)=="ideal" ) { ideal m=1; }
+   if( typeof(id)=="module" ) { module m=freemodule(nrows(id)); }
+   for( ii=1; ii<=d; ii=ii+1 )
+   {
+      if( p>=2 )
+      { "// checking whether element",ii,"is regular mod 1 ..",ii-1; }
+      if( is_reg(i[ii],id)==0 )
+      {
+        dbprint(p,"// elements 1.."+string(ii-1)+" are regular, " +
+                string(ii)+" is not regular mod 1.."+string(ii-1));
+         return(0);
+      }
+      id=id+i[ii]*m;
+   }
+   if( p>=1 ) { "// elements are a regular sequence of length",d; }
+   return(1);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   int p      = printlevel;
+   printlevel = 1;
+   ring r1    = 32003,(x,y,z),ds;
+   ideal i    = x8,y8,(x+y)^4;
+   is_regs(i);
+   module m   = [x,0,y];
+   i          = x8,(x+z)^4;;
+   is_regs(i,m);
+   printlevel = p;
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc milnor (ideal i)
+"USAGE:   milnor(i); i ideal or poly
+RETURN:  Milnor number of i, if i is ICIS (isolated complete intersection
+         singularity) in generic form, resp. -1 if not
+NOTE:    use proc nf_icis to put generators in generic form
+         printlevel >=1: display comments
+EXAMPLE: example milnor; shows an example
+"
+{
+  i = simplify(i,10);     //delete zeroes and multiples from set of generators
+  int n = size(i);
+  int l,q,m_nr;  ideal t;  intvec disc;
+  int p = printlevel-voice+2;             // p=printlevel+1 (default: p=0)
+//---------------------------- hypersurface case ------------------------------
+  if( n==1 or i==0 )
+  {
+     i = std(jacob(i[1]));
+     m_nr = vdim(i);
+     if( m_nr<0 and p>=1 ) { "// Milnor number is infinite"; }
+     return(m_nr);
+  }
+//------------ isolated complete intersection singularity (ICIS) --------------
+  for( l=n; l>0; l=l-1)
+  {   t      = minor(jacob(i),l);
+      i[l]   = 0;
+      q      = vdim(std(i+t));
+      disc[l]= q;
+      if( q ==-1 )
+      {  if( p>=1 )
+            {  "// not in generic form or no ICIS; use proc nf_icis to put";
+            "// generators in generic form and then try milnor again!";  }
+         return(q);
+      }
+      m_nr = q-m_nr;
+  }
+//---------------------------- change sign ------------------------------------
+  if (m_nr < 0) { m_nr=-m_nr; }
+  if( p>=1 ) { "//sequence of discriminant numbers:",disc; }
+  return(m_nr);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   int p      = printlevel;
+   printlevel = 2;
+   ring r     = 32003,(x,y,z),ds;
+   ideal j    = x5+y6+z6,x2+2y2+3z2,xyz+yx;
+   milnor(j);
+   poly f     = x7+y7+(x-y)^2*x2y2+z2;
+   milnor(f);
+   printlevel = p;
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc nf_icis (ideal i)
+"USAGE:   nf_icis(i); i ideal
+RETURN:  ideal = generic linear combination of generators of i if i is an ICIS
+         (isolated complete intersection singularity), return i if not
+NOTE:    this proc is useful in connection with proc milnor
+         printlevel >=0: display comments (default)
+EXAMPLE: example nf_icis; shows an example
+"
+{
+   i = simplify(i,10);  //delete zeroes and multiples from set of generators
+   int p,b = 100,0;
+   int n = size(i);
+   matrix mat=freemodule(n);
+   int P = printlevel-voice+3;  // P=printlevel+1 (default: P=1)
+//---------------------------- test: complete intersection? -------------------
+   intvec sl = is_ci(i);
+   if( n+sl[n] != nvars(basering) )
+   {
+      dbprint(P,"// no complete intersection");
+      return(i);
+   }
+//--------------- test: isolated singularity in generic form? -----------------
+   sl = is_is(i);
+   if ( sl[n] != 0 )
+   {
+      dbprint(P,"// no isolated singularity");
+      return(i);
+   }
+//------------ produce generic linear combinations of generators --------------
+   int prob;
+   while ( sum(sl) != 0 )
+   {  prob=prob+1;
+      p=p-25; b=b+10;
+      i = genericid(i,p,b);          // proc genericid from random.lib
+      sl = is_is(i);
+   }
+   dbprint(P,"// ICIS in generic form after "+string(prob)+" genericity loop(s)");
+   return(i);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   int p      = printlevel;
+   printlevel = 1;
+   ring r     = 32003,(x,y,z),ds;
+   ideal i    = x3+y4,z4+yx;
+   nf_icis(i);
+   ideal j    = x3+y4,xy,yz;
+   nf_icis(j);
+   printlevel = p;
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc slocus(ideal i)
+"USAGE:   slocus(i);  i ideal
+RETURN:  ideal of singular locus of i. Quotient rings and rings with integer coefficients are currently not supported.
+EXAMPLE: example slocus; shows an example
+"
+{
+  // quotient rings currently not supported
+  ASSUME( 0, 0==isQuotientRing(basering) );
+  // integer coefficient rings currently not supported
+  ASSUME( 0, hasFieldCoefficient(basering) );
+
+
+  def R=basering;
+  int j,k;
+  ideal res;
+
+  if(ord_test(basering)!=1)
+  {
+     string va=varstr(basering);
+     if( size( parstr(basering))>0){va=va+","+parstr(basering);}
+     execute ("ring S = ("+charstr(basering)+"),("+va+"),dp;");
+     ideal i=imap(R,i);
+     list l=equidim(i);
+     setring R;
+     list l=imap(S,l);
+  }
+  else
+  {
+     list l=equidim(i);
+  }
+  int n=size(l);
+  if (n==1){return(slocusEqi(i));}
+  res=slocusEqi(l[1]);
+  for(j=2;j<=n;j++){res=intersect(res,slocusEqi(l[j]));}
+  for(j=1;j<n;j++)
+  {
+     for(k=j+1;k<=n;k++){res=intersect(res,l[j]+l[k]);}
+  }
+  return(res);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r  = 0,(u,v,w,x,y,z),dp;
+   ideal i = wx,wy,wz,vx,vy,vz,ux,uy,uz,y3-x2;;
+   slocus(i);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+static proc slocusEqi (ideal i)
+"USAGE:   slocus(i);  i ideal
+RETURN:  ideal of singular locus of i if i is pure dimensional
+NOTE:    this proc returns i and c-minors of jacobian ideal of i where c is the
+         codimension of i. Hence, if i is not pure dimensional, slocus may
+         return an ideal such that its 0-locus is strictly contained in the
+         singular locus of i
+EXAMPLE: example slocus; shows an example
+"
+{
+  ideal ist=std(i);
+  if ( size(ist)==0 ) // we have a zero ideal
+  {
+     // the zero locus of the zero ideal is nonsingular
+     return( ideal(1) ) ;
+  }
+  if( deg( ist[1] ) == 0 ) // the ideal has a constant generator
+  {
+    return(ist);
+  }
+  int cod  = nvars(basering) - dim(ist);
+  i        = i + minor( jacob(i), cod );
+  return(i);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r  = 0,(x,y,z),ds;
+   ideal i = x5+y6+z6,x2+2y2+3z2;
+   slocus(i);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc qhspectrum (poly f, intvec w)
+"USAGE:   qhspectrum(f,w);  f=poly, w=intvec
+ASSUME:  f is a weighted homogeneous isolated singularity w.r.t. the weights
+         given by w; w must consist of as many positive integers as there
+         are variables of the basering
+COMPUTE: the spectral numbers of the w-homogeneous polynomial f, computed in a
+         ring of characteristic 0
+RETURN:  intvec  d,s1,...,su  where:
+         d = w-degree(f)  and  si/d = i-th spectral-number(f)
+         No return value if basering has parameters or if f is no isolated
+         singularity, displays a warning in this case.
+EXAMPLE: example qhspectrum; shows an example
+"
+{
+   int i,d,W;
+   intvec sp;
+   def r   = basering;
+   if( find(charstr(r),",")!=0 )
+   {
+       "// coefficient field must not have parameters!";
+       return();
+    }
+   ring s  = 0,x(1..nvars(r)),ws(w);
+   map phi = r,maxideal(1);
+   poly f  = phi(f);
+   d       = ord(f);
+   W       = sum(w)-d;
+   ideal k = std(jacob(f));
+   if( vdim(k) == -1 )
+   {
+       "// f is no isolated singuarity!";
+       return();
+    }
+   k = kbase(k);
+   for (i=1; i<=size(k); i++)
+   {
+      sp[i]=W+ord(k[i]);
+   }
+   list L  = sort(sp);
+   sp      = d,L[1];
+   return(sp);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r;
+   poly f=x3+y5+z2;
+   intvec w=10,6,15;
+   qhspectrum(f,w);
+   // the spectrum numbers are:
+   // 1/30,7/30,11/30,13/30,17/30,19/30,23/30,29/30
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc Tjurina (def id, list #)
+"USAGE:   Tjurina(id[,<any>]);  id=ideal or poly
+ASSUME:  id=ICIS (isolated complete intersection singularity)
+RETURN:  standard basis of Tjurina-module of id,
+         of type module if id=ideal, resp. of type ideal if id=poly.
+         If a second argument is present (of any type) return a list: @*
+           [1] = Tjurina number,
+           [2] = k-basis of miniversal deformation,
+           [3] = SB of Tjurina module,
+           [4] = Tjurina module
+DISPLAY: Tjurina number if printlevel >= 0 (default)
+NOTE:    Tjurina number = -1 implies that id is not an ICIS
+EXAMPLE: example Tjurina; shows examples
+"
+{
+//---------------------------- initialisation ---------------------------------
+  def i = simplify(id,10);
+  int tau,n = 0,size(i);
+  if( size(ideal(i))==1 ) { def m=i; }  // hypersurface case
+  else { def m=i*freemodule(n); }       // complete intersection case
+//--------------- compute Tjurina module, Tjurina number etc ------------------
+  def t1 = jacob(i)+m;                  // Tjurina module/ideal
+  def st1 = std(t1);                    // SB of Tjurina module/ideal
+  tau = vdim(st1);                      // Tjurina number
+  dbprint(printlevel-voice+3,"// Tjurina number = "+string(tau));
+  if( size(#)>0 )
+  {
+     def kB = kbase(st1);               // basis of miniversal deformation
+     return(tau,kB,st1,t1);
+  }
+  return(st1);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   int p      = printlevel;
+   printlevel = 1;
+   ring r     = 0,(x,y,z),ds;
+   poly f     = x5+y6+z7+xyz;        // singularity T[5,6,7]
+   list T     = Tjurina(f,"");
+   show(T[1]);                       // Tjurina number, should be 16
+   show(T[2]);                       // basis of miniversal deformation
+   show(T[3]);                       // SB of Tjurina ideal
+   show(T[4]); "";                   // Tjurina ideal
+   ideal j    = x2+y2+z2,x2+2y2+3z2;
+   show(kbase(Tjurina(j)));          // basis of miniversal deformation
+   hilb(Tjurina(j));                 // Hilbert series of Tjurina module
+   printlevel = p;
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc tjurina (ideal i)
+"USAGE:   tjurina(id);  id=ideal or poly
+ASSUME:  id=ICIS (isolated complete intersection singularity)
+RETURN:  int = Tjurina number of id
+NOTE:    Tjurina number = -1 implies that id is not an ICIS
+EXAMPLE: example tjurina; shows an example
+"
+{
+   return(vdim(Tjurina(i)));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r=32003,(x,y,z),(c,ds);
+   ideal j=x2+y2+z2,x2+2y2+3z2;
+   tjurina(j);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc T_1 (ideal id, list #)
+"USAGE:   T_1(id[,<any>]);  id = ideal or poly
+RETURN:  T_1(id): of type module/ideal if id is of type ideal/poly.
+         We call T_1(id) the T_1-module of id. It is a std basis of the
+         presentation of 1st order deformations of P/id, if P is the basering.
+         If a second argument is present (of any type) return a list of
+         3 modules:
+            [1]= T_1(id)
+            [2]= generators of normal bundle of id, lifted to P
+            [3]= module of relations of [2], lifted to P
+                 (note: transpose[3]*[2]=0 mod id)
+         The list contains all non-easy objects which must be computed
+         to get T_1(id).
+DISPLAY: k-dimension of T_1(id) if printlevel >= 0 (default)
+NOTE:    T_1(id) itself is usually of minor importance. Nevertheless, from it
+         all relevant information can be obtained. The most important are
+         probably vdim(T_1(id)); (which computes the Tjurina number),
+         hilb(T_1(id)); and kbase(T_1(id)).
+         If T_1 is called with two arguments, then matrix([2])*(kbase([1]))
+         represents a basis of 1st order semiuniversal deformation of id
+         (use proc 'deform', to get this in a direct way).
+         For a complete intersection the proc Tjurina is faster.
+EXAMPLE: example T_1; shows an example
+"
+{
+   def RR=basering;
+   list RRL=ringlist(RR);
+   if(RRL[4]!=0)
+   {
+      int aa=size(#);
+      ideal QU=RRL[4];
+      RRL[4]=ideal(0);
+      def RS=ring(RRL);
+      setring RS;
+      ideal id=imap(RR,id);
+      ideal QU=imap(RR,QU);
+      if(aa)
+      {
+         list RES=T_1(id+QU,1);
+      }
+      else
+      {
+         module RES=T_1(id+QU);
+      }
+      setring RR;
+      def RES=imap(RS,RES);
+      return(RES);
+   }
+   ideal J=simplify(id,10);
+//--------------------------- hypersurface case -------------------------------
+  if( size(J)<2 )
+  {
+     ideal t1  = std(J+jacob(J[1]));
+     module nb = [1]; module pnb;
+     dbprint(printlevel-voice+3,"// dim T_1 = "+string(vdim(t1)));
+     if( size(#)>0 )
+     {
+        module st1 = t1*gen(1);
+        attrib(st1,"isSB",1);
+        return(st1,nb,pnb);
+     }
+     return(t1);
+  }
+//--------------------------- presentation of J -------------------------------
+   int rk;
+   def P = basering;
+   module jac, t1;
+   jac  = jacob(J);                 // jacobian matrix of J converted to module
+   list A=nres(J,2);                // compute presentation of J
+   def A(1..2)=A[1..2]; kill A;     // A(2) = 1st syzygy module of J
+//---------- go to quotient ring mod J and compute normal bundle --------------
+   qring  R    = std(J);
+   module jac = fetch(P,jac);
+   module t1  = transpose(fetch(P,A(2)));
+   list B=nres(t1,2);               // resolve t1, B(2)=(J/J^2)*=normal_bdl
+   def B(1..2)=B[1..2]; kill B;
+   t1         = modulo(B(2),jac);   // pres. of normal_bdl/trivial_deformations
+   rk=nrows(t1);
+//-------------------------- pull back to basering ----------------------------
+   setring P;
+   t1 = fetch(R,t1)+J*freemodule(rk);  // T_1-module, presentation of T_1
+   t1 = std(t1);
+   dbprint(printlevel-voice+3,"// dim T_1 = "+string(vdim(t1)));
+   if( size(#)>0 )
+   {
+      module B2 = fetch(R,B(2));        // presentation of normal bundle
+      list L = t1,B2,A(2);
+      attrib(L[1],"isSB",1);
+      return(L);
+   }
+   return(t1);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   int p      = printlevel;
+   printlevel = 1;
+   ring r     = 32003,(x,y,z),(c,ds);
+   ideal i    = xy,xz,yz;
+   module T   = T_1(i);
+   vdim(T);                      // Tjurina number = dim_K(T_1), should be 3
+   list L=T_1(i,"");
+   module kB  = kbase(L[1]);
+   print(L[2]*kB);               // basis of 1st order miniversal deformation
+   show(L[2]);                   // presentation of normal bundle
+   print(L[3]);                  // relations of i
+   print(transpose(L[3])*L[2]);  // should be 0 (mod i)
+   printlevel = p;
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc T_2 (ideal id, list #)
+"USAGE:   T_2(id[,<any>]);  id = ideal
+RETURN:  T_2(id): T_2-module of id . This is a std basis of a presentation of
+         the module of obstructions of R=P/id, if P is the basering.
+         If a second argument is present (of any type) return a list of
+         4 modules and 1 ideal:
+            [1]= T_2(id)
+            [2]= standard basis of id (ideal)
+            [3]= module of relations of id (=1st syzygy module of id) @*
+            [4]= presentation of syz/kos
+            [5]= relations of Hom_P([3]/kos,R), lifted to P
+         The list contains all non-easy objects which must be computed
+         to get T_2(id).
+DISPLAY: k-dimension of T_2(id) if printlevel >= 0 (default)
+NOTE:    The most important information is probably vdim(T_2(id)).
+         Use proc miniversal to get equations of the miniversal deformation.
+EXAMPLE: example T_2; shows an example
+"
+{
+   def RR=basering;
+   list RRL=ringlist(RR);
+   if(RRL[4]!=0)
+   {
+      int aa=size(#);
+      ideal QU=RRL[4];
+      RRL[4]=ideal(0);
+      def RS=ring(RRL);
+      setring RS;
+      ideal id=imap(RR,id);
+      ideal QU=imap(RR,QU);
+      if(aa)
+      {
+         list RES=T_2(id+QU,1);
+      }
+      else
+      {
+         module RES=T_2(id+QU);
+      }
+      setring RR;
+      def RES=imap(RS,RES);
+      return(RES);
+   }
+
+//--------------------------- initialisation ----------------------------------
+  def P = basering;
+   ideal J = id;
+   module kos,SK,B2,t2;
+   list L;
+   int n,rk;
+//------------------- presentation of non-trivial syzygies --------------------
+   list A=nres(J,2);                      // resolve J, A(2)=syz
+   def A(1..2)=A[1..2]; kill A;
+   kos  = koszul(2,J);                    // module of Koszul relations
+   SK   = modulo(A(2),kos);               // presentation of syz/kos
+   ideal J0 = std(J);                     // standard basis of J
+//?*** sollte bei der Berechnung von res mit anfallen, zu aendern!!
+//---------------------- fetch to quotient ring mod J -------------------------
+   qring R = J0;                          // make P/J the basering
+   module A2' = transpose(fetch(P,A(2))); // dual of syz
+   module t2  = transpose(fetch(P,SK));   // dual of syz/kos
+   list B=nres(t2,2);                     // resolve (syz/kos)*
+   def B(1..2)=B[1..2]; kill B;
+   t2 = modulo(B(2),A2');                 // presentation of T_2
+   rk = nrows(t2);
+//---------------------  fetch back to basering -------------------------------
+   setring P;
+   t2 = fetch(R,t2)+J*freemodule(rk);
+   t2 = std(t2);
+   dbprint(printlevel-voice+3,"// dim T_2 = "+string(vdim(t2)));
+   if( size(#)>0 )
+   {
+      B2 = fetch(R,B(2));        // generators of Hom_P(syz/kos,R)
+      L  = t2,J0,A(2),SK,B2;
+      return(L);
+   }
+   return(t2);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   int p      = printlevel;
+   printlevel = 1;
+   ring  r    = 32003,(x,y),(c,dp);
+   ideal j    = x6-y4,x6y6,x2y4-x5y2;
+   module T   = T_2(j);
+   vdim(T);
+   hilb(T);"";
+   ring r1    = 0,(x,y,z),dp;
+   ideal id   = xy,xz,yz;
+   list L     = T_2(id,"");
+   vdim(L[1]);                           // vdim of T_2
+   print(L[3]);                          // syzygy module of id
+   printlevel = p;
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc T_12 (ideal i, list #)
+"USAGE:   T_12(i[,any]);  i = ideal
+RETURN:  T_12(i): list of 2 modules: @*
+           *  standard basis of T_1-module =T_1(i), 1st order deformations @*
+           *  standard basis of T_2-module =T_2(i), obstructions of R=P/i @*
+         If a second argument is present (of any type) return a list of
+         9 modules, matrices, integers: @*
+             [1]= standard basis of T_1-module
+             [2]= standard basis of T_2-module
+             [3]= vdim of T_1
+             [4]= vdim of T_2
+             [5]= matrix, whose cols present infinitesimal deformations @*
+             [6]= matrix, whose cols are generators of relations of i(=syz(i)) @*
+             [7]= matrix, presenting Hom_P(syz/kos,R), lifted to P @*
+             [8]= presentation of T_1-module, no std basis
+             [9]= presentation of T_2-module, no std basis
+DISPLAY: k-dimension of T_1 and T_2 if printlevel >= 0 (default)
+NOTE:    Use proc miniversal from deform.lib to get miniversal deformation of i,
+         the list contains all objects used by proc miniversal.
+EXAMPLE: example T_12; shows an example
+"
+{
+   def RR=basering;
+   list RRL=ringlist(RR);
+   if(RRL[4]!=0)
+   {
+      int aa=size(#);
+      ideal QU=RRL[4];
+      RRL[4]=ideal(0);
+      def RS=ring(RRL);
+      setring RS;
+      ideal id=imap(RR,id);
+      ideal QU=imap(RR,QU);
+      if(aa)
+      {
+         list RES=T_12(id+QU,1);
+      }
+      else
+      {
+         list RES=T_12(id+QU);
+      }
+      setring RR;
+      list RES=imap(RS,RES);
+      return(RES);
+   }
+
+//--------------------------- initialisation ----------------------------------
+   int  n,r1,r2,d1,d2;
+   def P = basering;
+   i = simplify(i,10);
+   module jac,t1,t2,sbt1,sbt2;
+   matrix Kos,Syz,SK,kbT_1,Sx;
+   list L;
+   ideal  i0 = std(i);
+//-------------------- presentation of non-trivial syzygies -------------------
+   list I= nres(i,2);                           // resolve i
+   Syz  = matrix(I[2]);                         // syz(i)
+   jac = jacob(i);                              // jacobi ideal
+   Kos = koszul(2,i);                           // koszul-relations
+   SK  = modulo(Syz,Kos);                       // presentation of syz/kos
+//--------------------- fetch to quotient ring  mod i -------------------------
+   qring   Ox  = i0;                             // make P/i the basering
+   module Jac = fetch(P,jac);
+   matrix No  = transpose(fetch(P,Syz));        // ker(No) = Hom(syz,Ox)
+   module So  = transpose(fetch(P,SK));         // Hom(syz/kos,R)
+   list resS  = nres(So,2);
+   matrix Sx  = resS[2];
+   list resN  = nres(No,2);
+   matrix Nx  = resN[2];
+   module T_2  = modulo(Sx,No);                  // presentation of T_2
+   r2         = nrows(T_2);
+   module T_1  = modulo(Nx,Jac);                 // presentation of T_1
+   r1         = nrows(T_1);
+//------------------------ pull back to basering ------------------------------
+   setring P;
+   t1   = fetch(Ox,T_1)+i*freemodule(r1);
+   t2   = fetch(Ox,T_2)+i*freemodule(r2);
+   sbt1 = std(t1);
+   d1   = vdim(sbt1);
+   sbt2 = std(t2);
+   d2   = vdim(sbt2);
+   dbprint(printlevel-voice+3,"// dim T_1 = "+string(d1),"// dim T_2 = "+string(d2));
+   if  ( size(#)>0)
+   {
+     if (d1>0)
+     {
+       kbT_1 = fetch(Ox,Nx)*kbase(sbt1);
+     }
+     else
+     {
+       kbT_1 = 0;
+     }
+     Sx   = fetch(Ox,Sx);
+     L = sbt1,sbt2,d1,d2,kbT_1,Syz,Sx,t1,t2;
+     return(L);
+   }
+   L = sbt1,sbt2;
+   return(L);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   int p      = printlevel;
+   printlevel = 1;
+   ring r     = 199,(x,y,z,u,v),(c,ws(4,3,2,3,4));
+   ideal i    = xz-y2,yz2-xu,xv-yzu,yu-z3,z2u-yv,zv-u2;
+                            //a cyclic quotient singularity
+   list L     = T_12(i,1);
+   print(L[5]);             //matrix of infin. deformations
+   printlevel = p;
+}
+///////////////////////////////////////////////////////////////////////////////
+proc codim (def id1,def id2)
+"USAGE:   codim(id1,id2); id1,id2 ideal or module, both must be standard bases
+RETURN:  int, which is:
+         1. the vectorspace dimension of id1/id2 if id2 is contained in id1
+            and if this number is finite@*
+         2. -1 if the dimension of id1/id2 is infinite@*
+         3. -2 if id2 is not contained in id1
+COMPUTE: consider the Hilbert series iv1(t) of id1 and iv2(t) of id2.
+         If codim(id1,id2) is finite,  q(t)=(iv2(t)-iv1(t))/(1-t)^n is
+         rational, and the codimension is the sum of the coefficients of q(t)
+         (n = dimension of basering).
+EXAMPLE: example codim; shows an example
+"
+{
+   if (attrib(id1,"isSB")!=1) { "first argument of codim is not a SB";}
+   if (attrib(id2,"isSB")!=1) { "second argument of codim is not a SB";}
+   intvec iv1, iv2, iv;
+   int i, d1, d2, dd, i1, i2, ia, ie;
+  //--------------------------- check id2 < id1 -------------------------------
+   ideal led = lead(id1);
+   attrib(led, "isSB",1);
+   i = size(NF(lead(id2),led));
+   if ( i > 0 )
+   {
+     return(-2);
+   }
+  //--------------------------- 1. check finiteness ---------------------------
+   i1 = dim(id1);
+   i2 = dim(id2);
+   if (i1 < 0)
+   {
+     if ( i2 < 0 )
+     {
+        return(0);
+     }
+     if (i2 == 0)
+     {
+       return (vdim(id2));
+     }
+     else
+     {
+       return(-1);
+     }
+   }
+   if (i2 != i1)
+   {
+     return(-1);
+   }
+   if (i2 <= 0)
+   {
+     return(vdim(id2)-vdim(id1));
+   }
+ // if (mult(id2) != mult(id1))
+ //{
+ //  return(-1);
+ // }
+  //--------------------------- module ---------------------------------------
+   d1 = nrows(id1);
+   d2 = nrows(id2);
+   dd = 0;
+   if (d1 > d2)
+   {
+     id2=id2,maxideal(1)*gen(d1);
+     dd = -1;
+   }
+   if (d2 > d1)
+   {
+     id1=id1,maxideal(1)*gen(d2);
+     dd = 1;
+   }
+  //--------------------------- compute first hilbertseries ------------------
+   iv1 = hilb(id1,1);
+   i1 = size(iv1);
+   iv2 = hilb(id2,1);
+   i2 = size(iv2);
+  //--------------------------- difference of hilbertseries ------------------
+   if (i2 > i1)
+   {
+     for ( i=1; i<=i1; i=i+1)
+     {
+       iv2[i] = iv2[i]-iv1[i];
+     }
+     ie = i2;
+     iv = iv2;
+   }
+   else
+   {
+     for ( i=1; i<=i2; i=i+1)
+     {
+       iv1[i] = iv2[i]-iv1[i];
+     }
+     iv = iv1;
+     for (ie=i1;ie>=0;ie=ie-1)
+     {
+       if (ie == 0)
+       {
+         return(0);
+       }
+       if (iv[ie] != 0)
+       {
+         break;
+       }
+     }
+   }
+   ia = 1;
+   while (iv[ia] == 0) { ia=ia+1; }
+  //--------------------------- ia <= nonzeros <= ie -------------------------
+   iv1 = iv[ia];
+   for(i=ia+1;i<=ie;i=i+1)
+   {
+     iv1=iv1,iv[i];
+   }
+  //--------------------------- compute second hilbertseries -----------------
+   iv2 = hilb(iv1);
+  //--------------------------- check finitenes ------------------------------
+   i2 = size(iv2);
+   i1 = ie - ia + 1 - i2;
+   if (i1 != nvars(basering))
+   {
+     return(-1);
+   }
+  //--------------------------- compute result -------------------------------
+   i1 = 0;
+   for ( i=1; i<=i2; i=i+1)
+   {
+     i1 = i1 + iv2[i];
+   }
+   return(i1+dd);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r  = 0,(x,y),dp;
+   ideal j = y6,x4;
+   ideal m = x,y;
+   attrib(m,"isSB",1);  //let Singular know that ideals are a standard basis
+   attrib(j,"isSB",1);
+   codim(m,j);          // should be 23 (Milnor number -1 of y7-x5)
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc tangentcone (def id,list #)
+"USAGE:   tangentcone(id [,n]); id = ideal, n = int
+RETURN:  the tangent cone of id
+NOTE:    The procedure works for any monomial ordering.
+         If n=0 use std w.r.t. local ordering ds, if n=1 use locstd.
+EXAMPLE: example tangentcone; shows an example
+"
+{
+  int ii,n;
+  def bas = basering;
+  ideal tang;
+  if (size(#) !=0) { n= #[1]; }
+  if( n==0 )
+  {
+     def @newr@=changeord(list(list("ds",1:nvars(basering))));
+     setring @newr@;
+     ideal @id = imap(bas,id);
+     @id = std(@id);
+     setring bas;
+     id = imap(@newr@, at id);
+     kill @newr@;
+  }
+  else
+  {
+    id = locstd(id);
+  }
+
+  for(ii=1; ii<=size(id); ii++)
+  {
+    tang[ii]=jet(id[ii],mindeg(id[ii]));
+  }
+  return(tang);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring R = 0,(x,y,z),ds;
+   ideal i  = 7xyz+z5,x2+y3+z7,5z5+y5;
+   tangentcone(i);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc locstd (def id)
+"USAGE:   locstd (id); id = ideal
+RETURN:  a standard basis for a local degree ordering
+NOTE:    the procedure homogenizes id w.r.t. a new 1st variable @t@, computes
+         a SB w.r.t. (dp(1),dp) and substitutes @t@ by 1.
+         Hence the result is a SB with respect to an ordering which sorts
+         first w.r.t. the order and then refines it with dp. This is a
+         local degree ordering.
+         This is done in order to avoid cancellation of units and thus
+         be able to use option(contentSB);
+EXAMPLE: example locstd; shows an example
+"
+{
+  int ii;
+  def bas = basering;
+  execute("ring  @r_locstd
+     =("+charstr(bas)+"),(@t@,"+varstr(bas)+"),(dp(1),dp);");
+  ideal @id = imap(bas,id);
+  ideal @hid = homog(@id, at t@);
+  @hid = std(@hid);
+  @hid = subst(@hid, at t@,1);
+  setring bas;
+  def @hid = imap(@r_locstd, at hid);
+  attrib(@hid,"isSB",1);
+  kill @r_locstd;
+  return(@hid);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring R = 0,(x,y,z),ds;
+   ideal i  = xyz+z5,2x2+y3+z7,3z5+y5;
+   locstd(i);
+}
diff --git a/Singular/LIB/sing4ti2.lib b/Singular/LIB/sing4ti2.lib
new file mode 100644
index 0000000..ccf7da5
--- /dev/null
+++ b/Singular/LIB/sing4ti2.lib
@@ -0,0 +1,383 @@
+///////////////////////////////////////////////////////////////
+version="version sing4ti2.lib 4.0.0.0 Jun_2013 "; // $Id: 6d7207e5dcaaff4625f6b70022f78ea194c8dcd2 $
+category="Commutative Algebra";
+info="
+LIBRARY:  sing4ti2.lib          Communication Interface to 4ti2
+
+AUTHORS:  Thomas Kahle , kahle at mis.mpg.de
+@*        Anne Fruehbis-Krueger, anne at math.uni-hannover.de
+
+NOTE: This library uses the external program 4ti2 for calculations
+@*    and the standard unix tools sed and awk for conversion of
+@*    the returned result
+
+PROCEDURES:
+markov4ti2(A[,i])   compute Markov basis of given lattice
+hilbert4ti2(A[,i])  compute Hilbert basis of given lattice
+graver4ti2(A[,i])   compute Graver basis of given lattice
+";
+
+
+proc markov4ti2(matrix A, list #)
+"USAGE:  markov4ti2(A[,i]);
+@*       A=intmat
+@*       i=int
+ASSUME:  - A is a matrix with integer entries which describes the lattice
+@*         as ker(A), if second argument is not present,
+@*         as left image Im(A) = {zA, z \in ZZ^k}(!), if second argument is a positive integer
+@*       - number of variables of basering equals number of columns of A
+@*         (for ker(A)) resp. of rows of A (for Im(A))
+CREATE:  files sing4ti2.mat, sing4ti2.lat, sing4ti2.mar in the current
+@*       directory (I/O files for communication with 4ti2)
+NOTE:    input rules for 4ti2 also apply to input to this procedure
+@*       hence ker(A)={x|Ax=0} and Im(A)={xA}
+RETURN:  toric ideal specified by Markov basis thereof
+EXAMPLE: example markov4ti2; shows an example
+"
+{
+//--------------------------------------------------------------------------
+// Initialization and Sanity Checks
+//--------------------------------------------------------------------------
+   int i,j;
+   int nr=nrows(A);
+   int nc=ncols(A);
+   string fileending="mat";
+   if (size(#)!=0)
+   {
+//--- default behaviour: use ker(A) as lattice
+//--- if #[1]!=0 use Im(A) as lattice
+      if(typeof(#[1])!="int")
+      {
+         ERROR("optional parameter needs to be integer value");\
+      }
+      if(#[1]!=0)
+      {
+         fileending="lat";
+      }
+   }
+//--- we should also be checking whether all entries are indeed integers
+//--- or whether there are fractions, but in this case the error message
+//--- of 4ti2 is printed directly
+   if(nvars(basering)!=ncols(A))
+      {
+          ERROR("number of columns needs to match number of variables");
+      }
+//--------------------------------------------------------------------------
+// preparing input file for 4ti2
+//--------------------------------------------------------------------------
+   link eing=":w sing4ti2."+fileending;
+   string eingstring=string(nr)+" "+string(nc);
+   write(eing,eingstring);
+   for(i=1;i<=nr;i++)
+   {
+      kill eingstring;
+      string eingstring;
+      for(j=1;j<=nc;j++)
+      {
+          if((deg(A[i,j])>0)||(char(basering)!=0)||(npars(basering)>0))
+          {
+             ERROR("Input to markov4ti2 needs to be a matrix with integer entries");
+          }
+          eingstring=eingstring+string(A[i,j])+" ";
+      }
+      write(eing, eingstring);
+   }
+   close(eing);
+
+//----------------------------------------------------------------------
+// calling 4ti2 and converting output
+// Singular's string is too clumsy for this, hence we first prepare
+// using standard unix commands
+//----------------------------------------------------------------------
+   j=system("sh","markov sing4ti2 >/dev/null 2>&1");
+   j=system("sh","awk \'BEGIN{ORS=\",\";}{print $0;}\' sing4ti2.mar | sed s/[\\\ \\\t\\\v\\\f]/,/g | sed s/,+/,/g|sed s/,,/,/g|sed s/,,/,/g > sing4ti2.converted");
+   if(!defined(keepfiles))
+   {
+      j=system("sh",("rm -f sing4ti2.mar sing4ti2."+fileending));
+   }
+//----------------------------------------------------------------------
+// reading output of 4ti2
+//----------------------------------------------------------------------
+   link ausg=":r sing4ti2.converted";
+//--- last entry ideal(0) is used to tie the list to the basering
+//--- it will not be processed any further
+   string ergstr="list erglist="+read(ausg)+ string(ideal(0))+";";
+   execute(ergstr);
+   ideal toric;
+   poly temppol1,temppol2;
+   for(i=1;i<=erglist[1];i++)
+   {
+     temppol1=1;
+     temppol2=1;
+     for(j=1;j<=erglist[2];j++)
+     {
+        if(erglist[2+(i-1)*erglist[2]+j]>=0)
+        {
+//--- positive exponents
+           temppol1=temppol1*(var(j)^erglist[2+(i-1)*erglist[2]+j]);
+        }
+        else
+        {
+//--- negative exponents
+           temppol2=temppol2*(var(j)^(-erglist[2+(i-1)*erglist[2]+j]));
+        }
+     }
+     toric=toric,temppol1-temppol2;
+   }
+//--- get rid of leading entry 0;
+   toric=toric[2..ncols(toric)];
+   return(toric);
+}
+example
+{"EXAMPLE:";
+   echo=2;
+   ring r=0,(x,y,z),dp;
+   matrix M[2][3]=0,1,2,2,1,0;
+   markov4ti2(M);
+   matrix N[1][3]=1,2,1;
+   markov4ti2(N,1);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc graver4ti2(matrix A, list #)
+"USAGE:  graver4ti2(A[,i]);
+@*       A=intmat
+@*       i=int
+ASSUME:  - A is a matrix with integer entries which describes the lattice
+@*         as ker(A), if second argument is not present,
+@*         as the left image Im(A) = {zA : z \in ZZ^k}, if second argument is a positive integer
+@*       - number of variables of basering equals number of columns of A
+@*         (for ker(A)) resp. of rows of A (for Im(A))
+CREATE:  temporary files sing4ti2.mat, sing4ti2.lat, sing4ti2.gra
+@*       in the current directory (I/O files for communication with 4ti2)
+NOTE:    input rules for 4ti2 also apply to input to this procedure
+@*       hence ker(A)={x|Ax=0} and Im(A)={xA}
+RETURN:  toric ideal specified by Graver basis thereof
+EXAMPLE: example graver4ti2; shows an example
+"
+{
+//--------------------------------------------------------------------------
+// Initialization and Sanity Checks
+//--------------------------------------------------------------------------
+   int i,j;
+   int nr=nrows(A);
+   int nc=ncols(A);
+   string fileending="mat";
+   if (size(#)!=0)
+   {
+//--- default behaviour: use ker(A) as lattice
+//--- if #[1]!=0 use Im(A) as lattice
+      if(typeof(#[1])!="int")
+      {
+         ERROR("optional parameter needs to be integer value");\
+      }
+      if(#[1]!=0)
+      {
+         fileending="lat";
+      }
+   }
+//--- we should also be checking whether all entries are indeed integers
+//--- or whether there are fractions, but in this case the error message
+//--- of 4ti2 is printed directly
+      if(nvars(basering)!=ncols(A))
+      {
+          ERROR("number of columns needs to match number of variables");
+      }
+//--------------------------------------------------------------------------
+// preparing input file for 4ti2
+//--------------------------------------------------------------------------
+   link eing=":w sing4ti2."+fileending;
+   string eingstring=string(nr)+" "+string(nc);
+   write(eing,eingstring);
+   for(i=1;i<=nr;i++)
+   {
+      kill eingstring;
+      string eingstring;
+      for(j=1;j<=nc;j++)
+      {
+          if((deg(A[i,j])>0)||(char(basering)!=0)||(npars(basering)>0))
+          {
+             ERROR("Input to graver4ti2 needs to be a matrix with integer entries");
+          }
+          eingstring=eingstring+string(A[i,j])+" ";
+      }
+      write(eing, eingstring);
+   }
+   close(eing);
+
+//----------------------------------------------------------------------
+// calling 4ti2 and converting output
+// Singular's string is too clumsy for this, hence we first prepare
+// using standard unix commands
+//----------------------------------------------------------------------
+   j=system("sh","graver sing4ti2 >/dev/null 2>&1");
+   j=system("sh","awk \'BEGIN{ORS=\",\";}{print $0;}\' sing4ti2.gra | sed s/[\\\ \\\t\\\v\\\f]/,/g | sed s/,+/,/g |sed s/,,/,/g|sed s/,,/,/g > sing4ti2.converted");
+   if(!defined(keepfiles))
+   {
+      j=system("sh",("rm -f sing4ti2.gra sing4ti2."+fileending));
+   }
+//----------------------------------------------------------------------
+// reading output of 4ti2
+//----------------------------------------------------------------------
+   link ausg=":r sing4ti2.converted";
+//--- last entry ideal(0) is used to tie the list to the basering
+//--- it will not be processed any further
+   string ergstr="list erglist="+read(ausg)+ string(ideal(0))+";";
+   execute(ergstr);
+   ideal toric;
+   poly temppol1,temppol2;
+   for(i=1;i<=erglist[1];i++)
+   {
+     temppol1=1;
+     temppol2=1;
+     for(j=1;j<=erglist[2];j++)
+     {
+        if(erglist[2+(i-1)*erglist[2]+j]>=0)
+        {
+//--- positive exponents
+           temppol1=temppol1*(var(j)^erglist[2+(i-1)*erglist[2]+j]);
+        }
+        else
+        {
+//--- negative exponents
+           temppol2=temppol2*(var(j)^(-erglist[2+(i-1)*erglist[2]+j]));
+        }
+     }
+     toric=toric,temppol1-temppol2;
+   }
+//--- get rid of leading entry 0;
+   toric=toric[2..ncols(toric)];
+   return(toric);
+}
+example
+{"EXAMPLE:";
+   echo=2;
+   ring r=0,(x,y,z,w),dp;
+   matrix M[2][4]=0,1,2,3,3,2,1,0;
+   graver4ti2(M);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc hilbert4ti2(matrix A, list #)
+"USAGE:  hilbert4ti2(A[,i]);
+@*       A=intmat
+@*       i=int
+ASSUME:  - A is a matrix with integer entries which describes the lattice
+@*         as ker(A), if second argument is not present,
+@*         as the left image Im(A) = {zA : z \in ZZ^k}, if second argument is a positive integer
+@*       - number of variables of basering equals number of columns of A
+@*         (for ker(A)) resp. of rows of A (for Im(A))
+CREATE:  temporary files sing4ti2.mat, sing4ti2.lat, sing4ti2.mar
+@*       in the current directory (I/O files for communication with 4ti2)
+NOTE:    input rules for 4ti2 also apply to input to this procedure
+@*       hence ker(A)={x|Ax=0} and Im(A)={xA}
+RETURN:  toric ideal specified by Hilbert basis thereof
+EXAMPLE: example graver4ti2; shows an example
+"
+{
+//--------------------------------------------------------------------------
+// Initialization and Sanity Checks
+//--------------------------------------------------------------------------
+   int i,j;
+   int nr=nrows(A);
+   int nc=ncols(A);
+   string fileending="mat";
+   if (size(#)!=0)
+   {
+//--- default behaviour: use ker(A) as lattice
+//--- if #[1]!=0 use Im(A) as lattice
+      if(typeof(#[1])!="int")
+      {
+         ERROR("optional parameter needs to be integer value");\
+      }
+      if(#[1]!=0)
+      {
+         fileending="lat";
+      }
+   }
+//--- we should also be checking whether all entries are indeed integers
+//--- or whether there are fractions, but in this case the error message
+//--- of 4ti2 is printed directly
+      if(nvars(basering)!=ncols(A))
+      {
+          ERROR("number of columns needs to match number of variables");
+      }
+//--------------------------------------------------------------------------
+// preparing input file for 4ti2
+//--------------------------------------------------------------------------
+   link eing=":w sing4ti2."+fileending;
+   string eingstring=string(nr)+" "+string(nc);
+   write(eing,eingstring);
+   for(i=1;i<=nr;i++)
+   {
+      kill eingstring;
+      string eingstring;
+      for(j=1;j<=nc;j++)
+      {
+          if((deg(A[i,j])>0)||(char(basering)!=0)||(npars(basering)>0))
+          {
+             ERROR("Input to hilbert4ti2 needs to be a matrix with integer entries");
+          }
+          eingstring=eingstring+string(A[i,j])+" ";
+      }
+      write(eing, eingstring);
+   }
+   close(eing);
+
+//----------------------------------------------------------------------
+// calling 4ti2 and converting output
+// Singular's string is too clumsy for this, hence we first prepare
+// using standard unix commands
+//----------------------------------------------------------------------
+   j=system("sh","hilbert sing4ti2 >/dev/null 2>&1");
+   j=system("sh","awk \'BEGIN{ORS=\",\";}{print $0;}\' sing4ti2.hil | sed s/[\\\ \\\t\\\v\\\f]/,/g | sed s/,+/,/g |sed s/,,/,/g|sed s/,,/,/g > sing4ti2.converted");
+   if(!defined(keepfiles))
+   {
+      j=system("sh",("rm -f sing4ti2.hil sing4ti2."+fileending));
+   }
+//----------------------------------------------------------------------
+// reading output of 4ti2
+//----------------------------------------------------------------------
+   link ausg=":r sing4ti2.converted";
+//--- last entry ideal(0) is used to tie the list to the basering
+//--- it will not be processed any further
+   string ergstr="list erglist="+read(ausg)+ string(ideal(0))+";";
+   execute(ergstr);
+   ideal toric;
+   poly temppol1,temppol2;
+   for(i=1;i<=erglist[1];i++)
+   {
+     temppol1=1;
+     temppol2=1;
+     for(j=1;j<=erglist[2];j++)
+     {
+        if(erglist[2+(i-1)*erglist[2]+j]>=0)
+        {
+//--- positive exponents
+           temppol1=temppol1*(var(j)^erglist[2+(i-1)*erglist[2]+j]);
+        }
+        else
+        {
+//--- negative exponents
+           temppol2=temppol2*(var(j)^(-erglist[2+(i-1)*erglist[2]+j]));
+        }
+     }
+     toric=toric,temppol1-temppol2;
+   }
+//--- get rid of leading entry 0;
+   toric=toric[2..ncols(toric)];
+   return(toric);
+}
+// A nice example here is the 3x3 Magic Squares
+example
+{"EXAMPLE:";
+   echo=2;
+   ring r=0,(x1,x2,x3,x4,x5,x6,x7,x8,x9),dp;
+   matrix M[7][9]=1,1,1,-1,-1,-1,0,0,0,1,1,1,0,0,0,-1,-1,-1,0,1,1,-1,0,0,-1,0,0,1,0,1,0,-1,0,0,-1,0,1,1,0,0,0,-1,0,0,-1,0,1,1,0,-1,0,0,0,-1,1,1,0,0,-1,0,-1,0,0;
+   hilbert4ti2(M);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
diff --git a/Singular/LIB/solve.lib b/Singular/LIB/solve.lib
new file mode 100644
index 0000000..a55d509
--- /dev/null
+++ b/Singular/LIB/solve.lib
@@ -0,0 +1,2237 @@
+////////////////////////////////////////////////////////////////////////////
+version="version solve.lib 4.0.0.0 Jun_2013 "; // $Id: 64be0dd86d499508ce7e77758fc36d99d8c68459 $
+category="Symbolic-numerical solving";
+info="
+LIBRARY: solve.lib     Complex Solving of Polynomial Systems
+AUTHOR:  Moritz Wenk,  email: wenk at mathematik.uni-kl.de
+         Wilfred Pohl, email: pohl at mathematik.uni-kl.de
+
+PROCEDURES:
+laguerre_solve(p,[..]); find all roots of univariate polynomial p
+solve(i,[..]);          all roots of 0-dim. ideal i using triangular sets
+ures_solve(i,[..]);     find all roots of 0-dimensional ideal i with resultants
+mp_res_mat(i,[..]);     multipolynomial resultant matrix of ideal i
+interpolate(p,v,d);     interpolate polynomial from evaluation points i and results j
+fglm_solve(i,[..]);     find roots of 0-dim. ideal using FGLM and lex_solve
+lex_solve(i,p,[..]);    find roots of reduced lexicographic standard basis
+simplexOut(l);          prints solution of simplex in nice format
+triangLf_solve(l,[..]); find roots using triangular sys. (factorizing Lazard)
+triangM_solve(l,[..]);  find roots of given triangular system (Moeller)
+triangL_solve(l,[..]);  find roots using triangular system (Lazard)
+triang_solve(l,p,[..]); find roots of given triangular system
+";
+
+LIB "triang.lib";    // needed for triang_solve
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc laguerre_solve( poly f, list # )
+"USAGE:   laguerre_solve(f [, m, l, n, s] ); f = polynomial,@*
+         m, l, n, s = integers (control parameters of the method)@*
+ m: precision of output in digits ( 4 <= m), if basering is not ring of
+      complex numbers;
+ l: precision of internal computation in decimal digits ( l >=8 )
+      only if the basering is not complex or complex with smaller precision;@*
+ n: control of multiplicity of roots or of splitting of f into
+      squarefree factors
+      n < 0, no split of f (good, if all roots are simple)
+      n >= 0, try to split
+      n = 0, return only different roots
+      n > 0, find all roots (with multiplicity)
+ s: s != 0, returns ERROR if  | f(root) | > 0.1^m (when computing in the
+      current ring)
+ ( default: m, l, n, s = 8, 30, 1, 0 )
+ASSUME:  f is a univariate polynomial;@*
+         basering has characteristic 0 and is either complex or without
+         parameters.
+RETURN:  list of (complex) roots of the polynomial f, depending on n. The
+         entries of the result are of type@*
+          string: if the basering is not complex,@*
+          number: otherwise.
+NOTE:    If printlevel >0: displays comments ( default = 0 ).
+         If s != 0 and if the procedure stops with ERROR, try a higher
+         internal precision m.
+EXAMPLE: example laguerre_solve; shows an example
+"
+{
+  if (char(basering)!=0){ERROR("characteristic of basering not 0");}
+  if ((charstr(basering)[1]=="0") and (npars(basering)!=0))
+    {ERROR("basering has parameters");}
+  int OLD_COMPLEX=0;
+  int iv=checkv(f);  // check for variable appearing in f
+  if(iv==0){ERROR("Wrong polynomial!");}
+  poly v=var(iv);    // f univariate in v
+
+  int solutionprec=8;// set the control
+  int numberprec=30;
+  int splitcontrol=1;
+  int rootcheck=0;
+  if(size(#)>0){solutionprec=#[1];if(solutionprec<4){solutionprec=4;}}
+  if(size(#)>1){numberprec=#[2];if(numberprec<8){numberprec=8;}}
+  if(solutionprec>numberprec){numberprec=solutionprec;}
+  if(size(#)>2){splitcontrol=#[3];}
+  if(size(#)>3){rootcheck=#[4];}
+  int prot=printlevel-voice+2;
+  int ringprec=0;
+
+  poly p=divzero(f,iv); // divide out zeros as solution
+  int iz=deg(f)-deg(p); // multiplicity of zero solution
+  if(prot!=0)
+  {
+    string pout;
+    string nl=newline;
+    pout="//BEGIN laguerre_solve";
+    if(iz!=0){pout=pout+nl+"//zeros: divide out "+string(iz);}
+    dbprint(prot,pout);
+  }
+  string ss,tt,oo;
+  ss="";oo=ss;
+  if(npars(basering)==1)
+  {
+    if(OLD_COMPLEX)
+    {
+      tt="1,"+string(par(1));
+      if(tt==charstr(basering))
+      {ss=tt;ringprec=system("getPrecDigits");}
+    }
+    else
+    {
+      tt=charstr(basering);
+      if(size(tt)>7)
+      {
+        if(string(tt[1..7])=="complex")
+        {
+          ss=tt;
+          ringprec=system("getPrecDigits");
+        }
+      }
+    }
+  }
+
+  list roots,simple;
+  if(deg(p)==0) // only zero was root
+  {
+    roots=addzero(roots,ss,iz,splitcontrol);
+    if(prot!=0){dbprint(prot,"//END laguerre_solve");}
+    return(roots);
+  }
+
+  if(prot!=0)// more informations
+  {
+    pout="//control: complex ring with precision "+string(numberprec);
+    if(size(ss)==0){pout=pout+nl+
+        "//         basering not complex, hence solutiontype string";
+    if(solutionprec<numberprec){pout=pout+nl+
+        "//         with precision "+string(solutionprec);}}
+    if(splitcontrol<0){pout=pout+nl+ "//       no spliting";}
+    if(splitcontrol==0){pout=pout+nl+"//       output without multiple roots";}
+    if(rootcheck){pout=pout+nl+
+        "//         check roots with precision "+string(solutionprec);}
+    dbprint(prot,pout);
+  }
+
+  def rn = basering;// set the complex ground field
+  if (ringprec<numberprec)
+  {
+    tt="ring lagc=(complex,"+string(numberprec)+","+string(numberprec)+
+       "),"+string(var(iv))+",lp;";
+    execute(tt);
+    poly p=imap(rn,p);
+    poly v=var(1);
+  }
+  int ima=0;
+  if(size(ss)!=0){ima=checkim(p);}
+  number prc=0.1;// set precision of the solution
+  prc=prc^solutionprec;
+  if(prot!=0)
+  {
+    if(ringprec<numberprec){pout="//working in:  "+tt;}
+    if((size(ss)!=0)&&(ima!=0)){pout=pout+nl+
+        "//         polynomial has complex coefficients";}
+    dbprint(prot,pout);
+  }
+
+  int i1=1;
+  int i2=1;
+  ideal SPLIT=p;
+  if(splitcontrol>=0)// splitting
+  {
+    if(prot!=0){dbprint(prot,"//split in working ring:");}
+    SPLIT=splitsqrfree(p,v);
+    i1=size(SPLIT);
+    if((i1==1)&&(charstr(rn)=="0"))
+    {
+      if(prot!=0){dbprint(prot,"//split exact in basering:");}
+      setring rn;
+      if(v>1)
+      {
+        ideal SQQQQ=splitsqrfree(p,v);
+        setring lagc;
+        SPLIT=imap(rn,SQQQQ);
+      }
+      else
+      {
+        oo="ring exa=0,"+string(var(1))+",lp;";
+        execute(oo);
+        ideal SQQQQ=splitsqrfree(imap(rn,p),var(1));
+        setring lagc;
+        SPLIT=imap(exa,SQQQQ);
+        kill exa;
+      }
+      i1=size(SPLIT);
+    }
+    if(prot!=0)
+    {
+      if(i1>1)
+      {
+        int i3=deg(SPLIT[1]);
+        pout="//results of split(the squarefree factors):";
+        if(i3>0){pout=pout+nl+
+           "//  multiplicity "+string(i2)+", degree "+string(i3);}
+        while(i2<i1)
+        {
+          i2++;
+          i3=deg(SPLIT[i2]);
+          if(i3>0){pout=pout+nl+
+             "//  multiplicity "+string(i2)+", degree "+string(i3);}
+        }
+        dbprint(prot,pout);
+        i2=1;
+      }
+      else
+      {
+        if(charstr(rn)=="0"){dbprint(prot,"// polynomial is squarefree");}
+        else{dbprint(prot,"//split without result");}
+      }
+    }
+  }
+
+  p=SPLIT[1];// the first part
+  if(deg(p)>0)
+  {
+    roots=laguerre(p,numberprec,1);// the ring is already complex, hence numberprec is dummy
+    if((size(roots)==0)||(string(roots[1])=="0")){ERROR("laguerre: no roots found");}
+    if(rootcheck){checkroots(p,v,roots,ima,prc);}
+  }
+  while(i2<i1)
+  {
+    i2++;
+    p=SPLIT[i2];// the part with multiplicity i2
+    if(deg(p)>0)
+    {
+      simple=laguerre(p,numberprec,1);
+      if((size(simple)==0)||(string(simple[1])=="0")){ERROR("laguerre: no roots found");}
+      if(rootcheck){checkroots(p,v,simple,ima,prc);}
+      if(splitcontrol==0)// no multiple roots
+      {
+        roots=roots+simple;
+      }
+      else// multiple roots
+      {
+        roots=roots+makemult(simple,i2);
+      }
+    }
+  }
+
+  if((solutionprec<numberprec)&&(size(ss)==0))// shorter output
+  {
+    oo="ring lout=(complex,"+string(solutionprec)+",1),"
+    +string(var(1))+",lp;";
+    execute(oo);
+    list roots=imap(lagc,roots);
+    roots=transroots(roots);
+    if(iz>0){roots=addzero(roots,ss,iz,splitcontrol);}
+    if(prot!=0){dbprint(prot,"//END laguerre_solve");}
+    return(roots);
+  }
+  if(size(ss)==0){roots=transroots(roots);}// transform to string
+  else         // or map in basering
+  {
+    if(ringprec<numberprec)
+    {
+      setring rn;
+      list roots=imap(lagc,roots);
+    }
+  }
+  if(iz>0){roots=addzero(roots,ss,iz,splitcontrol);}
+  if(prot!=0){dbprint(prot,"//END laguerre_solve");}
+  return(roots);
+}
+example
+{
+    "EXAMPLE:";echo=2;
+    // Find all roots of an univariate polynomial using Laguerre's method:
+    ring rs1= 0,(x,y),lp;
+    poly f = 15x5 + x3 + x2 - 10;
+    // 10 digits precision
+    laguerre_solve(f,10);
+
+    // Now with complex coefficients,
+    // internal precision is 30 digits (default)
+    printlevel=2;
+    ring rsc= (real,10,i),x,lp;
+    poly f = (15.4+i*5)*x^5 + (25.0e-2+i*2)*x^3 + x2 - 10*i;
+    list l = laguerre_solve(f);
+    l;
+    // check result, value of substituted polynomial should be near to zero
+    // remember that l contains a list of strings
+    // in the case of a different ring
+    subst(f,x,l[1]);
+    subst(f,x,l[2]);
+}
+//////////////////////////////////////////////////////////////////////////////
+//                subprocedures for laguerre_solve
+/*
+*  if p depends only on var(i)
+*       returns i
+*  otherwise    0
+*/
+static proc checkv(poly p)
+{
+  int n=nvars(basering);
+  int i=0;
+  int v;
+
+  while (n>0)
+  {
+    if ((p-subst(p,var(n),0))!=0)
+    {
+      i++;
+      if (i>1){return(0);}
+      v=n;
+    }
+    n--;
+  }
+  return(v);
+}
+/*
+*  if p has only real coefficients
+*       returns 0
+*  otherwise    1
+*/
+static proc checkim(poly p)
+{
+  poly q=p;
+
+  while(q!=0)
+  {
+    if(impart(leadcoef(q))!=0){return(1);}
+    q=q-lead(q);
+  }
+  return(0);
+}
+/*
+*  make multiplicity m
+*/
+static proc makemult(list si,int m)
+{
+  int k0=0;
+  int k1=size(si);
+  int k2,k3;
+  number ro;
+  list msi;
+
+  for(k2=1;k2<=k1;k2++)
+  {
+    ro=si[k2];
+    for(k3=m;k3>0;k3--){k0++;msi[k0]=ro;}
+  }
+  return(msi);
+}
+/*
+*  returns 1 for n<1
+*/
+static proc cmp1(number n)
+{
+  number r=repart(n);
+  number i=impart(n);
+  number c=r*r+i*i;
+  if(c>1){return(1);}
+  else{return(0);}
+}
+/*
+*  exact division of polys f/g
+*  (should be internal)
+*/
+static proc exdiv(poly f,poly g,poly v)
+{
+  int d1=deg(f);
+  int d2=deg(g);
+  poly r0=f;
+  poly rf=0;
+  poly h;
+  number n,m;
+
+  m=leadcoef(g);
+  while ((r0!=0)&&(d1>=d2))
+  {
+    n=leadcoef(r0)/m;
+    h=n*v^(d1-d2);
+    rf=rf+h;
+    r0=r0-h*g;
+    d1=deg(r0);
+  }
+  return(cleardenom(rf));
+}
+/*
+*  p is univariant in x
+*  perform a split of p into squarefree factors
+*  such that the returned ideal 'split' consists of
+*  the faktors, i.e.
+*    p = n * product ( split[i]^i ) , n a number
+*/
+static proc splitsqrfree(poly p, poly x)
+{
+  int dd=deg(p);
+  if(dd==1){return(p);}
+  int i=1;
+  int j;
+  ideal h,split;
+  poly high;
+
+  h=interred(ideal(p,diff(p,x)));
+  if(deg(h[1])==0){return(p);}
+  high=h[1];
+  split[1]=exdiv(p,high,x);
+  while(1)
+  {
+    h=interred(ideal(split[i],high));
+    j=deg(h[1]);
+    if(j==0){return(p);}
+    if(deg(h[1])==deg(split[i]))
+    {
+      split=split,split[i];
+      split[i]=1;
+    }
+    else
+    {
+      split[i]=exdiv(split[i],h[1],x);
+      split=split,h[1];
+      dd=dd-deg(split[i])*i;
+    }
+    j=j*(i+1);
+    if(j==dd){break;}
+    if(j>dd){return(p);}
+    high=exdiv(high,h[1],x);
+    if(deg(high)==0){return(p);}
+    i++;
+  }
+  return(split);
+}
+/*
+*  see checkroots
+*/
+static proc nerr(number n,number m)
+{
+  int r;
+  number z=0;
+  number nr=repart(n);
+  number ni=impart(n);
+  if(nr<z){nr=z-nr;}
+  if(ni<z){ni=nr-ni;}
+  else{ni=nr+ni;}
+  if(ni<m){r=0;}
+  else{r=1;}
+  return(r);
+}
+/*
+*  returns ERROR for nerr(p(r[i]))>=pr
+*/
+static proc checkroots(poly p,poly v,list r,int ima,number pr)
+{
+  int i=0;
+  int j;
+  number n,m;
+  ideal li;
+
+  while(i<size(r))
+  {
+    i++;
+    n=r[i];
+    j=cmp1(n);
+    if(j!=0){li[1]=v/n-1;m=1;}
+    else{li[1]=v-n;m=n;}
+    if((ima==0)&&(impart(n)!=0))
+    {
+      i++;
+      n=r[i];
+      if(j!=0){li[1]=li[1]*(v/n-1);}
+      else{li[1]=li[1]*(v-n);m=m*n;}
+    }
+    attrib(li,"isSB",1);
+    n=leadcoef(reduce(p,li));n=n/m;
+    if(n!=0)
+    {if(nerr(n,pr)!=0){ERROR("Unsufficient accuracy!");}}
+  }
+}
+/*
+*  transforms thr result to string
+*/
+static proc transroots(list r)
+{
+  int i=size(r);
+  while (i>0)
+  {
+    r[i]=string(r[i]);
+    i--;
+  }
+  return(r);
+}
+/*
+* returns a polynomial without zeroroots
+*/
+static proc divzero(poly f,int iv)
+{
+  poly p=f;
+  poly q=p;
+  poly r;
+  while(p==q)
+  {
+    q=p/var(iv);
+    r=q*var(iv);
+    if(r==p){p=q;}
+  }
+  return(p);
+}
+/*
+*  add zeros to solution
+*/
+static proc addzero(list zz,string ss,int iz,int a)
+{
+    int i=1;
+    int j=size(zz);
+
+    if(size(ss)==0){zz[j+1]="0";}
+    else{zz[j+1]=number(0);}
+    if(a==0){return(zz);}
+    while(i<iz)
+    {
+      i++;
+      if(size(ss)==0){zz[j+i]="0";}
+      else{zz[j+i]=number(0);}
+    }
+    return(zz);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc solve( ideal G, list # )
+"USAGE:   solve(G [, m, n [, l]] [,\"oldring\"] [,\"nodisplay\"] ); G = ideal,
+         m, n, l = integers (control parameters of the method), outR ring,@*
+         m: precision of output in digits ( 4 <= m) and of the generated ring
+            of complex numbers;
+         n: control of multiplicity
+            n = 0, return all different roots
+            n != 0, find all roots (with multiplicity)
+         l: precision of internal computation in decimal digits ( l >=8 )
+            only if the basering is not complex or complex with smaller
+            precision, @*
+         [default: (m,n,l) = (8,0,30), or if only (m,n) are set explicitly
+          with n!=0, then (m,n,l) = (m,n,60) ]
+ASSUME:  the ideal is 0-dimensional;@*
+         basering has characteristic 0 and is either complex or without
+         parameters;
+RETURN:  (1) If called without the additional parameter @code{\"oldring\"}: @*
+         ring @code{R} with the same number of variables but with complex
+         coefficients (and precision m). @code{R} comes with a list
+         @code{SOL} of numbers, in which complex roots of G are stored: @*
+         * If n  = 0, @code{SOL} is the list of all different solutions, each
+         of them being represented by a list of numbers. @*
+         * If n != 0, @code{SOL} is a list of two list: SOL[i][1] is the list
+         of all different solutions with the multiplicity SOL[i][2].@*
+         SOL is ordered w.r.t. multiplicity (the smallest first). @*
+         (2) If called with the additional parameter @code{\"oldring\"}, the
+         procedure looks for an appropriate ring (at top level) in which
+         the solutions can be stored (interactive). @*
+         The user may then select an appropriate ring and choose a name for
+         the output list in this ring. The list is exported directly to the
+         selected ring and the return value is a string \"result exported to\"
+         + name of the selected ring.
+NOTE:    If the problem is not 0-dim. the procedure stops with ERROR. If the
+         ideal G is not a lexicographic Groebner basis, the lexicographic
+         Groebner basis is computed internally (Hilbert driven).  @*
+         The computed solutions are displayed, unless @code{solve} is called
+         with the additional parameter @code{\"nodisplay\"}.
+EXAMPLE: example solve; shows an example
+"
+{
+// test if basering admissible
+  if (char(basering)!=0){ERROR("characteristic of basering not 0");}
+  if ((charstr(basering)[1]=="0") and (npars(basering)!=0))
+  { ERROR("basering has parameters"); }
+
+// some global settings and control
+  int oldr, nodisp, ii, jj;
+  list LL;
+  int outprec = 8;
+  int mu = 0;
+  int prec = 30;
+  // check additional parameters...
+  if (size(#)>0)
+  {
+    int sofar=1;
+    if (typeof(#[1])=="int")
+    {
+      outprec = #[1];
+      if (outprec<4){outprec = 4;}
+      if (size(#)>1)
+      {
+        if (typeof(#[2])=="int")
+        {
+          mu = #[2];
+          if (size(#)>2)
+          {
+            if (typeof(#[3])=="int")
+            {
+              prec = #[3];
+              if (prec<8){prec = 8;}
+            }
+            else
+            {
+              if(mu!=0){prec = 60;}
+              if (#[3]=="oldring"){ oldr=1; }
+              if (#[3]=="nodisplay"){ nodisp=1; }
+            }
+            sofar=3;
+          }
+        }
+        else
+        {
+          if (#[2]=="oldring"){ oldr=1; }
+          if (#[2]=="nodisplay"){ nodisp=1; }
+        }
+        sofar=2;
+      }
+    }
+    else
+    {
+      if (#[1]=="oldring"){ oldr=1; }
+      if (#[1]=="nodisplay"){ nodisp=1; }
+    }
+    for (ii=sofar+1;ii<=size(#);ii++)
+    { // check for additional strings
+      if (typeof(#[ii])=="string")
+      {
+        if (#[ii]=="oldring"){ oldr=1; }
+        if (#[ii]=="nodisplay"){ nodisp=1; }
+      }
+    }
+  }
+  if (outprec>prec){prec = outprec;}
+  // if interaktive version is chosen -- choice of basering (Top::`outR`)
+  // and name for list of solutions (outL):
+  if (oldr==1)
+  {
+    list Out;
+    LL=names(Top);
+    for (ii=1;ii<=size(LL);ii++)
+    {
+      if (typeof(`LL[ii]`)=="ring")
+      {
+        if (find(charstr(`LL[ii]`),"complex,"+string(outprec)))
+        {
+          jj++;
+          Out[jj]=LL[ii];
+        }
+      }
+    }
+    if (size(Out)>0)
+    {
+      print("// *** You may select between the following rings for storing "+
+            "the list of");
+      print("// *** complex solutions:");
+      Out;
+      print("// *** Enter the number of the chosen ring");
+      print("// ***  (0: none of them => new ring created and returned)");
+      string chosen;
+      while (chosen=="") { chosen=read(""); }
+      execute("def tchosen = "+chosen);
+      if (typeof(tchosen)=="int")
+      {
+        if ((tchosen>0) and (tchosen<=size(Out)))
+        {
+          string outR = Out[tchosen];
+          print("// *** You have chosen the ring "+ outR +". In this ring"
+                +" the following objects");
+          print("//*** are defined:");
+          listvar(Top::`outR`);
+          print("// *** Enter a name for the list of solutions (different "+
+                "from existing names):");
+          string outL;
+          while (outL==""){ outL=read(""); }
+        }
+      }
+    }
+    else
+    {
+      print("No appropriate ring for storing the list of solutions found " +
+             "=> new ring created and returned");
+    }
+    if (not(defined(outR))) { oldr=0; }
+  }
+
+//  string rinC = nameof(basering)+"C";
+  string sord = ordstr(basering);
+  int nv = nvars(basering);
+  def rin = basering;
+  intvec ovec = option(get);
+  option(redSB);
+  option(returnSB);
+  int sb = attrib(G,"isSB");
+  int lp = 0;
+  if (size(sord)==size("C,lp()"+string(nv)))
+  {
+    lp = find(sord,"lp");
+  }
+
+// ERROR
+  if (sb){if (dim(G)!=0){ERROR("ideal not zero-dimensional");}}
+
+// the trivial homogeneous case (unique solution: (0,...0))
+  if (homog(G))
+  {
+    if (sb==0)
+    {
+      execute("ring dphom=("+charstr(rin)+"),("+
+      varstr(rin)+"),dp;");
+      ideal G = std(imap(rin,G));
+      if (dim(G)!=0){ERROR("ideal not zero-dimensional");}
+      int vdG=vdim(G);
+    }
+    if (oldr!=1)
+    {
+      execute("ring rinC =(complex,"+string(outprec)+
+                 "),("+varstr(basering)+"),lp;");
+      list SOL;
+      if (mu==0){SOL[1] = zerolist(nv);}
+      else{SOL[1] = list(zerolist(nv),list(vdG));}
+      export SOL;
+      if (nodisp==0) { print(SOL); }
+      option(set,ovec);
+      dbprint( printlevel-voice+3,"
+// 'solve' created a ring, in which a list SOL of numbers (the complex solutions)
+// is stored.
+// To access the list of complex solutions, type (if the name R was assigned
+// to the return value):
+        setring R; SOL; ");
+      return(rinC);
+    }
+    else
+    {
+      setring (Top::`outR`);
+      list SOL;
+      if (mu==0){SOL[1] = zerolist(nv);}
+      else{SOL[1] = list(zerolist(nv),list(vdG));}
+      execute("def "+outL + "=SOL;");
+      execute("export "+outL+";");
+      if (nodisp==0) { print(SOL); }
+      option(set,ovec);
+      kill SOL;
+      return("result exported to "+outR+" as list "+outL);
+    }
+  }
+
+// look for reduced standard basis in lex
+  if (sb*lp==0)
+  {
+    if (sb==0)
+    {
+      execute("ring dphilb=("+charstr(rin)+"),("+ varstr(rin)+"),dp;");
+      ideal G = imap(rin,G);
+      G = std(G);
+      if (dim(G)!=0){ERROR("ideal not zero-dimensional");}
+    }
+    else
+    {
+      def dphilb = basering;
+      G=interred(G);
+      attrib(G,"isSB",1);
+    }
+    execute("ring lexhilb=("+charstr(rin)+"),("+ varstr(rin)+"),lp;");
+    option(redTail);
+    ideal H = fglm(dphilb,G);
+    kill dphilb;
+    H = simplify(H,2);
+    if (lp){setring rin;}
+    else
+    {
+      execute("ring lplex=("+charstr(rin)+"),("+varstr(rin)+"),lp;");
+    }
+    ideal H = imap(lexhilb,H);
+    kill lexhilb;
+  }
+  else{ideal H = interred(G);}
+
+// only 1 variable
+  def hr = basering;
+  if (nv==1)
+  {
+    if ((mu==0) and (charstr(basering)[1]=="0"))
+    { // special case
+      list L = laguerre_solve(H[1],prec,prec,mu,0); // list of strings
+      if (oldr!=1)
+      {
+        execute("ring rinC =(complex,"+string(outprec)+"),("+varstr(basering)+"),lp;");
+        list SOL;
+        for (ii=1; ii<=size(L); ii++ ) { execute("SOL[ii]=number("+L[ii]+");"); }
+        export SOL;
+        if (nodisp==0) { print(SOL); }
+        option(set,ovec);
+        dbprint( printlevel-voice+3,"
+// 'solve' created a ring, in which a list SOL of numbers (the complex solutions)
+// is stored.
+// To access the list of complex solutions, type (if the name R was assigned
+// to the return value):
+        setring R; SOL; ");
+        return(rinC);
+      }
+      else
+      {
+        setring (Top::`outR`);
+        list SOL;
+        for (ii=1; ii<=size(L); ii++ ) { execute("SOL[ii]="+L[ii]+";"); }
+        execute("def "+outL + "=SOL;");
+        execute("export "+outL+";");
+        if (nodisp==0) { print(SOL); }
+        option(set,ovec);
+        kill SOL;
+        return("result exported to "+outR+" as list "+outL);
+      }
+    }
+    else
+    {
+      execute("ring internC=(complex,"+string(prec)+"),("+varstr(basering)+"),lp;");
+      ideal H = imap(hr,H);
+      list sp = splittolist(splitsqrfree(H[1],var(1)));
+      jj = size(sp);
+      while(jj>0)
+      {
+        sp[jj][1] = laguerre(sp[jj][1],prec,1);
+        jj--;
+      }
+      setring hr;
+      if (oldr!=1)
+      {
+        execute("ring rinC =(complex,"+string(outprec)+"),("+varstr(basering)+"),lp;");
+        list SOL;
+        list sp=imap(internC,sp);
+        if(mu!=0){ SOL=sp; }
+        else
+        {
+          jj = size(sp);
+          SOL=sp[jj][1];
+          while(jj>1)
+          {
+            jj--;
+            SOL = sp[jj][1]+SOL;
+          }
+        }
+        export SOL;
+        if (nodisp==0) { print(SOL); }
+        option(set,ovec);
+        dbprint( printlevel-voice+3,"
+// 'solve' created a ring, in which a list SOL of numbers (the complex solutions)
+// is stored.
+// To access the list of complex solutions, type (if the name R was assigned
+// to the return value):
+        setring R; SOL; ");
+        return(rinC);
+      }
+      else
+      {
+        setring (Top::`outR`);
+        list SOL;
+        list sp=imap(internC,sp);
+        if(mu!=0){ SOL=sp; }
+        else
+        {
+          jj = size(sp);
+          SOL=sp[jj][1];
+          while(jj>1)
+          {
+            jj--;
+            SOL = sp[jj][1]+SOL;
+          }
+        }
+        kill sp;
+        execute("def "+outL + "=SOL;");
+        execute("export "+outL+";");
+        if (nodisp==0) { print(SOL); }
+        option(set,ovec);
+        kill SOL;
+        return("result exported to "+outR+" as list "+outL);
+      }
+    }
+  }
+
+// the triangular sets (not univariate case)
+  attrib(H,"isSB",1);
+  if (mu==0)
+  {
+    list sp = triangMH(H); // faster, but destroy multiplicity
+  }
+  else
+  {
+    list sp = triangM(H);
+  }
+
+//   create the complex ring and map the result
+  if (outprec<prec)
+  {
+    execute("ring internC=(complex,"+string(prec)+"),("+varstr(hr)+"),lp;");
+  }
+  else
+  {
+    execute("ring rinC =(complex,"+string(outprec)+"),("+varstr(basering)+"),lp;");
+  }
+  list triC = imap(hr,sp);
+
+// solve the tridiagonal systems
+  int js = size(triC);
+  list ret1;
+  if (mu==0)
+  {
+    ret1 = trisolve(list(),triC[1],prec);
+    while (js>1)
+    {
+      ret1 = trisolve(list(),triC[js],prec)+ret1;
+      js--;
+    }
+  }
+  else
+  {
+    ret1 = mutrisolve(list(),triC[1],prec);
+    while (js>1)
+    {
+      ret1 = addlist(mutrisolve(list(),triC[js],prec),ret1,1);
+      js--;
+    }
+    ret1 = finalclear(ret1);
+  }
+
+// final computations
+  option(set,ovec);
+  if (outprec==prec)
+  { // we are in ring rinC
+    if (oldr!=1)
+    {
+      list SOL=ret1;
+      export SOL;
+      if (nodisp==0) { print(SOL); }
+      dbprint( printlevel-voice+3,"
+// 'solve' created a ring, in which a list SOL of numbers (the complex solutions)
+// is stored.
+// To access the list of complex solutions, type (if the name R was assigned
+// to the return value):
+        setring R; SOL; ");
+      return(rinC);
+    }
+    else
+    {
+      setring (Top::`outR`);
+      list SOL=imap(rinC,ret1);
+      execute("def "+outL + "=SOL;");
+      execute("export "+outL+";");
+      if (nodisp==0) { print(SOL); }
+      kill SOL;
+      return("result exported to "+outR+" as list "+outL);
+    }
+  }
+  else
+  {
+    if (oldr!=1)
+    {
+      execute("ring rinC =(complex,"+string(outprec)+"),("+varstr(basering)+"),lp;");
+      list SOL=imap(internC,ret1);
+      export SOL;
+      if (nodisp==0) { print(SOL); }
+      dbprint( printlevel-voice+3,"
+// 'solve' created a ring, in which a list SOL of numbers (the complex solutions)
+// is stored.
+// To access the list of complex solutions, type (if the name R was assigned
+// to the return value):
+        setring R; SOL; ");
+      return(rinC);
+    }
+    else
+    {
+      setring (Top::`outR`);
+      list SOL=imap(internC,ret1);
+      execute("def "+outL + "=SOL;");
+      execute("export "+outL+";");
+      if (nodisp==0) { print(SOL); }
+      kill SOL;
+      return("result exported to "+outR+" as list "+outL);
+    }
+  }
+}
+example
+{
+    "EXAMPLE:";echo=2;
+    // Find all roots of a multivariate ideal using triangular sets:
+    int d,t,s = 4,3,2 ;
+    int i;
+    ring A=0,x(1..d),dp;
+    poly p=-1;
+    for (i=d; i>0; i--) { p=p+x(i)^s; }
+    ideal I = x(d)^t-x(d)^s+p;
+    for (i=d-1; i>0; i--) { I=x(i)^t-x(i)^s+p,I; }
+    I;
+    // the multiplicity is
+    vdim(std(I));
+    def AC=solve(I,6,0,"nodisplay");  // solutions should not be displayed
+    // list of solutions is stored in AC as the list SOL (default name)
+    setring AC;
+    size(SOL);               // number of different solutions
+    SOL[5];                  // the 5th solution
+    // you must start with char. 0
+    setring A;
+    def AC1=solve(I,6,1,"nodisplay");
+    setring AC1;
+    size(SOL);               // number of different multiplicities
+    SOL[1][1][1];            // a solution with
+    SOL[1][2];               // multiplicity 1
+    SOL[2][1][1];            // a solution with
+    SOL[2][2];               // multiplicity 12
+    // the number of different solutions is equal to
+    size(SOL[1][1])+size(SOL[2][1]);
+    // the number of complex solutions (counted with multiplicities) is
+    size(SOL[1][1])*SOL[1][2]+size(SOL[2][1])*SOL[2][2];
+}
+//////////////////////////////////////////////////////////////////////////////
+//                subprocedures for solve
+
+
+/*
+* return one zero-solution
+*/
+static proc zerolist(int nv)
+{
+  list ret;
+  int i;
+  number o=0;
+
+  for (i=nv;i>0;i--){ret[i] = o;}
+  return(ret);
+}
+
+/* ----------------------- check solution ----------------------- */
+static proc multsol(list ff, int c)
+{
+  int i,j;
+
+  i = 0;
+  j = size(ff);
+  while (j>0)
+  {
+    if(c){i = i+ff[j][2]*size(ff[j][1]);}
+    else{i = i+size(ff[j][1]);}
+    j--;
+  }
+  return(i);
+}
+
+/*
+* the inputideal A => zero ?
+*/
+static proc checksol(ideal A, list lr)
+{
+  int d = nvars(basering);
+  list ro;
+  ideal re,h;
+  int i,j,k;
+
+  for (i=size(lr);i>0;i--)
+  {
+    ro = lr[i];
+    for (j=d;j>0;j--)
+    {
+      re[j] = var(j)-ro[j];
+    }
+    attrib(re,"isSB",1);
+    k = size(reduce(A,re,1));
+    if (k){return(i);}
+  }
+  return(0);
+}
+
+/*
+*  compare 2 solutions: returns 0 for equal
+*/
+static proc cmpn(list a,list b)
+{
+  int ii;
+
+  for(ii=size(a);ii>0;ii--){if(a[ii]!=b[ii]) break;}
+  return(ii);
+}
+
+/*
+*  delete equal solutions in the list
+*/
+static proc delequal(list r, int w)
+{
+  list h;
+  int i,j,k,c;
+
+  if (w)
+  {
+    k = size(r);
+    h = r[k][1];
+    k--;
+    while (k>0)
+    {
+      h = r[k][1]+h;
+      k--;
+    }
+  }
+  else{h = r;}
+  k=size(h);
+  i=1;
+  while(i<k)
+  {
+    j=k;
+    while(j>i)
+    {
+      c=cmpn(h[i],h[j]);
+      if(c==0)
+      {
+        h=delete(h,j);
+        k--;
+      }
+      j--;
+    }
+    i++;
+  }
+  return(h);
+}
+
+/* ----------------------- substitution ----------------------- */
+/*
+* instead of subst(T,var(v),n), much faster
+*   need option(redSB) !
+*/
+static proc linreduce(ideal T, int v, number n)
+{
+  ideal re = var(v)-n;
+  attrib (re,"isSB",1);
+  return (reduce(T,re));
+}
+
+/* ----------------------- triangular solution ----------------------- */
+/*
+* solution of one tridiagonal system T
+*   with precision prec
+*   T[1] is univariant in var(1)
+*   list o is empty for the first call
+*/
+static proc trisolve(list o, ideal T, int prec)
+{
+  list lroots,ll;
+  ideal S;
+  int i,d;
+
+  d = size(T);
+  S = interred(ideal(T[1],diff(T[1],var(d))));
+  if (deg(S[1]))
+  {
+    T[1] = exdiv(T[1],S[1],var(d));
+  }
+  ll = laguerre(T[1],prec,1);
+  for (i=size(ll);i>0;i--){ll[i] = list(ll[i])+o;}
+  if (d==1){return(ll);}
+  for (i=size(ll);i>0;i--)
+  {
+    S = linreduce(ideal(T[2..d]),d,ll[i][1]);
+    lroots = trisolve(ll[i],S,prec)+lroots;
+  }
+  return(lroots);
+}
+
+/* ------------------- triangular solution (mult) ------------------- */
+/*
+*  recompute equal solutions w.r.t. multiplicity
+*/
+static proc finalclear(list b)
+{
+  list a = b;
+  list r;
+  int i,l,ju,j,k,ku,mu,c;
+
+// a[i] only
+  i = 1;
+  while (i<=size(a))
+  {
+    ju = size(a[i][1]);
+    j = 1;
+    while (j<=ju)
+    {
+      mu = 1;
+      k = j+1;
+      while (k<=ju)
+      {
+        c = cmpn(a[i][1][j],a[i][1][k]);
+        if (c==0)
+        {
+          a[i][1] = delete(a[i][1],k);
+          ju--;
+          mu++;
+        }
+        else{k++;}
+      }
+      if (mu>1)
+      {
+        r[1] = a[i];
+        r[1][1] = list(a[i][1][j]);
+        a[i][1] = delete(a[i][1],j);
+        a = addlist(r,a,mu);
+        ju--;
+      }
+      else{j++;}
+    }
+    if (ju==0){a = delete(a,i);}
+    else{i++;}
+  }
+// a[i], a[l]
+  i = 1;
+  while (i<size(a))
+  {
+    ju = size(a[i][1]);
+    l = i+1;
+    while (l<=size(a))
+    {
+      ku = size(a[l][1]);
+      j = 1;
+      while (j<=ju)
+      {
+        mu = 0;
+        k = 1;
+        while (k<=ku)
+        {
+          c = cmpn(a[i][1][j],a[l][1][k]);
+          if (c==0)
+          {
+            mu = a[i][2]+a[l][2];
+            r[1] = a[l];
+            r[1][1] = list(a[l][1][k]);
+            r[1][2] = mu;
+            a[l][1] = delete(a[l][1],k);
+            a = addlist(r,a,1);
+            ku--;
+            break;
+          }
+          else{k++;}
+        }
+        if (mu)
+        {
+          a[i][1] = delete(a[i][1],j);
+          ju--;
+        }
+        else{j++;}
+      }
+      if (ku){l++;}
+      else
+      {
+        a = delete(a,l);
+      }
+    }
+    if (ju){i++;}
+    else
+    {
+      a = delete(a,i);
+    }
+  }
+  return(a);
+}
+
+/*
+* convert to list
+*/
+static proc splittolist(ideal sp)
+{
+  int j = size(sp);
+  list spl = list(list(sp[j],j));
+
+  j--;
+  while (j>0)
+  {
+    if (deg(sp[j]))
+    {
+      spl = list(list(sp[j],j))+spl;
+    }
+    j--;
+  }
+  return(spl);
+}
+
+/*
+*  multiply the multiplicity
+*/
+static proc multlist(list a, int m)
+{
+  int i;
+  for (i=size(a);i>0;i--){a[i][2] = a[i][2]*m;}
+  return(a);
+}
+
+/*
+*  a+b w.r.t. to multiplicity as ordering
+*    (programming like spolys)
+*/
+static proc addlist(list a, list b, int m)
+{
+  int i,j,k,l,s;
+  list r = list();
+
+  if (m>1){a = multlist(a,m);}
+  k = size(a);
+  l = size(b);
+  i = 1;
+  j = 1;
+  while ((i<=k)&&(j<=l))
+  {
+    s = a[i][2]-b[j][2];
+    if (s>=0)
+    {
+      r = r+list(b[j]);
+      j++;
+      if (s==0)
+      {
+        s = size(r);
+        r[s][1] = r[s][1]+a[i][1];
+        i++;
+      }
+    }
+    else
+    {
+      r = r+list(a[i]);
+      i++;
+    }
+  }
+  if (i>k)
+  {
+    if (j<=l){r = r+list(b[j..l]);}
+  }
+  else{r = r+list(a[i..k]);}
+  return(r);
+}
+
+/*
+* solution of one tridiagonal system T with multiplicity
+*   with precision prec
+*   T[1] is univariant in var(1)
+*   list o is empty for the first call
+*/
+static proc mutrisolve(list o, ideal T, int prec)
+{
+  list lroots,ll,sp;
+  ideal S,h;
+  int i,d,m,z;
+
+  d = size(T);
+  sp = splittolist(splitsqrfree(T[1],var(d)));
+  if (d==1){return(l_mutrisolve(sp,o,prec));}
+  z = size(sp);
+  while (z>0)
+  {
+    m = sp[z][2];
+    ll = laguerre(sp[z][1],prec,1);
+    i = size(ll);
+    while(i>0)
+    {
+      h = linreduce(ideal(T[2..d]),d,ll[i]);
+      if (size(lroots))
+      {
+        lroots = addlist(mutrisolve(list(ll[i])+o,h,prec),lroots,m);
+      }
+      else
+      {
+        lroots = mutrisolve(list(ll[i])+o,h,prec);
+        if (m>1){lroots=multlist(lroots,m);}
+      }
+      i--;
+    }
+    z--;
+  }
+  return(lroots);
+}
+
+/*
+*  the last call, we are ready
+*/
+static proc l_mutrisolve(list sp, list o, int prec)
+{
+  list lroots,ll;
+  int z,m,i;
+
+  z = size(sp);
+  while (z>0)
+  {
+    m = sp[z][2];
+    ll = laguerre(sp[z][1],prec,1);
+    for (i=size(ll);i>0;i--){ll[i] = list(ll[i])+o;}
+    if (size(lroots))
+    {
+      lroots = addlist(list(list(ll,m)),lroots,1);
+    }
+    else
+    {
+      lroots = list(list(ll,m));
+    }
+    z--;
+  }
+  return(lroots);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc ures_solve( ideal gls, list # )
+"USAGE:   ures_solve(i [, k, p] ); i = ideal, k, p = integers
+   k=0: use sparse resultant matrix of Gelfand, Kapranov and Zelevinsky, @*
+   k=1: use resultant matrix of Macaulay which works only for
+          homogeneous ideals,@*
+   p>0: defines precision of the long floats for internal computation
+          if the basering is not complex (in decimal digits),
+   (default: k=0, p=30)
+ASSUME:  i is a zerodimensional ideal given by a quadratic system, that is,@*
+         nvars(basering) = ncols(i) = number of vars actually occurring in i,
+RETURN:  If the ground field is the field of complex numbers: list of numbers
+         (the complex roots of the polynomial system i=0). @*
+         Otherwise: ring @code{R} with the same number of variables but with
+         complex coefficients (and precision p). @code{R} comes with a list
+         @code{SOL} of numbers, in which complex roots of the polynomial
+         system i are stored: @*
+EXAMPLE: example ures_solve; shows an example
+"
+{
+  int typ=0;// defaults
+  int prec=30;
+
+  if ( size(#) > 0 )
+  {
+    typ= #[1];
+    if ( typ < 0 || typ > 1 )
+    {
+      ERROR("Valid values for second parameter k are:
+                   0: use sparse Resultant (default)
+                   1: use Macaulay Resultant");
+    }
+  }
+  if ( size(#) > 1 )
+  {
+    prec= #[2];
+    if ( prec < 8 )
+    {
+      prec = 8;
+    }
+  }
+
+  list LL=uressolve(gls,typ,prec,1);
+  int sizeLL=size(LL);
+  if (sizeLL==0)
+  {
+    dbprint(printlevel-voice+3,"No solution found!");
+    return(list());
+  }
+  if (typeof(LL[1][1])=="string")
+  {
+    int ii,jj;
+    int nv=size(LL[1]);
+    execute("ring rinC =(complex,"+string(prec)+",I),("
+                           +varstr(basering)+"),lp;");
+    list SOL,SOLnew;
+    for (ii=1; ii<=sizeLL; ii++)
+    {
+      SOLnew=list();
+      for (jj=1; jj<=nv; jj++)
+      {
+        execute("SOLnew["+string(jj)+"]="+LL[ii][jj]+";");
+      }
+      SOL[ii]=SOLnew;
+    }
+    kill SOLnew;
+    export SOL;
+    dbprint( printlevel-voice+3,"
+// 'ures_solve' created a ring, in which a list SOL of numbers (the complex
+// solutions) is stored.
+// To access the list of complex solutions, type (if the name R was assigned
+// to the return value):
+        setring R; SOL; ");
+    return(rinC);
+  }
+  else
+  {
+    return(LL);
+  }
+}
+example
+{
+    "EXAMPLE:";echo=2;
+    // compute the intersection points of two curves
+    ring rsq = 0,(x,y),lp;
+    ideal gls=  x2 + y2 - 10, x2 + xy + 2y2 - 16;
+    def R=ures_solve(gls,0,16);
+    setring R; SOL;
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc mp_res_mat( ideal i, list # )
+"USAGE:   mp_res_mat(i [, k] ); i ideal, k integer,
+    k=0: sparse resultant matrix of Gelfand, Kapranov and Zelevinsky,@*
+    k=1: resultant matrix of Macaulay (k=0 is default)
+ASSUME:  The number of elements in the input system must be the number of
+         variables in the basering plus one;
+         if k=1 then i must be homogeneous.
+RETURN:  module representing the multipolynomial resultant matrix
+EXAMPLE: example mp_res_mat; shows an example
+"
+{
+  int typ=0;
+
+  if ( size(#) > 0 )
+  {
+    typ= #[1];
+    if ( typ < 0 || typ > 1 )
+    {
+      ERROR("Valid values for third parameter are:
+                   0: sparse resultant (default)
+                   1: Macaulay resultant");
+    }
+  }
+  return(mpresmat(i,typ));
+}
+example
+{
+    "EXAMPLE:";echo=2;
+    // compute resultant matrix in ring with parameters (sparse resultant matrix)
+    ring rsq= (0,u0,u1,u2),(x1,x2),lp;
+    ideal i= u0+u1*x1+u2*x2,x1^2 + x2^2 - 10,x1^2 + x1*x2 + 2*x2^2 - 16;
+    module m = mp_res_mat(i);
+    print(m);
+    // computing sparse resultant
+    det(m);
+
+    // compute resultant matrix (Macaulay resultant matrix)
+    ring rdq= (0,u0,u1,u2),(x0,x1,x2),lp;
+    ideal h=  homog(imap(rsq,i),x0);
+    h;
+
+    module m = mp_res_mat(h,1);
+    print(m);
+    // computing Macaulay resultant (should be the same as above!)
+    det(m);
+
+    // compute numerical sparse resultant matrix
+    setring rsq;
+    ideal ir= 15+2*x1+5*x2,x1^2 + x2^2 - 10,x1^2 + x1*x2 + 2*x2^2 - 16;
+    module mn = mp_res_mat(ir);
+    print(mn);
+    // computing sparse resultant
+    det(mn);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc interpolate( ideal p, ideal w, int d )
+"USAGE:   interpolate(p,v,d); p,v=ideals of numbers, d=integer
+ASSUME:  Ground field K is the field of rational numbers, p and v are lists
+         of elements of the ground field K with p[j] != -1,0,1, size(p) = n
+         (= number of vars) and size(v)=N=(d+1)^n.
+RETURN:  poly f, the unique polynomial f of degree n*d with prescribed values
+         v[i] at the points p(i)=(p[1]^(i-1),..,p[n]^(i-1)), i=1,..,N.
+NOTE:    mainly useful when n=1, i.e. f is satisfying f(p^(i-1)) = v[i],
+         i=1..d+1.
+SEE ALSO: vandermonde.
+EXAMPLE: example interpolate; shows an example
+"
+{
+    return(vandermonde(p,w,d));
+}
+example
+{
+    "EXAMPLE:";  echo=2;
+    ring r1 = 0,(x),lp;
+    // determine f with deg(f) = 4 and
+    // v = values of f at points 3^0, 3^1, 3^2, 3^3, 3^4
+    ideal v=16,0,11376,1046880,85949136;
+    interpolate( 3, v, 4 );
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// changed for Singular 3
+// Return value is now a list: (rlist, rn@)
+static proc psubst( int d, int dd, int n, list resl,
+                    ideal fi, int elem, int nv, int prec, int rn@, list rlist)
+{
+    //   nv: number of ring variables         (fixed value)
+    // elem: number of elements in ideal fi   (fixed value)
+    //   fi: input ideal                      (fixed value)
+    //   rl: output list of roots
+    // resl: actual list of roots
+    //    n:
+    //   dd: actual element of fi
+    //    d: actual variable
+
+    list LL;
+    int pdebug;
+    int olddd=dd;
+
+    dbprint(printlevel-voice+2, "// 0 step "+string(dd)+" of "+string(elem) );
+
+    if ( dd <= elem )
+    {
+        int loop = 1;
+        int k;
+        list lsr,lh;
+        poly ps;
+        int thedd;
+
+        dbprint( printlevel-voice+1,"// 1 dd = "+string(dd) );
+
+        thedd=0;
+        while ( (dd+1 <= elem) && loop )
+        {
+            ps= fi[dd+1];
+
+            if ( n-1 > 0 )
+            {
+                dbprint( printlevel-voice,
+                    "// 2 ps=fi["+string(dd+1)+"]"+" size="
+                        +string(size(coeffs(ps,var(n-1))))
+                        +"  leadexp(ps)="+string(leadexp(ps)) );
+
+                if ( size(coeffs(ps,var(n-1))) == 1 )
+                {
+                    dd++;
+                    // hier Leading-Exponent pruefen???
+                    // oder ist das Polynom immer als letztes in der Liste?!?
+                    // leadexp(ps)
+                }
+                else
+                {
+                    loop=0;
+                }
+            }
+            else
+            {
+                dbprint( printlevel-voice,
+                    "// 2 ps=fi["+string(dd+1)+"]"+"  leadexp(ps)="
+                        +string(leadexp(ps)) );
+                dd++;
+            }
+        }
+        thedd=dd;
+        ps= fi[thedd];
+
+        dbprint( printlevel-voice+1,
+            "// 3    fi["+string(thedd-1)+"]"+"  leadexp(fi[thedd-1])="
+                +string(leadexp(fi[thedd-1])) );
+        dbprint( printlevel-voice+1,
+            "// 3 ps=fi["+string(thedd)+"]"+"  leadexp(ps)="
+                +string(leadexp(ps)) );
+
+        for ( k= nv; k > nv-d; k-- )
+        {
+            dbprint( printlevel-voice,
+                "// 4 subst(fi["+string(thedd)+"],"
+                    +string(var(k))+","+string(resl[k])+");" );
+            ps = subst(ps,var(k),resl[k]);
+        }
+
+        dbprint( printlevel-voice, "// 5 substituted ps="+string(ps) );
+
+        if ( ps != 0 )
+        {
+            lsr= laguerre_solve( ps, prec, prec, 0 );
+        }
+        else
+        {
+            dbprint( printlevel-voice+1,"// 30 ps == 0, thats not cool...");
+            lsr=list(number(0));
+        }
+
+        dbprint( printlevel-voice+1,
+         "// 6 laguerre_solve found roots: lsr["+string(size(lsr))+"]" );
+
+        if ( size(lsr) > 1 )
+        {
+            dbprint( printlevel-voice+1,
+                "// 10 checking roots found before, range "
+                    +string(dd-olddd)+" -- "+string(dd) );
+            dbprint( printlevel-voice+1,
+                "// 10 thedd = "+string(thedd) );
+
+            int i,j,l;
+            int ls=size(lsr);
+            int lss;
+            poly pss;
+            list nares;
+            int rroot;
+            int nares_size;
+
+
+            for ( i = 1; i <= ls; i++ ) // lsr[1..ls]
+            {
+                rroot=1;
+
+                if ( pdebug>=2 )
+                {"// 13 root lsr["+string(i)+"] = "+string(lsr[i]);}
+                for ( l = 0; l <= dd-olddd; l++ )
+                {
+                    if ( l+olddd != thedd )
+                    {
+                        if ( pdebug>=2 )
+                        {"// 11 checking ideal element "+string(l+olddd);}
+                        ps=fi[l+olddd];
+                        if ( pdebug>=3 )
+                        {"// 14 ps=fi["+string(l+olddd)+"]";}
+                        for ( k= nv; k > nv-d; k-- )
+                        {
+                            if ( pdebug>=3 )
+                            {
+                                "// 11 subst(fi["+string(olddd+l)+"],"
+                                    +string(var(k))+","+string(resl[k])+");";
+                            }
+                            ps = subst(ps,var(k),resl[k]);
+
+                        }
+
+                        pss=subst(ps,var(k),lsr[i]); // k=nv-d
+                        if ( pdebug>=3 )
+                        { "// 15 0 == "+string(pss); }
+                        if ( pss != 0 )
+                        {
+                            if ( system("complexNearZero",
+                                        leadcoef(pss),
+                                        prec) )
+                            {
+                                if ( pdebug>=2 )
+                                { "// 16 root "+string(i)+" is a real root"; }
+                            }
+                            else
+                            {
+                                if ( pdebug>=2 )
+                                { "// 17 0 == "+string(pss); }
+                                rroot=0;
+                            }
+                        }
+
+                    }
+                }
+
+                if ( rroot == 1 ) // add root to list ?
+                {
+                    if ( size(nares) > 0 )
+                    {
+                        nares=nares[1..size(nares)],lsr[i];
+                    }
+                    else
+                    {
+                        nares=lsr[i];
+                    }
+                    if ( pdebug>=2 )
+                    { "// 18 added root to list nares"; }
+                }
+            }
+
+            nares_size=size(nares);
+            if ( nares_size == 0 )
+            {
+                "Numerical problem: No root found...";
+                "Output may be incorrect!";
+                nares=list(number(0));
+            }
+
+            if ( pdebug>=1 )
+            { "// 20 found <"+string(size(nares))+"> roots"; }
+
+            for ( i= 1; i <= nares_size; i++ )
+            {
+                resl[nv-d]= nares[i];
+
+                if ( dd < elem )
+                {
+                    if ( i > 1 )
+                    {
+                        rn at ++;
+                    }
+                    LL = psubst( d+1, dd+1, n-1, resl, fi, elem, nv, prec,
+                                 rn@, rlist );
+                    rlist = LL[1];
+                    rn@ = LL[2];
+                }
+                else
+                {
+                   if ( i > 1 ) {  rn at ++; }  //bug found by O.Labs
+                   if ( pdebug>=1 )
+                   {"// 30_1 <"+string(rn@)+"> "+string(size(resl))+" <-----";}
+                   if ( pdebug>=2 ){ resl; }
+                   rlist[rn@]=resl;
+                }
+            }
+        }
+        else
+        {
+            if ( pdebug>=2 )
+            { "// 21 found root to be: "+string(lsr[1]); }
+            resl[nv-d]= lsr[1];
+
+            if ( dd < elem )
+            {
+                LL= psubst( d+1, dd+1, n-1, resl, fi, elem, nv, prec,
+                            rn@, rlist );
+                rlist = LL[1];
+                rn@ = LL[2];
+            }
+            else
+            {
+                if ( pdebug>=1 )
+                { "// 30_2 <"+string(rn@)+"> "+string(size(resl))+" <-----";}
+                if ( pdebug>=2 )
+                { resl; }
+                rlist[rn@]=resl;
+            }
+        }
+    }
+    return(list(rlist,rn@));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc fglm_solve( ideal fi, list # )
+"USAGE:   fglm_solve(i [, p] ); i ideal, p integer
+ASSUME:  the ground field has char 0.
+RETURN:  ring @code{R} with the same number of variables but with complex
+         coefficients (and precision p). @code{R} comes with a list
+         @code{rlist} of numbers, in which the complex roots of i are stored.@*
+         p>0: gives precision of complex numbers in decimal digits [default:
+         p=30].
+NOTE:    The procedure uses a standard basis of i to determine all complex
+         roots of i.
+EXAMPLE: example fglm_solve; shows an example
+"
+{
+    int prec=30;
+
+    if ( size(#)>=1  && typeof(#[1])=="int")
+    {
+        prec=#[1];
+    }
+
+    def R = lex_solve(stdfglm(fi),prec);
+    dbprint( printlevel-voice+3,"
+// 'fglm_solve' created a ring, in which a list rlist of numbers (the
+// complex solutions) is stored.
+// To access the list of complex solutions, type (if the name R was assigned
+// to the return value):
+        setring R; rlist; ");
+    return(R);
+}
+example
+{
+    "EXAMPLE:";echo=2;
+    ring r = 0,(x,y),lp;
+    // compute the intersection points of two curves
+    ideal s =  x2 + y2 - 10, x2 + xy + 2y2 - 16;
+    def R = fglm_solve(s,10);
+    setring R; rlist;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc lex_solve( ideal fi, list # )
+"USAGE:   lex_solve( i[,p] ); i=ideal, p=integer,
+  p>0: gives precision of complex numbers in decimal digits (default: p=30).
+ASSUME:  i is a reduced lexicographical Groebner bases of a zero-dimensional
+         ideal, sorted by increasing leading terms.
+RETURN:  ring @code{R} with the same number of variables but with complex
+         coefficients (and precision p). @code{R} comes with a list
+         @code{rlist} of numbers, in which the complex roots of i are stored.
+EXAMPLE: example lex_solve; shows an example
+"
+{
+    int prec=30;
+    list LL;
+
+    if ( size(#)>=1  && typeof(#[1])=="int")
+    {
+        prec=#[1];
+    }
+
+    if ( !defined(pdebug) ) { int pdebug; }
+    def oring= basering;
+
+    // change the ground field to complex numbers
+    string nrings= "ring RC =(complex,"+string(prec)
+        +"),("+varstr(basering)+"),lp;";
+    execute(nrings);
+
+    // map fi from old to new ring
+    ideal fi= imap(oring,fi);
+
+    int idelem= size(fi);
+    int nv= nvars(basering);
+    int i,j,k,lis;
+    list resl,li;
+
+    if ( !defined(rlist) )
+    {
+        list rlist;
+        export rlist;
+    }
+
+    li= laguerre_solve(fi[1],prec,prec,0);
+    lis= size(li);
+
+    dbprint(printlevel-voice+2,"// laguerre found roots: "+string(size(li)));
+    int rn@;
+
+    for ( j= 1; j <= lis; j++ )
+    {
+        dbprint(printlevel-voice+1,"// root "+string(j) );
+        rn at ++;
+        resl[nv]= li[j];
+        LL = psubst( 1, 2, nv-1, resl, fi, idelem, nv, prec, rn@, rlist );
+        rlist=LL[1];
+        rn@=LL[2];
+    }
+
+    dbprint( printlevel-voice+3,"
+// 'lex_solve' created a ring, in which a list rlist of numbers (the
+// complex solutions) is stored.
+// To access the list of complex solutions, type (if the name R was assigned
+// to the return value):
+        setring R; rlist; ");
+
+    return(RC);
+}
+example
+{
+    "EXAMPLE:";echo=2;
+    ring r = 0,(x,y),lp;
+    // compute the intersection points of two curves
+    ideal s =  x2 + y2 - 10, x2 + xy + 2y2 - 16;
+    def R = lex_solve(stdfglm(s),10);
+    setring R; rlist;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc triangLf_solve( ideal fi, list # )
+"USAGE:   triangLf_solve(i [, p] ); i ideal, p integer,
+         p>0: gives precision of complex numbers in digits (default: p=30).
+ASSUME:  the ground field has char 0;  i is a zero-dimensional ideal
+RETURN:  ring @code{R} with the same number of variables but with complex
+         coefficients (and precision p). @code{R} comes with a list
+         @code{rlist} of numbers, in which the complex roots of i are stored.
+NOTE:    The procedure uses a triangular system (Lazard's Algorithm with
+         factorization) computed from a standard basis to determine
+         recursively all complex roots of the input ideal i with Laguerre's
+         algorithm.
+EXAMPLE: example triangLf_solve; shows an example
+"
+{
+    int prec=30;
+
+    if ( size(#)>=1  && typeof(#[1])=="int")
+    {
+        prec=#[1];
+    }
+
+    def R=triang_solve(triangLfak(stdfglm(fi)),prec);
+    dbprint( printlevel-voice+3,"
+// 'triangLf_solve' created a ring, in which a list rlist of numbers (the
+// complex solutions) is stored.
+// To access the list of complex solutions, type (if the name R was assigned
+// to the return value):
+        setring R; rlist; ");
+    return(R);
+}
+example
+{
+    "EXAMPLE:";echo=2;
+    ring r = 0,(x,y),lp;
+    // compute the intersection points of two curves
+    ideal s = x2 + y2 - 10, x2 + xy + 2y2 - 16;
+    def R = triangLf_solve(s,10);
+    setring R; rlist;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc triangM_solve( ideal fi, list # )
+"USAGE:   triangM_solve(i [, p ] ); i=ideal, p=integer,
+         p>0: gives precision of complex numbers in digits (default: p=30).
+ASSUME:  the ground field has char 0;@*
+         i zero-dimensional ideal
+RETURN:  ring @code{R} with the same number of variables but with complex
+         coefficients (and precision p). @code{R} comes with a list
+         @code{rlist} of numbers, in which the complex roots of i are stored.
+NOTE:    The procedure uses a triangular system (Moellers Algorithm) computed
+         from a standard basis  of input ideal i to determine recursively all
+         complex roots with Laguerre's algorithm.
+EXAMPLE: example triangM_solve; shows an example
+"
+{
+    int prec=30;
+
+    if ( size(#)>=1  && typeof(#[1])=="int")
+    {
+        prec=#[1];
+    }
+
+    def R = triang_solve(triangM(stdfglm(fi)),prec);
+    dbprint( printlevel-voice+3,"
+// 'triangM_solve' created a ring, in which a list rlist of numbers (the
+// complex solutions) is stored.
+// To access the list of complex solutions, type (if the name R was assigned
+// to the return value):
+        setring R; rlist; ");
+    return(R);
+}
+example
+{
+    "EXAMPLE:";echo=2;
+    ring r = 0,(x,y),lp;
+    // compute the intersection points of two curves
+    ideal s =  x2 + y2 - 10, x2 + xy + 2y2 - 16;
+    def R = triangM_solve(s,10);
+    setring R; rlist;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc triangL_solve( ideal fi, list # )
+"USAGE:   triangL_solve(i [, p] ); i=ideal, p=integer,@*
+         p>0: gives precision of complex numbers in digits (default: p=30).
+ASSUME:  the ground field has char 0; i is a zero-dimensional ideal.
+RETURN:  ring @code{R} with the same number of variables, but with complex
+         coefficients (and precision p). @code{R} comes with a list
+         @code{rlist} of numbers, in which the complex roots of i are stored.
+NOTE:    The procedure uses a triangular system (Lazard's Algorithm) computed
+         from a standard basis of input ideal i to determine recursively all
+         complex roots with Laguerre's algorithm.
+EXAMPLE: example triangL_solve; shows an example
+"
+{
+    int prec=30;
+
+    if ( size(#)>=1  && typeof(#[1])=="int")
+    {
+        prec=#[1];
+    }
+
+    def R=triang_solve(triangL(stdfglm(fi)),prec);
+    dbprint( printlevel-voice+3,"
+// 'triangL_solve' created a ring, in which a list rlist of numbers (the
+// complex solutions) is stored.
+// To access the list of complex solutions, type (if the name R was assigned
+// to the return value):
+        setring R; rlist; ");
+    return(R);
+}
+example
+{
+    "EXAMPLE:";echo=2;
+    ring r = 0,(x,y),lp;
+    // compute the intersection points of two curves
+    ideal s =  x2 + y2 - 10, x2 + xy + 2y2 - 16;
+    def R = triangL_solve(s,10);
+    setring R; rlist;
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc triang_solve( list lfi, int prec, list # )
+"USAGE:   triang_solve(l,p [,d] ); l=list, p,d=integers@*
+         l is a list of finitely many triangular systems, such that the union of
+         their varieties equals the variety of the initial ideal.@*
+         p>0: gives precision of complex numbers in digits,@*
+         d>0: gives precision (1<d<p) for near-zero-determination,@*
+         (default: d=1/2*p).
+ASSUME:  the ground field has char 0;@*
+         l was computed using the algorithm of Lazard or the algorithm of
+         Moeller (see triang.lib).
+RETURN:  ring @code{R} with the same number of variables, but with complex
+         coefficients (and precision p). @code{R} comes with a list
+         @code{rlist} of numbers, in which the complex roots of l are stored.@*
+EXAMPLE: example triang_solve; shows an example
+"
+{
+    def oring= basering;
+    list LL;
+
+    // change the ground field to complex numbers
+    string nrings= "ring RC =(complex,"+string(prec)
+        +",I),("+varstr(basering)+"),lp;";
+    execute(nrings);
+
+    // list with entry 0 (number)
+    number nn=0;
+
+    // set number of digits for zero-comparison of roots
+    if ( !defined(myCompDigits) )
+    {
+        int myCompDigits;
+    }
+    if ( size(#)>=1  && typeof(#[1])=="int" )
+    {
+        myCompDigits=#[1];
+    }
+    else
+    {
+        myCompDigits=(system("getPrecDigits"));
+    }
+
+    dbprint( printlevel-voice+2,"// myCompDigits="+string(myCompDigits) );
+
+    int idelem;
+    int nv= nvars(basering);
+    int i,j,lis;
+    list resu,li;
+
+    if ( !defined(rlist) )
+    {
+        list rlist;
+        export rlist;
+    }
+
+    int rn@=0;
+
+    // map the list
+    list lfi= imap(oring,lfi);
+    int slfi= size(lfi);
+
+    ideal fi;
+    for ( i= 1; i <= slfi; i++ )
+    {
+        // map fi from old to new ring
+        fi= lfi[i]; //imap(oring,lfi[i]);
+
+        idelem= size(fi);
+
+        // solve fi[1]
+        li= laguerre_solve(fi[1],myCompDigits,myCompDigits,0);
+        lis= size(li);
+
+        dbprint( printlevel-voice+2,"// laguerre found roots: "+string(lis) );
+
+        for ( j= 1; j <= lis; j++ )
+        {
+            dbprint( printlevel-voice+2,"// root "+string(j) );
+            rn at ++;
+            resu[nv]= li[j];
+            LL = psubst( 1, 2, nv-1, resu, fi, idelem, nv, myCompDigits,
+                         rn@, rlist );
+            rlist = LL[1];
+            rn@ = LL[2];
+        }
+    }
+
+    dbprint( printlevel-voice+3,"
+// 'triang_solve' created a ring, in which a list rlist of numbers (the
+// complex solutions) is stored.
+// To access the list of complex solutions, type (if the name R was assigned
+// to the return value):
+        setring R; rlist; ");
+
+    return(RC);
+}
+example
+{
+    "EXAMPLE:";echo=2;
+    ring r = 0,(x,y),lp;
+    // compute the intersection points of two curves
+    ideal s=  x2 + y2 - 10, x2 + xy + 2y2 - 16;
+    def R=triang_solve(triangLfak(stdfglm(s)),10);
+    setring R; rlist;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc simplexOut(list l)
+"USAGE:   simplexOut(l); l list
+ASSUME:  l is the output of simplex.
+RETURN:  Nothing. The procedure prints the computed solution of simplex
+         (as strings) in a nice format.
+SEE ALSO: simplex
+EXAMPLE: example simplexOut; shows an example
+"
+{
+  int i,j;
+  matrix m= l[1];
+  intvec iposv= l[3];
+  int icase= l[2];
+
+  int cols= ncols(m);
+  int rows= nrows(m);
+
+  int N= l[6];
+
+  if ( 1 == icase )  // objective function is unbound
+  {
+    "objective function is unbound";
+    return();
+  }
+  if ( -1 == icase )  // no solution satisfies the given constraints
+  {
+    "no solution satisfies the given constraints";
+    return();
+  }
+  if ( -2 == icase )  // other error
+  {
+    "an error occurred during simplex computation!";
+    return();
+  }
+
+  for ( i = 1; i <= rows; i++ )
+  {
+    if (i == 1)
+    {
+      "z = "+string(m[1][1]);
+    }
+    else
+    {
+      if ( iposv[i-1] <= N )
+      {
+        "x"+string(iposv[i-1])+" = "+string(m[i,1]);
+      }
+//        else
+//        {
+//               "Y"; iposv[i-1]-N+1;
+//        }
+    }
+  }
+}
+example
+{
+  "EXAMPLE:";echo=2;
+  ring r = (real,10),(x),lp;
+
+  // consider the max. problem:
+  //
+  //    maximize  x(1) + x(2) + 3*x(3) - 0.5*x(4)
+  //
+  //  with constraints:   x(1) +          2*x(3)          <= 740
+  //                             2*x(2)          - 7*x(4) <=   0
+  //                               x(2) -   x(3) + 2*x(4) >=   0.5
+  //                      x(1) +   x(2) +   x(3) +   x(4)  =   9
+  //
+  matrix sm[5][5]=   0, 1, 1, 3,-0.5,
+                   740,-1, 0,-2, 0,
+                     0, 0,-2, 0, 7,
+                   0.5, 0,-1, 1,-2,
+                     9,-1,-1,-1,-1;
+
+  int n = 4;  // number of constraints
+  int m = 4;  // number of variables
+  int m1= 2;  // number of <= constraints
+  int m2= 1;  // number of >= constraints
+  int m3= 1;  // number of == constraints
+
+  list sol=simplex(sm, n, m, m1, m2, m3);
+  simplexOut(sol);
+}
+
+
+// local Variables: ***
+// c-set-style: bsd ***
+// End: ***
diff --git a/Singular/LIB/spcurve.lib b/Singular/LIB/spcurve.lib
new file mode 100644
index 0000000..30087cc
--- /dev/null
+++ b/Singular/LIB/spcurve.lib
@@ -0,0 +1,1065 @@
+//////////////////////////////////////////////////////////////////////////
+version="version spcurve.lib 4.0.0.0 Jun_2013 "; // $Id: c59b3ead180716d2b229ac5332b70c0a55115262 $
+category="Singularities";
+info="
+LIBRARY: spcurve.lib    Deformations and Invariants of CM-codim 2 Singularities
+AUTHOR:  Anne Fruehbis-Krueger, anne at mathematik.uni-kl.de
+
+PROCEDURES:
+ isCMcod2(i);            presentation matrix of the ideal i, if i is CM
+ CMtype(i);              Cohen-Macaulay type of the ideal i
+ matrixT1(M,n);          1st order deformation T1 in matrix description
+ semiCMcod2(M,T1);       semiuniversal deformation of maximal minors of M
+ discr(sem,n);           discriminant of semiuniversal deformation
+ qhmatrix(M);            weights if M is quasihomogeneous
+ relweight(N,W,a);       relative matrix weight of N w.r.t. weights (W,a)
+ posweight(M,T1,i);      deformation of coker(M) of non-negative weight
+ KSpencerKernel(M);      kernel of the Kodaira-Spencer map
+";
+
+LIB "elim.lib";
+LIB "homolog.lib";
+LIB "inout.lib";
+LIB "poly.lib";
+/////////////////////////////////////////////////////////////////////////////
+
+proc isCMcod2(ideal kurve)
+"USAGE:   isCMcod2(i);   i an ideal
+RETURN:  presentation matrix of i, if i is Cohen-Macaulay of codimension 2 @*
+         a zero matrix otherwise
+EXAMPLE: example isCMcod2; shows an example"
+{
+  int p = printlevel-voice+3;  // p=printlevel+1 (default: p=1)
+//---------------------------------------------------------------------------
+// Compute a minimal free resolution of the ideal and check if the
+// resolution has the expected structure
+//---------------------------------------------------------------------------
+  list kurveres=mres(kurve,0);
+  matrix M=kurveres[2];
+  if ((size(kurveres)>3) &&
+         ((size(kurveres[3])>1) ||
+          ((size(kurveres[3])<=1) && (kurveres[3][1,1]!=0))))
+  {
+    dbprint(p,"//not Cohen-Macaulay, codim 2");
+    matrix ret=0;
+    return(ret);
+  }
+  return(M);
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring r=32003,(x,y,z),ds;
+  ideal i=xz,yz,x^3-y^4;
+  print(isCMcod2(i));
+}
+/////////////////////////////////////////////////////////////////////////////
+
+proc CMtype(ideal kurve)
+"USAGE:   CMtype(i);  i an ideal, CM of codimension 2
+RETURN:  Cohen-Macaulay type of i (integer)
+         (-1, if i is not Cohen-Macaulay of codimension 2)
+EXAMPLE: example CMtype; shows an example"
+{
+  int p = printlevel-voice+3;  // p=printlevel+1 (default: p=1)
+  int gt = -1;
+//---------------------------------------------------------------------------
+// Compute a minimal free resolution of the ideal and check if the
+// resolution has the expected structure
+//---------------------------------------------------------------------------
+  list kurveres;
+  kurveres=mres(kurve,0);
+  if ((size(kurveres)>3) &&
+         ((size(kurveres[3])>1) ||
+          ((size(kurveres[3])<=1) && (kurveres[3][1,1]!=0))))
+  {
+    dbprint(p,"//not Cohen-Macaulay, codim 2");
+    return(gt);
+  }
+//---------------------------------------------------------------------------
+// Return the Cohen-Macaulay type of i
+//---------------------------------------------------------------------------
+  matrix M = matrix(kurveres[2]);
+  gt = ncols(M);
+  return(gt);
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring r=32003,(x,y,z),ds;
+  ideal i=xy,xz,yz;
+  CMtype(i);
+}
+/////////////////////////////////////////////////////////////////////////////
+
+proc matrixT1(matrix M ,int n)
+"USAGE:   matrixT1(M,n);  M matrix, n integer
+ASSUME:  M is a presentation matrix of an ideal i, CM of codimension 2;
+         consider i as a family of ideals in a ring in the first n
+         variables where the remaining variables are considered as
+         parameters
+RETURN:  list consisting of the k x (k+1) matrix M and a module K_M such that
+         T1=Mat(k,k+1;R)/K_M is the space of first order deformations of i
+EXAMPLE: example matrixT1; shows an example"
+{
+  int p = printlevel-voice+3;  // p=printlevel+1 (default: p=1)
+//--------------------------------------------------------------------------
+// Initialization and sanity checks
+//--------------------------------------------------------------------------
+  int nr=nrows(M);
+  int nc=ncols(M);
+  if ( nr < nc )
+  {
+    M=transpose(M);
+    int temp=nc;
+    nc=nr;
+    nr=temp;
+    int tra=1;
+  }
+  if ( nr != (nc+1) )
+  {
+    ERROR("not a k x (k+1) matrix");
+  }
+//---------------------------------------------------------------------------
+// Construct the denominator - step by step
+// step 1: initialization
+//---------------------------------------------------------------------------
+  int gt=nc;
+  int i,j;
+  ideal m = M;
+  ideal dx;
+  ideal rv;
+  ideal lv;
+  matrix R[gt][gt]=0;
+  matrix L[gt+1][gt+1]=0;
+  matrix T1[n+gt*gt+(gt+1)*(gt+1)][gt*(gt+1)] = 0;
+//---------------------------------------------------------------------------
+// step 2: the derivatives of the matrix are generators of the denominator
+//---------------------------------------------------------------------------
+  for( i=1; i<= n; i++ )
+  {
+    dx=diff(m,var(i));
+    T1[i,1..gt*(gt+1)] = dx;
+  }
+//---------------------------------------------------------------------------
+// step 3: M*R is a generator as well
+//---------------------------------------------------------------------------
+  for( i=1; i <= gt; i++ )
+  {
+    for ( j=1 ; j <= gt ; j++ )
+    {
+      R[i,j]=1;
+      rv = M * R;
+      T1[n+(i-1)*gt+j,1..gt*(gt+1)] = rv;
+      R[i,j]=0;
+    }
+  }
+//---------------------------------------------------------------------------
+// step 4: so is L*M
+//---------------------------------------------------------------------------
+  for( i=1; i <= (gt+1); i++)
+  {
+    for( j=1 ; j <= (gt+1);j++ )
+    {
+      L[i,j]=1;
+      lv = L * M;
+      T1[n+gt*gt+(i-1)*(gt+1)+j,1..gt*(gt+1)] = lv;
+      L[i,j]=0;
+    }
+  }
+//---------------------------------------------------------------------------
+// Compute the vectorspace basis of T1
+//---------------------------------------------------------------------------
+  module t1 = module(transpose(T1));
+  list result=M,t1;
+  return(result);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring r=32003,(x(1),x(2),x(3)),ds;
+  ideal curve=x(1)*x(2),x(1)*x(3),x(2)*x(3);
+  matrix M=isCMcod2(curve);
+  matrixT1(M,3);
+}
+/////////////////////////////////////////////////////////////////////////////
+
+proc semiCMcod2(matrix M, module t1,list #)
+"USAGE:   semiCMcod2(M,t1[,s]); M matrix, t1 module, s any
+ASSUME:  M is a presentation matrix of an ideal i, CM of codimension 2,
+         and t1 is a presentation of the space of first order deformations
+         of i ((M,t1) as returned by the procedure matrixT1)
+RETURN:  new ring in which the ideal semi describing the semiuniversal
+         deformation of i;
+         if the optional third argument is given, the perturbation matrix
+         of the semiuniversal deformation is returned instead of the ideal.
+NOTE:    The current basering should not contain any variables named
+         A(j) where j is some integer!
+EXAMPLE: example semiCMcod2; shows an example"
+{
+  int p = printlevel-voice+3;  // p=printlevel+1 (default: p=1)
+//---------------------------------------------------------------------------
+// Initialization
+//---------------------------------------------------------------------------
+  module t1erz=kbase(std(t1));
+  int tau=vdim(t1);
+  int gt=ncols(M);
+  int i;
+  def r=basering;
+  if(size(M)!=gt*(gt+1))
+  {
+    gt=gt-1;
+  }
+  for(i=1; i<=size(t1erz); i++)
+  {
+    if(rvar(A(i)))
+    {
+      int jj=-1;
+      break;
+    }
+  }
+  if (defined(jj)>1)
+  {
+    if (jj==-1)
+    {
+      ERROR("Your ring contains a variable T(i)!");
+    }
+  }
+//---------------------------------------------------------------------------
+// Definition of the new ring and the image of M and t1 in the new ring
+//---------------------------------------------------------------------------
+  ring rtemp=0,(A(1..tau)),dp;
+  def rneu=r+rtemp;
+  setring rneu;
+  matrix M=imap(r,M);
+  ideal m=M;
+  module t1erz=imap(r,t1erz);
+//---------------------------------------------------------------------------
+// Construction of the presentation matrix of the versal deformation
+//---------------------------------------------------------------------------
+  matrix N=matrix(m);
+  matrix Mtemp[gt*(gt+1)][1];
+  for( i=1; i<=tau; i++)
+  {
+    Mtemp=t1erz[i];
+    N=N+A(i)*transpose(Mtemp);
+  }
+  ideal n=N;
+  matrix O[gt+1][gt]=n;
+//---------------------------------------------------------------------------
+// Construction of the return value
+//---------------------------------------------------------------------------
+  if(size(#)>0)
+  {
+    matrix semi=O;
+  }
+  else
+  {
+    ideal semi=minor(O,gt);
+  }
+  export semi;
+  return(rneu);
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring r=32003,(x(1),x(2),x(3)),ds;
+  ideal curve=x(1)*x(2),x(1)*x(3),x(2)*x(3);
+  matrix M=isCMcod2(curve);
+  list l=matrixT1(M,3);
+  def rneu=semiCMcod2(l[1],std(l[2]));
+  setring rneu;
+  semi;
+}
+/////////////////////////////////////////////////////////////////////////////
+
+proc discr(ideal kurve, int n)
+"USAGE:   discr(sem,n);  sem ideal, n integer
+ASSUME:  sem is the versal deformation of an ideal of codimension 2. @*
+         The first n variables of the ring are treated as variables
+         all the others as parameters.
+RETURN:  ideal describing the discriminant
+NOTE:    This is not a powerful algorithm!
+EXAMPLE: example discr; shows an example"
+{
+  int p = printlevel-voice+3;  // p=printlevel+1 (default: p=1)
+//---------------------------------------------------------------------------
+// some sanity checks and initialization
+//---------------------------------------------------------------------------
+  int i;
+  ideal sem=std(kurve);
+  ideal semdiff;
+  ideal J2;
+  int ncol=ncols(matrix(sem));
+  matrix Jacob[n][ncol];
+//---------------------------------------------------------------------------
+// compute the Jacobian matrix
+//---------------------------------------------------------------------------
+  for (i=1; i<=n; i++)
+  {
+    semdiff=diff(sem,var(i));
+    Jacob[i,1..ncol]=semdiff;
+  }
+//---------------------------------------------------------------------------
+// eliminate the first n variables in the ideal generated by
+// the versal deformation and the 2x2 minors of the Jacobian
+//---------------------------------------------------------------------------
+  semdiff=minor(Jacob,2);
+  J2=sem,semdiff;
+  J2=std(J2);
+  poly eli=1;
+  for(i=1; i<=n; i++)
+  {
+    eli=eli*var(i);
+  }
+  ideal dis=eliminate(J2,eli);
+  return(dis);
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring r=32003,(x(1),x(2),x(3)),ds;
+  ideal curve=x(1)*x(2),x(1)*x(3),x(2)*x(3);
+  matrix M=isCMcod2(curve);
+  list l=matrixT1(M,3);
+  def rneu=semiCMcod2(l[1],std(l[2]));
+  setring rneu;
+  discr(semi,3);
+}
+/////////////////////////////////////////////////////////////////////////////
+
+proc qhmatrix(matrix M)
+"USAGE:   qhmatrix(M);   M a k x (k+1) matrix
+RETURN:  list, consisting of an integer vector containing the weights of
+         the variables of the basering and an integer matrix giving the
+         weights of the entries of M, if M is quasihomogeneous;
+         zero integer vector and zero integer matrix, if M is not
+         quasihomogeneous, i.e. does not allow row and column weights
+EXAMPLE: example qhmatrix; shows an example"
+{
+  int p = printlevel-voice+3;  // p=printlevel+1 (default: p=1)
+//---------------------------------------------------------------------------
+// Initialization and sanity checks
+//---------------------------------------------------------------------------
+  def r=basering;
+  int i,j,temp;
+  int tra=0;
+  int nr=nrows(M);
+  int nc=ncols(M);
+  if ( nr > nc )
+  {
+    M=transpose(M);
+    temp=nc;
+    nc=nr;
+    nr=temp;
+    tra=1;
+  }
+  if ( nc != (nr+1) )
+  {
+    ERROR("not a k x (k+1) matrix");
+  }
+  ideal m=minor(M,nr);
+//---------------------------------------------------------------------------
+// get the weight using the fact that the matrix is quasihomogeneous, if
+// its maximal minors are, and check, whether M is really quasihomogeneous
+//---------------------------------------------------------------------------
+  intvec a=weight(m);
+  string tempstr="ring rneu=" + charstr(r) + ",(" + varstr(r) + "),Ws(" + string(a) + ");";
+  execute(tempstr);
+  def M=imap(r,M);
+  int difset=0;
+  list l;
+  int dif;
+  int donttest=0;
+  int comprow=0;
+  intmat W[nr][nc];
+//---------------------------------------------------------------------------
+// find a row not containing a 0
+//---------------------------------------------------------------------------
+  for(i=1; i<=nr; i++)
+  {
+    if(comprow==0)
+    {
+      comprow=i;
+      for(j=1; j<=nc; j++)
+      {
+        if(M[i,j]==0)
+        {
+          comprow=0;
+          break;
+        }
+      }
+    }
+  }
+//---------------------------------------------------------------------------
+// get the weights of the comprow'th row or use emergency exit
+//---------------------------------------------------------------------------
+  if(comprow==0)
+  {
+    intvec v=0;
+    intmat V=0
+    list ret=v,V;
+    return(ret);
+  }
+  else
+  {
+    for(j=1; j<=nc; j++)
+    {
+      l[j]=deg(lead(M[comprow,j]));
+    }
+  }
+//---------------------------------------------------------------------------
+// do the checks
+//---------------------------------------------------------------------------
+  for(i=1; i<=nr; i++)
+  {
+    if ( i==comprow )
+    {
+// this row should not be tested against itself
+      donttest=1;
+    }
+    else
+    {
+// initialize the difference of the rows, but ignore 0-entries
+      if (M[i,1]!=0)
+      {
+        dif=deg(lead(M[i,1]))-l[1];
+        difset=1;
+      }
+      else
+      {
+        list memo;
+        memo[1]=1;
+      }
+    }
+// check column by column
+    for(j=1; j<=nc; j++)
+    {
+      if(M[i,j]==0)
+      {
+        if(defined(memo)!=0)
+        {
+          memo[size(memo)+1]=j;
+        }
+        else
+        {
+          list memo;
+          memo[1]=j;
+        }
+      }
+      temp=deg(lead(M[i,j]));
+      if((difset!=1) && (donttest!=1) && (M[i,j]!=0))
+      {
+// initialize the difference of the rows, if necessary - still ignore 0s
+        dif=deg(lead(M[i,j]))-l[j];
+        difset=1;
+      }
+// is M[i,j] quasihomogeneous - else emergency exit
+      if(M[i,j]!=jet(M[i,j],temp,a)-jet(M[i,j],temp-1,a))
+      {
+        intvec v=0;
+        intmat V=0;
+        list ret=v,V;
+        return(ret);
+      }
+      if(donttest!=1)
+      {
+// check row and column weights - else emergency exit
+        if(((temp-l[j])!=dif) && (M[i,j]!=0) && (difset==1))
+        {
+          intvec v=0;
+          intmat V=0;
+          list ret=v,V;
+          return(ret);
+        }
+      }
+// set the weight matrix entry
+      W[i,j]=temp;
+    }
+// clean up the 0's we left out
+    if((difset==1) && (defined(memo)!=0))
+    {
+      for(j=1; j<=size(memo); j++)
+      {
+        W[i,memo[j]]=dif+l[memo[j]];
+      }
+      kill memo;
+    }
+    donttest=0;
+  }
+//---------------------------------------------------------------------------
+// transpose, if M was transposed during initialization, and return the list
+//---------------------------------------------------------------------------
+  if ( tra==1 )
+  {
+    W=transpose(W);
+  }
+  setring r;
+  list ret=a,W;
+  return(ret);
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring r=0,(x,y,z),ds;
+  matrix M[3][2]=z,0,y,x,x^3,y;
+  qhmatrix(M);
+  pmat(M);
+}
+/////////////////////////////////////////////////////////////////////////////
+
+proc relweight(matrix N, intmat W, intvec a)
+"USAGE:   relweight(N,W,a); N matrix, W intmat, a intvec
+ASSUME:  N is a non-zero matrix
+         W is an integer matrix of the same size as N
+         a is an integer vector giving the weights of the variables
+RETURN:  integer, max(a-weighted order(N_ij) - W_ij | all entries ij) @*
+         string \"ERROR\" if sizes do not match
+EXAMPLE: example relweight; shows an example
+"
+{
+  int p = printlevel-voice+3;  // p=printlevel+1 (default: p=1)
+//---------------------------------------------------------------------------
+// Initialization and sanity checks
+//---------------------------------------------------------------------------
+  if ((size(N)!=size(W)) || (ncols(N)!=ncols(W)))
+  {
+    ERROR("matrix size does not match");
+  }
+  if (size(a)!=nvars(basering))
+  {
+    ERROR("length of weight vector != number of variables");
+  }
+  int i,j,temp;
+  def r=basering;
+//---------------------------------------------------------------------------
+// Comparision entry by entry
+//---------------------------------------------------------------------------
+  for(i=1; i<=nrows(N); i++)
+  {
+    for(j=1; j<=ncols(N); j++)
+    {
+      if (N[i,j]!=0)
+      {
+        temp=mindeg1(N[i,j],a)-W[i,j];
+        if (defined(ret))
+        {
+          if(temp > ret)
+          {
+            ret=temp;
+          }
+        }
+        else
+        {
+          int ret=temp;
+        }
+      }
+    }
+  }
+  return(ret);
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring r=32003,(x,y,z),ds;
+  matrix N[2][3]=z,0,y,x,x^3,y;
+  intmat W[2][3]=1,1,1,1,1,1;
+  intvec a=1,1,1;
+  relweight(N,W,a);
+}
+/////////////////////////////////////////////////////////////////////////////
+
+proc posweight(matrix M, module t1, int choose, list #)
+"USAGE:   posweight(M,t1,n[,s]); M matrix, t1 module, n int, s string @*
+         n=0 : all deformations of non-negative weight @*
+         n=1 : only non-constant deformations of non-negative weight @*
+         n=2 : all deformations of positive weight @*
+ASSUME:  M is a presentation matrix of a Cohen-Macaulay codimension 2
+         ideal and t1 is its T1 space in matrix notation
+RETURN:  new ring containing a list posw, consisting of a presentation
+         matrix describing the deformation given by the generators of T1
+         of non-negative/positive weight and the weight vector for the new
+         variables
+NOTE:   The current basering should not contain any variables named
+         T(i) where i is some integer!
+EXAMPLE: example posweight; shows an example"
+{
+//---------------------------------------------------------------------------
+// Initialization and sanity checks
+//---------------------------------------------------------------------------
+  if (size(#)>0)
+  {
+    if (typeof(#[1])=="string")
+    {
+      string newname=#[1];
+    }
+  }
+  if (attrib(t1,"isSB"))
+  {
+    module t1erz=kbase(t1);
+    int tau=vdim(t1);
+  }
+  else
+  { module t1erz=kbase(std(t1));
+    int tau=vdim(std(t1));
+  }
+  for(int i=1; i<=size(t1erz); i++)
+  {
+    if(rvar(T(i)))
+    {
+      int jj=-1;
+      break;
+    }
+  }
+  kill i;
+  if (defined(jj))
+  {
+    if (jj==-1)
+    {
+      ERROR("Your ring contains a variable T(i)!");
+    }
+  }
+  int pw=0;
+  int i;
+  def r=basering;
+  list l=qhmatrix(M);
+  int gt=ncols(M);
+  if(size(M)!=gt*(gt+1))
+  {
+    gt=gt-1;
+  }
+  matrix erzmat[gt+1][gt];
+  list erz;
+  if ((size(l[1])==1) && (l[1][1]==0) && (size(l[2])==1) && (l[2][1,1]==0))
+  {
+    ERROR("Internal Error: Problem determining the weights.");
+  }
+//---------------------------------------------------------------------------
+// Find the generators of T1 of non-negative weight
+//---------------------------------------------------------------------------
+  int relw;
+  list rlw;
+  for(i=1; i<=tau; i++)
+  {
+    erzmat=t1erz[i];
+    kill relw;
+    def relw=relweight(erzmat,l[2],l[1]);
+    if(typeof(relw)=="int")
+    {
+      if (((choose==0) && (relw>=0))
+           || ((choose==1) && (relw>=0) && (CMtype(minor(M+erzmat,gt))==gt))
+           || ((choose==2) && (relw > 0)))
+      {
+        pw++;
+        rlw[pw]=relw;
+        erz[pw]=erzmat;
+      }
+    }
+    else
+    {
+      ERROR("Internal Error: Problem determining relative weight.");
+    }
+  }
+//---------------------------------------------------------------------------
+// Definition of the new ring and the image of M and erz in the new ring
+//---------------------------------------------------------------------------
+  if(size(rlw)==0)
+  {
+    ERROR("Internal Error: Problem determining relative weight.");
+  }
+  intvec iv=rlw[1..size(rlw)];
+  ring rtemp=0,(T(1..pw)),dp;
+  def rneu=r+rtemp;
+  setring rneu;
+  matrix M=imap(r,M);
+  ideal m=M;
+// we cannot imap erz, if its size=0
+  if(pw==0)
+  {
+    list erz1;
+  }
+  else
+  {
+    list erz1=imap(r,erz);
+  }
+//---------------------------------------------------------------------------
+// Construction of the presentation matrix of the deformation
+//---------------------------------------------------------------------------
+  matrix N=matrix(m);
+  ideal mtemp;
+  matrix Mtemp[gt*(gt+1)][1];
+  for( i=1; i<=pw; i++)
+  {
+    mtemp=erz1[i];
+    Mtemp=mtemp;
+    N=N+T(i)*transpose(Mtemp);
+  }
+  ideal n=N;
+  matrix O[gt+1][gt]=n;
+//---------------------------------------------------------------------------
+// Keep the matrix and return the ring in which it lives
+//---------------------------------------------------------------------------
+  list posw=O,iv;
+  export posw;
+  return(rneu);
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring r=32003,(x(1),x(2),x(3)),ds;
+  ideal curve=(x(3)-x(1)^2)*x(3),(x(3)-x(1)^2)*x(2),x(2)^2-x(1)^7*x(3);
+  matrix M=isCMcod2(curve);
+  list l=matrixT1(M,3);
+  def rneu=posweight(l[1],std(l[2]),0);
+  setring rneu;
+  pmat(posw[1]);
+  posw[2];
+}
+/////////////////////////////////////////////////////////////////////////////
+
+proc KSpencerKernel(matrix M,list #)
+"USAGE:     KSpencerKernel(M[,s][,v]);  M matrix, s string, v intvec @*
+           optional parameters (please specify in this order, if both are
+           present):
+           *  s = first of the names of the new rings
+              e.g. \"R\" leads to ring names R and R1
+           *  v of size n(n+1) leads to the following module ordering @*
+              gen(v[1]) > gen(v[2]) > ... > gen(v[n(n+1)]) where the matrix
+              entry ij corresponds to gen((i-1)*n+j)
+ASSUME:    M is a quasihomogeneous n x (n+1) matrix where the n minors define
+           an isolated space curve singularity
+RETURN:    new ring containing the coefficient matrix KS representing
+           the kernel of the Kodaira-Spencer map of the family of
+           non-negative deformations having the given singularity as
+           special fibre
+NOTE:      * the initial basering should not contain variables with name
+             e(i) or T(i), since those variable names will internally be
+             used by the script
+           * setting an intvec with 5 entries and name watchProgress
+             shows the progress of the computations: @*
+             watchProgress[1]>0  => option(prot) in groebner commands @*
+             watchProgress[2]>0  => trace output for highcorner @*
+             watchProgress[3]>0  => output of deformed matrix @*
+             watchProgress[4]>0  => result of elimination step @*
+             watchProgress[4]>1  => trace output of multiplications with xyz
+                                    and subsequent reductions @*
+             watchProgress[5]>0  => matrix representing the kernel using print
+EXAMPLE:   example KSpencerKernel; shows an example"
+{
+  int p = printlevel-voice+3;  // p=printlevel+1 (default: p=1)
+//---------------------------------------------------------------------------
+// Initialization and sanity checks
+//---------------------------------------------------------------------------
+  intvec optvec=option(get);
+  if (size(#)>0)
+  {
+    if (typeof(#[1])=="string")
+    {
+      string newname=#[1];
+    }
+    if (typeof(#[1])=="intvec")
+    {
+      intvec desiredorder=#[1];
+    }
+    if (size(#)>1)
+    {
+      if (typeof(#[2])=="intvec")
+      {
+        intvec desiredorder=#[2];
+      }
+    }
+  }
+  if (defined(watchProgress))
+  {
+    if ((typeof(watchProgress)!="intvec") || (size(watchProgress)<5))
+    {
+      "watchProgress should be an intvec with at least 5 entries";
+      "ignoring watchProgress";
+      def kksave=watchProgress;
+      kill watchProgress;
+    }
+  }
+  option(redTail);
+  if (nvars(basering) != 3 )
+  {
+    ERROR("It should be a curve in 3 space");
+  }
+//---------------------------------------------------------------------------
+// change to a basering with the correct weihted order
+//---------------------------------------------------------------------------
+  def rt=basering;
+  list wl=qhmatrix(M);
+  if ((size(wl)!=2) || ((wl[1]==0) && (wl[2]==0)))
+  {
+    ERROR("The matrix was not n x (n+1) or not quasihomogenous");
+  }
+  string ringre=" ring r=" + charstr(rt) + ",(x,y,z), Ws(" + string(wl[1]) + ");";
+  execute(ringre);
+  matrix M=imap(rt,M);
+  int ne=size(M);
+  if (defined(desiredorder)>1)
+  {
+    intvec iv;
+    for(int i=1;i<=size(desiredorder);i++)
+    {
+      iv[desiredorder[i]]=i;
+    }
+  }
+  else
+  {
+    intvec iv=1..ne;
+  }
+  list l=matrixT1(M,3);
+  if (dim(std(l[2])) != 0)
+  {
+    ERROR("The matrix does not define an isolated space curve singularity");
+  }
+  module t1qh=l[2];
+//--------------------------------------------------------------------------
+// Passing to a new ring with extra variables e(i) corresponding to
+// the module generators gen(i) for weighted standard basis computation
+// accepting weights for the gen(i)
+//--------------------------------------------------------------------------
+  int jj=0;
+  for(int i=1; i<=ne; i++)
+  {
+    if(rvar(e(i)))
+    {
+      jj=-1;
+    }
+  }
+  if (jj==-1)
+  {
+    ERROR("Your ring contains a variable e(i)!");
+  }
+  if(defined(desiredorder)>1)
+  {
+    ringre="ring re=" + charstr(r) +",(e(1.." + string(ne) + "),"+
+                        varstr(basering) + "),Ws(";
+    intvec tempiv=intvec(wl[2]);
+    for(i=1;i<=ne;i++)
+    {
+      ringre=ringre + string((-1)*tempiv[desiredorder[i]]) + ",";
+    }
+    ringre= ringre  + string(wl[1]) + ");";
+  }
+  else
+  {
+    ringre="ring re=" + charstr(r) +",(e(1.." + string(ne) + "),"+ varstr(basering)
+                        + "),Ws(" + string((-1)*intvec(wl[2])) + ","
+                        + string(wl[1]) + ");";
+  }
+  execute(ringre);
+  module temp=imap(r,t1qh);
+  ideal t1qh=mod2id(temp,iv);
+  if (defined(watchProgress))
+  {
+    if (watchProgress[1]!=0)
+    {
+      option(prot);
+      "Protocol output of the groebner computation (quasihomogenous case)";
+    }
+  }
+  ideal t1qhs=std(t1qh);
+  if (defined(watchProgress))
+  {
+    if (watchProgress[1]!=0)
+    {
+      "groebner computation finished";
+      option(noprot);
+    }
+  }
+  ideal t1qhsl=lead(t1qhs);
+  module mo=id2mod(t1qhsl,iv);
+//--------------------------------------------------------------------------
+// Return to the initial ring to compute the kbase and noether there
+// (in the new ring t1qh is of course not of dimension 0 but of dimension 3
+// so we have to go back)
+//--------------------------------------------------------------------------
+  setring r;
+  module mo=imap(re,mo);
+  attrib(mo,"isSB",1);                // mo is monomial ==> SB
+  attrib(mo,"isHomog",intvec(wl[2])); // highcorner has to respect the weights
+  vector noe=highcorner(mo);
+  if (defined(watchProgress))
+  {
+    if (watchProgress[2]!=0)
+    {
+      "weights corresponding to the entries of the matrix:";
+      wl;
+      "leading term of the groebner basis (quasihomogeneous case)";
+      mo;
+      "noether";
+      noe;
+    }
+  }
+//--------------------------------------------------------------------------
+// Define the family of curves with the same quasihomogeneous initial
+// matrix M, compute T1 and pass again to the ring with the variables e(i)
+//--------------------------------------------------------------------------
+  def rneu=posweight(M,mo,2);
+  setring rneu;
+  list li=posw;
+  if (size(li)<=1)
+  {
+    ERROR("Internal Error: Problem determining perturbations of weight > 0.")
+  }
+  if (defined(watchProgress))
+  {
+    if(watchProgress[3]!=0)
+    {
+      "perturbed matrix and weights of the perturbations:";
+      li;
+    }
+  }
+  list li2=matrixT1(li[1],3);
+  module Mpert=transpose(matrix(ideal(li2[1])));
+  module t1pert=li2[2];
+  int nv=nvars(rneu)-nvars(r);
+  ring rtemp=0,(T(1..nv)),wp(li[2]);
+  def reneu=re+rtemp;
+  setring reneu;
+  module noe=matrix(imap(r,noe));
+  ideal noet=mod2id(noe,iv);
+  module temp=imap(rneu,t1pert);
+  ideal t1pert=mod2id(temp,iv);
+//--------------------------------------------------------------------------
+// Compute the standard basis and select those generators with leading term
+// divisible by some T(i)
+//--------------------------------------------------------------------------
+  noether=noet[size(noet)];
+  if (defined(watchProgress))
+  {
+    if (watchProgress[1]!=0)
+    {
+      "protocol output of the groebner command (perturbed case)";
+      option(prot);
+    }
+  }
+  ideal t1perts=std(t1pert);
+  noether=noet[size(noet)];
+  t1perts=interred(t1perts);
+  if (defined(Debug))
+  {
+    if (watchProgress[1]!=0)
+    {
+      "groebner computation finished (perturbed case)";
+      option(noprot);
+    }
+  }
+  ideal templ=lead(t1perts);
+  for(int j=1;j<=nv;j++)
+  {
+    templ=subst(templ,T(j),0);
+  }
+  ideal mx;
+  ideal mt;
+  for(j=1;j<=size(t1perts);j++)
+  {
+    if(templ[j]!=0)
+    {
+      mx=mx,t1perts[j];
+    }
+    else
+    {
+      mt=mt,t1perts[j];
+    }
+  }
+//--------------------------------------------------------------------------
+// multiply by the initial ring variables to shift the generators with
+// leading term divisible by some T(i) and reduce afterwards
+//--------------------------------------------------------------------------
+                       // This is obviously no SB, but we have to reduce by
+  attrib(mx,"isSB",1); // it and setting isSB suppresses error messages
+  noether=noet[size(noet)];
+  ideal ker_gen=reduce(mt,mx);
+  ideal ovar=var(ne+1),var(ne+2),var(ne+3);
+  j=1;
+  noether=noet[size(noet)];
+  if (defined(watchProgress))
+  {
+    if (watchProgress[4]!=0)
+    {
+      "generators of the kernel as a C[T]{x} module:";
+      mt;
+      "noether:";
+      noether;
+    }
+  }
+  int zeros;
+  templ=ker_gen;
+  while(zeros==0)
+  {
+    zeros=1;
+    templ=templ*ovar;
+    templ=reduce(templ,mx);
+    if(defined(watchProgress))
+    {
+      if(watchProgress[4]>1)
+      {
+        templ;
+      }
+    }
+    if (size(templ)!= 0)
+    {
+      zeros=0;
+      ker_gen=ker_gen,templ;
+    }
+  }
+//-------------------------------------------------------------------------
+// kill zero entries, keep only one of identical entries
+//-------------------------------------------------------------------------
+  ovar=var(1);
+  for(i=2;i<=ne;i++)
+  {
+    ovar=ovar,var(i);
+  }
+  ker_gen=ker_gen,ovar^2;
+  noether=noet[size(noet)];
+  ker_gen=simplify(ker_gen,10);
+//-------------------------------------------------------------------------
+// interreduce ker_gen as a k[T]-module
+//-------------------------------------------------------------------------
+  intvec mgen=1..(ne+3);
+  ideal Mpert=mod2id(imap(rneu,Mpert),iv);
+  templ=0;
+  for(i=1;i<=nv;i++)
+  {
+    templ[i]=diff(Mpert[size(Mpert)],T(i));
+  }
+  templ=templ,ovar^2;
+  list retl=subrInterred(templ,ker_gen,mgen);
+// Build up the matrix representing L
+  module retlm=transpose(retl[2]);
+  for(i=1;i<=size(retl[1]);i++)
+  {
+    if(reduce(retl[1][1,i],std(ovar^2))==0)
+    {
+      retlm[i]=0;
+    }
+  }
+  retlm=simplify(transpose(simplify(transpose(retlm),10)),10);
+  if(defined(watchProgress))
+  {
+    if(watchProgress[5]>0)
+    {
+      print(retlm);
+    }
+  }
+  ker_gen=retl[3];
+// we define ret=i(L),(delta_j(t_k))_jk
+  list ret=id2mod(ker_gen,iv),matrix(retlm);
+// cleanups - define what we previously killed
+  if(defined(kksave)>1)
+  {
+    def watchProgress=kksave;
+    export watch Progress;
+  }
+  option(set,optvec);
+  def KS=ret[2];
+  export KS;
+  return(reneu);
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring r=0,(x,y,z),ds;
+  matrix M[3][2]=z-x^7,0,y^2,z,x^9,y;
+  def rneu=KSpencerKernel(M,"ar");
+  setring rneu;
+  basering;
+  print(KS);
+}
+///////////////////////////////////////////////////////////////////////////
+
diff --git a/Singular/LIB/spectrum.lib b/Singular/LIB/spectrum.lib
new file mode 100644
index 0000000..4e6fcbc
--- /dev/null
+++ b/Singular/LIB/spectrum.lib
@@ -0,0 +1,62 @@
+////////////////////////////////////////////////////////////////////////////
+version="version spectrum.lib 4.0.0.0 Jun_2013 "; // $Id: f3e0a4f4c041175ac3b07f429fc854f78ecb0cde $
+category="Singularities";
+info="
+LIBRARY:  spectrum.lib  Singularity Spectrum for Nondegenerate Singularities
+AUTHOR:   S. Endrass
+
+PROCEDURES:
+ spectrumnd(poly f[,1]);  spectrum of nondegenerate isolated singularity f
+";
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc spectrumnd (poly f,list #)
+"USAGE:    spectrumnd(f[,1]); poly f
+ASSUME:   basering has characteristic 0 and local ordering,
+          f has isolated singularity at 0 and nondegenerate principal part
+RETURN:
+ at format
+list S:
+  ideal S[1]: spectral numbers in increasing order
+  intvec S[2]:
+    int S[2][i]: multiplicity of spectral number S[1][i]
+ at end format
+NOTE:     if a second argument 1 is given,
+          no test for a degenerate principal part will be done
+SEE_ALSO: gmssing_lib
+KEYWORDS: singularities; Gauss-Manin connection; spectrum
+EXAMPLE:  example spectrumnd; shows an example
+"
+{
+  if(charstr(basering)!="0")
+  {
+    ERROR("characteristic 0 expected");
+  }
+  if(size(#)==0)
+  {
+    list S=system("spectrum",f);
+  }
+  else
+  {
+    list S=system("spectrum",f,#[1]);
+  }
+  ideal a=number(S[4][1])/S[5][1]-1;
+  int i;
+  for(i=S[3];i>1;i--)
+  {
+    a[i]=number(S[4][i])/S[5][i]-1;
+  }
+  return(list(a,S[6]));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring R=0,(x,y),ds;
+  poly f=x^31+x^6*y^7+x^2*y^12+x^13*y^2+y^29;
+  list s=spectrumnd(f);
+  size(s[1]);
+  s[1][22];
+  s[2][22];
+}
+///////////////////////////////////////////////////////////////////////////////
+
diff --git a/Singular/LIB/standard.lib b/Singular/LIB/standard.lib
new file mode 100644
index 0000000..4910881
--- /dev/null
+++ b/Singular/LIB/standard.lib
@@ -0,0 +1,2510 @@
+///////////////////////////////////////////////////////////////////////////
+version="version standard.lib 4.0.0.0 Jun_2013 "; // $Id: b1a49400d8da5255857ae7d8bd5dda51ca9fc854 $
+category="Miscellaneous";
+info="
+LIBRARY: standard.lib   Procedures which are always loaded at Start-up
+
+PROCEDURES:
+ stdfglm(ideal[,ord])   standard basis of ideal via fglm [and ordering ord]
+ stdhilb(ideal[,h])     Hilbert driven Groebner basis of ideal
+ groebner(ideal,...)    standard basis using a heuristically chosen method
+ res(ideal/module,[i])  free resolution of ideal or module
+ sprintf(fmt,...)       returns fomatted string
+ fprintf(link,fmt,..)   writes formatted string to link
+ printf(fmt,...)        displays formatted string
+ weightKB(stc,dd,vl)    degree dd part of a kbase w.r.t. some weigths
+ qslimgb(i)             computes a standard basis with slimgb in a qring
+ par2varRing([i])       create a ring making pars to vars, together with i
+ datetime()             return date and time as a string
+ max(i,j)               maximum of i and j
+ min(i,j)               minimum of i and j
+
+";
+//AUXILIARY PROCEDURES:
+// hilbRing([i])          ring for computing the (weighted) hilbert series
+// quotientList(L,...)    ringlist for creating a correct quotient ring
+
+//////////////////////////////////////////////////////////////////////////////
+
+proc stdfglm (ideal i, list #)
+"SYNTAX: @code{stdfglm (} ideal_expression @code{)} @*
+         @code{stdfglm (} ideal_expression at code{,} string_expression @code{)}
+TYPE:    ideal
+PURPOSE: computes the standard basis of the ideal in the basering
+         via @code{fglm} from the ordering given as the second argument
+         to the ordering of the basering. If no second argument is given,
+         \"dp\" is used. The standard basis for the given ordering (resp. for
+         \"dp\") is computed via the command groebner except if a further
+         argument \"std\" or \"slimgb\" is given in which case std resp.
+         slimgb is used.
+SEE ALSO: fglm, groebner, std, slimgb, stdhilb
+KEYWORDS: fglm
+EXAMPLE: example stdfglm; shows an example"
+{
+  string os;
+  int s = size(#);
+  def P= basering;
+  string algorithm;
+  int ii;
+  for( ii=1; ii<=s; ii++)
+  {
+    if ( typeof(#[ii])== "string" )
+    {
+      if ( #[ii]=="std" || #[ii]=="slimgb" )
+      {
+        algorithm =  #[ii];
+        # = delete(#,ii);
+        s--;
+        ii--;
+      }
+    }
+  }
+
+  if((s > 0) && (typeof(#[1]) == "string"))
+  {
+    os = #[1];
+    ideal Qideal = ideal(P);
+    int sQ = size(Qideal);
+    int sM = size(minpoly);
+    if ( sM!=0 )
+    {
+      string mpoly = string(minpoly);
+    }
+    if (sQ!=0 )
+    {
+      execute("ring Rfglm=("+charstr(P)+"),("+varstr(P)+"),"+os+";");
+      ideal Qideal = fetch(P,Qideal);
+      qring Pfglm = groebner(Qideal,"std","slimgb");
+    }
+    else
+    {
+      execute("ring Pfglm=("+charstr(P)+"),("+varstr(P)+"),"+os+";");
+    }
+    if ( sM!=0 )
+    {
+      execute("minpoly="+mpoly+";");
+    }
+  }
+  else
+  {
+    list BRlist = ringlist(P);
+    int nvarP = nvars(P);
+    intvec w;                       //for ringweights of basering P
+    int k;
+    for(k=1;  k <= nvarP; k++)
+    {
+      w[k]=deg(var(k));
+    }
+
+    BRlist[3] = list();
+    if( s==0 or (typeof(#[1]) != "string") )
+    {
+      if( w==1 )
+      {
+        BRlist[3][1]=list("dp",w);
+      }
+      else
+      {
+        BRlist[3][1]=list("wp",w);
+      }
+      BRlist[3][2]=list("C",intvec(0));
+      def Pfglm = ring(quotientList(BRlist));
+      setring Pfglm;
+    }
+  }
+  ideal i = fetch(P,i);
+
+  intvec opt = option(get);            //save options
+  option(redSB);
+  if (size(algorithm) > 0)
+  {
+    i = groebner(i,algorithm);
+  }
+  else
+  {
+    i = groebner(i);
+  }
+  option(set,opt);
+  setring P;
+  return (fglm(Pfglm,i));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r  = 0,(x,y,z),lp;
+   ideal i = y3+x2,x2y+x2,x3-x2,z4-x2-y;
+   stdfglm(i);                   //uses fglm from "dp" (with groebner) to "lp"
+   stdfglm(i,"std");             //uses fglm from "dp" (with std) to "lp"
+
+   ring s  = (0,x),(y,z,u,v),lp;
+   minpoly = x2+1;
+   ideal i = u5-v4,zv-u2,zu3-v3,z2u-v2,z3-uv,yv-zu,yu-z2,yz-v,y2-u,u-xy2;
+   weight(i);
+   stdfglm(i,"(a(2,3,4,5),dp)"); //uses fglm from "(a(2,3,4,5),dp)" to "lp"
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+proc stdhilb(def i,list #)
+"SYNTAX: @code{stdhilb (} ideal_expression @code{)} @*
+         @code{stdhilb (} module_expression @code{)} @*
+         @code{stdhilb (} ideal_expression, intvec_expression @code{)}@*
+         @code{stdhilb (} module_expression, intvec_expression @code{)}@*
+         @code{stdhilb (} ideal_expression at code{,} list of string_expressions,
+               and intvec_expression @code{)} @*
+TYPE:    type of the first argument
+PURPOSE: Compute a Groebner basis of the ideal/module in the basering by
+         using the Hilbert driven Groebner basis algorithm.
+         If an argument of type string, stating @code{\"std\"} resp. @code{\"slimgb\"},
+         is given, the standard basis computation uses @code{std} or
+         @code{slimgb}, otherwise a heuristically chosen method (default)@*
+         If an optional second argument w of type intvec is given, w is used
+         as variable weights. If w is not given, it is computed as w[i] =
+         deg(var(i)). If the ideal is homogeneous w.r.t. w then the
+         Hilbert series is computed w.r.t. to these weights.
+THEORY:  If the ideal is not homogeneous compute first a Groebner basis
+         of the homogenization [w.r.t. the weights w] of the ideal/module,
+         then the Hilbert function and, finally, a Groebner basis in the
+         original ring by using the computed Hilbert function. If the given
+         w does not coincide with the variable weights of the basering, the
+         result may not be a groebner basis in the original ring.
+NOTE:    'Homogeneous' means weighted homogeneous with respect to the weights
+         w[i] of the variables var(i) of the basering. Parameters are not
+         converted to variables.
+SEE ALSO: stdfglm, std, slimgb, groebner
+KEYWORDS: Hilbert function
+EXAMPLE: example stdhilb;  shows an example"
+{
+
+//--------------------- save data from basering --------------------------
+  def P=basering;
+  int nr;
+  if (typeof(i)=="ideal") { nr=1;}
+  else                    { nr= nrows(i); }    //nr=1 if i is an ideal
+  ideal Qideal = ideal(P);      //defining the quotient ideal if P is a qring
+  int was_qring;                //remembers if basering was a qring
+  int is_homog =homog(i);       //check for homogeneity of i and Qideal
+  if (size(Qideal) > 0)
+  {
+     was_qring = 1;
+  }
+
+  // save ordering of basering P for later use
+  list ord_P = ringlist(P)[3];     //ordering of basering in ringlist
+  string ordstr_P = ordstr(P);     //ordering of basering as string
+  int nvarP = nvars(P);
+
+  //save options:
+  intvec gopt = option(get);
+  int p_opt;
+  string s_opt = option();
+  if (find(s_opt, "prot"))  { p_opt = 1; }
+
+//-------------------- check the given method and weights ---------------------
+//Note: stdhilb is used in elim where it is applied to an elimination ordering
+//a(1..1,0..0),wp(w). In such a ring deg(var(k)=0 for all vars corresponding to
+//0 in a(1..1,0..0), hence we cannot identify w via w[k] = deg(var(k));
+//Therefore hilbstd has the option to give ringweights.
+
+  int k;
+  string method;
+  for (k=1; k<=size(#); k++)
+  {
+    if (typeof(#[k]) == "intvec")
+    {
+        intvec w = #[k];         //given ringweights of basering P
+    }
+    if (typeof(#[k]) == "string")
+    {
+      method = method + "," + #[k];
+    }
+  }
+
+  if ( defined(w)!=voice )
+  {
+    intvec w;
+    for(k=nvarP;  k>=1; k--)
+    {
+       w[k] = deg(var(k));     //compute ring weights
+    }
+  }
+
+
+  if (npars(P) > 0)             //clear denominators of parameters
+  {
+    for( k=ncols(i); k>0; k-- )
+    {
+      i[k]=cleardenom(i[k]);
+    }
+  }
+
+//---------- exclude cases to which stdhilb should no be applied  ----------
+//Note that quotient ideal of qring must be homogeneous too
+
+  int neg=1-attrib (P,"global");
+
+  if( //find(ordstr_P,"s") ||// covered by neg
+     find(ordstr_P,"M") || neg )
+  {
+    // if( defined(hi) && is_homog )
+    // {
+    //  if (p_opt){"std with given Hilbert function in basering";}
+    //  return( std(i,hi,w) );
+    //### here we would need Hibert-Samuel function
+    // }
+
+    if (p_opt)
+    {"//-- stdhilb not implemented, we use std in ring:"; string(P);}
+    return( std(i) );
+  }
+
+//------------------------ change to hilbRing ----------------------------
+//The ground field of P and Philb coincide, Philb has an extra variable
+//@ or @(k). Philb is no qring and the predefined ideal/module Id(1) in
+//Philb is homogeneous (it is the homogenized i w.r.t. @ or @(k))
+//Parameters of P are not converted in Philb
+//Philb has only 1 block dp or wp(w)
+
+  list hiRi = hilbRing(i,w);
+  intvec W = hiRi[2];
+  def Philb = hiRi[1];
+  setring Philb;
+
+//-------- compute Hilbert series of homogenized ideal in Philb ---------
+//There are three cases
+
+  string algorithm;       //possibilities: std, slimgb, stdorslimgb
+  //define algorithm:
+  if( find(method,"std") && !find(method,"slimgb") )
+  {
+    algorithm = "std";
+  }
+  if( find(method,"slimgb") && !find(method,"std") )
+  {
+    algorithm = "slimgb";
+  }
+  if( find(method,"std") && find(method,"slimgb") ||
+    (!find(method,"std") && !find(method,"slimgb")) )
+  {
+    algorithm = "stdorslimgb";
+  }
+
+//### geaendert Dez08: es wird std(Id(1)) statt Id(1) aus Philb nach Phelp
+// weitergegeben fuer hilbertgetriebenen std
+
+  if (( algorithm=="std" || ( algorithm=="stdorslimgb" && char(P)>0 ) )
+  && (defined(hi)!=voice))
+  {
+    if (p_opt) {"compute hilbert series with std in ring " + string(Philb);
+                "weights used for hilbert series:",W;}
+    Id(1) = std(Id(1));
+    intvec hi = hilb( Id(1),1,W );
+  }
+  if (( algorithm=="slimgb" || ( algorithm=="stdorslimgb" && char(P)==0 ) )
+  && (defined(hi)!=voice))
+  {
+    if (p_opt) {"compute hilbert series with slimgb in ring " + string(Philb);
+                "weights used for hilbert series:",W;}
+    Id(1) = qslimgb(Id(1));
+    intvec hi = hilb( Id(1),1,W );
+  }
+
+  //-------------- we need another intermediate ring Phelp ----------------
+  //In Phelp we change only the ordering from Philb (otherwise it coincides
+  //with Philb). Phelp has in addition to P an extra homogenizing variable
+  //with name @ (resp. @(i) if @ and @(1), ..., @(i-1) are defined) with
+  //ordering an extra last block dp(1).
+  //Phelp has the same ordering as P on common variables. In Phelp
+  //a quotient ideal from P is added to the input
+
+  list BRlist = ringlist(Philb);
+  BRlist[3] = list();
+  int so = size(ord_P);
+  if( ord_P[so][1] =="c" || ord_P[so][1] =="C" )
+  {
+    list moduleord = ord_P[so];
+    so = so-1;
+  }
+  for (k=1; k<=so; k++)
+  {
+    BRlist[3][k] = ord_P[k];
+  }
+
+  BRlist[3][so+1] = list("dp",1);
+  w = w,1;
+
+  if( defined(moduleord)==voice )
+  {
+    BRlist[3][so+2] = moduleord;
+  }
+
+//--- change to extended ring Phelp and compute std with hilbert series ----
+  def Phelp = ring(quotientList(BRlist));
+  setring Phelp;
+  def i = imap(Philb, Id(1));
+  kill Philb;
+
+  // compute std with Hilbert series
+  option(redThrough);
+  if (w == 1)
+  {
+    if (p_opt){ "std with hilb in " + string(Phelp);}
+    i = std(i, hi);
+  }
+  else
+  {
+    if(p_opt){"std with weighted hilb in "+string(Phelp);}
+    i = std(i, hi, w);
+  }
+
+//-------------------- go back to original ring ---------------------------
+//The main computation is done. Do not forget to simplfy before maping.
+
+  // subst 1 for homogenizing var
+  if ( p_opt ) { "dehomogenization"; }
+  i = subst(i, var(nvars(basering)), 1);
+
+  if (p_opt) { "simplification"; }
+  i= simplify(i,34);
+
+  setring P;
+  if (p_opt) { "imap to ring "+string(P); }
+  i = imap(Phelp,i);
+  kill Phelp;
+  if( was_qring )
+  {
+    i = NF(i,std(0));
+  }
+  i = simplify(i,34);
+  // compute reduced SB
+  if (find(s_opt, "redSB") > 0)
+  {
+    if (p_opt) { "//interreduction"; }
+    i=interred(i);
+  }
+  attrib(i, "isSB", 1);
+  option(set,gopt);
+  return (i);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring  r = 0,(x,y,z),lp;
+   ideal i = y3+x2,x2y+x2z2,x3-z9,z4-y2-xz;
+   ideal j = stdhilb(i); j;
+
+   ring  r1 = 0,(x,y,z),wp(3,2,1);
+   ideal  i = y3+x2,x2y+x2z2,x3-z9,z4-y2-xz;  //ideal is homogeneous
+   ideal j = stdhilb(i,"std"); j;
+   //this is equivalent to:
+   intvec v = hilb(std(i),1);
+   ideal j1 = std(i,v,intvec(3,2,1)); j1;
+
+   size(NF(j,j1))+size(NF(j1,j));            //j and j1 define the same ideal
+}
+
+///////////////////////////////////////////////////////////////////////////////
+proc quotientList (list RL, list #)
+"SYNTAX: @code{quotientList (} list_expression @code{)} @*
+         @code{quotientList (} list_expression @code{,} string_expression at code{)}
+TYPE:    list
+PURPOSE: define a ringlist, say QL, of the first argument, say RL, which is
+         assumed to be the ringlist of a qring, but where the quotient ideal
+         RL[4] is not a standard basis with respect to the given monomial
+         order in RL[3]. Then QL will be obtained from RL just by replacing
+         RL[4] by a standard of it with respect to this order. RL itself
+         will be returnd if size(RL[4]) <= 1 (in which case it is known to be
+         a standard basis w.r.t. any ordering) or if a second argument
+         \"isSB\" of type string is given.
+NOTE:    the command ring(quotientList(RL)) defines a quotient ring correctly
+         and should be used instead of ring(RL) if the quotient ideal RL[4]
+         is not (or not known to be) a standard basis with respect to the
+         monomial ordering specified in RL[3].
+SEE ALSO: ringlist, ring
+EXAMPLE: example quotientList; shows an example"
+{
+  def P = basering;
+  if( size(#) > 0 )
+  {
+    if ( #[1] == "isSB")
+    {
+      return (RL);
+    }
+  }
+  ideal Qideal  = RL[4];  //##Achtung: falls basering Nullteiler hat, kann
+                           //die SB eines Elements mehrere Elemente enthalten
+  if( size(Qideal) <= 0)
+  {
+    return (RL);
+  }
+
+  RL[4] = ideal(0);
+  def Phelp = ring(RL);
+  setring Phelp;
+  ideal Qideal = groebner(fetch(P,Qideal));
+  setring P;
+  RL[4]=fetch(Phelp,Qideal);
+  return (RL);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring P = 0,(y,z,u,v),lp;
+   ideal i = y+u2+uv3, z+uv3;            //i is an lp-SB but not a dp_SB
+   qring Q = std(i);
+   list LQ = ringlist(Q);
+   LQ[3][1][1]="dp";
+   def Q1 = ring(quotientList(LQ));
+   setring Q1;
+   Q1;
+
+   setring Q;
+   ideal q1 = uv3+z, u2+y-z, yv3-zv3-zu; //q1 is a dp-standard basis
+   LQ[4] = q1;
+   def Q2 = ring(quotientList(LQ,"isSB"));
+   setring Q2;
+   Q2;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+proc par2varRing (list #)
+"USAGE:   par2varRing([l]); l list of ideals/modules [default:l=empty list]
+RETURN:  list, say L, with L[1] a ring where the parameters of the
+         basering have been converted to an additional last block of
+         variables, all of weight 1, and ordering dp.
+         If a list l with l[i] an ideal/module is given, then
+         l[i] + minpoly*freemodule(nrows(l[i])) is mapped to an ideal/module
+         in L[1] with name Id(i).
+         If the basering has no parameters then L[1] is the basering.
+EXAMPLE: example par2varRing; shows an example"
+{
+  def P = basering;
+  int npar = npars(P);  //number of parameters
+  int s = size(#);
+  int ii;
+  if ( npar == 0)
+  {
+    dbprint(printlevel-voice+3,"// ** no parameters, ring was not changed");
+    for( ii = 1; ii <= s; ii++)
+    {
+      def Id(ii) = #[ii];
+      export (Id(ii));
+    }
+    return(list(P));
+  }
+
+  list rlist = ringlist(P);
+  list parlist = rlist[1];
+  rlist[1] = parlist[1];
+
+  string @Minpoly = string(minpoly);     //check for minpoly:
+  int sm = size(minpoly);
+  //now create new ring
+  for( ii = 1; ii <= s; ii++)
+  {
+    def Id(ii) = #[ii];
+  }
+  int nvar = size(rlist[2]);
+  int nblock = size(rlist[3]);
+  int k;
+  for (k=1; k<=npar; k++)
+  {
+    rlist[2][nvar+k] = parlist[2][k];   //change variable list
+  }
+
+  //converted parameters get one block dp. If module ordering was in front
+  //it stays in front, otherwise it will be moved to the end
+  intvec OW = 1:npar;
+  if( rlist[3][nblock][1] =="c" || rlist[3][nblock][1] =="C" )
+  {
+    rlist[3][nblock+1] = rlist[3][nblock];
+    rlist[3][nblock] = list("dp",OW);
+  }
+  else
+  {
+    rlist[3][nblock+1] = list("dp",OW);
+  }
+
+  def Ppar2var = ring(quotientList(rlist));
+  setring Ppar2var;
+  if ( sm == 0 )
+  {
+    for( ii = 1; ii <= s; ii++)
+    {
+      def Id(ii) = imap(P,Id(ii));
+      export (Id(ii));
+    }
+  }
+  else
+  {
+    if( find(option(),"prot") ){"//add minpoly to input";}
+    execute("poly Minpoly = " + @Minpoly + " ;");
+    for( ii = 1; ii <= s; ii++)
+    {
+      def Id(ii) = imap(P,Id(ii));
+      if (typeof(Id(ii))=="module")
+      {
+        Id(ii) = Id(ii),Minpoly*freemodule(nrows(Id(ii)));
+      }
+      else
+      {
+        Id(ii) = Id(ii),Minpoly;
+      }
+      export (Id(ii));
+    }
+  }
+  list Lpar2var = Ppar2var;
+  return(Lpar2var);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring R = (0,x),(y,z,u,v),lp;
+   minpoly = x2+1;
+   ideal i = x3,x2+y+z+u+v,xyzuv-1; i;
+   def P = par2varRing(i)[1]; P;
+   setring(P);
+   Id(1);
+
+   setring R;
+   module m = x3*[1,1,1], (xyzuv-1)*[1,0,1];
+   def Q = par2varRing(m)[1]; Q;
+   setring(Q);
+   print(Id(1));
+}
+
+//////////////////////////////////////////////////////////////////////////////
+proc hilbRing ( list # )
+"USAGE:   hilbRing([w,l]); w = intvec, l = list of ideals/modules
+RETURN:  list, say L: L[1] is a ring and L[2] an intvec
+         L[1] is a ring whith an extra homogenizing variable with name @,
+         resp. @(i) if @ and @(1), ..., @(i-1) are defined.
+         The monomial ordering of L[1] is consists of 1 block: dp if the
+         weights of the variables of the basering, say R, are all 1, resp.
+         wp(w,1) wehre w is either given or the intvec of weights of the
+         variables of R, i.e. w[k]=deg(var(k)).
+         If R is a quotient ring P/Q, then L[1] is not a quotient ring but
+         contains the ideal @Qidealhilb@, the homogenized ideal Q of P.
+         (Parameters of R are not touched).
+         If a list l is given with l[i] an ideal/module, then l[i] is mapped
+         to Id(i), the homogenized l[i]+Q*freemodule(nrows(l[i]) in L[1]
+         (Id(i) = l[i] if l[i] is already homogeneous).
+         L[2] is the intvec (w,1).
+PURPOSE: Prepare a ring for computing the (weighted) hilbert series of
+         an ideal/module with an easy monomial ordering.
+NOTE:    For this purpose we need w[k]=deg(var(k)). However, if the ordering
+         contains an extra weight vector a(v,0..0)) deg(var(k)) returns 0 for
+         k being an index which is 0 in a. Therefore we must compute w
+         beforehand and give it to hilbRing.
+EXAMPLE: example hilbRing; shows an example
+"
+{
+  def P = basering;
+  ideal Qideal = ideal(P);    //defining the quotient ideal if P is a qring
+  if( size(Qideal) != 0 )
+  {
+    int is_qring =1;
+  }
+  list BRlist = ringlist(P);
+  BRlist[4] = ideal(0);      //kill quotient ideal in BRlist
+
+  int nvarP = nvars(P);
+  int s = size(#);
+  int k;
+
+  for(k = 1; k <= s; k++)
+  {
+    if ( typeof(#[k]) == "intvec" )
+    {
+       intvec w = #[k];      //given weights for the variables
+       # = delete (#,k);
+    }
+  }
+
+  s = size(#);
+  for(k = 1; k <= s; k++)
+  {
+     def Id(k) = #[k];
+     int nr(k) = nrows(Id(k));
+  }
+
+  if ( defined(w)!=voice )
+  {
+    intvec w;                   //for ringweights of basering P
+    for(k=1;  k<=nvarP; k++)
+    {
+      w[k]=deg(var(k));        //degree of kth variable
+    }
+  }
+  //--------------------- a homogenizing variable is added ------------------
+  // call it @, resp. @(k) if @(1),...,@(k-1) are defined
+  string homvar;
+  if ( defined(@)==0 )
+  {
+    homvar = "@";
+  }
+  else
+  {
+    k=1;
+    while( defined(@(k)) != 0 )
+    {
+      k++;
+    }
+    homvar = "@("+string(k)+")";
+  }
+  BRlist[2][nvarP+1] = homvar;
+  w[nvarP +1]=1;
+
+  //ordering is set to (dp,C) if weights of all variables are 1
+  //resp. to (wp(w,1),C) where w are the ringweights of basering P
+  //homogenizing var gets weight 1:
+
+  BRlist[3] = list();
+  BRlist[3][2]=list("C",intvec(0));  //put module ordering always last
+  if(w==1)
+  {
+    BRlist[3][1]=list("dp",w);
+  }
+  else
+  {
+    BRlist[3][1]=list("wp",w);
+  }
+
+  //-------------- change ring and get ideal from previous ring ---------------
+  def Philb = ring(quotientList(BRlist));
+  kill BRlist;
+  setring Philb;
+  if( defined(is_qring)==voice )
+  {
+    ideal @Qidealhilb@ =  imap(P,Qideal);
+    if ( ! homog(@Qidealhilb@) )
+    {
+       @Qidealhilb@ =  homog( @Qidealhilb@, `homvar` );
+    }
+    export(@Qidealhilb@);
+
+    if( find(option(),"prot") ){"add quotient ideal to input";}
+
+    for(k = 1; k <= s; k++)
+    { //homogenize if necessary
+      def Id(k) =  imap(P,Id(k));
+      if ( ! homog(Id(k)) )
+      {
+         Id(k) =  homog( imap(P,Id(k)), `homvar` );
+      }
+      if (typeof(Id(k))=="module")
+      {
+        Id(k) =  Id(k), at Qidealhilb@*freemodule(nr(k)) ;
+      }
+      else
+      {
+        Id(k) =  Id(k), at Qidealhilb@ ;
+      }
+      export(Id(k));
+    }
+  }
+  else
+  {
+    for(k = 1; k <= s; k++)
+    { //homogenize if  necessary
+      def Id(k) =  imap(P,Id(k));
+      if ( ! homog(Id(k)) )
+      {
+         Id(k) =  homog( imap(P,Id(k)), `homvar` );
+      }
+      export(Id(k));
+    }
+  }
+  list Lhilb = Philb,w;
+  setring(P); return(Lhilb);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring R = 0,(x,y,z,u,v),lp;
+   ideal i = x+y2+z3,xy+xv+yz+zu+uv,xyzuv-1;
+   intvec w = 6,3,2,1,1;
+   hilbRing(i,w);
+   def P = hilbRing(w,i)[1];
+   setring P;
+   Id(1);
+   hilb(std(Id(1)),1);
+
+   ring S =  0,(x,y,z,u,v),lp;
+   qring T = std(x+y2+z3);
+   ideal i = xy+xv+yz+zu+uv,xyzuv-v5;
+   module m = i*[0,1,1] + (xyzuv-v5)*[1,1,0];
+   def Q = hilbRing(m)[1];  Q;
+   setring Q;
+   print(Id(1));
+}
+
+//////////////////////////////////////////////////////////////////////////////
+proc qslimgb (def i)
+"USAGE:   qslimgb(i); i ideal or module
+RETURN:  same type as input, a standard basis of i computed with slimgb
+NOTE:    Only as long as slimgb does not know qrings qslimgb should be used
+         in case the basering is (possibly) a quotient ring.
+         The quotient ideal is added to the input and slimgb is applied.
+EXAMPLE: example qslimgb; shows an example"
+{
+  def P = basering;
+  ideal Qideal = ideal(P);      //defining the quotient ideal if P is a qring
+  int p_opt;
+  if( find(option(),"prot") )
+  {
+    p_opt=1;
+  }
+  if (size(Qideal) == 0)
+  {
+    if (p_opt) { "slimgb in ring " + string(P); }
+    return(slimgb(i));
+  }
+
+  //case of a qring; since slimgb does not know qrings we
+  //delete the quotient ideal and add it to i
+
+  list BRlist = ringlist(P);
+  BRlist[4] = ideal(0);
+  def Phelp = ring(BRlist);
+  kill BRlist;
+  setring Phelp;
+  // module case:
+  def iq = imap(P,i);
+  iq = iq, imap(P,Qideal)*freemodule(nrows(iq));
+  if (p_opt)
+  {
+    "slimgb in ring " + string(Phelp);
+    "(with quotient ideal added to input)";
+  }
+  iq = slimgb(iq);
+
+  setring P;
+  if (p_opt) { "//imap to original ring"; }
+  i = imap(Phelp,iq);
+  kill Phelp;
+
+  if (find(option(),"redSB") > 0)
+  {
+    if (p_opt) { "//interreduction"; }
+    i=reduce(i,std(0));
+    i=interred(i);
+  }
+  attrib(i, "isSB", 1);
+  return (i);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring R  = (0,v),(x,y,z,u),dp;
+   qring Q = std(x2-y3);
+   ideal i = x+y2,xy+yz+zu+u*v,xyzu*v-1;
+   ideal j = qslimgb(i); j;
+
+   module m = [x+y2,1,0], [1,1,x2+y2+xyz];
+   print(qslimgb(m));
+}
+
+//////////////////////////////////////////////////////////////////////////////
+proc groebner(def i_par, list #)
+"SYNTAX: @code{groebner (} ideal_expression @code{)} @*
+         @code{groebner (} module_expression @code{)} @*
+         @code{groebner (} ideal_expression at code{,} int_expression @code{)} @*
+         @code{groebner (} module_expression at code{,} int_expression @code{)} @*
+         @code{groebner (} ideal_expression at code{,} list of string_expressions
+               @code{)} @*
+         @code{groebner (} ideal_expression at code{,} list of string_expressions
+               and int_expression @code{)} @*
+         @code{groebner (} ideal_expression at code{,} int_expression @code{)}
+TYPE:    type of the first argument
+PURPOSE: computes a standard basis of the first argument @code{I}
+         (ideal or module) by a heuristically chosen method (default)
+         or by a method specified by further arguments of type string.
+         Possible methods are:  @*
+         - the direct methods @code{\"std\"} or @code{\"slimgb\"} without
+           conversion, @*
+         - conversion methods @code{\"hilb\"} or @code{\"fglm\"} where
+           a Groebner basis is first computed with an \"easy\" ordering
+           and then converted to the ordering of the basering by the
+           Hilbert driven Groebner basis computation or by linear algebra.
+           The actual computation of the Groebner basis can be
+           specified by @code{\"std\"} or by @code{\"slimgb\"}
+           (not for all orderings implemented). @*
+         A further string @code{\"par2var\"} converts parameters to an extra
+         block of variables before a Groebner basis computation (and
+         afterwards back).
+         @code{option(prot)} informs about the chosen method.
+NOTE:    If an additional argument, say @code{wait}, of type int is given,
+         then the computation runs for at most @code{wait} seconds.
+         That is, if no result could be computed in @code{wait} seconds,
+         then the computation is interrupted, 0 is returned, a warning
+         message is displayed, and the global variable
+         @code{Standard::groebner_error} is defined.
+         This feature uses MP and hence it is available on UNIX platforms, only.
+HINT:    Since there exists no uniform best method for computing standard
+         bases, and since the difference in performance of a method on
+         different examples can be huge, it is recommended to test, for hard
+         examples, first various methods on a simplified example (e.g. use
+         characteristic 32003 instead of 0 or substitute a subset of
+         parameters/variables by integers, etc.). @*
+SEE ALSO: stdhilb, stdfglm, std, slimgb
+KEYWORDS: time limit on computations; MP, groebner basis computations
+EXAMPLE: example groebner;  shows an example"
+
+{
+//Vorgabe einer Teilmenge aus {hilb,fglm,par2var,std,slimgb}
+//V1: Erste Einstellungen (Jan 2007)
+//V2: Aktuelle Aenderungen (Juni 2008)
+//---------------------------------
+//0. Immer Aufruf von std unabhaengig von der Vorgabe:
+//   gemischte Ordnungen, extra Gewichtsvektor, Matrix Ordnungen
+//   ### Todo: extra Gewichtsvektor sollte nicht immer mit std wirken,
+//   sondern z.B. mit "hilb" arbeiten koennen
+//   ### Todo: es sollte ein Gewichtsvektor mitgegeben werden koennen (oder
+//   berechnet werden), z.B. groebner(I,"hilb",w) oder groebner(I,"withWeights")
+//   wie bei elim in elim.lib
+
+//1. Keine Vorgabe: es wirkt die aktuelle Heuristk:
+//   - Char = p: std
+//V1 - Char = 0: slimgb (im qring wird Quotientenideal zum Input addiert)
+//V2 - Char = 0: std
+//   - 1-Block-Ordnungen/non-commutative: direkt Aufruf von std oder slimgb
+//   - Komplizierte Ordnungen (lp oder > 1 Block): hilb
+//V1 - Parameter werden grundsaetzlich nicht in Variable umgewandelt
+//V2 - Mehr als ein Parmeter wird zu Variable konvertiert
+//   - fglm is keine Heuristik, da sonst vorher dim==0 peprueft werden muss
+
+//2. Vorgabe aus {std,slimgb}: es wird wo immer moeglich das Angegebene
+//   gewaehlt (da slimgb keine Hilbertfunktion kennt, wird std verwendet).
+//   Bei slimgb im qring, wird das Quotientenideal zum Ideal addiert.
+//   Bei Angabe von std zusammen mit slimgb (aequivalent zur Angabe von
+//   keinem von beidem) wirkt obige Heuristik.
+
+//3. Nichtleere Vorgabe aus {hilb,fglm,std,slimgb}:
+//   es wird nur das Angegebene und Moegliche sowie das Notwendige verwendet
+//   und bei Wahlmoeglickeit je nach Heuristik.
+//   Z.B. Vorgabe von {hilb} ist aequivalent zu {hilb,std,slimgb} und es wird
+//   hilb und nach Heuristik std oder slimgb verwendet,
+//   (V1: aber nicht par2var)
+//   bei Vorgabe von {hilb,slimgb} wird hilb und wo moeglich slimgb verwendet.
+
+//4. Bei Vorgabe von {par2var} wird par2var immer mit hilb und nach Heuristik
+//   std oder slimgb verwendet. Zu Variablen konvertierte Parameter haben
+//   extra letzten Block und Gewichte 1.
+
+  def P=basering;
+  if ((typeof(i_par)=="vector")||(typeof(i_par)=="module")||(typeof(i_par)=="matrix")) {module i=i_par;}
+  else {ideal i=i_par; } // int, poly, number, ideal
+  kill i_par;
+// check for integer etc coefficients
+  if (charstr(basering)[1]=="i") // either integer or integer,q
+  {
+    if (find(option(),"prot"))  { "calling std for ideals in ring with ring coefficients"; }
+    return (std(i));
+  }
+
+//----------------------- save the given method ---------------------------
+  string method;                //all given methods as a coma separated string
+  list Method;                  //all given methods as a list
+  int k;
+  for (k=1; k<=size(#); k++)
+  {
+     if (typeof(#[k]) == "int")
+     {
+       int wait = #[k];
+     }
+     if (typeof(#[k]) == "string")
+     {
+       method = method + "," + #[k];
+       Method = Method + list(#[k]);
+     }
+  }
+
+ //======= we have an argument of type int -- try to use MPfork links =======
+  if ( defined(wait) == voice )
+  {
+    if ( system("with", "MP") )
+    {
+        int j = 10;
+        string bs = nameof(basering);
+        link l_fork = "MPtcp:fork";
+        open(l_fork);
+        write(l_fork, quote(system("pid")));
+        int pid = read(l_fork);
+//        write(l_fork, quote(groebner(eval(i))));
+        write(l_fork, quote(groebner(eval(i),eval(Method))));
+//###Fehlermeldung:
+// ***dError: undef. ringorder used
+// occured at:
+
+        // sleep in small intervalls for appr. one second
+        if (wait > 0)
+        {
+          while(j < 1000000)
+          {
+            if (status(l_fork, "read", "ready", j)) {break;}
+            j = j + j;
+          }
+        }
+
+        // sleep in intervalls of one second from now on
+        j = 1;
+        while (j < wait)
+        {
+          if (status(l_fork, "read", "ready", 1000000)) {break;}
+          j = j + 1;
+        }
+
+        if (status(l_fork, "read", "ready"))
+        {
+          def result = read(l_fork);
+          if (bs != nameof(basering))
+          {
+            def PP = basering;
+            setring P;
+            def result = imap(PP, result);
+            kill PP;
+          }
+          if (defined(groebner_error)==1)
+          {
+            kill groebner_error;
+          }
+          kill l_fork;
+        }
+        else
+        {
+          ideal result;
+          if (! defined(groebner_error))
+          {
+            int groebner_error = 1;
+            export groebner_error;
+          }
+          "** groebner did not finish";
+          j = system("sh", "kill " + string(pid));
+        }
+        return (result);
+    }
+    else
+    {
+      "** groebner with a time limit on computation is not supported
+          in this configuration";
+    }
+  }
+
+ //=========== we are still here -- do the actual computation =============
+
+//--------------------- save data from basering ---------------------------
+  string @Minpoly = string(minpoly);      //minimal polynomial
+  int was_minpoly;             //remembers if there was a minpoly in P
+  if (size(minpoly) > 0)
+  {
+     was_minpoly = 1;
+  }
+
+  ideal Qideal = ideal(P);      //defining the quotient ideal if P is a qring
+  int was_qring;                //remembers if basering was a qring
+  //int is_homog = 1;
+  if (size(Qideal) > 0)
+  {
+     was_qring = 1;
+     //is_homog = homog(Qideal); //remembers if Qideal was homog (homog(0)=1)
+  }
+  list BRlist = ringlist(P);     //ringlist of basering
+
+  // save ordering of basering P for later use
+  list ord_P = BRlist[3];       //should be available in all rings
+  string ordstr_P = ordstr(P);
+  int nvars_P = nvars(P);
+  int npars_P = npars(P);
+  intvec w;                     //for ringweights of basering P
+  for(k=1;  k<=nvars_P; k++)
+  {
+     w[k]=deg(var(k));
+  }
+  int neg=1-attrib (P,"global");
+
+  //save options:
+  intvec opt=option(get);
+  string s_opt = option();
+  int p_opt;
+  if (find(s_opt, "prot"))  { p_opt = 1; }
+
+//------------------ cases where std is always used ------------------------
+//If other methods are not implemented or do not make sense, i.e. for
+//local or mixed orderings, matrix orderings, extra weight vector
+//### Todo: extra weight vector should be allowed for e.g. with "hilb"
+
+  if(  //( find(ordstr_P,"s") > 0 ) || // covered by neg
+       ( find(ordstr_P,"M") > 0 )  || ( find(ordstr_P,"a") > 0 )  || neg )
+  {
+    if (p_opt) { "std in basering"; }
+    return(std(i));
+  }
+
+//now we have:
+//ideal or module, global ordering, no matrix ordering, no extra weight vector
+//The interesting cases start now.
+
+ //------------------ classify the possible settings ---------------------
+  string algorithm;       //possibilities: std, slimgb, stdorslimgb
+  string conversion;      //possibilities: hilb, fglm, hilborfglm, no
+  string partovar;        //possibilities: yes, no
+  string order;           //possibilities: simple, !simple
+  string direct;          //possibilities: yes, no
+
+  //define algorithm:
+  if( find(method,"std") && !find(method,"slimgb") )
+  {
+    algorithm = "std";
+  }
+  if( find(method,"slimgb") && !find(method,"std") )
+  {
+    algorithm = "slimgb";
+  }
+  if( find(method,"std") && find(method,"slimgb") ||
+      (!find(method,"std") && !find(method,"slimgb")) )
+  {
+    algorithm = "stdorslimgb";
+  }
+
+  //define conversion:
+  if( find(method,"hilb") && !find(method,"fglm") )
+  {
+     conversion = "hilb"; // $Id: b1a49400d8da5255857ae7d8bd5dda51ca9fc854 $
+  }
+  if( find(method,"fglm") && !find(method,"hilb") )
+  {
+    conversion = "fglm"; // $Id: b1a49400d8da5255857ae7d8bd5dda51ca9fc854 $
+  }
+  if( find(method,"fglm") && find(method,"hilb") )
+  {
+    conversion = "hilborfglm"; // $Id: b1a49400d8da5255857ae7d8bd5dda51ca9fc854 $
+  }
+  if( !find(method,"fglm") && !find(method,"hilb") )
+  {
+    conversion = "no"; // $Id: b1a49400d8da5255857ae7d8bd5dda51ca9fc854 $
+  }
+
+  //define partovar:
+  //if( find(method,"par2var") && npars_P > 0 )   //V1
+  if( find(method,"par2var") || npars_P > 1 )     //V2
+  {
+     partovar = "yes";
+  }
+  else
+  {
+     partovar = "no";
+  }
+
+  //define order:
+  if (system("nblocks") <= 2)
+  {
+    if ( find(ordstr_P,"M")+find(ordstr_P,"lp")+find(ordstr_P,"rp") <= 0 )
+    {
+      order = "simple";
+    }
+  }
+
+  //define direct:
+  if ( (order=="simple" && (size(method)==0)) ||
+       (size(BRlist)>4) ||
+        (order=="simple" && (method==",par2var" && npars_P==0 )) ||
+         (conversion=="no" && partovar=="no" &&
+           (algorithm=="std" || algorithm=="slimgb" ||
+            (find(method,"std") && find(method,"slimgb")) ) ) )
+  {
+    direct = "yes";
+  }
+  else
+  {
+    direct = "no";
+  }
+
+  //order=="simple" means that the ordering of the variables consists of one
+  //block which is not a matrix ordering and not a lexicographical ordering.
+  //(Note:Singular counts always least 2 blocks, one is for module component):
+  //Call a method "direct" if conversion=="no" && partovar="no" which means
+  //that we apply std or slimgb dircet in the basering (exception
+  //as long as slimgb does not know qrings: in a qring of a ring P
+  //the ideal Qideal is added to the ideal and slimgb is applied in P).
+  //We apply a direct method if we have a simple monomial ordering, if no
+  //conversion (fglm or hilb) is specified and if the parameters shall
+  //not be made to variables
+  //BRlist (=ringlist of basering) > 4 if the basering is non-commutative
+//---------------------------- direct methods -----------------------------
+  if ( direct == "yes" )
+  {
+  //if ( algorithm=="std" || (algorithm=="stdorslimgb" && char(P)>0) )   //V1
+    if ( algorithm=="std" || (algorithm=="stdorslimgb") )                //V2
+    {
+      if (p_opt) { "std in " + string(P); }
+      return(std(i));
+    }
+  //if( algorithm=="slimgb" || (algorithm=="stdorslimgb" && char(P)==0)) //V1
+    if ( algorithm=="slimgb" )                                           //V2
+    {
+      return(qslimgb(i));
+    }
+  }
+
+//--------------------------- indirect methods -----------------------------
+//indirect methods are methods where a conversion is used with a ring change
+//We are in the following situation:
+//direct=="no" (i.e. "hilb" or "fglm" or "par2var" is given)
+//or no method is given and we have a complicated monomial ordering
+//V1: "par2var" is not a default strategy, it must be explicitely
+//given in order to be performed.
+//V2: "par2var" is a default strategy if there are more than 1 parameters
+
+//------------ case where no parameters are made to variables  -------------
+  if (  partovar == "no" && conversion == "hilb"
+    || (partovar == "no" && conversion == "fglm" )
+    || (partovar == "no" && conversion == "hilborfglm" )
+    || (partovar == "no" && conversion == "no" && direct == "no") )
+  //last case: heuristic
+  {
+    if ( conversion=="fglm" )
+    {
+    //if ( algorithm=="std" || (algorithm=="stdorslimgb" && char(P)>0) ) //V1
+      if ( algorithm=="std" || (algorithm=="stdorslimgb") )              //V2
+      {
+        return (stdfglm(i,"std"));
+      }
+    //if(algorithm=="slimgb" || (algorithm=="stdorslimgb" && char(P)==0))//V1
+      if( algorithm=="slimgb" )                                          //V2
+      {
+        return (stdfglm(i,"slimgb"));
+      }
+    }
+    else
+    {
+    //if ( algorithm=="std" || (algorithm=="stdorslimgb" && char(P)>0) )//V1
+      if ( algorithm=="std" || (algorithm=="stdorslimgb" ) )            //V2
+      {
+        return (stdhilb(i,"std"));
+      }
+    //if(algorithm=="slimgb" || (algorithm=="stdorslimgb" && char(P)==0))//V1
+      if ( algorithm=="slimgb" )                                         //V2
+      {
+        return (stdhilb(i,"slimgb"));
+      }
+    }
+  }
+
+//------------ case where parameters are made to variables  ----------------
+//define a ring Phelp via par2varRing in which the parameters are variables
+
+  else
+  {
+    // reset options
+    option(none);
+    // turn on options prot, mem, redSB, intStrategy if previously set
+    if ( find(s_opt, "prot") )
+      { option(prot); }
+    if ( find(s_opt, "mem") )
+      { option(mem); }
+    if ( find(s_opt, "redSB") )
+      { option(redSB); }
+    if ( find(s_opt, "intStrategy") )
+      { option(intStrategy); }
+
+    //first clear denominators of parameters
+    if (npars_P > 0)
+    {
+      for( k=ncols(i); k>0; k-- )
+      { i[k]=cleardenom(i[k]); }
+    }
+
+    def Phelp = par2varRing(i)[1];   //minpoly is mapped with i
+    setring Phelp;
+    def i = Id(1);
+    //is_homog = homog(i);
+
+    //If parameters are converted to ring variables, they appear in an extra
+    //block. Therefore we use always hilb for this block ordering:
+    if ( conversion=="fglm" )
+    {
+      i = (stdfglm(i));       //only uesful for 1 parameter with minpoly
+    }
+    else
+    {
+    //if ( algorithm=="std" || (algorithm=="stdorslimgb" && char(P)>0) )//V1
+      if ( algorithm=="std" || (algorithm=="stdorslimgb" ))             //V2
+      {
+        i = stdhilb(i,"std");
+      }
+    //if(algorithm=="slimgb" || (algorithm=="stdorslimgb" && char(P)==0))//V1
+      if ( algorithm=="slimgb" )                                         //V2
+      {
+        i = stdhilb(i,"slimgb");
+      }
+    }
+  }
+
+//-------------------- go back to original ring ---------------------------
+//The main computation is done. However, the SB coming from a ring with
+//extra variables is in general too big. We simplify it before mapping it
+//to the basering.
+
+  if (p_opt) { "//simplification"; }
+
+  if (was_minpoly)
+  {
+    execute("ideal Minpoly = " + @Minpoly + ";");
+    attrib(Minpoly,"isSB",1);
+    i = simplify(NF(i,Minpoly),2);
+  }
+
+  def Li = lead(i);
+  setring P;
+  def Li = imap(Phelp,Li);
+  Li = simplify(Li,32);
+  intvec vi;
+  for (k=1; k<=ncols(Li); k++)
+  {
+    vi[k] = Li[k]==0;
+  }
+
+  setring Phelp;
+  for (k=1;  k<=size(i) ;k++)
+  {
+    if(vi[k]==1)
+    {
+      i[k]=0;
+    }
+  }
+  i = simplify(i,2);
+
+  setring P;
+  if (p_opt) { "//imap to original ring"; }
+  i = imap(Phelp,i);
+  kill Phelp;
+  i = simplify(i,34);
+
+  // clean-up time
+  option(set, opt);
+  if (find(s_opt, "redSB") > 0)
+  {
+    if (p_opt) { "//interreduction"; }
+    i=interred(i);
+  }
+  attrib(i, "isSB", 1);
+  return (i);
+}
+example
+{ "EXAMPLE: "; echo=2;
+  intvec opt = option(get);
+  option(prot);
+  ring r  = 0,(a,b,c,d),dp;
+  ideal i = a+b+c+d,ab+ad+bc+cd,abc+abd+acd+bcd,abcd-1;
+  groebner(i);
+
+  ring s  = 0,(a,b,c,d),lp;
+  ideal i = imap(r,i);
+  groebner(i,"hilb");
+
+  ring R  = (0,a),(b,c,d),lp;
+  minpoly = a2+1;
+  ideal i = a+b+c+d,ab+ad+bc+cd,abc+abd+acd+bcd,d2-c2b2;
+  groebner(i,"par2var","slimgb");
+
+  groebner(i,"fglm");          //computes a reduced standard basis
+
+  option(set,opt);
+}
+
+//////////////////////////////////////////////////////////////////////////
+
+proc res(list #)
+"@c we do texinfo here:
+ at cindex resolution, computation of
+ at table @code
+ at item @strong{Syntax:}
+ at code{res (} ideal_expression at code{,} int_expression @code{[,} any_expression @code{])}
+@*@code{res (} module_expression at code{,} int_expression @code{[,} any_expression @code{])}
+ at item @strong{Type:}
+resolution
+ at item @strong{Purpose:}
+computes a (possibly minimal) free resolution of an ideal or module using
+a heuristically chosen method.
+@* The second (int) argument (say @code{k}) specifies the length of
+the resolution. If it is not positive then @code{k} is assumed to be the
+number of variables of the basering.
+@* If a third argument is given, the returned resolution is minimized.
+
+Depending on the input, the returned resolution is computed using the
+following methods:
+ at table @asis
+ at item @strong{quotient rings:}
+ at code{nres} (classical method using syzygies) , see @ref{nres}.
+
+ at item @strong{homogeneous ideals and k=0:}
+ at code{lres} (La'Scala's method), see @ref{lres}.
+
+ at item @strong{not minimized resolution and (homogeneous input with k not 0, or local rings):}
+ at code{sres} (Schreyer's method), see @ref{sres}.
+
+ at item @strong{all other inputs:}
+ at code{mres} (classical method), see @ref{mres}.
+ at end table
+ at item @strong{Note:}
+Accessing single elements of a resolution may require some partial
+computations to be finished and may therefore take some time.
+ at end table
+ at c ref
+See also
+ at ref{betti};
+ at ref{ideal};
+ at ref{minres};
+ at ref{module};
+ at ref{mres};
+ at ref{nres};
+ at ref{lres};
+ at ref{hres};
+ at ref{sres};
+ at ref{resolution}.
+ at c ref
+"
+{
+   def P=basering;
+   if (size(#) < 2)
+   {
+     ERROR("res: need at least two arguments: ideal/module, int");
+   }
+
+   def m=#[1]; //the ideal or module
+   int i=#[2]; //the length of the resolution
+   if (i< 0) { i=0;}
+
+   string varstr_P = varstr(P);
+
+   int p_opt;
+   string s_opt = option();
+   // set p_opt, if option(prot) is set
+   if (find(s_opt, "prot"))
+   {
+     p_opt = 1;
+   }
+
+   if( (size(ideal(basering)) > 0) || (size(ringlist(P)) > 4) )
+   {
+     // the quick hack for qrings - seems to fit most needs
+     // (lres is not implemented for qrings, sres is not so efficient)
+     // || non-commutative, since only n/m-res are implemented for NC rings
+     if (p_opt) { "using nres";}
+     return(nres(m,i));
+   }
+
+/* if( attrib(basering, "global") == 1 ) // preparations for s_res usage. in testing!
+   {
+     if (p_opt) { "using s_res";}
+     if( !defined(s_res) )
+     {
+       def @@v=option(get); option(noloadLib); option(noloadProc); LIB( "schreyer.lib" ); // for s_res
+       option(set, @@v); kill @@v;
+     }
+     resolution re = s_res(m,i);
+     if(size(#)>2)
+     {
+       re=minres(re);
+     }
+     return(re);
+   }*/
+
+   if(homog(m)==1)
+   {
+      resolution re;
+      if (((i==0) or (i>=nvars(basering))) && (typeof(m) != "module") && (nvars(basering)>1))
+      {
+        //LaScala for the homogeneous case and i == 0
+        if (p_opt) { "using lres";}
+        re=lres(m,i);
+        if(size(#)>2)
+        {
+           re=minres(re);
+        }
+      }
+      else
+      {
+        if(size(#)>2)
+        {
+          if (p_opt) { "using mres";}
+          re=mres(m,i);
+        }
+        else
+        {
+          if (p_opt) { "using sres";}
+          re=sres(std(m),i);
+        }
+      }
+      return(re);
+   }
+
+   //mres for the global non homogeneous case
+   if(find(ordstr(P),"s")==0)
+   {
+      string ri= "ring Phelp ="
+                  +string(char(P))+",("+varstr_P+"),(dp,C);";
+      ri = ri + "minpoly = "+string(minpoly) + ";";
+      execute(ri);
+      def m=imap(P,m);
+      if (p_opt) { "using mres in another ring";}
+      list re=mres(m,i);
+      setring P;
+      resolution result=imap(Phelp,re);
+      if (size(#) > 2) {result = minres(result);}
+      return(result);
+   }
+
+   //sres for the local case and not minimal resolution
+   if(size(#)<=2)
+   {
+      string ri= "ring Phelp ="
+                  +string(char(P))+",("+varstr_P+"),(ls,c);";
+      ri = ri + "minpoly = "+string(minpoly) + ";";
+      execute(ri);
+      def m=imap(P,m);
+      m=std(m);
+      if (p_opt) { "using sres in another ring";}
+      list re=sres(m,i);
+      setring P;
+      resolution result=imap(Phelp,re);
+      return(result);
+   }
+
+   //mres for the local case and minimal resolution
+   string ri= "ring Phelp ="
+                  +string(char(P))+",("+varstr_P+"),(ls,C);";
+   ri = ri + "minpoly = "+string(minpoly) + ";";
+   execute(ri);
+   def m=imap(P,m);
+    if (p_opt) { "using mres in another ring";}
+   list re=mres(m,i);
+   setring P;
+   resolution result=imap(Phelp,re);
+   result = minres(result);
+   return(result);
+}
+example
+{"EXAMPLE:"; echo = 2;
+  ring r=0,(x,y,z),dp;
+  ideal i=xz,yz,x3-y3;
+  def l=res(i,0); // homogeneous ideal: uses lres
+  l;
+  print(betti(l), "betti"); // input to betti may be of type resolution
+  l[2];         // element access may take some time
+  i=i,x+1;
+  l=res(i,0);   // inhomogeneous ideal: uses mres
+  l;
+  ring rs=0,(x,y,z),ds;
+  ideal i=imap(r,i);
+  def l=res(i,0); // local ring not minimized: uses sres
+  l;
+  res(i,0,0);     // local ring and minimized: uses mres
+}
+/////////////////////////////////////////////////////////////////////////
+
+proc quot (def m1,def m2,list #)
+"SYNTAX: @code{quot (} module_expression at code{,} module_expression @code{)}
+         @*@code{quot (} module_expression at code{,} module_expression at code{,}
+            int_expression @code{)}
+         @*@code{quot (} ideal_expression at code{,} ideal_expression @code{)}
+         @*@code{quot (} ideal_expression at code{,} ideal_expression at code{,}
+            int_expression @code{)}
+TYPE:    ideal
+SYNTAX:  @code{quot (} module_expression at code{,} ideal_expression @code{)}
+TYPE:    module
+PURPOSE: computes the quotient of the 1st and the 2nd argument.
+         If a 3rd argument @code{n} is given the @code{n}-th method is used
+         (@code{n}=1...5).
+SEE ALSO: quotient
+EXAMPLE: example quot; shows an example"
+{
+  if (((typeof(m1)!="ideal") and (typeof(m1)!="module"))
+     or ((typeof(m2)!="ideal") and (typeof(m2)!="module")))
+  {
+    "USAGE:   quot(m1, m2[, n]); m1, m2 two submodules of k^s,";
+    "         n (optional) integer (1<= n <=5)";
+    "RETURN:  the quotient of m1 and m2";
+    "EXAMPLE: example quot; shows an example";
+    return();
+  }
+  if (typeof(m1)!=typeof(m2))
+  {
+    return(quotient(m1,m2));
+  }
+  if (size(#)>0)
+  {
+    if (typeof(#[1])=="int" )
+    {
+      return(quot1(m1,m2,#[1]));
+    }
+  }
+  else
+  {
+    return(quot1(m1,m2,2));
+  }
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring r=181,(x,y,z),(c,ls);
+  ideal id1=maxideal(4);
+  ideal id2=x2+xyz,y2-z3y,z3+y5xz;
+  option(prot);
+  ideal id3=quotient(id1,id2);
+  id3;
+  ideal id4=quot(id1,id2,1);
+  id4;
+  ideal id5=quot(id1,id2,2);
+  id5;
+}
+
+static proc quot1 (module m1, module m2,int n)
+"USAGE:   quot1(m1, m2, n); m1, m2 two submodules of k^s,
+         n integer (1<= n <=5)
+RETURN:  the quotient of m1 and m2
+EXAMPLE: example quot1; shows an example"
+{
+  if (n==1)
+  {
+    return(quotient1(m1,m2));
+  }
+  else
+  {
+    if (n==2)
+    {
+      return(quotient2(m1,m2));
+    }
+    else
+    {
+      if (n==3)
+      {
+        return(quotient3(m1,m2));
+      }
+      else
+      {
+        if (n==4)
+        {
+          return(quotient4(m1,m2));
+        }
+        else
+        {
+          if (n==5)
+          {
+            return(quotient5(m1,m2));
+          }
+          else
+          {
+            return(quotient(m1,m2));
+          }
+        }
+      }
+    }
+  }
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring r=181,(x,y,z),(c,ls);
+  ideal id1=maxideal(4);
+  ideal id2=x2+xyz,y2-z3y,z3+y5xz;
+  option(prot);
+  ideal id6=quotient(id1,id2);
+  id6;
+  ideal id7=quot1(id1,id2,1);
+  id7;
+  ideal id8=quot1(id1,id2,2);
+  id8;
+}
+
+static proc quotient0(module a,module b)
+{
+  module mm=b+a;
+  resolution rs=lres(mm,0);
+  list I=list(rs);
+  matrix M=I[2];
+  matrix A[1][nrows(M)]=M[1..nrows(M),1];
+  ideal i=A;
+  return (i);
+}
+proc quotient1(module a,module b)  //17sec
+"USAGE:   quotient1(m1, m2); m1, m2 two submodules of k^s,
+RETURN:  the quotient of m1 and m2"
+{
+  int i;
+  a=std(a);
+  module dummy;
+  module B=NF(b,a)+dummy;
+  ideal re=quotient(a,module(B[1]));
+  for(i=2;i<=ncols(B);i++)
+  {
+     re=intersect1(re,quotient(a,module(B[i])));
+  }
+  return(re);
+}
+proc quotient2(module a,module b)    //13sec
+"USAGE:   quotient2(m1, m2); m1, m2 two submodules of k^s,
+RETURN:  the quotient of m1 and m2"
+{
+  a=std(a);
+  module dummy;
+  module bb=NF(b,a)+dummy;
+  int i=ncols(bb);
+  ideal re=quotient(a,module(bb[i]));
+  bb[i]=0;
+  module temp;
+  module temp1;
+  module bbb;
+  int mx;
+  i=i-1;
+  while (1)
+  {
+    if (i==0) break;
+    temp = a+bb*re;
+    temp1 = lead(interred(temp));
+    mx=ncols(a);
+    if (ncols(temp1)>ncols(a))
+    {
+      mx=ncols(temp1);
+    }
+    temp1 = matrix(temp1,1,mx)-matrix(lead(a),1,mx);
+    temp1 = dummy+temp1;
+    if (deg(temp1[1])<0) break;
+    re=intersect1(re,quotient(a,module(bb[i])));
+    bb[i]=0;
+    i = i-1;
+  }
+  return(re);
+}
+proc quotient3(module a,module b)   //89sec
+"USAGE:   quotient3(m1, m2); m1, m2 two submodules of k^s,
+         only for global rings
+RETURN:  the quotient of m1 and m2"
+{
+  string s="ring @newr=("+charstr(basering)+
+           "),("+varstr(basering)+", at t, at w),dp;";
+  def @newP=basering;
+  execute(s);
+  module b=imap(@newP,b);
+  module a=imap(@newP,a);
+  int i;
+  int j=ncols(b);
+  vector @b;
+  for(i=1;i<=j;i++)
+  {
+     @b=@b+ at t^(i-1)*@w^(j-i+1)*b[i];
+  }
+  ideal re=quotient(a,module(@b));
+  setring @newP;
+  ideal re=imap(@newr,re);
+  return(re);
+}
+proc quotient5(module a,module b)   //89sec
+"USAGE:   quotient5(m1, m2); m1, m2 two submodules of k^s,
+         only for global rings
+RETURN:  the quotient of m1 and m2"
+{
+  string s="ring @newr=("+charstr(basering)+
+           "),("+varstr(basering)+", at t),dp;";
+  def @newP=basering;
+  execute(s);
+  module b=imap(@newP,b);
+  module a=imap(@newP,a);
+  int i;
+  int j=ncols(b);
+  vector @b;
+  for(i=1;i<=j;i++)
+  {
+     @b=@b+ at t^(i-1)*b[i];
+  }
+  @b=homog(@b, at w);
+  ideal re=quotient(a,module(@b));
+  setring @newP;
+  ideal re=imap(@newr,re);
+  return(re);
+}
+proc quotient4(module a,module b)   //95sec
+"USAGE:   quotient4(m1, m2); m1, m2 two submodules of k^s,
+         only for global rings
+RETURN:  the quotient of m1 and m2"
+{
+  string s="ring @newr=("+charstr(basering)+
+           "),("+varstr(basering)+", at t),dp;";
+  def @newP=basering;
+  execute(s);
+  module b=imap(@newP,b);
+  module a=imap(@newP,a);
+  int i;
+  vector @b=b[1];
+  for(i=2;i<=ncols(b);i++)
+  {
+     @b=@b+ at t^(i-1)*b[i];
+  }
+  matrix sy=modulo(@b,a);
+  ideal re=sy;
+  setring @newP;
+  ideal re=imap(@newr,re);
+  return(re);
+}
+static proc intersect1(ideal i,ideal j)
+{
+  def R=basering;
+  execute("ring gnir = ("+charstr(basering)+"),
+                       ("+varstr(basering)+", at t),(C,dp);");
+  ideal i=var(nvars(basering))*imap(R,i)+(var(nvars(basering))-1)*imap(R,j);
+  ideal j=eliminate(i,var(nvars(basering)));
+  setring R;
+  map phi=gnir,maxideal(1);
+  return(phi(j));
+}
+
+//////////////////////////////////////////////////////////////////
+///
+/// sprintf, fprintf printf
+///
+proc sprintf(string fmt, list #)
+"SYNTAX:  @code{sprintf (} string_expression @code{[,} any_expressions
+               @code{] )}
+RETURN:   string
+PURPOSE:  @code{sprintf(fmt,...);} performs output formatting. The first
+          argument is a format control string. Additional arguments may be
+          required, depending on the content of the control string. A series
+          of output characters is generated as directed by the control string;
+          these characters are returned as a string. @*
+          The control string @code{fmt} is simply text to be copied,
+          except that the string may contain conversion specifications.@*
+          Type @code{help print;} for a listing of valid conversion
+          specifications. As an addition to the conversions of @code{print},
+          the @code{%n} and @code{%2} conversion specification does not
+          consume an additional argument, but simply generates a newline
+          character.
+NOTE:     If one of the additional arguments is a list, then it should be
+          wrapped in an additional @code{list()} command, since passing a list
+          as an argument flattens the list by one level.
+SEE ALSO: fprintf, printf, print, string
+EXAMPLE : example sprintf; shows an example
+"
+{
+  int sfmt = size(fmt);
+  if (sfmt  <= 1)
+  {
+    return (fmt);
+  }
+  int next, l, nnext;
+  string ret;
+  list formats = "%l", "%s", "%2l", "%2s", "%t", "%;", "%p", "%b", "%n", "%2";
+  while (1)
+  {
+    if (size(#) <= 0)
+    {
+      return (ret + fmt);
+    }
+    nnext = 0;
+    while (nnext < sfmt)
+    {
+      nnext = find(fmt, "%", nnext + 1);
+      if (nnext == 0)
+      {
+        next = 0;
+        break;
+      }
+      l = 1;
+      while (l <= size(formats))
+      {
+        next = find(fmt, formats[l], nnext);
+        if (next == nnext) break;
+        l++;
+      }
+      if (next == nnext) break;
+    }
+    if (next == 0)
+    {
+      return (ret + fmt);
+    }
+    if (formats[l] != "%2" && formats[l] != "%n")
+    {
+      ret = ret + fmt[1, next - 1] + print(#[1], formats[l]);
+      # = delete(#, 1);
+    }
+    else
+    {
+      ret = ret + fmt[1, next - 1] + print("", "%2s");
+    }
+    if (size(fmt) <= (next + size(formats[l]) - 1))
+    {
+      return (ret);
+    }
+    fmt = fmt[next + size(formats[l]), size(fmt)-next-size(formats[l]) + 1];
+  }
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring r=0,(x,y,z),dp;
+  module m=[1,y],[0,x+z];
+  intmat M=betti(mres(m,0));
+  list l = r, m, M;
+  string s = sprintf("s:%s,%n l:%l", 1, 2); s;
+  s = sprintf("s:%n%s", l); s;
+  s = sprintf("s:%2%s", list(l)); s;
+  s = sprintf("2l:%n%2l", list(l)); s;
+  s = sprintf("%p", list(l)); s;
+  s = sprintf("%;", list(l)); s;
+  s = sprintf("%b", M); s;
+}
+
+proc printf(string fmt, list #)
+"SYNTAX:  @code{printf (} string_expression @code{[,} any_expressions at code{] )}
+RETURN:   none
+PURPOSE:  @code{printf(fmt,...);} performs output formatting. The first
+          argument is a format control string. Additional arguments may be
+          required, depending on the content of the control string. A series
+          of output characters is generated as directed by the control string;
+          these characters are displayed (i.e., printed to standard out). @*
+          The control string @code{fmt} is simply text to be copied, except
+          that the string may contain conversion specifications. @*
+          Type @code{help print;} for a listing of valid conversion
+          specifications. As an addition to the conversions of @code{print},
+          the @code{%n} and @code{%2} conversion specification does not
+          consume an additional argument, but simply generates a newline
+          character.
+NOTE:     If one of the additional arguments is a list, then it should be
+          enclosed once more into a @code{list()} command, since passing a
+          list as an argument flattens the list by one level.
+SEE ALSO: sprintf, fprintf, print, string
+EXAMPLE : example printf; shows an example
+"
+{
+  write("", sprintf(fmt, #));
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring r=0,(x,y,z),dp;
+  module m=[1,y],[0,x+z];
+  intmat M=betti(mres(m,0));
+  list l=r,m,matrix(M);
+  printf("s:%s,l:%l",1,2);
+  printf("s:%s",l);
+  printf("s:%s",list(l));
+  printf("2l:%2l",list(l));
+  printf("%p",matrix(M));
+  printf("%;",matrix(M));
+  printf("%b",M);
+}
+
+
+proc fprintf(link l, string fmt, list #)
+"SYNTAX:  @code{fprintf (} link_expression at code{,} string_expression @code{[,}
+                any_expressions at code{] )}
+RETURN:   none
+PURPOSE:  @code{fprintf(l,fmt,...);} performs output formatting.
+          The second argument is a format control string. Additional
+          arguments may be required, depending on the content of the
+          control string. A series of output characters is generated as
+          directed by the control string; these characters are
+          written to the link l.
+          The control string @code{fmt} is simply text to be copied, except
+          that the string may contain conversion specifications.@*
+          Type @code{help print;} for a listing of valid conversion
+          specifications. As an addition to the conversions of @code{print},
+          the @code{%n} and @code{%2} conversion specification does not
+          consume an additional argument, but simply generates a newline
+          character.
+NOTE:     If one of the additional arguments is a list, then it should be
+          enclosed once more into a @code{list()} command, since passing
+          a list as an argument flattens the list by one level.
+SEE ALSO: sprintf, printf, print, string
+EXAMPLE : example fprintf; shows an example
+"
+{
+  write(l, sprintf(fmt, #));
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring r=0,(x,y,z),dp;
+  module m=[1,y],[0,x+z];
+  intmat M=betti(mres(m,0));
+  list l=r,m,M;
+  link li="";   // link to stdout
+  fprintf(li,"s:%s,l:%l",1,2);
+  fprintf(li,"s:%s",l);
+  fprintf(li,"s:%s",list(l));
+  fprintf(li,"2l:%2l",list(l));
+  fprintf(li,"%p",list(l));
+  fprintf(li,"%;",list(l));
+  fprintf(li,"%b",M);
+}
+
+//////////////////////////////////////////////////////////////////////////
+
+/*
+proc minres(list #)
+{
+  if (size(#) == 2)
+  {
+    if (typeof(#[1]) == "ideal" || typeof(#[1]) == "module")
+    {
+      if (typeof(#[2] == "int"))
+      {
+        return (res(#[1],#[2],1));
+      }
+    }
+  }
+
+  if (typeof(#[1]) == "resolution")
+  {
+    return minimizeres(#[1]);
+  }
+  else
+  {
+    return minimizeres(#);
+  }
+
+}
+*/
+///////////////////////////////////////////////////////////////////////////////
+
+proc weightKB(def stc, int dd, list wim)
+"SYNTAX: @code{weightKB (} module_expression at code{,} int_expression @code{,}
+            list_expression @code{)}@*
+         @code{weightKB (} ideal_expression at code{,} int_expression at code{,}
+            list_expression @code{)}
+RETURN:  the same as the input type of the first argument
+PURPOSE: If @code{I,d,wim} denotes the three arguments then weightKB
+         computes the weighted degree- @code{d} part of a vector space basis
+         (consisting of monomials) of the quotient ring, resp. of the
+         quotient module, modulo @code{I} w.r.t. weights given by @code{wim}
+         The information about the weights is given as a list of two intvec:
+            @code{wim[1]} weights for all variables (positive),
+            @code{wim[2]} weights for the module generators.
+NOTE:    This is a generalization of the command @code{kbase} with the same
+         first two arguments.
+SEE ALSO: kbase
+EXAMPLE: example weightKB; shows an example
+"
+{
+  if(checkww(wim)){ERROR("wrong weights";);}
+  kbclass();
+  wwtop=wim[1];
+  stc=interred(lead(stc));
+  if(typeof(stc)=="ideal")
+  {
+    stdtop=stc;
+    ideal out=widkbase(dd);
+    delkbclass();
+    out=simplify(out,2); // delete 0
+    return(out);
+  }
+  list mbase=kbprepare(stc);
+  module mout;
+  int im,ii;
+  if(size(wim)>1){mmtop=wim[2];}
+  else{mmtop=0;}
+  for(im=size(mbase);im>0;im--)
+  {
+    stdtop=mbase[im];
+    if(im>size(mmtop)){ii=dd;}
+    else{ii=dd-mmtop[im];}
+    mout=mout+widkbase(ii)*gen(im);
+  }
+  delkbclass();
+  mout=simplify(mout,2); // delete 0
+  return(mout);
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring R=0, (x,y), wp(1,2);
+  weightKB(ideal(0),3,intvec(1,2));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc datetime()
+"SYNTAX: @code{datetime ()}
+RETURN:  string
+PURPOSE: return the curent date and time as a string
+EXAMPLE: example datetime; shows an example
+"
+{
+  return(read("|: date"));
+}
+example
+{ "EXAMPLE:"; echo=2;
+  datetime();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// construct global values
+static proc kbclass()
+{
+  intvec wwtop,mmtop;
+  export (wwtop,mmtop);
+  ideal stdtop,kbtop;
+  export (stdtop,kbtop);
+}
+// delete global values
+static proc delkbclass()
+{
+  kill wwtop,mmtop;
+  kill stdtop,kbtop;
+}
+//  select parts of the modul
+static proc kbprepare(module mstc)
+{
+  list rr;
+  ideal kk;
+  int i1,i2;
+  mstc=transpose(mstc);
+  for(i1=ncols(mstc);i1>0;i1--)
+  {
+    kk=0;
+    for(i2=nrows(mstc[i1]);i2>0;i2--)
+    {
+      kk=kk+mstc[i1][i2];
+    }
+    rr[i1]=kk;
+  }
+  return(rr);
+}
+//  check for weights
+static proc checkww(list vv)
+{
+  if(typeof(vv[1])!="intvec"){return(1);}
+  intvec ww=vv[1];
+  int mv=nvars(basering);
+  if(size(ww)<mv){return(1);}
+  while(mv>0)
+  {
+    if(ww[mv]<=0){return(1);}
+    mv--;
+  }
+  if(size(vv)>1)
+  {
+    if(typeof(vv[2])!="intvec"){return(1);}
+  }
+  return(0);
+}
+///////////////////////////////////////////////////////
+// The "Caller" for ideals
+//    dd   - the degree of the result
+static proc widkbase(int dd)
+{
+  if((size(stdtop)==1)&&(deg(stdtop[1])==0)){return(0);}
+  if(dd<=0)
+  {
+    if(dd<0){return(0);}
+    else{return(1);}
+  }
+  int m1,m2;
+  m1=nvars(basering);
+  while(wwtop[m1]>dd)
+  {
+    m1--;
+    if(m1==0){return(0);}
+  }
+  attrib(stdtop,"isSB",1);
+  poly mo=1;
+  if(m1==1)
+  {
+    m2=dd div wwtop[1];
+    if((m2*wwtop[1])==dd)
+    {
+      mo=var(1)^m2;
+      if(reduce(mo,stdtop)==mo){return(mo);}
+      else{return(0);}
+    }
+  }
+  kbtop=0;
+  m2=dd;
+  weightmon(m1-1,m2,mo);
+  while(m2>=wwtop[m1])
+  {
+    m2=m2-wwtop[m1];
+    mo=var(m1)*mo;
+    if(m2==0)
+    {
+      if((mo!=0) and (reduce(mo,stdtop)==mo))
+      {
+        kbtop[ncols(kbtop)+1]=mo;
+        return(kbtop);
+      }
+    }
+    weightmon(m1-1,m2,mo);
+  }
+  return(kbtop);
+}
+/////////////////////////////////////////////////////////
+// the recursive procedure
+//    va     - number of the variable
+//    drest  - rest of the degree
+//    mm     - the candidate
+static proc weightmon(int va, int drest, poly mm)
+{
+  while(wwtop[va]>drest)
+  {
+    va--;
+    if(va==0){return();}
+  }
+  int m2;
+  if(va==1)
+  {
+    m2=drest div wwtop[1];
+    if((m2*wwtop[1])==drest)
+    {
+      mm=var(1)^m2*mm;
+      if ((mm!=0) and (reduce(mm,stdtop)==mm))
+      {
+        kbtop[ncols(kbtop)+1]=mm;
+      }
+    }
+    return();
+  }
+  m2=drest;
+  if ((mm!=0) and (reduce(mm,stdtop)==mm))
+  {
+    weightmon(va-1,m2,mm);
+  }
+  while(m2>=wwtop[va])
+  {
+    m2=m2-wwtop[va];
+    mm=var(va)*mm;
+    if(m2==0)
+    {
+      if ((mm!=0) and (reduce(mm,stdtop)==mm))
+      {
+        kbtop[ncols(kbtop)+1]=mm;
+        return();
+      }
+    }
+     if ((mm!=0) and (reduce(mm,stdtop)==mm))
+     {
+       weightmon(va-1,m2,mm);
+     }
+  }
+  return();
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring r=0,(x,y,z),dp;
+  ideal i = x6,y4,xyz;
+  intvec w = 2,3,6;
+  weightKB(i, 12, list(w));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+proc max(def i,def j)
+"SYNTAX: max (i, j)
+TYPE:    same as type of i resp. j
+PURPOSE: returns the maximum for any 2 arguments of a type
+         for which '>' is defined
+SEE ALSO: min
+EXAMPLE: example max; shows an example"
+{
+  if(i>j){return(i);}
+  return(j);
+}
+example
+{ "EXAMPLE:"; echo=2;
+  max(2,3);
+  max(4,3);
+}
+///////////////////////////////////////////////////////////////////////////////
+proc min(def i,def j)
+"SYNTAX: min (i, j)
+TYPE:    same as type of i resp. j
+PURPOSE: returns the minimum for any 2 arguments of a type
+         for which '>' is defined
+SEE ALSO: max
+EXAMPLE: example min; shows an example"
+{
+  if(i>j){return(j);}
+  return(i);
+}
+example
+{ "EXAMPLE:"; echo=2;
+  min(2,3);
+  min(4,3);
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+/*
+                                Versuche:
+///////////////////////////////////////////////////////////////////////////////
+proc downsizeSB (def I, list #)
+"USAGE:   downsizeSB(I [,l]); I ideal, l list of integers [default: l=0]
+RETURN:  intvec, say v, with v[j] either 1 or 0. We have v[j]=1 if
+         leadmonom(I[j]) is divisible by some leadmonom(I[k]) or if
+         leadmonom(i[j]) == leadmonom(i[k]) and l[j] >= l[k], with k!=j.
+PURPOSE: The procedure is applied in a situation where the standard basis
+         computation in the basering R is done via a conversion through an
+         overring Phelp with additional variables and where a direct
+         imap from Phelp to R is too expensive.
+         Assume Phelp is created by the procedure @code{par2varRing} or
+         @code{hilbRing} and IPhelp is a SB in Phelp [ with l[j]=
+         length(IPhelp(j)) or any other integer reflecting the complexity
+         of a IPhelp[j] ]. Let I = lead(IPhelp) mapped to R and compute
+         v = downsizeSB(imap(Phelp,I),l) in R. Then, if Ihelp[j] is deleted
+         for all j with v[j]=1, we can apply imap to the remaining generators
+         of Ihelp and still get SB in R  (in general not minimal).
+EXAMPLE: example downsizeSB; shows an example"
+{
+   int k,j;
+   intvec v,l;
+   poly M,N,W;
+   int c=size(I);
+   if( size(#) != 0 )
+   {
+     if ( typeof(#[1]) == "intvec" )
+     {
+       l = #[1];
+     }
+     else
+     {
+        ERROR("// 2nd argument must be an intvec");
+     }
+   }
+
+   l[c+1]=0;
+   v[c]=0;
+
+   j=0;
+   while(j<c-1)
+   {
+     j++;
+     M = leadmonom(I[j]);
+     if( M != 0 )
+     {
+        for( k=j+1; k<=c; k++ )
+        {
+          N = leadmonom(I[k]);
+          if( N != 0 )
+          {
+             if( (M==N) && (l[j]>l[k]) )
+             {
+               I[j]=0;
+               v[j]=1;
+               break;
+             }
+             if( (M==N) && (l[j]<=l[k]) || N/M != 0 )
+             {
+               I[k]=0;
+               v[k]=1;
+             }
+          }
+        }
+      }
+   }
+   return(v);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring  r = 0,(x,y,z,t),(dp(3),dp);
+   ideal i = x+y+z+t,xy+yz+xt+zt,xyz+xyt+xzt+yzt,xyzt-t4;
+   ideal Id = std(i);
+   ideal I = lead(Id);  I;
+   ring S = (0,t),(x,y,z),dp;
+   downsizeSB(imap(r,I));
+   //Id[5] can be deleted, we still have a SB of i in the ring S
+
+   ring R = (0,x),(y,z,u),lp;
+   ideal i = x+y+z+u,xy+xu+yz+zu,xyz+xyu+xzu+yzu,xyzu-1;
+   def Phelp = par2varRing()[1];
+   setring Phelp;
+   ideal IPhelp = std(imap(R,i));
+   ideal I = lead(IPhelp);
+   setring R;
+   ideal I = imap(Phelp,I); I;
+   intvec v = downsizeSB(I); v;
+}
+///////////////////////////////////////////////////////////////////////////
+// PROBLEM: Die Prozedur funktioniert nur fuer Ringe die global bekannt
+//          sind, also interaktiv, aber nicht aus einer Prozedur.
+//          Z.B. funktioniert example imapDownsize; nicht
+
+proc imapDownsize (string R, string I)
+"SYNTAX: @code{imapDownsize (} string @code{,} string @code{)} *@
+         First string must be the string of the name of a ring, second
+         string must be the string of the name of an object in the ring.
+TYPE:    same type as the object with name the second string
+PURPOSE: maps the object given by the second string to the basering.
+         If R resp. I are the first resp. second string, then
+         imapDownsize(R,I) is equivalent to simplify(imap(`R`,`I`),34).
+NOTE:    imapDownsize is usually faster than imap if `I` is large and if
+         simplify has a great effect, since the procedure maps only those
+         generators from `I` which are not killed by simplify( - ,34).
+         This is useful if `I` is a standard bases for a block ordering of
+         `R` and if some variables from the last block in `R` are mapped
+         to parameters. Then the returned result is a standard basis in
+         the basering.
+SEE ALSO: imap, fetch, map
+EXAMPLE: example imapDownsize; shows an example"
+{
+       def BR = basering;
+       int k;
+
+       setring `R`;
+       def @leadI@ = lead(`I`);
+       int s = ncols(@leadI@);
+       setring BR;
+       ideal @leadI@ = simplify(imap(`R`, at leadI@),32);
+       intvec vi;
+       for (k=1; k<=s; k++)
+       {
+         vi[k] = @leadI@[k]==0;
+       }
+       kill @leadI@;
+
+       setring `R`;
+       kill @leadI@;
+       for (k=1;  k<=s; k++)
+       {
+           if( vi[k]==1 )
+           {
+              `I`[k]=0;
+           }
+       }
+       `I` = simplify(`I`,2);
+
+       setring BR;
+       return(imap(`R`,`I`));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring  r = 0,(x,y,z,t),(dp(3),dp);
+   ideal i = x+y+z+t,xy+yz+xt+zt,xyz+xyt+xzt+yzt,xyzt-1;
+   i = std(i); i;
+
+   ring s = (0,t),(x,y,z),dp;
+   imapDownsize("r","i");     //i[5] is omitted since lead(i[2]) | lead(i[5])
+}
+///////////////////////////////////////////////////////////////////////////////
+//die folgende proc war fuer groebner mit fglm vorgesehen, ist aber zu teuer.
+//Um die projektive Dimension korrekt zu berechnen, muss man aber teuer
+//voerher ein SB bzgl. einer Gradordnung berechnen und dann homogenisieren.
+//Sonst koennen hoeherdimensionale Komponenten in Unendlich entstehen
+
+proc projInvariants(ideal i,list #)
+"SYNTAX: @code{projInvariants (} ideal_expression @code{)} @*
+         @code{projInvariants (} ideal_expression at code{,} list of string_expres          sions at code{)}
+TYPE:    list, say L, with L[1] and L[2] of type int and L[3] of type intvec
+PURPOSE: Computes the (projective) dimension (L[1]), degree (L[2]) and the
+         first Hilbert series (L[3], as intvec) of the homogenized ideal
+         in the ring given by the procedure @code{hilbRing} with global
+         ordering dp (resp. wp if the variables have weights >1)
+         If an argument of type string @code{\"std\"} resp. @code{\"slimgb\"}
+         is given, the standard basis computatuion uses @code{std} or
+         @code{slimgb}, otherwise a heuristically chosen method (default)
+NOTE:    Homogenized means weighted homogenized with respect to the weights
+         w[i] of the variables var(i) of the basering. The returned dimension,
+         degree and Hilbertseries are the respective invariants of the
+         projective variety defined by the homogenized ideal. The dimension
+         is equal to the (affine) dimension of the ideal in the basering
+         (degree and Hilbert series make only sense for homogeneous ideals).
+SEE ALSO: dim, dmult, hilb
+KEYWORDS: dimension, degree, Hilbert function
+EXAMPLE: example projInvariants;  shows an example"
+{
+  def P = basering;
+  int p_opt;
+  string s_opt = option();
+  if (find(option(), "prot"))  { p_opt = 1; }
+
+//---------------- check method and clear denomintors --------------------
+  int k;
+  string method;
+  for (k=1; k<=size(#); k++)
+  {
+     if (typeof(#[k]) == "string")
+     {
+       method = method + "," + #[k];
+     }
+  }
+
+  if (npars(P) > 0)             //clear denominators of parameters
+  {
+    for( k=ncols(i); k>0; k-- )
+    {
+       i[k]=cleardenom(i[k]);
+    }
+  }
+
+//------------------------ change to hilbRing ----------------------------
+     list hiRi = hilbRing(i);
+     intvec W = hiRi[2];
+     def Philb = hiRi[1];      //note: Philb is no qring and the predefined
+     setring Philb;            //ideal Id(1) in Philb is homogeneous
+     int di, de;               //for dimension, degree
+     intvec hi;                //for hilbert series
+
+//-------- compute Hilbert function of homogenized ideal in Philb ---------
+//Philb has only 1 block. There are three cases
+
+     string algorithm;       //possibilities: std, slimgb, stdorslimgb
+     //define algorithm:
+     if( find(method,"std") && !find(method,"slimgb") )
+     {
+        algorithm = "std";
+     }
+     if( find(method,"slimgb") && !find(method,"std") )
+     {
+         algorithm = "slimgb";
+     }
+     if( find(method,"std") && find(method,"slimgb") ||
+         (!find(method,"std") && !find(method,"slimgb")) )
+     {
+         algorithm = "stdorslimgb";
+     }
+
+     if ( algorithm=="std" || ( algorithm=="stdorslimgb" && char(P)>0 ) )
+     {
+        if (p_opt) {"std in ring " + string(Philb);}
+        Id(1) = std(Id(1));
+        di = dim(Id(1))-1;
+        de = mult(Id(1));
+        hi = hilb( Id(1),1,W );
+     }
+     if ( algorithm=="slimgb" || ( algorithm=="stdorslimgb" && char(P)==0 ) )
+     {
+        if (p_opt) {"slimgb in ring " + string(Philb);}
+        Id(1) = slimgb(Id(1));
+        di = dim( Id(1) );
+        if (di > -1)
+        {
+           di = di-1;
+        }
+        de = mult( Id(1) );
+        hi = hilb( Id(1),1,W );
+     }
+     kill Philb;
+     list L = di,de,hi;
+     return(L);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r = 32003,(x,y,z),lp;
+   ideal i = y2-xz,x2-z;
+   projInvariants(i);
+
+   ring R = (0),(x,y,z,u,v),lp;
+   //minpoly = x2+1;
+   ideal i = x2+1,x2+y+z+u+v,xyzuv-1;
+   projInvariants(i);
+   qring S =std(x2+1);
+   ideal i = imap(R,i);
+   projInvariants(i);
+}
+
+*/
+///////////////////////////////////////////////////////////////////////////////
+//                           EXAMPLES
+///////////////////////////////////////////////////////////////////////////////
+/*
+example stdfglm;
+example stdhilb;
+example groebner;
+example res;
+example sprintf;
+example fprintf;
+example printf;
+example weightKB;
+example qslimgb;
+example par2varRing;
+*/
+static proc mod_init()
+{
+  //int pagelength=24;
+  //exportto(Top,pagelength);
+}
diff --git a/Singular/LIB/stratify.lib b/Singular/LIB/stratify.lib
new file mode 100644
index 0000000..d6af356
--- /dev/null
+++ b/Singular/LIB/stratify.lib
@@ -0,0 +1,1070 @@
+//////////////////////////////////////////////////////////////////////////
+version="version stratify.lib 4.0.0.0 Jun_2013 "; // $Id: 8644d49e73e108d6cf5156f28bedb19dee44523a $
+category="Invariant theory";
+info="
+LIBRARY: stratify.lib   Algorithmic Stratification for Unipotent Group-Actions
+AUTHOR:  Anne Fruehbis-Krueger, anne at mathematik.uni-kl.de
+
+PROCEDURES:
+  prepMat(M,wr,ws,step);  list of submatrices corresp. to given filtration
+  stratify(M,wr,ws,step); algorithmic stratifcation (main procedure)
+";
+////////////////////////////////////////////////////////////////////////////
+// REQUIRED LIBRARIES
+////////////////////////////////////////////////////////////////////////////
+
+// first the ones written in Singular
+LIB "general.lib";
+LIB "primdec.lib";
+
+// then the ones written in C/C++
+
+////////////////////////////////////////////////////////////////////////////
+// PROCEDURES
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// For the kernel of the Kodaira-Spencer map in the case of hypersurface
+// singularities or CM codimension 2 singularities:
+// * step=min{ord(x_i)}
+// * wr corresponds to the weight vector of the d/dt_i (i.e. to -ord(t_i))
+//   (since the entries should be non-negative it may be necessary to
+//   multiply the whole vector by -1)
+// * ws corresponds to the weight vector of the delta_i
+// * M is the matrix delta_i(t_j)
+/////////////////////////////////////////////////////////////////////////////
+
+proc prepMat(matrix M, intvec wr, intvec ws, int step)
+"USAGE:   prepMat(M,wr,ws,step);
+         where M is a matrix, wr is an intvec of size ncols(M),
+         ws an intvec of size nrows(M) and step is an integer
+RETURN:  2 lists of submatrices corresponding to the filtrations
+         specified by wr and ws:
+         the first list corresponds to the list for the filtration
+         of AdA, i.e. the ranks of these matrices will be the r_i,
+         the second one to the list for the filtration of L, i.e.
+         the ranks of these matrices will be the s_i
+NOTE:    * the entries of the matrix M are M_ij=delta_i(x_j),
+         * wr is used to determine what subset of the set of all dx_i is
+           generating AdF^l(A):
+           if (k-1)*step <= wr[i] < k*step, then dx_i is in the set of
+           generators of AdF^l(A) for all l>=k and the i-th column
+           of M appears in each submatrix starting from the k-th
+         * ws is used to determine what subset of the set of all delta_i
+           is generating Z_l(L):
+           if (k-1)*step <= ws[i] < k*step, then delta_i is in the set
+           of generators of Z_l(A) for l < k and the i-th row of M
+           appears in each submatrix up to the (k-1)th
+         * the entries of wr and ws as well as step should be positive
+           integers
+EXAMPLE: example prepMat; shows an example"
+{
+//----------------------------------------------------------------------
+// Initialization and sanity checks
+//----------------------------------------------------------------------
+  int i,j;
+  if ((size(wr)!=ncols(M)) || (size(ws)!=nrows(M)))
+  {
+    "size mismatch: wr should have " + string(ncols(M)) + "entries";
+    "               ws should have " + string(nrows(M)) + "entries";
+    return("ERROR");
+  }
+//----------------------------------------------------------------------
+// Sorting the matrix to obtain nice structure
+//----------------------------------------------------------------------
+  list sortwr=sort(wr);
+  list sortws=sort(ws);
+  if(sortwr[1]!=wr)
+  {
+    matrix N[nrows(M)][ncols(M)];
+    for(i=1;i<=size(wr);i++)
+    {
+      N[1..nrows(M),i]=M[1..nrows(M),sortwr[2][i]];
+    }
+    wr=sortwr[1];
+    M=N;
+    kill N;
+  }
+  if(sortws[1]!=ws)
+  {
+    matrix N[nrows(M)][ncols(M)];
+    for(i=1;i<=size(ws);i++)
+    {
+      N[i,1..ncols(M)]=M[sortws[2][i],1..ncols(M)];
+    }
+    ws=sortws[1];
+    M=N;
+    kill N;
+  }
+//---------------------------------------------------------------------
+// Forming the submatrices
+//---------------------------------------------------------------------
+  list R,S;
+  i=1;
+  j=0;
+  while ((step*(i-1))<=wr[size(wr)])
+  {
+    while ((step*i)>wr[j+1])
+    {
+      j++;
+      if(j==size(wr)) break;
+    }
+    if(j!=0)
+    {
+      matrix N[nrows(M)][j]=M[1..nrows(M),1..j];
+    }
+    else
+    {
+      matrix N=matrix(0);
+    }
+    R[i]=N;
+    kill N;
+    i++;
+    if(j==size(wr)) break;
+  }
+  i=1;
+  j=0;
+  while ((step*i)<=ws[size(ws)])
+  {
+    while ((step*i)>ws[j+1])
+    {
+      j++;
+      if(j==size(ws)) break;
+    }
+    if(j==size(ws)) break;
+    if(j!=0)
+    {
+      matrix N[nrows(M)-j][ncols(M)]=M[j+1..nrows(M),1..ncols(M)];
+      S[i]=N;
+      kill N;
+    }
+    else
+    {
+      S[i]=M;
+    }
+    i++;
+  }
+  list ret=R,S;
+  return(ret);
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring r=0,(t(1..3)),dp;
+  matrix M[2][3]=0,t(1),3*t(2),0,0,t(1);
+  print(M);
+  intvec wr=1,3,5;
+  intvec ws=2,4;
+  int step=2;
+  prepMat(M,wr,ws,step);
+}
+/////////////////////////////////////////////////////////////////////////////
+static
+proc minorList (list matlist)
+"USAGE:   minorList(l);
+         where l is a list of matrices satisfying the condition that l[i]
+         is a submatrix of l[i+1]
+RETURN:  list of lists in which each entry of the returned list corresponds
+         to one of the matrices of the list l and is itself the list of
+         the minors (i.e. the 1st entry is the ideal generated by the
+         1-minors of the matrix etc.)
+EXAMPLE: example minorList(l); shows an example"
+{
+//---------------------------------------------------------------------------
+// Initialization and sanity checks
+//---------------------------------------------------------------------------
+  int maxminor;
+  int counter;
+  if(size(matlist)==0)
+  {
+    return(matlist);
+  }
+  for(int i=1;i<=size(matlist);i++)
+  {
+    if(((typeof(matlist[i]))!="matrix") && ((typeof(matlist[i]))!="intmat"))
+    {
+      "The list should only contain matrices or intmats";
+      return("ERROR");
+    }
+  }
+  list ret,templist;
+  int j;
+  int k=0;
+  ideal minid;
+//---------------------------------------------------------------------------
+// find the maximal size of the minors and compute all possible minors,
+// and put a minimal system of generators into the list that will be returned
+//---------------------------------------------------------------------------
+  for(i=1;i<=size(matlist);i++)
+  {
+    if (nrows(matlist[i]) < ncols(matlist[i]))
+    {
+      maxminor=nrows(matlist[i]);
+    }
+    else
+    {
+      maxminor=ncols(matlist[i]);
+    }
+    if (maxminor < 1)
+    {
+      "The matrices should be of size at least 1 x 1";
+      return("ERROR");
+    }
+    kill templist;
+    list templist;
+    for(j=1;j<=maxminor;j++)
+    {
+      minid=minor(matlist[i],j);
+      if(size(minid)>0)
+      {
+        if (defined(watchdog_interrupt))
+        {
+          kill watchdog_interrupt;
+        }
+        string watchstring="radical(ideal(";
+        for(counter=1;counter <size(minid);counter++)
+        {
+          watchstring=watchstring+"eval("+string(minid[counter])+"),";
+        }
+        watchstring=watchstring+"eval("+string(minid[size(minid)])+")))";
+        def watchtempid=watchdog(180,watchstring);
+        kill watchstring;
+        if ((defined(watchdog_interrupt)) || (typeof(watchtempid)=="string"))
+        {
+          templist[j-k]=mstd(minid)[2];
+        }
+        else
+        {
+          templist[j-k]=mstd(watchtempid)[2];
+        }
+        kill watchtempid;
+      }
+      else
+      {
+        k++;
+      }
+    }
+    k=0;
+    ret[i]=templist;
+  }
+  return(ret);
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring r=0,(t(1..3)),dp;
+  matrix M[2][3]=0,t(1),3*t(2),0,0,t(1);
+  intvec wr=1,3,5;
+  intvec ws=2,4;
+  int step=2;
+  list l=prepMat(M,wr,ws,step);
+  l[1];
+  minorList(l[1]);
+}
+/////////////////////////////////////////////////////////////////////////////
+static
+proc strataList(list Minors, list d, ideal V, int r, int nl)
+"USAGE:   strataList(Minors,d,V,r,nl);
+         Minors: list of minors as returned by minorRadList
+         d:      list of polynomials
+                 the open set that we are dealing with is D(d[1])
+                 d[2..size(d)]=list of the factors of d
+         V:      ideal
+                 the closed set we are dealing with is V(V)
+         r:      offset of the rank
+         nl:     nesting level of the recursion
+RETURN:  list of lists, each entry of the big list corresponds to one
+         locally closed set and has the following entries:
+         1) intvec giving the corresponding r- resp. s-vector
+         2) ideal determining the closed set (cf. 3rd parameter V)
+         3) list of polynomials determining the open set (cf. 2nd
+            parameter d)
+NOTE:    * sensible default values are
+           d[1]=1; (list of length 1)
+           V=ideal(0);
+           r=0;
+           nl=0;
+           these parameters are only important in the recursion
+           (if you know what you are doing, you are free to set d, V
+           and r, but setting nl to a value other than 0 may give
+           unexpected results)
+         * no sanity checks are performed, since the procedure is designed
+           for internal use only
+         * for use with the list of minors corresponding to the s-vectors,
+           the list of minors has to be specified from back to front
+EXAMPLE: example strataList; shows an example"
+{
+//---------------------------------------------------------------------------
+// * No sanity checks, since the procedure is static
+// * First reduce everything using the ideal V of which we know
+//   that the desired stratum lies in its zero locus
+// * Throw away zero ideals
+//---------------------------------------------------------------------------
+  poly D=d[1];
+  int i,j,k,ll;
+  int isZero,isEmpty;
+  intvec rv=r;
+  intvec delvec;
+  list l=mstd(V);
+  ideal sV=l[1];
+  ideal mV=l[2];
+  list Ml;
+  for(i=1;i<=size(Minors);i++)
+  {
+    list templist;
+    for(j=1;j<=size(Minors[i]);j++)
+    {
+      templist[j]=reduce(Minors[i][j],sV);
+    }
+    Ml[i]=templist;
+    kill templist;
+  }
+  for(i=1;i<=size(Ml);i++)
+  {
+    list templist;
+    isZero=1;
+    for(j=size(Ml[i]);j>=1;j--)
+    {
+      if(size(Ml[i][j])!=0)
+      {
+        templist[j]=Ml[i][j];
+        isZero=0;
+      }
+      else
+      {
+        if(isZero==0)
+        {
+          return("ERROR");
+        }
+      }
+    }
+    if(size(templist)!=0)
+    {
+      Ml[i]=templist;
+    }
+    else
+    {
+      rv=rv,r;
+      delvec=delvec,i;
+    }
+    kill templist;
+  }
+  if(size(delvec)>=2)
+  {
+    intvec dummydel=delvec[2..size(delvec)];
+    Ml=deleteSublist(dummydel,Ml);
+    kill dummydel;
+  }
+//---------------------------------------------------------------------------
+// We do not need to go on if Ml disappeared
+//---------------------------------------------------------------------------
+  if(size(Ml)==0)
+  {
+    list ret;
+    list templist;
+    templist[1]=rv;
+    templist[2]=mV;
+    templist[3]=d;
+    ret[1]=templist;
+    return(ret);
+  }
+//---------------------------------------------------------------------------
+// Check for minors which cannot vanish at all
+//---------------------------------------------------------------------------
+  def rt=basering;
+  ring ru=0,(U),dp;
+  def rtu=rt+ru;
+  setring rtu;
+  def tempMl;
+  def ML;
+  def D;
+  setring rt;
+  int Mlrank=0;
+  setring rtu;
+  tempMl=imap(rt,Ml);
+  ML=tempMl[1];
+  D=imap(rt,D);
+  while(Mlrank<size(ML))
+  {
+    if(reduce(1,std(ML[Mlrank+1]+poly((U*D)-1)))==0)
+    {
+      Mlrank++;
+    }
+    else
+    {
+      break;
+    }
+  }
+  setring rt;
+  if(Mlrank!=0)
+  {
+    kill delvec;
+    intvec delvec;
+    isEmpty=1;
+    for(i=1;i<=size(Ml);i++)
+    {
+      if(Mlrank<size(Ml[i]))
+      {
+        list templi2=Ml[i];
+        list templist=templi2[Mlrank+1..size(Ml[i])];
+        kill templi2;
+        Ml[i]=templist;
+        isEmpty=0;
+      }
+      else
+      {
+        if(isEmpty==0)
+        {
+          return("ERROR");
+        }
+        rv=rv,(r+Mlrank);
+        delvec=delvec,i;
+      }
+      if(defined(templist)>1)
+      {
+        kill templist;
+      }
+    }
+    if(size(delvec)>=2)
+    {
+      intvec dummydel=delvec[2..size(delvec)];
+      Ml=deleteSublist(dummydel,Ml);
+      kill dummydel;
+    }
+  }
+//---------------------------------------------------------------------------
+// We do not need to go on if Ml disappeared
+//---------------------------------------------------------------------------
+  if(size(Ml)==0)
+  {
+    list ret;
+    list templist;
+    templist[1]=intvec(rv);
+    templist[2]=mV;
+    templist[3]=d;
+    ret[1]=templist;
+    return(ret);
+  }
+//---------------------------------------------------------------------------
+// For each possible rank of Ml[1] and each element of Ml[1][rk]
+// call this procedure again
+//---------------------------------------------------------------------------
+  ideal Did;
+  ideal newV;
+  ideal tempid;
+  poly f;
+  list newd;
+  int newr;
+  list templist,retlist;
+  setring rtu;
+  ideal newV;
+  ideal Did;
+  def d;
+  poly f;
+  setring rt;
+  for(i=0;i<=size(Ml[1]);i++)
+  {
+// find the polynomials which are not allowed to vanish simulateously
+    if((i<size(Ml[1]))&&(i!=0))
+    {
+      Did=mstd(reduce(Ml[1][i],std(Ml[1][i+1])))[2];
+    }
+    else
+    {
+      if(i==0)
+      {
+        Did=0;
+      }
+      else
+      {
+        Did=mstd(Ml[1][i])[2];
+      }
+    }
+// initialize the rank
+    newr=r + Mlrank + i;
+// find the new ideal V
+    for(j=0;j<=size(Did);j++)
+    {
+      if((i!=0)&&(j==0))
+      {
+        j++;
+        continue;
+      }
+      if(i<size(Ml[1]))
+      {
+        newV=mV,Ml[1][i+1];
+      }
+      else
+      {
+        newV=mV;
+      }
+// check whether the intersection of V and the new D is empty
+      setring rtu;
+      newV=imap(rt,newV);
+      Did=imap(rt,Did);
+      D=imap(rt,D);
+      d=imap(rt,d);
+      if(j==0)
+      {
+        if(reduce(1,std(newV+poly(D*U-1)))==0)
+        {
+          j++;
+          setring rt;
+          continue;
+        }
+      }
+      if(i!=0)
+      {
+        if(reduce(1,std(newV+poly(Did[j]*D*U-1)))==0)
+        {
+          j++;
+          setring rt;
+          continue;
+        }
+        f=Did[j];
+        for(k=2;k<=size(d);k++)
+        {
+          while(((f/d[k])*d[k])==f)
+          {
+            f=f/d[k];
+          }
+          if(deg(f)==0) break;
+        }
+      }
+      setring rt;
+      f=imap(rtu,f);
+// i==0 ==> f==0 ==> deg(f)<=0
+// otherwise factorize f, if it does not take too long,
+// and add its factors, resp. f itself, to the list d
+      if(deg(f)>0)
+      {
+        f=cleardenom(f);
+        if (defined(watchdog_interrupt))
+        {
+          kill watchdog_interrupt;
+        }
+        def watchtempid=watchdog(180,"factorize(eval(" + string(f) + "),1)");
+        if (defined(watchdog_interrupt))
+        {
+          newd=d;
+          newd[size(d)+1]=f;
+          newd[1]=d[1]*f;
+        }
+        else
+        {
+          tempid=watchtempid;
+          templist=tempid[1..size(tempid)];
+          newd=d+templist;
+          f=newd[1]*f;
+          tempid=simplify(ideal(newd[2..size(newd)]),14);
+          templist=tempid[1..size(tempid)];
+          kill newd;
+          list newd=f;
+          newd=newd+templist;
+        }
+        kill watchtempid;
+      }
+      else
+      {
+        newd=d;
+      }
+// take the corresponding sublist of the list of minors
+      list Mltemp=delete(Ml,1);
+      for(k=1;k<=size(Mltemp);k++)
+      {
+        templist=Mltemp[k];
+        if(i<size(Mltemp[k]))
+        {
+          Mltemp[k]=list(templist[(i+1)..size(Mltemp[k])]);
+        }
+        else
+        {
+          kill templist;
+          list templist;
+          Mltemp[k]=templist;
+        }
+      }
+// recursion
+      templist=strataList(Mltemp,newd,newV,newr,(nl+1));
+      kill Mltemp;
+// build up the result list
+      if(size(templist)!=0)
+      {
+        k=1;
+        ll=1;
+        while(k<=size(templist))
+        {
+          if(size(templist[k])!=0)
+          {
+            retlist[size(retlist)+ll]=templist[k];
+            ll++;
+          }
+          k++;
+        }
+      }
+    }
+  }
+  kill delvec;
+  intvec delvec;
+// clean up of the result list
+  for(i=1;i<=size(retlist);i++)
+  {
+    if(typeof(retlist[i])=="none")
+    {
+      delvec=delvec,i;
+    }
+  }
+  if(size(delvec)>=2)
+  {
+    intvec dummydel=delvec[2..size(delvec)];
+    retlist=deleteSublist(dummydel,retlist);
+    kill dummydel;
+  }
+// set the intvec to the correct value
+  for(i=1;i<=size(retlist);i++)
+  {
+    if(nl!=0)
+    {
+      intvec tempiv=rv,retlist[i][1];
+      retlist[i][1]=tempiv;
+      kill tempiv;
+    }
+    else
+    {
+      if(size(rv)>1)
+      {
+        intvec tempiv=rv[2..size(rv)];
+        retlist[i][1]=tempiv;
+        kill tempiv;
+      }
+    }
+  }
+  return(retlist);
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring r=0,(t(1..3)),dp;
+  matrix M[2][3]=0,t(1),3*t(2),0,0,t(1);
+  intvec wr=1,3,5;
+  intvec ws=2,4;
+  int step=2;
+  list l=prepMat(M,wr,ws,step);
+  l[1];
+  list l2=minorRadList(l[1]);
+  list d=poly(1);
+  strataList(l2,d,ideal(0),0,0);
+}
+/////////////////////////////////////////////////////////////////////////////
+static
+proc cleanup(list stratlist)
+"USAGE:   cleanup(l);
+         where l is a list of lists in the format which is e.g. returned
+         by strataList
+RETURN:  list in which entries to the same integer vector have been
+         joined to one entry
+         the changed entries may be identified by checking whether its
+         3rd entry is an empty list, then all entries starting from the
+         4th one give the different possibilities for the open set
+NOTE:    use the procedure killdups first to kill entries which are
+         contained in other entries to the same integer vector
+         otherwise the result will be meaningless
+EXAMPLE: example cleanup; shows an example"
+{
+  int i,j;
+  list leer;
+  intvec delvec;
+  if(size(stratlist)==0)
+  {
+    return(stratlist);
+  }
+  list ivlist;
+// sort the list using the intvec as criterion
+  for(i=1;i<=size(stratlist);i++)
+  {
+    ivlist[i]=stratlist[i][1];
+  }
+  list sortlist=sort(ivlist);
+  list retlist;
+  for(i=1;i<=size(stratlist);i++)
+  {
+    retlist[i]=stratlist[sortlist[2][i]];
+  }
+  i=1;
+// find duplicate intvecs in the list
+  while(i<size(stratlist))
+  {
+    j=i+1;
+    while(retlist[i][1]==retlist[j][1])
+    {
+      retlist[i][3+j-i]=retlist[j][3];
+      delvec=delvec,j;
+      j++;
+      if(j>size(stratlist)) break;
+    }
+    if (j!=(i+1))
+    {
+      retlist[i][3+j-i]=retlist[i][3];
+      retlist[i][3]=leer;
+      i=j-1;
+// retlist[..][3] is empty if and only if there was more than one entry to this intvec
+    }
+    if(j>size(stratlist)) break;
+    i++;
+  }
+  if(size(delvec)>=2)
+  {
+    intvec dummydel=delvec[2..size(delvec)];
+    retlist=deleteSublist(dummydel,retlist);
+    kill dummydel;
+  }
+  return(retlist);
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring r=0,(t(1),t(2)),dp;
+  intvec iv=1;
+  list plist=t(1),t(1);
+  list l1=iv,ideal(0),plist;
+  plist=t(2),t(2);
+  list l2=iv,ideal(0),plist;
+  list l=l1,l2;
+  cleanup(l);
+}
+/////////////////////////////////////////////////////////////////////////////
+static
+proc joinRS(list Rlist,list Slist)
+"USAGE:   joinRS(Rlist,Slist);
+         where Rlist and Slist are lists in the format returned by
+         strataList
+RETURN:  one list in the format returned by stratalist in which the
+         integer vector is the concatenation of the corresponding vectors
+         from Rlist and Slist
+         (of course only non-empty locally closed sets are returned)
+NOTE:    since Slist is a list returned by strataList corresponding to the
+         s-vector, it corresponds to the list of minors read from back to
+         front
+EXAMPLE: no example available at the moment"
+{
+  int j,k;
+  list retlist;
+  list templist,templi2;
+  intvec tempiv;
+  ideal tempid;
+  ideal dlist;
+  poly D;
+  def rt=basering;
+  ring ru=0,(U),dp;
+  def rtu=rt+ru;
+  setring rtu;
+  def Rlist=imap(rt,Rlist);
+  def Slist=imap(rt,Slist);
+  setring rt;
+  for(int i=1;i<=size(Rlist);i++)
+  {
+    for(j=1;j<=size(Slist);j++)
+    {
+// skip empty sets
+      if(Rlist[i][1][size(Rlist[i][1])]<Slist[j][1][size(Slist[j][1])])
+      {
+        j++;
+        continue;
+      }
+      setring rtu;
+      if(reduce(1,std(Slist[j][2]+poly(((Rlist[i][3][1])*U)-1)))==0)
+      {
+        j++;
+        setring rt;
+        continue;
+      }
+      if(reduce(1,std(Rlist[i][2]+poly(((Slist[j][3][1])*U)-1)))==0)
+      {
+        j++;
+        setring rt;
+        continue;
+      }
+      setring rt;
+// join the intvecs and the ideals V
+      tempiv=Rlist[i][1],Slist[j][1];
+      kill templist;
+      list templist;
+      templist[1]=tempiv;
+      if(size(Rlist[i][2]+Slist[j][2])>0)
+      {
+        templist[2]=mstd(Rlist[i][2]+Slist[j][2])[2];
+      }
+      else
+      {
+        templist[2]=ideal(0);
+      }
+// test again whether we are talking about the empty set
+      setring rtu;
+      def templist=imap(rt,templist);
+      def tempid=templist[2];
+      if(reduce(1,std(tempid+poly(((Slist[j][3][1])*(Rlist[i][3][1])*U)-1)))==0)
+      {
+        kill templist;
+        kill tempid;
+        j++;
+        setring rt;
+        continue;
+      }
+      else
+      {
+        kill templist;
+        kill tempid;
+        setring rt;
+      }
+// join the lists d
+      if(size(Rlist[i][3])>1)
+      {
+        templi2=Rlist[i][3];
+        dlist=templi2[2..size(templi2)];
+      }
+      else
+      {
+        kill dlist;
+        ideal dlist;
+      }
+      if(size(Slist[j][3])>1)
+      {
+        templi2=Slist[j][3];
+        tempid=templi2[2..size(templi2)];
+      }
+      else
+      {
+        kill tempid;
+        ideal tempid;
+      }
+      dlist=dlist+tempid;
+      dlist=simplify(dlist,14);
+      D=1;
+      for(k=1;k<=size(dlist);k++)
+      {
+        D=D*dlist[k];
+      }
+      if(size(dlist)>0)
+      {
+        templi2=D,dlist[1..size(dlist)];
+      }
+      else
+      {
+        templi2=list(1);
+      }
+      templist[3]=templi2;
+      retlist[size(retlist)+1]=templist;
+    }
+  }
+  return(retlist);
+}
+////////////////////////////////////////////////////////////////////////////
+
+proc stratify(matrix M, intvec wr, intvec ws,int step)
+"USAGE:   stratify(M,wr,ws,step);
+         where M is a matrix, wr is an intvec of size ncols(M),
+         ws an intvec of size nrows(M) and step is an integer
+RETURN:  list of lists, each entry of the big list corresponds to one
+         locally closed set and has the following entries:
+         1) intvec giving the corresponding rs-vector
+         2) ideal determining the closed set
+         3) list d of polynomials determining the open set D(d[1])
+            empty list if there is more than one open set
+         4-n) lists of polynomials determining open sets which all lead
+            to the same rs-vector
+NOTE:    * ring ordering should be global, i.e. the ring should be a
+           polynomial ring
+         * the entries of the matrix M are M_ij=delta_i(x_j),
+         * wr is used to determine what subset of the set of all dx_i is
+           generating AdF^l(A):
+           if (k-1)*step < wr[i] <= k*step, then dx_i is in the set of
+           generators of AdF^l(A) for all l>=k
+         * ws is used to determine what subset of the set of all delta_i
+           is generating Z_l(L):
+           if (k-1)*step <= ws[i] < k*step, then delta_i is in the set
+           of generators of Z_l(A) for l < k
+         * the entries of wr and ws as well as step should be positive
+           integers
+         * the filtrations have to be known, no sanity checks concerning
+           the filtrations are performed !!!
+EXAMPLE: example stratify; shows an example"
+{
+//---------------------------------------------------------------------------
+// Initialization and sanity checks
+//---------------------------------------------------------------------------
+  int i,j;
+  list submat=prepMat(M,wr,ws,step);
+  if(defined(watchProgress))
+  {
+    "List of submatrices to consider:";
+    submat;
+  }
+  if(ncols(submat[1][size(submat[1])])==nrows(submat[1][size(submat[1])]))
+  {
+    int symm=1;
+    int nr=nrows(submat[1][size(submat[1])]);
+    for(i=1;i<=nr;i++)
+    {
+      for(j=1;j<=nr-i;j++)
+      {
+        if(submat[1][size(submat[1])][i,j]!=submat[1][size(submat[1])][nr-j+1,nr-i+1])
+        {
+          symm=0;
+          break;
+        }
+      }
+      if(symm==0) break;
+    }
+  }
+  if(defined(symm)>1)
+  {
+    if(symm==0)
+    {
+      kill symm;
+    }
+  }
+  list Rminors=minorList(submat[1]);
+  if(defined(watchProgress))
+  {
+    "minors corresponding to the r-vector:";
+    Rminors;
+  }
+  if(defined(symm)<2)
+  {
+    list Sminors=minorList(submat[2]);
+    if(defined(watchProgress))
+    {
+      "minors corresponding to the s-vector:";
+      Sminors;
+    }
+  }
+  if(size(Rminors[1])==0)
+  {
+    Rminors=delete(Rminors,1);
+  }
+//---------------------------------------------------------------------------
+// Start the recursion and cleanup afterwards
+//---------------------------------------------------------------------------
+  list leer=poly(1);
+  list Rlist=strataList(Rminors,leer,0,0,0);
+  if(defined(watchProgress))
+  {
+    "list of strata corresponding to r-vectors:";
+    Rlist;
+  }
+  Rlist=killdups(Rlist);
+  if(defined(watchProgress))
+  {
+    "previous list after killing duplicate entries:";
+    Rminors;
+  }
+  if(defined(symm)<2)
+  {
+// Sminors have the smallest entry as the last one
+// In order to use the same routines as for the Rminors
+// we handle the s-vector in inverse order
+    list Stemp;
+    for(i=1;i<=size(Sminors);i++)
+    {
+      Stemp[size(Sminors)-i+1]=Sminors[i];
+    }
+    list Slist=strataList(Stemp,leer,0,0,0);
+    if(defined(watchProgress))
+    {
+      "list of strata corresponding to s-vectors:";
+      Slist;
+    }
+//---------------------------------------------------------------------------
+// Join the Rlist and the Slist to obtain the stratification
+//---------------------------------------------------------------------------
+    Slist=killdups(Slist);
+    if(defined(watchProgress))
+    {
+      "previous list after killing duplicate entries:";
+      Slist;
+    }
+    list ret=joinRS(Rlist,Slist);
+    if(defined(watchProgress))
+    {
+      "list of strata corresponding to r- and s-vectors:";
+      ret;
+    }
+    ret=killdups(ret);
+    if(defined(watchProgress))
+    {
+      "previous list after killing duplicate entries:";
+      ret;
+    }
+    ret=cleanup(ret);
+  }
+  else
+  {
+    list ret=cleanup(Rlist);
+  }
+  return(ret);
+}
+example
+{ "EXAMPLE:"; echo=2;
+  ring r=0,(t(1..3)),dp;
+  matrix M[2][3]=0,t(1),3*t(2),0,0,t(1);
+  intvec wr=1,3,5;
+  intvec ws=2,4;
+  int step=2;
+  stratify(M,wr,ws,step);
+}
+/////////////////////////////////////////////////////////////////////////////
+static
+proc killdups(list l)
+"USAGE:   killdups(l);
+         where l is a list in the form returned by strataList
+RETURN:  list which is obtained from the previous list by leaving out
+         entries which have the same intvec as another entry in which
+         the locally closed set is contained
+EXAMPLE: no example available at the moment"
+{
+  int i=1;
+  int j,k,skip;
+  while(i<size(l))
+  {
+    intvec delvec;
+    for(j=i+1;j<=size(l);j++)
+    {
+// we do not need to check the V ideals, since the intvecs coincide
+      if(l[i][1]==l[j][1])
+      {
+        if((l[i][3][1]/l[j][3][1])*l[j][3][1]==l[i][3][1])
+        {
+
+          delvec=delvec,i;
+          break;
+        }
+        else
+        {
+          if((l[j][3][1]/l[i][3][1])*l[i][3][1]==l[j][3][1])
+          {
+            delvec=delvec,j;
+            j++;
+            continue;
+          }
+        }
+      }
+    }
+    if(size(delvec)>=2)
+    {
+      delvec=sort(delvec)[1];
+      intvec dummydel=delvec[2..size(delvec)];
+      l=deleteSublist(dummydel,l);
+      kill dummydel;
+    }
+    kill delvec;
+    i++;
+  }
+  list ret=l;
+  return(ret);
+}
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+
+
+
+
+
+
diff --git a/Singular/LIB/surf.lib b/Singular/LIB/surf.lib
new file mode 100644
index 0000000..0f66f0d
--- /dev/null
+++ b/Singular/LIB/surf.lib
@@ -0,0 +1,382 @@
+////////////////////////////////////////////////////////////////////////////
+version="version surf.lib 4.0.0.0 Jun_2013 "; // $Id: c09b8905bb502f3fa20374ed4ae2aa15feb9abde $
+category="Visualization";
+info="
+LIBRARY: surf.lib    Procedures for Graphics with Surf
+AUTHOR: Hans Schoenemann, Frank Seelisch
+
+NOTE:
+ @texinfo
+ Using this library requires the program @code{surf} to be installed.
+ You can download @code{surf} either from
+  @uref{http://sourceforge.net/projects/surf}
+  or from @uref{ftp://www.mathematik.uni-kl.de/pub/Math/Singular/utils/}.
+ The procedure surfer requires the program @code{surfer} to be installed.
+ You can download @code{surfer} from
+  @uref{http://www.imaginary2008.de/surfer.imaginary2008.de}
+ @*Under Windows, version 159 or newer of @code{surfer} is required.
+ @end texinfo
+
+SEE ALSO: surfex_lib
+
+PROCEDURES:
+ plot(I);    plots plane curves and surfaces
+ surfer(I);  plots surfaces interactivly
+";
+
+///////////////////////////////////////////////////////////////////////////////
+proc num_of_vars(ideal I)
+"USAGE: num_of_vars(ideal I)
+
+RETURN: an intvec containing one entry for each ring variable.
+each contains the sums of all degrees in this variable of all monomials
+occuring in the ideal.
+An entry is zero if and only if the corresponding variable does not occur in the ideal.
+"
+{
+  intvec v;
+  int i;
+  poly p;
+  for(i=ncols(I);i>0;i--)
+  {
+    p=I[i];
+    while(p!=0)
+    {
+      v=v+leadexp(p);
+      p=p-lead(p);
+    }
+  }
+  return(v);
+}
+example
+{
+  "EXAMPLE:"; echo = 2;
+  ring r = 0, (x,y,z),dp;
+  ideal j0 = x^2-x*y;
+  num_of_vars(j0);
+  ideal j1 = x^2-x*y-y;
+  num_of_vars(j1);
+  ideal j2 = x^2-x*y-y, x^3-2*y;
+  num_of_vars(j2);
+}
+
+proc plot(ideal I,list #)
+"USAGE:   plot(I);  I ideal or poly
+ASSUME: I defines a plane curve or a surface given by one equation
+RETURN: nothing
+NOTE: requires the external program `surf` to be installed,
+      to close the graphical interface just press `Q`
+EXAMPLE: example plot; shows an example
+"
+{
+  string l = "/tmp/surf" + string(system("pid"));
+  string err_mes; // string containing error messages
+  def base=basering;
+  intvec v=num_of_vars(I);
+  int i,j,n;
+  for(i=size(v);i>0;i--)
+  {
+    if (v[i]!=0) { n++; }
+  }
+  if (n==0 or n>3)
+  {
+    err_mes="Cannot plot equations with "+string(n)+" variables";
+    ERROR(err_mes);
+  }
+  ring r=0,(x,y,z),dp;
+  short=0;
+  map phi=base,0;
+  j=1;
+  for(i=1;i<=size(v);i++)
+  {
+    if (v[i]!=0)
+    {
+      phi[i]=var(j);
+      j++;
+      if(j==4) break;
+    }
+  }
+  ideal I=simplify(phi(I),2);
+  if (leadcoef(I[1]) <0) { I[1]=-I[1]; }
+  if (ncols(I)==1 and n<=2 and nvars(base)!=3) // curve
+  {
+    write(":w "+l,"clip=none;");
+      write(l, "width=500; height=500; set_size; do_background=yes;
+               background_red=255; background_green=255;
+               background_blue=255;");
+    write(l,
+    "root_finder=d_chain_bisection;epsilon=0.0000000001;iterations=20000;");
+    write(l, "curve_green=0; curve_blue=0; curve_width=1.5;");
+    if (size(#)>0)
+    {
+      write(l,#[1]);
+    }
+    write(l,"curve=",I[1],";");
+    write(l,"draw_curve;");
+  }
+  else
+  {
+    if (ncols(I)==1 and (n==3 or nvars(base)==3)) // surface
+    {
+      write(":w " + l,
+            "root_finder=d_chain_bisection;epsilon=0.0000000001;iterations=20000;");
+      write(l, "width=500; height=500; set_size; do_background=yes; background_red=255; background_green=255; background_blue=255;");
+      write(l, "rot_x=0.14; rot_y=-0.3;");
+      if (size(#) > 0)
+      {
+          write(l, #[1]);
+      }
+      write(l, "surface=",I[1],";");
+      write(l, "draw_surface;");
+    }
+    else
+    {
+      err_mes = "cannot plot " + string(ncols(I)) + " equations in "
+              + string(n) + " variables";
+      ERROR(err_mes);
+    }
+  }
+
+  string surf_call; i = 0;
+  if (isWindows())
+  {
+    string surferPath = getShellOutput("which surfer");
+    if (find(surferPath, "no surfer in") != 0)
+    { /* did not find surfer: either not installed or
+         not yet included in $PATH variable */
+      err_mes = "calling `surfer` failed" + newline
+      + " (Either the program Surfer is not installed," + newline
+      + "  or it has not yet been included in $PATH.)";
+      ERROR(err_mes);
+    }
+    else
+    {
+      surf_call = "((xwin -multiwindow -clipboard -silent-dup-error";
+      surf_call = surf_call + " >/dev/null 2>&1 &) && sleep 5 && (sinngularsurf ";
+      surf_call = surf_call + l + ">/dev/null 2>&1))";
+      surf_call = surf_call + "&& /bin/rm " + l;
+      "Press q to exit from `surf`.";
+        " (You may leave the XServer running for further" + newline
+      + "  invocations of `plot`.)";
+      i = system("sh", surf_call);
+      if (i != 0)
+      {
+        err_mes = "calling `surf` failed" + newline
+                + " (The shell returned the error code "
+                + string(i) + "." + newline
+                + "  Perhaps the XServer was not properly set up, so" + newline
+                + "  try your plot command again. If `plot` fails" + newline
+                + "  again, then make sure that the program Surfer" + newline
+                + "  is installed and included in your $PATH variable.)";
+        ERROR(err_mes);
+      }
+    }
+  }
+  else
+  {
+    surf_call = "singularsurf ";
+    surf_call = surf_call + l + " >/dev/null 2>&1";
+    "Close window to exit from `singularurf`.";
+
+    i = system("sh", surf_call);
+    if (i != 0)
+    {
+      err_mes = "calling `surf` failed" + newline
+              + " (The shell returned the error code "
+              + string(i) + ".";
+      ERROR(err_mes);
+    }
+  }
+  system("sh", "/bin/rm " + l);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  // ---------  plane curves ------------
+  ring rr0 = 0,(x1,x2),dp;
+
+  ideal I = x1^3 - x2^2;
+  plot(I);
+
+  ring rr1 = 0,(x,y,z),dp;
+  ideal I(1) = 2x2-1/2x3 +1-y+1;
+  plot(I(1));
+
+  //  ---- Singular Logo --------------
+  poly logo = ((x+3)^3 + 2*(x+3)^2 - y^2)*(x^3 - y^2)*((x-3)^3-2*(x-3)^2-y^2);
+  plot(logo);
+
+  // Steiner surface
+  ideal J(2) = x^2*y^2+x^2*z^2+y^2*z^2-17*x*y*z;
+  plot(J(2));
+
+  // --------------------
+  plot(x*(x2-y2)+z2);
+
+  // E7
+  plot(x^3-x*y^3+z^2);
+
+  // Whitney umbrella
+  plot(z^2-x^2*y);
+
+}
+
+proc surfer(ideal I)
+"USAGE:   surfer(f);  f poly
+ASSUME: f defines a surface given by one equation
+RETURN: nothing
+NOTE: requires the external program `surfer` to be installed,
+      to close the graphical interface just close the window of surfer
+EXAMPLE: example surfer; shows an example
+"
+{
+  string lForWindows = "surfer" + string(system("pid"));
+  string l = "./" + lForWindows;
+  string err_mes; // string containing error messages
+  def base=basering;
+  intvec v=num_of_vars(I);
+  int i,j,n;
+  for(i=size(v);i>0;i--)
+  {
+    if (v[i]!=0) { n++; }
+  }
+  if (n==0 or n>3)
+  {
+    err_mes="Cannot plot equations with "+string(n)+" variables";
+    ERROR(err_mes);
+  }
+  ring r=0,(x,y,z),dp;
+  short=0;
+  map phi=base,0;
+  j=1;
+  for(i=1;i<=size(v);i++)
+  {
+    if (v[i]!=0)
+    {
+      phi[i]=var(j);
+      j++;
+      if(j==4) break;
+    }
+  }
+  ideal I=simplify(phi(I),2);
+  if (leadcoef(I[1]) <0) { I[1]=-I[1]; }
+  if (ncols(I)==1 and (n==3 or nvars(base)==3)) // surface
+  {
+    write(":w " + l, "surface=" + string(I[1]) + ";");
+  }
+  else
+  {
+    err_mes = "cannot plot " + string(ncols(I)) + " equations in "
+            + string(n) + " variables";
+    ERROR(err_mes);
+  }
+
+  string surf_call; i = 0;
+  if (isWindows())
+  {
+    string surferPath = getShellOutput("which surfer");
+    if (find(surferPath, "no surfer in") != 0)
+    { /* did not find surfer: either not installed or
+         not yet included in $PATH variable */
+      err_mes = "calling `surfer` failed" + newline
+      + " (Either the program Surfer is not installed," + newline
+      + "  or it has not yet been included in $PATH.)";
+      ERROR(err_mes);
+    }
+    else
+    {
+      string singularPath = getShellOutput("pwd");
+      surferPath = windowsCorrection(surferPath);
+      surferPath = surferPath[1..size(surferPath)-size("/surfer")];
+      singularPath = windowsCorrection(singularPath);
+      link ll = "|: cygpath -w " + singularPath;
+      singularPath = "'\""+read(ll)+"\"'"; close(ll);
+      surf_call = "cygstart -w -d " + surferPath + " ";
+      surf_call = surf_call + surferPath + "/surfer ";
+      surf_call = surf_call + singularPath + "/" + lForWindows;
+      "Close window to exit from `surfer`.";
+      i = system("sh", surf_call);
+    }
+  }
+  else
+  {
+    surf_call = "surfer " + l + " >/dev/null 2>&1";
+    "Close window to exit from `surfer`.";
+    i = system("sh", surf_call);
+  }
+  system("sh", "/bin/rm " + l);
+
+  if (i != 0)
+  {
+    err_mes = "calling `surfer` failed" + newline
+              + " (The shell returned the error code "
+              + string(i) + ".";
+    ERROR(err_mes);
+  }
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  ring rr1 = 0,(x,y,z),dp;
+  // Steiner surface
+  ideal J(2) = x^2*y^2+x^2*z^2+y^2*z^2-17*x*y*z;
+  surfer(J(2));
+
+  // --------------------
+  surfer(x*(x2-y2)+z2);
+
+  // E7
+  surfer(x^3-x*y^3+z^2);
+
+  // Whitney umbrella
+  surfer(z^2-x^2*y);
+}
+
+static proc isWindows()
+"returns 1 if this SINGULAR instance runs under (some) Windows OS;
+0 otherwise"
+{
+  string s = system("uname");
+  for (int i = 1; i <= size(s)-2; i = i + 1)
+  {
+    if (s[i] == "W")
+    {
+      if (s[i+1] == "i")
+      {
+        if (s[i+2] == "n")
+        {
+          return (1);
+        }
+      }
+    }
+  }
+  return (0);
+}
+
+static proc getShellOutput(string shellCommand)
+"returns the console output when executing the given shellCommand"
+{
+   int s;
+   string tempFilename = "tmp" + string(system("pid"));
+   s = system("sh", shellCommand + " > " + tempFilename + " 2>&1");
+   string r1 = read(tempFilename);
+   s = size(r1) - 1;
+   string r2 = r1[1..s];
+   s = system("sh", "/bin/rm " + tempFilename);
+   return (r2);
+}
+
+static proc windowsCorrection(string windowsPath)
+"puts a backslash in front of each space and each special character
+and returns the resulting string"
+{
+  string s = ""; int i;
+  for (i = 1; i <= size(windowsPath); i++)
+  {
+    if (find(" ()", windowsPath[i]) != 0)
+    {
+      s = s + "\\";
+    }
+    s = s + windowsPath[i];
+  }
+  return (s);
+}
+///////////////////////////////////////////////////////////////////////////////
diff --git a/Singular/LIB/surfacesignature.lib b/Singular/LIB/surfacesignature.lib
new file mode 100644
index 0000000..271a991
--- /dev/null
+++ b/Singular/LIB/surfacesignature.lib
@@ -0,0 +1,522 @@
+////////////////////////////////////////////////////////////////////////////
+version="version surfacesignature.lib 4.0.0.0 Jun_2014 "; // $Id: 84ea5c010b4c61b8ac700adbb14699ec0903b0c6 $
+category="Singularities";
+info="
+LIBRARY:  surfacesignature.lib        signature of surface singularity
+
+AUTHORS:  Gerhard Pfister             pfister at mathematik.uni-kl.de
+@*        Muhammad Ahsan Banyamin     ahsanbanyamin at gmail.com
+@*        Stefan Steidel              steidel at mathematik.uni-kl.de
+
+OVERVIEW:
+
+  A library for computing the signature of irreducible surface singularity.
+  The signature of a surface singularity is defined in [3]. The algorithm we
+  use has been proposed in [9].
+  Let g in C[x,y] define an isolated curve singularity at 0 in C^2 and
+  f:=z^N+g(x,y). The zero-set V:=V(f) in C^3 of f has an isolated singularity
+  at 0. For a small e>0 let V_e:=V(f-e) in C^3 be the Milnor fibre of (V,0) and
+  s: H_2(V_e,R) x H_2(V_e,R) ---> R be the intersection form (cf. [1],[7]).
+  H_2(V_e,R) is an m-dimensional R-vector space, m the Milnor number of (V,0)
+  (cf. [1],[4],[5],[6]), and s is a symmetric bilinear form.
+  Let sigma(f) be the signature of s, called the signature of the surface
+  singularity (V,0). Formulaes to compute the signature are given by Nemethi
+  (cf. [8],[9]) and van Doorn, Steenbrink (cf. [2]).
+  We have implemented three approaches using Puiseux expansions, the resolution
+  of singularities resp. the spectral pairs of the singularity.
+
+REFERENCES:
+
+ [1] Arnold, V.I.; Gusein-Zade, S.M.; Varchenko, A.N.: Singularities of
+     Differentiable Mappings. Vol. 1,2, Birkh\"auser (1988).
+ [2] van Doorn, M.G.M.; Steenbrink, J.H.M.: A supplement to the monodromy
+     theorem. Abh. Math. Sem. Univ. Hamburg 59, 225-233 (1989).
+ [3] Durfee, A.H.: The Signature of Smoothings of Complex Surface
+     Singularities. Mathematische Annalen 232, 85-98 (1978).
+ [4] de Jong, T.; Pfister, G.: Local Analytic Geometry. Vieweg (2000).
+ [5] Kerner, D.; Nemethi, A.: The Milnor fibre signature is not semi-continous.
+     arXiv:0907.5252 (2009).
+ [6] Kulikov, V.S.: Mixed Hodge Structures and Singularities. Cambridge Tracts
+     in Mathematics 132, Cambridge University Press (1998).
+ [7] Nemethi, A.: The real Seifert form and the spectral pairs of isolated
+     hypersurface singularities. Compositio Mathematica 98, 23-41 (1995).
+ [8] Nemethi, A.: Dedekind sums and the signature of f(x,y)+z^N. Selecta
+     Mathematica, New series, Vol. 4, 361-376 (1998).
+ [9] Nemethi, A.: The Signature of f(x,y)+z^$. Proceedings of Real and Complex
+     Singularities (C.T.C. Wall's 60th birthday meeting, Liverpool (England),
+     August 1996), London Math. Soc. Lecture Notes Series 263, 131--149 (1999).
+
+PROCEDURES:
+ signatureBrieskorn(a1,a2,a3);  signature of singularity x^a1+y^a2+z^a3
+ signaturePuiseux(N,f);         signature of singularity z^N+f(x,y)=0, f irred.
+ signatureNemethi(N,f);         signature of singularity z^N+f(x,y)=0
+";
+
+LIB "hnoether.lib";
+LIB "alexpoly.lib";
+LIB "gmssing.lib";
+
+///////////////////////////////////////////////////////////////////////////////
+//------- sigma(z^N + f) in terms of Puiseux pairs of f for f irreducible -----
+
+static proc exponentSequence(poly f)
+//=== computes the sequence a_1,...,a_s of exponents as described in [Nemethi]
+//=== using the Puiseux pairs (m_1, n_1),...,(m_s, n_s) of f:
+//===  - a_1 = m_1,
+//===  - a_i = m_i - n_i * (m_[i-1] - n_[i-1] * a_[i-1]).
+//===
+//=== Return: list of two intvecs:
+//===         1st entry: A = (a_1,...,a_s)
+//===         2nd entry: N = (n_1,...,n_s)
+{
+   def R = basering;
+   ring S = 0,(x,y),dp;
+   poly f = fetch(R,f);
+   list puiseuxPairs = invariants(f);
+   setring R;
+
+   intvec M = puiseuxPairs[1][3];
+   intvec N = puiseuxPairs[1][4];
+
+   int i;
+   int a = M[1];
+   intvec A = a;
+   for(i = 2; i <= size(M); i++)
+   {
+      a = M[i] - N[i] * (M[i-1] - N[i-1] * a);
+      A[size(A)+1] = a;
+   }
+
+   return(list(A,N));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r = 0,(x,y),dp;
+   exponentSequence(y4+2x3y2+x6+x5y);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc signatureBrieskorn(int a1, int a2, int a3)
+"USAGE:  signatureBrieskorn(a1,a2,a3); a1,a2,a3 = integers
+RETURN:  signature of Brieskorn singularity x^a1+y^a2+z^a3
+EXAMPLE: example signatureBrieskorn; shows an example
+"
+{
+   int a_temp, t, k1, k2, k3, s_t, sigma;
+   number s;
+
+   if(a1 > a2) { a_temp = a1; a1 = a2; a2 = a_temp; }
+   if(a2 > a3) { a_temp = a2; a2 = a3; a3 = a_temp; }
+   if(a1 > a2) { a_temp = a1; a1 = a2; a2 = a_temp; }
+
+   for(t = 0; t <= 2; t++)
+   {
+      s_t = 0;
+      for(k1 = 1; k1 <= a1-1; k1++)
+      {
+         for(k2 = 1; k2 <= a2-1; k2++)
+         {
+            for(k3 = 1; k3 <= a3-1; k3++)
+            {
+               s = number(k1)/a1 + number(k2)/a2 + number(k3)/a3;
+               if(t < s)
+               {
+                  if(s < t+1)
+                  {
+                     s_t = s_t + 1;
+                  }
+                  else
+                  {
+                     break;
+                  }
+               }
+            }
+            if(k3 == 1) { break; }
+         }
+         if(k2 == 1) { break; }
+      }
+      sigma = sigma + (-1)^t * s_t;
+   }
+   return(sigma);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring R = 0,x,dp;
+   signatureBrieskorn(11,3,5);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc signaturePuiseux(int N, poly f)
+"USAGE:  signaturePuiseux(N,f); N = int, f = irreducible poly in 2 variables
+RETURN:  signature of surface singularity defined by z^N + f(x,y) = 0
+EXAMPLE: example signaturePuiseux; shows an example
+"
+{
+   int i, d, prod, sigma;
+   list L = exponentSequence(f);
+   int s = size(L[2]);
+
+   if(s == 1)
+   {
+      return(signatureBrieskorn(L[1][1], L[2][1], N));
+   }
+
+   prod = 1;
+   sigma = signatureBrieskorn(L[1][s], L[2][s], N);
+   for(i = s - 1; i >= 1; i--)
+   {
+      prod = prod * L[2][i+1];
+      d = gcd(N, prod);
+      sigma = sigma + d * signatureBrieskorn(L[1][i], L[2][i], N div d);
+   }
+
+   return(sigma);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r = 0,(x,y),dp;
+   int N  = 3;
+   poly f = x15-21x14+8x13y-6x13-16x12y+20x11y2-x12+8x11y-36x10y2
+            +24x9y3+4x9y2-16x8y3+26x7y4-6x6y4+8x5y5+4x3y6-y8;
+   signaturePuiseux(N,f);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//------- sigma(z^N + f) in terms of the imbedded resolution graph of f -------
+
+static proc dedekindSum(number b, number c, int a)
+{
+   number s,d,e;
+   int k;
+   for(k=1;k<=a-1;k++)
+   {
+      d=bigint(k*b) mod a;
+      e=bigint(k*c) mod a;
+      if(d*e!=0)
+      {
+         s=s+(d/a-1/2)*(e/a-1/2);
+      }
+   }
+   return(s);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static proc isRupture(intvec v)
+//=== decides whether the exceptional divisor given by the row v in the
+//=== incidence matrix of the resolution graph intersects at least 3 other
+//=== divisors
+{
+   int i,j;
+   for(i=1;i<=size(v);i++)
+   {
+       if(v[i]<0){return(0);}
+       if(v[i]!=0){j++;}
+   }
+   return(j>=4);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static proc sumExcepDiv(intmat N, list M, int K, int n)
+//=== computes part of the formulae for eta(g,K), g defining an
+//=== isolated curve singularity
+//=== N the incidence matrix of the resolution graph of g
+//=== M list of total multiplicities
+//=== n = nrows(N)
+{
+   int i,j,m,d;
+   for(i=1;i<=n;i++)
+   {
+      if(N[i,i]>0)
+      {
+         m=gcd(K,M[i]);
+         for(j=1;j<=n;j++)
+         {
+            if((i!=j)&&(N[i,j]!=0))
+            {
+               if(m==1){break;}
+               m=gcd(m,M[j]);
+            }
+         }
+         d=d+m-1;
+      }
+   }
+   return(d);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static proc sumEdges(intmat N, list M, int K, int n)
+//=== computes part of the formulae for eta(g,K), g defining an
+//=== isolated curve singularity
+//=== N the incidence matrix of the resolution graph of g
+//=== M list of total multiplicities
+//=== n = nrows(N)
+{
+   int i,j,d;
+   for(i=1;i<=n-1;i++)
+   {
+      for(j=i+1;j<=n;j++)
+      {
+         if(N[i,j]==1)
+         {
+            d=d+gcd(K,gcd(M[i],M[j]))-1;
+         }
+      }
+   }
+   return(d);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static proc etaRes(list L, int K)
+//=== L total multiplicities
+//=== eta-invariant in terms of the imbedded resolution graph of f
+{
+   int i,j,d;
+   intvec v;
+   number e;
+   intmat N = L[1];         // incidence matrix of the resolution graph
+   int n = ncols(L[1]);     // number of vertices in the resolution graph
+   int a = ncols(L[2]);     // number of branches
+   list M;                  // total multiplicities
+   for(i=1;i<=n;i++)
+   {
+      d=L[2][i,1];
+      for(j=2;j<=a;j++)
+      {
+         d=d+L[2][i,j];
+      }
+      if(d==0){d=1;}
+      M[i]=d;
+   }
+   for(i=1;i<=n;i++)
+   {
+      v=N[i,1..n];
+      if(isRupture(v))      // the divisor intersects more then two others
+      {
+         for(j=1;j<=n;j++)
+         {
+            if((i!=j)&&(v[j]!=0))
+            {
+               e=e+dedekindSum(M[j],K,M[i]);
+            }
+         }
+      }
+   }
+   if(a==1)
+   {
+      //the irreducible case
+      return(4*e);
+   }
+   return(a-1+4*e+sumEdges(N,M,K,n)-sumExcepDiv(N,M,K,n));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static proc signatureRes(int N, poly f)
+//=== computes signature of surface singularity defined by z^N + f(x,y) = 0
+//=== in terms of the imbedded resolution graph of f
+{
+   list L = totalmultiplicities(f);
+   return(etaRes(L,N) - N*etaRes(L,1));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//------------ sigma(z^N + f) in terms of the spectral pairs of f -------------
+
+static proc fracPart(number n)
+//=== computes the fractional part n2 of n
+//=== i.e. n2 is not in Z but n-n2 is in Z
+{
+   number a,b;
+   int r;
+   a = numerator(n);
+   b = denominator(n);
+   int z = int(number(a));
+   int y = int(number(b));
+   r = z mod y;
+   int q = (z-r) div y;
+   number n1 = q;
+   number n2 = n-n1;
+   return(n2);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static proc etaSpec(list L, int N)
+//=== L spectral numbers
+//=== eta-invariant in terms of the spectral pairs of f
+{
+   int i;
+   number e, h;
+
+   int n = ncols(L[1]);
+
+   if((n mod 2) == 0)
+   // 0 is not a spectral number, thus f is irreducible
+   {
+      for(i = n div 2+1; i <= n; i++)
+      {
+         e = e + (1 - 2 * fracPart(N * number(L[1][i]))) * L[3][i];
+      }
+      return(2*e);
+   }
+   else
+   // 0 is a spectral number, thus f is reducible
+   {
+      // sum of Hodge numbers in eta function
+      for(i = 1; i <= n; i++)
+      {
+         if((L[2][i] == 2) && ((denominator(leadcoef(N*L[1][i]))==1)
+                              ||(denominator(leadcoef(N*L[1][i]))==-1)))
+         {
+            h = h + L[3][i];
+         }
+      }
+
+      // summand coming from spectral number 0 in eta function
+      h = h + L[3][(n+1) div 2];
+
+      // sum coming from non-zero spectral numbers in eta function
+      for(i = (n+3) div 2; i <= n; i++)
+      {
+         if(!((denominator(leadcoef(N*L[1][i]))==1)
+             ||(denominator(leadcoef(N*L[1][i]))==-1)))
+         {
+            e = e + (1 - 2 * fracPart(N * number(L[1][i]))) * L[3][i];
+         }
+      }
+      return(h + 2*e);
+   }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static proc signatureSpec(int N, poly f)
+//=== computes signature of surface singularity defined by z^N + f(x,y) = 0
+//=== in terms of the spectral pairs of f
+{
+   def R = basering;
+   def Rds = changeord(list(list("ds",1:nvars(basering))));
+   setring Rds;
+   poly f = imap(R,f);
+   list L = sppairs(f);
+   setring R;
+   list L = imap(Rds,L);
+   return(etaSpec(L,N) - N*etaSpec(L,1));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//----------------- Consolidation of the two recent variants ------------------
+
+proc signatureNemethi(int N, poly f, list #)
+"USAGE:  signatureNemethi(N,f); N = integer, f = reduced poly in 2 variables,
+                                # empty or 1,2,3
+@*       - if #[1] = 1 then resolution of singularity is used
+@*       - if #[1] = 2 then spectral pairs are used
+@*       - if # is empty then both upper variants are used in parallel and the
+@*                 fastest returns the result
+RETURN:  signature of surface singularity defined by z^N + f(x,y) = 0
+REMARK:  computes the signature of some special surface singularities
+EXAMPLE: example signatureNemethi; shows an example
+"
+{
+   if(size(#) == 0)
+   {
+      link l(1) = "ssi:fork"; open(l(1));
+      link l(2) = "ssi:fork"; open(l(2));
+      list l = list(l(1),l(2));
+      write(l(1), quote(signatureRes(N,f)));
+      write(l(2), quote(signatureSpec(N,f)));
+      int winner = waitfirst(l);
+      number sigma = read(l(winner));
+      close(l(1));
+      close(l(2));
+      if(printlevel >= 1)
+      {
+         if(winner == 1) { "Resolution of singularity has been used."; }
+         if(winner == 2) { "Spectral pairs have been used."; }
+      }
+      return(sigma);
+   }
+
+   if(#[1] == 1)
+   {
+      return(signatureRes(N,f));
+   }
+
+   if(#[1] == 2)
+   {
+      return(signatureSpec(N,f));
+   }
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r = 0,(x,y),dp;
+   int N  = 3;
+   poly f = x15-21x14+8x13y-6x13-16x12y+20x11y2-x12+8x11y-36x10y2
+            +24x9y3+4x9y2-16x8y3+26x7y4-6x6y4+8x5y5+4x3y6-y8;
+   signatureNemethi(N,f,1);
+   printlevel = 1;
+   signatureNemethi(N,f);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+/*
+Further examples
+
+ring r = 0,(x,y),dp;
+int N;
+poly f,g,g1,g2,g3;
+
+
+// irreducible polynomials
+
+N = 5;
+f = x15-21x14+8x13y-6x13-16x12y+20x11y2-x12+8x11y-36x10y2
+    +24x9y3+4x9y2-16x8y3+26x7y4-6x6y4+8x5y5+4x3y6-y8;
+g = f^3 + x17y17;
+
+N = 6;
+f = y4+2x3y2+x6+x5y;
+g1 = f^2 + x5y5;
+g2 = f^3 + x11y11;
+g3 = f^3 + x17y17;
+
+N = 7;
+f = x5+y11;
+g1 = f^3 + x11y11;
+g2 = f^3 + x17y17;
+
+N = 6;
+// k0 = 30, k1 = 35, k2 = 71
+f = x71+6x65+15x59-630x52y6+20x53+6230x46y6+910x39y12+15x47
+    -7530x40y6+14955x33y12-285x26y18+6x41+1230x34y6+4680x27y12
+    +1830x20y18+30x13y24+x35-5x28y6+10x21y12-10x14y18+5x7y24-y30;
+
+// k0 = 16, k1 = 24, k2 = 28, k3 = 30, k4 = 31
+f = x31-781x30+16x29y-3010x29-2464x28y+104x27y2-2805x28-7024x27y
+    -5352x26y2+368x25y3+366x27-7136x26y-984x25y2-8000x24y3
+    +836x23y4+34x26-320x25y-6464x24y2+6560x23y3-8812x22y4+1392x21y5
+    -12x25+256x24y-1296x23y2-1536x22y3+4416x21y4-8864x20y5+1752x19y6
+    -x24+16x23y-88x22y2-16x21y3-404x20y4+3056x19y5-6872x18y6+1648x17y7
+    +8x21y2-96x20y3+524x19y4-1472x18y5+3464x17y6-3808x16y7+1290x15y8
+    -28x18y4+240x17y5-976x16y6+2208x15y7-2494x14y8+816x13y9+56x15y6
+    -320x14y7+844x13y8-1216x12y9+440x11y10-70x12y8+240x11y9-344x10y10
+    +240x9y11+56x9y10-96x8y11+52x7y12-28x6y12+16x5y13+8x3y14-y16;
+
+
+// reducible polynomials
+
+N = 12;
+f = ((y2-x3)^2 - 4x5y - x7)*(x2-y3);
+
+f = 2x3y3-2y5+x4-xy2;
+
+f = -x3y3+x6y+xy6-x4y4;
+*/
diff --git a/Singular/LIB/surfex.lib b/Singular/LIB/surfex.lib
new file mode 100644
index 0000000..fa4eb7a
--- /dev/null
+++ b/Singular/LIB/surfex.lib
@@ -0,0 +1,1464 @@
+////////////////////////////////////////////////////////////////////////////
+version="version surfex.lib 4.0.0.0 Jun_2013 "; // $Id: 2fb800ee344397b6175558e40cba9e886c6192ba $
+category="Visualization";
+info="
+LIBRARY: surfex.lib      Procedures for visualizing and rotating surfaces.
+@*         It is still an alpha version (see http://www.AlgebraicSurface.net)
+AUTHOR: Oliver Labs
+        This library uses the program surf
+        (written by Stefan Endrass and others)
+        and surfex (written by Oliver Labs and others, mainly Stephan Holzer).
+
+NOTE:
+ This library requires the program surfex, surf and java to be installed.
+ The software is used for producing raytraced images of surfaces.
+ You can download @code{surfex} from http://www.surfex.AlgebraicSurface.net
+
+ surfex is a front-end for surf which aims to be easier to use than
+ the original tool.
+
+SEE ALSO: surf_lib
+
+PROCEDURES:
+plotRotated(poly,coord); Plot the surface given by the polynomial p
+                         with the coordinates coords(list)
+plotRot(poly);           Similar to plotRotated,
+                         but guesses automatically
+                         which coordinates should be used
+plotRotatedList(varieties, coords); Plot the varieties given by the list varieties
+                                    with the coordinates coords
+plotRotatedDirect(varieties);       Plot the varieties given by the list varietiesList
+plotRotatedListFromSpecifyList(varietiesList);  Plot the varieties given by the list varietiesList
+";
+
+LIB "solve.lib";
+LIB "primdec.lib";
+LIB "sing.lib";
+LIB "surf.lib";
+
+///////////////////////////////////////////////////////////
+//
+// the main procedures:
+//
+
+proc plotRot(poly p, list #)
+"
+USAGE: plotRot(poly p, list #)
+Similar to plotRotated, but guesses automatically which coordinates should be used.
+The optional int parameter can be used to set plotting quality.
+
+It opens the external program surfex for drawing the surface given by p,
+seen as a surface in the real affine space with coordinates coords.
+
+ASSUME: The basering is of characteristic zero and without parameters.
+"
+{
+    list coords = list();
+    if(num_vars_id(p)==3)
+    {
+        execute("coords = "+string_of_vars(p)+";");
+    }
+    else
+    {
+        if(num_vars_id(p)<3)
+        {
+            if(nvars(basering)==3)
+            {
+                execute("coords = "+varstr(basering)+";");
+            }
+            else
+            {
+                if(nvars(basering)<3) {
+                    "Could not guess the coordinates because the number of variables in the basering is smaller than 3!";
+                    "Please use plotRotated() instead of plotRot() and specify the coordinates explicitly.";
+                    return(0);
+                } else {
+                    "Could not guess the coordinates because the number of variables in the polynomial is smaller than 3 and the number of variables in the basering is greater than three!";
+                    "Please use plotRotated() instead of plotRot() and specify the coordinates explicitly.";
+                    return(0);
+                }
+            }
+        } else {
+            "Could not guess the coordinates because the number of variables in the polynomial is greater than 3!";
+                    "Please use plotRotated() instead of plotRot() and specify the coordinates explicitly.";
+            return(0);
+        }
+    }
+    return(plotRotatedList(list(p), coords, #));
+}
+example
+{
+    "Example:"; echo=2;
+
+    // More variables in the basering, but only 3 variables in the polynomial:
+    ring r1 = 0, (w,x,y,z), dp;
+    poly cayley_cubic = x^3+y^3+z^3+1^3-1/4*(x+y+z+1)^3;
+    plotRot(cayley_cubic);
+
+    // Three variables in the basering, but fewer variables in the polynomial:
+    ring r2 = 0, (x,y,z), dp;
+    plotRot(x^2+y^2-1);
+    plotRot(y^2+z^2-1);
+
+    // A cubic surface with a solitary point:
+    // Use the additional parameter 3 to ask singular
+    // to compute the singular locus before calling surfex.
+    ring r3 = 0, (x,y,z), dp;
+    poly kn_10 = x^3-3*x*y^2+z^3+3*x^2+3*y^2+z^2;
+    plotRot(kn_10, 3);
+
+    // The swallowtail:
+    // a surface with a real solitary curve sticking out of the surface.
+    // Use the additional parameter 3 to ask singular
+    // to compute the singular locus before calling surfex.
+    poly swallowtail = -4*y^2*z^3-16*x*z^4+27*y^4+144*x*y^2*z+128*x^2*z^2-256*x^3;
+}
+
+proc plotRotated(poly p, list coords, list #)
+"
+USAGE: plotRotated(poly p, list coords, list #)
+This opens the external program surfex for drawing the surface given by p,
+seen as a surface in the real affine space with coordinates coords.
+The optional int parameter can be used to set plotting quality.
+
+ASSUME: coords is a list of three variables.
+The basering is of characteristic zero and without parameters.
+"
+{
+    return(plotRotatedList(list(p), coords, #));
+}
+example
+{
+    "Example:"; echo=2;
+
+    // An easy example: a surface with four conical nodes.
+    ring r = 0, (x,y,z), dp;
+    poly cayley_cubic = x^3+y^3+z^3+1^3-1/4*(x+y+z+1)^3;
+//     plotRotated(cayley_cubic, list(x,y,z));
+
+    // A difficult example: a surface with a one-dimensional real component!
+    poly whitney_umbrella = x^2*z-y^2;
+    // The Whitney Umbrella without its handle:
+    plotRotated(whitney_umbrella, list(x,y,z));
+
+    // The Whitney Umbrella together with its handle:
+    plotRotated(whitney_umbrella, list(x,y,z), 2);
+}
+
+
+proc plotRotatedList(list varieties, list coords, list #)
+"
+USAGE: plotRotatedList(list varieties, list coords, list #)
+This opens the external program surfex for drawing the surfaces given by varieties,
+seen as a surface in the real affine space with coordinates coords.
+The optional int parameter can be used to set plotting quality.
+
+ASSUME: coords is a list of three variables, varieties is a list of ideals
+describing the varieties to be shown.
+The basering is of characteristic zero and without parameters.
+"
+{
+    def oring = basering;
+
+    int plotquality = 0;
+    if(size(#)>0) {
+        plotquality = #[1];
+    }
+
+    list varietiesList = list(list(), list(), list(), list());
+    list usedSurfaces = list();
+    list curveColors = list();
+
+    // go through the list of varieties
+    // produce a list which can be used as input for plotRotatedListFromList()
+    int i;
+    int j;
+    list indList;
+    int ind;
+    ideal itmp;
+    int ncurves;
+    list pd;
+    int k;
+    int surfind;
+    list curSurfColors = list();
+
+    list listOfPoints = list();
+    string str_I = "";
+
+    for(i=1; i<=size(varieties); i++) {
+        itmp = varieties[i];
+        if(plotquality>=3) {
+            itmp = radical(itmp);
+        }
+        itmp = simplify(itmp,1);
+        itmp = simplify(itmp,2);
+        if(size(itmp)==1) { // i.e.: a surface given by one equation
+            surfind = findInList(surfEqn(itmp[1],coords), usedSurfaces);
+            if(surfind==0) {
+                usedSurfaces = usedSurfaces + list(surfEqn(itmp[1],coords));
+                curSurfColors = list(list("insidecolor:",getInsideColorStr(size(varietiesList[1])+1)),
+                                     list("outsidecolor:",getOutsideColorStr(size(varietiesList[1])+1)));
+                varietiesList[1] = varietiesList[1] +
+                    list(list(list("eqno:",string(size(varietiesList[1])+1)),
+                              list("equation:",surfEqn(itmp[1], coords)),
+                              curSurfColors[1],
+                              curSurfColors[2],
+                              list("showcbox:","true"),
+                              list("transparency:","0")));
+                surfind = size(varietiesList[1]);
+
+            }
+            if(plotquality==1) {
+                varieties = varieties + list(slocus(itmp[1]));
+            }
+            if(plotquality==2 || plotquality==3) {
+                // remove doubled components and
+                // add the 1-dimensional singular components
+                // of the surface to the list of curves:
+                int dsl = dim_slocus(itmp[1]);
+                dsl;
+                if(dsl>=0) { // i.e. there is a singular locus
+                    "compute singular locus...";
+                    list eqd;
+                    //
+                    eqd = equidim(slocus(itmp[1]));
+                    ideal tmp_l;
+                    tmp_l = std(eqd[size(eqd)]);
+                    "dim:",dim(tmp_l);
+                    if(dim(tmp_l)==(nvars(basering)-3+2)) {
+                        "--- 2-dim.";
+                        // we have found a multiple component;
+                        // replace it by a simple copy of it
+                        itmp = quotient(itmp[1], tmp_l);
+                        varieties[i] = itmp[1];
+                        eqd = delete(eqd,size(eqd));
+                        if(size(eqd)>0) {
+                            tmp_l = std(eqd[size(eqd)]);
+                        }
+                    }
+                    if(dim(tmp_l)==(nvars(basering)-3+1)) {
+                        "--- 1-dim.";
+                        // we have found a 1-dimensional singular locus
+                        pd = std_primdecGTZ(tmp_l,2);
+                        for(k=1; k<=size(pd); k++) {
+                            if(pd[k][3]==(nvars(basering)-3+1)) {
+                                varieties = varieties + list(pd[k][2]);
+                                curveColors[size(varieties)] = curSurfColors;
+                            } else {
+                                "???";
+                            }
+                        }
+                        eqd = delete(eqd,size(eqd));
+                        if(size(eqd)>0) {
+                            tmp_l = std(eqd[size(eqd)]);
+                        }
+                    }
+                    if(dim(tmp_l)==(nvars(basering)-3+0)) {
+                        "--- 0-dim.";
+                        // we have found a 0-dimensional singular locus
+                        // we compute floating point approximations of the
+                        // coordinates of all singular points
+                        if(npars(oring)>0) {
+                            "str:",parstr(1),rootminpoly();
+                            list all_real_sols = allroots_minpoly();
+//                            "all sols:";all_real_sols;
+//                            sprintf("number %s = %s; ", parstr(1), rootminpoly());
+                            int minp;
+                            if((npars(basering) == 1) && (minpoly != 0)) {
+                                minp = 1;
+                            } else {
+                                minp = 0;
+                            }
+                            str_I = "";
+                            if(minp==1) {
+                                "minp=1";
+                                string str_para = parstr(1);
+                                string str_tmp_l;
+                                def cur_ring = basering;
+                                if(1) {
+                                    short=0;
+                                    str_tmp_l = "ideal eqd_tmp = "+
+//                                        string(tmp_l)+","+string(minpoly)+";";
+                                        string(tmp_l);
+                                    "str:",str_tmp_l;
+                                    string str_num_mp = "number "+parstr(1)+"="+
+                                        decstr2ratstr(rootminpoly())+";";
+                                    execute("ring Iring = 0,("
+//                                            +string(coords)+","+str_para+"),dp;");
+                                            +string(coords)+"),dp;");
+                                    basering;
+                                    execute(str_num_mp);
+                                    execute(str_tmp_l);
+                                    eqd_tmp;
+                                    list real_sols = real_solve(eqd_tmp);
+                                    real_sols;
+                                    $;
+                                    setring cur_ring;
+                                }
+                            } else {
+                                // minp==0: we do not know how to handle this
+                                "???";
+                            }
+                        } else {
+                            "no pars";
+                            ideal eqd_tmp = tmp_l;
+                            short=0;
+                            string str_tmp_l = "ideal eqd_tmp = "+string(tmp_l)+";";
+                            def cur_ring = basering;
+                            execute("ring Iring = (real,30),("+string(coords)+"),("+ordstr(oring)+");");
+//                            basering;
+                            execute(str_I);
+                            execute(str_tmp_l);
+                            list real_sols = real_solve(eqd_tmp);
+                            setring cur_ring;
+                        }
+                        "real_sols:";real_sols;
+                        for(k=1; k<=size(real_sols); k++) {
+                            "search point:";
+                             string(list(real_sols[k][1],real_sols[k][2],real_sols[k][3],string(surfind)));
+//                             listOfPoints;
+                            if(findInList(string(list(list(real_sols[k][1],real_sols[k][2],real_sols[k][3],string(surfind)))),
+                                          listOfPoints)==0) {
+                                "add pt";
+                                varietiesList[4] = varietiesList[4] +
+                                    list(list(real_sols[k][1],real_sols[k][2],real_sols[k][3],string(surfind)));
+                                listOfPoints = listOfPoints +
+                                    list(string(list(real_sols[k][1],real_sols[k][2],real_sols[k][3],string(surfind))));
+                            }
+                        }
+                    }
+                }
+            }
+        } else {
+            // i.e.: more than one equation
+            varietiesList[2] = varietiesList[2] +
+                list(list(list("surfaces:"),
+                          list("curveno:",
+                               string(size(varietiesList[2])+1)),
+                          list("showcbox:","true")));
+            if(size(curveColors) >= i) {
+                varietiesList[2][size(varietiesList[2])][4] = curveColors[i][1];
+                varietiesList[2][size(varietiesList[2])][4][1] = "color:";
+            }
+            ncurves = size(varietiesList[2]);
+            for(j=1; j<=size(itmp); j++) {
+                ind = findInList(surfEqn(itmp[j],coords), usedSurfaces);
+                usedSurfaces = usedSurfaces + list(surfEqn(itmp[1],coords));
+//                "indList:";indList;
+                if(ind == 0) {
+//                    "--------> not in list", surfEqn(itmp[j], coords);
+                    if(j==1) {
+                        varietiesList[1] = varietiesList[1] +
+                            list(list(list("eqno:",string(size(varietiesList[1])+1)),
+                                      list("equation:",surfEqn(itmp[j], coords)),
+                                      list("insidecolor:",getInsideColorStr(size(varietiesList[1])+1)),
+                                      list("outsidecolor:",getOutsideColorStr(size(varietiesList[1])+1)),
+                                      list("showcbox:","true"),
+                                      list("transparency:","100")));
+                    } else {
+                        varietiesList[1] = varietiesList[1] +
+                            list(list(list("eqno:",string(size(varietiesList[1])+1)),
+                                      list("equation:",surfEqn(itmp[j], coords)),
+                                      list("insidecolor:",getInsideColorStr(size(varietiesList[1])+1)),
+                                      list("outsidecolor:",getOutsideColorStr(size(varietiesList[1])+1)),
+                                      list("showcbox:","false"),
+                                      list("transparency:","0")));
+                    }
+                    ind = size(varietiesList[1]);
+                } else {
+                }
+                varietiesList[2][ncurves][1] = varietiesList[2][ncurves][1] + list(string(ind));
+            }
+        }
+    }
+
+//      "------------";
+//      varietiesList;
+//      "------------";
+    return(plotRotatedListFromSpecifyList(varietiesList, coords, #));
+}
+example {
+    "Example:"; echo=2;
+
+    // A cubic surface together with a tritangent plane
+    // (i.e. a plane which cuts out three lines).
+    ring r = 0, (x,y,z), dp;
+    poly cayley_cubic = x^3+y^3+z^3+1^3-1/4*(x+y+z+1)^3;
+    poly plane = 1-x-y-z;
+    plotRotatedList(list(cayley_cubic, plane), list(x,y,z));
+
+    // The same cubic and plane.
+    // The plane is not shown but only its intersection with the surface.
+    plotRotatedList(list(cayley_cubic, ideal(cayley_cubic, plane)), list(x,y,z));
+}
+
+
+proc plotRotatedListFromSpecifyList(list varietiesList, list #)
+"
+USAGE: plotRotatedListFromSpecifyList(list varietiesList, list #);
+varietiesList has a complicated format (not documented yet);
+see the example.@*
+The optional int parameter can be used to set plotting quality.
+
+ASSUME: The basering is of characteristic zero.
+
+EXAMPLE: example plotRotatedListFromSpecifyList;
+"
+{
+    // make the surfex file
+    string str = getSurfexCodeFromSpecifyList(varietiesList, #);
+
+    return(plotRotatedFromCode(str, #));
+}
+example
+{
+    "Example:"; echo=2;
+
+    // A cubic surface depending on a parameter:
+    ring r = (0,p1), (x,y,z), dp;
+    poly cayley_cubic = x^3+y^3+z^3+1^3-p1*(x+y+z+1)^3;
+    poly plane = 1-x-y-z;
+    plotRotatedListFromSpecifyList(list(list(list(list("eqno:","1"),
+                                                  list("equation:",
+                                                       string(cayley_cubic))
+                                                 )
+                                            ),
+                                        list(),
+                                        list(list(1,"0.0","1.0","500","0.25+0.25*sin(PI*p1)")),
+                                        list()
+                                       ));
+}
+
+
+proc plotRotatedListFromStringList(list varieties, list #)
+"
+RETURN: the return code of the system command which executes surfex.
+
+USAGE: not documented yet.
+"
+{
+    // make the surfex file
+    getSurfexCodeFromStringList(varieties, #);
+    string str = getSurfexCodeFromStringList(varieties, #);
+
+    return(plotRotatedFromCode(str, #));
+}
+
+
+proc plotRotatedDirect(list varieties, list #)
+"
+USAGE: plotRotatedDirect(list varieties, list #)
+This opens the external program surfex for drawing the surfaces given by varieties,
+seen as a surface in the real affine space with coordinates x,y,z.
+The format for the list varieties is not fully documented yet;
+please, see the examples below and try to adjust the examples to suit your needs.@*
+The optional int parameter can be used to set plotting quality.
+
+ASSUME:
+Passes the equations directly to surfex, i.e., the variable names should
+be x,y,z.
+The advantage is that one can use parameters p1, p2, ...;
+these will be passed to surfex.
+"
+{
+    string str = getSurfexCodeFromListDirect(varieties, #);
+
+    return(plotRotatedFromCode(str, #));
+}
+example
+{
+    "Example:"; echo=2;
+
+    // A cubic surface depending on a parameter:
+    ring r = (0,p1), (x,y,z), dp;
+    poly cayley_cubic = x^3+y^3+z^3+1^3-p1*(x+y+z+1)^3;
+    // The entries of the list of varieties can either be polynomials
+    plotRotatedDirect(list(list(list(cayley_cubic)),
+                           list(),
+                           list(list(1,"0.0","1.0","500","0.25+0.25*sin(PI*p1)"))
+                           ));
+
+    // or strings which represent surfex-readable polynomials
+    plotRotatedDirect(list(list(list("x^3+y^3+z^3+1^3-p1*(x+y+z+1)^3")),
+                           list(),
+                           list(list("1","0.0","1.0","500","0.25+0.25*sin(PI*p1)"))
+                           ));
+
+    // More complicated varieties
+    plotRotatedDirect(list(list(list("x^2+y^2-z^2-3^2"),
+                                list("x*sin(p1)+y*cos(p1)-3")),
+                           list(list(list(1,2))),
+                           list(list("1","0.0","1.0","500","2*PI*p1"))
+                           ));
+}
+
+proc plotRotatedFromCode(string str, list #)
+"
+USAGE: plotRotatedFromCode(string str, list #);
+
+This procedure is only for internal usage;
+it takes the surfex-code as a string and calls surfex.
+
+"
+{
+     // we need a temporary .sux file for surfex
+    string tmpd = "/tmp";
+    string l="surf"+string(system("pid"))+".sux";
+    // a temporary file which stores the output of surfex
+    string erg="/tmp/surferg"+string(system("pid"));
+
+    write(":w "+tmpd+"/"+l, str);
+
+    string surfex_path=system("Singular");
+    while(surfex_path[size(surfex_path)]!="/") { surfex_path=surfex_path[1..size(surfex_path)-1]; }
+    surfex_path=surfex_path+"../LIB/surfex";
+    if (status(surfex_path,"exists")=="no")
+    {
+    // search in SINGULAR_PATH:
+       string surfex_path1=system("SingularLib");
+       string surfex_path2=surfex_path1;
+       while (find(surfex_path1,":")!=0)
+       {
+         surfex_path2=surfex_path1[1..find(surfex_path1,":")-1];
+         while(surfex_path2[size(surfex_path2)]==" ") {
+           surfex_path2 = surfex_path2[1..(size(surfex_path2)-1)];
+         }
+
+         if (status(surfex_path2+"/surfex","exists")=="yes") break;
+         surfex_path1=surfex_path1[find(surfex_path1,":")+1,size(surfex_path1)];
+         surfex_path2=surfex_path1[1..(size(surfex_path1)-1)];
+         while(surfex_path2[size(surfex_path2)]==" ") {
+           surfex_path2 = surfex_path2[1..(size(surfex_path2)-1)];
+         }
+       }
+       surfex_path=surfex_path2+"/surfex";
+    }
+
+     int i=system("sh","surfex \""+surfex_path+"\" -d "+tmpd+" -i " + l +" >"+erg+" 2>/dev/null");
+
+    // delete the temporary file
+    i = system("sh","rm " + l +" 2>/dev/null");
+    return(read(erg));
+}
+
+
+///////////////////////////////////////////////////////////
+//
+// procedures used to produce the surf-code:
+//
+
+
+proc getSurfexCodeFromListDirect(list varieties, list #)
+"
+USAGE: getSurfexCodeFromListDirect(list varieties, list #)
+
+ASSUME: varieties has four components,
+        - the first is a list of polynomials, say f_1, ..., f_k
+        - the second is a list of lists of numbers in {1, ..., k} describing the curves
+          as intersections of the corresponding f_i
+        - the third is a list of lists describing the parameters used in the polynomials f_i
+        - the fourth is a list of lists of points given by their approximate coordinates (three decimal numbers)
+
+RETURN: the surfex code (.sux)
+"
+{
+    int i;
+    int j;
+    string str = "this is surfex v0.89.07"+newline;
+
+    str = str + "TYPE:" + newline;
+    str = str + "specify"+newline;
+    str = str + "EQUATIONS:"+newline;
+    str = str + string(size(varieties[1])) + newline;
+    for(i=1; i<=size(varieties[1]); i++) {
+        str = str + "Equation:"+newline;
+        str = str + "eqno:"+newline;
+        str = str + string(i) + newline;
+        str = str + "equation:"+newline;
+        str = str + surfEqnDir(varieties[1][i][1]) + newline;
+        if(size(varieties[1][i])>=2) {
+            str = str + "showcbox:"+newline;
+            str = str + varieties[1][i][2] + newline;     // show it or not
+            if(size(varieties[1][i])>=3) {
+                str = str + "transparency:"+newline;
+                str = str + string(varieties[1][i][3]) + newline;     // transparency
+            }
+        }
+    }
+    str = str + "CURVES:"+newline;
+    str = str + string(size(varieties[2])) + newline;
+    for(i=1; i<=size(varieties[2]); i++) {
+        str = str + "Curve:"+newline;
+        str = str + "curveno:"+newline;
+        str = str + string(i) + newline;
+        str = str + "surfaces:"+newline;
+//        "curves:";varieties[2][i];
+        for(j=1; j<=size(varieties[2][i][1]); j++) {
+            str = str + string(varieties[2][i][1][j]) + newline;
+        }
+        if(size(varieties[2][i])>=2) {
+            str = str + "showcbox:"+newline;
+            str = str + varieties[2][i][2] + newline;     // show it or not
+        }
+    }
+    str = str + "PARAMETERS:"+newline;
+    str = str + string(size(varieties[3])) + newline;
+    for(i=1; i<=size(varieties[3]); i++) {
+        str = str + "Parameter:"+newline;
+        str = str + "parno:"+newline;
+        str = str + string(varieties[3][i][1]) + newline;
+        str = str + "fromtoval:"+newline;
+        str = str + varieties[3][i][2] + newline;
+        str = str + varieties[3][i][3] + newline;
+        str = str + string(varieties[3][i][4]) + newline;
+        if(size(varieties[3][i])>=5) {
+            str = str + "function:"+newline;
+            str = str + varieties[3][i][5]+newline;
+        }
+    }
+//     str = str + "////////////////// Parameter: /////////////////////////"+newline;
+//     str = str + "1" + newline;
+//     str = str + "0.0" + newline;
+//     str = str + "1.0" + newline;
+//     str = str + "1000" + newline;
+//    str = str + string(size(varieties[3])) + newline;
+    return(str);
+}
+
+proc getSurfexCodeFromList(list varieties, list coords, list #)
+"
+ASSUME: varieties has four components,
+        - the first is a list of polynomials, say f_1, ..., f_k
+        - the second is a list of lists of numbers in {1, ..., k} describing the curves
+          as intersections of the corresponding f_i
+        - the third is a list of lists describing the parameters used in the polynomials f_i
+        - the fourth is a list of lists of points given by their approximate coordinates (three decimal numbers)
+
+RETURN: the surfex code (.sux)
+"
+{
+    int i;
+    int j;
+    string str = "this is surfex v0.89.07"+newline;
+
+    str = str + "TYPE:" + newline;
+    str = str + "specify"+newline;
+    str = str + "EQUATIONS:"+newline;
+    str = str + string(size(varieties[1])) + newline;
+    for(i=1; i<=size(varieties[1]); i++) {
+        str = str + "Equation:"+newline;
+        str = str + "eqno:"+newline;
+        str = str + string(i) + newline;
+        str = str + "equation:"+newline;
+        str = str + surfEqn(varieties[1][i][1], coords) + newline;
+        str = str + "showcbox:"+newline;
+        str = str + varieties[1][i][2] + newline;     // show it or not
+        str = str + "transparency:"+newline;
+        str = str + string(varieties[1][i][3]) + newline;     // transparency
+    }
+    str = str + "CURVES:"+newline;
+    str = str + string(size(varieties[2])) + newline;
+    for(i=1; i<=size(varieties[2]); i++) {
+        str = str + "Curve:"+newline;
+        str = str + "curveno:"+newline;
+        str = str + string(i) + newline;
+        str = str + "surfaces:"+newline;
+        for(j=1; j<=size(varieties[2][i]); j++) {
+            str = str + string(varieties[2][i][1][j]) + newline;
+        }
+        str = str + "showcbox:"+newline;
+        str = str + varieties[2][i][2] + newline;     // show it or not
+    }
+    str = str + "PARAMETERS:"+newline;
+    str = str + string(size(varieties[3])) + newline;
+    for(i=1; i<=size(varieties[3]); i++) {
+        str = str + "Parameter:"+newline;
+        str = str + "parno:"+newline;
+        str = str + string(varieties[3][i][1]) + newline;
+        str = str + "fromtoval:"+newline;
+        str = str + surfEqn(varieties[3][i][2], coords) + newline;
+        str = str + surfEqn(varieties[3][i][3], coords) + newline;
+        str = str + string(varieties[3][i][4]) + newline;
+        if(size(varieties[3][i])>=5) {
+            str = str + "function:"+newline;
+            str = str + varieties[3][i][5]+newline;
+        }
+    }
+//     str = str + "////////////////// Parameter: /////////////////////////"+newline;
+//     str = str + "1" + newline;
+//     str = str + "0.0" + newline;
+//     str = str + "1.0" + newline;
+//     str = str + "1000" + newline;
+//    str = str + string(size(varieties[3])) + newline;
+    return(str);
+}
+
+proc getSurfexCodeFromStringList(list varieties, list #)
+"
+ASSUME: varieties has three components,
+        - the first is a list of polynomials, say f_1, ..., f_k
+        - the second is a list of lists of numbers in {1, ..., k} describing the curves
+          as intersections of the corresponding f_i
+        - the third is a list of lists describing the parameters used in the polynomials f_i
+
+RETURN: the surfex code (.sux)
+"
+{
+    int i;
+    int j;
+    string str = "this is surfex v0.89.07"+newline;
+
+    str = str + "TYPE:" + newline;
+    str = str + "specify"+newline;
+    str = str + "EQUATIONS:"+newline;
+    str = str + string(size(varieties[1])) + newline;
+    for(i=1; i<=size(varieties[1]); i++) {
+        str = str + "Equation:"+newline;
+        str = str + "eqno:"+newline;
+        str = str + string(i) + newline;
+        str = str + "equation:"+newline;
+        str = str + varieties[1][i][1] + newline;
+        str = str + "showcbox:"+newline;
+        str = str + varieties[1][i][2] + newline;     // show it or not
+        str = str + "transparency:"+newline;
+        str = str + varieties[1][i][3] + newline;     // transparency
+    }
+    str = str + "CURVES:"+newline;
+    str = str + string(size(varieties[2])) + newline;
+    for(i=1; i<=size(varieties[2]); i++) {
+        str = str + "Curve:"+newline;
+        str = str + "curveno:"+newline;
+        str = str + string(i) + newline;
+        str = str + "surfaces:"+newline;
+        for(j=1; j<=size(varieties[2][i][1]); j++) {
+            str = str + string(varieties[2][i][1][j]) + newline;
+        }
+        str = str + "showcbox:"+newline;
+        str = str + varieties[2][i][2] + newline;     // show it or not
+    }
+    str = str + "PARAMETERS:"+newline;
+    str = str + string(size(varieties[3])) + newline;
+    for(i=1; i<=size(varieties[3]); i++) {
+        str = str + "Parameter:"+newline;
+        str = str + "parno:"+newline;
+        str = str + string(varieties[3][i][1]) + newline;
+        str = str + "fromtoval:"+newline;
+        str = str + varieties[3][i][2] + newline;
+        str = str + varieties[3][i][3] + newline;
+        str = str + string(varieties[3][i][4]) + newline;
+        if(size(varieties[3][i])>=5) {
+            str = str + "function:"+newline;
+            str = str + varieties[3][i][5]+newline;
+        }
+    }
+    return(str);
+}
+
+
+proc getSurfexCodeFromSpecifyList(list varieties, list #)
+"
+ASSUME: varieties has three components,
+        - the first is a list of polynomials, say f_1, ..., f_k
+        - the second is a list of lists of numbers in {1, ..., k} describing the curves
+          as intersections of the corresponding f_i
+        - the third is a list of lists describing the parameters used in the polynomials f_i
+        - the fourth is a list of lists describing the singular points to be shown as spheres
+
+RETURN: the surfex code (.sux)
+"
+{
+    int i;
+    int j;
+    int k;
+    string str = "this is surfex v0.89.07"+newline;
+
+    str = str + "TYPE:" + newline;
+    str = str + "specify"+newline;
+    str = str + "EQUATIONS:"+newline;
+    str = str + string(size(varieties[1])) + newline;
+    for(i=1; i<=size(varieties[1]); i++) {
+        str = str + "Equation:"+newline;
+        for(j=1; j<=size(varieties[1][i]); j++) {
+            str = str + varieties[1][i][j][1] +newline;
+            str = str + varieties[1][i][j][2] +newline;
+        }
+    }
+    str = str + "CURVES:"+newline;
+    str = str + string(size(varieties[2])) + newline;
+    for(i=1; i<=size(varieties[2]); i++) {
+        str = str + "Curve:"+newline;
+        for(j=1; j<=size(varieties[2][i]); j++) {
+            str = str + varieties[2][i][j][1] +newline;
+            if(varieties[2][i][j][1] == "surfaces:") {
+                for(k=2; k<=size(varieties[2][i][j]); k++) {
+                    str = str + string(varieties[2][i][j][k]) + newline;
+                }
+            } else {
+                str = str + varieties[2][i][j][2] +newline;
+            }
+        }
+//         str = str + "curveno:"+newline;
+//         str = str + string(i) + newline;
+//         str = str + "surfaces:"+newline;
+//         for(j=1; j<=size(varieties[2][i][1]); j++) {
+//             str = str + string(varieties[2][i][1][j]) + newline;
+//         }
+//         str = str + "showcbox:"+newline;
+//         str = str + varieties[2][i][2] + newline;     // show it or not
+    }
+    str = str + "PARAMETERS:"+newline;
+    str = str + string(size(varieties[3])) + newline;
+    for(i=1; i<=size(varieties[3]); i++) {
+        str = str + "Parameter:"+newline;
+        str = str + "parno:"+newline;
+        str = str + string(varieties[3][i][1]) + newline;
+        str = str + "fromtoval:"+newline;
+        str = str + varieties[3][i][2] + newline;
+        str = str + varieties[3][i][3] + newline;
+        str = str + string(varieties[3][i][4]) + newline;
+        if(size(varieties[3][i])>=5) {
+            str = str + "function:"+newline;
+            str = str + varieties[3][i][5]+newline;
+        }
+    }
+    string str_from = "0.0";
+    string str_to = "5.0";
+    string str_radius = "50";
+    str = str + "SOLITARY POINTS:"+newline;
+    str = str + string(size(varieties[4])) + newline;
+    for(i=1; i<=size(varieties[4]); i++) {
+        str = str + "SolitaryPoint:"+newline;
+        str = str + "solPtNo:"+newline;
+        str = str + string(i) + newline;
+        str = str + "surface:"+newline;
+        str = str + varieties[4][i][4] + newline;
+        str = str + "fromtoval:"+newline;
+        str = str + str_from + newline;
+        str = str + str_to + newline;
+        str = str + str_radius + newline;
+        str = str + "coords:" + newline;
+        str = str + varieties[4][i][1] + newline;
+        str = str + varieties[4][i][2] + newline;
+        str = str + varieties[4][i][3] + newline;
+    }
+    return(str);
+}
+
+///////////////////////////////////////////////////////////
+//
+// procedures for standard colors:
+//
+
+proc numBaseColors()
+"
+USAGE: numBaseColors()
+
+RETURN: the number of predefined surface colors.
+"
+{
+    return(6);
+}
+
+proc baseSurfaceColors(int no)
+"
+USAGE: baseSurfaceColors(int no)
+
+REMARK: There are currently 6=numBaseColors() basic surface colors.
+You can modify them according to your wishes
+by just redefining this procedure in your Singular-script.
+
+If you want more colors, then you also have to redefine numBaseColors() accordingly.
+
+RETURN: a list of three integers describing the RGB values of a color.
+"
+{
+    if(no%numBaseColors()==1) {
+        return(list(240,160,0));
+    }
+    if(no%numBaseColors()==2) {
+        return(list(160,240,0));
+    }
+    if(no%numBaseColors()==3) {
+        return(list(0,160,240));
+    }
+    if(no%numBaseColors()==4) {
+        return(list(240,0,160));
+    }
+    if(no%numBaseColors()==5) {
+        return(list(0,240,160));
+    }
+    if(no%numBaseColors()==0) {
+        return(list(160,0,240));
+    }
+}
+
+proc getInsideColorStr(int no)
+"
+USAGE: getInsideColorStr(int no)
+
+RETURN: a string describing inside color number no
+where the three integer RGB values are in one line each.
+"
+{
+    list bc = baseSurfaceColors(no);
+    string str = string(bc[1])+newline+string(bc[2])+newline+string(bc[3]);
+    return(str);
+}
+
+proc getOutsideColorStr(int no)
+"
+USAGE: getOutsideColorStr(int no)
+
+RETURN: a string describing outside color number no
+where the three integer RGB values are in one line each.
+"
+{
+    list bc = baseSurfaceColors(no);
+    string str = string(bc[1])+newline+string(bc[2])+newline+string(bc[3]);
+    return(str);
+}
+
+///////////////////////////////////////////////////////////
+//
+// procedures used by the plot procedures:
+//
+
+proc surfEqnDir(list #)
+"
+USAGE: surfEqnDir(list #) without any checks etc.
+
+RETURN: string(#[1]) where short=0.
+"
+{
+    int stmp = short; short = 0;
+    string str = string(#[1]);
+    short = stmp;
+    return(str);
+}
+
+proc surfEqn(poly p, list coords, list #)
+"
+USAGE: surfEqn(poly p, list coords)
+       Tries to produce a string for the equation of p which is convenient for surfex.
+ASSUME: - p defines a plane curve or a surface,
+         - coords is a list of the three coordinates to use, e.g. list(x,y,z),
+           in this way, it is possible to distinguish between x^2+y^2-1 and y^2+z^2-1
+RETURN: a string, that one can use with the external program surf
+EXAMPLE: example surfEqn; shows an example
+"
+{
+    int params=0;
+    if(size(#)>0) {
+        params = #[1];
+    }
+    string err_mes; // string containing error messages
+    def base=basering;
+    int mynvars = nvars(basering);
+
+    intvec ind=num_of_vars(p);
+
+    int i,j,n;
+    int minp = 0;
+    n=0;
+    for(i=size(ind);i>0;i--)
+    {
+          if (ind[i]!=0) {
+            n++;
+        } else {
+            if(var(i)==coords[1] || var(i)==coords[2] || var(i)==coords[3]) {
+                ind[i]=1;
+                n++;
+            }
+        }
+    }
+
+    params = params + npars(basering);
+    n = n + npars(basering);
+    if((npars(basering) == 1) && (minpoly != 0)) {
+        minp = 1;
+    } else {
+        minp = 0;
+    }
+    string str_I = "";
+    for(i=1; i<=npars(basering); i=i+1) {
+        if(!(parstr(i) == "i")) {
+            if(minp==1) {
+                str_I = str_I + sprintf("number %s = %s; ", parstr(i), rootminpoly());
+            } else {
+            }
+        }
+    }
+    int bshort = short; short = 0;
+    if(!(minp==1 || npars(basering)==0)) {
+        p=cleardenom(p);
+        err_mes="Cannot plot equations with a parameter without a specified minpoly";
+        ERROR(err_mes);
+    }
+    str_I = str_I + "poly p = " + string(p) + ";";
+
+    short = bshort;
+
+    if(params==0) {
+        if (n<=2 or n>=4)
+        {
+            err_mes="Cannot plot equations with "+string(n)+" variables";
+            ERROR(err_mes);
+//            return("0");
+        }
+        if(n==4) {
+            ring r=(real,30,30),(xx,yy,zz,ww),dp;
+        } else {
+            ring r=(real,30,30),(x,y,z),dp;
+        }
+    } else {
+        if(n-params<=2 || n-params>=4) {
+            err_mes="Cannot plot equations with "+string(n-params)+" variables";
+            ERROR(err_mes);
+//            return("0");
+        } else {
+            if(params == 1) {
+                if(n-params==3) {
+                    if(minp==1) {
+                        // switch to a ring without minimal polynomial:
+                        execute("ring rr = (real,30,30),("+varstr(base)+"), dp;");
+//                        rr;
+//                        "str_I",str_I;
+                        execute(str_I);
+                        def base = rr;
+                        ring r=(real,30,30),(x,y,z),dp;
+                    } else {
+                        p=cleardenom(p);
+                        ring r=(real,30,30),(x,y,z,p1),dp;
+                    }
+                }
+            }
+            if(params == 2) {
+                if(n-params==3) {
+                    p=cleardenom(p);
+                    ring r=(real,30,30),(x,y,z,p1,p2),dp;
+                }
+            }
+            if(params == 3) {
+                if(n-params==3) {
+                    p=cleardenom(p);
+                    execute("ring rr = (real,30,30),("+varstr(base)+","+parstr(base)+"), dp;");
+                    rr;
+                    "str_I",str_I;
+                    execute(str_I);
+                    "pnew:",p;
+                    def base = rr;
+
+                    ring r=(real,30,30),(x,y,z,p1,p2,p3),dp;
+                }
+            }
+        }
+    }
+//    basering;
+    short=0;
+    map phi=base,0;
+    j=1;
+
+    for(i=1;i<=mynvars;i++)
+    {
+        if (ind[i]!=0)
+        {
+            phi[i]=var(j);
+            j++;
+        }
+    }
+    poly p=(simplify(phi(p),1));
+    if (leadcoef(p) <0) {
+        if(size(#)>1) {
+            if(#[2]!=0) {
+                p=-p;
+            }
+        } else {
+            p=-p;
+        }
+    }
+    if(leadcoef(p)!=0) {
+        p = p/leadcoef(p);
+    }
+    string thesurfstr = string(p);
+    if(minp == 1) {
+        // replace k by rootRepl
+    }
+
+    return (thesurfstr);
+} // end of surfEqn()
+example
+{ "EXAMPLE:"; echo =2;
+
+  ring rr0 = 0,(x(1..3)),dp;
+  poly p = x(1)^3 - x(2)^2;
+  print(surfEqn(p,list(x(1),x(2),x(3))));
+
+  ring rr1 = 0,(x,y,z),dp;
+  poly I(1) = 2x2-1/2x3 +1-y+1;
+  print(surfEqn(I(1),list(x,y,z)));
+
+  // Steiner surface
+  poly J(2) = x^2*y^2+x^2*z^2+y^2*z^2-17*x*y*z;
+  print(surfEqn(J(2),list(x,y,z)));
+} // end of example surfEqn()
+
+
+proc num_vars_id(ideal I)
+"
+USAGE: num_vars_id(ideal I)
+
+RETURN: The number of ring-variables occurring in the ideal I.
+"
+{
+    intvec v = num_of_vars(I);
+    int num = 0;
+    for(int i=size(v);i>0;i--)
+    {
+        if (v[i]!=0) { num++; }
+    }
+    return(num);
+}
+example {
+    "EXAMPLE:"; echo = 2;
+    ring r = 0, (x,y,z),dp;
+    ideal j = x^2-y, x^3-2;
+    num_vars_id(j);
+}
+
+proc findInList(list obj, list l)
+"
+USAGE: findInList(list obj, list l)
+       Tries to find the object obj in the list l.
+
+ASSUME: the object obj[1] can be compared to the objects in the list l
+
+RETURN: if obj[1]=l[i] for some i, then return the first such i,
+        otherwise return 0
+"
+{
+    for(int i=1; i<=size(l); i++) {
+        if(l[i]==obj[1]) {
+            return(i);
+        }
+    }
+
+    return(0);
+}
+example {
+    "EXAMPLE:"; echo = 2;
+    ring r = 0,(x,y,z), dp;
+    list a = list(x^2+y^2+z^2+1, x^2+y^2+z^2-1, x^2+y^2-z^2+1, x^2+y^2-z^2-1);
+    findInList(x^2+y^2+z^2-1, a);
+    findInList(x^2+y^2+z^2, a);
+}
+
+proc std_primdecGTZ(ideal I, list #)
+"
+USAGE: std_primdecGTZ(ideal I, list #)
+Computes a primdary decomposition pd of I using primdecGTZ and then
+calls std_for_pd(pd).
+For the output and options, consult the help of std_for_pd.
+
+RETURN: see std_for_pd.
+"
+{
+    list pd = primdecGTZ(I);
+    return(std_for_pd(pd, #));
+}
+example {
+    "EXAMPLE:"; echo = 2;
+
+    ring r = 0, (x,y), dp;
+    ideal j = y-x^2,z-x^3;
+    primdecGTZ(j);
+    std_primdecGTZ(j);
+    std_primdecGTZ(j,1);
+}
+
+proc std_for_pd(list pd, list #)
+"
+USAGE: std_for_pd(list pd, list #)
+Call std for each of the prime ideals in the list pd
+replace the prime ideals by their standard-basis.
+Compute dim() and mult() of each prime component using these standard bases.
+If an additional argument is given then do the same for the primary components.
+
+ASSUME:
+pd is in the format produced by primdecGTZ() or primdecSY().
+
+RETURN: A list, say l, of lists, similar to a list returned by primdecSY() or primdecGTZ().
+However, each of the entries of l (which is a list l[i]) contains some additional entries:
+l[1]: the primary ideal
+l[2]: a standard basis of the associated prime ideal
+l[3]: dim() of this prime ideal
+l[4]: mult() of this prime ideal
+
+If an additional argument # is given then l[1] changes:
+l[1]: a standard basis of the primary ideal
+Morever, there are some more entries:
+l[5]: dim() of this primary ideal
+l[6]: mult() of this primary ideal
+l[7]: l[6] / l[5]
+"
+{
+
+    if(typeof(pd[1])=="ideal") {
+        // this is a Singular bug!?
+//        "bug!";pd;"---";
+        pd = list(list(pd[1], pd[1]));
+//        pd;$;
+    }
+    list pd_neu;
+    int i;
+    list coords;
+    ideal stdtmp;
+    ideal stdtmp2;
+    for(i=1; i<=size(pd); i++) {
+        stdtmp = std(pd[i][2]);
+        stdtmp2 = pd[i][1];
+        if(size(#)>0) {
+            stdtmp2 = std(stdtmp2);
+            if(mult(stdtmp)==0) {
+                pd_neu[i] = list(stdtmp2,
+                                 stdtmp,
+                                 dim(stdtmp), mult(stdtmp),
+                                 dim(stdtmp2), mult(stdtmp2),
+                                 0);
+            } else {
+                pd_neu[i] = list(stdtmp2,
+                                 stdtmp,
+                                 dim(stdtmp), mult(stdtmp),
+                                 dim(stdtmp2), mult(stdtmp2),
+                                 mult(stdtmp2) div mult(stdtmp));
+            }
+        } else {
+            pd_neu[i] = list(stdtmp2,
+                             stdtmp,
+                             dim(stdtmp), mult(stdtmp));
+        }
+    }
+    return(pd_neu);
+}
+example {
+    "EXAMPLE:"; echo = 2;
+
+    ring r = 0, (x,y,z), dp;
+    ideal j = y-x^2,z-x^3;
+    list pd = primdecGTZ(j);
+    pd;
+    std_for_pd(pd, 1);
+}
+
+proc real_solve(ideal to_solve)
+"
+USAGE: real_solve(ideal to_solve)
+
+RETURN: a list of all real solutions (as strings)
+of the zero-dimensional ideal to_solve (without multiplicities).
+
+REMARK: Until now, it may happen that some points appear more than once.
+"
+{
+    int k;
+    int i;
+
+//    def Isolring = solve(to_solve,30,0,60,"nodisplay");
+    def Isolring = solve(to_solve,9,0,13,"nodisplay");
+    setring Isolring;
+//    list SOL = solve(to_solve, "oldring", "nodisplay");
+    list real_sols = list();
+    list tmpl;
+    for(k=1; k<=size(SOL); k++) {
+        if(find(string(SOL[k]),"I")==0 && find(string(SOL[k]),"i")==0) {
+            tmpl = list();
+            for(i=1; i<=size(SOL[k]); i++) {
+                tmpl = tmpl + list(string(SOL[k][i]));
+            }
+            real_sols = real_sols + list(tmpl);
+        }
+    }
+    return(real_sols);
+}
+example {
+    "EXAMPLE:"; echo = 2;
+    ring r = 0, (x,y), dp;
+    number a = 2;
+    number b = 3;
+    ideal j = (x^2-a),(y^3-b);
+    real_solve(j);
+}
+
+proc rootminpoly(list #)
+"
+USAGE: rootminpoly(list #)
+
+RETURN: A root of the current minpoly
+as a string representation of a complex number with
+the given precision #[1] (default: 30).
+E.g. ring r=(0,s),x,dp; minpoly = s^2-2; => rootminpoly() 1.41421356237309504880168872421
+
+ASSUME: The current minpoly is non-zero.
+"
+{
+    int prec = 30;
+    int k, done;
+    if(size(#)>0) {
+        prec = #[1];
+    }
+    short = 0;
+    string str_lag = sprintf("list lag = laguerre_solve(%s);", minpoly);
+    string str_ring = sprintf("ring r_sqrt = (complex,prec,I),(%s),lp;", parstr(basering));
+    execute(str_ring);
+    execute(str_lag);
+//    lag;
+    // choose a real solution, if it exists:
+    done = 0;
+    for(k=1; k<=size(lag) && done==0; k++) {
+        if(find(string(lag[k]),"I")==0) {
+            done = k;
+        }
+    }
+    if(done==0) {
+//        "no real solution.";
+    }
+
+    if(size(lag)>2) {
+        // return the first real solution
+        return(sprintf("%s",lag[done]));
+    }
+
+    if(sprintf("%s",lag[1])[1] == "-") {
+        return(sprintf("%s",lag[2]));
+    } else {
+        if(sprintf("%s",lag[1])[1] == "(") {
+            if(sprintf("%s",lag[1])[2] == "-") {
+                return(sprintf("%s",lag[2]));
+            } else {
+                return(sprintf("%s",lag[1]));
+            }
+        } else {
+            return(sprintf("%s",lag[1]));
+        }
+    }
+    short = 1;
+}
+example
+{
+   "EXAMPLE:"; echo =2;
+   ring r=(0,s),x,dp;
+   minpoly = s^2-2;
+   rootminpoly();
+
+   ring R=(0,s),x,dp;
+   minpoly = s^2+2;
+   rootminpoly();
+}
+
+proc allroots_minpoly(list #)
+"
+USAGE: allroots_minpoly(list #)
+
+RETURN: a list of strings containing all real roots of the minimal polynomial of the active ring.
+
+ASSUME: The current minpoly is non-zero.
+"
+{
+    int prec = 30;
+    int k, done;
+    if(size(#)>0) {
+        prec = #[1];
+    }
+    short = 0;
+    string str_lag = sprintf("list lag = laguerre_solve(%s);", minpoly);
+    string str_ring = sprintf("ring r_sqrt = (complex,prec,I),(%s),lp;", parstr(basering));
+    execute(str_ring);
+    execute(str_lag);
+
+    // only take the real solutions:
+    done = 0;
+    list real_sols = list();
+    for(k=1; k<=size(lag) && done==0; k++) {
+        if(find(string(lag[k]),"I")==0) {
+            real_sols = real_sols + list(string(lag[k]));
+        }
+    }
+    return(real_sols);
+}
+example {
+    "EXAMPLE:"; echo = 2;
+   ring r=(0,s),x,dp;
+   minpoly = s^3-2;
+   allroots_minpoly();
+
+   ring R=(0,s),x,dp;
+   minpoly = s^2-2;
+   allroots_minpoly();
+}
+
+proc decstr2ratstr(string str)
+"
+USAGE: decstr2ratstr(string str)
+Convert a decimal number of not more than 30 digits to a rational number with 14 digits.
+
+REMARK: This procedure still has to be adapted to accept other precisions!
+"
+{
+    ring decR = (complex,30,I),(x),lp;
+    execute("number r="+str+";");
+    execute("r = "+truncdec(r,14)+";");
+    return(real2ratstr(r));
+}
+
+proc real2ratstr(number r)
+"
+USAGE: real2ratstr(number r)
+
+RETURN: A string containing a rational number representing the decimal number r.
+
+ASSUME: The current ring has either real or complex base field.
+"
+{
+    string ratstr = "number("+string(r*number(10000000000000000))+")/number(10000000000000000)";
+    return(ratstr);
+}
+
+proc truncdec(number r, int decs)
+"
+USAGE: truncdec(number r, int decs)
+Truncates a decimal number r to the given number (decs) of digits.
+
+RETURN: A string representing the truncated number.
+"
+{
+    string str = string(r);
+    return(str[1,(decs+2)]);
+}
+
+proc string_of_vars(ideal I)
+"
+USAGE: string_of_vars(ideal I)
+
+RETURN: A string of all variables contained in the ideal I, separated by commas.
+"
+{
+    list listvars = list();
+    intvec v;
+    int i;
+    poly p;
+    for(i=size(I);i>0;i--)
+    {
+        p=I[i];
+        while(p!=0)
+        {
+            v=v+leadexp(p);
+            p=p-lead(p);
+        }
+    }
+    for(i=1; i<=nvars(basering); i++) {
+        if(v[i] > 0) {
+            listvars = listvars + list(var(i));
+        }
+    }
+    string strvars = string(listvars);
+    return(strvars);
+}
diff --git a/Singular/LIB/symodstd.lib b/Singular/LIB/symodstd.lib
new file mode 100644
index 0000000..2488a15
--- /dev/null
+++ b/Singular/LIB/symodstd.lib
@@ -0,0 +1,1580 @@
+////////////////////////////////////////////////////////////////////////////
+version="version symodstd.lib 4.0.0.0 Dec_2013 "; // $Id: 7b032bd0d3432344e18ae4e46fd0f05bf012a596 $
+category = "Commutative Algebra";
+info="
+LIBRARY:  symodstd.lib    Procedures for computing Groebner basis of ideals
+                          being invariant under certain variable permutations.
+
+AUTHOR:   Stefan Steidel, steidel at mathematik.uni-kl.de
+
+OVERVIEW:
+
+   A library for computing the Groebner basis of an ideal in the polynomial
+   ring over the rational numbers, that is invariant under certain permutations
+   of the variables, using the symmetry and modular methods.
+   More precisely let I = <f1,...,fr> be an ideal in Q[x(1),...,x(n)] and
+   sigma a permutation of order k in Sym(n) such that sigma(I) = I.
+   We assume that sigma({f1,...,fr}) = {f1,...,fr}. This can always be obtained
+   by adding sigma(fi) to {f1,...,fr}.
+   To compute a standard basis of I we apply a modification of the modular
+   version of the standard basis algorithm (improving the calculations in
+   positive characteristic). Therefore we only allow primes p such that p-1 is
+   divisible by k. This guarantees the existance of a k-th primitive root of
+   unity in Z/pZ.
+
+PROCEDURES:
+ genSymId(I,sigma);      compute ideal J such that sigma(J) = J and J includes I
+ isSymmetric(I,sigma);   check if I is invariant under permutation sigma
+ primRoot(p,k);          int describing a k-th primitive root of unity in Z/pZ
+ eigenvalues(I,sigma);   list of eigenvalues of generators of I under sigma
+ symmStd(I,sigma);       standard basis of I using invariance of I under sigma
+ syModStd(I,sigma);      SB of I using modular methods and sigma(I) = I
+";
+
+LIB "brnoeth.lib";
+LIB "modstd.lib";
+LIB "parallel.lib";
+LIB "ring.lib";
+
+////////////////////////////////////////////////////////////////////////////////
+
+proc genSymId(ideal I, intvec sigma)
+"USAGE:  genSymId(I,sigma); I ideal, sigma intvec
+ASSUME:  size(sigma) = nvars(basering =: n
+RETURN:  ideal J such that sigma(J) = J and J includes I
+NOTE:    sigma is a permutation of the variables of the basering, i.e.
+@*       sigma: var(i) ----> var(sigma[i]), 1 <= i <= n.
+EXAMPLE: example genSymId; shows an example
+"
+{
+   if(nvars(basering) != size(sigma))
+   {
+      ERROR("The input is no permutation of the ring-variables!!");
+   }
+
+   int i;
+
+   ideal perm;
+   for(i = 1; i <= size(sigma); i++)
+   {
+      perm[size(perm)+1] = var(sigma[i]);
+   }
+
+   map f = basering, perm;
+   ideal J = I;
+   ideal helpJ = I;
+   for(i = 1; i <= order(sigma) - 1; i++)
+   {
+      helpJ = f(helpJ);
+      J = J, helpJ;
+   }
+
+   return(simplify(simplify(J,4),2));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring R = 0,(u,v,w,x,y),dp;
+   intvec pi = 2,3,4,5,1;
+   ideal I = u2v + x3y - w2;
+   genSymId(I,pi);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+proc isSymmetric(ideal I, intvec sigma)
+"USAGE:  isSymmetric(I,sigma); I ideal, sigma intvec
+ASSUME:  size(sigma) = nvars(basering) =: n
+RETURN:  1, if the set of generators of I is invariant under sigma;
+@*       0, if the set of generators of I is not invariant under sigma
+NOTE:    sigma is a permutation of the variables of the basering, i.e.
+@*       sigma: var(i) ----> var(sigma[i]), 1 <= i <= n.
+EXAMPLE: example isSymmetric; shows an example
+"
+{
+   if(nvars(basering) != size(sigma))
+   {
+      ERROR("The input is no permutation of the ring-variables!!");
+   }
+
+   int i, j;
+
+   list L;
+   for(i = 1; i <= size(I); i++)
+   {
+      L[size(L)+1] = I[i];
+   }
+
+   ideal perm;
+   for(i = 1; i <= size(sigma); i++)
+   {
+      perm[size(perm)+1] = var(sigma[i]);
+   }
+
+   map f = basering, perm;
+   ideal J = f(I);
+
+   poly g;
+   while(size(L) > 0)
+   {
+      j = size(L);
+      g = L[1];
+
+      for(i = 1; i <= size(J); i++)
+      {
+         if(g - J[i] == 0)
+         {
+            L = delete(L, 1);
+            break;
+         }
+      }
+
+      if(j == size(L))
+      {
+         return(0);
+      }
+   }
+
+   return(1);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring R = 0,x(1..5),dp;
+   ideal I = cyclic(5);
+   intvec pi = 2,3,4,5,1;
+   isSymmetric(I,pi);
+   intvec tau = 2,5,1,4,3;
+   isSymmetric(I,tau);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+static proc permute(intvec v, intvec P)
+{
+// permute the intvec v according to the permutation given by P
+
+   int s = size(v);
+   int n = size(P);
+   int i;
+   if(s < n)
+   {
+      for(i = s+1; i <= n; i = i+1)
+      {
+         v[i] = 0;
+      }
+      s = size(v);
+   }
+   intvec auxv = v;
+   for(i = 1; i <= n; i = i+1)
+   {
+      auxv[i] = v[P[i]];
+   }
+
+   return(auxv);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+static proc order(intvec sigma)
+{
+// compute the order of sigma in Sym({1,...,n}) with n := size(sigma)
+
+   int ORD = 1;
+   intvec id = 1..size(sigma);
+   intvec tau = sigma;
+
+   while(tau != id)
+   {
+      tau = permute(tau, sigma);
+      ORD = ORD + 1;
+   }
+
+   return(ORD);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+static proc modExpo(bigint x, bigint a, bigint n)
+{
+// compute x^a mod n
+
+   bigint z = 1;
+
+   while(a != 0)
+   {
+      while((a mod 2) == 0)
+      {
+         a = a div 2;
+         x = x^2 mod n;
+      }
+
+      a = a - 1;
+      z = (z*x) mod n;
+   }
+
+   return(z);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+proc primRoot(int p, int k)
+"USAGE:  primRoot(p,k); p,k integers
+ASSUME:  p is a prime and k divides p-1.
+RETURN:  int: a k-th primitive root of unity in Z/pZ
+EXAMPLE: example primRoot; shows an example
+"
+{
+   if(k == 2)
+   {
+      return(-1);
+   }
+
+   if(p == 0)
+   {
+      return(0);
+   }
+
+   int i, j;
+
+   if(((p-1) mod k) != 0)
+   {
+      ERROR("There is no "+string(k)+"-th primitive root of unity "
+             +"in Z/"+string(p)+"Z.");
+      return(0);
+   }
+
+   list PF = primefactors(p-1)[1];
+
+   bigint a;
+
+   for(i = 2; i <= p-1; i++)
+   {
+      a = i;
+
+      for(j = 1; j <= size(PF); j++)
+      {
+         if(modExpo(a, (p-1) div PF[j], p) == 1)
+         {
+            break;
+         }
+      }
+
+      if(j == size(PF)+1)
+      {
+         a = modExpo(a, (p-1) div k, p);
+
+         string str = "int xi = "+string(a);
+         execute(str);
+
+         return(xi);
+      }
+   }
+}
+example
+{ "EXAMPLE:";  echo = 2;
+   primRoot(181,10);
+   ring R = 2147482801, x, lp;
+   number a = primRoot(2147482801,5);
+   a;
+   a^2;
+   a^3;
+   a^4;
+   a^5;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+static proc permMat(intvec sigma, list #)
+{
+// compute an intmat such that i-th row describes sigma^i
+
+   int i;
+   int n = size(sigma);
+
+   if(size(#) == 0)
+   {
+      int ORD = order(sigma);
+   }
+   else
+   {
+      int ORD = #[1];
+   }
+
+   intmat P[ORD][n];
+   intvec sigmai = sigma;
+   for(i = 1; i <= ORD; i++)
+   {
+      P[i,1..n] = sigmai;
+      sigmai = permute(sigmai, sigma);
+   }
+
+   return(P);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+static proc genTransId(intvec sigma, list #)
+{
+// list L of two ideals such that
+// - L[1] describes the transformation and
+// - L[2] describes the retransformation (inverse mapping).
+// ORD is the order of sigma in Sym({1,...,n}) with n := size(sigma) and
+// sigma: {1,...,n} ---> {1,...,n}: sigma(j) = sigma[j]. Since sigma is a
+// permutation of variables it induces an automorphism phi of the
+// basering, more precisely a linear variable transformation which is
+// generated by this procedure. In terms it holds:
+//
+//             phi : basering  --------->  basering
+//                    var(i)     |---->     L[1][i]
+//                    L[2][i]    <----|     var(i)
+
+   int n = nvars(basering);
+
+   if(n != size(sigma))
+   {
+      ERROR("The input is no permutation of the ring-variables!!");
+   }
+
+   int i, j, k;
+
+   if(size(#) == 0)
+   {
+      int CHAR = char(basering);
+      int ORD = order(sigma);
+
+      if((((CHAR - 1) mod ORD) != 0) && (CHAR > 0))
+      {
+         ERROR("Basering of characteristic "+string(CHAR)+" has no "
+                +string(ORD)+"-th primitive root of unity!!");
+      }
+
+      if((CHAR == 0) && (ORD > 2))
+      {
+         "========================================
+          ========================================";
+         "If basering really has a "+string(ORD)+"-th "
+          +"primitive root of unity then insert it as input!!";
+         "========================================
+          ========================================";
+         return(list());
+      }
+      else
+      {
+         int xi = primRoot(CHAR, ORD);
+         number a = xi;
+      }
+   }
+   else
+   {
+      int ORD = #[1];
+      number a = #[2];
+   }
+
+   intmat PERM = permMat(sigma,ORD);
+
+   ideal TR, RETR;
+   poly s_trans;
+   matrix C;
+
+//-------------- retransformation ideal RETR is generated here -----------------
+   for(i = 1; i <= n; i++)
+   {
+      for(j = 0; j < ORD; j++)
+      {
+         for(k = 1; k <= ORD; k++)
+         {
+            // for each variable var(i):
+            // s_trans^(j) = sum_{k=1}^{ORD} a^(k*j)*sigma^k(var(i))
+            // for j = 0,...,ORD-1
+            s_trans = s_trans + a^(k*j)*var(PERM[k,i]);
+         }
+         RETR = RETR + simplify(s_trans, 1);
+         s_trans = 0;
+      }
+   }
+
+//---------------- transformation ideal TR is generated here -------------------
+   for(i = 1; i <= n; i++)
+   {
+      for(j = 1; j <= size(RETR); j++)
+      {
+         C = coeffs(RETR[j], var(i));
+         if(nrows(C) > 1)
+         {
+            // var(j) = RETR[j] = sum_{i in J} c_ij*var(i), J subset {1,...,n},
+            // and therefore var(i) = (sum_{j} s(j)/c_ij)/#(summands)
+            s_trans = s_trans + var(j)/(C[nrows(C),1]);
+         }
+      }
+
+      TR = TR + s_trans/number(size(s_trans));
+      s_trans = 0;
+   }
+
+   return(list(TR,RETR));
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+proc eigenvalues(ideal I, intvec sigma)
+"USAGE:  eigenvalues(I,sigma); I ideal, sigma intvec
+ASSUME:  size(sigma) = nvars(basering) =: n
+RETURN:  list of eigenvalues of generators of I under permutation sigma
+NOTE:    sigma is a permutation of the variables of the basering, i.e.
+         sigma: var(i) ----> var(sigma[i]), 1 <= i <= n.
+EXAMPLE: example eigenvalues; shows an example
+"
+{
+   int i, j;
+
+   def A = basering;
+   int n = nvars(A);
+
+   poly ev;
+   list EV;
+   poly s, help_var;
+   matrix C1, C2;
+
+   ideal perm;
+   for(i = 1; i <= n; i++)
+   {
+      perm[size(perm)+1] = var(sigma[i]);
+   }
+
+   map f = A, perm;
+
+   for(i = 1; i <= size(I); i++)
+   {
+//-------------- s is the image of I[i] under permutation sigma ----------------
+      s = I[i];
+      s = f(s);
+
+      for(j = 1; j <= n; j++)
+      {
+         C1 = coeffs(I[i], var(j));
+         C2 = coeffs(s, var(j));
+         if(nrows(C1) > 1)
+         {
+            ev = C2[nrows(C2),1]/C1[nrows(C1),1];
+
+//------ Furthermore check that I[i] is eigenvector of permutation sigma. ------
+            if(s == ev*I[i])
+            {
+               break;
+            }
+            else
+            {
+               ERROR("I["+string(i)+"] is no eigenvector "
+                      +"of permutation sigma!!");
+            }
+         }
+      }
+
+      EV[size(EV)+1] = ev;
+   }
+
+   return(EV);
+}
+example
+{ "EXAMPLE:";  echo = 2;
+   ring R = 11, x(1..5), dp;
+   poly p1 = x(1)+x(2)+x(3)+x(4)+x(5);
+   poly p2 = x(1)+4*x(2)+5*x(3)-2*x(4)+3*x(5);
+   poly p3 = x(1)+5*x(2)+3*x(3)+4*x(4)-2*x(5);
+   poly p4 = x(1)-2*x(2)+4*x(3)+3*x(4)+5*x(5);
+   poly p5 = x(1)+3*x(2)-2*x(3)+5*x(4)+4*x(5);
+   ideal I = p1,p2,p3,p4,p5;
+   intvec tau = 2,3,4,5,1;
+   eigenvalues(I,tau);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+proc symmStd(ideal I, intvec sigma, list #)
+"USAGE:  symmStd(I,sigma,#); I ideal, sigma intvec
+ASSUME:  size(sigma) = nvars(basering) =: n, basering has an order(sigma)-th
+         primitive root of unity a (if char(basering) > 0) and sigma(I) = I
+RETURN:  ideal, a standard basis of I
+NOTE:    Assuming that the ideal I is invariant under the variable permutation
+         sigma and the basering has an order(sigma)-th primitive root of unity
+         the procedure uses linear transformation of variables in order to
+         improve standard basis computation.
+         If char(basering) = 0 all computations are done in the polynomial ring
+         over the smallest field extension that has an order(sigma)-th primitive
+         root of unity.
+EXAMPLE: example symmStd; shows an example
+"
+{
+   if((nvars(basering) != size(sigma)) || (!isSymmetric(I,sigma)))
+   {
+      ERROR("The input is no permutation of the ring-variables!!");
+   }
+
+   option(redSB);
+
+   def R = basering;
+   int CHAR = char(R);
+   int n = nvars(R);
+
+   int t;
+
+//-------- (1) Compute the order of variable permutation sigma. ----------------
+   int ORD = order(sigma);
+   if((((CHAR - 1) mod ORD) != 0) && (CHAR > 0))
+   {
+      ERROR("Basering of characteristic "+string(CHAR)+" has no "
+             +string(ORD)+"-th primitive root of unity!!");
+   }
+
+//-------- (2) Compute the order(sigma)-th primitive root of unity -------------
+//--------     in basering or move to ring extension.              -------------
+   if((CHAR == 0) && (ORD > 2))
+   {
+      def save_ring=basering;
+      ring ext_ring=0,p,lp;
+      def S = changechar(ringlist(ext_ring),save_ring);
+      setring S;
+      kill ext_ring;
+      kill save_ring;
+      minpoly = rootofUnity(ORD);
+      ideal I = imap(R, I);
+      number a = p;
+   }
+   else
+   {
+      int xi = primRoot(CHAR, ORD);
+      number a = xi;
+   }
+
+//--------- (3) Define the linear transformation of variables with -------------
+//---------     respect to sigma.                                  -------------
+   list L = genTransId(sigma,ORD,a);
+   ideal TR = L[1];
+   ideal RETR = L[2];
+
+//--------- (4) Compute the eigenvalues of the "new" variables of --------------
+//---------     sigma after transformation.                       --------------
+   list EV = eigenvalues(RETR, sigma);
+
+//--------- (5) Transformation of the input-ideal is done here. ----------------
+   map f = basering, TR;
+   t = timer;
+   ideal I_trans = f(I);
+   if(printlevel >= 11) { "Transformation: "+string(timer - t)+" seconds"; }
+
+//--------- (6) Compute a standard basis of the transformed ideal. -------------
+   t = timer;
+   if(size(#) > 0) { ideal sI_trans = std(I_trans, #[1]); }
+   else { ideal sI_trans = std(I_trans); }
+   if(printlevel >= 11) { "1st Groebner basis: "+string(timer - t)+" seconds"; }
+
+//--------- (7) Retransformation is done here. ---------------------------------
+   map g = basering, RETR;
+   t = timer;
+   ideal I_retrans = g(sI_trans);
+   if(printlevel >= 11) { "Reverse Transformation: "+string(timer - t)
+                           +" seconds"; }
+
+//--------- (8) Compute a standard basis of the retransformaed ideal -----------
+//---------     which is then a standard basis of the input-ideal.   -----------
+   t = timer;
+   ideal sI_retrans = std(I_retrans);
+   if(printlevel >= 11) { "2nd Groebner basis: "+string(timer - t)+" seconds"; }
+
+   if((CHAR == 0) && (ORD > 2))
+   {
+      setring R;
+      ideal sI_retrans = fetch(S, sI_retrans);
+      return(sI_retrans);
+   }
+   else
+   {
+      return(sI_retrans);
+   }
+}
+example
+{ "EXAMPLE:";  echo = 2;
+   ring R = 0, x(1..4), dp;
+   ideal I = cyclic(4);
+   I;
+   intvec pi = 2,3,4,1;
+   ideal sI = symmStd(I,pi);
+   sI;
+
+   ring S = 31, (x,y,z), dp;
+   ideal J;
+   J[1] = xy-y2+xz;
+   J[2] = xy+yz-z2;
+   J[3] = -x2+xz+yz;
+   intvec tau = 3,1,2;
+   ideal sJ = symmStd(J,tau);
+   sJ;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+proc divPrimeTest(def II, bigint p, int k)
+{
+   if((p - 1) mod k != 0) { return(0); }
+
+   if(typeof(II) == "string")
+   {
+      execute("ideal I = "+II+";");
+   }
+   else
+   {
+      ideal I = II;
+   }
+
+   int i,j;
+   poly f;
+   number cnt;
+   for(i = 1; i <= size(I); i++)
+   {
+      f = cleardenom(I[i]);
+      if(f == 0) { return(0); }
+      cnt = leadcoef(I[i])/leadcoef(f);
+      if((bigint(numerator(cnt)) mod p) == 0) { return(0); }
+      if((bigint(denominator(cnt)) mod p) == 0) { return(0); }
+      for(j = size(f); j > 0; j--)
+      {
+         if((bigint(leadcoef(f[j])) mod p) == 0) { return(0); }
+      }
+   }
+   return(1);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+proc divPrimeList(int k, ideal I, int n, list #)
+{
+// the intvec of n greatest primes p <= 2147483647 (resp. n greatest primes
+// < L[size(L)] union with L) such that each (p-1) is divisible by k, and none
+// of these primes divides any coefficient occuring in I
+// --> similar to procedure primeList in modstd.lib
+
+   intvec L;
+   int i,p;
+   int ncores = 1;
+
+//-----------------  Initialize optional parameter ncores  ---------------------
+   if(size(#) > 0)
+   {
+      if(size(#) == 1)
+      {
+         if(typeof(#[1]) == "int")
+         {
+            ncores = #[1];
+            # = list();
+         }
+      }
+      else
+      {
+         ncores = #[2];
+      }
+   }
+
+   if(size(#) == 0)
+   {
+      p = 2147483647;
+      while(!divPrimeTest(I,p,k))
+      {
+         p = prime(p-1);
+         if(p == 2) { ERROR("No more primes."); }
+      }
+      L[1] = p;
+   }
+   else
+   {
+      L = #[1];
+      p = prime(L[size(L)]-1);
+      while(!divPrimeTest(I,p,k))
+      {
+         p = prime(p-1);
+         if(p == 2) { ERROR("No more primes."); }
+      }
+      L[size(L)+1] = p;
+   }
+   if(p == 2) { ERROR("No more primes."); }
+   if(ncores == 1)
+   {
+      for(i = 2; i <= n; i++)
+      {
+         p = prime(p-1);
+         while(!divPrimeTest(I,p,k))
+         {
+            p = prime(p-1);
+            if(p == 2) { ERROR("no more primes"); }
+         }
+         L[size(L)+1] = p;
+      }
+   }
+   else
+   {
+      int neededSize = size(L)+n-1;;
+      list parallelResults;
+      list arguments;
+      int neededPrimes = neededSize-size(L);
+      while(neededPrimes > 0)
+      {
+         arguments = list();
+         for(i = ((neededPrimes div ncores)+1-(neededPrimes%ncores == 0))
+            *ncores; i > 0; i--)
+         {
+            p = prime(p-1);
+            if(p == 2) { ERROR("no more primes"); }
+            arguments[i] = list("I", p, k);
+         }
+         parallelResults = parallelWaitAll("divPrimeTest", arguments, 0,
+            ncores);
+         for(i = size(arguments); i > 0; i--)
+         {
+            if(parallelResults[i])
+            {
+               L[size(L)+1] = arguments[i][2];
+            }
+         }
+         neededPrimes = neededSize-size(L);
+      }
+      if(size(L) > neededSize)
+      {
+         L = L[1..neededSize];
+      }
+   }
+   return(L);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r = 0,(x,y,z),dp;
+   ideal I = 2147483647x+y, z-181;
+   intvec L = divPrimeList(4,I,10,10);
+   size(L);
+   L[1];
+   L[size(L)];
+   L = divPrimeList(4,I,5,L,5);
+   size(L);
+   L[size(L)];
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+proc spTestSB(ideal I, ideal J, list L, intvec sigma, int variant, list #)
+"USAGE:  spTestSB(I,J,L,sigma,variant,#); I,J ideals, L intvec of primes,
+                                          sigma intvec, variant integer
+RETURN:  1 (resp. 0) if for a randomly chosen prime p, that is not in L and
+         divisible by the order of sigma, J mod p is (resp. is not) a standard
+         basis of I mod p
+EXAMPLE: example spTestSB; shows an example
+"
+{
+   int i,j,k,p;
+   int ORD = order(sigma);
+   def R = basering;
+   list r = ringlist(R);
+
+   while(!j)
+   {
+      j = 1;
+      while(((p - 1) mod ORD) != 0)
+      {
+         p = prime(random(1000000000,2134567879));
+         if(p == 2){ ERROR("no more primes"); }
+      }
+      for(i = 1; i <= size(L); i++)
+      {
+         if(p == L[i]){ j = 0; break }
+      }
+      if(j)
+      {
+         for(i = 1; i <= ncols(I); i++)
+         {
+            for(k = 2; k <= size(I[i]); k++)
+            {
+               if((bigint(denominator(leadcoef(I[i][k]))) mod p) == 0){ j = 0; break; }
+            }
+            if(!j){ break; }
+         }
+      }
+      if(j)
+      {
+         if(!primeTest(I,p)) { j = 0; }
+      }
+   }
+   r[1] = p;
+   def @R = ring(r);
+   setring @R;
+   ideal I = imap(R,I);
+   ideal J = imap(R,J);
+   attrib(J,"isSB",1);
+
+   int t = timer;
+   j = 1;
+   if(isIncluded(I,J) == 0){ j = 0; }
+
+   if(printlevel >= 11)
+   {
+      "isIncluded(I,J) takes "+string(timer - t)+" seconds";
+      "j = "+string(j);
+   }
+
+   t = timer;
+   if(j)
+   {
+      if(size(#) > 0)
+      {
+         ideal K = smpStd(I,sigma,p,variant,#[1])[1];
+      }
+      else
+      {
+         ideal K = smpStd(I,sigma,p,variant)[1];
+      }
+      t = timer;
+      if(isIncluded(J,K) == 0){ j = 0; }
+
+      if(printlevel >= 11)
+      {
+         "isIncluded(J,K) takes "+string(timer - t)+" seconds";
+         "j = "+string(j);
+      }
+   }
+   setring R;
+   return(j);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   intvec L = 2,3,5;
+   ring r = 0,(x,y,z),dp;
+   ideal I = x+1,y+1;
+   intvec sigma = 2,1,3;
+   ideal J = x+1,y;
+   spTestSB(I,J,L,sigma,2);
+   spTestSB(J,I,L,sigma,2);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+proc smpStd(ideal I, intvec sigma, int p, int variant, list #)
+"USAGE:  smpStd(I,sigma,p,#); I ideal, sigma intvec, p integer, variant integer
+ASSUME:  If size(#) > 0, then #[1] is an intvec describing the Hilbert series.
+RETURN:  ideal - a standard basis of I mod p, integer - p
+NOTE:    The procedure computes a standard basis of the ideal I modulo p and
+         fetches the result to the basering. If size(#) > 0 the Hilbert driven
+         standard basis computation symmStd(.,.,#[1]) is used in symmStd.
+         The standard basis computation modulo p does also vary depending on the
+         integer variant, namely
+@*       - variant = 1: symmStd(.,.,#[1]) resp. symmStd,
+@*       - variant = 2: symmStd,
+@*       - variant = 3: homog. - symmStd(.,.,#[1]) resp. symmStd - dehomog.,
+@*       - variant = 4: fglm.
+EXAMPLE: example smpStd; shows an example
+"
+{
+   def R0 = basering;
+   list rl = ringlist(R0);
+   rl[1] = p;
+   def @r = ring(rl);
+   setring @r;
+   ideal i = fetch(R0,I);
+
+   option(redSB);
+
+   if(variant == 1)
+   {
+      if(size(#) > 0)
+      {
+         i = symmStd(i, sigma, #[1]);
+      }
+      else
+      {
+         i = symmStd(i, sigma);
+      }
+   }
+
+   if(variant == 2)
+   {
+      i = symmStd(i, sigma);
+   }
+
+   if(variant == 3)
+   {
+      list rl = ringlist(@r);
+      int nvar at r = nvars(@r);
+
+      int k;
+      intvec w;
+      for(k = 1; k <= nvar at r; k++)
+      {
+         w[k] = deg(var(k));
+      }
+      w[nvar at r + 1] = 1;
+
+      rl[2][nvar at r + 1] = "homvar";
+      rl[3][2][2] = w;
+
+      def HomR = ring(rl);
+      setring HomR;
+      ideal i = imap(@r, i);
+      i = homog(i, homvar);
+      intvec tau = sigma, size(sigma)+1;
+
+      if(size(#) > 0)
+      {
+         if(w == 1)
+         {
+            i = symmStd(i, tau, #[1]);
+         }
+         else
+         {
+            i = symmStd(i, tau, #[1], w);
+         }
+      }
+      else
+      {
+         i = symmStd(i, tau);
+      }
+
+      i = subst(i, homvar, 1);
+      i = simplify(i, 34);
+
+      setring @r;
+      i = imap(HomR, i);
+      i = interred(i);
+      kill HomR;
+   }
+
+   if(variant == 4)
+   {
+      def R1 = changeord(list(list("dp",1:nvars(basering))));
+      setring R1;
+      ideal i = fetch(@r,i);
+      i = symmStd(i, sigma);
+      setring @r;
+      i = fglm(R1,i);
+   }
+
+   setring R0;
+   return(list(fetch(@r,i),p));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r1 = 0, x(1..4), dp;
+   ideal I = cyclic(4);
+   intvec sigma = 2,3,4,1;
+   int p = 181;
+   list P = smpStd(I,sigma,p,2);
+   P;
+
+   ring r2 = 0, x(1..5), lp;
+   ideal I = cyclic(5);
+   intvec tau = 2,3,4,5,1;
+   int q = 31981;
+   list Q = smpStd(I,tau,q,4);
+   Q;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+proc syModStd(ideal I, intvec sigma, list #)
+"USAGE:  syModStd(I,sigma); I ideal, sigma intvec
+ASSUME:  size(sigma) = nvars(basering) and sigma(I) = I. If size(#) > 0, then
+         # contains either 1, 2 or 4 integers such that
+@*       - #[1] is the number of available processors for the computation,
+@*       - #[2] is an optional parameter for the exactness of the computation,
+                if #[2] = 1, the procedure computes a standard basis for sure,
+@*       - #[3] is the number of primes until the first lifting,
+@*       - #[4] is the constant number of primes between two liftings until
+           the computation stops.
+RETURN:  ideal, a standard basis of I if no warning appears;
+NOTE:    The procedure computes a standard basis of the ideal I (over the
+         rational numbers) by using modular methods and the fact that I is
+         invariant under the variable permutation sigma.
+         By default the procedure computes a standard basis of I for sure, but
+         if the optional parameter #[2] = 0, it computes a standard basis of I
+         with high probability.
+         The procedure distinguishes between different variants for the standard
+         basis computation in positive characteristic depending on the ordering
+         of the basering, the parameter #[2] and if the ideal I is homogeneous.
+@*       - variant = 1, if I is homogeneous,
+@*       - variant = 2, if I is not homogeneous, 1-block-ordering,
+@*       - variant = 3, if I is not homogeneous, complicated ordering (lp or
+                        > 1 block),
+@*       - variant = 4, if I is not homogeneous, ordering lp, dim(I) = 0.
+EXAMPLE: example syModStd; shows an example
+"
+{
+   if((nvars(basering) != size(sigma)) || (!isSymmetric(I,sigma)))
+   {
+      ERROR("The input is no permutation of the ring-variables!!");
+   }
+
+   int TT = timer;
+   int RT = rtimer;
+
+   def R0 = basering;
+   list rl = ringlist(R0);
+   if((npars(R0) > 0) || (rl[1] > 0))
+   {
+      ERROR("Characteristic of basering should be zero, basering should
+             have no parameters.");
+   }
+
+   int index = 1;
+   int i,k,c;
+   int j = 1;
+   int pTest, sizeTest;
+   int en = 2134567879;
+   int an = 1000000000;
+   bigint N;
+   int ORD = order(sigma);
+
+//--------------------  Initialize optional parameters  ------------------------
+   if(size(#) > 0)
+   {
+      if(size(#) == 1)
+      {
+         int n1 = #[1];
+         int exactness = 1;
+         if(n1 >= 10)
+         {
+            int n2 = n1 + 1;
+            int n3 = n1;
+         }
+         else
+         {
+            int n2 = 10;
+            int n3 = 10;
+         }
+      }
+      if(size(#) == 2)
+      {
+         int n1 = #[1];
+         int exactness = #[2];
+         if(n1 >= 10)
+         {
+            int n2 = n1 + 1;
+            int n3 = n1;
+         }
+         else
+         {
+            int n2 = 10;
+            int n3 = 10;
+         }
+      }
+      if(size(#) == 4)
+      {
+         int n1 = #[1];
+         int exactness = #[2];
+         if(n1 >= #[3])
+         {
+            int n2 = n1 + 1;
+         }
+         else
+         {
+            int n2 = #[3];
+         }
+         if(n1 >= #[4])
+         {
+            int n3 = n1;
+         }
+         else
+         {
+            int n3 = #[4];
+         }
+      }
+   }
+   else
+   {
+      int n1 = 1;
+      int exactness = 1;
+      int n2 = 10;
+      int n3 = 10;
+   }
+
+   if(printlevel >= 10)
+   {
+      "n1 = "+string(n1)+", n2 = "+string(n2)+", n3 = "+string(n3)
+       +", exactness = "+string(exactness);
+   }
+
+//-------------------------- Save current options ------------------------------
+   intvec opt = option(get);
+
+   option(redSB);
+
+//--------------------  Initialize the list of primes  -------------------------
+   int tt = timer;
+   int rt = rtimer;
+   intvec L = divPrimeList(ORD,I,n2,n1);
+   if(printlevel >= 10)
+   {
+      "CPU-time for divPrimeList: "+string(timer-tt)+" seconds.";
+      "Real-time for divPrimeList: "+string(rtimer-rt)+" seconds.";
+   }
+
+//---------------------  Decide which variant to take  -------------------------
+   int variant;
+   int h = homog(I);
+
+   tt = timer;
+   rt = rtimer;
+
+   if(!hasMixedOrdering())
+   {
+      if(h)
+      {
+         variant = 1;
+         if(printlevel >= 10) { "variant = 1"; }
+
+         rl[1] = L[5];
+         def @r = ring(rl);
+         setring @r;
+         def @s = changeord(list(list("dp",1:nvars(basering))));
+         setring @s;
+         ideal I = std(fetch(R0,I));
+         intvec hi = hilb(I,1);
+         setring R0;
+         kill @r, at s;
+      }
+      else
+      {
+         string ordstr_R0 = ordstr(R0);
+         int neg = 1 - attrib(R0,"global");
+
+         if((find(ordstr_R0, "M") > 0) || (find(ordstr_R0, "a") > 0) || neg)
+         {
+            variant = 2;
+            if(printlevel >= 10) { "variant = 2"; }
+         }
+         else
+         {
+            string order;
+            if(system("nblocks") <= 2)
+            {
+               if(find(ordstr_R0, "M") + find(ordstr_R0, "lp")
+                                       + find(ordstr_R0, "rp") <= 0)
+               {
+                  order = "simple";
+               }
+            }
+
+            if((order == "simple") || (size(rl) > 4))
+            {
+               variant = 2;
+               if(printlevel >= 10) { "variant = 2"; }
+            }
+            else
+            {
+               rl[1] = L[5];
+               def @r = ring(rl);
+               setring @r;
+
+               def @s = changeord(list(list("dp",1:nvars(basering))));
+               setring @s;
+               ideal I = std(fetch(R0,I));
+               if(dim(I) == 0)
+               {
+                  variant = 4;
+                  if(printlevel >= 10) { "variant = 4"; }
+               }
+               else
+               {
+                  variant = 3;
+                  if(printlevel >= 10) { "variant = 3"; }
+
+                  int nvar at r = nvars(@r);
+                  intvec w;
+                  for(i = 1; i <= nvar at r; i++)
+                  {
+                     w[i] = deg(var(i));
+                  }
+                  w[nvar at r + 1] = 1;
+
+                  list hiRi = hilbRing(fetch(R0,I),w);
+                  intvec W = hiRi[2];
+                  @s = hiRi[1];
+                  setring @s;
+                  intvec tau = sigma, size(sigma)+1;
+
+                  Id(1) = symmStd(Id(1),tau);
+                  intvec hi = hilb(Id(1), 1, W);
+               }
+
+               setring R0;
+               kill @r, at s;
+            }
+         }
+      }
+   }
+   else
+   {
+      if(exactness == 1) { return(groebner(I)); }
+      if(h)
+      {
+         variant = 1;
+         if(printlevel >= 10) { "variant = 1"; }
+         rl[1] = L[5];
+         def @r = ring(rl);
+         setring @r;
+         def @s = changeord(list(list("dp",1:nvars(basering))));
+         setring @s;
+         ideal I = std(fetch(R0,I));
+         intvec hi = hilb(I,1);
+         setring R0;
+         kill @r, at s;
+      }
+      else
+      {
+         string ordstr_R0 = ordstr(R0);
+         int neg = 1 - attrib(R0,"global");
+
+         if((find(ordstr_R0, "M") > 0) || (find(ordstr_R0, "a") > 0) || neg)
+         {
+            variant = 2;
+            if(printlevel >= 10) { "variant = 2"; }
+         }
+         else
+         {
+            string order;
+            if(system("nblocks") <= 2)
+            {
+               if(find(ordstr_R0, "M") + find(ordstr_R0, "lp")
+                                       + find(ordstr_R0, "rp") <= 0)
+               {
+                  order = "simple";
+               }
+            }
+
+            if((order == "simple") || (size(rl) > 4))
+            {
+               variant = 2;
+               if(printlevel >= 10) { "variant = 2"; }
+            }
+            else
+            {
+               variant = 3;
+               if(printlevel >= 10) { "variant = 3"; }
+
+               rl[1] = L[5];
+               def @r = ring(rl);
+               setring @r;
+               int nvar at r = nvars(@r);
+               intvec w;
+               for(i = 1; i <= nvar at r; i++)
+               {
+                  w[i] = deg(var(i));
+               }
+               w[nvar at r + 1] = 1;
+
+               list hiRi = hilbRing(fetch(R0,I),w);
+               intvec W = hiRi[2];
+               def @s = hiRi[1];
+               setring @s;
+               intvec tau = sigma, size(sigma)+1;
+
+               Id(1) = symmStd(Id(1),tau);
+               intvec hi = hilb(Id(1), 1, W);
+
+               setring R0;
+               kill @r, at s;
+            }
+         }
+      }
+   }
+
+   list P,T1,T2,T3,LL;
+
+   ideal J,K,H;
+
+//-----  If there is more than one processor available, we parallelize the  ----
+//-----  main standard basis computations in positive characteristic        ----
+
+   if(n1 > 1)
+   {
+      ideal I_for_fork = I;
+      export(I_for_fork);           // I available for each link
+
+//-----  Create n1 links l(1),...,l(n1), open all of them and compute  ---------
+//-----  standard basis for the primes L[2],...,L[n1 + 1].             ---------
+
+      for(i = 1; i <= n1; i++)
+      {
+         //link l(i) = "MPtcp:fork";
+         link l(i) = "ssi:fork";
+         open(l(i));
+         if((variant == 1) || (variant == 3))
+         {
+            write(l(i), quote(smpStd(I_for_fork, eval(sigma), eval(L[i + 1]),
+                                                 eval(variant), eval(hi))));
+         }
+         if((variant == 2) || (variant == 4))
+         {
+            write(l(i), quote(smpStd(I_for_fork, eval(sigma), eval(L[i + 1]),
+                                                 eval(variant))));
+         }
+      }
+
+      int t = timer;
+      if((variant == 1) || (variant == 3))
+      {
+         P = smpStd(I_for_fork, sigma, L[1], variant, hi);
+      }
+      if((variant == 2) || (variant == 4))
+      {
+         P = smpStd(I_for_fork, sigma, L[1], variant);
+      }
+      t = timer - t;
+      if(t > 60) { t = 60; }
+      int i_sleep = system("sh", "sleep "+string(t));
+      T1[1] = P[1];
+      T2[1] = bigint(P[2]);
+      index++;
+
+      j = j + n1 + 1;
+   }
+
+//--------------  Main standard basis computations in positive  ----------------
+//----------------------  characteristic start here  ---------------------------
+
+   list arguments_farey, results_farey;
+
+   while(1)
+   {
+      tt = timer; rt = rtimer;
+
+      if(printlevel >= 10) { "size(L) = "+string(size(L)); }
+
+      if(n1 > 1)
+      {
+         while(j <= size(L) + 1)
+         {
+            for(i = 1; i <= n1; i++)
+            {
+               //--- ask if link l(i) is ready otherwise sleep for t seconds ---
+               if(status(l(i), "read", "ready"))
+               {
+                  //--- read the result from l(i) ---
+                  P = read(l(i));
+                  T1[index] = P[1];
+                  T2[index] = bigint(P[2]);
+                  index++;
+
+                  if(j <= size(L))
+                  {
+                     if((variant == 1) || (variant == 3))
+                     {
+                        write(l(i), quote(smpStd(I_for_fork, eval(sigma),
+                                        eval(L[j]), eval(variant), eval(hi))));
+                        j++;
+                     }
+                     if((variant == 2) || (variant == 4))
+                     {
+                        write(l(i), quote(smpStd(I_for_fork, eval(sigma),
+                                        eval(L[j]), eval(variant))));
+                        j++;
+                     }
+                  }
+                  else
+                  {
+                     k++;
+                     close(l(i));
+                  }
+               }
+            }
+            //--- k describes the number of closed links ---
+            if(k == n1)
+            {
+               j++;
+            }
+            i_sleep = system("sh", "sleep "+string(t));
+         }
+      }
+      else
+      {
+         while(j <= size(L))
+         {
+            if((variant == 1) || (variant == 3))
+            {
+               P = smpStd(I, sigma, L[j], variant, hi);
+            }
+            if((variant == 2) || (variant == 4))
+            {
+               P = smpStd(I, sigma, L[j], variant);
+            }
+
+            T1[index] = P[1];
+            T2[index] = bigint(P[2]);
+            index++;
+            j++;
+         }
+      }
+
+      if(printlevel >= 10)
+      {
+         "CPU-time for computing list is "+string(timer - tt)+" seconds.";
+         "Real-time for computing list is "+string(rtimer - rt)+" seconds.";
+      }
+
+//------------------------  Delete unlucky primes  -----------------------------
+//-------------  unlucky if and only if the leading ideal is wrong  ------------
+
+      LL = deleteUnluckyPrimes(T1,T2,h);
+      T1 = LL[1];
+      T2 = LL[2];
+
+//-------------------  Now all leading ideals are the same  --------------------
+//-------------------  Lift results to basering via farey  ---------------------
+
+      tt = timer; rt = rtimer;
+      N = T2[1];
+      for(i = 2; i <= size(T2); i++) { N = N*T2[i]; }
+      H = chinrem(T1,T2);
+      if(n1 == 1)
+      {
+         J = farey(H,N);
+      }
+      else
+      {
+         for(i = ncols(H); i > 0; i--)
+         {
+            arguments_farey[i] = list(ideal(H[i]), N);
+         }
+         results_farey = parallelWaitAll("farey", arguments_farey, 0, n1);
+         for(i = ncols(H); i > 0; i--)
+         {
+            J[i] = results_farey[i][1];
+         }
+      }
+      if(printlevel >= 10)
+      {
+         "CPU-time for lifting-process is "+string(timer - tt)+" seconds.";
+         "Real-time for lifting-process is "+string(rtimer - rt)+" seconds.";
+      }
+
+//----------------  Test if we already have a standard basis of I --------------
+
+      tt = timer; rt = rtimer;
+      if((variant == 1) || (variant == 3))
+      {
+         pTest = spTestSB(I,J,L,sigma,variant,hi);
+      }
+      if((variant == 2) || (variant == 4))
+      {
+         pTest = spTestSB(I,J,L,sigma,variant);
+      }
+
+      if(printlevel >= 10)
+      {
+         "CPU-time for pTest is "+string(timer - tt)+" seconds.";
+         "Real-time for pTest is "+string(rtimer - rt)+" seconds.";
+      }
+
+      if(pTest)
+      {
+         if(printlevel >= 10)
+         {
+            "CPU-time for computation without final tests is "
+            +string(timer - TT)+" seconds.";
+            "Real-time for computation without final tests is "
+            +string(rtimer - RT)+" seconds.";
+         }
+
+         attrib(J,"isSB",1);
+
+         if(exactness == 0)
+         {
+            option(set, opt);
+            if(n1 > 1) { kill I_for_fork; }
+            return(J);
+         }
+
+         if(exactness == 1)
+         {
+            tt = timer; rt = rtimer;
+            sizeTest = 1 - isIncluded(I,J,n1);
+
+            if(printlevel >= 10)
+            {
+               "CPU-time for checking if I subset <G> is "
+               +string(timer - tt)+" seconds.";
+               "Real-time for checking if I subset <G> is "
+               +string(rtimer - rt)+" seconds.";
+            }
+
+            if(sizeTest == 0)
+            {
+               tt = timer; rt = rtimer;
+               K = std(J);
+
+               if(printlevel >= 10)
+               {
+                  "CPU-time for last std-computation is "
+                  +string(timer - tt)+" seconds.";
+                  "Real-time for last std-computation is "
+                  +string(rtimer - rt)+" seconds.";
+               }
+
+               if(size(reduce(K,J)) == 0)
+               {
+                  option(set, opt);
+                  if(n1 > 1) { kill I_for_fork; }
+                  return(J);
+               }
+            }
+         }
+      }
+
+//--------------  We do not already have a standard basis of I  ----------------
+//-----------  Therefore do the main computation for more primes  --------------
+
+      T1 = H;
+      T2 = N;
+      index = 2;
+
+      j = size(L) + 1;
+      tt = timer; rt = rtimer;
+      L = divPrimeList(ORD,I,n3,L,n1);
+      if(printlevel >= 10)
+      {
+         "CPU-time for divPrimeList: "+string(timer-tt)+" seconds.";
+         "Real-time for divPrimeList: "+string(rtimer-rt)+" seconds.";
+      }
+
+      if(n1 > 1)
+      {
+         for(i = 1; i <= n1; i++)
+         {
+            open(l(i));
+            if((variant == 1) || (variant == 3))
+            {
+               write(l(i), quote(smpStd(I_for_fork, eval(sigma), eval(L[j+i-1]),
+                                                    eval(variant), eval(hi))));
+            }
+            if((variant == 2) || (variant == 4))
+            {
+               write(l(i), quote(smpStd(I_for_fork, eval(sigma), eval(L[j+i-1]),
+                                                    eval(variant))));
+            }
+         }
+         j = j + n1;
+         k = 0;
+      }
+   }
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring R1 = 0, (x,y,z), dp;
+   ideal I;
+   I[1] = -2xyz4+xz5+xz;
+   I[2] = -2xyz4+yz5+yz;
+   intvec sigma = 2,1,3;
+   ideal sI = syModStd(I,sigma);
+   sI;
+
+   ring R2 = 0, x(1..4), dp;
+   ideal I = cyclic(4);
+   I;
+   intvec pi = 2,3,4,1;
+   ideal sJ1 = syModStd(I,pi,1);
+   ideal sJ2 = syModStd(I,pi,1,0);
+   size(reduce(sJ1,sJ2));
+   size(reduce(sJ2,sJ1));
+}
diff --git a/Singular/LIB/tasks.lib b/Singular/LIB/tasks.lib
new file mode 100644
index 0000000..4b54f08
--- /dev/null
+++ b/Singular/LIB/tasks.lib
@@ -0,0 +1,1320 @@
+//////////////////////////////////////////////////////////////////////
+version="version tasks.lib 4.0.0.0 Dec_2013 "; // $Id: 9c9ecb6bd816d6b914cdf4a7a223d8aa98905ed0 $
+category="General purpose";
+info="
+LIBRARY:   tasks.lib  A parallel framework based on tasks
+
+AUTHOR:    Andreas Steenpass, e-mail: steenpass at mathematik.uni-kl.de
+
+OVERVIEW:
+This library provides a parallel framework based on tasks. It introduces a new
+Singular type @code{task}; an object of this type is a command (given by a
+string) applied to a list of arguments. Tasks can be computed in parallel via
+the procedures in this library and they can even be started recursively, i.e.
+from within other tasks.
+
+tasks.lib respects the limits for computational resources defined
+in @ref{resources_lib}, i.e., all tasks within the same Singular session will
+not use more computational resources than provided via resources.lib, even if
+tasks are started recursively.
+
+The Singular library @ref{parallel_lib} provides implementations of several
+parallel 'skeletons' based on tasks.lib.
+
+KEYWORDS:  parallelization; distributed computing; task
+
+SEE ALSO:  resources_lib, parallel_lib
+
+PROCEDURES:
+  createTask();    create a task
+  killTask();      kill a task
+  copyTask();      copy a task
+  compareTasks();  compare two tasks
+  printTask();     print a task
+  startTasks();    start tasks
+  stopTask();      stop a task
+  waitTasks();     wait for a certain number of tasks
+  waitAllTasks();  wait for all tasks
+  pollTask();      poll a task
+  getCommand();    get the command of a task
+  getArguments();  get the arguments of a task
+  getResult();     get the result of a task
+  getState();      get the state of a task
+";
+
+/*
+RATIONALE FOR DEVELOPERS
+
+The Singular type 'task'
+------------------------
+tasks.lib introduces a Singular type 'task' which makes use of a pointer-like
+model in order to avoid unnecessary copying of data. 'task' is defined as a
+newstruct whose only member is 'int index'. This index points to an entry in
+the lib-internal list 'tasks'. The elements of this list are of the type
+'internal_task' which is defined as a newstruct with the following members:
+int id         - the internal ID
+string command - the command
+list arguments - the arguments
+def result     - the result
+string state   - the current state, see 'The life cycle of a task'
+list links     - control handles, see 'Links'
+int linkID     - the ID of the control handles
+
+
+The life cycle of a task
+------------------------
+'uninitialized' --> 'created' --> 'started' --> 'completed'
+                                     | ^
+                                     v |
+                                  'stopped'
+
+The state of a task t is 'uninitialized' iff
+(t.index == 0) or (typeof(tasks[t.index]) != "internal_task").
+
+A task can be reset to 'uninitialized' by killTask() at any time.
+
+
+Assigned members for 'internal_task'
+------------------------------------
+For each state, the following members of an internal_task must be assigned:
+
+created:       command arguments        state
+started:    id command arguments        state links linkID
+stopped:       command arguments        state
+completed:     command arguments result state
+
+All other members should be wiped out.
+
+Local supervisors
+-----------------
+A call of 'startTasks(t(1..n));' for tasks t(1), ..., t(n) creates a child
+process which plays the role of a supervisor for these tasks. The computation
+of the tasks is done in child processes of the supervisor.
+
+The supervisor assigns an internal state to each task which is represented by
+an integer. The meaning of these integers and their relation to the global
+state of each task is as follows:
+
+internal state | meaning           | corresponding global state
+---------------|-------------------|---------------------------
+             0 | waiting           | started
+             1 | started           | started
+             2 | (result) computed | started
+             3 | (result) sent     | completed
+            -1 | stopped           | stopped
+
+Links
+-----
+The ssi link between the main process and the supervisor is named 'l(pid)'
+where pid is the PID of the main process. The links between the supervisor and
+its child processes are named 'll(pid)(1)', 'll(pid)(2)', ... where pid is the
+PID of the supervisor. The link between the child processes of the supervisor
+and the main process is named 'L(pid)' where pid is the PID of the main
+process. This link is only for sending the results to the main process and must
+not be used in the other direction!
+
+For any task t whose state is 'started', tasks[t.index].links is
+list(L(pid), l(pid)) where pid is the PID of the main process.
+
+Communication model
+-------------------
+stopTask() <--> supervisor
+    0, id -->
+
+waitTasks() <--> supervisor
+(demanded_task is an intvec containing the IDs of the tasks which are being
+waited for; ndemanded is the number of tasks that is being waited for.)
+    1, demanded_tasks, ndemanded -->
+    [receiving results]
+    1, 0:2, -1 -->
+    results_sent <--
+    [receiving remaining results]
+
+pollTask() <--> supervisor
+    2, id -->
+    state <--
+    [receive result if state == 2 (computed)]
+
+startTasks_child() <--> startTasks_grandchild()
+    [compute the result]
+    1, id <--
+    [wait until the result is requested]
+    1 -->
+    [send the result]
+    2 <--
+
+sending and receiving results:
+main process <--> supervisor <--> startTasks_grandchild()
+    [request the result, see above]
+    index, result  (main process <-- startTasks_grandchild())
+    3, id          (main process --> supervisor)
+*/
+
+LIB "resources.lib";
+
+static proc mod_init()
+{
+    /* initialize the semaphores */
+    if (!defined(Resources)) {
+        LIB "resources.lib";
+    }
+    // the number of processor cores
+    int sem_cores = Resources::sem_cores;
+    exportto(Tasks, sem_cores);
+    // the number of leaves in the parallel tree (not strict)
+    int sem_leaves = semaphore(system("--cpus")+10);
+    exportto(Tasks, sem_leaves);
+    // the number of processes waiting for sem_cores with low priority
+    int sem_queue = semaphore(2);
+    exportto(Tasks, sem_queue);
+
+    /* define the Singular type 'task' */
+    newstruct("task", "int index");
+    newstruct("internal_task", "int id, string command, list arguments,"
+        +"def result, string state, list links, int linkID");
+    system("install", "task", "=", createTask, 1);
+    system("install", "task", "==", compareTasks, 2);
+    system("install", "task", "print", printTask, 1);
+
+    /* define (lib-)global variables */
+    list tasks;     // the lib-internal list of tasks
+    exportto(Tasks, tasks);
+    int ntasks;     // the current maximal index in 'tasks'
+    exportto(Tasks, ntasks);
+    int nlinkIDs;   // the current maximal linkID
+    exportto(Tasks, nlinkIDs);
+}
+
+proc createTask(alias string command, alias list arguments)
+"USAGE:   createTask(command, arguments), command string, arguments list
+RETURN:   a task with the given command and arguments whose state is 'created'.
+NOTE:     't = command, arguments;' is a shortcut for
+          't = createTask(command, arguments);'.
+SEE ALSO: startTasks, getCommand, getArguments, getState, killTask, copyTask,
+          compareTasks, printTask
+EXAMPLE:  example createTask; shows an example"
+{
+    internal_task T;
+    ntasks++;
+    tasks[ntasks] = T;
+    tasks[ntasks].command = command;
+    tasks[ntasks].arguments = arguments;
+    tasks[ntasks].state = "created";
+    task t;
+    t.index = ntasks;
+    return(t);
+}
+example
+{
+    "EXAMPLE:";
+    echo = 2;
+    ring R = 0, (x,y), dp;
+    ideal I = x9y2+x10, x2y7-y8;
+    task t = createTask("std", list(I));
+    // This is the same as:
+    // task t = "std", list(I);
+    t;
+    killTask(t);
+}
+
+proc killTask(task t)
+"USAGE:   killTask(t), t task
+RETURN:   nothing. If the state of t is 'started', then t is stopped first. The
+          internal data structures of t are erased and its state is set to
+          'uninitialized'.
+NOTE:     'killTask(t);' is not the same as 'kill t;'. The latter command does
+          not erase the internal data structures of t. Hence killTask() should
+          be called for any no longer needed task in order to free memory.
+SEE ALSO: stopTask, getState, createTask, printTask
+EXAMPLE:  example killTask; shows an example"
+{
+    if (t.index == 0) {
+        return();
+    }
+    if (typeof(tasks[t.index]) != "internal_task") {
+        return();
+    }
+    if (tasks[t.index].state == "started") {
+        stopTask(t);
+    }
+    tasks[t.index] = def(0);
+}
+example
+{
+    "EXAMPLE:";
+    echo = 2;
+    ring R = 0, (x,y), dp;
+    ideal I = x9y2+x10, x2y7-y8;
+    task t = "std", list(I);
+    startTasks(t);
+    t;
+    killTask(t);
+    t;
+    getState(t);
+}
+
+proc copyTask(task t)
+"USAGE:   copyTask(t), t task
+RETURN:   a copy of t.
+NOTE:     'task t1 = copyTask(t2);' is not the same as 'task t1 = t2;'. After
+          the latter command, t1 points to the same object as t2; any changes
+          to t2 will also effect t1. In contrast to this, copyTask() creates a
+          new independend task.
+       @* A task whose state is 'started' cannot be copied.
+SEE ALSO: getCommand, getArguments, getResult, getState, createTask, killTask,
+          compareTasks, printTask
+EXAMPLE:  example copyTask; shows an example"
+{
+    task t_copy;
+    if (t.index == 0) {
+        return(t_copy);
+    }
+    if (typeof(tasks[t.index]) != "internal_task") {
+        return(t_copy);
+    }
+    if (tasks[t.index].state == "started") {
+        ERROR("cannot copy a task whose state is 'started'");
+    }
+    ntasks++;
+    tasks[ntasks] = tasks[t.index];
+    t_copy.index = ntasks;
+    return(t_copy);
+}
+example
+{
+    "EXAMPLE:";
+    echo = 2;
+    ring R = 0, (x,y), dp;
+    ideal I = x9y2+x10, x2y7-y8;
+    task t1 = "std", list(I);
+    startTasks(t1);
+    waitAllTasks(t1);
+    task t2 = copyTask(t1);
+    killTask(t1);
+    t2;   // t2 survived
+    getResult(t2);
+    killTask(t2);
+}
+
+proc compareTasks(task t1, task t2)
+"USAGE:   compareTasks(t1, t2), t1, t2 tasks
+RETURN:   1, if t1 and t2 coincide;
+          0, otherwise.
+NOTE:     The arguments and the results of t1 and t2 are not compared.
+       @* 't1 == t2' is a shortcut for 'compareTasks(t1, t2)'.
+SEE ALSO: getCommand, getArguments, getResult, getState, copyTask, printTask
+EXAMPLE:  example compareTasks; shows an example"
+{
+    if (tasks[t1.index].id != tasks[t2.index].id) {
+        return(0);
+    }
+    if (tasks[t1.index].command != tasks[t2.index].command) {
+        return(0);
+    }
+    if (tasks[t1.index].state != tasks[t2.index].state) {
+        return(0);
+    }
+    if (tasks[t1.index].linkID != tasks[t2.index].linkID) {
+        return(0);
+    }
+    return(1);
+}
+example
+{
+    "EXAMPLE:";
+    echo = 2;
+    ring R = 0, (x,y), dp;
+    ideal I = x9y2+x10, x2y7-y8;
+    task t1 = "std", list(I);
+    task t2 = "std", list(I);
+    compareTasks(t1, t2);
+    startTasks(t1);
+    waitAllTasks(t1);
+    t1 == t2;   // the same as compareTasks(t1, t2);
+    killTask(t1);
+    killTask(t2);
+    // The arguments and the result are not compared!
+    ideal J = x;
+    task t3 = "std", list(I);
+    task t4 = "std", list(J);
+    t3 == t4;
+    killTask(t3);
+    killTask(t4);
+}
+
+proc printTask(task t)
+"USAGE:   printTask(t), t task
+RETURN:   nothing. Prints information about t.
+NOTE:     'print(t);' and 't;' are shortcuts for 'printTask(t)'.
+SEE ALSO: getCommand, getArguments, getResult, getState, createTask, killTask
+EXAMPLE:  example printTask; shows an example"
+{
+    if (t.index == 0) {
+        "An uninitialized task";
+        return();
+    }
+    if (typeof(tasks[t.index]) != "internal_task") {
+        "An uninitialized task";
+        return();
+    }
+    "A task with the following properties:"+newline
+        +"command:          "+tasks[t.index].command+newline
+        +"no. of arguments: "+string(size(tasks[t.index].arguments))+newline
+        +"state:            "+tasks[t.index].state;
+}
+example
+{
+    "EXAMPLE:";
+    echo = 2;
+    ring R = 0, (x,y), dp;
+    ideal I = x9y2+x10, x2y7-y8;
+    task t;
+    printTask(t);
+    t = "std", list(I);
+    t;   // the same as printTask(t);
+    startTasks(t);
+    waitAllTasks(t);
+    t;
+    killTask(t);
+}
+
+proc startTasks(list #)
+"USAGE:   startTasks(t1, t2, ...), t1, t2, ... tasks
+RETURN:   nothing. Starts the tasks t1, t2, ... and sets their states to
+          'started'.
+NOTE:     A task whose state is neither 'created' nor 'stopped' cannot be
+          started.
+       @* If startTasks() is applied to a task whose state is 'stopped', then
+          the computation of this task will be restarted from the beginning.
+       @* Tasks can be started from within other tasks. A started task should
+          not be accessed from within any task other than the one within which
+          it was started.
+       @* For each task, the start of its computation is subject to the
+          internal scheduling.
+SEE ALSO: stopTask, waitTasks, pollTask, getState, createTask, printTask
+EXAMPLE:  example startTasks; shows an example"
+{
+    int nargs = size(#);
+    if (nargs == 0) {
+        ERROR("missing argument");
+    }
+    int i;
+    for (i = nargs; i > 0; i--) {
+        if (typeof(#[i]) != "task") {
+            ERROR("argument not of type 'task' (argument no. "+string(i)+")");
+        }
+        if (#[i].index == 0) {
+            ERROR("cannot start an uninitialized task (task no. "
+                +string(i)+")");
+        }
+        if (typeof(tasks[#[i].index]) != "internal_task") {
+            ERROR("cannot start an uninitialized task (task no. "
+                +string(i)+")");
+        }
+        if (tasks[#[i].index].state != "created"
+            && tasks[#[i].index].state != "stopped") {
+            ERROR("cannot start a task whose state is not"+newline
+                +"'created' or 'stopped'");
+        }
+    }
+    for (i = nargs; i > 0; i--) {
+        tasks[#[i].index].id = i;   // has to be set before forking
+        tasks[#[i].index].state = "started";
+    }
+    int pid = system("pid");
+    link l(pid) = "ssi:fork";
+    open(l(pid));
+    write(l(pid), quote(startTasks_child(#, eval(pid))));
+    int port = read(l(pid));
+    link L(pid) = "ssi:connect localhost:"+string(port);
+    open(L(pid));
+    nlinkIDs++;
+    for (i = nargs; i > 0; i--) {
+        tasks[#[i].index].links = list(L(pid), l(pid));
+        tasks[#[i].index].linkID = nlinkIDs;
+    }
+}
+example
+{
+    "EXAMPLE:";
+    echo = 2;
+    ring R = 0, (x,y), dp;
+    ideal I = x9y2+x10, x2y7-y8;
+    task t1 = "std", list(I);
+    task t2 = "slimgb", list(I);
+    startTasks(t1, t2);
+    waitAllTasks(t1, t2);
+    getResult(t1);
+    getResult(t2);
+    killTask(t1);
+    killTask(t2);
+}
+
+/* This procedure is started within the child after forking. */
+static proc startTasks_child(list localtasks, int pid_parent)
+{
+    int port = system("reserve", 1);
+    write(l(pid_parent), port);
+    link L(pid_parent) = system("reservedLink");
+    export(L(pid_parent));
+
+    int sem_write = semaphore(1);
+    int pid = system("pid");
+
+    int nlocaltasks = size(localtasks);
+    intvec state = 0:nlocaltasks;
+        // the internal state of each localtask (see rationale)
+    int nwaiting = nlocaltasks;
+        // the number of local tasks with internal state 0 (waiting)
+    int nfinished;
+        // the number of local tasks with internal state 3 (result sent) or
+        // -1 (stopped)
+    intvec queue = 1..nlocaltasks;
+    int next = 1;
+
+    list links;
+    links[nlocaltasks+1] = l(pid_parent);
+    intvec assignment = 0:nlocaltasks;
+        // the task with id = i is running in link no. assignment[i]
+    int nlinks;
+
+    // data sent by other processes
+    int code;
+    int id;
+    if (!defined(demanded_tasks)) {
+        intvec demanded_tasks;
+        int demanded_tasks_index = 1;
+        exportto(Tasks, demanded_tasks);
+        exportto(Tasks, demanded_tasks_index);
+    }
+    else {
+        demanded_tasks = 0;
+        demanded_tasks_index = 1;
+    }
+    int ndemanded = -1;
+
+    // internal counts
+    int granted_leaves;
+    int results_sent;
+
+    // auxiliary variables
+    intvec waiting_tasks;
+    int wait;
+    int deadlock;
+    int tmp;
+    int i;
+    int j;
+
+    while (nwaiting > 0) {
+        wait = 0;
+        if (nlinks == 0) {
+            wait = -1;
+            granted_leaves++;
+            while (-wait < nwaiting) {
+                if (system("semaphore", "try_acquire", sem_leaves) == 1) {
+                    wait--;
+                }
+                else {
+                    break;
+                }
+            }
+        }
+        while (wait == 0) {
+            wait = waitfirst(links, 500);
+            if (wait == 0) {
+                while (-wait < nwaiting) {
+                    if (system("semaphore", "try_acquire", sem_leaves) == 1) {
+                        wait--;
+                    }
+                    else {
+                        break;
+                    }
+                }
+            }
+        }
+        if (wait < 0) {   // open (-wait) new links
+            while (wait < 0) {
+                wait++;
+                nlinks++;
+                link ll(pid)(nlinks) = "ssi:fork";
+                open(ll(pid)(nlinks));
+                links[nlinks] = ll(pid)(nlinks);
+                write(links[nlinks],
+                    quote(startTasks_grandchild(
+                    eval(localtasks[queue[next]].index), eval(pid_parent),
+                    eval(pid), eval(nlinks), eval(sem_write))));
+                assignment[queue[next]] = nlinks;
+                state[queue[next]] = 1;
+                nwaiting--;
+                next++;
+            }
+            // wait == 0
+        }
+        if (wait > 0 && wait <= nlocaltasks) {
+            code = read(links[wait]);
+            if (code == 1) {   // result computed
+                id = read(links[wait]);
+                state[id] = 2;
+                if (ndemanded > 0 && removeDemanded(id)) {
+                    write(links[wait], 1);
+                    ndemanded--;
+                    results_sent++;
+                }
+            }
+            // code == 2: startTasks_grandchild() ended, do nothing
+        }
+        if (wait == nlocaltasks+1) {
+            code = read(l(pid_parent));
+            if (code == 0) {   // stopTask
+                id = read(l(pid_parent));
+                if (state[id] == 0) {   // waiting
+                    queue = give_priority(queue, intvec(id));
+                    next++;
+                }
+                if (state[id] == 1 || state[id] == 2) {  // started or computed
+                    close(links[assignment[id]]);
+                    open(links[assignment[id]]);
+                    write(links[assignment[id]],
+                        quote(startTasks_grandchild(
+                        eval(localtasks[queue[next]].index), eval(pid_parent),
+                        eval(pid), eval(assignment[id]), eval(sem_write))));
+                    assignment[queue[next]] = assignment[id];
+                    assignment[id] = 0;
+                    state[queue[next]] = 1;
+                    next++;
+                }
+                // state[id] == -1 (stopped) or state[id] == 3 (sent)
+                // should not happen
+                nwaiting--;
+                nfinished++;
+                state[id] = -1;
+            }
+            if (code == 1) {   // waitTasks
+                demanded_tasks = read(l(pid_parent));
+                demanded_tasks_index = size(demanded_tasks);
+                ndemanded = read(l(pid_parent));
+                if (ndemanded > demanded_tasks_index) {
+                    ndemanded = demanded_tasks_index;
+                }
+                if (demanded_tasks == 0 && ndemanded == -1) {
+                    write(l(pid_parent), results_sent);
+                    continue;
+                }
+                else {
+                    results_sent = 0;
+                }
+                demanded_tasks = demanded_tasks[demanded_tasks_index..1];
+                deadlock = 0;
+                waiting_tasks = 0:demanded_tasks_index;
+                j = 0;
+                for (i = demanded_tasks_index; i > 0; i--) {
+                    id = demanded_tasks[i];
+                    if (state[id] == 0) {   // waiting
+                        j++;
+                        waiting_tasks[j] = id;
+                        deadlock = 1;
+                    }
+                }
+                if (j > 0) {
+                    waiting_tasks = waiting_tasks[1..j];
+                    queue = queue[next..size(queue)];
+                    next = 1;
+                    queue = give_priority(queue, waiting_tasks);
+                    waiting_tasks = 0;
+                }
+                for (i = demanded_tasks_index; i > 0; i--) {
+                    id = demanded_tasks[i];
+                    if (state[id] == 1) {   // started
+                        deadlock = 0;
+                    }
+                    if (state[id] == 2) {   // computed
+                        write(links[assignment[id]], 1);
+                        tmp = removeDemanded(id);
+                        ndemanded--;
+                        results_sent++;
+                        deadlock = 0;
+                    }
+                }
+                if (deadlock) {
+                    granted_leaves++;
+                    nlinks++;
+                    link ll(pid)(nlinks) = "ssi:fork";
+                    open(ll(pid)(nlinks));
+                    links[nlinks] = ll(pid)(nlinks);
+                    write(links[nlinks],
+                        quote(startTasks_grandchild(
+                        eval(localtasks[queue[next]].index), eval(pid_parent),
+                        eval(pid), eval(nlinks), eval(sem_write))));
+                    assignment[queue[next]] = nlinks;
+                    state[queue[next]] = 1;
+                    nwaiting--;
+                    next++;
+                }
+            }
+            if (code == 2) {   // pollTask
+                id = read(l(pid_parent));
+                if (state[id] == 0) {   // waiting
+                    queue = queue[next..size(queue)];
+                    next = 1;
+                    queue = give_priority(queue, intvec(id));
+                }
+                if (state[id] == 2) {   // computed
+                    write(links[assignment[id]], 1);
+                }
+                write(l(pid_parent), state[id]);
+            }
+            if (code == 3) {   // got result
+                id = read(l(pid_parent));
+                write(links[assignment[id]],
+                    quote(startTasks_grandchild(
+                    eval(localtasks[queue[next]].index), eval(pid_parent),
+                    eval(pid), eval(assignment[id]), eval(sem_write))));
+                assignment[queue[next]] = assignment[id];
+                assignment[id] = 0;
+                state[queue[next]] = 1;
+                state[id] = 3;
+                nwaiting--;
+                nfinished++;
+                next++;
+            }
+        }
+    }
+    while (nfinished < nlocaltasks || ndemanded != -1) {
+        wait = waitfirst(links);
+        if (wait <= nlocaltasks) {
+            code = read(links[wait]);
+            if (code == 1) {   // result computed
+                id = read(links[wait]);
+                state[id] = 2;
+                if (ndemanded > 0 && removeDemanded(id)) {
+                    write(links[wait], 1);
+                    ndemanded--;
+                    results_sent++;
+                }
+            }
+            // code == 2: startTasks_grandchild() ended, do nothing
+        }
+        if (wait == nlocaltasks+1) {
+            code = read(l(pid_parent));
+            if (code == 0) {   // stopTask
+                id = read(l(pid_parent));
+                if (state[id] == 1 || state[id] == 2) {  // started or computed
+                    close(links[assignment[id]]);
+                    if (nlinks > granted_leaves) {
+                        tmp = system("semaphore", "release", sem_leaves);
+                    }
+                    links[assignment[id]] = def(0);
+                    nlinks--;
+                    assignment[id] = 0;
+                    nfinished++;
+                }
+                // else: nothing to do
+                state[id] = -1;
+            }
+            if (code == 1) {   // waitTasks
+                demanded_tasks = read(l(pid_parent));
+                demanded_tasks_index = size(demanded_tasks);
+                ndemanded = read(l(pid_parent));
+                if (ndemanded > demanded_tasks_index) {
+                    ndemanded = demanded_tasks_index;
+                }
+                if (demanded_tasks == 0 && ndemanded == -1) {
+                    write(l(pid_parent), results_sent);
+                    continue;
+                }
+                else {
+                    results_sent = 0;
+                }
+                demanded_tasks = demanded_tasks[demanded_tasks_index..1];
+                for (i = demanded_tasks_index; i > 0; i--) {
+                    id = demanded_tasks[i];
+                    if (state[id] == 2) {   // computed
+                        write(links[assignment[id]], 1);
+                        tmp = removeDemanded(id);
+                        ndemanded--;
+                        results_sent++;
+                    }
+                }
+            }
+            if (code == 2) {   // pollTask
+                id = read(l(pid_parent));
+                if (state[id] == 2) {   // computed
+                    write(links[assignment[id]], 1);
+                }
+                write(l(pid_parent), state[id]);
+            }
+            if (code == 3) {   // got result
+                id = read(l(pid_parent));
+                close(links[assignment[id]]);
+                if (nlinks > granted_leaves) {
+                    tmp = system("semaphore", "release", sem_leaves);
+                }
+                links[assignment[id]] = def(0);
+                nlinks--;
+                assignment[id] = 0;
+                state[id] = 3;
+                nfinished++;
+            }
+        }
+    }
+}
+
+/* This procedure has to be started within the grandchildren after forking. */
+static proc startTasks_grandchild(int index, int pid_grandparent,
+    int pid_parent, int link_no, int sem_write)
+{
+    def result;
+    int tmp = system("semaphore", "acquire", sem_queue);
+    tmp = system("semaphore", "acquire", sem_cores);
+    tmp = system("semaphore", "release", sem_queue);
+    execute("result = "+tasks[index].command+"("
+        +argsToString("tasks[index].arguments", size(tasks[index].arguments))
+        +");");
+    tmp = system("semaphore", "release", sem_cores);
+    write(ll(pid_parent)(link_no), 1);
+    write(ll(pid_parent)(link_no), tasks[index].id);
+    tmp = read(ll(pid_parent)(link_no));
+    tmp = system("semaphore", "acquire", sem_write);
+    write(L(pid_grandparent), index);
+    write(L(pid_grandparent), result);
+    tmp = system("semaphore", "release", sem_write);
+    return(2);
+}
+
+/* Remove id from demanded_tasks and return 1, if id is an element of
+ * demanded_tasks; return 0, otherwise. Note:
+ * - demanded_tasks and demanded_tasks_index are (lib-)global objects
+ *   exported in startTasks_child().
+ * - demanded_tasks_index is used to avoid copying. It is defined to be
+ *   the greatest integer with demanded_tasks[demanded_tasks_index] != 0
+ *   and demanded_tasks[demanded_tasks_index+1] == 0 (if defined).
+ */
+static proc removeDemanded(alias int id)
+{
+    if (demanded_tasks[demanded_tasks_index] == id) {
+        demanded_tasks[demanded_tasks_index] = 0;
+        demanded_tasks_index--;
+        return(1);
+    }
+    int i;
+    for (i = demanded_tasks_index-1; i > 0; i--) {
+        if (demanded_tasks[i] == id) {
+            demanded_tasks[i..demanded_tasks_index]
+                = demanded_tasks[(i+1)..demanded_tasks_index], 0;
+            demanded_tasks_index--;
+            return(1);
+        }
+    }
+    return(0);
+}
+
+/* Move the elements in 'preferred' to the beginning of 'queue'. We may assume
+ * that
+ * - 'preferred' is a subset of 'queue';
+ * - the elements of 'preferred' are distinct and non-zero;
+ * - the elements of 'queue' are distinct and non-zero.
+ * For performance reasons, we may also assume that 'queue' and 'preferred' are
+ * more or less ordered in most cases. Note that queue has the format
+ * '0, indices, 0'.
+ */
+static proc give_priority(intvec queue, intvec preferred)
+{
+    int size_queue = size(queue);
+    int size_preferred = size(preferred);
+    if (size_queue == size_preferred) {
+        return(queue);
+    }
+    int index = size_queue;
+    int i;
+    int j;
+    for (i = size_preferred; i > 0; i--) {
+        for (j = size_queue; j > 0; j--) {
+            if (queue[index] == preferred[i]) {
+                queue[index] = 0;
+                break;
+            }
+            index--;
+            if (index == 0) {
+                index = size_queue;
+            }
+        }
+    }
+    intvec not_preferred = 0:(size_queue-size_preferred);
+    index = 1;
+    for (i = 1; i <= size_queue; i++) {
+        if (queue[i]) {
+            not_preferred[index] = queue[i];
+            index++;
+        }
+    }
+    queue = preferred, not_preferred;
+    return(queue);
+}
+
+proc stopTask(task t)
+"USAGE:   stopTask(t), t task
+RETURN:   nothing. Stops the t and sets its state to 'stopped'.
+NOTE:     A task whose state is not 'started' cannot be stopped.
+       @* Intermediate results are discarded when a task is stopped.
+       @* killTask() should be called for any no longer needed task.
+SEE ALSO: startTasks, waitTasks, pollTask, getState, killTask, printTask
+EXAMPLE:  example stopTask; shows an example"
+{
+    if (t.index == 0) {
+        ERROR("cannot stop an uninitialized task");
+    }
+    if (typeof(tasks[t.index]) != "internal_task") {
+        ERROR("cannot stop an uninitialized task");
+    }
+    if (tasks[t.index].state != "started") {
+        ERROR("cannot stop a task whose state is not 'started'");
+    }
+    write(tasks[t.index].links[2], 0);
+    write(tasks[t.index].links[2], tasks[t.index].id);
+    tasks[t.index].id = 0;
+    tasks[t.index].links = list();
+    tasks[t.index].linkID = 0;
+    tasks[t.index].state = "stopped";
+}
+example
+{
+    "EXAMPLE:";
+    echo = 2;
+    ring R = 0, (x,y), dp;
+    ideal I = x9y2+x10, x2y7-y8;
+    task t = "std", list(I);
+    startTasks(t);
+    stopTask(t);
+    t;
+    killTask(t);
+}
+
+proc waitTasks(list T, int N, list #)
+"USAGE:   waitTasks(T, N[, timeout]), T list of tasks, N int, timeout int
+RETURN:   an ordered list of the indices of those tasks which have been
+          successfully completed. The state of these tasks is set to
+          'completed'.
+       @* The procedure waits for N tasks to complete.
+       @* An optional timeout in ms can be provided. Default is 0 which
+          disables the timeout.
+NOTE:     A task whose state is neither 'started' nor 'completed' cannot be
+          waited for.
+       @* The result of any completed task can be accessed via @ref{getResult}.
+       @* The returned list may contain more than N entries if the computation
+          of some tasks has already finished and/or if several tasks finish
+          \"at the same time\". It may contain less than N entries in
+          the case of timeout or errors occurring.
+       @* Polling is guaranteed, i.e. the index of any task t for which
+          'pollTask(t);' would return 1 will appear in the returned list.
+SEE ALSO: startTasks, pollTask, getResult, getState, printTask
+EXAMPLE:  example waitTasks; shows an example"
+{
+    /* initialize the timer */
+    int oldtimerresolution = system("--ticks-per-sec");
+    system("--ticks-per-sec", 1000);
+    int starting_time = rtimer;
+
+    /* read optional parameters */
+    int timeout;
+    if (size(#) > 0) {
+        if (size(#) > 1 || typeof(#[1]) != "int") {
+            ERROR("wrong optional parameter");
+        }
+        timeout = #[1];
+    }
+
+    /* check for errors */
+    if (timeout < 0) {
+        ERROR("negative timeout");
+    }
+    int nargs = size(T);
+    if (nargs == 0) {
+        ERROR("missing task");
+    }
+    if (N < 1 || N > nargs) {
+        ERROR("wrong number of tasks to wait for");
+    }
+    int i;
+    for (i = nargs; i > 0; i--) {
+        if (typeof(T[i]) != "task") {
+            ERROR("element not of type 'task' (element no. "+string(i)+")");
+        }
+        if (T[i].index == 0) {
+            ERROR("cannot wait for an uninitialized task (task no. "+string(i)
+                +")");
+        }
+        if (typeof(tasks[T[i].index]) != "internal_task") {
+            ERROR("cannot wait for an uninitialized task (task no. "+string(i)
+                +")");
+        }
+        if (tasks[T[i].index].state != "started"
+            && tasks[T[i].index].state != "completed") {
+            ERROR("cannot wait for a task whose state is not"+newline
+                +"'started' or 'completed' (task no. "+string(i)+")");
+        }
+    }
+
+    /* sort the tasks */
+    int ncompleted;
+    list requests;
+    list links;
+    int sorted_in;
+    int j;
+    for (i = 1; i <= nargs; i++) {
+        if (tasks[T[i].index].state == "completed") {
+            ncompleted++;
+        }
+        else {   // tasks[T[i].index].state == "started"
+            sorted_in = 0;
+            for (j = size(requests); j > 0; j--) {
+                if (requests[j][1] == tasks[T[i].index].linkID) {
+                    requests[j][2][size(requests[j][2])+1] =
+                        tasks[T[i].index].id;
+                    sorted_in = 1;
+                    break;
+                }
+            }
+            if (!sorted_in) {
+                requests[size(requests)+1] = list(tasks[T[i].index].linkID,
+                    intvec(tasks[T[i].index].id),
+                    tasks[T[i].index].links[2]);
+                links[size(links)+1] = tasks[T[i].index].links[1];
+            }
+        }
+    }
+
+    /* send the reqests */
+    for (j = size(requests); j > 0; j--) {
+        write(requests[j][3], 1);
+        write(requests[j][3], requests[j][2]);
+        write(requests[j][3], N-ncompleted);
+    }
+
+    /* wait for the results */
+    int wait;
+    int index;
+    int results_got;
+    int remaining_time;
+    int tmp;
+    while (ncompleted < N) {
+        wait = waitfirst(links, 0);
+        if (wait == 0) {
+            if (timeout == 0) {
+                tmp = system("semaphore", "release", sem_cores);
+                wait = waitfirst(links);
+                tmp = system("semaphore", "acquire", sem_cores);
+            }
+            else {
+                remaining_time = timeout-(rtimer-starting_time);
+                if (remaining_time < 0) {
+                    break;
+                }
+                else {
+                    tmp = system("semaphore", "release", sem_cores);
+                    wait = waitfirst(links, remaining_time);
+                    tmp = system("semaphore", "acquire", sem_cores);
+                }
+            }
+        }
+        if (wait < 1) {
+            break;
+        }
+        index = read(links[wait]);
+        tasks[index].result = read(links[wait]);
+        write(tasks[index].links[2], 3);
+        write(tasks[index].links[2], tasks[index].id);
+        tasks[index].id = 0;
+        tasks[index].links = list();
+        tasks[index].linkID = 0;
+        tasks[index].state = "completed";
+        ncompleted++;
+        results_got++;
+    }
+    if (wait == -1) {
+        ERROR("error in waitfirst()");
+    }
+
+    /* end communication process */
+    for (j = size(requests); j > 0; j--) {
+        write(requests[j][3], 1);
+        write(requests[j][3], 0);
+        write(requests[j][3], -1);
+    }
+    int results_sent;
+    for (j = size(requests); j > 0; j--) {
+        results_sent = results_sent + read(requests[j][3]);
+    }
+    while (results_sent > results_got) {
+        wait = waitfirst(links);
+        if (wait == -1) {
+            ERROR("error in waitfirst()");
+        }
+        index = read(links[wait]);
+        tasks[index].result = read(links[wait]);
+        write(tasks[index].links[2], 3);
+        write(tasks[index].links[2], tasks[index].id);
+        tasks[index].id = 0;
+        tasks[index].links = list();
+        tasks[index].linkID = 0;
+        tasks[index].state = "completed";
+        results_got++;
+    }
+
+    /* list completed tasks */
+    list completed;
+    completed[nargs+1] = 0;
+    j = 0;
+    for (i = 1; i <= nargs; i++) {
+        if (tasks[T[i].index].state == "completed") {
+            j++;
+            completed[j] = i;
+        }
+    }
+    completed[nargs+1] = def(0);
+
+    /* return the result */
+    system("--ticks-per-sec", oldtimerresolution);
+    return(completed);
+}
+example
+{
+    "EXAMPLE:";
+    echo = 2;
+    ring R = 0, (x,y), dp;
+    ideal I = x9y2+x10, x2y7-y8;
+    task t1 = "std", list(I);
+    task t2 = "slimgb", list(I);
+    startTasks(t1, t2);
+    waitTasks(list(t1, t2), 2);   // wait for both tasks
+    getResult(t1);
+    getResult(t2);
+    killTask(t1);
+    killTask(t2);
+}
+
+proc waitAllTasks(list #)
+"USAGE:   waitAllTasks(t1, t2, ...), t1, t2, ... tasks
+RETURN:   nothing. Waits for all the tasks t1, t2, ... to complete. The state
+          of the tasks is set to 'completed'.
+NOTE:     A task whose state is neither 'started' nor 'completed' cannot be
+          waited for.
+       @* The result of any completed task can be accessed via @ref{getResult}.
+       @* 'waitAllTasks(t1, t2, ...);' is a shortcut for
+          'waitTasks(list(t1, t2, ...), size(list(t1, t2, ...)));'. Since
+          returning a list of the indices of the completed tasks does not make
+          sense in this case, nothing is returned.
+SEE ALSO: waitTasks, startTasks, pollTask, getResult, getState, printTask
+EXAMPLE:  example waitAllTasks; shows an example"
+{
+    list tmp = waitTasks(#, size(#));
+}
+example
+{
+    "EXAMPLE:";
+    echo = 2;
+    ring R = 0, (x,y), dp;
+    ideal I = x9y2+x10, x2y7-y8;
+    task t1 = "std", list(I);
+    task t2 = "slimgb", list(I);
+    startTasks(t1, t2);
+    waitAllTasks(t1, t2);   // the same as 'waitTasks(list(t1, t2), 2);',
+                            // but without return value
+    getResult(t1);
+    getResult(t2);
+    killTask(t1);
+    killTask(t2);
+}
+
+proc pollTask(task t)
+"USAGE:   pollTask(t), t task
+RETURN:   1, if the computation of the task t has successfully finished;
+          0, otherwise.
+       @* The state of any task whose computation has successfully finished is
+          set to 'completed'.
+NOTE:     A task whose state is neither 'started' nor 'completed' cannot be
+          polled.
+       @* The result of any completed task can be accessed via @ref{getResult}.
+       @* pollTask() should return immediately. However, receiving the result
+          of the task may take some time.
+SEE ALSO: startTasks, waitTasks, getResult, getState, printTask
+EXAMPLE:  example pollTask; shows an example"
+{
+    if (t.index == 0) {
+        ERROR("cannot poll an uninitialized task");
+    }
+    if (typeof(tasks[t.index]) != "internal_task") {
+        ERROR("cannot poll an uninitialized task");
+    }
+    if (tasks[t.index].state != "started"
+        && tasks[t.index].state != "completed") {
+        ERROR("cannot poll a task whose state is not"+newline
+            +"'started' or 'completed'");
+    }
+    if (tasks[t.index].state == "completed") {
+        return(1);
+    }
+    // tasks[t.index].state == "started"
+    write(tasks[t.index].links[2], 2);
+    write(tasks[t.index].links[2], tasks[t.index].id);
+    int state = read(tasks[t.index].links[2]);
+    if (state == 0 || state == 1) {   // waiting or started
+        return(0);
+    }
+    if (state == 2) {   // computed
+        int index = read(tasks[t.index].links[1]);   // index == t.index
+        tasks[t.index].result = read(tasks[t.index].links[1]);
+        write(tasks[t.index].links[2], 3);
+        write(tasks[t.index].links[2], tasks[t.index].id);
+        tasks[t.index].id = 0;
+        tasks[t.index].links = list();
+        tasks[t.index].linkID = 0;
+        tasks[t.index].state = "completed";
+        return(1);
+    }
+    // state == -1 (stopped) or state == 3 (sent) should not happen
+}
+example
+{
+    "EXAMPLE:";
+    echo = 2;
+    ring R = 0, (x,y), dp;
+    ideal I = x9y2+x10, x2y7-y8;
+    task t = "std", list(I);
+    startTasks(t);
+    waitAllTasks(t);
+    pollTask(t);   // task already completed
+    t;
+    getResult(t);
+    killTask(t);
+}
+
+proc getCommand(task t)
+"USAGE:   getCommand(t), t task
+RETURN:   a string, the command of t.
+NOTE:     This command cannot be applied to tasks whose state is
+          'uninitialized'.
+SEE ALSO: getArguments, getResult, getState, createTask, printTask
+EXAMPLE:  example getCommand; shows an example"
+{
+    if (t.index == 0) {
+        ERROR("cannot get command of an uninitialized task");
+    }
+    if (typeof(tasks[t.index]) != "internal_task") {
+        ERROR("cannot get command of an uninitialized task");
+    }
+    return(tasks[t.index].command);
+}
+example
+{
+    "EXAMPLE:";
+    echo = 2;
+    ring R = 0, (x,y), dp;
+    ideal I = x9y2+x10, x2y7-y8;
+    task t = "std", list(I);
+    getCommand(t);
+    killTask(t);
+}
+
+proc getArguments(task t)
+"USAGE:   getArguments(t), t task
+RETURN:   a list, the arguments of t.
+NOTE:     This command cannot be applied to tasks whose state is
+          'uninitialized'.
+SEE ALSO: getCommand, getResult, getState, createTask, printTask
+EXAMPLE:  example getArguments; shows an example"
+{
+    if (t.index == 0) {
+        ERROR("cannot get arguments of an uninitialized task");
+    }
+    if (typeof(tasks[t.index]) != "internal_task") {
+        ERROR("cannot get arguments of an uninitialized task");
+    }
+    return(tasks[t.index].arguments);
+}
+example
+{
+    "EXAMPLE:";
+    echo = 2;
+    ring R = 0, (x,y), dp;
+    ideal I = x9y2+x10, x2y7-y8;
+    task t = "std", list(I);
+    getArguments(t);
+    killTask(t);
+}
+
+proc getResult(task t)
+"USAGE:   getResult(t), t task
+RETURN:   the result of t.
+NOTE:     This command cannot be applied to tasks whose state is not
+          'completed'.
+SEE ALSO: getCommand, getArguments, getState, waitTasks, pollTask, printTask
+EXAMPLE:  example getResult; shows an example"
+{
+    if (t.index == 0) {
+        ERROR("cannot get result of an uninitialized task");
+    }
+    if (typeof(tasks[t.index]) != "internal_task") {
+        ERROR("cannot get result of an uninitialized task");
+    }
+    if (tasks[t.index].state != "completed") {
+        ERROR("cannot get result of a task which is not completed");
+    }
+    return(tasks[t.index].result);
+}
+example
+{
+    "EXAMPLE:";
+    echo = 2;
+    ring R = 0, (x,y), dp;
+    ideal I = x9y2+x10, x2y7-y8;
+    task t = "std", list(I);
+    startTasks(t);
+    waitAllTasks(t);
+    getResult(t);
+    killTask(t);
+}
+
+proc getState(task t)
+"USAGE:   getState(t), t task
+RETURN:   a string, the state of t.
+SEE ALSO: getCommand, getArguments, getResult, printTask, createTask,
+          startTasks, stopTask, waitTasks, pollTask, killTask
+EXAMPLE:  example getState; shows an example"
+{
+    if (t.index == 0) {
+        return("uninitialized");
+    }
+    if (typeof(tasks[t.index]) != "internal_task") {
+        return("uninitialized");
+    }
+    return(tasks[t.index].state);
+}
+example
+{
+    "EXAMPLE:";
+    echo = 2;
+    ring R = 0, (x,y), dp;
+    ideal I = x9y2+x10, x2y7-y8;
+    task t = "std", list(I);
+    getState(t);
+    startTasks(t);
+    getState(t);
+    waitAllTasks(t);
+    getState(t);
+    killTask(t);
+    getState(t);
+}
+
+/ * construct the string "name[1], name[2], name[3], ..., name[length]" */
+static proc argsToString(string name, int length)
+{
+    string output;
+    if (length > 0) {
+        output = name+"[1]";
+    }
+    int i;
+    for (i = 2; i <= length; i++) {
+        output = output+", "+name+"["+string(i)+"]";
+    }
+    return(output);
+}
diff --git a/Singular/LIB/teachstd.lib b/Singular/LIB/teachstd.lib
new file mode 100644
index 0000000..3474fb1
--- /dev/null
+++ b/Singular/LIB/teachstd.lib
@@ -0,0 +1,858 @@
+////////////////////////////////////////////////////////////////////////////
+version="version teachstd.lib 4.0.0.0 Jun_2013 "; // $Id: 92ffc29de41ebc8e82235f0e4b83b6408de3d641 $
+category="Teaching";
+info="
+LIBRARY:  teachstd.lib   Procedures for teaching standard bases
+AUTHOR:                  G.-M. Greuel, greuel at mathematik.uni-kl.de
+
+NOTE: The library is intended to be used for teaching purposes, but not
+      for serious computations. Sufficiently high printlevel allows to
+      control each step, thus illustrating the algorithms at work.
+      The procedures are implemented exactly as described in the book
+      'A SINGULAR Introduction to Commutative Algebra' by G.-M. Greuel and
+      G. Pfister (Springer 2002).
+
+PROCEDURES:
+ ecart(f);              ecart of f
+ tail(f);               tail of f
+ sameComponent(f,g);    test for same module component of lead(f) and lead(g)
+ leadmonomial(f);       leading monomial as polynomial (also for vectors)
+ monomialLcm(m,n);      lcm of monomials m and n as polynomial (also for vectors)
+ spoly(f[,1]);          s-polynomial of f [symmetric form]
+ minEcart(T,h);         element g from T of minimal ecart s.t. LM(g)|LM(h)
+ NFMora(i);             normal form of i w.r.t Mora algorithm
+ prodcrit(f,g[,o]);     test for product criterion
+ chaincrit(f,g,h);      test for chain criterion
+ pairset(G);            pairs form G neither satifying prodcrit nor chaincrit
+ updatePairs(P,S,h);    pairset P enlarded by not useless pairs (h,f), f in S
+ standard(id);          standard basis of ideal/module
+ localstd(id);          local standard basis of id using Lazard's method
+
+              [parameters in square brackets are optional]
+";
+
+LIB "poly.lib";
+
+///////////////////////////////////////////////////////////////////////////////
+proc ecart(def f)
+"USAGE:   ecart(f); f poly or vector
+RETURN:  the ecart e of f of type int
+EXAMPLE: example ecart; shows an example
+"
+{
+  int e = maxdeg1(f)-maxdeg1(lead(f));
+  return(e);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r=0,(x,y,z),ls;
+   ecart((y+z+x+xyz)**2);
+   ring s=0,(x,y,z),dp;
+   ecart((y+z+x+xyz)**2);
+}
+///////////////////////////////////////////////////////////////////////////////
+proc leadmonomial(def f)
+"USAGE:   leadmonomial(f); f poly or vector
+RETURN:  the leading monomial of f of type poly
+NOTE:    if f is of type poly, leadmonomial(f)=leadmonom(f), if f is of type
+         vector and if leadmonom(f)=m*gen(i) then leadmonomial(f)=m
+EXAMPLE: example leadmonomial; shows an example
+"
+{
+  int e;
+  poly m;
+  if(typeof(f) == "vector")
+  {
+    e=leadexp(f)[nvars(basering)+1];
+    m=leadmonom(f)[e,1];
+  }
+  if(typeof(f) == "poly")
+  {
+    m=leadmonom(f);
+  }
+  return(m);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring s=0,(x,y,z),(c,dp);
+   leadmonomial((y+z+x+xyz)^2);
+   leadmonomial([(y+z+x+xyz)^2,xyz5]);
+}
+///////////////////////////////////////////////////////////////////////////////
+proc tail(def f)
+"USAGE:   tail(f); f poly or vector
+RETURN:  f-lead(f), the tail of f of type poly
+EXAMPLE: example tail; shows an example
+"
+{
+  def t = f-lead(f);
+  return(t);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r=0,(x,y,z),ls;
+   tail((y+z+x+xyz)**2);
+   ring s=0,(x,y,z),dp;
+   tail((y+z+x+xyz)**2);
+}
+///////////////////////////////////////////////////////////////////////////////
+proc sameComponent(def f,def g)
+"USAGE:   sameComponent(f,g); f,g poly or vector
+RETURN:  1 if f and g are of type poly or if f and g are of type vector and
+         their leading monomials involve the same module component,
+         0 if not
+EXAMPLE: example sameComponent; shows an example
+"
+{
+  if(typeof(f) != typeof(g))
+  {
+    ERROR("** arguments must be of same type");
+  }
+  if(typeof(f) == "vector")
+  {
+     if( leadexp(f)[nvars(basering)+1] !=  leadexp(g)[nvars(basering)+1] )
+     {
+       return(0);
+     }
+  }
+  return(1);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r=0,(x,y,z),dp;
+   sameComponent([y+z+x,xyz],[z2,xyz]);
+   sameComponent([y+z+x,xyz],[z4,xyz]);
+   sameComponent(y+z+x+xyz, xy+z5);
+}
+///////////////////////////////////////////////////////////////////////////////
+proc monomialLcm(def m,def n)
+"USAGE:   monomialLcm(m,n); m,n of type poly or vector
+RETURN:  least common multiple of leading monomials of m and n, of type poly
+NOTE:    if m = (x1...xr)^(a1,...,ar)*gen(i) (gen(i)=1 if m is of type poly)
+         and n = (x1...xr)^(b1,...,br)*gen(j), then the proc returns
+         (x1,...,xr)^(max(a1,b1),...,max(ar,br)) if i=j and 0 if i!=j.
+EXAMPLE: example monomialLcm; shows an example
+"
+{
+  if(typeof(n) != typeof(m))
+  {
+    ERROR("** arguments must be of same type");
+  }
+
+  poly u ;
+  if(sameComponent(m,n) == 0)   //leading term of vectors involve
+  {                             //different module components
+     return(u);
+  }
+
+  intvec v = leadexp(m);        //now start to compute lcm
+  intvec w = leadexp(n);
+  u=1;
+  int i;
+  for (i=1; i<=nvars(basering); i++)
+  {
+      if(v[i]>=w[i])
+      {
+         u = u*var(i)**v[i];
+      }
+      else
+      {
+         u = u*var(i)**w[i];
+      }
+   }
+   return(u);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r=0,(x,y,z),ds;
+   monomialLcm(xy2,yz3);
+   monomialLcm([xy2,xz],[yz3]);
+   monomialLcm([xy2,xz3],[yz3]);
+}
+///////////////////////////////////////////////////////////////////////////////
+proc spoly(def f,def g,list #)
+"USAGE:   spoly(f,g[,s]); f,g poly or vector, s int
+RETURN:  the s-polynomial of f and g, of type poly or vector
+         if s!=0 the symmetric s-polynomial (without division) is returned
+EXAMPLE: example spoly; shows an example
+"
+{
+  if(typeof(f) != typeof(g))
+  {
+    ERROR("** arguments must be of same type");
+  }
+  if(size(#) == 0)
+  {
+     #[1]=0;
+  }
+
+  int e;
+  poly o = monomialLcm(f,g);
+
+  if( o == 0)                    //can only happen, if vectors f and g involve
+  {                              //different module components
+    vector sp;
+    return(sp);
+  }
+
+  poly m=(o/leadmonomial(f));         //compute the leading monomial as poly
+  poly n=(o/leadmonomial(g));
+
+  f = m * f;
+  g = n * g; // now they have the same LM!
+
+  if (#[1]==0)                    //the asymmetric s-poly
+  {
+    def sp = f - (leadcoef(f)/leadcoef(g))*g;
+  }
+  else                            //the symmetric s-poly, avoiding division
+  {
+    def sp = leadcoef(g)*f - leadcoef(f)*g;
+  }
+  return(sp);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r=0,(x,y,z),ls;
+   spoly(2x2+x2y,3y3+xyz);
+   ring s=0,(x,y,z),(c,dp);
+   spoly(2x2+x2y,3y3+xyz);
+   spoly(2x2+x2y,3y3+xyz,1);             //symmetric s-poly without division
+   spoly([5x2+x2y,z5],[x2,y3,y4]);       //s-poly for vectors
+}
+///////////////////////////////////////////////////////////////////////////////
+proc minEcart(def T,def h)
+"USAGE:   minEcart(T,h); T ideal or module, h poly or vector
+RETURN:  element g from T such that leadmonom(g) divides leadmonom(h)@*
+         ecart(g) is minimal with this property (if T != 0);
+         return 0 if T is 0 or h = 0
+EXAMPLE: example minEcart; shows an example
+"
+{
+  int i,k,e;
+  if (size(T)==0 or h==0 )       //trivial cases
+  {
+     h = 0;
+     return(h);
+  }
+//---- check whether some element in T has the same module component as h ----
+  int v;
+  intvec w;
+  T = simplify(T,2);
+
+  if (typeof(h) == "vector")
+  {
+     e=1;
+     v = leadexp(h)[nvars(basering)+1];
+     for( i=1; i<=size(T); i++)
+     {
+       w[i]=leadexp(T[i])[nvars(basering)+1];
+       if(v == w[i])
+       {
+         e=0;         //some element in T involves the same component as h
+       }
+     }
+  }
+  if ( e == 1 )       //no element in T involves the same component as h
+  {
+     h = 0;
+     return(h);
+  }
+
+  if (typeof(h) == "poly")   //for polys v=w[i] for all i
+  {
+    v = 1;
+    w[size(T)]=0;
+    w=w+1;
+  }
+
+//------ check whether for some g in T leadmonom(g) divides leadmonom(h) -----
+  def g = T[1];
+  poly f = leadmonomial(h);
+
+  for( i=1; i<=size(T); i++)
+  {
+    if( f/leadmonomial(T[i]) != 0 and v==w[i] )
+    {
+       g=T[i];
+       k=i;
+       break;
+    }
+  }
+  if (k == 0)        //no leadmonom(g) divides leadmonom(h)
+  {
+     g = 0;
+     return(g);
+  }
+//--look for T[i] with minimal ecart s.t.leadmonom(T[i]) divides leadmonom(h)--
+
+  for( i=k+1; i<=size(T); i++)
+  {
+    if( f/leadmonomial(T[i]) != 0 and v==w[i] )
+    {
+       if (ecart(T[i]) < ecart(g))
+       {
+         g=T[i];
+        }
+     }
+  }
+  return(g);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring R=0,(x,y,z),dp;
+   ideal T = x2y+x2,y3+xyz,xyz2+z4;
+   poly h = x2y2z2+x5+yx3+z6;
+   minEcart(T,h);"";
+   ring S=0,(x,y,z),(c,ds);
+   module T = [x2+x2y,y2],[y3+xyz,x3-z3],[x3y+z4,0,x2];
+   vector h = [x3y+x5+x2y2z2+z6,x3];
+   minEcart(T,h);
+}
+///////////////////////////////////////////////////////////////////////////////
+proc NFMora(def f,def G,list #)
+"USAGE:   NFMora(f,G[,s]); f poly or vector,G ideal or module, s int
+RETURN:  the Mora normal form of f w.r.t. G, same type as f
+         if s!=0 the symmetric s-polynomial (without division) is used
+NOTE:    Show comments if printlevel > 0, pauses computation if printlevel > 1
+EXAMPLE: example NFMora; shows an example
+"
+{
+  if(size(#) == 0)
+  {
+     #[1]=0;
+  }
+
+  int y = printlevel - voice + 2;
+  if( f==0 or size(G) ==0 )
+  {
+     if (y>0)
+     {
+        "// 1st or 2nd argument 0";
+     }
+     return(f);
+  }
+
+  int i,e;
+  def h = f;
+  def T = G;
+// -------------------- start with f to be reduced by G --------------------
+  if (y>0)
+  {"";
+   "// Input for NFMora is (f,T):";
+   "// f:"; f;
+   "// T:"; T;
+   "// Reduce f with T, eventually enlarging T for local ordering";
+  }
+
+// ----------------------- enter the reduction loop ------------------------
+  def g = minEcart(T,h);
+  while (h!=0 and g!=0)
+  {
+     if (y>0)
+     {  "";
+        "//                Reduction-step in NFMora:",i;
+        "// h = (f after",i,"reductions) reduction with g from T:";
+        "// g = element of minimal ecart in T s.t. LM(g)|LM(h):";
+        "// h:";h;
+        "// g:";g;
+     }
+     if (y>1)
+     {
+        pause("press <return> to continue");
+        "// T, set used for reduction:"; T;
+        pause("press <return> to continue");
+     }
+     e=0;
+     if( ecart(g) > ecart(h) )
+     {
+        T=T,h;  e=1;
+     }
+     if (y>0 )
+     {
+        "// T-set enlarged for next reduction? (yes/no = 1/0):  ", e;
+        if( e==1 )
+        {
+          "// T-set for next reduction got enlarged by h:";
+          "// h:";h;
+          if (y>1)
+          {
+             pause("press <return> to continue");
+          }
+        }
+     }
+     h = spoly(h,g,#[1]);
+     g = minEcart(T,h);
+     i=i+1;
+  }
+  if(y>0)
+  { "";
+    "// normal form is:";
+  }
+  return(h);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r=0,(x,y,z),dp;
+   poly f = x2y2z2+x5+yx3+z6-3y3;
+   ideal G = x2y+x2,y3+xyz,xyz2+z6;
+   NFMora(f,G);"";
+   ring s=0,(x,y,z),ds;
+   poly f = x3y+x5+x2y2z2+z6;
+   ideal G = x2+x2y,y3+xyz,x3y2+z4;
+   NFMora(f,G);"";
+   vector v = [f,x2+x2y];
+   module M = [x2+x2y,f],[y3+xyz,y3],[x3y2+z4,z2];
+   NFMora(v,M);
+}
+///////////////////////////////////////////////////////////////////////////////
+proc prodcrit(def f,def g,list #)
+"USAGE:   prodcrit(f,g[,o]); f,g poly or vector, and optional int argument o
+RETURN:  1 if product criterion applies in the same module component,
+         2 if lead(f) and lead(g) involve different components, 0 else
+NOTE:    if product criterion applies we can delete (f,g) from pairset.
+         This procedure returns 0 if o is given and is a positive integer, or
+         you may set the attribute \"default_arg\" for prodcrit to 1.
+EXAMPLE: example prodcrit; shows an example
+"
+{
+// ------------------ check for optional disabling argument -------------
+  if( size(#) > 0 )
+  {// "size(#): ", size(#);   "typeof(#[1]): ", typeof(#[1]);
+
+    if( typeof(#[1]) == "int" )
+    {// "#[1] = int ", #[1];
+      if( #[1] > 0 )
+      {
+        return(0);
+      }
+    }
+  }
+
+// ------------------- product criterion for polynomials ---------------------
+  if(typeof(f)=="poly")
+  {
+    if( monomialLcm(f,g)==leadmonom(f)*leadmonom(g))
+    {
+      return(1);
+    }
+    return(0);
+  }
+// ------------------- product criterion for modules ---------------------
+  if(sameComponent(f,g)==1)
+  {
+     if( monomialLcm(f,g)==leadmonomial(f)*leadmonomial(g) )
+     {
+         int c = leadexp(f)[nvars(basering)+1];  //component involving lead(f)
+         if((f-f[c]*gen(c))-(g-g[c]*gen(c))==0)  //other components are 0
+         {
+           return(1);
+         }
+     }
+     return(0);
+  }
+  return(2);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r=0,(x,y,z),dp;
+   poly f = y3z3+x5+yx3+z6;
+   poly g = x5+yx3;
+   prodcrit(f,g);
+   vector v = x3z2*gen(1)+x3y*gen(1)+x2y*gen(2);
+   vector w = y4*gen(1)+y3*gen(2)+xyz*gen(1);
+   prodcrit(v,w);
+}
+///////////////////////////////////////////////////////////////////////////////
+proc chaincrit(def f,def g,def h)
+"USAGE:   chaincrit(f,g,h); f,g,h poly or module
+RETURN:  1 if chain criterion applies, 0 else
+NOTE:    if chain criterion applies to f,g,h we can delete (g,h) from pairset
+EXAMPLE: example chaincrit; shows an example
+"
+{
+  if(sameComponent(f,g) and sameComponent(f,h))
+  {
+    if( monomialLcm(g,h)/leadmonomial(f) !=0 )
+    {
+      return(1);
+    }
+  }
+  return(0);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r=0,(x,y,z),dp;
+   poly f = x2y2z2+x5+yx3+z6;
+   poly g = x5+yx3;
+   poly h = y2z5+x5+yx3;
+   chaincrit(f,g,h);
+   vector u = [x2y3-z2,x2y];
+   vector v = [x2y2+z2,x2-y2];
+   vector w = [x2y4+z3,x2+y2];
+   chaincrit(u,v,w);
+}
+///////////////////////////////////////////////////////////////////////////////
+proc pairset(def G)
+"USAGE:   pairset(G); G ideal or module
+RETURN:  list L,
+         L[1] = the pairset of G as list (not containing pairs for
+         which the product or the chain criterion applies),
+         L[2] = intvec v, v[1]= # product criterion, v[2]= # chain criterion
+EXAMPLE: example pairset; shows an example
+"
+{
+   int i,j,k,s,c,ccrit,pcrit,pr;
+   int y = printlevel - voice + 2;
+   G = simplify(G,10);
+   def g = G;
+   ideal pair;
+   list P,I;      //P=pairlist of G, I=list of corresponding indices of pairs
+   for (i=1; i<=size(G); i++)
+   {
+      for(j = i+1; j<=size(G); j++)
+      {
+         pr = prodcrit(G[i],G[j]);       //check first product criterion
+         if( pr != 0 )
+         {
+            pcrit=pcrit+(pr==1);
+         }
+         else
+         {
+            s = size(P);                //now check chain criterion
+            for(k=1; k<=s; k++)
+            {
+              if( i==I[k][2] )
+              {
+                if ( chaincrit(P[k][1],P[k][2],G[j]) )
+                {                     //need not include (G[i],G[j]) in P
+                  c=1; ccrit=ccrit+1;
+                  break;
+                }
+              }
+              if( j==I[k][1] and c==0 )
+              {
+                "########### enter pairset2 #############";
+                if ( chaincrit(G[i],P[k][1],P[k][2]) )
+                {                     //can delete P[k]=(P[k][1],P[k][2])
+                  ccrit=ccrit+1;
+                  P = delete(P,k);
+                  s = s-1;
+                }
+              }
+            }
+            if ( c==0 )
+            {
+               g = G[i],G[j];
+               P[s+1]=g;
+               I[s+1]=intvec(i,j);
+            }
+            c=0;
+         }
+      }
+   }
+   if (y>0)
+   {  "";
+      "// product criterion:",pcrit," chain criterion:",ccrit;
+   }
+   intvec v = pcrit,ccrit;
+   P=P,v;
+   return(P);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r=0,(x,y,z),dp;
+   ideal G = x2y+x2,y3+xyz,xyz2+z4;
+   pairset(G);"";
+   module T = [x2y3-z2,x2y],[x2y2+z2,x2-y2],[x2y4+z3,x2+y2];
+   pairset(T);
+}
+///////////////////////////////////////////////////////////////////////////////
+proc updatePairs(def P,def S,def h)
+"USAGE:   updatePairs(P,S,h); P list, S ideal or module, h poly or vector@*
+         P a list of pairs of polys or vectors (obtained from pairset)
+RETURN:  list Q,
+         Q[1] = the pairset P enlarged  by all pairs (f,h), f from S,
+         without pairs for which the product or the chain criterion applies@*
+         Q[2] = intvec v, v[1]= # product criterion, v[2]= # chain criterion
+EXAMPLE: example updatePairs; shows an example
+"
+{
+   int i,j,k,s,r,c,ccrit,pcrit,pr;
+   int y = printlevel - voice + 2;
+   ideal pair;
+   list Q = P;           //Q will become enlarged pairset
+   s = size(P);
+   r = size(Q);          //r will grow with Q
+   list R;
+   def g = S;            //give g the correct type ideal/module
+   for (i=1; i<=size(S); i++)
+   {
+      pr =  prodcrit(h,S[i]);
+      if( pr != 0 )     //check product criterion
+      {
+        pcrit=pcrit+(pr==1);       //count product criterion in same component
+      }
+      else
+      {                 //prodcrit did not apply, check for chaincrit
+         r=size(Q);
+         for(k=1; k<=r; k++)
+         {
+           if( Q[k][2]==S[i] )    //S[i]=Q[k][2]
+           {
+             if( chaincrit(Q[k][1],S[i],h) )
+             {                   //can forget (S[i],h)
+                c=1; ccrit=ccrit+1;
+                break;
+             }
+           }
+         }
+         if ( c==0 )
+         {
+            g = S[i],h;        //add pair (S[i],h)
+            Q[r+1] = g;
+         }
+         c=0;
+      }
+   }
+   if (y>0)
+   {  "";;
+      "// product criterion:",pcrit," chain criterion:",ccrit;
+   }
+   intvec v = pcrit,ccrit;
+   Q = Q,v;
+   return(Q);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring R1=0,(x,y,z),(c,dp);
+   ideal S = x2y+x2,y3+xyz;
+   poly h = x2y+xyz;
+   list P = pairset(S)[1];
+   P;"";
+   updatePairs(P,S,h);"";
+   module T = [x2y3-z2,x2y],[x2y4+z3,x2+y2];
+   P = pairset(T)[1];
+   P;"";
+   updatePairs(P,T,[x2+x2y,y3+xyz]);
+}
+///////////////////////////////////////////////////////////////////////////////
+proc standard(def id, list #)
+"USAGE:   standard(i[,s]); id ideal or module, s int
+RETURN:  a standard basis of id, using generalized Mora's algorithm
+         which is Buchberger's algorithm for global monomial orderings.
+         If s!=0 the symmetric s-polynomial (without division) is used
+NOTE:    Show comments if printlevel > 0, pauses computation if printlevel > 1
+EXAMPLE: example standard; shows an example
+"
+{
+  if(size(#) == 0)
+  {
+     #[1]=0;
+  }
+
+   def S = id;                 //S will become the standard basis of id
+   def h = S[1];
+   int i,z;
+   int y = printlevel - voice + 2;
+   if(y>0)
+   {  "";
+      "// the set S, to become a standard basis:"; S;
+      if(y>1)
+      {
+         "// create pairset, i.e. pairs from S,";
+         "// after application of product and chain criterion";
+      }
+   }
+   list P = pairset(S);        //create pairset of S=id
+   intvec v = P[2];
+   P = P[1];
+//-------------------------- Main loop in SB lgorithm ----------------------
+   while (size(P) !=0)
+   {  z=z+1;
+      if(y>0)
+      {  "";
+         "//              Enter NFMora for next pair, count",z;
+         "// size of partial standard basis S:    (",size(S),")";
+         "// number of pairs of S after updating: (",size(P),")";
+         if(y>1)
+         {
+            "// 1st pair of new pairset:"; P[1];
+            "// set T=S used for reduction:";S;
+            "// apply NFMora to (spoly,S), spoly = spoly(1st pair)";
+         }
+      }
+      //-------------------- apply NFMora = Mora's normal form -------------
+      h = spoly(P[1][1],P[1][2],#[1]);
+      if(y>1)
+      {
+         "// spoly:";h;
+      }
+      h = NFMora(h,S,#[1]);
+      if(h==0)           //normal form is 0
+      {
+         if(y==1)
+         {
+            "// pair has reduced to 0";
+         }
+          if(y>1)
+         { h;"";
+           pause("press <return> to continue");
+         }
+     }
+      P = delete(P,1);   //spoly of pair reduced to 0, pair can be deleted
+      //--- spoly of pair did not reduce to 0, update S and paiset of S ----
+      if( h != 0)
+      {
+         if(y==1)
+         {
+            "// ** new spoly in degree **:", deg(h);
+         }
+         if(y>1)
+         { h;"";
+           pause("press <return> to continue");
+           "// update pairset";
+         }
+        P=updatePairs(P,S,h);    //update P (=paisert of S)
+        v=v+P[2];                //with useful pairs (g,h), g from S
+         P=P[1];
+         S=S,h;                  //update S, will become the standard basis
+      }
+   }
+//------------------------------ finished ---------------------------------
+   if( find(option(),"prot") or y>0 )
+   {  "";                //show how often prodcrit and chaincrit applied
+      "// product criterion:",v[1]," chain criterion:",v[2];
+      "";
+      "// Final standard basis:";
+   }
+   return(S);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring r=0,(x,y,z),dp;
+   ideal G = x2y+x2,y3+xyz,xyz2+z4;
+   standard(G);"";
+   ring s=0,(x,y,z),(c,ds);
+   ideal G = 2x2+x2y,y3+xyz,3x3y+z4;
+   standard(G);"";
+   standard(G,1);"";           //use symmetric s-poly without division
+   module M = [2x2,x3y+z4],[3y3+xyz,y3],[5z4,z2];
+   standard(M);
+}
+///////////////////////////////////////////////////////////////////////////////
+proc localstd (def id)
+"USAGE:   localstd(id); id = ideal
+RETURN:  A standard basis for a local degree ordering, using Lazard's method.
+NOTE:    The procedure homogenizes id w.r.t. a new 1st variable local at t,
+         computes a SB w.r.t. (dp(1),dp) and substitutes local at t by 1.
+         Hence the result is a SB with respect to an ordering which sorts
+         first w.r.t. the subdegree of the original variables and then refines
+         it with dp. This is the local degree ordering ds.
+         localstd may be used in order to avoid cancellation of units and thus
+         to be able to use option(contentSB) also for local orderings.
+EXAMPLE: example localstd; shows an example
+"
+{
+  int ii;
+  def bas = basering;
+  execute("ring  @r_locstd
+     =("+charstr(bas)+"),(local at t,"+varstr(bas)+"),(dp(1),dp);");
+  ideal id = imap(bas,id);
+  ideal hid = homog(id,local at t);
+  hid = std(hid);
+  hid = subst(hid,local at t,1);
+  setring bas;
+  def hid = imap(@r_locstd,hid);
+  attrib(hid,"isSB",1);
+  kill @r_locstd;
+  return(hid);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring R = 0,(x,y,z),ds;
+   ideal i  = xyz+z5,2x2+y3+z7,3z5+y5;
+   localstd(i);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+/*
+// some examples:
+LIB"teachstd.lib";
+option(prot); printlevel=3;
+ring r0 = 0,(t,x,y),lp;
+ideal i = x-t2,y-t3;
+standard(i);
+
+printlevel=1;
+standard(i);
+
+option(prot); printlevel =1;
+ring r1 = (0,a,b),(x,y,z),(c,ds);
+module M = [ax2,bx3y+z4],[a3y3+xyz,by3],[5az4,(a+b)*z2];
+module N1= std(M);
+module N2 = standard(M,1);
+NF(lead(N2),lead(N1));
+NF(lead(N1),lead(N2));rom T
+ring r2 = 0,(x,y,z),dp;
+ideal I = x2y+x2,y3+xyz,xyz2+z4;
+option(prot);
+int tt = timer;
+ideal J = standard(I);
+timer -tt;                 //4sec, product criterion: 9  chain criterion: 6
+ideal J1 = std(I);
+NF(lead(J),lead(J1));
+NF(lead(J1),lead(J));
+
+ring r3 = 0,(x,y,z),ds;
+poly f = x3*y4+z5+xyz;
+ideal I = f,jacob(f);
+option(prot);
+int tt = timer;
+ideal J = standard(I);
+timer -tt;                 //3sec, product criterion: 1  chain criterion: 3
+ideal J1 = std(I);
+NF(lead(J),lead(J1));
+NF(lead(J1),lead(J));
+
+//Becker:
+ring r4 = 32003,(x,y,z),lp;
+ideal I = x3-1, y3-1,
+-27x3-243x2y+27x2z-729xy2+162xyz-9xz2-729y3+243y2z-27yz2+z3-27;
+option(prot);
+int tt = timer;
+ideal J = standard(I);
+timer -tt;                 //201sec, product criterion: 42  chain criterion: 33
+ideal J1 = std(I);
+NF(lead(J),lead(J1));
+NF(lead(J1),lead(J));
+
+//Alex
+ring r5 = 32003,(x,y,z,t),dp;
+ideal I =
+2t3xy2z+x2ty+2x2y,
+2tz+y3x2t+z2t3y2x;
+option(prot); printlevel =1;
+ideal J1 = std(I);
+int tt = timer;
+ideal J = standard(I);
+timer -tt;                 //15sec product criterion: 0  chain criterion: 12
+NF(lead(J),lead(J1));
+NF(lead(J1),lead(J));
+
+ring r6 = 32003,(x,y,z,t),dp; //is already SB for ds, for dp too long
+ideal I=
+9x8+y7t3z4+5x4y2t2+2xy2z3t2,
+9y8+7xy6t+2x5y4t2+2x2yz3t2,
+9z8+3x2y3z2t4;
+option(prot);
+int tt = timer;
+ideal J = standard(I);
+timer -tt;                 //0sec, product criterion: 3  chain criterion: 0
+ideal J1 = std(I);
+NF(lead(J),lead(J1));
+NF(lead(J1),lead(J));
+
+
+*/
+
diff --git a/Singular/LIB/template.lib b/Singular/LIB/template.lib
new file mode 100644
index 0000000..42a64e5
--- /dev/null
+++ b/Singular/LIB/template.lib
@@ -0,0 +1,116 @@
+////////////////////////////////////////////////////////////////
+version="version template.lib 4.0.0.0 Jun_2013 "; // $Id: 8831501251e6607a4e30cef97bd72587addbf16f $
+category="Miscellaneous";
+// summary description of the library
+info="
+LIBRARY:   template.lib  A Template for a Singular Library
+AUTHOR:    Olaf Bachmann, email: obachman at mathematik.uni-kl.de
+
+SEE ALSO:  standard_lib, Libraries,
+           Typesetting of help and info strings
+
+KEYWORDS: library, template.lib; template.lib; library, info string
+
+PROCEDURES:
+  mdouble(int)           return double of int argument
+  mtriple(int)          return three times int argument
+  msum([int,..,int])     sum of int arguments
+";
+////////////////////////////////////////////////////////////////////
+proc mdouble(int i)
+"USAGE:    mdouble(i); i int
+RETURN:   int: i+i
+NOTE:     Help string is in pure ASCII.
+          This line starts on a new line since previous line is short.
+          No new line here.
+SEE ALSO: msum, mtriple, Typesetting of help and info strings
+KEYWORDS: procedure, ASCII help
+EXAMPLE:  example mdouble; shows an example"
+{
+  return (i + i);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  mdouble(0);
+  mdouble(-1);
+}
+////////////////////////////////////////////////////////////////////
+proc mtriple(int i)
+"@c we do texinfo here
+ at table @asis
+ at item @strong{Usage:}
+ at code{mtriple(i)}; @code{i} int
+
+ at item @strong{Return:}
+int: @math{i+i+i}
+ at item @strong{Note:}
+Help is in pure Texinfo.
+@*This help string is written in texinfo, which enables you to use,
+among others, the @@math command for mathematical typesetting
+(for instance, to print @math{\alpha, \beta}).
+@*Texinfo also gives more control over the layout, but is, admittingly,
+more cumbersome to write.
+ at end table
+ at c use @c ref contstuct for references
+ at cindex procedure, texinfo help
+ at c ref
+ at strong{See also:}
+ at ref{mdouble}, @ref{msum}, @ref{Typesetting of help and info strings}
+ at c ref
+"
+{
+  return (i + i + i);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  mtriple(0);
+  mtriple(-1);
+}
+////////////////////////////////////////////////////////////////////
+proc msum(list #)
+"USAGE:  msum([i_1,..,i_n]); @code{i_1,..,i_n} def
+RETURN:  Sum of int arguments
+NOTE:    This help string is written in a mixture of ASCII and texinfo.
+         @* Use @ref for references (e.g.,  @pxref{mtriple}).
+         @* Use @code for typewriter font (e.g., @code{i_1}).
+         @* Use @math for simple math mode typesetting (e.g., @math{i_1}).
+         @* Warning: Parenthesis like } are not allowed inside @math and @code.
+         @* Use @example for indented, preformatted text typesetting in
+         typewriter font:
+ at example
+         this  --> that
+ at end example
+        Use @format for preformatted text typesetting in normal font:
+ at format
+         this --> that
+ at end format
+        Use @texinfo for text in pure texinfo:
+ at texinfo
+ at expansion{}
+ at tex
+$i_{1,1}$
+ at end tex
+
+ at end texinfo
+        Note that
+        automatic linebreaking         is still in affect (like in this line).
+SEE ALSO: mdouble, mtriple, Typesetting of help and info strings
+KEYWORDS: procedure, ASCII/Texinfo help
+EXAMPLE: example msum; shows an example"
+{
+  if (size(#) == 0) { return (0);}
+  if (size(#) == 1) { return (#[1]);}
+  int i;
+  def s = #[1];
+  for (i=2; i<=size(#); i++)
+  {
+    s = s + #[i];
+  }
+  return (s);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+  msum();
+  msum(4);
+  msum(1,2,3,4);
+}
diff --git a/Singular/LIB/toric.lib b/Singular/LIB/toric.lib
new file mode 100644
index 0000000..b506a9f
--- /dev/null
+++ b/Singular/LIB/toric.lib
@@ -0,0 +1,1098 @@
+///////////////////////////////////////////////////////////////////////////
+version="version toric.lib 4.0.0.0 Jun_2013 "; // $Id: 44e022afa582b7932c0f81c814395695cf47d67f $
+category="Commutative Algebra";
+info="
+LIBRARY: toric.lib   Standard Basis of Toric Ideals
+AUTHOR:  Christine Theis, email: ctheis at math.uni-sb.de
+
+PROCEDURES:
+toric_ideal(A,..);   computes the toric ideal of A
+toric_std(ideal I);  standard basis of I by a specialized Buchberger algorithm
+";
+
+///////////////////////////////////////////////////////////////////////////////
+
+static proc toric_ideal_1(intmat A, string alg)
+{
+  ideal I;
+  // to be returned
+
+  // check suitability of actual basering
+  if(nvars(basering)<ncols(A))
+  {
+    ERROR("The number of matrix columns is smaller than the number of ring variables.");
+  }
+
+  // check suitability of actual term ordering
+  // the "module ordering" c or C is ignored
+  string singular_ord=ordstr(basering);
+  string test_ord;
+  string external_ord="";
+  int i,j;
+  intvec weightvec;
+
+  if(find(singular_ord,"lp")==1)
+  {
+    external_ord="W_LEX";
+    for(i=1;i<=nvars(basering);i++)
+    {
+      weightvec[i]=0;
+    }
+    test_ord="lp("+string(nvars(basering))+"),";
+    if(singular_ord!=(test_ord+"C") && singular_ord!=(test_ord+"c"))
+    {
+      "Warning: Block orderings are not supported; lp used for computation.";
+    }
+  }
+  if(external_ord=="" && find(singular_ord,"lp")==3)
+  {
+    external_ord="W_LEX";
+    for(i=1;i<=nvars(basering);i++)
+    {
+      weightvec[i]=0;
+    }
+    test_ord="lp("+string(nvars(basering))+"),";
+    if(singular_ord!=("C"+test_ord) && singular_ord!=("c"+test_ord))
+    {
+      "Warning: Block orderings are not supported; lp used for computation.";
+    }
+  }
+
+  if(external_ord=="" && find(singular_ord,"dp")==1)
+  {
+    external_ord="W_REV_LEX";
+    for(i=1;i<=nvars(basering);i++)
+    {
+      weightvec[i]=1;
+    }
+    test_ord="dp("+string(nvars(basering))+"),";
+    if(singular_ord!=(test_ord+"C") && singular_ord!=(test_ord+"c"))
+    {
+      "Warning: Block orderings are not supported; dp used for computation.";
+    }
+  }
+  if(external_ord=="" && find(singular_ord,"dp")==3)
+  {
+    external_ord="W_REV_LEX";
+    for(i=1;i<=nvars(basering);i++)
+    {
+      weightvec[i]=1;
+    }
+    test_ord="dp("+string(nvars(basering))+"),";
+    if(singular_ord!=("C"+test_ord) && singular_ord!=("c"+test_ord))
+    {
+      "Warning: Block orderings are not supported; dp used for computation.";
+    }
+  }
+
+  if(external_ord=="" && find(singular_ord,"Dp")==1)
+  {
+    external_ord="W_LEX";
+    for(i=1;i<=nvars(basering);i++)
+    {
+      weightvec[i]=1;
+    }
+    test_ord="Dp("+string(nvars(basering))+"),";
+    if(singular_ord!=(test_ord+"C") && singular_ord!=(test_ord+"c"))
+    {
+      "Warning: Block orderings are not supported; Dp used for computation.";
+    }
+  }
+  if(external_ord=="" && find(singular_ord,"Dp")==3)
+  {
+    external_ord="W_LEX";
+    for(i=1;i<=nvars(basering);i++)
+    {
+      weightvec[i]=1;
+    }
+    test_ord="Dp("+string(nvars(basering))+"),";
+    if(singular_ord!=("C"+test_ord) && singular_ord!=("c"+test_ord))
+    {
+      "Warning: Block orderings are not supported; Dp used for computation.";
+    }
+  }
+
+  int pos;
+  string number_string;
+
+  if(external_ord=="" && find(singular_ord,"wp")==1)
+  {
+    external_ord="W_REV_LEX";
+    pos=3;
+    for(i=1;i<=nvars(basering);i++)
+    {
+      pos++;
+      number_string="";
+      while(singular_ord[pos]!=",")
+      {
+        number_string=number_string+singular_ord[pos];
+        pos++;
+      }
+      execute("weightvec[i]="+number_string);
+    }
+    test_ord="wp("+string(weightvec)+"),";
+    if(singular_ord!=(test_ord+"C") && singular_ord!=(test_ord+"c"))
+    {
+      "Warning: Block orderings are not supported; wp("+string(weightvec)+") used for computation.";
+    }
+  }
+  if(external_ord=="" && find(singular_ord,"wp")==3)
+  {
+    external_ord="W_REV_LEX";
+    pos=5;
+    for(i=1;i<=nvars(basering);i++)
+    {
+      pos++;
+      number_string="";
+      while(singular_ord[pos]!=",")
+      {
+        number_string=number_string+singular_ord[pos];
+        pos++;
+      }
+      execute("weightvec[i]="+number_string);
+    }
+    test_ord="wp("+string(weightvec)+"),";
+    if(singular_ord!=("C"+test_ord) && singular_ord!=("c"+test_ord))
+    {
+      "Warning: Block orderings are not supported; wp("+string(weightvec)+") used for computation.";
+    }
+  }
+
+  if(external_ord=="" && find(singular_ord,"Wp")==1)
+  {
+    external_ord="W_LEX";
+    pos=3;
+    for(i=1;i<=nvars(basering);i++)
+    {
+      pos++;
+      number_string="";
+      while(singular_ord[pos]!=",")
+      {
+        number_string=number_string+singular_ord[pos];
+        pos++;
+      }
+      execute("weightvec[i]="+number_string);
+    }
+    test_ord="Wp("+string(weightvec)+"),";
+    if(singular_ord!=(test_ord+"C") && singular_ord!=(test_ord+"c"))
+    {
+      "Warning: Block orderings are not supported; Wp("+string(weightvec)+") used for computation.";
+    }
+  }
+  if(external_ord=="" && find(singular_ord,"Wp")==3)
+  {
+    external_ord="W_LEX";
+    pos=5;
+    for(i=1;i<=nvars(basering);i++)
+    {
+      pos++;
+      number_string="";
+      while(singular_ord[pos]!=",")
+      {
+        number_string=number_string+singular_ord[pos];
+        pos++;
+      }
+      execute("weightvec[i]="+number_string);
+    }
+    test_ord="Wp("+string(weightvec)+"),";
+    if(singular_ord!=("C"+test_ord) && singular_ord!=("c"+test_ord))
+    {
+      "Warning: Block orderings are not supported; Wp("+string(weightvec)+") used for computation.";
+    }
+  }
+
+  if(external_ord=="")
+  {
+    ERROR("The term ordering of the actual basering is not supported.");
+  }
+
+  // check algorithm
+  if(alg=="ct" || alg=="pct")
+    // these algorithms will not cause an error in the external program;
+    // however, they do not compute the toric ideal of A, but of an
+    // extended matrix
+  {
+    ERROR("The chosen algorithm is not suitable.");
+  }
+
+  // create temporary file with which the external program is called
+
+  int dummy;
+  int process=system("pid");
+  string matrixfile="temp_MATRIX"+string(process);
+  link MATRIX=":w "+matrixfile;
+  open(MATRIX);
+
+  write(MATRIX,"MATRIX","columns:",ncols(A),"cost vector:");
+  for(j=1;j<=ncols(A);j++)
+  {
+    write(MATRIX,weightvec[j]);
+  }
+  write(MATRIX,"rows:",nrows(A),"matrix:");
+  for(i=1;i<=nrows(A);i++)
+  {
+    for(j=1;j<=ncols(A);j++)
+    {
+      write(MATRIX,A[i,j]);
+    }
+  }
+
+  // search for positive row space vector, if required by the
+  // algorithm
+  int found=0;
+  if((alg=="blr") || (alg=="hs"))
+  {
+    for(i=1;i<=nrows(A);i++)
+    {
+      found=i;
+      for(j=1;j<=ncols(A);j++)
+      {
+        if(A[i,j]<=0)
+        {
+          found=0;
+        }
+      }
+      if(found>0)
+      {
+        break;
+      }
+    }
+    if(found==0)
+    {
+      close(MATRIX);
+      dummy=system("sh","rm -f "+matrixfile);
+      ERROR("The chosen algorithm needs a positive vector in the row space of the matrix.");
+    }
+    write(MATRIX,"positive row space vector:");
+    for(j=1;j<=ncols(A);j++)
+    {
+      write(MATRIX,A[found,j]);
+    }
+  }
+  close(MATRIX);
+
+
+  // call external program
+  dummy=system("sh","toric_ideal -alg "+alg+" "+matrixfile);
+  if (dummy!=0) { ERROR("toric_ideal failed with error code "+string(dummy)); }
+
+  // read toric ideal from created file
+  link TORIC_IDEAL=":r "+matrixfile+".GB."+alg;
+  string toric_id=read(TORIC_IDEAL);
+
+  int generators;
+  pos=find(toric_id,"size");
+  pos=find(toric_id,":",pos);
+  pos++;
+
+  while(toric_id[pos]==" " || toric_id[pos]==newline)
+  {
+    pos++;
+  }
+  number_string="";
+  while(toric_id[pos]!=" " && toric_id[pos]!=newline)
+  {
+    number_string=number_string+toric_id[pos];
+    pos++;
+  }
+  execute("generators="+number_string+";");
+
+  intvec v;
+  poly head;
+  poly tail;
+
+  pos=find(toric_id,"basis");
+  pos=find(toric_id,":",pos);
+  pos++;
+
+  for(i=1;i<=generators;i++)
+  {
+    head=1;
+    tail=1;
+
+    for(j=1;j<=ncols(A);j++)
+    {
+      while(toric_id[pos]==" " || toric_id[pos]==newline)
+      {
+        pos++;
+      }
+      number_string="";
+      while(toric_id[pos]!=" " && toric_id[pos]!=newline)
+      {
+        number_string=number_string+toric_id[pos];
+        pos++;
+      }
+      execute("v[j]="+number_string+";");
+      if(v[j]<0)
+      {
+        tail=tail*var(j)^(-v[j]);
+      }
+      if(v[j]>0)
+      {
+        head=head*var(j)^v[j];
+      }
+    }
+    I[i]=head-tail;
+  }
+
+  // delete all created files
+  dummy=system("sh","rm -f "+matrixfile);
+  dummy=system("sh","rm -f "+matrixfile+".GB."+alg);
+
+  return(I);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+static proc toric_ideal_2(intmat A, string alg, intvec prsv)
+{
+  ideal I;
+  // to be returned
+
+  // check arguments
+  if(size(prsv)<ncols(A))
+  {
+    ERROR("The number of matrix columns does not equal the size of the positive row space vector.");
+  }
+
+  // check suitability of actual basering
+  if(nvars(basering)!=ncols(A))
+  {
+    ERROR("The number of matrix columns is smaller than the number of ring variables.");
+  }
+
+  // check suitability of actual term ordering
+  // the "module ordering" c or C is ignored
+  string singular_ord=ordstr(basering);
+  string test_ord;
+  string external_ord="";
+  int i,j;
+  intvec weightvec;
+
+  if(find(singular_ord,"lp")==1)
+  {
+    external_ord="W_LEX";
+    for(i=1;i<=nvars(basering);i++)
+    {
+      weightvec[i]=0;
+    }
+    test_ord="lp("+string(nvars(basering))+"),";
+    if(singular_ord!=(test_ord+"C") && singular_ord!=(test_ord+"c"))
+    {
+      "Warning: Block orderings are not supported; lp used for computation.";
+    }
+  }
+  if(external_ord=="" && find(singular_ord,"lp")==3)
+  {
+    external_ord="W_LEX";
+    for(i=1;i<=nvars(basering);i++)
+    {
+      weightvec[i]=0;
+    }
+    test_ord="lp("+string(nvars(basering))+"),";
+    if(singular_ord!=("C"+test_ord) && singular_ord!=("c"+test_ord))
+    {
+      "Warning: Block orderings are not supported; lp used for computation.";
+    }
+  }
+
+  if(external_ord=="" && find(singular_ord,"dp")==1)
+  {
+    external_ord="W_REV_LEX";
+    for(i=1;i<=nvars(basering);i++)
+    {
+      weightvec[i]=1;
+    }
+    test_ord="dp("+string(nvars(basering))+"),";
+    if(singular_ord!=(test_ord+"C") && singular_ord!=(test_ord+"c"))
+    {
+      "Warning: Block orderings are not supported; dp used for computation.";
+    }
+  }
+  if(external_ord=="" && find(singular_ord,"dp")==3)
+  {
+    external_ord="W_REV_LEX";
+    for(i=1;i<=nvars(basering);i++)
+    {
+      weightvec[i]=1;
+    }
+    test_ord="dp("+string(nvars(basering))+"),";
+    if(singular_ord!=("C"+test_ord) && singular_ord!=("c"+test_ord))
+    {
+      "Warning: Block orderings are not supported; dp used for computation.";
+    }
+  }
+
+  if(external_ord=="" && find(singular_ord,"Dp")==1)
+  {
+    external_ord="W_LEX";
+    for(i=1;i<=nvars(basering);i++)
+    {
+      weightvec[i]=1;
+    }
+    test_ord="Dp("+string(nvars(basering))+"),";
+    if(singular_ord!=(test_ord+"C") && singular_ord!=(test_ord+"c"))
+    {
+      "Warning: Block orderings are not supported; Dp used for computation.";
+    }
+  }
+  if(external_ord=="" && find(singular_ord,"Dp")==3)
+  {
+    external_ord="W_LEX";
+    for(i=1;i<=nvars(basering);i++)
+    {
+      weightvec[i]=1;
+    }
+    test_ord="Dp("+string(nvars(basering))+"),";
+    if(singular_ord!=("C"+test_ord) && singular_ord!=("c"+test_ord))
+    {
+      "Warning: Block orderings are not supported; Dp used for computation.";
+    }
+  }
+
+  int pos;
+  string number_string;
+
+  if(external_ord=="" && find(singular_ord,"wp")==1)
+  {
+    external_ord="W_REV_LEX";
+    pos=3;
+    for(i=1;i<=nvars(basering);i++)
+    {
+      pos++;
+      number_string="";
+      while(singular_ord[pos]!=",")
+      {
+        number_string=number_string+singular_ord[pos];
+        pos++;
+      }
+      execute("weightvec[i]="+number_string);
+    }
+    test_ord="wp("+string(weightvec)+"),";
+    if(singular_ord!=(test_ord+"C") && singular_ord!=(test_ord+"c"))
+    {
+      "Warning: Block orderings are not supported; wp("+string(weightvec)+") used for computation.";
+    }
+  }
+  if(external_ord=="" && find(singular_ord,"wp")==3)
+  {
+    external_ord="W_REV_LEX";
+    pos=5;
+    for(i=1;i<=nvars(basering);i++)
+    {
+      pos++;
+      number_string="";
+      while(singular_ord[pos]!=",")
+      {
+        number_string=number_string+singular_ord[pos];
+        pos++;
+      }
+      execute("weightvec[i]="+number_string);
+    }
+    test_ord="wp("+string(weightvec)+"),";
+    if(singular_ord!=("C"+test_ord) && singular_ord!=("c"+test_ord))
+    {
+      "Warning: Block orderings are not supported; wp("+string(weightvec)+") used for computation.";
+    }
+  }
+
+  if(external_ord=="" && find(singular_ord,"Wp")==1)
+  {
+    external_ord="W_LEX";
+    pos=3;
+    for(i=1;i<=nvars(basering);i++)
+    {
+      pos++;
+      number_string="";
+      while(singular_ord[pos]!=",")
+      {
+        number_string=number_string+singular_ord[pos];
+        pos++;
+      }
+      execute("weightvec[i]="+number_string);
+    }
+    test_ord="Wp("+string(weightvec)+"),";
+    if(singular_ord!=(test_ord+"C") && singular_ord!=(test_ord+"c"))
+    {
+      "Warning: Block orderings are not supported; Wp("+string(weightvec)+") used for computation.";
+    }
+  }
+  if(external_ord=="" && find(singular_ord,"Wp")==3)
+  {
+    external_ord="W_LEX";
+    pos=5;
+    for(i=1;i<=nvars(basering);i++)
+    {
+      pos++;
+      number_string="";
+      while(singular_ord[pos]!=",")
+      {
+        number_string=number_string+singular_ord[pos];
+        pos++;
+      }
+      execute("weightvec[i]="+number_string);
+    }
+    test_ord="Wp("+string(weightvec)+"),";
+    if(singular_ord!=("C"+test_ord) && singular_ord!=("c"+test_ord))
+    {
+      "Warning: Block orderings are not supported; Wp("+string(weightvec)+") used for computation.";
+    }
+  }
+
+  if(external_ord=="")
+  {
+    ERROR("The term ordering of the actual basering is not supported.");
+  }
+
+  // check algorithm
+  if(alg=="ct" || alg=="pct")
+    // these algorithms will not cause an error in the external program;
+    // however, they do not compute the toric ideal of A, but of an
+    // extended matrix
+  {
+    ERROR("The chosen algorithm is not suitable.");
+  }
+
+  // create temporary file with that the external program is called
+
+  int dummy;
+  int process=system("pid");
+  string matrixfile="temp_MATRIX"+string(process);
+  link MATRIX=":w "+matrixfile;
+  open(MATRIX);
+
+  write(MATRIX,"MATRIX","columns:",ncols(A),"cost vector:");
+  for(j=1;j<=ncols(A);j++)
+  {
+    write(MATRIX,weightvec[j]);
+  }
+  write(MATRIX,"rows:",nrows(A),"matrix:");
+  for(i=1;i<=nrows(A);i++)
+  {
+    for(j=1;j<=ncols(A);j++)
+    {
+      write(MATRIX,A[i,j]);
+    }
+  }
+
+  // enter positive row space vector, if required by the algorithm
+  if((alg=="blr") || (alg=="hs"))
+  {
+    write(MATRIX,"positive row space vector:");
+    for(j=1;j<=ncols(A);j++)
+    {
+      write(MATRIX,prsv[j]);
+    }
+  }
+  close(MATRIX);
+
+  // call external program
+  dummy=system("sh","toric_ideal -alg "+alg+" "+matrixfile);
+  if (dummy!=0) { ERROR("toric_ideal failed with error code "+string(dummy)); }
+
+  // read toric ideal from created file
+  link TORIC_IDEAL=":r "+matrixfile+".GB."+alg;
+  string toric_id=read(TORIC_IDEAL);
+
+  int generators;
+  pos=find(toric_id,"size");
+  pos=find(toric_id,":",pos);
+  pos++;
+
+  while(toric_id[pos]==" " || toric_id[pos]==newline)
+  {
+    pos++;
+  }
+  number_string="";
+  while(toric_id[pos]!=" " && toric_id[pos]!=newline)
+  {
+    number_string=number_string+toric_id[pos];
+    pos++;
+  }
+  execute("generators="+number_string+";");
+
+  intvec v;
+  poly head;
+  poly tail;
+
+  pos=find(toric_id,"basis");
+  pos=find(toric_id,":",pos);
+  pos++;
+
+  for(i=1;i<=generators;i++)
+  {
+    head=1;
+    tail=1;
+
+    for(j=1;j<=ncols(A);j++)
+    {
+      while(toric_id[pos]==" " || toric_id[pos]==newline)
+      {
+        pos++;
+      }
+      number_string="";
+      while(toric_id[pos]!=" " && toric_id[pos]!=newline)
+      {
+        number_string=number_string+toric_id[pos];
+        pos++;
+      }
+      execute("v[j]="+number_string+";");
+      if(v[j]<0)
+      {
+        tail=tail*var(j)^(-v[j]);
+      }
+      if(v[j]>0)
+      {
+        head=head*var(j)^v[j];
+      }
+    }
+    I[i]=head-tail;
+  }
+
+  // delete all created files
+  dummy=system("sh","rm -f "+matrixfile);
+  dummy=system("sh","rm -f "+matrixfile+".GB."+alg);
+
+  return(I);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc toric_ideal
+"USAGE: toric_ideal(A,alg);      A intmat, alg string
+        toric_ideal(A,alg,prsv); A intmat, alg string, prsv intvec
+RETURN: ideal: standard basis of the toric ideal of A
+NOTE:   These procedures return the standard basis of the toric ideal of A
+        with respect to the term ordering in the current basering. Not all
+        term orderings are supported: The usual global term orderings may be
+        used, but no block orderings combining them.
+        One may call the procedure with several different algorithms: @*
+        - the algorithm of Conti/Traverso using elimination (ect), @*
+        - the algorithm of Pottier (pt),
+        - an algorithm of Bigatti/La Scala/Robbiano (blr),
+        - the algorithm of Hosten/Sturmfels (hs),
+        - the algorithm of DiBiase/Urbanke (du).
+       The argument `alg' should be the abbreviation for an algorithm as
+       above: ect, pt, blr, hs or du.
+
+      If `alg' is chosen to be `blr' or `hs', the algorithm needs a vector
+      with positive coefficients in the row space of A.
+      If no row of A contains only positive entries, one has to use the
+      second version of toric_ideal which takes such a vector as its third
+      argument.
+      For the mathematical background, see
+  @texinfo
+  @ref{Toric ideals and integer programming}.
+  @end texinfo
+EXAMPLE:  example toric_ideal; shows an example
+SEE ALSO: toric_std, toric_lib, intprog_lib, Toric ideals
+"
+{
+  if(size(#)==2)
+  {
+    return(toric_ideal_1(#[1],#[2]));
+  }
+  else
+  {
+    return(toric_ideal_2(#[1],#[2],#[3]));
+  }
+}
+
+
+
+example
+{
+"EXAMPLE"; echo=2;
+
+ring r=0,(x,y,z),dp;
+
+// call with two arguments
+intmat A[2][3]=1,1,0,0,1,1;
+A;
+
+ideal I=toric_ideal(A,"du");
+I;
+
+I=toric_ideal(A,"blr");
+I;
+
+// call with three arguments
+intvec prsv=1,2,1;
+I=toric_ideal(A,"blr",prsv);
+I;
+
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc toric_std(ideal I)
+"USAGE:   toric_std(I);      I ideal
+RETURN:   ideal: standard basis of I
+NOTE:     This procedure computes the standard basis of I using a specialized
+          Buchberger algorithm. The generating system by which I is given has
+          to consist of binomials of the form x^u-x^v. There is no real check
+          if I is toric. If I is generated by binomials of the above form,
+          but not toric, toric_std computes an ideal `between' I and its
+          saturation with respect to all variables.
+          For the mathematical background, see
+   @texinfo
+   @ref{Toric ideals and integer programming}.
+   @end texinfo
+EXAMPLE:  example toric_std; shows an example
+SEE ALSO: toric_ideal, toric_lib, intprog_lib, Toric ideals
+"
+{
+  ideal J;
+  // to be returned
+
+  // check suitability of actual term ordering
+  // the "module ordering" c or C is ignored
+  string singular_ord=ordstr(basering);
+  string test_ord;
+  string external_ord="";
+  int i,j;
+  intvec weightvec;
+
+  if(find(singular_ord,"lp")==1)
+  {
+    external_ord="W_LEX";
+    for(i=1;i<=nvars(basering);i++)
+    {
+      weightvec[i]=0;
+    }
+    test_ord="lp("+string(nvars(basering))+"),";
+    if(singular_ord!=(test_ord+"C") && singular_ord!=(test_ord+"c"))
+    {
+      "Warning: Block orderings are not supported; lp used for computation.";
+    }
+  }
+  if(external_ord=="" && find(singular_ord,"lp")==3)
+  {
+    external_ord="W_LEX";
+    for(i=1;i<=nvars(basering);i++)
+    {
+      weightvec[i]=0;
+    }
+    test_ord="lp("+string(nvars(basering))+"),";
+    if(singular_ord!=("C"+test_ord) && singular_ord!=("c"+test_ord))
+    {
+      "Warning: Block orderings are not supported; lp used for computation.";
+    }
+  }
+
+  if(external_ord=="" && find(singular_ord,"dp")==1)
+  {
+    external_ord="W_REV_LEX";
+    for(i=1;i<=nvars(basering);i++)
+    {
+      weightvec[i]=1;
+    }
+    test_ord="dp("+string(nvars(basering))+"),";
+    if(singular_ord!=(test_ord+"C") && singular_ord!=(test_ord+"c"))
+    {
+      "Warning: Block orderings are not supported; dp used for computation.";
+    }
+  }
+  if(external_ord=="" && find(singular_ord,"dp")==3)
+  {
+    external_ord="W_REV_LEX";
+    for(i=1;i<=nvars(basering);i++)
+    {
+      weightvec[i]=1;
+    }
+    test_ord="dp("+string(nvars(basering))+"),";
+    if(singular_ord!=("C"+test_ord) && singular_ord!=("c"+test_ord))
+    {
+      "Warning: Block orderings are not supported; dp used for computation.";
+    }
+  }
+
+  if(external_ord=="" && find(singular_ord,"Dp")==1)
+  {
+    external_ord="W_LEX";
+    for(i=1;i<=nvars(basering);i++)
+    {
+      weightvec[i]=1;
+    }
+    test_ord="Dp("+string(nvars(basering))+"),";
+    if(singular_ord!=(test_ord+"C") && singular_ord!=(test_ord+"c"))
+    {
+      "Warning: Block orderings are not supported; Dp used for computation.";
+    }
+  }
+  if(external_ord=="" && find(singular_ord,"Dp")==3)
+  {
+    external_ord="W_LEX";
+    for(i=1;i<=nvars(basering);i++)
+    {
+      weightvec[i]=1;
+    }
+    test_ord="Dp("+string(nvars(basering))+"),";
+    if(singular_ord!=("C"+test_ord) && singular_ord!=("c"+test_ord))
+    {
+      "Warning: Block orderings are not supported; Dp used for computation.";
+    }
+  }
+
+  int pos;
+  string number_string;
+
+  if(external_ord=="" && find(singular_ord,"wp")==1)
+  {
+    external_ord="W_REV_LEX";
+    pos=3;
+    for(i=1;i<=nvars(basering);i++)
+    {
+      pos++;
+      number_string="";
+      while(singular_ord[pos]!="," && singular_ord[pos]!=")")
+      {
+        number_string=number_string+singular_ord[pos];
+        pos++;
+      }
+      execute("weightvec["+string(i)+"]="+number_string+";");
+    }
+    test_ord="wp("+string(weightvec)+"),";
+    if(singular_ord!=(test_ord+"C") && singular_ord!=(test_ord+"c"))
+    {
+      "Warning: Block orderings are not supported; wp("+string(weightvec)+") used for computation.";
+    }
+  }
+
+  if(external_ord=="" && find(singular_ord,"wp")==3)
+  {
+    external_ord="W_REV_LEX";
+    pos=5;
+    for(i=1;i<=nvars(basering);i++)
+    {
+      pos++;
+      number_string="";
+      while(singular_ord[pos]!=",")
+      {
+        number_string=number_string+singular_ord[pos];
+        pos++;
+      }
+      execute("weightvec[i]="+number_string);
+    }
+    test_ord="wp("+string(weightvec)+"),";
+    if(singular_ord!=("C"+test_ord) && singular_ord!=("c"+test_ord))
+    {
+      "Warning: Block orderings are not supported; wp("+string(weightvec)+") used for computation.";
+    }
+  }
+
+  if(external_ord=="" && find(singular_ord,"Wp")==1)
+  {
+    external_ord="W_LEX";
+    pos=3;
+    for(i=1;i<=nvars(basering);i++)
+    {
+      pos++;
+      number_string="";
+      while(singular_ord[pos]!=",")
+      {
+        number_string=number_string+singular_ord[pos];
+        pos++;
+      }
+      execute("weightvec[i]="+number_string);
+    }
+    test_ord="Wp("+string(weightvec)+"),";
+    if(singular_ord!=(test_ord+"C") && singular_ord!=(test_ord+"c"))
+    {
+      "Warning: Block orderings are not supported; Wp("+string(weightvec)+") used for computation.";
+    }
+  }
+  if(external_ord=="" && find(singular_ord,"Wp")==3)
+  {
+    external_ord="W_LEX";
+    pos=5;
+    for(i=1;i<=nvars(basering);i++)
+    {
+      pos++;
+      number_string="";
+      while(singular_ord[pos]!=",")
+      {
+        number_string=number_string+singular_ord[pos];
+        pos++;
+      }
+      execute("weightvec[i]="+number_string);
+    }
+    test_ord="Wp("+string(weightvec)+"),";
+    if(singular_ord!=("C"+test_ord) && singular_ord!=("c"+test_ord))
+    {
+      "Warning: Block orderings are not supported; Wp("+string(weightvec)+") used for computation.";
+    }
+  }
+
+  if(external_ord=="")
+  {
+    ERROR("The term ordering of the actual basering is not supported.");
+  }
+
+  // create first temporary file with which the external program is called
+
+  int dummy;
+  int process=system("pid");
+  string groebnerfile="temp_GROEBNER"+string(process);
+  link GROEBNER=":w "+groebnerfile;
+  open(GROEBNER);
+
+  write(GROEBNER,"GROEBNER","computed with algorithm:","pt","term ordering:","elimination block",0,"weighted block",nvars(basering),external_ord);
+  // algorithm is totally unimportant, only required by the external program
+
+  for(i=1;i<=nvars(basering);i++)
+  {
+    write(GROEBNER,weightvec[i]);
+  }
+
+  write(GROEBNER,"size:",size(I),"Groebner basis:");
+  poly head;
+  poly tail;
+  poly rest;
+  intvec v;
+
+  for(j=1;j<=size(I);j++)
+  {
+    // test suitability of generator j
+    rest=I[j];
+    head=lead(rest);
+    rest=rest-head;
+    tail=lead(rest);
+    rest=rest-tail;
+
+    if(head==0 && tail==0 && rest!=0)
+    {
+      close(GROEBNER);
+      dummy=system("sh","rm -f "+groebnerfile);
+      ERROR("Generator "+string(j)+" of the input ideal is no binomial.");
+    }
+
+    if(leadcoef(tail)!=-leadcoef(head))
+      // generator is no difference of monomials (or a constant multiple)
+    {
+      close(GROEBNER);
+      dummy=system("sh","rm -f "+groebnerfile);
+      ERROR("Generator "+string(j)+" of the input ideal is no difference of monomials.");
+    }
+
+    if(gcd(head,tail)!=1)
+    {
+      "Warning: The monomials of generator "+string(j)+" of the input ideal are not relatively prime.";
+    }
+
+    // write vector representation of generator j into the file
+    v=leadexp(head)-leadexp(tail);
+    for(i=1;i<=nvars(basering);i++)
+    {
+      write(GROEBNER,v[i]);
+    }
+  }
+  close(GROEBNER);
+
+  // create second temporary file
+
+  string newcostfile="temp_NEW_COST"+string(process);
+  link NEW_COST=":w "+newcostfile;
+  open(NEW_COST);
+
+  write(NEW_COST,"NEW_COST","variables:",nvars(basering),"cost vector:");
+  for(i=1;i<=nvars(basering);i++)
+  {
+    write(NEW_COST,weightvec[i]);
+  }
+
+  // call external program
+  dummy=system("sh","change_cost "+groebnerfile+" "+newcostfile);
+  if (dummy!=0) { ERROR("change_cost failed with error code "+string(dummy)); }
+
+  // read toric standard basis from created file
+  link TORIC_IDEAL=":r "+newcostfile+".GB.pt";
+  string toric_id=read(TORIC_IDEAL);
+
+  int generators;
+  pos=find(toric_id,"size");
+  pos=find(toric_id,":",pos);
+  pos++;
+
+  while(toric_id[pos]==" " || toric_id[pos]==newline)
+  {
+    pos++;
+  }
+  number_string="";
+  while(toric_id[pos]!=" " && toric_id[pos]!=newline)
+  {
+    number_string=number_string+toric_id[pos];
+    pos++;
+  }
+  execute("generators="+number_string+";");
+
+  pos=find(toric_id,"basis");
+  pos=find(toric_id,":",pos);
+  pos++;
+
+  for(j=1;j<=generators;j++)
+  {
+    head=1;
+    tail=1;
+
+    for(i=1;i<=nvars(basering);i++)
+    {
+      while(toric_id[pos]==" " || toric_id[pos]==newline)
+      {
+        pos++;
+      }
+      number_string="";
+      while(toric_id[pos]!=" " && toric_id[pos]!=newline)
+      {
+        number_string=number_string+toric_id[pos];
+        pos++;
+      }
+      execute("v[i]="+number_string+";");
+      if(v[i]<0)
+      {
+        tail=tail*var(i)^(-v[i]);
+      }
+      if(v[i]>0)
+      {
+        head=head*var(i)^v[i];
+      }
+    }
+    J[j]=head-tail;
+  }
+
+  // delete all created files
+  dummy=system("sh","rm -f "+groebnerfile);
+  dummy=system("sh","rm -f "+groebnerfile+".GB.pt");
+  dummy=system("sh","rm -f "+newcostfile);
+
+  return(J);
+}
+
+example
+{
+"EXAMPLE"; echo=2;
+
+ring r=0,(x,y,z),wp(3,2,1);
+
+// call with toric ideal (of the matrix A=(1,1,1))
+ideal I=x-y,x-z;
+ideal J=toric_std(I);
+J;
+
+// call with the same ideal, but badly chosen generators:
+// 1) not only binomials
+I=x-y,2x-y-z;
+J=toric_std(I);
+// 2) binomials whose monomials are not relatively prime
+I=x-y,xy-yz,y-z;
+J=toric_std(I);
+J;
+
+// call with a non-toric ideal that seems to be toric
+I=x-yz,xy-z;
+J=toric_std(I);
+J;
+// comparison with real standard basis and saturation
+ideal H=std(I);
+H;
+LIB "elim.lib";
+sat(H,xyz);
+}
+///////////////////////////////////////////////////////////////////////////////
diff --git a/Singular/LIB/triang.lib b/Singular/LIB/triang.lib
new file mode 100644
index 0000000..5b9155c
--- /dev/null
+++ b/Singular/LIB/triang.lib
@@ -0,0 +1,1195 @@
+///////////////////////////////////////////////////////////////////////////
+version="version triang.lib 4.0.0.0 Jun_2013 "; // $Id: d3a64a08e30d940468862f5d76cace02f83800ad $
+category="Symbolic-numerical solving";
+info="
+LIBRARY: triang.lib   Decompose Zero-dimensional Ideals into Triangular Sets
+AUTHOR: D. Hillebrand
+
+PROCEDURES:
+ triangL(G);          Decomposition of (G) into triangular systems (Lazard).
+ triangLfak(G);       Decomp. of (G) into tri. systems plus factorization.
+ triangM(G[,.]);      Decomposition of (G) into triangular systems (Moeller).
+ triangMH(G[,.]);     Decomp. of (G) into tri. syst. with disjoint varieties.
+";
+
+LIB "general.lib"; // Muss geladen werden fuer den Befehl sort().
+LIB "elim.lib";    // Muss geladen werden fuer sat().
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//  Der Lazard-Algorithmus
+//
+///////////////////////////////////////////////////////////////////////////////
+
+proc triangL (ideal G)
+"USAGE:   triangL(G); G=ideal
+ASSUME:  G is the reduced lexicographical Groebner basis of the
+         zero-dimensional ideal (G), sorted by increasing leading terms.
+RETURN:  a list of finitely many triangular systems, such that
+         the union of their varieties equals the variety of (G).
+NOTE:    Algorithm of Lazard (see: Lazard, D.: Solving zero-dimensional
+         algebraic systems, J. Symb. Comp. 13, 117 - 132, 1992).
+EXAMPLE: example triangL; shows an example
+"
+{
+
+    // Test, ob G Groebnerbasis eines nulldimensionalen Ideals ist.
+    if (attrib(G,"isSB") <> 1)
+    {
+        ERROR("The input is no groebner basis.");
+    }
+    else
+    {
+        if (dim(G) <> 0)
+        {
+            ERROR("ideal is not zero-dimensional.");
+        }
+    }
+
+    if (size(G) <= 2)  // schon Dreiecksbasis
+    {
+        return(list(G));
+    }
+
+    // Noetige Optionen setzen.
+    // obachman: save options so that tey can be reset on exit
+    intvec ovec = option(get);
+    option(redSB);
+    option(returnSB);
+    list B;    // Bearbeitungsliste
+    list F;    // Ergebnisliste = Triangulierung
+    ideal T, T_neu;
+    poly p,p_neu,r,s,lt,lc,lcr;
+    list inv;
+    int u,v;
+    int l,h;
+    string st;
+
+    T = ideal(G[1]);
+    attrib(T,"isSB",1);
+    B = list(list(T,2));
+
+    while (size(B) > 0)
+    {
+        T   = B[1][1];
+        h   = B[1][2];
+        B   = Listenrest(B);
+        p   = G[h];
+        v   = lvar(p);
+        lc  = lcoef(p,v);
+          st=string(nvars(basering)-v+1);
+          dbprint(string(timer)+" S"+st+": invertiere Leitkoeffizient von G["+string(h)+"].");
+
+        // Invertiere den Leitkoeffizienten von G[h] bzgl. var(v) modulo (T).
+        inv = invertieren(lc,T);
+
+          dbprint(string(timer)+" S"+st+": Anzahl Dreiecksbasen: "+string(size(inv))+".");
+
+        while (size(inv) > 0)
+        {
+            r   = inv[1][1];
+            s   = inv[1][2];
+            T   = inv[1][3];
+            inv = Listenrest(inv);
+            if (r == 0)  // r == 0?, dann p nicht der ggt der Stufe,
+            {
+                   dbprint(string(timer)+" S"+st+": Leitkoeffizient == 0.");
+                B = list(list(T,h+1)) + B;
+            }
+            else         // ansonsten ggt der Stufe gefunden.
+            {
+                   dbprint(string(timer)+" S"+st+": ggt gefunden.");
+                lt    = var(v)**degv(p,v);
+                p_neu = cleardenom(s*lt + reduce(r*(p-lc*lt),T));
+                T_neu = T,p_neu;
+                attrib(T_neu,"isSB",1);
+
+                // Restlichen Polynome der gleichen Stufe uebergehen.
+                for (l = h+1; l <= size(G); l++)
+                {
+                    u = lvar(G[l]);
+                    if (u <> v) {break;}
+                }
+
+                // Durchsuche restliche Stufen nach trivialen ggt's.
+                while (l <= size(G))
+                {
+                    lc = lcoef(G[l],u);
+                    lcr = reduce(lc,T_neu);
+
+                    while (lcr == 0) // Gehe bis zum ersten Polynom <> 0
+                    {                // modulo (T_neu).
+                        l++;
+                        lc = lcoef(G[l],u);
+                        lcr = reduce(lc,T_neu);
+                    }
+
+                    if (deg(lcr) == 0) // Polynom <> 0 normiert?, dann
+                    {                  // an Dreiecksbasis anhaengen,
+                          dbprint(string(timer)+" S"+string(nvars(basering)-u+1)+": Schnellerkennung: ggt gefunden.");
+                        lt = var(u)**degv(G[l],u);
+                        p_neu = cleardenom(lcr*lt +
+                                  reduce(G[l]-lc*lt,T_neu));
+                        T_neu = T_neu,p_neu;
+                        attrib(T_neu,"isSB",1);
+                        u = lvar(G[l]);
+                        l++;
+                        while (l <= size(G)) // Rest der Stufe uebergehen.
+                        {
+                            if (lvar(G[l]) <> u) {u = lvar(G[l]); break;}
+                            l++;
+                        }
+                    }
+                    else // sonst nicht normierte Polynome auf der Stufe.
+                    {
+                        break;
+                    }
+                }
+                if (l > size(G))  // Ende von G erreicht, dann Dreiecks-
+                {                 // basis der Triangulierung gefunden,
+                       dbprint(string(timer)+" S"+st+": Dreiecksbasis der Triangulierung gefunden.");
+                    F = F + list(T_neu);
+                }
+                else              // sonst T_neu,l erneut bearbeiten.
+                {
+                    B = list(list(T_neu,l)) + B;
+                }
+            }
+        }
+    }
+    option(set, ovec);
+    return(F);
+}
+//-------------------------------- example ----------------------------------
+example
+{  "EXAMPLE:"; echo = 2;
+    ring rC5 = 0,(e,d,c,b,a),lp;
+    triangL(stdfglm(cyclic(5)));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc triangLfak (ideal G)
+"USAGE:   triangLfak(G); G=ideal
+ASSUME:  G is the reduced lexicographical Groebner basis of the
+         zero-dimensional ideal (G), sorted by increasing leading terms.
+RETURN:  a list of finitely many triangular systems, such that
+         the union of their varieties equals the variety of (G).
+NOTE:    Algorithm of Lazard with factorization (see: Lazard, D.: Solving
+         zero-dimensional algebraic systems, J. Symb. Comp. 13, 117 - 132, 1992).
+REMARK:  each polynomial of the triangular systems is factorized.
+EXAMPLE: example triangLfak; shows an example
+"
+{
+    return(triangLbas(G,2));
+}
+//-------------------------------- example ----------------------------------
+example
+{  "EXAMPLE:"; echo = 2;
+    ring rC5 = 0,(e,d,c,b,a),lp;
+    triangLfak(stdfglm(cyclic(5)));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static proc triangLbas (ideal G, list #)
+"USAGE:   triangLbas(G[,i]); G reduzierte lexikographische Groebnerbasis
+                            des nulldimensionalen Ideals (G), nach
+                            Leittermen aufsteigend sortiert,
+                            i = 1 oder 2 (ohne Angabe i = 1).
+RETURN:  Triangulierung von (G).
+         Ist i == 2, dann wird jedes Polynom der Dreiecksbasen
+         der Triangulierung zusaetzlich faktorisiert.
+NOTE:    Algorithmus von Lazard (siehe: Lazard, D.: Solving
+         zero-dimensional algebraic systems,
+         J. Symb. Comp., Bd. 13, S. 117 - 132, 1992).
+"
+{
+
+    // Test, ob G Groebnerbasis eines nulldimensionalen Ideals ist.
+    if (attrib(G,"isSB") <> 1)
+    {
+        ERROR("The input is no groebner basis.");
+    }
+    else
+    {
+        if (dim(G) <> 0)
+        {
+            ERROR("ideal is not zero-dimensional.");
+        }
+    }
+
+    // Noetige Optionen setzen.
+    // obachman: save options so that tey can be reset on exit
+    intvec ovec = option(get);
+    option(redSB);
+    option(returnSB);
+    // Faktorisierungsschalter setzen.
+    int fak;
+    if (size(#) > 0 && typeof(#[1]) == "int")
+    {
+        if (#[1] == 2) {fak = 1;}
+    }
+
+    if (size(G) <= 2)  // schon Dreiecksbasis
+    {
+        list E;
+        if (fak)
+        {
+            E = faktorisiere_DB(G);
+        }
+        else
+        {
+            E = list(G);
+        }
+        option(set, ovec);
+        return(E);
+    }
+
+    list B;    // Bearbeitungsliste
+    list F;    // Ergebnisliste = Triangulierung
+    list T_neu;
+    ideal T;
+    poly p,p_neu,r,s,lt,lc;
+    list inv;
+    int v;
+    int l,h;
+    string st;
+
+    // B initialisieren
+    if (fak)
+    {
+        B = H_anhaengen(faktorisiere_letzten(G[1]),2);
+    }
+    else
+    {
+        T = ideal(G[1]);
+        attrib(T,"isSB",1);
+        B = list(list(T,2));
+    }
+
+    while (size(B) > 0)
+    {
+        T   = B[1][1];
+        h   = B[1][2];
+        B   = Listenrest(B);
+        p   = G[h];
+        v   = lvar(p);
+        lc  = lcoef(p,v);
+          st=string(nvars(basering)-v+1);
+          dbprint(string(timer)+" S"+st+": invertiere Leitkoeffizient von G["+string(h)+"].");
+
+        // invertiere den Leitkoeffizienten von G[h] bzgl. var(v) modulo (T).
+        inv = invertieren(lc,T);
+          dbprint(string(timer)+" S"+st+": Anzahl Dreiecksbasen: "+string(size(inv))+".");
+
+        while (size(inv) > 0)
+        {
+            r   = inv[1][1];
+            s   = inv[1][2];
+            T   = inv[1][3];
+            inv = Listenrest(inv);
+            if (r == 0)  // r == 0?, dann p nicht der ggt der Stufe,
+            {
+                   dbprint(string(timer)+" S"+st+": Leitkoeffizient == 0.");
+                B = list(list(T,h+1)) + B;
+            }
+            else         // ansonsten ggt der Stufe gefunden.
+            {
+                   dbprint(string(timer)+" S"+st+": ggt gefunden.");
+                lt    = var(v)**degv(p,v);
+                p_neu = cleardenom(s*lt + reduce(r*(p-lc*lt),T));
+                if (fak)
+                {
+                    T_neu = faktorisiere_letzten(list(T + p_neu));
+                }
+                else
+                {
+                    T_neu = list(T + p_neu);
+                }
+
+                // Restlichen Polynome der gleichen Stufe uebergehen.
+                for (l = h+1; l <= size(G); l++)
+                {
+                     if (lvar(G[l]) <> v) {break;}
+                }
+
+                if (l > size(G))  // Ende von G erreicht, dann Dreiecks-
+                {                 // basis der Triangulierung gefunden,
+                       dbprint(string(timer)+" S"+st+": Dreiecksbasis der Triangulierung gefunden.");
+                    F = F + T_neu;
+                }
+                else              // sonst T_neu,l erneut bearbeiten.
+                {
+                    B  = H_anhaengen(T_neu,l) + B;
+                }
+            }
+        }
+    }
+    option(set, ovec);
+    return(F);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static proc invertieren (poly p, ideal T)
+"USAGE:   invertieren(p,T); p Polynom, T reduzierte Dreiecksbasis.
+RETURN:  Liste von Tripeln (Listen) bestehend aus einem Polynom ri,
+         einem Element aus dem Grundring si, und einer
+         reduzierten Dreiecksbasis Ti, i = 1,...,m, so dass
+         [T1,...,Tm] eine Triangulierung von T ist und
+         p = 0 mod (Ti) falls ri = 0, ansonsten
+         ri*p = si mod (Ti) fuer i = 1,...,m.
+"
+{
+    // Triviale Faelle vorweg behandeln.
+    p = reduce(p,T);
+    if (p == 0) {return(list(list(0,0,T)));}
+    if (deg(p) == 0) {return(list(list(1,p,T)));}
+
+    list inv;
+    int zerlegt;      // zerlegt ist Schalter dafuer, ob T zerlegt wurde,
+    export zerlegt;   // einzige globale Variable.
+    list toSee = list(list(p,T));  // zu bearbeitende Paare
+    list toSave;                   // Ergebnisliste
+    poly pr;
+
+    while (size(toSee) > 0)
+    {
+        zerlegt = 0;             // zerlegt = FALSE
+        p = toSee[1][1];
+        T = toSee[1][2];
+        toSee = Listenrest(toSee);
+
+        // invertieren_oT aufrufen, um p+(T) zu invertieren.
+        inv = invertieren_oT(p,T);
+
+        if (zerlegt)   // T zerlegt?, dann pro neuer Dreiecksbasis
+        {              // weiteruntersuchen,
+            pr = reduce(p,inv[1]);
+            if (pr == 0) // es sei denn p ist reduziert gleich 0,
+            {
+                toSave = list(list(0,0,inv[1])) + toSave;
+                attrib(toSave[1][3],"isSB",1);
+            }
+            else
+            {
+                toSee  = list(list(pr,inv[1])) + toSee;
+                attrib(toSee[1][2],"isSB",1);
+            }
+            pr = reduce(p,inv[2]);
+            if (pr == 0)
+            {
+                toSave = list(list(0,0,inv[2])) + toSave;
+                attrib(toSave[1][3],"isSB",1);
+            }
+            else
+            {
+                toSee  = list(list(pr,inv[2])) + toSee;
+                attrib(toSee[1][2],"isSB",1);
+            }
+
+        }
+        else           // ansonsten Quasi-Inverses gefunden.
+        {
+            toSave = list(list(inv[1],inv[2],T)) + toSave;
+            attrib(toSave[1][3],"isSB",1);
+        }
+    }
+    kill zerlegt;
+    return(toSave);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static proc invertieren_oT (poly p, ideal T)
+"USAGE:   invertieren_oT(p,T); T reduzierte Dreiecksbasis,
+                              p <> 0 Polynom, irreduzibel modulo (T).
+RETURN:  Entweder ein Quasi-Inverses (r,s) von p modulo (T), d.h.
+         r*p = s mod (T) und s im Grundring,
+         oder eine Triangulierung [T1,T2] von T
+         mit (Ti) <> (T) fuer i = 1,2.
+"
+{
+    // Quasi-Inverses von Konstante klar.
+    if (deg(p) == 0) {return(list(1,p));}
+
+    ideal T_bis_k,T1,T2;
+    poly g,a,b;
+    list rq;
+    list gab;
+    int i;
+    int v = lvar(p);
+    int k = nvars(basering)-v+1;
+
+    // Zu p passende Dreiecksbasis auswaehlen.
+    if (k == 1)
+    {
+        T_bis_k = 0;
+    }
+    else
+    {
+        T_bis_k = T[1..(k-1)];
+    }
+    attrib(T_bis_k,"isSB",1);
+
+    // Um p+(T) zu invertieren, erw. eukl. Algorithmus anwenden.
+    gab = Erw_ggt_oT(T[k],p,v,T_bis_k);
+
+    // Entweder Triangulierung von T_bis_k erhalten,
+    if (zerlegt)
+    {
+        // T[k..size(T)] an gab[i] anhaengen und reduzieren.
+        T1 = gab[1];
+        T2 = gab[2];
+        for (i = k; i <= size(T); i++)
+        {
+            T1 = T1 + cleardenom(reduce(T[i],T1));
+            T2 = T2 + cleardenom(reduce(T[i],T2));
+            attrib(T1,"isSB",1);
+            attrib(T2,"isSB",1);
+        }
+        return(list(T1,T2));
+    }
+
+    // ansonsten gilt: a*T[k] + b*p = g mod (T_bis_k)
+    g = gab[1];
+    a = gab[2];
+    b = gab[3];
+
+    if (degv(g,v) > 0)        // Entweder echten Teiler von T[k] gefunden,
+    {                         // dann splitte T,
+        rq = pdiv(T[k],g,v);
+
+        T1 = T_bis_k;
+        T1[k] = cleardenom(reduce(g,T1));
+        attrib(T1,"isSB",1);
+        T2 = T_bis_k;
+        T2[k] = cleardenom(reduce(rq[2],T2));
+        attrib(T2,"isSB",1);
+
+        // T[k..size(T)] an T1, T2 anhaengen und reduzieren.
+        for (i = k + 1; i <= size(T); i++)
+        {
+            T1 = T1 + cleardenom(reduce(T[i],T1));
+            T2 = T2 + cleardenom(reduce(T[i],T2));
+            attrib(T1,"isSB",1);
+            attrib(T2,"isSB",1);
+        }
+
+        // zerlegt = TRUE, hier ist einzige Stelle, wo T zerlegt wird.
+        zerlegt = 1;
+        return(list(T1,T2));
+    }
+    else                      // ansonsten Quasi-Inverses gefunden.
+    {
+        return(list(b,g));
+    }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static proc Erw_ggt_oT (poly f, poly g, int v, ideal T)
+"USAGE:   Erw_ggt_oT(f,g,v,T);  f,g Polynome in var(v), f > g,
+                               T Dreiecksbasis mit groesster
+                               Variable var(v+1).
+RETURN:  Liste aus drei Polynomen d,a,b, wobei
+         a * f + b * g = d mod (T) und
+         (d + (T)) = ((f + (T), g + (T)).
+NOTE:    Dies ist der erweiterte euklidische Algorithmus im Polynom-
+         ring ueber dem Restklassenring modulo (T) in der Unbestimmten
+         var(v). Zusaetzlich wird jeweils der Dividend so normiert,
+         dass der Leitkoeffizient bzgl. var(v) im Grundring ist
+         und die Leikoeffizienten werden durch Anwendung der
+         Subresultant-remainder-sequence Variante des euklidischen
+         Algorithmus moeglichst klein gehalten.
+"
+{
+    // Initialisierung fuer erw. eukl. Algorithmus.
+    poly p1 = f;
+    poly p2 = g;
+    poly a1 = 1;
+    poly a2 = 0;
+    poly b1 = 0;
+    poly b2 = 1;
+
+    // Normierung des Dividenden.
+    list pab = normieren_oT(p2,a2,b2,v,T);
+    if (zerlegt) {return(pab);}
+    p2 = pab[1]; a2 = pab[2]; b2 = pab[3];
+
+    poly p3,a3,b3,q;  // Hilfspolynome
+    list rq;          // Rueckgabelisten der Fkten pdiv und normieren_oT
+    vector clden;
+
+    // Variablen fuer Subresultanten-Variante initialisieren.
+    int delta = degv(p1,v)-degv(p2,v);
+    number alpha;
+    number beta = (-1)**(delta + 1);
+    number psi = -1;
+    number m;
+
+    // Pseudodivision
+    rq = pdiv(p1,p2,v);
+    q  = rq[2];
+    p3 = reduce(rq[1],T);
+
+    while (p3 <> 0)   // Hauptschleife des eukl. Algorithmus.
+    {
+        alpha = number(lcoef(p2,v));  // return von lcoef ist type poly
+        m  = alpha**(delta + 1);   //m*p1 = q*p2 + p3  mod (T)
+        p3 = p3 / beta;            //m*p1 = q*p2 + beta * p3  mod (T)
+
+        // a und b anpassen.
+        q  = reduce(q,T);
+        a3 = reduce(m*a1 - q*a2,T);
+        b3 = reduce(m*b1 - q*b2,T);
+        a3 = a3 / beta;
+        b3 = b3 / beta;
+
+        // Variablen tauschen.
+        p1 = p2;
+        p2 = p3;
+        a1 = a2;
+        a2 = a3;
+        b1 = b2;
+        b2 = b3;
+
+        // Normierung des Dividenden.
+        pab = normieren_oT(p2,a2,b2,v,T);
+        if (zerlegt) {return(pab);}
+        p2 = pab[1]; a2 = pab[2]; b2 = pab[3];
+
+        if (degv(p2,v) > 0)     // Dividend aus Grundring?, dann
+        {                       // Subresultanten-Variabeln anpassen
+            if (delta > 0)
+            {
+                psi = ((-alpha)**delta) / (psi**(delta-1));
+            }
+            delta = degv(p1,v)-degv(p2,v);
+            beta  = (-alpha) * (psi**delta);
+
+            rq = pdiv(p1,p2,v); // und Pseudodivision,
+            q  = rq[2];
+            p3 = reduce(rq[1], T);
+        }
+        else                    // ansonsten Ende.
+        {
+            p3 = 0;
+        }
+    }
+
+    // Gemeinsame Teiler herausdividieren.
+    clden = cleardenom([p2,a2,b2]);
+    return(list(clden[1],clden[2],clden[3]));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static proc normieren_oT (poly p, poly a, poly b, int v, ideal T)
+"USAGE:   normieren_oT(p,a,b,v,T); p,a,b Polynome in var(v),
+                                  T Dreiecksbasis.
+RETURN:  Entweder Triangulierung [T1,T2] von (T) oder
+         Liste,wobei [1] = reduce(r*p,T),
+                     [2] = reduce(r*a,T),
+                     [3] = reduce(r*b,T),
+         und reduce(r*lcoef(p,v),T) ist im Grundring.
+"
+{
+    poly lc = lcoef(p,v);
+    if (deg(lc) == 0) {return(list(p,a,b));} // lc im Grundring
+    lc = cleardenom(lc);
+
+    // invertieren_oT aufrufen, um lc+(T) zu invertieren.
+    list inv = invertieren_oT(lc,T);
+    if (zerlegt) {return(inv);}
+
+    // ansonsten Polynom zurueck gekommen.
+    p = reduce(inv[1] * p,T);
+    a = reduce(inv[1] * a,T);
+    b = reduce(inv[1] * b,T);
+    return(list(p,a,b));
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//  Der Moeller-Algorithmus
+//
+///////////////////////////////////////////////////////////////////////////////
+
+proc triangM (ideal G, list #)
+"USAGE:   triangM(G[,i]); G=ideal, i=integer,@*
+ASSUME:  G is the reduced lexicographical Groebner basis of the
+         zero-dimensional ideal (G), sorted by increasing leading terms.
+RETURN:  a list of finitely many triangular systems, such that
+         the union of their varieties equals the variety of (G).
+         If i = 2, then each polynomial of the triangular systems
+         is factorized.
+NOTE:    Algorithm of Moeller (see: Moeller, H.M.: On decomposing systems of
+         polynomial equations with finitely many solutions, Appl. Algebra Eng.
+         Commun. Comput. 4, 217 - 230, 1993).
+EXAMPLE: example triangM; shows an example
+"
+{
+    // Test, ob G Groebnerbasis ist.
+    if (attrib(G,"isSB") <> 1)
+    {
+        ERROR("The input is no groebner basis.");
+    }
+
+    // Faktorisierungsschalter setzen.
+    int fak;
+    if (size(#) > 0 && typeof(#[1]) == "int")
+    {
+        if (#[1] == 2) {fak = 1;}
+    }
+
+    // Noetige Optionen setzen.
+    // obachman: save options so that they can be reset on exit
+    intvec ovec = option(get);
+    option(redSB);
+    option(returnSB);
+
+    list F,Fh;       // Ergebnislisten
+    int nG = size(G);
+    if (nG <= 2)     // G schon Dreiecksbasis?
+    {
+        if (fak)
+        {
+            F = faktorisiere_DB(G);
+        }
+        else
+        {
+            F = list(G);
+        }
+        option(set, ovec);
+        return(F);
+    }
+
+    int u = lvar(G[nG-1]);
+    int v = lvar(G[nG]);
+    int m = nG;
+    int l;
+    ideal lc,G1,G2,H;
+    poly lcr;
+    int i,j,k;
+      string s = string(nvars(basering)-v+1); // fuer Protokoll
+
+    // Oberes Dreieckssytem abschneiden.
+    while(u <> v)
+    {
+        m = m-1;
+        if (m == 2)  // G ist bereits Dreiecksbasis.
+        {
+            if (fak)
+            {
+                F = faktorisiere_DB(G);
+            }
+            else
+            {
+                F = list(G);
+            }
+            option(set, ovec);
+            return (F);
+        }
+        v = u;
+        u = lvar(G[m-1]);
+    }
+
+    // Leitkoeffizienten der Polynome bzgl. var(u) bestimmen.
+    l = m-1;
+    while(u == v)
+    {
+        lc = lc + lcoef(G[l],u);
+        l  = l - 1;
+        u  = lvar(G[l]);
+    }
+
+    // Erster Teil des Splitts.
+    G1 = sort_red(ideal(G[1..l]) + lc); // Sortiere und reduziere GB.
+
+      s = string(nvars(basering)-v+1);
+      dbprint(string(timer)+" S"+s+": Erster Teil des Splitts.");
+
+    // Rekursiver Aufruf, um G1 zu triangulieren.
+    F = triangM(G1,#);
+
+      dbprint(string(timer)+" S"+s+": Oberes Dreieckssystem anhaengen.");
+
+    // Oberes Dreieckssystem an jede berechnete Dreiecksbasis anhaengen.
+    for (j = m; j <= nG; j++)  // meist nur j = m = nG
+    {
+        for (i = 1; i <= size(F); i++)
+        {
+            F[i] = F[i] + cleardenom(G[j][1] + reduce(G[j]-G[j][1],F[i]));
+            attrib(F[i],"isSB",1);
+        }
+        if (fak)
+        {
+            F = faktorisiere_letzten(F);
+        }
+    }
+
+        dbprint(string(timer)+" S"+s+": Zweiter Teil des Splitts, "+string(m-l-1)+" Leitkoeffizient(en).");
+
+    // Zweiten Teil des Splitts berechnen.
+    H = ideal(G[1..m]);
+    attrib(H,"isSB",1);
+
+    for (k = m-l-1; k >= 1; k--)  // Leitkoeffizientenliste durchgehen,
+    {                             // angefangen mit lc des kleinsten Polynoms.
+        lcr = reduce(lc[k],H);
+        if (lcr <> 0)             // d.h. (H):lcr <> (1)
+        {
+              dbprint(string(timer)+" S"+s+"L"+string(m-l-k)+": Berechnung Idealquotient.");
+            G2 = quotient(H,lcr); // Wg. Option returnSB schon Standardbasis.
+            attrib(G2,"isSB",1);
+
+              dbprint(string(timer)+" S"+s+"L"+string(m-l-k)+": Rekursiver Aufruf.");
+            // Rekursiver Aufruf, um G2 zu triangulieren.
+            Fh = triangM(G2,#);
+
+              dbprint(string(timer)+" S"+s+"L"+string(m-l-k)+": Oberes Dreieckssystem, falls vorhanden, anhaengen.");
+            // Oberes Dreieckssystem, falls vorhanden,
+            // an jede berechnete Dreiecksbasis anhaengen.
+            for (j = m + 1; j <= nG; j++)
+            {
+                for (i = 1; i <= size(Fh); i++)
+                {
+                    Fh[i] = Fh[i] + cleardenom(G[j][1] +
+                                    reduce(G[j]-G[j][1],Fh[i]));
+                    attrib(Fh[i],"isSB",1);
+                }
+                if (fak)
+                {
+                    Fh = faktorisiere_letzten(Fh);
+                }
+            }
+            F = F + Fh;
+            if (k > 1)
+            {
+                  dbprint(string(timer)+" S"+s+"L"+string(m-l-k)+": Lex. GB von (H + lc) berechnen, naechsten lc reduzieren.");
+                H = std(H + lcr); // Wg. reduce(...,H) oben notwendig.
+            }
+        }
+        else
+        {
+              dbprint(string(timer)+" S"+s+"L"+string(m-l-k)+": Leere Varietaet.");
+        }
+    }
+
+    // Singular loescht die Attribute beim Listenverketten, deswegen neu setzen.
+    for (i = 1; i <= size(F); i++)
+    {
+        attrib(F[i],"isSB",1);
+    }
+    option(set, ovec);
+    return(F);
+}
+//-------------------------------- example----------------------------------
+example
+{ "EXAMPLE:"; echo = 2;
+   ring rC5 = 0,(e,d,c,b,a),lp;
+   triangM(stdfglm(cyclic(5))); //oder: triangM(stdfglm(cyclic(5)),2);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc triangMH (ideal G, list #)
+"USAGE:   triangMH(G[,i]); G=ideal, i=integer
+ASSUME:  G is the reduced lexicographical Groebner basis of the
+         zero-dimensional ideal (G), sorted by increasing leading terms.
+RETURN:  a list of finitely many triangular systems, such that
+         the disjoint union of their varieties equals the variety of (G).
+         If i = 2, then each polynomial of the triangular systems is factorized.
+NOTE:    Algorithm of Moeller and Hillebrand (see: Moeller, H.M.:
+         On decomposing systems of polynomial equations with finitely many
+         solutions, Appl. Algebra Eng. Commun. Comput. 4, 217 - 230, 1993 and
+         Hillebrand, D.: Triangulierung nulldimensionaler Ideale -
+         Implementierung und Vergleich zweier Algorithmen, master thesis,
+         Universitaet Dortmund, Fachbereich Mathematik, Prof. Dr. H.M. Moeller,
+         1999).
+EXAMPLE: example triangMH; shows an example
+"
+{
+    // Test, ob G Groebnerbasis ist.
+    if (attrib(G,"isSB") <> 1)
+    {
+        ERROR("The input is no groebner basis.");
+    }
+    if(npars(basering)<>0)
+    {
+        ERROR("basering has parameters");
+    }
+    // Faktorisierungsschalter setzen.
+    int fak;
+    if (size(#) > 0 && typeof(#[1]) == "int")
+    {
+        if (#[1] == 2) {fak = 1;}
+    }
+
+    // Noetige Optionen setzen.
+    // obachman: save options so that tey can be reset on exit
+    intvec ovec = option(get);
+    option(redSB);
+    option(redTail);
+    option(returnSB);
+
+    list F,Fh;       // Ergebnislisten
+    int nG = size(G);
+    if (nG <= 2)     // G schon Dreiecksbasis?
+    {
+        if (fak)
+        {
+            F = faktorisiere_DB(G);
+        }
+        else
+        {
+            F = list(G);
+        }
+        option(set, ovec);
+        return(F);
+    }
+
+    int u = lvar(G[nG-1]);
+    int v = lvar(G[nG]);
+    int m = nG;
+    int l;
+    poly lcr;
+    ideal lc,G1,G2,H;
+    int i,j,k;
+      string s = string(nvars(basering)-v+1); // fuer Protokoll
+
+    // Oberes Dreieckssytem abschneiden.
+    while(u <> v)
+    {
+        m = m-1;
+        if (m == 2)  // G ist Dreiecksbasis.
+        {
+            if (fak)
+            {
+                F = faktorisiere_DB(G);
+            }
+            else
+            {
+                F = list(G);
+            }
+            option(set, ovec);
+            return(F);
+         }
+        v = u;
+        u = lvar(G[m-1]);
+    }
+
+    // Leitkoeffizienten der Polynome bzgl. var(u) bestimmen.
+    l = m-1;
+    while(u == v)
+    {
+        lc = lc + lcoef(G[l],u);
+        l  = l - 1;
+        u  = lvar(G[l]);
+    }
+
+    // Erster Teil des Splitts.
+    G1 = sort_red(ideal(G[1..l]) + lc); // Sortiere und reduziere GB.
+
+      s = string(nvars(basering)-v+1);
+      dbprint(string(timer)+" S"+s+": Erster Teil des Splitts.");
+
+    // Rekursiver Aufruf, um G1 zu triangulieren.
+    F = triangMH(G1,#);
+
+      dbprint(string(timer)+" S"+s+": Oberes Dreieckssystem anhaengen.");
+
+    // Oberes Dreieckssystem an jede berechnete Dreiecksbasis anhaengen.
+    for (j = m; j <= nG; j++)  // meist nur j = m = nG
+    {
+        for (i = 1; i <= size(F); i++)
+        {
+            F[i] = F[i] + cleardenom(G[j][1] + reduce(G[j]-G[j][1],F[i]));
+            attrib(F[i],"isSB",1);
+        }
+        if (fak)
+        {
+            F = faktorisiere_letzten(F);
+        }
+    }
+
+        dbprint(string(timer)+" S"+s+": Zweiter Teil des Splitts, "+string(m-l-1)+" Leitkoeffizient(en).");
+
+    // Zweiten Teil des Splitts berechnen.
+    H = ideal(G[1..l]);   // Nur die Polynome in var(u).
+    attrib(H,"isSB",1);
+
+    for (k = m-l-1; k >= 1; k--)  // Leitkoeffizientenliste durchgehen,
+    {                             // angefangen mit lc des kleinsten Polynoms.
+        lcr = reduce(lc[k],H);
+        if (lcr <> 0)             // d.h. (H):lcr <> (1)
+        {
+              dbprint(string(timer)+" S"+s+"L"+string(m-l-k)+": Berechnung Saturation.");
+            G2 = sat(H,lcr)[1];     // Saturation statt Idealquotient.
+            attrib(G2,"isSB",1);
+
+            if (G2[1] <> 1)
+            {
+                  dbprint(string(timer)+" S"+s+"L"+string(m-l-k)+": Rekursiver Aufruf.");
+                // Rekursiver Aufruf, um G2 zu triangulieren.
+                Fh = triangMH(G2,#);
+
+                  dbprint(string(timer)+" S"+s+"L"+string(m-l-k)+": Ggt und oberes Dreieckssystem anhaengen.");
+                // Ggt an jede Dreiecksbasis anhaengen.
+                for (i = 1; i <= size(Fh); i++)
+                {
+                    Fh[i] = std(Fh[i] + G[m-k]);
+                }
+                if (fak)
+                {
+                    Fh = faktorisiere_letzten(Fh);
+                }
+                for (j = m+1; j <= nG; j++)  // oberes Dreieckssystem an jede
+                {                            // berechnete Dreiecksbasis anhaengen
+                    for (i = 1; i <= size(Fh); i++)
+                    {
+                        Fh[i] = Fh[i] + cleardenom(G[j][1]
+                                      + reduce(G[j]-G[j][1],Fh[i]));
+                        attrib(Fh[i],"isSB",1);
+                    }
+                    if (fak)
+                    {
+                        Fh = faktorisiere_letzten(Fh);
+                    }
+                }
+                F = F + Fh;
+            }
+            else
+            {
+                  dbprint(string(timer)+" S"+s+"L"+string(m-l-k)+": Leere Varietaet (G2 == (1)).");
+            }
+            if (k > 1)
+            {
+                  dbprint(string(timer)+" S"+s+"L"+string(m-l-k)+": Lex. GB von (H + lc) berechnen, naechsten lc reduzieren.");
+                H = std(H + lcr); // wegen reduce(...,H) oben
+            }
+        }
+        else
+        {
+              dbprint(string(timer)+" S"+s+"L"+string(m-l-k)+": Leere Varietaet (lcr == 0).");
+        }
+    }
+
+    // Singular loescht die Attribute beim Listenverketten, deswegen neu setzen.
+    for (i = 1; i <= size(F); i++)
+    {
+        attrib(F[i],"isSB",1);
+    }
+    option(set, ovec);
+    return(F);
+}
+//-------------------------------- example ----------------------------------
+example
+{ "EXAMPLE:"; echo = 2;
+   ring rC5 = 0,(e,d,c,b,a),lp;
+   triangMH(stdfglm(cyclic(5)));
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//  Hilfsfunktionen
+//
+///////////////////////////////////////////////////////////////////////////////
+
+static proc sort_red (ideal G)
+"USAGE:   sort_red(G);  G lexikographische Groebnerbasis.
+RETURN:  reduzierte lex. GB G, deren Elemente nach aufsteigenden
+         Leittermen sortiert sind.
+"
+{
+    int i;
+
+    // sortieren
+    G = sort(G)[1];
+
+    // reduzieren
+    ideal Gred = cleardenom(G[1]);
+    attrib(Gred,"isSB",1);
+
+    for (i = 2; i <= size(G); i++)
+    {
+        Gred = Gred + cleardenom(reduce(G[i],Gred));
+        attrib(Gred,"isSB",1);
+    }
+    attrib(Gred,"isSB",1);
+    return(Gred);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static proc Listenrest (list Liste)
+"USAGE:   Listenrest(Liste); Liste muss eine mindestens einelementige
+                            Liste sein (leere Liste ergibt Fehler).
+RETURN:  Liste ohne das erste Element.
+"
+{
+    return(delete(Liste,1));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static proc Idealrest (ideal i)
+"USAGE:   Idealrest(i); i Ideal, i <> (0).
+RETURN:  Ideal i ohne das erste Element bzw das Nullideal,
+         falls i nur ein Erzeugendes besass.
+"
+{
+    int ni = size(i);
+    if (ni == 1)
+    {
+        return(ideal(0));    // Nullideal
+    }
+    return(ideal(i[2..ni]));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static proc H_anhaengen (list L, int h)
+"USAGE:   H_anhaengen(L,h); L Liste aus Idealen, h natuerliche Zahl.
+RETURN:  Macht aus dem Listenelement i ein Paar [i,h] und setzt
+         Attribut "isSB" fuer i.
+"
+{
+    int i;
+    list E; // Ergebnisliste
+
+    for (i = 1; i <= size(L); i++)
+    {
+        E = E + list(list(L[i],h));
+        attrib(E[size(E)][1],"isSB",1);
+    }
+    return(E);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static proc faktorisiere_letzten (list L)
+"USAGE:   faktorisiere_letzten(L); L Liste aus Idealen.
+RETURN:  Faktorisiert letztes Polynom aus jedem Ideal der Liste und
+         zerlegt das Ideal entsprechend. Attribut "isSB" wird gesetzt.
+"
+{
+    int i,j;
+    ideal h;
+    int nh;
+    list factors;
+    list E;   // Ergebnisliste
+    for (i = 1; i <= size(L); i++)
+    {
+        h = L[i];
+        nh = size(h);
+        factors = factorize(h[nh],1);
+        for (j = 1; j <= size(factors[1]); j++)
+        {
+            h[nh] = factors[1][j];
+            E = insert(E,h,size(E));
+            attrib(E[size(E)],"isSB",1);
+        }
+    }
+    return(E);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static proc faktorisiere_DB (ideal db)
+"USAGE:   faktorisiere_DB(db); db reduzierte Dreiecksbasis.
+RETURN:  Liste aus reduzierten Dreiecksbasen,
+         die ensteht, indem, mit dem ersten beginnend,
+         jedes Polynom der Dreiecksbasis faktorisiert wird.
+"
+{
+    int i,j;
+    poly h;
+    list E = faktorisiere_letzten(db[1]);
+
+    for (j = 2; j <= size(db); j++)
+    {
+        for (i = 1; i <= size(E); i++)
+        {
+            h    = db[j][1] + reduce(db[j]-db[j][1],E[i]);
+            E[i] = E[i] + h;
+        }
+        E = faktorisiere_letzten(E);
+    }
+    return(E);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static proc degv (poly f, int v)
+"USAGE:   degv(f,v);  f Polynom in var(v).
+RETURN:  Liefert den Grad von f bzgl. var(v) bzw -1, falls f == 0.
+"
+{
+    if (f == 0) {return(-1);}
+    return(size(coeffs(f,var(v))) - 1);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+static proc pdiv (poly f, poly g, int v)
+"USAGE:   pdiv(f,g);  f,g Polynome in var(v), f > g.
+RETURN:  Liste, wobei [1] = prem(f,g) (Pseudoremainder),
+                      [2] = pquo(f,g) (Pseudoquotient).
+NOTE:    Pseudodivision von f durch g.
+"
+{
+    // Initialisierung
+    poly q      = 0;
+    poly rem    = f;
+    int deg_g   = degv(g,v);
+    int deg_rem = degv(rem,v);
+    poly lcg    = lcoef(g,v);     // Im Lazard-Algor. aus dem Grundring.
+    poly h;
+    rem = rem*lcg**(deg_rem - deg_g + 1); // f durch g teilbar machen.
+
+    // Gewoehnliche Polynomdivision
+    while (rem <> 0 and deg_rem >= deg_g)
+    {
+        h       = (lcoef(rem,v)/lcg)*var(v)**(deg_rem - deg_g);
+        q       = q + h;
+        rem     = rem - h*g;
+        deg_rem = degv(rem,v);
+    }
+    return(list(rem,q));
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+static proc lvar (poly f)
+"USAGE:   lvar(f);  f nicht-konstantes Polynom.
+RETURN:  groesste Variable von f bzgl. der aktuellen Termordnung.
+"
+{
+    int i = 1;
+    intvec exp = leadexp(f);
+
+    while (1)
+    {
+        if (exp[i] <> 0) {return(i);}
+        i++;
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+static proc lcoef (poly f, int v)
+"USAGE:   lcoef(f,v);  f Polynom, var(v) Ringvariable.
+RETURN:  Leitkoeffizient von f bzgl. var(v).
+"
+{
+    matrix m = coeffs(f,var(v));
+    return(m[size(m),1]);
+}
+///////////////////////////////////////////////////////////////////////////////
+
diff --git a/Singular/LIB/tropical.lib b/Singular/LIB/tropical.lib
new file mode 100644
index 0000000..cea2152
--- /dev/null
+++ b/Singular/LIB/tropical.lib
@@ -0,0 +1,8545 @@
+//
+version="version tropical.lib 4.0.0.0 Dec_2013 ";
+category="Tropical Geometry";
+info="
+LIBRARY:         tropical.lib  Computations in Tropical Geometry
+
+AUTHORS:         Anders Jensen Needergard, email: jensen at math.tu-berlin.de
+@*               Hannah Markwig,  email: hannah at uni-math.gwdg.de
+@*               Thomas Markwig,  email: keilen at mathematik.uni-kl.de
+
+WARNING:
+- tropicalLifting will only work with LINUX and if in addition gfan is installed.
+@*- drawTropicalCurve and drawTropicalNewtonSubdivision will only display the
+@*  tropical curve with LINUX and if in addition latex and kghostview
+@*  are installed.
+@*- For tropicalLifting in the definition of the basering the parameter t
+@*  from the Puiseux series field C{{t}} must be defined as a variable,
+@*  while for all other procedures it must be defined as a parameter.
+
+THEORY:
+  Fix some base field K and a bunch of lattice points v0,...,vm in the integer
+  lattice Z^n, then this defines a toric variety as the closure of (K*)^n in
+  the projective space P^m, where the torus is embedded via the map sending a
+  point x in (K*)^n to the point (x^v0,...,x^vm).
+  The generic hyperplane sections are just the images of the hypersurfaces
+  in (K*)^n defined by the polynomials f=a0*x^v0+...+am*x^vm=0. Some properties
+  of these hypersurfaces can be studied via tropicalisation.
+
+  For this we suppose that K=C{{t}} is the field of Puiseux series over the
+  field of complex numbers (or any other field with a valuation into the real
+  numbers). One associates to the hypersurface given by f=a0*x^v0+...+am*x^vm
+  the tropical hypersurface defined by the tropicalisation
+  trop(f)=min{val(a0)+<v0,x>,...,val(am)+<vm,x>}.
+  Here, <v,x> denotes the standard scalar product of the integer vector v in Z^n
+  with the vector x=(x1,...,xn) of variables, so that trop(f) is a piecewise
+  linear function on R^n. The corner locus of this function (i.e. the points
+  at which the minimum is attained a least twice) is the tropical hypersurface
+  defined by trop(f).
+  The theorem of Newton-Kapranov states that this tropical hypersurface is
+  the same as if one computes pointwise the valuation of the hypersurface
+  given by f. The analogue holds true if one replaces one equation f by an
+  ideal I. A constructive proof of the theorem is given by an adapted
+  version of the Newton-Puiseux algorithm. The hard part is to find a point
+  in the variety over C{{t}} which corresponds to a given point in the
+  tropical variety.
+
+  It is the purpose of this library to provide basic means to deal with
+  tropical varieties. Of course we cannot represent the field of Puiseux
+  series over C in its full strength, however, in order to compute interesting
+  examples it will be sufficient to replace the complex numbers C by the
+  rational numbers Q and to replace Puiseux series in t by rational functions
+  in t, i.e. we replace C{{t}} by Q(t), or sometimes even by Q[t].
+  Note, that this in particular forbids rational exponents for the t's.
+
+  Moreover, in @sc{Singular} no negative exponents of monomials are allowed, so
+  that the integer vectors vi will have to have non-negative entries.
+  Shifting all exponents by a fixed integer vector does not change the
+  tropicalisation nor does it change the toric variety. Thus this does not
+  cause any restriction.
+  If, however, for some reason you prefer to work with general vi, then you
+  have to pass right away to the tropicalisation of the equations, whereever
+  this is allowed -- these are linear polynomials where the constant coefficient
+  corresponds to the valuation of the original coefficient and where
+  the non-constant coefficient correspond to the exponents of the monomials,
+  thus they may be rational numbers respectively negative numbers:
+  e.g. if f=t^{1/2}*x^{-2}*y^3+2t*x*y+4  then  trop(f)=min{1/2-2x+3y,1+x+y,0}.
+
+  The main tools provided in this library are as follows:
+@*  - tropicalLifting    implements the constructive proof of the Theorem of
+                         Newton-Kapranov and constructs a point in the variety
+                         over C{{t}} corresponding to a given point in the
+                         corresponding tropical variety associated to an
+                         ideal I; the generators of I have to be in the
+                         polynomial ring Q[t,x1,...,xn] considered as a
+                         subring of C{{t}}[x1,...,xn]; a solution will be
+                         constructed up to given order; note that several
+                         field extensions of Q might be necessary throughout
+                         the intermediate computations; the procedures use
+                         the external program gfan
+@*  - puiseuxExpansion   computes a Newton-Puiseux expansion of a plane curve
+                         singularity
+@*  - drawTropicalCurve  visualises a tropical plane curve either given by a
+                         polynomial in Q(t)[x,y] or by a list of linear
+                         polynomials of the form ax+by+c with a,b in Z and c
+                         in Q; latex must be installed on your computer
+@*  - tropicalJInvariant computes the tropical j-invaiant of a tropical
+                         elliptic curve
+@*  - jInvariant         computes the j-invariant of an elliptic curve
+@*  - weierstrassForm     computes the Weierstrass form of an elliptic curve
+
+PROCEDURES FOR TROPICAL LIFTING:
+  tropicalLifting()          computes a point in the tropical variety
+  displayTropicalLifting()   displays the output of tropicalLifting
+  puiseuxExpansion()         computes a Newton-Puiseux expansion in the plane
+  displayPuiseuxExpansion()  displays the output of puiseuxExpansion
+
+PROCEDURES FOR DRAWING TROPICAL CURVES:
+  tropicalCurve()            computes a tropical curve and its Newton subdivision
+  drawTropicalCurve()        produces a post script image of a tropical curve
+  drawNewtonSubdivision()    produces a post script image of a Newton subdivision
+
+PROCEDURES FOR J-INVARIANTS:
+  tropicalJInvariant()       computes the tropical j-invariant of a tropical curve
+  weierstrassForm()          computes the Weierstrass form of a cubic polynomial
+  jInvariant()               computes the j-invariant of a cubic polynomial
+
+GENERAL PROCEDURES:
+  conicWithTangents()  computes a conic through five points with tangents
+  tropicalise()        computes the tropicalisation of a polynomial
+  tropicaliseSet()     computes the tropicalisation several polynomials
+  tInitialForm()       computes the tInitial form of a polynomial in Q[t,x_1,...,x_n]
+  tInitialIdeal()      computes the tInitial ideal of an ideal in Q[t,x_1,...,x_n]
+  initialForm()        computes the initial form of poly in Q[x_1,...,x_n]
+  initialIdeal()       computes the initial ideal of an ideal in Q[x_1,...,x_n]
+
+PROCEDURES FOR LATEX CONVERSION:
+  texNumber()          outputs the texcommand for the leading coefficient of poly
+  texPolynomial()      outputs the texcommand for the polynomial poly
+  texMatrix()          outputs the texcommand for the matrix
+  texDrawBasic()       embeds output of texDrawTropical in a texdraw environment
+  texDrawTropical()    computes the texdraw commands for a tropical curve
+  texDrawNewtonSubdivision()   computes texdraw commands for a Newton subdivision
+  texDrawTriangulation()       computes texdraw commands for a triangulation
+
+AUXILARY PROCEDURES:
+  radicalMemberShip()     checks radical membership
+  tInitialFormPar()       computes the t-initial form of poly in Q(t)[x_1,...,x_n]
+  tInitialFormParMax()    same as tInitialFormPar, but uses maximum
+  solveTInitialFormPar()  displays approximated solution of a 0-dim ideal
+  detropicalise()         computes the detropicalisation of a linear form
+  tDetropicalise()        computes the detropicalisation of a linear form
+  dualConic()             computes the dual of an affine plane conic
+  parameterSubstitute()   substitutes in the polynomial the parameter t by t^N
+  tropicalSubst()         makes certain substitutions in a tropical polynomial
+  randomPolyInT()         computes a polynomial with random coefficients
+  cleanTmp()              clears /tmp from files created by other procedures
+
+KEYWORDS:        tropical curves; tropical polynomials
+
+";
+
+///////////////////////////////////////////////////////////////////////////////
+/// Auxilary Static Procedures in this Library
+///////////////////////////////////////////////////////////////////////////////
+/// - phiOmega
+/// - cutdown
+/// - tropicalparametriseNoabs
+/// - findzeros
+/// - basictransformideal
+/// - testw
+/// - simplifyToOrder
+/// - scalarproduct
+/// - intvecdelete
+/// - invertorder
+/// - ordermaximalidealsNoabs
+/// - displaypoly
+/// - displaycoef
+/// - choosegfanvector
+/// - tropicalliftingresubstitute
+/// - tropicalparametrise
+/// - eliminatecomponents
+/// - findzerosAndBasictransform
+/// - ordermaximalideals
+/// - verticesTropicalCurve
+/// - bunchOfLines
+/// - clearintmat
+/// - sortintvec
+/// - sortintmat
+/// - intmatcoldelete
+/// - intmatconcat
+/// - minInIntvec
+/// - positionInList
+/// - sortlist
+/// - minInList
+/// - vergleiche
+/// - koeffizienten
+/// - minOfPolys
+/// - shorten
+/// - minOfStringDecimal
+/// - decimal
+/// - stringcontainment
+/// - stringdelete
+/// - stringinsert
+/// - texmonomial
+/// - texcoefficient
+/// - abs
+/// - findNonLoopVertex
+/// - coordinatechange
+/// - weierstrassFormOfACubic
+/// - weierstrassFormOfA4x2Curve
+/// - weierstrassFormOfA2x2Curve
+/// - jInvariantOfACubic
+/// - jInvariantOfA4x2Curve
+/// - jInvariantOfA2x2Curve
+/// - jInvariantOfAPuiseuxCubic
+//////////////////////////////////////////////////////////////////////////////
+
+
+
+//////////////////////////////////////////////////////////////////////////////
+LIB "random.lib";
+LIB "solve.lib";
+LIB "poly.lib";
+LIB "elim.lib";
+LIB "linalg.lib";
+LIB "polymake.lib";
+LIB "primdec.lib";
+LIB "absfact.lib";
+LIB "hnoether.lib";
+LIB "ring.lib";
+//////////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////////
+/// Procedures concerned with tropical parametrisation
+///////////////////////////////////////////////////////////////////////////////
+
+proc tropicalLifting (ideal i,intvec w,int ordnung,list #)
+"USAGE:  tropicalLifting(i,w,ord[,opt]); i ideal, w intvec, ord int, opt string
+ASSUME:  - i is an ideal in Q[t,x_1,...,x_n], w=(w_0,w_1,...,w_n)
+           and (w_1/w_0,...,w_n/w_0) is in the tropical variety of i,
+           and ord is the order up to which a point in V(i) over Q{{t}}
+           lying over (w_1/w_0,...,w_n/w_0) shall be computed;
+           w_0 may NOT be ZERO
+@*       - the basering should not have any parameters on its own
+           and it should have a global monomial ordering,
+           e.g. ring r=0,(t,x(1..n)),dp;
+@*       - the first variable of the basering will be treated as the
+           parameter t in the Puiseux series field
+@*       - the optional parameter opt should be one or more strings among
+           the following:
+@*         'isZeroDimensional'  : the dimension i is zero (not to be checked);
+@*         'isPrime'            : the ideal is prime over Q(t)[x_1,...,x_n]
+                                  (not to be checked);
+@*         'isInTrop'           : (w_1/w_0,...,w_n/w_0) is in the tropical
+                                  variety (not to be checked);
+@*         'oldGfan'            : uses gfan version 0.2.1 or less
+@*         'findAll'            : find all solutions of a zero-dimensional
+                                  ideal over (w_1/w_0,...,w_n/w_0)
+@*         'noAbs'              : do NOT use absolute primary decomposition
+@*         'puiseux'            : n=1 and i is generated by one equation
+@*         'noResubst'          : avoids the computation of the resubstitution
+RETURN:  IF THE OPTION 'findAll' WAS NOT SET THEN:
+@*       list, containing one lifting of the given point (w_1/w_0,...,w_n/w_0)
+               in the tropical variety of i to a point in V(i) over Puiseux
+               series field up to the first ord terms; more precisely:
+@*             IF THE OPTION 'noAbs' WAS NOT SET, THEN:
+@*             l[1] = ring Q[a]/m[[t]]
+@*             l[2] = int
+@*             l[3] = intvec
+@*             l[4] = list
+@*             IF THE OPTION 'noAbs' WAS SET, THEN:
+@*             l[1] = ring Q[X(1),...,X(k)]/m[[t]]
+@*             l[2] = int
+@*             l[3] = intvec
+@*             l[4] = list
+@*             l[5] = string
+@*       IF THE OPITON 'findAll' WAS SET, THEN:
+@*       list, containing ALL liftings of the given point ((w_1/w_0,...,w_n/w_0)
+               in the tropical variety of i to a point in V(i) over Puiseux
+               series field up to the first ord terms, if the ideal is
+               zero-dimensional over Q{{t}};
+               more precisely, each entry of the list is a list l as computed
+               if  'findAll' was NOT set
+@*       WE NOW DESCRIBE THE LIST ENTRIES IF 'findAll' WAS NOT SET:
+@*       - the ring l[1] contains an ideal LIFT, which contains
+           a point in V(i) lying over w up to the first ord terms;
+@*       - and if the integer l[2] is N then t has to be replaced by t^1/N
+           in the lift, or alternatively replace t by t^N in the defining ideal
+@*       - if the k+1st entry of l[3] is  non-zero, then the kth component of
+           LIFT has to be multiplied t^(-l[3][k]/l[3][1]) AFTER substituting t
+           by t^1/N
+@*       - unless the option 'noResubst' was set, the kth entry of list l[4]
+           is a string which represents the kth generator of
+           the ideal i where the coordinates have been replaced by the result
+           of the lift;
+           the t-order of the kth entry should in principle be larger than the
+           t-degree of LIFT
+@*       - if the option 'noAbs' was set, then the string in l[5] defines
+           a maximal ideal in the field Q[X(1),...,X(k)], where X(1),...,X(k)
+           are the parameters of the ring in l[1];
+           the basefield of the ring in l[1] should be considered modulo this
+           ideal
+REMARK:  - it is best to use the procedure displayTropicalLifting to
+           display the result
+@*       - the option 'findAll' cannot be used if 'noAbs' is set
+@*       - if the parameter 'findAll' is set AND the ideal i is zero-dimensional
+           in Q{{t}}[x_1,...,x_n] then ALL points in V(i) lying over w are
+           computed up to order ord; if the ideal is not-zero dimenisonal, then
+           only the points in the ideal after cutting down to dimension zero
+           will be computed
+@*       - the procedure requires that the program GFAN is installed on your
+           computer; if you have GFAN version less than 0.3.0 then you must
+           use the optional parameter 'oldGfan'
+@*       - the procedure requires the @sc{Singular} procedure absPrimdecGTZ to be
+           present in the package primdec.lib, unless the option 'noAbs' is set;
+           but even if absPrimdecGTZ is present it might be necessary to set
+           the option 'noAbs' in order to avoid the costly absolute primary
+           decomposition; the side effect is that the field extension which is
+           computed throughout the recursion might need more than one
+           parameter to be described
+@*       - since Q is infinite, the procedure finishes with probability one
+@*       - you can call the procedure with Z/pZ as base field instead of Q,
+           but there are some problems you should be aware of:
+@*         + the Puiseux series field over the algebraic closure of Z/pZ is
+             NOT algebraicall closed, and thus there may not exist a point in
+             V(i) over the Puiseux series field with the desired valuation;
+             so there is no chance that the procedure produced a sensible output
+             - e.g. if i=tx^p-tx-1
+@*         + if the dimension of i over Z/pZ(t) is not zero the process of
+             reduction to zero might not work if the characteristic is small
+             and you are unlucky
+@*         + the option 'noAbs' has to be used since absolute primary
+             decomposition in @sc{Singular} only works in characteristic zero
+@*       - the basefield should either be Q or Z/pZ for some prime p;
+           field extensions will be computed if necessary; if you need
+           parameters or field extensions from the beginning they should
+           rather be simulated as variables possibly adding their relations to
+           the ideal; the weights for the additional variables should be zero
+EXAMPLE: example tropicalLifting;   shows an example"
+{
+  // if the basering has parameters, then exit with an error message
+  if (parstr(basering)!="")
+  {
+    ERROR("The procedure is not implemented for rings with parameters. See: help tropicalLifting; for more information");
+  }
+  // in order to avoid unpleasent surprises with the names of the variables
+  // we change to a ring where the variables have names t and x(1),...,x(n)
+  def ALTERRING=basering;
+  if (nvars(basering)==2)
+  {
+    execute("ring BASERING=("+charstr(ALTERRING)+"),(t,x(1)),("+ordstr(ALTERRING)+");");
+  }
+  else
+  {
+    execute("ring BASERING=("+charstr(ALTERRING)+"),(t,x(1.."+string(nvars(ALTERRING)-1)+")),("+ordstr(ALTERRING)+");");
+  }
+  map altphi=ALTERRING,maxideal(1);
+  ideal i=altphi(i);
+  int j,k,l,jj,kk;  // index variables
+  // work through the optionional parameters
+  int isprime,iszerodim,isintrop,gfanold,findall,noabs,nogfan,noresubst,puiseux;
+  for (j=1;j<=size(#);j++)
+  {
+    if (#[j]=="isZeroDimensional")
+    {
+      iszerodim=1;
+    }
+    if (#[j]=="isPrime")
+    {
+      isprime=1;
+    }
+    if (#[j]=="isInTrop")
+    {
+      isintrop=1;
+    }
+    if (#[j]=="oldGfan")
+    {
+      gfanold=1;
+    }
+    if (#[j]=="findAll")
+    {
+      findall=1;
+    }
+    if (#[j]=="noAbs")
+    {
+      noabs=1;
+    }
+    if (#[j]=="puiseux")
+    {
+      int puiseuxgood=0;
+      // test, if the option puiseux makes sense, i.e. we are considering a plane curve
+      if ((size(i)==1) and (nvars(basering)==2))
+      {
+        puiseuxgood=1;
+      }
+      // the case, where the base field has a parameter and a minimal polynomial is
+      // treated by an additional variable (which should be the last variable)
+      // and an ideal containing the minimal polynomial as first entry
+      if ((size(i)==2) and (nvars(basering)==3))
+      {
+        // check if the first entry is the minimal polynomial
+        poly mpcheck=i[1];
+        if (substitute(mpcheck,var(1),0,var(2),0)==mpcheck)
+        {
+          puiseuxgood=1;
+        }
+        kill mpcheck;
+      }
+      if (puiseuxgood==0)
+      {
+        ERROR("The option puiseux is not allowed for this ring. See: help tropicalLifting; for more information");
+      }
+      puiseux=1;
+      nogfan=1;  // if puiseux is set, then gfan should not be used
+    }
+    // this option is not documented -- it prevents the execution of gfan and
+    // just asks for wneu to be inserted -- it can be used to check problems
+    // with the precedure without calling gfan, if wneu is know from previous
+    // computations
+    if (#[j]=="noGfan")
+    {
+      nogfan=1;
+    }
+    if (#[j]=="noResubst")
+    {
+      noresubst=1;
+    }
+  }
+  // if the basering has characteristic not equal to zero,
+  // then absolute factorisation
+  // is not available, and thus we need the option noAbs
+/*
+  if ((char(basering)!=0) and (noabs!=1))
+  {
+    ERROR("If the characteristic is not zero the procedure should be called with option 'noAbs'");
+  }
+*/
+  int N=1; // we are working with the variable t^1/N - the N may be changed
+  // w_0 must be non-zero!
+  if (w[1]==0)
+  {
+    Error("The first coordinate of your input w must be NON-ZERO, since it is a DENOMINATOR!");
+  }
+  // if w_0<0, then replace w by -w, so that the "denominator" w_0 is positive
+  if (w[1]<0)
+  {
+    w=-w;
+  }
+  intvec prew=w; // stores w for later reference
+  // for our computations, w[1] represents the weight of t and this
+  // should be -w_0 !!!
+  w[1]=-w[1];
+  // if w_0!=-1 then replace t by t^-w_0 and w_0 by -1
+  if (w[1]<-1)
+  {
+    i=subst(i,t,t^(-w[1]));
+    N=-w[1];
+    w[1]=-1;
+  }
+  // if some entry of w is positive, we have to make a transformation,
+  // which moves it to something non-positive
+  for (j=2;j<=nvars(basering);j++)
+  {
+    if (w[j]>0)
+    {
+      // transform x_j to t^(-w[j])*x_j in the ideal i
+      i=phiOmega(i,j,w[j]);
+      w[j]=0;
+    }
+  }
+  prew[1]=prew[1]+w[1];
+  prew=prew-w; // this now contains the positive part of the original w,
+  // but the original first comp. of w
+  // pass to a ring which represents Q[t]_<t>[x1,...,xn]
+  // for this, unfortunately, t has to be the last variable !!!
+  ideal variablen;
+  for (j=2;j<=nvars(basering);j++)
+  {
+    variablen=variablen+var(j);
+  }
+  execute("ring GRUNDRING=("+charstr(basering)+"),("+string(variablen)+",t),(dp("+string(nvars(basering)-1)+"),lp(1));");
+  ideal variablen;
+  for (j=1;j<=nvars(basering)-1;j++)
+  {
+    variablen=variablen+var(j);
+  }
+  map GRUNDPHI=BASERING,t,variablen;
+  ideal i=GRUNDPHI(i);
+  // compute the initial ideal of i and test if w is in the tropical
+  // variety of i
+  // - the last entry 1 only means that t is the last variable in the ring
+  ideal ini=tInitialIdeal(i,w,1);
+  if (isintrop==0) // test if w is in trop(i) only if isInTrop has not been set
+  {
+    poly product=1;
+    for (j=1;j<=nvars(basering)-1;j++)
+    {
+      product=product*var(j);
+    }
+    if (radicalMemberShip(product,ini)==1) // if w is not in Trop(i) - error
+    {
+      ERROR("The integer vector is not in the tropical variety of the ideal.");
+    }
+  }
+  // compute next the dimension of i in K(t)[x] and cut the ideal down to dim 0
+  if (iszerodim==0) // do so only if is_dim_zero is not set
+  {
+    execute("ring QUOTRING=("+charstr(basering)+",t),("+string(variablen)+"),dp;");
+    ideal i=groebner(imap(GRUNDRING,i));
+    int dd=dim(i);
+    setring GRUNDRING;
+    // if the dimension is not zero, we cut the ideal down to dimension zero
+    // and compute the
+    // t-initial ideal of the new ideal at the same time
+    if(dd!=0)
+    {
+      // the procedurce cutdown computes a new ring, in which there lives a
+      // zero-dimensional
+      // ideal which has been computed by cutting down the input with
+      // generic linear forms
+      // of the type x_i1-p_1,...,x_id-p_d for some polynomials
+      // p_1,...,p_d not depending
+      // on the variables x_i1,...,x_id; that way we have reduced
+      // the number of variables by dd !!!
+      // the new zero-dimensional ideal is called i, its t-initial
+      // ideal (with respect to
+      // the new w=CUTDOWN[2]) is ini, and finally there is a list
+      // repl in the ring
+      // which contains at the polynomial p_j at position i_j and
+      //a zero otherwise;
+      if (isprime==0) // the minimal associated primes of i are computed
+      {
+        list CUTDOWN=cutdown(i,w,dd);
+      }
+      else // i is assumed to be prime
+      {
+        list CUTDOWN=cutdown(i,w,dd,"isPrime");
+      }
+      def CUTDOWNRING=CUTDOWN[1];
+      intvec precutdownw=w;  // save the old w for later reference
+      w=CUTDOWN[2];          // the new w - some components have been eliminated
+      setring CUTDOWNRING;
+    }
+  }
+  else
+  {
+    int dd=0; // the dimension of i
+  }
+  list liftrings; // will contain the final result
+  // if the procedure is called without 'findAll' then it may happen, that no
+  // proper solution is found when dd>0; in that case we have
+  // to start all over again;
+  // this is controlled by the while-loop
+  intvec ordnungskontrollvektor=N,-w[2]; // used with the option puiseux
+  while (size(liftrings)==0)
+  {
+    // compute lifting for the zero-dimensional ideal via tropicalparametrise
+    if (noabs==1) // do not use absolute primary decomposition
+    {
+      list TP=list(tropicalparametriseNoabs(i,w,ordnung,gfanold,nogfan,puiseux,ini));
+    }
+    else // use absolute primary decomposition
+    {
+      list TP=tropicalparametrise(i,w,ordnung,ordnungskontrollvektor,gfanold,findall,nogfan,puiseux,ini);
+    }
+    // compute the liftrings by resubstitution
+    kk=1;  // counts the liftrings
+    int isgood;  // test in the non-zerodimensional case
+                 // if the result has the correct valuation
+    for (jj=1;jj<=size(TP);jj++)
+    {
+      // the list TP contains as a first entry the ring over which the
+      // tropical parametrisation
+      // of the (possibly cutdown ideal) i lives
+      def LIFTRING=TP[jj][1];
+      // if the dimension of i originally was not zero,
+      // then we have to fill in the missing
+      // parts of the parametrisation
+      if (dd!=0)
+      {
+        // we need a ring where the parameters X_1,...,X_k
+        // from LIFTRING are present,
+        // and where also the variables of CUTDOWNRING live
+        execute("ring REPLACEMENTRING=("+charstr(LIFTRING)+"),("+varstr(CUTDOWNRING)+"),dp;");
+        list repl=imap(CUTDOWNRING,repl); // get the replacement rules
+                                          // from CUTDOWNRING
+        ideal PARA=imap(LIFTRING,PARA);   // get the zero-dim. parametrisatio
+                                          // from LIFTRING
+        // compute the lift of the solution of the original ideal i
+        ideal LIFT;
+        k=1;
+        // the lift has as many components as GRUNDRING has variables!=t
+        for (j=1;j<=nvars(GRUNDRING)-1;j++)
+        {
+          // if repl[j]=0, then the corresponding variable was not eliminated
+          if (repl[j]==0)
+          {
+            LIFT[j]=PARA[k]; // thus the lift has been
+                             // computed by tropicalparametrise
+            k++; // k checks how many entries of PARA have already been used
+          }
+          else  // if repl[j]!=0, repl[j] contains replacement rule for the lift
+          {
+            LIFT[j]=repl[j]; // we still have to replace the vars
+                             // in repl[j] by the corresp. entries of PARA
+            // replace all variables!=t (from CUTDOWNRING)
+            for (l=1;l<=nvars(CUTDOWNRING)-1;l++)
+            {
+              // substitute the kth variable by PARA[k]
+              LIFT[j]=subst(LIFT[j],var(l),PARA[l]);
+            }
+          }
+        }
+        setring LIFTRING;
+        ideal LIFT=imap(REPLACEMENTRING,LIFT);
+        // test now if the LIFT has the correct valuation !!!
+        // note: it may happen, that when resubstituting PARA into
+        //       the replacement rules
+        //       there occured some unexpected cancellation;
+        //       we only know that for SOME
+        //       solution of the zero-dimensional reduction NO
+        //       canellation will occur,
+        //       but for others this may very well happen;
+        //       this in particular means that
+        //       we possibly MUST compute all zero-dimensional
+        //       solutions when cutting down!
+        intvec testw=precutdownw[1];
+        for (j=1;j<=size(LIFT);j++)
+        {
+          testw[j+1]=-ord(LIFT[j]);
+        }
+        if (testw==precutdownw)
+        {
+          isgood=1;
+        }
+        else
+        {
+          isgood=0;
+        }
+      }
+      else
+      {
+        setring LIFTRING;
+        ideal LIFT=PARA;
+        isgood=1;
+      }
+      kill PARA;
+      // only if LIFT has the right valuation we have to do something
+      if (isgood==1)
+      {
+        // it remains to reverse the original substitutions,
+        // where appropriate !!!
+        // if some entry of the original w was positive,
+        // we replace the corresponding
+        // variable x_i by t^-w[i]*x_i, so we must now replace
+        // the corresponding entry
+        // LIFT[i] by t^-w[i]*LIFT[i] --- the original w is stored in prew
+        // PROBLEM: THIS CANNOT BE DONE SINCE -w[i] IS NEGATIVE
+        // INSTEAD: RETURN prew IN THE LIST
+        /*
+          for (j=2;j<=size(prew);j++)
+          {
+          if (prew[j]>0)
+          {
+          LIFT[j-1]=t^(-prew[j])*LIFT[j-1];
+          }
+          }
+        */
+        // if LIFTRING contains a parameter @a, change it to a
+        if ((noabs==0) and (defined(@a)==-1))
+        {
+          // pass first to a ring where a and @a
+          // are variables in order to use maps
+          poly mp=minpoly;
+          ring INTERRING=char(LIFTRING),(t, at a,a),dp;
+          poly mp=imap(LIFTRING,mp);
+          ideal LIFT=imap(LIFTRING,LIFT);
+          kill LIFTRING;
+          // replace @a by a in minpoly and in LIFT
+          map phi=INTERRING,t,a,a;
+          mp=phi(mp);
+          LIFT=phi(LIFT);
+          // pass now to a ring whithout @a and with a as parameter
+          ring LIFTRING=(char(INTERRING),a),t,ls;
+          minpoly=number(imap(INTERRING,mp));
+          ideal LIFT=imap(INTERRING,LIFT);
+          kill INTERRING;
+        }
+        // then export LIFT
+        export(LIFT);
+        // test the  result by resubstitution
+        setring GRUNDRING;
+        list resubst;
+        if (noresubst==0)
+        {
+          if (noabs==1)
+          {
+            resubst=tropicalliftingresubstitute(substitute(i,t,t^(TP[jj][2])),list(LIFTRING),N*TP[jj][2],TP[jj][3]);
+          }
+          else
+          {
+            resubst=tropicalliftingresubstitute(substitute(i,t,t^(TP[jj][2])),list(LIFTRING),N*TP[jj][2]);
+          }
+        }
+        setring BASERING;
+        // Finally, if t has been replaced by t^N, then we have to change the
+        // third entry of TP by multiplying by N.
+        if (noabs==1)
+        {
+          liftrings[kk]=list(LIFTRING,N*TP[jj][2],prew,resubst,TP[jj][3]);
+        }
+        else
+        {
+          liftrings[kk]=list(LIFTRING,N*TP[jj][2],prew,resubst);
+        }
+        kk++;
+        kill resubst;
+      }
+      setring BASERING;
+      kill LIFTRING;
+    }
+    // if dd!=0 and the procedure was called without the
+    // option findAll, then it might very well
+    // be the case that no solution is found, since
+    // only one solution for the zero-dimensional
+    // reduction was computed and this one might have
+    // had cancellations when resubstituting;
+    // if so we have to restart the process with the option findAll
+    if (size(liftrings)==0)
+    {
+      "The procedure was called without findAll and no proper solution was found.";
+      "The procedure will be restarted with the option 'findAll'.";
+      "Go on by hitting RETURN!";
+      findall=1;
+      noabs=0;
+      setring CUTDOWNRING;
+      int hadproblems;
+      "i";i;
+      "ini";tInitialIdeal(i,w,1);
+
+/*
+      setring GRUNDRING;
+      list repl=imap(CUTDOWNRING,repl);
+      i=imap(CUTDOWNRING,i);
+      for (j=1;j<=nvars(basering)-1;j++)
+      {
+        if (repl[j]!=0)
+        {
+          i=i+ideal(var(j)-repl[j]);
+        }
+      }
+      ini=tInitialIdeal(i,precutdownw,1);
+      w=precutdownw;
+*/
+
+    }
+  }
+  // if internally the option findall was set, then return
+  // only the first solution
+  if (defined(hadproblems)!=0)
+  {
+    liftrings=liftrings[1];
+  }
+  ///////////////////////////////////////////////////////////
+  if (printlevel-voice+2>=0)
+  {
+
+      "The procedure has created a list of lists. The jth entry of this list
+contains a ring, an integer and an intvec.
+In this ring lives an ideal representing the wanted lifting,
+if the integer is N then in the parametrisation t has to be replaced by t^1/N,
+and if the ith component of the intvec is w[i] then the ith component in LIFT
+should be multiplied by t^-w[i]/N in order to get the parametrisation.
+
+Suppose your list has the name L, then you can access the 1st ring via:
+";
+    if (findall==1)
+    {
+      "def LIFTRing=L[1][1]; setring LIFTRing; LIFT;
+";
+    }
+    else
+    {
+      "def LIFTRing=L[1]; setring LIFTRing; LIFT;
+";
+    }
+  }
+  if (findall==1) // if all solutions have been computed, return a list of lists
+  {
+    return(liftrings);
+  }
+  else //if only 1 solution was to be computed, return the 1st list in liftrings
+  {
+    liftrings=liftrings[1];
+    return(liftrings);
+  }
+}
+example
+{
+   "EXAMPLE:";
+   int oldprintlevel=printlevel;
+   printlevel=1;
+   echo=2;
+   ////////////////////////////////////////////////////////
+   // 1st EXAMPLE:
+   ////////////////////////////////////////////////////////
+   ring r=0,(t,x),dp;
+   ideal i=(1+t2)*x2+t5x+t2;
+   intvec w=1,-1;
+   list LIST=tropicalLifting(i,w,4);
+   def LIFTRing=LIST[1];
+   setring LIFTRing;
+   // LIFT contains the first 4 terms of a point in the variety of i
+   // over the Puiseux series field C{{t}} whose order is -w[1]/w[0]=1
+   LIFT;
+   // Since the computations were done over Q a field extension was necessary,
+   // and the parameter "a" satisfies the equation given by minpoly
+   minpoly;
+   ////////////////////////////////////////////////////////
+   // 2nd EXAMPLE
+   ////////////////////////////////////////////////////////
+   setring r;
+   LIST=tropicalLifting(x12-t11,intvec(12,-11),2,"isPrime","isInTrop");
+   def LIFTRing2=LIST[1];
+   setring LIFTRing2;
+   // This time, LIFT contains the lifting of the point -w[1]/w[0]=11/12
+   // only after we replace in LIFT the variable t by t^1/N with N=LIST[3]
+   LIFT;
+   LIST[3];
+   ///////////////////////////////////////////////////////
+   // 3rd EXAMPLE
+   ////////////////////////////////////////////////////////
+   ring R=0,(t,x,y,z),dp;
+   ideal i=-y2t4+x2,yt3+xz+y;
+   w=1,-2,0,2;
+   LIST=tropicalLifting(i,w,3);
+   // This time, LIFT contains the lifting of the point v=(-2,0,2)
+   // only after we multiply LIFT[3] by t^k with k=-LIST[4][3];
+   // NOTE: since the last component of v is positive, the lifting
+   //       must start with a negative power of t, which in Singular
+   //       is not allowed for a variable.
+   def LIFTRing3=LIST[1];
+   setring LIFTRing3;
+   LIFT;
+   LIST[4];
+   // An easier way to display this is via displayTropicalLifting.
+   setring R;
+   displayTropicalLifting(LIST,"subst");
+   printlevel=oldprintlevel;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc displayTropicalLifting (list troplift,list #)
+"USAGE:    displaytropcallifting(troplift[,#]); troplift list, # list
+ASSUME:    troplift is the output of tropicalLifting; the optional parameter
+           # can be the string 'subst'
+RETURN:    none
+NOTE:      - the procedure displays the output of the procedure tropicalLifting
+@*         - if the optional parameter 'subst' is given, then the lifting is
+             substituted into the ideal and the result is displayed
+EXAMPLE:   example displayTropicalLifting;   shows an example"
+{
+  int j;
+  // if the procedure has to display more than one lifting
+  if (typeof(troplift[1])=="list")
+  {
+    for (j=1;j<=size(troplift);j++)
+    {
+      "=============================";
+      string(j)+". Lifting:";
+      "";
+      displayTropicalLifting(troplift[j],#);
+      "";
+    }
+  }
+  // if the procedure has to display only one lifting
+  else
+  {
+    list variablen;
+    for (j=2;j<=nvars(basering);j++)
+    {
+      variablen[j-1]=string(var(j));
+    }
+    def LIFTRing=troplift[1];
+    int N=troplift[2];
+    intvec wdiff=troplift[3];
+    string LIFTpar=parstr(LIFTRing);
+    if (char(LIFTRing)==0)
+    {
+      string Kstring="Q";
+    }
+    else
+    {
+      string Kstring="Z/"+string(char(LIFTRing))+"Z";
+    }
+    // this means that tropicalLifting was called with
+    // absolute primary decomposition
+    if (size(troplift)==4)
+    {
+      setring LIFTRing;
+      "The lifting of the point in the tropical variety lives in the ring";
+      if ((size(LIFTpar)==0) and (N==1))
+      {
+        Kstring+"[[t]]";
+      }
+      if ((size(LIFTpar)==0) and (N!=1))
+      {
+        Kstring+"[[t^(1/"+string(N)+")]]";
+      }
+      if ((size(LIFTpar)!=0) and (N!=1))
+      {
+        Kstring+"["+LIFTpar+"]/"+string(minpoly)+"[[t^(1/"+string(N)+")]]";
+      }
+      if ((size(LIFTpar)!=0) and (N==1))
+      {
+        Kstring+"["+LIFTpar+"]/"+string(minpoly)+"[[t]]";
+      }
+    }
+    else // tropicalLifting was called with the option noAbs
+    {
+      string m=troplift[5];
+      setring LIFTRing;
+      "The lifting of the point in the tropical variety lives in the ring";
+      if ((size(LIFTpar)==0) and (N==1))
+      {
+        Kstring+"[[t]]";
+      }
+      if ((size(LIFTpar)==0) and (N!=1))
+      {
+        Kstring+"[[t^(1/"+string(N)+")]]";
+      }
+      if ((size(LIFTpar)!=0) and (N!=1))
+      {
+        Kstring+"["+LIFTpar+"]/M[[t^(1/"+string(N)+")]]";
+        "where M is the maximal ideal";
+        "M=<"+m+">";
+      }
+      if ((size(LIFTpar)!=0) and (N==1))
+      {
+        Kstring+"["+LIFTpar+"]/M[[t]]";
+        "where M is the maximal ideal";
+        "M=<"+m+">";
+      }
+    }
+    "";
+    "The lifting has the form:";
+    for (j=1;j<=size(LIFT);j++)
+    {
+      if (ncols(LIFT)==size(variablen))
+      {
+        variablen[j]+"="+displaypoly(LIFT[j],N,wdiff[j+1],wdiff[1]);
+      }
+      else
+      {
+        "var("+string(j)+")="+displaypoly(LIFT[j],N,wdiff[j+1],wdiff[1]);
+      }
+    }
+    if (size(#)>0)
+    {
+      if (#[1]=="subst")
+      {
+        "";
+        "Substituting the solution into the ideal gives:";
+        for(j=1;j<=size(troplift[4]);j++)
+        {
+          "i["+string(j)+"]="+troplift[4][j];
+        }
+      }
+    }
+  }
+}
+example
+{
+   "EXAMPLE:";
+   echo=2;
+   ring r=0,(t,x,y,z),dp;
+   ideal i=-y2t4+x2,yt3+xz+y;
+   intvec w=2,-4,0,4;
+   displayTropicalLifting(tropicalLifting(i,w,3),"subst");
+}
+
+proc puiseuxExpansion (poly f,int n,list #)
+"USAGE:  puiseuxExpansion(f,n,#); f poly, n int, # list
+ASSUME:  f is a non-constant polynomial in two variables which is not
+         divisible by the first variable and which is squarefree
+         as a power series over the complex numbers;
+         the base field is either the field of rational numbers or a finite extension thereof;
+         monomial ordering is assumed to be local;
+         the optional parameter # can be the string 'subst'
+RETURN:  list, where each entry of the list l describes the Newton-Puiseux
+@*             parametrisations of one branch of the plane curve singularity
+@*             at the origin defined by f; only the terms up to order n of each
+@*             parametetrisation are computed
+@*             l[i][1] = is a ring
+@*             l[i][2] = int
+@*             l[i][3] = string
+@*
+@*       WE NOW DESCRIBE THE LIST ENTRIES l[i] IN MORE DETAIL:
+@*       - the ring l[i][1] contains an ideal LIFT and the Newton-Puiseux
+           parametrisation of the branch is given by x=t^N and y=LIFT[1],
+           where N=l[i][2]
+@*       - if the base field had a parameter and a minimal polynomial, then
+           the new base field will have a parameter and a new minimal polynomial,
+           and LIFT[2] describes how the old parameter can be computed from the new one
+@*       - if a field extension with minimal polynomial of degree k was necessary,
+           then to the one extension produced acutally k extensions correspond by replacing
+           the parameter a successively by all zeros of the minimal polynomial
+@*       - if the option subst was set l[i][3] contains the polynomial where
+           y has been substituted by y(t^{1/N}) as a string
+REMARK:  - it is best to use the procedure displayPuiseuxExpansion to
+           display the result
+@*       - the procedure requires the @sc{Singular} procedure absPrimdecGTZ to be
+           present in the package primdec.lib
+@*       - if f is not squarefree it will be replaced by its squarefree part
+EXAMPLE:   example puiseuxExpansion;   shows an example"
+{
+  if (deg(f)<=0)
+  {
+    ERROR("The input polynomial is not allowed to be constant!");
+  }
+  if (char(basering)!=0)
+  {
+    ERROR("In positive characteristic a Puiseux expansion will not in general exist!");
+  }
+  if ((npars(basering)>1) or ((npars(basering)==1) and (minpoly==0)))
+  {
+    ERROR("The procedure is not implemented for this base field!");
+  }
+  if (nvars(basering)!=2)
+  {
+    ERROR("The base ring should depend on exactly two variables.");
+  }
+  if (f==(f / var(1))*var(1))
+  {
+    ERROR("The input polynomial is not allowed to be divisible by the first variable.");
+  }
+  // if the ordering is not local, change to a local ordering
+  if ((1<var(1)) or (1<var(2)))
+  {
+    def GLOBALRING=basering;
+    def LOCALRING=changeordTo(GLOBALRING,"ds");
+    setring LOCALRING;
+    poly f=imap(GLOBALRING,f);
+  }
+  // check if a substitution is necessary
+  int noResubst;
+  if (size(#)>1)
+  {
+    if (#[1]=="subst")
+    {
+      noResubst=0;
+    }
+  }
+  // replace f by its squarefree part
+  f=squarefree(f);
+  // check if var(1) or var(2) divide f
+  int coordinatebranchtwo;
+  if (f==(f / var(2))*var(2))
+  {
+    coordinatebranchtwo=1;
+    f=f/var(2);
+  }
+  int jj;
+  // if f is now constant then we should skip the next part
+  if (deg(f)!=0)
+  {
+    // compute the Newton polygon
+    int zw;
+    intvec w;
+    int ggteiler;
+    list NewtP=newtonpoly(f);
+    list tls;
+    list pexp;
+    // if the base field has a minimal polynomial change the base ring and the ideal
+    if (minpoly!=0)
+    {
+      poly mp=minpoly;
+      def OLDRING=basering;
+      execute("ring NEWRING=0,("+varstr(basering)+","+parstr(basering)+"),ds;");
+      ideal I=imap(OLDRING,mp),imap(OLDRING,f);
+    }
+    else
+    {
+      ideal I=f;
+    }
+    // for each facet of the Newton polygon compute the corresponding parametrisations
+    // using tropicalLifting with the option "puiseux" which avoids gfan
+    for (jj=1;jj<=size(NewtP)-1;jj++)
+    {
+      w=NewtP[jj]-NewtP[jj+1];
+      ggteiler=gcd(w[1],w[2]);
+      zw=w[1] div ggteiler;
+      w[1]=w[2] div ggteiler;
+      w[2]=zw;
+      // if we have introduced a third variable for the parameter, then w needs a third component
+      if (nvars(basering)==3)
+      {
+        w[3]=0;
+      }
+      if (noResubst==0)
+      {
+        tls=tropicalLifting(I,w,n,"findAll","puiseux");
+      }
+      else
+      {
+        tls=tropicalLifting(I,w,n,"findAll","puiseux","noResubst");
+      }
+      pexp=pexp+tls;
+    }
+    // kill rings that are no longer needed
+    if (defined(NEWRING))
+    {
+      setring OLDRING;
+      kill NEWRING;
+    }
+    if (defined(GLOBALRING))
+    {
+      setring GLOBALRING;
+      kill LOCALRING;
+    }
+    // remove the third entry in the list of parametrisations since we know
+    // that none of the exponents in the parametrisation will be negative
+    for (jj=1;jj<=size(pexp);jj++)
+    {
+      pexp[jj]=delete(pexp[jj],3);
+      pexp[jj][3]=pexp[jj][3][size(pexp[jj][3])]; // replace the list in pexp[jj][3] by its first entry
+    }
+  }
+  else // if f was reduced to a constant we still have to introduce the list pexp
+  {
+    list pexp;
+  }
+  // we have to add the parametrisations for the branches var(1) resp. var(2) if
+  // we removed them
+  def BASERING=basering;
+  if (coordinatebranchtwo==1)
+  {
+    ring brring=0,t,ds;
+    ideal LIFT=0;
+    export(LIFT);
+    setring BASERING;
+    list pexpentry;
+    pexpentry[1]=brring;
+    pexpentry[2]=1;
+    pexpentry[3]="0";
+    pexp[size(pexp)+1]=pexpentry;
+    kill brring;
+  }
+  // check if all branches have been found
+  int numberofbranchesfound;
+  for (jj=1;jj<=size(pexp);jj++)
+  {
+    def countring=pexp[jj][1];
+    setring countring;
+    if (minpoly==0)
+    {
+      numberofbranchesfound=numberofbranchesfound+1;
+    }
+    else
+    {
+      poly mp=minpoly;
+      ring degreering=0,a,dp;
+      poly mp=imap(countring,mp);
+      numberofbranchesfound=numberofbranchesfound+deg(mp);
+      setring countring;
+      kill degreering;
+    }
+    setring BASERING;
+    kill countring;
+  }
+  // give a warning if not all branches have been found
+  if (numberofbranchesfound!=ord(subst(f,x,0))+coordinatebranchtwo)
+  {
+    "!!!! WARNING: The number of terms computed in the Puiseux expansion were";
+    "!!!!          not enough to find all branches of the curve singularity!";
+  }
+  return(pexp);
+}
+example
+{
+   "EXAMPLE:";
+   echo=2;
+   printlevel=1;
+   ring r=0,(x,y),ds;
+   poly f=x2-y4+x5y7;
+   puiseuxExpansion(f,3,"subst");
+   displayPuiseuxExpansion(puiseuxExpansion(f,3));
+}
+
+proc displayPuiseuxExpansion (list puiseux,list #)
+"USAGE:    displayPuiseuxExpansion(puiseux[,#]); puiseux list, # list
+ASSUME:    puiseux is the output of puiseuxExpansion; the optional parameter
+           # can be the string 'subst'
+RETURN:    none
+NOTE:      - the procedure displays the output of the procedure puiseuxExpansion
+@*         - if the optional parameter 'subst' is given, then the expansion is
+             substituted into the polynomial and the result is displayed
+@*         - if the base field had a parameter and a minimal polynomial, then the
+             new base field will have a parameter and a minimal polynomial;
+             var(2) is the old parameter and it is displayed how the old parameter
+             can be computed from the new one
+EXAMPLE:   example displayPuiseuxExpansion;   shows an example"
+{
+  int j;
+  // if the procedure has to display more than one expansion
+  if (typeof(puiseux[1])=="list")
+  {
+    for (j=1;j<=size(puiseux);j++)
+    {
+      "=============================";
+      string(j)+". Expansion:";
+      "";
+      displayPuiseuxExpansion(puiseux[j],#);
+      "";
+    }
+  }
+  // if the procedure has to display only one expansion
+  else
+  {
+    list variablen;
+    for (j=2;j<=nvars(basering);j++)
+    {
+      variablen[j-1]=string(var(j));
+    }
+    def BASERING=basering;
+    def LIFTRing=puiseux[1];
+    int N=puiseux[2];
+    string LIFTpar=parstr(LIFTRing);
+    string Kstring="Q";
+    setring LIFTRing;
+    "The Puiseux expansion lives in the ring";
+    if ((size(LIFTpar)==0) and (N==1))
+    {
+      Kstring+"[[t]]";
+    }
+    if ((size(LIFTpar)==0) and (N!=1))
+    {
+      Kstring+"[[t^(1/"+string(N)+")]]";
+    }
+    if ((size(LIFTpar)!=0) and (N!=1))
+    {
+      Kstring+"["+LIFTpar+"]/"+string(minpoly)+"[[t^(1/"+string(N)+")]]";
+    }
+    if ((size(LIFTpar)!=0) and (N==1))
+    {
+      Kstring+"["+LIFTpar+"]/"+string(minpoly)+"[[t]]";
+    }
+    "";
+    "The expansion has the form:";
+    // treat the case LIFT==0 separately
+    if (size(LIFT)==0)
+    {
+      variablen[1]+"=0";
+    }
+    else
+    {
+      for (j=1;j<=size(LIFT);j++)
+      {
+        if (ncols(LIFT)==size(variablen))
+        {
+          variablen[j]+"="+displaypoly(LIFT[j],N,0,1);
+        }
+        else
+        {
+          "var("+string(j)+")="+displaypoly(LIFT[j],N,0,1);
+        }
+      }
+    }
+    if (size(#)>0)
+    {
+      if (#[1]=="subst")
+      {
+        setring BASERING;
+        "";
+        "Substituting the expansion into the polynomial gives:";
+        "f="+puiseux[3];
+      }
+    }
+  }
+}
+example
+{
+   "EXAMPLE:";
+   echo=2;
+   ring r=0,(x,y),ds;
+   poly f=x2-y4+x5y7;
+   displayPuiseuxExpansion(puiseuxExpansion(f,3));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Procedures concerned with drawing a tropical curve or a Newton subdivision
+///////////////////////////////////////////////////////////////////////////////
+
+proc tropicalCurve (def tp,list #)
+"USAGE:      tropicalCurve(tp[,#]); tp list, # optional list
+ASSUME:      tp is list of linear polynomials of the form ax+by+c
+             with integers a, b and a rational number c representing
+             a tropical Laurent polynomial defining a tropical plane curve;
+             alternatively tp can be a polynomial in Q(t)[x,y] defining a
+             tropical plane curve via the valuation map;
+             the basering must have a global monomial ordering,
+             two variables and up to one parameter!
+RETURN:      list, each entry i=1,...,size(l)-1 corresponds to a vertex
+                   in the tropical plane curve defined by tp
+                   l[i][1] = x-coordinate of the ith vertex
+                   l[i][2] = y-coordinate of the ith vertex
+                   l[i][3] = intmat, if j is an entry in the first row
+                             of intmat then the ith vertex of
+                             the tropical curve is connected to the
+                             jth vertex with multiplicity given
+                             by the corresponding entry in the second row
+                   l[i][4] = list of lists, the first entry of a list is
+                             a primitive integer vector defining the direction
+                             of an unbounded edge emerging from the ith vertex
+                             of the graph, the corresponding second entry in
+                             the list is the multiplicity of the unbounded edge
+                   l[i][5] = a polynomial whose monomials mark the vertices
+                             in the Newton polygon corresponding to the entries
+                             in tp which take the common minimum at the ith
+                             vertex -- if some coefficient a or b of the
+                             linear polynomials in the input was negative,
+                             then each monomial has to be shifted by
+                             the values in l[size(l)][3]
+                   l[size(l)][1] = list, the entries describe the boundary
+                                         points of the Newton subdivision
+                   l[size(l)][2] = list, the entries are pairs of integer
+                                         vectors defining an interior
+                                         edge of the Newton subdivision
+                   l[size(l)][3] = intvec, the monmials occuring in l[i][5]
+                                           have to be shifted by this vector
+                                           in order to represent marked
+                                           vertices in the Newton polygon
+NOTE:        here the tropical polynomial is supposed to be the MINIMUM
+             of the linear forms in tp, unless the optional input #[1]
+             is the string 'max'
+EXAMPLE:     example tropicalCurve;   shows an example"
+{
+  // introduce necessary variables
+  int i,j,k,l,d;
+  intvec v,w,u;
+  intmat D[2][2];
+  // the basering must have a global monomial ordering
+  if (1>var(1))
+  {
+    ERROR("The basering should have a global monomial ordering, e.g. ring r=(0,t),(x,y),dp;");
+  }
+  // if you insert a single polynomial instead of an ideal
+  // representing a tropicalised polynomial,
+  // then we compute first the tropicalisation of this polynomial
+  // -- this feature is not documented in the above help string
+  if (typeof(tp)=="poly")
+  {
+    // exclude the case that the basering has not precisely
+    // one parameter and two indeterminates
+    if ((npars(basering)!=1) or (nvars(basering)!=2))
+    {
+      ERROR("The basering should have precisely one parameter and two indeterminates!");
+    }
+    poly f=tp;
+    kill tp;
+    list tp=tropicalise(f,#);  // the tropicalisation of f
+  }
+  // Exclude the case that the basering has more than 2 indeterminates
+  if (nvars(basering) != 2)
+  {
+    ERROR("The basering should have precisely two indeterminates!");
+  }
+  // -1) Exclude the pathological case that the defining
+  //     tropical polynomial has only one term,
+  //     so that the tropical variety is not defined.
+  if (size(tp)==1)
+  {
+    ERROR("A monomial does not define a tropical curve!");
+    intmat M[2][1]=0,0;
+    return(list(list(0,0,M,list(),detropicalise(tp[1])),list(list(leadexp(detropicalise(tp[1]))),list())));
+  }
+  // 0) If the input was a list of linear polynomials,
+  //    then some coefficient of x or y can be negative,
+  //    i.e. the input corresponds to the tropical curve
+  //    of a Laurent polynomial. In that case we should
+  //    add some ax+by, so that all coefficients are positive.
+  //    This does not change the tropical curve.
+  //    however, we have to save (a,b), since the Newton
+  //    polygone has to be shifted by (-a,-b).
+  poly aa,bb; // koeffizienten
+  for (i=1;i<=size(tp);i++)
+  {
+    if (koeffizienten(tp[i],1)<aa)
+    {
+      aa=koeffizienten(tp[i],1);
+    }
+    if (koeffizienten(tp[i],2)<bb)
+    {
+      bb=koeffizienten(tp[i],2);
+    }
+  }
+  if ((aa!=0) or (bb!=0))
+  {
+    for (i=1;i<=size(tp);i++)
+    {
+      tp[i]=tp[i]-aa*var(1)-bb*var(2);
+    }
+  }
+  // 1) compute the vertices of the tropical curve
+  //    defined by tp and the Newton subdivision
+  list vtp=verticesTropicalCurve(tp,#);
+  //    if vtp is empty, then the Newton polygone is just
+  //    a line segment and constitutes a bunch of lines
+  //    which can be computed by bunchOfLines
+  if (size(vtp)==0)
+  {
+    return(bunchOfLines(tp));
+  }
+  // 2) store all vertices belonging to the ith part of the
+  //    Newton subdivision in the list vtp[i] as 4th entry,
+  //    and store those, which are not corners of the ith subdivision polygon
+  //    in vtp[i][6]
+  poly nwt;
+  list boundaryNSD;  // stores the boundary of a Newton subdivision
+  intmat zwsp[2][1]; // used for intermediate storage
+  for (i=1;i<=size(vtp);i++)
+  {
+    k=1;
+    nwt=vtp[i][3]; // the polynomial representing the
+    // ith part of the Newton subdivision
+    // store the vertices of the ith part of the
+    // Newton subdivision in the list newton
+    list newton;
+    while (nwt!=0)
+    {
+      newton[k]=leadexp(nwt);
+      nwt=nwt-lead(nwt);
+      k++;
+    }
+    boundaryNSD=findOrientedBoundary(newton);// a list of the vertices
+                                             // of the Newton subdivision
+                                             // as integer vectors (only those
+                                             // on the boundary, and oriented
+                                             // clockwise)
+    vtp[i][4]=boundaryNSD[1];
+    vtp[i][5]=boundaryNSD[2];
+    vtp[i][6]=zwsp; // the entries of the first row will denote to which
+                    // vertex the ith one is connected
+                    // and the entries of the second row will denote
+                    //with which multiplicity
+    kill newton; // we kill the superflous list
+  }
+  // 3) Next we build for each part of the Newton
+  //    subdivision the list of all pairs of vertices on the
+  //    boundary, which are involved, including those which are not corners
+  list pairs,pair;
+  for (i=1;i<=size(vtp);i++)
+  {
+    list ipairs;
+    for (j=1;j<=size(vtp[i][4])-1;j++)
+    {
+      pair=vtp[i][4][j],vtp[i][4][j+1];
+      ipairs[j]=pair;
+    }
+    pair=vtp[i][4][size(vtp[i][4])],vtp[i][4][1];
+    ipairs[size(vtp[i][4])]=pair;
+    pairs[i]=ipairs;
+    kill ipairs;
+  }
+  // 4) Check for all pairs of verticies in the Newton diagram if they
+  //    occur in two different parts of the Newton subdivision
+  int deleted; // if a pair occurs in two NSD, it can be removed
+               // from both - deleted is then set to 1
+  list inneredges; // contains the list of all pairs contained in two NSD
+                   // - these are inner the edges of NSD
+  int ggt;
+  d=1;  // counts the inner edges
+  for (i=1;i<=size(pairs)-1;i++)
+  {
+    for (j=i+1;j<=size(pairs);j++)
+    {
+      for (k=size(pairs[i]);k>=1;k--)
+      {
+        deleted=0;
+        for (l=size(pairs[j]);l>=1 and deleted==0;l--)
+        {
+          if (((pairs[i][k][1]==pairs[j][l][1]) and (pairs[i][k][2]==pairs[j][l][2])) or ((pairs[i][k][1]==pairs[j][l][2]) and (pairs[i][k][2]==pairs[j][l][1])))
+          {
+            inneredges[d]=pairs[i][k];  // new inner edge is saved in inneredges
+            d++;
+            ggt=abs(gcd(pairs[i][k][1][1]-pairs[i][k][2][1],pairs[i][k][1][2]-pairs[i][k][2][2]));
+            zwsp=j,ggt;   // and it is recorded that the ith and jth
+                          // vertex should be connected with mult ggt
+            vtp[i][6]=intmatconcat(vtp[i][6],zwsp);
+            zwsp=i,ggt;
+            vtp[j][6]=intmatconcat(vtp[j][6],zwsp);
+            pairs[i]=delete(pairs[i],k);  // finally the pair is deleted
+                                          // from both sets of pairs
+            pairs[j]=delete(pairs[j],l);
+            deleted=1;
+          }
+        }
+      }
+    }
+  }
+  // 5) The entries in vtp[i][6] are ordered, multiple entries are removed,
+  //    and the redundant zero is removed as well
+  for (i=1;i<=size(vtp);i++)
+  {
+    vtp[i][6]=clearintmat(vtp[i][6]);
+  }
+  // 6) Declare the orientation of the boundary of the Newton polytope.
+  // 6.1) Collect all potential vertices of the boundary of the Newton polytope.
+  list vertices; // all vertices in the set of pairs
+  k=1;
+  for (i=1;i<=size(pairs);i++)
+  {
+    for (j=1;j<=size(pairs[i]);j++)
+    {
+      vertices[k]=pairs[i][j][1];
+      k++;
+      vertices[k]=pairs[i][j][2];
+      k++;
+    }
+  }
+  // 6.2) delete multiple vertices
+  for (i=size(vertices)-1;i>=1;i--)
+  {
+    for (j=size(vertices);j>=i+1;j--)
+    {
+      if (vertices[i]==vertices[j])
+      {
+        vertices=delete(vertices,j);
+      }
+    }
+  }
+  // 6.3) Order the vertices such that passing from one to the next we
+  //      travel along the boundary of the Newton polytope clock wise.
+  boundaryNSD=findOrientedBoundary(vertices);
+  list orderedvertices=boundaryNSD[1];
+  // 7) Find the unbounded edges emerging from a vertex in the tropical curve.
+  //    For this we check the remaining pairs for the ith NSD.
+  //    Each pair is ordered according
+  //    to the order in which the vertices occur in orderedvertices.
+  //    The direction of the
+  //    unbounded edge is then the outward pointing primitive normal
+  //    vector to the vector
+  //    pointing from the first vertex in a pair to the second one.
+  intvec normalvector;  // stores the outward pointing normal vector
+  intvec zwspp; // used for intermediate storage
+  int zw,pos1,pos2; // stores the gcd of entries of the
+                    // non-normalised normal vector, etc.
+  int gestorben; // tests if unbounded edges are multiple
+  for (i=1;i<=size(pairs);i++)
+  {
+    list ubedges; // stores the unbounded edges
+    k=1; // counts the unbounded edges
+    for (j=1;j<=size(pairs[i]);j++)
+    {
+      // computes the position of the vertices in the
+      pos1=positionInList(orderedvertices,pairs[i][j][1]);
+      // pair in the list orderedvertices
+      pos2=positionInList(orderedvertices,pairs[i][j][2]);
+      if (((pos1>pos2) and !((pos1==size(orderedvertices)) and (pos2==1))) or ((pos2==size(orderedvertices)) and (pos1==1)))  // reorders them if necessary
+      {
+        zwspp=pairs[i][j][1];
+        pairs[i][j][1]=pairs[i][j][2];
+        pairs[i][j][2]=zwspp;
+      }
+      // the vector pointing from vertex 1 in the pair to vertex2
+      normalvector=pairs[i][j][2]-pairs[i][j][1];
+      ggt=gcd(normalvector[1],normalvector[2]);   // the gcd of the entries
+      zw=normalvector[2];    // create the outward pointing normal vector
+      normalvector[2]=-normalvector[1] div ggt;
+      normalvector[1]=zw div ggt;
+      if (size(#)==0) // we are computing w.r.t. minimum
+      {
+        ubedges[k]=list(normalvector,ggt); // store outward pointing normal vec.
+      }
+      else // we are computing w.r.t. maximum
+      {
+        ubedges[k]=list(-normalvector,ggt); //store outward pointing normal vec.
+      }
+      k++;
+    }
+    // remove multiple unbounded edges
+    for (j=size(ubedges);j>=1;j--)
+    {
+      gestorben=0;
+      for(k=1;(k<=j-1) and (gestorben==0);k++)
+      {
+        if (ubedges[k][1]==ubedges[j][1])
+        {
+          ubedges[k][2]=ubedges[k][2]+ubedges[j][2]; // add the multiplicities
+          ubedges=delete(ubedges,j);
+          gestorben=1;
+        }
+      }
+    }
+    vtp[i][7]=ubedges; // store the unbounded edges in vtp[i][7]
+    kill ubedges;
+  }
+  // 8) Store the computed information for the ith part
+  //    of the NSD in the list graph[i].
+  list graph,gr;
+  for (i=1;i<=size(vtp);i++)
+  {
+    // the first coordinate of the ith vertex of the tropical curve
+    gr[1]=vtp[i][1];
+    // the second coordinate of the ith vertex of the tropical curve
+    gr[2]=vtp[i][2];
+    // to which vertices is the ith vertex of the tropical curve connected
+    gr[3]=vtp[i][6];
+    // the directions unbounded edges emerging from the ith
+    // vertex of the trop. curve
+    gr[4]=vtp[i][7];
+    // the vertices of the boundary of the ith part of the NSD
+    gr[5]=vtp[i][3];
+    graph[i]=gr;
+  }
+  // 9) Shift the Newton subdivision by (aa,bb) if necessary
+  intvec shiftvector=intvec(int(aa),int(bb));
+  if ((aa!=0) or (bb!=0))
+  {
+    for (i=1;i<=size(boundaryNSD[2]);i++)
+    {
+      boundaryNSD[2][i]=boundaryNSD[2][i]+shiftvector;
+    }
+    for (i=1;i<=size(inneredges);i++)
+    {
+      for (j=1;j<=size(inneredges[i]);j++)
+      {
+        inneredges[i][j]=inneredges[i][j]+shiftvector;
+      }
+    }
+  }
+  // 10) Finally store the boundary vertices and
+  //     the inner edges as last entry in the list graph.
+  //     This represents the NSD.
+  graph[size(vtp)+1]=list(boundaryNSD[2],inneredges,shiftvector);
+  return(graph);
+}
+example
+{
+   "EXAMPLE:";
+   echo=2;
+   ring r=(0,t),(x,y),dp;
+   poly f=t*(x7+y7+1)+1/t*(x4+y4+x2+y2+x3y+xy3)+1/t7*x2y2;
+   list graph=tropicalCurve(f);
+// the tropical curve has size(graph)-1 vertices
+   size(graph)-1;
+// the coordinates of the first vertex are graph[1][1],graph[1][2];
+   graph[1][1],graph[1][2];
+// the first vertex is connected to the vertices
+//     graph[1][3][1,1..ncols(graph[1][3])]
+   intmat M=graph[1][3];
+   M[1,1..ncols(graph[1][3])];
+// the weights of the edges to these vertices are
+//     graph[1][3][2,1..ncols(graph[1][3])]
+   M[2,1..ncols(graph[1][3])];
+// from the first vertex emerge size(graph[1][4]) unbounded edges
+   size(graph[1][4]);
+// the primitive integral direction vector of the first unbounded edge
+//     of the first vertex
+   graph[1][4][1][1];
+// the weight of the first unbounded edge of the first vertex
+   graph[1][4][1][2];
+// the monomials which are part of the Newton subdivision of the first vertex
+   graph[1][5];
+// connecting the points in graph[size(graph)][1] we get
+//     the boundary of the Newton polytope
+   graph[size(graph)][1];
+// an entry in graph[size(graph)][2] is a pair of points
+//     in the Newton polytope bounding an inner edge
+   graph[size(graph)][2][1];
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+proc drawTropicalCurve (def f,list #)
+"USAGE:      drawTropicalCurve(f[,#]); f poly or list, # optional list
+ASSUME:      f is list of linear polynomials of the form ax+by+c with
+             integers a, b and a rational number c representing a tropical
+             Laurent polynomial defining a tropical plane curve;
+             alternatively f can be a polynomial in Q(t)[x,y] defining
+             a tropical plane curve via the valuation map;
+             the basering must have a global monomial ordering, two
+             variables and up to one parameter!
+RETURN:      NONE
+NOTE:        - the procedure creates the files /tmp/tropicalcurveNUMBER.tex and
+               /tmp/tropicalcurveNUMBER.ps, where NUMBER is a random four
+               digit integer;
+               moreover it displays the tropical curve via kghostview;
+               if you wish to remove all these files from /tmp,
+               call the procedure cleanTmp
+@*           - edges with multiplicity greater than one carry this multiplicity
+@*           - if # is empty, then the tropical curve is computed w.r.t. minimum,
+               if #[1] is the string 'max', then it is computed w.r.t. maximum
+@*           - if the last optional argument is 'onlytexfile' then only the
+               latex file is produced; this option should be used if kghostview
+               is not installed on your system
+@*           - note that lattice points in the Newton subdivision which are
+               black correspond to markings of the marked subdivision,
+               while lattice points in grey are not marked
+EXAMPLE:     example drawTropicalCurve  shows an example"
+{
+  // check if the option "onlytexfile" is set, then only a tex file is produced
+  if (size(#)!=0)
+  {
+    if (#[size(#)]=="onlytexfile")
+    {
+      int onlytexfile;
+      #=delete(#,size(#));
+    }
+  }
+  // start the actual computations
+  string texf;
+  int j;
+  if (typeof(f)=="poly")
+  {
+    // exclude the case that the basering has not precisely
+    // one parameter and two indeterminates
+    if ((npars(basering)!=1) or (nvars(basering)!=2))
+    {
+      ERROR("The basering should have precisely one parameter and two indeterminates!");
+    }
+    // if the characteristic of the base field is not 0 then replace the base field
+    // by a field of characteristic zero
+    if (char(basering)!=0)
+    {
+      string polynomstring=string(f);
+      execute("ring drawring=(0,"+parstr(basering)+"),("+varstr(basering)+"),dp;");
+      execute("poly f="+polynomstring+";");
+    }
+    texf=texPolynomial(f); // write the polynomial over Q(t)
+    list graph=tropicalCurve(tropicalise(f,#),#); // graph of tropicalis. of f
+  }
+  if (typeof(f)=="list")
+  {
+    if (typeof(f[1])=="list")
+    {
+      texf="\\mbox{\\tt The defining equation was not handed over!}";
+      list graph=f;
+    }
+    else
+    { // write the tropical polynomial defined by f
+      if (size(#)==0)
+      {
+        texf="\\min\\{";
+      }
+      else
+      {
+        texf="\\max\\{";
+      }
+      for (j=1;j<=size(f);j++)
+      {
+        texf=texf+texPolynomial(f[j]);
+        if (j<size(f))
+        {
+          texf=texf+", ";
+        }
+        else
+        {
+          texf=texf+"\\}";
+        }
+      }
+      list graph=tropicalCurve(f,#); // the graph of the tropical polynomial f
+    }
+  }
+  // produce the tex file
+  string vertices;
+  for (j=1;j<=size(graph)-2;j++)
+  {
+    vertices=vertices+"("+string(graph[j][1])+","+string(graph[j][2])+"),\\;\\; ";
+  }
+  vertices=vertices+"("+string(graph[j][1])+","+string(graph[j][2])+")";
+  string TEXBILD="\\documentclass[12pt]{amsart}
+\\usepackage{texdraw}
+\\setlength{\\topmargin}{30mm}
+\\addtolength{\\topmargin}{-1in}
+\\addtolength{\\topmargin}{-\\headsep}
+\\addtolength{\\topmargin}{-\\headheight}
+\\addtolength{\\topmargin}{-\\topskip}
+\\setlength{\\textheight}{267mm}
+\\addtolength{\\textheight}{\\topskip}
+\\addtolength{\\textheight}{-\\footskip}
+\\addtolength{\\textheight}{-30pt}
+\\setlength{\\oddsidemargin}{-1in}
+\\addtolength{\\oddsidemargin}{20mm}
+\\setlength{\\evensidemargin}{\\oddsidemargin}
+\\setlength{\\textwidth}{170mm}
+
+\\begin{document}
+   \\parindent0cm
+   \\begin{center}
+      \\large\\bf The Tropicalisation of
+
+      \\bigskip
+
+      \\begin{math}
+          f="+texf+"
+      \\end{math}
+   \\end{center}
+   \\vspace*{0.5cm}
+   The vertices of the tropical curve are:
+   \\begin{center}
+      \\begin{math}
+         "+vertices+"
+      \\end{math}
+   \\end{center}
+   \\vspace*{0.5cm}
+
+   \\begin{center}
+"+texDrawBasic(texDrawTropical(graph,#))+  // write the tropical curve
+   "\\end{center}
+
+   \\vspace*{0.5cm}
+   The Newton subdivision of the tropical curve is:
+   \\vspace*{0.5cm}
+
+   \\begin{center}
+       "+texDrawNewtonSubdivision(graph,#)+"
+   \\end{center}
+\\end{document}";
+  if(defined(onlytexfile)==0)
+  {
+    int rdnum=random(1000,9999);
+    write(":w /tmp/tropicalcurve"+string(rdnum)+".tex",TEXBILD);
+    system("sh","cd /tmp; latex /tmp/tropicalcurve"+string(rdnum)+".tex; dvips /tmp/tropicalcurve"+string(rdnum)+".dvi -o; /bin/rm tropicalcurve"+string(rdnum)+".log;  /bin/rm tropicalcurve"+string(rdnum)+".aux;  /bin/rm tropicalcurve"+string(rdnum)+".ps?;  /bin/rm tropicalcurve"+string(rdnum)+".dvi; kghostview tropicalcurve"+string(rdnum)+".ps &");
+  }
+  else
+  {
+    return(TEXBILD);
+  }
+}
+example
+{
+   "EXAMPLE:";
+   echo=2;
+   ring r=(0,t),(x,y),dp;
+   poly f=t*(x3+y3+1)+1/t*(x2+y2+x+y+x2y+xy2)+1/t2*xy;
+// the command drawTropicalCurve(f) computes the graph of the tropical curve
+// given by f and displays a post script image, provided you have kghostview
+   drawTropicalCurve(f);
+// we can instead apply the procedure to a tropical polynomial and use "maximum"
+   poly g=1/t3*(x7+y7+1)+t3*(x4+y4+x2+y2+x3y+xy3)+t21*x2y2;
+   list tropical_g=tropicalise(g);
+   tropical_g;
+   drawTropicalCurve(tropical_g,"max");
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+proc drawNewtonSubdivision (def f,list #)
+"USAGE:   drawTropicalCurve(f[,#]); f poly, # optional list
+ASSUME:   f is list of linear polynomials of the form ax+by+c with integers
+          a, b and a rational number c representing a tropical Laurent
+          polynomial defining a tropical plane curve;
+          alternatively f can be a polynomial in Q(t)[x,y] defining a tropical
+          plane curve via the valuation map;
+          the basering must have a global monomial ordering, two variables
+          and up to one parameter!
+RETURN:   NONE
+NOTE:     - the procedure creates the files /tmp/newtonsubdivisionNUMBER.tex,
+            and /tmp/newtonsubdivisionNUMBER.ps, where NUMBER is a random
+            four digit integer;
+            moreover it desplays the tropical curve defined by f via kghostview;
+            if you wish to remove all these files from /tmp, call the procedure
+            cleanTmp;
+@*          if # is empty, then the tropical curve is computed w.r.t. minimum,
+            if #[1] is the string 'max', then it is computed w.r.t. maximum
+@*        - note that lattice points in the Newton subdivision which are black
+            correspond to markings of the marked subdivision, while lattice
+            points in grey are not marked
+EXAMPLE:     example drawNewtonSubdivision;   shows an example"
+{
+  string texf;
+  int j;
+  if (typeof(f)=="poly")
+  {
+    texf=texPolynomial(f); // write the polynomial over Q(t)
+    list graph=tropicalCurve(tropicalise(f,#),#); // graph of tropicalis. of f
+  }
+  else
+  { // write the tropical polynomial defined by f
+    if (size(#)==0)
+    {
+      texf="\\min\\{";
+    }
+    else
+    {
+      texf="\\max\\{";
+    }
+    for (j=1;j<=size(f);j++)
+    {
+      texf=texf+texPolynomial(f[j]);
+      if (j<size(f))
+      {
+        texf=texf+", ";
+      }
+      else
+      {
+        texf=texf+"\\}";
+      }
+    }
+    list graph=tropicalCurve(f,#); // the graph of the tropical polynomial f
+  }
+  string TEXBILD="\\documentclass[12pt]{amsart}
+\\usepackage{texdraw}
+\\begin{document}
+   \\parindent0cm
+   \\begin{center}
+      \\large\\bf The Newtonsubdivison of
+      \\begin{displaymath}
+          f="+texf+"
+      \\end{displaymath}
+   \\end{center}
+   \\vspace*{1cm}
+
+   \\begin{center}
+"+texDrawNewtonSubdivision(graph)+
+"   \\end{center}
+
+\\end{document}";
+  int rdnum=random(1000,9999);
+  write(":w /tmp/newtonsubdivision"+string(rdnum)+".tex",TEXBILD);
+  system("sh","cd /tmp; latex /tmp/newtonsubdivision"+string(rdnum)+".tex; dvips /tmp/newtonsubdivision"+string(rdnum)+".dvi -o; /bin/rm newtonsubdivision"+string(rdnum)+".log;  /bin/rm newtonsubdivision"+string(rdnum)+".aux;  /bin/rm newtonsubdivision"+string(rdnum)+".ps?;  /bin/rm newtonsubdivision"+string(rdnum)+".dvi; kghostview newtonsubdivision"+string(rdnum)+".ps &");
+//  return(TEXBILD);
+}
+example
+{
+   "EXAMPLE:";
+   echo=2;
+   ring r=(0,t),(x,y),dp;
+   poly f=t*(x3+y3+1)+1/t*(x2+y2+x+y+x2y+xy2)+1/t2*xy;
+// the command drawTropicalCurve(f) computes the graph of the tropical curve
+// given by f and displays a post script image, provided you have kghostview
+   drawNewtonSubdivision(f);
+// we can instead apply the procedure to a tropical polynomial
+   poly g=x+y+x2y+xy2+1/t*xy;
+   list tropical_g=tropicalise(g);
+   tropical_g;
+   drawNewtonSubdivision(tropical_g);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Procedures concerned with cubics
+///////////////////////////////////////////////////////////////////////////////
+
+proc tropicalJInvariant (def f,list #)
+"USAGE:      tropicalJInvariant(f[,#]); f poly or list, # optional list
+ASSUME:      f is list of linear polynomials of the form ax+by+c with integers
+             a, b and a rational number c representing a tropical Laurent
+             polynomial defining a tropical plane curve;
+             alternatively f can be a polynomial in Q(t)[x,y] defining a
+             tropical plane curve via the valuation map;
+@*           the basering must have a global monomial ordering, two variables
+             and up to one parameter!
+RETURN:      number, if the graph underlying the tropical curve has precisely
+                     one loop then its weighted lattice length is returned,
+                     otherwise the result will be -1
+NOTE:        - if the tropical curve is elliptic and its embedded graph has
+               precisely one loop, then the weigthed lattice length of
+               the loop is its tropical j-invariant
+@*           - the procedure checks if the embedded graph of the tropical
+               curve has genus one, but it does NOT check if the loop can
+               be resolved, so that the curve is not a proper tropical
+               elliptic curve
+@*           - if the embedded graph of a tropical elliptic curve has more
+               than one loop, then all but one can be resolved, but this is
+               not observed by this procedure, so it will not compute
+               the j-invariant
+@*           - if # is empty, then the tropical curve is computed w.r.t. minimum,
+               if #[1] is the string 'max', then it is computed w.r.t. maximum
+@*           - the tropicalJInvariant of a plane tropical cubic is the
+               'cycle length' of the cubic as introduced in the paper:
+               Eric Katz, Hannah Markwig, Thomas Markwig: The j-invariant
+               of a cubic tropical plane curve.
+EXAMPLE:     example tropicalJInvariant;   shows an example"
+{
+  // 1) compute first the graph of the tropical curve
+  if (typeof(f)=="poly")
+  {
+    list graph=tropicalCurve(f,#);
+  }
+  else
+  {
+    if (typeof(f)=="list")
+    {
+      if (typeof(f[1])=="list")
+      {
+        list graph=f;
+      }
+      else
+      {
+        if (typeof(f[1])=="poly")
+        {
+          list graph=tropicalCurve(f,#);
+        }
+        else
+        {
+          ERROR("This is no valid input.");
+        }
+      }
+    }
+    else
+    {
+      ERROR("This is no valid input.");
+    }
+  }
+  int i,j,k;
+  // 2) compute the genus of the embedded graph of the tropical curve
+  int genus;
+  for (i=1;i<=size(graph)-1;i++) // we count the number of bounded edges
+  {
+    genus=genus+ncols(graph[i][3]);
+  }
+  genus=-genus/2; // we have counted each bounded edge twice
+  genus=genus+size(graph); // the genus is 1-#bounded_edges+#vertices
+  // 3) if the embedded graph has not genus one,
+  //    we cannot compute the j-invariant
+  if(genus!=1)
+  {
+    if (printlevel>=0)
+    {
+      "The embedded graph of the curve has not genus one.";
+    }
+    return(-1);
+  }
+  else
+  {
+    intmat nullmat[2][1];  // used to set
+    // 4) find a vertex which has only one bounded edge,
+    //    if none exists zero is returned,
+    //    otherwise the number of the vertex in the list graph
+    int nonloopvertex=findNonLoopVertex(graph);
+    int dv; //checks if vert. has been found to which nonloopvertex is connected
+    intmat delvert; // takes for a moment graph[i][3] of the vertex
+                    // to which nonloopvertex is connected
+    // 5) delete successively vertices in the graph which
+    //    have only one bounded edge
+    while (nonloopvertex>0)
+    {
+      // find the only vertex to which the nonloopvertex
+      // is connected, when it is found
+      // delete the connection in graph[i][3] and set dv=1
+      dv=0;
+      for (i=1;i<=size(graph)-1 and dv==0;i++)
+      {
+        if (i!=nonloopvertex)
+        {
+          for (j=1;j<=ncols(graph[i][3]) and dv==0;j++)
+          {
+            if(graph[i][3][1,j]==nonloopvertex) // the vertex is found
+            {
+              delvert=graph[i][3];
+              delvert=intmatcoldelete(delvert,j); // delete the connection (note
+                                                  // there must have been two!)
+              dv=1;
+              graph[i][3]=delvert;
+            }
+          }
+        }
+      }
+      graph[nonloopvertex][3]=nullmat; // the only connection of nonloopvertex
+                                       // is killed
+      nonloopvertex=findNonLoopVertex(graph); // find the next vertex
+                                              // which has only one edge
+    }
+    // 6) find the loop and the weights of the edges
+    intvec loop,weights; // encodes the loop and the edges
+    i=1;
+    //    start by finding some vertex which belongs to the loop
+    while (loop==0)
+    {
+      // if graph[i][3] of a vertex in the loop has 2 columns, all others have 1
+      if (ncols(graph[i][3])==1)
+      {
+        i++;
+      }
+      else
+      {
+        loop[1]=i; // a starting vertex is found
+        loop[2]=graph[i][3][1,1]; // it is connected to vertex with this number
+        weights[2]=graph[i][3][2,1]; // and the edge has this weight
+      }
+    }
+    j=graph[i][3][1,1]; // the active vertex of the loop
+    k=2; // counts the vertices in the loop
+    while (j!=i)  // the loop ends with the same vertex with which it starts
+    {
+      // the first row of graph[j][3] has two entries
+      // corresponding to the two vertices
+      // to which the active vertex j is connected;
+      // one is loop[k-1], i.e. the one which
+      // precedes j in the loop; we have to choose the other one
+      if (graph[j][3][1,1]==loop[k-1])
+      {
+        loop[k+1]=graph[j][3][1,2];
+        weights[k+1]=graph[j][3][2,2];
+      }
+      else
+      {
+        loop[k+1]=graph[j][3][1,1];
+        weights[k+1]=graph[j][3][2,1];
+      }
+      j=loop[k+1]; // set loop[k+1] the new active vertex
+      k++;
+    }
+    // 7) compute for each edge in the loop the lattice length
+    poly xcomp,ycomp; // the x- and y-components of the vectors
+                      // connecting two vertices of the loop
+    number nenner;    // the product of the denominators of
+                      // the x- and y-components
+    number jinvariant;  // the j-invariant
+    int eins,zwei,ggt;
+    for (i=1;i<=size(loop)-1;i++) // compute the lattice length for each edge
+    {
+      xcomp=graph[loop[i]][1]-graph[loop[i+1]][1];
+      ycomp=graph[loop[i]][2]-graph[loop[i+1]][2];
+      nenner=denominator(leadcoef(xcomp))*denominator(leadcoef(ycomp));
+      execute("eins="+string(numerator(leadcoef(nenner*xcomp)))+";");
+      execute("zwei="+string(numerator(leadcoef(nenner*ycomp)))+";");
+      ggt=gcd(eins,zwei); // the lattice length is the "gcd"
+                          // of the x-component and the y-component
+      jinvariant=jinvariant+ggt/(nenner*weights[i+1]); // divided by the
+                                                       // weight of the edge
+    }
+    return(jinvariant);
+  }
+}
+example
+{
+   "EXAMPLE:";
+   echo=2;
+   ring r=(0,t),(x,y),dp;
+// tropcialJInvariant computes the tropical j-invariant of an elliptic curve
+   tropicalJInvariant(t*(x3+y3+1)+1/t*(x2+y2+x+y+x2y+xy2)+1/t2*xy);
+// the Newton polygone need not be the standard simplex
+   tropicalJInvariant(x+y+x2y+xy2+1/t*xy);
+// the curve can have arbitrary degree
+   tropicalJInvariant(t*(x7+y7+1)+1/t*(x4+y4+x2+y2+x3y+xy3)+1/t7*x2y2);
+// the procedure does not realise, if the embedded graph of the tropical
+//     curve has a loop that can be resolved
+   tropicalJInvariant(1+x+y+xy+tx2y+txy2);
+// but it does realise, if the curve has no loop at all ...
+   tropicalJInvariant(x+y+1);
+// or if the embedded graph has more than one loop - even if only one
+//     cannot be resolved
+   tropicalJInvariant(1+x+y+xy+tx2y+txy2+t3x5+t3y5+tx2y2+t2xy4+t2yx4);
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+proc weierstrassForm (poly f,list #)
+"USAGE:      weierstrassForm(wf[,#]); wf poly, # list
+ASSUME:      wf is a a polynomial whose Newton polygon has precisely one
+             interior lattice point, so that it defines an elliptic curve
+             on the toric surface corresponding to the Newton polygon
+RETURN:      poly, the Weierstrass normal form of the polynomial
+NOTE:        - the algorithm for the coefficients of the Weierstrass form is due
+               to Fernando Rodriguez Villegas, villegas at math.utexas.edu
+@*           - the characteristic of the base field should not be 2 or 3
+@*           - if an additional argument # is given, a simplified Weierstrass
+               form is computed
+EXAMPLE:     example weierstrassForm;   shows an example"
+{
+  // Check first if the Newton polygon has precisely one interior point
+  // - compute the Newton polygon
+  list polygon=newtonPolytopeLP(f);
+  // - find the vertices of the Newton cycle and order it clockwise
+  list pg=findOrientedBoundary(polygon)[2];
+  // - check if there is precisely one interior point in the Newton polygon
+  if (picksFormula(pg)[3]!=1)
+  {
+    ERROR("The Newton polygon of the input has NOT precisely one interior point!");
+  }
+  // Compute the Normal form of the polygon.
+  list nf=ellipticNF(polygon);
+  // Transform f by the unimodular affine coordinate transformation
+  poly tf=coordinatechange(f,nf[2],nf[3]);
+  // Check if the Newton polygon is of type 4x2, 2x2 or a cubic
+  poly a,b=flatten(coeffs(tf,ideal(var(1)^4,var(1)^2*var(2)^2)));
+  // if it is of type 4x2
+  if (a!=0)
+  {
+    return(weierstrassFormOfA4x2Curve(tf));
+  }
+  // if it is of type 2x2
+  if (b!=0)
+  {
+    return(weierstrassFormOfA2x2Curve(tf));
+  }
+  // else it is a cubic
+  return(weierstrassFormOfACubic(tf,#));
+}
+example
+{
+   "EXAMPLE:";
+   echo=2;
+   ring r=(0,t),(x,y),lp;
+// f is already in Weierstrass form
+   poly f=y2+yx+3y-x3-2x2-4x-6;
+   weierstrassForm(f);
+// g is not, but wg is
+   poly g=x+y+x2y+xy2+1/t*xy;
+   poly wg=weierstrassForm(g);
+   wg;
+// but it is not yet simple, since it still has an xy-term, unlike swg
+   poly swg=weierstrassForm(g,1);
+   swg;
+// the j-invariants of all three polynomials coincide
+   jInvariant(g);
+   jInvariant(wg);
+   jInvariant(swg);
+// the following curve is elliptic as well
+   poly h=x22y11+x19y10+x17y9+x16y9+x12y7+x9y6+x7y5+x2y3;
+// its Weierstrass form is
+   weierstrassForm(h);
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+proc jInvariant (poly f,list #)
+"USAGE:      jInvariant(f[,#]); f poly, # list
+ASSUME:      - f is a a polynomial whose Newton polygon has precisely one
+               interior lattice point, so that it defines an elliptic curve
+               on the toric surface corresponding to the Newton polygon
+@*           - it the optional argument # is present the base field should be
+               Q(t) and the optional argument should be one of the following
+               strings:
+@*             'ord'   : then the return value is of type integer,
+                         namely the order of the j-invariant
+@*             'split' : then the return value is a list of two polynomials,
+                         such that the quotient of these two is the j-invariant
+RETURN:      poly, the j-invariant of the elliptic curve defined by poly
+NOTE:        the characteristic of the base field should not be 2 or 3,
+             unless the input is a plane cubic
+EXAMPLE:     example jInvariant;   shows an example"
+{
+  // compute first the Weierstrass form of the cubic and then the j-invariant
+  if (size(#)==0)
+  {
+    return(jInvariantOfACubic(weierstrassForm(f),#));
+  }
+  else
+  {
+    if (#[1]=="split")
+    {
+      return(jInvariantOfAPuiseuxCubic(weierstrassForm(f)));
+    }
+    else
+    {
+      return(jInvariantOfAPuiseuxCubic(weierstrassForm(f),"ord"));
+    }
+  }
+}
+example
+{
+   "EXAMPLE:";
+   echo=2;
+   ring r=(0,t),(x,y),dp;
+// jInvariant computes the j-invariant of a cubic
+   jInvariant(x+y+x2y+y3+1/t*xy);
+// if the ground field has one parameter t, then we can instead
+//    compute the order of the j-invariant
+   jInvariant(x+y+x2y+y3+1/t*xy,"ord");
+// one can compare the order of the j-invariant to the tropical j-invariant
+   tropicalJInvariant(x+y+x2y+y3+1/t*xy);
+// the following curve is elliptic as well
+   poly h=x22y11+x19y10+x17y9+x16y9+x12y7+x9y6+x7y5+x2y3+x14y8;
+// its j-invariant is
+   jInvariant(h);
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+/// Procedures concerned with conics
+///////////////////////////////////////////////////////////////////////////////
+
+proc conicWithTangents (list points,list #)
+"USAGE:      conicWithTangents(points[,#]); points list, # optional list
+ASSUME:      points is a list of five points in the plane over K(t)
+RETURN:      list, l[1] = the list points of the five given points
+@*                 l[2] = the conic f passing through the five points
+@*                 l[3] = list of equations of tangents to f in the given points
+@*                 l[4] = ideal, tropicalisation of f (i.e. list of linear forms)
+@*                 l[5] = a list of the tropicalisation of the tangents
+@*                 l[6] = a list containing the vertices of the tropical conic f
+@*                 l[7] = a list containing lists with vertices of the tangents
+@*                 l[8] = a string which contains the latex-code to draw the
+                          tropical conic and its tropicalised tangents
+@*                 l[9] = if # is non-empty, this is the same data for the dual
+                          conic and the points dual to the computed tangents
+NOTE:        the points must be generic, i.e. no three on a line
+EXAMPLE:     example conicWithTangents;   shows an example"
+{
+  int i;
+  // Compute the tropical coordinates of the given points - part 1
+  list pointdenom,pointnum;
+  poly pp1,pp2;
+  for (i=1;i<=size(points);i++)
+  {
+    pp1=denominator(leadcoef(points[i][1]));
+    pp2=denominator(leadcoef(points[i][2]));
+    pointdenom[i]=list(pp1,pp2);
+    pp1=numerator(leadcoef(points[i][1]));
+    pp2=numerator(leadcoef(points[i][2]));
+    pointnum[i]=list(pp1,pp2);
+  }
+  // compute the equation of the conic
+  def BASERING=basering;
+  ring LINRING=(0,t),(x,y,a(1..6)),lp;
+  list points=imap(BASERING,points);
+  ideal I; // the ideal will contain the linear equations given by the conic
+           // and the points
+  for (i=1;i<=5;i++)
+  {
+    I=I,substitute(a(1)*x2+a(2)*xy+a(3)*y2+a(4)*x+a(5)*y+a(6),x,points[i][1],y,points[i][2]);
+  }
+  I=std(I);
+  list COEFFICIENTS;
+  ideal DENOMINATORS;
+  for (i=1;i<=6;i++)
+  {
+    COEFFICIENTS[i]=leadcoef(reduce(a(i),I));
+    DENOMINATORS[i]=denominator(leadcoef(COEFFICIENTS[i]));
+  }
+  // compute the common denominator of the coefficients
+  ring TRING=0,t,dp;
+  ideal DENOMINATORS=imap(LINRING,DENOMINATORS);
+  poly p=lcm(DENOMINATORS);
+  // compute the tropical coordinates of the points - part 2
+  ring tRING=0,t,ls;
+  list pointdenom=imap(BASERING,pointdenom);
+  list pointnum=imap(BASERING,pointnum);
+  intvec pointcoordinates;
+  for (i=1;i<=size(pointdenom);i++)
+  {
+    pointcoordinates[2*i-1]=ord(pointnum[i][1])-ord(pointdenom[i][1]);
+    pointcoordinates[2*i]=ord(pointnum[i][2])-ord(pointdenom[i][2]);
+  }
+  // multiply the coefficients of the conic by the common denominator
+  setring LINRING;
+  poly p=imap(TRING,p);
+  for (i=1;i<=6;i++)
+  {
+    COEFFICIENTS[i]=COEFFICIENTS[i]*p;
+  }
+  // Compute the tangents to the conic in the given points
+  // and tropicalise the conic and the tangents
+  setring BASERING;
+  list CO=imap(LINRING,COEFFICIENTS);
+  poly f=CO[1]*x2+CO[2]*xy+CO[3]*y2+CO[4]*x+CO[5]*y+CO[6];
+  poly fx=diff(f,x);
+  poly fy=diff(f,y);
+  list tangents;
+  list tropicaltangents;
+  for (i=1;i<=5;i++)
+  {
+    tangents[i]=substitute(fx,x,points[i][1],y,points[i][2])*x+substitute(fy,x,points[i][1],y,points[i][2])*y;
+    tangents[i]=tangents[i]-substitute(tangents[i],x,points[i][1],y,points[i][2]);
+    tropicaltangents[i]=tropicalise(tangents[i]);
+  }
+  list tropicalf=tropicalise(f);
+  // compute the vertices of the tropcial conic and of the tangents
+  list graphf=tropicalCurve(tropicalf);
+  list eckpunktef;
+  for (i=1;i<=size(graphf)-1;i++)
+  {
+    eckpunktef[i]=list(graphf[i][1],graphf[i][2]);
+  }
+  list eckpunktetangents;
+  for (i=1;i<=size(tropicaltangents);i++)
+  {
+    eckpunktetangents[i]=verticesTropicalCurve(tropicaltangents[i],0);
+  }
+  // find the minimal and maximal coordinates of vertices
+  poly minx,miny,maxx,maxy=graphf[1][1],graphf[1][2],graphf[1][1],graphf[1][2];
+  for (i=2;i<=size(graphf)-1;i++)
+  {
+    minx=minOfPolys(list(minx,graphf[i][1]));
+    miny=minOfPolys(list(miny,graphf[i][2]));
+    maxx=-minOfPolys(list(-maxx,-graphf[i][1]));
+    maxy=-minOfPolys(list(-maxy,-graphf[i][2]));
+  }
+  // find the scale factor for the texdraw image
+  poly maxdiffx,maxdiffy;
+  maxdiffx=maxx-minx;
+  maxdiffy=maxy-miny;
+  if (maxdiffx==0)
+  {
+    maxdiffx=1;
+  }
+  if (maxdiffy==0)
+  {
+    maxdiffy=1;
+  }
+  poly scalefactor=minOfPolys(list(12/leadcoef(maxdiffx),16/leadcoef(maxdiffy)))/4;
+  // Produce a Latex-Image of the Conic with each of its Tangents
+  string zusatzinfo;
+  string TEXBILD="\\documentclass[12pt]{amsart}
+\\usepackage{texdraw}
+\\begin{document}
+   \\parindent0cm
+   \\begin{center}
+      \\large\\bf A Tropical Conic through 5 Points and Tangents
+   \\end{center}
+
+   We consider the concic through the following five points:
+   \\begin{displaymath}
+";
+  string texf=texDrawTropical(graphf,list("",scalefactor));
+  for (i=1;i<=size(points);i++)
+  {
+    TEXBILD=TEXBILD+"p_"+string(i)+"=("+texNumber(points[i][1])+","+texNumber(points[i][2])+"),\\;\\;\\;";
+  }
+  TEXBILD=TEXBILD+"
+   \\end{displaymath}";
+  for (i=1;i<=size(points);i++)
+  {
+    zusatzinfo="
+    \\move ("+decimal(pointcoordinates[2*i-1])+" "+decimal(pointcoordinates[2*i])+")
+    \\fcir f:0.5 r:0.25
+    \\rmove (0.4 0.4)
+    \\htext{$p_"+string(i)+"$=("+string(pointcoordinates[2*i-1])+","+string(pointcoordinates[2*i])+")}
+    ";
+    TEXBILD=TEXBILD+"
+   Here we draw the conic and the tangent  through point $p_"+string(i)+"$:
+
+   \\vspace*{1cm}
+
+   \\begin{center}
+   "+texDrawBasic(list(texf,zusatzinfo,texDrawTropical(tropicalCurve(tropicaltangents[i]),list("",scalefactor,"       \\setgray 0.8 \\linewd 0.1 \\lpatt (0.1 0.4)"))))+
+   "\\end{center}";
+    if (i<size(points))
+    {
+      TEXBILD=TEXBILD+"
+
+   \\newpage
+
+   ";
+    }
+  }
+  TEXBILD=TEXBILD+"
+
+\\end{document}";
+  setring BASERING;
+  // If # non-empty, compute the dual conic and the tangents
+  // through the dual points
+  // corresponding to the tangents of the given conic.
+  if (size(#)>0)
+  {
+    list dualpoints;
+    for (i=1;i<=size(points);i++)
+    {
+      dualpoints[i]=list(leadcoef(tangents[i])/substitute(tangents[i],x,0,y,0),leadcoef(tangents[i]-lead(tangents[i]))/substitute(tangents[i],x,0,y,0));
+    }
+    list dualimage=conicWithTangents(dualpoints);
+    return(list(points,f,tangents,tropicalf,tropicaltangents,eckpunktef,eckpunktetangents,TEXBILD,dualimage));
+  }
+  else
+  {
+    return(list(points,f,tangents,tropicalf,tropicaltangents,eckpunktef,eckpunktetangents,TEXBILD));
+  }
+}
+example
+{
+   "EXAMPLE:";
+   echo=2;
+   ring r=(0,t),(x,y),dp;
+// the input consists of a list of five points in the plane over Q(t)
+   list points=list(1/t2,t),list(1/t,t2),list(1,1),list(t,1/t2),list(t2,1/t);
+   list conic=conicWithTangents(points);
+// conic[1] is the list of the given five points
+   conic[1];
+// conic[2] is the equation of the conic f passing through the five points
+   conic[2];
+// conic[3] is a list containing the equations of the tangents
+//          through the five points
+   conic[3];
+// conic[4] is an ideal representing the tropicalisation of the conic f
+   conic[4];
+// conic[5] is a list containing the tropicalisation
+//          of the five tangents in conic[3]
+   conic[5];
+// conic[6] is a list containing the vertices of the tropical conic
+   conic[6];
+// conic[7] is a list containing the vertices of the five tangents
+   conic[7];
+// conic[8] contains the latex code to draw the tropical conic and
+//          its tropicalised tangents; it can written in a file, processed and
+//          displayed via kghostview
+   write(":w /tmp/conic.tex",conic[8]);
+   system("sh","cd /tmp; latex /tmp/conic.tex; dvips /tmp/conic.dvi -o;
+            kghostview conic.ps &");
+// with an optional argument the same information for the dual conic is computed
+//         and saved in conic[9]
+   conic=conicWithTangents(points,1);
+   conic[9][2]; // the equation of the dual conic
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Procedures concerned with tropicalisation
+///////////////////////////////////////////////////////////////////////////////
+
+proc tropicalise (poly f,list #)
+"USAGE:      tropicalise(f[,#]); f polynomial, # optional list
+ASSUME:      f is a polynomial in Q(t)[x_1,...,x_n]
+RETURN:      list, the linear forms of the tropicalisation of f
+NOTE:        if # is empty, then the valuation of t will be 1,
+@*           if # is the string 'max' it will be -1;
+@*           the latter supposes that we consider the maximum of the
+             computed linear forms, the former that we consider their minimum
+EXAMPLE:     example tropicalise;   shows an example"
+{
+  int order,j;
+  list tropicalf;
+  intvec exp;
+  int i=0;
+  while (f!=0)
+  {
+    i++;
+    exp=leadexp(f);
+    if (size(#)==0)
+    {
+      tropicalf[i]=simplifyToOrder(f)[1];
+    }
+    else
+    {
+      tropicalf[i]=-simplifyToOrder(f)[1];
+    }
+    for (j=1;j<=nvars(basering);j++)
+    {
+      tropicalf[i]=tropicalf[i]+exp[j]*var(j);
+    }
+    f=f-lead(f);
+  }
+  return(tropicalf);
+}
+example
+{
+   "EXAMPLE:";
+   echo=2;
+   ring r=(0,t),(x,y),dp;
+   tropicalise(2t3x2-1/t*xy+2t3y2+(3t3-t)*x+ty+(t6+1));
+}
+
+
+/////////////////////////////////////////////////////////////////////////
+
+proc tropicaliseSet (ideal i)
+"USAGE:    tropicaliseSet(i); i ideal
+ASSUME:    i is an ideal in Q(t)[x_1,...,x_n]
+RETURN:    list, the jth entry is the tropicalisation of the jth generator of i
+EXAMPLE:   example tropicaliseSet;   shows an example"
+{
+  list tropicalid;
+  for (int j=1;j<=size(i);j++)
+  {
+    tropicalid[j]=tropicalise(i[j]);
+  }
+  return(tropicalid);
+}
+example
+{
+   "EXAMPLE:";
+   echo=2;
+   ring r=(0,t),(x,y),dp;
+   ideal i=txy-y2+1,2t3x2+1/t*y-t6;
+   tropicaliseSet(i);
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+proc tInitialForm (poly f, intvec w)
+"USAGE:      tInitialForm(f,w); f a polynomial, w an integer vector
+ASSUME:      f is a polynomial in Q[t,x_1,...,x_n] and w=(w_0,w_1,...,w_n)
+RETURN:      poly, the t-initialform of f(t,x) w.r.t. w evaluated at t=1
+NOTE:        the t-initialform is the sum of the terms with MAXIMAL
+             weighted order w.r.t. w
+EXAMPLE:     example tInitialForm;   shows an example"
+{
+  // take in lead(f) only the term of lowest t-order and set t=1
+  poly initialf=lead(f);
+  // compute the order of lead(f) w.r.t. (1,w)
+  int gewicht=scalarproduct(w,leadexp(f));
+  // do the same for the remaining part of f and compare the results
+  // keep only the smallest ones
+  int vglgewicht;
+  f=f-lead(f);
+  while (f!=0)
+  {
+    vglgewicht=scalarproduct(w,leadexp(f));
+    if (vglgewicht>gewicht)
+    {
+      initialf=lead(f);
+      gewicht=vglgewicht;
+    }
+    else
+    {
+      if (vglgewicht==gewicht)
+      {
+        initialf=initialf+lead(f);
+      }
+    }
+    f=f-lead(f);
+  }
+  initialf=substitute(initialf,var(1),1);
+  return(initialf);
+}
+example
+{
+   "EXAMPLE:";
+   echo=2;
+   ring r=0,(t,x,y),dp;
+   poly f=t4x2+y2-t2xy+t4x-t9;
+   intvec w=-1,-2,-3;
+   tInitialForm(f,w);
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+proc tInitialIdeal (ideal i,intvec w,list #)
+"USAGE:      tInitialIdeal(i,w); i ideal, w intvec
+ASSUME:      i is an ideal in Q[t,x_1,...,x_n] and w=(w_0,...,w_n)
+RETURN:      ideal ini, the t-initial ideal of i with respect to w"
+{
+  // THE PROCEDURE WILL BE CALLED FROM OTHER PROCEDURES INSIDE THIS LIBRARY;
+  // IN THIS CASE THE VARIABLE t WILL INDEED BE THE LAST VARIABLE INSTEAD OF
+  // THE FIRST,
+  // AND WE THEREFORE HAVE TO MOVE IT BACK TO THE FRONT!
+  // THIS IS NOT DOCUMENTED FOR THE GENERAL USER!!!!
+  def BASERING=basering;
+  int j;
+  if (size(#)>0)
+  {
+    // we first have to move the variable t to the front again
+    ideal variablen=var(nvars(basering));
+    for (j=1;j<nvars(basering);j++)
+    {
+      variablen=variablen+var(j);
+    }
+  }
+  else
+  {
+    ideal variablen=maxideal(1);
+  }
+  // we want to homogenise the ideal i ....
+  execute("ring HOMOGRING=("+charstr(basering)+"),(@s,"+string(variablen)+"),dp;");
+  ideal i=homog(std(imap(BASERING,i)), at s);
+  // ... and compute a standard basis with
+  // respect to the homogenised ordering defined by w. Since the generators
+  // of i will be homogeneous it we can instead take the ordering wp
+  // with the weightvector (0,w) replaced by (M,...,M)+(0,w) for some
+  // large M, so that all entries are positive
+  int M=-minInIntvec(w)[1]+1; // find M such that w[j]+M is
+                              // strictly positive for all j
+  intvec whomog=M;
+  for (j=1;j<=size(w);j++)
+  {
+    whomog[j+1]=w[j]+M;
+  }
+  intmat O=weightVectorToOrderMatrix(whomog);
+  execute("ring WEIGHTRING=("+charstr(basering)+"),("+varstr(basering)+"),(M("+string(O)+"));");
+  // map i to the new ring and compute a GB of i, then dehomogenise i,
+  // so that we can be sure, that the
+  // initial forms of the generators generate the initial ideal
+  ideal i=subst(groebner(imap(HOMOGRING,i)), at s,1);
+  // compute the w-initial ideal with the help of the procedure tInitialForm;
+  setring BASERING;
+  execute("ring COMPINIRING=("+charstr(basering)+"),("+string(variablen)+"),dp;");
+  ideal i=imap(WEIGHTRING,i);
+  ideal ini;
+  for (j=1;j<=size(i);j++)
+  {
+    ini=ini,tInitialForm(i[j],w);
+  }
+  // the first elementin in ini is zero, we can delete this one!
+  ini=simplify(ini,2);
+  // convert it to a string
+  setring BASERING;
+  return(imap(COMPINIRING,ini));
+}
+example
+{
+   "EXAMPLE:";
+   echo=2;
+   ring r=0,(t,x,y),dp;
+   ideal i=t2x-y+t3,t2x-y-2t3x;
+   intvec w=-1,2,0;
+   // the t-initial forms of the generators are
+   tInitialForm(i[1],w),tInitialForm(i[2],w);
+   // and they do not generate the t-initial ideal of i
+   tInitialIdeal(i,w);
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+proc initialForm (poly f, intvec w)
+"USAGE:      initialForm(f,w); f a polynomial, w an integer vector
+ASSUME:      f is a polynomial in Q[x_1,...,x_n] and w=(w_1,...,w_n)
+RETURN:      poly, the initial form of f(x) w.r.t. w
+NOTE:        the initialForm consists of the terms with MAXIMAL weighted order w.r.t. w
+EXAMPLE:     example initialForm;   shows an example"
+{
+  def BASERING=basering;
+  intmat O=weightVectorToOrderMatrix(w);
+  execute("ring INITIALRING=("+charstr(BASERING)+"),("+varstr(basering)+"),M("+string(O)+");");
+  poly f=imap(BASERING,f);
+  int GRAD=deg(f);
+  poly initialf=lead(f);
+  f=f-lead(f);
+  while (deg(f)==GRAD)
+  {
+    initialf=initialf+lead(f);
+    f=f-lead(f);
+  }
+  setring BASERING;
+  return(imap(INITIALRING,initialf));
+}
+example
+{
+   "EXAMPLE:";
+   echo=2;
+   ring r=0,(x,y),dp;
+   poly f=x3+y2-xy+x-1;
+   intvec w=2,3;
+   initialForm(f,w);
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+proc weightVectorToOrderMatrix (intvec w)
+"USAGE:      weightVectorToOrderMatrix(w); w intvec
+ASSUME:      w not zero vector
+RETURN:      intmat, an order matrix yielding a weighted degree ordering
+NOTE:        returns matrix of full rank with first row equal to m
+EXAMPLE:     example weightVectorToOrderMatrix;   shows an example"
+{
+  intmat O[size(w)][size(w)]; O[1,1..size(w)]=w;
+  for (int j=size(w);j>=1;j--)
+  {
+    if (w[j]<>0)  // find the last non-zero component of w
+    {
+      int r=2;
+      for (int k=1;k<=size(w);k++)
+      {           // fill the order matrix O with unit vectors
+        if(k<>j)  // except the unit vector of the non-zero component
+        {
+          intvec u;
+          u[size(w)]=0;
+          u[k]=1;
+          O[r,1..size(w)]=u;
+          r=r+1;
+          kill u;
+        }
+      }
+      return(O);
+    }
+  }
+}
+example
+{
+   "EXAMPLE:";
+   echo=2;
+   intvec v=2,3,0,0;
+   weightVectorToOrderMatrix(v);
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+proc initialIdeal (ideal i, intvec w)
+"USAGE:      initialIdeal(i,w); i ideal, w intvec
+ASSUME:      i is an ideal in Q[x_1,...,x_n] and w=(w_1,...,w_n)
+RETURN:      ideal, the initialIdeal of i w.r.t. w
+NOTE:        the initialIdeal consists of the terms with MAXIMAL weighted order w.r.t. w
+EXAMPLE:     example initialIdeal;   shows an example"
+{
+  def BASERING=basering;
+  intmat O=weightVectorToOrderMatrix(w);
+  execute("ring INITIALRING=("+charstr(BASERING)+"),("+varstr(basering)+"),M("+string(O)+");");
+  ideal i=imap(BASERING,i);
+  i=std(i);
+  ideal ini;
+  for (int j=1;j<=size(i);j++)
+  {
+    ini[j]=initialForm(i[j],w);
+  }
+  setring BASERING;
+  return(imap(INITIALRING,ini));
+}
+example
+{
+   "EXAMPLE:";
+   echo=2;
+   ring r=0,(x,y),dp;
+   poly f=x3+y2-xy+x-1;
+   intvec w=2,3;
+   initialIdeal(f,w);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// PROCEDURES CONCERNED WITH THE LATEX CONVERSION
+///////////////////////////////////////////////////////////////////////////////
+
+proc texNumber (poly p)
+"USAGE:   texNumber(f); f poly
+RETURN:   string, tex command representing leading coefficient of f using \frac
+EXAMPLE:  example texNumber;   shows an example"
+{
+  number n=leadcoef(p);
+  number den=denominator(n);
+  number num=numerator(n);
+  if (parstr(basering)=="")
+  {
+    if (den==-1)
+    {
+      den=-den;
+      num=-num;
+    }
+    if (den==1)
+    {
+      return(string(num));
+    }
+    else
+    {
+      return("\\tfrac{"+string(num)+"}{"+string(den)+"}");
+    }
+  }
+  def BASERING=basering;
+  execute("ring PARAMETERRING=("+string(char(basering))+"),("+parstr(basering)+"),ds;");
+  poly den=imap(BASERING,den);
+  poly num=imap(BASERING,num);
+  if (den==1)
+  {
+    return(texPolynomial(num));
+  }
+  else
+  {
+    return("\\tfrac{"+texPolynomial(num)+"}{"+texPolynomial(den)+"}");
+  }
+}
+example
+{
+   "EXAMPLE:";
+   echo=2;
+   ring r=(0,t),x,dp;
+   texNumber((3t2-1)/t3);
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+proc texPolynomial (poly f)
+"USAGE:      texPolynomial(f); f poly
+RETURN:      string, the tex command representing f
+EXAMPLE:     example texPolynomial;   shows an example"
+{
+  int altshort=short;
+  short=0;
+  if (f==0)
+  {
+    return("0");
+  }
+  string texmf;
+  string texco;
+  string texf;
+  string plus;
+  int laenge=size(f);
+  while (f!=0)
+  {
+    if (size(f)<laenge)
+    {
+      plus="+";
+    }
+    texmf=texmonomial(f);
+    if (texmf=="1")
+    {
+      texco=texcoefficient(f,1);
+      if (texco[1]=="-")
+      {
+        texf=texf+texco;
+      }
+      else
+      {
+        texf=texf+plus+texco;
+      }
+    }
+    else
+    {
+      texco=texcoefficient(f);
+      if (texco[1]=="-")
+      {
+        texf=texf+texco+texmf;
+      }
+      else
+      {
+        texf=texf+plus+texco+texmf;
+      }
+    }
+    f=f-lead(f);
+  }
+  short=altshort;
+  return(texf);
+}
+example
+{
+   "EXAMPLE:";
+   echo=2;
+   ring r=(0,t),x,dp;
+   texPolynomial(1/t*x2-t2x+1/t);
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+proc texMatrix (matrix M)
+"USAGE:      texMatrix(M); M matrix
+RETURN:      string, the tex command representing M
+EXAMPLE:     example texMatrix;   shows an example"
+{
+  int i,j;
+  string texmat="\\left(\\begin{array}{";
+  for (i=1;i<=ncols(M);i++)
+  {
+    texmat=texmat+"c";
+  }
+  texmat=texmat+"}
+   ";
+  for (i=1;i<=nrows(M);i++)
+  {
+    for (j=1;j<=ncols(M);j++)
+    {
+      texmat=texmat+texPolynomial(M[i,j]);
+      if (j<ncols(M))
+      {
+        texmat=texmat+" & ";
+      }
+      else
+      {
+        texmat=texmat+" \\\\
+     ";
+      }
+    }
+  }
+  texmat=texmat+"\\end{array}\\right)";
+  return(texmat);
+}
+example
+{
+   "EXAMPLE:";
+   echo=2;
+   ring r=(0,t),x,dp;
+   matrix M[2][2]=3/2,1/t*x2-t2x+1/t,5,-2x;
+   texMatrix(M);
+}
+
+
+/////////////////////////////////////////////////////////////////////////
+
+proc texDrawBasic (list texdraw)
+"USAGE:      texDrawBasic(texdraw); list texdraw
+ASSUME:      texdraw is a list of strings representing texdraw commands
+             (as produced by texDrawTropical) which should be embedded into
+             a texdraw environment
+RETURN:      string, a texdraw environment enclosing the input
+NOTE:        is called from conicWithTangents
+EXAMPLE:     example texDrawBasic;   shows an example"
+{
+  string texdrawtp="
+    \\begin{texdraw}
+       \\drawdim cm  \\relunitscale 0.7 \\arrowheadtype t:V
+       %\\linewd 0.05 \\lpatt (0.1 0.4)
+       %\\move (-4 0) \\avec (9 0) \\move (0 -4) \\avec (0 9)
+       \\linewd 0.1  \\lpatt (1 0)
+       ";
+  for (int i=1;i<=size(texdraw);i++)
+  {
+    texdrawtp=texdrawtp+texdraw[i];
+  }
+  texdrawtp=texdrawtp+"
+    \\end{texdraw}";
+  return(texdrawtp);
+}
+example
+{
+   "EXAMPLE:";
+   echo=2;
+   ring r=(0,t),(x,y),dp;
+   poly f=x+y+1;
+   string texf=texDrawTropical(tropicalCurve(f),list("",1));
+   texDrawBasic(texf);
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+proc texDrawTropical (list graph,list #)
+"USAGE:  texDrawTropical(graph[,#]); graph list, # optional list
+ASSUME:  graph is the output of tropicalCurve
+RETURN:  string, the texdraw code of the tropical plane curve encoded by graph
+NOTE:    - if the list # is non-empty, the first entry should be a string;
+           if this string is 'max', then the tropical curve is considered
+           with respect to the maximum
+@*       - the procedure computes a scalefactor for the texdraw command which
+           should help to display the curve in the right way; this may,
+           however, be a bad idea if several texDrawTropical outputs are
+           put together to form one image; the scalefactor can be prescribed
+           by the further optional entry of type poly
+@*       - one can add a string as last opional argument to the list #;
+           it can be used to insert further texdraw commands (e.g. to have
+           a lighter image as when called from inside conicWithTangents);
+@*       - the list # is optional and may as well be empty
+EXAMPLE:     example texDrawTropical;   shows an example"
+{
+  // there is one possible argument, which is not explained to the user;
+  // it is used to draw several tropical curves; there we want to suppress
+  // the weights sometimes; this is done by handing over the string "noweights"
+  int i,j;
+  int noweights; // controls if weights should be drawn or not
+  for (i=1;i<=size(#);i++)
+  {
+    if (typeof(#[i])=="string")
+    {
+      if (#[i]=="noweights")
+      {
+        noweights=1;
+        #=delete(#,i);
+      }
+    }
+  }
+  // deal first with the pathological case that
+  // the input polynomial was a monomial
+  // and does therefore not define a tropical curve,
+  // and check if the Newton polytope is
+  // a line segment so that the curve defines a bunch of lines
+  int bunchoflines;
+  // if the boundary of the Newton polytope consists of a single point
+  if (size(graph[size(graph)][1])==1)
+  {
+    return(string());
+  }
+  else
+  {
+    matrix M[2][size(graph[size(graph)][1])];
+    for (i=1;i<=size(graph[size(graph)][1]);i++)
+    {
+      M[1,i]=graph[size(graph)][1][i][1];
+      M[2,i]=graph[size(graph)][1][i][2];
+    }
+    // then the Newton polytope is a line segment
+    if ((size(graph[size(graph)][1])-size(syz(M)))==1)
+    {
+      bunchoflines=1;
+    }
+  }
+  // go on with the case that a tropical curve is defined
+  string texdrawtp="
+
+       \\setgray 0.6
+
+       ";
+  // if texdraw input has been inserted, it should be added
+  if (size(#)>=1)
+  {
+    if (typeof(#[size(#)])=="string")
+    {
+      if (#[size(#)]!="max")
+      {
+        texdrawtp=texdrawtp+#[size(#)];
+      }
+    }
+  }
+  // find the minimal and maximal coordinates of vertices
+  // and find the scale factor for the texdraw image
+  list SCFINPUT;
+  SCFINPUT[1]=graph;
+  list SCF=minScaleFactor(SCFINPUT);
+  poly minx,miny,maxx,maxy=SCF[4],SCF[5],SCF[6],SCF[7];
+  poly centerx,centery=SCF[8],SCF[9];
+  int nachkomma=2; // number of decimals for the scalefactor
+  number sf=1; // correction factor for scalefactor
+  // if no scale factor was handed over to the procedure, use the
+  // one computed by minScaleFactor;
+  // check first if a scale factor has been handed over
+  i=1;
+  int scfpresent;
+  while ((i<=size(#)) and (scfpresent==0))
+  {
+    // if the scalefactor as polynomial was handed over, get it
+    if (typeof(#[i])=="poly")
+    {
+      poly scalefactor=#[2];
+      scfpresent=1;
+    }
+    // if the procedure is called for drawing more than one tropical curve
+    // then scalefactor,sf,nachkomma,minx,miny,maxx,maxy,centerx,centery
+    // has been handed over to the procedure
+    if (typeof(#[i])=="list")
+    {
+      poly scalefactor=#[i][1];
+      sf=#[i][2];
+      nachkomma=#[i][3];
+      minx=#[i][4];
+      miny=#[i][5];
+      maxx=#[i][6];
+      maxy=#[i][7];
+      centerx=#[i][8];
+      centery=#[i][9];
+      scfpresent=1;
+    }
+    i++;
+  }
+  // if no scalefactor was handed over we take the one computed in SCF
+  if (scfpresent==0)
+  {
+    poly scalefactor=SCF[1];
+    sf=SCF[2];
+    nachkomma=SCF[3];
+    texdrawtp=texdrawtp+"
+       \\relunitscale "+ decimal(scalefactor,nachkomma);
+  }
+  // compute the texdrawoutput for the tropical curve given by f
+  list relxy;
+  for (i=1;i<=size(graph)-1;i++)
+  {
+    // if the curve is a bunch of lines no vertex has to be drawn
+    if (bunchoflines==0)
+    {
+      texdrawtp=texdrawtp+"
+       \\move ("+decimal((graph[i][1]-centerx)/sf)+" "+decimal((graph[i][2]-centery)/sf)+") \\fcir f:0 r:"+decimal(2/(leadcoef(scalefactor)*10),size(string(int(scalefactor)))+1);
+    }
+    // draw the bounded edges emerging from the ith vertex
+    for (j=1;j<=ncols(graph[i][3]);j++)
+    {
+      // don't draw it twice - and if there is only one vertex
+      //                       and graph[i][3][1,1] is thus 0, nothing is done
+      if (i<graph[i][3][1,j])
+      {
+        texdrawtp=texdrawtp+"
+       \\move ("+decimal((graph[i][1]-centerx)/sf)+" "+decimal((graph[i][2]-centery)/sf)+") \\lvec ("+decimal((graph[graph[i][3][1,j]][1]-centerx)/sf)+" "+decimal((graph[graph[i][3][1,j]][2]-centery)/sf)+")";
+        // if the multiplicity is more than one, denote it in the picture
+        if ((graph[i][3][2,j]>1) and (noweights==0))
+        {
+          texdrawtp=texdrawtp+"
+       \\htext ("+decimal((graph[i][1]-centerx+graph[graph[i][3][1,j]][1])/(2*sf))+" "+decimal((graph[i][2]-centery+graph[graph[i][3][1,j]][2])/(2*sf))+"){$"+string(graph[i][3][2,j])+"$}";
+        }
+      }
+    }
+    // draw the unbounded edges emerging from the ith vertex
+    // they should not be too long
+    for (j=1;j<=size(graph[i][4]);j++)
+    {
+      relxy=shorten(list(decimal((3*graph[i][4][j][1][1]/scalefactor)*sf),decimal((3*graph[i][4][j][1][2]/scalefactor)*sf),string(5*sf/2)));
+      texdrawtp=texdrawtp+"
+       \\move ("+decimal((graph[i][1]-centerx)/sf)+" "+decimal((graph[i][2]-centery)/sf)+") \\rlvec ("+relxy[1]+" "+relxy[2]+")";
+      // if the multiplicity is more than one, denote it in the picture
+      if ((graph[i][4][j][2]>1) and (noweights==0))
+      {
+        texdrawtp=texdrawtp+"
+       \\htext ("+decimal(graph[i][1]/sf-centerx/sf+graph[i][4][j][1][1]/scalefactor)+" "+decimal(graph[i][2]/sf-centery/sf+graph[i][4][j][1][2]/scalefactor)+"){$"+string(graph[i][4][j][2])+"$}";
+      }
+    }
+  }
+  // add lattice points if the scalefactor is >= 1/2
+  // and was not handed over
+  if ((scalefactor>1/2) and (scfpresent==0))
+  {
+    int uh=1;
+    if (scalefactor>3)
+    {
+      uh=0;
+    }
+    texdrawtp=texdrawtp+"
+
+   %% HERE STARTS THE CODE FOR THE LATTICE";
+    for (i=int(minx)-uh;i<=int(maxx)+uh;i++)
+    {
+      for (j=int(miny)-uh;j<=int(maxy)+uh;j++)
+      {
+        texdrawtp=texdrawtp+"
+        \\move ("+decimal(i-centerx)+" "+decimal(j-centery)+") \\fcir f:0.8 r:"+decimal(1/(10*scalefactor),size(string(int(scalefactor)))+1);
+      }
+    }
+    texdrawtp=texdrawtp+"
+   %% HERE ENDS THE CODE FOR THE LATTICE
+                          ";
+  }
+  return(texdrawtp);
+}
+example
+{
+   "EXAMPLE:";
+   echo=2;
+   ring r=(0,t),(x,y),dp;
+   poly f=x+y+x2y+xy2+1/t*xy;
+   list graph=tropicalCurve(f);
+// compute the texdraw code of the tropical curve defined by f
+   texDrawTropical(graph);
+// compute the texdraw code again, but set the scalefactor to 1
+   texDrawTropical(graph,"",1);
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+proc texDrawNewtonSubdivision (list graph,list #)
+"USAGE:      texDrawNewtonSubdivision(graph[,#]); graph list, # optional list
+ASSUME:      graph is the output of tropicalCurve
+RETURN:      string, the texdraw code of the Newton subdivision of the
+                     tropical plane curve encoded by graph
+NOTE:        - the list # may contain optional arguments, of which only
+               one will be considered, namely the first entry of type 'poly';
+               this entry should be a rational number which specifies the
+               scaling factor to be used; if it is missing, the factor will
+               be computed; the list # may as well be empty
+@*           - note that lattice points in the Newton subdivision which are
+               black correspond to markings of the marked subdivision,
+               while lattice points in grey are not marked
+EXAMPLE:     example texDrawNewtonSubdivision;   shows an example"
+{
+  int i,j,k,l;
+  list boundary=graph[size(graph)][1];
+  list inneredges=graph[size(graph)][2];
+  intvec shiftvector=graph[size(graph)][3];
+  string subdivision;
+  // find maximal and minimal x- and y-coordinates and define the scalefactor
+  poly maxx,maxy=1,1;
+  for (i=1;i<=size(boundary);i++)
+  {
+    maxx=-minOfPolys(list(-maxx,-boundary[i][1]));
+    maxy=-minOfPolys(list(-maxy,-boundary[i][2]));
+  }
+  // compute the scalefactor
+  poly scalefactor=minOfPolys(list(12/leadcoef(maxx),12/leadcoef(maxy)));
+  // Check if the scalefactor was handed over, then take that instead
+  if (size(#)>0)
+  {
+    int scfpresent;
+    i=1;
+    while (i<=size(#) and scfpresent==0)
+    {
+      if (typeof(#[i])=="poly")
+      {
+        scalefactor=#[i];
+        scfpresent=1;
+      }
+      i++;
+    }
+  }
+  // check if scaling is necessary
+  if (scalefactor<1)
+  {
+    subdivision=subdivision+"
+       \\relunitscale"+ decimal(scalefactor);
+  }
+  // define the texdraw code for the Newton subdivision
+  for (i=1;i<=size(boundary)-1;i++)
+  {
+    subdivision=subdivision+"
+        \\move ("+string(boundary[i][1])+" "+string(boundary[i][2])+")
+        \\lvec ("+string(boundary[i+1][1])+" "+string(boundary[i+1][2])+")";
+  }
+  subdivision=subdivision+"
+        \\move ("+string(boundary[size(boundary)][1])+" "+string(boundary[size(boundary)][2])+")
+        \\lvec ("+string(boundary[1][1])+" "+string(boundary[1][2])+")
+
+    ";
+  for (i=1;i<=size(inneredges);i++)
+  {
+    subdivision=subdivision+"
+        \\move ("+string(inneredges[i][1][1])+" "+string(inneredges[i][1][2])+")
+        \\lvec ("+string(inneredges[i][2][1])+" "+string(inneredges[i][2][2])+")";
+  }
+  // add lattice points if the scalefactor is >= 1/2
+  if (scalefactor>1/2)
+  {
+    for (i=shiftvector[1];i<=int(maxx);i++)
+    {
+      for (j=shiftvector[2];j<=int(maxy);j++)
+      {
+        if (scalefactor > 2)
+        {
+          subdivision=subdivision+"
+        \\move ("+string(i)+" "+string(j)+") \\fcir f:0.6 r:"+decimal(2/(10*scalefactor),size(string(int(scalefactor)))+1);
+        }
+        else
+        {
+          subdivision=subdivision+"
+        \\move ("+string(i)+" "+string(j)+") \\fcir f:0.6 r:"+decimal(2/(20*scalefactor),size(string(int(scalefactor)))+1);
+        }
+      }
+    }
+    if ((shiftvector[1]!=0) or (shiftvector[2]!=0))
+    {
+      subdivision=subdivision+"
+        \\htext (-0.3 0.1){{\\tiny $(0,0)$}}";
+    }
+  }
+  // deal with the pathological cases
+  if (size(boundary)==1) // then the Newton polytope is a point
+  {
+    subdivision=subdivision+"
+       \\move ("+string(boundary[1][1])+" "+string(boundary[1][2])+")
+       \\fcir f:0 r:0.15";
+  }
+  else
+  {
+    matrix M[2][size(boundary)];
+    for (i=1;i<=size(boundary);i++)
+    {
+      M[1,i]=boundary[i][1];
+      M[2,i]=boundary[i][2];
+    }
+    if ((size(boundary)-size(syz(M)))==1)
+    {
+      for (i=1;i<=size(boundary);i++)
+      {
+        subdivision=subdivision+"
+       \\move ("+string(boundary[i][1])+" "+string(boundary[i][2])+")
+       \\fcir f:0 r:"+decimal(2/(8*scalefactor),size(string(int(scalefactor)))+1);
+      }
+    }
+  }
+  // find the marked points in the subdivision
+  poly pg;
+  list markings;
+  k=1;
+  for (i=1;i<size(graph);i++)
+  {
+    pg=graph[i][5];
+    while (pg!=0)
+    {
+      markings[k]=leadexp(pg)+shiftvector;
+      pg=pg-lead(pg);
+      k++;
+    }
+  }
+  for (i=size(markings);i>=2;i--)
+  {
+    j=i-1;
+    while (j>=1)
+    {
+      if (markings[i]==markings[j])
+      {
+        markings=delete(markings,i);
+        j=0;
+      }
+      j--;
+    }
+  }
+  for (i=1;i<=size(markings);i++)
+  {
+    if (scalefactor > 2)
+    {
+      subdivision=subdivision+"
+       \\move ("+string(markings[i][1])+" "+string(markings[i][2])+")
+       \\fcir f:0 r:"+decimal(2/(8*scalefactor),size(string(int(scalefactor)))+1);
+    }
+    else
+    {
+      subdivision=subdivision+"
+       \\move ("+string(markings[i][1])+" "+string(markings[i][2])+")
+       \\fcir f:0 r:"+decimal(2/(16*scalefactor),size(string(int(scalefactor)))+1);
+    }
+  }
+  // enclose subdivision in the texdraw environment
+  string texsubdivision="
+    \\begin{texdraw}
+       \\drawdim cm  \\relunitscale 1
+       \\linewd 0.05"
+    +subdivision+"
+   \\end{texdraw}
+    ";
+  return(texsubdivision);
+}
+example
+{
+   "EXAMPLE:";
+   echo=2;
+   ring r=(0,t),(x,y),dp;
+   poly f=x+y+x2y+xy2+1/t*xy;
+   list graph=tropicalCurve(f);
+// compute the texdraw code of the Newton subdivision of the tropical curve
+   texDrawNewtonSubdivision(graph);
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+proc texDrawTriangulation (list triang,list polygon)
+"USAGE:      texDrawTriangulation(triang,polygon);  triang,polygon list
+ASSUME:      polygon is a list of integer vectors describing the
+             lattice points of a marked polygon;
+             triang is a list of integer vectors describing a
+             triangulation of the marked polygon
+             in the sense that an integer vector of the form (i,j,k) describes
+             the triangle formed by polygon[i], polygon[j] and polygon[k]
+RETURN:      string, a texdraw code for the triangulation described
+                     by triang without the texdraw environment
+EXAMPLE:     example texDrawTriangulation;   shows an example"
+{
+  // the header of the texdraw output
+  string latex="
+        \\drawdim cm  \\relunitscale 1.2 \\arrowheadtype t:V
+   ";
+  int i,j; // indices
+  list pairs,markings; // stores edges of the triangulation, respecively
+  // the marked points for each triangle store the edges and marked
+  // points of the triangle
+  for (i=1;i<=size(triang);i++)
+  {
+    pairs[3*i-2]=intvec(triang[i][1],triang[i][2]);
+    pairs[3*i-1]=intvec(triang[i][2],triang[i][3]);
+    pairs[3*i]=intvec(triang[i][3],triang[i][1]);
+    markings[3*i-2]=triang[i][1];
+    markings[3*i-1]=triang[i][2];
+    markings[3*i]=triang[i][3];
+  }
+  // delete redundant pairs which occur more than once
+  for (i=size(pairs);i>=1;i--)
+  {
+    for (j=1;j<i;j++)
+    {
+      if ((pairs[i]==pairs[j]) or ((pairs[i][1]==pairs[j][2]) and (pairs[i][2]==pairs[j][1])))
+      {
+        pairs=delete(pairs,i);
+        j=i;
+      }
+    }
+  }
+  // delete redundant marked points which occur more than once
+  for (i=size(markings);i>=1;i--)
+  {
+    for (j=1;j<i;j++)
+    {
+      if (markings[i]==markings[j])
+      {
+        markings=delete(markings,i);
+        j=i;
+      }
+    }
+  }
+  // change the color
+  latex=latex+"
+        \\setgray 0";
+  // draw first all marked points of the triangulation in fat black
+  for (i=1;i<=size(markings);i++)
+  {
+    latex=latex+"
+        \\move ("+string(polygon[markings[i]][1])+" "+string(polygon[markings[i]][2])+")
+        \\fcir f:0 r:0.08";
+  }
+  // next draw all edges in black
+  for (i=1;i<=size(pairs);i++)
+  {
+    latex=latex+"
+        \\move ("+string(polygon[pairs[i][1]][1])+" "+string(polygon[pairs[i][1]][2])+")
+        \\lvec ("+string(polygon[pairs[i][2]][1])+" "+string(polygon[pairs[i][2]][2])+")";
+  }
+  // finally daw all marked points of the polygon in small gray
+  for (i=1;i<=size(polygon);i++)
+  {
+    latex=latex+"
+        \\move ("+string(polygon[i][1])+" "+string(polygon[i][2])+")
+        \\fcir f:0.7 r:0.04";
+  }
+  return(latex);
+}
+example
+{
+   "EXAMPLE:";
+   echo=2;
+   // the lattice polygon spanned by the points (0,0), (3,0) and (0,3)
+   // with all integer points as markings
+   list polygon=intvec(1,1),intvec(3,0),intvec(2,0),intvec(1,0),intvec(0,0),
+                intvec(2,1),intvec(0,1),intvec(1,2),intvec(0,2),intvec(0,3);
+   // define a triangulation by connecting the only interior point
+   //        with the vertices
+   list triang=intvec(1,2,5),intvec(1,5,10),intvec(1,2,10);
+   // produce the texdraw output of the triangulation triang
+   texDrawTriangulation(triang,polygon);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Auxilary Procedures
+///////////////////////////////////////////////////////////////////////////////
+
+proc radicalMemberShip (poly f,ideal i)
+"USAGE:  radicalMemberShip (f,i); f poly, i ideal
+RETURN:  int, 1 if f is in the radical of i, 0 else
+EXAMPLE:     example radicalMemberShip;   shows an example"
+{
+  def BASERING=basering;
+  execute("ring RADRING=("+charstr(basering)+"),(@T,"+varstr(basering)+"),(dp(1),"+ordstr(basering)+");");
+  ideal I=ideal(imap(BASERING,i))+ideal(1- at T*imap(BASERING,f));
+  if (reduce(1,std(I))==0)
+  {
+    return(1);
+  }
+  else
+  {
+    return(0);
+  }
+}
+example
+{
+   "EXAMPLE:";
+   echo=2;
+   ring r=0,(x,y),dp;
+   ideal i=(x+1)*y2;
+   // y is NOT in the radical of i
+   radicalMemberShip(y,i);
+   ring rr=0,(x,y),ds;
+   ideal i=(x+1)*y2;
+   // since this time the ordering is local, y is in the radical of i
+   radicalMemberShip(y,i);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Auxilary Procedures concerned with initialforms
+///////////////////////////////////////////////////////////////////////////////
+
+proc tInitialFormPar (poly f, intvec w)
+"USAGE:  tInitialFormPar(f,w); f a polynomial, w an integer vector
+ASSUME:  f is a polynomial in Q(t)[x_1,...,x_n] and w=(w_1,...,w_2)
+RETURN:  poly, the t-initialform of f(t,x) w.r.t. (1,w) evaluated at t=1
+NOTE:    the t-initialform are the terms with MINIMAL weighted order w.r.t. (1,w)
+EXAMPLE: example tInitialFormPar;   shows an example"
+{
+  // compute first the t-order of the leading coefficient of f (leitkoef[1]) and
+  // the rational constant corresponding to this order in leadkoef(f)
+  // (leitkoef[2])
+  list leitkoef=simplifyToOrder(f);
+  execute("poly koef="+leitkoef[2]+";");
+  // take in lead(f) only the term of lowest t-order and set t=1
+  poly initialf=koef*leadmonom(f);
+  // compute the order of lead(f) w.r.t. (1,w)
+  int gewicht=leitkoef[1]+scalarproduct(w,leadexp(f));
+  // do the same for the remaining part of f and compare the results
+  // keep only the smallest ones
+  int vglgewicht;
+  f=f-lead(f);
+  while (f!=0)
+  {
+    leitkoef=simplifyToOrder(f);
+    vglgewicht=leitkoef[1]+scalarproduct(w,leadexp(f));
+    if (vglgewicht<gewicht)
+    {
+      execute("koef="+leitkoef[2]+";");
+      initialf=koef*leadmonom(f);
+      gewicht=vglgewicht;
+    }
+    else
+    {
+      if (vglgewicht==gewicht)
+      {
+        execute("koef="+leitkoef[2]+";");
+        initialf=initialf+koef*leadmonom(f);
+      }
+    }
+    f=f-lead(f);
+  }
+  return(initialf);
+}
+example
+{
+   "EXAMPLE:";
+   echo=2;
+   ring r=(0,t),(x,y),dp;
+   poly f=t4x2+y2-t2xy+t4x-t9;
+   intvec w=2,3;
+   tInitialFormPar(f,w);
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+proc tInitialFormParMax (poly f, intvec w)
+"USAGE:  tInitialFormParMax(f,w); f a polynomial, w an integer vector
+ASSUME:  f is a polynomial in Q(t)[x_1,...,x_n] and w=(w_1,...,w_2)
+RETURN:  poly, the t-initialform of f(t,x) w.r.t. (-1,w) evaluated at t=1
+NOTE:    the t-initialform are the terms with MAXIMAL weighted order w.r.t. (1,w)
+EXAMPLE: example tInitialFormParMax;   shows an example"
+{
+  // compute first the t-order of the leading coefficient of f (leitkoef[1]) and
+  // the rational constant corresponding to this order in leadkoef(f)
+  // (leitkoef[2])
+  list leitkoef=simplifyToOrder(f);
+  execute("poly koef="+leitkoef[2]+";");
+  // take in lead(f) only the term of lowest t-order and set t=1
+  poly initialf=koef*leadmonom(f);
+  // compute the order of lead(f) w.r.t. (-1,w)
+  int gewicht=-leitkoef[1]+scalarproduct(w,leadexp(f));
+  // do the same for the remaining part of f and compare the results
+  // keep only the largest ones
+  int vglgewicht;
+  f=f-lead(f);
+  while (f!=0)
+  {
+    leitkoef=simplifyToOrder(f);
+    vglgewicht=-leitkoef[1]+scalarproduct(w,leadexp(f));
+    if (vglgewicht>gewicht)
+    {
+      execute("koef="+leitkoef[2]+";");
+      initialf=koef*leadmonom(f);
+      gewicht=vglgewicht;
+    }
+    else
+    {
+      if (vglgewicht==gewicht)
+      {
+        execute("koef="+leitkoef[2]+";");
+        initialf=initialf+koef*leadmonom(f);
+      }
+    }
+    f=f-lead(f);
+  }
+  return(initialf);
+}
+example
+{
+   "EXAMPLE:";
+   echo=2;
+   ring r=(0,t),(x,y),dp;
+   poly f=t4x2+y2-t2xy+t4x-1/t6;
+   intvec w=2,3;
+   tInitialFormParMax(f,w);
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+proc solveTInitialFormPar (ideal i)
+"USAGE:      solveTInitialFormPar(i); i ideal
+ASSUME:      i is a zero-dimensional ideal in Q(t)[x_1,...,x_n] generated
+             by the (1,w)-homogeneous elements for some integer vector w
+             - i.e. by the (1,w)-initialforms of polynomials
+RETURN:      none
+NOTE:        the procedure just displays complex approximations
+             of the solution set of i
+EXAMPLE:     example solveTInitialFormPar;   shows an example"
+{
+  i=subst(i,t,1);
+  string CHARAKTERISTIK=charstr(basering);
+  CHARAKTERISTIK=CHARAKTERISTIK[1..size(CHARAKTERISTIK)-2];
+  def BASERING=basering;
+  execute("ring INITIALRING=("+CHARAKTERISTIK+"),("+varstr(basering)+"),("+ordstr(basering)+");");
+  list l=solve(imap(BASERING,i));
+  l;
+  setring BASERING;
+//  return(fetch(SUBSTRING,l));
+}
+example
+{
+   "EXAMPLE:";
+   echo=2;
+   ring r=(0,t),(x,y),dp;
+   ideal i=t2x2+y2,x-t2;
+   solveTInitialFormPar(i);
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+proc detropicalise (def p)
+"USAGE:   detropicalise(f); f poly or f list
+ASSUME:   if f is of type poly then t is a linear polynomial with
+          an arbitrary constant term and positive integer coefficients
+          as further coefficients;
+@*        if f is of type list then f is a list of polynomials of
+          the type just described in before
+RETURN:   poly, the detropicalisation of f ignoring the constant parts
+NOTE:     the output will be a monomial and the constant coefficient
+          has been ignored
+EXAMPLE:  example detropicalise;   shows an example"
+{
+  poly dtp=1;
+  while (p!=0)
+  {
+    if (leadmonom(p)!=1)
+    {
+      dtp=dtp*leadmonom(p)^int(leadcoef(p));
+    }
+    p=p-lead(p);
+  }
+  return(dtp);
+}
+example
+{
+   "EXAMPLE:";
+   echo=2;
+   ring r=(0,t),(x,y),dp;
+   detropicalise(3x+4y-1);
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+proc tDetropicalise (def p)
+"USAGE:   tDetropicalise(f); f poly or f list
+ASSUME:   if f is of type poly then f is a linear polynomial with an
+          integer constant term and positive integer coefficients
+          as further coefficients;
+@*        if f is of type list then it is a list of polynomials of
+          the type just described in before
+RETURN:   poly, the detropicalisation of f over the field Q(t)
+NOTE:     the output will be a term where the coeffiecient is a Laurent
+          monomial in the variable t
+EXAMPLE:  example tDetropicalise;   shows an example"
+{
+  poly dtp;
+  if (typeof(p)=="list")
+  {
+    int i;
+    for (i=1;i<=size(p);i++)
+    {
+      dtp=dtp+tDetropicalise(p[i]);
+    }
+  }
+  else
+  {
+    dtp=1;
+    while (p!=0)
+    {
+      if (leadmonom(p)!=1)
+      {
+        dtp=dtp*leadmonom(p)^int(leadcoef(p));
+      }
+      else
+      {
+        dtp=t^int(leadcoef(p))*dtp;
+      }
+      p=p-lead(p);
+    }
+  }
+  return(dtp);
+}
+example
+{
+   "EXAMPLE:";
+   echo=2;
+   ring r=(0,t),(x,y),dp;
+   tDetropicalise(3x+4y-1);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Auxilary Procedures concerned with conics
+///////////////////////////////////////////////////////////////////////////////
+
+proc dualConic (poly f)
+"USAGE:      dualConic(f); f poly
+ASSUME:      f is an affine conic in two variables x and y
+RETURN:      poly, the equation of the dual conic
+EXAMPLE:     example dualConic;   shows an example"
+{
+  if (deg(f)!=2)
+  {
+    "The polynomial is not a conic";
+    return(0);
+  }
+  matrix A=coeffs(f,ideal(var(1)^2,var(1)*var(2),var(2)^2,var(1),var(2),1));
+  matrix C[3][3]=A[1,1],A[2,1]/2,A[4,1]/2,A[2,1]/2,A[3,1],A[5,1]/2,A[4,1]/2,A[5,1]/2,A[6,1];
+  matrix M[3][1]=var(1),var(2),1;
+  matrix Cdual=-adjoint(C);
+  matrix ffd=transpose(M)*Cdual*M;
+  poly fdual=ffd[1,1];
+  return(fdual);
+}
+example
+{
+   "EXAMPLE:";
+   echo=2;
+   ring r=0,(x,y),dp;
+   poly conic=2x2+1/2y2-1;
+   dualConic(conic);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Auxilary Procedures concerned with substitution
+///////////////////////////////////////////////////////////////////////////////
+
+proc parameterSubstitute (poly f,int N)
+"USAGE:   parameterSubstitute(f,N); f poly, N int
+ASSUME:   f is a polynomial in Q(t)[x_1,...,x_n] describing
+          a plane curve over Q(t)
+RETURN:   poly f with t replaced by t^N
+EXAMPLE:  example parameterSubstitute;   shows an example"
+{
+  def BASERING=basering;
+  number nenner=1;
+  for (int i=1;i<=size(f);i++)
+  {
+    nenner=nenner*denominator(leadcoef(f[i]));
+  }
+  f=f*nenner;
+  f=subst(f,t,t^N)/number(subst(nenner,t,t^N));
+  return(f);
+}
+example
+{
+   "EXAMPLE:";
+   echo=2;
+   ring r=(0,t),(x,y),dp;
+   poly f=t2xy+1/t*y+t3;
+   parameterSubstitute(f,3);
+   parameterSubstitute(f,-1);
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+proc tropicalSubst (poly f,int N,list #)
+"USAGE:   parameterSubstitute(f,N,L); f poly, N int, L list
+ASSUME:   f is a polynomial in Q(t)[x_1,...,x_k]
+          and L is a list of the form var(i_1),poly_1,...,v(i_k),poly_k
+RETURN:   list, the list is the tropical polynomial which we get from f
+                by replacing the i-th variable be the i-th polynomial
+                but in the i-th polynomial the parameter t is replaced by t^1/N
+EXAMPLE:  example tropicalSubst;   shows an example"
+{
+  f=parameterSubstitute(f,N);
+  f=substitute(f,#);
+  list tp=tropicalise(f);
+  poly const;
+  for (int i=1;i<=size(tp);i++)
+  {
+    const=substitute(tp[i],x,0,y,0);
+    tp[i]=tp[i]-const+const/N;
+  }
+  return(tp);
+}
+example
+{
+   "EXAMPLE:";
+   echo=2;
+   ring r=(0,t),(x,y),dp;
+   poly f=t2x+1/t*y-1;
+   tropicalSubst(f,2,x,x+t,y,tx+y+t2);
+   // The procedure can be used to study the effect of a transformation of
+   // the form x -> x+t^b, with b a rational number, on the tropicalisation and
+   // the j-invariant of a cubic over the Puiseux series.
+   f=t7*y3+t3*y2+t*(x3+xy2+y+1)+xy;
+   // - the j-invariant, and hence its valuation,
+   //   does not change under the transformation
+   jInvariant(f,"ord");
+   // - b=3/2, then the cycle length of the tropical cubic equals -val(j-inv)
+   list g32=tropicalSubst(f,2,x,x+t3,y,y);
+   tropicalJInvariant(g32);
+   // - b=1, then it is still true, but only just ...
+   list g1=tropicalSubst(f,1,x,x+t,y,y);
+   tropicalJInvariant(g1);
+   // - b=2/3, as soon as b<1, the cycle length is strictly less than -val(j-inv)
+   list g23=tropicalSubst(f,3,x,x+t2,y,y);
+   tropicalJInvariant(g23);
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+proc randomPolyInT (int d,int ug, int og, list #)
+"USAGE:      randomPolyInT(d,ug,og[,#]);   d, ug, og int, # list
+ASSUME:      the basering has a parameter t
+RETURN:      poly, a polynomial of degree d where the coefficients are
+                   of the form t^j with j a random integer between ug and og
+NOTE:        if an optional argument # is given, then the coefficients are
+             instead either of the form t^j as above or they are zero,
+             and this is chosen randomly
+EXAMPLE:     example randomPolyInT;   shows an example"
+{
+  if (defined(t)!=-1) { ERROR("basering has no paramter t");}
+  int i,j,k;
+  def BASERING=basering;
+  ring RANDOMRING=(0,t),(x,y,z),dp;
+  ideal m=maxideal(d);
+  int nnn=size(m);
+  for (i=1;i<=nnn;i++)
+  {
+    m[i]=subst(m[i],z,1);
+  }
+  poly randomPolynomial;
+  for (i=1;i<=nnn;i++)
+  {
+    if (size(#)!=0)
+    {
+      k=random(0,1);
+    }
+    if (k==0)
+    {
+      j=random(ug,og);
+      randomPolynomial=randomPolynomial+t^j*m[i];
+    }
+  }
+  setring BASERING;
+  poly randomPolynomial=imap(RANDOMRING,randomPolynomial);
+  if ((size(randomPolynomial)<3) and (nnn>=3))
+  {
+    randomPolynomial=randomPolyInT(d,ug,og,#);
+  }
+  return(randomPolynomial);
+}
+example
+{
+   "EXAMPLE:";
+   echo=2;
+   ring r=(0,t),(x,y),dp;
+   randomPolyInT(3,-2,5);
+   randomPolyInT(3,-2,5,1);
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+proc cleanTmp ()
+"USAGE:  cleanTmp()
+PURPOSE: some procedures create latex and ps-files in the directory /tmp;
+         in order to remove them simply call cleanTmp();
+RETURN:  none"
+{
+  system("sh","cd /tmp; /bin/rm -f tropicalcurve*; /bin/rm -f tropicalnewtonsubdivision*");
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+/// AUXILARY PROCEDURES, WHICH ARE DECLARED STATIC
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////////////////////
+/// Procedures used in tropicalparametriseNoabs respectively in tropicalLifting:
+/// - phiOmega
+/// - cutdown
+/// - tropicalparametriseNoabs
+/// - findzeros
+/// - basictransformideal
+/// - testw
+/// - simplifyToOrder
+/// - scalarproduct
+/// - intvecdelete
+/// - invertorder
+/// - ordermaximalidealsNoabs
+/// - displaypoly
+/// - displaycoef
+/// - choosegfanvector
+/// - tropicalliftingresubstitute
+//////////////////////////////////////////////////////////////////////////////
+
+static proc phiOmega (ideal i,int j,int wj)
+"USAGE:      phiOmega(i,j,wj); i ideal, j int, wj int
+ASSUME:      i an ideal in Q[t,x_1,...,x_n] and 0<j<n+1
+RETURN:      ideal, in i var(j) has been substituted by t^-wj*var(j)
+NOTE:        is called from tropicalLifting"
+{
+  int k;
+  ideal variablen;
+  for (k=2;k<=nvars(basering);k++)
+  {
+    variablen=variablen+var(k);
+  }
+  def BASERING=basering;
+  execute("ring QUOTRING=("+charstr(basering)+",t),("+string(variablen)+"),dp;");
+  ideal i=subst(imap(BASERING,i),var(j-1),t^(-wj)*var(j-1));
+  for (k=1;k<=size(i);k++)
+  {
+    i[k]=i[k]/content(i[k]);
+  }
+  setring BASERING;
+  return(imap(QUOTRING,i));
+}
+
+
+
+/////////////////////////////////////////////////////////////////////////
+
+static proc cutdown (ideal jideal,intvec wvec,int dimension,list #)
+"USAGE:      cutdown(i,w,d); i ideal, w intvec, d int, # list
+ASSUME:      i an ideal in Q[t,x_1,...,x_n], (w_1,...,w_n) is in the tropical
+             variety of jideal and d=dim(i)>0, in Q(t)[x]; the optional
+             parameter # can contain the string 'isPrime' to indicate that
+             the input ideal is prime and no minimal associated primes have
+             to be computed
+RETURN:      list, the first entry is a ring, namely the basering where some
+                   variables have been eliminated, and the ring contains
+                   the ideal i (with the same variables eliminated),
+                   the t-initial ideal ini of i (w.r.t. the weight vector
+                   where the entries corresponding to the deleted variables
+                   have been eliminated) and a list repl where for each
+                   eliminated variable there is one entry, namely a polynomial
+                   in the remaining variables and t that explains how
+                   resubstitution of a solution for the new i gives a solution
+                   for the old i; the second entry is the weight vector
+                   wvec with the components corresponding to the eliminated
+                   variables removed
+NOTE:        needs the libraries random.lib and primdec.lib;
+             is called from tropicalLifting"
+{
+  // IDEA: i is an ideal of dimension d; we want to cut it with d random linear
+  //       forms in such a way that the resulting
+  //       ideal is 0-dim and still contains w in the tropical variety
+  // NOTE: t is the last variable in the basering
+  ideal pideal;  //this is the ideal we want to return
+  ideal cutideal;
+  ideal pini;    //this is the initial ideal
+  ideal primini; //the initial of the prime we picl
+  int j1,j2,dimp,winprim,j3;
+  poly product=1;
+  def BASERING=basering;
+  ideal variablen;
+  intvec setvec;intvec wvecp;
+  setvec[nvars(basering)-1]=0;
+  poly randomp=0;
+  poly randomp1=0;
+  poly randomp2=0;
+  list erglini;
+  list ergl;
+  for (j1=1;j1<=nvars(basering)-1;j1++)
+  {
+    variablen=variablen+var(j1); // read the set of variables
+                                 // (needed to make the quotring later)
+    product=product*var(j1); // make product of all variables
+                             // (needed for the initial-monomial-check later
+  }
+  execute("ring QUOTRING=("+charstr(basering)+",t),("+string(variablen)+"),dp;");
+  setring BASERING;
+  // change to quotring where we want to compute the primary decomposition of i
+  if (size(#)==0) // we only have to do so if isPrime is not set
+  {
+    setring QUOTRING;
+    ideal jideal=imap(BASERING,jideal);
+    list primp=minAssGTZ(jideal); //compute the primary decomposition
+    for (j1=1;j1<=size(primp);j1++)
+    {
+      for(j2=1;j2<=size(primp[j1]);j2++)
+      {
+        // clear all denominators
+        primp[j1][j2]=primp[j1][j2]/content(primp[j1][j2]);
+      }
+    }
+    setring BASERING;
+    list primp=imap(QUOTRING,primp);
+    // if i is not primary itself
+    // go through the list of min. ass. primes and find the first
+    // one which has w in its tropical variety
+    if (size(primp)>1)
+    {
+      j1=1;
+      while(winprim==0)
+      {
+        //compute the t-initial of the associated prime
+        // - the last entry 1 only means that t is the last variable in the ring
+        primini=tInitialIdeal(primp[j1],wvec,1);
+        // check if it contains a monomial (resp if the product of var
+        // is in the radical)
+        if (radicalMemberShip(product,primini)==0)
+        {
+          // if w is in the tropical variety of the prime, we take that
+          jideal=primp[j1];
+          setring QUOTRING;
+          dimension=dim(groebner(imap(BASERING,jideal)));//compute its dimension
+          setring BASERING;
+          winprim=1; // and stop the checking
+        }
+        j1=j1+1;  //else we look at the next associated prime
+      }
+    }
+    else
+    {
+      jideal=primp[1]; //if i is primary itself we take its prime instead
+    }
+  }
+  // now we start as a first try to intersect with a hyperplane parallel to
+  // coordinate axes, because this would make our further computations
+  // a lot easier.
+  // We choose a subset of our n variables of size d=dim(ideal).
+  // For each of these
+  // variables, we want to fix a value: x_i= a_i*t^-w_i.
+  // This will only work if the
+  // projection of the d-dim variety to the other n-d variables
+  // is the whole n-d plane.
+  // Then a general choice for a_i will intersect the variety
+  // in finitely many points.
+  // If the projection is not the whole n-d plane,
+  // then a general choice will not work.
+  // We could determine if we picked a good
+  // d-subset of variables using elimination
+  // (NOTE, there EXIST d variables such that
+  // a random choice of a_i's would work!).
+  // But since this involves many computations,
+  // we prefer to choose randomly and just
+  // try in the end if our intersected ideal
+  // satisfies our requirements. If this does not
+  // work, we give up this try and use our second intersection idea, which
+  // will work for a Zariksi-open subset (i.e. almost always).
+  //
+  // As random subset of d variables we choose
+  // those for which the absolute value of the
+  // wvec-coordinate is smallest, because this will
+  // give us the smallest powers of t and hence
+  // less effort in following computations.
+  // Note that the smallest absolute value have those
+  // which are biggest, because wvec is negative.
+  //print("first try");
+  intvec wminust=intvecdelete(wvec,1);
+  intmat A[2][size(wminust)];
+  // make a matrix with first row -wvec (without t) and second row 1..n
+  A[1,1..size(wminust)]=-wminust;
+  A[2,1..size(wminust)]=1..size(wminust);
+  // sort this matrix in order to get
+  // the d biggest entries and their position in wvec
+  A=sortintmat(A);
+  // we construct a vector which has 1 at entry j if j belongs to the list
+  // of the d biggest entries of wvec and a 0 else
+  for (j1=1;j1<=nvars(basering)-1;j1++) //go through the variables
+  {
+    for (j2=1;j2<=dimension;j2++) //go through the list of smallest entries
+    {
+      if (A[2,j2]==j1)//if the variable belongs to this list
+      {
+        setvec[j1]=1;//put a 1
+      }
+    }
+  }
+  // using this 0/1-vector we produce
+  // a random constant (i.e. coeff in Q times something in t)
+  // for each of the biggest variables,
+  // we add the forms x_i-random constant to the ideal
+  // and we save the constant at the i-th place of
+  // a list we want to return for later computations
+  j3=0;
+  while (j3<=1)
+  {
+    j3++;
+    pideal=jideal;
+    j2=1;
+    for (j1=1;j1<=nvars(basering)-1;j1++)
+    {
+      if(setvec[j1]==1)//if x_i belongs to the biggest variables
+      {
+        if ((j3==1) and ((char(basering)==0) or (char(basering)>3)))
+        {
+          randomp1=random(1,3);
+          randomp=t^(A[1,j2])*randomp1;// make a random constant
+                                       // --- first we try small numbers
+        }
+        if ((j3==2) and ((char(basering)==0) or (char(basering)>100)))
+        {
+          randomp1=random(1,100);
+          randomp=t^(A[1,j2])*randomp1;// make a random constant
+                                       // --- next we try bigger numbers
+        }
+        else
+        {
+          randomp1=random(1,char(basering)-1);
+          randomp=t^(A[1,j2])*randomp1;//make a random constant
+        }
+        ergl[A[2,j2]]=randomp;//and save the constant in a list
+        erglini[A[2,j2]]=randomp1;
+        j2=j2+1;
+      }
+      else
+      {
+        ergl[j1]=0; //if the variable is not among the d biggest ones,
+                    //save 0 in the list
+        erglini[j1]=0;
+      }
+    }
+      // print(ergl);print(pideal);
+      // now we check if we made a good choice of pideal, i.e. if dim=0 and
+      // wvec is still in the tropical variety
+      // change to quotring where we compute dimension
+      cutideal=pideal;
+    for(j1=1;j1<=nvars(basering)-1;j1++)
+    {
+      if(setvec[j1]==1)
+      {
+        cutideal=cutideal,var(j1)-ergl[j1];//add all forms to the ideal
+      }
+    }
+    setring QUOTRING;
+    ideal cutideal=imap(BASERING,cutideal);
+    dimp=dim(groebner(cutideal)); //compute the dim of p in the quotring
+    //print("dimension");
+    //print(dimp);
+    kill cutideal;
+    setring BASERING;
+    if (dimp==0) // if it is 0 as we want
+    {
+      // compute the t-initial of the associated prime
+      // - the last 1 just means that the variable t is
+      //   the last variable in the ring
+      pini=tInitialIdeal(cutideal,wvec ,1);
+      //print("initial");
+      //print(pini);
+      // and if the initial w.r.t. t contains no monomial
+      // as we want (checked with
+      // radical-membership of the product of all variables)
+      if (radicalMemberShip(product,pini)==0)
+      {
+        // we made the right choice and now
+        // we substitute the variables in the ideal
+        // to get an ideal in less variables
+        // also we make a projected vector
+        // from wvec only the components of the remaining variables
+        wvecp=wvec;
+        variablen=0;
+        j2=0;
+        for(j1=1;j1<=nvars(basering)-1;j1++)
+        {
+          if(setvec[j1]==1)//if j belongs to the biggest variables
+          {
+            j2=j2+1;
+            pideal=subst(pideal,var(j1),ergl[j1]);//substitute this variable
+            pini=subst(pini,var(j1),erglini[j1]);
+            wvecp=intvecdelete(wvecp,j1+2-j2);
+          }
+          else
+          {
+            variablen=variablen+var(j1); // read the set of remaining variables
+                                         // (needed to make quotring later)
+          }
+        }
+        // return pideal, the initial and the list ergl which tells us
+        // which variables we replaced by which form
+        execute("ring BASERINGLESS1=("+charstr(BASERING)+"),("+string(variablen)+",t),(dp("+string(ncols(variablen))+"),lp(1));");
+        ideal i=imap(BASERING,pideal);
+        ideal ini=imap(BASERING,pini); //ideal ini2=tInitialIdeal(i,wvecp,1);
+        list repl=imap(BASERING,ergl);
+        export(i);
+        export(ini);
+        export(repl);
+        return(list(BASERINGLESS1,wvecp));
+      }
+    }
+  }
+  // this is our second try to cut down, which we only use if the first try
+  // didn't work out. We intersect with d general hyperplanes
+  // (i.e. we don't choose
+  // them to be parallel to coordinate hyperplanes anymore. This works out with
+  // probability 1.
+  //
+  // We choose general hyperplanes, i.e. linear forms which involve all x_i.
+  // Each x_i has to be multiplied bz t^(w_i) in order
+  // to get the same weight (namely 0)
+  // for each term. As we cannot have negative exponents, we multiply
+  // the whole form by t^minimumw. Notice that then in the first form,
+  // there is one term without t- the term of the variable
+  // x_i such that w_i is minimal. That is, we can solve for this variable.
+  // In the second form, we can replace that variable,
+  // and divide by t as much as possible.
+  // Then there is again one term wihtout t -
+  // the term of the variable with second least w.
+  // So we can solve for this one again and also replace it in the first form.
+  // Since all our coefficients are chosen randomly,
+  // we can also from the beginning on
+  // choose the set of variables which belong to the d smallest entries of wvec
+  // (t not counting) and pick random forms g_i(t,x')
+  // (where x' is the set of remaining variables)
+  // and set x_i=g_i(t,x').
+  //
+  // make a matrix with first row wvec (without t) and second row 1..n
+  //print("second try");
+  setring BASERING;
+  A[1,1..size(wminust)]=wminust;
+  A[2,1..size(wminust)]=1..size(wminust);
+  // sort this matrix in otder to get the d smallest entries
+  // (without counting the t-entry)
+  A=sortintmat(A);
+  randomp=0;
+  setvec=0;
+  setvec[nvars(basering)-1]=0;
+  // we construct a vector which has 1 at entry j if j belongs to the list of
+  // the d smallest entries of wvec and a 0 else
+  for (j1=1;j1<=nvars(basering)-1;j1++) //go through the variables
+  {
+    for (j2=1;j2<=dimension;j2++) //go through the list of smallest entries
+    {
+      if (A[2,j2]==j1)//if the variable belongs to this list
+      {
+        setvec[j1]=1;//put a 1
+      }
+    }
+  }
+  variablen=0;
+  wvecp=wvec;
+  j2=0;
+  for(j1=1;j1<=nvars(basering)-1;j1++)
+  {
+    if(setvec[j1]==1)//if j belongs to the biggest variables
+    {
+      j2=j2+1;
+      wvecp=intvecdelete(wvecp,j1+2-j2);// delete the components
+                                        // we substitute from wvec
+    }
+    else
+    {
+      variablen=variablen+var(j1); // read the set of remaining variables
+                                   // (needed to make the quotring later)
+    }
+  }
+  setring BASERING;
+  execute("ring BASERINGLESS2=("+charstr(BASERING)+"),("+string(variablen)+",t),(dp("+string(ncols(variablen))+"),lp(1));");
+  // using the 0/1-vector which tells us which variables belong
+  // to the set of smallest entries of wvec
+  // we construct a set of d random linear
+  // polynomials of the form x_i=g_i(t,x'),
+  // where the set of all x_i is the set of
+  // all variables which are in the list of smallest
+  // entries in wvec, and x' are the other variables.
+  // We add these d random linear polynomials to
+  // the ideal pideal, i.e. we intersect
+  // with these and hope to get something
+  // 0-dim which still contains wvec in its
+  // tropical variety. Also, we produce a list ergl
+  // with g_i at the i-th position.
+  // This is a list we want to return.
+  // we try first with small numbers
+  setring BASERING;
+  pideal=jideal;
+  for(j1=1;j1<=dimension;j1++)//go through the list of variables
+  { // corres to the d smallest in wvec
+    if ((char(basering)==0) or (char(basering)>3))
+    {
+      randomp1=random(1,3);
+      randomp=randomp1*t^(-A[1,j1]);
+    }
+    else
+    {
+      randomp1=random(1,char(basering)-1);
+      randomp=randomp1*t^(-A[1,j1]);
+    }
+    for(j2=1;j2<=nvars(basering)-1;j2++)//go through all variables
+    {
+      if(setvec[j2]==0)//if x_j belongs to the set x'
+      {
+        // add a random term with the suitable power
+        // of t to the random linear form
+        if ((char(basering)==0) or (char(basering)>3))
+        {
+          randomp2=random(1,3);
+          randomp1=randomp1+randomp2*var(j2);
+          randomp=randomp+randomp2*t^(wminust[j2]-A[1,j1])*var(j2);
+        }
+
+        else
+        {
+          randomp2=random(char(basering)-1);
+          randomp1=randomp1+randomp2*var(j2);
+          randomp=randomp+randomp2*t^(wminust[j2]-A[1,j1])*var(j2);
+        }
+        ergl[j2]=0;//if j belongs to x' we want a 0 in our list
+        erglini[j2]=0;
+        }
+    }
+    ergl[A[2,j1]]=randomp;// else we put there the random oly g_i(t,x')
+    erglini[A[2,j1]]=randomp1;
+    randomp=0;
+    randomp1=0;
+    }
+  //print(ergl);
+  // Again, we have to test if we made a good choice
+  // to intersect,i.e. we have to check whether
+  // pideal is 0-dim and contains wvec in the tropical variety.
+  cutideal=pideal;
+  for(j1=1;j1<=nvars(basering)-1;j1++)
+  {
+    if(setvec[j1]==1)
+    {
+      cutideal=cutideal,var(j1)-ergl[j1];//add all forms to the ideal
+    }
+  }
+  setring QUOTRING;
+  ideal cutideal=imap(BASERING,cutideal);
+  dimp=dim(groebner(cutideal)); //compute the dim of p in the quotring
+  //print("dimension");
+  //print(dimp);
+  kill cutideal;
+  setring BASERING;
+  if (dimp==0) // if it is 0 as we want
+  {
+    // compute the t-initial of the associated prime
+    // - the last 1 just means that the variable t
+    // is the last variable in the ring
+    pini=tInitialIdeal(cutideal,wvec ,1);
+    //print("initial");
+    //print(pini);
+    // and if the initial w.r.t. t contains no monomial as we want (checked with
+    // radical-membership of the product of all variables)
+    if (radicalMemberShip(product,pini)==0)
+    {
+      // we want to replace the variables x_i by the forms -g_i in
+      // our ideal in order to return an ideal with less variables
+      // first we substitute the chosen variables
+      for(j1=1;j1<=nvars(basering)-1;j1++)
+      {
+        if(setvec[j1]==1)//if j belongs to the biggest variables
+        {
+          pideal=subst(pideal,var(j1),ergl[j1]);//substitute it
+          pini=subst(pini,var(j1),erglini[j1]);
+        }
+      }
+      setring BASERINGLESS2;
+      ideal i=imap(BASERING,pideal);
+      ideal ini=imap(BASERING,pini);//ideal ini2=tInitialIdeal(i,wvecp,1);
+      list repl=imap(BASERING,ergl);
+      export(i);
+      export(ini);
+      export(repl);
+      return(list(BASERINGLESS2,wvecp));
+    }
+  }
+  // now we try bigger numbers
+  while (1) //a never-ending loop which will stop with prob. 1
+  { // as we find a suitable ideal with that prob
+    setring BASERING;
+    pideal=jideal;
+    for(j1=1;j1<=dimension;j1++)//go through the list of variables
+    { // corres to the d smallest in wvec
+      randomp1=random(1,100);
+      randomp=randomp1*t^(-A[1,j1]);
+      for(j2=1;j2<=nvars(basering)-1;j2++)//go through all variables
+      {
+        if(setvec[j2]==0)//if x_j belongs to the set x'
+        {
+          // add a random term with the suitable power
+          // of t to the random linear form
+          if ((char(basering)==0) or (char(basering)>100))
+          {
+            randomp2=random(1,100);
+            randomp1=randomp1+randomp2*var(j2);
+            randomp=randomp+randomp2*t^(wminust[j2]-A[1,j1])*var(j2);
+          }
+          else
+          {
+            randomp2=random(1,char(basering)-1);
+            randomp1=randomp1+randomp2;
+            randomp=randomp+randomp2*t^(wminust[j2]-A[1,j1])*var(j2);
+          }
+          ergl[j2]=0;//if j belongs to x' we want a 0 in our list
+          erglini[j2]=0;
+          }
+      }
+      ergl[A[2,j1]]=randomp;// else we put there the random oly g_i(t,x')
+      erglini[A[2,j1]]=randomp1;
+      randomp=0;
+      randomp1=0;
+      }
+    //print(ergl);
+    // Again, we have to test if we made a good choice to
+    // intersect,i.e. we have to check whether
+    // pideal is 0-dim and contains wvec in the tropical variety.
+    cutideal=pideal;
+    for(j1=1;j1<=nvars(basering)-1;j1++)
+    {
+      if(setvec[j1]==1)
+      {
+        cutideal=cutideal,var(j1)-ergl[j1];//add all forms to the ideal
+      }
+    }
+    setring QUOTRING;
+    ideal cutideal=imap(BASERING,cutideal);
+    dimp=dim(groebner(cutideal)); //compute the dim of p in the quotring
+    //print("dimension");
+    //print(dimp);
+    kill cutideal;
+    setring BASERING;
+    if (dimp==0) // if it is 0 as we want
+    {
+      // compute the t-initial of the associated prime
+      // - the last 1 just means that the variable t
+      // is the last variable in the ring
+      pini=tInitialIdeal(cutideal,wvec ,1);
+      //print("initial");
+      //print(pini);
+      // and if the initial w.r.t. t contains no monomial
+      // as we want (checked with
+      // radical-membership of the product of all variables)
+      if (radicalMemberShip(product,pini)==0)
+      {
+        // we want to replace the variables x_i by the forms -g_i in
+        // our ideal in order to return an ideal with less variables
+        //first we substitute the chosen variables
+        for(j1=1;j1<=nvars(basering)-1;j1++)
+        {
+          if(setvec[j1]==1)//if j belongs to the biggest variables
+          {
+            pideal=subst(pideal,var(j1),ergl[j1]);//substitute it
+            pini=subst(pini,var(j1),erglini[j1]);
+          }
+        }
+        // return pideal and the list ergl which tells us
+        // which variables we replaced by which form
+        setring BASERINGLESS2;
+        ideal i=imap(BASERING,pideal);
+        ideal ini=imap(BASERING,pini);//ideal ini2=tInitialIdeal(i,wvecp,1);
+        list repl=imap(BASERING,ergl);
+        export(i);
+        export(ini);
+        export(repl);
+        return(list(BASERINGLESS2,wvecp));
+      }
+    }
+  }
+}
+
+
+/////////////////////////////////////////////////////////////////////////
+
+static proc tropicalparametriseNoabs (ideal i,intvec ww,int ordnung,int gfanold,int nogfan,int puiseux,list #)
+"USAGE:  tropicalparametriseNoabs(i,tw,ord,gf,ng,pu[,#]); i ideal, tw intvec, ord int, gf,ng,pu int, # opt. list
+ASSUME:  - i is an ideal in Q[t,x_1,...,x_n,X_1,...,X_k],
+           tw=(w_0,w_1,...,w_n,0,...,0) and (w_0,...,w_n,0,...,0) is in
+           the tropical variety of i, and ord is the order up to which a point
+           in V(i) over C((t)) lying over w shall be computed;
+         - moreover, k should be zero if the procedure is not called recursively;
+         - the point in the tropical variety is supposed to lie in the NEGATIVE
+           orthant;
+         - the ideal is zero-dimensional when considered
+           in (Q(t)[X_1,...,X_k]/m)[x_1,...,x_n],
+           where m=#[2] is a maximal ideal in Q(t)[X_1,...,X_k];
+         - gf is 0 if version 2.2 or larger is used and it is 1 else
+         - ng is 1 if gfan should not be executed
+         - pu is 1 if n=1 and i is generated by one polynomial and newtonpoly is used to find a
+           point in the tropical variety instead of gfan
+RETURN:  list, l[1] = ring Q(0,X_1,...,X_r)[[t]]
+               l[2] = int
+               l[3] = string
+NOTE:    - the procedure is also called recursively by itself, and
+           if it is called in the first recursion, the list # is empty,
+           otherwise #[1] is an integer, one more than the number
+           of true variables x_1,...,x_n,
+           and #[2] will contain the maximal ideal m in the variables X_1,...X_k
+           by which the ring Q[t,x_1,...,x_n,X_1,...,X_k] should be divided to
+           work correctly in K[t,x_1,...,x_n] where K=Q[X_1,...,X_k]/m is a field
+           extension of Q;
+         - the ring l[1] contains an ideal PARA, which contains the
+           parametrisation of a point in V(i) lying over w up to the
+           first ord terms;
+         - the string m=l[3] contains the code of the maximal ideal m,
+           by which we have to divide Q[X_1,...,X_r] in order to have
+           the appropriate field extension over which the parametrisation lives;
+         - and if the integer l[2] is N then t has to be replaced by t^1/N in
+           the parametrisation, or alternatively replace t by t^N in the
+           defining ideal
+         - the procedure REQUIRES that the program GFAN is installed on
+           your computer"
+{
+  def ALTRING=basering;
+  int recursively; // is set 1 if the procedure is called recursively by itself
+  int jj,kk;
+  if (size(#)==2) // this means the precedure has been called recursively
+  {
+    // how many variables are true variables, and how many come
+    // from the field extension
+    // only true variables have to be transformed
+    int anzahlvariablen=#[1];
+    ideal gesamt_m=std(#[2]); // stores all maxideals used for field extensions
+    // find the zeros of the w-initial ideal and transform the ideal i;
+    // findzeros and basictransformideal need to know how
+    // many of the variables are true variables
+    list m_ring=findzeros(i,ww,anzahlvariablen);
+    list btr=basictransformideal(i,ww,m_ring,anzahlvariablen);
+  }
+  else // the procedure has been called by tropicalLifting
+  {
+    // how many variables are true variables, and how many come from
+    // the field extension only true variables have to be transformed
+    int anzahlvariablen=nvars(basering);
+    ideal gesamt_m; // stores all maxideals used for field extensions
+    // the initial ideal of i has been handed over as #[1]
+    ideal ini=#[1];
+    // find the zeros of the w-initial ideal and transform the ideal i;
+    // we should hand the t-initial ideal ine to findzeros,
+    // since we know it already
+    list m_ring=findzeros(i,ww,ini);
+    list btr=basictransformideal(i,ww,m_ring);
+  }
+  // check if for the transformation a field extension was necessary, i.e. if the
+  // new variables had to be added to the old base ring; if so, change to the new
+  // ring in which the transformed i and m and the zero a of V(m) live; otherwise
+  // retreive i, a and m from btr
+  if (size(btr)==1)
+  {
+    def PREVIOUSRING=basering;
+    def TRRING=btr[1];
+    setring TRRING;
+    ideal gesamt_m=imap(PREVIOUSRING,gesamt_m)+m; // add the newly found maximal
+                                                  // ideal to the previous ones
+  }
+  else
+  {
+    i=std(btr[1]);
+    list a=btr[2];
+    ideal m=btr[3];
+    gesamt_m=gesamt_m+m; // add the newly found maximal
+                         // ideal to the previous ones
+  }
+  // check if there is a solution which has the n-th component zero,
+  // if so, then eliminate the n-th variable from sat(i+x_n,t),
+  // otherwise leave i as it is;
+  // then check if the (remaining) ideal has as solution
+  // where the n-1st component is zero,
+  // and procede as before; do the same for the remaining variables;
+  // this way we make sure that the remaining ideal has
+  // a solution which has no component zero;
+  intvec deletedvariables;    // the jth entry is set 1, if we eliminate x_j
+  int numberdeletedvariables; // the number of eliminated variables
+  ideal variablen;  // will contain the variables which are not eliminated
+  intvec tw=ww;     // in case some variables are deleted,
+                    // we have to store the old weight vector
+  deletedvariables[anzahlvariablen]=0;
+  ideal I,LI;
+  i=i+m; // if a field extension was necessary, then i has to be extended by m
+  for (jj=anzahlvariablen-1;jj>=1;jj--)  // the variable t is the last one !!!
+  {
+    I=sat(ideal(var(jj)+i),t)[1];
+    LI=subst(I,var(nvars(basering)),0);
+    //size(deletedvariables)=anzahlvariablen(before elim.)
+    for (kk=1;kk<=size(deletedvariables)-1;kk++)
+    {
+      LI=subst(LI,var(kk),0);
+    }
+    if (size(LI)==0) // if no power of t is in lead(I)
+    { // (where the X(i) are considered as field elements)
+      // get rid of var(jj)
+      i=eliminate(I,var(jj));
+      deletedvariables[jj]=1;
+      anzahlvariablen--; // if a variable is eliminated,
+                         // then the number of true variables drops
+      numberdeletedvariables++;
+    }
+    else
+    {
+      variablen=variablen+var(jj); // non-eliminated true variables are stored
+    }
+  }
+  variablen=invertorder(variablen);
+  // store also the additional variables and t,
+  // since they for sure have not been eliminated
+  for (jj=anzahlvariablen+numberdeletedvariables-1;jj<=nvars(basering);jj++)
+  {
+    variablen=variablen+var(jj);
+  }
+  // if some variables have been eliminated,
+  // then pass to a new ring which has less variables,
+  // but if no variables are left, then we are done
+  def BASERING=basering;
+  if ((numberdeletedvariables>0) and (anzahlvariablen>1)) // if only t remains,
+  { // all true variables are gone
+    execute("ring NEURING=("+charstr(basering)+"),("+string(variablen)+"),(dp("+string(size(variablen)-1)+"),lp(1));");
+    ideal i=imap(BASERING,i);
+    ideal gesamt_m=imap(BASERING,gesamt_m);
+  }
+  // now we have to compute a point ww on the tropical variety
+  // of the transformed ideal i;
+  // of course, we only have to do so, if we have not yet
+  // reached the order up to which we
+  // were supposed to do our computations
+  if ((ordnung>1) and (anzahlvariablen>1)) // if only t remains,
+  { // all true variables are gone
+    // else we have to use gfan
+    def PREGFANRING=basering;
+    if (nogfan!=1)
+    {
+      // pass to a ring which has variables which are suitable for gfan
+      execute("ring GFANRING=("+charstr(basering)+"),(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z),dp;");
+      ideal phiideal=b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z;
+      phiideal[nvars(PREGFANRING)]=a; // map t to a
+      map phi=PREGFANRING,phiideal;
+      ideal i=phi(i);
+      // homogenise the ideal i with the first not yet
+      // used variable in our ring, since gfan
+      // only handles homogenous ideals; in principle
+      // for this one has first to compute a
+      // standard basis of i and homogenise that,
+      // but for the tropical variety (says Anders)
+      // it suffices to homogenise an arbitrary system of generators
+      // i=groebner(i);
+      i=homog(i,maxideal(1)[nvars(PREGFANRING)+1]);
+      // if gfan version >= 0.3.0 is used and the characteristic
+      // is not zero, then write the basering to the output
+      if ((gfanold!=1) and (char(GFANRING)!=0))
+      {
+        string ringvariablen=varstr(GFANRING);
+        ringvariablen=ringvariablen[1..2*nvars(PREGFANRING)+1];
+        write(":w /tmp/gfaninput","Z/"+string(char(GFANRING))+"Z["+ringvariablen+"]");
+        // write the ideal to a file which gfan takes as input and call gfan
+        write(":a /tmp/gfaninput","{"+string(i)+"}");
+      }
+      else
+      {
+        // write the ideal to a file which gfan takes as input and call gfan
+        write(":w /tmp/gfaninput","{"+string(i)+"}");
+      }
+      if (gfanold==1)
+      {
+        if (charstr(basering)!="0")
+        {
+          system("sh","gfan_tropicalbasis --mod "+charstr(basering)+" < /tmp/gfaninput > /tmp/gfanbasis");
+          system("sh","gfan_tropicalintersection < /tmp/gfanbasis > /tmp/gfanoutput");
+        }
+        else
+        {
+//          system("sh","gfan_tropicalstartingcone < /tmp/gfaninput > /tmp/gfantropstcone");
+//          system("sh","gfan_tropicaltraverse < /tmp/gfantropstcone > /tmp/gfanoutput");
+          system("sh","gfan_tropicalbasis < /tmp/gfaninput > /tmp/gfanbasis");
+          system("sh","gfan_tropicalintersection < /tmp/gfanbasis > /tmp/gfanoutput");
+        }
+        string trop=read("/tmp/gfanoutput");
+        setring PREGFANRING;
+        intvec wneu=-1;    // this integer vector will store
+                           // the point on the tropical variety
+        wneu[nvars(basering)]=0;
+        // for the time being simply stop Singular and set wneu by yourself
+        int goon=1;
+        trop;
+        "CHOOSE A RAY IN THE OUTPUT OF GFAN WHICH HAS ONLY";
+        "NON-POSITIVE ENTRIES AND STARTS WITH A NEGATIVE ONE,";
+        "E.G. (-3,-4,-1,-5,0,0,0) - the last entry will always be 0 -";
+        "THEN TYPE THE FOLLOWING COMMAND IN SINGULAR:   wneu=-3,-4,-1,-5,0,0;";
+        "AND HIT THE RETURN BUTTON TWICE (!!!) - NOTE, THE LAST 0 IS OMITTED";
+        "IF YOU WANT wneu TO BE TESTED, THEN SET goon=0;";
+
+        // THIS IS NOT NECESSARY !!!! IF WE COMPUTE NOT ONLY THE
+        // TROPICAL PREVARIETY
+        // test, if wneu really is in the tropical variety
+        while (goon==0)
+        {
+          if (testw(reduce(i,std(gesamt_m)),wneu,anzahlvariablen)==1)
+          {
+            "CHOOSE A DIFFERENT RAY";
+
+          }
+          else
+          {
+            goon=1;
+          }
+        }
+      }
+      else
+      {
+        system("sh","gfan_tropicallifting -n "+string(anzahlvariablen)+" --noMult -c < /tmp/gfaninput > /tmp/gfanoutput");
+        // read the result from gfan and store it to a string,
+        // which in a later version
+        // should be interpreded by Singular
+        intvec wneu=choosegfanvector(read("/tmp/gfanoutput"),0)[1];
+        setring PREGFANRING;
+      }
+    }
+    else // if gfan is NOT executed
+    {
+      // if puiseux is set, then we are in the case of a plane curve and can use the command newtonpoly
+      if (puiseux==1)
+      {
+        list NewtP=newtonpoly(i[1]);
+        wneu=NewtP[1]-NewtP[2];
+        int ggteiler=gcd(wneu[1],wneu[2]);
+        wneu[1]=-wneu[1] div ggteiler;
+        wneu[2]=wneu[2] div ggteiler;
+        if (wneu[1]>0)
+        {
+          wneu=-wneu;
+        }
+        kill NewtP,ggteiler;
+      }
+      else // set wneu by hand
+      {
+        "Set intvec wneu!";
+
+      }
+    }
+  }
+  // if we have not yet computed our parametrisation
+  // up to the required order and
+  // zero is not yet a solution, then we have
+  // to go on by calling the procedure recursively;
+  // if all variables were deleted, then i=0 and thus anzahlvariablen==0
+  if ((ordnung>1) and (anzahlvariablen>1))
+  {
+    // we call the procedure with the transformed ideal i,
+    // the new weight vector, with the
+    // required order lowered by one, and with
+    // additional parameters, namely the number of
+    // true variables and the maximal ideal that
+    // was computed so far to describe the field extension
+    list PARALIST=tropicalparametriseNoabs(i,wneu,ordnung-1,gfanold,nogfan,puiseux,anzahlvariablen,gesamt_m);
+    // the output will be a ring, in which the
+    // parametrisation lives, and a string, which contains
+    // the maximal ideal that describes the necessary field extension
+    def PARARing=PARALIST[1];
+    int tweight=-tw[1]*PARALIST[2];
+    string PARAm=PARALIST[3];
+    setring PARARing;
+    // if some variables have been eliminated in before,
+    // then we have to insert zeros
+    // into the parametrisation for those variables
+    if (numberdeletedvariables>0)
+    {
+      ideal PARAneu=PARA;
+      int k;
+      for (jj=1;jj<=anzahlvariablen+numberdeletedvariables-1;jj++) // t admits
+      { // no parametrisation
+        if (deletedvariables[jj]!=1)
+        {
+          k++;
+          PARA[jj]=PARAneu[k];
+        }
+        else
+        {
+          PARA[jj]=poly(0);
+        }
+      }
+    }
+  }
+  // otherwise we are done and we can start to compute
+  // the last step of the parametrisation
+  else
+  {
+    // we store the information on m in a string
+    string PARAm=string(gesamt_m);
+    // we define the weight of t, i.e. in the parametrisation t
+    // has to be replaced by t^1/tweight
+    int tweight=-tw[1];
+    // if additional variables were necessary,
+    // we introduce them now as parameters;
+    // in any case the parametrisation ring will
+    // have only one variable, namely t,
+    // and its order will be local, so that it
+    // displays the lowest term in t first
+    if (anzahlvariablen+numberdeletedvariables<nvars(basering))
+    {
+      execute("ring PARARing=("+charstr(basering)+",X("+string(1)+".."+string(nvars(basering)-anzahlvariablen-numberdeletedvariables)+")),t,ls;");
+    }
+    else
+    {
+      execute("ring PARARing=("+charstr(basering)+"),t,ls;");
+    }
+    ideal PARA; // will contain the parametrisation
+    // we start by initialising the entries to be zero;
+    // one entry for each true variable
+    // here we also have to consider the variables
+    // that we have eliminated in before
+    for (jj=1;jj<=anzahlvariablen+numberdeletedvariables-1;jj++)
+    {
+      PARA[jj]=poly(0);
+    }
+  }
+  // we now have to change the parametrisation by
+  // reverting the transformations that we have done
+  list a=imap(BASERING,a);
+  if (defined(wneu)==0) // when tropicalparametriseNoabs is called for the
+  { // last time, it does not enter the part, where wneu is defined and the
+    intvec wneu=-1;     // variable t should have weight -1
+  }
+  for (jj=1;jj<=anzahlvariablen+numberdeletedvariables-1;jj++)
+  {
+    PARA[jj]=(PARA[jj]+a[jj+1])*t^(tw[jj+1]*tweight div ww[1]);
+  }
+  // if we have reached the stop-level, i.e. either
+  // we had only to compute up to order 1
+  // or zero was a solution of the ideal, then we have
+  // to export the computed parametrisation
+  // otherwise it has already been exported before
+  // note, if all variables were deleted, then i==0 and thus testaufnull==0
+  if ((ordnung==1) or (anzahlvariablen==1))
+  {
+    export(PARA);
+  }
+  // kill the gfan files in /tmp
+  system("sh","cd /tmp; /usr/bin/touch gfaninput; /usr/bin/touch gfanoutput; /bin/rm gfaninput; /bin/rm gfanoutput");
+  // we return a list which contains the
+  // parametrisation ring (with the parametrisation ideal)
+  // and the string representing the maximal ideal
+  // describing the necessary field extension
+  return(list(PARARing,tweight,PARAm));
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+static proc findzeros (ideal i,intvec w,list #)
+"USAGE:      findzeros(i,w[,#]); i ideal, w intvec, # an optional list
+ASSUME:      i is an ideal in Q[t,x_1,...,x_n,X_n+1,...,X_m] and
+             w=(w_0,...,w_n,0,...,0) is in the tropical variety of i
+RETURN:      list, l[1] = is polynomial ring containing an associated maximal
+                          ideal m of the w-initial ideal of i which does not
+                          contain any monomial and where the variables
+                          which do not lead to a field extension have already
+                          been eliminated, and containing a list a such that
+                          the non-zero entries of a correspond to the values
+                          of the zero of the associated maximal ideal for the
+                          eliminated variables
+                   l[2] = number of variables which have not been eliminated
+                   l[3] = intvec, if the entry is one then the corresponding
+                                  variable has not been eliminated
+NOTE:        the procedure is called from inside the recursive procedure
+             tropicalparametriseNoabs;
+             if it is called in the first recursion, the list #[1] contains
+             the t-initial ideal of i w.r.t. w, otherwise #[1] is an integer,
+             one more than the number of true variables x_1,...,x_n"
+{
+  def BASERING=basering;
+  // set anzahlvariablen to the number of true variables
+  if (typeof(#[1])=="int")
+  {
+    int anzahlvariablen=#[1];
+    // compute the initial ideal of i
+    // - the last 1 just means that the variable t is the last
+    //   variable in the ring
+    ideal ini=tInitialIdeal(i,w,1);
+  }
+  else
+  {
+    int anzahlvariablen=nvars(basering);
+    ideal ini=#[1]; // the t-initial ideal has been computed
+                    // in before and was handed over
+  }
+  // move to a polynomial ring with global monomial ordering
+  // - the variable t is superflous
+  ideal variablen;
+  for (int j=1;j<=nvars(basering)-1;j++)
+  {
+    variablen=variablen+var(j);
+  }
+  execute("ring INITIALRING=("+charstr(basering)+"),("+string(variablen)+"),dp;");
+  ideal ini=imap(BASERING,ini);
+  // compute the associated primes of the initialideal
+  // ordering the maximal ideals shall help to avoid
+  // unneccessary field extensions
+  list maximalideals=ordermaximalidealsNoabs(minAssGTZ(std(ini)),anzahlvariablen);
+  ideal m=maximalideals[1][1];              // the first associated maximal ideal
+  int neuvar=maximalideals[1][2];           // the number of new variables needed
+  intvec neuevariablen=maximalideals[1][3]; // the information which variable
+                                            // leads to a new one
+  list a=maximalideals[1][4];               // a_k is the kth component of a
+                                            // zero of m, if it is not zero
+  // eliminate from m the superflous variables, that is those ones,
+  // which do not lead to a new variable
+  poly elimvars=1;
+  for (j=1;j<=anzahlvariablen-1;j++)
+  {
+    if (neuevariablen[j+1]==0)
+    {
+      elimvars=elimvars*var(j);
+    }
+  }
+  m=eliminate(m,elimvars);
+  export(a);
+  export(m);
+  list m_ring=INITIALRING,neuvar,neuevariablen;
+  setring BASERING;
+  return(m_ring);
+}
+
+
+/////////////////////////////////////////////////////////////////////////
+
+static proc basictransformideal (ideal i,intvec w,list m_ring,list #)
+"USAGE:  basictransformideal(i,w,m_ring[,#]); i ideal, w intvec, m_ring list, # an optional list
+ASSUME:  i is an ideal in Q[t,x_1,...,x_n,X_1,...,X_k],
+         w=(w_0,...,w_n,0,...,0) is in the tropical variety of i, and
+         m_ring contains a ring containing a maximal ideal m needed
+         to describe the field extension over which a corresponding
+         associated maximal ideal of the initialideal of i, considered
+         in (Q[X_1,...,X_k]/m_alt)(t)[x_1,...,x_n], has a zero, and
+         containing a list a describing the zero of m, and m_ring contains
+         the information how many new variables are needed for m
+RETURN:  list, either l[1] = ideal, i transformed by x_j -> (a_j+x_j)*t^w_j
+                      l[2] = list,  a_1,...,a_n a point in V(m)
+                      l[3] = ideal, the maximal ideal m
+               or l[1] = ring which contains the ideals i and m, and the list a
+NOTE:    the procedure is called from inside the recursive procedure
+         tropicalparametriseNoabs;
+         if it is called in the first recursion, the list # is empty,
+         otherwise #[1] is an integer, the number of true variables x_1,...,x_n;
+         during the procedure we check if a field extension is necessary
+         to express a zero (a_1,...,a_n) of m; if so, we have to introduce
+         new variables and a list containing a ring is returned, otherwise
+         the list containing i, a and m is returned;
+         the ideal m will be changed during the procedure since all variables
+         which reduce to a polynomial in X_1,...,X_k modulo m will be eliminated,
+         while the others are replaced by new variables X_k+1,...,X_k'"
+{
+  def BASERING=basering;  // the variable t is acutally the LAST variable !!!
+  int j,k;     // counters
+  // store the weighted degrees of the elements of i in an integer vector
+  intvec wdegs;
+  for (j=1;j<=size(i);j++)
+  {
+    wdegs[j]=deg(i[j],intvec(w[2..size(w)],w[1]));
+  }
+  // how many variables are true variables,
+  // and how many come from the field extension
+  // only real variables have to be transformed
+  if (size(#)>0)
+  {
+    int anzahlvariablen=#[1];
+  }
+  else
+  {
+    int anzahlvariablen=nvars(basering);
+  }
+  //
+  int zaehler; // testvariable
+  // get the information if any new variables are needed from m_ring
+  int neuvar=m_ring[2];  // number of variables which have to be added
+  intvec neuevariablen=m_ring[3];  // [i]=1, if for the ith comp.
+                                   // of a zero of m a new variable is needed
+  def MRING=m_ring[1];   // MRING contains a and m
+  list a=imap(MRING,a);  // (a_1,...,a_n)=(a[2],...,a[n+1]) will be
+                         // a common zero of the ideal m
+  ideal m=std(imap(MRING,m)); // m is zero, if neuvar==0,
+                              // otherwise we change the ring anyway
+  // if a field extension is needed, then extend the polynomial
+  // ring by new variables X_k+1,...,X_k';
+  if (neuvar>0)
+  {
+    // change to a ring where for each variable needed
+    // in m a new variable has been introduced
+    ideal variablen;
+    // extract the variables x_1,...,x_n
+    for (j=1;j<nvars(basering);j++)
+    {
+      variablen=variablen+var(j);
+    }
+    execute("ring TRANSFORMRING=("+charstr(basering)+"),("+string(variablen)+",X("+string(nvars(BASERING)-anzahlvariablen+1)+".."+string(nvars(BASERING)-anzahlvariablen+neuvar)+"),t),(dp("+string(anzahlvariablen-1)+"),dp("+string(nvars(BASERING)+neuvar-anzahlvariablen)+"),lp(1));");
+    // map i into the new ring
+    ideal i=imap(BASERING,i);
+    // define a map phi which maps the true variables, which are not
+    // reduced to polynomials in the additional variables modulo m, to
+    // the corresponding newly introduced variables, and which maps
+    // the old additional variables to themselves
+    ideal phiideal;
+    k=1;
+    for (j=2;j<=size(neuevariablen);j++)  // starting with 2, since the
+    { // first entry corresponds to t
+      if(neuevariablen[j]==1)
+      {
+        phiideal[j-1]=var(nvars(BASERING)+k-1);  // -1 since t is the last variable
+        k++;
+      }
+      else
+      {
+        phiideal[j-1]=0;
+      }
+    }
+    if (anzahlvariablen<nvars(BASERING))
+    {
+      phiideal=phiideal,X(1..nvars(BASERING)-anzahlvariablen);
+    }
+    map phi=MRING,phiideal;
+    // map m and a to the new ring via phi, so that the true variables
+    // in m and a are replaced by
+    // the corresponding newly introduced variables
+    ideal m=std(phi(m));
+    list a=phi(a);
+  }
+  // replace now the zeros among the a_j by the corresponding
+  // newly introduced variables;
+  // note that no component of a can be zero
+  // since the maximal ideal m contains no variable!
+  // moreover, substitute right away in the ideal i
+  // the true variable x_j by (a_j+x_j)*t^w_j
+  zaehler=nvars(BASERING)-anzahlvariablen+1;
+  for (j=1;j<=anzahlvariablen;j++)
+  {
+    if ((a[j]==0) and (j!=1))  // a[1]=0, since t->t^w_0
+    {
+      a[j]=X(zaehler);
+      zaehler++;
+    }
+    for (k=1;k<=size(i);k++)
+    {
+      if (j!=1) // corresponds to  x_(j-1) --  note t is the last variable
+      {
+        i[k]=substitute(i[k],var(j-1),(a[j]+var(j-1))*t^(-w[j]));
+      }
+      else // corresponds to t
+      {
+        i[k]=substitute(i[k],t,t^(-w[j]));
+      }
+    }
+  }
+  // we can divide the jth generator of i by t^-wdegs[j]
+  for (j=1;j<=ncols(i);j++)
+  {
+    if (wdegs[j]<0) // if wdegs[j]==0 there is no need to divide, and
+    { // we made sure that it is no positive
+      i[j]=i[j]/t^(-wdegs[j]);
+    }
+  }
+  // since we want to consider i now in the ring
+  // (Q[X_1,...,X_k']/m)[t,x_1,...,x_n]
+  // we can  reduce i modulo m, so that "constant terms"
+  // which are "zero" since they
+  // are in m will disappear; simplify(...,2) then really removes them
+  i=simplify(reduce(i,m),2);
+  // if new variables have been introduced, we have
+  // to return the ring containing i, a and m
+  // otherwise we can simply return a list containing i, a and m
+  if (neuvar>0)
+  {
+    export(m);
+    export(i);
+    export(a);
+    list returnlist=TRANSFORMRING;
+    return(returnlist);
+  }
+  else
+  {
+    return(list(i,a,m));
+  }
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+static proc testw (ideal i,intvec w,int anzahlvariablen,list #)
+"USAGE:      testw(i,w,n); i ideal, w intvec, n number
+ASSUME:      i is an ideal in Q[t,x_1,...,x_n,X_1,...,X_k] and
+             w=(w_0,...,w_n,0,...,0)
+RETURN:      int b, 0 if the t-initial ideal of i considered in
+                    Q(X_1,...,X_k)[t,x_1,...,x_n] is monomial free, 1 else
+NOTE:        the procedure is called by tinitialform"
+{
+  // compute the t-initial of i
+  // - the last 1 just means that the variable t is the last variable in the ring
+  if (size(#)==0)
+  {
+    ideal tin=tInitialIdeal(i,w);
+  }
+  else
+  {
+    ideal tin=tInitialIdeal(i,w,1);
+  }
+
+  int j;
+  ideal variablen;
+  poly monom=1;
+  if (size(#)==0)
+  {
+    for (j=2;j<=anzahlvariablen;j++)
+    {
+      variablen=variablen+var(j);
+      monom=monom*var(j);
+    }
+    ideal Parameter;
+    for (j=anzahlvariablen+1;j<=nvars(basering);j++)
+    {
+      Parameter=Parameter+var(j);
+    }
+  }
+  else
+  {
+    for (j=1;j<=anzahlvariablen-1;j++)
+    {
+      variablen=variablen+var(j);
+      monom=monom*var(j);
+    }
+    ideal Parameter;
+    for (j=anzahlvariablen;j<=nvars(basering)-1;j++)
+    {
+      Parameter=Parameter+var(j);
+    }
+  }
+  def BASERING=basering;
+  if (anzahlvariablen<nvars(basering))
+  {
+    execute("ring TINRING=("+charstr(basering)+","+string(Parameter)+"),("+string(variablen)+"),dp;");
+  }
+  else
+  {
+    execute("ring TINRING=("+charstr(basering)+"),("+string(variablen)+"),dp;");
+  }
+  ideal tin=imap(BASERING,tin);
+  poly monom=imap(BASERING,monom);
+  return(radicalMemberShip(monom,tin));
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+static proc simplifyToOrder (poly f)
+"USAGE:      simplifyToOrder(f); f a polynomial
+ASSUME:      f is a polynomial in Q(t)[x_1,...,x_n]
+RETURN:      list, l[1] = t-order of leading term of f
+                   l[2] = the rational coefficient of the term of lowest t-order
+                          in lead(f)
+NOTE:        the procedure is called by tInitialFormPar"
+{
+  string denom=string(denominator(leadcoef(f)));
+  string num=string(numerator(leadcoef(f)));
+  string PMet=string(par(1));
+  def BASERING=basering;
+  execute("ring r=0,"+PMet+",ls;");
+  execute("poly denomi="+denom+";");
+  execute("poly numer="+num+";");
+  int ordnung=ord(numer)-ord(denomi);
+  string koeffizient=string(leadcoef(numer)/leadcoef(denomi));
+  setring BASERING;
+  return(list(ordnung,koeffizient));
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+static proc scalarproduct (intvec w,intvec v)
+"USAGE:      scalarproduct(w,v); w,v intvec
+ASSUME:      w and v are integer vectors of the same length
+RETURN:      int, the scalarproduct of v and w
+NOTE:        the procedure is called by tropicalparametriseNoabs"
+{
+  int sp;
+  for (int i=1;i<=size(w);i++)
+  {
+    sp=sp+v[i]*w[i];
+  }
+  return(sp);
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+static proc intvecdelete (intvec w,int i)
+"USAGE:      intvecdelete(w,i); w intvec, i int
+RETURN:      intvec, the integer vector w with the ith component deleted
+NOTE:        the procedure is called by tropicalparametriseNoabs"
+{
+  if ((i<1) or (i>size(w)) or (size(w)==1))
+  {
+    return(w);
+  }
+  if (i==1)
+  {
+    return(w[2..size(w)]);
+  }
+  if (i==size(w))
+  {
+    return(w[1..size(w)-1]);
+  }
+  else
+  {
+    intvec erg=w[1..i-1],w[i+1..size(w)];
+    return(erg);
+  }
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+static proc invertorder (ideal i)
+"USAGE:      intvertorder(i); i ideal
+RETURN:      ideal, the order of the entries of i has been inverted
+NOTE:        the procedure is called by tropicalparametriseNoabs"
+{
+  ideal ausgabe;
+  for (int j=size(i);j>=1;j--)
+  {
+    ausgabe[size(i)-j+1]=i[j];
+  }
+  return(ausgabe);
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+static proc ordermaximalidealsNoabs (list minassi,int anzahlvariablen)
+"USAGE:      ordermaximalidealsNoabs(minassi); minassi list
+ASSUME:      minassi is a list of maximal ideals
+RETURN:      list, the procedure orders the maximal ideals in minassi according
+                   to how many new variables are needed to describe the zeros
+                   of the ideal
+                   l[j][1] = jth maximal ideal
+                   l[j][2] = the number of variables needed
+                   l[j][3] = intvec, if for the kth variable a new variable is
+                                     needed to define the corresponding zero of
+                                     l[j][1], then the k+1st entry is one
+                   l[j][4] = list, if for the kth variable no new variable is
+                                   needed to define the corresponding zero of
+                                   l[j][1], then its value is the k+1st entry
+NOTE:        if a maximal ideal contains a variable, it is removed from the list;
+             the procedure is called by findzeros"
+{
+  int j,k,l;
+  int neuvar;        // number of new variables needed (for each maximal ideal)
+  int pruefer;       // is set one if a maximal ideal contains a variable
+  list minassisort;  // will contain the output
+  for (j=1;j<=size(minassi);j++){minassisort[j]=0;} // initialise minassisort
+                                                    // to fix its initial length
+  list zwischen;     // needed for reordering
+  list a;// (a_1,...,a_n)=(a[2],...,a[n+1]) will be a common zero of the ideal m
+  poly nf;           // normalform of a variable w.r.t. m
+  intvec neuevariablen; // ith entry is 1, if for the ith component of a zero
+                        // of m a new variable is needed
+  intvec testvariablen; // integer vector of length n=number of variables
+  // compute for each maximal ideal the number of new variables,
+  // which are needed to describe
+  // its zeros -- note, a new variable is needed if modulo
+  // the maximal ideal it does not reduce
+  // to something which only depends on the following variables;
+  // if no new variable is needed, then store the value
+  // a variable reduces to in the list a;
+  for (j=size(minassi);j>=1;j--)
+  {
+    a[1]=poly(0);         // the first entry in a and in neuevariablen
+                          // corresponds to the variable t,
+    neuevariablen[1]=0;   // which is not present in the INITIALRING
+    neuvar=0;
+    minassi[j]=std(minassi[j]);
+    for (k=1;(k<=anzahlvariablen-1) and (pruefer==0);k++)
+    {
+      nf=reduce(var(k),minassi[j]);
+      // if a variable reduces to zero, then the maximal ideal
+      // contains a variable and we can delete it
+      if (nf==0)
+      {
+        pruefer=1;
+      }
+      // set the entries of testvariablen corresponding to the first
+      // k variables to 1, and the others to 0
+      for (l=1;l<=nvars(basering);l++)
+      {
+        if (l<=k)
+        {
+          testvariablen[l]=1;
+        }
+        else
+        {
+          testvariablen[l]=0;
+        }
+      }
+      // if the variable x_j reduces to a polynomial
+      // in x_j+1,...,x_n,X_1,...,X_k modulo m
+      // then we can eliminate x_j from the maximal ideal
+      // (since we do not need any
+      // further field extension to express a_j) and a_j
+      // will just be this normalform,
+      // otherwise we have to introduce a new variable in order to express a_j;
+      if (scalarproduct(leadexp(nf),testvariablen)==0)
+      {
+        a[k+1]=nf; // a_k is the normal form of the kth variable modulo m
+        neuevariablen[k+1]=0;  // no new variable is needed
+      }
+      else
+      {
+        a[k+1]=poly(0); // a_k is set to zero until we have
+                        // introduced the new variable
+        neuevariablen[k+1]=1;
+        neuvar++;       // the number of newly needed variables is raised by one
+      }
+    }
+    // if the maximal ideal contains a variable, we simply delete it
+    if (pruefer==0)
+    {
+      minassisort[j]=list(minassi[j],neuvar,neuevariablen,a);
+    }
+    // otherwise we store the information on a,
+    // neuevariablen and neuvar together with the ideal
+    else
+    {
+      minassi=delete(minassi,j);
+      minassisort=delete(minassisort,j);
+      pruefer=0;
+    }
+  }
+  // sort the maximal ideals ascendingly according to
+  // the number of new variables needed to
+  // express the zero of the maximal ideal
+  for (j=2;j<=size(minassi);j++)
+  {
+    l=j;
+    for (k=j-1;k>=1;k--)
+    {
+      if (minassisort[l][2]<minassisort[k][2])
+      {
+        zwischen=minassisort[l];
+        minassisort[l]=minassisort[k];
+        minassisort[k]=zwischen;
+        l=k;
+      }
+    }
+  }
+  return(minassisort);
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+static proc displaypoly(poly p,int N,int wj,int w1)
+"USAGE:  displaypoly(p,N,wj,w1); p poly, N, wj, w1 int
+ASSUME:  p is a polynomial in r=(0,X(1..k)),t,ls
+RETURN:  string, the string of t^-wj/w1*p(t^1/N)
+NOTE:    the procedure is called from displayTropicalLifting"
+{
+  if (p==0)
+  {
+    return(string(0));
+  }
+  ideal tpowers;
+  for (int j=ord(p);j<=deg(p);j++)
+  {
+    tpowers=tpowers,t^j;
+  }
+  tpowers=simplify(tpowers,2);
+  ideal koeffizienten=flatten(coeffs(p,tpowers));;
+  string dp;
+  for (j=ord(p);j<=deg(p);j++)
+  {
+    if (koeffizienten[j-ord(p)+1]!=0)
+    {
+      if ((j-(N*wj) div w1)==0)
+      {
+        dp=dp+displaycoef(koeffizienten[j-ord(p)+1]);
+      }
+      if (((j-(N*wj) div w1)==1) and (N!=1))
+      {
+        dp=dp+displaycoef(koeffizienten[j-ord(p)+1])+"*t^(1/"+string(N)+")";
+      }
+      if (((j-(N*wj) div w1)==1) and (N==1))
+      {
+        dp=dp+displaycoef(koeffizienten[j-ord(p)+1])+"*t";
+      }
+      if (((j-(N*wj) div w1)==-1) and (N==1))
+      {
+        dp=dp+displaycoef(koeffizienten[j-ord(p)+1])+"*1/t";
+      }
+      if (((j-(N*wj) div w1)==-1) and (N!=1))
+      {
+        dp=dp+displaycoef(koeffizienten[j-ord(p)+1])+"*1/t^(1/"+string(N)+")";
+      }
+      if (((j-(N*wj) div w1)>1) and (N==1))
+      {
+        dp=dp+displaycoef(koeffizienten[j-ord(p)+1])+"*t^"+string(j-(N*wj) div w1);
+      }
+      if (((j-(N*wj) div w1)>1) and (N!=1))
+      {
+        dp=dp+displaycoef(koeffizienten[j-ord(p)+1])+"*t^("+string(j-(N*wj) div w1)+"/"+string(N)+")";
+      }
+      if (((j-(N*wj) div w1)<-1) and (N==1))
+      {
+        dp=dp+displaycoef(koeffizienten[j-ord(p)+1])+"*1/t^"+string(wj-j);
+      }
+      if (((j-(N*wj) div w1)<-1) and (N!=1))
+      {
+        dp=dp+displaycoef(koeffizienten[j-ord(p)+1])+"*1/t^("+string((N*wj) div w1-j)+"/"+string(N)+")";
+      }
+      if (j<deg(p))
+      {
+        dp=dp+" + ";
+      }
+    }
+  }
+  return(dp);
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+static proc displaycoef (poly p)
+"USAGE:      displaycoef(p); p poly
+RETURN:      string, the string of p where brackets around
+                     have been added if they were missing
+NOTE:        the procedure is called from displaypoly"
+{
+  string pp=string(p);
+  if (pp[1]=="(")
+  {
+    return(pp);
+  }
+  else
+  {
+    return("("+pp+")");
+  }
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+static proc choosegfanvector (string s,int findall)
+"USAGE:   choosegfanvector(s); s string
+RETURN:   list, the jth entry is the jth integer vector contained in s
+NOTE:     the procedure is called from tropicalparametrise"
+{
+  if (findall==0) // if only one point in the tropical variety should be found
+  {
+    int i=2;
+    string w;
+    while (s[i]!=")")
+    {
+      w=w+s[i];
+      i++;
+    }
+    execute("intvec ww="+w+";");
+    ww=ww[1..size(ww)-1];
+    return(list(ww));
+  }
+  else
+  {
+    int i=1;
+    string w;
+    list ww;
+    intvec www;
+    while (size(s)!=0)
+    {
+      while ((s[1]!="(") and (size(s)!=0))
+      {
+        s=stringdelete(s,1);
+      }
+      if (size(s)!=0)
+      {
+        s=stringdelete(s,1);
+      }
+      while ((s[1]!=")") and (size(s)!=0))
+      {
+        w=w+s[1];
+        s=stringdelete(s,1);
+      }
+      if (size(s)!=0)
+      {
+        execute("www=intvec("+w+");");
+        ww[i]=intvec(www[1..size(www)-1]);
+        w="";
+        i++;
+      }
+    }
+    return(ww);
+  }
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+static proc tropicalliftingresubstitute (ideal i,list liftring,int N,list #)
+"USAGE:   tropicalliftingresubstitute(i,L,N[,#]); i ideal, L list, N int, # string
+ASSUME:   i is an ideal and L[1] is a ring which contains the lifting of a
+          point in the tropical variety of i computed with tropicalLifting;
+          t has to be replaced by t^1/N in the lifting; #[1]=m is the string
+          of the maximal ideal defining the necessary field extension as
+          computed by tropicalLifting, if #[1] is present
+RETURN:   string, the lifting has been substituted into i
+NOTE:     the procedure is called from tropicalLifting"
+{
+  def BASERING=basering;
+  def LIFTRing=liftring[1];
+  if (size(parstr(LIFTRing))!=0)
+  {
+    if (size(#)>0) // noAbs was used
+    {
+      execute("ring NOQRing=("+string(char(LIFTRing))+"),("+varstr(basering)+","+parstr(LIFTRing)+"),dp;");
+      execute("qring TESTRing=std("+#[1]+");");
+      ideal i=imap(BASERING,i);
+    }
+    else // absolute primary decomposition was used
+    {
+      setring LIFTRing;
+      poly mp=minpoly;
+      execute("ring TESTRing=("+charstr(LIFTRing)+"),("+varstr(BASERING)+"),dp;");
+      minpoly=number(imap(LIFTRing,mp));
+      ideal i=imap(BASERING,i);
+    }
+  }
+  else
+  {
+    def TESTRing=BASERING;
+    setring TESTRing;
+  }
+  // map the ideal LIFT to the TESTRing and substitute the solutions in i
+  ideal liftideal=imap(LIFTRing,LIFT);
+  for (int j=1;j<=ncols(liftideal);j++)
+  {
+    i=substitute(i,var(j),liftideal[j]);
+  }
+  // map the resulting i back to LIFTRing;
+  // if noAbs, then reduce i modulo the maximal ideal
+  // before going back to LIFTRing
+  if ((size(parstr(LIFTRing))!=0) and size(#)>0)
+  {
+    i=reduce(i,std(0));
+    setring LIFTRing;
+    ideal i=imap(TESTRing,i);
+  }
+  else
+  {
+    setring LIFTRing;
+    ideal i=imap(TESTRing,i);
+  }
+  list SUBSTTEST;
+  // replace t by t^1/N
+  for (j=1;j<=ncols(i);j++)
+  {
+    SUBSTTEST[j]=displaypoly(i[j],N,0,1);
+  }
+  return(SUBSTTEST);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Procedures used in tropicalLifting when using absolute primary decomposition
+/// - tropicalparametrise
+/// - eliminatecomponents
+/// - findzerosAndBasictransform
+/// - ordermaximalideals
+///////////////////////////////////////////////////////////////////////////////
+
+static proc tropicalparametrise (ideal i,intvec ww,int ordnung,intvec ordnungskontrollvektor,int gfanold,int findall,int nogfan,int puiseux,list #)
+"USAGE:  tropicalparametrise(i,tw,ord,gf,fa,ng,pu[,#]); i ideal, tw intvec, ord int, gf,fa,ng,pu int, # opt. list
+ASSUME:  - i is an ideal in Q[t,x_1,...,x_n, at a], tw=(w_0,w_1,...,w_n,0)
+           and (w_0,...,w_n,0) is in the tropical variety of i,
+           and ord is the order up to which a point in V(i)
+           over K{{t}} lying over w shall be computed;
+         - moreover, @a should be not be there if the procedure is not
+           called recursively;
+         - the point in the tropical variety is supposed to lie in the
+           NEGATIVE orthant;
+         - the ideal is zero-dimensional when considered in
+           (K(t)[@a]/m)[x_1,...,x_n], where m=#[2] is a maximal ideal in K[@a];
+         - gf is 0 if version 2.2 or larger is used and it is 1 else
+         - fa is 1 if all solutions should be found
+         - ng is 1 if gfan should not be executed
+         - pu is 1 if n=1 and i is generated by one polynomial and newtonpoly is used to find a
+           point in the tropical variety instead of gfan
+RETURN:  list, l[1] = ring K[@a]/m[[t]]
+               l[2] = int
+NOTE:    - the procedure is also called recursively by itself, and
+           if it is called in the first recursion, the list # is empty,
+           otherwise #[1] is an integer, one more than the number of
+           true variables x_1,...,x_n, and #[2] will contain the maximal
+           ideal m in the variable @a by which the ring K[t,x_1,...,x_n, at a]
+           should be divided to work correctly in L[t,x_1,...,x_n] where
+           L=Q[@a]/m is a field extension of K
+         - the ring l[1] contains an ideal PARA, which contains the
+           parametrisation of a point in V(i) lying over w up to the first
+           ord terms;
+         - the string m contains the code of the maximal ideal m, by which we
+           have to divide K[@a] in order to have the appropriate field extension
+           over which the parametrisation lives;
+         - and if the integer l[3] is N then t has to be replaced by t^1/N in the
+           parametrisation, or alternatively replace t by t^N in the defining
+           ideal
+         - the procedure REQUIRES that the program GFAN is installed
+           on your computer"
+{
+  def BASERING=basering;
+  int recursively; // is set 1 if the procedure is called recursively by itself
+  int ii,jj,kk,ll,jjj,kkk,lll;
+  if (typeof(#[1])=="int") // this means the precedure has been
+  { // called recursively
+    // how many variables are true variables, and how many come
+    // from the field extension
+    // only true variables have to be transformed
+    int anzahlvariablen=#[1];
+    // find the zeros of the w-initial ideal and transform the ideal i;
+    // findzeros and basictransformideal need to know
+    // how many of the variables are true variables
+    // and do the basic transformation as well
+    list zerolist=#[2];
+    list trring=findzerosAndBasictransform(i,ww,zerolist,findall,anzahlvariablen);
+  }
+  else // the procedure has been called by tropicalLifting
+  {
+    // how many variables are true variables, and
+    // how many come from the field extension
+    // only true variables have to be transformed
+    int anzahlvariablen=nvars(basering);
+    list zerolist; // will carry the zeros which are
+    //computed in the recursion steps
+    // the initial ideal of i has been handed over as #[1]
+    ideal ini=#[1];
+    // find the zeros of the w-initial ideal and transform the ideal i;
+    // we should hand the t-initial ideal ine to findzeros,
+    // since we know it already;
+    // and do the basic transformation as well
+    list trring=findzerosAndBasictransform(i,ww,zerolist,findall,ini);
+  }
+  list wneulist; // carries all newly computed weight vector
+  intvec wneu;   // carries the newly computed weight vector
+  intvec okvneu; // carries the newly computed ordnungskontrollvektor
+  int tweight;   // carries the weight of t
+  list PARALIST; // carries the result when tropicalparametrise
+                 // is recursively called
+  list eliminaterings;     // carries the result of eliminatecomponents
+  intvec deletedvariables; // contains inform. which variables have been deleted
+  deletedvariables[anzahlvariablen-1]=0; // initialise this vector
+  int numberdeletedvariables;  // the number of deleted variables
+  int oldanzahlvariablen=anzahlvariablen; // anzahlvariablen for later reference
+  list liftings,partliftings;  // the computed liftings (all resp. partly)
+  // consider each ring which has been returned when computing the zeros of the
+  // the t-initial ideal, equivalently, consider
+  // each zero which has been returned
+  for (jj=1;jj<=size(trring);jj++)
+  {
+    def TRRING=trring[jj];
+    setring TRRING;
+    // check if a certain number of components lead to suitable
+    // solutions with zero components;
+    // compute them all if findall==1
+    eliminaterings=eliminatecomponents(i,m,oldanzahlvariablen,findall,oldanzahlvariablen-1,deletedvariables);
+    // consider each of the rings returned by eliminaterings ...
+    // there is at least one !!!
+    for (ii=1;ii<=size(eliminaterings);ii++)
+    {
+      // #variables which have been eliminated
+      numberdeletedvariables=oldanzahlvariablen-eliminaterings[ii][2];
+      // #true variables which remain (including t)
+      anzahlvariablen=eliminaterings[ii][2];
+      // a 1 in this vector says that variable was eliminated
+      deletedvariables=eliminaterings[ii][3];
+      setring TRRING; // set TRRING - this is important for the loop
+      // pass the ring computed by eliminatecomponents
+      def PREGFANRING=eliminaterings[ii][1];
+      setring PREGFANRING;
+      poly m=imap(TRRING,m);        // map the maximal ideal to this ring
+      list zero=imap(TRRING,zero);  // map the vector of zeros to this ring
+      // now we have to compute a point ww on the tropical
+      // variety of the transformed ideal i;
+      // of course, we only have to do so, if we have
+      // not yet reached the order up to which we
+      // were supposed to do our computations
+      if ((ordnung>1) and (anzahlvariablen>1)) // if only t remains,
+      { // all true variables are gone
+        if (nogfan!=1)
+        {
+          // pass to a ring which has variables which are suitable for gfan
+          execute("ring GFANRING=("+string(char(basering))+"),(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z),dp;");
+          ideal phiideal=b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z;
+          phiideal[nvars(PREGFANRING)]=a; // map t to a
+          map phi=PREGFANRING,phiideal;
+          ideal II=phi(i);
+          // homogenise the ideal II with the first not yet
+          // used variable in our ring, since gfan
+          // only handles homogenous ideals; in principle for this
+          // one has first to compute a
+          // standard basis of II and homogenise that,
+          // but for the tropical variety (says Anders)
+          // it suffices to homogenise an arbitrary system of generators
+          // II=groebner(II);
+          II=homog(II,maxideal(1)[nvars(PREGFANRING)+1]);
+          // if gfan version >= 0.3.0 is used and the characteristic
+          // is not zero, then write the basering to the output
+          if ((gfanold!=1) and (char(GFANRING)!=0))
+          {
+            string ringvariablen=varstr(GFANRING);
+            ringvariablen=ringvariablen[1..2*nvars(PREGFANRING)+1];
+            write(":w /tmp/gfaninput","Z/"+string(char(GFANRING))+"Z["+ringvariablen+"]");
+            // write the ideal to a file which gfan takes as input and call gfan
+            write(":a /tmp/gfaninput","{"+string(II)+"}");
+          }
+          else
+          {
+            // write the ideal to a file which gfan takes as input and call gfan
+            write(":w /tmp/gfaninput","{"+string(II)+"}");
+          }
+          if (gfanold==1)
+          {
+            if (charstr(basering)!="0")
+            {
+              system("sh","gfan_tropicalbasis --mod "+charstr(basering)+" < /tmp/gfaninput > /tmp/gfanbasis");
+              system("sh","gfan_tropicalintersection < /tmp/gfanbasis > /tmp/gfanoutput");
+            }
+            else
+            {
+//      system("sh","gfan_tropicalstartingcone < /tmp/gfaninput > /tmp/gfantropstcone");
+//      system("sh","gfan_tropicaltraverse < /tmp/gfantropstcone > /tmp/gfanoutput");
+              system("sh","gfan_tropicalbasis < /tmp/gfaninput > /tmp/gfanbasis");
+              system("sh","gfan_tropicalintersection < /tmp/gfanbasis > /tmp/gfanoutput");
+            }
+            string trop=read("/tmp/gfanoutput");
+            setring PREGFANRING;
+            wneu=-1;    // this integer vector will store the point on the tropical variety
+            wneu[nvars(basering)]=0;
+            // for the time being simply stop Singular and set wneu by yourself
+            int goon=1;
+            trop;
+            "CHOOSE A RAY IN THE OUTPUT OF GFAN WHICH HAS ONLY";
+            "NON-POSITIVE ENTRIES AND STARTS WITH A NEGATIVE ONE,";
+            "E.G. (-3,-4,-1,-5,0,0,0) - the last entry will always be 0 -";
+            "THEN TYPE THE FOLLOWING COMMAND IN SINGULAR:   wneu=-3,-4,-1,-5,0,0;";
+            "AND HIT THE RETURN BUTTON - NOTE, THE LAST 0 IS OMITTED";
+            "IF YOU WANT wneu TO BE TESTED, THEN SET goon=0;";
+
+            // THIS IS NOT NECESSARY !!!! IF WE COMPUTE NOT ONLY
+            // THE TROPICAL PREVARIETY
+            // test, if wneu really is in the tropical variety
+            while (goon==0)
+            {
+              if (testw(reduce(i,std(gesamt_m)),wneu,anzahlvariablen)==1)
+              {
+                "CHOOSE A DIFFERENT RAY";
+
+              }
+              else
+              {
+                goon=1;
+              }
+            }
+            wneulist[1]=wneu;
+          }
+          else
+          {
+            system("sh","gfan_tropicallifting -n "+string(anzahlvariablen)+" --noMult -c < /tmp/gfaninput > /tmp/gfanoutput");
+            // read the result from gfan and store it to a string,
+            // which in a later version
+            // should be interpreded by Singular
+            wneulist=choosegfanvector(read("/tmp/gfanoutput"),findall);
+            setring PREGFANRING;
+          }
+          kill GFANRING;
+        }
+        else // if gfan is NOT executed
+        {
+          // if puiseux is set, then we are in the case of a plane curve and can use the command newtonpoly
+          if (puiseux==1)
+          {
+            if (nvars(basering)>2) // if the basering has a parameter
+            { // we have to pass to a ring with two variables to compute the newtonpoly
+              def PRENPRing=basering;
+              poly NPpoly=i[1];
+              ring NPRING=(0, at a),(x(1),t),ds;
+              poly NPpoly=imap(PRENPRing,NPpoly);
+              list NewtP=newtonpoly(NPpoly);
+              setring PRENPRing;
+              kill NPRING;
+            }
+            else
+            {
+              list NewtP=newtonpoly(i[1]);
+            }
+            for (jjj=1;jjj<=size(NewtP)-1;jjj++)
+            {
+              wneu=NewtP[jjj]-NewtP[jjj+1];
+              int ggteiler=gcd(wneu[1],wneu[2]);
+              wneu[1]=-wneu[1] div ggteiler;
+              wneu[2]=wneu[2] div ggteiler;
+              if (wneu[1]>0)
+              {
+                wneu=-wneu;
+              }
+              if (nvars(basering)>2)
+              {
+                wneu[3]=0;
+              }
+              wneulist[jjj]=wneu;
+            }
+            kill NewtP,ggteiler;
+          }
+          else // we have to set the points in the tropical variety by hand
+          {
+            if (findall==1)
+            {
+              "Set wneulist!";
+
+            }
+            else
+            {
+              "Set intvec wneu!";
+
+              wneulist[1]=wneu;
+            }
+          }
+        }
+      }
+      // if we have not yet computed our parametrisation up to
+      // the required order and
+      // zero is not yet a solution, then we have to go on
+      // by calling the procedure recursively;
+      // if all variables were deleted, then i=0 and thus anzahlvariablen==0
+      lll=0;
+      if (((puiseux==0) and (ordnung>1)) or ((puiseux==1) and (ordnungskontrollvektor[2]<ordnungskontrollvektor[1]*ordnung)) and (anzahlvariablen>1))
+      {
+        partliftings=list(); // initialise partliftings
+        // we call the procedure with the transformed
+        // ideal i, the new weight vector, with the
+        // required order lowered by one, and with
+        // additional parameters, namely the number of
+        // true variables and the maximal ideal that
+        // was computed so far to describe the field extension
+        for (kk=1;kk<=size(wneulist);kk++)
+        {
+          wneu=wneulist[kk];
+          okvneu=-ordnungskontrollvektor[1]*wneu[1],-ordnungskontrollvektor[2]*wneu[1]-wneu[2];
+          if (puiseux==0)
+          {
+            PARALIST=tropicalparametrise(i,wneu,ordnung-1,okvneu,gfanold,findall,nogfan,puiseux,anzahlvariablen,zero);
+          }
+          else
+          {
+            PARALIST=tropicalparametrise(i,wneu,ordnung,okvneu,gfanold,findall,nogfan,puiseux,anzahlvariablen,zero);
+          }
+          // the output will be a ring, in which the
+          // parametrisation lives, and a string, which contains
+          // the maximal ideal that describes the necessary field extension
+          for (ll=1;ll<=size(PARALIST);ll++)
+          {
+            def PARARing=PARALIST[ll][1];
+            tweight=-ww[1]*PARALIST[ll][2];
+            setring PARARing;
+            // if some variables have been eliminated
+            // in before, then we have to insert zeros
+            // into the parametrisation for those variables
+            if (numberdeletedvariables>0)
+            {
+              ideal PARAneu=PARA;
+              kkk=0;
+              for (jjj=1;jjj<=anzahlvariablen+numberdeletedvariables-1;jjj++)
+              { // t admits no parametrisation
+                if (deletedvariables[jjj]!=1)
+                {
+                  kkk++;
+                  PARA[jjj]=PARAneu[kkk];
+                }
+                else
+                {
+                  PARA[jjj]=poly(0);
+                }
+              }
+            }
+            lll++;
+            partliftings[lll]=list(PARARing,tweight,wneu);
+            setring PREGFANRING;
+            kill PARARing;
+          }
+        }
+      }
+      // otherwise we are done and we can start
+      // to compute the last step of the parametrisation
+      else
+      {
+        // we define the weight of t, i.e. in the
+        // parametrisation t has to be replaced by t^1/tweight
+        tweight=-ww[1];
+        // if additional variables were necessary,
+        // we introduce them now as parameters;
+        // in any case the parametrisation ring will
+        // have only one variable, namely t,
+        // and its order will be local, so that it
+        // displays the lowest term in t first
+        if (anzahlvariablen<nvars(basering))
+        {
+          execute("ring PARARing=("+string(char(basering))+", at a),t,ls;");
+          minpoly=number(imap(PREGFANRING,m));
+        }
+        else
+        {
+          execute("ring PARARing=("+charstr(basering)+"),t,ls;");
+        }
+        ideal PARA; // will contain the parametrisation
+        // we start by initialising the entries to be zero;
+        // one entry for each true variable
+        // here we also have to consider the variables
+        // that we have eliminated in before
+        for (jjj=1;jjj<=anzahlvariablen+numberdeletedvariables-1;jjj++)
+        {
+          PARA[jjj]=poly(0);
+        }
+        list zeros=imap(PREGFANRING,zero);
+        export(PARA);
+        export(zeros);
+        partliftings=list(list(PARARing,tweight));
+        kill PARARing;
+      }
+      // we now have to change the parametrisation by
+      // reverting the transformations that we have done
+      for (lll=1;lll<=size(partliftings);lll++)
+      {
+        if (size(partliftings[lll])==2) // when tropicalparametrise is called
+        { // for the last time, it does not enter the part, where wneu is
+          wneu=-1;     // defined and the variable t should have weight -1
+        }
+        else
+        {
+          wneu=partliftings[lll][3];
+          partliftings[lll]=delete(partliftings[lll],3);
+        }
+        tweight=partliftings[lll][2];
+        def PARARing=partliftings[lll][1];
+        setring PARARing;
+        for (jjj=1;jjj<=anzahlvariablen+numberdeletedvariables-1;jjj++)
+        {
+          PARA[jjj]=(PARA[jjj]+zeros[size(zeros)][jjj+1])*t^(ww[jjj+1]*tweight div ww[1]);
+        }
+        // delete the last entry in zero, since that one has
+        // been used for the transformation
+        zeros=delete(zeros,size(zeros));
+        // in order to avoid redefining commands an empty
+        // zeros list should be removed
+        if (size(zeros)==0)
+        {
+          kill zeros;
+        }
+        partliftings[lll]=list(PARARing,tweight);
+        setring TRRING;
+        kill PARARing;
+      }
+      kill PREGFANRING;
+      liftings=liftings+partliftings;
+    }
+    kill TRRING;
+  }
+  if (nogfan!=1)
+  {
+    // kill the gfan files in /tmp
+    system("sh","cd /tmp; /usr/bin/touch gfaninput; /usr/bin/touch gfanoutput; /bin/rm gfaninput; /bin/rm gfanoutput");
+  }
+  // we return a list which contains lists of the parametrisation
+  // rings (with the parametrisation ideal)
+  // and an integer N such that t should be replaced by t^1/N
+  return(liftings);
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+static proc eliminatecomponents (ideal i,ideal m,int anzahlvariablen,int findall,int lastvar,intvec deletedvariables)
+"USAGE:  eliminatecomponents(i,m,n,a,v,d); i,m ideal, n,a,v int, d intvec
+ASSUME:  i is an ideal in Q[x_1,...,x_n, at a,t] and w=(-w_1/w_0,...,-w_n/w_0)
+         is in the tropical variety of i considered in
+         Q[@a]/m{{t}}[x_1,...,x_n];
+         considered in this ring i is zero-dimensional; @a need not be present
+         in which case m is zero; 1<=v<=n
+RETURN:  list, L of lists
+               L[j][1] = a ring containing an ideal i and an ideal m
+               L[j][2] = an integer anzahlvariablen
+               L[j][3] = an intvec deletedvariables
+NOTE:    - the procedure is called from inside the recursive
+           procedure tropicalparametrise
+         - the procedure checks for solutions which have certain
+           components zero; these are separated from the rest by
+           elimination and saturation; the integer deletedvariables
+           records which variables have been eliminated;
+           the integer anzahlvariablen records how many true variables remain
+           after the elimination
+         - if the integer a is one then all zeros of the ideal i are
+           considered and found, otherwise only one is considered, so that L
+           has length one"
+{
+  def BASERING=basering;
+  int j,k; // index variable
+  ideal I,LI; // stores the changed ideal i, respectively its leading ideal
+  // if all solutions have to be found
+  if (findall==1)
+  {
+    list saturatelist,eliminatelist; // carry the solution of the two tests
+    // we test first if there is a solution which has the component
+    // lastvar zero and
+    // where the order of each component is strictly positive;
+    // if so, we add this variable to the ideal and
+    // eliminate it - which amounts to
+    // to projecting the solutions with this component
+    // zero to the hyperplane without this component;
+    // for the test we compute the saturation with
+    // respect to t and replace each variable
+    // x_i and also t by zero -- if the result is zero,
+    // then 1 is not in I:t^infty
+    // (i.e. there is a solution which has the component lastvar zero) and
+    // the result lives in the maximal
+    // ideal <t,x_1,...,[no x_lastvar],...,x_n> so that
+    // there is a solution which has strictly positive valuation
+    // ADDENDUM:
+    // if i (without m) has only one polynomial, then we can divide
+    // i by t as long as possible to compute the saturation with respect to t
+/*
+    // DER NACHFOLGENDE TEIL IST MUELL UND WIRD NICHT MEHR GAMACHT
+    // for the test we simply compute the leading ideal
+    // and set all true variables zero;
+    // since the ordering was an elimination ordering
+    // with respect to (@a if present and) t
+    // there remains something not equal to zero
+    // if and only if there is polynomial which only
+    // depends on t (and @a if present), but that is
+    // a unit in K{{t}}, which would show that there
+    // is no solution with the component lastvar zero;
+    // however, we also have to ensure that if there
+    // exists a solution with the component lastvar
+    // equal to zero then this component has a
+    // valuation with all strictly positive values!!!!;
+    // for this we can either saturate the ideal
+    // after elimination with respect to <t,x_1,...,x_n>
+    // and see if the saturated ideal is contained in <t,x_1,...x_n>+m,
+    // or ALTERNATIVELY we can pass to the
+    // ring 0,(t,x_1,...,x_n, at a),(ds(n+1),dp(1)),
+    // compute a standard basis of the elimination
+    // ideal (plus m) there and check if the dimension 1
+    // (since we have not omitted the variable lastvar,
+    // this means that we have the ideal
+    // generated by t,x_1,...,[no x_lastvar],...,x_n
+    // and this defines NO curve after omitting x_lastvar)
+    I=std(ideal(var(lastvar)+i));
+    // first test,
+    LI=lead(reduce(I,std(m)));
+    //size(deletedvariables)=anzahlvariablen(before elimination)
+    for (j=1;j<=anzahlvariablen-1;j++)
+    {
+      LI=subst(LI,var(j),0);
+    }
+    if (size(LI)==0) // if no power of t is in lead(I) (where @a is considered as a field element)
+*/
+    if (size(i)-size(m)!=1)
+    {
+      I=reduce(sat(std(ideal(var(lastvar)+i)),t)[1],std(m)); // get rid of the minimal
+                                                             // polynomial for the test
+    }
+    else
+    {
+      I=subst(i,var(lastvar),0);
+      while ((I[1]!=0) and (subst(I[1],t,0)==0))
+      {
+        I[1]=I[1]/t;
+      }
+      I=reduce(I,std(m));
+    }
+    LI=subst(I,var(nvars(basering)),0);
+    //size(deletedvariables)=anzahlvariablen(before elimination)
+    for (j=1;j<=anzahlvariablen-1;j++)
+    {
+      LI=subst(LI,var(j),0);
+    }
+    if (size(LI)==0) // the saturation lives in the maximal
+    { // ideal generated by t and the x_i
+      // get rid of var(lastvar)
+      I=eliminate(I,var(lastvar))+m; // add the minimal polynomial again
+      // store the information which variable has been eliminated
+      intvec newdeletedvariables=deletedvariables;
+      newdeletedvariables[lastvar]=1;
+      // pass to a new ring whith one variable less
+      if (anzahlvariablen>2)
+      {
+        string elring="ring ELIMINATERING=("+charstr(basering)+"),("+string(simplify(reduce(maxideal(1),std(var(lastvar))),2))+"),(dp("+string(anzahlvariablen-2)+"),";
+      }
+      else
+      {
+        string elring="ring ELIMINATERING=("+charstr(basering)+"),("+string(simplify(reduce(maxideal(1),std(var(lastvar))),2))+"),(";
+      }
+      if (anzahlvariablen<nvars(basering)) // if @a was present, the
+      { // ordersting needs an additional entry
+        elring=elring+"dp(1),";
+      }
+      elring=elring+"lp(1));";
+      execute(elring);
+      ideal i=imap(BASERING,I); // move the ideal I to the new ring
+      // if not yet all variables have been checked,
+      // then go on with the next smaller variable,
+      // else prepare the elimination ring and the neccessary
+      // information for return
+      if (lastvar>1)
+      {
+        eliminatelist=eliminatecomponents(i,imap(BASERING,m),anzahlvariablen-1,findall,lastvar-1,newdeletedvariables);
+      }
+      else
+      {
+        export(i);
+          eliminatelist=list(list(ELIMINATERING,anzahlvariablen-1,newdeletedvariables));
+      }
+      setring BASERING;
+    }
+    // next we have to test if there is also a solution
+    // which has the variable lastvar non-zero;
+    // to do so, we saturate with respect to this variable;
+    // since when considered over K{{t}}
+    // the ideal is zero dimensional, this really removes
+    // all solutions with that component zero;
+    // the checking is then done as above
+    // ADDENDUM
+    // if the ideal i (without m) is generated by a single polynomial
+    // then we saturate by successively dividing by the variable
+    if (size(i)-size(m)==1)
+    {
+      while (subst(i[1],var(lastvar),0)==0)
+      {
+        i[1]=i[1]/var(lastvar);
+      }
+    }
+    else
+    {
+      i=std(sat(i,var(lastvar))[1]);
+    }
+    I=reduce(i,std(m)); // "remove" m from i
+    // test first, if i still is in the ideal <t,x_1,...,x_n> -- if not, then
+    // we know that i has no longer a point in the tropical
+    // variety with all components negative
+    LI=subst(I,var(nvars(basering)),0);
+    for (j=1;j<=anzahlvariablen-1;j++) // set all variables
+    { // t,x_1,...,x_n equal to zero
+      LI=subst(LI,var(j),0);
+    }
+    if (size(LI)==0) // the entries of i have no constant part
+    {
+      // check now, if the leading ideal of i contains an element
+      // which only depends on t
+      LI=lead(I);
+      //size(deletedvariables)=anzahlvariablen(before elimination)
+      for (j=1;j<=anzahlvariablen-1;j++)
+      {
+        LI=subst(LI,var(j),0);
+      }
+      if (size(LI)==0) // if no power of t is in lead(i)
+      { // (where @a is considered as a field element)
+        // if not yet all variables have been tested, go on with the
+        // next smaller variable
+        // else prepare the neccessary information for return
+        if (lastvar>1)
+        {
+          saturatelist=eliminatecomponents(i,m,anzahlvariablen,findall,lastvar-1,deletedvariables);
+        }
+        else
+        {
+          execute("ring SATURATERING=("+charstr(basering)+"),("+varstr(basering)+"),("+ordstr(basering)+");");
+          ideal i=imap(BASERING,i);
+          export(i);
+          setring BASERING;
+          saturatelist=list(list(SATURATERING,anzahlvariablen,deletedvariables));
+        }
+      }
+    }
+    return(eliminatelist+saturatelist);
+  }
+  else // only one solution is searched for, we can do a simplified
+  { // version of the above
+    // check if there is a solution which has the n-th component
+    // zero and with positive valuation,
+    // if so, then eliminate the n-th variable from
+    // sat(i+x_n,t), otherwise leave i as it is;
+    // then check if the (remaining) ideal has as
+    // solution where the n-1st component is zero ...,
+    // and procede as before; do the same for the remaining variables;
+    // this way we make sure that the remaining ideal has
+    // a solution which has no component zero;
+    ideal variablen; // will contain the variables which are not eliminated
+    for (j=anzahlvariablen-1;j>=1;j--)  // the variable t is the last one !!!
+    {
+      I=sat(ideal(std(var(j)+i)),t)[1];
+      LI=subst(I,var(nvars(basering)),0);
+      //size(deletedvariables)=anzahlvariablen-1(before elimination)
+      for (k=1;k<=size(deletedvariables);k++)
+      {
+        LI=subst(LI,var(k),0);
+      }
+      if (size(LI)==0) // if no power of t is in lead(I)
+      { // (where the X(i) are considered as field elements)
+        // get rid of var(j)
+        i=eliminate(I,var(j));
+        deletedvariables[j]=1;
+        anzahlvariablen--; // if a variable is eliminated,
+                           // then the number of true variables drops
+      }
+      else
+      {
+        variablen=variablen+var(j); // non-eliminated true variables are stored
+      }
+    }
+    variablen=invertorder(variablen);
+    // store also the additional variable and t,
+    // since they for sure have not been eliminated
+    for (j=size(deletedvariables)+1;j<=nvars(basering);j++)
+    {
+      variablen=variablen+var(j);
+    }
+    // if there are variables left, then pass to a ring which
+    // only realises these variables else we are done
+    if (anzahlvariablen>1)
+    {
+      string elring="ring ELIMINATERING=("+charstr(basering)+"),("+string(variablen)+"),(dp("+string(anzahlvariablen-1)+"),";
+    }
+    else
+    {
+      string elring="ring ELIMINATERING=("+charstr(basering)+"),("+string(variablen)+"),(";
+    }
+    if (size(deletedvariables)+1<nvars(basering)) // if @a was present,
+    { // the ordersting needs an additional entry
+      elring=elring+"dp(1),";
+    }
+    elring=elring+"lp(1));";
+    execute(elring);
+    ideal i=imap(BASERING,i);
+    ideal m=imap(BASERING,m);
+    export(i);
+    export(m);
+    return(list(list(ELIMINATERING,anzahlvariablen,deletedvariables)));
+  }
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+static proc findzerosAndBasictransform (ideal i,intvec w,list zerolist,int findall,list #)
+"USAGE:  findzerosAndBasictransform(i,w,z,f[,#]); i ideal, w intvec, z list, f int,# an optional list
+ASSUME:  i is an ideal in Q[t,x_1,...,x_n, at a] and w=(w_0,...,w_n,0)
+         is in the tropical variety of i; @a need not be present;
+         the list 'zero' contains the zeros computed in previous recursion steps;
+         if 'f' is one then all zeros should be found and returned,
+         otherwise only one
+RETURN:  list, each entry is a ring corresponding to one conjugacy class of
+               zeros of the t-initial ideal inside the torus; each of the rings
+               contains the following objects
+               ideal i    = the ideal i, where the variable @a (if present) has
+                            possibly been transformed according to the new
+                            minimal polynomial, and where itself has been
+                            submitted to the basic transform of the algorithm
+                            given by the jth zero found for the t-initial ideal;
+                            note that the new minimal polynomial has already
+                            been added
+               poly m     = the new minimal polynomial for @a
+                            (it is zero if no @a is present)
+               list zero  = zero[k+1] is the kth component of a zero
+                            the t-initial ideal of i
+NOTE:     -  the procedure is called from inside the recursive procedure
+             tropicalparametrise;
+             if it is called in the first recursion, the list #[1] contains
+             the t-initial ideal of i w.r.t. w, otherwise #[1] is an integer,
+             one more than the number of true variables x_1,...,x_n
+          -  if #[2] is present, then it is an integer which tells whether
+             ALL zeros should be found or not"
+{
+  def BASERING=basering;
+  string tvar=string(var(nvars(basering)));
+  int j,k,l; // indices
+  // store the weighted degrees of the elements of i in an integer vector
+  intvec wdegs;
+  for (j=1;j<=size(i);j++)
+  {
+    wdegs[j]=deg(i[j],intvec(w[2..size(w)],w[1]));
+  }
+  // set anzahlvariablen to the number of true variables
+  if (typeof(#[1])=="int")
+  {
+    int recursive=1; // checks if the procedure has been called recursively
+    int anzahlvariablen=#[1];
+    // compute the initial ideal of i
+    // - the last 1 just means that the variable t is the last
+    //   variable in the ring
+    ideal ini=tInitialIdeal(i,w,1);
+  }
+  else
+  {
+    int recursive=0;
+    int anzahlvariablen=nvars(basering);
+    ideal ini=#[1]; // the t-initial ideal has been computed
+                    // in before and was handed over
+  }
+  // collect the true variables x_1,...,x_n plus @a, if it is defined in BASERING
+  ideal variablen;
+  for (j=1;j<=nvars(basering)-1;j++)
+  {
+    variablen=variablen+var(j);
+  }
+  // move to a polynomial ring with global monomial ordering
+  // - the variable t is superflous,
+  // the variable @a is not if it was already present
+  execute("ring INITIALRING=("+charstr(basering)+"),("+string(variablen)+"),dp;");
+  ideal ini=imap(BASERING,ini);
+  // compute the minimal associated primes of the
+  // initialideal over the algebraic closure;
+  // ordering the maximal ideals shall help to
+  // avoid unneccessary field extensions
+  list absminass=absPrimdecGTZ(ini);
+  def ABSRING=absminass[1]; // the ring in which the minimal
+                            // associated primes live
+  setring ABSRING;
+  list maximalideals=ordermaximalideals(absolute_primes,anzahlvariablen);
+  if (findall==0) // only one maximal ideal shall be considered
+  {
+    maximalideals=list(maximalideals[1]);
+  }
+  list extensionringlist; // contains the rings which are to be returned
+  for (j=1;j<=size(maximalideals);j++)
+  {
+    // check if for the jth maximal ideal a field extension is necessary;
+    // the latter condition says that @a is not in BASERING;
+    // if some of the maximal ideals needs a field extension,
+    // then everything will live in this ring
+    if ((maximalideals[j][1]!=0) and (nvars(BASERING)==anzahlvariablen))
+    {
+      // define the extension ring which contains
+      // the new variable @a, if it is not yet present
+      execute("ring EXTENSIONRING=("+charstr(BASERING)+"),("+string(imap(BASERING,variablen))+", at a,"+tvar+"),(dp("+string(anzahlvariablen-1)+"),dp(1),lp(1));");
+      // phi maps x_i to x_i, @a to @a (if present in the ring),
+      // and the additional variable
+      // for the field extension is mapped to @a as well
+      // -- note that we only apply phi
+      // to the list a, and in this list no @a is present;
+      // therefore, it does not matter where this is mapped to
+      map phi=ABSRING,imap(BASERING,variablen), at a;
+    }
+    else // @a was already present in the BASERING or no
+    { // field extension is necessary
+      execute("ring EXTENSIONRING=("+charstr(BASERING)+"),("+varstr(BASERING)+"),("+ordstr(BASERING)+");");
+      // phi maps x_i to x_i, @a to @a (if present in the ring),
+      // and the additional variable
+      // for the field extension is mapped to @a as well respectively to 0,
+      // if no @a is present;
+      // note that we only apply phi to the list a and to
+      // the replacement rule for
+      // the old variable @a, and in this list resp.
+      // replacement rule no @a is present;
+      // therefore, it does not matter where this is mapped to;
+      if (anzahlvariablen<nvars(EXTENSIONRING)) // @a is in EXTENSIONRING
+      {
+        // additional variable is mapped to @a
+        map phi=ABSRING,imap(BASERING,variablen), at a;
+      }
+      else
+      {
+        // additional variable is mapped to 0
+        map phi=ABSRING,imap(BASERING,variablen),0;
+      }
+    }
+    // map the list maximalideals to the EXTENSIONRING
+    list maximalideals=phi(maximalideals);
+    poly m=maximalideals[j][1];    // extract m
+    list zeroneu=maximalideals[j][2]; // extract the new zero
+    poly repl=maximalideals[j][3]; // extract the replacement rule
+    // the list zero may very well exist as an EMPTY global list
+    // - in this case we have to remove it
+    // in order to avoid a redefining warning
+    if (defined(zero)!=0)
+    {
+      if (size(zero)==0)
+      {
+        kill zero;
+      }
+    }
+    // map i and alist to the new ring
+    if (repl==0) // in BASERING no @a was present
+    {
+      ideal i=imap(BASERING,i);
+      if (defined(zerolist)==0) // if zerolist is empty, it does not
+      { // depend on BASERING !
+        list zero=imap(BASERING,zerolist);
+      }
+      else
+      {
+        list zero=zerolist;
+      }
+    }
+    else // in BASERING was @a present
+    {
+      ideal variablen=imap(BASERING,variablen);
+      // map i and zerolist to EXTENSIONRING replacing @a
+      // by the replacement rule repl
+      map psi=BASERING,variablen[1..size(variablen)-1],repl,var(nvars(basering));
+      ideal i=psi(i);
+      list zero=psi(zerolist);
+      kill psi;
+    }
+    // add the last vector of zeros to zero
+    zero[size(zero)+1]=zeroneu;
+    // do now the basic transformation sending x_l -> t^-w_l*(zero_l+x_l)
+    for (l=1;l<=anzahlvariablen;l++)
+    {
+      for (k=1;k<=size(i);k++)
+      {
+        if (l!=1) // corresponds to  x_(l-1) --  note t is the last variable
+        {
+          i[k]=subst(i[k],var(l-1),(zeroneu[l]+var(l-1))*t^(-w[l]));
+        }
+        else // corresponds to t
+        {
+          i[k]=subst(i[k],var(nvars(basering)),var(nvars(basering))^(-w[l]));
+        }
+      }
+    }
+    // we can divide the lth generator of i by t^-wdegs[l]
+    for (l=1;l<=ncols(i);l++)
+    {
+      if (wdegs[l]<0) // if wdegs[l]==0 there is no need to divide,
+      { // and we made sure that it is no positive
+        i[l]=i[l]/t^(-wdegs[l]);
+      }
+    }
+    // since we want to consider i now in the ring (Q[@a]/m)[t,x_1,...,x_n]
+    // we can  reduce i modulo m, so that "constant terms"
+    // which are "zero" since they
+    // are in m will disappear; simplify(...,2) then really removes them;
+    // finally we add the minimal polynomial
+    i=simplify(ideal(reduce(i,std(m))+m),2);
+    export(i);
+    export(m);
+    export(zero);
+    extensionringlist[j]=EXTENSIONRING;
+    kill EXTENSIONRING;
+    setring ABSRING;
+  }
+  return(extensionringlist);
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+static proc ordermaximalideals (list minassi,int anzahlvariablen)
+"USAGE:      ordermaximalideals(minassi); minassi list
+ASSUME:      minassi is a list of maximal ideals (together with the information
+             how many conjugates it has), where the first polynomial is the
+             minimal polynomial of the last variable in the ring which is
+             considered as a parameter
+RETURN:      list, the procedure orders the maximal ideals in minassi according
+                   to how many new variables are needed (namely none or one) to
+                   describe the zeros of the ideal, and accordingly to the
+                   degree of the corresponding minimal polynomial
+                   l[j][1] = the minimal polynomial for the jth maximal ideal
+                   l[j][2] = list, the k+1st entry is the kth coordinate of the
+                                   zero described by the maximal ideal in terms
+                                   of the last variable
+                   l[j][3] = poly, the replacement for the old variable @a
+NOTE:        if a maximal ideal contains a variable, it is removed from the list;
+             the procedure is called by findzerosAndBasictransform"
+{
+  int j,k,l;
+  int pruefer;       // is set one if a maximal ideal contains a variable
+  list minassisort;  // will contain the output
+  for (j=1;j<=size(minassi);j++){minassisort[j]=0;} // initialise minassisort
+                                                    // to fix its initial length
+  list zwischen;     // needed for reordering
+  list zero;         // (a_1,...,a_n)=(zero[2],...,zero[n+1]) will be
+                     // a common zero of the ideal m
+  poly nf;           // normalform of a variable w.r.t. m
+  poly minimalpolynomial;  // minimal polynomial for the field extension
+  poly parrep;  // the old variable @a possibly has to be replaced by a new one
+  // compute for each maximal ideal the number of new variables, which are
+  // needed to describe its zeros -- note, a new variable is needed
+  // if the first entry of minassi[j][1] is not the last variable
+  // store the value a variable reduces to in the list a;
+  for (j=size(minassi);j>=1;j--)
+  {
+    minimalpolynomial=minassi[j][1][1];
+    if (minimalpolynomial==var(nvars(basering)))
+    {
+      minimalpolynomial=0;
+    }
+    zero[1]=poly(0);         // the first entry in zero and in
+                             // neuevariablen corresponds to the variable t,
+    minassi[j][1]=std(minassi[j][1]);
+    for (k=1;(k<=anzahlvariablen-1) and (pruefer==0);k++)
+    {
+      // zero_k+1 is the normal form of the kth variable modulo m
+      zero[k+1]=reduce(var(k),minassi[j][1]);
+      // if a variable reduces to zero, then the maximal
+      // ideal contains a variable and we can delete it
+      if (zero[k+1]==0)
+      {
+        pruefer=1;
+      }
+    }
+    // if anzahlvariablen<nvars(basering), then the old ring
+    // had already an additional variable;
+    // the old parameter @a then has to be replaced by parrep
+    if (anzahlvariablen<nvars(basering))
+    {
+      parrep=reduce(var(anzahlvariablen),minassi[j][1]);
+    }
+    // if the maximal ideal contains a variable, we simply delete it
+    if (pruefer==0)
+    {
+      minassisort[j]=list(minimalpolynomial,zero,parrep);
+    }
+    // otherwise we store the information on a, neuevariablen
+    // and neuvar together with the ideal
+    else
+    {
+      minassi=delete(minassi,j);
+      minassisort=delete(minassisort,j);
+      pruefer=0;
+    }
+  }
+  // sort the maximal ideals ascendingly according to the
+  // number of new variables needed to
+  // express the zero of the maximal ideal
+  for (j=2;j<=size(minassi);j++)
+  {
+    l=j;
+    for (k=j-1;k>=1;k--)
+    {
+      if (deg(minassisort[l][1])<deg(minassisort[k][1]))
+      {
+        zwischen=minassisort[l];
+        minassisort[l]=minassisort[k];
+        minassisort[k]=zwischen;
+        l=k;
+      }
+    }
+  }
+  return(minassisort);
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+/// Procedures used in tropicalCurve:
+/// - verticesTropicalCurve
+/// - bunchOfLines
+/// - clearintmat
+/// - sortintvec
+/// - sortintmat
+/// - intmatcoldelete
+/// - intmatconcat
+/// - minInIntvec
+/// - positionInList
+/// - sortlist
+/// - minInList
+/// - vergleiche
+/// - koeffizienten
+////////////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////
+
+static proc verticesTropicalCurve (def tp,list #)
+"USAGE:      verticesTropicalCurve(tp[,#]); tp list, # optional list
+ASSUME:      tp is represents an ideal in Z[x,y] representing a tropical
+             polynomial (in the form of the output of the procedure tropicalise)
+             defining a tropical plane curve
+RETURN:      list, each entry corresponds to a vertex in the tropical plane
+                   curve defined by tp
+                   l[i][1] = x-coordinate of the ith vertex
+                   l[i][2] = y-coordinate of the ith vertex
+                   l[i][3] = a polynomial whose monimials mark the vertices in
+                             the Newton polygon corresponding to the entries in
+                             tp which take the common minimum at the ith vertex
+NOTE:      - the information in l[i][3] represents the subdivision of the Newton
+             polygon of tp (respectively a polynomial which defines tp);
+           - if # is non-empty and #[1] is the string 'max', then in the
+             computations minimum and maximum are exchanged;
+           - if # is non-empty and the #[1] is not a string, only the vertices
+             will be computed and the information on the Newton subdivision will
+             be omitted;
+           - here the tropical polynomial is supposed to be the MINIMUM of the
+             linear forms in tp, unless the optional input #[1] is the
+             string 'max'
+           - the procedure is called from tropicalCurve and from
+             conicWithTangents"
+{
+  // if you insert a single polynomial instead of an ideal representing
+  // a tropicalised polynomial,
+  // then we compute first the tropicalisation of this polynomial
+  // -- this feature is not documented in the above help string
+  if (typeof(tp)=="poly")
+  {
+    poly f=tp;
+    kill tp;
+    list tp=tropicalise(f,#);
+  }
+  int i,j,k,l,z; // indices
+  // make sure that no constant entry of tp has type int since that
+  // would lead to trouble
+  // when using the procedure substitute
+  for (i=1;i<=size(tp);i++)
+  {
+    if (typeof(tp[i])=="int")
+    {
+      tp[i]=poly(tp[i]);
+    }
+  }
+  // introduce necessary variables
+  ideal punkt;
+  poly px,py;
+  poly wert,vergleich;
+  poly newton;
+  list eckpunkte;
+  int e=1;
+  option(redSB);
+  // for each triple (i,j,k) of entries in tp check if they have a
+  // point in common and if they attain at this point the minimal
+  // possible value for all linear forms in tp
+  for (i=1;i<=size(tp)-2;i++)
+  {
+    for(j=i+1;j<=size(tp)-1;j++)
+    {
+      for (k=j+1;k<=size(tp);k++)
+      {
+        punkt=std(ideal(tp[i]-tp[k],tp[j]-tp[k]));
+        if (size(punkt)==2)
+        {
+          if (leadmonom(punkt[1])==var(1))
+          {
+            px=(-punkt[1]+lead(punkt[1]))/leadcoef(punkt[1]);
+            py=(-punkt[2]+lead(punkt[2]))/leadcoef(punkt[2]);
+          }
+          else
+          {
+            py=(-punkt[1]+lead(punkt[1]))/leadcoef(punkt[1]);
+            px=(-punkt[2]+lead(punkt[2]))/leadcoef(punkt[2]);
+          }
+          l=1;
+          wert=substitute(tp[i],var(1),px,var(2),py);
+          newton=0;
+          vergleich=wert;
+          while((l<=size(tp)) and (vergleiche(wert,vergleich,#)))
+          {
+            vergleich=substitute(tp[l],var(1),px,var(2),py);
+            if (vergleich==wert)
+            {
+              newton=newton+detropicalise(tp[l]);
+            }
+            l++;
+          }
+          if ((l==size(tp)+1) and (vergleiche(wert,vergleich,#)))
+          {
+            if (size(#)==0)
+            {
+              eckpunkte[e]=list(px,py,newton);
+            }
+            else
+            {
+              if (typeof(#[1])=="string")
+              {
+                eckpunkte[e]=list(px,py,newton);
+              }
+              else
+              {
+                eckpunkte[e]=list(px,py);
+              }
+            }
+            e++;
+          }
+        }
+      }
+    }
+  }
+  // if a vertex appears several times, only its first occurence will be kept
+  for (i=size(eckpunkte);i>=2;i--)
+  {
+    for (j=i-1;j>=1;j--)
+    {
+      if ((eckpunkte[i][1]==eckpunkte[j][1]) and (eckpunkte[i][2]==eckpunkte[j][2]))
+      {
+        eckpunkte=delete(eckpunkte,i);
+        j=0;
+      }
+    }
+  }
+  return(eckpunkte);
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+static proc bunchOfLines (def tp,list #)
+"USAGE:      bunchOfLines(tp[,#]); tp list, # optional list
+ASSUME:      tp is represents an ideal in Q[x,y] representing a tropical
+             polynomial (in the form of the output of the procedure tropicalise)
+             defining a bunch of ordinary lines in the plane,
+             i.e. the Newton polygone is a line segment
+RETURN:      list, see the procedure tropicalCurve for an explanation of
+                   the syntax of this list
+NOTE:      - the tropical curve defined by tp will consist of a bunch of
+             parallel lines and throughout the procedure a list with the
+             name bunchoflines is computed, which represents these lines and
+             has the following interpretation:
+             list, each entry corresponds to a vertex in the tropical plane
+                   curve defined by tp
+                   l[i][1] = the equation of the ith line in the tropical curve
+                   l[i][2] = a polynomial whose monimials mark the vertices in
+                             the Newton polygon corresponding to the entries in
+                             tp which take the common minimum at the ith vertex
+           - the information in l[i][2] represents the subdivision of the Newton
+             polygon of tp (respectively a polynomial which defines tp);
+           - if # is non-empty and #[1] is the string 'max', then in the
+             computations minimum and maximum are exchanged;
+           - if # is non-empty and the #[1] is not a string, only the vertices
+             will be computed and the information on the Newton subdivision
+             will be omitted;
+           - here the tropical polynomial is supposed to be the MINIMUM of the
+             linear forms in tp, unless the optional input #[1] is the
+             string 'max'
+           - the procedure is called from tropicalCurve"
+{
+  // introduce necessary variables
+  list oldtp=tp; // save the old entries of tp
+  int i,j,k,l;
+  ideal punkt;
+  poly px;
+  poly wert,vergleich;
+  poly newton;
+  list bunchoflines;
+  int e=1;
+  option(redSB);
+  // find the direction of the line segment in the Newton polygon
+  intvec direction=leadexp(detropicalise(tp[1]))-leadexp(detropicalise(tp[2]));
+  direction=direction/gcd(direction[1],direction[2]);
+  // change the coordinates in such a way, that the Newton polygon
+  // lies on the x-axis
+  if (direction[1]==0) // there is no x-term - exchange x and y
+  { // and get rid of the new y part
+    for (i=1;i<=size(tp);i++)
+    {
+      tp[i]=substitute(tp[i],var(1),0,var(2),var(1));
+    }
+  }
+  else
+  {
+    for (i=1;i<=size(tp);i++)
+    {
+      tp[i]=substitute(tp[i],var(2),0);
+    }
+  }
+  // For all tuples (i,j) of entries in tp check if they attain
+  // at their point of intersection
+  // the minimal possible value for all linear forms in tp
+  for (i=1;i<=size(tp)-1;i++)
+  {
+    for(j=i+1;j<=size(tp);j++)
+    {
+      punkt=std(ideal(tp[i]-tp[j]));
+      px=-leadcoef(punkt[1]-lead(punkt[1]))/leadcoef(punkt[1]);
+      l=1;
+      wert=substitute(tp[i],var(1),px);
+      newton=0;
+      vergleich=wert;
+      while((l<=size(tp)) and (vergleiche(wert,vergleich,#)))
+      {
+        vergleich=substitute(tp[l],var(1),px);
+        if (vergleich==wert)
+        {
+          newton=newton+detropicalise(oldtp[l]);
+        }
+        l++;
+      }
+      if ((l==size(tp)+1) and (vergleiche(wert,vergleich,#)))
+      {
+        bunchoflines[e]=list((oldtp[i]-oldtp[j])/leadcoef(oldtp[i]-oldtp[j]),newton);
+        e++;
+      }
+    }
+  }
+  // if a vertex appears several times, only its first occurence will be kept
+  for (i=size(bunchoflines);i>=2;i--)
+  {
+    for (j=i-1;j>=1;j--)
+    {
+      if (bunchoflines[i][1]==bunchoflines[j][1])
+      {
+        bunchoflines=delete(bunchoflines,i);
+        j=0;
+      }
+    }
+  }
+  // sort the lines in an descending way according to the leading
+  // exponent of the polynomial
+  // defining the Newton polygone
+  list nbol;
+  list maximum;
+  while (size(bunchoflines)!=0)
+  {
+    j=1;
+    maximum=bunchoflines[1];
+    for (i=2;i<=size(bunchoflines);i++)
+    {
+      if (deg(bunchoflines[i][2])<deg(maximum[2]))
+      {
+        maximum=bunchoflines[i];
+        j=i;
+      }
+    }
+    nbol=nbol+list(maximum);
+    bunchoflines=delete(bunchoflines,j);
+  }
+  bunchoflines=nbol;
+  // define the lines by a point on the line and the direction vector
+  list graph,gr;
+  intmat M[2][1];
+  intvec extrema;
+  poly xc,yc,cc;
+  list NSD;
+  NSD[1]=leadexp(bunchoflines[1][2][size(bunchoflines[1][2])]);
+  for (i=1;i<=size(bunchoflines);i++)
+  {
+    NSD[i+1]=leadexp(bunchoflines[i][2]);
+    extrema=leadexp(bunchoflines[i][2])-leadexp(bunchoflines[i][2][size(bunchoflines[i][2])]);
+    cc=substitute(bunchoflines[i][1],var(2),0,var(1),0);
+    xc=substitute(bunchoflines[i][1]-cc,var(2),0,var(1),1);
+    yc=substitute(bunchoflines[i][1]-cc,var(2),1,var(1),0);
+    if (xc!=0) // then there is a point on the line with y-coordinate zero
+    {
+      gr[1]=-cc/leadcoef(xc);
+      gr[2]=0;
+    }
+    else // if there is no point with y-coordinate zero, then
+    { // there is point with x-coordinate zero
+      gr[1]=0;
+      gr[2]=-cc/leadcoef(yc);
+    }
+    gr[3]=M;
+    gr[4]=list(list(intvec(direction[2],-direction[1]),gcd(extrema[1],extrema[2])),list(intvec(-direction[2],direction[1]),1));
+    gr[5]=bunchoflines[i][2];
+    graph[i]=gr;
+  }
+  graph=graph+list(list(NSD,list(),intvec(0,0)));
+  return(graph);
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+static proc clearintmat (intmat vv)
+"USAGE:      clearintmat(vv); vv intmat
+ASSUME:      all entries of the first column of vv are non-negative,
+             not all entries are zero unless vv has only one column
+RETURN:      intmat, vv has been ordered in an ascending way by the entries
+                     of the first row;
+                     if an entry in the first row occurs several times, the
+                     entries in the second row have been added and only one
+                     row has been kept;
+                     colums with a zero in the first row have been removed
+                     unless vv has only one column
+NOTE:        called by tropicalCurve"
+{
+  vv=sortintmat(vv);
+  for (int i=ncols(vv)-1;i>=1;i--)
+  {
+    if (vv[1,i]==vv[1,i+1])
+    {
+      vv[2,i]=vv[2,i]+vv[2,i+1];
+      vv=intmatcoldelete(vv,i+1);
+    }
+    if (vv[1,i]==0)
+    {
+      vv=intmatcoldelete(vv,i);
+    }
+  }
+  return(vv);
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+static proc sortintvec (intvec w)
+"USAGE:      sortintvec(v); v intvec
+RETURN:      intvec, the entries of v are ordered in an ascending way
+NOTE:        not called at all"
+{
+  int j,k,stop;
+  intvec v=w[1];
+  for (j=2;j<=size(w);j++)
+  {
+    k=1;
+    stop=0;
+    while ((k<=size(v)) and (stop==0))
+    {
+      if (v[k]<w[j])
+      {
+        k++;
+      }
+      else
+      {
+        stop=1;
+      }
+    }
+    if (k==size(v)+1)
+    {
+      v=v,w[j];
+    }
+    else
+    {
+      if (k==1)
+      {
+        v=w[j],v;
+      }
+      else
+      {
+        v=v[1..k-1],w[j],v[k..size(v)];
+      }
+    }
+  }
+  return(v);
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+static proc sortintmat (intmat vv)
+"USAGE:      sortintmat(vv); vv intmat
+RETURN:      intmat, the columns of vv have been ordered in an ascending
+                     way by the first entry
+NOTE:        called by clearintmat"
+{
+  if(ncols(vv)==1)
+  {
+    return(vv);
+  }
+  intvec v=vv[1,1..ncols(vv)];
+  list ww=minInIntvec(v);
+  intmat M[2][1]=vv[1..2,ww[2]];
+  vv=sortintmat(intmatcoldelete(vv,ww[2]));
+  return(intmatconcat(M,vv));
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+static proc intmatcoldelete (intmat w,int i)
+"USAGE:      intmatcoldelete(w,i); w intmat, i int
+RETURN:      intmat, the integer matrix w with the ith comlumn deleted
+NOTE:        the procedure is called by intmatsort and normalFan"
+{
+  if ((i<1) or (i>ncols(w)) or (ncols(w)==1))
+  {
+    return(w);
+  }
+  if (i==1)
+  {
+    intmat M[nrows(w)][ncols(w)-1]=w[1..nrows(w),2..ncols(w)];
+    return(M);
+  }
+  if (i==ncols(w))
+  {
+    intmat M[nrows(w)][ncols(w)-1]=w[1..nrows(w),1..ncols(w)-1];
+    return(M);
+  }
+  else
+  {
+    intmat M[nrows(w)][i-1]=w[1..nrows(w),1..i-1];
+    intmat N[nrows(w)][ncols(w)-i]=w[1..nrows(w),i+1..ncols(w)];
+    return(intmatconcat(M,N));
+  }
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+static proc intmatconcat (intmat M,intmat N)
+"USAGE:      intmatconcat(M,N); M,N intmat
+RETURN:      intmat, M and N concatenated
+NOTE:        the procedure is called by intmatcoldelete and sortintmat"
+{
+  if (nrows(M)>=nrows(N))
+  {
+    int m=nrows(M);
+
+  }
+  else
+  {
+    int m=nrows(N);
+  }
+  intmat P[m][ncols(M)+ncols(N)];
+  P[1..nrows(M),1..ncols(M)]=M[1..nrows(M),1..ncols(M)];
+  P[1..nrows(N),ncols(M)+1..ncols(M)+ncols(N)]=N[1..nrows(N),1..ncols(N)];
+  return(P);
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+static proc minInIntvec (intvec v)
+"USAGE:      minInIntvec(v); v intvec
+RETURN:      list, first entry is the minimal value in v, second entry
+                   is its position in v
+NOTE:        called by sortintmat"
+{
+  int min=v[1];
+  int minpos=1;
+  for (int i=2;i<=size(v);i++)
+  {
+    if (v[i]<min)
+    {
+      min=v[i];
+      minpos=i;
+    }
+  }
+  return(list(v[minpos],minpos));
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+static proc positionInList (list L,intvec v)
+"USAGE:      positionInList(L,v); L list, v intvec
+RETURN:      int, the position in L in which v occurs first
+NOTE:        called by tropicalCurve"
+{
+  for (int i=1;i<=size(L);i++)
+  {
+    if (v==L[i])
+    {
+      return(i);
+    }
+  }
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+static proc sortlist (list v,int pos)
+"USAGE:      sortlist(v,pos); v list, pos int
+RETURN:      list, the list L ordered in an ascending way according
+                   to the pos-th entries
+NOTE:        called by tropicalCurve"
+{
+  if(size(v)==1)
+  {
+    return(v);
+  }
+  list w=minInList(v,pos);
+  v=delete(v,w[2]);
+  v=sortlist(v,pos);
+  v=list(w[1])+v;
+  return(v);
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+static proc minInList (list v,int pos)
+"USAGE:      minInList(v,pos); v list, pos int
+RETURN:      list, (v[i],i) such that v[i][pos] is minimal
+NOTE:        called by sortlist"
+{
+  int min=v[1][pos];
+  int minpos=1;
+  for (int i=2;i<=size(v);i++)
+  {
+    if (v[i][pos]<min)
+    {
+      min=v[i][pos];
+      minpos=i;
+    }
+  }
+  return(list(v[minpos],minpos));
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+static proc vergleiche (poly wert,poly vglwert,list #)
+"USAGE:      vergleiche(wert,vglwert,liste), wert, vglwert poly, liste list
+RETURN:      int, if list contains a string as first entry then 1
+                  is returned if wert is at most vglwert and 0 if wert is
+                  larger than vglwert, if liste is anything else 1 is returned if
+                  wert is at least vglwert and 0 if wert s less than vglwert"
+{
+  def BASERING=basering;
+  ring testring=0,x,lp;
+  poly wert=imap(BASERING,wert);
+  poly vglwert=imap(BASERING,vglwert);
+  int ergebnis;
+  if (size(#)==0)
+  {
+    ergebnis=1-(wert>vglwert);
+  }
+  if (size(#)>0)
+  {
+    if (typeof(#[1])=="string")
+    {
+      ergebnis=1-(wert<vglwert);
+    }
+    else
+    {
+      ergebnis=1-(wert>vglwert);
+    }
+  }
+  setring BASERING;
+  return(ergebnis);
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+static proc koeffizienten (poly f,int k)
+"USAGE:      koeffizienten(f,k)  f poly, k int
+ASSUME:      f=a*x+b*y+c is a linear polynomial in two variables,
+             k is either 0, 1 or 2
+RETURN:      poly, one of the coefficients of f, depending on the value of k:
+                   k=0 : c is returned
+                   k=1 : a is returned
+                   k=2 : b is returned
+NOTE:        the procedure is called from tropicalCurve"
+{
+  poly c=substitute(f,var(1),0,var(2),0);
+  if (k==0)
+  {
+    return(c);
+  }
+  f=f-c;
+  if (k==1)
+  {
+    return(substitute(f,var(1),1,var(2),0));
+  }
+  else
+  {
+    return(substitute(f,var(1),0,var(2),1));
+  }
+}
+
+////////////////////////////////////////////////////////////////////////////
+/// Procedures used in tex-procedures and conicWithTangents:
+/// - minOfPolys
+/// - shorten
+/// - minOfStringDecimal
+/// - decimal
+/// - stringdelete
+/// - stringinsert
+/// - texmonomial
+/// - texcoefficient
+/// - abs
+/////////////////////////////////////////////////////////////////////////////
+
+static proc minOfPolys (list v)
+"USAGE:      minOfPolys(v); v list
+RETURN:      poly, the minimum of the numbers in v
+NOTE:        called by texDrawTropical"
+{
+  poly min=v[1];
+  for (int i=2;i<=size(v);i++)
+  {
+    if (v[i]<min)
+    {
+      min=v[i];
+    }
+  }
+  return(min);
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+proc shorten (list AA)
+"USAGE:      shorten(AA); AA list
+ASSUME:      AA has three entries representing decimal numbers a, b and c
+RETURN:      list, containing strings representing the numbers a and b scaled
+                   down so that the absolute maximum of the two is no
+                   larger than c
+NOTE:        the procedure is called by texDrawTropical"
+{
+  ring REALRING=(real,50,100),x,lp;
+  execute("number aa,bb,cc="+AA[1]+","+AA[2]+","+AA[3]+";");
+  number ascale,bscale=1,1;
+  if ((aa>cc) or (aa<-cc))
+  {
+    ascale=abs(cc/aa);
+  }
+  if ((bb>cc) or (bb<-cc))
+  {
+    bscale=abs(cc/bb);
+  }
+  if (ascale<bscale)
+  {
+    aa=aa*ascale;
+    bb=bb*ascale;
+  }
+  else
+  {
+    aa=aa*bscale;
+    bb=bb*bscale;
+  }
+  return(list(string(aa),string(bb)));
+}
+
+
+/////////////////////////////////////////////////////////////////////////
+
+static proc minOfStringDecimal (string a, string b)
+"USAGE:      minOfStringDecimal(a,b); a,b string
+ASSUME:      a and b are strings representing decimal numbers
+RETURN:      string, the string representing the larger of the two numbers a or b
+NOTE:        the procedure is called by texDrawTropical"
+{
+  ring REALRING=(real,50,100),x,lp;
+  execute("poly aa,bb="+a+","+b+";");
+  if (aa<bb)
+  {
+    return(a);
+  }
+  else
+  {
+    return(b);
+  }
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+static proc decimal (poly n,list #)
+"USAGE:      decimal(f[,#]); f poly, # list
+ASSUME:      f is a polynomial in Q[x_1,...,x_n], and # is either empty
+             or #[1] is a positive integer
+RETURN:      string, a decimal expansion of the leading coefficient of f up
+                     to order two respectively #[1]
+NOTE:        the procedure is called by texDrawTropical and conicWithTangents
+             and f will actually be a number"
+{
+  def BASERING=basering;
+  execute("ring INTERRING=0,("+varstr(basering)+"),("+ordstr(basering)+");");
+  poly n=imap(BASERING,n);
+  execute("ring REALRING=(real,50,100),("+varstr(basering)+"),("+ordstr(basering)+");");
+  map phi=INTERRING,maxideal(1);
+  string s=string(phi(n));
+  int check=0;
+  int i=1;
+  int j;
+  string news;
+  int nachkomma=2;
+  if (size(#)>0)
+  {
+    nachkomma=#[1];
+  }
+  while ((check==0) and i<=size(s))
+  {
+    if (s[i]==".")
+    {
+      if (i+nachkomma>size(s))
+      {
+        nachkomma=size(s)-i;
+      }
+      for (j=i;j<=i+nachkomma;j++)
+      {
+        news=news+s[j];
+      }
+      check=1;
+    }
+    else
+    {
+      news=news+s[i];
+    }
+    i++;
+  }
+  setring BASERING;
+  return(news);
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+static proc stringcontainment (string a, string b)
+"USAGE:      stringcontainment(a,b); a,b string
+ASSUME:      a is a string containing a single letter
+RETURN:      int, one if a is one of the letters in b and zero else
+NOTE:        the procedure is called from extremeraysC"
+{
+  int i;
+  for (i=1;i<=size(b);i++)
+  {
+    if (a==b[i])
+    {
+      return(1);
+    }
+  }
+  return(0);
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+static proc stringdelete (string w,int i)
+"USAGE:      stringdelete(w,i); w string, i int
+RETURN:      string, the string w with the ith component deleted
+NOTE:        the procedure is called by texNumber and choosegfanvector"
+{
+  if ((i>size(w)) or (i<=0))
+  {
+    return(w);
+  }
+  if ((size(w)==1) and (i==1))
+  {
+    return("");
+
+  }
+  if (i==1)
+  {
+    return(w[2..size(w)]);
+  }
+  if (i==size(w))
+  {
+    return(w[1..size(w)-1]);
+  }
+  else
+  {
+    string erg=w[1..i-1],w[i+1..size(w)];
+    return(erg);
+  }
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+static proc stringinsert (string w,string v,int i)
+"USAGE:      stringinsert(w,v,i); w string, v string, i int
+RETURN:      string, the string w where at the ith component v has been inserted
+NOTE:        the procedure is called by texmonomial"
+{
+  if (i==1)
+  {
+    return(v[1]+w);
+  }
+  if (i==size(w)+1)
+  {
+    return(w+v[1]);
+  }
+  else
+  {
+    string anfang=w[1..i-1];
+    string ende=w[i..size(w)];
+    string erg=anfang+v+ende;
+    return(erg);
+  }
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+static proc texmonomial (poly f)
+"USAGE:      texmonomial(f); f poly
+RETURN:      string, the tex-command for the leading monomial of f
+NOTE:        the procedure is called by texPolynomial and texNumber"
+{
+  int altshort=short;
+  short=0;
+  string F=string(leadmonom(f));
+  int k;
+  for (int j=1;j<=size(F);j++)
+  {
+    if (F[j]=="^")
+    {
+      F=stringinsert(F,"{",j+1);
+      k=j+2;
+      while (k<=size(F) and ((F[k]=="0") or (F[k]=="1") or (F[k]=="2") or (F[k]=="3") or
+                                (F[k]=="4") or (F[k]=="5") or (F[k]=="6") or (F[k]=="7") or (F[k]=="8")
+                             or (F[k]=="9")))
+      {
+        k++;
+      }
+      F=stringinsert(F,"}",k);
+      j=k+1;
+    }
+    if (F[j]=="(")
+    {
+      F=stringdelete(F,j);
+      F=stringinsert(F,"_{",j);
+      k=j+2;
+      while (k<=size(F) and ((F[k]=="0") or (F[k]=="1") or (F[k]=="2") or (F[k]=="3") or
+                                (F[k]=="4") or (F[k]=="5") or (F[k]=="6") or (F[k]=="7") or (F[k]=="8")
+                             or (F[k]=="9")))
+      {
+        k++;
+      }
+      F=stringdelete(F,k);
+      F=stringinsert(F,"}",k);
+      j=k;
+    }
+    if (F[j]=="*")
+    {
+      F=stringdelete(F,j);
+      j--;
+    }
+  }
+  short=altshort;
+  return(F);
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+static proc texcoefficient (poly f,list #)
+"USAGE:      texcoefficient(f[,#]); f poly, # optional list
+RETURN:      string, the tex command representing the leading coefficient
+                     of f using \frac as coefficient
+NOTE:        if # is non-empty, then the cdot at the end is omitted;
+             this is needed for the constant term"
+{
+  string cdot;
+  if (size(#)==0)
+  {
+    cdot="\\cdot ";
+  }
+  string koeffizient=texNumber(f);
+  if (koeffizient=="1")
+  {
+    if (size(#)==0)
+    {
+      return("");
+    }
+    else
+    {
+      return(koeffizient);
+    }
+  }
+  if (koeffizient=="-1")
+  {
+    if (size(#)==0)
+    {
+      return("-");
+    }
+    else
+    {
+      return(koeffizient);
+    }
+  }
+  if (size(koeffizient)>5)
+  {
+    string tfractest=koeffizient[2..6];
+    if (tfractest=="tfrac")
+    {
+      return(koeffizient+cdot);
+    }
+  }
+  int anzahlplus,anzahlminus;
+  for(int j=1;j<=size(koeffizient);j++)
+  {
+    if (koeffizient[j]=="+")
+    {
+      anzahlplus++;
+    }
+    if (koeffizient[j]=="-")
+    {
+      anzahlminus++;
+    }
+  }
+  if ((anzahlplus==0) and (anzahlminus==1) and (koeffizient[1]=="-"))
+  {
+    return(koeffizient+cdot);
+  }
+  else
+  {
+    if (anzahlplus+anzahlminus>=1)
+    {
+      return("("+koeffizient+")"+cdot);
+    }
+    else
+    {
+      return(koeffizient+cdot);
+    }
+  }
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+static proc abs (def n)
+"USAGE:      abs(n); n poly or int
+RETURN:      poly or int, the absolute value of n"
+{
+  if (n>=0)
+  {
+    return(n);
+  }
+  else
+  {
+    return(-n);
+  }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Procedures only used to compute j-invariants
+/// - findNonLoopVertex
+/// - coordinatechange
+/// - weierstrassFormOfACubic
+/// - weierstrassFormOfA4x2Curve
+/// - weierstrassFormOfA2x2Curve
+/// - jInvariantOfACubic
+/// - jInvariantOfA4x2Curve
+/// - jInvariantOfA2x2Curve
+/// - jInvariantOfAPuiseuxCubic
+///////////////////////////////////////////////////////////////////////////////
+
+static proc findNonLoopVertex (list graph)
+"USAGE:      findNonLoopVertex(graph); graph list
+ASSUME:      graph is a list as in the output of tropicalCurve
+RETURN:      int, the number of a vertex which has only one edge
+NOTE:        the procedure is called by tropicalJInvariant"
+{
+  int i,j;
+  for (i=1;i<=size(graph)-1;i++)
+  {
+    if ((ncols(graph[i][3])==1) and (graph[i][3][1,1]!=0))
+    {
+      return(i);
+    }
+  }
+  return(-1);
+}
+
+
+/////////////////////////////////////////////////////////////////////////
+
+static proc coordinatechange (poly f,intmat A,intvec v)
+"USAGE:   coordinatechange(f,A,v);  f poly, A intmat, v intvec
+ASSUME:   f is a polynomial in two variables, A is a 2x2
+          integer matrix, and v is an integer vector with 2 entries
+RETURN:   poly, the polynomial transformed by (x,y)->A*(x,y)+v
+NOTE:     the procedure is called by weierstrassForm"
+{
+  poly g;
+  int i;
+  intmat exp[2][1];
+  for (i=1;i<=size(f);i++)
+  {
+    exp=leadexp(f[i]);
+    exp=A*exp;
+    g=g+leadcoef(f[i])*var(1)^(exp[1,1]+v[1])*var(2)^(exp[2,1]+v[2]);
+  }
+  return(g);
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+static proc weierstrassFormOfACubic (poly f,list #)
+"USAGE:      weierstrassFormOfACubic(wf[,#]); wf poly, # list
+ASSUME:      poly is a cubic polynomial
+RETURN:      poly, the Weierstrass normal form of the cubic, 0 if poly is
+                   not a cubic
+NOTE:        - the algorithm for the coefficients of the Weierstrass form is due
+               to Fernando Rodriguez Villegas, villegas at math.utexas.edu
+             - if an additional argument # is given, the simplified Weierstrass
+               form is computed
+             - the procedure is called by weierstrassForm
+             - the characteristic of the base field should not be 2 or 3
+               if # is non-empty"
+{
+  if (deg(f)!=3)
+  {
+    ERROR("The curve is not a cubic!");
+  }
+  // store the coefficients of f in a specific order
+  poly t0,s1,s0,r2,r1,r0,q3,q2,q1,q0=flatten(coeffs(f,ideal(var(2)^3,var(2)^2,var(2)^2*var(1),var(2),var(2)*var(1),var(2)*var(1)^2,1,var(1),var(1)^2,var(1)^3)));
+  // test, if f is already in Weierstrass form
+  if ((t0==0) and (s1==1) and (s0==0) and (r0==0) and (q0==-1) and (size(#)==0))
+  {
+    return (f);
+  }
+  // compute the coefficients a1,a2,a3,a4, and a6 of the Weierstrass
+  // form y^2+a1xy+a3y=x^3+a2x^2+a4x+a6
+  poly a1=r1;
+  poly a2=-(s0*q2+s1*q1+r0*r2);
+  poly a3=(9*t0*q0-s0*r0)*q3+((-t0*q1-s1*r0)*q2+(-s0*r2*q1-s1*r2*q0));
+  poly a4=((-3*t0*r0+s0^2)*q1+(-3*s1*s0*q0+s1*r0^2))*q3
+    +(t0*r0*q2^2+(s1*s0*q1+((-3*t0*r2+s1^2)*q0+s0*r0*r2))*q2
+      +(t0*r2*q1^2+s1*r0*r2*q1+s0*r2^2*q0));
+  poly a6=(-27*t0^2*q0^2+(9*t0*s0*r0-s0^3)*q0-t0*r0^3)*q3^2+
+        (((9*t0^2*q0-t0*s0*r0)*q1+((-3*t0*s0*r1+(3*t0*s1*r0+
+        2*s1*s0^2))*q0+(t0*r0^2*r1-s1*s0*r0^2)))*q2+(-t0^2*q1^3
+        +(t0*s0*r1+(2*t0*s1*r0-s1*s0^2))*q1^2+((3*t0*s0*r2+
+        (-3*t0*s1*r1+2*s1^2*s0))*q0+((2*t0*r0^2-s0^2*r0)*r2+
+        (-t0*r0*r1^2+s1*s0*r0*r1-s1^2*r0^2)))*q1+((9*t0*s1*r2-
+        s1^3)*q0^2+(((-3*t0*r0+s0^2)*r1-s1*s0*r0)*r2+(t0*r1^3
+        -s1*s0*r1^2+s1^2*r0*r1))*q0)))*q3+(-t0^2*q0*q2^3+
+        (-t0*s1*r0*q1+((2*t0*s0*r2+(t0*s1*r1-s1^2*s0))*q0-
+        t0*r0^2*r2))*q2^2+(-t0*s0*r2*q1^2+(-t0*s1*r2*q0+
+        (t0*r0*r1-s1*s0*r0)*r2)*q1+((2*t0*r0-s0^2)*r2^2+
+        (-t0*r1^2+s1*s0*r1-s1^2*r0)*r2)*q0)*q2+
+        (-t0*r0*r2^2*q1^2+(t0*r1-s1*s0)*r2^2*q0*q1-
+     t0*r2^3*q0^2));
+  poly b2=a1^2+4*a2;
+  poly b4=2*a4+a1*a3;
+  poly b6=a3^2+4*a6;
+  poly b8=a1^2*a6+4*a2*a6-a1*a3*a4+a2*a3^2-a4^2;
+  poly c4=b2^2-24*b4;
+  poly c6=-b2^3+36*b2*b4-216*b6;
+  if (size(#)!=0)
+  {
+    return(substitute(var(2)^2+a1*var(1)*var(2)+a3*var(2)-var(1)^3-a2*var(1)^2-a4*var(1)-a6,var(2),var(2)-(a1*var(1)+a3)/2));
+  }
+  else
+  {
+    return(var(2)^2+a1*var(1)*var(2)+a3*var(2)-var(1)^3-a2*var(1)^2-a4*var(1)-a6);
+  }
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+static proc weierstrassFormOfA4x2Curve (poly f)
+"USAGE:      weierstrassFormOfA4x2Curve(wf); wf poly
+ASSUME:      poly is a polynomial of type 4x2
+RETURN:      poly, the Weierstrass normal form of the curve
+NOTE:        - the procedure is called by weierstrassForm
+             - the characteristic of the base field should not be 2 or 3"
+{
+  poly u11,u40,u30,u20,u10,u00,u21,u01,u02=flatten(coeffs(f,ideal(var(1)*var(2),var(1)^4,var(1)^3,var(1)^2,var(1),1,var(1)^2*var(2),var(2),var(2)^2)));
+  poly c4=(u11^4 - 8*u11^2*u20*u02 - 8*u11^2*u01*u21 + 24*u11*u10*u21*u02 + 24*u11*u30*u01*u02 +
+           192*u00*u40*u02^2 - 48*u00*u21^2*u02 - 48*u10*u30*u02^2 + 16*u20^2*u02^2 -
+           16*u20*u01*u21*u02 - 48*u40*u01^2*u02 + 16*u01^2*u21^2)/lead(u02^4);
+  poly c6=(-u11^6 + 12*u11^4*u20*u02 + 12*u11^4*u01*u21 - 36*u11^3*u10*u21*u02 - 36*u11^3*u30*u01*u02 +
+           576*u11^2*u00*u40*u02^2 + 72*u11^2*u00*u21^2*u02 + 72*u11^2*u10*u30*u02^2 -
+           48*u11^2*u20^2*u02^2 - 24*u11^2*u20*u01*u21*u02 + 72*u11^2*u40*u01^2*u02 -
+           48*u11^2*u01^2*u21^2 - 864*u11*u00*u30*u21*u02^2 + 144*u11*u10*u20*u21*u02^2 -
+           864*u11*u10*u40*u01*u02^2 + 144*u11*u10*u01*u21^2*u02 + 144*u11*u20*u30*u01*u02^2 +
+           144*u11*u30*u01^2*u21*u02 - 2304*u00*u20*u40*u02^3 + 576*u00*u20*u21^2*u02^2 +
+           864*u00*u30^2*u02^3 + 1152*u00*u40*u01*u21*u02^2 - 288*u00*u01*u21^3*u02 +
+           864*u10^2*u40*u02^3 - 216*u10^2*u21^2*u02^2 - 288*u10*u20*u30*u02^3 +
+           144*u10*u30*u01*u21*u02^2 + 64*u20^3*u02^3 - 96*u20^2*u01*u21*u02^2 +
+           576*u20*u40*u01^2*u02^2 - 96*u20*u01^2*u21^2*u02 - 216*u30^2*u01^2*u02^2 -
+           288*u40*u01^3*u21*u02 + 64*u01^3*u21^3)/lead(u02^6);
+  return(var(2)^2-var(1)^3+27*c4*var(1)+54*c6);
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+static proc weierstrassFormOfA2x2Curve (poly f)
+"USAGE: weierstrassFormOfA2x2Curve(f); f poly
+ASSUME: poly, is a polynomial defining an elliptic curve of type (2,2) on P^1xP^1
+        i.e. a polynomial of the form a+bx+cx2+dy+exy+fx2y+gy2+hxy2+ix2y2
+RETURN: poly, a Weierstrass form of the elliptic curve defined by poly
+NOTE:   - the algorithm is based on the paper Sang Yook An, Seog Young Kim,
+          David C. Marshall, Susan H. Marshall, William G. McCallum and
+          Alexander R. Perlis: Jacobians of Genus One Curves. Journal of Number
+          Theory 90,2 (2001), 304-315.
+        - the procedure is called by weierstrassForm
+        - the characteristic of the base field should not be 2 or 3"
+{
+  // get the coefficients of the polynomial
+  poly A00,A10,A20,A01,A11,A21,A02,A12,A22=flatten(coeffs(f,ideal(1,var(1),var(1)^2,var(2),var(1)*var(2),var(1)^2*var(2),var(2)^2,var(1)*var(2)^2,var(1)^2*var(2)^2)));
+  // define P1xP1 as quadric in P3
+  matrix A[4][4]=0,0,0,1/2,0,0,1/2,0,0,1/2,0,0,1/2,0,0,0;
+  // define the image of the (2,2)-curve under the Segre embedding
+  // as quadric which should be
+  // intersected with the image of P1xP1
+  matrix B[4][4]=A00,A10/2,A01/2,0,A10/2,A20,A11/2,A21/2,A01/2,A11/2,A02,A12/2,0,A21/2,A12/2,A22;
+  // compute the coefficients of the Weierstrass form of
+  // the input polynomial and its j-invariant
+  poly a=det(x*A+B);
+  poly a0,a1,a2,a3,a4=flatten(coeffs(a,ideal(x4,x3,x2,x,1)));
+  a1,a2,a3=-a1/4,a2/6,-a3/4;
+  poly g2=a0*a4-4*a1*a3+3*a2^2;
+  poly g3=a0*a2*a4+2*a1*a2*a3-a0*a3^2-a4*a1^2-a2^3;
+  return(var(2)^2-var(1)^3+g2/4*var(1)+g3/4);
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+static proc jInvariantOfACubic (poly f,list #)
+"USAGE:      jInvariantOfACubic(f[,#]); f poly, # list
+ASSUME:      poly is a cubic polynomial defining an elliptic curve
+RETURN:      poly, the j-invariant of the elliptic curve defined by poly
+NOTE:        - if the base field is Q(t) an optional argument # may be given;
+               then the algorithm only computes the negative of the order
+               of the j-invariant"
+{
+  if (deg(f)!=3)
+  {
+    ERROR("The input polynomial is not a cubic!");
+  }
+  // compute first the Weierstrass form of the cubic
+  // - this does not change the j-invariant
+  f=weierstrassFormOfACubic(f);
+  // compute the coefficients of the Weierstrass form
+  poly a1,a2,a3,a4,a6=flatten(coeffs(f,ideal(var(1)*var(2),var(1)^2,var(2),var(1),1)));
+  a2,a4,a6=-a2,-a4,-a6;
+  // compute the j-invariant
+  poly b2=a1^2+4*a2;
+  poly b4=2*a4+a1*a3;
+  poly b6=a3^2+4*a6;
+  poly b8=a1^2*a6+4*a2*a6-a1*a3*a4+a2*a3^2-a4^2;
+  poly c4=b2^2-24*b4;
+  //  poly c6=-b2^3+36*b2*b4-216*b6;
+  poly delta=-b2^2*b8-8*b4^3-27*b6^2+9*b2*b4*b6;
+  if (delta==0)
+  {
+    ERROR("The input is a rational curve and has no j-invariant!");
+  }
+  if (size(#)>0) // if the optional argument is given, then only the
+  { // negative of the order is computed
+    int zaehler=3*simplifyToOrder(c4)[1];
+    int nenner=simplifyToOrder(delta)[1];
+    return(nenner-zaehler);
+  }
+  else
+  {
+    poly invariant=(c4^3/delta);
+    return(invariant);
+  }
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+static proc jInvariantOfA2x2Curve (poly f,list #)
+"USAGE: jInvariantOfA2x2Curve(f[,#]); f poly, # list
+ASSUME: poly, is a polynomial defining an elliptic curve of type (2,2) on P^1xP^1
+             i.e. a polynomial of the form a+bx+cx2+dy+exy+fx2y+gy2+hxy2+ix2y2
+RETURN: poly, the j-invariant of the elliptic curve defined by poly
+NOTE:   - if the base field is Q(t) an optional argument # may be given;
+          then the algorithm only computes the negative of the order of the
+          j-invariant
+        - the characteristic should not be 2 or 3
+        - the procedure is not called at all, it is just stored for the purpose
+          of comparison"
+{
+  // get the coefficients of the polynomial
+  poly A00,A10,A20,A01,A11,A21,A02,A12,A22=flatten(coeffs(f,ideal(1,var(1),var(1)^2,var(2),var(1)*var(2),var(1)^2*var(2),var(2)^2,var(1)*var(2)^2,var(1)^2*var(2)^2)));
+  // define P1xP1 as quadric in P3
+  matrix A[4][4]=0,0,0,1/2,0,0,1/2,0,0,1/2,0,0,1/2,0,0,0;
+  // define the image of the (2,2)-curve under the Segre embedding as quadric which should be
+  // intersected with the image of P1xP1
+  matrix B[4][4]=A00,A10/2,A01/2,0,A10/2,A20,A11/2,A21/2,A01/2,A11/2,A02,A12/2,0,A21/2,A12/2,A22;
+  // compute the coefficients of the Weierstrass form of
+  // the input polynomial and its j-invariant
+  poly a=det(var(1)*A+B);
+  poly a0,a1,a2,a3,a4=flatten(coeffs(a,ideal(var(1)^4,var(1)^3,var(1)^2,var(1),1)));
+  a1,a2,a3=-a1/4,a2/6,-a3/4;
+  poly g2=a0*a4-4*a1*a3+3*a2^2;
+  poly g3=a0*a2*a4+2*a1*a2*a3-a0*a3^2-a4*a1^2-a2^3;
+  poly G2cube=g2^3;
+  poly G3square=g3^2;
+  poly jinvnum=1728*G2cube;
+  poly jinvdenom=-27*G3square+G2cube;
+  // check if the curve is rational
+  if (jinvdenom==0)
+  {
+    ERROR("The input is a rational curve and has no j-invariant!");
+  }
+  if (size(#)>0) // if the optional argument is given,
+  { // then only the negative of the order is computed
+    int zaehler=simplifyToOrder(jinvnum)[1];
+    int nenner=simplifyToOrder(jinvdenom)[1];
+    return(nenner-zaehler);
+  }
+  else
+  {
+    poly invariant=(jinvnum/jinvdenom);
+    return(invariant);
+  }
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+static proc jInvariantOfA4x2Curve (poly f,list #)
+"USAGE:      jInvariantOfA4x2Curve(f[,#]); f poly, # list
+ASSUME:      poly, is a polynomial defining an elliptic curve of type (4,2),
+             i.e. a polynomial of the form a+bx+cx2+dx3+ex4+fy+gxy+hx2y+iy2
+RETURN:      poly, the j-invariant of the elliptic curve defined by poly
+NOTE:        - if the base field is Q(t) an optional argument # may be given;
+               then the algorithm only computes the negative of the order
+               of the j-invariant
+             - the characteristic should not be 2 or 3
+             - the procedure is not called at all, it is just stored
+               for the purpose of comparison"
+{
+  poly u11,u40,u30,u20,u10,u00,u21,u01,u02=flatten(coeffs(f,ideal(var(1)*var(2),var(1)^4,var(1)^3,var(1)^2,var(1),1,var(1)^2*var(2),var(2),var(2)^2)));
+  poly c4=(u11^4 - 8*u11^2*u20*u02 - 8*u11^2*u01*u21 + 24*u11*u10*u21*u02 + 24*u11*u30*u01*u02 +
+           192*u00*u40*u02^2 - 48*u00*u21^2*u02 - 48*u10*u30*u02^2 + 16*u20^2*u02^2 -
+           16*u20*u01*u21*u02 - 48*u40*u01^2*u02 + 16*u01^2*u21^2);
+  poly c6=(-u11^6 + 12*u11^4*u20*u02 + 12*u11^4*u01*u21 - 36*u11^3*u10*u21*u02 - 36*u11^3*u30*u01*u02 +
+           576*u11^2*u00*u40*u02^2 + 72*u11^2*u00*u21^2*u02 + 72*u11^2*u10*u30*u02^2 -
+           48*u11^2*u20^2*u02^2 - 24*u11^2*u20*u01*u21*u02 + 72*u11^2*u40*u01^2*u02 -
+           48*u11^2*u01^2*u21^2 - 864*u11*u00*u30*u21*u02^2 + 144*u11*u10*u20*u21*u02^2 -
+           864*u11*u10*u40*u01*u02^2 + 144*u11*u10*u01*u21^2*u02 + 144*u11*u20*u30*u01*u02^2 +
+           144*u11*u30*u01^2*u21*u02 - 2304*u00*u20*u40*u02^3 + 576*u00*u20*u21^2*u02^2 +
+           864*u00*u30^2*u02^3 + 1152*u00*u40*u01*u21*u02^2 - 288*u00*u01*u21^3*u02 +
+           864*u10^2*u40*u02^3 - 216*u10^2*u21^2*u02^2 - 288*u10*u20*u30*u02^3 +
+           144*u10*u30*u01*u21*u02^2 + 64*u20^3*u02^3 - 96*u20^2*u01*u21*u02^2 +
+           576*u20*u40*u01^2*u02^2 - 96*u20*u01^2*u21^2*u02 - 216*u30^2*u01^2*u02^2 -
+           288*u40*u01^3*u21*u02 + 64*u01^3*u21^3);
+  poly c4cube=c4^3;
+  poly jdenom=c4cube-c6^2;
+  if (size(#)>0) // if the optional argument is given,
+  { // then only the negative of the order is computed
+    int zaehler=3*simplifyToOrder(c4)[1];
+    int nenner=simplifyToOrder(jinvdenom)[1];
+    return(nenner-zaehler);
+  }
+  else
+  {
+    return(1728*(c4cube/(jdenom)));
+  }
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+static proc jInvariantOfAPuiseuxCubic (poly f,list #)
+"USAGE:  jInvariantOfAPuiseuxCubic(f[,#]); f poly, # list
+ASSUME:  poly is a cubic polynomial over Q(t) defining an elliptic curve
+         and # is empty
+RETURN:  list, containing two polynomials whose ratio is the j-invariant
+               of the  elliptic curve defined by poly
+ASSUME:  poly is a cubic polynomial over Q(t) defining an elliptic curve
+         and # is non-empty
+RETURN:  int, the order of the j-invariant of the elliptic curve defined by poly
+NOTE:    the procedure is called by jInvariant"
+{
+  if (deg(f)!=3)
+  {
+    ERROR("The input polynomial is not a cubic!");
+  }
+  // compute first the Weierstrass form of the cubic
+  // - this does not change the j-invariant
+  f=weierstrassFormOfACubic(f);
+  // compute the coefficients of the Weierstrass form
+  poly a1,a2,a3,a4,a6=flatten(coeffs(f,ideal(var(1)*var(2),var(1)^2,var(2),var(1),1)));
+  a2,a4,a6=-a2,-a4,-a6;
+  number dna1,dna2,dna3,dna4,dna6=denominator(leadcoef(a1)),denominator(leadcoef(a2)),denominator(leadcoef(a3)),denominator(leadcoef(a4)),denominator(leadcoef(a6));
+  number na1,na2,na3,na4,na6=numerator(leadcoef(a1)),numerator(leadcoef(a2)),numerator(leadcoef(a3)),numerator(leadcoef(a4)),numerator(leadcoef(a6));
+  number hn=dna1*dna2*dna3*dna4*dna6;
+  a1=na1*dna2*dna3*dna4*dna6;
+  a2=dna1*na2*dna3*dna4*dna6;
+  a3=dna1*dna2*na3*dna4*dna6;
+  a4=dna1*dna2*dna3*na4*dna6;
+  a6=dna1*dna2*dna3*dna4*na6;
+  // compute the j-invariant
+  poly b2=a1^2+4*a2*hn;
+  poly b4=2*a4*hn+a1*a3;
+  poly b6=a3^2+4*a6*hn;
+  poly b8=a1^2*a6+4*a2*a6*hn-a1*a3*a4+a2*a3^2-a4^2*hn;
+  poly c4=b2^2-24*b4*hn^2;
+  poly delta=-b2^2*b8-8*b4^3*hn-27*b6^2*hn^3+9*b2*b4*b6*hn;
+  if (delta==0)
+  {
+    ERROR("The input is a rational curve and has no j-invariant!");
+  }
+  if (size(#)>0) // if the optional argument is given,
+  { // then only the negative of the order is computed
+    int zaehler=3*simplifyToOrder(c4)[1];
+    int nenner=simplifyToOrder(delta)[1];
+    int ordhn=simplifyToOrder(hn)[1];
+    return(zaehler-nenner-5*ordhn);
+  }
+  else
+  {
+    def BASERING=basering;
+    execute("ring TRING="+string(char(BASERING))+",t,ds;");
+    poly hn=imap(BASERING,hn);
+    poly c4=imap(BASERING,c4);
+    poly delta=imap(BASERING,delta);
+    poly num=c4^3;
+    poly denom=delta*hn^5;
+    poly ggt=gcd(num,denom);
+    num=num div ggt;
+    denom=denom div ggt;
+    setring BASERING;
+    poly num=imap(TRING,num);
+    poly denom=imap(TRING,denom);
+    number teiler=1;
+    if (char(BASERING)==0)
+    {
+      teiler=gcd(leadcoef(num),leadcoef(denom));
+    }
+    num=num/teiler;
+    denom=denom/teiler;
+    list invariant=num,denom;
+    return(invariant);
+  }
+}
+
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+/// Further examples for testing the procedures
+/////////////////////////////////////////////////////////////////////////////
+/*
+
+/// Note, only the following procedures need further examples
+/// (the others are too simple):
+/// A) tropicalLifting (best tested via displayTropicalLifting)
+/// B) tropicalCurve   (best tested via drawTropicalCurve)
+/// C) tropicalJInvariant
+/// D) weierstrassForm
+/// E) jInvariant
+
+////////////////////////////////////////////////////////////////////////////
+/// A) Examples tropicalLifting
+////////////////////////////////////////////////////////////////////////////
+// -------------------------------------------------------
+// Example 1
+// -------------------------------------------------------
+ring r0=0,(t,x),dp;
+poly f=t7-6t4+3t3x+8t3-12t2x+6tx2-x3+t2;
+f;
+// The point -2/3 is in the tropical variety.
+list L=tropicalLifting(f,intvec(3,-2),4);
+L;
+displayTropicalLifting(L,"subst");
+// --------------------------------------------------------
+// Example 2 - a field extension is necessary
+// --------------------------------------------------------
+poly g=(1+t2)*x2+t5x+t2;
+g;
+// The poin -1 is in the tropical variety.
+displayTropicalLifting(tropicalLifting(g,intvec(1,-1),4),"subst");
+// --------------------------------------------------------
+// Example 3 - the ideal is not zero dimensional
+// --------------------------------------------------------
+ring r1=0,(t,x,y),dp;
+poly f=(9t27-12t26-5t25+21t24+35t23-51t22-40t21+87t20+56t19-94t18-62t17+92t16+56t15-70t14-42t13+38t12+28t11+18t10-50t9-48t8+40t7+36t6-16t5-12t4+4t2)*x2+(-9t24+12t23-4t22-42t20+28t19+30t18-20t17-54t16+16t15+48t14-16t12+8t11-18t10-26t9+30t8+20t7-24t6+4t5+28t4-8t3-16t2+4)*xy+(6t16-10t15-2t14+16t13+4t12-18t11-10t10+24t9+6t8-20t7+8t6+8t5-20t4-4t3+12t2+4t-4)*y2+(-9t28+3t27+8t26-4t25-45t24-6t23+42t22+30t21-94t20-40t19+68t18+82t17-38t16-60t15+26t14+36t13-22t12-20t11+4t10+4t9+12t8+8t7-8t6-8t5+4t4 [...]
+f;
+displayTropicalLifting(tropicalLifting(f,intvec(1,-1,-4),3),"subst");
+// --------------------------------------------------------
+// Example 4 - the ideal has even more equations
+// --------------------------------------------------------
+ring r2=0,(t,x,y,z),dp;
+ideal i=t-x3+3yz,t2xy-2x2z;
+i;
+displayTropicalLifting(tropicalLifting(i,intvec(1,1,3,0),2),"subst");
+// --------------------------------------------------------
+// Example 5-7 - testing some options
+// --------------------------------------------------------
+setring r0;
+poly f1=(x2-t3)*(x3-t5)*(x5-t7)*(x7-t11)*(x11-t13);
+f1;
+displayTropicalLifting(tropicalLifting(f1,intvec(7,-11),4,"noAbs"),"subst");
+poly f2=(1+t2)*x2+t5x+t2;
+f2;
+displayTropicalLifting(tropicalLifting(f2,intvec(1,-1),4,"isZeroDimensional","findAll"),"subst");
+poly f3=t7-6t4+3t3x+8t3-12t2x+6tx2-x3+t2;
+f3;
+displayTropicalLifting(tropicalLifting(f3,intvec(3,-2),4,"isInTrop","findAll"),"subst");
+// ---------------------------------------------------------
+// Even more examples
+// ---------------------------------------------------------
+ring r1=0,(t,x),dp;
+poly f1=(x2-t3)*(x3-t5)*(x5-t7)*(x7-t11)*(x11-t13);
+displayTropicalLifting(tropicalLifting(f1,intvec(7,-11),4,"noAbs"),"subst");
+///////////////////////////////////////////////////////////////////
+// weight was: (7,-11)
+///////////////////////////////////////////////////////////////////
+// one field extension needed
+// x=(X(1))*t+(-1/2*X(1))*t^3+(3/8*X(1)-1/2)*t^5+(-5/16*X(1)+1/2)*t^7+(19/128*X(1)-1/2)*t^9+(-15/256*X(1)+1/2)*t^11+(-9/1024*X(1)-1/2)*t^13 where t->t and X(1)^2+1=0
+poly f2=(1+t2)*x2+t5x+t2;
+displayTropicalLifting(tropicalLifting(f2,intvec(1,-1),4,"isZeroDimensional","findAll"),"subst");
+///////////////////////////////////////////////////////////////////
+// weight was: (1,-1)
+///////////////////////////////////////////////////////////////////
+// x=t2+2t3+t7   the result is exact
+poly f3=t7-6t4+3t3x+8t3-12t2x+6tx2-x3+t2;
+displayTropicalLifting(tropicalLifting(f3,intvec(3,-2),4,"isInTrop","findAll"),"subst");
+///////////////////////////////////////////////////////////////////
+// weight was: (3,-2)
+///////////////////////////////////////////////////////////////////
+//  full parametrisation is given by t->t2+t3 and x=3t7+t9+4t11-t12, this however cannot be computed
+// so: t->t2 and x=-3t7-21/2t8-239/8t9-78t10-25589/128t11-506t12-1298967/1024t13-3159t14-256667105/32768t15-19371t16-12540259065/262144t17-118066t18-1222177873545/4194304t19-719423t20-59637294735495/33554432t21
+poly f4=t12-83t11-88t10-69t9+3t8x+153t8+298t7x-81t7+165t6x-402t5x+3t4x2+189t4x-131t3x2+213t2x2-86tx2+x3+9x2;
+displayTropicalLifting(tropicalLifting(f4,intvec(2,-7),4,"findAll"),"subst");
+///////////////////////////////////////////////////////////////////
+// weight was: (2,-7)
+///////////////////////////////////////////////////////////////////
+// t->t6 and x=3t3+t7+4t11-t12
+poly f5=t12-4120t11+6t10x-1008t10-96t9x+15t8x2+4453t9-2016t8x-144t7x2+20t6x3-18t8-108t7x-1008t6x2-96t5x3+15t4x4-4681t7-36t6x-162t5x2-24t3x4+6t2x5+243t6-18t4x2-108t3x3+x6+1890t5+486t4x-27tx4+243t2x2-729t3;
+displayTropicalLifting(tropicalLifting(f5,intvec(2,-1),3,"isInTrop","isZeroDimensional","findAll"),"subst");
+///////////////////////////////////////////////////////////////////
+// weight was: (2,-1)
+///////////////////////////////////////////////////////////////////
+ring r2=0,(t,x,y),dp;
+poly f7=(9t27-12t26-5t25+21t24+35t23-51t22-40t21+87t20+56t19-94t18-62t17+92t16+56t15-70t14-42t13+38t12+28t11+18t10-50t9-48t8+40t7+36t6-16t5-12t4+4t2)*x2+(-9t24+12t23-4t22-42t20+28t19+30t18-20t17-54t16+16t15+48t14-16t12+8t11-18t10-26t9+30t8+20t7-24t6+4t5+28t4-8t3-16t2+4)*xy+(6t16-10t15-2t14+16t13+4t12-18t11-10t10+24t9+6t8-20t7+8t6+8t5-20t4-4t3+12t2+4t-4)*y2+(-9t28+3t27+8t26-4t25-45t24-6t23+42t22+30t21-94t20-40t19+68t18+82t17-38t16-60t15+26t14+36t13-22t12-20t11+4t10+4t9+12t8+8t7-8t6-8t5+4t [...]
+displayTropicalLifting(tropicalLifting(f7,intvec(1,-1,-4),4,"isPrime"),"subst");
+///////////////////////////////////////////////////////////////////
+// weight was: (1,-1,-4)
+///////////////////////////////////////////////////////////////////
+ring r3=0,(t,x,y,z),dp;
+ideal i1=-y2t4+x2,yt3+xz+y;
+displayTropicalLifting(tropicalLifting(i1,intvec(1,-2,0,2),4,"findAll"),"subst");
+///////////////////////////////////////////////////////////////////
+// weight was: (1,-2,0,2)
+///////////////////////////////////////////////////////////////////
+ideal i2=-y2t4+x2,yt3+yt2+xz;
+displayTropicalLifting(tropicalLifting(i2,intvec(1,-3,-1,0),4),"subst");
+///////////////////////////////////////////////////////////////////
+// weight was: (1,-3,-1,0)
+////////////////////////////////////////////////////////////////
+ring r4=0,(t,x,y,z,u),dp;
+ideal i3=t3x+ty+u,tx+t2u+y;
+displayTropicalLifting(tropicalLifting(i3,intvec(1,-1,-2,-1,-3),6),"subst");
+///////////////////////////////////////////////////////////////////
+// weight was: (1,-1,-2,-1,-3)
+/////////////////////////////////////////////////////////////////////
+setring r2;
+ideal i5=t3-t2y+t2-tx-ty+xy,t3-t2y+t2-2ty+y2,-t4+2t3x-t2x2-t3+3t2x-3tx2+x3+t2+t-x,-t4+2t3x-t2x2-t3+2t2x-tx2+t2y-2txy+x2y+t2+t-y;
+displayTropicalLifting(tropicalLifting(i5,intvec(1,-1,-1),3),"subst");
+///////////////////////////////////////////////////////////////////
+// weight was: (1,-1,-1)
+////////////////////////////////////////////////////////////////////
+ring r5=0,(t,V,W,X,Y,Z),dp;
+ideal i5=VXt5+3VZt4-2VXt3+WXt3+V2t2+3WZt2-2WXt+VW,-4W2X4+V2t2;
+displayTropicalLifting(tropicalLifting(i5,intvec(2,-3,-3,-1,-1,-1),3),"subst");
+///////////////////////////////////////////////////////////////////
+// weight was: (2,-3,-3,-1,-1,-1)
+///////////////////////////////////////////////////////////////////
+ring r6=0,(t,x,y,z),dp;
+ideal i6=t4xy-y3z3+3t2xy3-txy2+t4y;
+displayTropicalLifting(tropicalLifting(i6,intvec(3,0,-9,2),4),"subst");
+///////////////////////////////////////////////////////////////////
+// weight was: (3,0,-9,2)
+////////////////////////////////////////////////////////////
+// very easy example stops after one loop with an exact result
+ideal i7=t2xy-2x2z;
+displayTropicalLifting(tropicalLifting(i7,intvec(1,1,3,0),4),"subst");
+///////////////////////////////////////////////////////////////////
+// weight was: (1,1,3,0)
+/////////////////////////////////////////////////////////////
+displayTropicalLifting(tropicalLifting(i7,intvec(1,-3,-1,0),4),"subst");
+///////////////////////////////////////////////////////////////////
+// weight was: (1,-3,-1,0)
+/////////////////////////////////////////////////////////////////
+// requires one field extension
+ideal i8=t-x3+3yz;
+displayTropicalLifting(tropicalLifting(i8,intvec(1,1,3,0),4),"subst");
+///////////////////////////////////////////////////////////////////
+// weight was: (1,1,3,0)
+/////////////////////////////////////////////////////////////////
+displayTropicalLifting(tropicalLifting(i8,intvec(1,-3,-1,0),4),"subst");
+///////////////////////////////////////////////////////////////////
+// weight was: (1,-3,-1,0)
+/////////////////////////////////////////////////////////////////
+// requires one field extension
+ideal i9=t-x3+3yz,t2xy-2x2z;
+displayTropicalLifting(tropicalLifting(i9,intvec(1,1,3,0),4),"subst");
+///////////////////////////////////////////////////////////////////
+// weight was: (1,1,3,0)
+// takes too much time
+//displayTropicalLifting(tropicalLifting(i9,intvec(1,-3,-1,0),4),"subst");
+///////////////////////////////////////////////////////////////////
+// weight was: (1,-3,-1,0)
+/////////////////////////////////////////////////////////////////////
+// too much for Gfan did not work on my computer
+//ideal i10=t2xy+t4-z2,t-2xy+z2+tz,z2-y;
+//displayTropicalLifting(tropicalLifting(i10,intvec(2,4,-6,-3),2),"subst");
+///////////////////////////////////////////////////////////////////
+// weight was: (2,4,-6,-3)
+////////////////////////////////////////////////////////////////////
+ring r7=0,(t,x,y),dp;
+ideal i11=t4xy-y3+3t2xy3-txy2+t4y;
+displayTropicalLifting(tropicalLifting(i11,intvec(1,3,1),5),"subst");
+///////////////////////////////////////////////////////////////////
+// weight was: (1,3,1)
+////////////////////////////////////////////////////////////////
+ring r8=0,(t,x),dp;
+ideal i12=x32+(16t6)*x30+(8t10)*x29+(120t12)*x28+(112t16)*x27+(32t20+560t18)*x26+(728t22)*x25+(388t26+1820t24)*x24+(80t30+2912t28)*x23+(2160t32+4368t30)*x22+(824t36+8008t34)*x21+(138t40+7304t38+8008t36)*x20+(3840t42+16016t40)*x19+(1180t46+16720t44+11440t42)*x18+(170t50+10680t48+24024t46)*x17+(4480t52+27324t50+12870t48)*x16+(1168t56+19680t54+27456t52)*x15+(152t60+9920t58+32736t56+11440t54)*x14+(3472t62+25200t60+24024t58)*x13+(804t66+14140t64+29040t62+8008t60)*x12+(96t70+5824t68+22848t66+1 [...]
+displayTropicalLifting(tropicalLifting(i12,intvec(1,-3),2),"subst");
+///////////////////////////////////////////////////////////////////
+// weight was: (1,-3)
+////////////////////////////////////////////////////////////////
+ring r9=3,(t,x),dp;
+ideal i13=imap(r8,i12);
+displayTropicalLifting(tropicalLifting(i13,intvec(1,-3),3,"noAbs"),"subst");
+///////////////////////////////////////////////////////////////////
+// weight was: (1,-3)
+/////////////////////////////////////////////////////
+// without the option findAll we first get only a non-valid solution !!!
+ring r10=0,(t,x,y,z,u),dp;
+ideal i14=-y2t5-xyt4-2yzt3+yut2+xut+2zu;
+displayTropicalLifting(tropicalLifting(i14,intvec(1,-2,-1,-3,-3),3),"subst");
+///////////////////////////////////////////////////////////////////
+// weight was: (1,-2,-1,-3,-3)
+///////////////////////////////////////////////////////
+// test for positive characteristic
+///////////////////////////////////////////////////////////////////
+ring r11=13,(t,x),dp;
+poly f1=(x2-t3)*(x3-t5)*(x5-t7)*(x7-t11)*(x11-t13);
+displayTropicalLifting(tropicalLifting(f1,intvec(7,-11),4,"findAll"),"subst");
+///////////////////////////////////////////////////////////////////
+// weight was: (7,-11)
+///////////////////////////////////////////////////////////////////
+// one field extension needed
+// x=(X(1))*t+(-1/2*X(1))*t^3+(3/8*X(1)-1/2)*t^5+(-5/16*X(1)+1/2)*t^7+(19/128*X(1)-1/2)*t^9+(-15/256*X(1)+1/2)*t^11+(-9/1024*X(1)-1/2)*t^13 where t->t and X(1)^2+1=0
+poly f2=(1+t2)*x2+t5x+t2;
+displayTropicalLifting(tropicalLifting(f2,intvec(1,-1),4,"isZeroDimensional","findAll"),"subst");
+///////////////////////////////////////////////////////////////////
+ring r12=5,(t,x,y),dp;
+ideal i11=t4xy-y3+3t2xy3-txy2+t4y;
+displayTropicalLifting(tropicalLifting(i11,intvec(1,3,1),5),"subst");
+///////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////
+/// B) Examples for tropicalCurve
+///////////////////////////////////////////////////////////////////
+ring r=(0,t),(x,y),dp;
+poly f=t*(x7+y7+1)+1/t*(x4+y4+x2+y2+x3y+xy3)+1/t7*x2y2;
+list graph=tropicalCurve(f);
+graph;
+size(graph)-1;
+drawTropicalCurve(graph);
+poly g=t3*(x7+y7+1)+1/t3*(x4+y4+x2+y2+x3y+xy3)+1/t21*x2y2;
+list tropical_g=tropicalise(g);
+tropical_g;
+drawTropicalCurve(tropical_g);
+/// further examples
+poly f1=x+y;
+poly f2=xy+xy3+xy6+txy9;
+poly f3=xy+x2y3+x3y6+tx4y9;
+poly f4=t*(x3+y3+1)+1/t*(x2+y2+x+y+x2y+xy2)+1/t2*xy;
+poly f5=t8x3+t8y3+t8+t4x2y+t4xy2+t4x2+t4y2+t4x+t4y+t2xy;
+poly f6=x3+y3+1;
+poly f7=t*x70+t*y70+1/t*x40+1/t7*x20y20+1/t*y40+1/t*x30y+1/t*xy30+1/t*x20+1/t*y20+t;
+poly f8=t10*x7+t10*y7+1/t10*x4+1/t70*x2y2+1/t10*y4+1/t10*x3y+1/t10*xy3+1/t10*x2+1/t10*y2+t10;
+poly f9=x+y+x2y+xy2+1/t*xy;
+poly f10=1+x+y+xy+tx2y+txy2+t3x5+t3y5+tx2y2+t2xy4+t2yx4;
+poly f11=1/(t8)*x6y+1/(t16)*x5y2+1/(t9)*x4y3+(t4)*x2y5+1/(t11)*xy6+(t5)*y7+1/(t5)*x6+(t16)*x4y2+(t10)*x3y3+(t19)*xy5+(t14)*x5+1/(t17)*x3y2+(t10)*x2y3+1/(t20)*xy4+(t13)*y5+1/(t17)*x4+(t9)*x3y+(t11)*xy3+1/(t3)*xy2+(t7)*y3+1/(t18)*x2+(t16)*x;
+poly f12=-x3+(6t13+3t12+t5+3t4+3t3+1)/(t19)*x2+(2t5+1)/(t12)*xy+y2+(9t28-12t23-12t22+3t21+9t19+3t16-8t15-16t14-24t13-9t12-6t11-8t10-3t9-3t8-4t6-8t5-8t4-3t3-3t-2)/(t35)*x+(9t27+6t20-8t14-4t13-6t12-3t11-4t9-t8-4t5-4t4-2t3-1)/(t27)*y+(27t50+27t43-36t37-9t36-27t35-27t34-t32+12t31-18t30-11t29-54t28-36t27-12t25+13t24+28t23+61t22+27t21+18t20+16t19+3t18+14t17+3t16+16t15+26t14+44t13+34t12+21t11+27t10+12t9+7t8+t6+10t5+11t4+7t3+t2+2t+2)/(t50);
+poly f13=x3+(3t9+1)/(t8)*x2y+(3t10+2t+1)/(t8)*xy2+(t10+t7+t+1)/(t7)*y3+1/(t8)*x2+(2t5+1)/(t12)*xy+(t5+t3+1)/(t11)*y2+1/(t8)*x+(t+1)/(t8)*y+1;
+poly f14=x3+(3t9+3t6c+1)/(t8)*x2y+(3t12+6t9c+3t6c2+2t3+t2+2c)/(t10)*xy2+(t15+3t12c+t12+3t9c2+t6c3+t6+t5+2t3c+t2c+c2)/(t12)*y3+1/(t8)*x2+(2t5+2t2c+1)/(t12)*xy+(t8+t6+2t5c+t3+t2c2+c)/(t14)*y2+1/(t8)*x+(t3+t2+c)/(t10)*y+1;
+poly f15=x3+x2y+xy2+(t5)*y3+x2+1/(t4)*xy+y2+x+y+1;
+poly f16=t*(x7+y7+1)+1/t*(x4+y4+x2+y2+x3y+xy3)+1/t7*x2y2;
+
+///////////////////////////////////////////////////////////////////
+/// B) Examples for tropicalJInvariant
+///////////////////////////////////////////////////////////////////
+// tropcial_j_invariant computes the tropical j-invariant of the elliptic curve f
+tropicalJInvariant(t*(x3+y3+1)+1/t*(x2+y2+x+y+x2y+xy2)+1/t2*xy);
+// the Newton polygone need not be the standard simplex
+tropicalJInvariant(x+y+x2y+xy2+1/t*xy);
+// the curve can have arbitrary degree
+tropicalJInvariant(t*(x7+y7+1)+1/t*(x4+y4+x2+y2+x3y+xy3)+1/t7*x2y2);
+// the procedure does not realise, if the embedded graph of the tropical curve has
+// a loop that can be resolved
+tropicalJInvariant(1+x+y+xy+tx2y+txy2);
+// but it does realise, if the curve has no loop at all ...
+tropicalJInvariant(x+y+1);
+// or if the embedded graph has more than one loop - even if only one cannot be resolved
+tropicalJInvariant(1+x+y+xy+tx2y+txy2+t3x5+t3y5+tx2y2+t2xy4+t2yx4);
+// f is already in Weierstrass form
+weierstrassForm(y2+yx+3y-x3-2x2-4x-6);
+// g is not, but wg is
+g=x+y+x2y+xy2+1/t*xy;
+poly wg=weierstrassForm(g);
+wg;
+// ... but it is not yet a simple, since it still has an xy-term, unlike swg
+poly swg=weierstrassForm(g,1);
+swg;
+// the j-invariants of all three polynomials coincide ...
+jInvariant(g);
+jInvariant(wg);
+jInvariant(swg);
+// the following curve is elliptic as well
+poly h=x22y11+x19y10+x17y9+x16y9+x12y7+x9y6+x7y5+x2y3;
+// its Weierstrass form is
+weierstrassForm(h);
+jInvariant(x+y+x2y+y3+1/t*xy,"ord");
+// see also example f5-f16 in part B)
+
+
+*/
+
+
+/////////////////////////////////////////////////////////////////////////
+
+proc drawTwoTropicalCurves (list ff,list #)
+"USAGE:      drawTropicalCurve(f[,#]); f poly or list, # optional list
+ASSUME:      f is list of linear polynomials of the form ax+by+c with
+             integers a, b and a rational number c representing a tropical
+             Laurent polynomial defining a tropical plane curve;
+             alternatively f can be a polynomial in Q(t)[x,y] defining
+             a tropical plane curve via the valuation map;
+             the basering must have a global monomial ordering, two
+             variables and up to one parameter!
+RETURN:      NONE
+NOTE:        - the procedure creates the files /tmp/tropicalcurveNUMBER.tex and
+               /tmp/tropicalcurveNUMBER.ps, where NUMBER is a random four
+               digit integer;
+               moreover it displays the tropical curve via kghostview;
+               if you wish to remove all these files from /tmp,
+               call the procedure cleanTmp
+@*           - edges with multiplicity greater than one carry this multiplicity
+@*           - if # is empty, then the tropical curve is computed w.r.t. minimum,
+               if #[1] is the string 'max', then it is computed w.r.t. maximum
+@*           - if the last optional argument is 'onlytexfile' then only the
+               latex file is produced; this option should be used if kghostview
+               is not installed on your system
+@*           - note that lattice points in the Newton subdivision which are
+               black correspond to markings of the marked subdivision,
+               while lattice points in grey are not marked
+EXAMPLE:     example drawTropicalCurve  shows an example"
+{
+  // check if the option "onlytexfile" is set, then only a tex file is produced
+  if (size(#)!=0)
+  {
+    if (#[size(#)]=="onlytexfile")
+    {
+      int onlytexfile;
+      #=delete(#,size(#));
+    }
+  }
+  // store this list # for use in the Newton subdivision
+  list oldsharp=#;
+  // start the actual computations
+  string texf;
+  list graph,graphs,texfs;
+  int i,j;
+  for (i=1;i<=size(ff);i++)
+  {
+    def f=ff[i];
+    if (typeof(f)=="poly")
+    {
+      // exclude the case that the basering has not precisely
+      // one parameter and two indeterminates
+      if ((npars(basering)!=1) or (nvars(basering)!=2))
+      {
+        ERROR("The basering should have precisely one parameter and two indeterminates!");
+      }
+      texf=texPolynomial(f); // write the polynomial over Q(t)
+      graph=tropicalCurve(tropicalise(f,#),#); // graph of tropicalis. of f
+    }
+    if (typeof(f)=="list")
+    {
+      if (size(#)==0)
+      {
+        texf="\\min\\{";
+      }
+      else
+      {
+        texf="\\max\\{";
+      }
+      for (j=1;j<=size(f);j++)
+      {
+        texf=texf+texPolynomial(f[j]);
+        if (j<size(f))
+        {
+          texf=texf+", ";
+        }
+        else
+        {
+          texf=texf+"\\}";
+        }
+      }
+      graph=tropicalCurve(f,#); // the graph of the tropical polynomial f
+      // detropicalise ff[i]
+      ff[i]=tDetropicalise(f);
+    }
+    graphs[i]=graph;
+    texfs[i]=texf;
+    kill f;
+  }
+  // add the product of all curves as an additional curve
+  poly f=1;
+  for (i=1;i<=size(ff);i++)
+  {
+    f=f*ff[i];
+  }
+  ff=insert(ff,f);
+  graphs=insert(graphs,tropicalCurve(f,#));
+  texfs=insert(texfs,texPolynomial(f));
+  // produce the tex file
+  string vertices;
+  list verticess;
+  for (i=1;i<=size(ff);i++)
+  {
+    graph=graphs[i];
+    for (j=1;j<=size(graph)-2;j++)
+    {
+      vertices=vertices+"("+string(graph[j][1])+","+string(graph[j][2])+"),\\;\\;";
+    }
+    vertices=vertices+"("+string(graph[j][1])+","+string(graph[j][2])+")";
+    verticess[i]=vertices;
+    vertices="";
+  }
+  string TEXBILD="\\documentclass[12pt]{amsart}
+\\usepackage{texdraw}
+\\setlength{\\topmargin}{30mm}
+\\addtolength{\\topmargin}{-1in}
+\\addtolength{\\topmargin}{-\\headsep}
+\\addtolength{\\topmargin}{-\\headheight}
+\\addtolength{\\topmargin}{-\\topskip}
+\\setlength{\\textheight}{267mm}
+\\addtolength{\\textheight}{\\topskip}
+\\addtolength{\\textheight}{-\\footskip}
+\\addtolength{\\textheight}{-30pt}
+\\setlength{\\oddsidemargin}{-1in}
+\\addtolength{\\oddsidemargin}{20mm}
+\\setlength{\\evensidemargin}{\\oddsidemargin}
+\\setlength{\\textwidth}{170mm}
+
+\\begin{document}
+   \\parindent0cm
+   \\begin{center}
+      \\large\\bf The Tropicalisation of several curves:
+   \\end{center}
+
+      \\bigskip
+";
+  string fname;
+  for (i=1;i<=size(ff);i++)
+  {
+    if (i==1)
+    {
+      fname="f_1\\cdots f_{"+string(size(ff)-1)+"}";
+    }
+    else
+    {
+      fname="f_{"+string(i-1)+"}";
+    }
+    TEXBILD=TEXBILD+"
+    The vertices of the tropical curve
+    \\begin{center}
+      \\begin{math}
+          "+fname+"="+texfs[i]+"
+      \\end{math}
+    \\end{center}
+    are
+    \\begin{center}
+      \\begin{math}
+          "+verticess[i]+"
+      \\end{math}
+    \\end{center}
+    \\vspace*{0.5cm}
+  ";
+  }
+  // compute the center and the scale factor
+  list SCF=minScaleFactor(graphs);
+  #[size(#)+1]=SCF;
+  string relunitscale="
+       \\relunitscale "+ decimal(SCF[1],SCF[3]);
+  #[size(#)+1]=relunitscale;
+  // collect the texdraw input for all the curves with different color
+  string TDT;
+  for (i=1;i<=size(ff);i++)
+  {
+    #[size(#)+1]="\\setgray "+decimal(1-(number(i)/(size(ff)+1)))+"
+";
+    if (i>1)
+    {
+      TDT=TDT+"
+"+texDrawTropical(graphs[i],#);
+    }
+    else
+    {
+      #=insert(#,"noweights");
+      TDT=TDT+"
+"+texDrawTropical(graphs[i],#);
+      #=delete(#,1);
+    }
+  }
+  // add lattice points if the scalefactor is >= 1/2
+  // and was not handed over
+  def scalefactor=SCF[1];
+  if (scalefactor>1/2)
+  {
+    def minx=SCF[4];
+    def miny=SCF[5];
+    def maxx=SCF[6];
+    def maxy=SCF[7];
+    def centerx=SCF[8];
+    def centery=SCF[9];
+    int uh=1;
+    if (scalefactor>3)
+    {
+      uh=0;
+    }
+    TDT=TDT+"
+
+   %% HERE STARTS THE CODE FOR THE LATTICE";
+    for (i=int(minx)-uh;i<=int(maxx)+uh;i++)
+    {
+      for (j=int(miny)-uh;j<=int(maxy)+uh;j++)
+      {
+        TDT=TDT+"
+        \\move ("+decimal(i-centerx)+" "+decimal(j-centery)+") \\fcir f:0.8 r:"+decimal(1/(10*scalefactor),size(string(int(scalefactor)))+1);
+      }
+    }
+    TDT=TDT+"
+   %% HERE ENDS THE CODE FOR THE LATTICE
+                          ";
+  }
+  TEXBILD=TEXBILD+"
+   \\begin{center}
+"+texDrawBasic(TDT)+  // write the tropical curve
+   "\\end{center}
+
+   \\vspace*{0.5cm}
+";
+  // compute the scaling factor for the Newton subdivisions
+  oldsharp[size(oldsharp)+1]=nsdScaleFactor(graphs);
+  for (i=1;i<=size(ff);i++)
+  {
+    if (i==1)
+    {
+      fname="f_1\\cdots f_{"+string(size(ff)-1)+"}";
+    }
+    else
+    {
+      fname="f_{"+string(i-1)+"}";
+    }
+    TEXBILD=TEXBILD+"
+   The Newton subdivision of the tropical curve $"+fname+"$ is:
+   \\vspace*{0.5cm}
+
+   \\begin{center}
+       "+texDrawNewtonSubdivision(graphs[i],oldsharp)+"
+   \\end{center}
+
+   \\vspace*{0.5cm}
+";
+  }
+  TEXBILD=TEXBILD+"
+\\end{document}";
+  if(defined(onlytexfile)==0)
+  {
+    int rdnum=random(1000,9999);
+    write(":w /tmp/tropicalcurve"+string(rdnum)+".tex",TEXBILD);
+    system("sh","cd /tmp; latex /tmp/tropicalcurve"+string(rdnum)+".tex; dvips /tmp/tropicalcurve"+string(rdnum)+".dvi -o; /bin/rm tropicalcurve"+string(rdnum)+".log;  /bin/rm tropicalcurve"+string(rdnum)+".aux;  /bin/rm tropicalcurve"+string(rdnum)+".ps?;  /bin/rm tropicalcurve"+string(rdnum)+".dvi; kghostview tropicalcurve"+string(rdnum)+".ps &");
+  }
+  else
+  {
+    return(TEXBILD);
+  }
+}
+example
+{
+   "EXAMPLE:";
+   echo=2;
+   ring r=(0,t),(x,y),dp;
+//   poly f=t*(x3+y3+1)+1/t*(x2+y2+x+y+x2y+xy2)+1/t2*xy;
+   poly f=x+y+1;
+// the command drawTropicalCurve(f) computes the graph of the tropical curve
+// given by f and displays a post script image, provided you have kghostview
+// we can instead apply the procedure to a tropical polynomial and use "maximum"
+   poly g=t3*(x7+y7+1)+1/t3*(x4+y4+x2+y2+x3y+xy3)+1/t21*x2y2;
+//   list tropical_g=tropicalise(g);
+   drawTwoTropicalCurves(list(f,g),"max");
+}
+
+
+proc minScaleFactor (list graphs)
+{
+  list graph;
+  int j,i,k;
+  poly minx,miny,maxx,maxy;
+  poly minX,minY,maxX,maxY;
+  poly maxdiffx,maxdiffy;
+  poly centerx,centery;
+  int nachkomma;
+  number sf,scf;
+  poly scalefactor;
+  list SFCS;
+  for (k=1;k<=size(graphs);k++)
+  {
+    graph=graphs[k];
+    // find the minimal and maximal coordinates of vertices
+    minx,miny,maxx,maxy=graph[1][1],graph[1][2],graph[1][1],graph[1][2];
+    for (i=2;i<=size(graph)-1;i++)
+    {
+      minx=minOfPolys(list(minx,graph[i][1]));
+      miny=minOfPolys(list(miny,graph[i][2]));
+      maxx=-minOfPolys(list(-maxx,-graph[i][1]));
+      maxy=-minOfPolys(list(-maxy,-graph[i][2]));
+    }
+    if (k==1)
+    {
+      minX=minx;
+      minY=miny;
+      maxX=maxx;
+      maxY=maxy;
+    }
+    else
+    {
+      if (minx<minX)
+      {
+        minX=minx;
+      }
+      if (miny<minY)
+      {
+        minY=miny;
+      }
+      if (maxx>maxX)
+      {
+        maxX=maxx;
+      }
+      if (maxy>maxY)
+      {
+        maxY=maxy;
+      }
+    }
+  }
+  minx,miny,maxx,maxy=minX,minY,maxX,maxY;
+  // find the scale factor for the texdraw image
+  maxdiffx=maxx-minx;
+  maxdiffy=maxy-miny;
+  centerx,centery=int(minx+maxdiffx/2),int(miny+maxdiffy/2);
+  if (maxdiffx==0)
+  {
+    maxdiffx=1;
+  }
+  if (maxdiffy==0)
+  {
+    maxdiffy=1;
+  }
+  nachkomma=2; // number of decimals for the scalefactor
+  sf=1; // correction factor for scalefactor
+  scalefactor=minOfPolys(list(12/leadcoef(maxdiffx),16/leadcoef(maxdiffy)));
+  // if the scalefactor is less than 1/100, then we need more than 2 decimals
+  if (leadcoef(scalefactor) < 1/100)
+  {
+    scf=leadcoef(scalefactor);
+    while (scf < 1/100)
+    {
+      scf=scf * 10;
+      nachkomma++;
+    }
+  }
+  // if the scalefactor is < 1/100, then we should rather scale the
+  // coordinates directly, since otherwise texdraw gets into trouble
+  if (nachkomma > 2)
+  {
+    for (i=3;i<=nachkomma;i++)
+    {
+      scalefactor=scalefactor * 10;
+      sf=sf*10;
+    }
+  }
+  return(list(scalefactor,sf,nachkomma,minx,miny,maxx,maxy,centerx,centery));
+}
+example
+{
+   "EXAMPLE:";
+   echo=2;
+   ring r=(0,t),(x,y),dp;
+   poly f=t*(x3+y3+1)+1/t*(x2+y2+x+y+x2y+xy2)+1/t2*xy;
+   poly g=1/t3*(x7+y7+1)+t3*(x4+y4+x2+y2+x3y+xy3)+t21*x2y2;
+   list graphs;
+   graphs[1]=tropicalCurve(f);
+   graphs[2]=tropicalCurve(g);
+   minScaleFactor(graphs);
+}
+
+proc nsdScaleFactor (list graphs)
+{
+  int i,j;
+  list graph,boundary,scalefactors;
+  poly maxx,maxy;
+  for (j=1;j<=size(graphs);j++)
+  {
+    graph=graphs[j];
+    boundary=graph[size(graph)][1];
+    // find maximal and minimal x- and y-coordinates and define the scalefactor
+    maxx,maxy=1,1;
+    for (i=1;i<=size(boundary);i++)
+    {
+      maxx=-minOfPolys(list(-maxx,-boundary[i][1]));
+      maxy=-minOfPolys(list(-maxy,-boundary[i][2]));
+    }
+    scalefactors[j]=minOfPolys(list(12/leadcoef(maxx),12/leadcoef(maxy)));
+  }
+  return(minOfPolys(scalefactors));
+}
+
diff --git a/Singular/LIB/tst.lib b/Singular/LIB/tst.lib
new file mode 100644
index 0000000..52e263c
--- /dev/null
+++ b/Singular/LIB/tst.lib
@@ -0,0 +1,1109 @@
+//////////////////////////////////////////////////////////////////////////
+
+version="version tst.lib 4.0.0.0 Jun_2013 "; // $Id: 570d7af65f4ccc66df35930b4c1fcd594280d4c6 $
+category="Utilities";
+info="
+LIBRARY:  tst.lib      Procedures for running automatic tst Tests
+AUTHORS:  Singular team
+
+PROCEDURES:
+ tst_system(s)          returns string which is stdout of system(\"sh\", s)
+ tst_ignore(any,[keyword], [link]) writes string(any) to link (or stdout),
+                                   prepending prefix \"// tst_ignore:\"
+ tst_init()             writes some identification data to GetTstStatusFile()
+ tst_status([any])      writes status info to GetTstStatusFile()
+ tst_InitTimer()        initialize tst-Timer
+ tst_StopTimer()        stop Tst-Timer
+ tst_GetTimer           get value of Tst-Timer
+ tst_ReportTimer        report value of Tst-Timer
+ tst_groebnerTest(ideal i)
+                        tests groebner command
+ tst_stdEqual(ideal i1, ideal i2)
+                        test whether two std's are \"equal\"
+
+ tst_test_res(ideal i)  test different res commands for homog ideal i
+";
+
+/////////////////////////////////////////////////////////////////////////////
+proc tst_system(string s, list #)
+"USAGE:    tst_system(s); s string
+RETURN:   string which is stdout and stderr of system(\"sh\", s)
+EXAMPLE:  example tst_system; shows examples"
+{
+  string tmpfile = "/tmp/tst_" + string(system("pid"));
+  int errno;
+
+  s = s + " 1>" + tmpfile + " 2>&1";
+  errno = system("sh", s);
+  s = read(tmpfile);
+  errno = system("sh", "rm -f " + tmpfile);
+  if (size(#) > 0 && size(s) > 1)
+  {
+    s = s[1, size(s) -1];
+  }
+  return (s);
+}
+example
+{
+  "EXAMPLE"; echo = 2;
+  string s = tst_system("echo This is an example of tst_system");
+  "The following is what the system call wrote to stdout: " + s;
+}
+
+proc tst_ignore(list #)
+"USAGE:    tst_ignore(any,[keyword], [link])
+            any     -- valid argument to string()
+            keyword -- an arbitrary string
+            link    -- a link which can be written to
+RETURN:   none; writes string(any) to link (or stdout, if no link given),
+          prepending prefix \"// tst_ignore:\", or
+                            \"// tst_ignore:keyword hostname:\",
+                            if keyword was given.
+          Should be used in tst files to output system dependent data
+          (like date, pathnames).
+EXAMPLE:  example tst_ignore; shows examples
+"
+{
+  if (! defined(tst_no_status))
+  {
+    string s;
+    string keyword = "";
+    link outlink = "";
+
+    // Check # of args
+    if (size(#) < 1 || size(#) > 3)
+    {
+      ERROR("Error tst_ignore: Wrong number of arguments
+      Usage: tst_ignore (any,[keyword], [link]);");
+    }
+
+    // Get Args
+    s = string(#[1]);
+    if (size(#) == 3)
+    {
+      keyword = #[2];
+      outlink = #[3];
+    }
+    if (size(#) == 2)
+    {
+      if (typeof(#[2]) == "string")
+      {
+        keyword = #[2];
+      }
+      else
+      {
+        outlink = #[2];
+      }
+    }
+
+    // check args
+    if (typeof(keyword) != "string")
+    {
+      "Error tst_ignore: Keyword must be a string";
+      "Usage: tst_ignore (any,[keyword], [link]);";
+      return();
+    }
+
+    if (status(outlink, "open", "no"))
+    {
+      open(outlink);
+    }
+
+    if (status(outlink, "write", "not ready"))
+    {
+      "Error tst_ignore: Cannot write to link";
+      outlink;
+      "Usage: tst_ignore (any,[keyword], [link]);";
+      return();
+    }
+
+    // ready -- do the actual work
+    if (keyword != "")
+    {
+      write(outlink,"// tst_ignore:" + keyword + " :: " + tst_system("hostname", 1) + ":" + s);
+    }
+    else
+    {
+      write(outlink, "// tst_ignore: " + s);
+    }
+  }
+}
+example
+{
+  "EXAMPLE";
+  "System independent data can safely be output in tst files;";
+  "However, system dependent data like dates, or pathnames, should be output";
+  "using the command tst_ignore(...), like";
+  echo = 2;
+  tst_ignore(tst_system("date"));
+  int t1 = timer;
+  tst_ignore(t1, "time");
+  tst_ignore(memory(1), "memory");
+}
+
+static proc Get_tst_timer()
+{
+  if (! defined (tst_timer))
+  {
+    string tst_timer = "// tst_ignore:0";
+    export tst_timer;
+    return (0);
+  }
+  else
+  {
+    execute("int tst_int_timer = " + tst_timer[15,size(tst_timer)] + ";");
+    return (tst_int_timer);
+  }
+}
+
+static proc Set_tst_timer (int this_time)
+{
+  tst_timer = tst_timer[1,14] + string(this_time);
+}
+
+static proc GetTstStatusFile()
+{
+  if (!defined(tst_status_file))
+  {
+    return ("tst_status.out");
+  }
+  else
+  {
+    return (tst_status_file);
+  }
+}
+
+static proc tst_status_out (def prefix, def what, list #)
+{
+  string outstring;
+
+  outstring = string(prefix) + " >> " + string(what);
+  if (size(#) > 0)
+  {
+    outstring = outstring + " :: " +
+      tst_system("hostname", 1) + ":" + string(#[1]);
+  }
+  write(":a " + GetTstStatusFile(), outstring);
+}
+
+proc tst_status (list #)
+"USAGE:   tst_status([prefix [, start_up]])
+           prefix -- string
+           start_up -- int
+RETURN:   none
+PURPOSE: writes to tst-output the current memory usage and used CPU time.
+         If no integer argument is given, the elapsed CPU time since
+         the last call to tst_status() is reported.
+         If an integer argument is given, the elapsed CPU time since the
+         start-up of @sc{Singular} is reported.
+         If prefix is given, output reported start with prefix.
+NOTE:     Should be used regularly within tst files to enable automatic
+          tracking of memory and time performance.
+EXAMPLE: example tst_status; shows example
+SEE ALSO: tst_init
+"
+{
+  int start_up;
+
+  if (size(#) > 0)
+  {
+    if (typeof(#[1]) == "string")
+    {
+      string prefix = #[1];
+      if (size(#) > 1)
+      {
+        start_up = 1;
+      }
+    }
+    else
+    {
+      start_up = 1;
+    }
+  }
+  if (! defined(tst_no_status))
+  {
+    if (! defined(tst_status_counter))
+    {
+      int tst_status_counter = 1;
+      export tst_status_counter;
+    }
+    else
+    {
+      tst_status_counter++;
+    }
+
+    if (!defined(prefix))
+    {
+      def prefix = tst_status_counter;
+    }
+    tst_status_out(prefix, "tst_memory_0", memory(0));
+    tst_status_out(prefix, "tst_memory_1", memory(1));
+    tst_status_out(prefix, "tst_memory_2", memory(2));
+    if (start_up > 0)
+    {
+      tst_status_out(prefix, "tst_timer_1", timer);
+    }
+    else
+    {
+      tst_status_out(prefix, "tst_timer", timer - Get_tst_timer());
+      Set_tst_timer(timer);
+    }
+  }
+}
+example
+{
+  "EXAMPLE";  echo = 2;
+  tst_status();
+  ring r;
+  poly p = (x+y+z)^40;
+  tst_status();
+  tst_status(1);
+}
+
+
+proc tst_init(list #)
+"USAGE:   tst_init([file])
+            file -- string
+RETURN:  none
+PURPOSE: initializes further calls to tst routines:
+         If no arguments are given, and if tst_status_file is not defined,
+         then tst-output is written to stdout, else tst-output is written
+         to file.
+EXAMPLE: example tst_init; shows example
+"
+{
+  if (! defined(tst_no_status))
+  {
+    string outfile = "";
+
+    if (size(#) > 0)
+    {
+      if (typeof(#[1]) == string)
+      {
+        outfile  = #[1];
+      }
+    }
+    if (!defined(tst_status_file))
+    {
+      string tst_status_file = outfile;
+      export tst_status_file;
+    }
+    if (GetTstStatusFile() != "")
+    {
+      write(":w " + GetTstStatusFile(), "Status Output of " + GetTstStatusFile());
+    }
+    tst_status_out("init", "USER    :" + system("getenv", "USER"));
+    tst_status_out("init", "HOSTNAME:" + tst_system("hostname", 1));
+    tst_status_out("init", "uname -a:" + tst_system("uname -a", 1));
+    tst_status_out("init", "date    :" + tst_system("date", 1));
+    tst_status_out("init", "version :" + string(system("version")));
+    tst_status_out("init", "ticks   :" + string(system("--ticks-per-sec")));
+    "init >> " + GetTstStatusFile();
+  }
+}
+example
+{
+  "EXAMPLE";  echo = 2;
+  tst_init();
+}
+
+proc tst_InitTimer(list #)
+"USAGE: tst_InitTime([ticks_per_second])
+          ticks_per_second -- int
+RETURN: none
+PURPOSE: initializes tst timer for subsequent calls to tst_StopTimer or
+         tst_ReportTimer.
+         If the ticks_per_second argument is given, then the timer resolution
+         is set to this value. Otherwise, the default timer resolution is used.
+SEE ALSO: tst_StopTimer, tst_GetTimer, tst_ReportTimer
+"
+{
+  if (!defined(tst_Timer))
+  {
+    int tst_Timer;
+    export tst_Timer;
+  }
+  if (size(#) > 0)
+  {
+    if (typeof(#[1]) == "int")
+    {
+      if (#[1] > 0)
+      {
+        system("--ticks-per-sec", #[1]);
+      }
+      else
+      {
+        ERROR("need integer argument > 0");
+      }
+    }
+    else
+    {
+      ERROR("need integer argument");
+    }
+  }
+  tst_Timer = timer;
+}
+
+proc tst_StopTimer()
+"USAGE: tst_StopTimer()
+RETURN: int, timer ticks of elapsed CPU time since last call to tst_InitTimer
+PUPOSE: stops the timer initialized by previous call to tst_InitTimer
+SEE ALSO: tst_InitTimer, tst_GetTimer, tst_ReportTimer
+"
+{
+  tst_Timer = timer - tst_Timer;
+  return (tst_Timer);
+}
+
+proc tst_GetTimer()
+"USAGE: tst_GetTimer()
+RETURN: int, timer ticks of elapsed CPU time since last call to tst_Init
+NOTE:  does NOT stop the time initialized by previous call to tst_InitTimer
+SEE ALSO: tst_InitTimer, tst_GetTimer, tst_ReportTimer
+"
+{
+  int tt = timer - tst_Timer;
+  return (tt);
+}
+
+proc tst_ReportTimer(list #)
+"USAGE: tst_ReportTimer([prefix])
+RETURN: none
+PUPOSE: stops the timer initialized by previous call to tst_InitTimer;
+        reports time to tst-output;
+        if prefix is given, timer output is prefixed by it.
+SEE ALSO: tst_InitTimer, tst_GetTimer, tst_StopTimer, tst_OutTimer, tst_init
+"
+{
+  tst_Timer = timer - tst_Timer;
+  tst_OutTimer(tst_Timer, #);
+}
+
+proc tst_OutTimer(int tt, list #)
+"USAGE: tst_OutTimer(ticks [, prefix])
+RETURN: none
+PURPOSE: reports value of tt to tst-output;
+         if prefix is given, timer output is prefixed by it.
+SEE ALSO: tst_InitTimer, tst_GetTimer, tst_StopTimer, tst_ReportTimer, tst_init
+"
+{
+  string prefix = "OutTimer";
+
+  if (size(#) > 0)
+  {
+    prefix = string(#[1]);
+  }
+  tst_status_out(prefix, "tst-Timer", tt);
+}
+
+///////////////////////////////////////////////////////////////////////
+
+proc tst_groebnerTest(ideal i, list #)
+"USAGE: tst_groebnerTesti,[v]) : ideal i, [int v]
+RETURN: 1, if groebner command produced \"equal\" std as std command
+        0, otherwise
+        Two std's are \"equal\" here, if their redSB's are element-wise equal,
+        and if they reduce each other to zero, and if their leading ideals
+        are equal
+        On success, times of std - groebner is written with tst_ignore, and
+        times are added to global variables tst_std_time and
+        tst_groebner_time. If v given, and <= 0, short ideal
+        characteristic is printed, if v > 0, ideals are printed.
+        On failure, Error message and ideals are printed.
+EXAMPLE: example tst_groebner; shows an example
+"
+{
+  int st = timer;
+  ideal si = std(i);
+  st = timer - st;
+
+  int gt = timer;
+  ideal gi = groebner(i);
+  gt = timer - gt;
+
+  if (tst_stdEqual(si, gi))
+  {
+    tst_ignore(string(st) + " - " + string(gt) + " == " + string(st - gt));
+    if (! defined(tst_groebner_time))
+    {
+      int tst_groebner_time;
+      int tst_std_time;
+      export tst_groebner_time, tst_std_time;
+    }
+    tst_std_time = tst_std_time + st;
+    tst_groebner_time = tst_groebner_time + gt;
+    if (size(#))
+    {
+      if (typeof(#[1] == "int"))
+      {
+        if (#[1] <= 0)
+        {
+          idPrintShort(si, "si");
+          idPrintShort(gi, "gi");
+        }
+        else
+        {
+          si;
+          gi;
+        }
+      }
+    }
+    return (1);
+  }
+  return (0);
+}
+example
+{
+  "EXAMPLE: "; echo = 2;
+  ring r = 0, (a,b,c,d), lp;
+  ideal i = a+b+c+d, ab+ad+bc+cd, abc+abd+acd+bcd, abcd-1; // cyclic 4
+  tst_groebnerTest(i);
+  tst_groebnerTest(i, 0);
+  tst_groebnerTest(i, 1);
+}
+
+
+//
+// A routine which test for equality of "std-bases"
+//
+proc tst_stdEqual(ideal i1, ideal i2)
+"USAGE: tst_stdEqual(i1, i2)  ideal i1, i2
+RETURN 1, if i1 \"equald\" i2 as a std bases
+       0, otherwise
+       Two std's are \"equal\" here, if their redSB's are element-wise equal,
+       and if they reduce each other to zero, and if their leading ideals
+       are equal
+       On failure, error message is printed.
+EXAMPLE: example tst_stdEqual; shows an example
+"
+{
+  int i;
+  int back;
+  intvec opts = option(get);
+  option(redSB);
+
+  ideal ri1 = simplify(interred(i1), 1);
+  ideal ri2 = simplify(interred(i2), 1);
+
+  option(set, opts);
+
+  if (size(ri1) != size(ri2))
+  {
+    "Error in tst_stdEqual: Reduced sizes differ";
+    size(ri1);
+    size(ri2);
+    return(0);
+  }
+
+  for (i=1; i<=size(ri1); i++)
+  {
+    if (ri1[i] != ri2[i])
+    {
+      "Error in tst_stdEqual: " + string(i) + " th polynomials differ";
+      ri1[i];
+      ri2[i];
+      return(0);
+    }
+  }
+
+  // reduced SB are now equal
+  if (size(reduce(i1, i2, 1)) == 0)
+  {
+    if (size(reduce(i2, i1, 1)) == 0)
+    {
+      poly p1, p2;
+
+      ideal si1 = simplify(i1, 7);
+      ideal si2 = simplify(i2, 7);
+
+      if (size(si1) == size(si2))
+      {
+        for (i=1; i<=size(si1); i++)
+        {
+          p1 = p1 + lead(si1[i]);
+          p2 = p2 + lead(si2[i]);
+        }
+        if (p1 != p2)
+        {
+          "Error in tst_stdEqual: Lead monoms differ:";
+          p1;
+          p2;
+          return(0);
+        }
+      }
+      else
+      {
+        "Error in tst_stdEqual: size differs:";
+        size(si1);
+        size(si2);
+        return(0);
+      }
+    }
+    else
+    {
+      "Error in tst_stdEqual: reduce(i2, i1) != 0";
+      return(0);
+    }
+  }
+  else
+  {
+    back = 1; "Error in tst_stdEqual: reduce(i1, i2) != 0";
+    return(0);
+  }
+
+  return (1);
+}
+example
+{
+  "EXAMPLE: "; echo = 2;
+  ring r = 0, (a,b,c,d), lp;
+  ideal i = a+b+c+d, ab+ad+bc+cd, abc+abd+acd+bcd, abcd-1; // cyclic 4
+  tst_stdEqual(groebner(i), std(i));
+  tst_stdEqual(std(i), i);
+}
+
+static proc idPrintShort(ideal id, string name)
+{
+  "Summary of " + name + " (leading monoms and size of polys):";
+  int i;
+  for (i = 1; i<=size(id); i++)
+  {
+    "[" + string(i) + "]: #" + string(size(id[i])) + ":" + string(lead(id[i]));
+  }
+}
+
+
+proc tst_test_res(ideal i, list #)
+
+"USAGE:    tst_test_res(ideal i, only_lres_and_hres)
+RETURN:    1, if ok; 0 on error
+PURPOSE:   Tests sres, lres, hres, mres with betti commands and conversions
+           If optinal third argument is given, test only lres and hres
+EXAMPLE:  example tst_test_res shows an example"
+{
+  int ret = 1;
+
+  if (! homog(i))
+  {
+    ERROR("ERROR: input ideal needs to be homogenous ");
+  }
+
+  if (size(#) == 0)
+  {
+    resolution rs = sres(std(i), 0);
+    resolution rm = mres(i,0);
+  }
+
+  resolution rh = hres(i,0);
+  resolution rl = lres(i, 0);
+
+  if (size(#) == 0)
+  {
+    intmat is = betti(rs);
+    intmat im = betti(rm);
+  }
+
+  intmat ih = betti(rh);
+  intmat il = betti(rl);
+
+  if (size(ih) != size(il)){"ERROR: size(ih) != size(il)";return(0);}
+  if (size(#) == 0)
+  {
+    if (size(ih) != size(is)){"ERROR: size(ih) != size(is)";return(0);}
+    if (size(ih) != size(im)){"ERROR: size(ih) != size(im)";return(0);}
+  }
+
+  if (ih != il){"ERROR: ih != il";return(0);}
+  if (size(#) == 0)
+  {
+    if (ih != is){"ERROR: ih != is";return(0);}
+    if (ih != im){"ERROR: ih != im";return(0);}
+  }
+
+  if (size(#) == 0)
+  {
+    list ls = list(rs);
+    list lm = list(rm);
+  }
+  list lh = list(rh);
+  list ll = list(rl);
+
+  if (size(#) == 0)
+  {
+    intmat is_1 = betti(ls);
+    intmat im_1 = betti(lm);
+  }
+  intmat ih_1 = betti(lh);
+  intmat il_1 = betti(ll);
+
+  if (size(ih_1) != size(il_1)){"ERROR: size(ih_1) != size(il_1)";return(0);}
+  if (size(#) == 0)
+  {
+    if (size(ih_1) != size(is_1)){"ERROR: size(ih_1) != size(is_1)";return(0);}
+    if (size(ih_1) != size(im_1)){"ERROR: size(ih_1) != size(im_1)";return(0);}
+  }
+
+  if (ih_1 != il_1){"ERROR: ih_1 != il_1";return(0);}
+  if (size(#) == 0)
+  {
+    if (ih_1 != is_1){"ERROR: ih_1 != is_1";return(0);}
+    if (ih_1 != im_1){"ERROR: ih_1 != im_1";return(0);}
+  }
+
+
+  if (size(ih) != size(ih_1)) {"ERROR: size(ih) != size(ih_1)";return(0);}
+  if (ih != ih_1) {"ERROR: ih != ih_1";return(0);}
+
+  return (ret);
+}
+example
+{
+  "EXAMPLE: "; echo = 2;
+  ring an=0,(w,x,y,z),(dp,C);
+  ideal i=
+    1w2xy+1w2xz+1w2yz+1wxyz+1x2yz+1xy2z+1xyz2,
+    1w4x+1w4z+1w3yz+1w2xyz+1wx2yz+1x2y2z+1xy2z2,
+    1w6+1w5z+1w4xz+1w3xyz+1w2xy2z+1wx2y2z+1x2y2z2;
+  tst_test_res(i);
+  kill an;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+proc tst_rgen_init_weights(int n)
+{
+  intvec v = 1..n;
+  return (v);
+}
+
+proc tst_rgen_init_matrix(int n)
+{
+  intmat m[n][n];
+  int i;
+  // let us emulate lp
+  for (i=1; i<= n; i++)
+  {
+    m[i,i] = 1;
+  }
+  return (m);
+}
+
+proc tst_rgen_generate_block(int n_vars, string simple_ordering, int extra_weights)
+{
+  string order = simple_ordering;
+  if (extra_weights > n_vars)
+  {
+    extra_weights = n_vars;
+  }
+
+  if ((simple_ordering[1] == "W") || (simple_ordering[1] == "w"))
+  {
+    order = order + "(" + string(tst_rgen_init_weights(n_vars)) + ")";
+  }
+  else
+  {
+    if (simple_ordering[1] == "M")
+    {
+      order = order + "(" + string(tst_rgen_init_matrix(n_vars)) + ")";
+    }
+    else
+    {
+      order = order + "(" + string(n_vars) + ")";
+    }
+  }
+  if (extra_weights >= 1)
+  {
+    order = "a(" + string(tst_rgen_init_weights(extra_weights)) + ")," + order;
+  }
+  return (order);
+}
+
+proc tst_rgen_generate_blocks(int n_vars, list simple_orderings, intvec extra_weights)
+{
+  int i;
+  int j;
+  list blocks;
+
+  for (i=1; i<=size(simple_orderings); i++)
+  {
+    for (j=1; j<=size(extra_weights); j++)
+    {
+      blocks = blocks + list(tst_rgen_generate_block(n_vars, simple_orderings[i], extra_weights[j]));
+    }
+  }
+  return (blocks);
+}
+
+proc tst_rgen_generate_product_orderings(int n_vars, list simple_orderings, intvec extra_weights, intvec products)
+{
+  list p_orderings;
+  int i;
+  int nn_vars, j, k,l;
+  list nb_orderings;
+  string n_ordering;
+
+  for (i=1;i<=size(products);i++)
+  {
+    if (products[i] > 1 && products[i] <= n_vars)
+    {
+      nn_vars = n_vars div products[i];
+      nb_orderings = tst_rgen_generate_blocks(nn_vars, simple_orderings, extra_weights);
+      for (j=1; j<=size(nb_orderings); j++)
+      {
+        n_ordering = nb_orderings[j];
+        for (k=2; k<=products[i]; k++)
+        {
+          l = (j + k - 1) %  size(nb_orderings);
+          if (l == 0)
+          {
+            l = size(nb_orderings);
+          }
+          n_ordering = n_ordering + "," + nb_orderings[l];
+        }
+        if (products[i]*nn_vars < n_vars)
+        {
+          n_ordering = n_ordering + ", lp";
+        }
+        p_orderings = p_orderings + list(n_ordering);
+      }
+    }
+    else
+    {
+      if (products[i] == 1)
+      {
+        p_orderings = p_orderings + tst_rgen_generate_blocks(n_vars, simple_orderings, extra_weights);
+      }
+    }
+  }
+  if (size(p_orderings) < 1)
+  {
+    p_orderings = tst_rgen_generate_blocks(n_vars, simple_orderings, extra_weights);
+  }
+  return (p_orderings);
+}
+
+
+proc tst_rgen_init()
+{
+  if (! defined(tst_rgen_charstrs))
+  {
+    list tst_rgen_charstrs;
+    export(tst_rgen_charstrs);
+    tst_rgen_charstrs = list("32003", "0");
+  }
+  if (! defined(tst_rgen_nvars))
+  {
+    intvec tst_rgen_nvars;
+    export(tst_rgen_nvars);
+    tst_rgen_nvars = 1..10;
+  }
+  if (! defined(tst_rgen_simple_orderings))
+  {
+    list tst_rgen_simple_orderings;
+    export(tst_rgen_simple_orderings);
+    tst_rgen_simple_orderings = list("lp", "dp", "Dp", "ls", "ds", "Ds", "wp","Wp","ws","Ws","M");
+  }
+  if (! defined(tst_rgen_comp_orderings))
+  {
+    list tst_rgen_comp_orderings;
+    export(tst_rgen_comp_orderings);
+    tst_rgen_comp_orderings = list("", "C", "c", "CC", "cc");
+  }
+  if (! defined(tst_rgen_products))
+  {
+    intvec tst_rgen_products;
+    export(tst_rgen_products);
+    tst_rgen_products = 1..3;
+  }
+  if (! defined(tst_rgen_extra_weights))
+  {
+    intvec tst_rgen_extra_weights;
+    export(tst_rgen_extra_weights);
+    tst_rgen_extra_weights = 0..2;
+  }
+
+  if (! defined(tst_rgen_exp_bounds))
+  {
+    list tst_rgen_exp_bounds;
+    export(tst_rgen_exp_bounds);
+  }
+
+  if (! defined(tst_rgen_char_index))
+  {
+    int tst_rgen_char_index, tst_rgen_var_index, tst_rgen_comp_index, tst_rgen_ordering_index, tst_rgen_exp_bounds_index;
+    list tst_rgen_orderings;
+    export(tst_rgen_char_index);
+    export(tst_rgen_var_index);
+    export(tst_rgen_comp_index);
+    export(tst_rgen_ordering_index);
+    export(tst_rgen_orderings);
+    export(tst_rgen_exp_bounds_index);
+  }
+  tst_rgen_char_index = 1;
+  tst_rgen_var_index = 1;
+  tst_rgen_comp_index = 1;
+  tst_rgen_ordering_index = 0;
+  tst_rgen_exp_bounds_index = 1;
+  tst_rgen_orderings = tst_rgen_generate_product_orderings(tst_rgen_nvars[1], tst_rgen_simple_orderings, tst_rgen_extra_weights, tst_rgen_products);
+}
+
+proc tst_next_ring()
+{
+  tst_rgen_ordering_index++;
+  if (tst_rgen_ordering_index > size(tst_rgen_orderings))
+  {
+    tst_rgen_comp_index++;
+    if (tst_rgen_comp_index > size(tst_rgen_comp_orderings))
+    {
+      tst_rgen_exp_bounds_index++;
+      if (tst_rgen_exp_bounds_index > size(tst_rgen_exp_bounds))
+      {
+        tst_rgen_var_index++;
+        if (tst_rgen_var_index > size(tst_rgen_nvars))
+        {
+          tst_rgen_char_index++;
+          if (tst_rgen_char_index > size(tst_rgen_charstrs))
+          {
+            return ("");
+          }
+          tst_rgen_var_index = 1;
+        }
+        tst_rgen_exp_bounds_index = 1;
+      }
+      tst_rgen_comp_index = 1;
+      tst_rgen_orderings =  tst_rgen_generate_product_orderings(tst_rgen_nvars[tst_rgen_var_index], tst_rgen_simple_orderings, tst_rgen_extra_weights, tst_rgen_products);
+    }
+    tst_rgen_ordering_index = 1;
+  }
+
+  if (tst_rgen_nvars[tst_rgen_var_index] <= 26)
+  {
+    string rs = "(" + tst_rgen_charstrs[tst_rgen_char_index] + "),(" + A_Z("a", tst_rgen_nvars[tst_rgen_var_index]) + "),(";
+  }
+  else
+  {
+    string rs = "(" + tst_rgen_charstrs[tst_rgen_char_index] + "),(x(1.." + string(tst_rgen_nvars[tst_rgen_var_index]) + ")),(";
+  }
+
+  if (tst_rgen_comp_orderings[tst_rgen_comp_index] == "CC")
+  {
+    rs = rs + "C," + tst_rgen_orderings[tst_rgen_ordering_index];
+  }
+  else
+  {
+    if (tst_rgen_comp_orderings[tst_rgen_comp_index] == "cc")
+    {
+      rs = rs + "c," + tst_rgen_orderings[tst_rgen_ordering_index];
+    }
+    else
+    {
+      if (tst_rgen_comp_orderings[tst_rgen_comp_index] == "C")
+      {
+        rs = rs + tst_rgen_orderings[tst_rgen_ordering_index] + ", C";
+      }
+      else
+      {
+        if (tst_rgen_comp_orderings[tst_rgen_comp_index] == "c")
+        {
+          rs = rs + tst_rgen_orderings[tst_rgen_ordering_index] + ",c";
+        }
+        else
+        {
+          rs = rs + tst_rgen_orderings[tst_rgen_ordering_index];
+        }
+      }
+    }
+  }
+  if (size(tst_rgen_exp_bounds) > 0)
+  {
+    if (! defined(tst_rgen_Lring))
+    {
+      string tst_rgen_Lring;
+      export(tst_rgen_Lring);
+    }
+    tst_rgen_Lring = rs + ",L(" + string(tst_rgen_exp_bounds[tst_rgen_exp_bounds_index]) + "))";
+    if (system("version") >= 1309)
+    {
+      rs = tst_rgen_Lring;
+    }
+    else
+    {
+      rs = rs + ")";
+    }
+  }
+  else
+  {
+    rs = rs + ")";
+  }
+
+  return (rs);
+}
+
+
+proc tst_FullIdeal()
+{
+  ideal id, mid;
+  int n_vars = nvars(basering);
+  int i,j;
+  for (i=1; i<=n_vars; i++)
+  {
+    mid = maxideal(i);
+    id[i] = mid[1];
+    for (j=2;j<=size(mid); j++)
+    {
+      id[i] = id[i] + mid[j];
+    }
+  }
+  return (id);
+}
+
+proc tst_cyclic(int n)
+{
+  int i, j, k, l;
+  ideal id;
+
+  poly p, q;
+  for (i=1; i<n; i++)
+  {
+    p = 0;
+    k = 1;
+    for (j=1; j<=n; j++)
+    {
+      q = var(j);
+      k = j + 1;
+        if (k > n)
+        {
+          k=1;
+        }
+      for (l=2; l <= i; l++)
+      {
+        q = q*var(k);
+        k++;
+        if (k > n)
+        {
+          k=1;
+        }
+      }
+      p = p + q;
+    }
+    id[i] = p;
+  }
+
+  p = var(1);
+  for (i=2;i<=n;i++)
+  {
+    p = p*var(i);
+  }
+  id[n] = p -1;
+  return (id);
+}
+
+proc tst_hom_cyclic(int n)
+{
+  ideal i = tst_cyclic(n);
+  i[n] = i[n] + 1 + var(n+1)^n;
+  return (i);
+}
+
+proc tst_TestMult(ideal id, int how_often, int Module)
+{
+  int i, j, l, is, s;
+  module m;
+  def ret;
+  poly p;
+  if (Module > 0)
+  {
+    for (i=1; i<= size(id); i++)
+    {
+      m[i] = id[i] + gen(2)*id[i];
+    }
+    ret = m;
+  }
+  else
+  {
+    ret = id;
+  }
+  l = 0;
+  for (i=1; i<= how_often; i++)
+  {
+    l++;
+    if (l > size(id))
+    {
+      l = 1;
+    }
+    for (j=1;j<=size(id);j++)
+    {
+      ret[j] = ret[j]*id[l];
+    }
+  }
+  for (i=1; i<=size(ret); i++)
+  {
+    is = size(ret[i]);
+    s = s + is;
+    string(i) + " : " + string(is) + " : " + string(lead(ret[i]));
+  }
+  "s : " + string(s);
+}
+
+proc tst_TestAdd(ideal id, int how_often, int Module)
+{
+  int i, j, k, l;
+  module m;
+  ideal idl = 1, maxideal(1);
+
+  if (Module > 0)
+  {
+    for (i=1; i<= size(id); i++)
+    {
+      m[i] = id[i] + gen(2)*id[i];
+    }
+  }
+  def r,p;
+  if (Module > 0)
+  {
+    r = m;
+  }
+  else
+  {
+    r = id;
+  }
+  l = 0;
+  for (j=1; j<= how_often; j++)
+  {
+    l++;
+    if (l > size(idl))
+    {
+      l = 1;
+    }
+    for (k=1; k<=size(r); k++)
+    {
+      p = idl[l]*r[k];
+      for (i=1; i<=k;i++)
+      {
+        p = p + r[i];
+      }
+      r[k] = p;
+    }
+  }
+  int is, s;
+  for (i=1; i<=size(r); i++)
+  {
+    is = size(r[i]);
+    s = s + is;
+    string(i) + " : " + string(is) + " : " + string(lead(r[i]));
+  }
+  "s : " + string(s);
+}
+
+proc tst_PrintStats(def id)
+{
+  int i, is, s;
+
+  for (i=1; i<=size(id); i++)
+  {
+    is = size(id[i]);
+    s = s + is;
+    string(i) + " : " + string(is) + " : " + string(lead(id[i]));
+  }
+  "s : " + string(s);
+}
+
diff --git a/Singular/LIB/weierstr.lib b/Singular/LIB/weierstr.lib
new file mode 100644
index 0000000..e87ec20
--- /dev/null
+++ b/Singular/LIB/weierstr.lib
@@ -0,0 +1,241 @@
+////////////////////////////////////////////////////////////////////////////
+version="version weierstr.lib 4.0.0.0 Jun_2013 "; // $Id: b457489cc9c710a0b3f9d3dee99355b33c6ae63e $
+category="Teaching";
+info="
+LIBRARY:  weierstr.lib   Procedures for the Weierstrass Theorems
+AUTHOR:                  G.-M. Greuel, greuel at mathematik.uni-kl.de
+
+PROCEDURES:
+ weierstrDiv(g,f,d);   perform Weierstrass division of g by f up to degree d
+ weierstrPrep(f,d);    perform Weierstrass preparation of f up to degree d
+ lastvarGeneral(f);    make f general of finite order w.r.t. last variable
+ generalOrder(f);      compute integer b s.t. f is x_n-general of order b
+
+           (parameters in square brackets [] are optional)
+";
+
+LIB "mondromy.lib";
+LIB "poly.lib";
+///////////////////////////////////////////////////////////////////////////////
+
+proc generalOrder (poly f)
+"USAGE:   generalOrder(f); f=poly
+RETURN:  integer b if f is general of order b w.r.t. the last variable, say T,
+         resp. -1 if not
+         (i.e. f(0,...,0,T) is of order b, resp. f(0,...,0,T)==0)
+NOTE:    the procedure works for any monomial ordering
+EXAMPLE: example generalOrder; shows an example
+"
+{ int ii;
+  int n = nvars(basering);
+  for (ii=1; ii<n; ii++)
+  {
+    f = subst(f,var(ii),0);
+  }
+  return(mindeg(f));
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring R = 0,(x,y),ds;
+   poly f = x2-4xy+4y2-2xy2+4y3+y4;
+   generalOrder(f);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc weierstrDiv ( poly g, poly f, int d )
+"USAGE:   weierstrDiv(g,f,d); g,f=poly, d=integer
+ASSUME:  f must be general of finite order, say b, in the last ring variable,
+         say T; if not use the procedure lastvarGeneral first
+PURPOSE: perform the Weierstrass division of g by f up to order d
+RETURN:  - a list, say l, of two polynomials and an integer, such that@*
+            g = l[1]*f + l[2],  deg_T(l[2]) < b, up to (including) total degree d@*
+         - l[3] is the number of iterations used
+         - if f is not T-general, return (0,g)
+NOTE:    the procedure works for any monomial ordering
+THEORY:  the proof of Grauert-Remmert (Analytische Stellenalgebren) is used
+         for the algorithm
+EXAMPLE: example weierstrDiv; shows an example
+"
+{
+//------------- initialisation and check T - general -------------------------
+  int a,b,ii,D;
+  poly r,h;
+  list result;
+  int y = printlevel - voice + 2;
+  int n = nvars(basering);
+  intvec v;
+  v[n]=1;
+  b = generalOrder(f);
+  if (y>0)
+  {
+     "//",f;"// is "+string(var(n))+"-general of order", b;
+     pause("press <return> to continue");
+  }
+  if ( b==-1 )
+  {
+     "// second polynomial is not general w.r.t. last variable";
+     "// use the procedure lastvarGeneral first";
+     result=h,g;
+     return(result);
+  }
+//------------------------- start computation --------------------------------
+  D = d+b;
+  poly fhat = jet(f,b-1,v);
+  poly ftilde = (f-fhat)/var(n)^b;
+  poly u = invunit(ftilde,D);
+  if (y>0)
+  {
+     "// fhat (up to order", d,"):";
+     "//", fhat;
+     "// ftilde:";
+     "//", ftilde;
+     "// ftilde-inverse:";
+     "//", u;
+     pause("press <return> to continue");
+  }
+  poly khat, ktilde;
+  poly k=g;
+  khat = jet(k,b-1,v);
+  ktilde = (k-r)/var(n)^b;
+  r = khat;
+  h = ktilde;
+  ii=0;
+  while (size(k) > 0)
+  {
+  if (y>0)
+    {
+     "// loop",ii+1;
+     "// khat:";
+     "//", khat;
+     "// ktilde:";
+     "//", ktilde;
+     "// remainder:";
+     "//", r;
+     "// multiplier:";
+     "//", h;
+     pause("press <return> to continue");
+    }
+    k = jet(-fhat*u*ktilde,D);
+    khat = jet(k,b-1,v);
+    ktilde = (k-khat)/var(n)^b;
+    r = r + khat;
+    h = h + ktilde;
+    ii=ii+1;
+  }
+  result = jet(u*h,d),jet(r,d),ii;
+  return(result);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring R = 0,(x,y),ds;
+   poly f = y - xy2 + x2;
+   poly g = y;
+   list l = weierstrDiv(g,f,10); l;"";
+   l[1]*f + l[2];               //g = l[1]*f+l[2] up to degree 10
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc weierstrPrep (poly f, int d)
+"USAGE:   weierstrPrep(f,d); f=poly, d=integer
+ASSUME:  f must be general of finite order, say b, in the last ring variable,
+         say T; if not apply the procedure lastvarGeneral first
+PURPOSE: perform the Weierstrass preparation of f up to order d
+RETURN:  - a list, say l, of two polynomials and one integer,
+         l[1] a unit, l[2] a Weierstrass polynomial, l[3] an integer
+         such that l[1]*f = l[2], where l[2] is a Weierstrass polynomial,
+         (i.e. l[2] = T^b + lower terms in T) up to (including) total degree d
+         l[3] is the number of iterations used@*
+         - if f is not T-general, return (0,0)
+NOTE:    the procedure works for any monomial ordering
+THEORY:  the proof of Grauert-Remmert (Analytische Stellenalgebren) is used
+         for the algorithm
+EXAMPLE: example weierstrPrep; shows an example
+"
+{
+  int n = nvars(basering);
+  int b = generalOrder(f);
+  if ( b==-1 )
+  {
+     "// second polynomial is not general w.r.t. last variable";
+     "// use the procedure lastvarGeneral first";
+     poly h,g;
+     list result=h,g;
+     return(result);
+  }
+  list L = weierstrDiv(var(n)^b,f,d);
+  list result = L[1], var(n)^b - L[2],L[3];
+  return(result);
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring R = 0,(x,y),ds;
+   poly f = xy+y2+y4;
+   list l = weierstrPrep(f,5); l; "";
+   f*l[1]-l[2];                      // = 0 up to degree 5
+}
+///////////////////////////////////////////////////////////////////////////////
+
+proc lastvarGeneral (poly f)
+"USAGE:   lastvarGeneral(f,d); f=poly
+RETURN:  poly, say g, obtained from f by a generic change of variables, s.t.
+         g is general of finite order b w.r.t. the last ring variable, say T
+         (i.e. g(0,...,0,T)= c*T^b + higher terms, c!=0)
+NOTE:    the procedure works for any monomial ordering
+EXAMPLE: example lastvarGeneral; shows an example
+"
+{
+  int n = nvars(basering);
+  int b = generalOrder(f);
+  if ( b >=0 )  { return(f); }
+  else
+  {
+    def B = basering;
+    int ii;
+    map phi;
+    ideal m=maxideal(1);
+    int d = mindeg1(f);
+    poly g = jet(f,d);
+    for (ii=1; ii<=n-1; ii++)
+    {
+       if (size(g)>size(subst(g,var(ii),0)) )
+       {
+          m[ii]= var(ii)+ random(1-(voice-2)*10,1+(voice-2)*10)*var(n);
+          phi = B,m;
+          g = phi(f);
+          break;
+       }
+    }
+    if ( voice <=5 )
+    {
+       return(lastvarGeneral(g));
+    }
+    if ( voice ==6 )
+    {
+       for (ii=1; ii<=n-1; ii++)
+      {
+         m[ii]= var(ii)+ var(n)*random(1,1000);
+      }
+      phi = basering,m;
+      g = phi(f);
+      return(lastvarGeneral(g));
+    }
+    else
+    {
+      for (ii=1; ii<=n-1; ii++)
+      {
+         m[ii]= var(ii)+ var(n)^random(2,voice*d);
+      }
+      phi = basering,m;
+      g = phi(f);
+      return(lastvarGeneral(g));
+    }
+  }
+}
+example
+{ "EXAMPLE:"; echo = 2;
+   ring R = 2,(x,y,z),ls;
+   poly f = xyz;
+   lastvarGeneral(f);
+}
+///////////////////////////////////////////////////////////////////////////////
+
diff --git a/Singular/LIB/zeroset.lib b/Singular/LIB/zeroset.lib
new file mode 100644
index 0000000..063b591
--- /dev/null
+++ b/Singular/LIB/zeroset.lib
@@ -0,0 +1,1484 @@
+////////////////////////////////////////////////////////////////////////////
+version="version zeroset.lib 4.0.0.0 Jun_2013 "; // $Id: 5540e60ae4427cbb3496537ada892d633ad0b801 $
+category="Symbolic-numerical solving";
+info="
+LIBRARY:  zeroset.lib      Procedures for roots and factorization
+AUTHOR:   Thomas Bayer,    email: tbayer at mathematik.uni-kl.de,@*
+          http://wwwmayr.informatik.tu-muenchen.de/personen/bayert/@*
+          Current address: Hochschule Ravensburg-Weingarten
+
+OVERVIEW:
+ Algorithms for finding the zero-set of a zero-dim. ideal in Q(a)[x_1,..,x_n],
+ roots and factorization of univariate polynomials over Q(a)[t]
+ where a is an algebraic number. Written in the scope of the
+ diploma thesis (advisor: Prof. Gert-Martin Greuel) 'Computations of moduli
+ spaces of semiquasihomogeneous singularities and an implementation in Singular'.
+ This library is meant as a preliminary extension of the functionality
+ of @sc{Singular} for univariate factorization of polynomials over simple algebraic
+ extensions in characteristic 0.
+
+ NOTE:
+ Subprocedures with postfix 'Main' require that the ring contains a variable
+ 'a' and no parameters, and the ideal 'mpoly', where 'minpoly' from the
+ basering is stored.
+
+PROCEDURES:
+ Quotient(f, g)    quotient q  of f w.r.t. g (in f = q*g + remainder)
+ remainder(f,g)    remainder of the division of f by g
+ roots(f)    computes all roots of f in an extension field of Q
+ sqfrNorm(f)    norm of f (f must be squarefree)
+ zeroSet(I)    zero-set of the 0-dim. ideal I
+
+ egcdMain(f, g)    gcd over an algebraic extension field of Q
+ factorMain(f)    factorization of f over an algebraic extension field
+ invertNumberMain(c)  inverts an element of an algebraic extension field
+ quotientMain(f, g)  quotient of f w.r.t. g
+ remainderMain(f,g)  remainder of the division of f by g
+ rootsMain(f)    computes all roots of f, might extend the ground field
+ sqfrNormMain(f)  norm of f (f must be squarefree)
+ containedQ(data, f)  f in data ?
+ sameQ(a, b)    a == b (list a,b)
+";
+
+LIB "primitiv.lib";
+LIB "primdec.lib";
+
+// note : return a ring : ring need not be exported !!!
+
+// Artihmetic in Q(a)[x] without built-in procedures
+// assume basering = Q[x,a] and minpoly is represented by mpoly(a).
+// the algorithms are taken from "Polynomial Algorithms in Computer Algebra",
+// F. Winkler, Springer Verlag Wien, 1996.
+
+
+// To do :
+// squarefree factorization
+// multiplicities
+
+// Improvement :
+// a main problem is the growth of the coefficients. Try roots(x7 - 1)
+// return ideal mpoly !
+// mpoly is not monic, comes from primitive_extra
+
+// IMPLEMENTATION
+//
+// In procedures with name 'proc-name'Main a polynomial ring over a simple
+// extension field is represented as Q[x...,a] together with the ideal
+// 'mpoly' (attribute "isSB"). The arithmetic in the extension field is
+// implemented in the procedures in the procedures 'MultPolys' (multiplication)
+// and 'InvertNumber' (inversion). After addition and substraction one should
+// apply 'SimplifyPoly' to the result to reduce the result w.r.t. 'mpoly'.
+// This is done by reducing each coefficient seperately, which is more
+// efficient for polynomials with many terms.
+
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc roots(poly f)
+"USAGE:   roots(f); where f is a polynomial
+PURPOSE: compute all roots of f in a finite extension of the ground field
+         without multiplicities.
+RETURN:  ring, a polynomial ring over an extension field of the ground field,
+         containing a list 'theRoots' and polynomials 'newA' and 'f':
+  @format
+  - 'theRoots' is the list of roots of the polynomial f (no multiplicities)
+  - if the ground field is Q(a') and the extension field is Q(a), then
+    'newA' is the representation of a' in Q(a).
+    If the basering contains a parameter 'a' and the minpoly remains unchanged
+    then 'newA' = 'a'.
+    If the basering does not contain a parameter then 'newA' = 'a' (default).
+  - 'f' is the polynomial f in Q(a) (a' being substituted by 'newA')
+  @end format
+ASSUME:  ground field to be Q or a simple extension of Q given by a minpoly
+EXAMPLE: example roots; shows an example
+"
+{
+  int dbPrt = printlevel-voice+3;
+
+  // create a new ring where par(1) is replaced by the variable
+  // with the same name or, if basering does not contain a parameter,
+  // with a new variable 'a'.
+
+  def ROB = basering;
+  def ROR = TransferRing(basering);
+  setring ROR;
+  export(ROR);
+
+  // get the polynomial f and find the roots
+
+  poly f = imap(ROB, f);
+  list result = rootsMain(f);  // find roots of f
+
+  // store the roots and the new representation of 'a' and transform
+  // the coefficients of f.
+
+  list theRoots = result[1];
+  poly newA = result[2];
+  map F = basering, maxideal(1);
+  F[nvars(basering)] = newA;
+  poly fn = SimplifyPoly(F(f));
+
+  // create a new ring with minploy = mpoly[1] (from ROR)
+
+  def RON = NewBaseRing();
+  setring(RON);
+  list theRoots = imap(ROR, theRoots);
+  poly newA = imap(ROR, newA);
+  poly f = imap(ROR, fn);
+  kill ROR;
+  export(theRoots);
+  export(newA);
+  export(f); dbprint(dbPrt,"
+// 'roots' created a new ring which contains the list 'theRoots' and
+// the polynomials 'f' and 'newA'
+// To access the roots, newA and the new representation of f, type
+   def R = roots(f); setring R; theRoots; newA; f;
+");
+  return(RON);
+}
+example
+{"EXAMPLE:";  echo = 2;
+  ring R = (0,a), x, lp;
+  minpoly = a2+1;
+  poly f = x3 - a;
+  def R1 = roots(f);
+  setring R1;
+  minpoly;
+  newA;
+  f;
+  theRoots;
+  map F;
+  F[1] = theRoots[1];
+  F(f);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc rootsMain(poly f)
+"USAGE:   rootsMain(f); where f is a polynomial
+PURPOSE: compute all roots of f in a finite extension of the ground field
+         without multiplicities.
+RETURN:  list, all entries are polynomials
+  @format
+  _[1] = roots of f, each entry is a polynomial
+  _[2] = 'newA' - if the ground field is Q(b) and the extension field
+         is Q(a), then 'newA' is the representation of b in Q(a)
+  _[3] = minpoly of the algebraic extension of the ground field
+  @end format
+ASSUME:  basering = Q[x,a] ideal mpoly must be defined, it might be 0!
+NOTE:    might change the ideal mpoly!!
+EXAMPLE: example rootsMain; shows an example
+"
+{
+  int i, linFactors, nlinFactors, dbPrt;
+  intvec wt = 1,0;    // deg(a) = 0
+  list factorList, nlFactors, nlMult, roots, result;
+  poly fa, lc;
+
+  dbPrt = printlevel-voice+3;
+
+  // factor f in Q(a)[t] to obtain the roots lying in Q(a)
+  // firstly, find roots of the linear factors,
+  // nonlinear factors are processed later
+
+  dbprint(dbPrt, "roots of " + string(f) +  ", minimal polynomial = " + string(mpoly[1]));
+  factorList = factorMain(f);          // Factorize f
+  dbprint(dbPrt, (" prime factors of f are : " + string(factorList[1])));
+
+  linFactors = 0;
+  nlinFactors = 0;
+  for(i = 2; i <= size(factorList[1]); i = i + 1) {  // find linear and nonlinear factors
+    fa = factorList[1][i];
+    if(deg(fa, wt) == 1) {
+      linFactors++;        // get the root from the linear factor
+      lc = LeadTerm(fa, 1)[3];
+      fa = MultPolys(invertNumberMain(lc), fa); // make factor monic
+      roots[linFactors] = var(1) - fa;  // fa is monic !!
+    }
+    else {            // ignore nonlinear factors
+      nlinFactors++;
+      nlFactors[nlinFactors] = factorList[1][i];
+      nlMult[nlinFactors] = factorList[2][i];
+    }
+  }
+  if(linFactors == size(factorList[1]) - 1) {    // all roots of f are contained in the ground field
+    result[1] = roots;
+    result[2] = var(2);
+    result[3] = mpoly[1];
+    return(result);
+  }
+
+  // process the nonlinear factors, i.e., extend the ground field
+  // where a nonlinear factor (irreducible) is a minimal polynomial
+  // compute the primitive element of this extension
+
+  ideal primElem, minPolys, Fid;
+  list partSol;
+  map F, Xchange;
+  poly f1, newA, mp, oldMinPoly;
+
+  Fid = mpoly;
+  F[1] = var(1);
+  Xchange[1] = var(2);      // the variables have to be exchanged
+  Xchange[2] = var(1);      // for the use of 'primitive'
+
+  if(nlinFactors == 1)             // one nl factor
+  {
+    // compute the roots of the nonlinear (irreducible, monic) factor f1 of f
+    // by extending the basefield by a' with minimal polynomial f1
+    // Then call roots(f1) to find the roots of f1 over the new base field
+
+    f1 = nlFactors[1];
+    if(mpoly[1] != 0)
+    {
+      mp = mpoly[1];
+      minPolys = Xchange(mp), Xchange(f1);
+      if (deg(jet(minPolys[2],0,intvec(1,0)))==0)
+      { primElem = primitive(minPolys); } // random coord. change
+      else
+      { primElem = primitive_extra(minPolys); } // no random coord. change
+      mpoly = std(primElem[1]);
+      F = basering, maxideal(1);
+      F[2] = primElem[2];      // transfer all to the new representation
+      newA = primElem[2];      // new representation of a
+      f1 = SimplifyPoly(F(f1));     //reduce(F(f1), mpoly);
+      if(size(roots) > 0) {roots = SimplifyData(F(roots));}
+    }
+    else {
+      mpoly = std(Xchange(f1));
+      newA = var(2);
+    }
+    result[3] = mpoly[1];
+    oldMinPoly = mpoly[1];
+    partSol = rootsMain(f1);    // find roots of f1 over extended field
+
+    if(oldMinPoly != partSol[3]) {    // minpoly has changed ?
+      // all previously computed roots must be transformed
+      // because the minpoly has changed
+      result[3] = partSol[3];    // new minpoly
+      F[2] = partSol[2];    // new representation of algebraic number
+      if(size(roots) > 0) {roots = SimplifyData(F(roots)); }
+      newA = SimplifyPoly(F(newA)); // F(newA);
+    }
+    roots = roots + partSol[1];  // add roots
+    result[2] = newA;
+    result[1] = roots;
+  }
+  else {  // more than one nonlinear (irreducible) factor (f_1,...,f_r)
+    // solve each of them by rootsMain(f_i), append their roots
+    // change the minpoly and transform all previously computed
+    // roots if necessary.
+    // Note that the for-loop is more or less book-keeping
+
+    newA = var(2);
+    result[2] = newA;
+    for(i = 1; i <= size(nlFactors); i = i + 1) {
+      oldMinPoly = mpoly[1];
+      partSol = rootsMain(nlFactors[i]);    // main work
+      nlFactors[i] = 0;        // delete factor
+      result[3] = partSol[3];        // store minpoly
+
+      // book-keeping starts here as in the case 1 nonlinear factor
+
+      if(oldMinPoly != partSol[3]) { // minpoly has changed
+        F = basering, maxideal(1);
+        F[2] = partSol[2];    // transfer all to the new representation
+        newA = SimplifyPoly(F(newA));    // F(newA); new representation of a
+        result[2] = newA;
+        if(i < size(nlFactors)) {
+          nlFactors = SimplifyData(F(nlFactors));
+        } // transform remaining factors
+        if(size(roots) > 0) {roots = SimplifyData(F(roots));}
+      }
+      roots = roots + partSol[1];    // transform roots
+      result[1] = roots;
+    }  // end more than one nl factor
+
+  }
+  return(result);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc zeroSet(ideal I, list #)
+"USAGE:   zeroSet(I [,opt] ); I=ideal, opt=integer
+PURPOSE: compute the zero-set of the zero-dim. ideal I, in a finite extension
+         of the ground field.
+RETURN:  ring, a polynomial ring over an extension field of the ground field,
+         containing a list 'theZeroset', a polynomial 'newA', and an
+         ideal 'id':
+  @format
+  - 'theZeroset' is the list of the zeros of the ideal I, each zero is an ideal.
+  - if the ground field is Q(b) and the extension field is Q(a), then
+    'newA' is the representation of b in Q(a).
+    If the basering contains a parameter 'a' and the minpoly remains unchanged
+    then 'newA' = 'a'.
+    If the basering does not contain a parameter then 'newA' = 'a' (default).
+  - 'id' is the ideal I in Q(a)[x_1,...] (a' substituted by 'newA')
+  @end format
+ASSUME:  dim(I) = 0, and ground field to be Q or a simple extension of Q given
+         by a minpoly.
+OPTIONS: opt = 0: no primary decomposition (default)
+         opt > 0: primary decomposition
+NOTE:    If I contains an algebraic number (parameter) then I must be
+         transformed w.r.t. 'newA' in the new ring.
+EXAMPLE: example zeroSet; shows an example
+"
+{
+  int primaryDecQ, dbPrt;
+  list rp;
+
+  dbPrt = printlevel-voice+2;
+
+  if(size(#) > 0) { primaryDecQ = #[1]; }
+  else { primaryDecQ = 0; }
+
+  // create a new ring 'ZSR' with one additional variable instead of the
+  // parameter
+  // if the basering does not contain a parameter then 'a' is used as the
+  // additional variable.
+
+  def RZSB = basering;
+  def ZSR = TransferRing(RZSB);
+  setring ZSR;
+
+  // get ideal I and find the zero-set
+
+  ideal id = std(imap(RZSB, I));
+//  print(dim(id));
+  if(dim(id) > 1) {       // new variable adjoined to ZSR
+    ERROR(" ideal not zerodimensional ");
+  }
+
+  list result = zeroSetMain(id, primaryDecQ);
+
+  // store the zero-set, minimal polynomial and the new representative of 'a'
+
+  list theZeroset = result[1];
+  poly newA = result[2];
+  poly minPoly = result[3][1];
+
+  // transform the generators of the ideal I w.r.t. the new representation
+  // of 'a'
+
+  map F = basering, maxideal(1);
+  F[nvars(basering)] = newA;
+  id = SimplifyData(F(id));
+
+  // create a new ring with minpoly = minPoly
+
+  def RZBN = NewBaseRing();
+  setring RZBN;
+
+  list theZeroset = imap(ZSR, theZeroset);
+  poly newA = imap(ZSR, newA);
+  ideal id = imap(ZSR, id);
+  kill ZSR;
+
+  export(id);
+  export(theZeroset);
+  export(newA);
+    dbprint(dbPrt,"
+// 'zeroSet' created a new ring which contains the list 'theZeroset', the ideal
+// 'id' and the polynomial 'newA'. 'id' is the ideal of the input transformed
+// w.r.t. 'newA'.
+// To access the zero-set, 'newA' and the new representation of the ideal, type
+   def R = zeroSet(I); setring R; theZeroset; newA; id;
+");
+  setring RZSB;
+  return(RZBN);
+}
+example
+{"EXAMPLE:";  echo = 2;
+  ring R = (0,a), (x,y,z), lp;
+  minpoly = a2 + 1;
+  ideal I = x2 - 1/2, a*z - 1, y - 2;
+  def T = zeroSet(I);
+  setring T;
+  minpoly;
+  newA;
+  id;
+  theZeroset;
+  map F1 = basering, theZeroset[1];
+  map F2 = basering, theZeroset[2];
+  F1(id);
+  F2(id);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc invertNumberMain(poly f)
+"USAGE:   invertNumberMain(f); where f is a polynomial
+PURPOSE: compute 1/f if f is a number in Q(a), i.e., f is represented by a
+         polynomial in Q[a].
+RETURN:  poly 1/f
+ASSUME:  basering = Q[x_1,...,x_n,a], ideal mpoly must be defined and != 0 !
+NOTE:    outdated, use / instead
+"
+{
+  if(diff(f, var(1)) != 0) { ERROR("number must not contain variable !");}
+
+  int n = nvars(basering);
+  def RINB = basering;
+  string ringSTR = "ring RINR = 0, " + string(var(n)) + ", dp;";
+  execute(ringSTR);        // new ring = Q[a]
+
+  list gcdList;
+  poly f, g, inv;
+
+  f = imap(RINB, f);
+  g = imap(RINB, mpoly)[1];
+
+  if(diff(f, var(1)) != 0) { inv = extgcd(f, g)[2]; }  // f contains var(1)
+  else {  inv = 1/f;}          // f element in Q
+
+  setring(RINB);
+  return(imap(RINR, inv));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc MultPolys(poly f, poly g)
+"USAGE:   MultPolys(f, g); poly f,g
+PURPOSE: multiply the polynomials f and g and reduce them w.r.t. mpoly
+RETURN:  poly f*g
+ASSUME:  basering = Q[x,a], ideal mpoly must be defined, it might be 0 !
+"
+{
+  return(SimplifyPoly(f * g));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc LeadTerm(poly f, int i)
+"USAGE:   LeadTerm(f); poly f, int i
+PURPOSE: compute the leading coef and term of f w.r.t var(i), where the last
+         ring variable is treated as a parameter.
+RETURN:  list of polynomials
+         _[1] = leading term
+         _[2] = leading monomial
+         _[3] = leading coefficient
+ASSUME:  basering = Q[x_1,...,x_n,a]
+"
+{
+  list result;
+  matrix co = coef(f, var(i));
+  result[1] = co[1, 1]*co[2, 1];
+  result[2] = co[1, 1];
+  result[3] = co[2, 1];
+  return(result);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc Quotient(poly f, poly g)
+"USAGE:   Quotient(f, g); where f,g are polynomials;
+PURPOSE: compute the quotient q and remainder r s.t. f = g*q + r, deg(r) < deg(g)
+RETURN:  list of polynomials
+  @format
+  _[1] = quotient  q
+  _[2] = remainder r
+  @end format
+ASSUME:  basering = Q[x] or Q(a)[x]
+NOTE: This procedure is outdated, and should no longer be used. Use div and mod
+instead.
+EXAMPLE: example Quotient; shows an example
+"
+{
+  def QUOB = basering;
+  def QUOR = TransferRing(basering);  // new ring with parameter 'a' replaced by a variable
+  setring QUOR;
+  export(QUOR);
+  poly f = imap(QUOB, f);
+  poly g = imap(QUOB, g);
+  list result = quotientMain(f, g);
+
+  setring(QUOB);
+  list result = imap(QUOR, result);
+  kill QUOR;
+  return(result);
+}
+example
+{"EXAMPLE:";  echo = 2;
+ ring R = (0,a), x, lp;
+ minpoly = a2+1;
+ poly f =  x4 - 2;
+ poly g = x - a;
+ list qr = Quotient(f, g);
+ qr;
+ qr[1]*g + qr[2] - f;
+}
+
+proc quotientMain(poly f, poly g)
+"USAGE:   quotientMain(f, g); where f,g are polynomials
+PURPOSE: compute the quotient q and remainder r s.th. f = g*q + r, deg(r) < deg(g)
+RETURN:  list of polynomials
+  @format
+  _[1] = quotient  q
+  _[2] = remainder r
+  @end format
+ASSUME:  basering = Q[x,a] and ideal mpoly is defined (it might be 0),
+         this represents the ring Q(a)[x] together with its minimal polynomial.
+NOTE: outdated, use div/mod instead
+"
+{
+  if(g == 0) { ERROR("Division by zero !");}
+
+  def QMB = basering;
+  def QMR = NewBaseRing();
+  setring QMR;
+  poly f, g, h;
+  h = imap(QMB, f) / imap(QMB, g);
+  setring QMB;
+  return(list(imap(QMR, h), 0));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc remainder(poly f, poly g)
+"USAGE:   remainder(f, g); where f,g are polynomials
+PURPOSE: compute the remainder of the division of f by g, i.e. a polynomial r
+         s.t. f = g*q + r, deg(r) < deg(g).
+RETURN:  poly
+ASSUME:  basering = Q[x] or Q(a)[x]
+NOTE: outdated, use mod/reduce instead
+"
+{
+  def REMB = basering;
+  def REMR = TransferRing(basering);  // new ring with parameter 'a' replaced by a variable
+  setring(REMR);
+  export(REMR);
+  poly f = imap(REMB, f);
+  poly g = imap(REMB, g);
+  poly h = remainderMain(f, g);
+
+  setring(REMB);
+  poly r = imap(REMR, h);
+  kill REMR;
+  return(r);
+}
+example
+{"EXAMPLE:";  echo = 2;
+ ring R = (0,a), x, lp;
+ minpoly = a2+1;
+ poly f =  x4 - 1;
+ poly g = x3 - 1;
+ remainder(f, g);
+}
+
+proc remainderMain(poly f, poly g)
+"USAGE:   remainderMain(f, g); where f,g are polynomials
+PURPOSE: compute the remainder r s.t. f = g*q + r, deg(r) < deg(g)
+RETURN:  poly
+ASSUME:  basering = Q[x,a] and ideal mpoly is defined (it might be 0),
+         this represents the ring Q(a)[x] together with its minimal polynomial.
+NOTE: outdated, use mod/reduce instead
+"
+{
+  int dg;
+  intvec wt = 1,0;;
+  poly lc, g1, r;
+
+  if(deg(g, wt) == 0) { return(0); }
+
+  lc = LeadTerm(g, 1)[3];
+  g1 = MultPolys(invertNumberMain(lc), g);  // make g monic
+
+  return(SimplifyPoly(reduce(f, std(g1))));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc egcdMain(poly f, poly g)
+"USAGE:   egcdMain(f, g); where f,g are polynomials
+PURPOSE: compute the polynomial gcd of f and g over Q(a)[x]
+RETURN:  poly
+ASSUME:  basering = Q[x,a] and ideal mpoly is defined (it might be 0),
+         this represents the ring Q(a)[x] together with its minimal polynomial.
+NOTE: outdated, use gcd instead
+EXAMPLE: example EGCD; shows an example
+"
+{
+// might be extended to return s1, s2 s.t. f*s1 + g*s2 = gcd
+  int i = 1;
+  poly r1, r2, r;
+
+  r1 = f;
+  r2 = g;
+
+  while(r2 != 0) {
+    r  = remainderMain(r1, r2);
+    r1 = r2;
+    r2 = r;
+  }
+  return(r1);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc MEGCD(poly f, poly g, int varIndex)
+"USAGE:   MEGCD(f, g, i); poly f, g; int i
+PURPOSE: compute  the polynomial gcd of f and g in the i'th variable
+RETURN:  poly
+ASSUME:  f, g are polynomials in var(i), last variable is the algebraic number
+EXAMPLE: example MEGCD; shows an example
+"
+// might be extended to return s1, s2 s.t. f*s1 + g*s2 = gc
+// not used !
+{
+  string @str, @sf, @sg, @mp, @parName;
+
+  def @RGCDB = basering;
+
+  @sf = string(f);
+  @sg = string(g);
+  @mp = string(minpoly);
+
+  if(npars(basering) == 0) { @parName = "0";}
+  else { @parName = "(0, " + parstr(basering) + ")"; }
+  @str = "ring @RGCD = " + @parName + ", " + string(var(varIndex)) + ", dp;";
+  execute(@str);
+  if(@mp != "0") { execute ("minpoly = " + @mp + ";"); }
+  execute("poly @f = " + @sf + ";");
+  execute("poly @g = " + @sg + ";");
+  export(@RGCD);
+  poly @h = gcd(@f, @g);
+  setring(@RGCDB);
+  poly h = imap(@RGCD, @h);
+  kill @RGCD;
+  return(h);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc sqfrNorm(poly f)
+"USAGE:   sqfrNorm(f); where f is a polynomial
+PURPOSE: compute the norm of the squarefree polynomial f in Q(a)[x].
+RETURN:  list with 3 entries
+  @format
+  _[1] = squarefree norm of g (poly)
+  _[2] = g (= f(x - s*a)) (poly)
+  _[3] = s (int)
+  @end format
+ASSUME:  f must be squarefree, basering = Q(a)[x] and minpoly != 0.
+NOTE:    the norm is an element of Q[x]
+EXAMPLE: example sqfrNorm; shows an example
+"
+{
+  def SNB = basering;
+  def SNR = TransferRing(SNB);  // new ring with parameter 'a'
+                                // replaced by a variable
+  setring SNR;
+  poly f = imap(SNB, f);
+  list result = sqfrNormMain(f);  // squarefree norm of f
+
+  setring SNB;
+  list result = imap(SNR, result);
+  kill SNR;
+  return(result);
+}
+example
+{"EXAMPLE:";  echo = 2;
+   ring R = (0,a), x, lp;
+   minpoly = a2+1;
+  poly f =  x4 - 2*x + 1;
+  sqfrNorm(f);
+}
+
+proc sqfrNormMain(poly f)
+"USAGE:   sqfrNorm(f); where f is a polynomial
+PURPOSE: compute the norm of the squarefree polynomial f in Q(a)[x].
+RETURN:  list with 3 entries
+  @format
+  _[1] = squarefree norm of g (poly)
+  _[2] = g (= f(x - s*a)) (poly)
+  _[3] = s (int)
+  @end format
+ASSUME:  f must be squarefree, basering = Q[x,a] and ideal mpoly is equal to
+         'minpoly', this represents the ring Q(a)[x] together with 'minpoly'.
+NOTE:   the norm is an element of Q[x]
+EXAMPLE: example SqfrNorm; shows an example
+"
+{
+  def SNRMB = basering;
+  int s = 0;
+  intvec wt = 1,0;
+  ideal mapId;
+  // list result;
+  poly g, N, N1, h;
+  string ringSTR;
+
+  mapId[1] = var(1) - var(2);    // linear transformation
+  mapId[2] = var(2);
+  map Fs = SNRMB, mapId;
+
+  N = resultant(f, mpoly[1], var(2));  // norm of f
+  N1 = diff(N, var(1));
+  g = f;
+
+  ringSTR = "ring SNRM1 = 0, " + string(var(1)) + ", dp;";  // univariate ring
+  execute(ringSTR);
+  poly N, N1, h;        // N, N1 do not contain 'a', use built-in gcd
+  h = gcd(imap(SNRMB, N), imap(SNRMB, N1));
+  setring(SNRMB);
+  h = imap(SNRM1, h);
+  while(deg(h, wt) != 0) {    // while norm is not squarefree
+    s = s + 1;
+    g = reduce(Fs(g), mpoly);
+    N = reduce(resultant(g, mpoly[1], var(2)), mpoly);  // norm of g
+    N1 = reduce(diff(N, var(1)), mpoly);
+    setring(SNRM1);
+    h = gcd(imap(SNRMB, N), imap(SNRMB, N1));
+    setring(SNRMB);
+    h = imap(SNRM1, h);
+  }
+  return(list(N, g, s));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc factorMain(poly f)
+"USAGE:   factorMain(f); where f is a polynomial
+PURPOSE: compute the factorization of the squarefree polynomial f over Q(a)[t],
+         minpoly  = p(a).
+RETURN:  list with 2 entries
+  @format
+  _[1] = factors, first is a constant
+  _[2] = multiplicities (not yet implemented)
+  @end format
+ASSUME:  basering = Q[x,a], representing Q(a)[x]. An ideal mpoly must
+         be defined, representing the minimal polynomial (it might be 0!).
+NOTE: outdated, use factorize instead
+EXAMPLE: example Factor; shows an example
+"
+{
+// extend this by a squarefree factorization !!
+// multiplicities are not valid !!
+  int i, s;
+  list normList, factorList, quo_rem;
+  poly f1, h, h1, H, g, leadCoef, invCoeff;
+  ideal fac1, fac2;
+  map F;
+
+  // if no minimal polynomial is defined then use 'factorize'
+  // FactorOverQ is wrapped around 'factorize'
+
+  if(mpoly[1] == 0) {
+    // print(" factorize : deg = " + string(deg(f, intvec(1,0))));
+    factorList = factorize(f); // FactorOverQ(f);
+    return(factorList);
+  }
+
+  // if mpoly != 0 and f does not contain the algebraic number, a root of
+  // f might be contained in Q(a). Hence one must not use 'factorize'.
+
+  fac1[1] = 1;
+  fac2[1] = 1;
+  normList = sqfrNormMain(f);
+  // print(" factorize : deg = " + string(deg(normList[1], intvec(1,0))));
+  factorList = factorize(normList[1]);     // factor squarefree norm of f over Q[x]
+  g = normList[2];
+  s = normList[3];
+  F[1] = var(1) + s*var(2);      // inverse transformation
+  F[2] = var(2);
+  fac1[1] = factorList[1][1];
+  fac2[1] = factorList[2][1];
+  for(i = 2; i <= size(factorList[1]); i = i + 1) {
+    H = factorList[1][i];
+    h = egcdMain(H, g);
+    quo_rem = quotientMain(g, h);
+    g = quo_rem[1];
+    fac1[i] = SimplifyPoly(F(h));
+    fac2[i] = 1;        // to be changed later
+  }
+  return(list(fac1, fac2));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc zeroSetMain(ideal I, int primDecQ)
+"USAGE:   zeroSetMain(ideal I, int opt); ideal I, int opt
+PURPOSE: compute the zero-set of the zero-dim. ideal I, in a simple extension
+         of the ground field.
+RETURN:  list
+         - 'f' is the polynomial f in  Q(a) (a' being substituted by newA)
+         _[1] = zero-set (list), is the list of the zero-set of the ideal I,
+                each entry is an ideal.
+         _[2] = 'newA';  if the ground field is Q(a') and the extension field
+                is Q(a), then 'newA' is the representation of a' in Q(a).
+                If the basering contains a parameter 'a' and the minpoly
+                remains unchanged then 'newA' = 'a'. If the basering does not
+                contain a parameter then 'newA' = 'a' (default).
+         _[3] = 'mpoly' (ideal), the minimal polynomial of the simple extension
+                of the ground field.
+ASSUME:  basering = K[x_1,x_2,...,x_n] where K = Q or a simple extension of Q
+         given by a minpoly; dim(I) = 0.
+NOTE:    opt = 0  no primary decomposition
+         opt > 0  use a primary decomposition
+EXAMPLE: example zeroSetMain; shows an example
+"
+{
+  // main work is done in zeroSetMainWork, here the zero-set of each ideal from the
+  // primary decompostion is coputed by menas of zeroSetMainWork, and then the
+  // minpoly and the parameter representing the algebraic extension are
+  // transformed according to 'newA', i.e., only bookeeping is done.
+
+  def altring=basering;
+  int i, j, n, noMP, dbPrt;
+  intvec w;
+  list currentSol, result, idealList, primDecList, zeroSet;
+  ideal J;
+  map Fa;
+  poly newA, oldMinPoly;
+
+  dbPrt = printlevel-voice+2;
+  dbprint(dbPrt, "zeroSet of " + string(I) + ", minpoly = " + string(minpoly));
+
+  n = nvars(basering) - 1;
+  for(i = 1; i <= n; i++) { w[i] = 1;}
+  w[n + 1] = 0;
+
+  if(primDecQ == 0) { return(zeroSetMainWork(I, w, 0)); }
+
+  newA = var(n + 1);
+  if(mpoly[1] == 0) { noMP = 1;}
+  else {noMP = 0;}
+
+  primDecList = primdecGTZ(I);      // primary decomposition
+  dbprint(dbPrt, "primary decomposition consists of " + string(size(primDecList)) + " primary ideals ");
+  // idealList = PDSort(idealList);    // high degrees first
+
+  for(i = 1; i <= size(primDecList); i = i + 1) {
+    idealList[i] = primDecList[i][2];  // use prime component
+    dbprint(dbPrt, string(i) + "  " + string(idealList[i]));
+  }
+
+  // compute the zero-set of each primary ideal and join them.
+  // If necessary, change the ground field and transform the zero-set
+
+  dbprint(dbPrt, "
+find the zero-set of each primary ideal, form the union
+and keep track of the minimal polynomials ");
+
+  for(i = 1; i <= size(idealList); i = i + 1) {
+    J = idealList[i];
+    idealList[i] = 0;
+    oldMinPoly = mpoly[1];
+    dbprint(dbPrt, " ideal#" + string(i) + " of " + string(size(idealList)) + " = " + string(J));
+    currentSol = zeroSetMainWork(J, w, 0);
+
+    if(oldMinPoly != currentSol[3]) {   // change minpoly and transform solutions
+      dbprint(dbPrt, " change minpoly to " + string(currentSol[3][1]));
+      dbprint(dbPrt, " new representation of algebraic number = " + string(currentSol[2]));
+      if(!noMP) {      // transform the algebraic number a
+        Fa = basering, maxideal(1);
+        Fa[n + 1] = currentSol[2];
+        newA = SimplifyPoly(Fa(newA));  // new representation of a
+        if(size(zeroSet) > 0) {zeroSet = SimplifyZeroset(Fa(zeroSet)); }
+        if(i < size(idealList)) { idealList = SimplifyZeroset(Fa(idealList)); }
+      }
+      else { noMP = 0;}
+    }
+    zeroSet = zeroSet + currentSol[1];    // add new elements
+  }
+  return(list(zeroSet, newA, mpoly));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc zeroSetMainWork(ideal id, intvec wt, int sVars)
+"USAGE:   zeroSetMainWork(I, wt, sVars);
+PURPOSE: compute the zero-set of the zero-dim. ideal I, in a finite extension
+         of the ground field (without multiplicities).
+RETURN:  list, all entries are polynomials
+         _[1] = zeros, each entry is an ideal
+         _[2] = newA; if the ground field is Q(a') this is the rep. of a' w.r.t. a
+         _[3] = minpoly of the algebraic extension of the ground field (ideal)
+         _[4] = name of algebraic number (default = 'a')
+ASSUME:  basering = Q[x_1,x_2,...,x_n,a]
+         ideal mpoly must be defined, it might be 0!
+NOTE:    might change 'mpoly' !!
+EXAMPLE: example IdealSolve; shows an example
+"
+{
+  def altring=basering;
+  int i, j, k, nrSols, n, noMP;
+  ideal I, generators, gens, solid, partsolid;
+  list linSol, linearSolution, nLinSol, nonlinSolutions, partSol, sol, solutions, result;
+  list linIndex, nlinIndex, index;
+  map Fa, Fsubs;
+  poly oldMinPoly, newA;
+
+  if(mpoly[1] == 0) { noMP = 1;}
+  else { noMP = 0;}
+  n = nvars(basering) - 1;
+  newA = var(n + 1);
+
+  I = std(id);
+
+  // find linear solutions of univariate generators
+
+  linSol = LinearZeroSetMain(I, wt);
+  generators = linSol[3];      // they are a standardbasis
+  linIndex = linSol[2];
+  linearSolution = linSol[1];
+  if(size(linIndex) + sVars == n) {    // all variables solved
+    solid = SubsMapIdeal(linearSolution, linIndex, 0);
+    result[1] = list(solid);
+    result[2] = var(n + 1);
+    result[3] = mpoly;
+    return(result);
+  }
+
+  // find roots of the nonlinear univariate polynomials of generators
+  // if necessary, transform linear solutions w.r.t. newA
+
+  oldMinPoly = mpoly[1];
+  nLinSol =  NonLinearZeroSetMain(generators, wt);    // find solutions of univariate generators
+  nonlinSolutions = nLinSol[1];    // store solutions
+  nlinIndex = nLinSol[4];     // and index of solved variables
+  generators = nLinSol[5];    // new generators
+
+  // change minpoly if necessary and transform the ideal and the partial solutions
+
+  if(oldMinPoly != nLinSol[3]) {
+    newA = nLinSol[2];
+    if(!noMP && size(linearSolution) > 0) {    // transform the algebraic number a
+      Fa = basering, maxideal(1);
+      Fa[n + 1] = newA;
+      linearSolution = SimplifyData(Fa(linearSolution));  // ...
+    }
+  }
+
+  // check if all variables are solved.
+
+  if(size(linIndex) + size(nlinIndex) == n - sVars) {
+    solutions = MergeSolutions(linearSolution, linIndex, nonlinSolutions, nlinIndex, list(), n);
+  }
+
+  else {
+
+  // some variables are not solved.
+  // substitute each partial solution in generators and find the
+  // zero set of the resulting ideal by recursive application
+  // of zeroSetMainWork !
+
+  index = linIndex + nlinIndex;
+  nrSols = 0;
+  for(i = 1; i <=  size(nonlinSolutions); i = i + 1) {
+    sol = linearSolution + nonlinSolutions[i];
+    solid = SubsMapIdeal(sol, index, 1);
+    Fsubs = basering, solid;
+    gens = std(SimplifyData(Fsubs(generators)));    // substitute partial solution
+    oldMinPoly = mpoly[1];
+    partSol = zeroSetMainWork(gens, wt, size(index) + sVars);
+
+    if(oldMinPoly != partSol[3]) {    // minpoly has changed
+      Fa = basering, maxideal(1);
+      Fa[n + 1] = partSol[2];    // a -> p(a), representation of a w.r.t. new minpoly
+      newA = reduce(Fa(newA), mpoly);
+      generators = std(SimplifyData(Fa(generators)));
+      if(size(linearSolution) > 0) { linearSolution = SimplifyData(Fa(linearSolution));}
+      if(size(nonlinSolutions) > 0) {
+        nonlinSolutions = SimplifyZeroset(Fa(nonlinSolutions));
+      }
+      sol = linearSolution + nonlinSolutions[i];
+    }
+
+    for(j = 1; j <= size(partSol[1]); j++) {   // for all partial solutions
+      partsolid = partSol[1][j];
+      for(k = 1; k <= size(index); k++) {
+        partsolid[index[k]] = sol[k];
+       }
+      nrSols++;
+      solutions[nrSols] = partsolid;
+    }
+  }
+
+  }  // end else
+  return(list(solutions, newA, mpoly));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc LinearZeroSetMain(ideal I, intvec wt)
+"USAGE:   LinearZeroSetMain(I, wt)
+PURPOSE: solve the univariate linear polys in I
+ASSUME:  basering = Q[x_1,...,x_n,a]
+RETURN:  list
+         _[1] = partial solution of I
+         _[2] = index of solved vars
+         _[3] = new generators (standardbasis)
+"
+{
+  def altring=basering;
+  int i, ok, n, found, nrSols;
+  ideal generators, newGens;
+  list result, index, totalIndex, vars, sol, temp;
+  map F;
+  poly f;
+
+  result[1] = index;      // sol[1] should be the empty list
+  n = nvars(basering) - 1;
+  generators = I;        // might be wrong, use index !
+  ok = 1;
+  nrSols = 0;
+  while(ok) {
+    found = 0;
+    for(i = 1; i <= size(generators); i = i + 1) {
+      f = generators[i];
+      vars = Variables(f, n);
+      if(size(vars) == 1 && deg(f, wt) == 1) {  // univariate,linear
+        nrSols++; found++;
+        index[nrSols] = vars[1];
+        sol[nrSols] = var(vars[1]) - MultPolys(invertNumberMain(LeadTerm(f, vars[1])[3]), f);
+      }
+    }
+    if(found > 0) {
+      F = basering, SubsMapIdeal(sol, index, 1);
+      newGens = std(SimplifyData(F(generators)));    // substitute, simplify alg. number
+      if(size(newGens) == 0) {ok = 0;}
+      generators = newGens;
+    }
+    else {
+      ok = 0;
+    }
+  }
+  if(nrSols > 0) { result[1] = sol;}
+  result[2] = index;
+  result[3] = generators;
+  return(result);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc NonLinearZeroSetMain(ideal I, intvec wt)
+"USAGE:   NonLinearZeroSetMain(I, wt);
+PURPOSE: solves the (nonlinear) univariate polynomials in I
+         of the ground field (without multiplicities).
+RETURN:  list, all entries are polynomials
+         _[1] = list of solutions
+         _[2] = newA
+         _[3] = minpoly
+         _[4] - index of solved variables
+         _[5] = new representation of I
+ASSUME:  basering = Q[x_1,x_2,...,x_n,a], ideal 'mpoly' must be defined,
+         it might be 0 !
+NOTE:    might change 'mpoly' !!
+"
+{
+  int i, nrSols, ok, n;
+  ideal generators;
+  list result, sols, index, vars, partSol;
+  map F;
+  poly f, newA;
+  string ringSTR;
+
+  def NLZR = basering;
+  export(NLZR);
+
+  n = nvars(basering) - 1;
+
+  generators = I;
+  newA = var(n + 1);
+  result[2] = newA;            // default
+  nrSols = 0;
+  ok = 1;
+  i = 1;
+  while(ok) {
+
+    // test if the i-th generator of I is univariate
+
+    f = generators[i];
+    vars = Variables(f, n);
+    if(size(vars) == 1) {
+      generators[i] = 0;
+      generators = simplify(generators, 2);    // remove 0
+      nrSols++;
+      index[nrSols] = vars[1];      // store index of solved variable
+
+      // create univariate ring
+
+      ringSTR = "ring RIS1 = 0, (" + string(var(vars[1])) + ", " + string(var(n+1)) + "), lp;";
+      execute(ringSTR);
+      ideal mpoly = std(imap(NLZR, mpoly));
+      list roots;
+      poly f = imap(NLZR, f);
+      export(RIS1);
+      export(mpoly);
+      roots = rootsMain(f);
+
+      // get "old" basering with new minpoly
+
+      setring(NLZR);
+      partSol = imap(RIS1, roots);
+      kill RIS1;
+      if(mpoly[1] != partSol[3]) {      // change minpoly
+        mpoly = std(partSol[3]);
+        F = NLZR, maxideal(1);
+        F[n + 1] = partSol[2];
+        if(size(sols) > 0) {sols = SimplifyZeroset(F(sols)); }
+        newA = reduce(F(newA), mpoly);    // normal form
+        result[2] = newA;
+        generators = SimplifyData(F(generators));  // does not remove 0's
+      }
+      sols = ExtendSolutions(sols, partSol[1]);
+    } // end univariate
+    else {
+      i = i + 1;
+    }
+    if(i > size(generators)) { ok = 0;}
+  }
+  result[1] = sols;
+  result[3] = mpoly;
+  result[4] = index;
+  result[5] = std(generators);
+
+  kill NLZR;
+  return(result);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static proc ExtendSolutions(list solutions, list newSolutions)
+"USAGE:   ExtendSolutions(sols, newSols); list sols, newSols;
+PURPOSE: extend the entries of 'sols' by the entries of 'newSols',
+         each entry of 'newSols' is a number.
+RETURN:  list
+ASSUME:  basering = Q[x_1,...,x_n,a], ideal 'mpoly' must be defined,
+         it might be 0 !
+NOTE:    used by 'NonLinearZeroSetMain'
+"
+{
+  int i, j, k, n, nrSols;
+  list newSols, temp;
+
+  nrSols = size(solutions);
+  if(nrSols > 0) {n = size(solutions[1]);}
+  else {
+    n = 0;
+    nrSols = 1;
+  }
+  k = 0;
+  for(i = 1; i <= nrSols; i++) {
+    for(j = 1; j <= size(newSolutions); j++) {
+      k++;
+      if(n == 0) { temp[1] = newSolutions[j];}
+      else {
+        temp = solutions[i];
+        temp[n + 1] = newSolutions[j];
+      }
+      newSols[k] = temp;
+    }
+  }
+  return(newSols);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static proc MergeSolutions(list sol1, list index1, list sol2, list index2)
+"USAGE:   MergeSolutions(sol1, index1, sol2, index2); all parameters are lists
+RETURN:  list
+PURPOSE: create a list of solutions of size n, each entry of 'sol2' must
+         have size n. 'sol1' is one partial solution (from 'LinearZeroSetMain')
+         'sol2' is a list of partial solutions (from 'NonLinearZeroSetMain')
+ASSUME:  'sol2' is not empty
+NOTE:    used by 'zeroSetMainWork'
+{
+  int i, j, k, m;
+  ideal sol;
+  list newSols;
+
+  m = 0;
+  for(i = 1; i <= size(sol2); i++) {
+    m++;
+    newSols[m] = SubsMapIdeal(sol1 + sol2[i], index1 + index2, 0);
+  }
+  return(newSols);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static proc SubsMapIdeal(list sol, list index, int opt)
+"USAGE:   SubsMapIdeal(sol,index,opt); list sol, index; int opt;
+PURPOSE: built an ideal I as follows.
+         if i is contained in 'index' then set I[i] = sol[i]
+         if i is not contained in 'index' then
+         - opt = 0: set I[i] = 0
+         - opt = 1: set I[i] = var(i)
+         if opt = 1 and n = nvars(basering) then set I[n] = var(n).
+RETURN:  ideal
+ASSUME:  size(sol) = size(index) <= nvars(basering)
+"
+{
+  int k = 0;
+  ideal I;
+  for(int i = 1; i <= nvars(basering) - 1; i = i + 1) {    // built subs. map
+    if(containedQ(index, i)) {
+      k++;
+      I[index[k]] = sol[k];
+    }
+    else {
+      if(opt) { I[i] = var(i); }
+      else { I[i] = 0; }
+    }
+  }
+  if(opt) {I[nvars(basering)] = var(nvars(basering));}
+  return(I);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc SimplifyZeroset(def data)
+"USAGE:   SimplifyZeroset(data); list data
+PURPOSE: reduce the entries of the elements of 'data' w.r.t. the ideal 'mpoly'
+         'data' is a list of ideals/lists.
+RETURN:  list
+ASSUME:  basering = Q[x_1,...,x_n,a], order = lp
+         'data' is a list of ideals
+         ideal 'mpoly' must be defined, it might be 0 !
+"
+{
+  int i;
+  list result;
+
+  for(i = 1; i <= size(data); i++) {
+    result[i] = SimplifyData(data[i]);
+  }
+  return(result);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc Variables(poly f, int n)
+"USAGE:   Variables(f,n); poly f; int n;
+PURPOSE: list of variables among var(1),...,var(n) which occur in f.
+RETURN:  list
+ASSUME:  n <= nvars(basering)
+"
+{
+  int i, nrV;
+  list index;
+
+  nrV = 0;
+  for(i = 1; i <= n; i = i + 1) {
+    if(diff(f, var(i)) != 0) { nrV++; index[nrV] = i; }
+  }
+  return(index);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+proc containedQ(def data,def f, list #)
+"USAGE:    containedQ(data, f [, opt]); data=list; f=any type; opt=integer
+PURPOSE:  test if f is an element of data.
+RETURN:   int
+          0 if f not contained in data
+          1 if f contained in data
+OPTIONS:  opt = 0 : use '==' for comparing f with elements from data@*
+          opt = 1 : use @code{sameQ} for comparing f with elements from data
+"
+{
+  int opt, i, found;
+  if(size(#) > 0) { opt = #[1];}
+  else { opt = 0; }
+  i = 1;
+  found = 0;
+
+  while((!found) && (i <= size(data))) {
+    if(opt == 0) {
+      if(f == data[i]) { found = 1;}
+      else {i = i + 1;}
+    }
+    else {
+      if(sameQ(f, data[i])) { found = 1;}
+      else {i = i + 1;}
+    }
+  }
+  return(found);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+proc sameQ(def a,def b)
+"USAGE:    sameQ(a, b); a,b=list/intvec
+PURPOSE:  test a == b elementwise, i.e., a[i] = b[i].
+RETURN:   int
+          0 if a != b
+          1 if a == b
+"
+{
+  if(typeof(a) == typeof(b)) {
+    if(typeof(a) == "list" || typeof(a) == "intvec") {
+      if(size(a) == size(b)) {
+        int i = 1;
+        int ok = 1;
+        while(ok && (i <= size(a))) {
+          if(a[i] == b[i]) { i = i + 1;}
+          else {ok = 0;}
+        }
+        return(ok);
+      }
+      else { return(0); }
+    }
+    else { return(a == b);}
+  }
+  else { return(0);}
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static proc SimplifyPoly(poly f)
+"USAGE:   SimplifyPoly(f); poly f
+PURPOSE: reduces the coefficients of f w.r.t. the ideal 'moly' if they contain
+         the algebraic number 'a'.
+RETURN:  poly
+ASSUME:  basering = Q[x_1,...,x_n,a]
+         ideal mpoly must be defined, it might be 0 !
+NOTE: outdated, use reduce instead
+"
+{
+  matrix coMx;
+  poly f1, vp;
+
+  vp = 1;
+  for(int i = 1; i < nvars(basering); i++) { vp = vp * var(i);}
+
+  coMx = coef(f, vp);
+  f1 = 0;
+  for(i = 1; i <= ncols(coMx); i++) {
+    f1 = f1 + coMx[1, i] * reduce(coMx[2, i], mpoly);
+  }
+  return(f1);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static proc SimplifyData(def data)
+"USAGE:   SimplifyData(data); ideal/list data;
+PURPOSE: reduces the entries of 'data' w.r.t. the ideal 'mpoly' if they contain
+         the algebraic number 'a'
+RETURN:  ideal/list
+ASSUME:  basering = Q[x_1,...,x_n,a]
+         ideal 'mpoly' must be defined, it might be 0 !
+"
+{
+  def altring=basering;
+  int n;
+  poly f;
+
+  if(typeof(data) == "ideal") { n = ncols(data); }
+  else { n = size(data);}
+
+  for(int i = 1; i <= n; i++) {
+    f = data[i];
+    data[i] = SimplifyPoly(f);
+  }
+  return(data);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static proc TransferRing(def R)
+"USAGE:   TransferRing(R);
+PURPOSE: creates a new ring containing the same variables as R, but without
+         parameters. If R contains a parameter then this parameter is added
+         as the last variable and 'minpoly' is represented by the ideal 'mpoly'
+         If the basering does not contain a parameter then 'a' is added and
+         'mpoly' = 0.
+RETURN:  ring
+ASSUME:  R = K[x_1,...,x_n] where K = Q or K = Q(a).
+NOTE:    Creates the ring needed for all prodecures with name 'proc-name'Main
+"
+{
+  def altring=basering;
+  string ringSTR, parName, minPoly;
+
+  setring(R);
+
+  if(npars(basering) == 0) {
+    parName = "a";
+    minPoly = "0";
+  }
+  else {
+    parName = parstr(basering);
+    minPoly = string(minpoly);
+  }
+  ringSTR = "ring TR = 0, (" + varstr(basering) + "," + parName + "), lp;";
+
+  execute(ringSTR);
+  execute("ideal mpoly = std(" + minPoly + ");");
+  export(mpoly);
+  setring altring;
+  return(TR);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static proc NewBaseRing()
+"USAGE:   NewBaseRing();
+PURPOSE: creates a new ring, the last variable is added as a parameter.
+         minpoly is set to mpoly[1].
+RETURN:  ring
+ASSUME:  basering = Q[x_1,...,x_n, a], 'mpoly' must be defined
+"
+{
+  int n = nvars(basering);
+  int MP;
+  string ringSTR, parName, varString;
+
+  def BR = basering;
+  if(mpoly[1] != 0) {
+    parName = "(0, " + string(var(n)) + ")";
+    MP = 1;
+  }
+  else {
+    parName = "0";
+    MP = 0;
+  }
+
+
+  for(int i = 1; i < n - 1; i++) {
+    varString = varString + string(var(i)) + ",";
+  }
+  varString = varString + string(var(n-1));
+
+  ringSTR = "ring TR = " + parName + ", (" + varString + "), lp;";
+  execute(ringSTR);
+  if(MP) { minpoly = number(imap(BR, mpoly)[1]); }
+  setring BR;
+  return(TR);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+/*
+                           Examples:
+
+
+// order = 20;
+ring S1 = 0, (s(1..3)), lp;
+ideal I = s(2)*s(3), s(1)^2*s(2)+s(1)^2*s(3)-1, s(1)^2*s(3)^2-s(3), s(2)^4-s(3)^4+s(1)^2, s(1)^4+s(2)^3-s(3)^3, s(3)^5-s(1)^2*s(3);
+ideal mpoly = std(0);
+
+// order = 10
+ring S2 = 0, (s(1..5)), lp;
+ideal I = s(2)+s(3)-s(5), s(4)^2-s(5), s(1)*s(5)+s(3)*s(4)-s(4)*s(5), s(1)*s(4)+s(3)-s(5), s(3)^2-2*s(3)*s(5), s(1)*s(3)-s(1)*s(5)+s(4)*s(5), s(1)^2+s(4)^2-2*s(5), -s(1)+s(5)^3, s(3)*s(5)^2+s(4)-s(5)^3, s(1)*s(5)^2-1;
+ideal mpoly = std(0);
+
+//order = 126
+ring S3 =  0, (s(1..5)), lp;
+ideal I = s(3)*s(4), s(2)*s(4), s(1)*s(3), s(1)*s(2), s(3)^3+s(4)^3-1, s(2)^3+s(4)^3-1, s(1)^3-s(4)^3, s(4)^4-s(4), s(1)*s(4)^3-s(1), s(5)^7-1;
+ideal mpoly = std(0);
+
+// order = 192
+ring S4 = 0, (s(1..4)), lp;
+ideal I = s(2)*s(3)^2*s(4)+s(1)*s(3)*s(4)^2, s(2)^2*s(3)*s(4)+s(1)*s(2)*s(4)^2, s(1)*s(3)^3+s(2)*s(4)^3, s(1)*s(2)*s(3)^2+s(1)^2*s(3)*s(4), s(1)^2*s(3)^2-s(2)^2*s(4)^2, s(1)*s(2)^2*s(3)+s(1)^2*s(2)*s(4), s(1)^3*s(3)+s(2)^3*s(4), s(2)^4-s(3)^4, s(1)*s(2)^3+s(3)*s(4)^3, s(1)^2*s(2)^2-s(3)^2*s(4)^2, s(1)^3*s(2)+s(3)^3*s(4), s(1)^4-s(4)^4, s(3)^5*s(4)-s(3)*s(4)^5, s(3)^8+14*s(3)^4*s(4)^4+s(4)^8-1, 15*s(2)*s(3)*s(4)^7-s(1)*s(4)^8+s(1), 15*s(3)^4*s(4)^5+s(4)^9-s(4), 16*s(3)*s(4)^9-s(3)*s(4), 1 [...]
+ideal mpoly = std(0);
+
+ring R = (0,a), (x,y,z), lp;
+minpoly = a2 + 1;
+ideal I1 = x2 - 1/2, a*z - 1, y - 2;
+ideal I2 = x3 - 1/2, a*z2 - 3, y - 2*a;
+
+*/
diff --git a/Singular/Makefile.am b/Singular/Makefile.am
new file mode 100644
index 0000000..e3ff152
--- /dev/null
+++ b/Singular/Makefile.am
@@ -0,0 +1,276 @@
+ACLOCAL_AMFLAGS = -I../m4
+
+GIT_VERSION := $(shell $(top_srcdir)/git-version-gen $(top_srcdir)/.tarball-git-version)
+
+AM_CPPFLAGS = -I${top_srcdir} -I${top_builddir} -I${top_srcdir}/kernel -I${top_builddir}/kernel -I${top_srcdir}/libpolys -I${top_builddir}/libpolys $(FACTORY_INCLUDES)  $(GMP_CFLAGS) $(NTL_CFLAGS) $(FLINT_CFLAGS) -DGIT_VERSION='"$(GIT_VERSION)"'
+
+SUBDIRS = dyn_modules
+
+########################### Possible builtin modules... #########################
+BUILTIN_FLAGS = ${BUILTIN_LIBS}
+
+########################### libSingular* #########################
+
+libSingular_LTLIBRARIES = libSingular.la
+libSingulardir = $(libdir)
+
+libSingular_la_CPPFLAGS = ${AM_CPPFLAGS} -DLIBSINGULAR ${PTHREAD_CFLAGS}
+
+SOURCES = \
+   links/asciiLink.cc\
+   attrib.cc\
+   blackbox.cc\
+   calcSVD.cc\
+   cntrlc.cc\
+   countedref.cc\
+   denom_list.cc\
+   eigenval_ip.cc\
+   extra.cc\
+   feOpt.cc\
+   fehelp.cc\
+   fevoices.cc\
+   fglm.cc\
+   gms.cc\
+   grammar.cc\
+   iparith.cc\
+   ipassign.cc\
+   ipconv.cc\
+   ipid.cc\
+   iplib.cc\
+   ipprint.cc\
+   ipshell.cc\
+   libparse.cc\
+   linearAlgebra_ip.cc\
+   lists.cc\
+   maps_ip.cc\
+   misc_ip.cc\
+   mod_lib.cc\
+   links/ndbm.cc\
+   newstruct.cc\
+   number2.cc\
+   pcv.cc\
+   links/pipeLink.cc\
+   scanner.cc\
+   sdb.cc\
+   links/silink.cc\
+   links/sing_dbm.cc\
+   links/slInit_Static.cc\
+   links/ssiLink.cc\
+   links/semaphore.c\
+   subexpr.cc\
+   pyobject_setup.cc\
+   walk.cc\
+   walk_ip.cc\
+   wrapper.cc\
+   mmstd.c claptmpl.cc\
+   febase.cc
+
+#   links/slInit_Dynamic.cc
+
+libSingular_la_SOURCES   = $(SOURCES)
+
+SingularHEADERS = \
+   attrib.h \
+   blackbox.h \
+   cntrlc.h \
+   countedref.h \
+   links/dbm_sl.h \
+   distrib.h \
+   eigenval_ip.h \
+   feOpt.h feOptTab.h fehelp.h \
+   fglm.h \
+   gms.h \
+   grammar.h \
+   idrec.h \
+   ipconv.h \
+   ipid.h \
+   ipprint.h \
+   ipshell.h \
+   libparse.h \
+   libsingular.h \
+   linearAlgebra_ip.h\
+   lists.h \
+   locals.h \
+   maps_ip.h \
+   misc_ip.h \
+   mmalloc.h \
+   mod_lib.h \
+   omSingularConfig.h \
+   links/ndbm.h \
+   newstruct.h \
+   number2.h \
+   pcv.h \
+   links/pipeLink.h \
+   pyobject_setup.h \
+   run.h \
+   sdb.h \
+   links/silink.h \
+   links/sing_dbm.h \
+   links/slInit.h \
+   links/ssiLink.h \
+   links/simpleipc.h \
+   stype.h \
+   subexpr.h \
+   table.h \
+   tok.h \
+   walk.h \
+   fevoices.h
+
+
+# -DMAKE_DISTRIBUTION
+
+# plural_cmd.inc
+nodist_libSingular_la_SOURCES = feOpt.inc iparith.inc
+
+libSingular_la_LDFLAGS    =${USEPPROCSDYNAMICLDFLAGS} ${USEPPROCSDYNAMICLD} -release ${PACKAGE_VERSION} ${PTHREAD_LDFLAGS}
+libSingular_la_LIBADD     =${USEPPROCSDYNAMICLDFLAGS} ${USEPPROCSDYNAMICLD} ${BUILTIN_FLAGS} ${top_builddir}/kernel/libkernel.la ${PTHREAD_LIBS}
+
+libSingular_includedir = ${includedir}/singular/Singular
+nobase_libSingular_include_HEADERS = $(SingularHEADERS)
+
+#########################################################
+# handle all the generated *.inc
+
+noinst_PROGRAMS = gentable1 feOptGen feOptES feOptTS
+
+gentable1_SOURCES = gentable.cc grammar.h tok.h table.h
+gentable1_CPPFLAGS = ${AM_CPPFLAGS}
+
+feOptGen_SOURCES = feOptGen.cc feOptGen.h
+feOptGen_CPPFLAGS = ${AM_CPPFLAGS}
+
+feOptES_SOURCES = feOptGen.cc feOptGen.h
+feOptES_CPPFLAGS = ${AM_CPPFLAGS} -DESINGULAR
+
+feOptTS_SOURCES = feOptGen.cc feOptGen.h
+feOptTS_CPPFLAGS = ${AM_CPPFLAGS} -DTSINGULAR
+
+########################### Singular* #########################
+
+EXTRA_PROGRAMS =  libparse Singulard
+
+# the "optional_programs" variable should be defined in the configure
+# script, and listed in an AC_SUBST macro
+optional_Singular_programs =
+
+bin_PROGRAMS = Singular ESingular TSingular $(optional_Singular_programs)
+
+# the following dependency leads to Singular relinking upon a library update!
+Singular ESingular TSingular $(optional_Singular_programs): ${abs_builddir}/LIB
+
+Singular_SOURCES = tesths.cc mmalloc.cc fegetopt.c fegetopt.h utils.cc  utils.h
+
+Singular_LDADD = libSingular.la ${BUILTIN_FLAGS}
+
+Singular_LDFLAGS = -static ${AM_LDFLAGS} ${BUILTIN_FLAGS}
+
+Singulard_SOURCES = tesths.cc mmalloc.cc fegetopt.c fegetopt.h utils.cc  utils.h
+
+Singulard_LDADD = libSingular.la ${BUILTIN_FLAGS}
+
+Singulard_LDFLAGS = -shared ${AM_LDFLAGS} ${BUILTIN_FLAGS}
+
+scriptdir = $(libexecdir)/singular/MOD
+dist_script_SCRIPTS = singularsurf
+
+#### ESingular
+ESingular_CPPFLAGS = ${AM_CPPFLAGS} -DESINGULAR -DPROTO
+# ESingular_LDFLAGS = -static ${AM_LDFLAGS}
+ESingular_LDADD =  ${top_builddir}/libpolys/reporter/libreporter.la \
+${top_builddir}/libpolys/misc/libmisc.la ${top_builddir}/omalloc/libomalloc.la \
+${top_builddir}/resources/libresources.la
+
+
+ESingular_SOURCES = emacs.cc fegetopt.c fegetopt.h feOptES.inc feOpt.cc
+
+#### same for TSingular
+TSingular_CPPFLAGS = ${AM_CPPFLAGS} -DTSINGULAR -DPROTO
+# TSingular_LDFLAGS = -static ${AM_LDFLAGS}
+TSingular_LDADD = ${top_builddir}/libpolys/reporter/libreporter.la \
+${top_builddir}/libpolys/misc/libmisc.la ${top_builddir}/omalloc/libomalloc.la \
+${top_builddir}/resources/libresources.la
+
+TSingular_SOURCES = emacs.cc fegetopt.c fegetopt.h feOptTS.inc feOpt.cc
+# utils.cc utils.h
+
+
+#### libparse
+libparse_CPPFLAGS = ${AM_CPPFLAGS} -DSTANDALONE_PARSER
+
+libparse_SOURCES = libparse.cc fegetopt.c fegetopt.h utils.cc  utils.h
+
+libparse_LDADD = ${top_builddir}/omalloc/libomalloc.la
+libparse_LDFLAGS = -static ${AM_LDFLAGS}
+
+#########################################################
+# the Singular library (*.lib files)
+
+include ${srcdir}/singular-libs
+
+singularlibrarydir = ${datadir}/singular
+singularlibrary = $(SLIB0:%=LIB/%) $(SLIB1:%=LIB/%) $(PLIBS:%=LIB/%)
+nobase_dist_singularlibrary_DATA = LIB/tst.lib LIB/help.cnf ${singularlibrary}
+EXTRA_DIST = make_alllib.sh LIB/all.lib.tmpl singular-libs \
+             LIB/help.cnf links/slInit_Dynamic.cc
+
+singularalllibrarydir = ${datadir}/singular/LIB
+singularalllibrary = all.lib
+nobase_dist_singularalllibrary_DATA = all.lib
+
+all.lib: ${srcdir}/make_alllib.sh ${srcdir}/LIB/all.lib.tmpl ${singularlibrary}
+	${srcdir}/make_alllib.sh ${srcdir}/LIB/all.lib.tmpl ${SLIB0} ${PLIBS}
+
+########################### TEST #########################
+TESTS_ENVIRONMENT = SINGULARPATH='${top_builddir}/Singular/LIB:${top_srcdir}/Singular/LIB:${top_builddir}/libpolys/polys/.libs:${top_builddir}/factory/gftables'
+TESTS_ENVIRONMENT += SINGULAR_ROOT_DIR='${top_builddir}'
+
+TESTS=test
+
+check_PROGRAMS=$(TESTS)
+
+test_SOURCES = test.cc
+test_LDADD = libSingular.la
+
+#########################################################
+### plural_cmd.inc
+# These files are built first
+BUILT_SOURCES = feOpt.inc feOptTS.inc feOptES.inc iparith.inc all.lib gftables MOD
+
+CLEANFILES = $(BUILT_SOURCES) $(EXTRA_PROGRAMS)
+
+clean-local:
+	if [ "${abs_builddir}" != "${abs_srcdir}" ]; then \
+	  if [ -L ${abs_builddir}/LIB ]; then unlink ${abs_builddir}/LIB; fi \
+	fi
+
+feOpt.inc: feOptGen$(EXEEXT)
+	${builddir}/feOptGen$(EXEEXT)
+
+feOptES.inc: feOptES$(EXEEXT)
+	${builddir}/feOptES$(EXEEXT)
+
+feOptTS.inc: feOptTS$(EXEEXT)
+	${builddir}/feOptTS$(EXEEXT)
+
+# plural_cmd.inc is only necessary for documentation generation
+#plural_cmd.inc: gentable1$(EXEEXT)
+#	${builddir}/gentable1$(EXEEXT) argument
+
+iparith.inc: gentable1$(EXEEXT) table.h
+	${builddir}/gentable1$(EXEEXT)
+
+# # fake rule to fix parallel make http://www.gnu.org/s/hello/manual/automake/Multiple-Outputs.html
+
+gftables: ${top_srcdir}/factory/gftables
+	ln -snf ${top_srcdir}/factory/gftables ${builddir}/gftables
+
+${abs_builddir}/LIB: ${srcdir}/LIB
+	if [ "${abs_builddir}" != "${abs_srcdir}" ]; then \
+	  ln -snf ${abs_srcdir}/LIB ${abs_builddir}/; \
+	fi
+
+MOD:
+	if [ -d "${top_builddir}/libpolys/polys/.libs" ]; then \
+	  ln -snf ${top_builddir}/libpolys/polys/.libs/ ${abs_builddir}/MOD; \
+	fi
+
diff --git a/Singular/Makefile.in b/Singular/Makefile.in
new file mode 100644
index 0000000..25d407d
--- /dev/null
+++ b/Singular/Makefile.in
@@ -0,0 +1,2402 @@
+# Makefile.in generated by automake 1.13.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 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@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+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 = gentable1$(EXEEXT) feOptGen$(EXEEXT) \
+	feOptES$(EXEEXT) feOptTS$(EXEEXT)
+EXTRA_PROGRAMS = libparse$(EXEEXT) Singulard$(EXEEXT)
+bin_PROGRAMS = Singular$(EXEEXT) ESingular$(EXEEXT) TSingular$(EXEEXT) \
+	$(am__EXEEXT_1)
+TESTS = test$(EXEEXT)
+check_PROGRAMS = $(am__EXEEXT_2)
+subdir = Singular
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(dist_script_SCRIPTS) $(top_srcdir)/build-aux/depcomp \
+	$(nobase_dist_singularalllibrary_DATA) \
+	$(nobase_dist_singularlibrary_DATA) \
+	$(nobase_libSingular_include_HEADERS) \
+	$(top_srcdir)/build-aux/test-driver COPYING ChangeLog README \
+	mkinstalldirs
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_append_compile_flags.m4 \
+	$(top_srcdir)/m4/ax_append_flag.m4 \
+	$(top_srcdir)/m4/ax_append_link_flags.m4 \
+	$(top_srcdir)/m4/ax_check_compile_flag.m4 \
+	$(top_srcdir)/m4/ax_check_link_flag.m4 \
+	$(top_srcdir)/m4/ax_compute_relative_paths.m4 \
+	$(top_srcdir)/m4/ax_normalize_path.m4 \
+	$(top_srcdir)/m4/ax_prefix_config_h.m4 \
+	$(top_srcdir)/m4/ax_pthread.m4 \
+	$(top_srcdir)/m4/ax_python_embed.m4 \
+	$(top_srcdir)/m4/ax_python_with_version.m4 \
+	$(top_srcdir)/m4/cpu-check.m4 $(top_srcdir)/m4/dbm-check.m4 \
+	$(top_srcdir)/m4/flags.m4 $(top_srcdir)/m4/flint-check.m4 \
+	$(top_srcdir)/m4/gfanlib-check.m4 \
+	$(top_srcdir)/m4/gmp-check.m4 \
+	$(top_srcdir)/m4/google-perftools.m4 \
+	$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+	$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+	$(top_srcdir)/m4/lt~obsolete.m4 \
+	$(top_srcdir)/m4/mathic-check.m4 $(top_srcdir)/m4/ntl-check.m4 \
+	$(top_srcdir)/m4/options.m4 $(top_srcdir)/m4/p-procs.m4 \
+	$(top_srcdir)/m4/polymake-check.m4 \
+	$(top_srcdir)/m4/readline-check.m4 $(top_srcdir)/configure.ac
+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__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
+am__installdirs = "$(DESTDIR)$(libSingulardir)" "$(DESTDIR)$(bindir)" \
+	"$(DESTDIR)$(scriptdir)" "$(DESTDIR)$(singularalllibrarydir)" \
+	"$(DESTDIR)$(singularlibrarydir)" \
+	"$(DESTDIR)$(libSingular_includedir)"
+LTLIBRARIES = $(libSingular_LTLIBRARIES)
+am__DEPENDENCIES_1 =
+am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1)
+libSingular_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \
+	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) \
+	${top_builddir}/kernel/libkernel.la $(am__DEPENDENCIES_1)
+am__dirstamp = $(am__leading_dot)dirstamp
+am__objects_1 = links/libSingular_la-asciiLink.lo \
+	libSingular_la-attrib.lo libSingular_la-blackbox.lo \
+	libSingular_la-calcSVD.lo libSingular_la-cntrlc.lo \
+	libSingular_la-countedref.lo libSingular_la-denom_list.lo \
+	libSingular_la-eigenval_ip.lo libSingular_la-extra.lo \
+	libSingular_la-feOpt.lo libSingular_la-fehelp.lo \
+	libSingular_la-fevoices.lo libSingular_la-fglm.lo \
+	libSingular_la-gms.lo libSingular_la-grammar.lo \
+	libSingular_la-iparith.lo libSingular_la-ipassign.lo \
+	libSingular_la-ipconv.lo libSingular_la-ipid.lo \
+	libSingular_la-iplib.lo libSingular_la-ipprint.lo \
+	libSingular_la-ipshell.lo libSingular_la-libparse.lo \
+	libSingular_la-linearAlgebra_ip.lo libSingular_la-lists.lo \
+	libSingular_la-maps_ip.lo libSingular_la-misc_ip.lo \
+	libSingular_la-mod_lib.lo links/libSingular_la-ndbm.lo \
+	libSingular_la-newstruct.lo libSingular_la-number2.lo \
+	libSingular_la-pcv.lo links/libSingular_la-pipeLink.lo \
+	libSingular_la-scanner.lo libSingular_la-sdb.lo \
+	links/libSingular_la-silink.lo \
+	links/libSingular_la-sing_dbm.lo \
+	links/libSingular_la-slInit_Static.lo \
+	links/libSingular_la-ssiLink.lo \
+	links/libSingular_la-semaphore.lo libSingular_la-subexpr.lo \
+	libSingular_la-pyobject_setup.lo libSingular_la-walk.lo \
+	libSingular_la-walk_ip.lo libSingular_la-wrapper.lo \
+	libSingular_la-mmstd.lo libSingular_la-claptmpl.lo \
+	libSingular_la-febase.lo
+am_libSingular_la_OBJECTS = $(am__objects_1)
+nodist_libSingular_la_OBJECTS =
+libSingular_la_OBJECTS = $(am_libSingular_la_OBJECTS) \
+	$(nodist_libSingular_la_OBJECTS)
+AM_V_lt = $(am__v_lt_ at AM_V@)
+am__v_lt_ = $(am__v_lt_ at AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 = 
+libSingular_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
+	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
+	$(AM_CXXFLAGS) $(CXXFLAGS) $(libSingular_la_LDFLAGS) \
+	$(LDFLAGS) -o $@
+am__EXEEXT_1 =
+am__EXEEXT_2 = test$(EXEEXT)
+PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS)
+am_ESingular_OBJECTS = ESingular-emacs.$(OBJEXT) \
+	ESingular-fegetopt.$(OBJEXT) ESingular-feOpt.$(OBJEXT)
+ESingular_OBJECTS = $(am_ESingular_OBJECTS)
+ESingular_DEPENDENCIES =  \
+	${top_builddir}/libpolys/reporter/libreporter.la \
+	${top_builddir}/libpolys/misc/libmisc.la \
+	${top_builddir}/omalloc/libomalloc.la \
+	${top_builddir}/resources/libresources.la
+am_Singular_OBJECTS = tesths.$(OBJEXT) mmalloc.$(OBJEXT) \
+	fegetopt.$(OBJEXT) utils.$(OBJEXT)
+Singular_OBJECTS = $(am_Singular_OBJECTS)
+Singular_DEPENDENCIES = libSingular.la $(am__DEPENDENCIES_2)
+Singular_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+	$(CXXFLAGS) $(Singular_LDFLAGS) $(LDFLAGS) -o $@
+am_Singulard_OBJECTS = tesths.$(OBJEXT) mmalloc.$(OBJEXT) \
+	fegetopt.$(OBJEXT) utils.$(OBJEXT)
+Singulard_OBJECTS = $(am_Singulard_OBJECTS)
+Singulard_DEPENDENCIES = libSingular.la $(am__DEPENDENCIES_2)
+Singulard_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+	$(CXXFLAGS) $(Singulard_LDFLAGS) $(LDFLAGS) -o $@
+am_TSingular_OBJECTS = TSingular-emacs.$(OBJEXT) \
+	TSingular-fegetopt.$(OBJEXT) TSingular-feOpt.$(OBJEXT)
+TSingular_OBJECTS = $(am_TSingular_OBJECTS)
+TSingular_DEPENDENCIES =  \
+	${top_builddir}/libpolys/reporter/libreporter.la \
+	${top_builddir}/libpolys/misc/libmisc.la \
+	${top_builddir}/omalloc/libomalloc.la \
+	${top_builddir}/resources/libresources.la
+am_feOptES_OBJECTS = feOptES-feOptGen.$(OBJEXT)
+feOptES_OBJECTS = $(am_feOptES_OBJECTS)
+feOptES_LDADD = $(LDADD)
+am_feOptGen_OBJECTS = feOptGen-feOptGen.$(OBJEXT)
+feOptGen_OBJECTS = $(am_feOptGen_OBJECTS)
+feOptGen_LDADD = $(LDADD)
+am_feOptTS_OBJECTS = feOptTS-feOptGen.$(OBJEXT)
+feOptTS_OBJECTS = $(am_feOptTS_OBJECTS)
+feOptTS_LDADD = $(LDADD)
+am_gentable1_OBJECTS = gentable1-gentable.$(OBJEXT)
+gentable1_OBJECTS = $(am_gentable1_OBJECTS)
+gentable1_LDADD = $(LDADD)
+am_libparse_OBJECTS = libparse-libparse.$(OBJEXT) \
+	libparse-fegetopt.$(OBJEXT) libparse-utils.$(OBJEXT)
+libparse_OBJECTS = $(am_libparse_OBJECTS)
+libparse_DEPENDENCIES = ${top_builddir}/omalloc/libomalloc.la
+libparse_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+	$(CXXFLAGS) $(libparse_LDFLAGS) $(LDFLAGS) -o $@
+am_test_OBJECTS = test.$(OBJEXT)
+test_OBJECTS = $(am_test_OBJECTS)
+test_DEPENDENCIES = libSingular.la
+SCRIPTS = $(dist_script_SCRIPTS)
+AM_V_P = $(am__v_P_ at AM_V@)
+am__v_P_ = $(am__v_P_ at AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_ at AM_V@)
+am__v_GEN_ = $(am__v_GEN_ at AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_ at AM_V@)
+am__v_at_ = $(am__v_at_ at AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+DEFAULT_INCLUDES = -I. at am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+	$(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_ at AM_V@)
+am__v_CC_ = $(am__v_CC_ at AM_DEFAULT_V@)
+am__v_CC_0 = @echo "  CC      " $@;
+am__v_CC_1 = 
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+	$(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_ at AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_ at AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo "  CCLD    " $@;
+am__v_CCLD_1 = 
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \
+	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+	$(AM_CXXFLAGS) $(CXXFLAGS)
+AM_V_CXX = $(am__v_CXX_ at AM_V@)
+am__v_CXX_ = $(am__v_CXX_ at AM_DEFAULT_V@)
+am__v_CXX_0 = @echo "  CXX     " $@;
+am__v_CXX_1 = 
+CXXLD = $(CXX)
+CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+	$(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CXXLD = $(am__v_CXXLD_ at AM_V@)
+am__v_CXXLD_ = $(am__v_CXXLD_ at AM_DEFAULT_V@)
+am__v_CXXLD_0 = @echo "  CXXLD   " $@;
+am__v_CXXLD_1 = 
+DIST_SOURCES = $(libSingular_la_SOURCES) $(ESingular_SOURCES) \
+	$(Singular_SOURCES) $(Singulard_SOURCES) $(TSingular_SOURCES) \
+	$(feOptES_SOURCES) $(feOptGen_SOURCES) $(feOptTS_SOURCES) \
+	$(gentable1_SOURCES) $(libparse_SOURCES) $(test_SOURCES)
+RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
+	ctags-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 \
+	tags-recursive uninstall-recursive
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+DATA = $(nobase_dist_singularalllibrary_DATA) \
+	$(nobase_dist_singularlibrary_DATA)
+HEADERS = $(nobase_libSingular_include_HEADERS)
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive	\
+  distclean-recursive maintainer-clean-recursive
+am__recursive_targets = \
+  $(RECURSIVE_TARGETS) \
+  $(RECURSIVE_CLEAN_TARGETS) \
+  $(am__extra_recursive_targets)
+AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
+	check recheck distdir
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors_dummy = \
+  mgn= red= grn= lgn= blu= brg= std=; \
+  am__color_tests=no
+am__tty_colors = { \
+  $(am__tty_colors_dummy); \
+  if test "X$(AM_COLOR_TESTS)" = Xno; then \
+    am__color_tests=no; \
+  elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+    am__color_tests=yes; \
+  elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+    am__color_tests=yes; \
+  fi; \
+  if test $$am__color_tests = yes; then \
+    red=''; \
+    grn=''; \
+    lgn=''; \
+    blu=''; \
+    mgn=''; \
+    brg=''; \
+    std=''; \
+  fi; \
+}
+am__recheck_rx = ^[ 	]*:recheck:[ 	]*
+am__global_test_result_rx = ^[ 	]*:global-test-result:[ 	]*
+am__copy_in_global_log_rx = ^[ 	]*:copy-in-global-log:[ 	]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+  recheck = 1; \
+  while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+    { \
+      if (rc < 0) \
+        { \
+          if ((getline line2 < ($$0 ".log")) < 0) \
+	    recheck = 0; \
+          break; \
+        } \
+      else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+        { \
+          recheck = 0; \
+          break; \
+        } \
+      else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+        { \
+          break; \
+        } \
+    }; \
+  if (recheck) \
+    print $$0; \
+  close ($$0 ".trs"); \
+  close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+  print "fatal: making $@: " msg | "cat >&2"; \
+  exit 1; \
+} \
+function rst_section(header) \
+{ \
+  print header; \
+  len = length(header); \
+  for (i = 1; i <= len; i = i + 1) \
+    printf "="; \
+  printf "\n\n"; \
+} \
+{ \
+  copy_in_global_log = 1; \
+  global_test_result = "RUN"; \
+  while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+    { \
+      if (rc < 0) \
+         fatal("failed to read from " $$0 ".trs"); \
+      if (line ~ /$(am__global_test_result_rx)/) \
+        { \
+          sub("$(am__global_test_result_rx)", "", line); \
+          sub("[ 	]*$$", "", line); \
+          global_test_result = line; \
+        } \
+      else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+        copy_in_global_log = 0; \
+    }; \
+  if (copy_in_global_log) \
+    { \
+      rst_section(global_test_result ": " $$0); \
+      while ((rc = (getline line < ($$0 ".log"))) != 0) \
+      { \
+        if (rc < 0) \
+          fatal("failed to read from " $$0 ".log"); \
+        print line; \
+      }; \
+      printf "\n"; \
+    }; \
+  close ($$0 ".trs"); \
+  close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/   &   /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this.  Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+  --color-tests "$$am__color_tests" \
+  --enable-hard-errors "$$am__enable_hard_errors" \
+  --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test.  Creates the
+# directory for the log if needed.  Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log.  Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT.  Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup);					\
+$(am__vpath_adj_setup) $(am__vpath_adj)			\
+$(am__tty_colors);					\
+srcdir=$(srcdir); export srcdir;			\
+case "$@" in						\
+  */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;;	\
+    *) am__odir=.;; 					\
+esac;							\
+test "x$$am__odir" = x"." || test -d "$$am__odir" 	\
+  || $(MKDIR_P) "$$am__odir" || exit $$?;		\
+if test -f "./$$f"; then dir=./;			\
+elif test -f "$$f"; then dir=;				\
+else dir="$(srcdir)/"; fi;				\
+tst=$$dir$$f; log='$@'; 				\
+if test -n '$(DISABLE_HARD_ERRORS)'; then		\
+  am__enable_hard_errors=no; 				\
+else							\
+  am__enable_hard_errors=yes; 				\
+fi; 							\
+case " $(XFAIL_TESTS) " in				\
+  *[\ \	]$$f[\ \	]* | *[\ \	]$$dir$$f[\ \	]*) \
+    am__expect_failure=yes;;				\
+  *)							\
+    am__expect_failure=no;;				\
+esac; 							\
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed).  The result is saved in the shell variable
+# '$bases'.  This honors runtime overriding of TESTS and TEST_LOGS.  Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+  bases='$(TEST_LOGS)'; \
+  bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+  bases=`echo $$bases`
+RECHECK_LOGS = $(TEST_LOGS)
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+  case '$@' in \
+    */*) \
+      case '$*' in \
+        */*) b='$*';; \
+          *) b=`echo '$@' | sed 's/\.log$$//'`; \
+       esac;; \
+    *) \
+      b='$*';; \
+  esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT at .log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+	$(TEST_LOG_FLAGS)
+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@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BUILTIN_LIBS = @BUILTIN_LIBS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CDDGMPCPPFLAGS = @CDDGMPCPPFLAGS@
+CDDGMPLDFLAGS = @CDDGMPLDFLAGS@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATA_DIR = @DATA_DIR@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DOC_DIR = @DOC_DIR@
+DOXYGEN = @DOXYGEN@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FACTORY_INCLUDES = @FACTORY_INCLUDES@
+FACTORY_LIBS = @FACTORY_LIBS@
+FGREP = @FGREP@
+FLINT_CFLAGS = @FLINT_CFLAGS@
+FLINT_HOME = @FLINT_HOME@
+FLINT_LIBS = @FLINT_LIBS@
+GMP_CFLAGS = @GMP_CFLAGS@
+GMP_HOME = @GMP_HOME@
+GMP_LIBS = @GMP_LIBS@
+GMP_VERSION = @GMP_VERSION@
+GREP = @GREP@
+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@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NTL_CFLAGS = @NTL_CFLAGS@
+NTL_LIBS = @NTL_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OMALLOC_INCLUDES = @OMALLOC_INCLUDES@
+OMALLOC_LIBS = @OMALLOC_LIBS@
+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@
+PKG_REQUIRE = @PKG_REQUIRE@
+PMCONFIG = @PMCONFIG@
+PM_CFLAGS = @PM_CFLAGS@
+PM_INC = @PM_INC@
+PM_LDFLAGS = @PM_LDFLAGS@
+PM_LIBS = @PM_LIBS@
+POLYMAKE_CXXFLAGS = @POLYMAKE_CXXFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LDFLAGS = @PTHREAD_LDFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
+PYTHON = @PYTHON@
+PYTHON_CSPEC = @PYTHON_CSPEC@
+PYTHON_EXECPREFIX = @PYTHON_EXECPREFIX@
+PYTHON_LSPEC = @PYTHON_LSPEC@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+RANLIB = @RANLIB@
+RESOURCES_INCLUDES = @RESOURCES_INCLUDES@
+RESOURCES_LIBS = @RESOURCES_LIBS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SINGULAR_CFLAGS = @SINGULAR_CFLAGS@
+SI_COUNTEDREF_AUTOLOAD = @SI_COUNTEDREF_AUTOLOAD@
+SI_CPU_I386 = @SI_CPU_I386@
+SI_CPU_IA64 = @SI_CPU_IA64@
+SI_CPU_PPC = @SI_CPU_PPC@
+SI_CPU_SPARC = @SI_CPU_SPARC@
+SI_CPU_X86_64 = @SI_CPU_X86_64@
+STRIP = @STRIP@
+USEPPROCSDYNAMICLD = @USEPPROCSDYNAMICLD@
+USEPPROCSDYNAMICLDFLAGS = @USEPPROCSDYNAMICLDFLAGS@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
+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@
+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@
+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@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+ACLOCAL_AMFLAGS = -I../m4
+GIT_VERSION := $(shell $(top_srcdir)/git-version-gen $(top_srcdir)/.tarball-git-version)
+AM_CPPFLAGS = -I${top_srcdir} -I${top_builddir} -I${top_srcdir}/kernel -I${top_builddir}/kernel -I${top_srcdir}/libpolys -I${top_builddir}/libpolys $(FACTORY_INCLUDES)  $(GMP_CFLAGS) $(NTL_CFLAGS) $(FLINT_CFLAGS) -DGIT_VERSION='"$(GIT_VERSION)"'
+SUBDIRS = dyn_modules
+
+########################### Possible builtin modules... #########################
+BUILTIN_FLAGS = ${BUILTIN_LIBS}
+
+########################### libSingular* #########################
+libSingular_LTLIBRARIES = libSingular.la
+libSingulardir = $(libdir)
+libSingular_la_CPPFLAGS = ${AM_CPPFLAGS} -DLIBSINGULAR ${PTHREAD_CFLAGS}
+SOURCES = \
+   links/asciiLink.cc\
+   attrib.cc\
+   blackbox.cc\
+   calcSVD.cc\
+   cntrlc.cc\
+   countedref.cc\
+   denom_list.cc\
+   eigenval_ip.cc\
+   extra.cc\
+   feOpt.cc\
+   fehelp.cc\
+   fevoices.cc\
+   fglm.cc\
+   gms.cc\
+   grammar.cc\
+   iparith.cc\
+   ipassign.cc\
+   ipconv.cc\
+   ipid.cc\
+   iplib.cc\
+   ipprint.cc\
+   ipshell.cc\
+   libparse.cc\
+   linearAlgebra_ip.cc\
+   lists.cc\
+   maps_ip.cc\
+   misc_ip.cc\
+   mod_lib.cc\
+   links/ndbm.cc\
+   newstruct.cc\
+   number2.cc\
+   pcv.cc\
+   links/pipeLink.cc\
+   scanner.cc\
+   sdb.cc\
+   links/silink.cc\
+   links/sing_dbm.cc\
+   links/slInit_Static.cc\
+   links/ssiLink.cc\
+   links/semaphore.c\
+   subexpr.cc\
+   pyobject_setup.cc\
+   walk.cc\
+   walk_ip.cc\
+   wrapper.cc\
+   mmstd.c claptmpl.cc\
+   febase.cc
+
+
+#   links/slInit_Dynamic.cc
+libSingular_la_SOURCES = $(SOURCES)
+SingularHEADERS = \
+   attrib.h \
+   blackbox.h \
+   cntrlc.h \
+   countedref.h \
+   links/dbm_sl.h \
+   distrib.h \
+   eigenval_ip.h \
+   feOpt.h feOptTab.h fehelp.h \
+   fglm.h \
+   gms.h \
+   grammar.h \
+   idrec.h \
+   ipconv.h \
+   ipid.h \
+   ipprint.h \
+   ipshell.h \
+   libparse.h \
+   libsingular.h \
+   linearAlgebra_ip.h\
+   lists.h \
+   locals.h \
+   maps_ip.h \
+   misc_ip.h \
+   mmalloc.h \
+   mod_lib.h \
+   omSingularConfig.h \
+   links/ndbm.h \
+   newstruct.h \
+   number2.h \
+   pcv.h \
+   links/pipeLink.h \
+   pyobject_setup.h \
+   run.h \
+   sdb.h \
+   links/silink.h \
+   links/sing_dbm.h \
+   links/slInit.h \
+   links/ssiLink.h \
+   links/simpleipc.h \
+   stype.h \
+   subexpr.h \
+   table.h \
+   tok.h \
+   walk.h \
+   fevoices.h
+
+
+# -DMAKE_DISTRIBUTION
+
+# plural_cmd.inc
+nodist_libSingular_la_SOURCES = feOpt.inc iparith.inc
+libSingular_la_LDFLAGS = ${USEPPROCSDYNAMICLDFLAGS} ${USEPPROCSDYNAMICLD} -release ${PACKAGE_VERSION} ${PTHREAD_LDFLAGS}
+libSingular_la_LIBADD = ${USEPPROCSDYNAMICLDFLAGS} ${USEPPROCSDYNAMICLD} ${BUILTIN_FLAGS} ${top_builddir}/kernel/libkernel.la ${PTHREAD_LIBS}
+libSingular_includedir = ${includedir}/singular/Singular
+nobase_libSingular_include_HEADERS = $(SingularHEADERS)
+gentable1_SOURCES = gentable.cc grammar.h tok.h table.h
+gentable1_CPPFLAGS = ${AM_CPPFLAGS}
+feOptGen_SOURCES = feOptGen.cc feOptGen.h
+feOptGen_CPPFLAGS = ${AM_CPPFLAGS}
+feOptES_SOURCES = feOptGen.cc feOptGen.h
+feOptES_CPPFLAGS = ${AM_CPPFLAGS} -DESINGULAR
+feOptTS_SOURCES = feOptGen.cc feOptGen.h
+feOptTS_CPPFLAGS = ${AM_CPPFLAGS} -DTSINGULAR
+
+# the "optional_programs" variable should be defined in the configure
+# script, and listed in an AC_SUBST macro
+optional_Singular_programs = 
+Singular_SOURCES = tesths.cc mmalloc.cc fegetopt.c fegetopt.h utils.cc  utils.h
+Singular_LDADD = libSingular.la ${BUILTIN_FLAGS}
+Singular_LDFLAGS = -static ${AM_LDFLAGS} ${BUILTIN_FLAGS}
+Singulard_SOURCES = tesths.cc mmalloc.cc fegetopt.c fegetopt.h utils.cc  utils.h
+Singulard_LDADD = libSingular.la ${BUILTIN_FLAGS}
+Singulard_LDFLAGS = -shared ${AM_LDFLAGS} ${BUILTIN_FLAGS}
+scriptdir = $(libexecdir)/singular/MOD
+dist_script_SCRIPTS = singularsurf
+
+#### ESingular
+ESingular_CPPFLAGS = ${AM_CPPFLAGS} -DESINGULAR -DPROTO
+# ESingular_LDFLAGS = -static ${AM_LDFLAGS}
+ESingular_LDADD = ${top_builddir}/libpolys/reporter/libreporter.la \
+${top_builddir}/libpolys/misc/libmisc.la ${top_builddir}/omalloc/libomalloc.la \
+${top_builddir}/resources/libresources.la
+
+ESingular_SOURCES = emacs.cc fegetopt.c fegetopt.h feOptES.inc feOpt.cc
+
+#### same for TSingular
+TSingular_CPPFLAGS = ${AM_CPPFLAGS} -DTSINGULAR -DPROTO
+# TSingular_LDFLAGS = -static ${AM_LDFLAGS}
+TSingular_LDADD = ${top_builddir}/libpolys/reporter/libreporter.la \
+${top_builddir}/libpolys/misc/libmisc.la ${top_builddir}/omalloc/libomalloc.la \
+${top_builddir}/resources/libresources.la
+
+TSingular_SOURCES = emacs.cc fegetopt.c fegetopt.h feOptTS.inc feOpt.cc
+# utils.cc utils.h
+
+#### libparse
+libparse_CPPFLAGS = ${AM_CPPFLAGS} -DSTANDALONE_PARSER
+libparse_SOURCES = libparse.cc fegetopt.c fegetopt.h utils.cc  utils.h
+libparse_LDADD = ${top_builddir}/omalloc/libomalloc.la
+libparse_LDFLAGS = -static ${AM_LDFLAGS}
+singularlibrarydir = ${datadir}/singular
+singularlibrary = $(SLIB0:%=LIB/%) $(SLIB1:%=LIB/%) $(PLIBS:%=LIB/%)
+nobase_dist_singularlibrary_DATA = LIB/tst.lib LIB/help.cnf ${singularlibrary}
+EXTRA_DIST = make_alllib.sh LIB/all.lib.tmpl singular-libs \
+             LIB/help.cnf links/slInit_Dynamic.cc
+
+singularalllibrarydir = ${datadir}/singular/LIB
+singularalllibrary = all.lib
+nobase_dist_singularalllibrary_DATA = all.lib
+
+########################### TEST #########################
+TESTS_ENVIRONMENT = SINGULARPATH='${top_builddir}/Singular/LIB:${top_srcdir}/Singular/LIB:${top_builddir}/libpolys/polys/.libs:${top_builddir}/factory/gftables' \
+	SINGULAR_ROOT_DIR='${top_builddir}'
+test_SOURCES = test.cc
+test_LDADD = libSingular.la
+
+#########################################################
+### plural_cmd.inc
+# These files are built first
+BUILT_SOURCES = feOpt.inc feOptTS.inc feOptES.inc iparith.inc all.lib gftables MOD
+CLEANFILES = $(BUILT_SOURCES) $(EXTRA_PROGRAMS)
+all: $(BUILT_SOURCES)
+	$(MAKE) $(AM_MAKEFLAGS) all-recursive
+
+.SUFFIXES:
+.SUFFIXES: .c .cc .lo .log .o .obj .test .test$(EXEEXT) .trs
+$(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) --foreign Singular/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign Singular/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-libSingularLTLIBRARIES: $(libSingular_LTLIBRARIES)
+	@$(NORMAL_INSTALL)
+	@list='$(libSingular_LTLIBRARIES)'; test -n "$(libSingulardir)" || list=; \
+	list2=; for p in $$list; do \
+	  if test -f $$p; then \
+	    list2="$$list2 $$p"; \
+	  else :; fi; \
+	done; \
+	test -z "$$list2" || { \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(libSingulardir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(libSingulardir)" || exit 1; \
+	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libSingulardir)'"; \
+	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libSingulardir)"; \
+	}
+
+uninstall-libSingularLTLIBRARIES:
+	@$(NORMAL_UNINSTALL)
+	@list='$(libSingular_LTLIBRARIES)'; test -n "$(libSingulardir)" || list=; \
+	for p in $$list; do \
+	  $(am__strip_dir) \
+	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libSingulardir)/$$f'"; \
+	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libSingulardir)/$$f"; \
+	done
+
+clean-libSingularLTLIBRARIES:
+	-test -z "$(libSingular_LTLIBRARIES)" || rm -f $(libSingular_LTLIBRARIES)
+	@list='$(libSingular_LTLIBRARIES)'; \
+	locs=`for p in $$list; do echo $$p; done | \
+	      sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+	      sort -u`; \
+	test -z "$$locs" || { \
+	  echo rm -f $${locs}; \
+	  rm -f $${locs}; \
+	}
+links/$(am__dirstamp):
+	@$(MKDIR_P) links
+	@: > links/$(am__dirstamp)
+links/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) links/$(DEPDIR)
+	@: > links/$(DEPDIR)/$(am__dirstamp)
+links/libSingular_la-asciiLink.lo: links/$(am__dirstamp) \
+	links/$(DEPDIR)/$(am__dirstamp)
+links/libSingular_la-ndbm.lo: links/$(am__dirstamp) \
+	links/$(DEPDIR)/$(am__dirstamp)
+links/libSingular_la-pipeLink.lo: links/$(am__dirstamp) \
+	links/$(DEPDIR)/$(am__dirstamp)
+links/libSingular_la-silink.lo: links/$(am__dirstamp) \
+	links/$(DEPDIR)/$(am__dirstamp)
+links/libSingular_la-sing_dbm.lo: links/$(am__dirstamp) \
+	links/$(DEPDIR)/$(am__dirstamp)
+links/libSingular_la-slInit_Static.lo: links/$(am__dirstamp) \
+	links/$(DEPDIR)/$(am__dirstamp)
+links/libSingular_la-ssiLink.lo: links/$(am__dirstamp) \
+	links/$(DEPDIR)/$(am__dirstamp)
+links/libSingular_la-semaphore.lo: links/$(am__dirstamp) \
+	links/$(DEPDIR)/$(am__dirstamp)
+
+libSingular.la: $(libSingular_la_OBJECTS) $(libSingular_la_DEPENDENCIES) $(EXTRA_libSingular_la_DEPENDENCIES) 
+	$(AM_V_CXXLD)$(libSingular_la_LINK) -rpath $(libSingulardir) $(libSingular_la_OBJECTS) $(libSingular_la_LIBADD) $(LIBS)
+install-binPROGRAMS: $(bin_PROGRAMS)
+	@$(NORMAL_INSTALL)
+	@list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \
+	fi; \
+	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
+
+clean-checkPROGRAMS:
+	@list='$(check_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
+
+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
+
+ESingular$(EXEEXT): $(ESingular_OBJECTS) $(ESingular_DEPENDENCIES) $(EXTRA_ESingular_DEPENDENCIES) 
+	@rm -f ESingular$(EXEEXT)
+	$(AM_V_CXXLD)$(CXXLINK) $(ESingular_OBJECTS) $(ESingular_LDADD) $(LIBS)
+
+Singular$(EXEEXT): $(Singular_OBJECTS) $(Singular_DEPENDENCIES) $(EXTRA_Singular_DEPENDENCIES) 
+	@rm -f Singular$(EXEEXT)
+	$(AM_V_CXXLD)$(Singular_LINK) $(Singular_OBJECTS) $(Singular_LDADD) $(LIBS)
+
+Singulard$(EXEEXT): $(Singulard_OBJECTS) $(Singulard_DEPENDENCIES) $(EXTRA_Singulard_DEPENDENCIES) 
+	@rm -f Singulard$(EXEEXT)
+	$(AM_V_CXXLD)$(Singulard_LINK) $(Singulard_OBJECTS) $(Singulard_LDADD) $(LIBS)
+
+TSingular$(EXEEXT): $(TSingular_OBJECTS) $(TSingular_DEPENDENCIES) $(EXTRA_TSingular_DEPENDENCIES) 
+	@rm -f TSingular$(EXEEXT)
+	$(AM_V_CXXLD)$(CXXLINK) $(TSingular_OBJECTS) $(TSingular_LDADD) $(LIBS)
+
+feOptES$(EXEEXT): $(feOptES_OBJECTS) $(feOptES_DEPENDENCIES) $(EXTRA_feOptES_DEPENDENCIES) 
+	@rm -f feOptES$(EXEEXT)
+	$(AM_V_CXXLD)$(CXXLINK) $(feOptES_OBJECTS) $(feOptES_LDADD) $(LIBS)
+
+feOptGen$(EXEEXT): $(feOptGen_OBJECTS) $(feOptGen_DEPENDENCIES) $(EXTRA_feOptGen_DEPENDENCIES) 
+	@rm -f feOptGen$(EXEEXT)
+	$(AM_V_CXXLD)$(CXXLINK) $(feOptGen_OBJECTS) $(feOptGen_LDADD) $(LIBS)
+
+feOptTS$(EXEEXT): $(feOptTS_OBJECTS) $(feOptTS_DEPENDENCIES) $(EXTRA_feOptTS_DEPENDENCIES) 
+	@rm -f feOptTS$(EXEEXT)
+	$(AM_V_CXXLD)$(CXXLINK) $(feOptTS_OBJECTS) $(feOptTS_LDADD) $(LIBS)
+
+gentable1$(EXEEXT): $(gentable1_OBJECTS) $(gentable1_DEPENDENCIES) $(EXTRA_gentable1_DEPENDENCIES) 
+	@rm -f gentable1$(EXEEXT)
+	$(AM_V_CXXLD)$(CXXLINK) $(gentable1_OBJECTS) $(gentable1_LDADD) $(LIBS)
+
+libparse$(EXEEXT): $(libparse_OBJECTS) $(libparse_DEPENDENCIES) $(EXTRA_libparse_DEPENDENCIES) 
+	@rm -f libparse$(EXEEXT)
+	$(AM_V_CXXLD)$(libparse_LINK) $(libparse_OBJECTS) $(libparse_LDADD) $(LIBS)
+
+test$(EXEEXT): $(test_OBJECTS) $(test_DEPENDENCIES) $(EXTRA_test_DEPENDENCIES) 
+	@rm -f test$(EXEEXT)
+	$(AM_V_CXXLD)$(CXXLINK) $(test_OBJECTS) $(test_LDADD) $(LIBS)
+install-dist_scriptSCRIPTS: $(dist_script_SCRIPTS)
+	@$(NORMAL_INSTALL)
+	@list='$(dist_script_SCRIPTS)'; test -n "$(scriptdir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(scriptdir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(scriptdir)" || exit 1; \
+	fi; \
+	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)$(scriptdir)$$dir'"; \
+	       $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(scriptdir)$$dir" || exit $$?; \
+	     } \
+	; done
+
+uninstall-dist_scriptSCRIPTS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(dist_script_SCRIPTS)'; test -n "$(scriptdir)" || exit 0; \
+	files=`for p in $$list; do echo "$$p"; done | \
+	       sed -e 's,.*/,,;$(transform)'`; \
+	dir='$(DESTDIR)$(scriptdir)'; $(am__uninstall_files_from_dir)
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+	-rm -f links/*.$(OBJEXT)
+	-rm -f links/*.lo
+
+distclean-compile:
+	-rm -f *.tab.c
+
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ESingular-emacs.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ESingular-feOpt.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ESingular-fegetopt.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/TSingular-emacs.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/TSingular-feOpt.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/TSingular-fegetopt.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/feOptES-feOptGen.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/feOptGen-feOptGen.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/feOptTS-feOptGen.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/fegetopt.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/gentable1-gentable.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libSingular_la-attrib.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libSingular_la-blackbox.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libSingular_la-calcSVD.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libSingular_la-claptmpl.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libSingular_la-cntrlc.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libSingular_la-countedref.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libSingular_la-denom_list.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libSingular_la-eigenval_ip.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libSingular_la-extra.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libSingular_la-feOpt.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libSingular_la-febase.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libSingular_la-fehelp.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libSingular_la-fevoices.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libSingular_la-fglm.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libSingular_la-gms.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libSingular_la-grammar.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libSingular_la-iparith.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libSingular_la-ipassign.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libSingular_la-ipconv.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libSingular_la-ipid.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libSingular_la-iplib.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libSingular_la-ipprint.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libSingular_la-ipshell.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libSingular_la-libparse.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libSingular_la-linearAlgebra_ip.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libSingular_la-lists.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libSingular_la-maps_ip.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libSingular_la-misc_ip.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libSingular_la-mmstd.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libSingular_la-mod_lib.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libSingular_la-newstruct.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libSingular_la-number2.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libSingular_la-pcv.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libSingular_la-pyobject_setup.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libSingular_la-scanner.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libSingular_la-sdb.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libSingular_la-subexpr.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libSingular_la-walk.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libSingular_la-walk_ip.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libSingular_la-wrapper.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libparse-fegetopt.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libparse-libparse.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libparse-utils.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/mmalloc.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/test.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tesths.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/utils.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at links/$(DEPDIR)/libSingular_la-asciiLink.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at links/$(DEPDIR)/libSingular_la-ndbm.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at links/$(DEPDIR)/libSingular_la-pipeLink.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at links/$(DEPDIR)/libSingular_la-semaphore.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at links/$(DEPDIR)/libSingular_la-silink.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at links/$(DEPDIR)/libSingular_la-sing_dbm.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at links/$(DEPDIR)/libSingular_la-slInit_Static.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at links/$(DEPDIR)/libSingular_la-ssiLink.Plo at am__quote@
+
+.c.o:
+ at am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+ at am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+ at am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+ at am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+ at am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+ at am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+ at am__fastdepCC_TRUE@	$(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+links/libSingular_la-semaphore.lo: links/semaphore.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT links/libSingular_la-semaphore.lo -MD -MP -MF links/$(DEPDIR)/libSingular_la-semaphore.Tpo -c -o links/libSingular_la-semaphore.lo `test -f 'links/semaphore.c' || echo '$(srcdir)/'`links/semaphore.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) links/$(DEPDIR)/libSingular_la-semaphore.Tpo links/$(DEPDIR)/libSingular_la-semaphore.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='links/semaphore.c' object='links/libSingular_la-semaphore.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o links/libSingular_la-semaphore.lo `test -f 'links/semaphore.c' || echo '$(srcdir)/'`links/semaphore.c
+
+libSingular_la-mmstd.lo: mmstd.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libSingular_la-mmstd.lo -MD -MP -MF $(DEPDIR)/libSingular_la-mmstd.Tpo -c -o libSingular_la-mmstd.lo `test -f 'mmstd.c' || echo '$(srcdir)/'`mmstd.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libSingular_la-mmstd.Tpo $(DEPDIR)/libSingular_la-mmstd.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='mmstd.c' object='libSingular_la-mmstd.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libSingular_la-mmstd.lo `test -f 'mmstd.c' || echo '$(srcdir)/'`mmstd.c
+
+ESingular-fegetopt.o: fegetopt.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ESingular_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ESingular-fegetopt.o -MD -MP -MF $(DEPDIR)/ESingular-fegetopt.Tpo -c -o ESingular-fegetopt.o `test -f 'fegetopt.c' || echo '$(srcdir)/'`fegetopt.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/ESingular-fegetopt.Tpo $(DEPDIR)/ESingular-fegetopt.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='fegetopt.c' object='ESingular-fegetopt.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ESingular_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ESingular-fegetopt.o `test -f 'fegetopt.c' || echo '$(srcdir)/'`fegetopt.c
+
+ESingular-fegetopt.obj: fegetopt.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ESingular_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ESingular-fegetopt.obj -MD -MP -MF $(DEPDIR)/ESingular-fegetopt.Tpo -c -o ESingular-fegetopt.obj `if test -f 'fegetopt.c'; then $(CYGPATH_W) 'fegetopt.c'; else $(CYGPATH_W) '$(srcdir)/fegetopt.c'; fi`
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/ESingular-fegetopt.Tpo $(DEPDIR)/ESingular-fegetopt.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='fegetopt.c' object='ESingular-fegetopt.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ESingular_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ESingular-fegetopt.obj `if test -f 'fegetopt.c'; then $(CYGPATH_W) 'fegetopt.c'; else $(CYGPATH_W) '$(srcdir)/fegetopt.c'; fi`
+
+TSingular-fegetopt.o: fegetopt.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(TSingular_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT TSingular-fegetopt.o -MD -MP -MF $(DEPDIR)/TSingular-fegetopt.Tpo -c -o TSingular-fegetopt.o `test -f 'fegetopt.c' || echo '$(srcdir)/'`fegetopt.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/TSingular-fegetopt.Tpo $(DEPDIR)/TSingular-fegetopt.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='fegetopt.c' object='TSingular-fegetopt.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(TSingular_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o TSingular-fegetopt.o `test -f 'fegetopt.c' || echo '$(srcdir)/'`fegetopt.c
+
+TSingular-fegetopt.obj: fegetopt.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(TSingular_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT TSingular-fegetopt.obj -MD -MP -MF $(DEPDIR)/TSingular-fegetopt.Tpo -c -o TSingular-fegetopt.obj `if test -f 'fegetopt.c'; then $(CYGPATH_W) 'fegetopt.c'; else $(CYGPATH_W) '$(srcdir)/fegetopt.c'; fi`
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/TSingular-fegetopt.Tpo $(DEPDIR)/TSingular-fegetopt.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='fegetopt.c' object='TSingular-fegetopt.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(TSingular_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o TSingular-fegetopt.obj `if test -f 'fegetopt.c'; then $(CYGPATH_W) 'fegetopt.c'; else $(CYGPATH_W) '$(srcdir)/fegetopt.c'; fi`
+
+libparse-fegetopt.o: fegetopt.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libparse_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libparse-fegetopt.o -MD -MP -MF $(DEPDIR)/libparse-fegetopt.Tpo -c -o libparse-fegetopt.o `test -f 'fegetopt.c' || echo '$(srcdir)/'`fegetopt.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libparse-fegetopt.Tpo $(DEPDIR)/libparse-fegetopt.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='fegetopt.c' object='libparse-fegetopt.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libparse_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libparse-fegetopt.o `test -f 'fegetopt.c' || echo '$(srcdir)/'`fegetopt.c
+
+libparse-fegetopt.obj: fegetopt.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libparse_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libparse-fegetopt.obj -MD -MP -MF $(DEPDIR)/libparse-fegetopt.Tpo -c -o libparse-fegetopt.obj `if test -f 'fegetopt.c'; then $(CYGPATH_W) 'fegetopt.c'; else $(CYGPATH_W) '$(srcdir)/fegetopt.c'; fi`
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libparse-fegetopt.Tpo $(DEPDIR)/libparse-fegetopt.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='fegetopt.c' object='libparse-fegetopt.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libparse_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libparse-fegetopt.obj `if test -f 'fegetopt.c'; then $(CYGPATH_W) 'fegetopt.c'; else $(CYGPATH_W) '$(srcdir)/fegetopt.c'; fi`
+
+.cc.o:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+ at am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXXCOMPILE) -c -o $@ $<
+
+.cc.obj:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+ at am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.cc.lo:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+ at am__fastdepCXX_TRUE@	$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LTCXXCOMPILE) -c -o $@ $<
+
+links/libSingular_la-asciiLink.lo: links/asciiLink.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT links/libSingular_la-asciiLink.lo -MD -MP -MF links/$(DEPDIR)/libSingular_la-asciiLink.Tpo -c -o links/libSingular_la-asciiLink.lo `test -f 'links/asciiLink.cc' || echo '$(srcdir)/'`links/asciiLink.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) links/$(DEPDIR)/libSingular_la-asciiLink.Tpo links/$(DEPDIR)/libSingular_la-asciiLink.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='links/asciiLink.cc' object='links/libSingular_la-asciiLink.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o links/libSingular_la-asciiLink.lo `test -f 'links/asciiLink.cc' || echo '$(srcdir)/'`links/asciiLink.cc
+
+libSingular_la-attrib.lo: attrib.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libSingular_la-attrib.lo -MD -MP -MF $(DEPDIR)/libSingular_la-attrib.Tpo -c -o libSingular_la-attrib.lo `test -f 'attrib.cc' || echo '$(srcdir)/'`attrib.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libSingular_la-attrib.Tpo $(DEPDIR)/libSingular_la-attrib.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='attrib.cc' object='libSingular_la-attrib.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libSingular_la-attrib.lo `test -f 'attrib.cc' || echo '$(srcdir)/'`attrib.cc
+
+libSingular_la-blackbox.lo: blackbox.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libSingular_la-blackbox.lo -MD -MP -MF $(DEPDIR)/libSingular_la-blackbox.Tpo -c -o libSingular_la-blackbox.lo `test -f 'blackbox.cc' || echo '$(srcdir)/'`blackbox.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libSingular_la-blackbox.Tpo $(DEPDIR)/libSingular_la-blackbox.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='blackbox.cc' object='libSingular_la-blackbox.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libSingular_la-blackbox.lo `test -f 'blackbox.cc' || echo '$(srcdir)/'`blackbox.cc
+
+libSingular_la-calcSVD.lo: calcSVD.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libSingular_la-calcSVD.lo -MD -MP -MF $(DEPDIR)/libSingular_la-calcSVD.Tpo -c -o libSingular_la-calcSVD.lo `test -f 'calcSVD.cc' || echo '$(srcdir)/'`calcSVD.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libSingular_la-calcSVD.Tpo $(DEPDIR)/libSingular_la-calcSVD.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='calcSVD.cc' object='libSingular_la-calcSVD.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libSingular_la-calcSVD.lo `test -f 'calcSVD.cc' || echo '$(srcdir)/'`calcSVD.cc
+
+libSingular_la-cntrlc.lo: cntrlc.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libSingular_la-cntrlc.lo -MD -MP -MF $(DEPDIR)/libSingular_la-cntrlc.Tpo -c -o libSingular_la-cntrlc.lo `test -f 'cntrlc.cc' || echo '$(srcdir)/'`cntrlc.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libSingular_la-cntrlc.Tpo $(DEPDIR)/libSingular_la-cntrlc.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='cntrlc.cc' object='libSingular_la-cntrlc.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libSingular_la-cntrlc.lo `test -f 'cntrlc.cc' || echo '$(srcdir)/'`cntrlc.cc
+
+libSingular_la-countedref.lo: countedref.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libSingular_la-countedref.lo -MD -MP -MF $(DEPDIR)/libSingular_la-countedref.Tpo -c -o libSingular_la-countedref.lo `test -f 'countedref.cc' || echo '$(srcdir)/'`countedref.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libSingular_la-countedref.Tpo $(DEPDIR)/libSingular_la-countedref.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='countedref.cc' object='libSingular_la-countedref.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libSingular_la-countedref.lo `test -f 'countedref.cc' || echo '$(srcdir)/'`countedref.cc
+
+libSingular_la-denom_list.lo: denom_list.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libSingular_la-denom_list.lo -MD -MP -MF $(DEPDIR)/libSingular_la-denom_list.Tpo -c -o libSingular_la-denom_list.lo `test -f 'denom_list.cc' || echo '$(srcdir)/'`denom_list.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libSingular_la-denom_list.Tpo $(DEPDIR)/libSingular_la-denom_list.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='denom_list.cc' object='libSingular_la-denom_list.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libSingular_la-denom_list.lo `test -f 'denom_list.cc' || echo '$(srcdir)/'`denom_list.cc
+
+libSingular_la-eigenval_ip.lo: eigenval_ip.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libSingular_la-eigenval_ip.lo -MD -MP -MF $(DEPDIR)/libSingular_la-eigenval_ip.Tpo -c -o libSingular_la-eigenval_ip.lo `test -f 'eigenval_ip.cc' || echo '$(srcdir)/'`eigenval_ip.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libSingular_la-eigenval_ip.Tpo $(DEPDIR)/libSingular_la-eigenval_ip.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='eigenval_ip.cc' object='libSingular_la-eigenval_ip.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libSingular_la-eigenval_ip.lo `test -f 'eigenval_ip.cc' || echo '$(srcdir)/'`eigenval_ip.cc
+
+libSingular_la-extra.lo: extra.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libSingular_la-extra.lo -MD -MP -MF $(DEPDIR)/libSingular_la-extra.Tpo -c -o libSingular_la-extra.lo `test -f 'extra.cc' || echo '$(srcdir)/'`extra.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libSingular_la-extra.Tpo $(DEPDIR)/libSingular_la-extra.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='extra.cc' object='libSingular_la-extra.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libSingular_la-extra.lo `test -f 'extra.cc' || echo '$(srcdir)/'`extra.cc
+
+libSingular_la-feOpt.lo: feOpt.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libSingular_la-feOpt.lo -MD -MP -MF $(DEPDIR)/libSingular_la-feOpt.Tpo -c -o libSingular_la-feOpt.lo `test -f 'feOpt.cc' || echo '$(srcdir)/'`feOpt.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libSingular_la-feOpt.Tpo $(DEPDIR)/libSingular_la-feOpt.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='feOpt.cc' object='libSingular_la-feOpt.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libSingular_la-feOpt.lo `test -f 'feOpt.cc' || echo '$(srcdir)/'`feOpt.cc
+
+libSingular_la-fehelp.lo: fehelp.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libSingular_la-fehelp.lo -MD -MP -MF $(DEPDIR)/libSingular_la-fehelp.Tpo -c -o libSingular_la-fehelp.lo `test -f 'fehelp.cc' || echo '$(srcdir)/'`fehelp.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libSingular_la-fehelp.Tpo $(DEPDIR)/libSingular_la-fehelp.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='fehelp.cc' object='libSingular_la-fehelp.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libSingular_la-fehelp.lo `test -f 'fehelp.cc' || echo '$(srcdir)/'`fehelp.cc
+
+libSingular_la-fevoices.lo: fevoices.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libSingular_la-fevoices.lo -MD -MP -MF $(DEPDIR)/libSingular_la-fevoices.Tpo -c -o libSingular_la-fevoices.lo `test -f 'fevoices.cc' || echo '$(srcdir)/'`fevoices.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libSingular_la-fevoices.Tpo $(DEPDIR)/libSingular_la-fevoices.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='fevoices.cc' object='libSingular_la-fevoices.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libSingular_la-fevoices.lo `test -f 'fevoices.cc' || echo '$(srcdir)/'`fevoices.cc
+
+libSingular_la-fglm.lo: fglm.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libSingular_la-fglm.lo -MD -MP -MF $(DEPDIR)/libSingular_la-fglm.Tpo -c -o libSingular_la-fglm.lo `test -f 'fglm.cc' || echo '$(srcdir)/'`fglm.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libSingular_la-fglm.Tpo $(DEPDIR)/libSingular_la-fglm.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='fglm.cc' object='libSingular_la-fglm.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libSingular_la-fglm.lo `test -f 'fglm.cc' || echo '$(srcdir)/'`fglm.cc
+
+libSingular_la-gms.lo: gms.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libSingular_la-gms.lo -MD -MP -MF $(DEPDIR)/libSingular_la-gms.Tpo -c -o libSingular_la-gms.lo `test -f 'gms.cc' || echo '$(srcdir)/'`gms.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libSingular_la-gms.Tpo $(DEPDIR)/libSingular_la-gms.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='gms.cc' object='libSingular_la-gms.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libSingular_la-gms.lo `test -f 'gms.cc' || echo '$(srcdir)/'`gms.cc
+
+libSingular_la-grammar.lo: grammar.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libSingular_la-grammar.lo -MD -MP -MF $(DEPDIR)/libSingular_la-grammar.Tpo -c -o libSingular_la-grammar.lo `test -f 'grammar.cc' || echo '$(srcdir)/'`grammar.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libSingular_la-grammar.Tpo $(DEPDIR)/libSingular_la-grammar.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='grammar.cc' object='libSingular_la-grammar.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libSingular_la-grammar.lo `test -f 'grammar.cc' || echo '$(srcdir)/'`grammar.cc
+
+libSingular_la-iparith.lo: iparith.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libSingular_la-iparith.lo -MD -MP -MF $(DEPDIR)/libSingular_la-iparith.Tpo -c -o libSingular_la-iparith.lo `test -f 'iparith.cc' || echo '$(srcdir)/'`iparith.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libSingular_la-iparith.Tpo $(DEPDIR)/libSingular_la-iparith.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='iparith.cc' object='libSingular_la-iparith.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libSingular_la-iparith.lo `test -f 'iparith.cc' || echo '$(srcdir)/'`iparith.cc
+
+libSingular_la-ipassign.lo: ipassign.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libSingular_la-ipassign.lo -MD -MP -MF $(DEPDIR)/libSingular_la-ipassign.Tpo -c -o libSingular_la-ipassign.lo `test -f 'ipassign.cc' || echo '$(srcdir)/'`ipassign.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libSingular_la-ipassign.Tpo $(DEPDIR)/libSingular_la-ipassign.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='ipassign.cc' object='libSingular_la-ipassign.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libSingular_la-ipassign.lo `test -f 'ipassign.cc' || echo '$(srcdir)/'`ipassign.cc
+
+libSingular_la-ipconv.lo: ipconv.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libSingular_la-ipconv.lo -MD -MP -MF $(DEPDIR)/libSingular_la-ipconv.Tpo -c -o libSingular_la-ipconv.lo `test -f 'ipconv.cc' || echo '$(srcdir)/'`ipconv.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libSingular_la-ipconv.Tpo $(DEPDIR)/libSingular_la-ipconv.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='ipconv.cc' object='libSingular_la-ipconv.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libSingular_la-ipconv.lo `test -f 'ipconv.cc' || echo '$(srcdir)/'`ipconv.cc
+
+libSingular_la-ipid.lo: ipid.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libSingular_la-ipid.lo -MD -MP -MF $(DEPDIR)/libSingular_la-ipid.Tpo -c -o libSingular_la-ipid.lo `test -f 'ipid.cc' || echo '$(srcdir)/'`ipid.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libSingular_la-ipid.Tpo $(DEPDIR)/libSingular_la-ipid.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='ipid.cc' object='libSingular_la-ipid.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libSingular_la-ipid.lo `test -f 'ipid.cc' || echo '$(srcdir)/'`ipid.cc
+
+libSingular_la-iplib.lo: iplib.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libSingular_la-iplib.lo -MD -MP -MF $(DEPDIR)/libSingular_la-iplib.Tpo -c -o libSingular_la-iplib.lo `test -f 'iplib.cc' || echo '$(srcdir)/'`iplib.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libSingular_la-iplib.Tpo $(DEPDIR)/libSingular_la-iplib.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='iplib.cc' object='libSingular_la-iplib.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libSingular_la-iplib.lo `test -f 'iplib.cc' || echo '$(srcdir)/'`iplib.cc
+
+libSingular_la-ipprint.lo: ipprint.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libSingular_la-ipprint.lo -MD -MP -MF $(DEPDIR)/libSingular_la-ipprint.Tpo -c -o libSingular_la-ipprint.lo `test -f 'ipprint.cc' || echo '$(srcdir)/'`ipprint.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libSingular_la-ipprint.Tpo $(DEPDIR)/libSingular_la-ipprint.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='ipprint.cc' object='libSingular_la-ipprint.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libSingular_la-ipprint.lo `test -f 'ipprint.cc' || echo '$(srcdir)/'`ipprint.cc
+
+libSingular_la-ipshell.lo: ipshell.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libSingular_la-ipshell.lo -MD -MP -MF $(DEPDIR)/libSingular_la-ipshell.Tpo -c -o libSingular_la-ipshell.lo `test -f 'ipshell.cc' || echo '$(srcdir)/'`ipshell.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libSingular_la-ipshell.Tpo $(DEPDIR)/libSingular_la-ipshell.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='ipshell.cc' object='libSingular_la-ipshell.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libSingular_la-ipshell.lo `test -f 'ipshell.cc' || echo '$(srcdir)/'`ipshell.cc
+
+libSingular_la-libparse.lo: libparse.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libSingular_la-libparse.lo -MD -MP -MF $(DEPDIR)/libSingular_la-libparse.Tpo -c -o libSingular_la-libparse.lo `test -f 'libparse.cc' || echo '$(srcdir)/'`libparse.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libSingular_la-libparse.Tpo $(DEPDIR)/libSingular_la-libparse.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='libparse.cc' object='libSingular_la-libparse.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libSingular_la-libparse.lo `test -f 'libparse.cc' || echo '$(srcdir)/'`libparse.cc
+
+libSingular_la-linearAlgebra_ip.lo: linearAlgebra_ip.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libSingular_la-linearAlgebra_ip.lo -MD -MP -MF $(DEPDIR)/libSingular_la-linearAlgebra_ip.Tpo -c -o libSingular_la-linearAlgebra_ip.lo `test -f 'linearAlgebra_ip.cc' || echo '$(srcdir)/'`linearAlgebra_ip.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libSingular_la-linearAlgebra_ip.Tpo $(DEPDIR)/libSingular_la-linearAlgebra_ip.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='linearAlgebra_ip.cc' object='libSingular_la-linearAlgebra_ip.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libSingular_la-linearAlgebra_ip.lo `test -f 'linearAlgebra_ip.cc' || echo '$(srcdir)/'`linearAlgebra_ip.cc
+
+libSingular_la-lists.lo: lists.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libSingular_la-lists.lo -MD -MP -MF $(DEPDIR)/libSingular_la-lists.Tpo -c -o libSingular_la-lists.lo `test -f 'lists.cc' || echo '$(srcdir)/'`lists.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libSingular_la-lists.Tpo $(DEPDIR)/libSingular_la-lists.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='lists.cc' object='libSingular_la-lists.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libSingular_la-lists.lo `test -f 'lists.cc' || echo '$(srcdir)/'`lists.cc
+
+libSingular_la-maps_ip.lo: maps_ip.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libSingular_la-maps_ip.lo -MD -MP -MF $(DEPDIR)/libSingular_la-maps_ip.Tpo -c -o libSingular_la-maps_ip.lo `test -f 'maps_ip.cc' || echo '$(srcdir)/'`maps_ip.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libSingular_la-maps_ip.Tpo $(DEPDIR)/libSingular_la-maps_ip.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='maps_ip.cc' object='libSingular_la-maps_ip.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libSingular_la-maps_ip.lo `test -f 'maps_ip.cc' || echo '$(srcdir)/'`maps_ip.cc
+
+libSingular_la-misc_ip.lo: misc_ip.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libSingular_la-misc_ip.lo -MD -MP -MF $(DEPDIR)/libSingular_la-misc_ip.Tpo -c -o libSingular_la-misc_ip.lo `test -f 'misc_ip.cc' || echo '$(srcdir)/'`misc_ip.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libSingular_la-misc_ip.Tpo $(DEPDIR)/libSingular_la-misc_ip.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='misc_ip.cc' object='libSingular_la-misc_ip.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libSingular_la-misc_ip.lo `test -f 'misc_ip.cc' || echo '$(srcdir)/'`misc_ip.cc
+
+libSingular_la-mod_lib.lo: mod_lib.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libSingular_la-mod_lib.lo -MD -MP -MF $(DEPDIR)/libSingular_la-mod_lib.Tpo -c -o libSingular_la-mod_lib.lo `test -f 'mod_lib.cc' || echo '$(srcdir)/'`mod_lib.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libSingular_la-mod_lib.Tpo $(DEPDIR)/libSingular_la-mod_lib.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='mod_lib.cc' object='libSingular_la-mod_lib.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libSingular_la-mod_lib.lo `test -f 'mod_lib.cc' || echo '$(srcdir)/'`mod_lib.cc
+
+links/libSingular_la-ndbm.lo: links/ndbm.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT links/libSingular_la-ndbm.lo -MD -MP -MF links/$(DEPDIR)/libSingular_la-ndbm.Tpo -c -o links/libSingular_la-ndbm.lo `test -f 'links/ndbm.cc' || echo '$(srcdir)/'`links/ndbm.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) links/$(DEPDIR)/libSingular_la-ndbm.Tpo links/$(DEPDIR)/libSingular_la-ndbm.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='links/ndbm.cc' object='links/libSingular_la-ndbm.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o links/libSingular_la-ndbm.lo `test -f 'links/ndbm.cc' || echo '$(srcdir)/'`links/ndbm.cc
+
+libSingular_la-newstruct.lo: newstruct.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libSingular_la-newstruct.lo -MD -MP -MF $(DEPDIR)/libSingular_la-newstruct.Tpo -c -o libSingular_la-newstruct.lo `test -f 'newstruct.cc' || echo '$(srcdir)/'`newstruct.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libSingular_la-newstruct.Tpo $(DEPDIR)/libSingular_la-newstruct.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='newstruct.cc' object='libSingular_la-newstruct.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libSingular_la-newstruct.lo `test -f 'newstruct.cc' || echo '$(srcdir)/'`newstruct.cc
+
+libSingular_la-number2.lo: number2.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libSingular_la-number2.lo -MD -MP -MF $(DEPDIR)/libSingular_la-number2.Tpo -c -o libSingular_la-number2.lo `test -f 'number2.cc' || echo '$(srcdir)/'`number2.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libSingular_la-number2.Tpo $(DEPDIR)/libSingular_la-number2.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='number2.cc' object='libSingular_la-number2.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libSingular_la-number2.lo `test -f 'number2.cc' || echo '$(srcdir)/'`number2.cc
+
+libSingular_la-pcv.lo: pcv.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libSingular_la-pcv.lo -MD -MP -MF $(DEPDIR)/libSingular_la-pcv.Tpo -c -o libSingular_la-pcv.lo `test -f 'pcv.cc' || echo '$(srcdir)/'`pcv.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libSingular_la-pcv.Tpo $(DEPDIR)/libSingular_la-pcv.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='pcv.cc' object='libSingular_la-pcv.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libSingular_la-pcv.lo `test -f 'pcv.cc' || echo '$(srcdir)/'`pcv.cc
+
+links/libSingular_la-pipeLink.lo: links/pipeLink.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT links/libSingular_la-pipeLink.lo -MD -MP -MF links/$(DEPDIR)/libSingular_la-pipeLink.Tpo -c -o links/libSingular_la-pipeLink.lo `test -f 'links/pipeLink.cc' || echo '$(srcdir)/'`links/pipeLink.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) links/$(DEPDIR)/libSingular_la-pipeLink.Tpo links/$(DEPDIR)/libSingular_la-pipeLink.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='links/pipeLink.cc' object='links/libSingular_la-pipeLink.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o links/libSingular_la-pipeLink.lo `test -f 'links/pipeLink.cc' || echo '$(srcdir)/'`links/pipeLink.cc
+
+libSingular_la-scanner.lo: scanner.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libSingular_la-scanner.lo -MD -MP -MF $(DEPDIR)/libSingular_la-scanner.Tpo -c -o libSingular_la-scanner.lo `test -f 'scanner.cc' || echo '$(srcdir)/'`scanner.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libSingular_la-scanner.Tpo $(DEPDIR)/libSingular_la-scanner.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='scanner.cc' object='libSingular_la-scanner.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libSingular_la-scanner.lo `test -f 'scanner.cc' || echo '$(srcdir)/'`scanner.cc
+
+libSingular_la-sdb.lo: sdb.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libSingular_la-sdb.lo -MD -MP -MF $(DEPDIR)/libSingular_la-sdb.Tpo -c -o libSingular_la-sdb.lo `test -f 'sdb.cc' || echo '$(srcdir)/'`sdb.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libSingular_la-sdb.Tpo $(DEPDIR)/libSingular_la-sdb.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='sdb.cc' object='libSingular_la-sdb.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libSingular_la-sdb.lo `test -f 'sdb.cc' || echo '$(srcdir)/'`sdb.cc
+
+links/libSingular_la-silink.lo: links/silink.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT links/libSingular_la-silink.lo -MD -MP -MF links/$(DEPDIR)/libSingular_la-silink.Tpo -c -o links/libSingular_la-silink.lo `test -f 'links/silink.cc' || echo '$(srcdir)/'`links/silink.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) links/$(DEPDIR)/libSingular_la-silink.Tpo links/$(DEPDIR)/libSingular_la-silink.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='links/silink.cc' object='links/libSingular_la-silink.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o links/libSingular_la-silink.lo `test -f 'links/silink.cc' || echo '$(srcdir)/'`links/silink.cc
+
+links/libSingular_la-sing_dbm.lo: links/sing_dbm.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT links/libSingular_la-sing_dbm.lo -MD -MP -MF links/$(DEPDIR)/libSingular_la-sing_dbm.Tpo -c -o links/libSingular_la-sing_dbm.lo `test -f 'links/sing_dbm.cc' || echo '$(srcdir)/'`links/sing_dbm.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) links/$(DEPDIR)/libSingular_la-sing_dbm.Tpo links/$(DEPDIR)/libSingular_la-sing_dbm.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='links/sing_dbm.cc' object='links/libSingular_la-sing_dbm.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o links/libSingular_la-sing_dbm.lo `test -f 'links/sing_dbm.cc' || echo '$(srcdir)/'`links/sing_dbm.cc
+
+links/libSingular_la-slInit_Static.lo: links/slInit_Static.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT links/libSingular_la-slInit_Static.lo -MD -MP -MF links/$(DEPDIR)/libSingular_la-slInit_Static.Tpo -c -o links/libSingular_la-slInit_Static.lo `test -f 'links/slInit_Static.cc' || echo '$(srcdir)/'`links/slInit_Static.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) links/$(DEPDIR)/libSingular_la-slInit_Static.Tpo links/$(DEPDIR)/libSingular_la-slInit_Static.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='links/slInit_Static.cc' object='links/libSingular_la-slInit_Static.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o links/libSingular_la-slInit_Static.lo `test -f 'links/slInit_Static.cc' || echo '$(srcdir)/'`links/slInit_Static.cc
+
+links/libSingular_la-ssiLink.lo: links/ssiLink.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT links/libSingular_la-ssiLink.lo -MD -MP -MF links/$(DEPDIR)/libSingular_la-ssiLink.Tpo -c -o links/libSingular_la-ssiLink.lo `test -f 'links/ssiLink.cc' || echo '$(srcdir)/'`links/ssiLink.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) links/$(DEPDIR)/libSingular_la-ssiLink.Tpo links/$(DEPDIR)/libSingular_la-ssiLink.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='links/ssiLink.cc' object='links/libSingular_la-ssiLink.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o links/libSingular_la-ssiLink.lo `test -f 'links/ssiLink.cc' || echo '$(srcdir)/'`links/ssiLink.cc
+
+libSingular_la-subexpr.lo: subexpr.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libSingular_la-subexpr.lo -MD -MP -MF $(DEPDIR)/libSingular_la-subexpr.Tpo -c -o libSingular_la-subexpr.lo `test -f 'subexpr.cc' || echo '$(srcdir)/'`subexpr.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libSingular_la-subexpr.Tpo $(DEPDIR)/libSingular_la-subexpr.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='subexpr.cc' object='libSingular_la-subexpr.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libSingular_la-subexpr.lo `test -f 'subexpr.cc' || echo '$(srcdir)/'`subexpr.cc
+
+libSingular_la-pyobject_setup.lo: pyobject_setup.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libSingular_la-pyobject_setup.lo -MD -MP -MF $(DEPDIR)/libSingular_la-pyobject_setup.Tpo -c -o libSingular_la-pyobject_setup.lo `test -f 'pyobject_setup.cc' || echo '$(srcdir)/'`pyobject_setup.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libSingular_la-pyobject_setup.Tpo $(DEPDIR)/libSingular_la-pyobject_setup.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='pyobject_setup.cc' object='libSingular_la-pyobject_setup.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libSingular_la-pyobject_setup.lo `test -f 'pyobject_setup.cc' || echo '$(srcdir)/'`pyobject_setup.cc
+
+libSingular_la-walk.lo: walk.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libSingular_la-walk.lo -MD -MP -MF $(DEPDIR)/libSingular_la-walk.Tpo -c -o libSingular_la-walk.lo `test -f 'walk.cc' || echo '$(srcdir)/'`walk.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libSingular_la-walk.Tpo $(DEPDIR)/libSingular_la-walk.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='walk.cc' object='libSingular_la-walk.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libSingular_la-walk.lo `test -f 'walk.cc' || echo '$(srcdir)/'`walk.cc
+
+libSingular_la-walk_ip.lo: walk_ip.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libSingular_la-walk_ip.lo -MD -MP -MF $(DEPDIR)/libSingular_la-walk_ip.Tpo -c -o libSingular_la-walk_ip.lo `test -f 'walk_ip.cc' || echo '$(srcdir)/'`walk_ip.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libSingular_la-walk_ip.Tpo $(DEPDIR)/libSingular_la-walk_ip.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='walk_ip.cc' object='libSingular_la-walk_ip.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libSingular_la-walk_ip.lo `test -f 'walk_ip.cc' || echo '$(srcdir)/'`walk_ip.cc
+
+libSingular_la-wrapper.lo: wrapper.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libSingular_la-wrapper.lo -MD -MP -MF $(DEPDIR)/libSingular_la-wrapper.Tpo -c -o libSingular_la-wrapper.lo `test -f 'wrapper.cc' || echo '$(srcdir)/'`wrapper.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libSingular_la-wrapper.Tpo $(DEPDIR)/libSingular_la-wrapper.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='wrapper.cc' object='libSingular_la-wrapper.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libSingular_la-wrapper.lo `test -f 'wrapper.cc' || echo '$(srcdir)/'`wrapper.cc
+
+libSingular_la-claptmpl.lo: claptmpl.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libSingular_la-claptmpl.lo -MD -MP -MF $(DEPDIR)/libSingular_la-claptmpl.Tpo -c -o libSingular_la-claptmpl.lo `test -f 'claptmpl.cc' || echo '$(srcdir)/'`claptmpl.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libSingular_la-claptmpl.Tpo $(DEPDIR)/libSingular_la-claptmpl.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='claptmpl.cc' object='libSingular_la-claptmpl.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libSingular_la-claptmpl.lo `test -f 'claptmpl.cc' || echo '$(srcdir)/'`claptmpl.cc
+
+libSingular_la-febase.lo: febase.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libSingular_la-febase.lo -MD -MP -MF $(DEPDIR)/libSingular_la-febase.Tpo -c -o libSingular_la-febase.lo `test -f 'febase.cc' || echo '$(srcdir)/'`febase.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libSingular_la-febase.Tpo $(DEPDIR)/libSingular_la-febase.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='febase.cc' object='libSingular_la-febase.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libSingular_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libSingular_la-febase.lo `test -f 'febase.cc' || echo '$(srcdir)/'`febase.cc
+
+ESingular-emacs.o: emacs.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ESingular_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT ESingular-emacs.o -MD -MP -MF $(DEPDIR)/ESingular-emacs.Tpo -c -o ESingular-emacs.o `test -f 'emacs.cc' || echo '$(srcdir)/'`emacs.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/ESingular-emacs.Tpo $(DEPDIR)/ESingular-emacs.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='emacs.cc' object='ESingular-emacs.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ESingular_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o ESingular-emacs.o `test -f 'emacs.cc' || echo '$(srcdir)/'`emacs.cc
+
+ESingular-emacs.obj: emacs.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ESingular_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT ESingular-emacs.obj -MD -MP -MF $(DEPDIR)/ESingular-emacs.Tpo -c -o ESingular-emacs.obj `if test -f 'emacs.cc'; then $(CYGPATH_W) 'emacs.cc'; else $(CYGPATH_W) '$(srcdir)/emacs.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/ESingular-emacs.Tpo $(DEPDIR)/ESingular-emacs.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='emacs.cc' object='ESingular-emacs.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ESingular_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o ESingular-emacs.obj `if test -f 'emacs.cc'; then $(CYGPATH_W) 'emacs.cc'; else $(CYGPATH_W) '$(srcdir)/emacs.cc'; fi`
+
+ESingular-feOpt.o: feOpt.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ESingular_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT ESingular-feOpt.o -MD -MP -MF $(DEPDIR)/ESingular-feOpt.Tpo -c -o ESingular-feOpt.o `test -f 'feOpt.cc' || echo '$(srcdir)/'`feOpt.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/ESingular-feOpt.Tpo $(DEPDIR)/ESingular-feOpt.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='feOpt.cc' object='ESingular-feOpt.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ESingular_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o ESingular-feOpt.o `test -f 'feOpt.cc' || echo '$(srcdir)/'`feOpt.cc
+
+ESingular-feOpt.obj: feOpt.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ESingular_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT ESingular-feOpt.obj -MD -MP -MF $(DEPDIR)/ESingular-feOpt.Tpo -c -o ESingular-feOpt.obj `if test -f 'feOpt.cc'; then $(CYGPATH_W) 'feOpt.cc'; else $(CYGPATH_W) '$(srcdir)/feOpt.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/ESingular-feOpt.Tpo $(DEPDIR)/ESingular-feOpt.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='feOpt.cc' object='ESingular-feOpt.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ESingular_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o ESingular-feOpt.obj `if test -f 'feOpt.cc'; then $(CYGPATH_W) 'feOpt.cc'; else $(CYGPATH_W) '$(srcdir)/feOpt.cc'; fi`
+
+TSingular-emacs.o: emacs.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(TSingular_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT TSingular-emacs.o -MD -MP -MF $(DEPDIR)/TSingular-emacs.Tpo -c -o TSingular-emacs.o `test -f 'emacs.cc' || echo '$(srcdir)/'`emacs.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/TSingular-emacs.Tpo $(DEPDIR)/TSingular-emacs.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='emacs.cc' object='TSingular-emacs.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(TSingular_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o TSingular-emacs.o `test -f 'emacs.cc' || echo '$(srcdir)/'`emacs.cc
+
+TSingular-emacs.obj: emacs.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(TSingular_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT TSingular-emacs.obj -MD -MP -MF $(DEPDIR)/TSingular-emacs.Tpo -c -o TSingular-emacs.obj `if test -f 'emacs.cc'; then $(CYGPATH_W) 'emacs.cc'; else $(CYGPATH_W) '$(srcdir)/emacs.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/TSingular-emacs.Tpo $(DEPDIR)/TSingular-emacs.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='emacs.cc' object='TSingular-emacs.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(TSingular_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o TSingular-emacs.obj `if test -f 'emacs.cc'; then $(CYGPATH_W) 'emacs.cc'; else $(CYGPATH_W) '$(srcdir)/emacs.cc'; fi`
+
+TSingular-feOpt.o: feOpt.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(TSingular_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT TSingular-feOpt.o -MD -MP -MF $(DEPDIR)/TSingular-feOpt.Tpo -c -o TSingular-feOpt.o `test -f 'feOpt.cc' || echo '$(srcdir)/'`feOpt.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/TSingular-feOpt.Tpo $(DEPDIR)/TSingular-feOpt.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='feOpt.cc' object='TSingular-feOpt.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(TSingular_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o TSingular-feOpt.o `test -f 'feOpt.cc' || echo '$(srcdir)/'`feOpt.cc
+
+TSingular-feOpt.obj: feOpt.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(TSingular_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT TSingular-feOpt.obj -MD -MP -MF $(DEPDIR)/TSingular-feOpt.Tpo -c -o TSingular-feOpt.obj `if test -f 'feOpt.cc'; then $(CYGPATH_W) 'feOpt.cc'; else $(CYGPATH_W) '$(srcdir)/feOpt.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/TSingular-feOpt.Tpo $(DEPDIR)/TSingular-feOpt.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='feOpt.cc' object='TSingular-feOpt.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(TSingular_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o TSingular-feOpt.obj `if test -f 'feOpt.cc'; then $(CYGPATH_W) 'feOpt.cc'; else $(CYGPATH_W) '$(srcdir)/feOpt.cc'; fi`
+
+feOptES-feOptGen.o: feOptGen.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(feOptES_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT feOptES-feOptGen.o -MD -MP -MF $(DEPDIR)/feOptES-feOptGen.Tpo -c -o feOptES-feOptGen.o `test -f 'feOptGen.cc' || echo '$(srcdir)/'`feOptGen.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/feOptES-feOptGen.Tpo $(DEPDIR)/feOptES-feOptGen.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='feOptGen.cc' object='feOptES-feOptGen.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(feOptES_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o feOptES-feOptGen.o `test -f 'feOptGen.cc' || echo '$(srcdir)/'`feOptGen.cc
+
+feOptES-feOptGen.obj: feOptGen.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(feOptES_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT feOptES-feOptGen.obj -MD -MP -MF $(DEPDIR)/feOptES-feOptGen.Tpo -c -o feOptES-feOptGen.obj `if test -f 'feOptGen.cc'; then $(CYGPATH_W) 'feOptGen.cc'; else $(CYGPATH_W) '$(srcdir)/feOptGen.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/feOptES-feOptGen.Tpo $(DEPDIR)/feOptES-feOptGen.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='feOptGen.cc' object='feOptES-feOptGen.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(feOptES_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o feOptES-feOptGen.obj `if test -f 'feOptGen.cc'; then $(CYGPATH_W) 'feOptGen.cc'; else $(CYGPATH_W) '$(srcdir)/feOptGen.cc'; fi`
+
+feOptGen-feOptGen.o: feOptGen.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(feOptGen_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT feOptGen-feOptGen.o -MD -MP -MF $(DEPDIR)/feOptGen-feOptGen.Tpo -c -o feOptGen-feOptGen.o `test -f 'feOptGen.cc' || echo '$(srcdir)/'`feOptGen.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/feOptGen-feOptGen.Tpo $(DEPDIR)/feOptGen-feOptGen.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='feOptGen.cc' object='feOptGen-feOptGen.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(feOptGen_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o feOptGen-feOptGen.o `test -f 'feOptGen.cc' || echo '$(srcdir)/'`feOptGen.cc
+
+feOptGen-feOptGen.obj: feOptGen.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(feOptGen_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT feOptGen-feOptGen.obj -MD -MP -MF $(DEPDIR)/feOptGen-feOptGen.Tpo -c -o feOptGen-feOptGen.obj `if test -f 'feOptGen.cc'; then $(CYGPATH_W) 'feOptGen.cc'; else $(CYGPATH_W) '$(srcdir)/feOptGen.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/feOptGen-feOptGen.Tpo $(DEPDIR)/feOptGen-feOptGen.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='feOptGen.cc' object='feOptGen-feOptGen.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(feOptGen_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o feOptGen-feOptGen.obj `if test -f 'feOptGen.cc'; then $(CYGPATH_W) 'feOptGen.cc'; else $(CYGPATH_W) '$(srcdir)/feOptGen.cc'; fi`
+
+feOptTS-feOptGen.o: feOptGen.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(feOptTS_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT feOptTS-feOptGen.o -MD -MP -MF $(DEPDIR)/feOptTS-feOptGen.Tpo -c -o feOptTS-feOptGen.o `test -f 'feOptGen.cc' || echo '$(srcdir)/'`feOptGen.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/feOptTS-feOptGen.Tpo $(DEPDIR)/feOptTS-feOptGen.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='feOptGen.cc' object='feOptTS-feOptGen.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(feOptTS_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o feOptTS-feOptGen.o `test -f 'feOptGen.cc' || echo '$(srcdir)/'`feOptGen.cc
+
+feOptTS-feOptGen.obj: feOptGen.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(feOptTS_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT feOptTS-feOptGen.obj -MD -MP -MF $(DEPDIR)/feOptTS-feOptGen.Tpo -c -o feOptTS-feOptGen.obj `if test -f 'feOptGen.cc'; then $(CYGPATH_W) 'feOptGen.cc'; else $(CYGPATH_W) '$(srcdir)/feOptGen.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/feOptTS-feOptGen.Tpo $(DEPDIR)/feOptTS-feOptGen.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='feOptGen.cc' object='feOptTS-feOptGen.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(feOptTS_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o feOptTS-feOptGen.obj `if test -f 'feOptGen.cc'; then $(CYGPATH_W) 'feOptGen.cc'; else $(CYGPATH_W) '$(srcdir)/feOptGen.cc'; fi`
+
+gentable1-gentable.o: gentable.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gentable1_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gentable1-gentable.o -MD -MP -MF $(DEPDIR)/gentable1-gentable.Tpo -c -o gentable1-gentable.o `test -f 'gentable.cc' || echo '$(srcdir)/'`gentable.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/gentable1-gentable.Tpo $(DEPDIR)/gentable1-gentable.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='gentable.cc' object='gentable1-gentable.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gentable1_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gentable1-gentable.o `test -f 'gentable.cc' || echo '$(srcdir)/'`gentable.cc
+
+gentable1-gentable.obj: gentable.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gentable1_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gentable1-gentable.obj -MD -MP -MF $(DEPDIR)/gentable1-gentable.Tpo -c -o gentable1-gentable.obj `if test -f 'gentable.cc'; then $(CYGPATH_W) 'gentable.cc'; else $(CYGPATH_W) '$(srcdir)/gentable.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/gentable1-gentable.Tpo $(DEPDIR)/gentable1-gentable.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='gentable.cc' object='gentable1-gentable.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gentable1_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gentable1-gentable.obj `if test -f 'gentable.cc'; then $(CYGPATH_W) 'gentable.cc'; else $(CYGPATH_W) '$(srcdir)/gentable.cc'; fi`
+
+libparse-libparse.o: libparse.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libparse_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libparse-libparse.o -MD -MP -MF $(DEPDIR)/libparse-libparse.Tpo -c -o libparse-libparse.o `test -f 'libparse.cc' || echo '$(srcdir)/'`libparse.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libparse-libparse.Tpo $(DEPDIR)/libparse-libparse.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='libparse.cc' object='libparse-libparse.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libparse_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libparse-libparse.o `test -f 'libparse.cc' || echo '$(srcdir)/'`libparse.cc
+
+libparse-libparse.obj: libparse.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libparse_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libparse-libparse.obj -MD -MP -MF $(DEPDIR)/libparse-libparse.Tpo -c -o libparse-libparse.obj `if test -f 'libparse.cc'; then $(CYGPATH_W) 'libparse.cc'; else $(CYGPATH_W) '$(srcdir)/libparse.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libparse-libparse.Tpo $(DEPDIR)/libparse-libparse.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='libparse.cc' object='libparse-libparse.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libparse_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libparse-libparse.obj `if test -f 'libparse.cc'; then $(CYGPATH_W) 'libparse.cc'; else $(CYGPATH_W) '$(srcdir)/libparse.cc'; fi`
+
+libparse-utils.o: utils.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libparse_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libparse-utils.o -MD -MP -MF $(DEPDIR)/libparse-utils.Tpo -c -o libparse-utils.o `test -f 'utils.cc' || echo '$(srcdir)/'`utils.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libparse-utils.Tpo $(DEPDIR)/libparse-utils.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='utils.cc' object='libparse-utils.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libparse_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libparse-utils.o `test -f 'utils.cc' || echo '$(srcdir)/'`utils.cc
+
+libparse-utils.obj: utils.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libparse_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libparse-utils.obj -MD -MP -MF $(DEPDIR)/libparse-utils.Tpo -c -o libparse-utils.obj `if test -f 'utils.cc'; then $(CYGPATH_W) 'utils.cc'; else $(CYGPATH_W) '$(srcdir)/utils.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libparse-utils.Tpo $(DEPDIR)/libparse-utils.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='utils.cc' object='libparse-utils.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libparse_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libparse-utils.obj `if test -f 'utils.cc'; then $(CYGPATH_W) 'utils.cc'; else $(CYGPATH_W) '$(srcdir)/utils.cc'; fi`
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+	-rm -rf links/.libs links/_libs
+install-nobase_dist_singularalllibraryDATA: $(nobase_dist_singularalllibrary_DATA)
+	@$(NORMAL_INSTALL)
+	@list='$(nobase_dist_singularalllibrary_DATA)'; test -n "$(singularalllibrarydir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(singularalllibrarydir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(singularalllibrarydir)" || exit 1; \
+	fi; \
+	$(am__nobase_list) | while read dir files; do \
+	  xfiles=; for file in $$files; do \
+	    if test -f "$$file"; then xfiles="$$xfiles $$file"; \
+	    else xfiles="$$xfiles $(srcdir)/$$file"; fi; done; \
+	  test -z "$$xfiles" || { \
+	    test "x$$dir" = x. || { \
+	      echo " $(MKDIR_P) '$(DESTDIR)$(singularalllibrarydir)/$$dir'"; \
+	      $(MKDIR_P) "$(DESTDIR)$(singularalllibrarydir)/$$dir"; }; \
+	    echo " $(INSTALL_DATA) $$xfiles '$(DESTDIR)$(singularalllibrarydir)/$$dir'"; \
+	    $(INSTALL_DATA) $$xfiles "$(DESTDIR)$(singularalllibrarydir)/$$dir" || exit $$?; }; \
+	done
+
+uninstall-nobase_dist_singularalllibraryDATA:
+	@$(NORMAL_UNINSTALL)
+	@list='$(nobase_dist_singularalllibrary_DATA)'; test -n "$(singularalllibrarydir)" || list=; \
+	$(am__nobase_strip_setup); files=`$(am__nobase_strip)`; \
+	dir='$(DESTDIR)$(singularalllibrarydir)'; $(am__uninstall_files_from_dir)
+install-nobase_dist_singularlibraryDATA: $(nobase_dist_singularlibrary_DATA)
+	@$(NORMAL_INSTALL)
+	@list='$(nobase_dist_singularlibrary_DATA)'; test -n "$(singularlibrarydir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(singularlibrarydir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(singularlibrarydir)" || exit 1; \
+	fi; \
+	$(am__nobase_list) | while read dir files; do \
+	  xfiles=; for file in $$files; do \
+	    if test -f "$$file"; then xfiles="$$xfiles $$file"; \
+	    else xfiles="$$xfiles $(srcdir)/$$file"; fi; done; \
+	  test -z "$$xfiles" || { \
+	    test "x$$dir" = x. || { \
+	      echo " $(MKDIR_P) '$(DESTDIR)$(singularlibrarydir)/$$dir'"; \
+	      $(MKDIR_P) "$(DESTDIR)$(singularlibrarydir)/$$dir"; }; \
+	    echo " $(INSTALL_DATA) $$xfiles '$(DESTDIR)$(singularlibrarydir)/$$dir'"; \
+	    $(INSTALL_DATA) $$xfiles "$(DESTDIR)$(singularlibrarydir)/$$dir" || exit $$?; }; \
+	done
+
+uninstall-nobase_dist_singularlibraryDATA:
+	@$(NORMAL_UNINSTALL)
+	@list='$(nobase_dist_singularlibrary_DATA)'; test -n "$(singularlibrarydir)" || list=; \
+	$(am__nobase_strip_setup); files=`$(am__nobase_strip)`; \
+	dir='$(DESTDIR)$(singularlibrarydir)'; $(am__uninstall_files_from_dir)
+install-nobase_libSingular_includeHEADERS: $(nobase_libSingular_include_HEADERS)
+	@$(NORMAL_INSTALL)
+	@list='$(nobase_libSingular_include_HEADERS)'; test -n "$(libSingular_includedir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(libSingular_includedir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(libSingular_includedir)" || exit 1; \
+	fi; \
+	$(am__nobase_list) | while read dir files; do \
+	  xfiles=; for file in $$files; do \
+	    if test -f "$$file"; then xfiles="$$xfiles $$file"; \
+	    else xfiles="$$xfiles $(srcdir)/$$file"; fi; done; \
+	  test -z "$$xfiles" || { \
+	    test "x$$dir" = x. || { \
+	      echo " $(MKDIR_P) '$(DESTDIR)$(libSingular_includedir)/$$dir'"; \
+	      $(MKDIR_P) "$(DESTDIR)$(libSingular_includedir)/$$dir"; }; \
+	    echo " $(INSTALL_HEADER) $$xfiles '$(DESTDIR)$(libSingular_includedir)/$$dir'"; \
+	    $(INSTALL_HEADER) $$xfiles "$(DESTDIR)$(libSingular_includedir)/$$dir" || exit $$?; }; \
+	done
+
+uninstall-nobase_libSingular_includeHEADERS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(nobase_libSingular_include_HEADERS)'; test -n "$(libSingular_includedir)" || list=; \
+	$(am__nobase_strip_setup); files=`$(am__nobase_strip)`; \
+	dir='$(DESTDIR)$(libSingular_includedir)'; $(am__uninstall_files_from_dir)
+
+# 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.
+$(am__recursive_targets):
+	@fail=; \
+	if $(am__make_keepgoing); then \
+	  failcom='fail=yes'; \
+	else \
+	  failcom='exit 1'; \
+	fi; \
+	dot_seen=no; \
+	target=`echo $@ | sed s/-recursive//`; \
+	case "$@" in \
+	  distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+	  *) list='$(SUBDIRS)' ;; \
+	esac; \
+	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"
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-recursive
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	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; \
+	$(am__define_uniq_tagged_files); \
+	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-recursive
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	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"
+cscopelist: cscopelist-recursive
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'.  Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+	rm -f $< $@
+	$(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+	@:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+	@$(am__set_TESTS_bases); \
+	am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+	redo_bases=`for i in $$bases; do \
+	              am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+	            done`; \
+	if test -n "$$redo_bases"; then \
+	  redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+	  redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+	  if $(am__make_dryrun); then :; else \
+	    rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+	  fi; \
+	fi; \
+	if test -n "$$am__remaking_logs"; then \
+	  echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+	       "recursion detected" >&2; \
+	else \
+	  am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+	fi; \
+	if $(am__make_dryrun); then :; else \
+	  st=0;  \
+	  errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+	  for i in $$redo_bases; do \
+	    test -f $$i.trs && test -r $$i.trs \
+	      || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+	    test -f $$i.log && test -r $$i.log \
+	      || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+	  done; \
+	  test $$st -eq 0 || exit 1; \
+	fi
+	@$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+	ws='[ 	]'; \
+	results=`for b in $$bases; do echo $$b.trs; done`; \
+	test -n "$$results" || results=/dev/null; \
+	all=`  grep "^$$ws*:test-result:"           $$results | wc -l`; \
+	pass=` grep "^$$ws*:test-result:$$ws*PASS"  $$results | wc -l`; \
+	fail=` grep "^$$ws*:test-result:$$ws*FAIL"  $$results | wc -l`; \
+	skip=` grep "^$$ws*:test-result:$$ws*SKIP"  $$results | wc -l`; \
+	xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+	xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+	error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+	if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+	  success=true; \
+	else \
+	  success=false; \
+	fi; \
+	br='==================='; br=$$br$$br$$br$$br; \
+	result_count () \
+	{ \
+	    if test x"$$1" = x"--maybe-color"; then \
+	      maybe_colorize=yes; \
+	    elif test x"$$1" = x"--no-color"; then \
+	      maybe_colorize=no; \
+	    else \
+	      echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+	    fi; \
+	    shift; \
+	    desc=$$1 count=$$2; \
+	    if test $$maybe_colorize = yes && test $$count -gt 0; then \
+	      color_start=$$3 color_end=$$std; \
+	    else \
+	      color_start= color_end=; \
+	    fi; \
+	    echo "$${color_start}# $$desc $$count$${color_end}"; \
+	}; \
+	create_testsuite_report () \
+	{ \
+	  result_count $$1 "TOTAL:" $$all   "$$brg"; \
+	  result_count $$1 "PASS: " $$pass  "$$grn"; \
+	  result_count $$1 "SKIP: " $$skip  "$$blu"; \
+	  result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+	  result_count $$1 "FAIL: " $$fail  "$$red"; \
+	  result_count $$1 "XPASS:" $$xpass "$$red"; \
+	  result_count $$1 "ERROR:" $$error "$$mgn"; \
+	}; \
+	{								\
+	  echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" |	\
+	    $(am__rst_title);						\
+	  create_testsuite_report --no-color;				\
+	  echo;								\
+	  echo ".. contents:: :depth: 2";				\
+	  echo;								\
+	  for b in $$bases; do echo $$b; done				\
+	    | $(am__create_global_log);					\
+	} >$(TEST_SUITE_LOG).tmp || exit 1;				\
+	mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG);			\
+	if $$success; then						\
+	  col="$$grn";							\
+	 else								\
+	  col="$$red";							\
+	  test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG);		\
+	fi;								\
+	echo "$${col}$$br$${std}"; 					\
+	echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}";	\
+	echo "$${col}$$br$${std}"; 					\
+	create_testsuite_report --maybe-color;				\
+	echo "$$col$$br$$std";						\
+	if $$success; then :; else					\
+	  echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}";		\
+	  if test -n "$(PACKAGE_BUGREPORT)"; then			\
+	    echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}";	\
+	  fi;								\
+	  echo "$$col$$br$$std";					\
+	fi;								\
+	$$success || exit 1
+
+check-TESTS:
+	@list='$(RECHECK_LOGS)';           test -z "$$list" || rm -f $$list
+	@list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+	@test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+	@set +e; $(am__set_TESTS_bases); \
+	log_list=`for i in $$bases; do echo $$i.log; done`; \
+	trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+	log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+	$(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+	exit $$?;
+recheck: all $(check_PROGRAMS)
+	@test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+	@set +e; $(am__set_TESTS_bases); \
+	bases=`for i in $$bases; do echo $$i; done \
+	         | $(am__list_recheck_tests)` || exit 1; \
+	log_list=`for i in $$bases; do echo $$i.log; done`; \
+	log_list=`echo $$log_list`; \
+	$(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+	        am__force_recheck=am--force-recheck \
+	        TEST_LOGS="$$log_list"; \
+	exit $$?
+test.log: test$(EXEEXT)
+	@p='test$(EXEEXT)'; \
+	b='test'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+.test.log:
+	@p='$<'; \
+	$(am__set_b); \
+	$(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+ at am__EXEEXT_TRUE@.test$(EXEEXT).log:
+ at am__EXEEXT_TRUE@	@p='$<'; \
+ at am__EXEEXT_TRUE@	$(am__set_b); \
+ at am__EXEEXT_TRUE@	$(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ at am__EXEEXT_TRUE@	--log-file $$b.log --trs-file $$b.trs \
+ at am__EXEEXT_TRUE@	$(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ at am__EXEEXT_TRUE@	"$$tst" $(AM_TESTS_FD_REDIRECT)
+
+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 \
+	    $(am__make_dryrun) \
+	      || test -d "$(distdir)/$$subdir" \
+	      || $(MKDIR_P) "$(distdir)/$$subdir" \
+	      || exit 1; \
+	    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
+	$(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS)
+	$(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: $(BUILT_SOURCES)
+	$(MAKE) $(AM_MAKEFLAGS) check-recursive
+all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(SCRIPTS) $(DATA) \
+		$(HEADERS)
+installdirs: installdirs-recursive
+installdirs-am:
+	for dir in "$(DESTDIR)$(libSingulardir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(scriptdir)" "$(DESTDIR)$(singularalllibrarydir)" "$(DESTDIR)$(singularlibrarydir)" "$(DESTDIR)$(libSingular_includedir)"; 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:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+	-test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+	-test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+	-test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+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)
+	-rm -f links/$(DEPDIR)/$(am__dirstamp)
+	-rm -f links/$(am__dirstamp)
+
+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-binPROGRAMS clean-checkPROGRAMS clean-generic \
+	clean-libSingularLTLIBRARIES clean-libtool clean-local \
+	clean-noinstPROGRAMS mostlyclean-am
+
+distclean: distclean-recursive
+	-rm -rf ./$(DEPDIR) links/$(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-dist_scriptSCRIPTS \
+	install-libSingularLTLIBRARIES \
+	install-nobase_dist_singularalllibraryDATA \
+	install-nobase_dist_singularlibraryDATA \
+	install-nobase_libSingular_includeHEADERS
+
+install-dvi: install-dvi-recursive
+
+install-dvi-am:
+
+install-exec-am: install-binPROGRAMS
+
+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) links/$(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-binPROGRAMS uninstall-dist_scriptSCRIPTS \
+	uninstall-libSingularLTLIBRARIES \
+	uninstall-nobase_dist_singularalllibraryDATA \
+	uninstall-nobase_dist_singularlibraryDATA \
+	uninstall-nobase_libSingular_includeHEADERS
+
+.MAKE: $(am__recursive_targets) all check check-am install install-am \
+	install-strip
+
+.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \
+	check-TESTS check-am clean clean-binPROGRAMS \
+	clean-checkPROGRAMS clean-generic clean-libSingularLTLIBRARIES \
+	clean-libtool clean-local clean-noinstPROGRAMS cscopelist-am \
+	ctags ctags-am 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-data install-data-am install-dist_scriptSCRIPTS \
+	install-dvi install-dvi-am install-exec install-exec-am \
+	install-html install-html-am install-info install-info-am \
+	install-libSingularLTLIBRARIES install-man \
+	install-nobase_dist_singularalllibraryDATA \
+	install-nobase_dist_singularlibraryDATA \
+	install-nobase_libSingular_includeHEADERS 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-compile mostlyclean-generic mostlyclean-libtool \
+	pdf pdf-am ps ps-am recheck tags tags-am uninstall \
+	uninstall-am uninstall-binPROGRAMS \
+	uninstall-dist_scriptSCRIPTS uninstall-libSingularLTLIBRARIES \
+	uninstall-nobase_dist_singularalllibraryDATA \
+	uninstall-nobase_dist_singularlibraryDATA \
+	uninstall-nobase_libSingular_includeHEADERS
+
+
+# the following dependency leads to Singular relinking upon a library update!
+Singular ESingular TSingular $(optional_Singular_programs): ${abs_builddir}/LIB
+
+#########################################################
+# the Singular library (*.lib files)
+
+include ${srcdir}/singular-libs
+
+all.lib: ${srcdir}/make_alllib.sh ${srcdir}/LIB/all.lib.tmpl ${singularlibrary}
+	${srcdir}/make_alllib.sh ${srcdir}/LIB/all.lib.tmpl ${SLIB0} ${PLIBS}
+
+clean-local:
+	if [ "${abs_builddir}" != "${abs_srcdir}" ]; then \
+	  if [ -L ${abs_builddir}/LIB ]; then unlink ${abs_builddir}/LIB; fi \
+	fi
+
+feOpt.inc: feOptGen$(EXEEXT)
+	${builddir}/feOptGen$(EXEEXT)
+
+feOptES.inc: feOptES$(EXEEXT)
+	${builddir}/feOptES$(EXEEXT)
+
+feOptTS.inc: feOptTS$(EXEEXT)
+	${builddir}/feOptTS$(EXEEXT)
+
+# plural_cmd.inc is only necessary for documentation generation
+#plural_cmd.inc: gentable1$(EXEEXT)
+#	${builddir}/gentable1$(EXEEXT) argument
+
+iparith.inc: gentable1$(EXEEXT) table.h
+	${builddir}/gentable1$(EXEEXT)
+
+# # fake rule to fix parallel make http://www.gnu.org/s/hello/manual/automake/Multiple-Outputs.html
+
+gftables: ${top_srcdir}/factory/gftables
+	ln -snf ${top_srcdir}/factory/gftables ${builddir}/gftables
+
+${abs_builddir}/LIB: ${srcdir}/LIB
+	if [ "${abs_builddir}" != "${abs_srcdir}" ]; then \
+	  ln -snf ${abs_srcdir}/LIB ${abs_builddir}/; \
+	fi
+
+MOD:
+	if [ -d "${top_builddir}/libpolys/polys/.libs" ]; then \
+	  ln -snf ${top_builddir}/libpolys/polys/.libs/ ${abs_builddir}/MOD; \
+	fi
+
+# 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/Singular/README b/Singular/README
new file mode 100644
index 0000000..3c2a611
--- /dev/null
+++ b/Singular/README
@@ -0,0 +1,22 @@
+			 Singular version 4.0
+		     University of Kaiserslautern
+     Department of Mathematics        Centre for Computer Algebra
+	  Authors: W.Decker, G.-M. Greuel, G. Pfister, H. Schoenemann
+		  (C) 1986-2014 All Rights Reserved
+
+		   README FILE FOR SINGULAR INTERPRETER
+		   ====================================
+
+This directory contains the source files for the Singular interpreter and
+the following subdirectories:
+
+  'LIB'   -- contains Singular libraries written in Singular's
+             programming language
+
+If you receive this file as part of a complete Singular distribution,
+see also the files contained in the top
+directory of the full Singular distribution.
+
+GOOD LUCK and ENJOY!                         Your Singular team.
+
+
diff --git a/Singular/all.lib b/Singular/all.lib
new file mode 100644
index 0000000..626cc2c
--- /dev/null
+++ b/Singular/all.lib
@@ -0,0 +1,121 @@
+///////////////////////////////////////////////////////////////////////////////
+version="version all.lib 4.0.1.1 Nov_2014 ";
+category = "General purpose";
+info="
+LIBRARY:  all.lib   Load all libraries (commutative case)
+AUTHORS:  Singular team (automatically generated, do not edit)
+
+use: help Singular libraries; for a list of the libraries
+";
+
+///////////////////////////////////////////////////////////////////////////////
+
+LIB "absfact.lib";
+LIB "ainvar.lib";
+LIB "aksaka.lib";
+LIB "alexpoly.lib";
+LIB "algebra.lib";
+LIB "arcpoint.lib";
+LIB "assprimeszerodim.lib";
+LIB "atkins.lib";
+LIB "brnoeth.lib";
+LIB "cisimplicial.lib";
+LIB "classify.lib";
+LIB "compregb.lib";
+LIB "control.lib";
+LIB "crypto.lib";
+LIB "curvepar.lib";
+LIB "decodegb.lib";
+LIB "deform.lib";
+LIB "elim.lib";
+LIB "equising.lib";
+LIB "finvar.lib";
+LIB "general.lib";
+LIB "gmspoly.lib";
+LIB "gmssing.lib";
+LIB "graphics.lib";
+LIB "grobcov.lib";
+LIB "groups.lib";
+LIB "grwalk.lib";
+LIB "hnoether.lib";
+LIB "homolog.lib";
+LIB "hyperel.lib";
+LIB "integralbasis.lib";
+LIB "inout.lib";
+LIB "intprog.lib";
+LIB "jacobson.lib";
+LIB "kskernel.lib";
+LIB "latex.lib";
+LIB "linalg.lib";
+LIB "makedbm.lib";
+LIB "matrix.lib";
+LIB "modstd.lib";
+LIB "mondromy.lib";
+LIB "monomialideal.lib";
+LIB "mprimdec.lib";
+LIB "mregular.lib";
+LIB "noether.lib";
+LIB "normal.lib";
+LIB "normaliz.lib";
+LIB "ntsolve.lib";
+LIB "paraplanecurves.lib";
+LIB "phindex.lib";
+LIB "pointid.lib";
+LIB "poly.lib";
+LIB "presolve.lib";
+LIB "primdec.lib";
+LIB "primdecint.lib";
+LIB "primitiv.lib";
+LIB "qhmoduli.lib";
+LIB "random.lib";
+LIB "realclassify.lib";
+LIB "realrad.lib";
+LIB "reesclos.lib";
+LIB "resbinomial.lib";
+LIB "resgraph.lib";
+LIB "resjung.lib";
+LIB "resolve.lib";
+LIB "reszeta.lib";
+LIB "ring.lib";
+LIB "rinvar.lib";
+LIB "rootsmr.lib";
+LIB "rootsur.lib";
+LIB "sagbi.lib";
+LIB "sheafcoh.lib";
+LIB "sing.lib";
+LIB "sing4ti2.lib";
+LIB "signcond.lib";
+LIB "solve.lib";
+LIB "spcurve.lib";
+LIB "spectrum.lib";
+LIB "standard.lib";
+LIB "stratify.lib";
+LIB "surf.lib";
+LIB "surfacesignature.lib";
+LIB "surfex.lib";
+LIB "teachstd.lib";
+LIB "toric.lib";
+LIB "triang.lib";
+LIB "weierstr.lib";
+LIB "zeroset.lib";
+LIB "bimodules.lib";
+LIB "bfun.lib";
+LIB "central.lib";
+LIB "dmod.lib";
+LIB "dmodapp.lib";
+LIB "dmodvar.lib";
+LIB "fpadim.lib";
+LIB "freegb.lib";
+LIB "gkdim.lib";
+LIB "involut.lib";
+LIB "ncalg.lib";
+LIB "ncdecomp.lib";
+LIB "ncfactor.lib";
+LIB "ncpreim.lib";
+LIB "nctools.lib";
+LIB "perron.lib";
+LIB "qmatrix.lib";
+LIB "purityfiltration.lib";
+LIB "nchomolog.lib";
+LIB "ratgb.lib";
+LIB "ncall.lib";
diff --git a/Singular/attrib.cc b/Singular/attrib.cc
new file mode 100644
index 0000000..8654e81
--- /dev/null
+++ b/Singular/attrib.cc
@@ -0,0 +1,474 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+
+/*
+* ABSTRACT: attributes to leftv and idhdl
+*/
+
+#include <kernel/mod2.h>
+
+#include <omalloc/omalloc.h>
+
+#include <misc/options.h>
+#include <misc/intvec.h>
+
+#include <polys/matpol.h>
+
+#include <kernel/polys.h>
+#include <kernel/ideals.h>
+
+#include <Singular/tok.h>
+#include <Singular/ipid.h>
+#include <Singular/ipshell.h>
+#include <Singular/attrib.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <unistd.h>
+
+static omBin sattr_bin = omGetSpecBin(sizeof(sattr));
+
+void sattr::Print()
+{
+  omCheckAddrSize(this,sizeof(sattr));
+  ::Print("attr:%s, type %s \n",name,Tok2Cmdname(atyp));
+  if (next!=NULL) next->Print();
+}
+
+attr sattr::Copy()
+{
+  assume (this!=NULL);
+
+  omCheckAddrSize(this,sizeof(sattr));
+  attr n=(attr)omAlloc0Bin(sattr_bin);
+  n->atyp=atyp;
+  if (name!=NULL) n->name=omStrDup(name);
+  n->data=CopyA();
+  if (next!=NULL)
+  {
+    n->next=next->Copy();
+  }
+  return n;
+}
+
+// in subexr.cc:
+//void * sattr::CopyA()
+//{
+//  omCheckAddrSize(this,sizeof(sattr));
+//  return s_internalCopy(atyp,data);
+//}
+
+static void attr_free(attr h, const ring r=currRing)
+{
+  if (h->data!=NULL) /*avoid assume failure */
+  {
+    s_internalDelete(h->atyp,h->data,r);
+    h->data=NULL;
+  }
+}
+
+attr sattr::set(const char * s, void * d, int t)
+{
+  attr h = get(s);
+  attr result=this;
+  if (h!=NULL)
+  {
+    attr_free(h);
+  }
+  else
+  {
+    h = (attr)omAlloc0Bin(sattr_bin);
+    h->next = this;
+    result=h;
+  }
+  h->name = s;
+  h->data = d;
+  h->atyp = t;
+#ifdef TEST
+  //::Print("set attr >>%s<< of type %s\n",h->name, Tok2Cmdname(t));
+#endif
+  return  result;
+}
+
+attr sattr::get(const char * s)
+{
+  attr h = this;
+  while (h!=NULL)
+  {
+    if (0 == strcmp(s,h->name))
+    {
+#ifdef TEST
+      //::Print("get attr >>%s<< of type %s\n",h->name, Tok2Cmdname(h->atyp));
+#endif
+      return h;
+    }
+    h = h->next;
+  }
+  return NULL;
+}
+
+#if 0
+void * atGet(idhdl root,const char * name)
+{
+  attr temp = root->attribute->get(name);
+  if (temp!=NULL)
+    return temp->data;
+  else
+    return NULL;
+}
+
+void * atGet(leftv root,const char * name)
+{
+  attr temp;
+  attr a=*(root->Attribute());
+  temp = a->get(name);
+  if (temp!=NULL)
+    return temp->data;
+  else
+    return NULL;
+}
+#endif
+
+void * atGet(idhdl root,const char * name, int t, void *defaultReturnValue)
+{
+  attr temp = root->attribute->get(name);
+  if ((temp!=NULL) && (temp->atyp==t))
+    return temp->data;
+  else
+    return defaultReturnValue;
+}
+
+void * atGet(leftv root,const char * name, int t)
+{
+  attr *a=(root->Attribute());
+  if (a!=NULL)
+  {
+    attr temp = (*a)->get(name);
+    if ((temp!=NULL) && (temp->atyp==t))
+      return temp->data;
+  }
+  return NULL;
+}
+
+void atSet(idhdl root,const char * name,void * data,int typ)
+{
+  if (root!=NULL)
+  {
+    if ((IDTYP(root)!=RING_CMD)
+    && (IDTYP(root)!=QRING_CMD)
+    && (!RingDependend(IDTYP(root)))&&(RingDependend(typ)))
+      WerrorS("cannot set ring-dependend objects at this type");
+    else
+      root->attribute=root->attribute->set(name,data,typ);
+  }
+}
+
+void atSet(leftv root,const char * name,void * data,int typ)
+{
+  if (root!=NULL)
+  {
+    attr *a=root->Attribute();
+    int rt=root->Typ();
+    if (a==NULL)
+      WerrorS("cannot set attributes of this object");
+    else if ((rt!=RING_CMD)
+    && (rt!=QRING_CMD)
+    && (!RingDependend(rt))&&(RingDependend(typ)))
+      WerrorS("cannot set ring-dependend objects at this type");
+    else
+    {
+      *a=(*a)->set(name,data,typ);
+    }
+  }
+}
+
+void sattr::kill(const ring r)
+{
+  attr_free(this,r);
+  omFree((ADDRESS)name);
+  name=NULL;
+  omFreeBin((ADDRESS)this, sattr_bin);
+}
+
+void sattr::killAll(const ring r)
+{
+  attr temp = this,temp1;
+
+  while (temp!=NULL)
+  {
+    temp1 = temp->next;
+    omCheckAddr(temp);
+    temp->kill(r);
+    temp = temp1;
+  }
+}
+
+void at_Kill(idhdl root,const char * name, const ring r)
+{
+  attr temp = root->attribute->get(name);
+  if (temp!=NULL)
+  {
+    attr N = temp->next;
+    attr temp1 = root->attribute;
+    if (temp1==temp)
+    {
+      root->attribute = N;
+    }
+    else
+    {
+      while (temp1->next!=temp) temp1 = temp1->next;
+      temp1->next = N;
+    }
+    temp->kill(r);
+  }
+}
+
+void at_KillAll(idhdl root, const ring r)
+{
+  root->attribute->killAll(r);
+  root->attribute = NULL;
+}
+
+void at_KillAll(leftv root, const ring r)
+{
+  root->attribute->killAll(r);
+  root->attribute = NULL;
+}
+
+BOOLEAN atATTRIB1(leftv res,leftv v)
+{
+  int t;
+  attr *aa=(v->Attribute());
+  if (aa==NULL)
+  {
+    WerrorS("this object cannot have attributes");
+    return TRUE;
+  }
+  attr a=*aa;
+  BOOLEAN haveNoAttribute=TRUE;
+  if (v->e==NULL)
+  {
+    if (hasFlag(v,FLAG_STD))
+    {
+      PrintS("attr:isSB, type int\n");
+      haveNoAttribute=FALSE;
+    }
+    if (hasFlag(v,FLAG_QRING))
+    {
+      PrintS("attr:qringNF, type int\n");
+      haveNoAttribute=FALSE;
+    }
+    if (((t=v->Typ())==RING_CMD)||(t==QRING_CMD))
+    {
+      PrintS("attr:global, type int\n");
+      haveNoAttribute=FALSE;
+    }
+  }
+  else
+  {
+    leftv at=v->LData();
+    return atATTRIB1(res,at);
+  }
+  if (a!=NULL)                    a->Print();
+  else  if(haveNoAttribute)       PrintS("no attributes\n");
+  return FALSE;
+}
+BOOLEAN atATTRIB2(leftv res,leftv v,leftv b)
+{
+  char *name=(char *)b->Data();
+  int t;
+  leftv at=NULL;
+  if (v->e!=NULL)
+    at=v->LData();
+  if (strcmp(name,"isSB")==0)
+  {
+    res->rtyp=INT_CMD;
+    res->data=(void *)(long)hasFlag(v,FLAG_STD);
+    if (at!=NULL) res->data=(void *)(long)(hasFlag(v,FLAG_STD)||(hasFlag(at,FLAG_STD)));
+  }
+  else if ((strcmp(name,"rank")==0)&&(v->Typ()==MODUL_CMD))
+  {
+    res->rtyp=INT_CMD;
+    res->data=(void *)(((ideal)v->Data())->rank);
+  }
+  else if ((strcmp(name,"global")==0)
+  &&(((t=v->Typ())==RING_CMD)||(t==QRING_CMD)))
+  {
+    res->rtyp=INT_CMD;
+    res->data=(void *)(((ring)v->Data())->OrdSgn==1);
+  }
+  else if ((strcmp(name,"ring_cf")==0)
+  &&(((t=v->Typ())==RING_CMD)||(t==QRING_CMD)))
+  {
+    res->rtyp=INT_CMD;
+    res->data=(void *)(long)(rField_is_Ring((ring)v->Data()));
+  }
+  else if (strcmp(name,"qringNF")==0)
+  {
+    res->rtyp=INT_CMD;
+    res->data=(void *)(long)hasFlag(v,FLAG_QRING);
+    if (at!=NULL) res->data=(void *)(long)(hasFlag(v,FLAG_QRING)||(hasFlag(at,FLAG_QRING)));
+  }
+#ifdef HAVE_SHIFTBBA
+  else if ((strcmp(name,"isLPring")==0)
+  &&(((t=v->Typ())==RING_CMD)||(t==QRING_CMD)))
+  {
+    res->rtyp=INT_CMD;
+    res->data=(void *)(long)(((ring)v->Data())->isLPring);
+  }
+#endif
+  else
+  {
+    attr *aa=v->Attribute();
+    if (aa==NULL)
+    {
+      WerrorS("this object cannot have attributes");
+      return TRUE;
+    }
+    attr a=*aa;
+    a=a->get(name);
+    if (a!=NULL)
+    {
+      res->rtyp=a->atyp;
+      res->data=a->CopyA();
+    }
+    else
+    {
+      res->rtyp=STRING_CMD;
+      res->data=omStrDup("");
+    }
+  }
+  return FALSE;
+}
+BOOLEAN atATTRIB3(leftv /*res*/,leftv v,leftv b,leftv c)
+{
+  idhdl h=(idhdl)v->data;
+  int t;
+  if (v->e!=NULL)
+  {
+    v=v->LData();
+    if (v==NULL) return TRUE;
+    h=NULL;
+  }
+  else if (v->rtyp!=IDHDL) h=NULL;
+
+  char *name=(char *)b->Data();
+  if (strcmp(name,"isSB")==0)
+  {
+    if (c->Typ()!=INT_CMD)
+    {
+      WerrorS("attribute isSB must be int");
+      return TRUE;
+    }
+    if (((long)c->Data())!=0L)
+    {
+      if (h!=NULL) setFlag(h,FLAG_STD);
+      setFlag(v,FLAG_STD);
+    }
+    else
+    {
+      if (h!=NULL) resetFlag(h,FLAG_STD);
+      resetFlag(v,FLAG_STD);
+    }
+  }
+  else if (strcmp(name,"qringNF")==0)
+  {
+    if (c->Typ()!=INT_CMD)
+    {
+      WerrorS("attribute qringNF must be int");
+      return TRUE;
+    }
+    if (((long)c->Data())!=0L)
+    {
+      if (h!=NULL) setFlag(h,FLAG_QRING);
+      setFlag(v,FLAG_QRING);
+    }
+    else
+    {
+      if (h!=NULL) resetFlag(h,FLAG_QRING);
+      resetFlag(v,FLAG_QRING);
+    }
+  }
+  else if ((strcmp(name,"rank")==0)&&(v->Typ()==MODUL_CMD))
+  {
+    if (c->Typ()!=INT_CMD)
+    {
+      WerrorS("attribute `rank` must be int");
+      return TRUE;
+    }
+    ideal I=(ideal)v->Data();
+    I->rank=si_max((int)I->rank,(int)((long)c->Data()));
+  }
+  else if ((strcmp(name,"global")==0)
+  &&(((t=v->Typ())==RING_CMD)||(t==QRING_CMD)))
+  {
+    WerrorS("can not set attribute `global`");
+    return TRUE;
+  }
+#ifdef HAVE_SHIFTBBA
+  else if ((strcmp(name,"isLPring")==0)
+  &&(((t=v->Typ())==RING_CMD)||(t==QRING_CMD)))
+  {
+    if (c->Typ()==INT_CMD)
+      ((ring)v->Data())->isLPring=(int)(long)c->Data();
+    else
+    {
+      WerrorS("attribute `isLPring` must be int");
+      return TRUE;
+    }
+  }
+#endif
+  else
+  {
+    int typ=c->Typ();
+    if (h!=NULL) atSet(h,omStrDup(name),c->CopyD(typ),typ/*c->T(yp()*/);
+    else         atSet(v,omStrDup(name),c->CopyD(typ),typ/*c->T(yp()*/);
+  }
+  return FALSE;
+}
+
+BOOLEAN atKILLATTR1(leftv /*res*/,leftv a)
+{
+  idhdl h=NULL;
+  if ((a->rtyp==IDHDL)&&(a->e==NULL))
+  {
+    h=(idhdl)a->data;
+    resetFlag((idhdl)a->data,FLAG_STD);
+  }
+  resetFlag(a,FLAG_STD);
+  if (h->attribute!=NULL)
+  {
+    atKillAll(h);
+    a->attribute=NULL;
+  }
+  else atKillAll(a);
+  return FALSE;
+}
+BOOLEAN atKILLATTR2(leftv /*res*/,leftv a,leftv b)
+{
+  if ((a->rtyp!=IDHDL)||(a->e!=NULL))
+  {
+    WerrorS("object must have a name");
+    return TRUE;
+  }
+  char *name=(char *)b->Data();
+  if (strcmp(name,"isSB")==0)
+  {
+    resetFlag(a,FLAG_STD);
+    resetFlag((idhdl)a->data,FLAG_STD);
+  }
+  else if (strcmp(name,"global")==0)
+  {
+    WerrorS("can not set attribut `global`");
+    return TRUE;
+  }
+  else
+  {
+    atKill((idhdl)a->data,name);
+  }
+  return FALSE;
+}
+
diff --git a/Singular/attrib.h b/Singular/attrib.h
new file mode 100644
index 0000000..541de64
--- /dev/null
+++ b/Singular/attrib.h
@@ -0,0 +1,50 @@
+#ifndef ATTRIB_H
+#define ATTRIB_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: attributes to leftv and idhdl
+*/
+#include <string.h>
+#include <kernel/structs.h>
+
+class sattr;
+typedef sattr * attr;
+class sattr
+{
+  public:
+    inline void Init() { memset(this,0,sizeof(*this)); }
+    const char *  name;
+    void *  data;
+    attr    next;
+    int     atyp; /* the type of the attribut, describes the data field
+                  */
+
+    void Print();
+    attr Copy(); /* copy all arguments */
+    void * CopyA(); /* copy the data of this attribute */
+    attr set(const char * s, void * data, int t);
+    attr get(const char * s);
+    void kill(const ring r);
+    void killAll(const ring r);
+};
+
+//void * atGet(idhdl root,const char * name);
+//void * atGet(leftv root,const char * name);
+void * atGet(idhdl root,const char * name, int t, void *defaultReturnValue = NULL);
+void * atGet(leftv root,const char * name, int t);
+void atSet(idhdl root,const char * name,void * data,int typ);
+void atSet(leftv root,const char * name,void * data,int typ);
+void at_KillAll(idhdl root,const ring r);
+void at_KillAll(leftv root,const ring r);
+#define atKillAll(H) at_KillAll(H,currRing)
+void at_Kill(idhdl root,const char * name,const ring r);
+#define atKill(H,A) at_Kill(H,A,currRing)
+
+BOOLEAN atATTRIB1(leftv res,leftv a);
+BOOLEAN atATTRIB2(leftv res,leftv a,leftv b);
+BOOLEAN atATTRIB3(leftv res,leftv a,leftv b,leftv c);
+BOOLEAN atKILLATTR1(leftv res,leftv a);
+BOOLEAN atKILLATTR2(leftv res,leftv a,leftv b);
+#endif
diff --git a/Singular/blackbox.cc b/Singular/blackbox.cc
new file mode 100644
index 0000000..9dbeff2
--- /dev/null
+++ b/Singular/blackbox.cc
@@ -0,0 +1,206 @@
+
+
+
+#include <kernel/mod2.h>
+#include <misc/auxiliary.h>
+
+#include "tok.h"
+#include "subexpr.h"
+#include "ipshell.h"
+
+#include "blackbox.h"
+
+#define MAX_BB_TYPES 256
+// #define BLACKBOX_DEVEL 1
+
+static blackbox* blackboxTable[MAX_BB_TYPES];
+static char *    blackboxName[MAX_BB_TYPES];
+static int blackboxTableCnt=0;
+#define BLACKBOX_OFFSET (MAX_TOK+1)
+blackbox* getBlackboxStuff(const int t)
+{
+  if (t>MAX_TOK)  /*MAX_TOK+1 is BLACKBOX_OFFSET*/
+    return (blackboxTable[t-BLACKBOX_OFFSET]);
+  else
+    return NULL;
+}
+
+
+void blackbox_default_destroy(blackbox */*b*/, void */*d*/)
+{
+  WerrorS("missing blackbox_destroy");
+}
+char *blackbox_default_String(blackbox */*b*/,void */*d*/)
+{
+  WerrorS("missing blackbox_String");
+  return omStrDup("");
+}
+void *blackbox_default_Copy(blackbox */*b*/,void */*d*/)
+{
+  WerrorS("missing blackbox_Copy");
+  return NULL;
+}
+void blackbox_default_Print(blackbox *b,void *d)
+{
+  char *s=b->blackbox_String(b,d);
+  PrintS(s);
+  omFree(s);
+}
+void *blackbox_default_Init(blackbox */*b*/)
+{
+  return NULL;
+}
+
+BOOLEAN blackbox_default_serialize(blackbox */*b*/, void */*d*/, si_link /*f*/)
+{
+  return TRUE;
+}
+
+BOOLEAN blackbox_default_deserialize(blackbox **/*b*/, void **/*d*/, si_link /*f*/)
+{
+  return TRUE;
+}
+
+BOOLEAN blackboxDefaultOp1(int op,leftv l, leftv r)
+{
+  if (op==TYPEOF_CMD)
+  {
+    l->data=omStrDup(getBlackboxName(r->Typ()));
+    l->rtyp=STRING_CMD;
+    return FALSE;
+  }
+  else if (op==NAMEOF_CMD)
+  {
+    if (r->name==NULL) l->data=omStrDup("");
+    else               l->data=omStrDup(r->name);
+    l->rtyp=STRING_CMD;
+    return FALSE;
+  }
+
+  return TRUE;
+}
+
+BOOLEAN blackboxDefaultOp2(int op,leftv /*l*/, leftv r1, leftv /*r2*/)
+{
+  return TRUE;
+}
+
+BOOLEAN blackboxDefaultOp3(int op,leftv /*l*/, leftv r1,leftv /*r2*/, leftv /*r3*/)
+{
+  return TRUE;
+}
+
+BOOLEAN blackboxDefaultOpM(int op,leftv res, leftv args)
+{
+  if (op==LIST_CMD)
+  {
+    res->rtyp=LIST_CMD;
+    return jjLIST_PL(res,args);
+  }
+  else if(op==STRING_CMD)
+  {
+    blackbox *b=getBlackboxStuff(args->Typ());
+    res->data=b->blackbox_String(b,args->Data());
+    res->rtyp=STRING_CMD;
+    args=args->next;
+    if(args!=NULL)
+    {
+      sleftv res2;
+      int ret=iiExprArithM(&res2,args,op);
+      if (ret) return TRUE;
+      char *s2=(char*)omAlloc(strlen((char*)res->data)+strlen((char*)res2.data)+1);
+      sprintf(s2,"%s%s",(char*)res->data,(char*)res2.data);
+      omFree(res2.data);
+      omFree(res->data);
+      res->data=s2;
+    }
+    return FALSE;
+  }
+  return TRUE;
+}
+
+BOOLEAN blackbox_default_Check(blackbox *,leftv,leftv)
+{
+  return FALSE;
+}
+int setBlackboxStuff(blackbox *bb, const char *n)
+{
+  int where=-1;
+  if (MAX_BB_TYPES<=blackboxTableCnt)
+  {
+    // second try, find empty slot from removed bb:
+    for (int i=0;i<MAX_BB_TYPES;i++)
+    {
+      if (blackboxTable[i]==NULL) { where=i; break; }
+    }
+  }
+  else
+  {
+    where=blackboxTableCnt;
+    blackboxTableCnt++;
+  }
+  if (where==-1)
+  {
+    WerrorS("too many bb types defined");
+    return 0;
+  }
+  else
+  {
+    blackboxTable[where]=bb;
+    blackboxName[where]=omStrDup(n);
+#ifdef BLACKBOX_DEVEL
+  Print("setBlackboxStuff: define bb:name=%s:rt=%d (table:cnt=%d)\n",blackboxName[where],where+BLACKBOX_OFFSET,where);
+#endif
+    if (bb->blackbox_destroy==NULL) bb->blackbox_destroy=blackbox_default_destroy;
+    if (bb->blackbox_String==NULL)  bb->blackbox_String=blackbox_default_String;
+    if (bb->blackbox_Print==NULL)   bb->blackbox_Print=blackbox_default_Print;
+    if (bb->blackbox_Init==NULL)    bb->blackbox_Init=blackbox_default_Init;
+    if (bb->blackbox_Copy==NULL)    bb->blackbox_Copy=blackbox_default_Copy;
+    if (bb->blackbox_Op1==NULL)     bb->blackbox_Op1=blackboxDefaultOp1;
+    if (bb->blackbox_Op2==NULL)     bb->blackbox_Op2=blackboxDefaultOp2;
+    if (bb->blackbox_Op3==NULL)     bb->blackbox_Op3=blackboxDefaultOp3;
+    if (bb->blackbox_OpM==NULL)     bb->blackbox_OpM=blackboxDefaultOpM;
+    if (bb->blackbox_CheckAssign==NULL) bb->blackbox_CheckAssign=blackbox_default_Check;
+    if (bb->blackbox_serialize==NULL) bb->blackbox_serialize=blackbox_default_serialize;
+    if (bb->blackbox_deserialize==NULL) bb->blackbox_deserialize=blackbox_default_deserialize;
+    return where+BLACKBOX_OFFSET;
+  }
+}
+
+void removeBlackboxStuff(const int rt)
+{
+  omfree(blackboxTable[rt-BLACKBOX_OFFSET]);
+  omfree(blackboxName[rt-BLACKBOX_OFFSET]);
+  blackboxTable[rt-BLACKBOX_OFFSET]=NULL;
+  blackboxName[rt-BLACKBOX_OFFSET]=NULL;
+}
+const char *getBlackboxName(const int t)
+{
+ char *b=blackboxName[t-BLACKBOX_OFFSET];
+  if (b!=NULL) return b;
+  else         return "";
+}
+int blackboxIsCmd(const char *n, int & tok)
+{
+  for(int i=blackboxTableCnt-1;i>=0;i--)
+  {
+    if(strcmp(n,blackboxName[i])==0)
+    {
+#ifdef BLACKBOX_DEVEL
+      Print("blackboxIsCmd: found bb:%s:%d (table:%d)\n",n,i+BLACKBOX_OFFSET,i);
+#endif
+      tok=i+BLACKBOX_OFFSET;
+      return ROOT_DECL;
+    }
+  }
+  return 0;
+}
+
+void printBlackboxTypes()
+{
+  for(int i=blackboxTableCnt-1;i>=0;i--)
+  {
+    if (blackboxName[i]!=NULL)
+       Print("type %d: %s\n",i,blackboxName[i]);
+  }
+}
diff --git a/Singular/blackbox.h b/Singular/blackbox.h
new file mode 100644
index 0000000..ca6bbfc
--- /dev/null
+++ b/Singular/blackbox.h
@@ -0,0 +1,84 @@
+#ifndef BLACKBOX_H
+#define BLACKBOX_H
+
+#include <misc/auxiliary.h>
+#include <omalloc/omalloc.h>
+
+#include <kernel/structs.h>
+
+#include <Singular/lists.h>
+#include <Singular/links/silink.h>
+
+void removeBlackboxStuff(const int rt);
+
+struct blackbox_struct;
+
+typedef struct blackbox_struct blackbox;
+
+struct  blackbox_struct
+{
+  /// destroy the object: b points to blackbox_struct, d to data
+  void (*blackbox_destroy)(blackbox  *b, void *d);
+  /// convert the object to a string (which should be freed by omFree)
+  char *(*blackbox_String)(blackbox *b,void *d);
+  /// print the object: default: use string representation
+  void (*blackbox_Print)(blackbox *b,void *d);
+  /// construct the default object
+  void *(*blackbox_Init)(blackbox *b);
+  /// copy the object: b points to blackbox_struct, d to data
+  void *(*blackbox_Copy)(blackbox *b,void *d);
+  /// interpreter assign: l:=r
+  BOOLEAN (*blackbox_Assign)(leftv l, leftv r);
+  /// interpreter: unary operations op(r), r(), ...
+  // convention for blackbox_Op1..blackbox_OpM:
+  //             return FALSE, if op was successfully performed
+  //             return TRUE (and an error message) for failure
+  //             return TRUE (and no error message) if not defined
+  BOOLEAN (*blackbox_Op1)(int op,leftv l, leftv r);
+  /// interpreter: binary operations: op(r1,r2), r1 op r2,...
+  BOOLEAN (*blackbox_Op2)(int op,leftv l, leftv r1,leftv r2);
+  /// interpreter: tertiary op: op(r1,r2,r3)
+  BOOLEAN (*blackbox_Op3)(int op,leftv l, leftv r1,leftv r2, leftv r3);
+  /// interpreter: operations with undefined number of operands
+  BOOLEAN (*blackbox_OpM)(int op,leftv l, leftv r);
+  /// is an assign of r to l (part of b) impossible?
+  BOOLEAN (*blackbox_CheckAssign)(blackbox *b,leftv l, leftv r);
+  /// serialize
+  BOOLEAN (*blackbox_serialize)(blackbox *b,void *d, si_link f);
+  /// deserialize
+  BOOLEAN (*blackbox_deserialize)(blackbox **b,void **d, si_link f);
+  /// additional type info
+  void *data;
+  /// addtinional gneral properties
+  int properties; // bit 0:blackbox is only a wrapper for lists
+#define  BB_LIKE_LIST(B) ((B)->properties &1)
+} ;
+/// default procedure blackboxDefaultOp1, to be called as "default:" branch
+BOOLEAN blackboxDefaultOp1(int op,leftv l, leftv r);
+
+/// default procedure blackboxDefaultOp2, to be called as "default:" branch
+BOOLEAN blackboxDefaultOp2(int op,leftv l, leftv r1, leftv r2);
+
+/// default procedure blackboxDefaultOp3, to be called as "default:" branch
+BOOLEAN blackboxDefaultOp3(int op,leftv l, leftv r1,leftv r2, leftv r3);
+
+/// default procedure blackboxDefaultOpM, to be called as "default:" branch
+BOOLEAN blackboxDefaultOpM(int op,leftv l, leftv r);
+
+/// default procedure blackbox_default_Print: print the string
+void blackbox_default_Print(blackbox *b,void *d);
+
+/// return the structure to the type given by t
+blackbox* getBlackboxStuff(const int t);
+/// return the name to the type given by t (r/o)
+const char *    getBlackboxName(const int t);
+/// used by scanner: returns ROOT_DECL for known types
+/// (and the type number in @c tok)
+int blackboxIsCmd(const char *n, int & tok);
+/// define a new type
+int setBlackboxStuff(blackbox *bb,const char *name);
+
+/// list all defined type (for debugging)
+void printBlackboxTypes();
+
+#endif
diff --git a/Singular/calcSVD.cc b/Singular/calcSVD.cc
new file mode 100644
index 0000000..18eeab9
--- /dev/null
+++ b/Singular/calcSVD.cc
@@ -0,0 +1,118 @@
+#include <stdio.h>
+
+
+
+#include <kernel/mod2.h>
+
+#ifdef HAVE_SVD
+
+#include <Singular/svd_si.h>
+#include <kernel/structs.h>
+#include <kernel/polys.h>
+#include <polys/matpol.h>
+#include <Singular/lists.h>
+
+template class std::vector< amp::mpfr_record* >;
+
+poly p_svdInit(char *s)
+{
+  poly p=pInit();
+  n_Read(s, &pGetCoeff(p), currRing->cf);
+  return p;
+}
+
+/*************************************************************************
+Testing SVD decomposition subroutine
+*************************************************************************/
+lists testsvd(matrix M)
+{
+
+    const unsigned int Precision=300;
+
+    int max_i=M->nrows;
+    int max_j=M->ncols;
+    ap::template_2d_array< amp::ampf<Precision> > a;
+    int m;
+    int n;
+    int maxmn;
+    int i;
+    int j;
+    int gpass;
+    int pass;
+    bool waserrors;
+    bool wsorted;
+    bool wfailed;
+    amp::ampf<Precision> materr;
+    amp::ampf<Precision> orterr;
+    amp::ampf<Precision> othererr;
+    amp::ampf<Precision> threshold;
+    amp::ampf<Precision> failthreshold;
+    amp::ampf<Precision> failr;
+
+
+    materr = 0;
+    orterr = 0;
+    othererr = 0;
+    wsorted = true;
+    wfailed = false;
+    waserrors = false;
+    maxmn = 50;
+    threshold = 5*100*amp::ampf<Precision>::getAlgoPascalEpsilon();
+    failthreshold = amp::ampf<Precision>("5.0E-3");
+    a.setbounds(1, max_i, 1, max_j);
+
+
+        //
+        // fill matrix a entries from M
+        //
+        for(i=1; i<=max_i; i++)
+        {
+            for(j=1; j<=max_j; j++)
+            {
+            	char *str=pString(MATELEM(M,i,j));
+              	Print(" to svd:%d,%d=%s\n",i,j,str);
+                a(i,j) = amp::ampf<Precision>(str);
+            }
+        }
+        //testsvdproblem<Precision>(a, max_i, max_j, materr, orterr, othererr, wsorted, wfailed);
+    ap::template_2d_array< amp::ampf<Precision> > u;
+    ap::template_2d_array< amp::ampf<Precision> > vt;
+    ap::template_1d_array< amp::ampf<Precision> > w;
+    svd::svddecomposition<Precision>(a, max_i, max_j, 2, 2, 2, w, u, vt);
+    matrix Mu,Mw,Mvt;
+    Mu=mpNew(max_i,max_i);
+    Mw=mpNew(max_i,max_j);
+    Mvt=mpNew(max_j,max_j);
+    for(i=1;i<=max_i;i++)
+    {
+    	for(j=1;j<=max_i;j++)
+    	{
+    		MATELEM(Mu,i,j)=p_svdInit(u(i,j).toString());
+//        		Print(" after svd:%d,%d=%s\n",i,j,u(i,j).toString());
+    	}
+    }
+    for(i=1;i<=si_min(max_i,max_j);i++)
+    {
+    		MATELEM(Mw,i,i)=p_svdInit(w(i).toString());
+//Print(" after svd:%d,%d=%s\n",i,w(i).toString());
+    }
+    for(i=1;i<=max_j;i++)
+    {
+    	for(j=1;j<=max_j;j++)
+    	{
+    		MATELEM(Mvt,i,j)=p_svdInit(vt(i,j).toString());
+//Print(" after svd:%d,%d=%s\n",i,j,vt(i,j).toString());
+    	}
+    }
+    lists L=(lists)omAlloc(sizeof(slists));
+    L->Init(3);
+    L->m[0].rtyp=MATRIX_CMD;
+    L->m[1].rtyp=MATRIX_CMD;
+    L->m[2].rtyp=MATRIX_CMD;
+    L->m[0].data=(char*)Mu;
+    L->m[1].data=(char*)Mw;
+    L->m[2].data=(char*)Mvt;
+    return L;
+}
+
+#endif
diff --git a/Singular/claptmpl.cc b/Singular/claptmpl.cc
new file mode 100644
index 0000000..5a0ad7b
--- /dev/null
+++ b/Singular/claptmpl.cc
@@ -0,0 +1,137 @@
+// emacs edit mode for this file is -*- C++ -*-
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT - instantiation of all templates
+*/
+
+
+
+
+#include <kernel/mod2.h>
+//#include <vector>
+//using namespace std;
+  #define SINGULAR 1
+  #include <factory/factory.h>
+  #include <factory/templates/ftmpl_list.cc>
+  #include <kernel/fglm/fglm.h>
+
+// templates for fglm:
+  template class List<fglmSelem>;
+  template class ListItem<fglmSelem>;
+  template class ListIterator<fglmSelem>;
+  template class List<fglmDelem>;
+  template class ListItem<fglmDelem>;
+  template class ListIterator<fglmDelem>;
+
+// ----------------------------------------------------------------------------
+//  kmatrix.cc
+//  begin of file
+//  Stephan Endrass, endrass at mathematik.uni-mainz.de
+//  23.7.99
+// ----------------------------------------------------------------------------
+
+#ifdef HAVE_SPECTRUM
+
+#ifdef   KMATRIX_PRINT
+#include <iostream.h>
+#ifndef   KMATRIX_IOSTREAM
+#include <stdio.h>
+#endif
+#endif
+
+#include <kernel/spectrum/GMPrat.h>
+#include <kernel/spectrum/kmatrix.h>
+
+template class KMatrix<Rational>;
+
+#ifdef   KMATRIX_PRINT
+template    OSTREAM &   operator << ( OSTREAM&,const KMatrix<Rational>& );
+template    static  void    print_rational( OSTREAM&,int,const Rational& );
+#endif
+
+#endif /* HAVE_SPECTRUM */
+// ----------------------------------------------------------------------------
+//  kmatrix.cc
+//  end of file
+// ----------------------------------------------------------------------------
+
+#ifdef HAVE_PLURAL
+
+#include <polys/nc/ncSAMult.h> // for CMultiplier etc classes
+
+template class CMultiplier<int>;
+template class CMultiplier<poly>;
+template class CMultiplier<CPower>;
+
+// #include <kernel/ncSACache.h> // for CCacheHash etc classes
+// template class CCacheHash<poly>;
+// template class CCacheHash<int>;
+
+#endif
+
+#include <kernel/GBEngine/tgb_internal.h>
+#ifdef HAVE_BOOST
+#include <boost/dynamic_bitset.hpp>
+#include <vector>
+using std::vector;
+using boost::dynamic_bitset;
+template class dynamic_bitset<>;
+template class vector<dynamic_bitset<> >;
+#elif defined(USE_STDVECBOOL)
+#include <vector>
+using std::vector;
+template class vector<bool>;
+template class vector<vector<bool> >;
+#endif
+
+template int pos_helper(kStrategy strat, poly p, int len, intset  setL, polyset set);
+template int pos_helper(kStrategy strat, poly p, wlen_type len, wlen_set setL, polyset set);
+#ifdef NORO_CACHE
+//template class std::map<PolySimple,std::pair<PolySimple,int> >;
+//#include <queue>
+template class std::vector<PolySimple>;
+//template class std::priority_queue<MonRedRes>;
+//template class std::vector<NoroPlaceHolder>;
+//template class std::vector<std::vector<NoroPlaceHolder> >;
+//template class std::vector<DataNoroCacheNode<tgb_uint16>* >;
+//template class std::vector<DataNoroCacheNode<tgb_uint8>* >;
+template class std::vector<DataNoroCacheNode<tgb_uint32>* >;
+//template SparseRow<tgb_uint16> * noro_red_to_non_poly_t<tgb_uint16>(poly p, int &len, NoroCache<tgb_uint16>* cache,slimgb_alg* c);
+template SparseRow<tgb_uint32>* noro_red_to_non_poly_t<tgb_uint32>(poly p, int &len, NoroCache<tgb_uint32>* cache,slimgb_alg* c);
+//template SparseRow<tgb_uint8>* noro_red_to_non_poly_t<tgb_uint8>(poly p, int &len, NoroCache<tgb_uint8>* cache,slimgb_alg* c);
+//template void simplest_gauss_modp<tgb_uint16> (tgb_uint16* a, int nrows,int ncols);
+template void simplest_gauss_modp<tgb_uint32> (tgb_uint32* a, int nrows,int ncols);
+//template void simplest_gauss_modp<tgb_uint8> (tgb_uint8* a, int nrows,int ncols);
+//template poly row_to_poly<tgb_uint8>(tgb_uint8* row, poly* terms, int tn, ring r);
+template poly row_to_poly<tgb_uint32>(tgb_uint32* row, poly* terms, int tn, ring r);
+//template poly row_to_poly<tgb_uint16>(tgb_uint16* row, poly* terms, int tn, ring r);
+template void noro_step<tgb_uint8>(poly*p,int &pn,slimgb_alg* c);
+template void noro_step<tgb_uint16>(poly*p,int &pn,slimgb_alg* c);
+template void noro_step<tgb_uint32>(poly*p,int &pn,slimgb_alg* c);
+//std::priority_queue<MonRedRes>
+//
+#endif
+
+/* next lines are templates used in new minor code */
+#include <list>
+#include <kernel/linear_algebra/Minor.h>
+#include <kernel/linear_algebra/Cache.h>
+
+template class std::list<int>;
+template class std::list<MinorKey>;
+template class std::list<IntMinorValue>;
+template class std::list<PolyMinorValue>;
+
+
+/*
+template class std::_List_base<IntMinorValue, std::allocator<IntMinorValue> >;
+template class std::_List_base<int, std::allocator<int> >;
+template class std::_List_base<MinorKey, std::allocator<MinorKey> >;
+template class std::_List_base<PolyMinorValue, std::allocator<PolyMinorValue> >;
+*/
+
+template class Cache<MinorKey, IntMinorValue>;
+template class Cache<MinorKey, PolyMinorValue>;
+
diff --git a/Singular/cntrlc.cc b/Singular/cntrlc.cc
new file mode 100644
index 0000000..3dcb4ad
--- /dev/null
+++ b/Singular/cntrlc.cc
@@ -0,0 +1,597 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT - interupt handling
+*/
+#include <kernel/mod2.h>
+
+/* includes */
+#ifdef DecAlpha_OSF1
+#define _XOPEN_SOURCE_EXTENDED
+#endif /* MP3-Y2 0.022UF */
+
+#include <omalloc/omalloc.h>
+
+#include <reporter/si_signals.h>
+#include <Singular/fevoices.h>
+
+#include <Singular/tok.h>
+#include <Singular/ipshell.h>
+void sig_chld_hdl(int sig); /*#include <Singular/links/ssiLink.h>*/
+#include <Singular/cntrlc.h>
+#include <Singular/feOpt.h>
+#include <Singular/misc_ip.h>
+#include <Singular/links/silink.h>
+#include <Singular/links/ssiLink.h>
+
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <strings.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+/* undef, if you don't want GDB to come up on error */
+
+#define CALL_GDB
+
+#if defined(__OPTIMIZE__) && defined(CALL_GDB)
+#undef CALL_GDB
+#endif
+
+#if defined(unix)
+ #include <unistd.h>
+ #include <sys/types.h>
+
+ #ifdef TIME_WITH_SYS_TIME
+   #include <time.h>
+   #ifdef HAVE_SYS_TIME_H
+     #include <sys/time.h>
+   #endif
+ #else
+   #ifdef HAVE_SYS_TIME_H
+     #include <sys/time.h>
+   #else
+     #include <time.h>
+   #endif
+ #endif
+ #ifdef HAVE_SYS_TIMES_H
+   #include <sys/times.h>
+ #endif
+
+ #define INTERACTIVE 0
+ #define STACK_TRACE 1
+
+ #ifdef CALL_GDB
+   static void debug (int);
+   static void debug_stop (char *const*args);
+ #endif
+ #ifndef __OPTIMIZE__
+   static void stack_trace_sigchld (int);
+   static void stack_trace (char *const*args);
+ #endif
+#endif
+
+si_link pipeLastLink=NULL;
+BOOLEAN singular_in_batchmode=FALSE;
+
+void sig_pipe_hdl(int /*sig*/)
+{
+ if (pipeLastLink!=NULL)
+ {
+   slClose(pipeLastLink);
+   pipeLastLink=NULL;
+   WerrorS("pipe failed");
+ }
+}
+
+volatile BOOLEAN do_shutdown = FALSE;
+volatile int defer_shutdown = 0;
+
+void sig_term_hdl(int /*sig*/)
+{
+  do_shutdown = TRUE;
+  if (!defer_shutdown)
+  {
+    m2_end(1);
+  }
+}
+
+/*---------------------------------------------------------------------*
+ * File scope Variables (Variables share by several functions in
+ *                       the same file )
+ *
+ *---------------------------------------------------------------------*/
+/* data */
+jmp_buf si_start_jmpbuf;
+int siRandomStart;
+short si_restart=0;
+BOOLEAN siCntrlc = FALSE;
+
+typedef void (*si_hdl_typ)(int);
+
+
+/*0 implementation*/
+/*---------------------------------------------------------------------*
+ * Functions declarations
+ *
+ *---------------------------------------------------------------------*/
+void sigint_handler(int /*sig*/);
+
+si_hdl_typ si_set_signal ( int sig, si_hdl_typ signal_handler);
+
+/*---------------------------------------------------------------------*/
+/**
+ * @brief meta function for binding a signal to an handler
+
+ @param[in] sig             Signal number
+ @param[in] signal_handler  Pointer to signal handler
+
+ @return value of signal()
+**/
+/*---------------------------------------------------------------------*/
+si_hdl_typ si_set_signal ( int sig, si_hdl_typ signal_handler)
+{
+#if 0
+  si_hdl_typ retval=signal (sig, (si_hdl_typ)signal_handler);
+  if (retval == SIG_ERR)
+  {
+     fprintf(stderr, "Unable to init signal %d ... exiting...\n", sig);
+  }
+  si_siginterrupt(sig, 0);
+  /*system calls will be restarted if interrupted by  the  specified
+   * signal sig.  This is the default behavior in Linux.
+   */
+#else
+  struct sigaction new_action,old_action;
+  memset(&new_action, 0, sizeof(struct sigaction));
+
+  /* Set up the structure to specify the new action. */
+  new_action.sa_handler = signal_handler;
+  if (sig==SIGINT)
+    sigemptyset (&new_action.sa_mask);
+  else
+    new_action.sa_flags = SA_RESTART;
+
+  int r=si_sigaction (sig, &new_action, &old_action);
+  si_hdl_typ retval=(si_hdl_typ)old_action.sa_handler;
+  if (r == -1)
+  {
+     fprintf(stderr, "Unable to init signal %d ... exiting...\n", sig);
+     retval=SIG_ERR;
+  }
+#endif
+  return retval;
+}                               /* si_set_signal */
+
+
+/*---------------------------------------------------------------------*/
+#if defined(__linux__) && defined(__i386)
+  #if !defined(HAVE_SIGCONTEXT) && !defined(HAVE_ASM_SIGCONTEXT_H)
+// we need the following structure sigcontext_struct.
+// if configure finds asm/singcontext.h we assume
+// that this file contains the structure and is included
+// via signal.h
+struct sigcontext_struct {
+        unsigned short gs, __gsh;
+        unsigned short fs, __fsh;
+        unsigned short es, __esh;
+        unsigned short ds, __dsh;
+        unsigned long edi;
+        unsigned long esi;
+        unsigned long ebp;
+        unsigned long esp;
+        unsigned long ebx;
+        unsigned long edx;
+        unsigned long ecx;
+        unsigned long eax;
+        unsigned long trapno;
+        unsigned long err;
+        unsigned long eip;
+        unsigned short cs, __csh;
+        unsigned long eflags;
+        unsigned long esp_at_signal;
+        unsigned short ss, __ssh;
+        unsigned long i387;
+        unsigned long oldmask;
+        unsigned long cr2;
+};
+#endif
+#define HAVE_SIGSTRUCT
+typedef struct sigcontext_struct sigcontext;
+#endif
+
+#if defined(__linux__) && defined(__amd64)
+#define HAVE_SIGSTRUCT
+#endif
+
+
+#if defined(HAVE_SIGSTRUCT)
+/*2---------------------------------------------------------------------*/
+/**
+ * @brief signal handler for run time errors, linux/i386, x86_64 version
+
+ @param[in] sig
+ @param[in] s
+**/
+/*---------------------------------------------------------------------*/
+void sigsegv_handler(int sig, sigcontext s)
+{
+  fprintf(stderr,"Singular : signal %d (v: %d):\n",sig,SINGULAR_VERSION);
+  if (sig!=SIGINT)
+  {
+    fprintf(stderr,"current line:>>%s<<\n",my_yylinebuf);
+    fprintf(stderr,"Segment fault/Bus error occurred at %lx because of %lx (r:%d)\n"
+                   "please inform the authors\n",
+                   #ifdef __i386__
+                   (long)s.eip,
+                   #else /* x86_64*/
+                   (long)s.rip,
+                   #endif
+                   (long)s.cr2,siRandomStart);
+  }
+#ifdef __OPTIMIZE__
+  if(si_restart<3)
+  {
+    si_restart++;
+    fprintf(stderr,"trying to restart...\n");
+    init_signals();
+    longjmp(si_start_jmpbuf,1);
+  }
+#endif /* __OPTIMIZE__ */
+#ifdef CALL_GDB
+  if (sig!=SIGINT)
+  {
+    if (singular_in_batchmode) debug(STACK_TRACE);
+    else                       debug(INTERACTIVE);
+  }
+#endif /* CALL_GDB */
+  exit(0);
+}
+
+/*---------------------------------------------------------------------*/
+#elif defined(SunOS) /*SPARC_SUNOS*/
+/*2
+* signal handler for run time errors, sparc sunos 4 version
+*/
+void sigsegv_handler(int sig, int code, struct sigcontext *scp, char *addr)
+{
+  fprintf(stderr,"Singular : signal %d, code %d (v: %d):\n",
+    sig,code,SINGULAR_VERSION);
+  if ((sig!=SIGINT)&&(sig!=SIGABRT))
+  {
+    fprintf(stderr,"current line:>>%s<<\n",my_yylinebuf);
+    fprintf(stderr,"Segment fault/Bus error occurred at %x (r:%d)\n"
+                   "please inform the authors\n",
+                   (int)addr,siRandomStart);
+  }
+#ifdef __OPTIMIZE__
+  if(si_restart<3)
+  {
+    si_restart++;
+    fprintf(stderr,"trying to restart...\n");
+    init_signals();
+    longjmp(si_start_jmpbuf,1);
+  }
+#endif /* __OPTIMIZE__ */
+#ifdef CALL_GDB
+  if (sig!=SIGINT) debug(STACK_TRACE);
+#endif /* CALL_GDB */
+  exit(0);
+}
+
+#else
+
+/*---------------------------------------------------------------------*/
+/*2
+* signal handler for run time errors, general version
+*/
+void sigsegv_handler(int sig)
+{
+  fprintf(stderr,"Singular : signal %d (v: %d):\n",
+    sig,SINGULAR_VERSION);
+  if (sig!=SIGINT)
+  {
+    fprintf(stderr,"current line:>>%s<<\n",my_yylinebuf);
+    fprintf(stderr,"Segment fault/Bus error occurred (r:%d)\n"
+                   "please inform the authors\n",
+                   siRandomStart);
+  }
+  #ifdef __OPTIMIZE__
+  if(si_restart<3)
+  {
+    si_restart++;
+    fprintf(stderr,"trying to restart...\n");
+    init_signals();
+    longjmp(si_start_jmpbuf,1);
+  }
+  #endif /* __OPTIMIZE__ */
+  #if defined(unix)
+  #ifdef CALL_GDB
+  if (sig!=SIGINT) debug(STACK_TRACE);
+  #endif /* CALL_GDB */
+  #endif /* unix */
+  exit(0);
+}
+#endif
+
+
+/*2
+* signal handler for SIGINT
+*/
+int sigint_handler_cnt=0;
+void sigint_handler(int /*sig*/)
+{
+  mflush();
+  #ifdef HAVE_FEREAD
+  if (fe_is_raw_tty) fe_temp_reset();
+  #endif /* HAVE_FEREAD */
+  char default_opt=' ';
+  if ((feOptSpec[FE_OPT_CNTRLC].value!=NULL)
+      && ((char*)(feOptSpec[FE_OPT_CNTRLC].value))[0])
+  { default_opt=((char*)(feOptSpec[FE_OPT_CNTRLC].value))[0]; }
+  loop
+  {
+    int cnt=0;
+    int c;
+
+    if (singular_in_batchmode)
+    {
+      c = 'q';
+    }
+    else if (default_opt!=' ')
+    {
+      c = default_opt;
+    }
+    else
+    {
+      fprintf(stderr,"// ** Interrupt at cmd:`%s` in line:'%s'\n",
+        Tok2Cmdname(iiOp),my_yylinebuf);
+      if (feOptValue(FE_OPT_EMACS) == NULL)
+      {
+        fputs("abort after this command(a), abort immediately(r), print backtrace(b), continue(c) or quit Singular(q) ?",stderr);fflush(stderr);
+        c = fgetc(stdin);
+      }
+      else
+      {
+        c = 'a';
+      }
+    }
+
+    switch(c)
+    {
+      case 'q': case EOF:
+                m2_end(2);
+      case 'r':
+                if (sigint_handler_cnt<3)
+                {
+                  sigint_handler_cnt++;
+                  fputs("** Warning: Singular should be restarted as soon as possible **\n",stderr);
+                  fflush(stderr);
+                  longjmp(si_start_jmpbuf,1);
+                }
+                else
+                {
+                  fputs("** tried too often, try another possibility **\n",stderr);
+                  fflush(stderr);
+                }
+                break;
+      case 'b':
+                VoiceBackTrack();
+                break;
+      case 'a':
+                siCntrlc++;
+      case 'c':
+                if ((feOptValue(FE_OPT_EMACS) == NULL) && (default_opt!=' '))
+                {
+                  /* Read until a newline or EOF */
+                  while (c != EOF && c != '\n') c = fgetc(stdin);
+                }
+                si_set_signal(SIGINT ,(si_hdl_typ)sigint_handler);
+                return;
+                //siCntrlc ++;
+                //if (siCntrlc>2) si_set_signal(SIGINT,(si_hdl_typ) sigsegv_handler);
+                //else            si_set_signal(SIGINT,(si_hdl_typ) sigint_handler);
+    }
+    cnt++;
+    if(cnt>5) m2_end(2);
+  }
+}
+
+//void test_int()
+//{
+//  if (siCntrlc!=0)
+//  {
+//    int saveecho = si_echo;
+//    siCntrlc = FALSE;
+//    si_set_signal(SIGINT ,sigint_handler);
+//    iiDebug();
+//    si_echo = saveecho;
+//  }
+//}
+
+#ifdef unix
+#  ifndef __OPTIMIZE__
+volatile int si_stop_stack_trace_x;
+#    ifdef CALL_GDB
+static void debug (int method)
+{
+  if (feOptValue(FE_OPT_NO_TTY))
+  {
+    dReportError("Caught Signal 11");
+    return;
+  }
+  int pid;
+  char buf[16];
+  char * args[4] = { (char*)"gdb", (char*)"Singular", NULL, NULL };
+
+  #ifdef HAVE_FEREAD
+  if (fe_is_raw_tty) fe_temp_reset();
+  #endif /* HAVE_FEREAD */
+
+  sprintf (buf, "%d", getpid ());
+
+  args[2] = buf;
+
+  pid = fork ();
+  if (pid == 0)
+  {
+    switch (method)
+    {
+      case INTERACTIVE:
+        fprintf (stderr, "\n\nquit with \"p si_stop_stack_trace_x=0\"\n\n\n");
+        debug_stop (args);
+        break;
+      case STACK_TRACE:
+        fprintf (stderr, "stack_trace\n");
+        stack_trace (args);
+        break;
+      default:
+        // should not be reached:
+        exit(1);
+    }
+  }
+  else if (pid == -1)
+  {
+    perror ("could not fork");
+    return;
+  }
+
+  si_stop_stack_trace_x = 1;
+  while (si_stop_stack_trace_x) ;
+}
+
+static void debug_stop (char *const*args)
+{
+  execvp (args[0], args);
+  perror ("exec failed");
+  _exit (0);
+}
+#    endif /* CALL_GDB */
+
+static void stack_trace (char *const*args)
+{
+  int pid;
+  int in_fd[2];
+  int out_fd[2];
+  fd_set fdset;
+  fd_set readset;
+  struct timeval tv;
+  int sel, index, state;
+  char buffer[256];
+  char c;
+
+  if ((pipe (in_fd) == -1) || (pipe (out_fd) == -1))
+  {
+    perror ("could open pipe");
+    m2_end(999);
+  }
+
+  pid = fork ();
+  if (pid == 0)
+  {
+    si_close (0); si_dup2 (in_fd[0],0);   /* set the stdin to the in pipe */
+    si_close (1); si_dup2 (out_fd[1],1);  /* set the stdout to the out pipe */
+    si_close (2); si_dup2 (out_fd[1],2);  /* set the stderr to the out pipe */
+
+    execvp (args[0], args);      /* exec gdb */
+    perror ("exec failed");
+    m2_end(999);
+  }
+  else if (pid == -1)
+  {
+    perror ("could not fork");
+    m2_end(999);
+  }
+
+  FD_ZERO (&fdset);
+  FD_SET (out_fd[0], &fdset);
+
+  si_write (in_fd[1], "backtrace\n", 10);
+  si_write (in_fd[1], "p si_stop_stack_trace_x = 0\n", 28);
+  si_write (in_fd[1], "quit\n", 5);
+
+  index = 0;
+  state = 0;
+
+  loop
+  {
+    readset = fdset;
+    tv.tv_sec = 1;
+    tv.tv_usec = 0;
+
+    sel = si_select (FD_SETSIZE, &readset, NULL, NULL, &tv);
+    if (sel == -1)
+      break;
+
+    if ((sel > 0) && (FD_ISSET (out_fd[0], &readset)))
+    {
+      if (si_read (out_fd[0], &c, 1))
+      {
+        switch (state)
+        {
+          case 0:
+            if (c == '#')
+            {
+              state = 1;
+              index = 0;
+              buffer[index++] = c;
+            }
+            break;
+          case 1:
+            buffer[index++] = c;
+            if ((c == '\n') || (c == '\r'))
+            {
+              buffer[index] = 0;
+              fprintf (stderr, "%s", buffer);
+              state = 0;
+              index = 0;
+            }
+            break;
+          default:
+            break;
+        }
+      }
+    }
+    else if (si_stop_stack_trace_x==0)
+      break;
+  }
+
+  si_close (in_fd[0]);
+  si_close (in_fd[1]);
+  si_close (out_fd[0]);
+  si_close (out_fd[1]);
+  m2_end(0);
+}
+
+#  endif /* !__OPTIMIZE__ */
+#endif /* unix */
+
+/*2
+* init signal handlers
+*/
+void init_signals()
+{
+  #ifdef SIGSEGV
+  si_set_signal(SIGSEGV,(si_hdl_typ)sigsegv_handler);
+  #endif
+  #ifdef SIGBUS
+  si_set_signal(SIGBUS, (si_hdl_typ)sigsegv_handler);
+  #endif
+  #ifdef SIGFPE
+  si_set_signal(SIGFPE, (si_hdl_typ)sigsegv_handler);
+  #endif
+  #ifdef SIGILL
+  si_set_signal(SIGILL, (si_hdl_typ)sigsegv_handler);
+  #endif
+  #ifdef SIGIOT
+  si_set_signal(SIGIOT, (si_hdl_typ)sigsegv_handler);
+  #endif
+  si_set_signal(SIGINT ,(si_hdl_typ)sigint_handler);
+  si_set_signal(SIGCHLD, (si_hdl_typ)sig_chld_hdl);
+  si_set_signal(SIGPIPE, (si_hdl_typ)sig_pipe_hdl);
+  si_set_signal(SIGTERM, (si_hdl_typ)sig_term_hdl);
+}
+
diff --git a/Singular/cntrlc.h b/Singular/cntrlc.h
new file mode 100644
index 0000000..97a7f31
--- /dev/null
+++ b/Singular/cntrlc.h
@@ -0,0 +1,26 @@
+#ifndef CNTRLC_H
+#define CNTRLC_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT - interupt and signal handling
+*/
+#include <setjmp.h>
+#include <misc/auxiliary.h>
+#include <kernel/structs.h>
+
+extern jmp_buf si_start_jmpbuf;
+extern short si_restart;
+extern int siRandomStart;
+extern BOOLEAN siCntrlc;
+void init_signals();
+
+extern BOOLEAN singular_in_batchmode;
+/* TRUE for child of a fork or started with --batch*/
+
+/* for deferring the call of m2_end() in SIGTERM handler if necessary */
+extern volatile BOOLEAN do_shutdown;
+extern volatile int defer_shutdown;
+
+#endif
diff --git a/Singular/countedref.cc b/Singular/countedref.cc
new file mode 100644
index 0000000..a4faafa
--- /dev/null
+++ b/Singular/countedref.cc
@@ -0,0 +1,749 @@
+// -*- c++ -*-
+//*****************************************************************************
+/** @file countedref.cc
+ *
+ * @author Alexander Dreyer
+ * @date 2012-08-15
+ *
+ * This file defines reference countes interpreter objects and adds the
+ * @c blackbox operations for high-level types 'reference' and 'shared'.
+ *
+ * @note This works was supported by the "Industrial Algebra" project.
+ *
+ * @par Copyright:
+ *   (c) 2012 by The Singular Team, see LICENSE file
+**/
+//*****************************************************************************
+
+
+
+
+
+#include <kernel/mod2.h>
+
+#include "ipid.h"
+
+#include "countedref.h"
+
+#include "blackbox.h"
+#include "newstruct.h"
+#include "ipshell.h"
+
+
+/// Overloading ring destruction
+inline void CountedRefPtr_kill(ring r) { rKill(r); }
+
+
+/** @class CountedRefData
+ * This class stores a reference counter as well as a Singular interpreter object.
+ * It also take care of the context, e.g. the current ring, wrap object, etc.
+ **/
+class CountedRefData:
+  public RefCounter {
+  typedef CountedRefData self;
+public:
+  typedef CountedRefWeakPtr<self*> back_ptr;
+private:
+  typedef RefCounter base;
+
+  /// Generate object linked to other reference (e.g. for subscripts)
+  CountedRefData(leftv wrapid, back_ptr back):
+    base(), m_data(wrapid), m_ring(back->m_ring), m_back(back) {
+  }
+
+  /// @name Disallow copying to avoid inconsistence
+  //@{
+  self& operator=(const self&);
+  CountedRefData(const self&);
+  //@}
+
+public:
+  typedef LeftvDeep::copy_tag copy_tag;
+
+  /// Fix smart pointer type to referenced data
+  typedef back_ptr::ptr_type ptr_type;
+
+  /// Fix smart pointer type to ring
+  typedef CountedRefPtr<ring, true> ring_ptr;
+
+  /// Construct shared memory empty Singular object
+  explicit CountedRefData():
+    base(), m_data(), m_ring(), m_back() { }
+
+  /// Reference Singular object
+  explicit CountedRefData(leftv data):
+    base(), m_data(data), m_ring(parent(data)), m_back() { }
+
+  /// Construct reference for Singular object
+  CountedRefData(leftv data, copy_tag do_copy):
+    base(), m_data(data, do_copy), m_ring(parent(data)), m_back() { }
+
+  /// Destruct
+  ~CountedRefData() {
+    if (!m_back.unassigned()) {
+      if (m_back == this)
+        m_back.invalidate();
+      else
+        m_data.clearid(root());
+    }
+  }
+
+  /// Generate object for indexing
+  ptr_type wrapid() { return new self(m_data.idify(root()), weakref()); }
+
+  /// Gerenate  weak (but managed) reference to @c *this
+  back_ptr weakref() {
+    if (m_back.unassigned())
+      m_back = this;
+    return m_back;
+  }
+  /// Replace with other Singular data
+  self& operator=(leftv rhs) {
+    m_data = rhs;
+    m_ring = parent(rhs);
+    return *this;
+  }
+
+  /// Write (shallow) copy to given handle
+  BOOLEAN put(leftv res) { return broken() || m_data.put(res);  }
+
+  /// Extract (shallow) copy of stored data
+  LeftvShallow operator*() const { return (broken()? LeftvShallow(): (const LeftvShallow&)m_data); }
+
+  /// Determine active ring when ring dependency changes
+  BOOLEAN rering() {
+    if (m_ring ^ m_data.ringed()) m_ring = (m_ring? NULL: currRing);
+    return (m_back && (m_back != this) && m_back->rering());
+  }
+
+  /// Get the current context
+  idhdl* root() { return  (m_ring? &m_ring->idroot: &IDROOT); }
+
+  /// Check whether identifier became invalid
+  BOOLEAN broken() const {
+    if (!m_back.unassigned() && !m_back)
+      return complain("Back-reference broken");
+
+    if (m_ring) {
+      if (m_ring != currRing)
+        return complain("Referenced identifier not from current ring");
+
+      return m_data.isid()  && m_data.brokenid(currRing->idroot) &&
+        complain("Referenced identifier not available in ring anymore");
+    }
+
+    if (!m_data.isid()) return FALSE;
+    return  m_data.brokenid(IDROOT) &&
+     ((currPack == basePack) ||  m_data.brokenid(basePack->idroot)) &&
+     complain("Referenced identifier not available in current context");
+  }
+
+  /// Reassign actual object
+  BOOLEAN assign(leftv result, leftv arg) {
+
+    if (!m_data.isid()) {
+      (*this) = arg;
+      return FALSE;
+    }
+    return put(result) || iiAssign(result, arg) || rering();
+  }
+  /// Recover additional information (e.g. subexpression) from likewise object
+  BOOLEAN retrieve(leftv res) { return m_data.retrieve(res); }
+
+  /// Check whether data is all-zero
+  BOOLEAN unassigned() const { return m_data.unassigned(); }
+
+private:
+  /// Raise error message and return @c TRUE
+  BOOLEAN complain(const char* text) const
+  {
+    WerrorS(text);
+    return TRUE;
+  }
+
+  /// Store ring for ring-dependent objects
+  static ring parent(leftv rhs)
+  {
+    return (rhs->RingDependend()? currRing: NULL);
+  }
+
+protected:
+  /// Singular object
+  LeftvDeep m_data;
+
+  /// Store namespace for ring-dependent objects
+  ring_ptr m_ring;
+
+  /// Reference to actual object for wrap structures
+  back_ptr m_back;
+};
+
+/// Supporting smart pointer @c CountedRefPtr
+inline void CountedRefPtr_kill(CountedRefData* data) { delete data; }
+
+
+/// blackbox support - initialization
+void* countedref_Init(blackbox*)
+{
+  return NULL;
+}
+
+/// We use the function pointer as a marker of reference types
+/// for CountedRef::is_ref(leftv), see the latter for details
+BOOLEAN countedref_CheckAssign(blackbox */*b*/, leftv /*L*/, leftv /*R*/)
+{
+  return FALSE;
+}
+
+
+class CountedRef {
+  typedef CountedRef self;
+
+public:
+  /// name type for identifiers
+  typedef int id_type;
+
+  /// Name type for handling referenced data
+  typedef CountedRefData data_type;
+
+  /// Fix smart pointer type to referenced data
+  typedef CountedRefPtr<CountedRefData*> data_ptr;
+
+  /// Check whether argument is already a reference type
+  /// @note We check for the function pointer @c countedref_CheckAssign here,
+  /// that we (ab-)use as a unique marker. This avoids to check a bunch of
+  /// of runtime-varying @c typ IDs for identifying reference-like types.
+  static BOOLEAN is_ref(leftv arg) {
+    int typ = arg->Typ();
+    return ((typ > MAX_TOK) &&
+            (getBlackboxStuff(typ)->blackbox_CheckAssign == countedref_CheckAssign));
+  }
+
+  /// Reference given Singular data
+  explicit CountedRef(leftv arg):  m_data(new data_type(arg)) { }
+
+protected:
+  /// Recover previously constructed reference
+  CountedRef(data_ptr arg):  m_data(arg) { assume(arg); }
+
+public:
+  /// Construct copy
+  CountedRef(const self& rhs): m_data(rhs.m_data) { }
+
+  /// Replace reference
+  self& operator=(const self& rhs) {
+    m_data = rhs.m_data;
+    return *this;
+  }
+
+  BOOLEAN assign(leftv result, leftv arg) {
+    return m_data->assign(result,arg);
+  }
+
+  /// Extract (shallow) copy of stored data
+  LeftvShallow operator*() { return m_data->operator*(); }
+
+  /// Construct reference data object marked by given identifier number
+  BOOLEAN outcast(leftv res, int typ) {
+    res->rtyp = typ;
+    return outcast(res);
+  }
+
+  /// Construct reference data object from *this
+  BOOLEAN outcast(leftv res) {
+    if (res->rtyp == IDHDL)
+      IDDATA((idhdl)res->data) = (char *)outcast();
+    else
+      res->data = (void *)outcast();
+    return FALSE;
+  }
+
+  /// Construct raw reference data
+  data_type* outcast() {
+    m_data.reclaim();
+    return m_data;
+  }
+
+  /// Kills a link to the referenced object
+  void destruct() { m_data.release(); }
+
+  /// Kills the link to the referenced object
+  ~CountedRef() { }
+
+  /// Replaces argument by a shallow copy of the references data
+  BOOLEAN dereference(leftv arg) {
+    m_data.reclaim();
+    BOOLEAN b= m_data->put(arg) || ((arg->next != NULL) && resolve(arg->next));
+    m_data.release();
+    return b;
+  }
+
+  /// Check whether object in valid in current context
+  BOOLEAN broken() {return m_data->broken(); }
+
+  /// Check whether (shared) data was initialized but not assigned yet.
+  BOOLEAN unassigned() const { return m_data->unassigned(); }
+
+  /// Get number of references pointing here, too
+  BOOLEAN count(leftv res) { return construct(res, m_data.count() - 1); }
+
+  // Get internal indentifier
+  BOOLEAN enumerate(leftv res) { return construct(res, (long)(data_type*)m_data); }
+
+  /// Check for likewise identifiers
+  BOOLEAN likewise(leftv res, leftv arg) {
+    return resolve(arg) || construct(res, operator*()->data == arg->data);
+  }
+
+  /// Check for identical reference objects
+  BOOLEAN same(leftv res, leftv arg) {
+    return construct(res, m_data == arg->Data());
+  }
+
+  /// Get type of references data
+  BOOLEAN type(leftv res) {
+    return construct(res, Tok2Cmdname(operator*()->Typ()));
+  };
+
+  /// Get (possibly) internal identifier name
+  BOOLEAN name(leftv res) { return construct(res, operator*()->Name()); }
+
+  /// Recover the actual object from raw Singular data
+  static self cast(void* data) {
+    assume(data != NULL);
+    return self(static_cast<data_type*>(data));
+  }
+
+  /// Recover the actual object from Singular interpreter object
+  static self cast(leftv arg) {
+    assume(arg != NULL); assume(is_ref(arg));
+    return self::cast(arg->Data());
+  }
+
+  /// If necessary dereference.
+  static BOOLEAN resolve(leftv arg) {
+    assume(arg != NULL);
+    while (is_ref(arg)) { if(CountedRef::cast(arg).dereference(arg)) return TRUE; };
+    return (arg->next != NULL) && resolve(arg->next);
+  }
+
+  /// Construct integer value
+  static BOOLEAN construct(leftv res, long data) {
+    res->data = (void*) data;
+    res->rtyp = INT_CMD;
+    return FALSE;
+  }
+
+  /// Construct string
+  static BOOLEAN construct(leftv res, const char* data) {
+    res->data = (void*)omStrDup(data);
+    res->rtyp = STRING_CMD;
+    return FALSE;
+  }
+  /// Construct void-style object
+  static BOOLEAN construct(leftv res) {
+    res->data = NULL;
+    res->rtyp = NONE;
+    return FALSE;
+  }
+
+protected:
+  /// Store pointer to actual data
+  data_ptr m_data;
+};
+
+/// blackbox support - convert to string representation
+void countedref_Print(blackbox */*b*/, void* ptr)
+{
+  if (ptr) (*CountedRef::cast(ptr))->Print();
+  else PrintS("<unassigned reference or shared memory>");
+}
+
+/// blackbox support - convert to string representation
+char* countedref_String(blackbox */*b*/, void* ptr)
+{
+  if (ptr == NULL) return omStrDup(sNoName);
+  return (*CountedRef::cast(ptr))->String();
+}
+
+/// blackbox support - copy element
+void* countedref_Copy(blackbox*/*b*/, void* ptr)
+{
+  if (ptr) return CountedRef::cast(ptr).outcast();
+  return NULL;
+}
+
+/// blackbox support - assign element
+BOOLEAN countedref_Assign(leftv result, leftv arg)
+{
+  // Case: replace assignment behind reference
+  if (result->Data() != NULL) {
+    CountedRef ref = CountedRef::cast(result);
+    return CountedRef::resolve(arg) || ref.assign(result, arg);
+  }
+
+  // Case: copy reference
+  if (result->Typ() == arg->Typ())
+    return CountedRef::cast(arg).outcast(result);
+
+  // Case: new reference
+  if ((arg->rtyp == IDHDL) || CountedRef::is_ref(arg))
+    return CountedRef(arg).outcast(result);
+
+  WerrorS("Can only take reference from identifier");
+  return TRUE;
+}
+
+BOOLEAN countedref_CheckInit(leftv res, leftv arg)
+{
+  if (arg->Data() != NULL) return FALSE;
+  res->rtyp = NONE;
+  WerrorS("Noninitialized access");
+  return TRUE;
+}
+
+/// blackbox support - unary operations
+BOOLEAN countedref_Op1(int op, leftv res, leftv head)
+{
+  if(op == TYPEOF_CMD)
+    return blackboxDefaultOp1(op, res, head);
+
+  if (countedref_CheckInit(res, head)) return TRUE;
+
+  if ((op == DEF_CMD) || (op == head->Typ()))
+  {
+    res->rtyp = head->Typ();
+    return iiAssign(res, head);
+  }
+
+  CountedRef ref = CountedRef::cast(head);
+  return ref.dereference(head) ||
+    iiExprArith1(res, head, op == LINK_CMD? head->Typ(): op);
+}
+
+
+
+/// blackbox support - binary operations (resolve seocnd argument)
+static BOOLEAN countedref_Op2_(int op, leftv res, leftv head, leftv arg)
+{
+  if (CountedRef::is_ref(arg))
+  {
+    CountedRef ref = CountedRef::cast(arg);
+    return ref.dereference(arg) || iiExprArith2(res, head, op, arg);
+  }
+  return  iiExprArith2(res, head, op, arg);
+}
+
+BOOLEAN countedref_Op2(int op, leftv res, leftv head, leftv arg)
+{
+  if (countedref_CheckInit(res, head)) return TRUE;
+  if (CountedRef::is_ref(head))
+  {
+    CountedRef ref = CountedRef::cast(head);
+    return ref.dereference(head) || countedref_Op2_(op, res, head, arg);
+  }
+  return countedref_Op2_(op, res, head, arg);
+}
+
+static BOOLEAN countedref_Op3__(int op, leftv res, leftv head, leftv arg1, leftv arg2)
+{
+
+  if (CountedRef::is_ref(arg2))
+  {
+    CountedRef ref = CountedRef::cast(arg2);
+    return ref.dereference(arg2) || iiExprArith3(res, op, head, arg1, arg2);
+  }
+  return iiExprArith3(res, op, head, arg1, arg2);
+}
+
+static BOOLEAN countedref_Op3_(int op, leftv res, leftv head, leftv arg1, leftv arg2)
+{
+  if (CountedRef::is_ref(arg1))
+  {
+    CountedRef ref = CountedRef::cast(arg1);
+    return ref.dereference(arg1) || countedref_Op3__(op, res, head, arg1, arg2);
+  }
+  return countedref_Op3__(op, res, head, arg1, arg2);
+}
+
+
+/// blackbox support - ternary operations
+BOOLEAN countedref_Op3(int op, leftv res, leftv head, leftv arg1, leftv arg2)
+{
+  if (countedref_CheckInit(res, head)) return TRUE;
+  if (CountedRef::is_ref(head))
+  {
+    CountedRef ref = CountedRef::cast(head);
+    return ref.dereference(head) || countedref_Op3_(op, res, head, arg1, arg2);
+  }
+  return countedref_Op3_(op, res, head, arg1, arg2);
+}
+
+
+/// blackbox support - destruction
+void countedref_destroy(blackbox */*b*/, void* ptr)
+{
+  if (ptr) CountedRef::cast(ptr).destruct();
+}
+
+
+class CountedRefShared:
+  public CountedRef
+  {
+  typedef CountedRefShared self;
+  typedef CountedRef base;
+
+  /// Reinterprete @c CountedRef as @c CountedRefShared
+  CountedRefShared(const base& rhs):  base(rhs) { }
+
+  /// Generate from data pointer
+  CountedRefShared(data_ptr rhs):  base(rhs) { }
+
+public:
+  /// Default constructor for initialized, but all-zero, shared data object
+  CountedRefShared():  base(new data_type) { }
+
+  /// Construct internal copy of Singular interpreter object
+  explicit CountedRefShared(leftv arg):  base(new data_type(arg, data_type::copy_tag())) { }
+
+  /// Construct new reference to internal data
+  CountedRefShared(const self& rhs): base(rhs) { }
+
+  /// Desctruct
+  ~CountedRefShared() { }
+
+  /// Change reference to shared data
+  self& operator=(const self& rhs) {
+    return static_cast<self&>(base::operator=(rhs));
+  }
+
+  /// Recovering outcasted @c CountedRefShared object from interpreter object
+  static self cast(leftv arg) { return base::cast(arg); }
+
+  /// Recovering outcasted @c CountedRefShared object from raw data
+  static self cast(void* arg) { return base::cast(arg); }
+
+  /// Temporarily wrap with identifier for '[' and '.' operation
+  self wrapid() { return self(m_data->wrapid()); }
+
+  /// Generate weak reference (may get invalid)
+  data_type::back_ptr weakref() { return m_data->weakref(); }
+
+  /// Recover more information (e.g. subexpression data) from computed result
+  BOOLEAN retrieve(leftv res, int typ)
+  {
+    return (m_data->retrieve(res) && outcast(res, typ));
+  }
+};
+
+/// Blackbox support - generate initialized, but all-zero - shared data
+void* countedref_InitShared(blackbox*)
+{
+  return CountedRefShared().outcast();
+}
+
+/// Blackbox support - unary operation for shared data
+BOOLEAN countedref_Op1Shared(int op, leftv res, leftv head)
+{
+  if(op == TYPEOF_CMD)
+    return blackboxDefaultOp1(op, res, head);
+
+  if (countedref_CheckInit(res, head)) return TRUE;
+
+  if ((op == DEF_CMD) || (op == head->Typ()))
+  {
+    res->rtyp = head->Typ();
+    return iiAssign(res, head);
+  }
+
+  CountedRefShared ref = CountedRefShared::cast(head);
+
+  if (op == LINK_CMD)
+  {
+    if (ref.dereference(head)) return TRUE;
+    res->Copy(head);
+    return (res->Typ() == NONE);
+  }
+
+  CountedRefShared wrap = ref.wrapid();
+  int typ = head->Typ();
+  return wrap.dereference(head) || iiExprArith1(res, head, op) ||
+    wrap.retrieve(res, typ);
+}
+
+
+/// blackbox support - binary operations
+BOOLEAN countedref_Op2Shared(int op, leftv res, leftv head, leftv arg)
+{
+  if (countedref_CheckInit(res, head))  return TRUE;
+
+  if (CountedRefShared::is_ref(head))
+  {
+    CountedRefShared wrap = CountedRefShared::cast(head).wrapid();
+    int typ = head->Typ();
+    return wrap.dereference(head) || countedref_Op2_(op, res, head, arg) ||
+      wrap.retrieve(res, typ);
+  }
+
+  return countedref_Op2_(op, res, head, arg);
+}
+
+/// blackbox support - n-ary operations
+BOOLEAN countedref_OpM(int op, leftv res, leftv args)
+{
+  if (args->Data() == NULL) return FALSE;
+
+  if(op == SYSTEM_CMD)
+  {
+    if (args->next)
+    {
+      leftv next = args->next;
+      args->next = NULL;
+
+      char* name = (next->Typ() == STRING_CMD?
+                    (char*) next->Data(): (char*)next->Name());
+      next = next->next;
+
+      if (strcmp(name, "help") == 0)
+      {
+        PrintS("system(<ref>, ...): extended functionality for reference/shared data <ref>\n");
+        PrintS("  system(<ref>, count)         - number of references pointing to <ref>\n");
+        PrintS("  system(<ref>, enumerate)     - unique number for identifying <ref>\n");
+        PrintS("  system(<ref>, undefined)     - checks whether <ref> had been assigned\n");
+        PrintS("  system(<ref>, \"help\")        - prints this information message\n");
+        PrintS("  system(<ref>, \"typeof\")      - actual type referenced by <ref>\n");
+        PrintS("  system(<ref1>, same, <ref2>) - tests for identic reference objects\n");
+        return CountedRef::construct(res);
+      }
+      if (strncmp(name, "undef", 5) == 0)
+      {
+        return CountedRef::construct(res, args->Data()?
+                          (CountedRef::cast(args).unassigned()? 1: 2): 0);
+      }
+
+      CountedRef obj = CountedRef::cast(args);
+      if (next)
+      {
+        if (strcmp(name, "same") == 0) return obj.same(res, next);
+        // likewise may be hard to interprete, so we not not document it above
+        if (strncmp(name, "like", 4) == 0) return obj.likewise(res, next);
+      }
+      if (strncmp(name, "count", 5) == 0) return obj.count(res);
+      if (strncmp(name, "enum", 4) == 0) return obj.enumerate(res);
+      if (strcmp(name, "name") == 0) return obj.name(res); // undecumented
+      if (strncmp(name, "typ", 3) == 0) return obj.type(res);
+    }
+    return TRUE;
+  }
+  if (op == LIST_CMD)
+  {
+    res->rtyp = op;
+    return jjLIST_PL(res, args);
+  }
+  CountedRef ref = CountedRef::cast(args);
+  return ref.dereference(args) || iiExprArithM(res, args, op);
+}
+
+/// blackbox support - assign element
+BOOLEAN countedref_AssignShared(leftv result, leftv arg)
+{
+  /// Case: replace assignment behind reference
+  if ((result->Data() != NULL)  && !CountedRefShared::cast(result).unassigned()) {
+    CountedRef ref = CountedRef::cast(result);
+    return CountedRef::resolve(arg) || ref.assign(result, arg);
+  }
+
+  /// Case: new reference to already shared data
+  if (result->Typ() == arg->Typ())
+  {
+    if (result->Data() != NULL)
+      CountedRefShared::cast(result).destruct();
+    return CountedRefShared::cast(arg).outcast(result);
+  }
+  if(CountedRefShared::cast(result).unassigned())
+  {
+    return CountedRefShared::cast(result).assign(result, arg);
+  }
+
+  /// Case: new shared data
+  return CountedRefShared(arg).outcast(result);
+}
+
+/// blackbox support - destruction
+void countedref_destroyShared(blackbox */*b*/, void* ptr)
+{
+  if (ptr) CountedRefShared::cast(ptr).destruct();
+}
+
+
+BOOLEAN countedref_serialize(blackbox */*b*/, void *d, si_link f)
+{
+  sleftv l;
+  memset(&l,0,sizeof(l));
+  l.rtyp = STRING_CMD;
+  l.data = (void*)omStrDup("shared"); // references are converted
+  f->m->Write(f, &l);
+  CountedRefShared::cast(d).dereference(&l);
+  f->m->Write(f, &l);
+  return FALSE;
+}
+
+BOOLEAN countedref_deserialize(blackbox **/*b*/, void **d, si_link f)
+{
+  // rtyp must be set correctly (to the blackbox id) by routine calling
+  leftv data=f->m->Read(f);
+  CountedRefShared sh(data);
+  *d = sh.outcast();
+  return FALSE;
+}
+
+void countedref_reference_load()
+{
+  int tok;
+  if (blackboxIsCmd("reference", tok) == ROOT_DECL)
+    return;
+
+  blackbox *bbx = (blackbox*)omAlloc0(sizeof(blackbox));
+  bbx->blackbox_CheckAssign = countedref_CheckAssign;
+  bbx->blackbox_destroy = countedref_destroy;
+  bbx->blackbox_String  = countedref_String;
+  bbx->blackbox_Print  = countedref_Print;
+  bbx->blackbox_Init    = countedref_Init;
+  bbx->blackbox_Copy    = countedref_Copy;
+  bbx->blackbox_Assign  = countedref_Assign;
+  bbx->blackbox_Op1     = countedref_Op1;
+  bbx->blackbox_Op2     = countedref_Op2;
+  bbx->blackbox_Op3     = countedref_Op3;
+  bbx->blackbox_OpM     = countedref_OpM;
+  bbx->blackbox_serialize   = countedref_serialize;
+  bbx->blackbox_deserialize = countedref_deserialize;
+  bbx->data             = omAlloc0(newstruct_desc_size());
+  setBlackboxStuff(bbx, "reference");
+}
+
+void countedref_shared_load()
+{
+  int tok;
+  if (blackboxIsCmd("shared", tok) == ROOT_DECL)
+    return;
+
+  blackbox *bbxshared = (blackbox*)omAlloc0(sizeof(blackbox));
+  bbxshared->blackbox_String  = countedref_String;
+  bbxshared->blackbox_Print  = countedref_Print;
+  bbxshared->blackbox_Copy    = countedref_Copy;
+  bbxshared->blackbox_Op3     = countedref_Op3;
+  bbxshared->blackbox_OpM     = countedref_OpM;
+  bbxshared->blackbox_serialize   = countedref_serialize;
+  bbxshared->blackbox_deserialize = countedref_deserialize;
+
+  bbxshared->blackbox_CheckAssign = countedref_CheckAssign;
+  bbxshared->blackbox_Assign  = countedref_AssignShared;
+  bbxshared->blackbox_destroy = countedref_destroyShared;
+  bbxshared->blackbox_Op1     = countedref_Op1Shared;
+  bbxshared->blackbox_Op2     = countedref_Op2Shared;
+  bbxshared->blackbox_Init    = countedref_InitShared;
+  bbxshared->data             = omAlloc0(newstruct_desc_size());
+  setBlackboxStuff(bbxshared, "shared");
+}
+
+
diff --git a/Singular/countedref.h b/Singular/countedref.h
new file mode 100644
index 0000000..b2b1480
--- /dev/null
+++ b/Singular/countedref.h
@@ -0,0 +1,466 @@
+// -*- c++ -*-
+//*****************************************************************************
+/** @file countedref.h
+ *
+ * This file defines reusable classes supporting reference counted interpreter
+ * objects and initiates the @c blackbox operations for high-level types
+ * 'reference' and 'shared'.
+ *
+ * @note This works was supported by the "Industrial Algebra" project.
+ *
+ * @author Alexander Dreyer
+ * @date 2012-08-15
+ *
+ * @par Copyright:
+ *   (c) 2012 by The Singular Team, see LICENSE file
+**/
+//*****************************************************************************
+
+
+#ifndef SINGULAR_COUNTEDREF_H_
+#define SINGULAR_COUNTEDREF_H_
+
+#include <omalloc/omalloc.h>
+#include <kernel/structs.h>
+#include <Singular/subexpr.h>
+#include <Singular/idrec.h>
+#include <Singular/ipid.h>
+/** @class CountedRefPtr
+ * This class implements a smart pointer which handles pointer-style access
+ * to a reference-counted structure and destructing the latter after use.
+ *
+ * The template arguments, include the pointer type @c PtrType, and two
+ * integral (bool) properties: use @c Nondestructive to disallow destruction
+ * and @c NeverNull to assume, that @c PtrType cannot be @c NULL.
+ * Finally, @c CountType allows you to select a typ to represent the internal reference count.
+ *
+ * @note The class of @c PtrType must have an accessible integral attribute @c ref.
+ * For convenience use @c RefCounter as public base.
+ * In addition you must overload @c void CountedRefPtr_kill(PtrType) accordingly.
+ **/
+template <class PtrType, bool Nondestructive = false, bool NeverNull = false,
+          class CountType = short>
+class CountedRefPtr {
+  typedef CountedRefPtr self;
+
+public:
+  //{ @name Name template arguments
+  typedef PtrType ptr_type;
+  typedef CountType count_type;
+  enum { nondestructive = Nondestructive, never_null = NeverNull };
+  //}
+
+  /// Default constructor @note: exisis only if @c NeverNull is false
+  CountedRefPtr(): m_ptr(NULL) {}
+
+  /// Convert from pointer
+  CountedRefPtr(ptr_type ptr): m_ptr(ptr) { reclaim(); }
+
+  /// Convert from compatible smart pointer
+  template <bool Never>
+  CountedRefPtr(const CountedRefPtr<ptr_type, !nondestructive, Never, count_type>& rhs):
+    m_ptr(rhs.m_ptr) { reclaim(); }
+
+  /// Construct refernce copy
+  CountedRefPtr(const self& rhs):
+    m_ptr(rhs.m_ptr) { reclaim(); }
+
+  /// Unlink one reference
+  ~CountedRefPtr() { release(); }
+
+  //{ @name Replace data behind reference
+  self& operator=(const self& rhs) { return operator=(rhs.m_ptr); }
+  self& operator=(ptr_type ptr) {
+    release();
+    m_ptr = ptr;
+    reclaim();
+    return *this;
+  }
+  //}
+
+  /// Checking equality
+  bool operator==(const self& rhs) const { return m_ptr == rhs.m_ptr; }
+
+  //{ @name Pointer-style interface
+  bool operator==(ptr_type ptr) const { return m_ptr == ptr; }
+  operator bool() const { return NeverNull || m_ptr; }
+  operator const ptr_type() const { return m_ptr; }
+  operator ptr_type() { return m_ptr; }
+  const ptr_type operator->() const { return *this; }
+  ptr_type operator->() { return *this; }
+  //}
+
+  /// @name Reference count interface
+  //@{
+  count_type count() const { return (*this? m_ptr->ref: 0); }
+  void reclaim() { if (*this) ++m_ptr->ref; }
+  void release() {
+    if (*this && (--m_ptr->ref <= 0) && !nondestructive)
+      CountedRefPtr_kill(m_ptr);
+  }
+  //@}
+
+private:
+  /// Store actual pointer
+  ptr_type m_ptr;
+};
+
+/** @class RefCounter
+ * This class implements implements a refernce counter which we can use
+ * as a public base of objects managed by @CountedRefPtr.
+ **/
+class RefCounter {
+
+public:
+  /// Name numerical type for enumbering
+  typedef short count_type;
+
+  /// Allow our smart pointer to access internals
+  template <class, bool, bool, class> friend class CountedRefPtr;
+
+  /// Any Constructor resets the counter
+  RefCounter(...): ref(0) {}
+
+  /// Destructor
+  ~RefCounter() { assume(ref == 0); }
+
+private:
+  /// Number of references
+  count_type ref;  // naming consistent with other classes
+};
+
+
+template <class PtrType>
+class CountedRefWeakPtr;
+
+template <class PtrType>
+class CountedRefIndirectPtr:
+  public RefCounter {
+public:
+  friend class CountedRefWeakPtr<PtrType>;
+  ~CountedRefIndirectPtr()  { }
+
+private:
+  CountedRefIndirectPtr(PtrType ptr): m_ptr(ptr) { }
+  CountedRefIndirectPtr& operator=(PtrType ptr) { m_ptr = ptr; return *this; }
+
+  PtrType m_ptr;
+};
+
+template <class PtrType>
+inline void CountedRefPtr_kill(CountedRefIndirectPtr<PtrType>* pval) { delete pval; }
+
+template <class PtrType>
+class CountedRefWeakPtr {
+  typedef CountedRefWeakPtr self;
+
+public:
+
+  /// @name Name template arguments
+  //@{ Name template arguments
+  typedef PtrType ptr_type;
+  typedef CountedRefPtr<CountedRefIndirectPtr<ptr_type>*> ptrptr_type;
+  //@}
+
+  /// Construct unassigned weak reference
+  CountedRefWeakPtr(): m_indirect(NULL) { }
+
+  /// Convert from pointer
+  CountedRefWeakPtr(ptr_type ptr): m_indirect(new CountedRefIndirectPtr<ptr_type>(ptr)) { }
+
+  /// Construct copy
+  CountedRefWeakPtr(const self& rhs):  m_indirect(rhs.m_indirect) { }
+
+  /// Unlink one reference (handled by CountedRefPtr)
+  ~CountedRefWeakPtr() { }
+
+  /// Mark weak reference as invalid
+  void invalidate() {  *this = NULL; }
+
+  /// Test whether reference was never used
+  bool unassigned() const { return !m_indirect; }
+  /// Pointer-style interface
+  //@{
+  operator bool() const {  return operator->(); }
+  self& operator=(const self& rhs) {
+    m_indirect = rhs.m_indirect;
+    return *this;
+  }
+  self& operator=(ptr_type ptr) {
+    if (!m_indirect)
+      m_indirect = new CountedRefIndirectPtr<ptr_type>(ptr);
+    else
+      m_indirect->m_ptr = ptr;
+    return *this;
+  }
+  bool operator==(ptr_type ptr) const {
+    return m_indirect &&(m_indirect->m_ptr == ptr);
+  }
+  bool operator!=(ptr_type rhs) const { return !operator==(rhs); }
+  const ptr_type operator->() const { return (m_indirect? m_indirect->m_ptr: NULL); }
+  ptr_type operator->() {   return (m_indirect? m_indirect->m_ptr:NULL); }
+  //@}
+private:
+  ptrptr_type m_indirect;
+};
+
+
+
+/** @class LeftvHelper
+ * This class implements some recurrent code sniplets to be used with
+ * @c leftv and @c idhdl.implements a refernce counter which we can use
+ **/
+class LeftvHelper {
+public:
+  static leftv idify(leftv head, idhdl* root) {
+    idhdl handle = newid(head, root);
+    leftv res = (leftv)omAlloc0(sizeof(*res));
+    res->data =(void*) handle;
+    res->rtyp = IDHDL;
+    return res;
+  }
+
+  static idhdl newid(leftv head, idhdl* root) {
+
+    static unsigned int counter = 0;
+    char* name = (char*) omAlloc0(512);
+    sprintf(name, " :%u:%p:_shared_: ", ++counter, head->data);
+    if ((*root) == NULL )
+      enterid(name, 0, head->rtyp, root, TRUE, FALSE);
+    else
+      *root = (*root)->set(name, 0, head->rtyp, TRUE);
+
+    IDDATA(*root) = (char*) head->data;
+    return *root;
+  }
+
+  static void clearid(idhdl handle, idhdl* root) {
+    IDDATA(handle)=NULL;
+    IDTYP(handle)=NONE;
+    killhdl2(handle, root, NULL);
+  }
+
+  template <class Type>
+  static Type* cpy(Type* result, Type* data)  {
+    return (Type*)memcpy(result, data, sizeof(Type));
+  }
+  template <class Type>
+  static Type* cpy(Type* data)  {
+    return cpy((Type*)omAlloc0(sizeof(Type)), data);
+  }
+  template <class Type>
+  static Type* recursivecpy(Type* data)  {
+    if (data == NULL) return data;
+    Type* result = cpy(data);
+    result->next = recursivecpy(data->next);
+    return result;
+  }
+  template <class Type>
+  static Type* shallowcpy(Type* result, Type* data)  {
+    cpy(result, data)->e = recursivecpy(data->e);
+    return result;
+  }
+  template <class Type>
+  static Type* shallowcpy(Type* data)  {
+    return shallowcpy((Type*) omAlloc0(sizeof(Type)), data);
+  }
+  template <class Type>
+  static void recursivekill(Type* current) {
+    if(current == NULL) return;
+    recursivekill(current->next);
+    omFree(current);
+  }
+  static leftv allocate() { return (leftv)omAlloc0(sizeof(sleftv)); }
+
+};
+
+/** @class LeftvShallow
+ * Ths class wraps @c leftv by taking into acount memory allocation, destruction
+ * as well as shallowly copying of a given @c leftv, i.e. we just copy auxiliary
+ * information (like subexpressions), but not the actual data.
+ *
+ * @note This is useful to avoid invalidating @c leftv while operating on th
+ **/
+class LeftvShallow:
+  public LeftvHelper {
+  typedef LeftvShallow self;
+
+public:
+  /// Just allocate (all-zero) @c leftv
+  LeftvShallow(): m_data(allocate()) { }
+  /// Shallow copy the input data
+  LeftvShallow(leftv data): m_data(shallowcpy(data)) { }
+  /// Construct (shallow) copy of @c *this
+  LeftvShallow(const self& rhs):  m_data(shallowcpy(rhs.m_data)) { }
+
+  /// Destruct
+  ~LeftvShallow() {
+    recursivekill(m_data->e);
+    omFree(m_data);
+  }
+
+  /// Assign shallow copy of the input
+  self& operator=(leftv rhs) {
+    recursivekill(m_data->e);
+    shallowcpy(m_data, rhs);
+    return *this;
+  }
+  /// Assign (shallow) copy of @c *this
+  self& operator=(const self& rhs) { return (*this) = rhs.m_data; }
+
+  /// @name Pointer-style access
+  //@{
+  /*const*/ leftv operator->() const { return m_data;  }
+  /*^ warning: 'const' type qualifier on return type has no effect!!! */
+  leftv operator->() { return m_data;  }
+  //@]
+
+protected:
+  /// The actual data pointer
+  leftv m_data;
+};
+
+/** @class LeftvDeep
+ * This class wraps @c leftv by taking into acount memory allocation, destruction
+ * as well as deeply copying of a given @c leftv, i.e. we also take over
+ * ownership of the @c leftv data.
+ *
+ * We have two variants:
+   + LeftvDeep(leftv):           treats referenced identifiers as "the data"
+   + LeftvDeep(leftv, copy_tag): takes care of a full copy of identifier's data
+ *
+ * @note It invalidats @c leftv on input.
+ **/
+class LeftvDeep:
+  public LeftvHelper {
+  typedef LeftvDeep self;
+
+  /// @name Do not permit copying (avoid inconsistence)
+  //@{
+  self& operator=(const self&);
+  LeftvDeep(const self&);
+  //@}
+
+public:
+  /// Allocate all-zero object by default
+  LeftvDeep(): m_data(allocate()) {}
+
+  /// Store a deep copy of the data
+  /// @ note Occupies the provided @c leftv and invalidates the latter
+  LeftvDeep(leftv data): m_data(cpy(data)) {
+    data->e = NULL;   // occupy subexpression
+    if(!isid()) m_data->data=data->CopyD();
+  }
+
+  /// Construct even deeper copy:
+  /// Skip identifier (if any) and take care of the data on our own
+  struct copy_tag {};
+  LeftvDeep(leftv data, copy_tag): m_data(allocate()) {  m_data->Copy(data);  }
+
+  /// Really clear data
+  ~LeftvDeep() { m_data->CleanUp(); }
+
+  /// @name Access via shallow copy to avoid invalidating the stored handle
+  //@{
+  operator LeftvShallow() { return m_data; }
+  LeftvShallow operator*() {return *this; }
+  //@}
+
+  /// Determine whether we point to the same data
+  bool like(const self& rhs) const { return m_data->data == rhs.m_data->data; }
+
+  /// Reassign a new deep copy by occupieing another @c leftv
+  /// @note clears @c *this in the first
+  self& operator=(leftv rhs) {
+    if(isid()) {
+      m_data->e = rhs->e;
+      rhs->e = NULL;
+      IDTYP((idhdl)m_data->data) =  rhs->Typ();
+      IDDATA((idhdl)m_data->data) = (char*) rhs->CopyD();
+    }
+    else {
+      m_data->CleanUp();
+      m_data->Copy(rhs);
+    }
+    return *this;
+  }
+
+  /// Check a given context for our identifier
+  BOOLEAN brokenid(idhdl context) const {
+    assume(isid());
+    return (context == NULL) ||
+      ((context != (idhdl) m_data->data) && brokenid(IDNEXT(context)));
+  }
+
+  /// Put a shallow copy to given @c leftv
+  BOOLEAN put(leftv result) {
+    leftv next = result->next;
+    result->next = NULL;
+    result->CleanUp();
+
+    shallowcpy(result, m_data);
+    result->next = next;
+
+    /// @note @c attrib should read the attributes of the identifier
+    if (isid()) {
+      result->attribute = ((idhdl)m_data->data)->attribute;
+      result->flag = ((idhdl)m_data->data)->flag;
+
+    }
+    return FALSE;
+  }
+
+  /// Get additional data (e.g. subexpression data) from likewise instances
+  BOOLEAN retrieve(leftv res) {
+    if (res->data == m_data->data)  {
+      if(m_data->e != res->e) recursivekill(m_data->e);
+      cpy(m_data, res);
+      res->Init();
+      return TRUE;
+    }
+    return FALSE;
+  }
+
+
+  /// Check for being an identifier
+  BOOLEAN isid() const { return m_data->rtyp==IDHDL;}
+  /// Test whether we reference to ring-dependent data
+  BOOLEAN ringed() { return m_data->RingDependend(); }
+  /// Check whether (all-zero) initialized data was never assigned.
+  BOOLEAN unassigned() const { return m_data->Typ()==0; }
+
+  /// Wrap data by identifier, if not done yet
+  leftv idify(idhdl* root) {
+    leftv res = (isid()? m_data: LeftvHelper::idify(m_data, root));
+    ++(((idhdl)res->data)->ref);
+    return res;
+  }
+
+  /// Erase identifier handles by @c *this
+  /// @note Assumes that we reference an identifier and that we own the latter.
+  /// This is useful to clear the result of a subsequent call of @c idify.
+  void clearid(idhdl* root) {
+    assume(isid());
+    if (--((idhdl)m_data->data)->ref <= 0)  // clear only if we own
+      LeftvHelper::clearid((idhdl)m_data->data, root);
+  }
+
+private:
+  /// Store the actual data
+  leftv m_data;
+};
+
+/// Initialize @c blackbox types 'reference' and 'shared', or both
+void countedref_reference_load();
+void countedref_shared_load();
+
+inline void
+countedref_init()
+{
+  countedref_reference_load();
+  countedref_shared_load();
+}
+
+
+#endif /*SINGULAR_COUNTEDREF_H_ */
+
diff --git a/Singular/denom_list.cc b/Singular/denom_list.cc
new file mode 100644
index 0000000..1a50d33
--- /dev/null
+++ b/Singular/denom_list.cc
@@ -0,0 +1,30 @@
+
+
+
+#include <kernel/mod2.h>
+#include <kernel/GBEngine/kutil.h>
+#include <Singular/lists.h>
+
+lists get_denom_list()
+{
+  int size;
+  denominator_list d = DENOMINATOR_LIST;
+  size=0;
+  while(d!=0)
+    {
+      size++;
+      d=d->next;
+    }
+  lists l=(lists)omAlloc(sizeof(*l));
+  l->Init(size);
+  d=DENOMINATOR_LIST;
+  for (int i=0;i<size;i++)
+    {
+      l->m[i].rtyp=NUMBER_CMD;
+      l->m[i].data=d->n;
+      d=d->next;
+      omFree(DENOMINATOR_LIST);
+      DENOMINATOR_LIST=d;
+    }
+  return l;
+}
diff --git a/Singular/distrib.h b/Singular/distrib.h
new file mode 100644
index 0000000..9a71f1b
--- /dev/null
+++ b/Singular/distrib.h
@@ -0,0 +1 @@
+#undef MAKE_DISTRIBUTION
diff --git a/Singular/dyn_modules/Makefile.am b/Singular/dyn_modules/Makefile.am
new file mode 100644
index 0000000..7d28758
--- /dev/null
+++ b/Singular/dyn_modules/Makefile.am
@@ -0,0 +1,5 @@
+ACLOCAL_AMFLAGS = -I ../m4
+
+SUBDIRS=staticdemo bigintm syzextra pyobject gfanlib polymake singmathic Order
+
+
diff --git a/Singular/dyn_modules/Makefile.in b/Singular/dyn_modules/Makefile.in
new file mode 100644
index 0000000..3c68b03
--- /dev/null
+++ b/Singular/dyn_modules/Makefile.in
@@ -0,0 +1,676 @@
+# Makefile.in generated by automake 1.13.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 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@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+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 = Singular/dyn_modules
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_append_compile_flags.m4 \
+	$(top_srcdir)/m4/ax_append_flag.m4 \
+	$(top_srcdir)/m4/ax_append_link_flags.m4 \
+	$(top_srcdir)/m4/ax_check_compile_flag.m4 \
+	$(top_srcdir)/m4/ax_check_link_flag.m4 \
+	$(top_srcdir)/m4/ax_compute_relative_paths.m4 \
+	$(top_srcdir)/m4/ax_normalize_path.m4 \
+	$(top_srcdir)/m4/ax_prefix_config_h.m4 \
+	$(top_srcdir)/m4/ax_pthread.m4 \
+	$(top_srcdir)/m4/ax_python_embed.m4 \
+	$(top_srcdir)/m4/ax_python_with_version.m4 \
+	$(top_srcdir)/m4/cpu-check.m4 $(top_srcdir)/m4/dbm-check.m4 \
+	$(top_srcdir)/m4/flags.m4 $(top_srcdir)/m4/flint-check.m4 \
+	$(top_srcdir)/m4/gfanlib-check.m4 \
+	$(top_srcdir)/m4/gmp-check.m4 \
+	$(top_srcdir)/m4/google-perftools.m4 \
+	$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+	$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+	$(top_srcdir)/m4/lt~obsolete.m4 \
+	$(top_srcdir)/m4/mathic-check.m4 $(top_srcdir)/m4/ntl-check.m4 \
+	$(top_srcdir)/m4/options.m4 $(top_srcdir)/m4/p-procs.m4 \
+	$(top_srcdir)/m4/polymake-check.m4 \
+	$(top_srcdir)/m4/readline-check.m4 $(top_srcdir)/configure.ac
+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_V_P = $(am__v_P_ at AM_V@)
+am__v_P_ = $(am__v_P_ at AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_ at AM_V@)
+am__v_GEN_ = $(am__v_GEN_ at AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_ at AM_V@)
+am__v_at_ = $(am__v_at_ at AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+SOURCES =
+DIST_SOURCES =
+RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
+	ctags-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 \
+	tags-recursive uninstall-recursive
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive	\
+  distclean-recursive maintainer-clean-recursive
+am__recursive_targets = \
+  $(RECURSIVE_TARGETS) \
+  $(RECURSIVE_CLEAN_TARGETS) \
+  $(am__extra_recursive_targets)
+AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
+	distdir
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+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@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BUILTIN_LIBS = @BUILTIN_LIBS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CDDGMPCPPFLAGS = @CDDGMPCPPFLAGS@
+CDDGMPLDFLAGS = @CDDGMPLDFLAGS@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATA_DIR = @DATA_DIR@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DOC_DIR = @DOC_DIR@
+DOXYGEN = @DOXYGEN@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FACTORY_INCLUDES = @FACTORY_INCLUDES@
+FACTORY_LIBS = @FACTORY_LIBS@
+FGREP = @FGREP@
+FLINT_CFLAGS = @FLINT_CFLAGS@
+FLINT_HOME = @FLINT_HOME@
+FLINT_LIBS = @FLINT_LIBS@
+GMP_CFLAGS = @GMP_CFLAGS@
+GMP_HOME = @GMP_HOME@
+GMP_LIBS = @GMP_LIBS@
+GMP_VERSION = @GMP_VERSION@
+GREP = @GREP@
+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@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NTL_CFLAGS = @NTL_CFLAGS@
+NTL_LIBS = @NTL_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OMALLOC_INCLUDES = @OMALLOC_INCLUDES@
+OMALLOC_LIBS = @OMALLOC_LIBS@
+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@
+PKG_REQUIRE = @PKG_REQUIRE@
+PMCONFIG = @PMCONFIG@
+PM_CFLAGS = @PM_CFLAGS@
+PM_INC = @PM_INC@
+PM_LDFLAGS = @PM_LDFLAGS@
+PM_LIBS = @PM_LIBS@
+POLYMAKE_CXXFLAGS = @POLYMAKE_CXXFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LDFLAGS = @PTHREAD_LDFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
+PYTHON = @PYTHON@
+PYTHON_CSPEC = @PYTHON_CSPEC@
+PYTHON_EXECPREFIX = @PYTHON_EXECPREFIX@
+PYTHON_LSPEC = @PYTHON_LSPEC@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+RANLIB = @RANLIB@
+RESOURCES_INCLUDES = @RESOURCES_INCLUDES@
+RESOURCES_LIBS = @RESOURCES_LIBS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SINGULAR_CFLAGS = @SINGULAR_CFLAGS@
+SI_COUNTEDREF_AUTOLOAD = @SI_COUNTEDREF_AUTOLOAD@
+SI_CPU_I386 = @SI_CPU_I386@
+SI_CPU_IA64 = @SI_CPU_IA64@
+SI_CPU_PPC = @SI_CPU_PPC@
+SI_CPU_SPARC = @SI_CPU_SPARC@
+SI_CPU_X86_64 = @SI_CPU_X86_64@
+STRIP = @STRIP@
+USEPPROCSDYNAMICLD = @USEPPROCSDYNAMICLD@
+USEPPROCSDYNAMICLDFLAGS = @USEPPROCSDYNAMICLDFLAGS@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
+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@
+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@
+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@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+ACLOCAL_AMFLAGS = -I ../m4
+SUBDIRS = staticdemo bigintm syzextra pyobject gfanlib polymake singmathic Order
+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) --foreign Singular/dyn_modules/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign Singular/dyn_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):
+
+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.
+$(am__recursive_targets):
+	@fail=; \
+	if $(am__make_keepgoing); then \
+	  failcom='fail=yes'; \
+	else \
+	  failcom='exit 1'; \
+	fi; \
+	dot_seen=no; \
+	target=`echo $@ | sed s/-recursive//`; \
+	case "$@" in \
+	  distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+	  *) list='$(SUBDIRS)' ;; \
+	esac; \
+	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"
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-recursive
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	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; \
+	$(am__define_uniq_tagged_files); \
+	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-recursive
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	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"
+cscopelist: cscopelist-recursive
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+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 \
+	    $(am__make_dryrun) \
+	      || test -d "$(distdir)/$$subdir" \
+	      || $(MKDIR_P) "$(distdir)/$$subdir" \
+	      || exit 1; \
+	    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:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+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 Makefile
+distclean-am: clean-am 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-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
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: $(am__recursive_targets) install-am install-strip
+
+.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \
+	check-am clean clean-generic clean-libtool cscopelist-am ctags \
+	ctags-am 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 \
+	mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
+	ps ps-am tags tags-am uninstall uninstall-am
+
+
+# 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/Singular/dyn_modules/Order/Makefile.am b/Singular/dyn_modules/Order/Makefile.am
new file mode 100644
index 0000000..39b2790
--- /dev/null
+++ b/Singular/dyn_modules/Order/Makefile.am
@@ -0,0 +1,37 @@
+ACLOCAL_AMFLAGS = -I ../../m4
+
+SOURCES = nforder.cpp nforder.h \
+	  singular.cc \
+	  nforder_elt.cc nforder_elt.h \
+	  nforder_ideal.cc nforder_ideal.h
+
+MYINCLUDES =  -I${top_srcdir} -I${top_builddir} -I${srcdir} \
+-I${top_srcdir}/libpolys -I${top_builddir}/libpolys \
+-I${top_srcdir}/factory/include -I${top_builddir}/factory/include \
+$(FACTORY_CFLAGS) $(NTL_CFLAGS) $(GMP_CFLAGS) $(GOOGLE_PERFTOOLS_CFLAGS)
+
+if SI_BUILTIN_ORDER
+  noinst_LTLIBRARIES=Order.la
+  P_PROCS_CPPFLAGS_COMMON = -DSTATIC_VERSION
+  P_PROCS_MODULE_LDFLAGS = -module
+else
+  module_LTLIBRARIES=Order.la
+  moduledir = $(libexecdir)/singular/MOD
+  P_PROCS_CPPFLAGS_COMMON = -DDYNAMIC_VERSION
+# Add under Mac OS X: -flat_namespace -weak_reference_mismatches weak -undefined dynamic_lookup
+  P_PROCS_MODULE_LDFLAGS = -module -export-dynamic -avoid-version -flat_namespace -weak_reference_mismatches weak -undefined dynamic_lookup
+endif
+
+Order_la_SOURCES   = $(SOURCES)
+Order_la_CPPFLAGS  = ${MYINCLUDES} ${P_PROCS_CPPFLAGS_COMMON}
+Order_la_LDFLAGS   = ${AM_LDFLAGS} ${P_PROCS_MODULE_LDFLAGS} ${GOOGLE_PERFTOOL_LDFLAGS}
+
+# AM_COLOR_TESTS=always
+#
+# TESTS_ENVIRONMENT  = SINGULARPATH='${abs_top_builddir}/Singular/LIB:${abs_top_srcdir}/Singular/LIB:${abs_top_builddir}/libpolys/polys/.libs:${abs_top_builddir}/factory/gftables:${abs_builddir}/.libs:${abs_srcdir}'
+# TESTS_ENVIRONMENT += SINGULAR_ROOT_DIR='${abs_top_builddir}'
+# TESTS_ENVIRONMENT += SINGULAR_BIN_DIR='${abs_top_builddir}/Singular'
+#
+# TESTS=test_release.sh
+#
+# EXTRA_DIST = nforder.tst test.sh $(TESTS)
diff --git a/Singular/dyn_modules/Order/Makefile.in b/Singular/dyn_modules/Order/Makefile.in
new file mode 100644
index 0000000..1d15a87
--- /dev/null
+++ b/Singular/dyn_modules/Order/Makefile.in
@@ -0,0 +1,823 @@
+# Makefile.in generated by automake 1.13.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 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@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+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 = Singular/dyn_modules/Order
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/build-aux/depcomp
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_append_compile_flags.m4 \
+	$(top_srcdir)/m4/ax_append_flag.m4 \
+	$(top_srcdir)/m4/ax_append_link_flags.m4 \
+	$(top_srcdir)/m4/ax_check_compile_flag.m4 \
+	$(top_srcdir)/m4/ax_check_link_flag.m4 \
+	$(top_srcdir)/m4/ax_compute_relative_paths.m4 \
+	$(top_srcdir)/m4/ax_normalize_path.m4 \
+	$(top_srcdir)/m4/ax_prefix_config_h.m4 \
+	$(top_srcdir)/m4/ax_pthread.m4 \
+	$(top_srcdir)/m4/ax_python_embed.m4 \
+	$(top_srcdir)/m4/ax_python_with_version.m4 \
+	$(top_srcdir)/m4/cpu-check.m4 $(top_srcdir)/m4/dbm-check.m4 \
+	$(top_srcdir)/m4/flags.m4 $(top_srcdir)/m4/flint-check.m4 \
+	$(top_srcdir)/m4/gfanlib-check.m4 \
+	$(top_srcdir)/m4/gmp-check.m4 \
+	$(top_srcdir)/m4/google-perftools.m4 \
+	$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+	$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+	$(top_srcdir)/m4/lt~obsolete.m4 \
+	$(top_srcdir)/m4/mathic-check.m4 $(top_srcdir)/m4/ntl-check.m4 \
+	$(top_srcdir)/m4/options.m4 $(top_srcdir)/m4/p-procs.m4 \
+	$(top_srcdir)/m4/polymake-check.m4 \
+	$(top_srcdir)/m4/readline-check.m4 $(top_srcdir)/configure.ac
+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__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
+am__installdirs = "$(DESTDIR)$(moduledir)"
+LTLIBRARIES = $(module_LTLIBRARIES) $(noinst_LTLIBRARIES)
+Order_la_LIBADD =
+am__objects_1 = Order_la-nforder.lo Order_la-singular.lo \
+	Order_la-nforder_elt.lo Order_la-nforder_ideal.lo
+am_Order_la_OBJECTS = $(am__objects_1)
+Order_la_OBJECTS = $(am_Order_la_OBJECTS)
+AM_V_lt = $(am__v_lt_ at AM_V@)
+am__v_lt_ = $(am__v_lt_ at AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 = 
+Order_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+	$(CXXFLAGS) $(Order_la_LDFLAGS) $(LDFLAGS) -o $@
+ at SI_BUILTIN_ORDER_FALSE@am_Order_la_rpath = -rpath $(moduledir)
+ at SI_BUILTIN_ORDER_TRUE@am_Order_la_rpath =
+AM_V_P = $(am__v_P_ at AM_V@)
+am__v_P_ = $(am__v_P_ at AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_ at AM_V@)
+am__v_GEN_ = $(am__v_GEN_ at AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_ at AM_V@)
+am__v_at_ = $(am__v_at_ at AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+DEFAULT_INCLUDES = -I. at am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \
+	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+	$(AM_CXXFLAGS) $(CXXFLAGS)
+AM_V_CXX = $(am__v_CXX_ at AM_V@)
+am__v_CXX_ = $(am__v_CXX_ at AM_DEFAULT_V@)
+am__v_CXX_0 = @echo "  CXX     " $@;
+am__v_CXX_1 = 
+CXXLD = $(CXX)
+CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+	$(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CXXLD = $(am__v_CXXLD_ at AM_V@)
+am__v_CXXLD_ = $(am__v_CXXLD_ at AM_DEFAULT_V@)
+am__v_CXXLD_0 = @echo "  CXXLD   " $@;
+am__v_CXXLD_1 = 
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+	$(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_ at AM_V@)
+am__v_CC_ = $(am__v_CC_ at AM_DEFAULT_V@)
+am__v_CC_0 = @echo "  CC      " $@;
+am__v_CC_1 = 
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+	$(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_ at AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_ at AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo "  CCLD    " $@;
+am__v_CCLD_1 = 
+DIST_SOURCES = $(Order_la_SOURCES)
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BUILTIN_LIBS = @BUILTIN_LIBS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CDDGMPCPPFLAGS = @CDDGMPCPPFLAGS@
+CDDGMPLDFLAGS = @CDDGMPLDFLAGS@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATA_DIR = @DATA_DIR@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DOC_DIR = @DOC_DIR@
+DOXYGEN = @DOXYGEN@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FACTORY_INCLUDES = @FACTORY_INCLUDES@
+FACTORY_LIBS = @FACTORY_LIBS@
+FGREP = @FGREP@
+FLINT_CFLAGS = @FLINT_CFLAGS@
+FLINT_HOME = @FLINT_HOME@
+FLINT_LIBS = @FLINT_LIBS@
+GMP_CFLAGS = @GMP_CFLAGS@
+GMP_HOME = @GMP_HOME@
+GMP_LIBS = @GMP_LIBS@
+GMP_VERSION = @GMP_VERSION@
+GREP = @GREP@
+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@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NTL_CFLAGS = @NTL_CFLAGS@
+NTL_LIBS = @NTL_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OMALLOC_INCLUDES = @OMALLOC_INCLUDES@
+OMALLOC_LIBS = @OMALLOC_LIBS@
+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@
+PKG_REQUIRE = @PKG_REQUIRE@
+PMCONFIG = @PMCONFIG@
+PM_CFLAGS = @PM_CFLAGS@
+PM_INC = @PM_INC@
+PM_LDFLAGS = @PM_LDFLAGS@
+PM_LIBS = @PM_LIBS@
+POLYMAKE_CXXFLAGS = @POLYMAKE_CXXFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LDFLAGS = @PTHREAD_LDFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
+PYTHON = @PYTHON@
+PYTHON_CSPEC = @PYTHON_CSPEC@
+PYTHON_EXECPREFIX = @PYTHON_EXECPREFIX@
+PYTHON_LSPEC = @PYTHON_LSPEC@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+RANLIB = @RANLIB@
+RESOURCES_INCLUDES = @RESOURCES_INCLUDES@
+RESOURCES_LIBS = @RESOURCES_LIBS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SINGULAR_CFLAGS = @SINGULAR_CFLAGS@
+SI_COUNTEDREF_AUTOLOAD = @SI_COUNTEDREF_AUTOLOAD@
+SI_CPU_I386 = @SI_CPU_I386@
+SI_CPU_IA64 = @SI_CPU_IA64@
+SI_CPU_PPC = @SI_CPU_PPC@
+SI_CPU_SPARC = @SI_CPU_SPARC@
+SI_CPU_X86_64 = @SI_CPU_X86_64@
+STRIP = @STRIP@
+USEPPROCSDYNAMICLD = @USEPPROCSDYNAMICLD@
+USEPPROCSDYNAMICLDFLAGS = @USEPPROCSDYNAMICLDFLAGS@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
+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@
+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@
+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@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+ACLOCAL_AMFLAGS = -I ../../m4
+SOURCES = nforder.cpp nforder.h \
+	  singular.cc \
+	  nforder_elt.cc nforder_elt.h \
+	  nforder_ideal.cc nforder_ideal.h
+
+MYINCLUDES = -I${top_srcdir} -I${top_builddir} -I${srcdir} \
+-I${top_srcdir}/libpolys -I${top_builddir}/libpolys \
+-I${top_srcdir}/factory/include -I${top_builddir}/factory/include \
+$(FACTORY_CFLAGS) $(NTL_CFLAGS) $(GMP_CFLAGS) $(GOOGLE_PERFTOOLS_CFLAGS)
+
+ at SI_BUILTIN_ORDER_TRUE@noinst_LTLIBRARIES = Order.la
+ at SI_BUILTIN_ORDER_FALSE@P_PROCS_CPPFLAGS_COMMON = -DDYNAMIC_VERSION
+ at SI_BUILTIN_ORDER_TRUE@P_PROCS_CPPFLAGS_COMMON = -DSTATIC_VERSION
+# Add under Mac OS X: -flat_namespace -weak_reference_mismatches weak -undefined dynamic_lookup
+ at SI_BUILTIN_ORDER_FALSE@P_PROCS_MODULE_LDFLAGS = -module -export-dynamic -avoid-version -flat_namespace -weak_reference_mismatches weak -undefined dynamic_lookup
+ at SI_BUILTIN_ORDER_TRUE@P_PROCS_MODULE_LDFLAGS = -module
+ at SI_BUILTIN_ORDER_FALSE@module_LTLIBRARIES = Order.la
+ at SI_BUILTIN_ORDER_FALSE@moduledir = $(libexecdir)/singular/MOD
+Order_la_SOURCES = $(SOURCES)
+Order_la_CPPFLAGS = ${MYINCLUDES} ${P_PROCS_CPPFLAGS_COMMON}
+Order_la_LDFLAGS = ${AM_LDFLAGS} ${P_PROCS_MODULE_LDFLAGS} ${GOOGLE_PERFTOOL_LDFLAGS}
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .cc .cpp .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) --foreign Singular/dyn_modules/Order/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign Singular/dyn_modules/Order/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-moduleLTLIBRARIES: $(module_LTLIBRARIES)
+	@$(NORMAL_INSTALL)
+	@list='$(module_LTLIBRARIES)'; test -n "$(moduledir)" || list=; \
+	list2=; for p in $$list; do \
+	  if test -f $$p; then \
+	    list2="$$list2 $$p"; \
+	  else :; fi; \
+	done; \
+	test -z "$$list2" || { \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(moduledir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(moduledir)" || exit 1; \
+	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(moduledir)'"; \
+	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(moduledir)"; \
+	}
+
+uninstall-moduleLTLIBRARIES:
+	@$(NORMAL_UNINSTALL)
+	@list='$(module_LTLIBRARIES)'; test -n "$(moduledir)" || list=; \
+	for p in $$list; do \
+	  $(am__strip_dir) \
+	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(moduledir)/$$f'"; \
+	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(moduledir)/$$f"; \
+	done
+
+clean-moduleLTLIBRARIES:
+	-test -z "$(module_LTLIBRARIES)" || rm -f $(module_LTLIBRARIES)
+	@list='$(module_LTLIBRARIES)'; \
+	locs=`for p in $$list; do echo $$p; done | \
+	      sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+	      sort -u`; \
+	test -z "$$locs" || { \
+	  echo rm -f $${locs}; \
+	  rm -f $${locs}; \
+	}
+
+clean-noinstLTLIBRARIES:
+	-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+	@list='$(noinst_LTLIBRARIES)'; \
+	locs=`for p in $$list; do echo $$p; done | \
+	      sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+	      sort -u`; \
+	test -z "$$locs" || { \
+	  echo rm -f $${locs}; \
+	  rm -f $${locs}; \
+	}
+
+Order.la: $(Order_la_OBJECTS) $(Order_la_DEPENDENCIES) $(EXTRA_Order_la_DEPENDENCIES) 
+	$(AM_V_CXXLD)$(Order_la_LINK) $(am_Order_la_rpath) $(Order_la_OBJECTS) $(Order_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/Order_la-nforder.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/Order_la-nforder_elt.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/Order_la-nforder_ideal.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/Order_la-singular.Plo at am__quote@
+
+.cc.o:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+ at am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXXCOMPILE) -c -o $@ $<
+
+.cc.obj:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+ at am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.cc.lo:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+ at am__fastdepCXX_TRUE@	$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LTCXXCOMPILE) -c -o $@ $<
+
+Order_la-nforder.lo: nforder.cpp
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Order_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT Order_la-nforder.lo -MD -MP -MF $(DEPDIR)/Order_la-nforder.Tpo -c -o Order_la-nforder.lo `test -f 'nforder.cpp' || echo '$(srcdir)/'`nforder.cpp
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/Order_la-nforder.Tpo $(DEPDIR)/Order_la-nforder.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='nforder.cpp' object='Order_la-nforder.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Order_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o Order_la-nforder.lo `test -f 'nforder.cpp' || echo '$(srcdir)/'`nforder.cpp
+
+Order_la-singular.lo: singular.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Order_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT Order_la-singular.lo -MD -MP -MF $(DEPDIR)/Order_la-singular.Tpo -c -o Order_la-singular.lo `test -f 'singular.cc' || echo '$(srcdir)/'`singular.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/Order_la-singular.Tpo $(DEPDIR)/Order_la-singular.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='singular.cc' object='Order_la-singular.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Order_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o Order_la-singular.lo `test -f 'singular.cc' || echo '$(srcdir)/'`singular.cc
+
+Order_la-nforder_elt.lo: nforder_elt.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Order_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT Order_la-nforder_elt.lo -MD -MP -MF $(DEPDIR)/Order_la-nforder_elt.Tpo -c -o Order_la-nforder_elt.lo `test -f 'nforder_elt.cc' || echo '$(srcdir)/'`nforder_elt.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/Order_la-nforder_elt.Tpo $(DEPDIR)/Order_la-nforder_elt.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='nforder_elt.cc' object='Order_la-nforder_elt.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Order_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o Order_la-nforder_elt.lo `test -f 'nforder_elt.cc' || echo '$(srcdir)/'`nforder_elt.cc
+
+Order_la-nforder_ideal.lo: nforder_ideal.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Order_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT Order_la-nforder_ideal.lo -MD -MP -MF $(DEPDIR)/Order_la-nforder_ideal.Tpo -c -o Order_la-nforder_ideal.lo `test -f 'nforder_ideal.cc' || echo '$(srcdir)/'`nforder_ideal.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/Order_la-nforder_ideal.Tpo $(DEPDIR)/Order_la-nforder_ideal.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='nforder_ideal.cc' object='Order_la-nforder_ideal.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Order_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o Order_la-nforder_ideal.lo `test -f 'nforder_ideal.cc' || echo '$(srcdir)/'`nforder_ideal.cc
+
+.cpp.o:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+ at am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXXCOMPILE) -c -o $@ $<
+
+.cpp.obj:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+ at am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.cpp.lo:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+ at am__fastdepCXX_TRUE@	$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LTCXXCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	$(am__define_uniq_tagged_files); \
+	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-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	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"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+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 $(LTLIBRARIES)
+installdirs:
+	for dir in "$(DESTDIR)$(moduledir)"; 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:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+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 clean-moduleLTLIBRARIES \
+	clean-noinstLTLIBRARIES 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-moduleLTLIBRARIES
+
+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: uninstall-moduleLTLIBRARIES
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
+	clean-libtool clean-moduleLTLIBRARIES clean-noinstLTLIBRARIES \
+	cscopelist-am ctags ctags-am 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-moduleLTLIBRARIES 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 tags-am uninstall uninstall-am \
+	uninstall-moduleLTLIBRARIES
+
+
+# AM_COLOR_TESTS=always
+#
+# TESTS_ENVIRONMENT  = SINGULARPATH='${abs_top_builddir}/Singular/LIB:${abs_top_srcdir}/Singular/LIB:${abs_top_builddir}/libpolys/polys/.libs:${abs_top_builddir}/factory/gftables:${abs_builddir}/.libs:${abs_srcdir}'
+# TESTS_ENVIRONMENT += SINGULAR_ROOT_DIR='${abs_top_builddir}'
+# TESTS_ENVIRONMENT += SINGULAR_BIN_DIR='${abs_top_builddir}/Singular'
+#
+# TESTS=test_release.sh
+#
+# EXTRA_DIST = nforder.tst test.sh $(TESTS)
+
+# 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/Singular/dyn_modules/Order/nforder.cpp b/Singular/dyn_modules/Order/nforder.cpp
new file mode 100644
index 0000000..3663cd0
--- /dev/null
+++ b/Singular/dyn_modules/Order/nforder.cpp
@@ -0,0 +1,687 @@
+#include <coeffs/bigintmat.h>
+#include "nforder.h"
+#include <reporter/reporter.h>
+#include<coeffs/numbers.h>
+#include <coeffs/coeffs.h>
+#include "Singular/ipid.h"
+
+
+
+
+////////////////////////////////////
+//// Konstruktoren/Destruktoren ////
+////////////////////////////////////
+
+/*________________0_______________*/
+void nforder::init() {
+  rc = 1;
+  // Gibt es eine Multtable, so gibt es keine Baseorder
+  baseorder = NULL;
+  basis = NULL;
+  // Discriminante wird erst berechnet, wenn sie benötigt wird
+  discriminant = NULL;
+  divisor = NULL;
+  flags = 0;
+  multtable = NULL;
+  m_coeffs = NULL;
+  setOneIsOne();
+}
+
+nforder::nforder(int dim, bigintmat **m,const coeffs q) {
+  init();
+  m_coeffs = q;
+  dimension = dim;
+  multtable = (bigintmat**)(omAlloc(dim*sizeof(bigintmat*)));
+  for (int i=0; i<dim; i++) {
+    multtable[i] = new bigintmat(m[i]);
+  }
+  basis = NULL;
+  inv_basis = NULL;
+}
+
+nforder::nforder(nforder *o, bigintmat *base, number div, const coeffs q) {
+   init();
+   m_coeffs = q;
+   basis = new bigintmat(base);
+   //neue Ordnung erzeugen und übergebene Daten kopieren
+   baseorder = o;
+   o->ref_count_incref();
+   //Gibt es eine Baseorder, brauchen wir keine Multtable. Könnte aber evtl. generiert werden
+   multtable = NULL;
+   divisor = n_Copy(div,basecoeffs());
+   basis->simplifyContentDen(&divisor);
+   dimension = o->getDim();
+   discriminant = NULL;
+
+   inv_basis = new bigintmat(base->rows(), base->rows(), q);
+   inv_divisor = basis->pseudoinv(inv_basis);
+   inv_basis->skalmult(divisor, q);
+   inv_basis->simplifyContentDen(&inv_divisor);
+}
+
+nforder::nforder(nforder *o, int) {
+  init();
+  m_coeffs = o->basecoeffs();
+  ::Print("copy called: %lx\n", (long unsigned int) m_coeffs);
+  // Kopiert die Daten der übergebenen Ordnung auf die erzeugte
+  if (o->discriminant)
+    discriminant = n_Copy(o->discriminant,  basecoeffs());
+  // get-Funktionen liefern immer nur Kopien der Attribute zurück
+  dimension = o->getDim();
+  multtable = (bigintmat **)omAlloc(dimension*sizeof(bigintmat*));
+  if (!o->getMult(multtable)) {
+    omFree(multtable);
+    multtable = NULL;
+  }
+  baseorder = o->getBase();
+  if (baseorder) baseorder->ref_count_incref();
+  basis = o->getBasis();
+  if (o->divisor)
+    divisor = n_Copy(o->divisor,  basecoeffs());
+  if (o->inv_basis) {
+    inv_basis = new bigintmat(o->inv_basis);
+    inv_divisor = n_Copy(o->inv_divisor, basecoeffs());
+  }
+}
+
+void nforder::Write() {
+  StringAppend("Order:\nof dimension %d and rc: %d\n", dimension, ref_count());
+  if (discriminant && !n_IsZero(discriminant, m_coeffs)) {
+    StringAppend("and discriminant: ");
+    n_Write(discriminant, m_coeffs);
+    StringAppend("\n");
+  }
+//  coeffs
+  if (multtable) {
+    StringAppend("Multiplication table:\n");
+    for(int i=0; i<dimension; i++) {
+      StringAppend("%d: ", i);
+      multtable[i]->Write();
+      StringAppendS("\n");
+    }
+  }
+
+  if (baseorder) {
+    StringAppendS("as extension of:");
+    baseorder->Write();
+    StringAppendS("with basis:\n");
+    basis->Write();
+    StringAppendS("and denominator: ");
+    n_Write(divisor, m_coeffs);
+    StringAppendS("\nwith inv_basis:\n");
+    inv_basis->Write();
+    StringAppendS("and inv_denominator: ");
+    n_Write(inv_divisor, m_coeffs);
+    StringAppendS("\n");
+  }
+
+  StringAppend("Flags: %lx\n", flags);
+}
+
+char * nforder::String() {
+  StringSetS("");
+  Write();
+  return StringEndS();
+}
+void nforder::Print() {
+  char * s = String();
+  PrintS(s);
+  PrintS("\n");
+  omFree(s);
+}
+void nforder_delete(nforder* o) {
+  if (o->ref_count_decref()>0) {
+    return;
+  }
+  delete o;
+}
+
+nforder::~nforder() {
+  if (multtable != NULL) {
+    for (int i=0; i<dimension; i++)
+      delete multtable[i];
+    omFree(multtable);
+  }
+  else
+  {
+    // andernfalls werden baseorder und basis gelöscht
+    nforder_delete (baseorder);
+    delete basis;
+    if (divisor) n_Delete(&divisor, basecoeffs());
+    if (inv_basis) delete inv_basis;
+    if (inv_divisor) n_Delete(&inv_divisor, basecoeffs());
+  }
+  if (discriminant) n_Delete(&discriminant, basecoeffs());
+}
+
+/*
+////////////////////////////////////
+//////// Private Funktionen ////////
+///////////////////////////////////*/
+/*_______________-1_______________ */
+void nforder::calcdisc() {
+  // Determinante von Spurmatrix ist die Discriminante
+  if (discriminant) return;
+  if (baseorder == NULL) {
+    bigintmat *m = traceMatrix();
+    discriminant = m->det();
+    assume(discriminant);
+    delete m;
+  }
+  else
+  {
+    number prod = n_Init(1, basecoeffs());
+    number tmp, tmp2; //assumes that the basis is triangular!
+    for (int i=1; i<=dimension; i++) {
+      tmp2 = basis->view(i, i);
+      tmp = n_Mult(prod, tmp2, basecoeffs());
+      n_Delete(&prod, basecoeffs());
+      prod = tmp;
+    }
+    baseorder->calcdisc();
+    number disc = baseorder->viewDisc();
+    assume(disc);
+    number detquad = n_Mult(prod, prod, basis->basecoeffs());
+    discriminant = n_Mult(disc, detquad, basecoeffs());
+
+    for (int i=1; i<=2*dimension; i++) {
+      tmp = n_Div(discriminant, divisor, basecoeffs());
+      n_Delete(&discriminant, basecoeffs());
+      discriminant = tmp;
+    }
+    n_Delete(&detquad, basis->basecoeffs());
+  }
+}
+
+bigintmat *nforder::traceMatrix() {
+  bigintmat *m = new bigintmat(dimension, dimension, basecoeffs());
+  bigintmat *base1 = new bigintmat(dimension, 1, basecoeffs());
+  bigintmat *base2 = new bigintmat(dimension, 1, basecoeffs());
+  bigintmat *mm = new bigintmat(dimension, dimension, basecoeffs());
+  number sum;
+
+  for (int i=1; i<=dimension; i++) {
+    for (int j=i; j<=dimension; j++) {
+      // Berechnet Produkt von Basiselementen i und j und speichert es in base1
+      basis_elt(base1, i);
+      basis_elt(base2, j);
+      elMult(base1, base2);
+      // Schreibt Abbildungsmatrix der Multiplikation mit base1 in mm
+      sum = elTrace(base1);
+      m->set(i, j, sum, basecoeffs());
+      if (i!=j)
+        m->set(j, i, sum, basecoeffs());
+      n_Delete(&sum, basecoeffs());
+    }
+  }
+  delete base1;
+  delete base2;
+  delete mm;
+  return m;
+}
+////////////////////////////////////
+////// Öffentliche Funktionen //////
+////////////////////////////////////
+
+/*_____________+1_______________ */
+number nforder::getDisc() {
+  // Falls Discriminante bisher noch nicht berechnet wurde, berechne diese
+  if (!discriminant || n_IsZero(discriminant, basecoeffs())) {
+    calcdisc();
+  }
+  return n_Copy(discriminant, basecoeffs());
+}
+
+int nforder::getDim() {
+  return dimension;
+}
+
+bigintmat *nforder::getBasis() {
+  // Falls basis ein NULL-Pointer ist, liefere NULL zurück, andernfalls liefere eine Kopie von basis
+  if (basis == NULL)
+    return NULL;
+  bigintmat *m = new bigintmat(basis); //wenn Fehler dann hier
+  return m;
+}
+bigintmat *nforder::viewBasis() {
+  if (basis == NULL)
+    return NULL;
+  return basis;
+}
+bool nforder::getMult(bigintmat **m) {
+  // Falls multtable ein NULL-Pointer ist, liefere NULL zurück, andernfalls erzeuge neues Array of Matrix, kopiere die Matrizen aus multtable dort hinein, und gib es zurück
+  if (multtable == NULL) {
+    return false;
+  }
+  for (int i=0; i<dimension; i++)
+  {
+    m[i] = new bigintmat(multtable[i]);
+  }
+  return true;
+}
+
+
+number nforder::getDiv() {
+  return n_Copy(divisor, basecoeffs());
+}
+
+nforder *nforder::getBase() {
+  // returns the baseorder, if present. Does not incref the ref count.
+  if (baseorder == NULL)
+    return NULL;
+  return baseorder;
+}
+
+nforder *nforder::simplify() {
+  coeffs c = basecoeffs();
+  if (!baseorder || !baseorder->baseorder) {
+    ref_count_incref();
+    return this;
+  }
+  nforder * O = baseorder;
+  number den = n_Copy(divisor, c);
+  bigintmat *bas = getBasis();
+  while (O->baseorder) {
+    bigintmat * b = bimMult(bas, O->viewBasis());
+    n_InpMult(den, O->divisor, c);
+    O =  O->baseorder;
+    delete bas;
+    bas = b;
+  }
+  nforder * res = new nforder(O, bas, den, c);
+  if (discriminant)
+    res->discriminant = n_Copy(discriminant, c);
+
+  //TODO: copy multtable if we have it
+  delete bas;
+  n_Delete(&den, c);
+  return res;
+}
+
+void nforder::elAdd(bigintmat *a, bigintmat *b) {
+  if ((a->cols() != 1) || (a->rows() != dimension) || (b->cols() != 1) || (b->rows() != dimension)) {
+    Werror("Error in elSub");
+  }
+  else {
+    a->add(b);
+  }
+}
+
+
+void nforder::elSub(bigintmat *a, bigintmat *b) {
+  if ((a->cols() != 1) || (a->rows() != dimension) || (b->cols() != 1) || (b->rows() != dimension)) {
+    // Kein Zeilenvektor der korrekten Größe
+    Werror("Error in elSub");
+  }
+  else {
+    a->sub(b);
+  }
+}
+
+void nforder::elMult(bigintmat *a, bigintmat *b) {
+  if ((a->cols() != 1) || (a->rows() != dimension) || (b->cols() != 1) || (b->rows() != dimension)) {
+    // Kein Zeilenvektor der korrekten Größe
+    Werror("Error in elMult");
+  }
+
+  coeffs C = a->basecoeffs();
+  assume(C == b->basecoeffs());
+  assume(C == this->basecoeffs());
+
+  if (multtable != NULL) {
+    // Multiplikation mit Hilfe von Multiplikationstabelle
+    // Zu Grunde liegende Formel: Basis w_i; Für alpha = sum a_i*w_i und beta = sum b_i*w_i gilt:
+    // alpha*beta = sum sum a_i*b_j*w_i*w_j
+    bigintmat *sum = new bigintmat(dimension, 1, C);
+    bigintmat *tmp = new bigintmat(dimension, 1, C);
+    number ntmp;
+
+    for (int i=1; i<=dimension; i++) {
+      // Laufe mit i durch Basiselemente
+      for (int j=1; j<=dimension; j++) {
+        // Laufe mit j durch Basiselemente
+        // Speichere Produkt von Basiselem. i mit Basiselem. j als Koeff.vektor in tmp
+
+        multtable[i-1]->getcol(j, tmp);
+        // Multipliziere ihn mit a[i] und b[j]
+        ntmp = n_Mult(a->view(i, 1), b->view(j, 1), C);
+        tmp->skalmult(ntmp, C);
+
+        n_Delete(&ntmp, C);
+        // und addiere alles auf
+        sum->add(tmp);
+      }
+    }
+    delete tmp;
+    // Am Ende überschreibe a mit dem Ergebnis
+    for (int i=0; i<dimension; i++)
+      a->set(i+1, 1, sum->get(i+1, 1));
+    delete sum;
+  } else {
+  // Multiplikation mit hilfe von baseorder:
+    bigintmat *sumb = new bigintmat(dimension, 1, C);
+  // Produkt von a (b) mit basis liefert Koeff-Vektor von a*divisor (b*divisor) in baseorder
+    bimMult(basis, a, a);
+    bimMult(basis, b, sumb);
+    // Multipliziere Elemente in baseorder (und speichere in suma)
+    baseorder->elMult(a, sumb);
+    delete sumb;
+    a->skaldiv(divisor);
+    bimMult(inv_basis, a, a);
+    a->skaldiv(inv_divisor);
+    a->skaldiv(divisor);
+  }
+}
+
+
+//TODO: compute the trace from the mult-table without
+//      the explicit rep_mat
+number nforder::elTrace(bigintmat *a)
+{
+  bigintmat * rep_mat = elRepMat(a);
+  number t = rep_mat->trace();
+  delete rep_mat;
+  return t;
+}
+
+number nforder::elNorm(bigintmat *a)
+{
+  bigintmat * rep_mat = elRepMat(a);
+  number n = rep_mat->det();
+  delete rep_mat;
+  return n;
+}
+
+bigintmat * nforder::elRepMat(bigintmat *a)
+{
+  bigintmat *b=new bigintmat(dimension, dimension, basecoeffs());
+  multmap(a, b);
+  return b;
+}
+
+//CF: TODO if multtable, then use lin. comb. of multtable
+//rather than poducts. reduces complexity by a magnitude.
+void nforder::multmap(bigintmat *a, bigintmat *m) {
+  if ((m->cols() != dimension) || (m->rows() != dimension)) {
+    Werror("Error in multmap");
+    return;
+  }
+  bigintmat *bas = new bigintmat(dimension, 1, basecoeffs());
+  for (int i=1; i<=dimension; i++) {
+    // Durchläuft alle Basiselemente
+    // Multipliziert i-tes Basiselement mit a
+    basis_elt(bas, i);
+    elMult(bas, a);
+    // Schreibt Ergebnis in i-te Zeile der Matrix m. Am Ende ist m dann die Abbildungsmatrix der Multiplikation mit a
+    m->setcol(i, bas);
+  }
+  delete bas;
+}
+
+/*________________1_______________ */
+void basis_elt(bigintmat *m, int i) {
+  if (((m->rows() == 1) && (i <= m->cols())) || ((m->cols() == 1) && (i <= m->rows()))) {
+    // Falls m Zeilen- oder Spaltenvektor ist, setze alle Einträge auf 0 und Eintrag i auf 1 (Koeff-Vektor des i-ten Basiselements)
+    number t1 = n_Init(0,m->basecoeffs());
+    for (int j=0; ((j<m->rows()) || (j<m->cols())); j++) {
+      m->set(j, t1);
+
+    }
+    n_Delete(&t1,m->basecoeffs());
+    number t2 = n_Init(1,m->basecoeffs());
+    m->set(i-1, t2);
+    n_Delete(&t2,m->basecoeffs());
+  }
+  else
+    Werror("Error in basis_elt. Not a vector.");
+}
+
+////////////////////////////////////
+//////////// 2 Round 2 /////////////
+////////////////////////////////////
+//TODO: make the radical a proper ideal rather than a matrix
+//  or at least, provide an ideal based interface
+//  similar, expand the multring to deal with ideals
+
+bigintmat *radicalmodpbase(nforder *o, number p, coeffs c) {
+
+  number dimen = n_Init(o->getDim(), o->basecoeffs());
+  int n = o->getDim();
+
+  bigintmat *m, *bas;
+  // Berechnet F_p-Basis von I_p/pI_p (Radical mod p)
+  // Dazu:
+  if (n_Greater(p, dimen, c)) {
+    // Falls Primzahl größer gleich Dimension der Ordnung, so berechne Kern der Spurmatrix modulo p.
+    // also works it p is no prime.
+    m = o->traceMatrix();
+    bas = new bigintmat(n, 1, o->basecoeffs());
+  } else {
+    // Sonst: Berechne Kern der Abbildung x -> x^(p^j) mod p, wobei j>0 mit p^j >= dimension
+    int j = 1;
+    // ex als number, oder reicht long long int?
+    // Finde j von oben und berechne p^j
+    number ex = n_Init(1, o->basecoeffs());
+    number temp;
+    while (n_Greater(dimen, ex, o->basecoeffs())) {
+      temp = n_Mult(ex, p, o->basecoeffs());
+      n_Delete(&ex, o->basecoeffs());
+      ex = temp;
+      j++;
+    }
+
+    // Berechne Abbildungsmatrix der oben genannten Abbildung und speichere diese in m (genauere Erklärung dazu: Siehe multmap())
+    m = new bigintmat(n, n, o->basecoeffs());
+    bas = new bigintmat(n, 1, o->basecoeffs());
+    bigintmat *prod = new bigintmat(n, 1, o->basecoeffs());
+
+    number klauf;
+    number eins = n_Init(1, o->basecoeffs());
+
+    for (int i=1; i<=n; i++) {
+      basis_elt(bas, i);
+      prod->copy(bas);
+      klauf = n_Init(1, o->basecoeffs());
+      for (; n_Greater(ex, klauf, o->basecoeffs());) {
+        o->elMult(prod, bas);
+        prod->mod(p, c);
+        temp = n_Add(klauf, eins, o->basecoeffs());
+        n_Delete(&klauf, o->basecoeffs());
+        klauf = temp;
+      }
+      n_Delete(&klauf, o->basecoeffs());
+      m->setcol(i, prod);
+    }
+
+    delete prod;
+    n_Delete(&ex, o->basecoeffs());
+    n_Delete(&eins, o->basecoeffs());
+
+  }
+
+  bigintmat *kbase = new bigintmat(n, n, o->basecoeffs());
+
+  // Speichere Basiselemente von Kern der Matrix m (Spurmatrix oder Abbildungsmatrix, je nach if-else-Fall) (von Z/pZ -> Z/pZ) in kbase (ersten kdim Spalten bilden Basis)
+  int kdim = kernbase(m, kbase, p, c);
+  // Schreibe für jedes i=1,, .., dimension p*(i-tes Basiselement) als Spalten in Matrix gen, dahinter die oben errechnete Basis vom Kern
+  // Wir erhalten (als Spalten) ein Erzeugendensystem vom Kern von Z->Z/pZ: x->x^(p^j)
+  bigintmat *gen = new bigintmat(n, n+kdim, o->basecoeffs());
+
+  for (int i=1; i<=n; i++) {
+    basis_elt(bas, i);
+    bas->skalmult(p, c);
+    gen->setcol(i, bas);
+  }
+  for (int i=1; i<=kdim; i++) {
+    kbase->getcol(i, bas);
+    gen->setcol(i+n, bas);
+  }
+
+  // HNF auf EZS anwenden liefert (als letzten dimension Spalten) eine Basis des Kerns
+  gen->hnf();
+  bigintmat *tmp = new bigintmat(n, 1, o->basecoeffs());
+  bigintmat *nbase = new bigintmat(n, n, o->basecoeffs());
+  // Schreibe diese als Spalten in nbase und gib nbase zurück
+  for (int i=1; i<=n; i++) {
+    gen->getcol(gen->cols()-n+i, tmp);
+    nbase->setcol(i, tmp);
+  }
+
+  n_Delete(&dimen, o->basecoeffs());
+  delete m;
+  delete bas;
+  delete kbase;
+  delete gen;
+  delete tmp;
+  return nbase;
+
+}
+
+void rowhnf(bigintmat * b) {
+  bigintmat * n = b->transpose(), *m;
+//  for(int i=1; i<= n->rows() /2; i++)
+//    n->swaprow(i, n->rows()-i+1);
+// TODO: needs probable more row&column swapping.
+  n->hnf();
+  m =  n->transpose();
+  b->copy(m);
+  delete n;
+  delete m;
+}
+
+number multring(bigintmat *nbase, nforder *o, number p) {
+  coeffs R = o->basecoeffs();
+  number divi;
+  int n = o->getDim();
+
+  bigintmat *inv = new bigintmat(n, n, R);
+  divi = nbase->pseudoinv(inv);
+
+  // Zusammenbau der "langen" Matrix
+  bigintmat *lon = new bigintmat(n, 0, R);
+  bigintmat *oldlon;
+  bigintmat *mm = new bigintmat(n, n, R);
+  bigintmat *temp = new bigintmat(n, 1, R);
+  bigintmat *nochnetemp = new bigintmat(n, n, R);
+
+  for (int i=1; i<=n; i++) {
+    nbase->getcol(i, temp);
+    o->multmap(temp, mm);
+    bimMult(inv, mm, nochnetemp);
+    mm->copy(nochnetemp);
+    mm->inpTranspose();
+    oldlon = lon;
+    lon = new bigintmat(n, (i)*n, o->basecoeffs());
+    lon->concatcol(oldlon, mm);
+    delete oldlon;
+  }
+
+  lon->skaldiv(divi);
+
+  bigintmat * red;
+  if (1) {
+    bigintmat * cmp = lon->modhnf(p, o->basecoeffs());
+    red = cmp;
+  } else {
+    lon->hnf();
+    red = new bigintmat(n, n, o->basecoeffs());
+    lon->getColRange((n-1)*n+1, n, red);
+  }
+  delete lon;
+  red->inpTranspose();
+
+  number divisor = red->pseudoinv(nbase);
+  nbase->hnf();
+
+  delete inv;
+  delete mm;
+  delete temp;
+  delete red;
+  delete nochnetemp;
+  n_Delete(&divi, o->basecoeffs());
+  return divisor;
+}
+
+nforder *onestep(nforder *o, number p, coeffs c) {
+  // Berechne F_p-Basis von I_p/pI_p
+  bigintmat *basis;
+  basis = radicalmodpbase(o, p, c);
+
+
+  // Bestimme Basis vom Ring der Multiplikatoren (speicher diese in basis), und Nenner davon (in divisor)
+  number divisor = multring(basis, o, p);
+  // Erzeuge neue Ordnung, der o zu Grunde liegt, mit Basis basis und Nenner divisor
+  if (basis->isOne() && n_IsOne(divisor, c)) {
+    delete basis;
+    n_Delete(&divisor, c);
+    return o;
+  }
+
+  nforder *no = new nforder(o, basis, divisor, c);
+
+  delete basis;
+  n_Delete(&divisor, c);
+  return no;
+}
+
+nforder *pmaximal(nforder *o, number p) {
+  coeffs c = o->basecoeffs();
+  nforder *no = o;
+  nforder *otemp;
+  // TODO: check if p^2 still divides disc (maybe in onestep)
+  // simplify the tower
+  do {
+    otemp = no;
+    no = onestep(otemp, p, c);
+    if (no==otemp)
+      break;
+    nforder_delete (otemp);
+    otemp = no->simplify();
+    nforder_delete (no);
+    no = otemp;
+  } while (1);
+  return no;
+}
+
+/*
+// Zum Round2 fehlt noch die Faktorisierung der Diskriminante. Daher auch noch nicht getestet
+nforder *round2(nforder *o) {
+  nforder *otemp = new nforder(o,basecoeffs());
+  number p = otemp->getsmallestsqprime(); // Benötigt kleinste Primzahl, die die Disc. quadratisch teilt
+  nforder *no;
+  number eins = n_Init(1, basecoeffs());
+  number tmp;
+  while (n_GreaterZero(p,basecoeffs())) {
+    // Laufe durch Primzahlen p, die die Ordnung quadratisch teilen, und erzeuge p-maximale Ordnung
+    no = pmaximal(otemp, p);
+    delete otemp;
+    otemp = no;
+    // Nimm nächstgrößere Primzahl, welche die Ordnung quadratisch teilt
+    tmp = n_Add(p,eins, basecoeffs());
+    p = otemp->getsmallestsqprime(tmp); // Benötigt kleinste Primzahl größer tmp, die die Disc. quad. teilt
+    n_Delete(&tmp, basecoeffs());
+  }
+  n_Delete(&p, basecoeffs());
+  n_Delete(&eins, basecoeffs());
+  return otemp;
+}
+*/
+
+
+void nforder::createmulttable(bigintmat **a) {
+  // Falls es eine Multtable gibt, liefere eine Kopie davon zurück
+  if (multtable != NULL) {
+    for (int i=0; i<dimension; i++) {
+      a[i] = new bigintmat(multtable[i]);
+    }
+  }
+  else {
+    // Sonst berechne sie auf kanonische Art und Weise
+    bigintmat *bas = new bigintmat(1, dimension, basecoeffs());
+    for (int i=0; i<dimension; i++) {
+      basis_elt(bas, i+1);
+      a[i] = new bigintmat(dimension, dimension, basecoeffs());
+      multmap(bas, a[i]);
+    }
+  }
+}
diff --git a/Singular/dyn_modules/Order/nforder.h b/Singular/dyn_modules/Order/nforder.h
new file mode 100644
index 0000000..5e4dcac
--- /dev/null
+++ b/Singular/dyn_modules/Order/nforder.h
@@ -0,0 +1,137 @@
+//////////////////////////////////////////
+//////////////////////////////////////////
+////     Einfache Ordnungs-Klasse     ////
+//////////////////////////////////////////
+// Kira Kraft, Jan Albert, Marco Sieben //
+/////// Praktikum bei Herrn Fieker ///////
+//////////////////////////////////////////
+//////////////////////////////////////////
+/*
+ * - Einer Ordnung liegt entweder eine Multiplikationstabelle zu Grunde, oder sie wird durch eine O-Basis erzeugt, wobei O eine andere Ordnung ist
+ * - Ordnungselemente werden als Koeffizientenvektoren (Klasse matrix, Zeilenvektoren!) dargestellt und können addiert/subtrahiert/multipliziert werden
+ * - Die Diskriminante kann von selbst berechnet werden
+*/
+#ifndef NFORDER_HPP
+#define NFORDER_HPP
+
+enum order_flags_log {
+  one_is_one, //if 1 is the first basis element
+  is_maximal_known,
+  is_maximal
+};
+
+class nforder
+{
+private:
+  ////////////////////////////////////
+  ////////// Membervariablen /////////
+  ////////////////////////////////////
+  int rc;
+  number discriminant;
+  int dimension;
+  coeffs m_coeffs;
+  bigintmat **multtable; // Multiplikationstabelle als Array von Matrizen ...
+  nforder *baseorder; // ... oder zu Grunde liegende Ordnung
+  bigintmat *basis; // Lin.Komb. der Basiselemente von baseorder zu Basiselementen der Ordnung (Eine Zeile ^= ein Basiselement)
+  number divisor; // Hauptnenner der Linearkombination der Basiselemente
+    // Entweder multtable oder baseorder zeigt auf NULL - je nachdem, wie die Ordnung konstruiert wurde
+  bigintmat *inv_basis; // (inv_basis/inv_divisor) = (basis/divisor)^-1
+  number inv_divisor; //
+  int flags;
+
+  ////////////////////////////////////
+  /////// -1 Memberfunktionen ////////
+  ////////////////////////////////////
+  // Genauere Beschreibung aller Funktionen in der Funktionen.odt
+
+  void init(); //basic initialisation
+public:
+  void calcdisc(); // Berechnet Diskriminante
+  inline int ref_count_incref(){return rc++;};
+  inline int ref_count_decref(){return rc--;};
+  inline int ref_count(){return rc;};
+
+
+  ////////////////////////////////////
+  /// 0 Konstruktoren/Destruktoren ///
+  ////////////////////////////////////
+   //Lädt entweder Multiplikationstabelle von location, oder legt Ordnung o zu Grunde (mit Basis base und Hauptnenner div)
+  nforder(int dim, bigintmat **m, const coeffs q); // (keine Übergabe von const char *, sondern von bigintmat *, diese wird kopiert und als multtable verwendet)
+  nforder(nforder *o, bigintmat *base, number div, const coeffs q);
+  nforder(nforder *o, int);
+
+  ~nforder();
+  void Write();
+  char* String();
+  void Print();
+  nforder *simplify(); //collapses a tower: multipy all bases together
+
+  ////////////////////////////////////
+  // +1 Zugriff auf Membervariablen //
+  ////////////////////////////////////
+
+  number getDisc();
+  inline number viewDisc(){return discriminant;};
+  int getDim();
+  inline coeffs basecoeffs() const { return m_coeffs; }
+  number getDiv();
+  // Liefert Zeiger auf Kopier der Objekte zurück
+  bool getMult(bigintmat **m);
+  nforder *getBase();
+  bigintmat *getBasis();
+  bigintmat *viewBasis();
+
+  inline bool oneIsOne() {return (flags & (1<<one_is_one)) != 0;}
+  inline void setOneIsOne() {flags |= (1<<one_is_one);}
+
+  inline bool isMaximalKnown() {return (flags & (1<<is_maximal_known)) != 0;};
+  inline bool isMaximal() {return isMaximalKnown() && (flags & (1<<is_maximal_known));};
+  inline void setIsMaximal(bool is) {flags = (flags & (~((1<<is_maximal_known) + (1<<is_maximal)))) | (1<<is_maximal_known) | (is*(1<<is_maximal));};
+
+
+
+  ////////////////////////////////////
+  ////// +2 Elementoperationen ///////
+  ////////////////////////////////////
+  // Addiert/Subtrahiert/Multipliziert zu a das Element b hinzu
+  void elAdd(bigintmat *a, bigintmat *b);
+  void elSub(bigintmat *a, bigintmat *b);
+  void elMult(bigintmat *a, bigintmat *b);
+  number elTrace(bigintmat *a);
+  number elNorm(bigintmat *a);
+  bigintmat * elRepMat(bigintmat *a);
+
+  ////////////////////////////////////
+  //// +3 Funktionen für Round 2 /////
+  ////////////////////////////////////
+  // long long int getsmallestsqprime();
+  /* Liefert kleinste Primzahl >= p, die die Diskriminante quadratisch teilt  */
+  void multmap(bigintmat *a, bigintmat *m);
+  bigintmat *traceMatrix();
+
+  void createmulttable(bigintmat **a);
+
+};
+
+////////////////////////////////////
+////// 1 Komfortfunktionen /////////
+////////////////////////////////////
+/* Setzt Vektor m auf (0,...,0,1,0,...,0) (i-ten Basisvektor)  */
+void basis_elt(bigintmat *m, int i);
+
+////////////////////////////////////
+//////////// 2 Round 2 /////////////
+////////////////////////////////////
+/* Liefert bzgl. Primzahl p um eines größere Ordnung von o zurück */
+nforder *onestep(nforder *o, number p, coeffs c);
+/* Macht liefert p-maximale Ordnung von o zurück  */
+nforder *pmaximal(nforder *o, number p);
+/* Liefert Maximalordnung, ausgehend von o, zurück  */
+nforder *round2(nforder *o); // Benötigt Faktorisierung der Diskriminanten
+/* Liefert Basis von I_p(O)/pI_p(O)  */
+bigintmat *radicalmodpbase(nforder *o, number p, coeffs c);
+/* Berechnet die Basis mit Hilfe der langen Matrix  */
+number multring(bigintmat* nbase, nforder *o, number p);
+void nforder_delete(nforder *o);
+
+#endif
diff --git a/Singular/dyn_modules/Order/nforder_elt.cc b/Singular/dyn_modules/Order/nforder_elt.cc
new file mode 100644
index 0000000..8f3704f
--- /dev/null
+++ b/Singular/dyn_modules/Order/nforder_elt.cc
@@ -0,0 +1,269 @@
+#include "kernel/mod2.h" // general settings/macros
+//#include"kernel/febase.h"  // for Print, WerrorS
+#include"Singular/ipid.h" // for SModulFunctions, leftv
+#include"Singular/number2.h" // for SModulFunctions, leftv
+#include<coeffs/numbers.h> // nRegister, coeffs.h
+#include <coeffs/coeffs.h>
+#include"Singular/blackbox.h" // blackbox type
+#include "nforder.h"
+#include <coeffs/bigintmat.h>
+
+extern n_coeffType nforder_type;
+
+static void WriteRing(const coeffs r, BOOLEAN details)
+{
+  ((nforder *)r->data)->Print();
+}
+
+static char* CoeffString(const coeffs r)
+{
+  return ((nforder *)r->data)->String();
+}
+static void EltWrite(number &a, const coeffs r)
+{
+  bigintmat * b = (bigintmat*)a;
+  if (a) {
+    bigintmat * c = b->transpose();
+    c->Write();
+    StringAppendS("^t ");
+  } else {
+    StringAppendS("(Null)\n");
+  }
+}
+
+number EltCreateMat(nforder *a, bigintmat *b)
+{
+  number xx;
+  if (b->rows()==1) {
+    assume(b->cols()==a->getDim());
+    xx = (number) b->transpose();
+  } else {
+    assume(b->rows() == a->getDim());
+    assume(b->cols() == 1);
+    xx = (number) new bigintmat((bigintmat*)b);
+  }
+//  Print("Created new element %lx from %lx\n", xx, b);
+  return (number) xx;
+}
+
+
+static BOOLEAN order_cmp(coeffs n, n_coeffType t, void*parameter)
+{
+  return (t==nforder_type) && (n->data == parameter);
+}
+
+static void KillChar(coeffs r) {
+  Print("KillChar %lx\n", r);
+}
+#ifdef LDEBUG
+  BOOLEAN EltDBTest(number, const char *, const int, const coeffs)
+{
+    return TRUE;
+}
+#endif
+
+static void SetChar(const coeffs r)
+{
+  Print("%s called\n", __func__);
+}
+                                // or NULL
+   // general stuff
+static number EltMult(number a, number b, const coeffs r)
+{
+  nforder *O = (nforder*) (r->data);
+  bigintmat *c = new bigintmat((bigintmat*)a);
+  O->elMult(c, (bigintmat*) b);
+  return (number) c;
+}
+static number EltSub(number a, number b, const coeffs r)
+{
+  nforder *O = (nforder*) (r->data);
+  bigintmat *c = new bigintmat((bigintmat*)a);
+  O->elSub(c, (bigintmat*) b);
+  return (number) c;
+}
+static number EltAdd(number a, number b, const coeffs r)
+{
+  nforder *O = (nforder*) (r->data);
+  bigintmat *c = new bigintmat((bigintmat*)a);
+  O->elAdd(c, (bigintmat*) b);
+  return (number) c;
+}
+static number EltDiv(number a, number b, const coeffs r)
+{
+  Werror("%s called\n", __func__, a, b, r);
+  return NULL;
+}
+static number EltIntDiv(number a, number b, const coeffs r)
+{
+  Werror("IntDiv called on order elts", a, b, r);
+  return NULL;
+}
+static number EltIntMod(number a, number b, const coeffs r)
+{
+  Werror("IntMod called on order elts", a, b, r);
+  return NULL;
+}
+static number EltExactDiv(number a, number b, const coeffs r)
+{
+  Werror("%s called\n", __func__, a, b, r);
+  return NULL;
+}
+   /// init with an integer
+static number  EltInit(long i,const coeffs r)
+
+{
+  nforder * O = (nforder*) r->data;
+  if (!O) return NULL; //during init, this seems to be called with O==NULL
+  coeffs C = O->basecoeffs();
+  bigintmat * b = new bigintmat(O->getDim(), 1, C);
+  if (O->oneIsOne()) {
+    basis_elt(b, 1);
+    number I = n_Init(i, C);
+    b->skalmult(I, C);
+    n_Delete(&I, C);
+    return (number) b;
+  } else
+    return NULL;
+}
+
+   /// init with a GMP integer
+static number  EltInitMPZ(mpz_t i, const coeffs r)
+
+{
+  Werror("%s called\n", __func__);
+  return NULL;
+}
+   /// how complicated, (0) => 0, or positive
+static int EltSize(number n, const coeffs r)
+
+{
+  Werror("%s called\n", __func__);
+  return NULL;
+}
+   /// convertion to int, 0 if impossible
+static int EltInt(number &n, const coeffs r)
+
+{
+  Werror("%s called\n", __func__);
+  return NULL;
+}
+   /// Converts a non-negative number n into a GMP number, 0 if impossible
+static void EltMPZ(mpz_t result, number &n, const coeffs r)
+
+{
+  Werror("%s called\n", __func__);
+}
+   /// changes argument  inline: a:= -a
+   /// return -a! (no copy is returned)
+   /// the result should be assigned to the original argument: e.g. a = n_Neg(a,r)
+static number  EltNeg(number a, const coeffs r)
+   /// return -a
+{
+  Werror("%s called\n", __func__);
+  return NULL;
+}
+static number  EltInvers(number a, const coeffs r)
+   /// return 1/a
+{
+  Werror("%s called\n", __func__);
+  return NULL;
+}
+static number  EltCopy(number a, const coeffs r)
+{
+  return EltCreateMat((nforder*)r->data, (bigintmat*)a);
+}
+
+static const char * EltRead(const char * s, number * a, const coeffs r)
+{
+//  Print("%s called with ->%s-<\n", __func__, s);
+  return s;
+}
+
+static BOOLEAN EltEqual(number a,number b, const coeffs r)
+{
+  Print("%s called\n", __func__, a, b, r);
+  return 0;
+}
+static BOOLEAN EltGreater(number a,number b, const coeffs r)
+{
+  Print("%s called\n", __func__, a, b, r);
+  return 0;
+}
+static BOOLEAN EltIsOne(number a, const coeffs r)
+{
+//  Print("%s called\n", __func__, a, r);
+  return 0;
+}
+static BOOLEAN EltIsMOne(number a, const coeffs r)
+{
+//  Print("%s called\n", __func__, a, r);
+  return 0;
+}
+static BOOLEAN EltGreaterZero(number a, const coeffs r)
+{
+//  Print("%s called\n", __func__, a, r);
+  return 1;
+}
+static BOOLEAN EltIsZero(number a, const coeffs r)
+{
+  return (a==NULL) || ((bigintmat*)a)->isZero();
+}
+
+static nMapFunc EltSetMap(const coeffs src, const coeffs dst)
+{
+  Print("%s called\n", __func__, src, dst);
+  return NULL;
+}
+
+static void EltDelete(number * a, const coeffs r)
+{
+//  Print("Deleting %lx\n%s\n", *a, (((bigintmat*)(*a))->String()));
+
+  delete (bigintmat*)(*a);
+  *a = NULL;
+}
+
+BOOLEAN n_nfOrderInit(coeffs r,  void * parameter)
+{
+  assume( getCoeffType(r) == nforder_type );
+  r->nCoeffIsEqual=order_cmp;
+  r->cfKillChar = KillChar;
+  r->cfSetChar = SetChar;
+  r->cfCoeffString=CoeffString;
+  r->cfCoeffWrite=WriteRing;
+  r->cfWriteShort=EltWrite;
+  r->cfInit = EltInit;
+  r->cfMult = EltMult;
+  r->cfSub = EltSub;
+  r->cfAdd = EltAdd;
+  r->cfDiv = EltDiv;
+  r->cfExactDiv = EltExactDiv;
+  r->cfInitMPZ = EltInitMPZ;
+  r->cfSize = EltSize;
+  r->cfInt = EltInt;
+  r->cfMPZ = EltMPZ;
+  r->cfInpNeg = EltNeg;
+  r->cfInvers = EltInvers;
+  r->cfCopy = EltCopy;
+  r->data = parameter;
+
+  r->cfWriteLong = EltWrite;
+  r->cfRead =EltRead;
+  r->cfGreater = EltGreater;
+  r->cfEqual = EltEqual;
+  r->cfIsZero = EltIsZero;
+  r->cfIsOne = EltIsOne;
+  r->cfIsMOne = EltIsMOne;
+  r->cfGreaterZero = EltGreaterZero;
+  r->cfDelete = EltDelete;
+  r->cfSetMap = EltSetMap;
+  if (parameter)
+    r->nNULL = EltInit(0, r);
+#ifdef LDEBUG
+  r->cfDBTest = EltDBTest;
+#endif
+  return FALSE;
+}
+
+
diff --git a/Singular/dyn_modules/Order/nforder_elt.h b/Singular/dyn_modules/Order/nforder_elt.h
new file mode 100644
index 0000000..8e8d4fa
--- /dev/null
+++ b/Singular/dyn_modules/Order/nforder_elt.h
@@ -0,0 +1,10 @@
+#ifndef NFORDER_ELT_HPP
+#define NFORDER_ELT_HPP
+
+extern n_coeffType nforder_type;
+
+number EltCreateMat(nforder *a, bigintmat *b);
+
+BOOLEAN n_nfOrderInit(coeffs r,  void * parameter);
+
+#endif
diff --git a/Singular/dyn_modules/Order/nforder_ideal.cc b/Singular/dyn_modules/Order/nforder_ideal.cc
new file mode 100644
index 0000000..d0e9b6c
--- /dev/null
+++ b/Singular/dyn_modules/Order/nforder_ideal.cc
@@ -0,0 +1,322 @@
+#include <coeffs/bigintmat.h>
+#include "nforder.h"
+#include <reporter/reporter.h>
+#include <coeffs/numbers.h>
+#include <coeffs/coeffs.h>
+#include "Singular/ipid.h"
+#include "nforder_ideal.h"
+
+
+
+
+////////////////////////////////////
+//// Konstruktoren/Destruktoren ////
+////////////////////////////////////
+
+/*________________0_______________*/
+void nforder_ideal::init() {
+  memset(this, 0, sizeof(nforder_ideal));
+}
+
+nforder_ideal::nforder_ideal(bigintmat * _basis, const coeffs O) {
+  init();
+  ord = O;
+  basis = new bigintmat(_basis);
+}
+
+nforder_ideal::nforder_ideal(nforder_ideal *I, int) {
+  init();
+  ord = I->ord;
+  coeffs C = ((nforder *)ord->data)->basecoeffs();
+  basis = new bigintmat(I->basis);
+  if (I->den) {
+    den = n_Copy(I->den, C);
+  }
+  if (I->norm) {
+    norm = n_Copy(I->norm, C);
+    norm_den = n_Copy(I->norm_den, C);
+  }
+  if (I->min) {
+    min = n_Copy(I->min, C);
+    min_den = n_Copy(I->min_den, C);
+  }
+}
+
+void nforder_ideal::Write() {
+  coeffs C = ((nforder *)ord->data)->basecoeffs();
+  if (isFractional()) {
+    StringAppendS("Fractional ");
+  }
+  StringAppend("Ideal with basis:\n");
+  basis->Write();
+  if (isFractional()) {
+    number d;
+    StringAppend(" / ");
+    n_Write((d = viewBasisDen()), C);
+  }
+  StringAppendS("\n");
+  if (norm) {
+    StringAppendS("and norm ");
+    n_Write(norm, C);
+    StringAppendS(" / ");
+    n_Write(norm_den, C);
+    StringAppendS(" ");
+  }
+  if (min) {
+    StringAppendS("and min ");
+    n_Write(min, C);
+    StringAppendS(" / ");
+    n_Write(min_den, C);
+    StringAppendS(" ");
+  }
+}
+
+char * nforder_ideal::String() {
+  StringSetS("");
+  Write();
+  return StringEndS();
+}
+void nforder_ideal::Print() {
+  char * s = String();
+  PrintS(s);
+  PrintS("\n");
+  omFree(s);
+}
+
+nforder_ideal::~nforder_ideal() {
+  if (basis) delete basis;
+  coeffs C = ((nforder *)ord->data)->basecoeffs();
+  if (den) n_Delete(&den, C);
+  if (norm) {
+    n_Delete(&norm, C);
+    n_Delete(&norm_den, C);
+  }
+  if (min) {
+    n_Delete(&min, C);
+    n_Delete(&min_den, C);
+  }
+}
+
+nforder_ideal * nf_idAdd(nforder_ideal *A, nforder_ideal *B)
+{
+  assume(A->order() == B->order());
+  nforder * O = (nforder*) A->order()->data;
+  coeffs C = O->basecoeffs();
+  bigintmat * r = new bigintmat(O->getDim(), 2*O->getDim(), C),
+            *s1, *s2;
+  number den = NULL;
+  if (B->isFractional()) {
+    s1 = A->getBasis();
+    s1->skalmult(B->viewBasisDen(), C);
+    den = n_Copy(B->viewBasisDen(), C);
+  } else {
+    s1 = A->viewBasis();
+  }
+  if (A->isFractional()) {
+    s2 = B->getBasis();
+    s2->skalmult(A->viewBasisDen(), C);
+    if (den) {
+      number d = n_Mult(den, A->viewBasisDen(), C);
+      n_Delete(&den, C);
+      den = d;
+    } else {
+      den = n_Copy(A->viewBasisDen(), C);
+    }
+  } else {
+    s2 = B->viewBasis();
+  }
+  r->concatcol(s1, s2);
+
+  if (A->isFractional())
+    delete s2;
+  if (B->isFractional())
+    delete s1;
+
+  number modA = NULL, modB = NULL;
+  if (!(modA = A->viewMin())) {
+    modA = A->viewNorm();
+  }
+  if (!(modB = B->viewMin())) {
+    modB = B->viewNorm();
+  }
+  bigintmat *t2;
+  if (modA && modB) {
+    number mod = n_Gcd(modA, modB, C);
+    t2 = r->modhnf(mod, C);
+    n_Delete(&mod, C);
+  } else {
+    r->hnf();
+    t2 = new bigintmat(O->getDim(), O->getDim(), C);
+    t2->copySubmatInto(r, 1, O->getDim()+1, O->getDim(), O->getDim(), 1,1);
+  }
+  delete r;
+  if (den) {
+    t2->simplifyContentDen(&den);
+  }
+  nforder_ideal *D = new nforder_ideal(t2, A->order());
+  if (den)
+    D->setBasisDenTransfer(den);
+
+  if (O->oneIsOne())
+    D->setMinTransfer(t2->get(1,1), den ? n_Copy(den, C) : n_Init(1, C));
+  D->setNormTransfer(t2->det(), den ? n_Copy(den, C) : n_Init(1, C));
+  delete t2;
+  return D;
+}
+
+
+nforder_ideal * nf_idMult(nforder_ideal *A, nforder_ideal *B)
+{
+  assume(A->order() == B->order());
+  nforder * O = (nforder*) A->order()->data;
+  coeffs C = O->basecoeffs();
+  number den = NULL;
+
+  bigintmat * r= NULL;
+  bigintmat * c = new bigintmat(O->getDim(), 1, C),
+            *rep = new bigintmat(O->getDim(), O->getDim(), C);
+  for(int i=0; i<O->getDim(); i++) {
+    A->viewBasis()->getcol(i+1, c);
+    O->multmap(c, rep);
+    bigintmat * cc = bimMult(rep, B->viewBasis());
+    if (r) {
+      bigintmat * s = new bigintmat(O->getDim(), r->cols()+O->getDim(), C);
+      s->concatcol(r, cc);
+      delete r;
+      delete cc;
+      r = s;
+    } else {
+      r = cc;
+    }
+  }
+  delete c;
+
+  number modA = NULL, modB = NULL;
+  if (!(modA = A->viewMin())) {
+    modA = A->viewNorm();
+  }
+  if (!(modB = B->viewMin())) {
+    modB = B->viewNorm();
+  }
+
+
+  bigintmat * t1;
+  if (modA && modB) {
+    number mod = n_Mult(modA, modB, C);
+    t1 = r->modhnf(mod, C);
+    n_Delete(&mod, C);
+  } else {
+    r->hnf();
+    t1 = new bigintmat(O->getDim(), O->getDim(), C);
+    r->getColRange(r->cols()-O->getDim()+1, O->getDim(), t1);
+  }
+  delete r;
+
+  if (A->isFractional()) {
+    den = A->viewBasisDen();
+  }
+  if (B->isFractional()) {
+    if (den)
+      den = n_Mult(den, B->viewBasisDen(), C);
+    else
+      den = n_Copy(B->viewBasisDen(), C);
+  }
+  if (den) {
+    t1->simplifyContentDen(&den);
+  }
+  nforder_ideal *D = new nforder_ideal(t1, A->order());
+  if (den)
+    D->setBasisDenTransfer(den);
+
+  if (O->oneIsOne())
+    D->setMinTransfer(t1->get(1,1), den ? n_Copy(den, C) : n_Init(1, C));
+  D->setNormTransfer(t1->det(), den ? n_Copy(den, C) : n_Init(1, C));
+  delete t1;
+  return D;
+}
+
+nforder_ideal* nf_idMult(nforder_ideal * A, number b)
+{
+  nforder * O = (nforder*) A->order()->data;
+  coeffs C = O->basecoeffs();
+  bigintmat * r = O->elRepMat((bigintmat*) b);
+  bigintmat * s = bimMult(r, A->viewBasis());
+  delete r;
+  if (A->isFractional()) {
+    number d = n_Copy(A->viewBasisDen(), C);
+    s->simplifyContentDen(&d);
+    nforder_ideal * res = new nforder_ideal(s, A->order());
+    res->setBasisDenTransfer(d);
+    return res;
+  } else {
+    return new nforder_ideal(s, A->order());
+  }
+}
+
+nforder_ideal * nf_idInit(int i, coeffs O)
+{
+  nforder *ord = (nforder*) O->data;
+  coeffs C = ord->basecoeffs();
+  bigintmat * r = new bigintmat(ord->getDim(), ord->getDim(), C);
+  r->one();
+  number I = n_Init(i, C);
+  r->skalmult(I, C);
+  nforder_ideal * A = new nforder_ideal(r, O);
+  delete r;
+  number n;
+  n_Power(I, ord->getDim(), &n, C);
+  A->setNormTransfer(n, n_Init(1, C));
+  A->setMinTransfer(I, n_Init(1, C));
+  return A;
+}
+
+nforder_ideal * nf_idInit(number I, coeffs O)
+{
+  nforder *ord = (nforder*) O->data;
+  bigintmat * r = ord->elRepMat((bigintmat*)I);
+  nforder_ideal * A = new nforder_ideal(r, O);
+  delete r;
+  return A;
+}
+
+nforder_ideal* nf_idMult(nforder_ideal * A, int b)
+{
+  nforder * O = (nforder*) A->order()->data;
+  coeffs C = O->basecoeffs();
+  bigintmat * s = new bigintmat(A->viewBasis());
+  number bb = n_Init(b, C);
+  s->skalmult(bb, C);
+  n_Delete(&bb, C);
+
+  if (A->isFractional()) {
+    number d = n_Copy(A->viewBasisDen(), C);
+    s->simplifyContentDen(&d);
+    nforder_ideal * res = new nforder_ideal(s, A->order());
+    res->setBasisDenTransfer(d);
+    return res;
+  } else {
+    return new nforder_ideal(s, A->order());
+  }
+}
+
+nforder_ideal* nf_idPower(nforder_ideal* A, int i)
+{
+  if (i==0) {
+    return nf_idInit(1, A->order());
+  } else if (i==1) {
+    return new nforder_ideal(A, 1);
+  } else if (i<0) {
+    Werror("not done yet");
+  } else {
+    nforder_ideal *B = nf_idPower(A, i/2);
+    nforder_ideal *res = nf_idMult(B, B);
+    delete B;
+    if (i&1) {
+      nforder_ideal * C = nf_idMult(res, B);
+      delete res;
+      return C;
+    } else {
+      return res;
+    }
+  }
+}
diff --git a/Singular/dyn_modules/Order/nforder_ideal.h b/Singular/dyn_modules/Order/nforder_ideal.h
new file mode 100644
index 0000000..aa2366a
--- /dev/null
+++ b/Singular/dyn_modules/Order/nforder_ideal.h
@@ -0,0 +1,71 @@
+//////////////////////////////////////////
+//////////////////////////////////////////
+////     ideals in oforder    ////////////
+//////////////////////////////////////////
+//////////////////////////////////////////
+#ifndef NFORDER_IDEAL_HPP
+#define NFORDER_IDEAL_HPP
+
+#include <coeffs/bigintmat.h>
+
+class nforder_ideal
+{
+private:
+  ////////////////////////////////////
+  ////////// Membervariablen /////////
+  ////////////////////////////////////
+  number norm, norm_den, min, min_den;
+  coeffs ord;  // but of dynamic type order! (as cring)
+  bigintmat *basis;
+  number den;  // fractional ideals....
+public:
+
+  ////////////////////////////////////
+  /// 0 Konstruktoren/Destruktoren ///
+  ////////////////////////////////////
+  nforder_ideal();
+  void init();
+  nforder_ideal(bigintmat *basis,
+                   number * min, number * min_den,
+                   number * norm, number * norm_den,
+                   const coeffs ord);
+  nforder_ideal(bigintmat *basis, const coeffs q);
+  nforder_ideal(nforder_ideal *i, int);
+
+  ~nforder_ideal();
+  void Write();
+  char * String();
+  void Print();
+
+  ////////////////////////////////////
+  // +1 Zugriff auf Membervariablen //
+  ////////////////////////////////////
+
+  number getNorm(), getNormDen(), getMin(), getMinDen();
+  inline coeffs order() const { return ord; }
+  inline bigintmat * viewBasis() {return basis;};
+  inline bigintmat * getBasis() {return new bigintmat(basis);};
+  inline number viewBasisDen() {return den;};
+  inline int isFractional() {return den!=NULL;};
+  inline void setMinTransfer(number a, number b){min = a; min_den = b;}
+  inline void setNormTransfer(number a, number b){norm = a; norm_den = b;}
+  inline number viewNorm() { return norm;};
+  inline number viewMin() { return norm;};
+  inline void setBasisDenTransfer(number a){den = a;}
+
+  ////////////////////////////////////
+  ////// +2 Elementoperationen ///////
+  ////////////////////////////////////
+  // Addiert/Subtrahiert/Multipliziert zu a das Element b hinzu
+};
+
+nforder_ideal* nf_idAdd(nforder_ideal *a, nforder_ideal *b);
+nforder_ideal* nf_idMult(nforder_ideal *a, nforder_ideal *b);
+nforder_ideal* nf_idMult(nforder_ideal *a, number b);
+nforder_ideal* nf_idMult(nforder_ideal *a, int b);
+nforder_ideal* nf_idPower(nforder_ideal *a, int b);
+nforder_ideal* nf_idInit(int, coeffs);
+nforder_ideal* nf_idInit(number, coeffs);
+nforder_ideal* nf_idDiv(nforder_ideal *a, nforder_ideal *b);
+nforder_ideal* nf_idMeet(nforder_ideal *a, nforder_ideal *b);
+#endif
diff --git a/Singular/dyn_modules/Order/singular.cc b/Singular/dyn_modules/Order/singular.cc
new file mode 100644
index 0000000..d3f7316
--- /dev/null
+++ b/Singular/dyn_modules/Order/singular.cc
@@ -0,0 +1,514 @@
+#include "kernel/mod2.h" // general settings/macros
+#include "Singular/mod_lib.h"
+//#include"kernel/febase.h"  // for Print, WerrorS
+#include"Singular/ipid.h" // for SModulFunctions, leftv
+#include"Singular/number2.h" // for SModulFunctions, leftv
+#include<coeffs/numbers.h> // nRegister, coeffs.h
+#include <coeffs/coeffs.h>
+#include"Singular/blackbox.h" // blackbox type
+#include "nforder.h"
+#include "nforder_elt.h"
+#include "nforder_ideal.h"
+#include <coeffs/bigintmat.h>
+
+#ifdef SINGULAR_4_1
+static int nforder_type_id=0;
+n_coeffType nforder_type =n_unknown;
+
+// coeffs stuff: -----------------------------------------------------------
+static coeffs nforder_AE=NULL;
+static void nforder_Register()
+{
+  puts("nforder_Register called");
+  nforder_type=nRegister(n_unknown,n_nfOrderInit);
+  nforder_AE=nInitChar(nforder_type,NULL);
+}
+// black box stuff: ---------------------------------------------------------
+static void * nforder_ideal_Init(blackbox */*b*/)
+{
+  nforder_AE->ref++;
+  return nforder_AE;
+}
+static char * nforder_ideal_String(blackbox *b, void *d)
+{
+  StringSetS("");
+  if (d) ((nforder_ideal *)d)->Write();
+  else StringAppendS("o not defined o");
+  return StringEndS();
+}
+static void * nforder_ideal_Copy(blackbox* /*b*/, void *d)
+{ return new nforder_ideal((nforder_ideal*)d, 1);}
+
+static BOOLEAN nforder_ideal_Assign(leftv l, leftv r)
+{
+  if (l->Typ()==r->Typ())
+  {
+    if (l->rtyp==IDHDL)
+    {
+      IDDATA((idhdl)l->data)=(char *)nforder_ideal_Copy((blackbox*)NULL, r->data);
+    }
+    else
+    {
+      l->data=(char *)nforder_ideal_Copy((blackbox*)NULL, r->data);
+    }
+    return FALSE;
+  }
+  return TRUE;
+}
+static void nforder_ideal_destroy(blackbox * /*b*/, void *d)
+{
+  if (d!=NULL)
+  {
+    delete (nforder_ideal*)d;
+  }
+}
+
+BOOLEAN checkArgumentIsOrder(leftv arg, nforder * cmp, nforder ** result)
+{
+  if (arg->Typ() != CRING_CMD) return FALSE;
+  coeffs R = (coeffs) arg->Data();
+  if (getCoeffType(R) != nforder_type) return FALSE;
+  nforder * O = (nforder*) R->data;
+  if (cmp && cmp != O) return FALSE;
+  *result = O;
+  return TRUE;
+}
+
+BOOLEAN checkArgumentIsBigintmat(leftv arg, coeffs r, bigintmat ** result)
+{
+  if (arg->Typ() != BIGINTMAT_CMD) return FALSE;
+  bigintmat * b = (bigintmat*) arg->Data();
+  if (r && b->basecoeffs() != r) return FALSE;
+  *result = b;
+  return TRUE;
+}
+
+BOOLEAN checkArgumentIsNumber2(leftv arg, coeffs r, number2 * result)
+{
+  if (arg->Typ() != CNUMBER_CMD) return FALSE;
+  number2 b = (number2) arg->Data();
+  if (r && b->cf != r) return FALSE;
+  *result = b;
+  return TRUE;
+}
+
+
+BOOLEAN checkArgumentIsNFOrderIdeal(leftv arg, coeffs r, nforder_ideal ** result)
+{
+  if (arg->Typ() != nforder_type_id) return FALSE;
+  *result = (nforder_ideal *) arg->Data();
+  if (r && (*result)->order() != r) return FALSE;
+  return TRUE;
+}
+
+BOOLEAN checkArgumentIsInt(leftv arg, int* result)
+{
+  if (arg->Typ() != INT_CMD) return FALSE;
+  *result = (long) arg->Data();
+  return TRUE;
+}
+
+BOOLEAN checkArgumentIsBigint(leftv arg, number* result)
+{
+  switch (arg->Typ()) {
+    case BIGINT_CMD:
+      *result = (number)arg->Data();
+      return TRUE;
+      break;
+    case NUMBER_CMD:
+      if (currRing->cf == coeffs_BIGINT &&
+          getCoeffType(coeffs_BIGINT) == n_Z) {
+        *result = (number)arg->Data();
+        return TRUE;
+      } else
+        return FALSE;
+      break;
+    case CNUMBER_CMD:
+      {
+        number2 n = (number2)arg->Data();
+        if (getCoeffType(n->cf) == n_Z) {
+          *result = n->n;
+          return TRUE;
+        }
+        return FALSE;
+        break;
+      }
+    default:
+      return FALSE;
+  }
+}
+
+static BOOLEAN nforder_ideal_Op2(int op,leftv l, leftv r1, leftv r2)
+{
+  Print("Types are %d %d\n", r1->Typ(), r2->Typ());
+  number2 e;
+  int f;
+  nforder_ideal *I, *J, *H;
+  switch (op) {
+    case '+':
+      {
+      if (!checkArgumentIsNFOrderIdeal(r1, NULL, &I))
+        return TRUE;
+      if (!checkArgumentIsNFOrderIdeal(r2, I->order(), &J))
+        return TRUE;
+      H = nf_idAdd(I, J);
+      break;
+      }
+    case '*':
+      {
+      if (!checkArgumentIsNFOrderIdeal(r1, NULL, &I)) {
+        leftv r = r1;
+        r1 = r2;
+        r2 = r; //at least ONE argument has to be an ideal
+      }
+      if (!checkArgumentIsNFOrderIdeal(r1, NULL, &I))
+        return TRUE;
+      if (checkArgumentIsNFOrderIdeal(r2, I->order(), &J)) {
+        H = nf_idMult(I, J);
+      } else if (checkArgumentIsNumber2(r2, I->order(), &e)) {
+        H = nf_idMult(I, e->n);
+      } else if (checkArgumentIsInt(r2, &f)) {
+        H = nf_idMult(I, f);
+      } else
+        return TRUE;
+      break;
+      }
+    case '^':
+      {
+        if (!checkArgumentIsNFOrderIdeal(r1, NULL, &I))
+          return TRUE;
+        if (!checkArgumentIsInt(r2, &f))
+          return TRUE;
+        H = nf_idPower(I, f);
+        break;
+      }
+    default:
+      return TRUE;
+  }
+  l->rtyp = nforder_type_id;
+  l->data = (void*)H;
+  return FALSE;
+}
+static BOOLEAN nforder_ideal_bb_setup()
+{
+  blackbox *b=(blackbox*)omAlloc0(sizeof(blackbox));
+  // all undefined entries will be set to default in setBlackboxStuff
+  // the default Print is quite useful,
+  // all other are simply error messages
+  b->blackbox_destroy=nforder_ideal_destroy;
+  b->blackbox_String=nforder_ideal_String;
+  //b->blackbox_Print=blackbox_default_Print;
+  b->blackbox_Init=nforder_ideal_Init;
+  b->blackbox_Copy=nforder_ideal_Copy;
+  b->blackbox_Assign=nforder_ideal_Assign;
+  //b->blackbox_Op1=blackbox_default_Op1;
+  b->blackbox_Op2=nforder_ideal_Op2;
+  //b->blackbox_Op3=blackbox_default_Op3;
+  //b->blackbox_OpM=blackbox_default_OpM;
+  nforder_type_id = setBlackboxStuff(b,"NFOrderIdeal");
+  Print("setup: created a blackbox type [%d] '%s'",nforder_type_id, getBlackboxName(nforder_type_id));
+  PrintLn();
+  return FALSE; // ok, TRUE = error!
+}
+
+// module stuff: ------------------------------------------------------------
+
+BOOLEAN checkBigintmatDim(bigintmat * b, int r, int c)
+{
+  if (b->rows() != r) return FALSE;
+  if (b->cols() != c) return FALSE;
+  return TRUE;
+}
+
+#define returnNumber(_res, _n, _R) \
+  do {                                                          \
+    number2 _r = (number2)omAlloc(sizeof(struct snumber2));     \
+    _r->n = _n;                                                 \
+    _r->cf = _R;                                                \
+    _res->rtyp = CNUMBER_CMD;                                   \
+    _res->data = _r;                                            \
+  } while (0)
+
+
+static BOOLEAN build_ring(leftv result, leftv arg)
+{
+  nforder *o;
+  if (arg->Typ() == LIST_CMD) {
+    lists L = (lists)arg->Data();
+    int n = lSize(L)+1;
+    bigintmat **multtable = (bigintmat**)omAlloc(n*sizeof(bigintmat*));
+    for(int i=0; i<n; i++) {
+      multtable[i] = (bigintmat*)(L->m[i].Data());
+    }
+    o = new nforder(n, multtable, nInitChar(n_Z, 0));
+    omFree(multtable);
+  } else {
+    assume(arg->Typ() == INT_CMD);
+    int dimension = (int)(long)arg->Data();
+
+    bigintmat **multtable = (bigintmat**)omAlloc(dimension*sizeof(bigintmat*));
+    arg = arg->next;
+    for (int i=0; i<dimension; i++) {
+      multtable[i] = new bigintmat((bigintmat*)arg->Data());
+      arg = arg->next;
+    }
+    o = new nforder(dimension, multtable, nInitChar(n_Z, 0));
+    for (int i=0; i<dimension; i++) {
+      delete multtable[i];
+    }
+    omFree(multtable);
+  }
+  result->rtyp=CRING_CMD; // set the result type
+  result->data=(char*)nInitChar(nforder_type, o);// set the result data
+
+  return FALSE;
+}
+
+static BOOLEAN ideal_from_mat(leftv result, leftv arg)
+{
+  nforder * O;
+  if (!checkArgumentIsOrder(arg, NULL, &O)) {
+    WerrorS("usage: IdealFromMat(order, basis matrix)");
+    return TRUE;
+  }
+  arg = arg->next;
+  bigintmat *b;
+  if (!checkArgumentIsBigintmat(arg, O->basecoeffs(), &b)) {
+    WerrorS("3:usage: IdealFromMat(order, basis matrix)");
+    return TRUE;
+  }
+  result->rtyp = nforder_type_id;
+  result->data = new nforder_ideal(b, nInitChar(nforder_type, O));
+  return FALSE;
+}
+
+
+static BOOLEAN elt_from_mat(leftv result, leftv arg)
+{
+  nforder * O;
+  if (!checkArgumentIsOrder(arg, NULL, &O)) {
+    WerrorS("usage: EltFromMat(order, matrix)");
+    return TRUE;
+  }
+  arg = arg->next;
+  bigintmat *b;
+  if (!checkArgumentIsBigintmat(arg, O->basecoeffs(), &b)) {
+    WerrorS("2:usage: EltFromMat(order, matrix)");
+    return TRUE;
+  }
+  returnNumber(result, (number)EltCreateMat(O, b), nInitChar(nforder_type, O));
+  return FALSE;
+}
+
+static BOOLEAN discriminant(leftv result, leftv arg)
+{
+  nforder * O;
+  if (!checkArgumentIsOrder(arg, NULL, &O)) {
+    WerrorS("usage: Discriminant(order)");
+    return TRUE;
+  }
+  O->calcdisc();
+
+  returnNumber(result, O->getDisc(), O->basecoeffs());
+  return FALSE;
+}
+
+static BOOLEAN pMaximalOrder(leftv result, leftv arg)
+{
+  nforder * o;
+  if (!checkArgumentIsOrder(arg, NULL, &o)) {
+    WerrorS("usage: pMaximalOrder(order, int)");
+    return TRUE;
+  }
+  arg = arg->next;
+  long p = (int)(long)arg->Data();
+  number P = n_Init(p, o->basecoeffs());
+
+  nforder *op = pmaximal(o, P);
+
+  result->rtyp=CRING_CMD; // set the result type
+  result->data=(char*)nInitChar(nforder_type, op);// set the result data
+  assume(result->data);
+
+  return FALSE;
+}
+
+static BOOLEAN oneStep(leftv result, leftv arg)
+{
+  assume (arg->Typ()==CRING_CMD);
+  coeffs c = (coeffs)arg->Data();
+  assume (c->type == nforder_type);
+  nforder * o = (nforder*)c->data;
+  arg = arg->next;
+  long p = (int)(long)arg->Data();
+  number P = n_Init(p, o->basecoeffs());
+
+  nforder *op = onestep(o, P, o->basecoeffs());
+
+  result->rtyp=CRING_CMD; // set the result type
+  result->data=(char*)nInitChar(nforder_type, op);// set the result data
+
+  return FALSE;
+}
+
+static BOOLEAN nforder_simplify(leftv result, leftv arg)
+{
+  nforder * o;
+  if (!checkArgumentIsOrder(arg, NULL, &o)) {
+    WerrorS("usage: NFOrderSimplify(order)");
+    return TRUE;
+  }
+  nforder *op = o->simplify();
+
+  result->rtyp=CRING_CMD; // set the result type
+  result->data=(char*)nInitChar(nforder_type, op);// set the result data
+
+  return FALSE;
+}
+
+static BOOLEAN eltTrace(leftv result, leftv arg)
+{
+  number2 a;
+  if (!checkArgumentIsNumber2(arg, NULL, &a)) {
+    WerrorS("EltTrace(elt)");
+    return TRUE;
+  }
+  coeffs  c = a->cf;
+  if (getCoeffType(c) != nforder_type) {
+    WerrorS("EltTrace(elt in order)");
+    return TRUE;
+  }
+  bigintmat * aa = (bigintmat*)a->n;
+  nforder * o = (nforder*)c->data;
+  number t = o->elTrace(aa);
+  returnNumber(result, t, o->basecoeffs());
+  return FALSE;
+}
+
+static BOOLEAN eltNorm(leftv result, leftv arg)
+{
+  number2 a;
+  if (!checkArgumentIsNumber2(arg, NULL, &a)) {
+    WerrorS("EltNorm(elt)");
+    return TRUE;
+  }
+  coeffs  c = a->cf;
+  if (getCoeffType(c) != nforder_type) {
+    WerrorS("EltNorm(elt in order)");
+    return TRUE;
+  }
+  bigintmat * aa = (bigintmat*)a->n;
+  nforder * o = (nforder*)c->data;
+  number t = o->elNorm(aa);
+  returnNumber(result, t, o->basecoeffs());
+  return FALSE;
+}
+
+static BOOLEAN eltRepMat(leftv result, leftv arg)
+{
+  assume (arg->Typ()==CNUMBER_CMD);
+  number2 a = (number2) arg->Data();
+  coeffs  c = a->cf;
+  bigintmat * aa = (bigintmat*)a->n;
+  assume (c->type == nforder_type);
+  nforder * o = (nforder*)c->data;
+  bigintmat* t = o->elRepMat(aa);
+  result->rtyp = BIGINTMAT_CMD;
+  result->data = t;
+  return FALSE;
+}
+
+static BOOLEAN smithtest(leftv result, leftv arg)
+{
+  assume (arg->Typ()==BIGINTMAT_CMD);
+  bigintmat *a = (bigintmat *) arg->Data();
+  arg = arg->next;
+
+  long p = (int)(long)arg->Data();
+  number P = n_Init(p, a->basecoeffs());
+
+  bigintmat * A, *B;
+  diagonalForm(a, &A, &B);
+
+
+  result->rtyp = NONE;
+  return FALSE;
+}
+
+
+extern "C" int SI_MOD_INIT(Order)(SModulFunctions* psModulFunctions)
+{
+  nforder_Register();
+  nforder_ideal_bb_setup();
+  psModulFunctions->iiAddCproc(
+          (currPack->libname? currPack->libname: ""),// the library name,
+          "nfOrder",// the name for the singular interpreter
+          FALSE,  // should not be static
+          build_ring); // the C/C++ routine
+
+  psModulFunctions->iiAddCproc(
+          (currPack->libname? currPack->libname: ""),// the library name,
+          "pMaximalOrder",// the name for the singular interpreter
+          FALSE,  // should not be static
+          pMaximalOrder); // the C/C++ routine
+
+  psModulFunctions->iiAddCproc(
+          (currPack->libname? currPack->libname: ""),// the library name,
+          "oneStep",// the name for the singular interpreter
+          FALSE,  // should not be static
+          oneStep); // the C/C++ routine
+
+  psModulFunctions->iiAddCproc(
+          (currPack->libname? currPack->libname: ""),
+          "Discriminant",
+          FALSE,
+          discriminant);
+
+  psModulFunctions->iiAddCproc(
+          (currPack->libname? currPack->libname: ""),
+          "EltFromMat",
+          FALSE,
+          elt_from_mat);
+
+  psModulFunctions->iiAddCproc(
+          (currPack->libname? currPack->libname: ""),
+          "NFOrderSimplify",
+          FALSE,
+          nforder_simplify);
+
+  psModulFunctions->iiAddCproc(
+          (currPack->libname? currPack->libname: ""),
+          "EltNorm",
+          FALSE,
+          eltNorm);
+
+  psModulFunctions->iiAddCproc(
+          (currPack->libname? currPack->libname: ""),
+          "EltTrace",
+          FALSE,
+          eltTrace);
+
+  psModulFunctions->iiAddCproc(
+          (currPack->libname? currPack->libname: ""),
+          "EltRepMat",
+          FALSE,
+          eltRepMat);
+
+  psModulFunctions->iiAddCproc(
+          (currPack->libname? currPack->libname: ""),
+          "SmithTest",
+          FALSE,
+          smithtest);
+
+  psModulFunctions->iiAddCproc(
+          (currPack->libname? currPack->libname: ""),
+          "IdealFromMat",
+          FALSE,
+          ideal_from_mat);
+
+  module_help_main(
+     (currPack->libname? currPack->libname: "NFOrder"),// the library name,
+    "nforder: orders in number fields"); // the help string for the module
+  return MAX_TOK;
+}
+#endif
diff --git a/Singular/dyn_modules/bigintm/Makefile.am b/Singular/dyn_modules/bigintm/Makefile.am
new file mode 100644
index 0000000..85c73ef
--- /dev/null
+++ b/Singular/dyn_modules/bigintm/Makefile.am
@@ -0,0 +1,34 @@
+ACLOCAL_AMFLAGS = -I ../../m4
+
+if SI_BUILTIN_BIGINTM
+  noinst_LTLIBRARIES=bigintm.la
+#  check_LTLIBRARIES=bigintm.la
+  P_PROCS_CPPFLAGS_COMMON = -DSTATIC_VERSION
+  P_PROCS_MODULE_LDFLAGS  = -module
+else
+  module_LTLIBRARIES=bigintm.la
+  moduledir = $(libexecdir)/singular/MOD
+  P_PROCS_CPPFLAGS_COMMON = -DDYNAMIC_VERSION
+  P_PROCS_MODULE_LDFLAGS = -module -export-dynamic -avoid-version -flat_namespace -weak_reference_mismatches weak -undefined dynamic_lookup
+  # Add under Mac OS X: -flat_namespace -weak_reference_mismatches weak -undefined dynamic_lookup
+endif
+
+MYINCLUDES =  -I${top_srcdir} -I${top_builddir} \
+-I${top_srcdir}/libpolys -I${top_builddir}/libpolys \
+$(FACTORY_INCLUDES) $(RESOURCES_INCLUDES) $(OMALLOC_INCLUDES) \
+$(FLINT_CFLAGS) $(NTL_CFLAGS) $(GMP_CFLAGS)
+
+bigintm_la_SOURCES  = mod_main.cc bigintm.cc bigintm.h
+bigintm_la_CPPFLAGS = ${MYINCLUDES} ${P_PROCS_CPPFLAGS_COMMON}
+bigintm_la_LDFLAGS  = ${P_PROCS_MODULE_LDFLAGS}
+
+# AM_COLOR_TESTS=always
+#
+# TESTS_ENVIRONMENT  = SINGULARPATH='${abs_top_builddir}/Singular/LIB:${abs_top_srcdir}/Singular/LIB:${abs_top_builddir}/libpolys/polys/.libs:${abs_top_builddir}/factory/gftables:${abs_builddir}/.libs:${abs_srcdir}'
+# TESTS_ENVIRONMENT += SINGULAR_ROOT_DIR='${abs_top_builddir}'
+# TESTS_ENVIRONMENT += SINGULAR_BIN_DIR='${abs_top_builddir}/Singular'
+#
+# TESTS=test_release.sh
+#
+# EXTRA_DIST = test.sh $(TESTS)
+
diff --git a/Singular/dyn_modules/bigintm/Makefile.in b/Singular/dyn_modules/bigintm/Makefile.in
new file mode 100644
index 0000000..55766c4
--- /dev/null
+++ b/Singular/dyn_modules/bigintm/Makefile.in
@@ -0,0 +1,778 @@
+# Makefile.in generated by automake 1.13.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 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@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+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 = Singular/dyn_modules/bigintm
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/build-aux/depcomp
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_append_compile_flags.m4 \
+	$(top_srcdir)/m4/ax_append_flag.m4 \
+	$(top_srcdir)/m4/ax_append_link_flags.m4 \
+	$(top_srcdir)/m4/ax_check_compile_flag.m4 \
+	$(top_srcdir)/m4/ax_check_link_flag.m4 \
+	$(top_srcdir)/m4/ax_compute_relative_paths.m4 \
+	$(top_srcdir)/m4/ax_normalize_path.m4 \
+	$(top_srcdir)/m4/ax_prefix_config_h.m4 \
+	$(top_srcdir)/m4/ax_pthread.m4 \
+	$(top_srcdir)/m4/ax_python_embed.m4 \
+	$(top_srcdir)/m4/ax_python_with_version.m4 \
+	$(top_srcdir)/m4/cpu-check.m4 $(top_srcdir)/m4/dbm-check.m4 \
+	$(top_srcdir)/m4/flags.m4 $(top_srcdir)/m4/flint-check.m4 \
+	$(top_srcdir)/m4/gfanlib-check.m4 \
+	$(top_srcdir)/m4/gmp-check.m4 \
+	$(top_srcdir)/m4/google-perftools.m4 \
+	$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+	$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+	$(top_srcdir)/m4/lt~obsolete.m4 \
+	$(top_srcdir)/m4/mathic-check.m4 $(top_srcdir)/m4/ntl-check.m4 \
+	$(top_srcdir)/m4/options.m4 $(top_srcdir)/m4/p-procs.m4 \
+	$(top_srcdir)/m4/polymake-check.m4 \
+	$(top_srcdir)/m4/readline-check.m4 $(top_srcdir)/configure.ac
+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__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
+am__installdirs = "$(DESTDIR)$(moduledir)"
+LTLIBRARIES = $(module_LTLIBRARIES) $(noinst_LTLIBRARIES)
+bigintm_la_LIBADD =
+am_bigintm_la_OBJECTS = bigintm_la-mod_main.lo bigintm_la-bigintm.lo
+bigintm_la_OBJECTS = $(am_bigintm_la_OBJECTS)
+AM_V_lt = $(am__v_lt_ at AM_V@)
+am__v_lt_ = $(am__v_lt_ at AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 = 
+bigintm_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+	$(CXXFLAGS) $(bigintm_la_LDFLAGS) $(LDFLAGS) -o $@
+ at SI_BUILTIN_BIGINTM_FALSE@am_bigintm_la_rpath = -rpath $(moduledir)
+ at SI_BUILTIN_BIGINTM_TRUE@am_bigintm_la_rpath =
+AM_V_P = $(am__v_P_ at AM_V@)
+am__v_P_ = $(am__v_P_ at AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_ at AM_V@)
+am__v_GEN_ = $(am__v_GEN_ at AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_ at AM_V@)
+am__v_at_ = $(am__v_at_ at AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+DEFAULT_INCLUDES = -I. at am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \
+	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+	$(AM_CXXFLAGS) $(CXXFLAGS)
+AM_V_CXX = $(am__v_CXX_ at AM_V@)
+am__v_CXX_ = $(am__v_CXX_ at AM_DEFAULT_V@)
+am__v_CXX_0 = @echo "  CXX     " $@;
+am__v_CXX_1 = 
+CXXLD = $(CXX)
+CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+	$(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CXXLD = $(am__v_CXXLD_ at AM_V@)
+am__v_CXXLD_ = $(am__v_CXXLD_ at AM_DEFAULT_V@)
+am__v_CXXLD_0 = @echo "  CXXLD   " $@;
+am__v_CXXLD_1 = 
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+	$(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_ at AM_V@)
+am__v_CC_ = $(am__v_CC_ at AM_DEFAULT_V@)
+am__v_CC_0 = @echo "  CC      " $@;
+am__v_CC_1 = 
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+	$(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_ at AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_ at AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo "  CCLD    " $@;
+am__v_CCLD_1 = 
+SOURCES = $(bigintm_la_SOURCES)
+DIST_SOURCES = $(bigintm_la_SOURCES)
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BUILTIN_LIBS = @BUILTIN_LIBS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CDDGMPCPPFLAGS = @CDDGMPCPPFLAGS@
+CDDGMPLDFLAGS = @CDDGMPLDFLAGS@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATA_DIR = @DATA_DIR@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DOC_DIR = @DOC_DIR@
+DOXYGEN = @DOXYGEN@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FACTORY_INCLUDES = @FACTORY_INCLUDES@
+FACTORY_LIBS = @FACTORY_LIBS@
+FGREP = @FGREP@
+FLINT_CFLAGS = @FLINT_CFLAGS@
+FLINT_HOME = @FLINT_HOME@
+FLINT_LIBS = @FLINT_LIBS@
+GMP_CFLAGS = @GMP_CFLAGS@
+GMP_HOME = @GMP_HOME@
+GMP_LIBS = @GMP_LIBS@
+GMP_VERSION = @GMP_VERSION@
+GREP = @GREP@
+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@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NTL_CFLAGS = @NTL_CFLAGS@
+NTL_LIBS = @NTL_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OMALLOC_INCLUDES = @OMALLOC_INCLUDES@
+OMALLOC_LIBS = @OMALLOC_LIBS@
+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@
+PKG_REQUIRE = @PKG_REQUIRE@
+PMCONFIG = @PMCONFIG@
+PM_CFLAGS = @PM_CFLAGS@
+PM_INC = @PM_INC@
+PM_LDFLAGS = @PM_LDFLAGS@
+PM_LIBS = @PM_LIBS@
+POLYMAKE_CXXFLAGS = @POLYMAKE_CXXFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LDFLAGS = @PTHREAD_LDFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
+PYTHON = @PYTHON@
+PYTHON_CSPEC = @PYTHON_CSPEC@
+PYTHON_EXECPREFIX = @PYTHON_EXECPREFIX@
+PYTHON_LSPEC = @PYTHON_LSPEC@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+RANLIB = @RANLIB@
+RESOURCES_INCLUDES = @RESOURCES_INCLUDES@
+RESOURCES_LIBS = @RESOURCES_LIBS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SINGULAR_CFLAGS = @SINGULAR_CFLAGS@
+SI_COUNTEDREF_AUTOLOAD = @SI_COUNTEDREF_AUTOLOAD@
+SI_CPU_I386 = @SI_CPU_I386@
+SI_CPU_IA64 = @SI_CPU_IA64@
+SI_CPU_PPC = @SI_CPU_PPC@
+SI_CPU_SPARC = @SI_CPU_SPARC@
+SI_CPU_X86_64 = @SI_CPU_X86_64@
+STRIP = @STRIP@
+USEPPROCSDYNAMICLD = @USEPPROCSDYNAMICLD@
+USEPPROCSDYNAMICLDFLAGS = @USEPPROCSDYNAMICLDFLAGS@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
+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@
+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@
+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@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+ACLOCAL_AMFLAGS = -I ../../m4
+ at SI_BUILTIN_BIGINTM_TRUE@noinst_LTLIBRARIES = bigintm.la
+ at SI_BUILTIN_BIGINTM_FALSE@P_PROCS_CPPFLAGS_COMMON = -DDYNAMIC_VERSION
+#  check_LTLIBRARIES=bigintm.la
+ at SI_BUILTIN_BIGINTM_TRUE@P_PROCS_CPPFLAGS_COMMON = -DSTATIC_VERSION
+ at SI_BUILTIN_BIGINTM_FALSE@P_PROCS_MODULE_LDFLAGS = -module -export-dynamic -avoid-version -flat_namespace -weak_reference_mismatches weak -undefined dynamic_lookup
+ at SI_BUILTIN_BIGINTM_TRUE@P_PROCS_MODULE_LDFLAGS = -module
+ at SI_BUILTIN_BIGINTM_FALSE@module_LTLIBRARIES = bigintm.la
+ at SI_BUILTIN_BIGINTM_FALSE@moduledir = $(libexecdir)/singular/MOD
+MYINCLUDES = -I${top_srcdir} -I${top_builddir} \
+-I${top_srcdir}/libpolys -I${top_builddir}/libpolys \
+$(FACTORY_INCLUDES) $(RESOURCES_INCLUDES) $(OMALLOC_INCLUDES) \
+$(FLINT_CFLAGS) $(NTL_CFLAGS) $(GMP_CFLAGS)
+
+bigintm_la_SOURCES = mod_main.cc bigintm.cc bigintm.h
+bigintm_la_CPPFLAGS = ${MYINCLUDES} ${P_PROCS_CPPFLAGS_COMMON}
+bigintm_la_LDFLAGS = ${P_PROCS_MODULE_LDFLAGS}
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .cc .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) --foreign Singular/dyn_modules/bigintm/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign Singular/dyn_modules/bigintm/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-moduleLTLIBRARIES: $(module_LTLIBRARIES)
+	@$(NORMAL_INSTALL)
+	@list='$(module_LTLIBRARIES)'; test -n "$(moduledir)" || list=; \
+	list2=; for p in $$list; do \
+	  if test -f $$p; then \
+	    list2="$$list2 $$p"; \
+	  else :; fi; \
+	done; \
+	test -z "$$list2" || { \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(moduledir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(moduledir)" || exit 1; \
+	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(moduledir)'"; \
+	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(moduledir)"; \
+	}
+
+uninstall-moduleLTLIBRARIES:
+	@$(NORMAL_UNINSTALL)
+	@list='$(module_LTLIBRARIES)'; test -n "$(moduledir)" || list=; \
+	for p in $$list; do \
+	  $(am__strip_dir) \
+	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(moduledir)/$$f'"; \
+	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(moduledir)/$$f"; \
+	done
+
+clean-moduleLTLIBRARIES:
+	-test -z "$(module_LTLIBRARIES)" || rm -f $(module_LTLIBRARIES)
+	@list='$(module_LTLIBRARIES)'; \
+	locs=`for p in $$list; do echo $$p; done | \
+	      sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+	      sort -u`; \
+	test -z "$$locs" || { \
+	  echo rm -f $${locs}; \
+	  rm -f $${locs}; \
+	}
+
+clean-noinstLTLIBRARIES:
+	-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+	@list='$(noinst_LTLIBRARIES)'; \
+	locs=`for p in $$list; do echo $$p; done | \
+	      sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+	      sort -u`; \
+	test -z "$$locs" || { \
+	  echo rm -f $${locs}; \
+	  rm -f $${locs}; \
+	}
+
+bigintm.la: $(bigintm_la_OBJECTS) $(bigintm_la_DEPENDENCIES) $(EXTRA_bigintm_la_DEPENDENCIES) 
+	$(AM_V_CXXLD)$(bigintm_la_LINK) $(am_bigintm_la_rpath) $(bigintm_la_OBJECTS) $(bigintm_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/bigintm_la-bigintm.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/bigintm_la-mod_main.Plo at am__quote@
+
+.cc.o:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+ at am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXXCOMPILE) -c -o $@ $<
+
+.cc.obj:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+ at am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.cc.lo:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+ at am__fastdepCXX_TRUE@	$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LTCXXCOMPILE) -c -o $@ $<
+
+bigintm_la-mod_main.lo: mod_main.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bigintm_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT bigintm_la-mod_main.lo -MD -MP -MF $(DEPDIR)/bigintm_la-mod_main.Tpo -c -o bigintm_la-mod_main.lo `test -f 'mod_main.cc' || echo '$(srcdir)/'`mod_main.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/bigintm_la-mod_main.Tpo $(DEPDIR)/bigintm_la-mod_main.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='mod_main.cc' object='bigintm_la-mod_main.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bigintm_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o bigintm_la-mod_main.lo `test -f 'mod_main.cc' || echo '$(srcdir)/'`mod_main.cc
+
+bigintm_la-bigintm.lo: bigintm.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bigintm_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT bigintm_la-bigintm.lo -MD -MP -MF $(DEPDIR)/bigintm_la-bigintm.Tpo -c -o bigintm_la-bigintm.lo `test -f 'bigintm.cc' || echo '$(srcdir)/'`bigintm.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/bigintm_la-bigintm.Tpo $(DEPDIR)/bigintm_la-bigintm.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='bigintm.cc' object='bigintm_la-bigintm.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bigintm_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o bigintm_la-bigintm.lo `test -f 'bigintm.cc' || echo '$(srcdir)/'`bigintm.cc
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	$(am__define_uniq_tagged_files); \
+	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-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	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"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+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 $(LTLIBRARIES)
+installdirs:
+	for dir in "$(DESTDIR)$(moduledir)"; 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:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+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 clean-moduleLTLIBRARIES \
+	clean-noinstLTLIBRARIES 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-moduleLTLIBRARIES
+
+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: uninstall-moduleLTLIBRARIES
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
+	clean-libtool clean-moduleLTLIBRARIES clean-noinstLTLIBRARIES \
+	cscopelist-am ctags ctags-am 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-moduleLTLIBRARIES 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 tags-am uninstall uninstall-am \
+	uninstall-moduleLTLIBRARIES
+
+ at SI_BUILTIN_BIGINTM_FALSE@  # Add under Mac OS X: -flat_namespace -weak_reference_mismatches weak -undefined dynamic_lookup
+
+# AM_COLOR_TESTS=always
+#
+# TESTS_ENVIRONMENT  = SINGULARPATH='${abs_top_builddir}/Singular/LIB:${abs_top_srcdir}/Singular/LIB:${abs_top_builddir}/libpolys/polys/.libs:${abs_top_builddir}/factory/gftables:${abs_builddir}/.libs:${abs_srcdir}'
+# TESTS_ENVIRONMENT += SINGULAR_ROOT_DIR='${abs_top_builddir}'
+# TESTS_ENVIRONMENT += SINGULAR_BIN_DIR='${abs_top_builddir}/Singular'
+#
+# TESTS=test_release.sh
+#
+# EXTRA_DIST = test.sh $(TESTS)
+
+# 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/Singular/dyn_modules/bigintm/bigintm.cc b/Singular/dyn_modules/bigintm/bigintm.cc
new file mode 100644
index 0000000..f8d2be7
--- /dev/null
+++ b/Singular/dyn_modules/bigintm/bigintm.cc
@@ -0,0 +1,317 @@
+
+
+
+
+#include <kernel/mod2.h>
+
+#include <omalloc/omalloc.h>
+#include <coeffs/coeffs.h>
+
+#include <Singular/ipid.h>
+#include <Singular/subexpr.h>
+#include <Singular/tok.h>
+#include <Singular/blackbox.h>
+#include <Singular/ipshell.h>
+
+#include <Singular/ipid.h>
+// extern coeffs coeffs_BIGINT
+
+
+#include "bigintm.h"
+
+
+#define HAVE_BIGINTM 1
+
+namespace
+{
+
+#ifdef HAVE_BIGINTM
+static int bigintm_type_id = -1;
+#endif
+
+#ifdef HAVE_BIGINTM
+static char * bigintm_String(blackbox */*b*/, void *d)
+{ if (d==NULL) return omStrDup("oo");
+   else
+   {
+     StringSetS("");
+     number n=(number)d; n_Write(n, coeffs_BIGINT); d=(void*)n;
+     return StringEndS();
+    }
+}
+static void * bigintm_Copy(blackbox*/*b*/, void *d)
+{  number n=(number)d; return n_Copy(n, coeffs_BIGINT); }
+
+static BOOLEAN bigintm_Assign(leftv l, leftv r)
+{
+  assume( l->Typ() == bigintm_type_id );
+
+  // blackbox *ll=getBlackboxStuff(l->Typ());
+
+  if (r->Typ()>MAX_TOK)
+  {
+    if (bigintm_type_id == r->Typ())
+    {
+      // blackbox *rr=getBlackboxStuff(r->Typ());
+
+      if (l->Data()!=NULL) { number n1=(number)l->Data(); n_Delete(&n1,coeffs_BIGINT); }
+      number n2=(number)r->CopyD();
+      if (l->rtyp==IDHDL)
+      {
+        IDDATA((idhdl)l->data)=(char *)n2;
+      }
+      else
+      {
+        l->data=(void *)n2;
+      }
+      return FALSE;
+    }
+    else
+    {
+      Werror("bigintm_Assign: assign %s (%d) = %s (%d)",
+             getBlackboxName(l->Typ()), l->Typ(),
+             getBlackboxName(r->Typ()), r->Typ());
+      return TRUE;
+    }
+  }
+  else if (r->Typ()==INT_CMD)
+  {
+    if (l->Data()!=NULL) { number n1=(number)l->Data(); n_Delete(&n1,coeffs_BIGINT); }
+    number n2=n_Init((int)(long)r->Data(),coeffs_BIGINT);
+    if (l->rtyp==IDHDL)
+    {
+      IDDATA((idhdl)l->data)=(char *)n2;
+    }
+    else
+    {
+      l->data=(void *)n2;
+    }
+    return FALSE;
+  }
+  else
+    Werror("assign %d = %d",l->Typ(),r->Typ());
+
+  return TRUE;
+}
+
+BOOLEAN bigintm_Op1(int op,leftv l, leftv r)
+{
+  // interpreter: a1 is ist bigintm
+  assume( r->Typ() == bigintm_type_id );
+/*
+  // "typeof( <blackbox> )" is handled by 'blackboxDefaultOp1'
+  if (op==TYPEOF_CMD)
+  {
+    l->data=omStrDup(getBlackboxName(r->Typ()));
+    l->rtyp=STRING_CMD;
+    return FALSE;
+  }
+*/
+
+  return blackboxDefaultOp1(op, l, r);
+}
+
+
+static BOOLEAN bigintm_OpM(int op, leftv res, leftv args);
+
+
+static BOOLEAN bigintm_Op2(int op, leftv res, leftv a1, leftv a2)
+{
+  // interpreter: a1 is ist bigintm
+  assume( a1->Typ() == bigintm_type_id );
+
+  // blackbox *a=getBlackboxStuff(a1->Typ());
+  number n1=(number)a1->Data();
+  switch(op)
+  {
+    case '+':
+    {
+      if (a2->Typ()==INT_CMD)
+      {
+        number n2=n_Init((int)(long)a2->Data(), coeffs_BIGINT);
+        number n=n_Add(n1,n2, coeffs_BIGINT);
+        res->data=(void *)n;
+        res->rtyp=a1->Typ();
+        return FALSE;
+      }
+      else if (a2->Typ()==a1->Typ())
+      {
+        number n2=(number)a2->Data();
+        number n=n_Add(n1,n2, coeffs_BIGINT);
+        res->data=(void *)n;
+        res->rtyp=a1->Typ();
+        return FALSE;
+      }
+
+      Werror("bigintm_Op2: Op: '+': Sorry unsupported 2nd argument-type: %s in", Tok2Cmdname(a2->Typ()));
+      return TRUE;
+    }
+
+    case '-':
+    {
+      if (a2->Typ()==INT_CMD)
+      {
+        number n2=n_Init((int)(long)a2->Data(),coeffs_BIGINT);
+        number n=n_Sub(n1,n2, coeffs_BIGINT);
+        res->data=(void *)n;
+        res->rtyp=a1->Typ();
+        return FALSE;
+      }
+      else if (a2->Typ()==a1->Typ())
+      {
+        number n2=(number)a2->Data();
+        number n=n_Sub(n1,n2, coeffs_BIGINT);
+        res->data=(void *)n;
+        res->rtyp=a1->Typ();
+        return FALSE;
+      }
+
+      Werror("bigintm_Op2: Op: '-': Sorry unsupported 2nd argument-type: %s in", Tok2Cmdname(a2->Typ()));
+      return TRUE;
+    }
+
+
+    case '*':
+    {
+      if (a2->Typ()==INT_CMD)
+      {
+        number n2=n_Init((int)(long)a2->Data(), coeffs_BIGINT);
+        number n=n_Mult(n1,n2, coeffs_BIGINT);
+        res->data=(void *)n;
+        res->rtyp=a1->Typ();
+        return FALSE;
+      }
+      else if (a2->Typ()==a1->Typ())
+      {
+        number n2=(number)a2->Data();
+        number n=n_Mult(n1,n2, coeffs_BIGINT);
+        res->data=(void *)n;
+        res->rtyp=a1->Typ();
+        return FALSE;
+      }
+      Werror("bigintm_Op2: Op: '*': Sorry unsupported 2nd argument-type: '%s' in", Tok2Cmdname(a2->Typ()));
+      return TRUE;
+    }
+
+    case EQUAL_EQUAL:
+    {
+      if( a1 == a2)
+      {
+        res->data= (void *) (TRUE);
+        res->rtyp= INT_CMD;
+        return FALSE;
+      } else
+      if (a2->Typ()==INT_CMD)
+      {
+        number n2=n_Init((int)(long)a2->Data(), coeffs_BIGINT);
+        res->data=(void *) (long) n_Equal(n1,n2, coeffs_BIGINT);
+        res->rtyp= INT_CMD;
+        n_Delete(&n2,coeffs_BIGINT);
+        return FALSE;
+      }
+      else if (a2->Typ()==a1->Typ())
+      {
+        number n2=(number)a2->Data();
+        res->data=(void *) (long) n_Equal(n1,n2, coeffs_BIGINT);
+        res->rtyp= INT_CMD;
+        return FALSE;
+      }
+
+      Werror("bigintm_Op2: Op: '==': Sorry unsupported 2nd argument-type: '%s' in", Tok2Cmdname(a2->Typ()));
+      return TRUE;
+    }
+
+    case '.':
+    {
+
+      if (a2->name==NULL)
+      {
+        Werror("bigintm_Op2: Op: '.': 2nd argument-type: '%s'(%d) should be a NAME", Tok2Cmdname(a2->Typ()), a2->Typ());
+        return TRUE;
+      }
+
+      Werror("bigintm_Op2: Op: '.': 2nd argument-type: '%s'(%d) is called '%s' in ", Tok2Cmdname(a2->Typ()), a2->Typ(), a2->name);
+      return TRUE;
+    }
+
+    default:
+      return blackboxDefaultOp2(op,res,a1,a2);
+  }
+}
+// BOOLEAN opM(int op, leftv res, leftv args)
+static BOOLEAN bigintm_OpM(int op, leftv res, leftv args)
+{
+  // interpreter: args->1. arg is ist bigintm
+  assume( args->Typ() == bigintm_type_id );
+  blackbox *a=getBlackboxStuff(args->Typ());
+  switch(op)
+  {
+    case STRING_CMD:
+    {
+      res->data=(void *)a->blackbox_String(a,args->Data());
+      res->rtyp=STRING_CMD;
+      return FALSE;
+    }
+
+    default:
+      return blackboxDefaultOpM(op, res, args);
+  }
+  return blackboxDefaultOpM(op, res, args);
+}
+
+static void bigintm_destroy(blackbox */*b*/, void *d)
+{
+  if (d!=NULL)
+  {
+    number n=(number)d;
+    n_Delete(&n, coeffs_BIGINT);
+  }
+}
+
+#endif
+
+}
+
+// this is only a demo
+BOOLEAN bigintm_setup()
+{
+#ifndef HAVE_BIGINTM
+  Werror("bigintm_setup: Sorry BIGINTM was not compiled in!");
+  return TRUE; // ok, TRUE = error!
+#else
+
+  if( bigintm_type_id == -1 )
+  {
+    blackbox *b=(blackbox*)omAlloc0(sizeof(blackbox));
+    // all undefined entries will be set to default in setBlackboxStuff
+    // the default Print is quite usefule,
+    // all other are simply error messages
+    b->blackbox_destroy=bigintm_destroy;
+    b->blackbox_String=bigintm_String;
+    //b->blackbox_Print=blackbox_default_Print;
+    //b->blackbox_Init=blackbox_default_Init;
+    b->blackbox_Copy=bigintm_Copy;
+    b->blackbox_Assign=bigintm_Assign; // TO ASK: no default?!
+    b->blackbox_Op1=bigintm_Op1;
+    b->blackbox_Op2=bigintm_Op2;
+    //b->blackbox_Op3=blackboxDefaultOp3;
+    b->blackbox_OpM=bigintm_OpM;
+
+    bigintm_type_id = setBlackboxStuff(b,"bigintm");
+
+    Print("bigintm_setup: created a blackbox type [%d] '%s'",bigintm_type_id, getBlackboxName(bigintm_type_id));
+    PrintLn();
+
+    return FALSE; // ok, TRUE = error!
+  }
+  else
+  {
+    Werror("bigintm_setup: Sorry should NOT be run twice!");
+    return TRUE; // ok, TRUE = error!
+  }
+
+#endif
+}
+
+
+
diff --git a/Singular/dyn_modules/bigintm/bigintm.h b/Singular/dyn_modules/bigintm/bigintm.h
new file mode 100644
index 0000000..2c71527
--- /dev/null
+++ b/Singular/dyn_modules/bigintm/bigintm.h
@@ -0,0 +1,6 @@
+#ifndef BIGINTM_H
+#define BIGINTM_H
+
+BOOLEAN bigintm_setup();
+
+#endif
diff --git a/Singular/dyn_modules/bigintm/mod_main.cc b/Singular/dyn_modules/bigintm/mod_main.cc
new file mode 100644
index 0000000..14cc233
--- /dev/null
+++ b/Singular/dyn_modules/bigintm/mod_main.cc
@@ -0,0 +1,50 @@
+#include <kernel/mod2.h>
+
+#include <Singular/mod_lib.h>
+
+#include <Singular/blackbox.h>
+
+#include <Singular/tok.h>
+#include <Singular/ipid.h>
+#include <Singular/lists.h>
+
+#include <dlfcn.h>
+
+#include "bigintm.h"
+
+namespace
+{
+
+static inline void NoReturn(leftv& res)
+{
+  res->rtyp = NONE;
+  res->data = NULL;
+}
+
+
+/// listing all blackbox types (debug stuff)
+static BOOLEAN printBlackboxTypes0(leftv __res, leftv /*__v*/)
+{
+  NoReturn(__res);
+  printBlackboxTypes();
+  return FALSE;
+}
+
+/// init the bigintm (a sample blackbox) type
+static BOOLEAN bigintm_setup0(leftv __res, leftv /*__v*/)
+{
+  NoReturn(__res);
+  return bigintm_setup();
+}
+
+}
+
+
+extern "C" int SI_MOD_INIT(bigintm)(SModulFunctions* psModulFunctions)
+{
+   psModulFunctions->iiAddCproc(currPack->libname,(char*)"printBlackboxTypes",FALSE, printBlackboxTypes0);
+   psModulFunctions->iiAddCproc(currPack->libname,(char*)"bigintm_setup",FALSE, bigintm_setup0);
+
+   // Q: should we call 'bigintm_setup' here??!?!?
+   return MAX_TOK;
+}
diff --git a/Singular/dyn_modules/gfanlib/Makefile.am b/Singular/dyn_modules/gfanlib/Makefile.am
new file mode 100644
index 0000000..44f8bb9
--- /dev/null
+++ b/Singular/dyn_modules/gfanlib/Makefile.am
@@ -0,0 +1,44 @@
+ACLOCAL_AMFLAGS = -I ../../m4
+
+SOURCES = bbcone.cc bbcone.h bbfan.cc bbfan.h bbpolytope.cc bbpolytope.h gfan.h gitfan.cc gitfan.h gfanlib.cc
+
+MY_CPPFLAGS =  -I${top_srcdir} -I${top_builddir} \
+-I${top_srcdir}/libpolys -I${top_builddir}/libpolys \
+${FACTORY_INCLUDES} ${RESOURCES_INCLUDES} ${OMALLOC_INCLUDES} \
+${FLINT_CFLAGS} ${NTL_CFLAGS} ${GMP_CFLAGS}
+
+if SI_BUILTIN_GFANLIB
+  noinst_LTLIBRARIES=gfanlib.la
+##  moduledir = $(libdir)/singular
+  P_PROCS_CPPFLAGS_COMMON = -DSTATIC_VERSION
+  P_PROCS_MODULE_LDFLAGS  = -module
+else
+  module_LTLIBRARIES=gfanlib.la
+  moduledir = $(libexecdir)/singular/MOD
+  P_PROCS_CPPFLAGS_COMMON = -DDYNAMIC_VERSION
+# Add under Mac OS X: -flat_namespace -weak_reference_mismatches weak -undefined dynamic_lookup
+  P_PROCS_MODULE_LDFLAGS =  -module -export-dynamic -avoid-version -flat_namespace -weak_reference_mismatches weak -undefined dynamic_lookup
+endif
+
+gfanlib_la_SOURCES  = $(SOURCES)
+
+gfanlib_la_CPPFLAGS = ${MY_CPPFLAGS} ${P_PROCS_CPPFLAGS_COMMON} ${CDDGMPCPPFLAGS}
+gfanlib_la_LDFLAGS  = ${P_PROCS_MODULE_LDFLAGS}
+
+if HAVE_GFANLIB
+ gfanlib_la_LIBADD   = ${abs_top_builddir}/gfanlib/libgfan.la ${CDDGMPLDFLAGS}
+endif
+
+#AM_COLOR_TESTS=always
+#
+#TESTS_ENVIRONMENT  = SINGULARPATH='${abs_top_builddir}/Singular/LIB:${abs_top_srcdir}/Singular/LIB:${abs_top_builddir}/libpolys/polys/.libs:${abs_top_builddir}/factory/gftables:${abs_builddir}/.libs:${abs_srcdir}'
+#TESTS_ENVIRONMENT += SINGULAR_ROOT_DIR='${abs_top_builddir}'
+#TESTS_ENVIRONMENT += SINGULAR_BIN_DIR='${abs_top_builddir}/Singular' $(SHELL) -x
+#
+#if WANT_DEBUG
+# TESTS=test_release.sh test_debug.sh
+#else
+# TESTS=test_release.sh
+#endif
+#
+# EXTRA_DIST = gfanlib.tst test.sh $(TESTS)
diff --git a/Singular/dyn_modules/gfanlib/Makefile.in b/Singular/dyn_modules/gfanlib/Makefile.in
new file mode 100644
index 0000000..97f2eac
--- /dev/null
+++ b/Singular/dyn_modules/gfanlib/Makefile.in
@@ -0,0 +1,812 @@
+# Makefile.in generated by automake 1.13.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 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@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+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 = Singular/dyn_modules/gfanlib
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/build-aux/depcomp
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_append_compile_flags.m4 \
+	$(top_srcdir)/m4/ax_append_flag.m4 \
+	$(top_srcdir)/m4/ax_append_link_flags.m4 \
+	$(top_srcdir)/m4/ax_check_compile_flag.m4 \
+	$(top_srcdir)/m4/ax_check_link_flag.m4 \
+	$(top_srcdir)/m4/ax_compute_relative_paths.m4 \
+	$(top_srcdir)/m4/ax_normalize_path.m4 \
+	$(top_srcdir)/m4/ax_prefix_config_h.m4 \
+	$(top_srcdir)/m4/ax_pthread.m4 \
+	$(top_srcdir)/m4/ax_python_embed.m4 \
+	$(top_srcdir)/m4/ax_python_with_version.m4 \
+	$(top_srcdir)/m4/cpu-check.m4 $(top_srcdir)/m4/dbm-check.m4 \
+	$(top_srcdir)/m4/flags.m4 $(top_srcdir)/m4/flint-check.m4 \
+	$(top_srcdir)/m4/gfanlib-check.m4 \
+	$(top_srcdir)/m4/gmp-check.m4 \
+	$(top_srcdir)/m4/google-perftools.m4 \
+	$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+	$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+	$(top_srcdir)/m4/lt~obsolete.m4 \
+	$(top_srcdir)/m4/mathic-check.m4 $(top_srcdir)/m4/ntl-check.m4 \
+	$(top_srcdir)/m4/options.m4 $(top_srcdir)/m4/p-procs.m4 \
+	$(top_srcdir)/m4/polymake-check.m4 \
+	$(top_srcdir)/m4/readline-check.m4 $(top_srcdir)/configure.ac
+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__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
+am__installdirs = "$(DESTDIR)$(moduledir)"
+LTLIBRARIES = $(module_LTLIBRARIES) $(noinst_LTLIBRARIES)
+am__DEPENDENCIES_1 =
+ at HAVE_GFANLIB_TRUE@gfanlib_la_DEPENDENCIES =  \
+ at HAVE_GFANLIB_TRUE@	${abs_top_builddir}/gfanlib/libgfan.la \
+ at HAVE_GFANLIB_TRUE@	$(am__DEPENDENCIES_1)
+am__objects_1 = gfanlib_la-bbcone.lo gfanlib_la-bbfan.lo \
+	gfanlib_la-bbpolytope.lo gfanlib_la-gitfan.lo \
+	gfanlib_la-gfanlib.lo
+am_gfanlib_la_OBJECTS = $(am__objects_1)
+gfanlib_la_OBJECTS = $(am_gfanlib_la_OBJECTS)
+AM_V_lt = $(am__v_lt_ at AM_V@)
+am__v_lt_ = $(am__v_lt_ at AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 = 
+gfanlib_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+	$(CXXFLAGS) $(gfanlib_la_LDFLAGS) $(LDFLAGS) -o $@
+ at SI_BUILTIN_GFANLIB_FALSE@am_gfanlib_la_rpath = -rpath $(moduledir)
+ at SI_BUILTIN_GFANLIB_TRUE@am_gfanlib_la_rpath =
+AM_V_P = $(am__v_P_ at AM_V@)
+am__v_P_ = $(am__v_P_ at AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_ at AM_V@)
+am__v_GEN_ = $(am__v_GEN_ at AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_ at AM_V@)
+am__v_at_ = $(am__v_at_ at AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+DEFAULT_INCLUDES = -I. at am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \
+	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+	$(AM_CXXFLAGS) $(CXXFLAGS)
+AM_V_CXX = $(am__v_CXX_ at AM_V@)
+am__v_CXX_ = $(am__v_CXX_ at AM_DEFAULT_V@)
+am__v_CXX_0 = @echo "  CXX     " $@;
+am__v_CXX_1 = 
+CXXLD = $(CXX)
+CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+	$(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CXXLD = $(am__v_CXXLD_ at AM_V@)
+am__v_CXXLD_ = $(am__v_CXXLD_ at AM_DEFAULT_V@)
+am__v_CXXLD_0 = @echo "  CXXLD   " $@;
+am__v_CXXLD_1 = 
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+	$(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_ at AM_V@)
+am__v_CC_ = $(am__v_CC_ at AM_DEFAULT_V@)
+am__v_CC_0 = @echo "  CC      " $@;
+am__v_CC_1 = 
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+	$(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_ at AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_ at AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo "  CCLD    " $@;
+am__v_CCLD_1 = 
+DIST_SOURCES = $(gfanlib_la_SOURCES)
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BUILTIN_LIBS = @BUILTIN_LIBS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CDDGMPCPPFLAGS = @CDDGMPCPPFLAGS@
+CDDGMPLDFLAGS = @CDDGMPLDFLAGS@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATA_DIR = @DATA_DIR@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DOC_DIR = @DOC_DIR@
+DOXYGEN = @DOXYGEN@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FACTORY_INCLUDES = @FACTORY_INCLUDES@
+FACTORY_LIBS = @FACTORY_LIBS@
+FGREP = @FGREP@
+FLINT_CFLAGS = @FLINT_CFLAGS@
+FLINT_HOME = @FLINT_HOME@
+FLINT_LIBS = @FLINT_LIBS@
+GMP_CFLAGS = @GMP_CFLAGS@
+GMP_HOME = @GMP_HOME@
+GMP_LIBS = @GMP_LIBS@
+GMP_VERSION = @GMP_VERSION@
+GREP = @GREP@
+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@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NTL_CFLAGS = @NTL_CFLAGS@
+NTL_LIBS = @NTL_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OMALLOC_INCLUDES = @OMALLOC_INCLUDES@
+OMALLOC_LIBS = @OMALLOC_LIBS@
+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@
+PKG_REQUIRE = @PKG_REQUIRE@
+PMCONFIG = @PMCONFIG@
+PM_CFLAGS = @PM_CFLAGS@
+PM_INC = @PM_INC@
+PM_LDFLAGS = @PM_LDFLAGS@
+PM_LIBS = @PM_LIBS@
+POLYMAKE_CXXFLAGS = @POLYMAKE_CXXFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LDFLAGS = @PTHREAD_LDFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
+PYTHON = @PYTHON@
+PYTHON_CSPEC = @PYTHON_CSPEC@
+PYTHON_EXECPREFIX = @PYTHON_EXECPREFIX@
+PYTHON_LSPEC = @PYTHON_LSPEC@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+RANLIB = @RANLIB@
+RESOURCES_INCLUDES = @RESOURCES_INCLUDES@
+RESOURCES_LIBS = @RESOURCES_LIBS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SINGULAR_CFLAGS = @SINGULAR_CFLAGS@
+SI_COUNTEDREF_AUTOLOAD = @SI_COUNTEDREF_AUTOLOAD@
+SI_CPU_I386 = @SI_CPU_I386@
+SI_CPU_IA64 = @SI_CPU_IA64@
+SI_CPU_PPC = @SI_CPU_PPC@
+SI_CPU_SPARC = @SI_CPU_SPARC@
+SI_CPU_X86_64 = @SI_CPU_X86_64@
+STRIP = @STRIP@
+USEPPROCSDYNAMICLD = @USEPPROCSDYNAMICLD@
+USEPPROCSDYNAMICLDFLAGS = @USEPPROCSDYNAMICLDFLAGS@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
+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@
+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@
+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@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+ACLOCAL_AMFLAGS = -I ../../m4
+SOURCES = bbcone.cc bbcone.h bbfan.cc bbfan.h bbpolytope.cc bbpolytope.h gfan.h gitfan.cc gitfan.h gfanlib.cc
+MY_CPPFLAGS = -I${top_srcdir} -I${top_builddir} \
+-I${top_srcdir}/libpolys -I${top_builddir}/libpolys \
+${FACTORY_INCLUDES} ${RESOURCES_INCLUDES} ${OMALLOC_INCLUDES} \
+${FLINT_CFLAGS} ${NTL_CFLAGS} ${GMP_CFLAGS}
+
+ at SI_BUILTIN_GFANLIB_TRUE@noinst_LTLIBRARIES = gfanlib.la
+ at SI_BUILTIN_GFANLIB_FALSE@P_PROCS_CPPFLAGS_COMMON = -DDYNAMIC_VERSION
+ at SI_BUILTIN_GFANLIB_TRUE@P_PROCS_CPPFLAGS_COMMON = -DSTATIC_VERSION
+# Add under Mac OS X: -flat_namespace -weak_reference_mismatches weak -undefined dynamic_lookup
+ at SI_BUILTIN_GFANLIB_FALSE@P_PROCS_MODULE_LDFLAGS = -module -export-dynamic -avoid-version -flat_namespace -weak_reference_mismatches weak -undefined dynamic_lookup
+ at SI_BUILTIN_GFANLIB_TRUE@P_PROCS_MODULE_LDFLAGS = -module
+ at SI_BUILTIN_GFANLIB_FALSE@module_LTLIBRARIES = gfanlib.la
+ at SI_BUILTIN_GFANLIB_FALSE@moduledir = $(libexecdir)/singular/MOD
+gfanlib_la_SOURCES = $(SOURCES)
+gfanlib_la_CPPFLAGS = ${MY_CPPFLAGS} ${P_PROCS_CPPFLAGS_COMMON} ${CDDGMPCPPFLAGS}
+gfanlib_la_LDFLAGS = ${P_PROCS_MODULE_LDFLAGS}
+ at HAVE_GFANLIB_TRUE@gfanlib_la_LIBADD = ${abs_top_builddir}/gfanlib/libgfan.la ${CDDGMPLDFLAGS}
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .cc .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) --foreign Singular/dyn_modules/gfanlib/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign Singular/dyn_modules/gfanlib/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-moduleLTLIBRARIES: $(module_LTLIBRARIES)
+	@$(NORMAL_INSTALL)
+	@list='$(module_LTLIBRARIES)'; test -n "$(moduledir)" || list=; \
+	list2=; for p in $$list; do \
+	  if test -f $$p; then \
+	    list2="$$list2 $$p"; \
+	  else :; fi; \
+	done; \
+	test -z "$$list2" || { \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(moduledir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(moduledir)" || exit 1; \
+	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(moduledir)'"; \
+	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(moduledir)"; \
+	}
+
+uninstall-moduleLTLIBRARIES:
+	@$(NORMAL_UNINSTALL)
+	@list='$(module_LTLIBRARIES)'; test -n "$(moduledir)" || list=; \
+	for p in $$list; do \
+	  $(am__strip_dir) \
+	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(moduledir)/$$f'"; \
+	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(moduledir)/$$f"; \
+	done
+
+clean-moduleLTLIBRARIES:
+	-test -z "$(module_LTLIBRARIES)" || rm -f $(module_LTLIBRARIES)
+	@list='$(module_LTLIBRARIES)'; \
+	locs=`for p in $$list; do echo $$p; done | \
+	      sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+	      sort -u`; \
+	test -z "$$locs" || { \
+	  echo rm -f $${locs}; \
+	  rm -f $${locs}; \
+	}
+
+clean-noinstLTLIBRARIES:
+	-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+	@list='$(noinst_LTLIBRARIES)'; \
+	locs=`for p in $$list; do echo $$p; done | \
+	      sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+	      sort -u`; \
+	test -z "$$locs" || { \
+	  echo rm -f $${locs}; \
+	  rm -f $${locs}; \
+	}
+
+gfanlib.la: $(gfanlib_la_OBJECTS) $(gfanlib_la_DEPENDENCIES) $(EXTRA_gfanlib_la_DEPENDENCIES) 
+	$(AM_V_CXXLD)$(gfanlib_la_LINK) $(am_gfanlib_la_rpath) $(gfanlib_la_OBJECTS) $(gfanlib_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/gfanlib_la-bbcone.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/gfanlib_la-bbfan.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/gfanlib_la-bbpolytope.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/gfanlib_la-gfanlib.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/gfanlib_la-gitfan.Plo at am__quote@
+
+.cc.o:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+ at am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXXCOMPILE) -c -o $@ $<
+
+.cc.obj:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+ at am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.cc.lo:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+ at am__fastdepCXX_TRUE@	$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LTCXXCOMPILE) -c -o $@ $<
+
+gfanlib_la-bbcone.lo: bbcone.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gfanlib_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gfanlib_la-bbcone.lo -MD -MP -MF $(DEPDIR)/gfanlib_la-bbcone.Tpo -c -o gfanlib_la-bbcone.lo `test -f 'bbcone.cc' || echo '$(srcdir)/'`bbcone.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/gfanlib_la-bbcone.Tpo $(DEPDIR)/gfanlib_la-bbcone.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='bbcone.cc' object='gfanlib_la-bbcone.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gfanlib_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gfanlib_la-bbcone.lo `test -f 'bbcone.cc' || echo '$(srcdir)/'`bbcone.cc
+
+gfanlib_la-bbfan.lo: bbfan.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gfanlib_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gfanlib_la-bbfan.lo -MD -MP -MF $(DEPDIR)/gfanlib_la-bbfan.Tpo -c -o gfanlib_la-bbfan.lo `test -f 'bbfan.cc' || echo '$(srcdir)/'`bbfan.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/gfanlib_la-bbfan.Tpo $(DEPDIR)/gfanlib_la-bbfan.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='bbfan.cc' object='gfanlib_la-bbfan.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gfanlib_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gfanlib_la-bbfan.lo `test -f 'bbfan.cc' || echo '$(srcdir)/'`bbfan.cc
+
+gfanlib_la-bbpolytope.lo: bbpolytope.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gfanlib_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gfanlib_la-bbpolytope.lo -MD -MP -MF $(DEPDIR)/gfanlib_la-bbpolytope.Tpo -c -o gfanlib_la-bbpolytope.lo `test -f 'bbpolytope.cc' || echo '$(srcdir)/'`bbpolytope.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/gfanlib_la-bbpolytope.Tpo $(DEPDIR)/gfanlib_la-bbpolytope.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='bbpolytope.cc' object='gfanlib_la-bbpolytope.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gfanlib_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gfanlib_la-bbpolytope.lo `test -f 'bbpolytope.cc' || echo '$(srcdir)/'`bbpolytope.cc
+
+gfanlib_la-gitfan.lo: gitfan.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gfanlib_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gfanlib_la-gitfan.lo -MD -MP -MF $(DEPDIR)/gfanlib_la-gitfan.Tpo -c -o gfanlib_la-gitfan.lo `test -f 'gitfan.cc' || echo '$(srcdir)/'`gitfan.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/gfanlib_la-gitfan.Tpo $(DEPDIR)/gfanlib_la-gitfan.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='gitfan.cc' object='gfanlib_la-gitfan.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gfanlib_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gfanlib_la-gitfan.lo `test -f 'gitfan.cc' || echo '$(srcdir)/'`gitfan.cc
+
+gfanlib_la-gfanlib.lo: gfanlib.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gfanlib_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gfanlib_la-gfanlib.lo -MD -MP -MF $(DEPDIR)/gfanlib_la-gfanlib.Tpo -c -o gfanlib_la-gfanlib.lo `test -f 'gfanlib.cc' || echo '$(srcdir)/'`gfanlib.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/gfanlib_la-gfanlib.Tpo $(DEPDIR)/gfanlib_la-gfanlib.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='gfanlib.cc' object='gfanlib_la-gfanlib.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gfanlib_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gfanlib_la-gfanlib.lo `test -f 'gfanlib.cc' || echo '$(srcdir)/'`gfanlib.cc
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	$(am__define_uniq_tagged_files); \
+	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-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	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"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+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 $(LTLIBRARIES)
+installdirs:
+	for dir in "$(DESTDIR)$(moduledir)"; 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:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+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 clean-moduleLTLIBRARIES \
+	clean-noinstLTLIBRARIES 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-moduleLTLIBRARIES
+
+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: uninstall-moduleLTLIBRARIES
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
+	clean-libtool clean-moduleLTLIBRARIES clean-noinstLTLIBRARIES \
+	cscopelist-am ctags ctags-am 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-moduleLTLIBRARIES 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 tags-am uninstall uninstall-am \
+	uninstall-moduleLTLIBRARIES
+
+
+#AM_COLOR_TESTS=always
+#
+#TESTS_ENVIRONMENT  = SINGULARPATH='${abs_top_builddir}/Singular/LIB:${abs_top_srcdir}/Singular/LIB:${abs_top_builddir}/libpolys/polys/.libs:${abs_top_builddir}/factory/gftables:${abs_builddir}/.libs:${abs_srcdir}'
+#TESTS_ENVIRONMENT += SINGULAR_ROOT_DIR='${abs_top_builddir}'
+#TESTS_ENVIRONMENT += SINGULAR_BIN_DIR='${abs_top_builddir}/Singular' $(SHELL) -x
+#
+#if WANT_DEBUG
+# TESTS=test_release.sh test_debug.sh
+#else
+# TESTS=test_release.sh
+#endif
+#
+# EXTRA_DIST = gfanlib.tst test.sh $(TESTS)
+
+# 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/Singular/dyn_modules/gfanlib/bbcone.cc b/Singular/dyn_modules/gfanlib/bbcone.cc
new file mode 100644
index 0000000..38354d0
--- /dev/null
+++ b/Singular/dyn_modules/gfanlib/bbcone.cc
@@ -0,0 +1,1969 @@
+#include <kernel/mod2.h>
+
+#if HAVE_GFANLIB
+
+#include <misc/intvec.h>
+#include <misc/sirandom.h>
+
+#include <coeffs/bigintmat.h>
+#include <coeffs/longrat.h>
+
+#include <Singular/ipid.h>
+#include <Singular/ipid.h>
+#include <Singular/ipshell.h>
+#include <Singular/blackbox.h>
+
+// #include <omalloc/omalloc.h>
+// #include <kernel/intvec.h>
+// #include <kernel/longrat.h>
+// #include <Singular/lists.h>
+// #include <Singular/subexpr.h>
+
+#include <gfanlib/gfanlib.h>
+#include <gfanlib/gfanlib_q.h>
+
+#include "bbfan.h"
+#include "bbpolytope.h"
+
+
+#include <sstream>
+
+int coneID;
+
+number integerToNumber(const gfan::Integer &I)
+{
+  mpz_t i;
+  mpz_init(i);
+  I.setGmp(i);
+  long m = 268435456;
+  if(mpz_cmp_si(i,m))
+  {
+    int temp = (int) mpz_get_si(i);
+    return n_Init(temp,coeffs_BIGINT);
+  }
+  else
+    return n_InitMPZ(i,coeffs_BIGINT);
+}
+
+bigintmat* zVectorToBigintmat(const gfan::ZVector &zv)
+{
+  int d=zv.size();
+  bigintmat* bim = new bigintmat(1,d,coeffs_BIGINT);
+  for(int i=1;i<=d;i++)
+  {
+    number temp = integerToNumber(zv[i-1]);
+    bim->set(1,i,temp);
+    n_Delete(&temp,coeffs_BIGINT);
+  }
+  return bim;
+}
+
+bigintmat* zMatrixToBigintmat(const gfan::ZMatrix &zm)
+{
+  int d=zm.getHeight();
+  int n=zm.getWidth();
+  bigintmat* bim = new bigintmat(d,n,coeffs_BIGINT);
+  for(int i=1;i<=d;i++)
+    for(int j=1; j<=n; j++)
+    {
+      number temp = integerToNumber(zm[i-1][j-1]);
+      bim->set(i,j,temp);
+      n_Delete(&temp,coeffs_BIGINT);
+    }
+  return bim;
+}
+
+gfan::Integer* numberToInteger(const number &n)
+{
+  if (SR_HDL(n) & SR_INT)
+    return new gfan::Integer(SR_TO_INT(n));
+  else
+    return new gfan::Integer(n->z);
+}
+
+gfan::ZMatrix* bigintmatToZMatrix(const bigintmat &bim)
+{
+  int d=bim.rows();
+  int n=bim.cols();
+  gfan::ZMatrix* zm = new gfan::ZMatrix(d,n);
+  for(int i=0;i<d;i++)
+    for(int j=0;j<n;j++)
+    {
+      number temp = BIMATELEM(bim, i+1, j+1);
+      gfan::Integer* gi = numberToInteger(temp);
+      (*zm)[i][j] = *gi;
+      delete gi;
+    }
+  return zm;
+}
+
+gfan::ZVector* bigintmatToZVector(const bigintmat &bim)
+{
+  gfan::ZVector* zv=new gfan::ZVector(bim.cols());
+  for(int j=0; j<bim.cols(); j++)
+  {
+    number temp = BIMATELEM(bim, 1, j+1);
+    gfan::Integer* gi = numberToInteger(temp);
+    (*zv)[j] = *gi;
+    n_Delete(&temp,coeffs_BIGINT);
+    delete gi;
+  }
+  return zv;
+}
+
+char* toString(gfan::ZMatrix const &zm)
+{
+  bigintmat* bim = zMatrixToBigintmat(zm);
+  char* s = bim->StringAsPrinted();
+  if (s==NULL)
+    s = (char*) omAlloc0(sizeof(char));
+  delete bim;
+  return s;
+}
+
+std::string toString(const gfan::ZCone* const c)
+{
+  std::stringstream s;
+  s<<"AMBIENT_DIM"<<std::endl;
+  s<<c->ambientDimension()<<std::endl;
+
+  gfan::ZMatrix i=c->getInequalities();
+  char* ineqs = toString(i);
+  if (c->areFacetsKnown())
+    s<<"FACETS"<<std::endl;
+  else
+    s<<"INEQUALITIES"<<std::endl;
+  if (ineqs!=NULL)
+  {
+    s<<ineqs<<std::endl;
+    omFree(ineqs);
+  }
+
+  gfan::ZMatrix e=c->getEquations();
+  char* eqs = toString(e);
+  if (c->areImpliedEquationsKnown())
+    s<<"LINEAR_SPAN"<<std::endl;
+  else
+    s<<"EQUATIONS"<<std::endl;
+  if (eqs!=NULL)
+  {
+    s<<eqs<<std::endl;
+    omFree(eqs);
+  }
+
+  if (c->areExtremeRaysKnown())
+  {
+    gfan::ZMatrix r=c->extremeRays();
+    char* rs = toString(r);
+    s<<"RAYS"<<std::endl;
+    if (rs!=NULL)
+    {
+      s<<rs<<std::endl;
+      omFree(rs);
+    }
+    gfan::ZMatrix l=c->generatorsOfLinealitySpace();
+    char* ls = toString(l);
+    s<<"LINEALITY_SPACE"<<std::endl;
+    if (ls!=NULL)
+    {
+      s<<ls<<std::endl;
+      omFree(ls);
+    }
+  }
+
+  return s.str();
+}
+
+void* bbcone_Init(blackbox* /*b*/)
+{
+  return (void*)(new gfan::ZCone());
+}
+
+BOOLEAN bbcone_Assign(leftv l, leftv r)
+{
+  gfan::ZCone* newZc;
+  if (r==NULL)
+  {
+    if (l->Data()!=NULL)
+    {
+      gfan::ZCone* zd = (gfan::ZCone*)l->Data();
+      delete zd;
+    }
+    newZc = new gfan::ZCone();
+  }
+  else if (r->Typ()==l->Typ())
+  {
+    if (l->Data()!=NULL)
+    {
+      gfan::ZCone* zd = (gfan::ZCone*)l->Data();
+      delete zd;
+    }
+    gfan::ZCone* zc = (gfan::ZCone*)r->Data();
+    newZc = new gfan::ZCone(*zc);
+  }
+  else if (r->Typ()==INT_CMD)
+  {
+    int ambientDim = (int)(long)r->Data();
+    if (ambientDim < 0)
+    {
+      Werror("expected an int >= 0, but got %d", ambientDim);
+      return TRUE;
+    }
+    if (l->Data()!=NULL)
+    {
+      gfan::ZCone* zd = (gfan::ZCone*)l->Data();
+      delete zd;
+    }
+    newZc = new gfan::ZCone(ambientDim);
+  }
+  else
+  {
+    Werror("assign Type(%d) = Type(%d) not implemented",l->Typ(),r->Typ());
+    return TRUE;
+  }
+
+  if (l->rtyp==IDHDL)
+  {
+    IDDATA((idhdl)l->data)=(char*) newZc;
+  }
+  else
+  {
+    l->data=(void *)newZc;
+  }
+  return FALSE;
+}
+
+char* bbcone_String(blackbox* /*b*/, void *d)
+{
+  if (d==NULL) return omStrDup("invalid object");
+  else
+  {
+    std::string s=toString((gfan::ZCone*) d);
+    return omStrDup(s.c_str());
+  }
+}
+
+void bbcone_destroy(blackbox* /*b*/, void *d)
+{
+  if (d!=NULL)
+  {
+    gfan::ZCone* zc = (gfan::ZCone*) d;
+    delete zc;
+  }
+}
+
+void* bbcone_Copy(blackbox* /*b*/, void *d)
+{
+  gfan::ZCone* zc = (gfan::ZCone*)d;
+  gfan::ZCone* newZc = new gfan::ZCone(*zc);
+  return newZc;
+}
+
+static BOOLEAN bbcone_Op2(int op, leftv res, leftv i1, leftv i2)
+{
+  gfan::ZCone* zp = (gfan::ZCone*) i1->Data();
+  switch(op)
+  {
+    case '&':
+    {
+      if (i2->Typ()==coneID)
+      {
+        gfan::ZCone* zq = (gfan::ZCone*) i2->Data();
+        int d1 = zp->ambientDimension();
+        int d2 = zq->ambientDimension();
+        if (d1 != d2)
+        {
+          WerrorS("mismatching ambient dimensions");
+          return TRUE;
+        }
+        gfan::ZCone* zs = new gfan::ZCone();
+        *zs = gfan::intersection(*zp, *zq);
+        zs->canonicalize();
+        res->rtyp = coneID;
+        res->data = (void*) zs;
+        return FALSE;
+      }
+      return blackboxDefaultOp2(op,res,i1,i2);
+    }
+    case '|':
+    {
+      if(i2->Typ()==coneID)
+      {
+        gfan::ZCone* zq = (gfan::ZCone*) i2->Data();
+        int d1 = zp->ambientDimension();
+        int d2 = zq->ambientDimension();
+        if (d1 != d2)
+        {
+          WerrorS("mismatching ambient dimensions");
+          return TRUE;
+        }
+        gfan::ZMatrix rays = zp->extremeRays();
+        rays.append(zq->extremeRays());
+        gfan::ZMatrix lineality = zp->generatorsOfLinealitySpace();
+        lineality.append(zq->generatorsOfLinealitySpace());
+        gfan::ZCone* zs = new gfan::ZCone();
+        *zs = gfan::ZCone::givenByRays(rays,lineality);
+        zs->canonicalize();
+        res->rtyp = coneID;
+        res->data = (void*) zs;
+        return FALSE;
+      }
+    return blackboxDefaultOp2(op,res,i1,i2);
+    }
+    case EQUAL_EQUAL:
+    {
+      if(i2->Typ()==coneID)
+      {
+        gfan::ZCone* zq = (gfan::ZCone*) i2->Data();
+        zp->canonicalize();
+        zq->canonicalize();
+        bool b = !((*zp)!=(*zq));
+        res->rtyp = INT_CMD;
+        res->data = (void*) b;
+        return FALSE;
+      }
+      return blackboxDefaultOp2(op,res,i1,i2);
+    }
+    default:
+      return blackboxDefaultOp2(op,res,i1,i2);
+  }
+  return blackboxDefaultOp2(op,res,i1,i2);
+}
+
+
+/* singular wrapper for gfanlib functions */
+static BOOLEAN jjCONENORMALS1(leftv res, leftv v)
+{
+  /* method for generating a cone object from inequalities;
+     valid parametrizations: (intmat) */
+  bigintmat* ineq = NULL;
+  if (v->Typ() == INTMAT_CMD)
+  {
+    intvec* ineq0 = (intvec*) v->Data();
+    ineq = iv2bim(ineq0,coeffs_BIGINT);
+  }
+  else
+    ineq = (bigintmat*) v->Data();
+  gfan::ZMatrix* zm = bigintmatToZMatrix(ineq);
+  gfan::ZCone* zc = new gfan::ZCone(*zm, gfan::ZMatrix(0, zm->getWidth()));
+  delete zm;
+  if (v->Typ() == INTMAT_CMD)
+    delete ineq;
+  res->rtyp = coneID;
+  res->data = (void*) zc;
+  return FALSE;
+}
+
+static BOOLEAN jjCONENORMALS2(leftv res, leftv u, leftv v)
+{
+  /* method for generating a cone object from iequalities,
+     and equations (...)
+     valid parametrizations: (intmat, intmat)
+     Errors will be invoked in the following cases:
+     - u and v have different numbers of columns */
+  bigintmat* ineq = NULL; bigintmat* eq = NULL;
+  if (u->Typ() == INTMAT_CMD)
+  {
+    intvec* ineq0 = (intvec*) u->Data();
+    ineq = iv2bim(ineq0,coeffs_BIGINT);
+  }
+  else
+    ineq = (bigintmat*) u->Data();
+  if (v->Typ() == INTMAT_CMD)
+  {
+    intvec* eq0 = (intvec*) v->Data();
+    eq = iv2bim(eq0,coeffs_BIGINT);
+  }
+  else
+    eq = (bigintmat*) v->Data();
+
+  if (ineq->cols() != eq->cols())
+  {
+    Werror("expected same number of columns but got %d vs. %d",
+           ineq->cols(), eq->cols());
+    return TRUE;
+  }
+  gfan::ZMatrix* zm1 = bigintmatToZMatrix(ineq);
+  gfan::ZMatrix* zm2 = bigintmatToZMatrix(eq);
+  gfan::ZCone* zc = new gfan::ZCone(*zm1, *zm2);
+  delete zm1;
+  delete zm2;
+  if (u->Typ() == INTMAT_CMD)
+    delete ineq;
+  if (v->Typ() == INTMAT_CMD)
+    delete eq;
+  res->rtyp = coneID;
+  res->data = (void*) zc;
+  return FALSE;
+}
+
+static BOOLEAN jjCONENORMALS3(leftv res, leftv u, leftv v, leftv w)
+{
+  /* method for generating a cone object from inequalities, equations,
+     and an integer k;
+     valid parametrizations: (intmat, intmat, int);
+     Errors will be invoked in the following cases:
+     - u and v have different numbers of columns,
+     - k not in [0..3];
+     if the 2^0-bit of k is set, then ... */
+  bigintmat* ineq = NULL; bigintmat* eq = NULL;
+  if (u->Typ() == INTMAT_CMD)
+  {
+    intvec* ineq0 = (intvec*) u->Data();
+    ineq = iv2bim(ineq0,coeffs_BIGINT);
+  }
+  else
+    ineq = (bigintmat*) u->Data();
+  if (v->Typ() == INTMAT_CMD)
+  {
+    intvec* eq0 = (intvec*) v->Data();
+    eq = iv2bim(eq0,coeffs_BIGINT);
+  }
+  else
+    eq = (bigintmat*) v->Data();
+  if (ineq->cols() != eq->cols())
+  {
+    Werror("expected same number of columns but got %d vs. %d",
+            ineq->cols(), eq->cols());
+    return TRUE;
+  }
+  int k = (int)(long)w->Data();
+  if ((k < 0) || (k > 3))
+  {
+    WerrorS("expected int argument in [0..3]");
+    return TRUE;
+  }
+  gfan::ZMatrix* zm1 = bigintmatToZMatrix(ineq);
+  gfan::ZMatrix* zm2 = bigintmatToZMatrix(eq);
+  gfan::ZCone* zc = new gfan::ZCone(*zm1, *zm2, k);
+  delete zm1;
+  delete zm2;
+  if (u->Typ() == INTMAT_CMD)
+    delete ineq;
+  if (v->Typ() == INTMAT_CMD)
+    delete eq;
+  res->rtyp = coneID;
+  res->data = (void*) zc;
+  return FALSE;
+}
+
+BOOLEAN coneViaNormals(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && ((u->Typ() == BIGINTMAT_CMD) || (u->Typ() == INTMAT_CMD)))
+  {
+    if (u->next == NULL) return jjCONENORMALS1(res, u);
+  }
+  leftv v = u->next;
+  if ((v != NULL) && ((v->Typ() == BIGINTMAT_CMD) || (v->Typ() == INTMAT_CMD)))
+  {
+    if (v->next == NULL) return jjCONENORMALS2(res, u, v);
+  }
+  leftv w = v->next;
+  if ((w != NULL) && (w->Typ() == INT_CMD))
+  {
+    if (w->next == NULL) return jjCONENORMALS3(res, u, v, w);
+  }
+  WerrorS("coneViaInequalities: unexpected parameters");
+  return TRUE;
+}
+
+static BOOLEAN jjCONERAYS1(leftv res, leftv v)
+{
+  /* method for generating a cone object from half-lines
+     (cone = convex hull of the half-lines; note: there may be
+     entire lines in the cone);
+     valid parametrizations: (intmat) */
+  bigintmat* rays = NULL;
+  if (v->Typ() == INTMAT_CMD)
+  {
+    intvec* rays0 = (intvec*) v->Data();
+    rays = iv2bim(rays0,coeffs_BIGINT);
+  }
+  else
+    rays = (bigintmat*) v->Data();
+
+  gfan::ZMatrix* zm = bigintmatToZMatrix(rays);
+  gfan::ZCone* zc = new gfan::ZCone();
+  *zc = gfan::ZCone::givenByRays(*zm, gfan::ZMatrix(0, zm->getWidth()));
+  res->rtyp = coneID;
+  res->data = (void*) zc;
+
+  delete zm;
+  if (v->Typ() == INTMAT_CMD)
+    delete rays;
+  return FALSE;
+}
+
+static BOOLEAN jjCONERAYS2(leftv res, leftv u, leftv v)
+{
+  /* method for generating a cone object from half-lines,
+     and lines (any point in the cone being the sum of a point
+     in the convex hull of the half-lines and a point in the span
+     of the lines; the second argument may contain or entirely consist
+     of zero rows);
+     valid parametrizations: (intmat, intmat)
+     Errors will be invoked in the following cases:
+     - u and v have different numbers of columns */
+  bigintmat* rays = NULL; bigintmat* linSpace = NULL;
+  if (u->Typ() == INTMAT_CMD)
+  {
+    intvec* rays0 = (intvec*) u->Data();
+    rays = iv2bim(rays0,coeffs_BIGINT);
+  }
+  else
+    rays = (bigintmat*) u->Data();
+  if (v->Typ() == INTMAT_CMD)
+  {
+    intvec* linSpace0 = (intvec*) v->Data();
+    linSpace = iv2bim(linSpace0,coeffs_BIGINT);
+  }
+  else
+    linSpace = (bigintmat*) v->Data();
+
+  if (rays->cols() != linSpace->cols())
+  {
+    Werror("expected same number of columns but got %d vs. %d",
+           rays->cols(), linSpace->cols());
+    return TRUE;
+  }
+  gfan::ZMatrix* zm1 = bigintmatToZMatrix(rays);
+  gfan::ZMatrix* zm2 = bigintmatToZMatrix(linSpace);
+  gfan::ZCone* zc = new gfan::ZCone();
+  *zc = gfan::ZCone::givenByRays(*zm1, *zm2);
+  res->rtyp = coneID;
+  res->data = (void*) zc;
+
+  delete zm1;
+  delete zm2;
+  if (u->Typ() == INTMAT_CMD)
+    delete rays;
+  if (v->Typ() == INTMAT_CMD)
+    delete linSpace;
+  return FALSE;
+}
+
+static BOOLEAN jjCONERAYS3(leftv res, leftv u, leftv v, leftv w)
+{
+  /* method for generating a cone object from half-lines,
+     and lines (any point in the cone being the sum of a point
+     in the convex hull of the half-lines and a point in the span
+     of the lines), and an integer k;
+     valid parametrizations: (intmat, intmat, int);
+     Errors will be invoked in the following cases:
+     - u and v have different numbers of columns,
+     - k not in [0..3];
+     if the 2^0-bit of k is set, then the lineality space is known
+     to be the span of the provided lines;
+     if the 2^1-bit of k is set, then the extreme rays are known:
+     each half-line spans a (different) extreme ray */
+  bigintmat* rays = NULL; bigintmat* linSpace = NULL;
+  if (u->Typ() == INTMAT_CMD)
+  {
+    intvec* rays0 = (intvec*) u->Data();
+    rays = iv2bim(rays0,coeffs_BIGINT);
+  }
+  else
+    rays = (bigintmat*) u->Data();
+  if (v->Typ() == INTMAT_CMD)
+  {
+    intvec* linSpace0 = (intvec*) v->Data();
+    linSpace = iv2bim(linSpace0,coeffs_BIGINT);
+  }
+  else
+    linSpace = (bigintmat*) v->Data();
+
+  if (rays->cols() != linSpace->cols())
+  {
+    Werror("expected same number of columns but got %d vs. %d",
+           rays->cols(), linSpace->cols());
+    return TRUE;
+  }
+  int k = (int)(long)w->Data();
+  if ((k < 0) || (k > 3))
+  {
+    WerrorS("expected int argument in [0..3]");
+    return TRUE;
+  }
+  gfan::ZMatrix* zm1 = bigintmatToZMatrix(rays);
+  gfan::ZMatrix* zm2 = bigintmatToZMatrix(linSpace);
+  gfan::ZCone* zc = new gfan::ZCone();
+  *zc = gfan::ZCone::givenByRays(*zm1, *zm2);
+  //k should be passed on to zc; not available yet
+  res->rtyp = coneID;
+  res->data = (void*) zc;
+
+  delete zm1;
+  delete zm2;
+  if (u->Typ() == INTMAT_CMD)
+    delete rays;
+  if (v->Typ() == INTMAT_CMD)
+    delete linSpace;
+  return FALSE;
+}
+
+BOOLEAN coneViaRays(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && ((u->Typ() == BIGINTMAT_CMD) || (u->Typ() == INTMAT_CMD)))
+  {
+    if (u->next == NULL) return jjCONERAYS1(res, u);
+    leftv v = u->next;
+    if ((v != NULL) && ((v->Typ() == BIGINTMAT_CMD) || (v->Typ() == INTMAT_CMD)))
+    {
+      if (v->next == NULL) return jjCONERAYS2(res, u, v);
+      leftv w = v->next;
+      if ((w != NULL) && (w->Typ() == INT_CMD))
+      {
+        if (w->next == NULL) return jjCONERAYS3(res, u, v, w);
+      }
+    }
+  }
+  WerrorS("coneViaPoints: unexpected parameters");
+  return TRUE;
+}
+
+BOOLEAN inequalities(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && (u->Typ() == coneID || u->Typ() == polytopeID))
+  {
+    gfan::ZCone* zc = (gfan::ZCone*)u->Data();
+
+    gfan::ZMatrix zmat = zc->getInequalities();
+    res->rtyp = BIGINTMAT_CMD;
+    res->data = (void*) zMatrixToBigintmat(zmat);
+    return FALSE;
+  }
+  WerrorS("inequalities: unexpected parameters");
+  return TRUE;
+}
+
+BOOLEAN equations(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && (u->Typ() == coneID || u->Typ() == polytopeID))
+  {
+    gfan::ZCone* zc = (gfan::ZCone*)u->Data();
+    gfan::ZMatrix zmat = zc->getEquations();
+    res->rtyp = BIGINTMAT_CMD;
+    res->data = (void*) zMatrixToBigintmat(zmat);
+    return FALSE;
+  }
+  WerrorS("equations: unexpected parameters");
+  return TRUE;
+}
+
+BOOLEAN facets(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && (u->Typ() == coneID || u->Typ() == polytopeID))
+  {
+    gfan::ZCone* zc = (gfan::ZCone*)u->Data();
+    gfan::ZMatrix zm = zc->getFacets();
+    res->rtyp = BIGINTMAT_CMD;
+    res->data = (void*) zMatrixToBigintmat(zm);
+    return FALSE;
+  }
+  WerrorS("facets: unexpected parameters");
+  return TRUE;
+}
+
+BOOLEAN impliedEquations(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && (u->Typ() == coneID || u->Typ() == polytopeID))
+  {
+    gfan::ZCone* zc = (gfan::ZCone*)u->Data();
+    gfan::ZMatrix zmat = zc->getImpliedEquations();
+    res->rtyp = BIGINTMAT_CMD;
+    res->data = (void*) zMatrixToBigintmat(zmat);
+    return FALSE;
+  }
+  WerrorS("span: unexpected parameters");
+  return TRUE;
+}
+
+BOOLEAN generatorsOfSpan(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && (u->Typ() == coneID || u->Typ() == polytopeID))
+  {
+    gfan::ZCone* zc = (gfan::ZCone*)u->Data();
+    gfan::ZMatrix zmat = zc->generatorsOfSpan();
+    res->rtyp = BIGINTMAT_CMD;
+    res->data = (void*) zMatrixToBigintmat(zmat);
+    return FALSE;
+  }
+  WerrorS("generatorsOfSpan: unexpected parameters");
+  return TRUE;
+}
+
+BOOLEAN generatorsOfLinealitySpace(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && (u->Typ() == coneID || u->Typ() == polytopeID))
+  {
+    gfan::ZCone* zc = (gfan::ZCone*)u->Data();
+    gfan::ZMatrix zmat = zc->generatorsOfLinealitySpace();
+    res->rtyp = BIGINTMAT_CMD;
+    res->data = (void*) zMatrixToBigintmat(zmat);
+    return FALSE;
+  }
+  WerrorS("generatorsOfLinealitySpace: unexpected parameters");
+  return TRUE;
+}
+
+BOOLEAN rays(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && (u->Typ() == coneID))
+  {
+    gfan::ZCone* zc = (gfan::ZCone*)u->Data();
+    gfan::ZMatrix zm = zc->extremeRays();
+    res->rtyp = BIGINTMAT_CMD;
+    res->data = (void*)zMatrixToBigintmat(zm);
+    return FALSE;
+  }
+  if ((u != NULL) && (u->Typ() == fanID))
+  {
+    gfan::ZFan* zf = (gfan::ZFan*)u->Data();
+    gfan::ZMatrix zmat = rays(zf);
+    res->rtyp = BIGINTMAT_CMD;
+    res->data = (void*) zMatrixToBigintmat(zmat);
+    return FALSE;
+  }
+  WerrorS("rays: unexpected parameters");
+  return TRUE;
+}
+
+BOOLEAN quotientLatticeBasis(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && (u->Typ() == coneID))
+  {
+    gfan::ZCone* zc = (gfan::ZCone*)u->Data();
+    gfan::ZMatrix zmat = zc->quotientLatticeBasis();
+    res->rtyp = BIGINTMAT_CMD;
+    res->data = (void*) zMatrixToBigintmat(zmat);
+    return FALSE;
+  }
+  WerrorS("quotientLatticeBasis: unexpected parameters");
+  return TRUE;
+}
+
+BOOLEAN getLinearForms(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && (u->Typ() == coneID))
+  {
+    gfan::ZCone* zc = (gfan::ZCone*)u->Data();
+    gfan::ZMatrix zmat = zc->getLinearForms();
+    res->rtyp = BIGINTMAT_CMD;
+    res->data = (void*) zMatrixToBigintmat(zmat);
+    return FALSE;
+  }
+  WerrorS("getLinearForms: unexpected parameters");
+  return TRUE;
+}
+
+BOOLEAN ambientDimension(leftv res, leftv args)
+{
+  leftv u=args;
+  if ((u != NULL) && (u->Typ() == coneID))
+  {
+    gfan::ZCone* zc = (gfan::ZCone*)u->Data();
+    res->rtyp = INT_CMD;
+    res->data = (void*) (long) zc->ambientDimension();
+    return FALSE;
+  }
+  if ((u != NULL) && (u->Typ() == fanID))
+  {
+    gfan::ZFan* zf = (gfan::ZFan*)u->Data();
+    res->rtyp = INT_CMD;
+    res->data = (void*) (long) getAmbientDimension(zf);
+    return FALSE;
+  }
+  if ((u != NULL) && (u->Typ() == polytopeID))
+  {
+    gfan::ZCone* zc = (gfan::ZCone*)u->Data();
+    res->rtyp = INT_CMD;
+    res->data = (void*) (long) getAmbientDimension(zc);
+    return FALSE;
+  }
+  WerrorS("ambientDimension: unexpected parameters");
+  return TRUE;
+}
+
+BOOLEAN dimension(leftv res, leftv args)
+{
+  leftv u=args;
+  if ((u != NULL) && (u->Typ() == coneID))
+  {
+    gfan::ZCone* zc = (gfan::ZCone*)u->Data();
+    res->rtyp = INT_CMD;
+    res->data = (void*) (long) zc->dimension();
+    return FALSE;
+  }
+  if ((u != NULL) && (u->Typ() == fanID))
+  {
+    gfan::ZFan* zf = (gfan::ZFan*)u->Data();
+    res->rtyp = INT_CMD;
+    res->data = (void*) (long) getDimension(zf);
+    return FALSE;
+  }
+  if ((u != NULL) && (u->Typ() == polytopeID))
+  {
+    gfan::ZCone* zc = (gfan::ZCone*)u->Data();
+    res->rtyp = INT_CMD;
+    res->data = (void*) (long) getDimension(zc);
+    return FALSE;
+  }
+  WerrorS("dimension: unexpected parameters");
+  return TRUE;
+}
+
+BOOLEAN codimension(leftv res, leftv args)
+{
+  leftv u=args;
+  if ((u != NULL) && (u->Typ() == coneID))
+    {
+      gfan::ZCone* zc = (gfan::ZCone*)u->Data();
+      res->rtyp = INT_CMD;
+      res->data = (void*) (long) zc->codimension();
+      return FALSE;
+    }
+  if ((u != NULL) && (u->Typ() == fanID))
+    {
+      gfan::ZFan* zf = (gfan::ZFan*)u->Data();
+      res->rtyp = INT_CMD;
+      res->data = (void*) (long) getCodimension(zf);
+      return FALSE;
+    }
+  if ((u != NULL) && (u->Typ() == polytopeID))
+    {
+      gfan::ZCone* zc = (gfan::ZCone*)u->Data();
+      res->rtyp = INT_CMD;
+      res->data = (void*) (long) getCodimension(zc);
+      return FALSE;
+    }
+  WerrorS("getCodimension: unexpected parameters");
+  return TRUE;
+}
+
+BOOLEAN linealityDimension(leftv res, leftv args)
+{
+  leftv u=args;
+  if ((u != NULL) && (u->Typ() == coneID))
+  {
+    gfan::ZCone* zc = (gfan::ZCone*)u->Data();
+    res->rtyp = INT_CMD;
+    res->data = (void*) (long) zc->dimensionOfLinealitySpace();
+    return FALSE;
+  }
+  if ((u != NULL) && (u->Typ() == fanID))
+  {
+    gfan::ZFan* zf = (gfan::ZFan*)u->Data();
+    res->rtyp = INT_CMD;
+    res->data = (void*) (long) getLinealityDimension(zf);
+    return FALSE;
+  }
+  WerrorS("linealityDimension: unexpected parameters");
+  return TRUE;
+}
+
+BOOLEAN getMultiplicity(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && (u->Typ() == coneID))
+  {
+    gfan::ZCone* zc = (gfan::ZCone*)u->Data();
+    number i = integerToNumber(zc->getMultiplicity());
+    res->rtyp = BIGINT_CMD;
+    res->data = (void*) i;
+    return FALSE;
+  }
+  WerrorS("getMultiplicity: unexpected parameters");
+  return TRUE;
+}
+
+BOOLEAN isOrigin(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && (u->Typ() == coneID))
+  {
+    gfan::ZCone* zc = (gfan::ZCone*)u->Data();
+    int i = zc->isOrigin();
+    res->rtyp = INT_CMD;
+    res->data = (void*) (long) i;
+    return FALSE;
+  }
+  WerrorS("isOrigin: unexpected parameters");
+  return TRUE;
+}
+
+BOOLEAN isFullSpace(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && (u->Typ() == coneID))
+  {
+    gfan::ZCone* zc = (gfan::ZCone*)u->Data();
+    int i = zc->isFullSpace();
+    res->rtyp = INT_CMD;
+    res->data = (void*) (long) i;
+    return FALSE;
+  }
+  WerrorS("isFullSpace: unexpected parameters");
+  return TRUE;
+}
+
+BOOLEAN isSimplicial(leftv res, leftv args)
+{
+  leftv u=args;
+  if ((u != NULL) && (u->Typ() == coneID))
+  {
+    gfan::ZCone* zc = (gfan::ZCone*) u->Data();
+    int b = zc->isSimplicial();
+    res->rtyp = INT_CMD;
+    res->data = (void*) (long) b;
+    return FALSE;
+  }
+  if ((u != NULL) && (u->Typ() == fanID))
+  {
+    gfan::ZFan* zf = (gfan::ZFan*) u->Data();
+    bool b = isSimplicial(zf);
+    res->rtyp = INT_CMD;
+    res->data = (void*) (long) b;
+    return FALSE;
+  }
+  WerrorS("isSimplicial: unexpected parameters");
+  return TRUE;
+}
+
+BOOLEAN containsPositiveVector(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && (u->Typ() == coneID))
+  {
+    gfan::ZCone* zc = (gfan::ZCone*)u->Data();
+    int i = zc->containsPositiveVector();
+    res->rtyp = INT_CMD;
+    res->data = (void*) (long) i;
+    return FALSE;
+  }
+  WerrorS("containsPositiveVector: unexpected parameters");
+  return TRUE;
+}
+
+BOOLEAN linealitySpace(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && (u->Typ() == coneID))
+  {
+    gfan::ZCone* zc = (gfan::ZCone*)u->Data();
+    gfan::ZCone* zd = new gfan::ZCone(zc->linealitySpace());
+    res->rtyp = coneID;
+    res->data = (void*) zd;
+    return FALSE;
+  }
+  WerrorS("linealitySpace: unexpected parameters");
+  return TRUE;
+}
+
+BOOLEAN dualCone(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && (u->Typ() == coneID))
+  {
+    gfan::ZCone* zc = (gfan::ZCone*)u->Data();
+    gfan::ZCone* zd = new gfan::ZCone(zc->dualCone());
+    res->rtyp = coneID;
+    res->data = (void*) zd;
+    return FALSE;
+  }
+  WerrorS("dual: unexpected parameters");
+  return TRUE;
+}
+
+BOOLEAN negatedCone(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && (u->Typ() == coneID))
+  {
+    gfan::ZCone* zc = (gfan::ZCone*)u->Data();
+    gfan::ZCone* zd = new gfan::ZCone(zc->negated());
+    res->rtyp = coneID;
+    res->data = (void*) zd;
+    return FALSE;
+  }
+  WerrorS("negatedCone: unexpected parameters");
+  return TRUE;
+}
+
+BOOLEAN semigroupGenerator(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && (u->Typ() == coneID))
+  {
+    gfan::ZCone* zc = (gfan::ZCone*)u->Data();
+    int d = zc->dimension();
+    int dLS = zc->dimensionOfLinealitySpace();
+    if (d == dLS + 1)
+    {
+      gfan::ZVector zv = zc->semiGroupGeneratorOfRay();
+      res->rtyp = BIGINTMAT_CMD;
+      res->data = (void*) zVectorToBigintmat(zv);
+      return FALSE;
+    }
+    Werror("expected dim of cone one larger than dim of lin space\n"
+            "but got dimensions %d and %d", d, dLS);
+  }
+  WerrorS("semigroupGenerator: unexpected parameters");
+  return TRUE;
+}
+
+BOOLEAN relativeInteriorPoint(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && (u->Typ() == coneID))
+  {
+    gfan::ZCone* zc = (gfan::ZCone*)u->Data();
+    gfan::ZVector zv = zc->getRelativeInteriorPoint();
+    res->rtyp = BIGINTMAT_CMD;
+    res->data = (void*) zVectorToBigintmat(zv);
+    return FALSE;
+  }
+  WerrorS("relativeInteriorPoint: unexpected parameters");
+  return TRUE;
+}
+
+BOOLEAN uniquePoint(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && (u->Typ() == coneID))
+  {
+    gfan::ZCone* zc = (gfan::ZCone*)u->Data();
+    gfan::ZVector zv = zc->getUniquePoint();
+    res->rtyp = BIGINTMAT_CMD;
+    res->data = (void*) zVectorToBigintmat(zv);
+    return FALSE;
+  }
+  WerrorS("uniquePoint: unexpected parameters");
+  return TRUE;
+}
+
+gfan::ZVector randomPoint(const gfan::ZCone* zc)
+{
+  gfan::ZMatrix rays = zc->extremeRays();
+  gfan::ZVector rp = gfan::ZVector(zc->ambientDimension());
+  for (int i=0; i<rays.getHeight(); i++)
+  {
+    int n = siRand();
+    rp = rp + n * rays[i];
+  }
+  return rp;
+}
+
+BOOLEAN randomPoint(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && (u->Typ() == coneID))
+  {
+    gfan::ZCone* zc = (gfan::ZCone*)u->Data();
+    gfan::ZVector zv = randomPoint(zc);
+    res->rtyp = BIGINTMAT_CMD;
+    res->data = (void*) zVectorToBigintmat(zv);
+    return FALSE;
+  }
+  WerrorS("randomPoint: unexpected parameters");
+  return TRUE;
+}
+
+BOOLEAN setMultiplicity(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && (u->Typ() == coneID))
+  {
+    gfan::ZCone* zc = (gfan::ZCone*)u->Data();
+    leftv v = u->next;
+    if ((v != NULL) && (v->Typ() == INT_CMD))
+    {
+      int val = (int)(long)v->Data();
+      zc->setMultiplicity(gfan::Integer(val));
+      res->rtyp = NONE;
+      res->data = NULL;
+      return FALSE;
+    }
+  }
+  WerrorS("setMultiplicity: unexpected parameters");
+  return TRUE;
+}
+
+BOOLEAN setLinearForms(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && (u->Typ() == coneID))
+  {
+    gfan::ZCone* zc = (gfan::ZCone*)u->Data();
+    leftv v = u->next;
+    if ((v != NULL) && ((v->Typ() == BIGINTMAT_CMD) || (v->Typ() == INTVEC_CMD)))
+    {
+      bigintmat* mat=NULL;
+      if (v->Typ() == INTVEC_CMD)
+      {
+        intvec* mat0 = (intvec*) v->Data();
+        mat = iv2bim(mat0,coeffs_BIGINT)->transpose();
+      }
+      else
+        mat = (bigintmat*) v->Data();
+      gfan::ZMatrix* zm = bigintmatToZMatrix(mat);
+      zc->setLinearForms(*zm);
+      res->rtyp = NONE;
+      res->data = NULL;
+
+      delete zm;
+      if (v->Typ() == INTVEC_CMD)
+        delete mat;
+     return FALSE;
+    }
+  }
+  WerrorS("setLinearForms: unexpected parameters");
+  return TRUE;
+}
+
+gfan::ZMatrix liftUp(const gfan::ZMatrix &zm)
+{
+  int r=zm.getHeight();
+  int c=zm.getWidth();
+  gfan::ZMatrix zn(r+1,c+1);
+  zn[1][1]=1;
+  for (int i=0; i<r; i++)
+    for (int j=0; j<c; j++)
+      zn[i+1][j+1]=zm[i][j];
+  return zn;
+}
+
+gfan::ZCone liftUp(const gfan::ZCone &zc)
+{
+  gfan::ZMatrix ineq=zc.getInequalities();
+  gfan::ZMatrix eq=zc.getEquations();
+  gfan::ZCone zd(liftUp(ineq),liftUp(eq));
+  return zd;
+}
+
+BOOLEAN coneToPolytope(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && (u->Typ() == coneID))
+  {
+    gfan::ZCone* zc = (gfan::ZCone*) u->Data();
+    gfan::ZMatrix ineq=zc->getInequalities();
+    gfan::ZMatrix eq=zc->getEquations();
+    gfan::ZCone* zd = new gfan::ZCone(liftUp(ineq),liftUp(eq));
+    res->rtyp = polytopeID;
+    res->data = (void*) zd;
+    return FALSE;
+  }
+  WerrorS("makePolytope: unexpected parameters");
+  return TRUE;
+}
+
+BOOLEAN intersectCones(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && (u->Typ() == coneID))
+  {
+    leftv v = u->next;
+    if ((v != NULL) && (v->Typ() == coneID))
+    {
+      gfan::ZCone* zc1 = (gfan::ZCone*)u->Data();
+      gfan::ZCone* zc2 = (gfan::ZCone*)v->Data();
+      int d1 = zc1->ambientDimension();
+      int d2 = zc2->ambientDimension();
+      if (d1 != d2)
+      {
+        Werror("expected ambient dims of both cones to coincide\n"
+                "but got %d and %d", d1, d2);
+        return TRUE;
+      }
+      gfan::ZCone zc3 = gfan::intersection(*zc1, *zc2);
+      zc3.canonicalize();
+      res->rtyp = coneID;
+      res->data = (void *)new gfan::ZCone(zc3);
+      return FALSE;
+    }
+    if ((v != NULL) && (v->Typ() == polytopeID))
+    {
+      gfan::ZCone* zc11 = (gfan::ZCone*)u->Data();
+      gfan::ZCone zc1 = liftUp(*zc11);
+      gfan::ZCone* zc2 = (gfan::ZCone*)v->Data();
+      int d1 = zc1.ambientDimension();
+      int d2 = zc2->ambientDimension();
+      if (d1 != d2)
+      {
+        Werror("expected ambient dims of both cones to coincide\n"
+                "but got %d and %d", d1, d2);
+        return TRUE;
+      }
+      gfan::ZCone zc3 = gfan::intersection(zc1, *zc2);
+      zc3.canonicalize();
+      res->rtyp = polytopeID;
+      res->data = (void *)new gfan::ZCone(zc3);
+      return FALSE;
+    }
+  }
+  if ((u != NULL) && (u->Typ() == polytopeID))
+  {
+    leftv v = u->next;
+    if ((v != NULL) && (v->Typ() == coneID))
+    {
+      gfan::ZCone* zc1 = (gfan::ZCone*)u->Data();
+      gfan::ZCone* zc22 = (gfan::ZCone*)v->Data();
+      gfan::ZCone zc2 = liftUp(*zc22);
+      int d1 = zc1->ambientDimension();
+      int d2 = zc2.ambientDimension();
+      if (d1 != d2)
+      {
+        Werror("expected ambient dims of both cones to coincide\n"
+                "but got %d and %d", d1, d2);
+        return TRUE;
+      }
+      gfan::ZCone zc3 = gfan::intersection(*zc1, zc2);
+      zc3.canonicalize();
+      res->rtyp = polytopeID;
+      res->data = (void *)new gfan::ZCone(zc3);
+      return FALSE;
+    }
+    if ((v != NULL) && (v->Typ() == polytopeID))
+    {
+      gfan::ZCone* zc1 = (gfan::ZCone*)u->Data();
+      gfan::ZCone* zc2 = (gfan::ZCone*)v->Data();
+      int d1 = zc1->ambientDimension();
+      int d2 = zc2->ambientDimension();
+      if (d1 != d2)
+      {
+        Werror("expected ambient dims of both cones to coincide\n"
+                "but got %d and %d", d1, d2);
+        return TRUE;
+      }
+      gfan::ZCone zc3 = gfan::intersection(*zc1, *zc2);
+      zc3.canonicalize();
+      res->rtyp = polytopeID;
+      res->data = (void *)new gfan::ZCone(zc3);
+      return FALSE;
+    }
+  }
+  WerrorS("convexIntersection: unexpected parameters");
+  return TRUE;
+}
+
+BOOLEAN convexHull(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && (u->Typ() == coneID))
+  {
+    leftv v = u->next;
+    if ((v != NULL) && (v->Typ() == coneID))
+    {
+      gfan::ZCone* zc1 = (gfan::ZCone*)u->Data();
+      gfan::ZCone* zc2 = (gfan::ZCone*)v->Data();
+      int d1 = zc1->ambientDimension();
+      int d2 = zc2->ambientDimension();
+      if (d1 != d2)
+      {
+        Werror("expected ambient dims of both cones to coincide\n"
+                "but got %d and %d", d1, d2);
+        return TRUE;
+      }
+      gfan::ZMatrix zm1 = zc1->extremeRays();
+      gfan::ZMatrix zm2 = zc2->extremeRays();
+      gfan::ZMatrix zn1 = zc1->generatorsOfLinealitySpace();
+      gfan::ZMatrix zn2 = zc2->generatorsOfLinealitySpace();
+      gfan::ZMatrix zm = combineOnTop(zm1,zm2);
+      gfan::ZMatrix zn = combineOnTop(zn1,zn2);
+      gfan::ZCone* zc = new gfan::ZCone();
+      *zc = gfan::ZCone::givenByRays(zm, zn);
+      res->rtyp = coneID;
+      res->data = (void*) zc;
+      return FALSE;
+    }
+    if ((v != NULL) && (v->Typ() == polytopeID))
+    {
+      gfan::ZCone* zc11 = (gfan::ZCone*)u->Data();
+      gfan::ZCone zc1 = liftUp(*zc11);
+      gfan::ZCone* zc2 = (gfan::ZCone*)v->Data();
+      int d1 = zc1.ambientDimension()-1;
+      int d2 = zc2->ambientDimension()-1;
+      if (d1 != d2)
+      {
+        Werror("expected ambient dims of both cones to coincide\n"
+                "but got %d and %d", d1, d2);
+        return TRUE;
+      }
+      gfan::ZMatrix zm1 = zc1.extremeRays();
+      gfan::ZMatrix zm2 = zc2->extremeRays();
+      gfan::ZMatrix zn = zc1.generatorsOfLinealitySpace();
+      gfan::ZMatrix zm = combineOnTop(zm1,zm2);
+      gfan::ZCone* zc = new gfan::ZCone();
+      *zc = gfan::ZCone::givenByRays(zm, zn);
+      res->rtyp = polytopeID;
+      res->data = (void*) zc;
+      return FALSE;
+    }
+  }
+  if ((u != NULL) && (u->Typ() == polytopeID))
+  {
+    leftv v = u->next;
+    if ((v != NULL) && (v->Typ() == coneID))
+    {
+      gfan::ZCone* zc1 = (gfan::ZCone*)u->Data();
+      gfan::ZCone* zc22 = (gfan::ZCone*)v->Data();
+      gfan::ZCone zc2 = liftUp(*zc22);
+      int d1 = zc1->ambientDimension()-1;
+      int d2 = zc2.ambientDimension()-1;
+      if (d1 != d2)
+      {
+        Werror("expected ambient dims of both cones to coincide\n"
+                "but got %d and %d", d1, d2);
+        return TRUE;
+      }
+      gfan::ZMatrix zm1 = zc1->extremeRays();
+      gfan::ZMatrix zm2 = zc2.extremeRays();
+      gfan::ZMatrix zn = zc2.generatorsOfLinealitySpace();
+      gfan::ZMatrix zm = combineOnTop(zm1,zm2);
+      gfan::ZCone* zc = new gfan::ZCone();
+      *zc = gfan::ZCone::givenByRays(zm,gfan::ZMatrix(0, zm.getWidth()));
+      res->rtyp = polytopeID;
+      res->data = (void*) zc;
+      return FALSE;
+    }
+    if ((v != NULL) && (v->Typ() == polytopeID))
+    {
+      gfan::ZCone* zc1 = (gfan::ZCone*)u->Data();
+      gfan::ZCone* zc2 = (gfan::ZCone*)v->Data();
+      int d1 = zc1->ambientDimension()-1;
+      int d2 = zc2->ambientDimension()-1;
+      if (d1 != d2)
+      {
+        Werror("expected ambient dims of both cones to coincide\n"
+                "but got %d and %d", d1, d2);
+        return TRUE;
+      }
+      gfan::ZMatrix zm1 = zc1->extremeRays();
+      gfan::ZMatrix zm2 = zc2->extremeRays();
+      gfan::ZMatrix zm = combineOnTop(zm1,zm2);
+      gfan::ZCone* zc = new gfan::ZCone();
+      *zc = gfan::ZCone::givenByRays(zm,gfan::ZMatrix(0, zm.getWidth()));
+      res->rtyp = polytopeID;
+      res->data = (void*) zc;
+      return FALSE;
+    }
+  }
+  WerrorS("convexHull: unexpected parameters");
+  return TRUE;
+}
+
+BOOLEAN coneLink(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && (u->Typ() == coneID))
+  {
+    leftv v = u->next;
+    if ((v != NULL) && ((v->Typ() == BIGINTMAT_CMD) || (v->Typ() == INTVEC_CMD)))
+    {
+      gfan::ZCone* zc = (gfan::ZCone*)u->Data();
+      bigintmat* iv = NULL;
+      if (v->Typ() == INTVEC_CMD)
+      {
+        intvec* iv0 = (intvec*) v->Data();
+        iv = iv2bim(iv0,coeffs_BIGINT)->transpose();
+      }
+      else
+        iv = (bigintmat*)v->Data();
+      gfan::ZVector* zv = bigintmatToZVector(iv);
+      int d1 = zc->ambientDimension();
+      int d2 = zv->size();
+      if (d1 != d2)
+      {
+        Werror("expected ambient dim of cone and size of vector\n"
+               " to be equal but got %d and %d", d1, d2);
+        return TRUE;
+      }
+      if(!zc->contains(*zv))
+      {
+        WerrorS("the provided intvec does not lie in the cone");
+        return TRUE;
+      }
+      gfan::ZCone* zd = new gfan::ZCone(zc->link(*zv));
+      res->rtyp = coneID;
+      res->data = (void *) zd;
+
+      delete zv;
+      if (v->Typ() == INTMAT_CMD)
+        delete iv;
+      return FALSE;
+    }
+  }
+  WerrorS("coneLink: unexpected parameters");
+  return TRUE;
+}
+
+BOOLEAN containsInSupport(leftv res, leftv args)
+{
+  leftv u=args;
+  if ((u != NULL) && (u->Typ() == coneID))
+  {
+    leftv v=u->next;
+    if ((v != NULL) && (v->Typ() == coneID))
+    {
+      gfan::ZCone* zc = (gfan::ZCone*)u->Data();
+      gfan::ZCone* zd = (gfan::ZCone*)v->Data();
+      int d1 = zc->ambientDimension();
+      int d2 = zd->ambientDimension();
+      if (d1 != d2)
+      {
+        Werror("expected cones with same ambient dimensions\n but got"
+               " dimensions %d and %d", d1, d2);
+        return TRUE;
+      }
+      bool b = (zc->contains(*zd) ? 1 : 0);
+      res->rtyp = INT_CMD;
+      res->data = (void*) (long) b;
+      return FALSE;
+    }
+    if ((v != NULL) && ((v->Typ() == BIGINTMAT_CMD) || (v->Typ() == INTVEC_CMD)))
+    {
+      gfan::ZCone* zc = (gfan::ZCone*)u->Data();
+      bigintmat* iv = NULL;
+      if (v->Typ() == INTVEC_CMD)
+      {
+        intvec* iv0 = (intvec*) v->Data();
+        iv = iv2bim(iv0,coeffs_BIGINT)->transpose();
+      }
+      else
+        iv = (bigintmat*)v->Data();
+
+      gfan::ZVector* zv = bigintmatToZVector(iv);
+      int d1 = zc->ambientDimension();
+      int d2 = zv->size();
+      if (d1 != d2)
+      {
+        Werror("expected cones with same ambient dimensions\n but got"
+               " dimensions %d and %d", d1, d2);
+        return TRUE;
+      }
+      int b = zc->contains(*zv);
+      res->rtyp = INT_CMD;
+      res->data = (void*) (long) b;
+
+      delete zv;
+      if (v->Typ() == INTMAT_CMD)
+        delete iv;
+      return FALSE;
+    }
+  }
+  WerrorS("containsInSupport: unexpected parameters");
+  return TRUE;
+}
+
+BOOLEAN containsRelatively(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && (u->Typ() == coneID))
+  {
+    leftv v = u->next;
+    if ((v != NULL) && ((v->Typ() == BIGINTMAT_CMD) || (v->Typ() == INTVEC_CMD)))
+    {
+      gfan::ZCone* zc = (gfan::ZCone*)u->Data();
+      bigintmat* iv = NULL;
+      if (v->Typ() == INTVEC_CMD)
+      {
+        intvec* iv0 = (intvec*) v->Data();
+        iv = iv2bim(iv0,coeffs_BIGINT)->transpose();
+      }
+      else
+        iv = (bigintmat*)v->Data();
+      gfan::ZVector* zv = bigintmatToZVector(iv);
+      int d1 = zc->ambientDimension();
+      int d2 = zv->size();
+      if (d1 == d2)
+      {
+        bool b = (zc->containsRelatively(*zv) ? 1 : 0);
+        res->rtyp = INT_CMD;
+        res->data = (void *) b;
+        delete zv;
+        if (v->Typ() == INTMAT_CMD)
+          delete iv;
+        return FALSE;
+      }
+      delete zv;
+      if (v->Typ() == INTMAT_CMD)
+        delete iv;
+      Werror("expected ambient dim of cone and size of vector\n"
+             "to be equal but got %d and %d", d1, d2);
+    }
+  }
+  WerrorS("containsRelatively: unexpected parameters");
+  return TRUE;
+}
+
+BOOLEAN hasFace(leftv res, leftv args)
+{
+  leftv u=args;
+  if ((u != NULL) && (u->Typ() == coneID))
+  {
+    leftv v=u->next;
+    if ((v != NULL) && (v->Typ() == coneID))
+    {
+      gfan::ZCone* zc = (gfan::ZCone*)u->Data();
+      gfan::ZCone* zd = (gfan::ZCone*)v->Data();
+      bool b = zc->hasFace(*zd);
+      res->rtyp = INT_CMD;
+      res->data = (void*) (long) b;
+      return FALSE;
+    }
+  }
+  if ((u != NULL) && (u->Typ() == polytopeID))
+  {
+    leftv v=u->next;
+    if ((v != NULL) && (v->Typ() == polytopeID))
+    {
+      gfan::ZCone* zc = (gfan::ZCone*)u->Data();
+      gfan::ZCone* zd = (gfan::ZCone*)v->Data();
+      bool b = zc->hasFace(*zd);
+      res->rtyp = INT_CMD;
+      res->data = (void*) (long) b;
+      return FALSE;
+    }
+  }
+  WerrorS("containsAsFace: unexpected parameters");
+  return TRUE;
+}
+
+BOOLEAN canonicalizeCone(leftv res, leftv args)
+{
+  leftv u=args;
+  if ((u != NULL) && (u->Typ() == coneID))
+  {
+    gfan::ZCone* zc = (gfan::ZCone*)u->Data();
+    gfan::ZCone* zd = new gfan::ZCone(*zc);
+    zd->canonicalize();
+    res->rtyp = coneID;
+    res->data = (void*) zd;
+    return FALSE;
+  }
+  WerrorS("canonicalizeCone: unexpected parameters");
+  return TRUE;
+}
+
+BOOLEAN containsCone(leftv res, leftv args)
+{
+  leftv u=args;
+  if ((u != NULL) && (u->Typ() == LIST_CMD))
+  {
+    leftv v=u->next;
+    if ((v != NULL) && (v->Typ() == coneID))
+    {
+      lists l = (lists) u->Data();
+      gfan::ZCone* zc = (gfan::ZCone*) v->Data();
+      zc->canonicalize();
+      int b = 0;
+      for (int i=0; i<=lSize(l); i++)
+      {
+        if (l->m[i].Typ() != coneID)
+        {
+          WerrorS("containsCone: entries of wrong type in list");
+          return TRUE;
+        }
+        gfan::ZCone* ll = (gfan::ZCone*) l->m[i].Data();
+        ll->canonicalize();
+        if (!((*ll) != (*zc)))
+        {
+          b = 1;
+          break;
+        }
+      }
+      res->rtyp = INT_CMD;
+      res->data = (char*) (long) b;
+      return FALSE;
+    }
+  }
+  WerrorS("containsCone: unexpected parameters");
+  return TRUE;
+}
+
+gfan::ZVector intStar2ZVector(const int d, const int* i)
+{
+  gfan::ZVector zv(d);
+  for(int j=0; j<d; j++)
+    zv[j]=i[j+1];
+  return zv;
+}
+
+BOOLEAN maximalGroebnerCone(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && (u->Typ() == IDEAL_CMD))
+  {
+    leftv v = u->next;
+    if (v == NULL)
+    {
+      int n = currRing->N;
+      ideal I = (ideal) u->Data();
+      poly g = NULL;
+      int* leadexpv = (int*) omAlloc((n+1)*sizeof(int));
+      int* tailexpv = (int*) omAlloc((n+1)*sizeof(int));
+      gfan::ZVector leadexpw = gfan::ZVector(n);
+      gfan::ZVector tailexpw = gfan::ZVector(n);
+      gfan::ZMatrix inequalities = gfan::ZMatrix(0,n);
+      for (int i=0; i<IDELEMS(I); i++)
+      {
+        g = (poly) I->m[i]; pGetExpV(g,leadexpv);
+        leadexpw = intStar2ZVector(n, leadexpv);
+        pIter(g);
+        while (g != NULL)
+        {
+          pGetExpV(g,tailexpv);
+          tailexpw = intStar2ZVector(n, tailexpv);
+          inequalities.appendRow(leadexpw-tailexpw);
+          pIter(g);
+        }
+      }
+      gfan::ZCone* gCone = new gfan::ZCone(inequalities,gfan::ZMatrix(0, inequalities.getWidth()));
+      omFreeSize(leadexpv,(n+1)*sizeof(int));
+      omFreeSize(tailexpv,(n+1)*sizeof(int));
+
+      res->rtyp = coneID;
+      res->data = (void*) gCone;
+      return FALSE;
+    }
+  }
+  WerrorS("maximalGroebnerCone: unexpected parameters");
+  return TRUE;
+}
+
+
+lists listOfFacets(const gfan::ZCone &zc)
+{
+  gfan::ZMatrix inequalities = zc.getFacets();
+  gfan::ZMatrix equations = zc.getImpliedEquations();
+  lists L = (lists)omAllocBin(slists_bin);
+  int r = inequalities.getHeight();
+  int c = inequalities.getWidth();
+  L->Init(r);
+
+  /* next we iterate over each of the r facets, build the respective cone and add it to the list */
+  /* this is the i=0 case */
+  gfan::ZMatrix newInequalities = inequalities.submatrix(1,0,r,c);
+  gfan::ZMatrix newEquations = equations;
+  newEquations.appendRow(inequalities[0]);
+  L->m[0].rtyp = coneID; L->m[0].data=(void*) new gfan::ZCone(newInequalities,newEquations);
+
+  /* these are the cases i=1,...,r-2 */
+  for (int i=1; i<r-1; i++)
+  {
+    newInequalities = inequalities.submatrix(0,0,i-1,c);
+    newInequalities.append(inequalities.submatrix(i+1,0,r,c));
+    newEquations = equations;
+    newEquations.appendRow(inequalities[i]);
+    L->m[i].rtyp = coneID; L->m[i].data=(void*) new gfan::ZCone(newInequalities,newEquations);
+  }
+
+  /* this is the i=r-1 case */
+  newInequalities = inequalities.submatrix(0,0,r-1,c);
+  newEquations = equations;
+  newEquations.appendRow(inequalities[r]);
+  L->m[r-1].rtyp = coneID; L->m[r-1].data=(void*) new gfan::ZCone(newInequalities,newEquations);
+
+  return L;
+}
+
+
+BOOLEAN listOfFacets(leftv res, leftv args)
+{
+  leftv u=args;
+  if ((u != NULL) && (u->Typ() == coneID))
+  {
+    gfan::ZCone* zc = (gfan::ZCone*) u->Data();
+    lists L = listOfFacets(*zc);
+    res->rtyp = LIST_CMD;
+    res->data = (void*) L;
+    return FALSE;
+  }
+  WerrorS("listOfFacets: unexpected parameters");
+  return TRUE;
+}
+
+
+poly initial(poly p)
+{
+  poly g = p;
+  poly h = p_Head(g,currRing);
+  poly f = h;
+  long d = p_Deg(g,currRing);
+  pIter(g);
+  while ((g != NULL) && (p_Deg(g,currRing) == d))
+  {
+    pNext(h) = p_Head(g,currRing);
+    pIter(h);
+    pIter(g);
+  }
+  return(f);
+}
+
+
+BOOLEAN initial(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && (u->Typ() == POLY_CMD))
+  {
+    leftv v = u->next;
+    if (v == NULL)
+    {
+      poly p = (poly) u->Data();
+      res->rtyp = POLY_CMD;
+      res->data = (void*) initial(p);
+      return FALSE;
+    }
+  }
+  if ((u != NULL) && (u->Typ() == IDEAL_CMD))
+  {
+    leftv v = u->next;
+    if (v == NULL)
+    {
+      ideal I = (ideal) u->Data();
+      ideal inI = idInit(IDELEMS(I));
+      poly g;
+      for (int i=0; i<IDELEMS(I); i++)
+      {
+        g = (poly) I->m[i];
+        inI->m[i]=initial(g);
+      }
+      res->rtyp = IDEAL_CMD;
+      res->data = (void*) inI;
+      return FALSE;
+    }
+  }
+  WerrorS("initial: unexpected parameters");
+  return TRUE;
+}
+
+
+BOOLEAN homogeneitySpace(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && (u->Typ() == IDEAL_CMD))
+  {
+    leftv v = u->next;
+    if (v == NULL)
+    {
+      int n = currRing->N;
+      ideal I = (ideal) u->Data();
+      poly g;
+      int* leadexpv = (int*) omAlloc((n+1)*sizeof(int));
+      int* tailexpv = (int*) omAlloc((n+1)*sizeof(int));
+      gfan::ZVector leadexpw = gfan::ZVector(n);
+      gfan::ZVector tailexpw = gfan::ZVector(n);
+      gfan::ZMatrix equations = gfan::ZMatrix(0,n);
+      for (int i=0; i<IDELEMS(I); i++)
+      {
+        g = (poly) I->m[i]; pGetExpV(g,leadexpv);
+        leadexpw = intStar2ZVector(n, leadexpv);
+        pIter(g);
+        while (g != NULL)
+        {
+          pGetExpV(g,tailexpv);
+          tailexpw = intStar2ZVector(n, tailexpv);
+          equations.appendRow(leadexpw-tailexpw);
+          pIter(g);
+        }
+      }
+      gfan::ZCone* gCone = new gfan::ZCone(gfan::ZMatrix(0, equations.getWidth()),equations);
+      omFreeSize(leadexpv,(n+1)*sizeof(int));
+      omFreeSize(tailexpv,(n+1)*sizeof(int));
+
+      res->rtyp = coneID;
+      res->data = (void*) gCone;
+      return FALSE;
+    }
+  }
+  WerrorS("homogeneitySpace: unexpected parameters");
+  return TRUE;
+}
+
+
+BOOLEAN groebnerCone(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && (u->Typ() == IDEAL_CMD))
+  {
+    leftv v = u->next;
+    if (v == NULL)
+    {
+      int n = currRing->N;
+      ideal I = (ideal) u->Data();
+      poly g = NULL;
+      int* leadexpv = (int*) omAlloc((n+1)*sizeof(int));
+      int* tailexpv = (int*) omAlloc((n+1)*sizeof(int));
+      gfan::ZVector leadexpw = gfan::ZVector(n);
+      gfan::ZVector tailexpw = gfan::ZVector(n);
+      gfan::ZMatrix inequalities = gfan::ZMatrix(0,n);
+      gfan::ZMatrix equations = gfan::ZMatrix(0,n);
+      long d;
+      for (int i=0; i<IDELEMS(I); i++)
+      {
+        g = (poly) I->m[i]; pGetExpV(g,leadexpv);
+        leadexpw = intStar2ZVector(n, leadexpv);
+        pIter(g);
+        d = p_Deg(g,currRing);
+        while ((g != NULL) && (p_Deg(g,currRing) == d))
+        {
+          pGetExpV(g,tailexpv);
+          tailexpw = intStar2ZVector(n, tailexpv);
+          equations.appendRow(leadexpw-tailexpw);
+          pIter(g);
+        }
+
+        if (g != NULL)
+        {
+          while (g != NULL)
+          {
+            pGetExpV(g,tailexpv);
+            tailexpw = intStar2ZVector(n, tailexpv);
+            inequalities.appendRow(leadexpw-tailexpw);
+            pIter(g);
+          }
+        }
+      }
+      gfan::ZCone* gCone = new gfan::ZCone(inequalities,equations);
+      omFreeSize(leadexpv,(n+1)*sizeof(int));
+      omFreeSize(tailexpv,(n+1)*sizeof(int));
+
+      res->rtyp = coneID;
+      res->data = (void*) gCone;
+      return FALSE;
+    }
+  }
+  WerrorS("groebnerCone: unexpected parameters");
+  return TRUE;
+}
+
+/***
+ * Given a cone and a point in its boundary,
+ * returns the inner normal vector of a facet
+ * containing the point.
+ * In case no facet contains the point,
+ * then 0 is returned.
+ **/
+gfan::ZVector* facetContaining(gfan::ZCone* zc, gfan::ZVector* zv)
+{
+  gfan::ZMatrix facets = zc->getFacets();
+  for (int i=0; i<facets.getHeight(); i++)
+  {
+    gfan::ZVector facet = facets[i];
+    if (dot(facet,*zv) == (long) 0)
+      return new gfan::ZVector(facet);
+  }
+  return new gfan::ZVector(zc->ambientDimension());
+}
+
+
+BOOLEAN facetContaining(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && (u->Typ() == coneID))
+  {
+    leftv v = u->next;
+    if ((v != NULL) && ((v->Typ() == BIGINTMAT_CMD) || (v->Typ() == INTVEC_CMD)))
+    {
+      gfan::ZCone* zc = (gfan::ZCone*) u->Data();
+
+      bigintmat* point1;
+      if (v->Typ() == INTVEC_CMD)
+      {
+        intvec* point0 = (intvec*) v->Data();
+        point1 = iv2bim(point0,coeffs_BIGINT)->transpose();
+      }
+      else
+        point1 = (bigintmat*) v->Data();
+
+      gfan::ZVector* point = bigintmatToZVector(*point1);
+      gfan::ZVector* facet = facetContaining(zc, point);
+
+      res->rtyp = BIGINTMAT_CMD;
+      res->data = (void*) zVectorToBigintmat(*facet);
+
+      delete facet;
+      delete point;
+      if (v->Typ() == INTVEC_CMD)
+        delete point1;
+      return FALSE;
+    }
+  }
+  WerrorS("facetContaining: unexpected parameters");
+  return TRUE;
+}
+
+
+void bbcone_setup(SModulFunctions* p)
+{
+  blackbox *b=(blackbox*)omAlloc0(sizeof(blackbox));
+  // all undefined entries will be set to default in setBlackboxStuff
+  // the default Print is quite usefull,
+  // all other are simply error messages
+  b->blackbox_destroy=bbcone_destroy;
+  b->blackbox_String=bbcone_String;
+  // b->blackbox_Print=blackbox_default_Print;
+  b->blackbox_Init=bbcone_Init;
+  b->blackbox_Copy=bbcone_Copy;
+  b->blackbox_Assign=bbcone_Assign;
+  b->blackbox_Op2=bbcone_Op2;
+  p->iiAddCproc("","coneViaInequalities",FALSE,coneViaNormals);
+  p->iiAddCproc("","coneViaPoints",FALSE,coneViaRays);
+
+  // iiAddCproc("","makePolytope",FALSE,coneToPolytope);
+  p->iiAddCproc("","ambientDimension",FALSE,ambientDimension);
+  p->iiAddCproc("","canonicalizeCone",FALSE,canonicalizeCone);
+  p->iiAddCproc("","codimension",FALSE,codimension);
+  p->iiAddCproc("","coneLink",FALSE,coneLink);
+  p->iiAddCproc("","containsAsFace",FALSE,hasFace);
+  p->iiAddCproc("","containsInSupport",FALSE,containsInSupport);
+  p->iiAddCproc("","containsPositiveVector",FALSE,containsPositiveVector);
+  p->iiAddCproc("","containsRelatively",FALSE,containsRelatively);
+  p->iiAddCproc("","convexHull",FALSE,convexHull);
+  p->iiAddCproc("","convexIntersection",FALSE,intersectCones);
+  p->iiAddCproc("","dimension",FALSE,dimension);
+  p->iiAddCproc("","dualCone",FALSE,dualCone);
+  p->iiAddCproc("","equations",FALSE,equations);
+  p->iiAddCproc("","facets",FALSE,facets);
+  p->iiAddCproc("","generatorsOfLinealitySpace",FALSE,generatorsOfLinealitySpace);
+  p->iiAddCproc("","generatorsOfSpan",FALSE,generatorsOfSpan);
+  p->iiAddCproc("","getLinearForms",FALSE,getLinearForms);
+  p->iiAddCproc("","getMultiplicity",FALSE,getMultiplicity);
+  p->iiAddCproc("","inequalities",FALSE,inequalities);
+  p->iiAddCproc("","isFullSpace",FALSE,isFullSpace);
+  p->iiAddCproc("","isOrigin",FALSE,isOrigin);
+  p->iiAddCproc("","isSimplicial",FALSE,isSimplicial);
+  p->iiAddCproc("","linealityDimension",FALSE,linealityDimension);
+  p->iiAddCproc("","linealitySpace",FALSE,linealitySpace);
+  p->iiAddCproc("","negatedCone",FALSE,negatedCone);
+  p->iiAddCproc("","quotientLatticeBasis",FALSE,quotientLatticeBasis);
+  p->iiAddCproc("","randomPoint",FALSE,randomPoint);
+  p->iiAddCproc("","rays",FALSE,rays);
+  p->iiAddCproc("","relativeInteriorPoint",FALSE,relativeInteriorPoint);
+  p->iiAddCproc("","semigroupGenerator",FALSE,semigroupGenerator);
+  p->iiAddCproc("","setLinearForms",FALSE,setLinearForms);
+  p->iiAddCproc("","setMultiplicity",FALSE,setMultiplicity);
+  p->iiAddCproc("","span",FALSE,impliedEquations);
+  p->iiAddCproc("","uniquePoint",FALSE,uniquePoint);
+  p->iiAddCproc("","listContainsCone",FALSE,containsCone);
+  p->iiAddCproc("","listOfFacets",FALSE,listOfFacets);
+  p->iiAddCproc("","maximalGroebnerCone",FALSE,maximalGroebnerCone);
+  p->iiAddCproc("","groebnerCone",FALSE,groebnerCone);
+  p->iiAddCproc("","initial",FALSE,initial);
+  p->iiAddCproc("","homogeneitySpace",FALSE,homogeneitySpace);
+  p->iiAddCproc("","facetContaining",FALSE,facetContaining);
+  coneID=setBlackboxStuff(b,"cone");
+}
+
+#endif
diff --git a/Singular/dyn_modules/gfanlib/bbcone.h b/Singular/dyn_modules/gfanlib/bbcone.h
new file mode 100644
index 0000000..20c7ea0
--- /dev/null
+++ b/Singular/dyn_modules/gfanlib/bbcone.h
@@ -0,0 +1,42 @@
+#ifndef BBCONE_H
+#define BBCONE_H
+
+#include <kernel/mod2.h>
+
+#if HAVE_GFANLIB
+
+#include <misc/intvec.h>
+#include <coeffs/bigintmat.h>
+#include <Singular/ipid.h>
+
+#include <gfanlib/gfanlib.h>
+
+extern int coneID;
+
+void bbcone_setup(SModulFunctions* p);
+
+/***
+ * Conversion functions for data types
+ **/
+gfan::Integer* numberToInteger(const number &n);
+number integerToNumber(const gfan::Integer &I);
+bigintmat* zVectorToBigintmat(const gfan::ZVector &zv);
+bigintmat* zMatrixToBigintmat(const gfan::ZMatrix &zm);
+gfan::ZMatrix* bigintmatToZMatrix(const bigintmat &bim);
+gfan::ZVector* bigintmatToZVector(const bigintmat &bim);
+
+gfan::ZVector intStar2ZVector(const int d, const int* i);
+char* toString(gfan::ZMatrix const &m);
+std::string toString(const gfan::ZCone* const c);
+
+/***
+ * Other functions
+ **/
+int getDimension(gfan::ZCone* zc);
+int getCodimension(gfan::ZCone* zc);
+int getLinealityDimension(gfan::ZCone* zc);
+gfan::ZVector randomPoint(const gfan::ZCone* zc);
+gfan::ZCone liftUp(const gfan::ZCone &zc);
+
+#endif
+#endif
diff --git a/Singular/dyn_modules/gfanlib/bbfan.cc b/Singular/dyn_modules/gfanlib/bbfan.cc
new file mode 100644
index 0000000..540e7cc
--- /dev/null
+++ b/Singular/dyn_modules/gfanlib/bbfan.cc
@@ -0,0 +1,1067 @@
+#include <kernel/mod2.h>
+
+#if HAVE_GFANLIB
+
+#include <misc/intvec.h>
+#include <coeffs/coeffs.h>
+#include <coeffs/bigintmat.h>
+
+#include <Singular/ipid.h>
+#include <Singular/ipshell.h>
+#include <Singular/blackbox.h>
+
+#include "bbfan.h"
+#include "bbcone.h"
+#include "gfan.h"
+#include <sstream>
+
+// #include <kernel/bigintmat.h>
+// #include <omalloc/omalloc.h>
+// #include <kernel/longrat.h>
+// #include <Singular/subexpr.h>
+// #include <Singular/lists.h>
+// #include <gfanlib/gfanlib.h>
+// #include <gfanlib/gfanlib_zfan.h>
+
+int fanID;
+
+void* bbfan_Init(blackbox* /*b*/)
+{
+  return (void*) new gfan::ZFan(0);
+}
+
+void bbfan_destroy(blackbox* /*b*/, void *d)
+{
+  if (d!=NULL)
+  {
+    gfan::ZFan* zf = (gfan::ZFan*) d;
+    delete zf;
+  }
+}
+
+char* bbfan_String(blackbox* /*b*/, void *d)
+{
+  if (d==NULL) return omStrDup("invalid object");
+  else
+  {
+    gfan::ZFan* zf = (gfan::ZFan*)d;
+    std::string s = zf->toStringJustRaysAndMaximalCones();
+    return omStrDup(s.c_str());
+  }
+}
+
+void* bbfan_Copy(blackbox* /*b*/, void *d)
+{
+  gfan::ZFan* zf = (gfan::ZFan*)d;
+  gfan::ZFan* newZf = new gfan::ZFan(*zf);
+  return newZf;
+}
+
+BOOLEAN bbfan_Assign(leftv l, leftv r)
+{
+  gfan::ZFan* newZf;
+  if (r==NULL)
+  {
+    if (l->Data()!=NULL)
+    {
+      gfan::ZFan* zd = (gfan::ZFan*) l->Data();
+      delete zd;
+    }
+    newZf = new gfan::ZFan(0);
+  }
+  else if (r->Typ()==l->Typ())
+  {
+    if (l->Data()!=NULL)
+    {
+      gfan::ZFan* zd = (gfan::ZFan*) l->Data();
+      delete zd;
+    }
+    gfan::ZFan* zf = (gfan::ZFan*) r->Data();
+    newZf = new gfan::ZFan(*zf);
+  }
+  else if (r->Typ()==INT_CMD)
+  {
+    int ambientDim = (int) (long) r->Data();
+    if (ambientDim < 0)
+    {
+      Werror("expected an int >= 0, but got %d", ambientDim);
+      return TRUE;
+    }
+    if (l->Data()!=NULL)
+    {
+      gfan::ZFan* zd = (gfan::ZFan*) l->Data();
+      delete zd;
+    }
+    newZf = new gfan::ZFan(ambientDim);
+  }
+  else
+  {
+    Werror("assign Type(%d) = Type(%d) not implemented",l->Typ(),r->Typ());
+    return TRUE;
+  }
+
+  if (l->rtyp==IDHDL)
+  {
+    IDDATA((idhdl)l->data) = (char*) newZf;
+  }
+  else
+  {
+    l->data = (void*) newZf;
+  }
+  return FALSE;
+}
+
+/* returns 1 iff all rows consist of entries 1..n,
+   where n is the number of columns of the provided
+   bigintmat; 0 otherwise */
+static gfan::IntMatrix permutationIntMatrix(const bigintmat* iv)
+{
+  int cc = iv->cols();
+  int rr = iv->rows();
+  bigintmat* ivCopy = new bigintmat(rr, cc, coeffs_BIGINT);
+  for (int r = 1; r <= rr; r++)
+    for (int c = 1; c <= cc; c++)
+    {
+      number temp1 = n_Init(1,coeffs_BIGINT);
+      number temp2 = n_Sub(IMATELEM(*iv, r, c),temp1,coeffs_BIGINT);
+      ivCopy->set(r,c,temp2);
+      n_Delete(&temp1,coeffs_BIGINT);
+      n_Delete(&temp2,coeffs_BIGINT);
+    }
+  gfan::ZMatrix* zm = bigintmatToZMatrix(ivCopy);
+  gfan::IntMatrix im = gfan::IntMatrix(gfan::ZToIntMatrix(*zm));
+  delete zm;
+  return im;
+}
+static BOOLEAN jjFANEMPTY_I(leftv res, leftv v)
+{
+  int ambientDim = (int)(long)v->Data();
+  if (ambientDim < 0)
+  {
+    Werror("expected non-negative ambient dim but got %d", ambientDim);
+    return TRUE;
+  }
+  res->rtyp = fanID;
+  res->data = (void*)(new gfan::ZFan(ambientDim));
+  return FALSE;
+}
+
+static BOOLEAN jjFANEMPTY_IM(leftv res, leftv v)
+{
+  bigintmat* permutations = (bigintmat*)v->Data();
+  int ambientDim = permutations->cols();
+  gfan::IntMatrix im = permutationIntMatrix(permutations);
+  if (!gfan::Permutation::arePermutations(im))
+  {
+    Werror("provided bigintmat contains invalid permutations of {1, ..., %d}", ambientDim);
+    return TRUE;
+  }
+  gfan::SymmetryGroup sg = gfan::SymmetryGroup(ambientDim);
+  sg.computeClosure(im);
+  res->rtyp = fanID;
+  res->data = (void*)(new gfan::ZFan(sg));
+  return FALSE;
+}
+
+BOOLEAN emptyFan(leftv res, leftv args)
+{
+  leftv u = args;
+  if (u == NULL)
+  {
+    res->rtyp = fanID;
+    res->data = (void*) new gfan::ZFan(0);
+    return FALSE;
+  }
+  if ((u != NULL) && (u->Typ() == INT_CMD))
+  {
+    if (u->next == NULL) return jjFANEMPTY_I(res, u);
+  }
+  if ((u != NULL) && (u->Typ() == BIGINTMAT_CMD))
+  {
+    if (u->next == NULL) return jjFANEMPTY_IM(res, u);
+  }
+  WerrorS("emptyFan: unexpected parameters");
+  return TRUE;
+}
+
+static BOOLEAN jjFANFULL_I(leftv res, leftv v)
+{
+  int ambientDim = (int)(long)v->Data();
+  if (ambientDim < 0)
+  {
+    Werror("expected non-negative ambient dim but got %d", ambientDim);
+    return TRUE;
+  }
+  gfan::ZFan* zf = new gfan::ZFan(gfan::ZFan::fullFan(ambientDim));
+  res->rtyp = fanID;
+  res->data = (void*) zf;
+  return FALSE;
+}
+static BOOLEAN jjFANFULL_IM(leftv res, leftv v)
+{
+  bigintmat* permutations = (bigintmat*)v->Data();
+  int ambientDim = permutations->cols();
+  gfan::IntMatrix im = permutationIntMatrix(permutations);
+  if (!gfan::Permutation::arePermutations(im))
+  {
+    Werror("provided bigintmat contains invalid permutations of {1, ..., %d}", ambientDim);
+    return TRUE;
+  }
+  gfan::SymmetryGroup sg = gfan::SymmetryGroup(ambientDim);
+  sg.computeClosure(im);
+  gfan::ZFan* zf = new gfan::ZFan(gfan::ZFan::fullFan(sg));
+  res->rtyp = fanID;
+  res->data = (void*) zf;
+  return FALSE;
+}
+
+BOOLEAN fullFan(leftv res, leftv args)
+{
+  leftv u = args;
+  if (u == NULL)
+  {
+    res->rtyp = fanID;
+    res->data = (void*) new gfan::ZFan(0);
+    return FALSE;
+  }
+  if ((u != NULL) && (u->Typ() == INT_CMD))
+    if (u->next == NULL) return jjFANFULL_I(res, u);
+  if ((u != NULL) && (u->Typ() == BIGINTMAT_CMD))
+    if (u->next == NULL) return jjFANFULL_IM(res, u);
+  WerrorS("fullFan: unexpected parameters");
+  return TRUE;
+}
+
+int getAmbientDimension(gfan::ZFan* zf)
+{
+  return zf->getAmbientDimension();
+}
+
+int getCodimension(gfan::ZFan* zf)
+{
+  return zf->getCodimension();
+}
+
+int getDimension(gfan::ZFan* zf)
+{
+  return zf->getDimension();
+}
+
+int getLinealityDimension(gfan::ZFan* zf)
+{
+  return zf->getLinealityDimension();
+}
+
+BOOLEAN numberOfConesOfDimension(leftv res, leftv args)
+{
+  leftv u=args;
+  if ((u != NULL) && (u->Typ() == fanID))
+  {
+    leftv v=u->next;
+    if ((v != NULL) && (v->Typ() == INT_CMD))
+    {
+      leftv w=v->next;
+      if ((w != NULL) && (w->Typ() == INT_CMD))
+      {
+        leftv x=w->next;
+        if ((x != NULL) && (x->Typ() == INT_CMD))
+        {
+          gfan::ZFan* zf = (gfan::ZFan*) u->Data();
+          int d = (int)(long)v->Data();
+          int o = (int)(long)w->Data();
+          int m = (int)(long)x->Data();
+          if ( (0<=d) && (d <= zf->getAmbientDimension())
+                      && ((o == 0) || (o == 1))
+                      && ((m == 0) || (m == 1)))
+          {
+            bool oo = (bool) o;
+            bool mm = (bool) m;
+            int ld = zf->getLinealityDimension();
+            if (d-ld>=0)
+            {
+              int n = zf->numberOfConesOfDimension(d-ld,oo,mm);
+              res->rtyp = INT_CMD;
+              res->data = (void*) (long) n;
+              return FALSE;
+            }
+            res->rtyp = INT_CMD;
+            res->data = (void*) (long) 0;
+            return FALSE;
+          }
+        }
+      }
+    }
+  }
+  WerrorS("numberOfConesOfDimension: unexpected parameters");
+  return TRUE;
+}
+
+BOOLEAN ncones(leftv res, leftv args)
+{
+  leftv u=args;
+  if ((u != NULL) && (u->Typ() == fanID))
+    {
+      gfan::ZFan* zf = (gfan::ZFan*)u->Data();
+      int d = zf->getAmbientDimension();
+      int n = 0;
+
+      for (int i=0; i<=d; i++)
+        n = n + zf->numberOfConesOfDimension(i,0,0);
+
+      res->rtyp = INT_CMD;
+      res->data = (void*) (long) n;
+      return FALSE;
+    }
+  else
+    {
+      WerrorS("check_compatibility: unexpected parameters");
+      return TRUE;
+    }
+}
+
+BOOLEAN nmaxcones(leftv res, leftv args)
+{
+  leftv u=args;
+  if ((u != NULL) && (u->Typ() == fanID))
+    {
+      gfan::ZFan* zf = (gfan::ZFan*)u->Data();
+
+      int n = 0;
+      for (int d=0; d<=zf->getAmbientDimension(); d++)
+        { n = n + zf->numberOfConesOfDimension(d,0,1); }
+
+      res->rtyp = INT_CMD;
+      res->data = (void*) (long) n;
+      return FALSE;
+    }
+  else
+    {
+      WerrorS("nmaxcones: unexpected parameters");
+      return TRUE;
+    }
+}
+
+bool isCompatible(gfan::ZFan* zf, gfan::ZCone* zc)
+{
+  bool b = (zf->getAmbientDimension() == zc->ambientDimension());
+  if(b)
+  {
+    for (int d=0; d<=zf->getAmbientDimension(); d++)
+    {
+      for (int i=0; i<zf->numberOfConesOfDimension(d,0,1); i++)
+      {
+        gfan::ZCone zd = zf->getCone(d,i,0,1);
+        gfan::ZCone zt = gfan::intersection(*zc,zd);
+        zt.canonicalize();
+        b = b && zd.hasFace(zt);
+      }
+    }
+  }
+  return b;
+}
+
+BOOLEAN isCompatible(leftv res, leftv args)
+{
+  leftv u=args;
+  if ((u != NULL) && (u->Typ() == fanID))
+  {
+    leftv v=u->next;
+    if ((v != NULL) && (v->Typ() == coneID))
+    {
+      gfan::ZFan* zf = (gfan::ZFan*)u->Data();
+      gfan::ZCone* zc = (gfan::ZCone*)v->Data();
+      int b = isCompatible(zf,zc);
+      res->rtyp = INT_CMD;
+      res->data = (void*) (long) b;
+      return FALSE;
+    }
+  }
+  WerrorS("isCompatible: unexpected parameters");
+  return TRUE;
+}
+
+BOOLEAN insertCone(leftv res, leftv args)
+{
+  leftv u=args;
+  if ((u != NULL) && (u->rtyp==IDHDL) && (u->e==NULL) && (u->Typ() == fanID))
+  {
+    leftv v=u->next;
+    if ((v != NULL) && (v->Typ() == coneID))
+    {
+      gfan::ZFan* zf = (gfan::ZFan*)u->Data();
+      gfan::ZCone* zc = (gfan::ZCone*)v->Data();
+      zc->canonicalize();
+
+      leftv w=v->next;
+      int n;
+      if ((w != NULL) && (w->Typ() == INT_CMD))
+        n = (int)(long) w;
+
+      if (n != 0)
+      {
+        if (!isCompatible(zf,zc))
+        {
+          WerrorS("insertCone: cone and fan not compatible");
+          return TRUE;
+        }
+      }
+
+      zf->insert(*zc);
+      res->rtyp = NONE;
+      res->data = NULL;
+      IDDATA((idhdl)u->data) = (char*) zf;
+      return FALSE;
+    }
+  }
+  WerrorS("insertCone: unexpected parameters");
+  return TRUE;
+}
+
+bool containsInCollection(gfan::ZFan* zf, gfan::ZCone* zc)
+{
+  gfan::ZVector zv=zc->getRelativeInteriorPoint();
+  for (int d=0; d<=zf->getAmbientDimension(); d++)
+  {
+    for (int i=0; i<zf->numberOfConesOfDimension(d,0,1); i++)
+    {
+      gfan::ZCone zd = zf->getCone(d,i,0,1);
+      zd.canonicalize();
+      if (zd.containsRelatively(zv))
+      {
+        gfan::ZCone temp = *zc;
+        temp.canonicalize();
+        return (!(zd != temp));
+      }
+    }
+  }
+  return 0;
+}
+
+BOOLEAN containsInCollection(leftv res, leftv args)
+{
+  leftv u=args;
+  if ((u != NULL) && (u->Typ() == fanID))
+  {
+    leftv v=u->next;
+    if ((v != NULL) && (v->Typ() == coneID))
+    {
+      gfan::ZFan* zf = (gfan::ZFan*)u->Data();
+      gfan::ZCone* zc = (gfan::ZCone*)v->Data();
+      if((zf->getAmbientDimension() == zc->ambientDimension()))
+      {
+        res->rtyp = INT_CMD;
+        res->data = (void*) (long) (int) containsInCollection(zf,zc);
+        return FALSE;
+      }
+      WerrorS("containsInCollection: mismatching ambient dimensions");
+      return TRUE;
+    }
+  }
+  // if ((u != NULL) && (u->Typ() == coneID))
+  // {
+  //   leftv v=u->next;
+  //   if ((v != NULL) && (v->Typ() == coneID))
+  //   {
+  //     gfan::ZCone* zc = (gfan::ZCone*)u->Data();
+  //     gfan::ZCone* zd = (gfan::ZCone*)v->Data();
+  //     res->rtyp = INT_CMD;
+  //     res->data = (void*) (int) hasFace(zc,zd);
+  //     return FALSE;
+  //   }
+  // }
+  WerrorS("containsInCollection: unexpected parameters");
+  return TRUE;
+}
+
+// BOOLEAN coneContaining(leftv res, leftv args)
+// {
+//   leftv u=args;
+//   if ((u != NULL) && (u->Typ() == fanID))
+//   {
+//     if ((v != NULL) && (v->Typ() == BIGINTMAT_CMD))
+//     {
+//       gfan::ZFan* zf = (gfan::ZFan*)u->Data();
+//       bigintmat* vec = (bigintmat*)v->Data();
+//     }
+//   }
+//   WerrorS("coneContaining: unexpected parameters");
+//   return TRUE;
+// }
+
+BOOLEAN removeCone(leftv res, leftv args)
+{
+  leftv u=args;
+  if ((u != NULL) && (u->Typ() == fanID))
+  {
+    leftv v=u->next;
+    if ((v != NULL) && (v->Typ() == coneID))
+    {
+      gfan::ZFan* zf = (gfan::ZFan*)u->Data();
+      gfan::ZCone* zc = (gfan::ZCone*)v->Data();
+      zc->canonicalize();
+
+      leftv w=v->next; int n = 1;
+      if ((w != NULL) && (w->Typ() == INT_CMD))
+        n = (int)(long) w;
+
+      if (n != 0)
+      {
+        if (!containsInCollection(zf,zc))
+        {
+          WerrorS("removeCone: cone not contained in fan");
+          return TRUE;
+        }
+      }
+
+      zf->remove(*zc);
+      res->rtyp = NONE;
+      res->data = NULL;
+      IDDATA((idhdl)u->data) = (char*) zf;
+      return FALSE;
+    }
+  }
+  WerrorS("removeCone: unexpected parameters");
+  return TRUE;
+}
+
+BOOLEAN getCone(leftv res, leftv args)
+{
+  leftv u=args;
+  if ((u != NULL) && (u->Typ() == fanID))
+  {
+    leftv v=u->next;
+    if ((v != NULL) && (v->Typ() == INT_CMD))
+    {
+      leftv w=v->next;
+      if ((w != NULL) && (w->Typ() == INT_CMD))
+      {
+        gfan::ZFan* zf = (gfan::ZFan*) u->Data();
+        int d = (int)(long)v->Data();
+        int i = (int)(long)w->Data();
+        int o = -1;
+        int m = -1;
+        leftv x=w->next;
+        if ((x != NULL) && (x->Typ() == INT_CMD))
+        {
+          o = (int)(long)x->Data();
+          leftv y=x->next;
+          if ((y != NULL) && (y->Typ() == INT_CMD))
+          {
+            m = (int)(long)y->Data();
+          }
+        }
+        if (o == -1) o = 0;
+        if (m == -1) m = 0;
+        if (((o == 0) || (o == 1)) && ((m == 0) || (m == 1)))
+        {
+          bool oo = (bool) o;
+          bool mm = (bool) m;
+          if (0<=d && d<=zf->getAmbientDimension())
+          {
+            if (0<i && i<=zf->numberOfConesOfDimension(d,oo,mm))
+            {
+              i=i-1;
+              int ld = zf->getLinealityDimension();
+              if (d-ld>=0)
+              {
+                gfan::ZCone zc = zf->getCone(d-ld,i,oo,mm);
+                res->rtyp = coneID;
+                res->data = (void*)new gfan::ZCone(zc);
+                return FALSE;
+              }
+              else
+              {
+                WerrorS("getCone: invalid dimension; no cones in this dimension");
+                return TRUE;
+              }
+            }
+            else
+            {
+              WerrorS("getCone: invalid index");
+              return TRUE;
+            }
+          }
+          else
+          {
+            WerrorS("getCone: invalid dimension");
+            return TRUE;
+          }
+        }
+        else
+        {
+          WerrorS("getCone: invalid specifier for orbit or maximal");
+          return TRUE;
+        }
+      }
+    }
+  }
+  WerrorS("getCone: unexpected parameters");
+  return TRUE;
+}
+
+BOOLEAN getCones(leftv res, leftv args)
+{
+  leftv u=args;
+  if ((u != NULL) && (u->Typ() == fanID))
+  {
+    leftv v=u->next;
+    if ((v != NULL) && (v->Typ() == INT_CMD))
+    {
+      gfan::ZFan* zf = (gfan::ZFan*) u->Data();
+      int d = (int)(long)v->Data();
+      int o = -1;
+      int m = -1;
+      leftv w=v->next;
+      if ((w != NULL) && (w->Typ() == INT_CMD))
+      {
+        o = (int)(long)w->Data();
+        leftv x=w->next;
+        if ((x != NULL) && (x->Typ() == INT_CMD))
+        {
+          m = (int)(long)x->Data();
+        }
+      }
+      if (o == -1) o = 0;
+      if (m == -1) m = 0;
+      if (((o == 0) || (o == 1)) && ((m == 0) || (m == 1)))
+      {
+        bool oo = (bool) o;
+        bool mm = (bool) m;
+        if (0<=d && d<=zf->getAmbientDimension())
+        {
+          int ld = zf->getLinealityDimension();
+          if (d-ld>=0)
+          {
+            lists L = (lists)omAllocBin(slists_bin);
+            int n = zf->numberOfConesOfDimension(d-ld,oo,mm);
+            L->Init(n);
+            for (int i=0; i<n; i++)
+            {
+              gfan::ZCone zc = zf->getCone(d-ld,i,oo,mm);
+              L->m[i].rtyp = coneID; L->m[i].data=(void*) new gfan::ZCone(zc);
+            }
+            res->rtyp = LIST_CMD;
+            res->data = (void*) L;
+            return FALSE;
+          }
+          else
+          {
+            WerrorS("getCones: invalid dimension; no cones in this dimension");
+            return TRUE;
+          }
+        }
+        else
+        {
+          WerrorS("getCones: invalid dimension");
+          return TRUE;
+        }
+      }
+      else
+      {
+        WerrorS("getCones: invalid specifier for orbit or maximal");
+        return TRUE;
+      }
+    }
+  }
+  WerrorS("getCones: unexpected parameters");
+  return TRUE;
+}
+
+int isSimplicial(gfan::ZFan* zf)
+{
+  int i = zf->isSimplicial() ? 1 : 0;
+  return i;
+}
+
+BOOLEAN isPure(leftv res, leftv args)
+{
+  leftv u=args;
+  if ((u != NULL) && (u->Typ() == fanID))
+  {
+    gfan::ZFan* zf = (gfan::ZFan*) u->Data();
+    int b = zf->isPure();
+    res->rtyp = INT_CMD;
+    res->data = (void*) (long) b;
+    return FALSE;
+  }
+  WerrorS("isPure: unexpected parameters");
+  return TRUE;
+}
+
+BOOLEAN isComplete(leftv res, leftv args)
+{
+  leftv u=args;
+  if ((u != NULL) && (u->Typ() == fanID))
+  {
+    gfan::ZFan* zf = (gfan::ZFan*) u->Data();
+    int b = zf->isComplete();
+    res->rtyp = INT_CMD;
+    res->data = (void*) (long) b;
+    return FALSE;
+  }
+  WerrorS("isComplete: unexpected parameters");
+  return TRUE;
+}
+
+BOOLEAN fVector(leftv res, leftv args)
+{
+  leftv u=args;
+  if ((u != NULL) && (u->Typ() == fanID))
+  {
+    gfan::ZFan* zf = (gfan::ZFan*) u->Data();
+    gfan::ZVector zv=zf->getFVector();
+    res->rtyp = BIGINTMAT_CMD;
+    res->data = (void*) zVectorToBigintmat(zv);
+    return FALSE;
+  }
+  WerrorS("fVector: unexpected parameters");
+  return TRUE;
+}
+
+gfan::ZMatrix rays(const gfan::ZFan* const zf)
+{
+  gfan::ZMatrix rays(0,zf->getAmbientDimension());
+  for (int i=0; i<zf->numberOfConesOfDimension(1,0,0); i++)
+  {
+    gfan::ZCone zc = zf->getCone(1, i, 0, 0);
+    rays.append(zc.extremeRays());
+  }
+  return rays;
+}
+
+int numberOfConesWithVector(gfan::ZFan* zf, gfan::ZVector* v)
+{
+  int count = 0;
+  int ambientDim = zf->getAmbientDimension();
+  for (int i=0; i<zf->numberOfConesOfDimension(ambientDim, 0, 0); i++)
+  {
+    gfan::ZCone zc = zf->getCone(ambientDim, i, 0, 0);
+    if (zc.contains(*v))
+    {
+      count = count +1;
+      if (count > 1)
+        return count;
+    }
+  }
+  return count;
+}
+
+BOOLEAN numberOfConesWithVector(leftv res, leftv args)
+{
+  leftv u=args;
+  if ((u != NULL) && (u->Typ() == fanID))
+  {
+    leftv v=u->next;
+    if ((v != NULL) && (v->Typ() == BIGINTMAT_CMD))
+    {
+      gfan::ZFan* zf = (gfan::ZFan*) u->Data();
+      bigintmat* v0 = (bigintmat*) v->Data();
+      int ambientDim = zf->getAmbientDimension();
+      if (ambientDim != v0->cols())
+      {
+        WerrorS("numberOfConesWithVector: mismatching dimensions");
+        return TRUE;
+      }
+      gfan::ZVector* v1 = bigintmatToZVector(*v0);
+      int count = numberOfConesWithVector(zf, v1);
+      delete v1;
+      res->rtyp = INT_CMD;
+      res->data = (void*) (long) count;
+      return FALSE;
+    }
+  }
+  WerrorS("numberOfConesWithVector: unexpected parameters");
+  return TRUE;
+}
+
+BOOLEAN fanFromString(leftv res, leftv args)
+{
+  leftv u=args;
+  if ((u != NULL) && (u->Typ() == STRING_CMD))
+    {
+      std::string fanInString = (char*) u->Data();
+      std::istringstream s(fanInString);
+      gfan::ZFan* zf = new gfan::ZFan(s);
+      res->rtyp = fanID;
+      res->data = (void*) zf;
+      return FALSE;
+    }
+  WerrorS("fanFromString: unexpected parameters");
+  return TRUE;
+}
+
+BOOLEAN fanViaCones(leftv res, leftv args)
+{
+  leftv u=args;
+  if ((u != NULL) && (u->Typ() == LIST_CMD))
+  {
+    lists L = (lists) u->Data();
+    if (lSize(L)>-1)
+    {
+      if (L->m[0].Typ() != coneID)
+      {
+        WerrorS("fanViaCones: list contains entries of wrong type");
+        return TRUE;
+      }
+      gfan::ZCone* zc = (gfan::ZCone*) L->m[0].Data();
+      gfan::ZFan* zf = new gfan::ZFan(zc->ambientDimension());
+      zf->insert(*zc);
+      for (int i=1; i<=lSize(L); i++)
+      {
+        if (L->m[i].Typ() != coneID)
+        {
+          WerrorS("fanViaCones: entries of wrong type in list");
+          return TRUE;
+        }
+        gfan::ZCone* zc = (gfan::ZCone*) L->m[i].Data();
+        if (zc->ambientDimension() != zf->getAmbientDimension())
+        {
+          WerrorS("fanViaCones: inconsistent ambient dimensions amongst cones in list");
+          return TRUE;
+        }
+        zf->insert(*zc);
+      }
+      res->rtyp = fanID;
+      res->data = (void*) zf;
+      return FALSE;
+    }
+    res->rtyp = fanID;
+    res->data = (void*) new gfan::ZFan(0);
+    return FALSE;
+  }
+  if ((u != NULL) && (u->Typ() == coneID))
+  {
+    gfan::ZCone* zc = (gfan::ZCone*) u->Data();
+    gfan::ZFan* zf = new gfan::ZFan(zc->ambientDimension());
+    zf->insert(*zc);
+    while (u->next != NULL)
+    {
+      u = u->next;
+      if (u->Typ() != coneID)
+      {
+        WerrorS("fanViaCones: arguments of wrong type");
+        return TRUE;
+      }
+      gfan::ZCone* zc = (gfan::ZCone*) u->Data();
+      if (zc->ambientDimension() != zf->getAmbientDimension())
+      {
+        WerrorS("fanViaCones: inconsistent ambient dimensions amongst input cones");
+        return TRUE;
+      }
+      zf->insert(*zc);
+    }
+    res->rtyp = fanID;
+    res->data = (void*) zf;
+    return FALSE;
+  }
+  if (u == NULL)
+  {
+    res->rtyp = fanID;
+    res->data = (void*) new gfan::ZFan(0);
+    return FALSE;
+  }
+  WerrorS("fanViaCones: unexpected parameters");
+  return TRUE;
+}
+
+
+BOOLEAN tropicalVariety(leftv res, leftv args)
+{
+  leftv u=args;
+  if ((u != NULL) && (u->Typ() == POLY_CMD))
+  {
+    int n = rVar(currRing);
+    gfan::ZFan* zf = new gfan::ZFan(n);
+    int* expv1 = (int*)omAlloc((n+1)*sizeof(int));
+    int* expv2 = (int*)omAlloc((n+1)*sizeof(int));
+    int* expvr = (int*)omAlloc((n+1)*sizeof(int));
+    gfan::ZVector expw1 = gfan::ZVector(n);
+    gfan::ZVector expw2 = gfan::ZVector(n);
+    gfan::ZVector expwr = gfan::ZVector(n);
+    gfan::ZMatrix eq, ineq;
+    for (poly s1=(poly)u->Data(); s1!=NULL; pIter(s1))
+    {
+      pGetExpV(s1,expv1);
+      expw1 = intStar2ZVector(n,expv1);
+      for (poly s2=pNext(s1); s2!=NULL; pIter(s2))
+      {
+        pGetExpV(s2,expv2);
+        expw2 = intStar2ZVector(n,expv2);
+        eq = gfan::ZMatrix(0,n);
+        eq.appendRow(expw1-expw2);
+        ineq = gfan::ZMatrix(0,n);
+        for (poly r=(poly)u->Data(); r!=NULL; pIter(r))
+        {
+          pGetExpV(r,expvr);
+          expwr = intStar2ZVector(n,expvr);
+          if ((r!=s1) && (r!=s2))
+          {
+            ineq.appendRow(expw1-expwr);
+          }
+        }
+        gfan::ZCone zc = gfan::ZCone(ineq,eq);
+        zf->insert(zc);
+      }
+    }
+    omFreeSize(expv1,(n+1)*sizeof(int));
+    omFreeSize(expv2,(n+1)*sizeof(int));
+    omFreeSize(expvr,(n+1)*sizeof(int));
+    res->rtyp = fanID;
+    res->data = (void*) zf;
+    return FALSE;
+  }
+  WerrorS("tropicalVariety: unexpected parameters");
+  return TRUE;
+}
+
+gfan::ZFan* commonRefinement(gfan::ZFan* zf, gfan::ZFan* zg)
+{
+  assume(zf->getAmbientDimension() == zg->getAmbientDimension());
+
+  // gather all maximal cones of f and g
+  std::list<gfan::ZCone> maximalConesOfF;
+  for (int d=0; d<=zf->getAmbientDimension(); d++)
+  {
+    for (int i=0; i<zf->numberOfConesOfDimension(d,0,1); i++)
+    {
+      maximalConesOfF.push_back(zf->getCone(d,i,0,1));
+    }
+  }
+
+  std::list<gfan::ZCone> maximalConesOfG;
+  for (int d=0; d<=zg->getAmbientDimension(); d++)
+  {
+    for (int i=0; i<zg->numberOfConesOfDimension(d,0,1); i++)
+    {
+      maximalConesOfG.push_back(zg->getCone(d,i,0,1));
+    }
+  }
+
+  // construct a new fan out of their intersections
+  gfan::ZFan* zr = new gfan::ZFan(zf->getAmbientDimension());
+  for (std::list<gfan::ZCone>::iterator itf=maximalConesOfF.begin();
+       itf != maximalConesOfF.end(); itf++)
+  {
+    for (std::list<gfan::ZCone>::iterator itg=maximalConesOfG.begin();
+         itg != maximalConesOfG.end(); itg++)
+    {
+      zr->insert(intersection(*itf,*itg));
+    }
+  }
+
+  return zr;
+}
+
+BOOLEAN commonRefinement(leftv res, leftv args)
+{
+  leftv u=args;
+  if ((u != NULL) && (u->Typ() == fanID))
+  {
+    leftv v=u->next;
+    if ((v != NULL) && (v->Typ() == fanID))
+    {
+      gfan::ZFan* zf = (gfan::ZFan*) u->Data();
+      gfan::ZFan* zg = (gfan::ZFan*) v->Data();
+      gfan::ZFan* zr = commonRefinement(zf,zg);
+      res->rtyp = fanID;
+      res->data = (void*) zr;
+      return FALSE;
+    }
+  }
+  WerrorS("commonRefinement: unexpected parameters");
+  return TRUE;
+}
+
+// BOOLEAN grFan(leftv res, leftv h)
+// {
+//   /*======== GFAN ==============*/
+//   /*
+//    WILL HAVE TO CHANGE RETURN TYPE TO LIST_CMD
+//   */
+//   /*
+//     heuristic:
+//     0 = keep all Groebner bases in memory
+//     1 = write all Groebner bases to disk and read whenever necessary
+//     2 = use a mixed heuristic, based on length of Groebner bases
+//   */
+//   if( h!=NULL && h->Typ()==IDEAL_CMD && h->next!=NULL && h->next->Typ()==INT_CMD)
+//   {
+//     int heuristic;
+//     heuristic=(int)(long)h->next->Data();
+//     ideal I=((ideal)h->Data());
+//     #ifndef USE_ZFAN
+//         #define USE_ZFAN
+//     #endif
+//     #ifndef USE_ZFAN
+//     res->rtyp=LIST_CMD; //res->rtyp=coneID; res->data(void*)zcone;
+//     res->data=(lists) grfan(I,heuristic,FALSE);
+//     #else
+//     res->rtyp=fanID;
+//     res->data=(void*)(grfan(I,heuristic,FALSE));
+//     #endif
+//     return FALSE;
+//   }
+//   else
+//   {
+//     WerrorS("Usage: grfan(<ideal>,<int>)");
+//     return TRUE;
+//   }
+// }
+  //Possibility to have only one Groebner cone computed by specifying a weight vector FROM THE RELATIVE INTERIOR!
+  //Needs wp as ordering!
+//   if(strcmp(sys_cmd,"grcone")==0)
+//   {
+//     if(h!=NULL && h->Typ()==IDEAL_CMD && h->next!=NULL && h->next->Typ()==INT_CMD)
+//     {
+//       ideal I=((ideal)h->Data());
+//       res->rtyp=LIST_CMD;
+//       res->data=(lists)grcone_by_intvec(I);
+//     }
+//   }
+
+
+void bbfan_setup(SModulFunctions* p)
+{
+  blackbox *b=(blackbox*)omAlloc0(sizeof(blackbox));
+  // all undefined entries will be set to default in setBlackboxStuff
+  // the default Print is quite usefule,
+  // all other are simply error messages
+  b->blackbox_destroy=bbfan_destroy;
+  b->blackbox_String=bbfan_String;
+  //b->blackbox_Print=blackbox_default_Print;
+  b->blackbox_Init=bbfan_Init;
+  b->blackbox_Copy=bbfan_Copy;
+  b->blackbox_Assign=bbfan_Assign;
+  p->iiAddCproc("","emptyFan",FALSE,emptyFan);
+  p->iiAddCproc("","fullFan",FALSE,fullFan);
+  /* the following functions are implemented in bbcone.cc */
+  // iiAddCproc("","containsInSupport",FALSE,containsInSupport);
+  // iiAddCproc("","getAmbientDimension",FALSE,getAmbientDimension);
+  // iiAddCproc("","getCodimension",FALSE,getDimension);
+  // iiAddCproc("","getDimension",FALSE,getDimension);
+  // iiAddCproc("","getLinealityDimension",FALSE,getLinealityDimension);
+  // iiAddCproc("","isSimplicial",FALSE,isSimplicial);
+  /********************************************************/
+  p->iiAddCproc("","isCompatible",FALSE,isCompatible);
+  p->iiAddCproc("","numberOfConesOfDimension",FALSE,numberOfConesOfDimension);
+  p->iiAddCproc("","ncones",FALSE,ncones);
+  p->iiAddCproc("","nmaxcones",FALSE,nmaxcones);
+  p->iiAddCproc("","insertCone",FALSE,insertCone);
+  p->iiAddCproc("","removeCone",FALSE,removeCone);
+  p->iiAddCproc("","getCone",FALSE,getCone);
+  p->iiAddCproc("","getCones",FALSE,getCones);
+  p->iiAddCproc("","isPure",FALSE,isPure);
+  p->iiAddCproc("","fanFromString",FALSE,fanFromString);
+  p->iiAddCproc("","fanViaCones",FALSE,fanViaCones);
+  p->iiAddCproc("","numberOfConesWithVector",FALSE,numberOfConesWithVector);
+  // iiAddCproc("","isComplete",FALSE,isComplete);  not working as expected, should leave this to polymake
+  p->iiAddCproc("","fVector",FALSE,fVector);
+  p->iiAddCproc("","containsInCollection",FALSE,containsInCollection);
+  p->iiAddCproc("","tropicalVariety",FALSE,tropicalVariety);
+  p->iiAddCproc("","commonRefinement",FALSE,commonRefinement);
+  // iiAddCproc("","grFan",FALSE,grFan);
+  fanID=setBlackboxStuff(b,"fan");
+  //Print("created type %d (fan)\n",fanID);
+}
+
+#endif
diff --git a/Singular/dyn_modules/gfanlib/bbfan.h b/Singular/dyn_modules/gfanlib/bbfan.h
new file mode 100644
index 0000000..0db13ca
--- /dev/null
+++ b/Singular/dyn_modules/gfanlib/bbfan.h
@@ -0,0 +1,24 @@
+#ifndef BBFAN_H
+#define BBFAN_H
+
+#include <kernel/mod2.h>
+
+#if HAVE_GFANLIB
+
+#include <Singular/ipid.h>
+
+#include <gfanlib/gfanlib.h>
+
+extern int fanID;
+
+void bbfan_setup(SModulFunctions* p);
+
+int getAmbientDimension(gfan::ZFan* zf);
+int getCodimension(gfan::ZFan* zf);
+int getDimension(gfan::ZFan* zf);
+int getLinealityDimension(gfan::ZFan* zf);
+int isSimplicial(gfan::ZFan* zf);
+gfan::Matrix<gfan::Integer> rays(const gfan::ZFan* const zf);
+
+#endif
+#endif
diff --git a/Singular/dyn_modules/gfanlib/bbpolytope.cc b/Singular/dyn_modules/gfanlib/bbpolytope.cc
new file mode 100644
index 0000000..49901ed
--- /dev/null
+++ b/Singular/dyn_modules/gfanlib/bbpolytope.cc
@@ -0,0 +1,493 @@
+#include <kernel/mod2.h>
+
+#if HAVE_GFANLIB
+
+#include <Singular/ipid.h>
+#include <Singular/ipshell.h>
+#include <Singular/blackbox.h>
+#include <misc/intvec.h>
+#include <coeffs/bigintmat.h>
+
+#include <bbcone.h>
+#include <sstream>
+
+// #include <omalloc/omalloc.h>
+// #include <kernel/longrat.h>
+// #include <Singular/subexpr.h>
+// #include <gfanlib/gfanlib.h>
+// #include <kernel/ring.h>
+// #include <kernel/polys.h>
+
+#include <gfanlib/gfanlib.h>
+#include <gfanlib/gfanlib_q.h>
+
+int polytopeID;
+
+std::string bbpolytopeToString(gfan::ZCone const &c)
+{
+  std::stringstream s;
+  gfan::ZMatrix i=c.getInequalities();
+  gfan::ZMatrix e=c.getEquations();
+  s<<"AMBIENT_DIM"<<std::endl;
+  s<<c.ambientDimension()-1<<std::endl;
+  s<<"INEQUALITIES"<<std::endl;
+  s<<toString(i)<<std::endl;
+  s<<"EQUATIONS"<<std::endl;
+  s<<toString(e)<<std::endl;
+  return s.str();
+}
+
+void *bbpolytope_Init(blackbox* /*b*/)
+{
+  return (void*)(new gfan::ZCone());
+}
+
+BOOLEAN bbpolytope_Assign(leftv l, leftv r)
+{
+  gfan::ZCone* newZc;
+  if (r==NULL)
+  {
+    if (l->Data()!=NULL)
+    {
+      gfan::ZCone* zd = (gfan::ZCone*)l->Data();
+      delete zd;
+    }
+    newZc = new gfan::ZCone();
+  }
+  else if (r->Typ()==l->Typ())
+  {
+    if (l->Data()!=NULL)
+    {
+      gfan::ZCone* zd = (gfan::ZCone*)l->Data();
+      delete zd;
+    }
+    gfan::ZCone* zc = (gfan::ZCone*)r->Data();
+    newZc = new gfan::ZCone(*zc);
+  }
+  // else if (r->Typ()==INT_CMD)  TODO:r->Typ()==BIGINTMAT_CMD
+  // {
+  //   int ambientDim = (int)(long)r->Data();
+  //   if (ambientDim < 0)
+  //   {
+  //     Werror("expected an int >= 0, but got %d", ambientDim);
+  //     return TRUE;
+  //   }
+  //   if (l->Data()!=NULL)
+  //   {
+  //     gfan::ZCone* zd = (gfan::ZCone*)l->Data();
+  //     delete zd;
+  //   }
+  //   newZc = new gfan::ZCone(ambientDim);
+  // }
+  else
+  {
+    Werror("assign Type(%d) = Type(%d) not implemented",l->Typ(),r->Typ());
+    return TRUE;
+  }
+
+  if (l->rtyp==IDHDL)
+  {
+    IDDATA((idhdl)l->data) = (char*) newZc;
+  }
+  else
+  {
+    l->data=(void *)newZc;
+  }
+  return FALSE;
+}
+
+char* bbpolytope_String(blackbox* /*b*/, void *d)
+{ if (d==NULL) return omStrDup("invalid object");
+   else
+   {
+     gfan::ZCone* zc = (gfan::ZCone*)d;
+     std::string s=bbpolytopeToString(*zc);
+     return omStrDup(s.c_str());
+   }
+}
+
+void bbpolytope_destroy(blackbox* /*b*/, void *d)
+{
+  if (d!=NULL)
+  {
+    gfan::ZCone* zc = (gfan::ZCone*) d;
+    delete zc;
+  }
+}
+
+void* bbpolytope_Copy(blackbox* /*b*/, void *d)
+{
+  gfan::ZCone* zc = (gfan::ZCone*)d;
+  gfan::ZCone* newZc = new gfan::ZCone(*zc);
+  return newZc;
+}
+
+static BOOLEAN ppCONERAYS1(leftv res, leftv v)
+{
+  /* method for generating a cone object from half-lines
+     (cone = convex hull of the half-lines; note: there may be
+     entire lines in the cone);
+     valid parametrizations: (bigintmat) */
+  bigintmat* rays = NULL;
+  if (v->Typ() == INTMAT_CMD)
+  {
+    intvec* rays0 = (intvec*) v->Data();
+    rays = iv2bim(rays0,coeffs_BIGINT);
+  }
+  else
+    rays = (bigintmat*) v->Data();
+
+  gfan::ZMatrix* zm = bigintmatToZMatrix(rays);
+  gfan::ZCone* zc = new gfan::ZCone();
+  *zc = gfan::ZCone::givenByRays(*zm, gfan::ZMatrix(0, zm->getWidth()));
+  res->rtyp = polytopeID;
+  res->data = (void*) zc;
+
+  delete zm;
+  if (v->Typ() == INTMAT_CMD)
+    delete rays;
+  return FALSE;
+}
+
+static BOOLEAN ppCONERAYS3(leftv res, leftv u, leftv v)
+{
+  /* method for generating a cone object from half-lines
+     (any point in the cone being the sum of a point
+     in the convex hull of the half-lines and a point in the span
+     of the lines), and an integer k;
+     valid parametrizations: (bigintmat, int);
+     Errors will be invoked in the following cases:
+     - k not 0 or 1;
+     if the k=1, then the extreme rays are known:
+     each half-line spans a (different) extreme ray */
+  bigintmat* rays = NULL;
+  if (u->Typ() == INTMAT_CMD)
+  {
+    intvec* rays0 = (intvec*) u->Data();
+    rays = iv2bim(rays0,coeffs_BIGINT);
+  }
+  else
+    rays = (bigintmat*) u->Data();
+  int k = (int)(long)v->Data();
+
+  if ((k < 0) || (k > 1))
+  {
+    WerrorS("expected int argument in [0..1]");
+    return TRUE;
+  }
+  k=k*2;
+  gfan::ZMatrix* zm = bigintmatToZMatrix(rays);
+  gfan::ZCone* zc = new gfan::ZCone();
+  *zc = gfan::ZCone::givenByRays(*zm,gfan::ZMatrix(0, zm->getWidth()));
+  //k should be passed on to zc; not available yet
+  res->rtyp = polytopeID;
+  res->data = (void*) zc;
+
+  delete zm;
+  if (v->Typ() == INTMAT_CMD)
+    delete rays;
+  return FALSE;
+}
+
+BOOLEAN polytopeViaVertices(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && ((u->Typ() == BIGINTMAT_CMD) || (u->Typ() == INTMAT_CMD)))
+  {
+    if (u->next == NULL) return ppCONERAYS1(res, u);
+    leftv v = u->next;
+    if ((v != NULL) && (v->Typ() == INT_CMD))
+    {
+      if (v->next == NULL) return ppCONERAYS3(res, u, v);
+    }
+  }
+  WerrorS("polytopeViaPoints: unexpected parameters");
+  return TRUE;
+}
+
+static BOOLEAN ppCONENORMALS1(leftv res, leftv v)
+{
+  /* method for generating a cone object from inequalities;
+     valid parametrizations: (bigintmat) */
+  bigintmat* ineq = NULL;
+  if (v->Typ() == INTMAT_CMD)
+  {
+    intvec* ineq0 = (intvec*) v->Data();
+    ineq = iv2bim(ineq0,coeffs_BIGINT);
+  }
+  else
+    ineq = (bigintmat*) v->Data();
+  gfan::ZMatrix* zm = bigintmatToZMatrix(ineq);
+  gfan::ZCone* zc = new gfan::ZCone(*zm, gfan::ZMatrix(0, zm->getWidth()));
+  delete zm;
+  if (v->Typ() == INTMAT_CMD)
+    delete ineq;
+  res->rtyp = polytopeID;
+  res->data = (void*) zc;
+  return FALSE;
+}
+
+static BOOLEAN ppCONENORMALS2(leftv res, leftv u, leftv v)
+{
+  /* method for generating a cone object from iequalities,
+     and equations (...)
+     valid parametrizations: (bigintmat, bigintmat)
+     Errors will be invoked in the following cases:
+     - u and v have different numbers of columns */
+  bigintmat* ineq = NULL; bigintmat* eq = NULL;
+  if (u->Typ() == INTMAT_CMD)
+  {
+    intvec* ineq0 = (intvec*) u->Data();
+    ineq = iv2bim(ineq0,coeffs_BIGINT);
+  }
+  else
+    ineq = (bigintmat*) u->Data();
+  if (v->Typ() == INTMAT_CMD)
+  {
+    intvec* eq0 = (intvec*) v->Data();
+    eq = iv2bim(eq0,coeffs_BIGINT);
+  }
+  else
+    eq = (bigintmat*) v->Data();
+
+  if (ineq->cols() != eq->cols())
+  {
+    Werror("expected same number of columns but got %d vs. %d",
+           ineq->cols(), eq->cols());
+    return TRUE;
+  }
+  gfan::ZMatrix* zm1 = bigintmatToZMatrix(ineq);
+  gfan::ZMatrix* zm2 = bigintmatToZMatrix(eq);
+  gfan::ZCone* zc = new gfan::ZCone(*zm1, *zm2);
+  delete zm1;
+  delete zm2;
+  if (u->Typ() == INTMAT_CMD)
+    delete ineq;
+  if (v->Typ() == INTMAT_CMD)
+    delete eq;
+
+  res->rtyp = polytopeID;
+  res->data = (void*) zc;
+  return FALSE;
+}
+
+static BOOLEAN ppCONENORMALS3(leftv res, leftv u, leftv v, leftv w)
+{
+  /* method for generating a cone object from inequalities, equations,
+     and an integer k;
+     valid parametrizations: (bigintmat, bigintmat, int);
+     Errors will be invoked in the following cases:
+     - u and v have different numbers of columns,
+     - k not in [0..3];
+     if the 2^0-bit of k is set, then ... */
+  bigintmat* ineq = NULL; bigintmat* eq = NULL;
+  if (u->Typ() == INTMAT_CMD)
+  {
+    intvec* ineq0 = (intvec*) u->Data();
+    ineq = iv2bim(ineq0,coeffs_BIGINT);
+  }
+  else
+    ineq = (bigintmat*) u->Data();
+  if (v->Typ() == INTMAT_CMD)
+  {
+    intvec* eq0 = (intvec*) v->Data();
+    eq = iv2bim(eq0,coeffs_BIGINT);
+  }
+  else
+    eq = (bigintmat*) v->Data();
+
+  if (ineq->cols() != eq->cols())
+  {
+    Werror("expected same number of columns but got %d vs. %d",
+           ineq->cols(), eq->cols());
+    return TRUE;
+  }
+  int k = (int)(long)w->Data();
+  if ((k < 0) || (k > 3))
+  {
+    WerrorS("expected int argument in [0..3]");
+    return TRUE;
+  }
+  gfan::ZMatrix* zm1 = bigintmatToZMatrix(ineq);
+  gfan::ZMatrix* zm2 = bigintmatToZMatrix(eq);
+  gfan::ZCone* zc = new gfan::ZCone(*zm1, *zm2, k);
+  delete zm1;
+  delete zm2;
+  if (u->Typ() == INTMAT_CMD)
+    delete ineq;
+  if (v->Typ() == INTMAT_CMD)
+    delete eq;
+
+  res->rtyp = polytopeID;
+  res->data = (void*) zc;
+  return FALSE;
+}
+
+BOOLEAN polytopeViaNormals(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && ((u->Typ() == BIGINTMAT_CMD) || (u->Typ() == INTMAT_CMD)))
+  {
+    if (u->next == NULL) return ppCONENORMALS1(res, u);
+  }
+  leftv v = u->next;
+  if ((v != NULL) && ((v->Typ() == BIGINTMAT_CMD) || (v->Typ() == INTMAT_CMD)))
+  {
+    if (v->next == NULL) return ppCONENORMALS2(res, u, v);
+  }
+  leftv w = v->next;
+  if ((w != NULL) && (w->Typ() == INT_CMD))
+  {
+    if (w->next == NULL) return ppCONENORMALS3(res, u, v, w);
+  }
+  WerrorS("polytopeViaInequalities: unexpected parameters");
+  return TRUE;
+}
+
+BOOLEAN vertices(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && (u->Typ() == polytopeID))
+    {
+      gfan::ZCone* zc = (gfan::ZCone*)u->Data();
+      gfan::ZMatrix zmat = zc->extremeRays();
+      res->rtyp = BIGINTMAT_CMD;
+      res->data = (void*)zMatrixToBigintmat(zmat);
+      return FALSE;
+    }
+  WerrorS("vertices: unexpected parameters");
+  return TRUE;
+}
+
+int getAmbientDimension(gfan::ZCone* zc) // zc is meant to represent a polytope here
+{                                        // hence ambientDimension-1
+  return zc->ambientDimension()-1;
+}
+
+int getCodimension(gfan::ZCone *zc)
+{
+  return zc->codimension();
+}
+
+int getDimension(gfan::ZCone* zc)
+{
+  return zc->dimension()-1;
+}
+
+gfan::ZVector intStar2ZVectorWithLeadingOne(const int d, const int* i)
+{
+  gfan::ZVector zv(d+1);
+  zv[0]=1;
+  for(int j=1; j<=d; j++)
+  {
+    zv[j]=i[j];
+  }
+  return zv;
+}
+
+BOOLEAN newtonPolytope(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && (u->Typ() == POLY_CMD))
+  {
+    poly p = (poly)u->Data();
+    int N = rVar(currRing);
+    gfan::ZMatrix zm(1,N+1);
+    int *leadexpv = (int*)omAlloc((N+1)*sizeof(int));
+    while (p!=NULL)
+    {
+      pGetExpV(p,leadexpv);
+      gfan::ZVector zv = intStar2ZVectorWithLeadingOne(N, leadexpv);
+      zm.appendRow(zv);
+      pIter(p);
+    }
+    omFreeSize(leadexpv,(N+1)*sizeof(int));
+    gfan::ZCone* zc = new gfan::ZCone();
+    *zc = gfan::ZCone::givenByRays(zm, gfan::ZMatrix(0, zm.getWidth()));
+    res->rtyp = polytopeID;
+    res->data = (void*) zc;
+    return FALSE;
+  }
+  WerrorS("newtonPolytope: unexpected parameters");
+  return TRUE;
+}
+
+BOOLEAN scalePolytope(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && (u->Typ() == INT_CMD))
+  {
+    leftv v = u->next;
+    if ((v != NULL) && (v->Typ() == polytopeID))
+    {
+      int s = (int)(long) u->Data();
+      gfan::ZCone* zp = (gfan::ZCone*) v->Data();
+      gfan::ZMatrix zm = zp->extremeRays();
+      for (int i=0; i<zm.getHeight(); i++)
+        for (int j=1; j<zm.getWidth(); j++)
+          zm[i][j]*=s;
+      gfan::ZCone* zq = new gfan::ZCone();
+      *zq = gfan::ZCone::givenByRays(zm,gfan::ZMatrix(0, zm.getWidth()));
+      res->rtyp = polytopeID;
+      res->data = (void*) zq;
+      return FALSE;
+    }
+  }
+  WerrorS("scalePolytope: unexpected parameters");
+  return TRUE;
+}
+
+BOOLEAN dualPolytope(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && (u->Typ() == polytopeID))
+  {
+    gfan::ZCone* zp = (gfan::ZCone*) u->Data();
+    gfan::ZCone* zq = new gfan::ZCone(zp->dualCone());
+    res->rtyp = polytopeID;
+    res->data = (void*) zq;
+    return FALSE;
+  }
+  WerrorS("dualPolytope: unexpected parameters");
+  return TRUE;
+}
+
+void bbpolytope_setup(SModulFunctions* p)
+{
+  blackbox *b=(blackbox*)omAlloc0(sizeof(blackbox));
+  // all undefined entries will be set to default in setBlackboxStuff
+  // the default Print is quite usefule,
+  // all other are simply error messages
+  b->blackbox_destroy=bbpolytope_destroy;
+  b->blackbox_String=bbpolytope_String;
+  //b->blackbox_Print=blackbox_default_Print;
+  b->blackbox_Init=bbpolytope_Init;
+  b->blackbox_Copy=bbpolytope_Copy;
+  b->blackbox_Assign=bbpolytope_Assign;
+  p->iiAddCproc("","polytopeViaPoints",FALSE,polytopeViaVertices);
+  p->iiAddCproc("","polytopeViaInequalities",FALSE,polytopeViaNormals);
+  p->iiAddCproc("","vertices",FALSE,vertices);
+  p->iiAddCproc("","newtonPolytope",FALSE,newtonPolytope);
+  p->iiAddCproc("","scalePolytope",FALSE,scalePolytope);
+  p->iiAddCproc("","dualPolytope",FALSE,dualPolytope);
+  /********************************************************/
+  /* the following functions are implemented in bbcone.cc */
+  // iiAddCproc("","getAmbientDimension",FALSE,getAmbientDimension);
+  // iiAddCproc("","getCodimension",FALSE,getAmbientDimension);
+  // iiAddCproc("","getDimension",FALSE,getDimension);
+  /********************************************************/
+  /* the following functions are identical to those in bbcone.cc */
+  // iiAddCproc("","facets",FALSE,facets);
+  // iiAddCproc("","setLinearForms",FALSE,setLinearForms);
+  // iiAddCproc("","getLinearForms",FALSE,getLinearForms);
+  // iiAddCproc("","setMultiplicity",FALSE,setMultiplicity);
+  // iiAddCproc("","getMultiplicity",FALSE,getMultiplicity);
+  // iiAddCproc("","hasFace",FALSE,hasFace);
+  /***************************************************************/
+  // iiAddCproc("","getEquations",FALSE,getEquations);
+  // iiAddCproc("","getInequalities",FALSE,getInequalities);
+  polytopeID=setBlackboxStuff(b,"polytope");
+  //Print("created type %d (polytope)\n",polytopeID);
+}
+
+#endif
diff --git a/Singular/dyn_modules/gfanlib/bbpolytope.h b/Singular/dyn_modules/gfanlib/bbpolytope.h
new file mode 100644
index 0000000..aabca40
--- /dev/null
+++ b/Singular/dyn_modules/gfanlib/bbpolytope.h
@@ -0,0 +1,22 @@
+#ifndef BBPOLYTOPE_H
+#define BBPOLYTOPE_H
+
+#include <kernel/mod2.h>
+
+#if HAVE_GFANLIB
+
+#include <Singular/ipid.h>
+#include <gfanlib/gfanlib.h>
+
+extern int polytopeID;
+
+void bbpolytope_setup(SModulFunctions* p);
+
+// zc is meant to represent a polytope here
+bigintmat* getFacetNormals(gfan::ZCone *zc);
+int getAmbientDimension(gfan::ZCone* zc);
+int getCodimension(gfan::ZCone *zc);
+int getDimension(gfan::ZCone* zc);
+
+#endif
+#endif
diff --git a/Singular/dyn_modules/gfanlib/gfan.h b/Singular/dyn_modules/gfanlib/gfan.h
new file mode 100644
index 0000000..1781718
--- /dev/null
+++ b/Singular/dyn_modules/gfanlib/gfan.h
@@ -0,0 +1,284 @@
+/*
+gfan.h Interface to gfan.cc
+
+Author: monerjan
+*/
+#ifndef GFAN_H
+#define GFAN_H
+
+#include <kernel/mod2.h>
+
+#if HAVE_GFANLIB
+
+#include <misc/int64vec.h>
+
+#include <gfanlib/config.h>
+#ifdef HAVE_CDD_SETOPER_H
+#include <cdd/setoper.h>
+#include <cdd/cdd.h>
+#include <cdd/cddmp.h>
+#elif HAVE_CDDLIB_SETOPER_H
+#include <cddlib/setoper.h>
+#include <cddlib/cdd.h>
+#include <cddlib/cddmp.h>
+#else
+#include <setoper.h>
+#include <cdd.h>
+#include <cddmp.h>
+#endif
+#include <bbfan.h>
+#include <bbcone.h>
+extern int gfanHeuristic;
+
+#ifndef USE_ZFAN
+#define USE_ZFAN
+#endif
+#ifndef USE_ZFAN
+  lists grfan(ideal inputIdeal, int heuristic, bool singleCone);
+#else
+  #include <gfanlib/gfanlib.h>
+  gfan::ZFan *grfan(ideal inputIdeal, int h, bool singleCone);
+#endif
+// lists grcone_by_intvec(ideal inputIdeal);
+
+class facet
+{
+	private:
+		/** \brief Inner normal of the facet, describing it uniquely up to isomorphism */
+		int64vec *fNormal;
+
+		/** \brief An interior point of the facet*/
+		int64vec *interiorPoint;
+
+		/** \brief Universal Cone Number
+		 * The number of the cone the facet belongs to, Set in getConeNormals()
+		 */
+		int UCN;
+
+		/** \brief The codim of the facet
+		 */
+		short codim;
+
+		/** \brief The Groebner basis on the other side of a shared facet
+		 *
+		 * In order not to have to compute the flipped GB twice we store the basis we already get
+		 * when identifying search facets. Thus in the next step of the reverse search we can
+		 * just copy the old cone and update the facet and the gcBasis.
+		 * facet::flibGB is set via facet::setFlipGB() and printed via facet::printFlipGB
+		 */
+		ideal flipGB;		//The Groebner Basis on the other side, computed via gcone::flip
+
+	public:
+		/** \brief Boolean value to indicate whether a facet is flippable or not
+	 	* This is also used to mark facets that nominally are flippable but which do
+	 	* not intersect with the positive orthant. This check is done in gcone::getCodim2Normals
+		 */
+		bool isFlippable;	//**flippable facet? */
+		//bool isIncoming;	//Is the facet incoming or outgoing in the reverse search? No longer in use
+		facet *next;		//Pointer to next facet
+		facet *prev;		//Pointer to predecessor. Needed for the SearchList in noRevS
+		facet *codim2Ptr;	//Pointer to (codim-2)-facet. Bit of recursion here ;-)
+		int numCodim2Facets;	//#of (codim-2)-facets of this facet. Set in getCodim2Normals()
+		unsigned numRays;	//Number of spanning rays of the facet
+		ring flipRing;		//the ring on the other side of the facet
+// 		int64vec **fRays;
+
+		/** The default constructor. */
+		facet();
+		/** Constructor for lower dimensional faces*/
+		facet(const int &n);
+		/**  The copy constructor */
+		facet(const facet& f);
+		/** A shallow copy of facets*/
+		facet* shallowCopy(const facet& f);
+		void shallowDelete();
+		/** The default destructor */
+		~facet();
+		/** Comparison operator*/
+// 		inline bool operator==(const facet *f,const facet *g);
+		/** \brief Comparison of facets*/
+// 		inline bool areEqual(facet *f, facet *g);//Now static
+		/** Stores the facet normal \param int64vec*/
+		inline void setFacetNormal(int64vec *iv);
+		/** Returns the facet normal */
+		inline int64vec *getFacetNormal() const;
+		/** Return a reference to the facet normal*/
+		inline const int64vec *getRef2FacetNormal() const;
+		/** Method to print the facet normal*/
+		inline void printNormal() const;
+		/** Store the flipped GB*/
+		inline void setFlipGB(ideal I);
+		/** Return the flipped GB*/
+		inline ideal getFlipGB();
+		/** Print the flipped GB*/
+		inline void printFlipGB();
+		/** Set the UCN */
+		inline void setUCN(int n);
+		/** \brief Get the UCN
+		 * Returns the UCN iff this != NULL, else -1
+		 */
+		inline int getUCN();
+		/** Store an interior point of the facet */
+		inline void setInteriorPoint(int64vec *iv);
+		inline int64vec *getInteriorPoint();
+		inline const int64vec *getRef2InteriorPoint();
+		/** \brief Debugging function
+		 * prints the facet normal an all (codim-2)-facets that belong to it
+		 */
+		volatile void fDebugPrint();
+		friend class gcone;
+};
+
+
+/**
+ *\brief Implements the cone structure
+ *
+ * A cone is represented by a linked list of facet normals
+ * @see facet
+ */
+
+class gcone
+{
+	private:
+		ideal inputIdeal;	//the original
+		ring baseRing;		//the basering of the cone
+		int64vec *ivIntPt;	//an interior point of the cone
+		int UCN;		//unique number of the cone
+		int pred;		//UCN of the cone this one is derived from
+ 		static int counter;
+
+	public:
+		/** \brief Pointer to the first facet */
+		facet *facetPtr;	//Will hold the adress of the first facet; set by gcone::getConeNormals
+#ifdef gfanp
+		static float time_getConeNormals;
+		static float time_getCodim2Normals;
+		static float t_getExtremalRays;
+		static float t_ddPolyh;
+		static float time_flip;
+		static float time_flip2;
+		static float t_areEqual;
+		static float t_ffG;
+		static float t_markings;
+		static float t_dd;
+		static float t_kStd;
+		static float time_enqueue;
+		static float time_computeInv;
+		static float t_ddMC;
+		static float t_mI;
+		static float t_iP;
+		static float t_isParallel;
+		static unsigned parallelButNotEqual;
+		static unsigned numberOfFacetChecks;
+#endif
+		/** Matrix to contain the homogeneity/lineality space */
+		static dd_MatrixPtr dd_LinealitySpace;
+		static int lengthOfSearchList;
+		/** Maximum size of the searchlist*/
+		static int maxSize;
+		/** is the ideal homogeneous? */
+		static bool hasHomInput;
+		/** # of variables in the ring */
+		static int numVars;		//#of variables in the ring
+		/** The hilbert function - for the homogeneous case*/
+		static int64vec *hilbertFunction;
+		/** The zero vector. Needed in case of fNormal mismatch*/
+		static int64vec *ivZeroVector;
+
+		/** # of facets of the cone
+		 * This value is set by gcone::getConeNormals
+		 */
+		int numFacets;		//#of facets of the cone
+
+		/**
+		 * At least as a workaround we store the irredundant facets of a matrix here.
+		 * This is needed to compute an interior points of a cone. Note that there
+		 * will be non-flippable facets in it!
+		 */
+		dd_MatrixPtr ddFacets;	//Matrix to store irredundant facets of the cone
+
+		/** Array of intvecs representing the rays of the cone*/
+		int64vec **gcRays;
+		unsigned numRays;	//#rays of the cone
+		/** Contains the Groebner basis of the cone. Is set by gcone::getGB(ideal I)*/
+		ideal gcBasis;		//GB of the cone, set by gcone::getGB();
+		gcone *next;		//Pointer to next cone
+		gcone *prev;
+
+		gcone();
+		gcone(ring r, ideal I);
+		gcone(const gcone& gc, const facet &f);
+		~gcone();
+		inline int getCounter();
+		inline ring getBaseRing();
+		inline ring getRef2BaseRing();
+		inline void setBaseRing(ring r);
+		inline void setIntPoint(int64vec *iv);
+		inline int64vec *getIntPoint(bool shallow=FALSE);
+		inline void showIntPoint();
+		inline void setNumFacets();
+		inline int getNumFacets();
+		inline int getUCN();
+		inline int getPredUCN();
+		volatile void showFacets(short codim=1);
+// 		volatile void showSLA(facet &f);
+// 		void idDebugPrint(const ideal &I);
+// 		void invPrint(const ideal &I);
+// 		bool isMonomial(const ideal &I);
+// 		int64vec *ivNeg(const int64vec *iv);
+// 		inline int dotProduct(int64vec &iva, int64vec &ivb);
+// 		inline int dotProduct(const int64vec &iva, const int64vec &ivb);
+// 		inline bool isParallel(const int64vec &a, const int64vec &b);
+		void noRevS(gcone &gcRoot, bool usingIntPoint=FALSE);
+// 		inline int intgcd(const int &a, const int &b);
+		void writeConeToFile(const gcone &gc, bool usingIntPoints=FALSE);
+		void readConeFromFile(int gcNum, gcone *gc);
+		int64vec f2M(gcone *gc, facet *f, int n=1);
+// 		inline void sortRays(gcone *gc);
+		//The real stuff
+		void getConeNormals(const ideal &I, bool compIntPoint=FALSE);
+		void getCodim2Normals(const gcone &gc);
+		void getExtremalRays(const gcone &gc);
+		void orderRays();
+		void flip(ideal gb, facet *f);
+		void flip2(const ideal &gb, facet *f);
+		void computeInv(const ideal &gb, ideal &inv, const int64vec &f);
+		//poly restOfDiv(poly const &f, ideal const &I); removed with r12286
+		inline ideal ffG(const ideal &H, const ideal &G);
+		inline void getGB(ideal const &inputIdeal);
+		void interiorPoint( dd_MatrixPtr &M, int64vec &iv);//used from flip and optionally from getConeNormals
+// 		void interiorPoint2(); //removed Feb 8th, 2010, new method Feb 19th, 2010, again removed Mar 16th, 2010
+		void preprocessInequalities(dd_MatrixPtr &M);
+		ring rCopyAndAddWeight(const ring &r, int64vec *ivw);
+		ring rCopyAndAddWeight2(const ring &, const int64vec *, const int64vec *);
+// 		ring rCopyAndChangeWeight(const ring &r, int64vec *ivw);	//NOTE remove
+// 		void reverseSearch(gcone *gcAct); //NOTE both removed from r12286
+// 		bool isSearchFacet(gcone &gcTmp, facet *testfacet); //NOTE remove
+		void makeInt(const dd_MatrixPtr &M, const int line, int64vec &n);
+// 		void normalize();//NOTE REMOVE
+		facet * enqueueNewFacets(facet *f);
+		facet * enqueue2(facet *f);
+// 		dd_MatrixPtr facets2Matrix(const gcone &gc);//NOTE remove
+		/** Compute the lineality space Ax=0 and return it as dd_MatrixPtr dd_LinealitySpace*/
+		dd_MatrixPtr computeLinealitySpace();
+		inline bool iv64isStrictlyPositive(const int64vec *);
+		/** Exchange 2 ordertype_a by just 1 */
+		void replaceDouble_ringorder_a_ByASingleOne();
+// 		static void gcone::idPrint(ideal &I);
+// 		friend class facet;
+};
+lists lprepareResult(gcone *gc, const int n);
+/* static int64 int64gcd(const int64 &a, const int64 &b); */
+/* static int intgcd(const int &a, const int &b); */
+/* static int dotProduct(const int64vec &iva, const int64vec &ivb); */
+/* static bool isParallel(const int64vec &a, const int64vec &b); */
+/* static int64vec *ivNeg(/\*const*\/ int64vec *iv); */
+/* static void idDebugPrint(const ideal &I); */
+/* static volatile void showSLA(facet &f); */
+/* static bool isMonomial(const ideal &I); */
+/* static bool ivAreEqual(const int64vec &a, const int64vec &b); */
+/* static bool areEqual2(facet *f, facet *g); */
+/* static bool areEqual( facet *f, facet *g); */
+// bool iv64isStrictlyPositive(int64vec *);
+#endif
+#endif
diff --git a/Singular/dyn_modules/gfanlib/gfanlib.cc b/Singular/dyn_modules/gfanlib/gfanlib.cc
new file mode 100644
index 0000000..28c4c35
--- /dev/null
+++ b/Singular/dyn_modules/gfanlib/gfanlib.cc
@@ -0,0 +1,28 @@
+#include <kernel/mod2.h>
+
+#if HAVE_GFANLIB
+
+#include <bbcone.h>
+#include <bbfan.h>
+#include <bbpolytope.h>
+#include <gitfan.h>
+
+#include <Singular/ipid.h>
+#include <Singular/mod_lib.h>
+
+
+template class gfan::Vector<gfan::Integer>;
+template class gfan::Vector<gfan::Rational>;
+template class gfan::Matrix<gfan::Integer>;
+template class gfan::Matrix<gfan::Rational>;
+
+extern "C" int SI_MOD_INIT(gfanlib)(SModulFunctions* p)
+{
+  bbcone_setup(p);
+  bbfan_setup(p);
+  bbpolytope_setup(p);
+  gitfan_setup(p);
+  return MAX_TOK;
+}
+
+#endif
diff --git a/Singular/dyn_modules/gfanlib/gitfan.cc b/Singular/dyn_modules/gfanlib/gitfan.cc
new file mode 100644
index 0000000..ffd32d7
--- /dev/null
+++ b/Singular/dyn_modules/gfanlib/gitfan.cc
@@ -0,0 +1,377 @@
+/***************************************************************
+ *
+ * File:       gitfan.cc
+ * Purpose:    Computationally intensive procedures for gitfan.lib,
+ *             outsourced to improve the performance.
+ * Authors:    Janko Boehm    boehm at mathematik.uni-kl.de
+ *             Simon Keicher  keicher at mail.mathematik.uni-tuebingen.de
+ *             Yue Ren        ren at mathematik.uni-kl.de
+ *
+ ***************************************************************/
+
+#include <kernel/mod2.h>
+
+#if HAVE_GFANLIB
+
+#include <bbcone.h>
+#include <bbfan.h>
+#include <gitfan.h>
+
+#include <Singular/ipid.h>
+#include <Singular/lists.h>
+#include <Singular/ipshell.h>
+
+#include <coeffs/bigintmat.h>
+
+
+namespace gitfan
+{
+
+  facet::facet():
+    eta(gfan::ZCone()),
+    interiorPoint(gfan::ZVector()),
+    facetNormal(gfan::ZVector())
+  {
+  }
+
+  facet::facet(const gitfan::facet &f):
+    eta(f.eta),
+    interiorPoint(f.interiorPoint),
+    facetNormal(f.facetNormal)
+  {
+#ifndef SING_NDEBUG
+    gfan::ZCone c = f.eta;
+    gfan::ZVector v = f.interiorPoint;
+    gfan::ZVector w = f.facetNormal;
+    assume(c.ambientDimension() == (int)v.size());
+    assume(c.ambientDimension() == (int)w.size());
+    assume(c.contains(v));
+    assume(!c.contains(w));
+#endif
+  }
+
+  facet::facet(const gfan::ZCone &c, const gfan::ZVector &v, const gfan::ZVector &w):
+    eta(c),
+    interiorPoint(v),
+    facetNormal(w)
+  {
+#ifndef SING_NDEBUG
+    assume(c.ambientDimension() == (int)v.size());
+    assume(c.ambientDimension() == (int)w.size());
+    assume(c.contains(v));
+    assume(!c.contains(w));
+#endif
+  }
+
+  facet::~facet()
+  {
+#ifndef SING_NDEBUG
+    gfan::ZCone c = this->eta;
+    gfan::ZVector v = this->interiorPoint;
+    gfan::ZVector w = this->facetNormal;
+    assume(c.ambientDimension() == (int)v.size());
+    assume(c.ambientDimension() == (int)w.size());
+    assume(c.contains(v));
+    assume(!c.contains(w));
+#endif
+  }
+
+  void mergeFacets(facets &F, const facets &newFacets)
+  {
+    std::pair<facets::iterator,bool> check(newFacets.begin(),false);
+    for(facets::iterator p=newFacets.begin(); p!=newFacets.end(); p++)
+    {
+      check = F.insert(*p);
+      if(!check.second)
+        F.erase(check.first);
+    }
+  }
+
+}
+
+
+static gfan::ZCone subcone(const lists &cones, const gfan::ZVector &point)
+{
+  gfan::ZCone sigma = gfan::ZCone(gfan::ZMatrix(1,point.size()), gfan::ZMatrix(1,point.size()));
+  gfan::ZCone* zc;
+  for (int i=0; i<=cones->nr; i++)
+  {
+    zc = (gfan::ZCone*) cones->m[i].Data();
+    if (zc->contains(point))
+      sigma = gfan::intersection(sigma,*zc);
+  }
+  return(sigma);
+}
+
+static gitfan::facets interiorFacets(const gfan::ZCone &zc, const gfan::ZCone &bound)
+{
+  gfan::ZMatrix inequalities = zc.getFacets();
+  gfan::ZMatrix equations = zc.getImpliedEquations();
+  int r = inequalities.getHeight();
+  int c = inequalities.getWidth();
+  gitfan::facets F;
+  if (r*c == 0)
+    /***
+     * this is the trivial case where either we are in a zerodimensional ambient space,
+     * or the cone has no facets.
+     **/
+    return F;
+
+  // int index = 0;
+  /* next we iterate over each of the r facets, build the respective cone and add it to the list */
+  /* this is the i=0 case */
+  gfan::ZMatrix newInequalities = inequalities.submatrix(1,0,r,c);
+  gfan::ZMatrix newEquations = equations;
+  newEquations.appendRow(inequalities[0]);
+  gfan::ZCone eta = gfan::ZCone(newInequalities,newEquations);
+  eta.canonicalize();
+  gfan::ZVector v = eta.getRelativeInteriorPoint();
+  gfan::ZVector w = inequalities[0];
+
+  if (bound.containsRelatively(v))
+    F.insert(gitfan::facet(eta,v,w));
+
+  /* these are the cases i=1,...,r-2 */
+  for (int i=1; i<r-1; i++)
+  {
+    newInequalities = inequalities.submatrix(0,0,i,c);
+    newInequalities.append(inequalities.submatrix(i+1,0,r,c));
+    newEquations = equations;
+    newEquations.appendRow(inequalities[i]);
+    eta = gfan::ZCone(newInequalities,newEquations);
+    eta.canonicalize();
+    v = eta.getRelativeInteriorPoint();
+    w = inequalities[i];
+    if (bound.containsRelatively(v))
+      F.insert(gitfan::facet(eta,v,w));
+  }
+
+  /* this is the i=r-1 case */
+  newInequalities = inequalities.submatrix(0,0,r-1,c);
+  newEquations = equations;
+  newEquations.appendRow(inequalities[r-1]);
+  eta = gfan::ZCone(newInequalities,newEquations);
+  eta.canonicalize();
+
+  v = eta.getRelativeInteriorPoint();
+  w = inequalities[r-1];
+  if (bound.containsRelatively(v))
+    F.insert(gitfan::facet(eta,v,w));
+
+  return F;
+}
+
+BOOLEAN refineCones(leftv res, leftv args)
+{
+  leftv u=args;
+  if ((u != NULL) && (u->Typ() == LIST_CMD))
+  {
+    leftv v=u->next;
+    if ((v != NULL) && (v->Typ() == BIGINTMAT_CMD))
+    {
+      lists cones = (lists) u->Data();
+      bigintmat* bim = (bigintmat*) v->Data();
+      gfan::ZMatrix* zm = bigintmatToZMatrix(bim->transpose());
+      gfan::ZCone support = gfan::ZCone::givenByRays(*zm, gfan::ZMatrix(0, zm->getWidth()));
+      delete zm;
+
+      /***
+       * Randomly compute a first full-dimensional cone and insert it into the fan.
+       * Compute a list of facets and relative interior points.
+       * The relative interior points are unique, assuming the cone is stored in canonical form,
+       * which is the case in our algorithm, as we supply no redundant inequalities.
+       * Hence we can decide whether a facet need to be traversed by crosschecking
+       * its relative interior point with this list.
+       **/
+      gfan::ZCone lambda; gfan::ZVector point;
+      do
+      {
+        point = randomPoint(&support);
+        lambda = subcone(cones, point);
+      }
+      while (lambda.dimension() < lambda.ambientDimension());
+      int iterationNumber = 1;
+      std::cout << "cones found: " << iterationNumber++ << std::endl;
+
+      lambda.canonicalize();
+      gfan::ZFan* Sigma = new gfan::ZFan(lambda.ambientDimension());
+      Sigma->insert(lambda);
+      gitfan::facets F = interiorFacets(lambda, support);
+      if (F.empty())
+      {
+        res->rtyp = fanID;
+        res->data = (void*) Sigma;
+        return FALSE;
+      }
+      int mu = 1024;
+
+      gitfan::facet f;
+      gfan::ZCone eta;
+      gfan::ZVector interiorPoint;
+      gfan::ZVector facetNormal;
+      gitfan::facets newFacets;
+      while (!F.empty())
+      {
+        /***
+         * Extract a facet to traverse and its relative interior point.
+         **/
+        f = *(F.begin());
+        eta = f.getEta();
+        interiorPoint = f.getInteriorPoint();
+        facetNormal = f.getFacetNormal();
+
+        /***
+         * construct a point, which lies on the other side of the facet.
+         * make sure it lies in the known support of our fan
+         * and that the cone around the point is maximal, containing eta.
+         **/
+        point = mu * interiorPoint - facetNormal;
+        while (!support.containsRelatively(point))
+        {
+          mu = mu * 16;
+          point = mu * interiorPoint - facetNormal;
+        }
+
+        lambda = subcone(cones,point);
+        while ((lambda.dimension() < lambda.ambientDimension()) && !(lambda.contains(interiorPoint)))
+        {
+          mu = mu * 16;
+          point = mu * interiorPoint - facetNormal;
+          lambda = subcone(cones,point);
+        }
+        std::cout << "cones found: " << iterationNumber++ << std::endl;
+
+        /***
+         * insert lambda into Sigma, and create a list of facets of lambda.
+         * merge the two lists of facets
+         **/
+        lambda.canonicalize();
+        Sigma->insert(lambda);
+        newFacets = interiorFacets(lambda, support);
+        mergeFacets(F,newFacets);
+        newFacets.clear();
+      }
+      res->rtyp = fanID;
+      res->data = (void*) Sigma;
+      return FALSE;
+    }
+  }
+  WerrorS("refineCones: unexpected parameters");
+  return TRUE;
+}
+
+
+static int binomial(int n, int k)
+{
+  if (n<k)
+    return(0);
+  gfan::Integer num = 1;
+  gfan::Integer den = 1;
+  for (int i=1; i<=k; i++)
+    den = den*i;
+  for (int j=n-k+1; j<=n; j++)
+    num = num*j;
+  gfan::Integer bin = num/den;
+  return(bin.toInt());
+}
+
+
+intvec* intToAface(unsigned int v0, int n, int k)
+{
+  intvec* v = new intvec(k);
+  int j = 0;
+  for (int i=0; i<n; i++)
+  {
+    if (v0 & (1<<i))
+      (*v)[j++] = i+1;
+  }
+  return v;
+}
+
+
+BOOLEAN listOfAfacesToCheck(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && (u->Typ() == INT_CMD))
+  {
+    leftv v = u->next;
+    if ((v != NULL) && (v->Typ() == INT_CMD))
+    {
+      int n = (int)(long) u->Data();
+      int k = (int)(long) v->Data();
+      unsigned int v = 0;
+      for (int i=0; i<k; i++)
+        v |= 1<<i;  // sets the first k bits of v as 1
+
+      lists L = (lists)omAllocBin(slists_bin);
+      int count = (int) binomial(n,k); L->Init(count);
+      unsigned int t;
+      while (!(v & (1<<n)))
+      {
+        L->m[--count].rtyp = INTVEC_CMD;
+        L->m[count].data = (void*) intToAface(v,n,k);
+
+        // t gets v's least significant 0 bits set to 1
+        t = v | (v - 1);
+        // Next set to 1 the most significant bit to change,
+        // set to 0 the least significant ones, and add the necessary 1 bits.
+        v = (t + 1) | (((~t & -~t) - 1) >> (__builtin_ctz(v) + 1));
+      }
+      res->rtyp = LIST_CMD;
+      res->data = (void*) L;
+      return FALSE;
+    }
+  }
+  WerrorS("listOfAfacesToCheck: unexpected parameter");
+  return TRUE;
+}
+
+
+BOOLEAN nextAfaceToCheck(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && (u->Typ() == INTVEC_CMD))
+  {
+    leftv v = u->next;
+    if ((v != NULL) && (v->Typ() == INT_CMD))
+    {
+      leftv w = v->next;
+      if ((w != NULL) && (w->Typ() == INT_CMD))
+      {
+        intvec* aface = (intvec*) u->Data();
+        int ambientDimension = (int)(long) v->Data();
+        int dimension = (int)(long) w->Data();
+
+        unsigned int af = 0;
+        for (int i=0; i<aface->length(); i++)
+          af |= 1<<((*aface)[i]-1);
+
+        unsigned int t = af | (af - 1);
+        af = (t + 1) | (((~t & -~t) - 1) >> (__builtin_ctz(af) + 1));
+
+        if (af & (1<<ambientDimension))
+        {
+          res->rtyp = INTVEC_CMD;
+          res->data = (void*) new intvec(1);
+          return FALSE;
+        }
+
+        res->rtyp = INTVEC_CMD;
+        res->data = (void*) intToAface(af,ambientDimension,dimension);
+        return FALSE;
+      }
+    }
+  }
+  WerrorS("nextAfaceToCheck: unexpected parameter");
+  return TRUE;
+}
+
+
+void gitfan_setup(SModulFunctions* p)
+{
+  p->iiAddCproc("","refineCones",FALSE,refineCones);
+  p->iiAddCproc("","listOfAfacesToCheck",FALSE,listOfAfacesToCheck);
+  p->iiAddCproc("","nextAfaceToCheck",FALSE,nextAfaceToCheck);
+}
+
+#endif
diff --git a/Singular/dyn_modules/gfanlib/gitfan.h b/Singular/dyn_modules/gfanlib/gitfan.h
new file mode 100644
index 0000000..cb9de5d
--- /dev/null
+++ b/Singular/dyn_modules/gfanlib/gitfan.h
@@ -0,0 +1,59 @@
+#ifndef GITFAN_H
+#define GITFAN_H
+
+#include <kernel/mod2.h>
+
+#if HAVE_GFANLIB
+
+#include <bbcone.h>
+#include <bbfan.h>
+
+#include <Singular/ipid.h>
+
+
+namespace gitfan
+{
+
+  class facet
+  {
+    gfan::ZCone eta;
+    gfan::ZVector interiorPoint;
+    gfan::ZVector facetNormal;
+
+  public:
+
+    facet();
+    facet(const facet &f);
+    facet(const gfan::ZCone &c, const gfan::ZVector &v, const gfan::ZVector &w);
+    ~facet();
+
+    gfan::ZCone getEta() { return this->eta; };
+    gfan::ZVector getInteriorPoint() { return this->interiorPoint; };
+    gfan::ZVector getFacetNormal() { return this->facetNormal; };
+
+    friend struct facet_compare;
+  };
+
+  struct facet_compare
+  {
+    bool operator()(const facet &f, const facet &g) const
+    {
+      const gfan::ZVector v1 = f.interiorPoint;
+      const gfan::ZVector v2 = g.interiorPoint;
+#ifndef SING_NDEBUG
+      assume(v1.size() == v2.size());
+#endif
+      return v1 < v2;
+    }
+  };
+
+  typedef std::set<facet,facet_compare> facets;
+
+  void mergeFacets(facets &F, const facets &newFacets);
+
+}
+
+void gitfan_setup(SModulFunctions* p);
+#endif
+
+#endif
diff --git a/Singular/dyn_modules/polymake/Makefile.am b/Singular/dyn_modules/polymake/Makefile.am
new file mode 100644
index 0000000..5d14a6f
--- /dev/null
+++ b/Singular/dyn_modules/polymake/Makefile.am
@@ -0,0 +1,38 @@
+ACLOCAL_AMFLAGS = -I ../../m4
+
+AM_CPPFLAGS =  -I${top_srcdir} -I${top_builddir} \
+-I${top_srcdir}/libpolys -I${top_builddir}/libpolys \
+$(PM_INC) $(PM_CFLAGS) $(POLYMAKE_CXXFLAGS) \
+${FACTORY_INCLUDES} ${RESOURCES_INCLUDES} ${OMALLOC_INCLUDES} \
+${FLINT_CFLAGS} ${NTL_CFLAGS} ${GMP_CFLAGS}
+
+if SI_BUILTIN_POLYMAKE
+  noinst_LTLIBRARIES=polymake.la
+##  moduledir = $(libdir)/singular
+  P_PROCS_CPPFLAGS_COMMON = -DSTATIC_VERSION
+  P_PROCS_MODULE_LDFLAGS  = -module
+else
+  module_LTLIBRARIES=polymake.la
+  moduledir = $(libexecdir)/singular/MOD
+  P_PROCS_CPPFLAGS_COMMON = -DDYNAMIC_VERSION
+  P_PROCS_MODULE_LDFLAGS =  -module -export-dynamic -avoid-version -flat_namespace -weak_reference_mismatches weak -undefined dynamic_lookup
+# Add under Mac OS X: -flat_namespace -weak_reference_mismatches weak -undefined dynamic_lookup
+endif
+
+if SING_HAVE_POLYMAKE
+# forcefully enable exceptions for polymake
+ CXXFLAGS+= $(POLYMAKE_CXXFLAGS)
+ PM_CXXFLAGS= ${POLYMAKE_CXXFLAGS}
+ P_PROCS_MODULE_LDFLAGS+= ${PM_LDFLAGS}
+ polymake_la_LIBADD= ${PM_LIBS}
+endif
+
+SOURCES = polymake_conversion.cc polymake_documentation.cc polymake_wrapper.cc
+
+polymake_la_SOURCES = $(SOURCES)
+
+polymake_la_CPPFLAGS = ${AM_CPPFLAGS} ${P_PROCS_CPPFLAGS_COMMON} ${PM_CXXFLAGS}
+polymake_la_CXXFLAGS = ${PM_CXXFLAGS}
+polymake_la_CFLAGS   = ${PM_CXXFLAGS}
+
+polymake_la_LDFLAGS = ${P_PROCS_MODULE_LDFLAGS}
diff --git a/Singular/dyn_modules/polymake/Makefile.in b/Singular/dyn_modules/polymake/Makefile.in
new file mode 100644
index 0000000..ada818f
--- /dev/null
+++ b/Singular/dyn_modules/polymake/Makefile.in
@@ -0,0 +1,777 @@
+# Makefile.in generated by automake 1.13.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 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@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+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@
+# Add under Mac OS X: -flat_namespace -weak_reference_mismatches weak -undefined dynamic_lookup
+
+# forcefully enable exceptions for polymake
+ at SING_HAVE_POLYMAKE_TRUE@am__append_1 = $(POLYMAKE_CXXFLAGS)
+ at SING_HAVE_POLYMAKE_TRUE@am__append_2 = ${PM_LDFLAGS}
+subdir = Singular/dyn_modules/polymake
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/build-aux/depcomp
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_append_compile_flags.m4 \
+	$(top_srcdir)/m4/ax_append_flag.m4 \
+	$(top_srcdir)/m4/ax_append_link_flags.m4 \
+	$(top_srcdir)/m4/ax_check_compile_flag.m4 \
+	$(top_srcdir)/m4/ax_check_link_flag.m4 \
+	$(top_srcdir)/m4/ax_compute_relative_paths.m4 \
+	$(top_srcdir)/m4/ax_normalize_path.m4 \
+	$(top_srcdir)/m4/ax_prefix_config_h.m4 \
+	$(top_srcdir)/m4/ax_pthread.m4 \
+	$(top_srcdir)/m4/ax_python_embed.m4 \
+	$(top_srcdir)/m4/ax_python_with_version.m4 \
+	$(top_srcdir)/m4/cpu-check.m4 $(top_srcdir)/m4/dbm-check.m4 \
+	$(top_srcdir)/m4/flags.m4 $(top_srcdir)/m4/flint-check.m4 \
+	$(top_srcdir)/m4/gfanlib-check.m4 \
+	$(top_srcdir)/m4/gmp-check.m4 \
+	$(top_srcdir)/m4/google-perftools.m4 \
+	$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+	$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+	$(top_srcdir)/m4/lt~obsolete.m4 \
+	$(top_srcdir)/m4/mathic-check.m4 $(top_srcdir)/m4/ntl-check.m4 \
+	$(top_srcdir)/m4/options.m4 $(top_srcdir)/m4/p-procs.m4 \
+	$(top_srcdir)/m4/polymake-check.m4 \
+	$(top_srcdir)/m4/readline-check.m4 $(top_srcdir)/configure.ac
+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__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
+am__installdirs = "$(DESTDIR)$(moduledir)"
+LTLIBRARIES = $(module_LTLIBRARIES) $(noinst_LTLIBRARIES)
+am__DEPENDENCIES_1 =
+ at SING_HAVE_POLYMAKE_TRUE@polymake_la_DEPENDENCIES =  \
+ at SING_HAVE_POLYMAKE_TRUE@	$(am__DEPENDENCIES_1)
+am__objects_1 = polymake_la-polymake_conversion.lo \
+	polymake_la-polymake_documentation.lo \
+	polymake_la-polymake_wrapper.lo
+am_polymake_la_OBJECTS = $(am__objects_1)
+polymake_la_OBJECTS = $(am_polymake_la_OBJECTS)
+AM_V_lt = $(am__v_lt_ at AM_V@)
+am__v_lt_ = $(am__v_lt_ at AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 = 
+polymake_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(polymake_la_CXXFLAGS) \
+	$(CXXFLAGS) $(polymake_la_LDFLAGS) $(LDFLAGS) -o $@
+ at SI_BUILTIN_POLYMAKE_FALSE@am_polymake_la_rpath = -rpath $(moduledir)
+ at SI_BUILTIN_POLYMAKE_TRUE@am_polymake_la_rpath =
+AM_V_P = $(am__v_P_ at AM_V@)
+am__v_P_ = $(am__v_P_ at AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_ at AM_V@)
+am__v_GEN_ = $(am__v_GEN_ at AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_ at AM_V@)
+am__v_at_ = $(am__v_at_ at AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+DEFAULT_INCLUDES = -I. at am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \
+	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+	$(AM_CXXFLAGS) $(CXXFLAGS)
+AM_V_CXX = $(am__v_CXX_ at AM_V@)
+am__v_CXX_ = $(am__v_CXX_ at AM_DEFAULT_V@)
+am__v_CXX_0 = @echo "  CXX     " $@;
+am__v_CXX_1 = 
+CXXLD = $(CXX)
+CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+	$(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CXXLD = $(am__v_CXXLD_ at AM_V@)
+am__v_CXXLD_ = $(am__v_CXXLD_ at AM_DEFAULT_V@)
+am__v_CXXLD_0 = @echo "  CXXLD   " $@;
+am__v_CXXLD_1 = 
+DIST_SOURCES = $(polymake_la_SOURCES)
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BUILTIN_LIBS = @BUILTIN_LIBS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CDDGMPCPPFLAGS = @CDDGMPCPPFLAGS@
+CDDGMPLDFLAGS = @CDDGMPLDFLAGS@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@ $(am__append_1)
+CYGPATH_W = @CYGPATH_W@
+DATA_DIR = @DATA_DIR@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DOC_DIR = @DOC_DIR@
+DOXYGEN = @DOXYGEN@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FACTORY_INCLUDES = @FACTORY_INCLUDES@
+FACTORY_LIBS = @FACTORY_LIBS@
+FGREP = @FGREP@
+FLINT_CFLAGS = @FLINT_CFLAGS@
+FLINT_HOME = @FLINT_HOME@
+FLINT_LIBS = @FLINT_LIBS@
+GMP_CFLAGS = @GMP_CFLAGS@
+GMP_HOME = @GMP_HOME@
+GMP_LIBS = @GMP_LIBS@
+GMP_VERSION = @GMP_VERSION@
+GREP = @GREP@
+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@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NTL_CFLAGS = @NTL_CFLAGS@
+NTL_LIBS = @NTL_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OMALLOC_INCLUDES = @OMALLOC_INCLUDES@
+OMALLOC_LIBS = @OMALLOC_LIBS@
+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@
+PKG_REQUIRE = @PKG_REQUIRE@
+PMCONFIG = @PMCONFIG@
+PM_CFLAGS = @PM_CFLAGS@
+PM_INC = @PM_INC@
+PM_LDFLAGS = @PM_LDFLAGS@
+PM_LIBS = @PM_LIBS@
+POLYMAKE_CXXFLAGS = @POLYMAKE_CXXFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LDFLAGS = @PTHREAD_LDFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
+PYTHON = @PYTHON@
+PYTHON_CSPEC = @PYTHON_CSPEC@
+PYTHON_EXECPREFIX = @PYTHON_EXECPREFIX@
+PYTHON_LSPEC = @PYTHON_LSPEC@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+RANLIB = @RANLIB@
+RESOURCES_INCLUDES = @RESOURCES_INCLUDES@
+RESOURCES_LIBS = @RESOURCES_LIBS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SINGULAR_CFLAGS = @SINGULAR_CFLAGS@
+SI_COUNTEDREF_AUTOLOAD = @SI_COUNTEDREF_AUTOLOAD@
+SI_CPU_I386 = @SI_CPU_I386@
+SI_CPU_IA64 = @SI_CPU_IA64@
+SI_CPU_PPC = @SI_CPU_PPC@
+SI_CPU_SPARC = @SI_CPU_SPARC@
+SI_CPU_X86_64 = @SI_CPU_X86_64@
+STRIP = @STRIP@
+USEPPROCSDYNAMICLD = @USEPPROCSDYNAMICLD@
+USEPPROCSDYNAMICLDFLAGS = @USEPPROCSDYNAMICLDFLAGS@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
+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@
+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@
+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@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+ACLOCAL_AMFLAGS = -I ../../m4
+AM_CPPFLAGS = -I${top_srcdir} -I${top_builddir} \
+-I${top_srcdir}/libpolys -I${top_builddir}/libpolys \
+$(PM_INC) $(PM_CFLAGS) $(POLYMAKE_CXXFLAGS) \
+${FACTORY_INCLUDES} ${RESOURCES_INCLUDES} ${OMALLOC_INCLUDES} \
+${FLINT_CFLAGS} ${NTL_CFLAGS} ${GMP_CFLAGS}
+
+ at SI_BUILTIN_POLYMAKE_TRUE@noinst_LTLIBRARIES = polymake.la
+ at SI_BUILTIN_POLYMAKE_FALSE@P_PROCS_CPPFLAGS_COMMON = -DDYNAMIC_VERSION
+ at SI_BUILTIN_POLYMAKE_TRUE@P_PROCS_CPPFLAGS_COMMON = -DSTATIC_VERSION
+ at SI_BUILTIN_POLYMAKE_FALSE@P_PROCS_MODULE_LDFLAGS = -module \
+ at SI_BUILTIN_POLYMAKE_FALSE@	-export-dynamic -avoid-version \
+ at SI_BUILTIN_POLYMAKE_FALSE@	-flat_namespace \
+ at SI_BUILTIN_POLYMAKE_FALSE@	-weak_reference_mismatches weak \
+ at SI_BUILTIN_POLYMAKE_FALSE@	-undefined dynamic_lookup \
+ at SI_BUILTIN_POLYMAKE_FALSE@	$(am__append_2)
+ at SI_BUILTIN_POLYMAKE_TRUE@P_PROCS_MODULE_LDFLAGS = -module \
+ at SI_BUILTIN_POLYMAKE_TRUE@	$(am__append_2)
+ at SI_BUILTIN_POLYMAKE_FALSE@module_LTLIBRARIES = polymake.la
+ at SI_BUILTIN_POLYMAKE_FALSE@moduledir = $(libexecdir)/singular/MOD
+ at SING_HAVE_POLYMAKE_TRUE@PM_CXXFLAGS = ${POLYMAKE_CXXFLAGS}
+ at SING_HAVE_POLYMAKE_TRUE@polymake_la_LIBADD = ${PM_LIBS}
+SOURCES = polymake_conversion.cc polymake_documentation.cc polymake_wrapper.cc
+polymake_la_SOURCES = $(SOURCES)
+polymake_la_CPPFLAGS = ${AM_CPPFLAGS} ${P_PROCS_CPPFLAGS_COMMON} ${PM_CXXFLAGS}
+polymake_la_CXXFLAGS = ${PM_CXXFLAGS}
+polymake_la_CFLAGS = ${PM_CXXFLAGS}
+polymake_la_LDFLAGS = ${P_PROCS_MODULE_LDFLAGS}
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .cc .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) --foreign Singular/dyn_modules/polymake/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign Singular/dyn_modules/polymake/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-moduleLTLIBRARIES: $(module_LTLIBRARIES)
+	@$(NORMAL_INSTALL)
+	@list='$(module_LTLIBRARIES)'; test -n "$(moduledir)" || list=; \
+	list2=; for p in $$list; do \
+	  if test -f $$p; then \
+	    list2="$$list2 $$p"; \
+	  else :; fi; \
+	done; \
+	test -z "$$list2" || { \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(moduledir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(moduledir)" || exit 1; \
+	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(moduledir)'"; \
+	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(moduledir)"; \
+	}
+
+uninstall-moduleLTLIBRARIES:
+	@$(NORMAL_UNINSTALL)
+	@list='$(module_LTLIBRARIES)'; test -n "$(moduledir)" || list=; \
+	for p in $$list; do \
+	  $(am__strip_dir) \
+	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(moduledir)/$$f'"; \
+	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(moduledir)/$$f"; \
+	done
+
+clean-moduleLTLIBRARIES:
+	-test -z "$(module_LTLIBRARIES)" || rm -f $(module_LTLIBRARIES)
+	@list='$(module_LTLIBRARIES)'; \
+	locs=`for p in $$list; do echo $$p; done | \
+	      sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+	      sort -u`; \
+	test -z "$$locs" || { \
+	  echo rm -f $${locs}; \
+	  rm -f $${locs}; \
+	}
+
+clean-noinstLTLIBRARIES:
+	-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+	@list='$(noinst_LTLIBRARIES)'; \
+	locs=`for p in $$list; do echo $$p; done | \
+	      sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+	      sort -u`; \
+	test -z "$$locs" || { \
+	  echo rm -f $${locs}; \
+	  rm -f $${locs}; \
+	}
+
+polymake.la: $(polymake_la_OBJECTS) $(polymake_la_DEPENDENCIES) $(EXTRA_polymake_la_DEPENDENCIES) 
+	$(AM_V_CXXLD)$(polymake_la_LINK) $(am_polymake_la_rpath) $(polymake_la_OBJECTS) $(polymake_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/polymake_la-polymake_conversion.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/polymake_la-polymake_documentation.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/polymake_la-polymake_wrapper.Plo at am__quote@
+
+.cc.o:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+ at am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXXCOMPILE) -c -o $@ $<
+
+.cc.obj:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+ at am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.cc.lo:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+ at am__fastdepCXX_TRUE@	$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LTCXXCOMPILE) -c -o $@ $<
+
+polymake_la-polymake_conversion.lo: polymake_conversion.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(polymake_la_CPPFLAGS) $(CPPFLAGS) $(polymake_la_CXXFLAGS) $(CXXFLAGS) -MT polymake_la-polymake_conversion.lo -MD -MP -MF $(DEPDIR)/polymake_la-polymake_conversion.Tpo -c -o polymake_la-polymake_conversion.lo `test -f 'polymake_conversion.cc' || echo '$(srcdir)/'`polymake_conversion.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/polymake_la-polymake_conversion.Tpo $(DEPDIR)/polymake_la-polymake_conversion.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='polymake_conversion.cc' object='polymake_la-polymake_conversion.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(polymake_la_CPPFLAGS) $(CPPFLAGS) $(polymake_la_CXXFLAGS) $(CXXFLAGS) -c -o polymake_la-polymake_conversion.lo `test -f 'polymake_conversion.cc' || echo '$(srcdir)/'`polymake_conversion.cc
+
+polymake_la-polymake_documentation.lo: polymake_documentation.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(polymake_la_CPPFLAGS) $(CPPFLAGS) $(polymake_la_CXXFLAGS) $(CXXFLAGS) -MT polymake_la-polymake_documentation.lo -MD -MP -MF $(DEPDIR)/polymake_la-polymake_documentation.Tpo -c -o polymake_la-polymake_documentation.lo `test -f 'polymake_documentation.cc' || echo '$(srcdir)/'`polymake_documentation.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/polymake_la-polymake_documentation.Tpo $(DEPDIR)/polymake_la-polymake_documentation.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='polymake_documentation.cc' object='polymake_la-polymake_documentation.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(polymake_la_CPPFLAGS) $(CPPFLAGS) $(polymake_la_CXXFLAGS) $(CXXFLAGS) -c -o polymake_la-polymake_documentation.lo `test -f 'polymake_documentation.cc' || echo '$(srcdir)/'`polymake_documentation.cc
+
+polymake_la-polymake_wrapper.lo: polymake_wrapper.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(polymake_la_CPPFLAGS) $(CPPFLAGS) $(polymake_la_CXXFLAGS) $(CXXFLAGS) -MT polymake_la-polymake_wrapper.lo -MD -MP -MF $(DEPDIR)/polymake_la-polymake_wrapper.Tpo -c -o polymake_la-polymake_wrapper.lo `test -f 'polymake_wrapper.cc' || echo '$(srcdir)/'`polymake_wrapper.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/polymake_la-polymake_wrapper.Tpo $(DEPDIR)/polymake_la-polymake_wrapper.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='polymake_wrapper.cc' object='polymake_la-polymake_wrapper.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(polymake_la_CPPFLAGS) $(CPPFLAGS) $(polymake_la_CXXFLAGS) $(CXXFLAGS) -c -o polymake_la-polymake_wrapper.lo `test -f 'polymake_wrapper.cc' || echo '$(srcdir)/'`polymake_wrapper.cc
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	$(am__define_uniq_tagged_files); \
+	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-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	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"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+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 $(LTLIBRARIES)
+installdirs:
+	for dir in "$(DESTDIR)$(moduledir)"; 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:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+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 clean-moduleLTLIBRARIES \
+	clean-noinstLTLIBRARIES 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-moduleLTLIBRARIES
+
+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: uninstall-moduleLTLIBRARIES
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
+	clean-libtool clean-moduleLTLIBRARIES clean-noinstLTLIBRARIES \
+	cscopelist-am ctags ctags-am 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-moduleLTLIBRARIES 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 tags-am uninstall uninstall-am \
+	uninstall-moduleLTLIBRARIES
+
+
+# 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/Singular/dyn_modules/polymake/polymake_conversion.cc b/Singular/dyn_modules/polymake/polymake_conversion.cc
new file mode 100644
index 0000000..03fc2be
--- /dev/null
+++ b/Singular/dyn_modules/polymake/polymake_conversion.cc
@@ -0,0 +1,525 @@
+#include <kernel/mod2.h>
+
+#ifdef HAVE_POLYMAKE
+
+#include <gmpxx.h>
+
+#include <polymake/Main.h>
+#include <polymake/Matrix.h>
+#include <polymake/Rational.h>
+#include <polymake/Integer.h>
+#include <polymake/Set.h>
+#include <polymake/common/lattice_tools.h>
+#include <polymake/IncidenceMatrix.h>
+
+#include <gfanlib/gfanlib.h>
+#include <gfanlib/gfanlib_q.h>
+
+#include <misc/intvec.h>
+#include <coeffs/numbers.h>
+#include <coeffs/bigintmat.h>
+#include <Singular/lists.h>
+#include <Singular/ipid.h> // for bigints,
+// is there really nothing better than this?
+
+/* Functions for converting Integers, Rationals and their Matrices
+   in between C++, gfan, polymake and singular */
+
+/* gfan -> polymake */
+
+polymake::Integer GfInteger2PmInteger (const gfan::Integer& gi)
+{
+  mpz_t cache; mpz_init(cache);
+  gi.setGmp(cache);
+  polymake::Integer pi(cache);
+  return pi;
+}
+
+polymake::Rational GfRational2PmRational (const gfan::Rational& gr)
+{
+  mpq_t cache; mpq_init(cache);
+  gr.setGmp(cache);
+  polymake::Rational pr(cache);
+  return pr;
+}
+
+polymake::Vector<polymake::Integer> Intvec2PmVectorInteger (const intvec* iv)
+{
+  polymake::Vector<polymake::Integer> vi(iv->length());
+  for(int i=1; i<=iv->length(); i++)
+  {
+    vi[i-1]=(*iv)[i-1];
+  }
+  return vi;
+}
+
+polymake::Matrix<polymake::Integer> GfZMatrix2PmMatrixInteger (const gfan::ZMatrix* zm)
+{
+  int rows=zm->getHeight();
+  int cols=zm->getWidth();
+  polymake::Matrix<polymake::Integer> mi(rows,cols);
+  for(int r=1; r<=rows; r++)
+    for(int c=1; c<=cols; c++)
+      mi(r-1,c-1) = GfInteger2PmInteger((*zm)[r-1][c-1]);
+  return mi;
+}
+
+polymake::Matrix<polymake::Rational> GfQMatrix2PmMatrixRational (const gfan::QMatrix* qm)
+{
+  int rows=qm->getHeight();
+  int cols=qm->getWidth();
+  polymake::Matrix<polymake::Rational> mr(rows,cols);
+  for(int r=1; r<=rows; r++)
+    for(int c=1; c<=cols; c++)
+      mr(r-1,c-1) = GfRational2PmRational((*qm)[r-1][c-1]);
+  return mr;
+}
+
+/* gfan <- polymake */
+
+gfan::Integer PmInteger2GfInteger (const polymake::Integer& pi)
+{
+  mpz_class cache(pi.get_rep());
+  gfan::Integer gi(cache.get_mpz_t());
+  return gi;
+}
+
+gfan::Rational PmRational2GfRational (const polymake::Rational& pr)
+{
+  mpq_class cache(pr.get_rep());
+  gfan::Rational gr(cache.get_mpq_t());
+  return gr;
+}
+
+gfan::ZMatrix PmMatrixInteger2GfZMatrix (const polymake::Matrix<polymake::Integer>* mi)
+{
+  int rows=mi->rows();
+  int cols=mi->cols();
+  gfan::ZMatrix zm(rows,cols);
+  for(int r=1; r<=rows; r++)
+    for(int c=1; c<=cols; c++)
+      zm[r-1][c-1] = PmInteger2GfInteger((*mi)(r-1,c-1));
+  return zm;
+}
+
+gfan::QMatrix PmMatrixRational2GfQMatrix (const polymake::Matrix<polymake::Rational>* mr)
+{
+  int rows=mr->rows();
+  int cols=mr->cols();
+  gfan::QMatrix qm(rows,cols);
+  for(int r=1; r<=rows; r++)
+    for(int c=1; c<=cols; c++)
+      qm[r-1][c-1] = PmRational2GfRational((*mr)(r-1,c-1));
+  return qm;
+}
+
+/* polymake -> singular */
+
+int PmInteger2Int(const polymake::Integer& pi, bool &ok)
+{
+  int i=0;
+  try
+  {
+    i = pi.to_int();
+  }
+  catch (const std::exception& ex)
+  {
+    WerrorS("ERROR: "); WerrorS(ex.what()); WerrorS("\n");
+    ok = false;
+  }
+  return i;
+}
+
+number PmInteger2Number (const polymake::Integer& pi)
+{
+  mpz_class cache(pi.get_rep());
+  long m = 268435456;
+  if(mpz_cmp_si(cache.get_mpz_t(),m))
+  {
+    int temp = (int) mpz_get_si(cache.get_mpz_t());
+    return n_Init(temp,coeffs_BIGINT);
+  }
+  else
+    return n_InitMPZ(cache.get_mpz_t(),coeffs_BIGINT);
+}
+
+intvec* PmVectorInteger2Intvec (const polymake::Vector<polymake::Integer>* vi, bool &ok)
+{
+  intvec* iv = new intvec(vi->size());
+  for(int i=1; i<=vi->size(); i++)
+  {
+    (*iv)[i-1] = PmInteger2Int((*vi)[i-1],ok);
+  }
+  return iv;
+}
+
+intvec* PmMatrixInteger2Intvec (polymake::Matrix<polymake::Integer>* mi, bool &ok)
+{
+  int rows = mi->rows();
+  int cols = mi->cols();
+  intvec* iv = new intvec(rows,cols,0);
+  const polymake::Integer* pi = concat_rows(*mi).begin();
+  for (int r = 1; r <= rows; r++)
+    for (int c = 1; c <= cols; c++)
+    {
+      IMATELEM(*iv,r,c) = PmInteger2Int(*pi, ok);
+      pi++;
+    }
+  return iv;
+}
+
+bigintmat* PmMatrixInteger2Bigintmat (polymake::Matrix<polymake::Integer>* mi)
+{
+  int rows = mi->rows();
+  int cols = mi->cols();
+  bigintmat* bim= new bigintmat(rows,cols,coeffs_BIGINT);
+  const polymake::Integer* pi = concat_rows(*mi).begin();
+  for (int r = 1; r <= rows; r++)
+    for (int c = 1; c <= cols; c++)
+    {
+      number temp = PmInteger2Number(*pi);
+      bim->set(r,c,temp);
+      n_Delete(&temp,coeffs_BIGINT);
+      pi++;
+    }
+  return bim;
+}
+
+lists PmIncidenceMatrix2ListOfIntvecs (polymake::IncidenceMatrix<polymake::NonSymmetric>* icmat)
+{
+  int rows = icmat->rows();
+  int cols = icmat->cols();
+  lists L = (lists)omAllocBin(slists_bin);
+  L->Init(rows);
+
+  for (int r = 0; r < rows; r++)
+  {
+    intvec* iv = new intvec(cols); int i=0;
+    for (int c = 0; c < cols; c++)
+    {
+      if ((*icmat).row(r).exists(c))
+      { (*iv)[i]=c; i++; }
+    }
+    iv->resize(i);
+    L->m[r].rtyp = INTVEC_CMD;
+    L->m[r].data = (void*) iv;
+  }
+
+  return L;
+}
+
+lists PmAdjacencyMatrix2ListOfEdges (polymake::IncidenceMatrix<polymake::NonSymmetric>* icmat)
+{
+  int rows = icmat->rows();
+  int cols = icmat->cols();
+
+  // counting number of edges
+  int i=0; int r, c;
+  for (r=0; r<rows; r++)
+  {
+    for (c=0; c<cols; c++)
+    {
+      if ((*icmat).row(r).exists(c) && r<c)
+        i++;
+    }
+  }
+
+  lists L = (lists)omAllocBin(slists_bin);
+  L->Init(i);
+
+  i=0;
+  for (r=0; r<rows; r++)
+  {
+    for (c=0; c<cols; c++)
+    {
+      if ((*icmat).row(r).exists(c) && r<c)
+      {
+        intvec* iv = new intvec(2);
+        (*iv)[0]=r; (*iv)[1]=c;
+        L->m[i].rtyp = INTVEC_CMD;
+        L->m[i].data = (void*) iv;
+        i++;
+      }
+    }
+  }
+
+  return L;
+}
+
+intvec* PmSetInteger2Intvec (polymake::Set<polymake::Integer>* si, bool &b)
+{
+  polymake::Vector<polymake::Integer> vi(*si);
+  return PmVectorInteger2Intvec(&vi,b);
+}
+
+/* polymake <- singular */
+
+polymake::Matrix<polymake::Integer> Intvec2PmMatrixInteger (const intvec* im)
+{
+  int rows=im->rows();
+  int cols=im->cols();
+  polymake::Matrix<polymake::Integer> mi(rows,cols);
+  for(int r=0; r<rows; r++)
+    for(int c=0; c<cols; c++)
+      mi(r,c) = polymake::Integer(IMATELEM(*im, r+1, c+1));
+  return mi;
+}
+
+/* Functions for converting cones and fans in between gfan and polymake,
+   Singular shares the same cones and fans with gfan */
+
+gfan::ZCone* PmCone2ZCone (polymake::perl::Object* pc)
+{
+  if (pc->isa("Cone"))
+  {
+    polymake::Integer ambientdim1 = pc->give("CONE_AMBIENT_DIM");
+    bool ok=true; int ambientdim2 = PmInteger2Int(ambientdim1, ok);
+    if (!ok)
+    {
+      WerrorS("PmCone2ZCone: overflow while converting polymake::Integer to int");
+    }
+    polymake::Matrix<polymake::Rational> ineqrational = pc->give("FACETS");
+    polymake::Matrix<polymake::Rational> eqrational = pc->give("LINEAR_SPAN");
+    // polymake::Matrix<polymake::Rational> exraysrational = pc->give("RAYS");
+    // polymake::Matrix<polymake::Rational> linrational = pc->give("LINEALITY_SPACE");
+
+    gfan::ZMatrix zv, zw, zx, zy, zz;
+    // the following branching statements are to cover cases in which polymake returns empty matrices
+    // by convention, gfanlib ignores empty matrices, hence zero matrices of right dimensions have to be supplied
+    if (ineqrational.cols()!=0)
+    {
+      polymake::Matrix<polymake::Integer> ineqinteger = polymake::common::primitive(ineqrational);
+      zv = PmMatrixInteger2GfZMatrix(&ineqinteger);
+    }
+    else
+      zv = gfan::ZMatrix(0, ambientdim2);
+    if (eqrational.cols()!=0)
+    {
+      polymake::Matrix<polymake::Integer> eqinteger = polymake::common::primitive(eqrational);
+      zw = PmMatrixInteger2GfZMatrix(&eqinteger);
+    }
+    else
+      zw = gfan::ZMatrix(0, ambientdim2);
+    // if (exraysrational.cols()!=0)
+    // {
+    //   polymake::Matrix<polymake::Integer> exraysinteger = polymake::common::primitive(exraysrational);
+    //   zx = PmMatrixInteger2GfZMatrix(&exraysinteger);
+    // }
+    // else
+    //   zx = gfan::ZMatrix(0, ambientdim2);
+    // if (linrational.cols()!=0)
+    // {
+    //   polymake::Matrix<polymake::Integer> lininteger = polymake::common::primitive(linrational);
+    //   zy = PmMatrixInteger2GfZMatrix(&lininteger);
+    // }
+    // else
+    //   zy = gfan::ZMatrix(0, ambientdim2);
+
+    // gfan::ZCone* zc = new gfan::ZCone(zv,zw,zx,zy,zz,3);
+    gfan::ZCone* zc = new gfan::ZCone(zv,zw,3);
+    return zc;
+  }
+  WerrorS("PmCone2ZCone: unexpected parameters");
+  return NULL;
+}
+
+gfan::ZCone* PmPolytope2ZPolytope (polymake::perl::Object* pp)
+{
+  if (pp->isa("Polytope<Rational>"))
+  {
+    polymake::Integer ambientdim1 = pp->give("CONE_AMBIENT_DIM");
+    bool ok=true; int ambientdim2 = PmInteger2Int(ambientdim1, ok);
+    if (!ok)
+    {
+      WerrorS("overflow while converting polymake::Integer to int");
+    }
+    polymake::Matrix<polymake::Rational> ineqrational = pp->give("FACETS");
+    polymake::Matrix<polymake::Rational> eqrational = pp->give("AFFINE_HULL");
+    // polymake::Matrix<polymake::Rational> vertrational = pp->give("VERTICES");
+    // polymake::Matrix<polymake::Rational> linrational = pp->give("LINEALITY_SPACE");
+
+    gfan::ZMatrix zv, zw;
+    // the following branching statements are to cover the cases when polymake returns empty matrices
+    // by convention, gfanlib ignores empty matrices, hence zero matrices of right dimensions have to be supplied
+    if (ineqrational.cols()!=0)
+    {
+      polymake::Matrix<polymake::Integer> ineqinteger = polymake::common::primitive(ineqrational);
+      zv = PmMatrixInteger2GfZMatrix(&ineqinteger);
+    }
+    else
+      zv = gfan::ZMatrix(0, ambientdim2);
+
+    if (eqrational.cols()!=0)
+    {
+      polymake::Matrix<polymake::Integer> eqinteger = polymake::common::primitive(eqrational);
+      zw = PmMatrixInteger2GfZMatrix(&eqinteger);
+    }
+    else
+      zw = gfan::ZMatrix(0, ambientdim2);
+
+    // if (vertrational.cols()!=0)
+    // {
+    //   polymake::Matrix<polymake::Integer> vertinteger = polymake::common::primitive(vertrational);
+    //   zx = PmMatrixInteger2GfZMatrix(&vertinteger);
+    // }
+    // else
+    //   zx = gfan::ZMatrix(0, ambientdim2);
+    // if (linrational.cols()!=0)
+    //   {
+    //     polymake::Matrix<polymake::Integer> lininteger = polymake::common::primitive(linrational);
+    //     zy = PmMatrixInteger2GfZMatrix(&lininteger);
+    //   }
+    // else
+    //   zy = gfan::ZMatrix(0, ambientdim2);
+
+    // gfan::ZCone* zp = new gfan::ZCone(zv,zw,zx,zy,zz,3);
+    gfan::ZCone* zp = new gfan::ZCone(zv,zw,3);
+
+    return zp;
+  }
+  WerrorS("PmPolytope2ZPolytope: unexpected parameters");
+  return NULL;
+}
+
+gfan::ZFan* PmFan2ZFan (polymake::perl::Object* pf)
+{
+  if (pf->isa("PolyhedralFan"))
+  {
+    int d = (int) pf->give("FAN_AMBIENT_DIM");
+    gfan::ZFan* zf = new gfan::ZFan(d);
+
+    int n = pf->give("N_MAXIMAL_CONES");
+    for (int i=0; i<n; i++)
+      {
+        polymake::perl::Object pmcone=pf->CallPolymakeMethod("cone",i);
+        gfan::ZCone* zc=PmCone2ZCone(&pmcone);
+        zf->insert(*zc);
+      }
+    return zf;
+  }
+  WerrorS("PmFan2ZFan: unexpected parameters");
+  return NULL;
+}
+
+polymake::perl::Object* ZCone2PmCone (gfan::ZCone* zc)
+{
+  polymake::perl::Object* gc = new polymake::perl::Object("Cone<Rational>");
+
+  gfan::ZMatrix inequalities = zc->getInequalities();
+  gc->take("FACETS") << GfZMatrix2PmMatrixInteger(&inequalities);
+
+  gfan::ZMatrix equations = zc->getEquations();
+  gc->take("LINEAR_SPAN") << GfZMatrix2PmMatrixInteger(&equations);
+
+  // if(zc->areExtremeRaysKnown())
+  //   {
+  //     gfan::ZMatrix extremeRays = zc->extremeRays();
+  //     gc->take("RAYS") << GfZMatrix2PmMatrixInteger(&extremeRays);
+  //   }
+
+  // if(zc->areGeneratorsOfLinealitySpaceKnown())
+  //   {
+  //     gfan::ZMatrix lineality = zc->generatorsOfLinealitySpace();
+  //     gc->take("LINEALITY_SPACE") << GfZMatrix2PmMatrixInteger(&lineality);
+  //   }
+
+  return gc;
+}
+
+polymake::perl::Object* ZPolytope2PmPolytope (gfan::ZCone* zc)
+{
+  polymake::perl::Object* pp = new polymake::perl::Object("Polytope<Rational>");
+
+  gfan::ZMatrix inequalities = zc->getInequalities();
+  pp->take("FACETS") << GfZMatrix2PmMatrixInteger(&inequalities);
+
+  gfan::ZMatrix equations = zc->getEquations();
+  pp->take("LINEAR_SPAN") << GfZMatrix2PmMatrixInteger(&equations);
+
+  // if(zc->areExtremeRaysKnown())
+  //   {
+  //     gfan::ZMatrix vertices = zc->extremeRays();
+  //     pp->take("VERTICES") << GfZMatrix2PmMatrixInteger(&vertices);
+  //   }
+
+  return pp;
+}
+
+polymake::Matrix<polymake::Integer> raysOf(gfan::ZFan* zf)
+{
+  int d = zf->getAmbientDimension();
+  int n = zf->numberOfConesOfDimension(1,0,0);
+  gfan::ZMatrix zm(n,d);
+
+  for (int i=0; i<n; i++)
+    {
+      gfan::ZCone zc = zf->getCone(1,i,0,0);
+      gfan::ZMatrix ray = zc.extremeRays();
+      for (int j=0; j<d; j++)
+        {
+          zm[i][j]=ray[0][j];
+        }
+    }
+
+  return GfZMatrix2PmMatrixInteger(&zm);
+}
+
+int numberOfRaysOf(gfan::ZFan* zf)
+{
+  int n = zf->numberOfConesOfDimension(1,0,0);
+  return n;
+}
+
+int numberOfMaximalConesOf(gfan::ZFan* zf)
+{
+  int d = zf->getAmbientDimension();
+  int n = 0;
+
+  for (int i=0; i<=d; i++)
+    {
+      n = n + zf->numberOfConesOfDimension(i,0,1);
+    }
+
+  return n;
+}
+
+polymake::Array<polymake::Set<int> > conesOf(gfan::ZFan* zf)
+{
+  int r = numberOfMaximalConesOf(zf);
+
+  polymake::Matrix<polymake::Integer> pm=raysOf(zf);
+  polymake::Array<polymake::Set<int> > L(r);
+
+  int ii = 0;
+  for (int d=1; d<=zf->getAmbientDimension(); d++)
+    {
+      for (int i=0; i<zf->numberOfConesOfDimension(d,0,1); i++)
+        {
+          gfan::IntVector v = zf->getConeIndices(d,i,0,1);
+          polymake::Set<int> s;
+          for (int j=0; j<(int)v.size(); j++)
+            {
+              s = s+v[j];
+            }
+          L[ii] = s;
+          ii = ii + 1;
+        }
+    }
+  return L;
+}
+
+polymake::perl::Object* ZFan2PmFan (gfan::ZFan* zf)
+{
+  polymake::perl::Object* pf = new polymake::perl::Object("PolyhedralFan");
+
+  polymake::Matrix<polymake::Integer> zm = raysOf(zf);
+  pf->take("RAYS") << zm;  // using rays here instead of INPUT_RAYS prevents redundant computations
+
+  polymake::Array<polymake::Set<int> > ar = conesOf(zf);
+  pf->take("MAXIMAL_CONES") << ar;
+
+  return pf;
+}
+
+#endif
+
diff --git a/Singular/dyn_modules/polymake/polymake_documentation.cc b/Singular/dyn_modules/polymake/polymake_documentation.cc
new file mode 100644
index 0000000..d9c2843
--- /dev/null
+++ b/Singular/dyn_modules/polymake/polymake_documentation.cc
@@ -0,0 +1,227 @@
+#include <kernel/mod2.h>
+
+#ifdef HAVE_POLYMAKE
+
+/*
+#include <polymake_conversion.h>
+
+#include <Singular/dyn_modules/gfanlib/bbcone.h>
+#include <Singular/dyn_modules/gfanlib/bbfan.h>
+#include <Singular/dyn_modules/gfanlib/bbpolytope.h>
+
+#include <Singular/blackbox.h>
+#include <Singular/ipshell.h>
+#include <Singular/subexpr.h>
+
+#include <string>
+*/
+
+#include <Singular/ipid.h>
+
+
+void init_polymake_help()
+{
+
+  const char *polymake_banner =
+    "Welcome to polymake\nCopyright (c) 1997-2012\nEwgenij Gawrilow, Michael Joswig (TU Darmstadt)\nhttp://www.polymake.org\n";
+
+  PrintS(polymake_banner);
+
+  const char* polymake_help =
+    "SHARED LIBRARY: polymake.so  Interface to polymake (http://www.polymake.org)\nAUTHORS: Janko Boehm, boehm at mathematik.uni-kl.de\n         Yue Ren,     ren at mathematik.uni-kl.de\n\nOVERVIEW:\nPolymake is a tool to study the combinatorics \nand the geometry of convex polytopes and polyhedra. \nIt is also capable of dealing with simplicial complexes, \nmatroids, polyhedral fans, graphs, tropical objects.\nThe interface relies on the callable library functionality,\nby Ewgenij Gawrilow.\n [...]
+
+  module_help_main("polymake.so",polymake_help);
+
+
+  const char*isReflexive_help =
+    "USAGE:    isReflexive(polytope p)\nRETURN:   int, 1 if p is reflexive and 0 otherwise\nKEYWORDS: polytopes; polymake; reflexive\nEXAMPLE:  example isReflexive shows an example\nexample\n{ \"EXAMPLE: \";\nintmat M[4][4]=1,1,0,0, 1,0,1,0, 1,0,0,1, 1,-1,-1,-1;\npolytope p = polytopeViaVertices(M);\nPolymake::isReflexive(p);\nintmat N[4][4]=1,2,0,0, 1,0,2,0, 1,0,0,2, 1,-2,-2,-2;\nq = polytopeViaVertices(N);\nPolymake::isReflexive(q);\n}\n";
+
+ module_help_proc("polymake.so","isReflexive", isReflexive_help);
+
+  const char* isBounded_help =
+    "USAGE:    isBounded(polytope p)\nRETURN:   int, 1 if p is bounded, 0 otherwise.\nKEYWORDS: polytopes; polymake;\nEXAMPLE:  example isBounded shows an example\n";
+
+ module_help_proc("polymake.so","isBounded", isBounded_help);
+
+  const char* isGorenstein_help =
+    "USAGE:    isGorenstein(polytope p)\nRETURN:   int, 1 if p is gorenstein (i.e. reflexive after dilatation and translation), 0 otherwise.\nKEYWORDS: polytopes; polymake;\nEXAMPLE:  example isGorenstein shows an example\n";
+
+ module_help_proc("polymake.so","isGorenstein", isGorenstein_help);
+
+  const char* gorensteinIndex_help =
+    "USAGE:    gorensteinIndex(polytope p)\nRETURN:   int, n if p is reflexive after dilatation by n and translation, 0 otherwise.\nKEYWORDS: polytopes; polymake;\nEXAMPLE:  example gorensteinIndex shows an example\n";
+
+ module_help_proc("polymake.so","gorensteinIndex", gorensteinIndex_help);
+
+  const char* gorensteinVector_help =
+    "USAGE:    gorensteinVector(polytope p)\nRETURN:   intvec, v if p is reflexive after dilatation and translation by v, 0 otherwise.\nKEYWORDS: polytopes; polymake;\nEXAMPLE:  example gorensteinVector shows an example\n";
+
+ module_help_proc("polymake.so","gorensteinVector", gorensteinVector_help);
+
+  const char* isCanonical_help =
+    "USAGE:    isCanonical(polytope p)\nRETURN:   intvec, 1 if p has exactly one interior lattice point, 0 otherwise.\nKEYWORDS: polytopes; polymake;\nEXAMPLE:  example isCanonical shows an example\n";
+
+ module_help_proc("polymake.so","isCanonical", isCanonical_help);
+
+  const char* isTerminal_help =
+    "USAGE:    isLatticeEmpty(polytope p)\nRETURN:   int, 1 if p contains no lattice points other than the vertices, 0 otherwise.\nKEYWORDS: polytopes; polymake;\nEXAMPLE:  example isLatticeEmpty shows an example\n";
+
+ module_help_proc("polymake.so","isTerminal", isTerminal_help);
+
+  const char* latticeVolume_help =
+    "USAGE:    latticeVolume(polytope p)\nRETURN:   int, the normalized lattice volume of p, that is, (dim(P))! times the volume of P.\nKEYWORDS: polytopes; polymake;\nEXAMPLE:  example latticeVolume shows an example\n";
+
+ module_help_proc("polymake.so","latticeVolume", latticeVolume_help);
+
+  const char* latticeDegree_help =
+    "USAGE:    latticeDegree(polytope p)\nRETURN:   int, the lattice degree of p, i.e. degree of the Ehrhart polynomial of P.\nKEYWORDS: polytopes; polymake;\nEXAMPLE:  example latticeDegree shows an example\n";
+
+ module_help_proc("polymake.so","latticeDegree", latticeDegree_help);
+
+  const char* latticeCodegree_help =
+    "USAGE:    latticeCodegree(polytope p)\nRETURN:   int, getDimension(p)+1-latticeDegree(p), which is the smallest number k such that k*p has an interior latt\\nice point.\nKEYWORDS: polytopes; polymake;\nEXAMPLE:  example latticeCodegree shows an example\n";
+
+ module_help_proc("polymake.so","latticeCodegree", latticeCodegree_help);
+
+  const char* ehrhartPolynomialCoeff_help =
+    "USAGE:    ehrhartPolynomialCoeff(polytope p)\nRETURN:   intvec, coefficients of the Ehrhart polynomial of p.\nKEYWORDS: polytopes; polymake;\nEXAMPLE:  example ehrhartPolynomialCoeff shows an example\n";
+
+ module_help_proc("polymake.so","ehrhartPolynomialCoeff", ehrhartPolynomialCoeff_help);
+
+  const char* hStarVector_help =
+    "USAGE:    hStarVector(polytope p)\nRETURN:   intvec, h*-vector of p.\nKEYWORDS: polytopes; polymake;\nEXAMPLE:  example hStarVector shows an example\n";
+
+ module_help_proc("polymake.so","hStarVector", hStarVector_help);
+
+  const char* hVector_help =
+    "USAGE:    hVector(polytope p)\nRETURN:   intvec, h-vector of p.\nKEYWORDS: polytopes; polymake;\nEXAMPLE:  example hVector shows an example\n";
+
+ module_help_proc("polymake.so","hVector", hVector_help);
+
+  const char* fVector_help =
+    "USAGE:    fVector(polytope p)\nRETURN:   intvec, the f-vector of p.\nKEYWORDS: polytopes; polymake;\nEXAMPLE:  example fVector shows an example\n";
+
+ module_help_proc("polymake.so","fVector", fVector_help);
+
+  const char* isNormal_help =
+    "USAGE:    isNormal(polytope p)\nRETURN:   int, 1 if p is normal, i.e. the projective toric variety defined by p is projectively normal, 0 otherwise.\nKEYWORDS: polytopes; polymake;\nEXAMPLE:  example isNormal shows an example\n";
+
+ module_help_proc("polymake.so","isNormal", isNormal_help);
+
+  const char* facetWidths_help =
+    "USAGE:    facetWidths(polytope p)\nRETURN:   intvec, vector with the integral widths of p with respect to all facet normals.\nKEYWORDS: polytopes; polymake;\nEXAMPLE:  example facetWidths shows an example\n";
+
+ module_help_proc("polymake.so","facetWidths", facetWidths_help);
+
+  const char* facetWidth_help =
+    "USAGE:    facetWidth(polytope p)\nRETURN:   int, maximum of the integral widths of p over all facet normals.\nKEYWORDS: polytopes; polymake;\nEXAMPLE:  example facetWidth shows an example\n";
+
+ module_help_proc("polymake.so","facetWidth", facetWidth_help);
+
+  const char* facetVertexLatticeDistances_help =
+    "USAGE:    facetVertexLatticeDistances(polytope p)\nRETURN:   intmat, matrix of lattice distances between vertices (columns) and facets (rows).\nKEYWORDS: polytopes; polymake;\nEXAMPLE:  example facetVertexLatticeDistances shows an example\n";
+
+ module_help_proc("polymake.so","facetVertexLatticeDistances", facetVertexLatticeDistances_help);
+
+  const char* isCompressed_help =
+    "USAGE:    isCompressed(polytope p)\nRETURN:   int, 1 if facetWidth(p)=1, 0 otherwise.\nKEYWORDS: polytopes; polymake;\nEXAMPLE:  example isCompressed shows an example\n";
+
+ module_help_proc("polymake.so","isCompressed", isCompressed_help);
+
+  const char* isSmooth_help =
+    "USAGE:    isSmooth(polytope p)\n          isSmooth(cone c)\n          isSmooth(fan F)\nRETURN:   int, 1 if p, c, or F is smooth, 0 otherwise.\nKEYWORDS: polytopes; cones; fans; polymake;\nEXAMPLE:  example isSmooth shows an example\n";
+
+ module_help_proc("polymake.so","isSmooth", isSmooth_help);
+
+  const char* isVeryAmple_help =
+    "USAGE:    isVeryAmple(polytope p)\nRETURN:   int, 1 if p is very ample, 0 otherwise.\nKEYWORDS: polytopes; polymake;\nEXAMPLE:  example isVeryAmple shows an example\n";
+
+ module_help_proc("polymake.so","isVeryAmple", isVeryAmple_help);
+
+  const char* latticePoints_help =
+    "USAGE:    latticePoints(polytope p)\nRETURN:   intmat, matrix whose rows are the lattice points of p.\nKEYWORDS: polytopes; polymake;\nEXAMPLE:  example latticePoints shows an example\n";
+
+ module_help_proc("polymake.so","latticePoints", latticePoints_help);
+
+  const char* nLatticePoints_help =
+    "USAGE:    nLatticePoints(polytope p)\nRETURN:   int, number of lattice points of p.\nKEYWORDS: polytopes; polymake;\nEXAMPLE:  example nLatticePoints shows an example\n";
+
+ module_help_proc("polymake.so","nLatticePoints", nLatticePoints_help);
+
+  const char* interiorLatticePoints_help =
+    "USAGE:    interiorLatticePoints(polytope p)\nRETURN:   intmat, an matrix whose rows are the lattice points in the relative interior of p.\nKEYWORDS: polytopes; polymake;\nEXAMPLE:  example interiorLatticePoints shows an example\n";
+
+ module_help_proc("polymake.so","interiorLatticePoints", interiorLatticePoints_help);
+
+  const char* nInteriorLatticePoints_help =
+    "USAGE:    nInteriorLatticePoints(polytope p)\nRETURN:   int, number of lattice points in the relative interior of p.\nKEYWORDS: polytopes; polymake;\nEXAMPLE:  example nInteriorLatticePoints shows an example\n";
+
+ module_help_proc("polymake.so","nInteriorLatticePoints", nInteriorLatticePoints_help);
+
+  const char* boundaryLatticePoints_help =
+    "USAGE:    boundaryLatticePoints(polytope p)\nRETURN:   intmat, matrix whose rows are the lattice points in the relative boundary of p.\nKEYWORDS: polytopes; polymake;\nEXAMPLE:  example boundaryLatticePoints shows an example\n";
+
+ module_help_proc("polymake.so","boundaryLatticePoints", boundaryLatticePoints_help);
+
+  const char* nBoundaryLatticePoints_help =
+    "USAGE:    nBoundaryLatticePoints(polytope p)\nRETURN:   int, number of lattice points in the relative boundary of p.\nKEYWORDS: polytopes; polymake;\nEXAMPLE:  example nBoundaryLatticePoints shows an example\n";
+
+ module_help_proc("polymake.so","nBoundaryLatticePoints", nBoundaryLatticePoints_help);
+
+  const char* hilbertBasis_help =
+    "USAGE:    hilbertBasis(cone c)\nRETURN:   intmat, Hilbert basis of the semigroup of c.\nKEYWORDS: cones; polymake;\nEXAMPLE:  example hilbertBasis shows an example\n";
+
+ module_help_proc("polymake.so","hilbertBasis", hilbertBasis_help);
+
+  const char* nHilbertBasis_help =
+    "USAGE:    nHilbertBasis(cone c)\nRETURN:   int, size of the Hilbert basis of the semigroup of c.\nKEYWORDS: cones; polymake;\nEXAMPLE:  example nHilbertBasis shows an example\n";
+
+ module_help_proc("polymake.so","nHilbertBasis", nHilbertBasis_help);
+
+  const char* minkowskiSum_help =
+    "USAGE:    minkowskiSum(polytope p, polytope q)\nRETURN:   polytope, Minkowski sum of p and q.\nKEYWORDS: polytopes; polymake;\nEXAMPLE:  example minkowskiSum shows an example\n";
+
+ module_help_proc("polymake.so","minkowskiSum", minkowskiSum_help);
+
+  const char* minimalValue_help =
+    "USAGE:    minimalValue(polytope p, intvec v)\nRETURN:   int, the minimal value of the linear form v on p.\n          The first coordinate of v corresponds to a shift of the\n          minimal value since p is considered as a polytope\n          in the plane (first coordinate) = 1.\nKEYWORDS: polytopes; polymake;\nEXAMPLE:  example minimalValue shows an example\n";
+
+ module_help_proc("polymake.so","minimalValue", minimalValue_help);
+
+  const char* maximalValue_help =
+    "USAGE:    maximalValue(polytope p, intvec v)\nRETURN:   int, maximal value of the linear form v on p.\n          The first coordinate of v corresponds to a shift of the\n          maximal value since p is considered as a polytope\n          in the plane (first coordinate) = 1.\nKEYWORDS: polytopes; polymake;\nEXAMPLE:  example maximalValue shows an example\n";
+
+ module_help_proc("polymake.so","maximalValue", maximalValue_help);
+
+  const char* minimalFace_help =
+    "USAGE:    minimalFace(polytope p, intvec v)\nRETURN:   intmat, vertices of the face of p on which the linear form v\n          is minimal.\n          The first coordinate of v corresponds to a shift of the\n          minimal value since p is considered as a polytope\n          in the plane (first coordinate) = 1. Hence\n          the minimal face is independent of the first coordinate of v.\nKEYWORDS: polytopes; polymake;\nEXAMPLE:  example minimalFace shows an example\n";
+
+ module_help_proc("polymake.so","minimalFace", minimalFace_help);
+
+  const char* maximalFace_help =
+    "USAGE:    maximalFace(polytope p, intvec v)\nRETURN:   intmat, vertices of the face of p on which the linear form v\n          is maximal.\n          The first coordinate of v corresponds to a shift of the\n          maximal value since p is considered as a polytope\n          in the plane (first coordinate) = 1. Hence\n          the maximal face is independent of the first coordinate of v.\nKEYWORDS: polytopes; polymake;\nEXAMPLE:  example maximalFace shows an example\n";
+
+ module_help_proc("polymake.so","maximalFace", maximalFace_help);
+
+  const char* visual_help =
+    "USAGE:    visual(polytope p)\n          visual(fan F)\nRETURN:   none, draws the polytope p or fan F using jreality.\nKEYWORDS: polytopes; polymake; visualization;\nEXAMPLE:  example visual shows an example\n";
+
+ module_help_proc("polymake.so","visual", visual_help);
+
+  const char* normalFan_help =
+    "USAGE:    normalFan(polytope p)\nRETURN:   fan,\nKEYWORDS: polytopes; polymake; visualization;\nEXAMPLE:  example visual shows an example\n";
+
+    module_help_proc("polymake.so","normalFan", normalFan_help);
+
+  const char* vertexAdjacencyGraph_help =
+    "USAGE:    vertexAdjacencyGraph(polytope p)\nRETURN:   list,\nKEYWORDS: polytopes; polymake;\nEXAMPLE:  example visual shows an example\n";
+
+    module_help_proc("polymake.so","vertexAdjacencyGraph", normalFan_help);
+
+  const char* vertexEdgeGraph_help =
+    "USAGE:    vertexEdgeGraph(polytope p)\nRETURN:   list,\nKEYWORDS: polytopes; polymake;\nEXAMPLE:  example visual shows an example\n";
+
+    module_help_proc("polymake.so","vertexEdgeGraph", normalFan_help);
+
+}
+#endif
diff --git a/Singular/dyn_modules/polymake/polymake_wrapper.cc b/Singular/dyn_modules/polymake/polymake_wrapper.cc
new file mode 100644
index 0000000..399b5fa
--- /dev/null
+++ b/Singular/dyn_modules/polymake/polymake_wrapper.cc
@@ -0,0 +1,1815 @@
+#include <kernel/mod2.h>
+
+#ifdef HAVE_POLYMAKE
+
+#include <Singular/dyn_modules/gfanlib/bbcone.h>
+#include <Singular/dyn_modules/gfanlib/bbfan.h>
+#include <Singular/dyn_modules/gfanlib/bbpolytope.h>
+
+#include <Singular/blackbox.h>
+#include <Singular/ipshell.h>
+#include <Singular/subexpr.h>
+#include <Singular/mod_lib.h>
+
+#include <polymake_conversion.h>
+#include <polymake_documentation.h>
+#include <polymake/Graph.h>
+
+polymake::Main* init_polymake=NULL;
+
+static BOOLEAN bbpolytope_Op2(int op, leftv res, leftv i1, leftv i2)
+{
+  gfan::ZCone* zp = (gfan::ZCone*) i1->Data();
+  switch(op)
+  {
+    case '+':
+    {
+      if (i2->Typ()==polytopeID || i2->Typ()==coneID)
+      {
+        gfan::ZCone* zq = (gfan::ZCone*) i2->Data();
+        gfan::ZCone* ms;
+        try
+        {
+          polymake::perl::Object* pp = ZPolytope2PmPolytope(zp);
+          polymake::perl::Object* pq = ZPolytope2PmPolytope(zq);
+          polymake::perl::Object pms;
+          CallPolymakeFunction("minkowski_sum", *pp, *pq) >> pms;
+          ms = PmPolytope2ZPolytope(&pms);
+          delete pp;
+          delete pq;
+        }
+        catch (const std::exception& ex)
+        {
+          WerrorS("ERROR: "); WerrorS(ex.what()); WerrorS("\n");
+          return TRUE;
+        }
+        res->rtyp = polytopeID;
+        res->data = (void*) ms;
+        return FALSE;
+      }
+      return blackboxDefaultOp2(op,res,i1,i2);
+    }
+    case '*':
+    {
+      if (i2->Typ()==INT_CMD)
+      {
+        int s = (int)(long) i2->Data();
+        gfan::ZMatrix zm = zp->extremeRays();
+        for (int i=0; i<zm.getHeight(); i++)
+          for (int j=1; j<zm.getWidth(); j++)
+            zm[i][j] *= s;
+        gfan::ZCone* zs = new gfan::ZCone();
+        *zs = gfan::ZCone::givenByRays(zm,gfan::ZMatrix(0, zm.getWidth()));
+        res->rtyp = polytopeID;
+        res->data = (void*) zs;
+        return FALSE;
+      }
+      return blackboxDefaultOp2(op,res,i1,i2);
+    }
+    case '&':
+    {
+      if (i2->Typ()==polytopeID)
+      {
+        gfan::ZCone* zq = (gfan::ZCone*) i2->Data();
+        int d1 = zp->ambientDimension();
+        int d2 = zq->ambientDimension();
+        if (d1 != d2)
+        {
+          Werror("mismatching ambient dimensions");
+          return TRUE;
+        }
+        gfan::ZCone* zs = new gfan::ZCone();
+        *zs = gfan::intersection(*zp, *zq);
+        zs->canonicalize();
+        res->rtyp = polytopeID;
+        res->data = (void*) zs;
+        return FALSE;
+      }
+      return blackboxDefaultOp2(op,res,i1,i2);
+    }
+    case '|':
+    {
+      if(i2->Typ()==polytopeID)
+      {
+        gfan::ZCone* zq = (gfan::ZCone*) i2->Data();
+        int d1 = zp->ambientDimension();
+        int d2 = zq->ambientDimension();
+        if (d1 != d2)
+        {
+          Werror("mismatching ambient dimensions");
+          return TRUE;
+        }
+        gfan::ZMatrix rays = zp->extremeRays();
+        rays.append(zq->extremeRays());
+        gfan::ZMatrix lineality = zp->generatorsOfLinealitySpace();
+        lineality.append(zq->generatorsOfLinealitySpace());
+        gfan::ZCone* zs = new gfan::ZCone();
+        *zs = gfan::ZCone::givenByRays(rays,lineality);
+        zs->canonicalize();
+        res->rtyp = polytopeID;
+        res->data = (void*) zs;
+        return FALSE;
+      }
+    return blackboxDefaultOp2(op,res,i1,i2);
+    }
+    case EQUAL_EQUAL:
+    {
+      if(i2->Typ()==polytopeID)
+      {
+        gfan::ZCone* zq = (gfan::ZCone*) i2->Data();
+        zp->canonicalize();
+        zq->canonicalize();
+        bool b = !((*zp)!=(*zq));
+        res->rtyp = INT_CMD;
+        res->data = (char*) (long) b;
+        return FALSE;
+      }
+      return blackboxDefaultOp2(op,res,i1,i2);
+    }
+    default:
+      return blackboxDefaultOp2(op,res,i1,i2);
+  }
+  return blackboxDefaultOp2(op,res,i1,i2);
+}
+
+
+/* Functions for using Polymake in Singular */
+
+// BOOLEAN cube(leftv res, leftv args)
+// {
+//   leftv u = args;
+//   if ((u !=NULL) && (u->Typ() == INT_CMD))
+//     {
+//       int ambientDim = (int)(long)u->Data();
+//       if (ambientDim < 0)
+// 	{
+//           Werror("expected non-negative ambient dim but got %d", ambientDim);
+// 	  return TRUE;
+// 	}
+//       gfan::ZMatrix zm(ambientDim*2,ambientDim+1);
+//       int j=1;
+//       for (int i=0; i<ambientDim*2; i=i+2)
+//         {
+//           zm[i][0] = 1;
+//           zm[i][j] = 1;
+//           zm[i+1][0] = 1;
+//           zm[i+1][j] = -1;
+//           j = j+1;
+//         }
+//       gfan::ZCone* zc = new gfan::ZCone(zm, gfan::ZMatrix(0, zm.getWidth()));
+//       res->rtyp = coneID;
+//       res->data = (char *)zc;
+//       return FALSE;
+//     }
+//   WerrorS("cube: unexpected parameters");
+//   return TRUE;
+// }
+
+// BOOLEAN cross(leftv res, leftv args)
+// {
+//   leftv u = args;
+//   if ((u !=NULL) && (u->Typ() == INT_CMD))
+//     {
+//       int ambientDim = (int)(long)u->Data();
+//       if (ambientDim < 0)
+// 	{
+//           Werror("expected non-negative ambient dim but got %d", ambientDim);
+// 	  return TRUE;
+// 	}
+//       gfan::ZMatrix zm(ambientDim*2,ambientDim+1);
+//       int j=1;
+//       for (int i=0; i<ambientDim*2; i=i+2)
+//         {
+//           zm[i][0] = 1;
+//           zm[i][j] = 1;
+//           zm[i+1][0] = 1;
+//           zm[i+1][j] = -1;
+//           j = j+1;
+//         }
+//       gfan::ZCone* zc = new gfan::ZCone();
+//       *zc = gfan::ZCone::givenByRays(zm, gfan::ZMatrix(0, zm.getWidth()));
+//       res->rtyp = coneID;
+//       res->data = (char *)zc;
+//       return FALSE;
+//     }
+//   WerrorS("cross: unexpected parameters");
+//   return TRUE;
+// }
+
+
+BOOLEAN PMisLatticePolytope(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && (u->Typ() == polytopeID))
+  {
+    gfan::ZCone* zp = (gfan::ZCone*)u->Data();
+    bool b;
+    try
+    {
+      polymake::perl::Object* p = ZPolytope2PmPolytope(zp);
+      b = p->give("Lattice");
+      delete p;
+    }
+    catch (const std::exception& ex)
+    {
+      WerrorS("ERROR: "); WerrorS(ex.what()); WerrorS("\n");
+      return TRUE;
+    }
+    res->rtyp = INT_CMD;
+    res->data = (char*) (long) b;
+    return FALSE;
+  }
+  WerrorS("isLatticePolytope: unexpected parameters");
+  return TRUE;
+}
+
+
+BOOLEAN PMisBounded(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && (u->Typ() == polytopeID))
+  {
+    gfan::ZCone* zp = (gfan::ZCone*)u->Data();
+    bool b;
+    try
+    {
+      polymake::perl::Object* p = ZPolytope2PmPolytope(zp);
+      b = p->give("BOUNDED");
+      delete p;
+    }
+    catch (const std::exception& ex)
+    {
+      WerrorS("ERROR: "); WerrorS(ex.what()); WerrorS("\n");
+      return TRUE;
+    }
+    res->rtyp = INT_CMD;
+    res->data = (char*) (long) b;
+    return FALSE;
+  }
+  WerrorS("isBounded: unexpected parameters");
+  return TRUE;
+}
+
+
+BOOLEAN PMisReflexive(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && (u->Typ() == polytopeID))
+  {
+    gfan::ZCone* zp = (gfan::ZCone*)u->Data();
+    bool b;
+    try
+    {
+      polymake::perl::Object* p = ZPolytope2PmPolytope(zp);
+      b = p->give("REFLEXIVE");
+      delete p;
+    }
+    catch (const std::exception& ex)
+    {
+      WerrorS("ERROR: "); WerrorS(ex.what()); WerrorS("\n");
+      return TRUE;
+    }
+    res->rtyp = INT_CMD;
+    res->data = (char*) (long) b;
+    return FALSE;
+  }
+  WerrorS("isReflexive: unexpected parameters");
+  return TRUE;
+}
+
+
+BOOLEAN PMisGorenstein(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && (u->Typ() == polytopeID))
+  {
+    gfan::ZCone* zp = (gfan::ZCone*)u->Data();
+    bool b;
+    try
+    {
+      polymake::perl::Object* p = ZPolytope2PmPolytope(zp);
+      b = p->give("GORENSTEIN");
+      delete p;
+    }
+    catch (const std::exception& ex)
+    {
+      WerrorS("ERROR: "); WerrorS(ex.what()); WerrorS("\n");
+      return TRUE;
+    }
+    res->rtyp = INT_CMD;
+    res->data = (char*) (long) b;
+    return FALSE;
+  }
+  WerrorS("isGorenstein: unexpected parameters");
+  return TRUE;
+}
+
+
+BOOLEAN PMgorensteinIndex(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && (u->Typ() == polytopeID))
+  {
+    gfan::ZCone* zp = (gfan::ZCone*)u->Data();
+    int gi;
+    bool ok = true;
+    try
+    {
+      polymake::perl::Object* p = ZPolytope2PmPolytope(zp);
+      bool b = p->give("GORENSTEIN");
+      if (b)
+      {
+        polymake::Integer pgi = p->give("GORENSTEIN_INDEX");
+        gi = PmInteger2Int(pgi,ok);
+        delete p;
+      }
+      else
+      {
+        delete p;
+        WerrorS("gorensteinIndex: input polytope not gorenstein");
+        return TRUE;
+      }
+    }
+    catch (const std::exception& ex)
+    {
+      WerrorS("ERROR: "); WerrorS(ex.what()); WerrorS("\n");
+      return TRUE;
+    }
+    if (!ok)
+    {
+      WerrorS("overflow while converting polymake::Integer to int");
+      return TRUE;
+    }
+    res->rtyp = INT_CMD;
+    res->data = (char*) (long) gi;
+    return FALSE;
+  }
+  WerrorS("gorensteinIndex: unexpected parameters");
+  return TRUE;
+}
+
+
+BOOLEAN PMgorensteinVector(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && (u->Typ() == polytopeID))
+  {
+    gfan::ZCone* zp = (gfan::ZCone*)u->Data();
+    intvec* gv;
+    bool ok = true;
+    try
+    {
+      polymake::perl::Object* p = ZPolytope2PmPolytope(zp);
+      bool b = p->give("GORENSTEIN");
+      if (b)
+      {
+        polymake::Vector<polymake::Integer> pgv = p->give("GORENSTEIN_VECTOR");
+        gv = PmVectorInteger2Intvec(&pgv,ok);
+        delete p;
+      }
+      else
+      {
+        delete p;
+        WerrorS("gorensteinVector: input polytope not gorenstein");
+        return TRUE;
+      }
+    }
+    catch (const std::exception& ex)
+    {
+      WerrorS("ERROR: "); WerrorS(ex.what()); WerrorS("\n");
+      return TRUE;
+    }
+    if (!ok)
+    {
+      WerrorS("gorensteinVector: overflow in PmVectorInteger2Intvec");
+      return TRUE;
+    }
+    res->rtyp = INTVEC_CMD;
+    res->data = (char*) gv;
+    return FALSE;
+  }
+  WerrorS("gorensteinVector: unexpected parameters");
+  return TRUE;
+}
+
+
+BOOLEAN PMisCanonical(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && (u->Typ() == polytopeID))
+  {
+    gfan::ZCone* zp = (gfan::ZCone*)u->Data();
+    bool b;
+    try
+    {
+      polymake::perl::Object* p = ZPolytope2PmPolytope(zp);
+      b = p->give("CANONICAL");
+      delete p;
+    }
+    catch (const std::exception& ex)
+    {
+      WerrorS("ERROR: "); WerrorS(ex.what()); WerrorS("\n");
+      return TRUE;
+    }
+    res->rtyp = INT_CMD;
+    res->data = (char*) (long) b;
+    return FALSE;
+  }
+  WerrorS("isCanonical: unexpected parameters");
+  return TRUE;
+}
+
+
+BOOLEAN PMisTerminal(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && (u->Typ() == polytopeID))
+  {
+    gfan::ZCone* zp = (gfan::ZCone*)u->Data();
+    bool b;
+    try
+    {
+      polymake::perl::Object* p = ZPolytope2PmPolytope(zp);
+      b = p->give("TERMINAL");
+      delete p;
+    }
+    catch (const std::exception& ex)
+    {
+      WerrorS("ERROR: "); WerrorS(ex.what()); WerrorS("\n");
+      return TRUE;
+    }
+    res->rtyp = INT_CMD;
+    res->data = (char*) (long) b;
+    return FALSE;
+  }
+  WerrorS("isTerminal: unexpected parameters");
+  return TRUE;
+}
+
+
+BOOLEAN PMisLatticeEmpty(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && (u->Typ() == polytopeID))
+  {
+    gfan::ZCone* zp = (gfan::ZCone*)u->Data();
+    bool b;
+    try
+    {
+      polymake::perl::Object* p = ZPolytope2PmPolytope(zp);
+      b = p->give("LATTICE_EMPTY");
+      delete p;
+    }
+    catch (const std::exception& ex)
+    {
+      WerrorS("ERROR: "); WerrorS(ex.what()); WerrorS("\n");
+      return TRUE;
+    }
+    res->rtyp = INT_CMD;
+    res->data = (char*) (long) b;
+    return FALSE;
+  }
+  WerrorS("isLatticeEmpty: unexpected parameters");
+  return TRUE;
+}
+
+
+BOOLEAN PMlatticeVolume(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && (u->Typ() == polytopeID))
+  {
+    gfan::ZCone* zp = (gfan::ZCone*)u->Data();
+    int lv;
+    bool ok = true;
+    try
+    {
+      polymake::perl::Object* p = ZPolytope2PmPolytope(zp);
+      polymake::Integer plv = p->give("LATTICE_VOLUME");
+      delete p;
+      lv = PmInteger2Int(plv,ok);
+    }
+    catch (const std::exception& ex)
+    {
+      WerrorS("ERROR: "); WerrorS(ex.what()); WerrorS("\n");
+      return TRUE;
+    }
+    if (!ok)
+    {
+      WerrorS("overflow while converting polymake::Integer to int");
+      return TRUE;
+    }
+    res->rtyp = INT_CMD;
+    res->data = (char*) (long) lv;
+    return FALSE;
+  }
+  WerrorS("latticeVolume: unexpected parameters");
+  return TRUE;
+}
+
+
+BOOLEAN PMlatticeDegree(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && (u->Typ() == polytopeID))
+  {
+    gfan::ZCone* zp = (gfan::ZCone*)u->Data();
+    int ld;
+    bool ok = true;
+    try
+    {
+      polymake::perl::Object* p = ZPolytope2PmPolytope(zp);
+      polymake::Integer pld = p->give("LATTICE_DEGREE");
+      delete p;
+      ld = PmInteger2Int(pld,ok);
+    }
+    catch (const std::exception& ex)
+    {
+      WerrorS("ERROR: "); WerrorS(ex.what()); WerrorS("\n");
+      return TRUE;
+    }
+    if (!ok)
+    {
+      WerrorS("overflow while converting polymake::Integer to int");
+      return TRUE;
+    }
+    res->rtyp = INT_CMD;
+    res->data = (char*) (long) ld;
+    return FALSE;
+  }
+  WerrorS("latticeDegree: unexpected parameters");
+  return TRUE;
+}
+
+
+BOOLEAN PMlatticeCodegree(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && (u->Typ() == polytopeID))
+  {
+    gfan::ZCone* zp = (gfan::ZCone*)u->Data();
+    int lc;
+    bool ok = true;
+    try
+    {
+      polymake::perl::Object* p = ZPolytope2PmPolytope(zp);
+      polymake::Integer plc = p->give("LATTICE_CODEGREE");
+      delete p;
+      lc = PmInteger2Int(plc,ok);
+    }
+    catch (const std::exception& ex)
+    {
+      WerrorS("ERROR: "); WerrorS(ex.what()); WerrorS("\n");
+      return TRUE;
+    }
+    if (!ok)
+    {
+      WerrorS("overflow while converting polymake::Integer to int");
+      return TRUE;
+    }
+    res->rtyp = INT_CMD;
+    res->data = (char*) (long) lc;
+    return FALSE;
+  }
+  WerrorS("latticeCodegree: unexpected parameters");
+  return TRUE;
+}
+
+
+BOOLEAN PMehrhartPolynomialCoeff(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && (u->Typ() == polytopeID))
+  {
+    gfan::ZCone* zp = (gfan::ZCone*)u->Data();
+    intvec* ec;
+    bool ok = true;
+    try
+    {
+      polymake::perl::Object* p = ZPolytope2PmPolytope(zp);
+      polymake::Vector<polymake::Integer> pec = p->give("EHRHART_POLYNOMIAL_COEFF");
+      delete p;
+      ec = PmVectorInteger2Intvec(&pec,ok);
+    }
+    catch (const std::exception& ex)
+    {
+      WerrorS("ERROR: "); WerrorS(ex.what()); WerrorS("\n");
+      return TRUE;
+    }
+    if (!ok)
+    {
+      WerrorS("ehrhartPolynomialCoeff: overflow in PmVectorInteger2Intvec");
+      return TRUE;
+    }
+    res->rtyp = INTVEC_CMD;
+    res->data = (char*) ec;
+    return FALSE;
+  }
+  WerrorS("ehrhartPolynomialCoeff: unexpected parameters");
+  return TRUE;
+}
+
+
+BOOLEAN PMfVector(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && (u->Typ() == polytopeID))
+  {
+    gfan::ZCone* zp = (gfan::ZCone*)u->Data();
+    intvec* hv;
+    bool ok = true;
+    try
+    {
+      polymake::perl::Object* p = ZPolytope2PmPolytope(zp);
+      polymake::Vector<polymake::Integer> phv = p->give("F_VECTOR");
+      delete p;
+      hv = PmVectorInteger2Intvec(&phv,ok);
+    }
+    catch (const std::exception& ex)
+    {
+      WerrorS("ERROR: "); WerrorS(ex.what()); WerrorS("\n");
+      return TRUE;
+    }
+    if (!ok)
+    {
+      WerrorS("fVector: overflow in PmVectorInteger2Intvec");
+      return TRUE;
+    }
+    res->rtyp = INTVEC_CMD;
+    res->data = (char*) hv;
+    return FALSE;
+  }
+  WerrorS("fVector: unexpected parameters");
+  return TRUE;
+}
+
+
+BOOLEAN PMhVector(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && (u->Typ() == polytopeID))
+  {
+    gfan::ZCone* zp = (gfan::ZCone*)u->Data();
+    intvec* hv;
+    bool ok = true;
+    try
+    {
+      polymake::perl::Object* p = ZPolytope2PmPolytope(zp);
+      polymake::Vector<polymake::Integer> phv = p->give("H_VECTOR");
+      delete p;
+      hv = PmVectorInteger2Intvec(&phv,ok);
+    }
+    catch (const std::exception& ex)
+    {
+      WerrorS("ERROR: "); WerrorS(ex.what()); WerrorS("\n");
+      return TRUE;
+    }
+    if (!ok)
+    {
+      WerrorS("hVector: overflow in PmVectorInteger2Intvec");
+      return TRUE;
+    }
+    res->rtyp = INTVEC_CMD;
+    res->data = (char*) hv;
+    return FALSE;
+  }
+  WerrorS("hVector: unexpected parameters");
+  return TRUE;
+}
+
+
+BOOLEAN PMhStarVector(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && (u->Typ() == polytopeID))
+  {
+    gfan::ZCone* zp = (gfan::ZCone*)u->Data();
+    intvec* hv;
+    bool ok = true;
+    try
+    {
+      polymake::perl::Object* p = ZPolytope2PmPolytope(zp);
+      polymake::Vector<polymake::Integer> phv = p->give("H_STAR_VECTOR");
+      delete p;
+      hv = PmVectorInteger2Intvec(&phv,ok);
+    }
+    catch (const std::exception& ex)
+    {
+      WerrorS("ERROR: "); WerrorS(ex.what()); WerrorS("\n");
+      return TRUE;
+    }
+    if (!ok)
+    {
+      WerrorS("hStarVector: overflow in PmVectorInteger2Intvec");
+      return TRUE;
+    }
+    res->rtyp = INTVEC_CMD;
+    res->data = (char*) hv;
+    return FALSE;
+  }
+  WerrorS("hStarVector: unexpected parameters");
+  return TRUE;
+}
+
+
+BOOLEAN PMisNormal(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && (u->Typ() == polytopeID))
+  {
+    gfan::ZCone* zp = (gfan::ZCone*)u->Data();
+    bool b;
+    try
+    {
+      polymake::perl::Object* p = ZPolytope2PmPolytope(zp);
+      b = p->give("NORMAL");
+      delete p;
+    }
+    catch (const std::exception& ex)
+    {
+      WerrorS("ERROR: "); WerrorS(ex.what()); WerrorS("\n");
+      return TRUE;
+    }
+    res->rtyp = INT_CMD;
+    res->data = (char*) (long) b;
+    return FALSE;
+  }
+  WerrorS("isNormal: unexpected parameters");
+  return TRUE;
+}
+
+
+BOOLEAN PMfacetWidths(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && (u->Typ() == polytopeID))
+  {
+    gfan::ZCone* zp = (gfan::ZCone*)u->Data();
+    intvec* fw;
+    bool ok = true;
+    try
+    {
+      polymake::perl::Object* p = ZPolytope2PmPolytope(zp);
+      polymake::Vector<polymake::Integer> pfw = p->give("FACET_WIDTHS");
+      delete p;
+      fw = PmVectorInteger2Intvec(&pfw,ok);
+    }
+    catch (const std::exception& ex)
+    {
+      WerrorS("ERROR: "); WerrorS(ex.what()); WerrorS("\n");
+      return TRUE;
+    }
+    if (!ok)
+    {
+      WerrorS("facetWidths: overflow in PmVectorInteger2Intvec");
+      return TRUE;
+    }
+    res->rtyp = INTVEC_CMD;
+    res->data = (char*) fw;
+    return FALSE;
+  }
+  WerrorS("facetWidths: unexpected parameters");
+  return TRUE;
+}
+
+
+BOOLEAN PMfacetWidth(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && (u->Typ() == polytopeID))
+  {
+    gfan::ZCone* zp = (gfan::ZCone*)u->Data();
+    int fw;
+    bool ok = true;
+    try
+    {
+      polymake::perl::Object* p = ZPolytope2PmPolytope(zp);
+      polymake::Integer pfw = p->give("FACET_WIDTH");
+      delete p;
+      fw = PmInteger2Int(pfw,ok);
+    }
+    catch (const std::exception& ex)
+    {
+      WerrorS("ERROR: "); WerrorS(ex.what()); WerrorS("\n");
+      return TRUE;
+    }
+    if (!ok)
+    {
+      WerrorS("overflow while converting polymake::Integer to int");
+      return TRUE;
+    }
+    res->rtyp = INT_CMD;
+    res->data = (char*) (long) fw;
+    return FALSE;
+  }
+  WerrorS("facetWidth: unexpected parameters");
+  return TRUE;
+}
+
+
+BOOLEAN PMfacetVertexLatticeDistances(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && (u->Typ() == polytopeID))
+  {
+    gfan::ZCone* zp = (gfan::ZCone*)u->Data();
+    intvec* ld;
+    bool ok=true;
+    try
+    {
+      polymake::perl::Object* p = ZPolytope2PmPolytope(zp);
+      polymake::Matrix<polymake::Integer> pld = p->give("FACET_VERTEX_LATTICE_DISTANCES");
+      delete p;
+      ld = PmMatrixInteger2Intvec(&pld,ok);
+    }
+    catch (const std::exception& ex)
+    {
+      WerrorS("ERROR: "); WerrorS(ex.what()); WerrorS("\n");
+      return TRUE;
+    }
+    if (!ok)
+    {
+      WerrorS("overflow while converting polymake::Integer to int");
+      return TRUE;
+    }
+    res->rtyp = INTMAT_CMD;
+    res->data = (char*) ld;
+    return FALSE;
+  }
+  WerrorS("facetVertexLatticeDistances: unexpected parameters");
+  return TRUE;
+}
+
+
+BOOLEAN PMisCompressed(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && (u->Typ() == polytopeID))
+  {
+    gfan::ZCone* zp = (gfan::ZCone*)u->Data();
+    bool b;
+    try
+    {
+      polymake::perl::Object* p = ZPolytope2PmPolytope(zp);
+      b = p->give("COMPRESSED");
+      delete p;
+    }
+    catch (const std::exception& ex)
+    {
+      WerrorS("ERROR: "); WerrorS(ex.what()); WerrorS("\n");
+      return TRUE;
+    }
+    res->rtyp = INT_CMD;
+    res->data = (char*) (long) b;
+    return FALSE;
+  }
+  WerrorS("isCompressed: unexpected parameters");
+  return TRUE;
+}
+
+
+BOOLEAN PMisSmooth(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && (u->Typ() == coneID))
+  {
+    gfan::ZCone* zc = (gfan::ZCone*)u->Data();
+    bool b;
+    try
+    {
+      polymake::perl::Object* p = ZCone2PmCone(zc);
+      b = p->give("SMOOTH_CONE");
+      delete p;
+    }
+    catch (const std::exception& ex)
+    {
+      WerrorS("ERROR: "); WerrorS(ex.what()); WerrorS("\n");
+      return TRUE;
+    }
+    res->rtyp = INT_CMD;
+    res->data = (char*) (long) b;
+    return FALSE;
+  }
+  if ((u != NULL) && (u->Typ() == polytopeID))
+  {
+    gfan::ZCone* zp = (gfan::ZCone*)u->Data();
+    bool b;
+    try
+    {
+      polymake::perl::Object* p = ZPolytope2PmPolytope(zp);
+      b = p->give("SMOOTH");
+      delete p;
+    }
+    catch (const std::exception& ex)
+    {
+      WerrorS("ERROR: "); WerrorS(ex.what()); WerrorS("\n");
+      return TRUE;
+    }
+    res->rtyp = INT_CMD;
+    res->data = (char*) (long) b;
+    return FALSE;
+  }
+  if ((u != NULL) && (u->Typ() == fanID))
+  {
+    gfan::ZFan* zf = (gfan::ZFan*)u->Data();
+    bool b;
+    try
+    {
+      polymake::perl::Object* p = ZFan2PmFan(zf);
+      b = p->give("SMOOTH_FAN");
+      delete p;
+    }
+    catch (const std::exception& ex)
+    {
+      WerrorS("ERROR: "); WerrorS(ex.what()); WerrorS("\n");
+      return TRUE;
+    }
+    res->rtyp = INT_CMD;
+    res->data = (char*) (long) b;
+    return FALSE;
+  }
+  WerrorS("isSmooth: unexpected parameters");
+  return TRUE;
+}
+
+
+BOOLEAN PMisVeryAmple(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && (u->Typ() == polytopeID))
+  {
+    gfan::ZCone* zp = (gfan::ZCone*)u->Data();
+    bool b;
+    try
+    {
+      polymake::perl::Object* p = ZPolytope2PmPolytope(zp);
+      b = p->give("VERY_AMPLE");
+      delete p;
+    }
+    catch (const std::exception& ex)
+    {
+      WerrorS("ERROR: "); WerrorS(ex.what()); WerrorS("\n");
+      return TRUE;
+    }
+    res->rtyp = INT_CMD;
+    res->data = (char*) (long) b;
+    return FALSE;
+  }
+  WerrorS("isVeryAmple: unexpected parameters");
+  return TRUE;
+}
+
+
+BOOLEAN PMlatticePoints(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && (u->Typ() == polytopeID))
+  {
+    gfan::ZCone* zp = (gfan::ZCone*)u->Data();
+    intvec* iv;
+    bool ok = true;
+    try
+    {
+      polymake::perl::Object* p = ZPolytope2PmPolytope(zp);
+      polymake::Matrix<polymake::Integer> lp = p->give("LATTICE_POINTS");
+      delete p;
+      iv = PmMatrixInteger2Intvec(&lp,ok);
+    }
+    catch (const std::exception& ex)
+    {
+      WerrorS("ERROR: "); WerrorS(ex.what()); WerrorS("\n");
+      return TRUE;
+    }
+    if (!ok)
+    {
+      WerrorS("overflow while converting polymake::Integer to int");
+      return TRUE;
+    }
+    res->rtyp = INTMAT_CMD;
+    res->data = (char*) iv;
+    return FALSE;
+  }
+  WerrorS("LatticePoints: unexpected parameters");
+  return TRUE;
+}
+
+
+BOOLEAN PMnLatticePoints(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && (u->Typ() == polytopeID))
+  {
+    gfan::ZCone* zp = (gfan::ZCone*)u->Data();
+    int n;
+    bool ok = true;
+    try
+    {
+      polymake::perl::Object* p = ZPolytope2PmPolytope(zp);
+      polymake::Integer nlp = p->give("N_LATTICE_POINTS");
+      delete p;
+      n = PmInteger2Int(nlp,ok);
+    }
+    catch (const std::exception& ex)
+    {
+      WerrorS("ERROR: "); WerrorS(ex.what()); WerrorS("\n");
+      return TRUE;
+    }
+    if (!ok)
+    {
+      WerrorS("overflow while converting polymake::Integer to int");
+      return TRUE;
+    }
+    res->rtyp = INT_CMD;
+    res->data = (char*) (long) n;
+    return FALSE;
+  }
+  WerrorS("nLatticePoints: unexpected parameters");
+  return TRUE;
+}
+
+
+BOOLEAN PMinteriorLatticePoints(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && (u->Typ() == polytopeID))
+  {
+    gfan::ZCone* zp = (gfan::ZCone*)u->Data();
+    intvec* iv;
+    bool ok = true;
+    try
+    {
+      polymake::perl::Object* p = ZPolytope2PmPolytope(zp);
+      polymake::Matrix<polymake::Integer> lp = p->give("INTERIOR_LATTICE_POINTS");
+      delete p;
+      iv = PmMatrixInteger2Intvec(&lp,ok);
+    }
+    catch (const std::exception& ex)
+    {
+      WerrorS("ERROR: "); WerrorS(ex.what()); WerrorS("\n");
+      return TRUE;
+    }
+    if (!ok)
+    {
+      WerrorS("overflow while converting polymake::Integer to int");
+      return TRUE;
+    }
+    res->rtyp = INTMAT_CMD;
+    res->data = (char*) iv;
+    return FALSE;
+  }
+  WerrorS("interiorLatticePoints: unexpected parameters");
+  return TRUE;
+}
+
+
+BOOLEAN PMnInteriorLatticePoints(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && (u->Typ() == polytopeID))
+  {
+    gfan::ZCone* zp = (gfan::ZCone*)u->Data();
+    int n;
+    bool ok = true;
+    try
+    {
+      polymake::perl::Object* p = ZPolytope2PmPolytope(zp);
+      polymake::Integer nlp = p->give("N_INTERIOR_LATTICE_POINTS");
+      delete p;
+      n = PmInteger2Int(nlp,ok);
+    }
+    catch (const std::exception& ex)
+    {
+      WerrorS("ERROR: "); WerrorS(ex.what()); WerrorS("\n");
+      return TRUE;
+    }
+    if (!ok)
+    {
+      WerrorS("overflow while converting polymake::Integer to int");
+      return TRUE;
+    }
+    res->rtyp = INT_CMD;
+    res->data = (char*) (long) n;
+    return FALSE;
+  }
+  WerrorS("nInteriorLatticePoints: unexpected parameters");
+  return TRUE;
+}
+
+
+BOOLEAN PMboundaryLatticePoints(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && (u->Typ() == polytopeID))
+  {
+    gfan::ZCone* zp = (gfan::ZCone*)u->Data();
+    intvec* iv;
+    bool ok = true;
+    try
+    {
+      polymake::perl::Object* p = ZPolytope2PmPolytope(zp);
+      polymake::Matrix<polymake::Integer> lp = p->give("BOUNDARY_LATTICE_POINTS");
+      delete p;
+      iv = PmMatrixInteger2Intvec(&lp,ok);
+    }
+    catch (const std::exception& ex)
+    {
+      WerrorS("ERROR: "); WerrorS(ex.what()); WerrorS("\n");
+      return TRUE;
+    }
+    if (!ok)
+    {
+      WerrorS("overflow while converting polymake::Integer to int");
+      return TRUE;
+    }
+    res->rtyp = INTMAT_CMD;
+    res->data = (char*) iv;
+    return FALSE;
+  }
+  WerrorS("boundaryLatticePoints: unexpected parameters");
+  return TRUE;
+}
+
+
+BOOLEAN PMnBoundaryLatticePoints(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && (u->Typ() == polytopeID))
+  {
+    gfan::ZCone* zp = (gfan::ZCone*)u->Data();
+    int n;
+    bool ok = true;
+    try
+    {
+      polymake::perl::Object* p = ZPolytope2PmPolytope(zp);
+      polymake::Integer nlp = p->give("N_BOUNDARY_LATTICE_POINTS");
+      delete p;
+      n = PmInteger2Int(nlp,ok);
+    }
+    catch (const std::exception& ex)
+    {
+      WerrorS("ERROR: "); WerrorS(ex.what()); WerrorS("\n");
+      return TRUE;
+    }
+    if (!ok)
+    {
+      WerrorS("overflow while converting polymake::Integer to int");
+      return TRUE;
+    }
+    res->rtyp = INT_CMD;
+    res->data = (char*) (long) n;
+    return FALSE;
+  }
+  WerrorS("nBoundaryLatticePoints: unexpected parameters");
+  return TRUE;
+}
+
+
+BOOLEAN PMhilbertBasis(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && (u->Typ() == coneID))
+  {
+    gfan::ZCone* zp = (gfan::ZCone*)u->Data();
+    intvec* iv;
+    bool ok = true;
+    try
+    {
+      polymake::perl::Object* p = ZPolytope2PmPolytope(zp);
+      polymake::Matrix<polymake::Integer> lp = p->give("HILBERT_BASIS");
+      delete p;
+      iv = PmMatrixInteger2Intvec(&lp,ok);
+    }
+    catch (const std::exception& ex)
+    {
+      WerrorS("ERROR: "); WerrorS(ex.what()); WerrorS("\n");
+      return TRUE;
+    }
+    if (!ok)
+    {
+      WerrorS("overflow while converting polymake::Integer to int");
+      return TRUE;
+    }
+    res->rtyp = INTMAT_CMD;
+    res->data = (char*) iv;
+    return FALSE;
+  }
+  WerrorS("hilbertBasis: unexpected parameters");
+  return TRUE;
+}
+
+
+BOOLEAN PMnHilbertBasis(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && (u->Typ() == coneID))
+  {
+    gfan::ZCone* zp = (gfan::ZCone*)u->Data();
+    int n;
+    bool ok = true;
+    try
+    {
+      polymake::perl::Object* p = ZPolytope2PmPolytope(zp);
+      polymake::Integer nlp = p->give("N_HILBERT_BASIS");
+      delete p;
+      n = PmInteger2Int(nlp,ok);
+    }
+    catch (const std::exception& ex)
+    {
+      WerrorS("ERROR: "); WerrorS(ex.what()); WerrorS("\n");
+      return TRUE;
+    }
+    if (!ok)
+    {
+      WerrorS("overflow while converting polymake::Integer to int");
+      return TRUE;
+    }
+    res->rtyp = INT_CMD;
+    res->data = (char*) (long) n;
+    return FALSE;
+  }
+  WerrorS("nHilbertBasis: unexpected parameters");
+  return TRUE;
+}
+
+
+BOOLEAN PMminkowskiSum(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && (u->Typ() == polytopeID))
+  {
+    leftv v = u->next;
+    if ((v != NULL) && (v->Typ() == polytopeID))
+    {
+      gfan::ZCone* zp = (gfan::ZCone*)u->Data();
+      gfan::ZCone* zq = (gfan::ZCone*)v->Data();
+      gfan::ZCone* ms;
+      try
+      {
+        polymake::perl::Object* pp = ZPolytope2PmPolytope(zp);
+        polymake::perl::Object* pq = ZPolytope2PmPolytope(zq);
+        polymake::perl::Object pms;
+        CallPolymakeFunction("minkowski_sum", *pp, *pq) >> pms;
+        delete pp;
+        delete pq;
+        ms = PmPolytope2ZPolytope(&pms);
+      }
+      catch (const std::exception& ex)
+      {
+        WerrorS("ERROR: "); WerrorS(ex.what()); WerrorS("\n");
+        return TRUE;
+      }
+      res->rtyp = polytopeID;
+      res->data = (char*) ms;
+      return FALSE;
+    }
+    if ((v != NULL) && (v->Typ() == coneID))
+    {
+      gfan::ZCone* zp = (gfan::ZCone*)u->Data();
+      gfan::ZCone* zc = (gfan::ZCone*)v->Data();
+      gfan::ZCone* zq = new gfan::ZCone(liftUp(*zc));
+      gfan::ZCone* ms;
+      try
+      {
+        polymake::perl::Object* pp = ZPolytope2PmPolytope(zp);
+        polymake::perl::Object* pq = ZPolytope2PmPolytope(zq);
+        polymake::perl::Object pms;
+        CallPolymakeFunction("minkowski_sum", *pp, *pq) >> pms;
+        delete pp;
+        delete pq;
+        ms = PmPolytope2ZPolytope(&pms);
+      }
+      catch (const std::exception& ex)
+      {
+        WerrorS("ERROR: "); WerrorS(ex.what()); WerrorS("\n");
+        delete zq;
+        return TRUE;
+      }
+      res->rtyp = polytopeID;
+      res->data = (char*) ms;
+      delete zq;
+      return FALSE;
+    }
+  }
+  if ((u != NULL) && (u->Typ() == coneID))
+  {
+    leftv v = u->next;
+    if ((v != NULL) && (v->Typ() == polytopeID))
+    {
+      gfan::ZCone* zc = (gfan::ZCone*)u->Data();
+      gfan::ZCone* zp = new gfan::ZCone(liftUp(*zc));
+      gfan::ZCone* zq = (gfan::ZCone*)v->Data();
+      gfan::ZCone* ms;
+      try
+      {
+        polymake::perl::Object* pp = ZPolytope2PmPolytope(zp);
+        polymake::perl::Object* pq = ZPolytope2PmPolytope(zq);
+        polymake::perl::Object pms;
+        CallPolymakeFunction("minkowski_sum", *pp, *pq) >> pms;
+        delete pp;
+        delete pq;
+        ms = PmPolytope2ZPolytope(&pms);
+      }
+      catch (const std::exception& ex)
+      {
+        WerrorS("ERROR: "); WerrorS(ex.what()); WerrorS("\n");
+        delete zp;
+        return TRUE;
+      }
+      res->rtyp = polytopeID;
+      res->data = (char*) ms;
+      delete zp;
+      return FALSE;
+    }
+    if ((v != NULL) && (v->Typ() == coneID))
+    {
+      gfan::ZCone* zp = (gfan::ZCone*)u->Data();
+      gfan::ZCone* zq = (gfan::ZCone*)v->Data();
+      gfan::ZCone* ms;
+      try
+      {
+        polymake::perl::Object* pp = ZPolytope2PmPolytope(zp);
+        polymake::perl::Object* pq = ZPolytope2PmPolytope(zq);
+        polymake::perl::Object pms;
+        CallPolymakeFunction("minkowski_sum", *pp, *pq) >> pms;
+        delete pp;
+        delete pq;
+        ms = PmPolytope2ZPolytope(&pms);
+      }
+      catch (const std::exception& ex)
+      {
+        WerrorS("ERROR: "); WerrorS(ex.what()); WerrorS("\n");
+        return TRUE;
+      }
+      res->rtyp = coneID;
+      res->data = (char*) ms;
+      return FALSE;
+    }
+  }
+  WerrorS("minkowskiSum: unexpected parameters");
+  return TRUE;
+}
+
+
+polymake::Matrix<polymake::Integer> verticesOf(const polymake::perl::Object* p,
+                                               const polymake::Set<polymake::Integer>* s)
+{
+  polymake::Matrix<polymake::Integer> allrays = p->give("VERTICES");
+  polymake::Matrix<polymake::Integer> wantedrays;
+  bool ok = true;
+  for(polymake::Entire<polymake::Set<polymake::Integer> >::const_iterator i=polymake::entire(*s); !i.at_end(); i++)
+  {
+    wantedrays = wantedrays / allrays.row(PmInteger2Int(*i,ok));
+  }
+  if (!ok)
+  {
+    WerrorS("overflow while converting polymake::Integer to int in raysOf");
+  }
+  return wantedrays;
+}
+
+
+BOOLEAN PMmaximalFace(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && (u->Typ() == polytopeID))
+  {
+    leftv v = u->next;
+    if ((v != NULL) && (v->Typ() == INTVEC_CMD))
+    {
+      gfan::ZCone* zp = (gfan::ZCone*)u->Data();
+      intvec* iv = (intvec*) v->Data();
+      intvec* maxface;
+      bool ok = true;
+      try
+      {
+        polymake::perl::Object* p = ZPolytope2PmPolytope(zp);
+        polymake::perl::Object o("LinearProgram<Rational>");
+        o.take("LINEAR_OBJECTIVE") << Intvec2PmVectorInteger(iv);
+        p->take("LP") << o;
+        polymake::Set<polymake::Integer> mf = p->give("LP.MAXIMAL_FACE");
+        polymake::Matrix<polymake::Integer> vertices = verticesOf(p,&mf);
+        delete p;
+        maxface = new intvec(PmMatrixInteger2Intvec(&vertices,ok));
+      }
+      catch (const std::exception& ex)
+      {
+        WerrorS("ERROR: "); WerrorS(ex.what()); WerrorS("\n");
+        return TRUE;
+      }
+      if (!ok)
+      {
+        WerrorS("overflow while converting polymake::Integer to int");
+        return TRUE;
+      }
+      res->rtyp = INTVEC_CMD;
+      res->data = (char*) maxface;
+      return FALSE;
+    }
+  }
+  WerrorS("maximalFace: unexpected parameters");
+  return TRUE;
+}
+
+
+BOOLEAN PMminimalFace(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && (u->Typ() == polytopeID))
+  {
+    leftv v = u->next;
+    if ((v != NULL) && (v->Typ() == INTVEC_CMD))
+    {
+      gfan::ZCone* zp = (gfan::ZCone*)u->Data();
+      intvec* iv = (intvec*) v->Data();
+      intvec* minface;
+      bool ok = true;
+      try
+      {
+        polymake::perl::Object* p = ZPolytope2PmPolytope(zp);
+        polymake::perl::Object o("LinearProgram<Rational>");
+        o.take("LINEAR_OBJECTIVE") << Intvec2PmVectorInteger(iv);
+        p->take("LP") << o;
+        polymake::Set<polymake::Integer> mf = p->give("LP.MINIMAL_FACE");
+        polymake::Matrix<polymake::Integer> vertices = verticesOf(p,&mf);
+        delete p;
+        minface = new intvec(PmMatrixInteger2Intvec(&vertices,ok));
+      }
+      catch (const std::exception& ex)
+      {
+        WerrorS("ERROR: "); WerrorS(ex.what()); WerrorS("\n");
+        return TRUE;
+      }
+      if (!ok)
+      {
+        WerrorS("overflow while converting polymake::Integer to int");
+        return TRUE;
+      }
+      res->rtyp = INTVEC_CMD;
+      res->data = (char*) minface;
+      return FALSE;
+    }
+  }
+  WerrorS("minimalFace: unexpected parameters");
+  return TRUE;
+}
+
+
+BOOLEAN PMmaximalValue(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && (u->Typ() == polytopeID))
+  {
+    leftv v = u->next;
+    if ((v != NULL) && (v->Typ() == INTVEC_CMD))
+    {
+      gfan::ZCone* zp = (gfan::ZCone*)u->Data();
+      intvec* iv = (intvec*) v->Data();
+      if (iv->rows()==zp->ambientDimension())
+      {
+        int m;
+        bool ok = true;
+        try
+        {
+          polymake::perl::Object* p = ZPolytope2PmPolytope(zp);
+          polymake::Vector<polymake::Integer> lo = Intvec2PmVectorInteger(iv);
+          polymake::perl::Object o("LinearProgram<Rational>");
+          o.take("LINEAR_OBJECTIVE") << lo;
+          p->take("LP") << o;
+          polymake::Integer mv = p->give("LP.MAXIMAL_VALUE");
+          delete p;
+          m = PmInteger2Int(mv,ok);
+        }
+        catch (const std::exception& ex)
+        {
+          WerrorS("ERROR: "); WerrorS(ex.what()); WerrorS("\n");
+          return TRUE;
+        }
+        if (!ok)
+        {
+          WerrorS("overflow while converting polymake::Integer to int");
+          return TRUE;
+        }
+        res->rtyp = INT_CMD;
+        res->data = (char*) (long) m;
+        return FALSE;
+      }
+    }
+    WerrorS("maximalValue: vector is of wrong size");
+    return TRUE;
+  }
+  WerrorS("maximalValue: unexpected parameters");
+  return TRUE;
+}
+
+BOOLEAN PMminimalValue(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && (u->Typ() == polytopeID))
+  {
+    leftv v = u->next;
+    if ((v != NULL) && (v->Typ() == INTVEC_CMD))
+    {
+      gfan::ZCone* zp = (gfan::ZCone*)u->Data();
+      intvec* iv = (intvec*) v->Data();
+      if (iv->rows()==zp->ambientDimension())
+      {
+        int m;
+        bool ok = true;
+        try
+        {
+          polymake::perl::Object* p = ZPolytope2PmPolytope(zp);
+          polymake::Vector<polymake::Integer> lo = Intvec2PmVectorInteger(iv);
+          polymake::perl::Object o("LinearProgram<Rational>");
+          o.take("LINEAR_OBJECTIVE") << lo;
+          p->take("LP") << o;
+          polymake::Integer mv = p->give("LP.MINIMAL_VALUE");
+          delete p;
+          m = PmInteger2Int(mv,ok);
+        }
+        catch (const std::exception& ex)
+        {
+          WerrorS("ERROR: "); WerrorS(ex.what()); WerrorS("\n");
+          return TRUE;
+        }
+        if (!ok)
+        {
+          WerrorS("overflow while converting polymake::Integer to int");
+          return TRUE;
+        }
+        res->rtyp = INT_CMD;
+        res->data = (char*) (long) m;
+        return FALSE;
+      }
+    }
+    WerrorS("minimalValue: vector is of wrong size");
+    return TRUE;
+  }
+  WerrorS("minimalValue: unexpected parameters");
+  return TRUE;
+}
+
+
+BOOLEAN visual(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && (u->Typ() == polytopeID))
+  {
+    gfan::ZCone* zp = (gfan::ZCone*)u->Data();
+    try
+    {
+      polymake::perl::Object* pp = ZPolytope2PmPolytope(zp);
+      VoidCallPolymakeFunction("jreality",pp->CallPolymakeMethod("VISUAL"));
+      delete pp;
+    }
+    catch (const std::exception& ex)
+    {
+      WerrorS("ERROR: "); WerrorS(ex.what()); WerrorS("\n");
+      return TRUE;
+    }
+    res->rtyp = NONE;
+    res->data = NULL;
+    return FALSE;
+  }
+  if ((u != NULL) && (u->Typ() == fanID))
+  {
+    gfan::ZFan* zf = (gfan::ZFan*)u->Data();
+    try
+    {
+      polymake::perl::Object* pf=ZFan2PmFan(zf);
+      VoidCallPolymakeFunction("jreality",pf->CallPolymakeMethod("VISUAL"));
+    }
+    catch (const std::exception& ex)
+    {
+      WerrorS("ERROR: "); WerrorS(ex.what()); WerrorS("\n");
+      return TRUE;
+    }
+    res->rtyp = NONE;
+    res->data = NULL;
+    return FALSE;
+  }
+  WerrorS("visual: unexpected parameters");
+  return TRUE;
+}
+
+BOOLEAN normalFan(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && (u->Typ() == polytopeID))
+  {
+    gfan::ZCone* zp = (gfan::ZCone*)u->Data();
+    gfan::ZFan* zf = new gfan::ZFan(0);
+    try
+    {
+      polymake::perl::Object* p=ZPolytope2PmPolytope(zp);
+      polymake::perl::Object pf;
+      CallPolymakeFunction("normal_fan", *p) >> pf;
+      delete p;
+      zf = PmFan2ZFan(&pf);
+    }
+    catch (const std::exception& ex)
+    {
+      WerrorS("ERROR: "); WerrorS(ex.what()); WerrorS("\n");
+      return TRUE;
+    }
+    res->rtyp = fanID;
+    res->data = (char*) zf;
+    return FALSE;
+  }
+  WerrorS("normalFan: unexpected parameters");
+  return TRUE;
+}
+
+BOOLEAN PMconeViaRays(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && (u->Typ() == INTMAT_CMD))
+  {
+    polymake::perl::Object pc("Cone<Rational>");
+    intvec* hlines = (intvec*) u->Data(); // these will are half lines in the cone
+    polymake::Matrix<polymake::Integer> pmhlines = Intvec2PmMatrixInteger(hlines);
+    pc.take("INPUT_RAYS") << pmhlines;
+
+    leftv v = u->next;
+    if ((v != NULL) && (v->Typ() == INTMAT_CMD))
+    {
+      intvec* lines = (intvec*) v->Data(); // these will be lines in the cone
+      polymake::Matrix<polymake::Integer> pmlines = Intvec2PmMatrixInteger(lines);
+      pc.take("INPUT_LINEALITY") << pmlines;
+
+      // leftv w = v->next;
+      // if ((w != NULL) && (w->Typ() == INT_CMD))
+      // {
+      //   int flag = (int) (long) w->Data(); // TODO: this will indicate whether the
+      //                                      // information provided are exact
+      // }
+    }
+    gfan::ZCone* zc = PmCone2ZCone(&pc);
+    res->rtyp = coneID;
+    res->data = (char*) zc;
+    return FALSE;
+  }
+  WerrorS("coneViaRays: unexpected parameters");
+  return TRUE;
+}
+
+
+BOOLEAN PMpolytopeViaVertices(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && (u->Typ() == INTMAT_CMD))
+  {
+    polymake::perl::Object pp("Polytope<Rational>");
+    intvec* points = (intvec*) u->Data(); // these will be vertices of or points in the polytope
+    polymake::Matrix<polymake::Integer> pmpoints = Intvec2PmMatrixInteger(points);
+
+    leftv v = u->next;
+    if ((v != NULL) && (v->Typ() == INT_CMD))
+    {
+      int flag = (int) (long) v->Data();
+      switch(flag)
+      {
+        case 0:  pp.take("POINTS") << pmpoints;   // case means the matrix may contain points inside the polytope
+        case 1:  pp.take("VERTICES") << pmpoints; // case means the matrix only contains vertices of the polytope
+        default: WerrorS("polytopeViaVertices: invalid flag");
+      }
+    }
+    else
+      pp.take("POINTS") << pmpoints;              // by default, we assume that matrix may contain non-vertices
+
+    gfan::ZCone* zp = PmPolytope2ZPolytope(&pp);
+    res->rtyp = polytopeID;
+    res->data = (char*) zp;
+    return FALSE;
+  }
+  WerrorS("polytopeViaVertices: unexpected parameters");
+  return TRUE;
+}
+
+
+BOOLEAN PMvertexAdjacencyGraph(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && (u->Typ() == polytopeID))
+  {
+    gfan::ZCone* zp = (gfan::ZCone*) u->Data();
+    lists output=(lists)omAllocBin(slists_bin); output->Init(2);
+    try
+    {
+      polymake::perl::Object* p = ZPolytope2PmPolytope(zp);
+      polymake::Matrix<polymake::Integer> vert0 = p->give("VERTICES");
+      bigintmat* vert1 = PmMatrixInteger2Bigintmat(&vert0);
+      output->m[0].rtyp = BIGINTMAT_CMD;
+      output->m[0].data = (void*) vert1;
+
+      polymake::Graph<> gr=p->give("GRAPH.ADJACENCY");
+      polymake::IncidenceMatrix<polymake::NonSymmetric> adj = adjacency_matrix(gr);
+      lists listOfEdges = PmIncidenceMatrix2ListOfIntvecs(&adj);
+      output->m[1].rtyp = LIST_CMD;
+      output->m[1].data = (void*) listOfEdges;
+      delete p;
+    }
+    catch (const std::exception& ex)
+    {
+      WerrorS("ERROR: "); WerrorS(ex.what()); WerrorS("\n");
+      return TRUE;
+    }
+    res->rtyp = LIST_CMD;
+    res->data = (void*) output;
+    return FALSE;
+  }
+  WerrorS("vertexEdgeGraph: unexpected parameters");
+  return TRUE;
+}
+
+
+BOOLEAN PMvertexEdgeGraph(leftv res, leftv args)
+{
+  leftv u = args;
+  if ((u != NULL) && (u->Typ() == polytopeID))
+  {
+    gfan::ZCone* zp = (gfan::ZCone*) u->Data();
+    lists output=(lists)omAllocBin(slists_bin); output->Init(2);
+    try
+    {
+      polymake::perl::Object* p = ZPolytope2PmPolytope(zp);
+      polymake::Matrix<polymake::Integer> vert0 = p->give("VERTICES");
+      bigintmat* vert1 = PmMatrixInteger2Bigintmat(&vert0);
+      output->m[0].rtyp = BIGINTMAT_CMD;
+      output->m[0].data = (void*) vert1;
+
+      polymake::Graph<> gr=p->give("GRAPH.ADJACENCY");
+      polymake::IncidenceMatrix<polymake::NonSymmetric> adj = adjacency_matrix(gr);
+      lists listOfEdges = PmAdjacencyMatrix2ListOfEdges(&adj);
+      output->m[1].rtyp = LIST_CMD;
+      output->m[1].data = (void*) listOfEdges;
+      delete p;
+    }
+    catch (const std::exception& ex)
+    {
+      WerrorS("ERROR: "); WerrorS(ex.what()); WerrorS("\n");
+      return TRUE;
+    }
+    res->rtyp = LIST_CMD;
+    res->data = (void*) output;
+    return FALSE;
+  }
+  WerrorS("vertexEdgeGraph: unexpected parameters");
+  return TRUE;
+}
+
+extern "C" int SI_MOD_INIT(polymake)(SModulFunctions* p)
+{
+  if (init_polymake==NULL)
+    {init_polymake = new polymake::Main();}
+  init_polymake->set_application("fan");
+  // p->iiAddCproc("polymake.so","coneViaPoints",FALSE,PMconeViaRays);
+  // p->iiAddCproc("polymake.so","polytopeViaPoints",FALSE,PMpolytopeViaVertices);
+  p->iiAddCproc("polymake.so","isLatticePolytope",FALSE,PMisLatticePolytope);
+  p->iiAddCproc("polymake.so","isBounded",FALSE,PMisBounded);
+  p->iiAddCproc("polymake.so","isReflexive",FALSE,PMisReflexive);
+  p->iiAddCproc("polymake.so","isGorenstein",FALSE,PMisGorenstein);
+  p->iiAddCproc("polymake.so","gorensteinIndex",FALSE,PMgorensteinIndex);
+  p->iiAddCproc("polymake.so","gorensteinVector",FALSE,PMgorensteinVector);
+  p->iiAddCproc("polymake.so","isCanonical",FALSE,PMisCanonical);
+  p->iiAddCproc("polymake.so","isTerminal",FALSE,PMisTerminal);
+  p->iiAddCproc("polymake.so","isLatticeEmpty",FALSE,PMisLatticeEmpty);
+  p->iiAddCproc("polymake.so","latticeVolume",FALSE,PMlatticeVolume);
+  p->iiAddCproc("polymake.so","latticeDegree",FALSE,PMlatticeDegree);
+  p->iiAddCproc("polymake.so","latticeCodegree",FALSE,PMlatticeCodegree);
+  p->iiAddCproc("polymake.so","ehrhartPolynomialCoeff",FALSE,PMehrhartPolynomialCoeff);
+  p->iiAddCproc("polymake.so","fVector",FALSE,PMfVector);
+  p->iiAddCproc("polymake.so","hVector",FALSE,PMhVector);
+  p->iiAddCproc("polymake.so","hStarVector",FALSE,PMhStarVector);
+  p->iiAddCproc("polymake.so","isNormal",FALSE,PMisNormal);
+  p->iiAddCproc("polymake.so","facetWidths",FALSE,PMfacetWidths);
+  p->iiAddCproc("polymake.so","facetWidth",FALSE,PMfacetWidth);
+  p->iiAddCproc("polymake.so","facetVertexLatticeDistances",FALSE,PMfacetVertexLatticeDistances);
+  p->iiAddCproc("polymake.so","isCompressed",FALSE,PMisCompressed);
+  p->iiAddCproc("polymake.so","isSmooth",FALSE,PMisSmooth);
+  p->iiAddCproc("polymake.so","isVeryAmple",FALSE,PMisVeryAmple);
+  p->iiAddCproc("polymake.so","latticePoints",FALSE,PMlatticePoints);
+  p->iiAddCproc("polymake.so","nLatticePoints",FALSE,PMnLatticePoints);
+  p->iiAddCproc("polymake.so","interiorLatticePoints",FALSE,PMinteriorLatticePoints);
+  p->iiAddCproc("polymake.so","nInteriorLatticePoints",FALSE,PMnInteriorLatticePoints);
+  p->iiAddCproc("polymake.so","boundaryLatticePoints",FALSE,PMboundaryLatticePoints);
+  p->iiAddCproc("polymake.so","nBoundaryLatticePoints",FALSE,PMnBoundaryLatticePoints);
+  p->iiAddCproc("polymake.so","hilbertBasis",FALSE,PMhilbertBasis);
+  p->iiAddCproc("polymake.so","nHilbertBasis",FALSE,PMnHilbertBasis);
+  p->iiAddCproc("polymake.so","minkowskiSum",FALSE,PMminkowskiSum);
+  p->iiAddCproc("polymake.so","maximalFace",FALSE,PMmaximalFace);
+  p->iiAddCproc("polymake.so","minimalFace",FALSE,PMminimalFace);
+  p->iiAddCproc("polymake.so","maximalValue",FALSE,PMmaximalValue);
+  p->iiAddCproc("polymake.so","minimalValue",FALSE,PMminimalValue);
+  p->iiAddCproc("polymake.so","visual",FALSE,visual);
+  p->iiAddCproc("polymake.so","normalFan",FALSE,normalFan);
+  p->iiAddCproc("polymake.so","vertexAdjacencyGraph",FALSE,PMvertexAdjacencyGraph);
+  p->iiAddCproc("polymake.so","vertexEdgeGraph",FALSE,PMvertexEdgeGraph);
+
+  blackbox* b=getBlackboxStuff(polytopeID);
+  b->blackbox_Op2=bbpolytope_Op2;
+
+  init_polymake_help();
+  return MAX_TOK;
+}
+
+#endif /* HAVE_POLYMAKE */
diff --git a/Singular/dyn_modules/pyobject/Makefile.am b/Singular/dyn_modules/pyobject/Makefile.am
new file mode 100644
index 0000000..b7a307e
--- /dev/null
+++ b/Singular/dyn_modules/pyobject/Makefile.am
@@ -0,0 +1,27 @@
+ACLOCAL_AMFLAGS = -I ../../m4
+
+if SI_BUILTIN_PYOBJECT
+  noinst_LTLIBRARIES = pyobject.la
+##  moduledir = $(libdir)/singular
+  P_PROCS_CPPFLAGS_COMMON = -DSTATIC_VERSION
+  P_PROCS_MODULE_LDFLAGS  = -module
+else !SI_BUILTIN_PYOBJECT
+  module_LTLIBRARIES = pyobject.la
+  moduledir = $(libexecdir)/singular/MOD
+  P_PROCS_CPPFLAGS_COMMON = -DDYNAMIC_VERSION
+# Add under Mac OS X: -flat_namespace -weak_reference_mismatches weak -undefined dynamic_lookup
+  P_PROCS_MODULE_LDFLAGS = -module -export-dynamic -avoid-version -flat_namespace -weak_reference_mismatches weak -undefined dynamic_lookup
+###  -export-dynamic -shared -module -avoid-version (add to all DMs?)
+endif !SI_BUILTIN_PYOBJECT
+
+##########################################################################
+AM_CPPFLAGS = -I${top_srcdir} -I${top_builddir} -I${top_srcdir}/kernel -I${top_builddir}/kernel -I${top_srcdir}/libpolys -I${top_builddir}/libpolys $(FACTORY_INCLUDES)  $(GMP_CFLAGS) $(NTL_CFLAGS) $(FLINT_CFLAGS)
+
+pyobject_la_SOURCES = pyobject.cc
+
+### if HAVE_PYTHON???
+pyobject_la_CXXFLAGS = $(PYTHON_CSPEC)
+pyobject_la_CPPFLAGS = $(PYTHON_CPPFLAGS)  ${AM_CPPFLAGS} ${P_PROCS_CPPFLAGS_COMMON}
+
+pyobject_la_LDFLAGS = $(PYTHON_EXTRA_LIBS)  $(PYTHON_LSPEC) ${AM_LDFLAGS} $(PYTHON_EXTRA_LDFLAGS) $(PYTHON_LDFLAGS) ${P_PROCS_MODULE_LDFLAGS}
+pyobject_la_LIBADD = $(PYTHON_EXTRA_LIBS) $(PYTHON_LSPEC) $(PYTHON_EXTRA_LDFLAGS) $(PYTHON_LDFLAGS)
diff --git a/Singular/dyn_modules/pyobject/Makefile.in b/Singular/dyn_modules/pyobject/Makefile.in
new file mode 100644
index 0000000..013e33d
--- /dev/null
+++ b/Singular/dyn_modules/pyobject/Makefile.in
@@ -0,0 +1,745 @@
+# Makefile.in generated by automake 1.13.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 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@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+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 = Singular/dyn_modules/pyobject
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/build-aux/depcomp
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_append_compile_flags.m4 \
+	$(top_srcdir)/m4/ax_append_flag.m4 \
+	$(top_srcdir)/m4/ax_append_link_flags.m4 \
+	$(top_srcdir)/m4/ax_check_compile_flag.m4 \
+	$(top_srcdir)/m4/ax_check_link_flag.m4 \
+	$(top_srcdir)/m4/ax_compute_relative_paths.m4 \
+	$(top_srcdir)/m4/ax_normalize_path.m4 \
+	$(top_srcdir)/m4/ax_prefix_config_h.m4 \
+	$(top_srcdir)/m4/ax_pthread.m4 \
+	$(top_srcdir)/m4/ax_python_embed.m4 \
+	$(top_srcdir)/m4/ax_python_with_version.m4 \
+	$(top_srcdir)/m4/cpu-check.m4 $(top_srcdir)/m4/dbm-check.m4 \
+	$(top_srcdir)/m4/flags.m4 $(top_srcdir)/m4/flint-check.m4 \
+	$(top_srcdir)/m4/gfanlib-check.m4 \
+	$(top_srcdir)/m4/gmp-check.m4 \
+	$(top_srcdir)/m4/google-perftools.m4 \
+	$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+	$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+	$(top_srcdir)/m4/lt~obsolete.m4 \
+	$(top_srcdir)/m4/mathic-check.m4 $(top_srcdir)/m4/ntl-check.m4 \
+	$(top_srcdir)/m4/options.m4 $(top_srcdir)/m4/p-procs.m4 \
+	$(top_srcdir)/m4/polymake-check.m4 \
+	$(top_srcdir)/m4/readline-check.m4 $(top_srcdir)/configure.ac
+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__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
+am__installdirs = "$(DESTDIR)$(moduledir)"
+LTLIBRARIES = $(module_LTLIBRARIES) $(noinst_LTLIBRARIES)
+am__DEPENDENCIES_1 =
+pyobject_la_DEPENDENCIES = $(am__DEPENDENCIES_1)
+am_pyobject_la_OBJECTS = pyobject_la-pyobject.lo
+pyobject_la_OBJECTS = $(am_pyobject_la_OBJECTS)
+AM_V_lt = $(am__v_lt_ at AM_V@)
+am__v_lt_ = $(am__v_lt_ at AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 = 
+pyobject_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(pyobject_la_CXXFLAGS) \
+	$(CXXFLAGS) $(pyobject_la_LDFLAGS) $(LDFLAGS) -o $@
+ at SI_BUILTIN_PYOBJECT_FALSE@am_pyobject_la_rpath = -rpath $(moduledir)
+ at SI_BUILTIN_PYOBJECT_TRUE@am_pyobject_la_rpath =
+AM_V_P = $(am__v_P_ at AM_V@)
+am__v_P_ = $(am__v_P_ at AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_ at AM_V@)
+am__v_GEN_ = $(am__v_GEN_ at AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_ at AM_V@)
+am__v_at_ = $(am__v_at_ at AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+DEFAULT_INCLUDES = -I. at am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \
+	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+	$(AM_CXXFLAGS) $(CXXFLAGS)
+AM_V_CXX = $(am__v_CXX_ at AM_V@)
+am__v_CXX_ = $(am__v_CXX_ at AM_DEFAULT_V@)
+am__v_CXX_0 = @echo "  CXX     " $@;
+am__v_CXX_1 = 
+CXXLD = $(CXX)
+CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+	$(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CXXLD = $(am__v_CXXLD_ at AM_V@)
+am__v_CXXLD_ = $(am__v_CXXLD_ at AM_DEFAULT_V@)
+am__v_CXXLD_0 = @echo "  CXXLD   " $@;
+am__v_CXXLD_1 = 
+SOURCES = $(pyobject_la_SOURCES)
+DIST_SOURCES = $(pyobject_la_SOURCES)
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BUILTIN_LIBS = @BUILTIN_LIBS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CDDGMPCPPFLAGS = @CDDGMPCPPFLAGS@
+CDDGMPLDFLAGS = @CDDGMPLDFLAGS@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATA_DIR = @DATA_DIR@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DOC_DIR = @DOC_DIR@
+DOXYGEN = @DOXYGEN@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FACTORY_INCLUDES = @FACTORY_INCLUDES@
+FACTORY_LIBS = @FACTORY_LIBS@
+FGREP = @FGREP@
+FLINT_CFLAGS = @FLINT_CFLAGS@
+FLINT_HOME = @FLINT_HOME@
+FLINT_LIBS = @FLINT_LIBS@
+GMP_CFLAGS = @GMP_CFLAGS@
+GMP_HOME = @GMP_HOME@
+GMP_LIBS = @GMP_LIBS@
+GMP_VERSION = @GMP_VERSION@
+GREP = @GREP@
+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@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NTL_CFLAGS = @NTL_CFLAGS@
+NTL_LIBS = @NTL_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OMALLOC_INCLUDES = @OMALLOC_INCLUDES@
+OMALLOC_LIBS = @OMALLOC_LIBS@
+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@
+PKG_REQUIRE = @PKG_REQUIRE@
+PMCONFIG = @PMCONFIG@
+PM_CFLAGS = @PM_CFLAGS@
+PM_INC = @PM_INC@
+PM_LDFLAGS = @PM_LDFLAGS@
+PM_LIBS = @PM_LIBS@
+POLYMAKE_CXXFLAGS = @POLYMAKE_CXXFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LDFLAGS = @PTHREAD_LDFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
+PYTHON = @PYTHON@
+PYTHON_CSPEC = @PYTHON_CSPEC@
+PYTHON_EXECPREFIX = @PYTHON_EXECPREFIX@
+PYTHON_LSPEC = @PYTHON_LSPEC@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+RANLIB = @RANLIB@
+RESOURCES_INCLUDES = @RESOURCES_INCLUDES@
+RESOURCES_LIBS = @RESOURCES_LIBS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SINGULAR_CFLAGS = @SINGULAR_CFLAGS@
+SI_COUNTEDREF_AUTOLOAD = @SI_COUNTEDREF_AUTOLOAD@
+SI_CPU_I386 = @SI_CPU_I386@
+SI_CPU_IA64 = @SI_CPU_IA64@
+SI_CPU_PPC = @SI_CPU_PPC@
+SI_CPU_SPARC = @SI_CPU_SPARC@
+SI_CPU_X86_64 = @SI_CPU_X86_64@
+STRIP = @STRIP@
+USEPPROCSDYNAMICLD = @USEPPROCSDYNAMICLD@
+USEPPROCSDYNAMICLDFLAGS = @USEPPROCSDYNAMICLDFLAGS@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
+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@
+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@
+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@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+ACLOCAL_AMFLAGS = -I ../../m4
+ at SI_BUILTIN_PYOBJECT_TRUE@noinst_LTLIBRARIES = pyobject.la
+ at SI_BUILTIN_PYOBJECT_FALSE@P_PROCS_CPPFLAGS_COMMON = -DDYNAMIC_VERSION
+ at SI_BUILTIN_PYOBJECT_TRUE@P_PROCS_CPPFLAGS_COMMON = -DSTATIC_VERSION
+# Add under Mac OS X: -flat_namespace -weak_reference_mismatches weak -undefined dynamic_lookup
+ at SI_BUILTIN_PYOBJECT_FALSE@P_PROCS_MODULE_LDFLAGS = -module -export-dynamic -avoid-version -flat_namespace -weak_reference_mismatches weak -undefined dynamic_lookup
+ at SI_BUILTIN_PYOBJECT_TRUE@P_PROCS_MODULE_LDFLAGS = -module
+ at SI_BUILTIN_PYOBJECT_FALSE@module_LTLIBRARIES = pyobject.la
+ at SI_BUILTIN_PYOBJECT_FALSE@moduledir = $(libexecdir)/singular/MOD
+###  -export-dynamic -shared -module -avoid-version (add to all DMs?)
+
+##########################################################################
+AM_CPPFLAGS = -I${top_srcdir} -I${top_builddir} -I${top_srcdir}/kernel -I${top_builddir}/kernel -I${top_srcdir}/libpolys -I${top_builddir}/libpolys $(FACTORY_INCLUDES)  $(GMP_CFLAGS) $(NTL_CFLAGS) $(FLINT_CFLAGS)
+pyobject_la_SOURCES = pyobject.cc
+
+### if HAVE_PYTHON???
+pyobject_la_CXXFLAGS = $(PYTHON_CSPEC)
+pyobject_la_CPPFLAGS = $(PYTHON_CPPFLAGS)  ${AM_CPPFLAGS} ${P_PROCS_CPPFLAGS_COMMON}
+pyobject_la_LDFLAGS = $(PYTHON_EXTRA_LIBS)  $(PYTHON_LSPEC) ${AM_LDFLAGS} $(PYTHON_EXTRA_LDFLAGS) $(PYTHON_LDFLAGS) ${P_PROCS_MODULE_LDFLAGS}
+pyobject_la_LIBADD = $(PYTHON_EXTRA_LIBS) $(PYTHON_LSPEC) $(PYTHON_EXTRA_LDFLAGS) $(PYTHON_LDFLAGS)
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .cc .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) --foreign Singular/dyn_modules/pyobject/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign Singular/dyn_modules/pyobject/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-moduleLTLIBRARIES: $(module_LTLIBRARIES)
+	@$(NORMAL_INSTALL)
+	@list='$(module_LTLIBRARIES)'; test -n "$(moduledir)" || list=; \
+	list2=; for p in $$list; do \
+	  if test -f $$p; then \
+	    list2="$$list2 $$p"; \
+	  else :; fi; \
+	done; \
+	test -z "$$list2" || { \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(moduledir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(moduledir)" || exit 1; \
+	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(moduledir)'"; \
+	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(moduledir)"; \
+	}
+
+uninstall-moduleLTLIBRARIES:
+	@$(NORMAL_UNINSTALL)
+	@list='$(module_LTLIBRARIES)'; test -n "$(moduledir)" || list=; \
+	for p in $$list; do \
+	  $(am__strip_dir) \
+	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(moduledir)/$$f'"; \
+	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(moduledir)/$$f"; \
+	done
+
+clean-moduleLTLIBRARIES:
+	-test -z "$(module_LTLIBRARIES)" || rm -f $(module_LTLIBRARIES)
+	@list='$(module_LTLIBRARIES)'; \
+	locs=`for p in $$list; do echo $$p; done | \
+	      sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+	      sort -u`; \
+	test -z "$$locs" || { \
+	  echo rm -f $${locs}; \
+	  rm -f $${locs}; \
+	}
+
+clean-noinstLTLIBRARIES:
+	-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+	@list='$(noinst_LTLIBRARIES)'; \
+	locs=`for p in $$list; do echo $$p; done | \
+	      sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+	      sort -u`; \
+	test -z "$$locs" || { \
+	  echo rm -f $${locs}; \
+	  rm -f $${locs}; \
+	}
+
+pyobject.la: $(pyobject_la_OBJECTS) $(pyobject_la_DEPENDENCIES) $(EXTRA_pyobject_la_DEPENDENCIES) 
+	$(AM_V_CXXLD)$(pyobject_la_LINK) $(am_pyobject_la_rpath) $(pyobject_la_OBJECTS) $(pyobject_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/pyobject_la-pyobject.Plo at am__quote@
+
+.cc.o:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+ at am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXXCOMPILE) -c -o $@ $<
+
+.cc.obj:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+ at am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.cc.lo:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+ at am__fastdepCXX_TRUE@	$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LTCXXCOMPILE) -c -o $@ $<
+
+pyobject_la-pyobject.lo: pyobject.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pyobject_la_CPPFLAGS) $(CPPFLAGS) $(pyobject_la_CXXFLAGS) $(CXXFLAGS) -MT pyobject_la-pyobject.lo -MD -MP -MF $(DEPDIR)/pyobject_la-pyobject.Tpo -c -o pyobject_la-pyobject.lo `test -f 'pyobject.cc' || echo '$(srcdir)/'`pyobject.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/pyobject_la-pyobject.Tpo $(DEPDIR)/pyobject_la-pyobject.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='pyobject.cc' object='pyobject_la-pyobject.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pyobject_la_CPPFLAGS) $(CPPFLAGS) $(pyobject_la_CXXFLAGS) $(CXXFLAGS) -c -o pyobject_la-pyobject.lo `test -f 'pyobject.cc' || echo '$(srcdir)/'`pyobject.cc
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	$(am__define_uniq_tagged_files); \
+	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-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	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"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+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 $(LTLIBRARIES)
+installdirs:
+	for dir in "$(DESTDIR)$(moduledir)"; 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:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+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 clean-moduleLTLIBRARIES \
+	clean-noinstLTLIBRARIES 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-moduleLTLIBRARIES
+
+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: uninstall-moduleLTLIBRARIES
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
+	clean-libtool clean-moduleLTLIBRARIES clean-noinstLTLIBRARIES \
+	cscopelist-am ctags ctags-am 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-moduleLTLIBRARIES 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 tags-am uninstall uninstall-am \
+	uninstall-moduleLTLIBRARIES
+
+
+# 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/Singular/dyn_modules/pyobject/pyobject.cc b/Singular/dyn_modules/pyobject/pyobject.cc
new file mode 100644
index 0000000..ba4130f
--- /dev/null
+++ b/Singular/dyn_modules/pyobject/pyobject.cc
@@ -0,0 +1,736 @@
+// -*- c++ -*-
+//*****************************************************************************
+/** @file pyobject.cc
+ *
+ * @author Alexander Dreyer
+ * @date 2010-12-15
+ *
+ * This file defines the @c blackbox operations for the pyobject type.
+ *
+ * @par Copyright:
+ *   (c) 2010 by The Singular Team, see LICENSE file
+**/
+//*****************************************************************************
+
+#include <kernel/mod2.h>
+#ifdef HAVE_PYTHON
+
+#include <omalloc/omalloc.h>
+#include <misc/intvec.h>
+
+#include <Singular/subexpr.h>
+#include <Singular/ipid.h>
+#include <Singular/blackbox.h>
+#include <Singular/lists.h>
+#include <Singular/ipid.h>
+#include <Singular/ipshell.h>
+#include <Singular/newstruct.h>
+#include <resources/feResource.h>
+
+#include <Singular/mod_lib.h>
+
+#include <Python.h>
+
+// #include <iterator>             // std::distance
+// #include <stdio.h>
+
+void sync_contexts();
+
+/** @class PythonInterpreter
+ * This class initializes and finalized the python interpreter.
+ *
+ * It also stores the Singular token number, which is assigned to this type on
+ * runtime.
+ **/
+class PythonInterpreter {
+public:
+  typedef int id_type;
+
+  ~PythonInterpreter()  { if(m_owns_python) Py_Finalize();  }
+
+  /// Initialize unique (singleton) python interpreter instance,
+  /// and set Singular type identifier
+  static void init(id_type num) { instance().m_id = num; }
+
+  /// Get Singular type identitfier
+  static id_type id() { return instance().m_id; }
+
+private:
+  /// Singleton: Only init() is allowed to construct an instance
+  PythonInterpreter():
+    m_id(0), m_owns_python(false)  { start_python(); }
+
+  /// Static initialization -
+  /// safely takes care of destruction on program termination
+  static PythonInterpreter& instance()
+  {
+    static PythonInterpreter init_interpreter;
+    return init_interpreter;
+  }
+
+  void start_python()
+  {
+    if (!Py_IsInitialized()) init_python();
+    set_python_defaults();
+  }
+
+  void init_python()
+  {
+    Py_Initialize();
+    m_owns_python = true;
+  }
+
+  void set_python_defaults()
+  {
+    // Sone python modules needs argc, argv set for some reason
+    char* argv = (char*)"";
+    PySys_SetArgv(1, &argv);
+    PyRun_SimpleString("from sys import path, modules");
+    PyRun_SimpleString("_SINGULAR_IMPORTED = dict()");
+
+    char cmd[MAXPATHLEN + 20];
+    sprintf(cmd, "path.insert(0, '%s')", feGetResource('b'));
+    PyRun_SimpleString(cmd);
+    PyRun_SimpleString("del path");  // cleanup
+  }
+
+  id_type m_id;
+  bool m_owns_python;
+};
+
+/** @class PythonObject
+ * This class defines an interface for calling PyObject from Singular.
+ *
+ * @note This class does not take care of the memory mangement, this is done in
+ * the blackbox routines.
+ **/
+class PythonObject
+{
+  typedef PythonObject self;
+
+public:
+  typedef PyObject* ptr_type;
+  struct sequence_tag{};
+
+  PythonObject(): m_ptr(Py_None) { }
+  PythonObject(ptr_type ptr): m_ptr(ptr) {
+    if (!ptr && handle_exception()) m_ptr = Py_None;
+  }
+
+  ptr_type check_context(ptr_type ptr) const {
+    if(ptr) sync_contexts();
+    return ptr;
+  }
+  /// Unary operations
+  self operator()(int op) const
+  {
+    switch(op)
+    {
+    case '(':  return check_context(PyObject_CallObject(*this, NULL));
+    case ATTRIB_CMD: return PyObject_Dir(*this);
+    case PROC_CMD: return *this;
+    }
+
+    if (op == PythonInterpreter::id())
+      return *this;
+
+    return self(NULL);
+  }
+
+  /// Binary and n-ary operations
+  self operator()(int op, const self& arg) const {
+
+    switch(op)
+    {
+      case '+':  return PyNumber_Add(*this, arg);
+      case '-':  return PyNumber_Subtract(*this, arg);
+      case '*':  return PyNumber_Multiply(*this, arg);
+      case '/':  return PyNumber_Divide(*this, arg);
+      case '^':  return PyNumber_Power(*this, arg, Py_None);
+      case '(':  return check_context(PyObject_CallObject(*this, arg));
+      case '[':  return operator[](arg);
+      case KILLATTR_CMD: return del_attr(arg);
+      case LIST_CMD:     return args2list(arg);
+      case '.': case COLONCOLON: case ATTRIB_CMD: return attr(arg);
+    }
+    return self(NULL);
+  }
+
+  /// Ternary operations
+  self operator()(int op, const self& arg1, const self& arg2) const
+  {
+    switch(op)
+    {
+      case ATTRIB_CMD:
+        if(PyObject_SetAttr(*this, arg1, arg2) == -1) handle_exception();
+        return self();
+    }
+    return self(NULL);
+  }
+
+  /// Get item
+  self operator[](const self& idx) const { return PyObject_GetItem(*this, idx); }
+  self operator[](long idx) const { return operator[](PyInt_FromLong(idx));  }
+
+  /// Get actual PyObject*
+  operator const ptr_type() const { return m_ptr; }
+
+  /// Get representative as C-style string
+  char* repr() const
+  {
+    return omStrDup(PyString_AsString(PyObject_Repr(*this)));
+  }
+
+  /// Extract C-style string
+  char* str() const { return omStrDup(PyString_AsString(*this)); }
+
+  Py_ssize_t size() const { return PyObject_Size(m_ptr); }
+
+  BOOLEAN assign_to(leftv result)
+  {
+    return (m_ptr? (m_ptr == Py_None? none_to(result): python_to(result)): TRUE);
+  }
+
+  void import_as(const char* name) const {
+    idhdl handle = enterid(omStrDup(name), 0, DEF_CMD,
+                           &IDROOT, FALSE);
+
+    if (handle)
+    {
+      IDDATA(handle) = (char*)m_ptr;
+      Py_XINCREF(m_ptr);
+      IDTYP(handle) =  PythonInterpreter::id();
+    }
+    else { Werror("Importing pyobject to Singular failed"); }
+  }
+
+  int compare(int op, const self& arg) const
+  { return PyObject_RichCompareBool(*this, arg, py_opid(op)); }
+
+
+  self attr(const self& arg) const { return PyObject_GetAttr(*this, arg); }
+
+  self del_attr(const self& arg) const
+  {
+    if (!PyObject_HasAttr(*this, arg))
+      Werror("Cannot delete attribute %s.", arg.repr());
+    else
+      PyObject_DelAttr(*this, arg);
+
+    return self();
+  }
+
+protected:
+  self args2list(const self& args) const
+  {
+    self pylist(PyList_New(0));
+    PyList_Append(pylist, *this);
+    if(PyTuple_Check(args))  pylist.append_iter(PyObject_GetIter(args));
+    else PyList_Append(pylist, args);
+
+    return pylist;
+  }
+
+  BOOLEAN handle_exception() const {
+
+    if(!PyErr_Occurred()) return FALSE;
+
+    PyObject *pType, *pMessage, *pTraceback;
+    PyErr_Fetch(&pType, &pMessage, &pTraceback);
+
+    WerrorS("pyobject error occured");
+    WerrorS(PyString_AsString(pMessage));
+
+    Py_XDECREF(pType);
+    Py_XDECREF(pMessage);
+    Py_XDECREF(pTraceback);
+
+    PyErr_Clear();
+    return TRUE;
+  }
+
+  void append_iter(self iterator) {
+    ptr_type item;
+    while ((item = PyIter_Next(iterator))) {
+      PyList_Append(*this, item);
+      Py_DECREF(item);
+    }
+  }
+
+  int py_opid(int op) const{
+    switch(op)
+    {
+      case '<':  return Py_LT;
+      case '>':  return Py_GT;
+      case EQUAL_EQUAL:  return Py_EQ;
+      case NOTEQUAL:  return Py_NE;
+      case GE:  return Py_GE;
+      case LE:  return Py_LE;
+    }
+    return -1;
+  }
+
+private:
+  BOOLEAN none_to(leftv result) const
+  {
+    Py_XDECREF(m_ptr);
+    result->data = NULL;
+    result->rtyp = NONE;
+    return FALSE;
+  }
+
+  BOOLEAN python_to(leftv result) const
+  {
+    result->data = m_ptr;
+    Py_XINCREF(m_ptr);
+    result->rtyp = PythonInterpreter::id();
+    return !m_ptr;
+  }
+
+  /// The actual pointer
+  ptr_type m_ptr;
+};
+
+
+
+/** @class PythonCastStatic
+ * This template class does conversion of Singular objects to python objects on
+ * compile-time.
+ *
+ * @note The Singular objects are assumed to be equivalent to the template argument.
+ **/
+template <class CastType = PythonObject::ptr_type>
+class PythonCastStatic:
+  public PythonObject {
+  typedef PythonCastStatic self;
+public:
+
+  PythonCastStatic(void* value):
+    PythonObject(get(reinterpret_cast<CastType>(value))) {}
+
+  PythonCastStatic(leftv value):
+    PythonObject(get(reinterpret_cast<CastType>(value->Data()))) {}
+
+private:
+  ptr_type get(ptr_type value)       { return value; }
+  ptr_type get(long value)           { return PyInt_FromLong(value); }
+  ptr_type get(int value)            { return PyInt_FromLong((long)value); }
+  ptr_type get(const char* value)    { return PyString_FromString(value); }
+  ptr_type get(char* value) { return get(const_cast<const char*>(value)); }
+  ptr_type get(intvec* value);       // inlined below
+  ptr_type get(lists value);         // inlined after PythonObjectDynamic
+};
+
+template <class CastType>
+inline PythonObject::ptr_type
+PythonCastStatic<CastType>::get(intvec* value)
+{
+  ptr_type pylist(PyList_New(0));
+  for (int idx = 0; idx < value->length(); ++idx)
+    PyList_Append(pylist, self::get((*value)[idx]));
+
+  return pylist;
+}
+
+/** @class PythonCastDynamic
+ * This class does conversion of Singular objects to python objects on runtime.
+ *
+ **/
+class PythonCastDynamic:
+  public PythonObject {
+  typedef PythonCastDynamic self;
+
+public:
+  PythonCastDynamic(leftv value): PythonObject(get(value, value->Typ())) {}
+
+private:
+  PythonObject get(leftv value, int typeId)
+  {
+    if (typeId == PythonInterpreter::id()) return PythonCastStatic<>(value);
+
+    switch (typeId)
+    {
+    case INT_CMD:    return PythonCastStatic<long>(value);
+    case STRING_CMD: return PythonCastStatic<const char*>(value);
+    case LIST_CMD:   return PythonCastStatic<lists>(value);
+    case INTVEC_CMD: return PythonCastStatic<intvec*>(value);
+    }
+
+    sleftv tmp;
+    BOOLEAN newstruct_equal(int, leftv, leftv); // declaring overloaded '='
+    if (!newstruct_equal(PythonInterpreter::id(), &tmp, value))
+      return PythonCastStatic<>(&tmp);
+
+    if (typeId > MAX_TOK)       // custom types
+    {
+      blackbox *bbx = getBlackboxStuff(typeId);
+      assume(bbx != NULL);
+      if (! bbx->blackbox_Op1(PythonInterpreter::id(), &tmp, value))
+        return PythonCastStatic<>(&tmp);
+    }
+
+    Werror("type '%s` incompatible with 'pyobject`", iiTwoOps(typeId));
+    return PythonObject();
+  }
+};
+
+template <class CastType>
+inline PythonObject::ptr_type
+PythonCastStatic<CastType>::get(lists value)
+{
+  ptr_type pylist(PyList_New(0));
+  for (int i = 0; i <= value->nr; ++i)
+    PyList_Append(pylist, PythonCastDynamic((value->m) + i));
+
+  return pylist;
+}
+
+/// Template specialization for getting handling sequence
+template <>
+class PythonCastStatic<PythonObject::sequence_tag>:
+public PythonObject
+{
+public:
+
+  PythonCastStatic(leftv value):
+    PythonObject(PyTuple_New(size(value)))  { append_to(value); }
+
+
+private:
+  size_t size(leftv iter, size_t distance = 0) const
+  {
+    if (iter) { do { ++distance; } while((iter = iter->next)); };
+    return distance;
+  }
+
+  void append_to(leftv iter) const
+  {
+    for(size_t idx = 0; iter != NULL; iter = iter->next)
+      PyTuple_SetItem(*this, idx++, PythonCastDynamic(iter));
+  }
+};
+
+
+PythonObject get_attrib_name(leftv arg)
+{
+  typedef PythonCastStatic<const char*> result_type;
+  if (arg->Typ() == STRING_CMD)
+    return result_type(arg);
+
+  return result_type((void*)arg->Name());
+}
+
+/// Evaluate string in python
+PythonObject python_eval(const char* arg) {
+
+  PyObject* globals = PyModule_GetDict(PyImport_Import(PyString_FromString("__main__")));
+  return PyRun_String(arg, Py_eval_input, globals, globals);
+}
+
+/// Evaluate string in python from Singular
+BOOLEAN python_eval(leftv result, leftv arg) {
+  if ( !arg || (arg->Typ() != STRING_CMD) ) {
+    Werror("expected python_eval('string')");
+    return TRUE;
+  }
+
+  return python_eval(reinterpret_cast<const char*>(arg->Data())).assign_to(result);
+}
+
+
+/// Execute string in python from Singular
+BOOLEAN python_run(leftv result, leftv arg)
+{
+  if ( !arg || (arg->Typ() != STRING_CMD) ) {
+    Werror("expected python_run('string')");
+    return TRUE;
+  }
+
+  PyRun_SimpleString(reinterpret_cast<const char*>(arg->Data()));
+  sync_contexts();
+
+  Py_INCREF(Py_None);
+  return PythonCastStatic<>(Py_None).assign_to(result);
+}
+
+PythonObject names_from_module(const char* module_name)
+{
+  char buffer[strlen(module_name) + 30];
+  sprintf (buffer, "SINGULAR_MODULE_NAME = '%s'", module_name);
+  PyRun_SimpleString(buffer);
+  PyRun_SimpleString("from sys import modules");
+  PyRun_SimpleString("exec('from ' + SINGULAR_MODULE_NAME + ' import *')");
+
+  return python_eval("[str for str in dir(modules[SINGULAR_MODULE_NAME]) if str[0] != '_']");
+}
+
+void from_module_import_all(const char* module_name)
+{
+  char buffer[strlen(module_name) + 20];
+  sprintf (buffer, "from %s import *", module_name);
+  PyRun_SimpleString(buffer);
+}
+
+/// import python module and export identifiers in Singular namespace
+BOOLEAN python_import(leftv result, leftv value) {
+
+  if ((value == NULL) || (value->Typ()!= STRING_CMD)) {
+    Werror("expected python_import('string')");
+    return TRUE;
+  }
+
+  from_module_import_all(reinterpret_cast<const char*>(value->Data()));
+  sync_contexts();
+
+  Py_INCREF(Py_None);
+  return PythonCastStatic<>(Py_None).assign_to(result);
+}
+
+/// blackbox support - initialization
+void* pyobject_Init(blackbox*)
+{
+  Py_INCREF(Py_None);
+  return Py_None;
+}
+
+/// blackbox support - convert to string representation
+char* pyobject_String(blackbox *b, void* ptr)
+{
+  return PythonCastStatic<>(ptr).repr();
+}
+
+/// blackbox support - copy element
+void* pyobject_Copy(blackbox*b, void* ptr)
+{
+    Py_XINCREF(ptr);
+    return ptr;
+}
+
+/// blackbox support - assign element
+BOOLEAN pyobject_Assign(leftv l, leftv r)
+{
+  Py_XDECREF(l->Data());
+  PyObject* result = PythonCastDynamic(r);
+  Py_XINCREF(result);
+
+  if (l->rtyp == IDHDL)
+    IDDATA((idhdl)l->data) = (char *)result;
+  else
+    l->data = (void *)result;
+
+  return !result;
+}
+
+
+/// blackbox support - unary operations
+BOOLEAN pyobject_Op1(int op, leftv res, leftv head)
+{
+  switch(op)
+  {
+    case INT_CMD:               // built-in return types first
+    {
+      long value = PyInt_AsLong(PythonCastStatic<>(head));
+      if( (value == -1) &&  PyErr_Occurred() ) {
+        Werror("'pyobject` cannot be converted to integer");
+        PyErr_Clear();
+        return TRUE;
+      }
+      res->data = (void*) value;
+      res->rtyp = INT_CMD;
+      return FALSE;
+    }
+    case TYPEOF_CMD:
+      res->data = (void*) omStrDup("pyobject");
+      res->rtyp = STRING_CMD;
+      return FALSE;
+  }
+
+  if (!PythonCastStatic<>(head)(op).assign_to(res))
+    return FALSE;
+
+  BOOLEAN newstruct_Op1(int, leftv, leftv); // forward declaration
+  return newstruct_Op1(op, res, head);
+}
+
+
+/// blackbox support - binary operations
+BOOLEAN pyobject_Op2(int op, leftv res, leftv arg1, leftv arg2)
+{
+  PythonCastStatic<> lhs(arg1);
+
+  switch(op)                    // built-in return types and special cases first
+  {
+    case '<': case '>': case EQUAL_EQUAL: case NOTEQUAL: case GE: case LE:
+    {
+      res->data = (void *)(long)(lhs.compare(op, PythonCastDynamic(arg2)));
+      res->rtyp = INT_CMD;
+      return FALSE;
+    }
+    case '.': case COLONCOLON: case ATTRIB_CMD:
+      return lhs.attr(get_attrib_name(arg2)).assign_to(res);
+  }
+
+  PythonCastDynamic rhs(arg2);
+  if (!lhs(op, rhs).assign_to(res))
+    return FALSE;
+
+  BOOLEAN newstruct_Op2(int, leftv, leftv, leftv); // forward declaration
+  return newstruct_Op2(op, res, arg1, arg2);
+
+}
+
+/// blackbox support - ternary operations
+BOOLEAN pyobject_Op3(int op, leftv res, leftv arg1, leftv arg2, leftv arg3)
+{
+  PythonCastStatic<> lhs(arg1);
+  PythonCastDynamic rhs1(arg2);
+  PythonCastDynamic rhs2(arg3);
+
+  if (!lhs(op, rhs1, rhs2).assign_to(res))
+    return FALSE;
+
+  return blackboxDefaultOp3(op, res, arg1, arg2, arg3);
+}
+
+
+/// blackbox support - n-ary operations
+BOOLEAN pyobject_OpM(int op, leftv res, leftv args)
+{
+  switch(op)                    // built-in return types first
+  {
+    case STRING_CMD:
+    {
+      blackbox* a = getBlackboxStuff(args->Typ());
+      res->data = (void *)a->blackbox_String(a, args->Data());
+      res->rtyp = STRING_CMD;
+      return FALSE;
+    }
+
+    case INTVEC_CMD:
+      PythonObject obj = PythonCastStatic<>(args->Data());
+      unsigned long len = obj.size();
+
+      intvec* vec = new intvec(len);
+      for(unsigned long idx = 0; idx != len; ++idx) {
+        long value = PyInt_AsLong(obj[idx]);
+        (*vec)[idx] = static_cast<int>(value);
+
+        if ((value == -1) &&  PyErr_Occurred()) {
+          value = 0;
+          PyErr_Clear();
+        }
+        if (value != long((*vec)[idx])) {
+          delete vec;
+          Werror("'pyobject` cannot be converted to intvec");
+          return TRUE;
+        }
+      }
+      res->data = (void *)vec;
+      res->rtyp = op;
+      return FALSE;
+  }
+  typedef PythonCastStatic<PythonObject::sequence_tag> seq_type;
+  if (! PythonCastStatic<>(args)(op, seq_type(args->next)).assign_to(res))
+    return FALSE;
+
+  BOOLEAN newstruct_OpM(int, leftv, leftv); // forward declaration
+  return newstruct_OpM(op, res, args);
+}
+
+/// blackbox support - destruction
+void pyobject_destroy(blackbox *b, void* ptr)
+{
+  Py_XDECREF(ptr);
+}
+
+PyObject* get_current_definition(const char* name) {
+  idhdl handle =  ggetid(name);
+  if (!handle || (IDTYP(handle) != PythonInterpreter::id()))  return NULL;
+  PythonCastStatic<PyObject*> value(IDDATA(handle));
+  return value;
+}
+
+/// getting stuff from python to Singular namespace
+void sync_contexts()
+{
+  PyRun_SimpleString("_SINGULAR_NEW = modules['__main__'].__dict__.copy()");
+
+  PythonObject newElts = python_eval("[(_k, _e)   \
+    for (_k, _e) in _SINGULAR_NEW.iteritems() \
+    if _k not in _SINGULAR_IMPORTED or not _SINGULAR_IMPORTED[_k] is _e]");
+
+  long len = newElts.size();
+  for (long idx = 0; idx < len; ++idx)
+  {
+    long i = 0;
+    char* name = newElts[idx][i].str();
+    if (name && (*name != '\0') && (*name != '_'))
+    {
+      Py_XDECREF(get_current_definition(name));
+      i = 1;
+      newElts[idx][i].import_as(name);
+    }
+
+  }
+
+  PythonObject deletedElts =
+    python_eval("list(set(_SINGULAR_IMPORTED.iterkeys()) - \
+     set(_SINGULAR_NEW.iterkeys()))");
+  len = deletedElts.size();
+
+  for (long idx = 0; idx < len; ++idx)
+  {
+    char* name = deletedElts[idx].str();
+    if (name && (*name != '\0') && (*name != '_'))
+      killid(name, &IDROOT);
+  }
+
+  PyRun_SimpleString("_SINGULAR_IMPORTED =_SINGULAR_NEW");
+  PyRun_SimpleString("del  _SINGULAR_NEW");
+}
+
+
+
+blackbox* pyobject_blackbox(int& tok) {
+  if(blackboxIsCmd("pyobject", tok) != ROOT_DECL)
+  {
+    tok = setBlackboxStuff((blackbox*)omAlloc0(sizeof(blackbox)),
+			   "pyobject");
+  }
+  return getBlackboxStuff(tok);
+}
+
+
+
+#define PYOBJECT_ADD_C_PROC(name) \
+  psModulFunctions->iiAddCproc((currPack->libname? currPack->libname: ""),\
+     (char*)#name, FALSE, name);
+
+extern "C" int SI_MOD_INIT(pyobject)(SModulFunctions* psModulFunctions)
+{
+  int tok = -1;
+  blackbox* bbx = pyobject_blackbox(tok);
+  if (bbx->blackbox_Init != pyobject_Init)
+  {
+    bbx->blackbox_destroy = pyobject_destroy;
+    bbx->blackbox_String  = pyobject_String;
+    bbx->blackbox_Init    = pyobject_Init;
+    bbx->blackbox_Copy    = pyobject_Copy;
+    bbx->blackbox_Assign  = pyobject_Assign;
+    bbx->blackbox_Op1     = pyobject_Op1;
+    bbx->blackbox_Op2     = pyobject_Op2;
+    bbx->blackbox_Op3     = pyobject_Op3;
+    bbx->blackbox_OpM     = pyobject_OpM;
+    bbx->data             = (void*)omAlloc0(newstruct_desc_size());
+
+    PythonInterpreter::init(tok);
+
+    PYOBJECT_ADD_C_PROC(python_import);
+    PYOBJECT_ADD_C_PROC(python_eval);
+    PYOBJECT_ADD_C_PROC(python_run);
+  }
+  return MAX_TOK;
+}
+#undef PYOBJECT_ADD_C_PROC
+
+#endif /* HAVE_PYTHON */
diff --git a/Singular/dyn_modules/singmathic/Makefile.am b/Singular/dyn_modules/singmathic/Makefile.am
new file mode 100644
index 0000000..420ec2c
--- /dev/null
+++ b/Singular/dyn_modules/singmathic/Makefile.am
@@ -0,0 +1,33 @@
+ACLOCAL_AMFLAGS = -I ../../m4
+
+if SI_BUILTIN_SINGMATHIC
+  noinst_LTLIBRARIES=singmathic.la
+  P_PROCS_CPPFLAGS_COMMON = -DSTATIC_VERSION
+  P_PROCS_MODULE_LDFLAGS  = -module
+else
+  module_LTLIBRARIES=singmathic.la
+  moduledir = $(libexecdir)/singular/MOD
+  P_PROCS_CPPFLAGS_COMMON = -DDYNAMIC_VERSION
+  P_PROCS_MODULE_LDFLAGS = -module -export-dynamic -avoid-version -flat_namespace -weak_reference_mismatches weak -undefined dynamic_lookup
+  # Add under Mac OS X: -flat_namespace -weak_reference_mismatches weak -undefined dynamic_lookup
+endif
+
+MYINCLUDES =  -I${top_srcdir} -I${top_builddir} \
+-I${top_srcdir}/libpolys -I${top_builddir}/libpolys \
+$(FACTORY_INCLUDES) $(RESOURCES_INCLUDES) $(OMALLOC_INCLUDES) \
+$(FLINT_CFLAGS) $(NTL_CFLAGS) $(GMP_CFLAGS)
+
+singmathic_la_SOURCES  = singmathic.cc
+singmathic_la_CPPFLAGS = ${MYINCLUDES} ${P_PROCS_CPPFLAGS_COMMON}
+singmathic_la_LDFLAGS  = ${P_PROCS_MODULE_LDFLAGS}
+
+# AM_COLOR_TESTS=always
+#
+# TESTS_ENVIRONMENT  = SINGULARPATH='${abs_top_builddir}/Singular/LIB:${abs_top_srcdir}/Singular/LIB:${abs_top_builddir}/libpolys/polys/.libs:${abs_top_builddir}/factory/gftables:${abs_builddir}/.libs:${abs_srcdir}'
+# TESTS_ENVIRONMENT += SINGULAR_ROOT_DIR='${abs_top_builddir}'
+# TESTS_ENVIRONMENT += SINGULAR_BIN_DIR='${abs_top_builddir}/Singular'
+#
+# TESTS=test_release.sh
+#
+# EXTRA_DIST = test.sh $(TESTS)
+
diff --git a/Singular/dyn_modules/singmathic/Makefile.in b/Singular/dyn_modules/singmathic/Makefile.in
new file mode 100644
index 0000000..1dc8ccb
--- /dev/null
+++ b/Singular/dyn_modules/singmathic/Makefile.in
@@ -0,0 +1,753 @@
+# Makefile.in generated by automake 1.13.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 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@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+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 = Singular/dyn_modules/singmathic
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/build-aux/depcomp
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_append_compile_flags.m4 \
+	$(top_srcdir)/m4/ax_append_flag.m4 \
+	$(top_srcdir)/m4/ax_append_link_flags.m4 \
+	$(top_srcdir)/m4/ax_check_compile_flag.m4 \
+	$(top_srcdir)/m4/ax_check_link_flag.m4 \
+	$(top_srcdir)/m4/ax_compute_relative_paths.m4 \
+	$(top_srcdir)/m4/ax_normalize_path.m4 \
+	$(top_srcdir)/m4/ax_prefix_config_h.m4 \
+	$(top_srcdir)/m4/ax_pthread.m4 \
+	$(top_srcdir)/m4/ax_python_embed.m4 \
+	$(top_srcdir)/m4/ax_python_with_version.m4 \
+	$(top_srcdir)/m4/cpu-check.m4 $(top_srcdir)/m4/dbm-check.m4 \
+	$(top_srcdir)/m4/flags.m4 $(top_srcdir)/m4/flint-check.m4 \
+	$(top_srcdir)/m4/gfanlib-check.m4 \
+	$(top_srcdir)/m4/gmp-check.m4 \
+	$(top_srcdir)/m4/google-perftools.m4 \
+	$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+	$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+	$(top_srcdir)/m4/lt~obsolete.m4 \
+	$(top_srcdir)/m4/mathic-check.m4 $(top_srcdir)/m4/ntl-check.m4 \
+	$(top_srcdir)/m4/options.m4 $(top_srcdir)/m4/p-procs.m4 \
+	$(top_srcdir)/m4/polymake-check.m4 \
+	$(top_srcdir)/m4/readline-check.m4 $(top_srcdir)/configure.ac
+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__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
+am__installdirs = "$(DESTDIR)$(moduledir)"
+LTLIBRARIES = $(module_LTLIBRARIES) $(noinst_LTLIBRARIES)
+singmathic_la_LIBADD =
+am_singmathic_la_OBJECTS = singmathic_la-singmathic.lo
+singmathic_la_OBJECTS = $(am_singmathic_la_OBJECTS)
+AM_V_lt = $(am__v_lt_ at AM_V@)
+am__v_lt_ = $(am__v_lt_ at AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 = 
+singmathic_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
+	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
+	$(AM_CXXFLAGS) $(CXXFLAGS) $(singmathic_la_LDFLAGS) $(LDFLAGS) \
+	-o $@
+ at SI_BUILTIN_SINGMATHIC_FALSE@am_singmathic_la_rpath = -rpath \
+ at SI_BUILTIN_SINGMATHIC_FALSE@	$(moduledir)
+ at SI_BUILTIN_SINGMATHIC_TRUE@am_singmathic_la_rpath =
+AM_V_P = $(am__v_P_ at AM_V@)
+am__v_P_ = $(am__v_P_ at AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_ at AM_V@)
+am__v_GEN_ = $(am__v_GEN_ at AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_ at AM_V@)
+am__v_at_ = $(am__v_at_ at AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+DEFAULT_INCLUDES = -I. at am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \
+	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+	$(AM_CXXFLAGS) $(CXXFLAGS)
+AM_V_CXX = $(am__v_CXX_ at AM_V@)
+am__v_CXX_ = $(am__v_CXX_ at AM_DEFAULT_V@)
+am__v_CXX_0 = @echo "  CXX     " $@;
+am__v_CXX_1 = 
+CXXLD = $(CXX)
+CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+	$(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CXXLD = $(am__v_CXXLD_ at AM_V@)
+am__v_CXXLD_ = $(am__v_CXXLD_ at AM_DEFAULT_V@)
+am__v_CXXLD_0 = @echo "  CXXLD   " $@;
+am__v_CXXLD_1 = 
+SOURCES = $(singmathic_la_SOURCES)
+DIST_SOURCES = $(singmathic_la_SOURCES)
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BUILTIN_LIBS = @BUILTIN_LIBS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CDDGMPCPPFLAGS = @CDDGMPCPPFLAGS@
+CDDGMPLDFLAGS = @CDDGMPLDFLAGS@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATA_DIR = @DATA_DIR@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DOC_DIR = @DOC_DIR@
+DOXYGEN = @DOXYGEN@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FACTORY_INCLUDES = @FACTORY_INCLUDES@
+FACTORY_LIBS = @FACTORY_LIBS@
+FGREP = @FGREP@
+FLINT_CFLAGS = @FLINT_CFLAGS@
+FLINT_HOME = @FLINT_HOME@
+FLINT_LIBS = @FLINT_LIBS@
+GMP_CFLAGS = @GMP_CFLAGS@
+GMP_HOME = @GMP_HOME@
+GMP_LIBS = @GMP_LIBS@
+GMP_VERSION = @GMP_VERSION@
+GREP = @GREP@
+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@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NTL_CFLAGS = @NTL_CFLAGS@
+NTL_LIBS = @NTL_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OMALLOC_INCLUDES = @OMALLOC_INCLUDES@
+OMALLOC_LIBS = @OMALLOC_LIBS@
+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@
+PKG_REQUIRE = @PKG_REQUIRE@
+PMCONFIG = @PMCONFIG@
+PM_CFLAGS = @PM_CFLAGS@
+PM_INC = @PM_INC@
+PM_LDFLAGS = @PM_LDFLAGS@
+PM_LIBS = @PM_LIBS@
+POLYMAKE_CXXFLAGS = @POLYMAKE_CXXFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LDFLAGS = @PTHREAD_LDFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
+PYTHON = @PYTHON@
+PYTHON_CSPEC = @PYTHON_CSPEC@
+PYTHON_EXECPREFIX = @PYTHON_EXECPREFIX@
+PYTHON_LSPEC = @PYTHON_LSPEC@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+RANLIB = @RANLIB@
+RESOURCES_INCLUDES = @RESOURCES_INCLUDES@
+RESOURCES_LIBS = @RESOURCES_LIBS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SINGULAR_CFLAGS = @SINGULAR_CFLAGS@
+SI_COUNTEDREF_AUTOLOAD = @SI_COUNTEDREF_AUTOLOAD@
+SI_CPU_I386 = @SI_CPU_I386@
+SI_CPU_IA64 = @SI_CPU_IA64@
+SI_CPU_PPC = @SI_CPU_PPC@
+SI_CPU_SPARC = @SI_CPU_SPARC@
+SI_CPU_X86_64 = @SI_CPU_X86_64@
+STRIP = @STRIP@
+USEPPROCSDYNAMICLD = @USEPPROCSDYNAMICLD@
+USEPPROCSDYNAMICLDFLAGS = @USEPPROCSDYNAMICLDFLAGS@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
+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@
+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@
+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@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+ACLOCAL_AMFLAGS = -I ../../m4
+ at SI_BUILTIN_SINGMATHIC_TRUE@noinst_LTLIBRARIES = singmathic.la
+ at SI_BUILTIN_SINGMATHIC_FALSE@P_PROCS_CPPFLAGS_COMMON = -DDYNAMIC_VERSION
+ at SI_BUILTIN_SINGMATHIC_TRUE@P_PROCS_CPPFLAGS_COMMON = -DSTATIC_VERSION
+ at SI_BUILTIN_SINGMATHIC_FALSE@P_PROCS_MODULE_LDFLAGS = -module -export-dynamic -avoid-version -flat_namespace -weak_reference_mismatches weak -undefined dynamic_lookup
+ at SI_BUILTIN_SINGMATHIC_TRUE@P_PROCS_MODULE_LDFLAGS = -module
+ at SI_BUILTIN_SINGMATHIC_FALSE@module_LTLIBRARIES = singmathic.la
+ at SI_BUILTIN_SINGMATHIC_FALSE@moduledir = $(libexecdir)/singular/MOD
+MYINCLUDES = -I${top_srcdir} -I${top_builddir} \
+-I${top_srcdir}/libpolys -I${top_builddir}/libpolys \
+$(FACTORY_INCLUDES) $(RESOURCES_INCLUDES) $(OMALLOC_INCLUDES) \
+$(FLINT_CFLAGS) $(NTL_CFLAGS) $(GMP_CFLAGS)
+
+singmathic_la_SOURCES = singmathic.cc
+singmathic_la_CPPFLAGS = ${MYINCLUDES} ${P_PROCS_CPPFLAGS_COMMON}
+singmathic_la_LDFLAGS = ${P_PROCS_MODULE_LDFLAGS}
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .cc .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) --foreign Singular/dyn_modules/singmathic/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign Singular/dyn_modules/singmathic/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-moduleLTLIBRARIES: $(module_LTLIBRARIES)
+	@$(NORMAL_INSTALL)
+	@list='$(module_LTLIBRARIES)'; test -n "$(moduledir)" || list=; \
+	list2=; for p in $$list; do \
+	  if test -f $$p; then \
+	    list2="$$list2 $$p"; \
+	  else :; fi; \
+	done; \
+	test -z "$$list2" || { \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(moduledir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(moduledir)" || exit 1; \
+	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(moduledir)'"; \
+	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(moduledir)"; \
+	}
+
+uninstall-moduleLTLIBRARIES:
+	@$(NORMAL_UNINSTALL)
+	@list='$(module_LTLIBRARIES)'; test -n "$(moduledir)" || list=; \
+	for p in $$list; do \
+	  $(am__strip_dir) \
+	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(moduledir)/$$f'"; \
+	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(moduledir)/$$f"; \
+	done
+
+clean-moduleLTLIBRARIES:
+	-test -z "$(module_LTLIBRARIES)" || rm -f $(module_LTLIBRARIES)
+	@list='$(module_LTLIBRARIES)'; \
+	locs=`for p in $$list; do echo $$p; done | \
+	      sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+	      sort -u`; \
+	test -z "$$locs" || { \
+	  echo rm -f $${locs}; \
+	  rm -f $${locs}; \
+	}
+
+clean-noinstLTLIBRARIES:
+	-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+	@list='$(noinst_LTLIBRARIES)'; \
+	locs=`for p in $$list; do echo $$p; done | \
+	      sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+	      sort -u`; \
+	test -z "$$locs" || { \
+	  echo rm -f $${locs}; \
+	  rm -f $${locs}; \
+	}
+
+singmathic.la: $(singmathic_la_OBJECTS) $(singmathic_la_DEPENDENCIES) $(EXTRA_singmathic_la_DEPENDENCIES) 
+	$(AM_V_CXXLD)$(singmathic_la_LINK) $(am_singmathic_la_rpath) $(singmathic_la_OBJECTS) $(singmathic_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/singmathic_la-singmathic.Plo at am__quote@
+
+.cc.o:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+ at am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXXCOMPILE) -c -o $@ $<
+
+.cc.obj:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+ at am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.cc.lo:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+ at am__fastdepCXX_TRUE@	$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LTCXXCOMPILE) -c -o $@ $<
+
+singmathic_la-singmathic.lo: singmathic.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(singmathic_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT singmathic_la-singmathic.lo -MD -MP -MF $(DEPDIR)/singmathic_la-singmathic.Tpo -c -o singmathic_la-singmathic.lo `test -f 'singmathic.cc' || echo '$(srcdir)/'`singmathic.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/singmathic_la-singmathic.Tpo $(DEPDIR)/singmathic_la-singmathic.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='singmathic.cc' object='singmathic_la-singmathic.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(singmathic_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o singmathic_la-singmathic.lo `test -f 'singmathic.cc' || echo '$(srcdir)/'`singmathic.cc
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	$(am__define_uniq_tagged_files); \
+	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-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	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"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+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 $(LTLIBRARIES)
+installdirs:
+	for dir in "$(DESTDIR)$(moduledir)"; 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:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+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 clean-moduleLTLIBRARIES \
+	clean-noinstLTLIBRARIES 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-moduleLTLIBRARIES
+
+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: uninstall-moduleLTLIBRARIES
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
+	clean-libtool clean-moduleLTLIBRARIES clean-noinstLTLIBRARIES \
+	cscopelist-am ctags ctags-am 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-moduleLTLIBRARIES 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 tags-am uninstall uninstall-am \
+	uninstall-moduleLTLIBRARIES
+
+ at SI_BUILTIN_SINGMATHIC_FALSE@  # Add under Mac OS X: -flat_namespace -weak_reference_mismatches weak -undefined dynamic_lookup
+
+# AM_COLOR_TESTS=always
+#
+# TESTS_ENVIRONMENT  = SINGULARPATH='${abs_top_builddir}/Singular/LIB:${abs_top_srcdir}/Singular/LIB:${abs_top_builddir}/libpolys/polys/.libs:${abs_top_builddir}/factory/gftables:${abs_builddir}/.libs:${abs_srcdir}'
+# TESTS_ENVIRONMENT += SINGULAR_ROOT_DIR='${abs_top_builddir}'
+# TESTS_ENVIRONMENT += SINGULAR_BIN_DIR='${abs_top_builddir}/Singular'
+#
+# TESTS=test_release.sh
+#
+# EXTRA_DIST = test.sh $(TESTS)
+
+# 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/Singular/dyn_modules/singmathic/singmathic.cc b/Singular/dyn_modules/singmathic/singmathic.cc
new file mode 100644
index 0000000..a895000
--- /dev/null
+++ b/Singular/dyn_modules/singmathic/singmathic.cc
@@ -0,0 +1,564 @@
+#include <kernel/mod2.h>
+
+#ifdef HAVE_MATHICGB
+
+#include <misc/auxiliary.h>
+
+#include <misc/options.h>
+
+#include <kernel/ideals.h>
+#include <kernel/polys.h>
+
+#include <Singular/ipid.h>
+#include <Singular/mod_lib.h>
+
+#include <mathicgb.h>
+
+typedef mgb::GroebnerConfiguration::Coefficient Coefficient;
+typedef mgb::GroebnerConfiguration::VarIndex VarIndex;
+typedef mgb::GroebnerConfiguration::Exponent Exponent;
+typedef mgb::GroebnerConfiguration::BaseOrder BaseOrder;
+
+// Constructs a Singular ideal.
+class MathicToSingStream {
+public:
+  MathicToSingStream(Coefficient modulus, VarIndex varCount):
+    mModulus(modulus),
+    mVarCount(varCount),
+    mPolyCount(0),
+    mTerm(0),
+    mIdeal(0)
+  {}
+
+  ~MathicToSingStream() {deleteIdeal();}
+
+  // Mathic stream interface
+
+  Coefficient modulus() const {return mModulus;}
+  VarIndex varCount() const {return mModulus;}
+
+  void idealBegin(size_t polyCount) {
+    deleteIdeal();
+    mIdeal = idInit(polyCount);
+    mPolyCount = 0;
+  }
+
+  void appendPolynomialBegin(size_t termCount) {}
+
+  void appendTermBegin() {
+    if (mTerm == 0)
+      mTerm = mIdeal->m[mPolyCount] = pInit();
+    else
+      mTerm = mTerm->next = pInit();
+  }
+
+  void appendExponent(VarIndex index, Exponent exponent) {
+    pSetExp(mTerm, index + 1, exponent);
+  }
+
+  void appendTermDone(Coefficient coefficient) {
+    mTerm->coef = reinterpret_cast<number>(coefficient);
+    pSetm(mTerm);
+  }
+
+  void appendPolynomialDone() {
+    ++mPolyCount;
+    mTerm = 0;
+  }
+
+  void idealDone() {}
+
+
+  // Singular interface
+
+  ::ideal takeIdeal() {
+    ::ideal id = mIdeal;
+    mIdeal = 0;
+    return id;
+  }
+
+private:
+  void deleteIdeal() {
+    if (mIdeal != 0) {
+      idDelete(&mIdeal);
+      mIdeal = 0;
+    }
+  }
+
+  const Coefficient mModulus;
+  const VarIndex mVarCount;
+  size_t mPolyCount;
+  poly mTerm;
+  ::ideal mIdeal;
+};
+
+#include <iostream>
+
+bool setOrder(ring r, mgb::GroebnerConfiguration& conf) {
+  const VarIndex varCount = conf.varCount();
+
+  bool didSetComponentBefore = false;
+  mgb::GroebnerConfiguration::BaseOrder baseOrder =
+    mgb::GroebnerConfiguration::RevLexDescendingBaseOrder;
+
+  std::vector<Exponent> gradings;
+  for (int block = 0; r->order[block] != ringorder_no; ++block) {
+    // *** ringorder_no
+
+    const rRingOrder_t type = static_cast<rRingOrder_t>(r->order[block]);
+    if (r->block0[block] < 0 || r->block1[block] < 0) {
+      WerrorS("Unexpected negative block0/block1 in ring.");
+      return false;
+    }
+    const VarIndex block0 = static_cast<VarIndex>(r->block0[block]);
+    const VarIndex block1 = static_cast<VarIndex>(r->block1[block]);
+    const int* const weights = r->wvhdl[block];
+    if (block0 > block1) {
+      WerrorS("Unexpected block0 > block1 in ring.");
+      return false;
+    }
+
+    // *** ringorder_c and ringorder_C
+    if (type == ringorder_c || type == ringorder_C) {
+      if (block0 != 0 || block1 != 0 || weights != 0) {
+        WerrorS("Unexpected non-zero fields on c/C block in ring.");
+        return false;
+      }
+      if (didSetComponentBefore) {
+        WerrorS("Unexpected two c/C blocks in ring.");
+        return false;
+      }
+      didSetComponentBefore = true;
+      if (r->order[block + 1] == ringorder_no) {
+        conf.setComponentBefore
+          (mgb::GroebnerConfiguration::ComponentAfterBaseOrder);
+      } else
+        conf.setComponentBefore(gradings.size() / varCount);
+      conf.setComponentsAscending(type == ringorder_C);
+      continue;
+    }
+    if (block0 == 0 || block1 == 0) {
+      WerrorS("Expected block0 != 0 and block1 != 0 in ring.");
+      return false;
+    }
+    if (block1 > varCount) {
+      // todo: first handle any block types where this is not true
+      WerrorS("Expected block1 <= #vars in ring.");
+      return false;
+    }
+
+    // dim is how many variables this block concerns.
+    const size_t dim = static_cast<size_t>(block1 - block0 + 1);
+
+    // *** single-graded/ungraded lex/revlex orders
+    // a(w): w-graded and that's it
+    // a64(w): w-graded with 64-bit weights (not supported here)
+    //    lp:               lex from  left (descending)
+    //    Dp:  1-graded,    lex from  left (descending)
+    //    Ds: -1-graded,    lex from  left (descending)
+    // Wp(w):  w-graded,    lex from  left (descending)
+    // Ws(w): -w-graded,    lex from  left (descending)
+    //    rp:               lex from right (ascending)
+    //    rs:            revlex from right (descending)
+    //    dp:  1-graded, revlex from right (descending)
+    //    ds: -1-graded, revlex from right (descending)
+    // wp(w):  w-graded, revlex from right (descending)
+    // ws(w): -w-graded, revlex from right (descending)
+    //    ls:            revlex from  left (ascending)
+
+    if (type == ringorder_a64) {
+      WerrorS("Block type a64 not supported for MathicGB interface.");
+      return false;
+    }
+
+    // * handle the single-grading part
+    const bool oneGrading = (type == ringorder_Dp || type == ringorder_dp);
+    const bool minusOneGrading = (type == ringorder_Ds || type == ringorder_ds);
+    const bool wGrading =
+      (type == ringorder_a || type == ringorder_Wp || type == ringorder_wp);
+    const bool minusWGrading = (type == ringorder_ws || type == ringorder_Ws);
+    if (oneGrading || minusOneGrading || wGrading || minusWGrading) {
+      const VarIndex begin = gradings.size();
+      gradings.resize(begin + varCount);
+      if (oneGrading || minusOneGrading) {
+        if (weights != 0) {
+          WerrorS("Expect wvhdl == 0 in Dp/dp/Ds/ds-block in ring.");
+          return false;
+        }
+        const Exponent value = oneGrading ? 1 : -1;
+        for (int var = block0 - 1; var < block1; ++var)
+          gradings[begin + var] = value;
+      } else {
+        if (weights == 0) {
+          WerrorS("Expect wvhdl != 0 in a/Wp/wp/ws/Ws-block in ring.");
+          return false;
+        }
+        if (wGrading) {
+          for (int var = 0; var < dim; ++var)
+            gradings[begin + (block0 - 1) + var] = weights[var];
+        } else {
+          for (int var = 0; var < dim; ++var)
+            gradings[begin + (block0 - 1) + var] = -weights[var];
+        }
+      }
+    }
+    if (type == ringorder_a)
+      continue; // a has only the grading, so we are done already
+
+    // * handle the lex/revlex part
+    const bool lexFromLeft =
+      type == ringorder_lp ||
+      type == ringorder_Dp ||
+      type == ringorder_Ds ||
+      type == ringorder_Wp ||
+      type == ringorder_Ws;
+    const bool lexFromRight = type == ringorder_rp;
+    const bool revlexFromLeft = type == ringorder_ls;
+    const bool revlexFromRight =
+      type == ringorder_rs ||
+      type == ringorder_dp ||
+      type == ringorder_ds ||
+      type == ringorder_wp ||
+      type == ringorder_ws;
+    if (lexFromLeft || lexFromRight || revlexFromLeft || revlexFromRight) {
+      const int next = r->order[block + 1];
+      bool final = next == ringorder_no;
+      if (!final && r->order[block + 2] == ringorder_no)
+        final = next == ringorder_c || next == ringorder_C;
+      if (final) {
+        if (lexFromRight)
+          baseOrder = mgb::GroebnerConfiguration::LexAscendingBaseOrder;
+        else if (revlexFromRight)
+          baseOrder = mgb::GroebnerConfiguration::RevLexDescendingBaseOrder;
+        else if (lexFromLeft)
+          baseOrder = mgb::GroebnerConfiguration::LexDescendingBaseOrder;
+        else
+          baseOrder = mgb::GroebnerConfiguration::RevLexAscendingBaseOrder;
+        continue;
+      }
+
+      const size_t begin = gradings.size();
+      gradings.resize(begin + dim * varCount);
+      const Exponent value = (lexFromLeft || lexFromRight) ? 1 : -1;
+      if (lexFromLeft || revlexFromLeft) {
+        for (size_t row = 0; row < dim; ++row)
+          gradings[begin + row * varCount + (block0 - 1) + row] = value;
+      } else {
+        for (size_t row = 0; row < dim; ++row)
+          gradings[begin + row * varCount + (block1 - 1) - row] = value;
+      }
+      continue;
+    }
+
+    // *** ringorder_M: a square invertible matrix
+    if (type == ringorder_M) {
+      if (weights == 0) {
+        WerrorS("Expected wvhdl != 0 in M-block in ring.");
+        return false;
+      }
+      const size_t begin = gradings.size();
+      gradings.resize(begin + dim * varCount);
+      for (size_t row = 0; row < dim; ++row)
+        for (size_t col = block0 - 1; col < block1; ++col)
+          gradings[begin + row * varCount + col] = weights[row * dim + col];
+      continue;
+    }
+
+    // *** Miscellaneous unsupported or invalid block types
+    if (
+      type == ringorder_s ||
+      type == ringorder_S ||
+      type == ringorder_IS
+    ) {
+      // todo: Consider supporting this later.
+      WerrorS("Schreyer order s/S/IS not supported in MathicGB interface.");
+      return false;
+    }
+    if (type == ringorder_am) {
+      // This block is a Schreyer-like ordering only used in Spielwiese.
+      // todo: Consider supporting it later.
+      WerrorS("Block type am not supported in MathicGB interface");
+      return false;
+    }
+    if (type == ringorder_L) {
+      WerrorS("Invalid L-block found in order of ring.");
+      return false;
+    }
+    if (type == ringorder_aa) {
+      // I don't know what an aa block is supposed to do.
+      WerrorS("aa ordering not supported by the MathicGB interface.");
+      return false;
+    }
+    if (type == ringorder_unspec) {
+      WerrorS("Invalid unspec-block found in order of ring.");
+      return false;
+    }
+    WerrorS("Unknown block type found in order of ring.");
+    return false;
+  }
+
+  if (!didSetComponentBefore) {
+    WerrorS("Expected to find a c/C block in ring.");
+    return false;
+  }
+
+  if (!conf.setMonomialOrder(baseOrder, gradings)) {
+    WerrorS("MathicGB does not support non-global orders.");
+    return false;
+  }
+  return true;
+}
+
+bool prOrderMatrix(ring r) {
+  const int varCount = r->N;
+  mgb::GroebnerConfiguration conf(101, varCount);
+  if (!setOrder(r, conf))
+    return false;
+  const std::vector<Exponent>& gradings = conf.monomialOrder().second;
+  if (gradings.size() % varCount != 0) {
+    WerrorS("Expected matrix to be a multiple of varCount.");
+    return false;
+  }
+  const size_t rowCount = gradings.size() / varCount;
+  std::cout << "Order matrix:\n";
+  for (size_t row = 0; row < rowCount; ++row) {
+    for (size_t col = 0; col < varCount; ++col)
+      std::cerr << ' ' << gradings[row * varCount + col];
+    std::cerr << '\n';
+  }
+  std::cerr
+    << "Base order: "
+    << mgb::GroebnerConfiguration::baseOrderName(conf.monomialOrder().first)
+    << '\n';
+  std::cerr << "Component before: " << conf.componentBefore() << '\n';
+  std::cerr << "Components ascending: " << conf.componentsAscending() << '\n';
+  std::cerr << "Schreyering: " << conf.schreyering() << '\n';
+}
+
+void prOrder(ring r) {
+  std::cout << "Printing order of ring.\n";
+  for (int block = 0; ; ++block) {
+    switch (r->order[block]) {
+    case ringorder_no: // end of blocks
+      return;
+
+    case ringorder_a:
+      std::cout << "a";
+      break;
+
+    case ringorder_a64: ///< for int64 weights
+      std::cout << "a64";
+      break;
+
+    case ringorder_c:
+      std::cout << "c";
+      break;
+
+    case ringorder_C:
+      std::cout << "C";
+      break;
+
+    case ringorder_M:
+      std::cout << "M";
+      break;
+
+    case ringorder_S: ///< S?
+      std::cout << "S";
+      break;
+
+    case ringorder_s: ///< s?
+      std::cout << "s";
+      break;
+
+    case ringorder_lp:
+      std::cout << "lp";
+      break;
+
+    case ringorder_dp:
+      std::cout << "dp";
+      break;
+
+    case ringorder_rp:
+      std::cout << "rp";
+      break;
+
+    case ringorder_Dp:
+      std::cout << "Dp";
+      break;
+
+    case ringorder_wp:
+      std::cout << "wp";
+      break;
+
+    case ringorder_Wp:
+      std::cout << "Wp";
+      break;
+
+    case ringorder_ls:
+      std::cout << "ls"; // not global
+      break;
+
+    case ringorder_ds:
+      std::cout << "ds"; // not global
+      break;
+
+    case ringorder_Ds:
+      std::cout << "Ds"; // not global
+      break;
+
+    case ringorder_ws:
+      std::cout << "ws"; // not global
+      break;
+
+    case ringorder_Ws:
+      std::cout << "Ws"; // not global
+      break;
+
+    case ringorder_am:
+      std::cout << "am";
+      break;
+
+    case ringorder_L:
+      std::cout << "L";
+      break;
+
+    // the following are only used internally
+    case ringorder_aa: ///< for idElimination, like a, except pFDeg, pWeigths ignore it
+      std::cout << "aa";
+      break;
+
+    case ringorder_rs: ///< opposite of ls
+      std::cout << "rs";
+      break;
+
+    case ringorder_IS: ///< Induced (Schreyer) ordering
+      std::cout << "IS";
+      break;
+
+    case ringorder_unspec:
+      std::cout << "unspec";
+      break;
+    }
+    const int b0 = r->block0[block];
+    const int b1 = r->block1[block];
+    std::cout << ' ' << b0 << ':' << b1 << " (" << r->wvhdl[block] << ")" << std::flush;
+    if (r->wvhdl[block] != 0 && b0 != 0) {
+      for (int v = 0; v <= b1 - b0; ++v)
+        std::cout << ' ' << r->wvhdl[block][v];
+    } else
+      std::cout << " null";
+    std::cout << '\n';
+  }
+}
+
+BOOLEAN prOrderX(leftv result, leftv arg) {
+  if (currRing == 0) {
+    WerrorS("There is no current ring.");
+    return TRUE;
+  }
+  prOrder(currRing);
+  prOrderMatrix(currRing);
+  result->rtyp=NONE;
+  return FALSE;
+}
+
+BOOLEAN setRingGlobal(leftv result, leftv arg) {
+  currRing->OrdSgn = 1;
+  result->rtyp=NONE;
+  return FALSE;
+}
+
+BOOLEAN mathicgb(leftv result, leftv arg)
+{
+  result->rtyp=NONE;
+
+  if (arg == NULL || arg->next != NULL || arg->Typ() != IDEAL_CMD) {
+    WerrorS("Syntax: mathicgb(<ideal>)");
+    return TRUE;
+  }
+  if (!rField_is_Zp(currRing)) {
+    WerrorS("Polynomial ring must be over Zp.");
+    return TRUE;
+  }
+
+  const int characteristic = n_GetChar(currRing);
+  const int varCount = currRing->N;
+  mgb::GroebnerConfiguration conf(characteristic, varCount);
+  if (!setOrder(currRing, conf))
+    return TRUE;
+  if (TEST_OPT_PROT)
+    conf.setLogging("all");
+
+  mgb::GroebnerInputIdealStream toMathic(conf);
+
+  const ideal id = static_cast<const ideal>(arg->Data());
+  const int size = IDELEMS(id);
+  toMathic.idealBegin(size);
+  for (int i = 0; i < size; ++i) {
+    const poly origP = id->m[i];
+    int termCount = 0;
+    for (poly p = origP; p != 0; p = pNext(p))
+      ++termCount;
+    toMathic.appendPolynomialBegin(termCount);
+
+    for (poly p = origP; p != 0; p = pNext(p)) {
+      toMathic.appendTermBegin();
+      for (int i = 1; i <= currRing->N; ++i)
+        toMathic.appendExponent(i - 1, pGetExp(p, i));
+      const long coefLong = reinterpret_cast<long>(pGetCoeff(p));
+      toMathic.appendTermDone(static_cast<int>(coefLong));
+    }
+    toMathic.appendPolynomialDone();
+  }
+  toMathic.idealDone();
+
+  MathicToSingStream fromMathic(characteristic, varCount);
+  mgb::computeGroebnerBasis(toMathic, fromMathic);
+
+  result->rtyp=IDEAL_CMD;
+  result->data = fromMathic.takeIdeal();
+  return FALSE;
+}
+
+template class std::vector<Exponent>;
+template void mgb::computeGroebnerBasis<MathicToSingStream>
+  (mgb::GroebnerInputIdealStream&, MathicToSingStream&);
+
+int SI_MOD_INIT(singmathic)(SModulFunctions* psModulFunctions)
+{
+  PrintS("Initializing Singular-Mathic interface Singmathic.\n");
+  psModulFunctions->iiAddCproc(
+    (currPack->libname ? currPack->libname : ""),
+    "mathicgb",
+    FALSE,
+    mathicgb
+  );
+  psModulFunctions->iiAddCproc(
+    (currPack->libname ? currPack->libname : ""),
+    "mathicgb_prOrder",
+    FALSE,
+    prOrderX
+  );
+  psModulFunctions->iiAddCproc(
+    (currPack->libname ? currPack->libname : ""),
+    "mathicgb_setRingGlobal",
+    FALSE,
+    setRingGlobal
+  );
+  return MAX_TOK;
+}
+
+/* #else
+
+int SI_MOD_INIT(singmathic)(SModulFunctions* psModulFunctions)
+{
+  WerrorS(
+    "Cannot initialize the Singular interface to MathicGB "
+    "as this Singular executable was built without support "
+    "for MathicGB."
+  );
+  return 1;
+}
+*/
+
+#endif /* HAVE_MATHICGB */
diff --git a/Singular/dyn_modules/staticdemo/Makefile.am b/Singular/dyn_modules/staticdemo/Makefile.am
new file mode 100644
index 0000000..07dcace
--- /dev/null
+++ b/Singular/dyn_modules/staticdemo/Makefile.am
@@ -0,0 +1,19 @@
+ACLOCAL_AMFLAGS = -I ../../m4
+
+if SI_BUILTIN_STATICDEMO
+  noinst_LTLIBRARIES=staticdemo.la
+  P_PROCS_MODULE_LDFLAGS = -module
+  P_PROCS_CPPFLAGS_COMMON = -DSTATIC_VERSION
+
+  MYINCLUDES =  -I${top_srcdir} -I${top_builddir} \
+      -I${top_srcdir}/libpolys -I${top_builddir}/libpolys \
+      $(FACTORY_INCLUDES) $(RESOURCES_INCLUDES) $(OMALLOC_INCLUDES) \
+      $(FLINT_CFLAGS) $(NTL_CFLAGS) $(GMP_CFLAGS) $(GOOGLE_PERFTOOLS_CFLAGS)
+
+  staticdemo_la_SOURCES   = staticdemo.cc
+  staticdemo_la_CPPFLAGS  = ${MYINCLUDES} ${P_PROCS_CPPFLAGS_COMMON}
+  staticdemo_la_LDFLAGS   = ${AM_LDFLAGS} ${P_PROCS_MODULE_LDFLAGS}
+else
+  EXTRA_DIST=staticdemo.cc
+endif
+
diff --git a/Singular/dyn_modules/staticdemo/Makefile.in b/Singular/dyn_modules/staticdemo/Makefile.in
new file mode 100644
index 0000000..ac4b288
--- /dev/null
+++ b/Singular/dyn_modules/staticdemo/Makefile.in
@@ -0,0 +1,671 @@
+# Makefile.in generated by automake 1.13.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 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@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+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 = Singular/dyn_modules/staticdemo
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/build-aux/depcomp
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_append_compile_flags.m4 \
+	$(top_srcdir)/m4/ax_append_flag.m4 \
+	$(top_srcdir)/m4/ax_append_link_flags.m4 \
+	$(top_srcdir)/m4/ax_check_compile_flag.m4 \
+	$(top_srcdir)/m4/ax_check_link_flag.m4 \
+	$(top_srcdir)/m4/ax_compute_relative_paths.m4 \
+	$(top_srcdir)/m4/ax_normalize_path.m4 \
+	$(top_srcdir)/m4/ax_prefix_config_h.m4 \
+	$(top_srcdir)/m4/ax_pthread.m4 \
+	$(top_srcdir)/m4/ax_python_embed.m4 \
+	$(top_srcdir)/m4/ax_python_with_version.m4 \
+	$(top_srcdir)/m4/cpu-check.m4 $(top_srcdir)/m4/dbm-check.m4 \
+	$(top_srcdir)/m4/flags.m4 $(top_srcdir)/m4/flint-check.m4 \
+	$(top_srcdir)/m4/gfanlib-check.m4 \
+	$(top_srcdir)/m4/gmp-check.m4 \
+	$(top_srcdir)/m4/google-perftools.m4 \
+	$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+	$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+	$(top_srcdir)/m4/lt~obsolete.m4 \
+	$(top_srcdir)/m4/mathic-check.m4 $(top_srcdir)/m4/ntl-check.m4 \
+	$(top_srcdir)/m4/options.m4 $(top_srcdir)/m4/p-procs.m4 \
+	$(top_srcdir)/m4/polymake-check.m4 \
+	$(top_srcdir)/m4/readline-check.m4 $(top_srcdir)/configure.ac
+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 =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+staticdemo_la_LIBADD =
+am__staticdemo_la_SOURCES_DIST = staticdemo.cc
+ at SI_BUILTIN_STATICDEMO_TRUE@am_staticdemo_la_OBJECTS =  \
+ at SI_BUILTIN_STATICDEMO_TRUE@	staticdemo_la-staticdemo.lo
+staticdemo_la_OBJECTS = $(am_staticdemo_la_OBJECTS)
+AM_V_lt = $(am__v_lt_ at AM_V@)
+am__v_lt_ = $(am__v_lt_ at AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 = 
+staticdemo_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
+	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
+	$(AM_CXXFLAGS) $(CXXFLAGS) $(staticdemo_la_LDFLAGS) $(LDFLAGS) \
+	-o $@
+ at SI_BUILTIN_STATICDEMO_TRUE@am_staticdemo_la_rpath =
+AM_V_P = $(am__v_P_ at AM_V@)
+am__v_P_ = $(am__v_P_ at AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_ at AM_V@)
+am__v_GEN_ = $(am__v_GEN_ at AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_ at AM_V@)
+am__v_at_ = $(am__v_at_ at AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+DEFAULT_INCLUDES = -I. at am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \
+	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+	$(AM_CXXFLAGS) $(CXXFLAGS)
+AM_V_CXX = $(am__v_CXX_ at AM_V@)
+am__v_CXX_ = $(am__v_CXX_ at AM_DEFAULT_V@)
+am__v_CXX_0 = @echo "  CXX     " $@;
+am__v_CXX_1 = 
+CXXLD = $(CXX)
+CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+	$(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CXXLD = $(am__v_CXXLD_ at AM_V@)
+am__v_CXXLD_ = $(am__v_CXXLD_ at AM_DEFAULT_V@)
+am__v_CXXLD_0 = @echo "  CXXLD   " $@;
+am__v_CXXLD_1 = 
+SOURCES = $(staticdemo_la_SOURCES)
+DIST_SOURCES = $(am__staticdemo_la_SOURCES_DIST)
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BUILTIN_LIBS = @BUILTIN_LIBS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CDDGMPCPPFLAGS = @CDDGMPCPPFLAGS@
+CDDGMPLDFLAGS = @CDDGMPLDFLAGS@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATA_DIR = @DATA_DIR@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DOC_DIR = @DOC_DIR@
+DOXYGEN = @DOXYGEN@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FACTORY_INCLUDES = @FACTORY_INCLUDES@
+FACTORY_LIBS = @FACTORY_LIBS@
+FGREP = @FGREP@
+FLINT_CFLAGS = @FLINT_CFLAGS@
+FLINT_HOME = @FLINT_HOME@
+FLINT_LIBS = @FLINT_LIBS@
+GMP_CFLAGS = @GMP_CFLAGS@
+GMP_HOME = @GMP_HOME@
+GMP_LIBS = @GMP_LIBS@
+GMP_VERSION = @GMP_VERSION@
+GREP = @GREP@
+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@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NTL_CFLAGS = @NTL_CFLAGS@
+NTL_LIBS = @NTL_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OMALLOC_INCLUDES = @OMALLOC_INCLUDES@
+OMALLOC_LIBS = @OMALLOC_LIBS@
+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@
+PKG_REQUIRE = @PKG_REQUIRE@
+PMCONFIG = @PMCONFIG@
+PM_CFLAGS = @PM_CFLAGS@
+PM_INC = @PM_INC@
+PM_LDFLAGS = @PM_LDFLAGS@
+PM_LIBS = @PM_LIBS@
+POLYMAKE_CXXFLAGS = @POLYMAKE_CXXFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LDFLAGS = @PTHREAD_LDFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
+PYTHON = @PYTHON@
+PYTHON_CSPEC = @PYTHON_CSPEC@
+PYTHON_EXECPREFIX = @PYTHON_EXECPREFIX@
+PYTHON_LSPEC = @PYTHON_LSPEC@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+RANLIB = @RANLIB@
+RESOURCES_INCLUDES = @RESOURCES_INCLUDES@
+RESOURCES_LIBS = @RESOURCES_LIBS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SINGULAR_CFLAGS = @SINGULAR_CFLAGS@
+SI_COUNTEDREF_AUTOLOAD = @SI_COUNTEDREF_AUTOLOAD@
+SI_CPU_I386 = @SI_CPU_I386@
+SI_CPU_IA64 = @SI_CPU_IA64@
+SI_CPU_PPC = @SI_CPU_PPC@
+SI_CPU_SPARC = @SI_CPU_SPARC@
+SI_CPU_X86_64 = @SI_CPU_X86_64@
+STRIP = @STRIP@
+USEPPROCSDYNAMICLD = @USEPPROCSDYNAMICLD@
+USEPPROCSDYNAMICLDFLAGS = @USEPPROCSDYNAMICLDFLAGS@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
+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@
+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@
+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@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+ACLOCAL_AMFLAGS = -I ../../m4
+ at SI_BUILTIN_STATICDEMO_TRUE@noinst_LTLIBRARIES = staticdemo.la
+ at SI_BUILTIN_STATICDEMO_TRUE@P_PROCS_MODULE_LDFLAGS = -module
+ at SI_BUILTIN_STATICDEMO_TRUE@P_PROCS_CPPFLAGS_COMMON = -DSTATIC_VERSION
+ at SI_BUILTIN_STATICDEMO_TRUE@MYINCLUDES = -I${top_srcdir} -I${top_builddir} \
+ at SI_BUILTIN_STATICDEMO_TRUE@      -I${top_srcdir}/libpolys -I${top_builddir}/libpolys \
+ at SI_BUILTIN_STATICDEMO_TRUE@      $(FACTORY_INCLUDES) $(RESOURCES_INCLUDES) $(OMALLOC_INCLUDES) \
+ at SI_BUILTIN_STATICDEMO_TRUE@      $(FLINT_CFLAGS) $(NTL_CFLAGS) $(GMP_CFLAGS) $(GOOGLE_PERFTOOLS_CFLAGS)
+
+ at SI_BUILTIN_STATICDEMO_TRUE@staticdemo_la_SOURCES = staticdemo.cc
+ at SI_BUILTIN_STATICDEMO_TRUE@staticdemo_la_CPPFLAGS = ${MYINCLUDES} ${P_PROCS_CPPFLAGS_COMMON}
+ at SI_BUILTIN_STATICDEMO_TRUE@staticdemo_la_LDFLAGS = ${AM_LDFLAGS} ${P_PROCS_MODULE_LDFLAGS}
+ at SI_BUILTIN_STATICDEMO_FALSE@EXTRA_DIST = staticdemo.cc
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .cc .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) --foreign Singular/dyn_modules/staticdemo/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign Singular/dyn_modules/staticdemo/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-noinstLTLIBRARIES:
+	-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+	@list='$(noinst_LTLIBRARIES)'; \
+	locs=`for p in $$list; do echo $$p; done | \
+	      sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+	      sort -u`; \
+	test -z "$$locs" || { \
+	  echo rm -f $${locs}; \
+	  rm -f $${locs}; \
+	}
+
+staticdemo.la: $(staticdemo_la_OBJECTS) $(staticdemo_la_DEPENDENCIES) $(EXTRA_staticdemo_la_DEPENDENCIES) 
+	$(AM_V_CXXLD)$(staticdemo_la_LINK) $(am_staticdemo_la_rpath) $(staticdemo_la_OBJECTS) $(staticdemo_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/staticdemo_la-staticdemo.Plo at am__quote@
+
+.cc.o:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+ at am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXXCOMPILE) -c -o $@ $<
+
+.cc.obj:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+ at am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.cc.lo:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+ at am__fastdepCXX_TRUE@	$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LTCXXCOMPILE) -c -o $@ $<
+
+staticdemo_la-staticdemo.lo: staticdemo.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(staticdemo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT staticdemo_la-staticdemo.lo -MD -MP -MF $(DEPDIR)/staticdemo_la-staticdemo.Tpo -c -o staticdemo_la-staticdemo.lo `test -f 'staticdemo.cc' || echo '$(srcdir)/'`staticdemo.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/staticdemo_la-staticdemo.Tpo $(DEPDIR)/staticdemo_la-staticdemo.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='staticdemo.cc' object='staticdemo_la-staticdemo.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(staticdemo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o staticdemo_la-staticdemo.lo `test -f 'staticdemo.cc' || echo '$(srcdir)/'`staticdemo.cc
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	$(am__define_uniq_tagged_files); \
+	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-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	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"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+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 $(LTLIBRARIES)
+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:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+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 clean-noinstLTLIBRARIES \
+	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 TAGS all all-am check check-am clean clean-generic \
+	clean-libtool clean-noinstLTLIBRARIES cscopelist-am ctags \
+	ctags-am 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 tags-am uninstall uninstall-am
+
+
+# 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/Singular/dyn_modules/staticdemo/staticdemo.cc b/Singular/dyn_modules/staticdemo/staticdemo.cc
new file mode 100644
index 0000000..6d36d3b
--- /dev/null
+++ b/Singular/dyn_modules/staticdemo/staticdemo.cc
@@ -0,0 +1,15 @@
+#include <kernel/mod2.h>
+
+#include <Singular/mod_lib.h>
+#include <Singular/tok.h>
+
+class SModulFunctions;
+
+#ifndef STATIC_VERSION
+# error This is a demo static module. It is not supposed to be built dynamically...
+#endif
+
+#include <reporter/reporter.h>
+
+extern "C" int SI_MOD_INIT(staticdemo)(SModulFunctions*){ PrintS("init of staticdemo\n"); return (MAX_TOK); }
+
diff --git a/Singular/dyn_modules/syzextra/DebugPrint.cc b/Singular/dyn_modules/syzextra/DebugPrint.cc
new file mode 100644
index 0000000..e5a8c77
--- /dev/null
+++ b/Singular/dyn_modules/syzextra/DebugPrint.cc
@@ -0,0 +1,106 @@
+// -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+/*****************************************************************************\
+ * Computer Algebra System SINGULAR
+\*****************************************************************************/
+/** @file DebugPrint.cc
+ *
+ * Here we implement dPrint-s.
+ *
+ * ABSTRACT: debug-detailed-printing
+ *
+ * @author Oleksandr Motsak
+ *
+ *
+ **/
+/*****************************************************************************/
+
+
+
+
+
+// include header file
+#include <kernel/mod2.h>
+
+#include "DebugPrint.h"
+
+#include <omalloc/omalloc.h>
+#include <polys/monomials/p_polys.h>
+
+#include <kernel/ideals.h>
+
+
+
+BEGIN_NAMESPACE()
+/// debug-print monomial poly/vector p, assuming that it lives in the ring R
+static inline void m_DebugPrint(const poly p, const ring R)
+{
+  Print("\nexp[0..%d]\n", R->ExpL_Size - 1);
+  for(int i = 0; i < R->ExpL_Size; i++)
+    Print("%09lx ", p->exp[i]);
+  PrintLn();
+  Print("v0:%9ld ", p_GetComp(p, R));
+  for(int i = 1; i <= R->N; i++) Print(" v%d:%5ld",i, p_GetExp(p, i, R));
+  PrintLn();
+}
+END_NAMESPACE
+
+BEGIN_NAMESPACE_SINGULARXX    BEGIN_NAMESPACE(DEBUG)
+
+// debug-print at most nTerms (2 by default) terms from poly/vector p,
+// assuming that lt(p) lives in lmRing and tail(p) lives in tailRing.
+void dPrint(const poly p, const ring lmRing, const ring tailRing, const int nTerms)
+{
+  assume( nTerms >= 0 );
+  if( p != NULL )
+  {
+    assume( p != NULL );
+
+    p_Write(p, lmRing, tailRing);
+
+    if( (p != NULL) && (nTerms > 0) )
+    {
+      assume( p != NULL );
+      assume( nTerms > 0 );
+
+      // debug pring leading term
+      m_DebugPrint(p, lmRing);
+
+      poly q = pNext(p); // q = tail(p)
+
+      // debug pring tail (at most nTerms-1 terms from it)
+      for(int j = nTerms - 1; (q !=NULL) && (j > 0); pIter(q), --j)
+        m_DebugPrint(q, tailRing);
+
+      if (q != NULL)
+        PrintS("...\n");
+    }
+  }
+  else
+    PrintS("0\n");
+}
+
+// output an ideal
+void dPrint(const ideal id, const ring lmRing, const ring tailRing, const int nTerms)
+{
+  assume( nTerms >= 0 );
+
+  if( id == NULL )
+    PrintS("(NULL)");
+  else
+  {
+    Print("Module of rank %ld,real rank %ld and %d generators.\n",
+          id->rank,id_RankFreeModule(id, lmRing, tailRing),IDELEMS(id));
+
+    int j = (id->ncols*id->nrows) - 1;
+    while ((j > 0) && (id->m[j]==NULL)) j--;
+    for (int i = 0; i <= j; i++)
+    {
+      Print("generator %d: ",i); dPrint(id->m[i], lmRing, tailRing, nTerms);
+    }
+  }
+}
+
+END_NAMESPACE               END_NAMESPACE_SINGULARXX
+
+
+// Vi-modeline: vim: filetype=c:syntax:shiftwidth=2:tabstop=8:textwidth=0:expandtab
diff --git a/Singular/dyn_modules/syzextra/DebugPrint.h b/Singular/dyn_modules/syzextra/DebugPrint.h
new file mode 100644
index 0000000..6d064e2
--- /dev/null
+++ b/Singular/dyn_modules/syzextra/DebugPrint.h
@@ -0,0 +1,41 @@
+// -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+/*****************************************************************************\
+ * Computer Algebra System SINGULAR
+\*****************************************************************************/
+/** @file DebugPrint.h
+ *
+ * Detailed print for debugging
+ *
+ * ABSTRACT: dPrint outputs as much info as possible
+ *
+ * @author Oleksandr Motsak
+ *
+ *
+ **/
+/*****************************************************************************/
+
+#ifndef DEBUGPRINT_H
+#define DEBUGPRINT_H
+
+// include basic definitions
+#include "singularxx_defs.h"
+#include <kernel/polys.h>
+
+BEGIN_NAMESPACE_SINGULARXX    BEGIN_NAMESPACE(DEBUG)
+
+
+
+/// debug-print at most nTerms (2 by default) terms from poly/vector p,
+/// assuming that lt(p) lives in lmRing and tail(p) lives in tailRing.
+void dPrint(const poly p, const ring lmRing = currRing, const ring tailRing = currRing, const int nTerms = 2);
+
+/// prints an ideal, optionally with details
+void dPrint(const ideal id, const ring lmRing = currRing, const ring tailRing = currRing, const int nTerms = 0);
+
+END_NAMESPACE               END_NAMESPACE_SINGULARXX
+
+#endif
+/* #ifndef DEBUGPRINT_H */
+
+// Vi-modeline: vim: filetype=c:syntax:shiftwidth=2:tabstop=8:textwidth=0:expandtab
+
diff --git a/Singular/dyn_modules/syzextra/Makefile.am b/Singular/dyn_modules/syzextra/Makefile.am
new file mode 100644
index 0000000..facd2a5
--- /dev/null
+++ b/Singular/dyn_modules/syzextra/Makefile.am
@@ -0,0 +1,36 @@
+ACLOCAL_AMFLAGS = -I ../../m4
+
+MYINCLUDES =  -I${top_srcdir} -I${top_builddir} \
+-I${top_srcdir}/libpolys -I${top_builddir}/libpolys \
+$(FACTORY_INCLUDES) $(RESOURCES_INCLUDES) $(OMALLOC_INCLUDES) \
+$(FLINT_CFLAGS) $(NTL_CFLAGS) $(GMP_CFLAGS) $(GOOGLE_PERFTOOLS_CFLAGS)
+
+if SI_BUILTIN_SYZEXTRA
+  noinst_LTLIBRARIES=syzextra.la
+  P_PROCS_CPPFLAGS_COMMON = -DSTATIC_VERSION
+  P_PROCS_MODULE_LDFLAGS = -module
+else
+  module_LTLIBRARIES=syzextra.la
+  moduledir = $(libexecdir)/singular/MOD
+  P_PROCS_CPPFLAGS_COMMON = -DDYNAMIC_VERSION
+# Add under Mac OS X: -flat_namespace -weak_reference_mismatches weak -undefined dynamic_lookup
+  P_PROCS_MODULE_LDFLAGS = -module -export-dynamic -avoid-version -flat_namespace -weak_reference_mismatches weak -undefined dynamic_lookup
+endif
+
+SOURCES = mod_main.cc DebugPrint.cc DebugPrint.h myNF.cc myNF.h singularxx_defs.h syzextra.cc syzextra.h
+syzextra_la_SOURCES   = $(SOURCES)
+syzextra_la_CPPFLAGS  = ${MYINCLUDES} ${P_PROCS_CPPFLAGS_COMMON}
+syzextra_la_LDFLAGS   = ${AM_LDFLAGS} ${P_PROCS_MODULE_LDFLAGS} ${GOOGLE_PERFTOOL_LDFLAGS}
+
+AM_COLOR_TESTS=always
+
+TESTS_ENVIRONMENT  = SINGULARPATH='${abs_top_builddir}/Singular/LIB:${abs_top_srcdir}/Singular/LIB:${abs_top_builddir}/libpolys/polys/.libs:${abs_top_builddir}/factory/gftables:${abs_builddir}/.libs:${abs_srcdir}'
+TESTS_ENVIRONMENT += SINGULAR_ROOT_DIR='${abs_top_builddir}'
+TESTS_ENVIRONMENT += SINGULAR_BIN_DIR='${abs_top_builddir}/Singular'
+
+TESTS=test_release.sh
+
+EXTRA_DIST = test.sh $(TESTS)
+# syzextra.tst ederc.tst test_clear_enum.tst
+
+CLEANFILES = SimpleTests.json
diff --git a/Singular/dyn_modules/syzextra/Makefile.in b/Singular/dyn_modules/syzextra/Makefile.in
new file mode 100644
index 0000000..db68b78
--- /dev/null
+++ b/Singular/dyn_modules/syzextra/Makefile.in
@@ -0,0 +1,1139 @@
+# Makefile.in generated by automake 1.13.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 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@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+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 = Singular/dyn_modules/syzextra
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/build-aux/depcomp \
+	$(top_srcdir)/build-aux/test-driver
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_append_compile_flags.m4 \
+	$(top_srcdir)/m4/ax_append_flag.m4 \
+	$(top_srcdir)/m4/ax_append_link_flags.m4 \
+	$(top_srcdir)/m4/ax_check_compile_flag.m4 \
+	$(top_srcdir)/m4/ax_check_link_flag.m4 \
+	$(top_srcdir)/m4/ax_compute_relative_paths.m4 \
+	$(top_srcdir)/m4/ax_normalize_path.m4 \
+	$(top_srcdir)/m4/ax_prefix_config_h.m4 \
+	$(top_srcdir)/m4/ax_pthread.m4 \
+	$(top_srcdir)/m4/ax_python_embed.m4 \
+	$(top_srcdir)/m4/ax_python_with_version.m4 \
+	$(top_srcdir)/m4/cpu-check.m4 $(top_srcdir)/m4/dbm-check.m4 \
+	$(top_srcdir)/m4/flags.m4 $(top_srcdir)/m4/flint-check.m4 \
+	$(top_srcdir)/m4/gfanlib-check.m4 \
+	$(top_srcdir)/m4/gmp-check.m4 \
+	$(top_srcdir)/m4/google-perftools.m4 \
+	$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+	$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+	$(top_srcdir)/m4/lt~obsolete.m4 \
+	$(top_srcdir)/m4/mathic-check.m4 $(top_srcdir)/m4/ntl-check.m4 \
+	$(top_srcdir)/m4/options.m4 $(top_srcdir)/m4/p-procs.m4 \
+	$(top_srcdir)/m4/polymake-check.m4 \
+	$(top_srcdir)/m4/readline-check.m4 $(top_srcdir)/configure.ac
+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__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
+am__installdirs = "$(DESTDIR)$(moduledir)"
+LTLIBRARIES = $(module_LTLIBRARIES) $(noinst_LTLIBRARIES)
+syzextra_la_LIBADD =
+am__objects_1 = syzextra_la-mod_main.lo syzextra_la-DebugPrint.lo \
+	syzextra_la-myNF.lo syzextra_la-syzextra.lo
+am_syzextra_la_OBJECTS = $(am__objects_1)
+syzextra_la_OBJECTS = $(am_syzextra_la_OBJECTS)
+AM_V_lt = $(am__v_lt_ at AM_V@)
+am__v_lt_ = $(am__v_lt_ at AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 = 
+syzextra_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+	$(CXXFLAGS) $(syzextra_la_LDFLAGS) $(LDFLAGS) -o $@
+ at SI_BUILTIN_SYZEXTRA_FALSE@am_syzextra_la_rpath = -rpath $(moduledir)
+ at SI_BUILTIN_SYZEXTRA_TRUE@am_syzextra_la_rpath =
+AM_V_P = $(am__v_P_ at AM_V@)
+am__v_P_ = $(am__v_P_ at AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_ at AM_V@)
+am__v_GEN_ = $(am__v_GEN_ at AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_ at AM_V@)
+am__v_at_ = $(am__v_at_ at AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+DEFAULT_INCLUDES = -I. at am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \
+	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+	$(AM_CXXFLAGS) $(CXXFLAGS)
+AM_V_CXX = $(am__v_CXX_ at AM_V@)
+am__v_CXX_ = $(am__v_CXX_ at AM_DEFAULT_V@)
+am__v_CXX_0 = @echo "  CXX     " $@;
+am__v_CXX_1 = 
+CXXLD = $(CXX)
+CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+	$(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CXXLD = $(am__v_CXXLD_ at AM_V@)
+am__v_CXXLD_ = $(am__v_CXXLD_ at AM_DEFAULT_V@)
+am__v_CXXLD_0 = @echo "  CXXLD   " $@;
+am__v_CXXLD_1 = 
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+	$(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_ at AM_V@)
+am__v_CC_ = $(am__v_CC_ at AM_DEFAULT_V@)
+am__v_CC_0 = @echo "  CC      " $@;
+am__v_CC_1 = 
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+	$(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_ at AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_ at AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo "  CCLD    " $@;
+am__v_CCLD_1 = 
+DIST_SOURCES = $(syzextra_la_SOURCES)
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors_dummy = \
+  mgn= red= grn= lgn= blu= brg= std=; \
+  am__color_tests=no
+am__tty_colors = { \
+  $(am__tty_colors_dummy); \
+  if test "X$(AM_COLOR_TESTS)" = Xno; then \
+    am__color_tests=no; \
+  elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+    am__color_tests=yes; \
+  elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+    am__color_tests=yes; \
+  fi; \
+  if test $$am__color_tests = yes; then \
+    red=''; \
+    grn=''; \
+    lgn=''; \
+    blu=''; \
+    mgn=''; \
+    brg=''; \
+    std=''; \
+  fi; \
+}
+am__recheck_rx = ^[ 	]*:recheck:[ 	]*
+am__global_test_result_rx = ^[ 	]*:global-test-result:[ 	]*
+am__copy_in_global_log_rx = ^[ 	]*:copy-in-global-log:[ 	]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+  recheck = 1; \
+  while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+    { \
+      if (rc < 0) \
+        { \
+          if ((getline line2 < ($$0 ".log")) < 0) \
+	    recheck = 0; \
+          break; \
+        } \
+      else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+        { \
+          recheck = 0; \
+          break; \
+        } \
+      else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+        { \
+          break; \
+        } \
+    }; \
+  if (recheck) \
+    print $$0; \
+  close ($$0 ".trs"); \
+  close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+  print "fatal: making $@: " msg | "cat >&2"; \
+  exit 1; \
+} \
+function rst_section(header) \
+{ \
+  print header; \
+  len = length(header); \
+  for (i = 1; i <= len; i = i + 1) \
+    printf "="; \
+  printf "\n\n"; \
+} \
+{ \
+  copy_in_global_log = 1; \
+  global_test_result = "RUN"; \
+  while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+    { \
+      if (rc < 0) \
+         fatal("failed to read from " $$0 ".trs"); \
+      if (line ~ /$(am__global_test_result_rx)/) \
+        { \
+          sub("$(am__global_test_result_rx)", "", line); \
+          sub("[ 	]*$$", "", line); \
+          global_test_result = line; \
+        } \
+      else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+        copy_in_global_log = 0; \
+    }; \
+  if (copy_in_global_log) \
+    { \
+      rst_section(global_test_result ": " $$0); \
+      while ((rc = (getline line < ($$0 ".log"))) != 0) \
+      { \
+        if (rc < 0) \
+          fatal("failed to read from " $$0 ".log"); \
+        print line; \
+      }; \
+      printf "\n"; \
+    }; \
+  close ($$0 ".trs"); \
+  close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/   &   /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this.  Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+  --color-tests "$$am__color_tests" \
+  --enable-hard-errors "$$am__enable_hard_errors" \
+  --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test.  Creates the
+# directory for the log if needed.  Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log.  Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT.  Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup);					\
+$(am__vpath_adj_setup) $(am__vpath_adj)			\
+$(am__tty_colors);					\
+srcdir=$(srcdir); export srcdir;			\
+case "$@" in						\
+  */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;;	\
+    *) am__odir=.;; 					\
+esac;							\
+test "x$$am__odir" = x"." || test -d "$$am__odir" 	\
+  || $(MKDIR_P) "$$am__odir" || exit $$?;		\
+if test -f "./$$f"; then dir=./;			\
+elif test -f "$$f"; then dir=;				\
+else dir="$(srcdir)/"; fi;				\
+tst=$$dir$$f; log='$@'; 				\
+if test -n '$(DISABLE_HARD_ERRORS)'; then		\
+  am__enable_hard_errors=no; 				\
+else							\
+  am__enable_hard_errors=yes; 				\
+fi; 							\
+case " $(XFAIL_TESTS) " in				\
+  *[\ \	]$$f[\ \	]* | *[\ \	]$$dir$$f[\ \	]*) \
+    am__expect_failure=yes;;				\
+  *)							\
+    am__expect_failure=no;;				\
+esac; 							\
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed).  The result is saved in the shell variable
+# '$bases'.  This honors runtime overriding of TESTS and TEST_LOGS.  Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+  bases='$(TEST_LOGS)'; \
+  bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+  bases=`echo $$bases`
+RECHECK_LOGS = $(TEST_LOGS)
+AM_RECURSIVE_TARGETS = check recheck
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+  case '$@' in \
+    */*) \
+      case '$*' in \
+        */*) b='$*';; \
+          *) b=`echo '$@' | sed 's/\.log$$//'`; \
+       esac;; \
+    *) \
+      b='$*';; \
+  esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT at .log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+	$(TEST_LOG_FLAGS)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BUILTIN_LIBS = @BUILTIN_LIBS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CDDGMPCPPFLAGS = @CDDGMPCPPFLAGS@
+CDDGMPLDFLAGS = @CDDGMPLDFLAGS@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATA_DIR = @DATA_DIR@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DOC_DIR = @DOC_DIR@
+DOXYGEN = @DOXYGEN@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FACTORY_INCLUDES = @FACTORY_INCLUDES@
+FACTORY_LIBS = @FACTORY_LIBS@
+FGREP = @FGREP@
+FLINT_CFLAGS = @FLINT_CFLAGS@
+FLINT_HOME = @FLINT_HOME@
+FLINT_LIBS = @FLINT_LIBS@
+GMP_CFLAGS = @GMP_CFLAGS@
+GMP_HOME = @GMP_HOME@
+GMP_LIBS = @GMP_LIBS@
+GMP_VERSION = @GMP_VERSION@
+GREP = @GREP@
+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@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NTL_CFLAGS = @NTL_CFLAGS@
+NTL_LIBS = @NTL_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OMALLOC_INCLUDES = @OMALLOC_INCLUDES@
+OMALLOC_LIBS = @OMALLOC_LIBS@
+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@
+PKG_REQUIRE = @PKG_REQUIRE@
+PMCONFIG = @PMCONFIG@
+PM_CFLAGS = @PM_CFLAGS@
+PM_INC = @PM_INC@
+PM_LDFLAGS = @PM_LDFLAGS@
+PM_LIBS = @PM_LIBS@
+POLYMAKE_CXXFLAGS = @POLYMAKE_CXXFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LDFLAGS = @PTHREAD_LDFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
+PYTHON = @PYTHON@
+PYTHON_CSPEC = @PYTHON_CSPEC@
+PYTHON_EXECPREFIX = @PYTHON_EXECPREFIX@
+PYTHON_LSPEC = @PYTHON_LSPEC@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+RANLIB = @RANLIB@
+RESOURCES_INCLUDES = @RESOURCES_INCLUDES@
+RESOURCES_LIBS = @RESOURCES_LIBS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SINGULAR_CFLAGS = @SINGULAR_CFLAGS@
+SI_COUNTEDREF_AUTOLOAD = @SI_COUNTEDREF_AUTOLOAD@
+SI_CPU_I386 = @SI_CPU_I386@
+SI_CPU_IA64 = @SI_CPU_IA64@
+SI_CPU_PPC = @SI_CPU_PPC@
+SI_CPU_SPARC = @SI_CPU_SPARC@
+SI_CPU_X86_64 = @SI_CPU_X86_64@
+STRIP = @STRIP@
+USEPPROCSDYNAMICLD = @USEPPROCSDYNAMICLD@
+USEPPROCSDYNAMICLDFLAGS = @USEPPROCSDYNAMICLDFLAGS@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
+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@
+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@
+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@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+ACLOCAL_AMFLAGS = -I ../../m4
+MYINCLUDES = -I${top_srcdir} -I${top_builddir} \
+-I${top_srcdir}/libpolys -I${top_builddir}/libpolys \
+$(FACTORY_INCLUDES) $(RESOURCES_INCLUDES) $(OMALLOC_INCLUDES) \
+$(FLINT_CFLAGS) $(NTL_CFLAGS) $(GMP_CFLAGS) $(GOOGLE_PERFTOOLS_CFLAGS)
+
+ at SI_BUILTIN_SYZEXTRA_TRUE@noinst_LTLIBRARIES = syzextra.la
+ at SI_BUILTIN_SYZEXTRA_FALSE@P_PROCS_CPPFLAGS_COMMON = -DDYNAMIC_VERSION
+ at SI_BUILTIN_SYZEXTRA_TRUE@P_PROCS_CPPFLAGS_COMMON = -DSTATIC_VERSION
+# Add under Mac OS X: -flat_namespace -weak_reference_mismatches weak -undefined dynamic_lookup
+ at SI_BUILTIN_SYZEXTRA_FALSE@P_PROCS_MODULE_LDFLAGS = -module -export-dynamic -avoid-version -flat_namespace -weak_reference_mismatches weak -undefined dynamic_lookup
+ at SI_BUILTIN_SYZEXTRA_TRUE@P_PROCS_MODULE_LDFLAGS = -module
+ at SI_BUILTIN_SYZEXTRA_FALSE@module_LTLIBRARIES = syzextra.la
+ at SI_BUILTIN_SYZEXTRA_FALSE@moduledir = $(libexecdir)/singular/MOD
+SOURCES = mod_main.cc DebugPrint.cc DebugPrint.h myNF.cc myNF.h singularxx_defs.h syzextra.cc syzextra.h
+syzextra_la_SOURCES = $(SOURCES)
+syzextra_la_CPPFLAGS = ${MYINCLUDES} ${P_PROCS_CPPFLAGS_COMMON}
+syzextra_la_LDFLAGS = ${AM_LDFLAGS} ${P_PROCS_MODULE_LDFLAGS} ${GOOGLE_PERFTOOL_LDFLAGS}
+AM_COLOR_TESTS = always
+TESTS_ENVIRONMENT = SINGULARPATH='${abs_top_builddir}/Singular/LIB:${abs_top_srcdir}/Singular/LIB:${abs_top_builddir}/libpolys/polys/.libs:${abs_top_builddir}/factory/gftables:${abs_builddir}/.libs:${abs_srcdir}' \
+	SINGULAR_ROOT_DIR='${abs_top_builddir}' \
+	SINGULAR_BIN_DIR='${abs_top_builddir}/Singular'
+TESTS = test_release.sh
+EXTRA_DIST = test.sh $(TESTS)
+# syzextra.tst ederc.tst test_clear_enum.tst
+CLEANFILES = SimpleTests.json
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .cc .lo .log .o .obj .test .test$(EXEEXT) .trs
+$(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) --foreign Singular/dyn_modules/syzextra/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign Singular/dyn_modules/syzextra/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-moduleLTLIBRARIES: $(module_LTLIBRARIES)
+	@$(NORMAL_INSTALL)
+	@list='$(module_LTLIBRARIES)'; test -n "$(moduledir)" || list=; \
+	list2=; for p in $$list; do \
+	  if test -f $$p; then \
+	    list2="$$list2 $$p"; \
+	  else :; fi; \
+	done; \
+	test -z "$$list2" || { \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(moduledir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(moduledir)" || exit 1; \
+	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(moduledir)'"; \
+	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(moduledir)"; \
+	}
+
+uninstall-moduleLTLIBRARIES:
+	@$(NORMAL_UNINSTALL)
+	@list='$(module_LTLIBRARIES)'; test -n "$(moduledir)" || list=; \
+	for p in $$list; do \
+	  $(am__strip_dir) \
+	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(moduledir)/$$f'"; \
+	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(moduledir)/$$f"; \
+	done
+
+clean-moduleLTLIBRARIES:
+	-test -z "$(module_LTLIBRARIES)" || rm -f $(module_LTLIBRARIES)
+	@list='$(module_LTLIBRARIES)'; \
+	locs=`for p in $$list; do echo $$p; done | \
+	      sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+	      sort -u`; \
+	test -z "$$locs" || { \
+	  echo rm -f $${locs}; \
+	  rm -f $${locs}; \
+	}
+
+clean-noinstLTLIBRARIES:
+	-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+	@list='$(noinst_LTLIBRARIES)'; \
+	locs=`for p in $$list; do echo $$p; done | \
+	      sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+	      sort -u`; \
+	test -z "$$locs" || { \
+	  echo rm -f $${locs}; \
+	  rm -f $${locs}; \
+	}
+
+syzextra.la: $(syzextra_la_OBJECTS) $(syzextra_la_DEPENDENCIES) $(EXTRA_syzextra_la_DEPENDENCIES) 
+	$(AM_V_CXXLD)$(syzextra_la_LINK) $(am_syzextra_la_rpath) $(syzextra_la_OBJECTS) $(syzextra_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/syzextra_la-DebugPrint.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/syzextra_la-mod_main.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/syzextra_la-myNF.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/syzextra_la-syzextra.Plo at am__quote@
+
+.cc.o:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+ at am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXXCOMPILE) -c -o $@ $<
+
+.cc.obj:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+ at am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.cc.lo:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+ at am__fastdepCXX_TRUE@	$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LTCXXCOMPILE) -c -o $@ $<
+
+syzextra_la-mod_main.lo: mod_main.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(syzextra_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT syzextra_la-mod_main.lo -MD -MP -MF $(DEPDIR)/syzextra_la-mod_main.Tpo -c -o syzextra_la-mod_main.lo `test -f 'mod_main.cc' || echo '$(srcdir)/'`mod_main.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/syzextra_la-mod_main.Tpo $(DEPDIR)/syzextra_la-mod_main.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='mod_main.cc' object='syzextra_la-mod_main.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(syzextra_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o syzextra_la-mod_main.lo `test -f 'mod_main.cc' || echo '$(srcdir)/'`mod_main.cc
+
+syzextra_la-DebugPrint.lo: DebugPrint.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(syzextra_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT syzextra_la-DebugPrint.lo -MD -MP -MF $(DEPDIR)/syzextra_la-DebugPrint.Tpo -c -o syzextra_la-DebugPrint.lo `test -f 'DebugPrint.cc' || echo '$(srcdir)/'`DebugPrint.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/syzextra_la-DebugPrint.Tpo $(DEPDIR)/syzextra_la-DebugPrint.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='DebugPrint.cc' object='syzextra_la-DebugPrint.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(syzextra_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o syzextra_la-DebugPrint.lo `test -f 'DebugPrint.cc' || echo '$(srcdir)/'`DebugPrint.cc
+
+syzextra_la-myNF.lo: myNF.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(syzextra_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT syzextra_la-myNF.lo -MD -MP -MF $(DEPDIR)/syzextra_la-myNF.Tpo -c -o syzextra_la-myNF.lo `test -f 'myNF.cc' || echo '$(srcdir)/'`myNF.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/syzextra_la-myNF.Tpo $(DEPDIR)/syzextra_la-myNF.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='myNF.cc' object='syzextra_la-myNF.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(syzextra_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o syzextra_la-myNF.lo `test -f 'myNF.cc' || echo '$(srcdir)/'`myNF.cc
+
+syzextra_la-syzextra.lo: syzextra.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(syzextra_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT syzextra_la-syzextra.lo -MD -MP -MF $(DEPDIR)/syzextra_la-syzextra.Tpo -c -o syzextra_la-syzextra.lo `test -f 'syzextra.cc' || echo '$(srcdir)/'`syzextra.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/syzextra_la-syzextra.Tpo $(DEPDIR)/syzextra_la-syzextra.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='syzextra.cc' object='syzextra_la-syzextra.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(syzextra_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o syzextra_la-syzextra.lo `test -f 'syzextra.cc' || echo '$(srcdir)/'`syzextra.cc
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	$(am__define_uniq_tagged_files); \
+	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-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	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"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'.  Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+	rm -f $< $@
+	$(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+	@:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+	@$(am__set_TESTS_bases); \
+	am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+	redo_bases=`for i in $$bases; do \
+	              am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+	            done`; \
+	if test -n "$$redo_bases"; then \
+	  redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+	  redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+	  if $(am__make_dryrun); then :; else \
+	    rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+	  fi; \
+	fi; \
+	if test -n "$$am__remaking_logs"; then \
+	  echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+	       "recursion detected" >&2; \
+	else \
+	  am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+	fi; \
+	if $(am__make_dryrun); then :; else \
+	  st=0;  \
+	  errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+	  for i in $$redo_bases; do \
+	    test -f $$i.trs && test -r $$i.trs \
+	      || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+	    test -f $$i.log && test -r $$i.log \
+	      || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+	  done; \
+	  test $$st -eq 0 || exit 1; \
+	fi
+	@$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+	ws='[ 	]'; \
+	results=`for b in $$bases; do echo $$b.trs; done`; \
+	test -n "$$results" || results=/dev/null; \
+	all=`  grep "^$$ws*:test-result:"           $$results | wc -l`; \
+	pass=` grep "^$$ws*:test-result:$$ws*PASS"  $$results | wc -l`; \
+	fail=` grep "^$$ws*:test-result:$$ws*FAIL"  $$results | wc -l`; \
+	skip=` grep "^$$ws*:test-result:$$ws*SKIP"  $$results | wc -l`; \
+	xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+	xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+	error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+	if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+	  success=true; \
+	else \
+	  success=false; \
+	fi; \
+	br='==================='; br=$$br$$br$$br$$br; \
+	result_count () \
+	{ \
+	    if test x"$$1" = x"--maybe-color"; then \
+	      maybe_colorize=yes; \
+	    elif test x"$$1" = x"--no-color"; then \
+	      maybe_colorize=no; \
+	    else \
+	      echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+	    fi; \
+	    shift; \
+	    desc=$$1 count=$$2; \
+	    if test $$maybe_colorize = yes && test $$count -gt 0; then \
+	      color_start=$$3 color_end=$$std; \
+	    else \
+	      color_start= color_end=; \
+	    fi; \
+	    echo "$${color_start}# $$desc $$count$${color_end}"; \
+	}; \
+	create_testsuite_report () \
+	{ \
+	  result_count $$1 "TOTAL:" $$all   "$$brg"; \
+	  result_count $$1 "PASS: " $$pass  "$$grn"; \
+	  result_count $$1 "SKIP: " $$skip  "$$blu"; \
+	  result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+	  result_count $$1 "FAIL: " $$fail  "$$red"; \
+	  result_count $$1 "XPASS:" $$xpass "$$red"; \
+	  result_count $$1 "ERROR:" $$error "$$mgn"; \
+	}; \
+	{								\
+	  echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" |	\
+	    $(am__rst_title);						\
+	  create_testsuite_report --no-color;				\
+	  echo;								\
+	  echo ".. contents:: :depth: 2";				\
+	  echo;								\
+	  for b in $$bases; do echo $$b; done				\
+	    | $(am__create_global_log);					\
+	} >$(TEST_SUITE_LOG).tmp || exit 1;				\
+	mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG);			\
+	if $$success; then						\
+	  col="$$grn";							\
+	 else								\
+	  col="$$red";							\
+	  test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG);		\
+	fi;								\
+	echo "$${col}$$br$${std}"; 					\
+	echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}";	\
+	echo "$${col}$$br$${std}"; 					\
+	create_testsuite_report --maybe-color;				\
+	echo "$$col$$br$$std";						\
+	if $$success; then :; else					\
+	  echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}";		\
+	  if test -n "$(PACKAGE_BUGREPORT)"; then			\
+	    echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}";	\
+	  fi;								\
+	  echo "$$col$$br$$std";					\
+	fi;								\
+	$$success || exit 1
+
+check-TESTS:
+	@list='$(RECHECK_LOGS)';           test -z "$$list" || rm -f $$list
+	@list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+	@test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+	@set +e; $(am__set_TESTS_bases); \
+	log_list=`for i in $$bases; do echo $$i.log; done`; \
+	trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+	log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+	$(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+	exit $$?;
+recheck: all 
+	@test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+	@set +e; $(am__set_TESTS_bases); \
+	bases=`for i in $$bases; do echo $$i; done \
+	         | $(am__list_recheck_tests)` || exit 1; \
+	log_list=`for i in $$bases; do echo $$i.log; done`; \
+	log_list=`echo $$log_list`; \
+	$(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+	        am__force_recheck=am--force-recheck \
+	        TEST_LOGS="$$log_list"; \
+	exit $$?
+test_release.sh.log: test_release.sh
+	@p='test_release.sh'; \
+	b='test_release.sh'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+.test.log:
+	@p='$<'; \
+	$(am__set_b); \
+	$(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+ at am__EXEEXT_TRUE@.test$(EXEEXT).log:
+ at am__EXEEXT_TRUE@	@p='$<'; \
+ at am__EXEEXT_TRUE@	$(am__set_b); \
+ at am__EXEEXT_TRUE@	$(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ at am__EXEEXT_TRUE@	--log-file $$b.log --trs-file $$b.trs \
+ at am__EXEEXT_TRUE@	$(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ at am__EXEEXT_TRUE@	"$$tst" $(AM_TESTS_FD_REDIRECT)
+
+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 $(LTLIBRARIES)
+installdirs:
+	for dir in "$(DESTDIR)$(moduledir)"; 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:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+	-test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+	-test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+	-test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+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-moduleLTLIBRARIES \
+	clean-noinstLTLIBRARIES 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-moduleLTLIBRARIES
+
+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: uninstall-moduleLTLIBRARIES
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am clean \
+	clean-generic clean-libtool clean-moduleLTLIBRARIES \
+	clean-noinstLTLIBRARIES cscopelist-am ctags ctags-am 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-moduleLTLIBRARIES 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 \
+	recheck tags tags-am uninstall uninstall-am \
+	uninstall-moduleLTLIBRARIES
+
+
+# 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/Singular/dyn_modules/syzextra/mod_main.cc b/Singular/dyn_modules/syzextra/mod_main.cc
new file mode 100644
index 0000000..79f03ab
--- /dev/null
+++ b/Singular/dyn_modules/syzextra/mod_main.cc
@@ -0,0 +1,2038 @@
+#include <kernel/mod2.h>
+
+#include <omalloc/omalloc.h>
+
+#include <misc/intvec.h>
+#include <misc/options.h>
+
+#include <coeffs/coeffs.h>
+
+#include <polys/PolyEnumerator.h>
+
+#include <polys/monomials/p_polys.h>
+#include <polys/monomials/ring.h>
+#include <polys/simpleideals.h>
+
+// #include <kernel/longrat.h>
+#include <kernel/GBEngine/kstd1.h>
+
+#include <kernel/polys.h>
+
+#include <kernel/GBEngine/syz.h>
+
+#include <Singular/tok.h>
+#include <Singular/ipid.h>
+#include <Singular/lists.h>
+#include <Singular/attrib.h>
+
+#include <Singular/ipid.h>
+#include <Singular/ipshell.h> // For iiAddCproc
+
+// extern coeffs coeffs_BIGINT
+
+#include "singularxx_defs.h"
+
+#include "DebugPrint.h"
+#include "myNF.h"
+#include "syzextra.h"
+
+
+#include <Singular/mod_lib.h>
+
+
+#if GOOGLE_PROFILE_ENABLED
+#include <google/profiler.h>
+#endif // #if GOOGLE_PROFILE_ENABLED
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+
+
+extern void pISUpdateComponents(ideal F, const intvec *const V, const int MIN, const ring r);
+// extern ring rCurrRingAssure_SyzComp();
+extern ring rAssure_InducedSchreyerOrdering(const ring r, BOOLEAN complete, int sign);
+extern int rGetISPos(const int p, const ring r);
+
+// USING_NAMESPACE_SINGULARXX;
+
+USING_NAMESPACE( SINGULARXXNAME :: DEBUG )
+USING_NAMESPACE( SINGULARXXNAME :: NF )
+USING_NAMESPACE( SINGULARXXNAME :: SYZEXTRA )
+
+
+BEGIN_NAMESPACE_NONAME
+
+
+static inline void NoReturn(leftv& res)
+{
+  res->rtyp = NONE;
+  res->data = NULL;
+}
+
+/// wrapper around n_ClearContent
+static BOOLEAN _ClearContent(leftv res, leftv h)
+{
+  NoReturn(res);
+
+  const char *usage = "'ClearContent' needs a (non-zero!) poly or vector argument...";
+
+  if( h == NULL )
+  {
+    WarnS(usage);
+    return TRUE;
+  }
+
+  assume( h != NULL );
+
+  if( !( h->Typ() == POLY_CMD || h->Typ() == VECTOR_CMD) )
+  {
+    WarnS(usage);
+    return TRUE;
+  }
+
+  assume (h->Next() == NULL);
+
+  poly ph = reinterpret_cast<poly>(h->Data());
+
+  if( ph == NULL )
+  {
+    WarnS(usage);
+    return TRUE;
+  }
+
+  const ring r =  currRing;
+  assume( r != NULL ); assume( r->cf != NULL ); const coeffs C = r->cf;
+
+  number n;
+
+  // experimentall (recursive enumerator treatment) of alg. ext
+  CPolyCoeffsEnumerator itr(ph);
+  n_ClearContent(itr, n, C);
+
+  res->data = n;
+  res->rtyp = NUMBER_CMD;
+
+  return FALSE;
+}
+
+/// wrapper around n_ClearDenominators
+static BOOLEAN _ClearDenominators(leftv res, leftv h)
+{
+  NoReturn(res);
+
+  const char *usage = "'ClearDenominators' needs a (non-zero!) poly or vector argument...";
+
+  if( h == NULL )
+  {
+    WarnS(usage);
+    return TRUE;
+  }
+
+  assume( h != NULL );
+
+  if( !( h->Typ() == POLY_CMD || h->Typ() == VECTOR_CMD) )
+  {
+    WarnS(usage);
+    return TRUE;
+  }
+
+  assume (h->Next() == NULL);
+
+  poly ph = reinterpret_cast<poly>(h->Data());
+
+  if( ph == NULL )
+  {
+    WarnS(usage);
+    return TRUE;
+  }
+
+  const ring r =  currRing;
+  assume( r != NULL ); assume( r->cf != NULL ); const coeffs C = r->cf;
+
+  number n;
+
+  // experimentall (recursive enumerator treatment) of alg. ext.
+  CPolyCoeffsEnumerator itr(ph);
+  n_ClearDenominators(itr, n, C);
+
+  res->data = n;
+  res->rtyp = NUMBER_CMD;
+
+  return FALSE;
+}
+
+
+/// try to get an optional (simple) integer argument out of h
+/// or return the default value
+static int getOptionalInteger(const leftv& h, const int _n)
+{
+  if( h!= NULL && h->Typ() == INT_CMD )
+  {
+    int n = (int)(long)(h->Data());
+
+    if( n < 0 )
+      Warn("Negative (%d) optional integer argument", n);
+
+    return (n);
+  }
+
+  return (_n);
+}
+
+static BOOLEAN noop(leftv __res, leftv /*__v*/)
+{
+  NoReturn(__res);
+  return FALSE;
+}
+
+static BOOLEAN _ProfilerStart(leftv __res, leftv h)
+{
+  NoReturn(__res);
+#if GOOGLE_PROFILE_ENABLED
+  if( h!= NULL && h->Typ() == STRING_CMD )
+  {
+    const char* name = (char*)(h->Data());
+    assume( name != NULL );
+    ProfilerStart(name);
+  } else
+    WerrorS("ProfilerStart requires a string [name] argument");
+#else
+  WarnS("Sorry no google profiler support (GOOGLE_PROFILE_ENABLE!=1)...");
+//  return TRUE; // ?
+#endif // #if GOOGLE_PROFILE_ENABLED
+  return FALSE;
+  (void)h;
+}
+static BOOLEAN _ProfilerStop(leftv __res, leftv /*__v*/)
+{
+  NoReturn(__res);
+#if GOOGLE_PROFILE_ENABLED
+  ProfilerStop();
+#else
+  WarnS("Sorry no google profiler support (GOOGLE_PROFILE_ENABLED!=1)...");
+//  return TRUE; // ?
+#endif // #if GOOGLE_PROFILE_ENABLED
+  return FALSE;
+}
+
+static inline number jjLONG2N(long d)
+{
+  return n_Init(d, coeffs_BIGINT);
+}
+
+static inline void view(const intvec* v)
+{
+#ifndef SING_NDEBUG
+  v->view();
+#else
+  // This code duplication is only due to Hannes's #ifndef SING_NDEBUG!
+  Print ("intvec: {rows: %d, cols: %d, length: %d, Values: \n", v->rows(), v->cols(), v->length());
+
+  for (int i = 0; i < v->rows(); i++)
+  {
+    Print ("Row[%3d]:", i);
+    for (int j = 0; j < v->cols(); j++)
+      Print (" %5d", (*v)[j + i * (v->cols())] );
+    PrintLn ();
+  }
+  PrintS ("}\n");
+#endif
+
+}
+
+
+
+static BOOLEAN DetailedPrint(leftv __res, leftv h)
+{
+  NoReturn(__res);
+
+  if( h == NULL )
+  {
+    WarnS("DetailedPrint needs an argument...");
+    return TRUE;
+  }
+
+  if( h->Typ() == NUMBER_CMD)
+  {
+    number n = (number)h->Data();
+
+    const ring r = currRing;
+
+    n_Test(n, r->cf);
+
+    StringSetS("");
+    n_Write(n, r->cf);
+    PrintS(StringEndS());
+    PrintLn();
+
+    return FALSE;
+  }
+
+  if( h->Typ() == RING_CMD)
+  {
+    const ring r = (const ring)h->Data();
+    rWrite(r, TRUE);
+    PrintLn();
+#ifdef RDEBUG
+    //rDebugPrint(r);
+#endif
+    return FALSE;
+  }
+
+  if( h->Typ() == POLY_CMD || h->Typ() == VECTOR_CMD)
+  {
+    const poly p = (const poly)h->Data(); h = h->Next();
+
+    dPrint(p, currRing, currRing, getOptionalInteger(h, 3));
+
+    return FALSE;
+  }
+
+  if( h->Typ() == IDEAL_CMD || h->Typ() == MODUL_CMD)
+  {
+    const ideal id = (const ideal)h->Data(); h = h->Next();
+
+    dPrint(id, currRing, currRing, getOptionalInteger(h, 3));
+
+    return FALSE;
+  }
+
+  if( h->Typ() == RESOLUTION_CMD )
+  {
+    const syStrategy syzstr = reinterpret_cast<const syStrategy>(h->Data());
+
+    h = h->Next();
+
+    int nTerms = getOptionalInteger(h, 1);
+
+
+    Print("RESOLUTION_CMD(%p): ", reinterpret_cast<const void*>(syzstr)); PrintLn();
+
+    const ring save = currRing;
+    const ring r = syzstr->syRing;
+//    const ring rr = (r != NULL) ? r: save;
+
+
+    const int iLength = syzstr->length;
+
+    Print("int 'length': %d", iLength); PrintLn();
+    Print("int 'regularity': %d", syzstr->regularity); PrintLn();
+    Print("short 'list_length': %hd", syzstr->list_length); PrintLn();
+    Print("short 'references': %hd", syzstr->references); PrintLn();
+
+
+#define PRINT_pINTVECTOR(s, v) Print("intvec '%10s'(%p)", #v, reinterpret_cast<const void*>((s)->v)); \
+if( (s)->v != NULL ){ PrintS(": "); view((s)->v); }; \
+PrintLn();
+
+    PRINT_pINTVECTOR(syzstr, resolution);
+    PRINT_pINTVECTOR(syzstr, betti);
+    PRINT_pINTVECTOR(syzstr, Tl);
+    PRINT_pINTVECTOR(syzstr, cw);
+#undef PRINT_pINTVECTOR
+
+    if (r == NULL)
+      Print("ring '%10s': NULL", "syRing");
+    else
+      if (r == currRing)
+        Print("ring '%10s': currRing", "syRing");
+      else
+        if (r != NULL && r != save)
+        {
+          Print("ring '%10s': ", "syRing");
+          rWrite(r);
+#ifdef RDEBUG
+          //              rDebugPrint(r);
+#endif
+          // rChangeCurrRing(r);
+        }
+    PrintLn();
+
+    const SRes rP = syzstr->resPairs;
+    Print("SRes 'resPairs': %p", reinterpret_cast<const void*>(rP)); PrintLn();
+
+    if (rP != NULL)
+      for (int iLevel = 0; (iLevel < iLength) && (rP[iLevel] != NULL) && ((*syzstr->Tl)[iLevel] >= 0); iLevel++)
+      {
+        int n = 0;
+        const int iTl = (*syzstr->Tl)[iLevel];
+        for (int j = 0; (j < iTl) && ((rP[iLevel][j].lcm!=NULL) || (rP[iLevel][j].syz!=NULL)); j++)
+        {
+          if (rP[iLevel][j].isNotMinimal==NULL)
+            n++;
+        }
+        Print("minimal-resPairs-Size[1+%d]: %d", iLevel, n); PrintLn();
+      }
+
+
+    //  const ring rrr = (iLevel > 0) ? rr : save; ?
+#define PRINT_RESOLUTION(s, v) Print("resolution '%12s': %p", #v, reinterpret_cast<const void*>((s)->v)); PrintLn(); \
+if ((s)->v != NULL) \
+  for (int iLevel = 0; (iLevel < iLength) && ( ((s)->v)[iLevel] != NULL ); iLevel++) \
+  { \
+    /* const ring rrr = (iLevel > 0) ? save : save; */ \
+    Print("id '%10s'[%d]: (%p) ncols = %d / size: %d; nrows = %d, rank = %ld / rk: %ld", #v, iLevel, reinterpret_cast<const void*>(((s)->v)[iLevel]), ((s)->v)[iLevel]->ncols, idSize(((s)->v)[iLevel]), ((s)->v)[iLevel]->nrows, ((s)->v)[iLevel]->rank, -1L/*id_RankFreeModule(((s)->v)[iLevel], rrr)*/ ); \
+    PrintLn(); \
+  } \
+  PrintLn();
+
+    // resolvente:
+    PRINT_RESOLUTION(syzstr, minres);
+    PRINT_RESOLUTION(syzstr, fullres);
+
+//    assume (id_RankFreeModule (syzstr->res[1], rr) == syzstr->res[1]->rank);
+
+    PRINT_RESOLUTION(syzstr, res);
+    PRINT_RESOLUTION(syzstr, orderedRes);
+#undef PRINT_RESOLUTION
+
+#define PRINT_POINTER(s, v) Print("pointer '%17s': %p", #v, reinterpret_cast<const void*>((s)->v)); PrintLn();
+    // 2d arrays:
+    PRINT_POINTER(syzstr, truecomponents);
+    PRINT_POINTER(syzstr, ShiftedComponents);
+    PRINT_POINTER(syzstr, backcomponents);
+    PRINT_POINTER(syzstr, Howmuch);
+    PRINT_POINTER(syzstr, Firstelem);
+    PRINT_POINTER(syzstr, elemLength);
+    PRINT_POINTER(syzstr, sev);
+
+    // arrays of intvects:
+    PRINT_POINTER(syzstr, weights);
+    PRINT_POINTER(syzstr, hilb_coeffs);
+#undef PRINT_POINTER
+
+
+    if (syzstr->fullres==NULL)
+    {
+      PrintS("resolution 'fullres': (NULL) => resolution not computed yet");
+      PrintLn();
+    } else
+    {
+      Print("resolution 'fullres': (%p) => resolution seems to be computed already", reinterpret_cast<const void*>(syzstr->fullres));
+      PrintLn();
+      dPrint(*syzstr->fullres, save, save, nTerms);
+    }
+
+
+
+
+    if (syzstr->minres==NULL)
+    {
+      PrintS("resolution 'minres': (NULL) => resolution not minimized yet");
+      PrintLn();
+    } else
+    {
+      Print("resolution 'minres': (%p) => resolution seems to be minimized already", reinterpret_cast<const void*>(syzstr->minres));
+      PrintLn();
+      dPrint(*syzstr->minres, save, save, nTerms);
+    }
+
+
+
+
+    /*
+    int ** truecomponents;
+    long** ShiftedComponents;
+    int ** backcomponents;
+    int ** Howmuch;
+    int ** Firstelem;
+    int ** elemLength;
+    unsigned long ** sev;
+
+    intvec ** weights;
+    intvec ** hilb_coeffs;
+
+    SRes resPairs;               //polynomial data for internal use only
+
+    resolvente fullres;
+    resolvente minres;
+    resolvente res;              //polynomial data for internal use only
+    resolvente orderedRes;       //polynomial data for internal use only
+*/
+
+    //            if( currRing != save ) rChangeCurrRing(save);
+  }
+
+
+  return FALSE;
+}
+
+/// wrapper around p_Tail and id_Tail
+static BOOLEAN Tail(leftv res, leftv h)
+{
+  NoReturn(res);
+
+  if( h == NULL )
+  {
+    WarnS("Tail needs a poly/vector/ideal/module argument...");
+    return TRUE;
+  }
+
+  assume( h != NULL );
+
+  const ring r =  currRing;
+
+  if( h->Typ() == POLY_CMD || h->Typ() == VECTOR_CMD)
+  {
+    res->data = p_Tail( (const poly)h->Data(), r );
+    res->rtyp = h->Typ();
+
+    h = h->Next(); assume (h == NULL);
+
+    return FALSE;
+  }
+
+  if( h->Typ() == IDEAL_CMD || h->Typ() == MODUL_CMD)
+  {
+    res->data = id_Tail( (const ideal)h->Data(), r );
+    res->rtyp = h->Typ();
+
+    h = h->Next(); assume (h == NULL);
+
+    return FALSE;
+  }
+
+  WarnS("Tail needs a single poly/vector/ideal/module argument...");
+  return TRUE;
+}
+
+
+
+static BOOLEAN _ComputeLeadingSyzygyTerms(leftv res, leftv h)
+{
+  const SchreyerSyzygyComputationFlags attributes(currRingHdl);
+
+  const BOOLEAN OPT__DEBUG      = attributes.OPT__DEBUG;
+//  const BOOLEAN OPT__SYZCHECK   = attributes.OPT__SYZCHECK;
+  const BOOLEAN OPT__LEAD2SYZ   = attributes.OPT__LEAD2SYZ;
+//  const BOOLEAN OPT__HYBRIDNF   = attributes.OPT__HYBRIDNF;
+//  const BOOLEAN OPT__TAILREDSYZ = attributes.OPT__TAILREDSYZ;
+
+  const ring r = attributes.m_rBaseRing;
+  NoReturn(res);
+
+  if( h == NULL )
+  {
+    WarnS("ComputeLeadingSyzygyTerms needs an argument...");
+    return TRUE;
+  }
+
+  assume( h != NULL );
+
+  if( h->Typ() == IDEAL_CMD || h->Typ() == MODUL_CMD)
+  {
+    const ideal id = (const ideal)h->Data();
+
+    assume(id != NULL);
+
+    if( UNLIKELY( OPT__DEBUG ) )
+    {
+      PrintS("ComputeLeadingSyzygyTerms::Input: \n");
+      dPrint(id, r, r, 0);
+    }
+
+    assume( !OPT__LEAD2SYZ );
+
+    h = h->Next(); assume (h == NULL);
+
+    const ideal newid = ComputeLeadingSyzygyTerms(id,  attributes);
+
+    res->data = newid; res->rtyp = MODUL_CMD;
+    return FALSE;
+  }
+
+  WarnS("ComputeLeadingSyzygyTerms needs a single ideal/module argument...");
+  return TRUE;
+}
+
+///  sorting wrt <c,ds> & reversing...
+/// change the input inplace!!!
+// TODO: use a ring with >_{c, ds}!???
+static BOOLEAN _Sort_c_ds(leftv res, leftv h)
+{
+  const SchreyerSyzygyComputationFlags attributes(currRingHdl);
+
+  const BOOLEAN OPT__DEBUG      = FALSE; // attributes.OPT__DEBUG;
+//  const BOOLEAN OPT__SYZCHECK   = attributes.OPT__SYZCHECK;
+//  const BOOLEAN OPT__LEAD2SYZ   = attributes.OPT__LEAD2SYZ;
+//  const BOOLEAN OPT__HYBRIDNF   = attributes.OPT__HYBRIDNF;
+//  const BOOLEAN OPT__TAILREDSYZ = attributes.OPT__TAILREDSYZ;
+
+  NoReturn(res);
+
+  const ring r = attributes.m_rBaseRing;
+  NoReturn(res);
+
+  if( h == NULL )
+  {
+    WarnS("Sort_c_ds needs an argument...");
+    return TRUE;
+  }
+
+  assume( h != NULL );
+
+  if(    (h->Typ() == IDEAL_CMD || h->Typ() == MODUL_CMD)
+      && (h->rtyp  == IDHDL) // must be a variable!
+      && (h->e == NULL) // not a list element
+      )
+  {
+    const ideal id = (const ideal)h->Data();
+
+    assume(id != NULL);
+
+    if( UNLIKELY( OPT__DEBUG ) )
+    {
+      PrintS("Sort_c_ds::Input: \n");
+      dPrint(id, r, r, 0);
+    }
+
+    assume (h->Next() == NULL);
+
+    id_Test(id, r);
+
+    Sort_c_ds(id, r); // NOT A COPY! inplace sorting!!!
+
+//    res->data = id;
+//    res->rtyp = h->Typ();
+
+    if( UNLIKELY( OPT__DEBUG ) )
+    {
+      PrintS("Sort_c_ds::Output: \n");
+      dPrint(id, r, r, 0);
+    }
+
+    // NOTE: nothing is to be returned!!!
+    return FALSE;
+  }
+
+  WarnS("ComputeLeadingSyzygyTerms needs a single ideal/module argument (must be a variable!)...");
+  return TRUE;
+}
+
+
+static BOOLEAN _Compute2LeadingSyzygyTerms(leftv res, leftv h)
+{
+  const SchreyerSyzygyComputationFlags attributes(currRingHdl);
+
+  const BOOLEAN OPT__DEBUG      = attributes.OPT__DEBUG;
+//  const BOOLEAN OPT__SYZCHECK   = attributes.OPT__SYZCHECK;
+  const BOOLEAN OPT__LEAD2SYZ   = attributes.OPT__LEAD2SYZ;
+//  const BOOLEAN OPT__HYBRIDNF   = attributes.OPT__HYBRIDNF;
+//  const BOOLEAN OPT__TAILREDSYZ = attributes.OPT__TAILREDSYZ;
+
+  const ring r = attributes.m_rBaseRing;
+  NoReturn(res);
+
+  if( h == NULL )
+  {
+    WarnS("Compute2LeadingSyzygyTerms needs an argument...");
+    return TRUE;
+  }
+
+  assume( h != NULL );
+
+  assume( OPT__LEAD2SYZ ); // ???
+
+  if( h->Typ() == IDEAL_CMD || h->Typ() == MODUL_CMD)
+  {
+    const ideal id = (const ideal)h->Data();
+
+    assume(id != NULL);
+
+    if( UNLIKELY( OPT__DEBUG ) )
+    {
+      PrintS("Compute2LeadingSyzygyTerms::Input: \n");
+      dPrint(id, r, r, 0);
+    }
+
+    h = h->Next(); assume (h == NULL);
+
+    res->data = Compute2LeadingSyzygyTerms(id, attributes);
+    res->rtyp = MODUL_CMD;
+
+    return FALSE;
+  }
+
+  WarnS("Compute2LeadingSyzygyTerms needs a single ideal/module argument...");
+  return TRUE;
+}
+
+
+
+/// proc SSFindReducer(def product, def syzterm, def L, def T, list #)
+static BOOLEAN _FindReducer(leftv res, leftv h)
+{
+  const SchreyerSyzygyComputationFlags attributes(currRingHdl);
+
+  const BOOLEAN OPT__DEBUG      = attributes.OPT__DEBUG;
+//   const BOOLEAN OPT__SYZCHECK   = attributes.OPT__SYZCHECK;
+//   const BOOLEAN OPT__LEAD2SYZ   = attributes.OPT__LEAD2SYZ;
+//   const BOOLEAN OPT__HYBRIDNF   = attributes.OPT__HYBRIDNF;
+  const BOOLEAN OPT__TAILREDSYZ = attributes.OPT__TAILREDSYZ;
+
+  const char* usage = "`FindReducer(<poly/vector>, <vector/0>, <ideal/module>[,<module>])` expected";
+  const ring r = attributes.m_rBaseRing;
+
+  NoReturn(res);
+
+
+  if ((h==NULL) || (h->Typ()!=VECTOR_CMD && h->Typ() !=POLY_CMD) || (h->Data() == NULL))
+  {
+    WerrorS(usage);
+    return TRUE;
+  }
+
+  const poly product = (poly) h->Data(); assume (product != NULL);
+
+
+  h = h->Next();
+  if ((h==NULL) || !((h->Typ()==VECTOR_CMD) || (h->Data() == NULL)) )
+  {
+    WerrorS(usage);
+    return TRUE;
+  }
+
+  poly syzterm = NULL;
+
+  if(h->Typ()==VECTOR_CMD)
+    syzterm = (poly) h->Data();
+
+
+
+  h = h->Next();
+  if ((h==NULL) || (h->Typ()!=IDEAL_CMD && h->Typ() !=MODUL_CMD) || (h->Data() == NULL))
+  {
+    WerrorS(usage);
+    return TRUE;
+  }
+
+  const ideal L = (ideal) h->Data(); h = h->Next();
+
+  assume( IDELEMS(L) > 0 );
+
+  ideal LS = NULL;
+
+  if ((h != NULL) && (h->Typ() ==MODUL_CMD) && (h->Data() != NULL))
+  {
+    LS = (ideal)h->Data();
+    h = h->Next();
+  }
+
+#ifndef SING_NDEBUG
+  if( LIKELY( OPT__TAILREDSYZ) )
+    assume (LS != NULL);
+#endif
+
+  assume( h == NULL );
+
+  if( UNLIKELY(OPT__DEBUG) )
+  {
+    PrintS("FindReducer(product, syzterm, L, T, #)::Input: \n");
+
+    PrintS("product: "); dPrint(product, r, r, 0);
+    PrintS("syzterm: "); dPrint(syzterm, r, r, 0);
+//    PrintS("L: "); dPrint(L, r, r, 0);
+//    PrintS("T: "); dPrint(T, r, r, 0);
+
+    if( LS == NULL )
+//      PrintS("LS: NULL\n");
+      ;
+    else
+    {
+//      PrintS("LS: "); dPrint(LS, r, r, 0);
+    }
+  }
+
+  res->rtyp = VECTOR_CMD;
+  res->data = FindReducer(product, syzterm, L, LS, attributes);
+
+  if( UNLIKELY( OPT__DEBUG ) )
+  {
+    PrintS("FindReducer::Output: \n");
+    dPrint((poly)res->data, r, r, 0);
+  }
+
+  return FALSE;
+
+}
+
+// proc SchreyerSyzygyNF(vector syz_lead, vector syz_2, def L, def T, list #)
+static BOOLEAN _SchreyerSyzygyNF(leftv res, leftv h)
+{
+  const SchreyerSyzygyComputationFlags attributes(currRingHdl);
+
+  const BOOLEAN OPT__DEBUG      = attributes.OPT__DEBUG;
+//   const BOOLEAN OPT__SYZCHECK   = attributes.OPT__SYZCHECK;
+//   const BOOLEAN OPT__LEAD2SYZ   = attributes.OPT__LEAD2SYZ;
+  const BOOLEAN OPT__HYBRIDNF   = attributes.OPT__HYBRIDNF;
+  const BOOLEAN OPT__TAILREDSYZ = attributes.OPT__TAILREDSYZ;
+
+  const char* usage = "`SchreyerSyzygyNF(<vector>, <vector>, <ideal/module>, <ideal/module>[,<module>])` expected";
+  const ring r = attributes.m_rBaseRing;
+
+  NoReturn(res);
+
+  assume( OPT__HYBRIDNF ); // ???
+
+  if ((h==NULL) || (h->Typ() != VECTOR_CMD) || (h->Data() == NULL))
+  {
+    WerrorS(usage);
+    return TRUE;
+  }
+
+  const poly syz_lead = (poly) h->Data(); assume (syz_lead != NULL);
+
+
+  h = h->Next();
+  if ((h==NULL) || (h->Typ() != VECTOR_CMD) || (h->Data() == NULL))
+  {
+    WerrorS(usage);
+    return TRUE;
+  }
+
+  const poly syz_2 = (poly) h->Data(); assume (syz_2 != NULL);
+
+  h = h->Next();
+  if ((h==NULL) || (h->Typ()!=IDEAL_CMD && h->Typ() !=MODUL_CMD) || (h->Data() == NULL))
+  {
+    WerrorS(usage);
+    return TRUE;
+  }
+
+  const ideal L = (ideal) h->Data(); assume( IDELEMS(L) > 0 );
+
+
+  h = h->Next();
+  if ((h==NULL) || (h->Typ()!=IDEAL_CMD && h->Typ() !=MODUL_CMD) || (h->Data() == NULL))
+  {
+    WerrorS(usage);
+    return TRUE;
+  }
+
+  const ideal T = (ideal) h->Data();
+
+  assume( IDELEMS(L) == IDELEMS(T) );
+
+  ideal LS = NULL;
+
+  h = h->Next();
+  if ((h != NULL) && (h->Typ() ==MODUL_CMD) && (h->Data() != NULL))
+  {
+    LS = (ideal)h->Data();
+    h = h->Next();
+  }
+
+#ifndef SING_NDEBUG
+  if( LIKELY( OPT__TAILREDSYZ) )
+    assume (LS != NULL);
+#endif
+
+  assume( h == NULL );
+
+  if( UNLIKELY( OPT__DEBUG ) )
+  {
+    PrintS("SchreyerSyzygyNF(syz_lead, syz_2, L, T, #)::Input: \n");
+
+    PrintS("syz_lead: "); dPrint(syz_lead, r, r, 0);
+    PrintS("syz_2: "); dPrint(syz_2, r, r, 0);
+
+//    PrintS("L: "); dPrint(L, r, r, 0);
+//    PrintS("T: "); dPrint(T, r, r, 0);
+
+    if( LS == NULL )
+//      PrintS("LS: NULL\n")
+          ;
+    else
+    {
+//      PrintS("LS: "); dPrint(LS, r, r, 0);
+    }
+  }
+
+  res->rtyp = VECTOR_CMD;
+  res->data = SchreyerSyzygyNF(syz_lead,
+                               (syz_2!=NULL)? p_Copy(syz_2, r): syz_2, L, T, LS, attributes);
+
+  if( UNLIKELY( OPT__DEBUG ) )
+  {
+    PrintS("SchreyerSyzygyNF::Output: ");
+
+    dPrint((poly)res->data, r, r, 0);
+  }
+
+
+  return FALSE;
+}
+
+
+
+/// proc SSReduceTerm(poly m, def t, def syzterm, def L, def T, list #)
+static BOOLEAN _ReduceTerm(leftv res, leftv h)
+{
+  const SchreyerSyzygyComputationFlags attributes(currRingHdl);
+
+  const BOOLEAN OPT__DEBUG      = attributes.OPT__DEBUG;
+//  const BOOLEAN OPT__SYZCHECK   = attributes.OPT__SYZCHECK;
+//   const BOOLEAN OPT__LEAD2SYZ   = attributes.OPT__LEAD2SYZ;
+//   const BOOLEAN OPT__HYBRIDNF   = attributes.OPT__HYBRIDNF;
+  const BOOLEAN OPT__TAILREDSYZ = attributes.OPT__TAILREDSYZ;
+
+  const char* usage = "`ReduceTerm(<poly>, <poly/vector>, <vector/0>, <ideal/module>, <ideal/module>[,<module>])` expected";
+  const ring r = attributes.m_rBaseRing;
+
+  NoReturn(res);
+
+  if ((h==NULL) || (h->Typ() !=POLY_CMD) || (h->Data() == NULL))
+  {
+    WerrorS(usage);
+    return TRUE;
+  }
+
+  const poly multiplier = (poly) h->Data(); assume (multiplier != NULL);
+
+
+  h = h->Next();
+  if ((h==NULL) || (h->Typ()!=VECTOR_CMD && h->Typ() !=POLY_CMD) || (h->Data() == NULL))
+  {
+    WerrorS(usage);
+    return TRUE;
+  }
+
+  const poly term4reduction = (poly) h->Data(); assume( term4reduction != NULL );
+
+
+  poly syztermCheck = NULL;
+
+  h = h->Next();
+  if ((h==NULL) || !((h->Typ()==VECTOR_CMD) || (h->Data() == NULL)) )
+  {
+    WerrorS(usage);
+    return TRUE;
+  }
+
+  if(h->Typ()==VECTOR_CMD)
+    syztermCheck = (poly) h->Data();
+
+
+  h = h->Next();
+  if ((h==NULL) || (h->Typ()!=IDEAL_CMD && h->Typ() !=MODUL_CMD) || (h->Data() == NULL))
+  {
+    WerrorS(usage);
+    return TRUE;
+  }
+
+  const ideal L = (ideal) h->Data(); assume( IDELEMS(L) > 0 );
+
+
+  h = h->Next();
+  if ((h==NULL) || (h->Typ()!=IDEAL_CMD && h->Typ() !=MODUL_CMD) || (h->Data() == NULL))
+  {
+    WerrorS(usage);
+    return TRUE;
+  }
+
+  const ideal T = (ideal) h->Data();
+
+  assume( IDELEMS(L) == IDELEMS(T) );
+
+  ideal LS = NULL;
+
+  h = h->Next();
+  if ((h != NULL) && (h->Typ() ==MODUL_CMD) && (h->Data() != NULL))
+  {
+    LS = (ideal)h->Data();
+    h = h->Next();
+  }
+
+#ifndef SING_NDEBUG
+  if( LIKELY( OPT__TAILREDSYZ) )
+    assume (LS != NULL);
+#endif
+
+  assume( h == NULL );
+
+  if( UNLIKELY( OPT__DEBUG ) )
+  {
+    PrintS("ReduceTerm(m, t, syzterm, L, T, #)::Input: \n");
+
+    PrintS("m: "); dPrint(multiplier, r, r, 0);
+    PrintS("t: "); dPrint(term4reduction, r, r, 0);
+    PrintS("syzterm: "); dPrint(syztermCheck, r, r, 0);
+
+//    PrintS("L: "); dPrint(L, r, r, 0);
+//    PrintS("T: "); dPrint(T, r, r, 0);
+
+    if( LS == NULL )
+//      PrintS("LS: NULL\n")
+          ;
+    else
+    {
+//      PrintS("LS: "); dPrint(LS, r, r, 0);
+    }
+  }
+
+
+  if ( UNLIKELY( OPT__DEBUG && syztermCheck != NULL) )
+  {
+    const int c = p_GetComp(syztermCheck, r) - 1;
+    assume( c >= 0 && c < IDELEMS(L) );
+
+    const poly p = L->m[c];
+    assume( p != NULL ); assume( pNext(p) == NULL );
+
+    assume( p_EqualPolys(term4reduction, p, r) ); // assume? TODO
+
+
+    poly m = leadmonom(syztermCheck, r);
+    assume( m != NULL ); assume( pNext(m) == NULL );
+
+    assume( p_EqualPolys(multiplier, m, r) ); // assume? TODO
+
+    p_Delete(&m, r);
+
+// NOTE:   leadmonomial(syzterm) == m &&  L[leadcomp(syzterm)] == t
+  }
+
+  res->rtyp = VECTOR_CMD;
+  res->data = ReduceTerm(multiplier, term4reduction, syztermCheck, L, T, LS, attributes);
+
+
+  if( UNLIKELY( OPT__DEBUG ) )
+  {
+    PrintS("ReduceTerm::Output: ");
+
+    dPrint((poly)res->data, r, r, 0);
+  }
+
+
+  return FALSE;
+}
+
+
+
+
+// proc SSTraverseTail(poly m, def @tail, def L, def T, list #)
+static BOOLEAN _TraverseTail(leftv res, leftv h)
+{
+  const SchreyerSyzygyComputationFlags attributes(currRingHdl);
+
+  const BOOLEAN OPT__DEBUG      = attributes.OPT__DEBUG;
+//   const BOOLEAN OPT__SYZCHECK   = attributes.OPT__SYZCHECK;
+//   const BOOLEAN OPT__LEAD2SYZ   = attributes.OPT__LEAD2SYZ;
+//   const BOOLEAN OPT__HYBRIDNF   = attributes.OPT__HYBRIDNF;
+  const BOOLEAN OPT__TAILREDSYZ = attributes.OPT__TAILREDSYZ;
+
+  const char* usage = "`TraverseTail(<poly>, <poly/vector>, <ideal/module>, <ideal/module>[,<module>])` expected";
+  const ring r = attributes.m_rBaseRing;
+
+  NoReturn(res);
+
+  if ((h==NULL) || (h->Typ() !=POLY_CMD) || (h->Data() == NULL))
+  {
+    WerrorS(usage);
+    return TRUE;
+  }
+
+  const poly multiplier = (poly) h->Data(); assume (multiplier != NULL);
+
+  h = h->Next();
+  if ((h==NULL) || (h->Typ()!=VECTOR_CMD && h->Typ() !=POLY_CMD))
+  {
+    WerrorS(usage);
+    return TRUE;
+  }
+
+  const poly tail = (poly) h->Data();
+
+  h = h->Next();
+
+  if ((h==NULL) || (h->Typ()!=IDEAL_CMD && h->Typ() !=MODUL_CMD) || (h->Data() == NULL))
+  {
+    WerrorS(usage);
+    return TRUE;
+  }
+
+  const ideal L = (ideal) h->Data();
+
+  assume( IDELEMS(L) > 0 );
+
+  h = h->Next();
+  if ((h==NULL) || (h->Typ()!=IDEAL_CMD && h->Typ() !=MODUL_CMD) || (h->Data() == NULL))
+  {
+    WerrorS(usage);
+    return TRUE;
+  }
+
+  const ideal T = (ideal) h->Data();
+
+  assume( IDELEMS(L) == IDELEMS(T) );
+
+  h = h->Next();
+
+  ideal LS = NULL;
+
+  if ((h != NULL) && (h->Typ() ==MODUL_CMD) && (h->Data() != NULL))
+  {
+    LS = (ideal)h->Data();
+    h = h->Next();
+  }
+
+#ifndef SING_NDEBUG
+  if( LIKELY( OPT__TAILREDSYZ) )
+    assume (LS != NULL);
+#endif
+
+  assume( h == NULL );
+
+  if( UNLIKELY( OPT__DEBUG ) )
+  {
+    PrintS("TraverseTail(m, t, L, T, #)::Input: \n");
+
+    PrintS("m: "); dPrint(multiplier, r, r, 0);
+    PrintS("t: "); dPrint(tail, r, r, 0);
+
+//    PrintS("L: "); dPrint(L, r, r, 0);
+//    PrintS("T: "); dPrint(T, r, r, 0);
+
+    if( LS == NULL )
+//      PrintS("LS: NULL\n")
+          ;
+    else
+    {
+//      PrintS("LS: "); dPrint(LS, r, r, 0);
+    }
+  }
+
+  res->rtyp = VECTOR_CMD;
+  res->data = TraverseTail(multiplier, tail, L, T, LS, attributes);
+
+
+  if( UNLIKELY( OPT__DEBUG ) )
+  {
+    PrintS("TraverseTail::Output: ");
+    dPrint((poly)res->data, r, r, 0);
+  }
+
+  return FALSE;
+}
+
+
+static BOOLEAN _ComputeResolution(leftv res, leftv h)
+{
+  const SchreyerSyzygyComputationFlags attributes(currRingHdl);
+
+  const BOOLEAN OPT__DEBUG      = attributes.OPT__DEBUG;
+
+  const char* usage = "`ComputeResolution(<ideal/module>, <same as before>, <same as before>[,int])` expected";
+  const ring r = attributes.m_rBaseRing;
+
+  NoReturn(res);
+
+  // input
+  if ((h==NULL) || (h->Typ()!=IDEAL_CMD && h->Typ() !=MODUL_CMD) || (h->Data() == NULL))
+  {
+    WerrorS(usage);
+    return TRUE;
+  }
+
+  const int type = h->Typ();
+  ideal M = (ideal)(h->CopyD()); // copy for resolution...!???
+  int size = IDELEMS(M);
+
+  assume( size >= 0 );
+
+  h = h->Next();
+
+  // lead
+  if ((h==NULL) || (h->Typ()!=type) || (h->Data() == NULL))
+  {
+    WerrorS(usage);
+    return TRUE;
+  }
+
+  ideal L = (ideal)(h->CopyD()); // no copy!
+  assume( IDELEMS(L) == size );
+
+  h = h->Next();
+  if ((h==NULL) || (h->Typ()!=type) || (h->Data() == NULL))
+  {
+    WerrorS(usage);
+    return TRUE;
+  }
+
+  ideal T = (ideal)(h->CopyD()); // no copy!
+  assume( IDELEMS(T) == size );
+
+  h = h->Next();
+
+  // length..?
+  long length = 0;
+
+  if ((h!=NULL) && (h->Typ()==INT_CMD))
+  {
+    length = (long)(h->Data());
+    h = h->Next();
+  }
+
+  assume( h == NULL );
+
+  if( length <= 0 )
+    length = 1 + rVar(r);
+
+  if( UNLIKELY( OPT__DEBUG ) )
+  {
+    PrintS("ComputeResolution(M, length)::Input: \n");
+    Print( "starting length: %ld\n", length);
+    PrintS("M: \n"); dPrint(M, r, r, 0);
+    PrintS("L=LEAD(M): \n"); dPrint(L, r, r, 0);
+    PrintS("T=TAIL(M): \n"); dPrint(T, r, r, 0);
+  }
+
+
+  syStrategy _res=(syStrategy)omAlloc0(sizeof(ssyStrategy));
+
+//  class ssyStrategy; typedef ssyStrategy * syStrategy;
+//  typedef ideal *            resolvente;
+
+  _res->length = length + 1; // index + 1;
+  _res->fullres = (resolvente)omAlloc0((_res->length+1)*sizeof(ideal));
+  int index = 0;
+  _res->fullres[index++] = M;
+
+//  if (UNLIKELY(attributes.OPT__TREEOUTPUT))
+//    Print("{ \"RESOLUTION: HYBRIDNF:%d, TAILREDSYZ: %d, LEAD2SYZ: %d, IGNORETAILS: %d\": [\n", attributes.OPT__HYBRIDNF, attributes.OPT__TAILREDSYZ, attributes.OPT__LEAD2SYZ, attributes.OPT__IGNORETAILS);
+
+  while( (!idIs0(L)) && (index < length))
+  {
+    attributes.nextSyzygyLayer();
+    ideal LL, TT;
+
+    ComputeSyzygy(L, T, LL, TT, attributes);
+
+    if( UNLIKELY( OPT__DEBUG ) )
+    {
+      Print("ComputeResolution()::Separated Syzygy[%d]: \n", index);
+//      PrintS("LL: \n"); dPrint(LL, r, r, 0);
+//      PrintS("TT: \n"); dPrint(TT, r, r, 0);
+    }
+    size = IDELEMS(LL);
+
+    assume( size == IDELEMS(TT) );
+
+    id_Delete(&L, r); id_Delete(&T, r);
+
+    L = LL; T = TT;
+
+    // id_Add(T, L, r);
+    M = idInit(size, 0);
+    for( int i = size-1; i >= 0; i-- )
+    {
+      M->m[i] = p_Add_q(p_Copy(T->m[i], r), p_Copy(L->m[i], r), r); // TODO: :(((
+    }
+    M->rank = id_RankFreeModule(M, r);
+
+    if( UNLIKELY( OPT__DEBUG ) )
+    {
+      Print("ComputeResolution()::Restored Syzygy[%d]: \n", index);
+      PrintS("M = LL + TT: \n"); dPrint(M, r, r, 0);
+    }
+
+    _res->fullres[index++] = M; // ???
+  }
+//  if ( UNLIKELY(attributes.OPT__TREEOUTPUT) )
+//    PrintS("] }\n");
+
+  id_Delete(&L, r); id_Delete(&T, r);
+
+  res->data = _res;
+  res->rtyp = RESOLUTION_CMD;
+
+  if( UNLIKELY(OPT__DEBUG) )
+  {
+    Print("ComputeResolution::Output (index: %d): ", index);
+//    class sleftv; typedef sleftv * leftv;
+    sleftv _h;
+    DetailedPrint(&_h, res);
+  }
+
+//  omFreeSize(_res, sizeof(ssyStrategy));
+
+  return FALSE;
+
+}
+
+
+/// module (LL, TT) = SSComputeSyzygy(L, T);
+/// Compute Syz(L ++ T) = N = LL ++ TT
+// proc SSComputeSyzygy(def L, def T)
+static BOOLEAN _ComputeSyzygy(leftv res, leftv h)
+{
+  const SchreyerSyzygyComputationFlags attributes(currRingHdl);
+
+  const BOOLEAN OPT__DEBUG      = attributes.OPT__DEBUG;
+//   const BOOLEAN OPT__SYZCHECK   = attributes.OPT__SYZCHECK;
+//   const BOOLEAN OPT__LEAD2SYZ   = attributes.OPT__LEAD2SYZ;
+//   const BOOLEAN OPT__HYBRIDNF   = attributes.OPT__HYBRIDNF;
+//   const BOOLEAN OPT__TAILREDSYZ = attributes.OPT__TAILREDSYZ;
+
+  const char* usage = "`ComputeSyzygy(<ideal/module>, <ideal/module>)` expected";
+  const ring r = attributes.m_rBaseRing;
+
+  NoReturn(res);
+
+  if ((h==NULL) || (h->Typ()!=IDEAL_CMD && h->Typ() !=MODUL_CMD) || (h->Data() == NULL))
+  {
+    WerrorS(usage);
+    return TRUE;
+  }
+
+  const ideal L = (ideal) h->Data();
+
+  assume( IDELEMS(L) > 0 );
+
+  h = h->Next();
+  if ((h==NULL) || (h->Typ()!=IDEAL_CMD && h->Typ() !=MODUL_CMD) || (h->Data() == NULL))
+  {
+    WerrorS(usage);
+    return TRUE;
+  }
+
+  const ideal T = (ideal) h->Data();
+  assume( IDELEMS(L) == IDELEMS(T) );
+
+
+  h = h->Next(); assume( h == NULL );
+
+  if( UNLIKELY( OPT__DEBUG ) )
+  {
+    PrintS("ComputeSyzygy(L, T)::Input: \n");
+//    PrintS("L: "); dPrint(L, r, r, 0);
+//    PrintS("T: "); dPrint(T, r, r, 0);
+  }
+
+  ideal LL, TT;
+
+  ComputeSyzygy(L, T, LL, TT, attributes);
+
+  lists l = (lists)omAllocBin(slists_bin); l->Init(2);
+
+  l->m[0].rtyp = MODUL_CMD; l->m[0].data = reinterpret_cast<void *>(LL);
+
+  l->m[1].rtyp = MODUL_CMD; l->m[1].data = reinterpret_cast<void *>(TT);
+
+  res->data = l; res->rtyp = LIST_CMD;
+
+  if( UNLIKELY( OPT__DEBUG ) )
+  {
+    PrintS("ComputeSyzygy::Output: \nLL: \n");
+    dPrint(LL, r, r, 0);
+    PrintS("\nTT: \n");
+    dPrint(TT, r, r, 0);
+  }
+
+  return FALSE;
+
+}
+
+/// Get leading term without a module component
+static BOOLEAN _leadmonom(leftv res, leftv h)
+{
+  NoReturn(res);
+
+  if ((h!=NULL) && (h->Typ()==VECTOR_CMD || h->Typ()==POLY_CMD) && (h->Data() != NULL))
+  {
+    const ring r = currRing;
+    const poly p = (poly)(h->Data());
+
+    res->data = reinterpret_cast<void *>(  leadmonom(p, r) );
+    res->rtyp = POLY_CMD;
+
+    return FALSE;
+  }
+
+  WerrorS("`leadmonom(<poly/vector>)` expected");
+  return TRUE;
+}
+
+/// Get leading component
+static BOOLEAN leadcomp(leftv res, leftv h)
+{
+  NoReturn(res);
+
+  if ((h!=NULL) && (h->Typ()==VECTOR_CMD || h->Typ()==POLY_CMD))
+  {
+    const ring r = currRing;
+
+    const poly p = (poly)(h->Data());
+
+    if (p != NULL )
+    {
+      assume( p != NULL );
+      p_LmTest(p, r);
+
+      const unsigned long iComp = p_GetComp(p, r);
+
+  //    assume( iComp > 0 ); // p is a vector
+
+      res->data = reinterpret_cast<void *>(jjLONG2N(iComp));
+    } else
+      res->data = reinterpret_cast<void *>(jjLONG2N(0));
+
+
+    res->rtyp = BIGINT_CMD;
+    return FALSE;
+  }
+
+  WerrorS("`leadcomp(<poly/vector>)` expected");
+  return TRUE;
+}
+
+
+
+
+/// Get raw leading exponent vector
+static BOOLEAN leadrawexp(leftv res, leftv h)
+{
+  NoReturn(res);
+
+  if ((h!=NULL) && (h->Typ()==VECTOR_CMD || h->Typ()==POLY_CMD) && (h->Data() != NULL))
+  {
+    const ring r = currRing;
+    const poly p = (poly)(h->Data());
+
+    assume( p != NULL );
+    p_LmTest(p, r);
+
+    const int iExpSize = r->ExpL_Size;
+
+//    intvec *iv = new intvec(iExpSize);
+
+    lists l=(lists)omAllocBin(slists_bin);
+    l->Init(iExpSize);
+
+    for(int i = iExpSize-1; i >= 0; i--)
+    {
+      l->m[i].rtyp = BIGINT_CMD;
+      l->m[i].data = reinterpret_cast<void *>(jjLONG2N(p->exp[i])); // longs...
+    }
+
+    res->rtyp = LIST_CMD; // list of bigints
+    res->data = reinterpret_cast<void *>(l);
+    return FALSE;
+  }
+
+  WerrorS("`leadrawexp(<poly/vector>)` expected");
+  return TRUE;
+}
+
+
+/// Endowe the current ring with additional (leading) Syz-component ordering
+static BOOLEAN MakeSyzCompOrdering(leftv res, leftv /*h*/)
+{
+
+  NoReturn(res);
+
+  //    res->data = rCurrRingAssure_SyzComp(); // changes current ring! :(
+  res->data = reinterpret_cast<void *>(rAssure_SyzComp(currRing, TRUE));
+  res->rtyp = RING_CMD; // return new ring!
+  // QRING_CMD?
+
+  return FALSE;
+}
+
+
+/// Same for Induced Schreyer ordering (ordering on components is defined by sign!)
+static BOOLEAN MakeInducedSchreyerOrdering(leftv res, leftv h)
+{
+
+  NoReturn(res);
+
+  int sign = 1;
+  if ((h!=NULL) && (h->Typ()==INT_CMD))
+  {
+    const int s = (int)((long)(h->Data()));
+
+    if( s != -1 && s != 1 )
+    {
+      WerrorS("`MakeInducedSchreyerOrdering(<int>)` called with wrong integer argument (must be +-1)!");
+      return TRUE;
+    }
+
+    sign = s;
+  }
+
+  assume( sign == 1 || sign == -1 );
+  res->data = reinterpret_cast<void *>(rAssure_InducedSchreyerOrdering(currRing, TRUE, sign));
+  res->rtyp = RING_CMD; // return new ring!
+  // QRING_CMD?
+  return FALSE;
+}
+
+
+/// Returns old SyzCompLimit, can set new limit
+static BOOLEAN SetSyzComp(leftv res, leftv h)
+{
+  NoReturn(res);
+
+  const ring r = currRing;
+
+  if( !rIsSyzIndexRing(r) )
+  {
+    WerrorS("`SetSyzComp(<int>)` called on incompatible ring (not created by 'MakeSyzCompOrdering'!)");
+    return TRUE;
+  }
+
+  res->rtyp = INT_CMD;
+  res->data = reinterpret_cast<void *>(rGetCurrSyzLimit(r)); // return old syz limit
+
+  if ((h!=NULL) && (h->Typ()==INT_CMD))
+  {
+    const int iSyzComp = (int)reinterpret_cast<long>(h->Data());
+    assume( iSyzComp > 0 );
+    rSetSyzComp(iSyzComp, currRing);
+  }
+
+  return FALSE;
+}
+
+/// ?
+static BOOLEAN GetInducedData(leftv res, leftv h)
+{
+  NoReturn(res);
+
+  const ring r = currRing;
+
+  int p = 0; // which IS-block? p^th!
+
+  if ((h!=NULL) && (h->Typ()==INT_CMD))
+  {
+    p = (int)((long)(h->Data())); h=h->next;
+    assume(p >= 0);
+  }
+
+  const int pos = rGetISPos(p, r);
+
+  if(  /*(*/ -1 == pos /*)*/  )
+  {
+    WerrorS("`GetInducedData([int])` called on incompatible ring (not created by 'MakeInducedSchreyerOrdering'!)");
+    return TRUE;
+  }
+
+
+  const int iLimit = r->typ[pos].data.is.limit;
+  const ideal F = r->typ[pos].data.is.F;
+  ideal FF = id_Copy(F, r);
+
+
+
+  lists l=(lists)omAllocBin(slists_bin);
+  l->Init(2);
+
+  l->m[0].rtyp = INT_CMD;
+  l->m[0].data = reinterpret_cast<void *>(iLimit);
+
+
+  //        l->m[1].rtyp = MODUL_CMD;
+
+  if( idIsModule(FF, r) )
+  {
+    l->m[1].rtyp = MODUL_CMD;
+
+    //          Print("before: %d\n", FF->nrows);
+    //          FF->nrows = id_RankFreeModule(FF, r); // ???
+    //          Print("after: %d\n", FF->nrows);
+  }
+  else
+    l->m[1].rtyp = IDEAL_CMD;
+
+  l->m[1].data = reinterpret_cast<void *>(FF);
+
+  res->rtyp = LIST_CMD; // list of int/module
+  res->data = reinterpret_cast<void *>(l);
+
+  return FALSE;
+
+}
+
+
+/* // the following turned out to be unnecessary...
+/// Finds p^th AM ordering, and returns its position in r->typ[] AND
+/// corresponding &r->wvhdl[]
+/// returns FALSE if something went wrong!
+/// p - starts with 0!
+BOOLEAN rGetAMPos(const ring r, const int p, int &typ_pos, int &wvhdl_pos, const BOOLEAN bSearchWvhdl = FALSE)
+{
+#if MYTEST
+  Print("rGetAMPos(p: %d...)\nF:", p);
+  PrintLn();
+#endif
+  typ_pos = -1;
+  wvhdl_pos = -1;
+
+  if (r->typ==NULL)
+    return FALSE;
+
+
+  int j = p; // Which IS record to use...
+  for( int pos = 0; pos < r->OrdSize; pos++ )
+    if( r->typ[pos].ord_typ == ro_am)
+      if( j-- == 0 )
+      {
+        typ_pos = pos;
+
+        if( bSearchWvhdl )
+        {
+          const int nblocks = rBlocks(r) - 1;
+          const int* w = r->typ[pos].data.am.weights; // ?
+
+          for( pos = 0; pos <= nblocks; pos ++ )
+            if (r->order[pos] == ringorder_am)
+              if( r->wvhdl[pos] == w )
+              {
+                wvhdl_pos = pos;
+                break;
+              }
+          if (wvhdl_pos < 0)
+            return FALSE;
+
+          assume(wvhdl_pos >= 0);
+        }
+        assume(typ_pos >= 0);
+        return TRUE;
+      }
+
+  return FALSE;
+}
+
+// // ?
+// static BOOLEAN GetAMData(leftv res, leftv h)
+// {
+//   NoReturn(res);
+//
+//   const ring r = currRing;
+//
+//   int p = 0; // which IS-block? p^th!
+//
+//   if ((h!=NULL) && (h->Typ()==INT_CMD))
+//     p = (int)((long)(h->Data())); h=h->next;
+//
+//   assume(p >= 0);
+//
+//   int d, w;
+//
+//   if( !rGetAMPos(r, p, d, w, TRUE) )
+//   {
+//     Werror("`GetAMData([int])`: no %d^th _am block-ordering!", p);
+//     return TRUE;
+//   }
+//
+//   assume( r->typ[d].ord_typ == ro_am );
+//   assume( r->order[w] == ringorder_am );
+//
+//
+//   const short start = r->typ[d].data.am.start;  // bounds of ordering (in E)
+//   const short end = r->typ[d].data.am.end;
+//   const short len_gen = r->typ[d].data.am.len_gen; // i>len_gen: weight(gen(i)):=0
+//   const int *weights = r->typ[d].data.am.weights; // pointers into wvhdl field of length (end-start+1) + len_gen
+//   // contents w_1,... w_n, len, mod_w_1, .. mod_w_len, 0
+//
+//   assume( weights == r->wvhdl[w] );
+//
+//
+//   lists l=(lists)omAllocBin(slists_bin);
+//   l->Init(2);
+//
+//   const short V = end-start+1;
+//   intvec* ww_vars = new intvec(V);
+//   intvec* ww_gens = new intvec(len_gen);
+//
+//   for (int i = 0; i < V; i++ )
+//     (*ww_vars)[i] = weights[i];
+//
+//   assume( weights[V] == len_gen );
+//
+//   for (int i = 0; i < len_gen; i++ )
+//     (*ww_gens)[i] = weights[i - V - 1];
+//
+//
+//   l->m[0].rtyp = INTVEC_CMD;
+//   l->m[0].data = reinterpret_cast<void *>(ww_vars);
+//
+//   l->m[1].rtyp = INTVEC_CMD;
+//   l->m[1].data = reinterpret_cast<void *>(ww_gens);
+//
+//
+//   return FALSE;
+//
+// }
+*/
+
+/// Returns old SyzCompLimit, can set new limit
+static BOOLEAN SetInducedReferrence(leftv res, leftv h)
+{
+  NoReturn(res);
+
+  const ring r = currRing;
+
+  if( !( (h!=NULL) && ( (h->Typ()==IDEAL_CMD) || (h->Typ()==MODUL_CMD))) )
+  {
+    WerrorS("`SetInducedReferrence(<ideal/module>, [int[, int]])` expected");
+    return TRUE;
+  }
+
+  const ideal F = (ideal)h->Data(); ; // No copy!
+  h=h->next;
+
+  int rank = 0;
+
+  if ((h!=NULL) && (h->Typ()==INT_CMD))
+  {
+    rank = (int)((long)(h->Data())); h=h->next;
+    assume(rank >= 0);
+  } else
+    rank = id_RankFreeModule(F, r); // Starting syz-comp (1st: i+1)
+
+  int p = 0; // which IS-block? p^th!
+
+  if ((h!=NULL) && (h->Typ()==INT_CMD))
+  {
+    p = (int)((long)(h->Data())); h=h->next;
+    assume(p >= 0);
+  }
+
+  const int posIS = rGetISPos(p, r);
+
+  if(  /*(*/ -1 == posIS /*)*/  )
+  {
+    WerrorS("`SetInducedReferrence(<ideal/module>, [int[, int]])` called on incompatible ring (not created by 'MakeInducedSchreyerOrdering'!)");
+    return TRUE;
+  }
+
+
+
+  // F & componentWeights belong to that ordering block of currRing now:
+  rSetISReference(r, F, rank, p); // F will be copied!
+  return FALSE;
+}
+
+
+//    F = ISUpdateComponents( F, V, MIN );
+//    // replace gen(i) -> gen(MIN + V[i-MIN]) for all i > MIN in all terms from F!
+static BOOLEAN ISUpdateComponents(leftv res, leftv h)
+{
+  NoReturn(res);
+
+  PrintS("ISUpdateComponents:.... \n");
+
+  if ((h!=NULL) && (h->Typ()==MODUL_CMD))
+  {
+    ideal F = (ideal)h->Data(); ; // No copy!
+    h=h->next;
+
+    if ((h!=NULL) && (h->Typ()==INTVEC_CMD))
+    {
+      const intvec* const V = (const intvec* const) h->Data();
+      h=h->next;
+
+      if ((h!=NULL) && (h->Typ()==INT_CMD))
+      {
+        const int MIN = (int)((long)(h->Data()));
+
+        pISUpdateComponents(F, V, MIN, currRing);
+        return FALSE;
+      }
+    }
+  }
+
+  WerrorS("`ISUpdateComponents(<module>, intvec, int)` expected");
+  return TRUE;
+}
+
+
+/// NF using length
+static BOOLEAN reduce_syz(leftv res, leftv h)
+{
+  // const ring r = currRing;
+
+  if ( !( (h!=NULL) && (h->Typ()==VECTOR_CMD || h->Typ()==POLY_CMD) ) )
+  {
+    WerrorS("`reduce_syz(<poly/vector>!, <ideal/module>, <int>, [int])` expected");
+    return TRUE;
+  }
+
+  res->rtyp = h->Typ();
+  const poly v = reinterpret_cast<poly>(h->Data());
+  h=h->next;
+
+  if ( !( (h!=NULL) && (h->Typ()==MODUL_CMD || h->Typ()==IDEAL_CMD ) ) )
+  {
+    WerrorS("`reduce_syz(<poly/vector>, <ideal/module>!, <int>, [int])` expected");
+    return TRUE;
+  }
+
+  assumeStdFlag(h);
+  const ideal M = reinterpret_cast<ideal>(h->Data()); h=h->next;
+
+
+  if ( !( (h!=NULL) && (h->Typ()== INT_CMD)  ) )
+  {
+    WerrorS("`reduce_syz(<poly/vector>, <ideal/module>, <int>!, [int])` expected");
+    return TRUE;
+  }
+
+  const int iSyzComp = (int)((long)(h->Data())); h=h->next;
+
+  int iLazyReduce = 0;
+
+  if ( ( (h!=NULL) && (h->Typ()== INT_CMD)  ) )
+    iLazyReduce = (int)((long)(h->Data()));
+
+  res->data = (void *)kNFLength(M, currRing->qideal, v, iSyzComp, iLazyReduce); // NOTE: currRing :(
+  return FALSE;
+}
+
+
+/// Get raw syzygies (idPrepare)
+static BOOLEAN idPrepare(leftv res, leftv h)
+{
+  //        extern int rGetISPos(const int p, const ring r);
+
+  const ring r = currRing;
+
+  const bool isSyz = rIsSyzIndexRing(r);
+  const int posIS = rGetISPos(0, r);
+
+
+  if ( !( (h!=NULL) && (h->Typ()==MODUL_CMD) && (h->Data() != NULL) ) )
+  {
+    WerrorS("`idPrepare(<module>)` expected");
+    return TRUE;
+  }
+
+  const ideal I = reinterpret_cast<ideal>(h->Data());
+
+  assume( I != NULL );
+  idTest(I);
+
+  int iComp = -1;
+
+  h=h->next;
+  if ( (h!=NULL) && (h->Typ()==INT_CMD) )
+  {
+    iComp = (int)((long)(h->Data()));
+  } else
+  {
+      if( (!isSyz) && (-1 == posIS) )
+      {
+        WerrorS("`idPrepare(<...>)` called on incompatible ring (not created by 'MakeSyzCompOrdering' or 'MakeInducedSchreyerOrdering'!)");
+        return TRUE;
+      }
+
+    if( isSyz )
+      iComp = rGetCurrSyzLimit(r);
+    else
+      iComp = id_RankFreeModule(r->typ[posIS].data.is.F, r); // ;
+  }
+
+  assume(iComp >= 0);
+
+
+  intvec* w = reinterpret_cast<intvec *>(atGet(h, "isHomog", INTVEC_CMD));
+  tHomog hom = testHomog;
+
+  //           int add_row_shift = 0;
+  //
+  if (w!=NULL)
+  {
+    w = ivCopy(w);
+  //             add_row_shift = ww->min_in();
+  //
+  //             (*ww) -= add_row_shift;
+  //
+  //             if (idTestHomModule(I, currRing->qideal, ww))
+  //             {
+    hom = isHomog;
+  //               w = ww;
+  //             }
+  //             else
+  //             {
+  //               //WarnS("wrong weights");
+  //               delete ww;
+  //               w = NULL;
+  //               hom=testHomog;
+  //             }
+  }
+
+
+  // computes syzygies of h1,
+  // works always in a ring with ringorder_s
+  // NOTE: rSetSyzComp(syzcomp) should better be called beforehand
+  //        ideal idPrepare (ideal  h1, tHomog hom, int syzcomp, intvec **w);
+
+  ideal J = // idPrepare( I, hom, iComp, &w);
+           kStd(I, currRing->qideal, hom, &w, NULL, iComp);
+
+  idTest(J);
+
+  if (w!=NULL)
+    atSet(res, omStrDup("isHomog"), w, INTVEC_CMD);
+  //             if (w!=NULL) delete w;
+
+  res->rtyp = MODUL_CMD;
+  res->data = reinterpret_cast<void *>(J);
+  return FALSE;
+}
+
+/// Get raw syzygies (idPrepare)
+static BOOLEAN _p_Content(leftv res, leftv h)
+{
+  if ( !( (h!=NULL) && (h->Typ()==POLY_CMD) && (h->Data() != NULL) ) )
+  {
+    WerrorS("`p_Content(<poly-var>)` expected");
+    return TRUE;
+  }
+
+
+  const poly p = reinterpret_cast<poly>(h->Data());
+
+
+  pTest(p);  pWrite(p); PrintLn();
+
+
+  p_Content( p, currRing);
+
+  pTest(p);
+  pWrite(p); PrintLn();
+
+  NoReturn(res);
+  return FALSE;
+}
+
+static BOOLEAN _m2_end(leftv res, leftv h)
+{
+  int ret = 0;
+
+  if ( (h!=NULL) && (h->Typ()!=INT_CMD) )
+  {
+    WerrorS("`m2_end([<int>])` expected");
+    return TRUE;
+  }
+  ret = (int)(long)(h->Data());
+
+  m2_end( ret );
+
+  NoReturn(res);
+  return FALSE;
+}
+
+// no args.
+// init num stats
+static BOOLEAN _NumberStatsInit(leftv res, leftv h)
+{
+  if ( (h!=NULL) && (h->Typ()!=INT_CMD) )
+  {
+    WerrorS("`NumberStatsInit([<int>])` expected");
+    return TRUE;
+  }
+
+  unsigned long v = 0;
+
+  if( h != NULL )
+    v = (unsigned long)(h->Data());
+
+  number_stats_Init(v);
+
+  NoReturn(res);
+  return FALSE;
+}
+
+// maybe one arg.
+// print num stats
+static BOOLEAN _NumberStatsPrint(leftv res, leftv h)
+{
+  if ( (h!=NULL) && (h->Typ()!=STRING_CMD) )
+  {
+    WerrorS("`NumberStatsPrint([<string>])` expected");
+    return TRUE;
+  }
+
+  const char* msg = NULL;
+
+  if( h != NULL )
+    msg = (const char*)(h->Data());
+
+  number_stats_Print(msg);
+
+  NoReturn(res);
+  return FALSE;
+}
+
+END_NAMESPACE
+
+extern "C" int SI_MOD_INIT(syzextra)(SModulFunctions* psModulFunctions)
+{
+
+#define ADD(C,D,E) \
+  psModulFunctions->iiAddCproc((currPack->libname? currPack->libname: ""), (char*)C, D, E);
+
+
+// #define ADD(A,B,C,D,E) ADD0(iiAddCproc, "", C, D, E)
+
+//#define ADD0(A,B,C,D,E) A(B, (char*)C, D, E)
+// #define ADD(A,B,C,D,E) ADD0(A->iiAddCproc, B, C, D, E)
+  ADD("ClearContent", FALSE, _ClearContent);
+  ADD("ClearDenominators", FALSE, _ClearDenominators);
+
+  ADD("m2_end", FALSE, _m2_end);
+
+  ADD("DetailedPrint", FALSE, DetailedPrint);
+  ADD("leadmonomial", FALSE, _leadmonom);
+  ADD("leadcomp", FALSE, leadcomp);
+  ADD("leadrawexp", FALSE, leadrawexp);
+
+  ADD("ISUpdateComponents", FALSE, ISUpdateComponents);
+  ADD("SetInducedReferrence", FALSE, SetInducedReferrence);
+  ADD("GetInducedData", FALSE, GetInducedData);
+  ADD("SetSyzComp", FALSE, SetSyzComp);
+  ADD("MakeInducedSchreyerOrdering", FALSE, MakeInducedSchreyerOrdering);
+  ADD("MakeSyzCompOrdering", FALSE, MakeSyzCompOrdering);
+
+  ADD("ProfilerStart", FALSE, _ProfilerStart);
+  ADD("ProfilerStop",  FALSE, _ProfilerStop );
+
+  ADD("noop", FALSE, noop);
+  ADD("idPrepare", FALSE, idPrepare);
+  ADD("reduce_syz", FALSE, reduce_syz);
+
+  ADD("p_Content", FALSE, _p_Content);
+
+  ADD("Tail", FALSE, Tail);
+
+  ADD("ComputeLeadingSyzygyTerms", FALSE, _ComputeLeadingSyzygyTerms);
+  ADD("Compute2LeadingSyzygyTerms", FALSE, _Compute2LeadingSyzygyTerms);
+
+  ADD("Sort_c_ds", FALSE, _Sort_c_ds);
+  ADD("FindReducer", FALSE, _FindReducer);
+
+
+  ADD("ReduceTerm", FALSE, _ReduceTerm);
+  ADD("TraverseTail", FALSE, _TraverseTail);
+
+
+  ADD("SchreyerSyzygyNF", FALSE, _SchreyerSyzygyNF);
+  ADD("ComputeSyzygy", FALSE, _ComputeSyzygy);
+
+  ADD("ComputeResolution", FALSE, _ComputeResolution);
+//  ADD("GetAMData", FALSE, GetAMData);
+
+  ADD("NumberStatsInit", FALSE, _NumberStatsInit);
+  ADD("NumberStatsPrint", FALSE, _NumberStatsPrint);
+
+  //  ADD("", FALSE, );
+
+#undef ADD
+  return MAX_TOK;
+}
diff --git a/Singular/dyn_modules/syzextra/myNF.cc b/Singular/dyn_modules/syzextra/myNF.cc
new file mode 100644
index 0000000..505c240
--- /dev/null
+++ b/Singular/dyn_modules/syzextra/myNF.cc
@@ -0,0 +1,339 @@
+// -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+/*****************************************************************************\
+ * Computer Algebra System SINGULAR
+\*****************************************************************************/
+/** @file DebugPrint.cc
+ *
+ * Here we implement dPrint-s.
+ *
+ * ABSTRACT: debug-detailed-printing
+ *
+ * @author Oleksandr Motsak
+ *
+ *
+ **/
+/*****************************************************************************/
+
+
+
+
+
+// include header file
+#include <kernel/mod2.h>
+
+
+#include <omalloc/omalloc.h>
+
+#include <misc/intvec.h>
+
+#include <misc/options.h>
+
+#include <polys/monomials/p_polys.h>
+#include <polys/kbuckets.h>
+
+
+#include <kernel/structs.h>
+
+
+
+#include <kernel/ideals.h>
+
+#include <kernel/GBEngine/syz.h>
+// #include <kernel/longrat.h>
+#include <kernel/GBEngine/kutil.h>
+#include <kernel/GBEngine/kstd1.h>
+
+
+
+#include <kernel/polys.h>
+// #include <kernel/pInline2.h>
+
+#include "myNF.h"
+
+
+#ifdef HAVE_PLURAL
+#define PLURAL_INTERNAL_DECLARATIONS 1
+#endif
+
+#include <polys/nc/sca.h>
+#include <polys/nc/nc.h>
+#include <kernel/GBEngine/nc.h>
+
+
+
+BEGIN_NAMESPACE()
+
+///  reduction procedure for the normal form, which uses pLength instead of pSize!
+static poly redNFLength (poly h,int &max_ind,int nonorm,kStrategy strat)
+{
+  if (h==NULL) return NULL;
+  int j;
+  max_ind=strat->sl;
+
+  if (0 > strat->sl)
+  {
+    return h;
+  }
+  LObject P(h);
+  P.SetShortExpVector();
+  P.bucket = kBucketCreate(currRing);
+  kBucketInit(P.bucket,P.p,pLength(P.p));
+  kbTest(P.bucket);
+#ifdef HAVE_RINGS
+  BOOLEAN is_ring = rField_is_Ring(currRing);
+#endif
+#ifdef KDEBUG
+  if (TEST_OPT_DEBUG)
+  {
+    PrintS("redNF: starting S: ");
+    for( j = 0; j <= max_ind; j++ )
+    {
+      Print("S[%d] (of size: %d): ", j, pLength(strat->S[j]));
+      wrp(strat->S[j]);
+    }
+  };
+#endif
+
+  loop
+  {
+    j=kFindDivisibleByInS(strat,&max_ind,&P);
+    if (j>=0)
+    {
+#ifdef HAVE_RINGS
+      if (!is_ring)
+      {
+#endif
+        int sl=pLength(strat->S[j]);
+        int jj=j;
+        loop
+        {
+          int sll;
+          jj=kFindNextDivisibleByInS(strat,jj+1,max_ind,&P);
+          if (jj<0) break;
+          sll=pLength(strat->S[jj]);
+          if (sll<sl)
+          {
+#ifdef KDEBUG
+            if (TEST_OPT_DEBUG) Print("better(S%d:%d -> S%d:%d)\n",j,sl,jj,sll);
+#endif
+            //else if (TEST_OPT_PROT) { PrintS("b"); mflush(); }
+            j=jj;
+            sl=sll;
+          }
+        }
+        if ((nonorm==0) && (!nIsOne(pGetCoeff(strat->S[j]))))
+        {
+          pNorm(strat->S[j]);
+          //if (TEST_OPT_PROT) { PrintS("n"); mflush(); }
+        }
+#ifdef HAVE_RINGS
+      }
+#endif
+      nNormalize(pGetCoeff(P.p));
+#ifdef KDEBUG
+      if (TEST_OPT_DEBUG)
+      {
+        PrintS("red:");
+        wrp(h);
+        PrintS(" with ");
+        wrp(strat->S[j]);
+      }
+#endif
+#ifdef HAVE_PLURAL
+      if (rIsPluralRing(currRing))
+      {
+        number coef;
+        nc_kBucketPolyRed(P.bucket,strat->S[j],&coef);
+        nDelete(&coef);
+      }
+      else
+#endif
+      {
+        number coef;
+        coef=kBucketPolyRed(P.bucket,strat->S[j],pLength(strat->S[j]),strat->kNoether);
+        nDelete(&coef);
+      }
+      h = kBucketGetLm(P.bucket);   // FRAGE OLIVER
+      if (h==NULL)
+      {
+        kBucketDestroy(&P.bucket);
+
+#ifdef KDEBUG
+        if (TEST_OPT_DEBUG)
+        {
+          PrintS("redNF: starting S: ");
+          for( j = 0; j <= max_ind; j++ )
+          {
+            Print("S[%d] (of size: %d): ", j, pLength(strat->S[j]));
+            wrp(strat->S[j]);
+          }
+        };
+#endif
+
+        return NULL;
+      }
+      kbTest(P.bucket);
+      P.p=h;
+      P.t_p=NULL;
+      P.SetShortExpVector();
+#ifdef KDEBUG
+      if (TEST_OPT_DEBUG)
+      {
+        PrintS("\nto:");
+        wrp(h);
+        PrintLn();
+      }
+#endif
+    }
+    else
+    {
+      P.p=kBucketClear(P.bucket);
+      kBucketDestroy(&P.bucket);
+      pNormalize(P.p);
+
+#ifdef KDEBUG
+      if (TEST_OPT_DEBUG)
+      {
+        PrintS("redNF: starting S: ");
+        for( j = 0; j <= max_ind; j++ )
+        {
+          Print("S[%d] (of size: %d): ", j, pLength(strat->S[j]));
+          wrp(strat->S[j]);
+        }
+      };
+#endif
+
+      return P.p;
+    }
+  }
+}
+
+
+poly kNF2Length (ideal F,ideal Q,poly q,kStrategy strat, int lazyReduce)
+{
+  assume(q!=NULL);
+  assume(!(idIs0(F)&&(Q==NULL))); // NF(q, std(0) in polynomial ring?
+
+// lazy_reduce flags: can be combined by |
+//#define KSTD_NF_LAZY   1
+  // do only a reduction of the leading term
+//#define KSTD_NF_NONORM 4
+  // only global: avoid normalization, return a multiply of NF
+  poly   p;
+  // int   i;
+
+  //if ((idIs0(F))&&(Q==NULL))
+  //  return pCopy(q); /*F=0*/
+  //strat->ak = id_RankFreeModule(F, RING!);
+  /*- creating temp data structures------------------- -*/
+  BITSET save1;
+  SI_SAVE_OPT1(save1);
+  si_opt_1|=Sy_bit(OPT_REDTAIL);
+  initBuchMoraCrit(strat);
+  strat->initEcart = initEcartBBA;
+  strat->enterS = enterSBba;
+#ifndef NO_BUCKETS
+  strat->use_buckets = (!TEST_OPT_NOT_BUCKETS) && (!rIsPluralRing(currRing));
+#endif
+  /*- set S -*/
+  strat->sl = -1;
+  /*- init local data struct.---------------------------------------- -*/
+  /*Shdl=*/initS(F,Q,strat);
+  /*- compute------------------------------------------------------- -*/
+  //if ((TEST_OPT_INTSTRATEGY)&&(lazyReduce==0))
+  //{
+  //  for (i=strat->sl;i>=0;i--)
+  //    pNorm(strat->S[i]);
+  //}
+  kTest(strat);
+  if (TEST_OPT_PROT) { PrintS("r"); mflush(); }
+
+  if (BVERBOSE(23)) kDebugPrint(strat);
+
+  int max_ind;
+  p = redNFLength(pCopy(q),max_ind,lazyReduce & KSTD_NF_NONORM,strat);
+  if ((p!=NULL)&&((lazyReduce & KSTD_NF_LAZY)==0))
+  {
+    if (TEST_OPT_PROT) { PrintS("t"); mflush(); }
+#ifdef HAVE_RINGS
+    if (rField_is_Ring(currRing))
+    {
+      p = redtailBba_Z(p,max_ind,strat);
+    }
+    else
+#endif
+    {
+      si_opt_1 &= ~Sy_bit(OPT_INTSTRATEGY);
+      p = redtailBba(p,max_ind,strat,(lazyReduce & KSTD_NF_NONORM)==0);
+    }
+  }
+  /*- release temp data------------------------------- -*/
+  omfree(strat->sevS);
+  omfree(strat->ecartS);
+  omfree(strat->T);
+  omfree(strat->sevT);
+  omfree(strat->R);
+  omfree(strat->S_2_R);
+  omfree(strat->L);
+  omfree(strat->B);
+  omfree(strat->fromQ);
+  idDelete(&strat->Shdl);
+  SI_RESTORE_OPT1(save1);
+  if (TEST_OPT_PROT) PrintLn();
+  return p;
+}
+
+END_NAMESPACE
+
+
+BEGIN_NAMESPACE_SINGULARXX  BEGIN_NAMESPACE(NF)
+
+poly kNFLength(ideal F, ideal Q, poly p,int syzComp, int lazyReduce)
+{
+  if (p==NULL)
+    return NULL;
+
+  poly pp = p;
+
+#ifdef HAVE_PLURAL
+  if(rIsSCA(currRing))
+  {
+    const unsigned int m_iFirstAltVar = scaFirstAltVar(currRing);
+    const unsigned int m_iLastAltVar  = scaLastAltVar(currRing);
+    pp = p_KillSquares(pp, m_iFirstAltVar, m_iLastAltVar, currRing);
+
+    if(Q == currRing->qideal)
+      Q = SCAQuotient(currRing);
+  }
+#endif
+
+  if ((idIs0(F))&&(Q==NULL))
+  {
+#ifdef HAVE_PLURAL
+    if(p != pp)
+      return pp;
+#endif
+    return pCopy(p); /*F+Q=0*/
+  }
+
+  kStrategy strat=new skStrategy;
+  strat->syzComp = syzComp;
+  strat->ak = si_max(id_RankFreeModule(F, currRing),pMaxComp(p));
+  poly res;
+
+  if (rHasLocalOrMixedOrdering(currRing)==-1)
+    res=kNF1(F,Q,pp,strat,lazyReduce);
+  else
+    res=kNF2Length(F,Q,pp,strat,lazyReduce);
+  delete(strat);
+
+#ifdef HAVE_PLURAL
+  if(pp != p)
+    p_Delete(&pp, currRing);
+#endif
+  return res;
+}
+
+END_NAMESPACE               END_NAMESPACE_SINGULARXX
+
+// Vi-modeline: vim: filetype=c:syntax:shiftwidth=2:tabstop=8:textwidth=0:expandtab
diff --git a/Singular/dyn_modules/syzextra/myNF.h b/Singular/dyn_modules/syzextra/myNF.h
new file mode 100644
index 0000000..33e294a
--- /dev/null
+++ b/Singular/dyn_modules/syzextra/myNF.h
@@ -0,0 +1,47 @@
+// -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+/*****************************************************************************\
+ * Computer Algebra System SINGULAR
+\*****************************************************************************/
+/** @file myNF.h
+ *
+ * NF which uses pLength instead of pSize!
+ *
+ * ABSTRACT: NF using length
+ *
+ * @author Oleksandr Motsak
+ *
+ *
+ **/
+/*****************************************************************************/
+
+#ifndef MYNF_H
+#define MYNF_H
+
+// include basic definitions
+#include "singularxx_defs.h"
+
+struct  spolyrec;
+typedef struct spolyrec    polyrec;
+typedef polyrec *          poly;
+
+struct ip_sring;
+typedef struct ip_sring *         ring;
+
+struct sip_sideal;
+typedef struct sip_sideal *       ideal;
+
+BEGIN_NAMESPACE_SINGULARXX    BEGIN_NAMESPACE(NF)
+
+/// high-level functio, which calls kNF2Length(redNFLength)
+poly kNFLength(ideal F, ideal Q, poly p, int syzComp, int lazyReduce);
+
+END_NAMESPACE               END_NAMESPACE_SINGULARXX
+
+#endif
+/* #ifndef MYNF_H */
+
+// Vi-modeline: vim: filetype=c:syntax:shiftwidth=2:tabstop=8:textwidth=0:expandtab
+
+
+
+
diff --git a/Singular/dyn_modules/syzextra/singularxx_defs.h b/Singular/dyn_modules/syzextra/singularxx_defs.h
new file mode 100644
index 0000000..443b42d
--- /dev/null
+++ b/Singular/dyn_modules/syzextra/singularxx_defs.h
@@ -0,0 +1,74 @@
+// -*- c++ -*-
+//*****************************************************************************
+/** @file singularxx_defs.h
+ *
+ * @author Alexander Dreyer
+ * @date 2009-06-15
+ *
+ * This file includes some basic definitions for the SINGULAR++ interface.
+ *
+ * @par Copyright:
+ *   (c) 2009 by The SINGULAR Team, see LICENSE file
+ *
+**/
+//*****************************************************************************
+
+// Note: inclusion of CSINGULARTypes.h at the end
+
+
+// Get configuration
+// #include "singular_config.h"
+
+#ifndef SINGULAR_singular_defs_h_
+#define SINGULAR_singular_defs_h_
+
+
+#ifdef HAVE_NAMESPACES
+
+#define BEGIN_NAMESPACE(a) namespace a {
+#define END_NAMESPACE }
+
+#define USING_NAMESPACE(a) using namespace a;
+#define FROM_NAMESPACE(a, s) a :: s
+
+#else
+
+#define BEGIN_NAMESPACE(a)
+#define END_NAMESPACE
+
+#define USING_NAMESPACE(a)
+#define FROM_NAMESPACE(a, s) s
+
+#endif
+
+
+#define SINGULARXXNAME Singular
+
+#define BEGIN_NAMESPACE_SINGULARXX BEGIN_NAMESPACE(SINGULARXXNAME)
+#define END_NAMESPACE_SINGULARXX END_NAMESPACE
+
+#define USING_NAMESPACE_SINGULARXX USING_NAMESPACE(SINGULARXXNAME)
+#define FROM_NAMESPACE_SINGULARXXNAME(s) FROM_NAMESPACE(SINGULARXXNAME, s)
+
+#define BEGIN_NAMESPACE_NONAME BEGIN_NAMESPACE()
+
+
+
+#ifndef HAVE_THROW
+#  define SINGULARXX_THROW(type) throw type();
+#else
+#  define SINGULARXX_THROW(type) Werror(type().what());
+#endif
+
+/// For optimizing if-branches
+#ifdef __GNUC__
+#define LIKELY(expression) (__builtin_expect(!!(expression), 1))
+#define UNLIKELY(expression) (__builtin_expect(!!(expression), 0))
+#else
+#define LIKELY(expression) (expression)
+#define UNLIKELY(expression) (expression)
+#endif
+
+// #include "CSingularTypes.h"
+
+#endif /* SINGULAR_singular_defs_h_ */
diff --git a/Singular/dyn_modules/syzextra/syzextra.cc b/Singular/dyn_modules/syzextra/syzextra.cc
new file mode 100644
index 0000000..a302b9c
--- /dev/null
+++ b/Singular/dyn_modules/syzextra/syzextra.cc
@@ -0,0 +1,3099 @@
+// -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+/*****************************************************************************\
+ * Computer Algebra System SINGULAR
+\*****************************************************************************/
+/** @file syzextra.cc
+ *
+ * New implementations for the computation of syzygies and resolutions
+ *
+ * ABSTRACT: Computation of Syzygies due to Schreyer
+ *
+ * @author Oleksandr Motsak
+ *
+ **/
+/*****************************************************************************/
+
+#include <string.h>
+
+// include header file
+#include <kernel/mod2.h>
+
+#include "syzextra.h"
+
+#include "DebugPrint.h"
+
+#include <omalloc/omalloc.h>
+
+#include <misc/intvec.h>
+#include <misc/options.h>
+
+#include <coeffs/coeffs.h>
+
+#include <polys/monomials/p_polys.h>
+#include <polys/monomials/ring.h>
+#include <polys/simpleideals.h>
+
+#include <polys/kbuckets.h> // for kBucket*
+#include <polys/sbuckets.h> // for sBucket*
+//#include <polys/nc/summator.h> // for CPolynomialSummator
+#include <polys/operations/p_Mult_q.h> // for MIN_LENGTH_BUCKET
+
+#include <kernel/GBEngine/kstd1.h>
+#include <kernel/polys.h>
+#include <kernel/GBEngine/syz.h>
+#include <kernel/ideals.h>
+
+#include <kernel/oswrapper/timer.h>
+
+
+#include <Singular/tok.h>
+#include <Singular/ipid.h>
+#include <Singular/lists.h>
+#include <Singular/attrib.h>
+
+#include <Singular/ipid.h>
+#include <Singular/ipshell.h> // For iiAddCproc
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifndef RTIMER_BENCHMARKING
+# define RTIMER_BENCHMARKING 0
+#endif
+
+// USING_NAMESPACE_SINGULARXX;
+USING_NAMESPACE( SINGULARXXNAME :: DEBUG )
+
+
+BEGIN_NAMESPACE_SINGULARXX     BEGIN_NAMESPACE(SYZEXTRA)
+
+
+BEGIN_NAMESPACE_NONAME
+
+#ifndef SING_NDEBUG
+ring SBucketFactory::_GetBucketRing(const SBucketFactory::Bucket& bt)
+{
+  assume( bt != NULL );
+  return sBucketGetRing(bt);
+}
+
+bool SBucketFactory::_IsBucketEmpty(const SBucketFactory::Bucket& bt)
+{
+  assume( bt != NULL );
+  return sIsEmpty(bt);
+}
+#endif
+
+SBucketFactory::Bucket SBucketFactory::_CreateBucket(const ring r)
+{
+  const Bucket bt = sBucketCreate(r);
+
+  assume( bt != NULL );
+  assume( _IsBucketEmpty(bt) );
+  assume( r == _GetBucketRing(bt) );
+
+  return bt;
+}
+
+void SBucketFactory::_DestroyBucket(SBucketFactory::Bucket & bt)
+{
+  if( bt != NULL )
+  {
+    assume( _IsBucketEmpty(bt) );
+    sBucketDestroy( &bt );
+    bt = NULL;
+  }
+}
+
+class SBucketWrapper
+{
+  typedef SBucketFactory::Bucket Bucket;
+
+  private:
+    Bucket m_bucket;
+
+    SBucketFactory& m_factory;
+  public:
+    SBucketWrapper(const ring r, SBucketFactory& factory):
+        m_bucket( factory.getBucket(r) ),
+        m_factory( factory )
+    {}
+
+    ~SBucketWrapper()
+    {
+      m_factory.putBucket( m_bucket );
+    }
+
+  public:
+
+    /// adds p to the internal bucket
+    /// destroys p, l == length(p)
+    inline void Add( poly p, const int l )
+    {
+      assume( pLength(p) == l );
+      sBucket_Add_p( m_bucket, p, l );
+    }
+
+    /// adds p to the internal bucket
+    /// destroys p
+    inline void Add( poly p ){ Add(p, pLength(p)); }
+
+    poly ClearAdd()
+    {
+      poly p; int l;
+      sBucketClearAdd(m_bucket, &p, &l);
+      assume( pLength(p) == l );
+      return p;
+    }
+};
+
+static FORCE_INLINE poly pp_Add_qq( const poly a, const poly b, const ring R)
+{
+  return p_Add_q( p_Copy(a, R), p_Copy(b, R), R );
+}
+
+static FORCE_INLINE poly p_VectorProductLT( poly s,  const ideal& L, const ideal& T, const ring& R)
+{
+  assume( IDELEMS(L) == IDELEMS(T) );
+  poly vp = NULL; // resulting vector product
+
+  while( s != NULL )
+  {
+    const poly nxt = pNext(s);
+    pNext(s) = NULL;
+
+    if( !n_IsZero( p_GetCoeff(s, R), R) )
+    {
+      const int i = p_GetComp(s, R) - 1;
+      assume( i >= 0 ); assume( i < IDELEMS(L) );
+      p_SetComp(s, 0, R); p_SetmComp(s, R);
+
+      vp = p_Add_q( vp, pp_Mult_qq( s, L->m[i], R ), R);
+      vp = p_Add_q( vp, pp_Mult_qq( s, T->m[i], R ), R);
+    }
+
+    p_Delete(&s, R);
+
+    s = nxt;
+  };
+
+  assume( s == NULL );
+
+  return vp;
+}
+
+static FORCE_INLINE int atGetInt(idhdl rootRingHdl, const char* attribute, long def)
+{
+  return ((int)(long)(atGet(rootRingHdl, attribute, INT_CMD, (void*)def)));
+}
+
+END_NAMESPACE
+
+BEGIN_NAMESPACE(SORT_c_ds)
+
+#if (defined(HAVE_QSORT_R) && (defined __APPLE__ || defined __MACH__ || defined __DARWIN__ || defined __FreeBSD__ || defined __BSD__ || defined OpenBSD3_1 || defined OpenBSD3_9))
+static int cmp_c_ds(void *R, const void *p1, const void *p2){
+#elif (defined(HAVE_QSORT_R) && (defined _GNU_SOURCE || defined __GNU__ || defined __linux__))
+static int cmp_c_ds(const void *p1, const void *p2, void *R){
+#else
+static int cmp_c_ds(const void *p1, const void *p2){ void *R = currRing;
+#endif
+  assume(R != NULL);
+  const int YES = 1;
+  const int NO = -1;
+
+  const ring r =  (const ring) R; // TODO/NOTE: the structure is known: C, lp!!!
+
+  assume( r == currRing ); // for now...
+
+  const poly a = *(const poly*)p1;
+  const poly b = *(const poly*)p2;
+
+  assume( a != NULL );
+  assume( b != NULL );
+
+  p_LmTest(a, r);
+  p_LmTest(b, r);
+
+
+  const signed long iCompDiff = p_GetComp(a, r) - p_GetComp(b, r);
+
+  // TODO: test this!!!!!!!!!!!!!!!!
+
+  //return -( compare (c, qsorts) )
+
+#ifndef SING_NDEBUG
+  const int OPT__DEBUG = 0;
+  if( OPT__DEBUG )
+  {
+    PrintS("cmp_c_ds: a, b: \np1: "); dPrint(a, r, r, 0);
+    PrintS("b: "); dPrint(b, r, r, 0);
+    PrintLn();
+  }
+#endif
+
+
+  if( iCompDiff > 0 )
+    return YES;
+
+  if( iCompDiff < 0 )
+    return  NO;
+
+  assume( iCompDiff == 0 );
+
+  const signed long iDegDiff = p_Totaldegree(a, r) - p_Totaldegree(b, r);
+
+  if( iDegDiff > 0 )
+    return YES;
+
+  if( iDegDiff < 0 )
+    return  NO;
+
+  assume( iDegDiff == 0 );
+
+#ifndef SING_NDEBUG
+  if( OPT__DEBUG )
+  {
+    PrintS("cmp_c_ds: a & b have the same comp & deg! "); PrintLn();
+  }
+#endif
+
+  for (int v = rVar(r); v > 0; v--)
+  {
+    assume( v > 0 );
+    assume( v <= rVar(r) );
+
+    const signed int d = p_GetExp(a, v, r) - p_GetExp(b, v, r);
+
+    if( d > 0 )
+      return YES;
+
+    if( d < 0 )
+      return NO;
+
+    assume( d == 0 );
+  }
+
+  return 0;
+}
+
+/*
+static int cmp_poly(const poly &a, const poly &b)
+{
+  const int YES = 1;
+  const int NO = -1;
+
+  const ring r =  (const ring) currRing; // TODO/NOTE: the structure is known: C, lp!!!
+
+  assume( r == currRing );
+
+  assume( a != NULL );
+  assume( b != NULL );
+
+  p_LmTest(a, r);
+  p_LmTest(b, r);
+  assume( p_GetComp(a, r) == 0 );
+  assume( p_GetComp(b, r) == 0 );
+
+#ifndef SING_NDEBUG
+  const int OPT__DEBUG = 0;
+  if( OPT__DEBUG )
+  {
+    PrintS("cmp_lex: a, b: \np1: "); dPrint(a, r, r, 0);
+    PrintS("b: "); dPrint(b, r, r, 0);
+    PrintLn();
+  }
+#endif
+
+  for (int v = rVar(r); v > 0; v--)
+  {
+    assume( v > 0 );
+    assume( v <= rVar(r) );
+
+    const signed int d = p_GetExp(a, v, r) - p_GetExp(b, v, r);
+
+    if( d > 0 )
+      return YES;
+
+    if( d < 0 )
+      return NO;
+
+    assume( d == 0 );
+  }
+
+  return 0;
+}
+*/
+
+END_NAMESPACE
+/* namespace SORT_c_ds */
+
+/// writes a monomial (p),
+/// uses form x*gen(.) if ko != coloumn number of p
+static void writeLatexTerm(const poly t, const ring r, const bool bCurrSyz = true, const bool bLTonly = true)
+{
+  if( t == NULL )
+  {
+    PrintS(" 0 ");
+    return;
+  }
+
+  assume( r != NULL );
+  const coeffs C = r->cf; assume(C != NULL);
+
+  poly p = t;
+  BOOLEAN writePlus = FALSE;
+
+  do {
+  assume( p != NULL );
+
+  // write coef...
+  number& n = p_GetCoeff(p, r);
+
+  n_Normalize(n, C);
+
+  BOOLEAN writeMult = FALSE; ///< needs * before pp or module generator
+
+  BOOLEAN writeOne = FALSE; ///< need to write something after '-'!
+
+  if( n_IsZero(n, C) )
+  {
+    PrintS( writePlus? " + 0" : " 0 " ); writePlus = TRUE; writeMult = TRUE;
+//    return; // yes?
+  }
+
+  if (n_IsMOne(n, C))
+  {
+    PrintS(" - "); writeOne = TRUE; writePlus = FALSE;
+  }
+  else if (!n_IsOne(n, C))
+  {
+    if( writePlus && n_GreaterZero(n, C) )
+      PrintS(" + ");
+
+    StringSetS(""); n_WriteLong(n, C);
+    if (true)
+    {
+      char *s = StringEndS(); PrintS(s); omFree(s);
+    }
+
+
+    writeMult = TRUE;
+    writePlus = TRUE;
+  } else
+     writeOne = TRUE;
+
+  // missing '1' if no PP and gen...!?
+  // write monom...
+  const short N = rVar(r);
+
+  BOOLEAN wrotePP = FALSE; ///< needs * before module generator?
+
+  for (short i = 0; i < N; i++)
+  {
+    const long ee = p_GetExp(p, i+1, r);
+
+    if (ee!=0L)
+    {
+      if (writeMult)
+      {
+        PrintS(" ");
+        writeMult = FALSE;
+      } else
+      if( writePlus )
+        PrintS(" + ");
+
+      writePlus = FALSE;
+
+      if (ee != 1L)
+        Print(" %s^{%ld} ", rRingVar(i, r), ee);
+      else
+        Print(" %s ", rRingVar(i, r));
+
+      writeOne = FALSE;
+      wrotePP = TRUE;
+    }
+  }
+
+  writePlus = writePlus || wrotePP;
+  writeMult = writeMult || wrotePP;
+
+  // write module gen...
+  const long comp = p_GetComp(p, r);
+
+  if (comp > 0 )
+  {
+    if (writeMult)
+      PrintS("  ");
+     else
+      if( writePlus )
+        PrintS(" + ");
+
+    if (bCurrSyz)
+      Print(" \\\\GEN{%ld} ", comp);
+    else
+      Print(" \\\\GENP{%ld} ", comp);
+
+      writeOne = FALSE;
+  }
+
+  if ( writeOne )
+    PrintS( writePlus? " + 1 " : " 1 " );
+
+
+  pIter(p);
+
+  writePlus = TRUE;
+  } while( (!bLTonly) && (p != NULL) );
+
+}
+
+
+
+static FORCE_INLINE poly myp_Head(const poly p, const bool bIgnoreCoeff, const ring r)
+{
+  assume( p != NULL ); p_LmCheckPolyRing1(p, r);
+
+  poly np; omTypeAllocBin(poly, np, r->PolyBin);
+  p_SetRingOfLm(np, r);
+  memcpy(np->exp, p->exp, r->ExpL_Size*sizeof(long));
+  pNext(np) = NULL;
+  pSetCoeff0(np, (bIgnoreCoeff)? NULL : n_Copy(pGetCoeff(p), r->cf));
+
+  p_LmCheckPolyRing1(np, r);
+  return np;
+}
+
+
+/// return a new term: leading coeff * leading monomial of p
+/// with 0 leading component!
+poly leadmonom(const poly p, const ring r, const bool bSetZeroComp)
+{
+  if( UNLIKELY(p == NULL ) )
+     return NULL;
+
+    assume( p != NULL );
+    p_LmTest(p, r);
+
+    poly m = p_LmInit(p, r);
+    p_SetCoeff0(m, n_Copy(p_GetCoeff(p, r), r), r);
+
+    if( bSetZeroComp )
+      p_SetComp(m, 0, r);
+
+    p_Setm(m, r);
+
+    assume( m != NULL );
+    assume( pNext(m) == NULL );
+    p_LmTest(m, r);
+
+    if( bSetZeroComp )
+      assume( p_GetComp(m, r) == 0 );
+
+  return m;
+}
+
+
+
+poly p_Tail(const poly p, const ring r)
+{
+  if( UNLIKELY(p == NULL) )
+    return NULL;
+  else
+    return p_Copy( pNext(p), r );
+}
+
+
+ideal id_Tail(const ideal id, const ring r)
+{
+  if( UNLIKELY(id == NULL) )
+    return NULL;
+
+  const ideal newid = idInit(IDELEMS(id),id->rank);
+
+  for (int i=IDELEMS(id) - 1; i >= 0; i--)
+    newid->m[i] = p_Tail( id->m[i], r );
+
+  newid->rank = id_RankFreeModule(newid, currRing);
+
+  return newid;
+}
+
+
+
+void Sort_c_ds(const ideal id, const ring r)
+{
+  const int sizeNew = IDELEMS(id);
+
+#if ( (defined(HAVE_QSORT_R)) && (defined __APPLE__ || defined __MACH__ || defined __DARWIN__ || defined __FreeBSD__ || defined __BSD__ || defined OpenBSD3_1 || defined OpenBSD3_9) )
+#define qsort_my(m, s, ss, r, cmp) qsort_r(m, s, ss, r, cmp)
+#elif ( (defined(HAVE_QSORT_R)) && (defined _GNU_SOURCE || defined __GNU__ || defined __linux__))
+#define qsort_my(m, s, ss, r, cmp) qsort_r(m, s, ss, cmp, r)
+#else
+#define qsort_my(m, s, ss, r, cmp) qsort(m, s, ss, cmp)
+#endif
+
+  if( sizeNew >= 2 )
+    qsort_my(id->m, sizeNew, sizeof(poly), r, FROM_NAMESPACE(SORT_c_ds, cmp_c_ds));
+
+#undef qsort_my
+
+  id->rank = id_RankFreeModule(id, r);
+}
+
+/// Clean up all the accumulated data
+void SchreyerSyzygyComputation::CleanUp()
+{
+  extern void id_Delete (ideal*, const ring);
+
+  id_Delete(const_cast<ideal*>(&m_idTails), m_rBaseRing); // TODO!!!
+
+/*if( m_sum_bucket != NULL )
+  {
+    assume ( sIsEmpty(m_sum_bucket) );
+    sBucketDestroy(&m_sum_bucket);
+    m_sum_bucket = NULL;
+  }*/
+
+  if( m_spoly_bucket != NULL )
+  {
+    kBucketDestroy(&m_spoly_bucket);
+    m_spoly_bucket = NULL;
+  }
+
+  for( TCache::iterator it = m_cache.begin(); it != m_cache.end(); it++ )
+  {
+    TP2PCache& T = it->second;
+
+    for(TP2PCache::iterator vit = T.begin(); vit != T.end(); vit++ )
+    {
+      p_Delete( (&(vit->second)), m_rBaseRing);
+      p_Delete( const_cast<poly*>(&(vit->first)), m_rBaseRing);
+    }
+  }
+}
+  /*
+  for( TTailTerms::const_iterator it = m_idTailTerms.begin(); it != m_idTailTerms.end(); it++ )
+  {
+    const TTail& v = *it;
+    for(TTail::const_iterator vit = v.begin(); vit != v.end(); vit++ )
+      delete const_cast<CTailTerm*>(*vit);
+  }
+  */
+
+
+
+int CReducerFinder::PreProcessTerm(const poly t, CReducerFinder& syzChecker) const
+{
+  assume( t != NULL );
+
+  if( UNLIKELY(OPT__DEBUG & OPT__TAILREDSYZ) )
+    assume( !IsDivisible(t) ); // each input term should NOT be in <L>
+
+  const ring r = m_rBaseRing;
+
+
+  if( LIKELY(OPT__TAILREDSYZ) )
+    if( p_LmIsConstant(t, r) ) // most basic case of baing coprime with L, whatever that is...
+      return 1; // TODO: prove this...?
+
+  //   return false; // appears to be fine
+
+  const long comp = p_GetComp(t, r);
+
+  CReducersHash::const_iterator itr = m_hash.find(comp);
+
+  if ( itr == m_hash.end() )
+    return 2; // no such leading component!!!
+
+  assume( itr->first == comp );
+
+  const bool bIdealCase = (comp == 0);
+  const bool bSyzCheck = syzChecker.IsNonempty(); // need to check even in ideal case????? proof?  "&& !bIdealCase"
+
+  if( LIKELY(OPT__TAILREDSYZ && (bIdealCase || bSyzCheck)) )
+  {
+    const TReducers& v = itr->second;
+    const int N = rVar(r);
+    // TODO: extract exps of t beforehand?!
+    bool coprime = true;
+    for(TReducers::const_iterator vit = v.begin(); (vit != v.end()) && coprime; ++vit )
+    {
+      assume( (*vit)->CheckLT( m_L ) );
+
+      const poly p = (*vit)->lt();
+
+      assume( p_GetComp(p, r) == comp );
+
+      // TODO: check if coprime with Leads... if OPT__TAILREDSYZ !
+      for( int var = N; var > 0; --var )
+        if( (p_GetExp(p, var, r) != 0) && (p_GetExp(t, var, r) != 0) )
+        {
+#ifndef SING_NDEBUG
+          if( OPT__DEBUG | 0)
+          {
+            PrintS("CReducerFinder::PreProcessTerm, 't' is NOT co-prime with the following leading term: \n");
+            dPrint(p, r, r, 0);
+          }
+#endif
+          coprime = false; // t not coprime with p!
+          break;
+        }
+
+      if( bSyzCheck && coprime )
+      {
+        poly ss = p_LmInit(t, r);
+        p_SetCoeff0(ss, n_Init(1, r), r); // for delete & printout only!...
+        p_SetComp(ss, (*vit)->label() + 1, r); // coeff?
+        p_Setm(ss, r);
+
+        coprime = ( syzChecker.IsDivisible(ss) );
+
+#ifndef SING_NDEBUG
+        if( OPT__DEBUG && !coprime)
+        {
+          PrintS("CReducerFinder::PreProcessTerm, 't' is co-prime with p but may lead to NOT divisible syz.term: \n");
+          dPrint(ss, r, r, 0);
+        }
+#endif
+
+        p_LmDelete(&ss, r); // deletes coeff as well???
+      }
+
+      assume( p == (*vit)->lt() );
+      assume( (*vit)->CheckLT( m_L ) );
+    }
+
+#ifndef SING_NDEBUG
+    if( OPT__DEBUG && coprime )
+      PrintS("CReducerFinder::PreProcessTerm, the following 't' is 'co-prime' with all of leading terms! \n");
+#endif
+
+    return coprime? 3: 0; // t was coprime with all of leading terms!!!
+
+  }
+  //   return true; // delete the term
+
+  return 0;
+}
+
+
+void SchreyerSyzygyComputation::SetUpTailTerms()
+{
+  const ideal idTails = m_idTails;
+  assume( idTails != NULL );
+  assume( idTails->m != NULL );
+  const ring r = m_rBaseRing;
+
+  unsigned long pp[4] = {0,0,0,0}; // count preprocessed terms...
+
+#ifndef SING_NDEBUG
+  if( OPT__DEBUG | 0)
+  {
+    PrintS("SchreyerSyzygyComputation::SetUpTailTerms(): Tails: \n");
+    dPrint(idTails, r, r, 0);
+  }
+#endif
+
+  for( int p = IDELEMS(idTails) - 1; p >= 0; --p )
+    for( poly* tt = &(idTails->m[p]); (*tt) != NULL;  )
+    {
+      const poly t = *tt;
+      const int k = m_div.PreProcessTerm(t, m_checker); // 0..3
+      assume( 0 <= k && k <= 3 );
+
+      pp[k]++; // collect stats
+
+      if( k )
+      {
+#ifndef SING_NDEBUG
+        if( OPT__DEBUG)
+        {
+          Print("SchreyerSyzygyComputation::SetUpTailTerms(): PP (%d) the following TT: \n", k);
+          dPrint(t, r, r, 0);
+        }
+#endif
+
+        (*tt) = p_LmDeleteAndNext(t, r); // delete the lead and next...
+      }
+      else
+        tt = &pNext(t); // go next?
+
+    }
+
+#ifndef SING_NDEBUG
+  if( OPT__DEBUG | 0)
+  {
+    PrintS("SchreyerSyzygyComputation::SetUpTailTerms(): Preprocessed Tails: \n");
+    dPrint(idTails, r, r, 0);
+  }
+#endif
+
+  if( UNLIKELY(OPT__PROT) )
+  {
+    Print("(PP/ST: {c: %lu, C: %lu, P: %lu} + %lu)", pp[1], pp[2], pp[3], pp[0]);
+    m_stat[0] += pp [0]; m_stat[1] += pp [1]; m_stat[2] += pp [2]; m_stat[3] += pp [3];
+  }
+}
+
+/*
+  m_idTailTerms.resize( IDELEMS(idTails) );
+
+  for( unsigned int p = IDELEMS(idTails) - 1; p >= 0; p -- )
+  {
+    TTail& v = m_idTailTerms[p];
+    poly t = idTails->m[p];
+    v.resize( pLength(t) );
+
+    unsigned int pp = 0;
+
+    while( t != NULL )
+    {
+      assume( t != NULL );
+      // TODO: compute L:t!
+//      ideal reducers;
+//      CReducerFinder m_reducers
+
+      CTailTerm* d = v[pp] = new CTailTerm();
+
+      ++pp; pIter(t);
+    }
+  }
+*/
+
+void SchreyerSyzygyComputation::PrintStats() const
+{
+  Print("SchreyerSyzygyComputation Stats: (PP/ST: {c: %lu, C: %lu, P: %lu} + %lu, LOT: %lu, LCM: %lu, ST:%lu, LK: %lu {*: %lu})\n",
+        m_stat[1], m_stat[2], m_stat[3], m_stat[0],
+        m_stat[4], m_stat[5],
+        m_stat[8],
+        m_stat[6] + m_stat[7], m_stat[7]
+       );
+}
+
+
+ideal SchreyerSyzygyComputation::Compute1LeadingSyzygyTerms()
+{
+  const ideal& id = m_idLeads;
+  const ring& r = m_rBaseRing;
+//  const SchreyerSyzygyComputationFlags& attributes = m_atttributes;
+
+  assume(!OPT__LEAD2SYZ);
+
+  // 1. set of components S?
+  // 2. for each component c from S: set of indices of leading terms
+  // with this component?
+  // 3. short exp. vectors for each leading term?
+
+  const int size = IDELEMS(id);
+
+  if( size < 2 )
+  {
+    const ideal newid = idInit(1, 0); newid->m[0] = NULL; // zero ideal...
+    return newid;
+  }
+
+  // TODO/NOTE: input is supposed to be (reverse-) sorted wrt "(c,ds)"!??
+
+  // components should come in groups: count elements in each group
+  // && estimate the real size!!!
+
+
+  // use just a vector instead???
+  const ideal newid = idInit( (size * (size-1))/2, size); // maximal size: ideal case!
+
+  int k = 0;
+
+  for (int j = 0; j < size; j++)
+  {
+    const poly p = id->m[j];
+    assume( p != NULL );
+    const int  c = p_GetComp(p, r);
+
+    for (int i = j - 1; i >= 0; i--)
+    {
+      const poly pp = id->m[i];
+      assume( pp != NULL );
+      const int  cc = p_GetComp(pp, r);
+
+      if( c != cc )
+        continue;
+
+      const poly m = p_Init(r); // p_New???
+
+      // m = LCM(p, pp) / p! // TODO: optimize: knowing the ring structure: (C/lp)!
+      for (int v = rVar(r); v > 0; v--)
+      {
+        assume( v > 0 );
+        assume( v <= rVar(r) );
+
+        const short e1 = p_GetExp(p , v, r);
+        const short e2 = p_GetExp(pp, v, r);
+
+        if( e1 >= e2 )
+          p_SetExp(m, v, 0, r);
+        else
+          p_SetExp(m, v, e2 - e1, r);
+
+      }
+
+      assume( (j > i) && (i >= 0) );
+
+      p_SetComp(m, j + 1, r);
+      pNext(m) = NULL;
+      p_SetCoeff0(m, n_Init(1, r->cf), r); // for later...
+
+      p_Setm(m, r); // should not do anything!!!
+
+      newid->m[k++] = m;
+    }
+  }
+
+//   if( OPT__DEBUG & FALSE )
+//   {
+//     PrintS("ComputeLeadingSyzygyTerms::Temp0: \n");
+//     dPrint(newid, r, r, 0);
+//   }
+
+  // the rest of newid is assumed to be zeroes...
+
+  // simplify(newid, 2 + 32)??
+  // sort(newid, "C,ds")[1]???
+  id_DelDiv(newid, r); // #define SIMPL_LMDIV 32
+
+//   if( OPT__DEBUG & FALSE )
+//   {
+//     PrintS("ComputeLeadingSyzygyTerms::Temp1: \n");
+//     dPrint(newid, r, r, 0);
+//   }
+
+  idSkipZeroes(newid); // #define SIMPL_NULL 2
+
+//   if( OPT__DEBUG )
+//   {
+//     PrintS("ComputeLeadingSyzygyTerms::Output: \n");
+//     dPrint(newid, r, r, 0);
+//   }
+
+  Sort_c_ds(newid, r);
+
+  return newid;
+}
+
+ideal SchreyerSyzygyComputation::Compute2LeadingSyzygyTerms()
+{
+  const ideal& id = m_idLeads;
+  const ring& r = m_rBaseRing;
+//  const SchreyerSyzygyComputationFlags& attributes = m_atttributes;
+
+  // 1. set of components S?
+  // 2. for each component c from S: set of indices of leading terms
+  // with this component?
+  // 3. short exp. vectors for each leading term?
+
+  const int size = IDELEMS(id);
+
+  if( size < 2 )
+  {
+    const ideal newid = idInit(1, 1); newid->m[0] = NULL; // zero module...
+    return newid;
+  }
+
+
+  // TODO/NOTE: input is supposed to be sorted wrt "C,ds"!??
+
+  // components should come in groups: count elements in each group
+  // && estimate the real size!!!
+
+
+  // use just a vector instead???
+  ideal newid = idInit( (size * (size-1))/2, size); // maximal size: ideal case!
+
+  int k = 0;
+
+  for (int j = 0; j < size; j++)
+  {
+    const poly p = id->m[j];
+    assume( p != NULL );
+    const int  c = p_GetComp(p, r);
+
+    for (int i = j - 1; i >= 0; i--)
+    {
+      const poly pp = id->m[i];
+      assume( pp != NULL );
+      const int  cc = p_GetComp(pp, r);
+
+      if( c != cc )
+        continue;
+
+        // allocate memory & zero it out!
+      const poly m = p_Init(r); const poly mm = p_Init(r);
+
+
+        // m = LCM(p, pp) / p! mm = LCM(p, pp) / pp!
+        // TODO: optimize: knowing the ring structure: (C/lp)!
+
+      for (int v = rVar(r); v > 0; v--)
+      {
+        assume( v > 0 );
+        assume( v <= rVar(r) );
+
+        const short e1 = p_GetExp(p , v, r);
+        const short e2 = p_GetExp(pp, v, r);
+
+        if( e1 >= e2 )
+          p_SetExp(mm, v, e1 - e2, r); //            p_SetExp(m, v, 0, r);
+        else
+          p_SetExp(m, v, e2 - e1, r); //            p_SetExp(mm, v, 0, r);
+
+      }
+
+      assume( (j > i) && (i >= 0) );
+
+      p_SetComp(m, j + 1, r);
+      p_SetComp(mm, i + 1, r);
+
+      const number& lc1 = p_GetCoeff(p , r);
+      const number& lc2 = p_GetCoeff(pp, r);
+
+#if NODIVISION
+      assume( n_IsOne(lc1, r->cf) );
+      assume( n_IsOne(lc2, r->cf) );
+
+      p_SetCoeff0( m, n_Init( 1, r->cf), r );
+      p_SetCoeff0(mm, n_Init(-1, r->cf), r );
+#else
+      number g = n_Lcm( lc1, lc2, r->cf );
+      p_SetCoeff0(m ,       n_Div(g, lc1, r), r);
+      p_SetCoeff0(mm, n_InpNeg(n_Div(g, lc2, r), r), r);
+      n_Delete(&g, r);
+#endif
+
+      p_Setm(m, r); // should not do anything!!!
+      p_Setm(mm, r); // should not do anything!!!
+
+      pNext(m) = mm; //        pNext(mm) = NULL;
+
+      newid->m[k++] = m;
+    }
+  }
+
+//   if( OPT__DEBUG & FALSE )
+//   {
+//     PrintS("Compute2LeadingSyzygyTerms::Temp0: \n");
+//     dPrint(newid, r, r, 0);
+//   }
+
+  if( UNLIKELY(!OPT__TAILREDSYZ) )
+  {
+      // simplify(newid, 2 + 32)??
+      // sort(newid, "C,ds")[1]???
+    id_DelDiv(newid, r); // #define SIMPL_LMDIV 32
+
+//     if( OPT__DEBUG & FALSE )
+//     {
+//       PrintS("Compute2LeadingSyzygyTerms::Temp1 (deldiv): \n");
+//       dPrint(newid, r, r, 0);
+//     }
+  }
+  else
+  {
+      //      option(redSB); option(redTail);
+      //      TEST_OPT_REDSB
+      //      TEST_OPT_REDTAIL
+    assume( r == currRing );
+
+    BITSET _save_test; SI_SAVE_OPT1(_save_test);
+    SI_RESTORE_OPT1(Sy_bit(OPT_REDTAIL) | Sy_bit(OPT_REDSB) | _save_test);
+
+    intvec* w=new intvec(IDELEMS(newid));
+    ideal tmp = kStd(newid, currRing->qideal, isHomog, &w);
+    delete w;
+
+    SI_RESTORE_OPT1(_save_test)
+
+    id_Delete(&newid, r);
+    newid = tmp;
+
+//     if( OPT__DEBUG & FALSE )
+//     {
+//       PrintS("Compute2LeadingSyzygyTerms::Temp1 (std): \n");
+//       dPrint(newid, r, r, 0);
+//     }
+
+  }
+
+  idSkipZeroes(newid);
+
+  Sort_c_ds(newid, r);
+
+  return newid;
+}
+
+poly SchreyerSyzygyComputation::TraverseNF(const poly a, const poly a2) const
+{
+#ifndef SING_NDEBUG
+  if( OPT__DEBUG )  {    m_div.Verify();    m_checker.Verify();  }
+#endif
+
+  const ideal& L = m_idLeads;
+  const ideal& T = m_idTails;
+
+  const ring& R = m_rBaseRing;
+
+  const int r = p_GetComp(a, R) - 1;
+
+  assume( r >= 0 && r < IDELEMS(T) );
+  assume( r >= 0 && r < IDELEMS(L) );
+
+  assume( a != NULL );
+
+#ifndef SING_NDEBUG
+  if( OPT__DEBUG )
+  {
+    PrintS("SchreyerSyzygyComputation::TraverseNF(syz_lead, poly syz_2), \n");
+    PrintS("syz_lead: \n");
+    dPrint(a, R, R, 0);
+    PrintS("syz_2: \n");
+    dPrint(a2, R, R, 0);
+    PrintLn();
+  }
+#endif
+
+  if( UNLIKELY(OPT__TREEOUTPUT) )
+  {
+     PrintS("{ \"proc\": \"TraverseNF\", \"nodelabel\": \"");
+     writeLatexTerm(a, R);
+     PrintS("\", \"children\": [");
+  }
+
+  poly aa = leadmonom(a, R); assume( aa != NULL); // :(
+
+#ifndef SING_NDEBUG
+  if( OPT__DEBUG )  {    m_div.Verify();    m_checker.Verify();  }
+#endif
+
+  poly t = TraverseTail(aa, r);
+
+  if( a2 != NULL )
+  {
+    assume( OPT__LEAD2SYZ );
+
+    if( UNLIKELY(OPT__TREEOUTPUT) )
+    {
+
+       PrintS("{ \"proc\": \"TraverseNF2\", \"nodelabel\": \"");
+       writeLatexTerm(a2, R);
+       PrintS("\", \"children\": [");
+    }
+
+    // replace the following... ?
+    const int r2 = p_GetComp(a2, R) - 1; poly aa2 = leadmonom(a2, R); // :(
+
+    assume( r2 >= 0 && r2 < IDELEMS(T) );
+
+    poly s =  TraverseTail(aa2, r2);
+
+    p_Delete(&aa2, R);
+
+
+    if( UNLIKELY(OPT__TREEOUTPUT) )
+    {
+      PrintS("], \"noderesult\": \"");
+      writeLatexTerm(s, R, true, false);
+      PrintS("\" },");
+    }
+
+    t = p_Add_q(a2, p_Add_q(t, s, R), R);
+
+#ifndef SING_NDEBUG
+    if( OPT__DEBUG )    {      m_div.Verify();      m_checker.Verify();    }
+#endif
+
+  } else
+    t = p_Add_q(t, ReduceTerm(aa, L->m[r], a), R); // should be identical to bove with a2
+
+  p_Delete(&aa, R);
+
+  if( UNLIKELY(OPT__TREEOUTPUT) )
+  {
+//     poly tt = pp_Add_qq( a, t, R);
+     PrintS("], \"noderesult\": \"");
+     writeLatexTerm(t, R, true, false);
+     PrintS("\" },");
+//     p_Delete(&tt, R);
+  }
+#ifndef SING_NDEBUG
+  if( OPT__DEBUG )
+  {
+    PrintS("SchreyerSyzygyComputation::TraverseNF(syz_lead, poly syz_2), ==>>> \n");
+    dPrint(t, R, R, 0);
+    PrintLn();
+  }
+#endif
+
+#ifndef SING_NDEBUG
+  if( OPT__DEBUG )  {    m_div.Verify();    m_checker.Verify();  }
+#endif
+
+  return t;
+}
+
+void SchreyerSyzygyComputation::ComputeSyzygy()
+{
+#ifndef SING_NDEBUG
+  if( OPT__DEBUG )  {    m_div.Verify();    m_checker.Verify();  }
+#endif
+
+  assume( m_idLeads != NULL );
+  assume( m_idTails != NULL );
+
+  const ideal& L = m_idLeads;
+  const ideal& T = m_idTails;
+
+  ideal& TT = m_syzTails;
+  const ring& R = m_rBaseRing;
+
+//  if( m_sum_bucket == NULL )
+//    m_sum_bucket = sBucketCreate(R);
+//  assume ( sIsEmpty(m_sum_bucket) );
+
+  if( m_spoly_bucket == NULL )
+    m_spoly_bucket = kBucketCreate(R);
+
+
+  assume( IDELEMS(L) == IDELEMS(T) );
+
+#ifdef SING_NDEBUG
+  int t, r; // for rtimer benchmarking in prot realease mode
+#endif
+
+  if( UNLIKELY(OPT__TREEOUTPUT) )
+    Print("\n{ \"syzygylayer\": \"%d\", \"hybridnf\": \"%d\", \"diagrams\": \n[", OPT__SYZNUMBER, OPT__HYBRIDNF );
+
+  if( UNLIKELY(OPT__PROT) ) Print("\n[%d]", OPT__SYZNUMBER );
+
+  if( m_syzLeads == NULL )
+  {
+#ifdef SING_NDEBUG
+    if( UNLIKELY(OPT__PROT & RTIMER_BENCHMARKING) )
+    {
+      t = getTimer(); r = getRTimer();
+      Print("\n%% %5d **!TIME4!** SchreyerSyzygyComputation::ComputeSyzygy::ComputeLeadingSyzygyTerms: t: %d, r: %d\n", r, t, r);
+    }
+#endif
+
+    ComputeLeadingSyzygyTerms( OPT__LEAD2SYZ && !OPT__IGNORETAILS ); // 2 terms OR 1 term!
+
+#ifdef SING_NDEBUG
+    if( UNLIKELY(OPT__PROT & RTIMER_BENCHMARKING) )
+    {
+      t = getTimer() - t; r = getRTimer() - r;
+      Print("\n%% %5d **!TIME4!** SchreyerSyzygyComputation::ComputeSyzygy::ComputeLeadingSyzygyTerms: dt: %d, dr: %d\n", getRTimer(), t, r);
+    }
+#endif
+
+  }
+
+  assume( m_syzLeads != NULL );
+  ideal& LL = m_syzLeads;
+  const int size = IDELEMS(LL);
+
+  TT = idInit(size, 0);
+
+  if( size == 1 && LL->m[0] == NULL )
+  {
+     if( UNLIKELY(OPT__TREEOUTPUT) )
+       PrintS("]},");
+     return;
+  }
+
+
+  // use hybrid (Schreyer NF) method?
+  const bool method = (OPT__HYBRIDNF  == 1); //  || (OPT__HYBRIDNF == 2 && OPT__SYZNUMBER < 3);
+
+  if( UNLIKELY(OPT__PROT) ) Print("[%s NF|%s]",(method) ? "PR" : "TT", (NOPRODUCT == 1)? "_,_": "^*^" );
+
+
+  if(  LIKELY(!OPT__IGNORETAILS) )
+  {
+    if( T != NULL )
+    {
+#ifdef SING_NDEBUG
+      if( UNLIKELY(OPT__PROT & RTIMER_BENCHMARKING) )
+      {
+        t = getTimer(); r = getRTimer();
+        Print("\n%% %5d **!TIME4!** SchreyerSyzygyComputation::ComputeSyzygy::SetUpTailTerms(): t: %d, r: %d\n", r, t, r);
+      }
+#endif
+
+      SetUpTailTerms();
+
+#ifdef SING_NDEBUG
+      if( UNLIKELY(OPT__PROT & RTIMER_BENCHMARKING) )
+      {
+        t = getTimer() - t; r = getRTimer() - r;
+        Print("\n%% %5d **!TIME4!** SchreyerSyzygyComputation::ComputeSyzygy::SetUpTailTerms(): dt: %d, dr: %d\n", getRTimer(), t, r);
+      }
+#endif
+    }
+  }
+
+#ifdef SING_NDEBUG
+  if( UNLIKELY(OPT__PROT & RTIMER_BENCHMARKING) )
+  {
+    t = getTimer(); r = getRTimer();
+    Print("\n%% %5d **!TIME4!** SchreyerSyzygyComputation::ComputeSyzygy::SyzygyLift: t: %d, r: %d\n", r, t, r);
+  }
+#endif
+
+#ifndef SING_NDEBUG
+  if( OPT__DEBUG )  {    m_div.Verify();    m_checker.Verify();  }
+#endif
+
+//  for( int k = 0; k < size; ++k ) // TODO: should be fine now!
+  for( int k = size - 1; k >= 0; --k )
+  {
+    const poly a = LL->m[k]; assume( a != NULL );
+
+    poly a2 = pNext(a);
+
+    // Splitting 2-terms Leading syzygy module
+    if( a2 != NULL )
+      pNext(a) = NULL;
+
+    if( UNLIKELY(OPT__IGNORETAILS) )
+    {
+      TT->m[k] = NULL;
+
+      assume( a2 != NULL );
+
+      if( a2 != NULL )
+        p_Delete(&a2, R);
+
+      continue;
+    }
+
+    //    TT->m[k] = a2;
+
+#ifndef SING_NDEBUG
+    if( OPT__DEBUG )    {      m_div.Verify();      m_checker.Verify();    }
+#endif
+
+    poly nf;
+
+    if( method )
+      nf = SchreyerSyzygyNF(a, a2);
+    else
+      nf = TraverseNF(a, a2);
+
+#ifndef SING_NDEBUG
+    if( OPT__DEBUG )    {      m_div.Verify();      m_checker.Verify();    }
+#endif
+
+    TT->m[k] = nf;
+
+    if( UNLIKELY(OPT__SYZCHECK) )
+    {
+      // TODO: check the correctness (syzygy property): a + TT->m[k] should be a syzygy!!!
+
+      poly s = pp_Add_qq( a, TT->m[k], R); // current syzygy
+
+      poly vp = p_VectorProductLT(s, L, T, R);
+
+      if( UNLIKELY( OPT__DEBUG && (vp != NULL) && ! OPT__TREEOUTPUT ) )
+      {
+        Warn("SchreyerSyzygyComputation::ComputeSyzygy: failed syzygy property for syzygy [%d], non-zero image is as follows: ", k);
+        dPrint(vp, R, R, 0);       p_Delete(&vp, R);
+
+        PrintS("SchreyerSyzygyComputation::ComputeSyzygy: Wrong syzygy is as follows: ");
+        s = pp_Add_qq( a, TT->m[k], R);
+        dPrint(s, R, R, 0); p_Delete(&s, R);
+
+        PrintS("SchreyerSyzygyComputation::ComputeSyzygy: Testing with the other method");
+
+        if( !method )
+          s = SchreyerSyzygyNF(a, a2);
+        else
+          s = TraverseNF(a, a2);
+
+        s = p_Add_q( p_Copy(a, R), s, R); // another syzygy // :((((
+        PrintS("SchreyerSyzygyComputation::ComputeSyzygy: The other method gives the following  syzygy: ");
+        dPrint(s, R, R, 0);
+
+        vp = p_VectorProductLT(s, L, T, R);
+
+        if( vp == NULL )
+        {
+          PrintS("SchreyerSyzygyComputation::ComputeSyzygy: .... which is correct!!! ");
+        } else
+        {
+          Warn("SchreyerSyzygyComputation::ComputeSyzygy: failed to compute syzygy tail[%d] with both methods!!! Non-zero image (2nd) is as follows: ", k);
+          dPrint(vp, R, R, 0);
+        }
+
+#ifndef SING_NDEBUG
+        if( OPT__DEBUG )        {          m_div.Verify();          m_checker.Verify();         }
+#endif
+
+      } else
+        assume( vp == NULL );
+
+      if( UNLIKELY( OPT__PROT && (vp != NULL) ) ) Warn("ERROR: SyzCheck failed, wrong tail: [%d]\n\n", k); // check k'th syzygy failed
+
+      p_Delete(&vp, R);
+    }
+
+#ifndef SING_NDEBUG
+    if( OPT__DEBUG )    {      m_div.Verify();      m_checker.Verify();    }
+#endif
+  }
+
+#ifdef SING_NDEBUG
+  if( UNLIKELY( OPT__PROT & RTIMER_BENCHMARKING ) )
+  {
+    t = getTimer() - t; r = getRTimer() - r;
+    Print("\n%% %5d **!TIME4!** SchreyerSyzygyComputation::ComputeSyzygy::SyzygyLift: dt: %d, dr: %d\n", getRTimer(), t, r);
+  }
+#endif
+
+  TT->rank = id_RankFreeModule(TT, R);
+
+  if( UNLIKELY(OPT__TREEOUTPUT) )
+    PrintS("\n]},");
+
+  if( UNLIKELY(OPT__PROT) ) PrintLn();
+}
+
+void SchreyerSyzygyComputation::ComputeLeadingSyzygyTerms(bool bComputeSecondTerms)
+{
+//  const SchreyerSyzygyComputationFlags& attributes = m_atttributes;
+
+//  const BOOLEAN OPT__LEAD2SYZ   = attributes.OPT__LEAD2SYZ;
+//  const BOOLEAN OPT__TAILREDSYZ = attributes.OPT__TAILREDSYZ;
+
+  assume( m_syzLeads == NULL );
+
+  if( UNLIKELY(bComputeSecondTerms) )
+  {
+    assume( OPT__LEAD2SYZ );
+//    m_syzLeads = FROM_NAMESPACE(INTERNAL, _Compute2LeadingSyzygyTerms(m_idLeads, m_rBaseRing, m_atttributes));
+    m_syzLeads = Compute2LeadingSyzygyTerms();
+  }
+  else
+  {
+    assume( !OPT__LEAD2SYZ );
+
+    m_syzLeads = Compute1LeadingSyzygyTerms();
+  }
+//    m_syzLeads = FROM_NAMESPACE(INTERNAL, _ComputeLeadingSyzygyTerms(m_idLeads, m_rBaseRing, m_atttributes));
+
+  // NOTE: set m_LS if tails are to be reduced!
+  assume( m_syzLeads!= NULL );
+
+  if ( LIKELY( OPT__TAILREDSYZ && !OPT__IGNORETAILS && (IDELEMS(m_syzLeads) > 0) && !((IDELEMS(m_syzLeads) == 1) && (m_syzLeads->m[0] == NULL)) ) )
+  {
+    m_LS = m_syzLeads;
+    m_checker.Initialize(m_syzLeads);
+#ifndef SING_NDEBUG
+    if( OPT__DEBUG )
+    {
+      const ring& r = m_rBaseRing;
+      PrintS("SchreyerSyzygyComputation::ComputeLeadingSyzygyTerms: \n");
+      PrintS("m_syzLeads: \n");
+      dPrint(m_syzLeads, r, r, 0);
+      PrintS("m_checker.Initialize(m_syzLeads) => \n");
+      m_checker.DebugPrint();
+    }
+#endif
+    assume( m_checker.IsNonempty() ); // TODO: this always fails... BUG????
+  }
+
+  if( UNLIKELY( OPT__PROT ) ) Print("(L%dS:%d)", bComputeSecondTerms ? 2 : 1, IDELEMS(m_syzLeads));
+
+}
+
+poly SchreyerSyzygyComputation::SchreyerSyzygyNF(const poly syz_lead, poly syz_2) const
+{
+  assume( !OPT__IGNORETAILS );
+
+  const ideal& L = m_idLeads;
+  const ideal& T = m_idTails;
+  const ring& r = m_rBaseRing;
+
+  assume( syz_lead != NULL );
+
+
+#ifndef SING_NDEBUG
+  if( OPT__DEBUG )
+  {
+    PrintS("SchreyerSyzygyComputation::SchreyerSyzygyNF(syz_lead, poly syz_2), \n");
+    PrintS("syz_lead: \n");
+    dPrint(syz_lead, r, r, 0);
+    PrintS("syz_2: \n");
+    dPrint(syz_2, r, r, 0);
+    PrintLn();
+  }
+#endif
+
+  if( UNLIKELY( OPT__TREEOUTPUT ) )
+  {
+    PrintS("{   \"nodelabel\": \""); writeLatexTerm(syz_lead, r);
+    PrintS("\", \"children\": [");
+  }
+
+  if( syz_2 == NULL )
+  {
+    const int rr = p_GetComp(syz_lead, r) - 1;
+
+    assume( rr >= 0 && rr < IDELEMS(T) );
+    assume( rr >= 0 && rr < IDELEMS(L) );
+
+#if NOPRODUCT
+    syz_2 = m_div.FindReducer(syz_lead, L->m[rr], syz_lead, m_checker);
+    p_Test(syz_2, r);
+
+    if( UNLIKELY( OPT__TREEOUTPUT ) )
+    {
+      PrintS("{ \"nodelabel\": \""); writeLatexTerm(syz_2, r); PrintS("\" },");
+    }
+#else
+    poly aa = leadmonom(syz_lead, r); assume( aa != NULL); // :(
+    aa = p_Mult_mm(aa, L->m[rr], r);
+
+    if( UNLIKELY( OPT__TREEOUTPUT ) )
+    {
+      PrintS("{ \"nodelabel\": \""); writeLatexTerm(syz_2, r); PrintS("\", \"edgelabel\": \""); writeLatexTerm(aa, r, false); PrintS("\" },");
+    }
+
+    syz_2 = m_div.FindReducer(aa, syz_lead, m_checker);
+    p_Test(syz_2, r);
+
+    p_Delete(&aa, r);
+#endif
+
+  }
+
+  assume( syz_2 != NULL ); // by construction of S-Polynomial
+
+  assume( L != NULL );
+  assume( T != NULL );
+
+  assume( IDELEMS(L) == IDELEMS(T) );
+
+  int  c = p_GetComp(syz_lead, r) - 1;
+
+  assume( c >= 0 && c < IDELEMS(T) );
+
+  if( m_spoly_bucket == NULL )
+    m_spoly_bucket = kBucketCreate(r);
+
+  SBucketWrapper tail(r, m_sum_bucket_factory);
+
+
+  kBucket_pt bucket = m_spoly_bucket; assume( bucket != NULL ); kbTest(bucket); m_spoly_bucket = NULL;
+
+//  kBucketInit(bucket, NULL, 0); // not needed!?
+
+  poly p = leadmonom(syz_lead, r); // :(
+//  poly spoly = pp_Mult_qq(p, T->m[c], r);
+  kBucket_Plus_mm_Mult_pp(bucket, p, T->m[c], 0); // TODO: store pLength(T->m[c]) separately!?
+  p_Delete(&p, r);
+
+  kbTest(bucket);
+
+  c = p_GetComp(syz_2, r) - 1;
+  assume( c >= 0 && c < IDELEMS(T) );
+
+  p = leadmonom(syz_2, r); // :(
+//  spoly = p_Add_q(spoly, pp_Mult_qq(p, T->m[c], r), r);
+  kBucket_Plus_mm_Mult_pp(bucket, p, T->m[c], 0); // pLength(T->m[c])?!
+  kbTest(bucket);
+  p_Delete(&p, r);
+
+//  const bool bUsePolynomial = TEST_OPT_NOT_BUCKETS; //  || (pLength(spoly) < MIN_LENGTH_BUCKET);
+//  CPolynomialSummator tail(r, bUsePolynomial);
+  tail.Add(syz_2, 1);
+
+  kbTest(bucket);
+  for( poly spoly = kBucketExtractLm(bucket); spoly != NULL; p_LmDelete(&spoly, r), spoly = kBucketExtractLm(bucket))
+  {
+    kbTest(bucket);
+    poly t = m_div.FindReducer(spoly, NULL, m_checker);
+    p_Test(t, r);
+
+    if( t != NULL )
+    {
+      p = leadmonom(t, r); // :(
+      c = p_GetComp(t, r) - 1;
+
+      assume( c >= 0 && c < IDELEMS(T) );
+
+      if(UNLIKELY( OPT__TREEOUTPUT ))
+      {
+        PrintS("{ \"nodelabel\": \""); writeLatexTerm(t, r); PrintS("\", \"edgelabel\": \""); writeLatexTerm(spoly, r, false); PrintS("\" },");
+      }
+
+      kBucket_Plus_mm_Mult_pp(bucket, p, T->m[c], 0); // pLength(T->m[c])?
+//      spoly = p_Add_q(spoly, pp_Mult_qq(p, T->m[c], r), r);
+
+      p_Delete(&p, r);
+
+      tail.Add(t, 1);
+    } // otherwise discard that leading term altogether!
+    else
+      if( UNLIKELY(OPT__PROT) ) ++ m_stat[4]; // PrintS("$"); // LOT
+
+    kbTest(bucket);
+  }
+
+  kbTest(bucket);
+
+  // now bucket must be empty!
+  assume( kBucketClear(bucket) == NULL );
+
+  const poly result = tail.ClearAdd(); // TODO: use Merge with sBucket???
+
+
+  if( m_spoly_bucket == NULL )
+    m_spoly_bucket = bucket;
+  else
+    kBucketDestroy(&bucket);
+
+
+  if( UNLIKELY(OPT__TREEOUTPUT) )
+  {
+    PrintS("]},");
+  }
+
+#ifndef SING_NDEBUG
+  if( OPT__DEBUG )
+  {
+    PrintS("SchreyerSyzygyComputation::SchreyerSyzygyNF(syz_lead, poly syz_2) =>>> \n");
+    dPrint(result, r, r, 0);
+    PrintLn();
+    // TODO: Add SyzCheck!!!???
+  }
+#endif
+
+  return result;
+}
+
+// namespace     {
+
+// };
+
+
+bool my_p_LmCmp (poly a, poly b, const ring r) { return p_LmCmp(a, b, r) == -1; } // TODO: change to simple lex. memory compare!
+
+// NOTE: need p_Copy?????? for image + multiplier!!???
+// NOTE: better store complete syz. terms!!?
+poly SchreyerSyzygyComputation::TraverseTail(poly multiplier, const int tail) const
+{
+#ifndef SING_NDEBUG
+  if( OPT__DEBUG ) {    m_div.Verify();    m_checker.Verify();  }
+#endif
+
+  const ring& r = m_rBaseRing;
+
+  assume(m_idTails !=  NULL && m_idTails->m != NULL);
+  assume( tail >= 0 && tail < IDELEMS(m_idTails) );
+
+  p_Test(multiplier, r);
+
+  if( UNLIKELY(OPT__NOCACHING) )
+    return ComputeImage(multiplier, tail);
+
+  // TODO: store (multiplier, tail) -.-^-.-^-.--> !
+  TCache::iterator top_itr = m_cache.find(tail);
+
+  if ( top_itr != m_cache.end() )
+  {
+     assume( top_itr->first == tail );
+
+     TP2PCache& T = top_itr->second;
+
+     TP2PCache::iterator itr = T.find(multiplier);
+
+     if( itr != T.end() ) // Yey - Reuse!!!
+     {
+       assume( p_LmEqual(itr->first, multiplier, r) );
+
+       if( itr->second == NULL ) // leadcoeff plays no role if value is NULL!
+         return (NULL);
+
+       if( UNLIKELY( OPT__TREEOUTPUT ) )
+       {
+//         PrintS("{ \"nodelabel\": \""); writeLatexTerm(multiplier, r, false);
+//         Print("  \\\\GEN{%d}\", \"children\": [ ", tail + 1);
+         PrintS("{ \"proc\": \"TTLookup\", \"nodelabel\": \"");
+         writeLatexTerm(itr->first, r, false); Print(" \\\\GEN{%d}\", \"Lookup\": \"", tail + 1);
+         writeLatexTerm(itr->second, r, true, false);
+         PrintS("\", ");
+       }
+
+       poly p = p_Copy(itr->second, r); // COPY!!!
+
+       p_Test(multiplier, r);
+
+       if( !n_Equal( pGetCoeff(multiplier), pGetCoeff(itr->first), r) ) // normalize coeffs!?
+       {
+         number n = n_Div( pGetCoeff(multiplier), pGetCoeff(itr->first), r); // new number
+
+         if( UNLIKELY( OPT__TREEOUTPUT ) )
+         {
+           StringSetS("");
+           n_Write(n, r);
+           char* s = StringEndS();
+           Print("\"recale\": \"%s\", ", s);
+           omFree(s);
+         }
+
+         if( UNLIKELY( OPT__PROT ) ) ++ m_stat[7]; // PrintS("l*"); // lookup & rescale
+
+         p = p_Mult_nn(p, n, r); // !
+         n_Delete(&n, r);
+       } else
+         if( UNLIKELY( OPT__PROT ) ) ++ m_stat[6]; // PrintS("l"); // lookup no rescale
+
+       if( UNLIKELY(OPT__TREEOUTPUT) )
+       {
+         PrintS("\"noderesult\": \"");         writeLatexTerm(p, r, true, false);         PrintS("\" },");
+       }
+
+#ifndef SING_NDEBUG
+       if( OPT__DEBUG )       {         m_div.Verify();         m_checker.Verify();       }
+#endif
+       p_Test(multiplier, r);
+
+       return p;
+     }
+
+
+     if( UNLIKELY(OPT__TREEOUTPUT) )
+     {
+       Print("{ \"proc\": \"TTStore%d\", \"nodelabel\": \"", tail + 1); writeLatexTerm(multiplier, r, false); Print(" \\\\GEN{%d}\", \"children\": [", tail + 1);
+     }
+
+     p_Test(multiplier, r);
+
+     const poly p = ComputeImage(multiplier, tail);
+
+     if( UNLIKELY(OPT__TREEOUTPUT) )
+     {
+       PrintS("], \"noderesult\": \""); writeLatexTerm(p, r, true, false); PrintS("\" },");
+     }
+
+     if( UNLIKELY(OPT__PROT) ) ++ m_stat[8]; // PrintS("S"); // store
+
+     p_Test(multiplier, r);
+
+     T.insert( TP2PCache::value_type(myp_Head(multiplier, (p==NULL), r), p) ); //     T[ multiplier ] = p;
+
+     p_Test(multiplier, r);
+
+//     if( p == NULL )
+//        return (NULL);
+
+#ifndef SING_NDEBUG
+     if( OPT__DEBUG )     {       m_div.Verify();       m_checker.Verify();     }
+#endif
+
+     return p_Copy(p, r);
+  }
+
+  CCacheCompare o(r); TP2PCache T(o);
+
+  if( UNLIKELY(OPT__TREEOUTPUT) )
+  {
+    Print("{ \"proc\": \"TTStore%d\", \"nodelabel\": \"", 0); writeLatexTerm(multiplier, r, false); Print(" \\\\GEN{%d}\", \"children\": [", tail + 1);
+  }
+
+  const poly p = ComputeImage(multiplier, tail);
+
+  if( UNLIKELY(OPT__TREEOUTPUT) )
+  {
+    PrintS("], \"noderesult\": \""); writeLatexTerm(p, r, true, false); PrintS("\" },");
+  }
+
+  if( UNLIKELY( OPT__PROT ) ) ++ m_stat[8]; // PrintS("S"); // store // %d", tail + 1);
+
+  T.insert( TP2PCache::value_type(myp_Head(multiplier, (p==NULL), r), p) );
+
+  m_cache.insert( TCache::value_type(tail, T) );
+
+//  if( p == NULL )
+//    return (NULL);
+
+#ifndef SING_NDEBUG
+  if( OPT__DEBUG )  {    m_div.Verify();    m_checker.Verify();  }
+#endif
+
+  return p_Copy(p, r);
+}
+
+poly SchreyerSyzygyComputation::ComputeImage(poly multiplier, const int tail) const
+{
+  const ring& r = m_rBaseRing;
+
+  assume(m_idTails !=  NULL && m_idTails->m != NULL);
+  assume( tail >= 0 && tail < IDELEMS(m_idTails) );
+
+  p_Test(multiplier, r);
+
+  const poly t = m_idTails->m[tail]; // !!!
+
+  if(t != NULL)
+  {
+    if( UNLIKELY(OPT__TREEOUTPUT) )
+    {
+      PrintS("{ \"proc\": \"ComputeImage\", \"nodelabel\": \"");
+      writeLatexTerm(multiplier, r, false);
+      Print(" \\\\GEN{%d}\", \"edgelabel\": \"", tail + 1);
+      writeLatexTerm(t, r, false);
+      PrintS("\", \"children\": [");
+    }
+
+    const poly p = TraverseTail(multiplier, t);
+
+    p_Test(multiplier, r);
+
+    if( UNLIKELY(OPT__TREEOUTPUT) )
+    {
+      PrintS("], \"noderesult\": \""); writeLatexTerm(p, r, true, false); PrintS("\" },");
+    }
+
+    return p;
+
+  }
+
+  return NULL;
+}
+
+
+poly SchreyerSyzygyComputation::TraverseTail(poly multiplier, poly tail) const
+{
+  assume( !OPT__IGNORETAILS );
+
+  const ideal& L = m_idLeads;
+  const ideal& T = m_idTails;
+  const ring& r = m_rBaseRing;
+
+  assume( multiplier != NULL );
+
+  assume( L != NULL );
+  assume( T != NULL );
+
+  p_Test(multiplier, r);
+
+#ifndef SING_NDEBUG
+  if( OPT__DEBUG )  {    m_div.Verify();    m_checker.Verify();  }
+#endif
+
+  if( UNLIKELY( !(  (!OPT__TAILREDSYZ)   ||   m_lcm.Check(multiplier)     )) )
+  {
+    if( UNLIKELY(OPT__TAILREDSYZ && OPT__PROT) )
+    { 
+      ++ m_stat[5]; // PrintS("%"); // check LCM !
+#ifndef SING_NDEBUG
+      if( OPT__DEBUG )  
+      { 
+        PrintS("\nTT,%:"); dPrint(multiplier, r, r, 0); 
+        PrintS(",  *  :"); dPrint(tail, r, r, 0); 
+        PrintLn(); 
+      }
+#endif
+    }
+    return NULL;
+  }
+
+  //    const bool bUsePolynomial = TEST_OPT_NOT_BUCKETS; //  || (pLength(tail) < MIN_LENGTH_BUCKET);
+
+  SBucketWrapper sum(r, m_sum_bucket_factory);
+/*
+  sBucket_pt sum;
+
+  if( m_sum_bucket == NULL )
+    sum = sBucketCreate(r);
+  else
+  {
+    if( !sIsEmpty(m_sum_bucket) )
+      sum = sBucketCreate(r);
+    else
+    {
+      sum = m_sum_bucket;
+      m_sum_bucket = NULL;
+    }
+  }
+
+
+  assume( sum != NULL ); assume ( sIsEmpty(sum) );
+  assume( r == sBucketGetRing(sum) );
+*/
+
+//  poly s; int len;
+
+  //    CPolynomialSummator sum(r, bUsePolynomial);
+  //    poly s = NULL;
+
+  if( UNLIKELY( OPT__TREEOUTPUT & 0 ) )
+  {
+    Print("{ \"proc\": \"TTPoly\", \"nodelabel\": \""); writeLatexTerm(multiplier, r, false); Print(" * \\\\ldots \", \"children\": [");
+  }
+
+  // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+  // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+  for(poly p = tail; p != NULL; p = pNext(p))   // iterate over the tail
+  {
+    // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+    const poly rt = ReduceTerm(multiplier, p, NULL); // TODO: also return/store length?
+    sum.Add(rt);
+    // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+    // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+    // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+//    const int lp = pLength(rt);
+//    if( rt != NULL && lp != 0 )
+//      sBucket_Add_p(sum, rt, lp);
+  }
+  // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+  // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+//  sBucketClearAdd(sum, &s, &len); // Will Not Clear?!?
+  const poly s = sum.ClearAdd();
+
+//  assume( sum != NULL ); assume ( sIsEmpty(sum) );
+/*
+  if( m_sum_bucket == NULL )
+    m_sum_bucket = sum;
+  else
+    sBucketDestroy(&sum);
+
+  assume( pLength(s) == len );
+*/
+
+#ifndef SING_NDEBUG
+  if( OPT__DEBUG )  {    m_div.Verify();    m_checker.Verify();  }
+#endif
+
+  if( UNLIKELY( OPT__TREEOUTPUT & 0 ) )
+  {
+    PrintS("], \"noderesult\": \""); writeLatexTerm(s, r, true, false); PrintS("\" },");
+  }
+
+  p_Test(multiplier, r);
+
+  return s;
+}
+
+
+
+
+poly SchreyerSyzygyComputation::ReduceTerm(poly multiplier, poly term4reduction, poly syztermCheck) const
+{
+#ifndef SING_NDEBUG
+  if( OPT__DEBUG )  {    m_div.Verify();    m_checker.Verify();  }
+#endif
+
+  assume( !OPT__IGNORETAILS );
+
+  const ideal& L = m_idLeads;
+  const ideal& T = m_idTails;
+  const ring& r = m_rBaseRing;
+
+  assume( multiplier != NULL );
+  assume( term4reduction != NULL );
+
+
+  assume( L != NULL );
+  assume( T != NULL );
+
+  p_Test(multiplier, r);
+
+  // simple implementation with FindReducer:
+  poly s = NULL;
+
+  if( (!OPT__TAILREDSYZ) || m_lcm.Check(multiplier) ) // TODO: UNLIKELY / LIKELY ????
+  {
+#if NOPRODUCT
+    s = m_div.FindReducer(multiplier, term4reduction, syztermCheck, m_checker); // s ????
+    p_Test(s, r);
+
+    p_Test(multiplier, r);
+
+    if( s == NULL ) // No Reducer?
+    {
+      if( UNLIKELY(OPT__PROT) ) ++ m_stat[4]; // PrintS("$"); // LOT
+      return NULL;
+    }
+
+    if( UNLIKELY( OPT__TREEOUTPUT ) )
+    {
+      poly product = pp_Mult_mm(multiplier, term4reduction, r);
+      PrintS("{ \"proc\": \"RdTrmNoP\", \"nodelabel\": \""); writeLatexTerm(s, r); PrintS("\", \"edgelabel\": \""); writeLatexTerm(product, r, false);
+      p_Delete(&product, r);
+    }
+
+#else
+    // NOTE: only LT(term4reduction) should be used in the following:
+    poly product = pp_Mult_mm(multiplier, term4reduction, r);
+    p_Test(product, r);
+
+    s = m_div.FindReducer(product, syztermCheck, m_checker); // ??
+    p_Test(s, r);
+
+    p_Test(multiplier, r);
+
+    if( s == NULL ) // No Reducer?
+    {
+      if( UNLIKELY(OPT__PROT) ) ++ m_stat[4]; // PrintS("$"); // LOT
+      return NULL;
+    }
+
+    if( UNLIKELY(OPT__TREEOUTPUT) )
+    {
+      PrintS("{ \"proc\": \"RdTrmP\", \"nodelabel\": \""); writeLatexTerm(s, r); PrintS("\", \"edgelabel\": \""); writeLatexTerm(product, r, false);
+    }
+
+    p_Delete(&product, r);
+#endif
+  }
+
+#ifndef SING_NDEBUG
+  if( OPT__DEBUG )  {    m_div.Verify();    m_checker.Verify();  }
+#endif
+
+  if( s == NULL ) // No Reducer?
+  {
+    if( UNLIKELY( OPT__TAILREDSYZ && OPT__PROT) ) 
+    { 
+      ++ m_stat[5]; // PrintS("%"); // check LCM !
+#ifndef SING_NDEBUG
+      if( OPT__DEBUG )  
+      { 
+        PrintS("\n%: RedTail("); dPrint(multiplier, r, r, 0);  
+        PrintS(" * : "); dPrint(term4reduction, r,r,0 ); 
+        PrintS(", {  "); dPrint(syztermCheck,r,r,0 );
+        PrintS("  }) ");  PrintLn(); 
+      }
+#endif
+    }
+    return NULL;
+  }
+
+  p_Test(multiplier, r);
+  p_Test(s, r);
+
+  poly b = leadmonom(s, r);
+
+  p_Test(b, r);
+
+  const int c = p_GetComp(s, r) - 1;
+  assume( c >= 0 && c < IDELEMS(T) );
+
+
+  if( UNLIKELY( OPT__TREEOUTPUT ) )
+     PrintS("\", \"children\": [");
+
+  const poly t = TraverseTail(b, c); // T->m[c];
+
+  if( UNLIKELY( OPT__TREEOUTPUT ) )
+  {
+
+    PrintS("], \"noderesult\": \"");
+    writeLatexTerm(t, r, true, false);
+    PrintS("\"");
+
+    if( syztermCheck != NULL )
+    {
+      PrintS(", \"syztermCheck\":\"" );
+      writeLatexTerm(syztermCheck, r, true, false);
+      PrintS("\" },");
+    } else
+      PrintS(" },");
+  }
+
+  p_Test(multiplier, r);
+
+  if( t != NULL )
+    s = p_Add_q(s, t, r);
+
+
+#ifndef SING_NDEBUG
+  if( OPT__DEBUG )  {    m_div.Verify();    m_checker.Verify();  }
+#endif
+
+  p_Test(multiplier, r);
+
+  return s;
+}
+
+SchreyerSyzygyComputationFlags::SchreyerSyzygyComputationFlags(idhdl rootRingHdl):
+    OPT__DEBUG( atGetInt(rootRingHdl,"DEBUG", 0) ),
+    OPT__LEAD2SYZ( atGetInt(rootRingHdl, "LEAD2SYZ", 0) ),
+    OPT__TAILREDSYZ( atGetInt(rootRingHdl, "TAILREDSYZ", 1) ),
+    OPT__HYBRIDNF( atGetInt(rootRingHdl, "HYBRIDNF", 0) ),
+    OPT__IGNORETAILS( atGetInt(rootRingHdl, "IGNORETAILS", 0) ),
+    OPT__SYZNUMBER( atGetInt(rootRingHdl, "SYZNUMBER", 0) ),
+    OPT__TREEOUTPUT( atGetInt(rootRingHdl, "TREEOUTPUT", 0) ),
+    OPT__SYZCHECK( atGetInt(rootRingHdl, "SYZCHECK", 0) ),
+    OPT__PROT(TEST_OPT_PROT),
+    OPT__NOCACHING( atGetInt(rootRingHdl, "NOCACHING", 0) ),
+    m_rBaseRing( rootRingHdl->data.uring )
+{
+#ifndef SING_NDEBUG
+  if( OPT__DEBUG & 0 )
+  {
+    PrintS("SchreyerSyzygyComputationFlags: \n");
+    Print("        DEBUG: \t%d\n", OPT__DEBUG);
+//    Print("   SYZCHECK  : \t%d\n", OPT__SYZCHECK);
+    Print("     LEAD2SYZ: \t%d\n", OPT__LEAD2SYZ);
+    Print("   TAILREDSYZ: \t%d\n", OPT__TAILREDSYZ);
+    Print("  IGNORETAILS: \t%d\n", OPT__IGNORETAILS);
+    Print("   TREEOUTPUT: \t%d\n", OPT__TREEOUTPUT);
+    Print("     SYZCHECK: \t%d\n", OPT__SYZCHECK);
+  }
+#endif
+
+  // TODO: just current setting!
+  assume( rootRingHdl == currRingHdl );
+  assume( rootRingHdl->typ == RING_CMD );
+  assume( m_rBaseRing == currRing );
+  // move the global ring here inside???
+}
+
+
+
+CLeadingTerm::CLeadingTerm(unsigned int _label,  const poly _lt, const ring R):
+    m_sev( p_GetShortExpVector(_lt, R) ),  m_label( _label ),  m_lt( _lt )
+#ifndef SING_NDEBUG
+    , _R(R), m_lt_copy( myp_Head(_lt, true, R) ) // note that p_LmEqual only tests exponents!
+#endif
+{
+#ifndef SING_NDEBUG
+  assume( pNext(m_lt_copy) == NULL );
+#endif
+  assume( sev() == p_GetShortExpVector(lt(), R) );
+}
+
+#ifndef SING_NDEBUG
+CLeadingTerm::~CLeadingTerm()
+{
+  assume( p_LmEqual(m_lt, m_lt_copy, _R) );
+  assume( m_sev == p_GetShortExpVector(m_lt, _R) );
+
+  poly p = const_cast<poly>(m_lt_copy);
+  p_Delete(&p, _R);
+}
+poly CLeadingTerm::lt() const
+{
+  assume( p_LmEqual(m_lt, m_lt_copy, _R) );
+  assume( m_sev == p_GetShortExpVector(m_lt, _R) );
+  return m_lt;
+}
+
+unsigned long CLeadingTerm::sev() const
+{
+  assume( p_LmEqual(m_lt, m_lt_copy, _R) );
+  assume( m_sev == p_GetShortExpVector(m_lt, _R) );
+  return m_sev;
+}
+
+unsigned int CLeadingTerm::label() const
+{
+  assume( p_LmEqual(m_lt, m_lt_copy, _R) );
+  assume( m_sev == p_GetShortExpVector(m_lt, _R) );
+  return m_label;
+}
+#endif
+
+
+
+CReducerFinder::~CReducerFinder()
+{
+  for( CReducersHash::const_iterator it = m_hash.begin(); it != m_hash.end(); it++ )
+  {
+    const TReducers& v = it->second;
+    for(TReducers::const_iterator vit = v.begin(); vit != v.end(); vit++ )
+      delete const_cast<CLeadingTerm*>(*vit);
+  }
+}
+
+
+void CReducerFinder::Initialize(const ideal L)
+{
+  assume( m_L == NULL || m_L == L );
+  if( m_L == NULL )
+    m_L = L;
+
+  assume( m_L == L );
+
+  if( L != NULL )
+  {
+    const ring& R = m_rBaseRing;
+    assume( R != NULL );
+
+    for( int k = IDELEMS(L) - 1; k >= 0; k-- )
+    {
+      const poly a = L->m[k]; // assume( a != NULL );
+
+      // NOTE: label is k \in 0 ... |L|-1!!!
+      if( a != NULL )
+        m_hash[p_GetComp(a, R)].push_back( new CLeadingTerm(k, a, R) );
+    }
+  }
+}
+
+CReducerFinder::CReducerFinder(const ideal L, const SchreyerSyzygyComputationFlags& flags):
+    SchreyerSyzygyComputationFlags(flags),
+    m_L(const_cast<ideal>(L)), // for debug anyway
+    m_hash()
+{
+  assume( flags.m_rBaseRing == m_rBaseRing );
+  if( L != NULL )
+    Initialize(L);
+}
+
+/// _p_LmDivisibleByNoComp for a | b*c
+static inline BOOLEAN _p_LmDivisibleByNoComp(const poly a, const poly b, const poly c, const ring r)
+{
+  int i=r->VarL_Size - 1;
+  unsigned long divmask = r->divmask;
+  unsigned long la, lb;
+
+  if (r->VarL_LowIndex >= 0)
+  {
+    i += r->VarL_LowIndex;
+    do
+    {
+      la = a->exp[i];
+      lb = b->exp[i] + c->exp[i];
+      if ((la > lb) ||
+          (((la & divmask) ^ (lb & divmask)) != ((lb - la) & divmask)))
+      {
+        pDivAssume(p_DebugLmDivisibleByNoComp(a, b, r) == FALSE);
+        return FALSE;
+      }
+      i--;
+    }
+    while (i>=r->VarL_LowIndex);
+  }
+  else
+  {
+    do
+    {
+      la = a->exp[r->VarL_Offset[i]];
+      lb = b->exp[r->VarL_Offset[i]] + c->exp[r->VarL_Offset[i]];
+      if ((la > lb) ||
+          (((la & divmask) ^ (lb & divmask)) != ((lb - la) & divmask)))
+      {
+        pDivAssume(p_DebugLmDivisibleByNoComp(a, b, r) == FALSE);
+        return FALSE;
+      }
+      i--;
+    }
+    while (i>=0);
+  }
+#ifdef HAVE_RINGS
+  assume( !rField_is_Ring(r) ); // not implemented for rings...!
+#endif
+  return TRUE;
+}
+
+
+bool CLeadingTerm::CheckLT( const ideal & L ) const
+{
+//  for( int i = IDELEMS(L); i >= 0; --i) assume( pNext(L->m[i]) == NULL ); // ???
+  return ( L->m[label()] == lt() );
+}
+
+bool CLeadingTerm::DivisibilityCheck(const poly product, const unsigned long not_sev, const ring r) const
+{
+  // may have no coeff yet
+//  assume ( !n_IsZero( p_GetCoeff(product, r), r ) );
+
+  assume ( !n_IsZero( p_GetCoeff(lt(), r), r ) );
+  assume( sev() == p_GetShortExpVector(lt(), r) );
+
+  assume( product != NULL );
+  assume( (p_GetComp(lt(), r) == p_GetComp(product, r)) || (p_GetComp(lt(), r) == 0) );
+
+#ifndef SING_NDEBUG
+  assume( r == _R );
+#endif
+
+//  const int k = label();
+//  assume( m_L->m[k] == p );
+
+  return p_LmShortDivisibleByNoComp(lt(), sev(), product, not_sev, r);
+
+}
+
+#if NOPRODUCT
+/// as DivisibilityCheck(multiplier * t, ...) for monomial 'm'
+/// and a module term 't'
+bool CLeadingTerm::DivisibilityCheck(const poly m, const poly t, const unsigned long not_sev, const ring r) const
+{
+  assume ( !n_IsZero( p_GetCoeff(lt(), r), r ) );
+  assume( sev() == p_GetShortExpVector(lt(), r) );
+
+  assume( m != NULL );
+  assume( t != NULL );
+  assume ( !n_IsZero( p_GetCoeff(m, r), r ) );
+  assume ( !n_IsZero( p_GetCoeff(t, r), r ) );
+
+// assume( p_GetComp(m, r) == 0 );
+  assume( (p_GetComp(lt(), r) == p_GetComp(t, r))  || (p_GetComp(lt(), r) == 0)  );
+
+  p_Test(m, r);
+  p_Test(t, r);
+//  const int k = label();
+//  assume( m_L->m[k] == p );
+
+#ifndef SING_NDEBUG
+  assume( r == _R );
+#endif
+
+  if (sev() & not_sev)
+    return false;
+
+  return _p_LmDivisibleByNoComp(lt(), m, t, r);
+//  return p_LmShortDivisibleByNoComp(p, p_sev, product, not_sev, r);
+}
+#endif
+
+
+/// TODO:
+class CDivisorEnumerator: public SchreyerSyzygyComputationFlags
+{
+  private:
+    const CReducerFinder& m_reds;
+    const poly m_product;
+    const unsigned long m_not_sev;
+    const long m_comp;
+
+    CReducerFinder::CReducersHash::const_iterator m_itr;
+    CReducerFinder::TReducers::const_iterator m_current, m_finish;
+
+    bool m_active;
+
+  public:
+    CDivisorEnumerator(const CReducerFinder& self, const poly product):
+        SchreyerSyzygyComputationFlags(self),
+        m_reds(self),
+        m_product(product),
+        m_not_sev(~p_GetShortExpVector(product, m_rBaseRing)),
+        m_comp(p_GetComp(product, m_rBaseRing)),
+        m_itr(), m_current(), m_finish(),
+        m_active(false)
+    {
+      assume( m_comp >= 0 );
+      assume( m_reds.m_L != NULL ); /// TODO: m_L should stay the same!!!
+
+      assume( product != NULL ); // may have no coeff yet :(
+//      assume ( !n_IsZero( p_GetCoeff(product, m_rBaseRing), m_rBaseRing ) );
+#ifndef SING_NDEBUG
+      if( OPT__DEBUG )        m_reds.Verify();
+#endif
+    }
+
+    inline bool Reset()
+    {
+      m_active = false;
+
+      m_itr = m_reds.m_hash.find(m_comp);
+
+      if( m_itr == m_reds.m_hash.end() )
+        return false;
+
+      assume( m_itr->first == m_comp );
+
+      m_current = (m_itr->second).begin();
+      m_finish = (m_itr->second).end();
+
+      if (m_current == m_finish)
+        return false;
+
+//      m_active = true;
+      return true;
+    }
+
+    const CLeadingTerm& Current() const
+    {
+      assume( m_active );
+      assume( m_current != m_finish );
+
+      return *(*m_current);
+    }
+
+    inline bool MoveNext()
+    {
+      assume( m_current != m_finish );
+
+      if( m_active )
+        ++m_current;
+      else
+        m_active = true; // for Current()
+
+      // looking for the next good entry
+      for( ; m_current != m_finish; ++m_current )
+      {
+        assume( Current().CheckLT( m_reds.m_L ) );
+
+        if( Current().DivisibilityCheck(m_product, m_not_sev, m_rBaseRing) )
+        {
+#ifndef SING_NDEBUG
+          if( OPT__DEBUG )
+          {
+            Print("CDivisorEnumerator::MoveNext::est LS: q is divisible by LS[%d] !:((, diviser is: ", 1 + Current().label());
+            dPrint(Current().lt(), m_rBaseRing, m_rBaseRing, 0);
+          }
+#endif
+//          m_active = true;
+          assume( Current().CheckLT( m_reds.m_L ) );
+          return true;
+        }
+        assume( Current().CheckLT( m_reds.m_L ) );
+      }
+
+      // the end... :(
+      assume( m_current == m_finish );
+
+      m_active = false;
+      return false;
+    }
+};
+
+
+
+bool CReducerFinder::IsDivisible(const poly product) const
+{
+#ifndef SING_NDEBUG
+  if( OPT__DEBUG )    Verify();
+#endif
+
+  assume( product != NULL );
+
+  // NOTE: q may have no coeff!!!
+
+  CDivisorEnumerator itr(*this, product);
+  if( !itr.Reset() )
+    return false;
+
+  return itr.MoveNext();
+
+/*
+  const ring& r = m_rBaseRing;
+
+  const long comp = p_GetComp(product, r);
+  const unsigned long not_sev = ~p_GetShortExpVector(product, r);
+
+  assume( comp >= 0 );
+
+  CReducersHash::const_iterator it = m_hash.find(comp); // same module component
+
+  assume( m_L != NULL );
+
+  if( it == m_hash.end() )
+    return false;
+  // assume comp!
+
+  const TReducers& reducers = it->second;
+
+  for(TReducers::const_iterator vit = reducers.begin(); vit != reducers.end(); vit++ )
+  {
+    assume( (*vit)->CheckLT( m_L ) );
+
+    if( (*vit)->DivisibilityCheck(product, not_sev, r) )
+    {
+      if( OPT__DEBUG )
+      {
+        Print("_FindReducer::Test LS: q is divisible by LS[%d] !:((, diviser is: ", 1 + (*vit)->label());
+        dPrint((*vit)->lt(), r, r, 0);
+      }
+
+      return true;
+    }
+  }
+
+  return false;
+*/
+}
+
+
+#ifndef SING_NDEBUG
+void CReducerFinder::Verify() const
+{
+  const ring& r = m_rBaseRing;
+
+  for( CReducersHash::const_iterator it = m_hash.begin(); it != m_hash.end(); it++)
+  {
+    const TReducers& reducers = it->second;
+
+    for(TReducers::const_iterator vit = reducers.begin(); vit != reducers.end(); vit++ )
+    {
+      assume( (*vit)->CheckLT( m_L ) );
+
+      const poly p = (*vit)->lt();
+
+      const unsigned long p_sev = (*vit)->sev();
+      assume( p_sev == p_GetShortExpVector(p, r) );
+
+      assume( p_GetComp(p, r) == it->first );
+
+      const int k = (*vit)->label();
+      assume( m_L->m[k] == p );
+
+      pp_Test(p, r, r);
+    }
+  }
+}
+
+
+
+void CReducerFinder::DebugPrint() const
+{
+  const ring& r = m_rBaseRing;
+
+  for( CReducersHash::const_iterator it = m_hash.begin(); it != m_hash.end(); it++)
+  {
+    Print("Hash Key: %ld, Values: \n", it->first);
+    const TReducers& reducers = it->second;
+
+    for(TReducers::const_iterator vit = reducers.begin(); vit != reducers.end(); vit++ )
+    {
+      assume( (*vit)->CheckLT( m_L ) );
+
+      const int k = (*vit)->label();
+      const poly p = (*vit)->lt();
+
+      pp_Test(p, r, r);
+
+      assume( m_L->m[k] == p );
+
+      const unsigned long p_sev = (*vit)->sev();
+      assume( p_sev == p_GetShortExpVector(p, r) );
+
+      assume( p_GetComp(p, r) == it->first );
+
+      Print("L[%d]: ", k); dPrint(p, r, r, 0); Print("SEV: %ld\n", p_sev);
+
+      assume( m_L->m[k] == p );
+    }
+  }
+}
+#endif
+
+#if NOPRODUCT
+
+/// TODO:
+class CDivisorEnumerator2: public SchreyerSyzygyComputationFlags
+{
+  private:
+    const CReducerFinder& m_reds;
+    const poly m_multiplier, m_term;
+    const unsigned long m_not_sev;
+    const long m_comp;
+
+    CReducerFinder::CReducersHash::const_iterator m_itr;
+    CReducerFinder::TReducers::const_iterator m_current, m_finish;
+
+    bool m_active;
+
+  public:
+    CDivisorEnumerator2(const CReducerFinder& self, const poly m, const poly t):
+        SchreyerSyzygyComputationFlags(self),
+        m_reds(self),
+        m_multiplier(m), m_term(t),
+        m_not_sev(~p_GetShortExpVector(m, t, m_rBaseRing)),
+        m_comp(p_GetComp(t, m_rBaseRing)),
+        m_itr(), m_current(), m_finish(),
+        m_active(false)
+    {
+      assume( m_comp >= 0 );
+      assume( m_reds.m_L != NULL );
+      assume( m_multiplier != NULL );
+      assume( m_term != NULL );
+
+      assume( m != NULL );
+      assume( t != NULL );
+      assume ( !n_IsZero( p_GetCoeff(m, m_rBaseRing), m_rBaseRing ) );
+      assume ( !n_IsZero( p_GetCoeff(t, m_rBaseRing), m_rBaseRing ) );
+
+      p_Test(m, m_rBaseRing);
+
+//      assume( p_GetComp(m_multiplier, m_rBaseRing) == 0 );
+#ifndef SING_NDEBUG
+      if( OPT__DEBUG ) m_reds.Verify();
+#endif
+    }
+
+    inline bool Reset()
+    {
+      m_active = false;
+
+      m_itr = m_reds.m_hash.find(m_comp);
+
+      if( m_itr == m_reds.m_hash.end() )
+        return false;
+
+      assume( m_itr->first == m_comp );
+
+      m_current = (m_itr->second).begin();
+      m_finish = (m_itr->second).end();
+
+      if (m_current == m_finish)
+        return false;
+
+      return true;
+    }
+
+    const CLeadingTerm& Current() const
+    {
+      assume( m_active );
+      assume( m_current != m_finish );
+
+      return *(*m_current);
+    }
+
+    inline bool MoveNext()
+    {
+      assume( m_current != m_finish );
+
+      if( m_active )
+        ++m_current;
+      else
+        m_active = true;
+
+
+      // looking for the next good entry
+      for( ; m_current != m_finish; ++m_current )
+      {
+        assume( Current().CheckLT( m_reds.m_L ) );
+
+        if( Current().DivisibilityCheck(m_multiplier, m_term, m_not_sev, m_rBaseRing) )
+        {
+#ifndef SING_NDEBUG
+          if( OPT__DEBUG )
+          {
+            Print("CDivisorEnumerator::MoveNext::est LS: q is divisible by LS[%d] !:((, diviser is: ", 1 + Current().label());
+            dPrint(Current().lt(), m_rBaseRing, m_rBaseRing, 0);
+          }
+#endif
+//          m_active = true;
+          assume( Current().CheckLT( m_reds.m_L ) );
+          return true;
+
+        }
+        assume( Current().CheckLT( m_reds.m_L ) );
+      }
+
+      // the end... :(
+      assume( m_current == m_finish );
+
+      m_active = false;
+      return false;
+    }
+};
+
+poly CReducerFinder::FindReducer(const poly multiplier, const poly t,
+                                 const poly syzterm,
+                                 const CReducerFinder& syz_checker) const
+{
+  const ring& r = m_rBaseRing;
+
+#ifndef SING_NDEBUG
+  if( OPT__DEBUG )  {    Verify();    syz_checker.Verify();  }
+#endif
+
+  p_Test(multiplier, r);
+
+  CDivisorEnumerator2 itr(*this, multiplier, t);
+  if( !itr.Reset() )
+    return NULL;
+
+  // don't care about the module component of multiplier (as it may be the syzygy term)
+  // product = multiplier * t?
+
+  assume( multiplier != NULL ); assume( t != NULL );
+
+  const ideal& L = m_L; assume( L != NULL ); // for debug/testing only!
+
+  long c = 0;
+
+  if (syzterm != NULL)
+    c = p_GetComp(syzterm, r) - 1;
+
+  assume( c >= 0 && c < IDELEMS(L) );
+
+  p_Test(multiplier, r);
+
+  if (UNLIKELY( OPT__DEBUG && (syzterm != NULL) ))
+  {
+    const poly m = L->m[c]; assume( m != NULL ); assume( pNext(m) == NULL );
+
+    //  def @@c = leadcomp(syzterm); int @@r = int(@@c);
+    //  def @@product = leadmonomial(syzterm) * L[@@r];
+    poly lm = p_Mult_mm( leadmonom(syzterm, r, true), m, r); // !NC :(
+    poly pr = p_Mult_q( leadmonom(multiplier, r, true), leadmonom(t, r, false), r); // !NC :(
+
+    assume( p_EqualPolys(lm, pr, r) );
+
+    p_Delete(&lm, r);
+    p_Delete(&pr, r);
+  }
+
+#ifndef SING_NDEBUG
+  if( OPT__DEBUG )  {    Verify();    syz_checker.Verify();  }
+#endif
+
+  const BOOLEAN to_check = (syz_checker.IsNonempty()); // OPT__TAILREDSYZ &&
+
+//  const poly q = p_One(r);
+  const poly q = p_New(r); pNext(q) = NULL;
+
+  if( UNLIKELY(OPT__DEBUG) )
+    p_SetCoeff0(q, 0, r); // for printing q
+
+  assume( pNext(q) == NULL );
+
+  p_Test(multiplier, r);
+  while( itr.MoveNext() )
+  {
+    assume( itr.Current().CheckLT( L ) ); // ???
+
+    const poly p = itr.Current().lt(); // ???
+    const int k  = itr.Current().label();
+
+    p_ExpVectorSum(q, multiplier, t, r); // q == product == multiplier * t // TODO: do it once?
+    p_ExpVectorDiff(q, q, p, r); // (LM(product) / LM(L[k]))
+
+    p_SetComp(q, k + 1, r);
+    p_Setm(q, r);
+
+    p_Test(multiplier, r);
+
+    // cannot allow something like: a*gen(i) - a*gen(i)
+    if (syzterm != NULL && (k == c))
+      if (p_ExpVectorEqual(syzterm, q, r))
+      {
+#ifndef SING_NDEBUG
+        if( OPT__DEBUG )
+        {
+          Print("_FindReducer::Test SYZTERM: q == syzterm !:((, syzterm is: ");
+          dPrint(syzterm, r, r, 0);
+        }
+#endif
+        assume( itr.Current().CheckLT( L ) ); // ???
+        continue;
+      }
+
+    // while the complement (the fraction) is not reducible by leading syzygies
+    if( to_check && syz_checker.IsDivisible(q) )
+    {
+#ifndef SING_NDEBUG
+      if( OPT__DEBUG )
+      {
+        PrintS("_FindReducer::Test LS: q is divisible by LS[?] !:((: ");
+      }
+#endif
+      assume( itr.Current().CheckLT( L ) ); // ???
+      continue;
+    }
+
+    number n = n_Mult( p_GetCoeff(multiplier, r), p_GetCoeff(t, r), r);
+
+#if NODIVISION
+    // we assume all leading coeffs to be 1!
+    assume( n_IsOne(p_GetCoeff(p, r), r->cf) );
+#else
+    if( !n_IsOne( p_GetCoeff(p, r), r ) )
+      n = n_Div(n, p_GetCoeff(p, r), r);
+#endif
+
+    p_SetCoeff0(q, n_InpNeg(n, r), r);
+//    n_Delete(&n, r);
+
+#ifndef SING_NDEBUG
+    if( OPT__DEBUG )    {      Verify();      syz_checker.Verify();    }
+#endif
+    p_Test(multiplier, r);
+    p_Test(q, r);
+
+    assume( itr.Current().CheckLT( L ) ); // ???
+    return q;
+  }
+
+/*
+  const long comp = p_GetComp(t, r); assume( comp >= 0 );
+  const unsigned long not_sev = ~p_GetShortExpVector(multiplier, t, r); // !
+
+//   for( int k = IDELEMS(L)-1; k>= 0; k-- )
+//   {
+//     const poly p = L->m[k];
+//
+//     if ( p_GetComp(p, r) != comp )
+//       continue;
+//
+//     const unsigned long p_sev = p_GetShortExpVector(p, r); // to be stored in m_hash!!!
+
+   // looking for an appropriate diviser p = L[k]...
+  CReducersHash::const_iterator it = m_hash.find(comp); // same module component
+
+  if( it == m_hash.end() )
+    return NULL;
+
+  // assume comp!
+
+  assume( m_L != NULL );
+
+  const TReducers& reducers = it->second;
+
+  for(TReducers::const_iterator vit = reducers.begin(); vit != reducers.end(); vit++ )
+  {
+
+    const poly p = (*vit)->lt(); // ??
+    const int k = (*vit)->label();
+
+    assume( L->m[k] == p ); // CheckLT
+
+//    const unsigned long p_sev = (*vit)->sev();
+//    assume( p_sev == p_GetShortExpVector(p, r) );
+
+//    if( !p_LmShortDivisibleByNoComp(p, p_sev, product, not_sev, r) )
+//      continue;
+
+    if( !(*vit)->DivisibilityCheck(multiplier, t, not_sev, r) )
+      continue;
+
+
+//    if (p_sev & not_sev) continue;
+//    if( !_p_LmDivisibleByNoComp(p, multiplier, t, r) ) continue;
+
+
+    p_ExpVectorSum(q, multiplier, t, r); // q == product == multiplier * t
+    p_ExpVectorDiff(q, q, p, r); // (LM(product) / LM(L[k]))
+
+    p_SetComp(q, k + 1, r);
+    p_Setm(q, r);
+
+    // cannot allow something like: a*gen(i) - a*gen(i)
+    if (syzterm != NULL && (k == c))
+      if (p_ExpVectorEqual(syzterm, q, r))
+      {
+        if( OPT__DEBUG )
+        {
+          Print("_FindReducer::Test SYZTERM: q == syzterm !:((, syzterm is: ");
+          dPrint(syzterm, r, r, 0);
+        }
+
+        continue;
+      }
+
+    // while the complement (the fraction) is not reducible by leading syzygies
+    if( to_check && syz_checker.IsDivisible(q) )
+    {
+      if( OPT__DEBUG )
+      {
+        PrintS("_FindReducer::Test LS: q is divisible by LS[?] !:((: ");
+      }
+
+      continue;
+    }
+
+    number n = n_Mult( p_GetCoeff(multiplier, r), p_GetCoeff(t, r), r);
+    p_SetCoeff0(q, n_InpNeg( n_Div(n, p_GetCoeff(p, r), r), r), r);
+    n_Delete(&n, r);
+
+    return q;
+  }
+*/
+
+  p_LmFree(q, r);
+
+#ifndef SING_NDEBUG
+  if( OPT__DEBUG )  {    Verify();    syz_checker.Verify();  }
+#endif
+
+  p_Test(multiplier, r);
+
+  return NULL;
+
+}
+#endif
+
+
+poly CReducerFinder::FindReducer(const poly product, const poly syzterm, const CReducerFinder& syz_checker) const
+{
+
+#ifndef SING_NDEBUG
+  if( OPT__DEBUG )  {    Verify();    syz_checker.Verify();  }
+#endif
+
+  CDivisorEnumerator itr(*this, product);
+  if( !itr.Reset() )
+    return NULL;
+
+
+
+  const ring& r = m_rBaseRing;
+
+  assume( product != NULL );
+
+  const ideal& L = m_L; assume( L != NULL ); // for debug/testing only!
+
+  long c = 0;
+
+  if (syzterm != NULL)
+    c = p_GetComp(syzterm, r) - 1;
+
+  assume( c >= 0 && c < IDELEMS(L) );
+
+  if (UNLIKELY( OPT__DEBUG && (syzterm != NULL) ))
+  {
+    const poly m = L->m[c];
+
+    assume( m != NULL ); assume( pNext(m) == NULL );
+
+    poly lm = p_Mult_mm(leadmonom(syzterm, r), m, r);
+    assume( p_EqualPolys(lm, product, r) );
+
+    //  def @@c = leadcomp(syzterm); int @@r = int(@@c);
+    //  def @@product = leadmonomial(syzterm) * L[@@r];
+
+    p_Delete(&lm, r);
+  }
+
+#ifndef SING_NDEBUG
+  if( OPT__DEBUG )  {    Verify();    syz_checker.Verify();  }
+#endif
+
+  const BOOLEAN to_check = (syz_checker.IsNonempty()); // OPT__TAILREDSYZ &&
+
+  const poly q = p_New(r); pNext(q) = NULL;
+
+  if( UNLIKELY(OPT__DEBUG) )
+    p_SetCoeff0(q, 0, r); // ONLY for printing q
+
+  while( itr.MoveNext() )
+  {
+    assume( itr.Current().CheckLT( L ) ); // ???
+
+    const poly p = itr.Current().lt(); // ??
+    const int k  = itr.Current().label();
+
+    p_ExpVectorDiff(q, product, p, r); // (LM(product) / LM(L[k]))
+    p_SetComp(q, k + 1, r);
+    p_Setm(q, r);
+
+    // cannot allow something like: a*gen(i) - a*gen(i)
+    if (syzterm != NULL && (k == c))
+      if (p_ExpVectorEqual(syzterm, q, r))
+      {
+#ifndef SING_NDEBUG
+        if( OPT__DEBUG )
+        {
+          Print("_FindReducer::Test SYZTERM: q == syzterm !:((, syzterm is: ");
+          dPrint(syzterm, r, r, 0);
+        }
+#endif
+        assume( itr.Current().CheckLT( L ) ); // ???
+        continue;
+      }
+
+    // while the complement (the fraction) is not reducible by leading syzygies
+    if( to_check && syz_checker.IsDivisible(q) ) // ?????
+    {
+#ifndef SING_NDEBUG
+      if( OPT__DEBUG )
+      {
+        PrintS("_FindReducer::Test LS: q is divisible by LS[?] !:((: ");
+      }
+#endif
+      assume( itr.Current().CheckLT( L ) ); // ???
+      continue;
+    }
+
+
+#if NODIVISION
+    assume( n_IsOne(p_GetCoeff(p, r), r->cf) );
+    p_SetCoeff0(q, n_InpNeg( n_Copy(p_GetCoeff(product, r), r), r), r);
+#else
+    p_SetCoeff0(q, n_InpNeg( n_Div( p_GetCoeff(product, r), p_GetCoeff(p, r), r), r), r);
+#endif
+
+    assume( itr.Current().CheckLT( L ) ); // ???
+
+#ifndef SING_NDEBUG
+    if( OPT__DEBUG )    {      Verify();      syz_checker.Verify();    }
+#endif
+
+    return q;
+  }
+
+
+
+/*
+  const long comp = p_GetComp(product, r);
+  const unsigned long not_sev = ~p_GetShortExpVector(product, r);
+
+  assume( comp >= 0 );
+
+//   for( int k = IDELEMS(L)-1; k>= 0; k-- )
+//   {
+//     const poly p = L->m[k];
+//
+//     if ( p_GetComp(p, r) != comp )
+//       continue;
+//
+//     const unsigned long p_sev = p_GetShortExpVector(p, r); // to be stored in m_hash!!!
+
+   // looking for an appropriate diviser p = L[k]...
+  CReducersHash::const_iterator it = m_hash.find(comp); // same module component
+
+  if( it == m_hash.end() )
+    return NULL;
+
+  assume( m_L != NULL );
+
+  const TReducers& reducers = it->second;
+
+  const BOOLEAN to_check = (syz_checker.IsNonempty()); // OPT__TAILREDSYZ &&
+
+  const poly q = p_New(r); pNext(q) = NULL;
+
+  if( OPT__DEBUG )
+    p_SetCoeff0(q, 0, r); // for printing q
+
+  for(TReducers::const_iterator vit = reducers.begin(); vit != reducers.end(); vit++ )
+  {
+    const poly p = (*vit)->lt(); // ???
+
+    assume( p_GetComp(p, r) == comp );
+
+    const int k = (*vit)->label();
+
+    assume( L->m[k] == p ); // CheckLT
+
+    const unsigned long p_sev = (*vit)->sev();
+
+    assume( p_sev == p_GetShortExpVector(p, r) );
+
+    if( !p_LmShortDivisibleByNoComp(p, p_sev, product, not_sev, r) )
+      continue;
+
+//     // ... which divides the product, looking for the _1st_ appropriate one!
+//     if( !p_LmDivisibleByNoComp(p, product, r) ) // included inside  p_LmShortDivisibleBy!
+//       continue;
+
+    p_ExpVectorDiff(q, product, p, r); // (LM(product) / LM(L[k]))
+    p_SetComp(q, k + 1, r);
+    p_Setm(q, r);
+
+    // cannot allow something like: a*gen(i) - a*gen(i)
+    if (syzterm != NULL && (k == c))
+      if (p_ExpVectorEqual(syzterm, q, r))
+      {
+        if( OPT__DEBUG )
+        {
+          Print("_FindReducer::Test SYZTERM: q == syzterm !:((, syzterm is: ");
+          dPrint(syzterm, r, r, 0);
+        }
+
+        continue;
+      }
+
+    // while the complement (the fraction) is not reducible by leading syzygies
+    if( to_check && syz_checker.IsDivisible(q) )
+    {
+      if( OPT__DEBUG )
+      {
+        PrintS("_FindReducer::Test LS: q is divisible by LS[?] !:((: ");
+      }
+
+      continue;
+    }
+
+    p_SetCoeff0(q, n_InpNeg( n_Div( p_GetCoeff(product, r), p_GetCoeff(p, r), r), r), r);
+    return q;
+  }
+*/
+
+  p_LmFree(q, r);
+
+#ifndef SING_NDEBUG
+  if( OPT__DEBUG )  {    Verify();    syz_checker.Verify();  }
+#endif
+
+  return NULL;
+}
+
+
+
+CLCM::CLCM(const ideal& L, const SchreyerSyzygyComputationFlags& flags):
+    SchreyerSyzygyComputationFlags(flags), std::vector<bool>(),
+    m_compute(false), m_N(rVar(flags.m_rBaseRing))
+{
+  const ring& R = m_rBaseRing;
+  assume( flags.m_rBaseRing == R );
+  assume( R != NULL );
+
+  assume( L != NULL );
+
+  if( LIKELY( OPT__TAILREDSYZ && !OPT__HYBRIDNF && (L != NULL) )) // TODO: not hybrid!?
+  {
+    const int l = IDELEMS(L);
+
+    assume( l > 0 );
+
+    resize(l, false);
+
+    for( int k = l - 1; k >= 0; k-- )
+    {
+      const poly a = L->m[k]; assume( a != NULL );
+
+      for (unsigned int j = m_N; j > 0; j--)
+        if ( !(*this)[j] )
+          (*this)[j] = (p_GetExp(a, j, R) > 0);
+    }
+
+    m_compute = true;
+  }
+}
+
+
+bool CLCM::Check(const poly m) const
+{
+  assume( m != NULL );
+  if( m_compute && (m != NULL))
+  {
+    const ring& R = m_rBaseRing;
+
+    assume( OPT__TAILREDSYZ && !OPT__HYBRIDNF );
+
+    for (unsigned int j = m_N; j > 0; j--)
+      if ( (*this)[j] )
+        if(p_GetExp(m, j, R) > 0)
+          return true;
+
+    return false;
+
+  } else return true;
+}
+
+CCacheCompare::CCacheCompare(): m_ring(currRing) {}
+
+
+template class std::vector<bool>;
+template class std::vector<CLeadingTerm const*>;
+template class std::map< CReducerFinder::TComponentKey, CReducerFinder::TReducers >;
+
+template class std::map<TCacheKey, TCacheValue, struct CCacheCompare>;
+template class std::map<int, TP2PCache>;
+
+template class std::stack <sBucket_pt>;
+
+END_NAMESPACE               END_NAMESPACE_SINGULARXX
+
+
+// Vi-modeline: vim: filetype=c:syntax:shiftwidth=2:tabstop=8:textwidth=0:expandtab
diff --git a/Singular/dyn_modules/syzextra/syzextra.h b/Singular/dyn_modules/syzextra/syzextra.h
new file mode 100644
index 0000000..7563268
--- /dev/null
+++ b/Singular/dyn_modules/syzextra/syzextra.h
@@ -0,0 +1,638 @@
+// -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+/*****************************************************************************\
+ * Computer Algebra System SINGULAR
+\*****************************************************************************/
+/** @file syzextra.h
+ *
+ * Computation of Syzygies
+ *
+ * ABSTRACT: Computation of Syzygies due to Schreyer
+ *
+ * @author Oleksandr Motsak
+ *
+ **/
+/*****************************************************************************/
+
+#ifndef SYZEXTRA_H
+#define SYZEXTRA_H
+
+#include <vector>
+#include <map>
+#include <string.h>
+#include <stack>
+
+// include basic definitions
+#include "singularxx_defs.h"
+
+struct spolyrec; typedef struct spolyrec polyrec; typedef polyrec* poly;
+struct ip_sring; typedef struct ip_sring* ring; typedef struct ip_sring const* const_ring;
+
+struct sip_sideal; typedef struct sip_sideal *       ideal;
+class idrec; typedef idrec *   idhdl;
+
+class kBucket; typedef kBucket* kBucket_pt;
+
+#ifndef NOPRODUCT
+# define NOPRODUCT 1
+#endif
+
+// set to 1 if all leading coeffs are assumed to be all =1...
+// note the use of simplify on input in SSinit!
+#ifndef NODIVISION
+# define NODIVISION 1
+#endif
+
+BEGIN_NAMESPACE_SINGULARXX    BEGIN_NAMESPACE(SYZEXTRA)
+
+poly leadmonom(const poly p, const ring r, const bool bSetZeroComp = true);
+
+/// return the tail of a given polynomial or vector
+/// returns NULL if input is NULL, otherwise
+/// the result is a new polynomial/vector in the ring r
+poly p_Tail(const poly p, const ring r);
+
+
+/// return the tail of a given ideal or module
+/// returns NULL if input is NULL, otherwise
+/// the result is a new ideal/module in the ring r
+/// NOTE: the resulting rank is autocorrected
+ideal id_Tail(const ideal id, const ring r);
+
+/// inplace sorting of the module (ideal) id wrt <_(c,ds)
+void Sort_c_ds(const ideal id, const ring r);
+
+
+class sBucket; typedef sBucket* sBucket_pt;
+
+/** @class SBucketFactory syzextra.h
+ *
+ * sBucket Factory
+ *
+ * Cleate/store/reuse buckets
+ *
+ */
+class SBucketFactory: private std::stack <sBucket_pt>
+{
+  private:
+    typedef std::stack <sBucket_pt> Base;
+//    typedef std::vector<Bucket> Memory;
+//    typedef std::deque <Bucket> Memory;
+//    typedef std::stack <Bucket, Memory > Base;
+
+  public:
+    typedef Base::value_type Bucket;
+
+    SBucketFactory(const ring r)
+#ifndef SING_NDEBUG
+        : m_ring(r)
+#endif
+    {
+      push ( _CreateBucket(r) ); // start with at least one sBucket...?
+      assume( top() != NULL );
+    };
+
+    ~SBucketFactory()
+    {
+      while( !empty() )
+      {
+        _DestroyBucket( top() );
+        pop();
+      }
+    }
+
+    Bucket getBucket(const ring r, const bool remove = true)
+    {
+      assume( r == m_ring );
+
+      Bucket bt = NULL;
+
+      if( !empty() )
+      {
+        bt = top();
+
+        if( remove )
+          pop();
+      }
+      else
+      {
+        bt = _CreateBucket(r);
+
+        if( !remove )
+        {
+          push(bt);
+          assume( bt == top() );
+        }
+      }
+
+      assume( bt != NULL );
+      assume( _IsBucketEmpty(bt) );
+      assume( r == _GetBucketRing(bt) );
+
+      return bt;
+    }
+
+    // TODO: this may be spared if we give-out a smart Bucket (which returns here upon its destructor!)
+    void putBucket(const Bucket & bt, const bool replace = false)
+    {
+      assume( bt != NULL );
+      assume( _IsBucketEmpty(bt) );
+      assume( m_ring == _GetBucketRing(bt) );
+
+      if( empty() )
+        push( bt );
+      else
+      {
+        if( replace )
+          top() = bt;
+        else
+        {
+          if( bt != top() )
+            push( bt );
+        }
+      }
+
+      assume( bt == top() );
+    }
+
+  private:
+
+#ifndef SING_NDEBUG
+    const ring m_ring; ///< For debugging: all buckets are over the same ring... right?!
+
+    /// get bucket ring
+    static ring _GetBucketRing(const Bucket& bt);
+
+    static bool  _IsBucketEmpty(const Bucket& bt);
+#endif
+
+    /// inital allocation for new buckets
+    static Bucket _CreateBucket(const ring r);
+
+    /// we only expect empty buckets to be left at the end for destructor
+    /// bt will be set to NULL
+    static void _DestroyBucket(Bucket & bt);
+
+  private:
+    SBucketFactory();
+    SBucketFactory(const SBucketFactory&);
+    void operator=(const SBucketFactory&);
+
+};
+
+
+
+
+
+
+
+/// Computation attribute storage
+struct SchreyerSyzygyComputationFlags
+{
+    SchreyerSyzygyComputationFlags(idhdl rootRingHdl);
+
+    SchreyerSyzygyComputationFlags(const SchreyerSyzygyComputationFlags& attr):
+        OPT__DEBUG(attr.OPT__DEBUG),
+        OPT__LEAD2SYZ(attr.OPT__LEAD2SYZ),  OPT__TAILREDSYZ(attr.OPT__TAILREDSYZ),
+        OPT__HYBRIDNF(attr.OPT__HYBRIDNF), OPT__IGNORETAILS(attr.OPT__IGNORETAILS),
+        OPT__SYZNUMBER(attr.OPT__SYZNUMBER), OPT__TREEOUTPUT(attr.OPT__TREEOUTPUT),
+        OPT__SYZCHECK(attr.OPT__SYZCHECK), OPT__PROT(attr.OPT__PROT),
+        OPT__NOCACHING(attr.OPT__NOCACHING),
+        m_rBaseRing(attr.m_rBaseRing)
+    {}
+
+  /// output all the intermediate states
+  const int OPT__DEBUG; // DebugOutput;
+
+  /// ?
+  const int OPT__LEAD2SYZ; // TwoLeadingSyzygyTerms;
+
+  /// Reduce syzygy tails wrt the leading syzygy terms
+  const int OPT__TAILREDSYZ; // TailReducedSyzygies;
+
+  /// Use the usual NF's S-poly reduction while dropping lower order terms
+  /// 2 means - smart selection!
+  const int OPT__HYBRIDNF; // UseHybridNF
+
+
+  /// ignore tails and compute the pure Schreyer frame
+  const int OPT__IGNORETAILS; // @IGNORETAILS
+
+  /// Syzygy level (within a resolution)
+  mutable int OPT__SYZNUMBER;
+
+  inline void  nextSyzygyLayer() const
+  {
+     OPT__SYZNUMBER++;
+  }
+
+  /// output lifting tree
+  const int OPT__TREEOUTPUT;
+
+  /// CheckSyzygyProperty: TODO
+  const int OPT__SYZCHECK;
+
+  /// TEST_OPT_PROT
+  const bool OPT__PROT;
+
+  /// no caching/stores/lookups
+  const int OPT__NOCACHING;
+
+  /// global base ring
+  const ring m_rBaseRing;
+};
+
+class SchreyerSyzygyComputation;
+
+class CLCM: public SchreyerSyzygyComputationFlags, public std::vector<bool>
+{
+  public:
+    CLCM(const ideal& L, const SchreyerSyzygyComputationFlags& flags);
+
+    bool Check(const poly m) const;
+
+  private:
+    bool m_compute;
+
+    const unsigned int m_N; ///< number of ring variables
+};
+
+
+class CLeadingTerm
+{
+  public:
+    CLeadingTerm(unsigned int label,  const poly lt, const ring);
+
+#ifndef SING_NDEBUG
+    ~CLeadingTerm();
+#endif
+
+#if NOPRODUCT
+    bool DivisibilityCheck(const poly multiplier, const poly t, const unsigned long not_sev, const ring r) const;
+#endif
+    bool DivisibilityCheck(const poly product, const unsigned long not_sev, const ring r) const;
+
+    bool CheckLT( const ideal & L ) const;
+
+#ifndef SING_NDEBUG
+    poly lt() const;
+    unsigned long sev() const;
+    unsigned int label() const;
+#else
+    inline poly lt() const { return m_lt; };
+    inline unsigned long sev() const { return m_sev; };
+    inline unsigned int label() const { return m_label; };
+#endif
+
+  private:
+    const unsigned long m_sev; ///< not short exp. vector
+
+    // NOTE/TODO: either of the following should be enough:
+    const unsigned int  m_label; ///< index in the main L[] + 1
+
+    const poly          m_lt; ///< the leading term itself L[label-1]
+
+#ifndef SING_NDEBUG
+    const ring _R;
+
+    const poly          m_lt_copy; ///< original copy of LEAD(lt) (only for debug!!!)
+#endif
+
+    // disable the following:
+    CLeadingTerm();
+    CLeadingTerm(const CLeadingTerm&);
+    void operator=(const CLeadingTerm&);
+};
+
+
+// TODO: needs a specialized variant without a component (hash!)
+class CReducerFinder: public SchreyerSyzygyComputationFlags
+{
+#if NOPRODUCT
+  friend class CDivisorEnumerator2;
+#endif
+  friend class CDivisorEnumerator;
+
+  public:
+    typedef long TComponentKey;
+    typedef std::vector<const CLeadingTerm*> TReducers;
+
+  private:
+    typedef std::map< TComponentKey, TReducers> CReducersHash;
+
+  public:
+    /// goes over all leading terms
+    CReducerFinder(const ideal L, const SchreyerSyzygyComputationFlags& flags);
+
+    void Initialize(const ideal L);
+
+    ~CReducerFinder();
+
+
+#if NOPRODUCT
+    poly
+        FindReducer(const poly multiplier, const poly monom, const poly syzterm, const CReducerFinder& checker) const;
+
+#endif
+    // TODO: save shortcut (syz: |-.->) LM(LM(m) * "t") -> syz?
+    poly // const_iterator // TODO: return const_iterator it, s.th: it->m_lt is the needed
+        FindReducer(const poly product, const poly syzterm, const CReducerFinder& checker) const;
+
+    bool IsDivisible(const poly q) const;
+
+
+    inline bool IsNonempty() const { return !m_hash.empty(); }
+
+    /// is the term to be "preprocessed" as lower order term or lead to only reducible syzygies...
+    int PreProcessTerm(const poly t, CReducerFinder& syzChecker) const;
+
+#ifndef SING_NDEBUG
+    void DebugPrint() const;
+    void Verify() const;
+#endif
+
+  private:
+    ideal m_L; ///< only for debug
+
+    CReducersHash m_hash; // can also be replaced with a vector indexed by components
+
+  private:
+    CReducerFinder(const CReducerFinder&);
+    void operator=(const CReducerFinder&);
+};
+
+extern ideal id_Copy (const ideal, const ring);
+bool my_p_LmCmp (poly, poly, const ring);
+
+typedef poly TCacheKey;
+typedef poly TCacheValue;
+
+struct CCacheCompare
+{
+  const ring & m_ring;
+
+  CCacheCompare();
+
+  CCacheCompare(const ring& r): m_ring(r) { assume(r != NULL); }
+
+  CCacheCompare(const CCacheCompare& lhs): m_ring(lhs.m_ring) { assume(m_ring != NULL); }
+  CCacheCompare& operator=(const CCacheCompare& lhs) { assume(lhs.m_ring != NULL); return (const_cast<CCacheCompare&>(lhs)); }
+
+  inline bool operator() (const TCacheKey& l, const TCacheKey& r) const { assume(m_ring != NULL); return my_p_LmCmp(l, r, m_ring); }
+};
+
+typedef std::map<TCacheKey, TCacheValue, CCacheCompare> TP2PCache; // deallocation??? !!!
+typedef std::map<int, TP2PCache> TCache;
+
+
+/** @class SchreyerSyzygyComputation syzextra.h
+ *
+ * Computing syzygies after Schreyer
+ *
+ * Storing/accumulating data during the computation requires some global
+ * object, like this class. Ideally the above global functions should not
+ * be used in favour of this class.
+ *
+ * @sa Schreyer Syzygy Computation Paper & Talk & Python prototype
+ */
+class SchreyerSyzygyComputation: public SchreyerSyzygyComputationFlags
+{
+  friend class CLCM;
+  friend class CReducerFinder;
+
+  public:
+    /// Construct a global object for given input data (separated into leads & tails)
+    SchreyerSyzygyComputation(const ideal idLeads, const ideal idTails, const SchreyerSyzygyComputationFlags setting):
+        SchreyerSyzygyComputationFlags(setting),
+        m_idLeads(idLeads), m_idTails(id_Copy(idTails, setting.m_rBaseRing)),
+        m_syzLeads(NULL), m_syzTails(NULL),
+        m_LS(NULL), m_lcm(m_idLeads, setting),
+        m_div(m_idLeads, setting), m_checker(NULL, setting), m_cache(),
+        m_sum_bucket_factory(setting.m_rBaseRing),
+        m_spoly_bucket(NULL)
+    {
+      if( UNLIKELY(OPT__PROT) ) memset( &m_stat, 0, sizeof(m_stat) );
+    }
+
+    /// Construct a global object for given input data (separated into leads & tails)
+    SchreyerSyzygyComputation(const ideal idLeads, const ideal idTails, const ideal syzLeads, const SchreyerSyzygyComputationFlags setting):
+        SchreyerSyzygyComputationFlags(setting),
+        m_idLeads(idLeads), m_idTails(id_Copy(idTails, setting.m_rBaseRing)),
+        m_syzLeads(syzLeads), m_syzTails(NULL),
+        m_LS(syzLeads), m_lcm(m_idLeads, setting),
+        m_div(m_idLeads, setting), m_checker(NULL, setting), m_cache(),
+        m_sum_bucket_factory(setting.m_rBaseRing),
+        m_spoly_bucket(NULL)
+    {
+      if( UNLIKELY(OPT__PROT) ) memset( &m_stat, 0, sizeof(m_stat) );
+
+      if( LIKELY(OPT__TAILREDSYZ && !OPT__IGNORETAILS) )
+      {
+        if (syzLeads != NULL)
+          m_checker.Initialize(syzLeads);
+//        if( idTails != NULL )
+//          SetUpTailTerms();
+      }
+    }
+
+    /// Destructor should not destruct the resulting m_syzLeads, m_syzTails.
+    ~SchreyerSyzygyComputation(){ CleanUp(); }
+
+    /// Convert the given ideal of tails into the internal representation (with reducers!)
+    /// Preprocess m_idTails as well...?
+    void SetUpTailTerms();
+
+    /// print statistics about the used heuristics
+    void PrintStats() const;
+
+    /// Read off the results while detaching them from this object
+    /// NOTE: no copy!
+    inline void ReadOffResult(ideal& syzL, ideal& syzT)
+    {
+      syzL = m_syzLeads; syzT = m_syzTails;
+
+      m_syzLeads = m_syzTails = NULL; // m_LS ?
+
+      if ( UNLIKELY(OPT__PROT) )
+        PrintStats();
+    }
+
+
+    /// The main driver function: computes
+    void ComputeSyzygy();
+
+    /// Computes Syz(leads) or only LEAD of it.
+    /// The result is stored into m_syzLeads
+    void ComputeLeadingSyzygyTerms(bool bComputeSecondTerms = true);
+
+
+
+    /// Main HybridNF == 1: poly reduce + LOT + LCM?
+    poly SchreyerSyzygyNF(const poly syz_lead, poly syz_2 = NULL) const;
+
+
+    // Main (HybridNF == 0) Tree Travers + LOT + LCM?
+    poly TraverseNF(const poly syz_lead, const poly syz_2 = NULL) const;
+
+    /// High level caching function!!!
+    poly TraverseTail(poly multiplier, const int tail) const;
+
+    // REMOVE?
+    /// called only from above and from outside (for testing)
+    poly TraverseTail(poly multiplier, poly tail) const;
+
+    /// TODO: save shortcut (syz: |-.->) LM(m) * "t" -> ? ???
+    poly ReduceTerm(poly multiplier, poly term4reduction, poly syztermCheck) const;
+
+    /// low level computation...
+    poly ComputeImage(poly multiplier, const int tail) const;
+
+
+
+  public:
+    /// just for testing via the wrapper below
+    inline poly _FindReducer(const poly product, const poly syzterm) const
+        { return m_div.FindReducer(product, syzterm, m_checker); }
+ private:
+    void CleanUp();
+  protected:
+
+
+    /// just leading terms
+    ideal Compute1LeadingSyzygyTerms();
+
+    /// leading + second terms
+    ideal Compute2LeadingSyzygyTerms();
+
+
+
+  private:
+    /// input leading terms
+    const ideal m_idLeads;
+
+    /// input tails
+    const ideal m_idTails;
+
+    /// output (syzygy) leading terms (+2nd terms?)
+    ideal m_syzLeads;
+
+    /// output (syzygy) tails
+    ideal m_syzTails;
+
+    /*mutable?*/ ideal m_LS; ///< leading syzygy terms used for reducing syzygy tails
+
+
+    /// Bitmask for variables occuring in leading terms
+    const CLCM m_lcm;
+
+    /// Divisor finder
+    const CReducerFinder m_div;
+
+    /// for checking tail-terms and makeing them irreducible (wrt m_LS!)
+    CReducerFinder m_checker;
+
+    /*
+    // need more data here:
+    // (m_idLeads : m_tailterm) = (m, pos, compl), s.th: compl * m_tailterm divides m_idLeads[pos]
+    // but resulting sysygy compl * gen(pos) should not be in
+    // Idea: extend CReducerFinder??!!
+    struct CTailTerm
+    {
+      const poly m_tailterm;
+
+      const CReducerFinder m_reducers; // positions are labels (in m_idLeads)...
+      // compl - to be computed if needed?
+
+      CTailTerm(const poly tt, const CReducerFinder reds): m_tailterm(tt), m_reducers(reds) {}
+    };
+
+    typedef std::vector<const CTailTerm*> TTail;
+    typedef std::vector<TTail> TTailTerms;
+
+    TTailTerms m_idTailTerms;
+    */
+
+    mutable TCache m_cache; // cacher comp + poly -> poly! // mutable???
+
+/// TODO: look into m_idTailTerms!!!!!!!!!!!!!!!!!!!!!!!! map? heaps???
+    // NOTE/TODO: the following globally shared buckets violate reentrance - they should rather belong to TLS!
+
+    /// used for simple summing up
+    mutable SBucketFactory m_sum_bucket_factory; // sBucket_pt
+
+    /// for S-Polynomial reductions
+    mutable kBucket_pt m_spoly_bucket; // only used inside of SchreyerSyzygyNF! destruction by CleanUp()!
+
+
+    /// Statistics:
+    ///  0..3: as in SetUpTailTerms()::PreProcessTerm() // TODO!!??
+    ///  4: number of terms discarded due to LOT heuristics
+    ///  5: number of terms discarded due to LCM heuristics
+    ///  6, 7: lookups without & with rescale, 8: stores
+    mutable unsigned long m_stat[9];
+};
+
+// The following wrappers are just for testing separate functions on highest level (within schreyer.lib)
+
+static inline void ComputeSyzygy(const ideal L, const ideal T, ideal& LL, ideal& TT, const SchreyerSyzygyComputationFlags A)
+{
+  SchreyerSyzygyComputation syz(L, T, A);
+  syz.ComputeSyzygy();
+  syz.ReadOffResult(LL, TT);
+}
+
+static inline ideal ComputeLeadingSyzygyTerms(const ideal& L, const SchreyerSyzygyComputationFlags A)
+{
+  SchreyerSyzygyComputation syz(L, NULL, A);
+  syz.ComputeLeadingSyzygyTerms(false);
+  ideal LL, TT;
+  syz.ReadOffResult(LL, TT);
+  return LL; // assume TT is NULL!
+}
+
+static inline ideal Compute2LeadingSyzygyTerms(const ideal& L, const SchreyerSyzygyComputationFlags A)
+{
+  SchreyerSyzygyComputation syz(L, NULL, A);
+  syz.ComputeLeadingSyzygyTerms(true);
+  ideal LL, TT;
+  syz.ReadOffResult(LL, TT);
+  return LL; // assume TT is NULL!
+}
+
+static inline poly FindReducer(poly product, poly syzterm,
+                               ideal L, ideal LS, const SchreyerSyzygyComputationFlags A)
+{
+  SchreyerSyzygyComputation syz(L, NULL, LS, A);
+  return syz._FindReducer(product, syzterm);
+}
+
+static inline poly TraverseTail(poly multiplier, poly tail,
+                                ideal L, ideal T, ideal LS, const SchreyerSyzygyComputationFlags A)
+{
+  SchreyerSyzygyComputation syz(L, T, LS, A);
+  return syz.TraverseTail(multiplier, tail);
+}
+
+static inline poly ReduceTerm(poly multiplier, poly term4reduction, poly syztermCheck,
+                              ideal L, ideal T, ideal LS, const SchreyerSyzygyComputationFlags A)
+{
+  SchreyerSyzygyComputation syz(L, T, LS, A);
+  return syz.ReduceTerm(multiplier, term4reduction, syztermCheck);
+}
+
+
+static inline poly SchreyerSyzygyNF(poly syz_lead, poly syz_2,
+                                    ideal L, ideal T, ideal LS, const SchreyerSyzygyComputationFlags A)
+{
+  SchreyerSyzygyComputation syz(L, T, LS, A);
+  return syz.SchreyerSyzygyNF(syz_lead, syz_2);
+}
+
+END_NAMESPACE
+
+END_NAMESPACE_SINGULARXX
+
+#endif
+/* #ifndef SYZEXTRA_H */
+
+// Vi-modeline: vim: filetype=c:syntax:shiftwidth=2:tabstop=8:textwidth=0:expandtab
+
diff --git a/Singular/dyn_modules/syzextra/test.sh b/Singular/dyn_modules/syzextra/test.sh
new file mode 100755
index 0000000..24ca4a9
--- /dev/null
+++ b/Singular/dyn_modules/syzextra/test.sh
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+#"$SINGULAR_EXECUTABLE" -teq "$srcdir/test_clear_enum.tst" || exit 1
+#"$SINGULAR_EXECUTABLE" -teq "$srcdir/ederc.tst" || exit 1
+#"$SINGULAR_EXECUTABLE" -teq "$srcdir/syzextra.tst" || exit 1
+"$SINGULAR_EXECUTABLE" -tec 'LIB "schreyer.lib"; listvar(Top); proc T(){ Schreyer::testSimple(1, 0); /* Schreyer::testAGR(0); Schreyer::testAGRhard(0); */ } T(); $' || exit 1
diff --git a/Singular/dyn_modules/syzextra/test_release.sh b/Singular/dyn_modules/syzextra/test_release.sh
new file mode 100755
index 0000000..acd09bd
--- /dev/null
+++ b/Singular/dyn_modules/syzextra/test_release.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+export SINGULAR_EXECUTABLE="$SINGULAR_BIN_DIR/Singular"
+. "$srcdir/test.sh"
diff --git a/Singular/eigenval_ip.cc b/Singular/eigenval_ip.cc
new file mode 100644
index 0000000..011d63f
--- /dev/null
+++ b/Singular/eigenval_ip.cc
@@ -0,0 +1,285 @@
+/*****************************************
+*  Computer Algebra System SINGULAR      *
+*****************************************/
+/*
+* ABSTRACT: eigenvalues of constant square matrices
+*/
+
+
+
+
+#include <kernel/mod2.h>
+
+#ifdef HAVE_EIGENVAL
+
+#include <Singular/tok.h>
+#include <Singular/ipid.h>
+#include <misc/intvec.h>
+#include <coeffs/numbers.h>
+#include <kernel/polys.h>
+#include <kernel/ideals.h>
+#include <Singular/lists.h>
+#include <polys/matpol.h>
+#include <polys/clapsing.h>
+#include <kernel/linear_algebra/eigenval.h>
+#include <Singular/ipshell.h>
+#include <Singular/eigenval_ip.h>
+
+
+BOOLEAN evSwap(leftv res,leftv h)
+{
+  if(currRing)
+  {
+    short t[]={3,MATRIX_CMD,INT_CMD,INT_CMD};
+    if (iiCheckTypes(h,t,1))
+    {
+      matrix M=(matrix)h->Data();
+      h=h->next;
+      int i=(int)(long)h->Data();
+      h=h->next;
+      int j=(int)(long)h->Data();
+      res->rtyp=MATRIX_CMD;
+      res->data=(void *)evSwap(mp_Copy(M, currRing),i,j);
+      return FALSE;
+    }
+    return TRUE;
+  }
+  WerrorS("no ring active");
+  return TRUE;
+}
+
+BOOLEAN evRowElim(leftv res,leftv h)
+{
+  if(currRing)
+  {
+    short t[]={4,MATRIX_CMD,INT_CMD,INT_CMD,INT_CMD};
+    if (iiCheckTypes(h,t,1))
+    {
+      matrix M=(matrix)h->CopyD();
+      h=h->next;
+      int i=(int)(long)h->Data();
+      h=h->next;
+      int j=(int)(long)h->Data();
+      h=h->next;
+      int k=(int)(long)h->Data();
+      res->rtyp=MATRIX_CMD;
+      res->data=(void *)evRowElim(M,i,j,k);
+      return FALSE;
+    }
+    return TRUE;
+  }
+  WerrorS("no ring active");
+  return TRUE;
+}
+
+BOOLEAN evColElim(leftv res,leftv h)
+{
+  if(currRing)
+  {
+    short t[]={4,MATRIX_CMD,INT_CMD,INT_CMD,INT_CMD};
+    if (iiCheckTypes(h,t,1))
+    {
+      matrix M=(matrix)h->Data();
+      h=h->next;
+      int i=(int)(long)h->Data();
+      h=h->next;
+      int j=(int)(long)h->Data();
+      h=h->next;
+      int k=(int)(long)h->Data();
+      res->rtyp=MATRIX_CMD;
+      res->data=(void *)evColElim(mp_Copy(M, currRing),i,j,k);
+      return FALSE;
+    }
+    return TRUE;
+  }
+  WerrorS("no ring active");
+  return TRUE;
+}
+
+BOOLEAN evHessenberg(leftv res,leftv h)
+{
+  if(currRing)
+  {
+    if(h&&h->Typ()==MATRIX_CMD)
+    {
+      matrix M=(matrix)h->Data();
+      res->rtyp=MATRIX_CMD;
+      res->data=(void *)evHessenberg(mp_Copy(M, currRing));
+      return FALSE;
+    }
+    WerrorS("<matrix> expected");
+    return TRUE;
+  }
+  WerrorS("no ring active");
+  return TRUE;
+}
+
+
+lists evEigenvals(matrix M)
+{
+  lists l=(lists)omAllocBin(slists_bin);
+  if(MATROWS(M)!=MATCOLS(M))
+  {
+    l->Init(0);
+    return(l);
+  }
+
+  M=evHessenberg(M);
+
+  int n=MATCOLS(M);
+  ideal e=idInit(n,1);
+  intvec *m=new intvec(n);
+
+  poly t=pOne();
+  pSetExp(t,1,1);
+  pSetm(t);
+
+  for(int j0=1,j=2,k=0;j<=n+1;j0=j,j++)
+  {
+    while(j<=n&&MATELEM(M,j,j-1)!=NULL)
+      j++;
+    if(j==j0+1)
+    {
+      e->m[k]=pHead(MATELEM(M,j0,j0));
+      (*m)[k]=1;
+      k++;
+    }
+    else
+    {
+      int n0=j-j0;
+      matrix M0=mpNew(n0,n0);
+
+      j0--;
+      for(int i=1;i<=n0;i++)
+        for(int j=1;j<=n0;j++)
+          MATELEM(M0,i,j)=pCopy(MATELEM(M,j0+i,j0+j));
+      for(int i=1;i<=n0;i++)
+        MATELEM(M0,i,i)=pSub(MATELEM(M0,i,i),pCopy(t));
+
+      intvec *m0;
+      ideal e0=singclap_factorize(mp_DetBareiss(M0,currRing),&m0,2, currRing);
+      if (e0==NULL)
+      {
+        l->Init(0);
+        return(l);
+      }
+
+      for(int i=0;i<IDELEMS(e0);i++)
+      {
+        if(pNext(e0->m[i])==NULL)
+        {
+          (*m)[k]=(*m0)[i];
+          k++;
+        }
+        else
+        if(pGetExp(e0->m[i],1)<2&&pGetExp(pNext(e0->m[i]),1)<2&&
+           pNext(pNext(e0->m[i]))==NULL)
+        {
+          number e1=nCopy(pGetCoeff(e0->m[i]));
+          e1=nInpNeg(e1);
+          if(pGetExp(pNext(e0->m[i]),1)==0)
+            e->m[k]=pNSet(nDiv(pGetCoeff(pNext(e0->m[i])),e1));
+          else
+            e->m[k]=pNSet(nDiv(e1,pGetCoeff(pNext(e0->m[i]))));
+          nDelete(&e1);
+          pNormalize(e->m[k]);
+          (*m)[k]=(*m0)[i];
+          k++;
+        }
+        else
+        {
+          e->m[k]=e0->m[i];
+          pNormalize(e->m[k]);
+          e0->m[i]=NULL;
+          (*m)[k]=(*m0)[i];
+          k++;
+        }
+      }
+
+      delete(m0);
+      idDelete(&e0);
+    }
+  }
+
+  pDelete(&t);
+  idDelete((ideal *)&M);
+
+  for(int i0=0;i0<n-1;i0++)
+  {
+    for(int i1=i0+1;i1<n;i1++)
+    {
+      if(pEqualPolys(e->m[i0],e->m[i1]))
+      {
+        (*m)[i0]+=(*m)[i1];
+        (*m)[i1]=0;
+      }
+      else
+      {
+        if(e->m[i0]==NULL&&!nGreaterZero(pGetCoeff(e->m[i1]))||
+           e->m[i1]==NULL&&
+          (nGreaterZero(pGetCoeff(e->m[i0]))||pNext(e->m[i0])!=NULL)||
+           e->m[i0]!=NULL&&e->m[i1]!=NULL&&
+          (pNext(e->m[i0])!=NULL&&pNext(e->m[i1])==NULL||
+           pNext(e->m[i0])==NULL&&pNext(e->m[i1])==NULL&&
+           nGreater(pGetCoeff(e->m[i0]),pGetCoeff(e->m[i1]))))
+        {
+          poly e1=e->m[i0];
+          e->m[i0]=e->m[i1];
+          e->m[i1]=e1;
+          int m1=(*m)[i0];
+          (*m)[i0]=(*m)[i1];
+          (*m)[i1]=m1;
+        }
+      }
+    }
+  }
+
+  int n0=0;
+  for(int i=0;i<n;i++)
+    if((*m)[i]>0)
+      n0++;
+
+  ideal e0=idInit(n0,1);
+  intvec *m0=new intvec(n0);
+
+  for(int i=0,i0=0;i<n;i++)
+    if((*m)[i]>0)
+    {
+      e0->m[i0]=e->m[i];
+      e->m[i]=NULL;
+      (*m0)[i0]=(*m)[i];
+      i0++;
+    }
+
+  idDelete(&e);
+  delete(m);
+
+  l->Init(2);
+  l->m[0].rtyp=IDEAL_CMD;
+  l->m[0].data=e0;
+  l->m[1].rtyp=INTVEC_CMD;
+  l->m[1].data=m0;
+
+  return(l);
+}
+
+
+BOOLEAN evEigenvals(leftv res,leftv h)
+{
+  if(currRing)
+  {
+    if(h&&h->Typ()==MATRIX_CMD)
+    {
+      matrix M=(matrix)h->CopyD();
+      res->rtyp=LIST_CMD;
+      res->data=(void *)evEigenvals(M);
+      return FALSE;
+    }
+    WerrorS("<matrix> expected");
+    return TRUE;
+  }
+  WerrorS("no ring active");
+  return TRUE;
+}
+
+#endif /* HAVE_EIGENVAL */
diff --git a/Singular/eigenval_ip.h b/Singular/eigenval_ip.h
new file mode 100644
index 0000000..3f10498
--- /dev/null
+++ b/Singular/eigenval_ip.h
@@ -0,0 +1,21 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: eigenvalues of constant square matrices
+*/
+
+#ifndef EIGENVAL_IP_H
+#define EIGENVAL_IP_H
+#ifdef HAVE_EIGENVAL
+#include <kernel/linear_algebra/eigenval.h>
+
+BOOLEAN evSwap(leftv res,leftv h);
+BOOLEAN evRowElim(leftv res,leftv h);
+BOOLEAN evColElim(leftv res,leftv h);
+BOOLEAN evHessenberg(leftv res,leftv h);
+lists evEigenvals(matrix M);
+BOOLEAN evEigenvals(leftv res,leftv h);
+
+#endif /* ifdef HAVE_EIGENVAL */
+#endif /* EIGENVAL_IP_H */
diff --git a/Singular/emacs.cc b/Singular/emacs.cc
new file mode 100644
index 0000000..9145a19
--- /dev/null
+++ b/Singular/emacs.cc
@@ -0,0 +1,341 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: Esingular main file
+*/
+
+
+
+
+#include <kernel/mod2.h>
+#include <omalloc/omalloc.h>
+#include <resources/feResource.h>
+#include <Singular/feOpt.h>
+
+#ifdef __CYGWIN__
+#define BOOLEAN boolean
+#endif
+
+#include <stdio.h>
+#include <unistd.h>
+
+#ifdef DecAlpha_OSF1
+#define _BSD
+#endif
+
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+
+#ifdef __CYGWIN__
+#include <windows.h>
+#endif
+
+
+#if !defined(TSINGULAR) && !defined(ESINGULAR)
+#define ESINGULAR
+#endif
+
+#ifdef system
+#undef system
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+#ifndef TRUE
+#define TRUE 1
+#endif
+#ifndef MAXPATHLEN
+#define MAXPATHLEN 1024
+#endif
+#  define  DIR_SEP '/'
+#  define  DIR_SEPP "/"
+#  define  UP_DIR ".."
+
+#ifndef __CYGWIN__
+void error(const char *fmt, ...)
+{
+  va_list ap;
+  va_start(ap, fmt);
+  vfprintf(stderr, fmt, ap);
+}
+#else
+void error(const char* fmt, ...)
+{
+   char buf[4096];
+   int j =0;
+   va_list args;
+   va_start(args, fmt);
+   j =   sprintf(buf,    "");
+   j += vsprintf(buf + j,fmt,args);
+   j +=  sprintf(buf + j,"\n");
+   va_end(args);
+   MessageBox(NULL, buf, "ESingular.exe", MB_ICONSTOP);
+   exit(1);
+}
+#endif
+
+#define Warn  error
+#define WarnS error
+#define StringAppend printf
+#define Print error
+
+#define feReportBug(s) fePrintReportBug(s, __FILE__, __LINE__)
+void fePrintReportBug(char* msg, char* file, int line)
+{
+  error("YOU HAVE FOUND A BUG IN SINGULAR.\n"
+"Please, email the following output to singular at mathematik.uni-kl.de\n"
+"Bug occured at %s:%d\n"
+"Message: %s\n"
+"Version: " S_UNAME VERSION __DATE__ __TIME__,
+        file, line, msg);
+
+}
+
+void mainUsage()
+{
+  error( "Use `%s --help' for a complete list of options\n", feArgv0);
+}
+
+extern char* feResourceDefault(const char id);
+extern char* feResourceDefault(const char* key);
+
+
+int main(int argc, char** argv)
+{
+  char* singular = NULL;
+  char* emacs = NULL;
+#ifndef TSINGULAR
+  char* emacs_dir = NULL;
+  char* emacs_load = NULL;
+  char cwd[MAXPATHLEN];
+#endif
+  int no_emacs_call = 0;
+
+  // parse-cmdline options
+
+  feInitResources(argv[0]);
+  feResource('S');
+  feResource('b');
+  feResource('r');
+
+  int optc, option_index;
+
+  while ((optc = fe_getopt_long(argc, argv, SHORT_OPTS_STRING,
+                                feOptSpec, &option_index))
+        != EOF)
+  {
+    switch(optc)
+    {
+      case 'h':
+          extern void feOptHelp(const char* name);
+
+          feOptHelp(feArgv0);
+          exit(0);
+
+        case '?':
+        case ':':
+        case '\0':
+          mainUsage();
+          exit(1);
+
+        case  LONG_OPTION_RETURN:
+        {
+          switch(option_index)
+          {
+#ifdef TSINGULAR
+              case FE_OPT_XTERM:
+                emacs = fe_optarg;
+              break;
+#else
+              case FE_OPT_EMACS:
+                emacs = fe_optarg;
+                break;
+
+              case FE_OPT_EMACS_DIR:
+                emacs_dir = fe_optarg;
+                break;
+
+              case FE_OPT_EMACS_LOAD:
+                emacs_load = fe_optarg;
+                break;
+#endif
+              case FE_OPT_SINGULAR:
+                singular = fe_optarg;
+                break;
+
+              case FE_OPT_NO_CALL:
+                no_emacs_call = 1;
+                break;
+
+              default:
+                goto NEXT;
+          }
+          // delete options from option-list
+          if (fe_optind > 2 && *argv[fe_optind-1] != '-' &&
+              fe_optarg != NULL && feOptSpec[option_index].has_arg)
+          {
+            argv[fe_optind-2] = NULL;
+          }
+          argv[fe_optind-1] = NULL;
+        }
+    }
+    NEXT:{}
+  }
+
+  int i, length = 0;
+  char* syscall;
+  for (i=1; i<argc; i++)
+  {
+    if (argv[i] != NULL) length += strlen(argv[i]) + 3;
+  }
+
+#ifdef TSINGULAR
+  if (emacs == NULL) emacs = feResource('X', 0);
+  if (emacs == NULL)
+  {
+    error( "Error: Can't find emacs xterm program. \n Expected it at %s or %s\n Specify alternative with --xterm=PROGRAM option,\n or set ESINGULAR_EMACS environment variable to the name of the program to use as xterm.\n",
+           feResourceDefault('X'));
+    mainUsage();
+    exit(1);
+  }
+
+  if (singular == NULL) singular = feResource("SingularXterm", 0);
+  if (singular == NULL)
+  {
+    error( "Error: Can't find singular executable.\n Expected it at %s\n Specify with --singular option,\n or set TSINGULAR_SINGULAR environment variable.\n",
+            feResourceDefault("SingularXterm"));
+    mainUsage();
+    exit(1);
+  }
+
+#ifdef __CYGWIN__
+#define EXTRA_XTERM_ARGS "+vb -sl 2000 -fb Courier-bold-12 -tn xterm -cr Red3"
+#else
+#define EXTRA_XTERM_ARGS ""
+#endif
+
+  syscall = (char*) omAlloc(strlen(emacs) +
+                                 strlen(singular) +
+                                 length + 300);
+  sprintf(syscall, "%s %s -e %s ", emacs, EXTRA_XTERM_ARGS, singular);
+
+  for (i=1; i<argc; i++)
+  {
+    if (argv[i] != NULL)
+    {
+      strcat(syscall, " ");
+      strcat(syscall, argv[i]);
+    }
+  }
+#else
+  // make sure  emacs, singular, emacs_dir, emacs_load are set
+  if (emacs == NULL) emacs = feResource("xemacs", 0);
+  if (emacs == NULL) emacs = feResource("emacs", 0);
+  if (emacs == NULL)
+  {
+    error( "Error: Can't find emacs or xemacs executable. \n Expected it at %s or %s\n Specify alternative with --emacs option,\n or set ESINGULAR_EMACS environment variable.\n",
+            feResourceDefault("emacs"), feResourceDefault("xemacs"));
+    mainUsage();
+    exit(1);
+  }
+
+  if (singular == NULL) singular = feResource("SingularEmacs", 0);
+  if (singular == NULL)
+  {
+    error( "Error: Can't find singular executable.\n Expected it at %s\n Specify with --singular option,\n or set ESINGULAR_SINGULAR environment variable.\n",
+            feResourceDefault("SingularEmacs"));
+    mainUsage();
+    exit(1);
+  }
+
+  if (emacs_dir == NULL) emacs_dir = feResource("EmacsDir", 0);
+  if (emacs_dir == NULL)
+  {
+    error( "Error: Can't find emacs directory for Singular lisp files. \n Expected it at %s\n Specify with --emacs_dir option,\n or set ESINGULAR_EMACS_DIR environment variable.\n",
+            feResourceDefault("EmacsDir"));
+    mainUsage();
+    exit(1);
+  }
+
+  if (emacs_load == NULL)
+  {
+    // look into env variable
+    emacs_load = getenv("ESINGULAR_EMACS_LOAD");
+    if (access(emacs_load, R_OK))
+    {
+      // look in home-dir
+      emacs_load = getenv("HOME");
+#ifdef __CYGWIN__
+      if ((emacs_load==NULL)||(!access(emacs_load,X_OK)))
+        emacs_load = getenv("SINGHOME");
+#endif
+      sprintf(cwd, "%s/.emacs-singular", emacs_load);
+      if (! access(cwd, R_OK))
+      {
+        emacs_load = omStrDup(cwd);
+      }
+      else
+      {
+        // try with resources
+        emacs_load = feResource("EmacsLoad", 0);
+        if (emacs_load == NULL)
+        {
+          error( "Error: Can't find emacs load file for Singular mode. \n Expected it at %s\n Specify with --emacs_load option,\n or set ESINGULAR_EMACS_LOAD environment variable,\n or put file '.emacs-singular' in your home directory.\n",
+                  feResourceDefault("EmacsLoad"));
+          mainUsage();
+          exit(1);
+        }
+      }
+    }
+  }
+
+  syscall = (char*) omAlloc(strlen(emacs) +
+                           strlen(singular) +
+                           strlen(emacs_dir) +
+                           strlen(emacs_load) +
+                           length + 300);
+  const char* prefix = "--";
+  if (strstr(emacs, "xemacs") || strstr(emacs, "Xemacs") || strstr(emacs, "XEMACS"))
+    prefix = "-";
+  getcwd(cwd, MAXPATHLEN);
+  // append / at the end of cwd
+  if (cwd[strlen(cwd)-1] != '/') strcat(cwd, "/");
+
+  // Note: option -no-init-file should be equivalent to -q. Anyhow,
+  // xemacs-20.4 sometimes crashed on startup when using -q. Don�t know why.
+  sprintf(syscall, "%s %sno-init-file %seval '(progn (setq singular-emacs-home-directory \"%s\") (load-file \"%s\") (singular-other \"%s\" \"%s\" (list ",
+          emacs, prefix, prefix, emacs_dir, emacs_load,
+          singular, cwd);
+
+
+  for (i=1; i<argc; i++)
+  {
+    if (argv[i] != NULL)
+    {
+      strcat(syscall, "\"");
+      strcat(syscall, argv[i]);
+      strcat(syscall, "\" ");
+    }
+  }
+  strcat(syscall, ") \"singular\"))'");
+#endif
+
+  if (no_emacs_call)
+  {
+    printf("%s\n", syscall);
+  }
+  else
+  {
+    if (system(syscall) != 0)
+    {
+      error( "Error: Execution of\n%s\n", syscall);
+      mainUsage();
+      exit(1);
+    }
+  }
+}
+
+
diff --git a/Singular/extra.cc b/Singular/extra.cc
new file mode 100755
index 0000000..70f3afc
--- /dev/null
+++ b/Singular/extra.cc
@@ -0,0 +1,3721 @@
+/*****************************************
+*  Computer Algebra System SINGULAR      *
+*****************************************/
+/*
+* ABSTRACT: general interface to internals of Singular ("system" command)
+* jjSYSTEM: official commands, must be documented in the manual,
+*           #defines must be local to each command
+* jjEXTENDED_SYSTEM: tests, temporary comands etc.
+*/
+
+#define HAVE_WALK 1
+
+#include <kernel/mod2.h>
+#include <misc/auxiliary.h>
+#include <misc/sirandom.h>
+
+#include <factory/factory.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <signal.h>
+
+#ifdef TIME_WITH_SYS_TIME
+# include <time.h>
+# ifdef HAVE_SYS_TIME_H
+#   include <sys/time.h>
+# endif
+#else
+# ifdef HAVE_SYS_TIME_H
+#   include <sys/time.h>
+# else
+#   include <time.h>
+# endif
+#endif
+#ifdef HAVE_SYS_TIMES_H
+#include <sys/times.h>
+#endif
+
+#include <unistd.h>
+
+#include <misc/options.h>
+
+// #include <coeffs/ffields.h>
+#include <coeffs/coeffs.h>
+#include <coeffs/mpr_complex.h>
+#include "coeffs/AE.h"
+// #include "coeffs/OPAE.h"
+#include "coeffs/AEp.h"
+// #include "coeffs/OPAEp.h"
+#include "coeffs/AEQ.h"
+// #include "coeffs/OPAEQ.h"
+
+
+#include <resources/feResource.h>
+#include <polys/monomials/ring.h>
+#include <kernel/polys.h>
+
+#include <polys/monomials/maps.h>
+#include <polys/matpol.h>
+
+// #include <kernel/longalg.h>
+#include <polys/prCopy.h>
+#include <polys/weight.h>
+
+
+#include <kernel/fast_mult.h>
+#include <kernel/digitech.h>
+#include <kernel/combinatorics/stairc.h>
+#include <kernel/ideals.h>
+#include <kernel/GBEngine/kstd1.h>
+#include <kernel/GBEngine/syz.h>
+#include <kernel/GBEngine/kutil.h>
+
+#include <kernel/GBEngine/shiftgb.h>
+#include <kernel/linear_algebra/linearAlgebra.h>
+
+#include <kernel/combinatorics/hutil.h>
+
+// for tests of t-rep-GB
+#include <kernel/GBEngine/tgb.h>
+
+#include <kernel/linear_algebra/minpoly.h>
+
+#include <numeric/mpr_base.h>
+
+#include "tok.h"
+#include "ipid.h"
+#include "lists.h"
+#include "cntrlc.h"
+#include "ipshell.h"
+#include "sdb.h"
+#include "feOpt.h"
+#include "fehelp.h"
+#include "distrib.h"
+
+#include "misc_ip.h"
+
+#include "attrib.h"
+
+#include "links/silink.h"
+#include "walk.h"
+#include <Singular/newstruct.h>
+#include <Singular/blackbox.h>
+#include <Singular/pyobject_setup.h>
+
+
+#ifdef HAVE_RINGS
+#include <kernel/GBEngine/ringgb.h>
+#endif
+
+#ifdef HAVE_F5
+#include <kernel/GBEngine/f5gb.h>
+#endif
+
+#ifdef HAVE_WALK
+#include "walk.h"
+#endif
+
+#ifdef HAVE_SPECTRUM
+#include <kernel/spectrum/spectrum.h>
+#endif
+
+#ifdef HAVE_PLURAL
+#include <polys/nc/nc.h>
+#include <polys/nc/ncSAMult.h> // for CMultiplier etc classes
+#include <polys/nc/sca.h>
+#include <kernel/GBEngine/nc.h>
+#include "ipconv.h"
+#ifdef HAVE_RATGRING
+#include <kernel/GBEngine/ratgring.h>
+#endif
+#endif
+
+#ifdef __CYGWIN__ /* only for the DLLTest */
+/* #include "WinDllTest.h" */
+#ifdef HAVE_DL
+#include <polys/mod_raw.h>
+#endif
+#endif
+
+// Define to enable many more system commands
+//#undef MAKE_DISTRIBUTION
+#ifndef MAKE_DISTRIBUTION
+#define HAVE_EXTENDED_SYSTEM 1
+#endif
+
+#include <polys/flintconv.h>
+#include <polys/clapconv.h>
+#include <kernel/GBEngine/kstdfac.h>
+
+#include <polys/clapsing.h>
+
+#ifdef HAVE_EIGENVAL
+#include "eigenval_ip.h"
+#endif
+
+#ifdef HAVE_GMS
+#include "gms.h"
+#endif
+
+#ifdef HAVE_SIMPLEIPC
+#include "Singular/links/simpleipc.h"
+#endif
+
+#ifdef HAVE_PCV
+#include "pcv.h"
+#endif
+
+
+#ifdef __CYGWIN__
+//#include <Python.h>
+//#include <python_wrapper.h>
+#endif
+
+#ifndef MAKE_DISTRIBUTION
+static BOOLEAN jjEXTENDED_SYSTEM(leftv res, leftv h);
+#endif
+
+#ifdef __CYGWIN__  /* PySingular initialized? */
+static int PyInitialized = 0;
+#endif
+
+/* expects a SINGULAR square matrix with number entries
+   where currRing is expected to be over some field F_p;
+   returns a long** matrix with the "same", i.e.,
+   appropriately mapped entries;
+   leaves singularMatrix unmodified */
+unsigned long** singularMatrixToLongMatrix(matrix singularMatrix)
+{
+  int n = singularMatrix->rows();
+  assume(n == singularMatrix->cols());
+  unsigned long **longMatrix = 0;
+  longMatrix = new unsigned long *[n] ;
+  for (int i = 0 ; i < n; i++)
+    longMatrix[i] = new unsigned long [n];
+  number entry;
+  for (int r = 0; r < n; r++)
+    for (int c = 0; c < n; c++)
+    {
+      poly p=MATELEM(singularMatrix, r + 1, c + 1);
+      int entryAsInt;
+      if (p!=NULL)
+      {
+        entry = p_GetCoeff(p, currRing);
+        entryAsInt = n_Int(entry, currRing->cf);
+        if (entryAsInt < 0) entryAsInt += n_GetChar(currRing->cf);
+      }
+      else
+        entryAsInt=0;
+      longMatrix[r][c] = (unsigned long)entryAsInt;
+    }
+  return longMatrix;
+}
+
+/* expects an array of unsigned longs with valid indices 0..degree;
+   returns the following poly, where x denotes the first ring variable
+   of currRing, and d = degree:
+      polyCoeffs[d] * x^d + polyCoeffs[d-1] * x^(d-1) + ... + polyCoeffs[0]
+   leaves polyCoeffs unmodified */
+poly longCoeffsToSingularPoly(unsigned long *polyCoeffs, const int degree)
+{
+  poly result = NULL;
+  for (int i = 0; i <= degree; i++)
+  {
+    if ((int)polyCoeffs[i] != 0)
+    {
+      poly term = p_ISet((int)polyCoeffs[i], currRing);
+      if (i > 0)
+      {
+        p_SetExp(term, 1, i, currRing);
+        p_Setm(term, currRing);
+      }
+      result = p_Add_q(result, term, currRing);
+    }
+  }
+  return result;
+}
+
+//void emStart();
+/*2
+*  the "system" command
+*/
+BOOLEAN jjSYSTEM(leftv res, leftv args)
+{
+  if(args->Typ() == STRING_CMD)
+  {
+    const char *sys_cmd=(char *)(args->Data());
+    leftv h=args->next;
+// ONLY documented system calls go here
+// Undocumented system calls go down into jjEXTENDED_SYSTEM (#ifdef HAVE_EXTENDED_SYSTEM)
+/*==================== nblocks ==================================*/
+    if (strcmp(sys_cmd, "nblocks") == 0)
+    {
+      ring r;
+      if (h == NULL)
+      {
+        if (currRingHdl != NULL)
+        {
+          r = IDRING(currRingHdl);
+        }
+        else
+        {
+          WerrorS("no ring active");
+          return TRUE;
+        }
+      }
+      else
+      {
+        if (h->Typ() != RING_CMD)
+        {
+          WerrorS("ring expected");
+          return TRUE;
+        }
+        r = (ring) h->Data();
+      }
+      res->rtyp = INT_CMD;
+      res->data = (void*) (long)(rBlocks(r) - 1);
+      return FALSE;
+    }
+/*==================== version ==================================*/
+    if(strcmp(sys_cmd,"version")==0)
+    {
+      res->rtyp=INT_CMD;
+      res->data=(void *)SINGULAR_VERSION;
+      return FALSE;
+    }
+    else
+/*==================== cpu ==================================*/
+    if(strcmp(sys_cmd,"cpu")==0)
+    {
+      long cpu=1; //feOptValue(FE_OPT_CPUS);
+      #ifdef _SC_NPROCESSORS_ONLN
+      cpu=sysconf(_SC_NPROCESSORS_ONLN);
+      #elif defined(_SC_NPROCESSORS_CONF)
+      cpu=sysconf(_SC_NPROCESSORS_CONF);
+      #endif
+      res->data=(void *)cpu;
+      res->rtyp=INT_CMD;
+      return FALSE;
+    }
+    else
+
+/*==================== sh ==================================*/
+    if(strcmp(sys_cmd,"sh")==0)
+    {
+      if (feOptValue(FE_OPT_NO_SHELL))
+      {
+        WerrorS("shell execution is disallowed in restricted mode");
+        return TRUE;
+      }
+      res->rtyp=INT_CMD;
+      if (h==NULL) res->data = (void *)(long) system("sh");
+      else if (h->Typ()==STRING_CMD)
+        res->data = (void*)(long) system((char*)(h->Data()));
+      else
+        WerrorS("string expected");
+      return FALSE;
+    }
+    else
+    #if 0
+    if(strcmp(sys_cmd,"power1")==0)
+    {
+      res->rtyp=POLY_CMD;
+      poly f=(poly)h->CopyD();
+      poly g=pPower(f,2000);
+      res->data=(void *)g;
+      return FALSE;
+    }
+    else
+    if(strcmp(sys_cmd,"power2")==0)
+    {
+      res->rtyp=POLY_CMD;
+      poly f=(poly)h->Data();
+      poly g=pOne();
+      for(int i=0;i<2000;i++)
+        g=pMult(g,pCopy(f));
+      res->data=(void *)g;
+      return FALSE;
+    }
+    if(strcmp(sys_cmd,"power3")==0)
+    {
+      res->rtyp=POLY_CMD;
+      poly f=(poly)h->Data();
+      poly p2=pMult(pCopy(f),pCopy(f));
+      poly p4=pMult(pCopy(p2),pCopy(p2));
+      poly p8=pMult(pCopy(p4),pCopy(p4));
+      poly p16=pMult(pCopy(p8),pCopy(p8));
+      poly p32=pMult(pCopy(p16),pCopy(p16));
+      poly p64=pMult(pCopy(p32),pCopy(p32));
+      poly p128=pMult(pCopy(p64),pCopy(p64));
+      poly p256=pMult(pCopy(p128),pCopy(p128));
+      poly p512=pMult(pCopy(p256),pCopy(p256));
+      poly p1024=pMult(pCopy(p512),pCopy(p512));
+      poly p1536=pMult(p1024,p512);
+      poly p1792=pMult(p1536,p256);
+      poly p1920=pMult(p1792,p128);
+      poly p1984=pMult(p1920,p64);
+      poly p2000=pMult(p1984,p16);
+      res->data=(void *)p2000;
+      pDelete(&p2);
+      pDelete(&p4);
+      pDelete(&p8);
+      //pDelete(&p16);
+      pDelete(&p32);
+      //pDelete(&p64);
+      //pDelete(&p128);
+      //pDelete(&p256);
+      //pDelete(&p512);
+      //pDelete(&p1024);
+      //pDelete(&p1536);
+      //pDelete(&p1792);
+      //pDelete(&p1920);
+      //pDelete(&p1984);
+      return FALSE;
+    }
+    else
+    #endif
+/*==================== uname ==================================*/
+    if(strcmp(sys_cmd,"uname")==0)
+    {
+      res->rtyp=STRING_CMD;
+      res->data = omStrDup(S_UNAME);
+      return FALSE;
+    }
+    else
+/*==================== with ==================================*/
+    if(strcmp(sys_cmd,"with")==0)
+    {
+      if (h==NULL)
+      {
+        res->rtyp=STRING_CMD;
+        res->data=(void *)versionString();
+        return FALSE;
+      }
+      else if (h->Typ()==STRING_CMD)
+      {
+        #define TEST_FOR(A) if(strcmp(s,A)==0) res->data=(void *)1; else
+        char *s=(char *)h->Data();
+        res->rtyp=INT_CMD;
+        #ifdef HAVE_DBM
+          TEST_FOR("DBM")
+        #endif
+        #ifdef HAVE_DLD
+          TEST_FOR("DLD")
+        #endif
+          //TEST_FOR("factory")
+          //TEST_FOR("libfac")
+        #ifdef HAVE_READLINE
+          TEST_FOR("readline")
+        #endif
+        #ifdef TEST_MAC_ORDER
+          TEST_FOR("MAC_ORDER")
+        #endif
+        // unconditional since 3-1-0-6
+          TEST_FOR("Namespaces")
+        #ifdef HAVE_DYNAMIC_LOADING
+          TEST_FOR("DynamicLoading")
+        #endif
+        #ifdef HAVE_EIGENVAL
+          TEST_FOR("eigenval")
+        #endif
+        #ifdef HAVE_GMS
+          TEST_FOR("gms")
+        #endif
+        #ifdef OM_NDEBUG
+          TEST_FOR("om_ndebug")
+        #endif
+        #ifdef SING_NDEBUG
+          TEST_FOR("ndebug")
+        #endif
+          {};
+          return FALSE;
+        #undef TEST_FOR
+      }
+      return TRUE;
+    }
+    else
+  /*==================== browsers ==================================*/
+    if (strcmp(sys_cmd,"browsers")==0)
+    {
+      res->rtyp = STRING_CMD;
+      StringSetS("");
+      feStringAppendBrowsers(0);
+      res->data = StringEndS();
+      return FALSE;
+    }
+    else
+  /*==================== pid ==================================*/
+    if (strcmp(sys_cmd,"pid")==0)
+    {
+      res->rtyp=INT_CMD;
+      res->data=(void *)(long) getpid();
+      return FALSE;
+    }
+    else
+  /*==================== getenv ==================================*/
+    if (strcmp(sys_cmd,"getenv")==0)
+    {
+      if ((h!=NULL) && (h->Typ()==STRING_CMD))
+      {
+        res->rtyp=STRING_CMD;
+        const char *r=getenv((char *)h->Data());
+        if (r==NULL) r="";
+        res->data=(void *)omStrDup(r);
+        return FALSE;
+      }
+      else
+      {
+        WerrorS("string expected");
+        return TRUE;
+      }
+    }
+    else
+  /*==================== setenv ==================================*/
+    if (strcmp(sys_cmd,"setenv")==0)
+    {
+  #ifdef HAVE_SETENV
+      const short t[]={2,STRING_CMD,STRING_CMD};
+      if (iiCheckTypes(h,t,1))
+      {
+        res->rtyp=STRING_CMD;
+        setenv((char *)h->Data(), (char *)h->next->Data(), 1);
+        res->data=(void *)omStrDup((char *)h->next->Data());
+        feReInitResources();
+        return FALSE;
+      }
+      else
+      {
+        return TRUE;
+      }
+  #else
+      WerrorS("setenv not supported on this platform");
+      return TRUE;
+  #endif
+    }
+    else
+  /*==================== Singular ==================================*/
+    if (strcmp(sys_cmd, "Singular") == 0)
+    {
+      res->rtyp=STRING_CMD;
+      const char *r=feResource("Singular");
+      if (r == NULL) r="";
+      res->data = (void*) omStrDup( r );
+      return FALSE;
+    }
+    else
+    if (strcmp(sys_cmd, "SingularLib") == 0)
+    {
+      res->rtyp=STRING_CMD;
+      const char *r=feResource("SearchPath");
+      if (r == NULL) r="";
+      res->data = (void*) omStrDup( r );
+      return FALSE;
+    }
+    else
+  /*==================== options ==================================*/
+    if (strstr(sys_cmd, "--") == sys_cmd)
+    {
+      if (strcmp(sys_cmd, "--") == 0)
+      {
+        fePrintOptValues();
+        return FALSE;
+      }
+      feOptIndex opt = feGetOptIndex(&sys_cmd[2]);
+      if (opt == FE_OPT_UNDEF)
+      {
+        Werror("Unknown option %s", sys_cmd);
+        WerrorS("Use 'system(\"--\");' for listing of available options");
+        return TRUE;
+      }
+      // for Untyped Options (help version),
+      // setting it just triggers action
+      if (feOptSpec[opt].type == feOptUntyped)
+      {
+        feSetOptValue(opt,0);
+        return FALSE;
+      }
+      if (h == NULL)
+      {
+        if (feOptSpec[opt].type == feOptString)
+        {
+          res->rtyp = STRING_CMD;
+          const char *r=(const char*)feOptSpec[opt].value;
+          if (r == NULL) r="";
+          res->data = omStrDup(r);
+        }
+        else
+        {
+          res->rtyp = INT_CMD;
+          res->data = feOptSpec[opt].value;
+        }
+        return FALSE;
+      }
+      if (h->Typ() != STRING_CMD &&
+          h->Typ() != INT_CMD)
+      {
+        WerrorS("Need string or int argument to set option value");
+        return TRUE;
+      }
+      const char* errormsg;
+      if (h->Typ() == INT_CMD)
+      {
+        if (feOptSpec[opt].type == feOptString)
+        {
+          Werror("Need string argument to set value of option %s", sys_cmd);
+          return TRUE;
+        }
+        errormsg = feSetOptValue(opt, (int)((long) h->Data()));
+        if (errormsg != NULL)
+          Werror("Option '--%s=%d' %s", sys_cmd, (int) ((long)h->Data()), errormsg);
+      }
+      else
+      {
+        errormsg = feSetOptValue(opt, (char*) h->Data());
+        if (errormsg != NULL)
+          Werror("Option '--%s=%s' %s", sys_cmd, (char*) h->Data(), errormsg);
+      }
+      if (errormsg != NULL) return TRUE;
+      return FALSE;
+    }
+    else
+  /*==================== HC ==================================*/
+    if (strcmp(sys_cmd,"HC")==0)
+    {
+      res->rtyp=INT_CMD;
+      res->data=(void *)(long) HCord;
+      return FALSE;
+    }
+    else
+  /*==================== random ==================================*/
+    if(strcmp(sys_cmd,"random")==0)
+    {
+      const short t[]={1,INT_CMD};
+      if (h!=NULL)
+      {
+        if (iiCheckTypes(h,t,1))
+        {
+          siRandomStart=(int)((long)h->Data());
+          siSeed=siRandomStart;
+          factoryseed(siRandomStart);
+          return FALSE;
+        }
+        else
+        {
+          return TRUE;
+        }
+      }
+      res->rtyp=INT_CMD;
+      res->data=(void*)(long) siSeed;
+      return FALSE;
+    }
+    else
+  /*==================== complexNearZero ======================*/
+    if(strcmp(sys_cmd,"complexNearZero")==0)
+    {
+      const short t[]={2,NUMBER_CMD,INT_CMD};
+      if (iiCheckTypes(h,t,1))
+      {
+        if ( !rField_is_long_C(currRing) )
+        {
+          WerrorS( "unsupported ground field!");
+          return TRUE;
+        }
+        else
+        {
+          res->rtyp=INT_CMD;
+          res->data=(void*)complexNearZero((gmp_complex*)h->Data(),
+                             (int)((long)(h->next->Data())));
+          return FALSE;
+        }
+      }
+      else
+      {
+        return TRUE;
+      }
+    }
+    else
+  /*==================== getPrecDigits ======================*/
+    if(strcmp(sys_cmd,"getPrecDigits")==0)
+    {
+      if ( (currRing==NULL)
+      ||  (!rField_is_long_C(currRing) && !rField_is_long_R(currRing)))
+      {
+        WerrorS( "unsupported ground field!");
+        return TRUE;
+      }
+      res->rtyp=INT_CMD;
+      res->data=(void*)(long)gmp_output_digits;
+      //if (gmp_output_digits!=getGMPFloatDigits())
+      //{ Print("%d, %d\n",getGMPFloatDigits(),gmp_output_digits);}
+      return FALSE;
+    }
+    else
+  /*==================== lduDecomp ======================*/
+    if(strcmp(sys_cmd, "lduDecomp")==0)
+    {
+      const short t[]={1,MATRIX_CMD};
+      if (iiCheckTypes(h,t,1))
+      {
+        matrix aMat = (matrix)h->Data();
+        matrix pMat; matrix lMat; matrix dMat; matrix uMat;
+        poly l; poly u; poly prodLU;
+        lduDecomp(aMat, pMat, lMat, dMat, uMat, l, u, prodLU);
+        lists L = (lists)omAllocBin(slists_bin);
+        L->Init(7);
+        L->m[0].rtyp = MATRIX_CMD; L->m[0].data=(void*)pMat;
+        L->m[1].rtyp = MATRIX_CMD; L->m[1].data=(void*)lMat;
+        L->m[2].rtyp = MATRIX_CMD; L->m[2].data=(void*)dMat;
+        L->m[3].rtyp = MATRIX_CMD; L->m[3].data=(void*)uMat;
+        L->m[4].rtyp = POLY_CMD; L->m[4].data=(void*)l;
+        L->m[5].rtyp = POLY_CMD; L->m[5].data=(void*)u;
+        L->m[6].rtyp = POLY_CMD; L->m[6].data=(void*)prodLU;
+        res->rtyp = LIST_CMD;
+        res->data = (char *)L;
+        return FALSE;
+      }
+      else
+      {
+        return TRUE;
+      }
+    }
+    else
+  /*==================== lduSolve ======================*/
+    if(strcmp(sys_cmd, "lduSolve")==0)
+    {
+      /* for solving a linear equation system A * x = b, via the
+           given LDU-decomposition of the matrix A;
+           There is one valid parametrisation:
+           1) exactly eight arguments P, L, D, U, l, u, lTimesU, b;
+              P, L, D, and U realise the LDU-decomposition of A, that is,
+              P * A = L * D^(-1) * U, and P, L, D, and U satisfy the
+              properties decribed in method 'luSolveViaLDUDecomp' in
+              linearAlgebra.h; see there;
+              l, u, and lTimesU are as described in the same location;
+              b is the right-hand side vector of the linear equation system;
+           The method will return a list of either 1 entry or three entries:
+           1) [0] if there is no solution to the system;
+           2) [1, x, H] if there is at least one solution;
+              x is any solution of the given linear system,
+              H is the matrix with column vectors spanning the homogeneous
+              solution space.
+           The method produces an error if matrix and vector sizes do not
+           fit. */
+      const short t[]={7,MATRIX_CMD,MATRIX_CMD,MATRIX_CMD,MATRIX_CMD,POLY_CMD,POLY_CMD,MATRIX_CMD};
+      if (!iiCheckTypes(h,t,1))
+      {
+        return TRUE;
+      }
+      if (rField_is_Ring(currRing))
+      {
+        WerrorS("field required");
+	return TRUE;
+      }
+      matrix pMat  = (matrix)h->Data();
+      matrix lMat  = (matrix)h->next->Data();
+      matrix dMat  = (matrix)h->next->next->Data();
+      matrix uMat  = (matrix)h->next->next->next->Data();
+      poly l       = (poly)  h->next->next->next->next->Data();
+      poly u       = (poly)  h->next->next->next->next->next->Data();
+      poly lTimesU = (poly)  h->next->next->next->next->next->next->Data();
+      matrix bVec  = (matrix)h->next->next->next->next->next->next->next->Data();
+      matrix xVec; int solvable; matrix homogSolSpace;
+      if (pMat->rows() != pMat->cols())
+      {
+        Werror("first matrix (%d x %d) is not quadratic",
+                 pMat->rows(), pMat->cols());
+        return TRUE;
+      }
+      if (lMat->rows() != lMat->cols())
+      {
+        Werror("second matrix (%d x %d) is not quadratic",
+                 lMat->rows(), lMat->cols());
+        return TRUE;
+      }
+      if (dMat->rows() != dMat->cols())
+      {
+        Werror("third matrix (%d x %d) is not quadratic",
+                 dMat->rows(), dMat->cols());
+        return TRUE;
+      }
+      if (dMat->cols() != uMat->rows())
+      {
+        Werror("third matrix (%d x %d) and fourth matrix (%d x %d) %s",
+                 dMat->rows(), dMat->cols(), uMat->rows(), uMat->cols(),
+                 "do not t");
+        return TRUE;
+      }
+      if (uMat->rows() != bVec->rows())
+      {
+        Werror("fourth matrix (%d x %d) and vector (%d x 1) do not fit",
+                 uMat->rows(), uMat->cols(), bVec->rows());
+        return TRUE;
+      }
+      solvable = luSolveViaLDUDecomp(pMat, lMat, dMat, uMat, l, u, lTimesU,
+                                       bVec, xVec, homogSolSpace);
+
+      /* build the return structure; a list with either one or
+           three entries */
+      lists ll = (lists)omAllocBin(slists_bin);
+      if (solvable)
+      {
+        ll->Init(3);
+        ll->m[0].rtyp=INT_CMD;    ll->m[0].data=(void *)(long)solvable;
+        ll->m[1].rtyp=MATRIX_CMD; ll->m[1].data=(void *)xVec;
+        ll->m[2].rtyp=MATRIX_CMD; ll->m[2].data=(void *)homogSolSpace;
+      }
+      else
+      {
+        ll->Init(1);
+        ll->m[0].rtyp=INT_CMD;    ll->m[0].data=(void *)(long)solvable;
+      }
+      res->rtyp = LIST_CMD;
+      res->data=(char*)ll;
+      return FALSE;
+    }
+    else
+  /*==== countedref: reference and shared ====*/
+    if (strcmp(sys_cmd, "shared") == 0)
+    {
+      #ifndef SI_COUNTEDREF_AUTOLOAD
+      void countedref_shared_load();
+      countedref_shared_load();
+      #endif
+      res->rtyp = NONE;
+      return FALSE;
+    }
+    else if (strcmp(sys_cmd, "reference") == 0)
+    {
+      #ifndef SI_COUNTEDREF_AUTOLOAD
+      void countedref_reference_load();
+      countedref_reference_load();
+      #endif
+      res->rtyp = NONE;
+      return FALSE;
+    }
+    else
+/*==================== semaphore =================*/
+#ifdef HAVE_SIMPLEIPC
+    if (strcmp(sys_cmd,"semaphore")==0)
+    {
+      if((h!=NULL) && (h->Typ()==STRING_CMD) && (h->next!=NULL) && (h->next->Typ()==INT_CMD))
+      {
+        int v=1;
+        if ((h->next->next!=NULL)&& (h->next->next->Typ()==INT_CMD))
+          v=(int)(long)h->next->next->Data();
+        res->data=(char *)(long)simpleipc_cmd((char *)h->Data(),(int)(long)h->next->Data(),v);
+        res->rtyp=INT_CMD;
+        return FALSE;
+      }
+      else
+      {
+        WerrorS("Usage: system(\"semaphore\",<cmd>,int)");
+        return TRUE;
+      }
+    }
+    else
+#endif
+/*==================== reserved port =================*/
+    if (strcmp(sys_cmd,"reserve")==0)
+    {
+      int ssiReservePort(int clients);
+      const short t[]={1,INT_CMD};
+      if (iiCheckTypes(h,t,1))
+      {
+        res->rtyp=INT_CMD;
+        int p=ssiReservePort((int)(long)h->Data());
+        res->data=(void*)(long)p;
+        return (p==0);
+      }
+      return TRUE;
+    }
+    else
+/*==================== reserved link =================*/
+    if (strcmp(sys_cmd,"reservedLink")==0)
+    {
+      extern si_link ssiCommandLink();
+      res->rtyp=LINK_CMD;
+      si_link p=ssiCommandLink();
+      res->data=(void*)p;
+      return (p==NULL);
+    }
+    else
+/*==================== install newstruct =================*/
+    if (strcmp(sys_cmd,"install")==0)
+    {
+      const short t[]={4,STRING_CMD,STRING_CMD,PROC_CMD,INT_CMD};
+      if (iiCheckTypes(h,t,1))
+      {
+        return newstruct_set_proc((char*)h->Data(),(char*)h->next->Data(),
+                                (int)(long)h->next->next->next->Data(),
+                                (procinfov)h->next->next->Data());
+      }
+      return TRUE;
+    }
+    else
+/*==================== newstruct =================*/
+    if (strcmp(sys_cmd,"newstruct")==0)
+    {
+      const short t[]={1,STRING_CMD};
+      if (iiCheckTypes(h,t,1))
+      {
+        int id=0;
+        blackboxIsCmd((char*)h->Data(),id);
+        if (id>0)
+        {
+          blackbox *bb=getBlackboxStuff(id);
+          if (BB_LIKE_LIST(bb))
+          {
+            newstruct_desc desc=(newstruct_desc)bb->data;
+            newstructShow(desc);
+            return FALSE;
+          }
+        }
+      }
+      return TRUE;
+    }
+    else
+/*==================== blackbox =================*/
+    if (strcmp(sys_cmd,"blackbox")==0)
+    {
+      printBlackboxTypes();
+      return FALSE;
+    }
+    else
+  /*================= absBiFact ======================*/
+    #ifdef HAVE_NTL
+    if (strcmp(sys_cmd, "absFact") == 0)
+    {
+      const short t[]={1,POLY_CMD};
+      if (iiCheckTypes(h,t,1)
+      && (currRing!=NULL)
+      && (getCoeffType(currRing->cf)==n_transExt))
+      {
+        res->rtyp=LIST_CMD;
+        intvec *v=NULL;
+        ideal mipos= NULL;
+        int n= 0;
+        ideal f=singclap_absFactorize((poly)(h->Data()), mipos, &v, n, currRing);
+        if (f==NULL) return TRUE;
+        ivTest(v);
+        lists l=(lists)omAllocBin(slists_bin);
+        l->Init(4);
+        l->m[0].rtyp=IDEAL_CMD;
+        l->m[0].data=(void *)f;
+        l->m[1].rtyp=INTVEC_CMD;
+        l->m[1].data=(void *)v;
+        l->m[2].rtyp=IDEAL_CMD;
+        l->m[2].data=(void*) mipos;
+        l->m[3].rtyp=INT_CMD;
+        l->m[3].data=(void*) (long) n;
+        res->data=(void *)l;
+        return FALSE;
+      }
+      else return TRUE;
+    }
+    else
+    #endif
+  /* =================== LLL via NTL ==============================*/
+  #ifdef HAVE_NTL
+    if (strcmp(sys_cmd, "LLL") == 0)
+    {
+      if (h!=NULL)
+      {
+        res->rtyp=h->Typ();
+        if (h->Typ()==MATRIX_CMD)
+        {
+          res->data=(char *)singntl_LLL((matrix)h->Data(), currRing);
+          return FALSE;
+        }
+        else if (h->Typ()==INTMAT_CMD)
+        {
+          res->data=(char *)singntl_LLL((intvec*)h->Data());
+          return FALSE;
+        }
+        else return TRUE;
+      }
+      else return TRUE;
+    }
+    else
+  #endif
+  /* =================== LLL via Flint ==============================*/
+  #ifdef HAVE_FLINT
+  #ifdef FLINT_VER_2_4_5
+    if (strcmp(sys_cmd, "LLL_Flint") == 0)
+    {
+      if (h!=NULL)
+      {
+        if(h->next == NULL)
+        {
+            res->rtyp=h->Typ();
+            if (h->Typ()==BIGINTMAT_CMD)
+            {
+              res->data=(char *)singflint_LLL((bigintmat*)h->Data(), NULL);
+              return FALSE;
+            }
+            else if (h->Typ()==INTMAT_CMD)
+            {
+              res->data=(char *)singflint_LLL((intvec*)h->Data(), NULL);
+              return FALSE;
+            }
+            else return TRUE;
+        }
+        if(h->next->Typ()!= INT_CMD)
+        {
+            WerrorS("matrix,int or bigint,int expected");
+            return TRUE;
+        }
+        if(h->next->Typ()== INT_CMD)
+        {
+            if(((int)((long)(h->next->Data())) != 0) && (int)((long)(h->next->Data()) != 1))
+            {
+                WerrorS("int is different from 0, 1");
+                return TRUE;
+            }
+            res->rtyp=h->Typ();
+            if((long)(h->next->Data()) == 0)
+            {
+                if (h->Typ()==BIGINTMAT_CMD)
+                {
+                  res->data=(char *)singflint_LLL((bigintmat*)h->Data(), NULL);
+                  return FALSE;
+                }
+                else if (h->Typ()==INTMAT_CMD)
+                {
+                  res->data=(char *)singflint_LLL((intvec*)h->Data(), NULL);
+                  return FALSE;
+                }
+                else return TRUE;
+            }
+            // This will give also the transformation matrix U s.t. res = U * m
+            if((long)(h->next->Data()) == 1)
+            {
+                if (h->Typ()==BIGINTMAT_CMD)
+                {
+                  bigintmat* m = (bigintmat*)h->Data();
+                  bigintmat* T = new bigintmat(m->rows(),m->rows(),m->basecoeffs());
+                  for(int i = 1; i<=m->rows(); i++)
+                  {
+                    n_Delete(&(BIMATELEM(*T,i,i)),T->basecoeffs());
+                    BIMATELEM(*T,i,i)=n_Init(1, T->basecoeffs());
+                  }
+                  m = singflint_LLL(m,T);
+                  lists L = (lists)omAllocBin(slists_bin);
+                  L->Init(2);
+                  L->m[0].rtyp = BIGINTMAT_CMD;  L->m[0].data = (void*)m;
+                  L->m[1].rtyp = BIGINTMAT_CMD;  L->m[1].data = (void*)T;
+                  res->data=L;
+                  res->rtyp=LIST_CMD;
+                  return FALSE;
+                }
+                else if (h->Typ()==INTMAT_CMD)
+                {
+                  intvec* m = (intvec*)h->Data();
+                  intvec* T = new intvec(m->rows(),m->rows(),(int)0);
+                  for(int i = 1; i<=m->rows(); i++)
+                    IMATELEM(*T,i,i)=1;
+                  m = singflint_LLL(m,T);
+                  lists L = (lists)omAllocBin(slists_bin);
+                  L->Init(2);
+                  L->m[0].rtyp = INTMAT_CMD;  L->m[0].data = (void*)m;
+                  L->m[1].rtyp = INTMAT_CMD;  L->m[1].data = (void*)T;
+                  res->data=L;
+                  res->rtyp=LIST_CMD;
+                  return FALSE;
+                }
+                else return TRUE;
+            }
+        }
+
+      }
+      else return TRUE;
+    }
+    else
+  #endif
+  #endif
+  /*==================== shift-test for freeGB  =================*/
+  #ifdef HAVE_SHIFTBBA
+    if (strcmp(sys_cmd, "stest") == 0)
+    {
+      const short t[]={4,POLY_CMD,INT_CMD,INT_CMD,INT_CMD};
+      if (iiCheckTypes(h,t,1))
+      {
+        poly p=(poly)h->CopyD();
+        h=h->next;
+        int sh=(int)((long)(h->Data()));
+        h=h->next;
+        int uptodeg=(int)((long)(h->Data()));
+        h=h->next;
+        int lVblock=(int)((long)(h->Data()));
+        res->data = pLPshift(p,sh,uptodeg,lVblock);
+        res->rtyp = POLY_CMD;
+        return FALSE;
+      }
+      else return TRUE;
+    }
+    else
+  #endif
+  /*==================== block-test for freeGB  =================*/
+  #ifdef HAVE_SHIFTBBA
+    if (strcmp(sys_cmd, "btest") == 0)
+    {
+      const short t[]={2,POLY_CMD,INT_CMD};
+      if (iiCheckTypes(h,t,1))
+      {
+        poly p=(poly)h->CopyD();
+        h=h->next;
+        int lV=(int)((long)(h->Data()));
+        res->rtyp = INT_CMD;
+        res->data = (void*)(long)pLastVblock(p, lV);
+        return FALSE;
+      }
+      else return TRUE;
+    }
+    else
+  #endif
+  /*==================== shrink-test for freeGB  =================*/
+  #ifdef HAVE_SHIFTBBA
+    if (strcmp(sys_cmd, "shrinktest") == 0)
+    {
+      const short t[]={2,POLY_CMD,INT_CMD};
+      if (iiCheckTypes(h,t,1))
+      {
+        poly p=(poly)h->CopyD();
+        h=h->next;
+        int lV=(int)((long)(h->Data()));
+        res->rtyp = POLY_CMD;
+        //        res->data = p_mShrink(p, lV, currRing);
+        //        kStrategy strat=new skStrategy;
+        //        strat->tailRing = currRing;
+        res->data = p_Shrink(p, lV, currRing);
+        return FALSE;
+      }
+      else return TRUE;
+    }
+    else
+  #endif
+  /*==================== pcv ==================================*/
+  #ifdef HAVE_PCV
+    if(strcmp(sys_cmd,"pcvLAddL")==0)
+    {
+      return pcvLAddL(res,h);
+    }
+    else
+    if(strcmp(sys_cmd,"pcvPMulL")==0)
+    {
+      return pcvPMulL(res,h);
+    }
+    else
+    if(strcmp(sys_cmd,"pcvMinDeg")==0)
+    {
+      return pcvMinDeg(res,h);
+    }
+    else
+    if(strcmp(sys_cmd,"pcvP2CV")==0)
+    {
+      return pcvP2CV(res,h);
+    }
+    else
+    if(strcmp(sys_cmd,"pcvCV2P")==0)
+    {
+      return pcvCV2P(res,h);
+    }
+    else
+    if(strcmp(sys_cmd,"pcvDim")==0)
+    {
+      return pcvDim(res,h);
+    }
+    else
+    if(strcmp(sys_cmd,"pcvBasis")==0)
+    {
+      return pcvBasis(res,h);
+    }
+    else
+  #endif
+  /*==================== hessenberg/eigenvalues ==================================*/
+  #ifdef HAVE_EIGENVAL
+    if(strcmp(sys_cmd,"hessenberg")==0)
+    {
+      return evHessenberg(res,h);
+    }
+    else
+  #endif
+  /*==================== eigenvalues ==================================*/
+  #ifdef HAVE_EIGENVAL
+    if(strcmp(sys_cmd,"eigenvals")==0)
+    {
+      return evEigenvals(res,h);
+    }
+    else
+  #endif
+  /*==================== rowelim ==================================*/
+  #ifdef HAVE_EIGENVAL
+    if(strcmp(sys_cmd,"rowelim")==0)
+    {
+      return evRowElim(res,h);
+    }
+    else
+  #endif
+  /*==================== rowcolswap ==================================*/
+  #ifdef HAVE_EIGENVAL
+    if(strcmp(sys_cmd,"rowcolswap")==0)
+    {
+      return evSwap(res,h);
+    }
+    else
+  #endif
+  /*==================== Gauss-Manin system ==================================*/
+  #ifdef HAVE_GMS
+    if(strcmp(sys_cmd,"gmsnf")==0)
+    {
+      return gmsNF(res,h);
+    }
+    else
+  #endif
+  /*==================== contributors =============================*/
+    if(strcmp(sys_cmd,"contributors") == 0)
+    {
+      res->rtyp=STRING_CMD;
+      res->data=(void *)omStrDup(
+         "Olaf Bachmann, Michael Brickenstein, Hubert Grassmann, Kai Krueger, Victor Levandovskyy, Wolfgang Neumann, Thomas Nuessler, Wilfred Pohl, Jens Schmidt, Mathias Schulze, Thomas Siebert, Ruediger Stobbe, Moritz Wenk, Tim Wichmann");
+      return FALSE;
+    }
+    else
+  /*==================== spectrum =============================*/
+    #ifdef HAVE_SPECTRUM
+    if(strcmp(sys_cmd,"spectrum") == 0)
+    {
+      if ((h==NULL) || (h->Typ()!=POLY_CMD))
+      {
+        WerrorS("poly expected");
+        return TRUE;
+      }
+      if (h->next==NULL)
+        return spectrumProc(res,h);
+      if (h->next->Typ()!=INT_CMD)
+      {
+        WerrorS("poly,int expected");
+        return TRUE;
+      }
+      if(((long)h->next->Data())==1L)
+         return spectrumfProc(res,h);
+      return spectrumProc(res,h);
+    }
+    else
+  /*==================== semic =============================*/
+    if(strcmp(sys_cmd,"semic") == 0)
+    {
+      if ((h->next!=NULL)
+      && (h->Typ()==LIST_CMD)
+      && (h->next->Typ()==LIST_CMD))
+      {
+        if (h->next->next==NULL)
+          return semicProc(res,h,h->next);
+        else if (h->next->next->Typ()==INT_CMD)
+          return semicProc3(res,h,h->next,h->next->next);
+      }
+      return TRUE;
+    }
+    else
+  /*==================== spadd =============================*/
+    if(strcmp(sys_cmd,"spadd") == 0)
+    {
+      const short t[]={2,LIST_CMD,LIST_CMD};
+      if (iiCheckTypes(h,t,1))
+      {
+        return spaddProc(res,h,h->next);
+      }
+      return TRUE;
+    }
+    else
+  /*==================== spmul =============================*/
+    if(strcmp(sys_cmd,"spmul") == 0)
+    {
+      const short t[]={2,LIST_CMD,INT_CMD};
+      if (iiCheckTypes(h,t,1))
+      {
+        return spmulProc(res,h,h->next);
+      }
+      return TRUE;
+    }
+    else
+  #endif
+/*==================== tensorModuleMult ========================= */
+  #define HAVE_SHEAFCOH_TRICKS 1
+
+  #ifdef HAVE_SHEAFCOH_TRICKS
+    if(strcmp(sys_cmd,"tensorModuleMult")==0)
+    {
+      const short t[]={2,INT_CMD,MODUL_CMD};
+  //      WarnS("tensorModuleMult!");
+      if (iiCheckTypes(h,t,1))
+      {
+        int m = (int)( (long)h->Data() );
+        ideal M = (ideal)h->next->Data();
+        res->rtyp=MODUL_CMD;
+        res->data=(void *)id_TensorModuleMult(m, M, currRing);
+        return FALSE;
+      }
+      return TRUE;
+    }
+    else
+  #endif
+  /*==================== twostd  =================*/
+  #ifdef HAVE_PLURAL
+    if (strcmp(sys_cmd, "twostd") == 0)
+    {
+      ideal I;
+      if ((h!=NULL) && (h->Typ()==IDEAL_CMD))
+      {
+        I=(ideal)h->CopyD();
+        res->rtyp=IDEAL_CMD;
+        if (rIsPluralRing(currRing)) res->data=twostd(I);
+        else res->data=I;
+        setFlag(res,FLAG_TWOSTD);
+        setFlag(res,FLAG_STD);
+      }
+      else return TRUE;
+      return FALSE;
+    }
+    else
+  #endif
+  /*==================== lie bracket =================*/
+  #ifdef HAVE_PLURAL
+    if (strcmp(sys_cmd, "bracket") == 0)
+    {
+      const short t[]={2,POLY_CMD,POLY_CMD};
+      if (iiCheckTypes(h,t,1))
+      {
+        poly p=(poly)h->CopyD();
+        h=h->next;
+        poly q=(poly)h->Data();
+        res->rtyp=POLY_CMD;
+        if (rIsPluralRing(currRing))  res->data=nc_p_Bracket_qq(p,q, currRing);
+        return FALSE;
+      }
+      return TRUE;
+    }
+    else
+  #endif
+  /*==================== env ==================================*/
+  #ifdef HAVE_PLURAL
+    if (strcmp(sys_cmd, "env")==0)
+    {
+      if ((h!=NULL) && (h->Typ()==RING_CMD))
+      {
+        ring r = (ring)h->Data();
+        res->data = rEnvelope(r);
+        res->rtyp = RING_CMD;
+        return FALSE;
+      }
+      else
+      {
+        WerrorS("`system(\"env\",<ring>)` expected");
+        return TRUE;
+      }
+    }
+    else
+  #endif
+/* ============ opp ======================== */
+  #ifdef HAVE_PLURAL
+    if (strcmp(sys_cmd, "opp")==0)
+    {
+      if ((h!=NULL) && (h->Typ()==RING_CMD))
+      {
+        ring r=(ring)h->Data();
+        res->data=rOpposite(r);
+        res->rtyp=RING_CMD;
+        return FALSE;
+      }
+      else
+      {
+        WerrorS("`system(\"opp\",<ring>)` expected");
+        return TRUE;
+      }
+    }
+    else
+  #endif
+  /*==================== oppose ==================================*/
+  #ifdef HAVE_PLURAL
+    if (strcmp(sys_cmd, "oppose")==0)
+    {
+      if ((h!=NULL) && (h->Typ()==RING_CMD)
+      && (h->next!= NULL))
+      {
+        ring Rop = (ring)h->Data();
+        h   = h->next;
+        idhdl w;
+        if ((w=Rop->idroot->get(h->Name(),myynest))!=NULL)
+        {
+          poly p = (poly)IDDATA(w);
+          res->data = pOppose(Rop, p, currRing); // into CurrRing?
+          res->rtyp = POLY_CMD;
+          return FALSE;
+        }
+      }
+      else
+      {
+        WerrorS("`system(\"oppose\",<ring>,<poly>)` expected");
+        return TRUE;
+      }
+    }
+    else
+  #endif
+  /*==================== freeGB, twosided GB in free algebra =================*/
+  #ifdef HAVE_PLURAL
+  #ifdef HAVE_SHIFTBBA
+    if (strcmp(sys_cmd, "freegb") == 0)
+    {
+      const short t[]={3,IDEAL_CMD,INT_CMD,INT_CMD};
+      if (iiCheckTypes(h,t,1))
+      {
+        ideal I=(ideal)h->CopyD();
+        h=h->next;
+        int uptodeg=(int)((long)(h->Data()));
+        h=h->next;
+        int lVblock=(int)((long)(h->Data()));
+        res->data = freegb(I,uptodeg,lVblock);
+        if (res->data == NULL)
+        {
+          /* that is there were input errors */
+          res->data = I;
+        }
+        res->rtyp = IDEAL_CMD;
+        return FALSE;
+      }
+      else return TRUE;
+    }
+    else
+  #endif /*SHIFTBBA*/
+  #endif /*PLURAL*/
+  /*==================== walk stuff =================*/
+  /*==================== walkNextWeight =================*/
+  #ifdef HAVE_WALK
+  #ifdef OWNW
+    if (strcmp(sys_cmd, "walkNextWeight") == 0)
+    {
+      const short t[]={3,INTVEC_CMD,INTVEC_CMD,IDEAL_CMD};
+      if (!iiCheckTypes(h,t,1)) return TRUE;
+      if (((intvec*) h->Data())->length() != currRing->N ||
+          ((intvec*) h->next->Data())->length() != currRing->N)
+      {
+        Werror("system(\"walkNextWeight\" ...) intvecs not of length %d\n",
+               currRing->N);
+        return TRUE;
+      }
+      res->data = (void*) walkNextWeight(((intvec*) h->Data()),
+                                         ((intvec*) h->next->Data()),
+                                         (ideal) h->next->next->Data());
+      if (res->data == NULL || res->data == (void*) 1L)
+      {
+        res->rtyp = INT_CMD;
+      }
+      else
+      {
+        res->rtyp = INTVEC_CMD;
+      }
+      return FALSE;
+    }
+    else
+  #endif
+  #endif
+  /*==================== walkNextWeight =================*/
+  #ifdef HAVE_WALK
+  #ifdef OWNW
+    if (strcmp(sys_cmd, "walkInitials") == 0)
+    {
+      if (h == NULL || h->Typ() != IDEAL_CMD)
+      {
+        WerrorS("system(\"walkInitials\", ideal) expected");
+        return TRUE;
+      }
+      res->data = (void*) walkInitials((ideal) h->Data());
+      res->rtyp = IDEAL_CMD;
+      return FALSE;
+    }
+    else
+  #endif
+  #endif
+  /*==================== walkAddIntVec =================*/
+  #ifdef HAVE_WALK
+  #ifdef WAIV
+    if (strcmp(sys_cmd, "walkAddIntVec") == 0)
+    {
+      const short t[]={2,INTVEC_CMD,INTVEC_CMD};
+      if (!iiCheckTypes(h,t,1)) return TRUE;
+      intvec* arg1 = (intvec*) h->Data();
+      intvec* arg2 = (intvec*) h->next->Data();
+      res->data = (intvec*) walkAddIntVec(arg1, arg2);
+      res->rtyp = INTVEC_CMD;
+      return FALSE;
+    }
+    else
+  #endif
+  #endif
+  /*==================== MwalkNextWeight =================*/
+  #ifdef HAVE_WALK
+  #ifdef MwaklNextWeight
+    if (strcmp(sys_cmd, "MwalkNextWeight") == 0)
+    {
+      const short t[]={3,INTVEC_CMD,INTVEC_CMD,IDEAL_CMD};
+      if (!iiCheckTypes(h,t,1)) return TRUE;
+      if (((intvec*) h->Data())->length() != currRing->N ||
+        ((intvec*) h->next->Data())->length() != currRing->N)
+      {
+        Werror("system(\"MwalkNextWeight\" ...) intvecs not of length %d\n",
+               currRing->N);
+        return TRUE;
+      }
+      intvec* arg1 = (intvec*) h->Data();
+      intvec* arg2 = (intvec*) h->next->Data();
+      ideal arg3   =   (ideal) h->next->next->Data();
+      intvec* result = (intvec*) MwalkNextWeight(arg1, arg2, arg3);
+      res->rtyp = INTVEC_CMD;
+      res->data =  result;
+      return FALSE;
+    }
+    else
+  #endif //MWalkNextWeight
+  #endif
+  /*==================== Mivdp =================*/
+  #ifdef HAVE_WALK
+    if(strcmp(sys_cmd, "Mivdp") == 0)
+    {
+      if (h == NULL || h->Typ() != INT_CMD)
+      {
+        WerrorS("system(\"Mivdp\", int) expected");
+        return TRUE;
+      }
+      if ((int) ((long)(h->Data())) != currRing->N)
+      {
+        Werror("system(\"Mivdp\" ...) intvecs not of length %d\n",
+               currRing->N);
+        return TRUE;
+      }
+      int arg1 = (int) ((long)(h->Data()));
+      intvec* result = (intvec*) Mivdp(arg1);
+      res->rtyp = INTVEC_CMD;
+      res->data =  result;
+      return FALSE;
+    }
+    else
+  #endif
+  /*==================== Mivlp =================*/
+  #ifdef HAVE_WALK
+    if(strcmp(sys_cmd, "Mivlp") == 0)
+    {
+      if (h == NULL || h->Typ() != INT_CMD)
+      {
+        WerrorS("system(\"Mivlp\", int) expected");
+        return TRUE;
+      }
+      if ((int) ((long)(h->Data())) != currRing->N)
+      {
+        Werror("system(\"Mivlp\" ...) intvecs not of length %d\n",
+               currRing->N);
+        return TRUE;
+      }
+      int arg1 = (int) ((long)(h->Data()));
+      intvec* result = (intvec*) Mivlp(arg1);
+      res->rtyp = INTVEC_CMD;
+      res->data =  result;
+      return FALSE;
+    }
+    else
+  #endif
+  /*==================== MpDiv =================*/
+  #ifdef HAVE_WALK
+  #ifdef MpDiv
+    if(strcmp(sys_cmd, "MpDiv") == 0)
+    {
+      const short t[]={2,POLY_CMD,POLY_CMD};
+      if (!iiCheckTypes(h,t,1)) return TRUE;
+      poly arg1 = (poly) h->Data();
+      poly arg2 = (poly) h->next->Data();
+      poly result = MpDiv(arg1, arg2);
+      res->rtyp = POLY_CMD;
+      res->data = result;
+      return FALSE;
+    }
+    else
+  #endif
+  #endif
+  /*==================== MpMult =================*/
+  #ifdef HAVE_WALK
+  #ifdef MpMult
+    if(strcmp(sys_cmd, "MpMult") == 0)
+    {
+      const short t[]={2,POLY_CMD,POLY_CMD};
+      if (!iiCheckTypes(h,t,1)) return TRUE;
+      poly arg1 = (poly) h->Data();
+      poly arg2 = (poly) h->next->Data();
+      poly result = MpMult(arg1, arg2);
+      res->rtyp = POLY_CMD;
+      res->data = result;
+      return FALSE;
+    }
+    else
+  #endif
+  #endif
+  /*==================== MivSame =================*/
+  #ifdef HAVE_WALK
+    if (strcmp(sys_cmd, "MivSame") == 0)
+    {
+      const short t[]={2,INTVEC_CMD,INTVEC_CMD};
+      if (!iiCheckTypes(h,t,1)) return TRUE;
+      /*
+      if (((intvec*) h->Data())->length() != currRing->N ||
+      ((intvec*) h->next->Data())->length() != currRing->N)
+      {
+        Werror("system(\"MivSame\" ...) intvecs not of length %d\n",
+               currRing->N);
+        return TRUE;
+      }
+      */
+      intvec* arg1 = (intvec*) h->Data();
+      intvec* arg2 = (intvec*) h->next->Data();
+      /*
+      poly result = (poly) MivSame(arg1, arg2);
+      res->rtyp = POLY_CMD;
+      res->data =  (poly) result;
+      */
+      res->rtyp = INT_CMD;
+      res->data = (void*)(long) MivSame(arg1, arg2);
+      return FALSE;
+    }
+    else
+  #endif
+  /*==================== M3ivSame =================*/
+  #ifdef HAVE_WALK
+    if (strcmp(sys_cmd, "M3ivSame") == 0)
+    {
+      const short t[]={3,INTVEC_CMD,INTVEC_CMD,INTVEC_CMD};
+      if (!iiCheckTypes(h,t,1)) return TRUE;
+      /*
+      if (((intvec*) h->Data())->length() != currRing->N ||
+        ((intvec*) h->next->Data())->length() != currRing->N ||
+        ((intvec*) h->next->next->Data())->length() != currRing->N )
+      {
+        Werror("system(\"M3ivSame\" ...) intvecs not of length %d\n",
+              currRing->N);
+        return TRUE;
+      }
+      */
+      intvec* arg1 = (intvec*) h->Data();
+      intvec* arg2 = (intvec*) h->next->Data();
+      intvec* arg3 = (intvec*) h->next->next->Data();
+      /*
+      poly result = (poly) M3ivSame(arg1, arg2, arg3);
+      res->rtyp = POLY_CMD;
+      res->data =  (poly) result;
+      */
+      res->rtyp = INT_CMD;
+      res->data = (void*)(long) M3ivSame(arg1, arg2, arg3);
+      return FALSE;
+    }
+    else
+  #endif
+  /*==================== MwalkInitialForm =================*/
+  #ifdef HAVE_WALK
+    if(strcmp(sys_cmd, "MwalkInitialForm") == 0)
+    {
+      const short t[]={2,IDEAL_CMD,INTVEC_CMD};
+      if (!iiCheckTypes(h,t,1)) return TRUE;
+      if(((intvec*) h->next->Data())->length() != currRing->N)
+      {
+        Werror("system \"MwalkInitialForm\"...) intvec not of length %d\n",
+               currRing->N);
+        return TRUE;
+      }
+      ideal id      = (ideal) h->Data();
+      intvec* int_w = (intvec*) h->next->Data();
+      ideal result  = (ideal) MwalkInitialForm(id, int_w);
+      res->rtyp = IDEAL_CMD;
+      res->data = result;
+      return FALSE;
+    }
+    else
+  #endif
+  /*==================== MivMatrixOrder =================*/
+  #ifdef HAVE_WALK
+    /************** Perturbation walk **********/
+    if(strcmp(sys_cmd, "MivMatrixOrder") == 0)
+    {
+      if(h==NULL || h->Typ() != INTVEC_CMD)
+      {
+        WerrorS("system(\"MivMatrixOrder\",intvec) expected");
+        return TRUE;
+      }
+      intvec* arg1 = (intvec*) h->Data();
+      intvec* result = MivMatrixOrder(arg1);
+      res->rtyp = INTVEC_CMD;
+      res->data =  result;
+      return FALSE;
+    }
+    else
+  #endif
+  /*==================== MivMatrixOrderdp =================*/
+  #ifdef HAVE_WALK
+    if(strcmp(sys_cmd, "MivMatrixOrderdp") == 0)
+    {
+      if(h==NULL || h->Typ() != INT_CMD)
+      {
+        WerrorS("system(\"MivMatrixOrderdp\",intvec) expected");
+        return TRUE;
+      }
+      int arg1 = (int) ((long)(h->Data()));
+      intvec* result = (intvec*) MivMatrixOrderdp(arg1);
+      res->rtyp = INTVEC_CMD;
+      res->data =  result;
+      return FALSE;
+    }
+    else
+  #endif
+  /*==================== MPertVectors =================*/
+  #ifdef HAVE_WALK
+    if(strcmp(sys_cmd, "MPertVectors") == 0)
+    {
+      const short t[]={3,IDEAL_CMD,INTVEC_CMD,INT_CMD};
+      if (!iiCheckTypes(h,t,1)) return TRUE;
+      ideal arg1 = (ideal) h->Data();
+      intvec* arg2 = (intvec*) h->next->Data();
+      int arg3 = (int) ((long)(h->next->next->Data()));
+      intvec* result = (intvec*) MPertVectors(arg1, arg2, arg3);
+      res->rtyp = INTVEC_CMD;
+      res->data =  result;
+      return FALSE;
+    }
+    else
+  #endif
+  /*==================== MPertVectorslp =================*/
+  #ifdef HAVE_WALK
+    if(strcmp(sys_cmd, "MPertVectorslp") == 0)
+    {
+      const short t[]={3,IDEAL_CMD,INTVEC_CMD,INT_CMD};
+      if (!iiCheckTypes(h,t,1)) return TRUE;
+      ideal arg1 = (ideal) h->Data();
+      intvec* arg2 = (intvec*) h->next->Data();
+      int arg3 = (int) ((long)(h->next->next->Data()));
+      intvec* result = (intvec*) MPertVectorslp(arg1, arg2, arg3);
+      res->rtyp = INTVEC_CMD;
+      res->data =  result;
+      return FALSE;
+    }
+    else
+  #endif
+    /************** fractal walk **********/
+  #ifdef HAVE_WALK
+    if(strcmp(sys_cmd, "Mfpertvector") == 0)
+    {
+      const short t[]={2,IDEAL_CMD,INTVEC_CMD};
+      if (!iiCheckTypes(h,t,1)) return TRUE;
+      ideal arg1 = (ideal) h->Data();
+      intvec* arg2 = (intvec*) h->next->Data();
+      intvec* result = Mfpertvector(arg1, arg2);
+      res->rtyp = INTVEC_CMD;
+      res->data =  result;
+      return FALSE;
+    }
+    else
+  #endif
+  /*==================== MivUnit =================*/
+  #ifdef HAVE_WALK
+    if(strcmp(sys_cmd, "MivUnit") == 0)
+    {
+      const short t[]={1,INT_CMD};
+      if (!iiCheckTypes(h,t,1)) return TRUE;
+      int arg1 = (int) ((long)(h->Data()));
+      intvec* result = (intvec*) MivUnit(arg1);
+      res->rtyp = INTVEC_CMD;
+      res->data =  result;
+      return FALSE;
+    }
+    else
+  #endif
+  /*==================== MivWeightOrderlp =================*/
+  #ifdef HAVE_WALK
+    if(strcmp(sys_cmd, "MivWeightOrderlp") == 0)
+    {
+      const short t[]={1,INTVEC_CMD};
+      if (!iiCheckTypes(h,t,1)) return TRUE;
+      intvec* arg1 = (intvec*) h->Data();
+      intvec* result = MivWeightOrderlp(arg1);
+      res->rtyp = INTVEC_CMD;
+      res->data =  result;
+      return FALSE;
+    }
+    else
+  #endif
+  /*==================== MivWeightOrderdp =================*/
+  #ifdef HAVE_WALK
+    if(strcmp(sys_cmd, "MivWeightOrderdp") == 0)
+    {
+      if(h==NULL || h->Typ() != INTVEC_CMD)
+      {
+        WerrorS("system(\"MivWeightOrderdp\",intvec) expected");
+        return TRUE;
+      }
+      intvec* arg1 = (intvec*) h->Data();
+      //int arg2 = (int) h->next->Data();
+      intvec* result = MivWeightOrderdp(arg1);
+      res->rtyp = INTVEC_CMD;
+      res->data =  result;
+      return FALSE;
+    }
+    else
+  #endif
+  /*==================== MivMatrixOrderlp =================*/
+  #ifdef HAVE_WALK
+    if(strcmp(sys_cmd, "MivMatrixOrderlp") == 0)
+    {
+      if(h==NULL || h->Typ() != INT_CMD)
+      {
+        WerrorS("system(\"MivMatrixOrderlp\",int) expected");
+        return TRUE;
+      }
+      int arg1 = (int) ((long)(h->Data()));
+      intvec* result = (intvec*) MivMatrixOrderlp(arg1);
+      res->rtyp = INTVEC_CMD;
+      res->data =  result;
+      return FALSE;
+    }
+    else
+  #endif
+  /*==================== MkInterRedNextWeight =================*/
+  #ifdef HAVE_WALK
+    if (strcmp(sys_cmd, "MkInterRedNextWeight") == 0)
+    {
+      const short t[]={3,INTVEC_CMD,INTVEC_CMD,IDEAL_CMD};
+      if (!iiCheckTypes(h,t,1)) return TRUE;
+      if (((intvec*) h->Data())->length() != currRing->N ||
+        ((intvec*) h->next->Data())->length() != currRing->N)
+      {
+        Werror("system(\"MkInterRedNextWeight\" ...) intvecs not of length %d\n",
+                 currRing->N);
+        return TRUE;
+      }
+      intvec* arg1 = (intvec*) h->Data();
+      intvec* arg2 = (intvec*) h->next->Data();
+      ideal arg3   =   (ideal) h->next->next->Data();
+      intvec* result = (intvec*) MkInterRedNextWeight(arg1, arg2, arg3);
+      res->rtyp = INTVEC_CMD;
+      res->data =  result;
+      return FALSE;
+    }
+    else
+  #endif
+  /*==================== MPertNextWeight =================*/
+  #ifdef HAVE_WALK
+  #ifdef MPertNextWeight
+    if (strcmp(sys_cmd, "MPertNextWeight") == 0)
+    {
+      const short t[]={3,INTVEC_CMD,IDEAL_CMD,INT_CMD};
+      if (!iiCheckTypes(h,t,1)) return TRUE;
+      if (((intvec*) h->Data())->length() != currRing->N)
+      {
+        Werror("system(\"MPertNextWeight\" ...) intvecs not of length %d\n",
+                 currRing->N);
+        return TRUE;
+      }
+      intvec* arg1 = (intvec*) h->Data();
+      ideal arg2 = (ideal) h->next->Data();
+      int arg3   =   (int) h->next->next->Data();
+      intvec* result = (intvec*) MPertNextWeight(arg1, arg2, arg3);
+      res->rtyp = INTVEC_CMD;
+      res->data =  result;
+      return FALSE;
+    }
+    else
+  #endif //MPertNextWeight
+  #endif
+  /*==================== Mivperttarget =================*/
+  #ifdef HAVE_WALK
+  #ifdef Mivperttarget
+    if (strcmp(sys_cmd, "Mivperttarget") == 0)
+    {
+      const short t[]={2,IDEAL_CMD,INT_CMD};
+      if (!iiCheckTypes(h,t,1)) return TRUE;
+      ideal arg1 = (ideal) h->Data();
+      int arg2 = (int) h->next->Data();
+      intvec* result = (intvec*) Mivperttarget(arg1, arg2);
+      res->rtyp = INTVEC_CMD;
+      res->data =  result;
+      return FALSE;
+    }
+    else
+  #endif //Mivperttarget
+  #endif
+  /*==================== Mwalk =================*/
+  #ifdef HAVE_WALK
+    if (strcmp(sys_cmd, "Mwalk") == 0)
+    {
+      const short t[]={4,IDEAL_CMD,INTVEC_CMD,INTVEC_CMD,RING_CMD};
+      if (!iiCheckTypes(h,t,1)) return TRUE;
+      if (((intvec*) h->next->Data())->length() != currRing->N &&
+        ((intvec*) h->next->next->Data())->length() != currRing->N )
+      {
+        Werror("system(\"Mwalk\" ...) intvecs not of length %d\n",
+           currRing->N);
+        return TRUE;
+      }
+      ideal arg1 = (ideal) h->Data();
+      intvec* arg2 = (intvec*) h->next->Data();
+      intvec* arg3   =  (intvec*) h->next->next->Data();
+      ring arg4   =  (ring) h->next->next->next->Data();
+      ideal result = (ideal) Mwalk(arg1, arg2, arg3,arg4);
+      res->rtyp = IDEAL_CMD;
+      res->data =  result;
+      return FALSE;
+    }
+    else
+  #endif
+  /*==================== Mpwalk =================*/
+  #ifdef HAVE_WALK
+  #ifdef MPWALK_ORIG
+    if (strcmp(sys_cmd, "Mwalk") == 0)
+    {
+      const short t[]={4,IDEAL_CMD,INTVEC_CMD,INTVEC_CMD,RING_CMD};
+      if (!iiCheckTypes(h,t,1)) return TRUE;
+      if ((((intvec*) h->next->Data())->length() != currRing->N &&
+          ((intvec*) h->next->next->Data())->length() != currRing->N ) &&
+          (((intvec*) h->next->Data())->length() != (currRing->N)*(currRing->N) &&
+          ((intvec*) h->next->next->Data())->length() != (currRing->N)*(currRing->N)))
+      {
+        Werror("system(\"Mwalk\" ...) intvecs not of length %d or %d\n",
+               currRing->N,(currRing->N)*(currRing->N));
+        return TRUE;
+      }
+      ideal arg1 = (ideal) h->Data();
+      intvec* arg2 = (intvec*) h->next->Data();
+      intvec* arg3   =  (intvec*) h->next->next->Data();
+      ring arg4 = (ring) h->next->next->next->Data();
+      ideal result = (ideal) Mwalk(arg1, arg2, arg3,arg4);
+      res->rtyp = IDEAL_CMD;
+      res->data =  result;
+      return FALSE;
+    }
+    else
+  #else
+    if (strcmp(sys_cmd, "Mpwalk") == 0)
+    {
+      const short t[]={6,IDEAL_CMD,INT_CMD,INT_CMD,INTVEC_CMD,INTVEC_CMD,INT_CMD};
+      if (!iiCheckTypes(h,t,1)) return TRUE;
+      if(((intvec*) h->next->next->next->Data())->length() != currRing->N &&
+         ((intvec*) h->next->next->next->next->Data())->length()!=currRing->N)
+      {
+        Werror("system(\"Mpwalk\" ...) intvecs not of length %d\n",currRing->N);
+        return TRUE;
+      }
+      ideal arg1 = (ideal) h->Data();
+      int arg2 = (int) (long) h->next->Data();
+      int arg3 = (int) (long) h->next->next->Data();
+      intvec* arg4 = (intvec*) h->next->next->next->Data();
+      intvec* arg5 = (intvec*) h->next->next->next->next->Data();
+      int arg6 = (int) (long) h->next->next->next->next->next->Data();
+      ideal result = (ideal) Mpwalk(arg1, arg2, arg3, arg4, arg5,arg6);
+      res->rtyp = IDEAL_CMD;
+      res->data =  result;
+      return FALSE;
+    }
+    else
+    #endif
+  #endif
+  /*==================== Mrwalk =================*/
+  #ifdef HAVE_WALK
+    if (strcmp(sys_cmd, "Mrwalk") == 0)
+    {
+      const short t[]={6,IDEAL_CMD,INTVEC_CMD,INTVEC_CMD,INT_CMD,INT_CMD,RING_CMD};
+      if (!iiCheckTypes(h,t,1)) return TRUE;
+      if((((intvec*) h->next->Data())->length() != currRing->N &&
+         ((intvec*) h->next->next->Data())->length() != currRing->N ) &&
+         (((intvec*) h->next->Data())->length() != (currRing->N)*(currRing->N) &&
+         ((intvec*) h->next->next->Data())->length() != (currRing->N)*(currRing->N) ))
+      {
+        Werror("system(\"Mrwalk\" ...) intvecs not of length %d or %d\n",
+               currRing->N,(currRing->N)*(currRing->N));
+        return TRUE;
+      }
+      ideal arg1 = (ideal) h->Data();
+      intvec* arg2 = (intvec*) h->next->Data();
+      intvec* arg3 =  (intvec*) h->next->next->Data();
+      int arg4 = (int)(long) h->next->next->next->Data();
+      int arg5 = (int)(long) h->next->next->next->next->Data();
+      ring arg6 = (ring) h->next->next->next->next->next->Data();
+      ideal result = (ideal) Mrwalk(arg1, arg2, arg3, arg4, arg5, arg6);
+      res->rtyp = IDEAL_CMD;
+      res->data =  result;
+      return FALSE;
+    }
+    else
+  #endif
+  /*==================== MAltwalk1 =================*/
+  #ifdef HAVE_WALK
+    if (strcmp(sys_cmd, "MAltwalk1") == 0)
+    {
+      const short t[]={5,IDEAL_CMD,INT_CMD,INT_CMD,INTVEC_CMD,INTVEC_CMD};
+      if (!iiCheckTypes(h,t,1)) return TRUE;
+      if (((intvec*) h->next->next->next->Data())->length() != currRing->N &&
+        ((intvec*) h->next->next->next->next->Data())->length()!=currRing->N)
+      {
+        Werror("system(\"MAltwalk1\" ...) intvecs not of length %d\n",
+                 currRing->N);
+        return TRUE;
+      }
+      ideal arg1 = (ideal) h->Data();
+      int arg2 = (int) ((long)(h->next->Data()));
+      int arg3 = (int) ((long)(h->next->next->Data()));
+      intvec* arg4 = (intvec*) h->next->next->next->Data();
+      intvec* arg5   =  (intvec*) h->next->next->next->next->Data();
+      ideal result = (ideal) MAltwalk1(arg1, arg2, arg3, arg4, arg5);
+      res->rtyp = IDEAL_CMD;
+      res->data =  result;
+      return FALSE;
+    }
+    else
+  #endif
+  /*==================== MAltwalk1 =================*/
+  #ifdef HAVE_WALK
+  #ifdef MFWALK_ALT
+    if (strcmp(sys_cmd, "Mfwalk_alt") == 0)
+    {
+      const short t[]={4,IDEAL_CMD,INTVEC_CMD,INTVEC_CMD,INT_CMD};
+      if (!iiCheckTypes(h,t,1)) return TRUE;
+      if (((intvec*) h->next->Data())->length() != currRing->N &&
+        ((intvec*) h->next->next->Data())->length() != currRing->N )
+      {
+        Werror("system(\"Mfwalk\" ...) intvecs not of length %d\n",
+              currRing->N);
+        return TRUE;
+      }
+      ideal arg1 = (ideal) h->Data();
+      intvec* arg2 = (intvec*) h->next->Data();
+      intvec* arg3   =  (intvec*) h->next->next->Data();
+      int arg4 = (int) h->next->next->next->Data();
+      ideal result = (ideal) Mfwalk_alt(arg1, arg2, arg3, arg4);
+      res->rtyp = IDEAL_CMD;
+      res->data =  result;
+      return FALSE;
+    }
+    else
+  #endif
+  #endif
+  /*==================== Mfwalk =================*/
+  #ifdef HAVE_WALK
+    if (strcmp(sys_cmd, "Mfwalk") == 0)
+    {
+      const short t[]={3,IDEAL_CMD,INTVEC_CMD,INTVEC_CMD};
+      if (!iiCheckTypes(h,t,1)) return TRUE;
+      if (((intvec*) h->next->Data())->length() != currRing->N &&
+        ((intvec*) h->next->next->Data())->length() != currRing->N )
+      {
+        Werror("system(\"Mfwalk\" ...) intvecs not of length %d\n",
+                 currRing->N);
+        return TRUE;
+      }
+      ideal arg1 = (ideal) h->Data();
+      intvec* arg2 = (intvec*) h->next->Data();
+      intvec* arg3   =  (intvec*) h->next->next->Data();
+      ideal result = (ideal) Mfwalk(arg1, arg2, arg3);
+      res->rtyp = IDEAL_CMD;
+      res->data =  result;
+      return FALSE;
+    }
+    else
+  #endif
+  /*==================== Mfrwalk =================*/
+  #ifdef HAVE_WALK
+    if (strcmp(sys_cmd, "Mfrwalk") == 0)
+    {
+      const short t[]={6,IDEAL_CMD,INTVEC_CMD,INTVEC_CMD,INT_CMD,INT_CMD,RING_CMD};
+      if (!iiCheckTypes(h,t,1)) return TRUE;
+      if (((intvec*) h->next->Data())->length() != currRing->N &&
+          ((intvec*) h->next->next->Data())->length() != currRing->N)
+      {
+        Werror("system(\"Mfrwalk\" ...) intvecs not of length %d\n",currRing->N);
+        return TRUE;
+      }
+      ideal arg1 = (ideal) h->Data();
+      intvec* arg2 = (intvec*) h->next->Data();
+      intvec* arg3 = (intvec*) h->next->next->Data();
+      int arg4 = (int)(long) h->next->next->next->Data();
+      ideal result = (ideal) Mfrwalk(arg1, arg2, arg3, arg4);
+      res->rtyp = IDEAL_CMD;
+      res->data =  result;
+      return FALSE;
+    }
+    else
+  /*==================== Mprwalk =================*/
+    if (strcmp(sys_cmd, "Mprwalk") == 0)
+    {
+      const short t[]={7,IDEAL_CMD,INTVEC_CMD,INTVEC_CMD,INT_CMD,INT_CMD,INT_CMD,RING_CMD};
+      if (!iiCheckTypes(h,t,1)) return TRUE;
+      if (((intvec*) h->next->Data())->length() != currRing->N &&
+          ((intvec*) h->next->next->Data())->length() != currRing->N )
+      {
+        Werror("system(\"Mrwalk\" ...) intvecs not of length %d\n",
+               currRing->N);
+        return TRUE;
+      }
+      ideal arg1 = (ideal) h->Data();
+      intvec* arg2 = (intvec*) h->next->Data();
+      intvec* arg3 =  (intvec*) h->next->next->Data();
+      int arg4 = (int)(long) h->next->next->next->Data();
+      int arg5 = (int)(long) h->next->next->next->next->Data();
+      int arg6 = (int)(long) h->next->next->next->next->next->Data();
+      ring arg7 = (ring) h->next->next->next->next->next->next->Data();
+      ideal result = (ideal) Mprwalk(arg1, arg2, arg3, arg4, arg5, arg6, arg7);
+      res->rtyp = IDEAL_CMD;
+      res->data =  result;
+      return FALSE;
+    }
+    else
+  #endif
+  /*==================== TranMImprovwalk =================*/
+  #ifdef HAVE_WALK
+  #ifdef TRAN_Orig
+    if (strcmp(sys_cmd, "TranMImprovwalk") == 0)
+    {
+      const short t[]={3,IDEAL_CMD,INTVEC_CMD,INTVEC_CMD};
+      if (!iiCheckTypes(h,t,1)) return TRUE;
+      if (((intvec*) h->next->Data())->length() != currRing->N &&
+        ((intvec*) h->next->next->Data())->length() != currRing->N )
+      {
+        Werror("system(\"TranMImprovwalk\" ...) intvecs not of length %d\n",
+              currRing->N);
+        return TRUE;
+      }
+      ideal arg1 = (ideal) h->Data();
+      intvec* arg2 = (intvec*) h->next->Data();
+      intvec* arg3   =  (intvec*) h->next->next->Data();
+      ideal result = (ideal) TranMImprovwalk(arg1, arg2, arg3);
+      res->rtyp = IDEAL_CMD;
+      res->data =  result;
+      return FALSE;
+    }
+    else
+  #endif
+  #endif
+  /*==================== MAltwalk2 =================*/
+  #ifdef HAVE_WALK
+    if (strcmp(sys_cmd, "MAltwalk2") == 0)
+    {
+      const short t[]={3,IDEAL_CMD,INTVEC_CMD,INTVEC_CMD};
+      if (!iiCheckTypes(h,t,1)) return TRUE;
+      if (((intvec*) h->next->Data())->length() != currRing->N &&
+        ((intvec*) h->next->next->Data())->length() != currRing->N )
+      {
+        Werror("system(\"MAltwalk2\" ...) intvecs not of length %d\n",
+                 currRing->N);
+        return TRUE;
+      }
+      ideal arg1 = (ideal) h->Data();
+      intvec* arg2 = (intvec*) h->next->Data();
+      intvec* arg3   =  (intvec*) h->next->next->Data();
+      ideal result = (ideal) MAltwalk2(arg1, arg2, arg3);
+      res->rtyp = IDEAL_CMD;
+      res->data =  result;
+      return FALSE;
+    }
+    else
+  #endif
+  /*==================== MAltwalk2 =================*/
+  #ifdef HAVE_WALK
+    if (strcmp(sys_cmd, "TranMImprovwalk") == 0)
+    {
+      const short t[]={4,IDEAL_CMD,INTVEC_CMD,INTVEC_CMD,INT_CMD};
+      if (!iiCheckTypes(h,t,1)) return TRUE;
+      if (((intvec*) h->next->Data())->length() != currRing->N &&
+        ((intvec*) h->next->next->Data())->length() != currRing->N )
+      {
+        Werror("system(\"TranMImprovwalk\" ...) intvecs not of length %d\n",
+                 currRing->N);
+        return TRUE;
+      }
+      ideal arg1 = (ideal) h->Data();
+      intvec* arg2 = (intvec*) h->next->Data();
+      intvec* arg3   =  (intvec*) h->next->next->Data();
+      int arg4   =  (int) ((long)(h->next->next->next->Data()));
+      ideal result = (ideal) TranMImprovwalk(arg1, arg2, arg3, arg4);
+      res->rtyp = IDEAL_CMD;
+      res->data =  result;
+      return FALSE;
+    }
+    else
+  #endif
+  /*==================== TranMrImprovwalk =================*/
+  #if 0
+  #ifdef HAVE_WALK
+    if (strcmp(sys_cmd, "TranMrImprovwalk") == 0)
+    {
+      if (h == NULL || h->Typ() != IDEAL_CMD ||
+        h->next == NULL || h->next->Typ() != INTVEC_CMD ||
+        h->next->next == NULL || h->next->next->Typ() != INTVEC_CMD ||
+        h->next->next->next == NULL || h->next->next->next->Typ() != INT_CMD ||
+        h->next->next->next == NULL || h->next->next->next->next->Typ() != INT_CMD ||
+        h->next->next->next == NULL || h->next->next->next->next->next->Typ() != INT_CMD)
+      {
+        WerrorS("system(\"TranMrImprovwalk\", ideal, intvec, intvec) expected");
+        return TRUE;
+      }
+      if (((intvec*) h->next->Data())->length() != currRing->N &&
+        ((intvec*) h->next->next->Data())->length() != currRing->N )
+      {
+        Werror("system(\"TranMrImprovwalk\" ...) intvecs not of length %d\n", currRing->N);
+        return TRUE;
+      }
+      ideal arg1 = (ideal) h->Data();
+      intvec* arg2 = (intvec*) h->next->Data();
+      intvec* arg3 = (intvec*) h->next->next->Data();
+      int arg4 = (int)(long) h->next->next->next->Data();
+      int arg5 = (int)(long) h->next->next->next->next->Data();
+      int arg6 = (int)(long) h->next->next->next->next->next->Data();
+      ideal result = (ideal) TranMrImprovwalk(arg1, arg2, arg3, arg4, arg5, arg6);
+      res->rtyp = IDEAL_CMD;
+      res->data =  result;
+      return FALSE;
+    }
+    else
+  #endif
+  #endif
+  /*================= Extended system call ========================*/
+    {
+       #ifndef MAKE_DISTRIBUTION
+       return(jjEXTENDED_SYSTEM(res, args));
+       #else
+       Werror( "system(\"%s\",...) %s", sys_cmd, feNotImplemented );
+       #endif
+    }
+  } /* typ==string */
+  return TRUE;
+}
+
+
+#ifdef HAVE_EXTENDED_SYSTEM
+  // You can put your own system calls here
+#  include <kernel/fglm/fglmcomb.cc>
+#  include <kernel/fglm/fglm.h>
+#  ifdef HAVE_NEWTON
+#    include <hc_newton.h>
+#  endif
+#  include <polys/mod_raw.h>
+#  include <polys/monomials/ring.h>
+#  include <kernel/GBEngine/shiftgb.h>
+
+static BOOLEAN jjEXTENDED_SYSTEM(leftv res, leftv h)
+{
+    if(h->Typ() == STRING_CMD)
+    {
+      char *sys_cmd=(char *)(h->Data());
+      h=h->next;
+  /*==================== test syz strat =================*/
+      if (strcmp(sys_cmd, "syz") == 0)
+      {
+         int posInT_EcartFDegpLength(const TSet set,const int length,LObject &p);
+         int posInT_FDegpLength(const TSet set,const int length,LObject &p);
+         int posInT_pLength(const TSet set,const int length,LObject &p);
+         int posInT0(const TSet set,const int length,LObject &p);
+         int posInT1(const TSet set,const int length,LObject &p);
+         int posInT2(const TSet set,const int length,LObject &p);
+         int posInT11(const TSet set,const int length,LObject &p);
+         int posInT110(const TSet set,const int length,LObject &p);
+         int posInT13(const TSet set,const int length,LObject &p);
+         int posInT15(const TSet set,const int length,LObject &p);
+         int posInT17(const TSet set,const int length,LObject &p);
+         int posInT17_c(const TSet set,const int length,LObject &p);
+         int posInT19(const TSet set,const int length,LObject &p);
+         if ((h!=NULL) && (h->Typ()==STRING_CMD))
+         {
+           const char *s=(const char *)h->Data();
+           if (strcmp(s,"posInT_EcartFDegpLength")==0)
+             test_PosInT=posInT_EcartFDegpLength;
+           else if (strcmp(s,"posInT_FDegpLength")==0)
+             test_PosInT=posInT_FDegpLength;
+           else if (strcmp(s,"posInT_pLength")==0)
+             test_PosInT=posInT_pLength;
+           else if (strcmp(s,"posInT0")==0)
+             test_PosInT=posInT0;
+           else if (strcmp(s,"posInT1")==0)
+             test_PosInT=posInT1;
+           else if (strcmp(s,"posInT2")==0)
+             test_PosInT=posInT2;
+           else if (strcmp(s,"posInT11")==0)
+             test_PosInT=posInT11;
+           else if (strcmp(s,"posInT110")==0)
+             test_PosInT=posInT110;
+           else if (strcmp(s,"posInT13")==0)
+             test_PosInT=posInT13;
+           else if (strcmp(s,"posInT15")==0)
+             test_PosInT=posInT15;
+           else if (strcmp(s,"posInT17")==0)
+             test_PosInT=posInT17;
+           else if (strcmp(s,"posInT17_c")==0)
+             test_PosInT=posInT17_c;
+           else if (strcmp(s,"posInT19")==0)
+             test_PosInT=posInT19;
+           else Print("valid posInT:0,1,2,11,110,13,15,17,17_c,19,_EcartFDegpLength,_FDegpLength,_pLength,_EcartpLength\n");
+         }
+         else
+         {
+           test_PosInT=NULL;
+           test_PosInL=NULL;
+         }
+         si_opt_2|=Sy_bit(23);
+         return FALSE;
+      }
+      else
+  /*==================== locNF ======================================*/
+      if(strcmp(sys_cmd,"locNF")==0)
+      {
+        const short t[]={4,VECTOR_CMD,MODUL_CMD,INT_CMD,INTVEC_CMD};
+        if (iiCheckTypes(h,t,1))
+        {
+          poly f=(poly)h->Data();
+          h=h->next;
+          ideal m=(ideal)h->Data();
+          assumeStdFlag(h);
+          h=h->next;
+          int n=(int)((long)h->Data());
+          h=h->next;
+          intvec *v=(intvec *)h->Data();
+
+          /* == now the work starts == */
+
+          short * iv=iv2array(v, currRing);
+          poly r=0;
+          poly hp=ppJetW(f,n,iv);
+          int s=MATCOLS(m);
+          int j=0;
+          matrix T=mp_InitI(s,1,0, currRing);
+
+          while (hp != NULL)
+          {
+            if (pDivisibleBy(m->m[j],hp))
+            {
+              if (MATELEM(T,j+1,1)==0)
+              {
+                MATELEM(T,j+1,1)=pDivideM(pHead(hp),pHead(m->m[j]));
+              }
+              else
+              {
+                pAdd(MATELEM(T,j+1,1),pDivideM(pHead(hp),pHead(m->m[j])));
+              }
+              hp=ppJetW(ksOldSpolyRed(m->m[j],hp,0),n,iv);
+              j=0;
+            }
+            else
+            {
+              if (j==s-1)
+              {
+                r=pAdd(r,pHead(hp));
+                hp=pLmDeleteAndNext(hp); /* hp=pSub(hp,pHead(hp));*/
+                j=0;
+              }
+              else
+              {
+                j++;
+              }
+            }
+          }
+
+          matrix Temp=mp_Transp((matrix) id_Vec2Ideal(r, currRing), currRing);
+          matrix R=mpNew(MATCOLS((matrix) id_Vec2Ideal(f, currRing)),1);
+          for (int k=1;k<=MATROWS(Temp);k++)
+          {
+            MATELEM(R,k,1)=MATELEM(Temp,k,1);
+          }
+
+          lists L=(lists)omAllocBin(slists_bin);
+          L->Init(2);
+          L->m[0].rtyp=MATRIX_CMD;   L->m[0].data=(void *)R;
+          L->m[1].rtyp=MATRIX_CMD;   L->m[1].data=(void *)T;
+          res->data=L;
+          res->rtyp=LIST_CMD;
+          // iv aufraeumen
+          omFree(iv);
+          return FALSE;
+        }
+        else
+          return TRUE;
+      }
+      else
+  /*==================== poly debug ==================================*/
+        if(strcmp(sys_cmd,"p")==0)
+        {
+#  ifdef RDEBUG
+          p_DebugPrint((poly)h->Data(), currRing);
+#  else
+          Warn("Sorry: not available for release build!");
+#  endif
+          return FALSE;
+        }
+        else
+  /*==================== setsyzcomp ==================================*/
+      if(strcmp(sys_cmd,"setsyzcomp")==0)
+      {
+        if ((h!=NULL) && (h->Typ()==INT_CMD))
+        {
+          int k = (int)(long)h->Data();
+          if ( currRing->order[0] == ringorder_s )
+          {
+            rSetSyzComp(k, currRing);
+          }
+        }
+      }
+  /*==================== ring debug ==================================*/
+        if(strcmp(sys_cmd,"r")==0)
+        {
+#  ifdef RDEBUG
+          rDebugPrint((ring)h->Data());
+#  else
+          Warn("Sorry: not available for release build!");
+#  endif
+          return FALSE;
+        }
+        else
+  /*==================== changeRing ========================*/
+        /* The following code changes the names of the variables in the
+           current ring to "x1", "x2", ..., "xN", where N is the number
+           of variables in the current ring.
+           The purpose of this rewriting is to eliminate indexed variables,
+           as they may cause problems when generating scripts for Magma,
+           Maple, or Macaulay2. */
+        if(strcmp(sys_cmd,"changeRing")==0)
+        {
+          int varN = currRing->N;
+          char h[10];
+          for (int i = 1; i <= varN; i++)
+          {
+            omFree(currRing->names[i - 1]);
+            sprintf(h, "x%d", i);
+            currRing->names[i - 1] = omStrDup(h);
+          }
+          rComplete(currRing);
+          res->rtyp = INT_CMD;
+          res->data = (void*)0L;
+          return FALSE;
+        }
+        else
+  /*==================== mtrack ==================================*/
+      if(strcmp(sys_cmd,"mtrack")==0)
+      {
+  #ifdef OM_TRACK
+        om_Opts.MarkAsStatic = 1;
+        FILE *fd = NULL;
+        int max = 5;
+        while (h != NULL)
+        {
+          omMarkAsStaticAddr(h);
+          if (fd == NULL && h->Typ()==STRING_CMD)
+          {
+            fd = fopen((char*) h->Data(), "w");
+            if (fd == NULL)
+              Warn("Can not open %s for writing og mtrack. Using stdout"); // %s  ???
+          }
+          if (h->Typ() == INT_CMD)
+          {
+            max = (int)(long)h->Data();
+          }
+          h = h->Next();
+        }
+        omPrintUsedTrackAddrs((fd == NULL ? stdout : fd), max);
+        if (fd != NULL) fclose(fd);
+        om_Opts.MarkAsStatic = 0;
+        return FALSE;
+  #endif
+      }
+  /*==================== mtrack_all ==================================*/
+      if(strcmp(sys_cmd,"mtrack_all")==0)
+      {
+  #ifdef OM_TRACK
+        om_Opts.MarkAsStatic = 1;
+        FILE *fd = NULL;
+        if ((h!=NULL) &&(h->Typ()==STRING_CMD))
+        {
+          fd = fopen((char*) h->Data(), "w");
+          if (fd == NULL)
+            Warn("Can not open %s for writing og mtrack. Using stdout");
+          omMarkAsStaticAddr(h);
+        }
+        // OB: TBC print to fd
+        omPrintUsedAddrs((fd == NULL ? stdout : fd), 5);
+        if (fd != NULL) fclose(fd);
+        om_Opts.MarkAsStatic = 0;
+        return FALSE;
+  #endif
+      }
+      else
+  /*==================== backtrace ==================================*/
+  #ifndef OM_NDEBUG
+      if(strcmp(sys_cmd,"backtrace")==0)
+      {
+        omPrintCurrentBackTrace(stdout);
+        return FALSE;
+      }
+      else
+  #endif
+
+#if !defined(OM_NDEBUG)
+  /*==================== omMemoryTest ==================================*/
+      if (strcmp(sys_cmd,"omMemoryTest")==0)
+      {
+
+#ifdef OM_STATS_H
+        PrintS("\n[om_Info]: \n");
+        omUpdateInfo();
+#define OM_PRINT(name) Print(" %-22s : %10ld \n", #name, om_Info . name)
+        OM_PRINT(MaxBytesSystem);
+        OM_PRINT(CurrentBytesSystem);
+        OM_PRINT(MaxBytesSbrk);
+        OM_PRINT(CurrentBytesSbrk);
+        OM_PRINT(MaxBytesMmap);
+        OM_PRINT(CurrentBytesMmap);
+        OM_PRINT(UsedBytes);
+        OM_PRINT(AvailBytes);
+        OM_PRINT(UsedBytesMalloc);
+        OM_PRINT(AvailBytesMalloc);
+        OM_PRINT(MaxBytesFromMalloc);
+        OM_PRINT(CurrentBytesFromMalloc);
+        OM_PRINT(MaxBytesFromValloc);
+        OM_PRINT(CurrentBytesFromValloc);
+        OM_PRINT(UsedBytesFromValloc);
+        OM_PRINT(AvailBytesFromValloc);
+        OM_PRINT(MaxPages);
+        OM_PRINT(UsedPages);
+        OM_PRINT(AvailPages);
+        OM_PRINT(MaxRegionsAlloc);
+        OM_PRINT(CurrentRegionsAlloc);
+#undef OM_PRINT
+#endif
+
+#ifdef OM_OPTS_H
+        PrintS("\n[om_Opts]: \n");
+#define OM_PRINT(format, name) Print(" %-22s : %10" format"\n", #name, om_Opts . name)
+        OM_PRINT("d", MinTrack);
+        OM_PRINT("d", MinCheck);
+        OM_PRINT("d", MaxTrack);
+        OM_PRINT("d", MaxCheck);
+        OM_PRINT("d", Keep);
+        OM_PRINT("d", HowToReportErrors);
+        OM_PRINT("d", MarkAsStatic);
+        OM_PRINT("u", PagesPerRegion);
+        OM_PRINT("p", OutOfMemoryFunc);
+        OM_PRINT("p", MemoryLowFunc);
+        OM_PRINT("p", ErrorHook);
+#undef OM_PRINT
+#endif
+
+#ifdef OM_ERROR_H
+        Print("\n\n[om_ErrorStatus]        : '%s' (%s)\n",
+                omError2String(om_ErrorStatus),
+                omError2Serror(om_ErrorStatus));
+        Print("[om_InternalErrorStatus]: '%s' (%s)\n",
+                omError2String(om_InternalErrorStatus),
+                omError2Serror(om_InternalErrorStatus));
+
+#endif
+
+//        omTestMemory(1);
+//        omtTestErrors();
+        return FALSE;
+      }
+      else
+#endif
+  /*==================== pDivStat =============================*/
+  #if defined(PDEBUG) || defined(PDIV_DEBUG)
+      if(strcmp(sys_cmd,"pDivStat")==0)
+      {
+        extern void pPrintDivisbleByStat();
+        pPrintDivisbleByStat();
+        return FALSE;
+      }
+      else
+  #endif
+  /*==================== alarm ==================================*/
+  #ifdef unix
+      if(strcmp(sys_cmd,"alarm")==0)
+      {
+        if ((h!=NULL) &&(h->Typ()==INT_CMD))
+        {
+          // standard variant -> SIGALARM (standard: abort)
+          //alarm((unsigned)h->next->Data());
+          // process time (user +system): SIGVTALARM
+          struct itimerval t,o;
+          memset(&t,0,sizeof(t));
+          t.it_value.tv_sec     =(unsigned)((unsigned long)h->Data());
+          setitimer(ITIMER_VIRTUAL,&t,&o);
+          return FALSE;
+        }
+        else
+          WerrorS("int expected");
+      }
+      else
+  #endif
+  /*==================== red =============================*/
+  #if 0
+      if(strcmp(sys_cmd,"red")==0)
+      {
+        if ((h!=NULL) &&(h->Typ()==IDEAL_CMD))
+        {
+          res->rtyp=IDEAL_CMD;
+          res->data=(void *)kStdred((ideal)h->Data(),NULL,testHomog,NULL);
+          setFlag(res,FLAG_STD);
+          return FALSE;
+        }
+        else
+          WerrorS("ideal expected");
+      }
+      else
+  #endif
+  /*==================== fastcomb =============================*/
+      if(strcmp(sys_cmd,"fastcomb")==0)
+      {
+        if ((h!=NULL) &&(h->Typ()==IDEAL_CMD))
+        {
+          if (h->next!=NULL)
+          {
+            if (h->next->Typ()!=POLY_CMD)
+            {
+              Warn("Wrong types for poly= comb(ideal,poly)");
+            }
+          }
+          res->rtyp=POLY_CMD;
+          res->data=(void *) fglmLinearCombination(
+                             (ideal)h->Data(),(poly)h->next->Data());
+          return FALSE;
+        }
+        else
+          WerrorS("ideal expected");
+      }
+      else
+  /*==================== comb =============================*/
+      if(strcmp(sys_cmd,"comb")==0)
+      {
+        if ((h!=NULL) &&(h->Typ()==IDEAL_CMD))
+        {
+          if (h->next!=NULL)
+          {
+            if (h->next->Typ()!=POLY_CMD)
+            {
+                Warn("Wrong types for poly= comb(ideal,poly)");
+            }
+          }
+          res->rtyp=POLY_CMD;
+          res->data=(void *)fglmNewLinearCombination(
+                              (ideal)h->Data(),(poly)h->next->Data());
+          return FALSE;
+        }
+        else
+          WerrorS("ideal expected");
+      }
+      else
+  #if 0 /* debug only */
+  /*==================== listall ===================================*/
+      if(strcmp(sys_cmd,"listall")==0)
+      {
+        void listall(int showproc);
+        int showproc=0;
+        if ((h!=NULL) && (h->Typ()==INT_CMD)) showproc=(int)((long)h->Data());
+        listall(showproc);
+        return FALSE;
+      }
+      else
+  #endif
+  #if 0 /* debug only */
+  /*==================== proclist =================================*/
+      if(strcmp(sys_cmd,"proclist")==0)
+      {
+        void piShowProcList();
+        piShowProcList();
+        return FALSE;
+      }
+      else
+  #endif
+  /* ==================== newton ================================*/
+  #ifdef HAVE_NEWTON
+      if(strcmp(sys_cmd,"newton")==0)
+      {
+        if ((h->Typ()!=POLY_CMD)
+        || (h->next->Typ()!=INT_CMD)
+        || (h->next->next->Typ()!=INT_CMD))
+        {
+          WerrorS("system(\"newton\",<poly>,<int>,<int>) expected");
+          return TRUE;
+        }
+        poly  p=(poly)(h->Data());
+        int l=pLength(p);
+        short *points=(short *)omAlloc(currRing->N*l*sizeof(short));
+        int i,j,k;
+        k=0;
+        poly pp=p;
+        for (i=0;pp!=NULL;i++)
+        {
+          for(j=1;j<=currRing->N;j++)
+          {
+            points[k]=pGetExp(pp,j);
+            k++;
+          }
+          pIter(pp);
+        }
+        hc_ERG r=hc_KOENIG(currRing->N,      // dimension
+                  l,      // number of points
+                  (short*) points,   // points: x_1, y_1,z_1, x_2,y_2,z2,...
+                  currRing->OrdSgn==-1,
+                  (int) (h->next->Data()),      // 1: Milnor, 0: Newton
+                  (int) (h->next->next->Data()) // debug
+                 );
+        //----<>---Output-----------------------
+
+
+  //  PrintS("Bin jetzt in extra.cc bei der Auswertung.\n"); // **********
+
+
+        lists L=(lists)omAllocBin(slists_bin);
+        L->Init(6);
+        L->m[0].rtyp=STRING_CMD;               // newtonnumber;
+        L->m[0].data=(void *)omStrDup(r.nZahl);
+        L->m[1].rtyp=INT_CMD;
+        L->m[1].data=(void *)(long)r.achse;          // flag for unoccupied axes
+        L->m[2].rtyp=INT_CMD;
+        L->m[2].data=(void *)(long)r.deg;            // #degenerations
+        if ( r.deg != 0)              // only if degenerations exist
+        {
+          L->m[3].rtyp=INT_CMD;
+          L->m[3].data=(void *)(long)r.anz_punkte;     // #points
+          //---<>--number of points------
+          int anz = r.anz_punkte;    // number of points
+          int dim = (currRing->N);     // dimension
+          intvec* v = new intvec( anz*dim );
+          for (i=0; i<anz*dim; i++)    // copy points
+            (*v)[i] = r.pu[i];
+          L->m[4].rtyp=INTVEC_CMD;
+          L->m[4].data=(void *)v;
+          //---<>--degenerations---------
+          int deg = r.deg;    // number of points
+          intvec* w = new intvec( r.speicher );  // necessary memeory
+          i=0;               // start copying
+          do
+          {
+            (*w)[i] = r.deg_tab[i];
+            i++;
+          }
+          while (r.deg_tab[i-1] != -2);   // mark for end of list
+          L->m[5].rtyp=INTVEC_CMD;
+          L->m[5].data=(void *)w;
+        }
+        else
+        {
+          L->m[3].rtyp=INT_CMD; L->m[3].data=(char *)0;
+          L->m[4].rtyp=DEF_CMD;
+          L->m[5].rtyp=DEF_CMD;
+        }
+
+        res->data=(void *)L;
+        res->rtyp=LIST_CMD;
+        // free all pointer in r:
+        delete[] r.nZahl;
+        delete[] r.pu;
+        delete[] r.deg_tab;      // Ist das ein Problem??
+
+        omFreeSize((ADDRESS)points,currRing->N*l*sizeof(short));
+        return FALSE;
+      }
+      else
+  #endif
+  /*==== connection to Sebastian Jambor's code ======*/
+  /* This code connects Sebastian Jambor's code for
+     computing the minimal polynomial of an (n x n) matrix
+     with entries in F_p to SINGULAR. Two conversion methods
+     are needed; see further up in this file:
+        (1) conversion of a matrix with long entries to
+            a SINGULAR matrix with number entries, where
+            the numbers are coefficients in currRing;
+        (2) conversion of an array of longs (encoding the
+            coefficients of the minimal polynomial) to a
+            SINGULAR poly living in currRing. */
+      if (strcmp(sys_cmd, "minpoly") == 0)
+      {
+        if ((h == NULL) || (h->Typ() != MATRIX_CMD) || h->next != NULL)
+        {
+          Werror("expected exactly one argument: %s",
+                 "a square matrix with number entries");
+          return TRUE;
+        }
+        else
+        {
+          matrix m = (matrix)h->Data();
+          int n = m->rows();
+          unsigned long p = (unsigned long)n_GetChar(currRing->cf);
+          if (n != m->cols())
+          {
+            WerrorS("expected exactly one argument: "
+                   "a square matrix with number entries");
+            return TRUE;
+          }
+          unsigned long** ml = singularMatrixToLongMatrix(m);
+          unsigned long* polyCoeffs = computeMinimalPolynomial(ml, n, p);
+          poly theMinPoly = longCoeffsToSingularPoly(polyCoeffs, n);
+          res->rtyp = POLY_CMD;
+          res->data = (void *)theMinPoly;
+          for (int i = 0; i < n; i++) delete[] ml[i];
+          delete[] ml;
+          delete[] polyCoeffs;
+          return FALSE;
+        }
+      }
+      else
+  /*==================== sdb_flags =================*/
+  #ifdef HAVE_SDB
+      if (strcmp(sys_cmd, "sdb_flags") == 0)
+      {
+        if ((h!=NULL) && (h->Typ()==INT_CMD))
+        {
+          sdb_flags=(int)((long)h->Data());
+        }
+        else
+        {
+          WerrorS("system(\"sdb_flags\",`int`) expected");
+          return TRUE;
+        }
+        return FALSE;
+      }
+      else
+  #endif
+  /*==================== sdb_edit =================*/
+  #ifdef HAVE_SDB
+      if (strcmp(sys_cmd, "sdb_edit") == 0)
+      {
+        if ((h!=NULL) && (h->Typ()==PROC_CMD))
+        {
+          procinfov p=(procinfov)h->Data();
+          sdb_edit(p);
+        }
+        else
+        {
+          WerrorS("system(\"sdb_edit\",`proc`) expected");
+          return TRUE;
+        }
+        return FALSE;
+      }
+      else
+  #endif
+  /*==================== GF =================*/
+  #if 0 // for testing only
+      if (strcmp(sys_cmd, "GF") == 0)
+      {
+        if ((h!=NULL) && (h->Typ()==POLY_CMD))
+        {
+          int c=rChar(currRing);
+          setCharacteristic( c,nfMinPoly[0], currRing->parameter[0][0] );
+          CanonicalForm F( convSingGFFactoryGF( (poly)h->Data(), currRing ) );
+          res->rtyp=POLY_CMD;
+          res->data=convFactoryGFSingGF( F, currRing );
+          return FALSE;
+        }
+        else { WerrorS("wrong typ"); return TRUE;}
+      }
+      else
+  #endif
+  /*==================== stdX =================*/
+      if (strcmp(sys_cmd, "std") == 0)
+      {
+        ideal i1;
+        int i2;
+        if ((h!=NULL) && (h->Typ()==MODUL_CMD))
+        {
+          i1=(ideal)h->CopyD();
+          h=h->next;
+        }
+        else return TRUE;
+        if ((h!=NULL) && (h->Typ()==INT_CMD))
+        {
+          i2=(int)((long)h->Data());
+        }
+        else return TRUE;
+        res->rtyp=MODUL_CMD;
+        res->data=idXXX(i1,i2);
+        return FALSE;
+      }
+      else
+  /*==================== SVD =================*/
+  #ifdef HAVE_SVD
+       if (strcmp(sys_cmd, "svd") == 0)
+       {
+            extern lists testsvd(matrix M);
+              res->rtyp=LIST_CMD;
+            res->data=(char*)(testsvd((matrix)h->Data()));
+            return FALSE;
+       }
+       else
+  #endif
+
+
+  /*==================== DLL =================*/
+  #ifdef __CYGWIN__
+  #ifdef HAVE_DL
+  /* testing the DLL functionality under Win32 */
+        if (strcmp(sys_cmd, "DLL") == 0)
+        {
+          typedef void  (*Void_Func)();
+          typedef int  (*Int_Func)(int);
+          void *hh=dynl_open("WinDllTest.dll");
+          if ((h!=NULL) && (h->Typ()==INT_CMD))
+          {
+            int (*f)(int);
+            if (hh!=NULL)
+            {
+              int (*f)(int);
+              f=(Int_Func)dynl_sym(hh,"PlusDll");
+              int i=10;
+              if (f!=NULL) printf("%d\n",f(i));
+              else PrintS("cannot find PlusDll\n");
+            }
+          }
+          else
+          {
+            void (*f)();
+            f= (Void_Func)dynl_sym(hh,"TestDll");
+            if (f!=NULL) f();
+            else PrintS("cannot find TestDll\n");
+          }
+          return FALSE;
+        }
+        else
+  #endif
+  #endif
+  /*==================== facstd_debug ==================================*/
+  #if !defined(SING_NDEBUG)
+      if(strcmp(sys_cmd,"facstd")==0)
+      {
+        extern int strat_nr;
+        extern int strat_fac_debug;
+        strat_fac_debug=(int)(long)h->Data();
+        strat_nr=0;
+        return FALSE;
+      }
+      else
+  #endif
+  #ifdef HAVE_RING2TOM
+  /*==================== ring-GB ==================================*/
+      if (strcmp(sys_cmd, "findZeroPoly")==0)
+      {
+        ring r = currRing;
+        poly f = (poly) h->Data();
+        res->rtyp=POLY_CMD;
+        res->data=(poly) kFindZeroPoly(f, r, r);
+        return(FALSE);
+      }
+      else
+  /*==================== Creating zero polynomials =================*/
+  #ifdef HAVE_VANIDEAL
+      if (strcmp(sys_cmd, "createG0")==0)
+      {
+        /* long exp[50];
+        int N = 0;
+        while (h != NULL)
+        {
+          N += 1;
+          exp[N] = (long) h->Data();
+          // if (exp[i] % 2 != 0) exp[i] -= 1;
+          h = h->next;
+        }
+        for (int k = 1; N + k <= currRing->N; k++) exp[k] = 0;
+
+        poly t_p;
+        res->rtyp=POLY_CMD;
+        res->data= (poly) kCreateZeroPoly(exp, -1, &t_p, currRing, currRing);
+        return(FALSE); */
+
+        res->rtyp = IDEAL_CMD;
+        res->data = (ideal) createG0();
+        return(FALSE);
+      }
+      else
+  #endif
+  /*==================== redNF_ring =================*/
+      if (strcmp(sys_cmd, "redNF_ring")==0)
+      {
+        ring r = currRing;
+        poly f = (poly) h->Data();
+        h = h->next;
+        ideal G = (ideal) h->Data();
+        res->rtyp=POLY_CMD;
+        res->data=(poly) ringRedNF(f, G, r);
+        return(FALSE);
+      }
+      else
+  #endif
+  /*==================== Roune Hilb  =================*/
+       if (strcmp(sys_cmd, "hilbroune") == 0)
+       {
+         ideal I;
+         if ((h!=NULL) && (h->Typ()==IDEAL_CMD))
+         {
+           I=(ideal)h->CopyD();
+           slicehilb(I);
+         }
+         else return TRUE;
+         return FALSE;
+       }
+      else
+  /*==================== F5 Implementation =================*/
+  #ifdef HAVE_F5
+      if (strcmp(sys_cmd, "f5")==0)
+      {
+        if (h->Typ()!=IDEAL_CMD)
+        {
+          WerrorS("ideal expected");
+          return TRUE;
+        }
+
+        ring r = currRing;
+        ideal G = (ideal) h->Data();
+        h = h->next;
+        int opt;
+        if(h != NULL) {
+          opt = (int) (long) h->Data();
+        }
+        else {
+          opt = 2;
+        }
+        h = h->next;
+        int plus;
+        if(h != NULL) {
+          plus = (int) (long) h->Data();
+        }
+        else {
+          plus = 0;
+        }
+        h = h->next;
+        int termination;
+        if(h != NULL) {
+          termination = (int) (long) h->Data();
+        }
+        else {
+          termination = 0;
+        }
+        res->rtyp=IDEAL_CMD;
+        res->data=(ideal) F5main(G,r,opt,plus,termination);
+        return FALSE;
+      }
+      else
+  #endif
+  /*==================== Testing groebner basis =================*/
+  #ifdef HAVE_RINGS
+      if (strcmp(sys_cmd, "NF_ring")==0)
+      {
+        ring r = currRing;
+        poly f = (poly) h->Data();
+        h = h->next;
+        ideal G = (ideal) h->Data();
+        res->rtyp=POLY_CMD;
+        res->data=(poly) ringNF(f, G, r);
+        return(FALSE);
+      }
+      else
+      if (strcmp(sys_cmd, "spoly")==0)
+      {
+        poly f = pCopy((poly) h->Data());
+        h = h->next;
+        poly g = pCopy((poly) h->Data());
+
+        res->rtyp=POLY_CMD;
+        res->data=(poly) plain_spoly(f,g);
+        return(FALSE);
+      }
+      else
+      if (strcmp(sys_cmd, "testGB")==0)
+      {
+        ideal I = (ideal) h->Data();
+        h = h->next;
+        ideal GI = (ideal) h->Data();
+        res->rtyp = INT_CMD;
+        res->data = (void *)(long) testGB(I, GI);
+        return(FALSE);
+      }
+      else
+  #endif
+  /*==================== sca?AltVar ==================================*/
+  #ifdef HAVE_PLURAL
+      if ( (strcmp(sys_cmd, "AltVarStart") == 0) || (strcmp(sys_cmd, "AltVarEnd") == 0) )
+      {
+        ring r = currRing;
+
+        if((h!=NULL) && (h->Typ()==RING_CMD)) r = (ring)h->Data(); else
+        {
+          WerrorS("`system(\"AltVarStart/End\"[,<ring>])` expected");
+          return TRUE;
+        }
+
+        res->rtyp=INT_CMD;
+
+        if (rIsSCA(r))
+        {
+          if(strcmp(sys_cmd, "AltVarStart") == 0)
+            res->data = (void*)(long)scaFirstAltVar(r);
+          else
+            res->data = (void*)(long)scaLastAltVar(r);
+          return FALSE;
+        }
+
+        WerrorS("`system(\"AltVarStart/End\",<ring>) requires a SCA ring");
+        return TRUE;
+      }
+      else
+  #endif
+  /*==================== RatNF, noncomm rational coeffs =================*/
+  #ifdef HAVE_RATGRING
+      if (strcmp(sys_cmd, "intratNF") == 0)
+      {
+        poly p;
+        poly *q;
+        ideal I;
+        int is, k, id;
+        if ((h!=NULL) && (h->Typ()==POLY_CMD))
+        {
+          p=(poly)h->CopyD();
+          h=h->next;
+          //        Print("poly is done\n");
+        }
+        else return TRUE;
+        if ((h!=NULL) && (h->Typ()==IDEAL_CMD))
+        {
+          I=(ideal)h->CopyD();
+          q = I->m;
+          h=h->next;
+          //        Print("ideal is done\n");
+        }
+        else return TRUE;
+        if ((h!=NULL) && (h->Typ()==INT_CMD))
+        {
+          is=(int)((long)(h->Data()));
+          //        res->rtyp=INT_CMD;
+          //        Print("int is done\n");
+          //        res->rtyp=IDEAL_CMD;
+          if (rIsPluralRing(currRing))
+          {
+            id = IDELEMS(I);
+                   int *pl=(int*)omAlloc0(IDELEMS(I)*sizeof(int));
+            for(k=0; k < id; k++)
+            {
+              pl[k] = pLength(I->m[k]);
+            }
+            Print("starting redRat\n");
+            //res->data = (char *)
+            redRat(&p, q, pl, (int)IDELEMS(I),is,currRing);
+            res->data=p;
+            res->rtyp=POLY_CMD;
+            //        res->data = ncGCD(p,q,currRing);
+          }
+          else
+          {
+            res->rtyp=POLY_CMD;
+            res->data=p;
+          }
+        }
+        else return TRUE;
+        return FALSE;
+      }
+      else
+  /*==================== RatNF, noncomm rational coeffs =================*/
+      if (strcmp(sys_cmd, "ratNF") == 0)
+      {
+        poly p,q;
+        int is, htype;
+        if ((h!=NULL) && ( (h->Typ()==POLY_CMD) || (h->Typ()==VECTOR_CMD) ) )
+        {
+          p=(poly)h->CopyD();
+          h=h->next;
+          htype = h->Typ();
+        }
+        else return TRUE;
+        if ((h!=NULL) && ( (h->Typ()==POLY_CMD) || (h->Typ()==VECTOR_CMD) ) )
+        {
+          q=(poly)h->CopyD();
+          h=h->next;
+        }
+        else return TRUE;
+        if ((h!=NULL) && (h->Typ()==INT_CMD))
+        {
+          is=(int)((long)(h->Data()));
+          res->rtyp=htype;
+          //        res->rtyp=IDEAL_CMD;
+          if (rIsPluralRing(currRing))
+          {
+            res->data = nc_rat_ReduceSpolyNew(q,p,is, currRing);
+            //        res->data = ncGCD(p,q,currRing);
+          }
+          else res->data=p;
+        }
+        else return TRUE;
+        return FALSE;
+      }
+      else
+  /*==================== RatSpoly, noncomm rational coeffs =================*/
+      if (strcmp(sys_cmd, "ratSpoly") == 0)
+      {
+        poly p,q;
+        int is;
+        if ((h!=NULL) && (h->Typ()==POLY_CMD))
+        {
+          p=(poly)h->CopyD();
+          h=h->next;
+        }
+        else return TRUE;
+        if ((h!=NULL) && (h->Typ()==POLY_CMD))
+        {
+          q=(poly)h->CopyD();
+          h=h->next;
+        }
+        else return TRUE;
+        if ((h!=NULL) && (h->Typ()==INT_CMD))
+        {
+          is=(int)((long)(h->Data()));
+          res->rtyp=POLY_CMD;
+          //        res->rtyp=IDEAL_CMD;
+          if (rIsPluralRing(currRing))
+          {
+            res->data = nc_rat_CreateSpoly(p,q,is,currRing);
+            //        res->data = ncGCD(p,q,currRing);
+          }
+          else res->data=p;
+        }
+        else return TRUE;
+        return FALSE;
+      }
+      else
+  #endif // HAVE_RATGRING
+  /*==================== Rat def =================*/
+      if (strcmp(sys_cmd, "ratVar") == 0)
+      {
+        int start,end;
+        if ((h!=NULL) && (h->Typ()==POLY_CMD))
+        {
+          start=pIsPurePower((poly)h->Data());
+          h=h->next;
+        }
+        else return TRUE;
+        if ((h!=NULL) && (h->Typ()==POLY_CMD))
+        {
+          end=pIsPurePower((poly)h->Data());
+          h=h->next;
+        }
+        else return TRUE;
+        currRing->real_var_start=start;
+        currRing->real_var_end=end;
+        return (start==0)||(end==0)||(start>end);
+      }
+      else
+  /*==================== t-rep-GB ==================================*/
+      if (strcmp(sys_cmd, "unifastmult")==0)
+      {
+        poly f = (poly)h->Data();
+        h=h->next;
+        poly g=(poly)h->Data();
+        res->rtyp=POLY_CMD;
+        res->data=unifastmult(f,g,currRing);
+        return(FALSE);
+      }
+      else
+      if (strcmp(sys_cmd, "multifastmult")==0)
+      {
+        poly f = (poly)h->Data();
+        h=h->next;
+        poly g=(poly)h->Data();
+        res->rtyp=POLY_CMD;
+        res->data=multifastmult(f,g,currRing);
+        return(FALSE);
+      }
+      else
+      if (strcmp(sys_cmd, "mults")==0)
+      {
+        res->rtyp=INT_CMD ;
+        res->data=(void*)(long) Mults();
+        return(FALSE);
+      }
+      else
+      if (strcmp(sys_cmd, "fastpower")==0)
+      {
+        ring r = currRing;
+        poly f = (poly)h->Data();
+        h=h->next;
+        int n=(int)((long)h->Data());
+        res->rtyp=POLY_CMD ;
+        res->data=(void*) pFastPower(f,n,r);
+        return(FALSE);
+      }
+      else
+      if (strcmp(sys_cmd, "normalpower")==0)
+      {
+        poly f = (poly)h->Data();
+        h=h->next;
+        int n=(int)((long)h->Data());
+        res->rtyp=POLY_CMD ;
+        res->data=(void*) pPower(pCopy(f),n);
+        return(FALSE);
+      }
+      else
+      if (strcmp(sys_cmd, "MCpower")==0)
+      {
+        ring r = currRing;
+        poly f = (poly)h->Data();
+        h=h->next;
+        int n=(int)((long)h->Data());
+        res->rtyp=POLY_CMD ;
+        res->data=(void*) pFastPowerMC(f,n,r);
+        return(FALSE);
+      }
+      else
+      if (strcmp(sys_cmd, "bit_subst")==0)
+      {
+        ring r = currRing;
+        poly outer = (poly)h->Data();
+        h=h->next;
+        poly inner=(poly)h->Data();
+        res->rtyp=POLY_CMD ;
+        res->data=(void*) uni_subst_bits(outer, inner,r);
+        return(FALSE);
+      }
+      else
+  /*==================== gcd-varianten =================*/
+      if (strcmp(sys_cmd, "gcd") == 0)
+      {
+        if (h==NULL)
+        {
+#ifdef HAVE_PLURAL
+          Print("EZGCD:%d (use EZGCD for gcd of polynomials in char 0)\n",isOn(SW_USE_EZGCD));
+          Print("EZGCD_P:%d (use EZGCD_P for gcd of polynomials in char p)\n",isOn(SW_USE_EZGCD_P));
+          Print("CRGCD:%d (use chinese Remainder for gcd of polynomials in char 0)\n",isOn(SW_USE_CHINREM_GCD));
+          Print("QGCD:%d (use QGCD for gcd of polynomials in alg. ext.)\n",isOn(SW_USE_QGCD));
+#endif
+          Print("homog:%d (use homog. test for factorization of polynomials)\n",singular_homog_flag);
+          return FALSE;
+        }
+        else
+        if ((h!=NULL) && (h->Typ()==STRING_CMD)
+        && (h->next!=NULL) && (h->next->Typ()==INT_CMD))
+        {
+          int d=(int)(long)h->next->Data();
+          char *s=(char *)h->Data();
+#ifdef HAVE_PLURAL
+          if (strcmp(s,"EZGCD")==0) { if (d) On(SW_USE_EZGCD); else Off(SW_USE_EZGCD); } else
+          if (strcmp(s,"EZGCD_P")==0) { if (d) On(SW_USE_EZGCD_P); else Off(SW_USE_EZGCD_P); } else
+          if (strcmp(s,"CRGCD")==0) { if (d) On(SW_USE_CHINREM_GCD); else Off(SW_USE_CHINREM_GCD); } else
+          if (strcmp(s,"QGCD")==0) { if (d) On(SW_USE_QGCD); else Off(SW_USE_QGCD); } else
+#endif
+          if (strcmp(s,"homog")==0) { if (d) singular_homog_flag=1; else singular_homog_flag=0; } else
+          return TRUE;
+          return FALSE;
+        }
+        else return TRUE;
+      }
+      else
+  /*==================== subring =================*/
+      if (strcmp(sys_cmd, "subring") == 0)
+      {
+        if (h!=NULL)
+        {
+          extern ring rSubring(ring r,leftv v); /* ipshell.cc*/
+          res->data=(char *)rSubring(currRing,h);
+          res->rtyp=RING_CMD;
+          return res->data==NULL;
+        }
+        else return TRUE;
+      }
+      else
+  /*==================== HNF =================*/
+  #ifdef HAVE_NTL
+      if (strcmp(sys_cmd, "HNF") == 0)
+      {
+        if (h!=NULL)
+        {
+          res->rtyp=h->Typ();
+          if (h->Typ()==MATRIX_CMD)
+          {
+            res->data=(char *)singntl_HNF((matrix)h->Data(), currRing);
+            return FALSE;
+          }
+          else if (h->Typ()==INTMAT_CMD)
+          {
+            res->data=(char *)singntl_HNF((intvec*)h->Data());
+            return FALSE;
+          }
+          else return TRUE;
+        }
+        else return TRUE;
+      }
+      else
+  /*================= probIrredTest ======================*/
+      if (strcmp (sys_cmd, "probIrredTest") == 0)
+      {
+        if (h!=NULL && (h->Typ()== POLY_CMD) && ((h->next != NULL) && h->next->Typ() == STRING_CMD))
+        {
+          CanonicalForm F= convSingPFactoryP((poly)(h->Data()), currRing);
+          char *s=(char *)h->next->Data();
+          double error= atof (s);
+          int irred= probIrredTest (F, error);
+          res->rtyp= INT_CMD;
+          res->data= (void*)(long)irred;
+          return FALSE;
+        }
+        else return TRUE;
+      }
+      else
+  #endif
+  #ifdef __CYGWIN__
+  /*==================== Python Singular =================*/
+      if (strcmp(sys_cmd, "python") == 0)
+      {
+        const char* c;
+        if ((h!=NULL) && (h->Typ()==STRING_CMD))
+        {
+          c=(const char*)h->Data();
+          if (!PyInitialized) {
+            PyInitialized = 1;
+  //          Py_Initialize();
+  //          initPySingular();
+          }
+  //      PyRun_SimpleString(c);
+          return FALSE;
+        }
+        else return TRUE;
+      }
+      else
+  /*==================== Python Singular =================
+      if (strcmp(sys_cmd, "ipython") == 0)
+      {
+        const char* c;
+        {
+          if (!PyInitialized)
+          {
+            PyInitialized = 1;
+            Py_Initialize();
+            initPySingular();
+          }
+    PyRun_SimpleString(
+  "try:                                                                                       \n\
+      __IPYTHON__                                                                             \n\
+  except NameError:                                                                           \n\
+      argv = ['']                                                                             \n\
+      banner = exit_msg = ''                                                                  \n\
+  else:                                                                                       \n\
+      # Command-line options for IPython (a list like sys.argv)                               \n\
+      argv = ['-pi1','In <\\#>:','-pi2','   .\\D.:','-po','Out<\\#>:']                        \n\
+      banner = '*** Nested interpreter ***'                                                   \n\
+      exit_msg = '*** Back in main IPython ***'                                               \n\
+                            \n\
+  # First import the embeddable shell class                                                   \n\
+  from IPython.Shell import IPShellEmbed                                                      \n\
+  # Now create the IPython shell instance. Put ipshell() anywhere in your code                \n\
+  # where you want it to open.                                                                \n\
+  ipshell = IPShellEmbed(argv,banner=banner,exit_msg=exit_msg)                                \n\
+  ipshell()");
+          return FALSE;
+        }
+      }
+      else
+                */
+
+  #endif
+/*======================= demon_list =====================*/
+  if (strcmp(sys_cmd,"denom_list")==0)
+  {
+    res->rtyp=LIST_CMD;
+    extern lists get_denom_list();
+    res->data=(lists)get_denom_list();
+    return FALSE;
+  }
+  else
+  /*==================== mpz_t loader ======================*/
+    if(strcmp(sys_cmd, "GNUmpLoad")==0)
+    {
+      if ((h != NULL) && (h->Typ() == STRING_CMD))
+      {
+        char* filename = (char*)h->Data();
+        FILE* f = fopen(filename, "r");
+        if (f == NULL)
+        {
+          WerrorS( "invalid file name (in paths use '/')");
+          return FALSE;
+        }
+        mpz_t m; mpz_init(m);
+        mpz_inp_str(m, f, 10);
+        fclose(f);
+        number n = n_InitMPZ(m, coeffs_BIGINT);
+        res->rtyp = BIGINT_CMD;
+        res->data = (void*)n;
+        return FALSE;
+      }
+      else
+      {
+        WerrorS( "expected valid file name as a string");
+        return TRUE;
+      }
+    }
+    else
+  /*==================== intvec matching ======================*/
+    /* Given two non-empty intvecs, the call
+            'system("intvecMatchingSegments", ivec, jvec);'
+         computes all occurences of jvec in ivec, i.e., it returns
+         a list of int indices k such that ivec[k..size(jvec)+k-1] = jvec.
+         If no such k exists (e.g. when ivec is shorter than jvec), an
+         intvec with the single entry 0 is being returned. */
+    if(strcmp(sys_cmd, "intvecMatchingSegments")==0)
+    {
+      if ((h       != NULL) && (h->Typ()       == INTVEC_CMD) &&
+          (h->next != NULL) && (h->next->Typ() == INTVEC_CMD) &&
+          (h->next->next == NULL))
+      {
+        intvec* ivec = (intvec*)h->Data();
+        intvec* jvec = (intvec*)h->next->Data();
+        intvec* r = new intvec(1); (*r)[0] = 0;
+        int validEntries = 0;
+        for (int k = 0; k <= ivec->rows() - jvec->rows(); k++)
+        {
+          if (memcmp(&(*ivec)[k], &(*jvec)[0],
+                       sizeof(int) * jvec->rows()) == 0)
+          {
+            if (validEntries == 0)
+              (*r)[0] = k + 1;
+            else
+            {
+              r->resize(validEntries + 1);
+              (*r)[validEntries] = k + 1;
+            }
+            validEntries++;
+          }
+        }
+        res->rtyp = INTVEC_CMD;
+        res->data = (void*)r;
+        return FALSE;
+      }
+      else
+      {
+        WerrorS("expected two non-empty intvecs as arguments");
+        return TRUE;
+      }
+    }
+    else
+  /* ================== intvecOverlap ======================= */
+    /* Given two non-empty intvecs, the call
+            'system("intvecOverlap", ivec, jvec);'
+         computes the longest intvec kvec such that ivec ends with kvec
+         and jvec starts with kvec. The length of this overlap is being
+         returned. If there is no overlap at all, then 0 is being returned. */
+    if(strcmp(sys_cmd, "intvecOverlap")==0)
+    {
+      if ((h       != NULL) && (h->Typ()       == INTVEC_CMD) &&
+            (h->next != NULL) && (h->next->Typ() == INTVEC_CMD) &&
+            (h->next->next == NULL))
+      {
+        intvec* ivec = (intvec*)h->Data();
+        intvec* jvec = (intvec*)h->next->Data();
+        int ir = ivec->rows(); int jr = jvec->rows();
+        int r = jr; if (ir < jr) r = ir;   /* r = min{ir, jr} */
+        while ((r >= 1) && (memcmp(&(*ivec)[ir - r], &(*jvec)[0],
+                                     sizeof(int) * r) != 0))
+          r--;
+        res->rtyp = INT_CMD;
+        res->data = (void*)(long)r;
+        return FALSE;
+      }
+      else
+      {
+        WerrorS("expected two non-empty intvecs as arguments");
+        return TRUE;
+      }
+    }
+    else
+  /*==================== Hensel's lemma ======================*/
+    if(strcmp(sys_cmd, "henselfactors")==0)
+    {
+      if ((h != NULL) && (h->Typ() == INT_CMD) &&
+        (h->next != NULL) && (h->next->Typ() == INT_CMD) &&
+        (h->next->next != NULL) && (h->next->next->Typ() == POLY_CMD) &&
+        (h->next->next->next != NULL) &&
+        (h->next->next->next->Typ() == POLY_CMD) &&
+        (h->next->next->next->next != NULL) &&
+        (h->next->next->next->next->Typ() == POLY_CMD) &&
+        (h->next->next->next->next->next != NULL) &&
+        (h->next->next->next->next->next->Typ() == INT_CMD) &&
+        (h->next->next->next->next->next->next == NULL))
+      {
+        int xIndex = (int)(long)h->Data();
+        int yIndex = (int)(long)h->next->Data();
+        poly hh    = (poly)h->next->next->Data();
+        poly f0    = (poly)h->next->next->next->Data();
+        poly g0    = (poly)h->next->next->next->next->Data();
+        int d      = (int)(long)h->next->next->next->next->next->Data();
+        poly f; poly g;
+        henselFactors(xIndex, yIndex, hh, f0, g0, d, f, g);
+        lists L = (lists)omAllocBin(slists_bin);
+        L->Init(2);
+        L->m[0].rtyp = POLY_CMD; L->m[0].data=(void*)f;
+        L->m[1].rtyp = POLY_CMD; L->m[1].data=(void*)g;
+        res->rtyp = LIST_CMD;
+        res->data = (char *)L;
+        return FALSE;
+      }
+      else
+      {
+        WerrorS( "expected argument list (int, int, poly, poly, poly, int)");
+        return TRUE;
+      }
+    }
+    else
+  /*==================== neworder =============================*/
+    if(strcmp(sys_cmd,"neworder")==0)
+    {
+      if ((h!=NULL) &&(h->Typ()==IDEAL_CMD))
+      {
+        res->rtyp=STRING_CMD;
+        res->data=(void *)singclap_neworder((ideal)h->Data(), currRing);
+        return FALSE;
+      }
+      else
+        WerrorS("ideal expected");
+    }
+    else
+  /*==================== Approx_Step  =================*/
+  #ifdef HAVE_PLURAL
+    if (strcmp(sys_cmd, "astep") == 0)
+    {
+      ideal I;
+      if ((h!=NULL) && (h->Typ()==IDEAL_CMD))
+      {
+        I=(ideal)h->CopyD();
+        res->rtyp=IDEAL_CMD;
+        if (rIsPluralRing(currRing)) res->data=Approx_Step(I);
+        else res->data=I;
+        setFlag(res,FLAG_STD);
+      }
+      else return TRUE;
+      return FALSE;
+    }
+    else
+  #endif
+  /*==================== PrintMat  =================*/
+  #ifdef HAVE_PLURAL
+    if (strcmp(sys_cmd, "PrintMat") == 0)
+    {
+      int a;
+      int b;
+      ring r;
+      int metric;
+      if (h!=NULL)
+      {
+        if (h->Typ()==INT_CMD)
+        {
+          a=(int)((long)(h->Data()));
+          h=h->next;
+        }
+        else if (h->Typ()==INT_CMD)
+        {
+          b=(int)((long)(h->Data()));
+          h=h->next;
+        }
+        else if (h->Typ()==RING_CMD)
+        {
+          r=(ring)h->Data();
+          h=h->next;
+        }
+        else
+          return TRUE;
+      }
+      else
+        return TRUE;
+      if ((h!=NULL) && (h->Typ()==INT_CMD))
+      {
+        metric=(int)((long)(h->Data()));
+      }
+      res->rtyp=MATRIX_CMD;
+      if (rIsPluralRing(r)) res->data=nc_PrintMat(a,b,r,metric);
+      else res->data=NULL;
+      return FALSE;
+    }
+    else
+  #endif
+/* ============ NCUseExtensions ======================== */
+  #ifdef HAVE_PLURAL
+    if(strcmp(sys_cmd,"NCUseExtensions")==0)
+    {
+      if ((h!=NULL) && (h->Typ()==INT_CMD))
+        res->data=(void *)(long)setNCExtensions( (int)((long)(h->Data())) );
+      else
+        res->data=(void *)(long)getNCExtensions();
+      res->rtyp=INT_CMD;
+      return FALSE;
+    }
+    else
+  #endif
+/* ============ NCGetType ======================== */
+  #ifdef HAVE_PLURAL
+    if(strcmp(sys_cmd,"NCGetType")==0)
+    {
+      res->rtyp=INT_CMD;
+      if( rIsPluralRing(currRing) )
+        res->data=(void *)(long)ncRingType(currRing);
+      else
+        res->data=(void *)(-1L);
+      return FALSE;
+    }
+    else
+  #endif
+/* ============ ForceSCA ======================== */
+  #ifdef HAVE_PLURAL
+    if(strcmp(sys_cmd,"ForceSCA")==0)
+    {
+      if( !rIsPluralRing(currRing) )
+        return TRUE;
+      int b, e;
+      if ((h!=NULL) && (h->Typ()==INT_CMD))
+      {
+        b = (int)((long)(h->Data()));
+        h=h->next;
+      }
+      else return TRUE;
+      if ((h!=NULL) && (h->Typ()==INT_CMD))
+      {
+        e = (int)((long)(h->Data()));
+      }
+      else return TRUE;
+      if( !sca_Force(currRing, b, e) )
+        return TRUE;
+      return FALSE;
+    }
+    else
+  #endif
+/* ============ ForceNewNCMultiplication ======================== */
+  #ifdef HAVE_PLURAL
+    if(strcmp(sys_cmd,"ForceNewNCMultiplication")==0)
+    {
+      if( !rIsPluralRing(currRing) )
+        return TRUE;
+      if( !ncInitSpecialPairMultiplication(currRing) ) // No Plural!
+        return TRUE;
+      return FALSE;
+    }
+    else
+  #endif
+/* ============ ForceNewOldNCMultiplication ======================== */
+  #ifdef HAVE_PLURAL
+    if(strcmp(sys_cmd,"ForceNewOldNCMultiplication")==0)
+    {
+      if( !rIsPluralRing(currRing) )
+        return TRUE;
+      if( !ncInitSpecialPowersMultiplication(currRing) ) // Enable Formula for Plural (depends on swiches)!
+        return TRUE;
+      return FALSE;
+    }
+    else
+  #endif
+/*==================== Error =================*/
+      Werror( "(extended) system(\"%s\",...) %s", sys_cmd, feNotImplemented );
+  }
+  return TRUE;
+}
+
+#endif // HAVE_EXTENDED_SYSTEM
+
+
diff --git a/Singular/feOpt.cc b/Singular/feOpt.cc
new file mode 100644
index 0000000..93756f1
--- /dev/null
+++ b/Singular/feOpt.cc
@@ -0,0 +1,397 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: Implementation of option buisness
+*/
+
+
+
+
+#include <kernel/mod2.h>
+
+#include <string.h>
+#include <stdlib.h>
+
+#include <factory/factory.h>
+
+#define FE_OPT_STRUCTURE
+#include "feOpt.h"
+
+#if !defined(GENERATE_OPTION_INDEX) && !defined(ESINGULAR) && !defined(TSINGULAR)
+#include <misc/options.h>
+#include <misc/sirandom.h>
+#endif
+
+#include "fehelp.h"
+
+
+const char SHORT_OPTS_STRING[] = "bdhqstvxec:r:u:";
+
+//////////////////////////////////////////////////////////////
+//
+// Generation of feOptIndex
+//
+#ifdef GENERATE_OPTION_INDEX
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+int main()
+{
+  FILE* fd;
+#ifdef ESINGULAR
+  fd = fopen("feOptES.xx", "w");
+#elif defined(TSINGULAR)
+  fd = fopen("feOptTS.xx", "w");
+#else
+  fd = fopen("feOpt.xx", "w");
+#endif
+
+  if (fd == NULL) exit(1);
+
+  int i = 0;
+
+  fputs("typedef enum\n{\n", fd);
+
+  while (feOptSpec[i].name != NULL)
+  {
+    const char* name = feOptSpec[i].name;
+    fputs("FE_OPT_", fd);
+    while (*name != 0)
+    {
+      if (*name == '-')
+      {
+        putc('_', fd);
+      }
+      else if (*name >= 97 && *name <= 122)
+      {
+        putc(*name - 32, fd);
+      }
+      else
+      {
+        putc(*name, fd);
+      }
+      name++;
+    }
+    if (i == 0)
+    {
+      fputs("=0", fd);
+    }
+    i++;
+    fputs(",\n  ", fd);
+  }
+
+  fprintf(fd, "FE_OPT_UNDEF\n} feOptIndex;\n");
+  fclose(fd);
+#ifdef ESINGULAR
+  rename("feOptES.xx", "feOptES.inc");
+#elif defined(TSINGULAR)
+  rename("feOptTS.xx", "feOptTS.inc");
+#else
+  rename("feOpt.xx", "feOpt.inc");
+#endif
+  return(0);
+}
+
+#else // ! GENERATE_OPTION_INDEX
+
+///////////////////////////////////////////////////////////////
+//
+// Getting Values
+//
+
+feOptIndex feGetOptIndex(const char* name)
+{
+  int opt = 0;
+
+  while (opt != (int) FE_OPT_UNDEF)
+  {
+    if (strcmp(feOptSpec[opt].name, name) == 0)
+      return (feOptIndex) opt;
+    opt = opt + 1;
+  }
+  return FE_OPT_UNDEF;
+}
+
+feOptIndex feGetOptIndex(int optc)
+{
+  int opt = 0;
+
+  if (optc == LONG_OPTION_RETURN) return FE_OPT_UNDEF;
+
+  while (opt != (int) FE_OPT_UNDEF)
+  {
+    if (feOptSpec[opt].val == optc)
+      return (feOptIndex) opt;
+    opt = opt + 1;
+  }
+  return FE_OPT_UNDEF;
+}
+
+///////////////////////////////////////////////////////////////
+//
+// Setting Values
+//
+//
+// Return: NULL -- everything ok
+//         "error-string" on error
+#if !defined(ESINGULAR) && !defined(TSINGULAR)
+#include <omalloc/omalloc.h>
+#include <resources/feResource.h>
+#include <kernel/oswrapper/feread.h>
+#include <kernel/oswrapper/timer.h>
+
+#include "ipshell.h"
+#include "tok.h"
+#include "sdb.h"
+#include "cntrlc.h"
+
+#include <errno.h>
+
+static const char* feOptAction(feOptIndex opt);
+const char* feSetOptValue(feOptIndex opt, char* optarg)
+{
+  if (opt == FE_OPT_UNDEF) return "option undefined";
+
+  if (feOptSpec[opt].type != feOptUntyped)
+  {
+    if (feOptSpec[opt].type != feOptString)
+    {
+      if (optarg != NULL)
+      {
+        errno = 0;
+        feOptSpec[opt].value = (void*) strtol(optarg, NULL, 10);
+        if (errno) return "invalid integer argument";
+      }
+      else
+      {
+        feOptSpec[opt].value = (void*) 0;
+      }
+    }
+    else
+    {
+      assume(feOptSpec[opt].type == feOptString);
+      if (feOptSpec[opt].set && feOptSpec[opt].value != NULL)
+        omFree(feOptSpec[opt].value);
+      if (optarg != NULL)
+        feOptSpec[opt].value = omStrDup(optarg);
+      else
+        feOptSpec[opt].value = NULL;
+      feOptSpec[opt].set = 1;
+    }
+  }
+  return feOptAction(opt);
+}
+
+const char* feSetOptValue(feOptIndex opt, int optarg)
+{
+  if (opt == FE_OPT_UNDEF) return "option undefined";
+
+  if (feOptSpec[opt].type != feOptUntyped)
+  {
+    if (feOptSpec[opt].type == feOptString)
+      return "option value needs to be an integer";
+
+    feOptSpec[opt].value = (void*)(long) optarg;
+  }
+  return feOptAction(opt);
+}
+
+static const char* feOptAction(feOptIndex opt)
+{
+  // do some special actions
+  switch(opt)
+  {
+      case FE_OPT_BATCH:
+        if (feOptSpec[FE_OPT_BATCH].value)
+          fe_fgets_stdin=fe_fgets_dummy;
+        return NULL;
+
+      case FE_OPT_HELP:
+        feOptHelp(feArgv0);
+        return NULL;
+
+      case FE_OPT_QUIET:
+        if (feOptSpec[FE_OPT_QUIET].value)
+          si_opt_2 &= ~(Sy_bit(0)|Sy_bit(V_LOAD_LIB));
+        else
+          si_opt_2 |= Sy_bit(V_LOAD_LIB)|Sy_bit(0);
+        return NULL;
+
+      case FE_OPT_NO_TTY:
+#if defined(HAVE_FEREAD) || defined(HAVE_READLINE)
+        if (feOptSpec[FE_OPT_NO_TTY].value)
+          fe_fgets_stdin=fe_fgets;
+#endif
+        return NULL;
+
+      case FE_OPT_SDB:
+      #ifdef HAVE_SDB
+        if (feOptSpec[FE_OPT_SDB].value)
+          sdb_flags = 1;
+        else
+          sdb_flags = 0;
+      #endif
+        return NULL;
+
+      case FE_OPT_VERSION:
+        {
+	char *s=versionString();
+        printf("%s",s);
+	omFree(s);
+        return NULL;
+	}
+
+      case FE_OPT_ECHO:
+        si_echo = (int) ((long)(feOptSpec[FE_OPT_ECHO].value));
+        if (si_echo < 0 || si_echo > 9)
+          return "argument of option is not in valid range 0..9";
+        return NULL;
+
+      case FE_OPT_RANDOM:
+        siRandomStart = (unsigned int) ((unsigned long)
+			                  (feOptSpec[FE_OPT_RANDOM].value));
+        siSeed=siRandomStart;
+        factoryseed(siRandomStart);
+        return NULL;
+
+      case FE_OPT_EMACS:
+        if (feOptSpec[FE_OPT_EMACS].value)
+        {
+          // print EmacsDir and InfoFile so that Emacs
+          // mode can pcik it up
+          Warn("EmacsDir: %s", (feResource('e' /*"EmacsDir"*/) != NULL ?
+                                feResource('e' /*"EmacsDir"*/) : ""));
+          Warn("InfoFile: %s", (feResource('i' /*"InfoFile"*/) != NULL ?
+                                feResource('i' /*"InfoFile"*/) : ""));
+        }
+        return NULL;
+
+      case FE_OPT_NO_WARN:
+        if (feOptSpec[FE_OPT_NO_WARN].value)
+          feWarn = FALSE;
+        else
+          feWarn = TRUE;
+        return NULL;
+
+      case FE_OPT_NO_OUT:
+        if (feOptSpec[FE_OPT_NO_OUT].value)
+          feOut = FALSE;
+        else
+          feOut = TRUE;
+        return NULL;
+
+      case FE_OPT_MIN_TIME:
+      {
+        double mintime = atof((char*) feOptSpec[FE_OPT_MIN_TIME].value);
+        if (mintime <= 0) return "invalid float argument";
+        SetMinDisplayTime(mintime);
+        return NULL;
+      }
+
+      case FE_OPT_BROWSER:
+        feHelpBrowser((char*) feOptSpec[FE_OPT_BROWSER].value, 1);
+
+      case FE_OPT_TICKS_PER_SEC:
+      {
+        int ticks = (int) ((long)(feOptSpec[FE_OPT_TICKS_PER_SEC].value));
+        if (ticks <= 0)
+          return "integer argument must be larger than 0";
+        SetTimerResolution(ticks);
+        return NULL;
+      }
+
+      default:
+        return NULL;
+  }
+}
+
+// Prints usage message
+void fePrintOptValues()
+{
+  int i = 0;
+
+  while (feOptSpec[i].name != 0)
+  {
+    if (feOptSpec[i].help != NULL && feOptSpec[i].type != feOptUntyped
+#ifndef SING_NDEBUG
+        && *(feOptSpec[i].help) != '/'
+#endif
+        )
+    {
+      if (feOptSpec[i].type == feOptString)
+      {
+        if (feOptSpec[i].value == NULL)
+        {
+          Print("// --%-15s\n", feOptSpec[i].name);
+        }
+        else
+        {
+          Print("// --%-15s \"%s\"\n", feOptSpec[i].name, (char*) feOptSpec[i].value);
+        }
+      }
+      else
+      {
+        Print("// --%-15s %d\n", feOptSpec[i].name, (int)(long)feOptSpec[i].value);
+      }
+    }
+    i++;
+  }
+}
+
+#endif // ! ESingular
+
+// Prints help message
+void feOptHelp(const char* name)
+{
+  int i = 0;
+  char tmp[20];
+#ifdef ESINGULAR
+  printf("ESingular: A Program that starts-up Singular within emacs, for\n");
+#endif
+  printf("Singular version %s -- a CAS for polynomial computations. Usage:\n", VERSION);
+  printf("   %s [options] [file1 [file2 ...]]\n", name);
+  printf("Options:\n");
+
+  while (feOptSpec[i].name != 0)
+  {
+    if (feOptSpec[i].help != NULL
+#ifdef SING_NDEBUG
+        && *(feOptSpec[i].help) != '/'
+#endif
+        )
+    {
+      if (feOptSpec[i].has_arg > 0)
+      {
+        if  (feOptSpec[i].has_arg > 1)
+          sprintf(tmp, "%s[=%s]", feOptSpec[i].name, feOptSpec[i].arg_name);
+        else
+          sprintf(tmp, "%s=%s", feOptSpec[i].name, feOptSpec[i].arg_name);
+
+        printf(" %c%c --%-19s %s\n",
+               (feOptSpec[i].val != 0 ? '-' : ' '),
+               (feOptSpec[i].val != 0 ? feOptSpec[i].val : ' '),
+               tmp,
+               feOptSpec[i].help);
+      }
+      else
+      {
+        printf(" %c%c --%-19s %s\n",
+               (feOptSpec[i].val != 0 ? '-' : ' '),
+               (feOptSpec[i].val != 0 ? feOptSpec[i].val : ' '),
+               feOptSpec[i].name,
+               feOptSpec[i].help);
+      }
+    }
+    i++;
+  }
+
+  printf("\nFor more information, type `help;' from within Singular or visit\n");
+  printf("http://www.singular.uni-kl.de or consult the\n");
+  printf("Singular manual (available as on-line info or html manual).\n");
+}
+
+
+
+#endif // GENERATE_OPTION_INDEX
diff --git a/Singular/feOpt.h b/Singular/feOpt.h
new file mode 100644
index 0000000..c85fb4c
--- /dev/null
+++ b/Singular/feOpt.h
@@ -0,0 +1,82 @@
+#ifndef FEOPTS_H
+#define FEOPTS_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: Declarations for working with Options
+*/
+
+#include <Singular/fegetopt.h>
+
+#include <Singular/feOptTab.h>
+
+extern const char SHORT_OPTS_STRING[];
+
+/* specifies format of options */
+extern struct fe_option feOptSpec[];
+
+/* provides feOptIndex enum type for fast accesses to feOptSpec */
+#if ! defined(GENERATE_DEPEND)
+
+# ifdef ESINGULAR
+#  include <Singular/feOptES.inc>
+# elif defined(TSINGULAR)
+#  include <Singular/feOptTS.inc>
+# else
+#  include <Singular/feOpt.inc>
+# endif
+
+#else
+typedef enum {FE_OPT_UNDEF}  feOptIndex;
+#endif
+
+
+void feOptHelp(const char* name);
+
+#ifdef __cplusplus
+
+static inline void* feOptValue(feOptIndex opt)
+{
+  return feOptSpec[(int)opt].value;
+}
+inline int feOptValue(feOptIndex opt, char** val)
+{
+  if (opt != FE_OPT_UNDEF && feOptSpec[(int)opt].type == feOptString)
+  {
+    *val = (char*) feOptSpec[(int)opt].value;
+    return TRUE;
+  }
+  *val = NULL;
+  return FALSE;
+}
+inline int feOptValue(feOptIndex opt, int* val)
+{
+  if (opt != FE_OPT_UNDEF && feOptSpec[(int)opt].type != feOptString)
+  {
+    *val = (int) ((long)(feOptSpec[(int)opt].value));
+    return TRUE;
+  }
+  *val = 0;
+  return FALSE;
+}
+
+// maps name to otions
+feOptIndex feGetOptIndex(const char* name);
+feOptIndex feGetOptIndex(int optc);
+
+// Setting option values:
+// Return: NULL -- everything ok
+//         "error-string" on error
+
+// opt->type must be feOptInt or feOptBool
+const char* feSetOptValue(feOptIndex opt, int optarg);
+// for opt->type != feOptString, optarg is converted
+// to an int
+const char* feSetOptValue(feOptIndex opt, char* optarg);
+
+void fePrintOptValues();
+
+#endif /* __cplusplus */
+
+#endif /*  FEOPTS_H */
diff --git a/Singular/feOptES.inc b/Singular/feOptES.inc
new file mode 100644
index 0000000..12c090b
--- /dev/null
+++ b/Singular/feOptES.inc
@@ -0,0 +1,34 @@
+typedef enum
+{
+FE_OPT_EMACS=0,
+  FE_OPT_EMACS_DIR,
+  FE_OPT_EMACS_LOAD,
+  FE_OPT_SINGULAR,
+  FE_OPT_NO_CALL,
+  FE_OPT_BATCH,
+  FE_OPT_EXECUTE,
+  FE_OPT_SDB,
+  FE_OPT_ECHO,
+  FE_OPT_HELP,
+  FE_OPT_QUIET,
+  FE_OPT_SORT,
+  FE_OPT_RANDOM,
+  FE_OPT_NO_TTY,
+  FE_OPT_USER_OPTION,
+  FE_OPT_VERSION,
+  FE_OPT_ALLOW_NET,
+  FE_OPT_BROWSER,
+  FE_OPT_CNTRLC,
+  FE_OPT_NO_STDLIB,
+  FE_OPT_NO_RC,
+  FE_OPT_NO_WARN,
+  FE_OPT_NO_OUT,
+  FE_OPT_NO_SHELL,
+  FE_OPT_MIN_TIME,
+  FE_OPT_CPUS,
+  FE_OPT_MPPORT,
+  FE_OPT_MPHOST,
+  FE_OPT_LINK,
+  FE_OPT_TICKS_PER_SEC,
+  FE_OPT_UNDEF
+} feOptIndex;
diff --git a/Singular/feOptGen.cc b/Singular/feOptGen.cc
new file mode 100644
index 0000000..daf64bf
--- /dev/null
+++ b/Singular/feOptGen.cc
@@ -0,0 +1,86 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: Implementation of option business
+*/
+
+#include <string.h>
+#include <stdlib.h>
+
+
+
+
+#include <kernel/mod2.h>
+
+#define FE_OPT_STRUCTURE
+
+#include "feOptGen.h"
+
+#include "fehelp.h"
+
+const char SHORT_OPTS_STRING[] = "bdhqstvxec:r:u:";
+
+//////////////////////////////////////////////////////////////
+//
+// Generation of feOptIndex
+//
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+int main()
+{
+  FILE* fd;
+#ifdef ESINGULAR
+  fd = fopen("feOptES.xx", "w");
+#elif defined(TSINGULAR)
+  fd = fopen("feOptTS.xx", "w");
+#else
+  fd = fopen("feOpt.xx", "w");
+#endif
+
+  if (fd == NULL) exit(1);
+
+  int i = 0;
+
+  fputs("typedef enum\n{\n", fd);
+
+  while (feOptSpec[i].name != NULL)
+  {
+    const char* name = feOptSpec[i].name;
+    fputs("FE_OPT_", fd);
+    while (*name != 0)
+    {
+      if (*name == '-')
+      {
+        putc('_', fd);
+      }
+      else if (*name >= 97 && *name <= 122)
+      {
+        putc(*name - 32, fd);
+      }
+      else
+      {
+        putc(*name, fd);
+      }
+      name++;
+    }
+    if (i == 0)
+    {
+      fputs("=0", fd);
+    }
+    i++;
+    fputs(",\n  ", fd);
+  }
+
+  fprintf(fd, "FE_OPT_UNDEF\n} feOptIndex;\n");
+  fclose(fd);
+#ifdef ESINGULAR
+  rename("feOptES.xx", "feOptES.inc");
+#elif defined(TSINGULAR)
+  rename("feOptTS.xx", "feOptTS.inc");
+#else
+  rename("feOpt.xx", "feOpt.inc");
+#endif
+  return(0);
+}
diff --git a/Singular/feOptGen.h b/Singular/feOptGen.h
new file mode 100644
index 0000000..7266645
--- /dev/null
+++ b/Singular/feOptGen.h
@@ -0,0 +1,17 @@
+#ifndef FEOPTSGEN_H
+#define FEOPTSGEN_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: Declarations for working with Options
+*/
+
+#include <Singular/fegetopt.h>
+
+extern const char SHORT_OPTS_STRING[];
+
+#include <Singular/feOptTab.h>
+typedef enum {FE_OPT_UNDEF}  feOptIndex;
+
+#endif /*  FEOPTSGEN_H */
diff --git a/Singular/feOptTS.inc b/Singular/feOptTS.inc
new file mode 100644
index 0000000..bb40b83
--- /dev/null
+++ b/Singular/feOptTS.inc
@@ -0,0 +1,33 @@
+typedef enum
+{
+FE_OPT_XTERM=0,
+  FE_OPT_SINGULAR,
+  FE_OPT_NO_CALL,
+  FE_OPT_BATCH,
+  FE_OPT_EXECUTE,
+  FE_OPT_SDB,
+  FE_OPT_ECHO,
+  FE_OPT_HELP,
+  FE_OPT_QUIET,
+  FE_OPT_SORT,
+  FE_OPT_RANDOM,
+  FE_OPT_NO_TTY,
+  FE_OPT_USER_OPTION,
+  FE_OPT_VERSION,
+  FE_OPT_ALLOW_NET,
+  FE_OPT_BROWSER,
+  FE_OPT_CNTRLC,
+  FE_OPT_EMACS,
+  FE_OPT_NO_STDLIB,
+  FE_OPT_NO_RC,
+  FE_OPT_NO_WARN,
+  FE_OPT_NO_OUT,
+  FE_OPT_NO_SHELL,
+  FE_OPT_MIN_TIME,
+  FE_OPT_CPUS,
+  FE_OPT_MPPORT,
+  FE_OPT_MPHOST,
+  FE_OPT_LINK,
+  FE_OPT_TICKS_PER_SEC,
+  FE_OPT_UNDEF
+} feOptIndex;
diff --git a/Singular/feOptTab.h b/Singular/feOptTab.h
new file mode 100644
index 0000000..b776533
--- /dev/null
+++ b/Singular/feOptTab.h
@@ -0,0 +1,159 @@
+#ifndef FE_OPT_TAB_H
+#define FE_OPT_TAB_H
+
+#define LONG_OPTION_RETURN 13
+
+// Define here which cmd-line options are recognized
+#ifndef FE_OPT_STRUCTURE
+extern struct fe_option feOptSpec[];
+#else
+struct fe_option feOptSpec[] =
+{
+//
+//  Has to be of the form
+//    {name, has_arg, val,
+//     arg_name, help, type, value, set}
+//  where:
+//
+//        name   is the name of the long option.
+//
+//        has_arg
+//               is:  no_argument (or 0) if the option does not take
+//               an argument, required_argument (or 1) if the option
+//               requires  an  argument, or optional_argument (or 2)
+//               if the option takes an optional argument.
+//
+//        val    is  the  value  to  return,  or  to  load  into the
+//               variable pointed to by flag.
+//               NEEDS TO BE LONG_OPTION_RETURN, for long option
+//                           short option char,  for short option
+//
+//        arg_name if set, uses this value as name for argument in
+//                display of help
+//
+//        help  one-line description of option
+//
+//        type  one of feOptUntyped (value is never set),
+//                     feOptBool, feOptInt, feOptString
+//
+//        value (default) value of option
+//
+//       set   only relevant for feOptString:
+//             1: if value different from default value
+//             0: otherwise
+//
+// The order in which options are specified is the order in which
+// their help is printed on -h
+//
+// Options whose hel starts with an "//" are considered undocumented,
+// i.e., their help is not printed on -h
+//
+#if defined(ESINGULAR) || defined(TSINGULAR)
+#ifdef ESINGULAR
+// options only relevant for ESINGULAR
+  {"emacs",         required_argument,      LONG_OPTION_RETURN,
+   "EMACS",     "Use EMACS as emacs program to run Singular",          feOptString, 0,   0},
+
+  {"emacs-dir",         required_argument,  LONG_OPTION_RETURN,
+   "DIR",       "Use DIR as directory to look for emacs lisp files",   feOptString, 0,   0},
+
+  {"emacs-load",        required_argument,  LONG_OPTION_RETURN,
+   "FILE",      "Load FILE on emacs start-up, instead of default",     feOptString, 0,   0},
+#else
+  {"xterm",         required_argument,      LONG_OPTION_RETURN,
+   "XTERM",     "Use XTERM as terminal program to run Singular",       feOptString, 0,   0},
+#endif
+
+  {"singular",          required_argument,  LONG_OPTION_RETURN,
+   "PROG",      "Start PROG as Singular program within emacs",         feOptString, 0,   0},
+
+  {"no-call",     no_argument,        LONG_OPTION_RETURN,
+   0,          "Do not start program. Print call to stdout",           feOptBool,   0,   0},
+#endif
+
+  {"batch",             no_argument,        'b',
+   0,          "Run in batch mode",                                    feOptBool,    0,     0},
+
+  {"execute",           required_argument,  'c',
+   "STRING",   "Execute STRING on start-up",                           feOptString, 0,   0},
+
+  {"sdb",               no_argument,        'd',
+   0,          "Enable source code debugger (experimental)",           feOptBool,    0,      0},
+
+  {"echo",              optional_argument,  'e',
+   "VAL",       "Set value of variable `echo' to (integer) VAL",        feOptInt,    0,      0},
+
+  {"help",              no_argument,        'h',
+   0,          "Print help message and exit",                          feOptUntyped,    0,      0},
+
+  {"quiet",             no_argument,        'q',
+   0,          "Do not print start-up banner and lib load messages",   feOptBool,    0,      0},
+  {"sort",             no_argument,        's',
+   0,          "// Sort NTL results",                                  feOptBool,    0,      0},
+
+  {"random",            required_argument,  'r',
+   "SEED",     "Seed random generator with (integer) SEED",            feOptInt,    0,      0},
+
+  {"no-tty",            no_argument,        't',
+   0,          "Do not redefine the terminal characteristics",         feOptBool,    0,      0},
+
+  {"user-option",       required_argument,  'u',
+   "STRING",   "Return STRING on `system(\"--user-option\")'",         feOptString, 0,   0},
+
+  {"version",           no_argument,        'v',
+   0,          "Print extended version and configuration info",        feOptUntyped,    0,      0},
+
+
+  {"allow-net",         no_argument,        LONG_OPTION_RETURN,
+   0,          "Allow to fetch (html) help pages from the net",                feOptBool,    0,      0},
+
+  {"browser",           required_argument,  LONG_OPTION_RETURN,
+   "BROWSER",  "Display help in BROWSER (see help.cnf)",       feOptString, 0,   0},
+
+  {"cntrlc",           optional_argument,   LONG_OPTION_RETURN,
+   "CHAR",     "Automatic answer for CTRL-C prompt",                   feOptString, 0,   0},
+#ifndef ESINGULAR
+  {"emacs",             no_argument,        LONG_OPTION_RETURN,
+   0,          "Set defaults for running within emacs",                feOptBool,    0,      0},
+#endif
+
+  {"no-stdlib",         no_argument,        LONG_OPTION_RETURN,
+   0,          "Do not load `standard.lib' on start-up",               feOptBool,    0,      0},
+
+  {"no-rc",             no_argument,        LONG_OPTION_RETURN,
+   0,          "Do not execute `.singularrc' file(s) on start-up",     feOptBool,    0,      0},
+
+  {"no-warn",           no_argument,        LONG_OPTION_RETURN,
+   0,          "Do not display warning messages",                      feOptBool,    0,      0},
+
+  {"no-out",            no_argument,        LONG_OPTION_RETURN,
+   0,          "Suppress all output",                                  feOptBool,    0,      0},
+
+  {"no-shell",          no_argument,        LONG_OPTION_RETURN,
+   0,          "Restricted mode: prohibit shell escape commands and links", feOptBool,  0,      0},
+
+  {"min-time",          required_argument,  LONG_OPTION_RETURN,
+  "SECS",     "Do not display times smaller than SECS (in seconds)",   feOptString, (void*) "0.5",  0},
+
+  {"cpus",            required_argument,    LONG_OPTION_RETURN,
+   "#CPUs",   "maximal number of CPUs to use",                         feOptInt,    (void*)2,      0},
+
+
+  {"MPport",           required_argument,   LONG_OPTION_RETURN,
+   "PORT",     "Use PORT number for conections",                       feOptString,    0,      0},
+
+  {"MPhost",           required_argument,   LONG_OPTION_RETURN,
+   "HOST",     "Use HOST for connections",                             feOptString,    0,   0},
+
+  {"link",           required_argument,   LONG_OPTION_RETURN,
+   "LINK",     "Use LINK for connections",                             feOptString,    0,   0},
+
+  {"ticks-per-sec",     required_argument,  LONG_OPTION_RETURN,
+   "TICKS",     "Sets unit of timer to TICKS per second",               feOptInt,    (void*)1,      0},
+
+// terminator -- do NOT remove
+  { 0, 0, 0, 0, 0, feOptInt, 0, 0}
+};
+
+#endif
+#endif
diff --git a/Singular/febase.cc b/Singular/febase.cc
new file mode 100644
index 0000000..0b667ba
--- /dev/null
+++ b/Singular/febase.cc
@@ -0,0 +1,92 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: i/o system
+*/
+#include <kernel/mod2.h>
+
+/* I need myfread in standalone_parser */
+#ifndef STANDALONE_PARSER
+
+#include <omalloc/omalloc.h>
+#include <reporter/reporter.h>
+#include <misc/options.h>
+
+//#include <Singular/febase.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <misc/mylimits.h>
+#include <stdarg.h>
+#include <sys/stat.h>
+#include <ctype.h>
+#include <unistd.h>
+
+#ifdef HAVE_PWD_H
+#include <pwd.h>
+#endif
+
+#define fePutChar(c) fputc((unsigned char)(c),stdout)
+/*0 implementation */
+
+// char fe_promptstr[] ="  ";
+
+// output/print buffer:
+// line buffer for reading:
+// minimal value for MAX_FILE_BUFFER: 4*4096 - see Tst/Long/gcd0_l.tst
+// this is an upper limit for the size of monomials/numbers read via the interpreter
+#define MAX_FILE_BUFFER 4*4096
+
+int     si_echo = 0;
+int     printlevel = 0;
+int     colmax = 80;
+char    prompt_char = '>'; /*1 either '>' or '.'*/
+int     yylineno  = 0;
+int  myynest = -1;
+int  traceit = 0;
+char       my_yylinebuf[80];
+
+
+#if 0
+void monitor(char* s, int mode)
+{
+  if (feProt)
+  {
+    fclose(feProtFile);
+    feProt = 0;
+  }
+  if ((s!=NULL) && (*s!='\0'))
+  {
+    feProtFile = myfopen(s,"w");
+    if (feProtFile==NULL)
+    {
+      Werror("cannot open %s",s);
+      feProt=0;
+    }
+    else
+      feProt = mode;
+  }
+}
+#else
+void monitor(void *F, int mode)
+{
+  if (feProt)
+  {
+    fclose(feProtFile);
+    feProt = 0;
+  }
+  if (F!=NULL)
+  {
+    feProtFile = (FILE *)F;
+    feProt = mode;
+  }
+}
+#endif
+
+
+#else /* ! STANDALONE_PARSER */
+#include <stdio.h>
+
+#endif
+
diff --git a/Singular/fegetopt.c b/Singular/fegetopt.c
new file mode 100644
index 0000000..d44f37c
--- /dev/null
+++ b/Singular/fegetopt.c
@@ -0,0 +1,753 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+
+/* Getopt for GNU.
+   NOTE: getopt is now part of the C library, so if you don't know what
+   "Keep this file name-space clean" means, talk to roland at gnu.ai.mit.edu
+   before changing it!
+
+   Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94
+        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, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+/*
+   obachman 9/99: adapted to Singular by
+    * adding prefix fe_ to global variables
+    * extended fe_option structure
+*/
+
+
+
+
+
+#include <kernel/mod2.h>
+
+#ifndef __STDC__
+#  ifndef const
+#    define const
+#  endif
+#endif
+
+/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.  */
+#ifndef _NO_PROTO
+#define _NO_PROTO
+#endif
+
+#include <stdio.h>
+/* #include "tailor.h" */
+
+/* Comment out all this code if we are using the GNU C Library, and are not
+   actually compiling the library itself.  This code is part of the GNU C
+   Library, but also included in many other GNU distributions.  Compiling
+   and linking in this code is a waste when using the GNU C library
+   (especially if it is a shared library).  Rather than having every GNU
+   program understand `configure --with-gnu-libc' and omit the object files,
+   it is simpler to just do this in the source for each such file.  */
+
+/* This needs to come after some library #include
+   to get __GNU_LIBRARY__ defined.  */
+#ifdef  __GNU_LIBRARY__
+/* Don't include stdlib.h for non-GNU C libraries because some of them
+   contain conflicting prototypes for getopt.  */
+#include <stdlib.h>
+#endif  /* GNU C library.  */
+
+/* If GETOPT_COMPAT is defined, `+' as well as `--' can introduce a
+   long-named option.  Because this is not POSIX.2 compliant, it is
+   being phased out.  */
+/* #define GETOPT_COMPAT */
+
+/* This version of `getopt' appears to the caller like standard Unix `getopt'
+   but it behaves differently for the user, since it allows the user
+   to intersperse the options with the other arguments.
+
+   As `getopt' works, it permutes the elements of ARGV so that,
+   when it is done, all the options precede everything else.  Thus
+   all application programs are extended to handle flexible argument order.
+
+   Setting the environment variable POSIXLY_CORRECT disables permutation.
+   Then the behavior is completely standard.
+
+   GNU application programs can use a third alternative mode in which
+   they can distinguish the relative order of options and other arguments.  */
+
+#include <Singular/fegetopt.h>
+
+/* For communication from `getopt' to the caller.
+   When `getopt' finds an option that takes an argument,
+   the argument value is returned here.
+   Also, when `ordering' is RETURN_IN_ORDER,
+   each non-option ARGV-element is returned here.  */
+
+char *fe_optarg = 0;
+
+/* Index in ARGV of the next element to be scanned.
+   This is used for communication to and from the caller
+   and for communication between successive calls to `getopt'.
+
+   On entry to `getopt', zero means this is the first call; initialize.
+
+   When `getopt' returns EOF, this is the index of the first of the
+   non-option elements that the caller should itself scan.
+
+   Otherwise, `fe_optind' communicates from one call to the next
+   how much of ARGV has been scanned so far.  */
+
+/* XXX 1003.2 says this must be 1 before any call.  */
+int fe_optind = 0;
+
+/* The next char to be scanned in the option-element
+   in which the last option character we returned was found.
+   This allows us to pick up the scan where we left off.
+
+   If this is zero, or a null string, it means resume the scan
+   by advancing to the next ARGV-element.  */
+
+static char *nextchar;
+
+/* Callers store zero here to inhibit the error message
+   for unrecognized options.  */
+
+int fe_opterr = 1;
+
+/* Set to an option character which was unrecognized.
+   This must be initialized on some systems to avoid linking in the
+   system's own getopt implementation.  */
+
+#define BAD_OPTION '\0'
+int fe_optopt = BAD_OPTION;
+
+/* Describe how to deal with options that follow non-option ARGV-elements.
+
+   If the caller did not specify anything,
+   the default is REQUIRE_ORDER if the environment variable
+   POSIXLY_CORRECT is defined, PERMUTE otherwise.
+
+   REQUIRE_ORDER means don't recognize them as options;
+   stop option processing when the first non-option is seen.
+   This is what Unix does.
+   This mode of operation is selected by either setting the environment
+   variable POSIXLY_CORRECT, or using `+' as the first character
+   of the list of option characters.
+
+   PERMUTE is the default.  We permute the contents of ARGV as we scan,
+   so that eventually all the non-options are at the end.  This allows options
+   to be given in any order, even with programs that were not written to
+   expect this.
+
+   RETURN_IN_ORDER is an option available to programs that were written
+   to expect options and other ARGV-elements in any order and that care about
+   the ordering of the two.  We describe each non-option ARGV-element
+   as if it were the argument of an option with character code 1.
+   Using `-' as the first character of the list of option characters
+   selects this mode of operation.
+
+   The special argument `--' forces an end of option-scanning regardless
+   of the value of `ordering'.  In the case of RETURN_IN_ORDER, only
+   `--' can cause `getopt' to return EOF with `fe_optind' != ARGC.  */
+
+static enum
+{
+  REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
+} ordering;
+
+#ifdef  __GNU_LIBRARY__
+/* We want to avoid inclusion of string.h with non-GNU libraries
+   because there are many ways it can cause trouble.
+   On some systems, it contains special magic macros that don't work
+   in GCC.  */
+#include <string.h>
+#define my_index        strchr
+#define my_strlen       strlen
+#else
+
+/* Avoid depending on library functions or files
+   whose names are inconsistent.  */
+
+#if __STDC__ || defined(PROTO)
+extern char *getenv(const char *name);
+extern int  strcmp (const char *s1, const char *s2);
+extern int  strncmp(const char *s1, const char *s2, size_t n);
+
+static int my_strlen(const char *s);
+static const char *my_index (const char *str, int chr);
+#else
+extern char *getenv ();
+#endif
+
+static int my_strlen (const char *str)
+{
+  int n = 0;
+  while (*str++)
+    n++;
+  return n;
+}
+
+static const char * my_index (const char *str, int chr)
+{
+  while (*str)
+    {
+      if (*str == chr)
+        return (const char *) str;
+      str++;
+    }
+  return 0;
+}
+
+#endif                          /* GNU C library.  */
+
+/* Handle permutation of arguments.  */
+
+/* Describe the part of ARGV that contains non-options that have
+   been skipped.  `first_nonopt' is the index in ARGV of the first of them;
+   `last_nonopt' is the index after the last of them.  */
+
+static int first_nonopt;
+static int last_nonopt;
+
+/* Exchange two adjacent subsequences of ARGV.
+   One subsequence is elements [first_nonopt,last_nonopt)
+   which contains all the non-options that have been skipped so far.
+   The other is elements [last_nonopt,fe_optind), which contains all
+   the options processed since those non-options were skipped.
+
+   `first_nonopt' and `last_nonopt' are relocated so that they describe
+   the new indices of the non-options in ARGV after they are moved.
+
+   To perform the swap, we first reverse the order of all elements. So
+   all options now come before all non options, but they are in the
+   wrong order. So we put back the options and non options in original
+   order by reversing them again. For example:
+       original input:      a b c -x -y
+       reverse all:         -y -x c b a
+       reverse options:     -x -y c b a
+       reverse non options: -x -y a b c
+*/
+
+#if __STDC__ || defined(PROTO)
+static void exchange (char **argv);
+#endif
+
+static void exchange (char **argv)
+{
+  char *temp, **first, **last;
+
+  /* Reverse all the elements [first_nonopt, fe_optind) */
+  first = &argv[first_nonopt];
+  last  = &argv[fe_optind-1];
+  while (first < last) {
+    temp = *first; *first = *last; *last = temp; first++; last--;
+  }
+  /* Put back the options in order */
+  first = &argv[first_nonopt];
+  first_nonopt += (fe_optind - last_nonopt);
+  last  = &argv[first_nonopt - 1];
+  while (first < last) {
+    temp = *first; *first = *last; *last = temp; first++; last--;
+  }
+
+  /* Put back the non options in order */
+  first = &argv[first_nonopt];
+  last_nonopt = fe_optind;
+  last  = &argv[last_nonopt-1];
+  while (first < last) {
+    temp = *first; *first = *last; *last = temp; first++; last--;
+  }
+}
+
+/* Scan elements of ARGV (whose length is ARGC) for option characters
+   given in OPTSTRING.
+
+   If an element of ARGV starts with '-', and is not exactly "-" or "--",
+   then it is an option element.  The characters of this element
+   (aside from the initial '-') are option characters.  If `getopt'
+   is called repeatedly, it returns successively each of the option characters
+   from each of the option elements.
+
+   If `getopt' finds another option character, it returns that character,
+   updating `fe_optind' and `nextchar' so that the next call to `getopt' can
+   resume the scan with the following option character or ARGV-element.
+
+   If there are no more option characters, `getopt' returns `EOF'.
+   Then `fe_optind' is the index in ARGV of the first ARGV-element
+   that is not an option.  (The ARGV-elements have been permuted
+   so that those that are not options now come last.)
+
+   OPTSTRING is a string containing the legitimate option characters.
+   If an option character is seen that is not listed in OPTSTRING,
+   return BAD_OPTION after printing an error message.  If you set `fe_opterr' to
+   zero, the error message is suppressed but we still return BAD_OPTION.
+
+   If a char in OPTSTRING is followed by a colon, that means it wants an arg,
+   so the following text in the same ARGV-element, or the text of the following
+   ARGV-element, is returned in `fe_optarg'.  Two colons mean an option that
+   wants an optional arg; if there is text in the current ARGV-element,
+   it is returned in `fe_optarg', otherwise `fe_optarg' is set to zero.
+
+   If OPTSTRING starts with `-' or `+', it requests different methods of
+   handling the non-option ARGV-elements.
+   See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
+
+   Long-named options begin with `--' instead of `-'.
+   Their names may be abbreviated as long as the abbreviation is unique
+   or is an exact match for some defined option.  If they have an
+   argument, it follows the option name in the same ARGV-element, separated
+   from the option name by a `=', or else the in next ARGV-element.
+   When `getopt' finds a long-named option, it returns
+   the value of the option's `val' field.
+
+   The elements of ARGV aren't really const, because we permute them.
+   But we pretend they're const in the prototype to be compatible
+   with other systems.
+
+   LONGOPTS is a vector of `struct fe_option' terminated by an
+   element containing a name which is zero.
+
+   LONGIND returns the index in LONGOPT of the long-named option found.
+   It is only valid when a long-named option has been found by the most
+   recent call.
+
+   If LONG_ONLY is nonzero, '-' as well as '--' can introduce
+   long-named options.  */
+
+int _fe_getopt_internal (
+     int argc,
+     char *const *argv,
+     const char *optstring,
+     const struct fe_option *longopts,
+     int *longind,
+     int long_only)
+{
+  int option_index;
+
+  fe_optarg = 0;
+
+  /* Initialize the internal data when the first call is made.
+     Start processing options with ARGV-element 1 (since ARGV-element 0
+     is the program name); the sequence of previously skipped
+     non-option ARGV-elements is empty.  */
+
+  if (fe_optind == 0)
+    {
+      first_nonopt = last_nonopt = fe_optind = 1;
+
+      nextchar = NULL;
+
+      /* Determine how to handle the ordering of options and nonoptions.  */
+
+      if (optstring[0] == '-')
+        {
+          ordering = RETURN_IN_ORDER;
+          ++optstring;
+        }
+      else if (optstring[0] == '+')
+        {
+          ordering = REQUIRE_ORDER;
+          ++optstring;
+        }
+      else if (getenv ("POSIXLY_CORRECT") != NULL)
+        ordering = REQUIRE_ORDER;
+      else
+        ordering = PERMUTE;
+    }
+
+  if (nextchar == NULL || *nextchar == '\0')
+    {
+      if (ordering == PERMUTE)
+        {
+          /* If we have just processed some options following some non-options,
+             exchange them so that the options come first.  */
+
+          if (first_nonopt != last_nonopt && last_nonopt != fe_optind)
+            exchange ((char **) argv);
+          else if (last_nonopt != fe_optind)
+            first_nonopt = fe_optind;
+
+          /* Now skip any additional non-options
+             and extend the range of non-options previously skipped.  */
+
+          while (fe_optind < argc
+                 && (argv[fe_optind][0] != '-' || argv[fe_optind][1] == '\0')
+#ifdef GETOPT_COMPAT
+                 && (longopts == NULL
+                     || argv[fe_optind][0] != '+' || argv[fe_optind][1] == '\0')
+#endif                          /* GETOPT_COMPAT */
+                 )
+            fe_optind++;
+          last_nonopt = fe_optind;
+        }
+
+      /* Special ARGV-element `--' means premature end of options.
+         Skip it like a null option,
+         then exchange with previous non-options as if it were an option,
+         then skip everything else like a non-option.  */
+
+      if (fe_optind != argc && !strcmp (argv[fe_optind], "--"))
+        {
+          fe_optind++;
+
+          if (first_nonopt != last_nonopt && last_nonopt != fe_optind)
+            exchange ((char **) argv);
+          else if (first_nonopt == last_nonopt)
+            first_nonopt = fe_optind;
+          last_nonopt = argc;
+
+          fe_optind = argc;
+        }
+
+      /* If we have done all the ARGV-elements, stop the scan
+         and back over any non-options that we skipped and permuted.  */
+
+      if (fe_optind == argc)
+        {
+          /* Set the next-arg-index to point at the non-options
+             that we previously skipped, so the caller will digest them.  */
+          if (first_nonopt != last_nonopt)
+            fe_optind = first_nonopt;
+          return EOF;
+        }
+
+      /* If we have come to a non-option and did not permute it,
+         either stop the scan or describe it to the caller and pass it by.  */
+
+      if ((argv[fe_optind][0] != '-' || argv[fe_optind][1] == '\0')
+#ifdef GETOPT_COMPAT
+          && (longopts == NULL
+              || argv[fe_optind][0] != '+' || argv[fe_optind][1] == '\0')
+#endif                          /* GETOPT_COMPAT */
+          )
+        {
+          if (ordering == REQUIRE_ORDER)
+            return EOF;
+          fe_optarg = argv[fe_optind++];
+          return 1;
+        }
+
+      /* We have found another option-ARGV-element.
+         Start decoding its characters.  */
+
+      nextchar = (argv[fe_optind] + 1
+                  + (longopts != NULL && argv[fe_optind][1] == '-'));
+    }
+
+  if (longopts != NULL
+      && ((argv[fe_optind][0] == '-'
+           && (argv[fe_optind][1] == '-' || long_only))
+#ifdef GETOPT_COMPAT
+          || argv[fe_optind][0] == '+'
+#endif                          /* GETOPT_COMPAT */
+          ))
+    {
+      const struct fe_option *p;
+      char *s = nextchar;
+      int exact = 0;
+      int ambig = 0;
+      const struct fe_option *pfound = NULL;
+      int indfound = 0;
+
+      while (*s && *s != '=')
+        s++;
+
+      /* Test all options for either exact match or abbreviated matches.  */
+      for (p = longopts, option_index = 0; p->name;
+           p++, option_index++)
+        if (!strncmp (p->name, nextchar, s - nextchar))
+          {
+            if (s - nextchar == my_strlen (p->name))
+              {
+                /* Exact match found.  */
+                pfound = p;
+                indfound = option_index;
+                exact = 1;
+                break;
+              }
+            else if (pfound == NULL)
+              {
+                /* First nonexact match found.  */
+                pfound = p;
+                indfound = option_index;
+              }
+            else
+              /* Second nonexact match found.  */
+              ambig = 1;
+          }
+
+      if (ambig && !exact)
+        {
+          if (fe_opterr)
+            fprintf (stderr, "%s: option `%s' is ambiguous\n",
+                     argv[0], argv[fe_optind]);
+          nextchar += my_strlen (nextchar);
+          fe_optind++;
+          return BAD_OPTION;
+        }
+
+      if (pfound != NULL)
+        {
+          option_index = indfound;
+          fe_optind++;
+          if (*s)
+            {
+              /* Don't test has_arg with >, because some C compilers don't
+                 allow it to be used on enums.  */
+              if (pfound->has_arg)
+                fe_optarg = s + 1;
+              else
+                {
+                  if (fe_opterr)
+                    {
+                      if (argv[fe_optind - 1][1] == '-')
+                        /* --option */
+                        fprintf (stderr,
+                                 "%s: option `--%s' doesn't allow an argument\n",
+                                 argv[0], pfound->name);
+                      else
+                        /* +option or -option */
+                        fprintf (stderr,
+                             "%s: option `%c%s' doesn't allow an argument\n",
+                             argv[0], argv[fe_optind - 1][0], pfound->name);
+                    }
+                  nextchar += my_strlen (nextchar);
+                  return BAD_OPTION;
+                }
+            }
+          else if (pfound->has_arg == 1)
+            {
+              if (fe_optind < argc)
+                fe_optarg = argv[fe_optind++];
+              else
+                {
+                  if (fe_opterr)
+                    fprintf (stderr, "%s: option `%s' requires an argument\n",
+                             argv[0], argv[fe_optind - 1]);
+                  nextchar += my_strlen (nextchar);
+                  return optstring[0] == ':' ? ':' : BAD_OPTION;
+                }
+            }
+          nextchar += my_strlen (nextchar);
+          if (longind != NULL)
+            *longind = option_index;
+          return pfound->val;
+        }
+      /* Can't find it as a long option.  If this is not getopt_long_only,
+         or the option starts with '--' or is not a valid short
+         option, then it's an error.
+         Otherwise interpret it as a short option.  */
+      if (!long_only || argv[fe_optind][1] == '-'
+#ifdef GETOPT_COMPAT
+          || argv[fe_optind][0] == '+'
+#endif                          /* GETOPT_COMPAT */
+          || my_index (optstring, *nextchar) == NULL)
+        {
+          if (fe_opterr)
+            {
+              if (argv[fe_optind][1] == '-')
+                /* --option */
+                fprintf (stderr, "%s: unrecognized option `--%s'\n",
+                         argv[0], nextchar);
+              else
+                /* +option or -option */
+                fprintf (stderr, "%s: unrecognized option `%c%s'\n",
+                         argv[0], argv[fe_optind][0], nextchar);
+            }
+          nextchar = (char *) "";
+          fe_optind++;
+          return BAD_OPTION;
+        }
+    }
+
+  /* Look at and handle the next option-character.  */
+
+  {
+    char c = *nextchar++;
+    const char *temp = my_index (optstring, c);
+
+    /* Increment `fe_optind' when we start to process its last character.  */
+    if (*nextchar == '\0')
+      ++fe_optind;
+
+    if (temp == NULL || c == ':')
+      {
+        if (fe_opterr)
+          {
+#if 0
+            if (c < 040 || c >= 0177)
+              fprintf (stderr, "%s: unrecognized option, character code 0%o\n",
+                       argv[0], c);
+            else
+              fprintf (stderr, "%s: unrecognized option `-%c'\n", argv[0], c);
+#else
+            /* 1003.2 specifies the format of this message.  */
+            fprintf (stderr, "%s: illegal option -- %c\n", argv[0], c);
+#endif
+          }
+        fe_optopt = c;
+        return BAD_OPTION;
+      }
+    if (temp[1] == ':')
+      {
+        if (temp[2] == ':')
+          {
+            /* This is an option that accepts an argument optionally.  */
+            if (*nextchar != '\0')
+              {
+                fe_optarg = nextchar;
+                fe_optind++;
+              }
+            else
+              fe_optarg = 0;
+            nextchar = NULL;
+          }
+        else
+          {
+            /* This is an option that requires an argument.  */
+            if (*nextchar != '\0')
+              {
+                fe_optarg = nextchar;
+                /* If we end this ARGV-element by taking the rest as an arg,
+                   we must advance to the next element now.  */
+                fe_optind++;
+              }
+            else if (fe_optind == argc)
+              {
+                if (fe_opterr)
+                  {
+#if 0
+                    fprintf (stderr, "%s: option `-%c' requires an argument\n",
+                             argv[0], c);
+#else
+                    /* 1003.2 specifies the format of this message.  */
+                    fprintf (stderr, "%s: option requires an argument -- %c\n",
+                             argv[0], c);
+#endif
+                  }
+                fe_optopt = c;
+                if (optstring[0] == ':')
+                  c = ':';
+                else
+                  c = BAD_OPTION;
+              }
+            else
+              /* We already incremented `fe_optind' once;
+                 increment it again when taking next ARGV-elt as argument.  */
+              fe_optarg = argv[fe_optind++];
+            nextchar = NULL;
+          }
+      }
+    return c;
+  }
+}
+
+int fe_getopt (
+     int argc,
+     char *const *argv,
+     const char *optstring)
+{
+  return _fe_getopt_internal (argc, argv, optstring,
+                           (const struct fe_option *) 0,
+                           (int *) 0,
+                           0);
+}
+
+int fe_getopt_long (
+     int argc,
+     char *const *argv,
+     const char *options,
+     const struct fe_option *long_options,
+     int *opt_index)
+{
+  return _fe_getopt_internal (argc, argv, options, long_options, opt_index, 0);
+}
+
+int fe_getopt_long_only (
+     int argc,
+     char *const *argv,
+     const char *options,
+     const struct fe_option *long_options,
+     int *opt_index)
+{
+  return _fe_getopt_internal (argc, argv, options, long_options, opt_index, 1);
+}
+
+#ifdef TEST_GETOPT
+
+/* Compile with -DTEST_GETOPT to make an executable for use in testing
+   the above definition of `getopt'.  */
+
+int main (int argc, char **argv)
+{
+  int c;
+  int digit_optind = 0;
+
+  while (1)
+    {
+      int this_option_optind = optind ? optind : 1;
+
+      c = fe_getopt (argc, argv, "abc:d:0123456789");
+      if (c == EOF)
+        break;
+
+      switch (c)
+        {
+        case '0':
+        case '1':
+        case '2':
+        case '3':
+        case '4':
+        case '5':
+        case '6':
+        case '7':
+        case '8':
+        case '9':
+          if (digit_optind != 0 && digit_optind != this_option_optind)
+            printf ("digits occur in two different argv-elements.\n");
+          digit_optind = this_option_optind;
+          printf ("option %c\n", c);
+          break;
+
+        case 'a':
+          printf ("option a\n");
+          break;
+
+        case 'b':
+          printf ("option b\n");
+          break;
+
+        case 'c':
+          printf ("option c with value `%s'\n", fe_optarg);
+          break;
+
+        case BAD_OPTION:
+          break;
+
+        default:
+          printf ("?? fe_getopt returned character code 0%o ??\n", c);
+        }
+    }
+
+  if (fe_optind < argc)
+    {
+      printf ("non-option ARGV-elements: ");
+      while (fe_optind < argc)
+        printf ("%s ", argv[fe_optind++]);
+      printf ("\n");
+    }
+
+  exit (0);
+}
+
+#endif /* TEST_GETOPT */
diff --git a/Singular/fegetopt.h b/Singular/fegetopt.h
new file mode 100644
index 0000000..1f119bb
--- /dev/null
+++ b/Singular/fegetopt.h
@@ -0,0 +1,128 @@
+/* Declarations for getopt.
+   Copyright (C) 1989, 1990, 1991, 1992, 1993 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, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+/*
+   obachman 9/99: adapted to Singular by
+    * adding prefix fe_ to global variables
+    * extended fe_option structure
+*/
+
+#ifndef FEGETOPT_H
+#define FEGETOPT_H 1
+
+#ifdef        __cplusplus
+extern "C" {
+#endif
+
+/* For communication from `getopt' to the caller.
+   When `getopt' finds an option that takes an argument,
+   the argument value is returned here.
+   Also, when `ordering' is RETURN_IN_ORDER,
+   each non-option ARGV-element is returned here.  */
+
+extern char *fe_optarg;
+
+/* Index in ARGV of the next element to be scanned.
+   This is used for communication to and from the caller
+   and for communication between successive calls to `getopt'.
+
+   On entry to `getopt', zero means this is the first call; initialize.
+
+   When `getopt' returns EOF, this is the index of the first of the
+   non-option elements that the caller should itself scan.
+
+   Otherwise, `optind' communicates from one call to the next
+   how much of ARGV has been scanned so far.  */
+
+extern int fe_optind;
+
+/* Callers store zero here to inhibit the error message `getopt' prints
+   for unrecognized options.  */
+
+extern int fe_opterr;
+
+/* Set to an option character which was unrecognized.  */
+
+extern int fe_optopt;
+
+/* Describe the long-named options requested by the application.
+   The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
+   of `struct option' terminated by an element containing a name which is
+   zero.
+
+   The field `has_arg' is:
+   no_argument                (or 0) if the option does not take an argument,
+   required_argument        (or 1) if the option requires an argument,
+   optional_argument         (or 2) if the option takes an optional argument.
+
+   To have a long-named option do something other than set an `int' to
+   a compiled-in constant, such as set a value from `optarg', set the
+   `val' field to a nonzero value (the equivalent single-letter option
+   character, if there is one).
+   For long options `getopt' returns the contents of the `val' field.  */
+
+typedef enum {feOptUntyped, feOptBool, feOptInt, feOptString} feOptType;
+struct fe_option
+{
+#if        __STDC__
+  const char *name;
+#else
+  char *name;
+#endif
+  /* has_arg can't be an enum because some compilers complain about
+     type mismatches in all the code that assumes it is an int.  */
+  int has_arg;
+  int val;
+  /* Stuff added for Singular  */
+  const char*   arg_name;/* name of argument, for display in help */
+  const char*   help;    /* (short) help string */
+  feOptType     type;    /* type of argument, if has_arg > 0 */
+  void*         value;   /* (default) value of option */
+  int           set;     /* only relevant for strings: 0 if not set, 1 if set */
+};
+
+/* Names for the values of the `has_arg' field of `struct option'.  */
+
+#define        no_argument       0
+#define required_argument        1
+#define optional_argument        2
+
+#if defined(__STDC__) || defined(PROTO) || defined(__cplusplus)
+extern int fe_getopt (int argc, char *const *argv, const char *shortopts);
+extern int fe_getopt_long (int argc, char *const *argv, const char *shortopts,
+                        const struct fe_option *longopts, int *longind);
+extern int fe_getopt_long_only (int argc, char *const *argv,
+                             const char *shortopts,
+                             const struct fe_option *longopts, int *longind);
+
+/* Internal only.  Users should not call this directly.  */
+extern int _fe_getopt_internal (int argc, char *const *argv,
+                             const char *shortopts,
+                             const struct fe_option *longopts, int *longind,
+                             int long_only);
+#else /* not __STDC__ */
+extern int fe_getopt ();
+extern int fe_getopt_long ();
+extern int fe_getopt_long_only ();
+
+extern int _fe_getopt_internal ();
+#endif /* not __STDC__ */
+
+#ifdef        __cplusplus
+}
+#endif
+
+#endif /* _GETOPT_H */
diff --git a/Singular/fehelp.cc b/Singular/fehelp.cc
new file mode 100644
index 0000000..0c8db77
--- /dev/null
+++ b/Singular/fehelp.cc
@@ -0,0 +1,1149 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: help system
+*/
+
+#include <string.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <time.h>
+
+
+
+
+#include <kernel/mod2.h>
+
+#include <omalloc/omalloc.h>
+#include <misc/mylimits.h>
+
+#include <resources/feResource.h>
+#include <reporter/reporter.h>
+
+#include <resources/omFindExec.h>
+
+#include <reporter/si_signals.h>
+
+#include "ipid.h"
+#include "ipshell.h"
+#include "libparse.h"
+#include "feOpt.h"
+
+#include "tok.h"
+#include "fehelp.h"
+
+/*****************************************************************
+ *
+ * Declarations: Data  structures
+ *
+ *****************************************************************/
+#define MAX_HE_ENTRY_LENGTH 160
+typedef struct
+{
+  char key[MAX_HE_ENTRY_LENGTH];
+  char node[MAX_HE_ENTRY_LENGTH];
+  char url[MAX_HE_ENTRY_LENGTH];
+  long  chksum;
+} heEntry_s;
+typedef  heEntry_s * heEntry;
+
+typedef void (*heBrowserHelpProc)(heEntry hentry, int br);
+typedef BOOLEAN (*heBrowserInitProc)(int warn, int br);
+
+typedef struct
+{
+  const char* browser;
+  heBrowserInitProc init_proc;
+  heBrowserHelpProc help_proc;
+  const char* required;
+  const char* action;
+} heBrowser_s;
+typedef heBrowser_s * heBrowser;
+
+/*****************************************************************
+ *
+ * Declarations: Local functions
+ *
+ *****************************************************************/
+static char* strclean(char* str);
+static BOOLEAN heKey2Entry(char* filename, char* key, heEntry hentry);
+static int heReKey2Entry (char* filename, char* key, heEntry hentry);
+static BOOLEAN strmatch(char* s, char* re);
+static BOOLEAN heOnlineHelp(char* s);
+static void heBrowserHelp(heEntry hentry);
+static long heKeyChksum(char* key);
+
+// browser functions
+static BOOLEAN heGenInit(int,int);    static void heGenHelp(heEntry hentry,int);
+                                      static void heBuiltinHelp(heEntry hentry,int);
+static BOOLEAN heDummyInit(int,int);   static void heDummyHelp(heEntry hentry,int);
+static BOOLEAN heEmacsInit(int,int);   static void heEmacsHelp(heEntry hentry,int);
+
+static heBrowser heCurrentHelpBrowser = NULL;
+static int heCurrentHelpBrowserIndex= -1;
+
+
+/*****************************************************************
+ *
+ * Definition: available help browsers
+ *
+ *****************************************************************/
+// order is important -- first possible help is chosen
+// moved to LIB/help.cnf
+static heBrowser_s *heHelpBrowsers=NULL;
+
+/*****************************************************************
+ *
+ * Implementation: public function
+ *
+ *****************************************************************/
+void feHelp(char *str)
+{
+  str = strclean(str);
+  if (str == NULL) {heBrowserHelp(NULL); return;}
+
+  if (strlen(str) > MAX_HE_ENTRY_LENGTH - 2)  // need room for extra **
+    str[MAX_HE_ENTRY_LENGTH - 3] = '\0';
+
+  BOOLEAN key_is_regexp = (strchr(str, '*') != NULL);
+
+  // try proc help and library help
+  if (! key_is_regexp && heOnlineHelp(str)) return;
+
+  heEntry_s hentry;
+  memset(&hentry,0,sizeof(hentry));
+  char* idxfile = feResource('x' /*"IdxFile"*/);
+
+  // Try exact match of help string with key in index
+  if (!key_is_regexp && (idxfile != NULL) && heKey2Entry(idxfile, str, &hentry))
+  {
+    heBrowserHelp(&hentry);
+    return;
+  }
+
+  // Try to match approximately with key in index file
+  if (idxfile != NULL)
+  {
+    if (heCurrentHelpBrowser == NULL) feHelpBrowser(NULL, 0);
+    assume(heCurrentHelpBrowser != NULL);
+
+    StringSetS("");
+    int found = heReKey2Entry(idxfile, str, &hentry);
+
+    // Try to match with str*
+    if (found == 0)
+    {
+      char mkey[MAX_HE_ENTRY_LENGTH];
+      strcpy(mkey, str);
+      strcat(mkey, "*");
+      found = heReKey2Entry(idxfile, mkey, &hentry);
+      // Try to match with *str*
+      if (found == 0)
+      {
+        mkey[0] = '*';
+        strcpy(mkey + 1, str);
+        strcat(mkey, "*");
+        found = heReKey2Entry(idxfile, mkey, &hentry);
+      }
+
+      // Print warning and return if nothing found
+      if (found == 0)
+      {
+        Warn("No help for topic '%s' (not even for '*%s*')", str, str);
+        WarnS("Try '?;'       for general help");
+        WarnS("or  '?Index;'  for all available help topics.");
+        return;
+      }
+    }
+
+    // do help if unique match was found
+    if (found == 1)
+    {
+      heBrowserHelp(&hentry);
+      return;
+    }
+    // Print warning about multiple matches and return
+    if (key_is_regexp)
+      Warn("No unique help for '%s'", str);
+    else
+      Warn("No help for topic '%s'", str);
+    Warn("Try one of");
+    char *matches=StringEndS();
+    PrintS(matches);
+    omFree(matches);
+    PrintLn();
+    return;
+  }
+
+  // no idx file, let Browsers deal with it, if they can
+  strcpy(hentry.key, str);
+  *hentry.node = '\0';
+  *hentry.url = '\0';
+  hentry.chksum = 0;
+  heBrowserHelp(&hentry);
+}
+static void feBrowserFile()
+{
+  FILE *f=feFopen("help.cnf","r",NULL,TRUE);
+  int br=0;
+  if (f!=NULL)
+  {
+    char buf[512];
+    while (fgets( buf, sizeof(buf), f))
+    {
+      if ((buf[0]!='#') && (buf[0]>' ')) br++;
+    }
+    fseek(f,0,SEEK_SET);
+    // for the 4(!) default browsers
+    heHelpBrowsers=(heBrowser_s*)omAlloc0((br+4)*sizeof(heBrowser_s));
+    br = 0;
+    while (fgets( buf, sizeof(buf), f))
+    {
+      if ((buf[0]!='#') && (buf[0]>' '))
+      {
+        char *name=strtok(buf,"!");
+        char *req=strtok(NULL,"!");
+        char *cmd=strtok(NULL,"!");
+        if ((name!=NULL) && (req!=NULL) && (cmd!=NULL))
+        {
+          while ((cmd[0]!='\0') && (cmd[strlen(cmd)-1]<=' '))
+            cmd[strlen(cmd)-1]='\0';
+          //Print("name %d >>%s<<\n\treq:>>%s<<\n\tcmd:>>%s<<\n",br,name,req,cmd);
+          heHelpBrowsers[br].browser=(char *)omStrDup(name);
+          heHelpBrowsers[br].init_proc=heGenInit;
+          heHelpBrowsers[br].help_proc=heGenHelp;
+          heHelpBrowsers[br].required=omStrDup(req);
+          heHelpBrowsers[br].action=omStrDup(cmd);
+          br++;
+        }
+        else
+        {
+          Print("syntax error in help.cnf, at line starting with %s\n",buf);
+        }
+      }
+    }
+    fclose(f);
+  }
+  else
+  {
+    // for the 4(!) default browsers
+    heHelpBrowsers=(heBrowser_s*)omAlloc0(4*sizeof(heBrowser_s));
+  }
+  heHelpBrowsers[br].browser="builtin";
+  heHelpBrowsers[br].init_proc=heGenInit;
+  heHelpBrowsers[br].help_proc=heBuiltinHelp;
+  heHelpBrowsers[br].required="i";
+  //heHelpBrowsers[br].action=NULL;
+  br++;
+  heHelpBrowsers[br].browser="dummy";
+  heHelpBrowsers[br].init_proc=heDummyInit;
+  heHelpBrowsers[br].help_proc=heDummyHelp;
+  //heHelpBrowsers[br].required=NULL;
+  //heHelpBrowsers[br].action=NULL;
+  br++;
+  heHelpBrowsers[br].browser="emacs";
+  heHelpBrowsers[br].init_proc=heEmacsInit;
+  heHelpBrowsers[br].help_proc=heEmacsHelp;
+  //heHelpBrowsers[br].required=NULL;
+  //heHelpBrowsers[br].action=NULL;
+  //br++;
+  //heHelpBrowsers[br].browser=NULL;
+  //heHelpBrowsers[br].init_proc=NULL;
+  //heHelpBrowsers[br].help_proc=NULL;
+  //heHelpBrowsers[br].required=NULL;
+  //heHelpBrowsers[br].action=NULL;
+}
+
+const char* feHelpBrowser(char* which, int warn)
+{
+  int i = 0;
+
+  // if no argument, choose first available help browser
+  if (heHelpBrowsers==NULL) feBrowserFile();
+  if (which == NULL || *which == '\0')
+  {
+    // return, if already set
+    if (heCurrentHelpBrowser != NULL)
+      return heCurrentHelpBrowser->browser;
+
+    // First, try emacs, if emacs-option is set
+    if (feOptValue(FE_OPT_EMACS) != NULL)
+    {
+      while (heHelpBrowsers[i].browser != NULL)
+      {
+        if (strcmp(heHelpBrowsers[i].browser, "emacs") == 0 &&
+            (heHelpBrowsers[i].init_proc(0,i)))
+        {
+          heCurrentHelpBrowser = &(heHelpBrowsers[i]);
+          heCurrentHelpBrowserIndex=i;
+          goto Finish;
+        }
+        i++;
+      }
+      i=0;
+    }
+    while (heHelpBrowsers[i].browser != NULL)
+    {
+      if (heHelpBrowsers[i].init_proc(0,i))
+      {
+        heCurrentHelpBrowser = &(heHelpBrowsers[i]);
+        heCurrentHelpBrowserIndex=i;
+        goto Finish;
+      }
+      i++;
+    }
+    // should never get here
+    dReportBug("should never get here");
+  }
+
+  // with argument, find matching help browser
+  while (heHelpBrowsers[i].browser != NULL &&
+         strcmp(heHelpBrowsers[i].browser, which) != 0)
+  {i++;}
+
+  if (heHelpBrowsers[i].browser == NULL)
+  {
+    if (warn) Warn("No help browser '%s' available.", which);
+  }
+  else
+  {
+    // see whether we can init it
+    if (heHelpBrowsers[i].init_proc(warn,i))
+    {
+      heCurrentHelpBrowser = &(heHelpBrowsers[i]);
+      heCurrentHelpBrowserIndex=i;
+      goto Finish;
+    }
+  }
+
+  // something went wrong
+  if (heCurrentHelpBrowser == NULL)
+  {
+    feHelpBrowser();
+    assume(heCurrentHelpBrowser != NULL);
+    if (warn)
+      Warn("Setting help browser to '%s'.", heCurrentHelpBrowser->browser);
+    return heCurrentHelpBrowser->browser;
+  }
+  else
+  {
+    // or, leave as is
+    if (warn)
+      Warn("Help browser stays at '%s'.",  heCurrentHelpBrowser->browser);
+    return heCurrentHelpBrowser->browser;
+  }
+
+  Finish:
+  // update value of Browser Option
+  if (feOptSpec[FE_OPT_BROWSER].value == NULL ||
+      strcmp((char*) feOptSpec[FE_OPT_BROWSER].value,
+             heCurrentHelpBrowser->browser) != 0)
+  {
+    omfree(feOptSpec[FE_OPT_BROWSER].value);
+    feOptSpec[FE_OPT_BROWSER].value
+     = (void*) omStrDup(heCurrentHelpBrowser->browser);
+  }
+  return heCurrentHelpBrowser->browser;
+}
+
+void  feStringAppendBrowsers(int warn)
+{
+  int i;
+  StringAppendS("Available HelpBrowsers: ");
+
+  i = 0;
+  if (heHelpBrowsers==NULL) feBrowserFile();
+  while (heHelpBrowsers[i].browser != NULL)
+  {
+    if (heHelpBrowsers[i].init_proc(warn,i))
+      StringAppend("%s, ", heHelpBrowsers[i].browser);
+    i++;
+  }
+  StringAppend("\nCurrent HelpBrowser: %s ", feHelpBrowser());
+}
+
+
+/*****************************************************************
+ *
+ * Implementation: local function
+ *
+ *****************************************************************/
+// Remove whitspaces from beginning and end, return NULL if only whitespaces
+static char* strclean(char* str)
+{
+  if (str == NULL) return NULL;
+  char *s=str;
+  while ((*s <= ' ') && (*s != '\0')) s++;
+  if (*s == '\0') return NULL;
+  char *ss=s;
+  while (*ss!='\0') ss++;
+  ss--;
+  while ((*ss <= ' ') && (*ss != '\0'))
+  {
+    *ss='\0';
+    ss--;
+  }
+  if (*ss == '\0') return NULL;
+  return s;
+}
+
+// Finds help entry for key:
+// returns filled-in hentry and TRUE, on success
+// FALSE, on failure
+// Assumes that lines of idx file have the following form
+// key\tnode\turl\tchksum\n (chksum ma be empty, then it is set to -1)
+// and that lines are sorted alpahbetically w.r.t. index entries
+static BOOLEAN heKey2Entry(char* filename, char* key, heEntry hentry)
+{
+  FILE* fd;
+  int c, k;
+  int kl, i;
+  *(hentry->key) = '\0';
+  *(hentry->url) = '\0';
+  *(hentry->node) = '\0';
+  hentry->chksum = 0;
+  if (filename == NULL || key == NULL)  return FALSE;
+  fd = fopen(filename, "r");
+  if (fd == NULL) return FALSE;
+  kl = strlen(key);
+
+  k = key[0];
+  i = 0;
+  while ((c = getc(fd)) != EOF)
+  {
+    if (c < k)
+    {
+      /* Skip line */
+      while (getc(fd) != '\n') {};
+      if (i)
+      {
+        i=0;
+        k=key[0];
+      }
+    }
+    else if (c == k)
+    {
+      i++;
+      if (i == kl)
+      {
+        // \t must follow, otherwise only substring match
+        if (getc(fd) != '\t') goto Failure;
+
+        // Now we found an exact match
+        if (hentry->key != key) strcpy(hentry->key, key);
+        // get node
+        i = 0;
+        while ((c = getc(fd)) != '\t' && c != EOF)
+        {
+          hentry->node[i] = c;
+          i++;
+        }
+        if (c == EOF) goto Failure;
+	if (hentry->node[0]=='\0')
+	  strcpy(hentry->node,hentry->key);
+
+        // get url
+        //hentry->node[i] = '\0';
+        i = 0;
+        while ((c = getc(fd)) != '\t' && c != EOF)
+        {
+          hentry->url[i] = c;
+          i++;
+        }
+        if (c == EOF) goto Failure;
+
+        // get chksum
+        hentry->url[i] = '\0';
+
+        if (si_fscanf(fd, "%ld\n", &(hentry->chksum)) != 1)
+        {
+          hentry->chksum = -1;
+        }
+        fclose(fd);
+        return TRUE;
+      }
+      else if (i > kl)
+      {
+        goto Failure;
+      }
+      else
+      {
+        k = key[i];
+      }
+    }
+    else
+    {
+      goto Failure;
+    }
+  }
+  Failure:
+  fclose(fd);
+  return FALSE;
+}
+
+// return TRUE if s matches re
+// FALSE, otherwise
+// does not distinguish lower and upper cases
+// inteprets * as wildcard
+static BOOLEAN strmatch(char* s, char* re)
+{
+  if (s == NULL || *s == '\0')
+    return (re == NULL || *re == '\0' || strcmp(re, "*") == 0);
+  if (re == NULL || *re == '\0') return FALSE;
+
+  int i;
+  char ls[MAX_HE_ENTRY_LENGTH + 1];
+  char rs[MAX_HE_ENTRY_LENGTH + 1];
+  char *l, *r, *ll, *rr;
+
+  // make everything to lower case
+  i=1;
+  ls[0] = '\0';
+  do
+  {
+    if (*s >= 'A' && *s <= 'Z') ls[i] = *s + ('a' - 'A');
+    else ls[i] = *s;
+    i++;
+    s++;
+  } while (*s != '\0');
+  ls[i] = '\0';
+  l = &(ls[1]);
+
+  i=1;
+  rs[0] = '\0';
+  do
+  {
+    if (*re >= 'A' && *re <= 'Z') rs[i]= *re + ('a' - 'A');
+    else rs[i] = *re;
+    i++;
+    re++;
+  } while (*re != '\0');
+  rs[i] = '\0';
+  r = &(rs[1]);
+
+  // chopp of exact matches from beginning and end
+  while (*r != '*' && *r != '\0' && *l != '\0')
+  {
+    if (*r != *l) return FALSE;
+    *r = '\0';
+    *s = '\0';
+    r++;
+    l++;
+  }
+  if (*r == '\0') return (*l == '\0');
+  if (*r == '*' && r[1] == '\0') return TRUE;
+  if (*l == '\0') return FALSE;
+
+  rr = &r[strlen(r) - 1];
+  ll = &l[strlen(l) - 1];
+  while (*rr != '*' && *rr != '\0' && *ll != '\0')
+  {
+    if (*rr != *ll) return FALSE;
+    *rr = '\0';
+    *ll = '\0';
+    rr--;
+    ll--;
+  }
+  if (*rr == '\0') return (*ll == '\0');
+  if (*rr == '*' && rr[-1] == '\0') return TRUE;
+  if (*ll == '\0') return FALSE;
+
+  // now *r starts with a * and ends with a *
+  r++;
+  *rr = '\0'; rr--;
+  while (*r != '\0')
+  {
+    rr = r + 1;
+    while (*rr != '*' && *rr != '\0') rr++;
+    if (*rr == '*')
+    {
+      *rr = '\0';
+      rr++;
+    }
+    l = strstr(l, r);
+    if (l == NULL) return FALSE;
+    r = rr;
+  }
+  return TRUE;
+}
+
+// similar to heKey2Entry, except that
+// key is taken as regexp (see above)
+// and number of matches is returned
+// if number of matches > 0, then hentry contains entry for first match
+// if number of matches > 1, matches are printed as komma-separated
+// into global string
+static int heReKey2Entry (char* filename, char* key, heEntry hentry)
+{
+  int i = 0;
+  FILE* fd;
+  char index_key[MAX_HE_ENTRY_LENGTH];
+
+  if (filename == NULL || key == NULL)  return 0;
+  fd = fopen(filename, "r");
+  if (fd == NULL) return 0;
+  memset(index_key,0,MAX_HE_ENTRY_LENGTH);
+  while (si_fscanf(fd, "%[^\t]\t%*[^\n]\n", index_key) == 1)
+  {
+    if ((index_key[MAX_HE_ENTRY_LENGTH-1]!='\0'))
+    {
+      index_key[MAX_HE_ENTRY_LENGTH-1]='\0';
+      Werror("index file corrupt at line >>%s<<",index_key);
+      break;
+    }
+    else if (strmatch(index_key, key))
+    {
+      i++;
+      if (i == 1)
+      {
+        heKey2Entry(filename, index_key, hentry);
+      }
+      else if (i == 2)
+      {
+        StringAppend("?%s; ?%s;", hentry->key, index_key);
+      }
+      else
+      {
+        StringAppend(" ?%s;", index_key);
+      }
+    }
+  }
+  fclose(fd);
+  return i;
+}
+
+// test for h being a string and print it
+static void hePrintHelpStr(const idhdl hh,const char *id,const char *pa)
+{
+  if ((hh!=NULL) && (IDTYP(hh)==STRING_CMD))
+  {
+    PrintS(IDSTRING(hh));
+    PrintLn();
+  }
+  else
+    Print("`%s` not found in package %s\n",id,pa);
+}
+// try to find the help string as a loaded procedure or library
+// if found, display the help and return TRUE
+// otherwise, return FALSE
+static BOOLEAN heOnlineHelp(char* s)
+{
+  char *ss;
+  idhdl h;
+
+  if ((ss=strstr(s,"::"))!=NULL)
+  {
+    *ss='\0';
+    ss+=2;
+    h=ggetid(s);
+    if (h!=NULL)
+    {
+      Print("help for %s from package %s\n",ss,s);
+      char s_help[200];
+      strcpy(s_help,ss);
+      strcat(s_help,"_help");
+      idhdl hh=IDPACKAGE(h)->idroot->get(s_help,0);
+      hePrintHelpStr(hh,s_help,s);
+      return TRUE;
+    }
+    else Print("package %s not found\n",s);
+    return TRUE; /* do not search the manual */
+  }
+  h=IDROOT->get(s,myynest);
+  // try help for a procedure
+  if (h!=NULL)
+  {
+    if  (IDTYP(h)==PROC_CMD)
+    {
+      char *lib=iiGetLibName(IDPROC(h));
+      if((lib!=NULL)&&(*lib!='\0'))
+      {
+        Print("// proc %s from lib %s\n",s,lib);
+        s=iiGetLibProcBuffer(IDPROC(h), 0);
+        if (s!=NULL)
+        {
+          PrintS(s);
+          omFree((ADDRESS)s);
+        }
+        return TRUE;
+      }
+    }
+    else if (IDTYP(h)==PACKAGE_CMD)
+    {
+      idhdl hh=IDPACKAGE(h)->idroot->get("info",0);
+      hePrintHelpStr(hh,"info",s);
+      return TRUE;
+    }
+    return FALSE;
+  }
+
+  // try help for a library
+  int ls = strlen(s);
+  char* str = NULL;
+  // check that it ends with "[.,_]lib"
+  if (strlen(s) >=4 &&  strcmp(&s[ls-3], "lib") == 0)
+  {
+    if (s[ls - 4] == '.') str = s;
+    else
+    {
+      str = omStrDup(s);
+      str[ls - 4] = '.';
+    }
+  }
+  else
+  {
+    return FALSE;
+  }
+
+  char libnamebuf[128];
+  FILE *fp=NULL;
+  // first, search for library of that name
+  if ((str[1]!='\0') &&
+      ((iiLocateLib(str, libnamebuf) && (fp=feFopen(libnamebuf, "rb")) !=NULL)
+       ||
+       ((fp=feFopen(str,"rb", libnamebuf))!=NULL)))
+  {
+    extern FILE *yylpin;
+    lib_style_types lib_style; // = OLD_LIBSTYLE;
+
+    yylpin = fp;
+    yylplex(str, libnamebuf, &lib_style, IDROOT, FALSE, GET_INFO);
+    reinit_yylp();
+    if(lib_style == OLD_LIBSTYLE)
+    {
+      char buf[256];
+      fseek(fp, 0, SEEK_SET);
+      Warn( "library %s has an old format. Please fix it for the next time",
+            str);
+      if (str != s) omFree(str);
+      BOOLEAN found=FALSE;
+      while (fgets( buf, sizeof(buf), fp))
+      {
+        if (strncmp(buf,"//",2)==0)
+        {
+          if (found) return TRUE;
+        }
+        else if ((strncmp(buf,"proc ",5)==0)||(strncmp(buf,"LIB ",4)==0))
+        {
+          if (!found) WarnS("no help part in library found");
+          return TRUE;
+        }
+        else
+        {
+          found=TRUE;
+          PrintS(buf);
+        }
+      }
+    }
+    else
+    {
+      if (str != s) omFree(str);
+      fclose( yylpin );
+      PrintS(text_buffer);
+      omFree(text_buffer);
+      text_buffer=NULL;
+    }
+    return TRUE;
+  }
+
+  if (str != s) omFree(str);
+  return FALSE;
+}
+
+static long heKeyChksum(char* key)
+{
+  if (key == NULL || *key == '\0') return 0;
+  idhdl h=IDROOT->get(key,myynest);
+  if ((h!=NULL) && (IDTYP(h)==PROC_CMD))
+  {
+    procinfo *pi = IDPROC(h);
+    if (pi != NULL) return pi->data.s.help_chksum;
+  }
+  return 0;
+}
+
+/*****************************************************************
+ *
+ * Implementation : Help Browsers
+ *
+ *****************************************************************/
+
+static BOOLEAN feHelpCalled = FALSE;
+
+static void heBrowserHelp(heEntry hentry)
+{
+  // check checksums of procs
+  int kchksum = (hentry != NULL && hentry->chksum > 0 ?
+                 heKeyChksum(hentry->key) : 0);
+  if (kchksum  && kchksum != hentry->chksum && heOnlineHelp(hentry->key))
+    return;
+
+  if (heCurrentHelpBrowser == NULL) feHelpBrowser(NULL, 0);
+  assume(heCurrentHelpBrowser != NULL);
+  if (! feHelpCalled)
+  {
+    Warn("Displaying help in browser '%s'.", heCurrentHelpBrowser->browser);
+    //if (strcmp(heCurrentHelpBrowser->browser, "netscape") == 0 &&
+    //    feResource('h', 0) == NULL)
+    //{
+    //  Warn("Using URL '%s'.", feResource('u', 0));
+    //}
+    Warn("Use 'system(\"--browser\", <browser>);' to change browser,");
+    StringSetS("where <browser> can be: ");
+    int i = 0;
+    i = 0;
+    while (heHelpBrowsers[i].browser != NULL)
+    {
+      if (heHelpBrowsers[i].init_proc(0,i))
+        StringAppend("\"%s\", ", heHelpBrowsers[i].browser);
+      i++;
+    }
+    char *browsers=StringEndS();
+    if (browsers[strlen(browsers)-2] == ',')
+    {
+      browsers[strlen(browsers)-2] = '.';
+      browsers[strlen(browsers)-1] = '\0';
+    }
+    WarnS(browsers);
+    omFree(browsers);
+  }
+
+  heCurrentHelpBrowser->help_proc(hentry, heCurrentHelpBrowserIndex);
+  feHelpCalled = TRUE;
+}
+
+#define MAX_SYSCMD_LEN MAXPATHLEN*2
+static BOOLEAN heGenInit(int warn, int br)
+{
+  if (heHelpBrowsers[br].required==NULL) return TRUE;
+  const char *p=heHelpBrowsers[br].required;
+  while (*p>'\0')
+  {
+    switch (*p)
+    {
+      case '#': break;
+      case ' ': break;
+      case 'i': /* singular.hlp */
+      case 'x': /* singular.idx */
+      case 'h': /* html dir */
+               if (feResource(*p, warn) == NULL)
+               {
+                 if (warn) Warn("resource `%c` not found",*p);
+                 return FALSE;
+               }
+               break;
+      case 'D': /* DISPLAY */
+               if (getenv("DISPLAY") == NULL)
+               {
+                 if (warn) WarnS("resource `D` not found");
+                 return FALSE;
+               }
+               break;
+      case 'E': /* executable: E:xterm: */
+      case 'O': /* OS: O:ix86Mac-darwin/ppcMac-darwin: */
+               {
+                 char name[128];
+                 char exec[128];
+                 char op=*p;
+                 memset(name,0,128);
+                 int i=0;
+                 p++;
+                 while (((*p==':')||(*p<=' ')) && (*p!='\0')) p++;
+                 while((i<127) && (*p>' ') && (*p!=':'))
+                 {
+                   name[i]=*p; p++; i++;
+                 }
+                 if (i==0) return FALSE;
+
+                 if ((op=='O') && (strcmp(name,S_UNAME)!=0))
+                   return FALSE;
+                 if ((op=='E') && (omFindExec(name,exec)==NULL))
+                 {
+                   if (warn) Warn("executable `%s` not found",name);
+                   return FALSE;
+                 }
+               }
+               break;
+      default: Warn("unknown char %c",*p);
+               break;
+    }
+    p++;
+  }
+  return TRUE;
+}
+
+static void heGenHelp(heEntry hentry, int br)
+{
+  char sys[MAX_SYSCMD_LEN];
+  const char *p=heHelpBrowsers[br].action;
+  if (p==NULL) {PrintS("no action ?\n"); return;}
+  memset(sys,0,MAX_SYSCMD_LEN);
+  int i=0;
+  while ((*p>'\0')&& (i<MAX_SYSCMD_LEN))
+  {
+    if ((*p)=='%')
+    {
+      p++;
+      switch (*p)
+      {
+        case 'f': /* local html:file */
+        case 'h': /* local html:URL */
+        case 'H': /* www html */
+                 {
+                   char temp[256];
+                   char *htmldir = feResource('h' /*"HtmlDir"*/);
+                   if ((*p=='h')&&(htmldir!=NULL))
+                     strcat(sys,"file://localhost");
+                   else if ((*p=='H')||(htmldir==NULL))
+                     htmldir = feResource('u' /* %H -> "ManualUrl"*/);
+                     /* always defined */
+                   if (hentry != NULL && *(hentry->url) != '\0')
+                   #ifdef HAVE_VSNPRINTF
+                     snprintf(temp,256,"%s/%d-%d-%d/%s", htmldir,
+                                  SINGULAR_VERSION/1000,
+                                 (SINGULAR_VERSION % 1000)/100,
+                                 (SINGULAR_VERSION % 100)/10,
+                     hentry->url);
+                   else
+                     snprintf(temp,256,"%s/%d-%d-%d/index.htm", htmldir,
+                                  SINGULAR_VERSION/1000,
+                                 (SINGULAR_VERSION % 1000)/100,
+                                 (SINGULAR_VERSION % 100)/10
+                     );
+                   #else
+                     sprintf(temp,"%s/%d-%d-%d/%s", htmldir,
+                                  SINGULAR_VERSION/1000,
+                                 (SINGULAR_VERSION % 1000)/100,
+                                 (SINGULAR_VERSION % 100)/10,
+                     hentry->url);
+                   else
+                     sprintf(temp,"%s/%d-%d-%d/index.htm", htmldir,
+                                  SINGULAR_VERSION/1000,
+                                 (SINGULAR_VERSION % 1000)/100,
+                                 (SINGULAR_VERSION % 100)/10
+                     );
+                   #endif
+                   strcat(sys,temp);
+                   if ((*p)=='f')
+                   { // remove #SEC
+                     char *pp=(char *)strchr(sys,'#');
+                     if (pp!=NULL)
+                     {
+                       *pp='\0';
+                       i=strlen(sys);
+                       memset(pp,0,MAX_SYSCMD_LEN-i);
+                     }
+                   }
+                   i=strlen(sys);
+                   break;
+                 }
+        case 'i': /* singular.hlp */
+                 {
+                   char *i_res=feResource('i');
+                   if (i_res!=NULL) strcat(sys,i_res);
+                   else
+                   {
+                     WarnS("singular.hlp not found");
+                     return;
+                   }
+                   i=strlen(sys);
+                   break;
+                 }
+        case 'n': /* info node */
+                 {
+                   char temp[256];
+                   if ((hentry!=NULL) && (*(hentry->node) != '\0'))
+                     sprintf(temp,"%s",hentry->node);
+                   //else if ((hentry!=NULL) && (hentry->key!=NULL))
+                   //  sprintf(temp,"Index '%s'",hentry->key);
+                   else
+                     sprintf(temp,"Top");
+                   strcat(sys,temp);
+                   i=strlen(sys);
+                   break;
+                 }
+        case 'v': /* version number*/
+                 {
+                   char temp[256];
+                   sprintf(temp,"%d-%d-%d",SINGULAR_VERSION/1000,
+                                 (SINGULAR_VERSION % 1000)/100,
+                                 (SINGULAR_VERSION % 100)/10);
+                   strcat(sys,temp);
+                   i=strlen(sys);
+                   break;
+                 }
+        default: break;
+      }
+      p++;
+    }
+    else
+    {
+      sys[i]=*p;
+      p++;i++;
+    }
+  }
+  Print("running `%s`\n",sys);
+  (void) system(sys);
+}
+
+static BOOLEAN heDummyInit(int /*warn*/, int /*br*/)
+{
+  return TRUE;
+}
+static void heDummyHelp(heEntry /*hentry*/, int /*br*/)
+{
+  Werror("No functioning help browser available.");
+}
+
+static BOOLEAN heEmacsInit(int /*warn*/, int /*br*/)
+{
+  return TRUE;
+}
+static void heEmacsHelp(heEntry hentry, int /*br*/)
+{
+  WarnS("Your help command could not be executed. Use");
+  Warn("C-h C-s %s",
+       (hentry != NULL && *(hentry->node) != '\0' ? hentry->node : "Top"));
+  Warn("to enter the Singular online help. For general");
+  Warn("information on Singular running under Emacs, type C-h m.");
+}
+static int singular_manual(char *str, BOOLEAN isIndexEntry);
+static void heBuiltinHelp(heEntry hentry, int /*br*/)
+{
+  char* node = omStrDup(hentry != NULL && *(hentry->key) != '\0' ?
+                       hentry->key : "Top");
+  singular_manual(node,(hentry != NULL) && (hentry->url!=NULL));
+  omFree(node);
+}
+
+
+/* ========================================================================== */
+// old, stupid builtin_help
+// This could be implemented much more clever, but I'm too lazy to do this now
+//
+#define HELP_OK        0
+#define FIN_INDEX    '\037'
+#define HELP_NOT_OPEN  1
+#define HELP_NOT_FOUND 2
+#define BUF_LEN        256
+#define IDX_LEN        256
+#define MAX_LINES      21
+
+static inline char tolow(char p)
+{
+  if (('A'<=p)&&(p<='Z')) return p | 040;
+  return p;
+}
+
+/*************************************************/
+static int show(unsigned long offset, char *close)
+{ char buffer[BUF_LEN+1];
+  int  lines = 0;
+  FILE * help;
+
+  if( (help = fopen(feResource('i'), "rb")) == NULL)
+    return HELP_NOT_OPEN;
+
+  fseek(help,  (long)(offset+1), (int)0);
+  while( (!feof(help))
+        && (*fgets(buffer, BUF_LEN, help) != EOF)
+        && (buffer[0] != FIN_INDEX))
+  {
+    printf("%s", buffer);
+    if(lines++> MAX_LINES)
+    {
+      printf("\n Press <RETURN> to continue or x to exit help.\n");
+      fflush(stdout);
+      *close = (char)getchar();
+      if(*close=='x')
+      {
+        getchar();
+        break;
+      }
+      lines=0;
+    }
+  }
+  if(*close!='x')
+  {
+    printf("\nEnd of part. Press <RETURN> to continue or x to exit help.\n");
+    fflush(stdout);
+    *close = (char)getchar();
+    if(*close=='x')
+      getchar();
+  }
+  fclose(help);
+  return HELP_OK;
+}
+
+/*************************************************/
+static int singular_manual(char *str, BOOLEAN isIndexEntry)
+{ FILE *index=NULL;
+  unsigned long offset;
+  char *p,close=' ';
+  int done = 0;
+  char buffer[BUF_LEN+1],
+       Index[IDX_LEN+1],
+       String[IDX_LEN+1];
+  Print("HELP >>%s>>\n",str);
+
+  if( (index = fopen(feResource('i'), "rb")) == NULL)
+  {
+    return HELP_NOT_OPEN;
+  }
+
+  if (!isIndexEntry)
+  {
+    for(p=str; *p; p++) *p = tolow(*p);/* */
+    do
+    {
+      p--;
+    }
+    while ((p != str) && (*p<=' '));
+    p++;
+    *p='\0';
+    (void)sprintf(String, " %s ", str);
+  }
+  else
+  {
+    (void)sprintf(String, " %s", str);
+  }
+
+  while(!feof(index)
+        && (fgets(buffer, BUF_LEN, index) != (char *)0)
+        && (buffer[0] != FIN_INDEX));
+
+  while(!feof(index))
+  {
+    if (fgets(buffer, BUF_LEN, index)==NULL) break; /*fill buffer */
+    if (si_sscanf(buffer, "Node:%[^\177]\177%ld\n", Index, &offset)!=2)
+      continue;
+    if (!isIndexEntry)
+    {
+      for(p=Index; *p; p++) *p = tolow(*p);/* */
+      (void)strcat(Index, " ");
+      if( strstr(Index, String)!=NULL)
+      {
+        done++; (void)show(offset, &close);
+      }
+    }
+    else if( strcmp(Index, String)==0)
+    {
+      done++; (void)show(offset, &close);
+      break;
+    }
+    Index[0]='\0';
+    if(close=='x')
+    break;
+  }
+  if (index != NULL) (void)fclose(index);
+  if(done==0)
+  {
+    Warn("`%s` not found",String);
+    return HELP_NOT_FOUND;
+  }
+  return HELP_OK;
+}
+/*************************************************/
diff --git a/Singular/fehelp.h b/Singular/fehelp.h
new file mode 100644
index 0000000..c347177
--- /dev/null
+++ b/Singular/fehelp.h
@@ -0,0 +1,24 @@
+#ifndef FEHELP_H
+#define FEHELP_H
+
+
+/*****************************************************************
+ *
+ * help system (fehelp.cc)
+ *
+ *****************************************************************/
+// if str != NULL display help for str
+// display general help, otherwise
+void feHelp(char* str = NULL);
+// if browser != NULL or feOpt("browser") != NULL
+//    set HelpBrowser to browser
+// otherwise, if browser was already set, leave as is,
+//            if not, choose first available browser
+// return string identifying current browser
+// keeps feOpt("browser") up-to-date
+// Optional warn argument is as in feResource
+const char* feHelpBrowser(char* browser = NULL, int warn = -1);
+
+void feStringAppendBrowsers(int warn = -1);
+
+#endif /*  FEHELP_H */
diff --git a/Singular/fevoices.cc b/Singular/fevoices.cc
new file mode 100644
index 0000000..899f4ee
--- /dev/null
+++ b/Singular/fevoices.cc
@@ -0,0 +1,658 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: i/o system
+*/
+#include <kernel/mod2.h>
+
+/* I need myfread in standalone_parser */
+#ifndef STANDALONE_PARSER
+
+#include <omalloc/omalloc.h>
+#include <misc/options.h>
+#include <reporter/reporter.h>
+#include <kernel/oswrapper/feread.h>
+#include <Singular/fevoices.h>
+#include <Singular/subexpr.h>
+#include <Singular/ipshell.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <misc/mylimits.h>
+#include <stdarg.h>
+#include <sys/stat.h>
+#include <ctype.h>
+#include <unistd.h>
+
+#ifdef HAVE_PWD_H
+#include <pwd.h>
+#endif
+
+#define fePutChar(c) fputc((unsigned char)(c),stdout)
+/*0 implementation */
+
+
+char fe_promptstr[] ="  ";
+
+// output/print buffer:
+#define INITIAL_PRINT_BUFFER 24*1024L
+// line buffer for reading:
+// minimal value for MAX_FILE_BUFFER: 4*4096 - see Tst/Long/gcd0_l.tst
+// this is an upper limit for the size of monomials/numbers read via the interpreter
+#define MAX_FILE_BUFFER 4*4096
+// static long feBufferLength=INITIAL_PRINT_BUFFER;
+static char * feBuffer=(char *)omAlloc(INITIAL_PRINT_BUFFER);
+
+/**************************************************************************
+* handling of 'voices'
+**************************************************************************/
+
+extern int blocknest; /* scaner.l internal */
+
+int    yy_noeof=0;     // the scanner "state"
+int    yy_blocklineno; // to get the lineno of the block start from scanner
+Voice  *currentVoice = NULL;
+// FILE   *feFilePending; /*temp. storage for grammar.y */
+
+//static const char * BT_name[]={"BT_none","BT_break","BT_proc","BT_example",
+//                               "BT_file","BT_execute","BT_if","BT_else"};
+/*2
+* the name of the current 'Voice': the procname (or filename)
+*/
+const char * sNoName_fe="_";
+const char * VoiceName()
+{
+  if ((currentVoice!=NULL)
+  && (currentVoice->filename!=NULL))
+    return currentVoice->filename;
+  return sNoName_fe;
+}
+
+/*2
+* the calling chain of Voices
+*/
+void VoiceBackTrack()
+{
+  Voice *p=currentVoice;
+  while (p->prev!=NULL)
+  {
+    p=p->prev;
+    char *s=p->filename;
+    if (s==NULL)
+      PrintS("-- called from ? --\n");
+    else
+      Print("-- called from %s --\n",s);
+  }
+}
+
+/*2
+* init a new voice similiar to the current
+*/
+void Voice::Next()
+{
+  Voice *p=new Voice;
+  // OB: ???
+  // Hmm... when Singular is used as batch file
+  // then this voice is never freed
+  omMarkAsStaticAddr(p);
+  if (currentVoice != NULL)
+  {
+    currentVoice->curr_lineno=yylineno;
+    currentVoice->next=p;
+  }
+  p->prev=currentVoice;
+  currentVoice=p;
+  //Print("Next:");
+}
+
+feBufferTypes Voice::Typ()
+{
+  switch(typ)
+  {
+    case BT_proc:
+    case BT_example:
+    case BT_file:
+      return typ;
+    default:
+      if (prev==NULL) return (feBufferTypes)0;
+      return prev->Typ();
+  }
+}
+
+/*2
+* start the file 'fname' (STDIN is stdin) as a new voice (cf.VFile)
+* return FALSE on success, TRUE if an error occurs (file cannot be opened)
+*/
+BOOLEAN newFile(char *fname,FILE* f)
+{
+  currentVoice->Next();
+  //Print(":File%d(%s):%s(%x)\n",
+  //  currentVoice->typ,BT_name[currentVoice->typ],fname,currentVoice);
+  currentVoice->filename   = omStrDup(fname);
+  omMarkAsStaticAddr(currentVoice->filename);
+  if (strcmp(fname,"STDIN") == 0)
+  {
+    currentVoice->files = stdin;
+    currentVoice->sw = BI_stdin;
+    currentVoice->start_lineno = 1;
+  }
+  else
+  {
+    currentVoice->sw = BI_file; /* needed by exitVoice below */
+    if (f!=NULL)
+      currentVoice->files = f;
+    else
+    {
+      currentVoice->files = feFopen(fname,"r",NULL,TRUE);
+      if (currentVoice->files==NULL)
+      {
+        exitVoice();
+        return TRUE;
+      }
+    }
+    currentVoice->start_lineno = 0;
+  }
+  yylineno=currentVoice->start_lineno;
+  //Voice *p=currentVoice;
+  //Print("-----------------\ncurr:");
+  //do
+  //{
+  //Print("voice fn:%s\n",p->filename);
+  //p=p->prev;
+  //}
+  //while (p!=NULL);
+  //Print("----------------\n");
+  return FALSE;
+}
+
+void newBuffer(char* s, feBufferTypes t, procinfo* pi, int lineno)
+{
+  currentVoice->Next();
+  //Print(":Buffer%d(%s):%s(%x)\n",
+  //  t,BT_name[t],pname,currentVoice);
+  if (pi!=NULL)
+  {
+    long l=strlen(pi->procname);
+    if (pi->libname!=NULL) l+=strlen(pi->libname);
+    currentVoice->filename = (char *)omAlloc(l+3);
+    *currentVoice->filename='\0';
+    if (pi->libname!=NULL) strcat(currentVoice->filename,pi->libname);
+    strcat(currentVoice->filename,"::");
+    strcat(currentVoice->filename,pi->procname);
+    currentVoice->pi       = pi;
+  }
+  else
+  {
+    currentVoice->filename = omStrDup(currentVoice->prev->filename);
+    currentVoice->pi       = currentVoice->prev->pi;
+  }
+  currentVoice->buffer   = s;
+  currentVoice->sw       = BI_buffer;
+  currentVoice->typ      = t;
+  switch (t)
+  {
+    case BT_execute:
+                     yylineno-=2;
+                     break;
+    case BT_proc:
+    case BT_example:
+                     currentVoice->oldb=myynewbuffer();
+                     yylineno = lineno+1;
+                     break;
+    case BT_if:
+    case BT_else:
+    case BT_break:
+                     yylineno = yy_blocklineno-1;
+                     break;
+    //case BT_file:
+    default:
+                     yylineno = 1;
+                     break;
+  }
+  //Print("start body (%s) at line %d\n",BT_name[t],yylineno);
+  currentVoice->start_lineno = yylineno;
+  //printf("start buffer typ %d\n",t);
+  //Voice *p=currentVoice;
+  //Print("-----------------\ncurr:");
+  //do
+  //{
+  //Print("voice fn:%s\n",p->filename);
+  //p=p->prev;
+  //}
+  //while (p!=NULL);
+  //Print("----------------\n");
+}
+
+/*2
+* exit Buffer of type 'typ':
+* returns 1 if buffer type could not be found
+*/
+BOOLEAN exitBuffer(feBufferTypes typ)
+{
+  //printf("exitBuffer: %d(%s),(%x)\n",
+  //  typ,BT_name[typ], currentVoice);
+  //Voice *p=currentVoice;
+  //Print("-----------------\ncurr:");
+  //do
+  //{
+  //Print("voice fn:%s\n",p->filename);
+  //p=p->prev;
+  //}
+  //while (p!=NULL);
+  //Print("----------------\n");
+  if (typ == BT_break)  // valid inside for, while. may skip if, else
+  {
+    /*4 first check for valid buffer type, skip if/else*/
+    Voice *p=currentVoice;
+    loop
+    {
+      if ((p->typ != BT_if)
+      &&(p->typ != BT_else))
+      {
+        if (p->typ == BT_break /*typ*/)
+        {
+          while (p != currentVoice)
+          {
+            exitVoice();
+          }
+          exitVoice();
+          return FALSE;
+        }
+        else return TRUE;
+      }
+      if (p->prev==NULL) break;
+      p=p->prev;
+    }
+    /*4 break not inside a for/while: return an error*/
+    if (/*typ*/ BT_break != currentVoice->typ) return 1;
+    return exitVoice();
+  }
+
+  if ((typ == BT_proc)
+  || (typ == BT_example))
+  {
+    Voice *p=currentVoice;
+    loop
+    {
+      if ((p->typ == BT_proc)
+      || (p->typ == BT_example))
+      {
+        while (p != currentVoice)
+        {
+          exitVoice();
+        }
+        exitVoice();
+        return FALSE;
+      }
+      if (p->prev==NULL) break;
+      p=p->prev;
+    }
+  }
+  /*4 return not inside a proc: return an error*/
+  return TRUE;
+}
+
+/*2
+* jump to the beginning of a buffer
+*/
+BOOLEAN contBuffer(feBufferTypes typ)
+{
+  //printf("contBuffer: %d(%s),(%x)\n",
+  //  typ,BT_name[typ], currentVoice);
+  if (typ == BT_break)  // valid inside for, while. may skip if, else
+  {
+    // first check for valid buffer type
+    Voice *p=currentVoice;
+    loop
+    {
+      if ((p->typ != BT_if)
+        &&(p->typ != BT_else))
+      {
+        if (p->typ == BT_break /*typ*/)
+        {
+          while (p != currentVoice)
+          {
+            exitVoice();
+          }
+          yylineno = currentVoice->start_lineno;
+          currentVoice->fptr=0;
+          return FALSE;
+        }
+        else return TRUE;
+      }
+      if (p->prev==NULL) break;
+      p=p->prev;
+    }
+  }
+  return TRUE;
+}
+
+/*2
+* leave a voice: kill local variables
+* setup everything from the previous level
+* return 1 if leaving the top level, 0 otherwise
+*/
+BOOLEAN exitVoice()
+{
+  //printf("exitVoice: %d(%s),(%x)\n",
+  //  currentVoice->typ,BT_name[currentVoice->typ], currentVoice);
+  //{
+  //Voice *p=currentVoice;
+  //Print("-----------------\ncurr:");
+  //do
+  //{
+  //Print("voice fn:%s\n",p->filename);
+  //p=p->prev;
+  //}
+  //while (p!=NULL);
+  //Print("----------------\n");
+  //}
+  if (currentVoice!=NULL)
+  {
+    if (currentVoice->oldb!=NULL)
+    {
+      myyoldbuffer(currentVoice->oldb);
+      currentVoice->oldb=NULL;
+    }
+    if ((currentVoice->prev==NULL)&&(currentVoice->sw==BI_file))
+    {
+      currentVoice->prev=feInitStdin(currentVoice);
+    }
+    if (currentVoice->prev!=NULL)
+    {
+      //printf("exitVoice typ %d(%s)\n",
+      //  currentVoice->typ,BT_name[currentVoice->typ]);
+      if (currentVoice->typ==BT_if)
+      {
+        currentVoice->prev->ifsw=2;
+      }
+      else
+      {
+        currentVoice->prev->ifsw=0;
+      }
+      if ((currentVoice->sw == BI_file)
+      && (currentVoice->files!=NULL))
+      {
+        fclose(currentVoice->files);
+      }
+      if (currentVoice->filename!=NULL)
+      {
+        omFree((ADDRESS)currentVoice->filename);
+        currentVoice->filename=NULL;
+      }
+      if (currentVoice->buffer!=NULL)
+      {
+        omFree((ADDRESS)currentVoice->buffer);
+        currentVoice->buffer=NULL;
+      }
+      yylineno=currentVoice->prev->curr_lineno;
+      currentVoice->prev->next=NULL;
+    }
+    Voice *p=currentVoice->prev;
+    delete currentVoice;
+    currentVoice=p;
+  }
+  return currentVoice==NULL;
+}
+
+/*2
+* set prompt_char
+* only called with currentVoice->sw == BI_stdin
+*/
+static void feShowPrompt(void)
+{
+  fe_promptstr[0]=prompt_char;
+}
+
+/*2
+* print echo (si_echo or TRACE), set my_yylinebuf
+*/
+static int fePrintEcho(char *anf, char */*b*/)
+{
+  char *ss=strrchr(anf,'\n');
+  int len_s;
+  if (ss==NULL)
+  {
+    len_s=strlen(anf);
+  }
+  else
+  {
+    len_s=ss-anf+1;
+  }
+  // my_yylinebuf:
+  int mrc=si_min(len_s,79)-1;
+  strcpy(my_yylinebuf,anf+(len_s-1)-mrc);
+  if (my_yylinebuf[mrc] == '\n') my_yylinebuf[mrc] = '\0';
+  mrc--;
+  // handle echo:
+  if (((si_echo>myynest)
+    && ((currentVoice->typ==BT_proc)
+      || (currentVoice->typ==BT_example)
+      || (currentVoice->typ==BT_file)
+      || (currentVoice->typ==BT_none)
+    )
+    && (strncmp(anf,";return();",10)!=0)
+   )
+  || (traceit&TRACE_SHOW_LINE)
+  || (traceit&TRACE_SHOW_LINE1))
+  {
+    if (currentVoice->typ!=BT_example)
+    {
+      if (currentVoice->filename==NULL)
+        Print("(none) %3d%c ",yylineno,prompt_char);
+      else
+        Print("%s %3d%c ",currentVoice->filename,yylineno,prompt_char);
+     }
+    {
+      fwrite(anf,1,len_s,stdout);
+      mflush();
+    }
+    if (traceit&TRACE_SHOW_LINE)
+    {
+      while(fgetc(stdin)!='\n');
+    }
+  }
+  else if (traceit&TRACE_SHOW_LINENO)
+  {
+    Print("{%d}",yylineno);
+    mflush();
+  }
+#ifdef HAVE_SDB
+  if ((blocknest==0)
+  && (currentVoice->pi!=NULL)
+  && (currentVoice->pi->trace_flag!=0))
+  {
+    sdb(currentVoice, anf, len_s);
+  }
+#endif
+  prompt_char = '.';
+  return len_s;
+}
+
+int feReadLine(char* b, int l)
+{
+  char *s=NULL;
+  int offset = 0; /* will not be used if s==NULL*/
+  // try to read from the buffer into b, max l chars
+  if (currentVoice!=NULL)
+  {
+    if((currentVoice->buffer!=NULL)
+    && (currentVoice->buffer[currentVoice->fptr]!='\0'))
+    {
+  NewBuff:
+      register int i=0;
+      long startfptr=currentVoice->fptr;
+      long tmp_ptr=currentVoice->fptr;
+      l--;
+      loop
+      {
+        register char c=
+        b[i]=currentVoice->buffer[tmp_ptr/*currentVoice->fptr*/];
+        i++;
+        if (yy_noeof==noeof_block)
+        {
+          if (c<' ')  yylineno++;
+          else if (c=='}') break;
+        }
+        else
+        {
+          if ((c<' ') ||
+          (c==';') ||
+          (c==')')
+          )
+            break;
+        }
+        if (i>=l) break;
+        tmp_ptr++;/*currentVoice->fptr++;*/
+        if(currentVoice->buffer[tmp_ptr/*currentVoice->fptr*/]=='\0') break;
+      }
+      currentVoice->fptr=tmp_ptr;
+      b[i]='\0';
+      if (currentVoice->sw==BI_buffer)
+      {
+        if (startfptr==0)
+        {
+          char *anf=currentVoice->buffer;
+          const char *ss=strchr(anf,'\n');
+          long len;
+          if (ss==NULL) len=strlen(anf);
+          else          len=ss-anf;
+          char *s=(char *)omAlloc(len+2);
+          strncpy(s,anf,len+2);
+          s[len+1]='\0';
+          fePrintEcho(s,b);
+          omFree((ADDRESS)s);
+        }
+        else if (/*(startfptr>0) &&*/
+        (currentVoice->buffer[startfptr-1]=='\n'))
+        {
+          char *anf=currentVoice->buffer+startfptr;
+          const char *ss=strchr(anf,'\n');
+          long len;
+          if (ss==NULL) len=strlen(anf);
+          else          len=ss-anf;
+          char *s=(char *)omAlloc(len+2);
+          strncpy(s,anf,len+2);
+          s[len+1]='\0';
+          yylineno++;
+          fePrintEcho(s,b);
+          omFree((ADDRESS)s);
+        }
+      }
+      currentVoice->fptr++;
+      return i;
+    }
+    // no buffer there or e-o-buffer or eoln:
+    if (currentVoice->sw!=BI_buffer)
+    {
+      currentVoice->fptr=0;
+      if (currentVoice->buffer==NULL)
+      {
+        currentVoice->buffer=(char *)omAlloc(MAX_FILE_BUFFER-sizeof(ADDRESS));
+        omMarkAsStaticAddr(currentVoice->buffer);
+      }
+    }
+    offset=0;
+  NewRead:
+    yylineno++;
+    if (currentVoice->sw==BI_stdin)
+    {
+      feShowPrompt();
+      s=fe_fgets_stdin(fe_promptstr,
+                       &(currentVoice->buffer[offset]),
+                       omSizeOfAddr(currentVoice->buffer)-1-offset);
+      //int i=0;
+      //if (s!=NULL)
+      //  while((s[i]!='\0') /*&& (i<MAX_FILE_BUFFER)*/) {s[i] &= (char)127;i++;}
+    }
+    else if (currentVoice->sw==BI_file)
+    {
+      s=fgets(currentVoice->buffer+offset,(MAX_FILE_BUFFER-1-sizeof(ADDRESS))-offset,
+              currentVoice->files);
+    }
+    //else /* BI_buffer */ s==NULL  => return 0
+    // done by the default return
+  }
+  if (s!=NULL)
+  {
+    // handle prot:
+    if (feProt&SI_PROT_I)
+    {
+      fputs(s,feProtFile);
+    }
+    int rc=fePrintEcho(s,b)+1;
+    //s[strlen(s)+1]='\0'; add an second \0 at the end of the string
+    s[rc]='\0';
+    // handel \\ :
+    rc-=3;
+    if ((s[rc]=='\\')&&(currentVoice->sw!=BI_buffer))
+    {
+      s[rc]='\0';
+      offset+=rc;
+      if (offset<(int)omSizeOfAddr(currentVoice->buffer)) goto NewRead;
+    }
+    goto NewBuff;
+  }
+  /* else if (s==NULL) */
+  {
+    const char *err;
+    switch(yy_noeof)
+    {
+      case noeof_brace:
+      case noeof_block:
+        err="{...}";
+        break;
+      case noeof_asstring:
+        err="till `.`";
+        break;
+      case noeof_string:
+        err="string";
+        break;
+      case noeof_bracket:
+        err="(...)";
+        break;
+      case noeof_procname:
+        err="proc";
+        break;
+      case noeof_comment:
+        err="/*...*/";
+        break;
+      default:
+        return 0;
+    }
+    Werror("premature end of file while reading %s",err);
+    return 0;
+  }
+}
+
+/*2
+* init all data structures
+*/
+#ifndef STDIN_FILENO
+#define STDIN_FILENO 0
+#endif
+Voice * feInitStdin(Voice *pp)
+{
+  Voice *p = new Voice;
+  p->files = stdin;
+  p->sw = (isatty(STDIN_FILENO)) ? BI_stdin : BI_file;
+  if ((pp!=NULL) && (pp->files==stdin))
+  {
+    p->files=freopen("/dev/tty","r",stdin);
+    //stdin=p->files;
+    p->sw = BI_stdin;
+  }
+  p->filename   = omStrDup("STDIN");
+  p->start_lineno   = 1;
+  omMarkAsStaticAddr(p);
+  omMarkAsStaticAddr(p->filename);
+  return p;
+}
+
+
+#else /* ! STANDALONE_PARSER */
+#include <stdio.h>
+
+#endif
+
diff --git a/Singular/fevoices.h b/Singular/fevoices.h
new file mode 100644
index 0000000..a53e89d
--- /dev/null
+++ b/Singular/fevoices.h
@@ -0,0 +1,105 @@
+#ifndef FEVOICES_H
+#define FEVOICES_H
+/****************************************
+ * *  Computer Algebra System SINGULAR     *
+ * ****************************************/
+/*
+ * * ABSTRACT: class Voice
+ * */
+
+#include <reporter/reporter.h>
+
+#include <resources/feResource.h>
+
+#include <kernel/structs.h>
+
+enum   feBufferTypes
+{
+  BT_none  = 0,  // entry level
+  BT_break = 1,  // while, for
+  BT_proc,       // proc
+  BT_example,    // example
+  BT_file,       // <"file"
+  BT_execute,    // execute
+  BT_if,         // if
+  BT_else        // else
+};
+
+enum   feBufferInputs
+{
+  BI_stdin = 1,
+  BI_buffer,
+  BI_file
+};
+enum noeof_t
+{
+  noeof_brace = 1,
+  noeof_asstring,
+  noeof_block,
+  noeof_bracket,
+  noeof_comment,
+  noeof_procname,
+  noeof_string
+};  /* for scanner.l */
+
+extern int yylineno;
+extern char my_yylinebuf[80];
+
+#ifdef __cplusplus
+
+/* the C++-part: */
+
+// LANG_TOP     : Toplevel package only
+// LANG_SINGULAR:
+// LANG_C       :
+//
+
+class Voice
+{
+  public:
+    Voice  * next;
+    Voice  * prev;
+    char   * filename;    // file name or proc name
+    procinfo * pi;        // proc info
+    void   * oldb;        // internal scanner buffer
+    // for files only:
+    FILE * files;         // file handle
+    // for buffers only:
+    char * buffer;        // buffer pointer
+    long   fptr;          // current position in buffer
+
+    int    start_lineno;  // lineno, to restore in recursion
+    int    curr_lineno;   // current lineno
+    feBufferInputs   sw;  // BI_stdin: read from STDIN
+                          // BI_buffer: buffer
+                          // BI_file: files
+    char   ifsw;          // if-switch:
+            /*1 ifsw==0: no if statement, else is invalid
+            *       ==1: if (0) processed, execute else
+            *       ==2: if (1) processed, else allowed but not executed
+            */
+    feBufferTypes   typ;  // buffer type: see BT_..
+
+  Voice() { memset(this,0,sizeof(*this));}
+  feBufferTypes Typ();
+  void Next();
+} ;
+
+extern Voice  *currentVoice;
+
+Voice * feInitStdin(Voice *pp);
+
+const  char * VoiceName();
+void    VoiceBackTrack();
+BOOLEAN contBuffer(feBufferTypes typ);
+BOOLEAN exitBuffer(feBufferTypes typ);
+BOOLEAN exitVoice();
+void    monitor(void *F, int mode); /* FILE*, int */
+BOOLEAN newFile(char* fname, FILE *f=NULL);
+void    newBuffer(char* s, feBufferTypes t, procinfo *pname = NULL, int start_lineno = 0);
+void *  myynewbuffer();
+void    myyoldbuffer(void * oldb);
+
+#endif
+#endif
+
diff --git a/Singular/fglm.cc b/Singular/fglm.cc
new file mode 100644
index 0000000..3f0e92e
--- /dev/null
+++ b/Singular/fglm.cc
@@ -0,0 +1,499 @@
+// emacs edit mode for this file is -*- C++ -*-
+
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT - The FGLM-Algorithm plus extension
+*   Calculate a reduced groebner basis for one ordering, given a
+*   reduced groebner basis for another ordering.
+*   In this file the input is checked. Furthermore we decide, if
+*   the input is 0-dimensional ( then fglmzero.cc is used ) or
+*   if the input is homogeneous ( then fglmhom.cc is used. Yet
+*   not implemented ).
+*   The extension (finduni) finds minimal univariate Polynomials
+*   lying in a 0-dimensional ideal.
+*/
+
+
+
+
+#include <kernel/mod2.h>
+
+#include <omalloc/omalloc.h>
+#include <misc/options.h>
+
+#include <polys/monomials/ring.h>
+#include <polys/monomials/maps.h>
+
+#include <kernel/polys.h>
+#include <kernel/ideals.h>
+
+#include <kernel/GBEngine/kstd1.h>
+#include <kernel/fglm/fglm.h>
+
+#include <Singular/fglm.h>
+#include <Singular/ipid.h>
+#include <Singular/ipshell.h>
+#include <Singular/tok.h>
+
+
+// internal Version: 1.18.1.6
+//     enumeration to handle the various errors to occour.
+enum FglmState{
+    FglmOk,
+    FglmHasOne,
+    FglmNoIdeal,
+    FglmNotReduced,
+    FglmNotZeroDim,
+    FglmIncompatibleRings,
+    // for fglmquot:
+    FglmPolyIsOne,
+    FglmPolyIsZero
+};
+
+// Has to be called, if currRing->qideal != NULL. ( i.e. qring-case )
+// Then a new ideal is build, consisting of the generators of sourceIdeal
+// and the generators of currRing->qideal, which are completely reduced by
+// the sourceIdeal. This means: If sourceIdeal is reduced, then the new
+// ideal will be reduced as well.
+// Assumes that currRing == sourceRing
+ideal fglmUpdatesource( const ideal sourceIdeal )
+{
+    int k, l, offset;
+    BOOLEAN found;
+    ideal newSource= idInit( IDELEMS( sourceIdeal ) + IDELEMS( currRing->qideal ), 1 );
+    for ( k= IDELEMS( sourceIdeal )-1; k >=0; k-- )
+        (newSource->m)[k]= pCopy( (sourceIdeal->m)[k] );
+    offset= IDELEMS( sourceIdeal );
+    for ( l= IDELEMS( currRing->qideal )-1; l >= 0; l-- )
+    {
+        if ( (currRing->qideal->m)[l] != NULL )
+        {
+            found= FALSE;
+            for ( k= IDELEMS( sourceIdeal )-1; (k >= 0) && (found == FALSE); k-- )
+                if ( pDivisibleBy( (sourceIdeal->m)[k], (currRing->qideal->m)[l] ) )
+                    found= TRUE;
+            if ( ! found )
+            {
+                (newSource->m)[offset]= pCopy( (currRing->qideal->m)[l] );
+                offset++;
+            }
+        }
+    }
+    idSkipZeroes( newSource );
+    return newSource;
+}
+
+// Has to be called, if currRing->qideal != NULL, i.e. in qring-case.
+// Gets rid of the elements of result which are contained in
+// currRing->qideal and skips Zeroes.
+// Assumes that currRing == destRing
+void
+fglmUpdateresult( ideal & result )
+{
+    int k, l;
+    BOOLEAN found;
+    for ( k= IDELEMS( result )-1; k >=0; k-- )
+    {
+        if ( (result->m)[k] != NULL )
+        {
+            found= FALSE;
+            for ( l= IDELEMS( currRing->qideal )-1; (l >= 0) && ( found == FALSE ); l-- )
+                if ( pDivisibleBy( (currRing->qideal->m)[l], (result->m)[k] ) )
+                    found= TRUE;
+            if ( found ) pDelete( & ((result->m)[k]) );
+        }
+    }
+    idSkipZeroes( result );
+}
+
+// Checks if the two rings sringHdl and dringHdl are compatible enough to
+// be used for the fglm. This means:
+//  1) Same Characteristic, 2) globalOrderings in both rings,
+//  3) Same number of variables, 4) same number of parameters
+//  5) variables in one ring are permutated variables of the other one
+//  6) parameters in one ring are permutated parameters of the other one
+//  7) either both rings are rings or both rings are qrings
+//  8) if they are qrings, the quotientIdeals of both must coincide.
+// vperm must be a vector of length pVariables+1, initialized by 0.
+// If both rings are compatible, it stores the permutation of the
+// variables if mapped from sringHdl to dringHdl.
+// if the rings are compatible, it returns FglmOk.
+// Should be called with currRing= IDRING( sringHdl );
+FglmState
+fglmConsistency( idhdl sringHdl, idhdl dringHdl, int * vperm )
+{
+    int k;
+    FglmState state= FglmOk;
+    ring dring = IDRING( dringHdl );
+    ring sring = IDRING( sringHdl );
+
+    if ( rChar(sring) != rChar(dring) )
+    {
+        WerrorS( "rings must have same characteristic" );
+        state= FglmIncompatibleRings;
+    }
+    if ( (sring->OrdSgn != 1) || (dring->OrdSgn != 1) )
+    {
+        WerrorS( "only works for global orderings" );
+        state= FglmIncompatibleRings;
+    }
+    if ( sring->N != dring->N )
+    {
+        WerrorS( "rings must have same number of variables" );
+        state= FglmIncompatibleRings;
+    }
+    if ( rPar(sring) != rPar(dring) )
+    {
+        WerrorS( "rings must have same number of parameters" );
+        state= FglmIncompatibleRings;
+    }
+    if ( state != FglmOk ) return state;
+    // now the rings have the same number of variables resp. parameters.
+    // check if the names of the variables resp. parameters do agree:
+    int nvar = sring->N;
+    int npar = rPar(sring);
+    int * pperm;
+    if ( npar > 0 )
+        pperm= (int *)omAlloc0( (npar+1)*sizeof( int ) );
+    else
+        pperm= NULL;
+    maFindPerm( sring->names, nvar, rParameter(sring), npar,
+                dring->names, nvar, rParameter(dring), npar, vperm, pperm,
+                dring->cf->type);
+    for ( k= nvar; (k > 0) && (state == FglmOk); k-- )
+        if ( vperm[k] <= 0 )
+        {
+            WerrorS( "variable names do not agree" );
+            state= FglmIncompatibleRings;
+        }
+    for ( k= npar-1; (k >= 0) && (state == FglmOk); k-- )
+        if ( pperm[k] >= 0 )
+        {
+            WerrorS( "paramater names do not agree" );
+            state= FglmIncompatibleRings;
+        }
+    if (pperm != NULL) // OB: ????
+      omFreeSize( (ADDRESS)pperm, (npar+1)*sizeof( int ) );
+    if ( state != FglmOk ) return state;
+    // check if both rings are qrings or not
+    if ( sring->qideal != NULL )
+    {
+        if ( dring->qideal == NULL )
+        {
+            Werror( "%s is a qring, current ring not", sringHdl->id );
+            return FglmIncompatibleRings;
+        }
+        // both rings are qrings, now check if both quotients define the same ideal.
+        // check if sring->qideal is contained in dring->qideal:
+        rSetHdl( dringHdl );
+        nMapFunc nMap=n_SetMap(currRing->cf, sring->cf );
+        ideal sqind = idInit( IDELEMS( sring->qideal ), 1 );
+        for ( k= IDELEMS( sring->qideal )-1; k >= 0; k-- )
+          (sqind->m)[k]= p_PermPoly( (sring->qideal->m)[k], vperm, sring,
+                          currRing, nMap);
+        ideal sqindred = kNF( dring->qideal, NULL, sqind );
+        if ( ! idIs0( sqindred ) )
+        {
+            WerrorS( "the quotients do not agree" );
+            state= FglmIncompatibleRings;
+        }
+        idDelete( & sqind );
+        idDelete( & sqindred );
+        rSetHdl( sringHdl );
+        if ( state != FglmOk ) return state;
+        // check if dring->qideal is contained in sring->qideal:
+        int * dsvperm = (int *)omAlloc0( (nvar+1)*sizeof( int ) );
+        maFindPerm( dring->names, nvar, NULL, 0, sring->names, nvar, NULL, 0,
+                    dsvperm, NULL, sring->cf->type);
+        nMap=n_SetMap(currRing->cf, dring->cf);
+        ideal dqins = idInit( IDELEMS( dring->qideal ), 1 );
+        for ( k= IDELEMS( dring->qideal )-1; k >= 0; k-- )
+          (dqins->m)[k]=p_PermPoly( (dring->qideal->m)[k], dsvperm, sring,
+                         currRing, nMap);
+        ideal dqinsred = kNF( sring->qideal, NULL, dqins );
+        if ( ! idIs0( dqinsred ) )
+        {
+            WerrorS( "the quotients do not agree" );
+            state= FglmIncompatibleRings;
+        }
+        idDelete( & dqins );
+        idDelete( & dqinsred );
+        omFreeSize( (ADDRESS)dsvperm, (nvar+1)*sizeof( int ) );
+        if ( state != FglmOk ) return state;
+    }
+    else
+    {
+        if ( dring->qideal != NULL )
+        {
+            Werror( "current ring is a qring, %s not", sringHdl->id );
+            return FglmIncompatibleRings;
+        }
+    }
+    return FglmOk;
+}
+
+// Checks if the ideal "theIdeal" is zero-dimensional and minimal. It does
+//  not check, if it is reduced.
+// returns FglmOk if we can use theIdeal for CalculateFunctionals (this
+//                 function reports an error if theIdeal is not reduced,
+//                 so this need not to be tested here)
+//         FglmNotReduced if theIdeal is not minimal
+//         FglmNotZeroDim if it is not zero-dimensional
+//         FglmHasOne if 1 belongs to theIdeal
+FglmState
+fglmIdealcheck( const ideal theIdeal )
+{
+    FglmState state = FglmOk;
+    int power;
+    int k;
+    BOOLEAN * purePowers = (BOOLEAN *)omAlloc0( currRing->N*sizeof( BOOLEAN ) );
+
+    for ( k= IDELEMS( theIdeal ) - 1; (state == FglmOk) && (k >= 0); k-- )
+    {
+        poly p = (theIdeal->m)[k];
+        if (p!=NULL)
+        {
+          if( pIsConstant( p ) ) state= FglmHasOne;
+          else if ( (power= pIsPurePower( p )) > 0 )
+          {
+            fglmASSERT( 0 < power && power <= currRing->N, "illegal power" );
+            if ( purePowers[power-1] == TRUE  ) state= FglmNotReduced;
+            else purePowers[power-1]= TRUE;
+          }
+          for ( int l = IDELEMS( theIdeal ) - 1; state == FglmOk && l >= 0; l-- )
+            if ( (k != l) && pDivisibleBy( p, (theIdeal->m)[l] ) )
+                state= FglmNotReduced;
+        }
+    }
+    if ( state == FglmOk )
+    {
+        for ( k= currRing->N-1 ; (state == FglmOk) && (k >= 0); k-- )
+            if ( purePowers[k] == FALSE ) state= FglmNotZeroDim;
+    }
+    omFreeSize( (ADDRESS)purePowers, currRing->N*sizeof( BOOLEAN ) );
+    return state;
+}
+
+// The main function for the fglm-Algorithm.
+// Checks the input-data, and calls fglmzero (see fglmzero.cc).
+// Returns the new groebnerbasis or 0 if an error occoured.
+BOOLEAN
+fglmProc( leftv result, leftv first, leftv second )
+{
+    FglmState state = FglmOk;
+
+    idhdl destRingHdl = currRingHdl;
+    // ring destRing = currRing;
+    ideal destIdeal = NULL;
+    idhdl sourceRingHdl = (idhdl)first->data;
+    rSetHdl( sourceRingHdl );
+    // ring sourceRing = currRing;
+
+    int * vperm = (int *)omAlloc0( (currRing->N+1)*sizeof( int ) );
+    state= fglmConsistency( sourceRingHdl, destRingHdl, vperm );
+    omFreeSize( (ADDRESS)vperm, (currRing->N+1)*sizeof(int) );
+
+    if ( state == FglmOk )
+    {
+        idhdl ih = currRing->idroot->get( second->Name(), myynest );
+        if ( (ih != NULL) && (IDTYP(ih)==IDEAL_CMD) )
+        {
+            ideal sourceIdeal;
+            if ( currRing->qideal != NULL )
+                sourceIdeal= fglmUpdatesource( IDIDEAL( ih ) );
+            else
+                sourceIdeal = IDIDEAL( ih );
+            state= fglmIdealcheck( sourceIdeal );
+            if ( state == FglmOk )
+            {
+                // Now the settings are compatible with FGLM
+                assumeStdFlag( (leftv)ih );
+                if ( fglmzero( IDRING(sourceRingHdl), sourceIdeal, IDRING(destRingHdl), destIdeal, FALSE, (currRing->qideal != NULL) ) == FALSE )
+                    state= FglmNotReduced;
+            }
+        } else state= FglmNoIdeal;
+    }
+    if ( currRingHdl != destRingHdl )
+        rSetHdl( destRingHdl );
+    switch (state)
+    {
+        case FglmOk:
+            if ( currRing->qideal != NULL ) fglmUpdateresult( destIdeal );
+            break;
+        case FglmHasOne:
+            destIdeal= idInit(1,1);
+            (destIdeal->m)[0]= pOne();
+            state= FglmOk;
+            break;
+        case FglmIncompatibleRings:
+            Werror( "ring %s and current ring are incompatible", first->Name() );
+            destIdeal= NULL;
+            break;
+        case FglmNoIdeal:
+            Werror( "Can't find ideal %s in ring %s", second->Name(), first->Name() );
+            destIdeal= NULL;
+            break;
+        case FglmNotZeroDim:
+            Werror( "The ideal %s has to be 0-dimensional", second->Name() );
+            destIdeal= NULL;
+            break;
+        case FglmNotReduced:
+            Werror( "The ideal %s has to be given by a reduced SB", second->Name() );
+            destIdeal= NULL;
+            break;
+        default:
+            destIdeal= idInit(1,1);
+    }
+
+    result->rtyp = IDEAL_CMD;
+    result->data= (void *)destIdeal;
+    setFlag( result, FLAG_STD );
+    return (state != FglmOk);
+}
+
+// fglmQuotProc: Calculate I:f with FGLM methods.
+// Checks the input-data, and calls fglmquot (see fglmzero.cc).
+// Returns the new groebnerbasis if I:f or 0 if an error occoured.
+BOOLEAN
+fglmQuotProc( leftv result, leftv first, leftv second )
+{
+    FglmState state = FglmOk;
+
+    //    STICKYPROT("quotstart\n");
+    ideal sourceIdeal = (ideal)first->Data();
+    poly quot = (poly)second->Data();
+    ideal destIdeal = NULL;
+
+    state = fglmIdealcheck( sourceIdeal );
+    if ( state == FglmOk )
+    {
+      if ( quot == NULL ) state= FglmPolyIsZero;
+      else if ( pIsConstant( quot ) ) state= FglmPolyIsOne;
+    }
+
+    if ( state == FglmOk )
+    {
+      assumeStdFlag( first );
+      if ( fglmquot( sourceIdeal, quot, destIdeal ) == FALSE )
+        state= FglmNotReduced;
+    }
+
+    switch (state)
+    {
+        case FglmOk:
+            break;
+        case FglmHasOne:
+            destIdeal= idInit(1,1);
+            (destIdeal->m)[0]= pOne();
+            state= FglmOk;
+            break;
+        case FglmNotZeroDim:
+            Werror( "The ideal %s has to be 0-dimensional", first->Name() );
+            destIdeal= NULL;
+            break;
+        case FglmNotReduced:
+            Werror( "The poly %s has to be reduced", second->Name() );
+            destIdeal= NULL;
+            break;
+        case FglmPolyIsOne:
+            int k;
+            destIdeal= idInit( IDELEMS(sourceIdeal), 1 );
+            for ( k= IDELEMS( sourceIdeal )-1; k >=0; k-- )
+              (destIdeal->m)[k]= pCopy( (sourceIdeal->m)[k] );
+            state= FglmOk;
+            break;
+        case FglmPolyIsZero:
+            destIdeal= idInit(1,1);
+            (destIdeal->m)[0]= pOne();
+            state= FglmOk;
+            break;
+        default:
+            destIdeal= idInit(1,1);
+    }
+
+    result->rtyp = IDEAL_CMD;
+    result->data= (void *)destIdeal;
+    setFlag( result, FLAG_STD );
+    // STICKYPROT("quotend\n");
+    return (state != FglmOk);
+} // fglmQuotProt
+
+// The main function for finduni().
+// Checks the input-data, and calls FindUnivariateWrapper (see fglmzero.cc).
+// Returns an ideal containing the univariate Polynomials or 0 if an error
+// has occoured.
+BOOLEAN
+findUniProc( leftv result, leftv first )
+{
+    ideal sourceIdeal;
+    ideal destIdeal = NULL;
+    FglmState state;
+
+    sourceIdeal = (ideal)first->Data();
+
+    assumeStdFlag( first );
+    state= fglmIdealcheck( sourceIdeal );
+    if ( state == FglmOk )
+    {
+      // check for special cases: if the input contains
+      // univariate polys, try to reduce the problem
+      int i,k;
+      int count=0;
+      BOOLEAN * purePowers = (BOOLEAN *)omAlloc0( currRing->N*sizeof( BOOLEAN ) );
+      for ( k= IDELEMS( sourceIdeal ) - 1; k >= 0; k-- )
+      {
+        if((i=pIsUnivariate(sourceIdeal->m[k]))>0)
+        {
+          if (purePowers[i-1]==0)
+          {
+            purePowers[i-1]=k;
+            count++;
+            if (count==currRing->N) break;
+          }
+        }
+      }
+      if (count==currRing->N)
+      {
+        destIdeal=idInit(currRing->N,1);
+        for(k=currRing->N-1; k>=0; k--) destIdeal->m[k]=pCopy(sourceIdeal->m[purePowers[k]]);
+      }
+      omFreeSize((ADDRESS)purePowers, currRing->N*sizeof( BOOLEAN ) );
+      if (destIdeal!=NULL)
+            state = FglmOk;
+      else if ( FindUnivariateWrapper( sourceIdeal, destIdeal ) == FALSE )
+            state = FglmNotReduced;
+    }
+    switch (state)
+    {
+        case FglmOk:
+            break;
+        case FglmHasOne:
+            destIdeal= idInit(1,1);
+            (destIdeal->m)[0]= pOne();
+            state= FglmOk;
+            break;
+        case FglmNotZeroDim:
+            Werror( "The ideal %s has to be 0-dimensional", first->Name() );
+            destIdeal= NULL;
+            break;
+        case FglmNotReduced:
+            Werror( "The ideal %s has to be reduced", first->Name() );
+            destIdeal= NULL;
+            break;
+        default:
+            destIdeal= idInit(1,1);
+    }
+
+    result->rtyp = IDEAL_CMD;
+    result->data= (void *)destIdeal;
+
+    return FALSE;
+}
+// ----------------------------------------------------------------------------
+// Local Variables: ***
+// compile-command: "make Singular" ***
+// page-delimiter: "^\\(
\\|//!\\)" ***
+// fold-internal-margins: nil ***
+// End: ***
diff --git a/Singular/fglm.h b/Singular/fglm.h
new file mode 100644
index 0000000..f6eb578
--- /dev/null
+++ b/Singular/fglm.h
@@ -0,0 +1,36 @@
+#ifndef SINGULAR_FGLM_H
+#define SINGULAR_FGLM_H
+
+#include <misc/auxiliary.h>
+
+#include <kernel/ideals.h>
+#include <kernel/structs.h>
+
+// fglmproc(...):
+// The procedure which has to be called from the interpreter for fglm.
+// first is the sourceRing, second is the given ideal in sourceRing.
+// Returns the groebnerbasis of the sourceIdeal in the currentRing.
+// Checks, if the ideal is really a reduced groebner basis of a
+// 0-dimensional Ideal. Returns TRUE if an error occoured.
+BOOLEAN fglmProc( leftv result, leftv first, leftv second );
+
+// fglmquotproc(...):
+// The procedure which has to be called from the interpreter for fglmquot.
+// first is the ideal I, second is the polynomial q. The polynomial must
+// be reduced with respect to I.
+// Returns the groebnerbasis of I:q in the currentRing.
+// Checks, if the ideal is really a reduced groebner basis of a
+// 0-dimensional Ideal and if q is really reduced.
+//  Returns TRUE if an error occoured.
+BOOLEAN fglmQuotProc( leftv result, leftv first, leftv second );
+
+// FindUnivariatePolys (test)
+BOOLEAN FindUnivariateWrapper( ideal source, ideal & dest );
+
+// wrapper for FindUnivariatePolys (test)
+BOOLEAN findUniProc( leftv result, leftv first);
+
+// homogeneous FGLM
+ideal fglmhomProc(leftv first, leftv second);
+
+#endif // #ifndef SINGULAR_FGLM_H
diff --git a/Singular/gentable.cc b/Singular/gentable.cc
new file mode 100644
index 0000000..0f71c41
--- /dev/null
+++ b/Singular/gentable.cc
@@ -0,0 +1,948 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: generate iparith.inc etc.
+*/
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <time.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+// need global defines:
+#include "kernel/mod2.h"
+// need to include all tokens: *_CMD:
+#include "grammar.h"
+#include "tok.h"
+
+inline int RingDependend(int t) { return (BEGIN_RING<t)&&(t<END_RING); }
+
+// to produce convert_table.texi for doc:
+int produce_convert_table=0;
+
+// bits 0,1 for PLURAL
+#define NO_PLURAL        0
+#define ALLOW_PLURAL     1
+#define COMM_PLURAL      2
+#define PLURAL_MASK      3
+
+// bit 2 for RING-CF
+#define ALLOW_RING       4
+#define NO_RING          0
+
+// bit 3 for zerodivisors
+#define NO_ZERODIVISOR   8
+#define ALLOW_ZERODIVISOR  0
+#define ZERODIVISOR_MASK 8
+
+// bit 4 for warning, if used at toplevel
+#define WARN_RING        16
+
+/*=============== types =====================*/
+struct _scmdnames
+{
+  const char *name;
+  short alias;
+  short tokval;
+  short toktype;
+};
+typedef struct _scmdnames cmdnames;
+
+
+struct sValCmd2
+{
+  int p;
+  short cmd;
+  short res;
+  short arg1;
+  short arg2;
+  short valid_for;
+};
+struct sValCmd1
+{
+  int p;
+  short cmd;
+  short res;
+  short arg;
+  short valid_for;
+};
+struct sValCmd3
+{
+  int p;
+  short cmd;
+  short res;
+  short arg1;
+  short arg2;
+  short arg3;
+  short valid_for;
+};
+struct sValCmdM
+{
+  int p;
+  short cmd;
+  short res;
+  short number_of_args; /* -1: any, -2: any >0, .. */
+  short valid_for;
+};
+struct sValAssign_sys
+{
+  int p;
+  short res;
+  short arg;
+};
+
+struct sValAssign
+{
+  int p;
+  short res;
+  short arg;
+};
+
+struct sConvertTypes
+{
+  int i_typ;
+  int o_typ;
+  int p;
+  int pl;
+};
+
+
+#define jjWRONG   1
+#define jjWRONG2  1
+#define jjWRONG3  1
+
+#define D(A)     2
+#define NULL_VAL 0
+#define IPARITH
+#define GENTABLE
+#define IPCONV
+#define IPASSIGN
+
+#include "table.h"
+
+const char * Tok2Cmdname(int tok)
+{
+  if (tok < 0)
+  {
+    return cmds[0].name;
+  }
+  if (tok==COMMAND) return "command";
+  if (tok==ANY_TYPE) return "any_type";
+  if (tok==NONE) return "nothing";
+  //if (tok==IFBREAK) return "if_break";
+  //if (tok==VECTOR_FROM_POLYS) return "vector_from_polys";
+  //if (tok==ORDER_VECTOR) return "ordering";
+  //if (tok==REF_VAR) return "ref";
+  //if (tok==OBJECT) return "object";
+  //if (tok==PRINT_EXPR) return "print_expr";
+  if (tok==IDHDL) return "identifier";
+  if (tok==CRING_CMD) return "(c)ring";
+  // we do not blackbox objects during table generation:
+  //if (tok>MAX_TOK) return getBlackboxName(tok);
+  int i = 0;
+  while (cmds[i].tokval!=0)
+  {
+    if ((cmds[i].tokval == tok)&&(cmds[i].alias==0))
+    {
+      return cmds[i].name;
+    }
+    i++;
+  }
+  i=0;// try again for old/alias names:
+  while (cmds[i].tokval!=0)
+  {
+    if (cmds[i].tokval == tok)
+    {
+      return cmds[i].name;
+    }
+    i++;
+  }
+  #if 0
+  char *s=(char*)malloc(10);
+  sprintf(s,"(%d)",tok);
+  return s;
+  #else
+  return cmds[0].name;
+  #endif
+}
+/*---------------------------------------------------------------------*/
+/**
+ * @brief compares to entry of cmdsname-list
+
+ @param[in] a
+ @param[in] b
+
+ @return <ReturnValue>
+**/
+/*---------------------------------------------------------------------*/
+static int _gentable_sort_cmds( const void *a, const void *b )
+{
+  cmdnames *pCmdL = (cmdnames*)a;
+  cmdnames *pCmdR = (cmdnames*)b;
+
+  if(a==NULL || b==NULL)             return 0;
+
+  /* empty entries goes to the end of the list for later reuse */
+  if(pCmdL->name==NULL) return 1;
+  if(pCmdR->name==NULL) return -1;
+
+  /* $INVALID$ must come first */
+  if(strcmp(pCmdL->name, "$INVALID$")==0) return -1;
+  if(strcmp(pCmdR->name, "$INVALID$")==0) return  1;
+
+  /* tokval=-1 are reserved names at the end */
+  if (pCmdL->tokval==-1)
+  {
+    if (pCmdR->tokval==-1)
+       return strcmp(pCmdL->name, pCmdR->name);
+    /* pCmdL->tokval==-1, pCmdL goes at the end */
+    return 1;
+  }
+  /* pCmdR->tokval==-1, pCmdR goes at the end */
+  if(pCmdR->tokval==-1) return -1;
+
+  return strcmp(pCmdL->name, pCmdR->name);
+}
+
+static int _texi_sort_cmds( const void *a, const void *b )
+{
+  cmdnames *pCmdL = (cmdnames*)a;
+  cmdnames *pCmdR = (cmdnames*)b;
+
+  if(a==NULL || b==NULL)             return 0;
+
+  /* empty entries goes to the end of the list for later reuse */
+  if(pCmdL->name==NULL) return 1;
+  if(pCmdR->name==NULL) return -1;
+
+  /* $INVALID$ must come first */
+  if(strcmp(pCmdL->name, "$INVALID$")==0) return -1;
+  if(strcmp(pCmdR->name, "$INVALID$")==0) return  1;
+  char *ls=strdup(pCmdL->name);
+  char *rs=strdup(pCmdR->name);
+  char *s=ls;
+  while (*s) { *s=tolower(*s); s++; }
+  s=rs;
+  while (*s) { *s=tolower(*s); s++; }
+
+  /* tokval=-1 are reserved names at the end */
+  if (pCmdL->tokval==-1)
+  {
+    if (pCmdR->tokval==-1)
+       { int r=strcmp(ls,rs); free(ls); free(rs); return r; }
+    /* pCmdL->tokval==-1, pCmdL goes at the end */
+    free(ls);free(rs);
+    return 1;
+  }
+  /* pCmdR->tokval==-1, pCmdR goes at the end */
+  if(pCmdR->tokval==-1)
+  { free(ls);free(rs);return -1;}
+
+  { int r=strcmp(ls,rs); free(ls); free(rs); return r; }
+}
+
+/*generic*/
+const char * iiTwoOps(int t)
+{
+  if (t<127)
+  {
+    static char ch[2];
+    switch (t)
+    {
+      case '&':
+        return "and";
+      case '|':
+        return "or";
+      default:
+        ch[0]=t;
+        ch[1]='\0';
+        return ch;
+    }
+  }
+  switch (t)
+  {
+    case COLONCOLON:  return "::";
+    case DOTDOT:      return "..";
+    //case PLUSEQUAL:   return "+=";
+    //case MINUSEQUAL:  return "-=";
+    case MINUSMINUS:  return "--";
+    case PLUSPLUS:    return "++";
+    case EQUAL_EQUAL: return "==";
+    case LE:          return "<=";
+    case GE:          return ">=";
+    case NOTEQUAL:    return "<>";
+    default:          return Tok2Cmdname(t);
+  }
+}
+//
+// automatic conversions:
+//
+/*2
+* try to convert 'inputType' in 'outputType'
+* return 0 on failure, an index (<>0) on success
+* GENTABLE variant!
+*/
+int iiTestConvert (int inputType, int outputType)
+{
+  if ((inputType==outputType)
+  || (outputType==DEF_CMD)
+  || (outputType==IDHDL)
+  || (outputType==ANY_TYPE))
+  {
+    return -1;
+  }
+
+  // search the list
+  int i=0;
+  while (dConvertTypes[i].i_typ!=0)
+  {
+    if((dConvertTypes[i].i_typ==inputType)
+    &&(dConvertTypes[i].o_typ==outputType))
+    {
+      //Print("test convert %d to %d (%s -> %s):%d\n",inputType,outputType,
+      //Tok2Cmdname(inputType), Tok2Cmdname(outputType),i+1);
+      return i+1;
+    }
+    i++;
+  }
+  //Print("test convert %d to %d (%s -> %s):0\n",inputType,outputType,
+  // Tok2Cmdname(inputType), Tok2Cmdname(outputType));
+  return 0;
+}
+char *iparith_inc;
+void ttGen1()
+{
+  iparith_inc=strdup("iparith.xxxxxx");
+  int pid=getpid();
+  iparith_inc[8]=(pid %10)+'0'; pid/=10;
+  iparith_inc[9]=(pid %10)+'0'; pid/=10;
+  iparith_inc[10]=(pid %10)+'0'; pid/=10;
+  iparith_inc[11]=(pid %10)+'0'; pid/=10;
+  iparith_inc[12]=(pid %10)+'0'; pid/=10;
+  iparith_inc[13]=(pid %10)+'0';
+  FILE *outfile = fopen(iparith_inc,"w");
+  int i,j,l1=0,l2=0;
+  fprintf(outfile,
+  "/****************************************\n"
+  "*  Computer Algebra System SINGULAR     *\n"
+  "****************************************/\n\n");
+/*-------------------------------------------------------------------*/
+  fprintf(outfile,"// syntax table for Singular\n//\n");
+  fprintf(outfile,"// - search for an exact match of the argument types\n");
+  fprintf(outfile,"// - otherwise search for the first possibility\n");
+  fprintf(outfile,"//   with converted types of the arguments\n");
+  fprintf(outfile,"// - otherwise report an error\n//\n");
+
+  int op;
+  i=0;
+  while ((op=dArith1[i].cmd)!=0)
+  {
+    if (dArith1[i].p==jjWRONG)
+      fprintf(outfile,"// DUMMY ");
+    const char *s = iiTwoOps(op);
+    fprintf(outfile,"// operation: %s (%s)  ->  %s\n",
+          s,
+          Tok2Cmdname(dArith1[i].arg),
+          Tok2Cmdname(dArith1[i].res));
+    if (RingDependend(dArith1[i].res) && (!RingDependend(dArith1[i].arg)))
+    {
+      fprintf(outfile,"// WARNING: %s requires currRing\n",s);
+    }
+    i++;
+  }
+  fprintf(outfile,"/*---------------------------------------------*/\n");
+  i=0;
+  while ((op=dArith2[i].cmd)!=0)
+  {
+    if (dArith2[i].p==jjWRONG2)
+      fprintf(outfile,"// DUMMY ");
+    const char *s = iiTwoOps(op);
+    fprintf(outfile,"// operation: %s (%s, %s)  ->  %s\n",
+          s,
+          Tok2Cmdname(dArith2[i].arg1),
+          Tok2Cmdname(dArith2[i].arg2),
+          Tok2Cmdname(dArith2[i].res));
+    if (RingDependend(dArith2[i].res)
+       && (!RingDependend(dArith2[i].arg1))
+       && (!RingDependend(dArith2[i].arg2)))
+    {
+      fprintf(outfile,"// WARNING: %s requires currRing\n",s);
+    }
+    i++;
+  }
+  fprintf(outfile,"/*---------------------------------------------*/\n");
+  i=0;
+  while ((op=dArith3[i].cmd)!=0)
+  {
+    const char *s = iiTwoOps(op);
+    if (dArith3[i].p==jjWRONG3)
+      fprintf(outfile,"// DUMMY ");
+    fprintf(outfile,"// operation: %s (%s, %s, %s)  ->  %s\n",
+          s,
+          Tok2Cmdname(dArith3[i].arg1),
+          Tok2Cmdname(dArith3[i].arg2),
+          Tok2Cmdname(dArith3[i].arg3),
+          Tok2Cmdname(dArith3[i].res));
+    if (RingDependend(dArith3[i].res)
+       && (!RingDependend(dArith3[i].arg1))
+       && (!RingDependend(dArith3[i].arg2))
+       && (!RingDependend(dArith3[i].arg3)))
+    {
+      fprintf(outfile,"// WARNING: %s requires currRing\n",s);
+    }
+    i++;
+  }
+  fprintf(outfile,"/*---------------------------------------------*/\n");
+  i=0;
+  while ((op=dArithM[i].cmd)!=0)
+  {
+    const char *s = iiTwoOps(op);
+    fprintf(outfile,"// operation: %s (...)  ->  %s",
+          s,
+          Tok2Cmdname(dArithM[i].res));
+    switch(dArithM[i].number_of_args)
+    {
+      case -2:
+         fprintf(outfile," ( number of arguments >0 )\n");
+         break;
+      case -1:
+         fprintf(outfile," ( any number of arguments )\n");
+         break;
+      default:
+         fprintf(outfile," ( %d arguments )\n",dArithM[i].number_of_args);
+         break;
+    }
+    i++;
+  }
+  fprintf(outfile,"/*---------------------------------------------*/\n");
+  i=0;
+  while ((op=dAssign[i].res)!=0)
+  {
+    fprintf(outfile,"// assign: %s =  %s\n",
+          Tok2Cmdname(op/*dAssign[i].res*/),
+          Tok2Cmdname(dAssign[i].arg));
+    i++;
+  }
+/*-------------------------------------------------------------------*/
+  fprintf(outfile,"/*---------------------------------------------*/\n");
+  FILE *doctable;
+  if (produce_convert_table)
+  {
+    doctable=fopen("convert_table.texi","w");
+    fprintf(doctable,"@multitable @columnfractions .05 .18 .81\n");
+  }
+  int doc_nr=1;
+  for (j=257;j<=MAX_TOK+1;j++)
+  {
+    for(i=257;i<=MAX_TOK+1;i++)
+    {
+      if ((i!=j) && (j!=IDHDL) && (j!=DEF_CMD) && (j!=ANY_TYPE)
+      && iiTestConvert(i,j))
+      {
+        fprintf(outfile,"// convert %s -> %s\n",
+          Tok2Cmdname(i), Tok2Cmdname(j));
+        if (produce_convert_table)
+        {
+          fprintf(doctable,
+          "@item\n@   %d. @tab @code{%s}  @tab @expansion{} @code{%s}\n",
+          doc_nr,Tok2Cmdname(i),Tok2Cmdname(j));
+          doc_nr++;
+        }
+        if (j==ANY_TYPE) break;
+      }
+    }
+  }
+  if (produce_convert_table)
+  {
+    fprintf(doctable,"@end multitable\n");
+    fclose(doctable);
+  }
+  fprintf(outfile,"/*---------------------------------------------*/\n");
+  char ops[]="=><+*/[.^,%(;";
+  for(i=0;ops[i]!='\0';i++)
+    fprintf(outfile,"// token %d : %c\n", (int)ops[i], ops[i]);
+  for (i=257;i<=MAX_TOK;i++)
+  {
+    const char *s=iiTwoOps(i);
+    if (s[0]!='$')
+    {
+      fprintf(outfile,"// token %d : %s\n", i, s);
+    }
+  }
+/*-------------------------------------------------------------------*/
+  fprintf(outfile,"/*--max. token: %d, gr: %d --*/\n",MAX_TOK,UMINUS);
+/*-------------------------------------------------------------------*/
+  fprintf(outfile,"/*---------------------------------------------*/\n");
+  fprintf(outfile,
+  "struct sValCmdTab dArithTab1[]=\n"
+  "{\n");
+  for (j=1;j<=MAX_TOK+1;j++)
+  {
+    for(i=0;dArith1[i].cmd!=0;i++)
+    {
+      if (dArith1[i].cmd==j)
+      {
+        fprintf(outfile," { %d,%d },\n",j,i);
+        l1++;
+        break;
+      }
+    }
+  }
+  fprintf(outfile," { 10000,0 }\n};\n");
+  fprintf(outfile,"#define JJTAB1LEN %d\n",l1);
+/*-------------------------------------------------------------------*/
+  fprintf(outfile,
+  "struct sValCmdTab dArithTab2[]=\n"
+  "{\n");
+  for (j=1;j<=MAX_TOK+1;j++)
+  {
+    for(i=0;dArith2[i].cmd!=0;i++)
+    {
+      if (dArith2[i].cmd==j)
+      {
+        fprintf(outfile," { %d,%d },\n",j,i);
+        l2++;
+        break;
+      }
+    }
+  }
+  fprintf(outfile," { 10000,0 }\n};\n");
+  fprintf(outfile,"#define JJTAB2LEN %d\n",l2);
+  fclose(outfile);
+}
+/*---------------------------------------------------------------------*/
+/**
+ * @brief generate cmds initialisation
+**/
+/*---------------------------------------------------------------------*/
+
+void ttGen2b()
+{
+  int cmd_size = (sizeof(cmds)/sizeof(cmdnames))-1;
+
+  FILE *outfile = fopen(iparith_inc,"a");
+  fprintf(outfile,
+  "/****************************************\n"
+  "*  Computer Algebra System SINGULAR     *\n"
+  "****************************************/\n\n");
+/*-------------------------------------------------------------------*/
+  fprintf(outfile,"// identifier table for Singular\n//\n");
+
+  fprintf(
+    outfile,
+    "#ifdef MODULE_GENERATOR\n"
+    "#define omAlloc0(A) malloc(A)\n"
+    "#endif\n"
+    "void iiInitCmdName()\n{\n"
+    "  sArithBase.nCmdUsed      = 0;\n"
+    "  sArithBase.nCmdAllocated = %d;\n"
+    "  sArithBase.sCmds = (cmdnames*)omAlloc0(sArithBase.nCmdAllocated*sizeof(cmdnames));\n"
+    "\n"
+    "  // name-string                   alias  tokval toktype index\n",
+    cmd_size);
+  int m=0;
+  int id_nr=0;
+
+  qsort(&cmds, cmd_size, sizeof(cmdnames), (&_gentable_sort_cmds));
+
+  for(m=0; m<cmd_size; m++)
+  {
+    if(cmds[m].tokval>0) id_nr++;
+    fprintf(outfile,"  iiArithAddCmd(\"%s\", %*d, %3d, ",cmds[m].name,
+            (int)(20-strlen(cmds[m].name)),
+            cmds[m].alias,
+            cmds[m].tokval);
+    switch(cmds[m].toktype)
+    {
+        case CMD_1:            fprintf(outfile,"CMD_1"); break;
+        case CMD_2:            fprintf(outfile,"CMD_2"); break;
+        case CMD_3:            fprintf(outfile,"CMD_3"); break;
+        case CMD_12:           fprintf(outfile,"CMD_12"); break;
+        case CMD_123 :         fprintf(outfile,"CMD_123"); break;
+        case CMD_23:           fprintf(outfile,"CMD_23"); break;
+        case CMD_M:            fprintf(outfile,"CMD_M"); break;
+        case SYSVAR:           fprintf(outfile,"SYSVAR"); break;
+        case ROOT_DECL:        fprintf(outfile,"ROOT_DECL"); break;
+        case ROOT_DECL_LIST:   fprintf(outfile,"ROOT_DECL_LIST"); break;
+        case RING_DECL:        fprintf(outfile,"RING_DECL"); break;
+        case NONE:             fprintf(outfile,"NONE"); break;
+        default:
+          if((cmds[m].toktype>' ') &&(cmds[m].toktype<127))
+          {
+            fprintf(outfile,"'%c'",cmds[m].toktype);
+          }
+          else
+          {
+            fprintf(outfile,"%d",cmds[m].toktype);
+          }
+          break;
+#if 0
+          fprintf(outfile,"  iiArithAddCmd(\"%s\", %*d,  -1, 0 );\n",
+              cmds[m].name, 20-strlen(cmds[m].name),
+              0/*cmds[m].alias*/
+              /*-1 cmds[m].tokval*/
+              /*0 cmds[m].toktype*/);
+#endif
+    }
+    fprintf(outfile,", %d);\n", m);
+  }
+  fprintf(outfile, "/* end of list marker */\n");
+  fprintf(outfile,
+          "  sArithBase.nLastIdentifier = %d;\n",
+          id_nr);
+
+
+  fprintf(outfile,
+"}\n"
+"#define LAST_IDENTIFIER %d\n"
+  ,id_nr);
+  fclose(outfile);
+}
+int is_ref_cmd(cmdnames *c)
+{
+  if( c->tokval==0) return 0;
+  if (c->alias > 0) return 0;
+  if  ((c->toktype==CMD_1)
+        || (c->toktype==CMD_2)
+        || (c->toktype==CMD_3)
+        || (c->toktype==CMD_M)
+        || (c->toktype==CMD_12)
+        || (c->toktype==CMD_13)
+        || (c->toktype==CMD_23)
+        || (c->toktype==CMD_123)) return 1;
+  return 0;
+}
+void ttGen2c()
+{
+  int cmd_size = (sizeof(cmds)/sizeof(cmdnames))-1;
+
+  FILE *outfile = fopen("reference_table.texi","w");
+  fprintf(outfile, "@menu\n");
+/*-------------------------------------------------------------------*/
+  qsort(&cmds, cmd_size, sizeof(cmdnames), (&_texi_sort_cmds));
+
+  int m;
+  for(m=0; m<cmd_size; m++)
+  {
+    // assume that cmds[0].tokval== -1 and all others with tokval -1 at the end
+    if(is_ref_cmd(&(cmds[m])))
+    {
+      fprintf(outfile,"* %s::\n",cmds[m].name);
+    }
+  }
+  fprintf(outfile, "@end menu\n at c ---------------------------\n");
+  for(m=0; m<cmd_size; m++)
+  {
+    // assume that cmds[0].tokval== -1 and all others with tokval -1 at the end
+    if(is_ref_cmd(&(cmds[m])))
+    {
+      fprintf(outfile,"@node %s,",cmds[m].name);
+      // next:
+      int mm=m-1;
+      while((mm>0)&& (is_ref_cmd(&cmds[mm]))) mm--;
+      if((mm>0)&& (is_ref_cmd(&cmds[mm])))
+        fprintf(outfile,"%s,",cmds[mm].name);
+      else
+        fprintf(outfile,",");
+      // prev:
+      mm=m+1;
+      while((mm>0)&& (is_ref_cmd(&cmds[mm]))) mm++;
+      if((mm>0)&& (is_ref_cmd(&cmds[mm])))
+        fprintf(outfile,"%s,",cmds[m-1].name);
+      else
+        fprintf(outfile,",");
+      // up:, and header
+      fprintf(outfile,"Functions\n"
+      "@subsection %s\n"
+      "@cindex %s\n",cmds[m].name,cmds[m].name);
+      fprintf(outfile,"@include %s.part\n",cmds[m].name);
+      char partName[50];
+      sprintf(partName,"%s.part",cmds[m].name);
+      struct stat buf;
+      if (lstat(partName,&buf)!=0)
+      {
+        int op,i;
+        int only_field=0,only_comm=0,no_zerodiv=0;
+        FILE *part=fopen(partName,"w");
+        fprintf(part,"@table @code\n at item @strong{Syntax:}\n");
+        if ((cmds[m].toktype==CMD_1)
+        || (cmds[m].toktype==CMD_12)
+        || (cmds[m].toktype==CMD_13)
+        || (cmds[m].toktype==CMD_123))
+        {
+          op= cmds[m].tokval;
+          i=0;
+          while ((dArith1[i].cmd!=op) && (dArith1[i].cmd!=0)) i++;
+          while (dArith1[i].cmd==op)
+          {
+            if (dArith1[i].p!=jjWRONG)
+            {
+              fprintf(part,"@code{%s (} %s @code{)}\n",cmds[m].name,Tok2Cmdname(dArith1[i].arg));
+              fprintf(part,"@item @strong{Type:}\n%s\n",Tok2Cmdname(dArith1[i].res));
+              if ((dArith1[i].valid_for & ALLOW_PLURAL)==0)
+                only_comm=1;
+              if ((dArith1[i].valid_for & ALLOW_RING)==0)
+                only_field=1;
+              if ((dArith1[i].valid_for & ZERODIVISOR_MASK)==NO_ZERODIVISOR)
+                no_zerodiv=1;
+            }
+            i++;
+          }
+        }
+        if ((cmds[m].toktype==CMD_23)
+        || (cmds[m].toktype==CMD_12)
+        || (cmds[m].toktype==CMD_2)
+        || (cmds[m].toktype==CMD_123))
+        {
+          op= cmds[m].tokval;
+          i=0;
+          while ((dArith2[i].cmd!=op) && (dArith2[i].cmd!=0)) i++;
+          while (dArith2[i].cmd==op)
+          {
+            if (dArith2[i].p!=jjWRONG)
+            {
+              fprintf(part,"@code{%s (} %s, %s @code{)}\n",cmds[m].name,Tok2Cmdname(dArith2[i].arg1),Tok2Cmdname(dArith2[i].arg2));
+              fprintf(part,"@item @strong{Type:}\n%s\n",Tok2Cmdname(dArith2[i].res));
+              if ((dArith2[i].valid_for & ALLOW_PLURAL)==0)
+                 only_comm=1;
+              if ((dArith2[i].valid_for & ALLOW_RING)==0)
+                 only_field=1;
+              if ((dArith2[i].valid_for & ZERODIVISOR_MASK)==NO_ZERODIVISOR)
+                no_zerodiv=1;
+            }
+            i++;
+          }
+        }
+        if ((cmds[m].toktype==CMD_23)
+        || (cmds[m].toktype==CMD_13)
+        || (cmds[m].toktype==CMD_3)
+        || (cmds[m].toktype==CMD_123))
+        {
+          op= cmds[m].tokval;
+          i=0;
+          while ((dArith3[i].cmd!=op) && (dArith3[i].cmd!=0)) i++;
+          while (dArith3[i].cmd==op)
+          {
+            if (dArith3[i].p!=jjWRONG)
+            {
+              fprintf(part,"@code{%s (} %s, %s, %s @code{)}\n",cmds[m].name,
+                Tok2Cmdname(dArith3[i].arg1),
+                Tok2Cmdname(dArith3[i].arg2),
+                Tok2Cmdname(dArith3[i].arg3));
+              fprintf(part,"@item @strong{Type:}\n%s\n",Tok2Cmdname(dArith3[i].res));
+              if ((dArith3[i].valid_for & ALLOW_PLURAL)==0)
+                only_comm=1;
+              if ((dArith3[i].valid_for & ALLOW_RING)==0)
+                only_field=1;
+              if ((dArith3[i].valid_for & ZERODIVISOR_MASK)==NO_ZERODIVISOR)
+                no_zerodiv=1;
+            }
+            i++;
+          }
+        }
+        if (cmds[m].toktype==CMD_M)
+        {
+          op= cmds[m].tokval;
+          i=0;
+          while ((dArithM[i].cmd!=op) && (dArithM[i].cmd!=0)) i++;
+          while (dArithM[i].cmd==op)
+          {
+            if (dArithM[i].p!=jjWRONG)
+            {
+              fprintf(part,"@code{%s (} ... @code{)}\n",cmds[m].name);
+              fprintf(part,"@item @strong{Type:}\n%s\n",Tok2Cmdname(dArithM[i].res));
+              if ((dArithM[i].valid_for & ALLOW_PLURAL)==0)
+                only_comm=1;
+              if ((dArithM[i].valid_for & ALLOW_RING)==0)
+                only_field=1;
+              if ((dArithM[i].valid_for & ZERODIVISOR_MASK)==NO_ZERODIVISOR)
+                no_zerodiv=1;
+            }
+            i++;
+          }
+        }
+        if (only_comm)
+              fprintf(part,"@item @strong{Remark:}\n"
+                           "only for commutive polynomial rings\n");
+        if (only_field)
+              fprintf(part,"@item @strong{Remark:}\n"
+                           "only for polynomial rings over fields\n");
+        if (no_zerodiv)
+              fprintf(part,"@item @strong{Remark:}\n"
+                           "only for polynomial rings over domains\n");
+        fprintf(part,"@item @strong{Purpose:}\n"
+                     "@item @strong{Example:}\n"
+                     "@smallexample\n"
+                     "@c example\n"
+                     "@c example\n"
+                     "@end smallexample\n"
+                     "@c ref\n"
+                     "@c See\n"
+                     "@c ref{....};\n"
+                     "@c ref{....}.\n"
+                     "@c ref\n");
+        fclose(part);
+      }
+    }
+  }
+  fclose(outfile);
+}
+/*-------------------------------------------------------------------*/
+void ttGen4()
+{
+  FILE *outfile = fopen("plural_cmd.xx","w");
+  int i;
+  const char *old_s="";
+  fprintf(outfile,
+  "@c *****************************************\n"
+  "@c *  Computer Algebra System SINGULAR     *\n"
+  "@c *****************************************\n\n");
+/*-------------------------------------------------------------------*/
+  fprintf(outfile,"@multicolumn .45 .45\n");
+  int op;
+  i=0;
+  while ((op=dArith1[i].cmd)!=0)
+  {
+    if (dArith1[i].p!=jjWRONG)
+    {
+      const char *s = iiTwoOps(op);
+      if ((s!=NULL) && (isalpha(s[0])) && (strcmp(s,old_s)!=0))
+      {
+        old_s=s;
+        #ifdef HAVE_PLURAL
+        switch (dArith1[i].valid_for & PLURAL_MASK)
+        {
+          case NO_PLURAL:
+            fprintf(outfile,"@item @ref{%s} @tab @code{---}\n",s);
+            break;
+          case ALLOW_PLURAL:
+            fprintf(outfile,"@item @ref{%s} @tab @ref{%s (plural)}\n",s,s);
+            break;
+          case COMM_PLURAL:
+            fprintf(outfile,"@item @ref{%s} @tab %s\n",s,s);
+            break;
+        }
+        #endif
+        #ifdef HAVE_RINGS
+        #endif
+      }
+    }
+    i++;
+  }
+  fprintf(outfile,"@c ---------------------------------------------\n");
+  i=0;
+  while ((op=dArith2[i].cmd)!=0)
+  {
+    if (dArith2[i].p!=jjWRONG2)
+    {
+      const char *s = iiTwoOps(op);
+      if ((s!=NULL) && (isalpha(s[0])) && (strcmp(s,old_s)!=0))
+      {
+        old_s=s;
+        #ifdef HAVE_PLURAL
+        switch (dArith2[i].valid_for & PLURAL_MASK)
+        {
+          case NO_PLURAL:
+            fprintf(outfile,"@item @ref{%s} @tab @code{---}\n",s);
+            break;
+          case ALLOW_PLURAL:
+            fprintf(outfile,"@item @ref{%s} @tab @ref{%s (plural)}\n",s,s);
+            break;
+          case COMM_PLURAL:
+            fprintf(outfile,"@item @ref{%s} @tab %s\n",s,s);
+            break;
+        }
+        #endif
+        #ifdef HAVE_RINGS
+        #endif
+      }
+    }
+    i++;
+  }
+  fprintf(outfile,"@c ---------------------------------------------\n");
+  i=0;
+  while ((op=dArith3[i].cmd)!=0)
+  {
+    const char *s = iiTwoOps(op);
+    if (dArith3[i].p!=jjWRONG3)
+    {
+      if ((s!=NULL) && (isalpha(s[0])) && (strcmp(s,old_s)!=0))
+      {
+        old_s=s;
+        #ifdef HAVE_PLURAL
+        switch (dArith3[i].valid_for & PLURAL_MASK)
+        {
+          case NO_PLURAL:
+            fprintf(outfile,"@item @ref{%s} @tab @code{---}\n",s);
+            break;
+          case ALLOW_PLURAL:
+            fprintf(outfile,"@item @ref{%s} @tab @ref{%s (plural)}\n",s,s);
+            break;
+          case COMM_PLURAL:
+            fprintf(outfile,"@item @ref{%s} @tab %s\n",s,s);
+            break;
+        }
+        #endif
+        #ifdef HAVE_RINGS
+        #endif
+      }
+    }
+    i++;
+  }
+  fprintf(outfile,"@c ---------------------------------------------\n");
+  i=0;
+  while ((op=dArithM[i].cmd)!=0)
+  {
+    const char *s = iiTwoOps(op);
+    if ((s!=NULL) && (isalpha(s[0])) && (strcmp(s,old_s)!=0))
+    {
+        old_s=s;
+        #ifdef HAVE_PLURAL
+        switch (dArithM[i].valid_for & PLURAL_MASK)
+        {
+          case NO_PLURAL:
+            fprintf(outfile,"@item @ref{%s} @tab @code{---}\n",s);
+            break;
+          case ALLOW_PLURAL:
+            fprintf(outfile,"@item @ref{%s} @tab @ref{%s (plural)}\n",s,s);
+            break;
+          case COMM_PLURAL:
+            fprintf(outfile,"@item @ref{%s} @tab %s\n",s,s);
+            break;
+        }
+        #endif
+        #ifdef HAVE_RINGS
+        #endif
+    }
+    i++;
+  }
+  fprintf(outfile,"@c ---------------------------------------------\n");
+  fprintf(outfile,"@end table\n");
+  fclose(outfile);
+  rename("plural_cmd.xx","plural_cmd.inc");
+}
+/*-------------------------------------------------------------------*/
+
+int main(int argc, char** argv)
+{
+  if (argc>1)
+  {
+    produce_convert_table=1; /* for ttGen1 */
+    ttGen1();
+    unlink(iparith_inc);
+    ttGen4();
+    ttGen2c();
+  }
+  else
+  {
+    ttGen1();
+    ttGen2b();
+    rename(iparith_inc,"iparith.inc");
+  }
+  return 0;
+}
diff --git a/Singular/gms.cc b/Singular/gms.cc
new file mode 100644
index 0000000..85faf8e
--- /dev/null
+++ b/Singular/gms.cc
@@ -0,0 +1,141 @@
+/*****************************************
+*  Computer Algebra System SINGULAR      *
+*****************************************/
+/*
+* ABSTRACT: Gauss-Manin system normal form
+*/
+
+
+
+
+#include <kernel/mod2.h>
+
+#ifdef HAVE_GMS
+
+#include "gms.h"
+
+#include <coeffs/numbers.h>
+#include <kernel/polys.h>
+
+#include "ipid.h"
+
+lists gmsNF(ideal p,ideal g,matrix B,int D,int K)
+{
+  ideal r=idInit(IDELEMS(p),1);
+  ideal q=idInit(IDELEMS(p),1);
+
+  matrix B0=mpNew(MATROWS(B),MATCOLS(B));
+  for(int i=1;i<=MATROWS(B0);i++)
+     for(int j=1;j<=MATCOLS(B0);j++)
+      if(MATELEM(B,i,j)!=NULL)
+        MATELEM(B0,i,j)=pDiff(MATELEM(B,i,j),i+1);
+
+  for(int k=0;k<IDELEMS(p);k++)
+  {
+    while(p->m[k]!=NULL&&pGetExp(p->m[k],1)<=K)
+    {
+      int j=0;
+      while(j<IDELEMS(g)&&!pLmDivisibleBy(g->m[j],p->m[k]))
+        j++;
+
+      if(j<IDELEMS(g))
+      {
+        poly m=pDivideM(pHead(p->m[k]),pHead(g->m[j]));
+        p->m[k]=pSub(p->m[k],ppMult_mm(g->m[j],m));
+        pIncrExp(m,1);
+        pSetm(m);
+        for(int i=0;i<MATROWS(B);i++)
+        {
+          poly m0=pDiff(m,i+2);
+          if(MATELEM(B0,i+1,j+1)!=NULL)
+            p->m[k]=pAdd(p->m[k],ppMult_mm(MATELEM(B0,i+1,j+1),m));
+          if(MATELEM(B,i+1,j+1)!=NULL&&m0!=NULL)
+            p->m[k]=pAdd(p->m[k],ppMult_mm(MATELEM(B,i+1,j+1),m0));
+          pDelete(&m0);
+        }
+        pDelete(&m);
+      }
+      else
+      {
+        poly p0=p->m[k];
+        pIter(p->m[k]);
+        pNext(p0)=NULL;
+        r->m[k]=pAdd(r->m[k],p0);
+      }
+
+      while(p->m[k]!=NULL&&pGetExp(p->m[k],1)<=K&&pWTotaldegree(p->m[k])>D)
+      {
+        int i=pGetExp(p->m[k],1);
+        do
+        {
+          poly p0=p->m[k];
+          pIter(p->m[k]);
+          pNext(p0)=NULL;
+          q->m[k]=pAdd(q->m[k],p0);
+        }while(p->m[k]!=NULL&&pGetExp(p->m[k],1)==i);
+      }
+
+      pNormalize(p->m[k]);
+    }
+
+    q->m[k]=pAdd(q->m[k],p->m[k]);
+    p->m[k]=NULL;
+  }
+  idDelete(&p);
+  idDelete((ideal *)&B0);
+
+  id_Normalize(r, currRing);
+  id_Normalize(q, currRing);
+
+  lists l=(lists)omAllocBin(slists_bin);
+  l->Init(2);
+
+  l->m[0].rtyp=IDEAL_CMD;
+  l->m[0].data=r;
+  l->m[1].rtyp=IDEAL_CMD;
+  l->m[1].data=q;
+
+  return l;
+}
+
+
+BOOLEAN gmsNF(leftv res,leftv h)
+{
+  if(currRingHdl)
+  {
+    if(h&&h->Typ()==IDEAL_CMD)
+    {
+      ideal p=(ideal)h->CopyD();
+      h=h->next;
+      if(h&&h->Typ()==IDEAL_CMD)
+      {
+        ideal g=(ideal)h->Data();
+        h=h->next;
+        if(h&&h->Typ()==MATRIX_CMD)
+        {
+          matrix B=(matrix)h->Data();
+          h=h->next;
+          if(h&&h->Typ()==INT_CMD)
+          {
+            int D=(int)(long)h->Data();
+            h=h->next;
+            if(h&&h->Typ()==INT_CMD)
+            {
+              int K=(int)(long)h->Data();
+              res->rtyp=LIST_CMD;
+              res->data=(void *)gmsNF(p,g,B,D,K);
+              return FALSE;
+            }
+          }
+        }
+      }
+    }
+    WerrorS("<ideal>,<ideal>,<matrix>,<int>,<int> expected");
+    return TRUE;
+  }
+  WerrorS("no ring active");
+  return TRUE;
+}
+
+#endif /* HAVE_GMS */
+
diff --git a/Singular/gms.h b/Singular/gms.h
new file mode 100644
index 0000000..790982a
--- /dev/null
+++ b/Singular/gms.h
@@ -0,0 +1,22 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: Gauss-Manin system normal form
+*/
+
+#ifndef GMS_H
+#define GMS_H
+
+#include <misc/auxiliary.h>
+#include <polys/matpol.h>
+
+#include <kernel/structs.h>
+#include <kernel/ideals.h>
+
+#include <Singular/lists.h>
+
+lists gmsNF(ideal p, ideal g, matrix B, int D, int K);
+BOOLEAN gmsNF(leftv res, leftv h);
+
+#endif /* GMS_H */
diff --git a/Singular/grammar.cc b/Singular/grammar.cc
new file mode 100644
index 0000000..c96eb35
--- /dev/null
+++ b/Singular/grammar.cc
@@ -0,0 +1,4528 @@
+/* A Bison parser, made by GNU Bison 2.4.3.  */
+
+/* Skeleton implementation for Bison's Yacc-like parsers in C
+
+      Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
+   2009, 2010 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 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+/* As a special exception, you may create a larger work that contains
+   part or all of the Bison parser skeleton and distribute that work
+   under terms of your choice, so long as that work isn't itself a
+   parser generator using the skeleton or a modified version thereof
+   as a parser skeleton.  Alternatively, if you modify or redistribute
+   the parser skeleton itself, you may (at your option) remove this
+   special exception, which will cause the skeleton and the resulting
+   Bison output files to be licensed under the GNU General Public
+   License without this special exception.
+
+   This special exception was added by the Free Software Foundation in
+   version 2.2 of Bison.  */
+
+/* C LALR(1) parser skeleton written by Richard Stallman, by
+   simplifying the original so-called "semantic" parser.  */
+
+/* All symbols defined below should begin with yy or YY, to avoid
+   infringing on user name space.  This should be done even for local
+   variables, as they might otherwise be expanded by user macros.
+   There are some unavoidable exceptions within include files to
+   define necessary library symbols; they are noted "INFRINGES ON
+   USER NAME SPACE" below.  */
+
+/* Identify Bison output.  */
+#define YYBISON 1
+
+/* Bison version.  */
+#define YYBISON_VERSION "2.4.3"
+
+/* Skeleton name.  */
+#define YYSKELETON_NAME "yacc.c"
+
+/* Pure parsers.  */
+#define YYPURE 1
+
+/* Push parsers.  */
+#define YYPUSH 0
+
+/* Pull parsers.  */
+#define YYPULL 1
+
+/* Using locations.  */
+#define YYLSP_NEEDED 0
+
+
+
+/* Copy the first part of user declarations.  */
+
+/* Line 189 of yacc.c  */
+#line 7 "grammar.y"
+
+
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+
+#include <kernel/mod2.h>
+#include <misc/auxiliary.h>
+
+#include <misc/mylimits.h>
+#include <omalloc/omalloc.h>
+#include <Singular/tok.h>
+#include <misc/options.h>
+#include <Singular/stype.h>
+#include <Singular/fehelp.h>
+#include <Singular/ipid.h>
+#include <misc/intvec.h>
+#include <kernel/oswrapper/feread.h>
+#include <Singular/fevoices.h>
+#include <polys/matpol.h>
+#include <polys/monomials/ring.h>
+#include <kernel/GBEngine/kstd1.h>
+#include <Singular/subexpr.h>
+#include <Singular/ipshell.h>
+#include <Singular/ipconv.h>
+#include <Singular/sdb.h>
+#include <kernel/ideals.h>
+#include <coeffs/numbers.h>
+#include <kernel/polys.h>
+#include <kernel/combinatorics/stairc.h>
+#include <kernel/oswrapper/timer.h>
+#include <Singular/cntrlc.h>
+#include <polys/monomials/maps.h>
+#include <kernel/GBEngine/syz.h>
+#include <Singular/lists.h>
+#include <Singular/libparse.h>
+#include <coeffs/bigintmat.h>
+
+#if 0
+void debug_list(leftv v)
+{
+  idhdl r=basePackHdl;
+  idhdl h;
+  BOOLEAN found=FALSE;
+  const char *nn=v->name;
+  h=IDROOT->get(nn,myynest);
+  if (h!=NULL)
+  {
+     Print("Curr::%s, (%s)\n",nn,Tok2Cmdname((int)IDTYP(h)));
+     found=TRUE;
+  }
+  else         Print("`%s` not found in IDROOT\n",nn);
+  while (r!=NULL)
+  {
+    if ((IDTYP(r)==PACKAGE_CMD)
+    || (IDTYP(r)==RING_CMD)
+    || (IDTYP(r)==QRING_CMD))
+    {
+      h=IDPACKAGE(r)->idroot->get(nn,myynest);
+      if (h!=NULL)
+      {
+        Print("%s::%s, (%s)\n",r->id,nn,Tok2Cmdname((int)IDTYP(h)));
+        found=TRUE;
+      }
+      else         Print("%s::%s not found\n",r->id,nn);
+    }
+    if (r==basePackHdl) r=IDPACKAGE(r)->idroot;
+    r=r->next;
+   if (r==basePackHdl) break;
+  }
+  if (!found)
+  {
+    listall(TRUE);
+  }
+}
+#endif
+
+/* From the bison docu:
+
+     By defining the macro `YYMAXDEPTH', you can control how deep the
+parser stack can become before a stack overflow occurs.  Define the
+macro with a value that is an integer.  This value is the maximum number
+of tokens that can be shifted (and not reduced) before overflow.  It
+must be a constant expression whose value is known at compile time.
+
+   The stack space allowed is not necessarily allocated.  If you
+specify a large value for `YYMAXDEPTH', the parser actually allocates a
+small stack at first, and then makes it bigger by stages as needed.
+This increasing allocation happens automatically and silently.
+Therefore, you do not need to make `YYMAXDEPTH' painfully small merely
+to save space for ordinary inputs that do not need much stack.
+
+   The default value of `YYMAXDEPTH', if you do not define it, is 10000.
+*/
+#define YYMAXDEPTH MAX_INT_VAL
+
+extern int   yylineno;
+extern FILE* yyin;
+
+const  char *  currid;
+BOOLEAN    yyInRingConstruction=FALSE;
+BOOLEAN    expected_parms;
+int        cmdtok;
+int        inerror = 0;
+
+#define TESTSETINT(a,i)                                \
+   if ((a).Typ() != INT_CMD)                           \
+   {                                                   \
+     WerrorS("no int expression");                     \
+     YYERROR;                                          \
+   }                                                   \
+   (i) = (int)((long)(a).Data());(a).CleanUp()
+
+#define MYYERROR(a) { WerrorS(a); YYERROR; }
+
+void yyerror(const char * fmt)
+{
+
+  BOOLEAN old_errorreported=errorreported;
+  errorreported = TRUE;
+  if (currid!=NULL)
+  {
+    killid(currid,&IDROOT);
+    currid = NULL;
+  }
+  if(inerror==0)
+  {
+    {
+      if ((strlen(fmt)>1)
+      && (strncmp(fmt,"parse",5)!=0)
+      && (strncmp(fmt,"syntax",6)!=0))
+        WerrorS(fmt);
+      Werror( "error occurred in or before %s line %d: `%s`"
+             ,VoiceName(), yylineno, my_yylinebuf);
+    }
+    if (cmdtok!=0)
+    {
+      const char *s=Tok2Cmdname(cmdtok);
+      if (expected_parms)
+      {
+        Werror("expected %s-expression. type \'help %s;\'",s,s);
+      }
+      else
+      {
+        Werror("wrong type declaration. type \'help %s;\'",s);
+      }
+    }
+    if (!old_errorreported && (lastreserved!=NULL))
+    {
+      Werror("last reserved name was `%s`",lastreserved);
+    }
+    inerror=1;
+  }
+  if ((currentVoice!=NULL)
+  && (currentVoice->prev!=NULL)
+  && (myynest>0)
+#ifdef HAVE_SDB
+  && ((sdb_flags &1)==0)
+#endif
+  )
+  {
+    Werror("leaving %s",VoiceName());
+  }
+}
+
+
+
+/* Line 189 of yacc.c  */
+#line 243 "grammar.cc"
+
+/* Enabling traces.  */
+#ifndef YYDEBUG
+# define YYDEBUG 1
+#endif
+
+/* Enabling verbose error messages.  */
+#ifdef YYERROR_VERBOSE
+# undef YYERROR_VERBOSE
+# define YYERROR_VERBOSE 1
+#else
+# define YYERROR_VERBOSE 0
+#endif
+
+/* Enabling the token table.  */
+#ifndef YYTOKEN_TABLE
+# define YYTOKEN_TABLE 0
+#endif
+
+
+/* Tokens.  */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+   /* Put the tokens into the symbol table, so that GDB and other debuggers
+      know about them.  */
+   enum yytokentype {
+     DOTDOT = 258,
+     EQUAL_EQUAL = 259,
+     GE = 260,
+     LE = 261,
+     MINUSMINUS = 262,
+     NOT = 263,
+     NOTEQUAL = 264,
+     PLUSPLUS = 265,
+     COLONCOLON = 266,
+     ARROW = 267,
+     GRING_CMD = 268,
+     BIGINTMAT_CMD = 269,
+     INTMAT_CMD = 270,
+     PROC_CMD = 271,
+     RING_CMD = 272,
+     BEGIN_RING = 273,
+     IDEAL_CMD = 274,
+     MAP_CMD = 275,
+     MATRIX_CMD = 276,
+     MODUL_CMD = 277,
+     NUMBER_CMD = 278,
+     POLY_CMD = 279,
+     RESOLUTION_CMD = 280,
+     VECTOR_CMD = 281,
+     BETTI_CMD = 282,
+     COEFFS_CMD = 283,
+     COEF_CMD = 284,
+     CONTRACT_CMD = 285,
+     DEGREE_CMD = 286,
+     DEG_CMD = 287,
+     DIFF_CMD = 288,
+     DIM_CMD = 289,
+     DIVISION_CMD = 290,
+     ELIMINATION_CMD = 291,
+     E_CMD = 292,
+     FAREY_CMD = 293,
+     FETCH_CMD = 294,
+     FREEMODULE_CMD = 295,
+     KEEPRING_CMD = 296,
+     HILBERT_CMD = 297,
+     HOMOG_CMD = 298,
+     IMAP_CMD = 299,
+     INDEPSET_CMD = 300,
+     INTERRED_CMD = 301,
+     INTERSECT_CMD = 302,
+     JACOB_CMD = 303,
+     JET_CMD = 304,
+     KBASE_CMD = 305,
+     KOSZUL_CMD = 306,
+     LEADCOEF_CMD = 307,
+     LEADEXP_CMD = 308,
+     LEAD_CMD = 309,
+     LEADMONOM_CMD = 310,
+     LIFTSTD_CMD = 311,
+     LIFT_CMD = 312,
+     MAXID_CMD = 313,
+     MINBASE_CMD = 314,
+     MINOR_CMD = 315,
+     MINRES_CMD = 316,
+     MODULO_CMD = 317,
+     MONOM_CMD = 318,
+     MRES_CMD = 319,
+     MULTIPLICITY_CMD = 320,
+     ORD_CMD = 321,
+     PAR_CMD = 322,
+     PARDEG_CMD = 323,
+     PREIMAGE_CMD = 324,
+     QUOTIENT_CMD = 325,
+     QHWEIGHT_CMD = 326,
+     REDUCE_CMD = 327,
+     REGULARITY_CMD = 328,
+     RES_CMD = 329,
+     SBA_CMD = 330,
+     SIMPLIFY_CMD = 331,
+     SORTVEC_CMD = 332,
+     SRES_CMD = 333,
+     STD_CMD = 334,
+     SUBST_CMD = 335,
+     SYZYGY_CMD = 336,
+     VAR_CMD = 337,
+     VDIM_CMD = 338,
+     WEDGE_CMD = 339,
+     WEIGHT_CMD = 340,
+     VALTVARS = 341,
+     VMAXDEG = 342,
+     VMAXMULT = 343,
+     VNOETHER = 344,
+     VMINPOLY = 345,
+     END_RING = 346,
+     CMD_1 = 347,
+     CMD_2 = 348,
+     CMD_3 = 349,
+     CMD_12 = 350,
+     CMD_13 = 351,
+     CMD_23 = 352,
+     CMD_123 = 353,
+     CMD_M = 354,
+     ROOT_DECL = 355,
+     ROOT_DECL_LIST = 356,
+     RING_DECL = 357,
+     RING_DECL_LIST = 358,
+     EXAMPLE_CMD = 359,
+     EXPORT_CMD = 360,
+     HELP_CMD = 361,
+     KILL_CMD = 362,
+     LIB_CMD = 363,
+     LISTVAR_CMD = 364,
+     SETRING_CMD = 365,
+     TYPE_CMD = 366,
+     STRINGTOK = 367,
+     BLOCKTOK = 368,
+     INT_CONST = 369,
+     UNKNOWN_IDENT = 370,
+     RINGVAR = 371,
+     PROC_DEF = 372,
+     APPLY = 373,
+     ASSUME_CMD = 374,
+     BREAK_CMD = 375,
+     CONTINUE_CMD = 376,
+     ELSE_CMD = 377,
+     EVAL = 378,
+     QUOTE = 379,
+     FOR_CMD = 380,
+     IF_CMD = 381,
+     SYS_BREAK = 382,
+     WHILE_CMD = 383,
+     RETURN = 384,
+     PARAMETER = 385,
+     SYSVAR = 386,
+     UMINUS = 387
+   };
+#endif
+
+
+
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+#endif
+
+
+/* Copy the second part of user declarations.  */
+
+
+/* Line 264 of yacc.c  */
+#line 416 "grammar.cc"
+
+#ifdef short
+# undef short
+#endif
+
+#ifdef YYTYPE_UINT8
+typedef YYTYPE_UINT8 yytype_uint8;
+#else
+typedef unsigned char yytype_uint8;
+#endif
+
+#ifdef YYTYPE_INT8
+typedef YYTYPE_INT8 yytype_int8;
+#elif (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+typedef signed char yytype_int8;
+#else
+typedef short int yytype_int8;
+#endif
+
+#ifdef YYTYPE_UINT16
+typedef YYTYPE_UINT16 yytype_uint16;
+#else
+typedef unsigned short int yytype_uint16;
+#endif
+
+#ifdef YYTYPE_INT16
+typedef YYTYPE_INT16 yytype_int16;
+#else
+typedef short int yytype_int16;
+#endif
+
+#ifndef YYSIZE_T
+# ifdef __SIZE_TYPE__
+#  define YYSIZE_T __SIZE_TYPE__
+# elif defined size_t
+#  define YYSIZE_T size_t
+# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+#  include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+#  define YYSIZE_T size_t
+# else
+#  define YYSIZE_T unsigned int
+# endif
+#endif
+
+#define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
+
+#ifndef YY_
+# if defined YYENABLE_NLS && YYENABLE_NLS
+#  if ENABLE_NLS
+#   include <libintl.h> /* INFRINGES ON USER NAME SPACE */
+#   define YY_(msgid) dgettext ("bison-runtime", msgid)
+#  endif
+# endif
+# ifndef YY_
+#  define YY_(msgid) msgid
+# endif
+#endif
+
+/* Suppress unused-variable warnings by "using" E.  */
+#if ! defined lint || defined __GNUC__
+# define YYUSE(e) ((void) (e))
+#else
+# define YYUSE(e) /* empty */
+#endif
+
+/* Identity function, used to suppress warnings about constant conditions.  */
+#ifndef lint
+# define YYID(n) (n)
+#else
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static int
+YYID (int yyi)
+#else
+static int
+YYID (yyi)
+    int yyi;
+#endif
+{
+  return yyi;
+}
+#endif
+
+#if ! defined yyoverflow || YYERROR_VERBOSE
+
+/* The parser invokes alloca or malloc; define the necessary symbols.  */
+
+# ifdef YYSTACK_USE_ALLOCA
+#  if YYSTACK_USE_ALLOCA
+#   ifdef __GNUC__
+#    define YYSTACK_ALLOC __builtin_alloca
+#   elif defined __BUILTIN_VA_ARG_INCR
+#    include <alloca.h> /* INFRINGES ON USER NAME SPACE */
+#   elif defined _AIX
+#    define YYSTACK_ALLOC __alloca
+#   elif defined _MSC_VER
+#    include <malloc.h> /* INFRINGES ON USER NAME SPACE */
+#    define alloca _alloca
+#   else
+#    define YYSTACK_ALLOC alloca
+#    if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+#     include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+#     ifndef _STDLIB_H
+#      define _STDLIB_H 1
+#     endif
+#    endif
+#   endif
+#  endif
+# endif
+
+# ifdef YYSTACK_ALLOC
+   /* Pacify GCC's `empty if-body' warning.  */
+#  define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0))
+#  ifndef YYSTACK_ALLOC_MAXIMUM
+    /* The OS might guarantee only one guard page at the bottom of the stack,
+       and a page size can be as small as 4096 bytes.  So we cannot safely
+       invoke alloca (N) if N exceeds 4096.  Use a slightly smaller number
+       to allow for a few compiler-allocated temporary stack slots.  */
+#   define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
+#  endif
+# else
+#  define YYSTACK_ALLOC YYMALLOC
+#  define YYSTACK_FREE YYFREE
+#  ifndef YYSTACK_ALLOC_MAXIMUM
+#   define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
+#  endif
+#  if (defined __cplusplus && ! defined _STDLIB_H \
+       && ! ((defined YYMALLOC || defined malloc) \
+	     && (defined YYFREE || defined free)))
+#   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+#   ifndef _STDLIB_H
+#    define _STDLIB_H 1
+#   endif
+#  endif
+#  ifndef YYMALLOC
+#   define YYMALLOC malloc
+#   if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
+#   endif
+#  endif
+#  ifndef YYFREE
+#   define YYFREE free
+#   if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+void free (void *); /* INFRINGES ON USER NAME SPACE */
+#   endif
+#  endif
+# endif
+#endif /* ! defined yyoverflow || YYERROR_VERBOSE */
+
+
+#if (! defined yyoverflow \
+     && (! defined __cplusplus \
+	 || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
+
+/* A type that is properly aligned for any stack member.  */
+union yyalloc
+{
+  yytype_int16 yyss_alloc;
+  YYSTYPE yyvs_alloc;
+};
+
+/* The size of the maximum gap between one aligned stack and the next.  */
+# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
+
+/* The size of an array large to enough to hold all stacks, each with
+   N elements.  */
+# define YYSTACK_BYTES(N) \
+     ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \
+      + YYSTACK_GAP_MAXIMUM)
+
+/* Copy COUNT objects from FROM to TO.  The source and destination do
+   not overlap.  */
+# ifndef YYCOPY
+#  if defined __GNUC__ && 1 < __GNUC__
+#   define YYCOPY(To, From, Count) \
+      __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
+#  else
+#   define YYCOPY(To, From, Count)		\
+      do					\
+	{					\
+	  YYSIZE_T yyi;				\
+	  for (yyi = 0; yyi < (Count); yyi++)	\
+	    (To)[yyi] = (From)[yyi];		\
+	}					\
+      while (YYID (0))
+#  endif
+# endif
+
+/* Relocate STACK from its old location to the new one.  The
+   local variables YYSIZE and YYSTACKSIZE give the old and new number of
+   elements in the stack, and YYPTR gives the new location of the
+   stack.  Advance YYPTR to a properly aligned location for the next
+   stack.  */
+# define YYSTACK_RELOCATE(Stack_alloc, Stack)				\
+    do									\
+      {									\
+	YYSIZE_T yynewbytes;						\
+	YYCOPY (&yyptr->Stack_alloc, Stack, yysize);			\
+	Stack = &yyptr->Stack_alloc;					\
+	yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
+	yyptr += yynewbytes / sizeof (*yyptr);				\
+      }									\
+    while (YYID (0))
+
+#endif
+
+/* YYFINAL -- State number of the termination state.  */
+#define YYFINAL  2
+/* YYLAST -- Last index in YYTABLE.  */
+#define YYLAST   2531
+
+/* YYNTOKENS -- Number of terminals.  */
+#define YYNTOKENS  150
+/* YYNNTS -- Number of nonterminals.  */
+#define YYNNTS  45
+/* YYNRULES -- Number of rules.  */
+#define YYNRULES  174
+/* YYNRULES -- Number of states.  */
+#define YYNSTATES  396
+
+/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
+#define YYUNDEFTOK  2
+#define YYMAXUTOK   387
+
+#define YYTRANSLATE(YYX)						\
+  ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
+
+/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX.  */
+static const yytype_uint8 yytranslate[] =
+{
+       0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,   143,     2,
+     146,   147,     2,   135,   141,   136,   148,   137,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,   144,   142,
+     133,   132,   134,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,   138,     2,   139,   140,     2,   149,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     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,   145
+};
+
+#if YYDEBUG
+/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
+   YYRHS.  */
+static const yytype_uint16 yyprhs[] =
+{
+       0,     0,     3,     4,     7,     9,    12,    15,    17,    19,
+      21,    24,    26,    28,    30,    32,    34,    36,    38,    40,
+      43,    45,    47,    49,    51,    53,    55,    57,    59,    61,
+      64,    66,    68,    72,    76,    80,    85,    89,    91,    93,
+      95,   100,   105,   110,   114,   119,   124,   128,   133,   138,
+     143,   148,   155,   162,   169,   176,   185,   194,   203,   212,
+     216,   221,   230,   235,   244,   249,   253,   257,   259,   261,
+     263,   267,   274,   279,   286,   293,   300,   307,   314,   321,
+     325,   331,   337,   338,   344,   347,   350,   352,   355,   358,
+     362,   366,   370,   374,   378,   382,   386,   390,   394,   398,
+     401,   404,   407,   410,   412,   416,   419,   422,   425,   428,
+     437,   440,   444,   447,   449,   451,   457,   459,   461,   466,
+     468,   472,   474,   478,   480,   482,   484,   486,   487,   492,
+     496,   499,   503,   506,   509,   513,   518,   523,   528,   533,
+     538,   543,   548,   553,   560,   567,   574,   581,   588,   595,
+     602,   606,   608,   617,   620,   625,   628,   630,   632,   635,
+     638,   640,   646,   649,   655,   657,   659,   663,   669,   673,
+     677,   682,   685,   688,   693
+};
+
+/* YYRHS -- A `-1'-separated list of the rules' RHS.  */
+static const yytype_int16 yyrhs[] =
+{
+     151,     0,    -1,    -1,   151,   152,    -1,   153,    -1,   155,
+     142,    -1,   167,   142,    -1,   194,    -1,   127,    -1,   142,
+      -1,     1,   142,    -1,   189,    -1,   190,    -1,   154,    -1,
+     191,    -1,   192,    -1,   176,    -1,   178,    -1,   179,    -1,
+     104,   113,    -1,   156,    -1,   180,    -1,   181,    -1,   182,
+      -1,   193,    -1,   184,    -1,   185,    -1,   187,    -1,   188,
+      -1,   165,   158,    -1,   116,    -1,   166,    -1,   157,    11,
+     157,    -1,   159,   148,   157,    -1,   157,   146,   147,    -1,
+     157,   146,   158,   147,    -1,   138,   158,   139,    -1,   114,
+      -1,   131,    -1,   168,    -1,    16,   146,   159,   147,    -1,
+     100,   146,   159,   147,    -1,   101,   146,   158,   147,    -1,
+     101,   146,   147,    -1,   102,   146,   159,   147,    -1,   103,
+     146,   158,   147,    -1,   103,   146,   147,    -1,    92,   146,
+     159,   147,    -1,    95,   146,   159,   147,    -1,    96,   146,
+     159,   147,    -1,    98,   146,   159,   147,    -1,    93,   146,
+     159,   141,   159,   147,    -1,    95,   146,   159,   141,   159,
+     147,    -1,    97,   146,   159,   141,   159,   147,    -1,    98,
+     146,   159,   141,   159,   147,    -1,    94,   146,   159,   141,
+     159,   141,   159,   147,    -1,    96,   146,   159,   141,   159,
+     141,   159,   147,    -1,    97,   146,   159,   141,   159,   141,
+     159,   147,    -1,    98,   146,   159,   141,   159,   141,   159,
+     147,    -1,    99,   146,   147,    -1,    99,   146,   158,   147,
+      -1,   175,   146,   159,   141,   159,   141,   159,   147,    -1,
+     175,   146,   159,   147,    -1,    17,   146,   169,   141,   169,
+     141,   173,   147,    -1,    17,   146,   159,   147,    -1,   166,
+      12,   113,    -1,   158,   141,   159,    -1,   159,    -1,   164,
+      -1,   157,    -1,   146,   158,   147,    -1,   159,   138,   159,
+     141,   159,   139,    -1,   159,   138,   159,   139,    -1,   118,
+     146,   159,   141,    92,   147,    -1,   118,   146,   159,   141,
+      95,   147,    -1,   118,   146,   159,   141,    96,   147,    -1,
+     118,   146,   159,   141,    98,   147,    -1,   118,   146,   159,
+     141,    99,   147,    -1,   118,   146,   159,   141,   159,   147,
+      -1,   161,   159,   163,    -1,   161,   159,   132,   159,   163,
+      -1,   162,   159,   141,   159,   163,    -1,    -1,   123,   146,
+     160,   159,   147,    -1,   124,   146,    -1,   119,   146,    -1,
+     147,    -1,   159,    10,    -1,   159,     7,    -1,   159,   135,
+     159,    -1,   159,   136,   159,    -1,   159,   137,   159,    -1,
+     159,   140,   159,    -1,   159,   133,   159,    -1,   159,   143,
+     159,    -1,   159,     9,   159,    -1,   159,     4,   159,    -1,
+     159,     3,   159,    -1,   159,   144,   159,    -1,     8,   159,
+      -1,   136,   159,    -1,   167,   174,    -1,   158,   132,    -1,
+     115,    -1,   149,   159,   149,    -1,   100,   157,    -1,   101,
+     157,    -1,   102,   157,    -1,   103,   157,    -1,   175,   157,
+     138,   159,   139,   138,   159,   139,    -1,   175,   157,    -1,
+     167,   141,   157,    -1,    16,   157,    -1,   112,    -1,   159,
+      -1,   146,   159,   141,   158,   147,    -1,   115,    -1,   170,
+      -1,   170,   146,   158,   147,    -1,   171,    -1,   171,   141,
+     172,    -1,   171,    -1,   146,   172,   147,    -1,   132,    -1,
+      21,    -1,    15,    -1,    14,    -1,    -1,   133,   168,   177,
+     142,    -1,   106,   112,   142,    -1,   106,   142,    -1,   104,
+     112,   142,    -1,   105,   158,    -1,   107,   157,    -1,   181,
+     141,   157,    -1,   109,   146,   100,   147,    -1,   109,   146,
+     101,   147,    -1,   109,   146,   102,   147,    -1,   109,   146,
+     103,   147,    -1,   109,   146,    17,   147,    -1,   109,   146,
+     175,   147,    -1,   109,   146,    16,   147,    -1,   109,   146,
+     157,   147,    -1,   109,   146,   157,   141,   100,   147,    -1,
+     109,   146,   157,   141,   101,   147,    -1,   109,   146,   157,
+     141,   102,   147,    -1,   109,   146,   157,   141,   103,   147,
+      -1,   109,   146,   157,   141,    17,   147,    -1,   109,   146,
+     157,   141,   175,   147,    -1,   109,   146,   157,   141,    16,
+     147,    -1,   109,   146,   147,    -1,    17,    -1,   183,   157,
+     174,   169,   141,   169,   141,   173,    -1,   183,   157,    -1,
+     183,   157,   174,   157,    -1,   131,   168,    -1,   110,    -1,
+      41,    -1,   186,   159,    -1,   111,   159,    -1,   158,    -1,
+     126,   146,   159,   147,   113,    -1,   122,   113,    -1,   126,
+     146,   159,   147,   120,    -1,   120,    -1,   121,    -1,   128,
+     112,   113,    -1,   125,   112,   112,   112,   113,    -1,    16,
+     166,   113,    -1,   117,   112,   113,    -1,   117,   112,   112,
+     113,    -1,   130,   167,    -1,   130,   159,    -1,   129,   146,
+     158,   147,    -1,   129,   146,   147,    -1
+};
+
+/* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
+static const yytype_uint16 yyrline[] =
+{
+       0,   364,   364,   366,   400,   401,   403,   405,   409,   414,
+     416,   467,   468,   469,   470,   471,   472,   473,   474,   478,
+     481,   482,   483,   484,   485,   486,   487,   488,   489,   492,
+     499,   504,   508,   512,   516,   520,   533,   561,   585,   591,
+     597,   601,   605,   609,   613,   617,   621,   625,   629,   633,
+     637,   641,   645,   649,   653,   657,   661,   665,   669,   673,
+     677,   683,   687,   691,   695,   699,   706,   717,   723,   728,
+     729,   730,   734,   738,   742,   746,   750,   754,   758,   762,
+     766,   783,   790,   789,   807,   815,   823,   832,   836,   840,
+     844,   848,   852,   856,   860,   864,   868,   872,   876,   880,
+     892,   899,   900,   919,   920,   932,   937,   942,   946,   950,
+     990,  1016,  1037,  1045,  1049,  1050,  1064,  1072,  1081,  1126,
+    1127,  1136,  1137,  1143,  1150,  1152,  1154,  1164,  1163,  1171,
+    1176,  1183,  1191,  1203,  1219,  1238,  1242,  1246,  1251,  1255,
+    1259,  1263,  1267,  1272,  1278,  1284,  1290,  1296,  1302,  1308,
+    1320,  1327,  1331,  1368,  1375,  1383,  1389,  1389,  1392,  1464,
+    1468,  1497,  1510,  1527,  1536,  1541,  1549,  1561,  1580,  1590,
+    1609,  1632,  1638,  1650,  1656
+};
+#endif
+
+#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
+/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+   First, the terminals, then, starting at YYNTOKENS, nonterminals.  */
+static const char *const yytname[] =
+{
+  "$end", "error", "$undefined", "DOTDOT", "EQUAL_EQUAL", "GE", "LE",
+  "MINUSMINUS", "NOT", "NOTEQUAL", "PLUSPLUS", "COLONCOLON", "ARROW",
+  "GRING_CMD", "BIGINTMAT_CMD", "INTMAT_CMD", "PROC_CMD", "RING_CMD",
+  "BEGIN_RING", "IDEAL_CMD", "MAP_CMD", "MATRIX_CMD", "MODUL_CMD",
+  "NUMBER_CMD", "POLY_CMD", "RESOLUTION_CMD", "VECTOR_CMD", "BETTI_CMD",
+  "COEFFS_CMD", "COEF_CMD", "CONTRACT_CMD", "DEGREE_CMD", "DEG_CMD",
+  "DIFF_CMD", "DIM_CMD", "DIVISION_CMD", "ELIMINATION_CMD", "E_CMD",
+  "FAREY_CMD", "FETCH_CMD", "FREEMODULE_CMD", "KEEPRING_CMD",
+  "HILBERT_CMD", "HOMOG_CMD", "IMAP_CMD", "INDEPSET_CMD", "INTERRED_CMD",
+  "INTERSECT_CMD", "JACOB_CMD", "JET_CMD", "KBASE_CMD", "KOSZUL_CMD",
+  "LEADCOEF_CMD", "LEADEXP_CMD", "LEAD_CMD", "LEADMONOM_CMD",
+  "LIFTSTD_CMD", "LIFT_CMD", "MAXID_CMD", "MINBASE_CMD", "MINOR_CMD",
+  "MINRES_CMD", "MODULO_CMD", "MONOM_CMD", "MRES_CMD", "MULTIPLICITY_CMD",
+  "ORD_CMD", "PAR_CMD", "PARDEG_CMD", "PREIMAGE_CMD", "QUOTIENT_CMD",
+  "QHWEIGHT_CMD", "REDUCE_CMD", "REGULARITY_CMD", "RES_CMD", "SBA_CMD",
+  "SIMPLIFY_CMD", "SORTVEC_CMD", "SRES_CMD", "STD_CMD", "SUBST_CMD",
+  "SYZYGY_CMD", "VAR_CMD", "VDIM_CMD", "WEDGE_CMD", "WEIGHT_CMD",
+  "VALTVARS", "VMAXDEG", "VMAXMULT", "VNOETHER", "VMINPOLY", "END_RING",
+  "CMD_1", "CMD_2", "CMD_3", "CMD_12", "CMD_13", "CMD_23", "CMD_123",
+  "CMD_M", "ROOT_DECL", "ROOT_DECL_LIST", "RING_DECL", "RING_DECL_LIST",
+  "EXAMPLE_CMD", "EXPORT_CMD", "HELP_CMD", "KILL_CMD", "LIB_CMD",
+  "LISTVAR_CMD", "SETRING_CMD", "TYPE_CMD", "STRINGTOK", "BLOCKTOK",
+  "INT_CONST", "UNKNOWN_IDENT", "RINGVAR", "PROC_DEF", "APPLY",
+  "ASSUME_CMD", "BREAK_CMD", "CONTINUE_CMD", "ELSE_CMD", "EVAL", "QUOTE",
+  "FOR_CMD", "IF_CMD", "SYS_BREAK", "WHILE_CMD", "RETURN", "PARAMETER",
+  "SYSVAR", "'='", "'<'", "'>'", "'+'", "'-'", "'/'", "'['", "']'", "'^'",
+  "','", "';'", "'&'", "':'", "UMINUS", "'('", "')'", "'.'", "'`'",
+  "$accept", "lines", "pprompt", "flowctrl", "example_dummy", "command",
+  "assign", "elemexpr", "exprlist", "expr", "$@1", "quote_start",
+  "assume_start", "quote_end", "expr_arithmetic", "left_value",
+  "extendedid", "declare_ip_variable", "stringexpr", "rlist", "ordername",
+  "orderelem", "OrderingList", "ordering", "cmdeq", "mat_cmd", "filecmd",
+  "$@2", "helpcmd", "examplecmd", "exportcmd", "killcmd", "listcmd",
+  "ringcmd1", "ringcmd", "scriptcmd", "setrings", "setringcmd", "typecmd",
+  "ifcmd", "whilecmd", "forcmd", "proccmd", "parametercmd", "returncmd", 0
+};
+#endif
+
+# ifdef YYPRINT
+/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
+   token YYLEX-NUM.  */
+static const yytype_uint16 yytoknum[] =
+{
+       0,   256,   257,   258,   259,   260,   261,   262,   263,   264,
+     265,   266,   267,   268,   269,   270,   271,   272,   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,   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,    61,    60,    62,    43,    45,    47,    91,    93,
+      94,    44,    59,    38,    58,   387,    40,    41,    46,    96
+};
+# endif
+
+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
+static const yytype_uint8 yyr1[] =
+{
+       0,   150,   151,   151,   152,   152,   152,   152,   152,   152,
+     152,   153,   153,   153,   153,   153,   153,   153,   153,   154,
+     155,   155,   155,   155,   155,   155,   155,   155,   155,   156,
+     157,   157,   157,   157,   157,   157,   157,   157,   157,   157,
+     157,   157,   157,   157,   157,   157,   157,   157,   157,   157,
+     157,   157,   157,   157,   157,   157,   157,   157,   157,   157,
+     157,   157,   157,   157,   157,   157,   158,   158,   159,   159,
+     159,   159,   159,   159,   159,   159,   159,   159,   159,   159,
+     159,   159,   160,   159,   161,   162,   163,   164,   164,   164,
+     164,   164,   164,   164,   164,   164,   164,   164,   164,   164,
+     164,   165,   165,   166,   166,   167,   167,   167,   167,   167,
+     167,   167,   167,   168,   169,   169,   170,   171,   171,   172,
+     172,   173,   173,   174,   175,   175,   175,   177,   176,   178,
+     178,   179,   180,   181,   181,   182,   182,   182,   182,   182,
+     182,   182,   182,   182,   182,   182,   182,   182,   182,   182,
+     182,   183,   184,   184,   184,   185,   186,   186,   187,   188,
+     188,   189,   189,   189,   189,   189,   190,   191,   192,   192,
+     192,   193,   193,   194,   194
+};
+
+/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
+static const yytype_uint8 yyr2[] =
+{
+       0,     2,     0,     2,     1,     2,     2,     1,     1,     1,
+       2,     1,     1,     1,     1,     1,     1,     1,     1,     2,
+       1,     1,     1,     1,     1,     1,     1,     1,     1,     2,
+       1,     1,     3,     3,     3,     4,     3,     1,     1,     1,
+       4,     4,     4,     3,     4,     4,     3,     4,     4,     4,
+       4,     6,     6,     6,     6,     8,     8,     8,     8,     3,
+       4,     8,     4,     8,     4,     3,     3,     1,     1,     1,
+       3,     6,     4,     6,     6,     6,     6,     6,     6,     3,
+       5,     5,     0,     5,     2,     2,     1,     2,     2,     3,
+       3,     3,     3,     3,     3,     3,     3,     3,     3,     2,
+       2,     2,     2,     1,     3,     2,     2,     2,     2,     8,
+       2,     3,     2,     1,     1,     5,     1,     1,     4,     1,
+       3,     1,     3,     1,     1,     1,     1,     0,     4,     3,
+       2,     3,     2,     2,     3,     4,     4,     4,     4,     4,
+       4,     4,     4,     6,     6,     6,     6,     6,     6,     6,
+       3,     1,     8,     2,     4,     2,     1,     1,     2,     2,
+       1,     5,     2,     5,     1,     1,     3,     5,     3,     3,
+       4,     2,     2,     4,     3
+};
+
+/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
+   STATE-NUM when YYTABLE doesn't specify something else to do.  Zero
+   means the default is an error.  */
+static const yytype_uint8 yydefact[] =
+{
+       2,     0,     1,     0,     0,   126,   125,     0,   151,   124,
+     157,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,   156,     0,
+     113,    37,   103,    30,     0,     0,     0,   164,   165,     0,
+       0,     0,     0,     0,     8,     0,     0,     0,    38,     0,
+       0,     0,     9,     0,     0,     3,     4,    13,     0,    20,
+      69,   160,    67,     0,     0,    68,     0,    31,     0,    39,
+       0,    16,    17,    18,    21,    22,    23,     0,    25,    26,
+       0,    27,    28,    11,    12,    14,    15,    24,     7,    10,
+       0,     0,     0,     0,     0,     0,    38,    99,     0,     0,
+      69,     0,    31,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,    69,     0,    69,     0,    69,     0,    69,
+       0,    19,   132,     0,   130,    69,     0,   159,     0,     0,
+      85,   162,    82,    84,     0,     0,     0,     0,     0,   172,
+     171,   155,   127,   100,     0,     0,     0,     5,     0,     0,
+     102,     0,     0,     0,    88,     0,    87,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,    29,     0,
+     123,     0,     6,   101,     0,    69,     0,    69,   158,     0,
+       0,     0,     0,     0,     0,    67,   168,     0,   114,     0,
+       0,     0,     0,     0,     0,     0,     0,    59,     0,    67,
+      43,     0,    67,    46,     0,   131,   129,     0,     0,     0,
+       0,     0,     0,   150,    69,     0,     0,   169,     0,     0,
+       0,     0,   166,   174,     0,     0,    36,    70,   104,    32,
+      34,     0,    66,    97,    96,    95,    93,    89,    90,    91,
+       0,    92,    94,    98,    33,     0,    86,    79,     0,    65,
+      69,     0,     0,    69,     0,     0,     0,     0,     0,     0,
+       0,    40,    67,    64,     0,    47,     0,     0,     0,    48,
+       0,    49,     0,     0,    50,    60,    41,    42,    44,    45,
+     141,   139,   135,   136,   137,   138,     0,   142,   140,   170,
+       0,     0,     0,     0,   173,   128,    35,    72,     0,     0,
+       0,     0,    62,     0,    69,   114,     0,    42,    45,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+      83,   167,   161,   163,     0,    80,    81,     0,     0,     0,
+       0,     0,    51,     0,    52,     0,     0,    53,     0,    54,
+     149,   147,   143,   144,   145,   146,   148,    73,    74,    75,
+      76,    77,    78,    71,     0,     0,     0,   115,   116,     0,
+     117,   121,     0,     0,     0,     0,     0,     0,     0,     0,
+     119,     0,     0,    63,    55,    56,    57,    58,    61,   109,
+     152,     0,   122,     0,   120,   118
+};
+
+/* YYDEFGOTO[NTERM-NUM].  */
+static const yytype_int16 yydefgoto[] =
+{
+      -1,     1,    55,    56,    57,    58,    59,    60,   145,    62,
+     219,    63,    64,   247,    65,    66,    67,    68,    69,   189,
+     370,   371,   381,   372,   173,    98,    71,   225,    72,    73,
+      74,    75,    76,    77,    78,    79,    80,    81,    82,    83,
+      84,    85,    86,    87,    88
+};
+
+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+   STATE-NUM.  */
+#define YYPACT_NINF -363
+static const yytype_int16 yypact[] =
+{
+    -363,   326,  -363,  -129,  1852,  -363,  -363,  1910,   -95,  -363,
+    -363,   -75,   -67,   -58,   -42,   -37,   -30,   -25,   -13,  1970,
+    2028,  2088,  2146,   -87,  1852,  -104,  1852,    -5,  -363,  1852,
+    -363,  -363,  -363,  -363,   -71,    20,    29,  -363,  -363,    58,
+      39,    77,   -68,    83,  -363,   130,    98,  2206,   137,   137,
+    1852,  1852,  -363,  1852,  1852,  -363,  -363,  -363,   112,  -363,
+      35,  -111,  1335,  1852,  1852,  -363,  1852,   247,  -122,  -363,
+    2264,  -363,  -363,  -363,  -363,   131,  -363,  1852,  -363,  -363,
+    1852,  -363,  -363,  -363,  -363,  -363,  -363,  -363,  -363,  -363,
+     127,   -95,   129,   132,   133,   134,  -363,    30,   135,  1852,
+     359,  1335,    -8,  2324,  1852,  1852,  1852,  1852,  1852,  1852,
+    1852,  1498,  1852,   375,  1556,   405,  1852,   447,  1616,   469,
+     140,  -363,   142,   143,  -363,    92,  1674,  1335,   -53,  1852,
+    -363,  -363,  -363,  -363,   172,  1852,   174,  1734,  1910,  1335,
+     147,  -363,  -363,    30,   -52,  -105,   120,  -363,  1852,  1792,
+    -363,  1852,  1852,  1852,  -363,  1852,  -363,  1852,  1852,  1852,
+    1852,  1852,  1852,  1852,  1852,  1852,   236,   531,   142,   176,
+    -363,  1852,  -363,  -363,  1852,   220,  1852,    72,  1335,  1852,
+    1852,  1556,  1852,  1616,  1852,   545,  -363,  1852,   561,   149,
+     577,   593,   735,     2,   267,   749,   341,  -363,  -102,   763,
+    -363,   -98,   779,  -363,   -93,  -363,  -363,   -55,   -50,   -46,
+     -39,   -32,   -27,  -363,    74,   -15,   178,  -363,   795,  1852,
+     180,   809,  -363,  -363,   -85,   152,  -363,  -363,  -363,  -363,
+    -363,   -69,  1335,  1349,  1389,  1389,   169,    25,    25,    30,
+      54,    21,  1363,    25,  -363,  1852,  -363,  -363,  1852,  -363,
+     622,   483,  1852,    95,  2324,   545,   763,   -66,   779,   -65,
+     483,  -363,   825,  -363,  2324,  -363,  1852,  1852,  1852,  -363,
+    1852,  -363,  1852,  1852,  -363,  -363,  -363,  -363,  -363,  -363,
+    -363,  -363,  -363,  -363,  -363,  -363,  1012,  -363,  -363,  -363,
+    2382,   839,   182,   -86,  -363,  -363,  -363,  -363,  1852,   855,
+     855,  1852,  -363,   997,    42,  1335,   156,  -363,  -363,  1852,
+     157,  1011,  1027,  1041,  1057,   499,   515,   154,   163,   164,
+     175,   177,   181,   183,    70,    79,   101,   105,   115,  1071,
+    -363,  -363,  -363,  -363,  1087,  -363,  -363,  1101,   161,  2324,
+     -61,  -113,  -363,  1852,  -363,  1852,  1852,  -363,  1852,  -363,
+    -363,  -363,  -363,  -363,  -363,  -363,  -363,  -363,  -363,  -363,
+    -363,  -363,  -363,  -363,  1852,  1852,   162,  -363,  -363,   204,
+     179,  -363,   184,  1115,  1257,  1273,  1289,  1305,  1321,  -113,
+     188,   185,  1852,  -363,  -363,  -363,  -363,  -363,  -363,  -363,
+    -363,   204,  -363,   -57,  -363,  -363
+};
+
+/* YYPGOTO[NTERM-NUM].  */
+static const yytype_int16 yypgoto[] =
+{
+    -363,  -363,  -363,  -363,  -363,  -363,  -363,    -4,    -1,    48,
+    -363,  -363,  -363,  -206,  -363,  -363,   316,   286,   217,  -240,
+    -363,  -362,   -56,   -43,   160,     0,  -363,  -363,  -363,  -363,
+    -363,  -363,  -363,  -363,  -363,  -363,  -363,  -363,  -363,  -363,
+    -363,  -363,  -363,  -363,  -363
+};
+
+/* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
+   positive, shift that token.  If negative, reduce the rule which
+   number is the opposite.  If zero, do what YYDEFACT says.
+   If YYTABLE_NINF, syntax error.  */
+#define YYTABLE_NINF -155
+static const yytype_int16 yytable[] =
+{
+      61,    70,   368,   100,   169,   152,   153,   380,   123,   154,
+     170,   155,   156,    89,   306,   113,   115,   117,   119,   171,
+     172,   150,   125,   122,   310,   120,   121,   332,   154,   380,
+     151,   156,   154,   369,   333,   156,   151,   154,   124,   151,
+     156,   128,   227,   151,   134,   275,   148,    70,   151,   277,
+     144,   103,    97,   148,   279,   101,   151,   152,   153,   216,
+     217,   154,   294,   155,   156,   168,   175,   101,   101,   101,
+     101,   104,   151,   177,   101,   151,   151,   127,   296,   105,
+     151,   307,   308,   148,   151,   148,   367,   226,   106,   151,
+     395,   179,   280,   335,   336,   139,   103,   281,   143,   366,
+     180,   282,   146,   148,   107,   186,   148,   181,   283,   108,
+     198,   166,   167,   201,   182,   284,   109,   204,   101,   183,
+     285,   110,   214,   152,   153,   101,   215,   154,   178,   155,
+     156,   184,   288,   111,   100,   157,   224,   158,   159,   160,
+     161,   126,   162,   268,   229,   163,   164,   185,   231,   269,
+     165,   188,   190,   191,   192,   193,   194,   195,   196,   161,
+     199,   244,   160,   161,   202,   162,   129,   250,   161,   165,
+     162,   131,   253,   165,   101,   130,   154,   218,   165,   156,
+     257,   149,   259,   221,  -154,   132,   101,   157,   149,   158,
+     159,   160,   161,   297,   162,   298,   101,   163,   164,   232,
+     233,   234,   165,   235,   170,   236,   237,   238,   239,   240,
+     241,   242,   243,   101,  -153,   286,   104,   357,   149,   101,
+     149,   287,   251,   133,   101,   107,   358,   255,   256,   135,
+     258,   148,   260,  -133,  -133,   262,  -134,  -134,   149,   152,
+     153,   149,   136,   154,   137,   155,   156,   108,   359,    30,
+     304,   110,   360,   157,   147,   158,   159,   160,   161,   169,
+     162,   111,   361,   163,   164,   141,   142,   291,   165,   228,
+     152,   153,   176,   179,   154,   180,   155,   156,   181,   182,
+     183,   184,   205,   151,   220,   206,   323,   222,   171,   249,
+     264,   289,   292,   299,   295,   331,   300,   339,   341,   365,
+     303,   350,   305,   379,   158,   159,   160,   161,   340,   162,
+     351,   352,   305,   164,   311,   312,   313,   165,   314,   368,
+     315,   316,   353,   102,   354,   382,     2,     3,   355,   391,
+     356,   383,   392,   140,     4,   394,   390,   254,   329,     0,
+       5,     6,     7,     8,   152,   153,   334,     9,   154,   337,
+     155,   156,  -110,     0,     0,     0,     0,     0,   252,     0,
+       0,  -110,  -110,     0,     0,     0,   149,    10,   245,   157,
+     148,   158,   159,   160,   161,     0,   162,     0,     0,   163,
+     164,   393,     0,   246,   165,     0,   148,   305,     0,     0,
+       0,   373,     0,   374,   375,     0,   376,     0,     0,     0,
+     157,     0,   158,   159,   160,   161,     0,   162,   270,     0,
+     163,   164,   377,   378,   271,   165,   148,     0,    11,    12,
+      13,    14,    15,    16,    17,    18,    19,    20,    21,    22,
+      23,    24,    25,    26,     0,    27,    28,    29,    30,     0,
+      31,    32,    33,    34,    35,    36,    37,    38,    39,    40,
+      41,    42,    43,    44,    45,    46,    47,    48,   148,    49,
+       0,     0,    50,     0,    51,     0,     0,     0,    52,     0,
+       0,     0,    53,     0,   157,    54,   158,   159,   160,   161,
+     148,   162,   273,     0,   163,   164,   152,   153,   274,   165,
+     154,  -112,   155,   156,     0,     0,     0,     0,     0,     0,
+    -112,  -112,   152,   153,     0,   149,   154,  -105,   155,   156,
+       0,     0,     0,     0,     0,     0,  -105,  -105,   152,   153,
+       0,   149,   154,     0,   155,   156,     0,     0,     0,     0,
+       0,     0,     0,     0,   152,   153,     0,  -106,   154,     0,
+     155,   156,     0,     0,     0,     0,  -106,  -106,   152,   153,
+       0,   149,   154,     0,   155,   156,     0,     0,     0,     0,
+       0,     0,     0,     0,   152,   153,     0,     0,   154,     0,
+     155,   156,     0,     0,     0,     0,     0,     0,     0,  -107,
+     152,   153,     0,     0,   154,     0,   155,   156,  -107,  -107,
+       0,     0,     0,   149,     0,     0,   152,   153,     0,     0,
+     154,  -108,   155,   156,     0,     0,     0,     0,     0,     0,
+    -108,  -108,     0,     0,     0,   149,   157,     0,   158,   159,
+     160,   161,     0,   162,   301,     0,   163,   164,     0,     0,
+     302,   165,   157,   148,   158,   159,   160,   161,     0,   162,
+     346,     0,   163,   164,     0,     0,   347,   165,   157,     0,
+     158,   159,   160,   161,     0,   162,   348,     0,   163,   164,
+       0,     0,   349,   165,   157,     0,   158,   159,   160,   161,
+       0,   162,   248,     0,   163,   164,     0,     0,   157,   165,
+     158,   159,   160,   161,     0,   162,     0,     0,   163,   164,
+       0,     0,   261,   165,   157,     0,   158,   159,   160,   161,
+       0,   162,     0,     0,   163,   164,     0,     0,   263,   165,
+     157,     0,   158,   159,   160,   161,     0,   162,     0,     0,
+     163,   164,     0,     0,   265,   165,   157,     0,   158,   159,
+     160,   161,     0,   162,   266,     0,   163,   164,   152,   153,
+       0,   165,   154,     0,   155,   156,     0,     0,     0,     0,
+       0,     0,   152,   153,  -111,     0,   154,     0,   155,   156,
+       0,     0,     0,  -111,  -111,     0,   152,   153,   149,     0,
+     154,     0,   155,   156,     0,     0,     0,     0,     0,     0,
+       0,     0,   152,   153,     0,     0,   154,     0,   155,   156,
+       0,     0,     0,     0,     0,     0,     0,     0,   152,   153,
+       0,     0,   154,     0,   155,   156,     0,     0,     0,     0,
+       0,     0,   152,   153,     0,     0,   154,     0,   155,   156,
+       0,     0,     0,     0,     0,     0,     0,     0,   152,   153,
+       0,     0,   154,     0,   155,   156,     0,     0,     0,     0,
+       0,     0,   152,   153,     0,     0,   154,     0,   155,   156,
+       0,     0,     0,     0,     0,     0,     0,     0,   152,   153,
+       0,     0,   154,     0,   155,   156,     0,     0,   157,     0,
+     158,   159,   160,   161,     0,   162,   267,     0,   163,   164,
+       0,     0,   157,   165,   158,   159,   160,   161,     0,   162,
+     272,     0,   163,   164,     0,     0,   157,   165,   158,   159,
+     160,   161,     0,   162,     0,     0,   163,   164,     0,     0,
+     276,   165,   157,     0,   158,   159,   160,   161,     0,   162,
+       0,     0,   163,   164,     0,     0,   278,   165,   157,     0,
+     158,   159,   160,   161,     0,   162,   290,     0,   163,   164,
+       0,     0,   157,   165,   158,   159,   160,   161,     0,   162,
+       0,     0,   163,   164,     0,     0,   293,   165,   157,     0,
+     158,   159,   160,   161,     0,   162,   309,     0,   163,   164,
+       0,     0,   157,   165,   158,   159,   160,   161,     0,   162,
+       0,     0,   163,   164,     0,     0,   330,   165,   157,     0,
+     158,   159,   160,   161,     0,   162,     0,     0,   163,   164,
+     152,   153,   246,   165,   154,     0,   155,   156,     0,     0,
+       0,     0,     0,     0,   152,   153,     0,     0,   154,     0,
+     155,   156,     0,     0,     0,     0,     5,     6,   317,   318,
+     152,   153,     0,     9,   154,     0,   155,   156,     0,     0,
+       0,     0,     0,     0,   152,   153,     0,     0,   154,     0,
+     155,   156,     0,     0,     0,     0,     0,     0,     0,     0,
+     152,   153,     0,     0,   154,     0,   155,   156,     0,     0,
+       0,     0,     0,     0,   152,   153,     0,     0,   154,     0,
+     155,   156,     0,     0,     0,     0,     0,     0,     0,     0,
+     152,   153,     0,     0,   154,     0,   155,   156,     0,     0,
+       0,     0,     0,     0,   152,   153,     0,     0,   154,     0,
+     155,   156,   319,   320,   321,   322,     0,     0,   152,   153,
+       0,     0,   154,     0,   155,   156,     0,     0,     0,     0,
+     157,     0,   158,   159,   160,   161,   338,   162,     0,     0,
+     163,   164,     0,     0,   157,   165,   158,   159,   160,   161,
+       0,   162,     0,     0,   163,   164,     0,     0,   342,   165,
+     157,     0,   158,   159,   160,   161,     0,   162,   343,     0,
+     163,   164,     0,     0,   157,   165,   158,   159,   160,   161,
+       0,   162,     0,     0,   163,   164,     0,     0,   344,   165,
+     157,     0,   158,   159,   160,   161,     0,   162,   345,     0,
+     163,   164,     0,     0,   157,   165,   158,   159,   160,   161,
+       0,   162,     0,     0,   163,   164,     0,     0,   362,   165,
+     157,     0,   158,   159,   160,   161,   363,   162,     0,     0,
+     163,   164,     0,     0,   157,   165,   158,   159,   160,   161,
+       0,   162,   364,     0,   163,   164,     0,     0,   157,   165,
+     158,   159,   160,   161,     0,   162,     0,     0,   163,   164,
+     152,   153,   384,   165,   154,     0,   155,   156,     0,     0,
+       0,     0,     0,     0,     0,     0,   152,   153,     0,     0,
+     154,     0,   155,   156,     0,     0,     0,     0,     0,     0,
+       0,     0,   152,   153,     0,     0,   154,     0,   155,   156,
+       0,     0,     0,     0,     0,     0,     0,     0,   152,   153,
+       0,     0,   154,     0,   155,   156,     0,     0,     0,     0,
+       0,     0,     0,     0,   152,   153,     0,     0,   154,     0,
+     155,   156,     0,     0,     0,     0,     0,     0,   152,   153,
+       0,     0,   154,     0,   155,   156,     0,     0,     0,     0,
+       0,     0,  -155,   153,     0,     0,   154,     0,   155,   156,
+       0,     0,     0,     0,     0,     0,     0,   153,     0,     0,
+     154,     0,   155,   156,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+     157,     0,   158,   159,   160,   161,   154,   162,     0,   156,
+     163,   164,     0,     0,   385,   165,   157,     0,   158,   159,
+     160,   161,     0,   162,     0,     0,   163,   164,     0,     0,
+     386,   165,   157,     0,   158,   159,   160,   161,     0,   162,
+       0,     0,   163,   164,     0,     0,   387,   165,   157,     0,
+     158,   159,   160,   161,     0,   162,     0,     0,   163,   164,
+       0,     0,   388,   165,   157,     0,   158,   159,   160,   161,
+     389,   162,     0,     0,   163,   164,     0,     0,   157,   165,
+     158,   159,   160,   161,     0,   162,     0,     0,   163,   164,
+       0,     0,   157,   165,   158,   159,   160,   161,     0,   162,
+       0,     0,   163,   164,     0,     0,   157,   165,   158,   159,
+     160,   161,     0,   162,     0,     0,     4,   164,     0,     0,
+       0,   165,     5,     6,    90,    91,     0,     0,     0,     9,
+       0,     0,   157,     0,   158,   159,   160,   161,     0,   162,
+       0,     0,     0,   164,     0,     0,     0,   165,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     4,     0,     0,     0,     0,     0,
+       5,     6,    90,    91,     0,     0,     0,     9,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+      11,    12,    13,    14,    15,    16,    17,    18,    92,    93,
+      94,    95,     0,     0,     0,     0,     0,     0,     0,     0,
+      30,     0,    31,    32,    33,     0,    35,    36,     0,     0,
+       0,    40,    41,     0,     4,     0,     0,     0,     0,    96,
+       5,     6,    90,    91,    50,     0,    51,     9,     0,     0,
+       0,     0,     0,     0,    53,   197,     0,    54,    11,    12,
+      13,    14,    15,    16,    17,    18,    92,    93,    94,    95,
+       0,     0,     0,     0,     0,     0,     0,     0,    30,     0,
+      31,    32,    33,     0,    35,    36,     0,     0,     0,    40,
+      41,     0,     4,     0,     0,     0,     0,    96,     5,     6,
+     207,   208,    50,     0,    51,     9,     0,     0,     0,     0,
+       0,     0,    53,   200,     0,    54,     0,     0,    11,    12,
+      13,    14,    15,    16,    17,    18,    92,    93,    94,    95,
+       0,     0,     0,     0,     0,     0,     0,     0,    30,     0,
+      31,    32,    33,     0,    35,    36,     0,     0,     0,    40,
+      41,     0,     4,     0,     0,     0,     0,    96,     5,     6,
+      90,    91,    50,     0,    51,     9,     0,     0,     0,     0,
+       0,     0,    53,   203,     0,    54,    11,    12,    13,    14,
+      15,    16,    17,    18,   209,   210,   211,   212,     0,     0,
+       0,     0,     0,     0,     0,     0,    30,     0,    31,    32,
+      33,     0,    35,    36,     0,     0,     0,    40,    41,     0,
+       4,     0,     0,     0,     0,    96,     5,     6,    90,    91,
+      50,     0,    51,     9,     0,     0,     0,     0,     0,     0,
+      53,   213,     0,    54,     0,     0,    11,    12,    13,    14,
+      15,    16,    17,    18,    92,    93,    94,    95,     0,     0,
+       0,     0,     0,     0,     0,     0,    30,     0,    31,    32,
+      33,     0,    35,    36,     0,     0,     0,    40,    41,     0,
+       4,     0,     0,     0,     0,    96,     5,     6,    90,    91,
+      50,     0,    51,     9,     0,     0,     0,     0,     0,     0,
+      53,   223,     0,    54,    11,    12,    13,    14,    15,    16,
+      17,    18,    92,    93,    94,    95,     0,     0,     0,     0,
+       0,     0,     0,     0,    30,     0,    31,    32,    33,     0,
+      35,    36,     0,     0,     0,    40,    41,     0,     4,     0,
+       0,     0,     0,    96,     5,     6,    90,    91,    50,     0,
+      51,     9,     0,     0,     0,     0,     0,     0,    53,   230,
+       0,    54,     0,     0,    11,    12,    13,    14,    15,    16,
+      17,    18,    92,    93,    94,    95,     0,     0,     0,     0,
+       0,     0,     0,     0,    30,     0,    31,    32,    33,     0,
+      35,    36,     0,     0,     0,    40,    41,     0,     4,     0,
+       0,     0,     0,    96,     5,     6,    90,    91,    50,     0,
+      51,     9,     0,     0,     0,     0,     0,     0,    53,     0,
+       0,    54,    11,    12,    13,    14,    15,    16,    17,    18,
+      92,    93,    94,    95,     0,     0,     0,     0,     0,     0,
+       0,     0,    30,     0,    31,    32,    33,     0,    35,    36,
+       0,     0,     0,    40,    41,     0,     4,     0,     0,     0,
+       0,    96,     5,     6,    90,    91,    50,     0,    51,     9,
+       0,     0,     0,     0,     0,     0,    99,     0,     0,    54,
+       0,     0,    11,    12,    13,    14,    15,    16,    17,    18,
+      92,    93,    94,    95,     0,     0,     0,     0,     0,     0,
+       0,     0,    30,     0,    31,    32,    33,     0,    35,    36,
+       0,     0,     0,    40,    41,     0,     4,     0,     0,     0,
+       0,    96,     5,     6,    90,    91,    50,     0,    51,     9,
+       0,     0,     0,     0,     0,     0,   112,     0,     0,    54,
+      11,    12,    13,    14,    15,    16,    17,    18,    92,    93,
+      94,    95,     0,     0,     0,     0,     0,     0,     0,     0,
+      30,     0,    31,    32,    33,     0,    35,    36,     0,     0,
+       0,    40,    41,     0,     4,     0,     0,     0,     0,    96,
+       5,     6,    90,    91,    50,     0,    51,     9,     0,     0,
+       0,     0,     0,     0,   114,     0,     0,    54,     0,     0,
+      11,    12,    13,    14,    15,    16,    17,    18,    92,    93,
+      94,    95,     0,     0,     0,     0,     0,     0,     0,     0,
+      30,     0,    31,    32,    33,     0,    35,    36,     0,     0,
+       0,    40,    41,     0,     4,     0,     0,     0,     0,    96,
+       5,     6,   138,    91,    50,     0,    51,     9,     0,     0,
+       0,     0,     0,     0,   116,     0,     0,    54,    11,    12,
+      13,    14,    15,    16,    17,    18,    92,    93,    94,    95,
+       0,     0,     0,     0,     0,     0,     0,     0,    30,     0,
+      31,    32,    33,     0,    35,    36,     0,     0,     0,    40,
+      41,     0,     4,     0,     0,     0,     0,    96,     5,     6,
+      90,    91,    50,     0,    51,     9,     0,     0,     0,     0,
+       0,     0,   118,     0,     0,    54,     0,     0,    11,    12,
+      13,    14,    15,    16,    17,    18,    19,    20,    21,    22,
+       0,     0,     0,     0,     0,     0,     0,     0,    30,     0,
+      31,    32,    33,     0,    35,    36,     0,     0,     0,    40,
+      41,     0,     4,     0,     0,     0,     0,    96,     5,     6,
+      90,    91,    50,     0,    51,     9,     0,     0,     0,     0,
+       0,     0,    53,     0,     0,    54,    11,    12,    13,    14,
+      15,    16,    17,    18,    92,    93,    94,    95,     0,     0,
+       0,     0,     0,     0,     0,     0,    30,     0,    31,    32,
+      33,     0,    35,    36,     0,     0,     0,    40,    41,     0,
+       4,     0,     0,     0,     0,    96,     5,     6,    90,    91,
+      50,     0,    51,     9,     0,     0,     0,     0,     0,     0,
+     174,     0,     0,    54,     0,     0,    11,    12,    13,    14,
+      15,    16,    17,    18,    92,    93,    94,    95,     0,     0,
+       0,     0,     0,     0,     0,     0,    30,     0,    31,    32,
+      33,     0,    35,    36,     0,     0,     0,    40,    41,     0,
+       0,     0,     0,     0,     0,    96,     0,     0,     0,     0,
+      50,     0,    51,     0,     0,     0,     0,     0,     0,     0,
+     187,     0,     0,    54,   324,    12,    13,   325,   326,    16,
+     327,   328,    92,    93,    94,    95,     0,     0,     0,     0,
+       0,     0,     0,     0,    30,     0,    31,    32,    33,     0,
+      35,    36,     0,     0,     0,    40,    41,     0,     0,     0,
+       0,     0,     0,    96,     0,     0,     0,     0,    50,     0,
+      51,     0,     0,     0,     0,     0,     0,     0,    53,     0,
+       0,    54
+};
+
+static const yytype_int16 yycheck[] =
+{
+       1,     1,   115,     7,    12,     3,     4,   369,   112,     7,
+     132,     9,    10,   142,   254,    19,    20,    21,    22,   141,
+     142,   132,    26,    24,   264,   112,   113,   113,     7,   391,
+     141,    10,     7,   146,   120,    10,   141,     7,   142,   141,
+      10,   112,   147,   141,   112,   147,    11,    47,   141,   147,
+      51,   146,     4,    11,   147,     7,   141,     3,     4,   112,
+     113,     7,   147,     9,    10,    66,    70,    19,    20,    21,
+      22,   146,   141,    77,    26,   141,   141,    29,   147,   146,
+     141,   147,   147,    11,   141,    11,   147,   139,   146,   141,
+     147,   146,   147,   299,   300,    47,   146,   147,    50,   339,
+     146,   147,    54,    11,   146,   113,    11,   146,   147,   146,
+     111,    63,    64,   114,   146,   147,   146,   118,    70,   146,
+     147,   146,   126,     3,     4,    77,   126,     7,    80,     9,
+      10,   146,   147,   146,   138,   133,   137,   135,   136,   137,
+     138,   146,   140,   141,   148,   143,   144,    99,   149,   147,
+     148,   103,   104,   105,   106,   107,   108,   109,   110,   138,
+     112,   165,   137,   138,   116,   140,   146,   171,   138,   148,
+     140,   113,   176,   148,   126,   146,     7,   129,   148,    10,
+     181,   146,   183,   135,   142,   146,   138,   133,   146,   135,
+     136,   137,   138,   139,   140,   141,   148,   143,   144,   151,
+     152,   153,   148,   155,   132,   157,   158,   159,   160,   161,
+     162,   163,   164,   165,   142,   141,   146,   147,   146,   171,
+     146,   147,   174,   146,   176,   146,   147,   179,   180,   146,
+     182,    11,   184,   141,   142,   187,   141,   142,   146,     3,
+       4,   146,   112,     7,   146,     9,    10,   146,   147,   112,
+     254,   146,   147,   133,   142,   135,   136,   137,   138,    12,
+     140,   146,   147,   143,   144,    48,    49,   219,   148,   149,
+       3,     4,   141,   146,     7,   146,     9,    10,   146,   146,
+     146,   146,   142,   141,   112,   142,   286,   113,   141,   113,
+     141,   113,   112,   245,   142,   113,   248,   141,   141,   138,
+     252,   147,   254,   141,   135,   136,   137,   138,   309,   140,
+     147,   147,   264,   144,   266,   267,   268,   148,   270,   115,
+     272,   273,   147,     7,   147,   146,     0,     1,   147,   141,
+     147,   147,   147,    47,     8,   391,   379,   177,   290,    -1,
+      14,    15,    16,    17,     3,     4,   298,    21,     7,   301,
+       9,    10,   132,    -1,    -1,    -1,    -1,    -1,   138,    -1,
+      -1,   141,   142,    -1,    -1,    -1,   146,    41,   132,   133,
+      11,   135,   136,   137,   138,    -1,   140,    -1,    -1,   143,
+     144,   382,    -1,   147,   148,    -1,    11,   339,    -1,    -1,
+      -1,   343,    -1,   345,   346,    -1,   348,    -1,    -1,    -1,
+     133,    -1,   135,   136,   137,   138,    -1,   140,   141,    -1,
+     143,   144,   364,   365,   147,   148,    11,    -1,    92,    93,
+      94,    95,    96,    97,    98,    99,   100,   101,   102,   103,
+     104,   105,   106,   107,    -1,   109,   110,   111,   112,    -1,
+     114,   115,   116,   117,   118,   119,   120,   121,   122,   123,
+     124,   125,   126,   127,   128,   129,   130,   131,    11,   133,
+      -1,    -1,   136,    -1,   138,    -1,    -1,    -1,   142,    -1,
+      -1,    -1,   146,    -1,   133,   149,   135,   136,   137,   138,
+      11,   140,   141,    -1,   143,   144,     3,     4,   147,   148,
+       7,   132,     9,    10,    -1,    -1,    -1,    -1,    -1,    -1,
+     141,   142,     3,     4,    -1,   146,     7,   132,     9,    10,
+      -1,    -1,    -1,    -1,    -1,    -1,   141,   142,     3,     4,
+      -1,   146,     7,    -1,     9,    10,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,     3,     4,    -1,   132,     7,    -1,
+       9,    10,    -1,    -1,    -1,    -1,   141,   142,     3,     4,
+      -1,   146,     7,    -1,     9,    10,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,     3,     4,    -1,    -1,     7,    -1,
+       9,    10,    -1,    -1,    -1,    -1,    -1,    -1,    -1,   132,
+       3,     4,    -1,    -1,     7,    -1,     9,    10,   141,   142,
+      -1,    -1,    -1,   146,    -1,    -1,     3,     4,    -1,    -1,
+       7,   132,     9,    10,    -1,    -1,    -1,    -1,    -1,    -1,
+     141,   142,    -1,    -1,    -1,   146,   133,    -1,   135,   136,
+     137,   138,    -1,   140,   141,    -1,   143,   144,    -1,    -1,
+     147,   148,   133,    11,   135,   136,   137,   138,    -1,   140,
+     141,    -1,   143,   144,    -1,    -1,   147,   148,   133,    -1,
+     135,   136,   137,   138,    -1,   140,   141,    -1,   143,   144,
+      -1,    -1,   147,   148,   133,    -1,   135,   136,   137,   138,
+      -1,   140,   141,    -1,   143,   144,    -1,    -1,   133,   148,
+     135,   136,   137,   138,    -1,   140,    -1,    -1,   143,   144,
+      -1,    -1,   147,   148,   133,    -1,   135,   136,   137,   138,
+      -1,   140,    -1,    -1,   143,   144,    -1,    -1,   147,   148,
+     133,    -1,   135,   136,   137,   138,    -1,   140,    -1,    -1,
+     143,   144,    -1,    -1,   147,   148,   133,    -1,   135,   136,
+     137,   138,    -1,   140,   141,    -1,   143,   144,     3,     4,
+      -1,   148,     7,    -1,     9,    10,    -1,    -1,    -1,    -1,
+      -1,    -1,     3,     4,   132,    -1,     7,    -1,     9,    10,
+      -1,    -1,    -1,   141,   142,    -1,     3,     4,   146,    -1,
+       7,    -1,     9,    10,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,     3,     4,    -1,    -1,     7,    -1,     9,    10,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,     3,     4,
+      -1,    -1,     7,    -1,     9,    10,    -1,    -1,    -1,    -1,
+      -1,    -1,     3,     4,    -1,    -1,     7,    -1,     9,    10,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,     3,     4,
+      -1,    -1,     7,    -1,     9,    10,    -1,    -1,    -1,    -1,
+      -1,    -1,     3,     4,    -1,    -1,     7,    -1,     9,    10,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,     3,     4,
+      -1,    -1,     7,    -1,     9,    10,    -1,    -1,   133,    -1,
+     135,   136,   137,   138,    -1,   140,   141,    -1,   143,   144,
+      -1,    -1,   133,   148,   135,   136,   137,   138,    -1,   140,
+     141,    -1,   143,   144,    -1,    -1,   133,   148,   135,   136,
+     137,   138,    -1,   140,    -1,    -1,   143,   144,    -1,    -1,
+     147,   148,   133,    -1,   135,   136,   137,   138,    -1,   140,
+      -1,    -1,   143,   144,    -1,    -1,   147,   148,   133,    -1,
+     135,   136,   137,   138,    -1,   140,   141,    -1,   143,   144,
+      -1,    -1,   133,   148,   135,   136,   137,   138,    -1,   140,
+      -1,    -1,   143,   144,    -1,    -1,   147,   148,   133,    -1,
+     135,   136,   137,   138,    -1,   140,   141,    -1,   143,   144,
+      -1,    -1,   133,   148,   135,   136,   137,   138,    -1,   140,
+      -1,    -1,   143,   144,    -1,    -1,   147,   148,   133,    -1,
+     135,   136,   137,   138,    -1,   140,    -1,    -1,   143,   144,
+       3,     4,   147,   148,     7,    -1,     9,    10,    -1,    -1,
+      -1,    -1,    -1,    -1,     3,     4,    -1,    -1,     7,    -1,
+       9,    10,    -1,    -1,    -1,    -1,    14,    15,    16,    17,
+       3,     4,    -1,    21,     7,    -1,     9,    10,    -1,    -1,
+      -1,    -1,    -1,    -1,     3,     4,    -1,    -1,     7,    -1,
+       9,    10,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+       3,     4,    -1,    -1,     7,    -1,     9,    10,    -1,    -1,
+      -1,    -1,    -1,    -1,     3,     4,    -1,    -1,     7,    -1,
+       9,    10,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+       3,     4,    -1,    -1,     7,    -1,     9,    10,    -1,    -1,
+      -1,    -1,    -1,    -1,     3,     4,    -1,    -1,     7,    -1,
+       9,    10,   100,   101,   102,   103,    -1,    -1,     3,     4,
+      -1,    -1,     7,    -1,     9,    10,    -1,    -1,    -1,    -1,
+     133,    -1,   135,   136,   137,   138,   139,   140,    -1,    -1,
+     143,   144,    -1,    -1,   133,   148,   135,   136,   137,   138,
+      -1,   140,    -1,    -1,   143,   144,    -1,    -1,   147,   148,
+     133,    -1,   135,   136,   137,   138,    -1,   140,   141,    -1,
+     143,   144,    -1,    -1,   133,   148,   135,   136,   137,   138,
+      -1,   140,    -1,    -1,   143,   144,    -1,    -1,   147,   148,
+     133,    -1,   135,   136,   137,   138,    -1,   140,   141,    -1,
+     143,   144,    -1,    -1,   133,   148,   135,   136,   137,   138,
+      -1,   140,    -1,    -1,   143,   144,    -1,    -1,   147,   148,
+     133,    -1,   135,   136,   137,   138,   139,   140,    -1,    -1,
+     143,   144,    -1,    -1,   133,   148,   135,   136,   137,   138,
+      -1,   140,   141,    -1,   143,   144,    -1,    -1,   133,   148,
+     135,   136,   137,   138,    -1,   140,    -1,    -1,   143,   144,
+       3,     4,   147,   148,     7,    -1,     9,    10,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,     3,     4,    -1,    -1,
+       7,    -1,     9,    10,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,     3,     4,    -1,    -1,     7,    -1,     9,    10,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,     3,     4,
+      -1,    -1,     7,    -1,     9,    10,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,     3,     4,    -1,    -1,     7,    -1,
+       9,    10,    -1,    -1,    -1,    -1,    -1,    -1,     3,     4,
+      -1,    -1,     7,    -1,     9,    10,    -1,    -1,    -1,    -1,
+      -1,    -1,     3,     4,    -1,    -1,     7,    -1,     9,    10,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,     4,    -1,    -1,
+       7,    -1,     9,    10,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+     133,    -1,   135,   136,   137,   138,     7,   140,    -1,    10,
+     143,   144,    -1,    -1,   147,   148,   133,    -1,   135,   136,
+     137,   138,    -1,   140,    -1,    -1,   143,   144,    -1,    -1,
+     147,   148,   133,    -1,   135,   136,   137,   138,    -1,   140,
+      -1,    -1,   143,   144,    -1,    -1,   147,   148,   133,    -1,
+     135,   136,   137,   138,    -1,   140,    -1,    -1,   143,   144,
+      -1,    -1,   147,   148,   133,    -1,   135,   136,   137,   138,
+     139,   140,    -1,    -1,   143,   144,    -1,    -1,   133,   148,
+     135,   136,   137,   138,    -1,   140,    -1,    -1,   143,   144,
+      -1,    -1,   133,   148,   135,   136,   137,   138,    -1,   140,
+      -1,    -1,   143,   144,    -1,    -1,   133,   148,   135,   136,
+     137,   138,    -1,   140,    -1,    -1,     8,   144,    -1,    -1,
+      -1,   148,    14,    15,    16,    17,    -1,    -1,    -1,    21,
+      -1,    -1,   133,    -1,   135,   136,   137,   138,    -1,   140,
+      -1,    -1,    -1,   144,    -1,    -1,    -1,   148,    -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,     8,    -1,    -1,    -1,    -1,    -1,
+      14,    15,    16,    17,    -1,    -1,    -1,    21,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      92,    93,    94,    95,    96,    97,    98,    99,   100,   101,
+     102,   103,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+     112,    -1,   114,   115,   116,    -1,   118,   119,    -1,    -1,
+      -1,   123,   124,    -1,     8,    -1,    -1,    -1,    -1,   131,
+      14,    15,    16,    17,   136,    -1,   138,    21,    -1,    -1,
+      -1,    -1,    -1,    -1,   146,   147,    -1,   149,    92,    93,
+      94,    95,    96,    97,    98,    99,   100,   101,   102,   103,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,   112,    -1,
+     114,   115,   116,    -1,   118,   119,    -1,    -1,    -1,   123,
+     124,    -1,     8,    -1,    -1,    -1,    -1,   131,    14,    15,
+      16,    17,   136,    -1,   138,    21,    -1,    -1,    -1,    -1,
+      -1,    -1,   146,   147,    -1,   149,    -1,    -1,    92,    93,
+      94,    95,    96,    97,    98,    99,   100,   101,   102,   103,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,   112,    -1,
+     114,   115,   116,    -1,   118,   119,    -1,    -1,    -1,   123,
+     124,    -1,     8,    -1,    -1,    -1,    -1,   131,    14,    15,
+      16,    17,   136,    -1,   138,    21,    -1,    -1,    -1,    -1,
+      -1,    -1,   146,   147,    -1,   149,    92,    93,    94,    95,
+      96,    97,    98,    99,   100,   101,   102,   103,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,   112,    -1,   114,   115,
+     116,    -1,   118,   119,    -1,    -1,    -1,   123,   124,    -1,
+       8,    -1,    -1,    -1,    -1,   131,    14,    15,    16,    17,
+     136,    -1,   138,    21,    -1,    -1,    -1,    -1,    -1,    -1,
+     146,   147,    -1,   149,    -1,    -1,    92,    93,    94,    95,
+      96,    97,    98,    99,   100,   101,   102,   103,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,   112,    -1,   114,   115,
+     116,    -1,   118,   119,    -1,    -1,    -1,   123,   124,    -1,
+       8,    -1,    -1,    -1,    -1,   131,    14,    15,    16,    17,
+     136,    -1,   138,    21,    -1,    -1,    -1,    -1,    -1,    -1,
+     146,   147,    -1,   149,    92,    93,    94,    95,    96,    97,
+      98,    99,   100,   101,   102,   103,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,   112,    -1,   114,   115,   116,    -1,
+     118,   119,    -1,    -1,    -1,   123,   124,    -1,     8,    -1,
+      -1,    -1,    -1,   131,    14,    15,    16,    17,   136,    -1,
+     138,    21,    -1,    -1,    -1,    -1,    -1,    -1,   146,   147,
+      -1,   149,    -1,    -1,    92,    93,    94,    95,    96,    97,
+      98,    99,   100,   101,   102,   103,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,   112,    -1,   114,   115,   116,    -1,
+     118,   119,    -1,    -1,    -1,   123,   124,    -1,     8,    -1,
+      -1,    -1,    -1,   131,    14,    15,    16,    17,   136,    -1,
+     138,    21,    -1,    -1,    -1,    -1,    -1,    -1,   146,    -1,
+      -1,   149,    92,    93,    94,    95,    96,    97,    98,    99,
+     100,   101,   102,   103,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,   112,    -1,   114,   115,   116,    -1,   118,   119,
+      -1,    -1,    -1,   123,   124,    -1,     8,    -1,    -1,    -1,
+      -1,   131,    14,    15,    16,    17,   136,    -1,   138,    21,
+      -1,    -1,    -1,    -1,    -1,    -1,   146,    -1,    -1,   149,
+      -1,    -1,    92,    93,    94,    95,    96,    97,    98,    99,
+     100,   101,   102,   103,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,   112,    -1,   114,   115,   116,    -1,   118,   119,
+      -1,    -1,    -1,   123,   124,    -1,     8,    -1,    -1,    -1,
+      -1,   131,    14,    15,    16,    17,   136,    -1,   138,    21,
+      -1,    -1,    -1,    -1,    -1,    -1,   146,    -1,    -1,   149,
+      92,    93,    94,    95,    96,    97,    98,    99,   100,   101,
+     102,   103,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+     112,    -1,   114,   115,   116,    -1,   118,   119,    -1,    -1,
+      -1,   123,   124,    -1,     8,    -1,    -1,    -1,    -1,   131,
+      14,    15,    16,    17,   136,    -1,   138,    21,    -1,    -1,
+      -1,    -1,    -1,    -1,   146,    -1,    -1,   149,    -1,    -1,
+      92,    93,    94,    95,    96,    97,    98,    99,   100,   101,
+     102,   103,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+     112,    -1,   114,   115,   116,    -1,   118,   119,    -1,    -1,
+      -1,   123,   124,    -1,     8,    -1,    -1,    -1,    -1,   131,
+      14,    15,    16,    17,   136,    -1,   138,    21,    -1,    -1,
+      -1,    -1,    -1,    -1,   146,    -1,    -1,   149,    92,    93,
+      94,    95,    96,    97,    98,    99,   100,   101,   102,   103,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,   112,    -1,
+     114,   115,   116,    -1,   118,   119,    -1,    -1,    -1,   123,
+     124,    -1,     8,    -1,    -1,    -1,    -1,   131,    14,    15,
+      16,    17,   136,    -1,   138,    21,    -1,    -1,    -1,    -1,
+      -1,    -1,   146,    -1,    -1,   149,    -1,    -1,    92,    93,
+      94,    95,    96,    97,    98,    99,   100,   101,   102,   103,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,   112,    -1,
+     114,   115,   116,    -1,   118,   119,    -1,    -1,    -1,   123,
+     124,    -1,     8,    -1,    -1,    -1,    -1,   131,    14,    15,
+      16,    17,   136,    -1,   138,    21,    -1,    -1,    -1,    -1,
+      -1,    -1,   146,    -1,    -1,   149,    92,    93,    94,    95,
+      96,    97,    98,    99,   100,   101,   102,   103,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,   112,    -1,   114,   115,
+     116,    -1,   118,   119,    -1,    -1,    -1,   123,   124,    -1,
+       8,    -1,    -1,    -1,    -1,   131,    14,    15,    16,    17,
+     136,    -1,   138,    21,    -1,    -1,    -1,    -1,    -1,    -1,
+     146,    -1,    -1,   149,    -1,    -1,    92,    93,    94,    95,
+      96,    97,    98,    99,   100,   101,   102,   103,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,   112,    -1,   114,   115,
+     116,    -1,   118,   119,    -1,    -1,    -1,   123,   124,    -1,
+      -1,    -1,    -1,    -1,    -1,   131,    -1,    -1,    -1,    -1,
+     136,    -1,   138,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+     146,    -1,    -1,   149,    92,    93,    94,    95,    96,    97,
+      98,    99,   100,   101,   102,   103,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,   112,    -1,   114,   115,   116,    -1,
+     118,   119,    -1,    -1,    -1,   123,   124,    -1,    -1,    -1,
+      -1,    -1,    -1,   131,    -1,    -1,    -1,    -1,   136,    -1,
+     138,    -1,    -1,    -1,    -1,    -1,    -1,    -1,   146,    -1,
+      -1,   149
+};
+
+/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+   symbol of state STATE-NUM.  */
+static const yytype_uint8 yystos[] =
+{
+       0,   151,     0,     1,     8,    14,    15,    16,    17,    21,
+      41,    92,    93,    94,    95,    96,    97,    98,    99,   100,
+     101,   102,   103,   104,   105,   106,   107,   109,   110,   111,
+     112,   114,   115,   116,   117,   118,   119,   120,   121,   122,
+     123,   124,   125,   126,   127,   128,   129,   130,   131,   133,
+     136,   138,   142,   146,   149,   152,   153,   154,   155,   156,
+     157,   158,   159,   161,   162,   164,   165,   166,   167,   168,
+     175,   176,   178,   179,   180,   181,   182,   183,   184,   185,
+     186,   187,   188,   189,   190,   191,   192,   193,   194,   142,
+      16,    17,   100,   101,   102,   103,   131,   159,   175,   146,
+     157,   159,   166,   146,   146,   146,   146,   146,   146,   146,
+     146,   146,   146,   157,   146,   157,   146,   157,   146,   157,
+     112,   113,   158,   112,   142,   157,   146,   159,   112,   146,
+     146,   113,   146,   146,   112,   146,   112,   146,    16,   159,
+     167,   168,   168,   159,   158,   158,   159,   142,    11,   146,
+     132,   141,     3,     4,     7,     9,    10,   133,   135,   136,
+     137,   138,   140,   143,   144,   148,   159,   159,   158,    12,
+     132,   141,   142,   174,   146,   157,   141,   157,   159,   146,
+     146,   146,   146,   146,   146,   159,   113,   146,   159,   169,
+     159,   159,   159,   159,   159,   159,   159,   147,   158,   159,
+     147,   158,   159,   147,   158,   142,   142,    16,    17,   100,
+     101,   102,   103,   147,   157,   175,   112,   113,   159,   160,
+     112,   159,   113,   147,   158,   177,   139,   147,   149,   157,
+     147,   158,   159,   159,   159,   159,   159,   159,   159,   159,
+     159,   159,   159,   159,   157,   132,   147,   163,   141,   113,
+     157,   159,   138,   157,   174,   159,   159,   158,   159,   158,
+     159,   147,   159,   147,   141,   147,   141,   141,   141,   147,
+     141,   147,   141,   141,   147,   147,   147,   147,   147,   147,
+     147,   147,   147,   147,   147,   147,   141,   147,   147,   113,
+     141,   159,   112,   147,   147,   142,   147,   139,   141,   159,
+     159,   141,   147,   159,   157,   159,   169,   147,   147,   141,
+     169,   159,   159,   159,   159,   159,   159,    16,    17,   100,
+     101,   102,   103,   175,    92,    95,    96,    98,    99,   159,
+     147,   113,   113,   120,   159,   163,   163,   159,   139,   141,
+     158,   141,   147,   141,   147,   141,   141,   147,   141,   147,
+     147,   147,   147,   147,   147,   147,   147,   147,   147,   147,
+     147,   147,   147,   139,   141,   138,   169,   147,   115,   146,
+     170,   171,   173,   159,   159,   159,   159,   159,   159,   141,
+     171,   172,   146,   147,   147,   147,   147,   147,   147,   139,
+     173,   141,   147,   158,   172,   147
+};
+
+#define yyerrok		(yyerrstatus = 0)
+#define yyclearin	(yychar = YYEMPTY)
+#define YYEMPTY		(-2)
+#define YYEOF		0
+
+#define YYACCEPT	goto yyacceptlab
+#define YYABORT		goto yyabortlab
+#define YYERROR		goto yyerrorlab
+
+
+/* Like YYERROR except do call yyerror.  This remains here temporarily
+   to ease the transition to the new meaning of YYERROR, for GCC.
+   Once GCC version 2 has supplanted version 1, this can go.  However,
+   YYFAIL appears to be in use.  Nevertheless, it is formally deprecated
+   in Bison 2.4.2's NEWS entry, where a plan to phase it out is
+   discussed.  */
+
+#define YYFAIL		goto yyerrlab
+#if defined YYFAIL
+  /* This is here to suppress warnings from the GCC cpp's
+     -Wunused-macros.  Normally we don't worry about that warning, but
+     some users do, and we want to make it easy for users to remove
+     YYFAIL uses, which will produce warnings from Bison 2.5.  */
+#endif
+
+#define YYRECOVERING()  (!!yyerrstatus)
+
+#define YYBACKUP(Token, Value)					\
+do								\
+  if (yychar == YYEMPTY && yylen == 1)				\
+    {								\
+      yychar = (Token);						\
+      yylval = (Value);						\
+      yytoken = YYTRANSLATE (yychar);				\
+      YYPOPSTACK (1);						\
+      goto yybackup;						\
+    }								\
+  else								\
+    {								\
+      yyerror (YY_("syntax error: cannot back up")); \
+      YYERROR;							\
+    }								\
+while (YYID (0))
+
+
+#define YYTERROR	1
+#define YYERRCODE	256
+
+
+/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
+   If N is 0, then set CURRENT to the empty location which ends
+   the previous symbol: RHS[0] (always defined).  */
+
+#define YYRHSLOC(Rhs, K) ((Rhs)[K])
+#ifndef YYLLOC_DEFAULT
+# define YYLLOC_DEFAULT(Current, Rhs, N)				\
+    do									\
+      if (YYID (N))                                                    \
+	{								\
+	  (Current).first_line   = YYRHSLOC (Rhs, 1).first_line;	\
+	  (Current).first_column = YYRHSLOC (Rhs, 1).first_column;	\
+	  (Current).last_line    = YYRHSLOC (Rhs, N).last_line;		\
+	  (Current).last_column  = YYRHSLOC (Rhs, N).last_column;	\
+	}								\
+      else								\
+	{								\
+	  (Current).first_line   = (Current).last_line   =		\
+	    YYRHSLOC (Rhs, 0).last_line;				\
+	  (Current).first_column = (Current).last_column =		\
+	    YYRHSLOC (Rhs, 0).last_column;				\
+	}								\
+    while (YYID (0))
+#endif
+
+
+/* YY_LOCATION_PRINT -- Print the location on the stream.
+   This macro was not mandated originally: define only if we know
+   we won't break user code: when these are the locations we know.  */
+
+#ifndef YY_LOCATION_PRINT
+# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL
+#  define YY_LOCATION_PRINT(File, Loc)			\
+     fprintf (File, "%d.%d-%d.%d",			\
+	      (Loc).first_line, (Loc).first_column,	\
+	      (Loc).last_line,  (Loc).last_column)
+# else
+#  define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+# endif
+#endif
+
+
+/* YYLEX -- calling `yylex' with the right arguments.  */
+
+#ifdef YYLEX_PARAM
+# define YYLEX yylex (&yylval, YYLEX_PARAM)
+#else
+# define YYLEX yylex (&yylval)
+#endif
+
+/* Enable debugging if requested.  */
+#if YYDEBUG
+
+# ifndef YYFPRINTF
+#  include <stdio.h> /* INFRINGES ON USER NAME SPACE */
+#  define YYFPRINTF fprintf
+# endif
+
+# define YYDPRINTF(Args)			\
+do {						\
+  if (yydebug)					\
+    YYFPRINTF Args;				\
+} while (YYID (0))
+
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)			  \
+do {									  \
+  if (yydebug)								  \
+    {									  \
+      YYFPRINTF (stderr, "%s ", Title);					  \
+      yy_symbol_print (stderr,						  \
+		  Type, Value); \
+      YYFPRINTF (stderr, "\n");						  \
+    }									  \
+} while (YYID (0))
+
+
+/*--------------------------------.
+| Print this symbol on YYOUTPUT.  |
+`--------------------------------*/
+
+/*ARGSUSED*/
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static void
+yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
+#else
+static void
+yy_symbol_value_print (yyoutput, yytype, yyvaluep)
+    FILE *yyoutput;
+    int yytype;
+    YYSTYPE const * const yyvaluep;
+#endif
+{
+  if (!yyvaluep)
+    return;
+# ifdef YYPRINT
+  if (yytype < YYNTOKENS)
+    YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+# else
+  YYUSE (yyoutput);
+# endif
+  switch (yytype)
+    {
+      default:
+	break;
+    }
+}
+
+
+/*--------------------------------.
+| Print this symbol on YYOUTPUT.  |
+`--------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static void
+yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
+#else
+static void
+yy_symbol_print (yyoutput, yytype, yyvaluep)
+    FILE *yyoutput;
+    int yytype;
+    YYSTYPE const * const yyvaluep;
+#endif
+{
+  if (yytype < YYNTOKENS)
+    YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
+  else
+    YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
+
+  yy_symbol_value_print (yyoutput, yytype, yyvaluep);
+  YYFPRINTF (yyoutput, ")");
+}
+
+/*------------------------------------------------------------------.
+| yy_stack_print -- Print the state stack from its BOTTOM up to its |
+| TOP (included).                                                   |
+`------------------------------------------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static void
+yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)
+#else
+static void
+yy_stack_print (yybottom, yytop)
+    yytype_int16 *yybottom;
+    yytype_int16 *yytop;
+#endif
+{
+  YYFPRINTF (stderr, "Stack now");
+  for (; yybottom <= yytop; yybottom++)
+    {
+      int yybot = *yybottom;
+      YYFPRINTF (stderr, " %d", yybot);
+    }
+  YYFPRINTF (stderr, "\n");
+}
+
+# define YY_STACK_PRINT(Bottom, Top)				\
+do {								\
+  if (yydebug)							\
+    yy_stack_print ((Bottom), (Top));				\
+} while (YYID (0))
+
+
+/*------------------------------------------------.
+| Report that the YYRULE is going to be reduced.  |
+`------------------------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static void
+yy_reduce_print (YYSTYPE *yyvsp, int yyrule)
+#else
+static void
+yy_reduce_print (yyvsp, yyrule)
+    YYSTYPE *yyvsp;
+    int yyrule;
+#endif
+{
+  int yynrhs = yyr2[yyrule];
+  int yyi;
+  unsigned long int yylno = yyrline[yyrule];
+  YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
+	     yyrule - 1, yylno);
+  /* The symbols being reduced.  */
+  for (yyi = 0; yyi < yynrhs; yyi++)
+    {
+      YYFPRINTF (stderr, "   $%d = ", yyi + 1);
+      yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
+		       &(yyvsp[(yyi + 1) - (yynrhs)])
+		       		       );
+      YYFPRINTF (stderr, "\n");
+    }
+}
+
+# define YY_REDUCE_PRINT(Rule)		\
+do {					\
+  if (yydebug)				\
+    yy_reduce_print (yyvsp, Rule); \
+} while (YYID (0))
+
+/* Nonzero means print parse trace.  It is left uninitialized so that
+   multiple parsers can coexist.  */
+int yydebug;
+#else /* !YYDEBUG */
+# define YYDPRINTF(Args)
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
+# define YY_STACK_PRINT(Bottom, Top)
+# define YY_REDUCE_PRINT(Rule)
+#endif /* !YYDEBUG */
+
+
+/* YYINITDEPTH -- initial size of the parser's stacks.  */
+#ifndef	YYINITDEPTH
+# define YYINITDEPTH 200
+#endif
+
+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
+   if the built-in stack extension method is used).
+
+   Do not make this value too large; the results are undefined if
+   YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
+   evaluated with infinite-precision integer arithmetic.  */
+
+#ifndef YYMAXDEPTH
+# define YYMAXDEPTH 10000
+#endif
+
+

+
+#if YYERROR_VERBOSE
+
+# ifndef yystrlen
+#  if defined __GLIBC__ && defined _STRING_H
+#   define yystrlen strlen
+#  else
+/* Return the length of YYSTR.  */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static YYSIZE_T
+yystrlen (const char *yystr)
+#else
+static YYSIZE_T
+yystrlen (yystr)
+    const char *yystr;
+#endif
+{
+  YYSIZE_T yylen;
+  for (yylen = 0; yystr[yylen]; yylen++)
+    continue;
+  return yylen;
+}
+#  endif
+# endif
+
+# ifndef yystpcpy
+#  if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
+#   define yystpcpy stpcpy
+#  else
+/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
+   YYDEST.  */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static char *
+yystpcpy (char *yydest, const char *yysrc)
+#else
+static char *
+yystpcpy (yydest, yysrc)
+    char *yydest;
+    const char *yysrc;
+#endif
+{
+  char *yyd = yydest;
+  const char *yys = yysrc;
+
+  while ((*yyd++ = *yys++) != '\0')
+    continue;
+
+  return yyd - 1;
+}
+#  endif
+# endif
+
+# ifndef yytnamerr
+/* Copy to YYRES the contents of YYSTR after stripping away unnecessary
+   quotes and backslashes, so that it's suitable for yyerror.  The
+   heuristic is that double-quoting is unnecessary unless the string
+   contains an apostrophe, a comma, or backslash (other than
+   backslash-backslash).  YYSTR is taken from yytname.  If YYRES is
+   null, do not copy; instead, return the length of what the result
+   would have been.  */
+static YYSIZE_T
+yytnamerr (char *yyres, const char *yystr)
+{
+  if (*yystr == '"')
+    {
+      YYSIZE_T yyn = 0;
+      char const *yyp = yystr;
+
+      for (;;)
+	switch (*++yyp)
+	  {
+	  case '\'':
+	  case ',':
+	    goto do_not_strip_quotes;
+
+	  case '\\':
+	    if (*++yyp != '\\')
+	      goto do_not_strip_quotes;
+	    /* Fall through.  */
+	  default:
+	    if (yyres)
+	      yyres[yyn] = *yyp;
+	    yyn++;
+	    break;
+
+	  case '"':
+	    if (yyres)
+	      yyres[yyn] = '\0';
+	    return yyn;
+	  }
+    do_not_strip_quotes: ;
+    }
+
+  if (! yyres)
+    return yystrlen (yystr);
+
+  return yystpcpy (yyres, yystr) - yyres;
+}
+# endif
+
+/* Copy into YYRESULT an error message about the unexpected token
+   YYCHAR while in state YYSTATE.  Return the number of bytes copied,
+   including the terminating null byte.  If YYRESULT is null, do not
+   copy anything; just return the number of bytes that would be
+   copied.  As a special case, return 0 if an ordinary "syntax error"
+   message will do.  Return YYSIZE_MAXIMUM if overflow occurs during
+   size calculation.  */
+static YYSIZE_T
+yysyntax_error (char *yyresult, int yystate, int yychar)
+{
+  int yyn = yypact[yystate];
+
+  if (! (YYPACT_NINF < yyn && yyn <= YYLAST))
+    return 0;
+  else
+    {
+      int yytype = YYTRANSLATE (yychar);
+      YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
+      YYSIZE_T yysize = yysize0;
+      YYSIZE_T yysize1;
+      int yysize_overflow = 0;
+      enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
+      char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
+      int yyx;
+
+# if 0
+      /* This is so xgettext sees the translatable formats that are
+	 constructed on the fly.  */
+      YY_("syntax error, unexpected %s");
+      YY_("syntax error, unexpected %s, expecting %s");
+      YY_("syntax error, unexpected %s, expecting %s or %s");
+      YY_("syntax error, unexpected %s, expecting %s or %s or %s");
+      YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
+# endif
+      char *yyfmt;
+      char const *yyf;
+      static char const yyunexpected[] = "syntax error, unexpected %s";
+      static char const yyexpecting[] = ", expecting %s";
+      static char const yyor[] = " or %s";
+      char yyformat[sizeof yyunexpected
+		    + sizeof yyexpecting - 1
+		    + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
+		       * (sizeof yyor - 1))];
+      char const *yyprefix = yyexpecting;
+
+      /* Start YYX at -YYN if negative to avoid negative indexes in
+	 YYCHECK.  */
+      int yyxbegin = yyn < 0 ? -yyn : 0;
+
+      /* Stay within bounds of both yycheck and yytname.  */
+      int yychecklim = YYLAST - yyn + 1;
+      int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+      int yycount = 1;
+
+      yyarg[0] = yytname[yytype];
+      yyfmt = yystpcpy (yyformat, yyunexpected);
+
+      for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+	if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+	  {
+	    if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+	      {
+		yycount = 1;
+		yysize = yysize0;
+		yyformat[sizeof yyunexpected - 1] = '\0';
+		break;
+	      }
+	    yyarg[yycount++] = yytname[yyx];
+	    yysize1 = yysize + yytnamerr (0, yytname[yyx]);
+	    yysize_overflow |= (yysize1 < yysize);
+	    yysize = yysize1;
+	    yyfmt = yystpcpy (yyfmt, yyprefix);
+	    yyprefix = yyor;
+	  }
+
+      yyf = YY_(yyformat);
+      yysize1 = yysize + yystrlen (yyf);
+      yysize_overflow |= (yysize1 < yysize);
+      yysize = yysize1;
+
+      if (yysize_overflow)
+	return YYSIZE_MAXIMUM;
+
+      if (yyresult)
+	{
+	  /* Avoid sprintf, as that infringes on the user's name space.
+	     Don't have undefined behavior even if the translation
+	     produced a string with the wrong number of "%s"s.  */
+	  char *yyp = yyresult;
+	  int yyi = 0;
+	  while ((*yyp = *yyf) != '\0')
+	    {
+	      if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
+		{
+		  yyp += yytnamerr (yyp, yyarg[yyi++]);
+		  yyf += 2;
+		}
+	      else
+		{
+		  yyp++;
+		  yyf++;
+		}
+	    }
+	}
+      return yysize;
+    }
+}
+#endif /* YYERROR_VERBOSE */
+

+
+/*-----------------------------------------------.
+| Release the memory associated to this symbol.  |
+`-----------------------------------------------*/
+
+/*ARGSUSED*/
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static void
+yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep)
+#else
+static void
+yydestruct (yymsg, yytype, yyvaluep)
+    const char *yymsg;
+    int yytype;
+    YYSTYPE *yyvaluep;
+#endif
+{
+  YYUSE (yyvaluep);
+
+  if (!yymsg)
+    yymsg = "Deleting";
+  YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
+
+  switch (yytype)
+    {
+
+      default:
+	break;
+    }
+}
+
+/* Prevent warnings from -Wmissing-prototypes.  */
+#ifdef YYPARSE_PARAM
+#if defined __STDC__ || defined __cplusplus
+int yyparse (void *YYPARSE_PARAM);
+#else
+int yyparse ();
+#endif
+#else /* ! YYPARSE_PARAM */
+#if defined __STDC__ || defined __cplusplus
+int yyparse (void);
+#else
+int yyparse ();
+#endif
+#endif /* ! YYPARSE_PARAM */
+
+
+
+
+
+/*-------------------------.
+| yyparse or yypush_parse.  |
+`-------------------------*/
+
+#ifdef YYPARSE_PARAM
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+int
+yyparse (void *YYPARSE_PARAM)
+#else
+int
+yyparse (YYPARSE_PARAM)
+    void *YYPARSE_PARAM;
+#endif
+#else /* ! YYPARSE_PARAM */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+int
+yyparse (void)
+#else
+int
+yyparse ()
+
+#endif
+#endif
+{
+/* The lookahead symbol.  */
+int yychar;
+
+/* The semantic value of the lookahead symbol.  */
+YYSTYPE yylval;
+
+    /* Number of syntax errors so far.  */
+    int yynerrs;
+
+    int yystate;
+    /* Number of tokens to shift before error messages enabled.  */
+    int yyerrstatus;
+
+    /* The stacks and their tools:
+       `yyss': related to states.
+       `yyvs': related to semantic values.
+
+       Refer to the stacks thru separate pointers, to allow yyoverflow
+       to reallocate them elsewhere.  */
+
+    /* The state stack.  */
+    yytype_int16 yyssa[YYINITDEPTH];
+    yytype_int16 *yyss;
+    yytype_int16 *yyssp;
+
+    /* The semantic value stack.  */
+    YYSTYPE yyvsa[YYINITDEPTH];
+    YYSTYPE *yyvs;
+    YYSTYPE *yyvsp;
+
+    YYSIZE_T yystacksize;
+
+  int yyn;
+  int yyresult;
+  /* Lookahead token as an internal (translated) token number.  */
+  int yytoken;
+  /* The variables used to return semantic value and location from the
+     action routines.  */
+  YYSTYPE yyval;
+
+#if YYERROR_VERBOSE
+  /* Buffer for error messages, and its allocated size.  */
+  char yymsgbuf[128];
+  char *yymsg = yymsgbuf;
+  YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
+#endif
+
+#define YYPOPSTACK(N)   (yyvsp -= (N), yyssp -= (N))
+
+  /* The number of symbols on the RHS of the reduced rule.
+     Keep to zero when no symbol should be popped.  */
+  int yylen = 0;
+
+  yytoken = 0;
+  yyss = yyssa;
+  yyvs = yyvsa;
+  yystacksize = YYINITDEPTH;
+
+  YYDPRINTF ((stderr, "Starting parse\n"));
+
+  yystate = 0;
+  yyerrstatus = 0;
+  yynerrs = 0;
+  yychar = YYEMPTY; /* Cause a token to be read.  */
+
+  /* Initialize stack pointers.
+     Waste one element of value and location stack
+     so that they stay on the same level as the state stack.
+     The wasted elements are never initialized.  */
+  yyssp = yyss;
+  yyvsp = yyvs;
+
+  goto yysetstate;
+
+/*------------------------------------------------------------.
+| yynewstate -- Push a new state, which is found in yystate.  |
+`------------------------------------------------------------*/
+ yynewstate:
+  /* In all cases, when you get here, the value and location stacks
+     have just been pushed.  So pushing a state here evens the stacks.  */
+  yyssp++;
+
+ yysetstate:
+  *yyssp = yystate;
+
+  if (yyss + yystacksize - 1 <= yyssp)
+    {
+      /* Get the current used size of the three stacks, in elements.  */
+      YYSIZE_T yysize = yyssp - yyss + 1;
+
+#ifdef yyoverflow
+      {
+	/* Give user a chance to reallocate the stack.  Use copies of
+	   these so that the &'s don't force the real ones into
+	   memory.  */
+	YYSTYPE *yyvs1 = yyvs;
+	yytype_int16 *yyss1 = yyss;
+
+	/* Each stack pointer address is followed by the size of the
+	   data in use in that stack, in bytes.  This used to be a
+	   conditional around just the two extra args, but that might
+	   be undefined if yyoverflow is a macro.  */
+	yyoverflow (YY_("memory exhausted"),
+		    &yyss1, yysize * sizeof (*yyssp),
+		    &yyvs1, yysize * sizeof (*yyvsp),
+		    &yystacksize);
+
+	yyss = yyss1;
+	yyvs = yyvs1;
+      }
+#else /* no yyoverflow */
+# ifndef YYSTACK_RELOCATE
+      goto yyexhaustedlab;
+# else
+      /* Extend the stack our own way.  */
+      if (YYMAXDEPTH <= yystacksize)
+	goto yyexhaustedlab;
+      yystacksize *= 2;
+      if (YYMAXDEPTH < yystacksize)
+	yystacksize = YYMAXDEPTH;
+
+      {
+	yytype_int16 *yyss1 = yyss;
+	union yyalloc *yyptr =
+	  (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
+	if (! yyptr)
+	  goto yyexhaustedlab;
+	YYSTACK_RELOCATE (yyss_alloc, yyss);
+	YYSTACK_RELOCATE (yyvs_alloc, yyvs);
+#  undef YYSTACK_RELOCATE
+	if (yyss1 != yyssa)
+	  YYSTACK_FREE (yyss1);
+      }
+# endif
+#endif /* no yyoverflow */
+
+      yyssp = yyss + yysize - 1;
+      yyvsp = yyvs + yysize - 1;
+
+      YYDPRINTF ((stderr, "Stack size increased to %lu\n",
+		  (unsigned long int) yystacksize));
+
+      if (yyss + yystacksize - 1 <= yyssp)
+	YYABORT;
+    }
+
+  YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+
+  if (yystate == YYFINAL)
+    YYACCEPT;
+
+  goto yybackup;
+
+/*-----------.
+| yybackup.  |
+`-----------*/
+yybackup:
+
+  /* Do appropriate processing given the current state.  Read a
+     lookahead token if we need one and don't already have one.  */
+
+  /* First try to decide what to do without reference to lookahead token.  */
+  yyn = yypact[yystate];
+  if (yyn == YYPACT_NINF)
+    goto yydefault;
+
+  /* Not known => get a lookahead token if don't already have one.  */
+
+  /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol.  */
+  if (yychar == YYEMPTY)
+    {
+      YYDPRINTF ((stderr, "Reading a token: "));
+      yychar = YYLEX;
+    }
+
+  if (yychar <= YYEOF)
+    {
+      yychar = yytoken = YYEOF;
+      YYDPRINTF ((stderr, "Now at end of input.\n"));
+    }
+  else
+    {
+      yytoken = YYTRANSLATE (yychar);
+      YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
+    }
+
+  /* If the proper action on seeing token YYTOKEN is to reduce or to
+     detect an error, take that action.  */
+  yyn += yytoken;
+  if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
+    goto yydefault;
+  yyn = yytable[yyn];
+  if (yyn <= 0)
+    {
+      if (yyn == 0 || yyn == YYTABLE_NINF)
+	goto yyerrlab;
+      yyn = -yyn;
+      goto yyreduce;
+    }
+
+  /* Count tokens shifted since error; after three, turn off error
+     status.  */
+  if (yyerrstatus)
+    yyerrstatus--;
+
+  /* Shift the lookahead token.  */
+  YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
+
+  /* Discard the shifted token.  */
+  yychar = YYEMPTY;
+
+  yystate = yyn;
+  *++yyvsp = yylval;
+
+  goto yynewstate;
+
+
+/*-----------------------------------------------------------.
+| yydefault -- do the default action for the current state.  |
+`-----------------------------------------------------------*/
+yydefault:
+  yyn = yydefact[yystate];
+  if (yyn == 0)
+    goto yyerrlab;
+  goto yyreduce;
+
+
+/*-----------------------------.
+| yyreduce -- Do a reduction.  |
+`-----------------------------*/
+yyreduce:
+  /* yyn is the number of a rule to reduce with.  */
+  yylen = yyr2[yyn];
+
+  /* If YYLEN is nonzero, implement the default value of the action:
+     `$$ = $1'.
+
+     Otherwise, the following line sets YYVAL to garbage.
+     This behavior is undocumented and Bison
+     users should not rely upon it.  Assigning to YYVAL
+     unconditionally makes the parser a bit smaller, and it avoids a
+     GCC warning that YYVAL may be used uninitialized.  */
+  yyval = yyvsp[1-yylen];
+
+
+  YY_REDUCE_PRINT (yyn);
+  switch (yyn)
+    {
+        case 3:
+
+/* Line 1464 of yacc.c  */
+#line 367 "grammar.y"
+    {
+            if (timerv)
+            {
+              writeTime("used time:");
+              startTimer();
+            }
+            if (rtimerv)
+            {
+              writeRTime("used real time:");
+              startRTimer();
+            }
+            prompt_char = '>';
+#ifdef HAVE_SDB
+            if (sdb_flags & 2) { sdb_flags=1; YYERROR; }
+#endif
+            if(siCntrlc)
+            {
+              WerrorS("abort...");
+              while((currentVoice!=NULL) && (currentVoice->prev!=NULL)) exitVoice();
+              if (currentVoice!=NULL) currentVoice->ifsw=0;
+            }
+            if (errorreported) /* also catches abort... */
+            {
+              yyerror("");
+            }
+            if (inerror==2) PrintLn();
+            errorreported = inerror = cmdtok = 0;
+            lastreserved = currid = NULL;
+            expected_parms = siCntrlc = FALSE;
+          ;}
+    break;
+
+  case 5:
+
+/* Line 1464 of yacc.c  */
+#line 402 "grammar.y"
+    {currentVoice->ifsw=0;;}
+    break;
+
+  case 6:
+
+/* Line 1464 of yacc.c  */
+#line 404 "grammar.y"
+    { (yyvsp[(1) - (2)].lv).CleanUp(); currentVoice->ifsw=0;;}
+    break;
+
+  case 7:
+
+/* Line 1464 of yacc.c  */
+#line 406 "grammar.y"
+    {
+            YYACCEPT;
+          ;}
+    break;
+
+  case 8:
+
+/* Line 1464 of yacc.c  */
+#line 410 "grammar.y"
+    {
+            currentVoice->ifsw=0;
+            iiDebug();
+          ;}
+    break;
+
+  case 9:
+
+/* Line 1464 of yacc.c  */
+#line 415 "grammar.y"
+    {currentVoice->ifsw=0;;}
+    break;
+
+  case 10:
+
+/* Line 1464 of yacc.c  */
+#line 417 "grammar.y"
+    {
+            #ifdef SIQ
+            siq=0;
+            #endif
+            yyInRingConstruction = FALSE;
+            currentVoice->ifsw=0;
+            if (inerror)
+            {
+/*  bison failed here*/
+              if ((inerror!=3) && ((yyvsp[(1) - (2)].i)<UMINUS) && ((yyvsp[(1) - (2)].i)>' '))
+              {
+                // 1: yyerror called
+                // 2: scanner put actual string
+                // 3: error rule put token+\n
+                inerror=3;
+                Print(" error at token `%s`\n",iiTwoOps((yyvsp[(1) - (2)].i)));
+              }
+/**/
+
+            }
+            if (!errorreported) WerrorS("...parse error");
+            yyerror("");
+            yyerrok;
+#ifdef HAVE_SDB
+            if ((sdb_flags & 1) && currentVoice->pi!=NULL)
+            {
+              currentVoice->pi->trace_flag |=1;
+            }
+            else
+#endif
+            if (myynest>0)
+            {
+              feBufferTypes t=currentVoice->Typ();
+              //PrintS("leaving yyparse\n");
+              exitBuffer(BT_proc);
+              if (t==BT_example)
+                YYACCEPT;
+              else
+                YYABORT;
+            }
+            else if (currentVoice->prev!=NULL)
+            {
+              exitVoice();
+            }
+#ifdef HAVE_SDB
+            if (sdb_flags &2) sdb_flags=1;
+#endif
+          ;}
+    break;
+
+  case 18:
+
+/* Line 1464 of yacc.c  */
+#line 475 "grammar.y"
+    {if (currentVoice!=NULL) currentVoice->ifsw=0;;}
+    break;
+
+  case 19:
+
+/* Line 1464 of yacc.c  */
+#line 478 "grammar.y"
+    { omFree((ADDRESS)(yyvsp[(2) - (2)].name)); ;}
+    break;
+
+  case 29:
+
+/* Line 1464 of yacc.c  */
+#line 493 "grammar.y"
+    {
+            if(iiAssign(&(yyvsp[(1) - (2)].lv),&(yyvsp[(2) - (2)].lv))) YYERROR;
+          ;}
+    break;
+
+  case 30:
+
+/* Line 1464 of yacc.c  */
+#line 500 "grammar.y"
+    {
+            if (currRing==NULL) MYYERROR("no ring active");
+            syMake(&(yyval.lv),omStrDup((yyvsp[(1) - (1)].name)));
+          ;}
+    break;
+
+  case 31:
+
+/* Line 1464 of yacc.c  */
+#line 505 "grammar.y"
+    {
+            syMake(&(yyval.lv),(yyvsp[(1) - (1)].name));
+          ;}
+    break;
+
+  case 32:
+
+/* Line 1464 of yacc.c  */
+#line 509 "grammar.y"
+    {
+            if(iiExprArith2(&(yyval.lv), &(yyvsp[(1) - (3)].lv), COLONCOLON, &(yyvsp[(3) - (3)].lv))) YYERROR;
+          ;}
+    break;
+
+  case 33:
+
+/* Line 1464 of yacc.c  */
+#line 513 "grammar.y"
+    {
+            if(iiExprArith2(&(yyval.lv), &(yyvsp[(1) - (3)].lv), '.', &(yyvsp[(3) - (3)].lv))) YYERROR;
+          ;}
+    break;
+
+  case 34:
+
+/* Line 1464 of yacc.c  */
+#line 517 "grammar.y"
+    {
+            if(iiExprArith1(&(yyval.lv),&(yyvsp[(1) - (3)].lv),'(')) YYERROR;
+          ;}
+    break;
+
+  case 35:
+
+/* Line 1464 of yacc.c  */
+#line 521 "grammar.y"
+    {
+            if ((yyvsp[(1) - (4)].lv).rtyp==UNKNOWN)
+            { // for x(i)(j)
+              if(iiExprArith2(&(yyval.lv),&(yyvsp[(1) - (4)].lv),'(',&(yyvsp[(3) - (4)].lv))) YYERROR;
+            }
+            else
+            {
+              (yyvsp[(1) - (4)].lv).next=(leftv)omAllocBin(sleftv_bin);
+              memcpy((yyvsp[(1) - (4)].lv).next,&(yyvsp[(3) - (4)].lv),sizeof(sleftv));
+              if(iiExprArithM(&(yyval.lv),&(yyvsp[(1) - (4)].lv),'(')) YYERROR;
+            }
+          ;}
+    break;
+
+  case 36:
+
+/* Line 1464 of yacc.c  */
+#line 534 "grammar.y"
+    {
+            if (currRingHdl==NULL) MYYERROR("no ring active");
+            int j = 0;
+            memset(&(yyval.lv),0,sizeof(sleftv));
+            (yyval.lv).rtyp=VECTOR_CMD;
+            leftv v = &(yyvsp[(2) - (3)].lv);
+            while (v!=NULL)
+            {
+              int i,t;
+              sleftv tmp;
+              memset(&tmp,0,sizeof(tmp));
+              i=iiTestConvert((t=v->Typ()),POLY_CMD);
+              if((i==0) || (iiConvert(t /*v->Typ()*/,POLY_CMD,i,v,&tmp)))
+              {
+                pDelete((poly *)&(yyval.lv).data);
+                (yyvsp[(2) - (3)].lv).CleanUp();
+                MYYERROR("expected '[poly,...'");
+              }
+              poly p = (poly)tmp.CopyD(POLY_CMD);
+              pSetCompP(p,++j);
+              (yyval.lv).data = (void *)pAdd((poly)(yyval.lv).data,p);
+              v->next=tmp.next;tmp.next=NULL;
+              tmp.CleanUp();
+              v=v->next;
+            }
+            (yyvsp[(2) - (3)].lv).CleanUp();
+          ;}
+    break;
+
+  case 37:
+
+/* Line 1464 of yacc.c  */
+#line 562 "grammar.y"
+    {
+            memset(&(yyval.lv),0,sizeof((yyval.lv)));
+            int i = atoi((yyvsp[(1) - (1)].name));
+            /*remember not to omFree($1)
+            *because it is a part of the scanner buffer*/
+            (yyval.lv).rtyp  = INT_CMD;
+            (yyval.lv).data = (void *)(long)i;
+
+            /* check: out of range input */
+            int l = strlen((yyvsp[(1) - (1)].name))+2;
+            number n;
+            if (l >= MAX_INT_LEN)
+            {
+              char tmp[MAX_INT_LEN+5];
+              sprintf(tmp,"%d",i);
+              if (strcmp(tmp,(yyvsp[(1) - (1)].name))!=0)
+              {
+                n_Read((yyvsp[(1) - (1)].name),&n,coeffs_BIGINT);
+                (yyval.lv).rtyp=BIGINT_CMD;
+                (yyval.lv).data = n;
+              }
+            }
+          ;}
+    break;
+
+  case 38:
+
+/* Line 1464 of yacc.c  */
+#line 586 "grammar.y"
+    {
+            memset(&(yyval.lv),0,sizeof((yyval.lv)));
+            (yyval.lv).rtyp = (yyvsp[(1) - (1)].i);
+            (yyval.lv).data = (yyval.lv).Data();
+          ;}
+    break;
+
+  case 39:
+
+/* Line 1464 of yacc.c  */
+#line 592 "grammar.y"
+    {
+            memset(&(yyval.lv),0,sizeof((yyval.lv)));
+            (yyval.lv).rtyp  = STRING_CMD;
+            (yyval.lv).data = (yyvsp[(1) - (1)].name);
+          ;}
+    break;
+
+  case 40:
+
+/* Line 1464 of yacc.c  */
+#line 598 "grammar.y"
+    {
+            if(iiExprArith1(&(yyval.lv),&(yyvsp[(3) - (4)].lv),(yyvsp[(1) - (4)].i))) YYERROR;
+          ;}
+    break;
+
+  case 41:
+
+/* Line 1464 of yacc.c  */
+#line 602 "grammar.y"
+    {
+            if(iiExprArith1(&(yyval.lv),&(yyvsp[(3) - (4)].lv),(yyvsp[(1) - (4)].i))) YYERROR;
+          ;}
+    break;
+
+  case 42:
+
+/* Line 1464 of yacc.c  */
+#line 606 "grammar.y"
+    {
+            if(iiExprArithM(&(yyval.lv),&(yyvsp[(3) - (4)].lv),(yyvsp[(1) - (4)].i))) YYERROR;
+          ;}
+    break;
+
+  case 43:
+
+/* Line 1464 of yacc.c  */
+#line 610 "grammar.y"
+    {
+            if(iiExprArithM(&(yyval.lv),NULL,(yyvsp[(1) - (3)].i))) YYERROR;
+          ;}
+    break;
+
+  case 44:
+
+/* Line 1464 of yacc.c  */
+#line 614 "grammar.y"
+    {
+            if(iiExprArith1(&(yyval.lv),&(yyvsp[(3) - (4)].lv),(yyvsp[(1) - (4)].i))) YYERROR;
+          ;}
+    break;
+
+  case 45:
+
+/* Line 1464 of yacc.c  */
+#line 618 "grammar.y"
+    {
+            if(iiExprArithM(&(yyval.lv),&(yyvsp[(3) - (4)].lv),(yyvsp[(1) - (4)].i))) YYERROR;
+          ;}
+    break;
+
+  case 46:
+
+/* Line 1464 of yacc.c  */
+#line 622 "grammar.y"
+    {
+            if(iiExprArithM(&(yyval.lv),NULL,(yyvsp[(1) - (3)].i))) YYERROR;
+          ;}
+    break;
+
+  case 47:
+
+/* Line 1464 of yacc.c  */
+#line 626 "grammar.y"
+    {
+            if(iiExprArith1(&(yyval.lv),&(yyvsp[(3) - (4)].lv),(yyvsp[(1) - (4)].i))) YYERROR;
+          ;}
+    break;
+
+  case 48:
+
+/* Line 1464 of yacc.c  */
+#line 630 "grammar.y"
+    {
+            if(iiExprArith1(&(yyval.lv),&(yyvsp[(3) - (4)].lv),(yyvsp[(1) - (4)].i))) YYERROR;
+          ;}
+    break;
+
+  case 49:
+
+/* Line 1464 of yacc.c  */
+#line 634 "grammar.y"
+    {
+            if(iiExprArith1(&(yyval.lv),&(yyvsp[(3) - (4)].lv),(yyvsp[(1) - (4)].i))) YYERROR;
+          ;}
+    break;
+
+  case 50:
+
+/* Line 1464 of yacc.c  */
+#line 638 "grammar.y"
+    {
+            if(iiExprArith1(&(yyval.lv),&(yyvsp[(3) - (4)].lv),(yyvsp[(1) - (4)].i))) YYERROR;
+          ;}
+    break;
+
+  case 51:
+
+/* Line 1464 of yacc.c  */
+#line 642 "grammar.y"
+    {
+            if(iiExprArith2(&(yyval.lv),&(yyvsp[(3) - (6)].lv),(yyvsp[(1) - (6)].i),&(yyvsp[(5) - (6)].lv),TRUE)) YYERROR;
+          ;}
+    break;
+
+  case 52:
+
+/* Line 1464 of yacc.c  */
+#line 646 "grammar.y"
+    {
+            if(iiExprArith2(&(yyval.lv),&(yyvsp[(3) - (6)].lv),(yyvsp[(1) - (6)].i),&(yyvsp[(5) - (6)].lv),TRUE)) YYERROR;
+          ;}
+    break;
+
+  case 53:
+
+/* Line 1464 of yacc.c  */
+#line 650 "grammar.y"
+    {
+            if(iiExprArith2(&(yyval.lv),&(yyvsp[(3) - (6)].lv),(yyvsp[(1) - (6)].i),&(yyvsp[(5) - (6)].lv),TRUE)) YYERROR;
+          ;}
+    break;
+
+  case 54:
+
+/* Line 1464 of yacc.c  */
+#line 654 "grammar.y"
+    {
+            if(iiExprArith2(&(yyval.lv),&(yyvsp[(3) - (6)].lv),(yyvsp[(1) - (6)].i),&(yyvsp[(5) - (6)].lv),TRUE)) YYERROR;
+          ;}
+    break;
+
+  case 55:
+
+/* Line 1464 of yacc.c  */
+#line 658 "grammar.y"
+    {
+            if(iiExprArith3(&(yyval.lv),(yyvsp[(1) - (8)].i),&(yyvsp[(3) - (8)].lv),&(yyvsp[(5) - (8)].lv),&(yyvsp[(7) - (8)].lv))) YYERROR;
+          ;}
+    break;
+
+  case 56:
+
+/* Line 1464 of yacc.c  */
+#line 662 "grammar.y"
+    {
+            if(iiExprArith3(&(yyval.lv),(yyvsp[(1) - (8)].i),&(yyvsp[(3) - (8)].lv),&(yyvsp[(5) - (8)].lv),&(yyvsp[(7) - (8)].lv))) YYERROR;
+          ;}
+    break;
+
+  case 57:
+
+/* Line 1464 of yacc.c  */
+#line 666 "grammar.y"
+    {
+            if(iiExprArith3(&(yyval.lv),(yyvsp[(1) - (8)].i),&(yyvsp[(3) - (8)].lv),&(yyvsp[(5) - (8)].lv),&(yyvsp[(7) - (8)].lv))) YYERROR;
+          ;}
+    break;
+
+  case 58:
+
+/* Line 1464 of yacc.c  */
+#line 670 "grammar.y"
+    {
+            if(iiExprArith3(&(yyval.lv),(yyvsp[(1) - (8)].i),&(yyvsp[(3) - (8)].lv),&(yyvsp[(5) - (8)].lv),&(yyvsp[(7) - (8)].lv))) YYERROR;
+          ;}
+    break;
+
+  case 59:
+
+/* Line 1464 of yacc.c  */
+#line 674 "grammar.y"
+    {
+            if(iiExprArithM(&(yyval.lv),NULL,(yyvsp[(1) - (3)].i))) YYERROR;
+          ;}
+    break;
+
+  case 60:
+
+/* Line 1464 of yacc.c  */
+#line 678 "grammar.y"
+    {
+            int b=iiExprArithM(&(yyval.lv),&(yyvsp[(3) - (4)].lv),(yyvsp[(1) - (4)].i)); // handle branchTo
+            if (b==TRUE) YYERROR;
+            if (b==2) YYACCEPT;
+          ;}
+    break;
+
+  case 61:
+
+/* Line 1464 of yacc.c  */
+#line 684 "grammar.y"
+    {
+            if(iiExprArith3(&(yyval.lv),(yyvsp[(1) - (8)].i),&(yyvsp[(3) - (8)].lv),&(yyvsp[(5) - (8)].lv),&(yyvsp[(7) - (8)].lv))) YYERROR;
+          ;}
+    break;
+
+  case 62:
+
+/* Line 1464 of yacc.c  */
+#line 688 "grammar.y"
+    {
+            if(iiExprArith1(&(yyval.lv),&(yyvsp[(3) - (4)].lv),(yyvsp[(1) - (4)].i))) YYERROR;
+          ;}
+    break;
+
+  case 63:
+
+/* Line 1464 of yacc.c  */
+#line 692 "grammar.y"
+    {
+            if(iiExprArith3(&(yyval.lv),RING_CMD,&(yyvsp[(3) - (8)].lv),&(yyvsp[(5) - (8)].lv),&(yyvsp[(7) - (8)].lv))) YYERROR;
+          ;}
+    break;
+
+  case 64:
+
+/* Line 1464 of yacc.c  */
+#line 696 "grammar.y"
+    {
+            if(iiExprArith1(&(yyval.lv),&(yyvsp[(3) - (4)].lv),RING_CMD)) YYERROR;
+          ;}
+    break;
+
+  case 65:
+
+/* Line 1464 of yacc.c  */
+#line 700 "grammar.y"
+    {
+            if (iiARROW(&(yyval.lv),(yyvsp[(1) - (3)].name),(yyvsp[(3) - (3)].name))) YYERROR;
+          ;}
+    break;
+
+  case 66:
+
+/* Line 1464 of yacc.c  */
+#line 707 "grammar.y"
+    {
+            leftv v = &(yyvsp[(1) - (3)].lv);
+            while (v->next!=NULL)
+            {
+              v=v->next;
+            }
+            v->next = (leftv)omAllocBin(sleftv_bin);
+            memcpy(v->next,&((yyvsp[(3) - (3)].lv)),sizeof(sleftv));
+            (yyval.lv) = (yyvsp[(1) - (3)].lv);
+          ;}
+    break;
+
+  case 67:
+
+/* Line 1464 of yacc.c  */
+#line 718 "grammar.y"
+    {
+            (yyval.lv) = (yyvsp[(1) - (1)].lv);
+          ;}
+    break;
+
+  case 68:
+
+/* Line 1464 of yacc.c  */
+#line 724 "grammar.y"
+    {
+            /*if ($1.typ == eunknown) YYERROR;*/
+            (yyval.lv) = (yyvsp[(1) - (1)].lv);
+          ;}
+    break;
+
+  case 69:
+
+/* Line 1464 of yacc.c  */
+#line 728 "grammar.y"
+    { (yyval.lv) = (yyvsp[(1) - (1)].lv); ;}
+    break;
+
+  case 70:
+
+/* Line 1464 of yacc.c  */
+#line 729 "grammar.y"
+    { (yyval.lv) = (yyvsp[(2) - (3)].lv); ;}
+    break;
+
+  case 71:
+
+/* Line 1464 of yacc.c  */
+#line 731 "grammar.y"
+    {
+            if(iiExprArith3(&(yyval.lv),'[',&(yyvsp[(1) - (6)].lv),&(yyvsp[(3) - (6)].lv),&(yyvsp[(5) - (6)].lv))) YYERROR;
+          ;}
+    break;
+
+  case 72:
+
+/* Line 1464 of yacc.c  */
+#line 735 "grammar.y"
+    {
+            if(iiExprArith2(&(yyval.lv),&(yyvsp[(1) - (4)].lv),'[',&(yyvsp[(3) - (4)].lv))) YYERROR;
+          ;}
+    break;
+
+  case 73:
+
+/* Line 1464 of yacc.c  */
+#line 739 "grammar.y"
+    {
+            if (iiApply(&(yyval.lv), &(yyvsp[(3) - (6)].lv), (yyvsp[(5) - (6)].i), NULL)) YYERROR;
+          ;}
+    break;
+
+  case 74:
+
+/* Line 1464 of yacc.c  */
+#line 743 "grammar.y"
+    {
+            if (iiApply(&(yyval.lv), &(yyvsp[(3) - (6)].lv), (yyvsp[(5) - (6)].i), NULL)) YYERROR;
+          ;}
+    break;
+
+  case 75:
+
+/* Line 1464 of yacc.c  */
+#line 747 "grammar.y"
+    {
+            if (iiApply(&(yyval.lv), &(yyvsp[(3) - (6)].lv), (yyvsp[(5) - (6)].i), NULL)) YYERROR;
+          ;}
+    break;
+
+  case 76:
+
+/* Line 1464 of yacc.c  */
+#line 751 "grammar.y"
+    {
+            if (iiApply(&(yyval.lv), &(yyvsp[(3) - (6)].lv), (yyvsp[(5) - (6)].i), NULL)) YYERROR;
+          ;}
+    break;
+
+  case 77:
+
+/* Line 1464 of yacc.c  */
+#line 755 "grammar.y"
+    {
+            if (iiApply(&(yyval.lv), &(yyvsp[(3) - (6)].lv), (yyvsp[(5) - (6)].i), NULL)) YYERROR;
+          ;}
+    break;
+
+  case 78:
+
+/* Line 1464 of yacc.c  */
+#line 759 "grammar.y"
+    {
+            if (iiApply(&(yyval.lv), &(yyvsp[(3) - (6)].lv), 0, &(yyvsp[(5) - (6)].lv))) YYERROR;
+          ;}
+    break;
+
+  case 79:
+
+/* Line 1464 of yacc.c  */
+#line 763 "grammar.y"
+    {
+            (yyval.lv)=(yyvsp[(2) - (3)].lv);
+          ;}
+    break;
+
+  case 80:
+
+/* Line 1464 of yacc.c  */
+#line 767 "grammar.y"
+    {
+            #ifdef SIQ
+            siq++;
+            if (siq>0)
+            { if (iiExprArith2(&(yyval.lv),&(yyvsp[(2) - (5)].lv),'=',&(yyvsp[(4) - (5)].lv))) YYERROR; }
+            else
+            #endif
+            {
+              memset(&(yyval.lv),0,sizeof((yyval.lv)));
+              (yyval.lv).rtyp=NONE;
+              if (iiAssign(&(yyvsp[(2) - (5)].lv),&(yyvsp[(4) - (5)].lv))) YYERROR;
+            }
+            #ifdef SIQ
+            siq--;
+            #endif
+          ;}
+    break;
+
+  case 81:
+
+/* Line 1464 of yacc.c  */
+#line 784 "grammar.y"
+    {
+            iiTestAssume(&(yyvsp[(2) - (5)].lv),&(yyvsp[(4) - (5)].lv));
+            memset(&(yyval.lv),0,sizeof((yyval.lv)));
+            (yyval.lv).rtyp=NONE;
+          ;}
+    break;
+
+  case 82:
+
+/* Line 1464 of yacc.c  */
+#line 790 "grammar.y"
+    {
+            #ifdef SIQ
+            siq--;
+            #endif
+          ;}
+    break;
+
+  case 83:
+
+/* Line 1464 of yacc.c  */
+#line 796 "grammar.y"
+    {
+            #ifdef SIQ
+            if (siq<=0) (yyvsp[(4) - (5)].lv).Eval();
+            #endif
+            (yyval.lv)=(yyvsp[(4) - (5)].lv);
+            #ifdef SIQ
+            siq++;
+            #endif
+          ;}
+    break;
+
+  case 84:
+
+/* Line 1464 of yacc.c  */
+#line 808 "grammar.y"
+    {
+            #ifdef SIQ
+            siq++;
+            #endif
+          ;}
+    break;
+
+  case 85:
+
+/* Line 1464 of yacc.c  */
+#line 816 "grammar.y"
+    {
+            #ifdef SIQ
+            siq++;
+            #endif
+          ;}
+    break;
+
+  case 86:
+
+/* Line 1464 of yacc.c  */
+#line 824 "grammar.y"
+    {
+            #ifdef SIQ
+            siq--;
+            #endif
+          ;}
+    break;
+
+  case 87:
+
+/* Line 1464 of yacc.c  */
+#line 833 "grammar.y"
+    {
+            if(iiExprArith1(&(yyval.lv),&(yyvsp[(1) - (2)].lv),PLUSPLUS)) YYERROR;
+          ;}
+    break;
+
+  case 88:
+
+/* Line 1464 of yacc.c  */
+#line 837 "grammar.y"
+    {
+            if(iiExprArith1(&(yyval.lv),&(yyvsp[(1) - (2)].lv),MINUSMINUS)) YYERROR;
+          ;}
+    break;
+
+  case 89:
+
+/* Line 1464 of yacc.c  */
+#line 841 "grammar.y"
+    {
+            if(iiExprArith2(&(yyval.lv),&(yyvsp[(1) - (3)].lv),'+',&(yyvsp[(3) - (3)].lv))) YYERROR;
+          ;}
+    break;
+
+  case 90:
+
+/* Line 1464 of yacc.c  */
+#line 845 "grammar.y"
+    {
+            if(iiExprArith2(&(yyval.lv),&(yyvsp[(1) - (3)].lv),'-',&(yyvsp[(3) - (3)].lv))) YYERROR;
+          ;}
+    break;
+
+  case 91:
+
+/* Line 1464 of yacc.c  */
+#line 849 "grammar.y"
+    {
+            if(iiExprArith2(&(yyval.lv),&(yyvsp[(1) - (3)].lv),(yyvsp[(2) - (3)].i),&(yyvsp[(3) - (3)].lv))) YYERROR;
+          ;}
+    break;
+
+  case 92:
+
+/* Line 1464 of yacc.c  */
+#line 853 "grammar.y"
+    {
+            if(iiExprArith2(&(yyval.lv),&(yyvsp[(1) - (3)].lv),'^',&(yyvsp[(3) - (3)].lv))) YYERROR;
+          ;}
+    break;
+
+  case 93:
+
+/* Line 1464 of yacc.c  */
+#line 857 "grammar.y"
+    {
+            if(iiExprArith2(&(yyval.lv),&(yyvsp[(1) - (3)].lv),(yyvsp[(2) - (3)].i),&(yyvsp[(3) - (3)].lv))) YYERROR;
+          ;}
+    break;
+
+  case 94:
+
+/* Line 1464 of yacc.c  */
+#line 861 "grammar.y"
+    {
+            if(iiExprArith2(&(yyval.lv),&(yyvsp[(1) - (3)].lv),(yyvsp[(2) - (3)].i),&(yyvsp[(3) - (3)].lv))) YYERROR;
+          ;}
+    break;
+
+  case 95:
+
+/* Line 1464 of yacc.c  */
+#line 865 "grammar.y"
+    {
+            if(iiExprArith2(&(yyval.lv),&(yyvsp[(1) - (3)].lv),NOTEQUAL,&(yyvsp[(3) - (3)].lv))) YYERROR;
+          ;}
+    break;
+
+  case 96:
+
+/* Line 1464 of yacc.c  */
+#line 869 "grammar.y"
+    {
+            if(iiExprArith2(&(yyval.lv),&(yyvsp[(1) - (3)].lv),EQUAL_EQUAL,&(yyvsp[(3) - (3)].lv))) YYERROR;
+          ;}
+    break;
+
+  case 97:
+
+/* Line 1464 of yacc.c  */
+#line 873 "grammar.y"
+    {
+            if(iiExprArith2(&(yyval.lv),&(yyvsp[(1) - (3)].lv),DOTDOT,&(yyvsp[(3) - (3)].lv))) YYERROR;
+          ;}
+    break;
+
+  case 98:
+
+/* Line 1464 of yacc.c  */
+#line 877 "grammar.y"
+    {
+            if(iiExprArith2(&(yyval.lv),&(yyvsp[(1) - (3)].lv),':',&(yyvsp[(3) - (3)].lv))) YYERROR;
+          ;}
+    break;
+
+  case 99:
+
+/* Line 1464 of yacc.c  */
+#line 881 "grammar.y"
+    {
+            if (siq>0)
+            { if (iiExprArith1(&(yyval.lv),&(yyvsp[(2) - (2)].lv),NOT)) YYERROR; }
+            else
+            {
+              memset(&(yyval.lv),0,sizeof((yyval.lv)));
+              int i; TESTSETINT((yyvsp[(2) - (2)].lv),i);
+              (yyval.lv).rtyp  = INT_CMD;
+              (yyval.lv).data = (void *)(long)(i == 0 ? 1 : 0);
+            }
+          ;}
+    break;
+
+  case 100:
+
+/* Line 1464 of yacc.c  */
+#line 893 "grammar.y"
+    {
+            if(iiExprArith1(&(yyval.lv),&(yyvsp[(2) - (2)].lv),'-')) YYERROR;
+          ;}
+    break;
+
+  case 101:
+
+/* Line 1464 of yacc.c  */
+#line 899 "grammar.y"
+    { (yyval.lv) = (yyvsp[(1) - (2)].lv); ;}
+    break;
+
+  case 102:
+
+/* Line 1464 of yacc.c  */
+#line 901 "grammar.y"
+    {
+            if ((yyvsp[(1) - (2)].lv).rtyp==0)
+            {
+              Werror("`%s` is undefined",(yyvsp[(1) - (2)].lv).Fullname());
+              YYERROR;
+            }
+            else if (((yyvsp[(1) - (2)].lv).rtyp==MODUL_CMD)
+            // matrix m; m[2]=...
+            && ((yyvsp[(1) - (2)].lv).e!=NULL) && ((yyvsp[(1) - (2)].lv).e->next==NULL))
+            {
+              MYYERROR("matrix must have 2 indices");
+            }
+            (yyval.lv) = (yyvsp[(1) - (2)].lv);
+          ;}
+    break;
+
+  case 104:
+
+/* Line 1464 of yacc.c  */
+#line 921 "grammar.y"
+    {
+            if ((yyvsp[(2) - (3)].lv).Typ()!=STRING_CMD)
+            {
+              MYYERROR("string expression expected");
+            }
+            (yyval.name) = (char *)(yyvsp[(2) - (3)].lv).CopyD(STRING_CMD);
+            (yyvsp[(2) - (3)].lv).CleanUp();
+          ;}
+    break;
+
+  case 105:
+
+/* Line 1464 of yacc.c  */
+#line 933 "grammar.y"
+    {
+            if (iiDeclCommand(&(yyval.lv),&(yyvsp[(2) - (2)].lv),myynest,(yyvsp[(1) - (2)].i),&((yyvsp[(2) - (2)].lv).req_packhdl->idroot)))
+              YYERROR;
+          ;}
+    break;
+
+  case 106:
+
+/* Line 1464 of yacc.c  */
+#line 938 "grammar.y"
+    {
+            if (iiDeclCommand(&(yyval.lv),&(yyvsp[(2) - (2)].lv),myynest,(yyvsp[(1) - (2)].i),&((yyvsp[(2) - (2)].lv).req_packhdl->idroot)))
+              YYERROR;
+          ;}
+    break;
+
+  case 107:
+
+/* Line 1464 of yacc.c  */
+#line 943 "grammar.y"
+    {
+            if (iiDeclCommand(&(yyval.lv),&(yyvsp[(2) - (2)].lv),myynest,(yyvsp[(1) - (2)].i),&(currRing->idroot), TRUE)) YYERROR;
+          ;}
+    break;
+
+  case 108:
+
+/* Line 1464 of yacc.c  */
+#line 947 "grammar.y"
+    {
+            if (iiDeclCommand(&(yyval.lv),&(yyvsp[(2) - (2)].lv),myynest,(yyvsp[(1) - (2)].i),&(currRing->idroot), TRUE)) YYERROR;
+          ;}
+    break;
+
+  case 109:
+
+/* Line 1464 of yacc.c  */
+#line 951 "grammar.y"
+    {
+            int r; TESTSETINT((yyvsp[(4) - (8)].lv),r);
+            int c; TESTSETINT((yyvsp[(7) - (8)].lv),c);
+            if (r < 1)
+              MYYERROR("rows must be greater than 0");
+            if (c < 0)
+              MYYERROR("cols must be greater than -1");
+            leftv v;
+            idhdl h;
+            if ((yyvsp[(1) - (8)].i) == MATRIX_CMD)
+            {
+              if (iiDeclCommand(&(yyval.lv),&(yyvsp[(2) - (8)].lv),myynest,(yyvsp[(1) - (8)].i),&(currRing->idroot), TRUE)) YYERROR;
+              v=&(yyval.lv);
+              h=(idhdl)v->data;
+              idDelete(&IDIDEAL(h));
+              IDMATRIX(h) = mpNew(r,c);
+              if (IDMATRIX(h)==NULL) YYERROR;
+            }
+            else if ((yyvsp[(1) - (8)].i) == INTMAT_CMD)
+            {
+              if (iiDeclCommand(&(yyval.lv),&(yyvsp[(2) - (8)].lv),myynest,(yyvsp[(1) - (8)].i),&((yyvsp[(2) - (8)].lv).req_packhdl->idroot)))
+                YYERROR;
+              v=&(yyval.lv);
+              h=(idhdl)v->data;
+              delete IDINTVEC(h);
+              IDINTVEC(h) = new intvec(r,c,0);
+              if (IDINTVEC(h)==NULL) YYERROR;
+            }
+            else /* BIGINTMAT_CMD */
+            {
+              if (iiDeclCommand(&(yyval.lv),&(yyvsp[(2) - (8)].lv),myynest,(yyvsp[(1) - (8)].i),&((yyvsp[(2) - (8)].lv).req_packhdl->idroot)))
+                YYERROR;
+              v=&(yyval.lv);
+              h=(idhdl)v->data;
+              delete IDBIMAT(h);
+              IDBIMAT(h) = new bigintmat(r, c, coeffs_BIGINT);
+              if (IDBIMAT(h)==NULL) YYERROR;
+            }
+          ;}
+    break;
+
+  case 110:
+
+/* Line 1464 of yacc.c  */
+#line 991 "grammar.y"
+    {
+            if ((yyvsp[(1) - (2)].i) == MATRIX_CMD)
+            {
+              if (iiDeclCommand(&(yyval.lv),&(yyvsp[(2) - (2)].lv),myynest,(yyvsp[(1) - (2)].i),&(currRing->idroot), TRUE)) YYERROR;
+            }
+            else if ((yyvsp[(1) - (2)].i) == INTMAT_CMD)
+            {
+              if (iiDeclCommand(&(yyval.lv),&(yyvsp[(2) - (2)].lv),myynest,(yyvsp[(1) - (2)].i),&((yyvsp[(2) - (2)].lv).req_packhdl->idroot)))
+                YYERROR;
+              leftv v=&(yyval.lv);
+              idhdl h;
+              do
+              {
+                 h=(idhdl)v->data;
+                 delete IDINTVEC(h);
+                 IDINTVEC(h) = new intvec(1,1,0);
+                 v=v->next;
+              } while (v!=NULL);
+            }
+            else /* BIGINTMAT_CMD */
+            {
+              if (iiDeclCommand(&(yyval.lv),&(yyvsp[(2) - (2)].lv),myynest,(yyvsp[(1) - (2)].i),&((yyvsp[(2) - (2)].lv).req_packhdl->idroot)))
+                YYERROR;
+            }
+          ;}
+    break;
+
+  case 111:
+
+/* Line 1464 of yacc.c  */
+#line 1017 "grammar.y"
+    {
+            int t=(yyvsp[(1) - (3)].lv).Typ();
+            sleftv r;
+            memset(&r,0,sizeof(sleftv));
+            if ((BEGIN_RING<t) && (t<END_RING))
+            {
+              if (iiDeclCommand(&r,&(yyvsp[(3) - (3)].lv),myynest,t,&(currRing->idroot), TRUE))
+                YYERROR;
+            }
+            else
+            {
+              if (iiDeclCommand(&r,&(yyvsp[(3) - (3)].lv),myynest,t,&((yyvsp[(3) - (3)].lv).req_packhdl->idroot)))
+                YYERROR;
+            }
+            leftv v=&(yyvsp[(1) - (3)].lv);
+            while (v->next!=NULL) v=v->next;
+            v->next=(leftv)omAllocBin(sleftv_bin);
+            memcpy(v->next,&r,sizeof(sleftv));
+            (yyval.lv)=(yyvsp[(1) - (3)].lv);
+          ;}
+    break;
+
+  case 112:
+
+/* Line 1464 of yacc.c  */
+#line 1038 "grammar.y"
+    {
+            if (iiDeclCommand(&(yyval.lv),&(yyvsp[(2) - (2)].lv),myynest,(yyvsp[(1) - (2)].i),&((yyvsp[(2) - (2)].lv).req_packhdl->idroot)))
+              YYERROR;
+          ;}
+    break;
+
+  case 115:
+
+/* Line 1464 of yacc.c  */
+#line 1051 "grammar.y"
+    {
+            leftv v = &(yyvsp[(2) - (5)].lv);
+            while (v->next!=NULL)
+            {
+              v=v->next;
+            }
+            v->next = (leftv)omAllocBin(sleftv_bin);
+            memcpy(v->next,&((yyvsp[(4) - (5)].lv)),sizeof(sleftv));
+            (yyval.lv) = (yyvsp[(2) - (5)].lv);
+          ;}
+    break;
+
+  case 116:
+
+/* Line 1464 of yacc.c  */
+#line 1065 "grammar.y"
+    {
+          // let rInit take care of any errors
+          (yyval.i)=rOrderName((yyvsp[(1) - (1)].name));
+        ;}
+    break;
+
+  case 117:
+
+/* Line 1464 of yacc.c  */
+#line 1073 "grammar.y"
+    {
+            memset(&(yyval.lv),0,sizeof((yyval.lv)));
+            intvec *iv = new intvec(2);
+            (*iv)[0] = 1;
+            (*iv)[1] = (yyvsp[(1) - (1)].i);
+            (yyval.lv).rtyp = INTVEC_CMD;
+            (yyval.lv).data = (void *)iv;
+          ;}
+    break;
+
+  case 118:
+
+/* Line 1464 of yacc.c  */
+#line 1082 "grammar.y"
+    {
+            memset(&(yyval.lv),0,sizeof((yyval.lv)));
+            leftv sl = &(yyvsp[(3) - (4)].lv);
+            int slLength;
+            {
+              slLength =  exprlist_length(sl);
+              int l = 2 +  slLength;
+              intvec *iv = new intvec(l);
+              (*iv)[0] = slLength;
+              (*iv)[1] = (yyvsp[(1) - (4)].i);
+
+              int i = 2;
+              while ((i<l) && (sl!=NULL))
+              {
+                if (sl->Typ() == INT_CMD)
+                {
+                  (*iv)[i++] = (int)((long)(sl->Data()));
+                }
+                else if ((sl->Typ() == INTVEC_CMD)
+                ||(sl->Typ() == INTMAT_CMD))
+                {
+                  intvec *ivv = (intvec *)(sl->Data());
+                  int ll = 0,l = ivv->length();
+                  for (; l>0; l--)
+                  {
+                    (*iv)[i++] = (*ivv)[ll++];
+                  }
+                }
+                else
+                {
+                  delete iv;
+                  (yyvsp[(3) - (4)].lv).CleanUp();
+                  MYYERROR("wrong type in ordering");
+                }
+                sl = sl->next;
+              }
+              (yyval.lv).rtyp = INTVEC_CMD;
+              (yyval.lv).data = (void *)iv;
+            }
+            (yyvsp[(3) - (4)].lv).CleanUp();
+          ;}
+    break;
+
+  case 120:
+
+/* Line 1464 of yacc.c  */
+#line 1128 "grammar.y"
+    {
+            (yyval.lv) = (yyvsp[(1) - (3)].lv);
+            (yyval.lv).next = (sleftv *)omAllocBin(sleftv_bin);
+            memcpy((yyval.lv).next,&(yyvsp[(3) - (3)].lv),sizeof(sleftv));
+          ;}
+    break;
+
+  case 122:
+
+/* Line 1464 of yacc.c  */
+#line 1138 "grammar.y"
+    {
+            (yyval.lv) = (yyvsp[(2) - (3)].lv);
+          ;}
+    break;
+
+  case 123:
+
+/* Line 1464 of yacc.c  */
+#line 1144 "grammar.y"
+    {
+            expected_parms = TRUE;
+          ;}
+    break;
+
+  case 124:
+
+/* Line 1464 of yacc.c  */
+#line 1151 "grammar.y"
+    { (yyval.i) = (yyvsp[(1) - (1)].i); ;}
+    break;
+
+  case 125:
+
+/* Line 1464 of yacc.c  */
+#line 1153 "grammar.y"
+    { (yyval.i) = (yyvsp[(1) - (1)].i); ;}
+    break;
+
+  case 126:
+
+/* Line 1464 of yacc.c  */
+#line 1155 "grammar.y"
+    { (yyval.i) = (yyvsp[(1) - (1)].i); ;}
+    break;
+
+  case 127:
+
+/* Line 1464 of yacc.c  */
+#line 1164 "grammar.y"
+    { if ((yyvsp[(1) - (2)].i) != '<') YYERROR;
+            if((feFilePending=feFopen((yyvsp[(2) - (2)].name),"r",NULL,TRUE))==NULL) YYERROR; ;}
+    break;
+
+  case 128:
+
+/* Line 1464 of yacc.c  */
+#line 1167 "grammar.y"
+    { newFile((yyvsp[(2) - (4)].name),feFilePending); ;}
+    break;
+
+  case 129:
+
+/* Line 1464 of yacc.c  */
+#line 1172 "grammar.y"
+    {
+            feHelp((yyvsp[(2) - (3)].name));
+            omFree((ADDRESS)(yyvsp[(2) - (3)].name));
+          ;}
+    break;
+
+  case 130:
+
+/* Line 1464 of yacc.c  */
+#line 1177 "grammar.y"
+    {
+            feHelp(NULL);
+          ;}
+    break;
+
+  case 131:
+
+/* Line 1464 of yacc.c  */
+#line 1184 "grammar.y"
+    {
+            singular_example((yyvsp[(2) - (3)].name));
+            omFree((ADDRESS)(yyvsp[(2) - (3)].name));
+          ;}
+    break;
+
+  case 132:
+
+/* Line 1464 of yacc.c  */
+#line 1192 "grammar.y"
+    {
+          if (basePack!=(yyvsp[(2) - (2)].lv).req_packhdl)
+          {
+            if(iiExport(&(yyvsp[(2) - (2)].lv),0,currPack)) YYERROR;
+          }
+          else
+            if (iiExport(&(yyvsp[(2) - (2)].lv),0)) YYERROR;
+        ;}
+    break;
+
+  case 133:
+
+/* Line 1464 of yacc.c  */
+#line 1204 "grammar.y"
+    {
+          leftv v=&(yyvsp[(2) - (2)].lv);
+          if (v->rtyp!=IDHDL)
+          {
+            if (v->name!=NULL)
+            {
+               Werror("`%s` is undefined in kill",v->name);
+            }
+            else               WerrorS("kill what ?");
+          }
+          else
+          {
+            killhdl((idhdl)v->data,v->req_packhdl);
+          }
+        ;}
+    break;
+
+  case 134:
+
+/* Line 1464 of yacc.c  */
+#line 1220 "grammar.y"
+    {
+          leftv v=&(yyvsp[(3) - (3)].lv);
+          if (v->rtyp!=IDHDL)
+          {
+            if (v->name!=NULL)
+            {
+               Werror("`%s` is undefined in kill",v->name);
+            }
+            else               WerrorS("kill what ?");
+          }
+          else
+          {
+            killhdl((idhdl)v->data,v->req_packhdl);
+          }
+        ;}
+    break;
+
+  case 135:
+
+/* Line 1464 of yacc.c  */
+#line 1239 "grammar.y"
+    {
+            list_cmd((yyvsp[(3) - (4)].i),NULL,"// ",TRUE);
+          ;}
+    break;
+
+  case 136:
+
+/* Line 1464 of yacc.c  */
+#line 1243 "grammar.y"
+    {
+            list_cmd((yyvsp[(3) - (4)].i),NULL,"// ",TRUE);
+          ;}
+    break;
+
+  case 137:
+
+/* Line 1464 of yacc.c  */
+#line 1247 "grammar.y"
+    {
+            if ((yyvsp[(3) - (4)].i)==QRING_CMD) (yyvsp[(3) - (4)].i)=RING_CMD;
+            list_cmd((yyvsp[(3) - (4)].i),NULL,"// ",TRUE);
+          ;}
+    break;
+
+  case 138:
+
+/* Line 1464 of yacc.c  */
+#line 1252 "grammar.y"
+    {
+            list_cmd((yyvsp[(3) - (4)].i),NULL,"// ",TRUE);
+          ;}
+    break;
+
+  case 139:
+
+/* Line 1464 of yacc.c  */
+#line 1256 "grammar.y"
+    {
+            list_cmd(RING_CMD,NULL,"// ",TRUE);
+          ;}
+    break;
+
+  case 140:
+
+/* Line 1464 of yacc.c  */
+#line 1260 "grammar.y"
+    {
+            list_cmd((yyvsp[(3) - (4)].i),NULL,"// ",TRUE);
+           ;}
+    break;
+
+  case 141:
+
+/* Line 1464 of yacc.c  */
+#line 1264 "grammar.y"
+    {
+            list_cmd(PROC_CMD,NULL,"// ",TRUE);
+          ;}
+    break;
+
+  case 142:
+
+/* Line 1464 of yacc.c  */
+#line 1268 "grammar.y"
+    {
+            list_cmd(0,(yyvsp[(3) - (4)].lv).Fullname(),"// ",TRUE);
+            (yyvsp[(3) - (4)].lv).CleanUp();
+          ;}
+    break;
+
+  case 143:
+
+/* Line 1464 of yacc.c  */
+#line 1273 "grammar.y"
+    {
+            if((yyvsp[(3) - (6)].lv).Typ() == PACKAGE_CMD)
+              list_cmd((yyvsp[(5) - (6)].i),NULL,"// ",TRUE);
+            (yyvsp[(3) - (6)].lv).CleanUp();
+          ;}
+    break;
+
+  case 144:
+
+/* Line 1464 of yacc.c  */
+#line 1279 "grammar.y"
+    {
+            if((yyvsp[(3) - (6)].lv).Typ() == PACKAGE_CMD)
+              list_cmd((yyvsp[(5) - (6)].i),NULL,"// ",TRUE);
+            (yyvsp[(3) - (6)].lv).CleanUp();
+          ;}
+    break;
+
+  case 145:
+
+/* Line 1464 of yacc.c  */
+#line 1285 "grammar.y"
+    {
+            if((yyvsp[(3) - (6)].lv).Typ() == PACKAGE_CMD)
+              list_cmd((yyvsp[(5) - (6)].i),NULL,"// ",TRUE);
+            (yyvsp[(3) - (6)].lv).CleanUp();
+          ;}
+    break;
+
+  case 146:
+
+/* Line 1464 of yacc.c  */
+#line 1291 "grammar.y"
+    {
+            if((yyvsp[(3) - (6)].lv).Typ() == PACKAGE_CMD)
+              list_cmd((yyvsp[(5) - (6)].i),NULL,"// ",TRUE);
+            (yyvsp[(3) - (6)].lv).CleanUp();
+          ;}
+    break;
+
+  case 147:
+
+/* Line 1464 of yacc.c  */
+#line 1297 "grammar.y"
+    {
+            if((yyvsp[(3) - (6)].lv).Typ() == PACKAGE_CMD)
+              list_cmd((yyvsp[(5) - (6)].i),NULL,"// ",TRUE);
+            (yyvsp[(3) - (6)].lv).CleanUp();
+          ;}
+    break;
+
+  case 148:
+
+/* Line 1464 of yacc.c  */
+#line 1303 "grammar.y"
+    {
+            if((yyvsp[(3) - (6)].lv).Typ() == PACKAGE_CMD)
+              list_cmd((yyvsp[(5) - (6)].i),NULL,"// ",TRUE);
+            (yyvsp[(3) - (6)].lv).CleanUp();
+          ;}
+    break;
+
+  case 149:
+
+/* Line 1464 of yacc.c  */
+#line 1309 "grammar.y"
+    {
+            if((yyvsp[(3) - (6)].lv).Typ() == PACKAGE_CMD)
+              list_cmd((yyvsp[(5) - (6)].i),NULL,"// ",TRUE);
+            (yyvsp[(3) - (6)].lv).CleanUp();
+          ;}
+    break;
+
+  case 150:
+
+/* Line 1464 of yacc.c  */
+#line 1321 "grammar.y"
+    {
+            list_cmd(-1,NULL,"// ",TRUE);
+          ;}
+    break;
+
+  case 151:
+
+/* Line 1464 of yacc.c  */
+#line 1327 "grammar.y"
+    { yyInRingConstruction = TRUE; ;}
+    break;
+
+  case 152:
+
+/* Line 1464 of yacc.c  */
+#line 1336 "grammar.y"
+    {
+            const char *ring_name = (yyvsp[(2) - (8)].lv).name;
+            ring b=
+            rInit(&(yyvsp[(4) - (8)].lv),            /* characteristik and list of parameters*/
+                  &(yyvsp[(6) - (8)].lv),            /* names of ringvariables */
+                  &(yyvsp[(8) - (8)].lv));            /* ordering */
+            idhdl newRingHdl=NULL;
+
+            if (b!=NULL)
+            {
+              newRingHdl=enterid(ring_name, myynest, RING_CMD,
+                                   &((yyvsp[(2) - (8)].lv).req_packhdl->idroot),FALSE);
+              (yyvsp[(2) - (8)].lv).CleanUp();
+              if (newRingHdl!=NULL)
+              {
+                IDRING(newRingHdl)=b;
+              }
+              else
+              {
+                rKill(b);
+              }
+            }
+            yyInRingConstruction = FALSE;
+            if (newRingHdl==NULL)
+            {
+              MYYERROR("cannot make ring");
+            }
+            else
+            {
+              rSetHdl(newRingHdl);
+            }
+          ;}
+    break;
+
+  case 153:
+
+/* Line 1464 of yacc.c  */
+#line 1369 "grammar.y"
+    {
+            const char *ring_name = (yyvsp[(2) - (2)].lv).name;
+            if (!inerror) rDefault(ring_name);
+            yyInRingConstruction = FALSE;
+            (yyvsp[(2) - (2)].lv).CleanUp();
+          ;}
+    break;
+
+  case 154:
+
+/* Line 1464 of yacc.c  */
+#line 1376 "grammar.y"
+    {
+            yyInRingConstruction = FALSE;
+            if (iiAssignCR(&(yyvsp[(2) - (4)].lv),&(yyvsp[(4) - (4)].lv))) YYERROR;
+          ;}
+    break;
+
+  case 155:
+
+/* Line 1464 of yacc.c  */
+#line 1384 "grammar.y"
+    {
+            if (((yyvsp[(1) - (2)].i)!=LIB_CMD)||(jjLOAD((yyvsp[(2) - (2)].name),TRUE))) YYERROR;
+          ;}
+    break;
+
+  case 158:
+
+/* Line 1464 of yacc.c  */
+#line 1393 "grammar.y"
+    {
+            if (((yyvsp[(1) - (2)].i)==KEEPRING_CMD) && (myynest==0))
+               MYYERROR("only inside a proc allowed");
+            const char * n=(yyvsp[(2) - (2)].lv).Name();
+            if ((((yyvsp[(2) - (2)].lv).Typ()==RING_CMD)||((yyvsp[(2) - (2)].lv).Typ()==QRING_CMD))
+            && ((yyvsp[(2) - (2)].lv).rtyp==IDHDL))
+            {
+              idhdl h=(idhdl)(yyvsp[(2) - (2)].lv).data;
+              if ((yyvsp[(2) - (2)].lv).e!=NULL) h=rFindHdl((ring)(yyvsp[(2) - (2)].lv).Data(),NULL);
+              //Print("setring %s lev %d (ptr:%x)\n",IDID(h),IDLEV(h),IDRING(h));
+              if ((yyvsp[(1) - (2)].i)==KEEPRING_CMD)
+              {
+                if (h!=NULL)
+                {
+                  if (IDLEV(h)!=0)
+                  {
+                    if (iiExport(&(yyvsp[(2) - (2)].lv),myynest-1)) YYERROR;
+#if 1
+                    idhdl p=IDRING(h)->idroot;
+                    idhdl root=p;
+                    int prevlev=myynest-1;
+                    while (p!=NULL)
+                    {
+                      if (IDLEV(p)==myynest)
+                      {
+                        idhdl old=root->get(IDID(p),prevlev);
+                        if (old!=NULL)
+                        {
+                          if (BVERBOSE(V_REDEFINE))
+                            Warn("redefining %s",IDID(p));
+                          killhdl2(old,&root,IDRING(h));
+                          IDRING(h)->idroot=root;
+                        }
+                        IDLEV(p)=prevlev;
+                      }
+                      p=IDNEXT(p);
+                    }
+#endif
+                  }
+#ifdef USE_IILOCALRING
+                  iiLocalRing[myynest-1]=IDRING(h);
+#endif
+                  procstack->cRing=IDRING(h);
+                  procstack->cRingHdl=h;
+                }
+                else
+                {
+                  Werror("%s is no identifier",n);
+                  (yyvsp[(2) - (2)].lv).CleanUp();
+                  YYERROR;
+                }
+              }
+              if (h!=NULL) rSetHdl(h);
+              else
+              {
+                Werror("cannot find the name of the basering %s",n);
+                (yyvsp[(2) - (2)].lv).CleanUp();
+                YYERROR;
+              }
+              (yyvsp[(2) - (2)].lv).CleanUp();
+            }
+            else
+            {
+              Werror("%s is no name of a ring/qring",n);
+              (yyvsp[(2) - (2)].lv).CleanUp();
+              YYERROR;
+            }
+          ;}
+    break;
+
+  case 159:
+
+/* Line 1464 of yacc.c  */
+#line 1465 "grammar.y"
+    {
+            type_cmd(&((yyvsp[(2) - (2)].lv)));
+          ;}
+    break;
+
+  case 160:
+
+/* Line 1464 of yacc.c  */
+#line 1469 "grammar.y"
+    {
+            //Print("typ is %d, rtyp:%d\n",$1.Typ(),$1.rtyp);
+            #ifdef SIQ
+            if ((yyvsp[(1) - (1)].lv).rtyp!=COMMAND)
+            {
+            #endif
+              if ((yyvsp[(1) - (1)].lv).Typ()==UNKNOWN)
+              {
+                if ((yyvsp[(1) - (1)].lv).name!=NULL)
+                {
+                  Werror("`%s` is undefined",(yyvsp[(1) - (1)].lv).name);
+                  omFree((ADDRESS)(yyvsp[(1) - (1)].lv).name);
+                }
+                YYERROR;
+              }
+            #ifdef SIQ
+            }
+            #endif
+            (yyvsp[(1) - (1)].lv).Print(&sLastPrinted);
+            (yyvsp[(1) - (1)].lv).CleanUp(currRing);
+            if (errorreported) YYERROR;
+          ;}
+    break;
+
+  case 161:
+
+/* Line 1464 of yacc.c  */
+#line 1498 "grammar.y"
+    {
+            int i; TESTSETINT((yyvsp[(3) - (5)].lv),i);
+            if (i!=0)
+            {
+              newBuffer( (yyvsp[(5) - (5)].name), BT_if);
+            }
+            else
+            {
+              omFree((ADDRESS)(yyvsp[(5) - (5)].name));
+              currentVoice->ifsw=1;
+            }
+          ;}
+    break;
+
+  case 162:
+
+/* Line 1464 of yacc.c  */
+#line 1511 "grammar.y"
+    {
+            if (currentVoice->ifsw==1)
+            {
+              currentVoice->ifsw=0;
+              newBuffer( (yyvsp[(2) - (2)].name), BT_else);
+            }
+            else
+            {
+              if (currentVoice->ifsw!=2)
+              {
+                Warn("`else` without `if` in level %d",myynest);
+              }
+              omFree((ADDRESS)(yyvsp[(2) - (2)].name));
+            }
+            currentVoice->ifsw=0;
+          ;}
+    break;
+
+  case 163:
+
+/* Line 1464 of yacc.c  */
+#line 1528 "grammar.y"
+    {
+            int i; TESTSETINT((yyvsp[(3) - (5)].lv),i);
+            if (i)
+            {
+              if (exitBuffer(BT_break)) YYERROR;
+            }
+            currentVoice->ifsw=0;
+          ;}
+    break;
+
+  case 164:
+
+/* Line 1464 of yacc.c  */
+#line 1537 "grammar.y"
+    {
+            if (exitBuffer(BT_break)) YYERROR;
+            currentVoice->ifsw=0;
+          ;}
+    break;
+
+  case 165:
+
+/* Line 1464 of yacc.c  */
+#line 1542 "grammar.y"
+    {
+            if (contBuffer(BT_break)) YYERROR;
+            currentVoice->ifsw=0;
+          ;}
+    break;
+
+  case 166:
+
+/* Line 1464 of yacc.c  */
+#line 1550 "grammar.y"
+    {
+            /* -> if(!$2) break; $3; continue;*/
+            char * s = (char *)omAlloc( strlen((yyvsp[(2) - (3)].name)) + strlen((yyvsp[(3) - (3)].name)) + 36);
+            sprintf(s,"whileif (!(%s)) break;\n%scontinue;\n " ,(yyvsp[(2) - (3)].name),(yyvsp[(3) - (3)].name));
+            newBuffer(s,BT_break);
+            omFree((ADDRESS)(yyvsp[(2) - (3)].name));
+            omFree((ADDRESS)(yyvsp[(3) - (3)].name));
+          ;}
+    break;
+
+  case 167:
+
+/* Line 1464 of yacc.c  */
+#line 1562 "grammar.y"
+    {
+            /* $2 */
+            /* if (!$3) break; $5; $4; continue; */
+            char * s = (char *)omAlloc( strlen((yyvsp[(3) - (5)].name))+strlen((yyvsp[(4) - (5)].name))+strlen((yyvsp[(5) - (5)].name))+36);
+            sprintf(s,"forif (!(%s)) break;\n%s%s;\ncontinue;\n "
+                   ,(yyvsp[(3) - (5)].name),(yyvsp[(5) - (5)].name),(yyvsp[(4) - (5)].name));
+            omFree((ADDRESS)(yyvsp[(3) - (5)].name));
+            omFree((ADDRESS)(yyvsp[(4) - (5)].name));
+            omFree((ADDRESS)(yyvsp[(5) - (5)].name));
+            newBuffer(s,BT_break);
+            s = (char *)omAlloc( strlen((yyvsp[(2) - (5)].name)) + 3);
+            sprintf(s,"%s;\n",(yyvsp[(2) - (5)].name));
+            omFree((ADDRESS)(yyvsp[(2) - (5)].name));
+            newBuffer(s,BT_if);
+          ;}
+    break;
+
+  case 168:
+
+/* Line 1464 of yacc.c  */
+#line 1581 "grammar.y"
+    {
+            idhdl h = enterid((yyvsp[(2) - (3)].name),myynest,PROC_CMD,&IDROOT,TRUE);
+            if (h==NULL) {omFree((ADDRESS)(yyvsp[(2) - (3)].name));omFree((ADDRESS)(yyvsp[(3) - (3)].name)); YYERROR;}
+            iiInitSingularProcinfo(IDPROC(h),"", (yyvsp[(2) - (3)].name), 0, 0);
+            IDPROC(h)->data.s.body = (char *)omAlloc(strlen((yyvsp[(3) - (3)].name))+31);;
+            sprintf(IDPROC(h)->data.s.body,"parameter list #;\n%s;return();\n\n",(yyvsp[(3) - (3)].name));
+            omFree((ADDRESS)(yyvsp[(3) - (3)].name));
+            omFree((ADDRESS)(yyvsp[(2) - (3)].name));
+          ;}
+    break;
+
+  case 169:
+
+/* Line 1464 of yacc.c  */
+#line 1591 "grammar.y"
+    {
+            idhdl h = enterid((yyvsp[(1) - (3)].name),myynest,PROC_CMD,&IDROOT,TRUE);
+            if (h==NULL)
+            {
+              omFree((ADDRESS)(yyvsp[(1) - (3)].name));
+              omFree((ADDRESS)(yyvsp[(2) - (3)].name));
+              omFree((ADDRESS)(yyvsp[(3) - (3)].name));
+              YYERROR;
+            }
+            char *args=iiProcArgs((yyvsp[(2) - (3)].name),FALSE);
+            omFree((ADDRESS)(yyvsp[(2) - (3)].name));
+            iiInitSingularProcinfo(IDPROC(h),"", (yyvsp[(1) - (3)].name), 0, 0);
+            IDPROC(h)->data.s.body = (char *)omAlloc(strlen((yyvsp[(3) - (3)].name))+strlen(args)+14);;
+            sprintf(IDPROC(h)->data.s.body,"%s\n%s;return();\n\n",args,(yyvsp[(3) - (3)].name));
+            omFree((ADDRESS)args);
+            omFree((ADDRESS)(yyvsp[(3) - (3)].name));
+            omFree((ADDRESS)(yyvsp[(1) - (3)].name));
+          ;}
+    break;
+
+  case 170:
+
+/* Line 1464 of yacc.c  */
+#line 1610 "grammar.y"
+    {
+            omFree((ADDRESS)(yyvsp[(3) - (4)].name));
+            idhdl h = enterid((yyvsp[(1) - (4)].name),myynest,PROC_CMD,&IDROOT,TRUE);
+            if (h==NULL)
+            {
+              omFree((ADDRESS)(yyvsp[(1) - (4)].name));
+              omFree((ADDRESS)(yyvsp[(2) - (4)].name));
+              omFree((ADDRESS)(yyvsp[(4) - (4)].name));
+              YYERROR;
+            }
+            char *args=iiProcArgs((yyvsp[(2) - (4)].name),FALSE);
+            omFree((ADDRESS)(yyvsp[(2) - (4)].name));
+            iiInitSingularProcinfo(IDPROC(h),"", (yyvsp[(1) - (4)].name), 0, 0);
+            omFree((ADDRESS)(yyvsp[(1) - (4)].name));
+            IDPROC(h)->data.s.body = (char *)omAlloc(strlen((yyvsp[(4) - (4)].name))+strlen(args)+14);;
+            sprintf(IDPROC(h)->data.s.body,"%s\n%s;return();\n\n",args,(yyvsp[(4) - (4)].name));
+            omFree((ADDRESS)args);
+            omFree((ADDRESS)(yyvsp[(4) - (4)].name));
+          ;}
+    break;
+
+  case 171:
+
+/* Line 1464 of yacc.c  */
+#line 1633 "grammar.y"
+    {
+            // decl. of type proc p(int i)
+            if ((yyvsp[(1) - (2)].i)==PARAMETER)  { if (iiParameter(&(yyvsp[(2) - (2)].lv))) YYERROR; }
+            else                { if (iiAlias(&(yyvsp[(2) - (2)].lv))) YYERROR; }
+          ;}
+    break;
+
+  case 172:
+
+/* Line 1464 of yacc.c  */
+#line 1639 "grammar.y"
+    {
+            // decl. of type proc p(i)
+            sleftv tmp_expr;
+            if ((yyvsp[(1) - (2)].i)==ALIAS_CMD) MYYERROR("alias requires a type");
+            if ((iiDeclCommand(&tmp_expr,&(yyvsp[(2) - (2)].lv),myynest,DEF_CMD,&IDROOT))
+            || (iiParameter(&tmp_expr)))
+              YYERROR;
+          ;}
+    break;
+
+  case 173:
+
+/* Line 1464 of yacc.c  */
+#line 1651 "grammar.y"
+    {
+            iiRETURNEXPR.Copy(&(yyvsp[(3) - (4)].lv));
+            (yyvsp[(3) - (4)].lv).CleanUp();
+            if (exitBuffer(BT_proc)) YYERROR;
+          ;}
+    break;
+
+  case 174:
+
+/* Line 1464 of yacc.c  */
+#line 1657 "grammar.y"
+    {
+            if ((yyvsp[(1) - (3)].i)==RETURN)
+            {
+              iiRETURNEXPR.Init();
+              iiRETURNEXPR.rtyp=NONE;
+              if (exitBuffer(BT_proc)) YYERROR;
+            }
+          ;}
+    break;
+
+
+
+/* Line 1464 of yacc.c  */
+#line 4320 "grammar.cc"
+      default: break;
+    }
+  YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
+
+  YYPOPSTACK (yylen);
+  yylen = 0;
+  YY_STACK_PRINT (yyss, yyssp);
+
+  *++yyvsp = yyval;
+
+  /* Now `shift' the result of the reduction.  Determine what state
+     that goes to, based on the state we popped back to and the rule
+     number reduced by.  */
+
+  yyn = yyr1[yyn];
+
+  yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
+  if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+    yystate = yytable[yystate];
+  else
+    yystate = yydefgoto[yyn - YYNTOKENS];
+
+  goto yynewstate;
+
+
+/*------------------------------------.
+| yyerrlab -- here on detecting error |
+`------------------------------------*/
+yyerrlab:
+  /* If not already recovering from an error, report this error.  */
+  if (!yyerrstatus)
+    {
+      ++yynerrs;
+#if ! YYERROR_VERBOSE
+      yyerror (YY_("syntax error"));
+#else
+      {
+	YYSIZE_T yysize = yysyntax_error (0, yystate, yychar);
+	if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM)
+	  {
+	    YYSIZE_T yyalloc = 2 * yysize;
+	    if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))
+	      yyalloc = YYSTACK_ALLOC_MAXIMUM;
+	    if (yymsg != yymsgbuf)
+	      YYSTACK_FREE (yymsg);
+	    yymsg = (char *) YYSTACK_ALLOC (yyalloc);
+	    if (yymsg)
+	      yymsg_alloc = yyalloc;
+	    else
+	      {
+		yymsg = yymsgbuf;
+		yymsg_alloc = sizeof yymsgbuf;
+	      }
+	  }
+
+	if (0 < yysize && yysize <= yymsg_alloc)
+	  {
+	    (void) yysyntax_error (yymsg, yystate, yychar);
+	    yyerror (yymsg);
+	  }
+	else
+	  {
+	    yyerror (YY_("syntax error"));
+	    if (yysize != 0)
+	      goto yyexhaustedlab;
+	  }
+      }
+#endif
+    }
+
+
+
+  if (yyerrstatus == 3)
+    {
+      /* If just tried and failed to reuse lookahead token after an
+	 error, discard it.  */
+
+      if (yychar <= YYEOF)
+	{
+	  /* Return failure if at end of input.  */
+	  if (yychar == YYEOF)
+	    YYABORT;
+	}
+      else
+	{
+	  yydestruct ("Error: discarding",
+		      yytoken, &yylval);
+	  yychar = YYEMPTY;
+	}
+    }
+
+  /* Else will try to reuse lookahead token after shifting the error
+     token.  */
+  goto yyerrlab1;
+
+
+/*---------------------------------------------------.
+| yyerrorlab -- error raised explicitly by YYERROR.  |
+`---------------------------------------------------*/
+yyerrorlab:
+
+  /* Pacify compilers like GCC when the user code never invokes
+     YYERROR and the label yyerrorlab therefore never appears in user
+     code.  */
+  if (/*CONSTCOND*/ 0)
+     goto yyerrorlab;
+
+  /* Do not reclaim the symbols of the rule which action triggered
+     this YYERROR.  */
+  YYPOPSTACK (yylen);
+  yylen = 0;
+  YY_STACK_PRINT (yyss, yyssp);
+  yystate = *yyssp;
+  goto yyerrlab1;
+
+
+/*-------------------------------------------------------------.
+| yyerrlab1 -- common code for both syntax error and YYERROR.  |
+`-------------------------------------------------------------*/
+yyerrlab1:
+  yyerrstatus = 3;	/* Each real token shifted decrements this.  */
+
+  for (;;)
+    {
+      yyn = yypact[yystate];
+      if (yyn != YYPACT_NINF)
+	{
+	  yyn += YYTERROR;
+	  if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
+	    {
+	      yyn = yytable[yyn];
+	      if (0 < yyn)
+		break;
+	    }
+	}
+
+      /* Pop the current state because it cannot handle the error token.  */
+      if (yyssp == yyss)
+	YYABORT;
+
+
+      yydestruct ("Error: popping",
+		  yystos[yystate], yyvsp);
+      YYPOPSTACK (1);
+      yystate = *yyssp;
+      YY_STACK_PRINT (yyss, yyssp);
+    }
+
+  *++yyvsp = yylval;
+
+
+  /* Shift the error token.  */
+  YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
+
+  yystate = yyn;
+  goto yynewstate;
+
+
+/*-------------------------------------.
+| yyacceptlab -- YYACCEPT comes here.  |
+`-------------------------------------*/
+yyacceptlab:
+  yyresult = 0;
+  goto yyreturn;
+
+/*-----------------------------------.
+| yyabortlab -- YYABORT comes here.  |
+`-----------------------------------*/
+yyabortlab:
+  yyresult = 1;
+  goto yyreturn;
+
+#if !defined(yyoverflow) || YYERROR_VERBOSE
+/*-------------------------------------------------.
+| yyexhaustedlab -- memory exhaustion comes here.  |
+`-------------------------------------------------*/
+yyexhaustedlab:
+  yyerror (YY_("memory exhausted"));
+  yyresult = 2;
+  /* Fall through.  */
+#endif
+
+yyreturn:
+  if (yychar != YYEMPTY)
+     yydestruct ("Cleanup: discarding lookahead",
+		 yytoken, &yylval);
+  /* Do not reclaim the symbols of the rule which action triggered
+     this YYABORT or YYACCEPT.  */
+  YYPOPSTACK (yylen);
+  YY_STACK_PRINT (yyss, yyssp);
+  while (yyssp != yyss)
+    {
+      yydestruct ("Cleanup: popping",
+		  yystos[*yyssp], yyvsp);
+      YYPOPSTACK (1);
+    }
+#ifndef yyoverflow
+  if (yyss != yyssa)
+    YYSTACK_FREE (yyss);
+#endif
+#if YYERROR_VERBOSE
+  if (yymsg != yymsgbuf)
+    YYSTACK_FREE (yymsg);
+#endif
+  /* Make sure YYID is used.  */
+  return YYID (yyresult);
+}
+
+
+
diff --git a/Singular/grammar.h b/Singular/grammar.h
new file mode 100644
index 0000000..c952839
--- /dev/null
+++ b/Singular/grammar.h
@@ -0,0 +1,184 @@
+/* A Bison parser, made by GNU Bison 2.4.3.  */
+
+/* Skeleton interface for Bison's Yacc-like parsers in C
+
+      Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
+   2009, 2010 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 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+/* As a special exception, you may create a larger work that contains
+   part or all of the Bison parser skeleton and distribute that work
+   under terms of your choice, so long as that work isn't itself a
+   parser generator using the skeleton or a modified version thereof
+   as a parser skeleton.  Alternatively, if you modify or redistribute
+   the parser skeleton itself, you may (at your option) remove this
+   special exception, which will cause the skeleton and the resulting
+   Bison output files to be licensed under the GNU General Public
+   License without this special exception.
+
+   This special exception was added by the Free Software Foundation in
+   version 2.2 of Bison.  */
+
+
+/* Tokens.  */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+   /* Put the tokens into the symbol table, so that GDB and other debuggers
+      know about them.  */
+   enum yytokentype {
+     DOTDOT = 258,
+     EQUAL_EQUAL = 259,
+     GE = 260,
+     LE = 261,
+     MINUSMINUS = 262,
+     NOT = 263,
+     NOTEQUAL = 264,
+     PLUSPLUS = 265,
+     COLONCOLON = 266,
+     ARROW = 267,
+     GRING_CMD = 268,
+     BIGINTMAT_CMD = 269,
+     INTMAT_CMD = 270,
+     PROC_CMD = 271,
+     RING_CMD = 272,
+     BEGIN_RING = 273,
+     IDEAL_CMD = 274,
+     MAP_CMD = 275,
+     MATRIX_CMD = 276,
+     MODUL_CMD = 277,
+     NUMBER_CMD = 278,
+     POLY_CMD = 279,
+     RESOLUTION_CMD = 280,
+     VECTOR_CMD = 281,
+     BETTI_CMD = 282,
+     COEFFS_CMD = 283,
+     COEF_CMD = 284,
+     CONTRACT_CMD = 285,
+     DEGREE_CMD = 286,
+     DEG_CMD = 287,
+     DIFF_CMD = 288,
+     DIM_CMD = 289,
+     DIVISION_CMD = 290,
+     ELIMINATION_CMD = 291,
+     E_CMD = 292,
+     FAREY_CMD = 293,
+     FETCH_CMD = 294,
+     FREEMODULE_CMD = 295,
+     KEEPRING_CMD = 296,
+     HILBERT_CMD = 297,
+     HOMOG_CMD = 298,
+     IMAP_CMD = 299,
+     INDEPSET_CMD = 300,
+     INTERRED_CMD = 301,
+     INTERSECT_CMD = 302,
+     JACOB_CMD = 303,
+     JET_CMD = 304,
+     KBASE_CMD = 305,
+     KOSZUL_CMD = 306,
+     LEADCOEF_CMD = 307,
+     LEADEXP_CMD = 308,
+     LEAD_CMD = 309,
+     LEADMONOM_CMD = 310,
+     LIFTSTD_CMD = 311,
+     LIFT_CMD = 312,
+     MAXID_CMD = 313,
+     MINBASE_CMD = 314,
+     MINOR_CMD = 315,
+     MINRES_CMD = 316,
+     MODULO_CMD = 317,
+     MONOM_CMD = 318,
+     MRES_CMD = 319,
+     MULTIPLICITY_CMD = 320,
+     ORD_CMD = 321,
+     PAR_CMD = 322,
+     PARDEG_CMD = 323,
+     PREIMAGE_CMD = 324,
+     QUOTIENT_CMD = 325,
+     QHWEIGHT_CMD = 326,
+     REDUCE_CMD = 327,
+     REGULARITY_CMD = 328,
+     RES_CMD = 329,
+     SBA_CMD = 330,
+     SIMPLIFY_CMD = 331,
+     SORTVEC_CMD = 332,
+     SRES_CMD = 333,
+     STD_CMD = 334,
+     SUBST_CMD = 335,
+     SYZYGY_CMD = 336,
+     VAR_CMD = 337,
+     VDIM_CMD = 338,
+     WEDGE_CMD = 339,
+     WEIGHT_CMD = 340,
+     VALTVARS = 341,
+     VMAXDEG = 342,
+     VMAXMULT = 343,
+     VNOETHER = 344,
+     VMINPOLY = 345,
+     END_RING = 346,
+     CMD_1 = 347,
+     CMD_2 = 348,
+     CMD_3 = 349,
+     CMD_12 = 350,
+     CMD_13 = 351,
+     CMD_23 = 352,
+     CMD_123 = 353,
+     CMD_M = 354,
+     ROOT_DECL = 355,
+     ROOT_DECL_LIST = 356,
+     RING_DECL = 357,
+     RING_DECL_LIST = 358,
+     EXAMPLE_CMD = 359,
+     EXPORT_CMD = 360,
+     HELP_CMD = 361,
+     KILL_CMD = 362,
+     LIB_CMD = 363,
+     LISTVAR_CMD = 364,
+     SETRING_CMD = 365,
+     TYPE_CMD = 366,
+     STRINGTOK = 367,
+     BLOCKTOK = 368,
+     INT_CONST = 369,
+     UNKNOWN_IDENT = 370,
+     RINGVAR = 371,
+     PROC_DEF = 372,
+     APPLY = 373,
+     ASSUME_CMD = 374,
+     BREAK_CMD = 375,
+     CONTINUE_CMD = 376,
+     ELSE_CMD = 377,
+     EVAL = 378,
+     QUOTE = 379,
+     FOR_CMD = 380,
+     IF_CMD = 381,
+     SYS_BREAK = 382,
+     WHILE_CMD = 383,
+     RETURN = 384,
+     PARAMETER = 385,
+     SYSVAR = 386,
+     UMINUS = 387
+   };
+#endif
+
+
+
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+#endif
+
+
+
+
diff --git a/Singular/idrec.h b/Singular/idrec.h
new file mode 100644
index 0000000..189fac9
--- /dev/null
+++ b/Singular/idrec.h
@@ -0,0 +1,57 @@
+#ifndef IDREC_H
+#define IDREC_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT interpreter type for variables
+*/
+
+#include <Singular/lists.h>
+#include <Singular/attrib.h>
+#include <Singular/links/silink.h>
+
+class bigintmat;
+typedef union uutypes      utypes;
+union uutypes
+{
+  int           i;
+  ring          uring;
+  poly          p;
+  number        n;
+  ideal         uideal;
+  map           umap;
+  matrix        umatrix;
+  char *        ustring;
+  intvec *      iv;
+  bigintmat *   bim;
+  lists         l;
+  si_link       li;
+  package       pack;
+  procinfo *    pinf;
+};
+
+class idrec
+{
+  public:
+  /* !! do not change the first 6 entries !! (see subexpr.h: sleftv) */
+  idhdl      next;
+  const char *id;
+  utypes     data;
+  attr       attribute;
+  BITSET     flag;
+  int        typ;
+
+  short      lev;
+  short      ref;
+  int        id_i;
+
+  idrec() { memset(this,0,sizeof(*this)); }
+  idhdl get(const char * s, int lev);
+  idhdl set(const char * s, int lev, int t/*typ*/, BOOLEAN init=TRUE);
+  char * String(BOOLEAN typed = FALSE);
+//  ~idrec();
+};
+
+#endif
+
diff --git a/Singular/iparith.cc b/Singular/iparith.cc
new file mode 100644
index 0000000..b09e283
--- /dev/null
+++ b/Singular/iparith.cc
@@ -0,0 +1,9094 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+
+/*
+* ABSTRACT: table driven kernel interface, used by interpreter
+*/
+
+
+#include <kernel/mod2.h>
+
+#include <omalloc/omalloc.h>
+
+#include <factory/factory.h>
+
+#include <coeffs/bigintmat.h>
+#include <coeffs/coeffs.h>
+#include <coeffs/numbers.h>
+
+
+#include <misc/options.h>
+#include <misc/intvec.h>
+#include <misc/sirandom.h>
+
+#include <polys/prCopy.h>
+#include <polys/matpol.h>
+#include <polys/monomials/maps.h>
+#include <polys/coeffrings.h>
+#include <polys/sparsmat.h>
+#include <polys/weight.h>
+#include <polys/ext_fields/transext.h>
+#include <polys/clapsing.h>
+
+#include <kernel/combinatorics/stairc.h>
+#include <kernel/combinatorics/hilb.h>
+
+#include <kernel/linear_algebra/interpolation.h>
+#include <kernel/linear_algebra/linearAlgebra.h>
+#include <kernel/linear_algebra/MinorInterface.h>
+
+#include <kernel/spectrum/GMPrat.h>
+#include <kernel/groebner_walk/walkProc.h>
+#include <kernel/oswrapper/timer.h>
+#include <kernel/fglm/fglm.h>
+
+#include <kernel/GBEngine/kstdfac.h>
+#include <kernel/GBEngine/syz.h>
+#include <kernel/GBEngine/kstd1.h>
+#include <kernel/GBEngine/units.h>
+#include <kernel/GBEngine/tgb.h>
+
+#include <kernel/preimage.h>
+#include <kernel/polys.h>
+#include <kernel/ideals.h>
+
+#include <Singular/mod_lib.h>
+#include <Singular/fevoices.h>
+#include <Singular/tok.h>
+#include <Singular/ipid.h>
+#include <Singular/sdb.h>
+#include <Singular/subexpr.h>
+#include <Singular/lists.h>
+#include <Singular/maps_ip.h>
+
+#include <Singular/ipconv.h>
+#include <Singular/ipprint.h>
+#include <Singular/attrib.h>
+#include <Singular/links/silink.h>
+#include <Singular/misc_ip.h>
+#include <Singular/linearAlgebra_ip.h>
+
+#ifdef SINGULAR_4_1
+#include <Singular/number2.h>
+#endif
+
+#  include <Singular/fglm.h>
+
+#include <Singular/blackbox.h>
+#include <Singular/newstruct.h>
+#include <Singular/ipshell.h>
+//#include <kernel/mpr_inout.h>
+
+#include <reporter/si_signals.h>
+
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <time.h>
+#include <unistd.h>
+#include <vector>
+
+lists rDecompose(const ring r);
+ring rCompose(const lists  L, const BOOLEAN check_comp=TRUE);
+
+
+// defaults for all commands: NO_PLURAL | NO_RING | ALLOW_ZERODIVISOR
+
+#ifdef HAVE_PLURAL
+  #include <kernel/GBEngine/ratgring.h>
+  #include <kernel/GBEngine/nc.h>
+  #include <polys/nc/nc.h>
+  #include <polys/nc/sca.h>
+  #define  PLURAL_MASK 3
+#else /* HAVE_PLURAL */
+  #define  PLURAL_MASK     0
+#endif /* HAVE_PLURAL */
+
+#ifdef HAVE_RINGS
+  #define RING_MASK        4
+  #define ZERODIVISOR_MASK 8
+#else
+  #define RING_MASK        0
+  #define ZERODIVISOR_MASK 0
+#endif
+#define ALLOW_PLURAL     1
+#define NO_PLURAL        0
+#define COMM_PLURAL      2
+#define ALLOW_RING       4
+#define NO_RING          0
+#define NO_ZERODIVISOR   8
+#define ALLOW_ZERODIVISOR  0
+
+// bit 4 for warning, if used at toplevel
+#define WARN_RING        16
+
+static BOOLEAN check_valid(const int p, const int op);
+
+#ifdef SINGULAR_4_1
+// helper routine to catch all library/test parts which need to be changed
+// shall go away after the transition
+static void iiReWrite(const char *s)
+{
+  Print("please rewrite the use of >>%s<< in >>%s<<\n"
+        "%s is depreciated or changed in Singular 4-1\n",s,my_yylinebuf,s);
+}
+#endif
+
+/*=============== types =====================*/
+struct sValCmdTab
+{
+  short cmd;
+  short start;
+};
+
+typedef sValCmdTab jjValCmdTab[];
+
+struct _scmdnames
+{
+  char *name;
+  short alias;
+  short tokval;
+  short toktype;
+};
+typedef struct _scmdnames cmdnames;
+
+
+typedef char * (*Proc1)(char *);
+struct sValCmd1
+{
+  proc1 p;
+  short cmd;
+  short res;
+  short arg;
+  short valid_for;
+};
+
+typedef BOOLEAN (*proc2)(leftv,leftv,leftv);
+struct sValCmd2
+{
+  proc2 p;
+  short cmd;
+  short res;
+  short arg1;
+  short arg2;
+  short valid_for;
+};
+
+typedef BOOLEAN (*proc3)(leftv,leftv,leftv,leftv);
+struct sValCmd3
+{
+  proc3 p;
+  short cmd;
+  short res;
+  short arg1;
+  short arg2;
+  short arg3;
+  short valid_for;
+};
+struct sValCmdM
+{
+  proc1 p;
+  short cmd;
+  short res;
+  short number_of_args; /* -1: any, -2: any >0, .. */
+  short valid_for;
+};
+
+typedef struct
+{
+  cmdnames *sCmds;             /**< array of existing commands */
+  struct sValCmd1 *psValCmd1;
+  struct sValCmd2 *psValCmd2;
+  struct sValCmd3 *psValCmd3;
+  struct sValCmdM *psValCmdM;
+  int nCmdUsed;      /**< number of commands used */
+  int nCmdAllocated; /**< number of commands-slots allocated */
+  int nLastIdentifier; /**< valid indentifieres are slot 1..nLastIdentifier */
+} SArithBase;
+
+/*---------------------------------------------------------------------*
+ * File scope Variables (Variables share by several functions in
+ *                       the same file )
+ *
+ *---------------------------------------------------------------------*/
+static SArithBase sArithBase;  /**< Base entry for arithmetic */
+
+/*---------------------------------------------------------------------*
+ * Extern Functions declarations
+ *
+ *---------------------------------------------------------------------*/
+static int _gentable_sort_cmds(const void *a, const void *b);
+extern int iiArithRemoveCmd(char *szName);
+extern int iiArithAddCmd(const char *szName, short nAlias, short nTokval,
+                         short nToktype, short nPos=-1);
+
+/*============= proc =======================*/
+static int iiTabIndex(const jjValCmdTab dArithTab, const int len, const int op);
+static Subexpr jjMakeSub(leftv e);
+
+/*============= vars ======================*/
+extern int cmdtok;
+extern BOOLEAN expected_parms;
+
+#define ii_div_by_0 "div. by 0"
+
+int iiOp; /* the current operation*/
+
+/*=================== simple helpers =================*/
+poly pHeadProc(poly p)
+{
+  return pHead(p);
+}
+
+int iiTokType(int op)
+{
+  for (int i=0;i<sArithBase.nCmdUsed;i++)
+  {
+    if (sArithBase.sCmds[i].tokval==op)
+      return sArithBase.sCmds[i].toktype;
+  }
+  return 0;
+}
+
+/*=================== operations with 2 args.: static proc =================*/
+/* must be ordered: first operations for chars (infix ops),
+ * then alphabetically */
+
+static BOOLEAN jjOP_BIM_I(leftv res, leftv u, leftv v)
+{
+  bigintmat* aa= (bigintmat *)u->Data();
+  int bb = (int)(long)(v->Data());
+  if (errorreported) return TRUE;
+  bigintmat *cc=NULL;
+  switch (iiOp)
+  {
+    case '+': cc=bimAdd(aa,bb); break;
+    case '-': cc=bimSub(aa,bb); break;
+    case '*': cc=bimMult(aa,bb); break;
+  }
+  res->data=(char *)cc;
+  return cc==NULL;
+}
+static BOOLEAN jjOP_I_BIM(leftv res, leftv u, leftv v)
+{
+  return jjOP_BIM_I(res, v, u);
+}
+static BOOLEAN jjOP_BIM_BI(leftv res, leftv u, leftv v)
+{
+  bigintmat* aa= (bigintmat *)u->Data();
+  number bb = (number)(v->Data());
+  if (errorreported) return TRUE;
+  bigintmat *cc=NULL;
+  switch (iiOp)
+  {
+    case '*': cc=bimMult(aa,bb,coeffs_BIGINT); break;
+  }
+  res->data=(char *)cc;
+  return cc==NULL;
+}
+static BOOLEAN jjOP_BI_BIM(leftv res, leftv u, leftv v)
+{
+  return jjOP_BIM_BI(res, v, u);
+}
+static BOOLEAN jjOP_IV_I(leftv res, leftv u, leftv v)
+{
+  intvec* aa= (intvec *)u->CopyD(INTVEC_CMD);
+  int bb = (int)(long)(v->Data());
+  if (errorreported) return TRUE;
+  switch (iiOp)
+  {
+    case '+': (*aa) += bb; break;
+    case '-': (*aa) -= bb; break;
+    case '*': (*aa) *= bb; break;
+    case '/':
+    case INTDIV_CMD: (*aa) /= bb; break;
+    case '%': (*aa) %= bb; break;
+  }
+  res->data=(char *)aa;
+  return FALSE;
+}
+static BOOLEAN jjOP_I_IV(leftv res, leftv u, leftv v)
+{
+  return jjOP_IV_I(res,v,u);
+}
+static BOOLEAN jjOP_IM_I(leftv res, leftv u, leftv v)
+{
+  intvec* aa= (intvec *)u->CopyD(INTVEC_CMD);
+  int bb = (int)(long)(v->Data());
+  int i=si_min(aa->rows(),aa->cols());
+  switch (iiOp)
+  {
+    case '+': for (;i>0;i--) IMATELEM(*aa,i,i) += bb;
+              break;
+    case '-': for (;i>0;i--) IMATELEM(*aa,i,i) -= bb;
+              break;
+  }
+  res->data=(char *)aa;
+  return FALSE;
+}
+static BOOLEAN jjOP_I_IM(leftv res, leftv u, leftv v)
+{
+  return jjOP_IM_I(res,v,u);
+}
+static BOOLEAN jjCOLON(leftv res, leftv u, leftv v)
+{
+  int l=(int)(long)v->Data();
+  if (l>0)
+  {
+    int d=(int)(long)u->Data();
+    intvec *vv=new intvec(l);
+    int i;
+    for(i=l-1;i>=0;i--) { (*vv)[i]=d; }
+    res->data=(char *)vv;
+  }
+  return (l<=0);
+}
+static BOOLEAN jjDOTDOT(leftv res, leftv u, leftv v)
+{
+  res->data=(char *)new intvec((int)(long)u->Data(),(int)(long)v->Data());
+  return FALSE;
+}
+static void jjEQUAL_REST(leftv res,leftv u,leftv v);
+static BOOLEAN jjCOMPARE_IV(leftv res, leftv u, leftv v)
+{
+  intvec*    a = (intvec * )(u->Data());
+  intvec*    b = (intvec * )(v->Data());
+  int r=a->compare(b);
+  switch  (iiOp)
+  {
+    case '<':
+      res->data  = (char *) (r<0);
+      break;
+    case '>':
+      res->data  = (char *) (r>0);
+      break;
+    case LE:
+      res->data  = (char *) (r<=0);
+      break;
+    case GE:
+      res->data  = (char *) (r>=0);
+      break;
+    case EQUAL_EQUAL:
+    case NOTEQUAL: /* negation handled by jjEQUAL_REST */
+      res->data  = (char *) (r==0);
+      break;
+  }
+  jjEQUAL_REST(res,u,v);
+  if(r==-2) { WerrorS("size incompatible"); return TRUE; }
+  return FALSE;
+}
+static BOOLEAN jjCOMPARE_BIM(leftv res, leftv u, leftv v)
+{
+  bigintmat*    a = (bigintmat * )(u->Data());
+  bigintmat*    b = (bigintmat * )(v->Data());
+  int r=a->compare(b);
+  switch  (iiOp)
+  {
+    case '<':
+      res->data  = (char *) (r<0);
+      break;
+    case '>':
+      res->data  = (char *) (r>0);
+      break;
+    case LE:
+      res->data  = (char *) (r<=0);
+      break;
+    case GE:
+      res->data  = (char *) (r>=0);
+      break;
+    case EQUAL_EQUAL:
+    case NOTEQUAL: /* negation handled by jjEQUAL_REST */
+      res->data  = (char *) (r==0);
+      break;
+  }
+  jjEQUAL_REST(res,u,v);
+  if(r==-2) { WerrorS("size incompatible"); return TRUE; }
+  return FALSE;
+}
+static BOOLEAN jjCOMPARE_IV_I(leftv res, leftv u, leftv v)
+{
+  intvec* a = (intvec * )(u->Data());
+  int     b = (int)(long)(v->Data());
+  int r=a->compare(b);
+  switch  (iiOp)
+  {
+    case '<':
+      res->data  = (char *) (r<0);
+      break;
+    case '>':
+      res->data  = (char *) (r>0);
+      break;
+    case LE:
+      res->data  = (char *) (r<=0);
+      break;
+    case GE:
+      res->data  = (char *) (r>=0);
+      break;
+    case EQUAL_EQUAL:
+    case NOTEQUAL: /* negation handled by jjEQUAL_REST */
+      res->data  = (char *) (r==0);
+      break;
+  }
+  jjEQUAL_REST(res,u,v);
+  return FALSE;
+}
+static BOOLEAN jjCOMPARE_P(leftv res, leftv u, leftv v)
+{
+  poly p=(poly)u->Data();
+  poly q=(poly)v->Data();
+  int r=pCmp(p,q);
+  if (r==0)
+  {
+    number h=nSub(pGetCoeff(p),pGetCoeff(q));
+    /* compare lead coeffs */
+    r = -1+nIsZero(h)+2*nGreaterZero(h); /* -1: <, 0:==, 1: > */
+    nDelete(&h);
+  }
+  else if (p==NULL)
+  {
+    if (q==NULL)
+    {
+      /* compare 0, 0 */
+      r=0;
+    }
+    else if(pIsConstant(q))
+    {
+      /* compare 0, const */
+      r = 1-2*nGreaterZero(pGetCoeff(q)); /* -1: <, 1: > */
+    }
+  }
+  else if (q==NULL)
+  {
+    if (pIsConstant(p))
+    {
+      /* compare const, 0 */
+      r = -1+2*nGreaterZero(pGetCoeff(p)); /* -1: <, 1: > */
+    }
+  }
+  switch  (iiOp)
+  {
+    case '<':
+      res->data  = (char *) (r < 0);
+      break;
+    case '>':
+      res->data  = (char *) (r > 0);
+      break;
+    case LE:
+      res->data  = (char *) (r <= 0);
+      break;
+    case GE:
+      res->data  = (char *) (r >= 0);
+      break;
+    //case EQUAL_EQUAL:
+    //case NOTEQUAL: /* negation handled by jjEQUAL_REST */
+    //  res->data  = (char *) (r == 0);
+    //  break;
+  }
+  jjEQUAL_REST(res,u,v);
+  return FALSE;
+}
+static BOOLEAN jjCOMPARE_S(leftv res, leftv u, leftv v)
+{
+  char*    a = (char * )(u->Data());
+  char*    b = (char * )(v->Data());
+  int result = strcmp(a,b);
+  switch  (iiOp)
+  {
+    case '<':
+      res->data  = (char *) (result  < 0);
+      break;
+    case '>':
+      res->data  = (char *) (result  > 0);
+      break;
+    case LE:
+      res->data  = (char *) (result  <= 0);
+      break;
+    case GE:
+      res->data  = (char *) (result  >= 0);
+      break;
+    case EQUAL_EQUAL:
+    case NOTEQUAL: /* negation handled by jjEQUAL_REST */
+      res->data  = (char *) (result  == 0);
+      break;
+  }
+  jjEQUAL_REST(res,u,v);
+  return FALSE;
+}
+static BOOLEAN jjOP_REST(leftv res, leftv u, leftv v)
+{
+  if (u->Next()!=NULL)
+  {
+    u=u->next;
+    res->next = (leftv)omAllocBin(sleftv_bin);
+    return iiExprArith2(res->next,u,iiOp,v);
+  }
+  else if (v->Next()!=NULL)
+  {
+    v=v->next;
+    res->next = (leftv)omAllocBin(sleftv_bin);
+    return iiExprArith2(res->next,u,iiOp,v);
+  }
+  return FALSE;
+}
+static BOOLEAN jjPOWER_I(leftv res, leftv u, leftv v)
+{
+  int b=(int)(long)u->Data();
+  int e=(int)(long)v->Data();
+  int rc = 1;
+  BOOLEAN overflow=FALSE;
+  if (e >= 0)
+  {
+    if (b==0)
+    {
+      rc=(e==0);
+    }
+    else if ((e==0)||(b==1))
+    {
+      rc= 1;
+    }
+    else if (b== -1)
+    {
+      if (e&1) rc= -1;
+      else     rc= 1;
+    }
+    else
+    {
+      int oldrc;
+      while ((e--)!=0)
+      {
+        oldrc=rc;
+        rc *= b;
+        if (!overflow)
+        {
+          if(rc/b!=oldrc) overflow=TRUE;
+        }
+      }
+      if (overflow)
+        WarnS("int overflow(^), result may be wrong");
+    }
+    res->data = (char *)((long)rc);
+    if (u!=NULL) return jjOP_REST(res,u,v);
+    return FALSE;
+  }
+  else
+  {
+    WerrorS("exponent must be non-negative");
+    return TRUE;
+  }
+}
+static BOOLEAN jjPOWER_BI(leftv res, leftv u, leftv v)
+{
+  int e=(int)(long)v->Data();
+  number n=(number)u->Data();
+  if (e>=0)
+  {
+    n_Power(n,e,(number*)&res->data,coeffs_BIGINT);
+  }
+  else
+  {
+    WerrorS("exponent must be non-negative");
+    return TRUE;
+  }
+  if (u!=NULL) return jjOP_REST(res,u,v);
+  return FALSE;
+}
+static BOOLEAN jjPOWER_N(leftv res, leftv u, leftv v)
+{
+  int e=(int)(long)v->Data();
+  number n=(number)u->Data();
+  int d=0;
+  if (e<0)
+  {
+    n=nInvers(n);
+    e=-e;
+    d=1;
+  }
+  number r;
+  nPower(n,e,(number*)&r);
+  res->data=(char*)r;
+  if (d) nDelete(&n);
+  if (u!=NULL) return jjOP_REST(res,u,v);
+  return FALSE;
+}
+static BOOLEAN jjPOWER_P(leftv res, leftv u, leftv v)
+{
+  int v_i=(int)(long)v->Data();
+  if (v_i<0)
+  {
+    WerrorS("exponent must be non-negative");
+    return TRUE;
+  }
+  poly u_p=(poly)u->CopyD(POLY_CMD);
+  if ((u_p!=NULL)
+  && ((v_i!=0) &&
+      ((long)pTotaldegree(u_p) > (signed long)currRing->bitmask / (signed long)v_i/2)))
+  {
+    Werror("OVERFLOW in power(d=%ld, e=%d, max=%ld)",
+                                    pTotaldegree(u_p),v_i,currRing->bitmask/2);
+    pDelete(&u_p);
+    return TRUE;
+  }
+  res->data = (char *)pPower(u_p,v_i);
+  if (u!=NULL) return jjOP_REST(res,u,v);
+  return errorreported; /* pPower may set errorreported via Werror */
+}
+static BOOLEAN jjPOWER_ID(leftv res, leftv u, leftv v)
+{
+  res->data = (char *)id_Power((ideal)(u->Data()),(int)(long)(v->Data()), currRing);
+  if (u!=NULL) return jjOP_REST(res,u,v);
+  return FALSE;
+}
+static BOOLEAN jjPLUSMINUS_Gen(leftv res, leftv u, leftv v)
+{
+  u=u->next;
+  v=v->next;
+  if (u==NULL)
+  {
+    if (v==NULL) return FALSE;      /* u==NULL, v==NULL */
+    if (iiOp=='-')                  /* u==NULL, v<>NULL, iiOp=='-'*/
+    {
+      do
+      {
+        if (res->next==NULL)
+          res->next = (leftv)omAlloc0Bin(sleftv_bin);
+        leftv tmp_v=v->next;
+        v->next=NULL;
+        BOOLEAN b=iiExprArith1(res->next,v,'-');
+        v->next=tmp_v;
+        if (b)
+          return TRUE;
+        v=tmp_v;
+        res=res->next;
+      } while (v!=NULL);
+      return FALSE;
+    }
+    loop                            /* u==NULL, v<>NULL, iiOp=='+' */
+    {
+      res->next = (leftv)omAlloc0Bin(sleftv_bin);
+      res=res->next;
+      res->data = v->CopyD();
+      res->rtyp = v->Typ();
+      v=v->next;
+      if (v==NULL) return FALSE;
+    }
+  }
+  if (v!=NULL)                     /* u<>NULL, v<>NULL */
+  {
+    do
+    {
+      res->next = (leftv)omAlloc0Bin(sleftv_bin);
+      leftv tmp_u=u->next; u->next=NULL;
+      leftv tmp_v=v->next; v->next=NULL;
+      BOOLEAN b=iiExprArith2(res->next,u,iiOp,v);
+      u->next=tmp_u;
+      v->next=tmp_v;
+      if (b)
+        return TRUE;
+      u=tmp_u;
+      v=tmp_v;
+      res=res->next;
+    } while ((u!=NULL) && (v!=NULL));
+    return FALSE;
+  }
+  loop                             /* u<>NULL, v==NULL */
+  {
+    res->next = (leftv)omAlloc0Bin(sleftv_bin);
+    res=res->next;
+    res->data = u->CopyD();
+    res->rtyp = u->Typ();
+    u=u->next;
+    if (u==NULL) return FALSE;
+  }
+}
+static BOOLEAN jjCOLCOL(leftv res, leftv u, leftv v)
+{
+  idhdl packhdl;
+  switch(u->Typ())
+  {
+      case 0:
+      {
+        int name_err=0;
+        if(isupper(u->name[0]))
+        {
+          const char *c=u->name+1;
+          while((*c!='\0')&&(islower(*c)||(isdigit(*c)))) c++;
+          if (*c!='\0')
+            name_err=1;
+          else
+          {
+            Print("%s of type 'ANY'. Trying load.\n", u->name);
+            if(iiTryLoadLib(u, u->name))
+            {
+              Werror("'%s' no such package", u->name);
+              return TRUE;
+            }
+            syMake(u,u->name,NULL);
+          }
+        }
+        else name_err=1;
+        if(name_err)
+        { Werror("'%s' is an invalid package name",u->name);return TRUE;}
+        // and now, after the loading: use next case !!! no break !!!
+      }
+      case PACKAGE_CMD:
+        packhdl = (idhdl)u->data;
+        if((!IDPACKAGE(packhdl)->loaded)
+        && (IDPACKAGE(packhdl)->language > LANG_TOP))
+        {
+          Werror("'%s' not loaded", u->name);
+          return TRUE;
+        }
+        if(v->rtyp == IDHDL)
+        {
+          v->name = omStrDup(v->name);
+        }
+        else if (v->rtyp!=0)
+        {
+          WerrorS("reserved name with ::");
+          return TRUE;
+        }
+        v->req_packhdl=IDPACKAGE(packhdl);
+        syMake(v, v->name, packhdl);
+        memcpy(res, v, sizeof(sleftv));
+        memset(v, 0, sizeof(sleftv));
+        break;
+      case DEF_CMD:
+        break;
+      default:
+        WerrorS("<package>::<id> expected");
+        return TRUE;
+  }
+  return FALSE;
+}
+static BOOLEAN jjPLUS_I(leftv res, leftv u, leftv v)
+{
+  unsigned int a=(unsigned int)(unsigned long)u->Data();
+  unsigned int b=(unsigned int)(unsigned long)v->Data();
+  unsigned int c=a+b;
+  res->data = (char *)((long)c);
+  if (((Sy_bit(31)&a)==(Sy_bit(31)&b))&&((Sy_bit(31)&a)!=(Sy_bit(31)&c)))
+  {
+    WarnS("int overflow(+), result may be wrong");
+  }
+  return jjPLUSMINUS_Gen(res,u,v);
+}
+static BOOLEAN jjPLUS_BI(leftv res, leftv u, leftv v)
+{
+  res->data = (char *)(n_Add((number)u->Data(), (number)v->Data(),coeffs_BIGINT));
+  return jjPLUSMINUS_Gen(res,u,v);
+}
+static BOOLEAN jjPLUS_N(leftv res, leftv u, leftv v)
+{
+  res->data = (char *)(nAdd((number)u->Data(), (number)v->Data()));
+  return jjPLUSMINUS_Gen(res,u,v);
+}
+static BOOLEAN jjPLUS_P(leftv res, leftv u, leftv v)
+{
+  res->data = (char *)(pAdd((poly)u->CopyD(POLY_CMD) , (poly)v->CopyD(POLY_CMD)));
+  return jjPLUSMINUS_Gen(res,u,v);
+}
+static BOOLEAN jjPLUS_IV(leftv res, leftv u, leftv v)
+{
+  res->data = (char *)ivAdd((intvec*)(u->Data()), (intvec*)(v->Data()));
+  if (res->data==NULL)
+  {
+     WerrorS("intmat size not compatible");
+     return TRUE;
+  }
+  return jjPLUSMINUS_Gen(res,u,v);
+}
+static BOOLEAN jjPLUS_BIM(leftv res, leftv u, leftv v)
+{
+  res->data = (char *)bimAdd((bigintmat*)(u->Data()), (bigintmat*)(v->Data()));
+  if (res->data==NULL)
+  {
+    WerrorS("bigintmat/cmatrix not compatible");
+    return TRUE;
+  }
+  return jjPLUSMINUS_Gen(res,u,v);
+}
+static BOOLEAN jjPLUS_MA(leftv res, leftv u, leftv v)
+{
+  matrix A=(matrix)u->Data(); matrix B=(matrix)v->Data();
+  res->data = (char *)(mp_Add(A , B, currRing));
+  if (res->data==NULL)
+  {
+     Werror("matrix size not compatible(%dx%d, %dx%d)",
+             MATROWS(A),MATCOLS(A),MATROWS(B),MATCOLS(B));
+     return TRUE;
+  }
+  return jjPLUSMINUS_Gen(res,u,v);
+}
+static BOOLEAN jjPLUS_MA_P(leftv res, leftv u, leftv v)
+{
+  matrix m=(matrix)u->Data();
+  matrix p= mp_InitP(m->nrows,m->ncols,(poly)(v->CopyD(POLY_CMD)),currRing);
+  if (iiOp=='+')
+    res->data = (char *)mp_Add(m , p,currRing);
+  else
+    res->data = (char *)mp_Sub(m , p,currRing);
+  idDelete((ideal *)&p);
+  return jjPLUSMINUS_Gen(res,u,v);
+}
+static BOOLEAN jjPLUS_P_MA(leftv res, leftv u, leftv v)
+{
+  return jjPLUS_MA_P(res,v,u);
+}
+static BOOLEAN jjPLUS_S(leftv res, leftv u, leftv v)
+{
+  char*    a = (char * )(u->Data());
+  char*    b = (char * )(v->Data());
+  char*    r = (char * )omAlloc(strlen(a) + strlen(b) + 1);
+  strcpy(r,a);
+  strcat(r,b);
+  res->data=r;
+  return jjPLUSMINUS_Gen(res,u,v);
+}
+static BOOLEAN jjPLUS_ID(leftv res, leftv u, leftv v)
+{
+  res->data = (char *)idAdd((ideal)u->Data(),(ideal)v->Data());
+  return jjPLUSMINUS_Gen(res,u,v);
+}
+static BOOLEAN jjMINUS_I(leftv res, leftv u, leftv v)
+{
+  void *ap=u->Data(); void *bp=v->Data();
+  int aa=(int)(long)ap;
+  int bb=(int)(long)bp;
+  int cc=aa-bb;
+  unsigned int a=(unsigned int)(unsigned long)ap;
+  unsigned int b=(unsigned int)(unsigned long)bp;
+  unsigned int c=a-b;
+  if (((Sy_bit(31)&a)!=(Sy_bit(31)&b))&&((Sy_bit(31)&a)!=(Sy_bit(31)&c)))
+  {
+    WarnS("int overflow(-), result may be wrong");
+  }
+  res->data = (char *)((long)cc);
+  return jjPLUSMINUS_Gen(res,u,v);
+}
+static BOOLEAN jjMINUS_BI(leftv res, leftv u, leftv v)
+{
+  res->data = (char *)(n_Sub((number)u->Data(), (number)v->Data(),coeffs_BIGINT));
+  return jjPLUSMINUS_Gen(res,u,v);
+}
+static BOOLEAN jjMINUS_N(leftv res, leftv u, leftv v)
+{
+  res->data = (char *)(nSub((number)u->Data(), (number)v->Data()));
+  return jjPLUSMINUS_Gen(res,u,v);
+}
+static BOOLEAN jjMINUS_P(leftv res, leftv u, leftv v)
+{
+  res->data = (char *)(pSub((poly)u->CopyD(POLY_CMD) , (poly)v->CopyD(POLY_CMD)));
+  return jjPLUSMINUS_Gen(res,u,v);
+}
+static BOOLEAN jjMINUS_IV(leftv res, leftv u, leftv v)
+{
+  res->data = (char *)ivSub((intvec*)(u->Data()), (intvec*)(v->Data()));
+  if (res->data==NULL)
+  {
+     WerrorS("intmat size not compatible");
+     return TRUE;
+  }
+  return jjPLUSMINUS_Gen(res,u,v);
+}
+static BOOLEAN jjMINUS_BIM(leftv res, leftv u, leftv v)
+{
+  res->data = (char *)bimSub((bigintmat*)(u->Data()), (bigintmat*)(v->Data()));
+  if (res->data==NULL)
+  {
+    WerrorS("bigintmat/cmatrix not compatible");
+    return TRUE;
+  }
+  return jjPLUSMINUS_Gen(res,u,v);
+}
+static BOOLEAN jjMINUS_MA(leftv res, leftv u, leftv v)
+{
+  matrix A=(matrix)u->Data(); matrix B=(matrix)v->Data();
+  res->data = (char *)(mp_Sub(A , B, currRing));
+  if (res->data==NULL)
+  {
+     Werror("matrix size not compatible(%dx%d, %dx%d)",
+             MATROWS(A),MATCOLS(A),MATROWS(B),MATCOLS(B));
+     return TRUE;
+  }
+  return jjPLUSMINUS_Gen(res,u,v);
+  return FALSE;
+}
+static BOOLEAN jjTIMES_I(leftv res, leftv u, leftv v)
+{
+  int a=(int)(long)u->Data();
+  int b=(int)(long)v->Data();
+  int64 c=(int64)a * (int64)b;
+  if ((c>INT_MAX)||(c<INT_MIN))
+    WarnS("int overflow(*), result may be wrong");
+  res->data = (char *)((long)((int)c));
+  if ((u->Next()!=NULL) || (v->Next()!=NULL))
+    return jjOP_REST(res,u,v);
+  return FALSE;
+}
+static BOOLEAN jjTIMES_BI(leftv res, leftv u, leftv v)
+{
+  res->data = (char *)(n_Mult( (number)u->Data(), (number)v->Data(),coeffs_BIGINT));
+  if ((v->next!=NULL) || (u->next!=NULL))
+    return jjOP_REST(res,u,v);
+  return FALSE;
+}
+static BOOLEAN jjTIMES_N(leftv res, leftv u, leftv v)
+{
+  res->data = (char *)(nMult( (number)u->Data(), (number)v->Data()));
+  number n=(number)res->data;
+  nNormalize(n);
+  res->data=(char *)n;
+  if ((v->next!=NULL) || (u->next!=NULL))
+    return jjOP_REST(res,u,v);
+  return FALSE;
+}
+static BOOLEAN jjTIMES_P(leftv res, leftv u, leftv v)
+{
+  poly a;
+  poly b;
+  if (v->next==NULL)
+  {
+    a=(poly)u->CopyD(POLY_CMD); // works also for VECTOR_CMD
+    if (u->next==NULL)
+    {
+      b=(poly)v->CopyD(POLY_CMD); // works also for VECTOR_CMD
+      if ((a!=NULL) && (b!=NULL)
+      && ((long)pTotaldegree(a)>si_max((long)rVar(currRing),(long)currRing->bitmask/2)-(long)pTotaldegree(b)))
+      {
+        Warn("possible OVERFLOW in mult(d=%ld, d=%ld, max=%ld)",
+          pTotaldegree(a),pTotaldegree(b),currRing->bitmask/2);
+      }
+      res->data = (char *)(pMult( a, b));
+      pNormalize((poly)res->data);
+      return FALSE;
+    }
+    // u->next exists: copy v
+    b=pCopy((poly)v->Data());
+    if ((a!=NULL) && (b!=NULL)
+    && (pTotaldegree(a)+pTotaldegree(b)>si_max((long)rVar(currRing),(long)currRing->bitmask/2)))
+    {
+      Warn("possible OVERFLOW in mult(d=%ld, d=%ld, max=%ld)",
+          pTotaldegree(a),pTotaldegree(b),currRing->bitmask/2);
+    }
+    res->data = (char *)(pMult( a, b));
+    pNormalize((poly)res->data);
+    return jjOP_REST(res,u,v);
+  }
+  // v->next exists: copy u
+  a=pCopy((poly)u->Data());
+  b=(poly)v->CopyD(POLY_CMD); // works also for VECTOR_CMD
+  if ((a!=NULL) && (b!=NULL)
+  && ((unsigned long)(pTotaldegree(a)+pTotaldegree(b))>=currRing->bitmask/2))
+  {
+    pDelete(&a);
+    pDelete(&b);
+    WerrorS("OVERFLOW");
+    return TRUE;
+  }
+  res->data = (char *)(pMult( a, b));
+  pNormalize((poly)res->data);
+  return jjOP_REST(res,u,v);
+}
+static BOOLEAN jjTIMES_ID(leftv res, leftv u, leftv v)
+{
+  res->data = (char *)idMult((ideal)u->Data(),(ideal)v->Data());
+  id_Normalize((ideal)res->data,currRing);
+  if ((v->next!=NULL) || (u->next!=NULL))
+    return jjOP_REST(res,u,v);
+  return FALSE;
+}
+static BOOLEAN jjTIMES_IV(leftv res, leftv u, leftv v)
+{
+  res->data = (char *)ivMult((intvec*)(u->Data()), (intvec*)(v->Data()));
+  if (res->data==NULL)
+  {
+     WerrorS("intmat size not compatible");
+     return TRUE;
+  }
+  if ((v->next!=NULL) || (u->next!=NULL))
+    return jjOP_REST(res,u,v);
+  return FALSE;
+}
+static BOOLEAN jjTIMES_BIM(leftv res, leftv u, leftv v)
+{
+  res->data = (char *)bimMult((bigintmat*)(u->Data()), (bigintmat*)(v->Data()));
+  if (res->data==NULL)
+  {
+    WerrorS("bigintmat/cmatrix not compatible");
+    return TRUE;
+  }
+  if ((v->next!=NULL) || (u->next!=NULL))
+    return jjOP_REST(res,u,v);
+  return FALSE;
+}
+static BOOLEAN jjTIMES_MA_BI1(leftv res, leftv u, leftv v)
+{
+  nMapFunc nMap=n_SetMap(coeffs_BIGINT,currRing->cf);
+  if (nMap==NULL) return TRUE;
+  number n=nMap((number)v->Data(),coeffs_BIGINT,currRing->cf);
+  poly p=pNSet(n);
+  ideal I= (ideal)mp_MultP((matrix)u->CopyD(MATRIX_CMD),p,currRing);
+  res->data = (char *)I;
+  return FALSE;
+}
+static BOOLEAN jjTIMES_MA_BI2(leftv res, leftv u, leftv v)
+{
+  return jjTIMES_MA_BI1(res,v,u);
+}
+static BOOLEAN jjTIMES_MA_P1(leftv res, leftv u, leftv v)
+{
+  poly p=(poly)v->CopyD(POLY_CMD);
+  int r=pMaxComp(p);/* recompute the rank for the case ideal*vector*/
+  ideal I= (ideal)mp_MultP((matrix)u->CopyD(MATRIX_CMD),p,currRing);
+  if (r>0) I->rank=r;
+  id_Normalize(I,currRing);
+  res->data = (char *)I;
+  return FALSE;
+}
+static BOOLEAN jjTIMES_MA_P2(leftv res, leftv u, leftv v)
+{
+  poly p=(poly)u->CopyD(POLY_CMD);
+  int r=pMaxComp(p);/* recompute the rank for the case ideal*vector*/
+  ideal I= (ideal)pMultMp(p,(matrix)v->CopyD(MATRIX_CMD),currRing);
+  if (r>0) I->rank=r;
+  id_Normalize(I,currRing);
+  res->data = (char *)I;
+  return FALSE;
+}
+static BOOLEAN jjTIMES_MA_N1(leftv res, leftv u, leftv v)
+{
+  number n=(number)v->CopyD(NUMBER_CMD);
+  poly p=pNSet(n);
+  res->data = (char *)mp_MultP((matrix)u->CopyD(MATRIX_CMD),p,currRing);
+  id_Normalize((ideal)res->data,currRing);
+  return FALSE;
+}
+static BOOLEAN jjTIMES_MA_N2(leftv res, leftv u, leftv v)
+{
+  return jjTIMES_MA_N1(res,v,u);
+}
+static BOOLEAN jjTIMES_MA_I1(leftv res, leftv u, leftv v)
+{
+  res->data = (char *)mp_MultI((matrix)u->CopyD(MATRIX_CMD),(int)(long)v->Data(),currRing);
+  id_Normalize((ideal)res->data,currRing);
+  return FALSE;
+}
+static BOOLEAN jjTIMES_MA_I2(leftv res, leftv u, leftv v)
+{
+  return jjTIMES_MA_I1(res,v,u);
+}
+static BOOLEAN jjTIMES_MA(leftv res, leftv u, leftv v)
+{
+  matrix A=(matrix)u->Data(); matrix B=(matrix)v->Data();
+  res->data = (char *)mp_Mult(A,B,currRing);
+  if (res->data==NULL)
+  {
+     Werror("matrix size not compatible(%dx%d, %dx%d)",
+             MATROWS(A),MATCOLS(A),MATROWS(B),MATCOLS(B));
+     return TRUE;
+  }
+  id_Normalize((ideal)res->data,currRing);
+  if ((v->next!=NULL) || (u->next!=NULL))
+    return jjOP_REST(res,u,v);
+  return FALSE;
+}
+static BOOLEAN jjGE_BI(leftv res, leftv u, leftv v)
+{
+  number h=n_Sub((number)u->Data(),(number)v->Data(),coeffs_BIGINT);
+  res->data = (char *) (n_GreaterZero(h,coeffs_BIGINT)||(n_IsZero(h,coeffs_BIGINT)));
+  n_Delete(&h,coeffs_BIGINT);
+  return FALSE;
+}
+static BOOLEAN jjGE_I(leftv res, leftv u, leftv v)
+{
+  res->data = (char *)(long)((int)((long)u->Data()) >= (int)((long)v->Data()));
+  return FALSE;
+}
+static BOOLEAN jjGE_N(leftv res, leftv u, leftv v)
+{
+  res->data = (char *)(long) (nGreater((number)u->Data(),(number)v->Data())
+                       || nEqual((number)u->Data(),(number)v->Data()));
+  return FALSE;
+}
+static BOOLEAN jjGT_BI(leftv res, leftv u, leftv v)
+{
+  number h=n_Sub((number)u->Data(),(number)v->Data(),coeffs_BIGINT);
+  res->data = (char *)(long) (n_GreaterZero(h,coeffs_BIGINT)&&(!n_IsZero(h,coeffs_BIGINT)));
+  n_Delete(&h,coeffs_BIGINT);
+  return FALSE;
+}
+static BOOLEAN jjGT_I(leftv res, leftv u, leftv v)
+{
+  res->data = (char *)(long)((int)((long)u->Data()) > (int)((long)v->Data()));
+  return FALSE;
+}
+static BOOLEAN jjGT_N(leftv res, leftv u, leftv v)
+{
+  res->data = (char *)(long)(nGreater((number)u->Data(),(number)v->Data()));
+  return FALSE;
+}
+static BOOLEAN jjLE_BI(leftv res, leftv u, leftv v)
+{
+  return jjGE_BI(res,v,u);
+}
+static BOOLEAN jjLE_I(leftv res, leftv u, leftv v)
+{
+  res->data = (char *)(long)((int)((long)u->Data()) <= (int)((long)v->Data()));
+  return FALSE;
+}
+static BOOLEAN jjLE_N(leftv res, leftv u, leftv v)
+{
+  return jjGE_N(res,v,u);
+}
+static BOOLEAN jjLT_BI(leftv res, leftv u, leftv v)
+{
+  return jjGT_BI(res,v,u);
+}
+static BOOLEAN jjLT_I(leftv res, leftv u, leftv v)
+{
+  res->data = (char *)(long)((int)((long)u->Data()) < (int)((long)v->Data()));
+  return FALSE;
+}
+static BOOLEAN jjLT_N(leftv res, leftv u, leftv v)
+{
+  return jjGT_N(res,v,u);
+}
+static BOOLEAN jjDIVMOD_I(leftv res, leftv u, leftv v)
+{
+  if (iiOp=='/') Warn("int division with `/`: use `div` instead in line >>%s<<",my_yylinebuf);
+  int a= (int)(long)u->Data();
+  int b= (int)(long)v->Data();
+  if (b==0)
+  {
+    WerrorS(ii_div_by_0);
+    return TRUE;
+  }
+  int c=a%b;
+  int r=0;
+  switch (iiOp)
+  {
+    case '%':
+        r=c;            break;
+    case '/':
+    case INTDIV_CMD:
+        r=((a-c) /b);   break;
+  }
+  res->data=(void *)((long)r);
+  return FALSE;
+}
+static BOOLEAN jjDIV_BI(leftv res, leftv u, leftv v)
+{
+  number q=(number)v->Data();
+  if (n_IsZero(q,coeffs_BIGINT))
+  {
+    WerrorS(ii_div_by_0);
+    return TRUE;
+  }
+  q = n_Div((number)u->Data(),q,coeffs_BIGINT);
+  n_Normalize(q,coeffs_BIGINT);
+  res->data = (char *)q;
+  return FALSE;
+}
+static BOOLEAN jjDIV_N(leftv res, leftv u, leftv v)
+{
+  number q=(number)v->Data();
+  if (nIsZero(q))
+  {
+    WerrorS(ii_div_by_0);
+    return TRUE;
+  }
+  q = nDiv((number)u->Data(),q);
+  nNormalize(q);
+  res->data = (char *)q;
+  return FALSE;
+}
+static BOOLEAN jjDIV_P(leftv res, leftv u, leftv v)
+{
+  poly q=(poly)v->Data();
+  if (q==NULL)
+  {
+    WerrorS(ii_div_by_0);
+    return TRUE;
+  }
+  poly p=(poly)(u->Data());
+  if (p==NULL)
+  {
+    res->data=NULL;
+    return FALSE;
+  }
+  if ((pNext(q)!=NULL) && (!rField_is_Ring(currRing)))
+  { /* This means that q != 0 consists of at least two terms.
+       Moreover, currRing is over a field. */
+    if(pGetComp(p)==0)
+    {
+      res->data=(void*)(singclap_pdivide(p /*(poly)(u->Data())*/ ,
+                                         q /*(poly)(v->Data())*/ ,currRing));
+    }
+    else
+    {
+      int comps=pMaxComp(p);
+      ideal I=idInit(comps,1);
+      p=pCopy(p);
+      poly h;
+      int i;
+      // conversion to a list of polys:
+      while (p!=NULL)
+      {
+        i=pGetComp(p)-1;
+        h=pNext(p);
+        pNext(p)=NULL;
+        pSetComp(p,0);
+        I->m[i]=pAdd(I->m[i],p);
+        p=h;
+      }
+      // division and conversion to vector:
+      h=NULL;
+      p=NULL;
+      for(i=comps-1;i>=0;i--)
+      {
+        if (I->m[i]!=NULL)
+        {
+          h=singclap_pdivide(I->m[i],q,currRing);
+          pSetCompP(h,i+1);
+          p=pAdd(p,h);
+        }
+      }
+      idDelete(&I);
+      res->data=(void *)p;
+    }
+  }
+  else
+  { /* This means that q != 0 consists of just one term,
+       or that currRing is over a coefficient ring. */
+#ifdef HAVE_RINGS
+    if (!rField_is_Domain(currRing))
+    {
+      WerrorS("division only defined over coefficient domains");
+      return TRUE;
+    }
+    if (pNext(q)!=NULL)
+    {
+      WerrorS("division over a coefficient domain only implemented for terms");
+      return TRUE;
+    }
+#endif
+    res->data = (char *)pDivideM(pCopy(p),pHead(q));
+  }
+  pNormalize((poly)res->data);
+  return FALSE;
+}
+static BOOLEAN jjDIV_Ma(leftv res, leftv u, leftv v)
+{
+  poly q=(poly)v->Data();
+  if (q==NULL)
+  {
+    WerrorS(ii_div_by_0);
+    return TRUE;
+  }
+  matrix m=(matrix)(u->Data());
+  int r=m->rows();
+  int c=m->cols();
+  matrix mm=mpNew(r,c);
+  int i,j;
+  for(i=r;i>0;i--)
+  {
+    for(j=c;j>0;j--)
+    {
+      if (pNext(q)!=NULL)
+      {
+        MATELEM(mm,i,j) = singclap_pdivide( MATELEM(m,i,j) ,
+                                           q /*(poly)(v->Data())*/, currRing );
+      }
+      else
+        MATELEM(mm,i,j) = pDivideM(pCopy(MATELEM(m,i,j)),pHead(q));
+    }
+  }
+  id_Normalize((ideal)mm,currRing);
+  res->data=(char *)mm;
+  return FALSE;
+}
+static BOOLEAN jjEQUAL_BI(leftv res, leftv u, leftv v)
+{
+  res->data = (char *)((long)n_Equal((number)u->Data(),(number)v->Data(),coeffs_BIGINT));
+  jjEQUAL_REST(res,u,v);
+  return FALSE;
+}
+static BOOLEAN jjEQUAL_I(leftv res, leftv u, leftv v)
+{
+  res->data = (char *)((int)((long)u->Data()) == (int)((long)v->Data()));
+  jjEQUAL_REST(res,u,v);
+  return FALSE;
+}
+static BOOLEAN jjEQUAL_Ma(leftv res, leftv u, leftv v)
+{
+  res->data = (char *)((long)mp_Equal((matrix)u->Data(),(matrix)v->Data(),currRing));
+  jjEQUAL_REST(res,u,v);
+  return FALSE;
+}
+static BOOLEAN jjEQUAL_N(leftv res, leftv u, leftv v)
+{
+  res->data = (char *)((long)nEqual((number)u->Data(),(number)v->Data()));
+  jjEQUAL_REST(res,u,v);
+  return FALSE;
+}
+static BOOLEAN jjEQUAL_P(leftv res, leftv u, leftv v)
+{
+  poly p=(poly)u->Data();
+  poly q=(poly)v->Data();
+  res->data = (char *) ((long)pEqualPolys(p,q));
+  jjEQUAL_REST(res,u,v);
+  return FALSE;
+}
+static void jjEQUAL_REST(leftv res,leftv u,leftv v)
+{
+  if ((res->data) && (u->next!=NULL) && (v->next!=NULL))
+  {
+    int save_iiOp=iiOp;
+    if (iiOp==NOTEQUAL)
+      iiExprArith2(res,u->next,EQUAL_EQUAL,v->next);
+    else
+      iiExprArith2(res,u->next,iiOp,v->next);
+    iiOp=save_iiOp;
+  }
+  if (iiOp==NOTEQUAL) res->data=(char *)(!(long)res->data);
+}
+static BOOLEAN jjAND_I(leftv res, leftv u, leftv v)
+{
+  res->data = (char *)((long)u->Data() && (long)v->Data());
+  return FALSE;
+}
+static BOOLEAN jjOR_I(leftv res, leftv u, leftv v)
+{
+  res->data = (char *)((long)u->Data() || (long)v->Data());
+  return FALSE;
+}
+static BOOLEAN jjINDEX_I(leftv res, leftv u, leftv v)
+{
+  res->rtyp=u->rtyp; u->rtyp=0;
+  res->data=u->data; u->data=NULL;
+  res->name=u->name; u->name=NULL;
+  res->e=u->e;       u->e=NULL;
+  if (res->e==NULL) res->e=jjMakeSub(v);
+  else
+  {
+    Subexpr sh=res->e;
+    while (sh->next != NULL) sh=sh->next;
+    sh->next=jjMakeSub(v);
+  }
+  if (u->next!=NULL)
+  {
+    leftv rn=(leftv)omAlloc0Bin(sleftv_bin);
+    BOOLEAN bo=iiExprArith2(rn,u->next,iiOp,v);
+    res->next=rn;
+    return bo;
+  }
+  return FALSE;
+}
+static BOOLEAN jjINDEX_IV(leftv res, leftv u, leftv v)
+{
+  if ((u->rtyp!=IDHDL)||(u->e!=NULL))
+  {
+    WerrorS("indexed object must have a name");
+    return TRUE;
+  }
+  intvec * iv=(intvec *)v->Data();
+  leftv p=NULL;
+  int i;
+  sleftv t;
+  memset(&t,0,sizeof(t));
+  t.rtyp=INT_CMD;
+  for (i=0;i<iv->length(); i++)
+  {
+    t.data=(char *)((long)(*iv)[i]);
+    if (p==NULL)
+    {
+      p=res;
+    }
+    else
+    {
+      p->next=(leftv)omAlloc0Bin(sleftv_bin);
+      p=p->next;
+    }
+    p->rtyp=IDHDL;
+    p->data=u->data;
+    p->name=u->name;
+    p->flag=u->flag;
+    p->e=jjMakeSub(&t);
+  }
+  u->rtyp=0;
+  u->data=NULL;
+  u->name=NULL;
+  return FALSE;
+}
+static BOOLEAN jjINDEX_P(leftv res, leftv u, leftv v)
+{
+  poly p=(poly)u->Data();
+  int i=(int)(long)v->Data();
+  int j=0;
+  while (p!=NULL)
+  {
+    j++;
+    if (j==i)
+    {
+      res->data=(char *)pHead(p);
+      return FALSE;
+    }
+    pIter(p);
+  }
+  return FALSE;
+}
+static BOOLEAN jjINDEX_P_IV(leftv res, leftv u, leftv v)
+{
+  poly p=(poly)u->Data();
+  poly r=NULL;
+  intvec *iv=(intvec *)v->CopyD(INTVEC_CMD);
+  int i;
+  int sum=0;
+  for(i=iv->length()-1;i>=0;i--)
+    sum+=(*iv)[i];
+  int j=0;
+  while ((p!=NULL) && (sum>0))
+  {
+    j++;
+    for(i=iv->length()-1;i>=0;i--)
+    {
+      if (j==(*iv)[i])
+      {
+        r=pAdd(r,pHead(p));
+        sum-=j;
+        (*iv)[i]=0;
+        break;
+      }
+    }
+    pIter(p);
+  }
+  delete iv;
+  res->data=(char *)r;
+  return FALSE;
+}
+static BOOLEAN jjINDEX_V(leftv res, leftv u, leftv v)
+{
+  poly p=(poly)u->CopyD(VECTOR_CMD);
+  poly r=p; // pointer to the beginning of component i
+  poly o=NULL;
+  unsigned i=(unsigned)(long)v->Data();
+  while (p!=NULL)
+  {
+    if (pGetComp(p)!=i)
+    {
+      if (r==p) r=pNext(p);
+      if (o!=NULL)
+      {
+        if (pNext(o)!=NULL) pLmDelete(&pNext(o));
+        p=pNext(o);
+      }
+      else
+        pLmDelete(&p);
+    }
+    else
+    {
+      pSetComp(p, 0);
+      p_SetmComp(p, currRing);
+      o=p;
+      p=pNext(o);
+    }
+  }
+  res->data=(char *)r;
+  return FALSE;
+}
+static BOOLEAN jjINDEX_V_IV(leftv res, leftv u, leftv v)
+{
+  poly p=(poly)u->CopyD(VECTOR_CMD);
+  if (p!=NULL)
+  {
+    poly r=pOne();
+    poly hp=r;
+    intvec *iv=(intvec *)v->Data();
+    int i;
+    loop
+    {
+      for(i=0;i<iv->length();i++)
+      {
+        if (((int)pGetComp(p))==(*iv)[i])
+        {
+          poly h;
+          pSplit(p,&h);
+          pNext(hp)=p;
+          p=h;
+          pIter(hp);
+          break;
+        }
+      }
+      if (p==NULL) break;
+      if (i==iv->length())
+      {
+        pLmDelete(&p);
+        if (p==NULL) break;
+      }
+    }
+    pLmDelete(&r);
+    res->data=(char *)r;
+  }
+  return FALSE;
+}
+static BOOLEAN jjKLAMMER_rest(leftv res, leftv u, leftv v);
+static BOOLEAN jjKLAMMER(leftv res, leftv u, leftv v)
+{
+  if(u->name==NULL) return TRUE;
+  char * nn = (char *)omAlloc(strlen(u->name) + 14);
+  sprintf(nn,"%s(%d)",u->name,(int)(long)v->Data());
+  omFree((ADDRESS)u->name);
+  u->name=NULL;
+  char *n=omStrDup(nn);
+  omFree((ADDRESS)nn);
+  syMake(res,n);
+  if (u->next!=NULL) return jjKLAMMER_rest(res,u->next,v);
+  return FALSE;
+}
+static BOOLEAN jjKLAMMER_IV(leftv res, leftv u, leftv v)
+{
+  intvec * iv=(intvec *)v->Data();
+  leftv p=NULL;
+  int i;
+  long slen = strlen(u->name) + 14;
+  char *n = (char*) omAlloc(slen);
+
+  for (i=0;i<iv->length(); i++)
+  {
+    if (p==NULL)
+    {
+      p=res;
+    }
+    else
+    {
+      p->next=(leftv)omAlloc0Bin(sleftv_bin);
+      p=p->next;
+    }
+    sprintf(n,"%s(%d)",u->name,(*iv)[i]);
+    syMake(p,omStrDup(n));
+  }
+  omFree((ADDRESS)u->name);
+  u->name = NULL;
+  omFreeSize(n, slen);
+  if (u->next!=NULL) return jjKLAMMER_rest(res,u->next,v);
+  return FALSE;
+}
+static BOOLEAN jjKLAMMER_rest(leftv res, leftv u, leftv v)
+{
+  leftv tmp=(leftv)omAllocBin(sleftv_bin);
+  memset(tmp,0,sizeof(sleftv));
+  BOOLEAN b;
+  if (v->Typ()==INTVEC_CMD)
+    b=jjKLAMMER_IV(tmp,u,v);
+  else
+    b=jjKLAMMER(tmp,u,v);
+  if (b)
+  {
+    omFreeBin(tmp,sleftv_bin);
+    return TRUE;
+  }
+  leftv h=res;
+  while (h->next!=NULL) h=h->next;
+  h->next=tmp;
+  return FALSE;
+}
+BOOLEAN jjPROC(leftv res, leftv u, leftv v)
+{
+  void *d;
+  Subexpr e;
+  int typ;
+  BOOLEAN t=FALSE;
+  idhdl tmp_proc=NULL;
+  if ((u->rtyp!=IDHDL)||(u->e!=NULL))
+  {
+    tmp_proc=(idhdl)omAlloc0(sizeof(idrec));
+    tmp_proc->id="_auto";
+    tmp_proc->typ=PROC_CMD;
+    tmp_proc->data.pinf=(procinfo *)u->Data();
+    tmp_proc->ref=1;
+    d=u->data; u->data=(void *)tmp_proc;
+    e=u->e; u->e=NULL;
+    t=TRUE;
+    typ=u->rtyp; u->rtyp=IDHDL;
+  }
+  BOOLEAN sl;
+  if (u->req_packhdl==currPack)
+    sl = iiMake_proc((idhdl)u->data,NULL,v);
+  else
+    sl = iiMake_proc((idhdl)u->data,u->req_packhdl,v);
+  if (t)
+  {
+    u->rtyp=typ;
+    u->data=d;
+    u->e=e;
+    omFreeSize(tmp_proc,sizeof(idrec));
+  }
+  if (sl) return TRUE;
+  memcpy(res,&iiRETURNEXPR,sizeof(sleftv));
+  iiRETURNEXPR.Init();
+  return FALSE;
+}
+static BOOLEAN jjMAP(leftv res, leftv u, leftv v)
+{
+  //Print("try to map %s with %s\n",$3.Name(),$1.Name());
+  leftv sl=NULL;
+  if ((v->e==NULL)&&(v->name!=NULL))
+  {
+    map m=(map)u->Data();
+    sl=iiMap(m,v->name);
+  }
+  else
+  {
+    Werror("%s(<name>) expected",u->Name());
+  }
+  if (sl==NULL) return TRUE;
+  memcpy(res,sl,sizeof(sleftv));
+  omFreeBin((ADDRESS)sl, sleftv_bin);
+  return FALSE;
+}
+static BOOLEAN jjCHINREM_BI(leftv res, leftv u, leftv v)
+{
+  intvec *c=(intvec*)u->Data();
+  intvec* p=(intvec*)v->Data();
+  int rl=p->length();
+  number *x=(number *)omAlloc(rl*sizeof(number));
+  number *q=(number *)omAlloc(rl*sizeof(number));
+  int i;
+  for(i=rl-1;i>=0;i--)
+  {
+    q[i]=n_Init((*p)[i], coeffs_BIGINT);
+    x[i]=n_Init((*c)[i], coeffs_BIGINT);
+  }
+  number n=n_ChineseRemainderSym(x,q,rl,FALSE,coeffs_BIGINT);
+  for(i=rl-1;i>=0;i--)
+  {
+    n_Delete(&(q[i]),coeffs_BIGINT);
+    n_Delete(&(x[i]),coeffs_BIGINT);
+  }
+  omFree(x); omFree(q);
+  res->data=(char *)n;
+  return FALSE;
+}
+#if 0
+static BOOLEAN jjCHINREM_P(leftv res, leftv u, leftv v)
+{
+  lists c=(lists)u->CopyD(); // list of poly
+  intvec* p=(intvec*)v->Data();
+  int rl=p->length();
+  poly r=NULL,h, result=NULL;
+  number *x=(number *)omAlloc(rl*sizeof(number));
+  number *q=(number *)omAlloc(rl*sizeof(number));
+  int i;
+  for(i=rl-1;i>=0;i--)
+  {
+    q[i]=nlInit((*p)[i]);
+  }
+  loop
+  {
+    for(i=rl-1;i>=0;i--)
+    {
+      if (c->m[i].Typ()!=POLY_CMD)
+      {
+        Werror("poly expected at pos %d",i+1);
+        for(i=rl-1;i>=0;i--)
+        {
+          nlDelete(&(q[i]),currRing);
+        }
+        omFree(x); omFree(q); // delete c
+        return TRUE;
+      }
+      h=((poly)c->m[i].Data());
+      if (r==NULL) r=h;
+      else if (pLmCmp(r,h)==-1) r=h;
+    }
+    if (r==NULL) break;
+    for(i=rl-1;i>=0;i--)
+    {
+      h=((poly)c->m[i].Data());
+      if (pLmCmp(r,h)==0)
+      {
+        x[i]=pGetCoeff(h);
+        h=pLmFreeAndNext(h);
+        c->m[i].data=(char*)h;
+      }
+      else
+        x[i]=nlInit(0);
+    }
+    number n=n_ChineseRemainder(x,q,rl,currRing->cf);
+    for(i=rl-1;i>=0;i--)
+    {
+      nlDelete(&(x[i]),currRing);
+    }
+    h=pHead(r);
+    pSetCoeff(h,n);
+    result=pAdd(result,h);
+  }
+  for(i=rl-1;i>=0;i--)
+  {
+    nlDelete(&(q[i]),currRing);
+  }
+  omFree(x); omFree(q);
+  res->data=(char *)result;
+  return FALSE;
+}
+#endif
+static BOOLEAN jjCHINREM_ID(leftv res, leftv u, leftv v)
+{
+  coeffs cf;
+  lists c=(lists)u->CopyD(); // list of ideal or bigint/int
+  lists pl=NULL;
+  intvec *p=NULL;
+  if (v->Typ()==LIST_CMD) pl=(lists)v->Data();
+  else                    p=(intvec*)v->Data();
+  int rl=c->nr+1;
+  ideal result;
+  ideal *x=(ideal *)omAlloc(rl*sizeof(ideal));
+  number *xx=NULL;
+  int i;
+  int return_type=c->m[0].Typ();
+  if ((return_type!=IDEAL_CMD)
+  && (return_type!=MODUL_CMD)
+  && (return_type!=MATRIX_CMD)
+  && (return_type!=POLY_CMD))
+  {
+    if((return_type!=BIGINT_CMD)&&(return_type!=INT_CMD))
+    {
+      WerrorS("poly/ideal/module/matrix expected");
+      omFree(x); // delete c
+      return TRUE;
+    }
+    else
+      return_type=BIGINT_CMD;
+  }
+  if (return_type==BIGINT_CMD)
+    cf=coeffs_BIGINT;
+  else
+  {
+    cf=currRing->cf;
+    if (nCoeff_is_Extension(cf) && (cf->extRing!=NULL))
+      cf=cf->extRing->cf;
+  }
+  nMapFunc nMap=n_SetMap(coeffs_BIGINT,cf);
+  if (return_type!=BIGINT_CMD)
+  {
+    for(i=rl-1;i>=0;i--)
+    {
+      if (c->m[i].Typ()!=return_type)
+      {
+        Werror("%s expected at pos %d",Tok2Cmdname(return_type),i+1);
+        omFree(x); // delete c
+        return TRUE;
+      }
+      if (return_type==POLY_CMD)
+      {
+        x[i]=idInit(1,1);
+        x[i]->m[0]=(poly)c->m[i].CopyD();
+      }
+      else
+      {
+        x[i]=(ideal)c->m[i].CopyD();
+      }
+      //c->m[i].Init();
+    }
+  }
+  else
+  {
+    xx=(number *)omAlloc(rl*sizeof(number));
+    if (nMap==NULL)
+    {
+      Werror("not implemented: map bigint -> %s", nCoeffString(cf));
+      return TRUE;
+    }
+    for(i=rl-1;i>=0;i--)
+    {
+      if (c->m[i].Typ()==INT_CMD)
+      {
+        xx[i]=n_Init(((int)(long)c->m[i].Data()),cf);
+      }
+      else if (c->m[i].Typ()==BIGINT_CMD)
+      {
+        xx[i]=nMap((number)c->m[i].Data(),coeffs_BIGINT,cf);
+      }
+      else
+      {
+        Werror("bigint expected at pos %d",i+1);
+        omFree(x); // delete c
+        omFree(xx); // delete c
+        return TRUE;
+      }
+    }
+  }
+  number *q=(number *)omAlloc(rl*sizeof(number));
+  if (p!=NULL)
+  {
+    for(i=rl-1;i>=0;i--)
+    {
+      q[i]=n_Init((*p)[i], cf);
+    }
+  }
+  else
+  {
+    for(i=rl-1;i>=0;i--)
+    {
+      if (pl->m[i].Typ()==INT_CMD)
+      {
+        q[i]=n_Init((int)(long)pl->m[i].Data(),cf);
+      }
+      else if (pl->m[i].Typ()==BIGINT_CMD)
+      {
+        q[i]=nMap((number)(pl->m[i].Data()),coeffs_BIGINT,cf);
+      }
+      else
+      {
+        Werror("bigint expected at pos %d",i+1);
+        for(i++;i<rl;i++)
+        {
+          n_Delete(&(q[i]),cf);
+        }
+        omFree(x); // delete c
+        omFree(q); // delete pl
+        if (xx!=NULL) omFree(xx); // delete c
+        return TRUE;
+      }
+    }
+  }
+  if (return_type==BIGINT_CMD)
+  {
+    number n=n_ChineseRemainderSym(xx,q,rl,TRUE,coeffs_BIGINT);
+    res->data=(char *)n;
+  }
+  else
+  {
+    result=id_ChineseRemainder(x,q,rl,currRing);
+    // deletes also x
+    c->Clean();
+    if (return_type==POLY_CMD)
+    {
+      res->data=(char *)result->m[0];
+      result->m[0]=NULL;
+      idDelete(&result);
+    }
+    else
+      res->data=(char *)result;
+  }
+  for(i=rl-1;i>=0;i--)
+  {
+    n_Delete(&(q[i]),cf);
+  }
+  omFree(q);
+  res->rtyp=return_type;
+  return FALSE;
+}
+static BOOLEAN jjCOEF(leftv res, leftv u, leftv v)
+{
+  poly p=(poly)v->Data();
+  if ((p==NULL)||(pNext(p)!=NULL)) return TRUE;
+  res->data=(char *)mp_CoeffProc((poly)u->Data(),p /*(poly)v->Data()*/,currRing);
+  return FALSE;
+}
+static BOOLEAN jjCOEFFS_Id(leftv res, leftv u, leftv v)
+{
+  int i=pVar((poly)v->Data());
+  if (i==0)
+  {
+    WerrorS("ringvar expected");
+    return TRUE;
+  }
+  res->data=(char *)mp_Coeffs((ideal)u->CopyD(),i,currRing);
+  return FALSE;
+}
+static BOOLEAN jjCOEFFS2_KB(leftv res, leftv u, leftv v)
+{
+  poly p = pInit();
+  int i;
+  for (i=1; i<=currRing->N; i++)
+  {
+    pSetExp(p, i, 1);
+  }
+  pSetm(p);
+  res->data = (void*)idCoeffOfKBase((ideal)(u->Data()),
+                                    (ideal)(v->Data()), p);
+  pDelete(&p);
+  return FALSE;
+}
+static BOOLEAN jjCONTRACT(leftv res, leftv u, leftv v)
+{
+  res->data=(char *)idDiffOp((ideal)u->Data(),(ideal)v->Data(),FALSE);
+  return FALSE;
+}
+static BOOLEAN jjDEG_M_IV(leftv res, leftv u, leftv v)
+{
+  short *iv=iv2array((intvec *)v->Data(),currRing);
+  ideal I=(ideal)u->Data();
+  int d=-1;
+  int i;
+  for(i=IDELEMS(I);i>=0;i--) d=si_max(d,(int)p_DegW(I->m[i],iv,currRing));
+  omFreeSize( (ADDRESS)iv, (rVar(currRing)+1)*sizeof(short) );
+  res->data = (char *)((long)d);
+  return FALSE;
+}
+static BOOLEAN jjDEG_IV(leftv res, leftv u, leftv v)
+{
+  poly p=(poly)u->Data();
+  if (p!=NULL)
+  {
+    short *iv=iv2array((intvec *)v->Data(),currRing);
+    const long d = p_DegW(p,iv,currRing);
+    omFreeSize( (ADDRESS)iv, (rVar(currRing)+1)*sizeof(short) );
+    res->data = (char *)(d);
+  }
+  else
+    res->data=(char *)(long)(-1);
+  return FALSE;
+}
+static BOOLEAN jjDIFF_P(leftv res, leftv u, leftv v)
+{
+  int i=pVar((poly)v->Data());
+  if (i==0)
+  {
+    WerrorS("ringvar expected");
+    return TRUE;
+  }
+  res->data=(char *)pDiff((poly)(u->Data()),i);
+  return FALSE;
+}
+static BOOLEAN jjDIFF_ID(leftv res, leftv u, leftv v)
+{
+  int i=pVar((poly)v->Data());
+  if (i==0)
+  {
+    WerrorS("ringvar expected");
+    return TRUE;
+  }
+  res->data=(char *)idDiff((matrix)(u->Data()),i);
+  return FALSE;
+}
+static BOOLEAN jjDIFF_ID_ID(leftv res, leftv u, leftv v)
+{
+  res->data=(char *)idDiffOp((ideal)u->Data(),(ideal)v->Data());
+  return FALSE;
+}
+static BOOLEAN jjDIM2(leftv res, leftv v, leftv w)
+{
+  assumeStdFlag(v);
+#ifdef HAVE_RINGS
+  if (rField_is_Ring(currRing))
+  {
+    //ring origR = currRing;
+    //ring tempR = rCopy(origR);
+    //coeffs new_cf=nInitChar(n_Q,NULL);
+    //nKillChar(tempR->cf);
+    //tempR->cf=new_cf;
+    //rComplete(tempR);
+    ideal vid = (ideal)v->Data();
+    int i = idPosConstant(vid);
+    if ((i != -1) && (n_IsUnit(pGetCoeff(vid->m[i]),currRing->cf)))
+    { /* ideal v contains unit; dim = -1 */
+      res->data = (char *)-1;
+      return FALSE;
+    }
+    //rChangeCurrRing(tempR);
+    //ideal vv = idrCopyR(vid, origR, currRing);
+    ideal vv = id_Copy(vid, currRing);
+    //ideal ww = idrCopyR((ideal)w->Data(), origR, currRing);
+    ideal ww = id_Copy((ideal)w->Data(), currRing);
+    /* drop degree zero generator from vv (if any) */
+    if (i != -1) pDelete(&vv->m[i]);
+    long d = (long)scDimInt(vv, ww);
+    if (rField_is_Ring_Z(currRing) && (i == -1)) d++;
+    res->data = (char *)d;
+    idDelete(&vv); idDelete(&ww);
+    //rChangeCurrRing(origR);
+    //rDelete(tempR);
+    return FALSE;
+  }
+#endif
+  if(currRing->qideal==NULL)
+    res->data = (char *)((long)scDimInt((ideal)(v->Data()),(ideal)w->Data()));
+  else
+  {
+    ideal q=idSimpleAdd(currRing->qideal,(ideal)w->Data());
+    res->data = (char *)((long)scDimInt((ideal)(v->Data()),q));
+    idDelete(&q);
+  }
+  return FALSE;
+}
+static BOOLEAN jjDIVISION(leftv res, leftv u, leftv v)
+{
+  ideal vi=(ideal)v->Data();
+  int vl= IDELEMS(vi);
+  ideal ui=(ideal)u->Data();
+  int ul= IDELEMS(ui);
+  ideal R; matrix U;
+  ideal m = idLift(vi,ui,&R, FALSE,hasFlag(v,FLAG_STD),TRUE,&U);
+  if (m==NULL) return TRUE;
+  // now make sure that all matices have the corect size:
+  matrix T = id_Module2formatedMatrix(m,vl,ul,currRing);
+  int i;
+  if (MATCOLS(U) != ul)
+  {
+    int mul=si_min(ul,MATCOLS(U));
+    matrix UU=mpNew(ul,ul);
+    int j;
+    for(i=mul;i>0;i--)
+    {
+      for(j=mul;j>0;j--)
+      {
+        MATELEM(UU,i,j)=MATELEM(U,i,j);
+        MATELEM(U,i,j)=NULL;
+      }
+    }
+    idDelete((ideal *)&U);
+    U=UU;
+  }
+  // make sure that U is a diagonal matrix of units
+  for(i=ul;i>0;i--)
+  {
+    if(MATELEM(U,i,i)==NULL) MATELEM(U,i,i)=pOne();
+  }
+  lists L=(lists)omAllocBin(slists_bin);
+  L->Init(3);
+  L->m[0].rtyp=MATRIX_CMD;   L->m[0].data=(void *)T;
+  L->m[1].rtyp=u->Typ();     L->m[1].data=(void *)R;
+  L->m[2].rtyp=MATRIX_CMD;   L->m[2].data=(void *)U;
+  res->data=(char *)L;
+  return FALSE;
+}
+static BOOLEAN jjELIMIN(leftv res, leftv u, leftv v)
+{
+  res->data=(char *)idElimination((ideal)u->Data(),(poly)v->Data());
+  //setFlag(res,FLAG_STD);
+  return v->next!=NULL; //do not allow next like in eliminate(I,a(1..4))
+}
+static BOOLEAN jjELIMIN_IV(leftv res, leftv u, leftv v)
+{
+  poly p=pOne();
+  intvec *iv=(intvec*)v->Data();
+  for(int i=iv->length()-1; i>=0; i--)
+  {
+    pSetExp(p,(*iv)[i],1);
+  }
+  pSetm(p);
+  res->data=(char *)idElimination((ideal)u->Data(),p);
+  pLmDelete(&p);
+  //setFlag(res,FLAG_STD);
+  return FALSE;
+}
+static BOOLEAN jjEXPORTTO(leftv, leftv u, leftv v)
+{
+  //Print("exportto %s -> %s\n",v->Name(),u->Name() );
+  return iiExport(v,0,IDPACKAGE((idhdl)u->data));
+}
+static BOOLEAN jjERROR(leftv, leftv u)
+{
+  WerrorS((char *)u->Data());
+  extern int inerror;
+  inerror=3;
+  return TRUE;
+}
+static BOOLEAN jjEXTGCD_BI(leftv res, leftv u, leftv v)
+{
+  number uu=(number)u->Data();number vv=(number)v->Data();
+  lists L=(lists)omAllocBin(slists_bin);
+  number a,b;
+  number p0=n_ExtGcd(uu,vv,&a,&b,coeffs_BIGINT);
+  L->Init(3);
+  L->m[0].rtyp=BIGINT_CMD;   L->m[0].data=(void *)p0;
+  L->m[1].rtyp=BIGINT_CMD;   L->m[1].data=(void *)a;
+  L->m[2].rtyp=BIGINT_CMD;   L->m[2].data=(void *)b;
+  res->rtyp=LIST_CMD;
+  res->data=(char *)L;
+  return FALSE;
+}
+static BOOLEAN jjEXTGCD_I(leftv res, leftv u, leftv v)
+{
+  int uu=(int)(long)u->Data();int vv=(int)(long)v->Data();
+  int p0=ABS(uu),p1=ABS(vv);
+  int f0 = 1, f1 = 0, g0 = 0, g1 = 1, q, r;
+
+  while ( p1!=0 )
+  {
+    q=p0 / p1;
+    r=p0 % p1;
+    p0 = p1; p1 = r;
+    r = g0 - g1 * q;
+    g0 = g1; g1 = r;
+    r = f0 - f1 * q;
+    f0 = f1; f1 = r;
+  }
+  int a = f0;
+  int b = g0;
+  if ( uu /*(int)(long)u->Data()*/ < 0 ) a=-a;
+  if ( vv /*(int)(long)v->Data()*/ < 0 ) b=-b;
+  lists L=(lists)omAllocBin(slists_bin);
+  L->Init(3);
+  L->m[0].rtyp=INT_CMD;   L->m[0].data=(void *)(long)p0;
+  L->m[1].rtyp=INT_CMD;   L->m[1].data=(void *)(long)a;
+  L->m[2].rtyp=INT_CMD;   L->m[2].data=(void *)(long)b;
+  res->rtyp=LIST_CMD;
+  res->data=(char *)L;
+  return FALSE;
+}
+static BOOLEAN jjEXTGCD_P(leftv res, leftv u, leftv v)
+{
+  poly r,pa,pb;
+  BOOLEAN ret=singclap_extgcd((poly)u->Data(),(poly)v->Data(),r,pa,pb,currRing);
+  if (ret) return TRUE;
+  lists L=(lists)omAllocBin(slists_bin);
+  L->Init(3);
+  res->data=(char *)L;
+  L->m[0].data=(void *)r;
+  L->m[0].rtyp=POLY_CMD;
+  L->m[1].data=(void *)pa;
+  L->m[1].rtyp=POLY_CMD;
+  L->m[2].data=(void *)pb;
+  L->m[2].rtyp=POLY_CMD;
+  return FALSE;
+}
+extern int singclap_factorize_retry;
+static BOOLEAN jjFAC_P2(leftv res, leftv u,leftv dummy)
+{
+  intvec *v=NULL;
+  int sw=(int)(long)dummy->Data();
+  int fac_sw=sw;
+  if ((sw<0)||(sw>2)) fac_sw=1;
+  singclap_factorize_retry=0;
+  ideal f=singclap_factorize((poly)(u->CopyD()), &v, fac_sw,currRing);
+  if (f==NULL)
+    return TRUE;
+  switch(sw)
+  {
+    case 0:
+    case 2:
+    {
+      lists l=(lists)omAllocBin(slists_bin);
+      l->Init(2);
+      l->m[0].rtyp=IDEAL_CMD;
+      l->m[0].data=(void *)f;
+      l->m[1].rtyp=INTVEC_CMD;
+      l->m[1].data=(void *)v;
+      res->data=(void *)l;
+      res->rtyp=LIST_CMD;
+      return FALSE;
+    }
+    case 1:
+      res->data=(void *)f;
+      return FALSE;
+    case 3:
+      {
+        poly p=f->m[0];
+        int i=IDELEMS(f);
+        f->m[0]=NULL;
+        while(i>1)
+        {
+          i--;
+          p=pMult(p,f->m[i]);
+          f->m[i]=NULL;
+        }
+        res->data=(void *)p;
+        res->rtyp=POLY_CMD;
+      }
+      return FALSE;
+  }
+  WerrorS("invalid switch");
+  return TRUE;
+}
+static BOOLEAN jjFACSTD2(leftv res, leftv v, leftv w)
+{
+  ideal_list p,h;
+  h=kStdfac((ideal)v->Data(),NULL,testHomog,NULL,(ideal)w->Data());
+  p=h;
+  int l=0;
+  while (p!=NULL) { p=p->next;l++; }
+  lists L=(lists)omAllocBin(slists_bin);
+  L->Init(l);
+  l=0;
+  while(h!=NULL)
+  {
+    L->m[l].data=(char *)h->d;
+    L->m[l].rtyp=IDEAL_CMD;
+    p=h->next;
+    omFreeSize(h,sizeof(*h));
+    h=p;
+    l++;
+  }
+  res->data=(void *)L;
+  return FALSE;
+}
+static BOOLEAN jjFAREY_BI(leftv res, leftv u, leftv v)
+{
+  if (rField_is_Q(currRing))
+  {
+    number uu=(number)u->Data();
+    number vv=(number)v->Data();
+    res->data=(char *)n_Farey(uu,vv,currRing->cf);
+    return FALSE;
+  }
+  else return TRUE;
+}
+static BOOLEAN jjFAREY_ID(leftv res, leftv u, leftv v)
+{
+  ideal uu=(ideal)u->Data();
+  number vv=(number)v->Data();
+  res->data=(void*)id_Farey(uu,vv,currRing);
+  res->rtyp=u->Typ();
+  return FALSE;
+}
+static BOOLEAN jjFETCH(leftv res, leftv u, leftv v)
+{
+  ring r=(ring)u->Data();
+  idhdl w;
+  int op=iiOp;
+  nMapFunc nMap;
+
+  if ((w=r->idroot->get(v->Name(),myynest))!=NULL)
+  {
+    int *perm=NULL;
+    int *par_perm=NULL;
+    int par_perm_size=0;
+    BOOLEAN bo;
+    if ((nMap=n_SetMap(r->cf,currRing->cf))==NULL)
+    {
+      // Allow imap/fetch to be make an exception only for:
+      if ( (rField_is_Q_a(r) &&  // Q(a..) -> Q(a..) || Q || Zp || Zp(a)
+            (rField_is_Q(currRing) || rField_is_Q_a(currRing) ||
+             (rField_is_Zp(currRing) || rField_is_Zp_a(currRing))))
+           ||
+           (rField_is_Zp_a(r) &&  // Zp(a..) -> Zp(a..) || Zp
+            (rField_is_Zp(currRing, r->cf->ch) ||
+             rField_is_Zp_a(currRing, r->cf->ch))) )
+      {
+        par_perm_size=rPar(r);
+      }
+      else
+      {
+        goto err_fetch;
+      }
+    }
+    if ((iiOp!=FETCH_CMD) || (r->N!=currRing->N) || (rPar(r)!=rPar(currRing)))
+    {
+      perm=(int *)omAlloc0((r->N+1)*sizeof(int));
+      if (par_perm_size!=0)
+        par_perm=(int *)omAlloc0(par_perm_size*sizeof(int));
+      op=IMAP_CMD;
+      if (iiOp==IMAP_CMD)
+      {
+        int r_par=0;
+        char ** r_par_names=NULL;
+        if (r->cf->extRing!=NULL)
+        {
+          r_par=r->cf->extRing->N;
+          r_par_names=r->cf->extRing->names;
+        }
+        int c_par=0;
+        char ** c_par_names=NULL;
+        if (currRing->cf->extRing!=NULL)
+        {
+          c_par=currRing->cf->extRing->N;
+          c_par_names=currRing->cf->extRing->names;
+        }
+        maFindPerm(r->names,       r->N,       r_par_names, r_par,
+                   currRing->names,currRing->N,c_par_names, c_par,
+                   perm,par_perm, currRing->cf->type);
+      }
+      else
+      {
+        int i;
+        if (par_perm_size!=0)
+          for(i=si_min(rPar(r),rPar(currRing))-1;i>=0;i--) par_perm[i]=-(i+1);
+        for(i=si_min(r->N,currRing->N);i>0;i--) perm[i]=i;
+      }
+    }
+    if ((iiOp==FETCH_CMD) &&(BVERBOSE(V_IMAP)))
+    {
+      int i;
+      for(i=0;i<si_min(r->N,currRing->N);i++)
+      {
+        Print("// var nr %d: %s -> %s\n",i,r->names[i],currRing->names[i]);
+      }
+      for(i=0;i<si_min(rPar(r),rPar(currRing));i++) // possibly empty loop
+      {
+        Print("// par nr %d: %s -> %s\n",
+              i,rParameter(r)[i],rParameter(currRing)[i]);
+      }
+    }
+    if (IDTYP(w)==ALIAS_CMD) w=(idhdl)IDDATA(w);
+    sleftv tmpW;
+    memset(&tmpW,0,sizeof(sleftv));
+    tmpW.rtyp=IDTYP(w);
+    tmpW.data=IDDATA(w);
+    if ((bo=maApplyFetch(op,NULL,res,&tmpW, r,
+                         perm,par_perm,par_perm_size,nMap)))
+    {
+      Werror("cannot map %s of type %s(%d)",v->name, Tok2Cmdname(w->typ),w->typ);
+    }
+    if (perm!=NULL)
+      omFreeSize((ADDRESS)perm,(r->N+1)*sizeof(int));
+    if (par_perm!=NULL)
+      omFreeSize((ADDRESS)par_perm,par_perm_size*sizeof(int));
+    return bo;
+  }
+  else
+  {
+    Werror("identifier %s not found in %s",v->Fullname(),u->Fullname());
+  }
+  return TRUE;
+err_fetch:
+  Werror("no identity map from %s (%s -> %s)",u->Fullname(),
+         nCoeffString(r->cf),
+         nCoeffString(currRing->cf));
+  return TRUE;
+}
+static BOOLEAN jjFIND2(leftv res, leftv u, leftv v)
+{
+  /*4
+  * look for the substring what in the string where
+  * return the position of the first char of what in where
+  * or 0
+  */
+  char *where=(char *)u->Data();
+  char *what=(char *)v->Data();
+  char *found = strstr(where,what);
+  if (found != NULL)
+  {
+    res->data=(char *)((found-where)+1);
+  }
+  /*else res->data=NULL;*/
+  return FALSE;
+}
+static BOOLEAN jjFWALK(leftv res, leftv u, leftv v)
+{
+  res->data=(char *)fractalWalkProc(u,v);
+  setFlag( res, FLAG_STD );
+  return FALSE;
+}
+static BOOLEAN jjGCD_I(leftv res, leftv u, leftv v)
+{
+  int uu=(int)(long)u->Data();int vv=(int)(long)v->Data();
+  int p0=ABS(uu),p1=ABS(vv);
+  int r;
+  while ( p1!=0 )
+  {
+    r=p0 % p1;
+    p0 = p1; p1 = r;
+  }
+  res->rtyp=INT_CMD;
+  res->data=(char *)(long)p0;
+  return FALSE;
+}
+static BOOLEAN jjGCD_BI(leftv res, leftv u, leftv v)
+{
+  number n1 = (number) u->Data();
+  number n2 = (number) v->Data();
+  res->data = n_Gcd(n1,n2,coeffs_BIGINT);
+  return FALSE;
+}
+static BOOLEAN jjGCD_N(leftv res, leftv u, leftv v)
+{
+  number a=(number) u->Data();
+  number b=(number) v->Data();
+  if (nIsZero(a))
+  {
+    if (nIsZero(b)) res->data=(char *)nInit(1);
+    else            res->data=(char *)nCopy(b);
+  }
+  else
+  {
+    if (nIsZero(b))  res->data=(char *)nCopy(a);
+    //else res->data=(char *)n_Gcd(a, b, currRing->cf);
+    else res->data=(char *)n_SubringGcd(a, b, currRing->cf);
+  }
+  return FALSE;
+}
+static BOOLEAN jjGCD_P(leftv res, leftv u, leftv v)
+{
+  res->data=(void *)singclap_gcd((poly)(u->CopyD(POLY_CMD)),
+                                 (poly)(v->CopyD(POLY_CMD)),currRing);
+  return FALSE;
+}
+static BOOLEAN jjHILBERT2(leftv res, leftv u, leftv v)
+{
+#ifdef HAVE_RINGS
+  if (rField_is_Ring_Z(currRing))
+  {
+    ring origR = currRing;
+    ring tempR = rCopy(origR);
+    coeffs new_cf=nInitChar(n_Q,NULL);
+    nKillChar(tempR->cf);
+    tempR->cf=new_cf;
+    rComplete(tempR);
+    ideal uid = (ideal)u->Data();
+    rChangeCurrRing(tempR);
+    ideal uu = idrCopyR(uid, origR, currRing);
+    sleftv uuAsLeftv; memset(&uuAsLeftv, 0, sizeof(uuAsLeftv));
+    uuAsLeftv.rtyp = IDEAL_CMD;
+    uuAsLeftv.data = uu; uuAsLeftv.next = NULL;
+    if (hasFlag(u, FLAG_STD)) setFlag(&uuAsLeftv,FLAG_STD);
+    assumeStdFlag(&uuAsLeftv);
+    Print("// NOTE: computation of Hilbert series etc. is being\n");
+    Print("//       performed for generic fibre, that is, over Q\n");
+    intvec *module_w=(intvec*)atGet(&uuAsLeftv,"isHomog",INTVEC_CMD);
+    intvec *iv=hFirstSeries(uu,module_w,currRing->qideal);
+    int returnWithTrue = 1;
+    switch((int)(long)v->Data())
+    {
+      case 1:
+        res->data=(void *)iv;
+        returnWithTrue = 0;
+      case 2:
+        res->data=(void *)hSecondSeries(iv);
+        delete iv;
+        returnWithTrue = 0;
+    }
+    if (returnWithTrue)
+    {
+      WerrorS(feNotImplemented);
+      delete iv;
+    }
+    idDelete(&uu);
+    rChangeCurrRing(origR);
+    rDelete(tempR);
+    if (returnWithTrue) return TRUE; else return FALSE;
+  }
+#endif
+  assumeStdFlag(u);
+  intvec *module_w=(intvec*)atGet(u,"isHomog",INTVEC_CMD);
+  intvec *iv=hFirstSeries((ideal)u->Data(),module_w,currRing->qideal);
+  switch((int)(long)v->Data())
+  {
+    case 1:
+      res->data=(void *)iv;
+      return FALSE;
+    case 2:
+      res->data=(void *)hSecondSeries(iv);
+      delete iv;
+      return FALSE;
+  }
+  WerrorS(feNotImplemented);
+  delete iv;
+  return TRUE;
+}
+static BOOLEAN jjHOMOG_P(leftv res, leftv u, leftv v)
+{
+  int i=pVar((poly)v->Data());
+  if (i==0)
+  {
+    WerrorS("ringvar expected");
+    return TRUE;
+  }
+  poly p=pOne(); pSetExp(p,i,1); pSetm(p);
+  int d=pWTotaldegree(p);
+  pLmDelete(p);
+  if (d==1)
+    res->data = (char *)p_Homogen((poly)u->Data(), i, currRing);
+  else
+    WerrorS("variable must have weight 1");
+  return (d!=1);
+}
+static BOOLEAN jjHOMOG_ID(leftv res, leftv u, leftv v)
+{
+  int i=pVar((poly)v->Data());
+  if (i==0)
+  {
+    WerrorS("ringvar expected");
+    return TRUE;
+  }
+  pFDegProc deg;
+  if (currRing->pLexOrder && (currRing->order[0]==ringorder_lp))
+    deg=p_Totaldegree;
+   else
+    deg=currRing->pFDeg;
+  poly p=pOne(); pSetExp(p,i,1); pSetm(p);
+  int d=deg(p,currRing);
+  pLmDelete(p);
+  if (d==1)
+    res->data = (char *)id_Homogen((ideal)u->Data(), i, currRing);
+  else
+    WerrorS("variable must have weight 1");
+  return (d!=1);
+}
+static BOOLEAN jjHOMOG1_W(leftv res, leftv v, leftv u)
+{
+  intvec *w=new intvec(rVar(currRing));
+  intvec *vw=(intvec*)u->Data();
+  ideal v_id=(ideal)v->Data();
+  pFDegProc save_FDeg=currRing->pFDeg;
+  pLDegProc save_LDeg=currRing->pLDeg;
+  BOOLEAN save_pLexOrder=currRing->pLexOrder;
+  currRing->pLexOrder=FALSE;
+  kHomW=vw;
+  kModW=w;
+  pSetDegProcs(currRing,kHomModDeg);
+  res->data=(void *)(long)idHomModule(v_id,currRing->qideal,&w);
+  currRing->pLexOrder=save_pLexOrder;
+  kHomW=NULL;
+  kModW=NULL;
+  pRestoreDegProcs(currRing,save_FDeg,save_LDeg);
+  if (w!=NULL) delete w;
+  return FALSE;
+}
+static BOOLEAN jjINDEPSET2(leftv res, leftv u, leftv v)
+{
+  assumeStdFlag(u);
+  res->data=(void *)scIndIndset((ideal)(u->Data()),(int)(long)(v->Data()),
+                    currRing->qideal);
+  return FALSE;
+}
+static BOOLEAN jjINTERSECT(leftv res, leftv u, leftv v)
+{
+  res->data=(char *)idSect((ideal)u->Data(),(ideal)v->Data());
+  if (TEST_OPT_RETURN_SB) setFlag(res,FLAG_STD);
+  return FALSE;
+}
+static BOOLEAN jjINTERPOLATION (leftv res, leftv l, leftv v)
+{
+  const lists L = (lists)l->Data();
+  const int n = L->nr; assume (n >= 0);
+  std::vector<ideal> V(n + 1);
+
+  for(int i = n; i >= 0; i--) V[i] = (ideal)(L->m[i].Data());
+
+  res->data=interpolation(V, (intvec*)v->Data());
+  setFlag(res,FLAG_STD);
+  return errorreported;
+}
+static BOOLEAN jjJanetBasis2(leftv res, leftv u, leftv v)
+{
+  extern BOOLEAN jjStdJanetBasis(leftv res, leftv v,int flag);
+  return jjStdJanetBasis(res,u,(int)(long)v->Data());
+}
+
+static BOOLEAN jjJanetBasis(leftv res, leftv v)
+{
+  extern BOOLEAN jjStdJanetBasis(leftv res, leftv v,int flag);
+  return jjStdJanetBasis(res,v,0);
+}
+static BOOLEAN jjJET_P(leftv res, leftv u, leftv v)
+{
+  res->data = (char *)pJet((poly)u->CopyD(), (int)(long)v->Data());
+  return FALSE;
+}
+static BOOLEAN jjJET_ID(leftv res, leftv u, leftv v)
+{
+  res->data = (char *)id_Jet((ideal)u->Data(),(int)(long)v->Data(),currRing);
+  return FALSE;
+}
+static BOOLEAN jjKBASE2(leftv res, leftv u, leftv v)
+{
+  assumeStdFlag(u);
+  intvec *w_u=(intvec *)atGet(u,"isHomog",INTVEC_CMD);
+  res->data = (char *)scKBase((int)(long)v->Data(),
+                              (ideal)(u->Data()),currRing->qideal, w_u);
+  if (w_u!=NULL)
+  {
+    atSet(res,omStrDup("isHomog"),ivCopy(w_u),INTVEC_CMD);
+  }
+  return FALSE;
+}
+static BOOLEAN jjPREIMAGE(leftv res, leftv u, leftv v, leftv w);
+static BOOLEAN jjKERNEL(leftv res, leftv u, leftv v)
+{
+  return jjPREIMAGE(res,u,v,NULL);
+}
+static BOOLEAN jjKoszul(leftv res, leftv u, leftv v)
+{
+  return mpKoszul(res, u,v,NULL);
+}
+static BOOLEAN jjKoszul_Id(leftv res, leftv u, leftv v)
+{
+  sleftv h;
+  memset(&h,0,sizeof(sleftv));
+  h.rtyp=INT_CMD;
+  h.data=(void *)(long)IDELEMS((ideal)v->Data());
+  return mpKoszul(res, u, &h, v);
+}
+static BOOLEAN jjLIFT(leftv res, leftv u, leftv v)
+{
+  int ul= IDELEMS((ideal)u->Data());
+  int vl= IDELEMS((ideal)v->Data());
+  ideal m = idLift((ideal)u->Data(),(ideal)v->Data(),NULL,FALSE,
+                   hasFlag(u,FLAG_STD));
+  if (m==NULL) return TRUE;
+  res->data = (char *)id_Module2formatedMatrix(m,ul,vl,currRing);
+  return FALSE;
+}
+static BOOLEAN jjLIFTSTD(leftv res, leftv u, leftv v)
+{
+  if ((v->rtyp!=IDHDL)||(v->e!=NULL)) return TRUE;
+  idhdl h=(idhdl)v->data;
+  // CopyD for IDEAL_CMD and MODUL_CMD are identical:
+  res->data = (char *)idLiftStd((ideal)u->Data(),
+                                &(h->data.umatrix),testHomog);
+  setFlag(res,FLAG_STD); v->flag=0;
+  return FALSE;
+}
+static BOOLEAN jjLOAD2(leftv /*res*/, leftv, leftv v)
+{
+  return jjLOAD((char*)v->Data(),TRUE);
+}
+static BOOLEAN jjLOAD_E(leftv /*res*/, leftv v, leftv u)
+{
+  char * s=(char *)u->Data();
+  if(strcmp(s, "with")==0)
+    return jjLOAD((char*)v->Data(), TRUE);
+  WerrorS("invalid second argument");
+  WerrorS("load(\"libname\" [,\"with\"]);");
+  return TRUE;
+}
+static BOOLEAN jjMODULO(leftv res, leftv u, leftv v)
+{
+  intvec *w_u=(intvec *)atGet(u,"isHomog",INTVEC_CMD);
+  tHomog hom=testHomog;
+  if (w_u!=NULL)
+  {
+    w_u=ivCopy(w_u);
+    hom=isHomog;
+  }
+  intvec *w_v=(intvec *)atGet(v,"isHomog",INTVEC_CMD);
+  if (w_v!=NULL)
+  {
+    w_v=ivCopy(w_v);
+    hom=isHomog;
+  }
+  if ((w_u!=NULL) && (w_v==NULL))
+    w_v=ivCopy(w_u);
+  if ((w_v!=NULL) && (w_u==NULL))
+    w_u=ivCopy(w_v);
+  ideal u_id=(ideal)u->Data();
+  ideal v_id=(ideal)v->Data();
+  if (w_u!=NULL)
+  {
+     if ((*w_u).compare((w_v))!=0)
+     {
+       WarnS("incompatible weights");
+       delete w_u; w_u=NULL;
+       hom=testHomog;
+     }
+     else
+     {
+       if ((!idTestHomModule(u_id,currRing->qideal,w_v))
+       || (!idTestHomModule(v_id,currRing->qideal,w_v)))
+       {
+         WarnS("wrong weights");
+         delete w_u; w_u=NULL;
+         hom=testHomog;
+       }
+     }
+  }
+  res->data = (char *)idModulo(u_id,v_id ,hom,&w_u);
+  if (w_u!=NULL)
+  {
+    atSet(res,omStrDup("isHomog"),w_u,INTVEC_CMD);
+  }
+  delete w_v;
+  if (TEST_OPT_RETURN_SB) setFlag(res,FLAG_STD);
+  return FALSE;
+}
+static BOOLEAN jjMOD_BI(leftv res, leftv u, leftv v)
+{
+  number q=(number)v->Data();
+  if (n_IsZero(q,coeffs_BIGINT))
+  {
+    WerrorS(ii_div_by_0);
+    return TRUE;
+  }
+  res->data =(char *) n_IntMod((number)u->Data(),q,coeffs_BIGINT);
+  return FALSE;
+}
+static BOOLEAN jjMOD_N(leftv res, leftv u, leftv v)
+{
+  number q=(number)v->Data();
+  if (nIsZero(q))
+  {
+    WerrorS(ii_div_by_0);
+    return TRUE;
+  }
+  res->data =(char *) n_IntMod((number)u->Data(),q,currRing->cf);
+  return FALSE;
+}
+static BOOLEAN jjMONITOR2(leftv res, leftv u,leftv v);
+static BOOLEAN jjMONITOR1(leftv res, leftv v)
+{
+  return jjMONITOR2(res,v,NULL);
+}
+static BOOLEAN jjMONITOR2(leftv, leftv u,leftv v)
+{
+#if 0
+  char *opt=(char *)v->Data();
+  int mode=0;
+  while(*opt!='\0')
+  {
+    if (*opt=='i') mode |= SI_PROT_I;
+    else if (*opt=='o') mode |= SI_PROT_O;
+    opt++;
+  }
+  monitor((char *)(u->Data()),mode);
+#else
+  si_link l=(si_link)u->Data();
+  if (slOpen(l,SI_LINK_WRITE,u)) return TRUE;
+  if(strcmp(l->m->type,"ASCII")!=0)
+  {
+    Werror("ASCII link required, not `%s`",l->m->type);
+    slClose(l);
+    return TRUE;
+  }
+  SI_LINK_SET_CLOSE_P(l); // febase handles the FILE*
+  if ( l->name[0]!='\0') // "" is the stop condition
+  {
+    const char *opt;
+    int mode=0;
+    if (v==NULL) opt=(const char*)"i";
+    else         opt=(const char *)v->Data();
+    while(*opt!='\0')
+    {
+      if (*opt=='i') mode |= SI_PROT_I;
+      else if (*opt=='o') mode |= SI_PROT_O;
+      opt++;
+    }
+    monitor((FILE *)l->data,mode);
+  }
+  else
+    monitor(NULL,0);
+  return FALSE;
+#endif
+}
+static BOOLEAN jjMONOM(leftv res, leftv v)
+{
+  intvec *iv=(intvec *)v->Data();
+  poly p=pOne();
+  int i,e;
+  BOOLEAN err=FALSE;
+  for(i=si_min(currRing->N,iv->length()); i>0; i--)
+  {
+    e=(*iv)[i-1];
+    if (e>=0) pSetExp(p,i,e);
+    else err=TRUE;
+  }
+  if (iv->length()==(currRing->N+1))
+  {
+    res->rtyp=VECTOR_CMD;
+    e=(*iv)[currRing->N];
+    if (e>=0) pSetComp(p,e);
+    else err=TRUE;
+  }
+  pSetm(p);
+  res->data=(char*)p;
+  if(err) { pDelete(&p); WerrorS("no negative exponent allowed"); }
+  return err;
+}
+static BOOLEAN jjNEWSTRUCT2(leftv, leftv u, leftv v)
+{
+  // u: the name of the new type
+  // v: the elements
+  newstruct_desc d=newstructFromString((const char *)v->Data());
+  if (d!=NULL) newstruct_setup((const char *)u->Data(),d);
+  return d==NULL;
+}
+static BOOLEAN jjPARSTR2(leftv res, leftv u, leftv v)
+{
+  idhdl h=(idhdl)u->data;
+  int i=(int)(long)v->Data();
+  int p=0;
+  if ((0<i)
+  && (rParameter(IDRING(h))!=NULL)
+  && (i<=(p=rPar(IDRING(h)))))
+    res->data=omStrDup(rParameter(IDRING(h))[i-1]);
+  else
+  {
+    Werror("par number %d out of range 1..%d",i,p);
+    return TRUE;
+  }
+  return FALSE;
+}
+#ifdef HAVE_PLURAL
+static BOOLEAN jjPlural_num_poly(leftv res, leftv a, leftv b)
+{
+  if( currRing->qideal != NULL )
+  {
+    WerrorS("basering must NOT be a qring!");
+    return TRUE;
+  }
+
+  if (iiOp==NCALGEBRA_CMD)
+  {
+    return nc_CallPlural(NULL,NULL,(poly)a->Data(),(poly)b->Data(),currRing,false,true,false,currRing);
+  }
+  else
+  {
+    ring r=rCopy(currRing);
+    BOOLEAN result=nc_CallPlural(NULL,NULL,(poly)a->Data(),(poly)b->Data(),r,false,true,false,currRing);
+    res->data=r;
+    if (r->qideal!=NULL) res->rtyp=QRING_CMD;
+    return result;
+  }
+}
+static BOOLEAN jjPlural_num_mat(leftv res, leftv a, leftv b)
+{
+  if( currRing->qideal != NULL )
+  {
+    WerrorS("basering must NOT be a qring!");
+    return TRUE;
+  }
+
+  if (iiOp==NCALGEBRA_CMD)
+  {
+    return nc_CallPlural(NULL,(matrix)b->Data(),(poly)a->Data(),NULL,currRing,false,true,false,currRing);
+  }
+  else
+  {
+    ring r=rCopy(currRing);
+    BOOLEAN result=nc_CallPlural(NULL,(matrix)b->Data(),(poly)a->Data(),NULL,r,false,true,false,currRing);
+    res->data=r;
+    if (r->qideal!=NULL) res->rtyp=QRING_CMD;
+    return result;
+  }
+}
+static BOOLEAN jjPlural_mat_poly(leftv res, leftv a, leftv b)
+{
+  if( currRing->qideal != NULL )
+  {
+    WerrorS("basering must NOT be a qring!");
+    return TRUE;
+  }
+
+  if (iiOp==NCALGEBRA_CMD)
+  {
+    return nc_CallPlural((matrix)a->Data(),NULL,NULL,(poly)b->Data(),currRing,false,true,false,currRing);
+  }
+  else
+  {
+    ring r=rCopy(currRing);
+    BOOLEAN result=nc_CallPlural((matrix)a->Data(),NULL,NULL,(poly)b->Data(),r,false,true,false,currRing);
+    res->data=r;
+    if (r->qideal!=NULL) res->rtyp=QRING_CMD;
+    return result;
+  }
+}
+static BOOLEAN jjPlural_mat_mat(leftv res, leftv a, leftv b)
+{
+  if( currRing->qideal != NULL )
+  {
+    WerrorS("basering must NOT be a qring!");
+    return TRUE;
+  }
+
+  if (iiOp==NCALGEBRA_CMD)
+  {
+    return nc_CallPlural((matrix)a->Data(),(matrix)b->Data(),NULL,NULL,currRing,false,true,false,currRing);
+  }
+  else
+  {
+    ring r=rCopy(currRing);
+    BOOLEAN result=nc_CallPlural((matrix)a->Data(),(matrix)b->Data(),NULL,NULL,r,false,true,false,currRing);
+    res->data=r;
+    if (r->qideal!=NULL) res->rtyp=QRING_CMD;
+    return result;
+  }
+}
+static BOOLEAN jjBRACKET(leftv res, leftv a, leftv b)
+{
+  res->data=NULL;
+
+  if (rIsPluralRing(currRing))
+  {
+    const poly q = (poly)b->Data();
+
+    if( q != NULL )
+    {
+      if( (poly)a->Data() != NULL )
+      {
+        poly p = (poly)a->CopyD(POLY_CMD); // p = copy!
+        res->data = nc_p_Bracket_qq(p,q, currRing); // p will be destroyed!
+      }
+    }
+  }
+  return FALSE;
+}
+static BOOLEAN jjOPPOSE(leftv res, leftv a, leftv b)
+{
+  /* number, poly, vector, ideal, module, matrix */
+  ring  r = (ring)a->Data();
+  if (r == currRing)
+  {
+    res->data = b->Data();
+    res->rtyp = b->rtyp;
+    return FALSE;
+  }
+  if (!rIsLikeOpposite(currRing, r))
+  {
+    Werror("%s is not an opposite ring to current ring",a->Fullname());
+    return TRUE;
+  }
+  idhdl w;
+  if( ((w=r->idroot->get(b->Name(),myynest))!=NULL) && (b->e==NULL))
+  {
+    int argtype = IDTYP(w);
+    switch (argtype)
+    {
+    case NUMBER_CMD:
+      {
+        /* since basefields are equal, we can apply nCopy */
+        res->data = nCopy((number)IDDATA(w));
+        res->rtyp = argtype;
+        break;
+      }
+    case POLY_CMD:
+    case VECTOR_CMD:
+      {
+        poly    q = (poly)IDDATA(w);
+        res->data = pOppose(r,q,currRing);
+        res->rtyp = argtype;
+        break;
+      }
+    case IDEAL_CMD:
+    case MODUL_CMD:
+      {
+        ideal   Q = (ideal)IDDATA(w);
+        res->data = idOppose(r,Q,currRing);
+        res->rtyp = argtype;
+        break;
+      }
+    case MATRIX_CMD:
+      {
+        ring save = currRing;
+        rChangeCurrRing(r);
+        matrix  m = (matrix)IDDATA(w);
+        ideal   Q = id_Matrix2Module(mp_Copy(m, currRing),currRing);
+        rChangeCurrRing(save);
+        ideal   S = idOppose(r,Q,currRing);
+        id_Delete(&Q, r);
+        res->data = id_Module2Matrix(S,currRing);
+        res->rtyp = argtype;
+        break;
+      }
+    default:
+      {
+        WerrorS("unsupported type in oppose");
+        return TRUE;
+      }
+    }
+  }
+  else
+  {
+    Werror("identifier %s not found in %s",b->Fullname(),a->Fullname());
+    return TRUE;
+  }
+  return FALSE;
+}
+#endif /* HAVE_PLURAL */
+
+static BOOLEAN jjQUOT(leftv res, leftv u, leftv v)
+{
+  res->data = (char *)idQuot((ideal)u->Data(),(ideal)v->Data(),
+    hasFlag(u,FLAG_STD),u->Typ()==v->Typ());
+  id_DelMultiples((ideal)(res->data),currRing);
+  if (TEST_OPT_RETURN_SB) setFlag(res,FLAG_STD);
+  return FALSE;
+}
+static BOOLEAN jjRANDOM(leftv res, leftv u, leftv v)
+{
+  int i=(int)(long)u->Data();
+  int j=(int)(long)v->Data();
+  if (j-i <0) {WerrorS("invalid range for random"); return TRUE;}
+  res->data =(char *)(long)((i > j) ? i : (siRand() % (j-i+1)) + i);
+  return FALSE;
+}
+static BOOLEAN jjRANK2(leftv res, leftv u, leftv v)
+{
+  matrix m =(matrix)u->Data();
+  int isRowEchelon = (int)(long)v->Data();
+  if (isRowEchelon != 1) isRowEchelon = 0;
+  int rank = luRank(m, isRowEchelon);
+  res->data =(char *)(long)rank;
+  return FALSE;
+}
+static BOOLEAN jjREAD2(leftv res, leftv u, leftv v)
+{
+  si_link l=(si_link)u->Data();
+  leftv r=slRead(l,v);
+  if (r==NULL)
+  {
+    const char *s;
+    if ((l!=NULL)&&(l->name!=NULL)) s=l->name;
+    else                            s=sNoName;
+    Werror("cannot read from `%s`",s);
+    return TRUE;
+  }
+  memcpy(res,r,sizeof(sleftv));
+  omFreeBin((ADDRESS)r, sleftv_bin);
+  return FALSE;
+}
+static BOOLEAN jjREDUCE_P(leftv res, leftv u, leftv v)
+{
+  assumeStdFlag(v);
+  res->data = (char *)kNF((ideal)v->Data(),currRing->qideal,(poly)u->Data());
+  return FALSE;
+}
+static BOOLEAN jjREDUCE_ID(leftv res, leftv u, leftv v)
+{
+  assumeStdFlag(v);
+  ideal ui=(ideal)u->Data();
+  ideal vi=(ideal)v->Data();
+  res->data = (char *)kNF(vi,currRing->qideal,ui);
+  return FALSE;
+}
+#if 0
+static BOOLEAN jjRES(leftv res, leftv u, leftv v)
+{
+  int maxl=(int)(long)v->Data();
+  if (maxl<0)
+  {
+    WerrorS("length for res must not be negative");
+    return TRUE;
+  }
+  int l=0;
+  //resolvente r;
+  syStrategy r;
+  intvec *weights=NULL;
+  int wmaxl=maxl;
+  ideal u_id=(ideal)u->Data();
+
+  maxl--;
+  if (/*(*/ maxl==-1 /*)*/) /*&& (iiOp!=MRES_CMD)*/
+  {
+    maxl = currRing->N-1+2*(iiOp==MRES_CMD);
+    if (currRing->qideal!=NULL)
+    {
+      Warn(
+      "full resolution in a qring may be infinite, setting max length to %d",
+      maxl+1);
+    }
+  }
+  weights=(intvec*)atGet(u,"isHomog",INTVEC_CMD);
+  if (weights!=NULL)
+  {
+    if (!idTestHomModule(u_id,currRing->qideal,weights))
+    {
+      WarnS("wrong weights given:");weights->show();PrintLn();
+      weights=NULL;
+    }
+  }
+  intvec *ww=NULL;
+  int add_row_shift=0;
+  if (weights!=NULL)
+  {
+     ww=ivCopy(weights);
+     add_row_shift = ww->min_in();
+     (*ww) -= add_row_shift;
+  }
+  else
+    idHomModule(u_id,currRing->qideal,&ww);
+  weights=ww;
+
+  if ((iiOp == RES_CMD) || (iiOp == MRES_CMD))
+  {
+    r=syResolution(u_id,maxl, ww, iiOp==MRES_CMD);
+  }
+  else if (iiOp==SRES_CMD)
+  //  r=sySchreyerResolvente(u_id,maxl+1,&l);
+    r=sySchreyer(u_id,maxl+1);
+  else if (iiOp == LRES_CMD)
+  {
+    int dummy;
+    if((currRing->qideal!=NULL)||
+    (!idHomIdeal (u_id,NULL)))
+    {
+       WerrorS
+       ("`lres` not implemented for inhomogeneous input or qring");
+       return TRUE;
+    }
+    r=syLaScala3(u_id,&dummy);
+  }
+  else if (iiOp == KRES_CMD)
+  {
+    int dummy;
+    if((currRing->qideal!=NULL)||
+    (!idHomIdeal (u_id,NULL)))
+    {
+       WerrorS
+       ("`kres` not implemented for inhomogeneous input or qring");
+       return TRUE;
+    }
+    r=syKosz(u_id,&dummy);
+  }
+  else
+  {
+    int dummy;
+    if((currRing->qideal!=NULL)||
+    (!idHomIdeal (u_id,NULL)))
+    {
+       WerrorS
+       ("`hres` not implemented for inhomogeneous input or qring");
+       return TRUE;
+    }
+    r=syHilb(u_id,&dummy);
+  }
+  if (r==NULL) return TRUE;
+  //res->data=(void *)liMakeResolv(r,l,wmaxl,u->Typ(),weights);
+  r->list_length=wmaxl;
+  res->data=(void *)r;
+  if ((r->weights!=NULL) && (r->weights[0]!=NULL))
+  {
+    intvec *w=ivCopy(r->weights[0]);
+    if (weights!=NULL) (*w) += add_row_shift;
+    atSet(res,omStrDup("isHomog"),w,INTVEC_CMD);
+    w=NULL;
+  }
+  else
+  {
+//#if 0
+// need to set weights for ALL components (sres)
+    if (weights!=NULL)
+    {
+      atSet(res,omStrDup("isHomog"),ivCopy(weights),INTVEC_CMD);
+      r->weights = (intvec**)omAlloc0Bin(char_ptr_bin);
+      (r->weights)[0] = ivCopy(weights);
+    }
+//#endif
+  }
+  if (ww!=NULL) { delete ww; ww=NULL; }
+  return FALSE;
+}
+#else
+static BOOLEAN jjRES(leftv res, leftv u, leftv v)
+{
+  int maxl=(int)(long)v->Data();
+  if (maxl<0)
+  {
+    WerrorS("length for res must not be negative");
+    return TRUE;
+  }
+  syStrategy r;
+  intvec *weights=NULL;
+  int wmaxl=maxl;
+  ideal u_id=(ideal)u->Data();
+
+  maxl--;
+  if (/*(*/ maxl==-1 /*)*/) /*&& (iiOp!=MRES_CMD)*/
+  {
+    maxl = currRing->N-1+2*(iiOp==MRES_CMD);
+    if (currRing->qideal!=NULL)
+    {
+      Warn(
+      "full resolution in a qring may be infinite, setting max length to %d",
+      maxl+1);
+    }
+  }
+  weights=(intvec*)atGet(u,"isHomog",INTVEC_CMD);
+  if (weights!=NULL)
+  {
+    if (!idTestHomModule(u_id,currRing->qideal,weights))
+    {
+      WarnS("wrong weights given:");weights->show();PrintLn();
+      weights=NULL;
+    }
+  }
+  intvec *ww=NULL;
+  int add_row_shift=0;
+  if (weights!=NULL)
+  {
+     ww=ivCopy(weights);
+     add_row_shift = ww->min_in();
+     (*ww) -= add_row_shift;
+  }
+  if ((iiOp == RES_CMD) || (iiOp == MRES_CMD))
+  {
+    r=syResolution(u_id,maxl, ww, iiOp==MRES_CMD);
+  }
+  else if (iiOp==SRES_CMD)
+  //  r=sySchreyerResolvente(u_id,maxl+1,&l);
+    r=sySchreyer(u_id,maxl+1);
+  else if (iiOp == LRES_CMD)
+  {
+    int dummy;
+    if((currRing->qideal!=NULL)||
+    (!idHomIdeal (u_id,NULL)))
+    {
+       WerrorS
+       ("`lres` not implemented for inhomogeneous input or qring");
+       return TRUE;
+    }
+    if(currRing->N == 1)
+      WarnS("the current implementation of `lres` may not work in the case of a single variable");
+    r=syLaScala3(u_id,&dummy);
+  }
+  else if (iiOp == KRES_CMD)
+  {
+    int dummy;
+    if((currRing->qideal!=NULL)||
+    (!idHomIdeal (u_id,NULL)))
+    {
+       WerrorS
+       ("`kres` not implemented for inhomogeneous input or qring");
+       return TRUE;
+    }
+    r=syKosz(u_id,&dummy);
+  }
+  else
+  {
+    int dummy;
+    if((currRing->qideal!=NULL)||
+    (!idHomIdeal (u_id,NULL)))
+    {
+       WerrorS
+       ("`hres` not implemented for inhomogeneous input or qring");
+       return TRUE;
+    }
+    ideal u_id_copy=idCopy(u_id);
+    idSkipZeroes(u_id_copy);
+    r=syHilb(u_id_copy,&dummy);
+    idDelete(&u_id_copy);
+  }
+  if (r==NULL) return TRUE;
+  //res->data=(void *)liMakeResolv(r,l,wmaxl,u->Typ(),weights);
+  r->list_length=wmaxl;
+  res->data=(void *)r;
+  if ((weights!=NULL) && (ww!=NULL)) { delete ww; ww=NULL; }
+  if ((r->weights!=NULL) && (r->weights[0]!=NULL))
+  {
+    ww=ivCopy(r->weights[0]);
+    if (weights!=NULL) (*ww) += add_row_shift;
+    atSet(res,omStrDup("isHomog"),ww,INTVEC_CMD);
+  }
+  else
+  {
+    if (weights!=NULL)
+    {
+      atSet(res,omStrDup("isHomog"),ivCopy(weights),INTVEC_CMD);
+    }
+  }
+
+  // test the La Scala case' output
+  assume( ((iiOp == LRES_CMD) || (iiOp == HRES_CMD)) == (r->syRing != NULL) );
+  assume( (r->syRing != NULL) == (r->resPairs != NULL) );
+
+  if(iiOp != HRES_CMD)
+    assume( (r->minres != NULL) || (r->fullres != NULL) ); // is wrong for HRES_CMD...
+  else
+    assume( (r->orderedRes != NULL) || (r->res != NULL) ); // analog for hres...
+
+  return FALSE;
+}
+#endif
+static BOOLEAN jjPFAC2(leftv res, leftv u, leftv v)
+{
+  number n1; int i;
+
+  if ((u->Typ() == BIGINT_CMD) ||
+     ((u->Typ() == NUMBER_CMD) && rField_is_Q(currRing)))
+  {
+    n1 = (number)u->CopyD();
+  }
+  else if (u->Typ() == INT_CMD)
+  {
+    i = (int)(long)u->Data();
+    n1 = n_Init(i, coeffs_BIGINT);
+  }
+  else
+  {
+    return TRUE;
+  }
+
+  i = (int)(long)v->Data();
+
+  lists l = primeFactorisation(n1, i);
+  n_Delete(&n1, coeffs_BIGINT);
+  res->data = (char*)l;
+  return FALSE;
+}
+static BOOLEAN jjRSUM(leftv res, leftv u, leftv v)
+{
+  ring r;
+  int i=rSum((ring)u->Data(),(ring)v->Data(),r);
+  res->data = (char *)r;
+  return (i==-1);
+}
+#define SIMPL_LMDIV 32
+#define SIMPL_LMEQ  16
+#define SIMPL_MULT 8
+#define SIMPL_EQU  4
+#define SIMPL_NULL 2
+#define SIMPL_NORM 1
+static BOOLEAN jjSIMPL_ID(leftv res, leftv u, leftv v)
+{
+  int sw = (int)(long)v->Data();
+  // CopyD for IDEAL_CMD and MODUL_CMD are identical:
+  ideal id = (ideal)u->CopyD(IDEAL_CMD);
+  if (sw & SIMPL_LMDIV)
+  {
+    id_DelDiv(id,currRing);
+  }
+  if (sw & SIMPL_LMEQ)
+  {
+    id_DelLmEquals(id,currRing);
+  }
+  if (sw & SIMPL_MULT)
+  {
+    id_DelMultiples(id,currRing);
+  }
+  else if(sw & SIMPL_EQU)
+  {
+    id_DelEquals(id,currRing);
+  }
+  if (sw & SIMPL_NULL)
+  {
+    idSkipZeroes(id);
+  }
+  if (sw & SIMPL_NORM)
+  {
+    id_Norm(id,currRing);
+  }
+  res->data = (char * )id;
+  return FALSE;
+}
+extern int singclap_factorize_retry;
+static BOOLEAN jjSQR_FREE2(leftv res, leftv u, leftv dummy)
+{
+  intvec *v=NULL;
+  int sw=(int)(long)dummy->Data();
+  int fac_sw=sw;
+  if (sw<0) fac_sw=1;
+  singclap_factorize_retry=0;
+  ideal f=singclap_sqrfree((poly)(u->CopyD()), &v, fac_sw, currRing);
+  if (f==NULL)
+    return TRUE;
+  switch(sw)
+  {
+    case 0:
+    case 2:
+    {
+      lists l=(lists)omAllocBin(slists_bin);
+      l->Init(2);
+      l->m[0].rtyp=IDEAL_CMD;
+      l->m[0].data=(void *)f;
+      l->m[1].rtyp=INTVEC_CMD;
+      l->m[1].data=(void *)v;
+      res->data=(void *)l;
+      res->rtyp=LIST_CMD;
+      return FALSE;
+    }
+    case 1:
+      res->data=(void *)f;
+      return FALSE;
+    case 3:
+      {
+        poly p=f->m[0];
+        int i=IDELEMS(f);
+        f->m[0]=NULL;
+        while(i>1)
+        {
+          i--;
+          p=pMult(p,f->m[i]);
+          f->m[i]=NULL;
+        }
+        res->data=(void *)p;
+        res->rtyp=POLY_CMD;
+      }
+      return FALSE;
+  }
+  WerrorS("invalid switch");
+  return FALSE;
+}
+static BOOLEAN jjSTATUS2(leftv res, leftv u, leftv v)
+{
+  res->data = omStrDup(slStatus((si_link) u->Data(), (char *) v->Data()));
+  return FALSE;
+}
+static BOOLEAN jjSTATUS2L(leftv res, leftv u, leftv v)
+{
+  res->data = (void *)(long)slStatusSsiL((lists) u->Data(), (int)(long) v->Data());
+  //return (res->data== (void*)(long)-2);
+  return FALSE;
+}
+static BOOLEAN jjSIMPL_P(leftv res, leftv u, leftv v)
+{
+  int sw = (int)(long)v->Data();
+  // CopyD for POLY_CMD and VECTOR_CMD are identical:
+  poly p = (poly)u->CopyD(POLY_CMD);
+  if (sw & SIMPL_NORM)
+  {
+    pNorm(p);
+  }
+  res->data = (char * )p;
+  return FALSE;
+}
+static BOOLEAN jjSTD_HILB(leftv res, leftv u, leftv v)
+{
+  ideal result;
+  intvec *w=(intvec *)atGet(u,"isHomog",INTVEC_CMD);
+  tHomog hom=testHomog;
+  ideal u_id=(ideal)(u->Data());
+  if (w!=NULL)
+  {
+    if (!idTestHomModule(u_id,currRing->qideal,w))
+    {
+      WarnS("wrong weights:");w->show();PrintLn();
+      w=NULL;
+    }
+    else
+    {
+      w=ivCopy(w);
+      hom=isHomog;
+    }
+  }
+  result=kStd(u_id,currRing->qideal,hom,&w,(intvec *)v->Data());
+  idSkipZeroes(result);
+  res->data = (char *)result;
+  setFlag(res,FLAG_STD);
+  if (w!=NULL) atSet(res,omStrDup("isHomog"),w,INTVEC_CMD);
+  return FALSE;
+}
+static BOOLEAN jjSTD_1(leftv res, leftv u, leftv v);
+static void jjSTD_1_ID(leftv res, ideal i0, int t0, ideal p0, attr a)
+/* destroys i0, p0 */
+/* result (with attributes) in res */
+/* i0: SB*/
+/* t0: type of p0*/
+/* p0 new elements*/
+/* a attributes of i0*/
+{
+  int tp;
+  if (t0==IDEAL_CMD) tp=POLY_CMD;
+  else               tp=VECTOR_CMD;
+  for (int i=IDELEMS(p0)-1; i>=0; i--)
+  {
+    poly p=p0->m[i];
+    p0->m[i]=NULL;
+    if (p!=NULL)
+    {
+      sleftv u0,v0;
+      memset(&u0,0,sizeof(sleftv));
+      memset(&v0,0,sizeof(sleftv));
+      v0.rtyp=tp;
+      v0.data=(void*)p;
+      u0.rtyp=t0;
+      u0.data=i0;
+      u0.attribute=a;
+      setFlag(&u0,FLAG_STD);
+      jjSTD_1(res,&u0,&v0);
+      i0=(ideal)res->data;
+      res->data=NULL;
+      a=res->attribute;
+      res->attribute=NULL;
+      u0.CleanUp();
+      v0.CleanUp();
+      res->CleanUp();
+    }
+  }
+  idDelete(&p0);
+  res->attribute=a;
+  res->data=(void *)i0;
+  res->rtyp=t0;
+}
+static BOOLEAN jjSTD_1(leftv res, leftv u, leftv v)
+{
+  ideal result;
+  assumeStdFlag(u);
+  ideal i1=(ideal)(u->Data());
+  ideal i0;
+  int r=v->Typ();
+  if ((/*v->Typ()*/r==POLY_CMD) ||(r==VECTOR_CMD))
+  {
+    i0=idInit(1,i1->rank); // TODO: rank is wrong (if v is a vector!)
+    i0->m[0]=(poly)v->Data();
+    int ii0=idElem(i0); /* size of i0 */
+    i1=idSimpleAdd(i1,i0); //
+    memset(i0->m,0,sizeof(poly)*IDELEMS(i0));
+    idDelete(&i0);
+    intvec *w=(intvec *)atGet(u,"isHomog",INTVEC_CMD);
+    tHomog hom=testHomog;
+
+    if (w!=NULL)
+    {
+      if (!idTestHomModule(i1,currRing->qideal,w))
+      {
+        // no warnung: this is legal, if i in std(i,p)
+        // is homogeneous, but p not
+        w=NULL;
+      }
+      else
+      {
+        w=ivCopy(w);
+        hom=isHomog;
+      }
+    }
+    BITSET save1;
+    SI_SAVE_OPT1(save1);
+    si_opt_1|=Sy_bit(OPT_SB_1);
+    /* ii0 appears to be the position of the first element of il that
+       does not belong to the old SB ideal */
+    result=kStd(i1,currRing->qideal,hom,&w,NULL,0,ii0);
+    SI_RESTORE_OPT1(save1);
+    idDelete(&i1);
+    idSkipZeroes(result);
+    if (w!=NULL) atSet(res,omStrDup("isHomog"),w,INTVEC_CMD);
+    res->data = (char *)result;
+  }
+  else /*IDEAL/MODULE*/
+  {
+    attr *aa=u->Attribute();
+    attr a=NULL;
+    if ((aa!=NULL)&&(*aa!=NULL)) a=(*aa)->Copy();
+    jjSTD_1_ID(res,(ideal)u->CopyD(),r,(ideal)v->CopyD(),a);
+  }
+  if(!TEST_OPT_DEGBOUND) setFlag(res,FLAG_STD);
+  return FALSE;
+}
+static BOOLEAN jjVARSTR2(leftv res, leftv u, leftv v)
+{
+  idhdl h=(idhdl)u->data;
+  int i=(int)(long)v->Data();
+  if ((0<i) && (i<=IDRING(h)->N))
+    res->data=omStrDup(IDRING(h)->names[i-1]);
+  else
+  {
+    Werror("var number %d out of range 1..%d",i,IDRING(h)->N);
+    return TRUE;
+  }
+  return FALSE;
+}
+static BOOLEAN jjWAIT1ST2(leftv res, leftv u, leftv v)
+{
+// input: u: a list with links of type
+//           ssi-fork, ssi-tcp, MPtcp-fork or MPtcp-launch
+//        v: timeout for select in milliseconds
+//           or 0 for polling
+// returns: ERROR (via Werror): timeout negative
+//           -1: the read state of all links is eof
+//            0: timeout (or polling): none ready
+//           i>0: (at least) L[i] is ready
+  lists Lforks = (lists)u->Data();
+  int t = (int)(long)v->Data();
+  if(t < 0)
+  {
+    WerrorS("negative timeout"); return TRUE;
+  }
+  int i = slStatusSsiL(Lforks, t*1000);
+  if(i == -2) /* error */
+  {
+    return TRUE;
+  }
+  res->data = (void*)(long)i;
+  return FALSE;
+}
+static BOOLEAN jjWAITALL2(leftv res, leftv u, leftv v)
+{
+// input: u: a list with links of type
+//           ssi-fork, ssi-tcp, MPtcp-fork or MPtcp-launch
+//        v: timeout for select in milliseconds
+//           or 0 for polling
+// returns: ERROR (via Werror): timeout negative
+//           -1: the read state of all links is eof
+//           0: timeout (or polling): none ready
+//           1: all links are ready
+//              (caution: at least one is ready, but some maybe dead)
+  lists Lforks = (lists)u->CopyD();
+  int timeout = 1000*(int)(long)v->Data();
+  if(timeout < 0)
+  {
+    WerrorS("negative timeout"); return TRUE;
+  }
+  int t = getRTimer()/TIMER_RESOLUTION;  // in seconds
+  int i;
+  int ret = -1;
+  for(int nfinished = 0; nfinished < Lforks->nr+1; nfinished++)
+  {
+    i = slStatusSsiL(Lforks, timeout);
+    if(i > 0) /* Lforks[i] is ready */
+    {
+      ret = 1;
+      Lforks->m[i-1].CleanUp();
+      Lforks->m[i-1].rtyp=DEF_CMD;
+      Lforks->m[i-1].data=NULL;
+      timeout = si_max(0,timeout - 1000*(getRTimer()/TIMER_RESOLUTION - t));
+    }
+    else /* terminate the for loop */
+    {
+      if(i == -2) /* error */
+      {
+        return TRUE;
+      }
+      if(i == 0) /* timeout */
+      {
+        ret = 0;
+      }
+      break;
+    }
+  }
+  Lforks->Clean();
+  res->data = (void*)(long)ret;
+  return FALSE;
+}
+static BOOLEAN jjWEDGE(leftv res, leftv u, leftv v)
+{
+  res->data = (char *)mp_Wedge((matrix)u->Data(),(int)(long)v->Data(),currRing);
+  return FALSE;
+}
+#define jjWRONG2 (proc2)jjWRONG
+#define jjWRONG3 (proc3)jjWRONG
+static BOOLEAN jjWRONG(leftv, leftv)
+{
+  return TRUE;
+}
+
+/*=================== operations with 1 arg.: static proc =================*/
+/* must be ordered: first operations for chars (infix ops),
+ * then alphabetically */
+
+static BOOLEAN jjDUMMY(leftv res, leftv u)
+{
+  res->data = (char *)u->CopyD();
+  return FALSE;
+}
+static BOOLEAN jjNULL(leftv, leftv)
+{
+  return FALSE;
+}
+//static BOOLEAN jjPLUSPLUS(leftv res, leftv u)
+//{
+//  res->data = (char *)((int)(long)u->Data()+1);
+//  return FALSE;
+//}
+//static BOOLEAN jjMINUSMINUS(leftv res, leftv u)
+//{
+//  res->data = (char *)((int)(long)u->Data()-1);
+//  return FALSE;
+//}
+static BOOLEAN jjPLUSPLUS(leftv, leftv u)
+{
+  if (IDTYP((idhdl)u->data)==INT_CMD)
+  {
+    int i=IDINT((idhdl)u->data);
+    if (iiOp==PLUSPLUS) i++;
+    else                i--;
+    IDDATA((idhdl)u->data)=(char *)(long)i;
+    return FALSE;
+  }
+  return TRUE;
+}
+static BOOLEAN jjUMINUS_BI(leftv res, leftv u)
+{
+  number n=(number)u->CopyD(BIGINT_CMD);
+  n=n_InpNeg(n,coeffs_BIGINT);
+  res->data = (char *)n;
+  return FALSE;
+}
+static BOOLEAN jjUMINUS_I(leftv res, leftv u)
+{
+  res->data = (char *)(-(long)u->Data());
+  return FALSE;
+}
+static BOOLEAN jjUMINUS_N(leftv res, leftv u)
+{
+  number n=(number)u->CopyD(NUMBER_CMD);
+  n=nInpNeg(n);
+  res->data = (char *)n;
+  return FALSE;
+}
+static BOOLEAN jjUMINUS_P(leftv res, leftv u)
+{
+  res->data = (char *)pNeg((poly)u->CopyD(POLY_CMD));
+  return FALSE;
+}
+static BOOLEAN jjUMINUS_MA(leftv res, leftv u)
+{
+  poly m1=pISet(-1);
+  res->data = (char *)mp_MultP((matrix)u->CopyD(MATRIX_CMD),m1,currRing);
+  return FALSE;
+}
+static BOOLEAN jjUMINUS_IV(leftv res, leftv u)
+{
+  intvec *iv=(intvec *)u->CopyD(INTVEC_CMD);
+  (*iv)*=(-1);
+  res->data = (char *)iv;
+  return FALSE;
+}
+static BOOLEAN jjUMINUS_BIM(leftv res, leftv u)
+{
+  bigintmat *bim=(bigintmat *)u->CopyD(BIGINTMAT_CMD);
+  (*bim)*=(-1);
+  res->data = (char *)bim;
+  return FALSE;
+}
+static BOOLEAN jjPROC1(leftv res, leftv u)
+{
+  return jjPROC(res,u,NULL);
+}
+static BOOLEAN jjBAREISS(leftv res, leftv v)
+{
+  //matrix m=(matrix)v->Data();
+  //lists l=mpBareiss(m,FALSE);
+  intvec *iv;
+  ideal m;
+  sm_CallBareiss((ideal)v->Data(),0,0,m,&iv, currRing);
+  lists l=(lists)omAllocBin(slists_bin);
+  l->Init(2);
+  l->m[0].rtyp=MODUL_CMD;
+  l->m[1].rtyp=INTVEC_CMD;
+  l->m[0].data=(void *)m;
+  l->m[1].data=(void *)iv;
+  res->data = (char *)l;
+  return FALSE;
+}
+//static BOOLEAN jjBAREISS_IM(leftv res, leftv v)
+//{
+//  intvec *m=(intvec *)v->CopyD(INTMAT_CMD);
+//  ivTriangMat(m);
+//  res->data = (char *)m;
+//  return FALSE;
+//}
+static BOOLEAN jjBI2N(leftv res, leftv u)
+{
+  BOOLEAN bo=FALSE;
+  number n=(number)u->CopyD();
+  nMapFunc nMap=n_SetMap(coeffs_BIGINT,currRing->cf);
+  if (nMap!=NULL)
+    res->data=nMap(n,coeffs_BIGINT,currRing->cf);
+  else
+  {
+    Werror("cannot convert bigint to cring %s", nCoeffString(currRing->cf));
+    bo=TRUE;
+  }
+  n_Delete(&n,coeffs_BIGINT);
+  return bo;
+}
+static BOOLEAN jjBI2P(leftv res, leftv u)
+{
+  sleftv tmp;
+  BOOLEAN bo=jjBI2N(&tmp,u);
+  if (!bo)
+  {
+    number n=(number) tmp.data;
+    if (nIsZero(n)) { res->data=NULL;nDelete(&n); }
+    else
+    {
+      res->data=(void *)pNSet(n);
+    }
+  }
+  return bo;
+}
+static BOOLEAN jjCALL1MANY(leftv res, leftv u)
+{
+  return iiExprArithM(res,u,iiOp);
+}
+static BOOLEAN jjCHAR(leftv res, leftv v)
+{
+  res->data = (char *)(long)rChar((ring)v->Data());
+  return FALSE;
+}
+static BOOLEAN jjCOLS(leftv res, leftv v)
+{
+  res->data = (char *)(long)MATCOLS((matrix)(v->Data()));
+  return FALSE;
+}
+static BOOLEAN jjCOLS_BIM(leftv res, leftv v)
+{
+  res->data = (char *)(long)((bigintmat*)(v->Data()))->cols();
+  return FALSE;
+}
+static BOOLEAN jjCOLS_IV(leftv res, leftv v)
+{
+  res->data = (char *)(long)((intvec*)(v->Data()))->cols();
+  return FALSE;
+}
+static BOOLEAN jjCONTENT(leftv res, leftv v)
+{
+  // CopyD for POLY_CMD and VECTOR_CMD are identical:
+  poly p=(poly)v->CopyD(POLY_CMD);
+  if (p!=NULL) p_Cleardenom(p, currRing);
+  res->data = (char *)p;
+  return FALSE;
+}
+static BOOLEAN jjCOUNT_BI(leftv res, leftv v)
+{
+  res->data = (char *)(long)n_Size((number)v->Data(),coeffs_BIGINT);
+  return FALSE;
+}
+static BOOLEAN jjCOUNT_N(leftv res, leftv v)
+{
+  res->data = (char *)(long)nSize((number)v->Data());
+  return FALSE;
+}
+static BOOLEAN jjCOUNT_L(leftv res, leftv v)
+{
+  lists l=(lists)v->Data();
+  res->data = (char *)(long)(lSize(l)+1);
+  return FALSE;
+}
+static BOOLEAN jjCOUNT_M(leftv res, leftv v)
+{
+  matrix m=(matrix)v->Data();
+  res->data = (char *)(long)(MATROWS(m)*MATCOLS(m));
+  return FALSE;
+}
+static BOOLEAN jjCOUNT_IV(leftv res, leftv v)
+{
+  res->data = (char *)(long)((intvec*)(v->Data()))->length();
+  return FALSE;
+}
+static BOOLEAN jjCOUNT_RG(leftv res, leftv v)
+{
+  ring r=(ring)v->Data();
+  int elems=-1;
+  if (rField_is_Zp(r)||rField_is_GF(r)) elems=r->cf->ch;
+  else if (rField_is_Zp_a(r) && (r->cf->type==n_algExt))
+  {
+    extern int ipower ( int b, int n ); /* factory/cf_util */
+    elems=ipower(r->cf->ch,r->cf->extRing->pFDeg(r->cf->extRing->qideal->m[0],r->cf->extRing));
+  }
+  res->data = (char *)(long)elems;
+  return FALSE;
+}
+static BOOLEAN jjDEG(leftv res, leftv v)
+{
+  int dummy;
+  poly p=(poly)v->Data();
+  if (p!=NULL) res->data = (char *)currRing->pLDeg(p,&dummy,currRing);
+  else res->data=(char *)-1;
+  return FALSE;
+}
+static BOOLEAN jjDEG_M(leftv res, leftv u)
+{
+  ideal I=(ideal)u->Data();
+  int d=-1;
+  int dummy;
+  int i;
+  for(i=IDELEMS(I)-1;i>=0;i--)
+    if (I->m[i]!=NULL) d=si_max(d,(int)currRing->pLDeg(I->m[i],&dummy,currRing));
+  res->data = (char *)(long)d;
+  return FALSE;
+}
+static BOOLEAN jjDEGREE(leftv res, leftv v)
+{
+  SPrintStart();
+#ifdef HAVE_RINGS
+  if (rField_is_Ring_Z(currRing))
+  {
+    ring origR = currRing;
+    ring tempR = rCopy(origR);
+    coeffs new_cf=nInitChar(n_Q,NULL);
+    nKillChar(tempR->cf);
+    tempR->cf=new_cf;
+    rComplete(tempR);
+    ideal vid = (ideal)v->Data();
+    rChangeCurrRing(tempR);
+    ideal vv = idrCopyR(vid, origR, currRing);
+    sleftv vvAsLeftv; memset(&vvAsLeftv, 0, sizeof(vvAsLeftv));
+    vvAsLeftv.rtyp = IDEAL_CMD;
+    vvAsLeftv.data = vv; vvAsLeftv.next = NULL;
+    if (hasFlag(v, FLAG_STD)) setFlag(&vvAsLeftv,FLAG_STD);
+    assumeStdFlag(&vvAsLeftv);
+    Print("// NOTE: computation of degree is being performed for\n");
+    Print("//       generic fibre, that is, over Q\n");
+    intvec *module_w=(intvec*)atGet(&vvAsLeftv,"isHomog",INTVEC_CMD);
+    scDegree(vv,module_w,currRing->qideal);
+    idDelete(&vv);
+    rChangeCurrRing(origR);
+    rDelete(tempR);
+  }
+#endif
+  assumeStdFlag(v);
+  intvec *module_w=(intvec*)atGet(v,"isHomog",INTVEC_CMD);
+  scDegree((ideal)v->Data(),module_w,currRing->qideal);
+  char *s=SPrintEnd();
+  int l=strlen(s)-1;
+  s[l]='\0';
+  res->data=(void*)s;
+  return FALSE;
+}
+static BOOLEAN jjDEFINED(leftv res, leftv v)
+{
+  if ((v->rtyp==IDHDL)
+  && ((myynest==IDLEV((idhdl)v->data))||(0==IDLEV((idhdl)v->data))))
+  {
+    res->data=(void *)(long)(IDLEV((idhdl)v->data)+1);
+  }
+  else if (v->rtyp!=0) res->data=(void *)(-1);
+  return FALSE;
+}
+
+/// Return the denominator of the input number
+/// NOTE: the input number is normalized as a side effect
+static BOOLEAN jjDENOMINATOR(leftv res, leftv v)
+{
+  number n = reinterpret_cast<number>(v->Data());
+  res->data = reinterpret_cast<void*>(n_GetDenom(n, currRing));
+  return FALSE;
+}
+
+/// Return the numerator of the input number
+/// NOTE: the input number is normalized as a side effect
+static BOOLEAN jjNUMERATOR(leftv res, leftv v)
+{
+  number n = reinterpret_cast<number>(v->Data());
+  res->data = reinterpret_cast<void*>(n_GetNumerator(n, currRing));
+  return FALSE;
+}
+
+static BOOLEAN jjDET(leftv res, leftv v)
+{
+  matrix m=(matrix)v->Data();
+  poly p;
+  if (sm_CheckDet((ideal)m,m->cols(),TRUE, currRing))
+  {
+    ideal I=id_Matrix2Module(mp_Copy(m, currRing),currRing);
+    p=sm_CallDet(I, currRing);
+    idDelete(&I);
+  }
+  else
+    p=singclap_det(m,currRing);
+  res ->data = (char *)p;
+  return FALSE;
+}
+static BOOLEAN jjDET_BI(leftv res, leftv v)
+{
+  bigintmat * m=(bigintmat*)v->Data();
+  int i,j;
+  i=m->rows();j=m->cols();
+  if(i==j)
+    res->data = (char *)(long)singclap_det_bi(m,coeffs_BIGINT);
+  else
+  {
+    Werror("det of %d x %d bigintmat",i,j);
+    return TRUE;
+  }
+  return FALSE;
+}
+static BOOLEAN jjDET_I(leftv res, leftv v)
+{
+  intvec * m=(intvec*)v->Data();
+  int i,j;
+  i=m->rows();j=m->cols();
+  if(i==j)
+    res->data = (char *)(long)singclap_det_i(m,currRing);
+  else
+  {
+    Werror("det of %d x %d intmat",i,j);
+    return TRUE;
+  }
+  return FALSE;
+}
+static BOOLEAN jjDET_S(leftv res, leftv v)
+{
+  ideal I=(ideal)v->Data();
+  poly p;
+  if (IDELEMS(I)<1) return TRUE;
+  if (sm_CheckDet(I,IDELEMS(I),FALSE, currRing))
+  {
+    matrix m=id_Module2Matrix(id_Copy(I,currRing),currRing);
+    p=singclap_det(m,currRing);
+    idDelete((ideal *)&m);
+  }
+  else
+    p=sm_CallDet(I, currRing);
+  res->data = (char *)p;
+  return FALSE;
+}
+static BOOLEAN jjDIM(leftv res, leftv v)
+{
+  assumeStdFlag(v);
+#ifdef HAVE_RINGS
+  if (rField_is_Ring(currRing))
+  {
+    //ring origR = currRing;
+    //ring tempR = rCopy(origR);
+    //coeffs new_cf=nInitChar(n_Q,NULL);
+    //nKillChar(tempR->cf);
+    //tempR->cf=new_cf;
+    //rComplete(tempR);
+    ideal vid = (ideal)v->Data();
+    int i = idPosConstant(vid);
+    if ((i != -1) && (n_IsUnit(pGetCoeff(vid->m[i]),currRing->cf)))
+    { /* ideal v contains unit; dim = -1 */
+      res->data = (char *)-1;
+      return FALSE;
+    }
+    //rChangeCurrRing(tempR);
+    //ideal vv = idrCopyR(vid, origR, currRing);
+    ideal vv = id_Head(vid,currRing);
+    /* drop degree zero generator from vv (if any) */
+    if (i != -1) pDelete(&vv->m[i]);
+    long d = (long)scDimInt(vv, currRing->qideal);
+    if (rField_is_Ring_Z(currRing) && (i == -1)) d++;
+    res->data = (char *)d;
+    idDelete(&vv);
+    //rChangeCurrRing(origR);
+    //rDelete(tempR);
+    return FALSE;
+  }
+#endif
+  res->data = (char *)(long)scDimInt((ideal)(v->Data()),currRing->qideal);
+  return FALSE;
+}
+static BOOLEAN jjDUMP(leftv, leftv v)
+{
+  si_link l = (si_link)v->Data();
+  if (slDump(l))
+  {
+    const char *s;
+    if ((l!=NULL)&&(l->name!=NULL)) s=l->name;
+    else                            s=sNoName;
+    Werror("cannot dump to `%s`",s);
+    return TRUE;
+  }
+  else
+    return FALSE;
+}
+static BOOLEAN jjE(leftv res, leftv v)
+{
+  res->data = (char *)pOne();
+  int co=(int)(long)v->Data();
+  if (co>0)
+  {
+    pSetComp((poly)res->data,co);
+    pSetm((poly)res->data);
+  }
+  else WerrorS("argument of gen must be positive");
+  return (co<=0);
+}
+static BOOLEAN jjEXECUTE(leftv, leftv v)
+{
+  char * d = (char *)v->Data();
+  char * s = (char *)omAlloc(strlen(d) + 13);
+  strcpy( s, (char *)d);
+  strcat( s, "\n;RETURN();\n");
+  newBuffer(s,BT_execute);
+  return yyparse();
+}
+static BOOLEAN jjFACSTD(leftv res, leftv v)
+{
+  lists L=(lists)omAllocBin(slists_bin);
+  if (currRing->cf->convSingNFactoryN!=NULL) /* conversion to factory*/
+  {
+    ideal_list p,h;
+    h=kStdfac((ideal)v->Data(),NULL,testHomog,NULL);
+    if (h==NULL)
+    {
+      L->Init(1);
+      L->m[0].data=(char *)idInit(1);
+      L->m[0].rtyp=IDEAL_CMD;
+    }
+    else
+    {
+      p=h;
+      int l=0;
+      while (p!=NULL) { p=p->next;l++; }
+      L->Init(l);
+      l=0;
+      while(h!=NULL)
+      {
+        L->m[l].data=(char *)h->d;
+        L->m[l].rtyp=IDEAL_CMD;
+        p=h->next;
+        omFreeSize(h,sizeof(*h));
+        h=p;
+        l++;
+      }
+    }
+  }
+  else
+  {
+    WarnS("no factorization implemented");
+    L->Init(1);
+    iiExprArith1(&(L->m[0]),v,STD_CMD);
+  }
+  res->data=(void *)L;
+  return FALSE;
+}
+static BOOLEAN jjFAC_P(leftv res, leftv u)
+{
+  intvec *v=NULL;
+  singclap_factorize_retry=0;
+  ideal f=singclap_factorize((poly)(u->CopyD()), &v, 0,currRing);
+  if (f==NULL) return TRUE;
+  ivTest(v);
+  lists l=(lists)omAllocBin(slists_bin);
+  l->Init(2);
+  l->m[0].rtyp=IDEAL_CMD;
+  l->m[0].data=(void *)f;
+  l->m[1].rtyp=INTVEC_CMD;
+  l->m[1].data=(void *)v;
+  res->data=(void *)l;
+  return FALSE;
+}
+static BOOLEAN jjGETDUMP(leftv, leftv v)
+{
+  si_link l = (si_link)v->Data();
+  if (slGetDump(l))
+  {
+    const char *s;
+    if ((l!=NULL)&&(l->name!=NULL)) s=l->name;
+    else                            s=sNoName;
+    Werror("cannot get dump from `%s`",s);
+    return TRUE;
+  }
+  else
+    return FALSE;
+}
+static BOOLEAN jjHIGHCORNER(leftv res, leftv v)
+{
+  assumeStdFlag(v);
+  ideal I=(ideal)v->Data();
+  res->data=(void *)iiHighCorner(I,0);
+  return FALSE;
+}
+static BOOLEAN jjHIGHCORNER_M(leftv res, leftv v)
+{
+  assumeStdFlag(v);
+  intvec *w=(intvec*)atGet(v,"isHomog",INTVEC_CMD);
+  BOOLEAN delete_w=FALSE;
+  ideal I=(ideal)v->Data();
+  int i;
+  poly p=NULL,po=NULL;
+  int rk=id_RankFreeModule(I,currRing);
+  if (w==NULL)
+  {
+    w = new intvec(rk);
+    delete_w=TRUE;
+  }
+  for(i=rk;i>0;i--)
+  {
+    p=iiHighCorner(I,i);
+    if (p==NULL)
+    {
+      WerrorS("module must be zero-dimensional");
+      if (delete_w) delete w;
+      return TRUE;
+    }
+    if (po==NULL)
+    {
+      po=p;
+    }
+    else
+    {
+      // now po!=NULL, p!=NULL
+      int d=(currRing->pFDeg(po,currRing)-(*w)[pGetComp(po)-1] - currRing->pFDeg(p,currRing)+(*w)[i-1]);
+      if (d==0)
+        d=pLmCmp(po,p);
+      if (d > 0)
+      {
+        pDelete(&p);
+      }
+      else // (d < 0)
+      {
+        pDelete(&po); po=p;
+      }
+    }
+  }
+  if (delete_w) delete w;
+  res->data=(void *)po;
+  return FALSE;
+}
+static BOOLEAN jjHILBERT(leftv, leftv v)
+{
+#ifdef HAVE_RINGS
+  if (rField_is_Ring_Z(currRing))
+  {
+    ring origR = currRing;
+    ring tempR = rCopy(origR);
+    coeffs new_cf=nInitChar(n_Q,NULL);
+    nKillChar(tempR->cf);
+    tempR->cf=new_cf;
+    rComplete(tempR);
+    ideal vid = (ideal)v->Data();
+    rChangeCurrRing(tempR);
+    ideal vv = idrCopyR(vid, origR, currRing);
+    sleftv vvAsLeftv; memset(&vvAsLeftv, 0, sizeof(vvAsLeftv));
+    vvAsLeftv.rtyp = IDEAL_CMD;
+    vvAsLeftv.data = vv; vvAsLeftv.next = NULL;
+    if (hasFlag(v, FLAG_STD)) setFlag(&vvAsLeftv,FLAG_STD);
+    assumeStdFlag(&vvAsLeftv);
+    Print("// NOTE: computation of Hilbert series etc. is being\n");
+    Print("//       performed for generic fibre, that is, over Q\n");
+    intvec *module_w=(intvec*)atGet(&vvAsLeftv,"isHomog",INTVEC_CMD);
+    //scHilbertPoly(vv,currRing->qideal);
+    hLookSeries(vv,module_w,currRing->qideal);
+    idDelete(&vv);
+    rChangeCurrRing(origR);
+    rDelete(tempR);
+    return FALSE;
+  }
+#endif
+  assumeStdFlag(v);
+  intvec *module_w=(intvec*)atGet(v,"isHomog",INTVEC_CMD);
+  //scHilbertPoly((ideal)v->Data(),currRing->qideal);
+  hLookSeries((ideal)v->Data(),module_w,currRing->qideal);
+  return FALSE;
+}
+static BOOLEAN jjHILBERT_IV(leftv res, leftv v)
+{
+#ifdef HAVE_RINGS
+  if (rField_is_Ring_Z(currRing))
+  {
+    Print("// NOTE: computation of Hilbert series etc. is being\n");
+    Print("//       performed for generic fibre, that is, over Q\n");
+  }
+#endif
+  res->data=(void *)hSecondSeries((intvec *)v->Data());
+  return FALSE;
+}
+static BOOLEAN jjHOMOG1(leftv res, leftv v)
+{
+  intvec *w=(intvec*)atGet(v,"isHomog",INTVEC_CMD);
+  ideal v_id=(ideal)v->Data();
+  if (w==NULL)
+  {
+    res->data=(void *)(long)idHomModule(v_id,currRing->qideal,&w);
+    if (res->data!=NULL)
+    {
+      if (v->rtyp==IDHDL)
+      {
+        char *s_isHomog=omStrDup("isHomog");
+        if (v->e==NULL)
+          atSet((idhdl)(v->data),s_isHomog,w,INTVEC_CMD);
+        else
+          atSet((idhdl)(v->LData()),s_isHomog,w,INTVEC_CMD);
+      }
+      else if (w!=NULL) delete w;
+    } // if res->data==NULL then w==NULL
+  }
+  else
+  {
+    res->data=(void *)(long)idTestHomModule(v_id,currRing->qideal,w);
+    if((res->data==NULL) && (v->rtyp==IDHDL))
+    {
+      if (v->e==NULL)
+        atKill((idhdl)(v->data),"isHomog");
+      else
+        atKill((idhdl)(v->LData()),"isHomog");
+    }
+  }
+  return FALSE;
+}
+static BOOLEAN jjidMaxIdeal(leftv res, leftv v)
+{
+  res->data = (char *)idMaxIdeal((int)(long)v->Data());
+  setFlag(res,FLAG_STD);
+  return FALSE;
+}
+static BOOLEAN jjIDEAL_Ma(leftv res, leftv v)
+{
+  matrix mat=(matrix)v->CopyD(MATRIX_CMD);
+  IDELEMS((ideal)mat)=MATCOLS(mat)*MATROWS(mat);
+  if (IDELEMS((ideal)mat)==0)
+  {
+    idDelete((ideal *)&mat);
+    mat=(matrix)idInit(1,1);
+  }
+  else
+  {
+    MATROWS(mat)=1;
+    mat->rank=1;
+    idTest((ideal)mat);
+  }
+  res->data=(char *)mat;
+  return FALSE;
+}
+static BOOLEAN jjIDEAL_Map(leftv res, leftv v)
+{
+  map m=(map)v->CopyD(MAP_CMD);
+  omFree((ADDRESS)m->preimage);
+  m->preimage=NULL;
+  ideal I=(ideal)m;
+  I->rank=1;
+  res->data=(char *)I;
+  return FALSE;
+}
+static BOOLEAN jjIDEAL_R(leftv res, leftv v)
+{
+  if (currRing!=NULL)
+  {
+    ring q=(ring)v->Data();
+    if (rSamePolyRep(currRing, q))
+    {
+      if (q->qideal==NULL)
+        res->data=(char *)idInit(1,1);
+      else
+        res->data=(char *)idCopy(q->qideal);
+      return FALSE;
+    }
+  }
+  WerrorS("can only get ideal from identical qring");
+  return TRUE;
+}
+static BOOLEAN jjIm2Iv(leftv res, leftv v)
+{
+  intvec *iv = (intvec *)v->CopyD(INTMAT_CMD);
+  iv->makeVector();
+  res->data = iv;
+  return FALSE;
+}
+static BOOLEAN jjIMPART(leftv res, leftv v)
+{
+  res->data = (char *)n_ImPart((number)v->Data(),currRing->cf);
+  return FALSE;
+}
+static BOOLEAN jjINDEPSET(leftv res, leftv v)
+{
+  assumeStdFlag(v);
+  res->data=(void *)scIndIntvec((ideal)(v->Data()),currRing->qideal);
+  return FALSE;
+}
+static BOOLEAN jjINTERRED(leftv res, leftv v)
+{
+  ideal result=kInterRed((ideal)(v->Data()), currRing->qideal);
+  #ifdef HAVE_RINGS
+  if(rField_is_Ring(currRing))
+    Warn("interred: this command is experimental over the integers");
+  #endif
+  if (TEST_OPT_PROT) { PrintLn(); mflush(); }
+  res->data = result;
+  return FALSE;
+}
+static BOOLEAN jjIS_RINGVAR_P(leftv res, leftv v)
+{
+  res->data = (char *)(long)pVar((poly)v->Data());
+  return FALSE;
+}
+static BOOLEAN jjIS_RINGVAR_S(leftv res, leftv v)
+{
+  res->data = (char *)(long)(r_IsRingVar((char *)v->Data(), currRing->names,
+                                                            currRing->N)+1);
+  return FALSE;
+}
+static BOOLEAN jjIS_RINGVAR0(leftv res, leftv)
+{
+  res->data = (char *)0;
+  return FALSE;
+}
+static BOOLEAN jjJACOB_P(leftv res, leftv v)
+{
+  ideal i=idInit(currRing->N,1);
+  int k;
+  poly p=(poly)(v->Data());
+  for (k=currRing->N;k>0;k--)
+  {
+    i->m[k-1]=pDiff(p,k);
+  }
+  res->data = (char *)i;
+  return FALSE;
+}
+static BOOLEAN jjDIFF_COEF(leftv res, leftv u, leftv v)
+{
+  if (!nCoeff_is_transExt(currRing->cf))
+  {
+    WerrorS("differentiation not defined in the coefficient ring");
+    return TRUE;
+  }
+  number n = (number) u->Data();
+  number k = (number) v->Data();
+  res->data = ntDiff(n,k,currRing->cf);
+  return FALSE;
+}
+/*2
+ * compute Jacobi matrix of a module/matrix
+ * Jacobi(M) := ( diff(Mt,var(1))|, ... ,| diff(Mt,var(currRing->N))  ),
+ * where Mt := transpose(M)
+ * Note that this is consistent with the current conventions for jacob in Singular,
+ * whereas M2 computes its transposed.
+ */
+static BOOLEAN jjJACOB_M(leftv res, leftv a)
+{
+  ideal id = (ideal)a->Data();
+  id = idTransp(id);
+  int W = IDELEMS(id);
+
+  ideal result = idInit(W * currRing->N, id->rank);
+  poly *p = result->m;
+
+  for( int v = 1; v <= currRing->N; v++ )
+  {
+    poly* q = id->m;
+    for( int i = 0; i < W; i++, p++, q++ )
+      *p = pDiff( *q, v );
+  }
+  idDelete(&id);
+
+  res->data = (char *)result;
+  return FALSE;
+}
+
+
+static BOOLEAN jjKBASE(leftv res, leftv v)
+{
+  assumeStdFlag(v);
+  res->data = (char *)scKBase(-1,(ideal)(v->Data()),currRing->qideal);
+  return FALSE;
+}
+static BOOLEAN jjL2R(leftv res, leftv v)
+{
+  res->data=(char *)syConvList((lists)v->Data(),FALSE);
+  if (res->data != NULL)
+    return FALSE;
+  else
+    return TRUE;
+}
+static BOOLEAN jjLEADCOEF(leftv res, leftv v)
+{
+  poly p=(poly)v->Data();
+  if (p==NULL)
+  {
+    res->data=(char *)nInit(0);
+  }
+  else
+  {
+    res->data=(char *)nCopy(pGetCoeff(p));
+  }
+  return FALSE;
+}
+static BOOLEAN jjLEADEXP(leftv res, leftv v)
+{
+  poly p=(poly)v->Data();
+  int s=currRing->N;
+  if (v->Typ()==VECTOR_CMD) s++;
+  intvec *iv=new intvec(s);
+  if (p!=NULL)
+  {
+    for(int i = currRing->N;i;i--)
+    {
+      (*iv)[i-1]=pGetExp(p,i);
+    }
+    if (s!=currRing->N)
+      (*iv)[currRing->N]=pGetComp(p);
+  }
+  res->data=(char *)iv;
+  return FALSE;
+}
+static BOOLEAN jjLEADMONOM(leftv res, leftv v)
+{
+  poly p=(poly)v->Data();
+  if (p == NULL)
+  {
+    res->data = (char*) NULL;
+  }
+  else
+  {
+    poly lm = pLmInit(p);
+    pSetCoeff(lm, nInit(1));
+    res->data = (char*) lm;
+  }
+  return FALSE;
+}
+static BOOLEAN jjLOAD1(leftv /*res*/, leftv v)
+{
+  return jjLOAD((char*)v->Data(),FALSE);
+}
+static BOOLEAN jjLISTRING(leftv res, leftv v)
+{
+  ring r=rCompose((lists)v->Data());
+  if (r==NULL) return TRUE;
+  if (r->qideal!=NULL) res->rtyp=QRING_CMD;
+  res->data=(char *)r;
+  return FALSE;
+}
+static BOOLEAN jjPFAC1(leftv res, leftv v)
+{
+  /* call method jjPFAC2 with second argument = 0 (meaning that no
+     valid bound for the prime factors has been given) */
+  sleftv tmp;
+  memset(&tmp, 0, sizeof(tmp));
+  tmp.rtyp = INT_CMD;
+  return jjPFAC2(res, v, &tmp);
+}
+static BOOLEAN jjLU_DECOMP(leftv res, leftv v)
+{
+  /* computes the LU-decomposition of a matrix M;
+     i.e., M = P * L * U, where
+        - P is a row permutation matrix,
+        - L is in lower triangular form,
+        - U is in upper row echelon form
+     Then, we also have P * M = L * U.
+     A list [P, L, U] is returned. */
+  matrix mat = (const matrix)v->Data();
+  if (!idIsConstant((ideal)mat))
+  {
+    WerrorS("matrix must be constant");
+    return TRUE;
+  }
+  matrix pMat;
+  matrix lMat;
+  matrix uMat;
+
+  luDecomp(mat, pMat, lMat, uMat);
+
+  lists ll = (lists)omAllocBin(slists_bin);
+  ll->Init(3);
+  ll->m[0].rtyp=MATRIX_CMD; ll->m[0].data=(void *)pMat;
+  ll->m[1].rtyp=MATRIX_CMD; ll->m[1].data=(void *)lMat;
+  ll->m[2].rtyp=MATRIX_CMD; ll->m[2].data=(void *)uMat;
+  res->data=(char*)ll;
+
+  return FALSE;
+}
+static BOOLEAN jjMEMORY(leftv res, leftv v)
+{
+  omUpdateInfo();
+  switch(((int)(long)v->Data()))
+  {
+  case 0:
+    res->data=(char *)n_Init(om_Info.UsedBytes,coeffs_BIGINT);
+    break;
+  case 1:
+    res->data = (char *)n_Init(om_Info.CurrentBytesSystem,coeffs_BIGINT);
+    break;
+  case 2:
+    res->data = (char *)n_Init(om_Info.MaxBytesSystem,coeffs_BIGINT);
+    break;
+  default:
+    omPrintStats(stdout);
+    omPrintInfo(stdout);
+    omPrintBinStats(stdout);
+    res->data = (char *)0;
+    res->rtyp = NONE;
+  }
+  return FALSE;
+  res->data = (char *)0;
+  return FALSE;
+}
+//static BOOLEAN jjMONITOR1(leftv res, leftv v)
+//{
+//  return jjMONITOR2(res,v,NULL);
+//}
+static BOOLEAN jjMSTD(leftv res, leftv v)
+{
+  int t=v->Typ();
+  ideal r,m;
+  r=kMin_std((ideal)v->Data(),currRing->qideal,testHomog,NULL,m);
+  lists l=(lists)omAllocBin(slists_bin);
+  l->Init(2);
+  l->m[0].rtyp=t;
+  l->m[0].data=(char *)r;
+  setFlag(&(l->m[0]),FLAG_STD);
+  l->m[1].rtyp=t;
+  l->m[1].data=(char *)m;
+  res->data=(char *)l;
+  return FALSE;
+}
+static BOOLEAN jjMULT(leftv res, leftv v)
+{
+  assumeStdFlag(v);
+  res->data = (char *)(long)scMultInt((ideal)(v->Data()),currRing->qideal);
+  return FALSE;
+}
+static BOOLEAN jjMINRES_R(leftv res, leftv v)
+{
+  intvec *weights=(intvec*)atGet(v,"isHomog",INTVEC_CMD);
+
+  syStrategy tmp=(syStrategy)v->Data();
+  tmp = syMinimize(tmp); // enrich itself!
+
+  res->data=(char *)tmp;
+
+  if (weights!=NULL)
+    atSet(res, omStrDup("isHomog"),ivCopy(weights),INTVEC_CMD);
+
+  return FALSE;
+}
+static BOOLEAN jjN2BI(leftv res, leftv v)
+{
+  number n,i; i=(number)v->Data();
+  nMapFunc nMap=n_SetMap(currRing->cf,coeffs_BIGINT);
+  if (nMap!=NULL)
+    n=nMap(i,currRing->cf,coeffs_BIGINT);
+  else goto err;
+  res->data=(void *)n;
+  return FALSE;
+err:
+  WerrorS("cannot convert to bigint"); return TRUE;
+}
+static BOOLEAN jjNAMEOF(leftv res, leftv v)
+{
+  res->data = (char *)v->name;
+  if (res->data==NULL) res->data=omStrDup("");
+  v->name=NULL;
+  return FALSE;
+}
+static BOOLEAN jjNAMES(leftv res, leftv v)
+{
+  res->data=ipNameList(((ring)v->Data())->idroot);
+  return FALSE;
+}
+static BOOLEAN jjNAMES_I(leftv res, leftv v)
+{
+  res->data=ipNameListLev((IDROOT),(int)(long)v->Data());
+  return FALSE;
+}
+static BOOLEAN jjNOT(leftv res, leftv v)
+{
+  res->data=(char*)(long)((long)v->Data()==0 ? 1 : 0);
+  return FALSE;
+}
+static BOOLEAN jjNVARS(leftv res, leftv v)
+{
+  res->data = (char *)(long)(((ring)(v->Data()))->N);
+  return FALSE;
+}
+static BOOLEAN jjOpenClose(leftv, leftv v)
+{
+  si_link l=(si_link)v->Data();
+  if (iiOp==OPEN_CMD) return slOpen(l, SI_LINK_OPEN,v);
+  else                return slClose(l);
+}
+static BOOLEAN jjORD(leftv res, leftv v)
+{
+  poly p=(poly)v->Data();
+  res->data=(char *)( p==NULL ? -1 : currRing->pFDeg(p,currRing) );
+  return FALSE;
+}
+static BOOLEAN jjPAR1(leftv res, leftv v)
+{
+  int i=(int)(long)v->Data();
+  int p=0;
+  p=rPar(currRing);
+  if ((0<i) && (i<=p))
+  {
+    res->data=(char *)n_Param(i,currRing);
+  }
+  else
+  {
+    Werror("par number %d out of range 1..%d",i,p);
+    return TRUE;
+  }
+  return FALSE;
+}
+static BOOLEAN jjPARDEG(leftv res, leftv v)
+{
+  number nn=(number)v->Data();
+  res->data = (char *)(long)n_ParDeg(nn, currRing);
+  return FALSE;
+}
+static BOOLEAN jjPARSTR1(leftv res, leftv v)
+{
+  if (currRing==NULL)
+  {
+    WerrorS("no ring active");
+    return TRUE;
+  }
+  int i=(int)(long)v->Data();
+  int p=0;
+  if ((0<i) && (rParameter(currRing)!=NULL) && (i<=(p=rPar(currRing))))
+    res->data=omStrDup(rParameter(currRing)[i-1]);
+  else
+  {
+    Werror("par number %d out of range 1..%d",i,p);
+    return TRUE;
+  }
+  return FALSE;
+}
+static BOOLEAN jjP2BI(leftv res, leftv v)
+{
+  poly p=(poly)v->Data();
+  if (p==NULL) { res->data=(char *)n_Init(0,coeffs_BIGINT); return FALSE; }
+  if ((pNext(p)!=NULL)|| (!pIsConstant(p)))
+  {
+    WerrorS("poly must be constant");
+    return TRUE;
+  }
+  number i=pGetCoeff(p);
+  number n;
+  nMapFunc nMap=n_SetMap(currRing->cf,coeffs_BIGINT);
+  if (nMap!=NULL)
+    n=nMap(i,currRing->cf,coeffs_BIGINT);
+  else goto err;
+  res->data=(void *)n;
+  return FALSE;
+err:
+  WerrorS("cannot convert to bigint"); return TRUE;
+}
+static BOOLEAN jjP2I(leftv res, leftv v)
+{
+  poly p=(poly)v->Data();
+  if (p==NULL) { /*res->data=(char *)0;*/ return FALSE; }
+  if ((pNext(p)!=NULL)|| (!pIsConstant(p)))
+  {
+    WerrorS("poly must be constant");
+    return TRUE;
+  }
+  res->data = (char *)(long)n_Int(pGetCoeff(p),currRing->cf);
+  return FALSE;
+}
+static BOOLEAN jjPREIMAGE_R(leftv res, leftv v)
+{
+  map mapping=(map)v->Data();
+  syMake(res,omStrDup(mapping->preimage));
+  return FALSE;
+}
+static BOOLEAN jjPRIME(leftv res, leftv v)
+{
+  int i = IsPrime((int)(long)(v->Data()));
+  res->data = (char *)(long)(i > 1 ? i : 2);
+  return FALSE;
+}
+static BOOLEAN jjPRUNE(leftv res, leftv v)
+{
+  intvec *w=(intvec *)atGet(v,"isHomog",INTVEC_CMD);
+  ideal v_id=(ideal)v->Data();
+  if (w!=NULL)
+  {
+    if (!idTestHomModule(v_id,currRing->qideal,w))
+    {
+      WarnS("wrong weights");
+      w=NULL;
+      // and continue at the non-homog case below
+    }
+    else
+    {
+      w=ivCopy(w);
+      intvec **ww=&w;
+      res->data = (char *)idMinEmbedding(v_id,FALSE,ww);
+      atSet(res,omStrDup("isHomog"),*ww,INTVEC_CMD);
+      return FALSE;
+    }
+  }
+  res->data = (char *)idMinEmbedding(v_id);
+  return FALSE;
+}
+static BOOLEAN jjP2N(leftv res, leftv v)
+{
+  number n;
+  poly p;
+  if (((p=(poly)v->Data())!=NULL)
+  && (pIsConstant(p)))
+  {
+    n=nCopy(pGetCoeff(p));
+  }
+  else
+  {
+    n=nInit(0);
+  }
+  res->data = (char *)n;
+  return FALSE;
+}
+static BOOLEAN jjRESERVEDNAME(leftv res, leftv v)
+{
+  char *s= (char *)v->Data();
+  int i = 1;
+  for(i=0; i<sArithBase.nCmdUsed; i++)
+  {
+    //Print("test %d, >>%s<<, tab:>>%s<<\n",i,s,sArithBase.sCmds[i].name);
+    if (strcmp(s, sArithBase.sCmds[i].name) == 0)
+    {
+      res->data = (char *)1;
+      return FALSE;
+    }
+  }
+  //res->data = (char *)0;
+  return FALSE;
+}
+static BOOLEAN jjRANK1(leftv res, leftv v)
+{
+  matrix m =(matrix)v->Data();
+  int rank = luRank(m, 0);
+  res->data =(char *)(long)rank;
+  return FALSE;
+}
+static BOOLEAN jjREAD(leftv res, leftv v)
+{
+  return jjREAD2(res,v,NULL);
+}
+static BOOLEAN jjREGULARITY(leftv res, leftv v)
+{
+  res->data = (char *)(long)iiRegularity((lists)v->Data());
+  return FALSE;
+}
+static BOOLEAN jjREPART(leftv res, leftv v)
+{
+  res->data = (char *)n_RePart((number)v->Data(),currRing->cf);
+  return FALSE;
+}
+static BOOLEAN jjRINGLIST(leftv res, leftv v)
+{
+  ring r=(ring)v->Data();
+  if (r!=NULL)
+    res->data = (char *)rDecompose((ring)v->Data());
+  return (r==NULL)||(res->data==NULL);
+}
+static BOOLEAN jjROWS(leftv res, leftv v)
+{
+  ideal i = (ideal)v->Data();
+  res->data = (char *)i->rank;
+  return FALSE;
+}
+static BOOLEAN jjROWS_BIM(leftv res, leftv v)
+{
+  res->data = (char *)(long)((bigintmat*)(v->Data()))->rows();
+  return FALSE;
+}
+static BOOLEAN jjROWS_IV(leftv res, leftv v)
+{
+  res->data = (char *)(long)((intvec*)(v->Data()))->rows();
+  return FALSE;
+}
+static BOOLEAN jjRPAR(leftv res, leftv v)
+{
+  res->data = (char *)(long)rPar(((ring)v->Data()));
+  return FALSE;
+}
+static BOOLEAN jjSLIM_GB(leftv res, leftv u)
+{
+#ifdef HAVE_PLURAL
+  const bool bIsSCA = rIsSCA(currRing);
+#else
+  const bool bIsSCA = false;
+#endif
+
+  if ((currRing->qideal!=NULL) && !bIsSCA)
+  {
+    WerrorS("qring not supported by slimgb at the moment");
+    return TRUE;
+  }
+  if (rHasLocalOrMixedOrdering_currRing())
+  {
+    WerrorS("ordering must be global for slimgb");
+    return TRUE;
+  }
+  intvec *w=(intvec *)atGet(u,"isHomog",INTVEC_CMD);
+  // tHomog hom=testHomog;
+  ideal u_id=(ideal)u->Data();
+  if (w!=NULL)
+  {
+    if (!idTestHomModule(u_id,currRing->qideal,w))
+    {
+      WarnS("wrong weights");
+      w=NULL;
+    }
+    else
+    {
+      w=ivCopy(w);
+      // hom=isHomog;
+    }
+  }
+
+  assume(u_id->rank>=id_RankFreeModule(u_id, currRing));
+  res->data=(char *)t_rep_gb(currRing,
+    u_id,u_id->rank);
+  //res->data=(char *)t_rep_gb(currRing, u_id);
+
+  if(!TEST_OPT_DEGBOUND) setFlag(res,FLAG_STD);
+  if (w!=NULL) atSet(res,omStrDup("isHomog"),w,INTVEC_CMD);
+  return FALSE;
+}
+static BOOLEAN jjSBA(leftv res, leftv v)
+{
+  ideal result;
+  ideal v_id=(ideal)v->Data();
+  intvec *w=(intvec *)atGet(v,"isHomog",INTVEC_CMD);
+  tHomog hom=testHomog;
+  if (w!=NULL)
+  {
+    if (!idTestHomModule(v_id,currRing->qideal,w))
+    {
+      WarnS("wrong weights");
+      w=NULL;
+    }
+    else
+    {
+      hom=isHomog;
+      w=ivCopy(w);
+    }
+  }
+  result=kSba(v_id,currRing->qideal,hom,&w,1,0);
+  idSkipZeroes(result);
+  res->data = (char *)result;
+  if(!TEST_OPT_DEGBOUND) setFlag(res,FLAG_STD);
+  if (w!=NULL) atSet(res,omStrDup("isHomog"),w,INTVEC_CMD);
+  return FALSE;
+}
+static BOOLEAN jjSBA_1(leftv res, leftv v, leftv u)
+{
+  ideal result;
+  ideal v_id=(ideal)v->Data();
+  intvec *w=(intvec *)atGet(v,"isHomog",INTVEC_CMD);
+  tHomog hom=testHomog;
+  if (w!=NULL)
+  {
+    if (!idTestHomModule(v_id,currRing->qideal,w))
+    {
+      WarnS("wrong weights");
+      w=NULL;
+    }
+    else
+    {
+      hom=isHomog;
+      w=ivCopy(w);
+    }
+  }
+  result=kSba(v_id,currRing->qideal,hom,&w,(int)(long)u->Data(),0);
+  idSkipZeroes(result);
+  res->data = (char *)result;
+  if(!TEST_OPT_DEGBOUND) setFlag(res,FLAG_STD);
+  if (w!=NULL) atSet(res,omStrDup("isHomog"),w,INTVEC_CMD);
+  return FALSE;
+}
+static BOOLEAN jjSBA_2(leftv res, leftv v, leftv u, leftv t)
+{
+  ideal result;
+  ideal v_id=(ideal)v->Data();
+  intvec *w=(intvec *)atGet(v,"isHomog",INTVEC_CMD);
+  tHomog hom=testHomog;
+  if (w!=NULL)
+  {
+    if (!idTestHomModule(v_id,currRing->qideal,w))
+    {
+      WarnS("wrong weights");
+      w=NULL;
+    }
+    else
+    {
+      hom=isHomog;
+      w=ivCopy(w);
+    }
+  }
+  result=kSba(v_id,currRing->qideal,hom,&w,(int)(long)u->Data(),(int)(long)t->Data());
+  idSkipZeroes(result);
+  res->data = (char *)result;
+  if(!TEST_OPT_DEGBOUND) setFlag(res,FLAG_STD);
+  if (w!=NULL) atSet(res,omStrDup("isHomog"),w,INTVEC_CMD);
+  return FALSE;
+}
+static BOOLEAN jjSTD(leftv res, leftv v)
+{
+  ideal result;
+  ideal v_id=(ideal)v->Data();
+  intvec *w=(intvec *)atGet(v,"isHomog",INTVEC_CMD);
+  tHomog hom=testHomog;
+  if (w!=NULL)
+  {
+    if (!idTestHomModule(v_id,currRing->qideal,w))
+    {
+      WarnS("wrong weights");
+      w=NULL;
+    }
+    else
+    {
+      hom=isHomog;
+      w=ivCopy(w);
+    }
+  }
+  result=kStd(v_id,currRing->qideal,hom,&w);
+  idSkipZeroes(result);
+  res->data = (char *)result;
+  if(!TEST_OPT_DEGBOUND) setFlag(res,FLAG_STD);
+  if (w!=NULL) atSet(res,omStrDup("isHomog"),w,INTVEC_CMD);
+  return FALSE;
+}
+static BOOLEAN jjSort_Id(leftv res, leftv v)
+{
+  res->data = (char *)idSort((ideal)v->Data());
+  return FALSE;
+}
+static BOOLEAN jjSQR_FREE(leftv res, leftv u)
+{
+  singclap_factorize_retry=0;
+  intvec *v=NULL;
+  ideal f=singclap_sqrfree((poly)(u->CopyD()), &v, 0, currRing);
+  if (f==NULL) return TRUE;
+  ivTest(v);
+  lists l=(lists)omAllocBin(slists_bin);
+  l->Init(2);
+  l->m[0].rtyp=IDEAL_CMD;
+  l->m[0].data=(void *)f;
+  l->m[1].rtyp=INTVEC_CMD;
+  l->m[1].data=(void *)v;
+  res->data=(void *)l;
+  return FALSE;
+}
+#if 1
+static BOOLEAN jjSYZYGY(leftv res, leftv v)
+{
+  intvec *w=NULL;
+  res->data = (char *)idSyzygies((ideal)v->Data(),testHomog,&w);
+  if (w!=NULL) delete w;
+  if (TEST_OPT_RETURN_SB) setFlag(res,FLAG_STD);
+  return FALSE;
+}
+#else
+// activate, if idSyz handle module weights correctly !
+static BOOLEAN jjSYZYGY(leftv res, leftv v)
+{
+  intvec *w=(intvec *)atGet(v,"isHomog",INTVEC_CMD);
+  ideal v_id=(ideal)v->Data();
+  tHomog hom=testHomog;
+  int add_row_shift=0;
+  if (w!=NULL)
+  {
+    w=ivCopy(w);
+    add_row_shift=w->min_in();
+    (*w)-=add_row_shift;
+    if (idTestHomModule(v_id,currRing->qideal,w))
+      hom=isHomog;
+    else
+    {
+      //WarnS("wrong weights");
+      delete w; w=NULL;
+      hom=testHomog;
+    }
+  }
+  res->data = (char *)idSyzygies(v_id,hom,&w);
+  if (w!=NULL)
+  {
+    atSet(res,omStrDup("isHomog"),w,INTVEC_CMD);
+  }
+  return FALSE;
+}
+#endif
+static BOOLEAN jjTRACE_IV(leftv res, leftv v)
+{
+  res->data = (char *)(long)ivTrace((intvec*)(v->Data()));
+  return FALSE;
+}
+static BOOLEAN jjTRANSP_BIM(leftv res, leftv v)
+{
+  res->data = (char *)(((bigintmat*)(v->Data()))->transpose());
+  return FALSE;
+}
+static BOOLEAN jjTRANSP_IV(leftv res, leftv v)
+{
+  res->data = (char *)ivTranp((intvec*)(v->Data()));
+  return FALSE;
+}
+#ifdef HAVE_PLURAL
+static BOOLEAN jjOPPOSITE(leftv res, leftv a)
+{
+  ring    r = (ring)a->Data();
+  //if (rIsPluralRing(r))
+  if (r->OrdSgn==1)
+  {
+    res->data = rOpposite(r);
+  }
+  else
+  {
+    WarnS("opposite only for global orderings");
+    res->data = rCopy(r);
+  }
+  return FALSE;
+}
+static BOOLEAN jjENVELOPE(leftv res, leftv a)
+{
+  ring    r = (ring)a->Data();
+  if (rIsPluralRing(r))
+  {
+    //    ideal   i;
+//     if (a->rtyp == QRING_CMD)
+//     {
+//       i = r->qideal;
+//       r->qideal = NULL;
+//     }
+    ring s = rEnvelope(r);
+//     if (a->rtyp == QRING_CMD)
+//     {
+//       ideal is  = idOppose(r,i); /* twostd? */
+//       is        = idAdd(is,i);
+//       s->qideal = i;
+//     }
+    res->data = s;
+  }
+  else  res->data = rCopy(r);
+  return FALSE;
+}
+static BOOLEAN jjTWOSTD(leftv res, leftv a)
+{
+  if (rIsPluralRing(currRing))  res->data=(ideal)twostd((ideal)a->Data());
+  else  res->data=(ideal)a->CopyD();
+  setFlag(res,FLAG_STD);
+  setFlag(res,FLAG_TWOSTD);
+  return FALSE;
+}
+#endif
+
+static BOOLEAN jjTYPEOF(leftv res, leftv v)
+{
+  int t=(int)(long)v->data;
+  switch (t)
+  {
+    case CRING_CMD:
+    case INT_CMD:
+    case POLY_CMD:
+    case VECTOR_CMD:
+    case STRING_CMD:
+    case INTVEC_CMD:
+    case IDEAL_CMD:
+    case MATRIX_CMD:
+    case MODUL_CMD:
+    case MAP_CMD:
+    case PROC_CMD:
+    case RING_CMD:
+    case QRING_CMD:
+    case INTMAT_CMD:
+    case BIGINTMAT_CMD:
+    case NUMBER_CMD:
+    #ifdef SINGULAR_4_1
+    case CNUMBER_CMD:
+    #endif
+    case BIGINT_CMD:
+    case LIST_CMD:
+    case PACKAGE_CMD:
+    case LINK_CMD:
+    case RESOLUTION_CMD:
+         res->data=omStrDup(Tok2Cmdname(t)); break;
+    case DEF_CMD:
+    case NONE:           res->data=omStrDup("none"); break;
+    default:
+    {
+      if (t>MAX_TOK)
+        res->data=omStrDup(getBlackboxName(t));
+      else
+        res->data=omStrDup("?unknown type?");
+      break;
+    }
+  }
+  return FALSE;
+}
+static BOOLEAN jjUNIVARIATE(leftv res, leftv v)
+{
+  res->data=(char *)(long)pIsUnivariate((poly)v->Data());
+  return FALSE;
+}
+static BOOLEAN jjVAR1(leftv res, leftv v)
+{
+  int i=(int)(long)v->Data();
+  if ((0<i) && (i<=currRing->N))
+  {
+    poly p=pOne();
+    pSetExp(p,i,1);
+    pSetm(p);
+    res->data=(char *)p;
+  }
+  else
+  {
+    Werror("var number %d out of range 1..%d",i,currRing->N);
+    return TRUE;
+  }
+  return FALSE;
+}
+static BOOLEAN jjVARSTR1(leftv res, leftv v)
+{
+  if (currRing==NULL)
+  {
+    WerrorS("no ring active");
+    return TRUE;
+  }
+  int i=(int)(long)v->Data();
+  if ((0<i) && (i<=currRing->N))
+    res->data=omStrDup(currRing->names[i-1]);
+  else
+  {
+    Werror("var number %d out of range 1..%d",i,currRing->N);
+    return TRUE;
+  }
+  return FALSE;
+}
+static BOOLEAN jjVDIM(leftv res, leftv v)
+{
+  assumeStdFlag(v);
+  res->data = (char *)(long)scMult0Int((ideal)v->Data(),currRing->qideal);
+  return FALSE;
+}
+BOOLEAN jjWAIT1ST1(leftv res, leftv u)
+{
+// input: u: a list with links of type
+//           ssi-fork, ssi-tcp, MPtcp-fork or MPtcp-launch
+// returns: -1:  the read state of all links is eof
+//          i>0: (at least) u[i] is ready
+  lists Lforks = (lists)u->Data();
+  int i = slStatusSsiL(Lforks, -1);
+  if(i == -2) /* error */
+  {
+    return TRUE;
+  }
+  res->data = (void*)(long)i;
+  return FALSE;
+}
+BOOLEAN jjWAITALL1(leftv res, leftv u)
+{
+// input: u: a list with links of type
+//           ssi-fork, ssi-tcp, MPtcp-fork or MPtcp-launch
+// returns: -1: the read state of all links is eof
+//           1: all links are ready
+//              (caution: at least one is ready, but some maybe dead)
+  lists Lforks = (lists)u->CopyD();
+  int i;
+  int j = -1;
+  for(int nfinished = 0; nfinished < Lforks->nr+1; nfinished++)
+  {
+    i = slStatusSsiL(Lforks, -1);
+    if(i == -2) /* error */
+    {
+      return TRUE;
+    }
+    if(i == -1)
+    {
+      break;
+    }
+    j = 1;
+    Lforks->m[i-1].CleanUp();
+    Lforks->m[i-1].rtyp=DEF_CMD;
+    Lforks->m[i-1].data=NULL;
+  }
+  res->data = (void*)(long)j;
+  Lforks->Clean();
+  return FALSE;
+}
+
+BOOLEAN jjLOAD(const char *s, BOOLEAN autoexport)
+{
+  char libnamebuf[256];
+  lib_types LT = type_of_LIB(s, libnamebuf);
+
+#ifdef HAVE_DYNAMIC_LOADING
+  extern BOOLEAN load_modules(const char *newlib, char *fullpath, BOOLEAN autoexport);
+#endif /* HAVE_DYNAMIC_LOADING */
+  switch(LT)
+  {
+      default:
+      case LT_NONE:
+        Werror("%s: unknown type", s);
+        break;
+      case LT_NOTFOUND:
+        Werror("cannot open %s", s);
+        break;
+
+      case LT_SINGULAR:
+      {
+        char *plib = iiConvName(s);
+        idhdl pl = IDROOT->get(plib,0);
+        if (pl==NULL)
+        {
+          pl = enterid( plib,0, PACKAGE_CMD, &(basePack->idroot), TRUE );
+          IDPACKAGE(pl)->language = LANG_SINGULAR;
+          IDPACKAGE(pl)->libname=omStrDup(plib);
+        }
+        else if (IDTYP(pl)!=PACKAGE_CMD)
+        {
+          Werror("can not create package `%s`",plib);
+          omFree(plib);
+          return TRUE;
+        }
+        package savepack=currPack;
+        currPack=IDPACKAGE(pl);
+        IDPACKAGE(pl)->loaded=TRUE;
+        char libnamebuf[256];
+        FILE * fp = feFopen( s, "r", libnamebuf, TRUE );
+        BOOLEAN bo=iiLoadLIB(fp, libnamebuf, s, pl, autoexport, TRUE);
+        currPack=savepack;
+        IDPACKAGE(pl)->loaded=(!bo);
+        return bo;
+      }
+      case LT_BUILTIN:
+        SModulFunc_t iiGetBuiltinModInit(const char*);
+        return load_builtin(s,autoexport, iiGetBuiltinModInit(s));
+      case LT_MACH_O:
+      case LT_ELF:
+      case LT_HPUX:
+#ifdef HAVE_DYNAMIC_LOADING
+        return load_modules(s, libnamebuf, autoexport);
+#else /* HAVE_DYNAMIC_LOADING */
+        WerrorS("Dynamic modules are not supported by this version of Singular");
+        break;
+#endif /* HAVE_DYNAMIC_LOADING */
+  }
+  return TRUE;
+}
+
+static BOOLEAN jjstrlen(leftv res, leftv v)
+{
+  res->data = (char *)strlen((char *)v->Data());
+  return FALSE;
+}
+static BOOLEAN jjpLength(leftv res, leftv v)
+{
+  res->data = (char *)(long)pLength((poly)v->Data());
+  return FALSE;
+}
+static BOOLEAN jjidElem(leftv res, leftv v)
+{
+  res->data = (char *)(long)idElem((ideal)v->Data());
+  return FALSE;
+}
+static BOOLEAN jjidFreeModule(leftv res, leftv v)
+{
+  res->data = (char *)id_FreeModule((int)(long)v->Data(), currRing);
+  return FALSE;
+}
+static BOOLEAN jjidVec2Ideal(leftv res, leftv v)
+{
+  res->data = (char *)id_Vec2Ideal((poly)v->Data(), currRing);
+  return FALSE;
+}
+static BOOLEAN jjrCharStr(leftv res, leftv v)
+{
+#ifdef SINGULAR_4_1
+  iiReWrite("charstr");
+#endif
+  res->data = rCharStr((ring)v->Data());
+  return FALSE;
+}
+static BOOLEAN jjpHead(leftv res, leftv v)
+{
+  res->data = (char *)pHead((poly)v->Data());
+  return FALSE;
+}
+static BOOLEAN jjidHead(leftv res, leftv v)
+{
+  res->data = (char *)id_Head((ideal)v->Data(),currRing);
+  setFlag(res,FLAG_STD);
+  return FALSE;
+}
+static BOOLEAN jjidMinBase(leftv res, leftv v)
+{
+  res->data = (char *)idMinBase((ideal)v->Data());
+  return FALSE;
+}
+static BOOLEAN jjsyMinBase(leftv res, leftv v)
+{
+  res->data = (char *)syMinBase((ideal)v->Data());
+  return FALSE;
+}
+static BOOLEAN jjpMaxComp(leftv res, leftv v)
+{
+  res->data = (char *)pMaxComp((poly)v->Data());
+  return FALSE;
+}
+static BOOLEAN jjmpTrace(leftv res, leftv v)
+{
+  res->data = (char *)mp_Trace((matrix)v->Data(),currRing);
+  return FALSE;
+}
+static BOOLEAN jjmpTransp(leftv res, leftv v)
+{
+  res->data = (char *)mp_Transp((matrix)v->Data(),currRing);
+  return FALSE;
+}
+static BOOLEAN jjrOrdStr(leftv res, leftv v)
+{
+#ifdef SINGULAR_4_1
+  iiReWrite("ordstr");
+#endif
+  res->data = rOrdStr((ring)v->Data());
+  return FALSE;
+}
+static BOOLEAN jjrVarStr(leftv res, leftv v)
+{
+#ifdef SINGULAR_4_1
+  iiReWrite("varstr");
+#endif
+  res->data = rVarStr((ring)v->Data());
+  return FALSE;
+}
+static BOOLEAN jjrParStr(leftv res, leftv v)
+{
+#ifdef SINGULAR_4_1
+  iiReWrite("varstr");
+#endif
+  res->data = rParStr((ring)v->Data());
+  return FALSE;
+}
+static BOOLEAN jjCOUNT_RES(leftv res, leftv v)
+{
+  res->data=(char *)(long)sySize((syStrategy)v->Data());
+  return FALSE;
+}
+static BOOLEAN jjDIM_R(leftv res, leftv v)
+{
+  res->data = (char *)(long)syDim((syStrategy)v->Data());
+  return FALSE;
+}
+static BOOLEAN jjidTransp(leftv res, leftv v)
+{
+  res->data = (char *)idTransp((ideal)v->Data());
+  return FALSE;
+}
+static BOOLEAN jjnInt(leftv res, leftv u)
+{
+  number n=(number)u->CopyD(); // n_Int may call n_Normalize
+  res->data=(char *)(long)n_Int(n,currRing->cf);
+  n_Delete(&n,currRing->cf);
+  return FALSE;
+}
+static BOOLEAN jjnlInt(leftv res, leftv u)
+{
+  number n=(number)u->Data();
+  res->data=(char *)(long)n_Int(n,coeffs_BIGINT );
+  return FALSE;
+}
+/*=================== operations with 3 args.: static proc =================*/
+/* must be ordered: first operations for chars (infix ops),
+ * then alphabetically */
+static BOOLEAN jjBRACK_S(leftv res, leftv u, leftv v,leftv w)
+{
+  char *s= (char *)u->Data();
+  int   r = (int)(long)v->Data();
+  int   c = (int)(long)w->Data();
+  int l = strlen(s);
+
+  if ( (r<1) || (r>l) || (c<0) )
+  {
+    Werror("wrong range[%d,%d] in string %s",r,c,u->Fullname());
+    return TRUE;
+  }
+  res->data = (char *)omAlloc((long)(c+1));
+  sprintf((char *)res->data,"%-*.*s",c,c,s+r-1);
+  return FALSE;
+}
+static BOOLEAN jjBRACK_Im(leftv res, leftv u, leftv v,leftv w)
+{
+  intvec *iv = (intvec *)u->Data();
+  int   r = (int)(long)v->Data();
+  int   c = (int)(long)w->Data();
+  if ((r<1)||(r>iv->rows())||(c<1)||(c>iv->cols()))
+  {
+    Werror("wrong range[%d,%d] in intmat %s(%d x %d)",
+           r,c,u->Fullname(),iv->rows(),iv->cols());
+    return TRUE;
+  }
+  res->data=u->data; u->data=NULL;
+  res->rtyp=u->rtyp; u->rtyp=0;
+  res->name=u->name; u->name=NULL;
+  Subexpr e=jjMakeSub(v);
+          e->next=jjMakeSub(w);
+  if (u->e==NULL) res->e=e;
+  else
+  {
+    Subexpr h=u->e;
+    while (h->next!=NULL) h=h->next;
+    h->next=e;
+    res->e=u->e;
+    u->e=NULL;
+  }
+  return FALSE;
+}
+static BOOLEAN jjBRACK_Bim(leftv res, leftv u, leftv v, leftv w)
+{
+  bigintmat *bim = (bigintmat *)u->Data();
+  int   r = (int)(long)v->Data();
+  int   c = (int)(long)w->Data();
+  if ((r<1)||(r>bim->rows())||(c<1)||(c>bim->cols()))
+  {
+    Werror("wrong range[%d,%d] in bigintmat %s(%d x %d)",
+           r,c,u->Fullname(),bim->rows(),bim->cols());
+    return TRUE;
+  }
+  res->data=u->data; u->data=NULL;
+  res->rtyp=u->rtyp; u->rtyp=0;
+  res->name=u->name; u->name=NULL;
+  Subexpr e=jjMakeSub(v);
+          e->next=jjMakeSub(w);
+  if (u->e==NULL)
+    res->e=e;
+  else
+  {
+    Subexpr h=u->e;
+    while (h->next!=NULL) h=h->next;
+    h->next=e;
+    res->e=u->e;
+    u->e=NULL;
+  }
+  return FALSE;
+}
+static BOOLEAN jjBRACK_Ma(leftv res, leftv u, leftv v,leftv w)
+{
+  matrix m= (matrix)u->Data();
+  int   r = (int)(long)v->Data();
+  int   c = (int)(long)w->Data();
+  //Print("gen. elem %d, %d\n",r,c);
+  if ((r<1)||(r>MATROWS(m))||(c<1)||(c>MATCOLS(m)))
+  {
+    Werror("wrong range[%d,%d] in matrix %s(%d x %d)",r,c,u->Fullname(),
+      MATROWS(m),MATCOLS(m));
+    return TRUE;
+  }
+  res->data=u->data; u->data=NULL;
+  res->rtyp=u->rtyp; u->rtyp=0;
+  res->name=u->name; u->name=NULL;
+  Subexpr e=jjMakeSub(v);
+          e->next=jjMakeSub(w);
+  if (u->e==NULL)
+    res->e=e;
+  else
+  {
+    Subexpr h=u->e;
+    while (h->next!=NULL) h=h->next;
+    h->next=e;
+    res->e=u->e;
+    u->e=NULL;
+  }
+  return FALSE;
+}
+static BOOLEAN jjBRACK_Ma_I_IV(leftv res, leftv u, leftv v,leftv w)
+{
+  sleftv t;
+  sleftv ut;
+  leftv p=NULL;
+  intvec *iv=(intvec *)w->Data();
+  int l;
+  BOOLEAN nok;
+
+  if ((u->rtyp!=IDHDL)||(u->e!=NULL))
+  {
+    WerrorS("cannot build expression lists from unnamed objects");
+    return TRUE;
+  }
+  memcpy(&ut,u,sizeof(ut));
+  memset(&t,0,sizeof(t));
+  t.rtyp=INT_CMD;
+  for (l=0;l< iv->length(); l++)
+  {
+    t.data=(char *)(long)((*iv)[l]);
+    if (p==NULL)
+    {
+      p=res;
+    }
+    else
+    {
+      p->next=(leftv)omAlloc0Bin(sleftv_bin);
+      p=p->next;
+    }
+    memcpy(u,&ut,sizeof(ut));
+    if (u->Typ() == MATRIX_CMD)
+      nok=jjBRACK_Ma(p,u,v,&t);
+    else if (u->Typ() == BIGINTMAT_CMD)
+      nok=jjBRACK_Bim(p,u,v,&t);
+    else /* INTMAT_CMD */
+      nok=jjBRACK_Im(p,u,v,&t);
+    if (nok)
+    {
+      while (res->next!=NULL)
+      {
+        p=res->next->next;
+        omFreeBin((ADDRESS)res->next, sleftv_bin);
+        // res->e aufraeumen !!!!
+        res->next=p;
+      }
+      return TRUE;
+    }
+  }
+  return FALSE;
+}
+static BOOLEAN jjBRACK_Ma_IV_I(leftv res, leftv u, leftv v,leftv w)
+{
+  sleftv t;
+  sleftv ut;
+  leftv p=NULL;
+  intvec *iv=(intvec *)v->Data();
+  int l;
+  BOOLEAN nok;
+
+  if ((u->rtyp!=IDHDL)||(u->e!=NULL))
+  {
+    WerrorS("cannot build expression lists from unnamed objects");
+    return TRUE;
+  }
+  memcpy(&ut,u,sizeof(ut));
+  memset(&t,0,sizeof(t));
+  t.rtyp=INT_CMD;
+  for (l=0;l< iv->length(); l++)
+  {
+    t.data=(char *)(long)((*iv)[l]);
+    if (p==NULL)
+    {
+      p=res;
+    }
+    else
+    {
+      p->next=(leftv)omAlloc0Bin(sleftv_bin);
+      p=p->next;
+    }
+    memcpy(u,&ut,sizeof(ut));
+    if (u->Typ() == MATRIX_CMD)
+      nok=jjBRACK_Ma(p,u,&t,w);
+    else if (u->Typ() == BIGINTMAT_CMD)
+      nok=jjBRACK_Bim(p,u,&t,w);
+    else /* INTMAT_CMD */
+      nok=jjBRACK_Im(p,u,&t,w);
+    if (nok)
+    {
+      while (res->next!=NULL)
+      {
+        p=res->next->next;
+        omFreeBin((ADDRESS)res->next, sleftv_bin);
+        // res->e aufraeumen !!
+        res->next=p;
+      }
+      return TRUE;
+    }
+  }
+  return FALSE;
+}
+static BOOLEAN jjBRACK_Ma_IV_IV(leftv res, leftv u, leftv v,leftv w)
+{
+  sleftv t1,t2,ut;
+  leftv p=NULL;
+  intvec *vv=(intvec *)v->Data();
+  intvec *wv=(intvec *)w->Data();
+  int vl;
+  int wl;
+  BOOLEAN nok;
+
+  if ((u->rtyp!=IDHDL)||(u->e!=NULL))
+  {
+    WerrorS("cannot build expression lists from unnamed objects");
+    return TRUE;
+  }
+  memcpy(&ut,u,sizeof(ut));
+  memset(&t1,0,sizeof(sleftv));
+  memset(&t2,0,sizeof(sleftv));
+  t1.rtyp=INT_CMD;
+  t2.rtyp=INT_CMD;
+  for (vl=0;vl< vv->length(); vl++)
+  {
+    t1.data=(char *)(long)((*vv)[vl]);
+    for (wl=0;wl< wv->length(); wl++)
+    {
+      t2.data=(char *)(long)((*wv)[wl]);
+      if (p==NULL)
+      {
+        p=res;
+      }
+      else
+      {
+        p->next=(leftv)omAlloc0Bin(sleftv_bin);
+        p=p->next;
+      }
+      memcpy(u,&ut,sizeof(ut));
+      if (u->Typ() == MATRIX_CMD)
+        nok=jjBRACK_Ma(p,u,&t1,&t2);
+      else if (u->Typ() == BIGINTMAT_CMD)
+        nok=jjBRACK_Bim(p,u,&t1,&t2);
+      else /* INTMAT_CMD */
+        nok=jjBRACK_Im(p,u,&t1,&t2);
+      if (nok)
+      {
+        res->CleanUp();
+        return TRUE;
+      }
+    }
+  }
+  return FALSE;
+}
+static BOOLEAN jjPROC3(leftv res, leftv u, leftv v, leftv w)
+{
+  v->next=(leftv)omAllocBin(sleftv_bin);
+  memcpy(v->next,w,sizeof(sleftv));
+  memset(w,0,sizeof(sleftv));
+  return jjPROC(res,u,v);
+}
+static BOOLEAN jjBAREISS3(leftv res, leftv u, leftv v, leftv w)
+{
+  intvec *iv;
+  ideal m;
+  lists l=(lists)omAllocBin(slists_bin);
+  int k=(int)(long)w->Data();
+  if (k>=0)
+  {
+    sm_CallBareiss((ideal)u->Data(),(int)(long)v->Data(),(int)(long)w->Data(),m,&iv, currRing);
+    l->Init(2);
+    l->m[0].rtyp=MODUL_CMD;
+    l->m[1].rtyp=INTVEC_CMD;
+    l->m[0].data=(void *)m;
+    l->m[1].data=(void *)iv;
+  }
+  else
+  {
+    m=sm_CallSolv((ideal)u->Data(), currRing);
+    l->Init(1);
+    l->m[0].rtyp=IDEAL_CMD;
+    l->m[0].data=(void *)m;
+  }
+  res->data = (char *)l;
+  return FALSE;
+}
+static BOOLEAN jjCOEFFS3_Id(leftv res, leftv u, leftv v, leftv w)
+{
+  if ((w->rtyp!=IDHDL)||(w->e!=NULL))
+  {
+    WerrorS("3rd argument must be a name of a matrix");
+    return TRUE;
+  }
+  ideal i=(ideal)u->Data();
+  int rank=(int)i->rank;
+  BOOLEAN r=jjCOEFFS_Id(res,u,v);
+  if (r) return TRUE;
+  mp_Monomials((matrix)res->data, rank, pVar((poly)v->Data()),(matrix)w->Data(),currRing);
+  return FALSE;
+}
+static BOOLEAN jjCOEFFS3_KB(leftv res, leftv u, leftv v, leftv w)
+{
+  res->data=(void*)idCoeffOfKBase((ideal)(u->Data()),
+           (ideal)(v->Data()),(poly)(w->Data()));
+  return FALSE;
+}
+static BOOLEAN jjCOEFFS3_P(leftv res, leftv u, leftv v, leftv w)
+{
+  if ((w->rtyp!=IDHDL)||(w->e!=NULL))
+  {
+    WerrorS("3rd argument must be a name of a matrix");
+    return TRUE;
+  }
+  // CopyD for POLY_CMD and VECTOR_CMD are identical:
+  poly p=(poly)u->CopyD(POLY_CMD);
+  ideal i=idInit(1,1);
+  i->m[0]=p;
+  sleftv t;
+  memset(&t,0,sizeof(t));
+  t.data=(char *)i;
+  t.rtyp=IDEAL_CMD;
+  int rank=1;
+  if (u->Typ()==VECTOR_CMD)
+  {
+    i->rank=rank=pMaxComp(p);
+    t.rtyp=MODUL_CMD;
+  }
+  BOOLEAN r=jjCOEFFS_Id(res,&t,v);
+  t.CleanUp();
+  if (r) return TRUE;
+  mp_Monomials((matrix)res->data, rank, pVar((poly)v->Data()),(matrix)w->Data(),currRing);
+  return FALSE;
+}
+static BOOLEAN jjELIMIN_HILB(leftv res, leftv u, leftv v, leftv w)
+{
+  res->data=(char *)idElimination((ideal)u->Data(),(poly)v->Data(),
+    (intvec *)w->Data());
+  //setFlag(res,FLAG_STD);
+  return FALSE;
+}
+static BOOLEAN jjFIND3(leftv res, leftv u, leftv v, leftv w)
+{
+  /*4
+  * look for the substring what in the string where
+  * starting at position n
+  * return the position of the first char of what in where
+  * or 0
+  */
+  int n=(int)(long)w->Data();
+  char *where=(char *)u->Data();
+  char *what=(char *)v->Data();
+  char *found;
+  if ((1>n)||(n>(int)strlen(where)))
+  {
+    Werror("start position %d out of range",n);
+    return TRUE;
+  }
+  found = strchr(where+n-1,*what);
+  if (*(what+1)!='\0')
+  {
+    while((found !=NULL) && (strncmp(found+1,what+1,strlen(what+1))!=0))
+    {
+      found=strchr(found+1,*what);
+    }
+  }
+  if (found != NULL)
+  {
+    res->data=(char *)((found-where)+1);
+  }
+  return FALSE;
+}
+static BOOLEAN jjFWALK3(leftv res, leftv u, leftv v, leftv w)
+{
+  if ((int)(long)w->Data()==0)
+    res->data=(char *)walkProc(u,v);
+  else
+    res->data=(char *)fractalWalkProc(u,v);
+  setFlag( res, FLAG_STD );
+  return FALSE;
+}
+static BOOLEAN jjHILBERT3(leftv res, leftv u, leftv v, leftv w)
+{
+  intvec *wdegree=(intvec*)w->Data();
+  if (wdegree->length()!=currRing->N)
+  {
+    Werror("weight vector must have size %d, not %d",
+           currRing->N,wdegree->length());
+    return TRUE;
+  }
+#ifdef HAVE_RINGS
+  if (rField_is_Ring_Z(currRing))
+  {
+    ring origR = currRing;
+    ring tempR = rCopy(origR);
+    coeffs new_cf=nInitChar(n_Q,NULL);
+    nKillChar(tempR->cf);
+    tempR->cf=new_cf;
+    rComplete(tempR);
+    ideal uid = (ideal)u->Data();
+    rChangeCurrRing(tempR);
+    ideal uu = idrCopyR(uid, origR, currRing);
+    sleftv uuAsLeftv; memset(&uuAsLeftv, 0, sizeof(uuAsLeftv));
+    uuAsLeftv.rtyp = IDEAL_CMD;
+    uuAsLeftv.data = uu; uuAsLeftv.next = NULL;
+    if (hasFlag(u, FLAG_STD)) setFlag(&uuAsLeftv,FLAG_STD);
+    assumeStdFlag(&uuAsLeftv);
+    Print("// NOTE: computation of Hilbert series etc. is being\n");
+    Print("//       performed for generic fibre, that is, over Q\n");
+    intvec *module_w=(intvec*)atGet(&uuAsLeftv,"isHomog",INTVEC_CMD);
+    intvec *iv=hFirstSeries(uu,module_w,currRing->qideal,wdegree);
+    int returnWithTrue = 1;
+    switch((int)(long)v->Data())
+    {
+      case 1:
+        res->data=(void *)iv;
+        returnWithTrue = 0;
+      case 2:
+        res->data=(void *)hSecondSeries(iv);
+        delete iv;
+        returnWithTrue = 0;
+    }
+    if (returnWithTrue)
+    {
+      WerrorS(feNotImplemented);
+      delete iv;
+    }
+    idDelete(&uu);
+    rChangeCurrRing(origR);
+    rDelete(tempR);
+    if (returnWithTrue) return TRUE; else return FALSE;
+  }
+#endif
+  assumeStdFlag(u);
+  intvec *module_w=(intvec *)atGet(u,"isHomog",INTVEC_CMD);
+  intvec *iv=hFirstSeries((ideal)u->Data(),module_w,currRing->qideal,wdegree);
+  switch((int)(long)v->Data())
+  {
+    case 1:
+      res->data=(void *)iv;
+      return FALSE;
+    case 2:
+      res->data=(void *)hSecondSeries(iv);
+      delete iv;
+      return FALSE;
+  }
+  WerrorS(feNotImplemented);
+  delete iv;
+  return TRUE;
+}
+static BOOLEAN jjHOMOG_ID_W(leftv res, leftv u, leftv v, leftv /*w*/)
+{
+  PrintS("TODO\n");
+  int i=pVar((poly)v->Data());
+  if (i==0)
+  {
+    WerrorS("ringvar expected");
+    return TRUE;
+  }
+  poly p=pOne(); pSetExp(p,i,1); pSetm(p);
+  int d=pWTotaldegree(p);
+  pLmDelete(p);
+  if (d==1)
+    res->data = (char *)id_Homogen((ideal)u->Data(), i, currRing);
+  else
+    WerrorS("variable must have weight 1");
+  return (d!=1);
+}
+static BOOLEAN jjHOMOG_P_W(leftv res, leftv u, leftv v,leftv /*w*/)
+{
+  PrintS("TODO\n");
+  int i=pVar((poly)v->Data());
+  if (i==0)
+  {
+    WerrorS("ringvar expected");
+    return TRUE;
+  }
+  poly p=pOne(); pSetExp(p,i,1); pSetm(p);
+  int d=pWTotaldegree(p);
+  pLmDelete(p);
+  if (d==1)
+    res->data = (char *)p_Homogen((poly)u->Data(), i, currRing);
+  else
+    WerrorS("variable must have weight 1");
+  return (d!=1);
+}
+static BOOLEAN jjINTMAT3(leftv res, leftv u, leftv v,leftv w)
+{
+  intvec* im= new intvec((int)(long)v->Data(),(int)(long)w->Data(), 0);
+  intvec* arg = (intvec*) u->Data();
+  int i, n = si_min(im->cols()*im->rows(), arg->cols()*arg->rows());
+
+  for (i=0; i<n; i++)
+  {
+    (*im)[i] = (*arg)[i];
+  }
+
+  res->data = (char *)im;
+  return FALSE;
+}
+static BOOLEAN jjJET_P_IV(leftv res, leftv u, leftv v, leftv w)
+{
+  short *iw=iv2array((intvec *)w->Data(),currRing);
+  res->data = (char *)ppJetW((poly)u->Data(),(int)(long)v->Data(),iw);
+  omFreeSize( (ADDRESS)iw, (rVar(currRing)+1)*sizeof(short) );
+  return FALSE;
+}
+static BOOLEAN jjJET_P_P(leftv res, leftv u, leftv v, leftv w)
+{
+  if (!pIsUnit((poly)v->Data()))
+  {
+    WerrorS("2nd argument must be a unit");
+    return TRUE;
+  }
+  res->data = (char *)p_Series((int)(long)w->Data(),(poly)u->CopyD(),(poly)v->CopyD(),NULL,currRing);
+  return FALSE;
+}
+static BOOLEAN jjJET_ID_IV(leftv res, leftv u, leftv v, leftv w)
+{
+  res->data = (char *)id_JetW((ideal)u->Data(),(int)(long)v->Data(),
+                             (intvec *)w->Data(),currRing);
+  return FALSE;
+}
+static BOOLEAN jjJET_ID_M(leftv res, leftv u, leftv v, leftv w)
+{
+  if (!mp_IsDiagUnit((matrix)v->Data(), currRing))
+  {
+    WerrorS("2nd argument must be a diagonal matrix of units");
+    return TRUE;
+  }
+  res->data = (char *)idSeries((int)(long)w->Data(),(ideal)u->CopyD(),
+                               (matrix)v->CopyD());
+  return FALSE;
+}
+static BOOLEAN currRingIsOverIntegralDomain ()
+{
+  /* true for fields and Z, false otherwise */
+  if (rField_is_Ring_PtoM(currRing)) return FALSE;
+  if (rField_is_Ring_2toM(currRing)) return FALSE;
+  if (rField_is_Ring_ModN(currRing)) return FALSE;
+  return TRUE;
+}
+static BOOLEAN jjMINOR_M(leftv res, leftv v)
+{
+  /* Here's the use pattern for the minor command:
+        minor ( matrix_expression m, int_expression minorSize,
+                optional ideal_expression IasSB, optional int_expression k,
+                optional string_expression algorithm,
+                optional int_expression cachedMinors,
+                optional int_expression cachedMonomials )
+     This method here assumes that there are at least two arguments.
+     - If IasSB is present, it must be a std basis. All minors will be
+       reduced w.r.t. IasSB.
+     - If k is absent, all non-zero minors will be computed.
+       If k is present and k > 0, the first k non-zero minors will be
+       computed.
+       If k is present and k < 0, the first |k| minors (some of which
+       may be zero) will be computed.
+       If k is present and k = 0, an error is reported.
+     - If algorithm is absent, all the following arguments must be absent too.
+       In this case, a heuristic picks the best-suited algorithm (among
+       Bareiss, Laplace, and Laplace with caching).
+       If algorithm is present, it must be one of "Bareiss", "bareiss",
+       "Laplace", "laplace", "Cache", "cache". In the cases "Cache" and
+       "cache" two more arguments may be given, determining how many entries
+       the cache may have at most, and how many cached monomials there are at
+       most. (Cached monomials are counted over all cached polynomials.)
+       If these two additional arguments are not provided, 200 and 100000
+       will be used as defaults.
+  */
+  matrix m;
+  leftv u=v->next;
+  v->next=NULL;
+  int v_typ=v->Typ();
+  if (v_typ==MATRIX_CMD)
+  {
+     m = (const matrix)v->Data();
+  }
+  else
+  {
+    if (v_typ==0)
+    {
+      Werror("`%s` is undefined",v->Fullname());
+      return TRUE;
+    }
+    // try to convert to MATRIX:
+    int ii=iiTestConvert(v_typ,MATRIX_CMD);
+    BOOLEAN bo;
+    sleftv tmp;
+    if (ii>0) bo=iiConvert(v_typ,MATRIX_CMD,ii,v,&tmp);
+    else bo=TRUE;
+    if (bo)
+    {
+      Werror("cannot convert %s to matrix",Tok2Cmdname(v_typ));
+      return TRUE;
+    }
+    m=(matrix)tmp.data;
+  }
+  const int mk = (const int)(long)u->Data();
+  bool noIdeal = true; bool noK = true; bool noAlgorithm = true;
+  bool noCacheMinors = true; bool noCacheMonomials = true;
+  ideal IasSB; int k; char* algorithm; int cacheMinors; int cacheMonomials;
+
+  /* here come the different cases of correct argument sets */
+  if ((u->next != NULL) && (u->next->Typ() == IDEAL_CMD))
+  {
+    IasSB = (ideal)u->next->Data();
+    noIdeal = false;
+    if ((u->next->next != NULL) && (u->next->next->Typ() == INT_CMD))
+    {
+      k = (int)(long)u->next->next->Data();
+      noK = false;
+      assume(k != 0);
+      if ((u->next->next->next != NULL) &&
+          (u->next->next->next->Typ() == STRING_CMD))
+      {
+        algorithm = (char*)u->next->next->next->Data();
+        noAlgorithm = false;
+        if ((u->next->next->next->next != NULL) &&
+            (u->next->next->next->next->Typ() == INT_CMD))
+        {
+          cacheMinors = (int)(long)u->next->next->next->next->Data();
+          noCacheMinors = false;
+          if ((u->next->next->next->next->next != NULL) &&
+              (u->next->next->next->next->next->Typ() == INT_CMD))
+          {
+            cacheMonomials =
+               (int)(long)u->next->next->next->next->next->Data();
+            noCacheMonomials = false;
+          }
+        }
+      }
+    }
+  }
+  else if ((u->next != NULL) && (u->next->Typ() == INT_CMD))
+  {
+    k = (int)(long)u->next->Data();
+    noK = false;
+    assume(k != 0);
+    if ((u->next->next != NULL) && (u->next->next->Typ() == STRING_CMD))
+    {
+      algorithm = (char*)u->next->next->Data();
+      noAlgorithm = false;
+      if ((u->next->next->next != NULL) &&
+          (u->next->next->next->Typ() == INT_CMD))
+      {
+        cacheMinors = (int)(long)u->next->next->next->Data();
+        noCacheMinors = false;
+        if ((u->next->next->next->next != NULL) &&
+            (u->next->next->next->next->Typ() == INT_CMD))
+        {
+          cacheMonomials = (int)(long)u->next->next->next->next->Data();
+          noCacheMonomials = false;
+        }
+      }
+    }
+  }
+  else if ((u->next != NULL) && (u->next->Typ() == STRING_CMD))
+  {
+    algorithm = (char*)u->next->Data();
+    noAlgorithm = false;
+    if ((u->next->next != NULL) && (u->next->next->Typ() == INT_CMD))
+    {
+      cacheMinors = (int)(long)u->next->next->Data();
+      noCacheMinors = false;
+      if ((u->next->next->next != NULL) &&
+          (u->next->next->next->Typ() == INT_CMD))
+      {
+        cacheMonomials = (int)(long)u->next->next->next->Data();
+        noCacheMonomials = false;
+      }
+    }
+  }
+
+  /* upper case conversion for the algorithm if present */
+  if (!noAlgorithm)
+  {
+    if (strcmp(algorithm, "bareiss") == 0)
+      algorithm = (char*)"Bareiss";
+    if (strcmp(algorithm, "laplace") == 0)
+      algorithm = (char*)"Laplace";
+    if (strcmp(algorithm, "cache") == 0)
+      algorithm = (char*)"Cache";
+  }
+
+  v->next=u;
+  /* here come some tests */
+  if (!noIdeal)
+  {
+    assumeStdFlag(u->next);
+  }
+  if ((!noK) && (k == 0))
+  {
+    WerrorS("Provided number of minors to be computed is zero.");
+    return TRUE;
+  }
+  if ((!noAlgorithm) && (strcmp(algorithm, "Bareiss") != 0)
+      && (strcmp(algorithm, "Laplace") != 0)
+      && (strcmp(algorithm, "Cache") != 0))
+  {
+    WerrorS("Expected as algorithm one of 'B/bareiss', 'L/laplace', or 'C/cache'.");
+    return TRUE;
+  }
+  if ((!noAlgorithm) && (strcmp(algorithm, "Bareiss") == 0)
+      && (!currRingIsOverIntegralDomain()))
+  {
+    Werror("Bareiss algorithm not defined over coefficient rings %s",
+           "with zero divisors.");
+    return TRUE;
+  }
+  if ((mk < 1) || (mk > m->rows()) || (mk > m->cols()))
+  {
+    Werror("invalid size of minors: %d (matrix is (%d x %d))", mk,
+           m->rows(), m->cols());
+    return TRUE;
+  }
+  if ((!noAlgorithm) && (strcmp(algorithm, "Cache") == 0)
+      && (noCacheMinors || noCacheMonomials))
+  {
+    cacheMinors = 200;
+    cacheMonomials = 100000;
+  }
+
+  /* here come the actual procedure calls */
+  if (noAlgorithm)
+    res->data = getMinorIdealHeuristic(m, mk, (noK ? 0 : k),
+                                       (noIdeal ? 0 : IasSB), false);
+  else if (strcmp(algorithm, "Cache") == 0)
+    res->data = getMinorIdealCache(m, mk, (noK ? 0 : k),
+                                   (noIdeal ? 0 : IasSB), 3, cacheMinors,
+                                   cacheMonomials, false);
+  else
+    res->data = getMinorIdeal(m, mk, (noK ? 0 : k), algorithm,
+                              (noIdeal ? 0 : IasSB), false);
+  if (v_typ!=MATRIX_CMD) idDelete((ideal *)&m);
+  res->rtyp = IDEAL_CMD;
+  return FALSE;
+}
+static BOOLEAN jjNEWSTRUCT3(leftv, leftv u, leftv v, leftv w)
+{
+  // u: the name of the new type
+  // v: the parent type
+  // w: the elements
+  newstruct_desc d=newstructChildFromString((const char *)v->Data(),
+                                            (const char *)w->Data());
+  if (d!=NULL) newstruct_setup((const char *)u->Data(),d);
+  return (d==NULL);
+}
+static BOOLEAN jjPREIMAGE(leftv res, leftv u, leftv v, leftv w)
+{
+  // handles preimage(r,phi,i) and kernel(r,phi)
+  idhdl h;
+  ring rr;
+  map mapping;
+  BOOLEAN kernel_cmd= (iiOp==KERNEL_CMD);
+
+  if ((v->name==NULL) || (!kernel_cmd && (w->name==NULL)))
+  {
+    WerrorS("2nd/3rd arguments must have names");
+    return TRUE;
+  }
+  rr=(ring)u->Data();
+  const char *ring_name=u->Name();
+  if ((h=rr->idroot->get(v->name,myynest))!=NULL)
+  {
+    if (h->typ==MAP_CMD)
+    {
+      mapping=IDMAP(h);
+      idhdl preim_ring=IDROOT->get(mapping->preimage,myynest);
+      if ((preim_ring==NULL)
+      || (IDRING(preim_ring)!=currRing))
+      {
+        Werror("preimage ring `%s` is not the basering",mapping->preimage);
+        return TRUE;
+      }
+    }
+    else if (h->typ==IDEAL_CMD)
+    {
+      mapping=IDMAP(h);
+    }
+    else
+    {
+      Werror("`%s` is no map nor ideal",IDID(h));
+      return TRUE;
+    }
+  }
+  else
+  {
+    Werror("`%s` is not defined in `%s`",v->name,ring_name);
+    return TRUE;
+  }
+  ideal image;
+  if (kernel_cmd) image=idInit(1,1);
+  else
+  {
+    if ((h=rr->idroot->get(w->name,myynest))!=NULL)
+    {
+      if (h->typ==IDEAL_CMD)
+      {
+        image=IDIDEAL(h);
+      }
+      else
+      {
+        Werror("`%s` is no ideal",IDID(h));
+        return TRUE;
+      }
+    }
+    else
+    {
+      Werror("`%s` is not defined in `%s`",w->name,ring_name);
+      return TRUE;
+    }
+  }
+  if (((currRing->qideal!=NULL) && (rHasLocalOrMixedOrdering_currRing()))
+  || ((rr->qideal!=NULL) && (rHasLocalOrMixedOrdering(rr))))
+  {
+    WarnS("preimage in local qring may be wrong: use Ring::preimageLoc instead");
+  }
+  res->data=(char *)maGetPreimage(rr,mapping,image,currRing);
+  if (kernel_cmd) idDelete(&image);
+  return (res->data==NULL/* is of type ideal, should not be NULL*/);
+}
+static BOOLEAN jjRANDOM_Im(leftv res, leftv u, leftv v, leftv w)
+{
+  int di, k;
+  int i=(int)(long)u->Data();
+  int r=(int)(long)v->Data();
+  int c=(int)(long)w->Data();
+  if ((r<=0) || (c<=0)) return TRUE;
+  intvec *iv = new intvec(r, c, 0);
+  if (iv->rows()==0)
+  {
+    delete iv;
+    return TRUE;
+  }
+  if (i!=0)
+  {
+    if (i<0) i = -i;
+    di = 2 * i + 1;
+    for (k=0; k<iv->length(); k++)
+    {
+      (*iv)[k] = ((siRand() % di) - i);
+    }
+  }
+  res->data = (char *)iv;
+  return FALSE;
+}
+#ifdef SINGULAR_4_1
+static BOOLEAN jjRANDOM_CF(leftv res, leftv u, leftv v, leftv w)
+// <coeff>, par1, par2 -> number2
+{
+  coeffs cf=(coeffs)u->Data();
+  if ((cf!=NULL) && (cf->cfRandom!=NULL))
+  {
+    number n= n_Random(siRand,(number)v->Data(),(number)w->Data(),cf);
+    number2 nn=(number2)omAlloc(sizeof(*nn));
+    nn->cf=cf;
+    nn->n=n;
+    res->data=nn;
+    return FALSE;
+  }
+  return TRUE;
+}
+#endif
+static BOOLEAN jjSUBST_Test(leftv v,leftv w,
+  int &ringvar, poly &monomexpr)
+{
+  monomexpr=(poly)w->Data();
+  poly p=(poly)v->Data();
+#if 0
+  if (pLength(monomexpr)>1)
+  {
+    Werror("`%s` substitutes a ringvar only by a term",
+      Tok2Cmdname(SUBST_CMD));
+    return TRUE;
+  }
+#endif
+  if ((ringvar=pVar(p))==0)
+  {
+    if ((p!=NULL) && (currRing->cf->extRing!=NULL))
+    {
+      number n = pGetCoeff(p);
+      ringvar= -n_IsParam(n, currRing);
+    }
+    if(ringvar==0)
+    {
+      WerrorS("ringvar/par expected");
+      return TRUE;
+    }
+  }
+  return FALSE;
+}
+static BOOLEAN jjSUBST_P(leftv res, leftv u, leftv v,leftv w)
+{
+  int ringvar;
+  poly monomexpr;
+  BOOLEAN nok=jjSUBST_Test(v,w,ringvar,monomexpr);
+  if (nok) return TRUE;
+  poly p=(poly)u->Data();
+  if (ringvar>0)
+  {
+    if ((monomexpr!=NULL) && (p!=NULL) && (pTotaldegree(p)!=0) &&
+    ((unsigned long)pTotaldegree(monomexpr) > (currRing->bitmask / (unsigned long)pTotaldegree(p)/2)))
+    {
+      Warn("possible OVERFLOW in subst, max exponent is %ld, subtituting deg %d by deg %d",currRing->bitmask/2, pTotaldegree(monomexpr), pTotaldegree(p));
+      //return TRUE;
+    }
+    if ((monomexpr==NULL)||(pNext(monomexpr)==NULL))
+      res->data = pSubst((poly)u->CopyD(res->rtyp),ringvar,monomexpr);
+    else
+      res->data= pSubstPoly(p,ringvar,monomexpr);
+  }
+  else
+  {
+    res->data=pSubstPar(p,-ringvar,monomexpr);
+  }
+  return FALSE;
+}
+static BOOLEAN jjSUBST_Id(leftv res, leftv u, leftv v,leftv w)
+{
+  int ringvar;
+  poly monomexpr;
+  BOOLEAN nok=jjSUBST_Test(v,w,ringvar,monomexpr);
+  if (nok) return TRUE;
+  ideal id=(ideal)u->Data();
+  if (ringvar>0)
+  {
+    BOOLEAN overflow=FALSE;
+    if (monomexpr!=NULL)
+    {
+      long deg_monexp=pTotaldegree(monomexpr);
+      for(int i=IDELEMS(id)-1;i>=0;i--)
+      {
+        poly p=id->m[i];
+        if ((p!=NULL) && (pTotaldegree(p)!=0) &&
+        ((unsigned long)deg_monexp > (currRing->bitmask / (unsigned long)pTotaldegree(p)/2)))
+        {
+          overflow=TRUE;
+          break;
+        }
+      }
+    }
+    if (overflow)
+      Warn("possible OVERFLOW in subst, max exponent is %ld",currRing->bitmask/2);
+    if ((monomexpr==NULL)||(pNext(monomexpr)==NULL))
+    {
+      if (res->rtyp==MATRIX_CMD) id=(ideal)mp_Copy((matrix)id,currRing);
+      else                       id=id_Copy(id,currRing);
+      res->data = id_Subst(id, ringvar, monomexpr, currRing);
+    }
+    else
+      res->data = idSubstPoly(id,ringvar,monomexpr);
+  }
+  else
+  {
+    res->data = idSubstPar(id,-ringvar,monomexpr);
+  }
+  return FALSE;
+}
+// we do not want to have jjSUBST_Id_X inlined:
+static BOOLEAN jjSUBST_Id_X(leftv res, leftv u, leftv v,leftv w,
+                            int input_type);
+static BOOLEAN jjSUBST_Id_I(leftv res, leftv u, leftv v,leftv w)
+{
+  return jjSUBST_Id_X(res,u,v,w,INT_CMD);
+}
+static BOOLEAN jjSUBST_Id_N(leftv res, leftv u, leftv v,leftv w)
+{
+  return jjSUBST_Id_X(res,u,v,w,NUMBER_CMD);
+}
+static BOOLEAN jjSUBST_Id_X(leftv res, leftv u, leftv v,leftv w, int input_type)
+{
+  sleftv tmp;
+  memset(&tmp,0,sizeof(tmp));
+  // do not check the result, conversion from int/number to poly works always
+  iiConvert(input_type,POLY_CMD,iiTestConvert(input_type,POLY_CMD),w,&tmp);
+  BOOLEAN b=jjSUBST_Id(res,u,v,&tmp);
+  tmp.CleanUp();
+  return b;
+}
+static BOOLEAN jjMATRIX_Id(leftv res, leftv u, leftv v,leftv w)
+{
+  int mi=(int)(long)v->Data();
+  int ni=(int)(long)w->Data();
+  if ((mi<1)||(ni<1))
+  {
+    Werror("converting ideal to matrix: dimensions must be positive(%dx%d)",mi,ni);
+    return TRUE;
+  }
+  matrix m=mpNew(mi,ni);
+  ideal I=(ideal)u->CopyD(IDEAL_CMD);
+  int i=si_min(IDELEMS(I),mi*ni);
+  //for(i=i-1;i>=0;i--)
+  //{
+  //  m->m[i]=I->m[i];
+  //  I->m[i]=NULL;
+  //}
+  memcpy(m->m,I->m,i*sizeof(poly));
+  memset(I->m,0,i*sizeof(poly));
+  id_Delete(&I,currRing);
+  res->data = (char *)m;
+  return FALSE;
+}
+static BOOLEAN jjMATRIX_Mo(leftv res, leftv u, leftv v,leftv w)
+{
+  int mi=(int)(long)v->Data();
+  int ni=(int)(long)w->Data();
+  if ((mi<1)||(ni<1))
+  {
+    Werror("converting module to matrix: dimensions must be positive(%dx%d)",mi,ni);
+    return TRUE;
+  }
+  res->data = (char *)id_Module2formatedMatrix((ideal)u->CopyD(MODUL_CMD),
+           mi,ni,currRing);
+  return FALSE;
+}
+static BOOLEAN jjMATRIX_Ma(leftv res, leftv u, leftv v,leftv w)
+{
+  int mi=(int)(long)v->Data();
+  int ni=(int)(long)w->Data();
+  if ((mi<1)||(ni<1))
+  {
+     Werror("converting matrix to matrix: dimensions must be positive(%dx%d)",mi,ni);
+    return TRUE;
+  }
+  matrix m=mpNew(mi,ni);
+  matrix I=(matrix)u->CopyD(MATRIX_CMD);
+  int r=si_min(MATROWS(I),mi);
+  int c=si_min(MATCOLS(I),ni);
+  int i,j;
+  for(i=r;i>0;i--)
+  {
+    for(j=c;j>0;j--)
+    {
+      MATELEM(m,i,j)=MATELEM(I,i,j);
+      MATELEM(I,i,j)=NULL;
+    }
+  }
+  id_Delete((ideal *)&I,currRing);
+  res->data = (char *)m;
+  return FALSE;
+}
+static BOOLEAN jjLIFT3(leftv res, leftv u, leftv v, leftv w)
+{
+  if (w->rtyp!=IDHDL) return TRUE;
+  int ul= IDELEMS((ideal)u->Data());
+  int vl= IDELEMS((ideal)v->Data());
+  ideal m
+    = idLift((ideal)u->Data(),(ideal)v->Data(),NULL,FALSE,hasFlag(u,FLAG_STD),
+             FALSE, (matrix *)(&(IDMATRIX((idhdl)(w->data)))));
+  if (m==NULL) return TRUE;
+  res->data = (char *)id_Module2formatedMatrix(m,ul,vl,currRing);
+  return FALSE;
+}
+static BOOLEAN jjLIFTSTD3(leftv res, leftv u, leftv v, leftv w)
+{
+  if ((v->rtyp!=IDHDL)||(v->e!=NULL)) return TRUE;
+  if ((w->rtyp!=IDHDL)||(w->e!=NULL)) return TRUE;
+  idhdl hv=(idhdl)v->data;
+  idhdl hw=(idhdl)w->data;
+  // CopyD for IDEAL_CMD and MODUL_CMD are identical:
+  res->data = (char *)idLiftStd((ideal)u->Data(),
+                                &(hv->data.umatrix),testHomog,
+                                &(hw->data.uideal));
+  setFlag(res,FLAG_STD); v->flag=0; w->flag=0;
+  return FALSE;
+}
+static BOOLEAN jjREDUCE3_CP(leftv res, leftv u, leftv v, leftv w)
+{
+  assumeStdFlag(v);
+  if (!idIsZeroDim((ideal)v->Data()))
+  {
+    Werror("`%s` must be 0-dimensional",v->Name());
+    return TRUE;
+  }
+  res->data = (char *)redNF((ideal)v->CopyD(),(poly)u->CopyD(),
+    (poly)w->CopyD());
+  return FALSE;
+}
+static BOOLEAN jjREDUCE3_CID(leftv res, leftv u, leftv v, leftv w)
+{
+  assumeStdFlag(v);
+  if (!idIsZeroDim((ideal)v->Data()))
+  {
+    Werror("`%s` must be 0-dimensional",v->Name());
+    return TRUE;
+  }
+  res->data = (char *)redNF((ideal)v->CopyD(),(ideal)u->CopyD(),
+    (matrix)w->CopyD());
+  return FALSE;
+}
+static BOOLEAN jjREDUCE3_P(leftv res, leftv u, leftv v, leftv w)
+{
+  assumeStdFlag(v);
+  res->data = (char *)kNF((ideal)v->Data(),currRing->qideal,(poly)u->Data(),
+    0,(int)(long)w->Data());
+  return FALSE;
+}
+static BOOLEAN jjREDUCE3_ID(leftv res, leftv u, leftv v, leftv w)
+{
+  assumeStdFlag(v);
+  res->data = (char *)kNF((ideal)v->Data(),currRing->qideal,(ideal)u->Data(),
+    0,(int)(long)w->Data());
+  return FALSE;
+}
+#ifdef OLD_RES
+static BOOLEAN jjRES3(leftv res, leftv u, leftv v, leftv w)
+{
+  int maxl=(int)v->Data();
+  ideal u_id=(ideal)u->Data();
+  int l=0;
+  resolvente r;
+  intvec **weights=NULL;
+  int wmaxl=maxl;
+  maxl--;
+  if ((maxl==-1) && (iiOp!=MRES_CMD))
+    maxl = currRing->N-1;
+  if ((iiOp == RES_CMD) || (iiOp == MRES_CMD))
+  {
+    intvec * iv=(intvec*)atGet(u,"isHomog",INTVEC_CMD);
+    if (iv!=NULL)
+    {
+      l=1;
+      if (!idTestHomModule(u_id,currRing->qideal,iv))
+      {
+        WarnS("wrong weights");
+        iv=NULL;
+      }
+      else
+      {
+        weights = (intvec**)omAlloc0Bin(char_ptr_bin);
+        weights[0] = ivCopy(iv);
+      }
+    }
+    r=syResolvente(u_id,maxl,&l, &weights, iiOp==MRES_CMD);
+  }
+  else
+    r=sySchreyerResolvente((ideal)u->Data(),maxl+1,&l);
+  if (r==NULL) return TRUE;
+  int t3=u->Typ();
+  iiMakeResolv(r,l,wmaxl,w->name,t3,weights);
+  return FALSE;
+}
+#endif
+static BOOLEAN jjRING3(leftv res, leftv u, leftv v, leftv w)
+{
+  res->data=(void *)rInit(u,v,w);
+  return (res->data==NULL);
+}
+static BOOLEAN jjSTATUS3(leftv res, leftv u, leftv v, leftv w)
+{
+  int yes;
+  jjSTATUS2(res, u, v);
+  yes = (strcmp((char *) res->data, (char *) w->Data()) == 0);
+  omFree((ADDRESS) res->data);
+  res->data = (void *)(long)yes;
+  return FALSE;
+}
+static BOOLEAN jjSTD_HILB_W(leftv res, leftv u, leftv v, leftv w)
+{
+  intvec *vw=(intvec *)w->Data(); // weights of vars
+  if (vw->length()!=currRing->N)
+  {
+    Werror("%d weights for %d variables",vw->length(),currRing->N);
+    return TRUE;
+  }
+  ideal result;
+  intvec *ww=(intvec *)atGet(u,"isHomog",INTVEC_CMD);
+  tHomog hom=testHomog;
+  ideal u_id=(ideal)(u->Data());
+  if (ww!=NULL)
+  {
+    if (!idTestHomModule(u_id,currRing->qideal,ww))
+    {
+      WarnS("wrong weights");
+      ww=NULL;
+    }
+    else
+    {
+      ww=ivCopy(ww);
+      hom=isHomog;
+    }
+  }
+  result=kStd(u_id,
+              currRing->qideal,
+              hom,
+              &ww,                  // module weights
+              (intvec *)v->Data(),  // hilbert series
+              0,0,                  // syzComp, newIdeal
+              vw);                  // weights of vars
+  idSkipZeroes(result);
+  res->data = (char *)result;
+  setFlag(res,FLAG_STD);
+  if (ww!=NULL) atSet(res,omStrDup("isHomog"),ww,INTVEC_CMD);
+  return FALSE;
+}
+
+/*=================== operations with many arg.: static proc =================*/
+/* must be ordered: first operations for chars (infix ops),
+ * then alphabetically */
+static BOOLEAN jjBREAK0(leftv, leftv)
+{
+#ifdef HAVE_SDB
+  sdb_show_bp();
+#endif
+  return FALSE;
+}
+static BOOLEAN jjBREAK1(leftv, leftv v)
+{
+#ifdef HAVE_SDB
+  if(v->Typ()==PROC_CMD)
+  {
+    int lineno=0;
+    if((v->next!=NULL) && (v->next->Typ()==INT_CMD))
+    {
+      lineno=(int)(long)v->next->Data();
+    }
+    return sdb_set_breakpoint(v->Name(),lineno);
+  }
+  return TRUE;
+#else
+ return FALSE;
+#endif
+}
+static BOOLEAN jjCALL1ARG(leftv res, leftv v)
+{
+  return iiExprArith1(res,v,iiOp);
+}
+static BOOLEAN jjCALL2ARG(leftv res, leftv u)
+{
+  leftv v=u->next;
+  u->next=NULL;
+  BOOLEAN b=iiExprArith2(res,u,iiOp,v, (iiOp > 255));
+  u->next=v;
+  return b;
+}
+static BOOLEAN jjCALL3ARG(leftv res, leftv u)
+{
+  leftv v = u->next;
+  leftv w = v->next;
+  u->next = NULL;
+  v->next = NULL;
+  BOOLEAN b = iiExprArith3(res, iiOp, u, v, w);
+  u->next = v;
+  v->next = w;
+  return b;
+}
+
+static BOOLEAN jjCOEF_M(leftv, leftv v)
+{
+  short t[]={5,VECTOR_CMD,POLY_CMD,MATRIX_CMD,MATRIX_CMD,IDHDL};
+  if (iiCheckTypes(v,t))
+     return TRUE;
+  idhdl c=(idhdl)v->next->next->data;
+  if (v->next->next->next->rtyp!=IDHDL) return TRUE;
+  idhdl m=(idhdl)v->next->next->next->data;
+  idDelete((ideal *)&(c->data.uideal));
+  idDelete((ideal *)&(m->data.uideal));
+  mp_Coef2((poly)v->Data(),(poly)v->next->Data(),
+    (matrix *)&(c->data.umatrix),(matrix *)&(m->data.umatrix),currRing);
+  return FALSE;
+}
+
+static BOOLEAN jjDIVISION4(leftv res, leftv v)
+{ // may have 3 or 4 arguments
+  leftv v1=v;
+  leftv v2=v1->next;
+  leftv v3=v2->next;
+  leftv v4=v3->next;
+  assumeStdFlag(v2);
+
+  int i1=iiTestConvert(v1->Typ(),MODUL_CMD);
+  int i2=iiTestConvert(v2->Typ(),MODUL_CMD);
+
+  if((i1==0)||(i2==0)
+  ||(v3->Typ()!=INT_CMD)||((v4!=NULL)&&(v4->Typ()!=INTVEC_CMD)))
+  {
+    WarnS("<module>,<module>,<int>[,<intvec>] expected!");
+    return TRUE;
+  }
+
+  sleftv w1,w2;
+  iiConvert(v1->Typ(),MODUL_CMD,i1,v1,&w1);
+  iiConvert(v2->Typ(),MODUL_CMD,i2,v2,&w2);
+  ideal P=(ideal)w1.Data();
+  ideal Q=(ideal)w2.Data();
+
+  int n=(int)(long)v3->Data();
+  short *w=NULL;
+  if(v4!=NULL)
+  {
+    w = iv2array((intvec *)v4->Data(),currRing);
+    short * w0 = w + 1;
+    int i = currRing->N;
+    while( (i > 0) && ((*w0) > 0) )
+    {
+      w0++;
+      i--;
+    }
+    if(i>0)
+      WarnS("not all weights are positive!");
+  }
+
+  matrix T;
+  ideal R;
+  idLiftW(P,Q,n,T,R,w);
+
+  w1.CleanUp();
+  w2.CleanUp();
+  if(w!=NULL)
+    omFreeSize( (ADDRESS)w, (rVar(currRing)+1)*sizeof(short) );
+
+  lists L=(lists) omAllocBin(slists_bin);
+  L->Init(2);
+  L->m[1].rtyp=v1->Typ();
+  if(v1->Typ()==POLY_CMD||v1->Typ()==VECTOR_CMD)
+  {
+    if(v1->Typ()==POLY_CMD)
+      p_Shift(&R->m[0],-1,currRing);
+    L->m[1].data=(void *)R->m[0];
+    R->m[0]=NULL;
+    idDelete(&R);
+  }
+  else if(v1->Typ()==IDEAL_CMD||v1->Typ()==MATRIX_CMD)
+    L->m[1].data=(void *)id_Module2Matrix(R,currRing);
+  else
+  {
+    L->m[1].rtyp=MODUL_CMD;
+    L->m[1].data=(void *)R;
+  }
+  L->m[0].rtyp=MATRIX_CMD;
+  L->m[0].data=(char *)T;
+
+  res->data=L;
+  res->rtyp=LIST_CMD;
+
+  return FALSE;
+}
+
+//BOOLEAN jjDISPATCH(leftv res, leftv v)
+//{
+//  WerrorS("`dispatch`: not implemented");
+//  return TRUE;
+//}
+
+//static BOOLEAN jjEXPORTTO_M(leftv res, leftv u)
+//{
+//  int l=u->listLength();
+//  if (l<2) return TRUE;
+//  BOOLEAN b;
+//  leftv v=u->next;
+//  leftv zz=v;
+//  leftv z=zz;
+//  u->next=NULL;
+//  do
+//  {
+//    leftv z=z->next;
+//    b=iiExprArith2(res,u,iiOp,z, (iiOp > 255));
+//    if (b) break;
+//  } while (z!=NULL);
+//  u->next=zz;
+//  return b;
+//}
+static BOOLEAN jjIDEAL_PL(leftv res, leftv v)
+{
+  int s=1;
+  leftv h=v;
+  if (h!=NULL) s=exprlist_length(h);
+  ideal id=idInit(s,1);
+  int rank=1;
+  int i=0;
+  poly p;
+  while (h!=NULL)
+  {
+    switch(h->Typ())
+    {
+      case POLY_CMD:
+      {
+        p=(poly)h->CopyD(POLY_CMD);
+        break;
+      }
+      case INT_CMD:
+      {
+        number n=nInit((int)(long)h->Data());
+        if (!nIsZero(n))
+        {
+          p=pNSet(n);
+        }
+        else
+        {
+          p=NULL;
+          nDelete(&n);
+        }
+        break;
+      }
+      case BIGINT_CMD:
+      {
+        number b=(number)h->Data();
+        nMapFunc nMap=n_SetMap(coeffs_BIGINT,currRing->cf);
+        if (nMap==NULL) return TRUE;
+        number n=nMap(b,coeffs_BIGINT,currRing->cf);
+        if (!nIsZero(n))
+        {
+          p=pNSet(n);
+        }
+        else
+        {
+          p=NULL;
+          nDelete(&n);
+        }
+        break;
+      }
+      case NUMBER_CMD:
+      {
+        number n=(number)h->CopyD(NUMBER_CMD);
+        if (!nIsZero(n))
+        {
+          p=pNSet(n);
+        }
+        else
+        {
+          p=NULL;
+          nDelete(&n);
+        }
+        break;
+      }
+      case VECTOR_CMD:
+      {
+        p=(poly)h->CopyD(VECTOR_CMD);
+        if (iiOp!=MODUL_CMD)
+        {
+          idDelete(&id);
+          pDelete(&p);
+          return TRUE;
+        }
+        rank=si_max(rank,(int)pMaxComp(p));
+        break;
+      }
+      default:
+      {
+        idDelete(&id);
+        return TRUE;
+      }
+    }
+    if ((iiOp==MODUL_CMD)&&(p!=NULL)&&(pGetComp(p)==0))
+    {
+      pSetCompP(p,1);
+    }
+    id->m[i]=p;
+    i++;
+    h=h->next;
+  }
+  id->rank=rank;
+  res->data=(char *)id;
+  return FALSE;
+}
+static BOOLEAN jjFETCH_M(leftv res, leftv u)
+{
+  ring r=(ring)u->Data();
+  leftv v=u->next;
+  leftv perm_var_l=v->next;
+  leftv perm_par_l=v->next->next;
+  if ((perm_var_l->Typ()!=INTVEC_CMD)
+  ||((perm_par_l!=NULL)&&(perm_par_l->Typ()!=INTVEC_CMD))
+  ||((u->Typ()!=RING_CMD)&&(u->Typ()!=QRING_CMD)))
+  {
+    WerrorS("fetch(<ring>,<name>[,<intvec>[,<intvec>])");
+    return TRUE;
+  }
+  intvec *perm_var_v=(intvec*)perm_var_l->Data();
+  intvec *perm_par_v=NULL;
+  if (perm_par_l!=NULL)
+    perm_par_v=(intvec*)perm_par_l->Data();
+  idhdl w;
+  nMapFunc nMap;
+
+  if ((w=r->idroot->get(v->Name(),myynest))!=NULL)
+  {
+    int *perm=NULL;
+    int *par_perm=NULL;
+    int par_perm_size=0;
+    BOOLEAN bo;
+    if ((nMap=n_SetMap(r->cf,currRing->cf))==NULL)
+    {
+      // Allow imap/fetch to be make an exception only for:
+      if ( (rField_is_Q_a(r) &&  // Q(a..) -> Q(a..) || Q || Zp || Zp(a)
+            (rField_is_Q(currRing) || rField_is_Q_a(currRing) ||
+             (rField_is_Zp(currRing) || rField_is_Zp_a(currRing))))
+           ||
+           (rField_is_Zp_a(r) &&  // Zp(a..) -> Zp(a..) || Zp
+            (rField_is_Zp(currRing, r->cf->ch) ||
+             rField_is_Zp_a(currRing, r->cf->ch))) )
+      {
+        par_perm_size=rPar(r);
+      }
+      else
+      {
+        goto err_fetch;
+      }
+    }
+    else
+      par_perm_size=rPar(r);
+    perm=(int *)omAlloc0((rVar(r)+1)*sizeof(int));
+    if (par_perm_size!=0)
+      par_perm=(int *)omAlloc0(par_perm_size*sizeof(int));
+    int i;
+    if (perm_par_l==NULL)
+    {
+      if (par_perm_size!=0)
+        for(i=si_min(rPar(r),rPar(currRing))-1;i>=0;i--) par_perm[i]=-(i+1);
+    }
+    else
+    {
+      if (par_perm_size==0) WarnS("source ring has no parameters");
+      else
+      {
+        for(i=rPar(r)-1;i>=0;i--)
+        {
+          if (i<perm_par_v->length()) par_perm[i]=(*perm_par_v)[i];
+          if ((par_perm[i]<-rPar(currRing))
+          || (par_perm[i]>rVar(currRing)))
+          {
+            Warn("invalid entry for par %d: %d\n",i,par_perm[i]);
+            par_perm[i]=0;
+          }
+        }
+      }
+    }
+    for(i=rVar(r)-1;i>=0;i--)
+    {
+      if (i<perm_var_v->length()) perm[i+1]=(*perm_var_v)[i];
+      if ((perm[i]<-rPar(currRing))
+      || (perm[i]>rVar(currRing)))
+      {
+        Warn("invalid entry for var %d: %d\n",i,perm[i]);
+        perm[i]=0;
+      }
+    }
+    if (BVERBOSE(V_IMAP))
+    {
+      for(i=1;i<=si_min(rVar(r),rVar(currRing));i++)
+      {
+        if (perm[i]>0)
+          Print("// var nr %d: %s -> var %s\n",i,r->names[i-1],currRing->names[perm[i]-1]);
+        else if (perm[i]<0)
+          Print("// var nr %d: %s -> par %s\n",i,r->names[i-1],rParameter(currRing)[-perm[i]-1]);
+      }
+      for(i=1;i<=si_min(rPar(r),rPar(currRing));i++) // possibly empty loop
+      {
+        if (par_perm[i-1]<0)
+          Print("// par nr %d: %s -> par %s\n",
+              i,rParameter(r)[i-1],rParameter(currRing)[-par_perm[i-1]-1]);
+        else if (par_perm[i-1]>0)
+          Print("// par nr %d: %s -> var %s\n",
+              i,rParameter(r)[i-1],currRing->names[par_perm[i-1]-1]);
+      }
+    }
+    if (IDTYP(w)==ALIAS_CMD) w=(idhdl)IDDATA(w);
+    sleftv tmpW;
+    memset(&tmpW,0,sizeof(sleftv));
+    tmpW.rtyp=IDTYP(w);
+    tmpW.data=IDDATA(w);
+    if ((bo=maApplyFetch(IMAP_CMD,NULL,res,&tmpW, r,
+                         perm,par_perm,par_perm_size,nMap)))
+    {
+      Werror("cannot map %s of type %s(%d)",v->name, Tok2Cmdname(w->typ),w->typ);
+    }
+    if (perm!=NULL)
+      omFreeSize((ADDRESS)perm,(rVar(r)+1)*sizeof(int));
+    if (par_perm!=NULL)
+      omFreeSize((ADDRESS)par_perm,par_perm_size*sizeof(int));
+    return bo;
+  }
+  else
+  {
+    Werror("identifier %s not found in %s",v->Fullname(),u->Fullname());
+  }
+  return TRUE;
+err_fetch:
+  Werror("no identity map from %s (%s -> %s)",u->Fullname(),
+         nCoeffString(r->cf),
+         nCoeffString(currRing->cf));
+  return TRUE;
+}
+static BOOLEAN jjINTERSECT_PL(leftv res, leftv v)
+{
+  leftv h=v;
+  int l=v->listLength();
+  resolvente r=(resolvente)omAlloc0(l*sizeof(ideal));
+  BOOLEAN *copied=(BOOLEAN *)omAlloc0(l*sizeof(BOOLEAN));
+  int t=0;
+  // try to convert to IDEAL_CMD
+  while (h!=NULL)
+  {
+    if (iiTestConvert(h->Typ(),IDEAL_CMD)!=0)
+    {
+      t=IDEAL_CMD;
+    }
+    else break;
+    h=h->next;
+  }
+  // if failure, try MODUL_CMD
+  if (t==0)
+  {
+    h=v;
+    while (h!=NULL)
+    {
+      if (iiTestConvert(h->Typ(),MODUL_CMD)!=0)
+      {
+        t=MODUL_CMD;
+      }
+      else break;
+      h=h->next;
+    }
+  }
+  // check for success  in converting
+  if (t==0)
+  {
+    WerrorS("cannot convert to ideal or module");
+    return TRUE;
+  }
+  // call idMultSect
+  h=v;
+  int i=0;
+  sleftv tmp;
+  while (h!=NULL)
+  {
+    if (h->Typ()==t)
+    {
+      r[i]=(ideal)h->Data(); /*no copy*/
+      h=h->next;
+    }
+    else if(iiConvert(h->Typ(),t,iiTestConvert(h->Typ(),t),h,&tmp))
+    {
+      omFreeSize((ADDRESS)copied,l*sizeof(BOOLEAN));
+      omFreeSize((ADDRESS)r,l*sizeof(ideal));
+      Werror("cannot convert arg. %d to %s",i+1,Tok2Cmdname(t));
+      return TRUE;
+    }
+    else
+    {
+      r[i]=(ideal)tmp.Data(); /*now it's a copy*/
+      copied[i]=TRUE;
+      h=tmp.next;
+    }
+    i++;
+  }
+  res->rtyp=t;
+  res->data=(char *)idMultSect(r,i);
+  while(i>0)
+  {
+    i--;
+    if (copied[i]) idDelete(&(r[i]));
+  }
+  omFreeSize((ADDRESS)copied,l*sizeof(BOOLEAN));
+  omFreeSize((ADDRESS)r,l*sizeof(ideal));
+  return FALSE;
+}
+static BOOLEAN jjLU_INVERSE(leftv res, leftv v)
+{
+  /* computation of the inverse of a quadratic matrix A
+     using the L-U-decomposition of A;
+     There are two valid parametrisations:
+     1) exactly one argument which is just the matrix A,
+     2) exactly three arguments P, L, U which already
+        realise the L-U-decomposition of A, that is,
+        P * A = L * U, and P, L, and U satisfy the
+        properties decribed in method 'jjLU_DECOMP';
+        see there;
+     If A is invertible, the list [1, A^(-1)] is returned,
+     otherwise the list [0] is returned. Thus, the user may
+     inspect the first entry of the returned list to see
+     whether A is invertible. */
+  matrix iMat; int invertible;
+  short t1[]={1,MATRIX_CMD};
+  short t2[]={3,MATRIX_CMD,MATRIX_CMD,MATRIX_CMD};
+  if (iiCheckTypes(v,t1))
+  {
+    matrix aMat = (matrix)v->Data();
+    int rr = aMat->rows();
+    int cc = aMat->cols();
+    if (rr != cc)
+    {
+      Werror("given matrix (%d x %d) is not quadratic, hence not invertible", rr, cc);
+      return TRUE;
+    }
+    if (!idIsConstant((ideal)aMat))
+    {
+      WerrorS("matrix must be constant");
+      return TRUE;
+    }
+    invertible = luInverse(aMat, iMat);
+  }
+  else if (iiCheckTypes(v,t2))
+  {
+     matrix pMat = (matrix)v->Data();
+     matrix lMat = (matrix)v->next->Data();
+     matrix uMat = (matrix)v->next->next->Data();
+     int rr = uMat->rows();
+     int cc = uMat->cols();
+     if (rr != cc)
+     {
+       Werror("third matrix (%d x %d) is not quadratic, hence not invertible",
+              rr, cc);
+       return TRUE;
+     }
+      if (!idIsConstant((ideal)pMat)
+      || (!idIsConstant((ideal)lMat))
+      || (!idIsConstant((ideal)uMat))
+      )
+      {
+        WerrorS("matricesx must be constant");
+        return TRUE;
+      }
+     invertible = luInverseFromLUDecomp(pMat, lMat, uMat, iMat);
+  }
+  else
+  {
+    Werror("expected either one or three matrices");
+    return TRUE;
+  }
+
+  /* build the return structure; a list with either one or two entries */
+  lists ll = (lists)omAllocBin(slists_bin);
+  if (invertible)
+  {
+    ll->Init(2);
+    ll->m[0].rtyp=INT_CMD;    ll->m[0].data=(void *)(long)invertible;
+    ll->m[1].rtyp=MATRIX_CMD; ll->m[1].data=(void *)iMat;
+  }
+  else
+  {
+    ll->Init(1);
+    ll->m[0].rtyp=INT_CMD;    ll->m[0].data=(void *)(long)invertible;
+  }
+
+  res->data=(char*)ll;
+  return FALSE;
+}
+static BOOLEAN jjLU_SOLVE(leftv res, leftv v)
+{
+  /* for solving a linear equation system A * x = b, via the
+     given LU-decomposition of the matrix A;
+     There is one valid parametrisation:
+     1) exactly four arguments P, L, U, b;
+        P, L, and U realise the L-U-decomposition of A, that is,
+        P * A = L * U, and P, L, and U satisfy the
+        properties decribed in method 'jjLU_DECOMP';
+        see there;
+        b is the right-hand side vector of the equation system;
+     The method will return a list of either 1 entry or three entries:
+     1) [0] if there is no solution to the system;
+     2) [1, x, H] if there is at least one solution;
+        x is any solution of the given linear system,
+        H is the matrix with column vectors spanning the homogeneous
+        solution space.
+     The method produces an error if matrix and vector sizes do not fit. */
+  short t[]={4,MATRIX_CMD,MATRIX_CMD,MATRIX_CMD,MATRIX_CMD};
+  if (!iiCheckTypes(v,t))
+  {
+    WerrorS("expected exactly three matrices and one vector as input");
+    return TRUE;
+  }
+  matrix pMat = (matrix)v->Data();
+  matrix lMat = (matrix)v->next->Data();
+  matrix uMat = (matrix)v->next->next->Data();
+  matrix bVec = (matrix)v->next->next->next->Data();
+  matrix xVec; int solvable; matrix homogSolSpace;
+  if (pMat->rows() != pMat->cols())
+  {
+    Werror("first matrix (%d x %d) is not quadratic",
+           pMat->rows(), pMat->cols());
+    return TRUE;
+  }
+  if (lMat->rows() != lMat->cols())
+  {
+    Werror("second matrix (%d x %d) is not quadratic",
+           lMat->rows(), lMat->cols());
+    return TRUE;
+  }
+  if (lMat->rows() != uMat->rows())
+  {
+    Werror("second matrix (%d x %d) and third matrix (%d x %d) do not fit",
+           lMat->rows(), lMat->cols(), uMat->rows(), uMat->cols());
+    return TRUE;
+  }
+  if (uMat->rows() != bVec->rows())
+  {
+    Werror("third matrix (%d x %d) and vector (%d x 1) do not fit",
+           uMat->rows(), uMat->cols(), bVec->rows());
+    return TRUE;
+  }
+  if (!idIsConstant((ideal)pMat)
+  ||(!idIsConstant((ideal)lMat))
+  ||(!idIsConstant((ideal)uMat))
+  )
+  {
+    WerrorS("matrices must be constant");
+    return TRUE;
+  }
+  solvable = luSolveViaLUDecomp(pMat, lMat, uMat, bVec, xVec, homogSolSpace);
+
+  /* build the return structure; a list with either one or three entries */
+  lists ll = (lists)omAllocBin(slists_bin);
+  if (solvable)
+  {
+    ll->Init(3);
+    ll->m[0].rtyp=INT_CMD;    ll->m[0].data=(void *)(long)solvable;
+    ll->m[1].rtyp=MATRIX_CMD; ll->m[1].data=(void *)xVec;
+    ll->m[2].rtyp=MATRIX_CMD; ll->m[2].data=(void *)homogSolSpace;
+  }
+  else
+  {
+    ll->Init(1);
+    ll->m[0].rtyp=INT_CMD;    ll->m[0].data=(void *)(long)solvable;
+  }
+
+  res->data=(char*)ll;
+  return FALSE;
+}
+static BOOLEAN jjINTVEC_PL(leftv res, leftv v)
+{
+  int i=0;
+  leftv h=v;
+  if (h!=NULL) i=exprlist_length(h);
+  intvec *iv=new intvec(i);
+  i=0;
+  while (h!=NULL)
+  {
+    if(h->Typ()==INT_CMD)
+    {
+      (*iv)[i]=(int)(long)h->Data();
+    }
+    else if (h->Typ()==INTVEC_CMD)
+    {
+      intvec *ivv=(intvec*)h->Data();
+      for(int j=0;j<ivv->length();j++,i++)
+      {
+        (*iv)[i]=(*ivv)[j];
+      }
+      i--;
+    }
+    else
+    {
+      delete iv;
+      return TRUE;
+    }
+    i++;
+    h=h->next;
+  }
+  res->data=(char *)iv;
+  return FALSE;
+}
+static BOOLEAN jjJET4(leftv res, leftv u)
+{
+  short t1[]={4,POLY_CMD,POLY_CMD,POLY_CMD,INTVEC_CMD};
+  short t2[]={4,VECTOR_CMD,POLY_CMD,POLY_CMD,INTVEC_CMD};
+  short t3[]={4,IDEAL_CMD,MATRIX_CMD,INT_CMD,INTVEC_CMD};
+  short t4[]={4,MODUL_CMD,MATRIX_CMD,INT_CMD,INTVEC_CMD};
+  leftv u1=u;
+  leftv u2=u1->next;
+  leftv u3=u2->next;
+  leftv u4=u3->next;
+  if (iiCheckTypes(u,t1)||iiCheckTypes(u,t2))
+  {
+    if(!pIsUnit((poly)u2->Data()))
+    {
+      WerrorS("2nd argument must be a unit");
+      return TRUE;
+    }
+    res->rtyp=u1->Typ();
+    res->data=(char*)pSeries((int)(long)u3->Data(),pCopy((poly)u1->Data()),
+                             pCopy((poly)u2->Data()),(intvec*)u4->Data());
+    return FALSE;
+  }
+  else
+  if (iiCheckTypes(u,t3)||iiCheckTypes(u,t4))
+  {
+    if(!mp_IsDiagUnit((matrix)u2->Data(), currRing))
+    {
+      WerrorS("2nd argument must be a diagonal matrix of units");
+      return TRUE;
+    }
+    res->rtyp=u1->Typ();
+    res->data=(char*)idSeries(
+                              (int)(long)u3->Data(),
+                              idCopy((ideal)u1->Data()),
+                              mp_Copy((matrix)u2->Data(), currRing),
+                              (intvec*)u4->Data()
+                             );
+    return FALSE;
+  }
+  else
+  {
+    Werror("%s(`poly`,`poly`,`int`,`intvec`) exppected",
+           Tok2Cmdname(iiOp));
+    return TRUE;
+  }
+}
+static BOOLEAN jjKLAMMER_PL(leftv res, leftv u)
+{
+  if ((yyInRingConstruction)
+  && ((strcmp(u->Name(),"real")==0) || (strcmp(u->Name(),"complex")==0)))
+  {
+    memcpy(res,u,sizeof(sleftv));
+    memset(u,0,sizeof(sleftv));
+    return FALSE;
+  }
+  leftv v=u->next;
+  BOOLEAN b;
+  if(v==NULL)
+    b=iiExprArith1(res,u,iiOp);
+  else
+  {
+    u->next=NULL;
+    b=iiExprArith2(res,u,iiOp,v);
+    u->next=v;
+  }
+  return b;
+}
+BOOLEAN jjLIST_PL(leftv res, leftv v)
+{
+  int sl=0;
+  if (v!=NULL) sl = v->listLength();
+  lists L;
+  if((sl==1)&&(v->Typ()==RESOLUTION_CMD))
+  {
+    int add_row_shift = 0;
+    intvec *weights=(intvec*)atGet(v,"isHomog",INTVEC_CMD);
+    if (weights!=NULL)  add_row_shift=weights->min_in();
+    L=syConvRes((syStrategy)v->Data(),FALSE,add_row_shift);
+  }
+  else
+  {
+    L=(lists)omAllocBin(slists_bin);
+    leftv h=NULL;
+    int i;
+    int rt;
+
+    L->Init(sl);
+    for (i=0;i<sl;i++)
+    {
+      if (h!=NULL)
+      { /* e.g. not in the first step:
+         * h is the pointer to the old sleftv,
+         * v is the pointer to the next sleftv
+         * (in this moment) */
+         h->next=v;
+      }
+      h=v;
+      v=v->next;
+      h->next=NULL;
+      rt=h->Typ();
+      if (rt==0)
+      {
+        L->Clean();
+        Werror("`%s` is undefined",h->Fullname());
+        return TRUE;
+      }
+      if ((rt==RING_CMD)||(rt==QRING_CMD))
+      {
+        L->m[i].rtyp=rt;  L->m[i].data=h->Data();
+        ((ring)L->m[i].data)->ref++;
+      }
+      else
+        L->m[i].Copy(h);
+    }
+  }
+  res->data=(char *)L;
+  return FALSE;
+}
+static BOOLEAN jjNAMES0(leftv res, leftv)
+{
+  res->data=(void *)ipNameList(IDROOT);
+  return FALSE;
+}
+static BOOLEAN jjOPTION_PL(leftv res, leftv v)
+{
+  if(v==NULL)
+  {
+    res->data=(char *)showOption();
+    return FALSE;
+  }
+  res->rtyp=NONE;
+  return setOption(res,v);
+}
+static BOOLEAN jjREDUCE4(leftv res, leftv u)
+{
+  leftv u1=u;
+  leftv u2=u1->next;
+  leftv u3=u2->next;
+  leftv u4=u3->next;
+  if((u3->Typ()==INT_CMD)&&(u4->Typ()==INTVEC_CMD))
+  {
+    int save_d=Kstd1_deg;
+    Kstd1_deg=(int)(long)u3->Data();
+    kModW=(intvec *)u4->Data();
+    BITSET save2;
+    SI_SAVE_OPT2(save2);
+    si_opt_2|=Sy_bit(V_DEG_STOP);
+    u2->next=NULL;
+    BOOLEAN r=jjCALL2ARG(res,u);
+    kModW=NULL;
+    Kstd1_deg=save_d;
+    SI_RESTORE_OPT2(save2);
+    u->next->next=u3;
+    return r;
+  }
+  else
+  if((u1->Typ()==IDEAL_CMD)&&(u2->Typ()==MATRIX_CMD)&&(u3->Typ()==IDEAL_CMD)&&
+     (u4->Typ()==INT_CMD))
+  {
+    assumeStdFlag(u3);
+    if(!mp_IsDiagUnit((matrix)u2->Data(), currRing))
+    {
+      WerrorS("2nd argument must be a diagonal matrix of units");
+      return TRUE;
+    }
+    res->rtyp=IDEAL_CMD;
+    res->data=(char*)redNF(
+                           idCopy((ideal)u3->Data()),
+                           idCopy((ideal)u1->Data()),
+                           mp_Copy((matrix)u2->Data(), currRing),
+                           (int)(long)u4->Data()
+                          );
+    return FALSE;
+  }
+  else
+  if((u1->Typ()==POLY_CMD)&&(u2->Typ()==POLY_CMD)&&(u3->Typ()==IDEAL_CMD)&&
+     (u4->Typ()==INT_CMD))
+  {
+    assumeStdFlag(u3);
+    if(!pIsUnit((poly)u2->Data()))
+    {
+      WerrorS("2nd argument must be a unit");
+      return TRUE;
+    }
+    res->rtyp=POLY_CMD;
+    res->data=(char*)redNF(idCopy((ideal)u3->Data()),pCopy((poly)u1->Data()),
+                           pCopy((poly)u2->Data()),(int)(long)u4->Data());
+    return FALSE;
+  }
+  else
+  {
+    Werror("%s(`poly`,`ideal`,`int`,`intvec`) expected",Tok2Cmdname(iiOp));
+    return TRUE;
+  }
+}
+static BOOLEAN jjREDUCE5(leftv res, leftv u)
+{
+  leftv u1=u;
+  leftv u2=u1->next;
+  leftv u3=u2->next;
+  leftv u4=u3->next;
+  leftv u5=u4->next;
+  if((u1->Typ()==IDEAL_CMD)&&(u2->Typ()==MATRIX_CMD)&&(u3->Typ()==IDEAL_CMD)&&
+     (u4->Typ()==INT_CMD)&&(u5->Typ()==INTVEC_CMD))
+  {
+    assumeStdFlag(u3);
+    if(!mp_IsDiagUnit((matrix)u2->Data(), currRing))
+    {
+      WerrorS("2nd argument must be a diagonal matrix of units");
+      return TRUE;
+    }
+    res->rtyp=IDEAL_CMD;
+    res->data=(char*)redNF(
+                           idCopy((ideal)u3->Data()),
+                           idCopy((ideal)u1->Data()),
+                           mp_Copy((matrix)u2->Data(),currRing),
+                           (int)(long)u4->Data(),
+                           (intvec*)u5->Data()
+                          );
+    return FALSE;
+  }
+  else
+  if((u1->Typ()==POLY_CMD)&&(u2->Typ()==POLY_CMD)&&(u3->Typ()==IDEAL_CMD)&&
+     (u4->Typ()==INT_CMD)&&(u5->Typ()==INTVEC_CMD))
+  {
+    assumeStdFlag(u3);
+    if(!pIsUnit((poly)u2->Data()))
+    {
+      WerrorS("2nd argument must be a unit");
+      return TRUE;
+    }
+    res->rtyp=POLY_CMD;
+    res->data=(char*)redNF(idCopy((ideal)u3->Data()),pCopy((poly)u1->Data()),
+                           pCopy((poly)u2->Data()),
+                           (int)(long)u4->Data(),(intvec*)u5->Data());
+    return FALSE;
+  }
+  else
+  {
+    Werror("%s(`ideal`,`ideal`,`matrix`,`int`,`intvec`) exppected",
+           Tok2Cmdname(iiOp));
+    return TRUE;
+  }
+}
+static BOOLEAN jjRESERVED0(leftv, leftv)
+{
+  int i=1;
+  int nCount = (sArithBase.nCmdUsed-1)/3;
+  if((3*nCount)<sArithBase.nCmdUsed) nCount++;
+  //Print("CMDS: %d/%d\n", sArithBase.nCmdUsed,
+  //      sArithBase.nCmdAllocated);
+  for(i=0; i<nCount; i++)
+  {
+    Print("%-20s",sArithBase.sCmds[i+1].name);
+    if(i+1+nCount<sArithBase.nCmdUsed)
+      Print("%-20s",sArithBase.sCmds[i+1+nCount].name);
+    if(i+1+2*nCount<sArithBase.nCmdUsed)
+      Print("%-20s",sArithBase.sCmds[i+1+2*nCount].name);
+    //if ((i%3)==1) PrintLn();
+    PrintLn();
+  }
+  PrintLn();
+  printBlackboxTypes();
+  return FALSE;
+}
+static BOOLEAN jjSTRING_PL(leftv res, leftv v)
+{
+  if (v == NULL)
+  {
+    res->data = omStrDup("");
+    return FALSE;
+  }
+  int n = v->listLength();
+  if (n == 1)
+  {
+    res->data = v->String();
+    return FALSE;
+  }
+
+  char** slist = (char**) omAlloc(n*sizeof(char*));
+  int i, j;
+
+  for (i=0, j=0; i<n; i++, v = v ->next)
+  {
+    slist[i] = v->String();
+    assume(slist[i] != NULL);
+    j+=strlen(slist[i]);
+  }
+  char* s = (char*) omAlloc((j+1)*sizeof(char));
+  *s='\0';
+  for (i=0;i<n;i++)
+  {
+    strcat(s, slist[i]);
+    omFree(slist[i]);
+  }
+  omFreeSize(slist, n*sizeof(char*));
+  res->data = s;
+  return FALSE;
+}
+static BOOLEAN jjTEST(leftv, leftv v)
+{
+  do
+  {
+    if (v->Typ()!=INT_CMD)
+      return TRUE;
+    test_cmd((int)(long)v->Data());
+    v=v->next;
+  }
+  while (v!=NULL);
+  return FALSE;
+}
+
+#if defined(__alpha) && !defined(linux)
+extern "C"
+{
+  void usleep(unsigned long usec);
+};
+#endif
+static BOOLEAN jjFactModD_M(leftv res, leftv v)
+{
+  /* compute two factors of h(x,y) modulo x^(d+1) in K[[x]][y],
+     see a detailed documentation in /kernel/linear_algebra/linearAlgebra.h
+
+     valid argument lists:
+     - (poly h, int d),
+     - (poly h, int d, poly f0, poly g0),       optional: factors of h(0,y),
+     - (poly h, int d, int xIndex, int yIndex), optional: indices of vars x & y
+                                                          in list of ring vars,
+     - (poly h, int d, poly f0, poly g0, int xIndex, int yIndec),
+                                                optional: all 4 optional args
+     (The defaults are xIndex = 1, yIndex = 2, f0 and g0 polynomials as found
+      by singclap_factorize and h(0, y)
+      has exactly two distinct monic factors [possibly with exponent > 1].)
+     result:
+     - list with the two factors f and g such that
+       h(x,y) = f(x,y)*g(x,y) mod x^(d+1)   */
+
+  poly h      = NULL;
+  int  d      =    1;
+  poly f0     = NULL;
+  poly g0     = NULL;
+  int  xIndex =    1;   /* default index if none provided */
+  int  yIndex =    2;   /* default index if none provided */
+
+  leftv u = v; int factorsGiven = 0;
+  if ((u == NULL) || (u->Typ() != POLY_CMD))
+  {
+    WerrorS("expected arguments (poly, int [, poly, poly] [, int, int])");
+    return TRUE;
+  }
+  else h = (poly)u->Data();
+  u = u->next;
+  if ((u == NULL) || (u->Typ() != INT_CMD))
+  {
+    WerrorS("expected arguments (poly, int [, poly, poly] [, int, int])");
+    return TRUE;
+  }
+  else d = (int)(long)u->Data();
+  u = u->next;
+  if ((u != NULL) && (u->Typ() == POLY_CMD))
+  {
+    if ((u->next == NULL) || (u->next->Typ() != POLY_CMD))
+    {
+      WerrorS("expected arguments (poly, int [, poly, poly] [, int, int])");
+      return TRUE;
+    }
+    else
+    {
+      f0 = (poly)u->Data();
+      g0 = (poly)u->next->Data();
+      factorsGiven = 1;
+      u = u->next->next;
+    }
+  }
+  if ((u != NULL) && (u->Typ() == INT_CMD))
+  {
+    if ((u->next == NULL) || (u->next->Typ() != INT_CMD))
+    {
+      WerrorS("expected arguments (poly, int [, poly, poly] [, int, int])");
+      return TRUE;
+    }
+    else
+    {
+      xIndex = (int)(long)u->Data();
+      yIndex = (int)(long)u->next->Data();
+      u = u->next->next;
+    }
+  }
+  if (u != NULL)
+  {
+    WerrorS("expected arguments (poly, int [, poly, poly] [, int, int])");
+    return TRUE;
+  }
+
+  /* checks for provided arguments */
+  if (pIsConstant(h) || (factorsGiven && (pIsConstant(f0) || pIsConstant(g0))))
+  {
+    WerrorS("expected non-constant polynomial argument(s)");
+    return TRUE;
+  }
+  int n = rVar(currRing);
+  if ((xIndex < 1) || (n < xIndex))
+  {
+    Werror("index for variable x (%d) out of range [1..%d]", xIndex, n);
+    return TRUE;
+  }
+  if ((yIndex < 1) || (n < yIndex))
+  {
+    Werror("index for variable y (%d) out of range [1..%d]", yIndex, n);
+    return TRUE;
+  }
+  if (xIndex == yIndex)
+  {
+    WerrorS("expected distinct indices for variables x and y");
+    return TRUE;
+  }
+
+  /* computation of f0 and g0 if missing */
+  if (factorsGiven == 0)
+  {
+    poly h0 = pSubst(pCopy(h), xIndex, NULL);
+    intvec* v = NULL;
+    ideal i = singclap_factorize(h0, &v, 0,currRing);
+
+    ivTest(v);
+
+    if (i == NULL) return TRUE;
+
+    idTest(i);
+
+    if ((v->rows() != 3) || ((*v)[0] =! 1) || (!nIsOne(pGetCoeff(i->m[0]))))
+    {
+      WerrorS("expected h(0,y) to have exactly two distinct monic factors");
+      return TRUE;
+    }
+    f0 = pPower(pCopy(i->m[1]), (*v)[1]);
+    g0 = pPower(pCopy(i->m[2]), (*v)[2]);
+    idDelete(&i);
+  }
+
+  poly f; poly g;
+  henselFactors(xIndex, yIndex, h, f0, g0, d, f, g);
+  lists L = (lists)omAllocBin(slists_bin);
+  L->Init(2);
+  L->m[0].rtyp = POLY_CMD; L->m[0].data=(void*)f;
+  L->m[1].rtyp = POLY_CMD; L->m[1].data=(void*)g;
+  res->rtyp = LIST_CMD;
+  res->data = (char*)L;
+  return FALSE;
+}
+static BOOLEAN jjSTATUS_M(leftv res, leftv v)
+{
+  if ((v->Typ() != LINK_CMD) ||
+      (v->next->Typ() != STRING_CMD) ||
+      (v->next->next->Typ() != STRING_CMD) ||
+      (v->next->next->next->Typ() != INT_CMD))
+    return TRUE;
+  jjSTATUS3(res, v, v->next, v->next->next);
+#if defined(HAVE_USLEEP)
+  if (((long) res->data) == 0L)
+  {
+    int i_s = (int)(long) v->next->next->next->Data();
+    if (i_s > 0)
+    {
+      usleep((int)(long) v->next->next->next->Data());
+      jjSTATUS3(res, v, v->next, v->next->next);
+    }
+  }
+#elif defined(HAVE_SLEEP)
+  if (((int) res->data) == 0)
+  {
+    int i_s = (int) v->next->next->next->Data();
+    if (i_s > 0)
+    {
+      si_sleep((is - 1)/1000000 + 1);
+      jjSTATUS3(res, v, v->next, v->next->next);
+    }
+  }
+#endif
+  return FALSE;
+}
+static BOOLEAN jjSUBST_M(leftv res, leftv u)
+{
+  leftv v = u->next; // number of args > 0
+  if (v==NULL) return TRUE;
+  leftv w = v->next;
+  if (w==NULL) return TRUE;
+  leftv rest = w->next;;
+
+  u->next = NULL;
+  v->next = NULL;
+  w->next = NULL;
+  BOOLEAN b = iiExprArith3(res, iiOp, u, v, w);
+  if ((rest!=NULL) && (!b))
+  {
+    sleftv tmp_res;
+    leftv tmp_next=res->next;
+    res->next=rest;
+    memset(&tmp_res,0,sizeof(tmp_res));
+    b = iiExprArithM(&tmp_res,res,iiOp);
+    memcpy(res,&tmp_res,sizeof(tmp_res));
+    res->next=tmp_next;
+  }
+  u->next = v;
+  v->next = w;
+  // rest was w->next, but is already cleaned
+  return b;
+}
+static BOOLEAN jjQRDS(leftv res, leftv INPUT)
+{
+  if ((INPUT->Typ() != MATRIX_CMD) ||
+      (INPUT->next->Typ() != NUMBER_CMD) ||
+      (INPUT->next->next->Typ() != NUMBER_CMD) ||
+      (INPUT->next->next->next->Typ() != NUMBER_CMD))
+  {
+    WerrorS("expected (matrix, number, number, number) as arguments");
+    return TRUE;
+  }
+  leftv u = INPUT; leftv v = u->next; leftv w = v->next; leftv x = w->next;
+  res->data = (char *)qrDoubleShift((matrix)(u->Data()),
+                                    (number)(v->Data()),
+                                    (number)(w->Data()),
+                                    (number)(x->Data()));
+  return FALSE;
+}
+static BOOLEAN jjSTD_HILB_WP(leftv res, leftv INPUT)
+{ ideal result;
+  leftv u = INPUT;    /* an ideal, weighted homogeneous and standard */
+  leftv v = u->next;  /* one additional polynomial or ideal */
+  leftv h = v->next;  /* Hilbert vector */
+  leftv w = h->next;  /* weight vector */
+  assumeStdFlag(u);
+  ideal i1=(ideal)(u->Data());
+  ideal i0;
+  if (((u->Typ()!=IDEAL_CMD)&&(u->Typ()!=MODUL_CMD))
+  || (h->Typ()!=INTVEC_CMD)
+  || (w->Typ()!=INTVEC_CMD))
+  {
+    WerrorS("expected `std(`ideal/module`,`poly/vector`,`intvec`,`intvec`)");
+    return TRUE;
+  }
+  intvec *vw=(intvec *)w->Data(); // weights of vars
+  /* merging std_hilb_w and std_1 */
+  if (vw->length()!=currRing->N)
+  {
+    Werror("%d weights for %d variables",vw->length(),currRing->N);
+    return TRUE;
+  }
+  int r=v->Typ();
+  BOOLEAN cleanup_i0=FALSE;
+  if ((r==POLY_CMD) ||(r==VECTOR_CMD))
+  {
+    i0=idInit(1,i1->rank);
+    i0->m[0]=(poly)v->Data();
+    cleanup_i0=TRUE;
+  }
+  else if (r==IDEAL_CMD)/* IDEAL */
+  {
+    i0=(ideal)v->Data();
+  }
+  else
+  {
+    WerrorS("expected `std(`ideal/module`,`poly/vector`,`intvec`,`intvec`)");
+    return TRUE;
+  }
+  int ii0=idElem(i0);
+  i1 = idSimpleAdd(i1,i0);
+  if (cleanup_i0)
+  {
+    memset(i0->m,0,sizeof(poly)*IDELEMS(i0));
+    idDelete(&i0);
+  }
+  intvec *ww=(intvec *)atGet(u,"isHomog",INTVEC_CMD);
+  tHomog hom=testHomog;
+  /* u_id from jjSTD_W is now i1 as in jjSTD_1 */
+  if (ww!=NULL)
+  {
+    if (!idTestHomModule(i1,currRing->qideal,ww))
+    {
+      WarnS("wrong weights");
+      ww=NULL;
+    }
+    else
+    {
+      ww=ivCopy(ww);
+      hom=isHomog;
+    }
+  }
+  BITSET save1;
+  SI_SAVE_OPT1(save1);
+  si_opt_1|=Sy_bit(OPT_SB_1);
+  result=kStd(i1,
+              currRing->qideal,
+              hom,
+              &ww,                  // module weights
+              (intvec *)h->Data(),  // hilbert series
+              0,                    // syzComp, whatever it is...
+              IDELEMS(i1)-ii0,      // new ideal
+              vw);                  // weights of vars
+  SI_RESTORE_OPT1(save1);
+  idDelete(&i1);
+  idSkipZeroes(result);
+  res->data = (char *)result;
+  if (!TEST_OPT_DEGBOUND) setFlag(res,FLAG_STD);
+  if (ww!=NULL) atSet(res,omStrDup("isHomog"),ww,INTVEC_CMD);
+  return FALSE;
+}
+
+
+static Subexpr jjMakeSub(leftv e)
+{
+  assume( e->Typ()==INT_CMD );
+  Subexpr r=(Subexpr)omAlloc0Bin(sSubexpr_bin);
+  r->start =(int)(long)e->Data();
+  return r;
+}
+#define D(A)    (A)
+#define NULL_VAL NULL
+#define IPARITH
+#include "table.h"
+
+#include "iparith.inc"
+
+/*=================== operations with 2 args. ============================*/
+/* must be ordered: first operations for chars (infix ops),
+ * then alphabetically */
+
+static BOOLEAN iiExprArith2TabIntern(leftv res, leftv a, int op, leftv b,
+                                    BOOLEAN proccall,
+                                    struct sValCmd2* dA2,
+                                    int at, int bt,
+                                    struct sConvertTypes *dConvertTypes)
+{
+  memset(res,0,sizeof(sleftv));
+  BOOLEAN call_failed=FALSE;
+
+  if (!errorreported)
+  {
+    int i=0;
+    iiOp=op;
+    while (dA2[i].cmd==op)
+    {
+      if ((at==dA2[i].arg1)
+      && (bt==dA2[i].arg2))
+      {
+        res->rtyp=dA2[i].res;
+        if (currRing!=NULL)
+        {
+          if (check_valid(dA2[i].valid_for,op)) break;
+        }
+        else
+        {
+          if (RingDependend(dA2[i].res))
+          {
+            WerrorS("no ring active");
+            break;
+          }
+        }
+        if (traceit&TRACE_CALL)
+          Print("call %s(%s,%s)\n",iiTwoOps(op),Tok2Cmdname(at),Tok2Cmdname(bt));
+        if ((call_failed=dA2[i].p(res,a,b)))
+        {
+          break;// leave loop, goto error handling
+        }
+        a->CleanUp();
+        b->CleanUp();
+        //Print("op: %d,result typ:%d\n",op,res->rtyp);
+        return FALSE;
+      }
+      i++;
+    }
+    // implicite type conversion ----------------------------------------------
+    if (dA2[i].cmd!=op)
+    {
+      int ai,bi;
+      leftv an = (leftv)omAlloc0Bin(sleftv_bin);
+      leftv bn = (leftv)omAlloc0Bin(sleftv_bin);
+      BOOLEAN failed=FALSE;
+      i=0; /*iiTabIndex(dArithTab2,JJTAB2LEN,op);*/
+      //Print("op: %c, type: %s %s\n",op,Tok2Cmdname(at),Tok2Cmdname(bt));
+      while (dA2[i].cmd==op)
+      {
+        //Print("test %s %s\n",Tok2Cmdname(dA2[i].arg1),Tok2Cmdname(dA2[i].arg2));
+        if ((ai=iiTestConvert(at,dA2[i].arg1))!=0)
+        {
+          if ((bi=iiTestConvert(bt,dA2[i].arg2))!=0)
+          {
+            res->rtyp=dA2[i].res;
+            if (currRing!=NULL)
+            {
+              if (check_valid(dA2[i].valid_for,op)) break;
+            }
+            else
+            {
+              if (RingDependend(dA2[i].res))
+              {
+                WerrorS("no ring active");
+                break;
+              }
+            }
+            if (traceit&TRACE_CALL)
+              Print("call %s(%s,%s)\n",iiTwoOps(op),
+              Tok2Cmdname(dA2[i].arg1),Tok2Cmdname(dA2[i].arg2));
+            failed= ((iiConvert(at,dA2[i].arg1,ai,a,an))
+            || (iiConvert(bt,dA2[i].arg2,bi,b,bn))
+            || (call_failed=dA2[i].p(res,an,bn)));
+            // everything done, clean up temp. variables
+            if (failed)
+            {
+              // leave loop, goto error handling
+              break;
+            }
+            else
+            {
+              // everything ok, clean up and return
+              an->CleanUp();
+              bn->CleanUp();
+              omFreeBin((ADDRESS)an, sleftv_bin);
+              omFreeBin((ADDRESS)bn, sleftv_bin);
+              a->CleanUp();
+              b->CleanUp();
+              return FALSE;
+            }
+          }
+        }
+        i++;
+      }
+      an->CleanUp();
+      bn->CleanUp();
+      omFreeBin((ADDRESS)an, sleftv_bin);
+      omFreeBin((ADDRESS)bn, sleftv_bin);
+    }
+    // error handling ---------------------------------------------------
+    const char *s=NULL;
+    if (!errorreported)
+    {
+      if ((at==0) && (a->Fullname()!=sNoName))
+      {
+        s=a->Fullname();
+      }
+      else if ((bt==0) && (b->Fullname()!=sNoName))
+      {
+        s=b->Fullname();
+      }
+      if (s!=NULL)
+        Werror("`%s` is not defined",s);
+      else
+      {
+        i=0; /*iiTabIndex(dArithTab2,JJTAB2LEN,op);*/
+        s = iiTwoOps(op);
+        if (proccall)
+        {
+          Werror("%s(`%s`,`%s`) failed"
+                ,s,Tok2Cmdname(at),Tok2Cmdname(bt));
+        }
+        else
+        {
+          Werror("`%s` %s `%s` failed"
+                ,Tok2Cmdname(at),s,Tok2Cmdname(bt));
+        }
+        if ((!call_failed) && BVERBOSE(V_SHOW_USE))
+        {
+          while (dA2[i].cmd==op)
+          {
+            if(((at==dA2[i].arg1)||(bt==dA2[i].arg2))
+            && (dA2[i].res!=0)
+            && (dA2[i].p!=jjWRONG2))
+            {
+              if (proccall)
+                Werror("expected %s(`%s`,`%s`)"
+                  ,s,Tok2Cmdname(dA2[i].arg1),Tok2Cmdname(dA2[i].arg2));
+              else
+                Werror("expected `%s` %s `%s`"
+                  ,Tok2Cmdname(dA2[i].arg1),s,Tok2Cmdname(dA2[i].arg2));
+            }
+            i++;
+          }
+        }
+      }
+    }
+    res->rtyp = UNKNOWN;
+  }
+  a->CleanUp();
+  b->CleanUp();
+  return TRUE;
+}
+BOOLEAN iiExprArith2Tab(leftv res, leftv a, int op,
+                                    struct sValCmd2* dA2,
+                                    int at,
+                                    struct sConvertTypes *dConvertTypes)
+{
+  leftv b=a->next;
+  a->next=NULL;
+  int bt=b->Typ();
+  BOOLEAN bo=iiExprArith2TabIntern(res,a,op,b,TRUE,dA2,at,bt,dConvertTypes);
+  a->next=b;
+  a->CleanUp();
+  return bo;
+}
+BOOLEAN iiExprArith2(leftv res, leftv a, int op, leftv b, BOOLEAN proccall)
+{
+  memset(res,0,sizeof(sleftv));
+  BOOLEAN call_failed=FALSE;
+
+  if (!errorreported)
+  {
+#ifdef SIQ
+    if (siq>0)
+    {
+      //Print("siq:%d\n",siq);
+      command d=(command)omAlloc0Bin(sip_command_bin);
+      memcpy(&d->arg1,a,sizeof(sleftv));
+      //a->Init();
+      memcpy(&d->arg2,b,sizeof(sleftv));
+      //b->Init();
+      d->argc=2;
+      d->op=op;
+      res->data=(char *)d;
+      res->rtyp=COMMAND;
+      return FALSE;
+    }
+#endif
+    int at=a->Typ();
+    int bt=b->Typ();
+    // handling bb-objects ----------------------------------------------------
+    if (at>MAX_TOK)
+    {
+      blackbox *bb=getBlackboxStuff(at);
+      if (bb!=NULL)
+      {
+        if (!bb->blackbox_Op2(op,res,a,b)) return FALSE;
+        if (errorreported) return TRUE;
+        // else: no op defined
+      }
+      else          return TRUE;
+    }
+    else if ((bt>MAX_TOK)&&(op!='('))
+    {
+      blackbox *bb=getBlackboxStuff(bt);
+      if (bb!=NULL)
+      {
+        if(!bb->blackbox_Op2(op,res,a,b)) return FALSE;
+        if (errorreported) return TRUE;
+        // else: no op defined
+      }
+      else          return TRUE;
+    }
+    int i=iiTabIndex(dArithTab2,JJTAB2LEN,op);
+    return iiExprArith2TabIntern(res,a,op,b,proccall,dArith2+i,at,bt,dConvertTypes);
+  }
+  a->CleanUp();
+  b->CleanUp();
+  return TRUE;
+}
+
+/*==================== operations with 1 arg. ===============================*/
+/* must be ordered: first operations for chars (infix ops),
+ * then alphabetically */
+
+BOOLEAN iiExprArith1Tab(leftv res, leftv a, int op, struct sValCmd1* dA1, int at, struct sConvertTypes *dConvertTypes)
+{
+  memset(res,0,sizeof(sleftv));
+  BOOLEAN call_failed=FALSE;
+
+  if (!errorreported)
+  {
+    BOOLEAN failed=FALSE;
+    iiOp=op;
+    int i = 0;
+    while (dA1[i].cmd==op)
+    {
+      if (at==dA1[i].arg)
+      {
+        if (currRing!=NULL)
+        {
+          if (check_valid(dA1[i].valid_for,op)) break;
+        }
+        else
+        {
+          if (RingDependend(dA1[i].res))
+          {
+            WerrorS("no ring active");
+            break;
+          }
+        }
+        if (traceit&TRACE_CALL)
+          Print("call %s(%s)\n",iiTwoOps(op),Tok2Cmdname(at));
+        res->rtyp=dA1[i].res;
+        if ((call_failed=dA1[i].p(res,a)))
+        {
+          break;// leave loop, goto error handling
+        }
+        if (a->Next()!=NULL)
+        {
+          res->next=(leftv)omAllocBin(sleftv_bin);
+          failed=iiExprArith1(res->next,a->next,op);
+        }
+        a->CleanUp();
+        return failed;
+      }
+      i++;
+    }
+    // implicite type conversion --------------------------------------------
+    if (dA1[i].cmd!=op)
+    {
+      leftv an = (leftv)omAlloc0Bin(sleftv_bin);
+      i=0;
+      //Print("fuer %c , typ: %s\n",op,Tok2Cmdname(at));
+      while (dA1[i].cmd==op)
+      {
+        int ai;
+        //Print("test %s\n",Tok2Cmdname(dA1[i].arg));
+        if ((ai=iiTestConvert(at,dA1[i].arg,dConvertTypes))!=0)
+        {
+          if (currRing!=NULL)
+          {
+            if (check_valid(dA1[i].valid_for,op)) break;
+          }
+          else
+          {
+            if (RingDependend(dA1[i].res))
+            {
+              WerrorS("no ring active");
+              break;
+            }
+          }
+          if (traceit&TRACE_CALL)
+            Print("call %s(%s)\n",iiTwoOps(op),Tok2Cmdname(dA1[i].arg));
+          res->rtyp=dA1[i].res;
+          failed= ((iiConvert(at,dA1[i].arg,ai,a,an,dConvertTypes))
+          || (call_failed=dA1[i].p(res,an)));
+          // everything done, clean up temp. variables
+          if (failed)
+          {
+            // leave loop, goto error handling
+            break;
+          }
+          else
+          {
+            if (an->Next() != NULL)
+            {
+              res->next = (leftv)omAllocBin(sleftv_bin);
+              failed=iiExprArith1(res->next,an->next,op);
+            }
+            // everything ok, clean up and return
+            an->CleanUp();
+            omFreeBin((ADDRESS)an, sleftv_bin);
+            a->CleanUp();
+            return failed;
+          }
+        }
+        i++;
+      }
+      an->CleanUp();
+      omFreeBin((ADDRESS)an, sleftv_bin);
+    }
+    // error handling
+    if (!errorreported)
+    {
+      if ((at==0) && (a->Fullname()!=sNoName))
+      {
+        Werror("`%s` is not defined",a->Fullname());
+      }
+      else
+      {
+        i=0;
+        const char *s = iiTwoOps(op);
+        Werror("%s(`%s`) failed"
+                ,s,Tok2Cmdname(at));
+        if ((!call_failed) && BVERBOSE(V_SHOW_USE))
+        {
+          while (dA1[i].cmd==op)
+          {
+            if ((dA1[i].res!=0)
+            && (dA1[i].p!=jjWRONG))
+              Werror("expected %s(`%s`)"
+                ,s,Tok2Cmdname(dA1[i].arg));
+            i++;
+          }
+        }
+      }
+    }
+    res->rtyp = UNKNOWN;
+  }
+  a->CleanUp();
+  return TRUE;
+}
+BOOLEAN iiExprArith1(leftv res, leftv a, int op)
+{
+  memset(res,0,sizeof(sleftv));
+  BOOLEAN call_failed=FALSE;
+
+  if (!errorreported)
+  {
+#ifdef SIQ
+    if (siq>0)
+    {
+      //Print("siq:%d\n",siq);
+      command d=(command)omAlloc0Bin(sip_command_bin);
+      memcpy(&d->arg1,a,sizeof(sleftv));
+      //a->Init();
+      d->op=op;
+      d->argc=1;
+      res->data=(char *)d;
+      res->rtyp=COMMAND;
+      return FALSE;
+    }
+#endif
+    int at=a->Typ();
+    // handling bb-objects ----------------------------------------------------
+    if (at>MAX_TOK)
+    {
+      blackbox *bb=getBlackboxStuff(at);
+      if (bb!=NULL)
+      {
+        if(!bb->blackbox_Op1(op,res,a)) return FALSE;
+        if (errorreported) return TRUE;
+        // else: no op defined
+      }
+      else          return TRUE;
+    }
+
+    BOOLEAN failed=FALSE;
+    iiOp=op;
+    int i=iiTabIndex(dArithTab1,JJTAB1LEN,op);
+    return iiExprArith1Tab(res,a,op, dArith1+i,at,dConvertTypes);
+  }
+  a->CleanUp();
+  return TRUE;
+}
+
+/*=================== operations with 3 args. ============================*/
+/* must be ordered: first operations for chars (infix ops),
+ * then alphabetically */
+
+static BOOLEAN iiExprArith3TabIntern(leftv res, int op, leftv a, leftv b, leftv c,
+  struct sValCmd3* dA3, int at, int bt, int ct,
+  struct sConvertTypes *dConvertTypes)
+{
+  memset(res,0,sizeof(sleftv));
+  BOOLEAN call_failed=FALSE;
+
+  assume(dA3[0].cmd==op);
+
+  if (!errorreported)
+  {
+    int i=0;
+    iiOp=op;
+    while (dA3[i].cmd==op)
+    {
+      if ((at==dA3[i].arg1)
+      && (bt==dA3[i].arg2)
+      && (ct==dA3[i].arg3))
+      {
+        res->rtyp=dA3[i].res;
+        if (currRing!=NULL)
+        {
+          if (check_valid(dA3[i].valid_for,op)) break;
+        }
+        if (traceit&TRACE_CALL)
+          Print("call %s(%s,%s,%s)\n",
+            iiTwoOps(op),Tok2Cmdname(at),Tok2Cmdname(bt),Tok2Cmdname(ct));
+        if ((call_failed=dA3[i].p(res,a,b,c)))
+        {
+          break;// leave loop, goto error handling
+        }
+        a->CleanUp();
+        b->CleanUp();
+        c->CleanUp();
+        return FALSE;
+      }
+      i++;
+    }
+    // implicite type conversion ----------------------------------------------
+    if (dA3[i].cmd!=op)
+    {
+      int ai,bi,ci;
+      leftv an = (leftv)omAlloc0Bin(sleftv_bin);
+      leftv bn = (leftv)omAlloc0Bin(sleftv_bin);
+      leftv cn = (leftv)omAlloc0Bin(sleftv_bin);
+      BOOLEAN failed=FALSE;
+      i=0;
+      //while ((dA3[i].cmd!=op)&&(dA3[i].cmd!=0)) i++;
+      while (dA3[i].cmd==op)
+      {
+        if ((ai=iiTestConvert(at,dA3[i].arg1,dConvertTypes))!=0)
+        {
+          if ((bi=iiTestConvert(bt,dA3[i].arg2,dConvertTypes))!=0)
+          {
+            if ((ci=iiTestConvert(ct,dA3[i].arg3,dConvertTypes))!=0)
+            {
+              res->rtyp=dA3[i].res;
+              if (currRing!=NULL)
+              {
+                if (check_valid(dA3[i].valid_for,op)) break;
+              }
+              if (traceit&TRACE_CALL)
+                Print("call %s(%s,%s,%s)\n",
+                  iiTwoOps(op),Tok2Cmdname(dA3[i].arg1),
+                  Tok2Cmdname(dA3[i].arg2),Tok2Cmdname(dA3[i].arg3));
+              failed= ((iiConvert(at,dA3[i].arg1,ai,a,an,dConvertTypes))
+                || (iiConvert(bt,dA3[i].arg2,bi,b,bn,dConvertTypes))
+                || (iiConvert(ct,dA3[i].arg3,ci,c,cn,dConvertTypes))
+                || (call_failed=dA3[i].p(res,an,bn,cn)));
+              // everything done, clean up temp. variables
+              if (failed)
+              {
+                // leave loop, goto error handling
+                break;
+              }
+              else
+              {
+                // everything ok, clean up and return
+                an->CleanUp();
+                bn->CleanUp();
+                cn->CleanUp();
+                omFreeBin((ADDRESS)an, sleftv_bin);
+                omFreeBin((ADDRESS)bn, sleftv_bin);
+                omFreeBin((ADDRESS)cn, sleftv_bin);
+                a->CleanUp();
+                b->CleanUp();
+                c->CleanUp();
+        //Print("op: %d,result typ:%d\n",op,res->rtyp);
+                return FALSE;
+              }
+            }
+          }
+        }
+        i++;
+      }
+      an->CleanUp();
+      bn->CleanUp();
+      cn->CleanUp();
+      omFreeBin((ADDRESS)an, sleftv_bin);
+      omFreeBin((ADDRESS)bn, sleftv_bin);
+      omFreeBin((ADDRESS)cn, sleftv_bin);
+    }
+    // error handling ---------------------------------------------------
+    if (!errorreported)
+    {
+      const char *s=NULL;
+      if ((at==0) && (a->Fullname()!=sNoName))
+      {
+        s=a->Fullname();
+      }
+      else if ((bt==0) && (b->Fullname()!=sNoName))
+      {
+        s=b->Fullname();
+      }
+      else if ((ct==0) && (c->Fullname()!=sNoName))
+      {
+        s=c->Fullname();
+      }
+      if (s!=NULL)
+        Werror("`%s` is not defined",s);
+      else
+      {
+        i=0;
+        //while ((dA3[i].cmd!=op)&&(dA3[i].cmd!=0)) i++;
+        const char *s = iiTwoOps(op);
+        Werror("%s(`%s`,`%s`,`%s`) failed"
+                ,s,Tok2Cmdname(at),Tok2Cmdname(bt),Tok2Cmdname(ct));
+        if ((!call_failed) && BVERBOSE(V_SHOW_USE))
+        {
+          while (dA3[i].cmd==op)
+          {
+            if(((at==dA3[i].arg1)
+            ||(bt==dA3[i].arg2)
+            ||(ct==dA3[i].arg3))
+            && (dA3[i].res!=0))
+            {
+              Werror("expected %s(`%s`,`%s`,`%s`)"
+                  ,s,Tok2Cmdname(dA3[i].arg1)
+                  ,Tok2Cmdname(dA3[i].arg2)
+                  ,Tok2Cmdname(dA3[i].arg3));
+            }
+            i++;
+          }
+        }
+      }
+    }
+    res->rtyp = UNKNOWN;
+  }
+  a->CleanUp();
+  b->CleanUp();
+  c->CleanUp();
+        //Print("op: %d,result typ:%d\n",op,res->rtyp);
+  return TRUE;
+}
+BOOLEAN iiExprArith3(leftv res, int op, leftv a, leftv b, leftv c)
+{
+  memset(res,0,sizeof(sleftv));
+
+  if (!errorreported)
+  {
+#ifdef SIQ
+    if (siq>0)
+    {
+      //Print("siq:%d\n",siq);
+      command d=(command)omAlloc0Bin(sip_command_bin);
+      memcpy(&d->arg1,a,sizeof(sleftv));
+      //a->Init();
+      memcpy(&d->arg2,b,sizeof(sleftv));
+      //b->Init();
+      memcpy(&d->arg3,c,sizeof(sleftv));
+      //c->Init();
+      d->op=op;
+      d->argc=3;
+      res->data=(char *)d;
+      res->rtyp=COMMAND;
+      return FALSE;
+    }
+#endif
+    int at=a->Typ();
+    // handling bb-objects ----------------------------------------------
+    if (at>MAX_TOK)
+    {
+      blackbox *bb=getBlackboxStuff(at);
+      if (bb!=NULL)
+      {
+        if(!bb->blackbox_Op3(op,res,a,b,c)) return FALSE;
+        if (errorreported) return TRUE;
+        // else: no op defined
+      }
+      else          return TRUE;
+      if (errorreported) return TRUE;
+    }
+    int bt=b->Typ();
+    int ct=c->Typ();
+
+    iiOp=op;
+    int i=0;
+    while ((dArith3[i].cmd!=op)&&(dArith3[i].cmd!=0)) i++;
+    return iiExprArith3TabIntern(res,op,a,b,c,dArith3+i,at,bt,ct,dConvertTypes);
+  }
+  a->CleanUp();
+  b->CleanUp();
+  c->CleanUp();
+        //Print("op: %d,result typ:%d\n",op,res->rtyp);
+  return TRUE;
+}
+BOOLEAN iiExprArith3Tab(leftv res, leftv a, int op,
+                                    struct sValCmd3* dA3,
+                                    int at,
+                                    struct sConvertTypes *dConvertTypes)
+{
+  leftv b=a->next;
+  a->next=NULL;
+  int bt=b->Typ();
+  leftv c=b->next;
+  b->next=NULL;
+  int ct=c->Typ();
+  BOOLEAN bo=iiExprArith3TabIntern(res,op,a,b,c,dA3,at,bt,ct,dConvertTypes);
+  b->next=c;
+  a->next=b;
+  a->CleanUp();
+  return bo;
+}
+/*==================== operations with many arg. ===============================*/
+/* must be ordered: first operations for chars (infix ops),
+ * then alphabetically */
+
+BOOLEAN jjANY2LIST(leftv res, leftv v, int cnt)
+{
+  // cnt = 0: all
+  // cnt = 1: only first one
+  leftv next;
+  BOOLEAN failed = TRUE;
+  if(v==NULL) return failed;
+  res->rtyp = LIST_CMD;
+  if(cnt) v->next = NULL;
+  next = v->next;             // saving next-pointer
+  failed = jjLIST_PL(res, v);
+  v->next = next;             // writeback next-pointer
+  return failed;
+}
+
+BOOLEAN iiExprArithM(leftv res, leftv a, int op)
+{
+  memset(res,0,sizeof(sleftv));
+
+  if (!errorreported)
+  {
+#ifdef SIQ
+    if (siq>0)
+    {
+      //Print("siq:%d\n",siq);
+      command d=(command)omAlloc0Bin(sip_command_bin);
+      d->op=op;
+      res->data=(char *)d;
+      if (a!=NULL)
+      {
+        d->argc=a->listLength();
+        // else : d->argc=0;
+        memcpy(&d->arg1,a,sizeof(sleftv));
+        switch(d->argc)
+        {
+          case 3:
+            memcpy(&d->arg3,a->next->next,sizeof(sleftv));
+            a->next->next->Init();
+            /* no break */
+          case 2:
+            memcpy(&d->arg2,a->next,sizeof(sleftv));
+            a->next->Init();
+            a->next->next=d->arg2.next;
+            d->arg2.next=NULL;
+            /* no break */
+          case 1:
+            a->Init();
+            a->next=d->arg1.next;
+            d->arg1.next=NULL;
+        }
+        if (d->argc>3) a->next=NULL;
+        a->name=NULL;
+        a->rtyp=0;
+        a->data=NULL;
+        a->e=NULL;
+        a->attribute=NULL;
+        a->CleanUp();
+      }
+      res->rtyp=COMMAND;
+      return FALSE;
+    }
+#endif
+    if ((a!=NULL) && (a->Typ()>MAX_TOK))
+    {
+      blackbox *bb=getBlackboxStuff(a->Typ());
+      if (bb!=NULL)
+      {
+        if(!bb->blackbox_OpM(op,res,a)) return FALSE;
+        if (errorreported) return TRUE;
+        // else: no op defined
+      }
+      else          return TRUE;
+    }
+    BOOLEAN failed=FALSE;
+    int args=0;
+    if (a!=NULL) args=a->listLength();
+
+    iiOp=op;
+    int i=0;
+    while ((dArithM[i].cmd!=op)&&(dArithM[i].cmd!=0)) i++;
+    while (dArithM[i].cmd==op)
+    {
+      if ((args==dArithM[i].number_of_args)
+      || (dArithM[i].number_of_args==-1)
+      || ((dArithM[i].number_of_args==-2)&&(args>0)))
+      {
+        res->rtyp=dArithM[i].res;
+        if (currRing!=NULL)
+        {
+          if (check_valid(dArithM[i].valid_for,op)) break;
+        }
+        if (traceit&TRACE_CALL)
+          Print("call %s(... (%d args))\n", iiTwoOps(op),args);
+        if ((failed=dArithM[i].p(res,a))==TRUE)
+        {
+          break;// leave loop, goto error handling
+        }
+        if (a!=NULL) a->CleanUp();
+        //Print("op: %d,result typ:%d\n",op,res->rtyp);
+        return failed;
+      }
+      i++;
+    }
+    // error handling
+    if (!errorreported)
+    {
+      if ((args>0) && (a->rtyp==0) && (a->Name()!=sNoName))
+      {
+        Werror("`%s` is not defined",a->Fullname());
+      }
+      else
+      {
+        const char *s = iiTwoOps(op);
+        Werror("%s(...) failed",s);
+      }
+    }
+    res->rtyp = UNKNOWN;
+  }
+  if (a!=NULL) a->CleanUp();
+        //Print("op: %d,result typ:%d\n",op,res->rtyp);
+  return TRUE;
+}
+
+/*=================== general utilities ============================*/
+int IsCmd(const char *n, int & tok)
+{
+  int i;
+  int an=1;
+  int en=sArithBase.nLastIdentifier;
+
+  loop
+  //for(an=0; an<sArithBase.nCmdUsed; )
+  {
+    if(an>=en-1)
+    {
+      if (strcmp(n, sArithBase.sCmds[an].name) == 0)
+      {
+        i=an;
+        break;
+      }
+      else if ((an!=en) && (strcmp(n, sArithBase.sCmds[en].name) == 0))
+      {
+        i=en;
+        break;
+      }
+      else
+      {
+        // -- blackbox extensions:
+        // return 0;
+        return blackboxIsCmd(n,tok);
+      }
+    }
+    i=(an+en)/2;
+    if (*n < *(sArithBase.sCmds[i].name))
+    {
+      en=i-1;
+    }
+    else if (*n > *(sArithBase.sCmds[i].name))
+    {
+      an=i+1;
+    }
+    else
+    {
+      int v=strcmp(n,sArithBase.sCmds[i].name);
+      if(v<0)
+      {
+        en=i-1;
+      }
+      else if(v>0)
+      {
+        an=i+1;
+      }
+      else /*v==0*/
+      {
+        break;
+      }
+    }
+  }
+  lastreserved=sArithBase.sCmds[i].name;
+  tok=sArithBase.sCmds[i].tokval;
+  if(sArithBase.sCmds[i].alias==2)
+  {
+    Warn("outdated identifier `%s` used - please change your code",
+    sArithBase.sCmds[i].name);
+    sArithBase.sCmds[i].alias=1;
+  }
+  #if 0
+  if (currRingHdl==NULL)
+  {
+    #ifdef SIQ
+    if (siq<=0)
+    {
+    #endif
+      if ((tok>=BEGIN_RING) && (tok<=END_RING))
+      {
+        WerrorS("no ring active");
+        return 0;
+      }
+    #ifdef SIQ
+    }
+    #endif
+  }
+  #endif
+  if (!expected_parms)
+  {
+    switch (tok)
+    {
+      case IDEAL_CMD:
+      case INT_CMD:
+      case INTVEC_CMD:
+      case MAP_CMD:
+      case MATRIX_CMD:
+      case MODUL_CMD:
+      case POLY_CMD:
+      case PROC_CMD:
+      case RING_CMD:
+      case STRING_CMD:
+        cmdtok = tok;
+        break;
+    }
+  }
+  return sArithBase.sCmds[i].toktype;
+}
+static int iiTabIndex(const jjValCmdTab dArithTab, const int len, const int op)
+{
+  // user defined types are not in the pre-computed table:
+  if (op>MAX_TOK) return 0;
+
+  int a=0;
+  int e=len;
+  int p=len/2;
+  do
+  {
+     if (op==dArithTab[p].cmd) return dArithTab[p].start;
+     if (op<dArithTab[p].cmd) e=p-1;
+     else   a = p+1;
+     p=a+(e-a)/2;
+  }
+  while ( a <= e);
+
+  // catch missing a cmd:
+  // may be missing as a op for blackbox, if the first operand is "undef" instead of bb
+  // Print("op %d (%c) unknown",op,op);
+  return 0;
+}
+
+const char * Tok2Cmdname(int tok)
+{
+  if (tok <= 0)
+  {
+    return sArithBase.sCmds[0].name;
+  }
+  if (tok==ANY_TYPE) return "any_type";
+  if (tok==COMMAND) return "command";
+  if (tok==NONE) return "nothing";
+  //if (tok==IFBREAK) return "if_break";
+  //if (tok==VECTOR_FROM_POLYS) return "vector_from_polys";
+  //if (tok==ORDER_VECTOR) return "ordering";
+  //if (tok==REF_VAR) return "ref";
+  //if (tok==OBJECT) return "object";
+  //if (tok==PRINT_EXPR) return "print_expr";
+  if (tok==IDHDL) return "identifier";
+  if (tok==CRING_CMD) return "(c)ring";
+  if (tok>MAX_TOK) return getBlackboxName(tok);
+  int i;
+  for(i=0; i<sArithBase.nCmdUsed; i++)
+    //while (sArithBase.sCmds[i].tokval!=0)
+  {
+    if ((sArithBase.sCmds[i].tokval == tok)&&
+        (sArithBase.sCmds[i].alias==0))
+    {
+      return sArithBase.sCmds[i].name;
+    }
+  }
+  // try gain for alias/old names:
+  for(i=0; i<sArithBase.nCmdUsed; i++)
+  {
+    if (sArithBase.sCmds[i].tokval == tok)
+    {
+      return sArithBase.sCmds[i].name;
+    }
+  }
+  return sArithBase.sCmds[0].name;
+}
+
+
+/*---------------------------------------------------------------------*/
+/**
+ * @brief compares to entry of cmdsname-list
+
+ @param[in] a
+ @param[in] b
+
+ @return <ReturnValue>
+**/
+/*---------------------------------------------------------------------*/
+static int _gentable_sort_cmds( const void *a, const void *b )
+{
+  cmdnames *pCmdL = (cmdnames*)a;
+  cmdnames *pCmdR = (cmdnames*)b;
+
+  if(a==NULL || b==NULL)             return 0;
+
+  /* empty entries goes to the end of the list for later reuse */
+  if(pCmdL->name==NULL) return 1;
+  if(pCmdR->name==NULL) return -1;
+
+  /* $INVALID$ must come first */
+  if(strcmp(pCmdL->name, "$INVALID$")==0) return -1;
+  if(strcmp(pCmdR->name, "$INVALID$")==0) return  1;
+
+  /* tokval=-1 are reserved names at the end */
+  if (pCmdL->tokval==-1)
+  {
+    if (pCmdR->tokval==-1)
+       return strcmp(pCmdL->name, pCmdR->name);
+    /* pCmdL->tokval==-1, pCmdL goes at the end */
+    return 1;
+  }
+  /* pCmdR->tokval==-1, pCmdR goes at the end */
+  if(pCmdR->tokval==-1) return -1;
+
+  return strcmp(pCmdL->name, pCmdR->name);
+}
+
+/*---------------------------------------------------------------------*/
+/**
+ * @brief initialisation of arithmetic structured data
+
+ @retval 0 on success
+
+**/
+/*---------------------------------------------------------------------*/
+int iiInitArithmetic()
+{
+  //printf("iiInitArithmetic()\n");
+  memset(&sArithBase, 0, sizeof(sArithBase));
+  iiInitCmdName();
+  /* fix last-identifier */
+#if 0
+  /* we expect that gentable allready did every thing */
+  for(sArithBase.nLastIdentifier=sArithBase.nCmdUsed-1;
+      sArithBase.nLastIdentifier>0; sArithBase.nLastIdentifier--) {
+    if(sArithBase.sCmds[sArithBase.nLastIdentifier].tokval>=0) break;
+  }
+#endif
+  //Print("L=%d\n", sArithBase.nLastIdentifier);
+
+  //iiArithAddCmd(szName, nAlias, nTokval, nToktype);
+  //iiArithAddCmd("mygcd", 1, GCD_CMD, CMD_2);
+
+  //iiArithAddCmd("Top", 0,-1,0);
+
+
+  //for(i=0; i<sArithBase.nCmdUsed; i++) {
+  //  printf("CMD[%03d] %s, %d, %d, %d\n", i,
+  //         sArithBase.sCmds[i].name,
+  //         sArithBase.sCmds[i].alias,
+  //         sArithBase.sCmds[i].tokval,
+  //         sArithBase.sCmds[i].toktype);
+  //}
+  //iiArithRemoveCmd("Top");
+  //iiArithAddCmd("mygcd", 2, GCD_CMD, CMD_2);
+  //iiArithRemoveCmd("mygcd");
+  //iiArithAddCmd("kkk", 1, 1234, CMD_1);
+  return 0;
+}
+
+int iiArithFindCmd(const char *szName)
+{
+  int an=0;
+  int i = 0,v = 0;
+  int en=sArithBase.nLastIdentifier;
+
+  loop
+  //for(an=0; an<sArithBase.nCmdUsed; )
+  {
+    if(an>=en-1)
+    {
+      if (strcmp(szName, sArithBase.sCmds[an].name) == 0)
+      {
+        //Print("RET-an=%d %s\n", an, sArithBase.sCmds[an].name);
+        return an;
+      }
+      else if (strcmp(szName, sArithBase.sCmds[en].name) == 0)
+      {
+        //Print("RET-en=%d %s\n", en, sArithBase.sCmds[en].name);
+        return en;
+      }
+      else
+      {
+        //Print("RET- 1\n");
+        return -1;
+      }
+    }
+    i=(an+en)/2;
+    if (*szName < *(sArithBase.sCmds[i].name))
+    {
+      en=i-1;
+    }
+    else if (*szName > *(sArithBase.sCmds[i].name))
+    {
+      an=i+1;
+    }
+    else
+    {
+      v=strcmp(szName,sArithBase.sCmds[i].name);
+      if(v<0)
+      {
+        en=i-1;
+      }
+      else if(v>0)
+      {
+        an=i+1;
+      }
+      else /*v==0*/
+      {
+        //Print("RET-i=%d %s\n", i, sArithBase.sCmds[i].name);
+        return i;
+      }
+    }
+  }
+  //if(i>=0 && i<sArithBase.nCmdUsed)
+  //  return i;
+  //Print("RET-2\n");
+  return -2;
+}
+
+char *iiArithGetCmd( int nPos )
+{
+  if(nPos<0) return NULL;
+  if(nPos<sArithBase.nCmdUsed)
+    return sArithBase.sCmds[nPos].name;
+  return NULL;
+}
+
+int iiArithRemoveCmd(const char *szName)
+{
+  int nIndex;
+  if(szName==NULL) return -1;
+
+  nIndex = iiArithFindCmd(szName);
+  if(nIndex<0 || nIndex>=sArithBase.nCmdUsed)
+  {
+    Print("'%s' not found (%d)\n", szName, nIndex);
+    return -1;
+  }
+  omFree(sArithBase.sCmds[nIndex].name);
+  sArithBase.sCmds[nIndex].name=NULL;
+  qsort(sArithBase.sCmds, sArithBase.nCmdUsed, sizeof(cmdnames),
+        (&_gentable_sort_cmds));
+  sArithBase.nCmdUsed--;
+
+  /* fix last-identifier */
+  for(sArithBase.nLastIdentifier=sArithBase.nCmdUsed-1;
+      sArithBase.nLastIdentifier>0; sArithBase.nLastIdentifier--)
+  {
+    if(sArithBase.sCmds[sArithBase.nLastIdentifier].tokval>=0) break;
+  }
+  //Print("L=%d\n", sArithBase.nLastIdentifier);
+  return 0;
+}
+
+int iiArithAddCmd(
+  const char *szName,
+  short nAlias,
+  short nTokval,
+  short nToktype,
+  short nPos
+  )
+{
+  //printf("AddCmd(%s, %d, %d, %d, %d)\n", szName, nAlias,
+  //       nTokval, nToktype, nPos);
+  if(nPos>=0)
+  {
+    // no checks: we rely on a correct generated code in iparith.inc
+    assume(nPos < sArithBase.nCmdAllocated);
+    assume(szName!=NULL);
+    sArithBase.sCmds[nPos].name    = omStrDup(szName);
+    sArithBase.sCmds[nPos].alias   = nAlias;
+    sArithBase.sCmds[nPos].tokval  = nTokval;
+    sArithBase.sCmds[nPos].toktype = nToktype;
+    sArithBase.nCmdUsed++;
+    //if(nTokval>0) sArithBase.nLastIdentifier++;
+  }
+  else
+  {
+    if(szName==NULL) return -1;
+    int nIndex = iiArithFindCmd(szName);
+    if(nIndex>=0)
+    {
+      Print("'%s' already exists at %d\n", szName, nIndex);
+      return -1;
+    }
+
+    if(sArithBase.nCmdUsed>=sArithBase.nCmdAllocated)
+    {
+      /* needs to create new slots */
+      unsigned long nSize = (sArithBase.nCmdAllocated+1)*sizeof(cmdnames);
+      sArithBase.sCmds = (cmdnames *)omRealloc(sArithBase.sCmds, nSize);
+      if(sArithBase.sCmds==NULL) return -1;
+      sArithBase.nCmdAllocated++;
+    }
+    /* still free slots available */
+    sArithBase.sCmds[sArithBase.nCmdUsed].name    = omStrDup(szName);
+    sArithBase.sCmds[sArithBase.nCmdUsed].alias   = nAlias;
+    sArithBase.sCmds[sArithBase.nCmdUsed].tokval  = nTokval;
+    sArithBase.sCmds[sArithBase.nCmdUsed].toktype = nToktype;
+    sArithBase.nCmdUsed++;
+
+    qsort(sArithBase.sCmds, sArithBase.nCmdUsed, sizeof(cmdnames),
+          (&_gentable_sort_cmds));
+    for(sArithBase.nLastIdentifier=sArithBase.nCmdUsed-1;
+        sArithBase.nLastIdentifier>0; sArithBase.nLastIdentifier--)
+    {
+      if(sArithBase.sCmds[sArithBase.nLastIdentifier].tokval>=0) break;
+    }
+    //Print("L=%d\n", sArithBase.nLastIdentifier);
+  }
+  return 0;
+}
+
+static BOOLEAN check_valid(const int p, const int op)
+{
+  #ifdef HAVE_PLURAL
+  if (rIsPluralRing(currRing))
+  {
+    if ((p & PLURAL_MASK)==0 /*NO_PLURAL*/)
+    {
+      WerrorS("not implemented for non-commutative rings");
+      return TRUE;
+    }
+    else if ((p & PLURAL_MASK)==2 /*, COMM_PLURAL */)
+    {
+      Warn("assume commutative subalgebra for cmd `%s`",Tok2Cmdname(op));
+      return FALSE;
+    }
+    /* else, ALLOW_PLURAL */
+  }
+  #endif
+  #ifdef HAVE_RINGS
+  if (rField_is_Ring(currRing))
+  {
+    if ((p & RING_MASK)==0 /*NO_RING*/)
+    {
+      WerrorS("not implemented for rings with rings as coeffients");
+      return TRUE;
+    }
+    /* else ALLOW_RING */
+    else if (((p & ZERODIVISOR_MASK)==NO_ZERODIVISOR)
+    &&(!rField_is_Domain(currRing)))
+    {
+      WerrorS("domain required as coeffients");
+      return TRUE;
+    }
+    /* else ALLOW_ZERODIVISOR */
+    else if(((p & WARN_RING)==WARN_RING)&&(myynest==0))
+    {
+      WarnS("considering the image in Q[...]");
+    }
+  }
+  #endif
+  return FALSE;
+}
diff --git a/Singular/ipassign.cc b/Singular/ipassign.cc
new file mode 100644
index 0000000..6bfb017
--- /dev/null
+++ b/Singular/ipassign.cc
@@ -0,0 +1,2090 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: interpreter:
+*           assignment of expressions and lists to objects or lists
+*/
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+
+#include <kernel/mod2.h>
+
+#include <misc/auxiliary.h>
+#include <omalloc/omalloc.h>
+
+#define TRANSEXT_PRIVATES
+#include <polys/ext_fields/transext.h>
+
+#include <misc/options.h>
+#include <misc/intvec.h>
+
+#include <coeffs/coeffs.h>
+#include <coeffs/numbers.h>
+#include <coeffs/bigintmat.h>
+
+
+#include <polys/ext_fields/algext.h>
+
+#include <polys/monomials/ring.h>
+#include <polys/matpol.h>
+#include <polys/monomials/maps.h>
+#include <polys/nc/nc.h>
+#include <polys/nc/sca.h>
+#include <polys/prCopy.h>
+
+#include <kernel/polys.h>
+#include <kernel/ideals.h>
+#include <kernel/GBEngine/kstd1.h>
+#include <kernel/oswrapper/timer.h>
+#include <kernel/combinatorics/stairc.h>
+#include <kernel/GBEngine/syz.h>
+
+//#include "weight.h"
+#include "tok.h"
+#include "ipid.h"
+#include "idrec.h"
+#include "subexpr.h"
+#include "lists.h"
+#include "ipconv.h"
+#include "attrib.h"
+#include "links/silink.h"
+#include "ipshell.h"
+#include "blackbox.h"
+
+#include <Singular/number2.h>
+
+
+/*=================== proc =================*/
+static BOOLEAN jjECHO(leftv, leftv a)
+{
+  si_echo=(int)((long)(a->Data()));
+  return FALSE;
+}
+static BOOLEAN jjPRINTLEVEL(leftv, leftv a)
+{
+  printlevel=(int)((long)(a->Data()));
+  return FALSE;
+}
+static BOOLEAN jjCOLMAX(leftv, leftv a)
+{
+  colmax=(int)((long)(a->Data()));
+  return FALSE;
+}
+static BOOLEAN jjTIMER(leftv, leftv a)
+{
+  timerv=(int)((long)(a->Data()));
+  initTimer();
+  return FALSE;
+}
+#ifdef HAVE_GETTIMEOFDAY
+static BOOLEAN jjRTIMER(leftv, leftv a)
+{
+  rtimerv=(int)((long)(a->Data()));
+  initRTimer();
+  return FALSE;
+}
+#endif
+static BOOLEAN jjMAXDEG(leftv, leftv a)
+{
+  Kstd1_deg=(int)((long)(a->Data()));
+  if (Kstd1_deg!=0)
+    si_opt_1 |=Sy_bit(OPT_DEGBOUND);
+  else
+    si_opt_1 &=(~Sy_bit(OPT_DEGBOUND));
+  return FALSE;
+}
+static BOOLEAN jjMAXMULT(leftv, leftv a)
+{
+  Kstd1_mu=(int)((long)(a->Data()));
+  if (Kstd1_mu!=0)
+    si_opt_1 |=Sy_bit(OPT_MULTBOUND);
+  else
+    si_opt_1 &=(~Sy_bit(OPT_MULTBOUND));
+  return FALSE;
+}
+static BOOLEAN jjTRACE(leftv, leftv a)
+{
+  traceit=(int)((long)(a->Data()));
+  return FALSE;
+}
+static BOOLEAN jjSHORTOUT(leftv, leftv a)
+{
+  if (currRing != NULL)
+  {
+    BOOLEAN shortOut = (BOOLEAN)((long)a->Data());
+#if HAVE_CAN_SHORT_OUT
+    if (!shortOut)
+      currRing->ShortOut = 0;
+    else
+    {
+      if (currRing->CanShortOut)
+        currRing->ShortOut = 1;
+    }
+#else
+    currRing->ShortOut = shortOut;
+    coeffs cf = currRing->cf;
+    while (nCoeff_is_Extension(cf)) {
+      cf->extRing->ShortOut = shortOut;
+      assume(cf->extRing != NULL);
+      cf = cf->extRing->cf;
+    }
+#endif
+  }
+  return FALSE;
+}
+static void jjMINPOLY_red(idhdl h)
+{
+  switch(IDTYP(h))
+  {
+    case NUMBER_CMD:
+    {
+      number n=(number)IDDATA(h);
+      number one = nInit(1);
+      number nn=nMult(n,one);
+      nDelete(&n);nDelete(&one);
+      IDDATA(h)=(char*)nn;
+      break;
+    }
+    case VECTOR_CMD:
+    case POLY_CMD:
+    {
+      poly p=(poly)IDDATA(h);
+      IDDATA(h)=(char*)p_MinPolyNormalize(p, currRing);
+      break;
+    }
+    case IDEAL_CMD:
+    case MODUL_CMD:
+    case MAP_CMD:
+    case MATRIX_CMD:
+    {
+      int i;
+      ideal I=(ideal)IDDATA(h);
+      for(i=IDELEMS(I)-1;i>=0;i--)
+             I->m[i]=p_MinPolyNormalize(I->m[i], currRing);
+      break;
+    }
+    case LIST_CMD:
+    {
+      lists L=(lists)IDDATA(h);
+      int i=L->nr;
+      for(;i>=0;i--)
+      {
+        jjMINPOLY_red((idhdl)&(L->m[i]));
+      }
+    }
+    default:
+    //case RESOLUTION_CMD:
+       Werror("type %d too complex...set minpoly before",IDTYP(h)); break;
+  }
+}
+static BOOLEAN jjMINPOLY(leftv, leftv a)
+{
+  if( !nCoeff_is_transExt(currRing->cf) && (currRing->idroot == NULL) && n_IsZero((number)a->Data(), currRing->cf) )
+  {
+#ifndef SING_NDEBUG
+    WarnS("Set minpoly over non-transcendental ground field to 0?!");
+    Warn("in >>%s<<",my_yylinebuf);
+#endif
+    return FALSE;
+  }
+
+
+  if ( !nCoeff_is_transExt(currRing->cf) )
+  {
+    WarnS("Trying to set minpoly over non-transcendental ground field...");
+    if(!nCoeff_is_algExt(currRing->cf) )
+    {
+      WerrorS("cannot set minpoly for these coeffients");
+      return TRUE;
+    }
+  }
+  if ((rVar(currRing->cf->extRing)!=1)
+  && !n_IsZero((number)a->Data(), currRing->cf) )
+  {
+    WerrorS("only univarite minpoly allowed");
+    return TRUE;
+  }
+
+  if ( currRing->idroot != NULL )
+  {
+//    return TRUE;
+#ifndef SING_NDEBUG
+    idhdl p = currRing->idroot;
+
+    WarnS("no minpoly allowed if there are local objects belonging to the basering: ");
+
+    while(p != NULL)
+    {
+      PrintS(p->String(TRUE)); PrintLn();
+      p = p->next;
+    }
+#endif
+  }
+
+//  assume (currRing->idroot==NULL);
+
+  number p = (number)a->CopyD(NUMBER_CMD);
+  n_Normalize(p, currRing->cf);
+
+  if (n_IsZero(p, currRing->cf))
+  {
+    n_Delete(&p, currRing);
+    if( nCoeff_is_transExt(currRing->cf) )
+    {
+#ifndef SING_NDEBUG
+      WarnS("minpoly is already 0...");
+#endif
+      return FALSE;
+    }
+    WarnS("cannot set minpoly to 0 / alg. extension?");
+    return TRUE;
+  }
+
+  // remove all object currently in the ring
+  while(currRing->idroot!=NULL)
+  {
+#ifndef SING_NDEBUG
+    Warn("killing a local object due to minpoly change: %s", IDID(currRing->idroot));
+#endif
+    killhdl2(currRing->idroot,&(currRing->idroot),currRing);
+  }
+
+  AlgExtInfo A;
+
+  A.r = rCopy(currRing->cf->extRing); // Copy  ground field!
+  // if minpoly was already set:
+  if( currRing->cf->extRing->qideal != NULL ) id_Delete(&(A.r->qideal),A.r);
+  ideal q = idInit(1,1);
+  if ((p==NULL) ||(NUM((fraction)p)==NULL))
+  {
+    Werror("Could not construct the alg. extension: minpoly==0");
+    // cleanup A: TODO
+    rDelete( A.r );
+    return TRUE;
+  }
+  if (DEN((fraction)(p)) != NULL) // minpoly must be a fraction with poly numerator...!!
+  {
+    poly z=NUM((fraction)p);
+    poly n=DEN((fraction)(p));
+    z=p_Mult_nn(z,pGetCoeff(n),currRing->cf->extRing);
+    NUM((fraction)p)=z;
+    DEN((fraction)(p))=NULL;
+    p_Delete(&n,currRing->cf->extRing);
+  }
+
+  q->m[0] = NUM((fraction)p);
+  A.r->qideal = q;
+
+#if 0
+  PrintS("\nTrying to conver the currRing into an algebraic field: ");
+  PrintS("Ground poly. ring: \n");
+  rWrite( A.r );
+  PrintS("\nGiven MinPOLY: ");
+  p_Write( A.i->m[0], A.r );
+#endif
+
+  // :(
+//  NUM((fractionObject *)p) = NULL; // makes 0/ NULL fraction - which should not happen!
+//  n_Delete(&p, currRing->cf); // doesn't expect 0/ NULL :(
+  if(true)
+  {
+    extern omBin fractionObjectBin;
+    NUM((fractionObject *)p) = NULL; // not necessary, but still...
+    omFreeBin((ADDRESS)p, fractionObjectBin);
+  }
+
+
+  coeffs new_cf = nInitChar(n_algExt, &A);
+
+  if (new_cf==NULL)
+  {
+    Werror("Could not construct the alg. extension: llegal minpoly?");
+    // cleanup A: TODO
+    rDelete( A.r );
+    return TRUE;
+  }
+  else
+  {
+    nKillChar(currRing->cf); currRing->cf=new_cf;
+  }
+
+  return FALSE;
+}
+static BOOLEAN jjNOETHER(leftv, leftv a)
+{
+  poly p=(poly)a->CopyD(POLY_CMD);
+  pDelete(&(currRing->ppNoether));
+  (currRing->ppNoether)=p;
+  return FALSE;
+}
+/*=================== proc =================*/
+static void jiAssignAttr(leftv l,leftv r)
+{
+  // get the attribute of th right side
+  // and set it to l
+  leftv rv=r->LData();
+  if (rv!=NULL)
+  {
+    if (rv->e==NULL)
+    {
+      if (rv->attribute!=NULL)
+      {
+        attr la;
+        if (r->rtyp!=IDHDL)
+        {
+          la=rv->attribute;
+          rv->attribute=NULL;
+        }
+        else
+        {
+          la=rv->attribute->Copy();
+        }
+        l->attribute=la;
+      }
+      l->flag=rv->flag;
+    }
+  }
+  if (l->rtyp==IDHDL)
+  {
+    idhdl h=(idhdl)l->data;
+    IDATTR(h)=l->attribute;
+    IDFLAG(h)=l->flag;
+  }
+}
+static BOOLEAN jiA_INT(leftv res, leftv a, Subexpr e)
+{
+  if (e==NULL)
+  {
+    res->data=(void *)a->Data();
+    jiAssignAttr(res,a);
+  }
+  else
+  {
+    int i=e->start-1;
+    if (i<0)
+    {
+      Werror("index[%d] must be positive",i+1);
+      return TRUE;
+    }
+    intvec *iv=(intvec *)res->data;
+    if (e->next==NULL)
+    {
+      if (i>=iv->length())
+      {
+        intvec *iv1=new intvec(i+1);
+        (*iv1)[i]=(int)((long)(a->Data()));
+        intvec *ivn=ivAdd(iv,iv1);
+        delete iv;
+        delete iv1;
+        res->data=(void *)ivn;
+      }
+      else
+        (*iv)[i]=(int)((long)(a->Data()));
+    }
+    else
+    {
+      int c=e->next->start;
+      if ((i>=iv->rows())||(c<1)||(c>iv->cols()))
+      {
+        Werror("wrong range [%d,%d] in intmat %s(%d,%d)",i+1,c,res->Name(),iv->rows(),iv->cols());
+        return TRUE;
+      }
+      else
+        IMATELEM(*iv,i+1,c) = (int)((long)(a->Data()));
+    }
+  }
+  return FALSE;
+}
+static BOOLEAN jiA_NUMBER(leftv res, leftv a, Subexpr)
+{
+  number p=(number)a->CopyD(NUMBER_CMD);
+  if (res->data!=NULL) nDelete((number *)&res->data);
+  nNormalize(p);
+  res->data=(void *)p;
+  jiAssignAttr(res,a);
+  return FALSE;
+}
+#ifdef SINGULAR_4_1
+static BOOLEAN jiA_NUMBER2(leftv res, leftv a, Subexpr e)
+{
+  number2 n=(number2)a->CopyD(CNUMBER_CMD);
+  if (e==NULL)
+  {
+    if (res->data!=NULL)
+    {
+      number2 nn=(number2)res->data;
+      n2Delete(nn);
+    }
+    res->data=(void *)n;
+    jiAssignAttr(res,a);
+  }
+  else
+  {
+    int i=e->start-1;
+    if (i<0)
+    {
+      Werror("index[%d] must be positive",i+1);
+      return TRUE;
+    }
+    bigintmat *iv=(bigintmat *)res->data;
+    if (e->next==NULL)
+    {
+      WerrorS("only one index given");
+      return TRUE;
+    }
+    else
+    {
+      int c=e->next->start;
+      if ((i>=iv->rows())||(c<1)||(c>iv->cols()))
+      {
+        Werror("wrong range [%d,%d] in cmatrix %s(%d,%d)",i+1,c,res->Name(),iv->rows(),iv->cols());
+        return TRUE;
+      }
+      else if (iv->basecoeffs()==n->cf)
+      {
+        n_Delete((number *)&BIMATELEM(*iv,i+1,c),iv->basecoeffs());
+        BIMATELEM(*iv,i+1,c) = n->n;
+      }
+      else
+      {
+        WerrorS("different base");
+        return TRUE;
+      }
+    }
+  }
+  jiAssignAttr(res,a);
+  return FALSE;
+}
+#endif
+static BOOLEAN jiA_BIGINT(leftv res, leftv a, Subexpr e)
+{
+  number p=(number)a->CopyD(BIGINT_CMD);
+  if (e==NULL)
+  {
+    if (res->data!=NULL) n_Delete((number *)&res->data,coeffs_BIGINT);
+    res->data=(void *)p;
+  }
+  else
+  {
+    int i=e->start-1;
+    if (i<0)
+    {
+      Werror("index[%d] must be positive",i+1);
+      return TRUE;
+    }
+    bigintmat *iv=(bigintmat *)res->data;
+    if (e->next==NULL)
+    {
+      WerrorS("only one index given");
+      return TRUE;
+    }
+    else
+    {
+      int c=e->next->start;
+      if ((i>=iv->rows())||(c<1)||(c>iv->cols()))
+      {
+        Werror("wrong range [%d,%d] in bigintmat %s(%d,%d)",i+1,c,res->Name(),iv->rows(),iv->cols());
+        return TRUE;
+      }
+      else
+      {
+        n_Delete((number *)&BIMATELEM(*iv,i+1,c),iv->basecoeffs());
+        BIMATELEM(*iv,i+1,c) = p;
+      }
+    }
+  }
+  jiAssignAttr(res,a);
+  return FALSE;
+}
+static BOOLEAN jiA_LIST_RES(leftv res, leftv a,Subexpr)
+{
+  syStrategy r=(syStrategy)a->CopyD(RESOLUTION_CMD);
+  if (res->data!=NULL) ((lists)res->data)->Clean();
+  int add_row_shift = 0;
+  intvec *weights=(intvec*)atGet(a,"isHomog",INTVEC_CMD);
+  if (weights!=NULL)  add_row_shift=weights->min_in();
+  res->data=(void *)syConvRes(r,TRUE,add_row_shift);
+  //jiAssignAttr(res,a);
+  return FALSE;
+}
+static BOOLEAN jiA_LIST(leftv res, leftv a,Subexpr)
+{
+  lists l=(lists)a->CopyD(LIST_CMD);
+  if (res->data!=NULL) ((lists)res->data)->Clean();
+  res->data=(void *)l;
+  jiAssignAttr(res,a);
+  return FALSE;
+}
+static BOOLEAN jiA_POLY(leftv res, leftv a,Subexpr e)
+{
+  poly p=(poly)a->CopyD(POLY_CMD);
+  pNormalize(p);
+  if (e==NULL)
+  {
+    if (res->data!=NULL) pDelete((poly*)&res->data);
+    res->data=(void*)p;
+    jiAssignAttr(res,a);
+    if (TEST_V_QRING && (currRing->qideal!=NULL) && (!hasFlag(res,FLAG_QRING))) jjNormalizeQRingP(res);
+  }
+  else
+  {
+    int i,j;
+    matrix m=(matrix)res->data;
+    i=e->start;
+    if (e->next==NULL)
+    {
+      j=i; i=1;
+      // for all ideal like data types: check indices
+      if (j>MATCOLS(m))
+      {
+        if (TEST_V_ALLWARN)
+        {
+          Warn("increase ideal %d -> %d in %s",MATCOLS(m),j,my_yylinebuf);
+        }
+        pEnlargeSet(&(m->m),MATCOLS(m),j-MATCOLS(m));
+        MATCOLS(m)=j;
+      }
+      else if (j<=0)
+      {
+        Werror("index[%d] must be positive",j/*e->start*/);
+        return TRUE;
+      }
+    }
+    else
+    {
+      // for matrices: indices are correct (see ipExprArith3(..,'['..) )
+      j=e->next->start;
+    }
+    pDelete(&MATELEM(m,i,j));
+    MATELEM(m,i,j)=p;
+    /* for module: update rank */
+    if ((p!=NULL) && (pGetComp(p)!=0))
+    {
+      m->rank=si_max(m->rank,pMaxComp(p));
+    }
+    if (TEST_V_QRING) jjNormalizeQRingP(res);
+  }
+  return FALSE;
+}
+static BOOLEAN jiA_1x1INTMAT(leftv res, leftv a,Subexpr e)
+{
+  if (/*(*/ res->rtyp!=INTMAT_CMD /*)*/) /*|| (e!=NULL) - TRUE because of type int */
+  {
+    // no error message: assignment simply fails
+    return TRUE;
+  }
+  intvec* am=(intvec*)a->CopyD(INTMAT_CMD);
+  if ((am->rows()!=1) || (am->cols()!=1))
+  {
+    WerrorS("must be 1x1 intmat");
+    delete am;
+    return TRUE;
+  }
+  intvec* m=(intvec *)res->data;
+  // indices are correct (see ipExprArith3(..,'['..) )
+  int i=e->start;
+  int j=e->next->start;
+  IMATELEM(*m,i,j)=IMATELEM(*am,1,1);
+  delete am;
+  return FALSE;
+}
+static BOOLEAN jiA_1x1MATRIX(leftv res, leftv a,Subexpr e)
+{
+  if (/*(*/ res->rtyp!=MATRIX_CMD /*)*/) /*|| (e!=NULL) - TRUE because of type poly */
+  {
+    // no error message: assignment simply fails
+    return TRUE;
+  }
+  matrix am=(matrix)a->CopyD(MATRIX_CMD);
+  if ((MATROWS(am)!=1) || (MATCOLS(am)!=1))
+  {
+    WerrorS("must be 1x1 matrix");
+    idDelete((ideal *)&am);
+    return TRUE;
+  }
+  matrix m=(matrix)res->data;
+  // indices are correct (see ipExprArith3(..,'['..) )
+  int i=e->start;
+  int j=e->next->start;
+  pDelete(&MATELEM(m,i,j));
+  pNormalize(MATELEM(am,1,1));
+  MATELEM(m,i,j)=MATELEM(am,1,1);
+  MATELEM(am,1,1)=NULL;
+  idDelete((ideal *)&am);
+  return FALSE;
+}
+static BOOLEAN jiA_STRING(leftv res, leftv a, Subexpr e)
+{
+  if (e==NULL)
+  {
+    void* tmp = res->data;
+    res->data=(void *)a->CopyD(STRING_CMD);
+    jiAssignAttr(res,a);
+    omfree(tmp);
+  }
+  else
+  {
+    char *s=(char *)res->data;
+    if ((e->start>0)&&(e->start<=(int)strlen(s)))
+      s[e->start-1]=(char)(*((char *)a->Data()));
+    else
+    {
+      Werror("string index %d out of range 1..%d",e->start,(int)strlen(s));
+      return TRUE;
+    }
+  }
+  return FALSE;
+}
+static BOOLEAN jiA_PROC(leftv res, leftv a, Subexpr)
+{
+  extern procinfo *iiInitSingularProcinfo(procinfo *pi, const char *libname,
+                                          const char *procname, int line,
+                                          long pos, BOOLEAN pstatic=FALSE);
+  if(res->data!=NULL) piKill((procinfo *)res->data);
+  if(a->Typ()==STRING_CMD)
+  {
+    res->data = (void *)omAlloc0Bin(procinfo_bin);
+    ((procinfo *)(res->data))->language=LANG_NONE;
+    iiInitSingularProcinfo((procinfo *)res->data,"",res->name,0,0);
+    ((procinfo *)res->data)->data.s.body=(char *)a->CopyD(STRING_CMD);
+  }
+  else
+    res->data=(void *)a->CopyD(PROC_CMD);
+  jiAssignAttr(res,a);
+  return FALSE;
+}
+static BOOLEAN jiA_INTVEC(leftv res, leftv a, Subexpr)
+{
+  //if ((res->data==NULL) || (res->Typ()==a->Typ()))
+  {
+    if (res->data!=NULL) delete ((intvec *)res->data);
+    res->data=(void *)a->CopyD(INTVEC_CMD);
+    jiAssignAttr(res,a);
+    return FALSE;
+  }
+#if 0
+  else
+  {
+    intvec *r=(intvec *)(res->data);
+    intvec *s=(intvec *)(a->Data());
+    int i=si_min(r->length(), s->length())-1;
+    for(;i>=0;i--)
+    {
+      (*r)[i]=(*s)[i];
+    }
+    return FALSE; //(r->length()< s->length());
+  }
+#endif
+}
+static BOOLEAN jiA_BIGINTMAT(leftv res, leftv a, Subexpr)
+{
+  if (res->data!=NULL) delete ((bigintmat *)res->data);
+  res->data=(void *)a->CopyD(BIGINTMAT_CMD);
+  jiAssignAttr(res,a);
+  return FALSE;
+}
+static BOOLEAN jiA_IDEAL(leftv res, leftv a, Subexpr)
+{
+  if (res->data!=NULL) idDelete((ideal*)&res->data);
+  res->data=(void *)a->CopyD(MATRIX_CMD);
+  if (a->rtyp==IDHDL) id_Normalize((ideal)a->Data(), currRing);
+  else                id_Normalize((ideal)res->data, currRing);
+  jiAssignAttr(res,a);
+  if (((res->rtyp==IDEAL_CMD)||(res->rtyp==MODUL_CMD))
+  && (IDELEMS((ideal)(res->data))==1)
+  && (currRing->qideal==NULL)
+  && (!rIsPluralRing(currRing))
+  )
+  {
+    setFlag(res,FLAG_STD);
+  }
+  if (TEST_V_QRING && (currRing->qideal!=NULL)&& (!hasFlag(res,FLAG_QRING))) jjNormalizeQRingId(res);
+  return FALSE;
+}
+static BOOLEAN jiA_RESOLUTION(leftv res, leftv a, Subexpr)
+{
+  if (res->data!=NULL) syKillComputation((syStrategy)res->data);
+  res->data=(void *)a->CopyD(RESOLUTION_CMD);
+  jiAssignAttr(res,a);
+  return FALSE;
+}
+static BOOLEAN jiA_MODUL_P(leftv res, leftv a, Subexpr)
+{
+  if (res->data!=NULL) idDelete((ideal*)&res->data);
+  ideal I=idInit(1,1);
+  I->m[0]=(poly)a->CopyD(POLY_CMD);
+  if (I->m[0]!=NULL) pSetCompP(I->m[0],1);
+  pNormalize(I->m[0]);
+  res->data=(void *)I;
+  if (TEST_V_QRING && (currRing->qideal!=NULL))
+  {
+    if (hasFlag(a,FLAG_QRING)) setFlag(res,FLAG_QRING);
+    else                       jjNormalizeQRingId(res);
+  }
+  return FALSE;
+}
+static BOOLEAN jiA_IDEAL_M(leftv res, leftv a, Subexpr)
+{
+  if (res->data!=NULL) idDelete((ideal*)&res->data);
+  matrix m=(matrix)a->CopyD(MATRIX_CMD);
+  IDELEMS((ideal)m)=MATROWS(m)*MATCOLS(m);
+  ((ideal)m)->rank=1;
+  MATROWS(m)=1;
+  id_Normalize((ideal)m, currRing);
+  res->data=(void *)m;
+  if (TEST_V_QRING && (currRing->qideal!=NULL)) jjNormalizeQRingId(res);
+  return FALSE;
+}
+static BOOLEAN jiA_LINK(leftv res, leftv a, Subexpr)
+{
+  si_link l=(si_link)res->data;
+
+  if (l!=NULL) slCleanUp(l);
+
+  if (a->Typ() == STRING_CMD)
+  {
+    if (l == NULL)
+    {
+      l = (si_link) omAlloc0Bin(sip_link_bin);
+      res->data = (void *) l;
+    }
+    return slInit(l, (char *) a->Data());
+  }
+  else if (a->Typ() == LINK_CMD)
+  {
+    if (l != NULL) omFreeBin(l, sip_link_bin);
+    res->data = slCopy((si_link)a->Data());
+    return FALSE;
+  }
+  return TRUE;
+}
+// assign map -> map
+static BOOLEAN jiA_MAP(leftv res, leftv a, Subexpr)
+{
+  if (res->data!=NULL)
+  {
+    omFree((ADDRESS)((map)res->data)->preimage);
+    ((map)res->data)->preimage=NULL;
+    idDelete((ideal*)&res->data);
+  }
+  res->data=(void *)a->CopyD(MAP_CMD);
+  jiAssignAttr(res,a);
+  return FALSE;
+}
+// assign ideal -> map
+static BOOLEAN jiA_MAP_ID(leftv res, leftv a, Subexpr)
+{
+  map f=(map)res->data;
+  char *rn=f->preimage; // save the old/already assigned preimage ring name
+  f->preimage=NULL;
+  idDelete((ideal *)&f);
+  res->data=(void *)a->CopyD(IDEAL_CMD);
+  f=(map)res->data;
+  id_Normalize((ideal)f, currRing);
+  f->preimage = rn;
+  return FALSE;
+}
+static BOOLEAN jiA_QRING(leftv res, leftv a,Subexpr e)
+{
+  // the follwing can only happen, if:
+  //   - the left side is of type qring AND not an id
+  if ((e!=NULL)||(res->rtyp!=IDHDL))
+  {
+    WerrorS("qring_id expected");
+    return TRUE;
+  }
+  assume(res->Data()==NULL);
+
+  coeffs newcf = currRing->cf;
+#ifdef HAVE_RINGS
+  ideal id = (ideal)a->Data(); //?
+  const int cpos = idPosConstant(id);
+  if(rField_is_Ring(currRing))
+    if (cpos >= 0)
+    {
+        newcf = n_CoeffRingQuot1(p_GetCoeff(id->m[cpos], currRing), currRing->cf);
+        if(newcf == NULL)
+          return TRUE;
+    }
+#endif
+  //qr=(ring)res->Data();
+  //if (qr!=NULL) omFreeBin((ADDRESS)qr, ip_sring_bin);
+  ring qr = rCopy(currRing);
+  assume(qr->cf == currRing->cf);
+
+  if ( qr->cf != newcf )
+  {
+    nKillChar ( qr->cf ); // ???
+    qr->cf = newcf;
+  }
+                 // we have to fill it, but the copy also allocates space
+  idhdl h=(idhdl)res->data; // we have res->rtyp==IDHDL
+  IDRING(h)=qr;
+
+  ideal qid;
+
+#ifdef HAVE_RINGS
+  if((rField_is_Ring(currRing)) && (cpos != -1))
+    {
+      int i, j;
+      int *perm = (int *)omAlloc0((qr->N+1)*sizeof(int));
+
+      for(i=qr->N;i>0;i--)
+        perm[i]=i;
+
+      nMapFunc nMap = n_SetMap(currRing->cf, newcf);
+      qid = idInit(IDELEMS(id)-1,1);
+      for(i = 0, j = 0; i<IDELEMS(id); i++)
+        if( i != cpos )
+          qid->m[j++] = p_PermPoly(id->m[i], perm, currRing, qr, nMap, NULL, 0);
+    }
+    else
+#endif
+      qid = idrCopyR(id,currRing,qr);
+
+  idSkipZeroes(qid);
+  //idPrint(qid);
+  if ((idElem(qid)>1) || rIsSCA(currRing) || (currRing->qideal!=NULL))
+    assumeStdFlag(a);
+
+  if (currRing->qideal!=NULL) /* we are already in a qring! */
+  {
+    ideal tmp=idSimpleAdd(qid,currRing->qideal);
+    // both ideals should be GB, so dSimpleAdd is sufficient
+    idDelete(&qid);
+    qid=tmp;
+    // delete the qr copy of quotient ideal!!!
+    idDelete(&qr->qideal);
+  }
+  if (idElem(qid)==0)
+  {
+    qr->qideal = NULL;
+    id_Delete(&qid,currRing);
+    IDTYP(h)=RING_CMD;
+  }
+  else
+    qr->qideal = qid;
+
+  // qr is a copy of currRing with the new qideal!
+  #ifdef HAVE_PLURAL
+  if(rIsPluralRing(currRing) &&(qr->qideal!=NULL))
+  {
+    if (!hasFlag(a,FLAG_TWOSTD))
+    {
+      Warn("%s is no twosided standard basis",a->Name());
+    }
+
+    if( nc_SetupQuotient(qr, currRing) )
+    {
+//      WarnS("error in nc_SetupQuotient");
+    }
+  }
+  #endif
+  //rWrite(qr);
+  rSetHdl((idhdl)res->data);
+  return FALSE;
+}
+
+static BOOLEAN jiA_RING(leftv res, leftv a, Subexpr e)
+{
+  BOOLEAN have_id=TRUE;
+  if ((e!=NULL)||(res->rtyp!=IDHDL))
+  {
+    //WerrorS("id expected");
+    //return TRUE;
+    have_id=FALSE;
+  }
+  ring r=(ring)a->Data();
+  if (have_id)
+  {
+    idhdl rl=(idhdl)res->data;
+    if (IDRING(rl)!=NULL) rKill(rl);
+    IDRING(rl)=r;
+    if ((IDLEV((idhdl)a->data)!=myynest) && (r==currRing))
+      currRingHdl=(idhdl)res->data;
+  }
+  else
+  {
+    if (e==NULL) res->data=(char *)r;
+    else
+    {
+      WerrorS("id expected");
+      return TRUE;
+    }
+  }
+  r->ref++;
+  jiAssignAttr(res,a);
+  return FALSE;
+}
+static BOOLEAN jiA_PACKAGE(leftv res, leftv a, Subexpr)
+{
+  res->data=(void *)a->CopyD(PACKAGE_CMD);
+  jiAssignAttr(res,a);
+  return FALSE;
+}
+static BOOLEAN jiA_DEF(leftv res, leftv a, Subexpr e)
+{
+  res->data=(void *)0;
+  return FALSE;
+}
+#ifdef SINGULAR_4_1
+static BOOLEAN jiA_CRING(leftv res, leftv a, Subexpr e)
+{
+  res->data=(void *)a->CopyD(CRING_CMD);
+  jiAssignAttr(res,a);
+  return FALSE;
+}
+#endif
+
+/*=================== table =================*/
+#define IPASSIGN
+#define D(A)     A
+#define NULL_VAL NULL
+#include "table.h"
+/*=================== operations ============================*/
+/*2
+* assign a = b
+*/
+static BOOLEAN jiAssign_1(leftv l, leftv r)
+{
+  int rt=r->Typ();
+  if (rt==0)
+  {
+    if (!errorreported) Werror("`%s` is undefined",r->Fullname());
+    return TRUE;
+  }
+
+  int lt=l->Typ();
+  if (/*(*/ lt==0 /*)*/) /*&&(l->name!=NULL)*/
+  {
+    if (!errorreported) Werror("left side `%s` is undefined",l->Fullname());
+    return TRUE;
+  }
+  if(rt==NONE)
+  {
+    WarnS("right side is not a datum, assignment ignored");
+    // if (!errorreported)
+    //   WerrorS("right side is not a datum");
+    //return TRUE;
+    return FALSE;
+  }
+
+  int i=0;
+  if (lt==DEF_CMD)
+  {
+    if (TEST_V_ALLWARN
+    && (rt!=RING_CMD)
+    && (rt!=QRING_CMD)
+    && (l->name!=NULL)
+    && (l->e==NULL)
+    && (iiCurrArgs==NULL) /* not in proc header */
+    )
+    {
+      Warn("use `%s` instead of `def`",Tok2Cmdname(rt));
+    }
+    if (l->rtyp==IDHDL)
+    {
+      IDTYP((idhdl)l->data)=rt;
+    }
+    else if (l->name!=NULL)
+    {
+      sleftv ll;
+      iiDeclCommand(&ll,l,myynest,rt,&IDROOT);
+      memcpy(l,&ll,sizeof(sleftv));
+    }
+    else
+    {
+      l->rtyp=rt;
+    }
+    lt=rt;
+  }
+  else
+  {
+    if ((l->data==r->data)&&(l->e==NULL)&&(r->e==NULL))
+      return FALSE;
+  }
+  leftv ld=l;
+  if ((l->rtyp==IDHDL)&&(lt!=QRING_CMD)&&(lt!=RING_CMD))
+    ld=(leftv)l->data;
+  if (lt>MAX_TOK)
+  {
+    blackbox *bb=getBlackboxStuff(lt);
+#ifdef BLACKBOX_DEVEL
+    Print("bb-assign: bb=%lx\n",bb);
+#endif
+    return (bb==NULL) || bb->blackbox_Assign(l,r);
+  }
+  while (((dAssign[i].res!=lt)
+      || (dAssign[i].arg!=rt))
+    && (dAssign[i].res!=0)) i++;
+  if (dAssign[i].res!=0)
+  {
+    if (traceit&TRACE_ASSIGN) Print("assign %s=%s\n",Tok2Cmdname(lt),Tok2Cmdname(rt));
+    BOOLEAN b;
+    b=dAssign[i].p(ld,r,l->e);
+    if(l!=ld) /* i.e. l is IDHDL, l->data is ld */
+    {
+      l->flag=ld->flag;
+      l->attribute=ld->attribute;
+    }
+    return b;
+  }
+  // implicite type conversion ----------------------------------------------
+  if (dAssign[i].res==0)
+  {
+    int ri;
+    leftv rn = (leftv)omAlloc0Bin(sleftv_bin);
+    BOOLEAN failed=FALSE;
+    i=0;
+    while ((dAssign[i].res!=lt)
+      && (dAssign[i].res!=0)) i++;
+    while (dAssign[i].res==lt)
+    {
+      if ((ri=iiTestConvert(rt,dAssign[i].arg))!=0)
+      {
+        failed= iiConvert(rt,dAssign[i].arg,ri,r,rn);
+        if(!failed)
+        {
+          failed= dAssign[i].p(ld,rn,l->e);
+          if (traceit&TRACE_ASSIGN)
+            Print("assign %s=%s ok? %d\n",Tok2Cmdname(lt),Tok2Cmdname(rn->rtyp),!failed);
+        }
+        // everything done, clean up temp. variables
+        rn->CleanUp();
+        omFreeBin((ADDRESS)rn, sleftv_bin);
+        if (failed)
+        {
+          // leave loop, goto error handling
+          break;
+        }
+        else
+        {
+          if(l!=ld) /* i.e. l is IDHDL, l->data is ld */
+          {
+            l->flag=ld->flag;
+            l->attribute=ld->attribute;
+          }
+          // everything ok, return
+          return FALSE;
+        }
+     }
+     i++;
+    }
+    // error handling ---------------------------------------------------
+    if (!errorreported)
+    {
+      if ((l->rtyp==IDHDL) && (l->e==NULL))
+        Werror("`%s`(%s) = `%s` is not supported",
+          Tok2Cmdname(lt),l->Name(),Tok2Cmdname(rt));
+      else
+         Werror("`%s` = `%s` is not supported"
+             ,Tok2Cmdname(lt),Tok2Cmdname(rt));
+      if (BVERBOSE(V_SHOW_USE))
+      {
+        i=0;
+        while ((dAssign[i].res!=lt)
+          && (dAssign[i].res!=0)) i++;
+        while (dAssign[i].res==lt)
+        {
+          Werror("expected `%s` = `%s`"
+              ,Tok2Cmdname(lt),Tok2Cmdname(dAssign[i].arg));
+          i++;
+        }
+      }
+    }
+  }
+  return TRUE;
+}
+/*2
+* assign sys_var = val
+*/
+static BOOLEAN iiAssign_sys(leftv l, leftv r)
+{
+  int rt=r->Typ();
+
+  if (rt==0)
+  {
+    if (!errorreported) Werror("`%s` is undefined",r->Fullname());
+    return TRUE;
+  }
+  int i=0;
+  int lt=l->rtyp;
+  while (((dAssign_sys[i].res!=lt)
+      || (dAssign_sys[i].arg!=rt))
+    && (dAssign_sys[i].res!=0)) i++;
+  if (dAssign_sys[i].res!=0)
+  {
+    if (!dAssign_sys[i].p(l,r))
+    {
+      // everything ok, clean up
+      return FALSE;
+    }
+  }
+  // implicite type conversion ----------------------------------------------
+  if (dAssign_sys[i].res==0)
+  {
+    int ri;
+    leftv rn = (leftv)omAlloc0Bin(sleftv_bin);
+    BOOLEAN failed=FALSE;
+    i=0;
+    while ((dAssign_sys[i].res!=lt)
+      && (dAssign_sys[i].res!=0)) i++;
+    while (dAssign_sys[i].res==lt)
+    {
+      if ((ri=iiTestConvert(rt,dAssign_sys[i].arg))!=0)
+      {
+        failed= ((iiConvert(rt,dAssign_sys[i].arg,ri,r,rn))
+            || (dAssign_sys[i].p(l,rn)));
+        // everything done, clean up temp. variables
+        rn->CleanUp();
+        omFreeBin((ADDRESS)rn, sleftv_bin);
+        if (failed)
+        {
+          // leave loop, goto error handling
+          break;
+        }
+        else
+        {
+          // everything ok, return
+          return FALSE;
+        }
+     }
+     i++;
+    }
+    // error handling ---------------------------------------------------
+    if(!errorreported)
+    {
+      Werror("`%s` = `%s` is not supported"
+             ,Tok2Cmdname(lt),Tok2Cmdname(rt));
+      if (BVERBOSE(V_SHOW_USE))
+      {
+        i=0;
+        while ((dAssign_sys[i].res!=lt)
+          && (dAssign_sys[i].res!=0)) i++;
+        while (dAssign_sys[i].res==lt)
+        {
+          Werror("expected `%s` = `%s`"
+              ,Tok2Cmdname(lt),Tok2Cmdname(dAssign_sys[i].arg));
+          i++;
+        }
+      }
+    }
+  }
+  return TRUE;
+}
+static BOOLEAN jiA_INTVEC_L(leftv l,leftv r)
+{
+  /* right side is intvec, left side is list (of int)*/
+  BOOLEAN nok;
+  int i=0;
+  leftv l1=l;
+  leftv h;
+  sleftv t;
+  intvec *iv=(intvec *)r->Data();
+  memset(&t,0,sizeof(sleftv));
+  t.rtyp=INT_CMD;
+  while ((i<iv->length())&&(l!=NULL))
+  {
+    t.data=(char *)(long)(*iv)[i];
+    h=l->next;
+    l->next=NULL;
+    nok=jiAssign_1(l,&t);
+    l->next=h;
+    if (nok) return TRUE;
+    i++;
+    l=h;
+  }
+  l1->CleanUp();
+  r->CleanUp();
+  return FALSE;
+}
+static BOOLEAN jiA_VECTOR_L(leftv l,leftv r)
+{
+  /* right side is vector, left side is list (of poly)*/
+  BOOLEAN nok;
+  leftv l1=l;
+  ideal I=idVec2Ideal((poly)r->Data());
+  leftv h;
+  sleftv t;
+  int i=0;
+  while (l!=NULL)
+  {
+    memset(&t,0,sizeof(sleftv));
+    t.rtyp=POLY_CMD;
+    if (i>=IDELEMS(I))
+    {
+      t.data=NULL;
+    }
+    else
+    {
+      t.data=(char *)I->m[i];
+      I->m[i]=NULL;
+    }
+    h=l->next;
+    l->next=NULL;
+    nok=jiAssign_1(l,&t);
+    l->next=h;
+    t.CleanUp();
+    if (nok)
+    {
+      idDelete(&I);
+      return TRUE;
+    }
+    i++;
+    l=h;
+  }
+  idDelete(&I);
+  l1->CleanUp();
+  r->CleanUp();
+  //if (TEST_V_QRING && (currRing->qideal!=NULL)) jjNormalizeQRingP(l);
+  return FALSE;
+}
+static BOOLEAN jjA_L_LIST(leftv l, leftv r)
+/* left side: list/def, has to be a "real" variable
+*  right side: expression list
+*/
+{
+  int sl = r->listLength();
+  lists L=(lists)omAllocBin(slists_bin);
+  lists oldL;
+  leftv h=NULL,o_r=r;
+  int i;
+  int rt;
+
+  L->Init(sl);
+  for (i=0;i<sl;i++)
+  {
+    if (h!=NULL) { /* e.g. not in the first step:
+                   * h is the pointer to the old sleftv,
+                   * r is the pointer to the next sleftv
+                   * (in this moment) */
+                   h->next=r;
+                 }
+    h=r;
+    r=r->next;
+    h->next=NULL;
+    rt=h->Typ();
+    if ((rt==0)||(rt==NONE)||(rt==DEF_CMD))
+    {
+      L->Clean();
+      Werror("`%s` is undefined",h->Fullname());
+      //listall();
+      goto err;
+    }
+    //if ((rt==RING_CMD)||(rt==QRING_CMD))
+    //{
+    //  L->m[i].rtyp=rt;
+    //  L->m[i].data=h->Data();
+    //  ((ring)L->m[i].data)->ref++;
+    //}
+    //else
+      L->m[i].CleanUp();
+      L->m[i].Copy(h);
+      if(errorreported)
+      {
+        L->Clean();
+        goto err;
+      }
+  }
+  oldL=(lists)l->Data();
+  if (oldL!=NULL) oldL->Clean();
+  if (l->rtyp==IDHDL)
+  {
+    IDLIST((idhdl)l->data)=L;
+    IDTYP((idhdl)l->data)=LIST_CMD; // was possibly DEF_CMD
+    if (lRingDependend(L)) ipMoveId((idhdl)l->data);
+  }
+  else
+  {
+    l->LData()->data=L;
+    if ((l->e!=NULL) && (l->rtyp==DEF_CMD))
+      l->rtyp=LIST_CMD;
+  }
+err:
+  o_r->CleanUp();
+  return errorreported;
+}
+static BOOLEAN jjA_L_INTVEC(leftv l,leftv r,intvec *iv)
+{
+  /* left side is intvec/intmat, right side is list (of int,intvec,intmat)*/
+  leftv hh=r;
+  int i = 0;
+  while (hh!=NULL)
+  {
+    if (i>=iv->length())
+    {
+      if (traceit&TRACE_ASSIGN)
+      {
+        Warn("expression list length(%d) does not match intmat size(%d)",
+             iv->length()+exprlist_length(hh),iv->length());
+      }
+      break;
+    }
+    if (hh->Typ() == INT_CMD)
+    {
+      (*iv)[i++] = (int)((long)(hh->Data()));
+    }
+    else if ((hh->Typ() == INTVEC_CMD)
+            ||(hh->Typ() == INTMAT_CMD))
+    {
+      intvec *ivv = (intvec *)(hh->Data());
+      int ll = 0,l = si_min(ivv->length(),iv->length());
+      for (; l>0; l--)
+      {
+        (*iv)[i++] = (*ivv)[ll++];
+      }
+    }
+    else
+    {
+      delete iv;
+      return TRUE;
+    }
+    hh = hh->next;
+  }
+  if (l->rtyp==IDHDL)
+  {
+    if (IDINTVEC((idhdl)l->data)!=NULL) delete IDINTVEC((idhdl)l->data);
+    IDINTVEC((idhdl)l->data)=iv;
+  }
+  else
+  {
+    if (l->data!=NULL) delete ((intvec*)l->data);
+    l->data=(char*)iv;
+  }
+  return FALSE;
+}
+static BOOLEAN jjA_L_BIGINTMAT(leftv l,leftv r,bigintmat *bim)
+{
+  /* left side is bigintmat, right side is list (of int,intvec,intmat)*/
+  leftv hh=r;
+  int i = 0;
+  if (bim->length()==0) { WerrorS("bigintmat is 1x0"); delete bim; return TRUE; }
+  while (hh!=NULL)
+  {
+    if (i>=bim->cols()*bim->rows())
+    {
+      if (traceit&TRACE_ASSIGN)
+      {
+        Warn("expression list length(%d) does not match bigintmat size(%d x %d)",
+              exprlist_length(hh),bim->rows(),bim->cols());
+      }
+      break;
+    }
+    if (hh->Typ() == INT_CMD)
+    {
+      number tp = n_Init((int)((long)(hh->Data())), coeffs_BIGINT);
+      bim->set(i++, tp);
+      n_Delete(&tp, coeffs_BIGINT);
+    }
+    else if (hh->Typ() == BIGINT_CMD)
+    {
+      bim->set(i++, (number)(hh->Data()));
+    }
+    /*
+    ((hh->Typ() == INTVEC_CMD)
+            ||(hh->Typ() == INTMAT_CMD))
+    {
+      intvec *ivv = (intvec *)(hh->Data());
+      int ll = 0,l = si_min(ivv->length(),iv->length());
+      for (; l>0; l--)
+      {
+        (*iv)[i++] = (*ivv)[ll++];
+      }
+    }*/
+    else
+    {
+      delete bim;
+      return TRUE;
+    }
+    hh = hh->next;
+  }
+  if (IDBIMAT((idhdl)l->data)!=NULL) delete IDBIMAT((idhdl)l->data);
+  IDBIMAT((idhdl)l->data)=bim;
+  return FALSE;
+}
+static BOOLEAN jjA_L_STRING(leftv l,leftv r)
+{
+  /* left side is string, right side is list of string*/
+  leftv hh=r;
+  int sl = 1;
+  char *s;
+  char *t;
+  int tl;
+  /* find the length */
+  while (hh!=NULL)
+  {
+    if (hh->Typ()!= STRING_CMD)
+    {
+      return TRUE;
+    }
+    sl += strlen((char *)hh->Data());
+    hh = hh->next;
+  }
+  s = (char * )omAlloc(sl);
+  sl=0;
+  hh = r;
+  while (hh!=NULL)
+  {
+    t=(char *)hh->Data();
+    tl=strlen(t);
+    memcpy(s+sl,t,tl);
+    sl+=tl;
+    hh = hh->next;
+  }
+  s[sl]='\0';
+  omFree((ADDRESS)IDDATA((idhdl)(l->data)));
+  IDDATA((idhdl)(l->data))=s;
+  return FALSE;
+}
+static BOOLEAN jiA_MATRIX_L(leftv l,leftv r)
+{
+  /* right side is matrix, left side is list (of poly)*/
+  BOOLEAN nok=FALSE;
+  int i;
+  matrix m=(matrix)r->CopyD(MATRIX_CMD);
+  leftv h;
+  leftv ol=l;
+  leftv o_r=r;
+  sleftv t;
+  memset(&t,0,sizeof(sleftv));
+  t.rtyp=POLY_CMD;
+  int mxn=MATROWS(m)*MATCOLS(m);
+  loop
+  {
+    i=0;
+    while ((i<mxn /*MATROWS(m)*MATCOLS(m)*/)&&(l!=NULL))
+    {
+      t.data=(char *)m->m[i];
+      m->m[i]=NULL;
+      h=l->next;
+      l->next=NULL;
+      idhdl hh=NULL;
+      if ((l->rtyp==IDHDL)&&(l->Typ()==DEF_CMD)) hh=(idhdl)l->data;
+      nok=jiAssign_1(l,&t);
+      if (hh!=NULL) { ipMoveId(hh);hh=NULL;}
+      l->next=h;
+      if (nok)
+      {
+        idDelete((ideal *)&m);
+        goto ende;
+      }
+      i++;
+      l=h;
+    }
+    idDelete((ideal *)&m);
+    h=r;
+    r=r->next;
+    if (l==NULL)
+    {
+      if (r!=NULL)
+      {
+        Warn("list length mismatch in assign (l>r)");
+        nok=TRUE;
+      }
+      break;
+    }
+    else if (r==NULL)
+    {
+      Warn("list length mismatch in assign (l<r)");
+      nok=TRUE;
+      break;
+    }
+    if ((r->Typ()==IDEAL_CMD)||(r->Typ()==MATRIX_CMD))
+    {
+      m=(matrix)r->CopyD(MATRIX_CMD);
+      mxn=MATROWS(m)*MATCOLS(m);
+    }
+    else if (r->Typ()==POLY_CMD)
+    {
+      m=mpNew(1,1);
+      MATELEM(m,1,1)=(poly)r->CopyD(POLY_CMD);
+      pNormalize(MATELEM(m,1,1));
+      mxn=1;
+    }
+    else
+    {
+      nok=TRUE;
+      break;
+    }
+  }
+ende:
+  o_r->CleanUp();
+  ol->CleanUp();
+  return nok;
+}
+static BOOLEAN jiA_STRING_L(leftv l,leftv r)
+{
+  /*left side are strings, right side is a string*/
+  /*e.g. s[2..3]="12" */
+  /*the case s=t[1..4] is handled in iiAssign,
+  * the case s[2..3]=t[3..4] is handled in iiAssgn_rec*/
+  BOOLEAN nok=FALSE;
+  sleftv t;
+  leftv h,l1=l;
+  int i=0;
+  char *ss;
+  char *s=(char *)r->Data();
+  int sl=strlen(s);
+
+  memset(&t,0,sizeof(sleftv));
+  t.rtyp=STRING_CMD;
+  while ((i<sl)&&(l!=NULL))
+  {
+    ss=(char *)omAlloc(2);
+    ss[1]='\0';
+    ss[0]=s[i];
+    t.data=ss;
+    h=l->next;
+    l->next=NULL;
+    nok=jiAssign_1(l,&t);
+    if (nok)
+    {
+      break;
+    }
+    i++;
+    l=h;
+  }
+  r->CleanUp();
+  l1->CleanUp();
+  return nok;
+}
+static BOOLEAN jiAssign_list(leftv l, leftv r)
+{
+  int i=l->e->start-1;
+  if (i<0)
+  {
+    Werror("index[%d] must be positive",i+1);
+    return TRUE;
+  }
+  if(l->attribute!=NULL)
+  {
+    atKillAll((idhdl)l);
+    l->attribute=NULL;
+  }
+  l->flag=0;
+  lists li;
+  if (l->rtyp==IDHDL)
+  {
+    li=IDLIST((idhdl)l->data);
+  }
+  else
+  {
+    li=(lists)l->data;
+  }
+  if (i>li->nr)
+  {
+    if (TEST_V_ALLWARN)
+    {
+      Warn("increase list %d -> %d in %s",li->nr,i,my_yylinebuf);
+    }
+    li->m=(leftv)omreallocSize(li->m,(li->nr+1)*sizeof(sleftv),(i+1)*sizeof(sleftv));
+    memset(&(li->m[li->nr+1]),0,(i-li->nr)*sizeof(sleftv));
+    int j=li->nr+1;
+    for(;j<=i;j++)
+      li->m[j].rtyp=DEF_CMD;
+    li->nr=i;
+  }
+  leftv ld=&(li->m[i]);
+  ld->e=l->e->next;
+  BOOLEAN b;
+  if (/*(ld->rtyp!=LIST_CMD)
+  &&*/(ld->e==NULL)
+  && (ld->Typ()!=r->Typ()))
+  {
+    sleftv tmp;
+    memset(&tmp,0,sizeof(sleftv));
+    tmp.rtyp=DEF_CMD;
+    b=iiAssign(&tmp,r);
+    ld->CleanUp();
+    memcpy(ld,&tmp,sizeof(sleftv));
+  }
+  else if ((ld->e==NULL)
+  && (ld->Typ()==r->Typ())
+  && (ld->Typ()<MAX_TOK))
+  {
+    sleftv tmp;
+    memset(&tmp,0,sizeof(sleftv));
+    tmp.rtyp=r->Typ();
+    tmp.data=(char*)idrecDataInit(r->Typ());
+    b=iiAssign(&tmp,r);
+    ld->CleanUp();
+    memcpy(ld,&tmp,sizeof(sleftv));
+  }
+  else
+  {
+    b=iiAssign(ld,r);
+    if (l->e!=NULL) l->e->next=ld->e;
+    ld->e=NULL;
+  }
+  return b;
+}
+static BOOLEAN jiAssign_rec(leftv l, leftv r)
+{
+  leftv l1=l;
+  leftv r1=r;
+  leftv lrest;
+  leftv rrest;
+  BOOLEAN b;
+  do
+  {
+    lrest=l->next;
+    rrest=r->next;
+    l->next=NULL;
+    r->next=NULL;
+    b=iiAssign(l,r);
+    l->next=lrest;
+    r->next=rrest;
+    l=lrest;
+    r=rrest;
+  } while  ((!b)&&(l!=NULL));
+  l1->CleanUp();
+  r1->CleanUp();
+  return b;
+}
+BOOLEAN iiAssign(leftv l, leftv r)
+{
+  if (errorreported) return TRUE;
+  int ll=l->listLength();
+  int rl;
+  int lt=l->Typ();
+  int rt=NONE;
+  BOOLEAN b;
+  if (l->rtyp==ALIAS_CMD)
+  {
+    Werror("`%s` is read-only",l->Name());
+  }
+
+  if (l->rtyp==IDHDL)
+  {
+    atKillAll((idhdl)l->data);
+    IDFLAG((idhdl)l->data)=0;
+    l->attribute=NULL;
+  }
+  else if (l->attribute!=NULL)
+    atKillAll((idhdl)l);
+  l->flag=0;
+  if (ll==1)
+  {
+    /* l[..] = ... */
+    if(l->e!=NULL)
+    {
+      BOOLEAN like_lists=0;
+      blackbox *bb=NULL;
+      int bt;
+      if (((bt=l->rtyp)>MAX_TOK)
+      || ((l->rtyp==IDHDL) && ((bt=IDTYP((idhdl)l->data))>MAX_TOK)))
+      {
+        bb=getBlackboxStuff(bt);
+        like_lists=BB_LIKE_LIST(bb); // bb like a list
+      }
+      else if (((l->rtyp==IDHDL) && (IDTYP((idhdl)l->data)==LIST_CMD))
+        || (l->rtyp==LIST_CMD))
+      {
+        like_lists=2; // bb in a list
+      }
+      if(like_lists)
+      {
+        if (traceit&TRACE_ASSIGN) PrintS("assign list[..]=...or similiar\n");
+        if (like_lists==1)
+        {
+          // check blackbox/newtype type:
+          if(bb->blackbox_CheckAssign(bb,l,r)) return TRUE;
+        }
+        b=jiAssign_list(l,r);
+        if((!b) && (like_lists==2))
+        {
+          //Print("jjA_L_LIST: - 2 \n");
+          if((l->rtyp==IDHDL) && (l->data!=NULL))
+          {
+            ipMoveId((idhdl)l->data);
+            l->attribute=IDATTR((idhdl)l->data);
+            l->flag=IDFLAG((idhdl)l->data);
+          }
+        }
+        r->CleanUp();
+        Subexpr h;
+        while (l->e!=NULL)
+        {
+          h=l->e->next;
+          omFreeBin((ADDRESS)l->e, sSubexpr_bin);
+          l->e=h;
+        }
+        return b;
+      }
+    }
+    if (lt>MAX_TOK)
+    {
+      blackbox *bb=getBlackboxStuff(lt);
+#ifdef BLACKBOX_DEVEL
+      Print("bb-assign: bb=%lx\n",bb);
+#endif
+      return (bb==NULL) || bb->blackbox_Assign(l,r);
+    }
+    // end of handling elems of list and similiar
+    rl=r->listLength();
+    if (rl==1)
+    {
+      /* system variables = ... */
+      if(((l->rtyp>=VECHO)&&(l->rtyp<=VPRINTLEVEL))
+      ||((l->rtyp>=VALTVARS)&&(l->rtyp<=VMINPOLY)))
+      {
+        b=iiAssign_sys(l,r);
+        r->CleanUp();
+        //l->CleanUp();
+        return b;
+      }
+      rt=r->Typ();
+      /* a = ... */
+      if ((lt!=MATRIX_CMD)
+      &&(lt!=BIGINTMAT_CMD)
+      &&(lt!=CMATRIX_CMD)
+      &&(lt!=INTMAT_CMD)
+      &&((lt==rt)||(lt!=LIST_CMD)))
+      {
+        b=jiAssign_1(l,r);
+        if (l->rtyp==IDHDL)
+        {
+          if ((lt==DEF_CMD)||(lt==LIST_CMD))
+          {
+            ipMoveId((idhdl)l->data);
+          }
+          l->attribute=IDATTR((idhdl)l->data);
+          l->flag=IDFLAG((idhdl)l->data);
+          l->CleanUp();
+        }
+        r->CleanUp();
+        return b;
+      }
+      if (((lt!=LIST_CMD)
+        &&((rt==MATRIX_CMD)
+          ||(rt==BIGINTMAT_CMD)
+          ||(rt==CMATRIX_CMD)
+          ||(rt==INTMAT_CMD)
+          ||(rt==INTVEC_CMD)
+          ||(rt==MODUL_CMD)))
+      ||((lt==LIST_CMD)
+        &&(rt==RESOLUTION_CMD))
+      )
+      {
+        b=jiAssign_1(l,r);
+        if((l->rtyp==IDHDL)&&(l->data!=NULL))
+        {
+          if ((lt==DEF_CMD) || (lt==LIST_CMD))
+          {
+            //Print("ipAssign - 3.0\n");
+            ipMoveId((idhdl)l->data);
+          }
+          l->attribute=IDATTR((idhdl)l->data);
+          l->flag=IDFLAG((idhdl)l->data);
+        }
+        r->CleanUp();
+        Subexpr h;
+        while (l->e!=NULL)
+        {
+          h=l->e->next;
+          omFreeBin((ADDRESS)l->e, sSubexpr_bin);
+          l->e=h;
+        }
+        return b;
+      }
+    }
+    if (rt==NONE) rt=r->Typ();
+  }
+  else if (ll==(rl=r->listLength()))
+  {
+    b=jiAssign_rec(l,r);
+    return b;
+  }
+  else
+  {
+    if (rt==NONE) rt=r->Typ();
+    if (rt==INTVEC_CMD)
+      return jiA_INTVEC_L(l,r);
+    else if (rt==VECTOR_CMD)
+      return jiA_VECTOR_L(l,r);
+    else if ((rt==IDEAL_CMD)||(rt==MATRIX_CMD))
+      return jiA_MATRIX_L(l,r);
+    else if ((rt==STRING_CMD)&&(rl==1))
+      return jiA_STRING_L(l,r);
+    Werror("length of lists in assignment does not match (l:%d,r:%d)",
+      ll,rl);
+    return TRUE;
+  }
+
+  leftv hh=r;
+  BOOLEAN nok=FALSE;
+  BOOLEAN map_assign=FALSE;
+  switch (lt)
+  {
+    case INTVEC_CMD:
+      nok=jjA_L_INTVEC(l,r,new intvec(exprlist_length(r)));
+      break;
+    case INTMAT_CMD:
+    {
+      nok=jjA_L_INTVEC(l,r,new intvec(IDINTVEC((idhdl)l->data)));
+      break;
+    }
+    case BIGINTMAT_CMD:
+    {
+      nok=jjA_L_BIGINTMAT(l, r, new bigintmat(IDBIMAT((idhdl)l->data)));
+      break;
+    }
+    case MAP_CMD:
+    {
+      // first element in the list sl (r) must be a ring
+      if (((rt == RING_CMD)||(rt == QRING_CMD))&&(r->e==NULL))
+      {
+        omFree((ADDRESS)IDMAP((idhdl)l->data)->preimage);
+        IDMAP((idhdl)l->data)->preimage = omStrDup (r->Fullname());
+        /* advance the expressionlist to get the next element after the ring */
+        hh = r->next;
+        //r=hh;
+      }
+      else
+      {
+        WerrorS("expected ring-name");
+        nok=TRUE;
+        break;
+      }
+      if (hh==NULL) /* map-assign: map f=r; */
+      {
+        WerrorS("expected image ideal");
+        nok=TRUE;
+        break;
+      }
+      if ((hh->next==NULL)&&(hh->Typ()==IDEAL_CMD))
+        return jiAssign_1(l,hh); /* map-assign: map f=r,i; */
+      //no break, handle the rest like an ideal:
+      map_assign=TRUE;
+    }
+    case MATRIX_CMD:
+    case IDEAL_CMD:
+    case MODUL_CMD:
+    {
+      sleftv t;
+      matrix olm = (matrix)l->Data();
+      int rk=olm->rank;
+      char *pr=((map)olm)->preimage;
+      BOOLEAN module_assign=(/*l->Typ()*/ lt==MODUL_CMD);
+      matrix lm ;
+      int  num;
+      int j,k;
+      int i=0;
+      int mtyp=MATRIX_CMD; /*Type of left side object*/
+      int etyp=POLY_CMD;   /*Type of elements of left side object*/
+
+      if (lt /*l->Typ()*/==MATRIX_CMD)
+      {
+        num=olm->cols()*olm->rows();
+        lm=mpNew(olm->rows(),olm->cols());
+        int el;
+        if ((traceit&TRACE_ASSIGN) && (num!=(el=exprlist_length(hh))))
+        {
+          Warn("expression list length(%d) does not match matrix size(%d)",el,num);
+        }
+      }
+      else /* IDEAL_CMD or MODUL_CMD */
+      {
+        num=exprlist_length(hh);
+        lm=(matrix)idInit(num,1);
+        rk=1;
+        if (module_assign)
+        {
+          mtyp=MODUL_CMD;
+          etyp=VECTOR_CMD;
+        }
+      }
+
+      int ht;
+      loop
+      {
+        if (hh==NULL)
+          break;
+        else
+        {
+          matrix rm;
+          ht=hh->Typ();
+          if ((j=iiTestConvert(ht,etyp))!=0)
+          {
+            nok=iiConvert(ht,etyp,j,hh,&t);
+            hh->next=t.next;
+            if (nok) break;
+            lm->m[i]=(poly)t.CopyD(etyp);
+            pNormalize(lm->m[i]);
+            if (module_assign) rk=si_max(rk,(int)pMaxComp(lm->m[i]));
+            i++;
+          }
+          else
+          if ((j=iiTestConvert(ht,mtyp))!=0)
+          {
+            nok=iiConvert(ht,mtyp,j,hh,&t);
+            hh->next=t.next;
+            if (nok) break;
+            rm = (matrix)t.CopyD(mtyp);
+            if (module_assign)
+            {
+              j = si_min(num,rm->cols());
+              rk=si_max(rk,(int)rm->rank);
+            }
+            else
+              j = si_min(num-i,rm->rows() * rm->cols());
+            for(k=0;k<j;k++,i++)
+            {
+              lm->m[i]=rm->m[k];
+              pNormalize(lm->m[i]);
+              rm->m[k]=NULL;
+            }
+            idDelete((ideal *)&rm);
+          }
+          else
+          {
+            nok=TRUE;
+            break;
+          }
+          t.next=NULL;t.CleanUp();
+          if (i==num) break;
+          hh=hh->next;
+        }
+      }
+      if (nok)
+        idDelete((ideal *)&lm);
+      else
+      {
+        idDelete((ideal *)&olm);
+        if (module_assign)   lm->rank=rk;
+        else if (map_assign) ((map)lm)->preimage=pr;
+        l=l->LData();
+        if (l->rtyp==IDHDL)
+          IDMATRIX((idhdl)l->data)=lm;
+        else
+          l->data=(char *)lm;
+      }
+      break;
+    }
+    case STRING_CMD:
+      nok=jjA_L_STRING(l,r);
+      break;
+    //case DEF_CMD:
+    case LIST_CMD:
+      nok=jjA_L_LIST(l,r);
+      break;
+    case NONE:
+    case 0:
+      Werror("cannot assign to %s",l->Fullname());
+      nok=TRUE;
+      break;
+    default:
+      WerrorS("assign not impl.");
+      nok=TRUE;
+      break;
+  } /* end switch: typ */
+  if (nok && (!errorreported)) WerrorS("incompatible type in list assignment");
+  r->CleanUp();
+  return nok;
+}
+void jjNormalizeQRingId(leftv I)
+{
+  if ((currRing->qideal!=NULL) && (!hasFlag(I,FLAG_QRING)))
+  {
+    if (I->e==NULL)
+    {
+      ideal I0=(ideal)I->Data();
+      switch (I->Typ())
+      {
+        case IDEAL_CMD:
+        case MODUL_CMD:
+        {
+          ideal F=idInit(1,1);
+          ideal II=kNF(F,currRing->qideal,I0);
+          idDelete(&F);
+          if (I->rtyp!=IDHDL)
+          {
+            idDelete((ideal*)&(I0));
+            I->data=II;
+          }
+          else
+          {
+            idhdl h=(idhdl)I->data;
+            idDelete((ideal*)&IDIDEAL(h));
+            IDIDEAL(h)=II;
+            setFlag(h,FLAG_QRING);
+          }
+          break;
+        }
+        default: break;
+      }
+      setFlag(I,FLAG_QRING);
+    }
+  }
+}
+void jjNormalizeQRingP(leftv I)
+{
+  if ((currRing->qideal!=NULL) && (!hasFlag(I,FLAG_QRING)))
+  {
+    poly p=(poly)I->Data();
+    if ((I->e==NULL) && (p!=NULL))
+    {
+      ideal F=idInit(1,1);
+      poly II=kNF(F,currRing->qideal,p);
+      idDelete(&F);
+      if ((I->rtyp==POLY_CMD)
+      || (I->rtyp==VECTOR_CMD))
+      {
+        pDelete(&p);
+        I->data=II;
+      }
+      else if (I->rtyp==IDHDL)
+      {
+        pDelete(&p);
+        idhdl h=(idhdl)I->data;
+        IDPOLY(h)=II;
+        setFlag(h,FLAG_QRING);
+      }
+      else
+      {
+        pDelete(&II);
+      }
+    }
+    setFlag(I,FLAG_QRING);
+  }
+}
+BOOLEAN jjIMPORTFROM(leftv, leftv u, leftv v)
+{
+  //Print("importfrom %s::%s ->.\n",v->Name(),u->Name() );
+  assume(u->Typ()==PACKAGE_CMD);
+  char *vn=(char *)v->Name();
+  idhdl h=((package)(u->Data()))->idroot->get(vn /*v->Name()*/, myynest);
+  if (h!=NULL)
+  {
+    //check for existence
+    if (((package)(u->Data()))==basePack)
+    {
+      WarnS("source and destination packages are identical");
+      return FALSE;
+    }
+    idhdl t=basePack->idroot->get(vn /*v->Name()*/, myynest);
+    if (t!=NULL)
+    {
+      Warn("redefining `%s`",vn);
+      killhdl(t);
+    }
+    sleftv tmp_expr;
+    if (iiDeclCommand(&tmp_expr,v,myynest,DEF_CMD,&IDROOT)) return TRUE;
+    sleftv h_expr;
+    memset(&h_expr,0,sizeof(h_expr));
+    h_expr.rtyp=IDHDL;
+    h_expr.data=h;
+    h_expr.name=vn;
+    return iiAssign(&tmp_expr,&h_expr);
+  }
+  else
+  {
+    Werror("`%s` not found in `%s`",v->Name(), u->Name());
+    return TRUE;
+  }
+  return FALSE;
+}
diff --git a/Singular/ipconv.cc b/Singular/ipconv.cc
new file mode 100644
index 0000000..4787f92
--- /dev/null
+++ b/Singular/ipconv.cc
@@ -0,0 +1,447 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: automatic type conversions
+*/
+
+
+
+
+#include <kernel/mod2.h>
+#include <Singular/tok.h>
+#include <Singular/ipid.h>
+#include <misc/intvec.h>
+#include <misc/options.h>
+#include <omalloc/omalloc.h>
+#include <kernel/polys.h>
+#include <kernel/ideals.h>
+#include <Singular/subexpr.h>
+#include <coeffs/numbers.h>
+#include <coeffs/coeffs.h>
+#include <coeffs/bigintmat.h>
+//#include <polys/ext_fields/longalg.h>
+#include <polys/matpol.h>
+#include <Singular/links/silink.h>
+#include <kernel/GBEngine/syz.h>
+#include <Singular/attrib.h>
+#include <polys/monomials/ring.h>
+#include <Singular/ipshell.h>
+#include <Singular/ipconv.h>
+
+typedef void *   (*iiConvertProc)(void * data);
+typedef void    (*iiConvertProcL)(leftv out,leftv in);
+struct sConvertTypes
+{
+  int i_typ;
+  int o_typ;
+  iiConvertProc p;
+  iiConvertProcL pl;
+};
+
+// all of these static conversion routines work destructive on their input
+
+static void * iiI2P(void *data)
+{
+  poly p=pISet((int)(long)data);
+  return (void *)p;
+}
+
+static void * iiBI2P(void *data)
+{
+  nMapFunc nMap=n_SetMap(coeffs_BIGINT,currRing->cf);
+  if (nMap==NULL)
+  {
+    Werror("no conversion from bigint to %s", nCoeffString(currRing->cf));
+    return NULL;
+  }
+  number n=nMap((number)data,coeffs_BIGINT,currRing->cf);
+  n_Delete((number *)&data, coeffs_BIGINT);
+  poly p=p_NSet(n, currRing);
+  return (void *)p;
+}
+
+static void * iiI2V(void *data)
+{
+  poly p=pISet((int)(long)data);
+  if (p!=NULL) pSetComp(p,1);
+  return (void *)p;
+}
+
+static void * iiBI2V(void *data)
+{
+  nMapFunc nMap=n_SetMap(coeffs_BIGINT,currRing->cf);
+  if (nMap==NULL)
+  {
+    Werror("no conversion from bigint to %s", nCoeffString(currRing->cf));
+    return NULL;
+  }
+  number n=nMap((number)data,coeffs_BIGINT,currRing->cf);
+  n_Delete((number *)&data, coeffs_BIGINT);
+  poly p=p_NSet(n, currRing);
+  if (p!=NULL) pSetComp(p,1);
+  return (void *)p;
+}
+
+static void * iiI2Id(void *data)
+{
+  ideal I=idInit(1,1);
+  I->m[0]=pISet((int)(long)data);
+  return (void *)I;
+}
+
+static void * iiBI2Id(void *data)
+{
+  ideal I=idInit(1,1);
+  nMapFunc nMap=n_SetMap(coeffs_BIGINT,currRing->cf);
+  if (nMap==NULL)
+  {
+    Werror("no conversion from bigint to %s", nCoeffString(currRing->cf));
+    return NULL;
+  }
+  number n=nMap((number)data,coeffs_BIGINT,currRing->cf);
+  n_Delete((number *)&data,coeffs_BIGINT);
+  poly p=pNSet(n);
+  I->m[0]=p;
+  return (void *)I;
+}
+static void * iiP2V(void *data)
+{
+  poly p=(poly)data;
+  if (p!=NULL) pSetCompP(p,1);
+  return (void *)p;
+}
+
+static void * iiP2Id(void *data)
+{
+  ideal I=idInit(1,1);
+
+  if (data!=NULL)
+  {
+    poly p=(poly)data;
+    I->m[0]=p;
+    if (pGetComp(p)!=0) I->rank=pMaxComp(p);
+  }
+  return (void *)I;
+}
+
+static void * iiV2Ma(void *data)
+{
+  matrix m=(matrix)idVec2Ideal((poly)data);
+  int h=MATCOLS(m);
+  MATCOLS(m)=MATROWS(m);
+  MATROWS(m)=h;
+  m->rank=h;
+  pDelete((poly *)&data);
+  return (void *)m;
+}
+
+static void * iiN2P(void *data);
+
+static void * iiDummy(void *data)
+{
+  return data;
+}
+
+static void * iiMo2Ma(void *data)
+{
+  void *res=id_Module2Matrix((ideal)data,currRing);
+  return res;
+}
+
+static void * iiMa2Mo(void *data)
+{
+  void *res=id_Matrix2Module((matrix)data,currRing);
+  return res;
+}
+
+static void * iiI2Iv(void *data)
+{
+  int s=(int)(long)data;
+  intvec *iv=new intvec(s,s);
+  return (void *)iv;
+}
+
+static void * iiI2N(void *data)
+{
+  number n=nInit((int)(long)data);
+  return (void *)n;
+}
+
+static void * iiI2BI(void *data)
+{
+  number n=n_Init((int)(long)data, coeffs_BIGINT);
+  return (void *)n;
+}
+
+static void * iiBI2N(void *data)
+{
+  if (currRing==NULL) return NULL;
+  nMapFunc nMap=n_SetMap(coeffs_BIGINT,currRing->cf);
+  if (nMap==NULL)
+  {
+    Werror("no conversion from bigint to %s", nCoeffString(currRing->cf));
+    return NULL;
+  }
+  number n=nMap((number)data,coeffs_BIGINT,currRing->cf);
+  n_Delete((number *)&data, coeffs_BIGINT);
+  return (void*)n;
+}
+
+static void * iiIm2Ma(void *data)
+{
+  int i, j;
+  intvec *iv = (intvec *)data;
+  matrix m = mpNew(iv->rows(), iv->cols());
+
+  for (i=iv->rows(); i>0; i--)
+  {
+    for (j=iv->cols(); j>0; j--)
+    {
+      MATELEM(m, i, j) = pISet(IMATELEM(*iv, i, j));
+    }
+  }
+  delete iv;
+  return (void *)m;
+}
+
+static void * iiIm2Bim(void *data)
+{
+  intvec *iv=(intvec*)data;
+  void *r=(void *)iv2bim(iv,coeffs_BIGINT);
+  delete iv;
+  return r;
+}
+
+static void * iiBim2Im(void *data)
+{
+  bigintmat *b=(bigintmat*)data;
+  void *r=(void *)bim2iv(b);
+  delete b;
+  return r;
+}
+
+static void * iiN2P(void *data)
+{
+  poly p=NULL;
+  if (!nIsZero((number)data))
+  {
+    p=pNSet((number)data);
+  }
+  //else
+  //{
+  //  nDelete((number *)&data);
+  //}
+  return (void *)p;
+}
+
+static void * iiN2Ma(void *data)
+{
+  ideal I=idInit(1,1);
+  if (!nIsZero((number)data))
+  {
+    poly p=pNSet((number)data);
+    I->m[0]=p;
+  }
+  //else
+  //{
+  //  nDelete((number *)&data);
+  //}
+  return (void *)I;
+}
+
+static void * iiS2Link(void *data)
+{
+  si_link l=(si_link)omAlloc0Bin(ip_link_bin);
+  slInit(l, (char *) data);
+  omFree((ADDRESS)data);
+  return (void *)l;
+}
+
+/*
+static void * iiR2L(void * data)
+{
+  syStrategy tmp=(syStrategy)data;
+  return  (void *)syConvRes(tmp,TRUE);
+}
+*/
+static void iiR2L_l(leftv out, leftv in)
+{
+  int add_row_shift = 0;
+  intvec *weights=(intvec*)atGet(in,"isHomog",INTVEC_CMD);
+  if (weights!=NULL)  add_row_shift=weights->min_in();
+
+  syStrategy tmp=(syStrategy)in->CopyD();
+
+  out->data=(void *)syConvRes(tmp,TRUE,add_row_shift);
+}
+
+static void * iiL2R(void * data)
+{
+  return (void *)syConvList((lists)data,TRUE);
+}
+
+//
+// automatic conversions:
+//
+#define IPCONV
+#define D(A)     A
+#define NULL_VAL NULL
+#include <Singular/table.h>
+/*2
+* try to convert 'input' of type 'inputType' to 'output' of type 'outputType'
+* return FALSE on success
+*/
+BOOLEAN iiConvert (int inputType, int outputType, int index, leftv input, leftv output,struct sConvertTypes *dConvertTypes)
+{
+  memset(output,0,sizeof(sleftv));
+  if ((inputType==outputType)
+  || (outputType==DEF_CMD)
+  || ((outputType==IDHDL)&&(input->rtyp==IDHDL)))
+  {
+    memcpy(output,input,sizeof(*output));
+    memset(input,0,sizeof(*input));
+    return FALSE;
+  }
+  else if (outputType==ANY_TYPE)
+  {
+    output->rtyp=ANY_TYPE;
+    output->data=(char *)(long)input->Typ();
+    /* the name of the object:*/
+    if (input->e==NULL)
+    {
+      if (input->rtyp==IDHDL)
+      /* preserve name: copy it */
+        output->name=omStrDup(IDID((idhdl)(input->data)));
+      else if (input->name!=NULL)
+      {
+        if (input->rtyp==ALIAS_CMD)
+        output->name=omStrDup(input->name);
+        else
+        {
+          output->name=input->name;
+          input->name=NULL;
+        }
+      }
+      else if ((input->rtyp==POLY_CMD) && (input->name==NULL))
+      {
+        if (input->data!=NULL)
+        {
+          int nr=pIsPurePower((poly)input->data);
+          if (nr!=0)
+          {
+            if (pGetExp((poly)input->data,nr)==1)
+            {
+              output->name=omStrDup(currRing->names[nr-1]);
+            }
+            else
+            {
+              char *tmp=(char *)omAlloc(4);
+              sprintf(tmp,"%c%d",*(currRing->names[nr-1]),
+                (int)pGetExp((poly)input->data,nr));
+              output->name=tmp;
+            }
+          }
+          else if(pIsConstant((poly)input->data))
+          {
+            StringSetS("");
+            number n=(pGetCoeff((poly)input->data));
+            n_Write(n, currRing->cf);
+            (pGetCoeff((poly)input->data))=n;
+            output->name=StringEndS();
+          }
+        }
+      }
+      else if ((input->rtyp==NUMBER_CMD) && (input->name==NULL))
+      {
+        StringSetS("");
+        number n=(number)input->data;
+        n_Write(n, currRing->cf);
+        input->data=(void*)n;
+        output->name=StringEndS();
+      }
+      else
+      {
+        /* no need to preserve name: use it */
+        output->name=input->name;
+        memset(input,0,sizeof(*input));
+      }
+    }
+    output->next=input->next;
+    input->next=NULL;
+    return FALSE;
+  }
+  if (index!=0) /* iiTestConvert does not returned 'failure' */
+  {
+    index--;
+
+    if((dConvertTypes[index].i_typ==inputType)
+    &&(dConvertTypes[index].o_typ==outputType))
+    {
+      if(traceit&TRACE_CONV)
+      {
+        Print("automatic  conversion %s -> %s\n",
+        Tok2Cmdname(inputType),Tok2Cmdname(outputType));
+      }
+      if ((currRing==NULL) && (outputType>BEGIN_RING) && (outputType<END_RING))
+        return TRUE;
+      output->rtyp=outputType;
+      if (dConvertTypes[index].p!=NULL)
+      {
+        output->data=dConvertTypes[index].p(input->CopyD());
+      }
+      else
+      {
+        dConvertTypes[index].pl(output,input);
+      }
+      if ((output->data==NULL)
+      && ((outputType!=INT_CMD)
+        &&(outputType!=POLY_CMD)
+        &&(outputType!=VECTOR_CMD)
+        &&(outputType!=NUMBER_CMD)))
+      {
+        return TRUE;
+      }
+      output->next=input->next;
+      input->next=NULL;
+  //if (outputType==MATRIX_CMD) Print("convert %d -> matrix\n",inputType);
+      return FALSE;
+    }
+  }
+  return TRUE;
+}
+
+/*2
+* try to convert 'inputType' in 'outputType'
+* return 0 on failure, an index (<>0) on success
+*/
+int iiTestConvert (int inputType, int outputType,struct sConvertTypes *dConvertTypes)
+{
+  if ((inputType==outputType)
+  || (outputType==DEF_CMD)
+  || (outputType==IDHDL)
+  || (outputType==ANY_TYPE))
+  {
+    return -1;
+  }
+
+  if ((currRing==NULL) && (outputType>BEGIN_RING) && (outputType<END_RING))
+    return 0;
+
+  // search the list
+  int i=0;
+  while (dConvertTypes[i].i_typ!=0)
+  {
+    if((dConvertTypes[i].i_typ==inputType)
+    &&(dConvertTypes[i].o_typ==outputType))
+    {
+      //Print("test convert %d to %d (%s -> %s):%d\n",inputType,outputType,
+      //Tok2Cmdname(inputType), Tok2Cmdname(outputType),i+1);
+      return i+1;
+    }
+    i++;
+  }
+  //Print("test convert %d to %d (%s -> %s):0\n",inputType,outputType,
+  // Tok2Cmdname(inputType), Tok2Cmdname(outputType));
+  return 0;
+}
diff --git a/Singular/ipconv.h b/Singular/ipconv.h
new file mode 100644
index 0000000..392d58e
--- /dev/null
+++ b/Singular/ipconv.h
@@ -0,0 +1,16 @@
+#ifndef IPCONVERT_H
+#define IPCONVERT_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: interpreter: converting types
+*/
+#include <kernel/structs.h>
+#include <Singular/table.h>
+
+int iiTestConvert (int inputType, int outputType, struct sConvertTypes *dCT=dConvertTypes);
+BOOLEAN iiConvert (int inputType, int outputType, int index,
+                   leftv input, leftv output, struct sConvertTypes *dCT=dConvertTypes);
+#endif
+
diff --git a/Singular/ipid.cc b/Singular/ipid.cc
new file mode 100644
index 0000000..5a368fb
--- /dev/null
+++ b/Singular/ipid.cc
@@ -0,0 +1,740 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+
+/*
+* ABSTRACT: identfier handling
+*/
+
+
+
+
+
+#include <kernel/mod2.h>
+
+#include <omalloc/omalloc.h>
+
+#include <misc/options.h>
+#include <misc/intvec.h>
+
+#include <coeffs/numbers.h>
+#include <coeffs/bigintmat.h>
+
+#include <polys/matpol.h>
+#include <polys/monomials/ring.h>
+
+#include <kernel/polys.h>
+#include <kernel/ideals.h>
+#include <kernel/GBEngine/syz.h>
+
+#include <Singular/tok.h>
+#include <Singular/ipshell.h>
+#include <Singular/fevoices.h>
+#include <Singular/lists.h>
+#include <Singular/attrib.h>
+#include <Singular/links/silink.h>
+#include <Singular/ipid.h>
+#include <Singular/blackbox.h>
+
+#ifdef SINGULAR_4_1
+#include <Singular/number2.h>
+#endif
+#ifdef HAVE_DYNAMIC_LOADING
+#include <polys/mod_raw.h>
+#endif /* HAVE_DYNAMIC_LOADING */
+
+#include <string.h>
+
+omBin sip_command_bin = omGetSpecBin(sizeof(sip_command));
+omBin sip_package_bin = omGetSpecBin(sizeof(sip_package));
+//omBin ip_package_bin = omGetSpecBin(sizeof(ip_package));
+omBin idrec_bin = omGetSpecBin(sizeof(idrec));
+
+coeffs coeffs_BIGINT;
+
+FILE   *feFilePending; /*temp. storage for grammar.y */
+
+proclevel *procstack=NULL;
+//idhdl idroot = NULL;
+
+idhdl currPackHdl = NULL;
+idhdl basePackHdl = NULL;
+package currPack =NULL;
+package basePack =NULL;
+idhdl currRingHdl = NULL;
+const char* iiNoName="_";
+
+void paCleanUp(package pack);
+
+/*0 implementation*/
+
+int iiS2I(const char *s)
+{
+  int i;
+  i=s[0];
+  if (s[1]!='\0')
+  {
+    i=(i<<8)+s[1];
+    if (s[2]!='\0')
+    {
+      i=(i<<8)+s[2];
+      if (s[3]!='\0')
+      {
+        i=(i<<8)+s[3];
+      }
+    }
+  }
+  return i;
+}
+
+idhdl idrec::get(const char * s, int level)
+{
+  assume(s!=NULL);
+  assume((level>=0) && (level<=1000)); //not really, but if it isnt in that bounds..
+  idhdl h = this;
+  idhdl found=NULL;
+  int l;
+  const char *id_;
+  int i=iiS2I(s);
+  int less4=(i < (1<<24));
+  while (h!=NULL)
+  {
+    omCheckAddr((ADDRESS)IDID(h));
+    l=IDLEV(h);
+    if ((l==0)||(l==level))
+    {
+      if (i==h->id_i)
+      {
+        id_=IDID(h);
+        if (less4 || (0 == strcmp(s+4,id_+4)))
+        {
+          if (l==level) return h;
+          found=h;
+        }
+      }
+    }
+    h = IDNEXT(h);
+  }
+  return found;
+}
+
+//idrec::~idrec()
+//{
+//  if (id!=NULL)
+//  {
+//    omFree((ADDRESS)id);
+//    id=NULL;
+//  }
+//  /* much more !! */
+//}
+
+void *idrecDataInit(int t)
+{
+  switch (t)
+  {
+    //the type with init routines:
+#ifdef SINGULAR_4_1
+    case CNUMBER_CMD:
+      return (void*)n2Init(0,NULL);
+    case CMATRIX_CMD:
+#endif
+    case BIGINTMAT_CMD:
+      return (void *)new bigintmat();
+    case INTVEC_CMD:
+    case INTMAT_CMD:
+      return (void *)new intvec();
+    case NUMBER_CMD:
+      return (void *) nInit(0);
+    case BIGINT_CMD:
+      return (void *) n_Init(0, coeffs_BIGINT);
+    case IDEAL_CMD:
+    case MODUL_CMD:
+    case MATRIX_CMD:
+      return (void*) idInit(1,1);
+    case MAP_CMD:
+    {
+      map m = (map)idInit(1,1);
+      m->preimage = omStrDup(IDID(currRingHdl));
+      return (void *)m;
+    }
+    case STRING_CMD:
+      return (void *)omAlloc0(1);
+    case LIST_CMD:
+    {
+      lists l=(lists)omAllocBin(slists_bin);
+      l->Init();
+      return (void*)l;
+    }
+    //the types with the standard init: set the struct to zero
+    case LINK_CMD:
+      return (void*) omAlloc0Bin(sip_link_bin);
+    case RING_CMD:
+      return (void*) omAlloc0Bin(sip_sring_bin);
+    case PACKAGE_CMD:
+    {
+      package pa=(package)omAlloc0Bin(sip_package_bin);
+      pa->language=LANG_NONE;
+      pa->loaded = FALSE;
+      return (void*)pa;
+    }
+    case PROC_CMD:
+    {
+      procinfov pi=(procinfov)omAlloc0Bin(procinfo_bin);
+      pi->ref=1;
+      pi->language=LANG_NONE;
+      return (void*)pi;
+    }
+    case RESOLUTION_CMD:
+      return  (void *)omAlloc0(sizeof(ssyStrategy));
+    //other types: without init (int,script,poly,def,package)
+    case CRING_CMD:
+    case INT_CMD:
+    case DEF_CMD:
+    case POLY_CMD:
+    case VECTOR_CMD:
+    case QRING_CMD:
+       return (void*)0L;
+    default:
+      {
+        if (t>MAX_TOK)
+        {
+#ifdef BLACKBOX_DEVEL
+          Print("bb-type %d\n",t);
+#endif
+          blackbox *bb=getBlackboxStuff(t);
+          if (bb!=NULL)
+             return (void *)bb->blackbox_Init(bb);
+        }
+        else
+          Werror("unknown type %d",t);
+        break;
+      }
+  }
+  return (void *)0L;
+}
+idhdl idrec::set(const char * s, int level, int t, BOOLEAN init)
+{
+  //printf("define %s, %x, level: %d, typ: %d\n", s,s,level,t);
+  idhdl h = (idrec *)omAlloc0Bin(idrec_bin);
+  IDID(h)   = s;
+  IDTYP(h)  = t;
+  IDLEV(h)  = level;
+  IDNEXT(h) = this;
+  BOOLEAN at_start=(this==IDROOT);
+  h->id_i=iiS2I(s);
+  if (init)
+  {
+    if ((t==IDEAL_CMD)||(t==MODUL_CMD))
+      IDFLAG(h) = Sy_bit(FLAG_STD);
+    IDSTRING(h)=(char *)idrecDataInit(t);
+    // additional settings:--------------------------------------
+#if 0
+    // this leads to a memory leak
+    if (t == QRING_CMD)
+    {
+      // IDRING(h)=rCopy(currRing);
+      /* QRING_CMD is ring dep => currRing !=NULL */
+    }
+#endif
+  }
+  // --------------------------------------------------------
+  if (at_start)
+    IDNEXT(h) = IDROOT;
+  return  h;
+}
+
+char * idrec::String(BOOLEAN typed)
+{
+  sleftv tmp;
+  memset(&tmp,0,sizeof(sleftv));
+  tmp.rtyp=IDTYP(this);
+  tmp.data=IDDATA(this);
+  tmp.name=IDID(this);
+  return tmp.String(NULL, typed);
+}
+
+idhdl enterid(const char * s, int lev, int t, idhdl* root, BOOLEAN init, BOOLEAN search)
+{
+  if (s==NULL) return NULL;
+  if (root==NULL) return NULL;
+  idhdl h;
+  s=omStrDup(s);
+  // idhdl *save_root=root;
+  if (t==PACKAGE_CMD)
+  {
+    if (root!=&(basePack->idroot))
+    {
+      root=&(basePack->idroot);
+    }
+  }
+  // is it already defined in root ?
+  if ((h=(*root)->get(s,lev))!=NULL)
+  {
+    if (IDLEV(h)==lev)
+    {
+      if ((IDTYP(h) == t)||(t==DEF_CMD))
+      {
+        if ((IDTYP(h)==PACKAGE_CMD)
+        && (strcmp(s,"Top")==0))
+        {
+          goto errlabel;
+        }
+        if (BVERBOSE(V_REDEFINE))
+          Warn("redefining %s **",s);
+        if (s==IDID(h)) IDID(h)=NULL;
+        killhdl2(h,root,currRing);
+      }
+      else
+        goto errlabel;
+    }
+  }
+  // is it already defined in currRing->idroot ?
+  else if (search && (currRing!=NULL)&&((*root) != currRing->idroot))
+  {
+    if ((h=currRing->idroot->get(s,lev))!=NULL)
+    {
+      if (IDLEV(h)==lev)
+      {
+        if ((IDTYP(h) == t)||(t==DEF_CMD))
+        {
+          if (BVERBOSE(V_REDEFINE))
+            Warn("redefining %s **",s);
+          if (s==IDID(h)) IDID(h)=NULL;
+          killhdl2(h,&currRing->idroot,currRing);
+        }
+        else
+          goto errlabel;
+      }
+    }
+  }
+  // is it already defined in idroot ?
+  else if (search && (*root != IDROOT))
+  {
+    if ((h=IDROOT->get(s,lev))!=NULL)
+    {
+      if (IDLEV(h)==lev)
+      {
+        if ((IDTYP(h) == t)||(t==DEF_CMD))
+        {
+          if (BVERBOSE(V_REDEFINE))
+            Warn("redefining `%s` **",s);
+          if (s==IDID(h)) IDID(h)=NULL;
+          killhdl2(h,&IDROOT,NULL);
+        }
+        else
+          goto errlabel;
+      }
+    }
+  }
+  *root = (*root)->set(s, lev, t, init);
+#ifndef SING_NDEBUG
+  checkall();
+#endif
+  return *root;
+
+  errlabel:
+    //Werror("identifier `%s` in use(lev h=%d,typ=%d,t=%d, curr=%d)",s,IDLEV(h),IDTYP(h),t,lev);
+    Werror("identifier `%s` in use",s);
+    //listall();
+    omFree((ADDRESS)s);
+    return NULL;
+}
+void killid(const char * id, idhdl * ih)
+{
+  if (id!=NULL)
+  {
+    idhdl h = (*ih)->get(id,myynest);
+
+    // id not found in global list, is it defined in current ring ?
+    if (h==NULL)
+    {
+      if ((currRing!=NULL) && (*ih != (currRing->idroot)))
+      {
+        h = currRing->idroot->get(id,myynest);
+        if (h!=NULL)
+        {
+          killhdl2(h,&(currRing->idroot),currRing);
+          return;
+        }
+      }
+      Werror("`%s` is not defined",id);
+      return;
+    }
+    killhdl2(h,ih,currRing);
+  }
+  else
+    Werror("kill what ?");
+}
+
+void killhdl(idhdl h, package proot)
+{
+  int t=IDTYP(h);
+  if (((BEGIN_RING<t) && (t<END_RING) && (t!=QRING_CMD))
+  || ((t==LIST_CMD) && (lRingDependend((lists)IDDATA(h)))))
+    killhdl2(h,&currRing->idroot,currRing);
+  else
+  {
+    if(t==PACKAGE_CMD)
+    {
+      killhdl2(h,&(basePack->idroot),NULL);
+    }
+    else
+    {
+      idhdl s=proot->idroot;
+      while ((s!=h) && (s!=NULL)) s=s->next;
+      if (s!=NULL)
+        killhdl2(h,&(proot->idroot),NULL);
+      else if (basePack!=proot)
+      {
+        idhdl s=basePack->idroot;
+        while ((s!=h) && (s!=NULL)) s=s->next;
+        if (s!=NULL)
+          killhdl2(h,&(basePack->idroot),currRing);
+        else
+          killhdl2(h,&(currRing->idroot),currRing);
+       }
+    }
+  }
+}
+
+void killhdl2(idhdl h, idhdl * ih, ring r)
+{
+  //printf("kill %s, id %x, typ %d lev: %d\n",IDID(h),(int)IDID(h),IDTYP(h),IDLEV(h));
+  idhdl hh;
+
+  if (TEST_V_ALLWARN
+  && (IDLEV(h)!=myynest)
+  &&(IDLEV(h)==0))
+  {
+    if (((*ih)==basePack->idroot)
+    || ((currRing!=NULL)&&((*ih)==currRing->idroot)))
+      Warn("kill global `%s` at line >>%s<<\n",IDID(h),my_yylinebuf);
+  }
+  if (h->attribute!=NULL)
+  {
+    //h->attribute->killAll(r); MEMORY LEAK!
+    h->attribute=NULL;
+  }
+  if (IDTYP(h) == PACKAGE_CMD)
+  {
+    if (strcmp(IDID(h),"Top")==0)
+    {
+      WarnS("can not kill `Top`");
+      return;
+    }
+    // any objects defined for this package ?
+    if ((IDPACKAGE(h)->ref<=0)  &&  (IDPACKAGE(h)->idroot!=NULL))
+    {
+      if (currPack==IDPACKAGE(h))
+      {
+        currPack=basePack;
+        currPackHdl=NULL;
+      }
+      idhdl * hd = &IDRING(h)->idroot;
+      idhdl  hdh = IDNEXT(*hd);
+      idhdl  temp;
+      while (hdh!=NULL)
+      {
+        temp = IDNEXT(hdh);
+        killhdl2(hdh,&(IDPACKAGE(h)->idroot),NULL);
+        hdh = temp;
+      }
+      killhdl2(*hd,hd,NULL);
+      if (IDPACKAGE(h)->libname!=NULL) omFree((ADDRESS)(IDPACKAGE(h)->libname));
+    }
+    paKill(IDPACKAGE(h));
+    if (currPackHdl==h) currPackHdl=packFindHdl(currPack);
+    iiCheckPack(currPack);
+  }
+  else if ((IDTYP(h)==RING_CMD)||(IDTYP(h)==QRING_CMD))
+    rKill(h);
+  else if (IDDATA(h)!=NULL)
+    s_internalDelete(IDTYP(h),IDDATA(h),r);
+  //  general  -------------------------------------------------------------
+  // now dechain it and delete idrec
+  if (IDID(h)!=NULL) // OB: ?????
+    omFree((ADDRESS)IDID(h));
+  IDID(h)=NULL;
+  IDDATA(h)=NULL;
+  if (h == (*ih))
+  {
+    // h is at the beginning of the list
+    *ih = IDNEXT(h) /* ==*ih */;
+  }
+  else if (ih!=NULL)
+  {
+    // h is somethere in the list:
+    hh = *ih;
+    loop
+    {
+      if (hh==NULL)
+      {
+        PrintS(">>?<< not found for kill\n");
+        return;
+      }
+      idhdl hhh = IDNEXT(hh);
+      if (hhh == h)
+      {
+        IDNEXT(hh) = IDNEXT(hhh);
+        break;
+      }
+      hh = hhh;
+    }
+  }
+  omFreeBin((ADDRESS)h, idrec_bin);
+}
+
+idhdl ggetid(const char *n, BOOLEAN /*local*/, idhdl *packhdl)
+{
+  idhdl h = IDROOT->get(n,myynest);
+  idhdl h2=NULL;
+  *packhdl = NULL;
+  if ((currRing!=NULL) && ((h==NULL)||(IDLEV(h)!=myynest)))
+  {
+    h2 = currRing->idroot->get(n,myynest);
+  }
+  if (h2==NULL) return h;
+  return h2;
+}
+
+idhdl ggetid(const char *n)
+{
+  idhdl h = IDROOT->get(n,myynest);
+  if ((h!=NULL)&&(IDLEV(h)==myynest)) return h;
+  idhdl h2=NULL;
+  if (currRing!=NULL)
+  {
+    h2 = currRing->idroot->get(n,myynest);
+  }
+  if (h2!=NULL) return h2;
+  if (h!=NULL) return h;
+  if (basePack!=currPack)
+    return basePack->idroot->get(n,myynest);
+  return NULL;
+}
+
+void ipListFlag(idhdl h)
+{
+  if (hasFlag(h,FLAG_STD)) PrintS(" (SB)");
+#ifdef HAVE_PLURAL
+  if (hasFlag(h,FLAG_TWOSTD)) PrintS(" (2SB)");
+#endif
+}
+
+lists ipNameList(idhdl root)
+{
+  idhdl h=root;
+  /* compute the length */
+  int l=0;
+  while (h!=NULL) { l++; h=IDNEXT(h); }
+  /* allocate list */
+  lists L=(lists)omAllocBin(slists_bin);
+  L->Init(l);
+  /* copy names */
+  h=root;
+  l=0;
+  while (h!=NULL)
+  {
+    /* list is initialized with 0 => no need to clear anything */
+    L->m[l].rtyp=STRING_CMD;
+    L->m[l].data=omStrDup(IDID(h));
+    l++;
+    h=IDNEXT(h);
+  }
+  return L;
+}
+
+lists ipNameListLev(idhdl root, int lev)
+{
+  idhdl h=root;
+  /* compute the length */
+  int l=0;
+  while (h!=NULL) { if (IDLEV(h)==lev) l++; h=IDNEXT(h); }
+  /* allocate list */
+  lists L=(lists)omAllocBin(slists_bin);
+  L->Init(l);
+  /* copy names */
+  h=root;
+  l=0;
+  while (h!=NULL)
+  {
+    if (IDLEV(h)==lev)
+    {
+      /* list is initialized with 0 => no need to clear anything */
+      L->m[l].rtyp=STRING_CMD;
+      L->m[l].data=omStrDup(IDID(h));
+      l++;
+    }
+    h=IDNEXT(h);
+  }
+  return L;
+}
+
+/*
+* move 'tomove' from root1 list to root2 list
+*/
+static int ipSwapId(idhdl tomove, idhdl &root1, idhdl &root2)
+{
+  idhdl h;
+  /* search 'tomove' in root2 : if found -> do nothing */
+  h=root2;
+  while ((h!=NULL) && (h!=tomove)) h=IDNEXT(h);
+  if (h!=NULL) return FALSE; /*okay */
+  /* search predecessor of h in root1, remove 'tomove' */
+  h=root1;
+  if (tomove==h)
+  {
+    root1=IDNEXT(h);
+  }
+  else
+  {
+    while ((h!=NULL) && (IDNEXT(h)!=tomove)) h=IDNEXT(h);
+    if (h==NULL) return TRUE; /* not in the list root1 -> do nothing */
+    IDNEXT(h)=IDNEXT(tomove);
+  }
+  /* add to root2 list */
+  IDNEXT(tomove)=root2;
+  root2=tomove;
+  return FALSE;
+}
+
+void  ipMoveId(idhdl tomove)
+{
+  if ((currRing!=NULL)&&(tomove!=NULL))
+  {
+    if (((QRING_CMD!=IDTYP(tomove)) && RingDependend(IDTYP(tomove)))
+    || ((IDTYP(tomove)==LIST_CMD) && (lRingDependend(IDLIST(tomove)))))
+    {
+      /*move 'tomove' to ring id's*/
+      if (ipSwapId(tomove,IDROOT,currRing->idroot))
+      ipSwapId(tomove,basePack->idroot,currRing->idroot);
+    }
+    else
+    {
+      /*move 'tomove' to global id's*/
+      ipSwapId(tomove,currRing->idroot,IDROOT);
+    }
+  }
+}
+
+const char * piProcinfo(procinfov pi, const char *request)
+{
+  if((pi == NULL)||(pi->language==LANG_NONE)) return "empty proc";
+  else if (strcmp(request, "libname")  == 0) return pi->libname;
+  else if (strcmp(request, "procname") == 0) return pi->procname;
+  else if (strcmp(request, "type")     == 0)
+  {
+    switch (pi->language)
+    {
+      case LANG_SINGULAR: return "singular"; break;
+      case LANG_C:        return "object";   break;
+      case LANG_NONE:     return "none";     break;
+      default:            return "unknow language";
+    }
+  }
+  else if (strcmp(request, "ref")      == 0)
+  {
+    char p[8];
+    sprintf(p, "%d", pi->ref);
+    return omStrDup(p);  // MEMORY-LEAK
+  }
+  return "??";
+}
+
+BOOLEAN piKill(procinfov pi)
+{
+  Voice *p=currentVoice;
+  while (p!=NULL)
+  {
+    if (p->pi==pi && pi->ref <= 1)
+    {
+      Warn("`%s` in use, can not be killed",pi->procname);
+      return TRUE;
+    }
+    p=p->next;
+  }
+  (pi->ref)--;
+  if (pi->ref <= 0)
+  {
+    if (pi->libname != NULL) // OB: ????
+      omFree((ADDRESS)pi->libname);
+    if (pi->procname != NULL) // OB: ????
+      omFree((ADDRESS)pi->procname);
+
+    if( pi->language == LANG_SINGULAR)
+    {
+      if (pi->data.s.body != NULL) // OB: ????
+        omFree((ADDRESS)pi->data.s.body);
+    }
+    if( pi->language == LANG_C)
+    {
+    }
+    memset((void *) pi, 0, sizeof(procinfo));
+    pi->language=LANG_NONE;
+    omFreeBin((ADDRESS)pi,  procinfo_bin);
+  }
+  return FALSE;
+}
+
+void paCleanUp(package pack)
+{
+  (pack->ref)--;
+  if (pack->ref < 0)
+  {
+#ifndef HAVE_STATIC
+    if( pack->language == LANG_C)
+    {
+      Print("//dlclose(%s)\n",pack->libname);
+#ifdef HAVE_DYNAMIC_LOADING
+      dynl_close (pack->handle);
+#endif /* HAVE_DYNAMIC_LOADING */
+    }
+#endif /* HAVE_STATIC */
+    omFree((ADDRESS)pack->libname);
+    memset((void *) pack, 0, sizeof(sip_package));
+    pack->language=LANG_NONE;
+  }
+}
+
+void proclevel::push(char *n)
+{
+  //Print("push %s\n",n);
+  proclevel *p=(proclevel*)omAlloc0(sizeof(proclevel));
+  p->cRing=currRing;
+  p->cRingHdl=currRingHdl;
+  p->name=n;
+  p->cPackHdl=currPackHdl;
+  p->cPack=currPack;
+  p->next=this;
+  procstack=p;
+}
+void proclevel::pop()
+{
+  //Print("pop %s\n",name);
+  //if (currRing!=::currRing) PrintS("currRing wrong\n");;
+  //::currRing=this->currRing;
+  //if (r==NULL) Print("set ring to NULL at lev %d(%s)\n",myynest,name);
+  //::currRingHdl=this->currRingHdl;
+  //if((::currRingHdl==NULL)||(IDRING(::currRingHdl)!=(::currRing)))
+  //  ::currRingHdl=rFindHdl(::currRing,NULL,NULL);
+  //Print("restore pack=%s,1.obj=%s\n",IDID(currPackHdl),IDID(currPack->idroot));
+  currPackHdl=this->cPackHdl;
+  currPack=this->cPack;
+  iiCheckPack(currPack);
+  proclevel *p=this;
+  procstack=next;
+  omFreeSize(p,sizeof(proclevel));
+}
+
+idhdl packFindHdl(package r)
+{
+  idhdl h=basePack->idroot;
+  while (h!=NULL)
+  {
+    if ((IDTYP(h)==PACKAGE_CMD)
+        && (IDPACKAGE(h)==r))
+      return h;
+    h=IDNEXT(h);
+  }
+  return NULL;
+}
diff --git a/Singular/ipid.h b/Singular/ipid.h
new file mode 100644
index 0000000..1c04a09
--- /dev/null
+++ b/Singular/ipid.h
@@ -0,0 +1,151 @@
+#ifndef IPID_H
+#define IPID_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+
+/*
+* ABSTRACT: identfier handling
+*/
+#include <string.h>
+//#include <kernel/structs.h>
+#include <Singular/idrec.h>
+#include <Singular/subexpr.h>
+#include <Singular/lists.h>
+
+extern idhdl currPackHdl;
+extern idhdl basePackHdl;
+extern package currPack;
+extern package basePack;
+#define IDROOT (currPack->idroot)
+
+struct sip_command;
+typedef struct sip_command ip_command;
+typedef ip_command *       command;
+
+struct sip_command
+{
+  sleftv arg1; /*arg1 to build_in, proc to proc_call*/
+  sleftv arg2; /*NULL or arg2 to build_in, args to proc_call*/
+  sleftv arg3; /*NULL or arg3*/
+  short argc; /*0,1,2,3 to build_in, -1 otherwise*/
+  short op;   /* build_in or PROC_CMD*/
+};
+
+struct sip_package
+{
+  idhdl         idroot; /* local objects */
+  char          *libname;
+  short         ref;
+  language_defs language;
+  BOOLEAN       loaded;
+  void          *handle;
+};
+
+inline package paCopy(package pack)
+{
+  pack->ref++;
+  return pack;
+}
+
+inline void paKill(package pack)
+{
+  pack->ref--;
+}
+
+class proclevel
+{
+  public:
+  proclevel * next;
+  idhdl      cRingHdl;
+  ring       cRing;
+  idhdl      cPackHdl;
+  package    cPack;
+  char      * name;
+  proclevel()  { memset(this,0,sizeof(*this)); }
+  void    push(char *);
+  void    pop();
+};
+extern proclevel *procstack;
+
+typedef struct
+{
+  int (*iiAddCproc)(const char *libname, const char *procname, BOOLEAN pstatic,
+                    BOOLEAN(*func)(leftv res, leftv v));
+  int (*iiArithAddCmd)(const char *szName, short nAlias, short nTokval,
+                       short nToktype, short nPos);
+
+} SModulFunctions;
+
+
+extern idhdl      currRingHdl;
+/* ================================================================== */
+/* module support */
+typedef int (*SModulFunc_t)(SModulFunctions*);
+BOOLEAN load_builtin(const char *newlib, BOOLEAN autoexport, SModulFunc_t init);
+void module_help_main(const char *newlib,const char *help);
+void module_help_proc(const char *newlib,const char *p, const char *help);
+
+/* ================================================================== */
+
+/*extern ring     currRing;  in ring.h */
+
+idhdl enterid(const char * a, int lev, int t, idhdl* root, BOOLEAN init=TRUE, BOOLEAN serach=TRUE);
+idhdl ggetid(const char *n);
+idhdl ggetid(const char *n, BOOLEAN local, idhdl *packhdl);
+void  killid(const char * a, idhdl * i);
+void killhdl(idhdl h, package prooti=currPack);
+void  killhdl2(idhdl h, idhdl * ih, ring r);
+lists ipNameList(idhdl root);
+lists ipNameListLev(idhdl root, int lev);
+void  ipMoveId(idhdl h);
+BOOLEAN checkPackage(package pack);
+idhdl packFindHdl(package r);
+void jjNormalizeQRingId(leftv I);
+void jjNormalizeQRingP(leftv I);
+void *idrecDataInit(int t);
+
+#define FLAG_STD   0
+#define FLAG_TWOSTD  3
+#define FLAG_QRING   4
+#define hasFlag(A,F) Sy_inset((F),(A)->flag)
+#define setFlag(A,F) (A)->flag|=Sy_bit(F)
+#define resetFlag(A,F) (A)->flag&=~Sy_bit(F)
+void ipListFlag(idhdl h);
+
+
+#define IDNEXT(a)    ((a)->next)
+#define IDTYP(a)     ((a)->typ)
+#define IDFLAG(a)    ((a)->flag)
+#define IDLEV(a)     ((a)->lev)
+#define IDID(a)      ((a)->id)
+#define IDATTR(a)    ((a)->attribute)
+
+#define IDINT(a)    ((int)(long)((a)->data.ustring))
+#define IDDATA(a)   ((a)->data.ustring)
+#define IDRING(a)   ((a)->data.uring)
+#define IDINTVEC(a) ((a)->data.iv)
+#define IDBIMAT(a)  ((a)->data.bim)
+#define IDPOLY(a)   ((a)->data.p)
+#define IDBIGINT(a) ((a)->data.n)
+#define IDNUMBER(a) ((a)->data.n)
+#define IDIDEAL(a)  ((a)->data.uideal)
+#define IDMATRIX(a) ((a)->data.umatrix)
+#define IDMAP(a)    ((a)->data.umap)
+#define IDSTRING(a) ((a)->data.ustring)
+#define IDLIST(a)   ((a)->data.l)
+#define IDLINK(a)   ((a)->data.li)
+#define IDPACKAGE(a) ((a)->data.pack)
+#define IDPROC(a)   ((a)->data.pinf)
+
+extern omBin sip_command_bin;
+extern omBin sip_package_bin;
+extern omBin idrec_bin;
+extern omBin sleftv_bin;
+
+extern coeffs coeffs_BIGINT;
+
+extern FILE   *feFilePending; /*temp. storage for grammar.y */
+#endif
+
+
diff --git a/Singular/iplib.cc b/Singular/iplib.cc
new file mode 100644
index 0000000..da857cc
--- /dev/null
+++ b/Singular/iplib.cc
@@ -0,0 +1,1360 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: interpreter: LIB and help
+*/
+
+
+
+
+
+#include <kernel/mod2.h>
+
+#include <Singular/tok.h>
+#include <misc/options.h>
+#include <Singular/ipid.h>
+#include <omalloc/omalloc.h>
+#include <polys/monomials/ring.h>
+#include <Singular/subexpr.h>
+#include <Singular/ipshell.h>
+#include <Singular/fevoices.h>
+#include <Singular/lists.h>
+
+//#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <sys/stat.h>
+
+
+#if SIZEOF_LONG == 8
+#define SI_MAX_NEST 500
+#elif defined(__CYGWIN__)
+#define SI_MAX_NEST 480
+#else
+#define SI_MAX_NEST 1000
+#endif
+
+#if defined(ix86Mac_darwin) || defined(x86_64Mac_darwin) || defined(ppcMac_darwin)
+#  define MODULE_SUFFIX bundle
+#elif defined(__CYGWIN__)
+#  define MODULE_SUFFIX dll
+#else
+#  define MODULE_SUFFIX so
+#endif
+
+#define MODULE_SUFFIX_STRING EXPANDED_STRINGIFY(MODULE_SUFFIX)
+
+
+#ifdef HAVE_DYNAMIC_LOADING
+BOOLEAN load_modules(const char *newlib, char *fullname, BOOLEAN autoexport);
+#endif
+
+#ifdef HAVE_LIBPARSER
+#  include "libparse.h"
+#else /* HAVE_LIBPARSER */
+procinfo *iiInitSingularProcinfo(procinfov pi, const char *libname,
+              const char *procname, int line, long pos, BOOLEAN pstatic=FALSE);
+#endif /* HAVE_LIBPARSER */
+#define NS_LRING (procstack->cRing)
+
+extern int iiArithAddCmd(const char *szName, short nAlias, short nTokval,
+                         short nToktype, short nPos);
+
+#include <Singular/mod_lib.h>
+
+#ifdef HAVE_LIBPARSER
+void yylprestart (FILE *input_file );
+int current_pos(int i=0);
+extern int yylp_errno;
+extern int yylplineno;
+extern char *yylp_errlist[];
+void print_init();
+libstackv library_stack;
+#endif
+
+//int IsCmd(char *n, int tok);
+char mytolower(char c);
+
+/*2
+* return TRUE if the libray libname is already loaded
+*/
+BOOLEAN iiGetLibStatus(char *lib)
+{
+  idhdl hl;
+
+  char *plib = iiConvName(lib);
+  hl = basePack->idroot->get(plib,0);
+  omFree(plib);
+  if((hl==NULL) ||(IDTYP(hl)!=PACKAGE_CMD))
+  {
+    return FALSE;
+  }
+  return (strcmp(lib,IDPACKAGE(hl)->libname)==0);
+}
+
+/*2
+* find the library of an proc:
+*  => return (pi->libname)
+*/
+char * iiGetLibName(procinfov pi)
+{
+  return pi->libname;
+}
+
+/*2
+* given a line 'proc[ ]+{name}[ \t]*'
+* return a pointer to name and set the end of '\0'
+* changes the input!
+* returns: e: pointer to 'end of name'
+*          ct: changed char at the end of s
+*/
+char* iiProcName(char *buf, char & ct, char* &e)
+{
+  char *s=buf+5;
+  while (*s==' ') s++;
+  e=s+1;
+  while ((*e>' ') && (*e!='(')) e++;
+  ct=*e;
+  *e='\0';
+  return s;
+}
+
+/*2
+* given a line with args, return the argstr
+*/
+char * iiProcArgs(char *e,BOOLEAN withParenth)
+{
+  while ((*e==' ') || (*e=='\t') || (*e=='(')) e++;
+  if (*e<' ')
+  {
+    if (withParenth)
+    {
+      // no argument list, allow list #
+      return omStrDup("parameter list #;");
+    }
+    else
+    {
+      // empty list
+      return omStrDup("");
+    }
+  }
+  BOOLEAN in_args;
+  BOOLEAN args_found;
+  char *s;
+  char *argstr=(char *)omAlloc(127); // see ../omalloc/omTables.inc
+  int argstrlen=127;
+  *argstr='\0';
+  int par=0;
+  do
+  {
+    args_found=FALSE;
+    s=e; // set s to the starting point of the arg
+         // and search for the end
+    while(*s==' ') s++; e=s; // skip leading paces
+    while ((*e!=',')
+    &&((par!=0) || (*e!=')'))
+    &&(*e!='\0'))
+    {
+      if (*e=='(') par++;
+      else if (*e==')') par--;
+      args_found=args_found || (*e>' ');
+      e++;
+    }
+    in_args=(*e==',');
+    if (args_found)
+    {
+      *e='\0';
+      // check for space:
+      if ((int)strlen(argstr)+12 /* parameter + ;*/ +(int)strlen(s)>= argstrlen)
+      {
+        argstrlen*=2;
+        char *a=(char *)omAlloc( argstrlen);
+        strcpy(a,argstr);
+        omFree((ADDRESS)argstr);
+        argstr=a;
+      }
+      // copy the result to argstr
+      if(strncmp(s,"alias ",6)!=0)
+      {
+        strcat(argstr,"parameter ");
+      }
+      strcat(argstr,s);
+      strcat(argstr,"; ");
+      e++; // e was pointing to ','
+    }
+  } while (in_args);
+  return argstr;
+}
+
+/*2
+* locate `procname` in lib `libname` and find the part `part`:
+*  part=0: help, between, but excluding the line "proc ..." and "{...":
+*    => return
+*  part=1: body, between "{ ..." and "}", including the 1. line, w/o "{"
+*    => set pi->data.s.body, return NULL
+*  part=2: example, between, but excluding the line "exapmle {..." and "}":
+*    => return
+*/
+char* iiGetLibProcBuffer(procinfo *pi, int part )
+{
+  char buf[256], *s = NULL, *p;
+  long procbuflen;
+
+  FILE * fp = feFopen( pi->libname, "rb", NULL, TRUE );
+  if (fp==NULL)
+  {
+    return NULL;
+  }
+
+  fseek(fp, pi->data.s.proc_start, SEEK_SET);
+  if(part==0)
+  { // load help string
+    int i, offset=0;
+    long head = pi->data.s.def_end - pi->data.s.proc_start;
+    procbuflen = pi->data.s.help_end - pi->data.s.help_start;
+    if (procbuflen<5)
+    {
+      fclose(fp);
+      return NULL; // help part does not exist
+    }
+    //Print("Help=%ld-%ld=%d\n", pi->data.s.body_start,
+    //    pi->data.s.proc_start, procbuflen);
+    s = (char *)omAlloc(procbuflen+head+3);
+    myfread(s, head, 1, fp);
+    s[head] = '\n';
+    fseek(fp, pi->data.s.help_start, SEEK_SET);
+    myfread(s+head+1, procbuflen, 1, fp);
+    fclose(fp);
+    s[procbuflen+head+1] = '\n';
+    s[procbuflen+head+2] = '\0';
+    offset=0;
+    for(i=0;i<=procbuflen+head+2; i++)
+    {
+      if(s[i]=='\\' &&
+         (s[i+1]=='"' || s[i+1]=='{' || s[i+1]=='}' || s[i+1]=='\\'))
+      {
+        i++;
+        offset++;
+      }
+      if(offset>0) s[i-offset] = s[i];
+    }
+    return(s);
+  }
+  else if(part==1)
+  { // load proc part - must exist
+    procbuflen = pi->data.s.def_end - pi->data.s.proc_start;
+    char *ss=(char *)omAlloc(procbuflen+2);
+    //fgets(buf, sizeof(buf), fp);
+    myfread( ss, procbuflen, 1, fp);
+    char ct;
+    char *e;
+    s=iiProcName(ss,ct,e);
+    char *argstr=NULL;
+    *e=ct;
+    argstr=iiProcArgs(e,TRUE);
+
+    assume(pi->data.s.body_end > pi->data.s.body_start);
+
+    procbuflen = pi->data.s.body_end - pi->data.s.body_start;
+    pi->data.s.body = (char *)omAlloc( strlen(argstr)+procbuflen+15+
+                                      strlen(pi->libname) );
+    //Print("Body=%ld-%ld=%d\n", pi->data.s.body_end,
+    //    pi->data.s.body_start, procbuflen);
+    assume(pi->data.s.body != NULL);
+    fseek(fp, pi->data.s.body_start, SEEK_SET);
+    strcpy(pi->data.s.body,argstr);
+    myfread( pi->data.s.body+strlen(argstr), procbuflen, 1, fp);
+    fclose( fp );
+    procbuflen+=strlen(argstr);
+    omFree(argstr);
+    omFree(ss);
+    pi->data.s.body[procbuflen] = '\0';
+    strcat( pi->data.s.body+procbuflen, "\n;return();\n\n" );
+    strcat( pi->data.s.body+procbuflen+13,pi->libname);
+    s=(char *)strchr(pi->data.s.body,'{');
+    if (s!=NULL) *s=' ';
+    return NULL;
+  }
+  else if(part==2)
+  { // example
+    if ( pi->data.s.example_lineno == 0)
+      return NULL; // example part does not exist
+    // load example
+    fseek(fp, pi->data.s.example_start, SEEK_SET);
+    /*char *dummy=*/ (void) fgets(buf, sizeof(buf), fp); // skip line with "example"
+    procbuflen = pi->data.s.proc_end - pi->data.s.example_start - strlen(buf);
+    //Print("Example=%ld-%ld=%d\n", pi->data.s.proc_end,
+    //  pi->data.s.example_start, procbuflen);
+    s = (char *)omAlloc(procbuflen+14);
+    myfread(s, procbuflen, 1, fp);
+    s[procbuflen] = '\0';
+    strcat(s+procbuflen-3, "\n;return();\n\n" );
+    p=(char *)strchr(s,'{');
+    if (p!=NULL) *p=' ';
+    return(s);
+  }
+  return NULL;
+}
+
+// see below:
+struct soptionStruct
+{
+  const char * name;
+  unsigned   setval;
+  unsigned   resetval;
+};
+extern struct soptionStruct optionStruct[];
+extern struct soptionStruct verboseStruct[];
+
+
+BOOLEAN iiAllStart(procinfov pi, char *p,feBufferTypes t, int l)
+{
+  // see below:
+  BITSET save1=si_opt_1;
+  BITSET save2=si_opt_2;
+  newBuffer( omStrDup(p /*pi->data.s.body*/), t /*BT_proc*/,
+               pi, l );
+  BOOLEAN err=yyparse();
+  if (sLastPrinted.rtyp!=0)
+  {
+    sLastPrinted.CleanUp();
+  }
+  // the access to optionStruct and verboseStruct do not work
+  // on x86_64-Linux for pic-code
+  if ((TEST_V_ALLWARN) &&
+  (t==BT_proc) &&
+  ((save1!=si_opt_1)||(save2!=si_opt_2)) &&
+  (pi->libname!=NULL) && (pi->libname[0]!='\0'))
+  {
+    if ((pi->libname!=NULL) && (pi->libname[0]!='\0'))
+      Warn("option changed in proc %s from %s",pi->procname,pi->libname);
+    else
+      Warn("option changed in proc %s",pi->procname);
+    int i;
+    for (i=0; optionStruct[i].setval!=0; i++)
+    {
+      if ((optionStruct[i].setval & si_opt_1)
+      && (!(optionStruct[i].setval & save1)))
+      {
+          Print(" +%s",optionStruct[i].name);
+      }
+      if (!(optionStruct[i].setval & si_opt_1)
+      && ((optionStruct[i].setval & save1)))
+      {
+          Print(" -%s",optionStruct[i].name);
+      }
+    }
+    for (i=0; verboseStruct[i].setval!=0; i++)
+    {
+      if ((verboseStruct[i].setval & si_opt_2)
+      && (!(verboseStruct[i].setval & save2)))
+      {
+          Print(" +%s",verboseStruct[i].name);
+      }
+      if (!(verboseStruct[i].setval & si_opt_2)
+      && ((verboseStruct[i].setval & save2)))
+      {
+          Print(" -%s",verboseStruct[i].name);
+      }
+    }
+    PrintLn();
+  }
+  return err;
+}
+/*2
+* start a proc
+* parameters are built as exprlist
+* TODO:interrupt
+* return FALSE on success, TRUE if an error occurs
+*/
+BOOLEAN iiPStart(idhdl pn, sleftv  * v)
+{
+  procinfov pi=NULL;
+  int old_echo=si_echo;
+  BOOLEAN err=FALSE;
+  char save_flags=0;
+
+  /* init febase ======================================== */
+  /* we do not enter this case if filename != NULL !! */
+  if (pn!=NULL)
+  {
+    pi = IDPROC(pn);
+    if(pi!=NULL)
+    {
+      save_flags=pi->trace_flag;
+      if( pi->data.s.body==NULL )
+      {
+        iiGetLibProcBuffer(pi);
+        if (pi->data.s.body==NULL) return TRUE;
+      }
+//      omUpdateInfo();
+//      int m=om_Info.UsedBytes;
+//      Print("proc %s, mem=%d\n",IDID(pn),m);
+    }
+  }
+  else return TRUE;
+  /* generate argument list ======================================*/
+  if (v!=NULL)
+  {
+    iiCurrArgs=(leftv)omAllocBin(sleftv_bin);
+    memcpy(iiCurrArgs,v,sizeof(sleftv));
+    memset(v,0,sizeof(sleftv));
+  }
+  else
+  {
+    iiCurrArgs=NULL;
+  }
+  iiCurrProc=pn;
+  /* start interpreter ======================================*/
+  myynest++;
+  if (myynest > SI_MAX_NEST)
+  {
+    WerrorS("nesting too deep");
+    err=TRUE;
+  }
+  else
+  {
+    err=iiAllStart(pi,pi->data.s.body,BT_proc,pi->data.s.body_lineno-(v!=NULL));
+
+#ifdef USE_IILOCALRING
+#if 0
+  if(procstack->cRing != iiLocalRing[myynest]) Print("iiMake_proc: 1 ring not saved procs:%x, iiLocal:%x\n",procstack->cRing, iiLocalRing[myynest]);
+#endif
+    if (iiLocalRing[myynest-1] != currRing)
+    {
+      if (iiRETURNEXPR.RingDependend())
+      {
+        //idhdl hn;
+        const char *n;
+        const char *o;
+        idhdl nh=NULL, oh=NULL;
+        if (iiLocalRing[myynest-1]!=NULL)
+          oh=rFindHdl(iiLocalRing[myynest-1],NULL);
+        if (oh!=NULL)          o=oh->id;
+        else                   o="none";
+        if (currRing!=NULL)
+          nh=rFindHdl(currRing,NULL);
+        if (nh!=NULL)          n=nh->id;
+        else                   n="none";
+        Werror("ring change during procedure call: %s -> %s (level %d)",o,n,myynest);
+        iiRETURNEXPR.CleanUp();
+        err=TRUE;
+      }
+      currRing=iiLocalRing[myynest-1];
+    }
+    if ((currRing==NULL)
+    && (currRingHdl!=NULL))
+      currRing=IDRING(currRingHdl);
+    else
+    if ((currRing!=NULL) &&
+      ((currRingHdl==NULL)||(IDRING(currRingHdl)!=currRing)
+       ||(IDLEV(currRingHdl)>=myynest-1)))
+    {
+      rSetHdl(rFindHdl(currRing,NULL));
+      iiLocalRing[myynest-1]=NULL;
+    }
+#else /* USE_IILOCALRING */
+    if (procstack->cRing != currRing)
+    {
+      //if (procstack->cRingHdl!=NULL)
+      //Print("procstack:%s,",IDID(procstack->cRingHdl));
+      //if (currRingHdl!=NULL)
+      //Print(" curr:%s\n",IDID(currRingHdl));
+      //Print("pr:%x, curr: %x\n",procstack->cRing,currRing);
+      if (iiRETURNEXPR.RingDependend())
+      {
+        //idhdl hn;
+        const char *n;
+        const char *o;
+        if (procstack->cRing!=NULL)
+        {
+          //PrintS("reset ring\n");
+          procstack->cRingHdl=rFindHdl(procstack->cRing,NULL);
+          o=IDID(procstack->cRingHdl);
+          currRing=procstack->cRing;
+          currRingHdl=procstack->cRingHdl;
+        }
+        else                            o="none";
+        if (currRing!=NULL)             n=IDID(currRingHdl);
+        else                            n="none";
+        if (currRing==NULL)
+        {
+          Werror("ring change during procedure call: %s -> %s (level %d)",o,n,myynest);
+          iiRETURNEXPR.CleanUp();
+          err=TRUE;
+        }
+      }
+      if (procstack->cRingHdl!=NULL)
+      {
+        rSetHdl(procstack->cRingHdl);
+      }
+      else
+      { currRingHdl=NULL; currRing=NULL; }
+    }
+#endif /* USE_IILOCALRING */
+    //Print("kill locals for %s (level %d)\n",IDID(pn),myynest);
+    killlocals(myynest);
+#ifndef SING_NDEBUG
+    checkall();
+#endif
+    //Print("end kill locals for %s (%d)\n",IDID(pn),myynest);
+  }
+  myynest--;
+  si_echo=old_echo;
+  if (pi!=NULL)
+    pi->trace_flag=save_flags;
+//  omUpdateInfo();
+//  int m=om_Info.UsedBytes;
+//  Print("exit %s, mem=%d\n",IDID(pn),m);
+  return err;
+}
+
+#ifdef USE_IILOCALRING
+ring    *iiLocalRing;
+#endif
+sleftv  iiRETURNEXPR;
+int     iiRETURNEXPR_len=0;
+
+#ifdef RDEBUG
+static void iiShowLevRings()
+{
+  int i;
+#ifdef USE_IILOCALRING
+  for (i=0;i<=myynest;i++)
+  {
+    Print("lev %d:",i);
+    if (iiLocalRing[i]==NULL) PrintS("NULL");
+    else                      Print("%lx",(long)iiLocalRing[i]);
+    PrintLn();
+  }
+#endif
+#if  0
+  i=myynest;
+  proclevel *p=procstack;
+  while (p!=NULL)
+  {
+    Print("lev %d:",i);
+    if (p->cRingHdl==NULL) PrintS("NULL");
+    else                   Print("%s",IDID(p->cRingHdl));
+    PrintLn();
+    p=p->next;
+  }
+#endif
+  if (currRing==NULL) PrintS("curr:NULL\n");
+  else                Print ("curr:%lx\n",(long)currRing);
+}
+#endif /* RDEBUG */
+
+static void iiCheckNest()
+{
+  if (myynest >= iiRETURNEXPR_len-1)
+  {
+#ifdef USE_IILOCALRING
+    iiLocalRing=(ring *)omreallocSize(iiLocalRing,
+                                   iiRETURNEXPR_len*sizeof(ring),
+                                   (iiRETURNEXPR_len+16)*sizeof(ring));
+    memset(&(iiLocalRing[iiRETURNEXPR_len]),0,16*sizeof(ring));
+#endif
+    iiRETURNEXPR_len+=16;
+  }
+}
+BOOLEAN iiMake_proc(idhdl pn, package pack, sleftv* sl)
+{
+  int err;
+  procinfov pi = IDPROC(pn);
+  if(pi->is_static && myynest==0)
+  {
+    Werror("'%s::%s()' is a local procedure and cannot be accessed by an user.",
+           pi->libname, pi->procname);
+    return TRUE;
+  }
+  iiCheckNest();
+#ifdef USE_IILOCALRING
+  iiLocalRing[myynest]=currRing;
+  //Print("currRing(%d):%s(%x) in %s\n",myynest,IDID(currRingHdl),currRing,IDID(pn));
+#endif
+  iiRETURNEXPR.Init();
+  procstack->push(pi->procname);
+  if ((traceit&TRACE_SHOW_PROC)
+  || (pi->trace_flag&TRACE_SHOW_PROC))
+  {
+    if (traceit&TRACE_SHOW_LINENO) PrintLn();
+    Print("entering%-*.*s %s (level %d)\n",myynest*2,myynest*2," ",IDID(pn),myynest);
+  }
+#ifdef RDEBUG
+  if (traceit&TRACE_SHOW_RINGS) iiShowLevRings();
+#endif
+  switch (pi->language)
+  {
+    default:
+    case LANG_NONE:
+                 WerrorS("undefined proc");
+                 err=TRUE;
+                 break;
+
+    case LANG_SINGULAR:
+                 if ((pi->pack!=NULL)&&(currPack!=pi->pack))
+                 {
+                   currPack=pi->pack;
+                   iiCheckPack(currPack);
+                   currPackHdl=packFindHdl(currPack);
+                   //Print("set pack=%s\n",IDID(currPackHdl));
+                 }
+                 else if ((pack!=NULL)&&(currPack!=pack))
+                 {
+                   currPack=pack;
+                   iiCheckPack(currPack);
+                   currPackHdl=packFindHdl(currPack);
+                   //Print("set pack=%s\n",IDID(currPackHdl));
+                 }
+                 err=iiPStart(pn,sl);
+                 break;
+    case LANG_C:
+                 leftv res = (leftv)omAlloc0Bin(sleftv_bin);
+                 err = (pi->data.o.function)(res, sl);
+                 memcpy(&iiRETURNEXPR,res,sizeof(iiRETURNEXPR));
+                 omFreeBin((ADDRESS)res,  sleftv_bin);
+                 break;
+  }
+  if ((traceit&TRACE_SHOW_PROC)
+  || (pi->trace_flag&TRACE_SHOW_PROC))
+  {
+    if (traceit&TRACE_SHOW_LINENO) PrintLn();
+    Print("leaving %-*.*s %s (level %d)\n",myynest*2,myynest*2," ",IDID(pn),myynest);
+  }
+  //const char *n="NULL";
+  //if (currRingHdl!=NULL) n=IDID(currRingHdl);
+  //Print("currRing(%d):%s(%x) after %s\n",myynest,n,currRing,IDID(pn));
+#ifdef RDEBUG
+  if (traceit&TRACE_SHOW_RINGS) iiShowLevRings();
+#endif
+  if (err)
+  {
+    iiRETURNEXPR.CleanUp();
+    //iiRETURNEXPR.Init(); //done by CleanUp
+  }
+  if (iiCurrArgs!=NULL)
+  {
+    if (!err) Warn("too many arguments for %s",IDID(pn));
+    iiCurrArgs->CleanUp();
+    omFreeBin((ADDRESS)iiCurrArgs, sleftv_bin);
+    iiCurrArgs=NULL;
+  }
+  procstack->pop();
+  if (err)
+    return TRUE;
+  return FALSE;
+}
+
+/*2
+* start an example (as a proc),
+* destroys the string 'example'
+*/
+BOOLEAN iiEStart(char* example, procinfo *pi)
+{
+  BOOLEAN err;
+  int old_echo=si_echo;
+
+  iiCheckNest();
+  procstack->push(example);
+#ifdef USE_IILOCALRING
+  iiLocalRing[myynest]=currRing;
+#endif
+  if (traceit&TRACE_SHOW_PROC)
+  {
+    if (traceit&TRACE_SHOW_LINENO) printf("\n");
+    printf("entering example (level %d)\n",myynest);
+  }
+  myynest++;
+
+  err=iiAllStart(pi,example,BT_example,(pi != NULL ? pi->data.s.example_lineno: 0));
+
+  killlocals(myynest);
+  myynest--;
+  si_echo=old_echo;
+  if (traceit&TRACE_SHOW_PROC)
+  {
+    if (traceit&TRACE_SHOW_LINENO) printf("\n");
+    printf("leaving  -example- (level %d)\n",myynest);
+  }
+#ifdef USE_IILOCALRING
+  if (iiLocalRing[myynest] != currRing)
+  {
+    if (iiLocalRing[myynest]!=NULL)
+    {
+      rSetHdl(rFindHdl(iiLocalRing[myynest],NULL));
+      iiLocalRing[myynest]=NULL;
+    }
+    else
+    {
+      currRingHdl=NULL;
+      currRing=NULL;
+    }
+  }
+#else /* USE_IILOCALRING */
+#endif /* USE_IILOCALRING */
+  if (NS_LRING != currRing)
+  {
+    if (NS_LRING!=NULL)
+    {
+      idhdl rh=procstack->cRingHdl;
+      if ((rh==NULL)||(IDRING(rh)!=NS_LRING))
+        rh=rFindHdl(NS_LRING,NULL);
+      rSetHdl(rh);
+    }
+    else
+    {
+      currRingHdl=NULL;
+      currRing=NULL;
+    }
+  }
+//#endif /* USE_IILOCALRING */
+  procstack->pop();
+  return err;
+}
+
+
+extern "C"
+{
+#  define SI_GET_BUILTIN_MOD_INIT0(name) int SI_MOD_INIT0(name)(SModulFunctions*);
+          SI_FOREACH_BUILTIN(SI_GET_BUILTIN_MOD_INIT0)
+#  undef  SI_GET_BUILTIN_MOD_INIT0
+};
+
+
+SModulFunc_t
+iiGetBuiltinModInit(const char* libname)
+{
+#  define SI_GET_BUILTIN_MOD_INIT(name) if (strcmp(libname, #name ".so") == 0){ return SI_MOD_INIT0(name); }
+          SI_FOREACH_BUILTIN(SI_GET_BUILTIN_MOD_INIT)
+#  undef  SI_GET_BUILTIN_MOD_INIT
+
+  return NULL;
+}
+
+
+
+
+/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
+BOOLEAN iiTryLoadLib(leftv v, const char *id)
+{
+  BOOLEAN LoadResult = TRUE;
+  char libnamebuf[128];
+  char *libname = (char *)omAlloc(strlen(id)+5);
+  const char *suffix[] = { "", ".lib", ".so", ".sl", NULL };
+  int i = 0;
+  // FILE *fp;
+  // package pack;
+  // idhdl packhdl;
+  lib_types LT;
+  for(i=0; suffix[i] != NULL; i++)
+  {
+    sprintf(libname, "%s%s", id, suffix[i]);
+    *libname = mytolower(*libname);
+    if((LT = type_of_LIB(libname, libnamebuf)) > LT_NOTFOUND)
+    {
+      char *s=omStrDup(libname);
+      char libnamebuf[256];
+
+      if (LT==LT_SINGULAR)
+        LoadResult = iiLibCmd(s, FALSE, FALSE,TRUE);
+      #ifdef HAVE_DYNAMIC_LOADING
+      else if ((LT==LT_ELF) || (LT==LT_HPUX))
+        LoadResult = load_modules(s,libnamebuf,FALSE);
+      #endif
+      else if (LT==LT_BUILTIN)
+      {
+        LoadResult=load_builtin(s,FALSE, iiGetBuiltinModInit(s));
+      }
+      if(!LoadResult )
+      {
+        v->name = iiConvName(libname);
+        break;
+      }
+    }
+  }
+  omFree(libname);
+  return LoadResult;
+}
+
+/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
+/* check, if library lib has already been loaded
+   if yes, writes filename of lib into where and returns TRUE,
+      no, returns FALSE
+*/
+BOOLEAN iiLocateLib(const char* lib, char* where)
+{
+  char *plib = iiConvName(lib);
+  idhdl pl = basePack->idroot->get(plib,0);
+  if( (pl!=NULL) && (IDTYP(pl)==PACKAGE_CMD) &&
+    (IDPACKAGE(pl)->language == LANG_SINGULAR))
+  {
+    strncpy(where,IDPACKAGE(pl)->libname,127);
+    return TRUE;
+  }
+  else
+    return FALSE;;
+}
+
+BOOLEAN iiLibCmd( char *newlib, BOOLEAN autoexport, BOOLEAN tellerror, BOOLEAN force )
+{
+  char libnamebuf[128];
+  // procinfov pi;
+  // idhdl h;
+  idhdl pl;
+  // idhdl hl;
+  // long pos = 0L;
+  char *plib = iiConvName(newlib);
+  FILE * fp = feFopen( newlib, "r", libnamebuf, tellerror );
+  // int lines = 1;
+  BOOLEAN LoadResult = TRUE;
+
+  if (fp==NULL)
+  {
+    return TRUE;
+  }
+  pl = basePack->idroot->get(plib,0);
+  if (pl==NULL)
+  {
+    pl = enterid( plib,0, PACKAGE_CMD,
+                  &(basePack->idroot), TRUE );
+    IDPACKAGE(pl)->language = LANG_SINGULAR;
+    IDPACKAGE(pl)->libname=omStrDup(newlib);
+  }
+  else
+  {
+    if(IDTYP(pl)!=PACKAGE_CMD)
+    {
+      WarnS("not of type package.");
+      fclose(fp);
+      return TRUE;
+    }
+    if (!force) return FALSE;
+  }
+  LoadResult = iiLoadLIB(fp, libnamebuf, newlib, pl, autoexport, tellerror);
+  omFree((ADDRESS)newlib);
+
+  if(!LoadResult) IDPACKAGE(pl)->loaded = TRUE;
+  omFree((ADDRESS)plib);
+
+ return LoadResult;
+}
+/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
+static void iiCleanProcs(idhdl &root)
+{
+  idhdl prev=NULL;
+  loop
+  {
+    if (root==NULL) return;
+    if (IDTYP(root)==PROC_CMD)
+    {
+      procinfo *pi=(procinfo*)IDDATA(root);
+      if ((pi->language == LANG_SINGULAR)
+      && (pi->data.s.body_start == 0L))
+      {
+        // procinfo data incorrect:
+        // - no proc body can start at the beginning of the file
+        killhdl(root);
+        if (prev==NULL)
+          root=IDROOT;
+        else
+        {
+          root=prev;
+          prev=NULL;
+        }
+        continue;
+      }
+    }
+    prev=root;
+    root=IDNEXT(root);
+  }
+}
+static void iiRunInit(package p)
+{
+  idhdl h=p->idroot->get("mod_init",0);
+  if (h==NULL) return;
+  if (IDTYP(h)==PROC_CMD)
+  {
+    int save=yylineno;
+    myynest++;
+    // procinfo *pi=(procinfo*)IDDATA(h);
+    //PrintS("mod_init found\n");
+    iiMake_proc(h,p,NULL);
+    myynest--;
+    yylineno=save;
+  }
+}
+/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
+BOOLEAN iiLoadLIB(FILE *fp, const char *libnamebuf, const char*newlib,
+             idhdl pl, BOOLEAN autoexport, BOOLEAN tellerror)
+{
+  extern FILE *yylpin;
+  libstackv ls_start = library_stack;
+  lib_style_types lib_style;
+
+  yylpin = fp;
+  #if YYLPDEBUG > 1
+  print_init();
+  #endif
+  extern int lpverbose;
+  if (BVERBOSE(V_DEBUG_LIB)) lpverbose=1;
+  else lpverbose=0;
+  // yylplex sets also text_buffer
+  if (text_buffer!=NULL) *text_buffer='\0';
+  yylplex(newlib, libnamebuf, &lib_style, pl, autoexport);
+  if(yylp_errno)
+  {
+    Werror("Library %s: ERROR occured: in line %d, %d.", newlib, yylplineno,
+         current_pos(0));
+    if(yylp_errno==YYLP_BAD_CHAR)
+    {
+      Werror(yylp_errlist[yylp_errno], *text_buffer, yylplineno);
+      omFree((ADDRESS)text_buffer);
+      text_buffer=NULL;
+    }
+    else
+      Werror(yylp_errlist[yylp_errno], yylplineno);
+    Werror("Cannot load library,... aborting.");
+    reinit_yylp();
+    fclose( yylpin );
+    iiCleanProcs(IDROOT);
+    return TRUE;
+  }
+  if (BVERBOSE(V_LOAD_LIB))
+    Print( "// ** loaded %s %s\n", libnamebuf, text_buffer);
+  if( (lib_style == OLD_LIBSTYLE) && (BVERBOSE(V_LOAD_LIB)))
+  {
+    Warn( "library %s has old format. This format is still accepted,", newlib);
+    Warn( "but for functionality you may wish to change to the new");
+    Warn( "format. Please refer to the manual for further information.");
+  }
+  reinit_yylp();
+  fclose( yylpin );
+  fp = NULL;
+  iiRunInit(IDPACKAGE(pl));
+
+  {
+    libstackv ls;
+    for(ls = library_stack; (ls != NULL) && (ls != ls_start); )
+    {
+      if(ls->to_be_done)
+      {
+        ls->to_be_done=FALSE;
+        iiLibCmd(ls->get(),autoexport,tellerror,FALSE);
+        ls = ls->pop(newlib);
+      }
+    }
+#if 0
+    PrintS("--------------------\n");
+    for(ls = library_stack; ls != NULL; ls = ls->next)
+    {
+      Print("%s: LIB-stack:(%d), %s %s\n", newlib, ls->cnt, ls->get(),
+        ls->to_be_done ? "not loaded" : "loaded");
+    }
+    PrintS("--------------------\n");
+#endif
+  }
+
+  if(fp != NULL) fclose(fp);
+  return FALSE;
+}
+
+
+/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
+procinfo *iiInitSingularProcinfo(procinfov pi, const char *libname,
+              const char *procname, int line, long pos, BOOLEAN pstatic)
+{
+  pi->libname = omStrDup(libname);
+  pi->procname = omStrDup(procname);
+  pi->language = LANG_SINGULAR;
+  pi->ref = 1;
+  pi->pack = NULL;
+  pi->is_static = pstatic;
+  pi->data.s.proc_start = pos;
+  pi->data.s.def_end    = 0L;
+  pi->data.s.help_start = 0L;
+  pi->data.s.help_end   = 0L;
+  pi->data.s.body_start = 0L;
+  pi->data.s.body_end   = 0L;
+  pi->data.s.example_start = 0L;
+  pi->data.s.proc_lineno = line;
+  pi->data.s.body_lineno = 0;
+  pi->data.s.example_lineno = 0;
+  pi->data.s.body = NULL;
+  pi->data.s.help_chksum = 0;
+  return(pi);
+}
+
+/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
+int iiAddCproc(const char *libname, const char *procname, BOOLEAN pstatic,
+               BOOLEAN(*func)(leftv res, leftv v))
+{
+  procinfov pi;
+  idhdl h;
+
+  #ifndef SING_NDEBUG
+  int dummy;
+  if (IsCmd(procname,dummy))
+  {
+    Werror(">>%s< is a reserved name",procname);
+    return 0;
+  }
+  #endif
+
+  h = enterid(procname,0, PROC_CMD, &IDROOT, TRUE);
+  if ( h!= NULL )
+  {
+    pi = IDPROC(h);
+    pi->libname = omStrDup(libname);
+    pi->procname = omStrDup(procname);
+    pi->language = LANG_C;
+    pi->ref = 1;
+    pi->is_static = pstatic;
+    pi->data.o.function = func;
+    return(1);
+  }
+  else
+  {
+    PrintS("iiAddCproc: failed.\n");
+  }
+  return(0);
+}
+
+int iiAddCprocTop(const char *libname, const char *procname, BOOLEAN pstatic,
+               BOOLEAN(*func)(leftv res, leftv v))
+{
+  int r=iiAddCproc(libname,procname,pstatic,func);
+  package s=currPack;
+  currPack=basePack;
+  if (r) r=iiAddCproc(libname,procname,pstatic,func);
+  currPack=s;
+  return r;
+}
+
+/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
+#ifdef HAVE_DYNAMIC_LOADING
+BOOLEAN load_modules(const char *newlib, char *fullname, BOOLEAN autoexport)
+{
+#ifdef HAVE_STATIC
+  WerrorS("mod_init: static version can not load modules");
+  return TRUE;
+#else
+/*
+  typedef int (*fktn_t)(int(*iiAddCproc)(const char *libname, const char *procname,
+                               BOOLEAN pstatic,
+                               BOOLEAN(*func)(leftv res, leftv v)));
+*/
+  SModulFunc_t fktn;
+  idhdl pl;
+  char *plib = iiConvName(newlib);
+  BOOLEAN RET=TRUE;
+  int token;
+  char FullName[256];
+
+  memset(FullName,0,256);
+
+  if( *fullname != '/' &&  *fullname != '.' )
+    sprintf(FullName, "./%s", newlib);
+  else strncpy(FullName, fullname,255);
+
+
+  if(IsCmd(plib, token))
+  {
+    Werror("'%s' is resered identifier\n", plib);
+    goto load_modules_end;
+  }
+  pl = IDROOT->get(plib,0);
+  if (pl==NULL)
+  {
+    pl = enterid( plib,0, PACKAGE_CMD, &IDROOT,
+                  TRUE );
+    IDPACKAGE(pl)->language = LANG_C;
+    IDPACKAGE(pl)->libname=omStrDup(newlib);
+  }
+  else
+  {
+    if(IDTYP(pl)!=PACKAGE_CMD)
+    {
+      Warn("not of type package.");
+      goto load_modules_end;
+    }
+  }
+  if (dynl_check_opened(FullName))
+  {
+    if (BVERBOSE(V_LOAD_LIB)) Warn( "%s already loaded", fullname);
+    return FALSE;
+  }
+  if((IDPACKAGE(pl)->handle=dynl_open(FullName))==(void *)NULL)
+  {
+    Werror("dynl_open failed:%s", dynl_error());
+    Werror("%s not found", newlib);
+    goto load_modules_end;
+  }
+  else
+  {
+    SModulFunctions sModulFunctions;
+
+    package s=currPack;
+    currPack=IDPACKAGE(pl);
+    fktn = (SModulFunc_t)dynl_sym(IDPACKAGE(pl)->handle, "mod_init");
+    if( fktn!= NULL)
+    {
+      sModulFunctions.iiArithAddCmd = iiArithAddCmd;
+      if (autoexport) sModulFunctions.iiAddCproc = iiAddCprocTop;
+      else            sModulFunctions.iiAddCproc = iiAddCproc;
+      int ver=(*fktn)(&sModulFunctions);
+      if (ver==MAX_TOK)
+      {
+        if (BVERBOSE(V_LOAD_LIB)) Print( "// ** loaded %s\n", fullname);
+      }
+      else
+      {
+        Warn("// ** loaded %s for a different version of Singular(expected: %d, got %d)",fullname,MAX_TOK,ver);
+      }
+      currPack->loaded=1;
+      currPack=s;
+      RET=FALSE;
+    }
+    else Werror("mod_init not found:: %s\nThis is probably not a dynamic module for Singular!\n", dynl_error());
+  }
+
+  load_modules_end:
+  return RET;
+#endif /*STATIC */
+}
+#endif /* HAVE_DYNAMIC_LOADING */
+/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
+BOOLEAN load_builtin(const char *newlib, BOOLEAN autoexport, SModulFunc_t init)
+{
+  int iiAddCproc(const char *libname, const char *procname, BOOLEAN pstatic,
+                 BOOLEAN(*func)(leftv res, leftv v));
+/*
+  typedef int (*fktn_t)(int(*iiAddCproc)(const char *libname, const char *procname,
+                               BOOLEAN pstatic,
+                               BOOLEAN(*func)(leftv res, leftv v)));
+*/
+  // SModulFunc_t fktn;
+  idhdl pl;
+  char *plib = iiConvName(newlib);
+  // BOOLEAN RET=TRUE;
+  // int token;
+
+  pl = IDROOT->get(plib,0);
+  if (pl!=NULL)
+  {
+    if (BVERBOSE(V_LOAD_LIB)) Warn( "(builtin) %s already loaded", newlib);
+    omFree(plib);
+    return FALSE;
+  }
+
+  pl = enterid( plib,0, PACKAGE_CMD, &IDROOT,
+                TRUE );
+  IDPACKAGE(pl)->language = LANG_C;
+  IDPACKAGE(pl)->libname=omStrDup(newlib);
+
+  IDPACKAGE(pl)->handle=(void *)NULL;
+  SModulFunctions sModulFunctions;
+
+  package s=currPack;
+  currPack=IDPACKAGE(pl);
+  if( init!= NULL)
+  {
+    sModulFunctions.iiArithAddCmd = iiArithAddCmd;
+    if (autoexport) sModulFunctions.iiAddCproc = iiAddCprocTop;
+    else            sModulFunctions.iiAddCproc = iiAddCproc;
+    (*init)(&sModulFunctions);
+  }
+  if (BVERBOSE(V_LOAD_LIB)) Print( "// ** loaded (builtin) %s \n", newlib);
+  currPack->loaded=1;
+  currPack=s;
+
+  return FALSE;
+}
+/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
+void module_help_main(const char *newlib,const char *help)
+{
+  char *plib = iiConvName(newlib);
+  idhdl pl = basePack->idroot->get(plib,0);
+  if ((pl==NULL)||(IDTYP(pl)!=PACKAGE_CMD))
+    Werror(">>%s<< is not a package (trying to add package help)",plib);
+  else
+  {
+    package s=currPack;
+    currPack=IDPACKAGE(pl);
+    idhdl h=enterid(omStrDup("info"),0,STRING_CMD,&IDROOT,FALSE);
+    IDSTRING(h)=omStrDup(help);
+    currPack=s;
+  }
+}
+void module_help_proc(const char *newlib,const char *p, const char *help)
+{
+  char *plib = iiConvName(newlib);
+  idhdl pl = basePack->idroot->get(plib,0);
+  if ((pl==NULL)||(IDTYP(pl)!=PACKAGE_CMD))
+    Werror(">>%s<< is not a package(trying to add help for %s)",plib,p);
+  else
+  {
+    package s=currPack;
+    currPack=IDPACKAGE(pl);
+    char buff[256];
+    buff[255]='\0';
+    strncpy(buff,p,255);
+    strncat(buff,"_help",255-strlen(p));
+    idhdl h=enterid(omStrDup(buff),0,STRING_CMD,&IDROOT,FALSE);
+    IDSTRING(h)=omStrDup(help);
+    currPack=s;
+  }
+}
+/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
+
+// loads a dynamic module from the binary path and returns a named function
+// returns NULL, if something fails
+void* binary_module_function(const char* newlib, const char* funcname)
+{
+  void* result = NULL;
+
+#if defined(HAVE_STATIC) || !defined(HAVE_DYNAMIC_LOADING)
+  WerrorS("static version can not load function from dynamic modules");
+#else
+  const char* bin_dir = feGetResource('b');
+  if (!bin_dir)  { return NULL; }
+
+  char path_name[MAXPATHLEN];
+  sprintf(path_name, "%s%s%s.%s", bin_dir, DIR_SEPP, newlib, MODULE_SUFFIX_STRING);
+
+  void* openlib = dynl_open(path_name);
+  if(!openlib)
+  {
+    Werror("dynl_open of %s failed:%s", path_name, dynl_error());
+    return NULL;
+  }
+  result = dynl_sym(openlib, funcname);
+  if (!result) Werror("%s: %s\n", funcname, dynl_error());
+#endif
+
+  return result;
+}
+
+
+/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
+char mytoupper(char c)
+{
+  if(c>=97 && c<=(97+26)) c-=32;
+  return(c);
+}
+
+char mytolower(char c)
+{
+  if(c>=65 && c<=(65+26)) c+=32;
+  return(c);
+}
+
+/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
+//#if defined(WINNT)
+//#  define  FS_SEP '\\'
+//#else
+//#  define FS_SEP '/'
+//#endif
+
+char *iiConvName(const char *libname)
+{
+  char *tmpname = omStrDup(libname);
+  char *p = strrchr(tmpname, DIR_SEP);
+  char *r;
+  if(p==NULL) p = tmpname;
+  else p++;
+  r = (char *)strchr(p, '.');
+  if( r!= NULL) *r = '\0';
+  r = omStrDup(p);
+  *r = mytoupper(*r);
+  // printf("iiConvName: '%s' '%s' => '%s'\n", libname, tmpname, r);
+  omFree((ADDRESS)tmpname);
+
+  return(r);
+}
+
+/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
+#if 0 /* debug only */
+void piShowProcList()
+{
+  idhdl h;
+  procinfo *proc;
+  char *name;
+
+  Print( "%-15s  %20s      %s,%s  %s,%s   %s,%s\n", "Library", "function",
+         "line", "start", "line", "body", "line", "example");
+  for(h = IDROOT; h != NULL; h = IDNEXT(h))
+  {
+    if(IDTYP(h) == PROC_CMD)
+    {
+      proc = IDPROC(h);
+      if(strcmp(proc->procname, IDID(h))!=0)
+      {
+        name = (char *)omAlloc(strlen(IDID(h))+strlen(proc->procname)+4);
+        sprintf(name, "%s -> %s", IDID(h), proc->procname);
+        Print( "%d %-15s  %20s ", proc->is_static ? 1 : 0, proc->libname, name);
+        omFree((ADDRESS)name);
+      }
+      else
+        Print( "%d %-15s  %20s ", proc->is_static ? 1 : 0, proc->libname,
+               proc->procname);
+      if(proc->language==LANG_SINGULAR)
+        Print("line %4d,%-5ld  %4d,%-5ld  %4d,%-5ld\n",
+              proc->data.s.proc_lineno, proc->data.s.proc_start,
+              proc->data.s.body_lineno, proc->data.s.body_start,
+              proc->data.s.example_lineno, proc->data.s.example_start);
+      else if(proc->language==LANG_C)
+        Print("type: object\n");
+    }
+  }
+}
+#endif
+
+/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
+//char *iiLineNo(char *procname, int lineno)
+//{
+//  char buf[256];
+//  idhdl pn = ggetid(procname);
+//  procinfo *pi = IDPROC(pn);
+//
+//  sprintf(buf, "%s %3d\0", procname, lineno);
+//  //sprintf(buf, "%s::%s %3d\0", pi->libname, pi->procname,
+//  //  lineno + pi->data.s.body_lineno);
+//  return(buf);
+//}
+/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
+#ifdef HAVE_LIBPARSER
+void libstack::push(const char */*p*/, char *libn)
+{
+  libstackv lp;
+  if( !iiGetLibStatus(libn))
+  {
+    for(lp = this;lp!=NULL;lp=lp->next)
+    {
+      if(strcmp(lp->get(), libn)==0) break;
+    }
+    if(lp==NULL)
+    {
+      libstackv ls = (libstack *)omAlloc0Bin(libstack_bin);
+      ls->next = this;
+      ls->libname = omStrDup(libn);
+      ls->to_be_done = TRUE;
+      if(this != NULL) ls->cnt = this->cnt+1; else ls->cnt = 0;
+      library_stack = ls;
+    }
+  }
+}
+
+libstackv libstack::pop(const char */*p*/)
+{
+  libstackv ls = this;
+  //omFree((ADDRESS)ls->libname);
+  library_stack = ls->next;
+  omFreeBin((ADDRESS)ls,  libstack_bin);
+  return(library_stack);
+}
+
+#endif /* HAVE_LIBPARSER */
+/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
diff --git a/Singular/ipprint.cc b/Singular/ipprint.cc
new file mode 100644
index 0000000..a935ea0
--- /dev/null
+++ b/Singular/ipprint.cc
@@ -0,0 +1,473 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: interpreter: printing
+*/
+
+
+
+
+#include <kernel/mod2.h>
+#include <omalloc/omalloc.h>
+
+#include <misc/intvec.h>
+
+#include <polys/matpol.h>
+
+#include <kernel/polys.h>
+#include <kernel/ideals.h>
+
+#include "tok.h"
+#include "ipid.h"
+#include "subexpr.h"
+#include "ipshell.h"
+#include "ipprint.h"
+#include "attrib.h"
+
+/*2
+* print for: int, string, poly, vector, ideal
+*/
+/*2
+* print for: intvec
+*/
+static BOOLEAN ipPrint_INTVEC(leftv u)
+{
+  intvec *v=(intvec *)u->Data();
+  v->show();
+  PrintLn();
+  return FALSE;
+}
+
+/*2
+* print for: intmat
+*/
+static BOOLEAN ipPrint_INTMAT(leftv u)
+{
+  intvec *v=(intvec *)u->Data();
+  int i,j;
+  for(i=0;i<v->rows();i++)
+  {
+    for(j=0;j<v->cols();j++)
+    {
+      Print(" %5d",IMATELEM(*v,i+1,j+1));
+    }
+    PrintLn();
+  }
+  return FALSE;
+}
+
+/*2
+* internal print for: matrix
+*/
+static void ipPrint_MA0(matrix m, const char *name)
+{
+  if (MATCOLS(m)>0)
+  {
+    char **s=(char **)omAlloc(MATCOLS(m)*MATROWS(m)*sizeof(char*));
+    char *ss;
+    int *l=(int *)omAlloc0(MATCOLS(m)*sizeof(int));
+    int i,j,k;
+    int vl=si_max(colmax/MATCOLS(m),8);
+
+    /* make enough space for the "largest" name*/
+    ss=(char *)omAlloc(14+strlen(name));
+    sprintf(ss,"%s[%d,%d]",name,MATCOLS(m),MATROWS(m));
+    vl=si_max(vl,(int)strlen(ss));
+    omFree(ss);
+
+    /* convert all polys to string */
+    i=MATCOLS(m)*MATROWS(m)-1;
+    ss=pString(m->m[i]);
+    if ((int)strlen(ss)>colmax) { s[i]=NULL; omFree(ss); }
+    else                        s[i]=ss;
+    for(i--;i>=0;i--)
+    {
+      StringSetS("");
+      pString0(m->m[i]);
+      StringAppendS(",");
+      ss=StringEndS();
+      if ((int)strlen(ss)>colmax) s[i]=NULL;
+      else                        s[i]=ss;
+    }
+    /* look up the width of all columns, put it in l[col_nr] */
+    /* insert names for very long entries */
+    for(i=MATROWS(m)-1;i>=0;i--)
+    {
+      for(j=MATCOLS(m)-1;j>=0;j--)
+      {
+        if (s[i*MATCOLS(m)+j]==NULL)
+        {
+          ss=(char *)omAlloc(14+strlen(name));
+          s[i*MATCOLS(m)+j]=ss;
+          ss[0]='\0';
+          sprintf(ss,"%s[%d,%d]",name,i+1,j+1);
+          if ((i!=MATROWS(m)-1) || (j!=MATCOLS(m)-1))
+          {
+            strcat(ss,",");
+            vl=si_max(vl,(int)strlen(ss));
+          }
+        }
+        k=strlen(s[i*MATCOLS(m)+j]);
+        if (k>l[j]) l[j]=k;
+      }
+    }
+    /* does it fit on a line ? */
+    int maxlen=0;
+    for(j=MATCOLS(m)-1;j>=0;j--)
+    {
+      maxlen+=l[j];
+    }
+    if (maxlen>colmax)
+    {
+      /* NO, it does not fit, so retry: */
+      /* look up the width of all columns, clear very long entriess */
+      /* put length in l[col_nr] */
+      /* insert names for cleared entries */
+      for(j=MATCOLS(m)-1;j>=0;j--)
+      {
+        for(i=MATROWS(m)-1;i>=0;i--)
+        {
+          k=strlen(s[i*MATCOLS(m)+j]);
+          if (/*strlen(s[i*MATCOLS(m)+j])*/ k > vl)
+          {
+            omFree((ADDRESS)s[i*MATCOLS(m)+j]);
+            ss=(char *)omAlloc(14+strlen(name));
+            s[i*MATCOLS(m)+j]=ss;
+            ss[0]='\0';
+            sprintf(ss,"%s[%d,%d]",name,i+1,j+1);
+            if ((i!=MATROWS(m)-1) || (j!=MATCOLS(m)-1))
+            {
+              strcat(ss,",");
+            }
+            l[j]=strlen(s[i*MATCOLS(m)+j]);
+            if (l[j]>vl)
+            {
+//#ifdef TEST
+//              PrintS("pagewidth too small in print(matrix)\n");
+//#endif
+              vl=l[j]; /* make large names fit*/
+            }
+            i=MATROWS(m);
+          }
+          else
+          {
+            if (k>l[j]) l[j]=k;
+          }
+        }
+      }
+    }
+    /*output of the matrix*/
+    for(i=0;i<MATROWS(m);i++)
+    {
+      k=l[0];
+      Print("%-*.*s",l[0],l[0],s[i*MATCOLS(m)]);
+      omFree(s[i*MATCOLS(m)]);
+      for(j=1;j<MATCOLS(m);j++)
+      {
+        if (k+l[j]>colmax)
+        {
+          PrintS("\n  ");
+          k=2;
+        }
+        k+=l[j];
+        Print("%-*.*s",l[j],l[j],s[i*MATCOLS(m)+j]);
+        omFree(s[i*MATCOLS(m)+j]);
+      }
+      PrintLn();
+    }
+    /* clean up */
+    omFreeSize((ADDRESS)s,MATCOLS(m)*MATROWS(m)*sizeof(char*));
+    omFreeSize((ADDRESS)l,MATCOLS(m)*sizeof(int));
+  }
+}
+
+/*2
+* print for: matrix
+*/
+static BOOLEAN ipPrint_MA(leftv u)
+{
+  matrix m=(matrix)u->Data();
+  ipPrint_MA0(m,u->Name());
+  return FALSE;
+}
+
+/*2
+* print for: ring
+*/
+static BOOLEAN ipPrint_RING(leftv u)
+{
+  ring r=(ring)u->Data();
+  PrintS("polynomial ring, over a ");
+  if (rField_is_Ring(r))
+  {
+    if (rField_is_Domain(r)) PrintS("domain");
+    else                     PrintS("ring (with zero-divisors)");
+  }
+  else PrintS("field");
+  if (r->OrdSgn==1) PrintS(", global"); else PrintS(", local/mixed");
+  PrintS(" ordering\n");
+  rWrite(r, TRUE);
+  return FALSE;
+}
+
+#ifdef SINGULAR_4_1
+static BOOLEAN ipPrint_CRING(leftv u)
+{
+  coeffs r=(coeffs)u->Data();
+  if (nCoeff_is_Ring(r))
+  {
+    if (nCoeff_is_Domain(r)) PrintS("domain: ");
+    else                     PrintS("ring (with zero-divisors): ");
+  }
+  else PrintS("field: ");
+  PrintS(nCoeffName(r));
+  return FALSE;
+}
+#endif
+/*2
+* print for: vector
+*/
+static BOOLEAN ipPrint_V(leftv u)
+{
+  polyset m=NULL;
+  int l,j;
+  /*convert into an array of the components*/
+  p_Vec2Polys((poly)u->Data(), &m, &l, currRing);
+  /*output*/
+  PrintS("[");
+  j=0;
+  loop
+  {
+    PrintS(pString(m[j]));
+    j++;
+    if (j<l) PrintS(",");
+    else
+    {
+      PrintS("]\n");
+      break;
+    }
+  }
+  /* clean up */
+  for(j=l-1;j>=0;j--) pDelete(&m[j]);
+  omFreeSize((ADDRESS)m,l*sizeof(poly));
+  return FALSE;
+}
+
+BOOLEAN jjPRINT(leftv res, leftv u)
+{
+  SPrintStart();
+  BOOLEAN bo=FALSE;
+  switch(u->Typ())
+  {
+      case INTVEC_CMD:
+        bo=ipPrint_INTVEC(u);
+        break;
+
+      case INTMAT_CMD:
+        bo=ipPrint_INTMAT(u);
+        break;
+
+      case MATRIX_CMD:
+        bo=ipPrint_MA(u);
+        break;
+
+      case IDEAL_CMD:
+      {
+        char* s = u->String(NULL, FALSE, 2);
+        PrintS(s);
+        PrintLn();
+        omFree(s);
+        break;
+      }
+
+      case MODUL_CMD:
+      {
+        matrix m = id_Module2Matrix(id_Copy((ideal) u->Data(),currRing),currRing);
+        ipPrint_MA0(m, u->Name());
+        id_Delete((ideal *) &m,currRing);
+        break;
+      }
+
+      case VECTOR_CMD:
+        bo=ipPrint_V(u);
+        break;
+
+      case RING_CMD:
+      case QRING_CMD:
+        bo=ipPrint_RING(u);
+        break;
+
+      #ifdef SINGULAR_4_1
+      case CRING_CMD:
+        bo=ipPrint_CRING(u);
+        break;
+      #endif
+
+      default:
+        u->Print();
+        break;
+  }
+  char *s=SPrintEnd();
+  if (u->next==NULL)
+  {
+    int l=strlen(s);
+    if (s[l-1]=='\n') s[l-1]='\0';
+  }
+  res->data=(void*)s;
+  return bo;
+}
+
+
+/*2
+* dbprint
+*/
+BOOLEAN jjDBPRINT(leftv res, leftv u)
+{
+  BOOLEAN print=(printlevel>myynest);
+  if ((u->next!=NULL)&&(u->Typ()==INT_CMD))
+  {
+    print=  (((int)((long)(u->Data()))) > 0);
+    u=u->next;
+  }
+  if (print)
+  {
+    // BOOLEAN r=FALSE;
+    leftv h=u;
+    leftv hh;
+    while (h!=NULL)
+    {
+      hh=h->next;
+      h->next=NULL;
+      if (jjPRINT(res, h)) return TRUE;
+      PrintS((char*)res->data);
+      omFree(res->data);
+      PrintLn();
+      h->next=hh;
+      h=hh;
+    }
+  }
+  return FALSE;
+}
+
+static void ipPrintBetti(leftv u)
+{
+  int i,j;
+  int row_shift=(int)((long)(atGet(u,"rowShift",INT_CMD)));
+  intvec * betti=(intvec *)u->Data();
+  // head line --------------------------------------------------------
+  PrintS("      "); // 6 spaces for no. and :
+  for(j=0;j<betti->cols();j++) Print(" %5d",j); // 6 spaces pro column
+  PrintS("\n------"); // 6 spaces for no. and :
+  for(j=0;j<betti->cols();j++) PrintS("------"); // 6 spaces pro column
+  PrintLn();
+  // the table --------------------------------------------------------
+  for(i=0;i<betti->rows();i++)
+  {
+    Print("%5d:",i+row_shift);
+    for(j=1;j<=betti->cols();j++)
+    {
+      int m=IMATELEM(*betti,i+1,j);
+      if (m==0)
+        PrintS("     -");
+      else
+        Print(" %5d",m);
+    }
+    PrintLn();
+  }
+  // sum --------------------------------------------------------------
+  PrintS("------"); // 6 spaces for no. and :
+  for(j=0;j<betti->cols();j++) PrintS("------"); // 6 spaces pro column
+  PrintS("\ntotal:");
+  for(j=0;j<betti->cols();j++)
+  {
+    int s=0;
+    for(i=0;i<betti->rows();i++)
+    {
+      s+=IMATELEM(*betti,i+1,j+1);
+    }
+    Print(" %5d",s); // 6 spaces pro column
+  }
+  PrintLn();
+}
+
+
+/*2
+* print(...,"format")
+*/
+BOOLEAN jjPRINT_FORMAT(leftv res, leftv u, leftv v)
+{
+/* ==================== betti ======================================== */
+  if ((u->Typ()==INTMAT_CMD)&&(strcmp((char *)v->Data(),"betti")==0))
+  {
+    SPrintStart();
+    ipPrintBetti(u);
+    char *s = SPrintEnd();
+    s[strlen(s)]='\0';
+    res->data=s;
+  }
+  else
+/* ======================== end betti ================================= */
+  {
+    char* ns = omStrDup((char*) v->Data());
+    int dim = 1;
+    if (strlen(ns) == 3 && ns[1] == '2')
+    {
+      dim = 2;
+      ns[1] = ns[2];
+      ns[2] = '\0';
+    }
+    if (strcmp(ns,"%l") == 0)
+    {
+      res->data = (char*) u->String(NULL, TRUE, dim);
+      if (dim == 2)
+      {
+        char* ns = (char*) omAlloc(strlen((char*) res->data) + 2);
+        strcpy(ns, (char*) res->data);
+        omFree(res->data);
+        strcat(ns, "\n");
+        res->data = ns;
+      }
+    }
+    else if (strcmp(ns,"%t") == 0)
+    {
+      SPrintStart();
+      type_cmd(u);
+      res->data = SPrintEnd();
+      if (dim != 2)
+        ((char*)res->data)[strlen((char*)res->data) -1] = '\0';
+    }
+    else if (strcmp(ns,"%;") == 0)
+    {
+      SPrintStart();
+      u->Print();
+      if (dim == 2) PrintLn();
+      res->data = SPrintEnd();
+    }
+    else if  (strcmp(ns,"%p") == 0)
+    {
+      iiExprArith1(res, u, PRINT_CMD);
+    }
+    else if (strcmp(ns,"%b") == 0 && (u->Typ()==INTMAT_CMD))
+    {
+      SPrintStart();
+      ipPrintBetti(u);
+      if (dim == 2) PrintLn();
+      res->data = SPrintEnd();
+    }
+    else
+    {
+      res->data = u->String(NULL, FALSE, dim);
+      if (dim == 2)
+      {
+        char* ns = (char*) omAlloc(strlen((char*) res->data) + 2);
+        strcpy(ns, (char*) res->data);
+        omFree(res->data);
+        strcat(ns, "\n");
+        res->data = ns;
+      }
+    }
+    omFree(ns);
+  }
+  return FALSE;
+}
diff --git a/Singular/ipprint.h b/Singular/ipprint.h
new file mode 100644
index 0000000..e4d2edd
--- /dev/null
+++ b/Singular/ipprint.h
@@ -0,0 +1,18 @@
+#ifndef IPPRINT_H
+#define IPPRINT_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: interpreter: printing
+*/
+#include <kernel/structs.h>
+
+class sleftv; typedef sleftv * leftv;
+
+BOOLEAN jjPRINT(leftv res, leftv u);
+BOOLEAN jjPRINT_FORMAT(leftv res, leftv u, leftv v);
+BOOLEAN jjDBPRINT(leftv res, leftv u);
+
+#endif
+
diff --git a/Singular/ipshell.cc b/Singular/ipshell.cc
new file mode 100644
index 0000000..6a5d258
--- /dev/null
+++ b/Singular/ipshell.cc
@@ -0,0 +1,6087 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT:
+*/
+
+#include <kernel/mod2.h>
+
+#include <omalloc/omalloc.h>
+
+#include <factory/factory.h>
+
+#include <misc/auxiliary.h>
+#include <misc/options.h>
+#include <misc/mylimits.h>
+#include <misc/intvec.h>
+
+#include <coeffs/numbers.h>
+#include <coeffs/coeffs.h>
+
+#include <coeffs/rmodulon.h>
+#include <coeffs/longrat.h>
+
+#include <polys/monomials/ring.h>
+#include <polys/monomials/maps.h>
+
+#include <polys/prCopy.h>
+#include <polys/matpol.h>
+
+#include <polys/weight.h>
+#include <polys/clapsing.h>
+
+
+#include <polys/ext_fields/algext.h>
+#include <polys/ext_fields/transext.h>
+
+#include <kernel/polys.h>
+#include <kernel/ideals.h>
+
+#include <kernel/numeric/mpr_base.h>
+#include <kernel/numeric/mpr_numeric.h>
+
+#include <kernel/GBEngine/syz.h>
+#include <kernel/GBEngine/kstd1.h>
+
+#include <kernel/combinatorics/stairc.h>
+#include <kernel/combinatorics/hutil.h>
+
+#include <kernel/spectrum/semic.h>
+#include <kernel/spectrum/splist.h>
+#include <kernel/spectrum/spectrum.h>
+
+#include <kernel/oswrapper/feread.h>
+
+#include <Singular/lists.h>
+#include <Singular/attrib.h>
+#include <Singular/ipconv.h>
+#include <Singular/links/silink.h>
+#include <Singular/ipshell.h>
+#include <Singular/maps_ip.h>
+#include <Singular/tok.h>
+#include <Singular/ipid.h>
+#include <Singular/subexpr.h>
+#include <Singular/fevoices.h>
+
+#include <math.h>
+#include <ctype.h>
+
+// define this if you want to use the fast_map routine for mapping ideals
+#define FAST_MAP
+
+#ifdef FAST_MAP
+#include <kernel/maps/fast_maps.h>
+#endif
+
+#ifdef SINGULAR_4_1
+#include <Singular/number2.h>
+#include <coeffs/bigintmat.h>
+#endif
+leftv iiCurrArgs=NULL;
+idhdl iiCurrProc=NULL;
+const char *lastreserved=NULL;
+
+static BOOLEAN iiNoKeepRing=TRUE;
+
+/*0 implementation*/
+
+const char * iiTwoOps(int t)
+{
+  if (t<127)
+  {
+    static char ch[2];
+    switch (t)
+    {
+      case '&':
+        return "and";
+      case '|':
+        return "or";
+      default:
+        ch[0]=t;
+        ch[1]='\0';
+        return ch;
+    }
+  }
+  switch (t)
+  {
+    case COLONCOLON:  return "::";
+    case DOTDOT:      return "..";
+    //case PLUSEQUAL:   return "+=";
+    //case MINUSEQUAL:  return "-=";
+    case MINUSMINUS:  return "--";
+    case PLUSPLUS:    return "++";
+    case EQUAL_EQUAL: return "==";
+    case LE:          return "<=";
+    case GE:          return ">=";
+    case NOTEQUAL:    return "<>";
+    default:          return Tok2Cmdname(t);
+  }
+}
+
+int iiOpsTwoChar(const char *s)
+{
+/* not handling: &&, ||, ** */
+  if (s[1]=='\0') return s[0];
+  else if (s[2]!='\0') return 0;
+  switch(s[0])
+  {
+    case '.': if (s[1]=='.') return DOTDOT;
+              else           return 0;
+    case ':': if (s[1]==':') return COLONCOLON;
+              else           return 0;
+    case '-': if (s[1]=='-') return COLONCOLON;
+              else           return 0;
+    case '+': if (s[1]=='+') return PLUSPLUS;
+              else           return 0;
+    case '=': if (s[1]=='=') return EQUAL_EQUAL;
+              else           return 0;
+    case '<': if (s[1]=='=') return LE;
+              else if (s[1]=='>') return NOTEQUAL;
+              else           return 0;
+    case '>': if (s[1]=='=') return GE;
+              else           return 0;
+    case '!': if (s[1]=='=') return NOTEQUAL;
+              else           return 0;
+  }
+  return 0;
+}
+
+static void list1(const char* s, idhdl h,BOOLEAN c, BOOLEAN fullname)
+{
+  char buffer[22];
+  int l;
+  char buf2[128];
+
+  if(fullname) sprintf(buf2, "%s::%s", "", IDID(h));
+  else sprintf(buf2, "%s", IDID(h));
+
+  Print("%s%-30.30s [%d]  ",s,buf2,IDLEV(h));
+  if (h == currRingHdl) PrintS("*");
+  PrintS(Tok2Cmdname((int)IDTYP(h)));
+
+  ipListFlag(h);
+  switch(IDTYP(h))
+  {
+    case INT_CMD:   Print(" %d",IDINT(h)); break;
+    case INTVEC_CMD:Print(" (%d)",IDINTVEC(h)->length()); break;
+    case INTMAT_CMD:Print(" %d x %d",IDINTVEC(h)->rows(),IDINTVEC(h)->cols());
+                    break;
+    case POLY_CMD:
+    case VECTOR_CMD:if (c)
+                    {
+                      PrintS(" ");wrp(IDPOLY(h));
+                      if(IDPOLY(h) != NULL)
+                      {
+                        Print(", %d monomial(s)",pLength(IDPOLY(h)));
+                      }
+                    }
+                    break;
+    case MODUL_CMD: Print(", rk %d", (int)(IDIDEAL(h)->rank));
+    case IDEAL_CMD: Print(", %u generator(s)",
+                    IDELEMS(IDIDEAL(h))); break;
+    case MAP_CMD:
+                    Print(" from %s",IDMAP(h)->preimage); break;
+    case MATRIX_CMD:Print(" %u x %u"
+                      ,MATROWS(IDMATRIX(h))
+                      ,MATCOLS(IDMATRIX(h))
+                    );
+                    break;
+    case PACKAGE_CMD:
+                    paPrint(IDID(h),IDPACKAGE(h));
+                    break;
+    case PROC_CMD: if((IDPROC(h)->libname!=NULL)
+                   && (strlen(IDPROC(h)->libname)>0))
+                     Print(" from %s",IDPROC(h)->libname);
+                   if(IDPROC(h)->is_static)
+                     PrintS(" (static)");
+                   break;
+    case STRING_CMD:
+                   {
+                     char *s;
+                     l=strlen(IDSTRING(h));
+                     memset(buffer,0,22);
+                     strncpy(buffer,IDSTRING(h),si_min(l,20));
+                     if ((s=strchr(buffer,'\n'))!=NULL)
+                     {
+                       *s='\0';
+                     }
+                     PrintS(" ");
+                     PrintS(buffer);
+                     if((s!=NULL) ||(l>20))
+                     {
+                       Print("..., %d char(s)",l);
+                     }
+                     break;
+                   }
+    case LIST_CMD: Print(", size: %d",IDLIST(h)->nr+1);
+                   break;
+    case QRING_CMD:
+    case RING_CMD:
+                   if ((IDRING(h)==currRing) && (currRingHdl!=h))
+                     PrintS("(*)"); /* this is an alias to currRing */
+#ifdef RDEBUG
+                   if (traceit &TRACE_SHOW_RINGS)
+                     Print(" <%lx>",(long)(IDRING(h)));
+#endif
+                   break;
+#ifdef SINGULAR_4_1
+    case CNUMBER_CMD:
+                   {  number2 n=(number2)IDDATA(h);
+                      Print(" (%s)",nCoeffName(n->cf));
+                      break;
+                   }
+    case CMATRIX_CMD:
+                   {  bigintmat *b=(bigintmat*)IDDATA(h);
+                      Print(" %d x %d (%s)",
+                        b->rows(),b->cols(),
+                        nCoeffName(b->basecoeffs()));
+                      break;
+                   }
+#endif
+    /*default:     break;*/
+  }
+  PrintLn();
+}
+
+void type_cmd(leftv v)
+{
+  BOOLEAN oldShortOut = FALSE;
+
+  if (currRing != NULL)
+  {
+    oldShortOut = currRing->ShortOut;
+    currRing->ShortOut = 1;
+  }
+  int t=v->Typ();
+  Print("// %s %s ",v->Name(),Tok2Cmdname(t));
+  switch (t)
+  {
+    case MAP_CMD:Print(" from %s\n",((map)(v->Data()))->preimage); break;
+    case INTMAT_CMD: Print(" %d x %d\n",((intvec*)(v->Data()))->rows(),
+                                      ((intvec*)(v->Data()))->cols()); break;
+    case MATRIX_CMD:Print(" %u x %u\n" ,
+       MATROWS((matrix)(v->Data())),
+       MATCOLS((matrix)(v->Data())));break;
+    case MODUL_CMD: Print(", rk %d\n", (int)(((ideal)(v->Data()))->rank));break;
+    case LIST_CMD: Print(", size %d\n",((lists)(v->Data()))->nr+1); break;
+
+    case PROC_CMD:
+    case RING_CMD:
+    case IDEAL_CMD:
+    case QRING_CMD: PrintLn(); break;
+
+    //case INT_CMD:
+    //case STRING_CMD:
+    //case INTVEC_CMD:
+    //case POLY_CMD:
+    //case VECTOR_CMD:
+    //case PACKAGE_CMD:
+
+    default:
+      break;
+  }
+  v->Print();
+  if (currRing != NULL)
+    currRing->ShortOut = oldShortOut;
+}
+
+static void killlocals0(int v, idhdl * localhdl, const ring r)
+{
+  idhdl h = *localhdl;
+  while (h!=NULL)
+  {
+    int vv;
+    //Print("consider %s, lev: %d:",IDID(h),IDLEV(h));
+    if ((vv=IDLEV(h))>0)
+    {
+      if (vv < v)
+      {
+        if (iiNoKeepRing)
+        {
+          //PrintS(" break\n");
+          return;
+        }
+        h = IDNEXT(h);
+        //PrintLn();
+      }
+      else //if (vv >= v)
+      {
+        idhdl nexth = IDNEXT(h);
+        killhdl2(h,localhdl,r);
+        h = nexth;
+        //PrintS("kill\n");
+      }
+    }
+    else
+    {
+      h = IDNEXT(h);
+      //PrintLn();
+    }
+  }
+}
+
+void killlocals_rec(idhdl *root,int v, ring r)
+{
+  idhdl h=*root;
+  while (h!=NULL)
+  {
+    if (IDLEV(h)>=v)
+    {
+//      Print("kill %s, lev %d for lev %d\n",IDID(h),IDLEV(h),v);
+      idhdl n=IDNEXT(h);
+      killhdl2(h,root,r);
+      h=n;
+    }
+    else if (IDTYP(h)==PACKAGE_CMD)
+    {
+ //     Print("into pack %s, lev %d for lev %d\n",IDID(h),IDLEV(h),v);
+      if (IDPACKAGE(h)!=basePack)
+        killlocals_rec(&(IDRING(h)->idroot),v,r);
+      h=IDNEXT(h);
+    }
+    else if ((IDTYP(h)==RING_CMD)
+    ||(IDTYP(h)==QRING_CMD))
+    {
+      if ((IDRING(h)!=NULL) && (IDRING(h)->idroot!=NULL))
+      // we have to test IDRING(h)!=NULL: qring Q=groebner(...): killlocals
+      {
+  //    Print("into ring %s, lev %d for lev %d\n",IDID(h),IDLEV(h),v);
+        killlocals_rec(&(IDRING(h)->idroot),v,IDRING(h));
+      }
+      h=IDNEXT(h);
+    }
+    else
+    {
+//      Print("skip %s lev %d for lev %d\n",IDID(h),IDLEV(h),v);
+      h=IDNEXT(h);
+    }
+  }
+}
+BOOLEAN killlocals_list(int v, lists L)
+{
+  if (L==NULL) return FALSE;
+  BOOLEAN changed=FALSE;
+  int n=L->nr;
+  for(;n>=0;n--)
+  {
+    leftv h=&(L->m[n]);
+    void *d=h->data;
+    if (((h->rtyp==RING_CMD) || (h->rtyp==QRING_CMD))
+    && (((ring)d)->idroot!=NULL))
+    {
+      if (d!=currRing) {changed=TRUE;rChangeCurrRing((ring)d);}
+      killlocals0(v,&(((ring)h->data)->idroot),(ring)h->data);
+    }
+    else if (h->rtyp==LIST_CMD)
+      changed|=killlocals_list(v,(lists)d);
+  }
+  return changed;
+}
+void killlocals(int v)
+{
+  BOOLEAN changed=FALSE;
+  idhdl sh=currRingHdl;
+  ring cr=currRing;
+  if (sh!=NULL) changed=((IDLEV(sh)<v) || (IDRING(sh)->ref>0));
+  //if (changed) Print("currRing=%s(%x), lev=%d,ref=%d\n",IDID(sh),IDRING(sh),IDLEV(sh),IDRING(sh)->ref);
+
+  killlocals_rec(&(basePack->idroot),v,currRing);
+
+  if (iiRETURNEXPR_len > myynest)
+  {
+    int t=iiRETURNEXPR.Typ();
+    if ((/*iiRETURNEXPR.Typ()*/ t==RING_CMD)
+    || (/*iiRETURNEXPR.Typ()*/ t==QRING_CMD))
+    {
+      leftv h=&iiRETURNEXPR;
+      if (((ring)h->data)->idroot!=NULL)
+        killlocals0(v,&(((ring)h->data)->idroot),(ring)h->data);
+    }
+    else if (/*iiRETURNEXPR.Typ()*/ t==LIST_CMD)
+    {
+      leftv h=&iiRETURNEXPR;
+      changed |=killlocals_list(v,(lists)h->data);
+    }
+  }
+  if (changed)
+  {
+    currRingHdl=rFindHdl(cr,NULL);
+    if (currRingHdl==NULL)
+      currRing=NULL;
+    else if(cr!=currRing)
+      rChangeCurrRing(cr);
+  }
+
+  if (myynest<=1) iiNoKeepRing=TRUE;
+  //Print("end killlocals  >= %d\n",v);
+  //listall();
+}
+
+void list_cmd(int typ, const char* what, const char *prefix,BOOLEAN iterate, BOOLEAN fullname)
+{
+  package savePack=currPack;
+  idhdl h,start;
+  BOOLEAN all = typ<0;
+  BOOLEAN really_all=FALSE;
+
+  if ( typ==0 )
+  {
+    if (strcmp(what,"all")==0)
+    {
+      if (currPack!=basePack)
+        list_cmd(-1,NULL,prefix,iterate,fullname); // list current package
+      really_all=TRUE;
+      h=basePack->idroot;
+    }
+    else
+    {
+      h = ggetid(what);
+      if (h!=NULL)
+      {
+        if (iterate) list1(prefix,h,TRUE,fullname);
+        if (IDTYP(h)==ALIAS_CMD) PrintS("A");
+        if ((IDTYP(h)==RING_CMD)
+            || (IDTYP(h)==QRING_CMD)
+            //|| (IDTYP(h)==PACKE_CMD)
+        )
+        {
+          h=IDRING(h)->idroot;
+        }
+        else if(IDTYP(h)==PACKAGE_CMD)
+        {
+          currPack=IDPACKAGE(h);
+          //Print("list_cmd:package\n");
+          all=TRUE;typ=PROC_CMD;fullname=TRUE;really_all=TRUE;
+          h=IDPACKAGE(h)->idroot;
+        }
+        else
+        {
+          currPack=savePack;
+          return;
+        }
+      }
+      else
+      {
+        Werror("%s is undefined",what);
+        currPack=savePack;
+        return;
+      }
+    }
+    all=TRUE;
+  }
+  else if (RingDependend(typ))
+  {
+    h = currRing->idroot;
+  }
+  else
+    h = IDROOT;
+  start=h;
+  while (h!=NULL)
+  {
+    if ((all
+      && (IDTYP(h)!=PROC_CMD)
+      &&(IDTYP(h)!=PACKAGE_CMD)
+      && (IDTYP(h)!=CRING_CMD))
+    || (typ == IDTYP(h))
+    || ((typ==RING_CMD) &&(IDTYP(h)==CRING_CMD))
+    || ((IDTYP(h)==QRING_CMD) && (typ==RING_CMD)))
+    {
+      list1(prefix,h,start==currRingHdl, fullname);
+      if (((IDTYP(h)==RING_CMD)||(IDTYP(h)==QRING_CMD))
+        && (really_all || (all && (h==currRingHdl)))
+        && ((IDLEV(h)==0)||(IDLEV(h)==myynest)))
+      {
+        list_cmd(0,IDID(h),"//      ",FALSE);
+      }
+      if (IDTYP(h)==PACKAGE_CMD && really_all)
+      {
+        package save_p=currPack;
+        currPack=IDPACKAGE(h);
+        list_cmd(0,IDID(h),"//      ",FALSE);
+        currPack=save_p;
+      }
+    }
+    h = IDNEXT(h);
+  }
+  currPack=savePack;
+}
+
+void test_cmd(int i)
+{
+  int ii;
+
+  if (i<0)
+  {
+    ii= -i;
+    if (ii < 32)
+    {
+      si_opt_1 &= ~Sy_bit(ii);
+    }
+    else if (ii < 64)
+    {
+      si_opt_2 &= ~Sy_bit(ii-32);
+    }
+    else
+      WerrorS("out of bounds\n");
+  }
+  else if (i<32)
+  {
+    ii=i;
+    if (Sy_bit(ii) & kOptions)
+    {
+      Warn("Gerhard, use the option command");
+      si_opt_1 |= Sy_bit(ii);
+    }
+    else if (Sy_bit(ii) & validOpts)
+      si_opt_1 |= Sy_bit(ii);
+  }
+  else if (i<64)
+  {
+    ii=i-32;
+    si_opt_2 |= Sy_bit(ii);
+  }
+  else
+    WerrorS("out of bounds\n");
+}
+
+int exprlist_length(leftv v)
+{
+  int rc = 0;
+  while (v!=NULL)
+  {
+    switch (v->Typ())
+    {
+      case INT_CMD:
+      case POLY_CMD:
+      case VECTOR_CMD:
+      case NUMBER_CMD:
+        rc++;
+        break;
+      case INTVEC_CMD:
+      case INTMAT_CMD:
+        rc += ((intvec *)(v->Data()))->length();
+        break;
+      case MATRIX_CMD:
+      case IDEAL_CMD:
+      case MODUL_CMD:
+        {
+          matrix mm = (matrix)(v->Data());
+          rc += mm->rows() * mm->cols();
+        }
+        break;
+      case LIST_CMD:
+        rc+=((lists)v->Data())->nr+1;
+        break;
+      default:
+        rc++;
+    }
+    v = v->next;
+  }
+  return rc;
+}
+
+int iiIsPrime0(unsigned p)  /* brute force !!!! */
+{
+  unsigned i,j=0 /*only to avoid compiler warnings*/;
+  if (p<=32749) // max. small prime in factory
+  {
+    int a=0;
+    int e=cf_getNumSmallPrimes()-1;
+    i=e/2;
+    do
+    {
+      j=cf_getSmallPrime(i);
+      if (p==j) return p;
+      if (p<j) e=i-1;
+      else     a=i+1;
+      i=a+(e-a)/2;
+    } while ( a<= e);
+    if (p>j) return j;
+    else     return cf_getSmallPrime(i-1);
+  }
+  unsigned end_i=cf_getNumSmallPrimes()-1;
+  unsigned end_p=(unsigned)sqrt((double)p);
+restart:
+  for (i=0; i<end_i; i++)
+  {
+    j=cf_getSmallPrime(i);
+    if ((p%j) == 0)
+    {
+      if (p<=32751) return iiIsPrime0(p-2);
+      p-=2;
+      goto restart;
+    }
+    if (j > end_p) return p;
+  }
+  if (i>=end_i)
+  {
+    while(j<=end_p)
+    {
+      j+=2;
+      if ((p%j) == 0)
+      {
+        if (p<=32751) return iiIsPrime0(p-2);
+        p-=2;
+        goto restart;
+      }
+    }
+  }
+  return p;
+}
+int IsPrime(int p)  /* brute force !!!! */
+{
+  if      (p == 0)    return 0;
+  else if (p == 1)    return 1/*1*/;
+  else if ((p == 2)||(p==3))    return p;
+  else if (p < 0)     return 2; //(iiIsPrime0((unsigned)(-p)));
+  else if ((p & 1)==0) return iiIsPrime0((unsigned)(p-1));
+  return iiIsPrime0((unsigned)(p));
+}
+
+BOOLEAN iiWRITE(leftv,leftv v)
+{
+  sleftv vf;
+  if (iiConvert(v->Typ(),LINK_CMD,iiTestConvert(v->Typ(),LINK_CMD),v,&vf))
+  {
+    WerrorS("link expected");
+    return TRUE;
+  }
+  si_link l=(si_link)vf.Data();
+  if (vf.next == NULL)
+  {
+    WerrorS("write: need at least two arguments");
+    return TRUE;
+  }
+
+  BOOLEAN b=slWrite(l,vf.next); /* iiConvert preserves next */
+  if (b)
+  {
+    const char *s;
+    if ((l!=NULL)&&(l->name!=NULL)) s=l->name;
+    else                            s=sNoName;
+    Werror("cannot write to %s",s);
+  }
+  vf.CleanUp();
+  return b;
+}
+
+leftv iiMap(map theMap, const char * what)
+{
+  idhdl w,r;
+  leftv v;
+  int i;
+  nMapFunc nMap;
+
+  r=IDROOT->get(theMap->preimage,myynest);
+  if ((currPack!=basePack)
+  &&((r==NULL) || ((r->typ != RING_CMD) && (r->typ != QRING_CMD))))
+    r=basePack->idroot->get(theMap->preimage,myynest);
+  if ((r==NULL) && (currRingHdl!=NULL)
+  && (strcmp(theMap->preimage,IDID(currRingHdl))==0))
+  {
+    r=currRingHdl;
+  }
+  if ((r!=NULL) && ((r->typ == RING_CMD) || (r->typ== QRING_CMD)))
+  {
+    //if ((nMap=nSetMap(rInternalChar(IDRING(r)),
+    //             IDRING(r)->parameter,
+    //             rPar(IDRING(r)),
+    //             IDRING(r)->minpoly)))
+    if ((nMap=n_SetMap(IDRING(r)->cf, currRing->cf))==NULL)
+    {
+////////// WTF?
+//      if (rEqual(IDRING(r),currRing))
+//      {
+//        nMap = n_SetMap(currRing->cf, currRing->cf);
+//      }
+//      else
+//      {
+        Werror("can not map from ground field of %s to current ground field",
+          theMap->preimage);
+        return NULL;
+//      }
+    }
+    if (IDELEMS(theMap)<IDRING(r)->N)
+    {
+      theMap->m=(polyset)omReallocSize((ADDRESS)theMap->m,
+                                 IDELEMS(theMap)*sizeof(poly),
+                                 (IDRING(r)->N)*sizeof(poly));
+      for(i=IDELEMS(theMap);i<IDRING(r)->N;i++)
+        theMap->m[i]=NULL;
+      IDELEMS(theMap)=IDRING(r)->N;
+    }
+    if (what==NULL)
+    {
+      WerrorS("argument of a map must have a name");
+    }
+    else if ((w=IDRING(r)->idroot->get(what,myynest))!=NULL)
+    {
+      char *save_r=NULL;
+      v=(leftv)omAlloc0Bin(sleftv_bin);
+      sleftv tmpW;
+      memset(&tmpW,0,sizeof(sleftv));
+      tmpW.rtyp=IDTYP(w);
+      if (tmpW.rtyp==MAP_CMD)
+      {
+        tmpW.rtyp=IDEAL_CMD;
+        save_r=IDMAP(w)->preimage;
+        IDMAP(w)->preimage=0;
+      }
+      tmpW.data=IDDATA(w);
+#if 0
+      if (((tmpW.rtyp==IDEAL_CMD)||(tmpW.rtyp==MODUL_CMD)) && idIs0(IDIDEAL(w)))
+      {
+        v->rtyp=tmpW.rtyp;
+        v->data=idInit(IDELEMS(IDIDEAL(w)),IDIDEAL(w)->rank);
+      }
+      else
+#endif
+      {
+#ifdef FAST_MAP
+        if ((tmpW.rtyp==IDEAL_CMD) && (nMap == ndCopyMap)
+#ifdef HAVE_PLURAL
+        && (!rIsPluralRing(currRing))
+#endif
+        )
+        {
+          v->rtyp=IDEAL_CMD;
+          v->data=fast_map(IDIDEAL(w), IDRING(r), (ideal)theMap, currRing);
+        }
+        else
+#endif
+        if (maApplyFetch(MAP_CMD,theMap,v,&tmpW,IDRING(r),NULL,NULL,0,nMap))
+        {
+          Werror("cannot map %s(%d)",Tok2Cmdname(w->typ),w->typ);
+          omFreeBin((ADDRESS)v, sleftv_bin);
+          if (save_r!=NULL) IDMAP(w)->preimage=save_r;
+          return NULL;
+        }
+      }
+      if (save_r!=NULL)
+      {
+        IDMAP(w)->preimage=save_r;
+        IDMAP((idhdl)v)->preimage=omStrDup(save_r);
+        v->rtyp=MAP_CMD;
+      }
+      return v;
+    }
+    else
+    {
+      Werror("%s undefined in %s",what,theMap->preimage);
+    }
+  }
+  else
+  {
+    Werror("cannot find preimage %s",theMap->preimage);
+  }
+  return NULL;
+}
+
+#ifdef OLD_RES
+void  iiMakeResolv(resolvente r, int length, int rlen, char * name, int typ0,
+                   intvec ** weights)
+{
+  lists L=liMakeResolv(r,length,rlen,typ0,weights);
+  int i=0;
+  idhdl h;
+  char * s=(char *)omAlloc(strlen(name)+5);
+
+  while (i<=L->nr)
+  {
+    sprintf(s,"%s(%d)",name,i+1);
+    if (i==0)
+      h=enterid(s,myynest,typ0,&(currRing->idroot), FALSE);
+    else
+      h=enterid(s,myynest,MODUL_CMD,&(currRing->idroot), FALSE);
+    if (h!=NULL)
+    {
+      h->data.uideal=(ideal)L->m[i].data;
+      h->attribute=L->m[i].attribute;
+      if (BVERBOSE(V_DEF_RES))
+        Print("//defining: %s as %d-th syzygy module\n",s,i+1);
+    }
+    else
+    {
+      idDelete((ideal *)&(L->m[i].data));
+      Warn("cannot define %s",s);
+    }
+    //L->m[i].data=NULL;
+    //L->m[i].rtyp=0;
+    //L->m[i].attribute=NULL;
+    i++;
+  }
+  omFreeSize((ADDRESS)L->m,(L->nr+1)*sizeof(sleftv));
+  omFreeBin((ADDRESS)L, slists_bin);
+  omFreeSize((ADDRESS)s,strlen(name)+5);
+}
+#endif
+
+//resolvente iiFindRes(char * name, int * len, int *typ0)
+//{
+//  char *s=(char *)omAlloc(strlen(name)+5);
+//  int i=-1;
+//  resolvente r;
+//  idhdl h;
+//
+//  do
+//  {
+//    i++;
+//    sprintf(s,"%s(%d)",name,i+1);
+//    h=currRing->idroot->get(s,myynest);
+//  } while (h!=NULL);
+//  *len=i-1;
+//  if (*len<=0)
+//  {
+//    Werror("no objects %s(1),.. found",name);
+//    omFreeSize((ADDRESS)s,strlen(name)+5);
+//    return NULL;
+//  }
+//  r=(ideal *)omAlloc(/*(len+1)*/ i*sizeof(ideal));
+//  memset(r,0,(*len)*sizeof(ideal));
+//  i=-1;
+//  *typ0=MODUL_CMD;
+//  while (i<(*len))
+//  {
+//    i++;
+//    sprintf(s,"%s(%d)",name,i+1);
+//    h=currRing->idroot->get(s,myynest);
+//    if (h->typ != MODUL_CMD)
+//    {
+//      if ((i!=0) || (h->typ!=IDEAL_CMD))
+//      {
+//        Werror("%s is not of type module",s);
+//        omFreeSize((ADDRESS)r,(*len)*sizeof(ideal));
+//        omFreeSize((ADDRESS)s,strlen(name)+5);
+//        return NULL;
+//      }
+//      *typ0=IDEAL_CMD;
+//    }
+//    if ((i>0) && (idIs0(r[i-1])))
+//    {
+//      *len=i-1;
+//      break;
+//    }
+//    r[i]=IDIDEAL(h);
+//  }
+//  omFreeSize((ADDRESS)s,strlen(name)+5);
+//  return r;
+//}
+
+static resolvente iiCopyRes(resolvente r, int l)
+{
+  int i;
+  resolvente res=(ideal *)omAlloc0((l+1)*sizeof(ideal));
+
+  for (i=0; i<l; i++)
+    res[i]=idCopy(r[i]);
+  return res;
+}
+
+BOOLEAN jjMINRES(leftv res, leftv v)
+{
+  int len=0;
+  int typ0;
+  lists L=(lists)v->Data();
+  intvec *weights=(intvec*)atGet(v,"isHomog",INTVEC_CMD);
+  int add_row_shift = 0;
+  if (weights==NULL)
+    weights=(intvec*)atGet(&(L->m[0]),"isHomog",INTVEC_CMD);
+  if (weights!=NULL)  add_row_shift=weights->min_in();
+  resolvente rr=liFindRes(L,&len,&typ0);
+  if (rr==NULL) return TRUE;
+  resolvente r=iiCopyRes(rr,len);
+
+  syMinimizeResolvente(r,len,0);
+  omFreeSize((ADDRESS)rr,len*sizeof(ideal));
+  len++;
+  res->data=(char *)liMakeResolv(r,len,-1,typ0,NULL,add_row_shift);
+  return FALSE;
+}
+
+BOOLEAN jjBETTI(leftv res, leftv u)
+{
+  sleftv tmp;
+  memset(&tmp,0,sizeof(tmp));
+  tmp.rtyp=INT_CMD;
+  tmp.data=(void *)1;
+  if ((u->Typ()==IDEAL_CMD)
+  || (u->Typ()==MODUL_CMD))
+    return jjBETTI2_ID(res,u,&tmp);
+  else
+    return jjBETTI2(res,u,&tmp);
+}
+
+BOOLEAN jjBETTI2_ID(leftv res, leftv u, leftv v)
+{
+  lists l=(lists) omAllocBin(slists_bin);
+  l->Init(1);
+  l->m[0].rtyp=u->Typ();
+  l->m[0].data=u->Data();
+  attr *a=u->Attribute();
+  if (a!=NULL)
+  l->m[0].attribute=*a;
+  sleftv tmp2;
+  memset(&tmp2,0,sizeof(tmp2));
+  tmp2.rtyp=LIST_CMD;
+  tmp2.data=(void *)l;
+  BOOLEAN r=jjBETTI2(res,&tmp2,v);
+  l->m[0].data=NULL;
+  l->m[0].attribute=NULL;
+  l->m[0].rtyp=DEF_CMD;
+  l->Clean();
+  return r;
+}
+
+BOOLEAN jjBETTI2(leftv res, leftv u, leftv v)
+{
+  resolvente r;
+  int len;
+  int reg,typ0;
+  lists l=(lists)u->Data();
+
+  intvec *weights=NULL;
+  int add_row_shift=0;
+  intvec *ww=(intvec *)atGet(&(l->m[0]),"isHomog",INTVEC_CMD);
+  if (ww!=NULL)
+  {
+     weights=ivCopy(ww);
+     add_row_shift = ww->min_in();
+     (*weights) -= add_row_shift;
+  }
+  //Print("attr:%x\n",weights);
+
+  r=liFindRes(l,&len,&typ0);
+  if (r==NULL) return TRUE;
+  res->data=(char *)syBetti(r,len,&reg,weights,(int)(long)v->Data());
+  omFreeSize((ADDRESS)r,(len)*sizeof(ideal));
+  atSet(res,omStrDup("rowShift"),(void*)(long)add_row_shift,INT_CMD);
+  if (weights!=NULL) delete weights;
+  return FALSE;
+}
+
+int iiRegularity(lists L)
+{
+  int len,reg,typ0;
+
+  resolvente r=liFindRes(L,&len,&typ0);
+
+  if (r==NULL)
+    return -2;
+  intvec *weights=NULL;
+  int add_row_shift=0;
+  intvec *ww=(intvec *)atGet(&(L->m[0]),"isHomog",INTVEC_CMD);
+  if (ww!=NULL)
+  {
+     weights=ivCopy(ww);
+     add_row_shift = ww->min_in();
+     (*weights) -= add_row_shift;
+  }
+  //Print("attr:%x\n",weights);
+
+  intvec *dummy=syBetti(r,len,&reg,weights);
+  if (weights!=NULL) delete weights;
+  delete dummy;
+  omFreeSize((ADDRESS)r,len*sizeof(ideal));
+  return reg+1+add_row_shift;
+}
+
+BOOLEAN iiDebugMarker=TRUE;
+#define BREAK_LINE_LENGTH 80
+void iiDebug()
+{
+  Print("\n-- break point in %s --\n",VoiceName());
+  if (iiDebugMarker) VoiceBackTrack();
+  char * s;
+  iiDebugMarker=FALSE;
+  s = (char *)omAlloc(BREAK_LINE_LENGTH+4);
+  loop
+  {
+    memset(s,0,80);
+    fe_fgets_stdin("",s,BREAK_LINE_LENGTH);
+    if (s[BREAK_LINE_LENGTH-1]!='\0')
+    {
+      Print("line too long, max is %d chars\n",BREAK_LINE_LENGTH);
+    }
+    else
+      break;
+  }
+  if (*s=='\n')
+  {
+    iiDebugMarker=TRUE;
+  }
+#if MDEBUG
+  else if(strncmp(s,"cont;",5)==0)
+  {
+    iiDebugMarker=TRUE;
+  }
+#endif /* MDEBUG */
+  else
+  {
+    strcat( s, "\n;~\n");
+    newBuffer(s,BT_execute);
+  }
+}
+
+lists scIndIndset(ideal S, BOOLEAN all, ideal Q)
+{
+  int i;
+  indset save;
+  lists res=(lists)omAlloc0Bin(slists_bin);
+
+  hexist = hInit(S, Q, &hNexist, currRing);
+  if (hNexist == 0)
+  {
+    intvec *iv=new intvec(rVar(currRing));
+    for(i=0; i<rVar(currRing); i++) (*iv)[i]=1;
+    res->Init(1);
+    res->m[0].rtyp=INTVEC_CMD;
+    res->m[0].data=(intvec*)iv;
+    return res;
+  }
+  else if (hisModule!=0)
+  {
+    res->Init(0);
+    return res;
+  }
+  save = ISet = (indset)omAlloc0Bin(indlist_bin);
+  hMu = 0;
+  hwork = (scfmon)omAlloc(hNexist * sizeof(scmon));
+  hvar = (varset)omAlloc((rVar(currRing) + 1) * sizeof(int));
+  hpure = (scmon)omAlloc((1 + (rVar(currRing) * rVar(currRing))) * sizeof(long));
+  hrad = hexist;
+  hNrad = hNexist;
+  radmem = hCreate(rVar(currRing) - 1);
+  hCo = rVar(currRing) + 1;
+  hNvar = rVar(currRing);
+  hRadical(hrad, &hNrad, hNvar);
+  hSupp(hrad, hNrad, hvar, &hNvar);
+  if (hNvar)
+  {
+    hCo = hNvar;
+    memset(hpure, 0, (rVar(currRing) + 1) * sizeof(long));
+    hPure(hrad, 0, &hNrad, hvar, hNvar, hpure, &hNpure);
+    hLexR(hrad, hNrad, hvar, hNvar);
+    hDimSolve(hpure, hNpure, hrad, hNrad, hvar, hNvar);
+  }
+  if (hCo && (hCo < rVar(currRing)))
+  {
+    hIndMult(hpure, hNpure, hrad, hNrad, hvar, hNvar);
+  }
+  if (hMu!=0)
+  {
+    ISet = save;
+    hMu2 = 0;
+    if (all && (hCo+1 < rVar(currRing)))
+    {
+      JSet = (indset)omAlloc0Bin(indlist_bin);
+      hIndAllMult(hpure, hNpure, hrad, hNrad, hvar, hNvar);
+      i=hMu+hMu2;
+      res->Init(i);
+      if (hMu2 == 0)
+      {
+        omFreeBin((ADDRESS)JSet, indlist_bin);
+      }
+    }
+    else
+    {
+      res->Init(hMu);
+    }
+    for (i=0;i<hMu;i++)
+    {
+      res->m[i].data = (void *)save->set;
+      res->m[i].rtyp = INTVEC_CMD;
+      ISet = save;
+      save = save->nx;
+      omFreeBin((ADDRESS)ISet, indlist_bin);
+    }
+    omFreeBin((ADDRESS)save, indlist_bin);
+    if (hMu2 != 0)
+    {
+      save = JSet;
+      for (i=hMu;i<hMu+hMu2;i++)
+      {
+        res->m[i].data = (void *)save->set;
+        res->m[i].rtyp = INTVEC_CMD;
+        JSet = save;
+        save = save->nx;
+        omFreeBin((ADDRESS)JSet, indlist_bin);
+      }
+      omFreeBin((ADDRESS)save, indlist_bin);
+    }
+  }
+  else
+  {
+    res->Init(0);
+    omFreeBin((ADDRESS)ISet,  indlist_bin);
+  }
+  hKill(radmem, rVar(currRing) - 1);
+  omFreeSize((ADDRESS)hpure, (1 + (rVar(currRing) * rVar(currRing))) * sizeof(long));
+  omFreeSize((ADDRESS)hvar, (rVar(currRing) + 1) * sizeof(int));
+  omFreeSize((ADDRESS)hwork, hNexist * sizeof(scmon));
+  hDelete(hexist, hNexist);
+  return res;
+}
+
+int iiDeclCommand(leftv sy, leftv name, int lev,int t, idhdl* root,BOOLEAN isring, BOOLEAN init_b)
+{
+  BOOLEAN res=FALSE;
+  const char *id = name->name;
+
+  memset(sy,0,sizeof(sleftv));
+  if ((name->name==NULL)||(isdigit(name->name[0])))
+  {
+    WerrorS("object to declare is not a name");
+    res=TRUE;
+  }
+  else
+  {
+    //if (name->rtyp!=0)
+    //{
+    //  Warn("`%s` is already in use",name->name);
+    //}
+    {
+      sy->data = (char *)enterid(id,lev,t,root,init_b);
+    }
+    if (sy->data!=NULL)
+    {
+      sy->rtyp=IDHDL;
+      currid=sy->name=IDID((idhdl)sy->data);
+      // name->name=NULL; /* used in enterid */
+      //sy->e = NULL;
+      if (name->next!=NULL)
+      {
+        sy->next=(leftv)omAllocBin(sleftv_bin);
+        res=iiDeclCommand(sy->next,name->next,lev,t,root, isring);
+      }
+    }
+    else res=TRUE;
+  }
+  name->CleanUp();
+  return res;
+}
+
+BOOLEAN iiDefaultParameter(leftv p)
+{
+  attr at=NULL;
+  if (iiCurrProc!=NULL)
+     at=iiCurrProc->attribute->get("default_arg");
+  if (at==NULL)
+    return FALSE;
+  sleftv tmp;
+  memset(&tmp,0,sizeof(sleftv));
+  tmp.rtyp=at->atyp;
+  tmp.data=at->CopyA();
+  return iiAssign(p,&tmp);
+}
+BOOLEAN iiBranchTo(leftv r, leftv args)
+{
+  // <string1...stringN>,<proc>
+  // known: args!=NULL, l>=1
+  int l=args->listLength();
+  int ll=0;
+  if (iiCurrArgs!=NULL) ll=iiCurrArgs->listLength();
+  if (ll!=(l-1)) return FALSE;
+  leftv h=args;
+  short *t=(short*)omAlloc(l*sizeof(short));
+  t[0]=l-1;
+  int b;
+  int i;
+  for(i=1;i<l;i++,h=h->next)
+  {
+    if (h->Typ()!=STRING_CMD)
+    {
+      omFree(t);
+      Werror("arg %d is not a string",i);
+      return TRUE;
+    }
+    int tt;
+    b=IsCmd((char *)h->Data(),tt);
+    if(b) t[i]=tt;
+    else
+    {
+      omFree(t);
+      Werror("arg %d is not a type name",i);
+      return TRUE;
+    }
+  }
+  if (h->Typ()!=PROC_CMD)
+  {
+    omFree(t);
+    Werror("last arg is not a proc",i);
+    return TRUE;
+  }
+  b=iiCheckTypes(iiCurrArgs,t,0);
+  omFree(t);
+  if (b && (h->rtyp==IDHDL) && (h->e==NULL))
+  {
+    BOOLEAN err;
+    //Print("branchTo: %s\n",h->Name());
+    iiCurrProc=(idhdl)h->data;
+    err=iiAllStart(IDPROC(iiCurrProc),IDPROC(iiCurrProc)->data.s.body,BT_proc,IDPROC(iiCurrProc)->data.s.body_lineno-(iiCurrArgs==NULL));
+    exitBuffer(BT_proc);
+    if (iiCurrArgs!=NULL)
+    {
+      if (!err) Warn("too many arguments for %s",IDID(iiCurrProc));
+      iiCurrArgs->CleanUp();
+      omFreeBin((ADDRESS)iiCurrArgs, sleftv_bin);
+      iiCurrArgs=NULL;
+    }
+    return 2-err;
+  }
+  return FALSE;
+}
+BOOLEAN iiParameter(leftv p)
+{
+  if (iiCurrArgs==NULL)
+  {
+    if (strcmp(p->name,"#")==0)
+      return iiDefaultParameter(p);
+    Werror("not enough arguments for proc %s",VoiceName());
+    p->CleanUp();
+    return TRUE;
+  }
+  leftv h=iiCurrArgs;
+  leftv rest=h->next; /*iiCurrArgs is not NULL here*/
+  BOOLEAN is_default_list=FALSE;
+  if (strcmp(p->name,"#")==0)
+  {
+    is_default_list=TRUE;
+    rest=NULL;
+  }
+  else
+  {
+    h->next=NULL;
+  }
+  BOOLEAN res=iiAssign(p,h);
+  if (is_default_list)
+  {
+    iiCurrArgs=NULL;
+  }
+  else
+  {
+    iiCurrArgs=rest;
+  }
+  h->CleanUp();
+  omFreeBin((ADDRESS)h, sleftv_bin);
+  return res;
+}
+BOOLEAN iiAlias(leftv p)
+{
+  if (iiCurrArgs==NULL)
+  {
+    Werror("not enough arguments for proc %s",VoiceName());
+    p->CleanUp();
+    return TRUE;
+  }
+  leftv h=iiCurrArgs;
+  iiCurrArgs=h->next;
+  h->next=NULL;
+  if (h->rtyp!=IDHDL)
+  {
+    BOOLEAN res=iiAssign(p,h);
+    h->CleanUp();
+    omFreeBin((ADDRESS)h, sleftv_bin);
+    return res;
+  }
+  if (h->Typ()!=p->Typ())
+  {
+    WerrorS("type mismatch");
+    return TRUE;
+  }
+  idhdl pp=(idhdl)p->data;
+  switch(pp->typ)
+  {
+#ifdef SINGULAR_4_1
+      case CRING_CMD:
+        nKillChar((coeffs)pp);
+        break;
+#endif
+      case INT_CMD:
+        break;
+      case INTVEC_CMD:
+      case INTMAT_CMD:
+         delete IDINTVEC(pp);
+         break;
+      case NUMBER_CMD:
+         nDelete(&IDNUMBER(pp));
+         break;
+      case BIGINT_CMD:
+         n_Delete(&IDNUMBER(pp),coeffs_BIGINT);
+         break;
+      case MAP_CMD:
+         {
+           map im = IDMAP(pp);
+           omFree((ADDRESS)im->preimage);
+         }
+         // continue as ideal:
+      case IDEAL_CMD:
+      case MODUL_CMD:
+      case MATRIX_CMD:
+          idDelete(&IDIDEAL(pp));
+         break;
+      case PROC_CMD:
+      case RESOLUTION_CMD:
+      case STRING_CMD:
+         omFree((ADDRESS)IDSTRING(pp));
+         break;
+      case LIST_CMD:
+         IDLIST(pp)->Clean();
+         break;
+      case LINK_CMD:
+         omFreeBin(IDLINK(pp),sip_link_bin);
+         break;
+       // case ring: cannot happen
+       default:
+         Werror("unknown type %d",p->Typ());
+         return TRUE;
+  }
+  pp->typ=ALIAS_CMD;
+  IDDATA(pp)=(char*)h->data;
+  h->CleanUp();
+  omFreeBin((ADDRESS)h, sleftv_bin);
+  return FALSE;
+}
+
+static BOOLEAN iiInternalExport (leftv v, int toLev)
+{
+  idhdl h=(idhdl)v->data;
+  //Print("iiInternalExport('%s',%d)%s\n", v->name, toLev,"");
+  if (IDLEV(h)==0)
+  {
+    if (BVERBOSE(V_REDEFINE)) Warn("`%s` is already global",IDID(h));
+  }
+  else
+  {
+    h=IDROOT->get(v->name,toLev);
+    idhdl *root=&IDROOT;
+    if ((h==NULL)&&(currRing!=NULL))
+    {
+      h=currRing->idroot->get(v->name,toLev);
+      root=&currRing->idroot;
+    }
+    BOOLEAN keepring=FALSE;
+    if ((h!=NULL)&&(IDLEV(h)==toLev))
+    {
+      if (IDTYP(h)==v->Typ())
+      {
+        if (((IDTYP(h)==RING_CMD)||(IDTYP(h)==QRING_CMD))
+        && (v->Data()==IDDATA(h)))
+        {
+          IDRING(h)->ref++;
+          keepring=TRUE;
+          IDLEV(h)=toLev;
+          //WarnS("keepring");
+          return FALSE;
+        }
+        if (BVERBOSE(V_REDEFINE))
+        {
+          Warn("redefining %s",IDID(h));
+        }
+#ifdef USE_IILOCALRING
+        if (iiLocalRing[0]==IDRING(h) && (!keepring)) iiLocalRing[0]=NULL;
+#else
+        proclevel *p=procstack;
+        while (p->next!=NULL) p=p->next;
+        if ((p->cRing==IDRING(h)) && (!keepring))
+        {
+          p->cRing=NULL;
+          p->cRingHdl=NULL;
+        }
+#endif
+        killhdl2(h,root,currRing);
+      }
+      else
+      {
+        return TRUE;
+      }
+    }
+    h=(idhdl)v->data;
+    IDLEV(h)=toLev;
+    if (keepring) IDRING(h)->ref--;
+    iiNoKeepRing=FALSE;
+    //Print("export %s\n",IDID(h));
+  }
+  return FALSE;
+}
+
+BOOLEAN iiInternalExport (leftv v, int toLev, package rootpack)
+{
+  idhdl h=(idhdl)v->data;
+  if(h==NULL)
+  {
+    Warn("'%s': no such identifier\n", v->name);
+    return FALSE;
+  }
+  package frompack=v->req_packhdl;
+  if (frompack==NULL) frompack=currPack;
+  if ((RingDependend(IDTYP(h)))
+  || ((IDTYP(h)==LIST_CMD)
+     && (lRingDependend(IDLIST(h)))
+     )
+  )
+  {
+    //Print("// ==> Ringdependent set nesting to 0\n");
+    return (iiInternalExport(v, toLev));
+  }
+  else
+  {
+    IDLEV(h)=toLev;
+    v->req_packhdl=rootpack;
+    if (h==frompack->idroot)
+    {
+      frompack->idroot=h->next;
+    }
+    else
+    {
+      idhdl hh=frompack->idroot;
+      while ((hh!=NULL) && (hh->next!=h))
+        hh=hh->next;
+      if ((hh!=NULL) && (hh->next==h))
+        hh->next=h->next;
+      else
+      {
+        Werror("`%s` not found",v->Name());
+        return TRUE;
+      }
+    }
+    h->next=rootpack->idroot;
+    rootpack->idroot=h;
+  }
+  return FALSE;
+}
+
+BOOLEAN iiExport (leftv v, int toLev)
+{
+  BOOLEAN nok=FALSE;
+  leftv r=v;
+  while (v!=NULL)
+  {
+    if ((v->name==NULL)||(v->rtyp==0)||(v->e!=NULL))
+    {
+      Werror("cannot export:%s of internal type %d",v->name,v->rtyp);
+      nok=TRUE;
+    }
+    else
+    {
+      if(iiInternalExport(v, toLev))
+      {
+        r->CleanUp();
+        return TRUE;
+      }
+    }
+    v=v->next;
+  }
+  r->CleanUp();
+  return nok;
+}
+
+/*assume root!=idroot*/
+BOOLEAN iiExport (leftv v, int toLev, package pack)
+{
+#ifdef SINGULAR_4_1
+  if ((pack==basePack)&&(pack!=currPack))
+  { Warn("'exportto' to Top is depreciated in >>%s<<",my_yylinebuf);}
+#endif
+  BOOLEAN nok=FALSE;
+  leftv rv=v;
+  while (v!=NULL)
+  {
+    if ((v->name==NULL)||(v->rtyp==0)||(v->e!=NULL)
+    )
+    {
+      Werror("cannot export:%s of internal type %d",v->name,v->rtyp);
+      nok=TRUE;
+    }
+    else
+    {
+      idhdl old=pack->idroot->get( v->name,toLev);
+      if (old!=NULL)
+      {
+        if ((pack==currPack) && (old==(idhdl)v->data))
+        {
+          if (BVERBOSE(V_REDEFINE)) Warn("`%s` is already global",IDID(old));
+          break;
+        }
+        else if (IDTYP(old)==v->Typ())
+        {
+          if (BVERBOSE(V_REDEFINE))
+          {
+            Warn("redefining %s",IDID(old));
+          }
+          v->name=omStrDup(v->name);
+          killhdl2(old,&(pack->idroot),currRing);
+        }
+        else
+        {
+          rv->CleanUp();
+          return TRUE;
+        }
+      }
+      //Print("iiExport: pack=%s\n",IDID(root));
+      if(iiInternalExport(v, toLev, pack))
+      {
+        rv->CleanUp();
+        return TRUE;
+      }
+    }
+    v=v->next;
+  }
+  rv->CleanUp();
+  return nok;
+}
+
+BOOLEAN iiCheckRing(int i)
+{
+  if (currRing==NULL)
+  {
+    #ifdef SIQ
+    if (siq<=0)
+    {
+    #endif
+      if (RingDependend(i))
+      {
+        WerrorS("no ring active");
+        return TRUE;
+      }
+    #ifdef SIQ
+    }
+    #endif
+  }
+  return FALSE;
+}
+
+poly    iiHighCorner(ideal I, int ak)
+{
+  int i;
+  if(!idIsZeroDim(I)) return NULL; // not zero-dim.
+  poly po=NULL;
+  if (rHasLocalOrMixedOrdering_currRing())
+  {
+    scComputeHC(I,currRing->qideal,ak,po);
+    if (po!=NULL)
+    {
+      pGetCoeff(po)=nInit(1);
+      for (i=rVar(currRing); i>0; i--)
+      {
+        if (pGetExp(po, i) > 0) pDecrExp(po,i);
+      }
+      pSetComp(po,ak);
+      pSetm(po);
+    }
+  }
+  else
+    po=pOne();
+  return po;
+}
+
+void iiCheckPack(package &p)
+{
+  if (p==basePack) return;
+
+  idhdl t=basePack->idroot;
+
+  while ((t!=NULL) && (IDTYP(t)!=PACKAGE_CMD) && (IDPACKAGE(t)!=p)) t=t->next;
+
+  if (t==NULL)
+  {
+    WarnS("package not found\n");
+    p=basePack;
+  }
+  return;
+}
+
+idhdl rDefault(const char *s)
+{
+  idhdl tmp=NULL;
+
+  if (s!=NULL) tmp = enterid(s, myynest, RING_CMD, &IDROOT);
+  if (tmp==NULL) return NULL;
+
+// if ((currRing->ppNoether)!=NULL) pDelete(&(currRing->ppNoether));
+  if (sLastPrinted.RingDependend())
+  {
+    sLastPrinted.CleanUp();
+    memset(&sLastPrinted,0,sizeof(sleftv));
+  }
+
+  ring r = IDRING(tmp);
+
+  r->cf = nInitChar(n_Zp, (void*)32003); //   r->cf->ch = 32003;
+  r->N      = 3;
+  /*r->P     = 0; Alloc0 in idhdl::set, ipid.cc*/
+  /*names*/
+  r->names = (char **) omAlloc0(3 * sizeof(char_ptr));
+  r->names[0]  = omStrDup("x");
+  r->names[1]  = omStrDup("y");
+  r->names[2]  = omStrDup("z");
+  /*weights: entries for 3 blocks: NULL*/
+  r->wvhdl = (int **)omAlloc0(3 * sizeof(int_ptr));
+  /*order: dp,C,0*/
+  r->order = (int *) omAlloc(3 * sizeof(int *));
+  r->block0 = (int *)omAlloc0(3 * sizeof(int *));
+  r->block1 = (int *)omAlloc0(3 * sizeof(int *));
+  /* ringorder dp for the first block: var 1..3 */
+  r->order[0]  = ringorder_dp;
+  r->block0[0] = 1;
+  r->block1[0] = 3;
+  /* ringorder C for the second block: no vars */
+  r->order[1]  = ringorder_C;
+  /* the last block: everything is 0 */
+  r->order[2]  = 0;
+
+  /* complete ring intializations */
+  rComplete(r);
+  rSetHdl(tmp);
+  return currRingHdl;
+}
+
+idhdl rFindHdl(ring r, idhdl n)
+{
+  idhdl h=rSimpleFindHdl(r,IDROOT,n);
+  if (h!=NULL)  return h;
+  if (IDROOT!=basePack->idroot) h=rSimpleFindHdl(r,basePack->idroot,n);
+  if (h!=NULL)  return h;
+  proclevel *p=procstack;
+  while(p!=NULL)
+  {
+    if ((p->cPack!=basePack)
+    && (p->cPack!=currPack))
+      h=rSimpleFindHdl(r,p->cPack->idroot,n);
+    if (h!=NULL)  return h;
+    p=p->next;
+  }
+  idhdl tmp=basePack->idroot;
+  while (tmp!=NULL)
+  {
+    if (IDTYP(tmp)==PACKAGE_CMD)
+      h=rSimpleFindHdl(r,IDPACKAGE(tmp)->idroot,n);
+    if (h!=NULL)  return h;
+    tmp=IDNEXT(tmp);
+  }
+  return NULL;
+}
+
+void rDecomposeCF(leftv h,const ring r,const ring R)
+{
+  lists L=(lists)omAlloc0Bin(slists_bin);
+  L->Init(4);
+  h->rtyp=LIST_CMD;
+  h->data=(void *)L;
+  // 0: char/ cf - ring
+  // 1: list (var)
+  // 2: list (ord)
+  // 3: qideal
+  // ----------------------------------------
+  // 0: char/ cf - ring
+  L->m[0].rtyp=INT_CMD;
+  L->m[0].data=(void *)(long)r->cf->ch;
+  // ----------------------------------------
+  // 1: list (var)
+  lists LL=(lists)omAlloc0Bin(slists_bin);
+  LL->Init(r->N);
+  int i;
+  for(i=0; i<r->N; i++)
+  {
+    LL->m[i].rtyp=STRING_CMD;
+    LL->m[i].data=(void *)omStrDup(r->names[i]);
+  }
+  L->m[1].rtyp=LIST_CMD;
+  L->m[1].data=(void *)LL;
+  // ----------------------------------------
+  // 2: list (ord)
+  LL=(lists)omAlloc0Bin(slists_bin);
+  i=rBlocks(r)-1;
+  LL->Init(i);
+  i--;
+  lists LLL;
+  for(; i>=0; i--)
+  {
+    intvec *iv;
+    int j;
+    LL->m[i].rtyp=LIST_CMD;
+    LLL=(lists)omAlloc0Bin(slists_bin);
+    LLL->Init(2);
+    LLL->m[0].rtyp=STRING_CMD;
+    LLL->m[0].data=(void *)omStrDup(rSimpleOrdStr(r->order[i]));
+    if (r->block1[i]-r->block0[i] >=0 )
+    {
+      j=r->block1[i]-r->block0[i];
+      if(r->order[i]==ringorder_M) j=(j+1)*(j+1)-1;
+      iv=new intvec(j+1);
+      if ((r->wvhdl!=NULL) && (r->wvhdl[i]!=NULL))
+      {
+        for(;j>=0; j--) (*iv)[j]=r->wvhdl[i][j];
+      }
+      else switch (r->order[i])
+      {
+        case ringorder_dp:
+        case ringorder_Dp:
+        case ringorder_ds:
+        case ringorder_Ds:
+        case ringorder_lp:
+          for(;j>=0; j--) (*iv)[j]=1;
+          break;
+        default: /* do nothing */;
+      }
+    }
+    else
+    {
+      iv=new intvec(1);
+    }
+    LLL->m[1].rtyp=INTVEC_CMD;
+    LLL->m[1].data=(void *)iv;
+    LL->m[i].data=(void *)LLL;
+  }
+  L->m[2].rtyp=LIST_CMD;
+  L->m[2].data=(void *)LL;
+  // ----------------------------------------
+  // 3: qideal
+  L->m[3].rtyp=IDEAL_CMD;
+  if (nCoeff_is_transExt(R->cf))
+    L->m[3].data=(void *)idInit(1,1);
+  else
+  {
+    ideal q=idInit(IDELEMS(r->qideal));
+    q->m[0]=p_Init(R);
+    pSetCoeff0(q->m[0],(number)(r->qideal->m[0]));
+    L->m[3].data=(void *)q;
+//    I->m[0] = pNSet(R->minpoly);
+  }
+  // ----------------------------------------
+}
+void rDecomposeC(leftv h,const ring R)
+/* field is R or C */
+{
+  lists L=(lists)omAlloc0Bin(slists_bin);
+  if (rField_is_long_C(R)) L->Init(3);
+  else                     L->Init(2);
+  h->rtyp=LIST_CMD;
+  h->data=(void *)L;
+  // 0: char/ cf - ring
+  // 1: list (var)
+  // 2: list (ord)
+  // ----------------------------------------
+  // 0: char/ cf - ring
+  L->m[0].rtyp=INT_CMD;
+  L->m[0].data=(void *)0;
+  // ----------------------------------------
+  // 1:
+  lists LL=(lists)omAlloc0Bin(slists_bin);
+  LL->Init(2);
+    LL->m[0].rtyp=INT_CMD;
+    LL->m[0].data=(void *)(long)si_max(R->cf->float_len,SHORT_REAL_LENGTH/2);
+    LL->m[1].rtyp=INT_CMD;
+    LL->m[1].data=(void *)(long)si_max(R->cf->float_len2,SHORT_REAL_LENGTH);
+  L->m[1].rtyp=LIST_CMD;
+  L->m[1].data=(void *)LL;
+  // ----------------------------------------
+  // 2: list (par)
+  if (rField_is_long_C(R))
+  {
+    L->m[2].rtyp=STRING_CMD;
+    L->m[2].data=(void *)omStrDup(*rParameter(R));
+  }
+  // ----------------------------------------
+}
+
+#ifdef HAVE_RINGS
+void rDecomposeRing(leftv h,const ring R)
+/* field is R or C */
+{
+  lists L=(lists)omAlloc0Bin(slists_bin);
+  if (rField_is_Ring_Z(R)) L->Init(1);
+  else                     L->Init(2);
+  h->rtyp=LIST_CMD;
+  h->data=(void *)L;
+  // 0: char/ cf - ring
+  // 1: list (module)
+  // ----------------------------------------
+  // 0: char/ cf - ring
+  L->m[0].rtyp=STRING_CMD;
+  L->m[0].data=(void *)omStrDup("integer");
+  // ----------------------------------------
+  // 1: module
+  if (rField_is_Ring_Z(R)) return;
+  lists LL=(lists)omAlloc0Bin(slists_bin);
+  LL->Init(2);
+  LL->m[0].rtyp=BIGINT_CMD;
+  LL->m[0].data=nlMapGMP((number) R->cf->modBase, R->cf, R->cf); // TODO: what is this?? // extern number nlMapGMP(number from, const coeffs src, const coeffs dst); // FIXME: replace with n_InitMPZ(R->cf->modBase, coeffs_BIGINT); ?
+  LL->m[1].rtyp=INT_CMD;
+  LL->m[1].data=(void *) R->cf->modExponent;
+  L->m[1].rtyp=LIST_CMD;
+  L->m[1].data=(void *)LL;
+}
+#endif
+
+
+lists rDecompose(const ring r)
+{
+  assume( r != NULL );
+  const coeffs C = r->cf;
+  assume( C != NULL );
+
+  // sanity check: require currRing==r for rings with polynomial data
+  if ( (r!=currRing) && (
+           (nCoeff_is_algExt(C) && (C != currRing->cf))
+        || (r->qideal != NULL)
+#ifdef HAVE_PLURAL
+        || (rIsPluralRing(r))
+#endif
+                        )
+     )
+  {
+    WerrorS("ring with polynomial data must be the base ring or compatible");
+    return NULL;
+  }
+  // 0: char/ cf - ring
+  // 1: list (var)
+  // 2: list (ord)
+  // 3: qideal
+  // possibly:
+  // 4: C
+  // 5: D
+  lists L=(lists)omAlloc0Bin(slists_bin);
+  if (rIsPluralRing(r))
+    L->Init(6);
+  else
+    L->Init(4);
+  // ----------------------------------------
+  // 0: char/ cf - ring
+#ifdef SINGULAR_4_1
+  // 0: char/ cf - ring
+  L->m[0].rtyp=CRING_CMD;
+  L->m[0].data=(char*)r->cf; r->cf->ref++;
+#else
+  if (rField_is_numeric(r))
+  {
+    rDecomposeC(&(L->m[0]),r);
+  }
+#ifdef HAVE_RINGS
+  else if (rField_is_Ring(r))
+  {
+    rDecomposeRing(&(L->m[0]),r);
+  }
+#endif
+  else if ( r->cf->extRing!=NULL )// nCoeff_is_algExt(r->cf))
+  {
+    rDecomposeCF(&(L->m[0]), r->cf->extRing, r);
+  }
+  else if(rField_is_GF(r))
+  {
+    lists Lc=(lists)omAlloc0Bin(slists_bin);
+    Lc->Init(4);
+    // char:
+    Lc->m[0].rtyp=INT_CMD;
+    Lc->m[0].data=(void*)(long)r->cf->m_nfCharQ;
+    // var:
+    lists Lv=(lists)omAlloc0Bin(slists_bin);
+    Lv->Init(1);
+    Lv->m[0].rtyp=STRING_CMD;
+    Lv->m[0].data=(void *)omStrDup(*rParameter(r));
+    Lc->m[1].rtyp=LIST_CMD;
+    Lc->m[1].data=(void*)Lv;
+    // ord:
+    lists Lo=(lists)omAlloc0Bin(slists_bin);
+    Lo->Init(1);
+    lists Loo=(lists)omAlloc0Bin(slists_bin);
+    Loo->Init(2);
+    Loo->m[0].rtyp=STRING_CMD;
+    Loo->m[0].data=(void *)omStrDup(rSimpleOrdStr(ringorder_lp));
+
+    intvec *iv=new intvec(1); (*iv)[0]=1;
+    Loo->m[1].rtyp=INTVEC_CMD;
+    Loo->m[1].data=(void *)iv;
+
+    Lo->m[0].rtyp=LIST_CMD;
+    Lo->m[0].data=(void*)Loo;
+
+    Lc->m[2].rtyp=LIST_CMD;
+    Lc->m[2].data=(void*)Lo;
+    // q-ideal:
+    Lc->m[3].rtyp=IDEAL_CMD;
+    Lc->m[3].data=(void *)idInit(1,1);
+    // ----------------------
+    L->m[0].rtyp=LIST_CMD;
+    L->m[0].data=(void*)Lc;
+  }
+  else
+  {
+    L->m[0].rtyp=INT_CMD;
+    L->m[0].data=(void *)(long)r->cf->ch;
+  }
+#endif
+  // ----------------------------------------
+  // 1: list (var)
+  lists LL=(lists)omAlloc0Bin(slists_bin);
+  LL->Init(r->N);
+  int i;
+  for(i=0; i<r->N; i++)
+  {
+    LL->m[i].rtyp=STRING_CMD;
+    LL->m[i].data=(void *)omStrDup(r->names[i]);
+  }
+  L->m[1].rtyp=LIST_CMD;
+  L->m[1].data=(void *)LL;
+  // ----------------------------------------
+  // 2: list (ord)
+  LL=(lists)omAlloc0Bin(slists_bin);
+  i=rBlocks(r)-1;
+  LL->Init(i);
+  i--;
+  lists LLL;
+  for(; i>=0; i--)
+  {
+    intvec *iv;
+    int j;
+    LL->m[i].rtyp=LIST_CMD;
+    LLL=(lists)omAlloc0Bin(slists_bin);
+    LLL->Init(2);
+    LLL->m[0].rtyp=STRING_CMD;
+    LLL->m[0].data=(void *)omStrDup(rSimpleOrdStr(r->order[i]));
+
+    if(r->order[i] == ringorder_IS) //  || r->order[i] == ringorder_s || r->order[i] == ringorder_S)
+    {
+      assume( r->block0[i] == r->block1[i] );
+      const int s = r->block0[i];
+      assume( -2 < s && s < 2);
+
+      iv=new intvec(1);
+      (*iv)[0] = s;
+    }
+    else if (r->block1[i]-r->block0[i] >=0 )
+    {
+      int bl=j=r->block1[i]-r->block0[i];
+      if (r->order[i]==ringorder_M)
+      {
+        j=(j+1)*(j+1)-1;
+        bl=j+1;
+      }
+      else if (r->order[i]==ringorder_am)
+      {
+        j+=r->wvhdl[i][bl+1];
+      }
+      iv=new intvec(j+1);
+      if ((r->wvhdl!=NULL) && (r->wvhdl[i]!=NULL))
+      {
+        for(;j>=0; j--) (*iv)[j]=r->wvhdl[i][j+(j>bl)];
+      }
+      else switch (r->order[i])
+      {
+        case ringorder_dp:
+        case ringorder_Dp:
+        case ringorder_ds:
+        case ringorder_Ds:
+        case ringorder_lp:
+          for(;j>=0; j--) (*iv)[j]=1;
+          break;
+        default: /* do nothing */;
+      }
+    }
+    else
+    {
+      iv=new intvec(1);
+    }
+    LLL->m[1].rtyp=INTVEC_CMD;
+    LLL->m[1].data=(void *)iv;
+    LL->m[i].data=(void *)LLL;
+  }
+  L->m[2].rtyp=LIST_CMD;
+  L->m[2].data=(void *)LL;
+  // ----------------------------------------
+  // 3: qideal
+  L->m[3].rtyp=IDEAL_CMD;
+  if (r->qideal==NULL)
+    L->m[3].data=(void *)idInit(1,1);
+  else
+    L->m[3].data=(void *)idCopy(r->qideal);
+  // ----------------------------------------
+#ifdef HAVE_PLURAL // NC! in rDecompose
+  if (rIsPluralRing(r))
+  {
+    L->m[4].rtyp=MATRIX_CMD;
+    L->m[4].data=(void *)mp_Copy(r->GetNC()->C, r, r);
+    L->m[5].rtyp=MATRIX_CMD;
+    L->m[5].data=(void *)mp_Copy(r->GetNC()->D, r, r);
+  }
+#endif
+  return L;
+}
+
+void rComposeC(lists L, ring R)
+/* field is R or C */
+{
+  // ----------------------------------------
+  // 0: char/ cf - ring
+  if ((L->m[0].rtyp!=INT_CMD) || (L->m[0].data!=(char *)0))
+  {
+    Werror("invald coeff. field description, expecting 0");
+    return;
+  }
+//  R->cf->ch=0;
+  // ----------------------------------------
+  // 1:
+  if (L->m[1].rtyp!=LIST_CMD)
+    Werror("invald coeff. field description, expecting precision list");
+  lists LL=(lists)L->m[1].data;
+  int r1=(int)(long)LL->m[0].data;
+  int r2=(int)(long)LL->m[1].data;
+  if (L->nr==2) // complex
+    R->cf = nInitChar(n_long_C, NULL);
+  else if ((r1<=SHORT_REAL_LENGTH)
+  && (r2=SHORT_REAL_LENGTH))
+    R->cf = nInitChar(n_R, NULL);
+  else
+  {
+    LongComplexInfo* p = (LongComplexInfo *)omAlloc0(sizeof(LongComplexInfo));
+    p->float_len=r1;
+    p->float_len2=r2;
+    R->cf = nInitChar(n_long_R, NULL);
+  }
+
+  if ((r1<=SHORT_REAL_LENGTH)   // should go into nInitChar
+  && (r2=SHORT_REAL_LENGTH))
+  {
+    R->cf->float_len=SHORT_REAL_LENGTH/2;
+    R->cf->float_len2=SHORT_REAL_LENGTH;
+  }
+  else
+  {
+    R->cf->float_len=si_min(r1,32767);
+    R->cf->float_len2=si_min(r2,32767);
+  }
+  // ----------------------------------------
+  // 2: list (par)
+  if (L->nr==2)
+  {
+    //R->cf->extRing->N=1;
+    if (L->m[2].rtyp!=STRING_CMD)
+    {
+      Werror("invald coeff. field description, expecting parameter name");
+      return;
+    }
+    //(rParameter(R))=(char**)omAlloc0(rPar(R)*sizeof(char_ptr));
+    rParameter(R)[0]=omStrDup((char *)L->m[2].data);
+  }
+  // ----------------------------------------
+}
+
+#ifdef HAVE_RINGS
+void rComposeRing(lists L, ring R)
+/* field is R or C */
+{
+  // ----------------------------------------
+  // 0: string: integer
+  // no further entries --> Z
+  mpz_ptr modBase = NULL;
+  unsigned int modExponent = 1;
+
+  modBase = (mpz_ptr) omAlloc(sizeof(mpz_t));
+  if (L->nr == 0)
+  {
+    mpz_init_set_ui(modBase,0);
+    modExponent = 1;
+  }
+  // ----------------------------------------
+  // 1:
+  else
+  {
+    if (L->m[1].rtyp!=LIST_CMD) Werror("invald data, expecting list of numbers");
+    lists LL=(lists)L->m[1].data;
+    if ((LL->nr >= 0) && LL->m[0].rtyp == BIGINT_CMD)
+    {
+      number tmp= (number) LL->m[0].data; // never use CopyD() on list elements
+                                    // assume that tmp is integer, not rational
+      n_MPZ (modBase, tmp, coeffs_BIGINT);
+    }
+    else if (LL->nr >= 0 && LL->m[0].rtyp == INT_CMD)
+    {
+      mpz_init_set_ui(modBase,(unsigned long) LL->m[0].data);
+    }
+    else
+    {
+      mpz_init_set_ui(modBase,0);
+    }
+    if (LL->nr >= 1)
+    {
+      modExponent = (unsigned long) LL->m[1].data;
+    }
+    else
+    {
+      modExponent = 1;
+    }
+  }
+  // ----------------------------------------
+  if ((mpz_cmp_ui(modBase, 1) == 0) && (mpz_cmp_ui(modBase, 0) < 0))
+  {
+    Werror("Wrong ground ring specification (module is 1)");
+    return;
+  }
+  if (modExponent < 1)
+  {
+    Werror("Wrong ground ring specification (exponent smaller than 1");
+    return;
+  }
+  // module is 0 ---> integers
+  if (mpz_cmp_ui(modBase, 0) == 0)
+  {
+    R->cf=nInitChar(n_Z,NULL);
+  }
+  // we have an exponent
+  else if (modExponent > 1)
+  {
+    //R->cf->ch = R->cf->modExponent;
+    if ((mpz_cmp_ui(modBase, 2) == 0) && (modExponent <= 8*sizeof(unsigned long)))
+    {
+      /* this branch should be active for modExponent = 2..32 resp. 2..64,
+           depending on the size of a long on the respective platform */
+      R->cf=nInitChar(n_Z2m,(void*)(long)modExponent);       // Use Z/2^ch
+      omFreeSize (modBase, sizeof(mpz_t));
+    }
+    else
+    {
+      //ringtype 3
+      ZnmInfo info;
+      info.base= modBase;
+      info.exp= modExponent;
+      R->cf=nInitChar(n_Znm,(void*) &info);
+    }
+  }
+  // just a module m > 1
+  else
+  {
+    //ringtype = 2;
+    //const int ch = mpz_get_ui(modBase);
+    ZnmInfo info;
+    info.base= modBase;
+    info.exp= modExponent;
+    R->cf=nInitChar(n_Zn,(void*) &info);
+  }
+}
+#endif
+
+static void rRenameVars(ring R)
+{
+  int i,j;
+  BOOLEAN ch;
+  do
+  {
+    ch=0;
+    for(i=0;i<R->N-1;i++)
+    {
+      for(j=i+1;j<R->N;j++)
+      {
+        if (strcmp(R->names[i],R->names[j])==0)
+        {
+          ch=TRUE;
+          Warn("name conflict var(%d) and var(%d): `%s`, rename to `@%s`",i+1,j+1,R->names[i],R->names[i]);
+          omFree(R->names[j]);
+          R->names[j]=(char *)omAlloc(2+strlen(R->names[i]));
+          sprintf(R->names[j],"@%s",R->names[i]);
+        }
+      }
+    }
+  }
+  while (ch);
+  for(i=0;i<rPar(R); i++)
+  {
+    for(j=0;j<R->N;j++)
+    {
+      if (strcmp(rParameter(R)[i],R->names[j])==0)
+      {
+        Warn("name conflict par(%d) and var(%d): `%s`, renaming the VARIABLE to `@@(%d)`",i+1,j+1,R->names[j],i+1);
+//        omFree(rParameter(R)[i]);
+//        rParameter(R)[i]=(char *)omAlloc(10);
+//        sprintf(rParameter(R)[i],"@@(%d)",i+1);
+        omFree(R->names[j]);
+        R->names[j]=(char *)omAlloc(10);
+        sprintf(R->names[j],"@@(%d)",i+1);
+      }
+    }
+  }
+}
+
+ring rCompose(const lists  L, const BOOLEAN check_comp)
+{
+  if ((L->nr!=3)
+#ifdef HAVE_PLURAL
+  &&(L->nr!=5)
+#endif
+  )
+    return NULL;
+  int is_gf_char=0;
+  // 0: char/ cf - ring
+  // 1: list (var)
+  // 2: list (ord)
+  // 3: qideal
+  // possibly:
+  // 4: C
+  // 5: D
+
+  ring R = (ring) omAlloc0Bin(sip_sring_bin);
+
+
+  // ------------------------------------------------------------------
+  // 0: char:
+#ifdef SINGULAR_4_1
+  if (L->m[0].Typ()==CRING_CMD)
+  {
+    R->cf=(coeffs)L->m[0].Data();
+    R->cf->ref++;
+  }
+  else
+#endif
+  if (L->m[0].Typ()==INT_CMD)
+  {
+    int ch = (int)(long)L->m[0].Data();
+    assume( ch >= 0 );
+
+    if (ch == 0) // Q?
+      R->cf = nInitChar(n_Q, NULL);
+    else
+    {
+      int l = IsPrime(ch); // Zp?
+      if( l != ch )
+      {
+        Warn("%d is invalid characteristic of ground field. %d is used.", ch, l);
+        ch = l;
+      }
+      R->cf = nInitChar(n_Zp, (void*)(long)ch);
+    }
+  }
+  else if (L->m[0].Typ()==LIST_CMD) // something complicated...
+  {
+    lists LL=(lists)L->m[0].Data();
+
+#ifdef HAVE_RINGS
+    if (LL->m[0].Typ() == STRING_CMD) // 1st comes a string?
+    {
+      rComposeRing(LL, R); // Ring!?
+    }
+    else
+#endif
+    if (LL->nr < 3)
+      rComposeC(LL,R); // R, long_R, long_C
+    else
+    {
+      if (LL->m[0].Typ()==INT_CMD)
+      {
+        int ch = (int)(long)LL->m[0].Data();
+        while ((ch!=fftable[is_gf_char]) && (fftable[is_gf_char])) is_gf_char++;
+        if (fftable[is_gf_char]==0) is_gf_char=-1;
+
+        if(is_gf_char!= -1)
+        {
+          GFInfo param;
+
+          param.GFChar = ch;
+          param.GFDegree = 1;
+          param.GFPar_name = (const char*)(((lists)(LL->m[1].Data()))->m[0].Data());
+
+          // nfInitChar should be able to handle the case when ch is in fftables!
+          R->cf = nInitChar(n_GF, (void*)&param);
+        }
+      }
+
+      if( R->cf == NULL )
+      {
+        ring extRing = rCompose((lists)L->m[0].Data(),FALSE);
+
+        if (extRing==NULL)
+        {
+          WerrorS("could not create the specified coefficient field");
+          goto rCompose_err;
+        }
+
+        if( extRing->qideal != NULL ) // Algebraic extension
+        {
+          AlgExtInfo extParam;
+
+          extParam.r = extRing;
+
+          R->cf = nInitChar(n_algExt, (void*)&extParam);
+        }
+        else // Transcendental extension
+        {
+          TransExtInfo extParam;
+          extParam.r = extRing;
+          assume( extRing->qideal == NULL );
+
+          R->cf = nInitChar(n_transExt, &extParam);
+        }
+      }
+    }
+  }
+  else
+  {
+    WerrorS("coefficient field must be described by `int` or `list`");
+    goto rCompose_err;
+  }
+
+  if( R->cf == NULL )
+  {
+    WerrorS("could not create coefficient field described by the input!");
+    goto rCompose_err;
+  }
+
+  // ------------------------- VARS ---------------------------
+  if (L->m[1].Typ()==LIST_CMD)
+  {
+    lists v=(lists)L->m[1].Data();
+    R->N = v->nr+1;
+    if (R->N<=0)
+    {
+      WerrorS("no ring variables");
+      goto rCompose_err;
+    }
+    R->names   = (char **)omAlloc0(R->N * sizeof(char_ptr));
+    int i;
+    for(i=0;i<R->N;i++)
+    {
+      if (v->m[i].Typ()==STRING_CMD)
+        R->names[i]=omStrDup((char *)v->m[i].Data());
+      else if (v->m[i].Typ()==POLY_CMD)
+      {
+        poly p=(poly)v->m[i].Data();
+        int nr=pIsPurePower(p);
+        if (nr>0)
+          R->names[i]=omStrDup(currRing->names[nr-1]);
+        else
+        {
+          Werror("var name %d must be a string or a ring variable",i+1);
+          goto rCompose_err;
+        }
+      }
+      else
+      {
+        Werror("var name %d must be `string`",i+1);
+        goto rCompose_err;
+      }
+    }
+  }
+  else
+  {
+    WerrorS("variable must be given as `list`");
+    goto rCompose_err;
+  }
+  // ------------------------ ORDER ------------------------------
+  if (L->m[2].Typ()==LIST_CMD)
+  {
+    lists v=(lists)L->m[2].Data();
+    int n= v->nr+2;
+    int j;
+    // initialize fields of R
+    R->order=(int *)omAlloc0(n*sizeof(int));
+    R->block0=(int *)omAlloc0(n*sizeof(int));
+    R->block1=(int *)omAlloc0(n*sizeof(int));
+    R->wvhdl=(int**)omAlloc0(n*sizeof(int_ptr));
+    // init order, so that rBlocks works correctly
+    for (j=0; j < n-1; j++)
+      R->order[j] = (int) ringorder_unspec;
+    // orderings
+    for(j=0;j<n-1;j++)
+    {
+    // todo: a(..), M
+      if (v->m[j].Typ()!=LIST_CMD)
+      {
+        WerrorS("ordering must be list of lists");
+        goto rCompose_err;
+      }
+      lists vv=(lists)v->m[j].Data();
+      if ((vv->nr!=1)
+      || (vv->m[0].Typ()!=STRING_CMD)
+      || ((vv->m[1].Typ()!=INTVEC_CMD) && (vv->m[1].Typ()!=INT_CMD)))
+      {
+        WerrorS("ordering name must be a (string,intvec)");
+        goto rCompose_err;
+      }
+      R->order[j]=rOrderName(omStrDup((char*)vv->m[0].Data())); // assume STRING
+
+      if (j==0) R->block0[0]=1;
+      else
+      {
+         int jj=j-1;
+         while((jj>=0)
+         && ((R->order[jj]== ringorder_a)
+            || (R->order[jj]== ringorder_aa)
+            || (R->order[jj]== ringorder_am)
+            || (R->order[jj]== ringorder_c)
+            || (R->order[jj]== ringorder_C)
+            || (R->order[jj]== ringorder_s)
+            || (R->order[jj]== ringorder_S)
+         ))
+         {
+           //Print("jj=%, skip %s\n",rSimpleOrdStr(R->order[jj]));
+           jj--;
+         }
+         if (jj<0) R->block0[j]=1;
+         else       R->block0[j]=R->block1[jj]+1;
+      }
+      intvec *iv;
+      if (vv->m[1].Typ()==INT_CMD)
+        iv=new intvec((int)(long)vv->m[1].Data(),(int)(long)vv->m[1].Data());
+      else
+        iv=ivCopy((intvec*)vv->m[1].Data()); //assume INTVEC
+      int iv_len=iv->length();
+      R->block1[j]=si_max(R->block0[j],R->block0[j]+iv_len-1);
+      if (R->block1[j]>R->N)
+      {
+        R->block1[j]=R->N;
+        iv_len=R->block1[j]-R->block0[j]+1;
+      }
+      //Print("block %d from %d to %d\n",j,R->block0[j], R->block1[j]);
+      int i;
+      switch (R->order[j])
+      {
+         case ringorder_ws:
+         case ringorder_Ws:
+            R->OrdSgn=-1;
+         case ringorder_aa:
+         case ringorder_a:
+         case ringorder_wp:
+         case ringorder_Wp:
+           R->wvhdl[j] =( int *)omAlloc(iv_len*sizeof(int));
+           for (i=0; i<iv_len;i++)
+           {
+             R->wvhdl[j][i]=(*iv)[i];
+           }
+           break;
+         case ringorder_am:
+           R->wvhdl[j] =( int *)omAlloc((iv->length()+1)*sizeof(int));
+           for (i=0; i<iv_len;i++)
+           {
+             R->wvhdl[j][i]=(*iv)[i];
+           }
+           R->wvhdl[j][i]=iv->length() - iv_len;
+           //printf("ivlen:%d,iv->len:%d,mod:%d\n",iv_len,iv->length(),R->wvhdl[j][i]);
+           for (; i<iv->length(); i++)
+           {
+              R->wvhdl[j][i+1]=(*iv)[i];
+           }
+           break;
+         case ringorder_M:
+           R->wvhdl[j] =( int *)omAlloc((iv->length())*sizeof(int));
+           for (i=0; i<iv->length();i++) R->wvhdl[j][i]=(*iv)[i];
+           R->block1[j]=si_max(R->block0[j],R->block0[j]+(int)sqrt((double)(iv->length()-1)));
+           if (R->block1[j]>R->N)
+           {
+             WerrorS("ordering matrix too big");
+             goto rCompose_err;
+           }
+           break;
+         case ringorder_ls:
+         case ringorder_ds:
+         case ringorder_Ds:
+         case ringorder_rs:
+           R->OrdSgn=-1;
+         case ringorder_lp:
+         case ringorder_dp:
+         case ringorder_Dp:
+         case ringorder_rp:
+           break;
+         case ringorder_S:
+           break;
+         case ringorder_c:
+         case ringorder_C:
+           R->block1[j]=R->block0[j]=0;
+           break;
+
+         case ringorder_s:
+           break;
+
+         case ringorder_IS:
+         {
+           R->block1[j] = R->block0[j] = 0;
+           if( iv->length() > 0 )
+           {
+             const int s = (*iv)[0];
+             assume( -2 < s && s < 2 );
+             R->block1[j] = R->block0[j] = s;
+           }
+           break;
+         }
+         case 0:
+         case ringorder_unspec:
+           break;
+      }
+      delete iv;
+    }
+    // sanity check
+    j=n-2;
+    if ((R->order[j]==ringorder_c)
+    || (R->order[j]==ringorder_C)
+    || (R->order[j]==ringorder_unspec)) j--;
+    if (R->block1[j] != R->N)
+    {
+      if (((R->order[j]==ringorder_dp) ||
+           (R->order[j]==ringorder_ds) ||
+           (R->order[j]==ringorder_Dp) ||
+           (R->order[j]==ringorder_Ds) ||
+           (R->order[j]==ringorder_rp) ||
+           (R->order[j]==ringorder_rs) ||
+           (R->order[j]==ringorder_lp) ||
+           (R->order[j]==ringorder_ls))
+          &&
+            R->block0[j] <= R->N)
+      {
+        R->block1[j] = R->N;
+      }
+      else
+      {
+        Werror("ordering incomplete: size (%d) should be %d",R->block1[j],R->N);
+        goto rCompose_err;
+      }
+    }
+    if (R->block0[j]>R->N)
+    {
+      Werror("not enough variables (%d) for ordering block %d, scanned so far:",R->N,j+1);
+      for(int ii=0;ii<=j;ii++)
+        Werror("ord[%d]: %s from v%d to v%d",ii+1,rSimpleOrdStr(R->order[ii]),R->block0[ii],R->block1[ii]);
+      goto rCompose_err;
+    }
+    if (check_comp)
+    {
+      BOOLEAN comp_order=FALSE;
+      int jj;
+      for(jj=0;jj<n;jj++)
+      {
+        if ((R->order[jj]==ringorder_c) ||
+            (R->order[jj]==ringorder_C)) { comp_order=TRUE; break; }
+      }
+      if (!comp_order)
+      {
+        R->order=(int*)omRealloc0Size(R->order,n*sizeof(int),(n+1)*sizeof(int));
+        R->block0=(int*)omRealloc0Size(R->block0,n*sizeof(int),(n+1)*sizeof(int));
+        R->block1=(int*)omRealloc0Size(R->block1,n*sizeof(int),(n+1)*sizeof(int));
+        R->wvhdl=(int**)omRealloc0Size(R->wvhdl,n*sizeof(int_ptr),(n+1)*sizeof(int_ptr));
+        R->order[n-1]=ringorder_C;
+        R->block0[n-1]=0;
+        R->block1[n-1]=0;
+        R->wvhdl[n-1]=NULL;
+        n++;
+      }
+    }
+  }
+  else
+  {
+    WerrorS("ordering must be given as `list`");
+    goto rCompose_err;
+  }
+
+  // ------------------------ ??????? --------------------
+
+  rRenameVars(R);
+  rComplete(R);
+
+/*#ifdef HAVE_RINGS
+// currently, coefficients which are ring elements require a global ordering:
+  if (rField_is_Ring(R) && (R->OrdSgn==-1))
+  {
+    WerrorS("global ordering required for these coefficients");
+    goto rCompose_err;
+  }
+#endif*/
+
+
+  // ------------------------ Q-IDEAL ------------------------
+
+  if (L->m[3].Typ()==IDEAL_CMD)
+  {
+    ideal q=(ideal)L->m[3].Data();
+    if (q->m[0]!=NULL)
+    {
+      if (R->cf != currRing->cf) //->cf->ch!=currRing->cf->ch)
+      {
+      #if 0
+            WerrorS("coefficient fields must be equal if q-ideal !=0");
+            goto rCompose_err;
+      #else
+        ring orig_ring=currRing;
+        rChangeCurrRing(R);
+        int *perm=NULL;
+        int *par_perm=NULL;
+        int par_perm_size=0;
+        nMapFunc nMap;
+
+        if ((nMap=nSetMap(orig_ring->cf))==NULL)
+        {
+          if (rEqual(orig_ring,currRing))
+          {
+            nMap=n_SetMap(currRing->cf, currRing->cf);
+          }
+          else
+          // Allow imap/fetch to be make an exception only for:
+          if ( (rField_is_Q_a(orig_ring) &&  // Q(a..) -> Q(a..) || Q || Zp || Zp(a)
+            (rField_is_Q(currRing) || rField_is_Q_a(currRing) ||
+             (rField_is_Zp(currRing) || rField_is_Zp_a(currRing))))
+           ||
+           (rField_is_Zp_a(orig_ring) &&  // Zp(a..) -> Zp(a..) || Zp
+            (rField_is_Zp(currRing, rInternalChar(orig_ring)) ||
+             rField_is_Zp_a(currRing, rInternalChar(orig_ring)))) )
+          {
+            par_perm_size=rPar(orig_ring);
+
+//            if ((orig_ring->minpoly != NULL) || (orig_ring->qideal != NULL))
+//              naSetChar(rInternalChar(orig_ring),orig_ring);
+//            else ntSetChar(rInternalChar(orig_ring),orig_ring);
+
+            nSetChar(currRing->cf);
+          }
+          else
+          {
+            WerrorS("coefficient fields must be equal if q-ideal !=0");
+            goto rCompose_err;
+          }
+        }
+        perm=(int *)omAlloc0((orig_ring->N+1)*sizeof(int));
+        if (par_perm_size!=0)
+          par_perm=(int *)omAlloc0(par_perm_size*sizeof(int));
+        int i;
+        #if 0
+        // use imap:
+        maFindPerm(orig_ring->names,orig_ring->N,orig_ring->parameter,orig_ring->P,
+          currRing->names,currRing->N,currRing->parameter, currRing->P,
+          perm,par_perm, currRing->ch);
+        #else
+        // use fetch
+        if ((rPar(orig_ring)>0) && (rPar(currRing)==0))
+        {
+          for(i=si_min(rPar(orig_ring),rVar(currRing))-1;i>=0;i--) par_perm[i]=i+1;
+        }
+        else if (par_perm_size!=0)
+          for(i=si_min(rPar(orig_ring),rPar(currRing))-1;i>=0;i--) par_perm[i]=-(i+1);
+        for(i=si_min(orig_ring->N,rVar(currRing));i>0;i--) perm[i]=i;
+        #endif
+        ideal dest_id=idInit(IDELEMS(q),1);
+        for(i=IDELEMS(q)-1; i>=0; i--)
+        {
+          dest_id->m[i]=p_PermPoly(q->m[i],perm,orig_ring, currRing,nMap,
+                                  par_perm,par_perm_size);
+          //  PrintS("map:");pWrite(dest_id->m[i]);PrintLn();
+          pTest(dest_id->m[i]);
+        }
+        R->qideal=dest_id;
+        if (perm!=NULL)
+          omFreeSize((ADDRESS)perm,(orig_ring->N+1)*sizeof(int));
+        if (par_perm!=NULL)
+          omFreeSize((ADDRESS)par_perm,par_perm_size*sizeof(int));
+        rChangeCurrRing(orig_ring);
+      #endif
+      }
+      else
+        R->qideal=idrCopyR(q,currRing,R);
+    }
+  }
+  else
+  {
+    WerrorS("q-ideal must be given as `ideal`");
+    goto rCompose_err;
+  }
+
+
+  // ---------------------------------------------------------------
+  #ifdef HAVE_PLURAL
+  if (L->nr==5)
+  {
+    if (nc_CallPlural((matrix)L->m[4].Data(),
+                      (matrix)L->m[5].Data(),
+                      NULL,NULL,
+                      R,
+                      true, // !!!
+                      true, false,
+                      currRing, FALSE)) goto rCompose_err;
+    // takes care about non-comm. quotient! i.e. calls "nc_SetupQuotient" due to last true
+  }
+  #endif
+  return R;
+
+rCompose_err:
+  if (R->N>0)
+  {
+    int i;
+    if (R->names!=NULL)
+    {
+      i=R->N-1;
+      while (i>=0) { if (R->names[i]!=NULL) omFree(R->names[i]); i--; }
+      omFree(R->names);
+    }
+  }
+  if (R->order!=NULL) omFree(R->order);
+  if (R->block0!=NULL) omFree(R->block0);
+  if (R->block1!=NULL) omFree(R->block1);
+  if (R->wvhdl!=NULL) omFree(R->wvhdl);
+  omFree(R);
+  return NULL;
+}
+
+// from matpol.cc
+
+/*2
+* compute the jacobi matrix of an ideal
+*/
+BOOLEAN mpJacobi(leftv res,leftv a)
+{
+  int     i,j;
+  matrix result;
+  ideal id=(ideal)a->Data();
+
+  result =mpNew(IDELEMS(id),rVar(currRing));
+  for (i=1; i<=IDELEMS(id); i++)
+  {
+    for (j=1; j<=rVar(currRing); j++)
+    {
+      MATELEM(result,i,j) = pDiff(id->m[i-1],j);
+    }
+  }
+  res->data=(char *)result;
+  return FALSE;
+}
+
+/*2
+* returns the Koszul-matrix of degree d of a vectorspace with dimension n
+* uses the first n entrees of id, if id <> NULL
+*/
+BOOLEAN mpKoszul(leftv res,leftv c/*ip*/, leftv b/*in*/, leftv id)
+{
+  int n=(int)(long)b->Data();
+  int d=(int)(long)c->Data();
+  int     k,l,sign,row,col;
+  matrix  result;
+  ideal temp;
+  BOOLEAN bo;
+  poly    p;
+
+  if ((d>n) || (d<1) || (n<1))
+  {
+    res->data=(char *)mpNew(1,1);
+    return FALSE;
+  }
+  int *choise = (int*)omAlloc(d*sizeof(int));
+  if (id==NULL)
+    temp=idMaxIdeal(1);
+  else
+    temp=(ideal)id->Data();
+
+  k = binom(n,d);
+  l = k*d;
+  l /= n-d+1;
+  result =mpNew(l,k);
+  col = 1;
+  idInitChoise(d,1,n,&bo,choise);
+  while (!bo)
+  {
+    sign = 1;
+    for (l=1;l<=d;l++)
+    {
+      if (choise[l-1]<=IDELEMS(temp))
+      {
+        p = pCopy(temp->m[choise[l-1]-1]);
+        if (sign == -1) p = pNeg(p);
+        sign *= -1;
+        row = idGetNumberOfChoise(l-1,d,1,n,choise);
+        MATELEM(result,row,col) = p;
+      }
+    }
+    col++;
+    idGetNextChoise(d,n,&bo,choise);
+  }
+  if (id==NULL) idDelete(&temp);
+
+  res->data=(char *)result;
+  return FALSE;
+}
+
+// from syz1.cc
+/*2
+* read out the Betti numbers from resolution
+* (interpreter interface)
+*/
+BOOLEAN syBetti2(leftv res, leftv u, leftv w)
+{
+  syStrategy syzstr=(syStrategy)u->Data();
+
+  BOOLEAN minim=(int)(long)w->Data();
+  int row_shift=0;
+  int add_row_shift=0;
+  intvec *weights=NULL;
+  intvec *ww=(intvec *)atGet(u,"isHomog",INTVEC_CMD);
+  if (ww!=NULL)
+  {
+     weights=ivCopy(ww);
+     add_row_shift = ww->min_in();
+     (*weights) -= add_row_shift;
+  }
+
+  res->data=(void *)syBettiOfComputation(syzstr,minim,&row_shift,weights);
+  //row_shift += add_row_shift;
+  //Print("row_shift=%d, add_row_shift=%d\n",row_shift,add_row_shift);
+  atSet(res,omStrDup("rowShift"),(void*)(long)add_row_shift,INT_CMD);
+
+  return FALSE;
+}
+BOOLEAN syBetti1(leftv res, leftv u)
+{
+  sleftv tmp;
+  memset(&tmp,0,sizeof(tmp));
+  tmp.rtyp=INT_CMD;
+  tmp.data=(void *)1;
+  return syBetti2(res,u,&tmp);
+}
+
+/*3
+* converts a resolution into a list of modules
+*/
+lists syConvRes(syStrategy syzstr,BOOLEAN toDel,int add_row_shift)
+{
+  resolvente fullres = syzstr->fullres;
+  resolvente minres = syzstr->minres;
+
+  const int length = syzstr->length;
+
+  if ((fullres==NULL) && (minres==NULL))
+  {
+    if (syzstr->hilb_coeffs==NULL)
+    { // La Scala
+      fullres = syReorder(syzstr->res, length, syzstr);
+    }
+    else
+    { // HRES
+      minres = syReorder(syzstr->orderedRes, length, syzstr);
+      syKillEmptyEntres(minres, length);
+    }
+  }
+
+  resolvente tr;
+  int typ0=IDEAL_CMD;
+
+  if (minres!=NULL)
+    tr = minres;
+  else
+    tr = fullres;
+
+  resolvente trueres=NULL; intvec ** w=NULL;
+
+  if (length>0)
+  {
+    trueres = (resolvente)omAlloc0((length)*sizeof(ideal));
+    for (int i=(length)-1;i>=0;i--)
+    {
+      if (tr[i]!=NULL)
+      {
+        trueres[i] = idCopy(tr[i]);
+      }
+    }
+    if ( id_RankFreeModule(trueres[0], currRing) > 0)
+      typ0 = MODUL_CMD;
+    if (syzstr->weights!=NULL)
+    {
+      w = (intvec**)omAlloc0(length*sizeof(intvec*));
+      for (int i=length-1;i>=0;i--)
+      {
+        if (syzstr->weights[i]!=NULL) w[i] = ivCopy(syzstr->weights[i]);
+      }
+    }
+  }
+
+  lists li = liMakeResolv(trueres, length, syzstr->list_length,typ0,
+                          w, add_row_shift);
+
+  if (w != NULL) omFreeSize(w, length*sizeof(intvec*));
+
+  if (toDel)
+    syKillComputation(syzstr);
+  else
+  {
+    if( fullres != NULL && syzstr->fullres == NULL )
+      syzstr->fullres = fullres;
+
+    if( minres != NULL && syzstr->minres == NULL )
+      syzstr->minres = minres;
+  }
+
+  return li;
+
+
+}
+
+/*3
+* converts a list of modules into a resolution
+*/
+syStrategy syConvList(lists li,BOOLEAN toDel)
+{
+  int typ0;
+  syStrategy result=(syStrategy)omAlloc0(sizeof(ssyStrategy));
+
+  resolvente fr = liFindRes(li,&(result->length),&typ0,&(result->weights));
+  if (fr != NULL)
+  {
+
+    result->fullres = (resolvente)omAlloc0((result->length+1)*sizeof(ideal));
+    for (int i=result->length-1;i>=0;i--)
+    {
+      if (fr[i]!=NULL)
+        result->fullres[i] = idCopy(fr[i]);
+    }
+    result->list_length=result->length;
+    omFreeSize((ADDRESS)fr,(result->length)*sizeof(ideal));
+  }
+  else
+  {
+    omFreeSize(result, sizeof(ssyStrategy));
+    result = NULL;
+  }
+  if (toDel) li->Clean();
+  return result;
+}
+
+/*3
+* converts a list of modules into a minimal resolution
+*/
+syStrategy syForceMin(lists li)
+{
+  int typ0;
+  syStrategy result=(syStrategy)omAlloc0(sizeof(ssyStrategy));
+
+  resolvente fr = liFindRes(li,&(result->length),&typ0);
+  result->minres = (resolvente)omAlloc0((result->length+1)*sizeof(ideal));
+  for (int i=result->length-1;i>=0;i--)
+  {
+    if (fr[i]!=NULL)
+      result->minres[i] = idCopy(fr[i]);
+  }
+  omFreeSize((ADDRESS)fr,(result->length)*sizeof(ideal));
+  return result;
+}
+// from weight.cc
+BOOLEAN kWeight(leftv res,leftv id)
+{
+  ideal F=(ideal)id->Data();
+  intvec * iv = new intvec(rVar(currRing));
+  polyset s;
+  int  sl, n, i;
+  int  *x;
+
+  res->data=(char *)iv;
+  s = F->m;
+  sl = IDELEMS(F) - 1;
+  n = rVar(currRing);
+  double wNsqr = (double)2.0 / (double)n;
+  wFunctional = wFunctionalBuch;
+  x = (int * )omAlloc(2 * (n + 1) * sizeof(int));
+  wCall(s, sl, x, wNsqr, currRing);
+  for (i = n; i!=0; i--)
+    (*iv)[i-1] = x[i + n + 1];
+  omFreeSize((ADDRESS)x, 2 * (n + 1) * sizeof(int));
+  return FALSE;
+}
+
+BOOLEAN kQHWeight(leftv res,leftv v)
+{
+  res->data=(char *)id_QHomWeight((ideal)v->Data(), currRing);
+  if (res->data==NULL)
+    res->data=(char *)new intvec(rVar(currRing));
+  return FALSE;
+}
+/*==============================================================*/
+// from clapsing.cc
+#if 0
+BOOLEAN jjIS_SQR_FREE(leftv res, leftv u)
+{
+  BOOLEAN b=singclap_factorize((poly)(u->CopyD()), &v, 0);
+  res->data=(void *)b;
+}
+#endif
+
+BOOLEAN jjRESULTANT(leftv res, leftv u, leftv v, leftv w)
+{
+  res->data=singclap_resultant((poly)u->CopyD(),(poly)v->CopyD(),
+                  (poly)w->CopyD(), currRing);
+  return errorreported;
+}
+
+BOOLEAN jjCHARSERIES(leftv res, leftv u)
+{
+  res->data=singclap_irrCharSeries((ideal)u->Data(), currRing);
+  return (res->data==NULL);
+}
+
+// from semic.cc
+#ifdef HAVE_SPECTRUM
+
+// ----------------------------------------------------------------------------
+//  Initialize a  spectrum  deep from a  singular  lists
+// ----------------------------------------------------------------------------
+
+void copy_deep( spectrum& spec, lists l )
+{
+    spec.mu = (int)(long)(l->m[0].Data( ));
+    spec.pg = (int)(long)(l->m[1].Data( ));
+    spec.n  = (int)(long)(l->m[2].Data( ));
+
+    spec.copy_new( spec.n );
+
+    intvec  *num = (intvec*)l->m[3].Data( );
+    intvec  *den = (intvec*)l->m[4].Data( );
+    intvec  *mul = (intvec*)l->m[5].Data( );
+
+    for( int i=0; i<spec.n; i++ )
+    {
+        spec.s[i] = (Rational)((*num)[i])/(Rational)((*den)[i]);
+        spec.w[i] = (*mul)[i];
+    }
+}
+
+// ----------------------------------------------------------------------------
+//  singular lists  constructor for  spectrum
+// ----------------------------------------------------------------------------
+
+spectrum /*former spectrum::spectrum ( lists l )*/
+spectrumFromList( lists l )
+{
+    spectrum result;
+    copy_deep( result, l );
+    return result;
+}
+
+// ----------------------------------------------------------------------------
+//  generate a Singular  lists  from a spectrum
+// ----------------------------------------------------------------------------
+
+/* former spectrum::thelist ( void )*/
+lists   getList( spectrum& spec )
+{
+    lists   L  = (lists)omAllocBin( slists_bin);
+
+    L->Init( 6 );
+
+    intvec            *num  = new intvec( spec.n );
+    intvec            *den  = new intvec( spec.n );
+    intvec            *mult = new intvec( spec.n );
+
+    for( int i=0; i<spec.n; i++ )
+    {
+        (*num) [i] = spec.s[i].get_num_si( );
+        (*den) [i] = spec.s[i].get_den_si( );
+        (*mult)[i] = spec.w[i];
+    }
+
+    L->m[0].rtyp = INT_CMD;    //  milnor number
+    L->m[1].rtyp = INT_CMD;    //  geometrical genus
+    L->m[2].rtyp = INT_CMD;    //  # of spectrum numbers
+    L->m[3].rtyp = INTVEC_CMD; //  numerators
+    L->m[4].rtyp = INTVEC_CMD; //  denomiantors
+    L->m[5].rtyp = INTVEC_CMD; //  multiplicities
+
+    L->m[0].data = (void*)(long)spec.mu;
+    L->m[1].data = (void*)(long)spec.pg;
+    L->m[2].data = (void*)(long)spec.n;
+    L->m[3].data = (void*)num;
+    L->m[4].data = (void*)den;
+    L->m[5].data = (void*)mult;
+
+    return  L;
+}
+// from spectrum.cc
+// ----------------------------------------------------------------------------
+//  print out an error message for a spectrum list
+// ----------------------------------------------------------------------------
+
+typedef enum
+{
+    semicOK,
+    semicMulNegative,
+
+    semicListTooShort,
+    semicListTooLong,
+
+    semicListFirstElementWrongType,
+    semicListSecondElementWrongType,
+    semicListThirdElementWrongType,
+    semicListFourthElementWrongType,
+    semicListFifthElementWrongType,
+    semicListSixthElementWrongType,
+
+    semicListNNegative,
+    semicListWrongNumberOfNumerators,
+    semicListWrongNumberOfDenominators,
+    semicListWrongNumberOfMultiplicities,
+
+    semicListMuNegative,
+    semicListPgNegative,
+    semicListNumNegative,
+    semicListDenNegative,
+    semicListMulNegative,
+
+    semicListNotSymmetric,
+    semicListNotMonotonous,
+
+    semicListMilnorWrong,
+    semicListPGWrong
+
+} semicState;
+
+void    list_error( semicState state )
+{
+    switch( state )
+    {
+        case semicListTooShort:
+            WerrorS( "the list is too short" );
+            break;
+        case semicListTooLong:
+            WerrorS( "the list is too long" );
+            break;
+
+        case semicListFirstElementWrongType:
+            WerrorS( "first element of the list should be int" );
+            break;
+        case semicListSecondElementWrongType:
+            WerrorS( "second element of the list should be int" );
+            break;
+        case semicListThirdElementWrongType:
+            WerrorS( "third element of the list should be int" );
+            break;
+        case semicListFourthElementWrongType:
+            WerrorS( "fourth element of the list should be intvec" );
+            break;
+        case semicListFifthElementWrongType:
+            WerrorS( "fifth element of the list should be intvec" );
+            break;
+        case semicListSixthElementWrongType:
+            WerrorS( "sixth element of the list should be intvec" );
+            break;
+
+        case semicListNNegative:
+            WerrorS( "first element of the list should be positive" );
+            break;
+        case semicListWrongNumberOfNumerators:
+            WerrorS( "wrong number of numerators" );
+            break;
+        case semicListWrongNumberOfDenominators:
+            WerrorS( "wrong number of denominators" );
+            break;
+        case semicListWrongNumberOfMultiplicities:
+            WerrorS( "wrong number of multiplicities" );
+            break;
+
+        case semicListMuNegative:
+            WerrorS( "the Milnor number should be positive" );
+            break;
+        case semicListPgNegative:
+            WerrorS( "the geometrical genus should be nonnegative" );
+            break;
+        case semicListNumNegative:
+            WerrorS( "all numerators should be positive" );
+            break;
+        case semicListDenNegative:
+            WerrorS( "all denominators should be positive" );
+            break;
+        case semicListMulNegative:
+            WerrorS( "all multiplicities should be positive" );
+            break;
+
+        case semicListNotSymmetric:
+            WerrorS( "it is not symmetric" );
+            break;
+        case semicListNotMonotonous:
+            WerrorS( "it is not monotonous" );
+            break;
+
+        case semicListMilnorWrong:
+            WerrorS( "the Milnor number is wrong" );
+            break;
+        case semicListPGWrong:
+            WerrorS( "the geometrical genus is wrong" );
+            break;
+
+        default:
+            WerrorS( "unspecific error" );
+            break;
+    }
+}
+// ----------------------------------------------------------------------------
+//  this is the main spectrum computation function
+// ----------------------------------------------------------------------------
+
+enum    spectrumState
+{
+    spectrumOK,
+    spectrumZero,
+    spectrumBadPoly,
+    spectrumNoSingularity,
+    spectrumNotIsolated,
+    spectrumDegenerate,
+    spectrumWrongRing,
+    spectrumNoHC,
+    spectrumUnspecErr
+};
+
+// from splist.cc
+// ----------------------------------------------------------------------------
+//  Compute the spectrum of a  spectrumPolyList
+// ----------------------------------------------------------------------------
+
+/* former spectrumPolyList::spectrum ( lists*, int) */
+spectrumState   spectrumStateFromList( spectrumPolyList& speclist, lists *L,int fast )
+{
+  spectrumPolyNode  **node = &speclist.root;
+  spectrumPolyNode  *search;
+
+  poly              f,tmp;
+  int               found,cmp;
+
+  Rational smax( ( fast==0 ? 0 : rVar(currRing) ),
+                 ( fast==2 ? 2 : 1 ) );
+
+  Rational weight_prev( 0,1 );
+
+  int     mu = 0;          // the milnor number
+  int     pg = 0;          // the geometrical genus
+  int     n  = 0;          // number of different spectral numbers
+  int     z  = 0;          // number of spectral number equal to smax
+
+  while( (*node)!=(spectrumPolyNode*)NULL &&
+         ( fast==0 || (*node)->weight<=smax ) )
+  {
+        // ---------------------------------------
+        //  determine the first normal form which
+        //  contains the monomial  node->mon
+        // ---------------------------------------
+
+    found  = FALSE;
+    search = *node;
+
+    while( search!=(spectrumPolyNode*)NULL && found==FALSE )
+    {
+      if( search->nf!=(poly)NULL )
+      {
+        f = search->nf;
+
+        do
+        {
+                    // --------------------------------
+                    //  look for  (*node)->mon  in   f
+                    // --------------------------------
+
+          cmp = pCmp( (*node)->mon,f );
+
+          if( cmp<0 )
+          {
+            f = pNext( f );
+          }
+          else if( cmp==0 )
+          {
+                        // -----------------------------
+                        //  we have found a normal form
+                        // -----------------------------
+
+            found = TRUE;
+
+                        //  normalize coefficient
+
+            number inv = nInvers( pGetCoeff( f ) );
+            pMult_nn( search->nf,inv );
+            nDelete( &inv );
+
+                        //  exchange  normal forms
+
+            tmp         = (*node)->nf;
+            (*node)->nf = search->nf;
+            search->nf  = tmp;
+          }
+        }
+        while( cmp<0 && f!=(poly)NULL );
+      }
+      search = search->next;
+    }
+
+    if( found==FALSE )
+    {
+            // ------------------------------------------------
+            //  the weight of  node->mon  is a spectrum number
+            // ------------------------------------------------
+
+      mu++;
+
+      if( (*node)->weight<=(Rational)1 )              pg++;
+      if( (*node)->weight==smax )           z++;
+      if( (*node)->weight>weight_prev )     n++;
+
+      weight_prev = (*node)->weight;
+      node = &((*node)->next);
+    }
+    else
+    {
+            // -----------------------------------------------
+            //  determine all other normal form which contain
+            //  the monomial  node->mon
+            //  replace for  node->mon  its normal form
+            // -----------------------------------------------
+
+      while( search!=(spectrumPolyNode*)NULL )
+      {
+        if( search->nf!=(poly)NULL )
+        {
+          f = search->nf;
+
+          do
+          {
+                        // --------------------------------
+                        //  look for  (*node)->mon  in   f
+                        // --------------------------------
+
+            cmp = pCmp( (*node)->mon,f );
+
+            if( cmp<0 )
+            {
+              f = pNext( f );
+            }
+            else if( cmp==0 )
+            {
+              search->nf = pSub( search->nf,
+                                 ppMult_nn( (*node)->nf,pGetCoeff( f ) ) );
+              pNorm( search->nf );
+            }
+          }
+          while( cmp<0 && f!=(poly)NULL );
+        }
+        search = search->next;
+      }
+      speclist.delete_node( node );
+    }
+
+  }
+
+    // --------------------------------------------------------
+    //  fast computation exploits the symmetry of the spectrum
+    // --------------------------------------------------------
+
+  if( fast==2 )
+  {
+    mu = 2*mu - z;
+    n  = ( z > 0 ? 2*n - 1 : 2*n );
+  }
+
+    // --------------------------------------------------------
+    //  compute the spectrum numbers with their multiplicities
+    // --------------------------------------------------------
+
+  intvec            *nom  = new intvec( n );
+  intvec            *den  = new intvec( n );
+  intvec            *mult = new intvec( n );
+
+  int count         = 0;
+  int multiplicity  = 1;
+
+  for( search=speclist.root; search!=(spectrumPolyNode*)NULL &&
+              ( fast==0 || search->weight<=smax );
+       search=search->next )
+  {
+    if( search->next==(spectrumPolyNode*)NULL ||
+        search->weight<search->next->weight )
+    {
+      (*nom) [count] = search->weight.get_num_si( );
+      (*den) [count] = search->weight.get_den_si( );
+      (*mult)[count] = multiplicity;
+
+      multiplicity=1;
+      count++;
+    }
+    else
+    {
+      multiplicity++;
+    }
+  }
+
+    // --------------------------------------------------------
+    //  fast computation exploits the symmetry of the spectrum
+    // --------------------------------------------------------
+
+  if( fast==2 )
+  {
+    int n1,n2;
+    for( n1=0, n2=n-1; n1<n2; n1++, n2-- )
+    {
+      (*nom) [n2] = rVar(currRing)*(*den)[n1]-(*nom)[n1];
+      (*den) [n2] = (*den)[n1];
+      (*mult)[n2] = (*mult)[n1];
+    }
+  }
+
+    // -----------------------------------
+    //  test if the spectrum is symmetric
+    // -----------------------------------
+
+  if( fast==0 || fast==1 )
+  {
+    int symmetric=TRUE;
+
+    for( int n1=0, n2=n-1 ; n1<n2 && symmetric==TRUE; n1++, n2-- )
+    {
+      if( (*mult)[n1]!=(*mult)[n2] ||
+          (*den) [n1]!= (*den)[n2] ||
+          (*nom)[n1]+(*nom)[n2]!=rVar(currRing)*(*den) [n1] )
+      {
+        symmetric = FALSE;
+      }
+    }
+
+    if( symmetric==FALSE )
+    {
+            // ---------------------------------------------
+            //  the spectrum is not symmetric => degenerate
+            //  principal part
+            // ---------------------------------------------
+
+      *L = (lists)omAllocBin( slists_bin);
+      (*L)->Init( 1 );
+      (*L)->m[0].rtyp = INT_CMD;    //  milnor number
+      (*L)->m[0].data = (void*)(long)mu;
+
+      return spectrumDegenerate;
+    }
+  }
+
+  *L = (lists)omAllocBin( slists_bin);
+
+  (*L)->Init( 6 );
+
+  (*L)->m[0].rtyp = INT_CMD;    //  milnor number
+  (*L)->m[1].rtyp = INT_CMD;    //  geometrical genus
+  (*L)->m[2].rtyp = INT_CMD;    //  number of spectrum values
+  (*L)->m[3].rtyp = INTVEC_CMD; //  nominators
+  (*L)->m[4].rtyp = INTVEC_CMD; //  denomiantors
+  (*L)->m[5].rtyp = INTVEC_CMD; //  multiplicities
+
+  (*L)->m[0].data = (void*)(long)mu;
+  (*L)->m[1].data = (void*)(long)pg;
+  (*L)->m[2].data = (void*)(long)n;
+  (*L)->m[3].data = (void*)nom;
+  (*L)->m[4].data = (void*)den;
+  (*L)->m[5].data = (void*)mult;
+
+  return  spectrumOK;
+}
+
+spectrumState   spectrumCompute( poly h,lists *L,int fast )
+{
+  int i;
+
+  #ifdef SPECTRUM_DEBUG
+  #ifdef SPECTRUM_PRINT
+  #ifdef SPECTRUM_IOSTREAM
+    cout << "spectrumCompute\n";
+    if( fast==0 ) cout << "    no optimization" << endl;
+    if( fast==1 ) cout << "    weight optimization" << endl;
+    if( fast==2 ) cout << "    symmetry optimization" << endl;
+  #else
+    fprintf( stdout,"spectrumCompute\n" );
+    if( fast==0 ) fprintf( stdout,"    no optimization\n" );
+    if( fast==1 ) fprintf( stdout,"    weight optimization\n" );
+    if( fast==2 ) fprintf( stdout,"    symmetry optimization\n" );
+  #endif
+  #endif
+  #endif
+
+  // ----------------------
+  //  check if  h  is zero
+  // ----------------------
+
+  if( h==(poly)NULL )
+  {
+    return  spectrumZero;
+  }
+
+  // ----------------------------------
+  //  check if  h  has a constant term
+  // ----------------------------------
+
+  if( hasConstTerm( h, currRing ) )
+  {
+    return  spectrumBadPoly;
+  }
+
+  // --------------------------------
+  //  check if  h  has a linear term
+  // --------------------------------
+
+  if( hasLinearTerm( h, currRing ) )
+  {
+    *L = (lists)omAllocBin( slists_bin);
+    (*L)->Init( 1 );
+    (*L)->m[0].rtyp = INT_CMD;    //  milnor number
+    /* (*L)->m[0].data = (void*)0;a  -- done by Init */
+
+    return  spectrumNoSingularity;
+  }
+
+  // ----------------------------------
+  //  compute the jacobi ideal of  (h)
+  // ----------------------------------
+
+  ideal J = NULL;
+  J = idInit( rVar(currRing),1 );
+
+  #ifdef SPECTRUM_DEBUG
+  #ifdef SPECTRUM_PRINT
+  #ifdef SPECTRUM_IOSTREAM
+    cout << "\n   computing the Jacobi ideal...\n";
+  #else
+    fprintf( stdout,"\n   computing the Jacobi ideal...\n" );
+  #endif
+  #endif
+  #endif
+
+  for( i=0; i<rVar(currRing); i++ )
+  {
+    J->m[i] = pDiff( h,i+1); //j );
+
+    #ifdef SPECTRUM_DEBUG
+    #ifdef SPECTRUM_PRINT
+    #ifdef SPECTRUM_IOSTREAM
+      cout << "        ";
+    #else
+      fprintf( stdout,"        " );
+    #endif
+      pWrite( J->m[i] );
+    #endif
+    #endif
+  }
+
+  // --------------------------------------------
+  //  compute a standard basis  stdJ  of  jac(h)
+  // --------------------------------------------
+
+  #ifdef SPECTRUM_DEBUG
+  #ifdef SPECTRUM_PRINT
+  #ifdef SPECTRUM_IOSTREAM
+    cout << endl;
+    cout << "    computing a standard basis..." << endl;
+  #else
+    fprintf( stdout,"\n" );
+    fprintf( stdout,"    computing a standard basis...\n" );
+  #endif
+  #endif
+  #endif
+
+  ideal stdJ = kStd(J,currRing->qideal,isNotHomog,NULL);
+  idSkipZeroes( stdJ );
+
+  #ifdef SPECTRUM_DEBUG
+  #ifdef SPECTRUM_PRINT
+    for( i=0; i<IDELEMS(stdJ); i++ )
+    {
+      #ifdef SPECTRUM_IOSTREAM
+        cout << "        ";
+      #else
+        fprintf( stdout,"        " );
+      #endif
+
+      pWrite( stdJ->m[i] );
+    }
+  #endif
+  #endif
+
+  idDelete( &J );
+
+  // ------------------------------------------
+  //  check if the  h  has a singularity
+  // ------------------------------------------
+
+  if( hasOne( stdJ, currRing ) )
+  {
+    // -------------------------------
+    //  h is smooth in the origin
+    //  return only the Milnor number
+    // -------------------------------
+
+    *L = (lists)omAllocBin( slists_bin);
+    (*L)->Init( 1 );
+    (*L)->m[0].rtyp = INT_CMD;    //  milnor number
+    /* (*L)->m[0].data = (void*)0;a  -- done by Init */
+
+    return  spectrumNoSingularity;
+  }
+
+  // ------------------------------------------
+  //  check if the singularity  h  is isolated
+  // ------------------------------------------
+
+  for( i=rVar(currRing); i>0; i-- )
+  {
+    if( hasAxis( stdJ,i, currRing )==FALSE )
+    {
+      return  spectrumNotIsolated;
+    }
+  }
+
+  // ------------------------------------------
+  //  compute the highest corner  hc  of  stdJ
+  // ------------------------------------------
+
+  #ifdef SPECTRUM_DEBUG
+  #ifdef SPECTRUM_PRINT
+  #ifdef SPECTRUM_IOSTREAM
+    cout << "\n    computing the highest corner...\n";
+  #else
+    fprintf( stdout,"\n    computing the highest corner...\n" );
+  #endif
+  #endif
+  #endif
+
+  poly hc = (poly)NULL;
+
+  scComputeHC( stdJ,currRing->qideal, 0,hc );
+
+  if( hc!=(poly)NULL )
+  {
+    pGetCoeff(hc) = nInit(1);
+
+    for( i=rVar(currRing); i>0; i-- )
+    {
+      if( pGetExp( hc,i )>0 ) pDecrExp( hc,i );
+    }
+    pSetm( hc );
+  }
+  else
+  {
+    return  spectrumNoHC;
+  }
+
+  #ifdef SPECTRUM_DEBUG
+  #ifdef SPECTRUM_PRINT
+  #ifdef SPECTRUM_IOSTREAM
+    cout << "       ";
+  #else
+    fprintf( stdout,"       " );
+  #endif
+    pWrite( hc );
+  #endif
+  #endif
+
+  // ----------------------------------------
+  //  compute the Newton polygon  nph  of  h
+  // ----------------------------------------
+
+  #ifdef SPECTRUM_DEBUG
+  #ifdef SPECTRUM_PRINT
+  #ifdef SPECTRUM_IOSTREAM
+    cout << "\n    computing the newton polygon...\n";
+  #else
+    fprintf( stdout,"\n    computing the newton polygon...\n" );
+  #endif
+  #endif
+  #endif
+
+  newtonPolygon nph( h, currRing );
+
+  #ifdef SPECTRUM_DEBUG
+  #ifdef SPECTRUM_PRINT
+    cout << nph;
+  #endif
+  #endif
+
+  // -----------------------------------------------
+  //  compute the weight corner  wc  of  (stdj,nph)
+  // -----------------------------------------------
+
+  #ifdef SPECTRUM_DEBUG
+  #ifdef SPECTRUM_PRINT
+  #ifdef SPECTRUM_IOSTREAM
+    cout << "\n    computing the weight corner...\n";
+  #else
+    fprintf( stdout,"\n    computing the weight corner...\n" );
+  #endif
+  #endif
+  #endif
+
+  poly    wc = ( fast==0 ? pCopy( hc ) :
+               ( fast==1 ? computeWC( nph,(Rational)rVar(currRing), currRing ) :
+              /* fast==2 */computeWC( nph,
+                      ((Rational)rVar(currRing))/(Rational)2, currRing ) ) );
+
+  #ifdef SPECTRUM_DEBUG
+  #ifdef SPECTRUM_PRINT
+  #ifdef SPECTRUM_IOSTREAM
+    cout << "        ";
+  #else
+    fprintf( stdout,"        " );
+  #endif
+    pWrite( wc );
+  #endif
+  #endif
+
+  // -------------
+  //  compute  NF
+  // -------------
+
+  #ifdef SPECTRUM_DEBUG
+  #ifdef SPECTRUM_PRINT
+  #ifdef SPECTRUM_IOSTREAM
+    cout << "\n    computing NF...\n" << endl;
+  #else
+    fprintf( stdout,"\n    computing NF...\n" );
+  #endif
+  #endif
+  #endif
+
+  spectrumPolyList NF( &nph );
+
+  computeNF( stdJ,hc,wc,&NF, currRing );
+
+  #ifdef SPECTRUM_DEBUG
+  #ifdef SPECTRUM_PRINT
+    cout << NF;
+  #ifdef SPECTRUM_IOSTREAM
+    cout << endl;
+  #else
+    fprintf( stdout,"\n" );
+  #endif
+  #endif
+  #endif
+
+  // ----------------------------
+  //  compute the spectrum of  h
+  // ----------------------------
+//  spectrumState spectrumStateFromList( spectrumPolyList& speclist, lists *L, int fast );
+
+  return spectrumStateFromList(NF, L, fast );
+}
+
+// ----------------------------------------------------------------------------
+//  this procedure is called from the interpreter
+// ----------------------------------------------------------------------------
+//  first  = polynomial
+//  result = list of spectrum numbers
+// ----------------------------------------------------------------------------
+
+void spectrumPrintError(spectrumState state)
+{
+  switch( state )
+  {
+    case spectrumZero:
+      WerrorS( "polynomial is zero" );
+      break;
+    case spectrumBadPoly:
+      WerrorS( "polynomial has constant term" );
+      break;
+    case spectrumNoSingularity:
+      WerrorS( "not a singularity" );
+      break;
+    case spectrumNotIsolated:
+      WerrorS( "the singularity is not isolated" );
+      break;
+    case spectrumNoHC:
+      WerrorS( "highest corner cannot be computed" );
+      break;
+    case spectrumDegenerate:
+      WerrorS( "principal part is degenerate" );
+      break;
+    case spectrumOK:
+      break;
+
+    default:
+      WerrorS( "unknown error occurred" );
+      break;
+  }
+}
+
+BOOLEAN spectrumProc( leftv result,leftv first )
+{
+  spectrumState state = spectrumOK;
+
+  // -------------------
+  //  check consistency
+  // -------------------
+
+  //  check for a local ring
+
+  if( !ringIsLocal(currRing ) )
+  {
+    WerrorS( "only works for local orderings" );
+    state = spectrumWrongRing;
+  }
+
+  //  no quotient rings are allowed
+
+  else if( currRing->qideal != NULL )
+  {
+    WerrorS( "does not work in quotient rings" );
+    state = spectrumWrongRing;
+  }
+  else
+  {
+    lists   L    = (lists)NULL;
+    int     flag = 1; // weight corner optimization is safe
+
+    state = spectrumCompute( (poly)first->Data( ),&L,flag );
+
+    if( state==spectrumOK )
+    {
+      result->rtyp = LIST_CMD;
+      result->data = (char*)L;
+    }
+    else
+    {
+      spectrumPrintError(state);
+    }
+  }
+
+  return  (state!=spectrumOK);
+}
+
+// ----------------------------------------------------------------------------
+//  this procedure is called from the interpreter
+// ----------------------------------------------------------------------------
+//  first  = polynomial
+//  result = list of spectrum numbers
+// ----------------------------------------------------------------------------
+
+BOOLEAN spectrumfProc( leftv result,leftv first )
+{
+  spectrumState state = spectrumOK;
+
+  // -------------------
+  //  check consistency
+  // -------------------
+
+  //  check for a local polynomial ring
+
+  if( currRing->OrdSgn != -1 )
+  // ?? HS: the test above is also true for k[x][[y]], k[[x]][y]
+  // or should we use:
+  //if( !ringIsLocal( ) )
+  {
+    WerrorS( "only works for local orderings" );
+    state = spectrumWrongRing;
+  }
+  else if( currRing->qideal != NULL )
+  {
+    WerrorS( "does not work in quotient rings" );
+    state = spectrumWrongRing;
+  }
+  else
+  {
+    lists   L    = (lists)NULL;
+    int     flag = 2; // symmetric optimization
+
+    state = spectrumCompute( (poly)first->Data( ),&L,flag );
+
+    if( state==spectrumOK )
+    {
+      result->rtyp = LIST_CMD;
+      result->data = (char*)L;
+    }
+    else
+    {
+      spectrumPrintError(state);
+    }
+  }
+
+  return  (state!=spectrumOK);
+}
+
+// ----------------------------------------------------------------------------
+//  check if a list is a spectrum
+//  check for:
+//      list has 6 elements
+//      1st element is int (mu=Milnor number)
+//      2nd element is int (pg=geometrical genus)
+//      3rd element is int (n =number of different spectrum numbers)
+//      4th element is intvec (num=numerators)
+//      5th element is intvec (den=denomiantors)
+//      6th element is intvec (mul=multiplicities)
+//      exactly n numerators
+//      exactly n denominators
+//      exactly n multiplicities
+//      mu>0
+//      pg>=0
+//      n>0
+//      num>0
+//      den>0
+//      mul>0
+//      symmetriy with respect to numberofvariables/2
+//      monotony
+//      mu = sum of all multiplicities
+//      pg = sum of all multiplicities where num/den<=1
+// ----------------------------------------------------------------------------
+
+semicState  list_is_spectrum( lists l )
+{
+    // -------------------
+    //  check list length
+    // -------------------
+
+    if( l->nr < 5 )
+    {
+        return  semicListTooShort;
+    }
+    else if( l->nr > 5 )
+    {
+        return  semicListTooLong;
+    }
+
+    // -------------
+    //  check types
+    // -------------
+
+    if( l->m[0].rtyp != INT_CMD )
+    {
+        return  semicListFirstElementWrongType;
+    }
+    else if( l->m[1].rtyp != INT_CMD )
+    {
+        return  semicListSecondElementWrongType;
+    }
+    else if( l->m[2].rtyp != INT_CMD )
+    {
+        return  semicListThirdElementWrongType;
+    }
+    else if( l->m[3].rtyp != INTVEC_CMD )
+    {
+        return  semicListFourthElementWrongType;
+    }
+    else if( l->m[4].rtyp != INTVEC_CMD )
+    {
+        return  semicListFifthElementWrongType;
+    }
+    else if( l->m[5].rtyp != INTVEC_CMD )
+    {
+        return  semicListSixthElementWrongType;
+    }
+
+    // -------------------------
+    //  check number of entries
+    // -------------------------
+
+    int     mu = (int)(long)(l->m[0].Data( ));
+    int     pg = (int)(long)(l->m[1].Data( ));
+    int     n  = (int)(long)(l->m[2].Data( ));
+
+    if( n <= 0 )
+    {
+        return  semicListNNegative;
+    }
+
+    intvec  *num = (intvec*)l->m[3].Data( );
+    intvec  *den = (intvec*)l->m[4].Data( );
+    intvec  *mul = (intvec*)l->m[5].Data( );
+
+    if( n != num->length( ) )
+    {
+        return  semicListWrongNumberOfNumerators;
+    }
+    else if( n != den->length( ) )
+    {
+        return  semicListWrongNumberOfDenominators;
+    }
+    else if( n != mul->length( ) )
+    {
+        return  semicListWrongNumberOfMultiplicities;
+    }
+
+    // --------
+    //  values
+    // --------
+
+    if( mu <= 0 )
+    {
+        return  semicListMuNegative;
+    }
+    if( pg < 0 )
+    {
+        return  semicListPgNegative;
+    }
+
+    int i;
+
+    for( i=0; i<n; i++ )
+    {
+        if( (*num)[i] <= 0 )
+        {
+            return  semicListNumNegative;
+        }
+        if( (*den)[i] <= 0 )
+        {
+            return  semicListDenNegative;
+        }
+        if( (*mul)[i] <= 0 )
+        {
+            return  semicListMulNegative;
+        }
+    }
+
+    // ----------------
+    //  check symmetry
+    // ----------------
+
+    int     j;
+
+    for( i=0, j=n-1; i<=j; i++,j-- )
+    {
+        if( (*num)[i] != rVar(currRing)*((*den)[i]) - (*num)[j] ||
+            (*den)[i] != (*den)[j] ||
+            (*mul)[i] != (*mul)[j] )
+        {
+            return  semicListNotSymmetric;
+        }
+    }
+
+    // ----------------
+    //  check monotony
+    // ----------------
+
+    for( i=0, j=1; i<n/2; i++,j++ )
+    {
+        if( (*num)[i]*(*den)[j] >= (*num)[j]*(*den)[i] )
+        {
+            return  semicListNotMonotonous;
+        }
+    }
+
+    // ---------------------
+    //  check Milnor number
+    // ---------------------
+
+    for( mu=0, i=0; i<n; i++ )
+    {
+        mu += (*mul)[i];
+    }
+
+    if( mu != (int)(long)(l->m[0].Data( )) )
+    {
+        return  semicListMilnorWrong;
+    }
+
+    // -------------------------
+    //  check geometrical genus
+    // -------------------------
+
+    for( pg=0, i=0; i<n; i++ )
+    {
+        if( (*num)[i]<=(*den)[i] )
+        {
+            pg += (*mul)[i];
+        }
+    }
+
+    if( pg != (int)(long)(l->m[1].Data( )) )
+    {
+        return  semicListPGWrong;
+    }
+
+    return  semicOK;
+}
+
+// ----------------------------------------------------------------------------
+//  this procedure is called from the interpreter
+// ----------------------------------------------------------------------------
+//  first  = list of spectrum numbers
+//  second = list of spectrum numbers
+//  result = sum of the two lists
+// ----------------------------------------------------------------------------
+
+BOOLEAN spaddProc( leftv result,leftv first,leftv second )
+{
+    semicState  state;
+
+    // -----------------
+    //  check arguments
+    // -----------------
+
+    lists l1 = (lists)first->Data( );
+    lists l2 = (lists)second->Data( );
+
+    if( (state=list_is_spectrum( l1 )) != semicOK )
+    {
+        WerrorS( "first argument is not a spectrum:" );
+        list_error( state );
+    }
+    else if( (state=list_is_spectrum( l2 )) != semicOK )
+    {
+        WerrorS( "second argument is not a spectrum:" );
+        list_error( state );
+    }
+    else
+    {
+        spectrum s1= spectrumFromList ( l1 );
+        spectrum s2= spectrumFromList ( l2 );
+        spectrum sum( s1+s2 );
+
+        result->rtyp = LIST_CMD;
+        result->data = (char*)(getList(sum));
+    }
+
+    return  (state!=semicOK);
+}
+
+// ----------------------------------------------------------------------------
+//  this procedure is called from the interpreter
+// ----------------------------------------------------------------------------
+//  first  = list of spectrum numbers
+//  second = integer
+//  result = the multiple of the first list by the second factor
+// ----------------------------------------------------------------------------
+
+BOOLEAN spmulProc( leftv result,leftv first,leftv second )
+{
+    semicState  state;
+
+    // -----------------
+    //  check arguments
+    // -----------------
+
+    lists   l = (lists)first->Data( );
+    int     k = (int)(long)second->Data( );
+
+    if( (state=list_is_spectrum( l ))!=semicOK )
+    {
+        WerrorS( "first argument is not a spectrum" );
+        list_error( state );
+    }
+    else if( k < 0 )
+    {
+        WerrorS( "second argument should be positive" );
+        state = semicMulNegative;
+    }
+    else
+    {
+        spectrum s= spectrumFromList( l );
+        spectrum product( k*s );
+
+        result->rtyp = LIST_CMD;
+        result->data = (char*)getList(product);
+    }
+
+    return  (state!=semicOK);
+}
+
+// ----------------------------------------------------------------------------
+//  this procedure is called from the interpreter
+// ----------------------------------------------------------------------------
+//  first  = list of spectrum numbers
+//  second = list of spectrum numbers
+//  result = semicontinuity index
+// ----------------------------------------------------------------------------
+
+BOOLEAN    semicProc3   ( leftv res,leftv u,leftv v,leftv w )
+{
+  semicState  state;
+  BOOLEAN qh=(((int)(long)w->Data())==1);
+
+  // -----------------
+  //  check arguments
+  // -----------------
+
+  lists l1 = (lists)u->Data( );
+  lists l2 = (lists)v->Data( );
+
+  if( (state=list_is_spectrum( l1 ))!=semicOK )
+  {
+    WerrorS( "first argument is not a spectrum" );
+    list_error( state );
+  }
+  else if( (state=list_is_spectrum( l2 ))!=semicOK )
+  {
+    WerrorS( "second argument is not a spectrum" );
+    list_error( state );
+  }
+  else
+  {
+    spectrum s1= spectrumFromList( l1 );
+    spectrum s2= spectrumFromList( l2 );
+
+    res->rtyp = INT_CMD;
+    if (qh)
+      res->data = (void*)(long)(s1.mult_spectrumh( s2 ));
+    else
+      res->data = (void*)(long)(s1.mult_spectrum( s2 ));
+  }
+
+  // -----------------
+  //  check status
+  // -----------------
+
+  return  (state!=semicOK);
+}
+BOOLEAN    semicProc   ( leftv res,leftv u,leftv v )
+{
+  sleftv tmp;
+  memset(&tmp,0,sizeof(tmp));
+  tmp.rtyp=INT_CMD;
+  /* tmp.data = (void *)0;  -- done by memset */
+
+  return  semicProc3(res,u,v,&tmp);
+}
+
+#endif
+
+BOOLEAN loNewtonP( leftv res, leftv arg1 )
+{
+  res->data= (void*)loNewtonPolytope( (ideal)arg1->Data() );
+  return FALSE;
+}
+
+BOOLEAN loSimplex( leftv res, leftv args )
+{
+  if ( !(rField_is_long_R(currRing)) )
+  {
+    WerrorS("Ground field not implemented!");
+    return TRUE;
+  }
+
+  simplex * LP;
+  matrix m;
+
+  leftv v= args;
+  if ( v->Typ() != MATRIX_CMD ) // 1: matrix
+    return TRUE;
+  else
+    m= (matrix)(v->CopyD());
+
+  LP = new simplex(MATROWS(m),MATCOLS(m));
+  LP->mapFromMatrix(m);
+
+  v= v->next;
+  if ( v->Typ() != INT_CMD )    // 2: m = number of constraints
+    return TRUE;
+  else
+    LP->m= (int)(long)(v->Data());
+
+  v= v->next;
+  if ( v->Typ() != INT_CMD )    // 3: n = number of variables
+    return TRUE;
+  else
+    LP->n= (int)(long)(v->Data());
+
+  v= v->next;
+  if ( v->Typ() != INT_CMD )    // 4: m1 = number of <= constraints
+    return TRUE;
+  else
+    LP->m1= (int)(long)(v->Data());
+
+  v= v->next;
+  if ( v->Typ() != INT_CMD )    // 5: m2 = number of >= constraints
+    return TRUE;
+  else
+    LP->m2= (int)(long)(v->Data());
+
+  v= v->next;
+  if ( v->Typ() != INT_CMD )    // 6: m3 = number of == constraints
+    return TRUE;
+  else
+    LP->m3= (int)(long)(v->Data());
+
+#ifdef mprDEBUG_PROT
+  Print("m (constraints) %d\n",LP->m);
+  Print("n (columns) %d\n",LP->n);
+  Print("m1 (<=) %d\n",LP->m1);
+  Print("m2 (>=) %d\n",LP->m2);
+  Print("m3 (==) %d\n",LP->m3);
+#endif
+
+  LP->compute();
+
+  lists lres= (lists)omAlloc( sizeof(slists) );
+  lres->Init( 6 );
+
+  lres->m[0].rtyp= MATRIX_CMD; // output matrix
+  lres->m[0].data=(void*)LP->mapToMatrix(m);
+
+  lres->m[1].rtyp= INT_CMD;   // found a solution?
+  lres->m[1].data=(void*)(long)LP->icase;
+
+  lres->m[2].rtyp= INTVEC_CMD;
+  lres->m[2].data=(void*)LP->posvToIV();
+
+  lres->m[3].rtyp= INTVEC_CMD;
+  lres->m[3].data=(void*)LP->zrovToIV();
+
+  lres->m[4].rtyp= INT_CMD;
+  lres->m[4].data=(void*)(long)LP->m;
+
+  lres->m[5].rtyp= INT_CMD;
+  lres->m[5].data=(void*)(long)LP->n;
+
+  res->data= (void*)lres;
+
+  return FALSE;
+}
+
+BOOLEAN nuMPResMat( leftv res, leftv arg1, leftv arg2 )
+{
+  ideal gls = (ideal)(arg1->Data());
+  int imtype= (int)(long)arg2->Data();
+
+  uResultant::resMatType mtype= determineMType( imtype );
+
+  // check input ideal ( = polynomial system )
+  if ( mprIdealCheck( gls, arg1->Name(), mtype, true ) != mprOk )
+  {
+    return TRUE;
+  }
+
+  uResultant *resMat= new uResultant( gls, mtype, false );
+  if (resMat!=NULL)
+  {
+    res->rtyp = MODUL_CMD;
+    res->data= (void*)resMat->accessResMat()->getMatrix();
+    if (!errorreported) delete resMat;
+  }
+  return errorreported;
+}
+
+BOOLEAN nuLagSolve( leftv res, leftv arg1, leftv arg2, leftv arg3 )
+{
+
+  poly gls;
+  gls= (poly)(arg1->Data());
+  int howclean= (int)(long)arg3->Data();
+
+  if ( !(rField_is_R(currRing) ||
+         rField_is_Q(currRing) ||
+         rField_is_long_R(currRing) ||
+         rField_is_long_C(currRing)) )
+  {
+    WerrorS("Ground field not implemented!");
+    return TRUE;
+  }
+
+  if ( !(rField_is_R(currRing) || rField_is_long_R(currRing) || \
+                          rField_is_long_C(currRing)) )
+  {
+    unsigned long int ii = (unsigned long int)arg2->Data();
+    setGMPFloatDigits( ii, ii );
+  }
+
+  if ( gls == NULL || pIsConstant( gls ) )
+  {
+    WerrorS("Input polynomial is constant!");
+    return TRUE;
+  }
+
+  int ldummy;
+  int deg= currRing->pLDeg( gls, &ldummy, currRing );
+  //  int deg= pDeg( gls );
+  //  int len= pLength( gls );
+  int i,vpos=0;
+  poly piter;
+  lists elist;
+  lists rlist;
+
+  elist= (lists)omAlloc( sizeof(slists) );
+  elist->Init( 0 );
+
+  if ( rVar(currRing) > 1 )
+  {
+    piter= gls;
+    for ( i= 1; i <= rVar(currRing); i++ )
+      if ( pGetExp( piter, i ) )
+      {
+        vpos= i;
+        break;
+      }
+    while ( piter )
+    {
+      for ( i= 1; i <= rVar(currRing); i++ )
+        if ( (vpos != i) && (pGetExp( piter, i ) != 0) )
+        {
+          WerrorS("The input polynomial must be univariate!");
+          return TRUE;
+        }
+      pIter( piter );
+    }
+  }
+
+  rootContainer * roots= new rootContainer();
+  number * pcoeffs= (number *)omAlloc( (deg+1) * sizeof( number ) );
+  piter= gls;
+  for ( i= deg; i >= 0; i-- )
+  {
+    //if ( piter ) Print("deg %d, pDeg(piter) %d\n",i,pTotaldegree(piter));
+    if ( piter && pTotaldegree(piter) == i )
+    {
+      pcoeffs[i]= nCopy( pGetCoeff( piter ) );
+      //nPrint( pcoeffs[i] );PrintS("  ");
+      pIter( piter );
+    }
+    else
+    {
+      pcoeffs[i]= nInit(0);
+    }
+  }
+
+#ifdef mprDEBUG_PROT
+  for (i=deg; i >= 0; i--)
+  {
+    nPrint( pcoeffs[i] );PrintS("  ");
+  }
+  PrintLn();
+#endif
+
+  roots->fillContainer( pcoeffs, NULL, 1, deg, rootContainer::onepoly, 1 );
+  roots->solver( howclean );
+
+  int elem= roots->getAnzRoots();
+  char *dummy;
+  int j;
+
+  rlist= (lists)omAlloc( sizeof(slists) );
+  rlist->Init( elem );
+
+  if (rField_is_long_C(currRing))
+  {
+    for ( j= 0; j < elem; j++ )
+    {
+      rlist->m[j].rtyp=NUMBER_CMD;
+      rlist->m[j].data=(void *)nCopy((number)(roots->getRoot(j)));
+      //rlist->m[j].data=(void *)(number)(roots->getRoot(j));
+    }
+  }
+  else
+  {
+    for ( j= 0; j < elem; j++ )
+    {
+      dummy = complexToStr( (*roots)[j], gmp_output_digits, currRing->cf );
+      rlist->m[j].rtyp=STRING_CMD;
+      rlist->m[j].data=(void *)dummy;
+    }
+  }
+
+  elist->Clean();
+  //omFreeSize( (ADDRESS) elist, sizeof(slists) );
+
+  // this is (via fillContainer) the same data as in root
+  //for ( i= deg; i >= 0; i-- ) nDelete( &pcoeffs[i] );
+  //omFreeSize( (ADDRESS) pcoeffs, (deg+1) * sizeof( number ) );
+
+  delete roots;
+
+  res->rtyp= LIST_CMD;
+  res->data= (void*)rlist;
+
+  return FALSE;
+}
+
+BOOLEAN nuVanderSys( leftv res, leftv arg1, leftv arg2, leftv arg3)
+{
+  int i;
+  ideal p,w;
+  p= (ideal)arg1->Data();
+  w= (ideal)arg2->Data();
+
+  // w[0] = f(p^0)
+  // w[1] = f(p^1)
+  // ...
+  // p can be a vector of numbers (multivariate polynom)
+  //   or one number (univariate polynom)
+  // tdg = deg(f)
+
+  int n= IDELEMS( p );
+  int m= IDELEMS( w );
+  int tdg= (int)(long)arg3->Data();
+
+  res->data= (void*)NULL;
+
+  // check the input
+  if ( tdg < 1 )
+  {
+    WerrorS("Last input parameter must be > 0!");
+    return TRUE;
+  }
+  if ( n != rVar(currRing) )
+  {
+    Werror("Size of first input ideal must be equal to %d!",rVar(currRing));
+    return TRUE;
+  }
+  if ( m != (int)pow((double)tdg+1,(double)n) )
+  {
+    Werror("Size of second input ideal must be equal to %d!",
+      (int)pow((double)tdg+1,(double)n));
+    return TRUE;
+  }
+  if ( !(rField_is_Q(currRing) /* ||
+         rField_is_R() || rField_is_long_R() ||
+         rField_is_long_C()*/ ) )
+         {
+    WerrorS("Ground field not implemented!");
+    return TRUE;
+  }
+
+  number tmp;
+  number *pevpoint= (number *)omAlloc( n * sizeof( number ) );
+  for ( i= 0; i < n; i++ )
+  {
+    pevpoint[i]=nInit(0);
+    if (  (p->m)[i] )
+    {
+      tmp = pGetCoeff( (p->m)[i] );
+      if ( nIsZero(tmp) || nIsOne(tmp) || nIsMOne(tmp) )
+      {
+        omFreeSize( (ADDRESS)pevpoint, n * sizeof( number ) );
+        WerrorS("Elements of first input ideal must not be equal to -1, 0, 1!");
+        return TRUE;
+      }
+    } else tmp= NULL;
+    if ( !nIsZero(tmp) )
+    {
+      if ( !pIsConstant((p->m)[i]))
+      {
+        omFreeSize( (ADDRESS)pevpoint, n * sizeof( number ) );
+        WerrorS("Elements of first input ideal must be numbers!");
+        return TRUE;
+      }
+      pevpoint[i]= nCopy( tmp );
+    }
+  }
+
+  number *wresults= (number *)omAlloc( m * sizeof( number ) );
+  for ( i= 0; i < m; i++ )
+  {
+    wresults[i]= nInit(0);
+    if ( (w->m)[i] && !nIsZero(pGetCoeff((w->m)[i])) )
+    {
+      if ( !pIsConstant((w->m)[i]))
+      {
+        omFreeSize( (ADDRESS)pevpoint, n * sizeof( number ) );
+        omFreeSize( (ADDRESS)wresults, m * sizeof( number ) );
+        WerrorS("Elements of second input ideal must be numbers!");
+        return TRUE;
+      }
+      wresults[i]= nCopy(pGetCoeff((w->m)[i]));
+    }
+  }
+
+  vandermonde vm( m, n, tdg, pevpoint, FALSE );
+  number *ncpoly= vm.interpolateDense( wresults );
+  // do not free ncpoly[]!!
+  poly rpoly= vm.numvec2poly( ncpoly );
+
+  omFreeSize( (ADDRESS)pevpoint, n * sizeof( number ) );
+  omFreeSize( (ADDRESS)wresults, m * sizeof( number ) );
+
+  res->data= (void*)rpoly;
+  return FALSE;
+}
+
+BOOLEAN nuUResSolve( leftv res, leftv args )
+{
+  leftv v= args;
+
+  ideal gls;
+  int imtype;
+  int howclean;
+
+  // get ideal
+  if ( v->Typ() != IDEAL_CMD )
+    return TRUE;
+  else gls= (ideal)(v->Data());
+  v= v->next;
+
+  // get resultant matrix type to use (0,1)
+  if ( v->Typ() != INT_CMD )
+    return TRUE;
+  else imtype= (int)(long)v->Data();
+  v= v->next;
+
+  if (imtype==0)
+  {
+    ideal test_id=idInit(1,1);
+    int j;
+    for(j=IDELEMS(gls)-1;j>=0;j--)
+    {
+      if (gls->m[j]!=NULL)
+      {
+        test_id->m[0]=gls->m[j];
+        intvec *dummy_w=id_QHomWeight(test_id, currRing);
+        if (dummy_w!=NULL)
+        {
+          WerrorS("Newton polytope not of expected dimension");
+          delete dummy_w;
+          return TRUE;
+        }
+      }
+    }
+  }
+
+  // get and set precision in digits ( > 0 )
+  if ( v->Typ() != INT_CMD )
+    return TRUE;
+  else if ( !(rField_is_R(currRing) || rField_is_long_R(currRing) || \
+                          rField_is_long_C(currRing)) )
+  {
+    unsigned long int ii=(unsigned long int)v->Data();
+    setGMPFloatDigits( ii, ii );
+  }
+  v= v->next;
+
+  // get interpolation steps (0,1,2)
+  if ( v->Typ() != INT_CMD )
+    return TRUE;
+  else howclean= (int)(long)v->Data();
+
+  uResultant::resMatType mtype= determineMType( imtype );
+  int i,count;
+  lists listofroots= NULL;
+  number smv= NULL;
+  BOOLEAN interpolate_det= (mtype==uResultant::denseResMat)?TRUE:FALSE;
+
+  //emptylist= (lists)omAlloc( sizeof(slists) );
+  //emptylist->Init( 0 );
+
+  //res->rtyp = LIST_CMD;
+  //res->data= (void *)emptylist;
+
+  // check input ideal ( = polynomial system )
+  if ( mprIdealCheck( gls, args->Name(), mtype ) != mprOk )
+  {
+    return TRUE;
+  }
+
+  uResultant * ures;
+  rootContainer ** iproots;
+  rootContainer ** muiproots;
+  rootArranger * arranger;
+
+  // main task 1: setup of resultant matrix
+  ures= new uResultant( gls, mtype );
+  if ( ures->accessResMat()->initState() != resMatrixBase::ready )
+  {
+    WerrorS("Error occurred during matrix setup!");
+    return TRUE;
+  }
+
+  // if dense resultant, check if minor nonsingular
+  if ( mtype == uResultant::denseResMat )
+  {
+    smv= ures->accessResMat()->getSubDet();
+#ifdef mprDEBUG_PROT
+    PrintS("// Determinant of submatrix: ");nPrint(smv);PrintLn();
+#endif
+    if ( nIsZero(smv) )
+    {
+      WerrorS("Unsuitable input ideal: Minor of resultant matrix is singular!");
+      return TRUE;
+    }
+  }
+
+  // main task 2: Interpolate specialized resultant polynomials
+  if ( interpolate_det )
+    iproots= ures->interpolateDenseSP( false, smv );
+  else
+    iproots= ures->specializeInU( false, smv );
+
+  // main task 3: Interpolate specialized resultant polynomials
+  if ( interpolate_det )
+    muiproots= ures->interpolateDenseSP( true, smv );
+  else
+    muiproots= ures->specializeInU( true, smv );
+
+#ifdef mprDEBUG_PROT
+  int c= iproots[0]->getAnzElems();
+  for (i=0; i < c; i++) pWrite(iproots[i]->getPoly());
+  c= muiproots[0]->getAnzElems();
+  for (i=0; i < c; i++) pWrite(muiproots[i]->getPoly());
+#endif
+
+  // main task 4: Compute roots of specialized polys and match them up
+  arranger= new rootArranger( iproots, muiproots, howclean );
+  arranger->solve_all();
+
+  // get list of roots
+  if ( arranger->success() )
+  {
+    arranger->arrange();
+    listofroots= listOfRoots(arranger, gmp_output_digits );
+  }
+  else
+  {
+    WerrorS("Solver was unable to find any roots!");
+    return TRUE;
+  }
+
+  // free everything
+  count= iproots[0]->getAnzElems();
+  for (i=0; i < count; i++) delete iproots[i];
+  omFreeSize( (ADDRESS) iproots, count * sizeof(rootContainer*) );
+  count= muiproots[0]->getAnzElems();
+  for (i=0; i < count; i++) delete muiproots[i];
+  omFreeSize( (ADDRESS) muiproots, count * sizeof(rootContainer*) );
+
+  delete ures;
+  delete arranger;
+  nDelete( &smv );
+
+  res->data= (void *)listofroots;
+
+  //emptylist->Clean();
+  //  omFreeSize( (ADDRESS) emptylist, sizeof(slists) );
+
+  return FALSE;
+}
+
+// from mpr_numeric.cc
+lists listOfRoots( rootArranger* self, const unsigned int oprec )
+{
+  int i,j;
+  int count= self->roots[0]->getAnzRoots(); // number of roots
+  int elem= self->roots[0]->getAnzElems();  // number of koordinates per root
+
+  lists listofroots= (lists)omAlloc( sizeof(slists) ); // must be done this way!
+
+  if ( self->found_roots )
+  {
+    listofroots->Init( count );
+
+    for (i=0; i < count; i++)
+    {
+      lists onepoint= (lists)omAlloc(sizeof(slists)); // must be done this way!
+      onepoint->Init(elem);
+      for ( j= 0; j < elem; j++ )
+      {
+        if ( !rField_is_long_C(currRing) )
+        {
+          onepoint->m[j].rtyp=STRING_CMD;
+          onepoint->m[j].data=(void *)complexToStr((*self->roots[j])[i],oprec, currRing->cf);
+        }
+        else
+        {
+          onepoint->m[j].rtyp=NUMBER_CMD;
+          onepoint->m[j].data=(void *)n_Copy((number)(self->roots[j]->getRoot(i)), currRing->cf);
+        }
+        onepoint->m[j].next= NULL;
+        onepoint->m[j].name= NULL;
+      }
+      listofroots->m[i].rtyp=LIST_CMD;
+      listofroots->m[i].data=(void *)onepoint;
+      listofroots->m[j].next= NULL;
+      listofroots->m[j].name= NULL;
+    }
+
+  }
+  else
+  {
+    listofroots->Init( 0 );
+  }
+
+  return listofroots;
+}
+
+// from ring.cc
+void rSetHdl(idhdl h)
+{
+  ring rg = NULL;
+  if (h!=NULL)
+  {
+//   Print(" new ring:%s (l:%d)\n",IDID(h),IDLEV(h));
+    rg = IDRING(h);
+    if (rg==NULL) return; //id <>NULL, ring==NULL
+    omCheckAddrSize((ADDRESS)h,sizeof(idrec));
+    if (IDID(h))  // OB: ????
+      omCheckAddr((ADDRESS)IDID(h));
+    rTest(rg);
+  }
+
+  // clean up history
+  if (sLastPrinted.RingDependend())
+  {
+    sLastPrinted.CleanUp();
+    memset(&sLastPrinted,0,sizeof(sleftv));
+  }
+
+  // test for valid "currRing":
+  if ((rg!=NULL) && (rg->idroot==NULL))
+  {
+    ring old=rg;
+    rg=rAssure_HasComp(rg);
+    if (old!=rg)
+    {
+      rKill(old);
+      IDRING(h)=rg;
+    }
+  }
+   /*------------ change the global ring -----------------------*/
+  rChangeCurrRing(rg);
+  currRingHdl = h;
+}
+
+BOOLEAN rSleftvOrdering2Ordering(sleftv *ord, ring R)
+{
+  int last = 0, o=0, n = 1, i=0, typ = 1, j;
+  sleftv *sl = ord;
+
+  // determine nBlocks
+  while (sl!=NULL)
+  {
+    intvec *iv = (intvec *)(sl->data);
+    if (((*iv)[1]==ringorder_c)||((*iv)[1]==ringorder_C))
+      i++;
+    else if ((*iv)[1]==ringorder_L)
+    {
+      R->bitmask=(*iv)[2];
+      n--;
+    }
+    else if (((*iv)[1]!=ringorder_a)
+    && ((*iv)[1]!=ringorder_a64)
+    && ((*iv)[1]!=ringorder_am))
+      o++;
+    n++;
+    sl=sl->next;
+  }
+  // check whether at least one real ordering
+  if (o==0)
+  {
+    WerrorS("invalid combination of orderings");
+    return TRUE;
+  }
+  // if no c/C ordering is given, increment n
+  if (i==0) n++;
+  else if (i != 1)
+  {
+    // throw error if more than one is given
+    WerrorS("more than one ordering c/C specified");
+    return TRUE;
+  }
+
+  // initialize fields of R
+  R->order=(int *)omAlloc0(n*sizeof(int));
+  R->block0=(int *)omAlloc0(n*sizeof(int));
+  R->block1=(int *)omAlloc0(n*sizeof(int));
+  R->wvhdl=(int**)omAlloc0(n*sizeof(int_ptr));
+
+  int *weights=(int*)omAlloc0((R->N+1)*sizeof(int));
+
+  // init order, so that rBlocks works correctly
+  for (j=0; j < n-1; j++)
+    R->order[j] = (int) ringorder_unspec;
+  // set last _C order, if no c/C order was given
+  if (i == 0) R->order[n-2] = ringorder_C;
+
+  /* init orders */
+  sl=ord;
+  n=-1;
+  while (sl!=NULL)
+  {
+    intvec *iv;
+    iv = (intvec *)(sl->data);
+    if ((*iv)[1]!=ringorder_L)
+    {
+      n++;
+
+      /* the format of an ordering:
+       *  iv[0]: factor
+       *  iv[1]: ordering
+       *  iv[2..end]: weights
+       */
+      R->order[n] = (*iv)[1];
+      typ=1;
+      switch ((*iv)[1])
+      {
+          case ringorder_ws:
+          case ringorder_Ws:
+            typ=-1;
+          case ringorder_wp:
+          case ringorder_Wp:
+            R->wvhdl[n]=(int*)omAlloc((iv->length()-1)*sizeof(int));
+            R->block0[n] = last+1;
+            for (i=2; i<iv->length(); i++)
+            {
+              R->wvhdl[n][i-2] = (*iv)[i];
+              last++;
+              if (weights[last]==0) weights[last]=(*iv)[i]*typ;
+            }
+            R->block1[n] = last;
+            break;
+          case ringorder_ls:
+          case ringorder_ds:
+          case ringorder_Ds:
+          case ringorder_rs:
+            typ=-1;
+          case ringorder_lp:
+          case ringorder_dp:
+          case ringorder_Dp:
+          case ringorder_rp:
+            R->block0[n] = last+1;
+            if (iv->length() == 3) last+=(*iv)[2];
+            else last += (*iv)[0];
+            R->block1[n] = last;
+            //if ((R->block0[n]>R->block1[n])
+            //|| (R->block1[n]>rVar(R)))
+            //{
+            //  R->block1[n]=rVar(R);
+            //  //WerrorS("ordering larger than number of variables");
+            //  break;
+            //}
+            if (rCheckIV(iv)) return TRUE;
+            for(i=si_min(rVar(R),R->block1[n]);i>=R->block0[n];i--)
+            {
+              if (weights[i]==0) weights[i]=typ;
+            }
+            break;
+
+          case ringorder_s: // no 'rank' params!
+          {
+
+            if(iv->length() > 3)
+              return TRUE;
+
+            if(iv->length() == 3)
+            {
+              const int s = (*iv)[2];
+              R->block0[n] = s;
+              R->block1[n] = s;
+            }
+            break;
+          }
+          case ringorder_IS:
+          {
+            if(iv->length() != 3) return TRUE;
+
+            const int s = (*iv)[2];
+
+            if( 1 < s || s < -1 ) return TRUE;
+
+            R->block0[n] = s;
+            R->block1[n] = s;
+            break;
+          }
+          case ringorder_S:
+          case ringorder_c:
+          case ringorder_C:
+          {
+            if (rCheckIV(iv)) return TRUE;
+            break;
+          }
+          case ringorder_aa:
+          case ringorder_a:
+          {
+            R->block0[n] = last+1;
+            R->block1[n] = si_min(last+iv->length()-2 , rVar(R));
+            R->wvhdl[n] = (int*)omAlloc((iv->length()-1)*sizeof(int));
+            for (i=2; i<iv->length(); i++)
+            {
+              R->wvhdl[n][i-2]=(*iv)[i];
+              last++;
+              if (weights[last]==0) weights[last]=(*iv)[i]*typ;
+            }
+            last=R->block0[n]-1;
+            break;
+          }
+          case ringorder_am:
+          {
+            R->block0[n] = last+1;
+            R->block1[n] = si_min(last+iv->length()-2 , rVar(R));
+            R->wvhdl[n] = (int*)omAlloc(iv->length()*sizeof(int));
+            if (R->block1[n]- R->block0[n]+2>=iv->length())
+               WarnS("missing module weights");
+            for (i=2; i<=(R->block1[n]-R->block0[n]+2); i++)
+            {
+              R->wvhdl[n][i-2]=(*iv)[i];
+              last++;
+              if (weights[last]==0) weights[last]=(*iv)[i]*typ;
+            }
+            R->wvhdl[n][i-2]=iv->length() -3 -(R->block1[n]- R->block0[n]);
+            for (; i<iv->length(); i++)
+            {
+              R->wvhdl[n][i-1]=(*iv)[i];
+            }
+            last=R->block0[n]-1;
+            break;
+          }
+          case ringorder_a64:
+          {
+            R->block0[n] = last+1;
+            R->block1[n] = si_min(last+iv->length()-2 , rVar(R));
+            R->wvhdl[n] = (int*)omAlloc((iv->length()-1)*sizeof(int64));
+            int64 *w=(int64 *)R->wvhdl[n];
+            for (i=2; i<iv->length(); i++)
+            {
+              w[i-2]=(*iv)[i];
+              last++;
+              if (weights[last]==0) weights[last]=(*iv)[i]*typ;
+            }
+            last=R->block0[n]-1;
+            break;
+          }
+          case ringorder_M:
+          {
+            int Mtyp=rTypeOfMatrixOrder(iv);
+            if (Mtyp==0) return TRUE;
+            if (Mtyp==-1) typ = -1;
+
+            R->wvhdl[n] =( int *)omAlloc((iv->length()-1)*sizeof(int));
+            for (i=2; i<iv->length();i++)
+              R->wvhdl[n][i-2]=(*iv)[i];
+
+            R->block0[n] = last+1;
+            last += (int)sqrt((double)(iv->length()-2));
+            R->block1[n] = last;
+            for(i=si_min(rVar(R),R->block1[n]);i>=R->block0[n];i--)
+            {
+              if (weights[i]==0) weights[i]=typ;
+            }
+            break;
+          }
+
+          case ringorder_no:
+            R->order[n] = ringorder_unspec;
+            return TRUE;
+
+          default:
+            Werror("Internal Error: Unknown ordering %d", (*iv)[1]);
+            R->order[n] = ringorder_unspec;
+            return TRUE;
+      }
+    }
+    sl=sl->next;
+  }
+
+  // check for complete coverage
+  while ( n >= 0 && (
+          (R->order[n]==ringorder_c)
+      ||  (R->order[n]==ringorder_C)
+      ||  (R->order[n]==ringorder_s)
+      ||  (R->order[n]==ringorder_S)
+      ||  (R->order[n]==ringorder_IS)
+                    )) n--;
+
+  assume( n >= 0 );
+
+  if (R->block1[n] != R->N)
+  {
+    if (((R->order[n]==ringorder_dp) ||
+         (R->order[n]==ringorder_ds) ||
+         (R->order[n]==ringorder_Dp) ||
+         (R->order[n]==ringorder_Ds) ||
+         (R->order[n]==ringorder_rp) ||
+         (R->order[n]==ringorder_rs) ||
+         (R->order[n]==ringorder_lp) ||
+         (R->order[n]==ringorder_ls))
+        &&
+        R->block0[n] <= R->N)
+    {
+      R->block1[n] = R->N;
+    }
+    else
+    {
+      Werror("mismatch of number of vars (%d) and ordering (%d vars)",
+             R->N,R->block1[n]);
+      return TRUE;
+    }
+  }
+  // find OrdSgn:
+  R->OrdSgn = 1;
+  for(i=1;i<=R->N;i++)
+  { if (weights[i]<0) { R->OrdSgn=-1;break; }}
+  omFree(weights);
+  return FALSE;
+}
+
+BOOLEAN rSleftvList2StringArray(sleftv* sl, char** p)
+{
+
+  while(sl!=NULL)
+  {
+    if (sl->Name() == sNoName)
+    {
+      if (sl->Typ()==POLY_CMD)
+      {
+        sleftv s_sl;
+        iiConvert(POLY_CMD,ANY_TYPE,-1,sl,&s_sl);
+        if (s_sl.Name() != sNoName)
+          *p = omStrDup(s_sl.Name());
+        else
+          *p = NULL;
+        sl->next = s_sl.next;
+        s_sl.next = NULL;
+        s_sl.CleanUp();
+        if (*p == NULL) return TRUE;
+      }
+      else
+        return TRUE;
+    }
+    else
+      *p = omStrDup(sl->Name());
+    p++;
+    sl=sl->next;
+  }
+  return FALSE;
+}
+
+const short MAX_SHORT = 32767; // (1 << (sizeof(short)*8)) - 1;
+
+////////////////////
+//
+// rInit itself:
+//
+// INPUT:  s: name, pn: ch & parameter (names), rv: variable (names)
+//         ord: ordering
+// RETURN: currRingHdl on success
+//         NULL        on error
+// NOTE:   * makes new ring to current ring, on success
+//         * considers input sleftv's as read-only
+//idhdl rInit(char *s, sleftv* pn, sleftv* rv, sleftv* ord)
+ring rInit(sleftv* pn, sleftv* rv, sleftv* ord)
+{
+#ifdef HAVE_RINGS
+  //unsigned int ringtype = 0;
+  mpz_ptr modBase = NULL;
+  unsigned int modExponent = 1;
+#endif
+  int float_len=0;
+  int float_len2=0;
+  ring R = NULL;
+  //BOOLEAN ffChar=FALSE;
+
+  /* ch -------------------------------------------------------*/
+  // get ch of ground field
+
+  // allocated ring
+  R = (ring) omAlloc0Bin(sip_sring_bin);
+
+  coeffs cf = NULL;
+
+  assume( pn != NULL );
+  const int P = pn->listLength();
+
+  if ((pn->Typ()==CRING_CMD)&&(P==1))
+  {
+    cf=(coeffs)pn->CopyD();
+    assume( cf != NULL );
+  }
+  else if (pn->Typ()==INT_CMD)
+  {
+    int ch = (int)(long)pn->Data();
+
+    /* parameter? -------------------------------------------------------*/
+    pn = pn->next;
+
+    if (pn == NULL) // no params!?
+    {
+      if (ch!=0)
+      {
+        int ch2=IsPrime(ch);
+        if ((ch<2)||(ch!=ch2))
+        {
+          Warn("%d is invalid as characteristic of the ground field. 32003 is used.", ch);
+          ch=32003;
+        }
+        cf = nInitChar(n_Zp, (void*)(long)ch);
+      }
+      else
+        cf = nInitChar(n_Q, (void*)(long)ch);
+    }
+    else
+    {
+      const int pars = pn->listLength();
+
+      assume( pars > 0 );
+
+      // predefined finite field: (p^k, a)
+      if ((ch!=0) && (ch!=IsPrime(ch)) && (pars == 1))
+      {
+        GFInfo param;
+
+        param.GFChar = ch;
+        param.GFDegree = 1;
+        param.GFPar_name = pn->name;
+
+        cf = nInitChar(n_GF, &param);
+      }
+      else // (0/p, a, b, ..., z)
+      {
+        if ((ch!=0) && (ch!=IsPrime(ch)))
+        {
+          WerrorS("too many parameters");
+          goto rInitError;
+        }
+
+        char ** names = (char**)omAlloc0(pars * sizeof(char_ptr));
+
+        if (rSleftvList2StringArray(pn, names))
+        {
+          WerrorS("parameter expected");
+          goto rInitError;
+        }
+
+        TransExtInfo extParam;
+
+        extParam.r = rDefault( ch, pars, names); // Q/Zp [ p_1, ... p_pars ]
+        for(int i=pars-1; i>=0;i--)
+        {
+          omFree(names[i]);
+        }
+        omFree(names);
+
+        cf = nInitChar(n_transExt, &extParam);
+      }
+    }
+
+//    if (cf==NULL) goto rInitError;
+    assume( cf != NULL );
+  }
+  else if ((pn->name != NULL)
+  && ((strcmp(pn->name,"real")==0) || (strcmp(pn->name,"complex")==0)))
+  {
+    BOOLEAN complex_flag=(strcmp(pn->name,"complex")==0);
+    if ((pn->next!=NULL) && (pn->next->Typ()==INT_CMD))
+    {
+      float_len=(int)(long)pn->next->Data();
+      float_len2=float_len;
+      pn=pn->next;
+      if ((pn->next!=NULL) && (pn->next->Typ()==INT_CMD))
+      {
+        float_len2=(int)(long)pn->next->Data();
+        pn=pn->next;
+      }
+    }
+
+    if (!complex_flag)
+      complex_flag= pn->next != NULL;
+    if( !complex_flag && (float_len2 <= (short)SHORT_REAL_LENGTH))
+       cf=nInitChar(n_R, NULL);
+    else // longR or longC?
+    {
+       LongComplexInfo param;
+
+       param.float_len = si_min (float_len, 32767);
+       param.float_len2 = si_min (float_len2, 32767);
+
+       // set the parameter name
+       if (complex_flag)
+       {
+         if (param.float_len < SHORT_REAL_LENGTH)
+         {
+           param.float_len= SHORT_REAL_LENGTH;
+           param.float_len2= SHORT_REAL_LENGTH;
+         }
+         if (pn->next == NULL)
+           param.par_name=(const char*)"i"; //default to i
+         else
+           param.par_name = (const char*)pn->next->name;
+       }
+
+       cf = nInitChar(complex_flag ? n_long_C: n_long_R, (void*)&param);
+    }
+    assume( cf != NULL );
+  }
+#ifdef HAVE_RINGS
+  else if ((pn->name != NULL) && (strcmp(pn->name, "integer") == 0))
+  {
+    // TODO: change to use coeffs_BIGINT!?
+    modBase = (mpz_ptr) omAlloc(sizeof(mpz_t));
+    mpz_init_set_si(modBase, 0);
+    if (pn->next!=NULL)
+    {
+      if (pn->next->Typ()==INT_CMD)
+      {
+        mpz_set_ui(modBase, (int)(long) pn->next->Data());
+        pn=pn->next;
+        if ((pn->next!=NULL) && (pn->next->Typ()==INT_CMD))
+        {
+          modExponent = (long) pn->next->Data();
+          pn=pn->next;
+        }
+        while ((pn->next!=NULL) && (pn->next->Typ()==INT_CMD))
+        {
+          mpz_mul_ui(modBase, modBase, (int)(long) pn->next->Data());
+          pn=pn->next;
+        }
+      }
+      else if (pn->next->Typ()==BIGINT_CMD)
+      {
+        number p=(number)pn->next->CopyD(); // FIXME: why CopyD() here if nlGMP should not overtake p!?
+        nlGMP(p,(number)modBase,coeffs_BIGINT); // TODO? // extern void   nlGMP(number &i, number n, const coeffs r); // FIXME: n_MPZ( modBase, p, coeffs_BIGINT); ?
+        n_Delete(&p,coeffs_BIGINT);
+      }
+    }
+    else
+      cf=nInitChar(n_Z,NULL);
+
+    if ((mpz_cmp_ui(modBase, 1) == 0) && (mpz_cmp_ui(modBase, 0) < 0))
+    {
+      Werror("Wrong ground ring specification (module is 1)");
+      goto rInitError;
+    }
+    if (modExponent < 1)
+    {
+      Werror("Wrong ground ring specification (exponent smaller than 1");
+      goto rInitError;
+    }
+    // module is 0 ---> integers ringtype = 4;
+    // we have an exponent
+    if (modExponent > 1 && cf == NULL)
+    {
+      if ((mpz_cmp_ui(modBase, 2) == 0) && (modExponent <= 8*sizeof(unsigned long)))
+      {
+        /* this branch should be active for modExponent = 2..32 resp. 2..64,
+           depending on the size of a long on the respective platform */
+        //ringtype = 1;       // Use Z/2^ch
+        cf=nInitChar(n_Z2m,(void*)(long)modExponent);
+	mpz_clear(modBase);
+        omFreeSize (modBase, sizeof (mpz_t));
+      }
+      else
+      {
+        if (mpz_cmp_ui(modBase,0)==0)
+        {
+          WerrorS("modulus must not be 0 or parameter not allowed");
+          goto rInitError;
+        }
+        //ringtype = 3;
+        ZnmInfo info;
+        info.base= modBase;
+        info.exp= modExponent;
+        cf=nInitChar(n_Znm,(void*) &info); //exponent is missing
+      }
+    }
+    // just a module m > 1
+    else if (cf == NULL)
+    {
+      if (mpz_cmp_ui(modBase,0)==0)
+      {
+        WerrorS("modulus must not be 0 or parameter not allowed");
+        goto rInitError;
+      }
+      //ringtype = 2;
+      ZnmInfo info;
+      info.base= modBase;
+      info.exp= modExponent;
+      cf=nInitChar(n_Zn,(void*) &info);
+    }
+    assume( cf != NULL );
+  }
+#endif
+  // ring NEW = OLD, (), (); where OLD is a polynomial ring...
+  else if ((pn->Typ()==RING_CMD) && (P == 1))
+  {
+    TransExtInfo extParam;
+    extParam.r = (ring)pn->Data();
+    cf = nInitChar(n_transExt, &extParam);
+  }
+  else if ((pn->Typ()==QRING_CMD) && (P == 1)) // same for qrings - which should be fields!?
+  {
+    AlgExtInfo extParam;
+    extParam.r = (ring)pn->Data();
+
+    cf = nInitChar(n_algExt, &extParam);   // Q[a]/<minideal>
+  }
+  else
+  {
+    Werror("Wrong or unknown ground field specification");
+#ifndef SING_NDEBUG
+    sleftv* p = pn;
+    while (p != NULL)
+    {
+      Print( "pn[%p]: type: %d [%s]: %p, name: %s", (void*)p, p->Typ(), Tok2Cmdname(p->Typ()), p->Data(), (p->name == NULL? "NULL" : p->name) );
+      PrintLn();
+      p = p->next;
+    }
+#endif
+    goto rInitError;
+  }
+//  pn=pn->next;
+
+  /*every entry in the new ring is initialized to 0*/
+
+  /* characteristic -----------------------------------------------*/
+  /* input: 0 ch=0 : Q     parameter=NULL    ffChar=FALSE   float_len
+   *         0    1 : Q(a,...)        *names         FALSE
+   *         0   -1 : R               NULL           FALSE  0
+   *         0   -1 : R               NULL           FALSE  prec. >6
+   *         0   -1 : C               *names         FALSE  prec. 0..?
+   *         p    p : Fp              NULL           FALSE
+   *         p   -p : Fp(a)           *names         FALSE
+   *         q    q : GF(q=p^n)       *names         TRUE
+  */
+  if (cf==NULL)
+  {
+    Werror("Invalid ground field specification");
+    goto rInitError;
+//    const int ch=32003;
+//    cf=nInitChar(n_Zp, (void*)(long)ch);
+  }
+
+  assume( R != NULL );
+
+  R->cf = cf;
+
+  /* names and number of variables-------------------------------------*/
+  {
+    int l=rv->listLength();
+
+    if (l>MAX_SHORT)
+    {
+      Werror("too many ring variables(%d), max is %d",l,MAX_SHORT);
+       goto rInitError;
+    }
+    R->N = l; /*rv->listLength();*/
+  }
+  R->names   = (char **)omAlloc0(R->N * sizeof(char_ptr));
+  if (rSleftvList2StringArray(rv, R->names))
+  {
+    WerrorS("name of ring variable expected");
+    goto rInitError;
+  }
+
+  /* check names and parameters for conflicts ------------------------- */
+  rRenameVars(R); // conflicting variables will be renamed
+  /* ordering -------------------------------------------------------------*/
+  if (rSleftvOrdering2Ordering(ord, R))
+    goto rInitError;
+
+  // Complete the initialization
+  if (rComplete(R,1))
+    goto rInitError;
+
+/*#ifdef HAVE_RINGS
+// currently, coefficients which are ring elements require a global ordering:
+  if (rField_is_Ring(R) && (R->OrdSgn==-1))
+  {
+    WerrorS("global ordering required for these coefficients");
+    goto rInitError;
+  }
+#endif*/
+
+  rTest(R);
+
+  // try to enter the ring into the name list
+  // need to clean up sleftv here, before this ring can be set to
+  // new currRing or currRing can be killed beacuse new ring has
+  // same name
+  if (pn != NULL) pn->CleanUp();
+  if (rv != NULL) rv->CleanUp();
+  if (ord != NULL) ord->CleanUp();
+  //if ((tmp = enterid(s, myynest, RING_CMD, &IDROOT))==NULL)
+  //  goto rInitError;
+
+  //memcpy(IDRING(tmp),R,sizeof(*R));
+  // set current ring
+  //omFreeBin(R,  ip_sring_bin);
+  //return tmp;
+  return R;
+
+  // error case:
+  rInitError:
+  if  ((R != NULL)&&(R->cf!=NULL)) rDelete(R);
+  if (pn != NULL) pn->CleanUp();
+  if (rv != NULL) rv->CleanUp();
+  if (ord != NULL) ord->CleanUp();
+  return NULL;
+}
+
+ring rSubring(ring org_ring, sleftv* rv)
+{
+  ring R = rCopy0(org_ring);
+  int *perm=(int *)omAlloc0((org_ring->N+1)*sizeof(int));
+  int n = rBlocks(org_ring), i=0, j;
+
+  /* names and number of variables-------------------------------------*/
+  {
+    int l=rv->listLength();
+    if (l>MAX_SHORT)
+    {
+      Werror("too many ring variables(%d), max is %d",l,MAX_SHORT);
+       goto rInitError;
+    }
+    R->N = l; /*rv->listLength();*/
+  }
+  omFree(R->names);
+  R->names   = (char **)omAlloc0(R->N * sizeof(char_ptr));
+  if (rSleftvList2StringArray(rv, R->names))
+  {
+    WerrorS("name of ring variable expected");
+    goto rInitError;
+  }
+
+  /* check names for subring in org_ring ------------------------- */
+  {
+    i=0;
+
+    for(j=0;j<R->N;j++)
+    {
+      for(;i<org_ring->N;i++)
+      {
+        if (strcmp(org_ring->names[i],R->names[j])==0)
+        {
+          perm[i+1]=j+1;
+          break;
+        }
+      }
+      if (i>org_ring->N)
+      {
+        Werror("variable %d (%s) not in basering",j+1,R->names[j]);
+        break;
+      }
+    }
+  }
+  //Print("perm=");
+  //for(i=1;i<org_ring->N;i++) Print("v%d -> v%d\n",i,perm[i]);
+  /* ordering -------------------------------------------------------------*/
+
+  for(i=0;i<n;i++)
+  {
+    int min_var=-1;
+    int max_var=-1;
+    for(j=R->block0[i];j<=R->block1[i];j++)
+    {
+      if (perm[j]>0)
+      {
+        if (min_var==-1) min_var=perm[j];
+        max_var=perm[j];
+      }
+    }
+    if (min_var!=-1)
+    {
+      //Print("block %d: old %d..%d, now:%d..%d\n",
+      //      i,R->block0[i],R->block1[i],min_var,max_var);
+      R->block0[i]=min_var;
+      R->block1[i]=max_var;
+      if (R->wvhdl[i]!=NULL)
+      {
+        omFree(R->wvhdl[i]);
+        R->wvhdl[i]=(int*)omAlloc0((max_var-min_var+1)*sizeof(int));
+        for(j=org_ring->block0[i];j<=org_ring->block1[i];j++)
+        {
+          if (perm[j]>0)
+          {
+            R->wvhdl[i][perm[j]-R->block0[i]]=
+                org_ring->wvhdl[i][j-org_ring->block0[i]];
+            //Print("w%d=%d (orig_w%d)\n",perm[j],R->wvhdl[i][perm[j]-R->block0[i]],j);
+          }
+        }
+      }
+    }
+    else
+    {
+      if(R->block0[i]>0)
+      {
+        //Print("skip block %d\n",i);
+        R->order[i]=ringorder_unspec;
+        if (R->wvhdl[i] !=NULL) omFree(R->wvhdl[i]);
+        R->wvhdl[i]=NULL;
+      }
+      //else Print("keep block %d\n",i);
+    }
+  }
+  i=n-1;
+  while(i>0)
+  {
+    // removed unneded blocks
+    if(R->order[i-1]==ringorder_unspec)
+    {
+      for(j=i;j<=n;j++)
+      {
+        R->order[j-1]=R->order[j];
+        R->block0[j-1]=R->block0[j];
+        R->block1[j-1]=R->block1[j];
+        if (R->wvhdl[j-1] !=NULL) omFree(R->wvhdl[j-1]);
+        R->wvhdl[j-1]=R->wvhdl[j];
+      }
+      R->order[n]=ringorder_unspec;
+      n--;
+    }
+    i--;
+  }
+  n=rBlocks(org_ring)-1;
+  while (R->order[n]==0)  n--;
+  while (R->order[n]==ringorder_unspec)  n--;
+  if ((R->order[n]==ringorder_c) ||  (R->order[n]==ringorder_C)) n--;
+  if (R->block1[n] != R->N)
+  {
+    if (((R->order[n]==ringorder_dp) ||
+         (R->order[n]==ringorder_ds) ||
+         (R->order[n]==ringorder_Dp) ||
+         (R->order[n]==ringorder_Ds) ||
+         (R->order[n]==ringorder_rp) ||
+         (R->order[n]==ringorder_rs) ||
+         (R->order[n]==ringorder_lp) ||
+         (R->order[n]==ringorder_ls))
+        &&
+        R->block0[n] <= R->N)
+    {
+      R->block1[n] = R->N;
+    }
+    else
+    {
+      Werror("mismatch of number of vars (%d) and ordering (%d vars) in block %d",
+             R->N,R->block1[n],n);
+      return NULL;
+    }
+  }
+  omFree(perm);
+  // find OrdSgn:
+  R->OrdSgn = org_ring->OrdSgn; // IMPROVE!
+  //for(i=1;i<=R->N;i++)
+  //{ if (weights[i]<0) { R->OrdSgn=-1;break; }}
+  //omFree(weights);
+  // Complete the initialization
+  if (rComplete(R,1))
+    goto rInitError;
+
+  rTest(R);
+
+  if (rv != NULL) rv->CleanUp();
+
+  return R;
+
+  // error case:
+  rInitError:
+  if  (R != NULL) rDelete(R);
+  if (rv != NULL) rv->CleanUp();
+  return NULL;
+}
+
+void rKill(ring r)
+{
+  if ((r->ref<=0)&&(r->order!=NULL))
+  {
+#ifdef RDEBUG
+    if (traceit &TRACE_SHOW_RINGS) Print("kill ring %lx\n",(long)r);
+#endif
+    if (r->qideal!=NULL)
+    {
+      id_Delete(&r->qideal, r);
+      r->qideal = NULL;
+    }
+    int j;
+#ifdef USE_IILOCALRING
+    for (j=0;j<myynest;j++)
+    {
+      if (iiLocalRing[j]==r)
+      {
+        if (j+1==myynest) Warn("killing the basering for level %d",j);
+        iiLocalRing[j]=NULL;
+      }
+    }
+#else /* USE_IILOCALRING */
+//#endif /* USE_IILOCALRING */
+    {
+      proclevel * nshdl = procstack;
+      int lev=myynest-1;
+
+      for(; nshdl != NULL; nshdl = nshdl->next)
+      {
+        if (nshdl->cRing==r)
+        {
+          Warn("killing the basering for level %d",lev);
+          nshdl->cRing=NULL;
+          nshdl->cRingHdl=NULL;
+        }
+      }
+    }
+#endif /* USE_IILOCALRING */
+// any variables depending on r ?
+    while (r->idroot!=NULL)
+    {
+      r->idroot->lev=myynest; // avoid warning about kill global objects
+      killhdl2(r->idroot,&(r->idroot),r);
+    }
+    if (r==currRing)
+    {
+      // all dependend stuff is done, clean global vars:
+      if ((currRing->ppNoether)!=NULL) pDelete(&(currRing->ppNoether));
+      if (sLastPrinted.RingDependend())
+      {
+        sLastPrinted.CleanUp();
+      }
+      //if ((myynest>0) && (iiRETURNEXPR.RingDependend()))
+      //{
+      //  WerrorS("return value depends on local ring variable (export missing ?)");
+      //  iiRETURNEXPR.CleanUp();
+      //}
+      currRing=NULL;
+      currRingHdl=NULL;
+    }
+
+    /* nKillChar(r); will be called from inside of rDelete */
+    rDelete(r);
+    return;
+  }
+  r->ref--;
+}
+
+void rKill(idhdl h)
+{
+  ring r = IDRING(h);
+  int ref=0;
+  if (r!=NULL)
+  {
+    ref=r->ref;
+    rKill(r);
+  }
+  if (h==currRingHdl)
+  {
+    if (ref<=0) { currRing=NULL; currRingHdl=NULL;}
+    else
+    {
+      currRingHdl=rFindHdl(r,currRingHdl);
+    }
+  }
+}
+
+idhdl rSimpleFindHdl(ring r, idhdl root, idhdl n)
+{
+  //idhdl next_best=NULL;
+  idhdl h=root;
+  while (h!=NULL)
+  {
+    if (((IDTYP(h)==RING_CMD)||(IDTYP(h)==QRING_CMD))
+    && (h!=n)
+    && (IDRING(h)==r)
+    )
+    {
+   //   if (IDLEV(h)==myynest)
+   //     return h;
+   //   if ((IDLEV(h)==0) || (next_best==NULL))
+   //     next_best=h;
+   //   else if (IDLEV(next_best)<IDLEV(h))
+   //     next_best=h;
+      return h;
+    }
+    h=IDNEXT(h);
+  }
+  //return next_best;
+  return NULL;
+}
+
+extern BOOLEAN jjPROC(leftv res, leftv u, leftv v);
+ideal kGroebner(ideal F, ideal Q)
+{
+  //test|=Sy_bit(OPT_PROT);
+  idhdl save_ringhdl=currRingHdl;
+  ideal resid;
+  idhdl new_ring=NULL;
+  if ((currRingHdl==NULL) || (IDRING(currRingHdl)!=currRing))
+  {
+    currRingHdl=enterid(omStrDup(" GROEBNERring"),0,RING_CMD,&IDROOT,FALSE);
+    new_ring=currRingHdl;
+    IDRING(currRingHdl)=currRing;
+  }
+  sleftv v; memset(&v,0,sizeof(v)); v.rtyp=IDEAL_CMD; v.data=(char *) F;
+  idhdl h=ggetid("groebner");
+  sleftv u; memset(&u,0,sizeof(u)); u.rtyp=IDHDL; u.data=(char *) h;
+            u.name=IDID(h);
+
+  sleftv res; memset(&res,0,sizeof(res));
+  if(jjPROC(&res,&u,&v))
+  {
+    resid=kStd(F,Q,testHomog,NULL);
+  }
+  else
+  {
+    //printf("typ:%d\n",res.rtyp);
+    resid=(ideal)(res.data);
+  }
+  // cleanup GROEBNERring, save_ringhdl, u,v,(res )
+  if (new_ring!=NULL)
+  {
+    idhdl h=IDROOT;
+    if (h==new_ring) IDROOT=h->next;
+    else
+    {
+      while ((h!=NULL) &&(h->next!=new_ring)) h=h->next;
+      if (h!=NULL) h->next=h->next->next;
+    }
+    if (h!=NULL) omFreeSize(h,sizeof(*h));
+  }
+  currRingHdl=save_ringhdl;
+  u.CleanUp();
+  v.CleanUp();
+  return resid;
+}
+
+static void jjINT_S_TO_ID(int n,int *e, leftv res)
+{
+  if (n==0) n=1;
+  ideal l=idInit(n,1);
+  int i;
+  poly p;
+  for(i=rVar(currRing);i>0;i--)
+  {
+    if (e[i]>0)
+    {
+      n--;
+      p=pOne();
+      pSetExp(p,i,1);
+      pSetm(p);
+      l->m[n]=p;
+      if (n==0) break;
+    }
+  }
+  res->data=(char*)l;
+  setFlag(res,FLAG_STD);
+  omFreeSize((ADDRESS)e,(rVar(currRing)+1)*sizeof(int));
+}
+BOOLEAN jjVARIABLES_P(leftv res, leftv u)
+{
+  int *e=(int *)omAlloc0((rVar(currRing)+1)*sizeof(int));
+  int n=pGetVariables((poly)u->Data(),e);
+  jjINT_S_TO_ID(n,e,res);
+  return FALSE;
+}
+
+BOOLEAN jjVARIABLES_ID(leftv res, leftv u)
+{
+  int *e=(int *)omAlloc0((rVar(currRing)+1)*sizeof(int));
+  ideal I=(ideal)u->Data();
+  int i;
+  int n=0;
+  for(i=I->nrows*I->ncols-1;i>=0;i--)
+  {
+    int n0=pGetVariables(I->m[i],e);
+    if (n0>n) n=n0;
+  }
+  jjINT_S_TO_ID(n,e,res);
+  return FALSE;
+}
+
+void paPrint(const char *n,package p)
+{
+  Print(" %s (",n);
+  switch (p->language)
+  {
+    case LANG_SINGULAR: PrintS("S"); break;
+    case LANG_C:        PrintS("C"); break;
+    case LANG_TOP:      PrintS("T"); break;
+    case LANG_NONE:     PrintS("N"); break;
+    default:            PrintS("U");
+  }
+  if(p->libname!=NULL)
+  Print(",%s", p->libname);
+  PrintS(")");
+}
+
+BOOLEAN iiApplyINTVEC(leftv res, leftv a, int op, leftv proc)
+{
+  intvec *aa=(intvec*)a->Data();
+  intvec *r=ivCopy(aa);
+  sleftv tmp_out;
+  sleftv tmp_in;
+  BOOLEAN bo=FALSE;
+  for(int i=0;i<aa->length(); i++)
+  {
+    memset(&tmp_in,0,sizeof(tmp_in));
+    tmp_in.rtyp=INT_CMD;
+    tmp_in.data=(void*)(long)(*aa)[i];
+    if (proc==NULL)
+      bo=iiExprArith1(&tmp_out,&tmp_in,op);
+    else
+      bo=jjPROC(&tmp_out,proc,&tmp_in);
+    if (bo || (tmp_out.rtyp!=INT_CMD))
+    {
+      if (r!=NULL) delete r;
+      Werror("apply fails at index %d",i+1);
+      return TRUE;
+    }
+    (*r)[i]=(int)(long)tmp_out.data;
+  }
+  res->data=(void*)r;
+  return FALSE;
+}
+BOOLEAN iiApplyBIGINTMAT(leftv res, leftv a, int op, leftv proc)
+{
+  WerrorS("not implemented");
+  return TRUE;
+}
+BOOLEAN iiApplyIDEAL(leftv res, leftv a, int op, leftv proc)
+{
+  WerrorS("not implemented");
+  return TRUE;
+}
+BOOLEAN iiApplyLIST(leftv res, leftv a, int op, leftv proc)
+{
+  lists aa=(lists)a->Data();
+  lists r=(lists)omAlloc0Bin(slists_bin); r->Init(aa->nr+1);
+  sleftv tmp_out;
+  sleftv tmp_in;
+  BOOLEAN bo=FALSE;
+  for(int i=0;i<=aa->nr; i++)
+  {
+    memset(&tmp_in,0,sizeof(tmp_in));
+    tmp_in.Copy(&(aa->m[i]));
+    if (proc==NULL)
+      bo=iiExprArith1(&tmp_out,&tmp_in,op);
+    else
+      bo=jjPROC(&tmp_out,proc,&tmp_in);
+    tmp_in.CleanUp();
+    if (bo)
+    {
+      if (r!=NULL) r->Clean();
+      Werror("apply fails at index %d",i+1);
+      return TRUE;
+    }
+    memcpy(&(r->m[i]),&tmp_out,sizeof(sleftv));
+  }
+  res->data=(void*)r;
+  return FALSE;
+}
+BOOLEAN iiApply(leftv res, leftv a, int op, leftv proc)
+{
+  memset(res,0,sizeof(sleftv));
+  res->rtyp=a->Typ();
+  switch (res->rtyp /*a->Typ()*/)
+  {
+    case INTVEC_CMD:
+    case INTMAT_CMD:
+        return iiApplyINTVEC(res,a,op,proc);
+    case BIGINTMAT_CMD:
+        return iiApplyBIGINTMAT(res,a,op,proc);
+    case IDEAL_CMD:
+    case MODUL_CMD:
+    case MATRIX_CMD:
+        return iiApplyIDEAL(res,a,op,proc);
+    case LIST_CMD:
+        return iiApplyLIST(res,a,op,proc);
+  }
+  WerrorS("first argument to `apply` must allow an index");
+  return TRUE;
+}
+
+BOOLEAN iiTestAssume(leftv a, leftv b)
+{
+  // assume a: level
+  if ((a->Typ()==INT_CMD)&&((long)a->Data()>=0))
+  {
+    if ((TEST_V_ALLWARN) && (myynest==0)) WarnS("ASSUME at top level is of no use: see documentation");
+    char       assume_yylinebuf[80];
+    strncpy(assume_yylinebuf,my_yylinebuf,79);
+    int lev=(long)a->Data();
+    int startlev=0;
+    idhdl h=ggetid("assumeLevel");
+    if ((h!=NULL)&&(IDTYP(h)==INT_CMD)) startlev=(long)IDINT(h);
+    if(lev <=startlev)
+    {
+      BOOLEAN bo=b->Eval();
+      if (bo) { WerrorS("syntax error in ASSUME");return TRUE;}
+      if (b->Typ()!=INT_CMD) { WerrorS("ASUMME(<level>,<int expr>)");return TRUE; }
+      if (b->Data()==NULL) { Werror("ASSUME failed:%s",assume_yylinebuf);return TRUE;}
+    }
+  }
+  b->CleanUp();
+  a->CleanUp();
+  return FALSE;
+}
+
+#include "libparse.h"
+
+BOOLEAN iiARROW(leftv r, char* a, char *s)
+{
+  char *ss=(char*)omAlloc(strlen(a)+strlen(s)+30); /* max. 27 currently */
+  // find end of s:
+  int end_s=strlen(s);
+  while ((end_s>0) && ((s[end_s]<=' ')||(s[end_s]==';'))) end_s--;
+  s[end_s+1]='\0';
+  char *name=(char *)omAlloc(strlen(a)+strlen(s)+30);
+  sprintf(name,"%s->%s",a,s);
+  // find start of last expression
+  int start_s=end_s-1;
+  while ((start_s>=0) && (s[start_s]!=';')) start_s--;
+  if (start_s<0) // ';' not found
+  {
+    sprintf(ss,"parameter def %s;return(%s);\n",a,s);
+  }
+  else // s[start_s] is ';'
+  {
+    s[start_s]='\0';
+    sprintf(ss,"parameter def %s;%s;return(%s);\n",a,s,s+start_s+1);
+  }
+  memset(r,0,sizeof(*r));
+  // now produce procinfo for PROC_CMD:
+  r->data = (void *)omAlloc0Bin(procinfo_bin);
+  ((procinfo *)(r->data))->language=LANG_NONE;
+  iiInitSingularProcinfo((procinfo *)r->data,"",name,0,0);
+  ((procinfo *)r->data)->data.s.body=ss;
+  omFree(name);
+  r->rtyp=PROC_CMD;
+  //r->rtyp=STRING_CMD;
+  //r->data=ss;
+  return FALSE;
+}
+
+BOOLEAN iiAssignCR(leftv r, leftv arg)
+{
+  int t=arg->Typ();
+  char* ring_name=(char*)r->Name();
+  ring_name=omStrDup(ring_name);
+  if ((t==RING_CMD) ||(t==QRING_CMD))
+  {
+    sleftv tmp;
+    memset(&tmp,0,sizeof(tmp));
+    tmp.rtyp=IDHDL;
+    tmp.data=(char*)rDefault(ring_name);
+    if (tmp.data!=NULL)
+    {
+      BOOLEAN b=iiAssign(&tmp,arg);
+      if (b) return TRUE;
+      rSetHdl(ggetid(ring_name));
+      omFree(ring_name);
+      return FALSE;
+    }
+    else
+      return TRUE;
+  }
+  else if (t==CRING_CMD)
+  {
+    sleftv tmp;
+    sleftv n;
+    memset(&n,0,sizeof(n));
+    n.name=ring_name;
+    if (iiDeclCommand(&tmp,&n,myynest,CRING_CMD,&IDROOT)) return TRUE;
+    if (iiAssign(&tmp,arg)) return TRUE;
+    //Print("create %s\n",r->Name());
+    //Print("from %s(%d)\n",Tok2Cmdname(arg->Typ()),arg->Typ());
+    return FALSE;
+  }
+  return TRUE;// not handled -> error for now
+}
+
+static void iiReportTypes(int nr,int t,const short *T)
+{
+  char *buf=(char*)omAlloc(250);
+  buf[0]='\0';
+  if (nr==0)
+    sprintf(buf,"wrong length of parameters(%d), expected ",t);
+  else
+    sprintf(buf,"par. %d is of type `%s`, expected ",nr,Tok2Cmdname(t));
+  for(int i=1;i<=T[0];i++)
+  {
+    strcat(buf,"`");
+    strcat(buf,Tok2Cmdname(T[i]));
+    strcat(buf,"`");
+    if (i<T[0]) strcat(buf,",");
+  }
+  WerrorS(buf);
+}
+
+BOOLEAN iiCheckTypes(leftv args, const short *type_list, int report)
+{
+  if (args==NULL)
+  {
+    if (type_list[0]==0) return TRUE;
+    else
+    {
+      if (report) WerrorS("no arguments expected");
+      return FALSE;
+    }
+  }
+  int l=args->listLength();
+  if (l!=(int)type_list[0])
+  {
+    if (report) iiReportTypes(0,l,type_list);
+    return FALSE;
+  }
+  for(int i=1;i<=l;i++,args=args->next)
+  {
+    short t=type_list[i];
+    if (t!=ANY_TYPE)
+    {
+      if (((t==IDHDL)&&(args->rtyp!=IDHDL))
+      || (t!=args->Typ()))
+      {
+        if (report) iiReportTypes(i,args->Typ(),type_list);
+        return FALSE;
+      }
+    }
+  }
+  return TRUE;
+}
diff --git a/Singular/ipshell.h b/Singular/ipshell.h
new file mode 100644
index 0000000..25a11e4
--- /dev/null
+++ b/Singular/ipshell.h
@@ -0,0 +1,297 @@
+#ifndef IPSHELL_H
+#define IPSHELL_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT
+*/
+#include <stdio.h>
+//#include <kernel/structs.h>
+#include <kernel/ideals.h>
+#include <Singular/lists.h>
+#include <Singular/fevoices.h>
+
+struct _ssubexpr;
+typedef struct _ssubexpr *Subexpr;
+
+BOOLEAN    spectrumProc ( leftv,leftv );
+BOOLEAN    spectrumfProc( leftv,leftv );
+BOOLEAN    spaddProc    ( leftv,leftv,leftv );
+BOOLEAN    spmulProc    ( leftv,leftv,leftv );
+BOOLEAN    semicProc   ( leftv,leftv,leftv );
+BOOLEAN    semicProc3   ( leftv,leftv,leftv,leftv );
+
+BOOLEAN iiAssignCR(leftv, leftv);
+
+BOOLEAN iiARROW (leftv, char*,char *);
+
+extern leftv iiCurrArgs;
+extern idhdl iiCurrProc;
+extern int iiOp; /* the current operation*/
+extern const char *  currid;
+extern int     iiRETURNEXPR_len;
+extern sleftv  iiRETURNEXPR;
+#ifdef USE_IILOCALRING
+extern ring   *iiLocalRing;
+#endif
+//extern cmdnames cmds[];
+extern const char *lastreserved;
+extern const char *singular_date; /* tesths.cc, set by final compile */
+extern int myynest;
+extern int printlevel;
+extern int si_echo;
+
+
+extern BOOLEAN yyInRingConstruction; /* 1: during ring construction */
+
+int     IsCmd(const char *n, int & tok);
+
+BOOLEAN iiPStart(idhdl pn, sleftv * sl);
+BOOLEAN iiEStart(char* example, procinfo *pi);
+BOOLEAN iiAllStart(procinfov pi, char *p,feBufferTypes t, int l);
+void    type_cmd(leftv v);
+void    test_cmd(int i);
+void    list_cmd(int typ, const char* what, const char * prefix,
+                 BOOLEAN iterate, BOOLEAN fullname=FALSE);
+//char *  iiStringMatrix(matrix im, int dim, char ch=',');
+void    killlocals(int v);
+int     exprlist_length(leftv v);
+const char *  Tok2Cmdname(int i);
+const char *  iiTwoOps(int t);
+int           iiOpsTwoChar(const char *s);
+
+int     IsPrime(int i);
+
+BOOLEAN iiWRITE(leftv res,leftv exprlist);
+BOOLEAN iiExport(leftv v, int toLev);
+BOOLEAN iiExport(leftv v, int toLev, package pack);
+BOOLEAN iiInternalExport (leftv v, int toLev, package pack);
+char *  iiGetLibName(procinfov v);
+char *  iiGetLibProcBuffer( procinfov pi, int part=1 );
+char *  iiProcName(char *buf, char & ct, char* &e);
+char *  iiProcArgs(char *e,BOOLEAN withParenth);
+BOOLEAN iiLibCmd( char *newlib, BOOLEAN autoexport, BOOLEAN tellerror, BOOLEAN force );
+/* sees wheter library lib has already been loaded
+   if yes, writes filename of lib into where and returns TRUE,
+   if  no, returns FALSE
+*/
+/// load lib/module given in v
+BOOLEAN jjLOAD(const char *s, BOOLEAN autoexport = FALSE);
+BOOLEAN iiLocateLib(const char* lib, char* where);
+leftv   iiMap(map theMap, const char * what);
+void    iiMakeResolv(resolvente r, int length, int rlen, char * name, int typ0,
+           intvec ** weights=NULL);
+BOOLEAN jjMINRES(leftv res, leftv v);
+BOOLEAN jjBETTI(leftv res, leftv v);
+BOOLEAN jjBETTI2(leftv res, leftv u, leftv v);
+BOOLEAN jjBETTI2_ID(leftv res, leftv u, leftv v);
+BOOLEAN jjIMPORTFROM(leftv res, leftv u, leftv v);
+BOOLEAN jjLIST_PL(leftv res, leftv v);
+
+BOOLEAN jjVARIABLES_P(leftv res, leftv u);
+BOOLEAN jjVARIABLES_ID(leftv res, leftv u);
+
+int     iiRegularity(lists L);
+leftv   singular_system(sleftv h);
+BOOLEAN jjSYSTEM(leftv res, leftv v);
+void    iiDebug();
+BOOLEAN iiCheckRing(int i);
+poly    iiHighCorner(ideal i, int ak);
+char *  iiConvName(const char *libname);
+BOOLEAN iiLoadLIB(FILE *fp, const char *libnamebuf, const char *newlib,
+                         idhdl pl, BOOLEAN autoexport, BOOLEAN tellerror);
+
+// converts a resolution into a list of modules
+lists syConvRes(syStrategy syzstr,BOOLEAN toDel=FALSE,int add_row_shift=0);
+// converts a list of modules into a minimal resolution
+syStrategy syForceMin(lists li);
+// converts a list of modules into a resolution
+syStrategy syConvList(lists li,BOOLEAN toDel);
+
+BOOLEAN syBetti1(leftv res, leftv u);
+BOOLEAN syBetti2(leftv res, leftv u, leftv w);
+
+/* ================================================================== */
+/* Expressions : */
+BOOLEAN iiExprArith1(leftv res, sleftv* a, int op);
+BOOLEAN iiExprArith2(leftv res, sleftv* a, int op, sleftv* b,
+                     BOOLEAN proccall=FALSE);
+BOOLEAN iiExprArith3(leftv res, int op, leftv a, leftv b, leftv c);
+BOOLEAN iiExprArithM(leftv res, sleftv* a, int op);
+BOOLEAN iiApply(leftv res,leftv a, int op, leftv proc);
+
+typedef BOOLEAN (*proc1)(leftv,leftv);
+
+#ifdef GENTABLE
+typedef char * (*Proc1)(char *);
+struct sValCmd1
+{
+  proc1 p;
+  short cmd;
+  short res;
+  short arg;
+  short valid_for;
+};
+
+typedef BOOLEAN (*proc2)(leftv,leftv,leftv);
+struct sValCmd2
+{
+  proc2 p;
+  short cmd;
+  short res;
+  short arg1;
+  short arg2;
+  short valid_for;
+};
+
+typedef BOOLEAN (*proc3)(leftv,leftv,leftv,leftv);
+struct sValCmd3
+{
+  proc3 p;
+  short cmd;
+  short res;
+  short arg1;
+  short arg2;
+  short arg3;
+  short valid_for;
+};
+struct sValCmdM
+{
+  proc1 p;
+  short cmd;
+  short res;
+  short number_of_args; /* -1: any, -2: any >0, .. */
+  short valid_for;
+};
+extern struct sValCmd2 dArith2[];
+extern struct sValCmd1 dArith1[];
+extern struct sValCmd3 dArith3[];
+extern struct sValCmdM dArithM[];
+#endif
+
+/* ================================================================== */
+/* Assigments : */
+BOOLEAN iiAssign(leftv left, leftv right);
+
+typedef BOOLEAN (*proci)(leftv,leftv,Subexpr);
+struct sValAssign_sys
+{
+  proc1 p;
+  short res;
+  short arg;
+};
+
+struct sValAssign
+{
+  proci p;
+  short res;
+  short arg;
+};
+
+BOOLEAN iiParameter(leftv p);
+BOOLEAN iiAlias(leftv p);
+
+int iiTokType(int op);
+/* ================================================================== */
+int     iiDeclCommand(leftv sy, leftv name, int lev, int t, idhdl* root,
+  BOOLEAN isring = FALSE, BOOLEAN init_b=TRUE);
+BOOLEAN iiMake_proc(idhdl pn, package pack, sleftv* sl);
+// from misc.cc:
+char *  showOption();
+BOOLEAN setOption(leftv res, leftv v);
+/* ================================================================== */
+char * versionString();
+/* ================================================================== */
+void  singular_example(char *str);
+
+BOOLEAN iiTryLoadLib(leftv v, const char *id);
+
+int iiAddCproc(const char *libname, const char *procname, BOOLEAN pstatic,
+               BOOLEAN(*func)(leftv res, leftv v));
+
+void iiCheckPack(package &p);
+#ifndef SING_NDEBUG
+void checkall();
+#endif
+
+void rSetHdl(idhdl h);
+ring rInit(sleftv* pn, sleftv* rv, sleftv* ord);
+idhdl  rDefault(const char *s);
+
+idhdl rSimpleFindHdl(ring r, idhdl root, idhdl n=NULL);
+idhdl rFindHdl(ring r, idhdl n);
+void   rKill(idhdl h);
+void   rKill(ring r);
+lists scIndIndset(ideal S, BOOLEAN all, ideal Q);
+BOOLEAN mpKoszul(leftv res,leftv c/*ip*/, leftv b/*in*/, leftv id);
+BOOLEAN mpJacobi(leftv res,leftv a);
+BOOLEAN jjRESULTANT(leftv res, leftv u, leftv v, leftv w);
+BOOLEAN kQHWeight(leftv res,leftv v);
+BOOLEAN kWeight(leftv res,leftv id);
+BOOLEAN loSimplex( leftv res, leftv args );
+BOOLEAN loNewtonP( leftv res, leftv arg1 );
+BOOLEAN nuMPResMat( leftv res, leftv arg1, leftv arg2 );
+BOOLEAN nuLagSolve( leftv res, leftv arg1, leftv arg2, leftv arg3 );
+BOOLEAN nuVanderSys( leftv res, leftv arg1, leftv arg2, leftv arg3);
+BOOLEAN nuUResSolve( leftv res, leftv args );
+
+BOOLEAN jjCHARSERIES(leftv res, leftv u);
+/*
+BOOLEAN jjRESULTANT(leftv res, leftv u, leftv v, leftv w);
+#if 0
+BOOLEAN jjIS_SQR_FREE(leftv res, leftv u);
+#endif
+*/
+/* ================================================================== */
+void paPrint(const char *n,package p);
+/* ================================================================== */
+
+
+BOOLEAN iiTestAssume(leftv a, leftv b);
+
+/* table inteface for iiAddCproc */
+/// apply an operation 'op' to an argument a
+/// return TRUE on failure
+BOOLEAN iiExprArith1Tab(leftv res,///< [out] pre-allocated result
+                        leftv a,  ///< [in]  argument
+                        int op,   ///< [in]  operation
+                        struct sValCmd1* dA1, ///< [in] table of possible proc
+                                                  ///< assumes dArith1[0].cmd==op
+                        int at,   ///< [in] a->Typ()
+                        struct sConvertTypes *dConvertTypes ///< [in] table of type conversions
+                        );
+/// apply an operation 'op' to arguments a and a->next
+/// return TRUE on failure
+BOOLEAN iiExprArith2Tab(leftv res,///< [out] pre-allocated result
+                        leftv a,  ///< [in]  2 arguments
+                        int op,   ///< [in]  operation
+                        struct sValCmd2* dA2,///< [in] table of possible proc
+                                   ///< assumes dA2[0].cmd==op
+                        int at,    ///< [in] a->Typ()
+                        struct sConvertTypes *dConvertTypes ///< [in] table of type conversions
+                        );
+/// apply an operation 'op' to arguments a, a->next and a->next->next
+/// return TRUE on failure
+BOOLEAN iiExprArith3Tab(leftv res, ///< [out] pre-allocated result
+                        leftv a,   ///< [in]  3 arguments
+                        int op,    ///< [in]  operation
+                        struct sValCmd3* dA3,///< [in] table of possible proc
+                                   ///< assumes dA3[0].cmd==op
+                        int at,    ///< [in] a->Typ()
+                        struct sConvertTypes *dConvertTypes ///< [in] table of type conversions
+                        );
+
+/// check a list of arguemys against a given field of types
+/// return TRUE if the types match
+/// return FALSE (and, if report) report an error via Werror otherwise
+BOOLEAN iiCheckTypes(leftv args,/// < [in] argument list (may be NULL)
+                      const short *type_list,///< [in] field of types
+                                             ///< len, t1,t2,...
+                      int report=0  /// ;in] report error?
+                      );
+
+BOOLEAN iiBranchTo(leftv r, leftv args);
+
+#endif
+
diff --git a/Singular/libparse.cc b/Singular/libparse.cc
new file mode 100644
index 0000000..044039d
--- /dev/null
+++ b/Singular/libparse.cc
@@ -0,0 +1,3535 @@
+#define yy_create_buffer yylp_create_buffer
+#define yy_delete_buffer yylp_delete_buffer
+#define yy_scan_buffer yylp_scan_buffer
+#define yy_scan_string yylp_scan_string
+#define yy_scan_bytes yylp_scan_bytes
+#define yy_flex_debug yylp_flex_debug
+#define yy_init_buffer yylp_init_buffer
+#define yy_flush_buffer yylp_flush_buffer
+#define yy_load_buffer_state yylp_load_buffer_state
+#define yy_switch_to_buffer yylp_switch_to_buffer
+#define yyin yylpin
+#define yyleng yylpleng
+#define yylex yylplex
+#define yyout yylpout
+#define yyrestart yylprestart
+#define yytext yylptext
+#define yywrap yylpwrap
+
+/* A lexical scanner generated by flex */
+
+/* Scanner skeleton version:
+ * $Header: /home/daffy/u0/vern/flex/RCS/flex.skl,v 2.91 96/09/10 16:58:48 vern Exp $
+ */
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 5
+
+#include <stdio.h>
+
+
+/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */
+#ifdef c_plusplus
+#ifndef __cplusplus
+#define __cplusplus
+#endif
+#endif
+
+
+#ifdef __cplusplus
+
+#include <stdlib.h>
+#include <unistd.h>
+
+/* Use prototypes in function declarations. */
+#define YY_USE_PROTOS
+
+/* The "const" storage-class-modifier is valid. */
+#define YY_USE_CONST
+
+#else	/* ! __cplusplus */
+
+#if __STDC__
+
+#define YY_USE_PROTOS
+#define YY_USE_CONST
+
+#endif	/* __STDC__ */
+#endif	/* ! __cplusplus */
+
+#ifdef __TURBOC__
+ #pragma warn -rch
+ #pragma warn -use
+#include <io.h>
+#include <stdlib.h>
+#define YY_USE_CONST
+#define YY_USE_PROTOS
+#endif
+
+#ifdef YY_USE_CONST
+#define yyconst const
+#else
+#define yyconst
+#endif
+
+
+#ifdef YY_USE_PROTOS
+#define YY_PROTO(proto) proto
+#else
+#define YY_PROTO(proto) ()
+#endif
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+
+/* Promotes a possibly negative, possibly signed char to an unsigned
+ * integer for use as an array index.  If the signed char is negative,
+ * we want to instead treat it as an 8-bit unsigned char, hence the
+ * double cast.
+ */
+#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+
+/* Enter a start condition.  This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN yy_start = 1 + 2 *
+
+/* Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state.  The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START ((yy_start - 1) / 2)
+#define YYSTATE YY_START
+
+/* Action number for EOF rule of a given start state. */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+
+/* Special action meaning "start processing a new file". */
+#define YY_NEW_FILE yyrestart( yyin )
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#define YY_BUF_SIZE 16384
+
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+
+extern int yyleng;
+extern FILE *yyin, *yyout;
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+/* The funky do-while in the following #define is used to turn the definition
+ * int a single C statement (which needs a semi-colon terminator).  This
+ * avoids problems with code like:
+ *
+ * 	if ( condition_holds )
+ *		yyless( 5 );
+ *	else
+ *		do_something_else();
+ *
+ * Prior to using the do-while the compiler would get upset at the
+ * "else" because it interpreted the "if" statement as being all
+ * done when it reached the ';' after the yyless() call.
+ */
+
+/* Return all but the first 'n' matched characters back to the input stream. */
+
+#define yyless(n) \
+	do \
+		{ \
+		/* Undo effects of setting up yytext. */ \
+		*yy_cp = yy_hold_char; \
+		YY_RESTORE_YY_MORE_OFFSET \
+		yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \
+		YY_DO_BEFORE_ACTION; /* set up yytext again */ \
+		} \
+	while ( 0 )
+
+#define unput(c) yyunput( c, yytext_ptr )
+
+/* The following is because we cannot portably get our hands on size_t
+ * (without autoconf's help, which isn't available because we want
+ * flex-generated scanners to compile on their own).
+ */
+typedef unsigned int yy_size_t;
+
+
+struct yy_buffer_state
+	{
+	FILE *yy_input_file;
+
+	char *yy_ch_buf;		/* input buffer */
+	char *yy_buf_pos;		/* current position in input buffer */
+
+	/* Size of input buffer in bytes, not including room for EOB
+	 * characters.
+	 */
+	yy_size_t yy_buf_size;
+
+	/* Number of characters read into yy_ch_buf, not including EOB
+	 * characters.
+	 */
+	int yy_n_chars;
+
+	/* Whether we "own" the buffer - i.e., we know we created it,
+	 * and can realloc() it to grow it, and should free() it to
+	 * delete it.
+	 */
+	int yy_is_our_buffer;
+
+	/* Whether this is an "interactive" input source; if so, and
+	 * if we're using stdio for input, then we want to use getc()
+	 * instead of fread(), to make sure we stop fetching input after
+	 * each newline.
+	 */
+	int yy_is_interactive;
+
+	/* Whether we're considered to be at the beginning of a line.
+	 * If so, '^' rules will be active on the next match, otherwise
+	 * not.
+	 */
+	int yy_at_bol;
+
+	/* Whether to try to fill the input buffer when we reach the
+	 * end of it.
+	 */
+	int yy_fill_buffer;
+
+	int yy_buffer_status;
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+	/* When an EOF's been seen but there's still some text to process
+	 * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+	 * shouldn't try reading from the input source any more.  We might
+	 * still have a bunch of tokens to match, though, because of
+	 * possible backing-up.
+	 *
+	 * When we actually see the EOF, we change the status to "new"
+	 * (via yyrestart()), so that the user can continue scanning by
+	 * just pointing yyin at a new input file.
+	 */
+#define YY_BUFFER_EOF_PENDING 2
+	};
+
+static YY_BUFFER_STATE yy_current_buffer = 0;
+
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state".
+ */
+#define YY_CURRENT_BUFFER yy_current_buffer
+
+
+/* yy_hold_char holds the character lost when yytext is formed. */
+static char yy_hold_char;
+
+static int yy_n_chars;		/* number of characters read into yy_ch_buf */
+
+
+int yyleng;
+
+/* Points to current character in buffer. */
+static char *yy_c_buf_p = (char *) 0;
+static int yy_init = 1;		/* whether we need to initialize */
+static int yy_start = 0;	/* start state number */
+
+/* Flag which is used to allow yywrap()'s to do buffer switches
+ * instead of setting up a fresh yyin.  A bit of a hack ...
+ */
+static int yy_did_buffer_switch_on_eof;
+
+void yyrestart YY_PROTO(( FILE *input_file ));
+
+void yy_switch_to_buffer YY_PROTO(( YY_BUFFER_STATE new_buffer ));
+void yy_load_buffer_state YY_PROTO(( void ));
+YY_BUFFER_STATE yy_create_buffer YY_PROTO(( FILE *file, int size ));
+void yy_delete_buffer YY_PROTO(( YY_BUFFER_STATE b ));
+void yy_init_buffer YY_PROTO(( YY_BUFFER_STATE b, FILE *file ));
+void yy_flush_buffer YY_PROTO(( YY_BUFFER_STATE b ));
+#define YY_FLUSH_BUFFER yy_flush_buffer( yy_current_buffer )
+
+YY_BUFFER_STATE yy_scan_buffer YY_PROTO(( char *base, yy_size_t size ));
+YY_BUFFER_STATE yy_scan_string YY_PROTO(( yyconst char *yy_str ));
+YY_BUFFER_STATE yy_scan_bytes YY_PROTO(( yyconst char *bytes, int len ));
+
+static void *yy_flex_alloc YY_PROTO(( yy_size_t ));
+static void *yy_flex_realloc YY_PROTO(( void *, yy_size_t ));
+static void yy_flex_free YY_PROTO(( void * ));
+
+#define yy_new_buffer yy_create_buffer
+
+#define yy_set_interactive(is_interactive) \
+	{ \
+	if ( ! yy_current_buffer ) \
+		yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
+	yy_current_buffer->yy_is_interactive = is_interactive; \
+	}
+
+#define yy_set_bol(at_bol) \
+	{ \
+	if ( ! yy_current_buffer ) \
+		yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
+	yy_current_buffer->yy_at_bol = at_bol; \
+	}
+
+#define YY_AT_BOL() (yy_current_buffer->yy_at_bol)
+
+typedef unsigned char YY_CHAR;
+FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;
+typedef int yy_state_type;
+extern char *yytext;
+#define yytext_ptr yytext
+
+static yy_state_type yy_get_previous_state YY_PROTO(( void ));
+static yy_state_type yy_try_NUL_trans YY_PROTO(( yy_state_type current_state ));
+static int yy_get_next_buffer YY_PROTO(( void ));
+static void yy_fatal_error YY_PROTO(( yyconst char msg[] ));
+
+/* Done after the current pattern has been matched and before the
+ * corresponding action - sets up yytext.
+ */
+#define YY_DO_BEFORE_ACTION \
+	yytext_ptr = yy_bp; \
+	yytext_ptr -= yy_more_len; \
+	yyleng = (int) (yy_cp - yytext_ptr); \
+	yy_hold_char = *yy_cp; \
+	*yy_cp = '\0'; \
+	yy_c_buf_p = yy_cp;
+
+#define YY_NUM_RULES 96
+#define YY_END_OF_BUFFER 97
+static yyconst short int yy_accept[485] =
+    {   0,
+        0,    0,    0,    0,   28,   28,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,   49,   49,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,   97,   95,
+        1,   92,   93,    2,   94,   95,   95,   95,   95,   95,
+       95,   95,   95,   95,   20,   19,   20,   20,   20,   20,
+       20,   20,   20,   20,   29,   28,   27,   29,   29,   29,
+       29,   29,   29,   29,   29,   96,   30,   96,   96,   96,
+       39,   32,   36,   33,   34,   38,   35,   43,   43,   96,
+       43,   43,   43,   43,   43,   43,   42,   47,   46,   47,
+
+       45,   49,   51,   48,   50,   63,   62,   53,   58,   59,
+       63,   60,   61,   63,   56,   57,   83,   82,   75,   78,
+       79,   83,   80,   81,   76,   77,   88,   87,   84,   88,
+       73,   72,   70,   73,   91,   90,   91,   66,   65,   64,
+       69,   68,   67,    0,    1,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,   28,   28,    0,    0,    0,    0,    0,
+        0,    0,    0,   30,    0,   31,    0,    0,   37,    0,
+        0,    0,    0,    0,    0,    0,   42,    0,    0,    0,
+        0,    0,   42,   42,   44,   49,   52,    0,   74,   86,
+
+       85,   71,   89,    0,    1,    1,    0,    1,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,   14,   13,
+        0,    0,    0,    0,    0,    0,   28,   28,   28,   28,
+       22,   21,    0,    0,    0,    0,    0,    0,   37,   37,
+        0,    0,    0,   41,    0,   42,    0,    0,    0,    0,
+        0,   52,    0,   74,    0,    0,    0,    1,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,   14,   13,
+       13,    0,    0,    0,    0,    0,    0,    0,   28,   22,
+       21,   21,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,   41,    0,    0,   40,    0,   41,    0,    0,    0,
+
+       10,   11,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,   13,    0,    0,    0,    0,   16,    0,
+       17,    0,   15,   21,    0,    0,    0,    0,   23,    0,
+       25,    0,   24,    0,    0,   40,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,    8,    8,    7,    0,    0,
+        5,    0,    0,    0,    0,   12,    0,    0,    0,   18,
+        0,    0,    0,   26,    0,    0,    0,    0,    0,   55,
+        0,    0,    8,    8,    0,    9,    0,    0,    3,    0,
+        0,    8,    8,    8,    5,    5,    0,    0,   12,   12,
+       12,    0,    0,    0,    0,    0,    0,    8,    8,    8,
+
+        0,    3,    3,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,    6,    0,    0,   12,    0,    0,    0,    0,    0,
+        0,   54,    0,    0,    0,    0,    0,    4,    0,    0,
+        6,    6,   12,   12,   12,    0,    0,    0,    0,    0,
+        0,    0,    4,    4,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,    0
+    } ;
+
+static yyconst int yy_ec[256] =
+    {   0,
+        1,    1,    1,    1,    1,    1,    1,    1,    2,    3,
+        1,    1,    4,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    5,    6,    7,    8,    9,   10,   11,   12,   13,
+       14,   15,   11,   16,   11,   10,   17,   18,   18,   18,
+       18,   18,   18,   18,   18,   18,   18,   19,   20,   11,
+       21,   11,   11,   12,   22,   23,   22,   22,   22,   22,
+       22,   24,   25,   22,   22,   26,   22,   22,   22,   22,
+       22,   22,   22,   22,   22,   22,   22,   22,   22,   22,
+       27,   28,   29,   30,   31,   11,   32,   22,   33,   34,
+
+       35,   36,   37,   22,   38,   22,   22,   39,   40,   41,
+       42,   43,   22,   44,   45,   46,   47,   48,   22,   49,
+       50,   22,   51,   11,   52,   11,    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,    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
+    } ;
+
+static yyconst int yy_meta[53] =
+    {   0,
+        1,    2,    3,    4,    2,    1,    5,    6,    1,    5,
+        1,    7,    8,    9,    5,   10,    5,   11,    5,    1,
+        1,    7,    7,    7,    7,    7,    1,    1,    1,    5,
+        7,    7,    7,    7,    7,    7,    7,    7,    7,    7,
+        7,    7,    7,    7,    7,    7,    7,    7,    7,    7,
+        4,    1
+    } ;
+
+static yyconst short int yy_base[533] =
+    {   0,
+        0,   47,    6,   93,  140,  187,  235,  287,  339,  391,
+        5,   11,  443,    0,    9,   12,   63,   69,  493,  543,
+        0,    0,  593,  643,   72,   80,   81,   90,   26,   31,
+       24,   52,   54,   95,    0,    0,    0,    0, 1250, 2200,
+     1202, 2200, 2200, 1226, 2200, 1213, 1221, 1183, 1164, 1170,
+     1162, 1105, 1106, 1114, 2200, 2200, 1131,   61, 1115, 1105,
+     1100, 1108, 1117, 1096, 2200,   84, 2200, 1121,   95, 1105,
+     1095, 1091, 1098, 1100, 1073, 2200, 2200, 1109, 1099, 1101,
+     2200, 2200, 2200, 2200, 2200, 1083, 2200, 2200,  694,    0,
+        0,  125,  745,  144,  151,  157, 2200, 2200, 2200, 1048,
+
+     2200,   99, 2200, 2200, 2200, 2200, 2200, 2200, 2200, 2200,
+     1080, 2200, 2200, 1052, 2200, 2200, 2200, 2200, 2200, 2200,
+     2200, 1073, 2200, 2200, 2200, 2200, 2200, 2200, 2200,    4,
+     2200, 2200, 2200,   14, 2200, 2200, 1071, 2200, 2200, 2200,
+     2200, 2200, 2200, 1041, 1066, 1056, 1071, 1029, 1042, 1032,
+     1024, 1033, 1024, 1002,  163, 1039, 1027,  984,  992,  983,
+      976,  986,  966,  111,  796,  985,  972,  941,  945,  936,
+      874,  894,  874, 2200,  908, 2200,  900,  906,  895,    0,
+        0,  172,    0,  179,  191,  207, 2200,  904,  903,  219,
+      902,   74,  847,  198, 2200,  119,    0,  866,    0, 2200,
+
+     2200, 2200, 2200,  865,    0,  889,  213,    0,  869,  760,
+      757,  659,  645,  263,  645,  245,   82,  672,    0,  671,
+      651,  643,  274,  639,  132,  650,  665,  651,  649,  642,
+        0,  632,  612,  601,  278,  593,  133,  601,    0,  611,
+      318,  324,  330,    0,  375,  612,    0,    0,  381,    0,
+      609,    0,  578,    0,  576,  349,  594,    0,  562,  555,
+      368,  161,  559,  404,  509,  547,  548,  547,    0,    0,
+      560,  538,  500,  412,  522,  536,  422,  564,    0,    0,
+        0,  551,  530,  550,  530,  559,  527,  571,  553,  586,
+      610, 2200,  622,  628,    0,  307, 2200,  536,  226,  214,
+
+     2200, 2200,  507,  509,  600,  660,  577,  514,  898,  918,
+      495,  491,  500,  501,  475,  637,  969,  975, 2200,  473,
+     2200,  502, 2200,  491,  459,  650,  981,  990, 2200,  457,
+     2200,  491, 2200,  996, 1001,    0,  646, 1051, 1010, 1101,
+     1005,  453,  406, 1014, 1151,  121, 2200, 2200,  433,  432,
+        0,  431,  430,  390,  396, 1203,  384, 1022,  381, 2200,
+      369, 1055,  362, 2200, 1029,  227,  370,  270,  526, 2200,
+      269,    0,  287, 2200,  349, 2200,  380,  358,    0,  357,
+      350,  288,  318,  343, 2200,  348, 1046,  312,    0, 1255,
+      311,  274, 1068,  254, 1089, 1093, 1076,  345,  403,  405,
+
+     1223, 2200,  290, 1118, 1124,  241, 1231, 1216, 1244, 1237,
+     1275, 1287, 1110,  101, 1307, 1293, 1314, 1344, 1334, 1351,
+     1364, 1374, 1394,  254, 1445, 1449, 1455, 1469, 1475, 1481,
+      662, 1300,  238,    0,  239, 1313,  154, 1490, 1510,  245,
+      200,    0,  199,  192, 1562, 1590, 1596, 1591,  605,  214,
+     1035, 2200, 1610, 1332, 1607,  190,  184,    0,  143,  137,
+     2200,  126,    0, 1641,  103, 1622,  155, 1692, 1655, 1673,
+     1722, 1712, 2200,  104, 1618,    0,   91, 1685,  220, 1728,
+      656,  230, 1734, 2200, 1765, 1776, 1787, 1798, 1809, 1820,
+     1831, 1842, 1853, 1864, 1875, 1886, 1897, 1908, 1919, 1926,
+
+     1933, 1944, 1955, 1966, 1977, 1988, 1999, 2010, 2021, 2032,
+     2042, 2048, 2054, 2064, 2065, 2076,   92, 2081, 2092, 2102,
+     2112, 2118, 2124, 2129,   51, 2140, 2150, 2160, 2167, 2177,
+     2183, 2188
+    } ;
+
+static yyconst short int yy_def[533] =
+    {   0,
+      485,  485,  486,  486,  487,  487,  488,  488,  489,  489,
+      490,  490,  484,   13,  491,  491,  492,  492,  493,  493,
+      492,  492,  494,  494,  495,  495,  496,  496,  497,  497,
+      498,  498,  499,  499,  492,  492,  492,  492,  484,  484,
+      484,  484,  484,  484,  484,  484,  484,  484,  484,  484,
+      484,  484,  484,  484,  484,  484,  484,  484,  484,  484,
+      484,  484,  484,  484,  484,  484,  484,  484,  484,  484,
+      484,  484,  484,  484,  484,  484,  484,  500,  484,  501,
+      484,  484,  484,  484,  484,  484,  484,  484,  484,   89,
+       89,   89,  484,   89,   89,   89,  484,  484,  484,  484,
+
+      484,  484,  484,  484,  484,  484,  484,  484,  484,  484,
+      484,  484,  484,  484,  484,  484,  484,  484,  484,  484,
+      484,  484,  484,  484,  484,  484,  484,  484,  484,  484,
+      484,  484,  484,  484,  484,  484,  484,  484,  484,  484,
+      484,  484,  484,  484,  502,  484,  484,  484,  484,  484,
+      484,  484,  484,  484,  484,  484,  484,  484,  484,  484,
+      484,  484,  484,  484,  484,  484,  484,  484,  484,  484,
+      484,  484,  484,  484,  500,  484,  484,  501,  503,   89,
+       89,   89,   93,   89,   89,   89,  484,   93,   93,   93,
+       93,   93,  484,   89,  484,  484,  504,  484,  505,  484,
+
+      484,  484,  484,  484,  502,  502,  484,  506,  484,  484,
+      484,  484,  484,  484,  484,  484,  484,  484,  507,  508,
+      484,  484,  484,  484,  484,  484,  165,  165,  165,  165,
+      509,  510,  484,  484,  484,  484,  484,  484,  503,  503,
+       89,   93,   93,  193,   93,   93,  193,  193,  484,  193,
+      193,  504,  484,  505,  484,  484,  484,  506,  484,  484,
+      484,  484,  484,  484,  484,  484,  484,  484,  507,  508,
+      508,  484,  484,  484,  484,  484,  484,  484,  165,  509,
+      510,  510,  484,  484,  484,  484,  484,  484,  484,   89,
+       89,  484,   93,   93,  193,  484,  484,  193,  511,  484,
+
+      484,  484,  484,  484,  484,  484,  512,  484,  484,  484,
+      484,  484,  484,  508,  484,  484,  484,  484,  484,  484,
+      484,  484,  484,  510,  484,  484,  484,  484,  484,  484,
+      484,  484,  484,  193,  193,  193,  511,  513,  511,  513,
+      514,  484,  484,  484,  484,  515,  484,  484,  310,  310,
+      310,  310,  310,  484,  484,  516,  484,  484,  484,  484,
+      484,  484,  484,  484,  484,  340,  517,  340,  340,  484,
+      339,  340,  518,  484,  484,  484,  345,  345,  345,  345,
+      345,  515,  515,  515,  484,  310,  484,  484,  519,  516,
+      390,  484,  484,  484,  484,  520,  521,  518,  518,  518,
+
+      484,  484,  345,  484,  484,  484,  484,  484,  484,  484,
+      484,  484,  522,  484,  523,  520,  520,  523,  521,  484,
+      484,  484,  484,  484,  484,  484,  484,  484,  484,  484,
+      524,  484,  525,  418,  484,  417,  417,  484,  484,  423,
+      423,  423,  423,  423,  526,  484,  484,  524,  484,  484,
+      484,  484,  527,  528,  524,  439,  439,  439,  439,  439,
+      484,  423,  529,  526,  464,  530,  484,  531,  527,  527,
+      531,  528,  484,  439,  532,  471,  484,  470,  470,  532,
+      484,  484,  532,    0,  484,  484,  484,  484,  484,  484,
+      484,  484,  484,  484,  484,  484,  484,  484,  484,  484,
+
+      484,  484,  484,  484,  484,  484,  484,  484,  484,  484,
+      484,  484,  484,  484,  484,  484,  484,  484,  484,  484,
+      484,  484,  484,  484,  484,  484,  484,  484,  484,  484,
+      484,  484
+    } ;
+
+static yyconst short int yy_nxt[2253] =
+    {   0,
+      484,   41,   42,   43,   41,  484,   82,   83,   56,   82,
+      200,   99,   82,   83,   99,   82,   44,   84,   85,   45,
+      202,   86,   57,   84,   85,   46,  139,   86,  136,   47,
+      140,  201,   48,  136,   49,   58,  100,   50,   59,  100,
+      137,  202,   51,   60,   52,  137,   53,   54,   41,   42,
+       43,   41,   61,   62,  139,   87,  142,  453,  140,  101,
+      143,   87,  101,   44,  102,  103,   45,  102,  156,  104,
+      102,  103,   46,  102,  128,  104,   47,  157,  129,   48,
+      245,   49,  128,  132,   50,  164,  129,  133,  164,   51,
+      217,   52,  132,   53,   54,   56,  133,  142,  396,  130,
+
+      196,  143,  166,  196,  483,  267,  268,  130,  134,   57,
+      473,  167,  164,  105,  432,  164,  433,  134,   63,  105,
+      196,  465,   58,  196,  246,   59,  182,  185,  185,  182,
+       60,  185,  461,  277,  288,   64,  277,  288,  383,   61,
+       62,   66,   67,  474,   66,  182,  185,  185,  182,  473,
+      185,  384,  182,  185,  185,  182,   68,  185,  182,  185,
+      185,  182,  307,  185,  216,  307,  435,  216,  432,   69,
+      433,  217,   70,  182,  185,  185,  182,   71,  185,  218,
+      182,  185,  185,  182,  437,  185,   72,   73,   66,   67,
+      473,   66,  182,  185,  185,  182,  473,  185,  462,  182,
+
+      185,  185,  182,   68,  185,  461,  461,  194,  182,  185,
+      185,  182,   74,  185,  256,  341,   69,  256,  341,   70,
+      242,  243,  243,  242,   71,  257,  435,  337,  365,   75,
+      337,  365,  477,   72,   73,   76,   76,   76,   76,   76,
+       76,   77,  477,   76,  450,   76,  216,   76,   76,  216,
+      479,  461,  455,  217,   76,   76,  339,  194,  340,  366,
+      482,   76,   76,   76,  264,  264,  264,  264,  454,  244,
+      371,  365,  445,  371,  365,  274,  274,  274,  274,  285,
+      285,  285,  285,  265,  424,   76,   76,   76,   76,   76,
+       76,   76,   76,   77,  275,   76,  402,   76,  286,   76,
+
+       76,  214,  366,  410,  399,  383,   76,   76,  296,  296,
+      296,  296,  223,   76,   76,   76,  235,  400,  384,  290,
+      291,  291,  290,  407,  241,  242,  243,  243,  242,  391,
+      241,  242,  243,  243,  242,  383,  241,   76,   76,   76,
+       76,   76,   76,   76,   76,   79,  406,   76,  384,   76,
+      256,   76,   76,  256,  385,  301,  403,  297,   76,   76,
+      383,  257,  399,  402,  402,   76,   76,   76,  292,  305,
+      305,  305,  305,  384,  244,  400,  293,  294,  294,  293,
+      244,  241,  296,  296,  296,  296,  402,  249,  306,   76,
+       76,   76,   76,   76,   76,   76,   76,   79,  401,   76,
+
+      397,   76,  395,   76,   76,  264,  264,  264,  264,  261,
+       76,   76,  394,  274,  274,  274,  274,   76,   76,   76,
+      399,  393,  399,  277,  265,  295,  277,  392,  321,  388,
+      387,  297,  275,  400,  322,  400,  386,  385,  385,  385,
+      376,   76,   76,   88,   89,   90,   91,   89,   92,   93,
+       92,   94,   92,   92,   94,   92,   92,   92,   92,   92,
+       94,   92,   92,   92,   95,   95,   95,   95,   95,   92,
+       96,   92,   92,   92,   95,   95,   95,   95,   95,   95,
+       95,   95,   95,   95,   95,   95,   95,   95,   95,   95,
+       95,   95,   95,   97,   92,  107,  375,  364,  363,  108,
+
+      361,  316,  316,  316,  316,  109,  110,  282,  360,  111,
+      309,  309,  309,  309,  359,  310,  357,  271,  356,  112,
+      317,  113,  355,  318,  318,  318,  318,  365,  319,  265,
+      365,  285,  285,  285,  285,  114,  354,  334,  335,  335,
+      334,  273,  275,  115,  116,  107,  348,  343,  342,  108,
+      286,  326,  326,  326,  326,  109,  110,  333,  366,  111,
+      328,  328,  328,  328,  330,  329,  325,  324,  323,  112,
+      327,  113,  288,  320,  315,  288,  314,  331,  307,  286,
+      313,  307,  312,  332,  311,  114,  336,  290,  291,  291,
+      290,  284,  185,  115,  116,  118,  308,  304,  303,  119,
+
+      302,  305,  305,  305,  305,  120,  121,  347,  300,  122,
+      299,  290,  291,  291,  290,  298,  185,  435,  241,  123,
+      306,  124,  449,  293,  294,  294,  293,  240,  241,  293,
+      294,  294,  293,  289,  241,  450,  292,  287,  316,  316,
+      316,  316,  284,  125,  126,  118,  283,  337,  282,  119,
+      337,  326,  326,  326,  326,  120,  121,  317,  279,  122,
+      292,  344,  344,  344,  344,  227,  345,  227,  477,  123,
+      327,  124,  295,  481,  435,  432,  339,  433,  295,  449,
+      306,  227,  278,  276,  273,  272,  482,  271,  155,  266,
+      263,  262,  450,  125,  126,  180,  181,  181,  180,  182,
+
+      183,  182,  184,  182,  182,  184,  182,  182,  182,  182,
+      182,  184,  182,  182,  182,  185,  185,  185,  185,  185,
+      182,  186,  182,  182,  182,  185,  185,  185,  185,  185,
+      185,  185,  185,  185,  185,  185,  185,  185,  185,  185,
+      185,  185,  185,  185,  187,  182,  188,  189,  189,  188,
+      188,  190,  188,  191,  188,  188,  191,  188,  188,  188,
+      188,  188,  191,  188,  188,  188,  189,  189,  189,  189,
+      189,  188,  192,  188,  188,  188,  189,  189,  189,  189,
+      189,  189,  189,  189,  189,  189,  189,  189,  189,  189,
+      189,  189,  189,  189,  189,  193,  188,  227,  261,  260,
+
+      227,  227,  228,  227,  229,  227,  227,  229,  227,  227,
+      227,  227,  230,  229,  227,  227,  227,  228,  228,  228,
+      228,  228,  227,  227,  227,  227,  227,  228,  228,  228,
+      228,  228,  228,  228,  228,  228,  228,  228,  228,  228,
+      228,  228,  228,  228,  228,  228,  227,  227,  247,  248,
+      248,  247,  247,  249,  247,  250,  247,  247,  250,  247,
+      247,  247,  247,  247,  250,  247,  247,  247,  248,  248,
+      248,  248,  248,  247,  251,  247,  247,  247,  248,  248,
+      248,  248,  248,  248,  248,  248,  248,  248,  248,  248,
+      248,  248,  248,  248,  248,  248,  248,  247,  247,  309,
+
+      309,  309,  309,  259,  310,  206,  255,  253,  241,  241,
+      241,  240,  177,  176,  174,  238,  237,  236,  265,  349,
+      350,  350,  349,  349,  351,  349,  352,  349,  349,  352,
+      349,  349,  349,  349,  349,  352,  349,  349,  349,  350,
+      350,  350,  350,  350,  349,  353,  349,  349,  349,  350,
+      350,  350,  350,  350,  350,  350,  350,  350,  350,  350,
+      350,  350,  350,  350,  350,  350,  350,  350,  349,  349,
+      358,  358,  358,  358,  235,  319,  318,  318,  318,  318,
+      234,  319,  362,  362,  362,  362,  233,  329,  232,  317,
+      231,  328,  328,  328,  328,  275,  329,  334,  335,  335,
+
+      334,  327,  334,  335,  335,  334,  341,  226,  225,  341,
+      286,  365,  365,  365,  365,  344,  344,  344,  344,  224,
+      345,  223,  367,  358,  358,  358,  358,  222,  319,  221,
+      365,  365,  365,  365,  306,  374,  451,  451,  451,  451,
+      339,  367,  317,  220,  219,  215,  336,  404,  404,  404,
+      404,  336,  365,  365,  365,  365,  362,  362,  362,  362,
+      370,  329,  214,  367,  213,  212,  405,  211,  368,  408,
+      408,  408,  408,  210,  209,  327,  208,  413,  207,  370,
+      413,  369,  206,  414,  204,  452,  387,  203,  409,  199,
+      411,  411,  411,  411,  413,  198,  197,  413,  195,  179,
+
+      414,  370,  371,  365,  365,  371,  419,  177,  393,  412,
+      416,  413,  176,  367,  413,  174,  173,  414,  368,  404,
+      404,  404,  404,  417,  172,  422,  422,  422,  422,  395,
+      423,  369,  171,  372,  170,  169,  168,  165,  405,  163,
+      414,  162,  161,  160,  405,  159,  158,  155,  154,  153,
+      152,  370,  377,  378,  378,  377,  377,  379,  377,  380,
+      377,  377,  380,  377,  377,  377,  377,  377,  380,  377,
+      377,  377,  378,  378,  378,  378,  378,  377,  381,  377,
+      377,  377,  378,  378,  378,  378,  378,  378,  378,  378,
+      378,  378,  378,  378,  378,  378,  378,  378,  378,  378,
+
+      378,  377,  377,  389,  389,  151,  389,  389,  389,  389,
+      150,  389,  149,  389,  148,  389,  389,  408,  408,  408,
+      408,  391,  389,  389,  420,  420,  420,  420,  147,  389,
+      389,  389,  425,  425,  425,  425,  409,  146,  428,  428,
+      428,  428,  145,  421,  144,  427,  427,  427,  427,  484,
+      319,  426,  484,  389,  389,  389,  389,  429,  389,  389,
+      389,  389,  484,  389,  409,  389,  484,  389,  389,  484,
+      484,  484,  401,  484,  389,  389,  411,  411,  411,  411,
+      407,  389,  389,  389,  484,  484,  410,  484,  430,  430,
+      430,  430,  484,  329,  413,  412,  484,  413,  484,  484,
+
+      414,  451,  451,  451,  451,  389,  389,  412,  413,  484,
+      416,  413,  367,  484,  414,  413,  484,  484,  413,  435,
+      432,  414,  433,  417,  436,  435,  484,  432,  484,  433,
+      436,  416,  484,  466,  484,  413,  466,  437,  413,  467,
+      484,  414,  484,  437,  417,  413,  484,  432,  413,  433,
+      452,  414,  420,  420,  420,  420,  435,  432,  484,  433,
+      484,  436,  472,  484,  419,  438,  438,  438,  438,  484,
+      439,  421,  484,  484,  437,  422,  422,  422,  422,  484,
+      423,  484,  484,  484,  421,  484,  484,  484,  484,  484,
+      484,  484,  484,  484,  405,  440,  441,  441,  440,  440,
+
+      442,  440,  443,  440,  440,  443,  440,  440,  440,  440,
+      440,  443,  440,  440,  440,  441,  441,  441,  441,  441,
+      440,  444,  440,  440,  440,  441,  441,  441,  441,  441,
+      441,  441,  441,  441,  441,  441,  441,  441,  441,  441,
+      441,  441,  441,  441,  440,  440,  425,  425,  425,  425,
+      446,  446,  446,  446,  484,  319,  427,  427,  427,  427,
+      484,  319,  484,  484,  484,  426,  484,  484,  484,  426,
+      428,  428,  428,  428,  484,  409,  447,  447,  447,  447,
+      484,  329,  430,  430,  430,  430,  484,  329,  484,  429,
+      484,  438,  438,  438,  438,  429,  439,  484,  484,  484,
+
+      484,  412,  484,  484,  484,  484,  484,  484,  484,  484,
+      421,  456,  457,  457,  456,  456,  458,  456,  459,  456,
+      456,  459,  456,  456,  456,  456,  456,  459,  456,  456,
+      456,  457,  457,  457,  457,  457,  456,  460,  456,  456,
+      456,  457,  457,  457,  457,  457,  457,  457,  457,  457,
+      457,  457,  457,  457,  457,  457,  457,  457,  457,  457,
+      456,  456,  463,  463,  484,  463,  463,  463,  463,  484,
+      463,  484,  463,  484,  463,  463,  484,  484,  484,  484,
+      465,  463,  463,  484,  484,  484,  484,  484,  463,  463,
+      463,  446,  446,  446,  446,  484,  319,  447,  447,  447,
+
+      447,  484,  329,  435,  484,  484,  484,  484,  449,  484,
+      426,  466,  463,  463,  466,  484,  429,  467,  484,  435,
+      432,  450,  433,  466,  449,  484,  466,  469,  484,  467,
+      477,  432,  484,  433,  484,  481,  484,  450,  484,  484,
+      470,  463,  463,  484,  463,  463,  463,  463,  482,  463,
+      484,  463,  467,  463,  463,  484,  466,  484,  484,  466,
+      463,  463,  467,  484,  484,  484,  484,  463,  463,  463,
+      484,  484,  469,  484,  466,  484,  484,  466,  484,  484,
+      467,  484,  484,  484,  484,  470,  432,  484,  433,  484,
+      469,  463,  463,  466,  484,  484,  466,  477,  484,  467,
+
+      484,  484,  478,  470,  477,  432,  484,  433,  484,  478,
+      484,  484,  484,  466,  484,  479,  466,  484,  484,  467,
+      484,  484,  479,  466,  484,  432,  466,  433,  484,  467,
+      484,  484,  484,  484,  477,  432,  484,  433,  484,  478,
+      477,  484,  472,  484,  484,  481,  477,  432,  484,  433,
+      484,  481,  479,  484,  484,  484,  484,  484,  482,  484,
+      484,  484,  484,  484,  482,   40,   40,   40,   40,   40,
+       40,   40,   40,   40,   40,   40,   55,   55,   55,   55,
+       55,   55,   55,   55,   55,   55,   55,   65,   65,   65,
+       65,   65,   65,   65,   65,   65,   65,   65,   78,   78,
+
+       78,   78,   78,   78,   78,   78,   78,   78,   78,   80,
+       80,   80,   80,   80,   80,   80,   80,   80,   80,   80,
+       81,   81,   81,   81,   81,   81,   81,   81,   81,   81,
+       81,   98,   98,   98,   98,   98,   98,   98,   98,   98,
+       98,   98,   76,   76,   76,   76,   76,   76,   76,   76,
+       76,   76,   76,  106,  106,  106,  106,  106,  106,  106,
+      106,  106,  106,  106,  117,  117,  117,  117,  117,  117,
+      117,  117,  117,  117,  117,  127,  127,  127,  127,  127,
+      127,  127,  127,  127,  127,  127,  131,  131,  131,  131,
+      131,  131,  131,  131,  131,  131,  131,  135,  135,  135,
+
+      135,  135,  135,  135,  135,  135,  135,  135,  138,  138,
+      138,  138,  138,  138,  138,  138,  138,  138,  138,  141,
+      141,  141,  141,  141,  141,  141,  141,  141,  141,  141,
+      175,  175,  175,  484,  484,  175,  175,  178,  178,  178,
+      484,  484,  178,  178,  205,  205,  484,  205,  205,  205,
+      205,  205,  205,  205,  205,  239,  239,  484,  239,  239,
+      239,  239,  239,  239,  239,  239,  252,  252,  484,  252,
+      252,  252,  252,  252,  252,  252,  252,  254,  254,  484,
+      254,  254,  254,  254,  254,  254,  254,  254,  258,  258,
+      484,  258,  258,  258,  258,  258,  258,  258,  258,  269,
+
+      269,  484,  269,  269,  269,  269,  269,  269,  269,  269,
+      270,  270,  484,  270,  270,  270,  270,  270,  270,  270,
+      270,  280,  280,  484,  280,  280,  280,  280,  280,  280,
+      280,  280,  281,  281,  484,  281,  281,  281,  281,  281,
+      281,  281,  281,  338,  484,  484,  484,  484,  338,  346,
+      484,  484,  484,  484,  346,  366,  366,  366,  484,  484,
+      366,  366,  484,  484,  366,  373,  484,  484,  484,  484,
+      373,  382,  484,  484,  484,  382,  390,  390,  484,  390,
+      390,  390,  390,  390,  390,  390,  390,  398,  484,  484,
+      484,  398,  389,  389,  484,  389,  389,  389,  389,  389,
+
+      389,  389,  389,  415,  484,  484,  484,  415,  415,  484,
+      484,  484,  415,  418,  484,  484,  484,  418,  418,  431,
+      484,  484,  484,  431,  431,  434,  484,  484,  484,  434,
+      434,  434,  434,  434,  434,  448,  448,  448,  448,  448,
+      464,  464,  484,  464,  464,  464,  464,  464,  464,  464,
+      464,  468,  484,  484,  484,  468,  468,  484,  484,  484,
+      468,  471,  484,  484,  484,  471,  471,  463,  463,  484,
+      463,  463,  463,  463,  463,  463,  463,  463,  475,  484,
+      484,  484,  475,  475,  476,  484,  484,  484,  476,  476,
+      476,  476,  476,  476,  480,  480,  480,  480,  480,   39,
+
+      484,  484,  484,  484,  484,  484,  484,  484,  484,  484,
+      484,  484,  484,  484,  484,  484,  484,  484,  484,  484,
+      484,  484,  484,  484,  484,  484,  484,  484,  484,  484,
+      484,  484,  484,  484,  484,  484,  484,  484,  484,  484,
+      484,  484,  484,  484,  484,  484,  484,  484,  484,  484,
+      484,  484
+    } ;
+
+static yyconst short int yy_chk[2253] =
+    {   0,
+        0,    1,    1,    1,    1,    0,   11,   11,    3,   11,
+      130,   15,   12,   12,   16,   12,    1,   11,   11,    1,
+      134,   11,    3,   12,   12,    1,   31,   12,   29,    1,
+       31,  130,    1,   30,    1,    3,   15,    1,    3,   16,
+       29,  134,    1,    3,    1,   30,    1,    1,    2,    2,
+        2,    2,    3,    3,   32,   11,   33,  525,   32,   15,
+       33,   12,   16,    2,   17,   17,    2,   17,   58,   17,
+       18,   18,    2,   18,   25,   18,    2,   58,   25,    2,
+      192,    2,   26,   27,    2,   66,   26,   27,   66,    2,
+      217,    2,   28,    2,    2,    4,   28,   34,  517,   25,
+
+      102,   34,   69,  102,  477,  217,  217,   26,   27,    4,
+      474,   69,  164,   17,  414,  164,  414,   28,    4,   18,
+      196,  465,    4,  196,  192,    4,   92,   92,   92,   92,
+        4,   92,  462,  225,  237,    4,  225,  237,  346,    4,
+        4,    5,    5,  460,    5,   94,   94,   94,   94,  459,
+       94,  346,   95,   95,   95,   95,    5,   95,   96,   96,
+       96,   96,  262,   96,  155,  262,  437,  155,  467,    5,
+      467,  155,    5,  182,  182,  182,  182,    5,  182,  155,
+      184,  184,  184,  184,  437,  184,    5,    5,    6,    6,
+      457,    6,  185,  185,  185,  185,  456,  185,  444,  194,
+
+      194,  194,  194,    6,  194,  443,  441,   96,  186,  186,
+      186,  186,    6,  186,  207,  300,    6,  207,  300,    6,
+      190,  190,  190,  190,    6,  207,  450,  299,  366,    6,
+      299,  366,  479,    6,    6,    7,    7,    7,    7,    7,
+        7,    7,  482,    7,  450,    7,  216,    7,    7,  216,
+      479,  440,  435,  216,    7,    7,  299,  186,  299,  366,
+      482,    7,    7,    7,  214,  214,  214,  214,  433,  190,
+      371,  368,  424,  371,  368,  223,  223,  223,  223,  235,
+      235,  235,  235,  214,  406,    7,    7,    8,    8,    8,
+        8,    8,    8,    8,  223,    8,  403,    8,  235,    8,
+
+        8,  214,  368,  394,  373,  382,    8,    8,  296,  296,
+      296,  296,  223,    8,    8,    8,  235,  373,  382,  241,
+      241,  241,  241,  392,  241,  242,  242,  242,  242,  391,
+      242,  243,  243,  243,  243,  383,  243,    8,    8,    9,
+        9,    9,    9,    9,    9,    9,  388,    9,  383,    9,
+      256,    9,    9,  256,  386,  256,  381,  296,    9,    9,
+      384,  256,  398,  380,  378,    9,    9,    9,  241,  261,
+      261,  261,  261,  384,  242,  398,  245,  245,  245,  245,
+      243,  245,  249,  249,  249,  249,  377,  249,  261,    9,
+        9,   10,   10,   10,   10,   10,   10,   10,  375,   10,
+
+      367,   10,  363,   10,   10,  264,  264,  264,  264,  261,
+       10,   10,  361,  274,  274,  274,  274,   10,   10,   10,
+      399,  359,  400,  277,  264,  245,  277,  357,  277,  355,
+      354,  249,  274,  399,  277,  400,  353,  352,  350,  349,
+      343,   10,   10,   13,   13,   13,   13,   13,   13,   13,
+       13,   13,   13,   13,   13,   13,   13,   13,   13,   13,
+       13,   13,   13,   13,   13,   13,   13,   13,   13,   13,
+       13,   13,   13,   13,   13,   13,   13,   13,   13,   13,
+       13,   13,   13,   13,   13,   13,   13,   13,   13,   13,
+       13,   13,   13,   13,   13,   19,  342,  332,  330,   19,
+
+      325,  273,  273,  273,  273,   19,   19,  324,  322,   19,
+      265,  265,  265,  265,  320,  265,  315,  314,  313,   19,
+      273,   19,  312,  275,  275,  275,  275,  369,  275,  265,
+      369,  285,  285,  285,  285,   19,  311,  298,  298,  298,
+      298,  273,  275,   19,   19,   20,  308,  304,  303,   20,
+      285,  284,  284,  284,  284,   20,   20,  289,  369,   20,
+      286,  286,  286,  286,  287,  286,  283,  282,  278,   20,
+      284,   20,  288,  276,  272,  288,  271,  288,  307,  286,
+      268,  307,  267,  288,  266,   20,  298,  290,  290,  290,
+      290,  284,  290,   20,   20,   23,  263,  260,  259,   23,
+
+      257,  305,  305,  305,  305,   23,   23,  307,  255,   23,
+      253,  291,  291,  291,  291,  251,  291,  449,  246,   23,
+      305,   23,  449,  293,  293,  293,  293,  240,  293,  294,
+      294,  294,  294,  238,  294,  449,  290,  236,  316,  316,
+      316,  316,  234,   23,   23,   24,  233,  337,  232,   24,
+      337,  326,  326,  326,  326,   24,   24,  316,  230,   24,
+      291,  306,  306,  306,  306,  229,  306,  228,  481,   24,
+      326,   24,  293,  481,  431,  431,  337,  431,  294,  431,
+      306,  227,  226,  224,  222,  221,  481,  220,  218,  215,
+      213,  212,  431,   24,   24,   89,   89,   89,   89,   89,
+
+       89,   89,   89,   89,   89,   89,   89,   89,   89,   89,
+       89,   89,   89,   89,   89,   89,   89,   89,   89,   89,
+       89,   89,   89,   89,   89,   89,   89,   89,   89,   89,
+       89,   89,   89,   89,   89,   89,   89,   89,   89,   89,
+       89,   89,   89,   89,   89,   89,   93,   93,   93,   93,
+       93,   93,   93,   93,   93,   93,   93,   93,   93,   93,
+       93,   93,   93,   93,   93,   93,   93,   93,   93,   93,
+       93,   93,   93,   93,   93,   93,   93,   93,   93,   93,
+       93,   93,   93,   93,   93,   93,   93,   93,   93,   93,
+       93,   93,   93,   93,   93,   93,   93,  165,  211,  210,
+
+      165,  165,  165,  165,  165,  165,  165,  165,  165,  165,
+      165,  165,  165,  165,  165,  165,  165,  165,  165,  165,
+      165,  165,  165,  165,  165,  165,  165,  165,  165,  165,
+      165,  165,  165,  165,  165,  165,  165,  165,  165,  165,
+      165,  165,  165,  165,  165,  165,  165,  165,  193,  193,
+      193,  193,  193,  193,  193,  193,  193,  193,  193,  193,
+      193,  193,  193,  193,  193,  193,  193,  193,  193,  193,
+      193,  193,  193,  193,  193,  193,  193,  193,  193,  193,
+      193,  193,  193,  193,  193,  193,  193,  193,  193,  193,
+      193,  193,  193,  193,  193,  193,  193,  193,  193,  309,
+
+      309,  309,  309,  209,  309,  206,  204,  198,  191,  189,
+      188,  179,  178,  177,  175,  173,  172,  171,  309,  310,
+      310,  310,  310,  310,  310,  310,  310,  310,  310,  310,
+      310,  310,  310,  310,  310,  310,  310,  310,  310,  310,
+      310,  310,  310,  310,  310,  310,  310,  310,  310,  310,
+      310,  310,  310,  310,  310,  310,  310,  310,  310,  310,
+      310,  310,  310,  310,  310,  310,  310,  310,  310,  310,
+      317,  317,  317,  317,  170,  317,  318,  318,  318,  318,
+      169,  318,  327,  327,  327,  327,  168,  327,  167,  317,
+      166,  328,  328,  328,  328,  318,  328,  334,  334,  334,
+
+      334,  327,  335,  335,  335,  335,  341,  163,  162,  341,
+      328,  339,  339,  339,  339,  344,  344,  344,  344,  161,
+      344,  160,  339,  358,  358,  358,  358,  159,  358,  158,
+      365,  365,  365,  365,  344,  341,  451,  451,  451,  451,
+      339,  365,  358,  157,  156,  154,  334,  387,  387,  387,
+      387,  335,  338,  338,  338,  338,  362,  362,  362,  362,
+      339,  362,  153,  338,  152,  151,  387,  150,  338,  393,
+      393,  393,  393,  149,  148,  362,  147,  397,  146,  365,
+      397,  338,  145,  397,  144,  451,  387,  137,  393,  122,
+      395,  395,  395,  395,  396,  114,  111,  396,  100,   86,
+
+      396,  338,  340,  340,  340,  340,  397,   80,  393,  395,
+      396,  413,   79,  340,  413,   78,   75,  413,  340,  404,
+      404,  404,  404,  396,   74,  405,  405,  405,  405,  395,
+      405,  340,   73,  340,   72,   71,   70,   68,  404,   64,
+      413,   63,   62,   61,  405,   60,   59,   57,   54,   53,
+       52,  340,  345,  345,  345,  345,  345,  345,  345,  345,
+      345,  345,  345,  345,  345,  345,  345,  345,  345,  345,
+      345,  345,  345,  345,  345,  345,  345,  345,  345,  345,
+      345,  345,  345,  345,  345,  345,  345,  345,  345,  345,
+      345,  345,  345,  345,  345,  345,  345,  345,  345,  345,
+
+      345,  345,  345,  356,  356,   51,  356,  356,  356,  356,
+       50,  356,   49,  356,   48,  356,  356,  408,  408,  408,
+      408,  356,  356,  356,  401,  401,  401,  401,   47,  356,
+      356,  356,  407,  407,  407,  407,  408,   46,  410,  410,
+      410,  410,   44,  401,   41,  409,  409,  409,  409,   39,
+      409,  407,    0,  356,  356,  390,  390,  410,  390,  390,
+      390,  390,    0,  390,  409,  390,    0,  390,  390,    0,
+        0,    0,  401,    0,  390,  390,  411,  411,  411,  411,
+      407,  390,  390,  390,    0,    0,  410,    0,  412,  412,
+      412,  412,    0,  412,  416,  411,    0,  416,    0,    0,
+
+      416,  432,  432,  432,  432,  390,  390,  412,  415,    0,
+      416,  415,  432,    0,  415,  417,    0,    0,  417,  415,
+      415,  417,  415,  416,  415,  436,  436,  417,  436,  417,
+      436,  417,    0,  454,    0,  419,  454,  415,  419,  454,
+        0,  419,    0,  436,  417,  418,    0,  419,  418,  419,
+      432,  418,  420,  420,  420,  420,  418,  418,    0,  418,
+        0,  418,  454,    0,  419,  421,  421,  421,  421,    0,
+      421,  420,    0,    0,  418,  422,  422,  422,  422,    0,
+      422,    0,    0,    0,  421,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,  422,  423,  423,  423,  423,  423,
+
+      423,  423,  423,  423,  423,  423,  423,  423,  423,  423,
+      423,  423,  423,  423,  423,  423,  423,  423,  423,  423,
+      423,  423,  423,  423,  423,  423,  423,  423,  423,  423,
+      423,  423,  423,  423,  423,  423,  423,  423,  423,  423,
+      423,  423,  423,  423,  423,  423,  425,  425,  425,  425,
+      426,  426,  426,  426,    0,  426,  427,  427,  427,  427,
+        0,  427,    0,    0,    0,  425,    0,    0,    0,  426,
+      428,  428,  428,  428,    0,  427,  429,  429,  429,  429,
+        0,  429,  430,  430,  430,  430,    0,  430,    0,  428,
+        0,  438,  438,  438,  438,  429,  438,    0,    0,    0,
+
+        0,  430,    0,    0,    0,    0,    0,    0,    0,    0,
+      438,  439,  439,  439,  439,  439,  439,  439,  439,  439,
+      439,  439,  439,  439,  439,  439,  439,  439,  439,  439,
+      439,  439,  439,  439,  439,  439,  439,  439,  439,  439,
+      439,  439,  439,  439,  439,  439,  439,  439,  439,  439,
+      439,  439,  439,  439,  439,  439,  439,  439,  439,  439,
+      439,  439,  445,  445,    0,  445,  445,  445,  445,    0,
+      445,    0,  445,    0,  445,  445,    0,    0,    0,    0,
+      445,  445,  445,    0,    0,    0,    0,    0,  445,  445,
+      445,  446,  446,  446,  446,    0,  446,  447,  447,  447,
+
+      447,    0,  447,  448,  448,    0,  448,    0,  448,    0,
+      446,  453,  445,  445,  453,    0,  447,  453,    0,  455,
+      455,  448,  455,  466,  455,    0,  466,  453,    0,  466,
+      475,  475,    0,  475,    0,  475,    0,  455,    0,    0,
+      453,  464,  464,    0,  464,  464,  464,  464,  475,  464,
+        0,  464,  466,  464,  464,    0,  469,    0,    0,  469,
+      464,  464,  469,    0,    0,    0,    0,  464,  464,  464,
+        0,    0,  469,    0,  470,    0,    0,  470,    0,    0,
+      470,    0,    0,    0,    0,  469,  470,    0,  470,    0,
+      470,  464,  464,  468,    0,    0,  468,  478,  478,  468,
+
+      478,    0,  478,  470,  468,  468,    0,  468,    0,  468,
+        0,    0,    0,  472,    0,  478,  472,    0,    0,  472,
+        0,    0,  468,  471,    0,  472,  471,  472,    0,  471,
+        0,    0,    0,    0,  471,  471,    0,  471,    0,  471,
+      480,  480,  472,  480,    0,  480,  483,  483,    0,  483,
+        0,  483,  471,    0,    0,    0,    0,    0,  480,    0,
+        0,    0,    0,    0,  483,  485,  485,  485,  485,  485,
+      485,  485,  485,  485,  485,  485,  486,  486,  486,  486,
+      486,  486,  486,  486,  486,  486,  486,  487,  487,  487,
+      487,  487,  487,  487,  487,  487,  487,  487,  488,  488,
+
+      488,  488,  488,  488,  488,  488,  488,  488,  488,  489,
+      489,  489,  489,  489,  489,  489,  489,  489,  489,  489,
+      490,  490,  490,  490,  490,  490,  490,  490,  490,  490,
+      490,  491,  491,  491,  491,  491,  491,  491,  491,  491,
+      491,  491,  492,  492,  492,  492,  492,  492,  492,  492,
+      492,  492,  492,  493,  493,  493,  493,  493,  493,  493,
+      493,  493,  493,  493,  494,  494,  494,  494,  494,  494,
+      494,  494,  494,  494,  494,  495,  495,  495,  495,  495,
+      495,  495,  495,  495,  495,  495,  496,  496,  496,  496,
+      496,  496,  496,  496,  496,  496,  496,  497,  497,  497,
+
+      497,  497,  497,  497,  497,  497,  497,  497,  498,  498,
+      498,  498,  498,  498,  498,  498,  498,  498,  498,  499,
+      499,  499,  499,  499,  499,  499,  499,  499,  499,  499,
+      500,  500,  500,    0,    0,  500,  500,  501,  501,  501,
+        0,    0,  501,  501,  502,  502,    0,  502,  502,  502,
+      502,  502,  502,  502,  502,  503,  503,    0,  503,  503,
+      503,  503,  503,  503,  503,  503,  504,  504,    0,  504,
+      504,  504,  504,  504,  504,  504,  504,  505,  505,    0,
+      505,  505,  505,  505,  505,  505,  505,  505,  506,  506,
+        0,  506,  506,  506,  506,  506,  506,  506,  506,  507,
+
+      507,    0,  507,  507,  507,  507,  507,  507,  507,  507,
+      508,  508,    0,  508,  508,  508,  508,  508,  508,  508,
+      508,  509,  509,    0,  509,  509,  509,  509,  509,  509,
+      509,  509,  510,  510,    0,  510,  510,  510,  510,  510,
+      510,  510,  510,  511,    0,    0,    0,    0,  511,  512,
+        0,    0,    0,    0,  512,  513,  513,  513,    0,    0,
+      513,  513,    0,    0,  513,  514,    0,    0,    0,    0,
+      514,  515,    0,    0,    0,  515,  516,  516,    0,  516,
+      516,  516,  516,  516,  516,  516,  516,  518,    0,    0,
+        0,  518,  519,  519,    0,  519,  519,  519,  519,  519,
+
+      519,  519,  519,  520,    0,    0,    0,  520,  520,    0,
+        0,    0,  520,  521,    0,    0,    0,  521,  521,  522,
+        0,    0,    0,  522,  522,  523,    0,    0,    0,  523,
+      523,  523,  523,  523,  523,  524,  524,  524,  524,  524,
+      526,  526,    0,  526,  526,  526,  526,  526,  526,  526,
+      526,  527,    0,    0,    0,  527,  527,    0,    0,    0,
+      527,  528,    0,    0,    0,  528,  528,  529,  529,    0,
+      529,  529,  529,  529,  529,  529,  529,  529,  530,    0,
+        0,    0,  530,  530,  531,    0,    0,    0,  531,  531,
+      531,  531,  531,  531,  532,  532,  532,  532,  532,  484,
+
+      484,  484,  484,  484,  484,  484,  484,  484,  484,  484,
+      484,  484,  484,  484,  484,  484,  484,  484,  484,  484,
+      484,  484,  484,  484,  484,  484,  484,  484,  484,  484,
+      484,  484,  484,  484,  484,  484,  484,  484,  484,  484,
+      484,  484,  484,  484,  484,  484,  484,  484,  484,  484,
+      484,  484
+    } ;
+
+static yy_state_type yy_last_accepting_state;
+static char *yy_last_accepting_cpos;
+
+/* The intent behind this definition is that it'll catch
+ * any uses of REJECT which flex missed.
+ */
+#define REJECT reject_used_but_not_detected
+static int yy_more_flag = 0;
+static int yy_more_len = 0;
+#define yymore() (yy_more_flag = 1)
+#define YY_MORE_ADJ yy_more_len
+#define YY_RESTORE_YY_MORE_OFFSET
+char *yytext;
+#line 1 "libparse.l"
+#define INITIAL 0
+#line 2 "libparse.l"
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <kernel/mod2.h>
+#ifdef STANDALONE_PARSER
+  #include <Singular/utils.h>
+
+  #define HAVE_LIBPARSER
+  #define YYLPDEBUG 1
+  #define myfread fread
+#else
+  #include <Singular/subexpr.h>
+  #include <Singular/grammar.h>
+  #include <Singular/ipshell.h>
+  #include <Singular/ipid.h>
+  #include <Singular/tok.h>
+  #include <misc/options.h>
+  #include <omalloc/omalloc.h>
+#endif
+#include <Singular/libparse.h>
+
+#ifdef HAVE_LIBPARSER
+#define YY_SKIP_YYWRAP
+
+typedef enum { LP_NONE, LP_INFO, LP_CATEGORY, LP_URL, LP_VERSION} lib_cmds;
+
+int libread(FILE* f, char* buf, int max_size);
+int current_pos(int i);
+void print_version(lp_modes mode, char *p);
+void copy_string(lp_modes mode);
+void make_version(char *p, int what);
+
+int brace1 = 0;  /* { } */
+int brace2 = 0;  /* ( ) */
+int brace3 = 0;  /* [ ] */
+int quote  = 0;  /* " */
+int offset = 0;
+BOOLEAN p_static = FALSE;
+int old_state = 0;
+lib_cmds last_cmd = LP_NONE;
+
+char libnamebuf[128];
+char *text_buffer=NULL;
+long string_start;
+
+char *yylp_buffer_start;
+#ifndef NEW_FLEX
+int yylplineno = 1;
+#endif /* NEW_FLEX */
+int lpverbose = 0, check = 0;
+int texinfo_out = 0;
+int found_info=0,
+    found_cat=0,
+    found_version=0,
+    found_oldhelp = 0,
+    found_proc_in_proc = 0;
+
+const char *yylp_errlist[]= {
+   "",
+   "missing close bracket ')' for proc definition in line %d.",  /*  1 */
+   "missing close bracket ')' for procbody in line %d.",         /*  2 */
+   "missing close bracket ']' for procbody in line %d.",         /*  3 */
+   "too many ')' closed brackets in line %d.",                   /*  4 */
+   "too many ']' closed brackets in line %d.",                   /*  5 */
+   "missing close bracket ')' for example in line %d.",          /*  6 */
+   "missing close bracket ']' for example in line %d.",          /*  7 */
+   "cannot assign character '%c' in line %d to any group.",      /*  8 */
+   "there must be a quote missing somewhere before line %d.",    /*  9 */
+   "missing close bracket '}' at end of library in line %d.",    /* 10 */
+   "missing close bracket ')' at end of library in line %d.",    /* 11 */
+   "missing close bracket ']' at end of library in line %d.",    /* 12 */
+   NULL
+};
+int yylp_errno = 0;
+
+#ifdef STANDALONE_PARSER
+procinfov pi;
+int category_out = 0;
+void printpi(procinfov pi);
+void pi_clear(procinfov pi);
+extern "C" {
+  int yylpwrap();
+}
+void main_init(int argc, char *argv[]);
+void main_result(char *libname);
+#else /* STANDALONE_PARSER */
+idhdl h0;
+idhdl h_top;
+#define pi IDPROC(h0)
+extern "C"
+{
+  int yylpwrap();
+}
+extern libstackv library_stack;
+#endif /* STANDALONE_PARSER */
+
+static unsigned long help_chksum;
+
+#define SET_DEF_END(mode, pi, p) \
+  if ( mode == LOAD_LIB) pi->data.s.def_end = p;
+#define SET_HELP_START(mode, pi, p) \
+  if ( mode == LOAD_LIB) {pi->data.s.help_start = p; help_chksum = 0;}
+#define SET_HELP_END(mode, pi, p) \
+  if ( mode == LOAD_LIB) {pi->data.s.help_end = p;  \
+              pi->data.s.help_chksum = help_chksum;}
+
+#define SET_BODY_START(mode, pi, l, p) \
+     if ( mode == LOAD_LIB)            \
+     {                                 \
+       pi->data.s.body_lineno = l;     \
+       pi->data.s.body_start = p;      \
+     }
+#define SET_BODY_END(mode, pi, p) \
+     if ( mode == LOAD_LIB)       \
+     {                            \
+       pi->data.s.body_end = p-1; \
+       pi->data.s.proc_end = p-1; \
+     }
+
+#define SET_EXAMPLE_START(mode, pi, l, p) \
+   if ( mode == LOAD_LIB)                 \
+   {                                      \
+     pi->data.s.example_lineno = l;       \
+     pi->data.s.example_start = p;        \
+   }
+#define SET_PROC_END(mode, pi, p)   \
+     if ( mode == LOAD_LIB)         \
+     {                              \
+       pi->data.s.proc_end = p-1;   \
+       if(pi->data.s.body_end==0)   \
+         pi->data.s.body_end = p-1; \
+     }
+
+#define ROTATE_RIGHT(c) if ((c) & 01) (c) = ((c) >>1) + 0x8000; else (c) >>= 1;
+#define IncrCheckSum(c)                          \
+do                                            \
+{                                             \
+  ROTATE_RIGHT(help_chksum);                  \
+  help_chksum += c;                           \
+  help_chksum &= 0xffff;                      \
+}                                             \
+while(0)
+
+#undef YY_DECL
+#define YY_DECL int yylex(const char *newlib, const char *libfile, \
+                           lib_style_types *lib_style, \
+                           idhdl pl, BOOLEAN autoexport, lp_modes mode)
+#undef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+          if ( ((result = libread( (yyin), (char *) buf, max_size )) < 0 ) \
+                  && ferror( yyin ) ) \
+                YY_FATAL_ERROR( "read in flex scanner failed" );
+
+#define YY_USER_INIT { \
+       BEGIN(header); \
+       yylplineno = 1; \
+       yylp_errno = 0; \
+       *lib_style = OLD_LIBSTYLE; \
+       strcpy(libnamebuf,"(**unknown version**)"); \
+     }
+
+#if 0
+<pbody>proc[ \t]+{name}  {
+                           printf("MISSING: PROC-cmd found. ERROR!\n"); }
+<pbody>example[ \t]*\n   {
+                           yylplineno++;
+                           printf("MISSING: EXAMPLE-cmd found. ERROR!\n"); }
+info=+"\"" {
+#endif
+
+/* %start START */
+#define header 1
+
+#define help 2
+
+#define libcmd 3
+
+#define libcmd2 4
+
+#define pdef 5
+
+#define phead 6
+
+#define poldhelp 7
+
+#define phelp 8
+
+#define pbody 9
+
+#define pstr 10
+
+#define pexample 11
+
+#define pestr 12
+
+#define string 13
+
+#define comment 14
+
+#define info 15
+
+#define category 16
+
+#define url 17
+
+#define version 18
+
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int yywrap YY_PROTO(( void ));
+#else
+extern int yywrap YY_PROTO(( void ));
+#endif
+#endif
+
+#ifndef YY_NO_UNPUT
+static void yyunput YY_PROTO(( int c, char *buf_ptr ));
+#endif
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy YY_PROTO(( char *, yyconst char *, int ));
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen YY_PROTO(( yyconst char * ));
+#endif
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+static int yyinput YY_PROTO(( void ));
+#else
+static int input YY_PROTO(( void ));
+#endif
+#endif
+
+#if YY_STACK_USED
+static int yy_start_stack_ptr = 0;
+static int yy_start_stack_depth = 0;
+static int *yy_start_stack = 0;
+#ifndef YY_NO_PUSH_STATE
+static void yy_push_state YY_PROTO(( int new_state ));
+#endif
+#ifndef YY_NO_POP_STATE
+static void yy_pop_state YY_PROTO(( void ));
+#endif
+#ifndef YY_NO_TOP_STATE
+static int yy_top_state YY_PROTO(( void ));
+#endif
+
+#else
+#define YY_NO_PUSH_STATE 1
+#define YY_NO_POP_STATE 1
+#define YY_NO_TOP_STATE 1
+#endif
+
+#ifdef YY_MALLOC_DECL
+YY_MALLOC_DECL
+#else
+#if __STDC__
+#ifndef __cplusplus
+#include <stdlib.h>
+#endif
+#else
+/* Just try to get by without declaring the routines.  This will fail
+ * miserably on non-ANSI systems for which sizeof(size_t) != sizeof(int)
+ * or sizeof(void*) != sizeof(int).
+ */
+#endif
+#endif
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#define YY_READ_BUF_SIZE 8192
+#endif
+
+/* Copy whatever the last rule matched to the standard output. */
+
+#ifndef ECHO
+/* This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+#define ECHO (void) fwrite( yytext, yyleng, 1, yyout )
+#endif
+
+/* Gets input and stuffs it into "buf".  number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+	if ( yy_current_buffer->yy_is_interactive ) \
+		{ \
+		int c = '*', n; \
+		for ( n = 0; n < max_size && \
+			     (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
+			buf[n] = (char) c; \
+		if ( c == '\n' ) \
+			buf[n++] = (char) c; \
+		if ( c == EOF && ferror( yyin ) ) \
+			YY_FATAL_ERROR( "input in flex scanner failed" ); \
+		result = n; \
+		} \
+	else if ( ((result = fread( buf, 1, max_size, yyin )) == 0) \
+		  && ferror( yyin ) ) \
+		YY_FATAL_ERROR( "input in flex scanner failed" );
+#endif
+
+/* No semi-colon after return; correct usage is to write "yyterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
+#endif
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL int yylex YY_PROTO(( void ))
+#endif
+
+/* Code executed at the beginning of each rule, after yytext and yyleng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_BREAK
+#define YY_BREAK break;
+#endif
+
+#define YY_RULE_SETUP \
+	if ( yyleng > 0 ) \
+		yy_current_buffer->yy_at_bol = \
+				(yytext[yyleng - 1] == '\n'); \
+	YY_USER_ACTION
+
+YY_DECL
+	{
+	register yy_state_type yy_current_state;
+	register char *yy_cp, *yy_bp;
+	register int yy_act;
+
+#line 229 "libparse.l"
+
+
+	if ( yy_init )
+		{
+		yy_init = 0;
+
+#ifdef YY_USER_INIT
+		YY_USER_INIT;
+#endif
+
+		if ( ! yy_start )
+			yy_start = 1;	/* first start state */
+
+		if ( ! yyin )
+			yyin = stdin;
+
+		if ( ! yyout )
+			yyout = stdout;
+
+		if ( ! yy_current_buffer )
+			yy_current_buffer =
+				yy_create_buffer( yyin, YY_BUF_SIZE );
+
+		yy_load_buffer_state();
+		}
+
+	while ( 1 )		/* loops until end-of-file is reached */
+		{
+		yy_more_len = 0;
+		if ( yy_more_flag )
+			{
+			yy_more_len = yy_c_buf_p - yytext_ptr;
+			yy_more_flag = 0;
+			}
+		yy_cp = yy_c_buf_p;
+
+		/* Support of yytext. */
+		*yy_cp = yy_hold_char;
+
+		/* yy_bp points to the position in yy_ch_buf of the start of
+		 * the current run.
+		 */
+		yy_bp = yy_cp;
+
+		yy_current_state = yy_start;
+		yy_current_state += YY_AT_BOL();
+yy_match:
+		do
+			{
+			register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
+			if ( yy_accept[yy_current_state] )
+				{
+				yy_last_accepting_state = yy_current_state;
+				yy_last_accepting_cpos = yy_cp;
+				}
+			while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+				{
+				yy_current_state = (int) yy_def[yy_current_state];
+				if ( yy_current_state >= 485 )
+					yy_c = yy_meta[(unsigned int) yy_c];
+				}
+			yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+			++yy_cp;
+			}
+		while ( yy_base[yy_current_state] != 2200 );
+
+yy_find_action:
+		yy_act = yy_accept[yy_current_state];
+		if ( yy_act == 0 )
+			{ /* have to back up */
+			yy_cp = yy_last_accepting_cpos;
+			yy_current_state = yy_last_accepting_state;
+			yy_act = yy_accept[yy_current_state];
+			}
+
+		YY_DO_BEFORE_ACTION;
+
+
+do_action:	/* This label is used only to access EOF actions. */
+
+
+		switch ( yy_act )
+	{ /* beginning of action switch */
+			case 0: /* must back up */
+			/* undo the effects of YY_DO_BEFORE_ACTION */
+			*yy_cp = yy_hold_char;
+			yy_cp = yy_last_accepting_cpos;
+			yy_current_state = yy_last_accepting_state;
+			goto yy_find_action;
+
+case 1:
+YY_RULE_SETUP
+#line 230 "libparse.l"
+{ }
+	YY_BREAK
+case 2:
+YY_RULE_SETUP
+#line 231 "libparse.l"
+{ old_state = YYSTATE; BEGIN(comment); }
+	YY_BREAK
+case 3:
+YY_RULE_SETUP
+#line 233 "libparse.l"
+{
+         yyless(4); old_state = YYSTATE; BEGIN(info);
+       }
+	YY_BREAK
+case 4:
+YY_RULE_SETUP
+#line 236 "libparse.l"
+{
+         yyless(8); old_state = YYSTATE; BEGIN(category);
+       }
+	YY_BREAK
+case 5:
+YY_RULE_SETUP
+#line 239 "libparse.l"
+{
+             if ( mode != GET_INFO )
+             {
+               #ifdef STANDALONE_PARSER
+               if (texinfo_out)
+               {
+                 char *c = yytext;
+                 printf("$url = \"");
+                 while ((*c != '\0') && (*c != '"')) c++;
+                 c++;
+                 while ((*c != '\0') && (*c != '"'))
+                 {
+                    if (*c != '\r') putchar(*c);
+                    c++;
+                 }
+                 printf("\";\n");
+               }
+               #endif
+             }
+       }
+	YY_BREAK
+case 6:
+YY_RULE_SETUP
+#line 260 "libparse.l"
+{
+             found_version++;
+             if ( mode != GET_INFO )
+             {
+               make_version(yytext,1);
+               #ifdef STANDALONE_PARSER
+               if (texinfo_out)
+               {
+                 char *c = libnamebuf;
+                 printf("$version = \"");
+                 while (*c != '\0')
+                 {
+                    if (*c  == '$' || *c  == '@') putchar('\\');
+                    if (*c != '\r') putchar(*c);
+                    if (*c  == '\\')
+                    {
+                      c++;
+                      if (*c != '"') putchar('\\');
+                    }
+                    else
+                      c++;
+                 }
+                 printf("\";\n");
+               }
+               else if (!category_out)
+                 printf("Version:%s;\n", libnamebuf);
+               #else
+               if (text_buffer!=NULL) omFree((ADDRESS)text_buffer);
+               text_buffer = omStrDup(libnamebuf);
+               omMarkAsStaticAddr(text_buffer);
+               #endif
+             }
+           }
+	YY_BREAK
+case 7:
+YY_RULE_SETUP
+#line 294 "libparse.l"
+{ p_static=TRUE; }
+	YY_BREAK
+case 8:
+YY_RULE_SETUP
+#line 296 "libparse.l"
+{
+             char proc[256];
+             BEGIN(pdef);
+             found_proc_in_proc = 0;
+             proc[0]='\0';
+             sscanf( yytext, "%*[^p]proc %s", proc);
+             if(strlen(proc)<1) sscanf( yytext, "proc %s", proc);
+             #if YYLPDEBUG > 1
+             printf("Newlib:%s\n", newlib);
+             #endif
+             #ifdef STANDALONE_PARSER
+             if ( pi != NULL )
+             {
+               printpi(pi);
+               pi_clear(pi);
+             }
+             pi = (procinfo *)malloc(sizeof(procinfo));
+             iiInitSingularProcinfo(pi, newlib, proc, yylplineno,
+                                    current_pos(0), p_static);
+             #else /*STANDALONE_PARSER*/
+             if( mode == LOAD_LIB)
+             {
+               h0 = enterid( proc, 0 /*myynest*/, PROC_CMD,
+                                 &(IDPACKAGE(pl)->idroot), TRUE, !p_static);
+               if (h0==NULL) return(1);
+               if((!p_static) && autoexport)
+               {
+                  package save=currPack;
+                  currPack=basePack;
+                  h_top = enterid( proc, 0 /*myynest*/, PROC_CMD,
+                                 &(basePack->idroot), FALSE );
+                  currPack=save;
+                  if (h_top==NULL) return(1);
+               }
+               /* omCheckAddr(IDID(h0)); */
+               if (h0!=NULL)
+               {
+                 iiInitSingularProcinfo(IDPROC(h0), newlib, proc,
+                                yylplineno, current_pos(0),p_static);
+                 if ((!p_static) && (h_top != NULL) && autoexport)
+                 {
+                   if(IDPROC(h_top)!=NULL) piKill((procinfo *)IDPROC(h_top));
+                   IDPROC(h_top)=IDPROC(h0);
+                   IDPROC(h_top)->ref++;
+                 }
+                 IDPROC(h0)->pack=IDPACKAGE(pl);
+                 if (BVERBOSE(V_LOAD_PROC))
+                   Warn( "     proc '%s' registered", proc );
+               }
+               #endif /*STANDALONE_PARSER*/
+               SET_DEF_END(mode, pi, current_pos(yyleng+1));
+               #if YYLPDEBUG
+               if(lpverbose)
+               {
+                  printf("// PROCEDURE '%s' status: %s, ", proc,
+                      p_static ? "local" : "global");
+                  printf("starting at line %d,%d: definition end: %d (%d).\n",
+                      yylplineno, current_pos(0), (int)pi->data.s.def_end, brace1);
+               }
+               #endif
+               p_static=FALSE;
+             #ifndef STANDALONE_PARSER
+             }
+             #endif /*STANDALONE_PARSER*/
+           }
+	YY_BREAK
+case 9:
+YY_RULE_SETUP
+#line 361 "libparse.l"
+{
+             BEGIN(pexample);
+             SET_EXAMPLE_START(mode, pi, yylplineno, current_pos(0));
+             #if YYLPDEBUG
+             if(lpverbose)
+             {
+                printf("//     EXAMPLE at line %d,%d (%d)\n", yylplineno,
+                    current_pos(0), brace1);
+             }
+             #endif
+           }
+	YY_BREAK
+case 10:
+YY_RULE_SETUP
+#line 373 "libparse.l"
+{ quote++;
+             BEGIN(libcmd);
+           }
+	YY_BREAK
+case 11:
+YY_RULE_SETUP
+#line 377 "libparse.l"
+{ quote++; brace2++;
+             BEGIN(libcmd2);
+           }
+	YY_BREAK
+case 12:
+YY_RULE_SETUP
+#line 381 "libparse.l"
+{
+             make_version(yytext, 0);
+             #if YYLPDEBUG > 1
+             printf("+(id)HEAD:%s\n", yytext);
+             #endif
+           }
+	YY_BREAK
+case 13:
+YY_RULE_SETUP
+#line 387 "libparse.l"
+{
+             #if YYLPDEBUG
+             printf("+(cmt)HEAD:%s\n", yytext);
+             #endif
+           }
+	YY_BREAK
+case 14:
+YY_RULE_SETUP
+#line 392 "libparse.l"
+{
+             #if YYLPDEBUG > 1
+             printf("-HEAD:%s\n", yytext);
+             #endif
+           }
+	YY_BREAK
+case 15:
+YY_RULE_SETUP
+#line 397 "libparse.l"
+{ yyless(0);
+             BEGIN(INITIAL);
+             yymore();
+           }
+	YY_BREAK
+case 16:
+YY_RULE_SETUP
+#line 401 "libparse.l"
+{
+             yyless(0);
+             *lib_style = NEW_LIBSTYLE;
+             BEGIN(INITIAL);
+             yymore();
+           }
+	YY_BREAK
+case 17:
+YY_RULE_SETUP
+#line 408 "libparse.l"
+{ quote++;
+             BEGIN(libcmd);
+           }
+	YY_BREAK
+case 18:
+YY_RULE_SETUP
+#line 411 "libparse.l"
+{ quote++; brace2++;
+             BEGIN(libcmd2);
+           }
+	YY_BREAK
+case 19:
+YY_RULE_SETUP
+#line 414 "libparse.l"
+{ yylplineno++; }
+	YY_BREAK
+case 20:
+YY_RULE_SETUP
+#line 415 "libparse.l"
+{
+             #if YYLPDEBUG > 1
+             printf(" HEAD:%s\n", yytext);
+             #endif
+             yyless(0);
+             BEGIN(help);
+           }
+	YY_BREAK
+case 21:
+YY_RULE_SETUP
+#line 422 "libparse.l"
+{
+             #if YYLPDEBUG > 1
+             printf(" HELP:%s\n", yytext);
+             #endif
+             BEGIN(INITIAL); }
+	YY_BREAK
+case 22:
+YY_RULE_SETUP
+#line 427 "libparse.l"
+{
+             #if YYLPDEBUG > 1
+             printf(" HELP:%s\n", yytext);
+             #endif
+             BEGIN(INITIAL);
+           }
+	YY_BREAK
+case 23:
+YY_RULE_SETUP
+#line 433 "libparse.l"
+{
+             yyless(0);
+             *lib_style = NEW_LIBSTYLE;
+             BEGIN(INITIAL);
+             yymore();
+           }
+	YY_BREAK
+case 24:
+YY_RULE_SETUP
+#line 439 "libparse.l"
+{
+             yyless(0);
+             //printf("2) proc found.\n");
+             BEGIN(INITIAL);
+             yymore();
+           }
+	YY_BREAK
+case 25:
+YY_RULE_SETUP
+#line 445 "libparse.l"
+{ quote++;
+             BEGIN(libcmd);
+           }
+	YY_BREAK
+case 26:
+YY_RULE_SETUP
+#line 448 "libparse.l"
+{ quote++; brace2++;
+             BEGIN(libcmd2);
+           }
+	YY_BREAK
+case 27:
+YY_RULE_SETUP
+#line 452 "libparse.l"
+{ yylplineno++; }
+	YY_BREAK
+case 28:
+YY_RULE_SETUP
+#line 453 "libparse.l"
+{
+             #if YYLPDEBUG
+             if(lpverbose>2) printf("--->%s<---\n", yytext);
+             #endif
+           }
+	YY_BREAK
+case 29:
+YY_RULE_SETUP
+#line 458 "libparse.l"
+{
+             found_oldhelp=1;
+             #if YYLPDEBUG > 1
+             printf("-HELP:%s\n", yytext);
+             #endif
+           }
+	YY_BREAK
+case 30:
+YY_RULE_SETUP
+#line 466 "libparse.l"
+{ quote--;
+             yytext[yyleng-1] = '\0';
+             #ifndef STANDALONE_PARSER
+             if ( mode == LOAD_LIB )
+             {
+               library_stack->push(newlib, yytext);
+             }
+             #endif /* STANDALONE_PARSER */
+             #if YYLPDEBUG
+             if(lpverbose>1) printf("LIB:'%s'\n", yytext);
+             #endif
+             BEGIN(INITIAL);
+           }
+	YY_BREAK
+case 31:
+YY_RULE_SETUP
+#line 479 "libparse.l"
+{ quote--; brace2--;
+             yytext[yyleng-1] = '\0';
+             #ifndef STANDALONE_PARSER
+             if ( mode == LOAD_LIB )
+             {
+               library_stack->push(newlib, yytext);
+             }
+             #endif /* STANDALONE_PARSER */
+             #if YYLPDEBUG
+             if(lpverbose>1) printf("LIB:'%s'\n", yytext);
+             #endif
+             BEGIN(INITIAL);
+           }
+	YY_BREAK
+case 32:
+YY_RULE_SETUP
+#line 493 "libparse.l"
+{ }
+	YY_BREAK
+case 33:
+YY_RULE_SETUP
+#line 494 "libparse.l"
+{
+             brace2++;
+             #if YYLPDEBUG > 1
+             printf("%s", yytext);
+             #endif
+           }
+	YY_BREAK
+case 34:
+YY_RULE_SETUP
+#line 500 "libparse.l"
+{
+             brace2--;
+             #if YYLPDEBUG > 1
+             printf(">%s<\n", yytext);
+             printf("{=%d, (=%d, [=%d\n", brace1, brace2, brace3);
+             #endif
+             if(brace2<=0)
+             {
+               #if YYLPDEBUG > 1
+               printf("BEGIN(phead){=%d, (=%d, [=%d\n", brace1, brace2, brace3);
+               #endif
+               SET_DEF_END(mode, pi, current_pos(yyleng));
+               BEGIN(phead);
+             }
+           }
+	YY_BREAK
+case 35:
+YY_RULE_SETUP
+#line 515 "libparse.l"
+{
+             if(brace2>0)
+             {
+               #if YYLPDEBUG > 1
+               printf("{=%d, (=%d, [=%d\n", brace1, brace2, brace3);
+               #endif
+               yylp_errno = YYLP_DEF_BR2;
+               return(1);
+             }
+             else
+             {
+               brace1++; BEGIN(pbody);
+               if(lpverbose)
+                  printf("//     BODY at line %d,%d (%d)\n", yylplineno,
+                      current_pos(0), brace1);
+               SET_BODY_START(mode, pi, yylplineno, current_pos(0));
+             }
+           }
+	YY_BREAK
+case 36:
+YY_RULE_SETUP
+#line 533 "libparse.l"
+{ yylplineno++;
+              if(brace2<=0)
+              {
+#if YYLPDEBUG > 1
+                printf("BEGIN(phead-2){=%d, (=%d, [=%d\n", brace1, brace2, brace3);
+#endif
+                BEGIN(phead);
+              }
+            }
+	YY_BREAK
+case 37:
+YY_RULE_SETUP
+#line 542 "libparse.l"
+{ }
+	YY_BREAK
+case 38:
+YY_RULE_SETUP
+#line 543 "libparse.l"
+{ old_state = YYSTATE; BEGIN(comment); }
+	YY_BREAK
+case 39:
+YY_RULE_SETUP
+#line 544 "libparse.l"
+{
+             if(brace2<=0)
+             {
+               BEGIN(phead);
+               yyless(0);
+             }
+           }
+	YY_BREAK
+case 40:
+YY_RULE_SETUP
+#line 552 "libparse.l"
+{
+              #if YYLPDEBUG
+              if(lpverbose>2)printf("0-Len=%d;\n", yyleng);
+              #endif
+              if(check)
+              {
+                printf("Procedure %s (line %d) has OLD-STYLE-HELP!\n",
+                       pi->procname, pi->data.s.proc_lineno);
+              }
+              SET_HELP_START(mode, pi, current_pos(0));
+              BEGIN(poldhelp);
+              yyless(0);
+           }
+	YY_BREAK
+case 41:
+YY_RULE_SETUP
+#line 565 "libparse.l"
+{
+              #if YYLPDEBUG
+              if(lpverbose>2)printf("1-Len=%d;\n", yyleng);
+              #endif
+              BEGIN(phelp);
+              yyless(0);
+           }
+	YY_BREAK
+case 42:
+YY_RULE_SETUP
+#line 572 "libparse.l"
+{
+              if(check && yyleng>2)
+              {
+                printf("Procedure %s (line %d) has OLD-STYLE-HELP!\n",
+                       pi->procname, pi->data.s.proc_lineno);
+              }
+              #if YYLPDEBUG
+              if(lpverbose>2 && yyleng>2)
+                 printf("2-Len=%d, %s;\n", yyleng, pi->procname);
+              #endif
+              SET_HELP_START(mode, pi, current_pos(0));
+              BEGIN(poldhelp);
+              yyless(0);
+           }
+	YY_BREAK
+case 43:
+YY_RULE_SETUP
+#line 586 "libparse.l"
+{ printf("[%s]", yytext); }
+	YY_BREAK
+case 44:
+YY_RULE_SETUP
+#line 588 "libparse.l"
+{ }
+	YY_BREAK
+case 45:
+YY_RULE_SETUP
+#line 589 "libparse.l"
+{
+                SET_HELP_END(mode, pi, current_pos(0));
+                brace1++; BEGIN(pbody);
+                if(lpverbose)
+                {
+                   printf("//     HELP from %d to %d\n",
+                       (int)pi->data.s.help_start, (int)pi->data.s.help_end);
+                   printf("//     BODY at line %d,%d (%d)\n", yylplineno,
+                       current_pos(0), brace1);
+                }
+#if YYLPDEBUG > 1
+                printf("BEGIN(pbody){=%d, (=%d, [=%d\n", brace1, brace2, brace3);
+#endif
+                SET_BODY_START(mode, pi, yylplineno, current_pos(0));
+#if YYLPDEBUG > 1
+                printf("BODY at %d/%d", yylplineno, current_pos(0));
+#endif
+              }
+	YY_BREAK
+case 46:
+YY_RULE_SETUP
+#line 607 "libparse.l"
+{ yylplineno++; }
+	YY_BREAK
+case 47:
+YY_RULE_SETUP
+#line 608 "libparse.l"
+{ }
+	YY_BREAK
+case 48:
+YY_RULE_SETUP
+#line 610 "libparse.l"
+{
+             old_state = YYSTATE;
+             BEGIN(string);
+             SET_HELP_START(mode, pi, current_pos(1));
+           }
+	YY_BREAK
+case 49:
+YY_RULE_SETUP
+#line 615 "libparse.l"
+{}
+	YY_BREAK
+case 50:
+YY_RULE_SETUP
+#line 616 "libparse.l"
+{
+             brace1++; BEGIN(pbody);
+             if(lpverbose)
+             {
+                printf("//     HELP from %d to %d\n",
+                    (int)pi->data.s.help_start, (int)pi->data.s.help_end);
+                printf("//     BODY at line %d,%d (%d)\n", yylplineno,
+                    current_pos(0), brace1);
+             }
+             #if YYLPDEBUG > 1
+             printf("BEGIN(pbody){=%d, (=%d, [=%d\n", brace1, brace2, brace3);
+             #endif
+             SET_BODY_START(mode, pi, yylplineno, current_pos(0));
+             #if YYLPDEBUG > 1
+             printf("BODY at %d/%d", yylplineno, current_pos(0));
+             #endif
+           }
+	YY_BREAK
+case 51:
+YY_RULE_SETUP
+#line 633 "libparse.l"
+{ yylplineno++;}
+	YY_BREAK
+case 52:
+YY_RULE_SETUP
+#line 635 "libparse.l"
+{ }
+	YY_BREAK
+case 53:
+YY_RULE_SETUP
+#line 636 "libparse.l"
+{ quote++; old_state = YYSTATE;
+                 BEGIN(string); /* printf("%s", yytext); */
+               }
+	YY_BREAK
+case 54:
+YY_RULE_SETUP
+#line 640 "libparse.l"
+{
+             if(check) printf("*** found 2 proc whithin procedure '%s'.\n",
+                          pi->procname);
+             yyless(yyleng-1);
+           }
+	YY_BREAK
+case 55:
+YY_RULE_SETUP
+#line 645 "libparse.l"
+{
+             if(check) printf("*** found 1 proc whithin procedure '%s'.\n",
+                          pi->procname);
+             yyless(yyleng-1);
+           }
+	YY_BREAK
+case 56:
+YY_RULE_SETUP
+#line 650 "libparse.l"
+{
+                 brace1++;
+                 #if YYLPDEBUG > 1
+                 printf("line: %d, (%d)%s\n", yylplineno, brace1, yytext);
+                 #endif
+                }
+	YY_BREAK
+case 57:
+YY_RULE_SETUP
+#line 656 "libparse.l"
+{
+                           #if YYLPDEBUG > 1
+                           printf("line: %d, (%d)%s\n",
+                             yylplineno, brace1, yytext);
+                           #endif
+                           brace1--;
+                           if(brace2>0)
+                           {
+                             yylp_errno = YYLP_BODY_BR2;
+                             return(1);
+                           }
+                           if(brace3>0)
+                           {
+                             yylp_errno = YYLP_BODY_BR3;
+                             return(1);
+                           }
+                           if(brace1<=0)
+                           {
+                             SET_BODY_END(mode, pi, current_pos(yyleng));
+                             SET_PROC_END(mode, pi, current_pos(yyleng));
+                             #if YYLPDEBUG > 1
+                               printf("-%d\n", current_pos(0));
+                             #endif
+                             BEGIN(INITIAL);
+                           }
+                         }
+	YY_BREAK
+case 58:
+YY_RULE_SETUP
+#line 682 "libparse.l"
+{
+                           brace2++; /* printf("%s", yytext); */
+                         }
+	YY_BREAK
+case 59:
+YY_RULE_SETUP
+#line 685 "libparse.l"
+{
+                           brace2--; /* printf("%s", yytext); */
+                           if(brace2<0) {
+                             yylp_errno = YYLP_BODY_TMBR2;
+                             return(1);
+                           }
+                         }
+	YY_BREAK
+case 60:
+YY_RULE_SETUP
+#line 692 "libparse.l"
+{
+                           brace3++; /* printf("%s", yytext); */
+                         }
+	YY_BREAK
+case 61:
+YY_RULE_SETUP
+#line 695 "libparse.l"
+{
+                           brace3--; /* printf("%s", yytext); */
+                           if(brace3<0) {
+                             yylp_errno = YYLP_BODY_TMBR3;
+                             return(1);
+                           }
+                         }
+	YY_BREAK
+case 62:
+YY_RULE_SETUP
+#line 702 "libparse.l"
+{ yylplineno++; }
+	YY_BREAK
+case 63:
+YY_RULE_SETUP
+#line 703 "libparse.l"
+{ }
+	YY_BREAK
+case 64:
+YY_RULE_SETUP
+#line 705 "libparse.l"
+{
+             quote++; BEGIN(string);
+             found_info++;
+             string_start = current_pos(yyleng);
+             *lib_style = NEW_LIBSTYLE;
+             last_cmd = LP_INFO;
+       }
+	YY_BREAK
+case 65:
+YY_RULE_SETUP
+#line 712 "libparse.l"
+{ yylplineno++; }
+	YY_BREAK
+case 66:
+YY_RULE_SETUP
+#line 713 "libparse.l"
+{ }
+	YY_BREAK
+case 67:
+YY_RULE_SETUP
+#line 715 "libparse.l"
+{
+             quote++; BEGIN(string);
+             found_cat++;
+             string_start = current_pos(yyleng);
+             *lib_style = NEW_LIBSTYLE;
+             last_cmd = LP_CATEGORY;
+       }
+	YY_BREAK
+case 68:
+YY_RULE_SETUP
+#line 722 "libparse.l"
+{ yylplineno++; }
+	YY_BREAK
+case 69:
+YY_RULE_SETUP
+#line 723 "libparse.l"
+{ }
+	YY_BREAK
+case 70:
+YY_RULE_SETUP
+#line 726 "libparse.l"
+{ quote--;
+                           copy_string(mode);
+                           last_cmd = LP_NONE;
+                           if(old_state==phelp)
+                           {
+                              SET_HELP_END(mode, pi, current_pos(0));
+                           }
+                           BEGIN(old_state); /* printf("%s", yytext); */
+                         }
+	YY_BREAK
+case 71:
+YY_RULE_SETUP
+#line 735 "libparse.l"
+{ if (old_state == phelp) IncrCheckSum(*yytext);}
+	YY_BREAK
+case 72:
+YY_RULE_SETUP
+#line 736 "libparse.l"
+{ yylplineno++; if (old_state == phelp) IncrCheckSum('\n');}
+	YY_BREAK
+case 73:
+YY_RULE_SETUP
+#line 737 "libparse.l"
+{ if (old_state == phelp) IncrCheckSum(*yytext);}
+	YY_BREAK
+case 74:
+YY_RULE_SETUP
+#line 739 "libparse.l"
+{ }
+	YY_BREAK
+case 75:
+YY_RULE_SETUP
+#line 740 "libparse.l"
+{ quote++; old_state = YYSTATE;
+                           BEGIN(string); /* printf("%s", yytext); */
+                         }
+	YY_BREAK
+case 76:
+YY_RULE_SETUP
+#line 743 "libparse.l"
+{
+                           brace1++; /* printf("(%d)%s", brace1, yytext); */
+                         }
+	YY_BREAK
+case 77:
+YY_RULE_SETUP
+#line 746 "libparse.l"
+{
+                           brace1--; /* printf("(%d)%s", brace1, yytext); */
+                           if(brace1<=0) {
+                             if(brace2>0) { yylp_errno=YYLP_EX_BR2; return(1); }
+                             if(brace3>0) { yylp_errno=YYLP_EX_BR3; return(1); }
+                             BEGIN(INITIAL);
+                             SET_PROC_END(mode, pi, current_pos(yyleng));
+                           }
+                         }
+	YY_BREAK
+case 78:
+YY_RULE_SETUP
+#line 755 "libparse.l"
+{
+                           brace2++; /* printf("%s", yytext); */
+                         }
+	YY_BREAK
+case 79:
+YY_RULE_SETUP
+#line 758 "libparse.l"
+{
+                           brace2--; /* printf("%s", yytext); */
+                         }
+	YY_BREAK
+case 80:
+YY_RULE_SETUP
+#line 761 "libparse.l"
+{
+                           brace3++; /* printf("%s", yytext); */
+                         }
+	YY_BREAK
+case 81:
+YY_RULE_SETUP
+#line 764 "libparse.l"
+{
+                           brace3--; /* printf("%s", yytext); */
+                         }
+	YY_BREAK
+case 82:
+YY_RULE_SETUP
+#line 767 "libparse.l"
+{ yylplineno++; }
+	YY_BREAK
+case 83:
+YY_RULE_SETUP
+#line 768 "libparse.l"
+{ }
+	YY_BREAK
+case 84:
+YY_RULE_SETUP
+#line 770 "libparse.l"
+{ quote--;
+                           BEGIN(pexample); /* printf("%s", yytext); */
+                         }
+	YY_BREAK
+case 85:
+YY_RULE_SETUP
+#line 773 "libparse.l"
+{ }
+	YY_BREAK
+case 86:
+YY_RULE_SETUP
+#line 774 "libparse.l"
+{ }
+	YY_BREAK
+case 87:
+YY_RULE_SETUP
+#line 775 "libparse.l"
+{ yylplineno++; }
+	YY_BREAK
+case 88:
+YY_RULE_SETUP
+#line 776 "libparse.l"
+{ }
+	YY_BREAK
+case 89:
+YY_RULE_SETUP
+#line 778 "libparse.l"
+{ BEGIN(old_state); }
+	YY_BREAK
+case 90:
+YY_RULE_SETUP
+#line 779 "libparse.l"
+{ yylplineno++; }
+	YY_BREAK
+case 91:
+YY_RULE_SETUP
+#line 780 "libparse.l"
+{ }
+	YY_BREAK
+case 92:
+YY_RULE_SETUP
+#line 782 "libparse.l"
+{ yylplineno++; }
+	YY_BREAK
+case 93:
+YY_RULE_SETUP
+#line 783 "libparse.l"
+{ }
+	YY_BREAK
+case 94:
+YY_RULE_SETUP
+#line 784 "libparse.l"
+{ p_static = FALSE;
+                            #if YYLPDEBUG > 1
+                            printf("%s", yytext);
+                            #endif
+                         }
+	YY_BREAK
+case 95:
+YY_RULE_SETUP
+#line 789 "libparse.l"
+{ p_static = FALSE;
+                           yylp_errno = YYLP_BAD_CHAR;
+                           #ifdef STANDALONE_PARSER
+                           printf("[%d]", *yytext);
+                           #else
+                           if (text_buffer!=NULL) omFree((ADDRESS)text_buffer);
+                           text_buffer = omStrDup(yytext);
+                           omMarkAsStaticAddr(text_buffer);
+                           #endif
+                           #if YYLPDEBUG > 1
+                             printf("[%s]", yytext);
+                           #endif
+                           return(1);
+                         }
+	YY_BREAK
+case 96:
+YY_RULE_SETUP
+#line 804 "libparse.l"
+ECHO;
+	YY_BREAK
+case YY_STATE_EOF(INITIAL):
+case YY_STATE_EOF(header):
+case YY_STATE_EOF(help):
+case YY_STATE_EOF(libcmd):
+case YY_STATE_EOF(libcmd2):
+case YY_STATE_EOF(pdef):
+case YY_STATE_EOF(phead):
+case YY_STATE_EOF(poldhelp):
+case YY_STATE_EOF(phelp):
+case YY_STATE_EOF(pbody):
+case YY_STATE_EOF(pstr):
+case YY_STATE_EOF(pexample):
+case YY_STATE_EOF(pestr):
+case YY_STATE_EOF(string):
+case YY_STATE_EOF(comment):
+case YY_STATE_EOF(info):
+case YY_STATE_EOF(category):
+case YY_STATE_EOF(url):
+case YY_STATE_EOF(version):
+	yyterminate();
+
+	case YY_END_OF_BUFFER:
+		{
+		/* Amount of text matched not including the EOB char. */
+		int yy_amount_of_matched_text = (int) (yy_cp - yytext_ptr) - 1;
+
+		/* Undo the effects of YY_DO_BEFORE_ACTION. */
+		*yy_cp = yy_hold_char;
+		YY_RESTORE_YY_MORE_OFFSET
+
+		if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW )
+			{
+			/* We're scanning a new file or input source.  It's
+			 * possible that this happened because the user
+			 * just pointed yyin at a new source and called
+			 * yylex().  If so, then we have to assure
+			 * consistency between yy_current_buffer and our
+			 * globals.  Here is the right place to do so, because
+			 * this is the first action (other than possibly a
+			 * back-up) that will match for the new input source.
+			 */
+			yy_n_chars = yy_current_buffer->yy_n_chars;
+			yy_current_buffer->yy_input_file = yyin;
+			yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL;
+			}
+
+		/* Note that here we test for yy_c_buf_p "<=" to the position
+		 * of the first EOB in the buffer, since yy_c_buf_p will
+		 * already have been incremented past the NUL character
+		 * (since all states make transitions on EOB to the
+		 * end-of-buffer state).  Contrast this with the test
+		 * in input().
+		 */
+		if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] )
+			{ /* This was really a NUL. */
+			yy_state_type yy_next_state;
+
+			yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text;
+
+			yy_current_state = yy_get_previous_state();
+
+			/* Okay, we're now positioned to make the NUL
+			 * transition.  We couldn't have
+			 * yy_get_previous_state() go ahead and do it
+			 * for us because it doesn't know how to deal
+			 * with the possibility of jamming (and we don't
+			 * want to build jamming into it because then it
+			 * will run more slowly).
+			 */
+
+			yy_next_state = yy_try_NUL_trans( yy_current_state );
+
+			yy_bp = yytext_ptr + YY_MORE_ADJ;
+
+			if ( yy_next_state )
+				{
+				/* Consume the NUL. */
+				yy_cp = ++yy_c_buf_p;
+				yy_current_state = yy_next_state;
+				goto yy_match;
+				}
+
+			else
+				{
+				yy_cp = yy_c_buf_p;
+				goto yy_find_action;
+				}
+			}
+
+		else switch ( yy_get_next_buffer() )
+			{
+			case EOB_ACT_END_OF_FILE:
+				{
+				yy_did_buffer_switch_on_eof = 0;
+
+				if ( yywrap() )
+					{
+					/* Note: because we've taken care in
+					 * yy_get_next_buffer() to have set up
+					 * yytext, we can now set up
+					 * yy_c_buf_p so that if some total
+					 * hoser (like flex itself) wants to
+					 * call the scanner after we return the
+					 * YY_NULL, it'll still work - another
+					 * YY_NULL will get returned.
+					 */
+					yy_c_buf_p = yytext_ptr + YY_MORE_ADJ;
+
+					yy_act = YY_STATE_EOF(YY_START);
+					goto do_action;
+					}
+
+				else
+					{
+					if ( ! yy_did_buffer_switch_on_eof )
+						YY_NEW_FILE;
+					}
+				break;
+				}
+
+			case EOB_ACT_CONTINUE_SCAN:
+				yy_c_buf_p =
+					yytext_ptr + yy_amount_of_matched_text;
+
+				yy_current_state = yy_get_previous_state();
+
+				yy_cp = yy_c_buf_p;
+				yy_bp = yytext_ptr + YY_MORE_ADJ;
+				goto yy_match;
+
+			case EOB_ACT_LAST_MATCH:
+				yy_c_buf_p =
+				&yy_current_buffer->yy_ch_buf[yy_n_chars];
+
+				yy_current_state = yy_get_previous_state();
+
+				yy_cp = yy_c_buf_p;
+				yy_bp = yytext_ptr + YY_MORE_ADJ;
+				goto yy_find_action;
+			}
+		break;
+		}
+
+	default:
+		YY_FATAL_ERROR(
+			"fatal flex scanner internal error--no action found" );
+	} /* end of action switch */
+		} /* end of scanning one token */
+	} /* end of yylex */
+
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ *	EOB_ACT_LAST_MATCH -
+ *	EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ *	EOB_ACT_END_OF_FILE - end of file
+ */
+
+static int yy_get_next_buffer()
+	{
+	register char *dest = yy_current_buffer->yy_ch_buf;
+	register char *source = yytext_ptr;
+	register int number_to_move, i;
+	int ret_val;
+
+	if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] )
+		YY_FATAL_ERROR(
+		"fatal flex scanner internal error--end of buffer missed" );
+
+	if ( yy_current_buffer->yy_fill_buffer == 0 )
+		{ /* Don't try to fill the buffer, so this is an EOF. */
+		if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 )
+			{
+			/* We matched a single character, the EOB, so
+			 * treat this as a final EOF.
+			 */
+			return EOB_ACT_END_OF_FILE;
+			}
+
+		else
+			{
+			/* We matched some text prior to the EOB, first
+			 * process it.
+			 */
+			return EOB_ACT_LAST_MATCH;
+			}
+		}
+
+	/* Try to read more data. */
+
+	/* First move last chars to start of buffer. */
+	number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1;
+
+	for ( i = 0; i < number_to_move; ++i )
+		*(dest++) = *(source++);
+
+	if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+		/* don't do the read, it's not guaranteed to return an EOF,
+		 * just force an EOF
+		 */
+		yy_current_buffer->yy_n_chars = yy_n_chars = 0;
+
+	else
+		{
+		int num_to_read =
+			yy_current_buffer->yy_buf_size - number_to_move - 1;
+
+		while ( num_to_read <= 0 )
+			{ /* Not enough room in the buffer - grow it. */
+#ifdef YY_USES_REJECT
+			YY_FATAL_ERROR(
+"input buffer overflow, can't enlarge buffer because scanner uses REJECT" );
+#else
+
+			/* just a shorter name for the current buffer */
+			YY_BUFFER_STATE b = yy_current_buffer;
+
+			int yy_c_buf_p_offset =
+				(int) (yy_c_buf_p - b->yy_ch_buf);
+
+			if ( b->yy_is_our_buffer )
+				{
+				int new_size = b->yy_buf_size * 2;
+
+				if ( new_size <= 0 )
+					b->yy_buf_size += b->yy_buf_size / 8;
+				else
+					b->yy_buf_size *= 2;
+
+				b->yy_ch_buf = (char *)
+					/* Include room in for 2 EOB chars. */
+					yy_flex_realloc( (void *) b->yy_ch_buf,
+							 b->yy_buf_size + 2 );
+				}
+			else
+				/* Can't grow it, we don't own it. */
+				b->yy_ch_buf = 0;
+
+			if ( ! b->yy_ch_buf )
+				YY_FATAL_ERROR(
+				"fatal error - scanner input buffer overflow" );
+
+			yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset];
+
+			num_to_read = yy_current_buffer->yy_buf_size -
+						number_to_move - 1;
+#endif
+			}
+
+		if ( num_to_read > YY_READ_BUF_SIZE )
+			num_to_read = YY_READ_BUF_SIZE;
+
+		/* Read in more data. */
+		YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]),
+			yy_n_chars, num_to_read );
+
+		yy_current_buffer->yy_n_chars = yy_n_chars;
+		}
+
+	if ( yy_n_chars == 0 )
+		{
+		if ( number_to_move == YY_MORE_ADJ )
+			{
+			ret_val = EOB_ACT_END_OF_FILE;
+			yyrestart( yyin );
+			}
+
+		else
+			{
+			ret_val = EOB_ACT_LAST_MATCH;
+			yy_current_buffer->yy_buffer_status =
+				YY_BUFFER_EOF_PENDING;
+			}
+		}
+
+	else
+		ret_val = EOB_ACT_CONTINUE_SCAN;
+
+	yy_n_chars += number_to_move;
+	yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR;
+	yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
+
+	yytext_ptr = &yy_current_buffer->yy_ch_buf[0];
+
+	return ret_val;
+	}
+
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+static yy_state_type yy_get_previous_state()
+	{
+	register yy_state_type yy_current_state;
+	register char *yy_cp;
+
+	yy_current_state = yy_start;
+	yy_current_state += YY_AT_BOL();
+
+	for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp )
+		{
+		register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
+		if ( yy_accept[yy_current_state] )
+			{
+			yy_last_accepting_state = yy_current_state;
+			yy_last_accepting_cpos = yy_cp;
+			}
+		while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+			{
+			yy_current_state = (int) yy_def[yy_current_state];
+			if ( yy_current_state >= 485 )
+				yy_c = yy_meta[(unsigned int) yy_c];
+			}
+		yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+		}
+
+	return yy_current_state;
+	}
+
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ *	next_state = yy_try_NUL_trans( current_state );
+ */
+
+#ifdef YY_USE_PROTOS
+static yy_state_type yy_try_NUL_trans( yy_state_type yy_current_state )
+#else
+static yy_state_type yy_try_NUL_trans( yy_current_state )
+yy_state_type yy_current_state;
+#endif
+	{
+	register int yy_is_jam;
+	register char *yy_cp = yy_c_buf_p;
+
+	register YY_CHAR yy_c = 1;
+	if ( yy_accept[yy_current_state] )
+		{
+		yy_last_accepting_state = yy_current_state;
+		yy_last_accepting_cpos = yy_cp;
+		}
+	while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+		{
+		yy_current_state = (int) yy_def[yy_current_state];
+		if ( yy_current_state >= 485 )
+			yy_c = yy_meta[(unsigned int) yy_c];
+		}
+	yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+	yy_is_jam = (yy_current_state == 484);
+
+	return yy_is_jam ? 0 : yy_current_state;
+	}
+
+
+#ifndef YY_NO_UNPUT
+#ifdef YY_USE_PROTOS
+static void yyunput( int c, register char *yy_bp )
+#else
+static void yyunput( c, yy_bp )
+int c;
+register char *yy_bp;
+#endif
+	{
+	register char *yy_cp = yy_c_buf_p;
+
+	/* undo effects of setting up yytext */
+	*yy_cp = yy_hold_char;
+
+	if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
+		{ /* need to shift things up to make room */
+		/* +2 for EOB chars. */
+		register int number_to_move = yy_n_chars + 2;
+		register char *dest = &yy_current_buffer->yy_ch_buf[
+					yy_current_buffer->yy_buf_size + 2];
+		register char *source =
+				&yy_current_buffer->yy_ch_buf[number_to_move];
+
+		while ( source > yy_current_buffer->yy_ch_buf )
+			*--dest = *--source;
+
+		yy_cp += (int) (dest - source);
+		yy_bp += (int) (dest - source);
+		yy_current_buffer->yy_n_chars =
+			yy_n_chars = yy_current_buffer->yy_buf_size;
+
+		if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
+			YY_FATAL_ERROR( "flex scanner push-back overflow" );
+		}
+
+	*--yy_cp = (char) c;
+
+
+	yytext_ptr = yy_bp;
+	yy_hold_char = *yy_cp;
+	yy_c_buf_p = yy_cp;
+	}
+#endif	/* ifndef YY_NO_UNPUT */
+
+
+#ifdef __cplusplus
+static int yyinput()
+#else
+static int input()
+#endif
+	{
+	int c;
+
+	*yy_c_buf_p = yy_hold_char;
+
+	if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR )
+		{
+		/* yy_c_buf_p now points to the character we want to return.
+		 * If this occurs *before* the EOB characters, then it's a
+		 * valid NUL; if not, then we've hit the end of the buffer.
+		 */
+		if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] )
+			/* This was really a NUL. */
+			*yy_c_buf_p = '\0';
+
+		else
+			{ /* need more input */
+			int offset = yy_c_buf_p - yytext_ptr;
+			++yy_c_buf_p;
+
+			switch ( yy_get_next_buffer() )
+				{
+				case EOB_ACT_LAST_MATCH:
+					/* This happens because yy_g_n_b()
+					 * sees that we've accumulated a
+					 * token and flags that we need to
+					 * try matching the token before
+					 * proceeding.  But for input(),
+					 * there's no matching to consider.
+					 * So convert the EOB_ACT_LAST_MATCH
+					 * to EOB_ACT_END_OF_FILE.
+					 */
+
+					/* Reset buffer status. */
+					yyrestart( yyin );
+
+					/* fall through */
+
+				case EOB_ACT_END_OF_FILE:
+					{
+					if ( yywrap() )
+						return EOF;
+
+					if ( ! yy_did_buffer_switch_on_eof )
+						YY_NEW_FILE;
+#ifdef __cplusplus
+					return yyinput();
+#else
+					return input();
+#endif
+					}
+
+				case EOB_ACT_CONTINUE_SCAN:
+					yy_c_buf_p = yytext_ptr + offset;
+					break;
+				}
+			}
+		}
+
+	c = *(unsigned char *) yy_c_buf_p;	/* cast for 8-bit char's */
+	*yy_c_buf_p = '\0';	/* preserve yytext */
+	yy_hold_char = *++yy_c_buf_p;
+
+	yy_current_buffer->yy_at_bol = (c == '\n');
+
+	return c;
+	}
+
+
+#ifdef YY_USE_PROTOS
+void yyrestart( FILE *input_file )
+#else
+void yyrestart( input_file )
+FILE *input_file;
+#endif
+	{
+	if ( ! yy_current_buffer )
+		yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE );
+
+	yy_init_buffer( yy_current_buffer, input_file );
+	yy_load_buffer_state();
+	}
+
+
+#ifdef YY_USE_PROTOS
+void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer )
+#else
+void yy_switch_to_buffer( new_buffer )
+YY_BUFFER_STATE new_buffer;
+#endif
+	{
+	if ( yy_current_buffer == new_buffer )
+		return;
+
+	if ( yy_current_buffer )
+		{
+		/* Flush out information for old buffer. */
+		*yy_c_buf_p = yy_hold_char;
+		yy_current_buffer->yy_buf_pos = yy_c_buf_p;
+		yy_current_buffer->yy_n_chars = yy_n_chars;
+		}
+
+	yy_current_buffer = new_buffer;
+	yy_load_buffer_state();
+
+	/* We don't actually know whether we did this switch during
+	 * EOF (yywrap()) processing, but the only time this flag
+	 * is looked at is after yywrap() is called, so it's safe
+	 * to go ahead and always set it.
+	 */
+	yy_did_buffer_switch_on_eof = 1;
+	}
+
+
+#ifdef YY_USE_PROTOS
+void yy_load_buffer_state( void )
+#else
+void yy_load_buffer_state()
+#endif
+	{
+	yy_n_chars = yy_current_buffer->yy_n_chars;
+	yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos;
+	yyin = yy_current_buffer->yy_input_file;
+	yy_hold_char = *yy_c_buf_p;
+	}
+
+
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_create_buffer( FILE *file, int size )
+#else
+YY_BUFFER_STATE yy_create_buffer( file, size )
+FILE *file;
+int size;
+#endif
+	{
+	YY_BUFFER_STATE b;
+
+	b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) );
+	if ( ! b )
+		YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+	b->yy_buf_size = size;
+
+	/* yy_ch_buf has to be 2 characters longer than the size given because
+	 * we need to put in 2 end-of-buffer characters.
+	 */
+	b->yy_ch_buf = (char *) yy_flex_alloc( b->yy_buf_size + 2 );
+	if ( ! b->yy_ch_buf )
+		YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+	b->yy_is_our_buffer = 1;
+
+	yy_init_buffer( b, file );
+
+	return b;
+	}
+
+
+#ifdef YY_USE_PROTOS
+void yy_delete_buffer( YY_BUFFER_STATE b )
+#else
+void yy_delete_buffer( b )
+YY_BUFFER_STATE b;
+#endif
+	{
+	if ( ! b )
+		return;
+
+	if ( b == yy_current_buffer )
+		yy_current_buffer = (YY_BUFFER_STATE) 0;
+
+	if ( b->yy_is_our_buffer )
+		yy_flex_free( (void *) b->yy_ch_buf );
+
+	yy_flex_free( (void *) b );
+	}
+
+
+#ifndef YY_ALWAYS_INTERACTIVE
+#ifndef YY_NEVER_INTERACTIVE
+extern int isatty YY_PROTO(( int ));
+#endif
+#endif
+
+#ifdef YY_USE_PROTOS
+void yy_init_buffer( YY_BUFFER_STATE b, FILE *file )
+#else
+void yy_init_buffer( b, file )
+YY_BUFFER_STATE b;
+FILE *file;
+#endif
+
+
+	{
+	yy_flush_buffer( b );
+
+	b->yy_input_file = file;
+	b->yy_fill_buffer = 1;
+
+#if YY_ALWAYS_INTERACTIVE
+	b->yy_is_interactive = 1;
+#else
+#if YY_NEVER_INTERACTIVE
+	b->yy_is_interactive = 0;
+#else
+	b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
+#endif
+#endif
+	}
+
+
+#ifdef YY_USE_PROTOS
+void yy_flush_buffer( YY_BUFFER_STATE b )
+#else
+void yy_flush_buffer( b )
+YY_BUFFER_STATE b;
+#endif
+
+	{
+	if ( ! b )
+		return;
+
+	b->yy_n_chars = 0;
+
+	/* We always need two end-of-buffer characters.  The first causes
+	 * a transition to the end-of-buffer state.  The second causes
+	 * a jam in that state.
+	 */
+	b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+	b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+	b->yy_buf_pos = &b->yy_ch_buf[0];
+
+	b->yy_at_bol = 1;
+	b->yy_buffer_status = YY_BUFFER_NEW;
+
+	if ( b == yy_current_buffer )
+		yy_load_buffer_state();
+	}
+
+
+#ifndef YY_NO_SCAN_BUFFER
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_buffer( char *base, yy_size_t size )
+#else
+YY_BUFFER_STATE yy_scan_buffer( base, size )
+char *base;
+yy_size_t size;
+#endif
+	{
+	YY_BUFFER_STATE b;
+
+	if ( size < 2 ||
+	     base[size-2] != YY_END_OF_BUFFER_CHAR ||
+	     base[size-1] != YY_END_OF_BUFFER_CHAR )
+		/* They forgot to leave room for the EOB's. */
+		return 0;
+
+	b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) );
+	if ( ! b )
+		YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
+
+	b->yy_buf_size = size - 2;	/* "- 2" to take care of EOB's */
+	b->yy_buf_pos = b->yy_ch_buf = base;
+	b->yy_is_our_buffer = 0;
+	b->yy_input_file = 0;
+	b->yy_n_chars = b->yy_buf_size;
+	b->yy_is_interactive = 0;
+	b->yy_at_bol = 1;
+	b->yy_fill_buffer = 0;
+	b->yy_buffer_status = YY_BUFFER_NEW;
+
+	yy_switch_to_buffer( b );
+
+	return b;
+	}
+#endif
+
+
+#ifndef YY_NO_SCAN_STRING
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_string( yyconst char *yy_str )
+#else
+YY_BUFFER_STATE yy_scan_string( yy_str )
+yyconst char *yy_str;
+#endif
+	{
+	int len;
+	for ( len = 0; yy_str[len]; ++len )
+		;
+
+	return yy_scan_bytes( yy_str, len );
+	}
+#endif
+
+
+#ifndef YY_NO_SCAN_BYTES
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_bytes( yyconst char *bytes, int len )
+#else
+YY_BUFFER_STATE yy_scan_bytes( bytes, len )
+yyconst char *bytes;
+int len;
+#endif
+	{
+	YY_BUFFER_STATE b;
+	char *buf;
+	yy_size_t n;
+	int i;
+
+	/* Get memory for full buffer, including space for trailing EOB's. */
+	n = len + 2;
+	buf = (char *) yy_flex_alloc( n );
+	if ( ! buf )
+		YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
+
+	for ( i = 0; i < len; ++i )
+		buf[i] = bytes[i];
+
+	buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR;
+
+	b = yy_scan_buffer( buf, n );
+	if ( ! b )
+		YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
+
+	/* It's okay to grow etc. this buffer, and we should throw it
+	 * away when we're done.
+	 */
+	b->yy_is_our_buffer = 1;
+
+	return b;
+	}
+#endif
+
+
+#ifndef YY_NO_PUSH_STATE
+#ifdef YY_USE_PROTOS
+static void yy_push_state( int new_state )
+#else
+static void yy_push_state( new_state )
+int new_state;
+#endif
+	{
+	if ( yy_start_stack_ptr >= yy_start_stack_depth )
+		{
+		yy_size_t new_size;
+
+		yy_start_stack_depth += YY_START_STACK_INCR;
+		new_size = yy_start_stack_depth * sizeof( int );
+
+		if ( ! yy_start_stack )
+			yy_start_stack = (int *) yy_flex_alloc( new_size );
+
+		else
+			yy_start_stack = (int *) yy_flex_realloc(
+					(void *) yy_start_stack, new_size );
+
+		if ( ! yy_start_stack )
+			YY_FATAL_ERROR(
+			"out of memory expanding start-condition stack" );
+		}
+
+	yy_start_stack[yy_start_stack_ptr++] = YY_START;
+
+	BEGIN(new_state);
+	}
+#endif
+
+
+#ifndef YY_NO_POP_STATE
+static void yy_pop_state()
+	{
+	if ( --yy_start_stack_ptr < 0 )
+		YY_FATAL_ERROR( "start-condition stack underflow" );
+
+	BEGIN(yy_start_stack[yy_start_stack_ptr]);
+	}
+#endif
+
+
+#ifndef YY_NO_TOP_STATE
+static int yy_top_state()
+	{
+	return yy_start_stack[yy_start_stack_ptr - 1];
+	}
+#endif
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+#ifdef YY_USE_PROTOS
+static void yy_fatal_error( yyconst char msg[] )
+#else
+static void yy_fatal_error( msg )
+char msg[];
+#endif
+	{
+	(void) fprintf( stderr, "%s\n", msg );
+	exit( YY_EXIT_FAILURE );
+	}
+
+
+
+/* Redefine yyless() so it works in section 3 code. */
+
+#undef yyless
+#define yyless(n) \
+	do \
+		{ \
+		/* Undo effects of setting up yytext. */ \
+		yytext[yyleng] = yy_hold_char; \
+		yy_c_buf_p = yytext + n; \
+		yy_hold_char = *yy_c_buf_p; \
+		*yy_c_buf_p = '\0'; \
+		yyleng = n; \
+		} \
+	while ( 0 )
+
+
+/* Internal utility routines. */
+
+#ifndef yytext_ptr
+#ifdef YY_USE_PROTOS
+static void yy_flex_strncpy( char *s1, yyconst char *s2, int n )
+#else
+static void yy_flex_strncpy( s1, s2, n )
+char *s1;
+yyconst char *s2;
+int n;
+#endif
+	{
+	register int i;
+	for ( i = 0; i < n; ++i )
+		s1[i] = s2[i];
+	}
+#endif
+
+#ifdef YY_NEED_STRLEN
+#ifdef YY_USE_PROTOS
+static int yy_flex_strlen( yyconst char *s )
+#else
+static int yy_flex_strlen( s )
+yyconst char *s;
+#endif
+	{
+	register int n;
+	for ( n = 0; s[n]; ++n )
+		;
+
+	return n;
+	}
+#endif
+
+
+#ifdef YY_USE_PROTOS
+static void *yy_flex_alloc( yy_size_t size )
+#else
+static void *yy_flex_alloc( size )
+yy_size_t size;
+#endif
+	{
+	return (void *) malloc( size );
+	}
+
+#ifdef YY_USE_PROTOS
+static void *yy_flex_realloc( void *ptr, yy_size_t size )
+#else
+static void *yy_flex_realloc( ptr, size )
+void *ptr;
+yy_size_t size;
+#endif
+	{
+	/* The cast to (char *) in the following accommodates both
+	 * implementations that use char* generic pointers, and those
+	 * that use void* generic pointers.  It works with the latter
+	 * because both ANSI C and C++ allow castless assignment from
+	 * any pointer type to void*, and deal with argument conversions
+	 * as though doing an assignment.
+	 */
+	return (void *) realloc( (char *) ptr, size );
+	}
+
+#ifdef YY_USE_PROTOS
+static void yy_flex_free( void *ptr )
+#else
+static void yy_flex_free( ptr )
+void *ptr;
+#endif
+	{
+	free( ptr );
+	}
+
+#if YY_MAIN
+int main()
+	{
+	yylex();
+	return 0;
+	}
+#endif
+#line 804 "libparse.l"
+
+
+int current_pos(int i)
+{
+  return(i+offset+(int)(yytext-yylp_buffer_start));
+}
+
+int libread(FILE* f, char* buf, int max_size)
+{ int rc;
+
+  offset = ftell(f);
+  rc  = myfread( buf, 1, max_size, f );
+  #if YYLPDEBUG >2
+    printf("fread: %d of %d\n", rc, max_size);
+  #endif
+  yylp_buffer_start = buf;
+  return rc;
+}
+
+extern "C" {
+  int yylpwrap()
+  {
+    //printf("======================= YYWRAP ====================\n");
+    if(brace1>0) { yylp_errno=YYLP_MISS_BR1; }
+    if(brace2>0) { yylp_errno=YYLP_MISS_BR2; }
+    if(brace3>0) { yylp_errno=YYLP_MISS_BR3; }
+    if(quote>0) { yylp_errno=YYLP_MISSQUOT; }
+    //printf("{=%d, (=%d, [=%d\n", brace1, brace2, brace3);
+    if(feof(yyin)) return 1; else return 0;
+  }
+}
+
+void reinit_yylp()
+{
+   brace1 = 0;
+   brace2 = 0;
+   brace3 = 0;
+   quote  = 0;
+   yy_init=1;
+   yy_delete_buffer(YY_CURRENT_BUFFER);
+}
+
+void make_version(char *p,int what)
+{
+  char ver[10];
+  char date[16];
+  ver[0]='?'; ver[1]='.'; ver[2]='?'; ver[3]='\0';
+  date[0]='?'; date[1]='\0';
+  if(what) sscanf(p,"%*[^=]= %*s %*s %10s %16s",ver,date);
+  else sscanf(p,"// %*s %*s %10s %16s",ver,date);
+  strcpy(libnamebuf,"(");
+  strcat(libnamebuf,ver);
+  strcat(libnamebuf,",");
+  strcat(libnamebuf,date);
+  strcat(libnamebuf,")");
+  if(what && strcmp(libnamebuf, "(?.?,?)")==0)
+  {
+    sscanf(p,"%*[^\"]\"%[^\"]\"",libnamebuf);
+  }
+  //printf("ID=(%d)%s; \n", what, p);
+}
+
+void copy_string(lp_modes mode)
+{
+#ifdef STANDALONE_PARSER
+  if ((texinfo_out
+     && (last_cmd == LP_INFO || last_cmd == LP_CATEGORY || last_cmd == LP_URL))
+  || (category_out && last_cmd == LP_CATEGORY)
+)
+  {
+    long current_location = ftell(yylpin), i = string_start, quote = 0;
+    char c;
+    if (texinfo_out)
+    {
+     if (last_cmd == LP_INFO)
+     {
+       printf("$info = <<EOT;\n");
+     }
+     else if (last_cmd == LP_URL)
+     {
+       printf("$url = <<EOT;\n");
+     }
+     else
+     {
+       printf("$category = <<EOT;\n");
+     }
+    }
+    fseek (yylpin, i, SEEK_SET);
+    while (i< current_location)
+    {
+      c = fgetc(yylpin);
+      if (c == '\\')
+      {
+        quote = (! quote);
+      }
+      else if (c == '"')
+      {
+        if (! quote) break;
+      }
+      else
+        quote = 0;
+      if (c == '@' || c == '$') putchar('\\');
+      if (c != '\r') putchar(c);
+      i++;
+    }
+    if (category_out) exit(0);
+    fseek (yylpin, current_location, SEEK_SET);
+    printf("\nEOT\n");
+  }
+#else
+  if((last_cmd == LP_INFO)&&(mode == GET_INFO))
+  {
+    int i, offset=0;
+    long current_location = ftell(yylpin);
+    int len = (int)(current_pos(0) - string_start);
+    fseek(yylpin, string_start, SEEK_SET);
+    if (text_buffer!=NULL) omFree((ADDRESS)text_buffer);
+    text_buffer = (char *)omAlloc(len+2);
+    omMarkAsStaticAddr(text_buffer);
+    myfread(text_buffer, len, 1, yylpin);
+    fseek(yylpin, current_location, SEEK_SET);
+    text_buffer[len]='\0';
+    offset=0;
+    for(i=0;i<=len; i++)
+    {
+      if(text_buffer[i]=='\\' &&
+         (text_buffer[i+1]=='\"' || text_buffer[i+1]=='{' ||
+          text_buffer[i+1]=='}' || text_buffer[i+1]=='\\'))
+      {
+        i++;
+        offset++;
+      }
+      if(offset>0) text_buffer[i-offset] = text_buffer[i];
+    }
+  }
+#endif /* STANDALONE_PARSER */
+}
+
+void print_init()
+{
+   printf("Init=%d\n", yy_init);
+}
+
+void print_version(lp_modes mode, char *p)
+{
+#ifdef STANDALONE_PARSER
+  //printf("loading %s%s", p, libnamebuf);
+#else
+  if ( mode == LOAD_LIB )
+  {
+    if (BVERBOSE(V_LOAD_LIB) && p!=NULL ) Print(" %s...", p);
+       //Warn( "loading %s%s", p, libnamebuf);
+  }
+#endif
+}
+
+#ifdef STANDALONE_PARSER
+int main( int argc, char *argv[] )
+{
+  lib_style_types lib_style;
+  main_init(argc, argv);
+  if(yyin == NULL)
+  {
+    fprintf(stderr, "No library found to parse.\n");
+    return 1;
+  }
+  if (! (texinfo_out || category_out))
+  {
+    if(lpverbose)printf("Verbose level=%d\n", lpverbose);
+    if(check)printf("Reporting most possible annomalies.\n");
+    if(lpverbose||check)printf("\n");
+
+    printf( "  %-15s  %20s      %s,%s    %s,%s     %s,%s\n", "Library",
+            "function", "line", "start-eod", "line", "body-eob",
+            "line", "example-eoe");
+  }
+  yylplex(argv[0], argv[0], &lib_style,NULL);
+  if(yylp_errno)
+  {
+    printf("ERROR occured: [%d] ", yylp_errno);
+    printf(yylp_errlist[yylp_errno], yylplineno);
+    printf("\n");
+  }
+  else if(pi!=NULL) printpi(pi);
+  if (texinfo_out)
+    printf("1;");
+  return 0;
+}
+
+#endif /* STANDALONE_PARSER */
+#endif /* HAVE_LIBPARSE */
diff --git a/Singular/libparse.h b/Singular/libparse.h
new file mode 100644
index 0000000..1ee0fcd
--- /dev/null
+++ b/Singular/libparse.h
@@ -0,0 +1,111 @@
+#ifndef LIBPARSE_H
+#define LIBPARSE_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: lib parsing
+*/
+typedef enum { OLD_LIBSTYLE, NEW_LIBSTYLE } lib_style_types;
+typedef enum { LOAD_LIB, GET_INFO } lp_modes;
+
+#ifdef STANDALONE_PARSER
+
+
+#define idhdl void*
+#define leftv void*
+#define package void*
+#define BOOLEAN int
+
+typedef enum { LANG_NONE, LANG_TOP, LANG_SINGULAR, LANG_C, LANG_MAX} language_defs;
+// LANG_TOP     : Toplevel package only
+// LANG_SINGULAR:
+// LANG_C       :
+//
+
+class proc_singular
+{
+public:
+  long   proc_start;       // position where proc is starting
+  long   def_end;          // position where proc header is ending
+  long   help_start;       // position where help is starting
+  long   help_end;         // position where help is starting
+  long   body_start;       // position where proc-body is starting
+  long   body_end;         // position where proc-body is ending
+  long   example_start;    // position where example is starting
+  long   proc_end;         // position where proc is ending
+  int    proc_lineno;
+  int    body_lineno;
+  int    example_lineno;
+  char   *body;
+  long help_chksum;
+};
+
+struct proc_object
+{
+//public:
+  BOOLEAN (*function)(leftv res, leftv v);
+};
+union uprocinfodata
+{
+public:
+  proc_singular  s;        // data of Singular-procedure
+  struct proc_object    o; // pointer to binary-function
+};
+
+typedef union uprocinfodata procinfodata;
+
+class procinfo;
+typedef procinfo *         procinfov;
+
+class procinfo
+{
+public:
+  char          *libname;
+  char          *procname;
+  package       pack;
+  language_defs language;
+  short         ref;
+  char          is_static;        // if set, proc not accessible for user
+  char          trace_flag;
+  procinfodata  data;
+};
+#endif
+
+procinfo *iiInitSingularProcinfo(procinfo* pi, const char *libname,
+              const char *procname, int line, long pos, BOOLEAN pstatic=FALSE);
+
+int yylplex(const char *libname, const char *libfile, lib_style_types *lib_style,
+           idhdl pl, BOOLEAN autoexport=FALSE, lp_modes=LOAD_LIB);
+
+void reinit_yylp();
+
+extern char * text_buffer;
+
+#  define YYLP_ERR_NONE    0
+#  define YYLP_DEF_BR2     1
+#  define YYLP_BODY_BR2    2
+#  define YYLP_BODY_BR3    3
+#  define YYLP_BODY_TMBR2  4
+#  define YYLP_BODY_TMBR3  5
+#  define YYLP_EX_BR2      6
+#  define YYLP_EX_BR3      7
+#  define YYLP_BAD_CHAR    8
+#  define YYLP_MISSQUOT    9
+#  define YYLP_MISS_BR1   10
+#  define YYLP_MISS_BR2   11
+#  define YYLP_MISS_BR3   12
+
+#  ifdef STANDALONE_PARSER
+#ifndef unix
+extern FILE* myfopen(char *path, char *mode);
+extern size_t myfread(void *ptr, size_t size, size_t nmemb, FILE *stream);
+#else
+#define myfopen fopen
+#define myfread fread
+#endif
+#  endif
+
+#endif /* LIBPARSE_H */
+
+
diff --git a/Singular/libsingular.h b/Singular/libsingular.h
new file mode 100644
index 0000000..aa17fc3
--- /dev/null
+++ b/Singular/libsingular.h
@@ -0,0 +1,35 @@
+#ifndef LIBSINGULAR__H
+#define LIBSINGULAR__H
+
+#include <math.h> // Why this?
+
+#include <misc/auxiliary.h>
+#include <kernel/structs.h>
+#include <kernel/polys.h>
+#include <coeffs/numbers.h>
+#include <kernel/oswrapper/feread.h>
+#include <polys/monomials/ring.h>
+#include <omalloc/omalloc.h>
+#include <polys/clapsing.h>
+#include <polys/monomials/maps.h>
+#include <kernel/GBEngine/kutil.h>
+#include <kernel/GBEngine/kstd1.h>
+#include <kernel/GBEngine/tgb.h>
+#include <polys/sparsmat.h>
+
+#include <Singular/subexpr.h>
+#include <Singular/tok.h>
+#include <Singular/grammar.h>
+#include <Singular/ipid.h>
+#include <Singular/ipshell.h>
+#include <Singular/attrib.h>
+#include <misc/options.h>
+
+void siInit(char *);
+
+/* we need this function in Sage*/
+number nr2mMapZp(number from); // TODO: replace with something else...
+
+
+#endif // #ifndef LIBSINGULAR__H
+
diff --git a/Singular/linearAlgebra_ip.cc b/Singular/linearAlgebra_ip.cc
new file mode 100644
index 0000000..b0c1faa
--- /dev/null
+++ b/Singular/linearAlgebra_ip.cc
@@ -0,0 +1,105 @@
+
+
+
+#include <kernel/mod2.h>
+#include <Singular/lists.h>
+#include <kernel/linear_algebra/linearAlgebra.h>
+
+/**
+ * Computes all eigenvalues of a given real quadratic matrix with
+ * multiplicites.
+ *
+ * The method assumes that the current ground field is the complex numbers.
+ * Computations are based on the QR double shift algorithm involving
+ * Hessenberg form and householder transformations.
+ * If the algorithm works, then it returns a list with two entries which
+ * are again lists of the same size:
+ * _[1][i] is the i-th mutually distinct eigenvalue that was found,
+ * _[2][i] is the (int) multiplicity of _[1][i].
+ * If the algorithm does not work (due to an ill-posed matrix), a list with
+ * the single entry (int)0 is returned.
+ * 'tol1' is used for detection of deflation in the actual qr double shift
+ * algorithm.
+ * 'tol2' is used for ending Heron's iteration whenever square roots
+ * are being computed.
+ * 'tol3' is used to distinguish between distinct eigenvalues: When
+ * the Euclidean distance between two computed eigenvalues is less then
+ * tol3, then they will be regarded equal, resulting in a higher
+ * multiplicity of the corresponding eigenvalue.
+ *
+ * @return a list with one entry (int)0, or two entries which are again lists
+ **/
+lists qrDoubleShift(
+       const matrix A,     /**< [in]  the quadratic matrix         */
+       const number tol1,  /**< [in]  tolerance for deflation      */
+       const number tol2,  /**< [in]  tolerance for square roots   */
+       const number tol3,   /**< [in]  tolerance for distinguishing
+                                      eigenvalues                  */
+       const ring r= currRing
+                   );
+
+lists qrDoubleShift(const matrix A, const number tol1, const number tol2,
+                    const number tol3, const ring R)
+{
+  int n = MATROWS(A);
+  matrix* queue = new matrix[n];
+  queue[0] = mp_Copy(A,R); int queueL = 1;
+  number* eigenVs = new number[n]; int eigenL = 0;
+  /* here comes the main call: */
+  bool worked = qrDS(n, queue, queueL, eigenVs, eigenL, tol1, tol2,R);
+  lists result = (lists)omAlloc(sizeof(slists));
+  if (!worked)
+  {
+    for (int i = 0; i < eigenL; i++)
+      nDelete(&eigenVs[i]);
+    delete [] eigenVs;
+    for (int i = 0; i < queueL; i++)
+      idDelete((ideal*)&queue[i]);
+    delete [] queue;
+    result->Init(1);
+    result->m[0].rtyp = INT_CMD;
+    result->m[0].data = (void*)0;   /* a list with a single entry
+                                             which is the int zero */
+  }
+  else
+  {
+    /* now eigenVs[0..eigenL-1] contain all eigenvalues; among them, there
+       may be equal entries */
+    number* distinctEVs = new number[n]; int distinctC = 0;
+    int* mults = new int[n];
+    for (int i = 0; i < eigenL; i++)
+    {
+      int index = similar(distinctEVs, distinctC, eigenVs[i], tol3);
+      if (index == -1) /* a new eigenvalue */
+      {
+        distinctEVs[distinctC] = nCopy(eigenVs[i]);
+        mults[distinctC++] = 1;
+      }
+      else mults[index]++;
+      nDelete(&eigenVs[i]);
+    }
+    delete [] eigenVs;
+
+    lists eigenvalues = (lists)omAlloc(sizeof(slists));
+    eigenvalues->Init(distinctC);
+    lists multiplicities = (lists)omAlloc(sizeof(slists));
+    multiplicities->Init(distinctC);
+    for (int i = 0; i < distinctC; i++)
+    {
+      eigenvalues->m[i].rtyp = NUMBER_CMD;
+      eigenvalues->m[i].data = (void*)nCopy(distinctEVs[i]);
+      multiplicities->m[i].rtyp = INT_CMD;
+      multiplicities->m[i].data = (void*)(long)mults[i];
+      nDelete(&distinctEVs[i]);
+    }
+    delete [] distinctEVs; delete [] mults;
+
+    result->Init(2);
+    result->m[0].rtyp = LIST_CMD;
+    result->m[0].data = (char*)eigenvalues;
+    result->m[1].rtyp = LIST_CMD;
+    result->m[1].data = (char*)multiplicities;
+  }
+  return result;
+}
+
diff --git a/Singular/linearAlgebra_ip.h b/Singular/linearAlgebra_ip.h
new file mode 100644
index 0000000..07bf542
--- /dev/null
+++ b/Singular/linearAlgebra_ip.h
@@ -0,0 +1,38 @@
+#ifndef LINEARALGEBRA_H
+#define LINEARALGEBRA_H
+#include <Singular/lists.h>
+#include <kernel/linear_algebra/linearAlgebra.h>
+
+/**
+ * Computes all eigenvalues of a given real quadratic matrix with
+ * multiplicites.
+ *
+ * The method assumes that the current ground field is the complex numbers.
+ * Computations are based on the QR double shift algorithm involving
+ * Hessenberg form and householder transformations.
+ * If the algorithm works, then it returns a list with two entries which
+ * are again lists of the same size:
+ * _[1][i] is the i-th mutually distinct eigenvalue that was found,
+ * _[2][i] is the (int) multiplicity of _[1][i].
+ * If the algorithm does not work (due to an ill-posed matrix), a list with
+ * the single entry (int)0 is returned.
+ * 'tol1' is used for detection of deflation in the actual qr double shift
+ * algorithm.
+ * 'tol2' is used for ending Heron's iteration whenever square roots
+ * are being computed.
+ * 'tol3' is used to distinguish between distinct eigenvalues: When
+ * the Euclidean distance between two computed eigenvalues is less then
+ * tol3, then they will be regarded equal, resulting in a higher
+ * multiplicity of the corresponding eigenvalue.
+ *
+ * @return a list with one entry (int)0, or two entries which are again lists
+ **/
+lists qrDoubleShift(
+       const matrix A,     /**< [in]  the quadratic matrix         */
+       const number tol1,  /**< [in]  tolerance for deflation      */
+       const number tol2,  /**< [in]  tolerance for square roots   */
+       const number tol3,   /**< [in]  tolerance for distinguishing
+                                      eigenvalues                  */
+       const ring r= currRing
+                   );
+#endif
diff --git a/Singular/links/asciiLink.cc b/Singular/links/asciiLink.cc
new file mode 100644
index 0000000..a19f415
--- /dev/null
+++ b/Singular/links/asciiLink.cc
@@ -0,0 +1,503 @@
+/****************************************
+ * *  Computer Algebra System SINGULAR     *
+ * ****************************************/
+
+/*
+ * ABSTRACT: ascii links (standard)
+ */
+
+#include <kernel/mod2.h>
+#include <misc/options.h>
+#include <omalloc/omalloc.h>
+
+#include <Singular/tok.h>
+#include <Singular/subexpr.h>
+#include <Singular/ipshell.h>
+#include <Singular/ipid.h>
+#include <Singular/fevoices.h>
+#include <kernel/oswrapper/feread.h>
+#include <Singular/ipshell.h>
+#include <Singular/links/silink.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+/* declarations */
+static BOOLEAN DumpAscii(FILE *fd, idhdl h);
+static BOOLEAN DumpAsciiIdhdl(FILE *fd, idhdl h);
+static const char* GetIdString(idhdl h);
+static int DumpRhs(FILE *fd, idhdl h);
+static BOOLEAN DumpQring(FILE *fd, idhdl h, const char *type_str);
+static BOOLEAN DumpAsciiMaps(FILE *fd, idhdl h, idhdl rhdl);
+
+extern si_link_extension si_link_root;
+
+/* =============== ASCII ============================================= */
+BOOLEAN slOpenAscii(si_link l, short flag, leftv /*h*/)
+{
+  const char *mode;
+  if (flag & SI_LINK_OPEN)
+  {
+    if (l->mode[0] != '\0' && (strcmp(l->mode, "r") == 0))
+      flag = SI_LINK_READ;
+    else flag = SI_LINK_WRITE;
+  }
+
+  if (flag == SI_LINK_READ) mode = "r";
+  else if (strcmp(l->mode, "w") == 0) mode = "w";
+  else mode = "a";
+
+
+  if (l->name[0] == '\0')
+  {
+    // stdin or stdout
+    if (flag == SI_LINK_READ)
+    {
+      l->data = (void *) stdin;
+      mode = "r";
+    }
+    else
+    {
+      l->data = (void *) stdout;
+      mode = "a";
+    }
+  }
+  else
+  {
+    // normal ascii link to a file
+    FILE *outfile;
+    char *filename=l->name;
+
+    if(filename[0]=='>')
+    {
+      if (filename[1]=='>')
+      {
+        filename+=2;
+        mode = "a";
+      }
+      else
+      {
+        filename++;
+        mode="w";
+      }
+    }
+    outfile=myfopen(filename,mode);
+    if (outfile!=NULL)
+      l->data = (void *) outfile;
+    else
+      return TRUE;
+  }
+
+  omFree(l->mode);
+  l->mode = omStrDup(mode);
+  SI_LINK_SET_OPEN_P(l, flag);
+  return FALSE;
+}
+
+BOOLEAN slCloseAscii(si_link l)
+{
+  SI_LINK_SET_CLOSE_P(l);
+  if (l->name[0] != '\0')
+  {
+    return (fclose((FILE *)l->data)!=0);
+  }
+  return FALSE;
+}
+
+leftv slReadAscii2(si_link l, leftv pr)
+{
+  FILE * fp=(FILE *)l->data;
+  char * buf=NULL;
+  if (fp!=NULL && l->name[0] != '\0')
+  {
+    fseek(fp,0L,SEEK_END);
+    long len=ftell(fp);
+    fseek(fp,0L,SEEK_SET);
+    buf=(char *)omAlloc((int)len+1);
+    if (BVERBOSE(V_READING))
+      Print("//Reading %ld chars\n",len);
+    myfread( buf, len, 1, fp);
+    buf[len]='\0';
+  }
+  else
+  {
+    if (pr->Typ()==STRING_CMD)
+    {
+      buf=(char *)omAlloc(80);
+      fe_fgets_stdin((char *)pr->Data(),buf,80);
+    }
+    else
+    {
+      WerrorS("read(<link>,<string>) expected");
+      buf=omStrDup("");
+    }
+  }
+  leftv v=(leftv)omAlloc0Bin(sleftv_bin);
+  v->rtyp=STRING_CMD;
+  v->data=buf;
+  return v;
+}
+
+leftv slReadAscii(si_link l)
+{
+  sleftv tmp;
+  memset(&tmp,0,sizeof(sleftv));
+  tmp.rtyp=STRING_CMD;
+  tmp.data=(void*) "? ";
+  return slReadAscii2(l,&tmp);
+}
+
+BOOLEAN slWriteAscii(si_link l, leftv v)
+{
+  FILE *outfile=(FILE *)l->data;
+  BOOLEAN err=FALSE;
+  char *s;
+  while (v!=NULL)
+  {
+    s = v->String();
+    // free v ??
+    if (s!=NULL)
+    {
+      fprintf(outfile,"%s\n",s);
+      omFree((ADDRESS)s);
+    }
+    else
+    {
+      Werror("cannot convert to string");
+      err=TRUE;
+    }
+    v = v->next;
+  }
+  fflush(outfile);
+  return err;
+}
+
+const char* slStatusAscii(si_link l, const char* request)
+{
+  if (strcmp(request, "read") == 0)
+  {
+    if (SI_LINK_R_OPEN_P(l)) return "ready";
+    else return "not ready";
+  }
+  else if (strcmp(request, "write") == 0)
+  {
+    if (SI_LINK_W_OPEN_P(l)) return "ready";
+    else return "not ready";
+  }
+  else return "unknown status request";
+}
+
+/*------------------ Dumping in Ascii format -----------------------*/
+
+BOOLEAN slDumpAscii(si_link l)
+{
+  FILE *fd = (FILE *) l->data;
+  idhdl h = IDROOT, rh = currRingHdl;
+  BOOLEAN status = DumpAscii(fd, h);
+
+  if (! status ) status = DumpAsciiMaps(fd, h, NULL);
+
+  if (currRingHdl != rh) rSetHdl(rh);
+  fprintf(fd, "option(set, intvec(%d, %d));\n", si_opt_1, si_opt_2);
+  fprintf(fd, "RETURN();\n");
+  fflush(fd);
+
+  return status;
+}
+
+// we do that recursively, to dump ids in the the order in which they
+// were actually defined
+static BOOLEAN DumpAscii(FILE *fd, idhdl h)
+{
+  if (h == NULL) return FALSE;
+
+  if (DumpAscii(fd, IDNEXT(h))) return TRUE;
+
+  // need to set the ring before writing it, otherwise we get in
+  // trouble with minpoly
+  if (IDTYP(h) == RING_CMD || IDTYP(h) == QRING_CMD)
+    rSetHdl(h);
+
+  if (DumpAsciiIdhdl(fd, h)) return TRUE;
+
+  if (IDTYP(h) == RING_CMD || IDTYP(h) == QRING_CMD)
+    return DumpAscii(fd, IDRING(h)->idroot);
+  else
+    return FALSE;
+}
+
+static BOOLEAN DumpAsciiMaps(FILE *fd, idhdl h, idhdl rhdl)
+{
+  if (h == NULL) return FALSE;
+  if (DumpAsciiMaps(fd, IDNEXT(h), rhdl)) return TRUE;
+
+  if (IDTYP(h) == RING_CMD || IDTYP(h) == QRING_CMD)
+    return DumpAsciiMaps(fd, IDRING(h)->idroot, h);
+  else if (IDTYP(h) == MAP_CMD)
+  {
+    char *rhs;
+    rSetHdl(rhdl);
+    rhs = h->String();
+
+    if (fprintf(fd, "setring %s;\n", IDID(rhdl)) == EOF) return TRUE;
+    if (fprintf(fd, "%s %s = %s, %s;\n", Tok2Cmdname(MAP_CMD), IDID(h),
+                IDMAP(h)->preimage, rhs) == EOF)
+    {
+      omFree(rhs);
+      return TRUE;
+    }
+    else
+    {
+      omFree(rhs);
+      return FALSE;
+    }
+  }
+  else return FALSE;
+}
+
+static BOOLEAN DumpAsciiIdhdl(FILE *fd, idhdl h)
+{
+  const char *type_str = GetIdString(h);
+  int type_id = IDTYP(h);
+
+  if ((type_id == PACKAGE_CMD) &&(strcmp(IDID(h), "Top") == 0))
+    return FALSE;
+
+  // we do not throw an error if a wrong type was attempted to be dumped
+  if (type_str == NULL)
+    return FALSE;
+
+  // handle qrings separately
+  if (type_id == QRING_CMD)
+    return DumpQring(fd, h, type_str);
+
+  // C-proc not to be dumped
+  if ((type_id == PROC_CMD) && (IDPROC(h)->language == LANG_C))
+    return FALSE;
+
+  // put type and name
+  if (fprintf(fd, "%s %s", type_str, IDID(h)) == EOF)
+    return TRUE;
+  // for matricies, append the dimension
+  if (type_id == MATRIX_CMD)
+  {
+    ideal id = IDIDEAL(h);
+    if (fprintf(fd, "[%d][%d]", id->nrows, id->ncols)== EOF) return TRUE;
+  }
+  else if (type_id == INTMAT_CMD)
+  {
+    if (fprintf(fd, "[%d][%d]", IDINTVEC(h)->rows(), IDINTVEC(h)->cols())
+        == EOF) return TRUE;
+  }
+
+  if (type_id == PACKAGE_CMD)
+  {
+    return (fprintf(fd, ";\n") == EOF);
+  }
+
+  // write the equal sign
+  if (fprintf(fd, " = ") == EOF) return TRUE;
+
+  // and the right hand side
+  if (DumpRhs(fd, h) == EOF) return TRUE;
+
+  // semicolon und tschuess
+  if (fprintf(fd, ";\n") == EOF) return TRUE;
+
+  return FALSE;
+}
+
+static const char* GetIdString(idhdl h)
+{
+  int type = IDTYP(h);
+
+  switch(type)
+  {
+      case LIST_CMD:
+      {
+        lists l = IDLIST(h);
+        int i, nl = l->nr + 1;
+
+        for (i=0; i<nl; i++)
+          if (GetIdString((idhdl) &(l->m[i])) == NULL) return NULL;
+      }
+      case PACKAGE_CMD:
+      case INT_CMD:
+      case INTVEC_CMD:
+      case INTMAT_CMD:
+      case STRING_CMD:
+      case RING_CMD:
+      case QRING_CMD:
+      case PROC_CMD:
+      case NUMBER_CMD:
+      case POLY_CMD:
+      case IDEAL_CMD:
+      case VECTOR_CMD:
+      case MODUL_CMD:
+      case MATRIX_CMD:
+        return Tok2Cmdname(type);
+
+      case MAP_CMD:
+      case LINK_CMD:
+        return NULL;
+
+      default:
+       Warn("Error dump data of type %s", Tok2Cmdname(IDTYP(h)));
+       return NULL;
+  }
+}
+
+static BOOLEAN DumpQring(FILE *fd, idhdl h, const char *type_str)
+{
+  char *ring_str = h->String();
+  if (fprintf(fd, "%s temp_ring = %s;\n", Tok2Cmdname(RING_CMD), ring_str)
+              == EOF) return TRUE;
+  if (fprintf(fd, "%s temp_ideal = %s;\n", Tok2Cmdname(IDEAL_CMD),
+              iiStringMatrix((matrix) IDRING(h)->qideal, 1, currRing, n_GetChar(currRing->cf)))
+      == EOF) return TRUE;
+  if (fprintf(fd, "attrib(temp_ideal, \"isSB\", 1);\n") == EOF) return TRUE;
+  if (fprintf(fd, "%s %s = temp_ideal;\n", type_str, IDID(h)) == EOF)
+    return TRUE;
+  if (fprintf(fd, "kill temp_ring;\n") == EOF) return TRUE;
+  else
+  {
+    omFree(ring_str);
+    return FALSE;
+  }
+}
+
+
+static int DumpRhs(FILE *fd, idhdl h)
+{
+  int type_id = IDTYP(h);
+
+  if (type_id == LIST_CMD)
+  {
+    lists l = IDLIST(h);
+    int i, nl = l->nr;
+
+    fprintf(fd, "list(");
+
+    for (i=0; i<nl; i++)
+    {
+      if (DumpRhs(fd, (idhdl) &(l->m[i])) == EOF) return EOF;
+      fprintf(fd, ",");
+    }
+    if (nl > 0)
+    {
+      if (DumpRhs(fd, (idhdl) &(l->m[nl])) == EOF) return EOF;
+    }
+    fprintf(fd, ")");
+  }
+  else  if (type_id == STRING_CMD)
+  {
+    char *pstr = IDSTRING(h);
+    fputc('"', fd);
+    while (*pstr != '\0')
+    {
+      if (*pstr == '"' || *pstr == '\\')  fputc('\\', fd);
+      fputc(*pstr, fd);
+      pstr++;
+    }
+    fputc('"', fd);
+  }
+  else  if (type_id == PROC_CMD)
+  {
+    procinfov pi = IDPROC(h);
+    if (pi->language == LANG_SINGULAR)
+    {
+      if( pi->data.s.body==NULL) iiGetLibProcBuffer(pi);
+      char *pstr = pi->data.s.body;
+      fputc('"', fd);
+      while (*pstr != '\0')
+      {
+        if (*pstr == '"' || *pstr == '\\') fputc('\\', fd);
+        fputc(*pstr, fd);
+        pstr++;
+      }
+      fputc('"', fd);
+    }
+    else fputs("(null)", fd);
+  }
+  else
+  {
+    char *rhs = h->String();
+
+    if (rhs == NULL) return EOF;
+
+    BOOLEAN need_klammer=FALSE;
+    if (type_id == INTVEC_CMD) { fprintf(fd, "intvec(");need_klammer=TRUE; }
+    else if (type_id == IDEAL_CMD) { fprintf(fd, "ideal(");need_klammer=TRUE; }
+    else if (type_id == MODUL_CMD) { fprintf(fd, "module(");need_klammer=TRUE; }
+
+    if (fprintf(fd, "%s", rhs) == EOF) return EOF;
+    omFree(rhs);
+
+    if ((type_id == RING_CMD || type_id == QRING_CMD) &&
+        IDRING(h)->cf->type==n_algExt)
+    {
+      StringSetS("");
+      p_Write(IDRING(h)->cf->extRing->qideal->m[0],IDRING(h)->cf->extRing);
+      rhs = StringEndS();
+      if (fprintf(fd, "; minpoly = %s", rhs) == EOF) { omFree(rhs); return EOF;}
+      omFree(rhs);
+    }
+    else if (need_klammer) fprintf(fd, ")");
+  }
+  return 1;
+}
+
+BOOLEAN slGetDumpAscii(si_link l)
+{
+  if (l->name[0] == '\0')
+  {
+    Werror("getdump: Can not get dump from stdin");
+    return TRUE;
+  }
+  else
+  {
+    BOOLEAN status = newFile(l->name);
+    if (status)
+      return TRUE;
+
+    int old_echo=si_echo;
+    si_echo=0;
+
+    status=yyparse();
+
+    si_echo=old_echo;
+
+    if (status)
+      return TRUE;
+    else
+    {
+      // lets reset the file pointer to the end to reflect that
+      // we are finished with reading
+      FILE *f = (FILE *) l->data;
+      fseek(f, 0L, SEEK_END);
+      return FALSE;
+    }
+  }
+}
+
+
+void slStandardInit()
+{
+  si_link_extension s;
+  si_link_root=(si_link_extension)omAlloc0Bin(s_si_link_extension_bin);
+  si_link_root->Open=slOpenAscii;
+  si_link_root->Close=slCloseAscii;
+  si_link_root->Kill=NULL;
+  si_link_root->Read=slReadAscii;
+  si_link_root->Read2=slReadAscii2;
+  si_link_root->Write=slWriteAscii;
+  si_link_root->Dump=slDumpAscii;
+  si_link_root->GetDump=slGetDumpAscii;
+  si_link_root->Status=slStatusAscii;
+  si_link_root->type="ASCII";
+  s = si_link_root;
+  s->next = NULL;
+}
diff --git a/Singular/links/dbm_sl.h b/Singular/links/dbm_sl.h
new file mode 100644
index 0000000..dbcd662
--- /dev/null
+++ b/Singular/links/dbm_sl.h
@@ -0,0 +1,15 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    dbm_sl.h
+ *  Purpose: declaration of sl_link routines for dbm
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 12/00
+ *******************************************************************/
+LINKAGE BOOLEAN dbOpen(si_link l, short flag, leftv u);
+LINKAGE BOOLEAN dbWrite(si_link l, leftv v);
+LINKAGE leftv dbRead1(si_link l);
+LINKAGE leftv dbRead2(si_link l, leftv key);
+LINKAGE BOOLEAN dbClose(si_link l);
+
diff --git a/Singular/links/ndbm.cc b/Singular/links/ndbm.cc
new file mode 100644
index 0000000..7f9325a
--- /dev/null
+++ b/Singular/links/ndbm.cc
@@ -0,0 +1,551 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+
+//**************************************************************************/
+//
+//
+//**************************************************************************/
+// 'ndbm.cc' containes all low-level functions to manipulate dbm-files
+// for the original Copyright of this file and 'ndbm.h' see below .
+//
+// some minor change where needed to compile and run under MacOS/MPW
+//
+//**************************************************************************/
+
+
+#include <kernel/mod2.h>
+
+#include <reporter/si_signals.h>
+
+#ifdef HAVE_DBM
+#ifndef HPUX_9
+#include <strings.h>
+#endif
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.  The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ * for details see ndbm.h
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)ndbm.c        5.3 (Berkeley) 3/9/86";
+#endif
+
+//**************************************************************************/
+
+#include <stdio.h>
+/* alternative:
+* #   define EPERM 1
+* #   define ENOMEM 23
+* #   define ENOSPC 28
+* #   define L_SET SEEK_SET
+*/
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/file.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#ifndef HAVE_BCOPY
+#   define bcopy(a,b,c) memmove(b,a,c)
+#endif /* not HAVE_BCOPY */
+#include <Singular/links/ndbm.h>
+
+#define BYTESIZ 8
+#undef setbit
+
+static  void dbm_access(register DBM *db, long hash);
+static  int getbit(register DBM *db);
+static  void setbit(register DBM *db);
+static  datum makdatum(char buf[PBLKSIZ], int n);
+static  int finddatum(char buf[PBLKSIZ], datum item);
+static  long dcalchash(datum item);
+static  int delitem(char buf[PBLKSIZ], int n);
+static  int additem(char buf[PBLKSIZ], datum item, datum item1);
+// extern  int errno;
+extern "C" int singular_fstat(int fd, struct stat *buf);
+
+DBM * dbm_open(char *file, int flags, int mode)
+{
+  struct stat statb;
+  register DBM *db;
+
+  if ((db = (DBM *)malloc(sizeof *db)) == 0)
+  {
+    errno = ENOMEM;
+    return ((DBM *)0);
+  }
+#ifdef MSDOS
+  // default mode of open is ascii, we need binary mode.
+  flags |= O_BINARY;
+#endif
+  db->dbm_flags = (flags & 03) == O_RDONLY ? _DBM_RDONLY : 0;
+  if ((flags & 03) == O_WRONLY)
+    flags = (flags & ~03) | O_RDWR;
+  strcpy(db->dbm_pagbuf, file);
+  strcat(db->dbm_pagbuf, ".pag");
+  db->dbm_pagf = si_open(db->dbm_pagbuf, flags, mode);
+  if (db->dbm_pagf < 0)
+    goto bad;
+  strcpy(db->dbm_pagbuf, file);
+  strcat(db->dbm_pagbuf, ".dir");
+  db->dbm_dirf = si_open(db->dbm_pagbuf, flags, mode);
+  if (db->dbm_dirf < 0)
+    goto bad1;
+  singular_fstat(db->dbm_dirf, &statb);
+  db->dbm_maxbno = statb.st_size*BYTESIZ-1;
+  db->dbm_pagbno = db->dbm_dirbno = -1;
+  return (db);
+bad1:
+  (void) si_close(db->dbm_pagf);
+bad:
+  free((char *)db);
+  return ((DBM *)0);
+}
+
+void dbm_close(DBM *db)
+{
+  (void) si_close(db->dbm_dirf);
+  (void) si_close(db->dbm_pagf);
+  free((char *)db);
+}
+
+long dbm_forder(register DBM *db, datum key)
+{
+  long hash;
+
+  hash = dcalchash(key);
+  for (db->dbm_hmask=0;; db->dbm_hmask=(db->dbm_hmask<<1)+1)
+  {
+    db->dbm_blkno = hash & db->dbm_hmask;
+    db->dbm_bitno = db->dbm_blkno + db->dbm_hmask;
+    if (getbit(db) == 0)
+      break;
+  }
+  return (db->dbm_blkno);
+}
+
+datum dbm_fetch(register DBM *db, datum key)
+{
+  register int i;
+  datum item;
+
+  if (dbm_error(db))
+    goto err;
+  dbm_access(db, dcalchash(key));
+  if ((i = finddatum(db->dbm_pagbuf, key)) >= 0)
+  {
+    item = makdatum(db->dbm_pagbuf, i+1);
+    if (item.dptr != NULL)
+      return (item);
+  }
+err:
+  item.dptr = NULL;
+  item.dsize = 0;
+  return (item);
+}
+
+int dbm_delete(register DBM *db, datum key)
+{
+  register int i;
+  // datum item;
+
+  if (dbm_error(db))
+    return (-1);
+  if (dbm_rdonly(db))
+  {
+    errno = EPERM;
+    return (-1);
+  }
+  dbm_access(db, dcalchash(key));
+  if ((i = finddatum(db->dbm_pagbuf, key)) < 0)
+    return (-1);
+  if (!delitem(db->dbm_pagbuf, i))
+    goto err;
+  db->dbm_pagbno = db->dbm_blkno;
+  (void) lseek(db->dbm_pagf, db->dbm_blkno*PBLKSIZ, L_SET);
+  if (si_write(db->dbm_pagf, db->dbm_pagbuf, PBLKSIZ) != PBLKSIZ)
+  {
+  err:
+    db->dbm_flags |= _DBM_IOERR;
+    return (-1);
+  }
+  return (0);
+}
+
+int dbm_store(register DBM *db, datum key, datum dat, int replace)
+{
+  register int i;
+  int ret;
+  datum item, item1;
+  char ovfbuf[PBLKSIZ];
+
+  if (dbm_error(db))
+    return (-1);
+  if (dbm_rdonly(db))
+  {
+    errno = EPERM;
+    return (-1);
+  }
+
+_loop:
+  dbm_access(db, dcalchash(key));
+  if ((i = finddatum(db->dbm_pagbuf, key)) >= 0)
+  {
+    if (!replace)
+      return (1);
+    if (!delitem(db->dbm_pagbuf, i))
+    {
+      db->dbm_flags |= _DBM_IOERR;
+      return (-1);
+    }
+  }
+  if (!additem(db->dbm_pagbuf, key, dat))
+    goto split;
+  db->dbm_pagbno = db->dbm_blkno;
+  (void) lseek(db->dbm_pagf, db->dbm_blkno*PBLKSIZ, L_SET);
+  if ( (ret=si_write(db->dbm_pagf, db->dbm_pagbuf, PBLKSIZ)) != PBLKSIZ)
+  {
+    db->dbm_flags |= _DBM_IOERR;
+    return (-1);
+  }
+  return (0);
+
+split:
+  if (key.dsize+dat.dsize+3*sizeof(short) >= PBLKSIZ)
+  {
+    db->dbm_flags |= _DBM_IOERR;
+    errno = ENOSPC;
+    return (-1);
+  }
+  memset(ovfbuf, 0, PBLKSIZ);
+  for (i=0;;) {
+    item = makdatum(db->dbm_pagbuf, i);
+    if (item.dptr == NULL)
+      break;
+    if (dcalchash(item) & (db->dbm_hmask+1))
+    {
+      item1 = makdatum(db->dbm_pagbuf, i+1);
+      if (item1.dptr == NULL) {
+        fprintf(stderr, "ndbm: split not paired\n");
+        db->dbm_flags |= _DBM_IOERR;
+        break;
+      }
+      if (!additem(ovfbuf, item, item1) ||
+          !delitem(db->dbm_pagbuf, i))
+      {
+        db->dbm_flags |= _DBM_IOERR;
+        return (-1);
+      }
+      continue;
+    }
+    i += 2;
+  }
+  db->dbm_pagbno = db->dbm_blkno;
+  (void) lseek(db->dbm_pagf, db->dbm_blkno*PBLKSIZ, L_SET);
+  if (si_write(db->dbm_pagf, db->dbm_pagbuf, PBLKSIZ) != PBLKSIZ)
+  {
+    db->dbm_flags |= _DBM_IOERR;
+    return (-1);
+  }
+  (void) lseek(db->dbm_pagf, (db->dbm_blkno+db->dbm_hmask+1)*PBLKSIZ, L_SET);
+  if (si_write(db->dbm_pagf, ovfbuf, PBLKSIZ) != PBLKSIZ)
+  {
+    db->dbm_flags |= _DBM_IOERR;
+    return (-1);
+  }
+  setbit(db);
+  goto _loop;
+}
+
+datum dbm_firstkey(DBM *db)
+{
+
+  db->dbm_blkptr = 0L;
+  db->dbm_keyptr = 0;
+  return (dbm_nextkey(db));
+}
+
+datum dbm_nextkey(register DBM *db)
+{
+  struct stat statb;
+  datum item;
+
+  if (dbm_error(db)
+       || singular_fstat(db->dbm_pagf, &statb) < 0
+  )
+                goto err;
+  statb.st_size /= PBLKSIZ;
+  for (;;)
+  {
+    if (db->dbm_blkptr != db->dbm_pagbno)
+    {
+      db->dbm_pagbno = db->dbm_blkptr;
+      (void) lseek(db->dbm_pagf, db->dbm_blkptr*PBLKSIZ, L_SET);
+      if (si_read(db->dbm_pagf, db->dbm_pagbuf, PBLKSIZ) != PBLKSIZ)
+        memset(db->dbm_pagbuf, 0, PBLKSIZ);
+#ifdef DEBUG
+      else if (chkblk(db->dbm_pagbuf) < 0)
+        db->dbm_flags |= _DBM_IOERR;
+#endif
+    }
+    if (((short *)db->dbm_pagbuf)[0] != 0)
+    {
+      item = makdatum(db->dbm_pagbuf, db->dbm_keyptr);
+      if (item.dptr != NULL)
+      {
+        db->dbm_keyptr += 2;
+        return (item);
+      }
+      db->dbm_keyptr = 0;
+    }
+    if (++db->dbm_blkptr >= statb.st_size)
+      break;
+  }
+err:
+  item.dptr = NULL;
+  item.dsize = 0;
+  return (item);
+}
+
+static void dbm_access(register DBM *db, long hash)
+{
+  for (db->dbm_hmask=0;; db->dbm_hmask=(db->dbm_hmask<<1)+1)
+  {
+    db->dbm_blkno = hash & db->dbm_hmask;
+    db->dbm_bitno = db->dbm_blkno + db->dbm_hmask;
+    if (getbit(db) == 0)
+      break;
+  }
+  if (db->dbm_blkno != db->dbm_pagbno)
+  {
+    db->dbm_pagbno = db->dbm_blkno;
+    (void) lseek(db->dbm_pagf, db->dbm_blkno*PBLKSIZ, L_SET);
+    if (si_read(db->dbm_pagf, db->dbm_pagbuf, PBLKSIZ) != PBLKSIZ)
+      memset(db->dbm_pagbuf, 0, PBLKSIZ);
+#ifdef DEBUG
+    else if (chkblk(db->dbm_pagbuf) < 0)
+      db->dbm_flags |= _DBM_IOERR;
+#endif
+  }
+}
+
+static int getbit(register DBM *db)
+{
+  long bn;
+  register int b, i, n;
+
+
+  if (db->dbm_bitno > db->dbm_maxbno)
+    return (0);
+  n = db->dbm_bitno % BYTESIZ;
+  bn = db->dbm_bitno / BYTESIZ;
+  i = bn % DBLKSIZ;
+  b = bn / DBLKSIZ;
+  if (b != db->dbm_dirbno)
+  {
+    db->dbm_dirbno = b;
+    (void) lseek(db->dbm_dirf, (long)b*DBLKSIZ, L_SET);
+    if (si_read(db->dbm_dirf, db->dbm_dirbuf, DBLKSIZ) != DBLKSIZ)
+      memset(db->dbm_dirbuf, 0, DBLKSIZ);
+  }
+  return (db->dbm_dirbuf[i] & (1<<n));
+}
+
+static void setbit(register DBM *db)
+{
+  long bn;
+  register int i, n, b;
+
+  if (db->dbm_bitno > db->dbm_maxbno)
+    db->dbm_maxbno = db->dbm_bitno;
+  n = db->dbm_bitno % BYTESIZ;
+  bn = db->dbm_bitno / BYTESIZ;
+  i = bn % DBLKSIZ;
+  b = bn / DBLKSIZ;
+  if (b != db->dbm_dirbno)
+  {
+    db->dbm_dirbno = b;
+    (void) lseek(db->dbm_dirf, (long)b*DBLKSIZ, L_SET);
+    if (si_read(db->dbm_dirf, db->dbm_dirbuf, DBLKSIZ) != DBLKSIZ)
+      memset(db->dbm_dirbuf, 0, DBLKSIZ);
+  }
+  db->dbm_dirbuf[i] |= 1<<n;
+  db->dbm_dirbno = b;
+  (void) lseek(db->dbm_dirf, (long)b*DBLKSIZ, L_SET);
+  if (si_write(db->dbm_dirf, db->dbm_dirbuf, DBLKSIZ) != DBLKSIZ)
+    db->dbm_flags |= _DBM_IOERR;
+}
+
+static datum makdatum(char buf[PBLKSIZ], int n)
+{
+  register short *sp;
+  register int t;
+  datum item;
+
+  sp = (short *)buf;
+  if ((unsigned)n >= (unsigned)sp[0])
+  {
+    item.dptr = NULL;
+    item.dsize = 0;
+    return (item);
+  }
+  t = PBLKSIZ;
+  if (n > 0)
+    t = sp[n];
+  item.dptr = buf+sp[n+1];
+  item.dsize = t - sp[n+1];
+  return (item);
+}
+
+static int finddatum(char buf[PBLKSIZ], datum item)
+{
+  register short *sp;
+  register int i, n, j;
+
+  sp = (short *)buf;
+  n = PBLKSIZ;
+  for (i=0, j=sp[0]; i<j; i+=2, n = sp[i])
+  {
+    n -= sp[i+1];
+    if (n != item.dsize)
+      continue;
+    if (n == 0 || memcmp(&buf[sp[i+1]], item.dptr, n) == 0)
+      return (i);
+  }
+  return (-1);
+}
+
+static  int hitab[16]
+/* ken's
+{
+        055,043,036,054,063,014,004,005,
+        010,064,077,000,035,027,025,071,
+};
+*/
+ = {    61, 57, 53, 49, 45, 41, 37, 33,
+        29, 25, 21, 17, 13,  9,  5,  1,
+};
+static  long hltab[64]
+ = {
+        06100151277L,06106161736L,06452611562L,05001724107L,
+        02614772546L,04120731531L,04665262210L,07347467531L,
+        06735253126L,06042345173L,03072226605L,01464164730L,
+        03247435524L,07652510057L,01546775256L,05714532133L,
+        06173260402L,07517101630L,02431460343L,01743245566L,
+        00261675137L,02433103631L,03421772437L,04447707466L,
+        04435620103L,03757017115L,03641531772L,06767633246L,
+        02673230344L,00260612216L,04133454451L,00615531516L,
+        06137717526L,02574116560L,02304023373L,07061702261L,
+        05153031405L,05322056705L,07401116734L,06552375715L,
+        06165233473L,05311063631L,01212221723L,01052267235L,
+        06000615237L,01075222665L,06330216006L,04402355630L,
+        01451177262L,02000133436L,06025467062L,07121076461L,
+        03123433522L,01010635225L,01716177066L,05161746527L,
+        01736635071L,06243505026L,03637211610L,01756474365L,
+        04723077174L,03642763134L,05750130273L,03655541561L,
+};
+
+static long dcalchash(datum item)
+{
+  register int s, c, j;
+  register char *cp;
+  register unsigned long hashl;
+  register unsigned int hashi;
+
+  hashl = 0;
+  hashi = 0;
+  for (cp = item.dptr, s=item.dsize; --s >= 0; )
+  {
+    c = *cp++;
+    for (j=0; j<BYTESIZ; j+=4)
+    {
+      hashi += hitab[c&017];
+      hashl += hltab[hashi&63];
+      c >>= 4;
+    }
+  }
+  return (long)(hashl);
+}
+
+/*
+ * Delete pairs of items (n & n+1).
+ */
+static int delitem(char buf[PBLKSIZ], int n)
+{
+  register short *sp, *sp1;
+  register int i1, i2;
+
+  sp = (short *)buf;
+  i2 = sp[0];
+  if ((unsigned)n >= (unsigned)i2 || (n & 1))
+    return (0);
+  if (n == i2-2)
+  {
+    sp[0] -= 2;
+    return (1);
+  }
+  i1 = PBLKSIZ;
+  if (n > 0)
+    i1 = sp[n];
+  i1 -= sp[n+2];
+  if (i1 > 0)
+  {
+    i2 = sp[i2];
+    bcopy(&buf[i2], &buf[i2 + i1], sp[n+2] - i2);
+  }
+  sp[0] -= 2;
+  for (sp1 = sp + sp[0], sp += n+1; sp <= sp1; sp++)
+    sp[0] = sp[2] + i1;
+  return (1);
+}
+
+/*
+ * Add pairs of items (item & item1).
+ */
+static int additem(char buf[PBLKSIZ], datum item, datum item1)
+{
+  register short *sp;
+  register int i1, i2, tmp;
+
+  sp = (short *)buf;
+  i1 = PBLKSIZ;
+  i2 = sp[0];
+  if (i2 > 0)
+    i1 = sp[i2];
+  i1 -= item.dsize + item1.dsize;
+  tmp = (i2+3) * sizeof(short);
+  if (i1 <= tmp) return (0);
+  sp[0] += 2;
+  sp[++i2] = i1 + item1.dsize;
+  bcopy(item.dptr, &buf[i1 + item1.dsize], item.dsize);
+  sp[++i2] = i1;
+  bcopy(item1.dptr, &buf[i1], item1.dsize);
+  return (1);
+}
+
+#ifdef DEBUG
+static chkblk(char buf[PBLKSIZ])
+{
+  register short *sp;
+  register t, i;
+
+  sp = (short *)buf;
+  t = PBLKSIZ;
+  for (i=0; i<sp[0]; i++)
+  {
+    if (sp[i+1] > t)
+      return (-1);
+    t = sp[i+1];
+  }
+  if (t < (sp[0]+1)*sizeof(short))
+    return (-1);
+  return (0);
+}
+#endif
+
+#endif /* HAVE_DBM */
diff --git a/Singular/links/ndbm.h b/Singular/links/ndbm.h
new file mode 100644
index 0000000..ce58529
--- /dev/null
+++ b/Singular/links/ndbm.h
@@ -0,0 +1,103 @@
+#ifndef NDBM_H
+#define NDBM_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: DBM
+*/
+
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.  The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ *
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)ndbm.h	5.1 (Berkeley) 5/30/85
+ *
+ * Par. 3 removed due to a license change (1999)
+ * see ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
+ */
+
+/*
+ * Hashed key data base library.
+ */
+#define PBLKSIZ 1024
+
+#define DBLKSIZ 4096
+
+typedef struct {
+	int	dbm_dirf;		/* open directory file */
+	int	dbm_pagf;		/* open page file */
+	int	dbm_flags;		/* flags, see below */
+	long	dbm_maxbno;		/* last ``bit'' in dir file */
+	long	dbm_bitno;		/* current bit number */
+	long	dbm_hmask;		/* hash mask */
+	long	dbm_blkptr;		/* current block for dbm_nextkey */
+	int	dbm_keyptr;		/* current key for dbm_nextkey */
+	long	dbm_blkno;		/* current page to read/write */
+	long	dbm_pagbno;		/* current page in pagbuf */
+	char	dbm_pagbuf[PBLKSIZ];	/* page file block buffer */
+	long	dbm_dirbno;		/* current block in dirbuf */
+	char	dbm_dirbuf[DBLKSIZ];	/* directory file block buffer */
+} DBM;
+
+#define _DBM_RDONLY	0x01	/* data base open read-only */
+#define _DBM_IOERR	0x02	/* data base I/O error */
+
+#define dbm_rdonly(db)	((db)->dbm_flags & _DBM_RDONLY)
+
+#define dbm_error(db)	((db)->dbm_flags & _DBM_IOERR)
+	/* use this one at your own risk! */
+#define dbm_clearerr(db)	((db)->dbm_flags &= ~_DBM_IOERR)
+
+/* for flock(2) and fstat(2) */
+#define dbm_dirfno(db)	((db)->dbm_dirf)
+#define dbm_pagfno(db)	((db)->dbm_pagf)
+
+typedef struct {
+	char	*dptr;
+	int	dsize;
+} datum;
+
+/*
+ * flags to dbm_store()
+ */
+#define DBM_INSERT	0
+#define DBM_REPLACE	1
+
+DBM	*dbm_open(char *file, int flags, int mode);
+void	dbm_close(DBM *db);
+datum	dbm_fetch(register DBM *db, datum key);
+datum	dbm_firstkey(DBM *db);
+datum	dbm_nextkey(register DBM *db);
+long	dbm_forder(register DBM *db, datum key);
+int	dbm_delete(register DBM *db, datum key);
+int	dbm_store(register DBM *db, datum key, datum dat, int replace);
+
+#endif /* NDBM_H */
diff --git a/Singular/links/pipeLink.cc b/Singular/links/pipeLink.cc
new file mode 100644
index 0000000..bc3edf6
--- /dev/null
+++ b/Singular/links/pipeLink.cc
@@ -0,0 +1,208 @@
+/****************************************
+ * Computer Algebra System SINGULAR     *
+ ****************************************/
+/***************************************************************
+ * File:    pipeLink.h
+ *  Purpose: declaration of sl_link routines for pipe
+ ***************************************************************/
+
+#include <kernel/mod2.h>
+
+#include <omalloc/omalloc.h>
+#include <reporter/si_signals.h>
+
+#include "tok.h"
+#include "ipid.h"
+#include "subexpr.h"
+#include "links/silink.h"
+#include "lists.h"
+#include "pipeLink.h"
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <signal.h>
+#include <sys/types.h>          /* for portability */
+#include <sys/select.h>
+#include <sys/socket.h>
+
+typedef struct
+{
+  FILE *f_read;
+  FILE *f_write;
+  pid_t pid; /* only valid for fork/tcp mode*/
+  int fd_read,fd_write; /* only valid for fork/tcp mode*/
+  char level;
+} pipeInfo;
+
+//**************************************************************************/
+BOOLEAN pipeOpen(si_link l, short flag, leftv /*u*/)
+{
+  pipeInfo *d=(pipeInfo*)omAlloc0(sizeof(pipeInfo));
+  if (flag & SI_LINK_OPEN)
+  {
+      flag = SI_LINK_READ| SI_LINK_WRITE;
+  }
+  int pc[2];
+  int cp[2];
+  pipe(pc);
+  pipe(cp);
+  pid_t pid=fork();
+  if (pid==0) /*child*/
+  {
+    /* close unnecessary pipe descriptors for a clean environment */
+    si_close(pc[1]); si_close(cp[0]);
+    /* dup pipe read/write to stdin/stdout */
+    si_dup2( pc[0], STDIN_FILENO );
+    si_dup2( cp[1], STDOUT_FILENO  );
+    int r=system(l->name);
+    si_close(pc[0]);
+    si_close(cp[1]);
+    exit(r);
+        /* never reached*/
+  }
+  else if (pid>0)
+  {
+    d->pid=pid;
+    si_close(pc[0]); si_close(cp[1]);
+    d->f_read=fdopen(cp[0],"r");
+    d->fd_read=cp[0];
+    d->f_write=fdopen(pc[1],"w");
+    d->fd_write=pc[1];
+    SI_LINK_SET_RW_OPEN_P(l);
+  }
+  else
+  {
+    Werror("fork failed (%d)",errno);
+    omFreeSize(d,sizeof(*d));
+    return TRUE;
+  }
+  l->data=d;
+  return FALSE;
+}
+
+//**************************************************************************/
+LINKAGE BOOLEAN pipeClose(si_link l)
+{
+  pipeInfo *d = (pipeInfo *)l->data;
+  if (d!=NULL)
+  {
+    if (d->f_read!=NULL) fclose(d->f_read);
+    if (d->f_write!=NULL) fclose(d->f_write);
+    if (d->pid!=0) { kill(d->pid,15); kill(d->pid,9); }
+  }
+  SI_LINK_SET_CLOSE_P(l);
+  return FALSE;
+}
+
+//**************************************************************************/
+LINKAGE BOOLEAN pipeKill(si_link l)
+{
+  if(SI_LINK_OPEN_P(l)) pipeClose(l);
+  pipeInfo *d = (pipeInfo *)l->data;
+  if (d!=NULL)
+  {
+    omFreeSize((ADDRESS)d,(sizeof *d));
+  }
+  l->data=NULL;
+  return FALSE;
+}
+
+//**************************************************************************/
+LINKAGE leftv pipeRead1(si_link l)
+{
+  pipeInfo *d = (pipeInfo *)l->data;
+  leftv res=(leftv)omAlloc0(sizeof(sleftv));
+  char *s=(char *)omAlloc0(1024);
+  char *ss=fgets(s,1024,d->f_read);
+  if (ss==NULL) { omFreeSize(s,1024); pipeClose(l);return NULL; }
+  int i=strlen(s)-1;
+  if ((i>=0) && (s[i]=='\n')) s[i]='\0';
+  res->rtyp=STRING_CMD;
+  res->data=s;
+  return res;
+}
+//**************************************************************************/
+extern si_link pipeLastLink;
+LINKAGE BOOLEAN pipeWrite(si_link l, leftv data)
+{
+  if(!SI_LINK_W_OPEN_P(l)) slOpen(l,SI_LINK_OPEN|SI_LINK_WRITE,NULL);
+  pipeInfo *d = (pipeInfo *)l->data;
+  FILE *outfile=d->f_write;;
+  BOOLEAN err=FALSE;
+  char *s;
+  pipeLastLink=l;
+  while (data!=NULL)
+  {
+    s = data->String();
+    // free data ??
+    if (s!=NULL)
+    {
+      fprintf(outfile,"%s\n",s);
+      omFree((ADDRESS)s);
+    }
+    else
+    {
+      Werror("cannot convert to string");
+      err=TRUE;
+    }
+    if (pipeLastLink==NULL) return TRUE;
+    data = data->next;
+  }
+  fflush(outfile);
+  pipeLastLink=NULL;
+  return err;
+}
+
+const char* slStatusPipe(si_link l, const char* request)
+{
+  pipeInfo *d=(pipeInfo*)l->data;
+  if (d==NULL) return "not open";
+  if(strcmp(request, "read") == 0)
+  {
+    int s;
+    if ((!SI_LINK_R_OPEN_P(l)) || (feof(d->f_read))) s=0;
+    else
+    {
+      fd_set  mask/*, fdmask*/;
+      struct timeval wt;
+      /* Don't block. Return socket status immediately. */
+      wt.tv_sec  = 0;
+      wt.tv_usec = 0;
+
+      FD_ZERO(&mask);
+      FD_SET(d->fd_read, &mask);
+      //Print("test fd %d\n",d->fd_read);
+      /* check with select: chars waiting: no -> not ready */
+      s=si_select(d->fd_read+1, &mask, NULL, NULL, &wt);
+    }
+    switch (s)
+    {
+      case 0: /* not ready */ return "not ready";
+      case -1: /*error*/      return "error";
+      default: /*1: ready ? */return "ready";
+    }
+  }
+  else if (strcmp(request, "write") == 0)
+  {
+    if (SI_LINK_W_OPEN_P(l)) return "ready";
+    return "not ready";
+  }
+  return "unknown status request";
+}
+
+si_link_extension slInitPipeExtension(si_link_extension s)
+{
+  s->Open=pipeOpen;
+  s->Close=pipeClose;
+  s->Kill=pipeKill;
+  s->Read=pipeRead1;
+  s->Read2=(slRead2Proc)NULL;
+  s->Write=pipeWrite;
+
+  s->Status=slStatusPipe;
+  s->type="pipe";
+  return s;
+}
diff --git a/Singular/links/pipeLink.h b/Singular/links/pipeLink.h
new file mode 100644
index 0000000..adce922
--- /dev/null
+++ b/Singular/links/pipeLink.h
@@ -0,0 +1,12 @@
+/****************************************
+ * Computer Algebra System SINGULAR     *
+ ****************************************/
+/***************************************************************
+ * File:    pipeLink.h
+ *  Purpose: declaration of sl_link routines for pipe
+ ***************************************************************/
+#ifndef PIPELINK_H
+#define PIPELINK_H
+si_link_extension slInitPipeExtension(si_link_extension s);
+#endif
+
diff --git a/Singular/links/semaphore.c b/Singular/links/semaphore.c
new file mode 100644
index 0000000..2817a03
--- /dev/null
+++ b/Singular/links/semaphore.c
@@ -0,0 +1,139 @@
+
+
+
+
+#include <kernel/mod2.h>
+
+#ifdef HAVE_SIMPLEIPC
+#include <semaphore.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+
+# include "simpleipc.h"
+
+#include <Singular/cntrlc.h>
+#include <reporter/si_signals.h>
+
+
+
+// Not yet implemented: SYSV IPC Semaphores
+// They are more difficult to clean up after a process crash
+// but are supported more widely.
+
+sem_t *semaphore[SIPC_MAX_SEMAPHORES];
+int sem_acquired[SIPC_MAX_SEMAPHORES];
+
+/* return 1 on success,
+ *        0 if already initialized,
+ *       -1 for errors
+ */
+int sipc_semaphore_init(int id, int count)
+{
+  char buf[100];
+  sem_t *sem;
+  if ((id<0) || (id >= SIPC_MAX_SEMAPHORES))
+    return -1;
+  // Already initialized?
+  if (semaphore[id])
+    return 0;
+  // to make it completely safe, we should generate a name
+  // from /dev/urandom.
+#if USE_SEM_INIT
+  // TODO: This should really use mapped memory so that processes
+  // can keep using the semaphore after fork + exec.
+  sem = malloc(sizeof(sem_t));
+  if (!sem)
+    return -1;
+  if (sem_init(sem, 1, count) < 0)
+  {
+    free(sem);
+    return -1;
+  }
+#else
+  sprintf(buf, "/%d:sem%d", getpid(), id);
+  sem_unlink(buf);
+  sem = sem_open(buf, O_CREAT, 0600, count);
+#endif
+  if (sem == SEM_FAILED || !sem)
+    return -1;
+  semaphore[id] = sem;
+#if !USE_SEM_INIT
+  sem_unlink(buf);
+#endif
+  return 1;
+}
+
+int sipc_semaphore_exists(int id)
+{
+  if ((id<0) || (id >= SIPC_MAX_SEMAPHORES))  return -1;
+  return semaphore[id] != NULL;
+}
+
+int sipc_semaphore_acquire(int id)
+{
+  if ((id<0) || (id >= SIPC_MAX_SEMAPHORES) || (semaphore[id]==NULL))  return -1;
+  defer_shutdown++;
+  si_sem_wait(semaphore[id]);
+  sem_acquired[id]++;
+  defer_shutdown--;
+  if (!defer_shutdown && do_shutdown) m2_end(1);
+  return 1;
+}
+
+int sipc_semaphore_try_acquire(int id)
+{
+  if ((id<0) || (id >= SIPC_MAX_SEMAPHORES) || (semaphore[id]==NULL))  return -1;
+  defer_shutdown++;
+  int trywait = si_sem_trywait(semaphore[id]);
+  if (!trywait)
+  {
+    sem_acquired[id]++;
+  }
+  defer_shutdown--;
+  if (!defer_shutdown && do_shutdown) m2_end(1);
+  return !trywait;
+}
+
+int sipc_semaphore_release(int id)
+{
+  if ((id<0) || (id >= SIPC_MAX_SEMAPHORES) || (semaphore[id]==NULL))  return -1;
+  defer_shutdown++;
+  sem_post(semaphore[id]);
+  sem_acquired[id]--;
+  defer_shutdown--;
+  if (!defer_shutdown && do_shutdown) m2_end(1);
+  return 1;
+}
+
+int sipc_semaphore_get_value(int id)
+{
+  int val;
+  if ((id<0) || (id >= SIPC_MAX_SEMAPHORES) || (semaphore[id]==NULL))  return -1;
+  sem_getvalue(semaphore[id], &val);
+  return val;
+}
+
+int simpleipc_cmd(char *cmd, int id, int v)
+{
+  if (strcmp(cmd,"init")==0)
+    return sipc_semaphore_init(id,v);
+  else if (strcmp(cmd,"exists")==0)
+    return sipc_semaphore_exists(id);
+  else if (strcmp(cmd,"acquire")==0)
+    return  sipc_semaphore_acquire(id);
+  else if (strcmp(cmd,"try_acquire")==0)
+    return sipc_semaphore_try_acquire(id);
+  else if (strcmp(cmd,"release")==0)
+    return sipc_semaphore_release(id);
+  else if (strcmp(cmd,"get_value")==0)
+    return sipc_semaphore_get_value(id);
+  else printf("unknown\n");
+    return  -2;
+}
+#endif
diff --git a/Singular/links/silink.cc b/Singular/links/silink.cc
new file mode 100644
index 0000000..1207f5e
--- /dev/null
+++ b/Singular/links/silink.cc
@@ -0,0 +1,450 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+
+/*
+* ABSTRACT: general interface to links
+*/
+
+#include <kernel/mod2.h>
+
+#include <omalloc/omalloc.h>
+#include <misc/options.h>
+#include <misc/intvec.h>
+#include <reporter/si_signals.h>
+#include <coeffs/numbers.h>
+
+#include <polys/matpol.h>
+#include <polys/monomials/ring.h>
+
+#include <kernel/ideals.h>
+
+#include <Singular/lists.h>
+#include <Singular/cntrlc.h>
+#include <Singular/links/ssiLink.h>
+#include <Singular/links/pipeLink.h>
+#include <Singular/tok.h>
+#include <Singular/subexpr.h>
+#include <Singular/ipid.h>
+#include <Singular/links/silink.h>
+#include <Singular/ipshell.h>
+#include "feOpt.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+// #ifdef HAVE_DBM
+// #ifdef __CYGWIN__
+// #define USE_GDBM
+// #endif
+// #endif
+
+omBin s_si_link_extension_bin = omGetSpecBin(sizeof(s_si_link_extension));
+omBin sip_link_bin = omGetSpecBin(sizeof(sip_link));
+omBin ip_link_bin = omGetSpecBin(sizeof(ip_link));
+
+/* ====================================================================== */
+static si_link_extension slTypeInit(si_link_extension s, const char* type);
+si_link_extension si_link_root=NULL;
+
+BOOLEAN slInit(si_link l, char *istr)
+{
+  char *type = NULL, *mode = NULL, *name = NULL;
+  int i = 0, j;
+
+  // set mode and type
+  if (istr != NULL)
+  {
+    // find the first colon char in istr
+    i = 0;
+    while (istr[i] != ':' && istr[i] != '\0') i++;
+    if (istr[i] == ':')
+    {
+      // if found, set type
+      if (i > 0)
+      {
+        istr[i] = '\0';
+        type = omStrDup(istr);
+        istr[i] = ':';
+      }
+      // and check for mode
+      j = ++i;
+      while (istr[j] != ' ' && istr[j] != '\0') j++;
+      if (j > i)
+      {
+        mode = omStrDup(&(istr[i]));
+        mode[j - i] = '\0';
+      }
+      // and for the name
+      while (istr[j] == ' '&& istr[j] != '\0') j++;
+      if (istr[j] != '\0') name = omStrDup(&(istr[j]));
+    }
+    else // no colon find -- string is entire name
+    {
+      j=0;
+      while (istr[j] == ' '&& istr[j] != '\0') j++;
+      if (istr[j] != '\0') name = omStrDup(&(istr[j]));
+    }
+  }
+
+  // set the link extension
+  if (type != NULL)
+  {
+    si_link_extension s = si_link_root;
+    si_link_extension prev = s;
+
+    while (strcmp(s->type, type) != 0)
+    {
+      if (s->next == NULL)
+      {
+        prev = s;
+        s = NULL;
+        break;
+      }
+      else
+      {
+        s = s->next;
+      }
+    }
+
+    if (s != NULL)
+      l->m = s;
+    else
+    {
+      l->m = slTypeInit(prev, type);
+    }
+    omFree(type);
+  }
+  else
+    l->m = si_link_root;
+
+  if (l->m == NULL) return TRUE;
+
+  l->name = (name != NULL ? name : omStrDup(""));
+  l->mode = (mode != NULL ? mode : omStrDup(""));
+  l->ref = 1;
+  return FALSE;
+}
+
+void slCleanUp(si_link l)
+{
+  defer_shutdown++;
+  (l->ref)--;
+  if (l->ref == 0)
+  {
+    if (SI_LINK_OPEN_P(l))
+    {
+      if (l->m->Close != NULL) l->m->Close(l);
+    }
+    if ((l->data != NULL) && (l->m->Kill != NULL)) l->m->Kill(l);
+    omFree((ADDRESS)l->name);
+    omFree((ADDRESS)l->mode);
+    memset((void *) l, 0, sizeof(ip_link));
+  }
+  defer_shutdown--;
+  if (!defer_shutdown && do_shutdown) m2_end(1);
+}
+
+void slKill(si_link l)
+{
+  defer_shutdown++;
+  slCleanUp(l);
+  if ((l!=NULL) &&(l->ref == 0))
+    omFreeBin((ADDRESS)l,  ip_link_bin);
+  defer_shutdown--;
+  if (!defer_shutdown && do_shutdown) m2_end(1);
+}
+
+const char* slStatus(si_link l, const char *request)
+{
+  if (l == NULL) return "empty link";
+  else if (l->m == NULL) return "unknown link type";
+  else if (strcmp(request, "type") == 0) return l->m->type;
+  else if (strcmp(request, "mode") == 0) return l->mode;
+  else if (strcmp(request, "name") == 0) return l->name;
+  else if (strcmp(request, "exists") ==0)
+  {
+    struct stat buf;
+    if (si_lstat(l->name,&buf)==0) return "yes";
+    else return "no";
+  }
+  else if (strcmp(request, "open") == 0)
+  {
+    if (SI_LINK_OPEN_P(l)) return "yes";
+    else return "no";
+  }
+  else if (strcmp(request, "openread") == 0)
+  {
+    if (SI_LINK_R_OPEN_P(l)) return "yes";
+    else return "no";
+  }
+  else if (strcmp(request, "openwrite") == 0)
+  {
+    if (SI_LINK_W_OPEN_P(l)) return "yes";
+    else return "no";
+  }
+  else if (l->m->Status == NULL) return "unknown status request";
+  else return l->m->Status(l, request);
+}
+
+//--------------------------------------------------------------------------
+BOOLEAN slSetRingDummy(si_link, ring r, BOOLEAN send)
+{
+  if (currRing!=r) rChangeCurrRing(r);
+  return FALSE;
+}
+BOOLEAN slOpen(si_link l, short flag, leftv h)
+{
+  BOOLEAN res = TRUE;
+  if (l!=NULL)
+  {
+
+    if (l->m == NULL) slInit(l, ((char*)""));
+
+    if (feOptValue(FE_OPT_NO_SHELL)) {WerrorS("no links allowed");return TRUE;}
+
+    const char *c="_";;
+    if (h!=NULL) c=h->Name();
+
+    if (SI_LINK_OPEN_P(l))
+    {
+      Warn("open: link of type: %s, mode: %s, name: %s is already open",
+         l->m->type, l->mode, l->name);
+      return FALSE;
+    }
+    else if (l->m->Open != NULL)
+    {
+      res = l->m->Open(l, flag, h);
+      if (res)
+        Werror("open: Error for link %s of type: %s, mode: %s, name: %s",
+             c, l->m->type, l->mode, l->name);
+    }
+    if (l->m->SetRing==NULL) l->m->SetRing=slSetRingDummy;
+  }
+  return res;
+}
+
+BOOLEAN slPrepClose(si_link l)
+{
+
+  if(! SI_LINK_OPEN_P(l))
+    return FALSE;
+
+  BOOLEAN res = TRUE;
+  if (l->m->PrepClose != NULL)
+  {
+    res = l->m->PrepClose(l);
+    if (res)
+      Werror("close: Error for link of type: %s, mode: %s, name: %s",
+           l->m->type, l->mode, l->name);
+  }
+  return res;
+}
+
+BOOLEAN slClose(si_link l)
+{
+
+  if(! SI_LINK_OPEN_P(l))
+    return FALSE;
+
+  defer_shutdown++;
+  BOOLEAN res = TRUE;
+  if (l->m->Close != NULL)
+  {
+    res = l->m->Close(l);
+    if (res)
+      Werror("close: Error for link of type: %s, mode: %s, name: %s",
+           l->m->type, l->mode, l->name);
+  }
+  defer_shutdown--;
+  if (!defer_shutdown && do_shutdown) m2_end(1);
+  return res;
+}
+
+leftv slRead(si_link l, leftv a)
+{
+  leftv v = NULL;
+  if( ! SI_LINK_R_OPEN_P(l)) // open r ?
+  {
+#ifdef HAVE_DBM
+#ifdef USE_GDBM
+    if (! SI_LINK_CLOSE_P(l))
+      {
+        if (slClose(l)) return NULL;
+      }
+#endif
+#endif
+    if (slOpen(l, SI_LINK_READ,NULL)) return NULL;
+  }
+
+  if (SI_LINK_R_OPEN_P(l))
+  { // open r
+    if (a==NULL)
+    {
+      if (l->m->Read != NULL) v = l->m->Read(l);
+    }
+    else
+    {
+      if (l->m->Read2 != NULL) v = l->m->Read2(l,a);
+    }
+  }
+  else
+  {
+    Werror("read: Error to open link of type %s, mode: %s, name: %s for reading",
+           l->m->type, l->mode, l->name);
+    return NULL;
+  }
+
+  // here comes the eval:
+  if (v != NULL)
+  {
+    if (v->Eval() && !errorreported)
+      WerrorS("eval: failed");
+  }
+  else
+    Werror("read: Error for link of type %s, mode: %s, name: %s",
+           l->m->type, l->mode, l->name);
+  return v;
+}
+
+BOOLEAN slWrite(si_link l, leftv v)
+{
+  BOOLEAN res;
+
+  if(! SI_LINK_W_OPEN_P(l)) // open w ?
+  {
+#ifdef HAVE_DBM
+#ifdef USE_GDBM
+    if (! SI_LINK_CLOSE_P(l))
+      {
+        if (slClose(l)) return TRUE;
+      }
+#endif
+#endif
+    if (slOpen(l, SI_LINK_WRITE,NULL)) return TRUE;
+  }
+
+  if (SI_LINK_W_OPEN_P(l))
+  { // now open w
+    if (l->m->Write != NULL)
+      res = l->m->Write(l,v);
+    else
+      res = TRUE;
+
+    if (res)
+      Werror("write: Error for link of type %s, mode: %s, name: %s",
+             l->m->type, l->mode, l->name);
+    return res;
+  }
+  else
+  {
+    Werror("write: Error to open link of type %s, mode: %s, name: %s for writing",
+           l->m->type, l->mode, l->name);
+    return TRUE;
+  }
+}
+
+BOOLEAN slDump(si_link l)
+{
+  BOOLEAN res;
+
+  if(! SI_LINK_W_OPEN_P(l)) // open w ?
+  {
+    if (slOpen(l, SI_LINK_WRITE,NULL)) return TRUE;
+  }
+
+  if(SI_LINK_W_OPEN_P(l))
+  { // now open w
+    if (l->m->Dump != NULL)
+      res = l->m->Dump(l);
+    else
+      res = TRUE;
+
+    if (res)
+      Werror("dump: Error for link of type %s, mode: %s, name: %s",
+             l->m->type, l->mode, l->name);
+    if (!SI_LINK_R_OPEN_P(l)) slClose(l); // do not close r/w links
+    return res;
+  }
+  else
+  {
+    Werror("dump: Error to open link of type %s, mode: %s, name: %s for writing",
+           l->m->type, l->mode, l->name);
+    return TRUE;
+  }
+}
+
+BOOLEAN slGetDump(si_link l)
+{
+  BOOLEAN res;
+
+  if(! SI_LINK_R_OPEN_P(l)) // open r ?
+  {
+    if (slOpen(l, SI_LINK_READ,NULL)) return TRUE;
+  }
+
+  if(SI_LINK_R_OPEN_P(l))
+  { // now open r
+    if (l->m->GetDump != NULL)
+      res = l->m->GetDump(l);
+    else
+      res = TRUE;
+
+    if (res)
+      Werror("getdump: Error for link of type %s, mode: %s, name: %s",
+             l->m->type, l->mode, l->name);
+    //res|=slClose(l);
+    return res;
+  }
+  else
+  {
+    Werror("dump: Error open link of type %s, mode: %s, name: %s for reading",
+           l->m->type, l->mode, l->name);
+    return TRUE;
+  }
+}
+
+/*------------Initialization at Start-up time------------------------*/
+
+#include <Singular/links/slInit.h>
+
+static si_link_extension slTypeInit(si_link_extension s, const char* type)
+{
+  assume(s != NULL);
+  s->next = NULL;
+  si_link_extension ns = (si_link_extension)omAlloc0Bin(s_si_link_extension_bin);
+
+  if (0)
+    ; // dummy
+#ifdef HAVE_DBM
+  else if (strcmp(type, "DBM") == 0)
+    s->next = slInitDBMExtension(ns);
+#endif
+#if 1
+  else if (strcmp(type, "ssi") == 0)
+    s->next = slInitSsiExtension(ns);
+#endif
+#if 1
+  else if (strcmp(type, "|") == 0)
+    s->next = slInitPipeExtension(ns);
+#endif
+  else
+  {
+    Warn("Found unknown link type: %s", type);
+    Warn("Use default link type: %s", si_link_root->type);
+    omFreeBin(ns, s_si_link_extension_bin);
+    return si_link_root;
+  }
+
+  if (s->next == NULL)
+  {
+    Werror("Can not initialize link type %s", type);
+    omFreeBin(ns, s_si_link_extension_bin);
+    return NULL;
+  }
+  return s->next;
+}
+
diff --git a/Singular/links/silink.h b/Singular/links/silink.h
new file mode 100644
index 0000000..4bee0c6
--- /dev/null
+++ b/Singular/links/silink.h
@@ -0,0 +1,131 @@
+#ifndef SILINK_H
+#define SILINK_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: general interface to links
+*/
+
+#include <misc/auxiliary.h>
+#include <kernel/structs.h>
+
+#include <Singular/links/sing_dbm.h>
+#include <Singular/lists.h>
+#include <Singular/attrib.h>
+
+struct sip_link;
+typedef struct sip_link    ip_link;
+typedef ip_link *          si_link;
+
+
+// extension links:
+typedef BOOLEAN    (*slOpenProc)(si_link l, short flag, leftv h);
+typedef BOOLEAN    (*slWriteProc)(si_link l, leftv lv);
+typedef BOOLEAN    (*slCloseProc)(si_link l);
+typedef BOOLEAN    (*slPrepCloseProc)(si_link l);
+typedef BOOLEAN    (*slKillProc)(si_link l);
+typedef leftv      (*slReadProc)(si_link l);
+typedef leftv      (*slRead2Proc)(si_link l, leftv a);
+typedef BOOLEAN    (*slDumpProc)(si_link l);
+typedef BOOLEAN    (*slGetDumpProc)(si_link l);
+typedef const char* (*slStatusProc)(si_link l, const char *request);
+typedef BOOLEAN    (*slSetRingProc)(si_link l, ring r, BOOLEAN send);
+
+struct s_si_link_extension
+{
+  si_link_extension next;
+  slOpenProc       Open;
+  slCloseProc      Close;
+  slPrepCloseProc  PrepClose;
+  slKillProc       Kill;
+  slReadProc       Read;
+  slRead2Proc      Read2;
+  slWriteProc      Write;
+  slDumpProc       Dump;
+  slGetDumpProc    GetDump;
+  slStatusProc     Status;
+  slSetRingProc    SetRing;
+  const char       *type;
+};
+
+struct sip_link
+{
+  si_link_extension m; // methods
+  char *mode;
+  char *name;          // used for filename and/or further specs
+  void *data;          // the link itself
+  BITSET flags;        // 0=close open = 1: read = 2: write = 3
+  short ref;           // reference counter
+};
+
+// flags:
+#define SI_LINK_CLOSE   0
+#define SI_LINK_OPEN    1
+#define SI_LINK_READ    2
+#define SI_LINK_WRITE   4
+
+// tests:
+#define SI_LINK_CLOSE_P(l)  (!(l)->flags)
+#define SI_LINK_OPEN_P(l)   ((l)->flags & SI_LINK_OPEN)
+#define SI_LINK_W_OPEN_P(l) ((l)->flags &  SI_LINK_WRITE)
+#define SI_LINK_R_OPEN_P(l) ((l)->flags &  SI_LINK_READ)
+#define SI_LINK_RW_OPEN_P(l) (SI_LINK_W_OPEN_P(l) && SI_LINK_R_OPEN_P(l))
+
+#define SI_LINK_SET_CLOSE_P(l)  ((l)->flags = SI_LINK_CLOSE)
+#define SI_LINK_SET_OPEN_P(l, flag)   ((l)->flags |= SI_LINK_OPEN |flag)
+#define SI_LINK_SET_W_OPEN_P(l) ((l)->flags |= (SI_LINK_OPEN | SI_LINK_WRITE))
+#define SI_LINK_SET_R_OPEN_P(l) ((l)->flags |= (SI_LINK_OPEN | SI_LINK_READ))
+#define SI_LINK_SET_RW_OPEN_P(l) ((l)->flags |= (SI_LINK_OPEN | SI_LINK_READ | SI_LINK_WRITE))
+
+BOOLEAN slOpen(si_link l, short flag, leftv h);
+BOOLEAN slClose(si_link l);
+BOOLEAN slPrepClose(si_link l);
+leftv   slRead(si_link l,leftv a=NULL);
+BOOLEAN slWrite(si_link l, leftv v);
+BOOLEAN slDump(si_link l);
+BOOLEAN slGetDump(si_link l);
+const char* slStatus(si_link l, const char *request);
+BOOLEAN slInit(si_link l, char *str);
+void slKill(si_link l);
+void slCleanUp(si_link l);
+void slStandardInit();
+inline si_link slCopy(si_link l)
+{
+  l->ref++;
+  return l;
+}
+
+#include <omalloc/omalloc.h>
+inline char* slString(si_link l)
+{
+  if (l->name != NULL)
+  {
+    return omStrDup(l->name);
+  }
+  else
+  {
+    return omStrDup("");
+  }
+}
+
+extern omBin s_si_link_extension_bin;
+extern omBin sip_link_bin;
+extern omBin ip_link_bin;
+
+int slStatusSsiL(lists L, int timeout);
+int ssiBatch(const char *host, const char * port);
+
+
+typedef struct
+{
+  leftv u;
+  si_link l;
+  void * next;
+} link_struct;
+
+typedef link_struct* link_list;
+
+extern link_list ssiToBeClosed;
+extern volatile BOOLEAN ssiToBeClosed_inactive;
+#endif // SILINK_H
diff --git a/Singular/links/simpleipc.h b/Singular/links/simpleipc.h
new file mode 100644
index 0000000..92daa8f
--- /dev/null
+++ b/Singular/links/simpleipc.h
@@ -0,0 +1,28 @@
+#include <semaphore.h>
+
+#ifndef _SIMPLEIPC_H
+#define _SIMPLEIPC_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+#define SIPC_MAX_SEMAPHORES 256
+
+#define USE_SEM_INIT 0
+
+extern sem_t *semaphore[SIPC_MAX_SEMAPHORES];
+extern int sem_acquired[SIPC_MAX_SEMAPHORES];
+
+int sipc_semaphore_init(int id, int count);
+int sipc_semaphore_exists(int id);
+int sipc_semaphore_acquire(int id);
+int sipc_semaphore_try_acquire(int id);
+int sipc_semaphore_get_value(int id);
+int sipc_semaphore_release(int id);
+
+int simpleipc_cmd(char *cmd, int id, int v);
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/Singular/links/sing_dbm.cc b/Singular/links/sing_dbm.cc
new file mode 100644
index 0000000..c291c0d
--- /dev/null
+++ b/Singular/links/sing_dbm.cc
@@ -0,0 +1,456 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+
+//**************************************************************************/
+//  'sing_dbm.cc' containes command to handle dbm-files under
+// Singular.
+//
+//**************************************************************************/
+
+#include <kernel/mod2.h>
+
+#  include <stdio.h>
+#  include <fcntl.h>
+#  include <errno.h>
+
+#ifdef HAVE_DBM
+
+#  include <omalloc/omalloc.h>
+#  include <Singular/tok.h>
+#  include <Singular/ipid.h>
+#  include <Singular/links/silink.h>
+#  include <Singular/links/sing_dbm.h>
+
+// #ifdef __CYGWIN__
+// #  define USE_GDBM
+// #  define BLOCKSIZE 1
+// #  define GDBM_STATIC
+// #  include <gdbm.h>
+// #endif
+
+#ifdef USE_GDBM
+typedef struct {
+  GDBM_FILE db;        // pointer to open database
+  int first;      // firstkey to look for?
+  datum actual;  // the actual key
+} GDBM_info;
+
+//**************************************************************************/
+LINKAGE BOOLEAN dbOpen(si_link l, short flag, leftv u)
+{
+  char *mode = "r";
+  GDBM_info *db;
+  datum d_key;
+  //  int dbm_flags = O_RDONLY | O_CREAT;  // open database readonly as default
+  int read_write= GDBM_READER;
+
+  if(flag & SI_LINK_WRITE)
+  {
+ //    if((l->mode==NULL)
+//     || ((l->mode[0]!='w')&&(l->mode[1]!='w')))
+//     {
+//       // request w- open, but mode is not "w" nor "rw" => fail
+//       return TRUE;
+//    }
+    //    dbm_flags = O_RDWR | O_CREAT;
+    read_write =  GDBM_WRCREAT | GDBM_NOLOCK;
+    mode = "rw";
+  }
+  if(flag & SI_LINK_READ)
+    {
+      if (strcmp(l->mode,"rw")==0) mode="rw";
+    }
+  //if (((db = (DBM_info *)omAlloc(sizeof *db)) != NULL)
+  //&&((db->db = dbm_open(l->name, dbm_flags, 0664 )) != NULL ))
+  db = (GDBM_info *)omAlloc0(sizeof *db);
+  if((db->db = gdbm_open(l->name, BLOCKSIZE, read_write, 0664, 0)) != NULL )
+  {
+//     if (db->first) // first created?
+//       {
+//         db->actual=gdbm_firstkey(db->db);
+//       }
+//     else
+//       {
+//     d_key=db->actual;
+//     if (d_key.dptr!=NULL)
+//       {
+//         db->actual=gdbm_nextkey(db->db,db->actual);
+//       }
+//     else { db->actual=gdbm_firstkey(db->db); }
+//      }
+    db->first=1;
+    if(flag & SI_LINK_WRITE)
+      SI_LINK_SET_W_OPEN_P(l);
+    else
+      SI_LINK_SET_R_OPEN_P(l);
+    l->data=(void *)(db);
+    omFree(l->mode);
+    l->mode=omStrDup(mode);
+    return FALSE;
+  }
+  Print("%d/%s",gdbm_errno,gdbm_strerror(gdbm_errno));
+  return TRUE;
+}
+
+//**************************************************************************/
+LINKAGE BOOLEAN dbClose(si_link l)
+{
+  GDBM_info *db = (GDBM_info *)l->data;
+  gdbm_sync(db->db);
+  gdbm_close(db->db);
+  omFreeSize((ADDRESS)db,(sizeof *db));
+  l->data=NULL;
+  SI_LINK_SET_CLOSE_P(l);
+  return FALSE;
+}
+
+//**************************************************************************/
+static datum d_value;
+LINKAGE leftv dbRead2(si_link l, leftv key)
+{
+  GDBM_info *db = (GDBM_info *)l->data;
+  // GDBM_info *db;
+//   db = (GDBM_info *)omAlloc0(sizeof *db);
+//   db = (GDBM_info *)l->data;
+  leftv v=NULL;
+  datum d_key;
+  int flag;
+
+  if (!SI_LINK_R_OPEN_P(l)) //exceptions
+    //  if (strcmp(l->mode,"rw")==0) //rw-mode
+    {
+      if (!SI_LINK_CLOSE_P(l))
+	{
+	  if (!dbClose(l)) {Print("cannot close link!\n");}
+	}
+      //(SI_LINK_CLOSE_P(l)) automatically
+      if (dbOpen(l, SI_LINK_READ)) return NULL;
+    }
+  if (SI_LINK_RW_OPEN_P(l)) {Print("I/O Error!\n");}
+
+  if(key!=NULL)
+  {
+    if (key->Typ()==STRING_CMD)
+    {
+      d_key.dptr = (char*)key->Data();
+      d_key.dsize = strlen(d_key.dptr)+1;
+      d_value = gdbm_fetch(db->db, d_key);
+      v=(leftv)omAlloc0Bin(sleftv_bin);
+      if (d_value.dptr!=NULL) v->data=omStrDup(d_value.dptr);
+      else                    v->data=omStrDup("");
+      v->rtyp=STRING_CMD;
+    }
+    else
+    {
+      WerrorS("read(`GDBM link`,`string`) expected");
+    }
+  }
+  else
+  {
+    if (db->first)
+    {
+      db->first=0;
+      d_key = gdbm_firstkey(db->db);
+   //    db->actual=d_key;
+//       Print("firstkey:%s\n",d_key.dptr);
+    }
+    else
+    {
+      if (db->actual.dptr==NULL)
+      {
+	db->actual=gdbm_firstkey(db->db);
+      }
+      d_key = gdbm_nextkey(db->db,db->actual);
+      db->actual=d_key;
+      if (d_key.dptr==NULL)
+      {
+        db->first=1;
+      // Print("nextkey:NULL\n");
+      }
+     //  else
+//       Print("nextkey:%s\n",d_key.dptr);
+    }
+
+    if (d_key.dptr!=NULL)
+      d_value = gdbm_fetch(db->db, d_key);
+    else
+      d_value.dptr=NULL;
+
+    v=(leftv)omAlloc0Bin(sleftv_bin);
+    v->rtyp=STRING_CMD;
+    if (d_value.dptr!=NULL)
+    {
+      v->data=omStrDup(d_key.dptr);
+      db->first = 0;
+    }
+    else
+    {
+      v->data=omStrDup("");
+      //      db->first = 1;
+    }
+
+  }
+  return v;
+}
+LINKAGE leftv dbRead1(si_link l)
+{
+  return dbRead2(l,NULL);
+}
+//**************************************************************************/
+LINKAGE BOOLEAN dbWrite(si_link l, leftv key)
+{
+  GDBM_info *db = (GDBM_info *)l->data;
+ //  GDBM_info *db;
+//   db = (GDBM_info *)omAlloc0(sizeof *db);
+//   db = (GDBM_info *)l->data;
+  BOOLEAN b=TRUE;
+  register int ret;
+
+  if (strcmp(l->mode,"rw")!=0) // r-mode
+    {
+      Print("Write error on readonly source\n");
+    }
+  else //rw-mode
+    {
+      if (!SI_LINK_W_OPEN_P(l)) //exceptions
+	{
+	  if (!SI_LINK_CLOSE_P(l))
+	    {
+	      if (!dbClose(l)) {Print("close error\n");};
+	    }
+	  if (!dbOpen(l,SI_LINK_WRITE)) {Print("open_for_write error\n");}
+	}
+    }
+
+  if((key!=NULL) && (key->Typ()==STRING_CMD) )
+  {
+    if (key->next!=NULL)                   // have a second parameter ?
+    {
+      if(key->next->Typ()==STRING_CMD)     // replace (key,value)
+      {
+        datum d_key, d_value;
+
+        d_key.dptr = (char *)key->Data();
+        d_key.dsize = strlen(d_key.dptr)+1;
+        d_value.dptr = (char *)key->next->Data();
+        d_value.dsize = strlen(d_value.dptr)+1;
+        ret  = gdbm_store(db->db, d_key, d_value, GDBM_REPLACE);
+//         db->actual=d_key;
+	if (ret==-1) {Print("reader calls gdbm_store!");}
+        if (ret==0)
+          { b=FALSE; }
+        else
+        {
+          //          if(gdbm_error(db->db))
+          if (gdbm_errno != 0)
+          {
+            Werror("GDBM link I/O error: '%s' ", gdbm_errno);
+	    //            Print(gdbm_strerror(gdbm_errno));
+            //dbm_clearerr(db->db);
+	    //            gdbm_errno=0;
+          }
+        }
+      }
+    }
+    else
+    {                               // delete (key)
+      datum d_key;
+
+      d_key.dptr = (char *)key->Data();
+      d_key.dsize = strlen(d_key.dptr)+1;
+ //      db->actual=gdbm_nextkey(db->db,d_key);
+      gdbm_delete(db->db, d_key);
+      b=FALSE;
+    }
+  }
+  else
+  {
+    WerrorS("write(`GDBM link`,`key string` [,`data string`]) expected");
+  }
+  gdbm_sync(db->db);
+  return b;
+}
+#endif /* USE_GDBM */
+
+#ifndef USE_GDBM
+/* These are the routines in dbm. */
+#  include "ndbm.h"
+typedef struct {
+  DBM *db;        // pointer to open database
+  int first;      // firstkey to look for?
+} DBM_info;
+
+//**************************************************************************/
+LINKAGE BOOLEAN dbOpen(si_link l, short flag, leftv /*u*/)
+{
+  const char *mode = "r";
+  DBM_info *db;
+  int dbm_flags = O_RDONLY | O_CREAT;  // open database readonly as default
+
+  if((l->mode!=NULL)
+  && ((l->mode[0]=='w')||(l->mode[1]=='w')))
+  {
+    dbm_flags = O_RDWR | O_CREAT;
+    mode = "rw";
+    flag|=SI_LINK_WRITE|SI_LINK_READ;
+  }
+  else if(flag & SI_LINK_WRITE)
+  {
+    // request w- open, but mode is not "w" nor "rw" => fail
+    return TRUE;
+  }
+  //if (((db = (DBM_info *)omAlloc(sizeof *db)) != NULL)
+  //&&((db->db = dbm_open(l->name, dbm_flags, 0664 )) != NULL ))
+  db = (DBM_info *)omAlloc(sizeof *db);
+  if((db->db = dbm_open(l->name, dbm_flags, 0664 )) != NULL )
+  {
+    db->first=1;
+    if(flag & SI_LINK_WRITE)
+      SI_LINK_SET_RW_OPEN_P(l);
+    else
+      SI_LINK_SET_R_OPEN_P(l);
+    l->data=(void *)(db);
+    omFree(l->mode);
+    l->mode=omStrDup(mode);
+    return FALSE;
+  }
+  return TRUE;
+}
+
+//**************************************************************************/
+LINKAGE BOOLEAN dbClose(si_link l)
+{
+  DBM_info *db = (DBM_info *)l->data;
+
+  dbm_close(db->db);
+  omFreeSize((ADDRESS)db,(sizeof *db));
+  l->data=NULL;
+  SI_LINK_SET_CLOSE_P(l);
+  return FALSE;
+}
+
+//**************************************************************************/
+static datum d_value;
+LINKAGE leftv dbRead2(si_link l, leftv key)
+{
+  DBM_info *db = (DBM_info *)l->data;
+  leftv v=NULL;
+  datum d_key;
+
+  if(key!=NULL)
+  {
+    if (key->Typ()==STRING_CMD)
+    {
+      d_key.dptr = (char*)key->Data();
+      d_key.dsize = strlen(d_key.dptr)+1;
+      d_value = dbm_fetch(db->db, d_key);
+      v=(leftv)omAlloc0Bin(sleftv_bin);
+      if (d_value.dptr!=NULL) v->data=omStrDup(d_value.dptr);
+      else                    v->data=omStrDup("");
+      v->rtyp=STRING_CMD;
+    }
+    else
+    {
+      WerrorS("read(`DBM link`,`string`) expected");
+    }
+  }
+  else
+  {
+    if(db->first)
+      d_value = dbm_firstkey((DBM *)db->db);
+    else
+      d_value = dbm_nextkey((DBM *)db->db);
+
+    v=(leftv)omAlloc0Bin(sleftv_bin);
+    v->rtyp=STRING_CMD;
+    if (d_value.dptr!=NULL)
+    {
+      v->data=omStrDup(d_value.dptr);
+      db->first = 0;
+    }
+    else
+    {
+      v->data=omStrDup("");
+      db->first = 1;
+    }
+
+  }
+  return v;
+}
+LINKAGE leftv dbRead1(si_link l)
+{
+  return dbRead2(l,NULL);
+}
+//**************************************************************************/
+LINKAGE BOOLEAN dbWrite(si_link l, leftv key)
+{
+  DBM_info *db = (DBM_info *)l->data;
+  BOOLEAN b=TRUE;
+  register int ret;
+
+  // database is opened
+  if((key!=NULL) && (key->Typ()==STRING_CMD) )
+  {
+    if (key->next!=NULL)                   // have a second parameter ?
+    {
+      if(key->next->Typ()==STRING_CMD)     // replace (key,value)
+      {
+        datum d_key, d_value;
+
+        d_key.dptr = (char *)key->Data();
+        d_key.dsize = strlen(d_key.dptr)+1;
+        d_value.dptr = (char *)key->next->Data();
+        d_value.dsize = strlen(d_value.dptr)+1;
+        ret  = dbm_store(db->db, d_key, d_value, DBM_REPLACE);
+        if(!ret )
+          b=FALSE;
+        else
+        {
+          if(dbm_error(db->db))
+          {
+            Werror("DBM link I/O error. Is '%s' readonly?", l->name);
+            dbm_clearerr(db->db);
+          }
+        }
+      }
+    }
+    else
+    {                               // delete (key)
+      datum d_key;
+
+      d_key.dptr = (char *)key->Data();
+      d_key.dsize = strlen(d_key.dptr)+1;
+      dbm_delete(db->db, d_key);
+      b=FALSE;
+    }
+  }
+  else
+  {
+    WerrorS("write(`DBM link`,`key string` [,`data string`]) expected");
+  }
+  return b;
+}
+//**************************************************************************/
+//char *dbStatus(si_link l, char *request)
+//{
+//  if (strcmp(request, "read") == 0)
+//  {
+//    if (SI_LINK_R_OPEN_P(l))
+//      return "ready";
+//    else
+//      return "not ready";
+//  }
+//  else if (strcmp(request, "write") == 0)
+//  {
+//    if (SI_LINK_W_OPEN_P(l))
+//      return "ready";
+//    else
+//      return "not ready";
+//  }
+//  else return "unknown status request";
+//}
+//**************************************************************************/
+
+#endif /* USE_GDBM */
+#endif /* HAVE_DBM */
diff --git a/Singular/links/sing_dbm.h b/Singular/links/sing_dbm.h
new file mode 100644
index 0000000..3382623
--- /dev/null
+++ b/Singular/links/sing_dbm.h
@@ -0,0 +1,14 @@
+#ifndef SING_DBM_H
+#define SING_DBM_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: interface to DBM links
+*/
+
+struct s_si_link_extension;
+typedef struct s_si_link_extension *si_link_extension;
+
+si_link_extension slInitDBMExtension(si_link_extension s);
+#endif
diff --git a/Singular/links/slInit.h b/Singular/links/slInit.h
new file mode 100644
index 0000000..e7ecf88
--- /dev/null
+++ b/Singular/links/slInit.h
@@ -0,0 +1,20 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    slInit.h
+ *  Purpose: declarations of link initialization functions
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 12/00
+ *******************************************************************/
+#ifndef SL_INIT_H
+#define SL_INIT_H
+
+#include <Singular/links/silink.h>
+
+#ifdef HAVE_DBM
+si_link_extension slInitDBMExtension(si_link_extension s);
+#endif
+const char* slStatusAscii(si_link l,const  char* request);
+
+#endif // SL_INIT_H
diff --git a/Singular/links/slInit_Dynamic.cc b/Singular/links/slInit_Dynamic.cc
new file mode 100644
index 0000000..1a195db
--- /dev/null
+++ b/Singular/links/slInit_Dynamic.cc
@@ -0,0 +1,57 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    slInit_Dynamic.cc
+ *  Purpose: link initialization for dynamic linking
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 12/00
+ *******************************************************************/
+
+
+
+
+#include <kernel/mod2.h>
+#include <Singular/links/silink.h>
+#include <Singular/links/slInit.h>
+#include <Singular/mod_lib.h>
+
+#ifdef HAVE_DL
+
+#ifdef HAVE_DBM
+#include "dbm_sl.h"
+
+static void* dbm_so_handle = NULL;
+static void* slInitDBMHandle()
+{
+  if (dbm_so_handle == NULL)
+    dbm_so_handle = dynl_open_binary_warn("dbmsr");
+
+  return dbm_so_handle;
+}
+
+si_link_extension slInitDBMExtension(si_link_extension s)
+{
+  void* handle = slInitDBMHandle();
+
+  if (handle == NULL) return NULL;
+
+  s->Open=(slOpenProc)dynl_sym_warn(handle, "dbOpen");
+  s->Close=(slCloseProc)dynl_sym_warn(handle, "dbClose");
+  s->Kill=NULL;
+  s->Read=(slReadProc)dynl_sym_warn(handle, "dbRead1");
+  s->Read2=(slRead2Proc)dynl_sym_warn(handle, "dbRead2");
+  s->Write=(slWriteProc)dynl_sym_warn(handle, "dbWrite");
+
+  if (s->Open == NULL || s->Close == NULL ||
+      s->Read == NULL || s->Read2 == NULL)
+    return NULL;
+
+  s->Status=slStatusAscii;
+  s->type="DBM";
+  return s;
+}
+
+#endif
+#endif
+
diff --git a/Singular/links/slInit_Static.cc b/Singular/links/slInit_Static.cc
new file mode 100644
index 0000000..415f293
--- /dev/null
+++ b/Singular/links/slInit_Static.cc
@@ -0,0 +1,39 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    slInit_Static.cc
+ *  Purpose: link initialization for static linking
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 12/00
+ *******************************************************************/
+
+
+
+
+#include <kernel/mod2.h>
+
+#include <Singular/links/silink.h>
+#include <Singular/links/slInit.h>
+
+#ifdef HAVE_DBM
+
+# ifndef USE_GDBM
+#   include <Singular/links/dbm_sl.h>
+# else
+#   include <Singular/links/sing_dbm.h>
+#endif
+
+si_link_extension slInitDBMExtension(si_link_extension s)
+{
+  s->Open=dbOpen;
+  s->Close=dbClose;
+  s->Kill=dbClose;
+  s->Read=dbRead1;
+  s->Read2=dbRead2;
+  s->Write=dbWrite;
+  s->Status=slStatusAscii;
+  s->type="DBM";
+  return s;
+}
+#endif /* #ifdef HAVE_DBM */
diff --git a/Singular/links/ssiLink.cc b/Singular/links/ssiLink.cc
new file mode 100644
index 0000000..c1d084c
--- /dev/null
+++ b/Singular/links/ssiLink.cc
@@ -0,0 +1,2067 @@
+/****************************************
+ * Computer Algebra System SINGULAR     *
+ ****************************************/
+/***************************************************************
+ * File:    ssiLink.h
+ *  Purpose: declaration of sl_link routines for ssi
+ ***************************************************************/
+#define TRANSEXT_PRIVATES 1 /* allow access to transext internals */
+
+#include <kernel/mod2.h>
+
+#include <omalloc/omalloc.h>
+
+#include <misc/intvec.h>
+#include <misc/options.h>
+
+#include <reporter/si_signals.h>
+#include <reporter/s_buff.h>
+
+#include <coeffs/bigintmat.h>
+#include <coeffs/longrat.h>
+
+#include <polys/monomials/ring.h>
+#include <polys/monomials/p_polys.h>
+#include <polys/ext_fields/transext.h>
+#include <polys/simpleideals.h>
+#include <polys/matpol.h>
+
+#include <kernel/oswrapper/timer.h>
+#include <kernel/oswrapper/feread.h>
+#include <kernel/oswrapper/rlimit.h>
+
+#include <Singular/tok.h>
+#include <Singular/ipid.h>
+#include <Singular/ipshell.h>
+#include <Singular/subexpr.h>
+#include <Singular/links/silink.h>
+#include <Singular/cntrlc.h>
+#include <Singular/lists.h>
+#include <Singular/blackbox.h>
+#include <Singular/links/ssiLink.h>
+
+#ifdef HAVE_SIMPLEIPC
+#include <Singular/links/simpleipc.h>
+#endif
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <signal.h>
+#include <sys/types.h>          /* for portability */
+#include <sys/select.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <ctype.h>   /*for isdigit*/
+#include <netdb.h>
+#include <sys/wait.h>
+#include <time.h>
+
+#define SSI_VERSION 8
+// 5->6: changed newstruct representation
+// 6->7: attributes
+// 7->8: qring
+
+#define SSI_BASE 16
+typedef struct
+{
+  s_buff f_read;
+  FILE *f_write;
+  ring r;
+  pid_t pid; /* only valid for fork/tcp mode*/
+  int fd_read,fd_write; /* only valid for fork/tcp mode*/
+  char level;
+  char send_quit_at_exit;
+  char quit_sent;
+
+} ssiInfo;
+
+link_list ssiToBeClosed=NULL;
+volatile BOOLEAN ssiToBeClosed_inactive=TRUE;
+
+// forward declarations:
+void ssiWritePoly_R(const ssiInfo *d, int typ, poly p, const ring r);
+void ssiWriteIdeal(const ssiInfo *d, int typ,ideal I);
+poly ssiReadPoly_R(const ssiInfo *D, const ring r);
+ideal ssiReadIdeal_R(const ssiInfo *d,const ring r);
+
+// the helper functions:
+void ssiSetCurrRing(const ring r)
+{
+  //  if (currRing!=NULL)
+  //  Print("need to change the ring, currRing:%s, switch to: ssiRing%d\n",IDID(currRingHdl),nr);
+  //  else
+  //  Print("no ring, switch to ssiRing%d\n",nr);
+  if (!rEqual(r,currRing,1))
+  {
+    char name[20];
+    int nr=0;
+    do
+    { sprintf(name,"ssiRing%d",nr); nr++; }
+    while(IDROOT->get(name, 0)!=NULL);
+    idhdl h=enterid(omStrDup(name),0,RING_CMD,&IDROOT,FALSE);
+    IDRING(h)=r;
+    r->ref++;
+    rSetHdl(h);
+  }
+}
+// the implementation of the functions:
+void ssiWriteInt(const ssiInfo *d,const int i)
+{
+  fprintf(d->f_write,"%d ",i);
+  //if (d->f_debug!=NULL) fprintf(d->f_debug,"int: %d ",i);
+}
+
+void ssiWriteString(const ssiInfo *d,const char *s)
+{
+  fprintf(d->f_write,"%d %s ",(int)strlen(s),s);
+  //if (d->f_debug!=NULL) fprintf(d->f_debug,"stringi: %d \"%s\" ",strlen(s),s);
+}
+
+void ssiWriteBigInt(const ssiInfo *d, const number n)
+{
+ n_WriteFd(n,d->f_write,coeffs_BIGINT);
+}
+
+void ssiWriteNumber_CF(const ssiInfo *d, const number n, const coeffs cf)
+{
+  // syntax is as follows:
+  // case 1 Z/p:   3 <int>
+  // case 2 Q:     3 4 <int>
+  //        or     3 0 <mpz_t nominator> <mpz_t denominator>
+  //        or     3 1  dto.
+  //        or     3 3 <mpz_t nominator>
+  //        or     3 5 <mpz_t raw nom.> <mpz_t raw denom.>
+  //        or     3 6 <mpz_t raw nom.> <mpz_t raw denom.>
+  //        or     3 8 <mpz_t raw nom.>
+  if (getCoeffType(cf)==n_transExt)
+  {
+    fraction f=(fraction)n;
+    ssiWritePoly_R(d,POLY_CMD,NUM(f),cf->extRing);
+    ssiWritePoly_R(d,POLY_CMD,DEN(f),cf->extRing);
+  }
+  else if (getCoeffType(cf)==n_algExt)
+  {
+    ssiWritePoly_R(d,POLY_CMD,(poly)n,cf->extRing);
+  }
+  else if (cf->cfWriteFd!=NULL)
+  {
+    n_WriteFd(n,d->f_write,cf);
+  }
+  else WerrorS("coeff field not implemented");
+}
+
+void ssiWriteNumber(const ssiInfo *d, const number n)
+{
+  ssiWriteNumber_CF(d,n,d->r->cf);
+}
+
+void ssiWriteRing_R(ssiInfo *d,const ring r)
+{
+  /* 5 <ch> <N> <l1> <v1> ...<lN> <vN> <number of orderings> <ord1> <block0_1> <block1_1> .... <extRing> <Q-ideal> */
+  /* ch=-1: transext, coeff ring follows */
+  /* ch=-2: algext, coeff ring and minpoly follows */
+  if (r!=NULL)
+  {
+    if (rField_is_Q(r) || rField_is_Zp(r))
+      fprintf(d->f_write,"%d %d ",n_GetChar(r->cf),r->N);
+    else if (rFieldType(r)==n_transExt)
+      fprintf(d->f_write,"-1 %d ",r->N);
+    else if (rFieldType(r)==n_algExt)
+      fprintf(d->f_write,"-2 %d ",r->N);
+    else /*dummy*/
+      fprintf(d->f_write,"0 %d ",r->N);
+
+    int i;
+    for(i=0;i<r->N;i++)
+    {
+      fprintf(d->f_write,"%d %s ",(int)strlen(r->names[i]),r->names[i]);
+    }
+    /* number of orderings:*/
+    i=0;
+    // remember dummy ring: everything 0:
+    if (r->order!=NULL) while (r->order[i]!=0) i++;
+    fprintf(d->f_write,"%d ",i);
+    /* each ordering block: */
+    i=0;
+    if (r->order!=NULL) while(r->order[i]!=0)
+    {
+      fprintf(d->f_write,"%d %d %d ",r->order[i],r->block0[i], r->block1[i]);
+      switch(r->order[i])
+      {
+        case ringorder_a:
+        case ringorder_wp:
+        case ringorder_Wp:
+        case ringorder_ws:
+        case ringorder_Ws:
+        case ringorder_aa:
+        {
+          int ii;
+          for(ii=r->block0[i];ii<=r->block1[i];ii++)
+            fprintf(d->f_write,"%d ",r->wvhdl[i][ii-r->block0[i]]);
+        }
+        break;
+
+        case ringorder_a64:
+        case ringorder_M:
+        case ringorder_L:
+        case ringorder_IS:
+          Werror("ring oder not implemented for ssi:%d",r->order[i]);
+          break;
+
+        default: break;
+      }
+      i++;
+    }
+    if ((rFieldType(r)==n_transExt)
+    || (rFieldType(r)==n_algExt))
+    {
+      ssiWriteRing_R(d,r->cf->extRing);
+      if  (rFieldType(r)==n_algExt)
+      {
+        ssiWritePoly_R(d,POLY_CMD,r->cf->extRing->qideal->m[0],r->cf->extRing);
+      }
+    }
+    /* Q-ideal :*/
+    if (r->qideal!=NULL)
+    {
+      ssiWriteIdeal(d,IDEAL_CMD,r->qideal);
+    }
+    else
+    {
+      fprintf(d->f_write,"0 "/*ideal with 0 entries */);
+    }
+  }
+  else /* dummy ring r==NULL*/
+  {
+    fprintf(d->f_write,"0 0 0 0 "/*,r->ch,r->N, blocks, q-ideal*/);
+  }
+}
+
+void ssiWriteRing(ssiInfo *d,const ring r)
+{
+  /* 5 <ch> <N> <l1> <v1> ...<lN> <vN> <number of orderings> <ord1> <block0_1> <block1_1> .... <extRing> <Q-ideal> */
+  /* ch=-1: transext, coeff ring follows */
+  /* ch=-2: algext, coeff ring and minpoly follows */
+  if (r==currRing) // see recursive calls for transExt/algExt
+  {
+    if (d->r!=NULL) rKill(d->r);
+    d->r=r;
+  }
+  if (r!=NULL)
+  {
+    /*d->*/r->ref++;
+  }
+  ssiWriteRing_R(d,r);
+}
+void ssiWritePoly_R(const ssiInfo *d, int typ, poly p, const ring r)
+{
+  fprintf(d->f_write,"%d ",pLength(p));//number of terms
+
+  while(p!=NULL)
+  {
+    ssiWriteNumber_CF(d,pGetCoeff(p),r->cf);
+    //nWrite(fich,pGetCoeff(p));
+    fprintf(d->f_write,"%ld ",p_GetComp(p,r));//component
+
+    for(int j=1;j<=rVar(r);j++)
+    {
+      fprintf(d->f_write,"%ld ",p_GetExp(p,j,r ));//x^j
+    }
+    pIter(p);
+  }
+}
+
+void ssiWritePoly(const ssiInfo *d, int typ, poly p)
+{
+  ssiWritePoly_R(d,typ,p,d->r);
+}
+
+void ssiWriteIdeal(const ssiInfo *d, int typ,ideal I)
+{
+   // syntax: 7 # of elements <poly 1> <poly2>.....
+   // syntax: 8 <rows> <cols> <poly 1> <poly2>.....
+   matrix M=(matrix)I;
+   int mn;
+   if (typ==MATRIX_CMD)
+   {
+     mn=MATROWS(M)*MATCOLS(M);
+     fprintf(d->f_write,"%d %d ", MATROWS(M),MATCOLS(M));
+   }
+   else
+   {
+     mn=IDELEMS(I);
+     fprintf(d->f_write,"%d ",IDELEMS(I));
+   }
+
+   int i;
+   int tt;
+   if (typ==MODUL_CMD) tt=VECTOR_CMD;
+   else                tt=POLY_CMD;
+
+   for(i=0;i<mn;i++)
+   {
+     ssiWritePoly(d,tt,I->m[i]);
+   }
+}
+
+void ssiWriteCommand(si_link l, command D)
+{
+  ssiInfo *d=(ssiInfo*)l->data;
+  // syntax: <num ops> <operation> <op1> <op2> ....
+  fprintf(d->f_write,"%d %d ",D->argc,D->op);
+  if (D->argc >0) ssiWrite(l, &(D->arg1));
+  if (D->argc < 4)
+  {
+    if (D->argc >1) ssiWrite(l, &(D->arg2));
+    if (D->argc >2) ssiWrite(l, &(D->arg3));
+  }
+}
+
+void ssiWriteProc(const ssiInfo *d,procinfov p)
+{
+  if (p->data.s.body==NULL)
+    iiGetLibProcBuffer(p);
+  if (p->data.s.body!=NULL)
+    ssiWriteString(d,p->data.s.body);
+  else
+    ssiWriteString(d,"");
+}
+
+void ssiWriteList(si_link l,lists dd)
+{
+  ssiInfo *d=(ssiInfo*)l->data;
+  int Ll=lSize(dd);
+  fprintf(d->f_write,"%d ",Ll+1);
+  int i;
+  for(i=0;i<=Ll;i++)
+  {
+    ssiWrite(l,&(dd->m[i]));
+  }
+}
+void ssiWriteIntvec(const ssiInfo *d,intvec * v)
+{
+  fprintf(d->f_write,"%d ",v->length());
+  int i;
+  for(i=0;i<v->length();i++)
+  {
+    fprintf(d->f_write,"%d ",(*v)[i]);
+  }
+}
+void ssiWriteIntmat(const ssiInfo *d,intvec * v)
+{
+  fprintf(d->f_write,"%d %d ",v->rows(),v->cols());
+  int i;
+  for(i=0;i<v->length();i++)
+  {
+    fprintf(d->f_write,"%d ",(*v)[i]);
+  }
+}
+
+void ssiWriteBigintmat(const ssiInfo *d,bigintmat * v)
+{
+  fprintf(d->f_write,"%d %d ",v->rows(),v->cols());
+  int i;
+  for(i=0;i<v->length();i++)
+  {
+    ssiWriteBigInt(d,(*v)[i]);
+  }
+}
+
+char *ssiReadString(const ssiInfo *d)
+{
+  char *buf;
+  int l;
+  l=s_readint(d->f_read);
+  buf=(char*)omAlloc0(l+1);
+  int c =s_getc(d->f_read); /* skip ' '*/
+  int ll=s_readbytes(buf,l,d->f_read);
+  //if (ll!=l) printf("want %d, got %d bytes\n",l,ll);
+  buf[l]='\0';
+  return buf;
+}
+
+int ssiReadInt(s_buff fich)
+{
+  return s_readint(fich);
+}
+
+number ssiReadNumber_CF(const ssiInfo *d, const coeffs cf)
+{
+  if (cf->cfReadFd!=NULL)
+  {
+     return n_ReadFd(d->f_read,cf);
+  }
+  else if (getCoeffType(cf) == n_transExt)
+  {
+    // poly poly
+    fraction f=(fraction)n_Init(1,cf);
+    p_Delete(&NUM(f),cf->extRing);
+    NUM(f)=ssiReadPoly_R(d,cf->extRing);
+    DEN(f)=ssiReadPoly_R(d,cf->extRing);
+    return (number)f;
+  }
+  else if (getCoeffType(cf) == n_algExt)
+  {
+    // poly
+    return (number)ssiReadPoly_R(d,cf->extRing);
+  }
+  else Werror("coeffs not implemented in ssiReadNumber");
+  return NULL;
+}
+
+number ssiReadBigInt(const ssiInfo *d)
+{
+  number n=ssiReadNumber_CF(d,coeffs_BIGINT);
+  if ((SR_HDL(n) & SR_INT)==0)
+  {
+    if (n->s!=3) Werror("invalid sub type in bigint:%d",n->s);
+  }
+  return n;
+}
+
+number ssiReadNumber(const ssiInfo *d)
+{
+  return ssiReadNumber_CF(d,d->r->cf);
+}
+
+ring ssiReadRing(const ssiInfo *d)
+{
+/* syntax is <ch> <N> <l1> <v1> ...<lN> <vN> <number of orderings> <ord1> <block0_1> <block1_1> .... <Q-ideal> */
+  int ch, N,i;
+  char **names;
+  ch=s_readint(d->f_read);
+  N=s_readint(d->f_read);
+  if (N!=0)
+  {
+    names=(char**)omAlloc(N*sizeof(char*));
+    for(i=0;i<N;i++)
+    {
+      names[i]=ssiReadString(d);
+    }
+  }
+  // read the orderings:
+  int num_ord; // number of orderings
+  num_ord=s_readint(d->f_read);
+  int *ord=(int *)omAlloc0((num_ord+1)*sizeof(int));
+  int *block0=(int *)omAlloc0((num_ord+1)*sizeof(int));
+  int *block1=(int *)omAlloc0((num_ord+1)*sizeof(int));
+  int **wvhdl=(int**)omAlloc0((num_ord+1)*sizeof(int*));
+  for(i=0;i<num_ord;i++)
+  {
+    ord[i]=s_readint(d->f_read);
+    block0[i]=s_readint(d->f_read);
+    block1[i]=s_readint(d->f_read);
+    switch(ord[i])
+    {
+      case ringorder_a:
+      case ringorder_wp:
+      case ringorder_Wp:
+      case ringorder_ws:
+      case ringorder_Ws:
+      case ringorder_aa:
+      {
+        wvhdl[i]=(int*)omAlloc((block1[i]-block0[i]+1)*sizeof(int));
+        int ii;
+        for(ii=block0[i];ii<=block1[i];ii++)
+          wvhdl[i][ii-block0[i]]=s_readint(d->f_read);
+      }
+      break;
+
+      case ringorder_a64:
+      case ringorder_M:
+      case ringorder_L:
+      case ringorder_IS:
+        Werror("ring oder not implemented for ssi:%d",ord[i]);
+        break;
+
+      default: break;
+    }
+  }
+  if (N==0)
+  {
+    omFree(ord);
+    omFree(block0);
+    omFree(block1);
+    omFree(wvhdl);
+    return NULL;
+  }
+  else
+  {
+    ring r=NULL;
+    if (ch>=0) /* Q, Z/p */
+      r=rDefault(ch,N,names,num_ord,ord,block0,block1,wvhdl);
+    else if (ch==-1) /* trans ext. */
+    {
+      TransExtInfo T;
+      T.r=ssiReadRing(d);
+      coeffs cf=nInitChar(n_transExt,&T);
+      r=rDefault(cf,N,names,num_ord,ord,block0,block1,wvhdl);
+    }
+    else if (ch==-2) /* alg ext. */
+    {
+      TransExtInfo T;
+      T.r=ssiReadRing(d);
+      T.r->qideal=idInit(1,1);
+      T.r->qideal->m[0]=ssiReadPoly_R(d,T.r);
+      coeffs cf=nInitChar(n_algExt,&T);
+      r=rDefault(cf,N,names,num_ord,ord,block0,block1,wvhdl);
+    }
+    else
+    {
+      Werror("ssi: read unknown coeffs type (%d)",ch);
+      return NULL;
+    }
+    ideal q=ssiReadIdeal_R(d,r);
+    if (IDELEMS(q)==0) omFreeBin(q,sip_sideal_bin);
+    else r->qideal=q;
+    return r;
+  }
+}
+
+poly ssiReadPoly_R(const ssiInfo *D, const ring r)
+{
+// < # of terms> < term1> < .....
+  int n,i,l;
+  n=ssiReadInt(D->f_read);
+  //Print("poly: terms:%d\n",n);
+  poly p;
+  poly ret=NULL;
+  poly prev=NULL;
+  for(l=0;l<n;l++) // read n terms
+  {
+// coef,comp.exp1,..exp N
+    p=p_Init(r);
+    pSetCoeff0(p,ssiReadNumber_CF(D,r->cf));
+    int d;
+    d=s_readint(D->f_read);
+    p_SetComp(p,d,r);
+    for(i=1;i<=rVar(r);i++)
+    {
+      d=s_readint(D->f_read);
+      p_SetExp(p,i,d,r);
+    }
+    p_Setm(p,r);
+    p_Test(p,r);
+    if (ret==NULL) ret=p;
+    else           pNext(prev)=p;
+    prev=p;
+ }
+ return ret;
+}
+
+poly ssiReadPoly(const ssiInfo *D)
+{
+// < # of terms> < term1> < .....
+  return ssiReadPoly_R(D,D->r);
+}
+
+ideal ssiReadIdeal_R(const ssiInfo *d,const ring r)
+{
+  int n,i;
+  ideal I;
+  n=s_readint(d->f_read);
+  I=idInit(n,1);
+  for(i=0;i<IDELEMS(I);i++) // read n terms
+  {
+    I->m [i]=ssiReadPoly_R(d,r);
+  }
+  return I;
+}
+
+ideal ssiReadIdeal(const ssiInfo *d)
+{
+  return ssiReadIdeal_R(d,d->r);
+}
+
+matrix ssiReadMatrix(const ssiInfo *d)
+{
+  int n,m;
+  m=s_readint(d->f_read);
+  n=s_readint(d->f_read);
+  matrix M=mpNew(m,n);
+  poly p;
+  for(int i=1;i<=MATROWS(M);i++)
+    for(int j=1;j<=MATCOLS(M);j++)
+    {
+      p=ssiReadPoly(d);
+      MATELEM(M,i,j)=p;
+    }
+  return M;
+}
+
+command ssiReadCommand(si_link l)
+{
+  ssiInfo *d=(ssiInfo*)l->data;
+  // syntax: <num ops> <operation> <op1> <op2> ....
+  command D=(command)omAlloc0(sizeof(*D));
+  int argc,op;
+  argc=s_readint(d->f_read);
+  op=s_readint(d->f_read);
+  D->argc=argc; D->op=op;
+  leftv v;
+  if (argc >0)
+  {
+    v=ssiRead1(l);
+    memcpy(&(D->arg1),v,sizeof(*v));
+    omFreeBin(v,sleftv_bin);
+  }
+  if (argc <4)
+  {
+    if (D->argc >1)
+    {
+      v=ssiRead1(l);
+      memcpy(&(D->arg2),v,sizeof(*v));
+      omFreeBin(v,sleftv_bin);
+    }
+    if (D->argc >2)
+    {
+      v=ssiRead1(l);
+      memcpy(&(D->arg3),v,sizeof(*v));
+      omFreeBin(v,sleftv_bin);
+    }
+  }
+  else
+  {
+    leftv prev=&(D->arg1);
+    argc--;
+    while(argc >0)
+    {
+      v=ssiRead1(l);
+      prev->next=v;
+      prev=v;
+      argc--;
+    }
+  }
+  return D;
+}
+
+procinfov ssiReadProc(const ssiInfo *d)
+{
+  char *s=ssiReadString(d);
+  procinfov p=(procinfov)omAlloc0Bin(procinfo_bin);
+  p->language=LANG_SINGULAR;
+  p->libname=omStrDup("");
+  p->procname=omStrDup("");
+  p->data.s.body=s;
+  return p;
+}
+lists ssiReadList(si_link l)
+{
+  ssiInfo *d=(ssiInfo*)l->data;
+  int nr;
+  nr=s_readint(d->f_read);
+  lists L=(lists)omAlloc(sizeof(*L));
+  L->Init(nr);
+
+  int i;
+  leftv v;
+  for(i=0;i<nr;i++)
+  {
+    v=ssiRead1(l);
+    memcpy(&(L->m[i]),v,sizeof(*v));
+    omFreeBin(v,sleftv_bin);
+  }
+  return L;
+}
+intvec* ssiReadIntvec(const ssiInfo *d)
+{
+  int nr;
+  nr=s_readint(d->f_read);
+  intvec *v=new intvec(nr);
+  for(int i=0;i<nr;i++)
+  {
+    (*v)[i]=s_readint(d->f_read);
+  }
+  return v;
+}
+intvec* ssiReadIntmat(const ssiInfo *d)
+{
+  int r,c;
+  r=s_readint(d->f_read);
+  c=s_readint(d->f_read);
+  intvec *v=new intvec(r,c,0);
+  for(int i=0;i<r*c;i++)
+  {
+    (*v)[i]=s_readint(d->f_read);
+  }
+  return v;
+}
+bigintmat* ssiReadBigintmat(const ssiInfo *d)
+{
+  int r,c;
+  r=s_readint(d->f_read);
+  c=s_readint(d->f_read);
+  bigintmat *v=new bigintmat(r,c,coeffs_BIGINT);
+  for(int i=0;i<r*c;i++)
+  {
+    (*v)[i]=ssiReadBigInt(d);
+  }
+  return v;
+}
+
+void ssiReadBlackbox(leftv res, si_link l)
+{
+  ssiInfo *d=(ssiInfo*)l->data;
+  int throwaway;
+  throwaway=s_readint(d->f_read);
+  char *name=ssiReadString(d);
+  int tok;
+  blackboxIsCmd(name,tok);
+  if (tok>MAX_TOK)
+  {
+    blackbox *b=getBlackboxStuff(tok);
+    res->rtyp=tok;
+    b->blackbox_deserialize(&b,&(res->data),l);
+  }
+  else
+  {
+    Werror("blackbox %s not found",name);
+  }
+}
+
+void ssiReadAttrib(leftv res, si_link l)
+{
+  ssiInfo *d=(ssiInfo*)l->data;
+  BITSET fl=(BITSET)s_readint(d->f_read);
+  int nr_of_attr=s_readint(d->f_read);
+  if (nr_of_attr>0)
+  {
+    for(int i=1;i<nr_of_attr;i++)
+    {
+    }
+  }
+  leftv tmp=ssiRead1(l);
+  memcpy(res,tmp,sizeof(sleftv));
+  memset(tmp,0,sizeof(sleftv));
+  omFreeSize(tmp,sizeof(sleftv));
+  if (nr_of_attr>0)
+  {
+  }
+  res->flag=fl;
+}
+//**************************************************************************/
+
+BOOLEAN ssiOpen(si_link l, short flag, leftv u)
+{
+  if (l!=NULL)
+  {
+    const char *mode;
+    ssiInfo *d=(ssiInfo*)omAlloc0(sizeof(ssiInfo));
+    if (flag & SI_LINK_OPEN)
+    {
+      if (l->mode[0] != '\0' && (strcmp(l->mode, "r") == 0))
+        flag = SI_LINK_READ;
+      else flag = SI_LINK_WRITE;
+    }
+
+    if (flag == SI_LINK_READ) mode = "r";
+    else if (strcmp(l->mode, "w") == 0) mode = "w";
+    else if (strcmp(l->mode, "fork") == 0) mode = "fork";
+    else if (strcmp(l->mode, "tcp") == 0) mode = "tcp";
+    else if (strcmp(l->mode, "connect") == 0) mode = "connect";
+    else mode = "a";
+
+
+    SI_LINK_SET_OPEN_P(l, flag);
+    l->data=d;
+    omFree(l->mode);
+    l->mode = omStrDup(mode);
+
+    if (l->name[0] == '\0')
+    {
+      if (strcmp(mode,"fork")==0)
+      {
+        link_list n=(link_list)omAlloc(sizeof(link_struct));
+        n->u=u;
+        n->l=l;
+        n->next=(void *)ssiToBeClosed;
+        ssiToBeClosed=n;
+
+        int pc[2];
+        int cp[2];
+        pipe(pc);
+        pipe(cp);
+        pid_t pid = fork();
+        if (pid == -1 && errno == EAGAIN)   // RLIMIT_NPROC too low?
+        {
+          raise_rlimit_nproc();
+          pid = fork();
+        }
+        if (pid == -1)
+        {
+          WerrorS("could not fork");
+        }
+        if (pid==0) /*fork: child*/
+        {
+          /* block SIGINT */
+          sigset_t sigint;
+          sigemptyset(&sigint);
+          sigaddset(&sigint, SIGINT);
+          sigprocmask(SIG_BLOCK, &sigint, NULL);
+
+          link_list hh=(link_list)ssiToBeClosed->next;
+          /* we know: l is the first entry in ssiToBeClosed-list */
+          while(hh!=NULL)
+          {
+            SI_LINK_SET_CLOSE_P(hh->l);
+            ssiInfo *dd=(ssiInfo*)hh->l->data;
+            s_close(dd->f_read);
+            s_free(dd->f_read);
+            fclose(dd->f_write);
+            if (dd->r!=NULL) rKill(dd->r);
+            omFreeSize((ADDRESS)dd,(sizeof *dd));
+            hh->l->data=NULL;
+            link_list nn=(link_list)hh->next;
+            omFree(hh);
+            hh=nn;
+          }
+          ssiToBeClosed->next=NULL;
+#ifdef HAVE_SIMPLEIPC
+          memset(sem_acquired, 0, SIPC_MAX_SEMAPHORES*sizeof(sem_acquired[0]));
+#endif   // HAVE_SIMPLEIPC
+          si_close(pc[1]); si_close(cp[0]);
+          d->f_write=fdopen(cp[1],"w");
+          d->f_read=s_open(pc[0]);
+          d->fd_read=pc[0];
+          d->fd_write=cp[1];
+          //d->r=currRing;
+          //if (d->r!=NULL) d->r->ref++;
+          l->data=d;
+          omFree(l->mode);
+          l->mode = omStrDup(mode);
+          singular_in_batchmode=TRUE;
+          SI_LINK_SET_RW_OPEN_P(l);
+          //myynest=0;
+          fe_fgets_stdin=fe_fgets_dummy;
+          if ((u!=NULL)&&(u->rtyp==IDHDL))
+          {
+            idhdl h=(idhdl)u->data;
+            h->lev=0;
+          }
+          loop
+          {
+            leftv h=ssiRead1(l); /*contains an exit.... */
+            if (feErrors != NULL && *feErrors != '\0')
+            {
+              // handle errors:
+              PrintS(feErrors); /* currently quite simple */
+              *feErrors = '\0';
+            }
+            ssiWrite(l,h);
+            h->CleanUp();
+            omFreeBin(h, sleftv_bin);
+          }
+          /* never reached*/
+        }
+        else if (pid>0) /*fork: parent*/
+        {
+          d->pid=pid;
+          si_close(pc[0]); si_close(cp[1]);
+          d->f_write=fdopen(pc[1],"w");
+          d->f_read=s_open(cp[0]);
+          d->fd_read=cp[0];
+          d->fd_write=pc[1];
+          SI_LINK_SET_RW_OPEN_P(l);
+          d->send_quit_at_exit=1;
+          //d->r=currRing;
+          //if (d->r!=NULL) d->r->ref++;
+        }
+        else
+        {
+          Werror("fork failed (%d)",errno);
+          l->data=NULL;
+          omFree(d);
+          return TRUE;
+        }
+      }
+      // ---------------------------------------------------------------------
+      else if (strcmp(mode,"tcp")==0)
+      {
+        int sockfd, newsockfd, portno, clilen;
+        struct sockaddr_in serv_addr, cli_addr;
+        sockfd = socket(AF_INET, SOCK_STREAM, 0);
+        if(sockfd < 0)
+        {
+          WerrorS("ERROR opening socket");
+          l->data=NULL;
+          omFree(d);
+          return TRUE;
+        }
+        memset((char *) &serv_addr,0, sizeof(serv_addr));
+        portno = 1025;
+        serv_addr.sin_family = AF_INET;
+        serv_addr.sin_addr.s_addr = INADDR_ANY;
+        do
+        {
+          portno++;
+          serv_addr.sin_port = htons(portno);
+          if(portno > 50000)
+          {
+            WerrorS("ERROR on binding (no free port available?)");
+            l->data=NULL;
+            omFree(d);
+            return TRUE;
+          }
+        }
+        while(bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0);
+        Print("waiting on port %d\n", portno);mflush();
+        listen(sockfd,1);
+        newsockfd = si_accept(sockfd, (struct sockaddr *) &cli_addr, (socklen_t *)&clilen);
+        if(newsockfd < 0)
+        {
+          WerrorS("ERROR on accept");
+          l->data=NULL;
+          omFree(d);
+          return TRUE;
+        }
+        PrintS("client accepted\n");
+        d->fd_read = newsockfd;
+        d->fd_write = newsockfd;
+        d->f_read = s_open(newsockfd);
+        d->f_write = fdopen(newsockfd, "w");
+        SI_LINK_SET_RW_OPEN_P(l);
+        si_close(sockfd);
+      }
+      // no ssi-Link on stdin or stdout
+      else
+      {
+        Werror("invalid mode >>%s<< for ssi",mode);
+        l->data=NULL;
+        omFree(d);
+        return TRUE;
+      }
+    }
+    // =========================================================================
+    else /*l->name=NULL*/
+    {
+      // tcp mode
+      if(strcmp(mode,"tcp")==0)
+      {
+        int sockfd, newsockfd, portno, clilen;
+        struct sockaddr_in serv_addr, cli_addr;
+        sockfd = socket(AF_INET, SOCK_STREAM, 0);
+        if(sockfd < 0)
+        {
+          WerrorS("ERROR opening socket");
+          l->data=NULL;
+          omFree(d);
+          return TRUE;
+        }
+        memset((char *) &serv_addr,0, sizeof(serv_addr));
+        portno = 1025;
+        serv_addr.sin_family = AF_INET;
+        serv_addr.sin_addr.s_addr = INADDR_ANY;
+        do
+        {
+          portno++;
+          serv_addr.sin_port = htons(portno);
+          if(portno > 50000)
+          {
+            WerrorS("ERROR on binding (no free port available?)");
+            l->data=NULL;
+            return TRUE;
+          }
+        }
+        while(bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0);
+        //Print("waiting on port %d\n", portno);mflush();
+        listen(sockfd,1);
+        char* cli_host = (char*)omAlloc(256);
+        char* path = (char*)omAlloc(1024);
+        int r = si_sscanf(l->name,"%255[^:]:%s",cli_host,path);
+        if(r == 0)
+        {
+          WerrorS("ERROR: no host specified");
+          l->data=NULL;
+          omFree(d);
+          omFree(path);
+          omFree(cli_host);
+          return TRUE;
+        }
+        else if(r == 1)
+        {
+          WarnS("program not specified, using /usr/local/bin/Singular");
+          strcpy(path,"/usr/local/bin/Singular");
+        }
+        char* ssh_command = (char*)omAlloc(256);
+        char* ser_host = (char*)omAlloc(64);
+        gethostname(ser_host,64);
+        sprintf(ssh_command,"ssh %s %s -q --batch --link=ssi --MPhost=%s --MPport=%d &",cli_host,path,ser_host,portno);
+        //Print("client on %s started:%s\n",cli_host,path);
+        omFree(path);
+        omFree(cli_host);
+        if (TEST_OPT_PROT) { Print("running >>%s<<\n",ssh_command); }
+        system(ssh_command);
+        omFree(ssh_command);
+        omFree(ser_host);
+        clilen = sizeof(cli_addr);
+        newsockfd = si_accept(sockfd, (struct sockaddr *) &cli_addr, (socklen_t *)&clilen);
+        if(newsockfd < 0)
+        {
+          WerrorS("ERROR on accept");
+          l->data=NULL;
+          omFree(d);
+          return TRUE;
+        }
+        //PrintS("client accepted\n");
+        d->fd_read = newsockfd;
+        d->fd_write = newsockfd;
+        d->f_read = s_open(newsockfd);
+        d->f_write = fdopen(newsockfd, "w");
+        si_close(sockfd);
+        SI_LINK_SET_RW_OPEN_P(l);
+        d->send_quit_at_exit=1;
+        link_list newlink=(link_list)omAlloc(sizeof(link_struct));
+        newlink->u=u;
+        newlink->l=l;
+        newlink->next=(void *)ssiToBeClosed;
+        ssiToBeClosed=newlink;
+        fprintf(d->f_write,"98 %d %d %u %u\n",SSI_VERSION,MAX_TOK,si_opt_1,si_opt_2);
+      }
+      // ----------------------------------------------------------------------
+      else if(strcmp(mode,"connect")==0)
+      {
+        char* host = (char*)omAlloc(256);
+        int sockfd, portno;
+        struct sockaddr_in serv_addr;
+        struct hostent *server;
+
+        si_sscanf(l->name,"%255[^:]:%d",host,&portno);
+        //Print("connect to host %s, port %d\n",host,portno);mflush();
+        if (portno!=0)
+        {
+          sockfd = socket(AF_INET, SOCK_STREAM, 0);
+          if (sockfd < 0) { WerrorS("ERROR opening socket"); return TRUE; }
+          server = gethostbyname(host);
+          if (server == NULL) {  WerrorS("ERROR, no such host");  return TRUE; }
+          memset((char *) &serv_addr, 0, sizeof(serv_addr));
+          serv_addr.sin_family = AF_INET;
+          memcpy((char *)&serv_addr.sin_addr.s_addr,
+                (char *)server->h_addr,
+                server->h_length);
+          serv_addr.sin_port = htons(portno);
+          if (si_connect(sockfd,(sockaddr*)&serv_addr,sizeof(serv_addr)) < 0)
+          { Werror("ERROR connecting(errno=%d)",errno); return TRUE; }
+          //PrintS("connected\n");mflush();
+          d->f_read=s_open(sockfd);
+          d->fd_read=sockfd;
+          d->f_write=fdopen(sockfd,"w");
+          d->fd_write=sockfd;
+          SI_LINK_SET_RW_OPEN_P(l);
+          omFree(host);
+        }
+        else
+        {
+          l->data=NULL;
+          omFree(d);
+          return TRUE;
+        }
+      }
+      // ======================================================================
+      else
+      {
+        // normal link to a file
+        FILE *outfile;
+        char *filename=l->name;
+
+        if(filename[0]=='>')
+        {
+          if (filename[1]=='>')
+          {
+            filename+=2;
+            mode = "a";
+          }
+          else
+          {
+            filename++;
+            mode="w";
+          }
+        }
+        outfile=myfopen(filename,mode);
+        if (outfile!=NULL)
+        {
+          if (strcmp(l->mode,"r")==0)
+          {
+            fclose(outfile);
+            d->f_read=s_open_by_name(filename);
+          }
+          else
+          {
+            d->f_write = outfile;
+            fprintf(d->f_write,"98 %d %d %u %u\n",SSI_VERSION,MAX_TOK,si_opt_1,si_opt_2);
+          }
+        }
+        else
+        {
+          omFree(d);
+          l->data=NULL;
+          return TRUE;
+        }
+      }
+    }
+  }
+
+  return FALSE;
+}
+
+//**************************************************************************/
+BOOLEAN ssiPrepClose(si_link l)
+{
+  if (l!=NULL)
+  {
+    ssiInfo *d = (ssiInfo *)l->data;
+    if (d!=NULL)
+    {
+      if (d->send_quit_at_exit)
+      {
+        fputs("99\n",d->f_write);
+        fflush(d->f_write);
+      }
+      d->quit_sent=1;
+    }
+  }
+  return FALSE;
+}
+
+BOOLEAN ssiClose(si_link l)
+{
+  if (l!=NULL)
+  {
+    SI_LINK_SET_CLOSE_P(l);
+    ssiInfo *d = (ssiInfo *)l->data;
+    if (d!=NULL)
+    {
+      if ((d->send_quit_at_exit)
+      && (d->quit_sent==0))
+      {
+        fputs("99\n",d->f_write);
+        fflush(d->f_write);
+      }
+      if (d->r!=NULL) rKill(d->r);
+      if ((d->pid!=0)
+      && (si_waitpid(d->pid,NULL,WNOHANG)==0))
+      {
+        struct timespec t;
+        t.tv_sec=0;
+        t.tv_nsec=100000000; // <=100 ms
+        struct timespec rem;
+        int r;
+        do
+        {
+          r = nanosleep(&t, &rem);
+          t = rem;
+        } while ((r < 0) && (errno == EINTR)
+            && (si_waitpid(d->pid,NULL,WNOHANG) == 0));
+        if ((r == 0) && (si_waitpid(d->pid,NULL,WNOHANG) == 0))
+        {
+          kill(d->pid,15);
+          t.tv_sec=5; // <=5s
+          t.tv_nsec=0;
+          do
+          {
+            r = nanosleep(&t, &rem);
+            t = rem;
+          } while ((r < 0) && (errno == EINTR)
+              && (si_waitpid(d->pid,NULL,WNOHANG) == 0));
+          if ((r == 0) && (si_waitpid(d->pid,NULL,WNOHANG) == 0))
+          {
+            kill(d->pid,9); // just to be sure
+            si_waitpid(d->pid,NULL,0);
+          }
+        }
+      }
+      if (d->f_read!=NULL) s_close(d->f_read);
+      if (d->f_read!=NULL) s_free(d->f_read);
+      if (d->f_write!=NULL) fclose(d->f_write);
+      if ((strcmp(l->mode,"tcp")==0)
+      || (strcmp(l->mode,"fork")==0))
+      {
+        link_list hh=ssiToBeClosed;
+        if (hh!=NULL)
+        {
+          if (hh->l==l)
+          {
+             ssiToBeClosed=(link_list)hh->next;
+             omFreeSize(hh,sizeof(link_struct));
+          }
+          else while(hh->next!=NULL)
+          {
+            link_list hhh=(link_list)hh->next;
+            if (hhh->l==l)
+            {
+              hh->next=hhh->next;
+              omFreeSize(hhh,sizeof(link_struct));
+              break;
+            }
+            else
+              hh=(link_list)hh->next;
+          }
+        }
+      }
+      omFreeSize((ADDRESS)d,(sizeof *d));
+    }
+    l->data=NULL;
+  }
+  return FALSE;
+}
+
+//**************************************************************************/
+leftv ssiRead1(si_link l)
+{
+  ssiInfo *d = (ssiInfo *)l->data;
+  leftv res=(leftv)omAlloc0(sizeof(sleftv));
+  int t=0;
+  t=s_readint(d->f_read);
+  //Print("got type %d\n",t);
+  switch(t)
+  {
+    case 1:res->rtyp=INT_CMD;
+           res->data=(char *)(long)ssiReadInt(d->f_read);
+           break;
+    case 2:res->rtyp=STRING_CMD;
+           res->data=(char *)ssiReadString(d);
+           break;
+    case 3:res->rtyp=NUMBER_CMD;
+           res->data=(char *)ssiReadNumber(d);
+           break;
+    case 4:res->rtyp=BIGINT_CMD;
+           res->data=(char *)ssiReadBigInt(d);
+           break;
+    case 15:
+    case 5:{
+             d->r=ssiReadRing(d);
+             res->data=(char*)d->r;
+             if (d->r->qideal==NULL)
+               res->rtyp=RING_CMD;
+             else
+               res->rtyp=QRING_CMD;
+             // we are in the top-level, so set the basering to d->r:
+             if (d->r!=NULL)
+             {
+               d->r->ref++;
+               ssiSetCurrRing(d->r);
+             }
+             if (t==15) return ssiRead1(l);
+           }
+           break;
+    case 6:res->rtyp=POLY_CMD;
+           if (d->r==NULL) goto no_ring;
+           res->data=(char*)ssiReadPoly(d);
+           break;
+    case 7:res->rtyp=IDEAL_CMD;
+           if (d->r==NULL) goto no_ring;
+           res->data=(char*)ssiReadIdeal(d);
+           break;
+    case 8:res->rtyp=MATRIX_CMD;
+           if (d->r==NULL) goto no_ring;
+           res->data=(char*)ssiReadMatrix(d);
+           break;
+    case 9:res->rtyp=VECTOR_CMD;
+           if (d->r==NULL) goto no_ring;
+           res->data=(char*)ssiReadPoly(d);
+           break;
+    case 10:res->rtyp=MODUL_CMD;
+           if (d->r==NULL) goto no_ring;
+           res->data=(char*)ssiReadIdeal(d);
+           break;
+    case 11:
+           {
+             res->rtyp=COMMAND;
+             res->data=ssiReadCommand(l);
+             int nok=res->Eval();
+             if (nok) WerrorS("error in eval");
+             break;
+           }
+    case 12: /*DEF_CMD*/
+           {
+             res->rtyp=0;
+             res->name=(char *)ssiReadString(d);
+             int nok=res->Eval();
+             if (nok) WerrorS("error in name lookup");
+             break;
+           }
+    case 13: res->rtyp=PROC_CMD;
+             res->data=ssiReadProc(d);
+             break;
+    case 14: res->rtyp=LIST_CMD;
+             res->data=ssiReadList(l);
+             break;
+    case 16: res->rtyp=NONE; res->data=NULL;
+             break;
+    case 17: res->rtyp=INTVEC_CMD;
+             res->data=ssiReadIntvec(d);
+             break;
+    case 18: res->rtyp=INTMAT_CMD;
+             res->data=ssiReadIntmat(d);
+             break;
+    case 19: res->rtyp=BIGINTMAT_CMD;
+             res->data=ssiReadBigintmat(d);
+             break;
+    case 20: ssiReadBlackbox(res,l);
+             break;
+    case 21: ssiReadAttrib(res,l);
+             break;
+    // ------------
+    case 98: // version
+             {
+                int n98_v,n98_m;
+                BITSET n98_o1,n98_o2;
+                n98_v=s_readint(d->f_read);
+                n98_m=s_readint(d->f_read);
+                n98_o1=s_readint(d->f_read);
+                n98_o2=s_readint(d->f_read);
+                if ((n98_v!=SSI_VERSION) ||(n98_m!=MAX_TOK))
+                {
+                  Print("incompatible versions of ssi: %d/%d vs %d/%d",
+                                  SSI_VERSION,MAX_TOK,n98_v,n98_m);
+                }
+                #ifndef SING_NDEBUG
+                if (TEST_OPT_DEBUG)
+                  Print("// opening ssi-%d, MAX_TOK=%d\n",n98_v,n98_m);
+                #endif
+                si_opt_1=n98_o1;
+                si_opt_2=n98_o2;
+                return ssiRead1(l);
+             }
+    case 99: ssiClose(l); m2_end(0);
+    case 0: if (s_iseof(d->f_read))
+            {
+              ssiClose(l);
+            }
+            res->rtyp=DEF_CMD;
+            break;
+    default: Werror("not implemented (t:%d)",t);
+             omFreeSize(res,sizeof(sleftv));
+             res=NULL;
+             break;
+  }
+  // if currRing is required for the result, but lost
+  // define "ssiRing%d" as currRing:
+  if ((d->r!=NULL)
+  && (currRing!=d->r)
+  && (res->RingDependend()))
+  {
+    ssiSetCurrRing(d->r);
+  }
+  return res;
+no_ring: WerrorS("no ring");
+  omFreeSize(res,sizeof(sleftv));
+  return NULL;
+}
+//**************************************************************************/
+BOOLEAN ssiSetRing(si_link l, ring r, BOOLEAN send)
+{
+  if(SI_LINK_W_OPEN_P(l)==0)
+     if (slOpen(l,SI_LINK_OPEN|SI_LINK_WRITE,NULL)) return TRUE;
+  ssiInfo *d = (ssiInfo *)l->data;
+  if (d->r!=r)
+  {
+    if (send)
+    {
+      fputs("15 ",d->f_write);
+      ssiWriteRing(d,r);
+    }
+    d->r=r;
+  }
+  if (currRing!=r) rChangeCurrRing(r);
+  return FALSE;
+}
+//**************************************************************************/
+
+BOOLEAN ssiWrite(si_link l, leftv data)
+{
+  if(SI_LINK_W_OPEN_P(l)==0)
+     if (slOpen(l,SI_LINK_OPEN|SI_LINK_WRITE,NULL)) return TRUE;
+  ssiInfo *d = (ssiInfo *)l->data;
+  d->level++;
+  //FILE *fich=d->f;
+  while (data!=NULL)
+  {
+    int tt=data->Typ();
+    void *dd=data->Data();
+    attr *aa=data->Attribute();
+    BOOLEAN with_attr=FALSE;
+    if (((*aa)!=NULL)||(data->flag!=0))
+    {
+      attr a=*aa;
+      int n=0;
+      while(a!=NULL) { n++; a=a->next;}
+      fprintf(d->f_write,"21 %d %d ",data->flag,n);
+      a=*aa;
+    }
+    if ((dd==NULL) && (data->name!=NULL) && (tt==0)) tt=DEF_CMD;
+      // return pure undefined names as def
+
+    switch(tt /*data->Typ()*/)
+    {
+          case 0: /*error*/
+          case NONE/* nothing*/:fputs("16 ",d->f_write);
+                          break;
+          case STRING_CMD: fputs("2 ",d->f_write);
+                           ssiWriteString(d,(char *)dd);
+                           break;
+          case INT_CMD: fputs("1 ",d->f_write);
+                        ssiWriteInt(d,(int)(long)dd);
+                        break;
+          case BIGINT_CMD:fputs("4 ",d->f_write);
+                        ssiWriteBigInt(d,(number)dd);
+                        break;
+          case NUMBER_CMD:
+                          if (d->r!=currRing)
+                          {
+                            fputs("15 ",d->f_write);
+                            ssiWriteRing(d,currRing);
+                            if (d->level<=1) fputc('\n',d->f_write);
+                          }
+                          fputs("3 ",d->f_write);
+                          ssiWriteNumber(d,(number)dd);
+                        break;
+          case QRING_CMD:
+          case RING_CMD:fputs("5 ",d->f_write);
+                        ssiWriteRing(d,(ring)dd);
+                        break;
+          case POLY_CMD:
+          case VECTOR_CMD:
+                        if (d->r!=currRing)
+                        {
+                          fputs("15 ",d->f_write);
+                          ssiWriteRing(d,currRing);
+                          if (d->level<=1) fputc('\n',d->f_write);
+                        }
+                        if(tt==POLY_CMD) fputs("6 ",d->f_write);
+                        else             fputs("9 ",d->f_write);
+                        ssiWritePoly(d,tt,(poly)dd);
+                        break;
+          case IDEAL_CMD:
+          case MODUL_CMD:
+          case MATRIX_CMD:
+                        if (d->r!=currRing)
+                        {
+                          fputs("15 ",d->f_write);
+                          ssiWriteRing(d,currRing);
+                          if (d->level<=1) fputc('\n',d->f_write);
+                        }
+                        if(tt==IDEAL_CMD)       fputs("7 ",d->f_write);
+                        else if(tt==MATRIX_CMD) fputs("8 ",d->f_write);
+                        else                    fputs("10 ",d->f_write);
+                        ssiWriteIdeal(d,tt,(ideal)dd);
+                        break;
+          case COMMAND:
+                   fputs("11 ",d->f_write);
+                   ssiWriteCommand(l,(command)dd);
+                   break;
+          case DEF_CMD: /* not evaluated stuff in quotes */
+                   fputs("12 ",d->f_write);
+                   ssiWriteString(d,data->Name());
+                   break;
+          case PROC_CMD:
+                   fputs("13 ",d->f_write);
+                   ssiWriteProc(d,(procinfov)dd);
+                   break;
+          case LIST_CMD:
+                   fputs("14 ",d->f_write);
+                   ssiWriteList(l,(lists)dd);
+                   break;
+          case INTVEC_CMD:
+                   fputs("17 ",d->f_write);
+                   ssiWriteIntvec(d,(intvec *)dd);
+                   break;
+          case INTMAT_CMD:
+                   fputs("18 ",d->f_write);
+                   ssiWriteIntmat(d,(intvec *)dd);
+                   break;
+          case BIGINTMAT_CMD:
+                   fputs("19 ",d->f_write);
+                   ssiWriteBigintmat(d,(bigintmat *)dd);
+                   break;
+          default:
+            if (tt>MAX_TOK)
+            {
+              blackbox *b=getBlackboxStuff(tt);
+              fputs("20 ",d->f_write);
+              b->blackbox_serialize(b,dd,l);
+            }
+            else
+            {
+              Werror("not implemented (t:%d, rtyp:%d)",tt, data->rtyp);
+              d->level=0;
+              return TRUE;
+            }
+            break;
+    }
+    if (d->level<=1) { fputc('\n',d->f_write); fflush(d->f_write); }
+    data=data->next;
+  }
+  d->level--;
+  return FALSE;
+}
+
+BOOLEAN ssiGetDump(si_link l);
+BOOLEAN ssiDump(si_link l);
+
+si_link_extension slInitSsiExtension(si_link_extension s)
+{
+  s->Open=ssiOpen;
+  s->Close=ssiClose;
+  s->Kill=ssiClose;
+  s->Read=ssiRead1;
+  s->Read2=(slRead2Proc)NULL;
+  s->Write=ssiWrite;
+  s->Dump=ssiDump;
+  s->GetDump=ssiGetDump;
+
+  s->Status=slStatusSsi;
+  s->SetRing=ssiSetRing;
+  s->type="ssi";
+  return s;
+}
+
+const char* slStatusSsi(si_link l, const char* request)
+{
+  ssiInfo *d=(ssiInfo*)l->data;
+  if (d==NULL) return "not open";
+  if (((strcmp(l->mode,"fork")==0)
+  ||(strcmp(l->mode,"tcp")==0)
+  ||(strcmp(l->mode,"connect")==0))
+  && (strcmp(request, "read") == 0))
+  {
+    fd_set  mask;
+    struct timeval wt;
+    if (s_isready(d->f_read)) return "ready";
+    loop
+    {
+      /* Don't block. Return socket status immediately. */
+      wt.tv_sec  = 0;
+      wt.tv_usec = 0;
+
+      FD_ZERO(&mask);
+      FD_SET(d->fd_read, &mask);
+      //Print("test fd %d\n",d->fd_read);
+    /* check with select: chars waiting: no -> not ready */
+      switch (si_select(d->fd_read+1, &mask, NULL, NULL, &wt))
+      {
+        case 0: /* not ready */ return "not ready";
+        case -1: /*error*/      return "error";
+        case 1: /*ready ? */    break;
+      }
+    /* yes: read 1 char*/
+    /* if \n, check again with select else ungetc(c), ready*/
+      int c=s_getc(d->f_read);
+      //Print("try c=%d\n",c);
+      if (c== -1) return "eof"; /* eof or error */
+      else if (isdigit(c))
+      { s_ungetc(c,d->f_read); return "ready"; }
+      else if (c>' ')
+      {
+        Werror("unknown char in ssiLink(%d)",c);
+        return "error";
+      }
+      /* else: next char */
+    }
+  }
+  else if (strcmp(request, "read") == 0)
+  {
+    if (SI_LINK_R_OPEN_P(l) && (!s_iseof(d->f_read)) && (s_isready(d->f_read))) return "ready";
+    else return "not ready";
+  }
+  else if (strcmp(request, "write") == 0)
+  {
+    if (SI_LINK_W_OPEN_P(l)) return "ready";
+    else return "not ready";
+  }
+  else return "unknown status request";
+}
+
+int slStatusSsiL(lists L, int timeout)
+{
+// input: L: a list with links of type
+//           ssi-connect, ssi-fork, ssi-tcp, MPtcp-fork or MPtcp-launch.
+//           Note: Not every entry in L must be set.
+//        timeout: timeout for select in micro-seconds
+//           or -1 for infinity
+//           or 0 for polling
+// returns: ERROR (via Werror): L has wrong elements or link not open
+//           -2: select returns an error
+//           -1: the read state of all links is eof
+//           0:  timeout (or polling): none ready,
+//           i>0: (at least) L[i] is ready
+  si_link l;
+  ssiInfo *d;
+  int d_fd;
+  fd_set  mask, fdmask;
+  FD_ZERO(&fdmask);
+  FD_ZERO(&mask);
+  int max_fd=0; /* 1 + max fd in fd_set */
+
+  /* timeout */
+  struct timeval wt;
+  struct timeval *wt_ptr=&wt;
+  int startingtime = getRTimer()/TIMER_RESOLUTION;  // in seconds
+  if (timeout== -1)
+  {
+    wt_ptr=NULL;
+  }
+  else
+  {
+    wt.tv_sec  = timeout / 1000000;
+    wt.tv_usec = timeout % 1000000;
+  }
+
+  /* auxiliary variables */
+  int i;
+  int j;
+  int k;
+  int s;
+  char fdmaskempty;
+
+  /* check the links and fill in fdmask */
+  /* check ssi links for ungetc_buf */
+  for(i=L->nr; i>=0; i--)
+  {
+    if (L->m[i].Typ()!=DEF_CMD)
+    {
+      if (L->m[i].Typ()!=LINK_CMD)
+      { WerrorS("all elements must be of type link"); return -2;}
+      l=(si_link)L->m[i].Data();
+      if(SI_LINK_OPEN_P(l)==0)
+      { WerrorS("all links must be open"); return -2;}
+      if (((strcmp(l->m->type,"ssi")!=0) && (strcmp(l->m->type,"MPtcp")!=0))
+      || ((strcmp(l->mode,"fork")!=0) && (strcmp(l->mode,"tcp")!=0)
+        && (strcmp(l->mode,"launch")!=0) && (strcmp(l->mode,"connect")!=0)))
+      {
+        WerrorS("all links must be of type ssi:fork, ssi:tcp, ssi:connect");
+        return -2;
+      }
+      if (strcmp(l->m->type,"ssi")==0)
+      {
+        d=(ssiInfo*)l->data;
+        d_fd=d->fd_read;
+        if (!s_isready(d->f_read))
+        {
+          FD_SET(d_fd, &fdmask);
+          if (d_fd > max_fd) max_fd=d_fd;
+        }
+        else
+          return i+1;
+      }
+      else
+      {
+        Werror("wrong link type >>%s<<",l->m->type);
+        return -2;
+      }
+    }
+  }
+  max_fd++;
+
+do_select:
+  /* copy fdmask to mask */
+  FD_ZERO(&mask);
+  for(k = 0; k < max_fd; k++)
+  {
+    if(FD_ISSET(k, &fdmask))
+    {
+      FD_SET(k, &mask);
+    }
+  }
+
+  /* check with select: chars waiting: no -> not ready */
+  s = si_select(max_fd, &mask, NULL, NULL, wt_ptr);
+  if (s==-1)
+  {
+    WerrorS("error in select call");
+    return -2; /*error*/
+  }
+  if (s==0)
+  {
+    return 0; /*poll: not ready */
+  }
+  else /* s>0, at least one ready  (the number of fd which are ready is s)*/
+  {
+    j=0;
+    while (j<=max_fd) { if (FD_ISSET(j,&mask)) break; j++; }
+    for(i=L->nr; i>=0; i--)
+    {
+      if (L->m[i].rtyp==LINK_CMD)
+      {
+        l=(si_link)L->m[i].Data();
+        if (strcmp(l->m->type,"ssi")==0)
+        {
+          d=(ssiInfo*)l->data;
+          d_fd=d->fd_read;
+          if(j==d_fd) break;
+        }
+        else
+        {
+          Werror("wrong link type >>%s<<",l->m->type);
+          return -2;
+        }
+      }
+    }
+    // only ssi links:
+    loop
+    {
+      /* yes: read 1 char*/
+      /* if \n, check again with select else ungetc(c), ready*/
+      /* setting: d: current ssiInfo, j current fd, i current entry in L*/
+      int c=s_getc(d->f_read);
+      //Print("try c=%d\n",c);
+      if (c== -1) /* eof */
+      {
+        FD_CLR(j,&fdmask);
+        fdmaskempty = 1;
+        for(k = 0; k < max_fd; k++)
+        {
+          if(FD_ISSET(k, &fdmask))
+          {
+            fdmaskempty = 0;
+            break;
+          }
+        }
+        if(fdmaskempty)
+        {
+          return -1;
+        }
+        if(timeout != -1)
+        {
+          timeout = si_max(0,
+             timeout - 1000000*(getRTimer()/TIMER_RESOLUTION - startingtime));
+          wt.tv_sec  = timeout / 1000000;
+          wt.tv_usec = (timeout % 1000000);
+        }
+        goto do_select;
+      }
+
+      else if (isdigit(c))
+      { s_ungetc(c,d->f_read); return i+1; }
+      else if (c>' ')
+      {
+        Werror("unknown char in ssiLink(%d)",c);
+        return -2;
+      }
+      /* else: next char */
+      goto do_select;
+    }
+  }
+}
+
+int ssiBatch(const char *host, const char * port)
+/* return 0 on success, >0 else*/
+{
+  si_link l=(si_link) omAlloc0Bin(sip_link_bin);
+  char *buf=(char*)omAlloc(256);
+  sprintf(buf,"ssi:connect %s:%s",host,port);
+  slInit(l, buf);
+  if (slOpen(l,SI_LINK_OPEN,NULL)) return 1;
+  SI_LINK_SET_RW_OPEN_P(l);
+
+  idhdl id = enterid(omStrDup("link_ll"), 0, LINK_CMD, &IDROOT, FALSE);
+  IDLINK(id) = l;
+
+  loop
+  {
+    leftv h=ssiRead1(l); /*contains an exit.... */
+    if (feErrors != NULL && *feErrors != '\0')
+    {
+      // handle errors:
+      PrintS(feErrors); /* currently quite simple */
+      *feErrors = '\0';
+    }
+    ssiWrite(l,h);
+    h->CleanUp();
+    omFreeBin(h, sleftv_bin);
+  }
+  /* never reached*/
+  exit(0);
+}
+
+static int ssiReserved_P=0;
+static int ssiReserved_sockfd;
+static  struct sockaddr_in ssiResverd_serv_addr;
+static int  ssiReserved_Clients;
+int ssiReservePort(int clients)
+{
+  if (ssiReserved_P!=0)
+  {
+    WerrorS("ERROR already a reverved port requested");
+    return 0;
+  }
+  int portno;
+  ssiReserved_sockfd = socket(AF_INET, SOCK_STREAM, 0);
+  if(ssiReserved_sockfd < 0)
+  {
+    WerrorS("ERROR opening socket");
+    return 0;
+  }
+  memset((char *) &ssiResverd_serv_addr,0, sizeof(ssiResverd_serv_addr));
+  portno = 1025;
+  ssiResverd_serv_addr.sin_family = AF_INET;
+  ssiResverd_serv_addr.sin_addr.s_addr = INADDR_ANY;
+  do
+  {
+    portno++;
+    ssiResverd_serv_addr.sin_port = htons(portno);
+    if(portno > 50000)
+    {
+      WerrorS("ERROR on binding (no free port available?)");
+      return 0;
+    }
+  }
+  while(bind(ssiReserved_sockfd, (struct sockaddr *) &ssiResverd_serv_addr, sizeof(ssiResverd_serv_addr)) < 0);
+  ssiReserved_P=portno;
+  listen(ssiReserved_sockfd,clients);
+  ssiReserved_Clients=clients;
+  return portno;
+}
+
+extern si_link_extension si_link_root;
+si_link ssiCommandLink()
+{
+  if (ssiReserved_P==0)
+  {
+    WerrorS("ERROR no reverved port requested");
+    return NULL;
+  }
+  struct sockaddr_in cli_addr;
+  int clilen = sizeof(cli_addr);
+  int newsockfd = si_accept(ssiReserved_sockfd, (struct sockaddr *) &cli_addr, (socklen_t *)&clilen);
+  if(newsockfd < 0)
+  {
+    Werror("ERROR on accept (errno=%d)",errno);
+    return NULL;
+  }
+  si_link l=(si_link) omAlloc0Bin(sip_link_bin);
+  si_link_extension s = si_link_root;
+  si_link_extension prev = s;
+  while (strcmp(s->type, "ssi") != 0)
+  {
+    if (s->next == NULL)
+    {
+      prev = s;
+      s = NULL;
+      break;
+    }
+    else
+    {
+      s = s->next;
+    }
+  }
+  if (s != NULL)
+    l->m = s;
+  else
+  {
+    si_link_extension ns = (si_link_extension)omAlloc0Bin(s_si_link_extension_bin);
+    prev->next=slInitSsiExtension(ns);
+    l->m = prev->next;
+  }
+  l->name=omStrDup("");
+  l->mode=omStrDup("tcp");
+  l->ref=1;
+  ssiInfo *d=(ssiInfo*)omAlloc0(sizeof(ssiInfo));
+  l->data=d;
+  d->fd_read = newsockfd;
+  d->fd_write = newsockfd;
+  d->f_read = s_open(newsockfd);
+  d->f_write = fdopen(newsockfd, "w");
+  SI_LINK_SET_RW_OPEN_P(l);
+  ssiReserved_Clients--;
+  if (ssiReserved_Clients<=0)
+  {
+    ssiReserved_P=0;
+    si_close(ssiReserved_sockfd);
+  }
+  return l;
+}
+/*---------------------------------------------------------------------*/
+/**
+ * @brief additional default signal handler
+
+  // some newer Linux version cannot have SIG_IGN for SIGCHLD,
+  // so use this nice routine here:
+  //  SuSe 9.x reports -1 always
+  //  Redhat 9.x/FC x reports sometimes -1
+  // see also: hpux_system
+  // also needed by getrusage (timer etc.)
+
+ @param[in] sig
+**/
+/*---------------------------------------------------------------------*/
+void sig_chld_hdl(int sig)
+{
+  pid_t kidpid;
+  int status;
+
+  loop
+  {
+    kidpid = si_waitpid(-1, &status, WNOHANG);
+    if (kidpid==-1)
+    {
+      /* continue on interruption (EINTR): */
+      if (errno == EINTR) continue;
+      /* break on anything else (EINVAL or ECHILD according to manpage): */
+      break;
+    }
+    else if (kidpid==0) break; /* no more children to process, so break */
+
+    //printf("Child %ld terminated\n", kidpid);
+    link_list hh=ssiToBeClosed;
+    while((hh!=NULL)&&(ssiToBeClosed_inactive))
+    {
+      if((hh->l!=NULL) && (hh->l->m->Open==ssiOpen))
+      {
+        ssiInfo *d = (ssiInfo *)hh->l->data;
+        if(d->pid==kidpid)
+        {
+          if(ssiToBeClosed_inactive)
+          {
+            ssiToBeClosed_inactive=FALSE;
+            slClose(hh->l);
+            ssiToBeClosed_inactive=TRUE;
+            break;
+          }
+          else break;
+        }
+        else hh=(link_list)hh->next;
+      }
+      else hh=(link_list)hh->next;
+    }
+  }
+}
+
+static BOOLEAN DumpSsiIdhdl(si_link l, idhdl h)
+{
+  int type_id = IDTYP(h);
+
+  // C-proc not to be dumped, also LIB-proc not
+  if (type_id == PROC_CMD)
+  {
+    if (IDPROC(h)->language == LANG_C) return FALSE;
+    if (IDPROC(h)->libname != NULL) return FALSE;
+  }
+  // do not dump links
+  if (type_id == LINK_CMD) return FALSE;
+
+  // do not dump ssi internal rings: ssiRing*
+  if ((type_id == RING_CMD) && (strncmp(IDID(h),"ssiRing",7)==0))
+    return FALSE;
+
+  command D=(command)omAlloc0(sizeof(*D));
+  sleftv tmp;
+  memset(&tmp,0,sizeof(tmp));
+  tmp.rtyp=COMMAND;
+  tmp.data=D;
+
+  if (type_id == PACKAGE_CMD)
+  {
+    // do not dump Top
+    if (strcmp(IDID(h), "Top") == 0) return FALSE;
+    package p=(package)IDDATA(h);
+    // dump Singular-packages as load("...");
+    if (p->language==LANG_SINGULAR)
+    {
+      D->op=LOAD_CMD;
+      D->argc=1;
+      D->arg1.rtyp=STRING_CMD;
+      D->arg1.data=p->libname;
+      ssiWrite(l,&tmp);
+      omFree(D);
+      return FALSE;
+    }
+  }
+
+  // handle qrings separately
+  //if (type_id == QRING_CMD)
+  //  return DumpSsiQringQring(l, h);
+
+  // put type and name
+  //Print("generic dump:%s,%s\n",IDID(h),Tok2Cmdname(IDTYP(h)));
+  D->op='=';
+  D->argc=2;
+  D->arg1.rtyp=DEF_CMD;
+  D->arg1.name=IDID(h);
+  D->arg2.rtyp=IDTYP(h);
+  D->arg2.data=IDDATA(h);
+  ssiWrite(l,&tmp);
+  omFree(D);
+  return FALSE;
+}
+static BOOLEAN ssiDumpIter(si_link l, idhdl h)
+{
+  if (h == NULL) return FALSE;
+
+  if (ssiDumpIter(l, IDNEXT(h))) return TRUE;
+
+  // need to set the ring before writing it, otherwise we get in
+  // trouble with minpoly
+  if (IDTYP(h) == RING_CMD || IDTYP(h) == QRING_CMD)
+    rSetHdl(h);
+
+  if (DumpSsiIdhdl(l, h)) return TRUE;
+
+  // do not dump ssi internal rings: ssiRing*
+  // but dump objects of all other rings
+  if ((IDTYP(h) == RING_CMD || IDTYP(h) == QRING_CMD)
+  && (strncmp(IDID(h),"ssiRing",7)!=0))
+    return ssiDumpIter(l, IDRING(h)->idroot);
+  else
+    return FALSE;
+}
+BOOLEAN ssiDump(si_link l)
+{
+  idhdl h = IDROOT, rh = currRingHdl;
+  BOOLEAN status = ssiDumpIter(l, h);
+
+  //if (! status ) status = DumpAsciiMaps(fd, h, NULL);
+
+  if (currRingHdl != rh) rSetHdl(rh);
+  //fprintf(fd, "option(set, intvec(%d, %d));\n", si_opt_1, si_opt_2);
+
+  return status;
+}
+BOOLEAN ssiGetDump(si_link l)
+{
+  ssiInfo *d=(ssiInfo*)l->data;
+  loop
+  {
+    if (!SI_LINK_OPEN_P(l)) break;
+    if (s_iseof(d->f_read)) break;
+    leftv h=ssiRead1(l); /*contains an exit.... */
+    if (feErrors != NULL && *feErrors != '\0')
+    {
+      // handle errors:
+      PrintS(feErrors); /* currently quite simple */
+      return TRUE;
+      *feErrors = '\0';
+    }
+    h->CleanUp();
+    omFreeBin(h, sleftv_bin);
+  }
+  return FALSE;
+}
+// ----------------------------------------------------------------
+// format
+// 1 int %d
+// 2 string <len> %s
+// 3 number
+// 4 bigint 4 %d or 3 <mpz_t>
+// 5 ring
+// 6 poly
+// 7 ideal
+// 8 matrix
+// 9 vector
+// 10 module
+// 11 command
+// 12 def <len> %s
+// 13 proc <len> %s
+// 14 list %d <elem1> ....
+// 15 setring .......
+// 16 nothing
+// 17 intvec <len> ...
+// 18 intmat
+// 19 bigintmat <r> <c> ...
+// 20 blackbox <name> 1 <len> ...
+// 21 attrib <bit-attrib> <len> <a-name1> <val1>... <data>
+//
+// 98: verify version: <ssi-version> <MAX_TOK> <OPT1> <OPT2>
+// 99: quit Singular
diff --git a/Singular/links/ssiLink.h b/Singular/links/ssiLink.h
new file mode 100644
index 0000000..dd52355
--- /dev/null
+++ b/Singular/links/ssiLink.h
@@ -0,0 +1,23 @@
+/****************************************
+ * Computer Algebra System SINGULAR     *
+ ****************************************/
+/***************************************************************
+ * File:    ssiLink.h
+ *  Purpose: declaration of sl_link routines for ssi
+ ***************************************************************/
+#ifndef SSILINK_H
+#define SSILINK_H
+
+#include <Singular/links/silink.h>
+
+BOOLEAN ssiOpen(si_link l, short flag, leftv u);
+BOOLEAN ssiWrite(si_link l, leftv v);
+leftv ssiRead1(si_link l);
+leftv ssiRead2(si_link l, leftv key);
+BOOLEAN ssiClose(si_link l);
+const char* slStatusSsi(si_link l, const char* request);
+si_link_extension slInitSsiExtension(si_link_extension s);
+
+void sig_chld_hdl(int sig);
+#endif
+
diff --git a/Singular/lists.cc b/Singular/lists.cc
new file mode 100644
index 0000000..8220cb9
--- /dev/null
+++ b/Singular/lists.cc
@@ -0,0 +1,422 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: handling of the list type
+*/
+// to produce a non-inline version from lists.h
+#define LISTS_CC
+
+
+
+
+#include <kernel/mod2.h>
+#include <Singular/tok.h>
+//#include "ipid.h"
+#include <kernel/polys.h>
+#include <kernel/ideals.h>
+#include <Singular/attrib.h>
+#include <Singular/ipshell.h>
+#include <misc/intvec.h>
+#include <Singular/lists.h>
+
+omBin slists_bin = omGetSpecBin(sizeof(slists));
+
+int lSize(lists L)
+{
+  int n=L->nr;
+   while ((n>=0)&&((L->m[n].rtyp==DEF_CMD)||(L->m[n].rtyp==0))) n--;
+  return n;
+}
+
+lists lCopy(lists L)
+{
+  lists N=(lists)omAlloc0Bin(slists_bin);
+  int n=L->nr;
+  if (L->nr>=0)
+    N->Init(n+1);
+  else
+    N->Init();
+  for(;n>=0;n--)
+  {
+    N->m[n].Copy(&L->m[n]);
+  }
+  //Print("copy list with %d -> %d elems\n",L->nr,N->nr);
+  return N;
+}
+
+/*2
+* concat 2 lists
+*/
+BOOLEAN lAdd(leftv res, leftv u, leftv v)
+{
+  lists l=(lists) omAllocBin(slists_bin);
+  lists ul=(lists)u->CopyD();
+  lists vl=(lists)v->CopyD();
+  l->Init(ul->nr+vl->nr+2);
+  int i;
+
+  for(i=0;i<=ul->nr;i++)
+  {
+    //Print("u[%d]->r[%d]\n",i,i);
+    l->m[i].rtyp=ul->m[i].rtyp;
+    l->m[i].data=ul->m[i].data;
+  }
+  for(i=0;i<=vl->nr;i++)
+  {
+    //Print("v[%d]->r[%d]\n",i,i+ul->nr+1);
+    l->m[i+ul->nr+1].rtyp=vl->m[i].rtyp;
+    l->m[i+ul->nr+1].data=vl->m[i].data;
+  }
+  if (ul->m != NULL)
+    omFreeSize((ADDRESS)ul->m,(ul->nr+1)*sizeof(sleftv));
+  omFreeBin((ADDRESS)ul, slists_bin);
+  if (vl->m != NULL)
+    omFreeSize((ADDRESS)vl->m,(vl->nr+1)*sizeof(sleftv));
+  omFreeBin((ADDRESS)vl, slists_bin);
+  memset(u,0,sizeof(*u));
+  memset(v,0,sizeof(*v));
+  res->data = (char *)l;
+  //res->Print();
+  return FALSE;
+}
+
+/*2
+* insert v into list ul, destroys u
+*/
+lists lInsert0(lists ul, leftv v, int pos)
+{
+  if ((pos<0)||(v->rtyp==NONE))
+    return NULL;
+  lists l=(lists) omAllocBin(slists_bin);
+  l->Init(si_max(ul->nr+2,pos+1));
+  int i,j;
+
+  for(i=j=0;i<=ul->nr;i++,j++)
+  {
+    if(j==pos) j++;
+    l->m[j]=ul->m[i];
+  }
+  for(j=ul->nr+1;j<pos;j++)
+    l->m[j].rtyp=DEF_CMD;
+  // memset(&(l->m[pos]),0,sizeof(sleftv)); - done by Init
+  l->m[pos].rtyp=v->Typ();
+  l->m[pos].data=v->CopyD();
+  l->m[pos].flag=v->flag;
+  attr *a=v->Attribute();
+  if ((a!=NULL)&&(*a!=NULL))
+  {
+    l->m[pos].attribute=(*a)->Copy();
+  }
+  if (ul->m != NULL)
+    omFreeSize((ADDRESS)ul->m,(ul->nr+1)*sizeof(sleftv));
+  omFreeBin((ADDRESS)ul, slists_bin);
+  return l;
+}
+
+/*2
+* insert v into list u, at the beginning
+*/
+BOOLEAN lInsert(leftv res, leftv u, leftv v)
+{
+  lists ul=(lists)u->CopyD();
+  res->data=(char *)lInsert0(ul,v,0);
+  if (res->data==NULL)
+  {
+    Werror("cannot insert type `%s`",Tok2Cmdname(v->Typ()));
+    return TRUE;
+  }
+  return FALSE;
+}
+
+/*2
+* insert v into list u at pos w
+*/
+BOOLEAN lInsert3(leftv res, leftv u, leftv v, leftv w)
+{
+  lists ul=(lists)u->CopyD();
+  res->data=(char *)lInsert0(ul,v,(int)(long)w->Data());
+  if (res->data==NULL)
+  {
+    Werror("cannot insert type `%s` at pos. %d",
+      Tok2Cmdname(v->Typ()),(int)(long)w->Data());
+    return TRUE;
+  }
+  return FALSE;
+}
+
+/*2
+* append v to list u
+*/
+BOOLEAN lAppend(leftv res, leftv u, leftv v)
+{
+  lists ul=(lists)u->CopyD();
+  res->data=(char *)lInsert0(ul,v,ul->nr+1);
+  return (res->data==NULL);
+}
+
+/*2
+* delete v-th element from list u
+*/
+BOOLEAN lDelete(leftv res, leftv u, leftv v)
+{
+  lists ul=(lists)u->Data();
+  int VIndex=(int)(long)v->Data()-1;
+  int EndIndex=lSize(ul);
+
+  if((0<=VIndex)&&(VIndex<=ul->nr))
+  {
+    ul=(lists)u->CopyD();
+    int i,j;
+    lists l=(lists) omAllocBin(slists_bin);
+    l->Init(EndIndex+(VIndex>EndIndex));
+
+    for(i=j=0;i<=EndIndex;i++,j++)
+    {
+      if (i!=VIndex)
+      {
+        l->m[j]=ul->m[i];
+        memset(&ul->m[i],0,sizeof(ul->m[i]));
+      }
+      else
+      {
+        j--;
+        ul->m[i].CleanUp();
+      }
+    }
+    omFreeSize((ADDRESS)ul->m,(ul->nr+1)*sizeof(sleftv));
+    omFreeBin((ADDRESS)ul, slists_bin);
+    res->data = (char *)l;
+    return FALSE;
+  }
+  Werror("wrong index %d in list(%d)",VIndex+1,ul->nr+1);
+  return TRUE;
+}
+
+/*2
+* check, if a list contains any ring dependend data
+*/
+BOOLEAN lRingDependend(lists L)
+{
+  if (L==NULL) return FALSE;
+  int i=0;
+  while (i<=L->nr)
+  {
+    if ((L->m[i].rtyp!=QRING_CMD)
+    && (BEGIN_RING<L->m[i].rtyp)
+    && (L->m[i].rtyp<END_RING))
+      return TRUE;
+    if ((L->m[i].rtyp==LIST_CMD)&&lRingDependend((lists)L->m[i].data))
+      return TRUE;
+    i++;
+  }
+  return FALSE;
+}
+
+lists liMakeResolv(resolvente r, int length, int reallen,
+  int typ0, intvec ** weights, int add_row_shift)
+{
+  lists L=(lists)omAlloc0Bin(slists_bin);
+  if (length<=0)
+  {
+    // handle "empty" resolutions
+    L->Init(0);
+  }
+  else
+  {
+    int oldlength=length;
+    while (r[length-1]==NULL) length--;
+    if (reallen<=0) reallen=currRing->N;
+    reallen=si_max(reallen,length);
+    L->Init(reallen);
+    int i=0;
+
+    while (i<length)
+    {
+      if (r[i]!=NULL)
+      {
+        if (i==0)
+        {
+          L->m[i].rtyp=typ0;
+          int j=IDELEMS(r[0])-1;
+          while ((j>0) && (r[0]->m[j]==NULL)) j--;
+          j++;
+          if (j!=IDELEMS(r[0]))
+          {
+            pEnlargeSet(&(r[0]->m),IDELEMS(r[0]),j-IDELEMS(r[0]));
+            IDELEMS(r[0])=j;
+          }
+        }
+        else
+        {
+          L->m[i].rtyp=MODUL_CMD;
+          int rank=IDELEMS(r[i-1]);
+          if (idIs0(r[i-1]))
+          {
+            idDelete(&(r[i]));
+            r[i]=id_FreeModule(rank, currRing);
+          }
+          else
+          {
+            r[i]->rank=si_max(rank,(int)id_RankFreeModule(r[i], currRing));
+          }
+          idSkipZeroes(r[i]);
+        }
+        L->m[i].data=(void *)r[i];
+        if ((weights!=NULL) && (weights[i]!=NULL))
+        {
+          intvec *w=ivCopy(weights[i]);
+          (*w) += add_row_shift;
+          atSet((idhdl)&L->m[i],omStrDup("isHomog"),w,INTVEC_CMD);
+          weights[i] = NULL;
+        }
+      }
+      #ifdef TEST
+      else
+      {
+        // should not happen:
+        Warn("internal NULL in resolvente");
+        L->m[i].data=(void *)idInit(1,1);
+      }
+      #endif
+      i++;
+    }
+    omFreeSize((ADDRESS)r,oldlength*sizeof(ideal));
+    if (i==0)
+    {
+      L->m[0].rtyp=typ0;
+      L->m[0].data=(char *)idInit(1,1);
+      i=1;
+    }
+    while (i<reallen)
+    {
+      L->m[i].rtyp=MODUL_CMD;
+      ideal I=(ideal)L->m[i-1].data;
+      ideal J;
+      int rank=IDELEMS(I);
+      if (idIs0(I))
+      {
+        J=idFreeModule(rank);
+      }
+      else
+      {
+        J=idInit(1,rank);
+      }
+      L->m[i].data=(void *)J;
+      i++;
+    }
+    //Print("make res of length %d (0..%d) L:%d\n",length,length-1,L->nr);
+  }
+  return L;
+}
+
+resolvente liFindRes(lists L, int * len, int *typ0,intvec *** weights)
+{
+  resolvente r;
+  intvec ** w=NULL,*tw=NULL;
+
+  *len=L->nr+1;
+  if (*len<=0)
+  {
+    WerrorS("empty list");
+    return NULL;
+  }
+  r=(ideal *)omAlloc0((*len)*sizeof(ideal));
+  w=(intvec**)omAlloc0((*len)*sizeof(intvec*));
+  int i=0;
+  *typ0=MODUL_CMD;
+  while (i<(*len))
+  {
+    if (L->m[i].rtyp != MODUL_CMD)
+    {
+      if (L->m[i].rtyp!=IDEAL_CMD)
+      {
+        Werror("element %d is not of type module",i+1);
+        omFreeSize((ADDRESS)r,(*len)*sizeof(ideal));
+        return NULL;
+      }
+      *typ0=IDEAL_CMD;
+    }
+    if ((i>0) && (idIs0(r[i-1])))
+    {
+      //*len=i-1;
+      break;
+    }
+    r[i]=(ideal)L->m[i].data;
+    tw=(intvec*)atGet((idhdl)&L->m[i],"isHomog",INTVEC_CMD);
+    if (tw!=NULL)
+    {
+      w[i]=ivCopy(tw);
+    }
+    tw = NULL;
+    i++;
+  }
+  BOOLEAN hom_complex=TRUE;
+  int j=0;
+  while ((j<i) && hom_complex)
+  {
+    hom_complex = hom_complex && (w[i]!=NULL);
+    j++;
+  }
+  if ((!hom_complex) || (weights==NULL))
+  {
+    for (j=0;j<i;j++)
+    {
+      if (w[j]!=NULL) delete w[j];
+    }
+    omFreeSize((ADDRESS)w,(*len)*sizeof(intvec*));
+  }
+  else
+  {
+    *weights = w;
+  }
+  //Print("find res of length %d (0..%d) L:%d\n",*len,(*len)-1,L->nr);
+  return r;
+}
+
+char* lString(lists l, BOOLEAN typed, int dim)
+{
+  if (l->nr == -1)
+  {
+    if (typed) return omStrDup("list()");
+    return omStrDup("");
+  }
+
+  char** slist = (char**) omAlloc((l->nr+1) * sizeof(char*));
+  int i, j, k;
+  char *s;
+  for (i=0, j = 0, k = 0; i<=l->nr; i++)
+  {
+    slist[i] = l->m[i].String(NULL, typed, dim);
+    assume(slist[i] != NULL);
+    omCheckAddr(slist[i]);
+    if (*(slist[i]) != '\0')
+    {
+      j += strlen(slist[i]);
+      k++;
+    }
+  }
+  s = (char*) omAlloc(j+k+2+(typed ? 10 : 0) + (dim == 2 ? k : 0));
+
+  if (typed)
+    sprintf(s, "list(");
+  else
+    *s = '\0';
+
+  for (i=0; i<=l->nr; i++)
+  {
+    if (*(slist[i]) != '\0')
+    {
+      strcat(s, slist[i]);
+      strcat(s, ",");
+      if (dim == 2) strcat(s, "\n");
+    }
+    omCheckAddr(s);
+    omFree(slist[i]);
+  }
+  if (k > 0) s[strlen(s) - (dim == 2 ? 2 : 1)] = '\0';
+  if (typed) strcat(s, ")");
+  omCheckAddr(s);
+  omFreeSize(slist, (l->nr+1) * sizeof(char*));
+  return s;
+}
diff --git a/Singular/lists.h b/Singular/lists.h
new file mode 100644
index 0000000..d0c2edf
--- /dev/null
+++ b/Singular/lists.h
@@ -0,0 +1,73 @@
+#ifndef LISTS_H
+#define LISTS_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: handling of the list type
+*/
+#include <omalloc/omalloc.h>
+#include <kernel/structs.h>
+#include <kernel/ideals.h>
+#include <Singular/subexpr.h>
+#include <Singular/tok.h>
+
+#ifdef MDEBUG
+#define INLINE_THIS
+#else
+#define INLINE_THIS inline
+#endif
+
+extern omBin slists_bin;
+class slists
+{
+  public:
+    void Clean(ring r=currRing)
+    {
+      assume (this!=NULL);
+
+      if (nr>=0)
+      {
+        int i;
+        for(i=nr;i>=0;i--)
+        {
+          if (m[i].rtyp!=DEF_CMD) m[i].CleanUp(r);
+        }
+        omFreeSize((ADDRESS)m, (nr+1)*sizeof(sleftv));
+        nr=-1;
+      }
+      //omFreeSize((ADDRESS)this, sizeof(slists));
+      omFreeBin((ADDRESS)this,slists_bin);
+    }
+    INLINE_THIS void Init(int l=0);
+    int    nr; /* the number of elements in the list -1 */
+               /* -1: empty list */
+    sleftv  *m;  /* field of sleftv */
+};
+
+typedef slists *           lists;
+
+int lSize(lists L);
+lists lCopy(lists L);
+lists lInsert0(lists ul, leftv v, int pos);
+BOOLEAN lInsert(leftv res, leftv u, leftv v);
+BOOLEAN lInsert3(leftv res, leftv u, leftv v, leftv w);
+BOOLEAN lAppend(leftv res, leftv u, leftv v);
+BOOLEAN lDelete(leftv res, leftv u, leftv v);
+BOOLEAN lAdd(leftv res, leftv u, leftv v);
+BOOLEAN lRingDependend(lists L);
+char* lString(lists l, BOOLEAN typed = FALSE, int dim = 1);
+
+
+lists liMakeResolv(resolvente r, int length, int reallen, int typ0, intvec ** weights,int add_row_shift);
+resolvente liFindRes(lists L, int * len, int *typ0,intvec *** weights=NULL);
+
+#if ! defined(MDEBUG) || defined(LISTS_CC)
+INLINE_THIS void slists::Init(int l)
+      { nr=l-1; m=(sleftv *)((l>0) ? omAlloc0(l*sizeof(sleftv)): NULL);
+      }
+#endif
+
+#undef INLINE_THIS
+
+#endif
diff --git a/Singular/locals.h b/Singular/locals.h
new file mode 100644
index 0000000..b7fd621
--- /dev/null
+++ b/Singular/locals.h
@@ -0,0 +1,29 @@
+/*
+ * part of modgen
+ */
+
+// #include <kernel/mod2.h>
+#include <Singular/tok.h>
+#include <Singular/ipid.h>
+//#include <mmemory.h>
+#include <Singular/subexpr.h>
+//#include <utils.h>
+
+#include <kernel/structs.h>
+#include <Singular/ipconv.h>
+
+BOOLEAN jjANY2LIST(leftv res, leftv v, int cnt);
+
+#if 0
+extern "C"
+{
+  void   Print(char* fmt, ...);
+  void   PrintLn();
+  void   PrintS(char* s);
+
+  void   Werror(char *fmt, ...);
+  void   WerrorS(const char *s);
+}
+#endif
+
+const char *Tok2Cmdname( int tok);
diff --git a/Singular/make_alllib.sh b/Singular/make_alllib.sh
new file mode 100755
index 0000000..90d1a04
--- /dev/null
+++ b/Singular/make_alllib.sh
@@ -0,0 +1,16 @@
+#!/bin/sh
+#C="$1"
+#C=`readlink -f "$C"`
+#C=`dirname "$C"`
+#C=`ls -d1 "$C"`
+
+cp $1 all.lib.n
+chmod u+rw all.lib.n
+shift
+for i in $*
+do
+	echo "LIB \"$i\";" >> all.lib.n
+done
+#	[ ! -e "$i" ] && (cp -nv "$C/$i" .)
+chmod u-w all.lib.n
+mv -f all.lib.n all.lib
diff --git a/Singular/maps_ip.cc b/Singular/maps_ip.cc
new file mode 100644
index 0000000..7d63de2
--- /dev/null
+++ b/Singular/maps_ip.cc
@@ -0,0 +1,459 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT - the mapping of polynomials to other rings
+*/
+#define TRANSEXT_PRIVATES
+
+
+
+
+#include <kernel/mod2.h>
+#include <omalloc/omalloc.h>
+
+#include <coeffs/numbers.h>
+#include <coeffs/coeffs.h>
+
+#include <polys/monomials/ring.h>
+#include <polys/monomials/maps.h>
+#include <polys/matpol.h>
+#include <polys/prCopy.h>
+#include <polys/ext_fields/transext.h>
+
+//#include <libpolys/polys/ext_fields/longtrans.h>
+// #include <kernel/longalg.h>
+
+#include <kernel/GBEngine/kstd1.h>
+
+#include "maps_ip.h"
+#include "ipid.h"
+
+
+#include "lists.h"
+#include "tok.h"
+
+/* debug output: Tok2Cmdname in maApplyFetch*/
+#include "ipshell.h"
+
+// define this if you want to use the fast_map routine for mapping ideals
+//#define FAST_MAP
+
+#ifdef FAST_MAP
+#include <polys/monomials/maps.h>
+#endif
+
+
+/*2
+* maps the expression w to res,
+* switch what: MAP_CMD: use theMap for mapping, N for preimage ring
+*              //FETCH_CMD: use pOrdPoly for mapping
+*              IMAP_CMD: use perm for mapping, N for preimage ring
+*              default: map only poly-structures,
+*                       use perm and par_perm, N and P,
+*/
+BOOLEAN maApplyFetch(int what,map theMap,leftv res, leftv w, ring preimage_r,
+                     int *perm, int *par_perm, int P, nMapFunc nMap)
+{
+  int i;
+  int N = preimage_r->N;
+#if 0
+  Print("N=%d what=%s ",N,Tok2Cmdname(what));
+  if (perm!=NULL) for(i=1;i<=N;i++) Print("%d -> %d ",i,perm[i]);
+  PrintS("\n");
+  Print("P=%d ",P);
+  if (par_perm!=NULL) for(i=0;i<P;i++) Print("%d -> %d ",i,par_perm[i]);
+  PrintS("\n");
+#endif
+
+  void *data=w->Data();
+  res->rtyp = w->rtyp;
+  switch (w->rtyp)
+  {
+    case NUMBER_CMD:
+      if (P!=0)
+      {
+//        WerrorS("Sorry 'napPermNumber' was lost in the refactoring process (due to Frank): needs to be fixed");
+//        return TRUE;
+#if 1
+// poly n_PermNumber(const number z, const int *par_perm, const int OldPar, const ring src, const ring dst);
+        res->data= (void *) n_PermNumber((number)data, par_perm, P, preimage_r, currRing);
+#endif
+        res->rtyp=POLY_CMD;
+        if (nCoeff_is_Extension(currRing->cf))
+          res->data=(void *)p_MinPolyNormalize((poly)res->data, currRing);
+        pTest((poly) res->data);
+      }
+      else
+      {
+        assume( nMap != NULL );
+
+        number a = nMap((number)data, preimage_r->cf, currRing->cf);
+
+
+        if (nCoeff_is_Extension(currRing->cf))
+        {
+          n_Normalize(a, currRing->cf); // ???
+/*
+          number a = (number)res->data;
+          number one = nInit(1);
+          number product = nMult(a, one );
+          nDelete(&one);
+          nDelete(&a);
+          res->data=(void *)product;
+ */
+        }
+        #ifdef LDEBUG
+        n_Test(a, currRing->cf);
+        #endif
+        res->data=(void *)a;
+
+      }
+      break;
+    case POLY_CMD:
+    case VECTOR_CMD:
+      if ((what==FETCH_CMD)&& (preimage_r->cf==currRing->cf))
+        res->data=(void *)prCopyR( (poly)data, preimage_r, currRing);
+      else
+        if ( (what==IMAP_CMD) || /*(*/ (what==FETCH_CMD) /*)*/) /* && (nMap!=nCopy)*/
+        res->data=(void *)p_PermPoly((poly)data,perm,preimage_r,currRing, nMap,par_perm,P);
+      else /*if (what==MAP_CMD)*/
+      {
+        p_Test((poly)data,preimage_r);
+        matrix s=mpNew(N,maMaxDeg_P((poly)data, preimage_r));
+        res->data=(void *)maEval(theMap, (poly)data, preimage_r, nMap, (ideal)s, currRing);
+        idDelete((ideal *)&s);
+      }
+      if (nCoeff_is_Extension(currRing->cf))
+        res->data=(void *)p_MinPolyNormalize((poly)res->data, currRing);
+      pTest((poly)res->data);
+      break;
+    case MODUL_CMD:
+    case MATRIX_CMD:
+    case IDEAL_CMD:
+    case MAP_CMD:
+    {
+      int C=((matrix)data)->cols();
+      int R;
+      if (w->rtyp==MAP_CMD) R=1;
+      else R=((matrix)data)->rows();
+      matrix m=mpNew(R,C);
+      char *tmpR=NULL;
+      if(w->rtyp==MAP_CMD)
+      {
+        tmpR=((map)data)->preimage;
+        ((matrix)data)->rank=((matrix)data)->rows();
+      }
+      if ((what==FETCH_CMD)&& (preimage_r->cf == currRing->cf))
+      {
+        for (i=R*C-1;i>=0;i--)
+        {
+          m->m[i]=prCopyR(((ideal)data)->m[i], preimage_r, currRing);
+          pTest(m->m[i]);
+        }
+      }
+      else
+      if ( (what==IMAP_CMD) || /*(*/ (what==FETCH_CMD) /*)*/) /* && (nMap!=nCopy)*/
+      {
+        for (i=R*C-1;i>=0;i--)
+        {
+          m->m[i]=p_PermPoly(((ideal)data)->m[i],perm,preimage_r,currRing,
+                          nMap,par_perm,P);
+          pTest(m->m[i]);
+        }
+      }
+      else /* if(what==MAP_CMD) */
+      {
+        matrix s=mpNew(N,maMaxDeg_Ma((ideal)data,preimage_r));
+        for (i=R*C-1;i>=0;i--)
+        {
+          m->m[i]=maEval(theMap, ((ideal)data)->m[i], preimage_r, nMap, (ideal)s, currRing);
+          pTest(m->m[i]);
+        }
+        idDelete((ideal *)&s);
+      }
+      if (nCoeff_is_Extension(currRing->cf))
+      {
+        for (i=R*C-1;i>=0;i--)
+        {
+          m->m[i]=p_MinPolyNormalize(m->m[i], currRing);
+          pTest(m->m[i]);
+        }
+      }
+      if(w->rtyp==MAP_CMD)
+      {
+        ((map)data)->preimage=tmpR;
+        ((map)m)->preimage=omStrDup(tmpR);
+      }
+      else
+      {
+        m->rank=((matrix)data)->rank;
+      }
+      res->data=(char *)m;
+      idTest((ideal) m);
+      break;
+    }
+
+    case LIST_CMD:
+    {
+      lists l=(lists)data;
+      lists ml=(lists)omAllocBin(slists_bin);
+      ml->Init(l->nr+1);
+      for(i=0;i<=l->nr;i++)
+      {
+        if (((l->m[i].rtyp>BEGIN_RING)&&(l->m[i].rtyp<END_RING))
+        ||(l->m[i].rtyp==LIST_CMD))
+        {
+          if (maApplyFetch(what,theMap,&ml->m[i],&l->m[i],
+                           preimage_r,perm,par_perm,P,nMap))
+          {
+            ml->Clean();
+            omFreeBin((ADDRESS)ml, slists_bin);
+            res->rtyp=0;
+            return TRUE;
+          }
+        }
+        else
+        {
+          ml->m[i].Copy(&l->m[i]);
+        }
+      }
+      res->data=(char *)ml;
+      break;
+    }
+    default:
+    {
+      return TRUE;
+    }
+  }
+  return FALSE;
+}
+
+/*2
+* substitutes the parameter par (from 1..N) by image,
+* does not destroy p and  image
+*/
+poly pSubstPar(poly p, int par, poly image)
+{
+  const ring R = currRing->cf->extRing;
+  ideal theMapI = idInit(rPar(currRing),1);
+  nMapFunc nMap = n_SetMap(R->cf, currRing->cf);
+  int i;
+  for(i = rPar(currRing);i>0;i--)
+  {
+    if (i != par)
+      theMapI->m[i-1]= p_NSet(n_Param(i, currRing), currRing);
+    else
+      theMapI->m[i-1] = p_Copy(image, currRing);
+    p_Test(theMapI->m[i-1],currRing);
+  }
+  //iiWriteMatrix((matrix)theMapI,"map:",1,currRing,0);
+
+  map theMap=(map)theMapI;
+  theMap->preimage=NULL;
+
+  leftv v=(leftv)omAllocBin(sleftv_bin);
+  sleftv tmpW;
+  poly res=NULL;
+
+  p_Normalize(p,currRing);
+  if (currRing->cf->rep==n_rep_rat_fct )
+  {
+    while (p!=NULL)
+    {
+      memset(v,0,sizeof(sleftv));
+
+      number d = n_GetDenom(p_GetCoeff(p, currRing), currRing);
+      p_Test((poly)NUM(d), R);
+
+      if ( n_IsOne (d, currRing->cf) )
+      {
+        n_Delete(&d, currRing); d = NULL;
+      }
+      else if (!p_IsConstant((poly)NUM(d), R))
+      {
+        WarnS("ignoring denominators of coefficients...");
+        n_Delete(&d, currRing); d = NULL;
+      }
+
+      number num = n_GetNumerator(p_GetCoeff(p, currRing), currRing);
+      memset(&tmpW,0,sizeof(sleftv));
+      tmpW.rtyp = POLY_CMD;
+      p_Test((poly)NUM(num), R);
+
+      tmpW.data = NUM (num); // a copy of this poly will be used
+
+      p_Normalize(NUM(num),R);
+      if (maApplyFetch(MAP_CMD,theMap,v,&tmpW,R,NULL,NULL,0,nMap))
+      {
+        WerrorS("map failed");
+        v->data=NULL;
+      }
+      n_Delete(&num, currRing);
+      //TODO check for memory leaks
+      poly pp = pHead(p);
+      //PrintS("map:");pWrite(pp);
+      if( d != NULL )
+      {
+        pSetCoeff(pp, n_Invers(d, currRing->cf));
+        n_Delete(&d, currRing); // d = NULL;
+      }
+      else
+        pSetCoeff(pp, nInit(1));
+
+      //PrintS("->");pWrite((poly)(v->data));
+      poly ppp = pMult((poly)(v->data),pp);
+      //PrintS("->");pWrite(ppp);
+      res=pAdd(res,ppp);
+      pIter(p);
+    }
+  }
+  else if (currRing->cf->rep==n_rep_poly )
+  {
+    while (p!=NULL)
+    {
+      memset(v,0,sizeof(sleftv));
+
+      number num = n_GetNumerator(p_GetCoeff(p, currRing), currRing);
+      memset(&tmpW,0,sizeof(sleftv));
+      tmpW.rtyp = POLY_CMD;
+      p_Test((poly)num, R);
+
+
+      p_Normalize((poly)num,R);
+      if (num==NULL) num=(number)R->qideal->m[0];
+      tmpW.data = num; // a copy of this poly will be used
+      if (maApplyFetch(MAP_CMD,theMap,v,&tmpW,R,NULL,NULL,0,nMap))
+      {
+        WerrorS("map failed");
+        v->data=NULL;
+      }
+      if (num!=(number)R->qideal->m[0]) n_Delete(&num, currRing);
+      //TODO check for memory leaks
+      poly pp = pHead(p);
+      //PrintS("map:");pWrite(pp);
+      pSetCoeff(pp,n_Init(1,currRing));
+      //PrintS("cf->");pWrite((poly)(v->data));
+      poly ppp = pMult((poly)(v->data),pp);
+      //PrintS("->");pWrite(ppp);
+      res=pAdd(res,ppp);
+      pIter(p);
+    }
+  }
+  else
+  {
+    WerrorS("cannot apply subst for these coeffcients");
+  }
+  idDelete((ideal *)(&theMap));
+  omFreeBin((ADDRESS)v, sleftv_bin);
+  return res;
+}
+
+/*2
+* substitute the n-th parameter by the poly e in id
+* does not destroy id and e
+*/
+ideal  idSubstPar(ideal id, int n, poly e)
+{
+  int k=MATROWS((matrix)id)*MATCOLS((matrix)id);
+  ideal res=(ideal)mpNew(MATROWS((matrix)id),MATCOLS((matrix)id));
+
+  res->rank = id->rank;
+  for(k--;k>=0;k--)
+  {
+    res->m[k]=pSubstPar(id->m[k],n,e);
+  }
+  return res;
+}
+
+/*2
+* substitutes the variable var (from 1..N) by image,
+* does not destroy p and  image
+*/
+poly pSubstPoly(poly p, int var, poly image)
+{
+  if (p==NULL) return NULL;
+#ifdef HAVE_PLURAL
+  if (rIsPluralRing(currRing))
+  {
+    return pSubst(pCopy(p),var,image);
+  }
+#endif
+  map theMap=(map)idMaxIdeal(1);
+  theMap->preimage=NULL;
+  pDelete(&(theMap->m[var-1]));
+  theMap->m[var-1]=pCopy(image);
+
+  poly res=NULL;
+#ifdef FAST_MAP
+  if (pGetComp(p)==0)
+  {
+    ideal src_id=idInit(1,1);
+    src_id->m[0]=p;
+    ideal res_id=fast_map(src_id,currRing,(ideal)theMap,currRing);
+    res=res_id->m[0];
+    res_id->m[0]=NULL; idDelete(&res_id);
+    src_id->m[0]=NULL; idDelete(&src_id);
+  }
+  else
+#endif
+  {
+    sleftv tmpW;
+    memset(&tmpW,0,sizeof(sleftv));
+    tmpW.rtyp=POLY_CMD;
+    tmpW.data=p;
+    leftv v=(leftv)omAlloc0Bin(sleftv_bin);
+    if (maApplyFetch(MAP_CMD,theMap,v,&tmpW,currRing,NULL,NULL,0,
+                            n_SetMap(currRing->cf, currRing->cf)))
+    {
+      WerrorS("map failed");
+      v->data=NULL;
+    }
+    res=(poly)(v->data);
+    omFreeBin((ADDRESS)v, sleftv_bin);
+  }
+  idDelete((ideal *)(&theMap));
+  return res;
+}
+
+/*2
+* substitute the n-th variable by the poly e in id
+* does not destroy id and e
+*/
+ideal  idSubstPoly(ideal id, int n, poly e)
+{
+
+#ifdef HAVE_PLURAL
+  if (rIsPluralRing(currRing))
+  {
+    int k=MATROWS((matrix)id)*MATCOLS((matrix)id);
+    ideal res=(ideal)mpNew(MATROWS((matrix)id),MATCOLS((matrix)id));
+    res->rank = id->rank;
+    for(k--;k>=0;k--)
+    {
+      res->m[k]=pSubst(pCopy(id->m[k]),n,e);
+    }
+    return res;
+  }
+#endif
+  map theMap=(map)idMaxIdeal(1);
+  theMap->preimage=NULL;
+  pDelete(&(theMap->m[n-1]));
+  theMap->m[n-1]=pCopy(e);
+
+  leftv v=(leftv)omAlloc0Bin(sleftv_bin);
+  sleftv tmpW;
+  memset(&tmpW,0,sizeof(sleftv));
+  tmpW.rtyp=IDEAL_CMD;
+  tmpW.data=id;
+  if (maApplyFetch(MAP_CMD,theMap,v,&tmpW,currRing,NULL,NULL,0,
+                          n_SetMap(currRing->cf, currRing->cf)))
+  {
+    WerrorS("map failed");
+    v->data=NULL;
+  }
+  ideal res=(ideal)(v->data);
+  idDelete((ideal *)(&theMap));
+  omFreeBin((ADDRESS)v, sleftv_bin);
+  return res;
+}
diff --git a/Singular/maps_ip.h b/Singular/maps_ip.h
new file mode 100644
index 0000000..f6909be
--- /dev/null
+++ b/Singular/maps_ip.h
@@ -0,0 +1,33 @@
+#ifndef MAPS_IP_H
+#define MAPS_IP_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT - the mapping of polynomials to other rings
+*/
+
+#include <misc/auxiliary.h>
+#include <polys/matpol.h>
+
+#include <kernel/structs.h>
+#include <kernel/ideals.h>
+#include <kernel/polys.h>
+
+poly pSubstPoly(poly p, int var, poly image);
+poly pSubstPar(poly p, int par, poly image);
+ideal  idSubstPoly(ideal id, int n, poly e);
+ideal  idSubstPar(ideal id, int n, poly e);
+
+
+/*
+* maps the expression w to res,
+* switch what: MAP_CMD: use theMap for mapping, N for preimage ring
+*              //FETCH_CMD: use pOrdPoly for mapping
+*              IMAP_CMD: use perm for mapping, N for preimage ring
+*              default: map only poly-structures,
+*                       use perm and par_perm, N and P,
+*/
+BOOLEAN maApplyFetch(int what,map theMap,leftv res, leftv w, ring preimage_r,
+                     int *perm, int *par_perm, int P, nMapFunc nMap);
+#endif
diff --git a/Singular/misc_ip.cc b/Singular/misc_ip.cc
new file mode 100644
index 0000000..ae176fe
--- /dev/null
+++ b/Singular/misc_ip.cc
@@ -0,0 +1,1317 @@
+/*****************************************************************************\
+ * Computer Algebra System SINGULAR
+\*****************************************************************************/
+/** @file misc_ip.cc
+ *
+ * This file provides miscellaneous functionality.
+ *
+ * For more general information, see the documentation in misc_ip.h.
+ *
+ **/
+/*****************************************************************************/
+
+// include header files
+
+#include <kernel/mod2.h>
+#include <misc/auxiliary.h>
+#include <misc/sirandom.h>
+
+#include <reporter/si_signals.h>
+
+#include <factory/factory.h>
+
+#include <coeffs/si_gmp.h>
+#include <coeffs/coeffs.h>
+#include <coeffs/OPAE.h>
+#include <coeffs/OPAEQ.h>
+#include <coeffs/OPAEp.h>
+
+#include <polys/ext_fields/algext.h>
+#include <polys/ext_fields/transext.h>
+
+#ifdef HAVE_SIMPLEIPC
+#include <Singular/links/simpleipc.h>
+#endif
+
+#include "misc_ip.h"
+#include "ipid.h"
+#include "feOpt.h"
+#include "links/silink.h"
+#include "mod_lib.h"
+
+static FORCE_INLINE void number2mpz(number n, mpz_t m){ number2mpz(n, coeffs_BIGINT, m); }
+static FORCE_INLINE number mpz2number(mpz_t m){ return mpz2number(m, coeffs_BIGINT); }
+
+
+void setListEntry(lists L, int index, mpz_t n)
+{ /* assumes n > 0 */
+  /* try to fit nn into an int: */
+  if (mpz_size1(n)<=1)
+  {
+    int ui=(int)mpz_get_si(n);
+    if ((((ui<<3)>>3)==ui)
+    && (mpz_cmp_si(n,(long)ui)==0))
+    {
+      L->m[index].rtyp = INT_CMD; L->m[index].data = (void*)(long)ui;
+      return;
+    }
+  }
+  number nn = mpz2number(n);
+  L->m[index].rtyp = BIGINT_CMD; L->m[index].data = (void*)nn;
+}
+
+void setListEntry_ui(lists L, int index, unsigned long ui)
+{ /* assumes n > 0 */
+  /* try to fit nn into an int: */
+  int i=(int)ui;
+  if ((((unsigned long)i)==ui) && (((i<<3)>>3)==i))
+  {
+    L->m[index].rtyp = INT_CMD; L->m[index].data = (void*)(long)i;
+  }
+  else
+  {
+    number nn = n_Init(ui, coeffs_BIGINT);
+    L->m[index].rtyp = BIGINT_CMD; L->m[index].data = (void*)nn;
+  }
+}
+
+/* Factoring with Pollard's rho method. stolen from GMP/demos */
+static unsigned add[] = {4, 2, 4, 2, 4, 6, 2, 6};
+
+static int factor_using_division (mpz_t t, unsigned int limit,lists primes, int *multiplicities,int &index, unsigned long bound)
+{
+  mpz_t q, r;
+  unsigned long int f;
+  int ai;
+  unsigned *addv = add;
+  unsigned int failures;
+  int bound_not_reached=1;
+
+  mpz_init (q);
+  mpz_init (r);
+
+  f = mpz_scan1 (t, 0);
+  mpz_div_2exp (t, t, f);
+  if (f>0)
+  {
+    setListEntry_ui(primes, index, 2);
+    multiplicities[index++] = f;
+  }
+
+  f=0;
+  loop
+  {
+    mpz_tdiv_qr_ui (q, r, t, 3);
+    if (mpz_cmp_ui (r, 0) != 0)
+        break;
+    mpz_set (t, q);
+    f++;
+  }
+  if (f>0)
+  {
+    setListEntry_ui(primes, index, 3);
+    multiplicities[index++] = f;
+  }
+  f=0;
+  loop
+  {
+    mpz_tdiv_qr_ui (q, r, t, 5);
+    if (mpz_cmp_ui (r, 0) != 0)
+        break;
+    mpz_set (t, q);
+    f++;
+  }
+  if (f>0)
+  {
+    setListEntry_ui(primes, index, 5);
+    multiplicities[index++] = f;
+  }
+
+  failures = 0;
+  f = 7;
+  ai = 0;
+  unsigned long last_f=0;
+  while (mpz_cmp_ui (t, 1) != 0)
+  {
+    mpz_tdiv_qr_ui (q, r, t, f);
+    if (mpz_cmp_ui (r, 0) != 0)
+    {
+      f += addv[ai];
+      if (mpz_cmp_ui (t, f) < 0)
+        break;
+      ai = (ai + 1) & 7;
+      failures++;
+      if (failures > limit)
+        break;
+      if ((bound!=0) && (f>bound))
+      {
+        bound_not_reached=0;
+        break;
+      }
+    }
+    else
+    {
+      mpz_swap (t, q);
+      if (f!=last_f)
+      {
+        setListEntry_ui(primes, index, f);
+        multiplicities[index]++;
+        index++;
+      }
+      else
+      {
+        multiplicities[index-1]++;
+      }
+      last_f=f;
+      failures = 0;
+    }
+  }
+
+  mpz_clear (q);
+  mpz_clear (r);
+  //printf("bound=%d,f=%d,failures=%d, reached=%d\n",bound,f,failures,bound_not_reached);
+  return bound_not_reached;
+}
+
+static void factor_using_pollard_rho (mpz_t n, unsigned long a, lists primes, int * multiplicities,int &index)
+{
+  mpz_t x, x1, y, P;
+  mpz_t t1, t2;
+  mpz_t last_f;
+  unsigned long long k, l, i;
+
+  mpz_init (t1);
+  mpz_init (t2);
+  mpz_init_set_si (last_f, 0);
+  mpz_init_set_si (y, 2);
+  mpz_init_set_si (x, 2);
+  mpz_init_set_si (x1, 2);
+  mpz_init_set_ui (P, 1);
+  k = 1;
+  l = 1;
+
+  while (mpz_cmp_ui (n, 1) != 0)
+  {
+    loop
+    {
+      do
+      {
+        mpz_mul (t1, x, x);
+        mpz_mod (x, t1, n);
+        mpz_add_ui (x, x, a);
+        mpz_sub (t1, x1, x);
+        mpz_mul (t2, P, t1);
+        mpz_mod (P, t2, n);
+
+        if (k % 32 == 1)
+        {
+          mpz_gcd (t1, P, n);
+          if (mpz_cmp_ui (t1, 1) != 0)
+            goto factor_found;
+          mpz_set (y, x);
+        }
+      }
+      while (--k != 0);
+
+      mpz_gcd (t1, P, n);
+      if (mpz_cmp_ui (t1, 1) != 0)
+        goto factor_found;
+
+      mpz_set (x1, x);
+      k = l;
+      l = 2 * l;
+      for (i = 0; i < k; i++)
+      {
+        mpz_mul (t1, x, x);
+        mpz_mod (x, t1, n);
+        mpz_add_ui (x, x, a);
+      }
+      mpz_set (y, x);
+    }
+
+  factor_found:
+    do
+    {
+      mpz_mul (t1, y, y);
+      mpz_mod (y, t1, n);
+      mpz_add_ui (y, y, a);
+      mpz_sub (t1, x1, y);
+      mpz_gcd (t1, t1, n);
+    }
+    while (mpz_cmp_ui (t1, 1) == 0);
+
+    mpz_divexact (n, n, t1);        /* divide by t1, before t1 is overwritten */
+
+    if (!mpz_probab_prime_p (t1, 10))
+    {
+      do
+      {
+        mp_limb_t a_limb;
+        mpn_random (&a_limb, (mp_size_t) 1);
+        a = a_limb;
+      }
+      while (a == 0);
+
+      factor_using_pollard_rho (t1, a, primes,multiplicities,index);
+    }
+    else
+    {
+      if (mpz_cmp(t1,last_f)==0)
+      {
+        multiplicities[index-1]++;
+      }
+      else
+      {
+        mpz_set(last_f,t1);
+        setListEntry(primes, index, t1);
+        multiplicities[index++] = 1;
+      }
+    }
+    mpz_mod (x, x, n);
+    mpz_mod (x1, x1, n);
+    mpz_mod (y, y, n);
+    if (mpz_probab_prime_p (n, 10))
+    {
+      if (mpz_cmp(n,last_f)==0)
+      {
+        multiplicities[index-1]++;
+      }
+      else
+      {
+        mpz_set(last_f,n);
+        setListEntry(primes, index, n);
+        multiplicities[index++] = 1;
+      }
+      mpz_set_ui(n,1);
+      break;
+    }
+  }
+
+  mpz_clear (P);
+  mpz_clear (t2);
+  mpz_clear (t1);
+  mpz_clear (x1);
+  mpz_clear (x);
+  mpz_clear (y);
+  mpz_clear (last_f);
+}
+
+static void factor_gmp (mpz_t t,lists primes,int *multiplicities,int &index,unsigned long bound)
+{
+  unsigned int division_limit;
+
+  if (mpz_sgn (t) == 0)
+    return;
+
+  /* Set the trial division limit according the size of t.  */
+  division_limit = mpz_sizeinbase (t, 2);
+  if (division_limit > 1000)
+    division_limit = 1000 * 1000;
+  else
+    division_limit = division_limit * division_limit;
+
+  if (factor_using_division (t, division_limit,primes,multiplicities,index,bound))
+  {
+    if (mpz_cmp_ui (t, 1) != 0)
+    {
+      if (mpz_probab_prime_p (t, 10))
+      {
+        setListEntry(primes, index, t);
+        multiplicities[index++] = 1;
+        mpz_set_ui(t,1);
+      }
+      else
+        factor_using_pollard_rho (t, 1L, primes,multiplicities,index);
+    }
+  }
+}
+/* n and pBound are assumed to be bigint numbers */
+lists primeFactorisation(const number n, const int pBound)
+{
+  int i;
+  int index=0;
+  mpz_t nn; number2mpz(n, nn);
+  lists primes = (lists)omAllocBin(slists_bin); primes->Init(1000);
+  int* multiplicities = (int*)omAlloc0(1000*sizeof(int));
+  int positive=1;
+
+  if (!n_IsZero(n, coeffs_BIGINT))
+  {
+    if (!n_GreaterZero(n, coeffs_BIGINT))
+    {
+      positive=-1;
+      mpz_neg(nn,nn);
+    }
+    factor_gmp(nn,primes,multiplicities,index,pBound);
+  }
+
+  lists primesL = (lists)omAllocBin(slists_bin);
+  primesL->Init(index);
+  for (i = 0; i < index; i++)
+  {
+    primesL->m[i].rtyp = primes->m[i].rtyp;
+    primesL->m[i].data = primes->m[i].data;
+    primes->m[i].rtyp=0;
+    primes->m[i].data=NULL;
+  }
+  primes->Clean(NULL);
+
+  lists multiplicitiesL = (lists)omAllocBin(slists_bin);
+  multiplicitiesL->Init(index);
+  for (i = 0; i < index; i++)
+  {
+    multiplicitiesL->m[i].rtyp = INT_CMD;
+    multiplicitiesL->m[i].data = (void*)(long)multiplicities[i];
+  }
+  omFree(multiplicities);
+
+  lists L=(lists)omAllocBin(slists_bin);
+  L->Init(3);
+  if (positive==-1) mpz_neg(nn,nn);
+  L->m[0].rtyp = LIST_CMD; L->m[0].data = (void*)primesL;
+  L->m[1].rtyp = LIST_CMD; L->m[1].data = (void*)multiplicitiesL;
+  setListEntry(L, 2, nn);
+
+  mpz_clear(nn);
+
+  return L;
+}
+
+#include <omalloc/omalloc.h>
+#include <misc/mylimits.h>
+
+#include <misc/options.h>
+#include <misc/intvec.h>
+
+#include <polys/monomials/ring.h>
+#include <polys/templates/p_Procs.h>
+
+#include <kernel/GBEngine/kstd1.h>
+#include <kernel/oswrapper/timer.h>
+#include <resources/feResource.h>
+#include <kernel/oswrapper/feread.h>
+
+#include "subexpr.h"
+#include "cntrlc.h"
+#include "ipid.h"
+#include "ipshell.h"
+
+#include "fehelp.h"
+
+#ifdef HAVE_STATIC
+#undef HAVE_DYN_RL
+#endif
+
+//#ifdef HAVE_LIBPARSER
+//#  include "libparse.h"
+//#endif /* HAVE_LIBPARSER */
+
+
+/*2
+* the renice routine for very large jobs
+* works only on unix machines,
+* testet on : linux, HP 9.0
+*
+*#include <sys/times.h>
+*#include <sys/resource.h>
+*extern "C" int setpriority(int,int,int);
+*void very_nice()
+*{
+*#ifndef NO_SETPRIORITY
+*  setpriority(PRIO_PROCESS,0,19);
+*#endif
+*  sleep(10);
+*}
+*/
+
+#include <string.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <time.h>
+
+
+void singular_example(char *str)
+{
+  assume(str!=NULL);
+  char *s=str;
+  while (*s==' ') s++;
+  char *ss=s;
+  while (*ss!='\0') ss++;
+  while (*ss<=' ')
+  {
+    *ss='\0';
+    ss--;
+  }
+  idhdl h=IDROOT->get(s,myynest);
+  if ((h!=NULL) && (IDTYP(h)==PROC_CMD))
+  {
+    char *lib=iiGetLibName(IDPROC(h));
+    if((lib!=NULL)&&(*lib!='\0'))
+    {
+      Print("// proc %s from lib %s\n",s,lib);
+      s=iiGetLibProcBuffer(IDPROC(h), 2);
+      if (s!=NULL)
+      {
+        if (strlen(s)>5)
+        {
+          iiEStart(s,IDPROC(h));
+          omFree((ADDRESS)s);
+          return;
+        }
+        else omFree((ADDRESS)s);
+      }
+    }
+  }
+  else
+  {
+    char sing_file[MAXPATHLEN];
+    FILE *fd=NULL;
+    char *res_m=feResource('m', 0);
+    if (res_m!=NULL)
+    {
+      sprintf(sing_file, "%s/%s.sing", res_m, s);
+      fd = feFopen(sing_file, "r");
+    }
+    if (fd != NULL)
+    {
+
+      int old_echo = si_echo;
+      int length, got;
+      char* s;
+
+      fseek(fd, 0, SEEK_END);
+      length = ftell(fd);
+      fseek(fd, 0, SEEK_SET);
+      s = (char*) omAlloc((length+20)*sizeof(char));
+      got = fread(s, sizeof(char), length, fd);
+      fclose(fd);
+      if (got != length)
+      {
+        Werror("Error while reading file %s", sing_file);
+      }
+      else
+      {
+        s[length] = '\0';
+        strcat(s, "\n;return();\n\n");
+        si_echo = 2;
+        iiEStart(s, NULL);
+        si_echo = old_echo;
+      }
+      omFree(s);
+    }
+    else
+    {
+      Werror("no example for %s", str);
+    }
+  }
+}
+
+
+struct soptionStruct
+{
+  const char * name;
+  unsigned   setval;
+  unsigned   resetval;
+};
+
+struct soptionStruct optionStruct[]=
+{
+  {"prot",         Sy_bit(OPT_PROT),           ~Sy_bit(OPT_PROT)   },
+  {"redSB",        Sy_bit(OPT_REDSB),          ~Sy_bit(OPT_REDSB)   },
+  {"notBuckets",   Sy_bit(OPT_NOT_BUCKETS),    ~Sy_bit(OPT_NOT_BUCKETS)   },
+  {"notSugar",     Sy_bit(OPT_NOT_SUGAR),      ~Sy_bit(OPT_NOT_SUGAR)   },
+  {"interrupt",    Sy_bit(OPT_INTERRUPT),      ~Sy_bit(OPT_INTERRUPT)   },
+  {"sugarCrit",    Sy_bit(OPT_SUGARCRIT),      ~Sy_bit(OPT_SUGARCRIT)   },
+  {"teach",        Sy_bit(OPT_DEBUG),          ~Sy_bit(OPT_DEBUG)  },
+  {"notSyzMinim",  Sy_bit(OPT_NO_SYZ_MINIM),   ~Sy_bit(OPT_NO_SYZ_MINIM)  },
+  /* 9 return SB in syz, quotient, intersect */
+  {"returnSB",     Sy_bit(OPT_RETURN_SB),      ~Sy_bit(OPT_RETURN_SB)  },
+  {"fastHC",       Sy_bit(OPT_FASTHC),         ~Sy_bit(OPT_FASTHC)  },
+  /* 11-19 sort in L/T */
+  {"staircaseBound",Sy_bit(OPT_STAIRCASEBOUND),~Sy_bit(OPT_STAIRCASEBOUND)  },
+  {"multBound",    Sy_bit(OPT_MULTBOUND),      ~Sy_bit(OPT_MULTBOUND)  },
+  {"degBound",     Sy_bit(OPT_DEGBOUND),       ~Sy_bit(OPT_DEGBOUND)  },
+  /* 25 no redTail(p)/redTail(s) */
+  {"redTail",      Sy_bit(OPT_REDTAIL),        ~Sy_bit(OPT_REDTAIL)  },
+  {"redThrough",   Sy_bit(OPT_REDTHROUGH),     ~Sy_bit(OPT_REDTHROUGH)  },
+  {"lazy",         Sy_bit(OPT_OLDSTD),         ~Sy_bit(OPT_OLDSTD)  },
+  {"intStrategy",  Sy_bit(OPT_INTSTRATEGY),    ~Sy_bit(OPT_INTSTRATEGY)  },
+  {"infRedTail",   Sy_bit(OPT_INFREDTAIL),     ~Sy_bit(OPT_INFREDTAIL)  },
+  /* 30: use not regularity for syz */
+  {"notRegularity",Sy_bit(OPT_NOTREGULARITY),  ~Sy_bit(OPT_NOTREGULARITY)  },
+  {"weightM",      Sy_bit(OPT_WEIGHTM),        ~Sy_bit(OPT_WEIGHTM)  },
+/*special for "none" and also end marker for showOption:*/
+  {"ne",           0,                          0 }
+};
+
+struct soptionStruct verboseStruct[]=
+{
+  {"mem",      Sy_bit(V_SHOW_MEM),  ~Sy_bit(V_SHOW_MEM)   },
+  {"yacc",     Sy_bit(V_YACC),      ~Sy_bit(V_YACC)       },
+  {"redefine", Sy_bit(V_REDEFINE),  ~Sy_bit(V_REDEFINE)   },
+  {"reading",  Sy_bit(V_READING),   ~Sy_bit(V_READING)    },
+  {"loadLib",  Sy_bit(V_LOAD_LIB),  ~Sy_bit(V_LOAD_LIB)   },
+  {"debugLib", Sy_bit(V_DEBUG_LIB), ~Sy_bit(V_DEBUG_LIB)  },
+  {"loadProc", Sy_bit(V_LOAD_PROC), ~Sy_bit(V_LOAD_PROC)  },
+  {"defRes",   Sy_bit(V_DEF_RES),   ~Sy_bit(V_DEF_RES)    },
+  {"usage",    Sy_bit(V_SHOW_USE),  ~Sy_bit(V_SHOW_USE)   },
+  {"Imap",     Sy_bit(V_IMAP),      ~Sy_bit(V_IMAP)       },
+  {"prompt",   Sy_bit(V_PROMPT),    ~Sy_bit(V_PROMPT)     },
+  {"length",   Sy_bit(V_LENGTH),    ~Sy_bit(V_LENGTH)     },
+  {"notWarnSB",Sy_bit(V_NSB),       ~Sy_bit(V_NSB)        },
+  {"contentSB",Sy_bit(V_CONTENTSB), ~Sy_bit(V_CONTENTSB)  },
+  {"cancelunit",Sy_bit(V_CANCELUNIT),~Sy_bit(V_CANCELUNIT)},
+  {"modpsolve",Sy_bit(V_MODPSOLVSB),~Sy_bit(V_MODPSOLVSB)},
+  {"geometricSB",Sy_bit(V_UPTORADICAL),~Sy_bit(V_UPTORADICAL)},
+  {"findMonomials",Sy_bit(V_FINDMONOM),~Sy_bit(V_FINDMONOM)},
+  {"coefStrat",Sy_bit(V_COEFSTRAT), ~Sy_bit(V_COEFSTRAT)},
+  {"qringNF",  Sy_bit(V_QRING),     ~Sy_bit(V_QRING)},
+  {"warn",     Sy_bit(V_ALLWARN),   ~Sy_bit(V_ALLWARN)},
+  {"interedSyz",Sy_bit(V_INTERSECT_SYZ), ~Sy_bit(V_INTERSECT_SYZ)},
+  {"interedElim",Sy_bit(V_INTERSECT_ELIM), ~Sy_bit(V_INTERSECT_ELIM)},
+/*special for "none" and also end marker for showOption:*/
+  {"ne",         0,          0 }
+};
+
+BOOLEAN setOption(leftv res, leftv v)
+{
+  const char *n;
+  do
+  {
+    if (v->Typ()==STRING_CMD)
+    {
+      n=(const char *)v->CopyD(STRING_CMD);
+    }
+    else
+    {
+      if (v->name==NULL)
+        return TRUE;
+      if (v->rtyp==0)
+      {
+        n=v->name;
+        v->name=NULL;
+      }
+      else
+      {
+        n=omStrDup(v->name);
+      }
+    }
+
+    int i;
+
+    if(strcmp(n,"get")==0)
+    {
+      intvec *w=new intvec(2);
+      (*w)[0]=si_opt_1;
+      (*w)[1]=si_opt_2;
+      res->rtyp=INTVEC_CMD;
+      res->data=(void *)w;
+      goto okay;
+    }
+    if(strcmp(n,"set")==0)
+    {
+      if((v->next!=NULL)
+      &&(v->next->Typ()==INTVEC_CMD))
+      {
+        v=v->next;
+        intvec *w=(intvec*)v->Data();
+        si_opt_1=(*w)[0];
+        si_opt_2=(*w)[1];
+#if 0
+        if (TEST_OPT_INTSTRATEGY && (currRing!=NULL)
+        && rField_has_simple_inverse()
+#ifdef HAVE_RINGS
+        && !rField_is_Ring(currRing)
+#endif
+        ) {
+          si_opt_1 &=~Sy_bit(OPT_INTSTRATEGY);
+        }
+#endif
+        goto okay;
+      }
+    }
+    if(strcmp(n,"none")==0)
+    {
+      si_opt_1=0;
+      si_opt_2=0;
+      goto okay;
+    }
+    for (i=0; (i==0) || (optionStruct[i-1].setval!=0); i++)
+    {
+      if (strcmp(n,optionStruct[i].name)==0)
+      {
+        if (optionStruct[i].setval & validOpts)
+        {
+          si_opt_1 |= optionStruct[i].setval;
+          // optOldStd disables redthrough
+          if (optionStruct[i].setval == Sy_bit(OPT_OLDSTD))
+            si_opt_1 &= ~Sy_bit(OPT_REDTHROUGH);
+        }
+        else
+          Warn("cannot set option");
+#if 0
+        if (TEST_OPT_INTSTRATEGY && (currRing!=NULL)
+        && rField_has_simple_inverse()
+#ifdef HAVE_RINGS
+        && !rField_is_Ring(currRing)
+#endif
+        ) {
+          test &=~Sy_bit(OPT_INTSTRATEGY);
+        }
+#endif
+        goto okay;
+      }
+      else if ((strncmp(n,"no",2)==0)
+      && (strcmp(n+2,optionStruct[i].name)==0))
+      {
+        if (optionStruct[i].setval & validOpts)
+        {
+          si_opt_1 &= optionStruct[i].resetval;
+        }
+        else
+          Warn("cannot clear option");
+        goto okay;
+      }
+    }
+    for (i=0; (i==0) || (verboseStruct[i-1].setval!=0); i++)
+    {
+      if (strcmp(n,verboseStruct[i].name)==0)
+      {
+        si_opt_2 |= verboseStruct[i].setval;
+        #ifdef YYDEBUG
+        #if YYDEBUG
+        /*debugging the bison grammar --> grammar.cc*/
+        extern int    yydebug;
+        if (BVERBOSE(V_YACC)) yydebug=1;
+        else                  yydebug=0;
+        #endif
+        #endif
+        goto okay;
+      }
+      else if ((strncmp(n,"no",2)==0)
+      && (strcmp(n+2,verboseStruct[i].name)==0))
+      {
+        si_opt_2 &= verboseStruct[i].resetval;
+        #ifdef YYDEBUG
+        #if YYDEBUG
+        /*debugging the bison grammar --> grammar.cc*/
+        extern int    yydebug;
+        if (BVERBOSE(V_YACC)) yydebug=1;
+        else                  yydebug=0;
+        #endif
+        #endif
+        goto okay;
+      }
+    }
+    Werror("unknown option `%s`",n);
+  okay:
+    if (currRing != NULL)
+      currRing->options = si_opt_1 & TEST_RINGDEP_OPTS;
+    omFree((ADDRESS)n);
+    v=v->next;
+  } while (v!=NULL);
+
+#ifdef OM_SINGULAR_CONFIG_H
+   // set global variable to show memory usage
+  extern int om_sing_opt_show_mem;
+  if (BVERBOSE(V_SHOW_MEM)) om_sing_opt_show_mem = 1;
+  else om_sing_opt_show_mem = 0;
+#endif
+
+  return FALSE;
+}
+
+char * showOption()
+{
+  int i;
+  BITSET tmp;
+
+  StringSetS("//options:");
+  if ((si_opt_1!=0)||(si_opt_2!=0))
+  {
+    tmp=si_opt_1;
+    if(tmp)
+    {
+      for (i=0; optionStruct[i].setval!=0; i++)
+      {
+        if (optionStruct[i].setval & tmp)
+        {
+          StringAppend(" %s",optionStruct[i].name);
+          tmp &=optionStruct[i].resetval;
+        }
+      }
+      for (i=0; i<32; i++)
+      {
+        if (tmp & Sy_bit(i)) StringAppend(" %d",i);
+      }
+    }
+    tmp=si_opt_2;
+    if (tmp)
+    {
+      for (i=0; verboseStruct[i].setval!=0; i++)
+      {
+        if (verboseStruct[i].setval & tmp)
+        {
+          StringAppend(" %s",verboseStruct[i].name);
+          tmp &=verboseStruct[i].resetval;
+        }
+      }
+      for (i=1; i<32; i++)
+      {
+        if (tmp & Sy_bit(i)) StringAppend(" %d",i+32);
+      }
+    }
+    return StringEndS();
+  }
+  StringAppendS(" none");
+  return StringEndS();
+}
+
+/* version strings */
+#ifdef HAVE_FLINT
+extern "C"
+{
+#ifndef __GMP_BITS_PER_MP_LIMB
+#define __GMP_BITS_PER_MP_LIMB GMP_LIMB_BITS
+#endif
+#include <flint/flint.h>
+}
+#endif
+
+char * versionString(/*const bool bShowDetails = false*/ )
+{
+  StringSetS("");
+  StringAppend("Singular for %s version %s (%d, %d bit) %s #%s",
+               S_UNAME, VERSION, // SINGULAR_VERSION,
+               SINGULAR_VERSION, SIZEOF_VOIDP*8, singular_date, GIT_VERSION);
+  StringAppendS("\nwith\n\t");
+
+#if defined(mpir_version)
+              StringAppend("MPIR(%s)~GMP(%s),", mpir_version, gmp_version);
+#elif defined(gmp_version)
+              // #if defined (__GNU_MP_VERSION) && defined (__GNU_MP_VERSION_MINOR)
+              //              StringAppend("GMP(%d.%d),",__GNU_MP_VERSION,__GNU_MP_VERSION_MINOR);
+              StringAppend("GMP(%s),", gmp_version);
+#endif
+#ifdef HAVE_NTL
+#include <NTL/version.h>
+              StringAppend("NTL(%s),",NTL_VERSION);
+#endif
+
+#ifdef HAVE_FLINT
+              StringAppend("FLINT(%s),",version);
+#endif
+              StringAppend("factory(%s),\n\t", factoryVersion);
+#if defined(HAVE_DYN_RL)
+              if (fe_fgets_stdin==fe_fgets_dummy)
+                StringAppendS("no input,");
+              else if (fe_fgets_stdin==fe_fgets)
+                StringAppendS("fgets,");
+              if (fe_fgets_stdin==fe_fgets_stdin_drl)
+                StringAppendS("dynamic readline,");
+              #ifdef HAVE_FEREAD
+              else if (fe_fgets_stdin==fe_fgets_stdin_emu)
+                StringAppendS("emulated readline,");
+              #endif
+              else
+                StringAppendS("unknown fgets method,");
+#else
+  #if defined(HAVE_READLINE) && !defined(FEREAD)
+              StringAppendS("static readline,");
+  #else
+    #ifdef HAVE_FEREAD
+              StringAppendS("emulated readline,");
+    #else
+              StringAppendS("fgets,");
+    #endif
+  #endif
+#endif
+#ifdef HAVE_PLURAL
+              StringAppendS("Plural,");
+#endif
+#ifdef HAVE_DBM
+              StringAppendS("DBM,\n\t");
+#else
+              StringAppendS("\n\t");
+#endif
+#ifdef HAVE_DYNAMIC_LOADING
+              StringAppendS("dynamic modules,");
+#endif
+              if (p_procs_dynamic) StringAppendS("dynamic p_Procs,");
+#if YYDEBUG
+              StringAppendS("YYDEBUG=1,");
+#endif
+#ifdef HAVE_ASSUME
+             StringAppendS("ASSUME,");
+#endif
+#ifdef MDEBUG
+              StringAppend("MDEBUG=%d,",MDEBUG);
+#endif
+#ifdef OM_CHECK
+              StringAppend("OM_CHECK=%d,",OM_CHECK);
+#endif
+#ifdef OM_TRACK
+              StringAppend("OM_TRACK=%d,",OM_TRACK);
+#endif
+#ifdef OM_NDEBUG
+              StringAppendS("OM_NDEBUG,");
+#endif
+#ifdef SING_NDEBUG
+              StringAppendS("SING_NDEBUG,");
+#endif
+#ifdef PDEBUG
+              StringAppendS("PDEBUG,");
+#endif
+#ifdef KDEBUG
+              StringAppendS("KDEBUG,");
+#endif
+#ifdef __OPTIMIZE__
+              StringAppendS("CC:OPTIMIZE,");
+#endif
+#ifdef __OPTIMIZE_SIZE__
+              StringAppendS("CC:OPTIMIZE_SIZE,");
+#endif
+#ifdef __NO_INLINE__
+              StringAppendS("CC:NO_INLINE,");
+#endif
+#ifdef HAVE_EIGENVAL
+              StringAppendS("eigenvalues,");
+#endif
+#ifdef HAVE_GMS
+              StringAppendS("Gauss-Manin system,");
+#endif
+#ifdef HAVE_RATGRING
+              StringAppendS("ratGB,");
+#endif
+              StringAppend("random=%d\n",siRandomStart);
+
+#define SI_SHOW_BUILTIN_MODULE(name) StringAppend(" %s", #name);
+              StringAppendS("built-in modules: {");
+              SI_FOREACH_BUILTIN(SI_SHOW_BUILTIN_MODULE)
+              StringAppendS("}\n");
+#undef SI_SHOW_BUILTIN_MODULE
+
+              StringAppend("AC_CONFIGURE_ARGS = %s,\n"
+                           "CC = %s,FLAGS : %s,\n"
+                           "CXX = %s,FLAGS : %s,\n"
+                           "DEFS : %s,CPPFLAGS : %s,\n"
+                           "LDFLAGS : %s,LIBS : %s "
+#ifdef __GNUC__
+              "(ver: " __VERSION__ ")"
+#endif
+              "\n",AC_CONFIGURE_ARGS, CC,CFLAGS, CXX,CXXFLAGS,  DEFS,CPPFLAGS,  LDFLAGS,LIBS);
+              feStringAppendResources(0);
+              feStringAppendBrowsers(0);
+              StringAppendS("\n");
+              return StringEndS();
+}
+
+#ifdef PDEBUG
+#if (OM_TRACK > 2) && defined(OM_TRACK_CUSTOM)
+void p_SetRingOfLeftv(leftv l, ring r)
+{
+  switch(l->rtyp)
+  {
+    case INT_CMD:
+    case BIGINT_CMD:
+    case IDHDL:
+    case DEF_CMD:
+      break;
+    case POLY_CMD:
+    case VECTOR_CMD:
+    {
+      poly p=(poly)l->data;
+      while(p!=NULL) { p_SetRingOfLm(p,r); pIter(p); }
+      break;
+    }
+    case IDEAL_CMD:
+    case MODUL_CMD:
+    case MATRIX_CMD:
+    {
+      ideal I=(ideal)l->data;
+      int i;
+      for(i=IDELEMS(I)-1;i>=0;i--)
+      {
+        poly p=I->m[i];
+        while(p!=NULL) { p_SetRingOfLm(p,r); pIter(p); }
+      }
+      break;
+    }
+    case COMMAND:
+    {
+      command d=(command)l->data;
+      p_SetRingOfLeftv(&d->arg1, r);
+      if (d->argc>1) p_SetRingOfLeftv(&d->arg2, r);
+      if (d->argc>2) p_SetRingOfLeftv(&d->arg3, r);
+      break;
+    }
+    default:
+     printf("type %d not yet implementd in p_SetRingOfLeftv\n",l->rtyp);
+     break;
+  }
+}
+#endif
+#endif
+
+#if 0 /* debug only */
+void listall(int showproc)
+{
+      idhdl hh=basePack->idroot;
+      PrintS("====== Top ==============\n");
+      while (hh!=NULL)
+      {
+        if (showproc || (IDTYP(hh)!=PROC_CMD))
+        {
+          if (IDDATA(hh)==(void *)currRing) PrintS("(R)");
+          else if (IDDATA(hh)==(void *)currPack) PrintS("(P)");
+          else PrintS("   ");
+          Print("::%s, typ %s level %d data %lx",
+                 IDID(hh),Tok2Cmdname(IDTYP(hh)),IDLEV(hh),(long)IDDATA(hh));
+          if ((IDTYP(hh)==RING_CMD)
+          || (IDTYP(hh)==QRING_CMD))
+            Print(" ref: %d\n",IDRING(hh)->ref);
+          else
+            PrintLn();
+        }
+        hh=IDNEXT(hh);
+      }
+      hh=basePack->idroot;
+      while (hh!=NULL)
+      {
+        if (IDDATA(hh)==(void *)basePack)
+          Print("(T)::%s, typ %s level %d data %lx\n",
+          IDID(hh),Tok2Cmdname(IDTYP(hh)),IDLEV(hh),(long)IDDATA(hh));
+        else
+        if ((IDTYP(hh)==RING_CMD)
+        || (IDTYP(hh)==QRING_CMD)
+        || (IDTYP(hh)==PACKAGE_CMD))
+        {
+          Print("====== %s ==============\n",IDID(hh));
+          idhdl h2=IDRING(hh)->idroot;
+          while (h2!=NULL)
+          {
+            if (showproc || (IDTYP(h2)!=PROC_CMD))
+            {
+              if ((IDDATA(h2)==(void *)currRing)
+              && ((IDTYP(h2)==RING_CMD)||(IDTYP(h2)==QRING_CMD)))
+                PrintS("(R)");
+              else if (IDDATA(h2)==(void *)currPack) PrintS("(P)");
+              else PrintS("   ");
+              Print("%s::%s, typ %s level %d data %lx\n",
+              IDID(hh),IDID(h2),Tok2Cmdname(IDTYP(h2)),IDLEV(h2),(long)IDDATA(h2));
+            }
+            h2=IDNEXT(h2);
+          }
+        }
+        hh=IDNEXT(hh);
+      }
+      Print("currRing:%lx, currPack:%lx,basePack:%lx\n",(long)currRing,(long)currPack,(long)basePack);
+      iiCheckPack(currPack);
+}
+#endif
+
+#ifndef SING_NDEBUG
+void checkall()
+{
+      idhdl hh=basePack->idroot;
+      while (hh!=NULL)
+      {
+        omCheckAddr(hh);
+        omCheckAddr((ADDRESS)IDID(hh));
+        if (RingDependend(IDTYP(hh)))
+        {
+          Print("%s typ %d in Top (should be in ring)\n",IDID(hh),IDTYP(hh));
+        }
+        hh=IDNEXT(hh);
+      }
+      hh=basePack->idroot;
+      while (hh!=NULL)
+      {
+        if (IDTYP(hh)==PACKAGE_CMD)
+        {
+          idhdl h2=IDPACKAGE(hh)->idroot;
+          if (IDPACKAGE(hh)!=basePack)
+          {
+            while (h2!=NULL)
+            {
+              omCheckAddr(h2);
+              omCheckAddr((ADDRESS)IDID(h2));
+              if (RingDependend(IDTYP(h2)))
+              {
+                Print("%s typ %d in %s (should be in ring)\n",IDID(h2),IDTYP(h2),IDID(hh));
+              }
+              h2=IDNEXT(h2);
+            }
+          }
+        }
+        hh=IDNEXT(hh);
+      }
+}
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+extern "C"
+int singular_fstat(int fd, struct stat *buf)
+{
+  return si_fstat(fd,buf);
+}
+
+/*2
+* the global exit routine of Singular
+*/
+extern "C" {
+/* Note: We cannot use a mutex here because mutexes are not async-safe, but
+ * m2_end is called by sig_term_hdl(). Anyway, the race condition in the first
+ * few lines of m2_end() should not matter.
+ */
+volatile BOOLEAN m2_end_called = FALSE;
+
+void m2_end(int i)
+{
+  if (!m2_end_called)
+  {
+    m2_end_called = TRUE;
+#ifdef HAVE_SIMPLEIPC
+    for (int j = SIPC_MAX_SEMAPHORES; j >= 0; j--)
+    {
+      if (semaphore[j] != NULL)
+      {
+        while (sem_acquired[j] > 0)
+        {
+          sem_post(semaphore[j]);
+          sem_acquired[j]--;
+        }
+      }
+    }
+#endif   // HAVE_SIMPLEIPC
+    fe_reset_input_mode();
+#ifdef PAGE_TEST
+    mmEndStat();
+#endif
+    fe_reset_input_mode();
+    if (ssiToBeClosed_inactive)
+    {
+      link_list hh=ssiToBeClosed;
+      while(hh!=NULL)
+      {
+        //Print("close %s\n",hh->l->name);
+        slPrepClose(hh->l);
+        hh=(link_list)hh->next;
+      }
+      ssiToBeClosed_inactive=FALSE;
+
+      idhdl h = currPack->idroot;
+      while(h != NULL)
+      {
+        if(IDTYP(h) == LINK_CMD)
+        {
+          idhdl hh=h->next;
+          //Print("kill %s\n",IDID(h));
+          killhdl(h, currPack);
+          h = hh;
+        }
+        else
+        {
+          h = h->next;
+        }
+      }
+      hh=ssiToBeClosed;
+      while(hh!=NULL)
+      {
+        //Print("close %s\n",hh->l->name);
+        slClose(hh->l);
+        hh=ssiToBeClosed;
+      }
+    }
+    if (!singular_in_batchmode)
+    {
+      if (i<=0)
+      {
+        if (TEST_V_QUIET)
+        {
+          if (i==0)
+            printf("Auf Wiedersehen.\n");
+          else
+            printf("\n$Bye.\n");
+        }
+        //#ifdef sun
+        //  #ifndef __svr4__
+        //    _cleanup();
+        //    _exit(0);
+        //  #endif
+        //#endif
+        i=0;
+      }
+      else
+      {
+        printf("\nhalt %d\n",i);
+      }
+    }
+    exit(i);
+  }
+}
+}
+
+const char *singular_date=__DATE__ " " __TIME__;
+
+extern "C"
+{
+  void omSingOutOfMemoryFunc()
+  {
+    fprintf(stderr, "\nSingular error: no more memory\n");
+    omPrintStats(stderr);
+    m2_end(14);
+    /* should never get here */
+    exit(1);
+  }
+}
+
+#ifdef SINGULAR_4_1
+static n_coeffType n_pAE=n_unknown;
+static BOOLEAN ii_pAE_init(leftv res,leftv a)
+{
+  if (a->Typ()!=INT_CMD)
+  {
+    WerrorS("`int` expected");
+    return TRUE;
+  }
+  else
+  {
+    res->rtyp=CRING_CMD;
+    res->data=(void*)nInitChar(n_pAE,(void*)a->Data());
+    return FALSE;
+  }
+}
+#endif
+/*2
+* initialize components of Singular
+*/
+void siInit(char *name)
+{
+// factory default settings: -----------------------------------------------
+  On(SW_USE_EZGCD);
+  On(SW_USE_CHINREM_GCD);
+  //On(SW_USE_FF_MOD_GCD);
+  On(SW_USE_EZGCD_P);
+  On(SW_USE_QGCD);
+  Off(SW_USE_NTL_SORT); // may be changed by an command line option
+  factoryError=WerrorS;
+
+// memory initialization: -----------------------------------------------
+    om_Opts.OutOfMemoryFunc = omSingOutOfMemoryFunc;
+#ifndef OM_NDEBUG
+#ifndef __OPTIMIZE__
+    om_Opts.ErrorHook = dErrorBreak;
+#else
+    om_Opts.Keep = 0; /* !OM_NDEBUG, __OPTIMIZE__*/
+#endif
+#else
+    om_Opts.Keep = 0; /* OM_NDEBUG */
+#endif
+    omInitInfo();
+
+// interpreter tables etc.: -----------------------------------------------
+  memset(&sLastPrinted,0,sizeof(sleftv));
+  sLastPrinted.rtyp=NONE;
+
+  extern int iiInitArithmetic(); iiInitArithmetic(); // iparith.cc
+
+  basePack=(package)omAlloc0(sizeof(*basePack));
+  currPack=basePack;
+  idhdl h;
+  h=enterid("Top", 0, PACKAGE_CMD, &IDROOT, TRUE);
+  IDPACKAGE(h)->language = LANG_TOP;
+  IDPACKAGE(h)=basePack;
+  currPackHdl=h;
+  basePackHdl=h;
+
+  coeffs_BIGINT = nInitChar(n_Q,(void*)1);
+
+#if 1
+   // def HAVE_POLYEXTENSIONS
+  if(TRUE)
+  {
+    n_coeffType type = nRegister(n_algExt, naInitChar);
+    assume(type == n_algExt);
+
+    type = nRegister(n_transExt, ntInitChar);
+    assume(type == n_transExt);
+
+    (void)type;
+  }
+#endif
+
+// random generator: -----------------------------------------------
+  int t=initTimer();
+  if (t==0) t=1;
+  initRTimer();
+  siSeed=t;
+  factoryseed(t);
+  siRandomStart=t;
+  feOptSpec[FE_OPT_RANDOM].value = (void*) ((long)siRandomStart);
+
+// ressource table: ----------------------------------------------------
+  // Don't worry: ifdef OM_NDEBUG, then all these calls are undef'ed
+  // hack such that all shared' libs in the bindir are loaded correctly
+  feInitResources(name);
+
+// singular links: --------------------------------------------------
+  slStandardInit();
+  myynest=0;
+// semapohore 0 -----------------------------------------------------
+  int cpus=2;
+  int cpu_n;
+  #ifdef _SC_NPROCESSORS_ONLN
+  if ((cpu_n=sysconf(_SC_NPROCESSORS_ONLN))>cpus) cpus=cpu_n;
+  #elif defined(_SC_NPROCESSORS_CONF)
+  if ((cpu_n=sysconf(_SC_NPROCESSORS_CONF))>cpus) cpus=cpu_n;
+  #endif
+  feSetOptValue(FE_OPT_CPUS, cpus);
+
+#ifdef SINGULAR_4_1
+// default coeffs
+  {
+    idhdl h;
+    h=enterid(omStrDup("QQ"),0/*level*/, CRING_CMD,&(basePack->idroot),FALSE /*init*/,FALSE /*search*/);
+    IDDATA(h)=(char*)nInitChar(n_Q,NULL);
+    h=enterid(omStrDup("ZZ"),0/*level*/, CRING_CMD,&(basePack->idroot),FALSE /*init*/,FALSE /*search*/);
+    IDDATA(h)=(char*)nInitChar(n_Z,NULL);
+    //h=enterid(omStrDup("RR"),0/*level*/, CRING_CMD,&(basePack->idroot),FALSE /*init*/,FALSE /*search*/);
+    //IDDATA(h)=(char*)nInitChar(n_R,NULL);
+    //h=enterid(omStrDup("CC"),0/*level*/, CRING_CMD,&(basePack->idroot),FALSE /*init*/,FALSE /*search*/);
+    //IDDATA(h)=(char*)nInitChar(n_long_C,NULL);
+    n_coeffType t=nRegister(n_unknown,n_AEInitChar);
+    if (t!=n_unknown)
+    {
+      h=enterid(omStrDup("AE"),0/*level*/, CRING_CMD,&(basePack->idroot),FALSE /*init*/,FALSE /*search*/);
+      IDDATA(h)=(char*)nInitChar(t,NULL);
+    }
+    t=nRegister(n_unknown,n_QAEInitChar);
+    if (t!=n_unknown)
+    {
+      h=enterid(omStrDup("QAE"),0/*level*/, CRING_CMD,&(basePack->idroot),FALSE /*init*/,FALSE /*search*/);
+      IDDATA(h)=(char*)nInitChar(t,NULL);
+    }
+    n_pAE=nRegister(n_unknown,n_pAEInitChar);
+    if (n_pAE!=n_unknown)
+    {
+      iiAddCproc("kernel","pAE",FALSE,ii_pAE_init);
+    }
+  }
+#endif
+// loading standard.lib -----------------------------------------------
+  if (! feOptValue(FE_OPT_NO_STDLIB))
+  {
+    BITSET save1,save2;
+    SI_SAVE_OPT(save1,save2);
+    si_opt_2 &= ~Sy_bit(V_LOAD_LIB);
+    iiLibCmd(omStrDup("standard.lib"), TRUE,TRUE,TRUE);
+    SI_RESTORE_OPT(save1,save2);
+  }
+  errorreported = 0;
+}
diff --git a/Singular/misc_ip.h b/Singular/misc_ip.h
new file mode 100644
index 0000000..c6ad9e2
--- /dev/null
+++ b/Singular/misc_ip.h
@@ -0,0 +1,74 @@
+/*****************************************************************************\
+ * Computer Algebra System SINGULAR
+\*****************************************************************************/
+/** @file misc_ip.h
+ *
+ * This file provides miscellaneous functionality.
+ *
+ * ABSTRACT: This file provides the following miscellaneous functionality:
+ *           - prime factorisation of bigints with prime factors < 2^31
+ *            (This will require at most 256 MByte of RAM.)
+ *           - approximate square root of a bigint
+ *
+ *           Most of the functioanlity implemented here had earlier been
+ *           coded in SINGULAR in some library. Due to performance reasons
+ *           these algorithms have been moved to the C/C++ kernel.
+ *
+ * @author Frank Seelisch
+ *
+ *
+ **/
+/*****************************************************************************/
+
+#ifndef MISC_H
+#define MISC_H
+
+#include <misc/auxiliary.h>
+
+#include <coeffs/si_gmp.h>
+#include <coeffs/coeffs.h>
+
+#include <Singular/lists.h>
+
+/**
+ * Factorises a given bigint number n into its prime factors less
+ * than or equal to a given bound, with corresponding multiplicities.
+ *
+ * The method finds all prime factors with multiplicities. If a positive
+ * bound is given, then only the prime factors <= pBound are being found.
+ * In this case, there may remain an unfactored portion m of n.
+ * Also, when n is negative, m will contain the sign. If n is zero, m will
+ * be zero.
+ * The method returns a list L filled with three entries:
+ * L[1] a list; L[1][i] contains the i-th prime factor of |n| as int or
+ *                      bigint (sorted in ascending order),
+ * L[2] a list; L[2][i] contains the multiplicity of L[1, i] in |n| as int
+ * L[3] contains the remainder m as int or bigint, depending on the size,
+ *
+ * We thus have: n = L[1][1]^L[2][1] * ... * L[1][k]^L[2][k] * L[3], where
+ * k is the number of mutually distinct prime factors (<= a provided non-
+ * zero bound).
+ * Note that for n = 0, L[1] and L[2] will be emtpy lists and L[3] will be
+ * zero.
+ *
+ * @return the factorisation data in a SINGULAR-internal list
+ **/
+lists primeFactorisation(
+       const number n,     /**< [in]  the bigint > 0 to be factorised   */
+       const int pBound    /**< [in]  bound on the prime factors
+                                      seeked                            */
+                        );
+
+
+
+#ifdef PDEBUG
+#if (OM_TRACK > 2) && defined(OM_TRACK_CUSTOM)
+// #include <kernel/polys.h>
+/* Needed for debug Version of p_SetRingOfLeftv, Oliver */
+#include <kernel/structs.h>
+void p_SetRingOfLeftv(leftv l, ring r);
+#endif
+#endif
+
+#endif
+/* MISC_H */
diff --git a/Singular/mkinstalldirs b/Singular/mkinstalldirs
new file mode 100755
index 0000000..5b6d1ba
--- /dev/null
+++ b/Singular/mkinstalldirs
@@ -0,0 +1,32 @@
+#!/bin/sh
+# mkinstalldirs --- make directory hierarchy
+# Author: Noah Friedman <friedman at prep.ai.mit.edu>
+# Created: 1993-05-16
+# Last modified: 1994-03-25
+# Public domain
+
+errstatus=0
+
+for file in ${1+"$@"} ; do
+   set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
+   shift
+
+   pathcomp=
+   for d in ${1+"$@"} ; do
+     pathcomp="$pathcomp$d"
+     case "$pathcomp" in
+       -* ) pathcomp=./$pathcomp ;;
+     esac
+
+     if test ! -d "$pathcomp"; then
+        echo "mkdir $pathcomp" 1>&2
+        mkdir "$pathcomp" || errstatus=$?
+     fi
+
+     pathcomp="$pathcomp/"
+   done
+done
+
+exit $errstatus
+
+# mkinstalldirs ends here
diff --git a/Singular/mmalloc.cc b/Singular/mmalloc.cc
new file mode 100644
index 0000000..fb33338
--- /dev/null
+++ b/Singular/mmalloc.cc
@@ -0,0 +1,87 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: standard version of C++-memory management alloc func
+*/
+#include <kernel/mod2.h>
+
+#include <omalloc/omalloc.h>
+
+#include <new>
+#include <stdlib.h>
+
+/* We define those, so that our values of
+   OM_TRACK and OM_CHECK are used  */
+void* operator new ( size_t size )
+#ifndef __GNUC__
+throw (std::bad_alloc)
+#endif
+{
+  void* addr;
+  if (size==(size_t)0) size = 1;
+  omTypeAlloc(void*, addr, size);
+  return addr;
+}
+
+void operator delete ( void* block )
+#ifndef __GNUC__
+throw ()
+#endif
+{
+  omfree( block );
+}
+
+void* operator new[] ( size_t size )
+#ifndef __GNUC__
+throw (std::bad_alloc)
+#endif
+{
+  void* addr;
+  if (size==(size_t)0) size = (size_t)1;
+  omTypeAlloc(void*, addr, size);
+  return addr;
+}
+
+void operator delete[] ( void* block )
+#ifndef __GNUC__
+throw ()
+#endif
+{
+  omfree( block );
+}
+
+// The C++ standard has ratified a change to the new operator.
+//
+//  T *p = new T;
+//
+// Previously, if the call to new above failed, a null pointer would've been returned.
+// Under the ISO C++ Standard, an exception of type std::bad_alloc is thrown.
+// It is possible to suppress this behaviour in favour of the old style
+// by using the nothrow version.
+//
+//  T *p = new (std::nothrow) T;
+//
+// So we have to overload this new also, just to be sure.
+//
+// A further interesting question is, if you don't have enough resources
+// to allocate a request for memory,
+// do you expect to have enough to be able to deal with it?
+// Most operating systems will have slowed to be unusable
+// long before the exception gets thrown.
+
+void * operator new(size_t size, const std::nothrow_t &) throw()
+{
+  void* addr;
+  if (size==(size_t)0) size = (size_t)1;
+  omTypeAlloc(void*, addr, size);
+  return addr;
+}
+
+void * operator new[](size_t size, const std::nothrow_t &) throw()
+{
+  void* addr;
+  if (size==(size_t)0) size = (size_t)1;
+  omTypeAlloc(void*, addr, size);
+  return addr;
+}
diff --git a/Singular/mmalloc.h b/Singular/mmalloc.h
new file mode 100644
index 0000000..b3b44f2
--- /dev/null
+++ b/Singular/mmalloc.h
@@ -0,0 +1,24 @@
+#ifndef MMEMORY_H
+#define MMEMORY_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: declaration of routines for memory stuff
+*/
+
+#include <stdlib.h>
+
+#undef reallocSize
+#undef freeSize
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+  void* reallocSize(void* old_addr, size_t old_size, size_t new_size);
+  void  freeSize(void* addr, size_t size);
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/Singular/mmstd.c b/Singular/mmstd.c
new file mode 100644
index 0000000..40129db
--- /dev/null
+++ b/Singular/mmstd.c
@@ -0,0 +1,56 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: standard version of C-memory management alloc func
+* i.e. (malloc/realloc/free)
+*/
+
+
+
+
+#include <kernel/mod2.h>
+
+#include <omalloc/omalloc.h>
+
+/* we provide these functions, so that the settings of OM_CHECK
+* and OM_TRACK are used, but only provide them if omalloc is not based
+* on them
+* already provided in libomalloc */
+#if !defined(OMALLOC_USES_MALLOC) && !defined(X_OMALLOC)
+
+/* in mmstd.c, for some architectures freeSize() unconditionally uses the *system* free() */
+/* sage ticket 5344: http://trac.sagemath.org/sage_trac/ticket/5344 */
+/* solution: correctly check OMALLOC_USES_MALLOC from omalloc.h, */
+/* do not rely on the default in Singular as libsingular may be different */
+
+/* define this so that all addr allocated there are marked
+* as static, i.e. not metioned by omPrintUsedAddr*/
+#define OM_MALLOC_MARK_AS_STATIC
+#define strdup_ strdup__
+#include <omalloc/omalloc.c> /// UGLY!!!!!!!!!!!!!!!!
+
+#else
+#include <Singular/mmalloc.h>
+
+void freeSize(void* addr, size_t size)
+{
+  (void) size;
+  if (addr) free(addr);
+}
+
+void* reallocSize(void* old_addr, size_t old_size, size_t new_size)
+{
+  if (old_addr && new_size)
+  {
+   return realloc(old_addr, new_size);
+  }
+  else
+  {
+    freeSize(old_addr, old_size);
+    return malloc(new_size);
+  }
+}
+
+#endif
+
diff --git a/Singular/mod_lib.cc b/Singular/mod_lib.cc
new file mode 100644
index 0000000..c3d86f6
--- /dev/null
+++ b/Singular/mod_lib.cc
@@ -0,0 +1,121 @@
+#include <kernel/mod2.h>
+
+#include <resources/feFopen.h>
+#include <polys/mod_raw.h>
+
+#include <Singular/mod_lib.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <sys/stat.h>
+#include <errno.h>
+
+
+#define SI_BUILTIN_LIBSTR(name) (char*) #name ".so",
+
+const char * const si_builtin_libs[] = { SI_FOREACH_BUILTIN(SI_BUILTIN_LIBSTR) NULL };
+
+#undef SI_BUILTIN_LIBSTR
+
+#define BYTES_TO_CHECK 7
+
+lib_types type_of_LIB(const char *newlib, char *libnamebuf)
+{
+  const unsigned char mach_o[]={0xfe,0xed,0xfa,0xce,0};
+  const unsigned char mach_O[]={0xce,0xfa,0xed,0xfe,0};
+
+  const unsigned char mach_o64[]={0xfe,0xed,0xfa,0xcf,0};
+  const unsigned char mach_O64[]={0xcf,0xfa,0xed,0xfe,0};
+
+  const unsigned char mach_FAT[]={0xca,0xfe,0xba,0xbe,0};
+  const unsigned char mach_fat[]={0xbe,0xba,0xfe,0xca,0};
+
+  int i=0;
+  while(si_builtin_libs[i]!=NULL)
+  {
+    if (strcmp(newlib,si_builtin_libs[i])==0)
+    {
+      if(libnamebuf!=NULL) strcpy(libnamebuf,newlib);
+      return LT_BUILTIN;
+    }
+    i++;
+  }
+  char        buf[BYTES_TO_CHECK+1];        /* one extra for terminating '\0' */
+  struct stat sb;
+  int nbytes = 0;
+  int ret;
+  lib_types LT=LT_NONE;
+
+  FILE * fp = feFopen( newlib, "r", libnamebuf, FALSE );
+
+  do
+  {
+    ret = stat(libnamebuf, &sb);
+  } while((ret < 0) and (errno == EINTR));
+
+  if (fp==NULL)
+  {
+    return LT_NOTFOUND;
+  }
+  if((sb.st_mode & S_IFMT) != S_IFREG)
+  {
+    goto lib_type_end;
+  }
+  if ((nbytes = fread((char *)buf, sizeof(char), BYTES_TO_CHECK, fp)) == -1)
+  {
+    goto lib_type_end;
+    /*NOTREACHED*/
+  }
+  if (nbytes == 0)
+    goto lib_type_end;
+  else
+  {
+    buf[nbytes++] = '\0';        /* null-terminate it */
+  }
+  if( (strncmp(buf, "\177ELF", 4)==0)) /* generic ELF */
+  {
+    LT = LT_ELF;
+    //omFree(newlib);
+    //newlib = omStrDup(libnamebuf);
+    goto lib_type_end;
+  }
+
+  if( (strncmp(buf, (const char *)mach_o, 4)==0) || (strncmp(buf, (const char *)mach_O, 4)==0)) /* generic Mach-O module */
+  {
+    LT = LT_MACH_O;
+    //omFree(newlib);
+    //newlib = omStrDup(libnamebuf);
+    goto lib_type_end;
+  }
+
+  if( (strncmp(buf, (const char *)mach_o64, 4)==0) || (strncmp(buf, (const char *)mach_O64, 4)==0)) /* generic Mach-O 64-bit module */
+  {
+    LT = LT_MACH_O;
+    //omFree(newlib);
+    //newlib = omStrDup(libnamebuf);
+    goto lib_type_end;
+  }
+
+  if( (strncmp(buf, (const char *)mach_FAT, 4)==0) || (strncmp(buf, (const char *)mach_fat, 4)==0)) /* generic Mach-O fat universal module */
+  {
+    LT = LT_MACH_O;
+    //omFree(newlib);
+    //newlib = omStrDup(libnamebuf);
+    goto lib_type_end;
+  }
+
+  if( (strncmp(buf, "\02\020\01\016\05\022@", 7)==0))
+  {
+    LT = LT_HPUX;
+    //omFree(newlib);
+    //newlib = omStrDup(libnamebuf);
+    goto lib_type_end;
+  }
+  if(isprint(buf[0]) || buf[0]=='\n')
+  { LT = LT_SINGULAR; goto lib_type_end; }
+
+  lib_type_end:
+  fclose(fp);
+  return LT;
+}
diff --git a/Singular/mod_lib.h b/Singular/mod_lib.h
new file mode 100644
index 0000000..3a0d256
--- /dev/null
+++ b/Singular/mod_lib.h
@@ -0,0 +1,35 @@
+#ifndef MOD_LIB_H
+#define MOD_LIB_H
+
+#define SI_MOD_INIT0(name) name##_mod_init
+
+#ifdef STATIC_VERSION
+#  define SI_MOD_INIT(name) SI_MOD_INIT0(name)
+#elif defined(DYNAMIC_VERSION)
+#  define SI_MOD_INIT(name) mod_init
+#endif
+
+// Note that STATIC_VERSION and DYNAMIC_VERSION should not be defined in the following config header mod2.h!
+#include <kernel/mod2.h> /* for SI_BUILTINMODULES_ADD */
+
+/// Data for @c type_of_LIB to determine built-in modules,
+/// use @c add(name) to add built-in library to macro
+#define SI_FOREACH_BUILTIN(add) SI_BUILTINMODULES_ADD(add)
+
+#include <polys/mod_raw.h>  /* for lib_types */
+lib_types type_of_LIB(const char *newlib, char *fullname);
+
+#endif
+
+/*
+#if HAVE_GFANLIB
+#define SI_BUILTIN_GFANLIB(add) add(gfanlib)
+#endif
+#ifdef HAVE_MATHICGB
+# define SI_BUILTIN_MATHIC(add) add(singmathic)
+#endif
+#ifdef EMBED_PYTHON
+//TODO: the line above means that syzextra should be staticly embedded IFF pyobjects do so :(((((
+#define SI_BUILTIN_PYOBJECT(add) add(pyobject) add(syzextra) SI_BUILTIN_GFANLIB(add) SI_BUILTIN_MATHIC(add)
+#endif
+*/
diff --git a/Singular/newstruct.cc b/Singular/newstruct.cc
new file mode 100644
index 0000000..66244e2
--- /dev/null
+++ b/Singular/newstruct.cc
@@ -0,0 +1,877 @@
+#include <kernel/mod2.h>
+
+#include <Singular/ipid.h>
+#include <Singular/blackbox.h>
+#include <Singular/lists.h>
+#include <Singular/ipid.h>
+#include <Singular/ipshell.h>
+#include <Singular/newstruct.h>
+
+#include <ctype.h>
+
+struct newstruct_member_s;
+typedef struct newstruct_member_s *newstruct_member;
+struct  newstruct_member_s
+{
+  newstruct_member next;
+  char *         name;
+  int            typ;
+  int            pos;
+};
+
+struct newstruct_proc_s;
+typedef struct newstruct_proc_a *newstruct_proc;
+struct  newstruct_proc_a
+{
+  newstruct_proc next;
+  int            t; /*tok id */
+  int            args; /* number of args */
+  procinfov      p;
+};
+
+struct newstruct_desc_s
+{
+  newstruct_member member;
+  newstruct_desc   parent;
+  newstruct_proc   procs;
+  int            size; // number of mebers +1
+  int            id;   // the type id assigned to this bb
+};
+
+int newstruct_desc_size()
+{
+  return sizeof(newstruct_desc_s);
+}
+
+char * newstruct_String(blackbox *b, void *d)
+{
+  if (d==NULL) return omStrDup("oo");
+  else
+  {
+    newstruct_desc ad=(newstruct_desc)(b->data);
+
+    newstruct_proc p=ad->procs;
+    while((p!=NULL)&&(p->t!=STRING_CMD))
+      p=p->next;
+
+    if (p!=NULL)
+    {
+      BOOLEAN sl;
+      sleftv tmp;
+      memset(&tmp,0,sizeof(tmp));
+      tmp.rtyp=ad->id;
+      void * newstruct_Copy(blackbox*, void *); //forward declaration
+      tmp.data=(void*)newstruct_Copy(b,d);
+      idrec hh;
+      memset(&hh,0,sizeof(hh));
+      hh.id=Tok2Cmdname(p->t);
+      hh.typ=PROC_CMD;
+      hh.data.pinf=p->p;
+      sl=iiMake_proc(&hh,NULL,&tmp);
+
+      if ((!sl)&& (iiRETURNEXPR.Typ() == STRING_CMD))
+      {
+        char *res = omStrDup((char*)iiRETURNEXPR.CopyD());
+        iiRETURNEXPR.CleanUp();
+        iiRETURNEXPR.Init();
+        return res;
+      }
+      iiRETURNEXPR.CleanUp();
+      iiRETURNEXPR.Init();
+    }
+
+    lists l=(lists)d;
+    newstruct_member a=ad->member;
+    StringSetS("");
+    loop
+    {
+      StringAppendS(a->name);
+      StringAppendS("=");
+      if ((!RingDependend(a->typ))
+      || ((l->m[a->pos-1].data==(void *)currRing)
+         && (currRing!=NULL)))
+      {
+        if (l->m[a->pos].rtyp==LIST_CMD)
+        {
+          StringAppendS("<list>");
+        }
+        else
+        {
+          char *tmp2=omStrDup(l->m[a->pos].String());
+          if ((strlen(tmp2)>80)||(strchr(tmp2,'\n')!=NULL))
+          {
+            StringAppendS("<");
+            StringAppendS(Tok2Cmdname(l->m[a->pos].rtyp));
+            StringAppendS(">");
+          }
+          else StringAppendS(tmp2);
+          omFree(tmp2);
+        }
+      }
+      else StringAppendS("??");
+      if (a->next==NULL) break;
+      StringAppendS("\n");
+      if(errorreported) break;
+      a=a->next;
+    }
+    return StringEndS();
+  }
+}
+lists lCopy_newstruct(lists L)
+{
+  lists N=(lists)omAlloc0Bin(slists_bin);
+  int n=L->nr;
+  ring save_ring=currRing;
+  N->Init(n+1);
+  for(;n>=0;n--)
+  {
+    if (RingDependend(L->m[n].rtyp)
+    ||((L->m[n].rtyp==LIST_CMD)&&lRingDependend((lists)L->m[n].data)))
+    {
+      assume((L->m[n-1].rtyp==RING_CMD) || (L->m[n-1].data==NULL));
+      if(L->m[n-1].data!=NULL)
+      {
+        if (L->m[n-1].data!=(void*)currRing)
+          rChangeCurrRing((ring)(L->m[n-1].data));
+        N->m[n].Copy(&L->m[n]);
+      }
+      else
+      {
+        N->m[n].rtyp=L->m[n].rtyp;
+        N->m[n].data=idrecDataInit(L->m[n].rtyp);
+      }
+    }
+    else if(L->m[n].rtyp==LIST_CMD)
+    {
+      N->m[n].rtyp=L->m[n].rtyp;
+      N->m[n].data=(void *)lCopy((lists)(L->m[n].data));
+    }
+    else if(L->m[n].rtyp>MAX_TOK)
+    {
+      N->m[n].rtyp=L->m[n].rtyp;
+      blackbox *b=getBlackboxStuff(N->m[n].rtyp);
+      N->m[n].data=(void *)b->blackbox_Copy(b,L->m[n].data);
+    }
+    else
+      N->m[n].Copy(&L->m[n]);
+  }
+  if (currRing!=save_ring) rChangeCurrRing(save_ring);
+  return N;
+}
+void * newstruct_Copy(blackbox*, void *d)
+{
+  lists n1=(lists)d;
+  return (void*)lCopy_newstruct(n1);
+}
+
+// Used by newstruct_Assign for overloaded '='
+BOOLEAN newstruct_equal(int op, leftv l, leftv r)
+{
+  blackbox *ll=getBlackboxStuff(op);
+  assume(ll->data != NULL);
+  newstruct_desc nt=(newstruct_desc)ll->data;
+  newstruct_proc p=nt->procs;
+
+  while( (p!=NULL) && ((p->t!='=')||(p->args!=1)) ) p=p->next;
+
+  if (p!=NULL)
+  {
+    BOOLEAN sl;
+    idrec hh;
+    memset(&hh,0,sizeof(hh));
+    hh.id=Tok2Cmdname(p->t);
+    hh.typ=PROC_CMD;
+    hh.data.pinf=p->p;
+    sleftv tmp;
+    memset(&tmp,0,sizeof(sleftv));
+    tmp.Copy(r);
+    sl = iiMake_proc(&hh, NULL, &tmp);
+    if (!sl)
+    {
+      if (iiRETURNEXPR.Typ() == op)
+      {
+        l->Copy(&iiRETURNEXPR);
+        iiRETURNEXPR.Init();
+        return FALSE;
+      }
+      iiRETURNEXPR.CleanUp();
+      iiRETURNEXPR.Init();
+    }
+  }
+  return TRUE;
+}
+
+void lClean_newstruct(lists l)
+{
+  if (l->nr>=0)
+  {
+    int i;
+    ring r=NULL;
+    for(i=l->nr;i>=0;i--)
+    {
+      if ((i>0) && (l->m[i-1].rtyp==RING_CMD))
+        r=(ring)(l->m[i-1].data);
+      else
+        r=NULL;
+      l->m[i].CleanUp(r);
+    }
+    omFreeSize((ADDRESS)l->m, (l->nr+1)*sizeof(sleftv));
+    l->nr=-1;
+  }
+  omFreeBin((ADDRESS)l,slists_bin);
+}
+
+BOOLEAN newstruct_Assign(leftv l, leftv r)
+{
+  if (r->Typ()>MAX_TOK)
+  {
+    blackbox *rr=getBlackboxStuff(r->Typ());
+    if (l->Typ()!=r->Typ())
+    {
+      newstruct_desc rrn=(newstruct_desc)rr->data;
+
+      if (!rrn)
+      {
+        Werror("custom type %s(%d) cannot be assigned to newstruct %s(%d)",
+               Tok2Cmdname(r->Typ()), r->Typ(), Tok2Cmdname(l->Typ()), l->Typ());
+        return TRUE;
+      }
+
+      newstruct_desc rrp=rrn->parent;
+      while ((rrp!=NULL)&&(rrp->id!=l->Typ())) rrp=rrp->parent;
+      if (rrp!=NULL)
+      {
+        if (l->rtyp==IDHDL)
+        {
+          IDTYP((idhdl)l->data)=r->Typ();
+        }
+        else
+        {
+          l->rtyp=r->Typ();
+        }
+      }
+      else                      // unrelated types - look for custom conversion
+      {
+        sleftv tmp;
+        BOOLEAN newstruct_Op1(int, leftv, leftv);  // forward declaration
+        if (! newstruct_Op1(l->Typ(), &tmp, r))  return newstruct_Assign(l, &tmp);
+      }
+    }
+    if (l->Typ()==r->Typ())
+    {
+      if (l->Data()!=NULL)
+      {
+        lists n1=(lists)l->Data();
+        lClean_newstruct(n1);
+      }
+      lists n2=(lists)r->Data();
+      n2=lCopy_newstruct(n2);
+      r->CleanUp();
+      if (l->rtyp==IDHDL)
+      {
+        IDDATA((idhdl)l->data)=(char *)n2;
+      }
+      else
+      {
+        l->data=(void *)n2;
+      }
+      return FALSE;
+    }
+  }
+  else
+  {
+    assume(l->Typ() > MAX_TOK);
+    sleftv tmp;
+    if(!newstruct_equal(l->Typ(), &tmp, r)) return newstruct_Assign(l, &tmp);
+  }
+  Werror("assign %s(%d) = %s(%d)",
+        Tok2Cmdname(l->Typ()),l->Typ(),Tok2Cmdname(r->Typ()),r->Typ());
+  return TRUE;
+}
+
+BOOLEAN newstruct_Op1(int op, leftv res, leftv arg)
+{
+  // interpreter: arg is newstruct
+  blackbox *a=getBlackboxStuff(arg->Typ());
+  newstruct_desc nt=(newstruct_desc)a->data;
+  newstruct_proc p=nt->procs;
+
+  while((p!=NULL) &&( (p->t!=op) || (p->args!=1) )) p=p->next;
+
+  if (p!=NULL)
+  {
+    BOOLEAN sl;
+    sleftv tmp;
+    memset(&tmp,0,sizeof(sleftv));
+    tmp.Copy(arg);
+    idrec hh;
+    memset(&hh,0,sizeof(hh));
+    hh.id=Tok2Cmdname(p->t);
+    hh.typ=PROC_CMD;
+    hh.data.pinf=p->p;
+    sl=iiMake_proc(&hh,NULL,&tmp);
+    if (sl) return TRUE;
+    else
+    {
+      res->Copy(&iiRETURNEXPR);
+      iiRETURNEXPR.Init();
+      return FALSE;
+    }
+  }
+  return blackboxDefaultOp1(op,res,arg);
+}
+
+
+
+BOOLEAN newstruct_Op2(int op, leftv res, leftv a1, leftv a2)
+{
+  // interpreter: a1 or a2 is newstruct
+  blackbox *a=getBlackboxStuff(a1->Typ());
+  newstruct_desc nt;
+  lists al=(lists)a1->Data();
+  if (a!=NULL)
+  {
+    nt=(newstruct_desc)a->data;
+    switch(op)
+    {
+      case '.':
+      {
+        if (a2->name!=NULL)
+        {
+          BOOLEAN search_ring=FALSE;
+          newstruct_member nm=nt->member;
+          while ((nm!=NULL)&&(strcmp(nm->name,a2->name)!=0)) nm=nm->next;
+          if ((nm==NULL) && (strncmp(a2->name,"r_",2)==0))
+          {
+            nm=nt->member;
+            while ((nm!=NULL)&&(strcmp(nm->name,a2->name+2)!=0)) nm=nm->next;
+            if ((nm!=NULL)&&(RingDependend(nm->typ)))
+              search_ring=TRUE;
+            else
+              nm=NULL;
+          }
+          if (nm==NULL)
+          {
+            Werror("member %s not found", a2->name);
+            return TRUE;
+          }
+          if (search_ring)
+          {
+            ring r;
+            res->rtyp=RING_CMD;
+            res->data=al->m[nm->pos-1].data;
+            r=(ring)res->data;
+            if (r==NULL)
+            {
+              res->data=(void *)currRing; r=currRing;
+              if (r!=NULL) r->ref++;
+              else Werror("ring of this member is not set and no basering found");
+            }
+            return r==NULL;
+          }
+          else if (RingDependend(nm->typ)
+          || (al->m[nm->pos].RingDependend()))
+          {
+            if (al->m[nm->pos].data==NULL)
+            {
+              // NULL belongs to any ring
+              ring r=(ring)al->m[nm->pos-1].data;
+              if (r!=NULL)
+              {
+                r->ref--;
+                al->m[nm->pos-1].data=NULL;
+                al->m[nm->pos-1].rtyp=DEF_CMD;
+              }
+            }
+            else
+            {
+              //Print("checking ring at pos %d for dat at pos %d\n",nm->pos-1,nm->pos);
+              if ((al->m[nm->pos-1].data!=(void *)currRing)
+              &&(al->m[nm->pos-1].data!=(void*)0L))
+              {
+                Werror("different ring %lx(data) - %lx(basering)",
+                  (long unsigned)(al->m[nm->pos-1].data),(long unsigned)currRing);
+                Werror("name of basering: %s",IDID(currRingHdl));
+                rWrite(currRing,TRUE);PrintLn();
+                idhdl hh=rFindHdl((ring)(al->m[nm->pos-1].data),NULL);
+                const char *nn="??";
+                if (hh!=NULL) nn=IDID(hh);
+                Werror("(possible) name of ring of data: %s",nn);
+                rWrite((ring)(al->m[nm->pos-1].data),TRUE);PrintLn();
+
+                return TRUE;
+              }
+            }
+            if ((currRing!=NULL)&&(al->m[nm->pos-1].data==NULL))
+            {
+              // remember the ring, if not already set
+              al->m[nm->pos-1].data=(void *)currRing;
+              al->m[nm->pos-1].rtyp=RING_CMD;
+              currRing->ref++;
+            }
+          }
+          else if ((nm->typ==DEF_CMD)||(nm->typ==LIST_CMD))
+          {
+            if (al->m[nm->pos-1].data==NULL)
+            {
+              al->m[nm->pos-1].data=(void*)currRing;
+              if (currRing!=NULL) currRing->ref++;
+            }
+          }
+          Subexpr r=(Subexpr)omAlloc0Bin(sSubexpr_bin);
+          r->start = nm->pos+1;
+          memcpy(res,a1,sizeof(sleftv));
+          memset(a1,0,sizeof(sleftv));
+          if (res->e==NULL) res->e=r;
+          else
+          {
+            Subexpr sh=res->e;
+            while (sh->next != NULL) sh=sh->next;
+            sh->next=r;
+          }
+          return FALSE;
+        }
+        else
+        {
+          WerrorS("name expected");
+          return TRUE;
+        }
+      }
+    }
+  }
+  else
+  {
+    a=getBlackboxStuff(a2->Typ());
+    nt=(newstruct_desc)a->data;
+    al=(lists)a2->Data();
+  }
+  newstruct_proc p=nt->procs;
+  while((p!=NULL) && ( (p->t!=op) || (p->args!=2) )) p=p->next;
+  if (p!=NULL)
+  {
+    BOOLEAN sl;
+    sleftv tmp;
+    memset(&tmp,0,sizeof(sleftv));
+    tmp.Copy(a1);
+    tmp.next=(leftv)omAlloc0(sizeof(sleftv));
+    tmp.next->Copy(a2);
+    idrec hh;
+    memset(&hh,0,sizeof(hh));
+    hh.id=Tok2Cmdname(p->t);
+    hh.typ=PROC_CMD;
+    hh.data.pinf=p->p;
+    sl=iiMake_proc(&hh,NULL,&tmp);
+    if (sl) return TRUE;
+    else
+    {
+      res->Copy(&iiRETURNEXPR);
+      iiRETURNEXPR.Init();
+      return FALSE;
+    }
+  }
+  return blackboxDefaultOp2(op,res,a1,a2);
+}
+
+// BOOLEAN opM(int op, leftv res, leftv args)
+BOOLEAN newstruct_OpM(int op, leftv res, leftv args)
+{
+  // interpreter: args->1. arg is newstruct
+  blackbox *a=getBlackboxStuff(args->Typ());
+  newstruct_desc nt=(newstruct_desc)a->data;
+  switch(op)
+  {
+    case STRING_CMD:
+    {
+      res->data=(void *)a->blackbox_String(a,args->Data());
+      res->rtyp=STRING_CMD;
+      return FALSE;
+    }
+    default:
+      break;
+  }
+  newstruct_proc p=nt->procs;
+
+  while((p!=NULL) &&( (p->t!=op) || (p->args!=4) )) p=p->next;
+
+  if (p!=NULL)
+  {
+    BOOLEAN sl;
+    sleftv tmp;
+    memset(&tmp,0,sizeof(sleftv));
+    tmp.Copy(args);
+    idrec hh;
+    memset(&hh,0,sizeof(hh));
+    hh.id=Tok2Cmdname(p->t);
+    hh.typ=PROC_CMD;
+    hh.data.pinf=p->p;
+    sl=iiMake_proc(&hh,NULL,&tmp);
+    if (sl) return TRUE;
+    else
+    {
+      res->Copy(&iiRETURNEXPR);
+      iiRETURNEXPR.Init();
+      return FALSE;
+    }
+  }
+  return blackboxDefaultOpM(op,res,args);
+}
+
+void newstruct_destroy(blackbox */*b*/, void *d)
+{
+  if (d!=NULL)
+  {
+    lists n=(lists)d;
+    lClean_newstruct(n);
+  }
+}
+
+void *newstruct_Init(blackbox *b)
+{
+  newstruct_desc n=(newstruct_desc)b->data;
+  lists l=(lists)omAlloc0Bin(slists_bin);
+  l->Init(n->size);
+  newstruct_member nm=n->member;
+  while (nm!=NULL)
+  {
+    l->m[nm->pos].rtyp=nm->typ;
+    if (RingDependend(nm->typ) ||(nm->typ==DEF_CMD)||(nm->typ==LIST_CMD))
+      l->m[nm->pos-1].rtyp=RING_CMD;
+    l->m[nm->pos].data=idrecDataInit(nm->typ);
+    nm=nm->next;
+  }
+  return l;
+}
+
+BOOLEAN newstruct_CheckAssign(blackbox */*b*/, leftv L, leftv R)
+{
+  int lt=L->Typ();
+  int rt=R->Typ();
+  if ((lt!=DEF_CMD)&&(lt!=rt))
+  {
+    const char *rt1=Tok2Cmdname(rt);
+    const char *lt1=Tok2Cmdname(lt);
+    if ((rt>0) && (lt>0)
+    && ((strcmp(rt1,Tok2Cmdname(0))==0)||(strcmp(lt1,Tok2Cmdname(0))==0)))
+    {
+      Werror("can not assign %s(%d) to member of type %s(%d)",
+            rt1,rt,lt1,lt);
+    }
+    else
+    {
+      Werror("can not assign %s to member of type %s",rt1,lt1);
+    }
+    return TRUE;
+  }
+  return FALSE;
+}
+
+/* check internal structure:
+* BOOLEAN newstruct_Check(blackbox *b, void *d)
+{
+  newstruct_desc n=(newstruct_desc)b->data;
+  lists l=(lists)d;
+  newstruct_member nm=n->member;
+  while (nm!=NULL)
+  {
+    if ((l->m[nm->pos].rtyp!=nm->typ)
+    &&( nm->typ!=DEF_CMD))
+    {
+      Werror("type change in member %s (%s(%d) -> %s(%d))",nm->name,
+          Tok2Cmdname(nm->typ),nm->typ,
+          Tok2Cmdname(l->m[nm->pos].rtyp),l->m[nm->pos].rtyp);
+      return TRUE;
+    }
+    nm=nm->next;
+  }
+  return FALSE;
+}
+*/
+
+BOOLEAN newstruct_serialize(blackbox *b, void *d, si_link f)
+{
+  newstruct_desc dd=(newstruct_desc)b->data;
+  sleftv l;
+  memset(&l,0,sizeof(l));
+  l.rtyp=STRING_CMD;
+  l.data=(void*)getBlackboxName(dd->id);
+  f->m->Write(f, &l);
+  lists ll=(lists)d;
+  int Ll=lSize(ll);
+  l.rtyp=INT_CMD;
+  l.data=(void*)(long)Ll;
+  f->m->Write(f, &l);
+  // set all entries corresponding to "real" mebers to 1 in rings
+  char *rings=(char*)omAlloc0(Ll+1);
+  newstruct_member elem=dd->member;
+  while (elem!=NULL)
+  {
+    rings[elem->pos]='\1';
+    elem=elem->next;
+  }
+  int i;
+  BOOLEAN ring_changed=FALSE;
+  ring save_ring=currRing;
+  for(i=0;i<=Ll;i++)
+  {
+    if (rings[i]=='\0') // ring entry for pos i+1
+    {
+      if (ll->m[i].data!=NULL)
+      {
+        ring_changed=TRUE;
+        f->m->SetRing(f,(ring)ll->m[i].data,TRUE);
+      }
+    }
+    f->m->Write(f,&(ll->m[i]));
+  }
+  if (ring_changed)
+    f->m->SetRing(f,save_ring,FALSE);
+  return FALSE;
+}
+
+BOOLEAN newstruct_deserialize(blackbox **b, void **d, si_link f)
+{
+  // newstruct is serialiazed as analog to a list,
+  // just read a list and take data,
+  // rtyp must be set correctly (to the blackbox id) by routine calling
+  // newstruct_deserialize
+  leftv l=f->m->Read(f); // int: length of list
+  int Ll=(int)(long)(l->data);
+  omFree(l);
+  lists L=(lists)omAllocBin(slists_bin);
+  L->Init(Ll+1);
+  for(int i=0;i<=Ll;i++)
+  {
+    l=f->m->Read(f);
+    memcpy(&(L->m[i]),l,sizeof(sleftv));
+    omFree(l);
+  }
+  //newstruct_desc n=(newstruct_desc)b->data;
+  //TODO: check compatibility of list l->data with description in n
+  *d=L;
+  return FALSE;
+}
+
+void newstruct_Print(blackbox *b,void *d)
+{
+  newstruct_desc dd=(newstruct_desc)b->data;
+  newstruct_proc p=dd->procs;
+  while((p!=NULL)&&(p->t!=PRINT_CMD))
+    p=p->next;
+  if (p!=NULL)
+  {
+    BOOLEAN sl;
+    sleftv tmp;
+    memset(&tmp,0,sizeof(tmp));
+    tmp.rtyp=dd->id;
+    tmp.data=(void*)newstruct_Copy(b,d);
+    idrec hh;
+    memset(&hh,0,sizeof(hh));
+    hh.id=Tok2Cmdname(p->t);
+    hh.typ=PROC_CMD;
+    hh.data.pinf=p->p;
+    sl=iiMake_proc(&hh,NULL,&tmp);
+    if (!sl)
+    {
+      if (iiRETURNEXPR.Typ()!=NONE) Warn("ignoring return value (%s)",Tok2Cmdname(iiRETURNEXPR.Typ()));
+      iiRETURNEXPR.CleanUp();
+    }
+    iiRETURNEXPR.Init();
+  }
+  else
+    blackbox_default_Print(b,d);
+}
+void newstruct_setup(const char *n, newstruct_desc d )
+{
+  blackbox *b=(blackbox*)omAlloc0(sizeof(blackbox));
+  // all undefined entries will be set to default in setBlackboxStuff
+  // the default Print is quite useful,
+  // all other are simply error messages
+  b->blackbox_destroy=newstruct_destroy;
+  b->blackbox_String=newstruct_String;
+  b->blackbox_Print=newstruct_Print;//blackbox_default_Print;
+  b->blackbox_Init=newstruct_Init;
+  b->blackbox_Copy=newstruct_Copy;
+  b->blackbox_Assign=newstruct_Assign;
+  b->blackbox_Op1=newstruct_Op1;
+  b->blackbox_Op2=newstruct_Op2;
+  //b->blackbox_Op3=blackboxDefaultOp3;
+  b->blackbox_OpM=newstruct_OpM;
+  b->blackbox_CheckAssign=newstruct_CheckAssign;
+  b->blackbox_serialize=newstruct_serialize;
+  b->blackbox_deserialize=newstruct_deserialize;
+  b->data=d;
+  b->properties=1; // list_like
+  int rt=setBlackboxStuff(b,n);
+  d->id=rt;
+  //Print("create type %d (%s)\n",rt,n);
+}
+
+static newstruct_desc scanNewstructFromString(const char *s, newstruct_desc res)
+{
+  char *ss=omStrDup(s);
+  char *p=ss;
+  char *start;
+  int t;
+  char c;
+  newstruct_member elem;
+
+  idhdl save_ring=currRingHdl;
+  currRingHdl=(idhdl)1; // fake ring detection
+  loop
+  {
+    // read type:
+    while ((*p!='\0') && (*p<=' ')) p++;
+    start=p;
+    while (isalnum(*p)) p++;
+    *p='\0';
+    IsCmd(start,t);
+    if (t==0)
+    {
+      Werror("unknown type `%s`",start);
+      omFree(ss);
+      omFree(res);
+      currRingHdl=save_ring;
+      return NULL;
+    }
+    if (RingDependend(t) || (t==DEF_CMD)||(t==LIST_CMD))
+      res->size++;    // one additional field for the ring (before the data)
+    //Print("found type %s at real-pos %d",start,res->size);
+    elem=(newstruct_member)omAlloc0(sizeof(*elem));
+    // read name:
+    p++;
+    while ((*p!='\0') && (*p<=' ')) p++;
+    start=p;
+    while (isalnum(*p)) p++;
+    c=*p;
+    *p='\0';
+    elem->typ=t;
+    elem->pos=res->size;
+    if ((*start=='\0') /*empty name*/||(isdigit(*start)))
+    {
+      WerrorS("illegal/empty name for element");
+      goto error_in_newstruct_def;
+    }
+    elem->name=omStrDup(start);
+    //Print(" name:%s\n",start);
+    elem->next=res->member;
+    res->member=elem;
+    res->size++;
+
+    // next ?
+    *p=c;
+    while ((*p!='\0') && (*p<=' ')) p++;
+    if (*p!=',')
+    {
+      if (*p!='\0')
+      {
+        Werror("unknown character in newstruct:>>%s<<",p);
+        goto error_in_newstruct_def;
+      }
+      break; // end-of-list
+    }
+    p++;
+  }
+  omFree(ss);
+  currRingHdl=save_ring;
+  //Print("new type with %d elements\n",res->size);
+  //newstructShow(res);
+  return res;
+error_in_newstruct_def:
+   omFree(elem);
+   omFree(ss);
+   omFree(res);
+   currRingHdl=save_ring;
+   return NULL;
+}
+newstruct_desc newstructFromString(const char *s)
+{
+  newstruct_desc res=(newstruct_desc)omAlloc0(sizeof(*res));
+  res->size=0;
+
+  return scanNewstructFromString(s,res);
+}
+newstruct_desc newstructChildFromString(const char *parent, const char *s)
+{
+  // find parent:
+  int parent_id=0;
+  blackboxIsCmd(parent,parent_id);
+  if (parent_id<MAX_TOK)
+  {
+    Werror(">>%s< not found",parent);
+    return NULL;
+  }
+  blackbox *parent_bb=getBlackboxStuff(parent_id);
+  // check for the correct type:
+  if (parent_bb->blackbox_destroy!=newstruct_destroy)
+  {
+    Werror(">>%s< is not a user defined type",parent);
+    return NULL;
+  }
+  // setup for scanNewstructFromString:
+  newstruct_desc res=(newstruct_desc)omAlloc0(sizeof(*res));
+  newstruct_desc parent_desc=(newstruct_desc)parent_bb->data;
+  res->size=parent_desc->size;
+  res->member=parent_desc->member;
+  res->parent=parent_desc;
+
+  return scanNewstructFromString(s,res);
+}
+
+void newstructShow(newstruct_desc d)
+{
+  newstruct_member elem;
+  Print("id: %d\n",d->id);
+  elem=d->member;
+  while (elem!=NULL)
+  {
+    Print(">>%s<< at pos %d, type %d (%s)\n",elem->name,elem->pos,elem->typ,Tok2Cmdname(elem->typ));
+    if (RingDependend(elem->typ)|| (elem->typ==DEF_CMD) ||(elem->typ==LIST_CMD))
+      Print(">>r_%s<< at pos %d, shadow ring\n",elem->name,elem->pos-1);
+    elem=elem->next;
+  }
+  newstruct_proc p=d->procs;
+  while (p!=NULL)
+  {
+    Print("op:%d(%s) with %d args -> %s\n",p->t,iiTwoOps(p->t),p->args,p->p->procname);
+    p=p->next;
+  }
+}
+
+BOOLEAN newstruct_set_proc(const char *bbname,const char *func, int args,procinfov pr)
+{
+  int id=0;
+  blackboxIsCmd(bbname,id);
+  if (id<MAX_TOK)
+  {
+    Werror(">>%s<< is not a newstruct type",bbname);
+    return TRUE;
+  }
+  blackbox *bb=getBlackboxStuff(id);
+  newstruct_desc desc=(newstruct_desc)bb->data;
+  newstruct_proc p=(newstruct_proc)omAlloc(sizeof(*p));
+  p->next=desc->procs; desc->procs=p;
+
+  idhdl save_ring=currRingHdl;
+  currRingHdl=(idhdl)1; // fake ring detection
+
+  if(!IsCmd(func,p->t))
+  {
+    int t=0;
+    if (func[1]=='\0') p->t=func[0];
+    else if((t=iiOpsTwoChar(func))!=0)
+    {
+      p->t=t;
+    }
+    else
+    {
+      Werror(">>%s<< is not a kernel command",func);
+      currRingHdl = save_ring;
+      return TRUE;
+    }
+  }
+  p->args=args;
+  p->p=pr; pr->ref++;
+  pr->is_static=0;
+  currRingHdl = save_ring;
+  return FALSE;
+}
diff --git a/Singular/newstruct.h b/Singular/newstruct.h
new file mode 100644
index 0000000..41d208f
--- /dev/null
+++ b/Singular/newstruct.h
@@ -0,0 +1,13 @@
+#ifndef NEWTYPES_H
+#define NEWTYPES_H
+
+typedef struct newstruct_desc_s *newstruct_desc;
+
+void newstruct_setup(const char * name, newstruct_desc d);
+int newstruct_desc_size();
+newstruct_desc newstructFromString(const char *s);
+newstruct_desc newstructChildFromString(const char *p, const char *s);
+BOOLEAN newstruct_set_proc(const char *name,const char *func,int args, procinfov p);
+void newstructShow(newstruct_desc d);
+
+#endif
diff --git a/Singular/number2.cc b/Singular/number2.cc
new file mode 100644
index 0000000..0a2ffea
--- /dev/null
+++ b/Singular/number2.cc
@@ -0,0 +1,336 @@
+#include "kernel/mod2.h" // general settings/macros
+
+#ifdef SINGULAR_4_1
+#include <reporter/reporter.h>  // for Print, WerrorS
+#include <coeffs/numbers.h> // nRegister, coeffs.h
+#include <coeffs/rmodulon.h> // ZnmInfo
+#include <coeffs/bigintmat.h> // bigintmat
+#include <coeffs/longrat.h> // BIGINTs: nlGMP
+
+#include <Singular/blackbox.h> // blackbox type
+#include <Singular/ipshell.h> // IsPrime
+
+#include <Singular/ipid.h> // for SModulFunctions, leftv
+
+#include <Singular/number2.h>
+
+char *crString(coeffs c)
+{
+  if (c==NULL)
+  {
+    return omStrDup("oo");
+  }
+  return omStrDup(nCoeffName(c));
+}
+void crPrint(coeffs c)
+{
+  char *s=crString(c);
+  PrintS(s);
+  omFree(s);
+}
+
+// -----------------------------------------------------------
+// interpreter stuff for cring/coeffs
+// -----------------------------------------------------------
+BOOLEAN jjCRING_Zp(leftv res, leftv a, leftv b)
+{
+  coeffs c1=(coeffs)a->Data();
+  int    i2=(int)(long)b->Data();
+  if (c1->type==n_Z)
+  {
+    if (i2==IsPrime(i2))
+    {
+      res->data=(void *)nInitChar(n_Zp,(void*)(long)i2);
+    }
+    else
+    {
+      ZnmInfo info;
+      mpz_ptr modBase= (mpz_ptr) omAlloc(sizeof(mpz_t));
+      mpz_init_set_ui(modBase,i2);
+      info.base= modBase;
+      info.exp= 1;
+      res->data=(void *)nInitChar(n_Zn,&info);
+    }
+    return FALSE;
+  }
+  return TRUE;
+}
+BOOLEAN jjCRING_Zm(leftv res, leftv a, leftv b)
+{
+  coeffs c1=(coeffs)a->Data();
+  number i2=(number)b->Data();
+  if (c1->type==n_Z)
+  {
+    ZnmInfo info;
+    number modBase= (number) omAlloc(sizeof(mpz_t));
+    nlGMP(i2,modBase,coeffs_BIGINT); // FIXME? TODO? // extern void   nlGMP(number &i, number n, const coeffs r); // to be replaced with n_MPZ(modBase,i2,coeffs_BIGINT); // ?
+    info.base= (mpz_ptr)modBase;
+    info.exp= 1;
+    res->data=(void *)nInitChar(n_Zn,&info);
+    return FALSE;
+  }
+  return TRUE;
+}
+
+// -----------------------------------------------------------
+// interpreter stuff for Number/number2
+// -----------------------------------------------------------
+BOOLEAN jjNUMBER2_OP2(leftv res, leftv a, leftv b)
+{
+  int op=iiOp;
+  // binary operations for number2
+  number2 a2=NULL;
+  number aa=NULL;
+  number2 b2=NULL;
+  number bb=NULL;
+  if (a->Typ()==CNUMBER_CMD)
+  {
+    a2=(number2)a->Data();
+    aa=a2->n;
+  }
+  if (b->Typ()==CNUMBER_CMD)
+  {
+    b2=(number2)b->Data();
+    if ((a2!=NULL) && (a2->cf!=b2->cf))
+    {
+      WerrorS("Number not compatible");
+      return TRUE;
+    }
+    bb=b2->n;
+  }
+  number2 r=(number2)omAlloc(sizeof(*r));
+  if (a2!=NULL) r->cf=a2->cf;
+  else          r->cf=b2->cf;
+  if (r->cf==NULL) op=0; // force error
+  else
+  if (a2==NULL)
+  {
+    if (a->Typ()==INT_CMD) aa=n_Init((long)a->Data(),r->cf);
+    else if (a->Typ()==BIGINT_CMD)
+    {
+      //aa=n_Init_bigint((number)a->Data(),coeffs_BIGINT,r->cf);
+      nMapFunc nMap=n_SetMap(coeffs_BIGINT,r->cf);
+      aa=nMap((number)a->Data(),coeffs_BIGINT,r->cf);
+    }
+    else op=0;
+  }
+  if ((b2==NULL) &&(op!='^') &&(op!=0))
+  {
+    if (b->Typ()==INT_CMD) bb=n_Init((long)b->Data(),r->cf);
+    else if (b->Typ()==BIGINT_CMD)
+    {
+      //bb=n_Init_bigint((number)b->Data(),coeffs_BIGINT,r->cf);
+      nMapFunc nMap=n_SetMap(coeffs_BIGINT,r->cf);
+      bb=nMap((number)b->Data(),coeffs_BIGINT,r->cf);
+    }
+    else op=0;
+  }
+  switch(op)
+  {
+    case '+': r->n=n_Add(aa,bb,r->cf);break;
+    case '-': r->n=n_Sub(aa,bb,r->cf);break;
+    case '*': r->n=n_Mult(aa,bb,r->cf);break;
+    case '/': r->n=n_Div(aa,bb,r->cf);break;
+    case '%': r->n=n_IntMod(aa,bb,r->cf);break;
+
+    case '^': n_Power(aa,(int)(long)b->Data(),&(r->n),r->cf); break;
+
+    default: Werror("unknown binary operation %s(%d)",Tok2Cmdname(op),op);
+             omFree(r);
+             return TRUE;
+  }
+  res->data=(void*)r;
+  r->cf->ref++;
+  return FALSE;
+}
+BOOLEAN jjNUMBER2_OP1(leftv res, leftv a)
+{
+  int op=iiOp;
+  // unary operations for number2
+  number2 a2=(number2)a->Data();
+  number2 r=(number2)omAlloc(sizeof(*r));
+  r->cf=a2->cf;
+  if (a2->cf==NULL) op=0; // force error
+  switch(op)
+  {
+    case '-': r->n=n_Copy(a2->n,a2->cf);r->n=n_InpNeg(r->n,a2->cf);break;
+    default: Werror("unknown unary operation %s(%d)",Tok2Cmdname(op),op);
+             omFree(r);
+             return TRUE;
+  }
+  res->data=(void*)r;
+  r->cf->ref++;
+  return FALSE;
+}
+
+BOOLEAN jjNUMBER2CR(leftv res, leftv a, leftv b)
+{
+  number2 r=(number2)omAlloc(sizeof(*r));
+  r->cf=(coeffs)b->CopyD();
+  BOOLEAN bo=FALSE;
+  switch(a->Typ())
+  {
+    case INT_CMD:
+      r->n=n_Init((long)a->Data(),r->cf); break;
+    case BIGINT_CMD:
+    {
+      nMapFunc nMap=n_SetMap(coeffs_BIGINT,r->cf);
+      r->n=nMap((number)a->Data(),coeffs_BIGINT,r->cf); break;
+    }
+    case NUMBER_CMD:
+    {
+      nMapFunc nMap=n_SetMap(currRing->cf,r->cf);
+      if (nMap!=NULL)
+        r->n=nMap((number)a->Data(),currRing->cf,r->cf);
+      else
+        bo=TRUE;
+      break;
+    }
+    case CNUMBER_CMD:
+    {
+      number2 a2=(number2)a->Data();
+      if (a2->cf==NULL) bo=TRUE;
+      else
+      {
+        nMapFunc nMap=n_SetMap(a2->cf,r->cf);
+        if (nMap!=NULL)
+          r->n=nMap(a2->n,a2->cf,r->cf);
+        else
+          bo=TRUE;
+      }
+      break;
+    }
+    default: bo=TRUE; break;
+  }
+  if (bo)
+  {
+    Werror("no conversion to Number from %s",Tok2Cmdname(a->Typ()));
+    omFreeSize(r,sizeof(*r));
+  }
+  else
+    res->data=(void*)r;
+  return bo;
+}
+
+BOOLEAN jjN2_CR(leftv res, leftv a)              // number2 ->cring
+{
+  number2 n=(number2)a->Data();
+  n->cf->ref++;
+  res->data=(void*)n->cf;
+  return FALSE;
+}
+
+BOOLEAN jjCM_CR(leftv res, leftv a)              // cmatrix ->cring
+{
+  bigintmat *b=(bigintmat*)a->Data();
+  coeffs cf=b->basecoeffs();
+  if (cf!=NULL)
+  {
+    cf->ref++;
+  }
+  res->data=(void*)cf;
+  return FALSE;
+}
+
+BOOLEAN jjCMATRIX_3(leftv res, leftv r, leftv c,leftv cf)
+{
+  bigintmat *b=new bigintmat((int)(long)r->Data(),
+                             (int)(long)c->Data(),
+                             (coeffs)cf->Data());
+  res->data=(char*)b;
+  return FALSE;
+}
+
+BOOLEAN jjN2_N(leftv res, leftv a)              // number2 ->number
+{
+  number2 n2=(number2)a->Data();
+  BOOLEAN bo=TRUE;
+  if (currRing!=NULL)
+  {
+    nMapFunc nMap=n_SetMap(n2->cf,currRing->cf);
+    if (nMap!=NULL)
+    {
+      res->data=(void*)nMap(n2->n,n2->cf,currRing->cf);
+      bo=FALSE;
+    }
+  }
+  return bo;
+}
+
+BOOLEAN jjEQUAL_CR(leftv res, leftv a, leftv b)
+{
+  coeffs a2=(coeffs)a->Data();
+  coeffs b2=(coeffs)b->Data();
+  res->data=(void*)(long)(a2==b2);
+  return FALSE;
+}
+// -----------------------------------------------------------
+// operations with Number/number2
+// -----------------------------------------------------------
+number2 n2Copy(const number2 d)
+{
+  number2 r=NULL;
+  if ((d!=NULL)&&(d->cf!=NULL))
+  {
+    r=(number2)omAlloc(sizeof(*r));
+    d->cf->ref++;
+    r->cf=d->cf;
+    if (d->cf!=NULL)
+      r->n=n_Copy(d->n,d->cf);
+    else
+      r->n=NULL;
+  }
+  return r;
+}
+void n2Delete(number2 &d)
+{
+  if (d!=NULL)
+  {
+    if (d->cf!=NULL)
+    {
+      n_Delete(&d->n,d->cf);
+      nKillChar(d->cf);
+    }
+    omFreeSize(d,sizeof(*d));
+    d=NULL;
+  }
+}
+char *n2String(number2 d, BOOLEAN typed)
+{
+  StringSetS("");
+  if ((d!=NULL) && (d->cf!=NULL))
+  {
+    if (typed) StringAppendS("Number(");
+    n_Write(d->n,d->cf);
+    if (typed) StringAppendS(")");
+  }
+  else StringAppendS("oo");
+  return StringEndS();
+}
+
+void n2Print(number2 d)
+{
+  char *s=n2String(d,FALSE);
+  PrintS(s);
+  omFree(s);
+}
+
+#include <coeffs/bigintmat.h>
+BOOLEAN jjBIM2_CR(leftv res, leftv a)              // bigintmat ->cring
+{
+  bigintmat *b=(bigintmat*)a->Data();
+  coeffs cf=b->basecoeffs();
+  cf->ref++;
+  res->data=(void*)cf;
+  return FALSE;
+}
+
+BOOLEAN jjR2_CR(leftv res, leftv a)              // ring ->cring
+{
+  ring r=(ring)a->Data();
+  coeffs cf=r->cf;
+  cf->ref++;
+  res->data=(void*)cf;
+  return FALSE;
+}
+#endif
diff --git a/Singular/number2.h b/Singular/number2.h
new file mode 100644
index 0000000..59fca9f
--- /dev/null
+++ b/Singular/number2.h
@@ -0,0 +1,48 @@
+#ifndef NUMBER2_H
+#define NUMBER2_H
+
+#include <libpolys/misc/auxiliary.h>
+
+#ifdef SINGULAR_4_1
+#include <omalloc/omalloc.h>
+#include <coeffs/coeffs.h>
+#include <kernel/structs.h>
+struct snumber2;
+typedef struct snumber2 *   number2;
+struct snumber2
+{ coeffs cf;
+  number n;
+};
+
+static inline number2 n2Init(long i, coeffs c)
+{ number2 N=(number2)omAlloc0(sizeof(snumber2)); if (c!=NULL) { N->cf=c; N->n=n_Init(i,c);} return N;}
+
+char *crString(coeffs c);
+
+void crPrint(coeffs cf);
+
+BOOLEAN jjCRING_Zp(leftv res, leftv a, leftv b);
+BOOLEAN jjCRING_Zm(leftv res, leftv a, leftv b);
+
+BOOLEAN jjEQUAL_CR(leftv res, leftv a, leftv b); // compare cring
+
+// type conversion:
+BOOLEAN jjNUMBER2CR(leftv res, leftv a, leftv b); // <any>,cring ->number2
+BOOLEAN jjN2_CR(leftv res, leftv a);              // number2 ->cring
+BOOLEAN jjCM_CR(leftv res, leftv a);              // cmatrix ->cring
+BOOLEAN jjBIM2_CR(leftv res, leftv a);              // bigint ->cring
+BOOLEAN jjR2_CR(leftv res, leftv a);              // ring ->cring
+BOOLEAN jjN2_N(leftv res, leftv a);             // number2 ->number
+
+// operations:
+BOOLEAN jjNUMBER2_OP1(leftv res, leftv a);
+BOOLEAN jjNUMBER2_OP2(leftv res, leftv a, leftv b);
+
+number2 n2Copy(const number2 d);
+void n2Delete(number2 &d);
+char *n2String(number2 d, BOOLEAN typed);
+void n2Print(number2 d);
+
+BOOLEAN jjCMATRIX_3(leftv, leftv, leftv,leftv);
+#endif
+#endif
diff --git a/Singular/omSingularConfig.h b/Singular/omSingularConfig.h
new file mode 100644
index 0000000..5ff798e
--- /dev/null
+++ b/Singular/omSingularConfig.h
@@ -0,0 +1,61 @@
+/*******************************************************************
+ *  File:    omSingularConfig.h
+ *  Purpose: declaration of External Config stuff for omalloc
+ *           This file is inlcuded by omDefaultConfig.h, i.e., at the the time
+ *           the omalloc library is built. Any changes to the default config
+ *           of omalloc should be done here (and, of course, you need to
+ *           rebuilt the library).
+ *  Author:  obachman at mathematik.uni-kl.de (Olaf Bachmann)
+ *  Created: 8/00
+ *******************************************************************/
+#ifndef OM_SINGULAR_CONFIG_H
+#define OM_SINGULAR_CONFIG_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#define OM_MALLOC_HOOK(size)                OM_SINGULAR_HOOK
+#define OM_FREE_HOOK(size)                  OM_SINGULAR_HOOK
+#define OM_ALLOC_BINPAGE_HOOK               OM_SINGULAR_HOOK
+#define OM_FREE_BINPAGE_HOOK                OM_SINGULAR_HOOK
+
+#ifdef OM_ALLOC_SYSTEM_C
+int om_sing_opt_show_mem = 0;
+size_t om_sing_last_reported_size = 0;
+#else
+extern int om_sing_opt_show_mem;
+extern size_t om_sing_last_reported_size;
+#endif
+
+/* number of bytes for difference to report: every 1 MByte */
+#define SING_REPORT_THRESHOLD 1000*1024
+#define OM_SINGULAR_HOOK                                                        \
+do                                                                            \
+{                                                                             \
+  if (om_sing_opt_show_mem)                                                   \
+  {                                                                           \
+    size_t _current_bytes = om_Info.CurrentBytesFromMalloc +                  \
+                            (om_Info.UsedPages << LOG_BIT_SIZEOF_SYSTEM_PAGE);\
+    size_t _diff = (_current_bytes > om_sing_last_reported_size ?             \
+                   _current_bytes - om_sing_last_reported_size :              \
+                   om_sing_last_reported_size - _current_bytes);              \
+    if (_diff >= SING_REPORT_THRESHOLD)                                       \
+    {                                                                         \
+      fprintf(stdout, "[%ldk]", (long)(_current_bytes + 1023)/1024);                \
+      fflush(stdout);                                                         \
+      om_sing_last_reported_size = _current_bytes;                            \
+    }                                                                         \
+  }                                                                           \
+}                                                                             \
+while (0)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* OM_SINGULAR_CONFIG_H */
diff --git a/Singular/pcv.cc b/Singular/pcv.cc
new file mode 100644
index 0000000..9c0bfad
--- /dev/null
+++ b/Singular/pcv.cc
@@ -0,0 +1,444 @@
+/*****************************************
+*  Computer Algebra System SINGULAR      *
+*****************************************/
+/*
+* ABSTRACT: conversion between polys and coef vectors
+*/
+
+
+
+
+#include <kernel/mod2.h>
+
+#ifdef HAVE_PCV
+
+#include <Singular/tok.h>
+#include <Singular/ipid.h>
+#include <coeffs/numbers.h>
+#include <kernel/polys.h>
+#include <kernel/ideals.h>
+#include <Singular/lists.h>
+#include <polys/matpol.h>
+#include <Singular/ipshell.h>
+#include <Singular/pcv.h>
+
+static int pcvMaxDegree;
+static int pcvTableSize;
+static int pcvIndexSize;
+static unsigned* pcvTable=NULL;
+static unsigned** pcvIndex=NULL;
+
+lists pcvLAddL(lists l1,lists l2)
+{
+  lists l0=(lists)omAllocBin(slists_bin);
+  int i=l1->nr;
+  if(l1->nr<l2->nr) i=l2->nr;
+  l0->Init(i+1);
+  for(;i>=0;i--)
+  {
+    if(i<=l1->nr&&(l1->m[i].rtyp==POLY_CMD||l1->m[i].rtyp==VECTOR_CMD))
+    {
+      l0->m[i].rtyp=l1->m[i].rtyp;
+      l0->m[i].data=pCopy((poly)l1->m[i].data);
+      if(i<=l2->nr&&l2->m[i].rtyp==l1->m[i].rtyp)
+        l0->m[i].data=pAdd((poly)l0->m[i].data,pCopy((poly)l2->m[i].data));
+    }
+    else
+    if(i<=l2->nr&&(l2->m[i].rtyp==POLY_CMD||l2->m[i].rtyp==VECTOR_CMD))
+    {
+      l0->m[i].rtyp=l2->m[i].rtyp;
+      l0->m[i].data=pCopy((poly)l2->m[i].data);
+    }
+  }
+  return(l0);
+}
+
+lists pcvPMulL(poly p,lists l1)
+{
+  lists l0=(lists)omAllocBin(slists_bin);
+  l0->Init(l1->nr+1);
+  for(int i=l1->nr;i>=0;i--)
+  {
+    if(l1->m[i].rtyp==POLY_CMD)
+    {
+      l0->m[i].rtyp=POLY_CMD;
+      l0->m[i].data=ppMult_qq(p,(poly)l1->m[i].data);
+    }
+  }
+  return(l0);
+}
+
+BOOLEAN pcvLAddL(leftv res,leftv h)
+{
+  short t[]={2,LIST_CMD,LIST_CMD};
+  if (iiCheckTypes(h,t,1))
+  {
+    lists l1=(lists)h->Data();
+    h=h->next;
+    lists l2=(lists)h->Data();
+    res->rtyp=LIST_CMD;
+    res->data=(void*)pcvLAddL(l1,l2);
+    return FALSE;
+  }
+  return TRUE;
+}
+
+BOOLEAN pcvPMulL(leftv res,leftv h)
+{
+  short t[]={2,POLY_CMD,LIST_CMD};
+  if (iiCheckTypes(h,t,1))
+  {
+    poly p=(poly)h->Data();
+    h=h->next;
+    lists l=(lists)h->Data();
+    res->rtyp=LIST_CMD;
+    res->data=(void*)pcvPMulL(p,l);
+    return FALSE;
+  }
+  return TRUE;
+}
+
+int pcvDeg(poly p)
+{
+  int d=0;
+  for(int i=currRing->N;i>=1;i--) d+=pGetExp(p,i);
+  return d;
+}
+
+int pcvMinDeg(poly p)
+{
+  if(!p) return -1;
+  int md=pcvDeg(p);
+  pIter(p);
+  while(p)
+  {
+    int d=pcvDeg(p);
+    if(d<md) md=d;
+    pIter(p);
+  }
+  return md;
+}
+
+int pcvMinDeg(matrix m)
+{
+  int i,j,d;
+  int md=-1;
+  for(i=1;i<=MATROWS(m);i++)
+  {
+    for(j=1;j<=MATCOLS(m);j++)
+    {
+      d=pcvMinDeg(MATELEM(m,i,j));
+      if((d>=0&&md>d)||md==-1) md=d;
+    }
+  }
+  return(md);
+}
+
+BOOLEAN pcvMinDeg(leftv res,leftv h)
+{
+  if(h)
+  {
+    if(h->Typ()==POLY_CMD)
+    {
+      res->rtyp=INT_CMD;
+      res->data=(void*)(long)pcvMinDeg((poly)h->Data());
+      return FALSE;
+    }
+    else
+    if(h->Typ()==MATRIX_CMD)
+    {
+      res->rtyp=INT_CMD;
+      res->data=(void*)(long)pcvMinDeg((matrix)h->Data());
+      return FALSE;
+    }
+  }
+  WerrorS("<poly> expected");
+  return TRUE;
+}
+
+void pcvInit(int d)
+{
+  if(d<0) d=1;
+  pcvMaxDegree=d+1;
+  pcvTableSize=currRing->N*pcvMaxDegree*sizeof(unsigned);
+  pcvTable=(unsigned*)omAlloc0(pcvTableSize);
+  pcvIndexSize=currRing->N*sizeof(unsigned*);
+  pcvIndex=(unsigned**)omAlloc(pcvIndexSize);
+  for(int i=0;i<currRing->N;i++)
+    pcvIndex[i]=pcvTable+i*pcvMaxDegree;
+  for(int i=0;i<pcvMaxDegree;i++)
+    pcvIndex[0][i]=i;
+  unsigned k,l;
+  for(int i=1;i<currRing->N;i++)
+  {
+    k=0;
+    for(int j=0;j<pcvMaxDegree;j++)
+    {
+      l=pcvIndex[i-1][j];
+      if(l>unsigned(~0)-k)
+      {
+        j=pcvMaxDegree;
+        i=currRing->N;
+        WerrorS("unsigned overflow");
+      }
+      else pcvIndex[i][j]=k+=l;
+    }
+  }
+}
+
+void pcvClean()
+{
+  if(pcvTable)
+  {
+    omFreeSize(pcvTable,pcvTableSize);
+    pcvTable=NULL;
+  }
+  if(pcvIndex)
+  {
+    omFreeSize(pcvIndex,pcvIndexSize);
+    pcvIndex=NULL;
+  }
+}
+
+int pcvM2N(poly m)
+{
+  unsigned n=0,dn,d=0;
+  for(int i=0;i<currRing->N;i++)
+  {
+    d+=pGetExp(m,i+1);
+    dn=pcvIndex[i][d];
+    if(dn>MAX_INT_VAL-n)
+    {
+      i=currRing->N;
+      WerrorS("component overflow");
+    }
+    else n+=dn;
+  }
+  return n+1;
+}
+
+poly pcvN2M(int n)
+{
+  n--;
+  poly m=pOne();
+  int i,j=0,k;
+  for(i=currRing->N-1;i>=0;i--)
+  {
+    k=j;
+    for(j=0; (j<pcvMaxDegree) && (pcvIndex[i][j]<=(unsigned)n); j++);
+    j--;
+    n-=pcvIndex[i][j];
+    if(i<currRing->N-1) pSetExp(m,i+2,k-j);
+  }
+  if(n==0)
+  {
+    pSetExp(m,1,j);
+    pSetm(m);
+    return m;
+  }
+  else
+  {
+    pLmDelete(&m);
+    return NULL;
+  }
+}
+
+poly pcvP2CV(poly p,int d0,int d1)
+{
+  poly cv=NULL;
+  while(p)
+  {
+    int d=pcvDeg(p);
+    if(d0<=d&&d<d1)
+    {
+      poly c=pNSet(nCopy(pGetCoeff(p)));
+      pSetComp(c,pcvM2N(p));
+      cv=pAdd(cv,c);
+    }
+    pIter(p);
+  }
+  return cv;
+}
+
+poly pcvCV2P(poly cv,int d0,int d1)
+{
+  poly p=NULL;
+  while(cv)
+  {
+    poly m=pcvN2M(pGetComp(cv));
+    if(m)
+    {
+      int d=pcvDeg(m);
+      if(d0<=d&&d<d1)
+      {
+        pSetCoeff(m,nCopy(pGetCoeff(cv)));
+        p=pAdd(p,m);
+      }
+    }
+    pIter(cv);
+  }
+  return p;
+}
+
+lists pcvP2CV(lists pl,int d0,int d1)
+{
+  lists cvl=(lists)omAllocBin(slists_bin);
+  cvl->Init(pl->nr+1);
+  pcvInit(d1);
+  for(int i=pl->nr;i>=0;i--)
+  {
+    if(pl->m[i].rtyp==POLY_CMD)
+    {
+      cvl->m[i].rtyp=VECTOR_CMD;
+      cvl->m[i].data=pcvP2CV((poly)pl->m[i].data,d0,d1);
+    }
+  }
+  pcvClean();
+  return cvl;
+}
+
+lists pcvCV2P(lists cvl,int d0,int d1)
+{
+  lists pl=(lists)omAllocBin(slists_bin);
+  pl->Init(cvl->nr+1);
+  pcvInit(d1);
+  for(int i=cvl->nr;i>=0;i--)
+  {
+    if(cvl->m[i].rtyp==VECTOR_CMD)
+    {
+      pl->m[i].rtyp=POLY_CMD;
+      pl->m[i].data=pcvCV2P((poly)cvl->m[i].data,d0,d1);
+    }
+  }
+  pcvClean();
+  return pl;
+}
+
+BOOLEAN pcvP2CV(leftv res,leftv h)
+{
+  if(currRing)
+  {
+    short t[]={3,LIST_CMD,INT_CMD,INT_CMD};
+    if (iiCheckTypes(h,t,1))
+    {
+      lists p=(lists)h->Data();
+      h=h->next;
+      int d0=(int)(long)h->Data();
+      h=h->next;
+      int d1=(int)(long)h->Data();
+      res->rtyp=LIST_CMD;
+      res->data=(void*)pcvP2CV(p,d0,d1);
+      return FALSE;
+    }
+    return TRUE;
+  }
+  WerrorS("no ring active");
+  return TRUE;
+}
+
+BOOLEAN pcvCV2P(leftv res,leftv h)
+{
+  if(currRing)
+  {
+    short t[]={3,LIST_CMD,INT_CMD,INT_CMD};
+    if (iiCheckTypes(h,t,1))
+    {
+      lists pl=(lists)h->Data();
+      h=h->next;
+      int d0=(int)(long)h->Data();
+      h=h->next;
+      int d1=(int)(long)h->Data();
+      res->rtyp=LIST_CMD;
+      res->data=(void*)pcvCV2P(pl,d0,d1);
+      return FALSE;
+    }
+    return TRUE;
+  }
+  WerrorS("no ring active");
+  return TRUE;
+}
+
+int pcvDim(int d0,int d1)
+{
+  if(d0<0) d0=0;
+  if(d1<0) d1=0;
+  pcvInit(d1);
+  int d=pcvIndex[currRing->N-1][d1]-pcvIndex[currRing->N-1][d0];
+  pcvClean();
+  return d;
+}
+
+BOOLEAN pcvDim(leftv res,leftv h)
+{
+  if(currRing)
+  {
+    short t[]={2,INT_CMD,INT_CMD};
+    if (iiCheckTypes(h,t,1))
+    {
+      int d0=(int)(long)h->Data();
+      h=h->next;
+      int d1=(int)(long)h->Data();
+      res->rtyp=INT_CMD;
+      res->data=(void*)(long)pcvDim(d0,d1);
+      return FALSE;
+    }
+    return TRUE;
+  }
+  WerrorS("no ring active");
+  return TRUE;
+}
+
+int pcvBasis(lists b,int i,poly m,int d,int n)
+{
+  if(n<currRing->N)
+  {
+    for(int k=0,l=d;k<=l;k++,d--)
+    {
+      pSetExp(m,n,k);
+      i=pcvBasis(b,i,m,d,n+1);
+    }
+  }
+  else
+  {
+    pSetExp(m,n,d);
+    pSetm(m);
+    b->m[i].rtyp=POLY_CMD;
+    b->m[i++].data=pCopy(m);
+  }
+  return i;
+}
+
+lists pcvBasis(int d0,int d1)
+{
+  if(d0<0) d0=0;
+  if(d1<0) d1=0;
+  lists b=(lists)omAllocBin(slists_bin);
+  b->Init(pcvDim(d0,d1));
+  poly m=pOne();
+  for(int d=d0,i=0;d<d1;d++)
+    i=pcvBasis(b,i,m,d,1);
+  pLmDelete(&m);
+  return b;
+}
+
+BOOLEAN pcvBasis(leftv res,leftv h)
+{
+  if(currRing)
+  {
+    short t[]={2,INT_CMD,INT_CMD};
+    if (iiCheckTypes(h,t,1))
+    {
+      int d0=(int)(long)h->Data();
+      h=h->next;
+      int d1=(int)(long)h->Data();
+      res->rtyp=LIST_CMD;
+      res->data=(void*)pcvBasis(d0,d1);
+      return FALSE;
+    }
+    return TRUE;
+  }
+  WerrorS("no ring active");
+  return TRUE;
+}
+
+#endif /* HAVE_PCV */
diff --git a/Singular/pcv.h b/Singular/pcv.h
new file mode 100644
index 0000000..8cd1f15
--- /dev/null
+++ b/Singular/pcv.h
@@ -0,0 +1,37 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: conversion between polys and coef vectors
+*/
+
+#ifndef PCV_H
+#define PCV_H
+
+lists pcvLAddL(lists l1,lists l2);
+lists pcvPMulL(poly p,lists l1);
+BOOLEAN pcvLAddL(leftv res,leftv h);
+BOOLEAN pcvPMulL(leftv res,leftv h);
+int pcvDeg(poly p);
+int pcvMinDeg(poly p);
+int pcvMinDeg(matrix m);
+BOOLEAN pcvMinDeg(leftv res,leftv h);
+void pcvInit(int d);
+void pcvClean();
+int pcvM2N(poly m);
+poly pcvN2M(int n);
+poly pcvP2CV(poly p,int d0,int d1);
+poly pcvCV2P(poly cv,int d0,int d1);
+lists pcvP2CV(lists pl,int d0,int d1);
+ideal pcvP2CV(ideal p,int d0,int d1);
+lists pcvCV2P(lists cvl,int d0,int d1);
+ideal pcvCV2P(ideal cv,int d0,int d1);
+BOOLEAN pcvP2CV(leftv res,leftv h);
+BOOLEAN pcvCV2P(leftv res,leftv h);
+int pcvDim(int d0,int d1);
+BOOLEAN pcvDim(leftv res,leftv h);
+int pcvBasis(lists b,int i,poly m,int d,int n);
+lists pcvBasis(int d0,int d1);
+BOOLEAN pcvBasis(leftv res,leftv h);
+
+#endif
diff --git a/Singular/pyobject_setup.cc b/Singular/pyobject_setup.cc
new file mode 100644
index 0000000..232a54e
--- /dev/null
+++ b/Singular/pyobject_setup.cc
@@ -0,0 +1,56 @@
+// -*- c++ -*-
+//*****************************************************************************
+/** @file pyobject_setup.cc
+ *
+ * @author Alexander Dreyer
+ * @date 2010-12-15
+ *
+ * This header file defines the @c blackbox setup operations for the pyobject
+ *
+ * @par Copyright:
+ *   (c) 2010 by The Singular Team, see LICENSE file
+**/
+//*****************************************************************************
+
+#include <kernel/mod2.h>
+
+#include <Singular/blackbox.h>
+#include <Singular/ipshell.h>
+
+static BOOLEAN pyobject_load()
+{
+  return jjLOAD("pyobject.so", TRUE);
+}
+
+/// blackbox support - initialization via autoloading
+void* pyobject_autoload(blackbox* bbx)
+{
+  assume(bbx != NULL);
+  return (pyobject_load() || (bbx->blackbox_Init == pyobject_autoload)?
+	  NULL: bbx->blackbox_Init(bbx));
+}
+
+void pyobject_default_destroy(blackbox  */*b*/, void */*d*/)
+{
+  Werror("Python-based functionality not available!");
+}
+
+// Setting up an empty blackbox type, which can be filled with pyobject
+void pyobject_setup()
+{
+  blackbox *bbx = (blackbox*)omAlloc0(sizeof(blackbox));
+  bbx->blackbox_Init = pyobject_autoload;
+  bbx->blackbox_destroy = pyobject_default_destroy;
+  setBlackboxStuff(bbx, "pyobject");
+}
+
+/// Explicitely load, if not loaded already
+BOOLEAN pyobject_ensure()
+{
+
+  int tok = -1;
+  blackbox* bbx = (blackboxIsCmd("pyobject", tok) == ROOT_DECL?
+                   getBlackboxStuff(tok): (blackbox*)NULL);
+  if (bbx == NULL) return TRUE;
+  return (bbx->blackbox_Init == pyobject_autoload?  pyobject_load(): FALSE);
+}
diff --git a/Singular/pyobject_setup.h b/Singular/pyobject_setup.h
new file mode 100644
index 0000000..bdd7464
--- /dev/null
+++ b/Singular/pyobject_setup.h
@@ -0,0 +1,25 @@
+// -*- c++ -*-
+//*****************************************************************************
+/** @file pyobject_setup.h
+ *
+ * @author Alexander Dreyer
+ * @date 2010-12-15
+ *
+ * This header file defines the @c blackbox setup interface for the pyobject
+ *
+ * @par Copyright:
+ *   (c) 2010 by The Singular Team, see LICENSE file
+**/
+//*****************************************************************************
+
+
+#ifndef SINGULAR_PYOBJECT_SETUP_H
+#define SINGULAR_PYOBJECT_SETUP_H
+
+/// initialize blackbox support for @c pyobject; functionilty os autoloaded on demand
+void pyobject_setup();
+
+/// force leading of pyobject functionality
+BOOLEAN pyobject_ensure();
+
+#endif
diff --git a/Singular/run.h b/Singular/run.h
new file mode 100644
index 0000000..d212d3b
--- /dev/null
+++ b/Singular/run.h
@@ -0,0 +1,100 @@
+// #define DEBUG
+// #define DEBUGALL
+
+// B19 - egcs automatically defines CYGWIN32 but not CYGWIN
+// B20 - egcs automatically defines both CYGWIN32 and CYGWIN
+// Bfuture - (???) defines CYGWIN but not CYGWIN32
+#if defined(__CYGWIN32__)
+#if !defined(__CYGWIN__)
+ #define B19
+ #define __CYGWIN__
+#else
+ #define B20
+#endif
+#else
+#if defined(__CYGWIN__)
+ #define B21
+#endif
+#endif
+// Now: use __CYGWIN__ to represent any version
+// distinguish using B19, B20, or B21
+
+#if defined(__CYGWIN__)
+#ifdef B19
+#define CYGWIN_ATTACH_HANDLE_TO_FD(a)      cygwin32_attach_handle_to_fd      a
+#define CYGWIN_CONV_TO_FULL_POSIX_PATH(a)  cygwin32_conv_to_full_posix_path  a
+#define CYGWIN_CONV_TO_FULL_WIN32_PATH(a)  cygwin32_conv_to_full_win32_path  a
+#define CYGWIN_CONV_TO_POSIX_PATH(a)       cygwin32_conv_to_posix_path       a
+#define CYGWIN_CONV_TO_WIN32_PATH(a)       cygwin32_conv_to_win32_path       a
+#define CYGWIN_DETACH_DLL(a)               cygwin32_detach_dll               a
+#define CYGWIN_GETSHARED(a)                cygwin32_getshared                a
+#define CYGWIN_INTERNAL(a)                 cygwin32_internal                 a
+#define CYGWIN_POSIX_PATH_LIST_P(a)        cygwin32_posix_path_list_p        a
+#define CYGWIN_POSIX_TO_WIN32_PATH_LIST(a) cygwin32_posix_to_win32_path_list a
+#define CYGWIN_POSIX_TO_WIN32_PATH_LIST_BUF_SIZE(a) cygwin32_posix_to_win32_path_list_buf_size a
+#define CYGWIN_SPLIT_PATH(a)               cygwin32_split_path               a
+#define CYGWIN_WIN32_TO_POSIX_PATH_LIST(a) cygwin32_win32_to_posix_path_list a
+#define CYGWIN_WIN32_TO_POSIX_PATH_LIST_BUF_SIZE(a) cygwin32_win32_to_posix_path_list_buf_size a
+#define CYGWIN_WINPID_TO_PID(a)            cygwin32_winpid_to_pid            a
+#else
+#define CYGWIN_ATTACH_HANDLE_TO_FD(a)      cygwin_attach_handle_to_fd      a
+#define CYGWIN_CONV_TO_FULL_POSIX_PATH(a)  cygwin_conv_to_full_posix_path  a
+#define CYGWIN_CONV_TO_FULL_WIN32_PATH(a)  cygwin_conv_to_full_win32_path  a
+#define CYGWIN_CONV_TO_POSIX_PATH(a)       cygwin_conv_to_posix_path       a
+#define CYGWIN_CONV_TO_WIN32_PATH(a)       cygwin_conv_to_win32_path       a
+#define CYGWIN_DETACH_DLL(a)               cygwin_detach_dll               a
+#define CYGWIN_GETSHARED(a)                cygwin_getshared                a
+#define CYGWIN_INTERNAL(a)                 cygwin_internal                 a
+#define CYGWIN_POSIX_PATH_LIST_P(a)        cygwin_posix_path_list_p        a
+#define CYGWIN_POSIX_TO_WIN32_PATH_LIST(a) cygwin_posix_to_win32_path_list a
+#define CYGWIN_POSIX_TO_WIN32_PATH_LIST_BUF_SIZE(a) cygwin_posix_to_win32_path_list_buf_size a
+#define CYGWIN_SPLIT_PATH(a)               cygwin_split_path               a
+#define CYGWIN_WIN32_TO_POSIX_PATH_LIST(a) cygwin_win32_to_posix_path_list a
+#define CYGWIN_WIN32_TO_POSIX_PATH_LIST_BUF_SIZE(a) cygwin_win32_to_posix_path_list_buf_size a
+#define CYGWIN_WINPID_TO_PID(a)            cygwin_winpid_to_pid            a
+#endif
+#endif
+
+#if defined(__CYGWIN__)
+ #define PATH_SEP_CHAR_STR "/"
+ #define SEP_CHARS ":"
+#else
+ #define PATH_SEP_CHAR_STR "\\"
+ #define SEP_CHARS ";"
+#endif
+
+#ifndef RC_INVOKED
+
+#define MAX_ARGS 20
+
+#ifdef DEBUG
+ #define Trace(x)   Trace_ x
+#else
+ #define Trace(x)
+#endif
+
+#define NUM_EXTENSIONS 2
+const char* exts[NUM_EXTENSIONS] = { "", ".exe" };
+
+char* pfopen(char *retval, const char *name, const char *dirs);
+void error(char* fmt, ...);
+void message(char* fmt, ...);
+void Trace_(char* fmt, ...);
+int get_exec_name_and_path(char* execname, char* execpath);
+char* my_strtok(char* s, const char* delim, char** lasts);
+int parse_cmdline_to_arg_array(char* argv[MAX_ARGS], char* cmdline);
+void strip_exe(char* s);
+int start_child(char* cmdline, int wait_for_child);
+void xemacs_special(char* exec);
+int build_cmdline(char* new_cmdline, char* exec, int argc, char* argv[]);
+void process_execname(char *exec, const char* execname, const char* execpath);
+int fileExists(char* fullname, const char* path, const char* name);
+int endsWith(const char* s1, const char* s2);
+int fileExistsMulti(char* fullname, const char* path,
+                    const char* name_noext, const char* exts[],
+                    const int extcnt);
+
+#endif /* RC_INVOKED */
+
+
+
diff --git a/Singular/scanner.cc b/Singular/scanner.cc
new file mode 100644
index 0000000..61d3c61
--- /dev/null
+++ b/Singular/scanner.cc
@@ -0,0 +1,2331 @@
+/* A lexical scanner generated by flex */
+
+/* Scanner skeleton version:
+ * $Header: /home/daffy/u0/vern/flex/RCS/flex.skl,v 2.91 96/09/10 16:58:48 vern Exp $
+ */
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 5
+
+#include <stdio.h>
+
+
+/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */
+#ifdef c_plusplus
+#ifndef __cplusplus
+#define __cplusplus
+#endif
+#endif
+
+
+#ifdef __cplusplus
+
+#include <stdlib.h>
+#include <unistd.h>
+
+/* Use prototypes in function declarations. */
+#define YY_USE_PROTOS
+
+/* The "const" storage-class-modifier is valid. */
+#define YY_USE_CONST
+
+#else	/* ! __cplusplus */
+
+#if __STDC__
+
+#define YY_USE_PROTOS
+#define YY_USE_CONST
+
+#endif	/* __STDC__ */
+#endif	/* ! __cplusplus */
+
+#ifdef __TURBOC__
+ #pragma warn -rch
+ #pragma warn -use
+#include <io.h>
+#include <stdlib.h>
+#define YY_USE_CONST
+#define YY_USE_PROTOS
+#endif
+
+#ifdef YY_USE_CONST
+#define yyconst const
+#else
+#define yyconst
+#endif
+
+
+#ifdef YY_USE_PROTOS
+#define YY_PROTO(proto) proto
+#else
+#define YY_PROTO(proto) ()
+#endif
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+
+/* Promotes a possibly negative, possibly signed char to an unsigned
+ * integer for use as an array index.  If the signed char is negative,
+ * we want to instead treat it as an 8-bit unsigned char, hence the
+ * double cast.
+ */
+#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+
+/* Enter a start condition.  This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN yy_start = 1 + 2 *
+
+/* Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state.  The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START ((yy_start - 1) / 2)
+#define YYSTATE YY_START
+
+/* Action number for EOF rule of a given start state. */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+
+/* Special action meaning "start processing a new file". */
+#define YY_NEW_FILE yyrestart( yyin )
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#define YY_BUF_SIZE 16384
+
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+
+extern int yyleng;
+extern FILE *yyin, *yyout;
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+/* The funky do-while in the following #define is used to turn the definition
+ * int a single C statement (which needs a semi-colon terminator).  This
+ * avoids problems with code like:
+ *
+ * 	if ( condition_holds )
+ *		yyless( 5 );
+ *	else
+ *		do_something_else();
+ *
+ * Prior to using the do-while the compiler would get upset at the
+ * "else" because it interpreted the "if" statement as being all
+ * done when it reached the ';' after the yyless() call.
+ */
+
+/* Return all but the first 'n' matched characters back to the input stream. */
+
+#define yyless(n) \
+	do \
+		{ \
+		/* Undo effects of setting up yytext. */ \
+		*yy_cp = yy_hold_char; \
+		YY_RESTORE_YY_MORE_OFFSET \
+		yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \
+		YY_DO_BEFORE_ACTION; /* set up yytext again */ \
+		} \
+	while ( 0 )
+
+#define unput(c) yyunput( c, yytext_ptr )
+
+/* The following is because we cannot portably get our hands on size_t
+ * (without autoconf's help, which isn't available because we want
+ * flex-generated scanners to compile on their own).
+ */
+typedef unsigned int yy_size_t;
+
+
+struct yy_buffer_state
+	{
+	FILE *yy_input_file;
+
+	char *yy_ch_buf;		/* input buffer */
+	char *yy_buf_pos;		/* current position in input buffer */
+
+	/* Size of input buffer in bytes, not including room for EOB
+	 * characters.
+	 */
+	yy_size_t yy_buf_size;
+
+	/* Number of characters read into yy_ch_buf, not including EOB
+	 * characters.
+	 */
+	int yy_n_chars;
+
+	/* Whether we "own" the buffer - i.e., we know we created it,
+	 * and can realloc() it to grow it, and should free() it to
+	 * delete it.
+	 */
+	int yy_is_our_buffer;
+
+	/* Whether this is an "interactive" input source; if so, and
+	 * if we're using stdio for input, then we want to use getc()
+	 * instead of fread(), to make sure we stop fetching input after
+	 * each newline.
+	 */
+	int yy_is_interactive;
+
+	/* Whether we're considered to be at the beginning of a line.
+	 * If so, '^' rules will be active on the next match, otherwise
+	 * not.
+	 */
+	int yy_at_bol;
+
+	/* Whether to try to fill the input buffer when we reach the
+	 * end of it.
+	 */
+	int yy_fill_buffer;
+
+	int yy_buffer_status;
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+	/* When an EOF's been seen but there's still some text to process
+	 * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+	 * shouldn't try reading from the input source any more.  We might
+	 * still have a bunch of tokens to match, though, because of
+	 * possible backing-up.
+	 *
+	 * When we actually see the EOF, we change the status to "new"
+	 * (via yyrestart()), so that the user can continue scanning by
+	 * just pointing yyin at a new input file.
+	 */
+#define YY_BUFFER_EOF_PENDING 2
+	};
+
+static YY_BUFFER_STATE yy_current_buffer = 0;
+
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state".
+ */
+#define YY_CURRENT_BUFFER yy_current_buffer
+
+
+/* yy_hold_char holds the character lost when yytext is formed. */
+static char yy_hold_char;
+
+static int yy_n_chars;		/* number of characters read into yy_ch_buf */
+
+
+int yyleng;
+
+/* Points to current character in buffer. */
+static char *yy_c_buf_p = (char *) 0;
+static int yy_init = 1;		/* whether we need to initialize */
+static int yy_start = 0;	/* start state number */
+
+/* Flag which is used to allow yywrap()'s to do buffer switches
+ * instead of setting up a fresh yyin.  A bit of a hack ...
+ */
+static int yy_did_buffer_switch_on_eof;
+
+void yyrestart YY_PROTO(( FILE *input_file ));
+
+void yy_switch_to_buffer YY_PROTO(( YY_BUFFER_STATE new_buffer ));
+void yy_load_buffer_state YY_PROTO(( void ));
+YY_BUFFER_STATE yy_create_buffer YY_PROTO(( FILE *file, int size ));
+void yy_delete_buffer YY_PROTO(( YY_BUFFER_STATE b ));
+void yy_init_buffer YY_PROTO(( YY_BUFFER_STATE b, FILE *file ));
+void yy_flush_buffer YY_PROTO(( YY_BUFFER_STATE b ));
+#define YY_FLUSH_BUFFER yy_flush_buffer( yy_current_buffer )
+
+YY_BUFFER_STATE yy_scan_buffer YY_PROTO(( char *base, yy_size_t size ));
+YY_BUFFER_STATE yy_scan_string YY_PROTO(( yyconst char *yy_str ));
+YY_BUFFER_STATE yy_scan_bytes YY_PROTO(( yyconst char *bytes, int len ));
+
+static void *yy_flex_alloc YY_PROTO(( yy_size_t ));
+static void *yy_flex_realloc YY_PROTO(( void *, yy_size_t ));
+static void yy_flex_free YY_PROTO(( void * ));
+
+#define yy_new_buffer yy_create_buffer
+
+#define yy_set_interactive(is_interactive) \
+	{ \
+	if ( ! yy_current_buffer ) \
+		yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
+	yy_current_buffer->yy_is_interactive = is_interactive; \
+	}
+
+#define yy_set_bol(at_bol) \
+	{ \
+	if ( ! yy_current_buffer ) \
+		yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
+	yy_current_buffer->yy_at_bol = at_bol; \
+	}
+
+#define YY_AT_BOL() (yy_current_buffer->yy_at_bol)
+
+typedef unsigned char YY_CHAR;
+FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;
+typedef int yy_state_type;
+extern char *yytext;
+#define yytext_ptr yytext
+
+static yy_state_type yy_get_previous_state YY_PROTO(( void ));
+static yy_state_type yy_try_NUL_trans YY_PROTO(( yy_state_type current_state ));
+static int yy_get_next_buffer YY_PROTO(( void ));
+static void yy_fatal_error YY_PROTO(( yyconst char msg[] ));
+
+/* Done after the current pattern has been matched and before the
+ * corresponding action - sets up yytext.
+ */
+#define YY_DO_BEFORE_ACTION \
+	yytext_ptr = yy_bp; \
+	yytext_ptr -= yy_more_len; \
+	yyleng = (int) (yy_cp - yytext_ptr); \
+	yy_hold_char = *yy_cp; \
+	*yy_cp = '\0'; \
+	yy_c_buf_p = yy_cp;
+
+#define YY_NUM_RULES 66
+#define YY_END_OF_BUFFER 67
+static yyconst short int yy_accept[171] =
+    {   0,
+        0,    0,    0,    0,   30,   30,    0,    0,    0,    0,
+        0,    0,   20,   20,    0,    0,   67,   65,   40,   40,
+       50,   34,   64,   59,   65,   64,   65,   65,   65,   65,
+       65,   57,   65,   65,   65,   65,    6,   55,   64,   64,
+       64,   64,   64,   64,   64,   24,   65,   35,   64,   36,
+       39,   36,   30,   25,   30,   32,   33,   26,   29,   26,
+       13,   11,   12,   15,   14,   17,   16,   21,   20,   21,
+       18,   23,   19,    9,   66,   10,   51,   46,   64,   64,
+       64,   53,   44,   43,   54,   41,   61,    3,    1,   61,
+        0,    0,   57,   42,   48,   52,   45,   49,    6,   64,
+
+       64,   64,   64,   64,   64,   64,   47,    2,   38,   37,
+       30,   30,   28,   27,   21,   20,   21,    0,   21,    9,
+        0,    1,   61,   63,   61,   63,   58,   64,   64,    5,
+       64,   64,   64,   64,   64,    2,   30,   31,   22,    0,
+        0,    0,   64,   64,    6,   64,   64,   64,   61,   62,
+        0,   64,    0,   60,   64,    0,    4,   64,   64,    0,
+        0,    7,   56,    0,    0,    8,    0,    0,    7,    0
+    } ;
+
+static yyconst int yy_ec[256] =
+    {   0,
+        1,    1,    1,    1,    1,    1,    1,    1,    2,    3,
+        1,    1,    4,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    2,    5,    6,    7,    8,    1,    9,   10,   11,
+       12,   13,   14,   15,   16,   17,   18,   19,   19,   19,
+       19,   19,   19,   19,   19,   19,   19,   20,   21,   22,
+       23,   24,   25,   10,   10,   10,   10,   10,   10,   10,
+       10,   10,   10,   10,   10,   10,   10,   10,   10,   10,
+       10,   10,   10,   10,   10,   10,   10,   10,   10,   10,
+        1,   26,    1,    1,   27,    1,   28,   10,   29,   10,
+
+       30,   31,   10,   32,   33,   10,   10,   34,   35,   36,
+       37,   38,   39,   40,   10,   41,   42,   10,   43,   44,
+       10,   10,   45,   46,   47,   48,    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,    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
+    } ;
+
+static yyconst int yy_meta[49] =
+    {   0,
+        1,    2,    3,    1,    1,    4,    1,    1,    1,    5,
+        6,    7,    1,    1,    7,    1,    8,    9,   10,    1,
+       11,    1,    1,    1,    1,    1,   12,    5,    5,    5,
+        5,    5,    5,    5,    5,    5,    5,    5,    5,    5,
+        5,    5,    5,    5,    4,    1,    4,    1
+    } ;
+
+static yyconst short int yy_base[192] =
+    {   0,
+        0,  299,   43,   44,   45,   46,   47,   48,   50,   54,
+      295,  294,   74,   92,   75,   76,  296,  561,  561,  561,
+      269,  561,  561,  561,  267,   40,  250,  229,   84,   38,
+       69,   92,  221,   60,  194,  181,   99,  561,   86,   87,
+       93,   98,   99,  100,  102,  561,  154,  561,  177,  561,
+      561,   62,    0,  561,  158,  561,  561,  561,  561,  109,
+      561,  561,  561,  561,  561,  561,  561,    0,  129,  134,
+      561,  561,  561,    0,  561,  561,  561,  561,  114,  124,
+      125,  561,  561,  561,  561,  561,  128,  561,    0,  136,
+      129,  149,  143,  561,  561,  561,  561,  561,  154,  144,
+
+      146,  147,  148,  151,  136,  151,  561,    0,  561,  561,
+        0,  177,  561,  561,    0,  187,  190,  144,    0,    0,
+      171,    0,  180,  561,  176,  193,  193,  180,  186,  188,
+      190,  192,  201,  203,  204,    0,  236,    0,  561,  119,
+      103,   97,  207,  244,  246,  222,  231,  223,   80,   39,
+      243,  224,  266,  561,  238,  252,  242,  252,  256,  286,
+       70,  288,  245,  192,  291,  561,  292,  293,  296,  561,
+      320,  332,  344,  356,  368,  380,  392,  400,  408,  418,
+      430,  442,  454,  466,  478,  490,  502,  514,  526,  537,
+      548
+
+    } ;
+
+static yyconst short int yy_def[192] =
+    {   0,
+      170,    1,  171,  171,  172,  172,  173,  173,  174,  174,
+      175,  175,  176,  176,  177,  177,  170,  170,  170,  170,
+      170,  170,  170,  170,  170,  178,  170,  170,  170,  170,
+      170,  179,  170,  170,  170,  170,  170,  170,  178,  178,
+      178,  178,  178,  178,  178,  170,  170,  170,  170,  170,
+      170,  170,  180,  170,  180,  170,  170,  170,  170,  170,
+      170,  170,  170,  170,  170,  170,  170,  181,  170,  182,
+      170,  170,  170,  183,  170,  170,  170,  170,  178,  178,
+      178,  170,  170,  170,  170,  170,  170,  170,  184,  179,
+      185,  170,  179,  170,  170,  170,  170,  170,  170,  178,
+
+      178,  178,  178,  178,  100,  100,  170,  186,  170,  170,
+      180,  187,  170,  170,  181,  170,  182,  188,  181,  183,
+      170,  184,  179,  170,  170,  170,  179,  100,  100,  100,
+      100,  100,  100,  100,  100,  186,  187,  189,  170,  170,
+      170,  170,  100,  100,  144,  100,  100,  100,  170,  170,
+      179,  100,  170,  170,  100,  190,  100,  100,  100,  191,
+      170,  144,  100,  170,  191,  170,  191,  191,  170,    0,
+      170,  170,  170,  170,  170,  170,  170,  170,  170,  170,
+      170,  170,  170,  170,  170,  170,  170,  170,  170,  170,
+      170
+
+    } ;
+
+static yyconst short int yy_nxt[610] =
+    {   0,
+       18,   19,   20,   19,   21,   22,   23,   24,   25,   26,
+       18,   18,   27,   28,   18,   29,   30,   31,   32,   33,
+       18,   34,   35,   36,   37,   38,   23,   26,   26,   39,
+       40,   41,   26,   26,   26,   42,   26,   43,   44,   26,
+       26,   26,   45,   26,   46,   47,   18,   48,   51,   51,
+       54,   54,   59,   59,   86,   62,   87,  150,   80,   62,
+       63,   64,   55,   55,   63,   64,   81,  109,   52,   52,
+       65,  164,   60,   60,   65,   69,   69,   75,   75,   70,
+      166,   88,   95,   96,   71,   72,   89,  110,   73,   56,
+       56,   57,   57,   69,   69,   76,   76,   70,  149,   84,
+
+       99,   99,   71,   72,   80,   80,   73,   85,   91,   92,
+       93,   80,   81,   81,  113,  151,   80,   80,   80,   81,
+       80,  150,  102,  101,   81,   81,   81,  103,   81,  100,
+      116,  116,   80,  106,  114,  118,  118,  149,  104,  119,
+       81,  105,   80,   80,  118,  118,   87,  125,  118,  139,
+       81,   81,  170,  170,  123,   99,   99,  121,  126,   91,
+       92,   93,   80,   79,   80,   80,   80,  127,  134,   80,
+       81,  128,   81,   81,   81,  112,  129,   81,   79,  111,
+      131,  108,  138,  135,  140,  130,  140,  133,  116,  116,
+      132,  118,  118,  164,   87,  119,  170,  170,  123,  107,
+
+      118,  118,  166,   98,  118,  121,  141,   79,  141,  170,
+      142,  127,   79,   79,  143,   79,   97,   79,   79,   79,
+       79,  138,   79,  138,   79,  146,  144,  145,   79,  147,
+       79,   79,  156,   79,   79,   79,   79,  148,  111,   79,
+       94,  138,   83,  144,  152,  153,  153,   99,   99,   79,
+       79,   79,  157,  156,  155,   79,   79,  158,   79,  170,
+      142,  151,   82,   79,  154,   79,  170,  153,  153,   79,
+       79,   79,   79,  159,   79,   78,   79,   79,  161,   79,
+      138,  162,  138,   79,   79,  163,  154,  164,   79,  169,
+      169,   77,  164,  164,  164,  170,  166,  169,  169,   67,
+
+       67,  166,  166,  166,  167,   49,  170,  170,  170,  167,
+      167,  167,  168,  170,  170,  170,  170,  168,  168,  168,
+       50,   50,   50,   50,   50,   50,   50,   50,   50,   50,
+       50,   50,   53,   53,   53,   53,   53,   53,   53,   53,
+       53,   53,   53,   53,   58,   58,   58,   58,   58,   58,
+       58,   58,   58,   58,   58,   58,   61,   61,   61,   61,
+       61,   61,   61,   61,   61,   61,   61,   61,   66,   66,
+       66,   66,   66,   66,   66,   66,   66,   66,   66,   66,
+       68,   68,   68,   68,   68,   68,   68,   68,   68,   68,
+       68,   68,   74,   74,   74,   74,   74,   74,   74,   74,
+
+       74,   74,   74,   74,   79,  170,  170,  170,  170,   79,
+      170,   79,   90,  170,  170,   90,   90,   90,  111,  111,
+      111,  170,  111,  111,  111,  111,  111,  111,  111,  111,
+      115,  170,  170,  115,  115,  170,  170,  115,  115,  115,
+      115,  115,  117,  117,  117,  117,  117,  117,  117,  117,
+      117,  117,  117,  117,  120,  120,  170,  120,  120,  120,
+      120,  120,  120,  120,  170,  120,  122,  122,  170,  122,
+      122,  122,  122,  122,  122,  122,  122,  122,  124,  124,
+      124,  124,  124,  124,  124,  170,  124,  124,  124,  124,
+      136,  136,  170,  136,  136,  136,  136,  136,  136,  136,
+
+      136,  136,  137,  137,  137,  137,  137,  137,  137,  137,
+      137,  137,  137,  137,  118,  118,  118,  118,  118,  118,
+      118,  118,  118,  118,  118,  118,  138,  138,  170,  138,
+      138,  138,  138,  138,  138,  138,  138,  138,  160,  170,
+      170,  160,  170,  170,  170,  170,  170,  170,  160,  165,
+      170,  170,  165,  165,  170,  170,  170,  165,  170,  165,
+       17,  170,  170,  170,  170,  170,  170,  170,  170,  170,
+      170,  170,  170,  170,  170,  170,  170,  170,  170,  170,
+      170,  170,  170,  170,  170,  170,  170,  170,  170,  170,
+      170,  170,  170,  170,  170,  170,  170,  170,  170,  170,
+
+      170,  170,  170,  170,  170,  170,  170,  170,  170
+    } ;
+
+static yyconst short int yy_chk[610] =
+    {   0,
+        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,    3,    4,
+        5,    6,    7,    8,   30,    9,   30,  150,   26,   10,
+        9,    9,    5,    6,   10,   10,   26,   52,    3,    4,
+        9,  161,    7,    8,   10,   13,   13,   15,   16,   13,
+      161,   31,   34,   34,   13,   13,   31,   52,   13,    5,
+        6,    5,    6,   14,   14,   15,   16,   14,  149,   29,
+
+       37,   37,   14,   14,   39,   40,   14,   29,   32,   32,
+       32,   41,   39,   40,   60,  142,   42,   43,   44,   41,
+       45,  141,   41,   40,   42,   43,   44,   42,   45,   39,
+       69,   69,   79,   45,   60,   70,   70,  140,   43,   70,
+       79,   44,   80,   81,   70,   70,   87,   91,   70,  118,
+       80,   81,   90,   90,   90,   99,   99,   87,   91,   93,
+       93,   93,  100,  105,  101,  102,  103,   92,  105,  104,
+      100,  100,  101,  102,  103,   55,  100,  104,  106,  112,
+      102,   49,  112,  106,  121,  101,  121,  104,  116,  116,
+      103,  117,  117,  164,  125,  117,  123,  123,  123,   47,
+
+      117,  117,  164,   36,  117,  125,  126,  128,  126,  127,
+      127,  127,  128,  129,  128,  130,   35,  131,  129,  132,
+      130,  112,  131,  112,  132,  132,  129,  131,  133,  133,
+      134,  135,  147,  133,  143,  134,  135,  135,  137,  143,
+       33,  137,   28,  134,  143,  144,  144,  145,  145,  146,
+      148,  152,  148,  156,  146,  148,  152,  152,  147,  151,
+      151,  151,   27,  147,  144,  155,  145,  153,  153,  157,
+      155,  144,  163,  155,  157,   25,  144,  163,  156,  158,
+      137,  158,  137,  159,  158,  159,  153,  160,  159,  162,
+      162,   21,  165,  167,  168,   17,  160,  169,  169,   12,
+
+       11,  165,  167,  168,  160,    2,    0,    0,  162,  165,
+      167,  168,  160,    0,    0,    0,    0,  165,  167,  168,
+      171,  171,  171,  171,  171,  171,  171,  171,  171,  171,
+      171,  171,  172,  172,  172,  172,  172,  172,  172,  172,
+      172,  172,  172,  172,  173,  173,  173,  173,  173,  173,
+      173,  173,  173,  173,  173,  173,  174,  174,  174,  174,
+      174,  174,  174,  174,  174,  174,  174,  174,  175,  175,
+      175,  175,  175,  175,  175,  175,  175,  175,  175,  175,
+      176,  176,  176,  176,  176,  176,  176,  176,  176,  176,
+      176,  176,  177,  177,  177,  177,  177,  177,  177,  177,
+
+      177,  177,  177,  177,  178,    0,    0,    0,    0,  178,
+        0,  178,  179,    0,    0,  179,  179,  179,  180,  180,
+      180,    0,  180,  180,  180,  180,  180,  180,  180,  180,
+      181,    0,    0,  181,  181,    0,    0,  181,  181,  181,
+      181,  181,  182,  182,  182,  182,  182,  182,  182,  182,
+      182,  182,  182,  182,  183,  183,    0,  183,  183,  183,
+      183,  183,  183,  183,    0,  183,  184,  184,    0,  184,
+      184,  184,  184,  184,  184,  184,  184,  184,  185,  185,
+      185,  185,  185,  185,  185,    0,  185,  185,  185,  185,
+      186,  186,    0,  186,  186,  186,  186,  186,  186,  186,
+
+      186,  186,  187,  187,  187,  187,  187,  187,  187,  187,
+      187,  187,  187,  187,  188,  188,  188,  188,  188,  188,
+      188,  188,  188,  188,  188,  188,  189,  189,    0,  189,
+      189,  189,  189,  189,  189,  189,  189,  189,  190,    0,
+        0,  190,    0,    0,    0,    0,    0,    0,  190,  191,
+        0,    0,  191,  191,    0,    0,    0,  191,    0,  191,
+      170,  170,  170,  170,  170,  170,  170,  170,  170,  170,
+      170,  170,  170,  170,  170,  170,  170,  170,  170,  170,
+      170,  170,  170,  170,  170,  170,  170,  170,  170,  170,
+      170,  170,  170,  170,  170,  170,  170,  170,  170,  170,
+
+      170,  170,  170,  170,  170,  170,  170,  170,  170
+    } ;
+
+static yy_state_type yy_last_accepting_state;
+static char *yy_last_accepting_cpos;
+
+/* The intent behind this definition is that it'll catch
+ * any uses of REJECT which flex missed.
+ */
+#define REJECT reject_used_but_not_detected
+static int yy_more_flag = 0;
+static int yy_more_len = 0;
+#define yymore() (yy_more_flag = 1)
+#define YY_MORE_ADJ yy_more_len
+#define YY_RESTORE_YY_MORE_OFFSET
+char *yytext;
+#line 1 "<stdin>"
+#define INITIAL 0
+#line 2 "<stdin>"
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+#include <kernel/mod2.h>
+#include <omalloc/omalloc.h>
+#include <Singular/tok.h>
+#include <Singular/stype.h>
+#include <Singular/ipshell.h>
+#include <Singular/fevoices.h>
+#include <kernel/oswrapper/feread.h>
+
+int feReadLine(char* b, int l);
+#define ALLOC(a) omAlloc((a))
+#ifndef NEW_FLEX
+#endif /* NEW_LEX */
+int blocknest = 0;
+extern char * yytext;
+//extern unsigned char * yytext;
+extern int yyleng;
+extern int inerror;
+
+// this is to  shadow the malloc/realloc
+// used by yy_flex_malloc/yy_flex_realloc
+// so that we can mark stuff as static
+static void* my_malloc(size_t size)
+{
+  void* addr = omAlloc(size);
+  omMarkAsStaticAddr(addr);
+  return addr;
+}
+
+static void* my_realloc(void* addr, size_t size)
+{
+  void* new_addr = omRealloc(addr, size);
+  omMarkAsStaticAddr(new_addr);
+  return new_addr;
+}
+static void my_free(void* addr)
+{
+  omFree(addr);
+}
+#undef malloc
+#define malloc my_malloc
+#undef realloc
+#define realloc my_realloc
+#undef free
+#define free my_free
+static char * dupyytext()
+{
+  char* s;
+  if (yyleng>0) yytext[yyleng-1] = '\0';
+  s = omStrDup((char *)yytext);
+  omMarkAsStaticAddr(s);
+  return s;
+}
+
+static char * dupyytextNL()
+{
+  int i = yyleng;//strlen((char *)yytext);
+  char * rc = (char*)omAlloc( 3 + i );
+  omMarkAsStaticAddr(rc);
+  if (i>0)
+  {
+    strncpy( rc, (char *)yytext, i-1 );
+  }
+  else
+  {
+    i++;
+  }
+  rc[i-1] = '\n';
+  rc[i] = '\n';
+  rc[i+1] = '\0';
+  return rc;
+}
+
+  #undef YY_DECL
+  #define YY_DECL int yylex(YYSTYPE* lvalp)
+
+  #undef yywrap
+  extern "C" {
+  int yywrap() { return exitVoice(); }
+  }
+
+  #undef YY_INPUT
+  #define YY_INPUT(buf,result,max_size) \
+          result = feReadLine( (char *) (buf), (max_size) )
+
+  #undef YY_USER_ACTION
+  #define YY_USER_ACTION \
+          if ((inerror==1)&&(*yytext>=' '))\
+          { Print("   skipping text from `%s`",yytext);inerror=2; }
+
+/* %start START */
+#define YY_ALWAYS_INTERACTIVE 1
+#define string 1
+
+#define block 2
+
+#define blockstr 3
+
+#define brace 4
+
+#define bracestr 5
+
+#define bracket 6
+
+#define asstring 7
+
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int yywrap YY_PROTO(( void ));
+#else
+extern int yywrap YY_PROTO(( void ));
+#endif
+#endif
+
+#ifndef YY_NO_UNPUT
+static void yyunput YY_PROTO(( int c, char *buf_ptr ));
+#endif
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy YY_PROTO(( char *, yyconst char *, int ));
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen YY_PROTO(( yyconst char * ));
+#endif
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+static int yyinput YY_PROTO(( void ));
+#else
+static int input YY_PROTO(( void ));
+#endif
+#endif
+
+#if YY_STACK_USED
+static int yy_start_stack_ptr = 0;
+static int yy_start_stack_depth = 0;
+static int *yy_start_stack = 0;
+#ifndef YY_NO_PUSH_STATE
+static void yy_push_state YY_PROTO(( int new_state ));
+#endif
+#ifndef YY_NO_POP_STATE
+static void yy_pop_state YY_PROTO(( void ));
+#endif
+#ifndef YY_NO_TOP_STATE
+static int yy_top_state YY_PROTO(( void ));
+#endif
+
+#else
+#define YY_NO_PUSH_STATE 1
+#define YY_NO_POP_STATE 1
+#define YY_NO_TOP_STATE 1
+#endif
+
+#ifdef YY_MALLOC_DECL
+YY_MALLOC_DECL
+#else
+#if __STDC__
+#ifndef __cplusplus
+#include <stdlib.h>
+#endif
+#else
+/* Just try to get by without declaring the routines.  This will fail
+ * miserably on non-ANSI systems for which sizeof(size_t) != sizeof(int)
+ * or sizeof(void*) != sizeof(int).
+ */
+#endif
+#endif
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#define YY_READ_BUF_SIZE 8192
+#endif
+
+/* Copy whatever the last rule matched to the standard output. */
+
+#ifndef ECHO
+/* This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+#define ECHO (void) fwrite( yytext, yyleng, 1, yyout )
+#endif
+
+/* Gets input and stuffs it into "buf".  number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+	if ( yy_current_buffer->yy_is_interactive ) \
+		{ \
+		int c = '*', n; \
+		for ( n = 0; n < max_size && \
+			     (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
+			buf[n] = (char) c; \
+		if ( c == '\n' ) \
+			buf[n++] = (char) c; \
+		if ( c == EOF && ferror( yyin ) ) \
+			YY_FATAL_ERROR( "input in flex scanner failed" ); \
+		result = n; \
+		} \
+	else if ( ((result = fread( buf, 1, max_size, yyin )) == 0) \
+		  && ferror( yyin ) ) \
+		YY_FATAL_ERROR( "input in flex scanner failed" );
+#endif
+
+/* No semi-colon after return; correct usage is to write "yyterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
+#endif
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL int yylex YY_PROTO(( void ))
+#endif
+
+/* Code executed at the beginning of each rule, after yytext and yyleng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_BREAK
+#define YY_BREAK break;
+#endif
+
+#define YY_RULE_SETUP \
+	if ( yyleng > 0 ) \
+		yy_current_buffer->yy_at_bol = \
+				(yytext[yyleng - 1] == '\n'); \
+	YY_USER_ACTION
+
+YY_DECL
+	{
+	register yy_state_type yy_current_state;
+	register char *yy_cp, *yy_bp;
+	register int yy_act;
+
+#line 121 "<stdin>"
+
+
+	if ( yy_init )
+		{
+		yy_init = 0;
+
+#ifdef YY_USER_INIT
+		YY_USER_INIT;
+#endif
+
+		if ( ! yy_start )
+			yy_start = 1;	/* first start state */
+
+		if ( ! yyin )
+			yyin = stdin;
+
+		if ( ! yyout )
+			yyout = stdout;
+
+		if ( ! yy_current_buffer )
+			yy_current_buffer =
+				yy_create_buffer( yyin, YY_BUF_SIZE );
+
+		yy_load_buffer_state();
+		}
+
+	while ( 1 )		/* loops until end-of-file is reached */
+		{
+		yy_more_len = 0;
+		if ( yy_more_flag )
+			{
+			yy_more_len = yy_c_buf_p - yytext_ptr;
+			yy_more_flag = 0;
+			}
+		yy_cp = yy_c_buf_p;
+
+		/* Support of yytext. */
+		*yy_cp = yy_hold_char;
+
+		/* yy_bp points to the position in yy_ch_buf of the start of
+		 * the current run.
+		 */
+		yy_bp = yy_cp;
+
+		yy_current_state = yy_start;
+		yy_current_state += YY_AT_BOL();
+yy_match:
+		do
+			{
+			register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
+			if ( yy_accept[yy_current_state] )
+				{
+				yy_last_accepting_state = yy_current_state;
+				yy_last_accepting_cpos = yy_cp;
+				}
+			while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+				{
+				yy_current_state = (int) yy_def[yy_current_state];
+				if ( yy_current_state >= 171 )
+					yy_c = yy_meta[(unsigned int) yy_c];
+				}
+			yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+			++yy_cp;
+			}
+		while ( yy_base[yy_current_state] != 561 );
+
+yy_find_action:
+		yy_act = yy_accept[yy_current_state];
+		if ( yy_act == 0 )
+			{ /* have to back up */
+			yy_cp = yy_last_accepting_cpos;
+			yy_current_state = yy_last_accepting_state;
+			yy_act = yy_accept[yy_current_state];
+			}
+
+		YY_DO_BEFORE_ACTION;
+
+
+do_action:	/* This label is used only to access EOF actions. */
+
+
+		switch ( yy_act )
+	{ /* beginning of action switch */
+			case 0: /* must back up */
+			/* undo the effects of YY_DO_BEFORE_ACTION */
+			*yy_cp = yy_hold_char;
+			yy_cp = yy_last_accepting_cpos;
+			yy_current_state = yy_last_accepting_state;
+			goto yy_find_action;
+
+case 1:
+YY_RULE_SETUP
+#line 122 "<stdin>"
+{ }
+	YY_BREAK
+case 2:
+YY_RULE_SETUP
+#line 123 "<stdin>"
+{ }
+	YY_BREAK
+case 3:
+YY_RULE_SETUP
+#line 124 "<stdin>"
+{
+                           yy_noeof=noeof_comment;
+                           loop
+                           {
+                             register int c;
+                             while ( (c = yyinput()) != '*' && c != EOF );
+                             if ( c == '*' )
+                             {
+                               while ( (c = yyinput()) == '*' );
+                               if ( c == '/' ) break; /* found the end */
+                             }
+                             else
+                             {
+                               break;
+                             }
+                           }
+                           yy_noeof=0;
+                         }
+	YY_BREAK
+case 4:
+YY_RULE_SETUP
+#line 142 "<stdin>"
+{ prompt_char='.';
+                           blocknest = 0; yy_noeof = noeof_brace; BEGIN(brace);
+                           return WHILE_CMD;}
+	YY_BREAK
+case 5:
+YY_RULE_SETUP
+#line 145 "<stdin>"
+{ prompt_char='.';
+                           blocknest = 0; yy_noeof = noeof_brace; BEGIN(brace);
+                           return FOR_CMD;}
+	YY_BREAK
+case 6:
+YY_RULE_SETUP
+#line 149 "<stdin>"
+{ yy_noeof = noeof_asstring;
+                           BEGIN(asstring);
+                           return HELP_CMD;
+                         }
+	YY_BREAK
+case 7:
+YY_RULE_SETUP
+#line 154 "<stdin>"
+{ yy_noeof = noeof_asstring;
+                           BEGIN(asstring);
+                           return EXAMPLE_CMD;
+                         }
+	YY_BREAK
+case 8:
+YY_RULE_SETUP
+#line 159 "<stdin>"
+{
+                           char c; char *cp;
+                           lvalp->name = omStrDup(iiProcName((char *)yytext,c,cp));
+                           yy_noeof = noeof_procname;
+                           blocknest = 1;
+                           BEGIN(brace);
+                           return PROC_DEF;
+                         }
+	YY_BREAK
+case 9:
+YY_RULE_SETUP
+#line 167 "<stdin>"
+{
+                           lvalp->name = omStrDup((char *)yytext);
+                           yy_noeof = 0; BEGIN(INITIAL);
+                           return STRINGTOK;
+                         }
+	YY_BREAK
+case 10:
+YY_RULE_SETUP
+#line 172 "<stdin>"
+{
+                           yy_noeof = 0; BEGIN(INITIAL);
+                           return *yytext;
+                         }
+	YY_BREAK
+case 11:
+YY_RULE_SETUP
+#line 177 "<stdin>"
+{
+                           yy_noeof = noeof_string;
+                           BEGIN(bracestr);
+                           yymore();
+                         }
+	YY_BREAK
+case 12:
+YY_RULE_SETUP
+#line 182 "<stdin>"
+{ if (blocknest++) yymore(); }
+	YY_BREAK
+case 13:
+YY_RULE_SETUP
+#line 183 "<stdin>"
+{ if (blocknest) yymore(); }
+	YY_BREAK
+case 14:
+YY_RULE_SETUP
+#line 184 "<stdin>"
+{
+                           if (blocknest)
+                           {
+                             lvalp->name = dupyytext();
+                             return STRINGTOK;
+                           }
+                         }
+	YY_BREAK
+case 15:
+YY_RULE_SETUP
+#line 191 "<stdin>"
+{
+                           if (--blocknest <= 0)
+                           {
+                             yy_noeof = 0;
+                             BEGIN(INITIAL);
+                             lvalp->name = dupyytext();
+                             return STRINGTOK;
+                           }
+                           yymore();
+                         }
+	YY_BREAK
+case 16:
+YY_RULE_SETUP
+#line 201 "<stdin>"
+{
+                           yy_noeof = noeof_brace;
+                           BEGIN(brace);
+                           yymore();
+                         }
+	YY_BREAK
+case 17:
+YY_RULE_SETUP
+#line 206 "<stdin>"
+{ yymore(); }
+	YY_BREAK
+case 18:
+YY_RULE_SETUP
+#line 207 "<stdin>"
+{ return '('; }
+	YY_BREAK
+case 19:
+YY_RULE_SETUP
+#line 208 "<stdin>"
+{ return ','; }
+	YY_BREAK
+case 20:
+YY_RULE_SETUP
+#line 209 "<stdin>"
+{ ; }
+	YY_BREAK
+case 21:
+YY_RULE_SETUP
+#line 210 "<stdin>"
+{
+                           lvalp->name = omStrDup((char *)yytext);
+                           return STRINGTOK;
+                         }
+	YY_BREAK
+case 22:
+YY_RULE_SETUP
+#line 214 "<stdin>"
+{
+                           lvalp->name = omStrDup((char *)yytext);
+                           return STRINGTOK;
+                         }
+	YY_BREAK
+case 23:
+YY_RULE_SETUP
+#line 218 "<stdin>"
+{
+                           yy_noeof = 0; BEGIN(INITIAL);
+                           return ')';
+                         }
+	YY_BREAK
+case 24:
+YY_RULE_SETUP
+#line 223 "<stdin>"
+{
+                           yy_blocklineno = yylineno;
+                           blocknest = 1;
+                           yy_noeof = noeof_block;
+                           BEGIN(block);
+                         }
+	YY_BREAK
+case 25:
+YY_RULE_SETUP
+#line 229 "<stdin>"
+{
+                           yy_noeof = noeof_string;
+                           BEGIN(blockstr);
+                           yymore();
+                         }
+	YY_BREAK
+case 26:
+YY_RULE_SETUP
+#line 234 "<stdin>"
+{ yymore(); }
+	YY_BREAK
+case 27:
+YY_RULE_SETUP
+#line 235 "<stdin>"
+{ yymore(); }
+	YY_BREAK
+case 28:
+YY_RULE_SETUP
+#line 236 "<stdin>"
+{ yymore(); }
+	YY_BREAK
+case 29:
+YY_RULE_SETUP
+#line 237 "<stdin>"
+{
+                           yy_noeof = noeof_block;
+                           BEGIN(block);
+                           yymore();
+                         }
+	YY_BREAK
+case 30:
+YY_RULE_SETUP
+#line 242 "<stdin>"
+{ yymore(); }
+	YY_BREAK
+case 31:
+YY_RULE_SETUP
+#line 243 "<stdin>"
+{ yymore(); }
+	YY_BREAK
+case 32:
+YY_RULE_SETUP
+#line 244 "<stdin>"
+{ blocknest++; yymore(); }
+	YY_BREAK
+case 33:
+YY_RULE_SETUP
+#line 245 "<stdin>"
+{
+                           if (--blocknest <= 0)
+                           {
+                             BEGIN(INITIAL);
+                             yy_noeof = 0;
+                             lvalp->name = dupyytextNL();
+                             return BLOCKTOK;
+                           }
+                           yymore();
+                         }
+	YY_BREAK
+case 34:
+YY_RULE_SETUP
+#line 255 "<stdin>"
+{ BEGIN(string); yy_noeof = noeof_string;}
+	YY_BREAK
+case 35:
+YY_RULE_SETUP
+#line 256 "<stdin>"
+{ return SYS_BREAK; }
+	YY_BREAK
+case 36:
+YY_RULE_SETUP
+#line 257 "<stdin>"
+{ yymore(); }
+	YY_BREAK
+case 37:
+YY_RULE_SETUP
+#line 258 "<stdin>"
+{ yymore(); }
+	YY_BREAK
+case 38:
+YY_RULE_SETUP
+#line 259 "<stdin>"
+{ yymore(); }
+	YY_BREAK
+case 39:
+YY_RULE_SETUP
+#line 260 "<stdin>"
+{
+                           char * s;
+                           yy_noeof = 0;
+                           BEGIN(INITIAL);
+                           s = lvalp->name = dupyytext();
+                           while (*yytext)
+                           {
+                             if (*yytext == '\\') yytext++;
+                             *s++ = *yytext++;
+                           }
+                           *s++ = *yytext++;
+                           return STRINGTOK;
+                         }
+	YY_BREAK
+case 40:
+YY_RULE_SETUP
+#line 274 "<stdin>"
+/* skip whitespace */
+	YY_BREAK
+case 41:
+YY_RULE_SETUP
+#line 275 "<stdin>"
+{ return DOTDOT; }
+	YY_BREAK
+case 42:
+YY_RULE_SETUP
+#line 276 "<stdin>"
+{ return COLONCOLON; }
+	YY_BREAK
+case 43:
+YY_RULE_SETUP
+#line 277 "<stdin>"
+{ return MINUSMINUS; }
+	YY_BREAK
+case 44:
+YY_RULE_SETUP
+#line 278 "<stdin>"
+{ return PLUSPLUS  ; }
+	YY_BREAK
+case 45:
+YY_RULE_SETUP
+#line 279 "<stdin>"
+{ return EQUAL_EQUAL; }
+	YY_BREAK
+case 46:
+YY_RULE_SETUP
+#line 280 "<stdin>"
+{ lvalp->i='&'; return LOGIC_OP; }
+	YY_BREAK
+case 47:
+YY_RULE_SETUP
+#line 281 "<stdin>"
+{ lvalp->i='|'; return LOGIC_OP; }
+	YY_BREAK
+case 48:
+YY_RULE_SETUP
+#line 282 "<stdin>"
+{ lvalp->i=LE; return COMP_OP; }
+	YY_BREAK
+case 49:
+YY_RULE_SETUP
+#line 283 "<stdin>"
+{ lvalp->i=GE; return COMP_OP; }
+	YY_BREAK
+case 50:
+YY_RULE_SETUP
+#line 284 "<stdin>"
+{ return NOT; }
+	YY_BREAK
+case 51:
+YY_RULE_SETUP
+#line 285 "<stdin>"
+{ return NOTEQUAL; }
+	YY_BREAK
+case 52:
+YY_RULE_SETUP
+#line 286 "<stdin>"
+{ return NOTEQUAL; }
+	YY_BREAK
+case 53:
+YY_RULE_SETUP
+#line 287 "<stdin>"
+{ return '^'; }
+	YY_BREAK
+case 54:
+YY_RULE_SETUP
+#line 288 "<stdin>"
+{ return ARROW; }
+	YY_BREAK
+case 55:
+YY_RULE_SETUP
+#line 289 "<stdin>"
+{ return '\\'; }
+	YY_BREAK
+case 56:
+YY_RULE_SETUP
+#line 290 "<stdin>"
+{
+                           lvalp->name = omStrDup("\n");
+                           return STRINGTOK;
+                         }
+	YY_BREAK
+case 57:
+YY_RULE_SETUP
+#line 294 "<stdin>"
+{
+                           lvalp->name = (char *)yytext;
+                           return INT_CONST;
+                         }
+	YY_BREAK
+case 58:
+YY_RULE_SETUP
+#line 298 "<stdin>"
+{
+                           lvalp->name = (char *)yytext;
+                           return RINGVAR;
+                         }
+	YY_BREAK
+case 59:
+YY_RULE_SETUP
+#line 302 "<stdin>"
+{
+                           m2_end(-1);
+                         }
+	YY_BREAK
+case 60:
+YY_RULE_SETUP
+#line 305 "<stdin>"
+{
+                           #ifdef MM_STAT
+                           mmStat(-500);
+                           #endif
+                           #ifdef OM_TRACK
+			   #ifndef SING_NDEBUG
+                             omPrintUsedTrackAddrs(stdout, 10);
+                           #endif
+                           #endif
+                           m2_end(0);
+                         }
+	YY_BREAK
+case 61:
+YY_RULE_SETUP
+#line 317 "<stdin>"
+{
+                           lvalp->name = (char *)yytext;
+                           return RINGVAR;
+                         }
+	YY_BREAK
+case 62:
+YY_RULE_SETUP
+#line 321 "<stdin>"
+{
+                           lvalp->name = (char *)yytext;
+                           return RINGVAR;
+                         }
+	YY_BREAK
+case 63:
+*yy_cp = yy_hold_char; /* undo effects of setting up yytext */
+yy_c_buf_p = yy_cp -= 1;
+YY_DO_BEFORE_ACTION; /* set up yytext again */
+YY_RULE_SETUP
+#line 325 "<stdin>"
+{
+                           lvalp->name = (char *)yytext;
+                           return RINGVAR;
+                         }
+	YY_BREAK
+case 64:
+YY_RULE_SETUP
+#line 330 "<stdin>"
+{
+                           /* {name} */
+                           int rc=0;
+                           if (yytext[strlen((char *)yytext)-1] == '\n')
+                           {
+                             yytext[strlen((char *)yytext)-1] = '\0';
+                           }
+                           if (yyleng > 1)
+                           {
+                             rc = IsCmd((char *)yytext,lvalp->i);
+                             if (rc) return rc;
+                           }
+                           lvalp->name = omStrDup((char *)yytext);
+                           return UNKNOWN_IDENT;
+                         }
+	YY_BREAK
+case 65:
+YY_RULE_SETUP
+#line 346 "<stdin>"
+{
+                           /*if (*yytext == '\n') REJECT;*/
+                           register char ch= *yytext;
+                           lvalp->i = ch;
+                           switch(ch)
+                           {
+                             /* case '&': */
+                             case '|':
+                               return LOGIC_OP;
+                             /* case '/': */
+                             case '%':
+                             case '*':
+                               return MULDIV_OP;
+                             /* case '<': */
+                             case '>':
+                               return COMP_OP;
+                             default:
+                               break;
+                            }
+                            return ch;
+                         }
+	YY_BREAK
+case 66:
+YY_RULE_SETUP
+#line 367 "<stdin>"
+YY_FATAL_ERROR( "flex scanner jammed" );
+	YY_BREAK
+case YY_STATE_EOF(INITIAL):
+case YY_STATE_EOF(string):
+case YY_STATE_EOF(block):
+case YY_STATE_EOF(blockstr):
+case YY_STATE_EOF(brace):
+case YY_STATE_EOF(bracestr):
+case YY_STATE_EOF(bracket):
+case YY_STATE_EOF(asstring):
+	yyterminate();
+
+	case YY_END_OF_BUFFER:
+		{
+		/* Amount of text matched not including the EOB char. */
+		int yy_amount_of_matched_text = (int) (yy_cp - yytext_ptr) - 1;
+
+		/* Undo the effects of YY_DO_BEFORE_ACTION. */
+		*yy_cp = yy_hold_char;
+		YY_RESTORE_YY_MORE_OFFSET
+
+		if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW )
+			{
+			/* We're scanning a new file or input source.  It's
+			 * possible that this happened because the user
+			 * just pointed yyin at a new source and called
+			 * yylex().  If so, then we have to assure
+			 * consistency between yy_current_buffer and our
+			 * globals.  Here is the right place to do so, because
+			 * this is the first action (other than possibly a
+			 * back-up) that will match for the new input source.
+			 */
+			yy_n_chars = yy_current_buffer->yy_n_chars;
+			yy_current_buffer->yy_input_file = yyin;
+			yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL;
+			}
+
+		/* Note that here we test for yy_c_buf_p "<=" to the position
+		 * of the first EOB in the buffer, since yy_c_buf_p will
+		 * already have been incremented past the NUL character
+		 * (since all states make transitions on EOB to the
+		 * end-of-buffer state).  Contrast this with the test
+		 * in input().
+		 */
+		if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] )
+			{ /* This was really a NUL. */
+			yy_state_type yy_next_state;
+
+			yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text;
+
+			yy_current_state = yy_get_previous_state();
+
+			/* Okay, we're now positioned to make the NUL
+			 * transition.  We couldn't have
+			 * yy_get_previous_state() go ahead and do it
+			 * for us because it doesn't know how to deal
+			 * with the possibility of jamming (and we don't
+			 * want to build jamming into it because then it
+			 * will run more slowly).
+			 */
+
+			yy_next_state = yy_try_NUL_trans( yy_current_state );
+
+			yy_bp = yytext_ptr + YY_MORE_ADJ;
+
+			if ( yy_next_state )
+				{
+				/* Consume the NUL. */
+				yy_cp = ++yy_c_buf_p;
+				yy_current_state = yy_next_state;
+				goto yy_match;
+				}
+
+			else
+				{
+				yy_cp = yy_c_buf_p;
+				goto yy_find_action;
+				}
+			}
+
+		else switch ( yy_get_next_buffer() )
+			{
+			case EOB_ACT_END_OF_FILE:
+				{
+				yy_did_buffer_switch_on_eof = 0;
+
+				if ( yywrap() )
+					{
+					/* Note: because we've taken care in
+					 * yy_get_next_buffer() to have set up
+					 * yytext, we can now set up
+					 * yy_c_buf_p so that if some total
+					 * hoser (like flex itself) wants to
+					 * call the scanner after we return the
+					 * YY_NULL, it'll still work - another
+					 * YY_NULL will get returned.
+					 */
+					yy_c_buf_p = yytext_ptr + YY_MORE_ADJ;
+
+					yy_act = YY_STATE_EOF(YY_START);
+					goto do_action;
+					}
+
+				else
+					{
+					if ( ! yy_did_buffer_switch_on_eof )
+						YY_NEW_FILE;
+					}
+				break;
+				}
+
+			case EOB_ACT_CONTINUE_SCAN:
+				yy_c_buf_p =
+					yytext_ptr + yy_amount_of_matched_text;
+
+				yy_current_state = yy_get_previous_state();
+
+				yy_cp = yy_c_buf_p;
+				yy_bp = yytext_ptr + YY_MORE_ADJ;
+				goto yy_match;
+
+			case EOB_ACT_LAST_MATCH:
+				yy_c_buf_p =
+				&yy_current_buffer->yy_ch_buf[yy_n_chars];
+
+				yy_current_state = yy_get_previous_state();
+
+				yy_cp = yy_c_buf_p;
+				yy_bp = yytext_ptr + YY_MORE_ADJ;
+				goto yy_find_action;
+			}
+		break;
+		}
+
+	default:
+		YY_FATAL_ERROR(
+			"fatal flex scanner internal error--no action found" );
+	} /* end of action switch */
+		} /* end of scanning one token */
+	} /* end of yylex */
+
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ *	EOB_ACT_LAST_MATCH -
+ *	EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ *	EOB_ACT_END_OF_FILE - end of file
+ */
+
+static int yy_get_next_buffer()
+	{
+	register char *dest = yy_current_buffer->yy_ch_buf;
+	register char *source = yytext_ptr;
+	register int number_to_move, i;
+	int ret_val;
+
+	if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] )
+		YY_FATAL_ERROR(
+		"fatal flex scanner internal error--end of buffer missed" );
+
+	if ( yy_current_buffer->yy_fill_buffer == 0 )
+		{ /* Don't try to fill the buffer, so this is an EOF. */
+		if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 )
+			{
+			/* We matched a single character, the EOB, so
+			 * treat this as a final EOF.
+			 */
+			return EOB_ACT_END_OF_FILE;
+			}
+
+		else
+			{
+			/* We matched some text prior to the EOB, first
+			 * process it.
+			 */
+			return EOB_ACT_LAST_MATCH;
+			}
+		}
+
+	/* Try to read more data. */
+
+	/* First move last chars to start of buffer. */
+	number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1;
+
+	for ( i = 0; i < number_to_move; ++i )
+		*(dest++) = *(source++);
+
+	if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+		/* don't do the read, it's not guaranteed to return an EOF,
+		 * just force an EOF
+		 */
+		yy_current_buffer->yy_n_chars = yy_n_chars = 0;
+
+	else
+		{
+		int num_to_read =
+			yy_current_buffer->yy_buf_size - number_to_move - 1;
+
+		while ( num_to_read <= 0 )
+			{ /* Not enough room in the buffer - grow it. */
+#ifdef YY_USES_REJECT
+			YY_FATAL_ERROR(
+"input buffer overflow, can't enlarge buffer because scanner uses REJECT" );
+#else
+
+			/* just a shorter name for the current buffer */
+			YY_BUFFER_STATE b = yy_current_buffer;
+
+			int yy_c_buf_p_offset =
+				(int) (yy_c_buf_p - b->yy_ch_buf);
+
+			if ( b->yy_is_our_buffer )
+				{
+				int new_size = b->yy_buf_size * 2;
+
+				if ( new_size <= 0 )
+					b->yy_buf_size += b->yy_buf_size / 8;
+				else
+					b->yy_buf_size *= 2;
+
+				b->yy_ch_buf = (char *)
+					/* Include room in for 2 EOB chars. */
+					yy_flex_realloc( (void *) b->yy_ch_buf,
+							 b->yy_buf_size + 2 );
+				}
+			else
+				/* Can't grow it, we don't own it. */
+				b->yy_ch_buf = 0;
+
+			if ( ! b->yy_ch_buf )
+				YY_FATAL_ERROR(
+				"fatal error - scanner input buffer overflow" );
+
+			yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset];
+
+			num_to_read = yy_current_buffer->yy_buf_size -
+						number_to_move - 1;
+#endif
+			}
+
+		if ( num_to_read > YY_READ_BUF_SIZE )
+			num_to_read = YY_READ_BUF_SIZE;
+
+		/* Read in more data. */
+		YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]),
+			yy_n_chars, num_to_read );
+
+		yy_current_buffer->yy_n_chars = yy_n_chars;
+		}
+
+	if ( yy_n_chars == 0 )
+		{
+		if ( number_to_move == YY_MORE_ADJ )
+			{
+			ret_val = EOB_ACT_END_OF_FILE;
+			yyrestart( yyin );
+			}
+
+		else
+			{
+			ret_val = EOB_ACT_LAST_MATCH;
+			yy_current_buffer->yy_buffer_status =
+				YY_BUFFER_EOF_PENDING;
+			}
+		}
+
+	else
+		ret_val = EOB_ACT_CONTINUE_SCAN;
+
+	yy_n_chars += number_to_move;
+	yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR;
+	yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
+
+	yytext_ptr = &yy_current_buffer->yy_ch_buf[0];
+
+	return ret_val;
+	}
+
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+static yy_state_type yy_get_previous_state()
+	{
+	register yy_state_type yy_current_state;
+	register char *yy_cp;
+
+	yy_current_state = yy_start;
+	yy_current_state += YY_AT_BOL();
+
+	for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp )
+		{
+		register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
+		if ( yy_accept[yy_current_state] )
+			{
+			yy_last_accepting_state = yy_current_state;
+			yy_last_accepting_cpos = yy_cp;
+			}
+		while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+			{
+			yy_current_state = (int) yy_def[yy_current_state];
+			if ( yy_current_state >= 171 )
+				yy_c = yy_meta[(unsigned int) yy_c];
+			}
+		yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+		}
+
+	return yy_current_state;
+	}
+
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ *	next_state = yy_try_NUL_trans( current_state );
+ */
+
+#ifdef YY_USE_PROTOS
+static yy_state_type yy_try_NUL_trans( yy_state_type yy_current_state )
+#else
+static yy_state_type yy_try_NUL_trans( yy_current_state )
+yy_state_type yy_current_state;
+#endif
+	{
+	register int yy_is_jam;
+	register char *yy_cp = yy_c_buf_p;
+
+	register YY_CHAR yy_c = 1;
+	if ( yy_accept[yy_current_state] )
+		{
+		yy_last_accepting_state = yy_current_state;
+		yy_last_accepting_cpos = yy_cp;
+		}
+	while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+		{
+		yy_current_state = (int) yy_def[yy_current_state];
+		if ( yy_current_state >= 171 )
+			yy_c = yy_meta[(unsigned int) yy_c];
+		}
+	yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+	yy_is_jam = (yy_current_state == 170);
+
+	return yy_is_jam ? 0 : yy_current_state;
+	}
+
+
+#ifndef YY_NO_UNPUT
+#ifdef YY_USE_PROTOS
+static void yyunput( int c, register char *yy_bp )
+#else
+static void yyunput( c, yy_bp )
+int c;
+register char *yy_bp;
+#endif
+	{
+	register char *yy_cp = yy_c_buf_p;
+
+	/* undo effects of setting up yytext */
+	*yy_cp = yy_hold_char;
+
+	if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
+		{ /* need to shift things up to make room */
+		/* +2 for EOB chars. */
+		register int number_to_move = yy_n_chars + 2;
+		register char *dest = &yy_current_buffer->yy_ch_buf[
+					yy_current_buffer->yy_buf_size + 2];
+		register char *source =
+				&yy_current_buffer->yy_ch_buf[number_to_move];
+
+		while ( source > yy_current_buffer->yy_ch_buf )
+			*--dest = *--source;
+
+		yy_cp += (int) (dest - source);
+		yy_bp += (int) (dest - source);
+		yy_current_buffer->yy_n_chars =
+			yy_n_chars = yy_current_buffer->yy_buf_size;
+
+		if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
+			YY_FATAL_ERROR( "flex scanner push-back overflow" );
+		}
+
+	*--yy_cp = (char) c;
+
+
+	yytext_ptr = yy_bp;
+	yy_hold_char = *yy_cp;
+	yy_c_buf_p = yy_cp;
+	}
+#endif	/* ifndef YY_NO_UNPUT */
+
+
+#ifdef __cplusplus
+static int yyinput()
+#else
+static int input()
+#endif
+	{
+	int c;
+
+	*yy_c_buf_p = yy_hold_char;
+
+	if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR )
+		{
+		/* yy_c_buf_p now points to the character we want to return.
+		 * If this occurs *before* the EOB characters, then it's a
+		 * valid NUL; if not, then we've hit the end of the buffer.
+		 */
+		if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] )
+			/* This was really a NUL. */
+			*yy_c_buf_p = '\0';
+
+		else
+			{ /* need more input */
+			int offset = yy_c_buf_p - yytext_ptr;
+			++yy_c_buf_p;
+
+			switch ( yy_get_next_buffer() )
+				{
+				case EOB_ACT_LAST_MATCH:
+					/* This happens because yy_g_n_b()
+					 * sees that we've accumulated a
+					 * token and flags that we need to
+					 * try matching the token before
+					 * proceeding.  But for input(),
+					 * there's no matching to consider.
+					 * So convert the EOB_ACT_LAST_MATCH
+					 * to EOB_ACT_END_OF_FILE.
+					 */
+
+					/* Reset buffer status. */
+					yyrestart( yyin );
+
+					/* fall through */
+
+				case EOB_ACT_END_OF_FILE:
+					{
+					if ( yywrap() )
+						return EOF;
+
+					if ( ! yy_did_buffer_switch_on_eof )
+						YY_NEW_FILE;
+#ifdef __cplusplus
+					return yyinput();
+#else
+					return input();
+#endif
+					}
+
+				case EOB_ACT_CONTINUE_SCAN:
+					yy_c_buf_p = yytext_ptr + offset;
+					break;
+				}
+			}
+		}
+
+	c = *(unsigned char *) yy_c_buf_p;	/* cast for 8-bit char's */
+	*yy_c_buf_p = '\0';	/* preserve yytext */
+	yy_hold_char = *++yy_c_buf_p;
+
+	yy_current_buffer->yy_at_bol = (c == '\n');
+
+	return c;
+	}
+
+
+#ifdef YY_USE_PROTOS
+void yyrestart( FILE *input_file )
+#else
+void yyrestart( input_file )
+FILE *input_file;
+#endif
+	{
+	if ( ! yy_current_buffer )
+		yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE );
+
+	yy_init_buffer( yy_current_buffer, input_file );
+	yy_load_buffer_state();
+	}
+
+
+#ifdef YY_USE_PROTOS
+void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer )
+#else
+void yy_switch_to_buffer( new_buffer )
+YY_BUFFER_STATE new_buffer;
+#endif
+	{
+	if ( yy_current_buffer == new_buffer )
+		return;
+
+	if ( yy_current_buffer )
+		{
+		/* Flush out information for old buffer. */
+		*yy_c_buf_p = yy_hold_char;
+		yy_current_buffer->yy_buf_pos = yy_c_buf_p;
+		yy_current_buffer->yy_n_chars = yy_n_chars;
+		}
+
+	yy_current_buffer = new_buffer;
+	yy_load_buffer_state();
+
+	/* We don't actually know whether we did this switch during
+	 * EOF (yywrap()) processing, but the only time this flag
+	 * is looked at is after yywrap() is called, so it's safe
+	 * to go ahead and always set it.
+	 */
+	yy_did_buffer_switch_on_eof = 1;
+	}
+
+
+#ifdef YY_USE_PROTOS
+void yy_load_buffer_state( void )
+#else
+void yy_load_buffer_state()
+#endif
+	{
+	yy_n_chars = yy_current_buffer->yy_n_chars;
+	yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos;
+	yyin = yy_current_buffer->yy_input_file;
+	yy_hold_char = *yy_c_buf_p;
+	}
+
+
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_create_buffer( FILE *file, int size )
+#else
+YY_BUFFER_STATE yy_create_buffer( file, size )
+FILE *file;
+int size;
+#endif
+	{
+	YY_BUFFER_STATE b;
+
+	b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) );
+	if ( ! b )
+		YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+	b->yy_buf_size = size;
+
+	/* yy_ch_buf has to be 2 characters longer than the size given because
+	 * we need to put in 2 end-of-buffer characters.
+	 */
+	b->yy_ch_buf = (char *) yy_flex_alloc( b->yy_buf_size + 2 );
+	if ( ! b->yy_ch_buf )
+		YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+	b->yy_is_our_buffer = 1;
+
+	yy_init_buffer( b, file );
+
+	return b;
+	}
+
+
+#ifdef YY_USE_PROTOS
+void yy_delete_buffer( YY_BUFFER_STATE b )
+#else
+void yy_delete_buffer( b )
+YY_BUFFER_STATE b;
+#endif
+	{
+	if ( ! b )
+		return;
+
+	if ( b == yy_current_buffer )
+		yy_current_buffer = (YY_BUFFER_STATE) 0;
+
+	if ( b->yy_is_our_buffer )
+		yy_flex_free( (void *) b->yy_ch_buf );
+
+	yy_flex_free( (void *) b );
+	}
+
+
+#ifndef YY_ALWAYS_INTERACTIVE
+#ifndef YY_NEVER_INTERACTIVE
+extern int isatty YY_PROTO(( int ));
+#endif
+#endif
+
+#ifdef YY_USE_PROTOS
+void yy_init_buffer( YY_BUFFER_STATE b, FILE *file )
+#else
+void yy_init_buffer( b, file )
+YY_BUFFER_STATE b;
+FILE *file;
+#endif
+
+
+	{
+	yy_flush_buffer( b );
+
+	b->yy_input_file = file;
+	b->yy_fill_buffer = 1;
+
+#if YY_ALWAYS_INTERACTIVE
+	b->yy_is_interactive = 1;
+#else
+#if YY_NEVER_INTERACTIVE
+	b->yy_is_interactive = 0;
+#else
+	b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
+#endif
+#endif
+	}
+
+
+#ifdef YY_USE_PROTOS
+void yy_flush_buffer( YY_BUFFER_STATE b )
+#else
+void yy_flush_buffer( b )
+YY_BUFFER_STATE b;
+#endif
+
+	{
+	if ( ! b )
+		return;
+
+	b->yy_n_chars = 0;
+
+	/* We always need two end-of-buffer characters.  The first causes
+	 * a transition to the end-of-buffer state.  The second causes
+	 * a jam in that state.
+	 */
+	b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+	b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+	b->yy_buf_pos = &b->yy_ch_buf[0];
+
+	b->yy_at_bol = 1;
+	b->yy_buffer_status = YY_BUFFER_NEW;
+
+	if ( b == yy_current_buffer )
+		yy_load_buffer_state();
+	}
+
+
+#ifndef YY_NO_SCAN_BUFFER
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_buffer( char *base, yy_size_t size )
+#else
+YY_BUFFER_STATE yy_scan_buffer( base, size )
+char *base;
+yy_size_t size;
+#endif
+	{
+	YY_BUFFER_STATE b;
+
+	if ( size < 2 ||
+	     base[size-2] != YY_END_OF_BUFFER_CHAR ||
+	     base[size-1] != YY_END_OF_BUFFER_CHAR )
+		/* They forgot to leave room for the EOB's. */
+		return 0;
+
+	b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) );
+	if ( ! b )
+		YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
+
+	b->yy_buf_size = size - 2;	/* "- 2" to take care of EOB's */
+	b->yy_buf_pos = b->yy_ch_buf = base;
+	b->yy_is_our_buffer = 0;
+	b->yy_input_file = 0;
+	b->yy_n_chars = b->yy_buf_size;
+	b->yy_is_interactive = 0;
+	b->yy_at_bol = 1;
+	b->yy_fill_buffer = 0;
+	b->yy_buffer_status = YY_BUFFER_NEW;
+
+	yy_switch_to_buffer( b );
+
+	return b;
+	}
+#endif
+
+
+#ifndef YY_NO_SCAN_STRING
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_string( yyconst char *yy_str )
+#else
+YY_BUFFER_STATE yy_scan_string( yy_str )
+yyconst char *yy_str;
+#endif
+	{
+	int len;
+	for ( len = 0; yy_str[len]; ++len )
+		;
+
+	return yy_scan_bytes( yy_str, len );
+	}
+#endif
+
+
+#ifndef YY_NO_SCAN_BYTES
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_bytes( yyconst char *bytes, int len )
+#else
+YY_BUFFER_STATE yy_scan_bytes( bytes, len )
+yyconst char *bytes;
+int len;
+#endif
+	{
+	YY_BUFFER_STATE b;
+	char *buf;
+	yy_size_t n;
+	int i;
+
+	/* Get memory for full buffer, including space for trailing EOB's. */
+	n = len + 2;
+	buf = (char *) yy_flex_alloc( n );
+	if ( ! buf )
+		YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
+
+	for ( i = 0; i < len; ++i )
+		buf[i] = bytes[i];
+
+	buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR;
+
+	b = yy_scan_buffer( buf, n );
+	if ( ! b )
+		YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
+
+	/* It's okay to grow etc. this buffer, and we should throw it
+	 * away when we're done.
+	 */
+	b->yy_is_our_buffer = 1;
+
+	return b;
+	}
+#endif
+
+
+#ifndef YY_NO_PUSH_STATE
+#ifdef YY_USE_PROTOS
+static void yy_push_state( int new_state )
+#else
+static void yy_push_state( new_state )
+int new_state;
+#endif
+	{
+	if ( yy_start_stack_ptr >= yy_start_stack_depth )
+		{
+		yy_size_t new_size;
+
+		yy_start_stack_depth += YY_START_STACK_INCR;
+		new_size = yy_start_stack_depth * sizeof( int );
+
+		if ( ! yy_start_stack )
+			yy_start_stack = (int *) yy_flex_alloc( new_size );
+
+		else
+			yy_start_stack = (int *) yy_flex_realloc(
+					(void *) yy_start_stack, new_size );
+
+		if ( ! yy_start_stack )
+			YY_FATAL_ERROR(
+			"out of memory expanding start-condition stack" );
+		}
+
+	yy_start_stack[yy_start_stack_ptr++] = YY_START;
+
+	BEGIN(new_state);
+	}
+#endif
+
+
+#ifndef YY_NO_POP_STATE
+static void yy_pop_state()
+	{
+	if ( --yy_start_stack_ptr < 0 )
+		YY_FATAL_ERROR( "start-condition stack underflow" );
+
+	BEGIN(yy_start_stack[yy_start_stack_ptr]);
+	}
+#endif
+
+
+#ifndef YY_NO_TOP_STATE
+static int yy_top_state()
+	{
+	return yy_start_stack[yy_start_stack_ptr - 1];
+	}
+#endif
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+#ifdef YY_USE_PROTOS
+static void yy_fatal_error( yyconst char msg[] )
+#else
+static void yy_fatal_error( msg )
+char msg[];
+#endif
+	{
+	(void) fprintf( stderr, "%s\n", msg );
+	exit( YY_EXIT_FAILURE );
+	}
+
+
+
+/* Redefine yyless() so it works in section 3 code. */
+
+#undef yyless
+#define yyless(n) \
+	do \
+		{ \
+		/* Undo effects of setting up yytext. */ \
+		yytext[yyleng] = yy_hold_char; \
+		yy_c_buf_p = yytext + n; \
+		yy_hold_char = *yy_c_buf_p; \
+		*yy_c_buf_p = '\0'; \
+		yyleng = n; \
+		} \
+	while ( 0 )
+
+
+/* Internal utility routines. */
+
+#ifndef yytext_ptr
+#ifdef YY_USE_PROTOS
+static void yy_flex_strncpy( char *s1, yyconst char *s2, int n )
+#else
+static void yy_flex_strncpy( s1, s2, n )
+char *s1;
+yyconst char *s2;
+int n;
+#endif
+	{
+	register int i;
+	for ( i = 0; i < n; ++i )
+		s1[i] = s2[i];
+	}
+#endif
+
+#ifdef YY_NEED_STRLEN
+#ifdef YY_USE_PROTOS
+static int yy_flex_strlen( yyconst char *s )
+#else
+static int yy_flex_strlen( s )
+yyconst char *s;
+#endif
+	{
+	register int n;
+	for ( n = 0; s[n]; ++n )
+		;
+
+	return n;
+	}
+#endif
+
+
+#ifdef YY_USE_PROTOS
+static void *yy_flex_alloc( yy_size_t size )
+#else
+static void *yy_flex_alloc( size )
+yy_size_t size;
+#endif
+	{
+	return (void *) malloc( size );
+	}
+
+#ifdef YY_USE_PROTOS
+static void *yy_flex_realloc( void *ptr, yy_size_t size )
+#else
+static void *yy_flex_realloc( ptr, size )
+void *ptr;
+yy_size_t size;
+#endif
+	{
+	/* The cast to (char *) in the following accommodates both
+	 * implementations that use char* generic pointers, and those
+	 * that use void* generic pointers.  It works with the latter
+	 * because both ANSI C and C++ allow castless assignment from
+	 * any pointer type to void*, and deal with argument conversions
+	 * as though doing an assignment.
+	 */
+	return (void *) realloc( (char *) ptr, size );
+	}
+
+#ifdef YY_USE_PROTOS
+static void yy_flex_free( void *ptr )
+#else
+static void yy_flex_free( ptr )
+void *ptr;
+#endif
+	{
+	free( ptr );
+	}
+
+#if YY_MAIN
+int main()
+	{
+	yylex();
+	return 0;
+	}
+#endif
+#line 367 "<stdin>"
+
+
+void * myynewbuffer()
+{
+  void * oldb = YY_CURRENT_BUFFER;
+  yy_switch_to_buffer(yy_create_buffer(NULL, YY_BUF_SIZE));
+  return oldb;
+}
+
+void myyoldbuffer(void * oldb)
+{
+  yy_delete_buffer(YY_CURRENT_BUFFER);
+  yy_switch_to_buffer((YY_BUFFER_STATE)oldb);
+  //yy_flush_buffer((YY_BUFFER_STATE)oldb);
+}
diff --git a/Singular/sdb.cc b/Singular/sdb.cc
new file mode 100644
index 0000000..9a2c715
--- /dev/null
+++ b/Singular/sdb.cc
@@ -0,0 +1,325 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: Singular debugger
+*/
+
+#include <kernel/mod2.h>
+#include <omalloc/omalloc.h>
+#include <misc/options.h>
+#include <reporter/si_signals.h>
+
+#include <Singular/tok.h>
+#include <Singular/ipshell.h>
+#include <Singular/ipid.h>
+#include <Singular/fevoices.h>
+#include <kernel/oswrapper/feread.h>
+#include <Singular/sdb.h>
+
+#include <unistd.h>   // for unlink,fork,execlp,getpid
+#include <sys/wait.h> // for wait
+
+
+#ifdef HAVE_SDB
+// We use 8 breakpoints - corresponding to a bit in a char variable in procinfo
+// bit 1..7 force a breakpoint, if lineno==sdb_lines[i-1],
+//                         (for displaying only: file sdb_files[i-1])
+// bit 0 force a breakpoint in every line (used for 'n')
+
+int sdb_lines[]={-1,-1,-1,-1,-1,-1,-1,-1};
+char * sdb_files[6];
+int sdb_flags=0;
+
+int sdb_checkline(char f)
+{
+  int i;
+  char ff=f>>1;
+  for(i=0;i<7;i++)
+  {
+    if((ff & 1) && (yylineno==sdb_lines[i]))
+      return i+1;
+    ff>>=1;
+    if (ff==0) return 0;
+  }
+  return 0;
+}
+
+static char *sdb_find_arg(char *p)
+{
+  p++;
+  while (*p==' ') p++;
+  char *pp=p;
+  while (*pp>' ') pp++;
+  *pp='\0';
+  return p;
+}
+
+void sdb_show_bp()
+{
+  for(int i=0; i<7;i++)
+    if (sdb_lines[i]!= -1)
+      Print("Breakpoint %d: %s::%d\n",i+1,sdb_files[i],sdb_lines[i]);
+}
+
+BOOLEAN sdb_set_breakpoint(const char *pp, int given_lineno)
+{
+  idhdl h=ggetid(pp);
+  if ((h==NULL)||(IDTYP(h)!=PROC_CMD))
+  {
+    PrintS(" not found\n");
+    return TRUE;
+  }
+  else
+  {
+    procinfov p=(procinfov)IDDATA(h);
+    #ifdef HAVE_DYNAMIC_LOADING
+    if (p->language!=LANG_SINGULAR)
+    {
+      PrintS("is not a Singular procedure\n");
+      return TRUE;
+    }
+    #endif
+    int lineno;
+    if (given_lineno >0) lineno=given_lineno;
+    else                 lineno=p->data.s.body_lineno;
+    int i;
+    if (given_lineno== -1)
+    {
+      i=p->trace_flag;
+      p->trace_flag &=1;
+      Print("breakpoints in %s deleted(%#x)\n",p->procname,i &255);
+      return FALSE;
+    }
+    i=0;
+    while((i<7) && (sdb_lines[i]!=-1)) i++;
+    if (sdb_lines[i]!= -1)
+    {
+      PrintS("too many breakpoints set, max is 7\n");
+      return TRUE;
+    }
+    sdb_lines[i]=lineno;
+    sdb_files[i]=p->libname;
+    i++;
+    p->trace_flag|=(1<<i);
+    Print("breakpoint %d, at line %d in %s\n",i,lineno,p->procname);
+    return FALSE;
+  }
+}
+
+void sdb_edit(procinfo *pi)
+{
+  char * filename = omStrDup("/tmp/sd000000");
+  sprintf(filename+7,"%d",getpid());
+  FILE *fp=fopen(filename,"w");
+  if (fp==NULL)
+  {
+    Print("cannot open %s\n",filename);
+    omFree(filename);
+    return;
+  }
+  if (pi->language!= LANG_SINGULAR)
+  {
+    Print("cannot edit type %d\n",pi->language);
+    fclose(fp);
+    fp=NULL;
+  }
+  else
+  {
+    const char *editor=getenv("EDITOR");
+    if (editor==NULL)
+      editor=getenv("VISUAL");
+    if (editor==NULL)
+      editor="vi";
+    editor=omStrDup(editor);
+
+    if (pi->data.s.body==NULL)
+    {
+      iiGetLibProcBuffer(pi);
+      if (pi->data.s.body==NULL)
+      {
+        PrintS("cannot get the procedure body\n");
+        fclose(fp);
+        si_unlink(filename);
+        omFree(filename);
+        return;
+      }
+    }
+
+    fwrite(pi->data.s.body,1,strlen(pi->data.s.body),fp);
+    fclose(fp);
+
+    int pid=fork();
+    if (pid!=0)
+    {
+      si_wait(&pid);
+    }
+    else if(pid==0)
+    {
+      if (strchr(editor,' ')==NULL)
+      {
+        execlp(editor,editor,filename,NULL);
+        Print("cannot exec %s\n",editor);
+      }
+      else
+      {
+        char *p=(char *)omAlloc(strlen(editor)+strlen(filename)+2);
+        sprintf(p,"%s %s",editor,filename);
+        system(p);
+      }
+      exit(0);
+    }
+    else
+    {
+      PrintS("cannot fork\n");
+    }
+
+    fp=fopen(filename,"r");
+    if (fp==NULL)
+    {
+      Print("cannot read from %s\n",filename);
+    }
+    else
+    {
+      fseek(fp,0L,SEEK_END);
+      long len=ftell(fp);
+      fseek(fp,0L,SEEK_SET);
+
+      omFree((ADDRESS)pi->data.s.body);
+      pi->data.s.body=(char *)omAlloc((int)len+1);
+      myfread( pi->data.s.body, len, 1, fp);
+      pi->data.s.body[len]='\0';
+      fclose(fp);
+    }
+  }
+  si_unlink(filename);
+  omFree(filename);
+}
+
+static char sdb_lastcmd='c';
+
+void sdb(Voice * currentVoice, const char * currLine, int len)
+{
+  int bp=0;
+  if ((len>1)
+  && ((currentVoice->pi->trace_flag & 1)
+    || (bp=sdb_checkline(currentVoice->pi->trace_flag)))
+  )
+  {
+    loop
+    {
+      char gdb[80];
+      char *p=(char *)currLine+len-1;
+      while ((*p<=' ') && (p!=currLine))
+      {
+        p--; len--;
+      }
+      if (p==currLine) return;
+
+      currentVoice->pi->trace_flag&= ~1; // delete flag for "all lines"
+      Print("(%s,%d) >>",currentVoice->filename,yylineno);
+      fwrite(currLine,1,len,stdout);
+      Print("<<\nbreakpoint %d (press ? for list of commands)\n",bp);
+      p=fe_fgets_stdin(">>",gdb,80);
+      while (*p==' ') p++;
+      if (*p >' ')
+      {
+        sdb_lastcmd=*p;
+      }
+      Print("command:%c\n",sdb_lastcmd);
+      switch(sdb_lastcmd)
+      {
+        case '?':
+        case 'h':
+        {
+          PrintS(
+          "b - print backtrace of calling stack\n"
+          "B <proc> [<line>] - define breakpoint\n"
+          "c - continue\n"
+          "d - delete current breakpoint\n"
+          "D - show all breakpoints\n"
+          "e - edit the current procedure (current call will be aborted)\n"
+          "h,? - display this help screen\n"
+          "n - execute current line, break at next line\n"
+          "p <var> - display type and value of the variable <var>\n"
+          "q <flags> - quit debugger, set debugger flags(0,1,2)\n"
+          "Q - quit Singular\n");
+          int i;
+          for(i=0;i<7;i++)
+          {
+            if (sdb_lines[i] != -1)
+              Print("breakpoint %d at line %d in %s\n",
+                i,sdb_lines[i],sdb_files[i]);
+          }
+          break;
+        }
+        case 'd':
+        {
+          Print("delete break point %d\n",bp);
+          currentVoice->pi->trace_flag &= (~Sy_bit(bp));
+          if (bp!=0)
+          {
+            sdb_lines[bp-1]=-1;
+          }
+          break;
+        }
+        case 'D':
+          sdb_show_bp();
+          break;
+        case 'n':
+          currentVoice->pi->trace_flag|= 1;
+          return;
+        case 'e':
+        {
+          sdb_edit(currentVoice->pi);
+          sdb_flags=2;
+          return;
+        }
+        case 'p':
+        {
+          p=sdb_find_arg(p);
+          Print("variable `%s`",p);
+          idhdl h=ggetid(p);
+          if (h==NULL)
+            PrintS(" not found\n");
+          else
+          {
+            sleftv tmp;
+            memset(&tmp,0,sizeof(tmp));
+            tmp.rtyp=IDHDL;
+            tmp.data=h;
+            Print("(type %s):\n",Tok2Cmdname(tmp.Typ()));
+            tmp.Print();
+          }
+          break;
+        }
+        case 'b':
+          VoiceBackTrack();
+          break;
+        case 'B':
+        {
+          p=sdb_find_arg(p);
+          Print("procedure `%s` ",p);
+          sdb_set_breakpoint(p);
+          break;
+        }
+        case 'q':
+        {
+          p=sdb_find_arg(p);
+          if (*p!='\0')
+          {
+            sdb_flags=atoi(p);
+            Print("new sdb_flags:%d\n",sdb_flags);
+          }
+          return;
+        }
+        case 'Q':
+          m2_end(999);
+        case 'c':
+        default:
+          return;
+      }
+    }
+  }
+}
+#endif
diff --git a/Singular/sdb.h b/Singular/sdb.h
new file mode 100644
index 0000000..a2cdef3
--- /dev/null
+++ b/Singular/sdb.h
@@ -0,0 +1,25 @@
+#ifndef SDB_H
+#define SDB_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: Singular debugger
+*/
+
+#define HAVE_SDB
+
+#ifdef HAVE_SDB
+#include <kernel/structs.h>
+
+extern int    sdb_lines[];
+extern char * sdb_files[];
+extern int    sdb_flags;
+
+void sdb_edit(procinfo *pi);
+void sdb_show_bp();
+BOOLEAN sdb_set_breakpoint(const char *p, int lineno=0);
+void sdb(Voice * currentVoice, const char * currLine, int len);
+#endif
+#endif
+
diff --git a/Singular/singular-libs b/Singular/singular-libs
new file mode 100644
index 0000000..2646c50
--- /dev/null
+++ b/Singular/singular-libs
@@ -0,0 +1,63 @@
+#
+# Singular libraries which go into distribution
+# (they should be ordered alphabetically)
+# MAKE SURE THAT THIS IS UP_TO_DATE
+# and use:
+# svn propset svn:keywords "Id" yourlib.lib
+# for new libs
+#
+
+SLIB0 = absfact.lib ainvar.lib aksaka.lib alexpoly.lib algebra.lib \
+	arcpoint.lib assprimeszerodim.lib atkins.lib brnoeth.lib \
+	cisimplicial.lib classify.lib \
+	compregb.lib control.lib crypto.lib curvepar.lib decodegb.lib \
+	deform.lib elim.lib  equising.lib  finvar.lib  general.lib gmspoly.lib \
+	gmssing.lib graphics.lib grobcov.lib groups.lib grwalk.lib \
+	hnoether.lib \
+	homolog.lib hyperel.lib integralbasis.lib inout.lib intprog.lib \
+	jacobson.lib \
+	kskernel.lib latex.lib linalg.lib makedbm.lib \
+	matrix.lib modstd.lib mondromy.lib monomialideal.lib \
+	mprimdec.lib mregular.lib \
+	noether.lib normal.lib normaliz.lib ntsolve.lib \
+	paraplanecurves.lib phindex.lib \
+	pointid.lib poly.lib \
+	presolve.lib primdec.lib primdecint.lib \
+	primitiv.lib qhmoduli.lib random.lib realclassify.lib \
+	realrad.lib reesclos.lib resbinomial.lib \
+	resgraph.lib resjung.lib resolve.lib \
+	reszeta.lib ring.lib rinvar.lib rootsmr.lib rootsur.lib \
+	sagbi.lib sheafcoh.lib sing.lib sing4ti2.lib signcond.lib \
+	solve.lib spcurve.lib spectrum.lib standard.lib stratify.lib \
+	surf.lib surfacesignature.lib surfex.lib \
+	teachstd.lib toric.lib triang.lib \
+	weierstr.lib zeroset.lib
+
+# libs in beta testing:
+# the will be included in share.tar.gz, but not in all.lib
+# (they should be ordered alphabetically)
+# and use:
+# svn propset svn:keywords "Id" yourlib.lib
+# for new libs
+
+SLIB1 = classifyceq.lib classifyci.lib classify_aeq.lib algemodstd.lib \
+        dmodloc.lib divisors.lib \
+        ffsolve.lib decomp.lib template.lib \
+        findifs.lib finitediff.lib \
+        gitfan.lib \
+        locnormal.lib modnormal.lib modular.lib \
+	JMBTest.lib JMSConst.lib multigrading.lib\
+	numerAlg.lib numerDecom.lib \
+        orbitparam.lib parallel.lib polymake.lib\
+	realizationMatroids.lib resources.lib ringgb.lib \
+	schreyer.lib symodstd.lib derham.lib polybori.lib ellipticcovers.lib \
+	schubert.lib tasks.lib tropical.lib hdepth.lib
+
+PLIBS = bimodules.lib bfun.lib central.lib dmod.lib dmodapp.lib dmodvar.lib\
+        fpadim.lib \
+	freegb.lib gkdim.lib involut.lib ncalg.lib ncdecomp.lib \
+	ncfactor.lib ncpreim.lib nctools.lib perron.lib qmatrix.lib \
+        purityfiltration.lib nchomolog.lib ratgb.lib \
+	ncall.lib
+
+
diff --git a/Singular/singularsurf b/Singular/singularsurf
new file mode 100755
index 0000000..725378a
--- /dev/null
+++ b/Singular/singularsurf
@@ -0,0 +1,11 @@
+#!/bin/sh
+echo "width=400;" >$1.pic
+echo "height=400;" >>$1.pic
+cat $1 >>$1.pic
+echo "color_file_format = jpg;">>$1.pic
+echo "filename = \"/tmp/surf.jpg\";">>$1.pic
+echo "save_color_image;">>$1.pic
+surf $1.pic
+/bin/rm $1.pic
+display /tmp/surf.jpg
+/bin/rm /tmp/surf.jpg
diff --git a/Singular/stype.h b/Singular/stype.h
new file mode 100644
index 0000000..6794ce8
--- /dev/null
+++ b/Singular/stype.h
@@ -0,0 +1,24 @@
+#ifndef STYPE_H
+#define STYPE_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: flex/bison interface
+*/
+
+#include <kernel/structs.h>
+#include <Singular/subexpr.h>
+
+typedef union
+{
+  int       i;
+  char    * name;
+  sleftv    lv;
+} MYYSTYPE;
+#define YYSTYPE MYYSTYPE
+extern YYSTYPE  yylval;
+
+int yylex(MYYSTYPE *l);
+
+#endif
diff --git a/Singular/subexpr.cc b/Singular/subexpr.cc
new file mode 100644
index 0000000..01633b9
--- /dev/null
+++ b/Singular/subexpr.cc
@@ -0,0 +1,1922 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: handling of leftv
+*/
+
+#include <kernel/mod2.h>
+
+#include <omalloc/omalloc.h>
+
+#include <misc/intvec.h>
+#include <misc/options.h>
+
+#include <coeffs/numbers.h>
+#include <coeffs/bigintmat.h>
+
+#include <coeffs/ffields.h> // nfShowMipo // minpoly printing...
+
+#include <polys/monomials/maps.h>
+#include <polys/matpol.h>
+#include <polys/monomials/ring.h>
+
+// #include <coeffs/longrat.h>
+
+#include <kernel/polys.h>
+#include <kernel/ideals.h>
+#include <kernel/GBEngine/kstd1.h>
+#include <kernel/GBEngine/syz.h>
+#include <kernel/oswrapper/timer.h>
+
+#include <Singular/tok.h>
+#include <Singular/ipid.h>
+#include <Singular/ipshell.h>
+#include <Singular/lists.h>
+#include <Singular/attrib.h>
+#include <Singular/links/silink.h>
+#include <Singular/attrib.h>
+#include <Singular/subexpr.h>
+#include <Singular/blackbox.h>
+#include <Singular/number2.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <unistd.h>
+
+omBin sSubexpr_bin = omGetSpecBin(sizeof(_ssubexpr));
+omBin sleftv_bin = omGetSpecBin(sizeof(sleftv));
+omBin procinfo_bin = omGetSpecBin(sizeof(procinfo));
+omBin libstack_bin = omGetSpecBin(sizeof(libstack));
+static omBin size_two_bin = omGetSpecBin(2);
+
+sleftv     sLastPrinted;
+const char sNoName[]="_";
+#ifdef SIQ
+BOOLEAN siq=FALSE;
+#endif
+
+int sleftv::listLength()
+{
+  int n = 1;
+  leftv sl = next;
+  while (sl!=NULL)
+  {
+    n++;
+    sl=sl->next;
+  }
+  return n;
+}
+
+void sleftv::Print(leftv store, int spaces)
+{
+  int  t=Typ();
+  if (errorreported) return;
+#ifdef SIQ
+  if (rtyp==COMMAND)
+  {
+    command c=(command)data;
+    char ch[2];
+    ch[0]=c->op;ch[1]='\0';
+    const char *s=ch;
+    if (c->op>127) s=iiTwoOps(c->op);
+    ::Print("##command %d(%s), %d args\n",
+      c->op, s, c->argc);
+    if (c->argc>0)
+      c->arg1.Print(NULL,spaces+2);
+    if(c->argc<4)
+    {
+      if (c->argc>1)
+        c->arg2.Print(NULL,spaces+2);
+      if (c->argc>2)
+        c->arg3.Print(NULL,spaces+2);
+    }
+    PrintS("##end");
+  }
+  else
+#endif
+  {
+    const char *n=Name();
+    char *s;
+    void *d=Data();
+    if (errorreported) return;
+    if ((store!=NULL)&&(store!=this))
+      store->CleanUp();
+
+    switch (t /*=Typ()*/)
+      {
+#ifdef SINGULAR_4_1
+        case CRING_CMD:
+          crPrint((coeffs)d);
+          break;
+        case CNUMBER_CMD:
+          n2Print((number2)d);
+          break;
+        case CMATRIX_CMD: // like BIGINTMAT
+#endif
+        case BIGINTMAT_CMD:
+          ((bigintmat *)d)->pprint(80);
+          break;
+        case UNKNOWN:
+        case DEF_CMD:
+          PrintNSpaces(spaces);
+          PrintS("`");PrintS(n);PrintS("`");
+          break;
+        case PACKAGE_CMD:
+          PrintNSpaces(spaces);
+          paPrint(n,(package)d);
+          break;
+        case NONE:
+          return;
+        case INTVEC_CMD:
+        case INTMAT_CMD:
+          ((intvec *)d)->show(t,spaces);
+          break;
+        case RING_CMD:
+        case QRING_CMD:
+        {
+          PrintNSpaces(spaces);
+          const ring r = (const ring)d;
+          rWrite(r, currRing == r);
+          break;
+        }
+        case MATRIX_CMD:
+          iiWriteMatrix((matrix)d,n,2, currRing, spaces);
+          break;
+        case MODUL_CMD:
+        case IDEAL_CMD:
+          if ((TEST_V_QRING)  &&(currRing->qideal!=NULL)
+          &&(!hasFlag(this,FLAG_QRING)))
+          {
+            jjNormalizeQRingId(this);
+            d=Data();
+          }
+          // no break:
+        case MAP_CMD:
+          iiWriteMatrix((matrix)d,n,1, currRing, spaces);
+          break;
+        case POLY_CMD:
+        case VECTOR_CMD:
+          if ((TEST_V_QRING)  &&(currRing->qideal!=NULL)
+          &&(!hasFlag(this,FLAG_QRING)))
+          {
+            jjNormalizeQRingP(this);
+            d=Data();
+          }
+          PrintNSpaces(spaces);
+          pWrite0((poly)d);
+          break;
+        case RESOLUTION_CMD:
+        {
+          syStrategy tmp=(syStrategy)d;
+          syPrint(tmp,IDID(currRingHdl));
+          break;
+        }
+        case STRING_CMD:
+          PrintNSpaces(spaces);
+          PrintS((char *)d);
+          break;
+       case INT_CMD:
+          PrintNSpaces(spaces);
+          ::Print("%d",(int)(long)d);
+          break;
+       case PROC_CMD:
+         {
+           procinfov pi=(procinfov)d;
+
+           PrintNSpaces(spaces);
+           PrintS("// libname  : ");
+           PrintS(piProcinfo(pi, "libname"));
+           PrintLn();
+
+           PrintNSpaces(spaces);
+           PrintS("// procname : ");
+           PrintS(piProcinfo(pi, "procname"));
+           PrintLn();
+
+           PrintNSpaces(spaces);
+           PrintS("// type     : ");
+           PrintS(piProcinfo(pi, "type"));
+           //           ::Print("%-*.*s// ref      : %s",spaces,spaces," ",
+           //   piProcinfo(pi, "ref"));
+           break;
+         }
+       case LINK_CMD:
+          {
+            si_link l=(si_link)d;
+            PrintNSpaces(spaces);
+            ::Print("// type : %s\n", slStatus(l, "type"));
+            PrintNSpaces(spaces);
+            ::Print("// mode : %s\n", slStatus(l, "mode"));
+            PrintNSpaces(spaces);
+            ::Print("// name : %s\n", slStatus(l, "name"));
+            PrintNSpaces(spaces);
+            ::Print("// open : %s\n", slStatus(l, "open"));
+            PrintNSpaces(spaces);
+            ::Print("// read : %s\n", slStatus(l, "read"));
+            PrintNSpaces(spaces);
+            ::Print("// write: %s", slStatus(l, "write"));
+          break;
+          }
+        case NUMBER_CMD:
+        case BIGINT_CMD:
+          s=String(d);
+          if (s==NULL) return;
+          PrintNSpaces(spaces);
+          PrintS(s);
+          omFree((ADDRESS)s);
+          break;
+        case LIST_CMD:
+        {
+          lists l=(lists)d;
+          if (lSize(l)<0)
+          {
+             PrintNSpaces(spaces);
+             PrintS("empty list\n");
+          }
+          else
+          {
+            int i=0;
+            for (;i<=l->nr;i++)
+            {
+              if (l->m[i].rtyp!=DEF_CMD)
+              {
+                PrintNSpaces(spaces);
+                ::Print("[%d]:\n",i+1);
+                l->m[i].Print(NULL,spaces+3);
+              }
+            }
+          }
+          break;
+        }
+
+        default:
+          if (t>MAX_TOK)
+          {
+            blackbox * bb=getBlackboxStuff(t);
+            PrintNSpaces(spaces);
+            if (bb!=NULL) { bb->blackbox_Print(bb,d); }
+            else          { ::Print("Print: blackbox %d(bb=NULL)",t); }
+          }
+          else
+          ::Print("Print:unknown type %s(%d)", Tok2Cmdname(t),t);
+      } /* end switch: (Typ()) */
+  }
+  if (next!=NULL)
+  {
+    if (t==COMMAND) PrintLn();
+    else if (t!=LIST_CMD) PrintS(" ");
+    next->Print(NULL,spaces);
+  }
+  else if (t!=LIST_CMD)
+  {
+    PrintLn();
+  }
+#ifdef SIQ
+  if (rtyp!=COMMAND)
+#endif
+  {
+    if ((store!=NULL)
+    && (store!=this))
+    {
+      if((t/*Typ()*/!=LINK_CMD)
+      && (t/*Typ()*/!=PACKAGE_CMD)
+      && (t/*Typ()*/!=DEF_CMD)
+      )
+      {
+        store->rtyp=t/*Typ()*/;
+        store->data=CopyD();
+        if(attribute!=NULL)
+        {
+          store->attribute=CopyA();
+        }
+        store->flag=flag;
+      }
+    }
+  }
+}
+
+void sleftv::CleanUp(ring r)
+{
+  if ((name!=NULL) && (name!=sNoName) && (rtyp!=IDHDL) && (rtyp!=ALIAS_CMD))
+  {
+    //::Print("free %x (%s)\n",name,name);
+    omFree((ADDRESS)name);
+  }
+  //name=NULL;
+  //flag=0;
+  if (data!=NULL)
+  {
+     if (rtyp==IDHDL) attribute=NULL; // is only a pointer to attribute of id
+     else s_internalDelete(rtyp,data,r);
+    //data=NULL; // will be done by Init() at the end
+  }
+  if (attribute!=NULL)
+  {
+    switch (rtyp)
+    {
+      case PACKAGE_CMD:
+      case IDHDL:
+      case ANY_TYPE:
+      case VECHO:
+      case VPRINTLEVEL:
+      case VCOLMAX:
+      case VTIMER:
+      case VRTIMER:
+      case VOICE:
+      case VMAXDEG:
+      case VMAXMULT:
+      case TRACE:
+      case VSHORTOUT:
+      case VNOETHER:
+      case VMINPOLY:
+      case LIB_CMD:
+      case 0:
+        //attribute=NULL; // will be done by Init() at the end
+        break;
+      default:
+      {
+        attribute->killAll(r);
+      }
+    }
+  }
+  Subexpr h;
+  while (e!=NULL)
+  {
+    h=e->next;
+    omFreeBin((ADDRESS)e, sSubexpr_bin);
+    e=h;
+  }
+  //rtyp=NONE; // will be done by Init() at the end
+  if (next!=NULL)
+  {
+    leftv tmp_n;
+    do
+    {
+      tmp_n=next->next;
+      //next->name=NULL;
+      next->next=NULL;
+      next->CleanUp(r);
+      omFreeBin((ADDRESS)next, sleftv_bin);
+      next=tmp_n;
+    } while (next!=NULL);
+  }
+  Init();
+}
+
+BOOLEAN sleftv::RingDependend()
+{
+  int rt=Typ();
+  if(::RingDependend(rt) && (rt!=QRING_CMD))
+    return TRUE;
+  if (rt==LIST_CMD)
+    return lRingDependend((lists)Data());
+  if (this->next!=NULL)
+    return this->next->RingDependend();
+  return FALSE;
+}
+
+static inline void * s_internalCopy(const int t,  void *d)
+{
+  switch (t)
+  {
+#ifdef SINGULAR_4_1
+    case CRING_CMD:
+      {
+        coeffs cf=(coeffs)d;
+        cf->ref++;
+        return (void*)d;
+      }
+    case CNUMBER_CMD:
+      return (void*)n2Copy((number2)d);
+    case CMATRIX_CMD: // like BIGINTMAT
+#endif
+    case BIGINTMAT_CMD:
+      return (void*)bimCopy((bigintmat *)d);
+    case INTVEC_CMD:
+    case INTMAT_CMD:
+      return (void *)ivCopy((intvec *)d);
+    case MATRIX_CMD:
+      return (void *)mp_Copy((matrix)d, currRing);
+    case IDEAL_CMD:
+    case MODUL_CMD:
+      return  (void *)idCopy((ideal)d);
+    case STRING_CMD:
+        return (void *)omStrDup((char *)d);
+    case PACKAGE_CMD:
+      return  (void *)paCopy((package) d);
+    case PROC_CMD:
+      return  (void *)piCopy((procinfov) d);
+    case POLY_CMD:
+    case VECTOR_CMD:
+      return  (void *)pCopy((poly)d);
+    case INT_CMD:
+      return  d;
+    case NUMBER_CMD:
+      return  (void *)nCopy((number)d);
+    case BIGINT_CMD:
+      return  (void *)n_Copy((number)d, coeffs_BIGINT);
+    case MAP_CMD:
+      return  (void *)maCopy((map)d, currRing);
+    case LIST_CMD:
+      return  (void *)lCopy((lists)d);
+    case LINK_CMD:
+      return (void *)slCopy((si_link) d);
+    case RING_CMD:
+    case QRING_CMD:
+      {
+        ring r=(ring)d;
+        if (r!=NULL) r->ref++;
+        //Print("+  ring %d, ref %d\n",r,r->ref);
+        return d;
+      }
+    case RESOLUTION_CMD:
+      return (void*)syCopy((syStrategy)d);
+    case DEF_CMD:
+    case NONE:
+    case 0: /* type in error case */
+      break; /* error recovery: do nothing */
+    //case COMMAND:
+    default:
+    {
+      if (t>MAX_TOK)
+      {
+        blackbox *b=getBlackboxStuff(t);
+        if (b!=NULL) return b->blackbox_Copy(b,d);
+        return NULL;
+      }
+      else
+      Warn("s_internalCopy: cannot copy type %s(%d)",
+            Tok2Cmdname(t),t);
+    }
+  }
+  return NULL;
+}
+
+void s_internalDelete(const int t,  void *d, const ring r)
+{
+  assume(d!=NULL);
+  switch (t)
+  {
+#ifdef SINGULAR_4_1
+    case CRING_CMD:
+      nKillChar((coeffs)d);
+      break;
+    case CNUMBER_CMD:
+      {
+        number2 n=(number2)d;
+        n2Delete(n);
+        break;
+      }
+    case CMATRIX_CMD: //like BIGINTMAT
+#endif
+    case BIGINTMAT_CMD:
+    {
+      bigintmat *v=(bigintmat*)d;
+      delete v;
+      break;
+    }
+    case INTVEC_CMD:
+    case INTMAT_CMD:
+    {
+      intvec *v=(intvec*)d;
+      delete v;
+      break;
+    }
+    case MAP_CMD:
+    {
+      map m=(map)d;
+      omFreeBinAddr((ADDRESS)m->preimage);
+      m->preimage=NULL;
+      /* no break: continue as IDEAL*/
+    }
+    case MATRIX_CMD:
+    case IDEAL_CMD:
+    case MODUL_CMD:
+    {
+      ideal i=(ideal)d;
+      id_Delete(&i,r);
+      break;
+    }
+    case STRING_CMD:
+      omFree(d);
+      break;
+    //case PACKAGE_CMD:
+    //  return  (void *)paCopy((package) d);
+    case PROC_CMD:
+      piKill((procinfo*)d);
+      break;
+    case POLY_CMD:
+    case VECTOR_CMD:
+    {
+      poly p=(poly)d;
+      p_Delete(&p,r);
+      break;
+    }
+    case NUMBER_CMD:
+    {
+      number n=(number)d;
+      n_Delete(&n,r);
+      break;
+    }
+    case BIGINT_CMD:
+    {
+      number n=(number)d;
+      n_Delete(&n,coeffs_BIGINT);
+      break;
+    }
+    case LIST_CMD:
+    {
+      lists l=(lists)d;
+      l->Clean(r);
+      break;
+    }
+    case LINK_CMD:
+    {
+      si_link l=(si_link)d;
+      slKill(l);
+      break;
+    }
+    case RING_CMD:
+    case QRING_CMD:
+    {
+      ring R=(ring)d;
+      if ((R!=currRing)||(R->ref>=0))
+        rKill(R);
+      #ifdef TEST
+      else
+        Print("currRing? ref=%d\n",R->ref);
+      #endif
+      break;
+    }
+    case RESOLUTION_CMD:
+    {
+      syStrategy s=(syStrategy)d;
+      if (s!=NULL) syKillComputation(s,r);
+      break;
+    }
+    case COMMAND:
+    {
+     command cmd=(command)d;
+     if (cmd->arg1.rtyp!=0) cmd->arg1.CleanUp(r);
+     if (cmd->arg2.rtyp!=0) cmd->arg2.CleanUp(r);
+     if (cmd->arg3.rtyp!=0) cmd->arg3.CleanUp(r);
+     omFreeBin((ADDRESS)d, sip_command_bin);
+     break;
+    }
+    case INT_CMD:
+    case DEF_CMD:
+    case ALIAS_CMD:
+    case PACKAGE_CMD:
+    case IDHDL:
+    case NONE:
+    case ANY_TYPE:
+    case VECHO:
+    case VPRINTLEVEL:
+    case VCOLMAX:
+    case VTIMER:
+    case VRTIMER:
+    case VOICE:
+    case VMAXDEG:
+    case VMAXMULT:
+    case TRACE:
+    case VSHORTOUT:
+    case VNOETHER:
+    case VMINPOLY:
+    case LIB_CMD:
+    case 0: /* type in error case */
+      break; /* error recovery: do nothing */
+    //case COMMAND:
+    //case COMMAND:
+    default:
+    {
+      if (t>MAX_TOK)
+      {
+        blackbox *b=getBlackboxStuff(t);
+        if (b!=NULL) b->blackbox_destroy(b,d);
+        break;
+      }
+      else
+      Warn("s_internalDelete: cannot delete type %s(%d)",
+            Tok2Cmdname(t),t);
+    }
+  }
+}
+
+void * slInternalCopy(leftv source, const int t, void *d, Subexpr e)
+{
+  if (t==STRING_CMD)
+  {
+      if ((e==NULL)
+      || (source->rtyp==LIST_CMD)
+      || ((source->rtyp==IDHDL)
+          &&((IDTYP((idhdl)source->data)==LIST_CMD)
+            || (IDTYP((idhdl)source->data)>MAX_TOK)))
+      || (source->rtyp>MAX_TOK))
+        return (void *)omStrDup((char *)d);
+      else if (e->next==NULL)
+      {
+        char *s=(char*)omAllocBin(size_two_bin);
+        s[0]=*(char *)d;
+        s[1]='\0';
+        return s;
+      }
+      #ifdef TEST
+      else
+      {
+        Werror("not impl. string-op in `%s`",my_yylinebuf);
+        return NULL;
+      }
+      #endif
+  }
+  return s_internalCopy(t,d);
+}
+
+void sleftv::Copy(leftv source)
+{
+  Init();
+  rtyp=source->Typ();
+  void *d=source->Data();
+  if(!errorreported)
+  {
+    data=s_internalCopy(rtyp,d);
+    if ((source->attribute!=NULL)||(source->e!=NULL))
+      attribute=source->CopyA();
+    flag=source->flag;
+    if (source->next!=NULL)
+    {
+      next=(leftv)omAllocBin(sleftv_bin);
+      next->Copy(source->next);
+    }
+  }
+}
+
+void * sleftv::CopyD(int t)
+{
+  if ((rtyp!=IDHDL)&&(rtyp!=ALIAS_CMD)&&(e==NULL))
+  {
+    if (iiCheckRing(t)) return NULL;
+    void *x = data;
+    if (rtyp==VNOETHER) x = (void *)pCopy((currRing->ppNoether));
+    else if ((rtyp==VMINPOLY) && nCoeff_is_algExt(currRing->cf) && (!nCoeff_is_GF(currRing->cf)))
+    {
+      const ring A = currRing->cf->extRing;
+
+      assume( A != NULL );
+      assume( A->qideal != NULL );
+
+      x=(void *)p_Copy(A->qideal->m[0], A);
+    }
+    data=NULL;
+    return x;
+  }
+  void *d=Data(); // will also do a iiCheckRing
+  if ((!errorreported) && (d!=NULL)) return slInternalCopy(this,t,d,e);
+  return NULL;
+}
+
+//void * sleftv::CopyD()
+//{
+  //if ((rtyp!=IDHDL)&&(e==NULL)
+  //&&(rtyp!=VNOETHER)&&(rtyp!=LIB_CMD)&&(rtyp!=VMINPOLY))
+  //{
+  //  void *x=data;
+  //  data=NULL;
+  //  return x;
+  //}
+//  return CopyD(Typ());
+//}
+
+attr sleftv::CopyA()
+{
+  attr *a=Attribute();
+  if ((a!=NULL) && (*a!=NULL))
+    return (*a)->Copy();
+  return NULL;
+}
+
+char *  sleftv::String(void *d, BOOLEAN typed, int dim)
+{
+#ifdef SIQ
+  if (rtyp==COMMAND)
+  {
+    ::Print("##command %d\n",((command)data)->op);
+    if (((command)data)->arg1.rtyp!=0)
+      ((command)data)->arg1.Print(NULL,2);
+    if (((command)data)->arg2.rtyp!=0)
+      ((command)data)->arg2.Print(NULL,2);
+    if (((command)data)->arg3.rtyp==0)
+      ((command)data)->arg3.Print(NULL,2);
+    PrintS("##end\n");
+    return omStrDup("");
+  }
+#endif
+  if (d==NULL) d=Data();
+  if (!errorreported)
+  {
+    char *s;
+    int t=Typ();
+    switch (t /*Typ()*/)
+    {
+        case INT_CMD:
+          if (typed)
+          {
+            s=(char *)omAlloc(MAX_INT_LEN+7);
+            sprintf(s,"int(%d)",(int)(long)d);
+          }
+          else
+          {
+            s=(char *)omAlloc(MAX_INT_LEN+2);
+            sprintf(s,"%d",(int)(long)d);
+          }
+          return s;
+
+        case STRING_CMD:
+          if (d == NULL)
+          {
+            if (typed) return omStrDup("\"\"");
+            return omStrDup("");
+          }
+          if (typed)
+          {
+            s = (char*) omAlloc(strlen((char*) d) + 3);
+            sprintf(s,"\"%s\"", (char*) d);
+            return s;
+          }
+          else
+          {
+            return omStrDup((char*)d);
+          }
+
+        case POLY_CMD:
+        case VECTOR_CMD:
+          if (typed)
+          {
+            char* ps = pString((poly) d);
+            s = (char*) omAlloc(strlen(ps) + 10);
+            sprintf(s,"%s(%s)", (t /*Typ()*/ == POLY_CMD ? "poly" : "vector"), ps);
+            omFree(ps);
+            return s;
+          }
+          else
+            return pString((poly)d);
+
+        #ifdef SINGULAR_4_1
+        case CNUMBER_CMD:
+          return n2String((number2)d,typed);
+        #endif
+
+        case NUMBER_CMD:
+          StringSetS((char*) (typed ? "number(" : ""));
+          if ((rtyp==IDHDL)&&(IDTYP((idhdl)data)==NUMBER_CMD))
+          {
+            nWrite(IDNUMBER((idhdl)data));
+          }
+          else if (rtyp==NUMBER_CMD)
+          {
+            number n=(number)data;
+            nWrite(n);
+            data=(char *)n;
+          }
+          else if((rtyp==VMINPOLY)&&(rField_is_GF(currRing)))
+          {
+            nfShowMipo(currRing->cf);
+          }
+          else
+          {
+            number n=nCopy((number)d);
+            nWrite(n);
+            nDelete(&n);
+          }
+          StringAppendS((char*) (typed ? ")" : ""));
+          return StringEndS();
+
+        case BIGINT_CMD:
+          {
+          StringSetS((char*) (typed ? "bigint(" : ""));
+          number nl=(number)d;
+          n_Write(nl,coeffs_BIGINT);
+          StringAppendS((char*) (typed ? ")" : ""));
+          return StringEndS();
+          }
+
+        case MATRIX_CMD:
+          s= iiStringMatrix((matrix)d,dim, currRing);
+          if (typed)
+          {
+            char* ns = (char*) omAlloc(strlen(s) + 40);
+            sprintf(ns, "matrix(ideal(%s),%d,%d)", s,
+                    ((ideal) d)->nrows, ((ideal) d)->ncols);
+            omCheckAddr(ns);
+            return ns;
+          }
+          else
+          {
+            return omStrDup(s);
+          }
+
+        case MODUL_CMD:
+        case IDEAL_CMD:
+        case MAP_CMD:
+          s= iiStringMatrix((matrix)d,dim, currRing);
+          if (typed)
+          {
+            char* ns = (char*) omAlloc(strlen(s) + 10);
+            sprintf(ns, "%s(%s)", (t/*Typ()*/==MODUL_CMD ? "module" : "ideal"), s);
+            omCheckAddr(ns);
+            return ns;
+          }
+          return omStrDup(s);
+
+        case INTVEC_CMD:
+        case INTMAT_CMD:
+        {
+          intvec *v=(intvec *)d;
+          s = v->String(dim);
+          if (typed)
+          {
+            char* ns;
+            if (t/*Typ()*/ == INTMAT_CMD)
+            {
+              ns = (char*) omAlloc(strlen(s) + 40);
+              sprintf(ns, "intmat(intvec(%s),%d,%d)", s, v->rows(), v->cols());
+            }
+            else
+            {
+              ns = (char*) omAlloc(strlen(s) + 10);
+              sprintf(ns, "intvec(%s)", s);
+            }
+            omCheckAddr(ns);
+            omFree(s);
+            return ns;
+          }
+          else
+            return s;
+        }
+        case BIGINTMAT_CMD:
+        {
+          bigintmat *bim=(bigintmat*)d;
+          s = bim->String();
+          if (typed)
+          {
+            char* ns = (char*) omAlloc0(strlen(s) + 40);
+            sprintf(ns, "bigintmat(bigintvec(%s),%d,%d)", s, bim->rows(), bim->cols());
+            omCheckAddr(ns);
+            return ns;
+          }
+          else
+            return omStrDup(s);
+        }
+
+        case RING_CMD:
+        case QRING_CMD:
+          s  = rString((ring)d);
+
+          if (typed)
+          {
+            char* ns;
+            if (t/*Typ()*/ == QRING_CMD)
+            {
+              char* id = iiStringMatrix((matrix) ((ring) d)->qideal, dim,
+                              currRing);
+              ns = (char*) omAlloc(strlen(s) + strlen(id) + 20);
+              sprintf(ns, "\"%s\";%sideal(%s)", s,(dim == 2 ? "\n" : " "), id);
+            }
+            else
+            {
+              ns = (char*) omAlloc(strlen(s) + 4);
+              sprintf(ns, "\"%s\"", s);
+            }
+            omFree(s);
+            omCheckAddr(ns);
+            return ns;
+          }
+          return s;
+        case RESOLUTION_CMD:
+        {
+          lists l = syConvRes((syStrategy)d);
+          s = lString(l, typed, dim);
+          l->Clean();
+          return s;
+        }
+
+        case PROC_CMD:
+        {
+          procinfo* pi = (procinfo*) d;
+          if((pi->language == LANG_SINGULAR) && (pi->data.s.body!=NULL))
+            s = (pi->data.s.body);
+          else
+            s = (char *)"";
+          if (typed)
+          {
+            char* ns = (char*) omAlloc(strlen(s) + 4);
+            sprintf(ns, "\"%s\"", s);
+            omCheckAddr(ns);
+            return ns;
+          }
+          return omStrDup(s);
+        }
+
+        case LINK_CMD:
+          s = slString((si_link) d);
+          if (typed)
+          {
+            char* ns = (char*) omAlloc(strlen(s) + 10);
+            sprintf(ns, "link(\"%s\")", s);
+            omFreeBinAddr(s);
+            omCheckAddr(ns);
+            return ns;
+          }
+          return s;
+
+        case LIST_CMD:
+          return lString((lists) d, typed, dim);
+
+        default:
+          if(t> MAX_TOK)
+          {
+            blackbox *bb=getBlackboxStuff(t);
+            if (bb!=NULL) return bb->blackbox_String(bb,d);
+          }
+    } /* end switch: (Typ()) */
+  }
+  return omStrDup("");
+}
+
+
+int  sleftv::Typ()
+{
+  if (e==NULL)
+  {
+    switch (rtyp)
+    {
+      case IDHDL:
+        return IDTYP((idhdl)data);
+      case ALIAS_CMD:
+         {
+           idhdl h=(idhdl)data;
+           return  ((idhdl)h->data.ustring)->typ;
+         }
+      case VECHO:
+      case VPRINTLEVEL:
+      case VCOLMAX:
+      case VTIMER:
+      case VRTIMER:
+      case VOICE:
+      case VMAXDEG:
+      case VMAXMULT:
+      case TRACE:
+      case VSHORTOUT:
+        return INT_CMD;
+      case VMINPOLY:
+        data=NULL;
+        return NUMBER_CMD;
+      case VNOETHER:
+        data=NULL;
+        return POLY_CMD;
+      //case COMMAND:
+      //  return COMMAND;
+      default:
+        return rtyp;
+    }
+  }
+  int r=0;
+  int t=rtyp;
+  void *d=data;
+  if (t==IDHDL) t=IDTYP((idhdl)data);
+  else if (t==ALIAS_CMD)
+  { idhdl h=(idhdl)IDDATA((idhdl)data); t=IDTYP(h);d=IDDATA(h); }
+  switch (t)
+  {
+#ifdef SINGULAR_4_1
+    case CMATRIX_CMD:
+    {
+      bigintmat *b=(bigintmat*)d;
+      if ((currRing!=NULL)&&(currRing->cf==b->basecoeffs()))
+        return NUMBER_CMD;
+      else
+        return CNUMBER_CMD;
+    }
+#endif
+    case INTVEC_CMD:
+    case INTMAT_CMD:
+      r=INT_CMD;
+      break;
+    case BIGINTMAT_CMD:
+      r=BIGINT_CMD;
+      break;
+    case IDEAL_CMD:
+    case MATRIX_CMD:
+    case MAP_CMD:
+      r=POLY_CMD;
+      break;
+    case MODUL_CMD:
+      r=VECTOR_CMD;
+      break;
+    case STRING_CMD:
+      r=STRING_CMD;
+      break;
+    default:
+    {
+      blackbox *b=NULL;
+      if (t>MAX_TOK)
+      {
+        b=getBlackboxStuff(t);
+      }
+      if ((t==LIST_CMD)||((b!=NULL)&&BB_LIKE_LIST(b)))
+      {
+        lists l;
+        if (rtyp==IDHDL) l=IDLIST((idhdl)data);
+        else if (rtyp==ALIAS_CMD)
+        {
+          idhdl h=(idhdl)data;
+          l=(lists)(((idhdl)h->data.ustring)->data.ustring);
+        }
+        else             l=(lists)data;
+        if ((0<e->start)&&(e->start<=l->nr+1))
+        {
+          Subexpr tmp=l->m[e->start-1].e;
+          l->m[e->start-1].e=e->next;
+          r=l->m[e->start-1].Typ();
+          e->next=l->m[e->start-1].e;
+          l->m[e->start-1].e=tmp;
+        }
+        else
+        {
+          //Warn("out of range: %d not in 1..%d",e->start,l->nr+1);
+          r=DEF_CMD;
+        }
+      }
+      else
+        Werror("cannot index type %s(%d)",Tok2Cmdname(t),t);
+      break;
+    }
+  }
+  return r;
+}
+
+int  sleftv::LTyp()
+{
+  lists l=NULL;
+  int r;
+  if (rtyp==LIST_CMD)
+    l=(lists)data;
+  else if ((rtyp==IDHDL)&& (IDTYP((idhdl)data)==LIST_CMD))
+    l=IDLIST((idhdl)data);
+  else
+    return Typ();
+  //if (l!=NULL)
+  {
+    if ((e!=NULL) && (e->next!=NULL))
+    {
+      if ((0<e->start)&&(e->start<=l->nr+1))
+      {
+        l->m[e->start-1].e=e->next;
+        r=l->m[e->start-1].LTyp();
+        l->m[e->start-1].e=NULL;
+      }
+      else
+      {
+        //Warn("out of range: %d not in 1..%d",e->start,l->nr+1);
+        r=NONE;
+      }
+      return r;
+    }
+    return LIST_CMD;
+  }
+  return Typ();
+}
+
+#ifdef SINGULAR_4_1
+static snumber2 iiNumber2Data[4];
+static int iiCmatrix_index=0;
+#endif
+void * sleftv::Data()
+{
+  if ((rtyp!=IDHDL) && iiCheckRing(rtyp))
+     return NULL;
+  if (e==NULL)
+  {
+    switch (rtyp)
+    {
+      case ALIAS_CMD:
+      {
+        idhdl h=(idhdl)data;
+        return  ((idhdl)h->data.ustring)->data.ustring;
+      }
+      case VECHO:      return (void *)(long)si_echo;
+      case VPRINTLEVEL:return (void *)(long)printlevel;
+      case VCOLMAX:    return (void *)(long)colmax;
+      case VTIMER:     return (void *)(long)getTimer();
+      case VRTIMER:    return (void *)(long)getRTimer();
+      case VOICE:      return (void *)(long)(myynest+1);
+      case VMAXDEG:    return (void *)(long)Kstd1_deg;
+      case VMAXMULT:   return (void *)(long)Kstd1_mu;
+      case TRACE:      return (void *)(long)traceit;
+      case VSHORTOUT:  return (void *)(long)(currRing != NULL ? currRing->ShortOut : 0);
+      case VMINPOLY:
+        if ( (currRing != NULL)  && nCoeff_is_algExt(currRing->cf) && !nCoeff_is_GF(currRing->cf))
+        {
+          /* Q(a), Fp(a), but not GF(q) */
+          const ring A = currRing->cf->extRing;
+
+          assume( A != NULL );
+          assume( A->qideal != NULL );
+
+          return (void *)A->qideal->m[0];
+        }
+        else
+          return (void *)currRing->cf->nNULL;
+
+      case VNOETHER:   return (void *) (currRing->ppNoether);
+      case IDHDL:
+        return IDDATA((idhdl)data);
+      case COMMAND:
+        //return NULL;
+      default:
+        return data;
+    }
+  }
+  /* e != NULL : */
+  int t=rtyp;
+  void *d=data;
+  if (t==IDHDL)
+  {
+    t=((idhdl)data)->typ;
+    d=IDDATA((idhdl)data);
+  }
+  else if (t==ALIAS_CMD)
+  {
+    idhdl h=(idhdl)IDDATA((idhdl)data);
+    t=IDTYP(h);
+    d=IDDATA(h);
+  }
+  if (iiCheckRing(t))
+    return NULL;
+  char *r=NULL;
+  int index=e->start;
+  switch (t)
+  {
+    case INTVEC_CMD:
+    {
+      intvec *iv=(intvec *)d;
+      if ((index<1)||(index>iv->length()))
+      {
+        if (!errorreported)
+          Werror("wrong range[%d] in intvec %s(%d)",index,this->Name(),iv->length());
+      }
+      else
+        r=(char *)(long)((*iv)[index-1]);
+      break;
+    }
+    case INTMAT_CMD:
+    {
+      intvec *iv=(intvec *)d;
+      if ((index<1)
+         ||(index>iv->rows())
+         ||(e->next->start<1)
+         ||(e->next->start>iv->cols()))
+      {
+        if (!errorreported)
+        Werror("wrong range[%d,%d] in intmat %s(%dx%d)",index,e->next->start,
+                                           this->Name(),iv->rows(),iv->cols());
+      }
+      else
+        r=(char *)(long)(IMATELEM((*iv),index,e->next->start));
+      break;
+    }
+    case BIGINTMAT_CMD:
+    {
+      bigintmat *m=(bigintmat *)d;
+      if ((index<1)
+         ||(index>m->rows())
+         ||(e->next->start<1)
+         ||(e->next->start>m->cols()))
+      {
+        if (!errorreported)
+        Werror("wrong range[%d,%d] in bigintmat %s(%dx%d)",index,e->next->start,
+                                                     this->Name(),m->rows(),m->cols());
+      }
+      else
+        r=(char *)(BIMATELEM((*m),index,e->next->start));
+      break;
+    }
+#ifdef SINGULAR_4_1
+    case CMATRIX_CMD:
+    {
+      bigintmat *m=(bigintmat *)d;
+      if ((index<1)
+         ||(index>m->rows())
+         ||(e->next->start<1)
+         ||(e->next->start>m->cols()))
+      {
+        if (!errorreported)
+        Werror("wrong range[%d,%d] in matrix %s(%dx%d)",index,e->next->start,
+                                                     this->Name(),m->rows(),m->cols());
+      }
+      else
+      {
+        iiNumber2Data[iiCmatrix_index].cf=m->basecoeffs();
+        iiNumber2Data[iiCmatrix_index].n=BIMATELEM((*m),index,e->next->start);
+        r=(char*)&iiNumber2Data[iiCmatrix_index];
+        iiCmatrix_index=(iiCmatrix_index+1) % 4;
+      }
+      break;
+    }
+#endif
+    case IDEAL_CMD:
+    case MODUL_CMD:
+    case MAP_CMD:
+    {
+      ideal I=(ideal)d;
+      if ((index<1)||(index>IDELEMS(I)))
+      {
+        if (!errorreported)
+          Werror("wrong range[%d] in ideal/module %s(%d)",index,this->Name(),IDELEMS(I));
+      }
+      else
+        r=(char *)I->m[index-1];
+      break;
+    }
+    case STRING_CMD:
+    {
+      // this was a memory leak
+      // we evalute it, cleanup and replace this leftv by it's evalutated form
+      // the evalutated form will be build in tmp
+      sleftv tmp;
+      tmp.Init();
+      tmp.rtyp=STRING_CMD;
+      r=(char *)omAllocBin(size_two_bin);
+      if ((index>0)&& (index<=(int)strlen((char *)d)))
+      {
+        r[0]=*(((char *)d)+index-1);
+        r[1]='\0';
+      }
+      else
+      {
+        r[0]='\0';
+      }
+      tmp.data=r;
+      if ((rtyp==IDHDL)||(rtyp==STRING_CMD))
+      {
+        tmp.next=next; next=NULL;
+        //if (rtyp==STRING_CMD) { omFree((ADDRESS)data); }
+        //data=NULL;
+        d=NULL;
+        CleanUp();
+        memcpy(this,&tmp,sizeof(tmp));
+      }
+      // and, remember, r is also the result...
+      else
+      {
+        // ???
+        // here we still have a memory leak...
+        // example: list L="123","456";
+        // L[1][2];
+        // therefore, it should never happen:
+        assume(0);
+        // but if it happens: here is the temporary fix:
+        // omMarkAsStaticAddr(r);
+      }
+      break;
+    }
+    case MATRIX_CMD:
+    {
+      if ((index<1)
+         ||(index>MATROWS((matrix)d))
+         ||(e->next->start<1)
+         ||(e->next->start>MATCOLS((matrix)d)))
+      {
+        if (!errorreported)
+          Werror("wrong range[%d,%d] in matrix %s(%dx%d)",
+                  index,e->next->start,
+                  this->Name(),
+                  MATROWS((matrix)d),MATCOLS((matrix)d));
+      }
+      else
+        r=(char *)MATELEM((matrix)d,index,e->next->start);
+      break;
+    }
+    default:
+    {
+      blackbox *b=NULL;
+      if (t>MAX_TOK)
+      {
+        b=getBlackboxStuff(t);
+      }
+      if ((t==LIST_CMD)||((b!=NULL)&&(BB_LIKE_LIST(b))))
+      {
+        lists l=(lists)d;
+        if ((0<index)&&(index<=l->nr+1))
+        {
+          if ((e->next!=NULL)
+          && (l->m[index-1].rtyp==STRING_CMD))
+          // string[..].Data() modifies sleftv, so let's do it ourself
+          {
+            char *dd=(char *)l->m[index-1].data;
+            int j=e->next->start-1;
+            r=(char *)omAllocBin(size_two_bin);
+            if ((j>=0) && (j<(int)strlen(dd)))
+            {
+              r[0]=*(dd+j);
+              r[1]='\0';
+            }
+            else
+            {
+              r[0]='\0';
+            }
+          }
+          else
+          {
+            Subexpr tmp=l->m[index-1].e;
+            l->m[index-1].e=e->next;
+            r=(char *)l->m[index-1].Data();
+            e->next=l->m[index-1].e;
+            l->m[index-1].e=tmp;
+          }
+        }
+        else //if (!errorreported)
+          Werror("wrong range[%d] in list %s(%d)",index,this->Name(),l->nr+1);
+      }
+      else
+        Werror("cannot index %s of type %s(%d)",this->Name(),Tok2Cmdname(t),t);
+      break;
+    }
+  }
+  return r;
+}
+
+attr * sleftv::Attribute()
+{
+  if (e==NULL) return &attribute;
+  if ((rtyp==LIST_CMD)
+  ||((rtyp==IDHDL)&&(IDTYP((idhdl)data)==LIST_CMD))
+  || (rtyp>MAX_TOK)
+  || ((rtyp==IDHDL)&&(IDTYP((idhdl)data)>MAX_TOK)))
+  {
+    leftv v=LData();
+    return &(v->attribute);
+  }
+  return NULL;
+}
+
+leftv sleftv::LData()
+{
+  if (e!=NULL)
+  {
+    lists l=NULL;
+    blackbox *b=getBlackboxStuff(rtyp);
+
+    if ((rtyp==LIST_CMD)
+    || ((b!=NULL)&&(BB_LIKE_LIST(b))))
+      l=(lists)data;
+    else if ((rtyp==IDHDL)&& (IDTYP((idhdl)data)==LIST_CMD))
+      l=IDLIST((idhdl)data);
+    else if ((rtyp==IDHDL)&& (IDTYP((idhdl)data)>MAX_TOK))
+    {
+      b=getBlackboxStuff(IDTYP((idhdl)data));
+      if (BB_LIKE_LIST(b)) l=IDLIST((idhdl)data);
+    }
+    else if (rtyp==ALIAS_CMD)
+    {
+      idhdl h=(idhdl)data;
+      l= (lists)(((idhdl)h->data.ustring)->data.ustring);
+    }
+    if (l!=NULL)
+    {
+      if ((0>=e->start)||(e->start>l->nr+1))
+        return NULL;
+      if (e->next!=NULL)
+      {
+        l->m[e->start-1].e=e->next;
+        leftv r=l->m[e->start-1].LData();
+        l->m[e->start-1].e=NULL;
+        return r;
+      }
+      return &(l->m[e->start-1]);
+    }
+  }
+  return this;
+}
+
+#if 0
+leftv sleftv::LHdl()
+{
+  if (e!=NULL)
+  {
+    lists l=NULL;
+
+    if (rtyp==LIST_CMD)
+      l=(lists)data;
+    if ((rtyp==IDHDL)&& (IDTYP((idhdl)data)==LIST_CMD))
+      l=IDLIST((idhdl)data);
+    if (l!=NULL)
+    {
+      if ((0>=e->start)||(e->start>l->nr+1))
+        return NULL;
+      if (e->next!=NULL)
+      {
+        l->m[e->start-1].e=e->next;
+        leftv r=l->m[e->start-1].LHdl();
+        l->m[e->start-1].e=NULL;
+        return r;
+      }
+      return &(l->m[e->start-1]);
+    }
+  }
+  return this;
+}
+#endif
+
+BOOLEAN assumeStdFlag(leftv h)
+{
+  if (h->e!=NULL)
+  {
+    leftv hh=h->LData();
+    if (h!=hh) return assumeStdFlag(h->LData());
+  }
+  if (!hasFlag(h,FLAG_STD))
+  {
+    if (!TEST_VERB_NSB)
+    {
+      if (TEST_V_ALLWARN)
+        Warn("%s is no standard basis in >>%s<<",h->Name(),my_yylinebuf);
+      else
+        Warn("%s is no standard basis",h->Name());
+    }
+    return FALSE;
+  }
+  return TRUE;
+}
+
+/*2
+* transforms a name (as an string created by omAlloc or omStrDup)
+* into an expression (sleftv), deletes the string
+* utility for grammar and iparith
+*/
+void syMake(leftv v,const char * id, idhdl packhdl)
+{
+  /* resolv an identifier: (to DEF_CMD, if siq>0)
+  * 1) reserved id: done by scanner
+  * 2) `basering` / 'Current`
+  * 3) existing identifier, local
+  * 4) ringvar, ringpar, local ring
+  * 5) existing identifier, global
+  * 6) monom (resp. number), local ring: consisting of:
+  * 6') ringvar,  ringpar,global ring
+  * 6'') monom (resp. number), local ring
+  * 7) monom (resp. number), non-local ring
+  * 8) basering
+  * 9) `_`
+  * 10) everything else is of type 0
+  */
+#ifdef TEST
+  if ((*id<' ')||(*id>(char)126))
+  {
+    Print("wrong id :%s:\n",id);
+  }
+#endif
+  idhdl save_ring=currRingHdl;
+  v->Init();
+  if(packhdl != NULL)
+  {
+  //  Print("setting req_packhdl to %s\n",IDID(packhdl));
+    v->req_packhdl = IDPACKAGE(packhdl);
+  }
+  else v->req_packhdl = currPack;
+//  if (v->req_packhdl!=basePack)
+//    Print("search %s in %s\n",id,v->req_packhdl->libname);
+  idhdl h=NULL;
+#ifdef SIQ
+  if (siq<=0)
+#endif
+  {
+    if (!isdigit(id[0]))
+    {
+      if (strcmp(id,"basering")==0)
+      {
+        if (currRingHdl!=NULL)
+        {
+          if (id!=IDID(currRingHdl)) omFreeBinAddr((ADDRESS)id);
+          h=currRingHdl;
+          goto id_found;
+        }
+        else
+        {
+          v->name = id;
+          return; /* undefined */
+        }
+      }
+      else if (strcmp(id,"Current")==0)
+      {
+        if (currPackHdl!=NULL)
+        {
+          omFreeBinAddr((ADDRESS)id);
+          h=currPackHdl;
+          goto id_found;
+        }
+        else
+        {
+          v->name = id;
+          return; /* undefined */
+        }
+      }
+      if(v->req_packhdl!=currPack)
+      {
+        h=v->req_packhdl->idroot->get(id,myynest);
+      }
+      else
+      h=ggetid(id);
+      /* 3) existing identifier, local */
+      if ((h!=NULL) && (IDLEV(h)==myynest))
+      {
+        if (id!=IDID(h)) omFreeBinAddr((ADDRESS)id); /*assume strlen(id) <1000 */
+        goto id_found;
+      }
+    }
+    if (yyInRingConstruction)
+    {
+      currRingHdl=NULL;
+    }
+    /* 4. local ring: ringvar */
+    if ((currRingHdl!=NULL) && (IDLEV(currRingHdl)==myynest)
+    /*&& (!yyInRingConstruction)*/)
+    {
+      int vnr;
+      if ((vnr=r_IsRingVar(id, currRing->names,currRing->N))>=0)
+      {
+        poly p=pOne();
+        pSetExp(p,vnr+1,1);
+        pSetm(p);
+        v->data = (void *)p;
+        v->name = id;
+        v->rtyp = POLY_CMD;
+        return;
+      }
+      if((n_NumberOfParameters(currRing->cf)>0)
+      &&((vnr=r_IsRingVar(id, (char**)n_ParameterNames(currRing->cf),
+                              n_NumberOfParameters(currRing->cf))>=0)))
+      {
+        BOOLEAN ok=FALSE;
+        poly p = pmInit(id,ok);
+        if (ok && (p!=NULL))
+        {
+          v->data = pGetCoeff(p);
+          pGetCoeff(p)=NULL;
+          pLmFree(p);
+          v->rtyp = NUMBER_CMD;
+          v->name = id;
+          return;
+        }
+      }
+    }
+    /* 5. existing identifier, global */
+    if (h!=NULL)
+    {
+      if (id!=IDID(h)) omFreeBinAddr((ADDRESS)id);  /*assume strlen(id) <1000 */
+      goto id_found;
+    }
+    /* 6. local ring: number/poly */
+    if ((currRingHdl!=NULL) && (IDLEV(currRingHdl)==myynest))
+    {
+      BOOLEAN ok=FALSE;
+      /*poly p = (!yyInRingConstruction) ? pmInit(id,ok) : (poly)NULL;*/
+      poly p = pmInit(id,ok);
+      if (ok)
+      {
+        if (p==NULL)
+        {
+          v->data = (void *)nInit(0);
+          v->rtyp = NUMBER_CMD;
+          #ifdef HAVE_PLURAL
+          // in this case we may have monomials equal to 0 in p_Read
+          v->name = id;
+          #else
+          omFreeBinAddr((ADDRESS)id);
+          #endif
+        }
+        else if (pIsConstant(p))
+        {
+          v->data = pGetCoeff(p);
+          pGetCoeff(p)=NULL;
+          pLmFree(p);
+          v->rtyp = NUMBER_CMD;
+          v->name = id;
+        }
+        else
+        {
+          v->data = p;
+          v->rtyp = POLY_CMD;
+          v->name = id;
+        }
+        return;
+      }
+    }
+    /* 7. non-local ring: number/poly */
+    {
+      BOOLEAN ok=FALSE;
+      poly p = ((currRing!=NULL)     /* ring required */
+               && (currRingHdl!=NULL)
+               /*&& (!yyInRingConstruction) - not in decl */
+               && (IDLEV(currRingHdl)!=myynest)) /* already in case 4/6 */
+                     ? pmInit(id,ok) : (poly)NULL;
+      if (ok)
+      {
+        if (p==NULL)
+        {
+          v->data = (void *)nInit(0);
+          v->rtyp = NUMBER_CMD;
+          #ifdef HAVE_PLURAL
+          // in this case we may have monomials equal to 0 in p_Read
+          v->name = id;
+          #else
+          omFreeBinAddr((ADDRESS)id);
+          #endif
+        }
+        else
+        if (pIsConstant(p))
+        {
+          v->data = pGetCoeff(p);
+          pGetCoeff(p)=NULL;
+          pLmFree(p);
+          v->rtyp = NUMBER_CMD;
+          v->name = id;
+        }
+        else
+        {
+          v->data = p;
+          v->rtyp = POLY_CMD;
+          v->name = id;
+        }
+        if (TEST_V_ALLWARN /*&& (myynest>0)*/
+        && ((r_IsRingVar(id, currRing->names,currRing->N)>=0)
+          || ((n_NumberOfParameters(currRing->cf)>0)
+             &&(r_IsRingVar(id, (char**)n_ParameterNames(currRing->cf),
+                                n_NumberOfParameters(currRing->cf))>=0))))
+        {
+        // WARNING: do not use ring variable names in procedures
+          Warn("use of variable >>%s<< in a procedure in line %s",id,my_yylinebuf);
+        }
+        return;
+      }
+    }
+    /* 8. basering ? */
+    if ((myynest>1)&&(currRingHdl!=NULL))
+    {
+      if (strcmp(id,IDID(currRingHdl))==0)
+      {
+        if (IDID(currRingHdl)!=id) omFreeBinAddr((ADDRESS)id); /*assume strlen (id) <1000 */
+        h=currRingHdl;
+        goto id_found;
+      }
+    }
+    if((v->req_packhdl!=basePack) && (v->req_packhdl==currPack))
+    {
+      h=basePack->idroot->get(id,myynest);
+      if (h!=NULL)
+      {
+        if (id!=IDID(h)) omFreeBinAddr((ADDRESS)id); /*assume strlen(id) <1000 */
+        v->req_packhdl=basePack;
+        goto id_found;
+      }
+    }
+  }
+#ifdef SIQ
+  else
+    v->rtyp=DEF_CMD;
+#endif
+  /* 9: _ */
+  if (strcmp(id,"_")==0)
+  {
+    omFreeBinAddr((ADDRESS)id);
+    v->Copy(&sLastPrinted);
+  }
+  else
+  {
+    /* 10: everything else */
+    /* v->rtyp = UNKNOWN;*/
+    v->name = id;
+  }
+  currRingHdl=save_ring;
+  return;
+id_found: // we have an id (in h) found, to set the data in from h
+  if (IDTYP(h)!=ALIAS_CMD)
+  {
+    v->rtyp = IDHDL;
+    v->flag = IDFLAG(h);
+    v->attribute=IDATTR(h);
+  }
+  else
+  {
+    v->rtyp = ALIAS_CMD;
+  }
+  v->name = IDID(h);
+  v->data = (char *)h;
+  currRingHdl=save_ring;
+}
+
+int sleftv::Eval()
+{
+  BOOLEAN nok=FALSE;
+  leftv nn=next;
+  next=NULL;
+  if(rtyp==IDHDL)
+  {
+    int t=Typ();
+    if (t!=PROC_CMD)
+    {
+      void *d=CopyD(t);
+      data=d;
+      rtyp=t;
+      name=NULL;
+      e=NULL;
+    }
+  }
+  else if (rtyp==COMMAND)
+  {
+    command d=(command)data;
+    if(d->op==PROC_CMD) //assume d->argc==2
+    {
+      char *what=(char *)(d->arg1.Data());
+      idhdl h=ggetid(what);
+      if((h!=NULL)&&(IDTYP(h)==PROC_CMD))
+      {
+        nok=d->arg2.Eval();
+        if(!nok)
+        {
+          nok=iiMake_proc(h,req_packhdl,&d->arg2);
+          this->CleanUp(currRing);
+          if (!nok)
+          {
+            memcpy(this,&iiRETURNEXPR,sizeof(sleftv));
+            memset(&iiRETURNEXPR,0,sizeof(sleftv));
+          }
+        }
+      }
+      else nok=TRUE;
+    }
+    else if (d->op=='=') //assume d->argc==2
+    {
+      if ((d->arg1.rtyp!=IDHDL)&&(d->arg1.rtyp!=DEF_CMD))
+      {
+        nok=d->arg1.Eval();
+      }
+      if (!nok)
+      {
+        const char *n=d->arg1.name;
+        nok=(n == NULL) || d->arg2.Eval();
+        if (!nok)
+        {
+          int save_typ=d->arg1.rtyp;
+          omCheckAddr((ADDRESS)n);
+          if (d->arg1.rtyp!=IDHDL)
+          syMake(&d->arg1,n);
+          omCheckAddr((ADDRESS)d->arg1.name);
+          if (d->arg1.rtyp==IDHDL)
+          {
+            n=omStrDup(IDID((idhdl)d->arg1.data));
+            killhdl((idhdl)d->arg1.data);
+            d->arg1.Init();
+            //d->arg1.data=NULL;
+            d->arg1.name=n;
+          }
+          d->arg1.rtyp=DEF_CMD;
+          sleftv t;
+          if(save_typ!=PROC_CMD) save_typ=d->arg2.rtyp;
+          if (::RingDependend(d->arg2.rtyp))
+            nok=iiDeclCommand(&t,&d->arg1,0,save_typ,&currRing->idroot);
+          else
+            nok=iiDeclCommand(&t,&d->arg1,0,save_typ,&IDROOT);
+          memcpy(&d->arg1,&t,sizeof(sleftv));
+          omCheckAddr((ADDRESS)d->arg1.name);
+          nok=nok||iiAssign(&d->arg1,&d->arg2);
+          omCheckIf(d->arg1.name != NULL,  // OB: ????
+                    omCheckAddr((ADDRESS)d->arg1.name));
+          if (!nok)
+          {
+            memset(&d->arg1,0,sizeof(sleftv));
+            this->CleanUp();
+            rtyp=NONE;
+          }
+        }
+      }
+      else nok=TRUE;
+    }
+    else
+    {
+      sleftv tmp;
+      int toktype=iiTokType(d->op);
+      if ((toktype==CMD_M)
+      ||( toktype==ROOT_DECL_LIST)
+      ||( toktype==RING_DECL_LIST))
+      {
+        if (d->argc <=3)
+        {
+          if (d->argc>=1) nok=d->arg1.Eval();
+          if ((!nok) && (d->argc>=2))
+          {
+            nok=d->arg2.Eval();
+            d->arg1.next=(leftv)omAllocBin(sleftv_bin);
+            memcpy(d->arg1.next,&d->arg2,sizeof(sleftv));
+            d->arg2.Init();
+          }
+          if ((!nok) && (d->argc==3))
+          {
+            nok=d->arg3.Eval();
+            d->arg1.next->next=(leftv)omAllocBin(sleftv_bin);
+            memcpy(d->arg1.next->next,&d->arg3,sizeof(sleftv));
+            d->arg3.Init();
+          }
+          if (d->argc==0)
+            nok=nok||iiExprArithM(&tmp,NULL,d->op);
+          else
+            nok=nok||iiExprArithM(&tmp,&d->arg1,d->op);
+        }
+        else
+        {
+          nok=d->arg1.Eval();
+          nok=nok||iiExprArithM(&tmp,&d->arg1,d->op);
+        }
+      }
+      else if (d->argc==1)
+      {
+        nok=d->arg1.Eval();
+        nok=nok||iiExprArith1(&tmp,&d->arg1,d->op);
+      }
+      else if(d->argc==2)
+      {
+        nok=d->arg1.Eval();
+        nok=nok||d->arg2.Eval();
+        nok=nok||iiExprArith2(&tmp,&d->arg1,d->op,&d->arg2);
+      }
+      else if(d->argc==3)
+      {
+        nok=d->arg1.Eval();
+        nok=nok||d->arg2.Eval();
+        nok=nok||d->arg3.Eval();
+        nok=nok||iiExprArith3(&tmp,d->op,&d->arg1,&d->arg2,&d->arg3);
+      }
+      else if(d->argc!=0)
+      {
+        nok=d->arg1.Eval();
+        nok=nok||iiExprArithM(&tmp,&d->arg1,d->op);
+      }
+      else // d->argc == 0
+      {
+        nok = iiExprArithM(&tmp, NULL, d->op);
+      }
+      this->CleanUp();
+      memcpy(this,&tmp,sizeof(tmp));
+    }
+  }
+  else if (((rtyp==0)||(rtyp==DEF_CMD))
+    &&(name!=NULL))
+  {
+     syMake(this,name);
+  }
+#ifdef MDEBUG
+  switch(Typ())
+  {
+    case NUMBER_CMD:
+#ifdef LDEBUG
+      nTest((number)Data());
+#endif
+      break;
+    case BIGINT_CMD:
+#ifdef LDEBUG
+      n_Test((number)Data(),coeffs_BIGINT);
+#endif
+      break;
+    case POLY_CMD:
+      pTest((poly)Data());
+      break;
+    case IDEAL_CMD:
+    case MODUL_CMD:
+    case MATRIX_CMD:
+      {
+        ideal id=(ideal)Data();
+        omCheckAddrSize(id,sizeof(*id));
+        int i=id->ncols*id->nrows-1;
+        for(;i>=0;i--) pTest(id->m[i]);
+      }
+      break;
+  }
+#endif
+  if (nn!=NULL) nok=nok||nn->Eval();
+  next=nn;
+  return nok;
+}
+
+const char *iiSleftv2name(leftv v)
+{
+  return(v->name);
+}
+
+void * sattr::CopyA()
+{
+  omCheckAddrSize(this,sizeof(sattr));
+  return s_internalCopy(atyp,data);
+}
+
diff --git a/Singular/subexpr.h b/Singular/subexpr.h
new file mode 100644
index 0000000..fc0ed9a
--- /dev/null
+++ b/Singular/subexpr.h
@@ -0,0 +1,180 @@
+#ifndef SUBEXPR_H
+#define SUBEXPR_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: handling of leftv
+*/
+
+#include <string.h>
+
+#include <polys/monomials/ring.h>
+
+//#include <Singular/ipid.h>
+
+#include <Singular/grammar.h>
+#include <Singular/tok.h>
+#include <Singular/attrib.h>
+
+typedef enum { LANG_NONE, LANG_TOP, LANG_SINGULAR, LANG_C, LANG_MAX} language_defs;
+class proc_singular
+{
+public:
+  long   proc_start;       // position where proc is starting
+  long   def_end;          // position where proc header is ending
+  long   help_start;       // position where help is starting
+  long   help_end;         // position where help is starting
+  long   body_start;       // position where proc-body is starting
+  long   body_end;         // position where proc-body is ending
+  long   example_start;    // position where example is starting
+  long   proc_end;         // position where proc is ending
+  int    proc_lineno;
+  int    body_lineno;
+  int    example_lineno;
+  char   *body;
+  long help_chksum;
+};
+struct proc_object
+{
+//public:
+  BOOLEAN (*function)(leftv res, leftv v);
+};
+
+union uprocinfodata
+{
+public:
+  proc_singular  s;        // data of Singular-procedure
+  struct proc_object    o; // pointer to binary-function
+};
+typedef union uprocinfodata procinfodata;
+
+class procinfo
+{
+public:
+  char          *libname;
+  char          *procname;
+  package       pack;
+  language_defs language;
+  short         ref;
+  char          is_static;        // if set, proc not accessible for user
+  char          trace_flag;
+  procinfodata  data;
+};
+
+typedef procinfo *         procinfov;
+
+struct _ssubexpr
+{
+  struct _ssubexpr * next;
+  int start;
+};
+
+typedef struct _ssubexpr *Subexpr;
+
+extern const char sNoName[];
+extern BOOLEAN siq;
+extern const char *iiSleftv2name(leftv v);
+
+class sleftv;
+typedef sleftv * leftv;
+
+/// Class used for (list of) interpreter objects
+class sleftv
+{
+  public:
+  /* !! do not change the first 6 entries !! (see ipid.h: idrec) */
+    leftv       next;
+    const char *name;
+    void *      data;
+    attr        attribute;
+    BITSET      flag;
+    int         rtyp;
+                 /* the type of the expression, describes the data field
+                  * (E) markes the type field in iparith
+                  * (S) markes the rtyp in sleftv
+                  * ANY_TYPE:   data is int: real type or 0    (E)
+                  * DEF_CMD:    all types, no change in sleftv (E)
+                  * IDHDL: existing variable         (E)
+                  * IDHDL: variable, data is idhdl   (S)
+                  * COMMAND: data is command         (S)
+                  * INT_CMD:      int constant, data is int  (E,S)
+                  * INTVEC_CMD:   intvec constant, data is intvec * (E,S)
+                  * POLY_CMD:     poly constant, data is poly (E,S)
+                  * ....
+                  */
+    Subexpr e;    /* holds the indices for indexed values */
+    package     req_packhdl;
+    inline void Init() { memset(this,0,sizeof(*this)); }
+    void CleanUp(ring r=currRing);
+
+    /// Called by type_cmd (e.g. "r;") or as default in jPRINT
+    void Print(leftv store=NULL,int spaces=0);
+
+    /// Called for conversion to string (used by string(..), write(..),..)
+    char * String(void *d=NULL, BOOLEAN typed = FALSE, int dim = 1);
+
+    void Copy(leftv e);
+    attr CopyA();
+    void * CopyD(int t);
+    void * CopyD() { return CopyD(Typ()); }
+    inline const char * Name()
+    {
+      if ((name!=NULL) && (e==NULL)) return name;
+      else return sNoName;
+    }
+    inline const char * Fullname()
+    {
+      if ((name!=NULL) && (e==NULL)) return(iiSleftv2name(this));
+      else return sNoName;
+    }
+    int  Typ();
+    int  LTyp(); /* returns LIST_CMD for l[i], otherwise returns Typ() */
+    void * Data();
+    leftv LData(); /* returns &(l[i]) for l[i], otherwise returns this */
+    //leftv LHdl();
+    attr * Attribute();
+    inline leftv Next() { return next; }
+    int listLength();
+    int Eval(); /*replace a COMMAND by its result otherwise by CopyD*/
+    BOOLEAN RingDependend();
+};
+
+inline BOOLEAN RingDependend(int t) { return (BEGIN_RING<t)&&(t<END_RING); }
+extern sleftv sLastPrinted;
+
+void syMake(leftv v,const char * name, idhdl packhdl = NULL);
+BOOLEAN assumeStdFlag(leftv h);
+
+inline procinfov piCopy(procinfov pi)
+{
+  pi->ref++;
+  return pi;
+}
+BOOLEAN piKill(procinfov l);
+const char *piProcinfo(procinfov pi, const char *request);
+void piShowProcinfo(procinfov pi, char *txt);
+#ifdef HAVE_LIBPARSER
+class libstack;
+typedef libstack *  libstackv;
+
+class libstack
+{
+ public:
+  libstackv next;
+  char      *libname;
+  BOOLEAN   to_be_done;
+  int       cnt;
+  void      push(const char *p, char * libname);
+  libstackv pop(const char *p);
+  inline char *get() { return(libname); }
+};
+#endif /* HAVE_LIBPARSER */
+
+extern omBin sSubexpr_bin;
+extern omBin procinfo_bin;
+extern omBin libstack_bin;
+
+void s_internalDelete(const int t,  void *d, const ring r);
+
+#endif
diff --git a/Singular/table.h b/Singular/table.h
new file mode 100644
index 0000000..78bbbb8
--- /dev/null
+++ b/Singular/table.h
@@ -0,0 +1,1264 @@
+#ifdef IPARITH
+// additional to the usual types: INT_CMD etc.
+// thre are special types:
+// for the input:
+// IDHDL: argument must have a name
+// DEF_CMD: no restriktions on the argument
+// ANY_TYPE: changes to pseudo data (for "defined", "typeof", etc.)
+// with the following subfields
+//        - name !=NULL
+//        - data := original type id
+
+// for the output:
+// NONE: does not return a value
+// ANY_TYPE: various types, the routines have to set it
+
+// the procedures have to be wrapped into the macro D(...)
+// with the exception of jjWRONG... (which always fails)
+/*=================== operations with 1 arg.: table =================*/
+struct sValCmd1 dArith1[]=
+{
+// operations:
+// proc            cmd               res             arg            context
+ {D(jjPLUSPLUS),   PLUSPLUS,        NONE,           IDHDL         , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjPLUSPLUS),   MINUSMINUS,      NONE,           IDHDL         , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjUMINUS_I),   '-',             INT_CMD,        INT_CMD       , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjUMINUS_BI),   '-',            BIGINT_CMD,     BIGINT_CMD    , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjUMINUS_N),   '-',             NUMBER_CMD,     NUMBER_CMD    , ALLOW_PLURAL |ALLOW_RING}
+#ifdef SINGULAR_4_1
+,{D(jjNUMBER2_OP1),'-',             CNUMBER_CMD,    CNUMBER_CMD   , ALLOW_PLURAL |ALLOW_RING}
+#endif
+,{D(jjUMINUS_P),   '-',             POLY_CMD,       POLY_CMD      , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjUMINUS_P),   '-',             VECTOR_CMD,     VECTOR_CMD    , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjUMINUS_MA),  '-',             MATRIX_CMD,     MATRIX_CMD    , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjUMINUS_IV),  '-',             INTVEC_CMD,     INTVEC_CMD    , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjUMINUS_IV),  '-',             INTMAT_CMD,     INTMAT_CMD    , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjUMINUS_BIM), '-',             BIGINTMAT_CMD,  BIGINTMAT_CMD , ALLOW_PLURAL |ALLOW_RING}
+#ifdef SINGULAR_4_1
+,{D(jjUMINUS_BIM), '-',             CMATRIX_CMD,    CMATRIX_CMD ,   ALLOW_PLURAL |ALLOW_RING}
+#endif
+,{D(jjPROC1),      '(',             ANY_TYPE/*set by p*/,PROC_CMD , ALLOW_PLURAL |ALLOW_RING}
+// and the procedures with 1 argument:
+,{D(atATTRIB1),    ATTRIB_CMD,      NONE,           DEF_CMD       , ALLOW_PLURAL |ALLOW_RING}
+//,{D(jjBAREISS_IM), BAREISS_CMD,     INTMAT_CMD,     INTMAT_CMD  , NO_PLURAL |ALLOW_RING | NO_ZERODIVISOR}
+,{D(jjBAREISS),    BAREISS_CMD,     LIST_CMD,       MODUL_CMD     , NO_PLURAL |ALLOW_RING | NO_ZERODIVISOR}
+,{D(jjBETTI),      BETTI_CMD,       INTMAT_CMD,     LIST_CMD      , ALLOW_PLURAL |ALLOW_RING}
+,{D(syBetti1),     BETTI_CMD,       INTMAT_CMD,     RESOLUTION_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjBETTI),      BETTI_CMD,       INTMAT_CMD,     IDEAL_CMD     , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjBETTI),      BETTI_CMD,       INTMAT_CMD,     MODUL_CMD     , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjDUMMY),      BIGINT_CMD,      BIGINT_CMD,     BIGINT_CMD    , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjN2BI),       BIGINT_CMD,      BIGINT_CMD,     NUMBER_CMD    , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjP2BI),       BIGINT_CMD,      BIGINT_CMD,     POLY_CMD      , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjDUMMY),      BIGINTMAT_CMD,   BIGINTMAT_CMD,  BIGINTMAT_CMD , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjCHAR),       CHARACTERISTIC_CMD, INT_CMD,     RING_CMD      , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjCHAR),       CHARACTERISTIC_CMD, INT_CMD,     QRING_CMD     , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjCHARSERIES), CHAR_SERIES_CMD, MATRIX_CMD,     IDEAL_CMD     , NO_PLURAL |NO_RING}
+,{D(jjrCharStr),   CHARSTR_CMD,     STRING_CMD,     RING_CMD      , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjrCharStr),   CHARSTR_CMD,     STRING_CMD,     QRING_CMD     , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjOpenClose),  CLOSE_CMD,       NONE,           LINK_CMD      , ALLOW_PLURAL |ALLOW_RING}
+//,{  jjWRONG ,       COLS_CMD,        0,              VECTOR_CMD  , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjCOLS),       COLS_CMD,        INT_CMD,        MATRIX_CMD    , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjCOLS),       COLS_CMD,        INT_CMD,        IDEAL_CMD     , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjCOLS),       COLS_CMD,        INT_CMD,        MODUL_CMD     , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjCOLS_IV),    COLS_CMD,        INT_CMD,        INTMAT_CMD    , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjCOLS_BIM),   COLS_CMD,        INT_CMD,        BIGINTMAT_CMD , ALLOW_PLURAL |ALLOW_RING}
+,{  jjWRONG ,      COLS_CMD,        0,              INTVEC_CMD    , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjCONTENT),    CONTENT_CMD,     POLY_CMD,       POLY_CMD      , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjCONTENT),    CONTENT_CMD,     VECTOR_CMD,     VECTOR_CMD    , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjCOUNT_BI),   COUNT_CMD,       INT_CMD,        BIGINT_CMD    , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjCOUNT_N),    COUNT_CMD,       INT_CMD,        NUMBER_CMD    , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjCOUNT_RES),  COUNT_CMD,       INT_CMD,        RESOLUTION_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjstrlen),     COUNT_CMD,       INT_CMD,        STRING_CMD    , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjpLength),    COUNT_CMD,       INT_CMD,        POLY_CMD      , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjpLength),    COUNT_CMD,       INT_CMD,        VECTOR_CMD    , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjidElem),     COUNT_CMD,       INT_CMD,        IDEAL_CMD     , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjidElem),     COUNT_CMD,       INT_CMD,        MODUL_CMD     , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjCOUNT_M),    COUNT_CMD,       INT_CMD,        MATRIX_CMD    , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjCOUNT_IV),   COUNT_CMD,       INT_CMD,        INTVEC_CMD    , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjCOUNT_IV),   COUNT_CMD,       INT_CMD,        INTMAT_CMD    , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjCOUNT_L),    COUNT_CMD,       INT_CMD,        LIST_CMD      , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjCOUNT_RG),   COUNT_CMD,       INT_CMD,        RING_CMD      , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjNULL),       DEF_CMD,         DEF_CMD,        INT_CMD       , ALLOW_PLURAL |ALLOW_RING}
+,{  jjWRONG ,      DEF_CMD,         0,              ANY_TYPE      , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjDEG),        DEG_CMD,         INT_CMD,        POLY_CMD      , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjDEG),        DEG_CMD,         INT_CMD,        VECTOR_CMD    , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjDEG_M),      DEG_CMD,         INT_CMD,        MATRIX_CMD    , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjDEGREE),     DEGREE_CMD,      STRING_CMD,     IDEAL_CMD     , NO_PLURAL |ALLOW_RING | NO_ZERODIVISOR}
+,{D(jjDEGREE),     DEGREE_CMD,      STRING_CMD,     MODUL_CMD     , NO_PLURAL |ALLOW_RING | NO_ZERODIVISOR}
+,{D(jjDEFINED),    DEFINED_CMD,     INT_CMD,        DEF_CMD       , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjDENOMINATOR),DENOMINATOR_CMD, NUMBER_CMD,     NUMBER_CMD    , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjNUMERATOR),  NUMERATOR_CMD,   NUMBER_CMD,     NUMBER_CMD    , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjDET_BI),     DET_CMD,         BIGINT_CMD,     BIGINTMAT_CMD , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjDET_I),      DET_CMD,         INT_CMD,        INTMAT_CMD    , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjDET),        DET_CMD,         POLY_CMD,       MATRIX_CMD    , NO_PLURAL |ALLOW_RING}
+,{D(jjDET_S),      DET_CMD,         POLY_CMD,       MODUL_CMD     , NO_PLURAL |NO_RING}
+,{D(jjDIM),        DIM_CMD,         INT_CMD,        IDEAL_CMD     , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjDIM),        DIM_CMD,         INT_CMD,        MODUL_CMD     , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjDIM_R),      DIM_CMD,         INT_CMD,        RESOLUTION_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjDUMP),       DUMP_CMD,        NONE,           LINK_CMD      , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjE),          E_CMD,           VECTOR_CMD,     INT_CMD       , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjEXECUTE),    EXECUTE_CMD,     NONE,           STRING_CMD    , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjERROR),      ERROR_CMD,       NONE,           STRING_CMD    , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjFAC_P),      FAC_CMD,         LIST_CMD,       POLY_CMD      , NO_PLURAL |NO_RING}
+,{D(findUniProc),  FINDUNI_CMD,     IDEAL_CMD,      IDEAL_CMD     , NO_PLURAL |NO_RING}
+,{D(jjidFreeModule),FREEMODULE_CMD, MODUL_CMD,      INT_CMD       , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjFACSTD),     FACSTD_CMD,      LIST_CMD,       IDEAL_CMD     , NO_PLURAL |NO_RING}
+,{D(jjGETDUMP),    GETDUMP_CMD,     NONE,           LINK_CMD      , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjHIGHCORNER), HIGHCORNER_CMD,  POLY_CMD,       IDEAL_CMD     , NO_PLURAL |ALLOW_RING}
+,{D(jjHIGHCORNER_M), HIGHCORNER_CMD,VECTOR_CMD,     MODUL_CMD     , NO_PLURAL |ALLOW_RING}
+,{D(jjHILBERT),    HILBERT_CMD,     NONE,           IDEAL_CMD     , NO_PLURAL |ALLOW_RING | NO_ZERODIVISOR}
+,{D(jjHILBERT),    HILBERT_CMD,     NONE,           MODUL_CMD     , NO_PLURAL |ALLOW_RING | NO_ZERODIVISOR}
+,{D(jjHILBERT_IV), HILBERT_CMD,     INTVEC_CMD,     INTVEC_CMD    , NO_PLURAL |ALLOW_RING | NO_ZERODIVISOR}
+,{D(jjHOMOG1),     HOMOG_CMD,       INT_CMD,        IDEAL_CMD     , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjHOMOG1),     HOMOG_CMD,       INT_CMD,        MODUL_CMD     , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjDUMMY),      IDEAL_CMD,       IDEAL_CMD,      IDEAL_CMD     , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjidVec2Ideal),IDEAL_CMD,       IDEAL_CMD,      VECTOR_CMD    , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjIDEAL_Ma),   IDEAL_CMD,       IDEAL_CMD,      MATRIX_CMD    , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjIDEAL_R),    IDEAL_CMD,       IDEAL_CMD,      QRING_CMD     , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjIDEAL_R),    IDEAL_CMD,       IDEAL_CMD,      RING_CMD      , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjIDEAL_Map),  IDEAL_CMD,       IDEAL_CMD,      MAP_CMD       , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjIMPART),     IMPART_CMD,      NUMBER_CMD,     NUMBER_CMD    , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjINDEPSET),   INDEPSET_CMD,    INTVEC_CMD,     IDEAL_CMD     , NO_PLURAL |NO_RING}
+,{D(jjDUMMY),      INT_CMD,         INT_CMD,        INT_CMD       , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjnlInt),      INT_CMD,         INT_CMD,        BIGINT_CMD    , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjnInt),       INT_CMD,         INT_CMD,        NUMBER_CMD    , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjP2I),        INT_CMD,         INT_CMD,        POLY_CMD      , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjINTERRED),   INTERRED_CMD,    IDEAL_CMD,      IDEAL_CMD     , ALLOW_PLURAL |NO_RING}
+,{D(jjINTERRED),   INTERRED_CMD,    MODUL_CMD,      MODUL_CMD     , ALLOW_PLURAL |NO_RING}
+,{D(jjDUMMY),      INTMAT_CMD,      INTMAT_CMD,     INTMAT_CMD    , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjIm2Iv),      INTVEC_CMD,      INTVEC_CMD,     INTMAT_CMD    , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjDUMMY),      INTVEC_CMD,      INTVEC_CMD,     INTVEC_CMD    , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjIS_RINGVAR_P), IS_RINGVAR,    INT_CMD,        POLY_CMD      , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjIS_RINGVAR_S), IS_RINGVAR,    INT_CMD,        STRING_CMD    , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjIS_RINGVAR0),IS_RINGVAR,      INT_CMD,        ANY_TYPE      , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjJACOB_P),    JACOB_CMD,       IDEAL_CMD,      POLY_CMD      , ALLOW_PLURAL |ALLOW_RING}
+,{D(mpJacobi),     JACOB_CMD,       MATRIX_CMD,     IDEAL_CMD     , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjJACOB_M),    JACOB_CMD,       MODUL_CMD,      MODUL_CMD     , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjJanetBasis), JANET_CMD,       IDEAL_CMD,      IDEAL_CMD     , ALLOW_PLURAL |NO_RING}
+,{D(jjKBASE),      KBASE_CMD,       IDEAL_CMD,      IDEAL_CMD     , ALLOW_PLURAL |ALLOW_RING|WARN_RING} /*ring-cf: warning at top level*/
+,{D(jjKBASE),      KBASE_CMD,       MODUL_CMD,      MODUL_CMD     , ALLOW_PLURAL |ALLOW_RING|WARN_RING} /*ring-cf: warning at top level*/
+,{D(jjLU_DECOMP),  LU_CMD,          LIST_CMD,       MATRIX_CMD    , NO_PLURAL |NO_RING}
+,{D(jjPFAC1),      PFAC_CMD,        LIST_CMD,       BIGINT_CMD    , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjPFAC1),      PFAC_CMD,        LIST_CMD,       NUMBER_CMD    , ALLOW_PLURAL |ALLOW_RING}
+,{D(atKILLATTR1),  KILLATTR_CMD,    NONE,           IDHDL         , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjpHead),      LEAD_CMD,        POLY_CMD,       POLY_CMD      , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjidHead),     LEAD_CMD,        IDEAL_CMD,      IDEAL_CMD     , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjpHead),      LEAD_CMD,        VECTOR_CMD,     VECTOR_CMD    , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjidHead),     LEAD_CMD,        MODUL_CMD,      MODUL_CMD     , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjLEADCOEF),   LEADCOEF_CMD,    NUMBER_CMD,     POLY_CMD      , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjLEADCOEF),   LEADCOEF_CMD,    NUMBER_CMD,     VECTOR_CMD    , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjLEADEXP),    LEADEXP_CMD,     INTVEC_CMD,     POLY_CMD      , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjLEADEXP),    LEADEXP_CMD,     INTVEC_CMD,     VECTOR_CMD    , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjLEADMONOM),  LEADMONOM_CMD,   POLY_CMD,       POLY_CMD      , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjLEADMONOM),  LEADMONOM_CMD,   VECTOR_CMD,     VECTOR_CMD    , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjDUMMY),      LINK_CMD,        LINK_CMD,       LINK_CMD      , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjCALL1MANY),  LIST_CMD,        LIST_CMD,       DEF_CMD       , ALLOW_PLURAL |ALLOW_RING}
+,{  jjWRONG ,      MAP_CMD,         0,              ANY_TYPE      , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjDUMMY),      MATRIX_CMD,      MATRIX_CMD,     MATRIX_CMD    , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjidMaxIdeal), MAXID_CMD,       IDEAL_CMD,      INT_CMD       , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjMEMORY),     MEMORY_CMD,      BIGINT_CMD,     INT_CMD       , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjidMinBase),  MINBASE_CMD,     IDEAL_CMD,      IDEAL_CMD     , NO_PLURAL |NO_RING}
+,{D(jjidMinBase),  MINBASE_CMD,     MODUL_CMD,      MODUL_CMD     , NO_PLURAL |NO_RING}
+,{D(jjMINRES),     MINRES_CMD,      LIST_CMD,       LIST_CMD      , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjMINRES_R),   MINRES_CMD,      RESOLUTION_CMD, RESOLUTION_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjDUMMY),      MODUL_CMD,       MODUL_CMD,      MODUL_CMD     , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjMONITOR1),   MONITOR_CMD,     NONE,           LINK_CMD      , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjMONOM),      MONOM_CMD,       POLY_CMD,       INTVEC_CMD    , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjMULT),       MULTIPLICITY_CMD,  INT_CMD,      IDEAL_CMD     , NO_PLURAL |ALLOW_RING}
+,{D(jjMULT),       MULTIPLICITY_CMD,  INT_CMD,      MODUL_CMD     , NO_PLURAL |ALLOW_RING}
+,{D(jjMSTD),       MSTD_CMD,        LIST_CMD,       IDEAL_CMD     , NO_PLURAL |ALLOW_RING}
+,{D(jjMSTD),       MSTD_CMD,        LIST_CMD,       MODUL_CMD     , NO_PLURAL |ALLOW_RING}
+,{D(jjNAMEOF),     NAMEOF_CMD,      STRING_CMD,     ANY_TYPE      , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjNAMES_I),    NAMES_CMD,       LIST_CMD,       INT_CMD       , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjNAMES),      NAMES_CMD,       LIST_CMD,       PACKAGE_CMD   , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjNAMES),      NAMES_CMD,       LIST_CMD,       RING_CMD      , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjNAMES),      NAMES_CMD,       LIST_CMD,       QRING_CMD     , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjNOT),        NOT,             INT_CMD,        INT_CMD       , ALLOW_PLURAL |ALLOW_RING}
+#ifdef SINGULAR_4_1
+,{D(jjN2_N),       NUMBER_CMD,      NUMBER_CMD,     CNUMBER_CMD   , ALLOW_PLURAL |ALLOW_RING}
+#endif
+,{D(jjDUMMY),      NUMBER_CMD,      NUMBER_CMD,     NUMBER_CMD    , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjP2N),        NUMBER_CMD,      NUMBER_CMD,     POLY_CMD      , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjBI2N),       NUMBER_CMD,      NUMBER_CMD,     BIGINT_CMD    , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjRPAR),       NPARS_CMD,       INT_CMD,        RING_CMD      , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjRPAR),       NPARS_CMD,       INT_CMD,        QRING_CMD     , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjNVARS),      NVARS_CMD,       INT_CMD,        RING_CMD      , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjNVARS),      NVARS_CMD,       INT_CMD,        QRING_CMD     , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjOpenClose),  OPEN_CMD,        NONE,           LINK_CMD      , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjCALL1MANY),  OPTION_CMD,      NONE,           DEF_CMD       , ALLOW_PLURAL |ALLOW_RING} /*libsing*/
+,{D(jjORD),        ORD_CMD,         INT_CMD,        POLY_CMD      , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjORD),        ORD_CMD,         INT_CMD,        VECTOR_CMD    , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjrOrdStr),    ORDSTR_CMD,      STRING_CMD,     RING_CMD      , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjrOrdStr),    ORDSTR_CMD,      STRING_CMD,     QRING_CMD     , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjPAR1),       PAR_CMD,         NUMBER_CMD,     INT_CMD       , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjPARDEG),     PARDEG_CMD,      INT_CMD,        NUMBER_CMD    , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjPARSTR1),    PARSTR_CMD,      STRING_CMD,     INT_CMD       , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjrParStr),    PARSTR_CMD,      STRING_CMD,     RING_CMD      , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjrParStr),    PARSTR_CMD,      STRING_CMD,     QRING_CMD     , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjDUMMY),      POLY_CMD,        POLY_CMD,       POLY_CMD      , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjBI2P),       POLY_CMD,        POLY_CMD,       BIGINT_CMD    , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjPREIMAGE_R), PREIMAGE_CMD,    RING_CMD,       MAP_CMD       , NO_PLURAL |ALLOW_RING}
+,{D(jjPRIME),      PRIME_CMD,       INT_CMD,        INT_CMD       , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjPRINT),      PRINT_CMD,       STRING_CMD,     LIST_CMD      , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjPRINT),      PRINT_CMD,       STRING_CMD,     DEF_CMD       , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjDUMMY),      PROC_CMD,        PROC_CMD,       PROC_CMD       , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjPRUNE),      PRUNE_CMD,       MODUL_CMD,      MODUL_CMD     , ALLOW_PLURAL |ALLOW_RING}
+,{D(kQHWeight),    QHWEIGHT_CMD,    INTVEC_CMD,     IDEAL_CMD     , ALLOW_PLURAL |ALLOW_RING}
+,{D(kQHWeight),    QHWEIGHT_CMD,    INTVEC_CMD,     MODUL_CMD     , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjDUMMY),      QRING_CMD,       QRING_CMD,      QRING_CMD      , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjDUMMY),      QRING_CMD,       QRING_CMD,      RING_CMD       , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjRANK1),      RANK_CMD,        INT_CMD,        MATRIX_CMD    , ALLOW_PLURAL |NO_RING}
+,{D(jjREAD),       READ_CMD,        STRING_CMD,     LINK_CMD      , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjREGULARITY), REGULARITY_CMD,  INT_CMD,        LIST_CMD      , NO_PLURAL |ALLOW_RING}
+,{D(jjREPART),     REPART_CMD,      NUMBER_CMD,     NUMBER_CMD    , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjRESERVEDNAME),RESERVEDNAME_CMD, INT_CMD,      STRING_CMD    , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjL2R),        RESOLUTION_CMD,  RESOLUTION_CMD, LIST_CMD      , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjDUMMY),      RESOLUTION_CMD,  RESOLUTION_CMD, RESOLUTION_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjRINGLIST),   RINGLIST_CMD,    LIST_CMD,       RING_CMD      , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjRINGLIST),   RINGLIST_CMD,    LIST_CMD,       QRING_CMD     , ALLOW_PLURAL |ALLOW_RING}
+#ifdef SINGULAR_4_1
+,{D(jjN2_CR),      RING_CMD,        CRING_CMD,      CNUMBER_CMD   , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjCM_CR),      RING_CMD,        CRING_CMD,      CMATRIX_CMD   , ALLOW_PLURAL |ALLOW_RING}
+#endif
+,{D(jjDUMMY),      RING_CMD,        RING_CMD,       RING_CMD      , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjLISTRING),   RING_CMD,        RING_CMD,       LIST_CMD      , ALLOW_PLURAL |ALLOW_RING}
+//,{  jjWRONG ,      ROWS_CMD,        0,              POLY_CMD    , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjpMaxComp),   ROWS_CMD,        INT_CMD,        VECTOR_CMD    , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjROWS),       ROWS_CMD,        INT_CMD,        MODUL_CMD     , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjROWS),       ROWS_CMD,        INT_CMD,        MATRIX_CMD    , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjROWS_IV),    ROWS_CMD,        INT_CMD,        INTMAT_CMD    , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjROWS_BIM),   ROWS_CMD,        INT_CMD,        BIGINTMAT_CMD , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjCOUNT_IV),   ROWS_CMD,        INT_CMD,        INTVEC_CMD    , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjSBA),        SBA_CMD,         IDEAL_CMD,      IDEAL_CMD     , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjSBA),        SBA_CMD,         MODUL_CMD,      MODUL_CMD     , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjSLIM_GB),    SLIM_GB_CMD,     IDEAL_CMD,      IDEAL_CMD     , ALLOW_PLURAL }
+,{D(jjSLIM_GB),    SLIM_GB_CMD,     MODUL_CMD,      MODUL_CMD     , ALLOW_PLURAL }
+,{D(jjSort_Id),    SORTVEC_CMD,     INTVEC_CMD,     IDEAL_CMD     , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjSort_Id),    SORTVEC_CMD,     INTVEC_CMD,     MODUL_CMD     , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjSQR_FREE),   SQR_FREE_CMD,    LIST_CMD,      POLY_CMD      , NO_PLURAL |NO_RING}
+,{D(jjSTD),        STD_CMD,         IDEAL_CMD,      IDEAL_CMD     , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjSTD),        STD_CMD,         MODUL_CMD,      MODUL_CMD     , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjDUMMY),      STRING_CMD,      STRING_CMD,     STRING_CMD    , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjSYZYGY),     SYZYGY_CMD,      MODUL_CMD,      IDEAL_CMD     , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjSYZYGY),     SYZYGY_CMD,      MODUL_CMD,      MODUL_CMD     , ALLOW_PLURAL |ALLOW_RING}
+#ifdef HAVE_PLURAL
+,{D(jjENVELOPE),   ENVELOPE_CMD,    RING_CMD,       RING_CMD      , ALLOW_PLURAL |NO_RING}
+,{D(jjENVELOPE),   ENVELOPE_CMD,    QRING_CMD,      QRING_CMD     , ALLOW_PLURAL |NO_RING}
+,{D(jjOPPOSITE),   OPPOSITE_CMD,    RING_CMD,       RING_CMD      , ALLOW_PLURAL |NO_RING}
+,{D(jjOPPOSITE),   OPPOSITE_CMD,    QRING_CMD,      QRING_CMD     , ALLOW_PLURAL |NO_RING}
+,{D(jjTWOSTD),     TWOSTD_CMD,      IDEAL_CMD,      IDEAL_CMD     , ALLOW_PLURAL |NO_RING}
+#endif
+,{  jjWRONG ,      TRACE_CMD,       0,              INTVEC_CMD    , ALLOW_PLURAL |ALLOW_RING}
+,{  jjWRONG ,      TRACE_CMD,       0,              IDEAL_CMD     , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjTRACE_IV),   TRACE_CMD,       INT_CMD,        INTMAT_CMD    , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjmpTrace),    TRACE_CMD,       POLY_CMD,       MATRIX_CMD    , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjTRANSP_IV),  TRANSPOSE_CMD,   INTMAT_CMD,     INTVEC_CMD    , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjTRANSP_IV),  TRANSPOSE_CMD,   INTMAT_CMD,     INTMAT_CMD    , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjTRANSP_BIM), TRANSPOSE_CMD,   BIGINTMAT_CMD,  BIGINTMAT_CMD , ALLOW_PLURAL |ALLOW_RING}
+#ifdef SINGULAR_4_1
+,{D(jjTRANSP_BIM), TRANSPOSE_CMD,   CMATRIX_CMD,    CMATRIX_CMD ,   ALLOW_PLURAL |ALLOW_RING}
+#endif
+,{D(jjmpTransp),   TRANSPOSE_CMD,   MATRIX_CMD,     MATRIX_CMD    , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjidTransp),   TRANSPOSE_CMD,   MODUL_CMD,      MODUL_CMD     , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjTYPEOF),     TYPEOF_CMD,      STRING_CMD,     ANY_TYPE      , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjUNIVARIATE), UNIVARIATE_CMD,  INT_CMD,        POLY_CMD      , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjVARIABLES_P),VARIABLES_CMD,   IDEAL_CMD,      POLY_CMD      , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjVARIABLES_ID),VARIABLES_CMD,  IDEAL_CMD,      IDEAL_CMD     , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjVARIABLES_ID),VARIABLES_CMD,  IDEAL_CMD,      MATRIX_CMD    , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjDUMMY),      VECTOR_CMD,      VECTOR_CMD,     VECTOR_CMD    , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjVDIM),       VDIM_CMD,        INT_CMD,        IDEAL_CMD     , ALLOW_PLURAL |ALLOW_RING |WARN_RING} /*ring-cf: warning at top level*/
+,{D(jjVDIM),       VDIM_CMD,        INT_CMD,        MODUL_CMD     , ALLOW_PLURAL |ALLOW_RING |WARN_RING} /*ring-cf: warning at top level*/
+,{D(jjVAR1),       VAR_CMD,         POLY_CMD,       INT_CMD       , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjVARSTR1),    VARSTR_CMD,      STRING_CMD,     INT_CMD       , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjrVarStr),    VARSTR_CMD,      STRING_CMD,     RING_CMD      , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjrVarStr),    VARSTR_CMD,      STRING_CMD,     QRING_CMD     , ALLOW_PLURAL |ALLOW_RING}
+,{D(kWeight),      WEIGHT_CMD,      INTVEC_CMD,     IDEAL_CMD     , ALLOW_PLURAL |ALLOW_RING}
+,{D(kWeight),      WEIGHT_CMD,      INTVEC_CMD,     MODUL_CMD     , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjLOAD1),      LOAD_CMD,        NONE,           STRING_CMD    , ALLOW_PLURAL |ALLOW_RING}
+,{D(loNewtonP),    NEWTONPOLY_CMD,  IDEAL_CMD,      IDEAL_CMD     , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjWAIT1ST1),   WAIT1ST_CMD,     INT_CMD,        LIST_CMD      , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjWAITALL1),   WAITALL_CMD,     INT_CMD,        LIST_CMD      , ALLOW_PLURAL |ALLOW_RING}
+,{NULL_VAL,        0,               0,              0             , NO_PLURAL |NO_RING}
+};
+/*=================== operations with 2 arg.: table =================*/
+struct sValCmd2 dArith2[]=
+{
+// operations:
+// proc           cmd              res             arg1        arg2   context
+ {D(jjCOLCOL),    COLONCOLON,     ANY_TYPE,       DEF_CMD,    DEF_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjPLUS_I),    '+',            INT_CMD,        INT_CMD,    INT_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjPLUS_BI),   '+',            BIGINT_CMD,     BIGINT_CMD, BIGINT_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjPLUS_N),    '+',            NUMBER_CMD,     NUMBER_CMD, NUMBER_CMD, ALLOW_PLURAL | ALLOW_RING}
+#ifdef SINGULAR_4_1
+,{D(jjNUMBER2_OP2),'+',           CNUMBER_CMD,    CNUMBER_CMD,CNUMBER_CMD, ALLOW_PLURAL | ALLOW_RING}
+#endif
+,{D(jjPLUS_P),    '+',            POLY_CMD,       POLY_CMD,   POLY_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjPLUS_P),    '+',            VECTOR_CMD,     VECTOR_CMD, VECTOR_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjPLUS_ID),   '+',            IDEAL_CMD,      IDEAL_CMD,  IDEAL_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjPLUS_ID),   '+',            MODUL_CMD,      MODUL_CMD,  MODUL_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjPLUS_P_MA), '+',            MATRIX_CMD,     POLY_CMD,   MATRIX_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjPLUS_MA_P), '+',            MATRIX_CMD,     MATRIX_CMD, POLY_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjPLUS_MA),   '+',            MATRIX_CMD,     MATRIX_CMD, MATRIX_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjPLUS_S),    '+',            STRING_CMD,     STRING_CMD, STRING_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjOP_IV_I),   '+',            INTVEC_CMD,     INTVEC_CMD, INT_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjOP_I_IV),   '+',            INTVEC_CMD,     INT_CMD,    INTVEC_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjOP_IM_I),   '+',            INTMAT_CMD,     INTMAT_CMD, INT_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjOP_I_IM),   '+',            INTMAT_CMD,     INT_CMD,    INTMAT_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjPLUS_IV),   '+',            INTVEC_CMD,     INTVEC_CMD, INTVEC_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjPLUS_IV),   '+',            INTMAT_CMD,     INTMAT_CMD, INTMAT_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjPLUS_BIM),  '+',            BIGINTMAT_CMD,  BIGINTMAT_CMD, BIGINTMAT_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjOP_BIM_I),  '+',            BIGINTMAT_CMD,  BIGINTMAT_CMD, INT_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjOP_I_BIM),  '+',            BIGINTMAT_CMD,  INT_CMD, BIGINTMAT_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjOP_BIM_BI),  '+',           BIGINTMAT_CMD,  BIGINTMAT_CMD, BIGINT_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjOP_BI_BIM),  '+',           BIGINTMAT_CMD,  BIGINT_CMD, BIGINTMAT_CMD, ALLOW_PLURAL | ALLOW_RING}
+#ifdef SINGULAR_4_1
+,{D(jjPLUS_BIM),  '+',            CMATRIX_CMD,    CMATRIX_CMD, CMATRIX_CMD, ALLOW_PLURAL | ALLOW_RING}
+#endif
+,{D(lAdd),        '+',            LIST_CMD,       LIST_CMD,   LIST_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjRSUM),      '+',            RING_CMD,       RING_CMD,   RING_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjRSUM),      '+',            QRING_CMD,      QRING_CMD,  RING_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjRSUM),      '+',            QRING_CMD,      RING_CMD,   QRING_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjRSUM),      '+',            QRING_CMD,      QRING_CMD,  QRING_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjMINUS_I),   '-',            INT_CMD,        INT_CMD,    INT_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjMINUS_BI),  '-',            BIGINT_CMD,     BIGINT_CMD, BIGINT_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjMINUS_N),   '-',            NUMBER_CMD,     NUMBER_CMD, NUMBER_CMD, ALLOW_PLURAL | ALLOW_RING}
+#ifdef SINGULAR_4_1
+,{D(jjNUMBER2_OP2),'-',           CNUMBER_CMD,    CNUMBER_CMD,CNUMBER_CMD, ALLOW_PLURAL | ALLOW_RING}
+#endif
+,{D(jjMINUS_P),   '-',            POLY_CMD,       POLY_CMD,   POLY_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjMINUS_P),   '-',            VECTOR_CMD,     VECTOR_CMD, VECTOR_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjPLUS_MA_P), '-',            MATRIX_CMD,     MATRIX_CMD, POLY_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjMINUS_MA),  '-',            MATRIX_CMD,     MATRIX_CMD, MATRIX_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjOP_IV_I),   '-',            INTVEC_CMD,     INTVEC_CMD, INT_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjOP_IM_I),   '-',            INTMAT_CMD,     INTMAT_CMD, INT_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjMINUS_IV),  '-',            INTVEC_CMD,     INTVEC_CMD, INTVEC_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjMINUS_IV),  '-',            INTMAT_CMD,     INTMAT_CMD, INTMAT_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjMINUS_BIM), '-',            BIGINTMAT_CMD,  BIGINTMAT_CMD, BIGINTMAT_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjOP_BIM_I),  '-',            BIGINTMAT_CMD,  BIGINTMAT_CMD, INT_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjOP_I_BIM),  '-',            BIGINTMAT_CMD,  INT_CMD, BIGINTMAT_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjOP_BIM_BI),  '-',           BIGINTMAT_CMD,  BIGINTMAT_CMD, BIGINT_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjOP_BI_BIM),  '-',           BIGINTMAT_CMD,  BIGINT_CMD, BIGINTMAT_CMD, ALLOW_PLURAL | ALLOW_RING}
+#ifdef SINGULAR_4_1
+,{D(jjMINUS_BIM), '-',            CMATRIX_CMD,    CMATRIX_CMD,CMATRIX_CMD, ALLOW_PLURAL | ALLOW_RING}
+#endif
+,{  jjWRONG2 ,    '-',            NONE,           IDEAL_CMD,  IDEAL_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{  jjWRONG2 ,    '-',            NONE,           MODUL_CMD,  MODUL_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjTIMES_I),   '*',            INT_CMD,        INT_CMD,    INT_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjTIMES_BI),  '*',            BIGINT_CMD,     BIGINT_CMD, BIGINT_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjTIMES_N),   '*',            NUMBER_CMD,     NUMBER_CMD, NUMBER_CMD, ALLOW_PLURAL | ALLOW_RING}
+#ifdef SINGULAR_4_1
+,{D(jjNUMBER2_OP2),'*',           CNUMBER_CMD,    CNUMBER_CMD,CNUMBER_CMD, ALLOW_PLURAL | ALLOW_RING}
+#endif
+,{D(jjTIMES_P),   '*',            POLY_CMD,       POLY_CMD,   POLY_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjTIMES_P),   '*',            VECTOR_CMD,     POLY_CMD,   VECTOR_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjTIMES_P),   '*',            VECTOR_CMD,     VECTOR_CMD, POLY_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjTIMES_MA_P1),'*',           IDEAL_CMD,      IDEAL_CMD,  POLY_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjTIMES_MA_P2),'*',           IDEAL_CMD,      POLY_CMD,   IDEAL_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjTIMES_MA_P1),'*',           MODUL_CMD,      MODUL_CMD,  POLY_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjTIMES_MA_P2),'*',           MODUL_CMD,      POLY_CMD,   MODUL_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjTIMES_ID),  '*',            IDEAL_CMD,      IDEAL_CMD,  IDEAL_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjTIMES_MA_P1),'*',           MODUL_CMD,      IDEAL_CMD,  VECTOR_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjTIMES_MA_P2),'*',           MODUL_CMD,      VECTOR_CMD, IDEAL_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjTIMES_ID),  '*',            MODUL_CMD,      IDEAL_CMD,  MODUL_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjTIMES_ID),  '*',            MODUL_CMD,      MODUL_CMD,  IDEAL_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjTIMES_MA_P1),'*',           MATRIX_CMD,     MATRIX_CMD, POLY_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjTIMES_MA_P2),'*',           MATRIX_CMD,     POLY_CMD,   MATRIX_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjTIMES_MA_N1),'*',           MATRIX_CMD,     MATRIX_CMD, NUMBER_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjTIMES_MA_N2),'*',           MATRIX_CMD,     NUMBER_CMD, MATRIX_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjTIMES_MA_I1),'*',           MATRIX_CMD,     MATRIX_CMD, INT_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjTIMES_MA_I2),'*',           MATRIX_CMD,     INT_CMD,    MATRIX_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjTIMES_MA),  '*',            MATRIX_CMD,     MATRIX_CMD, MATRIX_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjTIMES_MA_BI1),'*',          MATRIX_CMD,     MATRIX_CMD, BIGINT_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjTIMES_MA_BI2),'*',          MATRIX_CMD,     BIGINT_CMD, MATRIX_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjOP_IV_I),   '*',            INTVEC_CMD,     INTVEC_CMD, INT_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjOP_I_IV),   '*',            INTVEC_CMD,     INT_CMD,    INTVEC_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjOP_IV_I),   '*',            INTMAT_CMD,     INTMAT_CMD, INT_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjOP_I_IV),   '*',            INTMAT_CMD,     INT_CMD,    INTMAT_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjTIMES_IV),  '*',            INTVEC_CMD,     INTMAT_CMD, INTVEC_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjTIMES_IV),  '*',            INTMAT_CMD,     INTMAT_CMD, INTMAT_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjTIMES_IV),  '*',            INTMAT_CMD,     INTVEC_CMD, INTMAT_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjTIMES_BIM), '*',            BIGINTMAT_CMD,  BIGINTMAT_CMD, BIGINTMAT_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjOP_BIM_I),  '*',            BIGINTMAT_CMD,  BIGINTMAT_CMD, INT_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjOP_I_BIM),  '*',            BIGINTMAT_CMD,  INT_CMD, BIGINTMAT_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjOP_BIM_BI),  '*',           BIGINTMAT_CMD,  BIGINTMAT_CMD, BIGINT_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjOP_BI_BIM),  '*',           BIGINTMAT_CMD,  BIGINT_CMD, BIGINTMAT_CMD, ALLOW_PLURAL | ALLOW_RING}
+#ifdef SINGULAR_4_1
+,{D(jjTIMES_BIM), '*',            CMATRIX_CMD,    CMATRIX_CMD, CMATRIX_CMD, ALLOW_PLURAL | ALLOW_RING}
+#endif
+,{D(jjDIV_N),     '/',            NUMBER_CMD,     NUMBER_CMD, NUMBER_CMD, ALLOW_PLURAL | ALLOW_RING}
+#ifdef SINGULAR_4_1
+,{D(jjNUMBER2_OP2),'/',           CNUMBER_CMD,    CNUMBER_CMD,CNUMBER_CMD, ALLOW_PLURAL | ALLOW_RING}
+#endif
+,{D(jjDIV_P),     '/',            POLY_CMD,       POLY_CMD,   POLY_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjDIV_P),     '/',            VECTOR_CMD,     VECTOR_CMD, POLY_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjDIV_Ma),    '/',            MATRIX_CMD,     MATRIX_CMD, POLY_CMD, ALLOW_PLURAL | NO_RING}
+,{D(jjDIVMOD_I),  '/',            INT_CMD,        INT_CMD,    INT_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjDIV_BI),    '/',            BIGINT_CMD,     BIGINT_CMD, BIGINT_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjOP_IV_I),   '/',            INTVEC_CMD,     INTVEC_CMD, INT_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjOP_IV_I),   '/',            INTMAT_CMD,     INTMAT_CMD, INT_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjDIVMOD_I),  INTDIV_CMD,     INT_CMD,        INT_CMD,    INT_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjDIV_BI),    INTDIV_CMD,     BIGINT_CMD,     BIGINT_CMD, BIGINT_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjOP_IV_I),   INTDIV_CMD,     INTVEC_CMD,     INTVEC_CMD, INT_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjOP_IV_I),   INTDIV_CMD,     INTMAT_CMD,     INTMAT_CMD, INT_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjDIVMOD_I),  '%',            INT_CMD,        INT_CMD,    INT_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjMOD_BI),    '%',            BIGINT_CMD,     BIGINT_CMD, BIGINT_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjOP_IV_I),   '%',            INTVEC_CMD,     INTVEC_CMD, INT_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjOP_IV_I),   '%',            INTMAT_CMD,     INTMAT_CMD, INT_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjMOD_N),     '%',            NUMBER_CMD,     NUMBER_CMD, NUMBER_CMD, ALLOW_PLURAL | ALLOW_RING}
+#ifdef SINGULAR_4_1
+,{D(jjNUMBER2_OP2),'%',           CNUMBER_CMD,    CNUMBER_CMD,CNUMBER_CMD, ALLOW_PLURAL | ALLOW_RING}
+#endif
+,{D(jjPOWER_I),   '^',            INT_CMD,        INT_CMD,    INT_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjPOWER_BI),   '^',           BIGINT_CMD,     BIGINT_CMD, INT_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjPOWER_N),   '^',            NUMBER_CMD,     NUMBER_CMD, INT_CMD, ALLOW_PLURAL | ALLOW_RING}
+#ifdef SINGULAR_4_1
+,{D(jjNUMBER2_OP2),'^',           CNUMBER_CMD,    CNUMBER_CMD,INT_CMD, ALLOW_PLURAL | ALLOW_RING}
+#endif
+,{D(jjPOWER_P),   '^',            POLY_CMD,       POLY_CMD,   INT_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjPOWER_ID),  '^',            IDEAL_CMD,      IDEAL_CMD,  INT_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjLE_I),      LE,             INT_CMD,        INT_CMD,    INT_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjLE_BI),     LE,             INT_CMD,        BIGINT_CMD, BIGINT_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjLE_N),      LE,             INT_CMD,        NUMBER_CMD, NUMBER_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjCOMPARE_S), LE,             INT_CMD,        STRING_CMD, STRING_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjCOMPARE_IV_I),LE,           INT_CMD,        INTVEC_CMD, INT_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjCOMPARE_IV),LE,             INT_CMD,        INTVEC_CMD, INTVEC_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjCOMPARE_P), LE,             INT_CMD,        POLY_CMD,   POLY_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjCOMPARE_P), LE,             INT_CMD,        VECTOR_CMD, VECTOR_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjLT_I),      '<',            INT_CMD,        INT_CMD,    INT_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjLT_BI),     '<',            INT_CMD,        BIGINT_CMD, BIGINT_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjLT_N),      '<',            INT_CMD,        NUMBER_CMD, NUMBER_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjCOMPARE_IV_I),'<',          INT_CMD,        INTVEC_CMD, INT_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjCOMPARE_IV),'<',            INT_CMD,        INTVEC_CMD, INTVEC_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjCOMPARE_S), '<',            INT_CMD,        STRING_CMD, STRING_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjCOMPARE_P), '<',            INT_CMD,        POLY_CMD,   POLY_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjCOMPARE_P), '<',            INT_CMD,        VECTOR_CMD, VECTOR_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjGE_I),      GE,             INT_CMD,        INT_CMD,    INT_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjGE_BI),     GE,             INT_CMD,        BIGINT_CMD, BIGINT_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjGE_N),      GE,             INT_CMD,        NUMBER_CMD, NUMBER_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjCOMPARE_S), GE,             INT_CMD,        STRING_CMD, STRING_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjCOMPARE_IV_I),GE,           INT_CMD,        INTVEC_CMD, INT_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjCOMPARE_IV),GE,             INT_CMD,        INTVEC_CMD, INTVEC_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjCOMPARE_P), GE,             INT_CMD,        POLY_CMD,   POLY_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjCOMPARE_P), GE,             INT_CMD,        VECTOR_CMD, VECTOR_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjGT_I),      '>',            INT_CMD,        INT_CMD,    INT_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjGT_BI),     '>',            INT_CMD,        BIGINT_CMD, BIGINT_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjGT_N),      '>',            INT_CMD,        NUMBER_CMD, NUMBER_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjCOMPARE_S), '>',            INT_CMD,        STRING_CMD, STRING_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjCOMPARE_IV_I),'>',          INT_CMD,        INTVEC_CMD, INT_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjCOMPARE_IV),'>',            INT_CMD,        INTVEC_CMD, INTVEC_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjCOMPARE_P), '>',            INT_CMD,        POLY_CMD,   POLY_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjCOMPARE_P), '>',            INT_CMD,        VECTOR_CMD, VECTOR_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjAND_I),     '&',            INT_CMD,        INT_CMD,    INT_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjOR_I),      '|',            INT_CMD,        INT_CMD,    INT_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjEQUAL_I),   EQUAL_EQUAL,    INT_CMD,        INT_CMD,    INT_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjEQUAL_BI),  EQUAL_EQUAL,    INT_CMD,        BIGINT_CMD, BIGINT_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjEQUAL_N),   EQUAL_EQUAL,    INT_CMD,        NUMBER_CMD, NUMBER_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjCOMPARE_S), EQUAL_EQUAL,    INT_CMD,        STRING_CMD, STRING_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjEQUAL_P),   EQUAL_EQUAL,    INT_CMD,        POLY_CMD,   POLY_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjEQUAL_P),   EQUAL_EQUAL,    INT_CMD,        VECTOR_CMD, VECTOR_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjCOMPARE_IV_I),EQUAL_EQUAL,  INT_CMD,        INTVEC_CMD, INT_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjCOMPARE_IV),EQUAL_EQUAL,    INT_CMD,        INTVEC_CMD, INTVEC_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjCOMPARE_IV),EQUAL_EQUAL,    INT_CMD,        INTMAT_CMD, INTMAT_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjCOMPARE_BIM),EQUAL_EQUAL,   INT_CMD,        BIGINTMAT_CMD, BIGINTMAT_CMD, ALLOW_PLURAL | ALLOW_RING}
+#ifdef SINGULAR_4_1
+,{D(jjCOMPARE_BIM),EQUAL_EQUAL,   INT_CMD,        CMATRIX_CMD, CMATRIX_CMD, ALLOW_PLURAL | ALLOW_RING}
+#endif
+,{D(jjEQUAL_Ma),  EQUAL_EQUAL,    INT_CMD,        MATRIX_CMD, MATRIX_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{  jjWRONG2 ,    EQUAL_EQUAL,    0,              IDEAL_CMD,  IDEAL_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{  jjWRONG2 ,    EQUAL_EQUAL,    0,              MODUL_CMD,  MODUL_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{  jjWRONG2 ,    EQUAL_EQUAL,    0,              IDEAL_CMD,  MODUL_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{  jjWRONG2 ,    EQUAL_EQUAL,    0,              MODUL_CMD,  IDEAL_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjEQUAL_I),   NOTEQUAL,       INT_CMD,        INT_CMD,    INT_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjEQUAL_BI),  NOTEQUAL,       INT_CMD,        BIGINT_CMD, BIGINT_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjEQUAL_N),   NOTEQUAL,       INT_CMD,        NUMBER_CMD, NUMBER_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjCOMPARE_S), NOTEQUAL,       INT_CMD,        STRING_CMD, STRING_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjEQUAL_P),   NOTEQUAL,       INT_CMD,        POLY_CMD,   POLY_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjEQUAL_P),   NOTEQUAL,       INT_CMD,        VECTOR_CMD, VECTOR_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjCOMPARE_IV),NOTEQUAL,       INT_CMD,        INTVEC_CMD, INTVEC_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjCOMPARE_IV),NOTEQUAL,       INT_CMD,        INTMAT_CMD, INTMAT_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjEQUAL_Ma),  NOTEQUAL,       INT_CMD,        MATRIX_CMD, MATRIX_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{  jjWRONG2 ,    NOTEQUAL,       0,              IDEAL_CMD,  IDEAL_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{  jjWRONG2 ,    NOTEQUAL,       0,              MODUL_CMD,  MODUL_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{  jjWRONG2 ,    NOTEQUAL,       0,              IDEAL_CMD,  MODUL_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{  jjWRONG2 ,    NOTEQUAL,       0,              MODUL_CMD,  IDEAL_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjDOTDOT),    DOTDOT,         INTVEC_CMD,     INT_CMD,    INT_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjINDEX_I),   '[',            INT_CMD,        INTVEC_CMD, INT_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjINDEX_IV),  '[',            INT_CMD,        INTVEC_CMD, INTVEC_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjINDEX_I),   '[',            POLY_CMD,       IDEAL_CMD,  INT_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjINDEX_I),   '[',            POLY_CMD,       MAP_CMD,    INT_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjINDEX_IV),  '[',            POLY_CMD,       IDEAL_CMD,  INTVEC_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjINDEX_I),   '[',            VECTOR_CMD,     MODUL_CMD,  INT_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjINDEX_IV),  '[',            VECTOR_CMD,     MODUL_CMD,  INTVEC_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjINDEX_I),   '[',            STRING_CMD,     STRING_CMD, INT_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjINDEX_IV),  '[',            STRING_CMD,     STRING_CMD, INTVEC_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjINDEX_I),   '[',            ANY_TYPE/*set by p*/,LIST_CMD, INT_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjINDEX_IV),  '[',            ANY_TYPE/*set by p*/,LIST_CMD, INTVEC_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjINDEX_P),   '[',            POLY_CMD,       POLY_CMD,   INT_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjINDEX_P_IV),'[',            POLY_CMD,       POLY_CMD,   INTVEC_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjINDEX_V),   '[',            POLY_CMD,       VECTOR_CMD, INT_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjINDEX_V_IV),'[',            VECTOR_CMD,     VECTOR_CMD, INTVEC_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjPROC),      '(',            ANY_TYPE/*set by p*/,PROC_CMD, DEF_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjMAP),       '(',            ANY_TYPE/*set by p*/,MAP_CMD, DEF_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjLOAD2),     '(',            NONE,             LIB_CMD,    STRING_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjKLAMMER),   '(',            ANY_TYPE/*set by p*/,ANY_TYPE, INT_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjKLAMMER_IV),'(',            ANY_TYPE/*set by p*/,ANY_TYPE, INTVEC_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjCOLON),     ':',            INTVEC_CMD,     INT_CMD,    INT_CMD, ALLOW_PLURAL | ALLOW_RING}
+// and the procedures with 2 arguments:
+,{D(atATTRIB2),   ATTRIB_CMD,     NONE/*set by p*/,DEF_CMD,   STRING_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjBETTI2),    BETTI_CMD,      INTMAT_CMD,     LIST_CMD,   INT_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(syBetti2),    BETTI_CMD,      INTMAT_CMD,     RESOLUTION_CMD, INT_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjBETTI2_ID), BETTI_CMD,      INTMAT_CMD,     IDEAL_CMD,  INT_CMD, ALLOW_PLURAL | ALLOW_RING}
+,{D(jjBETTI2_ID), BETTI_CMD,      INTMAT_CMD,     MODUL_CMD,  INT_CMD, ALLOW_PLURAL | ALLOW_RING}
+#ifdef HAVE_PLURAL
+,{D(jjBRACKET),   BRACKET_CMD,    POLY_CMD,       POLY_CMD,   POLY_CMD, ALLOW_PLURAL | NO_RING}
+#endif
+,{D(jjCHINREM_BI),CHINREM_CMD,    BIGINT_CMD,     INTVEC_CMD, INTVEC_CMD, ALLOW_PLURAL |ALLOW_RING}
+//,{D(jjCHINREM_P), CHINREM_CMD,    POLY_CMD,       LIST_CMD,   INTVEC_CMD, ALLOW_PLURAL}
+,{D(jjCHINREM_ID),CHINREM_CMD,    ANY_TYPE/*set by p*/,LIST_CMD,INTVEC_CMD, ALLOW_PLURAL |NO_RING}
+,{D(jjCHINREM_ID),CHINREM_CMD,    ANY_TYPE/*set by p*/,LIST_CMD,LIST_CMD, ALLOW_PLURAL |NO_RING}
+#ifdef SINGULAR_4_1
+,{D(jjNUMBER2CR), CNUMBER_CMD,    CNUMBER_CMD,     INT_CMD,    CRING_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjNUMBER2CR), CNUMBER_CMD,    CNUMBER_CMD,     BIGINT_CMD, CRING_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjNUMBER2CR), CNUMBER_CMD,    CNUMBER_CMD,     NUMBER_CMD, CRING_CMD, ALLOW_PLURAL |ALLOW_RING}
+#endif
+,{D(jjCOEF),      COEF_CMD,       MATRIX_CMD,     POLY_CMD,   POLY_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjCOEFFS_Id), COEFFS_CMD,     MATRIX_CMD,     IDEAL_CMD,  POLY_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjCOEFFS_Id), COEFFS_CMD,     MATRIX_CMD,     MODUL_CMD,  POLY_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjCOEFFS2_KB),COEFFS_CMD,     MATRIX_CMD,     IDEAL_CMD,  IDEAL_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjCOEFFS2_KB),COEFFS_CMD,     MATRIX_CMD,     MODUL_CMD,  MODUL_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjCONTRACT),  CONTRACT_CMD,   MATRIX_CMD,     IDEAL_CMD,  IDEAL_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjDEG_IV),    DEG_CMD,        INT_CMD,        POLY_CMD,   INTVEC_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjDEG_IV),    DEG_CMD,        INT_CMD,        VECTOR_CMD, INTVEC_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjDEG_M_IV),  DEG_CMD,        INT_CMD,        MATRIX_CMD, INTVEC_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(lDelete),     DELETE_CMD,     LIST_CMD,       LIST_CMD,   INT_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjDIFF_P),    DIFF_CMD,       POLY_CMD,       POLY_CMD,   POLY_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjDIFF_P),    DIFF_CMD,       VECTOR_CMD,     VECTOR_CMD, POLY_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjDIFF_ID),   DIFF_CMD,       IDEAL_CMD,      IDEAL_CMD,  POLY_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjDIFF_ID_ID),DIFF_CMD,       MATRIX_CMD,     IDEAL_CMD,  IDEAL_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjDIFF_ID),   DIFF_CMD,       MODUL_CMD,      MODUL_CMD,  POLY_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjDIFF_ID),   DIFF_CMD,       MATRIX_CMD,     MATRIX_CMD, POLY_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjDIFF_COEF), DIFF_CMD,       NUMBER_CMD,     NUMBER_CMD, NUMBER_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjDIM2),      DIM_CMD,        INT_CMD,        IDEAL_CMD,  IDEAL_CMD, ALLOW_PLURAL |NO_RING}
+,{D(jjDIM2),      DIM_CMD,        INT_CMD,        MODUL_CMD,  IDEAL_CMD, ALLOW_PLURAL |NO_RING}
+,{D(jjDIVISION),  DIVISION_CMD,   LIST_CMD,       IDEAL_CMD,  IDEAL_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjDIVISION),  DIVISION_CMD,   LIST_CMD,       MODUL_CMD,  MODUL_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjELIMIN),    ELIMINATION_CMD,IDEAL_CMD,      IDEAL_CMD,  POLY_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjELIMIN),    ELIMINATION_CMD,MODUL_CMD,      MODUL_CMD,  POLY_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjELIMIN_IV), ELIMINATION_CMD,IDEAL_CMD,      IDEAL_CMD,  INTVEC_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjELIMIN_IV), ELIMINATION_CMD,MODUL_CMD,      MODUL_CMD,  INTVEC_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjEXPORTTO),  EXPORTTO_CMD,   NONE,           PACKAGE_CMD, IDHDL, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjEXTGCD_I),  EXTGCD_CMD,     LIST_CMD,       INT_CMD,    INT_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjEXTGCD_BI), EXTGCD_CMD,     LIST_CMD,       BIGINT_CMD, BIGINT_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjEXTGCD_P),  EXTGCD_CMD,     LIST_CMD,       POLY_CMD,   POLY_CMD, NO_PLURAL |NO_RING}
+,{D(jjFAC_P2),    FAC_CMD,        IDEAL_CMD,      POLY_CMD,   INT_CMD, NO_PLURAL |NO_RING}
+,{D(jjFACSTD2),   FACSTD_CMD,     LIST_CMD,       IDEAL_CMD,  IDEAL_CMD, NO_PLURAL |NO_RING}
+,{D(jjFAREY_BI),  FAREY_CMD,      NUMBER_CMD,     BIGINT_CMD,  BIGINT_CMD, ALLOW_PLURAL |NO_RING}
+,{D(jjFAREY_ID),  FAREY_CMD,     ANY_TYPE/*set by p*/,IDEAL_CMD,BIGINT_CMD, ALLOW_PLURAL |NO_RING}
+,{D(jjFAREY_ID),  FAREY_CMD,     ANY_TYPE/*set by p*/,MODUL_CMD,BIGINT_CMD, ALLOW_PLURAL |NO_RING}
+,{D(jjFAREY_ID),  FAREY_CMD,     ANY_TYPE/*set by p*/,MATRIX_CMD,BIGINT_CMD, ALLOW_PLURAL |NO_RING}
+,{D(jjFETCH),     FETCH_CMD,      ANY_TYPE/*set by p*/,RING_CMD,  ANY_TYPE, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjFETCH),     FETCH_CMD,      ANY_TYPE/*set by p*/,QRING_CMD, ANY_TYPE, ALLOW_PLURAL |ALLOW_RING}
+,{D(fglmProc),    FGLM_CMD,       IDEAL_CMD,      RING_CMD,   DEF_CMD, NO_PLURAL |NO_RING}
+,{D(fglmProc),    FGLM_CMD,       IDEAL_CMD,      QRING_CMD,  DEF_CMD, NO_PLURAL |NO_RING}
+,{D(fglmQuotProc),FGLMQUOT_CMD,   IDEAL_CMD,      IDEAL_CMD,  POLY_CMD, NO_PLURAL |NO_RING}
+,{D(jjFIND2),     FIND_CMD,       INT_CMD,        STRING_CMD, STRING_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjFWALK),     FWALK_CMD,      IDEAL_CMD,      RING_CMD,   DEF_CMD, NO_PLURAL |NO_RING}
+,{D(jjGCD_I),     GCD_CMD,        INT_CMD,        INT_CMD,    INT_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjGCD_N),     GCD_CMD,        NUMBER_CMD,     NUMBER_CMD, NUMBER_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjGCD_BI),    GCD_CMD,        BIGINT_CMD,     BIGINT_CMD, BIGINT_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjGCD_P),     GCD_CMD,        POLY_CMD,       POLY_CMD,   POLY_CMD, NO_PLURAL |ALLOW_RING}
+,{D(jjHILBERT2),  HILBERT_CMD,    INTVEC_CMD,     IDEAL_CMD,  INT_CMD, NO_PLURAL | ALLOW_RING | NO_ZERODIVISOR}
+,{D(jjHILBERT2),  HILBERT_CMD,    INTVEC_CMD,     MODUL_CMD,  INT_CMD, NO_PLURAL | ALLOW_RING | NO_ZERODIVISOR}
+,{D(jjHOMOG1_W),  HOMOG_CMD,      INT_CMD,        IDEAL_CMD,  INTVEC_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjHOMOG1_W),  HOMOG_CMD,      INT_CMD,        MODUL_CMD,   INTVEC_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjHOMOG_P),   HOMOG_CMD,      POLY_CMD,       POLY_CMD,   POLY_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjHOMOG_P),   HOMOG_CMD,      VECTOR_CMD,     VECTOR_CMD, POLY_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjHOMOG_ID),  HOMOG_CMD,      IDEAL_CMD,      IDEAL_CMD,  POLY_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjHOMOG_ID),  HOMOG_CMD,      MODUL_CMD,      MODUL_CMD,  POLY_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjRES),       HRES_CMD,       RESOLUTION_CMD, IDEAL_CMD,  INT_CMD, NO_PLURAL |NO_RING}
+,{D(jjFETCH),     IMAP_CMD,       ANY_TYPE/*set by p*/,RING_CMD,  ANY_TYPE, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjFETCH),     IMAP_CMD,       ANY_TYPE/*set by p*/,QRING_CMD, ANY_TYPE, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjIMPORTFROM),IMPORTFROM_CMD, NONE,           PACKAGE_CMD, ANY_TYPE, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjINDEPSET2), INDEPSET_CMD,   LIST_CMD,       IDEAL_CMD,  INT_CMD, NO_PLURAL |NO_RING}
+,{D(lInsert),     INSERT_CMD,     LIST_CMD,       LIST_CMD,   DEF_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjINTERPOLATION),INTERPOLATE_CMD,IDEAL_CMD,   LIST_CMD,   INTVEC_CMD, NO_PLURAL |NO_RING}
+,{D(jjINTERSECT), INTERSECT_CMD,  IDEAL_CMD,      IDEAL_CMD,  IDEAL_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjINTERSECT), INTERSECT_CMD,  MODUL_CMD,      MODUL_CMD,  MODUL_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjJanetBasis2), JANET_CMD,    IDEAL_CMD,      IDEAL_CMD,  INT_CMD, ALLOW_PLURAL |NO_RING}
+,{D(jjJET_P),     JET_CMD,        POLY_CMD,       POLY_CMD,   INT_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjJET_ID),    JET_CMD,        IDEAL_CMD,      IDEAL_CMD,  INT_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjJET_P),     JET_CMD,        VECTOR_CMD,     VECTOR_CMD, INT_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjJET_ID),    JET_CMD,        MODUL_CMD,      MODUL_CMD,  INT_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjJET_ID),    JET_CMD,        MATRIX_CMD,     MATRIX_CMD,  INT_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjKBASE2),    KBASE_CMD,      IDEAL_CMD,      IDEAL_CMD,  INT_CMD, ALLOW_PLURAL |ALLOW_RING |WARN_RING} /*ring-cf: warning at top level*/
+,{D(jjKBASE2),    KBASE_CMD,      MODUL_CMD,      MODUL_CMD,  INT_CMD, ALLOW_PLURAL |ALLOW_RING |WARN_RING} /*ring-cf: warning at top level*/
+,{D(jjKERNEL),    KERNEL_CMD,     IDEAL_CMD, RING_CMD,        ANY_TYPE, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjKERNEL),    KERNEL_CMD,     IDEAL_CMD, QRING_CMD,       ANY_TYPE, ALLOW_PLURAL |ALLOW_RING}
+,{D(atKILLATTR2), KILLATTR_CMD,   NONE,           IDHDL,      STRING_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjKoszul),    KOSZUL_CMD,     MATRIX_CMD,     INT_CMD,    INT_CMD, NO_PLURAL |ALLOW_RING}
+,{D(jjKoszul_Id), KOSZUL_CMD,     MATRIX_CMD,     INT_CMD,    IDEAL_CMD, NO_PLURAL |ALLOW_RING}
+,{D(jjRES),       KRES_CMD,       RESOLUTION_CMD, IDEAL_CMD,  INT_CMD, NO_PLURAL |NO_RING}
+,{D(jjLIFT),      LIFT_CMD,       MATRIX_CMD,     IDEAL_CMD,  IDEAL_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjLIFT),      LIFT_CMD,       MATRIX_CMD,     MODUL_CMD,  MODUL_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjLIFTSTD),   LIFTSTD_CMD,    IDEAL_CMD,      IDEAL_CMD,  MATRIX_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjLIFTSTD),   LIFTSTD_CMD,    MODUL_CMD,      MODUL_CMD,  MATRIX_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjLOAD_E),    LOAD_CMD,       NONE,           STRING_CMD, STRING_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjRES),       LRES_CMD,       RESOLUTION_CMD, IDEAL_CMD,  INT_CMD, NO_PLURAL |NO_RING}
+,{D(jjMODULO),    MODULO_CMD,     MODUL_CMD,      IDEAL_CMD,  IDEAL_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjMODULO),    MODULO_CMD,     MODUL_CMD,      MODUL_CMD,  MODUL_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjMONITOR2),  MONITOR_CMD,    NONE,           LINK_CMD, STRING_CMD, ALLOW_PLURAL |ALLOW_RING}
+//,{D(jjRES),       MRES_CMD,       LIST_CMD,       IDEAL_CMD,  INT_CMD, NO_PLURAL |ALLOW_RING}
+//,{D(jjRES),       MRES_CMD,       LIST_CMD,       MODUL_CMD,  INT_CMD, NO_PLURAL |ALLOW_RING}
+,{D(nuMPResMat),  MPRES_CMD,      MODUL_CMD,      IDEAL_CMD,  INT_CMD, NO_PLURAL |NO_RING}
+,{D(jjNEWSTRUCT2),NEWSTRUCT_CMD,  NONE,           STRING_CMD, STRING_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjRES),       MRES_CMD,       RESOLUTION_CMD, IDEAL_CMD,  INT_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjRES),       MRES_CMD,       RESOLUTION_CMD, MODUL_CMD,  INT_CMD, ALLOW_PLURAL |ALLOW_RING}
+//,{D(nuMPResMat),  MPRES_CMD,      MODUL_CMD,      IDEAL_CMD,  INT_CMD, NO_PLURAL |ALLOW_RING}
+,{D(jjPFAC2),     PFAC_CMD,       LIST_CMD,       BIGINT_CMD, INT_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjPFAC2),     PFAC_CMD,       LIST_CMD,       NUMBER_CMD, INT_CMD, ALLOW_PLURAL |ALLOW_RING}
+#ifdef HAVE_PLURAL
+,{D(jjPlural_num_poly), NCALGEBRA_CMD,NONE,       POLY_CMD,   POLY_CMD  , NO_PLURAL |NO_RING}
+,{D(jjPlural_num_mat),  NCALGEBRA_CMD,NONE,       POLY_CMD,   MATRIX_CMD, NO_PLURAL |NO_RING}
+,{D(jjPlural_mat_poly), NCALGEBRA_CMD,NONE,       MATRIX_CMD, POLY_CMD  , NO_PLURAL |NO_RING}
+,{D(jjPlural_mat_mat),  NCALGEBRA_CMD,NONE,       MATRIX_CMD, MATRIX_CMD, NO_PLURAL |NO_RING}
+,{D(jjPlural_num_poly), NC_ALGEBRA_CMD,RING_CMD,  POLY_CMD,   POLY_CMD  , NO_PLURAL |NO_RING}
+,{D(jjPlural_num_mat),  NC_ALGEBRA_CMD,RING_CMD,  POLY_CMD,   MATRIX_CMD, NO_PLURAL |NO_RING}
+,{D(jjPlural_mat_poly), NC_ALGEBRA_CMD,RING_CMD,  MATRIX_CMD, POLY_CMD  , NO_PLURAL |NO_RING}
+,{D(jjPlural_mat_mat),  NC_ALGEBRA_CMD,RING_CMD,  MATRIX_CMD, MATRIX_CMD, NO_PLURAL |NO_RING}
+,{D(jjOPPOSE),    OPPOSE_CMD,     ANY_TYPE/*set by p*/, RING_CMD,   DEF_CMD, ALLOW_PLURAL |NO_RING}
+,{D(jjOPPOSE),    OPPOSE_CMD,     ANY_TYPE/*set by p*/, QRING_CMD,   DEF_CMD, ALLOW_PLURAL |NO_RING}
+#endif
+,{D(jjPARSTR2),   PARSTR_CMD,     STRING_CMD,     RING_CMD,   INT_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjPARSTR2),   PARSTR_CMD,     STRING_CMD,     QRING_CMD,  INT_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjPRINT_FORMAT), PRINT_CMD,   STRING_CMD,     DEF_CMD,    STRING_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjQUOT),      QUOTIENT_CMD,   IDEAL_CMD,      IDEAL_CMD,  IDEAL_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjQUOT),      QUOTIENT_CMD,   MODUL_CMD,      MODUL_CMD,  IDEAL_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjQUOT),      QUOTIENT_CMD,   IDEAL_CMD,      MODUL_CMD,  MODUL_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjRANDOM),    RANDOM_CMD,     INT_CMD,        INT_CMD,    INT_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjRANK2),     RANK_CMD,       INT_CMD,        MATRIX_CMD, INT_CMD, ALLOW_PLURAL |NO_RING}
+,{D(jjREAD2),     READ_CMD,       STRING_CMD,     LINK_CMD,   STRING_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjREDUCE_P),  REDUCE_CMD,     POLY_CMD,       POLY_CMD,   IDEAL_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjREDUCE_P),  REDUCE_CMD,     VECTOR_CMD,     VECTOR_CMD, IDEAL_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjREDUCE_P),  REDUCE_CMD,     VECTOR_CMD,     VECTOR_CMD, MODUL_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjREDUCE_ID), REDUCE_CMD,     IDEAL_CMD,      IDEAL_CMD,  IDEAL_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjREDUCE_ID), REDUCE_CMD,     MODUL_CMD,      MODUL_CMD,  IDEAL_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjREDUCE_ID), REDUCE_CMD,     MODUL_CMD,      MODUL_CMD,  MODUL_CMD, ALLOW_PLURAL |ALLOW_RING}
+//,{D(jjRES),       RES_CMD,        LIST_CMD,       IDEAL_CMD,  INT_CMD, NO_PLURAL |ALLOW_RING}
+//,{D(jjRES),       RES_CMD,        LIST_CMD,       MODUL_CMD,  INT_CMD, NO_PLURAL |ALLOW_RING}
+,{D(jjRES),       RES_CMD,        RESOLUTION_CMD, IDEAL_CMD,  INT_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjRES),       RES_CMD,        RESOLUTION_CMD, MODUL_CMD,  INT_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjSQR_FREE2), SQR_FREE_CMD,   IDEAL_CMD,      POLY_CMD,   INT_CMD, NO_PLURAL |ALLOW_RING}
+,{D(jjSTATUS2),   STATUS_CMD,     STRING_CMD,     LINK_CMD,   STRING_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjSTATUS2L),  STATUS_CMD,     INT_CMD,        LIST_CMD,   INT_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjSIMPL_P),   SIMPLIFY_CMD,   POLY_CMD,       POLY_CMD,   INT_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjSIMPL_P),   SIMPLIFY_CMD,   VECTOR_CMD,     VECTOR_CMD, INT_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjSIMPL_ID),  SIMPLIFY_CMD,   IDEAL_CMD,      IDEAL_CMD,  INT_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjSIMPL_ID),  SIMPLIFY_CMD,   MODUL_CMD,      MODUL_CMD,  INT_CMD, ALLOW_PLURAL |ALLOW_RING}
+//,{D(jjRES),       SRES_CMD,       LIST_CMD,       IDEAL_CMD,  INT_CMD, NO_PLURAL |ALLOW_RING}
+//,{D(jjRES),       SRES_CMD,       LIST_CMD,       MODUL_CMD,  INT_CMD, NO_PLURAL |ALLOW_RING}
+,{D(jjRES),       SRES_CMD,       RESOLUTION_CMD, IDEAL_CMD,  INT_CMD, NO_PLURAL |ALLOW_RING}
+,{D(jjRES),       SRES_CMD,       RESOLUTION_CMD, MODUL_CMD,  INT_CMD, NO_PLURAL |ALLOW_RING}
+,{D(jjSBA_1),     SBA_CMD,        IDEAL_CMD,      IDEAL_CMD,  INT_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjSBA_1),     SBA_CMD,        MODUL_CMD,      MODUL_CMD,  INT_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjSTD_1),     STD_CMD,        IDEAL_CMD,      IDEAL_CMD,  POLY_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjSTD_1),     STD_CMD,        MODUL_CMD,      MODUL_CMD,  VECTOR_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjSTD_1),     STD_CMD,        IDEAL_CMD,      IDEAL_CMD,  IDEAL_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjSTD_1),     STD_CMD,        MODUL_CMD,      MODUL_CMD,  MODUL_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjSTD_HILB),  STD_CMD,        IDEAL_CMD,      IDEAL_CMD,  INTVEC_CMD, NO_PLURAL |NO_RING}
+,{D(jjSTD_HILB),  STD_CMD,        MODUL_CMD,      MODUL_CMD,  INTVEC_CMD, NO_PLURAL |NO_RING}
+,{D(jjVARSTR2),   VARSTR_CMD,     STRING_CMD,     RING_CMD,   INT_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjVARSTR2),   VARSTR_CMD,     STRING_CMD,     QRING_CMD,  INT_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjWAIT1ST2),  WAIT1ST_CMD,    INT_CMD,        LIST_CMD,   INT_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjWAITALL2),  WAITALL_CMD,    INT_CMD,        LIST_CMD,   INT_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjWEDGE),     WEDGE_CMD,      MATRIX_CMD,     MATRIX_CMD, INT_CMD, NO_PLURAL |ALLOW_RING}
+,{NULL_VAL,       0,              0,              0,          0, NO_PLURAL |NO_RING}
+};
+/*=================== operations with 3 args.: table =================*/
+struct sValCmd3 dArith3[]=
+{
+// operations:
+// proc                cmd          res         arg1        arg2        arg3   context
+ {D(jjBRACK_S),        '[',        STRING_CMD, STRING_CMD, INT_CMD,    INT_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjBRACK_Im),       '[',        INT_CMD,    INTMAT_CMD, INT_CMD,    INT_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjBRACK_Bim),      '[',        BIGINT_CMD, BIGINTMAT_CMD, INT_CMD, INT_CMD, ALLOW_PLURAL |ALLOW_RING}
+#ifdef SINGULAR_4_1
+,{D(jjBRACK_Bim),      '[',        CNUMBER_CMD, CMATRIX_CMD, INT_CMD, INT_CMD, ALLOW_PLURAL |ALLOW_RING}
+#endif
+,{D(jjBRACK_Ma_I_IV),  '[',        INT_CMD,    INTMAT_CMD, INT_CMD,    INTVEC_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjBRACK_Ma_I_IV),  '[',        BIGINT_CMD, BIGINTMAT_CMD, INT_CMD,    INTVEC_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjBRACK_Ma_IV_I),  '[',        INT_CMD,    INTMAT_CMD, INTVEC_CMD, INT_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjBRACK_Ma_IV_I),  '[',        BIGINT_CMD, BIGINTMAT_CMD, INTVEC_CMD, INT_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjBRACK_Ma_IV_IV), '[',        INT_CMD,    INTMAT_CMD, INTVEC_CMD, INTVEC_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjBRACK_Ma_IV_IV), '[',        BIGINT_CMD, BIGINTMAT_CMD, INTVEC_CMD, INTVEC_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjBRACK_Ma),       '[',        POLY_CMD,   MATRIX_CMD, INT_CMD,    INT_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjBRACK_Ma_I_IV),  '[',        POLY_CMD,   MATRIX_CMD, INT_CMD,    INTVEC_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjBRACK_Ma_IV_I),  '[',        POLY_CMD,   MATRIX_CMD, INTVEC_CMD, INT_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjBRACK_Ma_IV_IV), '[',        POLY_CMD,   MATRIX_CMD, INTVEC_CMD, INTVEC_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjPROC3),          '(',        ANY_TYPE,   PROC_CMD,   DEF_CMD,    DEF_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(atATTRIB3),        ATTRIB_CMD, NONE,       IDHDL,      STRING_CMD, DEF_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjBAREISS3),       BAREISS_CMD,LIST_CMD,   MODUL_CMD,  INT_CMD,    INT_CMD, NO_PLURAL |ALLOW_RING|NO_ZERODIVISOR}
+,{D(jjCOEFFS3_P),      COEFFS_CMD, MATRIX_CMD, POLY_CMD,   POLY_CMD,   MATRIX_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjCOEFFS3_P),      COEFFS_CMD, MATRIX_CMD, VECTOR_CMD, POLY_CMD,   MATRIX_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjCOEFFS3_Id),     COEFFS_CMD, MATRIX_CMD, IDEAL_CMD,  POLY_CMD,   MATRIX_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjCOEFFS3_Id),     COEFFS_CMD, MATRIX_CMD, MODUL_CMD,  POLY_CMD,   MATRIX_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjCOEFFS3_KB),     COEFFS_CMD, MATRIX_CMD, IDEAL_CMD,  IDEAL_CMD,  POLY_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjCOEFFS3_KB),     COEFFS_CMD, MATRIX_CMD, MODUL_CMD,  MODUL_CMD,  POLY_CMD, ALLOW_PLURAL |ALLOW_RING}
+#ifdef SINGULAR_4_1
+,{D(jjCMATRIX_3),     CMATRIX_CMD, CMATRIX_CMD,INT_CMD,    INT_CMD,   CRING_CMD, ALLOW_PLURAL |ALLOW_RING}
+#endif
+,{D(jjELIMIN_HILB),    ELIMINATION_CMD,IDEAL_CMD, IDEAL_CMD, POLY_CMD, INTVEC_CMD, NO_PLURAL |ALLOW_RING}
+,{D(jjELIMIN_HILB),    ELIMINATION_CMD,MODUL_CMD, MODUL_CMD, POLY_CMD, INTVEC_CMD, NO_PLURAL |ALLOW_RING}
+,{D(jjFIND3),          FIND_CMD,   INT_CMD,    STRING_CMD, STRING_CMD, INT_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjFWALK3),         FWALK_CMD,  IDEAL_CMD,  RING_CMD,   DEF_CMD,    INT_CMD, NO_PLURAL |ALLOW_RING}
+,{D(jjHILBERT3),       HILBERT_CMD,INTVEC_CMD, IDEAL_CMD,  INT_CMD,    INTVEC_CMD, NO_PLURAL | ALLOW_RING | NO_ZERODIVISOR}
+,{D(jjHILBERT3),       HILBERT_CMD,INTVEC_CMD, MODUL_CMD,  INT_CMD,    INTVEC_CMD, NO_PLURAL | ALLOW_RING | NO_ZERODIVISOR}
+,{D(jjHOMOG_P_W),      HOMOG_CMD,  POLY_CMD,   POLY_CMD,   POLY_CMD,   INTVEC_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjHOMOG_P_W),      HOMOG_CMD,  VECTOR_CMD, VECTOR_CMD, POLY_CMD,   INTVEC_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjHOMOG_ID_W),     HOMOG_CMD,  IDEAL_CMD,  IDEAL_CMD,  POLY_CMD,   INTVEC_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjHOMOG_ID_W),     HOMOG_CMD,  MODUL_CMD,  MODUL_CMD,  POLY_CMD,   INTVEC_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(lInsert3),         INSERT_CMD, LIST_CMD,   LIST_CMD,   DEF_CMD,    INT_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjINTMAT3),        INTMAT_CMD, INTMAT_CMD, INTMAT_CMD, INT_CMD,    INT_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjJET_P_IV),       JET_CMD,    POLY_CMD,   POLY_CMD,   INT_CMD,    INTVEC_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjJET_ID_IV),      JET_CMD,    IDEAL_CMD,  IDEAL_CMD,  INT_CMD,    INTVEC_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjJET_P_IV),       JET_CMD,    VECTOR_CMD, VECTOR_CMD, INT_CMD,    INTVEC_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjJET_ID_IV),      JET_CMD,    MODUL_CMD,  MODUL_CMD,  INT_CMD,    INTVEC_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjJET_P_P),        JET_CMD,    POLY_CMD,   POLY_CMD,   POLY_CMD,   INT_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjJET_P_P),        JET_CMD,    VECTOR_CMD, VECTOR_CMD, POLY_CMD,   INT_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjJET_ID_M),       JET_CMD,    IDEAL_CMD,  IDEAL_CMD,  MATRIX_CMD, INT_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjJET_ID_M),       JET_CMD,    MODUL_CMD,  MODUL_CMD,  MATRIX_CMD, INT_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{  jjWRONG3 ,         JET_CMD,    POLY_CMD,   POLY_CMD,   INT_CMD,    INT_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(mpKoszul),         KOSZUL_CMD, MATRIX_CMD, INT_CMD,    INT_CMD,    IDEAL_CMD, NO_PLURAL |NO_RING}
+,{D(jjLIFT3),          LIFT_CMD,   MATRIX_CMD, IDEAL_CMD,  IDEAL_CMD,  MATRIX_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjLIFT3),          LIFT_CMD,   MATRIX_CMD, MODUL_CMD,  MODUL_CMD,  MATRIX_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjLIFTSTD3),       LIFTSTD_CMD,IDEAL_CMD,  IDEAL_CMD,  MATRIX_CMD, MODUL_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjLIFTSTD3),       LIFTSTD_CMD,MODUL_CMD,  MODUL_CMD,  MATRIX_CMD, MODUL_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjMATRIX_Id),      MATRIX_CMD, MATRIX_CMD, IDEAL_CMD,  INT_CMD,    INT_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjMATRIX_Mo),      MATRIX_CMD, MATRIX_CMD, MODUL_CMD,  INT_CMD,    INT_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjMATRIX_Ma),      MATRIX_CMD, MATRIX_CMD, MATRIX_CMD, INT_CMD,    INT_CMD, ALLOW_PLURAL |ALLOW_RING}
+#ifdef OLD_RES
+,{D(jjRES3),           MRES_CMD,   NONE,       IDEAL_CMD,  INT_CMD,    ANY_TYPE, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjRES3),           MRES_CMD,   NONE,       MODUL_CMD,  INT_CMD,    ANY_TYPE, ALLOW_PLURAL |ALLOW_RING}
+#endif
+,{D(jjNEWSTRUCT3),     NEWSTRUCT_CMD, NONE,     STRING_CMD, STRING_CMD, STRING_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjPREIMAGE),       PREIMAGE_CMD, IDEAL_CMD, RING_CMD,  ANY_TYPE,   ANY_TYPE, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjPREIMAGE),       PREIMAGE_CMD, IDEAL_CMD, QRING_CMD, ANY_TYPE,   ANY_TYPE, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjRANDOM_Im),      RANDOM_CMD, INTMAT_CMD, INT_CMD,    INT_CMD,    INT_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjREDUCE3_P),      REDUCE_CMD, POLY_CMD,   POLY_CMD,   IDEAL_CMD,  INT_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjREDUCE3_P),      REDUCE_CMD, VECTOR_CMD, VECTOR_CMD, IDEAL_CMD,  INT_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjREDUCE3_P),      REDUCE_CMD, VECTOR_CMD, VECTOR_CMD, MODUL_CMD,  INT_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjREDUCE3_ID),     REDUCE_CMD, IDEAL_CMD,  IDEAL_CMD,  IDEAL_CMD,  INT_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjREDUCE3_ID),     REDUCE_CMD, MODUL_CMD,  MODUL_CMD,  MODUL_CMD,  INT_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjREDUCE3_ID),     REDUCE_CMD, MODUL_CMD,  MODUL_CMD,  IDEAL_CMD,  INT_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjREDUCE3_CP),     REDUCE_CMD, POLY_CMD,   POLY_CMD,   POLY_CMD,   IDEAL_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjREDUCE3_CP),     REDUCE_CMD, VECTOR_CMD, VECTOR_CMD, POLY_CMD,   MODUL_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjREDUCE3_CID),    REDUCE_CMD, IDEAL_CMD,  IDEAL_CMD,  IDEAL_CMD,  MATRIX_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjREDUCE3_CID),    REDUCE_CMD, MODUL_CMD,  MODUL_CMD,  MODUL_CMD,  MATRIX_CMD, ALLOW_PLURAL |ALLOW_RING}
+#ifdef OLD_RES
+,{D(jjRES3),           RES_CMD,    NONE,       IDEAL_CMD,  INT_CMD,    ANY_TYPE, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjRES3),           RES_CMD,    NONE,       MODUL_CMD,  INT_CMD,    ANY_TYPE, ALLOW_PLURAL |ALLOW_RING}
+#endif
+,{D(jjRESULTANT),      RESULTANT_CMD, POLY_CMD,POLY_CMD,   POLY_CMD,   POLY_CMD, NO_PLURAL |ALLOW_RING}
+,{D(jjRING3),          RING_CMD,   RING_CMD,   DEF_CMD,    DEF_CMD,    DEF_CMD, ALLOW_PLURAL |ALLOW_RING}
+#ifdef OLD_RES
+,{D(jjRES3),           SRES_CMD,   NONE,       IDEAL_CMD,  INT_CMD,    ANY_TYPE, NO_PLURAL |ALLOW_RING}
+,{D(jjRES3),           SRES_CMD,   NONE,       MODUL_CMD,  INT_CMD,    ANY_TYPE, NO_PLURAL |ALLOW_RING}
+#endif
+,{D(jjSBA_2),          SBA_CMD,    IDEAL_CMD,  IDEAL_CMD,  INT_CMD, INT_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjSBA_2),          SBA_CMD,    MODUL_CMD,  MODUL_CMD,  INT_CMD, INT_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjSTATUS3),        STATUS_CMD, INT_CMD,    LINK_CMD,   STRING_CMD, STRING_CMD, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjSTD_HILB_W),     STD_CMD,    IDEAL_CMD,  IDEAL_CMD,  INTVEC_CMD, INTVEC_CMD, NO_PLURAL |NO_RING}
+,{D(jjSTD_HILB_W),     STD_CMD,    MODUL_CMD,  MODUL_CMD,  INTVEC_CMD, INTVEC_CMD, NO_PLURAL |NO_RING}
+,{D(jjSUBST_P),        SUBST_CMD,  POLY_CMD,   POLY_CMD,   POLY_CMD,   POLY_CMD , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjSUBST_P),        SUBST_CMD,  POLY_CMD,   POLY_CMD,   POLY_CMD,   POLY_CMD , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjSUBST_P),        SUBST_CMD,  VECTOR_CMD, VECTOR_CMD, POLY_CMD,   POLY_CMD , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjSUBST_Id),       SUBST_CMD,  IDEAL_CMD,  IDEAL_CMD,  POLY_CMD,   POLY_CMD , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjSUBST_Id),       SUBST_CMD,  MODUL_CMD,  MODUL_CMD,  POLY_CMD,   POLY_CMD , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjSUBST_Id),       SUBST_CMD,  MATRIX_CMD, MATRIX_CMD, POLY_CMD,   POLY_CMD , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjSUBST_Id_I),     SUBST_CMD,  MATRIX_CMD, MATRIX_CMD, POLY_CMD,   INT_CMD  , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjSUBST_Id_N),     SUBST_CMD,  MATRIX_CMD, MATRIX_CMD, POLY_CMD,   NUMBER_CMD , ALLOW_PLURAL |ALLOW_RING}
+,{D(nuLagSolve),       LAGSOLVE_CMD,LIST_CMD,  POLY_CMD,   INT_CMD,    INT_CMD  , NO_PLURAL |NO_RING}
+,{D(nuVanderSys),      VANDER_CMD, POLY_CMD,   IDEAL_CMD,  IDEAL_CMD,  INT_CMD  , NO_PLURAL |NO_RING}
+,{NULL_VAL,            0,          0,          0,          0,          0        , NO_PLURAL |NO_RING}
+};
+/*=================== operations with many arg.: table =================*/
+/* number_of_args:  -1: any), -2: any >0, .. */
+struct sValCmdM dArithM[]=
+{
+// operations:
+// proc            cmd               res        number_of_args   context
+ {D(jjKLAMMER_PL),  '(',           ANY_TYPE,           -2      , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjBREAK0),    BREAKPOINT_CMD,  NONE,               0       , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjBREAK1),    BREAKPOINT_CMD,  NONE,               -2      , ALLOW_PLURAL |ALLOW_RING}
+,{D(iiBranchTo),  BRANCHTO_CMD,    NONE,               -2      , ALLOW_PLURAL |ALLOW_RING}
+#ifdef SINGULAR_4_1
+,{D(jjCALL3ARG),  CMATRIX_CMD,     CMATRIX_CMD,        3       , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjCALL2ARG),  CNUMBER_CMD,     CNUMBER_CMD,        2       , ALLOW_PLURAL |ALLOW_RING}
+#endif
+,{D(jjCALL2ARG),  COEF_CMD,        MATRIX_CMD,         2       , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjCOEF_M),    COEF_CMD,        NONE,               4       , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjCALL2ARG),  DIVISION_CMD,    ANY_TYPE/*or set by p*/,2   , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjDIVISION4), DIVISION_CMD,    ANY_TYPE/*or set by p*/,3   , NO_PLURAL |NO_RING}
+,{D(jjDIVISION4), DIVISION_CMD,    ANY_TYPE/*or set by p*/,4   , NO_PLURAL |NO_RING}
+,{D(jjDBPRINT),   DBPRINT_CMD,     NONE,               -2      , ALLOW_PLURAL |ALLOW_RING}
+//,{D(jjEXPORTTO_M),  EXPORTTO_CMD,    NONE,             -2      , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjCALL2ARG),  FETCH_CMD,       ANY_TYPE/*or set by p*/,2   , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjFETCH_M),   FETCH_CMD,       ANY_TYPE/*or set by p*/,3   , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjFETCH_M),   FETCH_CMD,       ANY_TYPE/*or set by p*/,4   , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjCALL1ARG),  IDEAL_CMD,       IDEAL_CMD,          1       , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjIDEAL_PL),  IDEAL_CMD,       IDEAL_CMD,          -1      , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjCALL2ARG),  INTERSECT_CMD,   IDEAL_CMD,          2       , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjINTERSECT_PL),INTERSECT_CMD, IDEAL_CMD,          -2      , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjCALL1ARG),  INTVEC_CMD,      INTVEC_CMD,         1       , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjINTVEC_PL), INTVEC_CMD,      INTVEC_CMD,         -2      , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjCALL2ARG),  JET_CMD,         POLY_CMD,/*or set by p*/ 2  , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjCALL3ARG),  JET_CMD,         POLY_CMD,/*or set by p*/ 3  , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjJET4),      JET_CMD,         POLY_CMD,/*or set by p*/ 4  , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjCALL1ARG),  LIB_CMD,         NONE,                1  , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjLIST_PL),   LIST_CMD,        LIST_CMD,           -1      , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjLU_INVERSE),LUI_CMD,         LIST_CMD,           -2      , NO_PLURAL |NO_RING}
+,{D(jjLU_SOLVE),  LUS_CMD,         LIST_CMD,           -2      , NO_PLURAL |NO_RING}
+,{  jjWRONG ,     MINOR_CMD,       NONE,               1       , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjMINOR_M),   MINOR_CMD,       IDEAL_CMD,          -2      , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjCALL1ARG),  MODUL_CMD,       MODUL_CMD,          1       , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjIDEAL_PL),  MODUL_CMD,       MODUL_CMD,          -1      , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjCALL1ARG),  NAMES_CMD,       LIST_CMD,            1      , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjNAMES0),    NAMES_CMD,       LIST_CMD,            0      , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjOPTION_PL), OPTION_CMD,      STRING_CMD/*or set by p*/,-1, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjCALL2ARG),  REDUCE_CMD,      IDEAL_CMD/*or set by p*/,  2, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjCALL3ARG),  REDUCE_CMD,      IDEAL_CMD/*or set by p*/,  3, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjREDUCE4),   REDUCE_CMD,      IDEAL_CMD/*or set by p*/,  4, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjREDUCE5),   REDUCE_CMD,      IDEAL_CMD/*or set by p*/,  5, ALLOW_PLURAL |ALLOW_RING}
+,{D(jjCALL1ARG),  RESERVEDNAME_CMD, INT_CMD,            1      , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjRESERVED0), RESERVEDNAME_CMD, NONE,               0      , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjSTRING_PL), STRING_CMD,      STRING_CMD,         -1      , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjCALL3ARG),  SUBST_CMD,       NONE/*set by p*/,   3       , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjSUBST_M),   SUBST_CMD,       NONE/*set by p*/,   -2      , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjSYSTEM),    SYSTEM_CMD,      NONE/*or set by p*/,-2      , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjTEST),      TEST_CMD,        NONE,               -2      , ALLOW_PLURAL |ALLOW_RING}
+,{D(iiWRITE),     WRITE_CMD,       NONE,               -2      , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjCALL2ARG),  STATUS_CMD,      STRING_CMD,          2      , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjCALL3ARG),  STATUS_CMD,      INT_CMD,             3      , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjSTATUS_M),  STATUS_CMD,      INT_CMD,             4      , ALLOW_PLURAL |ALLOW_RING}
+,{D(loSimplex),   SIMPLEX_CMD,     LIST_CMD,            6      , NO_PLURAL |NO_RING}
+,{D(nuUResSolve), URSOLVE_CMD,     LIST_CMD,            4      , NO_PLURAL |NO_RING}
+,{D(jjCALL1ARG),  STD_CMD,         IDEAL_CMD,           1      , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjCALL2ARG),  STD_CMD,         IDEAL_CMD,           2      , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjCALL3ARG),  STD_CMD,         IDEAL_CMD,           3      , NO_PLURAL |ALLOW_RING}
+,{D(jjSTD_HILB_WP), STD_CMD,       IDEAL_CMD,           4      , NO_PLURAL |NO_RING}
+,{D(jjQRDS),      QRDS_CMD,        LIST_CMD,            4      , ALLOW_PLURAL |ALLOW_RING}
+,{D(jjFactModD_M),FMD_CMD,         LIST_CMD,           -2      , NO_PLURAL |NO_RING}
+,{NULL_VAL,       0,               0,                   0      , NO_PLURAL |NO_RING}
+};
+#ifdef GENTABLE
+// this table MUST be order alphabetically by its first entry:
+cmdnames cmds[] =
+// alias: 0: real name, 1: this is an alias, 2: this is an outdated alias
+{  // name-string alias tokval          toktype
+  { "$INVALID$",   0, -1,                 0},
+  { "ASSUME",      0, ASSUME_CMD,         ASSUME_CMD},
+  { "LIB",         0, LIB_CMD ,           SYSVAR},
+  { "alias",       0, ALIAS_CMD ,         PARAMETER},
+  { "and",         0, '&' ,               LOGIC_OP},
+  { "apply",       0, APPLY,              APPLY},
+  { "attrib",      0, ATTRIB_CMD ,        CMD_123},
+  { "bareiss",     0, BAREISS_CMD ,       CMD_13},
+  { "betti",       0, BETTI_CMD ,         CMD_12},
+  { "bigint",      0, BIGINT_CMD ,        ROOT_DECL},
+  { "bigintmat",   0, BIGINTMAT_CMD ,     BIGINTMAT_CMD},
+  { "branchTo",    0, BRANCHTO_CMD ,      CMD_M},
+  #ifdef HAVE_PLURAL
+  { "bracket",     0, BRACKET_CMD ,       CMD_2},
+  #endif
+  { "break",       0, BREAK_CMD ,         BREAK_CMD},
+  { "breakpoint",  0, BREAKPOINT_CMD ,    CMD_M},
+  { "char",        0, CHARACTERISTIC_CMD ,CMD_1},
+  { "char_series", 0, CHAR_SERIES_CMD ,   CMD_1},
+  { "charstr",     0, CHARSTR_CMD ,       CMD_1},
+  { "chinrem",     0, CHINREM_CMD ,       CMD_2},
+  { "cleardenom",  0, CONTENT_CMD ,       CMD_1},
+  { "close",       0, CLOSE_CMD ,         CMD_1},
+#ifdef SINGULAR_4_1
+  { "cmatrix",     0, CMATRIX_CMD ,       ROOT_DECL_LIST},
+  { "cnumber",     0, CNUMBER_CMD ,       ROOT_DECL_LIST},
+#endif
+  { "coef",        0, COEF_CMD ,          CMD_M},
+  { "coeffs",      0, COEFFS_CMD ,        CMD_23},
+  { "continue",    0, CONTINUE_CMD ,      CONTINUE_CMD},
+  { "contract",    0, CONTRACT_CMD ,      CMD_2},
+  { "convhull",    0, NEWTONPOLY_CMD,     CMD_1},
+  { "dbprint",     0, DBPRINT_CMD ,       CMD_M},
+  { "def",         0, DEF_CMD ,           ROOT_DECL},
+  { "defined",     0, DEFINED_CMD ,       CMD_1},
+  { "deg",         0, DEG_CMD ,           CMD_12},
+  { "degree",      0, DEGREE_CMD ,        CMD_1},
+  { "delete",      0, DELETE_CMD ,        CMD_2},
+  { "denominator", 0, DENOMINATOR_CMD ,   CMD_1},
+  { "det",         0, DET_CMD ,           CMD_1},
+  { "diff",        0, DIFF_CMD ,          CMD_2},
+  { "dim",         0, DIM_CMD ,           CMD_12},
+  { "div",         0, INTDIV_CMD ,        MULDIV_OP},
+  { "division",    0, DIVISION_CMD ,      CMD_M},
+  { "dump",        0, DUMP_CMD,           CMD_1},
+  { "extgcd",      0, EXTGCD_CMD ,        CMD_2},
+  { "ERROR",       0, ERROR_CMD ,         CMD_1},
+  { "eliminate",   0, ELIMINATION_CMD,    CMD_23},
+  { "else",        0, ELSE_CMD ,          ELSE_CMD},
+  #ifdef HAVE_PLURAL
+  { "envelope",    0, ENVELOPE_CMD ,      CMD_1},
+  #endif
+  { "eval",        0, EVAL ,              EVAL},
+  { "example",     0, EXAMPLE_CMD ,       EXAMPLE_CMD},
+  { "execute",     0, EXECUTE_CMD ,       CMD_1},
+  { "export",      0, EXPORT_CMD ,        EXPORT_CMD},
+  { "exportto",    0, EXPORTTO_CMD ,      CMD_2},
+  { "facstd",      0, FACSTD_CMD ,        CMD_12},
+  { "factmodd",    0, FMD_CMD ,           CMD_M},
+  { "factorize",   0, FAC_CMD ,           CMD_12},
+  { "farey",       0, FAREY_CMD ,         CMD_2},
+  { "fetch",       0, FETCH_CMD ,         CMD_M},
+  { "fglm",        0, FGLM_CMD ,          CMD_2},
+  { "fglmquot",    0, FGLMQUOT_CMD,       CMD_2},
+  { "find",        0, FIND_CMD ,          CMD_23},
+  { "finduni",     0, FINDUNI_CMD,        CMD_1},
+  { "forif",       0, IF_CMD ,            IF_CMD},
+  { "freemodule",  0, FREEMODULE_CMD ,    CMD_1},
+  { "frwalk",      0, FWALK_CMD ,         CMD_23},
+  { "gen",         0, E_CMD ,             CMD_1},
+  { "getdump",     0, GETDUMP_CMD,        CMD_1},
+  { "gcd",         0, GCD_CMD ,           CMD_2},
+  { "GCD",         2, GCD_CMD ,           CMD_2},
+  { "hilb",        0, HILBERT_CMD ,       CMD_123},
+  { "highcorner",  0, HIGHCORNER_CMD,     CMD_1},
+  { "homog",       0, HOMOG_CMD ,         CMD_123},
+  { "hres",        0, HRES_CMD ,          CMD_2},
+  { "ideal",       0, IDEAL_CMD ,         RING_DECL_LIST},
+  { "if",          0, IF_CMD ,            IF_CMD},
+  { "imap",        0, IMAP_CMD ,          CMD_2},
+  { "impart",      0, IMPART_CMD ,        CMD_1},
+  { "importfrom",  0, IMPORTFROM_CMD ,    CMD_2},
+  { "indepSet",    0, INDEPSET_CMD ,      CMD_12},
+  { "insert",      0, INSERT_CMD ,        CMD_23},
+  { "int",         0, INT_CMD ,           ROOT_DECL},
+  { "interpolation",0,INTERPOLATE_CMD ,   CMD_2},
+  { "interred",    0, INTERRED_CMD ,      CMD_1},
+  { "intersect",   0, INTERSECT_CMD ,     CMD_M},
+  { "intmat",      0, INTMAT_CMD ,        INTMAT_CMD},
+  { "intvec",      0, INTVEC_CMD ,        ROOT_DECL_LIST},
+  { "jacob",       0, JACOB_CMD ,         CMD_1},
+  { "janet",       0, JANET_CMD ,         CMD_12},
+  { "jet",         0, JET_CMD ,           CMD_M},
+  { "kbase",       0, KBASE_CMD ,         CMD_12},
+  { "keepring",    0, KEEPRING_CMD ,      KEEPRING_CMD},
+  { "kernel",      0, KERNEL_CMD ,        CMD_2},
+  { "kill",        0, KILL_CMD ,          KILL_CMD},
+  { "killattrib",  0, KILLATTR_CMD ,      CMD_12},
+  { "koszul",      0, KOSZUL_CMD ,        CMD_23},
+  { "kres",        0, KRES_CMD ,          CMD_2},
+  { "laguerre",    0, LAGSOLVE_CMD,       CMD_3},
+  { "lead",        0, LEAD_CMD ,          CMD_1},
+  { "leadcoef",    0, LEADCOEF_CMD ,      CMD_1},
+  { "leadexp",     0, LEADEXP_CMD ,       CMD_1},
+  { "leadmonom",   0, LEADMONOM_CMD ,     CMD_1},
+  { "lift",        0, LIFT_CMD ,          CMD_23},
+  { "liftstd",     0, LIFTSTD_CMD ,       CMD_23},
+  { "link",        0, LINK_CMD ,          ROOT_DECL},
+  { "listvar",     0, LISTVAR_CMD ,       LISTVAR_CMD},
+  { "list",        0, LIST_CMD ,          ROOT_DECL_LIST},
+  { "load",        0, LOAD_CMD ,          CMD_12},
+  { "lres",        0, LRES_CMD ,          CMD_2},
+  { "ludecomp",    0, LU_CMD ,            CMD_1},
+  { "luinverse",   0, LUI_CMD ,           CMD_M},
+  { "lusolve",     0, LUS_CMD ,           CMD_M},
+  { "map",         0, MAP_CMD ,           RING_DECL},
+  { "matrix",      0, MATRIX_CMD ,        MATRIX_CMD},
+  { "maxideal",    0, MAXID_CMD ,         CMD_1},
+  { "memory",      0, MEMORY_CMD ,        CMD_1},
+  { "minbase",     0, MINBASE_CMD ,       CMD_1},
+  { "minor",       0, MINOR_CMD ,         CMD_M},
+  { "minres",      0, MINRES_CMD ,        CMD_1},
+  { "mod",         0, '%' ,               MULDIV_OP},
+  { "module",      0, MODUL_CMD ,         RING_DECL_LIST},
+  { "modulo",      0, MODULO_CMD ,        CMD_2},
+  { "monitor",     0, MONITOR_CMD ,       CMD_12},
+  { "monomial",    0, MONOM_CMD ,         CMD_1},
+  { "mpresmat",    0, MPRES_CMD,          CMD_2},
+  { "mult",        0, MULTIPLICITY_CMD ,  CMD_1},
+  #ifdef OLD_RES
+  { "mres",        0, MRES_CMD ,          CMD_23},
+  #else
+  { "mres",        0, MRES_CMD ,          CMD_2},
+  #endif
+  { "mstd",        0, MSTD_CMD ,          CMD_1},
+  { "nameof",      0, NAMEOF_CMD ,        CMD_1},
+  { "names",       0, NAMES_CMD ,         CMD_M},
+  { "newstruct",   0, NEWSTRUCT_CMD ,     CMD_23},
+  #ifdef HAVE_PLURAL
+  { "ncalgebra",   2, NCALGEBRA_CMD ,     CMD_2},
+  { "nc_algebra",  0, NC_ALGEBRA_CMD ,    CMD_2},
+  #endif
+  { "ncols",       0, COLS_CMD ,          CMD_1},
+  { "not",         0, NOT ,               NOT},
+  { "npars",       0, NPARS_CMD ,         CMD_1},
+  #ifdef OLD_RES
+  { "nres",        0, RES_CMD ,           CMD_23},
+  #else
+  { "nres",        0, RES_CMD ,           CMD_2},
+  #endif
+  { "nrows",       0, ROWS_CMD ,          CMD_1},
+  { "number",      0, NUMBER_CMD ,        RING_DECL},
+  { "numerator",   0, NUMERATOR_CMD ,     CMD_1},
+  { "nvars",       0, NVARS_CMD ,         CMD_1},
+  { "open",        0, OPEN_CMD ,          CMD_1},
+  #ifdef HAVE_PLURAL
+  { "oppose",      0, OPPOSE_CMD ,        CMD_2},
+  { "opposite",    0, OPPOSITE_CMD ,      CMD_1},
+  #endif
+  { "option",      0, OPTION_CMD ,        CMD_M},
+  { "or",          0, '|' ,               LOGIC_OP},
+  { "ord",         0, ORD_CMD ,           CMD_1},
+  { "ordstr",      0, ORDSTR_CMD ,        CMD_1},
+  { "package",     0, PACKAGE_CMD ,       ROOT_DECL},
+  { "par",         0, PAR_CMD ,           CMD_1},
+  { "parameter",   0, PARAMETER ,         PARAMETER},
+  { "pardeg",      0, PARDEG_CMD ,        CMD_1},
+  { "parstr",      0, PARSTR_CMD ,        CMD_12},
+  { "poly",        0, POLY_CMD ,          RING_DECL},
+  { "preimage",    0, PREIMAGE_CMD ,      CMD_13},
+  { "prime",       0, PRIME_CMD ,         CMD_1},
+  { "primefactors",0, PFAC_CMD ,          CMD_12},
+  { "print",       0, PRINT_CMD ,         CMD_12},
+  { "prune",       0, PRUNE_CMD ,         CMD_1},
+  { "proc",        0, PROC_CMD ,          PROC_CMD},
+  { "qhweight",    0, QHWEIGHT_CMD ,      CMD_1},
+  { "qrds",        0, QRDS_CMD ,          CMD_M},
+  { "qring",       0, QRING_CMD ,         ROOT_DECL},
+  { "quote",       0, QUOTE ,             QUOTE},
+  { "quotient",    0, QUOTIENT_CMD ,      CMD_2},
+  { "random",      0, RANDOM_CMD ,        CMD_23},
+  { "rank",        0, RANK_CMD ,          CMD_12},
+  { "read",        0, READ_CMD ,          CMD_12},
+  { "reduce",      0, REDUCE_CMD ,        CMD_M},
+  { "regularity",  0, REGULARITY_CMD ,    CMD_1},
+  { "repart",      0, REPART_CMD ,        CMD_1},
+  { "reservedName",0, RESERVEDNAME_CMD ,  CMD_M},
+  { "resolution",  0, RESOLUTION_CMD ,    RING_DECL},
+  { "resultant",   0, RESULTANT_CMD,      CMD_3},
+  { "return",      0, RETURN ,            RETURN},
+  { "RETURN",      0, END_GRAMMAR ,       RETURN},
+  { "ring",        0, RING_CMD ,          RING_CMD},
+  { "ringlist",    0, RINGLIST_CMD ,      CMD_1},
+  { "rvar",        0, IS_RINGVAR ,        CMD_1},
+  { "sba",         0, SBA_CMD ,           CMD_123},
+  { "setring",     0, SETRING_CMD ,       SETRING_CMD},
+  { "simplex",     0, SIMPLEX_CMD,        CMD_M},
+  { "simplify",    0, SIMPLIFY_CMD ,      CMD_2},
+  { "size",        0, COUNT_CMD ,         CMD_1},
+  { "slimgb",      0, SLIM_GB_CMD ,       CMD_1},
+  { "sortvec",     0, SORTVEC_CMD ,       CMD_1},
+  { "sqrfree",     0, SQR_FREE_CMD ,      CMD_12},
+#ifdef OLD_RES
+  { "sres",        0, SRES_CMD ,          CMD_23},
+#else /* OLD_RES */
+  { "sres",        0, SRES_CMD ,          CMD_2},
+#endif /* OLD_RES */
+  { "status",      0, STATUS_CMD,         CMD_M},
+  { "std",         0, STD_CMD ,           CMD_M},
+  { "string",      0, STRING_CMD ,        ROOT_DECL_LIST},
+  { "subst",       0, SUBST_CMD ,         CMD_M},
+  { "system",      0, SYSTEM_CMD,         CMD_M},
+  { "syz",         0, SYZYGY_CMD ,        CMD_1},
+  { "test",        0, TEST_CMD ,          CMD_M},
+  { "trace",       0, TRACE_CMD ,         CMD_1},
+  { "transpose",   0, TRANSPOSE_CMD ,     CMD_1},
+#ifdef HAVE_PLURAL
+  { "twostd",      0, TWOSTD_CMD ,        CMD_1},
+#endif /* HAVE_PLURAL */
+  { "type",        0, TYPE_CMD ,          TYPE_CMD},
+  { "typeof",      0, TYPEOF_CMD ,        CMD_1},
+  { "univariate",  0, UNIVARIATE_CMD,     CMD_1},
+  { "uressolve",   0, URSOLVE_CMD,        CMD_M},
+  { "vandermonde", 0, VANDER_CMD,         CMD_3},
+  { "var",         0, VAR_CMD ,           CMD_1},
+  { "variables",   0, VARIABLES_CMD,      CMD_1},
+  { "varstr",      0, VARSTR_CMD ,        CMD_12},
+  { "vdim",        0, VDIM_CMD ,          CMD_1},
+  { "vector",      0, VECTOR_CMD ,        RING_DECL},
+  { "waitfirst",   0, WAIT1ST_CMD ,       CMD_12},
+  { "waitall",     0, WAITALL_CMD ,       CMD_12},
+  { "wedge",       0, WEDGE_CMD ,         CMD_2},
+  { "weight",      0, WEIGHT_CMD ,        CMD_1},
+  { "whileif",     0, IF_CMD ,            IF_CMD},
+  { "write",       0, WRITE_CMD ,         CMD_M},
+/* delete for next version:*/
+  { "IN",          1, LEAD_CMD ,          CMD_1},
+  { "NF",          1, REDUCE_CMD ,        CMD_M},
+  { "multiplicity",1, MULTIPLICITY_CMD ,  CMD_1},
+  { "verbose",     2, OPTION_CMD ,        CMD_M},
+//  { "rank",        1, ROWS_CMD ,          CMD_1},
+//  { "Current",     0, -1 ,                SYSVAR},
+//  { "Top",         0, -1 ,                SYSVAR},
+//  { "Up",          0, -1 ,                SYSVAR},
+
+/* set sys vars*/
+  { "degBound",    0, VMAXDEG ,           SYSVAR},
+  { "echo",        0, VECHO ,             SYSVAR},
+  { "minpoly",     0, VMINPOLY ,          SYSVAR},
+  { "multBound",   0, VMAXMULT ,          SYSVAR},
+  { "noether",     0, VNOETHER ,          SYSVAR},
+  { "pagewidth",   0, VCOLMAX ,           SYSVAR},
+  { "printlevel",  0, VPRINTLEVEL ,       SYSVAR},
+  { "short",       0, VSHORTOUT ,         SYSVAR},
+  { "timer",       0, VTIMER ,            SYSVAR},
+  { "rtimer",      0, VRTIMER,            SYSVAR},
+  { "TRACE",       0, TRACE ,             SYSVAR},
+  { "voice",       0, VOICE ,             SYSVAR},
+
+/* other reserved words:scanner.l */
+  { "pause",       2, -1 ,             0},
+  { "while",       0, -1 ,             0},
+  { "for",         0, -1 ,             0},
+  { "help",        0, -1 ,             0},
+  { "newline",     0, -1 ,             0},
+  { "exit",        0, -1 ,             0},
+  { "quit",        0, -1 ,             0},
+/* end of list marker */
+  { NULL, 0, 0, 0}
+};
+#endif /* GENTABLE */
+#endif
+
+#ifdef IPCONV
+struct sConvertTypes dConvertTypes[] =
+{
+//   input type       output type     convert procedure
+//  int -> bigint
+   { INT_CMD,         BIGINT_CMD,     D(iiI2BI) , NULL_VAL },
+//  int -> number
+   { INT_CMD,         NUMBER_CMD,     D(iiI2N) , NULL_VAL },
+   { BIGINT_CMD,      NUMBER_CMD,     D(iiBI2N) , NULL_VAL },
+//  int -> poly
+   { INT_CMD,         POLY_CMD,       D(iiI2P) , NULL_VAL },
+   { BIGINT_CMD,      POLY_CMD,       D(iiBI2P) , NULL_VAL },
+//  int -> vector
+   { INT_CMD,         VECTOR_CMD,     D(iiI2V) , NULL_VAL },
+   { BIGINT_CMD,      VECTOR_CMD,     D(iiBI2V) , NULL_VAL },
+//  int -> ideal
+   { INT_CMD,         IDEAL_CMD,      D(iiI2Id) , NULL_VAL },
+   { BIGINT_CMD,      IDEAL_CMD,      D(iiBI2Id) , NULL_VAL },
+//  int -> matrix
+   { INT_CMD,         MATRIX_CMD,     D(iiI2Id) , NULL_VAL },
+   { BIGINT_CMD,      MATRIX_CMD,     D(iiBI2Id) , NULL_VAL },
+//  int -> intvec
+   { INT_CMD,         INTVEC_CMD,     D(iiI2Iv) , NULL_VAL },
+//  intvec -> intmat
+   { INTVEC_CMD,      INTMAT_CMD,     D(iiDummy), NULL_VAL },
+//  intvec -> matrix
+   { INTVEC_CMD,      MATRIX_CMD,     D(iiIm2Ma) , NULL_VAL },
+//  intmat -> bigintmat
+   { INTMAT_CMD,      BIGINTMAT_CMD,  D(iiIm2Bim) , NULL_VAL },
+//  bigintmat -> intmat
+   { BIGINTMAT_CMD,   INTMAT_CMD,     D(iiBim2Im) , NULL_VAL },
+//  intmat -> matrix
+   { INTMAT_CMD,      MATRIX_CMD,     D(iiIm2Ma) , NULL_VAL },
+//  number -> poly
+   { NUMBER_CMD,      POLY_CMD,       D(iiN2P)  , NULL_VAL },
+//  number -> matrix
+   { NUMBER_CMD,      MATRIX_CMD,     D(iiN2Ma)  , NULL_VAL },
+//  number -> ideal
+//  number -> vector
+//  number -> module
+//  poly -> number
+//  poly -> ideal
+   { POLY_CMD,        IDEAL_CMD,      D(iiP2Id) , NULL_VAL },
+//  poly -> vector
+   { POLY_CMD,        VECTOR_CMD,     D(iiP2V) , NULL_VAL },
+//  poly -> matrix
+   { POLY_CMD,        MATRIX_CMD,     D(iiP2Id) , NULL_VAL },
+//  vector -> module
+   { VECTOR_CMD,      MODUL_CMD,      D(iiP2Id) , NULL_VAL },
+//  vector -> matrix
+   { VECTOR_CMD,      MATRIX_CMD,     D(iiV2Ma) , NULL_VAL },
+//  ideal -> module
+   { IDEAL_CMD,       MODUL_CMD,      D(iiMa2Mo) , NULL_VAL },
+//  ideal -> matrix
+   { IDEAL_CMD,       MATRIX_CMD,     D(iiDummy) , NULL_VAL },
+//  module -> matrix
+   { MODUL_CMD,       MATRIX_CMD,     D(iiMo2Ma) , NULL_VAL },
+//  matrix -> ideal
+//  matrix -> module
+   { MATRIX_CMD,      MODUL_CMD,      D(iiMa2Mo) , NULL_VAL },
+//  intvec
+//  link
+   { STRING_CMD,      LINK_CMD,       D(iiS2Link) , NULL_VAL },
+// resolution -> list
+   { RESOLUTION_CMD,  LIST_CMD,       NULL_VAL /*iiR2L*/ , D(iiR2L_l) },
+// list -> resolution
+   { LIST_CMD,        RESOLUTION_CMD, D(iiL2R) , NULL_VAL},
+//  end of list
+   { 0,               0,              NULL_VAL , NULL_VAL }
+};
+#else
+extern struct sConvertTypes dConvertTypes[];
+#endif
+#ifdef IPASSIGN
+struct sValAssign dAssign[]=
+{
+// proc         res             arg
+ {D(jiA_IDEAL),    IDEAL_CMD,      IDEAL_CMD }
+,{D(jiA_IDEAL_M),  IDEAL_CMD,      MATRIX_CMD }
+,{D(jiA_RESOLUTION),RESOLUTION_CMD,RESOLUTION_CMD }
+,{D(jiA_INT),      INT_CMD,        INT_CMD }
+,{D(jiA_1x1INTMAT), INT_CMD,       INTMAT_CMD }
+,{D(jiA_IDEAL),    MATRIX_CMD,     MATRIX_CMD }
+,{D(jiA_MAP_ID),   MAP_CMD,        IDEAL_CMD }
+,{D(jiA_MAP),      MAP_CMD,        MAP_CMD }
+,{D(jiA_IDEAL),    MODUL_CMD,      MODUL_CMD }
+,{D(jiA_MODUL_P),  MODUL_CMD,      POLY_CMD }
+,{D(jiA_POLY),     POLY_CMD,       POLY_CMD }
+,{D(jiA_1x1MATRIX),POLY_CMD,       MATRIX_CMD }
+,{D(jiA_QRING),    QRING_CMD,      IDEAL_CMD }
+,{D(jiA_RING),     RING_CMD,       RING_CMD }
+,{D(jiA_RING),     QRING_CMD,      QRING_CMD }
+,{D(jiA_RING),     QRING_CMD,      RING_CMD }
+,{D(jiA_STRING),   STRING_CMD,     STRING_CMD }
+,{D(jiA_PROC),     PROC_CMD,       STRING_CMD }
+,{D(jiA_PROC),     PROC_CMD,       PROC_CMD }
+,{D(jiA_POLY),     VECTOR_CMD,     VECTOR_CMD }
+,{D(jiA_INTVEC),   INTVEC_CMD,     INTVEC_CMD }
+,{D(jiA_INTVEC),   INTMAT_CMD,     INTMAT_CMD }
+//,{D(jiA_INTVEC),   INTMAT_CMD,     INTVEC_CMD }
+,{D(jiA_BIGINTMAT),BIGINTMAT_CMD,  BIGINTMAT_CMD}
+,{D(jiA_NUMBER),   NUMBER_CMD,     NUMBER_CMD }
+,{D(jiA_BIGINT),   BIGINT_CMD,     BIGINT_CMD }
+,{D(jiA_LIST_RES), LIST_CMD,       RESOLUTION_CMD }
+,{D(jiA_LIST),     LIST_CMD,       LIST_CMD }
+,{D(jiA_LINK),     LINK_CMD,       STRING_CMD }
+,{D(jiA_LINK),     LINK_CMD,       LINK_CMD }
+,{D(jiA_PACKAGE),  PACKAGE_CMD,    PACKAGE_CMD }
+,{D(jiA_DEF),      DEF_CMD,        DEF_CMD }
+#ifdef SINGULAR_4_1
+,{D(jiA_BIGINTMAT),CMATRIX_CMD,    CMATRIX_CMD}
+,{D(jiA_NUMBER2),  CNUMBER_CMD,    CNUMBER_CMD }
+,{D(jiA_CRING),    CRING_CMD,      CRING_CMD }
+#endif
+,{NULL_VAL,        0,              0 }
+};
+struct sValAssign_sys dAssign_sys[]=
+{
+// sysvars:
+ {D(jjECHO),       VECHO,          INT_CMD }
+,{D(jjPRINTLEVEL), VPRINTLEVEL,    INT_CMD }
+,{D(jjCOLMAX),     VCOLMAX,        INT_CMD }
+,{D(jjTIMER),      VTIMER,         INT_CMD }
+#ifdef HAVE_GETTIMEOFDAY
+,{D(jjRTIMER),     VRTIMER,        INT_CMD }
+#endif
+,{D(jjMAXDEG),     VMAXDEG,        INT_CMD }
+,{D(jjMAXMULT),    VMAXMULT,       INT_CMD }
+,{D(jjTRACE),      TRACE,          INT_CMD }
+,{D(jjSHORTOUT),   VSHORTOUT,      INT_CMD }
+,{D(jjMINPOLY),    VMINPOLY,       NUMBER_CMD }
+,{D(jjNOETHER),    VNOETHER,       POLY_CMD }
+,{NULL_VAL,        0,              0 }
+};
+#endif
diff --git a/Singular/test.cc b/Singular/test.cc
new file mode 100644
index 0000000..d0d7eb7
--- /dev/null
+++ b/Singular/test.cc
@@ -0,0 +1,385 @@
+
+
+
+
+#include <kernel/mod2.h>
+
+#include <omalloc/omalloc.h>
+#include <misc/auxiliary.h>
+
+#include <factory/factory.h> // :(
+
+
+#include <misc/intvec.h>
+#include <misc/int64vec.h>
+#include <misc/mylimits.h>
+#include <misc/options.h>
+
+#include <reporter/reporter.h>
+
+#include <resources/feFopen.h>
+#include <resources/feResource.h>
+
+#include <coeffs/coeffs.h>
+
+#include <coeffs/si_gmp.h>
+
+#include <polys/kbuckets.h>
+#include <polys/matpol.h>
+#include <polys/mod_raw.h>
+#include <polys/prCopy.h>
+#include <polys/sbuckets.h>
+#include <polys/simpleideals.h>
+#include <polys/weight.h>
+
+#include <polys/monomials/maps.h>
+#include <polys/monomials/monomials.h>
+#include <polys/monomials/p_polys.h>
+#include <polys/monomials/ring.h>
+
+#include <polys/nc/nc.h>
+#include <polys/nc/ncSACache.h>
+#include <polys/nc/ncSAFormula.h>
+#include <polys/nc/ncSAMult.h>
+#include <polys/nc/sca.h>
+#include <polys/nc/summator.h>
+
+
+#include <polys/templates/p_MemAdd.h>
+#include <polys/templates/p_Procs.h>
+
+#include <polys/operations/pShallowCopyDelete.h>
+
+#include <polys/clapsing.h>
+
+
+#include <coeffs/numbers.h>
+#include <kernel/polys.h>
+
+
+#include <kernel/structs.h>
+
+
+// HEADERS:
+#include <kernel/combinatorics/hutil.h>
+#include <kernel/combinatorics/stairc.h>
+#include <kernel/ideals.h>
+#include <kernel/GBEngine/syz.h>
+#include <kernel/maps/fast_maps.h>
+#include <Singular/fevoices.h>
+#include <kernel/groebner_walk/walkProc.h>
+#include <kernel/groebner_walk/walkMain.h>
+#include <kernel/groebner_walk/walkSupport.h>
+#include <kernel/GBEngine/khstd.h>
+/// #include <kernel/sparsmat.h> // TODO: install polys/this!
+//+
+
+#include <kernel/fglm/fglm.h>
+#include <kernel/GBEngine/kstd1.h>
+#include <kernel/fglm/fglmgauss.h>
+#include <kernel/fglm/fglmvec.h>
+#include <kernel/GBEngine/kstdfac.h>
+#include <kernel/spectrum/kmatrix.h>
+#include <kernel/spectrum/GMPrat.h>
+#include <kernel/spectrum/multicnt.h>
+#include <kernel/spectrum/npolygon.h>
+#include <kernel/spectrum/semic.h>
+#include <kernel/spectrum/spectrum.h>
+#include <kernel/spectrum/splist.h>
+#include <kernel/spectrum/multicnt.h>
+#include <kernel/linear_algebra/eigenval.h>
+#include <kernel/GBEngine/units.h>
+#include <kernel/GBEngine/ratgring.h>
+#include <kernel/GBEngine/shiftgb.h>
+
+#include <kernel/GBEngine/kutil.h>
+
+// #include <kernel/dbm_sl.h> // TODO: needs si_link// already moved to Singular/!
+
+// #include "CCRing.h" // Too old!
+#include <kernel/digitech.h>
+#include <kernel/linear_algebra/eigenval.h>
+#include <kernel/maps/fast_maps.h>
+#include <kernel/fast_mult.h>
+#include <kernel/oswrapper/feread.h>
+
+#include <kernel/fglm/fglmgauss.h>
+#include <kernel/fglm/fglm.h>
+#include <kernel/fglm/fglmvec.h>
+
+////////#include "F5cData.h"
+#include <kernel/GBEngine/f5c.h>
+#include <kernel/GBEngine/f5data.h>
+#include <kernel/GBEngine/f5gb.h>
+#include <kernel/GBEngine/f5lists.h>
+////////#include <kernel/F5cLists.h>
+
+
+#include <kernel/spectrum/GMPrat.h>
+
+#include <kernel/combinatorics/hutil.h>
+// #include <kernel/Ideal.h> // Too old?
+
+
+#include <kernel/ideals.h>
+
+#include <kernel/spectrum/kmatrix.h>
+#include <kernel/GBEngine/kstd1.h>
+#include <kernel/GBEngine/kstdfac.h>
+#include <kernel/GBEngine/khstd.h>
+
+#include <kernel/linear_algebra/linearAlgebra.h>
+
+
+
+// #include "lplist.h" // Too old!
+#include <kernel/spectrum/multicnt.h>
+#include <kernel/spectrum/npolygon.h>
+// #include <kernel/Number.h> // Too old?
+// #include <kernel/Poly.h> // Too old?
+// #include <kernel/PowerSeries.h> // Too old?
+
+#include <kernel/preimage.h>
+
+#include <kernel/GBEngine/nc.h>
+
+#include <kernel/GBEngine/ratgring.h>
+#include <kernel/GBEngine/ringgb.h>
+#include <kernel/spectrum/semic.h>
+#include <kernel/GBEngine/shiftgb.h>
+
+#include <kernel/spectrum/spectrum.h>
+#include <kernel/spectrum/splist.h>
+#include <kernel/structs.h>
+#include <kernel/GBEngine/syz.h>
+// #include <kernel/testpoly.h> // Too old?
+
+#include <kernel/GBEngine/tgbgauss.h>
+#include <kernel/GBEngine/tgb.h>
+
+#include <kernel/oswrapper/timer.h>
+
+#include <kernel/GBEngine/units.h>
+#include <kernel/groebner_walk/walkMain.h>
+#include <kernel/groebner_walk/walkProc.h>
+#include <kernel/groebner_walk/walkSupport.h>
+
+
+// #include <polys/clapconv.h> // due to factory? :(
+// #include <kernel/tgb_internal.h> // :(
+// #include <kernel/F4.h> // uses tgb_internal // :(
+// #include <kernel/IIntvec.h> // :(
+
+
+// headers in Singular/
+#include <Singular/mmalloc.h>
+//#include <Singular/idrec.h> // moved to Singular
+#include <Singular/attrib.h>
+#include <Singular/blackbox.h>
+#include <Singular/cntrlc.h>
+#include <Singular/links/dbm_sl.h>
+#include <Singular/distrib.h>
+#include <Singular/eigenval_ip.h>
+#include <Singular/gms.h>
+#include <Singular/grammar.h>
+#include <Singular/ipconv.h>
+#include <Singular/ipid.h>
+#include <Singular/ipprint.h>
+#include <Singular/ipshell.h>
+#include <Singular/libparse.h>
+#include <Singular/lists.h>
+#include <Singular/locals.h>
+#include <Singular/maps_ip.h>
+#include <Singular/misc_ip.h>
+#include <Singular/links/ndbm.h>
+#include <Singular/newstruct.h>
+#include <Singular/omSingularConfig.h>
+#include <Singular/pcv.h>
+#include <Singular/links/pipeLink.h>
+#include <Singular/run.h>
+#include <Singular/sdb.h>
+#include <Singular/links/silink.h>
+#include <Singular/links/sing_dbm.h>
+#include <Singular/links/slInit.h>
+#include <Singular/links/ssiLink.h>
+#include <Singular/stype.h>
+#include <Singular/subexpr.h>
+#include <Singular/tok.h>
+#include <Singular/utils.h>
+#include <Singular/walk.h>
+
+#include <Singular/fegetopt.h>
+
+void siInit(char *);
+
+int main( int, char *argv[] )
+{
+  assume( sizeof(long) == SIZEOF_LONG );
+
+  if( sizeof(long) != SIZEOF_LONG )
+  {
+     WerrorS("Bad config.h: wrong size of long!");
+
+     return(1);
+  }
+
+   // init path names etc.
+//  feInitResources(argv[0]); //???
+  siInit(argv[0]); // ?
+
+  if( char *s = versionString() )
+  {
+    PrintS(s);
+    omFree(s);
+  }
+
+
+
+  StringSetS("ressources in use (as reported by feStringAppendResources(0):\n");
+  feStringAppendResources(0);
+  StringAppendS("\n");
+  if( char * s = StringEndS() )
+  {
+    PrintS(s);
+    omFree(s);
+  }
+
+
+
+
+  // Libpolys tests:
+
+  // construct the ring Z/32003[x,y,z]
+  // the variable names
+  char **n=(char**)omalloc(3*sizeof(char*));
+  n[0]=omStrDup("x");
+  n[1]=omStrDup("y");
+  n[2]=omStrDup("z2");
+
+
+
+/*
+  ring R=rDefault(32003,3,n);
+  // make R the default ring:
+  rChangeCurrRing(R);
+
+  // create the polynomial 1
+  poly p1=pISet(1);
+
+  // create tthe polynomial 2*x^3*z^2
+  poly p2=p_ISet(2,R);
+  pSetExp(p2,1,3);
+  pSetExp(p2,3,2);
+  pSetm(p2);
+
+  // print p1 + p2
+  pWrite(p1); printf(" + \n"); pWrite(p2); printf("\n");
+
+  // compute p1+p2
+  p1=p_Add_q(p1,p2,R); p2=NULL;
+  pWrite(p1);
+
+  // clean up:
+  pDelete(&p1);
+
+  rDelete(R);
+  rChangeCurrRing(NULL);
+
+*/
+
+
+
+  currentVoice=feInitStdin(NULL);
+
+  int err=iiEStart(omStrDup("ring R = (0, a), x, dp; R; system(\"r\", R); minpoly=a*a+1; R; system(\"r\", R); kill R; return();\n"),NULL);
+
+  printf("interpreter returns %d\n",err);
+  if (err)
+     errorreported = 0; // reset error handling
+
+  assume( err == 0 );
+
+
+
+  // hook for error handling:
+  // WerrorS_callback=......; of type p(const char *)
+  err=iiEStart(omStrDup("int ver=system(\"version\");export ver;return();\n"),NULL);
+
+  printf("interpreter returns %d\n",err);
+  if (err)
+     errorreported = 0; // reset error handling
+
+  assume( err == 0 );
+
+  idhdl h=ggetid("ver");
+
+  if (h != NULL)
+    printf("singular variable ver of type %d contains %d\n",h->typ,(int)(long)IDDATA(h));
+  else
+    printf("variable ver does not exist\n");
+
+  assume( h != NULL );
+
+
+  err = iiEStart(
+                 omStrDup("system(\"--version\");return();\n"),
+                 NULL);
+
+  printf("interpreter returns %d\n",err);
+  if (err)
+     errorreported = 0; // reset error handling
+
+  assume( err == 0 );
+
+  // calling a singular-library function
+  idhdl datetime=ggetid("datetime");
+  if (datetime==NULL)
+    printf("datetime not found\n");
+  else
+  {
+    const BOOLEAN res=iiMake_proc(datetime,NULL,NULL);
+    if (res)
+    {
+      printf("iiMake_proc: datetime return an error\n");
+      errorreported = 0;
+    }
+    else
+    {
+      printf("iiMake_proc: datetime returned type %d, >>%s<<\n", iiRETURNEXPR.Typ(), (char *)iiRETURNEXPR.Data());
+      iiRETURNEXPR.CleanUp(); // calls Init afterwards
+    }
+  }
+
+  // changing a ring for the interpreter
+  // re-using n and R from above
+  ring R = rDefault(32003, 3, n);
+  idhdl newRingHdl=enterid("R" /* ring name*/,
+                           0, /*nesting level, 0=global*/
+                           RING_CMD,
+                           &IDROOT,
+                           FALSE);
+
+  IDRING(newRingHdl)=R;
+  // make R the default ring (include rChangeCurrRing):
+  rSetHdl(newRingHdl);
+  err=iiEStart(omStrDup("R; system(\"r\", R); poly p=x; p; system(\"p\", p); \"\"; poly pp = p * p; pp; listvar(); return();\n"),NULL);
+
+  // calling a kernel function via the interpreter interface
+  sleftv r1; memset(&r1,0,sizeof(r1));
+  sleftv arg; memset(&arg,0,sizeof(r1));
+  arg.rtyp=STRING_CMD;
+  arg.data=omStrDup("huhu");
+  err=iiExprArith1(&r1,&arg,TYPEOF_CMD);
+
+  printf("interpreter returns %d\n",err);
+  if (err)
+     errorreported = 0; // reset error handling
+  else
+     printf("typeof returned type %d, >>%s<<\n",r1.Typ(),r1.Data());
+
+  // clean up r1:
+  r1.CleanUp();
+
+  return 0;
+}
+
diff --git a/Singular/tesths.cc b/Singular/tesths.cc
new file mode 100644
index 0000000..893f215
--- /dev/null
+++ b/Singular/tesths.cc
@@ -0,0 +1,234 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+
+/*
+* ABSTRACT - initialize SINGULARs components, run Script and start SHELL
+*/
+
+
+
+
+#include <kernel/mod2.h>
+#include <omalloc/omalloc.h>
+
+#include <misc/auxiliary.h>
+#include <misc/options.h>
+
+#include <factory/factory.h>
+
+#include <kernel/oswrapper/feread.h>
+#include <Singular/fevoices.h>
+#include <kernel/oswrapper/timer.h>
+
+// #ifdef HAVE_FANS
+// #include <callgfanlib/bbcone.h>
+// #include <callgfanlib/bbpolytope.h>
+// #include <callgfanlib/bbfan.h>
+// #include <callgfanlib/gitfan.h>
+// #endif
+
+#include "ipshell.h"
+#include "cntrlc.h"
+#include "links/silink.h"
+#include "ipid.h"
+#include "sdb.h"
+#include "feOpt.h"
+#include "distrib.h"
+#include "mmalloc.h"
+#include "tok.h"
+#include "fegetopt.h"
+
+#include <Singular/countedref.h>
+#include <Singular/pyobject_setup.h>
+
+#include <unistd.h>
+#include <string.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <time.h>
+#include <errno.h>
+
+
+extern int siInit(char *);
+
+int mmInit( void )
+{
+#if defined(OMALLOC_USES_MALLOC) || defined(X_OMALLOC)
+    /* in mmstd.c, for some architectures freeSize() unconditionally uses the *system* free() */
+    /* sage ticket 5344: http://trac.sagemath.org/sage_trac/ticket/5344 */
+    /* do not rely on the default in Singular as libsingular may be different */
+    mp_set_memory_functions(omMallocFunc,omReallocSizeFunc,omFreeSizeFunc);
+#else
+    mp_set_memory_functions(malloc,reallocSize,freeSize);
+#endif
+  return 1;
+}
+
+/*0 implementation*/
+int main(          /* main entry to Singular */
+    int argc,      /* number of parameter */
+    char** argv)   /* parameter array */
+{
+  mmInit();
+  // Don't worry: ifdef OM_NDEBUG, then all these calls are undef'ed
+  omInitRet_2_Info(argv[0]);
+  omInitGetBackTrace();
+
+  siInit(argv[0]);
+  init_signals();
+
+  // parse command line options
+  int optc, option_index;
+  const char* errormsg;
+  while((optc = fe_getopt_long(argc, argv,
+                               SHORT_OPTS_STRING, feOptSpec, &option_index))
+        != EOF)
+  {
+    if (optc == '?' || optc == 0)
+    {
+      fprintf(stderr, "Use '%s --help' for a complete list of options\n", feArgv0);
+      exit(1);
+    }
+
+    if (optc != LONG_OPTION_RETURN)
+      option_index = feGetOptIndex(optc);
+
+    assume(option_index >= 0 && option_index < (int) FE_OPT_UNDEF);
+
+    if (fe_optarg == NULL &&
+        (feOptSpec[option_index].type == feOptBool ||
+         feOptSpec[option_index].has_arg == optional_argument))
+      errormsg = feSetOptValue((feOptIndex) option_index, (int) 1);
+    else
+      errormsg = feSetOptValue((feOptIndex) option_index, fe_optarg);
+
+    if (errormsg)
+    {
+      if (fe_optarg == NULL)
+        fprintf(stderr, "Error: Option '--%s' %s\n",
+               feOptSpec[option_index].name, errormsg);
+      else
+        fprintf(stderr, "Error: Option '--%s=%s' %s\n",
+               feOptSpec[option_index].name, fe_optarg, errormsg);
+      fprintf(stderr, "Use '%s --help' for a complete list of options\n", feArgv0);
+      exit(1);
+    }
+    if (optc == 'h') exit(0);
+  }
+
+  /* say hello */
+
+  if (TEST_V_QUIET)
+  {
+    (printf)(
+"                     SINGULAR                                 /"
+#ifndef MAKE_DISTRIBUTION
+"  Development"
+#endif
+"\n"
+" A Computer Algebra System for Polynomial Computations       /   version %s\n"
+"                                                           0<\n"
+" by: W. Decker, G.-M. Greuel, G. Pfister, H. Schoenemann     \\   %s\n"
+"FB Mathematik der Universitaet, D-67653 Kaiserslautern        \\\n"
+, VERSION, VERSION_DATE);
+  if (feOptValue(FE_OPT_NO_SHELL)) Warn("running in restricted mode:"
+    " shell invocation and links are disallowed");
+  }
+  else
+  {
+    if (feOptValue(FE_OPT_SORT)) On(SW_USE_NTL_SORT);
+#ifdef HAVE_SDB
+    sdb_flags = 0;
+#endif
+    dup2(1,2);
+    /* alternative:
+    *    memcpy(stderr,stdout,sizeof(FILE));
+    */
+  }
+
+#ifdef SINGULAR_PYOBJECT_SETUP_H
+   pyobject_setup();
+#endif
+#ifdef SI_COUNTEDREF_AUTOLOAD
+  countedref_init();
+#endif
+// #ifdef HAVE_FANS
+//   bbcone_setup();
+//   bbpolytope_setup();
+//   bbfan_setup();
+//   gitfan_setup();
+// #endif /* HAVE_FANS */
+  errorreported = 0;
+
+  // -- example for "static" modules ------
+  //load_builtin("huhu.so",FALSE,(SModulFunc_t)huhu_mod_init);
+  //module_help_main("huhu.so","Help for huhu\nhaha\n");
+  //module_help_proc("huhu.so","p","Help for huhu::p\nhaha\n");
+  setjmp(si_start_jmpbuf);
+
+  // Now, put things on the stack of stuff to do
+  // Last thing to do is to execute given scripts
+  if (fe_optind < argc)
+  {
+    int i = argc - 1;
+    FILE *fd;
+    while (i >= fe_optind)
+    {
+      if ((fd = feFopen(argv[i], "r")) == NULL)
+      {
+        Warn("Can not open %s", argv[i]);
+      }
+      else
+      {
+        fclose(fd);
+        newFile(argv[i]);
+      }
+      i--;
+    }
+  }
+  else
+  {
+    currentVoice=feInitStdin(NULL);
+  }
+
+  // before scripts, we execute -c, if it was given
+  if (feOptValue(FE_OPT_EXECUTE) != NULL)
+    newBuffer(omStrDup((char*) feOptValue(FE_OPT_EXECUTE)), BT_execute);
+
+  // first thing, however, is to load .singularrc from Singularpath
+  // and cwd/$HOME (in that order).
+  if (! feOptValue(FE_OPT_NO_RC))
+  {
+    char buf[MAXPATHLEN];
+    FILE * rc = feFopen("." DIR_SEPP ".singularrc", "r", buf);
+    if (rc == NULL) rc = feFopen("~" DIR_SEPP ".singularrc", "r", buf);
+    if (rc == NULL) rc = feFopen(".singularrc", "r", buf);
+
+    if (rc != NULL)
+    {
+      if (BVERBOSE(V_LOAD_LIB))
+        Print("// ** executing %s\n", buf);
+      fclose(rc);
+      newFile(buf);
+    }
+  }
+
+  /* start shell */
+  if (fe_fgets_stdin==fe_fgets_dummy)
+  {
+    singular_in_batchmode=TRUE;
+    char *linkname=(char*) feOptValue(FE_OPT_LINK);
+    if((linkname!=NULL)&&(strcmp(linkname,"ssi")==0))
+    {
+      return ssiBatch((char*) feOptValue(FE_OPT_MPHOST),(char*) feOptValue(FE_OPT_MPPORT));
+      //Print("batch: p:%s, h:%s\n",(char*) feOptValue(FE_OPT_MPPORT),(char*) feOptValue(FE_OPT_MPHOST));
+      //exit(0);
+    }
+  }
+  setjmp(si_start_jmpbuf);
+  yyparse();
+  m2_end(0);
+  return 0;
+}
+
diff --git a/Singular/tok.h b/Singular/tok.h
new file mode 100644
index 0000000..9e415b1
--- /dev/null
+++ b/Singular/tok.h
@@ -0,0 +1,172 @@
+#ifndef TOK_H
+#define TOK_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: tokens, types for interpreter; general macros
+*/
+
+#ifndef UMINUS
+#include <Singular/grammar.h>
+#endif
+
+extern int      yylineno;
+extern char     my_yylinebuf[80];
+
+#if defined(__cplusplus)
+extern int  yyparse(void);
+#endif
+
+/* Define to use old mechanismen for saving currRing with procedures
+ */
+#define USE_IILOCALRING 1
+
+
+/* the follwing defines for infix operators should not be changed: *
+*  grammar.y does not use the symbolic names                       *
+*  scanner.l uses the identies for some optimzations              */
+#define LOGIC_OP         '&'
+#define MULDIV_OP        '/'
+#define COMP_OP          '<'
+
+#define COMMAND           UMINUS+2 /* in tok.h */
+#define ANY_TYPE          UMINUS+3
+#define IDHDL             UMINUS+4
+
+enum {
+  ALIAS_CMD     = UMINUS + 15,
+  ATTRIB_CMD,
+  BAREISS_CMD,
+  BIGINT_CMD,
+  BRANCHTO_CMD,
+  BRACKET_CMD,
+  BREAKPOINT_CMD,
+  CHARACTERISTIC_CMD,
+  CHARSTR_CMD,
+  CHAR_SERIES_CMD,
+  CHINREM_CMD,
+  CMATRIX_CMD,
+  CNUMBER_CMD,
+  CLOSE_CMD,
+  COLS_CMD,
+  CONTENT_CMD,
+  COUNT_CMD,
+  CRING_CMD,
+  DBPRINT_CMD,
+  DEF_CMD,
+  DEFINED_CMD,
+  DELETE_CMD,
+  DENOMINATOR_CMD,
+  DET_CMD,
+  DUMP_CMD,
+  END_GRAMMAR,
+  ENVELOPE_CMD,
+  ERROR_CMD,
+  EXECUTE_CMD,
+  EXPORTTO_CMD,
+  EXTGCD_CMD,
+  FAC_CMD,
+  FIND_CMD,
+  FACSTD_CMD,
+  FMD_CMD,
+  FWALK_CMD,
+  FGLM_CMD,
+  FGLMQUOT_CMD,
+  FINDUNI_CMD,
+  GCD_CMD,
+  GETDUMP_CMD,
+  HIGHCORNER_CMD,
+  HRES_CMD,
+  IMPART_CMD,
+  IMPORTFROM_CMD,
+  INSERT_CMD,
+  INT_CMD,
+  INTDIV_CMD,
+  INTERPOLATE_CMD,
+  INTVEC_CMD,
+  IS_RINGVAR,
+  JANET_CMD,
+  KERNEL_CMD,
+  KILLATTR_CMD,
+  KRES_CMD,
+  LAGSOLVE_CMD,
+  LINK_CMD,
+  LIST_CMD,
+  LOAD_CMD,
+  LRES_CMD,
+  LU_CMD,
+  LUI_CMD,
+  LUS_CMD,
+  MEMORY_CMD,
+  MONITOR_CMD,
+  MPRES_CMD,
+  MSTD_CMD,
+  NAMEOF_CMD,
+  NAMES_CMD,
+  NEWSTRUCT_CMD,
+  NCALGEBRA_CMD,
+  NC_ALGEBRA_CMD,
+  NEWTONPOLY_CMD,
+  NPARS_CMD,
+  NUMERATOR_CMD,
+  NVARS_CMD,
+  OPEN_CMD,
+  OPPOSE_CMD,
+  OPPOSITE_CMD,
+  OPTION_CMD,
+  ORDSTR_CMD,
+  PACKAGE_CMD,
+  PARSTR_CMD,
+  PFAC_CMD,
+  PRIME_CMD,
+  PRINT_CMD,
+  PRUNE_CMD,
+  QRING_CMD,
+  QRDS_CMD,
+  RANDOM_CMD,
+  RANK_CMD,
+  READ_CMD,
+  REPART_CMD,
+  RESERVEDNAME_CMD,
+  RESULTANT_CMD,
+  RINGLIST_CMD,
+  ROWS_CMD,
+  SIMPLEX_CMD,
+  SLIM_GB_CMD,
+  SQR_FREE_CMD,
+  STATUS_CMD,
+  STRING_CMD,
+  SYSTEM_CMD,
+  TEST_CMD,
+  TRANSPOSE_CMD,
+  TRACE_CMD,
+  TWOSTD_CMD,
+  TYPEOF_CMD,
+  UNIVARIATE_CMD,
+  UNLOAD_CMD, /* unused*/
+  URSOLVE_CMD,
+  VANDER_CMD,
+  VARIABLES_CMD,
+  VARSTR_CMD,
+  WAIT1ST_CMD,
+  WAITALL_CMD,
+  WRITE_CMD,
+  /* start system var section: VECHO */
+  VECHO,
+  VCOLMAX,
+  VTIMER,
+  VRTIMER,
+  TRACE,
+  VOICE,
+  VSHORTOUT,
+  VPRINTLEVEL,
+  /* end system var section: VPRINTLEVEL */
+
+  MAX_TOK /* must be the last, biggest token number */
+};
+
+#define NONE END_RING
+#define UNKNOWN 0
+
+#endif
diff --git a/Singular/utils.cc b/Singular/utils.cc
new file mode 100644
index 0000000..9e0852f
--- /dev/null
+++ b/Singular/utils.cc
@@ -0,0 +1,250 @@
+#include <kernel/mod2.h>
+
+#ifdef STANDALONE_PARSER
+
+#include <Singular/fegetopt.h>
+#include <Singular/utils.h>
+#include <Singular/libparse.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+extern FILE *yylpin;
+extern char *optarg;
+extern int optind, opterr, optopt;
+extern int lpverbose, check;
+extern int texinfo_out;
+
+extern int category_out;
+
+extern int found_version, found_info, found_oldhelp, found_proc_in_proc;
+int warning_info = 0, warning_version = 0;
+
+static void usage(char *progname)
+{
+  printf("libparse: a syntax-checker for Singular Libraries.\n");
+  printf("USAGE: %s [options] singular-library\n", progname);
+  printf("Options:\n");
+  printf("   -f <singular library> : performs syntax-checks\n");
+  printf("   -d [digit]            : digit=1,..,4 increases the verbosity of the checks\n");
+  printf("   -s                    : turns on reporting about violations of unenforced syntax rules\n");
+  printf("   -i                    : perl output of examples and help of procs\n");
+  printf("   -c                    : print category of lib to stdout and exit\n");
+  printf("   -h                    : print this message\n");
+  exit(1);
+}
+
+static char* lib_file = NULL;
+
+/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
+void main_init(int argc, char *argv[])
+{
+  char c;
+
+  while((c=fe_getopt(argc, argv, "ihdc:sf:"))>=0)
+  {
+    switch(c)
+    {
+        case 'd':
+          lpverbose = 1;
+          if(isdigit(argv[fe_optind-1][0])) sscanf(optarg, "%d", &lpverbose);
+          else fe_optind--;
+          break;
+        case 'f': lib_file = argv[fe_optind-1];
+          break;
+        case 's':
+          check++;
+          break;
+        case 'i':
+          texinfo_out = 1;
+          break;
+        case 'c':
+          category_out = 1;
+          break;
+
+        case 'h' :
+          usage(argv[0]);
+          break;
+        case -1 : printf("no such option:%s\n", argv[fe_optind]);
+          usage(argv[0]);
+          break;
+        default: printf("no such option.%x, %c %s\n", c&0xff, c, argv[fe_optind]);
+          usage(argv[0]);
+    }
+  }
+  if (texinfo_out || category_out) lpverbose = 0;
+
+  if(lib_file!=NULL)
+  {
+    yylpin = fopen( lib_file, "rb" );
+    if (! (texinfo_out || category_out))
+      printf("Checking library '%s'\n", lib_file);
+    else if (! category_out)
+      printf("$library = \"%s\";\n", lib_file);
+  }
+  else
+  {
+    while(argc>fe_optind && yylpin==NULL)
+    {
+      yylpin = fopen( argv[fe_optind], "rb" );
+      if(yylpin!=NULL)
+      {
+        lib_file = argv[fe_optind];
+        if (! (texinfo_out || category_out) )
+          printf("Checking library '%s'\n", argv[fe_optind]);
+        else if (! category_out)
+          printf("$library = \"%s\";\n", lib_file);
+      }
+      else fe_optind++;
+    }
+  }
+  if(yylpin == NULL)
+  {
+    printf("No library found to parse.\n");
+    usage(argv[0]);
+  }
+}
+
+/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
+void main_result(char */*libname*/)
+{
+  if(!found_info)    printf("*** No info-string found!\n");
+  if(!found_version) printf("*** No version-string found!\n");
+  if(found_oldhelp)  printf("*** Library has stil OLD library-format.\n");
+  if(found_info && warning_info)
+    printf("*** INFO-string should come before every procedure definition.\n");
+  if(found_version && warning_version)
+    printf("*** VERSION-string should come before every procedure definition.\n");
+}
+/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
+procinfo *iiInitSingularProcinfo(procinfo* pi, const char *libname,
+                                 const char *procname, int line, long pos,
+                                 BOOLEAN pstatic /*= FALSE*/)
+{
+  pi->libname = (char *)malloc(strlen(libname)+1);
+  memcpy(pi->libname, libname, strlen(libname));
+  *(pi->libname+strlen(libname)) = '\0';
+
+  pi->procname = (char *)malloc(strlen(procname)+1);
+  strcpy(pi->procname, procname/*, strlen(procname)*/);
+  pi->language = LANG_SINGULAR;
+  pi->ref = 1;
+  pi->is_static = pstatic;
+  pi->data.s.proc_start = pos;
+  pi->data.s.def_end    = 0L;
+  pi->data.s.help_start = 0L;
+  pi->data.s.body_start = 0L;
+  pi->data.s.body_end   = 0L;
+  pi->data.s.example_start = 0L;
+  pi->data.s.proc_lineno = line;
+  pi->data.s.body_lineno = 0;
+  pi->data.s.example_lineno = 0;
+  pi->data.s.body = NULL;
+  pi->data.s.help_chksum = 0;
+  return(pi);
+}
+
+/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
+void pi_clear(procinfov pi)
+{
+  free(pi->libname);
+  free(pi->procname);
+  free(pi);
+}
+
+/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
+
+#ifndef SEEK_SET
+#define SEEK_SET 0
+#endif
+
+static void PrintOut(FILE *fd, int pos_start, int pos_end)
+{
+  if (pos_start <= 0 || pos_end - pos_start <= 4) return;
+  char c = 0;
+
+  fseek(fd, pos_start, SEEK_SET);
+  while (pos_start++ <= pos_end)
+  {
+    if (c == '\\')
+    {
+      c = fgetc(fd);
+      if (c != '"') putchar('\\');
+    }
+    else
+      c = fgetc(fd);
+    if (c == '@' || c == '$') putchar('\\');
+    if (c != '\r') putchar(c);
+  }
+  if (c == '\\') putchar('\\');
+}
+
+
+void printpi(procinfov pi)
+{
+  // char *buf, name[256];
+  // int len1, len2;
+  /* pi->libname is badly broken -- use file, instead */
+  FILE *fp = fopen( lib_file, "rb");
+
+  if (fp == NULL)
+  {
+    printf("Can not open %s\n", lib_file);
+    return;
+  }
+
+  if(!found_info && !warning_info) warning_info++;
+  if(!found_version && !warning_version) warning_version++;
+  if(pi->data.s.body_end==0)
+    pi->data.s.body_end = pi->data.s.proc_end;
+
+  if (texinfo_out)
+  {
+   if ((! pi->is_static) &&
+        (pi->data.s.body_start - pi->data.s.def_end > 10) &&
+        (! found_proc_in_proc))
+    {
+      printf("push(@procs, \"%s\");\n", pi->procname);
+      printf("$help{\"%s\"} = <<EOT;\n", pi->procname);
+      PrintOut(fp, pi->data.s.help_start, pi->data.s.body_start-3);
+      printf("\nEOT\n");
+      if ((pi->data.s.example_start > 0) &&
+          (pi->data.s.proc_end - pi->data.s.example_start > 10))
+      {
+        printf("$example{\"%s\"} = <<EOT;\n", pi->procname);
+        PrintOut(fp, pi->data.s.example_start, pi->data.s.proc_end);
+        printf("\nEOT\n");
+      }
+      printf("$chksum{\"%s\"} = %ld;\n", pi->procname, pi->data.s.help_chksum);
+    }
+  }
+  else if (! category_out)
+  {
+    if(lpverbose) printf("//     ");
+    printf( "%c %-15s  %20s ", pi->is_static ? 'l' : 'g', pi->libname,
+            pi->procname);
+    printf("line %4d,%5ld-%-5ld  %4d,%5ld-%-5ld  %4d,%5ld-%-5ld\n",
+           pi->data.s.proc_lineno, pi->data.s.proc_start, pi->data.s.def_end,
+           pi->data.s.body_lineno, pi->data.s.body_start, pi->data.s.body_end,
+           pi->data.s.example_lineno, pi->data.s.example_start,
+           pi->data.s.proc_end);
+    if(check) {
+      if(!pi->is_static && (pi->data.s.body_start-pi->data.s.def_end)<4)
+        printf("*** Procedure '%s' is global and has no help-section.\n",
+               pi->procname);
+      if(!pi->is_static && !pi->data.s.example_start)
+        printf("*** Procedure '%s' is global and has no example-section.\n",\
+               pi->procname);
+      if(found_proc_in_proc)
+        printf("*** found proc within procedure '%s'.\n", pi->procname);
+    }
+  }
+
+  if (fp != NULL) fclose(fp);
+
+}
+
+/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
+#endif
diff --git a/Singular/utils.h b/Singular/utils.h
new file mode 100644
index 0000000..eb265b0
--- /dev/null
+++ b/Singular/utils.h
@@ -0,0 +1,11 @@
+/*
+ */
+
+#ifndef FALSE
+#define FALSE       0
+#endif
+
+#ifndef TRUE
+#define TRUE        1
+#endif
+
diff --git a/Singular/walk.cc b/Singular/walk.cc
new file mode 100644
index 0000000..a5a72a6
--- /dev/null
+++ b/Singular/walk.cc
@@ -0,0 +1,8723 @@
+/*****************************************
+*  Computer Algebra System SINGULAR      *
+*****************************************/
+/* $Id$ */
+/*
+* ABSTRACT: Implementation of the Groebner walk
+*/
+
+// define if the Buchberger alg should be used
+//   to compute a reduced GB of a omega-homogenoues ideal
+// default: we use the hilbert driven algorithm.
+#define BUCHBERGER_ALG  //we use the improved Buchberger alg.
+
+//#define UPPER_BOUND //for the original "Tran" algorithm
+//#define REPRESENTATION_OF_SIGMA //if one perturbs sigma in Tran
+
+//#define TEST_OVERFLOW
+//#define CHECK_IDEAL
+//#define CHECK_IDEAL_MWALK
+
+//#define NEXT_VECTORS_CC
+//#define PRINT_VECTORS //to print vectors (sigma, tau, omega)
+
+#define INVEPS_SMALL_IN_FRACTAL  //to choose the small invers of epsilon
+#define INVEPS_SMALL_IN_MPERTVECTOR  //to choose the small invers of epsilon
+#define INVEPS_SMALL_IN_TRAN  //to choose the small invers of epsilon
+
+#define FIRST_STEP_FRACTAL // to define the first step of the fractal
+//#define MSTDCC_FRACTAL // apply Buchberger alg to compute a red GB, if
+//                          tau doesn't stay in the correct cone
+
+//#define TIME_TEST // print the used time of each subroutine
+//#define ENDWALKS //print the size of the last omega-homogenoues Groebner basis
+
+/* includes */
+
+#include <kernel/mod2.h>
+#include <misc/intvec.h>
+#include <Singular/cntrlc.h>
+#include <misc/options.h>
+#include <omalloc/omalloc.h>
+#include <Singular/ipshell.h>
+#include <Singular/ipconv.h>
+#include <coeffs/coeffs.h>
+#include <Singular/subexpr.h>
+
+#include <polys/monomials/maps.h>
+
+/* include Hilbert-function */
+#include <kernel/combinatorics/stairc.h>
+
+/** kstd2.cc */
+#include <kernel/GBEngine/kutil.h>
+#include <kernel/GBEngine/khstd.h>
+
+#include <Singular/walk.h>
+#include <kernel/polys.h>
+#include <kernel/ideals.h>
+#include <Singular/ipid.h>
+#include <Singular/tok.h>
+#include <coeffs/numbers.h>
+#include <Singular/ipid.h>
+#include <polys/monomials/ring.h>
+#include <kernel/GBEngine/kstd1.h>
+#include <polys/matpol.h>
+#include <polys/weight.h>
+#include <misc/intvec.h>
+#include <kernel/GBEngine/syz.h>
+#include <Singular/lists.h>
+#include <polys/prCopy.h>
+#include <polys/monomials/ring.h>
+//#include <polys/ext_fields/longalg.h>
+#include <polys/clapsing.h>
+
+#include <coeffs/mpr_complex.h>
+
+#include <stdio.h>
+// === Zeit & System (Holger Croeni ===
+#include <time.h>
+#include <sys/time.h>
+#include <math.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <float.h>
+#include <misc/mylimits.h>
+#include <sys/types.h>
+
+int nstep;
+
+extern BOOLEAN ErrorCheck();
+
+extern BOOLEAN pSetm_error;
+
+void Set_Error( BOOLEAN f) { pSetm_error=f; }
+
+BOOLEAN Overflow_Error =  FALSE;
+
+clock_t xtif, xtstd, xtlift, xtred, xtnw;
+clock_t xftostd, xtextra, xftinput, to;
+
+/****************************
+ * utilities for TSet, LSet *
+ ****************************/
+inline static intset initec (int maxnr)
+{
+  return (intset)omAlloc(maxnr*sizeof(int));
+}
+
+inline static unsigned long* initsevS (int maxnr)
+{
+  return (unsigned long*)omAlloc0(maxnr*sizeof(unsigned long));
+}
+inline static int* initS_2_R (int maxnr)
+{
+  return (int*)omAlloc0(maxnr*sizeof(int));
+}
+
+/************************************
+ * construct the set s from F u {P} *
+ ************************************/
+// unused
+#if 0
+static void initSSpecialCC (ideal F, ideal Q, ideal P,kStrategy strat)
+{
+  int   i,pos;
+
+  if (Q!=NULL) i=((IDELEMS(Q)+(setmaxTinc-1))/setmaxTinc)*setmaxTinc;
+  else i=setmaxT;
+
+  strat->ecartS=initec(i);
+  strat->sevS=initsevS(i);
+  strat->S_2_R=initS_2_R(i);
+  strat->fromQ=NULL;
+  strat->Shdl=idInit(i,F->rank);
+  strat->S=strat->Shdl->m;
+
+  // - put polys into S -
+  if (Q!=NULL)
+  {
+    strat->fromQ=initec(i);
+    memset(strat->fromQ,0,i*sizeof(int));
+    for (i=0; i<IDELEMS(Q); i++)
+    {
+      if (Q->m[i]!=NULL)
+      {
+        LObject h;
+        h.p = pCopy(Q->m[i]);
+        //if (TEST_OPT_INTSTRATEGY)
+        //{
+        //  //pContent(h.p);
+        //  h.pCleardenom(); // also does a pContent
+        //}
+        //else
+        //{
+        //  h.pNorm();
+        //}
+        strat->initEcart(&h);
+        if (rHasLocalOrMixedOrdering_currRing())
+        {
+          deleteHC(&h,strat);
+        }
+        if (h.p!=NULL)
+        {
+          if (strat->sl==-1)
+            pos =0;
+          else
+          {
+            pos = posInS(strat,strat->sl,h.p,h.ecart);
+          }
+          h.sev = pGetShortExpVector(h.p);
+          h.SetpFDeg();
+          strat->enterS(h,pos,strat, strat->tl+1);
+          enterT(h, strat);
+          strat->fromQ[pos]=1;
+        }
+      }
+    }
+  }
+  //- put polys into S -
+  for (i=0; i<IDELEMS(F); i++)
+  {
+    if (F->m[i]!=NULL)
+    {
+      LObject h;
+      h.p = pCopy(F->m[i]);
+      if (rHasGlobalOrdering(currRing))
+      {
+        //h.p=redtailBba(h.p,strat->sl,strat);
+        h.p=redtailBba(h.p,strat->sl,strat);
+      }
+      else
+      {
+        deleteHC(&h,strat);
+      }
+      strat->initEcart(&h);
+      if (h.p!=NULL)
+      {
+        if (strat->sl==-1)
+          pos =0;
+        else
+          pos = posInS(strat,strat->sl,h.p,h.ecart);
+        h.sev = pGetShortExpVector(h.p);
+        strat->enterS(h,pos,strat, strat->tl+1);
+        h.length = pLength(h.p);
+        h.SetpFDeg();
+        enterT(h,strat);
+      }
+    }
+  }
+#ifdef INITSSPECIAL
+  for (i=0; i<IDELEMS(P); i++)
+  {
+    if (P->m[i]!=NULL)
+    {
+      LObject h;
+      h.p=pCopy(P->m[i]);
+      strat->initEcart(&h);
+      h.length = pLength(h.p);
+      if (TEST_OPT_INTSTRATEGY)
+      {
+        h.pCleardenom();
+      }
+      else
+      {
+        h.pNorm();
+      }
+      if(strat->sl>=0)
+      {
+        if (rHasGlobalOrdering(currRing))
+        {
+          h.p=redBba(h.p,strat->sl,strat);
+          if (h.p!=NULL)
+            h.p=redtailBba(h.p,strat->sl,strat);
+        }
+        else
+        {
+          h.p=redMora(h.p,strat->sl,strat);
+          strat->initEcart(&h);
+        }
+        if(h.p!=NULL)
+        {
+          if (TEST_OPT_INTSTRATEGY)
+          {
+            h.pCleardenom();
+          }
+          else
+          {
+            h.is_normalized = 0;
+            h.pNorm();
+          }
+          h.sev = pGetShortExpVector(h.p);
+          h.SetpFDeg();
+          pos = posInS(strat->S,strat->sl,h.p,h.ecart);
+          enterpairsSpecial(h.p,strat->sl,h.ecart,pos,strat,strat->tl+1);
+          strat->enterS(h,pos,strat, strat->tl+1);
+          enterT(h,strat);
+        }
+      }
+      else
+      {
+        h.sev = pGetShortExpVector(h.p);
+        h.SetpFDeg();
+        strat->enterS(h,0,strat, strat->tl+1);
+        enterT(h,strat);
+      }
+    }
+  }
+#endif
+}
+#endif
+
+/*****************
+ *interreduce F  *
+ *****************/
+static ideal kInterRedCC(ideal F, ideal Q)
+{
+  int j;
+  kStrategy strat = new skStrategy;
+
+//  if (TEST_OPT_PROT)
+//  {
+//    writeTime("start InterRed:");
+//    mflush();
+//  }
+  //strat->syzComp     = 0;
+  strat->kHEdgeFound = (currRing->ppNoether) != NULL;
+  strat->kNoether=pCopy((currRing->ppNoether));
+  strat->ak = id_RankFreeModule(F, currRing);
+  initBuchMoraCrit(strat);
+  strat->NotUsedAxis = (BOOLEAN *)omAlloc((currRing->N+1)*sizeof(BOOLEAN));
+  for(j=currRing->N; j>0; j--)
+  {
+    strat->NotUsedAxis[j] = TRUE;
+  }
+  strat->enterS      = enterSBba;
+  strat->posInT      = posInT0;
+  strat->initEcart   = initEcartNormal;
+  strat->sl   = -1;
+  strat->tl          = -1;
+  strat->tmax        = setmaxT;
+  strat->T           = initT();
+  strat->R           = initR();
+  strat->sevT        = initsevT();
+  if(rHasLocalOrMixedOrdering_currRing())
+  {
+    strat->honey = TRUE;
+  }
+
+  //initSCC(F,Q,strat);
+  initS(F,Q,strat);
+
+  /*
+  timetmp=clock();//22.01.02
+  initSSpecialCC(F,Q,NULL,strat);
+  tininitS=tininitS+clock()-timetmp;//22.01.02
+  */
+  if(TEST_OPT_REDSB)
+  {
+    strat->noTailReduction=FALSE;
+  }
+  updateS(TRUE,strat);
+
+  if(TEST_OPT_REDSB && TEST_OPT_INTSTRATEGY)
+  {
+    completeReduce(strat);
+  }
+  pDelete(&strat->kHEdge);
+  omFreeSize((ADDRESS)strat->T,strat->tmax*sizeof(TObject));
+  omFreeSize((ADDRESS)strat->ecartS,IDELEMS(strat->Shdl)*sizeof(int));
+  omFreeSize((ADDRESS)strat->sevS,IDELEMS(strat->Shdl)*sizeof(unsigned long));
+  omFreeSize((ADDRESS)strat->NotUsedAxis,(currRing->N+1)*sizeof(BOOLEAN));
+  omfree(strat->sevT);
+  omfree(strat->S_2_R);
+  omfree(strat->R);
+
+  if(strat->fromQ)
+  {
+    for(j=0; j<IDELEMS(strat->Shdl); j++)
+    {
+      if(strat->fromQ[j])
+      {
+        pDelete(&strat->Shdl->m[j]);
+      }
+    }
+    omFreeSize((ADDRESS)strat->fromQ,IDELEMS(strat->Shdl)*sizeof(int));
+    strat->fromQ = NULL;
+  }
+//  if (TEST_OPT_PROT)
+//  {
+//    writeTime("end Interred:");
+//    mflush();
+//  }
+  ideal shdl=strat->Shdl;
+  idSkipZeroes(shdl);
+  delete(strat);
+
+  return shdl;
+}
+
+//unused
+#if 0
+static void TimeString(clock_t tinput, clock_t tostd, clock_t tif,clock_t tstd,
+                       clock_t tlf,clock_t tred, clock_t tnw, int step)
+{
+  double totm = ((double) (clock() - tinput))/1000000;
+  double ostd,mostd, mif, mstd, mlf, mred, mnw, mxif,mxstd,mxlf,mxred,mxnw,tot;
+  // double mextra
+  Print("\n// total time = %.2f sec", totm);
+  Print("\n// tostd = %.2f sec = %.2f", ostd=((double) tostd)/1000000,
+        mostd=((((double) tostd)/1000000)/totm)*100);
+  Print("\n// tif   = %.2f sec = %.2f", ((double) tif)/1000000,
+        mif=((((double) tif)/1000000)/totm)*100);
+  Print("\n// std   = %.2f sec = %.2f", ((double) tstd)/1000000,
+        mstd=((((double) tstd)/1000000)/totm)*100);
+  Print("\n// lift  = %.2f sec = %.2f", ((double) tlf)/1000000,
+        mlf=((((double) tlf)/1000000)/totm)*100);
+  Print("\n// ired  = %.2f sec = %.2f", ((double) tred)/1000000,
+        mred=((((double) tred)/1000000)/totm)*100);
+  Print("\n// nextw = %.2f sec = %.2f", ((double) tnw)/1000000,
+        mnw=((((double) tnw)/1000000)/totm)*100);
+  PrintS("\n Time for the last step:");
+  Print("\n// xinfo = %.2f sec = %.2f", ((double) xtif)/1000000,
+        mxif=((((double) xtif)/1000000)/totm)*100);
+  Print("\n// xstd  = %.2f sec = %.2f", ((double) xtstd)/1000000,
+        mxstd=((((double) xtstd)/1000000)/totm)*100);
+  Print("\n// xlift = %.2f sec = %.2f", ((double) xtlift)/1000000,
+        mxlf=((((double) xtlift)/1000000)/totm)*100);
+  Print("\n// xired = %.2f sec = %.2f", ((double) xtred)/1000000,
+        mxred=((((double) xtred)/1000000)/totm)*100);
+  Print("\n// xnextw= %.2f sec = %.2f", ((double) xtnw)/1000000,
+        mxnw=((((double) xtnw)/1000000)/totm)*100);
+
+  tot=mostd+mif+mstd+mlf+mred+mnw+mxif+mxstd+mxlf+mxred+mxnw;
+  double res = (double) 100 - tot;
+  Print("\n// &%d&%.2f&%.2f&%.2f&%.2f&%.2f&%.2f&%.2f&%.2f&%.2f&%.2f&%.2f&%.2f&%.2f&%.2f&%.2f(%.2f)\\ \\",
+        step, ostd, totm, mostd,mif,mstd,mlf,mred,mnw,mxif,mxstd,mxlf,mxred,mxnw,tot,res,
+        ((((double) xtextra)/1000000)/totm)*100);
+}
+#endif
+
+//unused
+#if 0
+static void TimeStringFractal(clock_t tinput, clock_t tostd, clock_t tif,clock_t tstd,
+                       clock_t textra, clock_t tlf,clock_t tred, clock_t tnw)
+{
+
+  double totm = ((double) (clock() - tinput))/1000000;
+  double ostd, mostd, mif, mstd, mextra, mlf, mred, mnw, tot, res;
+  Print("\n// total time = %.2f sec", totm);
+  Print("\n// tostd = %.2f sec = %.2f", ostd=((double) tostd)/1000000,
+        mostd=((((double) tostd)/1000000)/totm)*100);
+  Print("\n// tif   = %.2f sec = %.2f", ((double) tif)/1000000,
+        mif=((((double) tif)/1000000)/totm)*100);
+  Print("\n// std   = %.2f sec = %.2f", ((double) tstd)/1000000,
+        mstd=((((double) tstd)/1000000)/totm)*100);
+  Print("\n// xstd  = %.2f sec = %.2f", ((double) textra)/1000000,
+        mextra=((((double) textra)/1000000)/totm)*100);
+  Print("\n// lift  = %.2f sec = %.2f", ((double) tlf)/1000000,
+        mlf=((((double) tlf)/1000000)/totm)*100);
+  Print("\n// ired  = %.2f sec = %.2f", ((double) tred)/1000000,
+        mred=((((double) tred)/1000000)/totm)*100);
+  Print("\n// nextw = %.2f sec = %.2f", ((double) tnw)/1000000,
+        mnw=((((double) tnw)/1000000)/totm)*100);
+  tot = mostd+mif+mstd+mextra+mlf+mred+mnw;
+  res = (double) 100.00-tot;
+  Print("\n// &%.2f &%.2f&%.2f &%.2f &%.2f &%.2f &%.2f &%.2f &%.2f&%.2f&%.2f\\ \\ ",
+        ostd,totm,mostd,mif,mstd,mextra,mlf,mred,mnw,tot,res);
+}
+#endif
+
+#ifdef CHECK_IDEAL_MWALK
+static void idString(ideal L, const char* st)
+{
+  int i, nL = IDELEMS(L);
+
+  Print("\n//  ideal %s =  ", st);
+  for(i=0; i<nL-1; i++)
+  {
+    Print(" %s, ", pString(L->m[i]));
+  }
+  Print(" %s;", pString(L->m[nL-1]));
+}
+#endif
+
+#if defined(CHECK_IDEAL_MWALK) || defined(ENDWALKS)
+static void headidString(ideal L, char* st)
+{
+  int i, nL = IDELEMS(L);
+
+  Print("\n//  ideal %s =  ", st);
+  for(i=0; i<nL-1; i++)
+  {
+    Print(" %s, ", pString(pHead(L->m[i])));
+  }
+  Print(" %s;", pString(pHead(L->m[nL-1])));
+}
+#endif
+
+#if defined(CHECK_IDEAL_MWALK) || defined(ENDWALKS)
+static void idElements(ideal L, char* st)
+{
+  int i, nL = IDELEMS(L);
+  int *K=(int *)omAlloc(nL*sizeof(int));
+
+  Print("\n//  #monoms of %s =  ", st);
+  for(i=0; i<nL; i++)
+  {
+    K[i] = pLength(L->m[i]);
+  }
+  int j, nsame;
+  // int  nk=0;
+  for(i=0; i<nL; i++)
+  {
+    if(K[i]!=0)
+    {
+      nsame = 1;
+      for(j=i+1; j<nL; j++)
+      {
+        if(K[j]==K[i])
+        {
+          nsame ++;
+          K[j]=0;
+        }
+      }
+      if(nsame == 1)
+      {
+        Print("%d, ",K[i]);
+      }
+      else
+      {
+        Print("%d[%d], ", K[i], nsame);
+      }
+    }
+  }
+  omFree(K);
+}
+#endif
+
+
+static void ivString(intvec* iv, const char* ch)
+{
+  int nV = iv->length()-1;
+  Print("\n// intvec %s =  ", ch);
+
+  for(int i=0; i<nV; i++)
+  {
+    Print("%d, ", (*iv)[i]);
+  }
+  Print("%d;", (*iv)[nV]);
+}
+
+//unused
+//#if 0
+static void MivString(intvec* iva, intvec* ivb, intvec* ivc)
+{
+  int nV = iva->length()-1;
+  int i;
+  PrintS("\n//  (");
+  for(i=0; i<nV; i++)
+  {
+    Print("%d, ", (*iva)[i]);
+  }
+  Print("%d) ==> (", (*iva)[nV]);
+  for(i=0; i<nV; i++)
+  {
+    Print("%d, ", (*ivb)[i]);
+  }
+  Print("%d) := (", (*ivb)[nV]);
+
+  for(i=0; i<nV; i++)
+  {
+    Print("%d, ", (*ivc)[i]);
+  }
+  Print("%d)", (*ivc)[nV]);
+}
+//#endif
+
+/********************************************************************
+ * returns gcd of integers a and b                                  *
+ ********************************************************************/
+static inline long gcd(const long a, const long b)
+{
+  long r, p0 = a, p1 = b;
+  //assume(p0 >= 0 && p1 >= 0);
+  if(p0 < 0)
+  {
+    p0 = -p0;
+  }
+  if(p1 < 0)
+  {
+    p1 = -p1;
+  }
+  while(p1 != 0)
+  {
+    r = p0 % p1;
+    p0 = p1;
+    p1 = r;
+  }
+  return p0;
+}
+
+/*********************************************
+ * cancel gcd of integers zaehler and nenner *
+ *********************************************/
+static void cancel(mpz_t zaehler, mpz_t nenner)
+{
+//  assume(zaehler >= 0 && nenner > 0);
+  mpz_t g;
+  mpz_init(g);
+  mpz_gcd(g, zaehler, nenner);
+
+  mpz_div(zaehler , zaehler, g);
+  mpz_div(nenner ,  nenner, g);
+
+  mpz_clear(g);
+}
+
+//unused
+#if 0
+static int isVectorNeg(intvec* omega)
+{
+  int i;
+
+  for(i=omega->length(); i>=0; i--)
+  {
+    if((*omega)[i]<0)
+    {
+      return 1;
+    }
+  }
+  return 0;
+}
+#endif
+
+/********************************************************************
+ * compute a weight degree of a monomial p w.r.t. a weight_vector   *
+ ********************************************************************/
+static inline int MLmWeightedDegree(const poly p, intvec* weight)
+{
+  /* 2147483647 is max. integer representation in SINGULAR */
+  mpz_t sing_int;
+  mpz_init_set_ui(sing_int,  2147483647);
+
+  int i, wgrad;
+
+  mpz_t zmul;
+  mpz_init(zmul);
+  mpz_t zvec;
+  mpz_init(zvec);
+  mpz_t zsum;
+  mpz_init(zsum);
+
+  for (i=currRing->N; i>0; i--)
+  {
+    mpz_set_si(zvec, (*weight)[i-1]);
+    mpz_mul_ui(zmul, zvec, pGetExp(p, i));
+    mpz_add(zsum, zsum, zmul);
+  }
+
+  wgrad = mpz_get_ui(zsum);
+
+  if(mpz_cmp(zsum, sing_int)>0)
+  {
+    if(Overflow_Error ==  FALSE)
+    {
+      PrintLn();
+      PrintS("\n// ** OVERFLOW in \"MwalkInitialForm\": ");
+      mpz_out_str( stdout, 10, zsum);
+      PrintS(" is greater than 2147483647 (max. integer representation)");
+      Overflow_Error = TRUE;
+    }
+  }
+
+  mpz_clear(zmul);
+  mpz_clear(zvec);
+  mpz_clear(zsum);
+  mpz_clear(sing_int);
+
+  return wgrad;
+}
+
+/********************************************************************
+ * compute a weight degree of a polynomial p w.r.t. a weight_vector *
+ ********************************************************************/
+static inline int MwalkWeightDegree(poly p, intvec* weight_vector)
+{
+  assume(weight_vector->length() >= currRing->N);
+  int max = 0, maxtemp;
+
+  while(p != NULL)
+  {
+    maxtemp = MLmWeightedDegree(p, weight_vector);
+    pIter(p);
+
+    if (maxtemp > max)
+    {
+      max = maxtemp;
+    }
+  }
+  return max;
+}
+
+
+/********************************************************************
+ * compute a weight degree of a monomial p w.r.t. a weight_vector   *
+ ********************************************************************/
+static  void  MLmWeightedDegree_gmp(mpz_t result, const poly p, intvec* weight)
+{
+  /* 2147483647 is max. integer representation in SINGULAR */
+  mpz_t sing_int;
+  mpz_init_set_ui(sing_int,  2147483647);
+
+  int i;
+
+  mpz_t zmul;
+  mpz_init(zmul);
+  mpz_t zvec;
+  mpz_init(zvec);
+  mpz_t ztmp;
+  mpz_init(ztmp);
+
+  for (i=currRing->N; i>0; i--)
+  {
+    mpz_set_si(zvec, (*weight)[i-1]);
+    mpz_mul_ui(zmul, zvec, pGetExp(p, i));
+    mpz_add(ztmp, ztmp, zmul);
+  }
+  mpz_init_set(result, ztmp);
+  mpz_clear(ztmp);
+  mpz_clear(sing_int);
+  mpz_clear(zvec);
+  mpz_clear(zmul);
+}
+
+
+/*****************************************************************************
+ * return an initial form of the polynom g w.r.t. a weight vector curr_weight *
+ *****************************************************************************/
+static poly MpolyInitialForm(poly g, intvec* curr_weight)
+{
+  if(g == NULL)
+  {
+    return NULL;
+  }
+  mpz_t max; mpz_init(max);
+  mpz_t maxtmp; mpz_init(maxtmp);
+
+  poly hg, in_w_g = NULL;
+
+  while(g != NULL)
+  {
+    hg = g;
+    pIter(g);
+    MLmWeightedDegree_gmp(maxtmp, hg, curr_weight);
+
+    if(mpz_cmp(maxtmp, max)>0)
+    {
+      mpz_init_set(max, maxtmp);
+      pDelete(&in_w_g);
+      in_w_g = pHead(hg);
+    }
+    else
+    {
+      if(mpz_cmp(maxtmp, max)==0)
+      {
+        in_w_g = pAdd(in_w_g, pHead(hg));
+      }
+    }
+  }
+  return in_w_g;
+}
+
+/************************************************************************
+ * compute the initial form of an ideal <G> w.r.t. a weight vector iva  *
+ ************************************************************************/
+ideal MwalkInitialForm(ideal G, intvec* ivw)
+{
+  BOOLEAN nError =  Overflow_Error;
+  Overflow_Error = FALSE;
+
+  int i, nG = IDELEMS(G);
+  ideal Gomega = idInit(nG, 1);
+
+  for(i=nG-1; i>=0; i--)
+  {
+    Gomega->m[i] = MpolyInitialForm(G->m[i], ivw);
+  }
+  if(Overflow_Error == FALSE)
+  {
+    Overflow_Error = nError;
+  }
+  return Gomega;
+}
+
+/************************************************************************
+ * test whether the weight vector iv is in the cone of the ideal G      *
+ *     i.e. test whether in(in_w(g)) = in(g) for all g in G             *
+ ************************************************************************/
+
+static int test_w_in_ConeCC(ideal G, intvec* iv)
+{
+  if(G->m[0] == NULL)
+  {
+    PrintS("//** the result may be WRONG, i.e. 0!!\n");
+    return 0;
+  }
+
+  BOOLEAN nError =  Overflow_Error;
+  Overflow_Error = FALSE;
+
+  int i, nG = IDELEMS(G);
+  poly mi, gi;
+
+  for(i=nG-1; i>=0; i--)
+  {
+    mi = MpolyInitialForm(G->m[i], iv);
+    gi = G->m[i];
+
+    if(mi == NULL)
+    {
+      pDelete(&mi);
+      if(Overflow_Error == FALSE)
+      {
+        Overflow_Error = nError;
+      }
+      return 0;
+    }
+    if(!pLmEqual(mi, gi))
+    {
+      pDelete(&mi);
+      if(Overflow_Error == FALSE)
+      {
+        Overflow_Error = nError;
+      }
+      return 0;
+    }
+    pDelete(&mi);
+  }
+
+  if(Overflow_Error == FALSE)
+  {
+    Overflow_Error = nError;
+  }
+  return 1;
+}
+
+/***************************************************
+ * compute a least common multiple of two integers *
+ ***************************************************/
+static inline long Mlcm(long &i1, long &i2)
+{
+  long temp = gcd(i1, i2);
+  return ((i1 / temp)* i2);
+}
+
+
+/***************************************************
+ * return  the dot product of two intvecs a and b  *
+ ***************************************************/
+static inline long  MivDotProduct(intvec* a, intvec* b)
+{
+  assume( a->length() ==  b->length());
+  int i, n = a->length();
+  long result = 0;
+
+  for(i=n-1; i>=0; i--)
+    {
+    result += (*a)[i] * (*b)[i];
+    }
+  return result;
+}
+
+/*****************************************************
+ * Substract two given intvecs componentwise         *
+ *****************************************************/
+static intvec* MivSub(intvec* a, intvec* b)
+{
+  assume( a->length() ==  b->length());
+  int i, n = a->length();
+  intvec* result = new intvec(n);
+
+  for(i=n-1; i>=0; i--)
+  {
+    (*result)[i] = (*a)[i] - (*b)[i];
+  }
+  return result;
+}
+
+/*****************************************************
+ * return the "intvec" lead exponent of a polynomial *
+ *****************************************************/
+static intvec* MExpPol(poly f)
+{
+  int i, nR = currRing->N;
+  intvec* result = new intvec(nR);
+
+  for(i=nR-1; i>=0; i--)
+  {
+    (*result)[i] = pGetExp(f,i+1);
+  }
+  return result;
+}
+
+/*****************************************************
+ * Compare two given intvecs and return 1, if they   *
+ * are the same, otherwise 0                         *
+ *****************************************************/
+int MivSame(intvec* u , intvec* v)
+{
+  assume(u->length() == v->length());
+
+  int i, niv = u->length();
+
+  for (i=0; i<niv; i++)
+  {
+    if ((*u)[i] != (*v)[i])
+    {
+      return 0;
+    }
+  }
+  return 1;
+}
+
+/******************************************************
+ * Compare 3 given intvecs and return 0, if the first *
+ * and the second are the same. Return 1, if the      *
+ * the second and the third are the same, otherwise 2 *
+ ******************************************************/
+int M3ivSame(intvec* temp, intvec* u , intvec* v)
+{
+  assume(temp->length() == u->length() && u->length() == v->length());
+
+  if((MivSame(temp, u)) == 1)
+  {
+    return 0;
+  }
+  if((MivSame(temp, v)) == 1)
+  {
+    return 1;
+  }
+  return 2;
+}
+
+/*****************************************************
+ * compute a Groebner basis of an ideal              *
+ *****************************************************/
+static ideal MstdCC(ideal G)
+{
+  BITSET save1,save2;
+  SI_SAVE_OPT(save1,save2);
+  si_opt_1|=(Sy_bit(OPT_REDTAIL)|Sy_bit(OPT_REDSB));
+  ideal G1 = kStd(G, NULL, testHomog, NULL);
+  SI_RESTORE_OPT(save1,save2);
+
+  idSkipZeroes(G1);
+  return G1;
+}
+
+/*****************************************************
+ * compute a Groebner basis of an homogeneous ideal  *
+ *****************************************************/
+static ideal MstdhomCC(ideal G)
+{
+  BITSET save1,save2;
+  SI_SAVE_OPT(save1,save2);
+  si_opt_1|=(Sy_bit(OPT_REDTAIL)|Sy_bit(OPT_REDSB));
+  ideal G1 = kStd(G, NULL, isHomog, NULL);
+  SI_RESTORE_OPT(save1,save2);
+
+  idSkipZeroes(G1);
+  return G1;
+}
+
+
+/*****************************************************************************
+* create a weight matrix order as intvec of an extra weight vector (a(iv),lp)*
+******************************************************************************/
+intvec* MivMatrixOrder(intvec* iv)
+{
+  int i, nR = iv->length();
+
+  intvec* ivm = new intvec(nR*nR);
+
+  for(i=0; i<nR; i++)
+  {
+    (*ivm)[i] = (*iv)[i];
+  }
+  for(i=1; i<nR; i++)
+  {
+    (*ivm)[i*nR+i-1] = 1;
+  }
+  return ivm;
+}
+
+/*****************************************************************************
+* create a weight matrix order as intvec of an extra weight vector (a(iv),lp)*
+******************************************************************************/
+intvec* MivMatrixOrderRefine(intvec* iv, intvec* iw)
+{
+  assume(iv->length() == iw->length());
+  int i, nR = iv->length();
+
+  intvec* ivm = new intvec(nR*nR);
+
+  for(i=0; i<nR; i++)
+  {
+    (*ivm)[i] = (*iv)[i];
+    (*ivm)[i+nR] = (*iw)[i];
+  }
+  for(i=2; i<nR; i++)
+  {
+    (*ivm)[i*nR+i-2] = 1;
+  }
+  return ivm;
+}
+
+/*******************************
+ * return intvec = (1, ..., 1) *
+ *******************************/
+intvec* Mivdp(int nR)
+{
+  int i;
+  intvec* ivm = new intvec(nR);
+
+  for(i=nR-1; i>=0; i--)
+  {
+    (*ivm)[i] = 1;
+  }
+  return ivm;
+}
+
+/**********************************
+ * return intvvec = (1,0, ..., 0) *
+ **********************************/
+intvec* Mivlp(int nR)
+{
+  intvec* ivm = new intvec(nR);
+  (*ivm)[0] = 1;
+
+  return ivm;
+}
+
+//unused
+/*****************************************************************************
+ * print the max total degree and the max coefficient of G                   *
+ *****************************************************************************/
+#if 0
+static void checkComplexity(ideal G, char* cG)
+{
+  int nV = currRing->N;
+  int nG = IDELEMS(G);
+  intvec* ivUnit = Mivdp(nV);
+  int i, tmpdeg, maxdeg=0;
+  number tmpcoeff , maxcoeff=currRing->cf->nNULL;
+  poly p;
+  for(i=nG-1; i>=0; i--)
+  {
+    tmpdeg = MwalkWeightDegree(G->m[i], ivUnit);
+    if(tmpdeg > maxdeg )
+    {
+      maxdeg = tmpdeg;
+    }
+  }
+
+  for(i=nG-1; i>=0; i--)
+  {
+    p = pCopy(G->m[i]);
+    while(p != NULL)
+    {
+      //tmpcoeff = pGetCoeff(pHead(p));
+      tmpcoeff = pGetCoeff(p);
+      if(nGreater(tmpcoeff,maxcoeff))
+      {
+         maxcoeff = nCopy(tmpcoeff);
+      }
+      pIter(p);
+    }
+    pDelete(&p);
+  }
+  p = pNSet(maxcoeff);
+  char* pStr = pString(p);
+  delete ivUnit;
+  Print("// max total degree of %s = %d\n",cG, maxdeg);
+  Print("// max coefficient of %s  = %s", cG, pStr);//ing(p));
+  Print(" which consists of %d digits", (int)strlen(pStr));
+  PrintLn();
+}
+#endif
+
+/*****************************************************************************
+* If target_ord = intmat(A1, ..., An) then calculate the perturbation        *
+* vectors                                                                    *
+*   tau_p_dep = inveps^(p_deg-1)*A1 + inveps^(p_deg-2)*A2 +... + A_p_deg     *
+* where                                                                      *
+*      inveps > totaldegree(G)*(max(A2)+...+max(A_p_deg))                    *
+* intmat target_ord is an integer order matrix of the monomial ordering of   *
+* basering.                                                                  *
+* This programm computes a perturbated vector with a p_deg perturbation      *
+* degree which smaller than the numbers of variables                         *
+******************************************************************************/
+intvec* MPertVectors(ideal G, intvec* ivtarget, int pdeg)
+{
+  // ivtarget is a matrix order of a degree reverse lex. order
+  int nV = currRing->N;
+  //assume(pdeg <= nV && pdeg >= 0);
+
+  int i, j, nG = IDELEMS(G);
+  intvec* v_null =  new intvec(nV);
+
+
+  // Check that the perturbed degree is valid
+  if(pdeg > nV || pdeg <= 0)
+  {
+    WerrorS("//** The perturbed degree is wrong!!");
+    return v_null;
+  }
+  delete v_null;
+
+  if(pdeg == 1)
+  {
+    return ivtarget;
+  }
+  mpz_t *pert_vector = (mpz_t*)omAlloc(nV*sizeof(mpz_t));
+  //mpz_t *pert_vector1 = (mpz_t*)omAlloc(nV*sizeof(mpz_t));
+
+  for(i=0; i<nV; i++)
+  {
+    mpz_init_set_si(pert_vector[i], (*ivtarget)[i]);
+   // mpz_init_set_si(pert_vector1[i], (*ivtarget)[i]);
+  }
+  // Calculate max1 = Max(A2)+Max(A3)+...+Max(Apdeg),
+  // where the Ai are the i-te rows of the matrix target_ord.
+  int ntemp, maxAi, maxA=0;
+  for(i=1; i<pdeg; i++)
+  {
+    maxAi = (*ivtarget)[i*nV];
+    if(maxAi<0)
+    {
+      maxAi = -maxAi;
+    }
+    for(j=i*nV+1; j<(i+1)*nV; j++)
+    {
+      ntemp = (*ivtarget)[j];
+      if(ntemp < 0)
+      {
+        ntemp = -ntemp;
+      }
+      if(ntemp > maxAi)
+      {
+        maxAi = ntemp;
+      }
+    }
+    maxA += maxAi;
+  }
+
+  // Calculate inveps = 1/eps, where 1/eps > totaldeg(p)*max1 for all p in G.
+
+  intvec* ivUnit = Mivdp(nV);
+
+  mpz_t tot_deg; mpz_init(tot_deg);
+  mpz_t maxdeg; mpz_init(maxdeg);
+  mpz_t inveps; mpz_init(inveps);
+
+
+  for(i=nG-1; i>=0; i--)
+  {
+     mpz_set_ui(maxdeg, MwalkWeightDegree(G->m[i], ivUnit));
+     if (mpz_cmp(maxdeg,  tot_deg) > 0 )
+     {
+       mpz_set(tot_deg, maxdeg);
+     }
+  }
+
+  delete ivUnit;
+  mpz_mul_ui(inveps, tot_deg, maxA);
+  mpz_add_ui(inveps, inveps, 1);
+
+
+  // takes  "small" inveps
+#ifdef INVEPS_SMALL_IN_MPERTVECTOR
+  if(mpz_cmp_ui(inveps, pdeg)>0 && pdeg > 3)
+  {
+    //  Print("\n// choose the\"small\" inverse epsilon := %d / %d = ", mpz_get_si(inveps), pdeg);
+    mpz_fdiv_q_ui(inveps, inveps, pdeg);
+    // mpz_out_str(stdout, 10, inveps);
+  }
+#else
+  // PrintS("\n// the \"big\" inverse epsilon: ");
+  mpz_out_str(stdout, 10, inveps);
+#endif
+
+  // pert(A1) = inveps^(pdeg-1)*A1 + inveps^(pdeg-2)*A2+...+A_pdeg,
+  // pert_vector := A1
+  for( i=1; i < pdeg; i++ )
+  {
+    for(j=0; j<nV; j++)
+    {
+      mpz_mul(pert_vector[j], pert_vector[j], inveps);
+      if((*ivtarget)[i*nV+j]<0)
+      {
+        mpz_sub_ui(pert_vector[j], pert_vector[j],-(*ivtarget)[i*nV+j]);
+      }
+      else
+      {
+        mpz_add_ui(pert_vector[j], pert_vector[j],(*ivtarget)[i*nV+j]);
+      }
+    }
+  }
+  mpz_t ztemp;
+  mpz_init(ztemp);
+  mpz_set(ztemp, pert_vector[0]);
+  for(i=1; i<nV; i++)
+  {
+    mpz_gcd(ztemp, ztemp, pert_vector[i]);
+    if(mpz_cmp_si(ztemp, 1)  == 0)
+    {
+      break;
+    }
+  }
+  if(mpz_cmp_si(ztemp, 1) != 0)
+  {
+    for(i=0; i<nV; i++)
+    {
+      mpz_divexact(pert_vector[i], pert_vector[i], ztemp);
+    }
+  }
+
+  intvec *pert_vector1= new intvec(nV);
+  j = 0;
+  for(i=0; i<nV; i++)
+  {
+    (* pert_vector1)[i] = mpz_get_si(pert_vector[i]);
+    (* pert_vector1)[i] = 0.1*(* pert_vector1)[i];
+    (* pert_vector1)[i] = floor((* pert_vector1)[i] + 0.5);
+    if((* pert_vector1)[i] == 0)
+    {
+      j++;
+    }
+  }
+  if(j > nV - 1)
+  {
+    // Print("\n//  MPertVectors: geaenderter vector gleich Null! \n");
+    delete pert_vector1;
+    goto CHECK_OVERFLOW;
+  }
+
+// check that the perturbed weight vector lies in the Groebner cone
+  if(test_w_in_ConeCC(G,pert_vector1) != 0)
+  {
+    // Print("\n//  MPertVectors: geaenderter vector liegt in Groebnerkegel! \n");
+    for(i=0; i<nV; i++)
+    {
+      mpz_set_si(pert_vector[i], (*pert_vector1)[i]);
+    }
+  }
+  else
+  {
+    //Print("\n// MpertVectors: geaenderter vector liegt nicht in Groebnerkegel! \n");
+  }
+  delete pert_vector1;
+
+  CHECK_OVERFLOW:
+  intvec* result = new intvec(nV);
+
+  /* 2147483647 is max. integer representation in SINGULAR */
+  mpz_t sing_int;
+  mpz_init_set_ui(sing_int,  2147483647);
+
+  int ntrue=0;
+  for(i=0; i<nV; i++)
+  {
+    (*result)[i] = mpz_get_si(pert_vector[i]);
+    if(mpz_cmp(pert_vector[i], sing_int)>=0)
+    {
+      ntrue++;
+      if(Overflow_Error == FALSE)
+      {
+        Overflow_Error = TRUE;
+        PrintS("\n// ** OVERFLOW in \"MPertvectors\": ");
+        mpz_out_str( stdout, 10, pert_vector[i]);
+        PrintS(" is greater than 2147483647 (max. integer representation)");
+        Print("\n//  So vector[%d] := %d is wrong!!", i+1, (*result)[i]);
+      }
+    }
+  }
+
+  if(Overflow_Error == TRUE)
+  {
+    ivString(result, "pert_vector");
+    Print("\n// %d element(s) of it is overflow!!", ntrue);
+  }
+
+  mpz_clear(ztemp);
+  mpz_clear(sing_int);
+  omFree(pert_vector);
+  //omFree(pert_vector1);
+  mpz_clear(tot_deg);
+  mpz_clear(maxdeg);
+  mpz_clear(inveps);
+
+  rComplete(currRing);
+  for(j=0; j<IDELEMS(G); j++)
+  {
+    poly p=G->m[j];
+    while(p!=NULL)
+    {
+      p_Setm(p,currRing); pIter(p);
+    }
+  }
+  return result;
+}
+
+/*****************************************************************************
+ * The following procedure returns                                           *
+ *     Pert(A1) = 1/eps^(pdeg-1)*A_1 + 1/eps^(pdeg-2)*A_2+...+A_pdeg,        *
+ * where the A_i are the i-th rows of the matrix target_ord and              *
+ *     1/eps > deg(p)*(max(A_2) + max(A_3)+...+max(A_pdeg))                  *
+ *****************************************************************************/
+intvec* MPertVectorslp(ideal G, intvec* ivtarget, int pdeg)
+{
+  // ivtarget is a matrix order of the lex. order
+  int nV = currRing->N;
+  //assume(pdeg <= nV && pdeg >= 0);
+
+  int i, j, nG = IDELEMS(G);
+  intvec* pert_vector =  new intvec(nV);
+
+  //Checking that the perturbated degree is valid
+  if(pdeg > nV || pdeg <= 0)
+  {
+    WerrorS("//** The perturbed degree is wrong!!");
+    return pert_vector;
+  }
+  for(i=0; i<nV; i++)
+  {
+    (*pert_vector)[i]=(*ivtarget)[i];
+  }
+  if(pdeg == 1)
+  {
+    return pert_vector;
+  }
+  // Calculate max1 = Max(A2)+Max(A3)+...+Max(Apdeg),
+  // where the Ai are the i-te rows of the matrix target_ord.
+  int ntemp, maxAi, maxA=0;
+  for(i=1; i<pdeg; i++)
+  {
+    maxAi = (*ivtarget)[i*nV];
+    for(j=i*nV+1; j<(i+1)*nV; j++)
+    {
+      ntemp = (*ivtarget)[j];
+      if(ntemp > maxAi)
+      {
+        maxAi = ntemp;
+      }
+    }
+    maxA += maxAi;
+  }
+
+  // Calculate inveps := 1/eps, where 1/eps > deg(p)*max1 for all p in G.
+  int inveps, tot_deg = 0, maxdeg;
+
+  intvec* ivUnit = Mivdp(nV);//19.02
+  for(i=nG-1; i>=0; i--)
+  {
+    // maxdeg = pTotaldegree(G->m[i], currRing); //it's wrong for ex1,2,rose
+    maxdeg = MwalkWeightDegree(G->m[i], ivUnit);
+    if (maxdeg > tot_deg )
+    {
+      tot_deg = maxdeg;
+    }
+  }
+  delete ivUnit;
+
+  inveps = (tot_deg * maxA) + 1;
+
+#ifdef INVEPS_SMALL_IN_FRACTAL
+  //  Print("\n// choose the\"small\" inverse epsilon := %d / %d = ", inveps, pdeg);
+  if(inveps > pdeg && pdeg > 3)
+  {
+    inveps = inveps / pdeg;
+  }
+  // Print(" %d", inveps);
+#else
+  PrintS("\n// the \"big\" inverse epsilon %d", inveps);
+#endif
+
+  // Pert(A1) = inveps^(pdeg-1)*A1 + inveps^(pdeg-2)*A2+...+A_pdeg
+  for ( i=1; i < pdeg; i++ )
+  {
+    for(j=0; j<nV; j++)
+    {
+      (*pert_vector)[j] = inveps*((*pert_vector)[j]) + (*ivtarget)[i*nV+j];
+    }
+  }
+
+  int temp = (*pert_vector)[0];
+  for(i=1; i<nV; i++)
+  {
+    temp = gcd(temp, (*pert_vector)[i]);
+    if(temp == 1)
+    {
+      break;
+    }
+  }
+  if(temp != 1)
+  {
+    for(i=0; i<nV; i++)
+    {
+      (*pert_vector)[i] = (*pert_vector)[i] / temp;
+    }
+  }
+
+  intvec* result = pert_vector;
+  delete pert_vector;
+  return result;
+}
+
+/*****************************************************************************
+ * define a lexicographic order matrix as intvec                             *
+ *****************************************************************************/
+intvec* MivMatrixOrderlp(int nV)
+{
+  int i;
+  intvec* ivM = new intvec(nV*nV);
+
+  for(i=0; i<nV; i++)
+  {
+    (*ivM)[i*nV + i] = 1;
+  }
+  return(ivM);
+}
+
+
+/*****************************************************************************
+ * define a reverse lexicographic order (dp) matrix as intvec                *
+ *****************************************************************************/
+intvec* MivMatrixOrderdp(int nV)
+{
+  int i;
+  intvec* ivM = new intvec(nV*nV);
+
+  for(i=0; i<nV; i++)
+  {
+    (*ivM)[i] = 1;
+  }
+  for(i=1; i<nV; i++)
+  {
+    (*ivM)[(i+1)*nV - i] = -1;
+  }
+  return(ivM);
+}
+
+/*****************************************************************************
+ * creates an intvec of the monomial order Wp(ivstart)                       *
+ *****************************************************************************/
+intvec* MivWeightOrderlp(intvec* ivstart)
+{
+  int i;
+  int nV = ivstart->length();
+  intvec* ivM = new intvec(nV*nV);
+
+  for(i=0; i<nV; i++)
+  {
+    (*ivM)[i] = (*ivstart)[i];
+  }
+  for(i=1; i<nV; i++)
+  {
+    (*ivM)[i*nV + i-1] = 1;
+  }
+  return(ivM);
+}
+
+/*****************************************************************************
+ * creates an intvec of the monomial order dp(ivstart)                       *
+ *****************************************************************************/
+intvec* MivWeightOrderdp(intvec* ivstart)
+{
+  int i;
+  int nV = ivstart->length();
+  intvec* ivM = new intvec(nV*nV);
+
+  for(i=0; i<nV; i++)
+  {
+    (*ivM)[i] = (*ivstart)[i];
+  }
+  for(i=0; i<nV; i++)
+  {
+    (*ivM)[nV+i] = 1;
+  }
+  for(i=2; i<nV; i++)
+  {
+    (*ivM)[(i+1)*nV - i] = -1;
+  }
+  return(ivM);
+}
+
+//unused
+#if 0
+static intvec* MatrixOrderdp(int nV)
+{
+  int i;
+  intvec* ivM = new intvec(nV*nV);
+
+  for(i=0; i<nV; i++)
+  {
+    (*ivM)[i] = 1;
+  }
+  for(i=1; i<nV; i++)
+  {
+    (*ivM)[(i+1)*nV - i] = -1;
+  }
+  return(ivM);
+}
+#endif
+
+intvec* MivUnit(int nV)
+{
+  int i;
+  intvec* ivM = new intvec(nV);
+  for(i=nV-1; i>=0; i--)
+  {
+    (*ivM)[i] = 1;
+  }
+  return(ivM);
+}
+
+
+/************************************************************************
+*  compute a perturbed weight vector of a matrix order w.r.t. an ideal  *
+*************************************************************************/
+int Xnlev;
+intvec* Mfpertvector(ideal G, intvec* ivtarget)
+{
+  int i, j, nG = IDELEMS(G);
+  int nV = currRing->N;
+  int niv = nV*nV;
+
+
+  // Calculate maxA = Max(A2) + Max(A3) + ... + Max(AnV),
+  // where the Ai are the i-te rows of the matrix 'targer_ord'.
+  int ntemp, maxAi, maxA=0;
+  for(i=1; i<nV; i++)
+  {
+    maxAi = (*ivtarget)[i*nV];
+    if(maxAi<0)
+    {
+      maxAi = -maxAi;
+    }
+    for(j=i*nV+1; j<(i+1)*nV; j++)
+    {
+      ntemp = (*ivtarget)[j];
+      if(ntemp < 0)
+      {
+        ntemp = -ntemp;
+      }
+      if(ntemp > maxAi)
+      {
+        maxAi = ntemp;
+      }
+    }
+    maxA = maxA + maxAi;
+  }
+  intvec* ivUnit = Mivdp(nV);
+
+  // Calculate inveps = 1/eps, where 1/eps > deg(p)*maxA for all p in G.
+  mpz_t tot_deg; mpz_init(tot_deg);
+  mpz_t maxdeg; mpz_init(maxdeg);
+  mpz_t inveps; mpz_init(inveps);
+
+
+  for(i=nG-1; i>=0; i--)
+  {
+    mpz_set_ui(maxdeg, MwalkWeightDegree(G->m[i], ivUnit));
+    if (mpz_cmp(maxdeg,  tot_deg) > 0 )
+    {
+      mpz_set(tot_deg, maxdeg);
+    }
+  }
+
+  delete ivUnit;
+  //inveps = (tot_deg * maxA) + 1;
+  mpz_mul_ui(inveps, tot_deg, maxA);
+  mpz_add_ui(inveps, inveps, 1);
+
+  // takes  "small" inveps
+#ifdef INVEPS_SMALL_IN_FRACTAL
+  if(mpz_cmp_ui(inveps, nV)>0 && nV > 3)
+  {
+    mpz_cdiv_q_ui(inveps, inveps, nV);
+  }
+  //PrintS("\n// choose the \"small\" inverse epsilon!");
+#endif
+
+  // PrintLn();  mpz_out_str(stdout, 10, inveps);
+
+  // Calculate the perturbed target orders:
+  mpz_t *ivtemp=(mpz_t *)omAlloc(nV*sizeof(mpz_t));
+  mpz_t *pert_vector=(mpz_t *)omAlloc(niv*sizeof(mpz_t));
+
+  for(i=0; i < nV; i++)
+  {
+    mpz_init_set_si(ivtemp[i], (*ivtarget)[i]);
+    mpz_init_set_si(pert_vector[i], (*ivtarget)[i]);
+  }
+
+  mpz_t ztmp; mpz_init(ztmp);
+  // BOOLEAN isneg = FALSE;
+
+  for(i=1; i<nV; i++)
+  {
+    for(j=0; j<nV; j++)
+    {
+      mpz_mul(ztmp, inveps, ivtemp[j]);
+      if((*ivtarget)[i*nV+j]<0)
+      {
+        mpz_sub_ui(ivtemp[j], ztmp, -(*ivtarget)[i*nV+j]);
+      }
+      else
+      {
+        mpz_add_ui(ivtemp[j], ztmp,(*ivtarget)[i*nV+j]);
+      }
+    }
+
+    for(j=0; j<nV; j++)
+      {
+      mpz_init_set(pert_vector[i*nV+j],ivtemp[j]);
+      }
+  }
+
+  /* 2147483647 is max. integer representation in SINGULAR */
+  mpz_t sing_int;
+  mpz_init_set_ui(sing_int,  2147483647);
+
+  intvec* result = new intvec(niv);
+  intvec* result1 = new intvec(niv);
+  BOOLEAN nflow = FALSE;
+
+  // computes gcd
+  mpz_set(ztmp, pert_vector[0]);
+  for(i=0; i<niv; i++)
+  {
+    mpz_gcd(ztmp, ztmp, pert_vector[i]);
+    if(mpz_cmp_si(ztmp, 1)==0)
+    {
+      break;
+    }
+  }
+
+  for(i=0; i<niv; i++)
+  {
+    mpz_divexact(pert_vector[i], pert_vector[i], ztmp);
+    (* result)[i] = mpz_get_si(pert_vector[i]);
+  }
+
+  j = 0;
+  for(i=0; i<nV; i++)
+  {
+    (* result1)[i] = mpz_get_si(pert_vector[i]);
+    (* result1)[i] = 0.1*(* result1)[i];
+    (* result1)[i] = floor((* result1)[i] + 0.5);
+    if((* result1)[i] == 0)
+    {
+      j++;
+    }
+  }
+  if(j > nV - 1)
+  {
+    // Print("\n//  MfPertwalk: geaenderter vector gleich Null! \n");
+    delete result1;
+    goto CHECK_OVERFLOW;
+  }
+
+// check that the perturbed weight vector lies in the Groebner cone
+  if(test_w_in_ConeCC(G,result1) != 0)
+  {
+    // Print("\n//  MfPertwalk: geaenderter vector liegt in Groebnerkegel! \n");
+    delete result;
+    result = result1;
+    for(i=0; i<nV; i++)
+    {
+      mpz_set_si(pert_vector[i], (*result1)[i]);
+    }
+  }
+  else
+  {
+    delete result1;
+    // Print("\n// Mfpertwalk: geaenderter vector liegt nicht in Groebnerkegel! \n");
+  }
+
+  CHECK_OVERFLOW:
+
+  for(i=0; i<niv; i++)
+  {
+    if(mpz_cmp(pert_vector[i], sing_int)>0)
+    {
+      if(nflow == FALSE)
+      {
+        Xnlev = i / nV;
+        nflow = TRUE;
+        Overflow_Error = TRUE;
+        Print("\n// Xlev = %d and the %d-th element is", Xnlev,  i+1);
+        PrintS("\n// ** OVERFLOW in \"Mfpertvector\": ");
+        mpz_out_str( stdout, 10, pert_vector[i]);
+        PrintS(" is greater than 2147483647 (max. integer representation)");
+        Print("\n//  So vector[%d] := %d is wrong!!", i+1, (*result)[i]);
+      }
+    }
+  }
+  if(Overflow_Error == TRUE)
+  {
+    ivString(result, "new_vector");
+  }
+  omFree(pert_vector);
+  omFree(ivtemp);
+  mpz_clear(ztmp);
+  mpz_clear(tot_deg);
+  mpz_clear(maxdeg);
+  mpz_clear(inveps);
+  mpz_clear(sing_int);
+
+  rComplete(currRing);
+  for(j=0; j<IDELEMS(G); j++)
+  {
+    poly p=G->m[j];
+    while(p!=NULL)
+    {
+      p_Setm(p,currRing); pIter(p);
+    }
+  }
+  return result;
+}
+
+/****************************************************************
+ * Multiplication of two ideals element by element              *
+ * i.e. Let be A := (a_i) and B := (b_i), return C := (a_i*b_i) *
+ *  destroy A, keeps B                                          *
+ ****************************************************************/
+static ideal MidMult(ideal A, ideal B)
+{
+  int mA = IDELEMS(A), mB = IDELEMS(B);
+
+  if(A==NULL || B==NULL)
+  {
+    return NULL;
+  }
+  if(mB < mA)
+  {
+    mA = mB;
+  }
+  ideal result = idInit(mA, 1);
+
+  int i, k=0;
+  for(i=0; i<mA; i++)
+    {
+      result->m[k] = pMult(A->m[i], pCopy(B->m[i]));
+      A->m[i]=NULL;
+      if (result->m[k]!=NULL)
+      {
+        k++;
+      }
+    }
+
+  idDelete(&A);
+  idSkipZeroes(result);
+  return result;
+}
+
+/*********************************************************************
+ * G is a red. Groebner basis w.r.t. <_1                             *
+ * Gomega is an initial form ideal of <G> w.r.t. a weight vector w   *
+ * M is a subideal of <Gomega> and M selft is a red. Groebner basis  *
+ *    of the ideal <Gomega> w.r.t. <_w                               *
+ * Let m_i = h1.gw1 + ... + hs.gws for each m_i in M; gwi in Gomega  *
+ * return F with n(F) = n(M) and f_i = h1.g1 + ... + hs.gs for each i*
+ ********************************************************************/
+static ideal MLifttwoIdeal(ideal Gw, ideal M, ideal G)
+{
+  ideal Mtmp = idLift(Gw, M, NULL, FALSE, TRUE, TRUE, NULL);
+
+  // If Gw is a GB, then isSB = TRUE, otherwise FALSE
+  // So, it is better, if one tests whether Gw is a GB
+  // in ideals.cc:
+  // idLift (ideal mod, ideal submod,ideal * rest, BOOLEAN goodShape,
+  //           BOOLEAN isSB,BOOLEAN divide,matrix * unit)
+
+  // Let be Mtmp = {m1,...,ms}, where mi=sum hij.in_gj, for all i=1,...,s
+  // We compute F = {f1,...,fs}, where fi=sum hij.gj
+  int i, j, nM = IDELEMS(Mtmp);
+  ideal idpol, idLG;
+  ideal F = idInit(nM, 1);
+
+  for(i=0; i<nM; i++)
+  {
+     idpol = idVec2Ideal(Mtmp->m[i]);
+     idLG = MidMult(idpol, G);
+     idpol = NULL;
+     F->m[i] = NULL;
+     for(j=IDELEMS(idLG)-1; j>=0; j--)
+     {
+       F->m[i] = pAdd(F->m[i], idLG->m[j]);
+       idLG->m[j]=NULL;
+     }
+     idDelete(&idLG);
+  }
+  idDelete(&Mtmp);
+  return F;
+}
+
+//unused
+#if 0
+static void checkidealCC(ideal G, char* Ch)
+{
+  int i,nmon=0,ntmp;
+  int nG = IDELEMS(G);
+  int n = nG-1;
+  Print("\n//** Ideal %s besteht aus %d Polynomen mit ", Ch, nG);
+
+  for(i=0; i<nG; i++)
+  {
+    ntmp =  pLength(G->m[i]);
+    nmon += ntmp;
+
+    if(i != n)
+    {
+      Print("%d, ", ntmp);
+    }
+    else
+    {
+      Print(" bzw. %d ", ntmp);
+    }
+  }
+  PrintS(" Monomen.\n");
+  Print("//** %s besitzt %d Monome.", Ch, nmon);
+  PrintLn();
+}
+#endif
+
+//unused
+#if 0
+static void HeadidString(ideal L, char* st)
+{
+  int i, nL = IDELEMS(L)-1;
+
+  Print("//  The head terms of the ideal %s = ", st);
+  for(i=0; i<nL; i++)
+  {
+    Print(" %s, ", pString(pHead(L->m[i])));
+  }
+  Print(" %s;\n", pString(pHead(L->m[nL])));
+}
+#endif
+
+static inline int MivComp(intvec* iva, intvec* ivb)
+{
+  assume(iva->length() == ivb->length());
+  int i;
+  for(i=iva->length()-1; i>=0; i--)
+  {
+    if((*iva)[i] - (*ivb)[i] != 0)
+    {
+      return 0;
+    }
+  }
+  return 1;
+}
+
+/**********************************************
+ * Look for the smallest absolut value in vec *
+ **********************************************/
+static int MivAbsMax(intvec* vec)
+{
+  int i,k;
+  if((*vec)[0] < 0)
+  {
+    k = -(*vec)[0];
+  }
+  else
+  {
+    k = (*vec)[0];
+  }
+  for(i=1; i < (vec->length()); i++)
+  {
+    if((*vec)[i] < 0)
+    {
+      if(-(*vec)[i] > k)
+      {
+        k = -(*vec)[i];
+      }
+    }
+    else
+    {
+      if((*vec)[i] > k)
+      {
+        k = (*vec)[i];
+      }
+    }
+  }
+  return k;
+}
+
+/**********************************************************************
+ * Compute a next weight vector between curr_weight and target_weight *
+ * with respect to an ideal <G>.                                      *
+**********************************************************************/
+static intvec* MwalkNextWeightCC(intvec* curr_weight, intvec* target_weight,
+                                 ideal G)
+{
+  BOOLEAN nError = Overflow_Error;
+  Overflow_Error = FALSE;
+
+  assume(currRing != NULL && curr_weight != NULL &&
+         target_weight != NULL && G != NULL);
+
+  int nRing = currRing->N;
+  int checkRed, j, kkk, nG = IDELEMS(G);
+  intvec* ivtemp;
+
+  mpz_t t_zaehler, t_nenner;
+  mpz_init(t_zaehler);
+  mpz_init(t_nenner);
+
+  mpz_t s_zaehler, s_nenner, temp, MwWd;
+  mpz_init(s_zaehler);
+  mpz_init(s_nenner);
+  mpz_init(temp);
+  mpz_init(MwWd);
+
+  mpz_t sing_int;
+  mpz_init(sing_int);
+  mpz_set_si(sing_int,  2147483647);
+
+  mpz_t sing_int_half;
+  mpz_init(sing_int_half);
+  mpz_set_si(sing_int_half,  3*(1073741824/2));
+
+  mpz_t deg_w0_p1, deg_d0_p1;
+  mpz_init(deg_w0_p1);
+  mpz_init(deg_d0_p1);
+
+  mpz_t sztn, sntz;
+  mpz_init(sztn);
+  mpz_init(sntz);
+
+  mpz_t t_null;
+  mpz_init(t_null);
+
+  mpz_t ggt;
+  mpz_init(ggt);
+
+  mpz_t dcw;
+  mpz_init(dcw);
+
+  //int tn0, tn1, tz1, ncmp, gcd_tmp, ntmp;
+  int gcd_tmp;
+  intvec* diff_weight = MivSub(target_weight, curr_weight);
+
+  intvec* diff_weight1 = MivSub(target_weight, curr_weight);
+  poly g;
+  //poly g, gw;
+  for (j=0; j<nG; j++)
+  {
+    g = G->m[j];
+    if (g != NULL)
+    {
+      ivtemp = MExpPol(g);
+      mpz_set_si(deg_w0_p1, MivDotProduct(ivtemp, curr_weight));
+      mpz_set_si(deg_d0_p1, MivDotProduct(ivtemp, diff_weight));
+      delete ivtemp;
+
+      pIter(g);
+      while (g != NULL)
+      {
+        ivtemp = MExpPol(g);
+        mpz_set_si(MwWd, MivDotProduct(ivtemp, curr_weight));
+        mpz_sub(s_zaehler, deg_w0_p1, MwWd);
+
+        if(mpz_cmp(s_zaehler, t_null) != 0)
+        {
+          mpz_set_si(MwWd, MivDotProduct(ivtemp, diff_weight));
+          mpz_sub(s_nenner, MwWd, deg_d0_p1);
+
+          // check for 0 < s <= 1
+          if( (mpz_cmp(s_zaehler,t_null) > 0 &&
+               mpz_cmp(s_nenner, s_zaehler)>=0) ||
+              (mpz_cmp(s_zaehler, t_null) < 0 &&
+               mpz_cmp(s_nenner, s_zaehler)<=0))
+          {
+            // make both positive
+            if (mpz_cmp(s_zaehler, t_null) < 0)
+            {
+              mpz_neg(s_zaehler, s_zaehler);
+              mpz_neg(s_nenner, s_nenner);
+            }
+
+            //compute a simple fraction of s
+            cancel(s_zaehler, s_nenner);
+
+            if(mpz_cmp(t_nenner, t_null) != 0)
+            {
+              mpz_mul(sztn, s_zaehler, t_nenner);
+              mpz_mul(sntz, s_nenner, t_zaehler);
+
+              if(mpz_cmp(sztn,sntz) < 0)
+              {
+                mpz_add(t_nenner, t_null, s_nenner);
+                mpz_add(t_zaehler,t_null, s_zaehler);
+              }
+            }
+            else
+            {
+              mpz_add(t_nenner, t_null, s_nenner);
+              mpz_add(t_zaehler,t_null, s_zaehler);
+            }
+          }
+        }
+        pIter(g);
+        delete ivtemp;
+      }
+    }
+  }
+//Print("\n// Alloc Size = %d \n", nRing*sizeof(mpz_t));
+  mpz_t *vec=(mpz_t*)omAlloc(nRing*sizeof(mpz_t));
+
+
+  // there is no 0<t<1 and define the next weight vector that is equal to the current weight vector
+  if(mpz_cmp(t_nenner, t_null) == 0)
+  {
+    #ifndef SING_NDEBUG
+    Print("\n//MwalkNextWeightCC: t_nenner ist Null!");
+    #endif
+    delete diff_weight;
+    diff_weight = ivCopy(curr_weight);//take memory
+    goto FINISH;
+  }
+
+  // define the target vector as the next weight vector, if t = 1
+  if(mpz_cmp_si(t_nenner, 1)==0 && mpz_cmp_si(t_zaehler,1)==0)
+  {
+    delete diff_weight;
+    diff_weight = ivCopy(target_weight); //this takes memory
+    goto FINISH;
+  }
+
+   checkRed = 0;
+
+  SIMPLIFY_GCD:
+
+  // simplify the vectors curr_weight and diff_weight (C-int)
+  gcd_tmp = (*curr_weight)[0];
+
+  for (j=1; j<nRing; j++)
+  {
+    gcd_tmp = gcd(gcd_tmp, (*curr_weight)[j]);
+    if(gcd_tmp == 1)
+    {
+      break;
+    }
+  }
+  if(gcd_tmp != 1)
+  {
+    for (j=0; j<nRing; j++)
+    {
+      gcd_tmp = gcd(gcd_tmp, (*diff_weight)[j]);
+      if(gcd_tmp == 1)
+      {
+        break;
+      }
+    }
+  }
+  if(gcd_tmp != 1)
+  {
+    for (j=0; j<nRing; j++)
+    {
+      (*curr_weight)[j] =  (*curr_weight)[j]/gcd_tmp;
+      (*diff_weight)[j] =  (*diff_weight)[j]/gcd_tmp;
+    }
+  }
+  if(checkRed > 0)
+  {
+    for (j=0; j<nRing; j++)
+    {
+      mpz_set_si(vec[j], (*diff_weight)[j]);
+    }
+    goto TEST_OVERFLOW;
+  }
+
+#ifdef  NEXT_VECTORS_CC
+  Print("\n// gcd of the weight vectors (current and target) = %d", gcd_tmp);
+  ivString(curr_weight, "new cw");
+  ivString(diff_weight, "new dw");
+
+  PrintS("\n// t_zaehler: ");  mpz_out_str( stdout, 10, t_zaehler);
+  PrintS(", t_nenner: ");  mpz_out_str( stdout, 10, t_nenner);
+#endif
+
+  //  BOOLEAN isdwpos;
+
+  // construct a new weight vector
+  for (j=0; j<nRing; j++)
+  {
+    mpz_set_si(dcw, (*curr_weight)[j]);
+    mpz_mul(s_nenner, t_nenner, dcw);
+
+    if( (*diff_weight)[j]>0)
+    {
+      mpz_mul_ui(s_zaehler, t_zaehler, (*diff_weight)[j]);
+    }
+    else
+    {
+      mpz_mul_ui(s_zaehler, t_zaehler, -(*diff_weight)[j]);
+      mpz_neg(s_zaehler, s_zaehler);
+    }
+    mpz_add(sntz, s_nenner, s_zaehler);
+    mpz_init_set(vec[j], sntz);
+
+#ifdef NEXT_VECTORS_CC
+    Print("\n//   j = %d ==> ", j);
+    PrintS("(");
+    mpz_out_str( stdout, 10, t_nenner);
+    Print(" * %d)", (*curr_weight)[j]);
+    Print(" + ("); mpz_out_str( stdout, 10, t_zaehler);
+    Print(" * %d) =  ",  (*diff_weight)[j]);
+    mpz_out_str( stdout, 10, s_nenner);
+    PrintS(" + ");
+    mpz_out_str( stdout, 10, s_zaehler);
+    PrintS(" = "); mpz_out_str( stdout, 10, sntz);
+    Print(" ==> vector[%d]: ", j); mpz_out_str(stdout, 10, vec[j]);
+#endif
+
+    if(j==0)
+    {
+      mpz_set(ggt, sntz);
+    }
+    else
+    {
+      if(mpz_cmp_si(ggt,1) != 0)
+      {
+        mpz_gcd(ggt, ggt, sntz);
+      }
+    }
+  }
+
+#ifdef  NEXT_VECTORS_CC
+  PrintS("\n// gcd of elements of the vector: ");
+  mpz_out_str( stdout, 10, ggt);
+#endif
+
+/**********************************************************************
+* construct a new weight vector and check whether vec[j] is overflow, *
+* i.e. vec[j] > 2^31.                                                 *
+* If vec[j] doesn't overflow, define a weight vector. Otherwise,      *
+* report that overflow appears. In the second case, test whether the  *
+* the correctness of the new vector plays an important role           *
+**********************************************************************/
+  kkk=0;
+  for(j=0; j<nRing; j++)
+    {
+    if(mpz_cmp(vec[j], sing_int_half) >= 0)
+      {
+      goto REDUCTION;
+      }
+    }
+  checkRed = 1;
+  for (j=0; j<nRing; j++)
+    {
+      (*diff_weight)[j] = mpz_get_si(vec[j]);
+    }
+  goto SIMPLIFY_GCD;
+
+  REDUCTION:
+  for (j=0; j<nRing; j++)
+  {
+    (*diff_weight)[j] = mpz_get_si(vec[j]);
+  }
+  while(MivAbsMax(diff_weight) >= 5)
+  {
+    for (j=0; j<nRing; j++)
+    {
+      if(mpz_cmp_si(ggt,1)==0)
+      {
+        (*diff_weight1)[j] = floor(0.1*(*diff_weight)[j] + 0.5);
+        // Print("\n//  vector[%d] = %d \n",j+1, (*diff_weight1)[j]);
+      }
+      else
+      {
+        mpz_divexact(vec[j], vec[j], ggt);
+        (*diff_weight1)[j] = floor(0.1*(*diff_weight)[j] + 0.5);
+        // Print("\n//  vector[%d] = %d \n",j+1, (*diff_weight1)[j]);
+      }
+/*
+      if((*diff_weight1)[j] == 0)
+      {
+        kkk = kkk + 1;
+      }
+*/
+    }
+
+
+/*
+    if(kkk > nRing - 1)
+    {
+      // diff_weight was reduced to zero
+      // Print("\n // MwalkNextWeightCC: geaenderter Vector gleich Null! \n");
+      goto TEST_OVERFLOW;
+    }
+*/
+
+    if(test_w_in_ConeCC(G,diff_weight1) != 0)
+    {
+      Print("\n// MwalkNextWeightCC: geaenderter vector liegt in Groebnerkegel! \n");
+      for (j=0; j<nRing; j++)
+      {
+        (*diff_weight)[j] = (*diff_weight1)[j];
+      }
+      if(MivAbsMax(diff_weight) < 5)
+      {
+        checkRed = 1;
+        goto SIMPLIFY_GCD;
+      }
+    }
+    else
+    {
+      // Print("\n// MwalkNextWeightCC: geaenderter vector liegt nicht in Groebnerkegel! \n");
+      break;
+    }
+  }
+
+ TEST_OVERFLOW:
+
+  for (j=0; j<nRing; j++)
+  {
+    if(mpz_cmp(vec[j], sing_int)>=0)
+    {
+      if(Overflow_Error == FALSE)
+      {
+        Overflow_Error = TRUE;
+        PrintS("\n// ** OVERFLOW in \"MwalkNextWeightCC\": ");
+        mpz_out_str( stdout, 10, vec[j]);
+        PrintS(" is greater than 2147483647 (max. integer representation)\n");
+        //Print("//  So vector[%d] := %d is wrong!!\n",j+1, vec[j]);// vec[j] is mpz_t
+      }
+    }
+  }
+
+ FINISH:
+   delete diff_weight1;
+   mpz_clear(t_zaehler);
+   mpz_clear(t_nenner);
+   mpz_clear(s_zaehler);
+   mpz_clear(s_nenner);
+   mpz_clear(sntz);
+   mpz_clear(sztn);
+   mpz_clear(temp);
+   mpz_clear(MwWd);
+   mpz_clear(deg_w0_p1);
+   mpz_clear(deg_d0_p1);
+   mpz_clear(ggt);
+   omFree(vec);
+   mpz_clear(sing_int_half);
+   mpz_clear(sing_int);
+   mpz_clear(dcw);
+   mpz_clear(t_null);
+
+
+
+  if(Overflow_Error == FALSE)
+  {
+    Overflow_Error = nError;
+  }
+ rComplete(currRing);
+  for(kkk=0; kkk<IDELEMS(G);kkk++)
+  {
+    poly p=G->m[kkk];
+    while(p!=NULL)
+    {
+      p_Setm(p,currRing);
+      pIter(p);
+    }
+  }
+return diff_weight;
+}
+
+/**********************************************************************
+* Compute an intermediate weight vector from iva to ivb w.r.t.        *
+* the reduced Groebner basis G.                                       *
+* Return NULL, if it is equal to iva or iva = avb.                    *
+**********************************************************************/
+intvec* MkInterRedNextWeight(intvec* iva, intvec* ivb, ideal G)
+{
+  intvec* tmp = new intvec(iva->length());
+  intvec* result;
+
+  if(G == NULL)
+  {
+    return tmp;
+  }
+  if(MivComp(iva, ivb) == 1)
+  {
+    return tmp;
+  }
+  result = MwalkNextWeightCC(iva, ivb, G);
+
+  if(MivComp(result, iva) == 1)
+  {
+    delete result;
+    return tmp;
+  }
+
+  delete tmp;
+  return result;
+}
+
+/**************************************************************
+ * define and execute a new ring which order is (a(vb),a(va),lp,C)  *
+ * ************************************************************/
+static void VMrHomogeneous(intvec* va, intvec* vb)
+{
+
+  if ((currRing->ppNoether)!=NULL)
+  {
+    pDelete(&(currRing->ppNoether));
+  }
+  if (((sLastPrinted.rtyp>BEGIN_RING) && (sLastPrinted.rtyp<END_RING)) ||
+      ((sLastPrinted.rtyp==LIST_CMD)&&(lRingDependend((lists)sLastPrinted.data))))
+  {
+    sLastPrinted.CleanUp();
+  }
+
+  ring r = (ring) omAlloc0Bin(sip_sring_bin);
+  int i, nv = currRing->N;
+
+  r->cf  = currRing->cf;
+  r->N   = currRing->N;
+  int nb = 4;
+
+
+  //names
+  char* Q; // In order to avoid the corrupted memory, do not change.
+  r->names = (char **) omAlloc0(nv * sizeof(char_ptr));
+  for(i=0; i<nv; i++)
+  {
+    Q = currRing->names[i];
+    r->names[i]  = omStrDup(Q);
+  }
+
+  //weights: entries for 3 blocks: NULL Made:???
+  r->wvhdl = (int **)omAlloc0(nb * sizeof(int_ptr));
+  r->wvhdl[0] = (int*) omAlloc(nv*sizeof(int));
+  r->wvhdl[1] = (int*) omAlloc((nv-1)*sizeof(int));
+
+  for(i=0; i<nv-1; i++)
+  {
+    r->wvhdl[1][i] = (*vb)[i];
+    r->wvhdl[0][i] = (*va)[i];
+  }
+  r->wvhdl[0][nv] = (*va)[nv];
+
+  // order: (1..1),a,lp,C
+  r->order = (int *) omAlloc(nb * sizeof(int *));
+  r->block0 = (int *)omAlloc0(nb * sizeof(int *));
+  r->block1 = (int *)omAlloc0(nb * sizeof(int *));
+
+  // ringorder a for the first block: var 1..nv
+  r->order[0]  = ringorder_a;
+  r->block0[0] = 1;
+  r->block1[0] = nv;
+
+ // ringorder a for the second block: var 2..nv
+  r->order[1]  = ringorder_a;
+  r->block0[1] = 2;
+  r->block1[1] = nv;
+
+  // ringorder lp for the third block: var 2..nv
+  r->order[2]  = ringorder_lp;
+  r->block0[2] = 2;
+  r->block1[2] = nv;
+
+  // ringorder C for the 4th block
+  // it is very important within "idLift",
+  // especially, by ring syz_ring=rCurrRingAssure_SyzComp();
+  // therefore, nb  must be (nBlocks(currRing)  + 1)
+  r->order[3]  = ringorder_C;
+
+  // polynomial ring
+  r->OrdSgn    = 1;
+
+  // complete ring intializations
+
+  rComplete(r);
+
+  rChangeCurrRing(r);
+}
+
+
+/**************************************************************
+ * define and execute a new ring which order is (a(va),lp,C)  *
+ * ************************************************************/
+static ring VMrDefault(intvec* va)
+{
+
+  if ((currRing->ppNoether)!=NULL)
+  {
+    pDelete(&(currRing->ppNoether));
+  }
+  if (((sLastPrinted.rtyp>BEGIN_RING) && (sLastPrinted.rtyp<END_RING)) ||
+      ((sLastPrinted.rtyp==LIST_CMD)&&(lRingDependend((lists)sLastPrinted.data))))
+  {
+    sLastPrinted.CleanUp();
+  }
+
+  ring r = (ring) omAlloc0Bin(sip_sring_bin);
+  int i, nv = currRing->N;
+
+  r->cf  = currRing->cf;
+  r->N   = currRing->N;
+
+  int nb = 4;
+
+  //names
+  char* Q; // In order to avoid the corrupted memory, do not change.
+  r->names = (char **) omAlloc0(nv * sizeof(char_ptr));
+  for(i=0; i<nv; i++)
+  {
+    Q = currRing->names[i];
+    r->names[i]  = omStrDup(Q);
+  }
+
+  /*weights: entries for 3 blocks: NULL Made:???*/
+  r->wvhdl = (int **)omAlloc0(nb * sizeof(int_ptr));
+  r->wvhdl[0] = (int*) omAlloc(nv*sizeof(int));
+  for(i=0; i<nv; i++)
+    r->wvhdl[0][i] = (*va)[i];
+
+  /* order: a,lp,C,0 */
+  r->order = (int *) omAlloc(nb * sizeof(int *));
+  r->block0 = (int *)omAlloc0(nb * sizeof(int *));
+  r->block1 = (int *)omAlloc0(nb * sizeof(int *));
+
+  // ringorder a for the first block: var 1..nv
+  r->order[0]  = ringorder_a;
+  r->block0[0] = 1;
+  r->block1[0] = nv;
+
+  // ringorder lp for the second block: var 1..nv
+  r->order[1]  = ringorder_lp;
+  r->block0[1] = 1;
+  r->block1[1] = nv;
+
+  // ringorder C for the third block
+  // it is very important within "idLift",
+  // especially, by ring syz_ring=rCurrRingAssure_SyzComp();
+  // therefore, nb  must be (nBlocks(currRing)  + 1)
+  r->order[2]  = ringorder_C;
+
+  // the last block: everything is 0
+  r->order[3]  = 0;
+
+  // polynomial ring
+  r->OrdSgn    = 1;
+
+  // complete ring intializations
+
+  rComplete(r);
+  return r;
+  //rChangeCurrRing(r);
+}
+
+static ring VMrDefault1(intvec* va)
+{
+
+  if ((currRing->ppNoether)!=NULL)
+  {
+    pDelete(&(currRing->ppNoether));
+  }
+  if (((sLastPrinted.rtyp>BEGIN_RING) && (sLastPrinted.rtyp<END_RING)) ||
+      ((sLastPrinted.rtyp==LIST_CMD)&&(lRingDependend((lists)sLastPrinted.data))))
+  {
+    sLastPrinted.CleanUp();
+  }
+
+  ring r = (ring) omAlloc0Bin(sip_sring_bin);
+  int i, nv = currRing->N;
+
+  r->cf  = currRing->cf;
+  r->N   = currRing->N;
+
+  int nb = 4;
+
+  //names
+  char* Q; // In order to avoid the corrupted memory, do not change.
+  r->names = (char **) omAlloc0(nv * sizeof(char_ptr));
+  for(i=0; i<nv; i++)
+  {
+    Q = currRing->names[i];
+    r->names[i]  = omStrDup(Q);
+  }
+
+  /*weights: entries for 3 blocks: NULL Made:???*/
+  r->wvhdl = (int **)omAlloc0(nb * sizeof(int_ptr));
+  r->wvhdl[0] = (int*) omAlloc(nv*sizeof(int));
+  for(i=0; i<nv; i++)
+    r->wvhdl[0][i] = (*va)[i];
+
+  /* order: a,lp,C,0 */
+  r->order = (int *) omAlloc(nb * sizeof(int *));
+  r->block0 = (int *)omAlloc0(nb * sizeof(int *));
+  r->block1 = (int *)omAlloc0(nb * sizeof(int *));
+
+  // ringorder a for the first block: var 1..nv
+  r->order[0]  = ringorder_a;
+  r->block0[0] = 1;
+  r->block1[0] = nv;
+
+  // ringorder lp for the second block: var 1..nv
+  r->order[1]  = ringorder_lp;
+  r->block0[1] = 1;
+  r->block1[1] = nv;
+
+  // ringorder C for the third block
+  // it is very important within "idLift",
+  // especially, by ring syz_ring=rCurrRingAssure_SyzComp();
+  // therefore, nb  must be (nBlocks(currRing)  + 1)
+  r->order[2]  = ringorder_C;
+
+  // the last block: everything is 0
+  r->order[3]  = 0;
+
+  // polynomial ring
+  r->OrdSgn    = 1;
+
+  // complete ring intializations
+
+  rComplete(r);
+
+  //rChangeCurrRing(r);
+  return r;
+}
+
+/****************************************************************
+ * define and execute a new ring with ordering (a(va),Wp(vb),C) *
+ * **************************************************************/
+
+static ring VMrRefine(intvec* va, intvec* vb)
+{
+
+  if ((currRing->ppNoether)!=NULL)
+  {
+    pDelete(&(currRing->ppNoether));
+  }
+  if (((sLastPrinted.rtyp>BEGIN_RING) && (sLastPrinted.rtyp<END_RING)) ||
+      ((sLastPrinted.rtyp==LIST_CMD)&&(lRingDependend((lists)sLastPrinted.data))))
+  {
+    sLastPrinted.CleanUp();
+  }
+
+  ring r = (ring) omAlloc0Bin(sip_sring_bin);
+  int i, nv = currRing->N;
+
+  r->cf  = currRing->cf;
+  r->N   = currRing->N;
+  //int nb = nBlocks(currRing)  + 1;
+  int nb = 4;
+
+  //names
+  char* Q; // In order to avoid the corrupted memory, do not change.
+  r->names = (char **) omAlloc0(nv * sizeof(char_ptr));
+  for(i=0; i<nv; i++)
+  {
+    Q = currRing->names[i];
+    r->names[i]  = omStrDup(Q);
+  }
+
+  //weights: entries for 3 blocks: NULL Made:???
+  r->wvhdl = (int **)omAlloc0(nb * sizeof(int_ptr));
+  r->wvhdl[0] = (int*) omAlloc(nv*sizeof(int));
+  r->wvhdl[1] = (int*) omAlloc(nv*sizeof(int));
+
+  for(i=0; i<nv; i++)
+  {
+    r->wvhdl[0][i] = (*va)[i];
+    r->wvhdl[1][i] = (*vb)[i];
+  }
+  r->wvhdl[2]=NULL;
+  r->wvhdl[3]=NULL;
+
+  // order: (1..1),a,lp,C
+  r->order = (int *) omAlloc(nb * sizeof(int *));
+  r->block0 = (int *)omAlloc0(nb * sizeof(int *));
+  r->block1 = (int *)omAlloc0(nb * sizeof(int *));
+
+  // ringorder a for the first block: var 1..nv
+  r->order[0]  = ringorder_a;
+  r->block0[0] = 1;
+  r->block1[0] = nv;
+
+ // ringorder Wp for the second block: var 1..nv
+  r->order[1]  = ringorder_Wp;
+  r->block0[1] = 1;
+  r->block1[1] = nv;
+
+  // ringorder lp for the third block: var 1..nv
+  r->order[2]  = ringorder_C;
+  r->block0[2] = 1;
+  r->block1[2] = nv;
+
+  // ringorder C for the 4th block
+  // it is very important within "idLift",
+  // especially, by ring syz_ring=rCurrRingAssure_SyzComp();
+  // therefore, nb  must be (nBlocks(currRing)  + 1)
+  r->order[3]  = 0;
+
+  // polynomial ring
+  r->OrdSgn    = 1;
+
+  // complete ring intializations
+
+  rComplete(r);
+
+  //rChangeCurrRing(r);
+  return r;
+}
+
+/*****************************************************
+ * define and execute a new ring with ordering (M,C) *
+ *****************************************************/
+static ring VMatrDefault(intvec* va)
+{
+
+  if ((currRing->ppNoether)!=NULL)
+  {
+    pDelete(&(currRing->ppNoether));
+  }
+  if (((sLastPrinted.rtyp>BEGIN_RING) && (sLastPrinted.rtyp<END_RING)) ||
+      ((sLastPrinted.rtyp==LIST_CMD)&&(lRingDependend((lists)sLastPrinted.data))))
+  {
+    sLastPrinted.CleanUp();
+  }
+
+  ring r = (ring) omAlloc0Bin(sip_sring_bin);
+  int i, nv = currRing->N;
+
+  r->cf  = currRing->cf;
+  r->N   = currRing->N;
+
+  int nb = 4;
+
+  //names
+  char* Q; // In order to avoid the corrupted memory, do not change.
+  r->names = (char **) omAlloc0(nv * sizeof(char_ptr));
+  for(i=0; i<nv; i++)
+  {
+    Q = currRing->names[i];
+    r->names[i]  = omStrDup(Q);
+  }
+
+  /*weights: entries for 3 blocks: NULL Made:???*/
+  r->wvhdl = (int **)omAlloc0(nb * sizeof(int_ptr));
+  r->wvhdl[0] = (int*) omAlloc(nv*nv*sizeof(int));
+  r->wvhdl[1] =NULL; // (int*) omAlloc(nv*sizeof(int));
+  r->wvhdl[2]=NULL;
+  r->wvhdl[3]=NULL;
+  for(i=0; i<nv*nv; i++)
+    r->wvhdl[0][i] = (*va)[i];
+
+  /* order: a,lp,C,0 */
+  r->order = (int *) omAlloc(nb * sizeof(int *));
+  r->block0 = (int *)omAlloc0(nb * sizeof(int *));
+  r->block1 = (int *)omAlloc0(nb * sizeof(int *));
+
+  // ringorder a for the first block: var 1..nv
+  r->order[0]  = ringorder_M;
+  r->block0[0] = 1;
+  r->block1[0] = nv;
+
+  // ringorder C for the second block
+  r->order[1]  = ringorder_C;
+  r->block0[1] = 1;
+  r->block1[1] = nv;
+
+
+// ringorder C for the third block: var 1..nv
+  r->order[2]  = ringorder_C;
+  r->block0[2] = 1;
+  r->block1[2] = nv;
+
+
+  // the last block: everything is 0
+  r->order[3]  = 0;
+
+  // polynomial ring
+  r->OrdSgn    = 1;
+
+  // complete ring intializations
+
+  rComplete(r);
+
+  //rChangeCurrRing(r);
+  return r;
+}
+
+/***********************************************************
+ * define and execute a new ring with ordering (a(vb),M,C) *
+ ***********************************************************/
+static ring VMatrRefine(intvec* va, intvec* vb)
+{
+
+  if ((currRing->ppNoether)!=NULL)
+  {
+    pDelete(&(currRing->ppNoether));
+  }
+  if (((sLastPrinted.rtyp>BEGIN_RING) && (sLastPrinted.rtyp<END_RING)) ||
+      ((sLastPrinted.rtyp==LIST_CMD)&&(lRingDependend((lists)sLastPrinted.data))))
+  {
+    sLastPrinted.CleanUp();
+  }
+
+  ring r = (ring) omAlloc0Bin(sip_sring_bin);
+  int i, nv = currRing->N;
+  int nvs = nv*nv;
+  r->cf  = currRing->cf;
+  r->N   = currRing->N;
+
+  int nb = 4;
+
+  //names
+  char* Q; // In order to avoid the corrupted memory, do not change.
+  r->names = (char **) omAlloc0(nv * sizeof(char_ptr));
+  for(i=0; i<nv; i++)
+  {
+    Q = currRing->names[i];
+    r->names[i]  = omStrDup(Q);
+  }
+
+  /*weights: entries for 3 blocks: NULL Made:???*/
+  r->wvhdl = (int **)omAlloc0(nb * sizeof(int_ptr));
+  r->wvhdl[0] = (int*) omAlloc(nv*sizeof(int));
+  r->wvhdl[1] = (int*) omAlloc(nvs*sizeof(int));
+  r->wvhdl[2]=NULL;
+  r->wvhdl[3]=NULL;
+  for(i=0; i<nvs; i++)
+  {
+    r->wvhdl[1][i] = (*va)[i];
+  }
+  for(i=0; i<nv; i++)
+  {
+    r->wvhdl[0][i] = (*vb)[i];
+  }
+  /* order: a,lp,C,0 */
+  r->order = (int *) omAlloc(nb * sizeof(int *));
+  r->block0 = (int *)omAlloc0(nb * sizeof(int *));
+  r->block1 = (int *)omAlloc0(nb * sizeof(int *));
+
+  // ringorder a for the first block: var 1..nv
+  r->order[0]  = ringorder_a;
+  r->block0[0] = 1;
+  r->block1[0] = nv;
+
+  // ringorder M for the second block: var 1..nv
+  r->order[1]  = ringorder_M;
+  r->block0[1] = 1;
+  r->block1[1] = nv;
+
+  // ringorder C for the third block: var 1..nv
+  r->order[2]  = ringorder_C;
+  r->block0[2] = 1;
+  r->block1[2] = nv;
+
+
+  // the last block: everything is 0
+  r->order[3]  = 0;
+
+  // polynomial ring
+  r->OrdSgn    = 1;
+
+  // complete ring intializations
+
+  rComplete(r);
+
+  //rChangeCurrRing(r);
+  return r;
+}
+
+/**********************************************************************
+* define and execute a new ring which order is  a lexicographic order *
+***********************************************************************/
+static void VMrDefaultlp(void)
+{
+
+  if ((currRing->ppNoether)!=NULL)
+  {
+    pDelete(&(currRing->ppNoether));
+  }
+  if (((sLastPrinted.rtyp>BEGIN_RING) && (sLastPrinted.rtyp<END_RING)) ||
+      ((sLastPrinted.rtyp==LIST_CMD)&&(lRingDependend((lists)sLastPrinted.data))))
+
+  {
+    sLastPrinted.CleanUp();
+  }
+
+  ring r = (ring) omAlloc0Bin(sip_sring_bin);
+  int i, nv = currRing->N;
+
+  r->cf  = currRing->cf;
+  r->N   = currRing->N;
+  int nb = rBlocks(currRing) + 1;
+
+  // names
+  char* Q; // to avoid the corrupted memory, do not change!!
+  r->names = (char **) omAlloc0(nv * sizeof(char_ptr));
+  for(i=0; i<nv; i++)
+  {
+    Q = currRing->names[i];
+    r->names[i]  = omStrDup(Q);
+  }
+
+  /*weights: entries for 3 blocks: NULL Made:???*/
+
+  r->wvhdl = (int **)omAlloc0(nb * sizeof(int_ptr));
+
+  /* order: lp,C,0 */
+  r->order = (int *) omAlloc(nb * sizeof(int *));
+  r->block0 = (int *)omAlloc0(nb * sizeof(int *));
+  r->block1 = (int *)omAlloc0(nb * sizeof(int *));
+
+  /* ringorder lp for the first block: var 1..nv */
+  r->order[0]  = ringorder_lp;
+  r->block0[0] = 1;
+  r->block1[0] = nv;
+
+  /* ringorder C for the second block */
+  r->order[1]  = ringorder_C;
+
+  /* the last block: everything is 0 */
+  r->order[2]  = 0;
+
+  /*polynomial ring*/
+  r->OrdSgn    = 1;
+
+  /* complete ring intializations */
+
+  rComplete(r);
+
+  rChangeCurrRing(r);
+}
+
+
+/* define a ring with parameters und change to it */
+/* DefRingPar and DefRingParlp corrupt still memory */
+static void DefRingPar(intvec* va)
+{
+  int i, nv = currRing->N;
+  int nb = rBlocks(currRing) + 1;
+
+  ring res=(ring)omAllocBin(sip_sring_bin);
+
+  memcpy(res,currRing,sizeof(ip_sring));
+
+  res->VarOffset = NULL;
+  res->ref=0;
+
+  res->cf = currRing->cf; currRing->cf->ref++;
+
+
+  /*weights: entries for 3 blocks: NULL Made:???*/
+  res->wvhdl = (int **)omAlloc0(nb * sizeof(int_ptr));
+  res->wvhdl[0] = (int*) omAlloc(nv*sizeof(int));
+  for(i=0; i<nv; i++)
+    res->wvhdl[0][i] = (*va)[i];
+
+  /* order: a,lp,C,0 */
+
+  res->order = (int *) omAlloc(nb * sizeof(int *));
+  res->block0 = (int *)omAlloc0(nb * sizeof(int *));
+  res->block1 = (int *)omAlloc0(nb * sizeof(int *));
+
+  // ringorder a for the first block: var 1..nv
+  res->order[0]  = ringorder_a;
+  res->block0[0] = 1;
+  res->block1[0] = nv;
+
+  // ringorder lp for the second block: var 1..nv
+  res->order[1]  = ringorder_lp;
+  res->block0[1] = 1;
+  res->block1[1] = nv;
+
+  // ringorder C for the third block
+  // it is very important within "idLift",
+  // especially, by ring syz_ring=rCurrRingAssure_SyzComp();
+  // therefore, nb  must be (nBlocks(currRing)  + 1)
+  res->order[2]  = ringorder_C;
+
+  // the last block: everything is 0
+  res->order[3]  = 0;
+
+  // polynomial ring
+  res->OrdSgn    = 1;
+
+
+  res->names   = (char **)omAlloc0(nv * sizeof(char_ptr));
+  for (i=nv-1; i>=0; i--)
+  {
+    res->names[i] = omStrDup(currRing->names[i]);
+  }
+  // complete ring intializations
+  rComplete(res);
+
+  // clean up history
+  if (sLastPrinted.RingDependend())
+  {
+    sLastPrinted.CleanUp();
+  }
+
+
+  // execute the created ring
+  rChangeCurrRing(res);
+}
+
+
+static void DefRingParlp(void)
+{
+  int i, nv = currRing->N;
+
+  ring r=(ring)omAllocBin(sip_sring_bin);
+
+  memcpy(r,currRing,sizeof(ip_sring));
+
+  r->VarOffset = NULL;
+  r->ref=0;
+
+  r->cf = currRing->cf; currRing->cf->ref++;
+
+
+  r->cf  = currRing->cf;
+  r->N   = currRing->N;
+  int nb = rBlocks(currRing) + 1;
+
+  // names
+  char* Q;
+  r->names = (char **) omAlloc0(nv * sizeof(char_ptr));
+  for(i=nv-1; i>=0; i--)
+  {
+    Q = currRing->names[i];
+    r->names[i]  = omStrDup(Q);
+  }
+
+  /*weights: entries for 3 blocks: NULL Made:???*/
+
+  r->wvhdl = (int **)omAlloc0(nb * sizeof(int_ptr));
+
+  /* order: lp,C,0 */
+  r->order = (int *) omAlloc(nb * sizeof(int *));
+  r->block0 = (int *)omAlloc0(nb * sizeof(int *));
+  r->block1 = (int *)omAlloc0(nb * sizeof(int *));
+
+  /* ringorder lp for the first block: var 1..nv */
+  r->order[0]  = ringorder_lp;
+  r->block0[0] = 1;
+  r->block1[0] = nv;
+
+  /* ringorder C for the second block */
+  r->order[1]  = ringorder_C;
+
+  /* the last block: everything is 0 */
+  r->order[2]  = 0;
+
+  /*polynomial ring*/
+  r->OrdSgn    = 1;
+
+
+//   if (rParameter(currRing)!=NULL)
+//   {
+//     r->cf->extRing->qideal->m[0]=p_Copy(currRing->cf->extRing->qideal->m[0], currRing->cf->extRing);
+//     int l=rPar(currRing);
+//     r->cf->extRing->names=(char **)omAlloc(l*sizeof(char_ptr));
+//
+//     for(i=l-1;i>=0;i--)
+//     {
+//       rParameter(r)[i]=omStrDup(rParameter(currRing)[i]);
+//     }
+//   }
+
+  // complete ring intializations
+
+  rComplete(r);
+
+  // clean up history
+  if (sLastPrinted.RingDependend())
+  {
+    sLastPrinted.CleanUp();
+  }
+
+  // execute the created ring
+  rChangeCurrRing(r);
+}
+
+//unused
+/**************************************************************
+ * check wheather one or more components of a vector are zero *
+ **************************************************************/
+//#if 0
+static int isNolVector(intvec* hilb)
+{
+  int i;
+  for(i=hilb->length()-1; i>=0; i--)
+  {
+    if((* hilb)[i]==0)
+    {
+      return 1;
+    }
+  }
+  return 0;
+}
+//#endif
+
+/******************************  Februar 2002  ****************************
+ * G is a Groebner basis w.r.t. (a(curr_weight),lp) and                   *
+ * we compute a GB of <G> w.r.t. the lex. order by the perturbation walk  *
+ * its perturbation degree is tp_deg                                      *
+ * We call the following subfunction LastGB, if                           *
+ * the computed intermediate weight vector or                             *
+ * if the perturbed target weight vector does NOT lie n the correct cone  *
+ **************************************************************************/
+
+static ideal LastGB(ideal G, intvec* curr_weight,int tp_deg)
+{
+  BOOLEAN nError = Overflow_Error;
+  Overflow_Error = FALSE;
+
+  int i, nV = currRing->N;
+  int nwalk=0, endwalks=0, nnwinC=1;
+  int nlast = 0;
+  ideal Gomega, M, F, Gomega1, Gomega2, M1,F1,result,ssG;
+  ring newRing, oldRing, TargetRing;
+  intvec* iv_M_lp;
+  intvec* target_weight;
+  intvec* iv_lp = Mivlp(nV); //define (1,0,...,0)
+  intvec* pert_target_vector;
+  intvec* ivNull = new intvec(nV);
+  intvec* extra_curr_weight = new intvec(nV);
+  intvec* next_weight;
+
+#ifndef  BUCHBERGER_ALG
+  intvec* hilb_func;
+#endif
+
+  // to avoid (1,0,...,0) as the target vector
+  intvec* last_omega = new intvec(nV);
+  for(i=nV-1; i>0; i--)
+  {
+    (*last_omega)[i] = 1;
+  }
+  (*last_omega)[0] = 10000;
+
+  ring EXXRing = currRing;
+
+  // compute a pertubed weight vector of the target weight vector
+  if(tp_deg > 1 && tp_deg <= nV)
+  {
+    //..25.03.03 VMrDefaultlp();//    VMrDefault(target_weight);
+    if (rParameter (currRing) != NULL)
+    {
+      DefRingParlp();
+    }
+    else
+    {
+      VMrDefaultlp();
+    }
+    TargetRing = currRing;
+    ssG = idrMoveR(G,EXXRing,currRing);
+    iv_M_lp = MivMatrixOrderlp(nV);
+    //target_weight = MPertVectorslp(ssG, iv_M_lp, tp_deg);
+    target_weight = MPertVectors(ssG, iv_M_lp, tp_deg);
+    delete iv_M_lp;
+    pert_target_vector = target_weight;
+
+    rChangeCurrRing(EXXRing);
+    G = idrMoveR(ssG, TargetRing,currRing);
+  }
+  else
+  {
+    target_weight = Mivlp(nV);
+  }
+  //Print("\n// ring r%d_%d = %s;\n", tp_deg, nwalk, rString(currRing));
+
+  while(1)
+  {
+    nwalk++;
+    nstep++;
+    to=clock();
+   // compute a next weight vector
+    next_weight = MkInterRedNextWeight(curr_weight,target_weight, G);
+    xtnw=xtnw+clock()-to;
+
+#ifdef PRINT_VECTORS
+    MivString(curr_weight, target_weight, next_weight);
+#endif
+
+    if(Overflow_Error == TRUE)
+    {
+      newRing = currRing;
+      nnwinC = 0;
+      if(tp_deg == 1)
+      {
+        nlast = 1;
+      }
+      delete next_weight;
+
+      //idElements(G, "G");
+      //Print("\n// ring r%d_%d = %s;\n", tp_deg, nwalk, rString(currRing));
+
+      break;
+    }
+
+    if(MivComp(next_weight, ivNull) == 1)
+    {
+      //Print("\n// ring r%d_%d = %s;\n", tp_deg, nwalk, rString(currRing));
+      newRing = currRing;
+      delete next_weight;
+      break;
+    }
+
+    if(MivComp(next_weight, target_weight) == 1)
+      endwalks = 1;
+
+    for(i=nV-1; i>=0; i--)
+    {
+      (*extra_curr_weight)[i] = (*curr_weight)[i];
+    }
+    /* 06.11.01 NOT Changed */
+    for(i=nV-1; i>=0; i--)
+    {
+      (*curr_weight)[i] = (*next_weight)[i];
+    }
+    oldRing = currRing;
+    to=clock();
+    // compute an initial form ideal of <G> w.r.t. "curr_vector"
+    Gomega = MwalkInitialForm(G, curr_weight);
+    xtif=xtif+clock()-to;
+
+#ifdef ENDWALKS
+    if(endwalks == 1)
+    {
+      Print("\n// ring r%d_%d = %s;\n", tp_deg, nwalk, rString(currRing));
+      idElements(Gomega, "Gw");
+      headidString(Gomega, "Gw");
+    }
+#endif
+
+#ifndef  BUCHBERGER_ALG
+    if(isNolVector(curr_weight) == 0)
+    {
+      hilb_func = hFirstSeries(Gomega,NULL,NULL,curr_weight,currRing);
+    }
+    else
+    {
+      hilb_func = hFirstSeries(Gomega,NULL,NULL,last_omega,currRing);
+    }
+#endif // BUCHBERGER_ALG
+
+    /* define a new ring that its ordering is "(a(curr_weight),lp) */
+    //..25.03.03 VMrDefault(curr_weight);
+    if (rParameter (currRing) != NULL)
+    {
+      DefRingPar(curr_weight);
+    }
+    else
+    {
+      rChangeCurrRing(VMrDefault(curr_weight)); //Aenderung
+    }
+    newRing = currRing;
+    Gomega1 = idrMoveR(Gomega, oldRing,currRing);
+
+    to=clock();
+    /* compute a reduced Groebner basis of <Gomega> w.r.t. "newRing" */
+#ifdef  BUCHBERGER_ALG
+    M = MstdhomCC(Gomega1);
+#else
+    M=kStd(Gomega1,NULL,isHomog,NULL,hilb_func,0,NULL,curr_weight);
+    delete hilb_func;
+#endif // BUCHBERGER_ALG
+    xtstd=xtstd+clock()-to;
+    /* change the ring to oldRing */
+    rChangeCurrRing(oldRing);
+    M1 =  idrMoveR(M, newRing,currRing);
+    Gomega2 =  idrMoveR(Gomega1, newRing,currRing);
+
+    to=clock();
+    /* compute a reduced Groebner basis of <G> w.r.t. "newRing" */
+    F = MLifttwoIdeal(Gomega2, M1, G);
+    xtlift=xtlift+clock()-to;
+
+    idDelete(&M1);
+    idDelete(&G);
+
+    /* change the ring to newRing */
+    rChangeCurrRing(newRing);
+    F1 = idrMoveR(F, oldRing,currRing);
+
+    to=clock();
+    /* reduce the Groebner basis <G> w.r.t. new ring */
+    G = kInterRedCC(F1, NULL);
+    xtred=xtred+clock()-to;
+    idDelete(&F1);
+
+    if(endwalks == 1)
+    {
+      //Print("\n// ring r%d_%d = %s;\n", tp_deg, nwalk, rString(currRing));
+      break;
+    }
+
+    delete next_weight;
+  }//while
+
+  delete ivNull;
+
+  if(tp_deg != 1)
+  {
+    //..25.03.03 VMrDefaultlp();//define and execute the ring "lp"
+    if (rParameter (currRing) != NULL)
+    {
+      DefRingParlp();
+    }
+    else
+    {
+      VMrDefaultlp();
+    }
+    F1 = idrMoveR(G, newRing,currRing);
+
+    if(nnwinC == 0 || test_w_in_ConeCC(F1, pert_target_vector) != 1)
+    {
+      oldRing = currRing;
+      rChangeCurrRing(newRing);
+      G = idrMoveR(F1, oldRing,currRing);
+      Print("\n// takes %d steps and calls the recursion of level %d:",
+             nwalk, tp_deg-1);
+
+      F1 = LastGB(G,curr_weight, tp_deg-1);
+    }
+
+    TargetRing = currRing;
+    rChangeCurrRing(EXXRing);
+    result = idrMoveR(F1, TargetRing,currRing);
+  }
+  else
+  {
+    if(nlast == 1)
+    {
+      //OMEGA_OVERFLOW_LASTGB:
+      /*
+      if(MivSame(curr_weight, iv_lp) == 1)
+        if (rParameter(currRing) != NULL)
+          DefRingParlp();
+        else
+          VMrDefaultlp();
+      else
+        if (rParameter(currRing) != NULL)
+          DefRingPar(curr_weight);
+        else
+          VMrDefault(curr_weight);
+      */
+
+        //..25.03.03 VMrDefaultlp();//define and execute the ring "lp"
+        if (rParameter (currRing) != NULL)
+        {
+          DefRingParlp();
+        }
+        else
+        {
+          VMrDefaultlp();
+        }
+
+      F1 = idrMoveR(G, newRing,currRing);
+      //Print("\n// Apply \"std\" in ring r%d_%d = %s;\n", tp_deg, nwalk, rString(currRing));
+
+      G = MstdCC(F1);
+      idDelete(&F1);
+      newRing = currRing;
+    }
+
+    rChangeCurrRing(EXXRing);
+    result = idrMoveR(G, newRing,currRing);
+  }
+  delete target_weight;
+  delete last_omega;
+  delete iv_lp;
+
+  if(Overflow_Error == FALSE)
+  {
+    Overflow_Error = nError;
+  }
+  return(result);
+}
+
+/**********************************************************
+ * check whether a polynomial of G has least 3 monomials  *
+ **********************************************************/
+static int lengthpoly(ideal G)
+{
+  int i;
+  for(i=IDELEMS(G)-1; i>=0; i--)
+  {
+#if 0
+    if(pLength(G->m[i])>2)
+    {
+      return 1;
+    }
+#else
+    if((G->m[i]!=NULL) /* len >=0 */
+       && (G->m[i]->next!=NULL) /* len >=1 */
+       && (G->m[i]->next->next!=NULL) /* len >=2 */
+       && (G->m[i]->next->next->next!=NULL) /* len >=3 */
+      //&& (G->m[i]->next->next->next->next!=NULL) /* len >=4 */
+       )
+    {
+    return 1;
+    }
+#endif
+  }
+  return 0;
+}
+
+/*********************************************************
+ * check whether a polynomial of G has least 2 monomials *
+**********************************************************/
+static int islengthpoly2(ideal G)
+{
+  int i;
+  for(i=IDELEMS(G)-1; i>=0; i--)
+  {
+    if((G->m[i]!=NULL) /* len >=0 */
+       && (G->m[i]->next!=NULL) /* len >=1 */
+       && (G->m[i]->next->next!=NULL)) /* len >=2 */
+    {
+      return 1;
+    }
+  }
+  return 0;
+}
+
+
+
+/* Implementation of the improved Groebner walk algorithm which is written
+   by Quoc-Nam Tran (2000).
+   One perturbs the original target weight vector, only if
+   the next intermediate weight vector is equal to the current target weight
+   vector. This must be repeated until the wanted reduced Groebner basis
+   to reach.
+   If the numbers of variables is big enough, the representation of the origin
+   weight vector may be very big. Therefore, it is possible the intermediate
+   weight vector doesn't stay in the correct Groebner cone.
+   In this case we have just a reduced Groebner basis of the given ideal
+   with respect to another monomial order. Then we have to compute
+   a wanted reduced Groebner basis of it with respect to the given order.
+   At the following subroutine we use the improved Buchberger algorithm or
+   the changed perturbation walk algorithm with a decrased degree.
+ */
+
+/***************************************
+ * return the initial term of an ideal *
+ ***************************************/
+static ideal idHeadCC(ideal h)
+{
+  int i, nH =IDELEMS(h);
+
+  ideal m = idInit(nH,h->rank);
+
+  for (i=nH-1;i>=0; i--)
+  {
+    if (h->m[i]!=NULL)
+    {
+      m->m[i]=pHead(h->m[i]);
+    }
+  }
+  return m;
+}
+
+/**********************************************
+ * check whether two head-ideals are the same *
+ **********************************************/
+static inline int test_G_GB_walk(ideal H0, ideal H1)
+{
+  int i, nG = IDELEMS(H0);
+
+  if(nG != IDELEMS(H1))
+  {
+    return 0;
+  }
+  for(i=nG-1; i>=0; i--)
+  {
+#if 0
+    poly t;
+    if((t=pSub(pCopy(H0->m[i]), pCopy(H1->m[i]))) != NULL)
+    {
+      pDelete(&t);
+      return 0;
+    }
+    pDelete(&t);
+#else
+    if(!pEqualPolys(H0->m[i],H1->m[i]))
+    {
+      return 0;
+    }
+#endif
+  }
+  return 1;
+}
+
+//unused
+/*****************************************************
+ * find the maximal total degree of polynomials in G *
+ *****************************************************/
+#if 0
+static int Trandegreebound(ideal G)
+{
+  int i, nG = IDELEMS(G);
+  // int np=1;
+  int nV = currRing->N;
+  int degtmp, result = 0;
+  intvec* ivUnit = Mivdp(nV);
+
+  for(i=nG-1; i>=0; i--)
+  {
+    // find the maximal total degree of the polynomial G[i]
+    degtmp = MwalkWeightDegree(G->m[i], ivUnit);
+    if(degtmp > result)
+    {
+      result = degtmp;
+    }
+  }
+  delete ivUnit;
+  return result;
+}
+#endif
+
+//unused
+/************************************************************************
+ * perturb the weight vector iva w.r.t. the ideal G.                    *
+ *  the monomial order of the current ring is the w_1 weight lex. order *
+ *  define w := d^(n-1)w_1+ d^(n-2)w_2, ...+ dw_(n-1)+ w_n              *
+ *  where d := 1 + max{totdeg(g):g in G}*m, or                          *
+ *  d := (2*maxdeg*maxdeg + (nV+1)*maxdeg)*m;                           *
+ ************************************************************************/
+#if 0
+static intvec* TranPertVector(ideal G, intvec* iva)
+{
+  BOOLEAN nError = Overflow_Error;
+  Overflow_Error = FALSE;
+
+  int i, j;
+  // int nG = IDELEMS(G);
+  int nV = currRing->N;
+
+  // define the sequence which expresses the current monomial ordering
+  // w_1 = iva; w_2 = (1,0,..,0); w_n = (0,...,0,1,0)
+  intvec* ivMat = MivMatrixOrder(iva);
+
+  int  mtmp, m=(*iva)[0];
+
+  for(i=ivMat->length(); i>=0; i--)
+  {
+    mtmp = (*ivMat)[i];
+    if(mtmp <0)
+    {
+      mtmp = -mtmp;
+    }
+    if(mtmp > m)
+    {
+      m = mtmp;
+    }
+  }
+
+  // define the maximal total degree of polynomials of G
+  mpz_t ndeg;
+  mpz_init(ndeg);
+
+ // 12 Juli 03
+#ifndef UPPER_BOUND
+  mpz_set_si(ndeg, Trandegreebound(G)+1);
+#else
+  mpz_t ztmp;
+  mpz_init(ztmp);
+
+  mpz_t maxdeg;
+  mpz_init_set_si(maxdeg, Trandegreebound(G));
+
+  //ndeg = (2*maxdeg*maxdeg + (nV+1)*maxdeg)*m;//Kalkbrenner (1999)
+  mpz_pow_ui(ztmp, maxdeg, 2);
+  mpz_mul_ui(ztmp, ztmp, 2);
+  mpz_mul_ui(maxdeg, maxdeg, nV+1);
+  mpz_add(ndeg, ztmp, maxdeg);
+  mpz_mul_ui(ndeg, ndeg, m);
+
+  mpz_clear(ztmp);
+
+  //PrintS("\n// with the new upper degree bound (2d^2+(n+1)d)*m ");
+  //Print("\n//         where d = %d, n = %d and bound = %d", maxdeg, nV, ndeg);
+#endif //UPPER_BOUND
+
+#ifdef INVEPS_SMALL_IN_TRAN
+  if(mpz_cmp_ui(ndeg, nV)>0 && nV > 3)
+  {
+    mpz_cdiv_q_ui(ndeg, ndeg, nV);
+  }
+ //PrintS("\n// choose the \"small\" inverse epsilon:");
+ //mpz_out_str(stdout, 10, ndeg);
+#endif
+  mpz_t deg_tmp;
+  mpz_init_set(deg_tmp, ndeg);
+
+  mpz_t *ivres=( mpz_t *) omAlloc(nV*sizeof(mpz_t));
+  mpz_init_set_si(ivres[nV-1],1);
+
+  for(i=nV-2; i>=0; i--)
+  {
+    mpz_init_set(ivres[i], deg_tmp);
+    mpz_mul(deg_tmp, deg_tmp, ndeg);
+  }
+
+  mpz_t *ivtmp=(mpz_t *)omAlloc(nV*sizeof(mpz_t));
+  for(i=0; i<nV; i++)
+  {
+    mpz_init(ivtmp[i]);
+  }
+  mpz_t sing_int;
+  mpz_init_set_ui(sing_int,  2147483647);
+
+  intvec* repr_vector = new intvec(nV);
+
+  // define ivtmp := ndeg^(n-1).w_1 + ndeg^(n-2).w_2 + ... + w_n
+  for(i=0; i<nV; i++)
+  {
+    for(j=0; j<nV; j++)
+    {
+      if( (*ivMat)[i*nV+j] >= 0 )
+      {
+        mpz_mul_ui(ivres[i], ivres[i], (*ivMat)[i*nV+j]);
+      }
+      else
+      {
+        mpz_mul_ui(ivres[i], ivres[i], -(*ivMat)[i*nV+j]);
+        mpz_neg(ivres[i], ivres[i]);
+      }
+      mpz_add(ivtmp[j], ivtmp[j], ivres[i]);
+    }
+  }
+  delete ivMat;
+
+  int ntrue=0;
+  for(i=0; i<nV; i++)
+  {
+    (*repr_vector)[i] = mpz_get_si(ivtmp[i]);
+    if(mpz_cmp(ivtmp[i], sing_int)>=0)
+    {
+      ntrue++;
+      if(Overflow_Error == FALSE)
+      {
+        Overflow_Error = TRUE;
+
+        PrintS("\n// ** OVERFLOW in \"Repr.Vector\": ");
+        mpz_out_str( stdout, 10, ivtmp[i]);
+        PrintS(" is greater than 2147483647 (max. integer representation)");
+        Print("\n//  So vector[%d] := %d is wrong!!\n",i+1,(*repr_vector)[i]);
+      }
+    }
+  }
+  if(Overflow_Error == TRUE)
+  {
+    ivString(repr_vector, "repvector");
+    Print("\n// %d element(s) of it are overflow!!", ntrue);
+  }
+
+  if(Overflow_Error == FALSE)
+    Overflow_Error=nError;
+
+  omFree(ivres);
+  omFree(ivtmp);
+
+  mpz_clear(sing_int);
+  mpz_clear(deg_tmp);
+  mpz_clear(ndeg);
+
+  return repr_vector;
+}
+#endif
+
+//unused
+#if 0
+static intvec* TranPertVector_lp(ideal G)
+{
+  BOOLEAN nError = Overflow_Error;
+  Overflow_Error = FALSE;
+  // int j, nG = IDELEMS(G);
+  int i;
+  int nV = currRing->N;
+
+  // define the maximal total degree of polynomials of G
+  mpz_t ndeg;
+  mpz_init(ndeg);
+
+ // 12 Juli 03
+#ifndef UPPER_BOUND
+  mpz_set_si(ndeg, Trandegreebound(G)+1);
+#else
+  mpz_t ztmp;
+  mpz_init(ztmp);
+
+  mpz_t maxdeg;
+  mpz_init_set_si(maxdeg, Trandegreebound(G));
+
+  //ndeg = (2*maxdeg*maxdeg + (nV+1)*maxdeg);//Kalkbrenner (1999)
+  mpz_pow_ui(ztmp, maxdeg, 2);
+  mpz_mul_ui(ztmp, ztmp, 2);
+  mpz_mul_ui(maxdeg, maxdeg, nV+1);
+  mpz_add(ndeg, ztmp, maxdeg);
+  // PrintS("\n// with the new upper degree bound (2d^2+(n+1)d)*m ");
+  // Print("\n//         where d = %d, n = %d and bound = %d",
+  // mpz_get_si(maxdeg), nV, mpz_get_si(ndeg));
+
+ mpz_clear(ztmp);
+
+#endif
+
+#ifdef INVEPS_SMALL_IN_TRAN
+ if(mpz_cmp_ui(ndeg, nV)>0 && nV > 3)
+    mpz_cdiv_q_ui(ndeg, ndeg, nV);
+
+ //PrintS("\n// choose the \"small\" inverse epsilon:");
+ // mpz_out_str(stdout, 10, ndeg);
+#endif
+
+  mpz_t deg_tmp;
+  mpz_init_set(deg_tmp, ndeg);
+
+  mpz_t *ivres=(mpz_t *)omAlloc(nV*sizeof(mpz_t));
+  mpz_init_set_si(ivres[nV-1], 1);
+
+  for(i=nV-2; i>=0; i--)
+  {
+    mpz_init_set(ivres[i], deg_tmp);
+    mpz_mul(deg_tmp, deg_tmp, ndeg);
+  }
+
+  mpz_t sing_int;
+  mpz_init_set_ui(sing_int,  2147483647);
+
+  intvec* repr_vector = new intvec(nV);
+  int ntrue=0;
+  for(i=0; i<nV; i++)
+  {
+    (*repr_vector)[i] = mpz_get_si(ivres[i]);
+
+    if(mpz_cmp(ivres[i], sing_int)>=0)
+    {
+      ntrue++;
+      if(Overflow_Error == FALSE)
+      {
+        Overflow_Error = TRUE;
+        PrintS("\n// ** OVERFLOW in \"Repr.Vector\": ");
+        mpz_out_str( stdout, 10, ivres[i]);
+        PrintS(" is greater than 2147483647 (max. integer representation)");
+        Print("\n//  So vector[%d] := %d is wrong!!\n",i+1,(*repr_vector)[i]);
+      }
+    }
+  }
+  if(Overflow_Error == TRUE)
+  {
+    ivString(repr_vector, "repvector");
+    Print("\n// %d element(s) of it are overflow!!", ntrue);
+  }
+  if(Overflow_Error == FALSE)
+    Overflow_Error = nError;
+
+  omFree(ivres);
+
+  mpz_clear(ndeg);
+  mpz_clear(sing_int);
+
+  return repr_vector;
+}
+#endif
+
+//unused
+#if 0
+static intvec* RepresentationMatrix_Dp(ideal G, intvec* M)
+{
+  BOOLEAN nError = Overflow_Error;
+  Overflow_Error = FALSE;
+
+  int i, j;
+  int nV = currRing->N;
+
+  intvec* ivUnit = Mivdp(nV);
+  int degtmp, maxdeg = 0;
+
+  for(i=IDELEMS(G)-1; i>=0; i--)
+  {
+    // find the maximal total degree of the polynomial G[i]
+    degtmp = MwalkWeightDegree(G->m[i], ivUnit);
+    if(degtmp > maxdeg)
+      maxdeg = degtmp;
+  }
+
+  mpz_t ztmp;
+  mpz_init_set_si(ztmp, maxdeg);
+  mpz_t *ivres=(mpz_t *)omAlloc(nV*sizeof(mpz_t));
+  mpz_init_set_si(ivres[nV-1], 1); // (*ivres)[nV-1] = 1;
+
+  for(i=nV-2; i>=0; i--)
+  {
+    mpz_init_set(ivres[i], ztmp); //(*ivres)[i] = ztmp;
+    mpz_mul_ui(ztmp, ztmp, maxdeg); //ztmp *=maxdeg;
+  }
+
+  mpz_t *ivtmp=(mpz_t*)omAlloc(nV*sizeof(mpz_t));
+  for(i=0; i<nV; i++)
+    mpz_init(ivtmp[i]);
+
+  // define ivtmp := ndeg^(n-1).w_1 + ndeg^(n-2).w_2 + ... + w_n
+  for(i=0; i<nV; i++)
+    for(j=0; j<nV; j++)
+    {
+      if((*M)[i*nV+j] < 0)
+      {
+        mpz_mul_ui(ztmp, ivres[i], -(*M)[i*nV+j]);
+        mpz_neg(ztmp, ztmp);
+      }
+      else
+        mpz_mul_ui(ztmp, ivres[i], (*M)[i*nV+j]);
+
+      mpz_add(ivtmp[j], ivtmp[j], ztmp);
+    }
+  delete ivres;
+  mpz_t sing_int;
+  mpz_init_set_ui(sing_int,  2147483647);
+
+  int ntrue=0;
+  intvec* repvector = new intvec(nV);
+  for(i=0; i<nV; i++)
+  {
+    (*repvector)[i] = mpz_get_si(ivtmp[i]);
+    if(mpz_cmp(ivtmp[i], sing_int)>0)
+    {
+      ntrue++;
+      if(Overflow_Error == FALSE)
+      {
+        Overflow_Error = TRUE;
+        PrintS("\n// ** OVERFLOW in \"Repr.Matrix\": ");
+        mpz_out_str( stdout, 10, ivtmp[i]);
+        PrintS(" is greater than 2147483647 (max. integer representation)");
+        Print("\n//  So vector[%d] := %d is wrong!!\n",i+1,(*repvector)[i]);
+      }
+    }
+  }
+  if(Overflow_Error == TRUE)
+  {
+    ivString(repvector, "repvector");
+    Print("\n// %d element(s) of it are overflow!!", ntrue);
+  }
+
+  if(Overflow_Error == FALSE)
+    Overflow_Error = nError;
+
+  mpz_clear(sing_int);
+  mpz_clear(ztmp);
+  omFree(ivtmp);
+  omFree(ivres);
+  return repvector;
+}
+#endif
+
+/*****************************************************************************
+ * The following subroutine is the implementation of our first improved      *
+ * Groebner walk algorithm, i.e. the first altervative algorithm.            *
+ * First we use the Grobner walk algorithm and then we call the changed      *
+ * perturbation walk algorithm with decreased degree, if an intermediate     *
+ * weight vector is equal to the current target weight vector.               *
+ * This call will be only repeated until we get the wanted reduced Groebner  *
+ * basis or n times, where n is the numbers of variables.                    *
+ *****************************************************************************/
+
+//unused
+#if 0
+static int testnegintvec(intvec* v)
+{
+  int n = v->length();
+  int i;
+  for(i=0; i<n; i++)
+  {
+    if((*v)[i]<0)
+    {
+      return(1);
+    }
+  }
+  return(0);
+}
+#endif
+
+// npwinc = 0, if curr_weight doesn't stay in the correct Groebner cone
+static ideal Rec_LastGB(ideal G, intvec* curr_weight,
+                        intvec* orig_target_weight, int tp_deg, int npwinc)
+{
+  BOOLEAN nError = Overflow_Error;
+  Overflow_Error = FALSE;
+  // BOOLEAN nOverflow_Error = FALSE;
+
+  clock_t tproc=0;
+  clock_t tinput = clock();
+
+  int i,  nV = currRing->N;
+  int nwalk=0, endwalks=0, nnwinC=1;
+  int nlast = 0;
+  ideal Gomega, M, F, Gomega1, Gomega2, M1,F1,result,ssG;
+  ring newRing, oldRing, TargetRing;
+  intvec* iv_M_lp;
+  intvec* target_weight;
+  intvec* ivNull = new intvec(nV); //define (0,...,0)
+  ring EXXRing = currRing;
+  //int NEG=0; //19 juni 03
+  intvec* next_weight;
+#ifndef  BUCHBERGER_ALG
+  //08 Juli 03
+  intvec* hilb_func;
+#endif
+  // to avoid (1,0,...,0) as the target vector
+  intvec* last_omega = new intvec(nV);
+  for(i=nV-1; i>0; i--)
+    (*last_omega)[i] = 1;
+  (*last_omega)[0] = 10000;
+
+  BOOLEAN isGB = FALSE;
+
+  // compute a pertubed weight vector of the target weight vector
+  if(tp_deg > 1 && tp_deg <= nV)
+  {
+    ideal H0 = idHeadCC(G);
+
+    if (rParameter (currRing) != NULL)
+    {
+      DefRingParlp();
+    }
+    else
+    {
+      VMrDefaultlp();
+    }
+    TargetRing = currRing;
+    ssG = idrMoveR(G,EXXRing,currRing);
+
+    ideal H0_tmp = idrMoveR(H0,EXXRing,currRing);
+    ideal H1 = idHeadCC(ssG);
+
+    // Apply Lemma 2.2 in Collart et. al (1997) to check whether cone(k-1) is equal to cone(k)
+    if(test_G_GB_walk(H0_tmp,H1)==1)
+    {
+      idDelete(&H0_tmp);
+      idDelete(&H1);
+      G = ssG;
+      ssG = NULL;
+      newRing = currRing;
+      delete ivNull;
+
+      if(npwinc != 0)
+      {
+        goto LastGB_Finish;
+      }
+      else
+      {
+        isGB = TRUE;
+        goto KSTD_Finish;
+      }
+    }
+    idDelete(&H0_tmp);
+    idDelete(&H1);
+
+    iv_M_lp = MivMatrixOrderlp(nV);
+    target_weight  = MPertVectors(ssG, iv_M_lp, tp_deg);
+    delete iv_M_lp;
+    //PrintS("\n// Input is not GB!!");
+    rChangeCurrRing(EXXRing);
+    G = idrMoveR(ssG, TargetRing,currRing);
+
+    if(Overflow_Error == TRUE)
+    {
+      //nOverflow_Error = Overflow_Error;
+      //NEG = 1;
+      newRing = currRing;
+      goto JUNI_STD;
+    }
+  }
+
+  while(1)
+  {
+    nwalk ++;
+    nstep++;
+
+    if(nwalk==1)
+    {
+      goto FIRST_STEP;
+    }
+    to=clock();
+    // compute an initial form ideal of <G> w.r.t. "curr_vector"
+    Gomega = MwalkInitialForm(G, curr_weight);
+    xtif=xtif+clock()-to;
+
+#ifndef  BUCHBERGER_ALG
+    if(isNolVector(curr_weight) == 0)
+    {
+      hilb_func = hFirstSeries(Gomega,NULL,NULL,curr_weight,currRing);
+    }
+    else
+    {
+      hilb_func = hFirstSeries(Gomega,NULL,NULL,last_omega,currRing);
+    }
+#endif // BUCHBERGER_ALG
+
+    oldRing = currRing;
+
+    // defiNe a new ring that its ordering is "(a(curr_weight),lp)
+    if (rParameter(currRing) != NULL)
+    {
+      DefRingPar(curr_weight);
+    }
+    else
+    {
+      rChangeCurrRing(VMrDefault(curr_weight)); //Aenderung
+    }
+    newRing = currRing;
+    Gomega1 = idrMoveR(Gomega, oldRing,currRing);
+    to=clock();
+    // compute a reduced Groebner basis of <Gomega> w.r.t. "newRing"
+#ifdef  BUCHBERGER_ALG
+    M = MstdhomCC(Gomega1);
+#else
+    M=kStd(Gomega1,NULL,isHomog,NULL,hilb_func,0,NULL,curr_weight);
+    delete hilb_func;
+#endif // BUCHBERGER_ALG
+    xtstd=xtstd+clock()-to;
+    // change the ring to oldRing
+    rChangeCurrRing(oldRing);
+    M1 =  idrMoveR(M, newRing,currRing);
+    Gomega2 =  idrMoveR(Gomega1, newRing,currRing);
+
+     to=clock();
+    // compute a reduced Groebner basis of <G> w.r.t. "newRing" by the lifting process
+    F = MLifttwoIdeal(Gomega2, M1, G);
+    xtlift=xtlift+clock()-to;
+    idDelete(&M1);
+    idDelete(&Gomega2);
+    idDelete(&G);
+
+    // change the ring to newRing
+    rChangeCurrRing(newRing);
+    F1 = idrMoveR(F, oldRing,currRing);
+
+    to=clock();
+    // reduce the Groebner basis <G> w.r.t. new ring
+    G = kInterRedCC(F1, NULL);
+    xtred=xtred+clock()-to;
+    idDelete(&F1);
+
+    if(endwalks == 1)
+    {
+      break;
+    }
+  FIRST_STEP:
+    to=clock();
+    Overflow_Error = FALSE;
+    // compute a next weight vector
+    next_weight = MkInterRedNextWeight(curr_weight,target_weight, G);
+    xtnw=xtnw+clock()-to;
+#ifdef PRINT_VECTORS
+    MivString(curr_weight, target_weight, next_weight);
+#endif
+
+    if(Overflow_Error == TRUE)
+    {
+      //PrintS("\n// ** The next vector does NOT stay in Cone!!\n");
+#ifdef TEST_OVERFLOW
+      goto  LastGB_Finish;
+#endif
+
+      nnwinC = 0;
+      if(tp_deg == nV)
+      {
+        nlast = 1;
+      }
+      delete next_weight;
+      break;
+    }
+
+    if(MivComp(next_weight, ivNull) == 1)
+    {
+      //newRing = currRing;
+      delete next_weight;
+      break;
+    }
+
+    if(MivComp(next_weight, target_weight) == 1)
+    {
+      if(tp_deg == nV)
+      {
+        endwalks = 1;
+      }
+      else
+      {
+        // REC_LAST_GB_ALT2:
+        //nOverflow_Error = Overflow_Error;
+        tproc=tproc+clock()-tinput;
+        /*
+          Print("\n// takes %d steps and calls \"Rec_LastGB\" (%d):",
+          nwalk, tp_deg+1);
+        */
+        G = Rec_LastGB(G,curr_weight, orig_target_weight, tp_deg+1,nnwinC);
+        newRing = currRing;
+        delete next_weight;
+        break;
+      }
+    }
+
+    for(i=nV-1; i>=0; i--)
+    {
+      (*curr_weight)[i] = (*next_weight)[i];
+    }
+    delete next_weight;
+  }//while
+
+  delete ivNull;
+
+  if(tp_deg != nV)
+  {
+    newRing = currRing;
+
+    if (rParameter(currRing) != NULL)
+    {
+      DefRingParlp();
+    }
+    else
+    {
+      VMrDefaultlp();
+    }
+    F1 = idrMoveR(G, newRing,currRing);
+
+    if(nnwinC == 0 || test_w_in_ConeCC(F1, target_weight) != 1 )
+    {
+      // nOverflow_Error = Overflow_Error;
+      //Print("\n//  takes %d steps and calls \"Rec_LastGB (%d):", tp_deg+1);
+      tproc=tproc+clock()-tinput;
+      F1 = Rec_LastGB(F1,curr_weight, orig_target_weight, tp_deg+1,nnwinC);
+    }
+    delete target_weight;
+
+    TargetRing = currRing;
+    rChangeCurrRing(EXXRing);
+    result = idrMoveR(F1, TargetRing,currRing);
+  }
+  else
+  {
+    if(nlast == 1)
+    {
+      JUNI_STD:
+
+      newRing = currRing;
+      if (rParameter(currRing) != NULL)
+      {
+        DefRingParlp();
+      }
+      else
+      {
+        VMrDefaultlp();
+      }
+      KSTD_Finish:
+      if(isGB == FALSE)
+      {
+        F1 = idrMoveR(G, newRing,currRing);
+      }
+      else
+      {
+        F1 = G;
+      }
+      to=clock();
+      // Print("\n// apply the Buchberger's alg in ring = %s",rString(currRing));
+      // idElements(F1, "F1");
+      G = MstdCC(F1);
+      xtextra=xtextra+clock()-to;
+
+
+      idDelete(&F1);
+      newRing = currRing;
+    }
+
+    LastGB_Finish:
+    rChangeCurrRing(EXXRing);
+    result = idrMoveR(G, newRing,currRing);
+  }
+
+  if(Overflow_Error == FALSE)
+    {
+    Overflow_Error=nError;
+    }
+// Print("\n// \"Rec_LastGB\" (%d) took %d steps and %.2f sec.Overflow_Error (%d)", tp_deg, nwalk, ((double) tproc)/1000000, nOverflow_Error);
+  return(result);
+}
+
+/* The following subroutine is the implementation of our second improved
+   Groebner walk algorithm, i.e. the second altervative algorithm.
+   First we use the Grobner walk algorithm and then we call the changed
+   perturbation walk algorithm with increased degree, if an intermediate
+   weight vector is equal to the current target weight vector.
+   This call will be only repeated until we get the wanted reduced Groebner
+   basis or n times, where n is the numbers of variables.
+*/
+
+/******************************
+ * walk + recursive LastGB    *
+ ******************************/
+ideal MAltwalk2(ideal Go, intvec* curr_weight, intvec* target_weight)
+{
+  Set_Error(FALSE);
+  Overflow_Error = FALSE;
+  //BOOLEAN nOverflow_Error = FALSE;
+  //Print("// pSetm_Error = (%d)", ErrorCheck());
+
+  xtif=0; xtstd=0; xtlift=0; xtred=0; xtnw=0; xtextra=0;
+  xftinput = clock();
+  clock_t tostd, tproc;
+
+  nstep = 0;
+  int i, nV = currRing->N;
+  int nwalk=0, endwalks=0;
+  // int nhilb = 1;
+  ideal Gomega, M, F, Gomega1, Gomega2, M1, F1, G;
+  //ideal  G1;
+  //ring endRing;
+  ring newRing, oldRing;
+  intvec* ivNull = new intvec(nV);
+  intvec* next_weight;
+#if 0
+  intvec* extra_curr_weight = new intvec(nV);
+#endif
+  //intvec* hilb_func;
+  intvec* exivlp = Mivlp(nV);
+
+  ring XXRing = currRing;
+
+  //Print("\n// ring r_input = %s;", rString(currRing));
+  to = clock();
+  /* compute the reduced Groebner basis of the given ideal w.r.t.
+     a "fast" monomial order, e.g. degree reverse lex. order (dp) */
+  G = MstdCC(Go);
+  tostd=clock()-to;
+
+  /*
+  Print("\n// Computation of the first std took = %.2f sec",
+        ((double) tostd)/1000000);
+  */
+  if(currRing->order[0] == ringorder_a)
+  {
+    goto NEXT_VECTOR;
+  }
+  while(1)
+  {
+    nwalk ++;
+    nstep ++;
+    to = clock();
+    /* compute an initial form ideal of <G> w.r.t. "curr_vector" */
+    Gomega = MwalkInitialForm(G, curr_weight);
+    xtif=xtif+clock()-to;
+#if 0
+    if(Overflow_Error == TRUE)
+    {
+      for(i=nV-1; i>=0; i--)
+        (*curr_weight)[i] = (*extra_curr_weight)[i];
+      delete extra_curr_weight;
+      goto LAST_GB_ALT2;
+    }
+#endif
+    oldRing = currRing;
+
+    /* define a new ring that its ordering is "(a(curr_weight),lp) */
+    if (rParameter(currRing) != NULL)
+    {
+      DefRingPar(curr_weight);
+    }
+    else
+    {
+      rChangeCurrRing(VMrDefault(curr_weight)); // Aenderung
+    }
+    newRing = currRing;
+    Gomega1 = idrMoveR(Gomega, oldRing,currRing);
+    to = clock();
+    /* compute a reduced Groebner basis of <Gomega> w.r.t. "newRing" */
+    M = MstdhomCC(Gomega1);
+    xtstd=xtstd+clock()-to;
+    /* change the ring to oldRing */
+    rChangeCurrRing(oldRing);
+    M1 =  idrMoveR(M, newRing,currRing);
+    Gomega2 =  idrMoveR(Gomega1, newRing,currRing);
+
+    to = clock();
+    /* compute the reduced Groebner basis of <G> w.r.t. "newRing"
+       by the liftig process */
+    F = MLifttwoIdeal(Gomega2, M1, G);
+    xtlift=xtlift+clock()-to;
+    idDelete(&M1);
+    idDelete(&Gomega2);
+    idDelete(&G);
+
+    /* change the ring to newRing */
+    rChangeCurrRing(newRing);
+    F1 = idrMoveR(F, oldRing,currRing);
+
+    to = clock();
+    /* reduce the Groebner basis <G> w.r.t. newRing */
+    G = kInterRedCC(F1, NULL);
+    xtred=xtred+clock()-to;
+    idDelete(&F1);
+
+    if(endwalks == 1)
+      break;
+
+  NEXT_VECTOR:
+    to = clock();
+    /* compute a next weight vector */
+    next_weight = MkInterRedNextWeight(curr_weight,target_weight, G);
+    xtnw=xtnw+clock()-to;
+#ifdef PRINT_VECTORS
+    MivString(curr_weight, target_weight, next_weight);
+#endif
+
+    if(Overflow_Error == TRUE)
+    {
+      /*
+        ivString(next_weight, "omega");
+        PrintS("\n// ** The weight vector does NOT stay in Cone!!\n");
+      */
+#ifdef TEST_OVERFLOW
+      goto  TEST_OVERFLOW_OI;
+#endif
+
+      newRing = currRing;
+      if (rParameter(currRing) != NULL)
+      {
+        DefRingPar(target_weight);
+      }
+      else
+      {
+        rChangeCurrRing(VMrDefault(target_weight)); // Aenderung
+      }
+      F1 = idrMoveR(G, newRing,currRing);
+      G = MstdCC(F1);
+      idDelete(&F1);
+      newRing = currRing;
+      break;
+    }
+
+    if(MivComp(next_weight, ivNull) == 1)
+    {
+      newRing = currRing;
+      delete next_weight;
+      break;
+    }
+
+    if(MivComp(next_weight, target_weight) == 1)
+    {
+      if(MivSame(target_weight, exivlp)==1)
+      {
+     // LAST_GB_ALT2:
+        //nOverflow_Error = Overflow_Error;
+        tproc = clock()-xftinput;
+        //Print("\n// takes %d steps and calls the recursion of level 2:",  nwalk);
+        /* call the changed perturbation walk algorithm with degree 2 */
+        G = Rec_LastGB(G, curr_weight, target_weight, 2,1);
+        newRing = currRing;
+        delete next_weight;
+        break;
+      }
+      endwalks = 1;
+    }
+
+    for(i=nV-1; i>=0; i--)
+    {
+      //(*extra_curr_weight)[i] = (*curr_weight)[i];
+      (*curr_weight)[i] = (*next_weight)[i];
+    }
+    delete next_weight;
+  }
+#ifdef TEST_OVERFLOW
+ TEST_OVERFLOW_OI:
+#endif
+  rChangeCurrRing(XXRing);
+  G = idrMoveR(G, newRing,currRing);
+  delete ivNull;
+  delete exivlp;
+
+#ifdef TIME_TEST
+ // Print("\n// \"Main procedure\"  took %d steps dnd %.2f sec. Overflow_Error (%d)", nwalk, ((double) tproc)/1000000, nOverflow_Error);
+
+  TimeStringFractal(xftinput, tostd, xtif, xtstd, xtextra,xtlift, xtred,xtnw);
+
+  Print("\n// pSetm_Error = (%d)", ErrorCheck());
+  //Print("\n// Overflow_Error? (%d)", nOverflow_Error);
+  Print("\n// Awalk2 took %d steps!!", nstep);
+#endif
+
+  return(G);
+}
+
+
+/**************************************
+ * perturb the matrix order of  "lex" *
+ **************************************/
+static intvec* NewVectorlp(ideal I)
+{
+  int nV = currRing->N;
+  intvec* iv_wlp =  MivMatrixOrderlp(nV);
+  intvec* result = Mfpertvector(I, iv_wlp);
+  delete iv_wlp;
+  return result;
+}
+
+int ngleich;
+intvec* Xsigma;
+intvec* Xtau;
+int xn;
+intvec* Xivinput;
+intvec* Xivlp;
+
+#if 0
+/********************************
+ * compute a next weight vector *
+ ********************************/
+static intvec* MWalkRandomNextWeight(ideal G, intvec* curr_weight, intvec* target_weight, int weight_rad, int pert_deg)
+{
+  int i, weight_norm;
+  int nV = currRing->N;
+  intvec* next_weight2;
+  intvec* next_weight22 = new intvec(nV);
+  intvec* next_weight = MwalkNextWeightCC(curr_weight,target_weight, G);
+  if(MivComp(next_weight, target_weight) == 1)
+  {
+    return(next_weight);
+  }
+  else
+  {
+    //compute a perturbed next weight vector "next_weight1"
+    intvec* next_weight1 = MkInterRedNextWeight(MPertVectors(G, MivMatrixOrder(curr_weight), pert_deg), target_weight, G);
+    //Print("\n // size of next_weight1 = %d", sizeof((*next_weight1)));
+
+    //compute a random next weight vector "next_weight2"
+    while(1)
+    {
+      weight_norm = 0;
+      while(weight_norm == 0)
+      {
+        for(i=0; i<nV; i++)
+        {
+          //Print("\n//  next_weight[%d]  = %d", i, (*next_weight)[i]);
+          (*next_weight22)[i] = rand() % 60000 - 30000;
+          weight_norm = weight_norm + (*next_weight22)[i]*(*next_weight22)[i];
+        }
+        weight_norm = 1 + floor(sqrt(weight_norm));
+      }
+
+      for(i=nV-1; i>=0; i--)
+      {
+        if((*next_weight22)[i] < 0)
+        {
+          (*next_weight22)[i] = 1 + (*curr_weight)[i] + floor(weight_rad*(*next_weight22)[i]/weight_norm);
+        }
+        else
+        {
+          (*next_weight22)[i] = (*curr_weight)[i] + floor(weight_rad*(*next_weight22)[i]/weight_norm);
+        }
+      //Print("\n//  next_weight22[%d]  = %d", i, (*next_weight22)[i]);
+      }
+
+      if(test_w_in_ConeCC(G, next_weight22) == 1)
+      {
+        //Print("\n//MWalkRandomNextWeight: next_weight2 im Kegel\n");
+        next_weight2 = MkInterRedNextWeight(next_weight22, target_weight, G);
+        delete next_weight22;
+        break;
+      }
+    }
+    intvec* result = new intvec(nV);
+    ideal G_test = MwalkInitialForm(G, next_weight);
+    ideal G_test1 = MwalkInitialForm(G, next_weight1);
+    ideal G_test2 = MwalkInitialForm(G, next_weight2);
+
+    // compare next_weights
+    if(IDELEMS(G_test1) < IDELEMS(G_test))
+    {
+      if(IDELEMS(G_test2) <= IDELEMS(G_test1)) // |G_test2| <= |G_test1| < |G_test|
+      {
+        for(i=0; i<nV; i++)
+        {
+          (*result)[i] = (*next_weight2)[i];
+        }
+      }
+      else // |G_test1| < |G_test|, |G_test1| < |G_test2|
+      {
+        for(i=0; i<nV; i++)
+        {
+          (*result)[i] = (*next_weight1)[i];
+        }
+      }
+    }
+    else
+    {
+      if(IDELEMS(G_test2) <= IDELEMS(G_test)) // |G_test2| <= |G_test| <= |G_test1|
+      {
+        for(i=0; i<nV; i++)
+        {
+          (*result)[i] = (*next_weight2)[i];
+        }
+      }
+      else // |G_test| <= |G_test1|, |G_test| < |G_test2|
+      {
+        for(i=0; i<nV; i++)
+        {
+          (*result)[i] = (*next_weight)[i];
+        }
+      }
+    }
+    delete next_weight;
+    delete next_weight1;
+    idDelete(&G_test);
+    idDelete(&G_test1);
+    idDelete(&G_test2);
+    if(test_w_in_ConeCC(G, result) == 1)
+    {
+      delete next_weight2;
+      return result;
+    }
+    else
+    {
+      delete result;
+      return next_weight2;
+    }
+  }
+}
+#endif
+
+/********************************
+ * compute a next weight vector *
+ ********************************/
+static intvec* MWalkRandomNextWeight(ideal G, intvec* curr_weight, intvec* target_weight, int weight_rad, int pert_deg)
+{
+  int i, weight_norm;
+  //int randCount=0;
+  int nV = currRing->N;
+  intvec* next_weight2;
+  intvec* next_weight22 = new intvec(nV);
+  intvec* result = new intvec(nV);
+
+  //compute a perturbed next weight vector "next_weight1"
+  //intvec* next_weight1 = MkInterRedNextWeight(MPertVectors(G,MivMatrixOrderRefine(curr_weight,target_weight),pert_deg),target_weight,G);
+  intvec* next_weight1 =MkInterRedNextWeight(curr_weight,target_weight,G);
+  //compute a random next weight vector "next_weight2"
+  while(1)
+  {
+    weight_norm = 0;
+    while(weight_norm == 0)
+    {
+      for(i=0; i<nV; i++)
+      {
+        (*next_weight22)[i] = rand() % 60000 - 30000;
+        weight_norm = weight_norm + (*next_weight22)[i]*(*next_weight22)[i];
+      }
+      weight_norm = 1 + floor(sqrt(weight_norm));
+    }
+    for(i=0; i<nV; i++)
+    {
+      if((*next_weight22)[i] < 0)
+      {
+        (*next_weight22)[i] = 1 + (*curr_weight)[i] + floor(weight_rad*(*next_weight22)[i]/weight_norm);
+      }
+      else
+      {
+        (*next_weight22)[i] = (*curr_weight)[i] + floor(weight_rad*(*next_weight22)[i]/weight_norm);
+      }
+    }
+    if(test_w_in_ConeCC(G, next_weight22) == 1)
+    {
+      next_weight2 = MkInterRedNextWeight(next_weight22,target_weight,G);
+      delete next_weight22;
+      break;
+    }
+  }
+  // compute "usual" next weight vector
+  intvec* next_weight = MwalkNextWeightCC(curr_weight,target_weight, G);
+  ideal G_test = MwalkInitialForm(G, next_weight);
+  ideal G_test2 = MwalkInitialForm(G, next_weight2);
+
+  // compare next weights
+  if(Overflow_Error == FALSE)
+  {
+    ideal G_test1 = MwalkInitialForm(G, next_weight1);
+    if(IDELEMS(G_test1) < IDELEMS(G_test))
+    {
+      if(IDELEMS(G_test2) < IDELEMS(G_test1))
+      {
+        // |G_test2| < |G_test1| < |G_test|
+        for(i=0; i<nV; i++)
+        {
+          (*result)[i] = (*next_weight2)[i];
+        }
+      }
+      else
+      {
+        // |G_test1| < |G_test|, |G_test1| <= |G_test2|
+        for(i=0; i<nV; i++)
+        {
+          (*result)[i] = (*next_weight1)[i];
+        }
+      }
+    }
+    else
+    {
+      if(IDELEMS(G_test2) < IDELEMS(G_test)) // |G_test2| < |G_test| <= |G_test1|
+      {
+        for(i=0; i<nV; i++)
+        {
+          (*result)[i] = (*next_weight2)[i];
+        }
+      }
+      else
+      {
+        // |G_test| < |G_test1|, |G_test| <= |G_test2|
+        for(i=0; i<nV; i++)
+        {
+          (*result)[i] = (*next_weight)[i];
+        }
+      }
+    }
+    idDelete(&G_test1);
+  }
+  else
+  {
+    Overflow_Error = FALSE;
+    if(IDELEMS(G_test2) < IDELEMS(G_test))
+    {
+      for(i=1; i<nV; i++)
+      {
+        (*result)[i] = (*next_weight2)[i];
+      }
+    }
+    else
+    {
+      for(i=0; i<nV; i++)
+      {
+        (*result)[i] = (*next_weight)[i];
+      }
+    }
+  }
+  idDelete(&G_test);
+  idDelete(&G_test2);
+  if(test_w_in_ConeCC(G, result) == 1)
+  {
+    delete next_weight2;
+    delete next_weight;
+    delete next_weight1;
+    return result;
+  }
+  else
+  {
+    delete result;
+    delete next_weight2;
+    delete next_weight1;
+    return next_weight;
+  }
+}
+
+
+/***************************************************************************
+ * The procedur REC_GB_Mwalk computes a GB for <G> w.r.t. the weight order *
+ * otw, where G is a reduced GB w.r.t. the weight order cw.                *
+ * The new procedur Mwalk calls REC_GB.                                    *
+ ***************************************************************************/
+static ideal REC_GB_Mwalk(ideal G, intvec* curr_weight, intvec* orig_target_weight,
+                          int tp_deg, int npwinc)
+{
+  BOOLEAN nError = Overflow_Error;
+  Overflow_Error = FALSE;
+
+  int i,  nV = currRing->N;
+  int nwalk=0, endwalks=0, nnwinC=1, nlast = 0;
+  ideal Gomega, M, F, Gomega1, Gomega2, M1,F1,result,ssG;
+  ring newRing, oldRing, TargetRing;
+  intvec* target_weight;
+  intvec* ivNull = new intvec(nV);
+#ifndef BUCHBERGER_ALG
+  intvec* hilb_func;
+  // to avoid (1,0,...,0) as the target vector
+  intvec* last_omega = new intvec(nV);
+  for(i=nV-1; i>0; i--)
+  {
+    (*last_omega)[i] = 1;
+  }
+  (*last_omega)[0] = 10000;
+#endif
+  BOOLEAN isGB = FALSE;
+
+  ring EXXRing = currRing;
+
+  // compute a pertubed weight vector of the target weight vector
+  if(tp_deg > 1 && tp_deg <= nV)
+  {
+    ideal H0 = idHeadCC(G);
+    if (rParameter(currRing) != NULL)
+    {
+      DefRingPar(orig_target_weight);
+    }
+    else
+    {
+      rChangeCurrRing(VMrDefault(orig_target_weight)); // Aenderung
+    }
+    TargetRing = currRing;
+    ssG = idrMoveR(G,EXXRing,currRing);
+
+    ideal H0_tmp = idrMoveR(H0,EXXRing,currRing);
+    ideal H1 = idHeadCC(ssG);
+    id_Delete(&H0,EXXRing);
+
+    if(test_G_GB_walk(H0_tmp,H1)==1)
+    {
+      //Print("\n//REC_GB_Mwalk: input in %d-th recursive is a GB!\n",tp_deg);
+      idDelete(&H0_tmp);
+      idDelete(&H1);
+      G = ssG;
+      ssG = NULL;
+      newRing = currRing;
+      delete ivNull;
+      if(npwinc == 0)
+      {
+        isGB = TRUE;
+        goto KSTD_Finish;
+      }
+      else
+      {
+        goto LastGB_Finish;
+      }
+    }
+    idDelete(&H0_tmp);
+    idDelete(&H1);
+
+    target_weight  = MPertVectors(ssG, MivMatrixOrder(orig_target_weight), tp_deg);
+
+    rChangeCurrRing(EXXRing);
+    G = idrMoveR(ssG, TargetRing,currRing);
+  }
+
+  while(1)
+  {
+    nwalk ++;
+    nstep++;
+    if(nwalk == 1)
+    {
+      goto NEXT_STEP;
+    }
+    //Print("\n//REC_GB_Mwalk: Entering the %d-th step in the %d-th recursive:\n",nwalk,tp_deg);
+    to = clock();
+    // compute an initial form ideal of <G> w.r.t. "curr_vector"
+    Gomega = MwalkInitialForm(G, curr_weight);
+    xtif = xtif + clock()-to;
+
+#ifndef  BUCHBERGER_ALG
+    if(isNolVector(curr_weight) == 0)
+    {
+      hilb_func = hFirstSeries(Gomega,NULL,NULL,curr_weight,currRing);
+    }
+    else
+    {
+      hilb_func = hFirstSeries(Gomega,NULL,NULL,last_omega,currRing);
+    }
+#endif
+
+    oldRing = currRing;
+
+    // define a new ring with ordering "(a(curr_weight),lp)
+    if (rParameter(currRing) != NULL)
+    {
+      DefRingPar(curr_weight);
+    }
+    else
+    {
+      rChangeCurrRing(VMrDefault(curr_weight)); // Aenderung
+    }
+    newRing = currRing;
+    Gomega1 = idrMoveR(Gomega, oldRing,currRing);
+
+    to = clock();
+    // compute a reduced Groebner basis of <Gomega> w.r.t. "newRing"
+#ifdef  BUCHBERGER_ALG
+    M = MstdhomCC(Gomega1);
+#else
+    M=kStd(Gomega1,NULL,isHomog,NULL,hilb_func,0,NULL,curr_weight);
+    delete hilb_func;
+#endif
+    xtstd = xtstd + clock() - to;
+
+    // change the ring to oldRing
+    rChangeCurrRing(oldRing);
+
+    M1 =  idrMoveR(M, newRing,currRing);
+    Gomega2 =  idrMoveR(Gomega1, newRing,currRing);
+
+    to = clock();
+    F = MLifttwoIdeal(Gomega2, M1, G);
+    xtlift = xtlift + clock() -to;
+
+    idDelete(&M1);
+    idDelete(&Gomega2);
+    idDelete(&G);
+
+
+    // change the ring to newRing
+    rChangeCurrRing(newRing);
+    F1 = idrMoveR(F, oldRing,currRing);
+
+    to = clock();
+    // reduce the Groebner basis <G> w.r.t. new ring
+    G = kInterRedCC(F1, NULL);
+    xtred = xtred + clock() -to;
+
+    idDelete(&F1);
+
+    if(endwalks == 1)
+    {
+      break;
+    }
+  NEXT_STEP:
+    to = clock();
+    // compute a next weight vector
+    intvec* next_weight = MkInterRedNextWeight(curr_weight,target_weight, G);
+
+
+    xtnw = xtnw + clock() - to;
+
+#ifdef PRINT_VECTORS
+    MivString(curr_weight, target_weight, next_weight);
+#endif
+
+    if(Overflow_Error == TRUE)
+    {
+      //PrintS("\n//REC_GB_Mwalk: The computed vector does NOT stay in the correct cone!!\n");
+      nnwinC = 0;
+      if(tp_deg == nV)
+      {
+        nlast = 1;
+      }
+      delete next_weight;
+      break;
+    }
+    if(MivComp(next_weight, ivNull) == 1)
+    {
+      newRing = currRing;
+      delete next_weight;
+      break;
+    }
+
+    if(MivComp(next_weight, target_weight) == 1)
+    {
+      if(tp_deg == nV)
+      {
+        endwalks = 1;
+      }
+      else
+      {
+        G = REC_GB_Mwalk(G,curr_weight, orig_target_weight, tp_deg+1,nnwinC);
+        newRing = currRing;
+        delete next_weight;
+        break;
+      }
+    }
+
+    for(i=nV-1; i>=0; i--)
+    {
+      (*curr_weight)[i] = (*next_weight)[i];
+    }
+    delete next_weight;
+  }
+
+  delete ivNull;
+
+  if(tp_deg != nV)
+  {
+    newRing = currRing;
+
+    if (rParameter(currRing) != NULL)
+    {
+      DefRingPar(orig_target_weight);
+    }
+    else
+    {
+      rChangeCurrRing(VMrDefault(orig_target_weight)); // Aenderung
+    }
+    F1 = idrMoveR(G, newRing,currRing);
+
+    if(nnwinC == 0)
+    {
+      F1 = REC_GB_Mwalk(F1,curr_weight, orig_target_weight, tp_deg+1,nnwinC);
+    }
+    else
+    {
+      if(test_w_in_ConeCC(F1, target_weight) != 1)
+      {
+        F1 = REC_GB_Mwalk(F1,curr_weight, orig_target_weight,tp_deg+1,nnwinC);
+      }
+    }
+    delete target_weight;
+
+    TargetRing = currRing;
+    rChangeCurrRing(EXXRing);
+    result = idrMoveR(F1, TargetRing,currRing);
+  }
+  else
+  {
+    if(nlast == 1)
+    {
+      if (rParameter(currRing) != NULL)
+      {
+        DefRingPar(orig_target_weight);
+      }
+      else
+      {
+        rChangeCurrRing(VMrDefault(orig_target_weight)); // Aenderung
+      }
+    KSTD_Finish:
+      if(isGB == FALSE)
+      {
+        F1 = idrMoveR(G, newRing,currRing);
+      }
+      else
+      {
+        F1 = G;
+      }
+      to=clock();
+      // apply Buchberger alg to compute a red. GB of F1
+      G = MstdCC(F1);
+      xtextra=clock()-to;
+      idDelete(&F1);
+      newRing = currRing;
+    }
+
+  LastGB_Finish:
+    rChangeCurrRing(EXXRing);
+    result = idrMoveR(G, newRing,currRing);
+  }
+
+  if(Overflow_Error == FALSE)
+    {
+    Overflow_Error = nError;
+    }
+#ifndef BUCHBERGER_ALG
+  delete last_omega;
+#endif
+  return(result);
+}
+
+
+// THE NEW GROEBNER WALK ALGORITHM
+// Groebnerwalk with a recursive "second" alternative GW, called REC_GB_Mwalk that only computes the last reduced GB
+ideal MwalkAlt(ideal Go, intvec* curr_weight, intvec* target_weight)
+{
+  Set_Error(FALSE);
+  Overflow_Error = FALSE;
+  //Print("// pSetm_Error = (%d)", ErrorCheck());
+
+  clock_t tinput, tostd, tif=0, tstd=0, tlift=0, tred=0, tnw=0;
+  xtif=0; xtstd=0; xtlift=0; xtred=0; xtnw=0;
+  tinput = clock();
+  clock_t tim;
+  nstep=0;
+  int i;
+  int nV = currRing->N;
+  int nwalk=0;
+  int endwalks=0;
+
+  ideal Gomega, M, F, Gomega1, Gomega2, M1, F1, G;
+  //ideal G1;
+  //ring endRing;
+  ring newRing, oldRing;
+  intvec* ivNull = new intvec(nV);
+  intvec* exivlp = Mivlp(nV);
+#ifndef BUCHBERGER_ALG
+  intvec* hilb_func;
+#endif
+  intvec* tmp_weight = new intvec(nV);
+  for(i=nV-1; i>=0; i--)
+    (*tmp_weight)[i] = (*curr_weight)[i];
+
+   // to avoid (1,0,...,0) as the target vector
+  intvec* last_omega = new intvec(nV);
+  for(i=nV-1; i>0; i--)
+    (*last_omega)[i] = 1;
+  (*last_omega)[0] = 10000;
+
+  ring XXRing = currRing;
+
+  to = clock();
+  // the monomial ordering of this current ring would be "dp"
+  G = MstdCC(Go);
+  tostd = clock()-to;
+
+  if(currRing->order[0] == ringorder_a)
+    goto NEXT_VECTOR;
+
+  while(1)
+  {
+    nwalk ++;
+    nstep ++;
+    to = clock();
+    // compute an initial form ideal of <G> w.r.t. "curr_vector"
+    Gomega = MwalkInitialForm(G, curr_weight);
+    tif = tif + clock()-to;
+    oldRing = currRing;
+
+    if(endwalks == 1)
+    {
+      /* compute a reduced Groebner basis of Gomega w.r.t. >>_cw by
+         the recursive changed perturbation walk alg. */
+      tim = clock();
+      /*
+        Print("\n// **** Gr�bnerwalk took %d steps and ", nwalk);
+        PrintS("\n// **** call the rec. Pert. Walk to compute a red GB of:");
+        idElements(Gomega, "G_omega");
+      */
+
+      if(MivSame(exivlp, target_weight)==1)
+        M = REC_GB_Mwalk(idCopy(Gomega), tmp_weight, curr_weight, 2,1);
+      else
+        goto NORMAL_GW;
+      /*
+        Print("\n//  time for the last std(Gw)  = %.2f sec",
+        ((double) (clock()-tim)/1000000));
+        PrintS("\n// ***************************************************\n");
+      */
+#ifdef CHECK_IDEAL_MWALK
+      idElements(Gomega, "G_omega");
+      headidString(Gomega, "Gw");
+      idElements(M, "M");
+      //headidString(M, "M");
+#endif
+      to = clock();
+      F = MLifttwoIdeal(Gomega, M, G);
+      xtlift = xtlift + clock() - to;
+
+      idDelete(&Gomega);
+      idDelete(&M);
+      idDelete(&G);
+
+      oldRing = currRing;
+
+      /* create a new ring newRing */
+       if (rParameter(currRing) != NULL)
+       {
+         DefRingPar(curr_weight);
+       }
+       else
+       {
+         rChangeCurrRing(VMrDefault(curr_weight)); // Aenderung
+       }
+      newRing = currRing;
+      F1 = idrMoveR(F, oldRing,currRing);
+    }
+    else
+    {
+    NORMAL_GW:
+#ifndef  BUCHBERGER_ALG
+      if(isNolVector(curr_weight) == 0)
+      {
+        hilb_func = hFirstSeries(Gomega,NULL,NULL,curr_weight,currRing);
+      }
+      else
+      {
+        hilb_func = hFirstSeries(Gomega,NULL,NULL,last_omega,currRing);
+      }
+#endif // BUCHBERGER_ALG
+
+      // define a new ring that its ordering is "(a(curr_weight),lp)
+      if (rParameter(currRing) != NULL)
+      {
+        DefRingPar(curr_weight);
+      }
+      else
+      {
+        rChangeCurrRing(VMrDefault(curr_weight));  //Aenderung
+      }
+      newRing = currRing;
+      Gomega1 = idrMoveR(Gomega, oldRing,currRing);
+
+      to = clock();
+      // compute a reduced Groebner basis of <Gomega> w.r.t. "newRing"
+#ifdef  BUCHBERGER_ALG
+      M = MstdhomCC(Gomega1);
+#else
+      M=kStd(Gomega1,NULL,isHomog,NULL,hilb_func,0,NULL,curr_weight);
+      delete hilb_func;
+#endif // BUCHBERGER_ALG
+      tstd = tstd + clock() - to;
+
+      // change the ring to oldRing
+      rChangeCurrRing(oldRing);
+      M1 =  idrMoveR(M, newRing,currRing);
+      Gomega2 =  idrMoveR(Gomega1, newRing,currRing);
+
+      to = clock();
+      // compute a representation of the generators of submod (M) with respect to those of mod (Gomega). Gomega is a reduced Groebner basis w.r.t. the current ring.
+      F = MLifttwoIdeal(Gomega2, M1, G);
+      tlift = tlift + clock() - to;
+
+      idDelete(&M1);
+      idDelete(&Gomega2);
+      idDelete(&G);
+
+      // change the ring to newRing
+      rChangeCurrRing(newRing);
+      F1 = idrMoveR(F, oldRing,currRing);
+    }
+
+    to = clock();
+    // reduce the Groebner basis <G> w.r.t. new ring
+    G = kInterRedCC(F1, NULL);
+    if(endwalks != 1)
+    {
+      tred = tred + clock() - to;
+    }
+    else
+    {
+      xtred = xtred + clock() - to;
+    }
+    idDelete(&F1);
+    if(endwalks == 1)
+    {
+      break;
+    }
+  NEXT_VECTOR:
+    to = clock();
+    // compute a next weight vector
+    intvec* next_weight = MkInterRedNextWeight(curr_weight,target_weight,G);
+    tnw = tnw + clock() - to;
+#ifdef PRINT_VECTORS
+    MivString(curr_weight, target_weight, next_weight);
+#endif
+
+    //if(test_w_in_ConeCC(G, next_weight) != 1)
+    if(Overflow_Error == TRUE)
+    {
+      newRing = currRing;
+      PrintS("\n// ** The computed vector does NOT stay in Cone!!\n");
+
+      if (rParameter(currRing) != NULL)
+      {
+        DefRingPar(target_weight);
+      }
+      else
+      {
+        rChangeCurrRing(VMrDefault(target_weight)); // Aenderung
+      }
+      F1 = idrMoveR(G, newRing,currRing);
+      G = MstdCC(F1);
+      idDelete(&F1);
+
+      newRing = currRing;
+      break;
+    }
+
+    if(MivComp(next_weight, ivNull) == 1)
+    {
+      newRing = currRing;
+      delete next_weight;
+      break;
+    }
+    if(MivComp(next_weight, target_weight) == 1)
+    {
+      endwalks = 1;
+    }
+    for(i=nV-1; i>=0; i--)
+    {
+      (*tmp_weight)[i] = (*curr_weight)[i];
+      (*curr_weight)[i] = (*next_weight)[i];
+    }
+    delete next_weight;
+  }
+  rChangeCurrRing(XXRing);
+  G = idrMoveR(G, newRing,currRing);
+
+  delete tmp_weight;
+  delete ivNull;
+  delete exivlp;
+
+#ifdef TIME_TEST
+  TimeString(tinput, tostd, tif, tstd, tlift, tred, tnw, nstep);
+
+  Print("\n// pSetm_Error = (%d)", ErrorCheck());
+  Print("\n// Overflow_Error? (%d)\n", Overflow_Error);
+#endif
+  return(G);
+}
+
+
+/*******************************
+ * THE GROEBNER WALK ALGORITHM *
+ *******************************/
+ideal Mwalk(ideal Go, intvec* orig_M, intvec* target_M, ring baseRing)
+{
+  BITSET save1 = si_opt_1; // save current options
+  //si_opt_1 &= (~Sy_bit(OPT_REDSB)); // no reduced Groebner basis
+  //si_opt_1 &= (~Sy_bit(OPT_REDTAIL)); // not tail reductions
+  //si_opt_1|=(Sy_bit(OPT_REDTAIL)|Sy_bit(OPT_REDSB));
+  Set_Error(FALSE);
+  Overflow_Error = FALSE;
+#ifdef TIME_TEST
+  clock_t tinput, tostd, tif=0, tstd=0, tlift=0, tred=0, tnw=0;
+  xtif=0; xtstd=0; xtlift=0; xtred=0; xtnw=0;
+  tinput = clock();
+  clock_t tim;
+#endif
+  nstep=0;
+  int i,nwalk,endwalks = 0;
+  int nV = baseRing->N;
+
+  ideal Gomega, M, F, Gomega1, Gomega2, M1; //, F1;
+  ring newRing;
+  ring XXRing = baseRing;
+  intvec* ivNull = new intvec(nV);
+  intvec* curr_weight = new intvec(nV);
+  intvec* target_weight = new intvec(nV);
+  intvec* exivlp = Mivlp(nV);
+  intvec* tmp_weight = new intvec(nV);
+  for(i=0; i<nV; i++)
+  {
+    (*tmp_weight)[i] = (*target_M)[i];
+  }
+  for(i=0; i<nV; i++)
+  {
+    (*curr_weight)[i] = (*orig_M)[i];
+    (*target_weight)[i] = (*target_M)[i];
+  }
+#ifndef BUCHBERGER_ALG
+  intvec* hilb_func;
+   // to avoid (1,0,...,0) as the target vector
+  intvec* last_omega = new intvec(nV);
+  for(i=nV-1; i>0; i--)
+  {
+    (*last_omega)[i] = 1;
+  }
+  (*last_omega)[0] = 10000;
+#endif
+  rComplete(currRing);
+#ifdef CHECK_IDEAL_MWALK
+    idString(Go,"Go");
+#endif
+#ifdef TIME_TEST
+  to = clock();
+#endif
+     if(orig_M->length() == nV)
+      {
+        newRing = VMrDefault(curr_weight); // define a new ring with ordering "(a(curr_weight),lp)
+      }
+      else
+      {
+        newRing = VMatrDefault(orig_M);
+      }
+  rChangeCurrRing(newRing);
+  ideal G = MstdCC(idrMoveR(Go,baseRing,currRing));
+  baseRing = currRing;
+#ifdef TIME_TEST
+  tostd = clock()-to;
+#endif
+
+  nwalk = 0;
+  while(1)
+  {
+    nwalk ++;
+    nstep ++;
+#ifdef TIME_TEST
+    to = clock();
+#endif
+#ifdef CHECK_IDEAL_MWALK
+    idString(G,"G");
+#endif
+    Gomega = MwalkInitialForm(G, curr_weight); // compute an initial form ideal of <G> w.r.t. "curr_vector"
+#ifdef TIME_TEST
+    tif = tif + clock()-to; //time for computing initial form ideal
+#endif
+#ifdef CHECK_IDEAL_MWALK
+    idString(Gomega,"Gomega");
+#endif
+#ifndef  BUCHBERGER_ALG
+    if(isNolVector(curr_weight) == 0)
+    {
+      hilb_func = hFirstSeries(Gomega,NULL,NULL,curr_weight,currRing);
+    }
+    else
+    {
+      hilb_func = hFirstSeries(Gomega,NULL,NULL,last_omega,currRing);
+    }
+#endif
+    if(nwalk == 1)
+    {
+      if(orig_M->length() == nV)
+      {
+        newRing = VMrDefault(curr_weight); // define a new ring with ordering "(a(curr_weight),lp)
+      }
+      else
+      {
+        newRing = VMatrDefault(orig_M);
+      }
+    }
+    else
+    {
+     if(target_M->length() == nV)
+     {
+       newRing = VMrRefine(curr_weight,target_weight); //define a new ring with ordering "(a(curr_weight),Wp(target_weight))"
+     }
+     else
+     {
+       newRing = VMatrRefine(target_M,curr_weight);
+     }
+    }
+    rChangeCurrRing(newRing);
+    Gomega1 = idrMoveR(Gomega, baseRing,currRing);
+    idDelete(&Gomega);
+    // compute a reduced Groebner basis of <Gomega> w.r.t. "newRing"
+#ifdef TIME_TEST
+    to = clock();
+#endif
+#ifndef  BUCHBERGER_ALG
+    M=kStd(Gomega1,NULL,isHomog,NULL,hilb_func,0,NULL,curr_weight);
+    delete hilb_func;
+#else
+    M = kStd(Gomega1,NULL,testHomog,NULL,NULL,0,0,NULL);
+#endif
+#ifdef TIME_TEST
+    tstd = tstd + clock() - to;
+#endif
+    idSkipZeroes(M);
+#ifdef CHECK_IDEAL_MWALK
+    PrintS("\n//** Mwalk: computed M.\n");
+    idString(M, "M");
+#endif
+    //change the ring to baseRing
+    rChangeCurrRing(baseRing);
+    M1 =  idrMoveR(M, newRing,currRing);
+    idDelete(&M);
+    Gomega2 = idrMoveR(Gomega1, newRing,currRing);
+    idDelete(&Gomega1);
+#ifdef TIME_TEST
+    to = clock();
+#endif
+    // compute a representation of the generators of submod (M) with respect to those of mod (Gomega), where Gomega is a reduced Groebner basis w.r.t. the current ring
+    F = MLifttwoIdeal(Gomega2, M1, G);
+#ifdef TIME_TEST
+    tlift = tlift + clock() - to;
+#endif
+#ifdef CHECK_IDEAL_MWALK
+    idString(F, "F");
+#endif
+    idDelete(&Gomega2);
+    idDelete(&M1);
+    rChangeCurrRing(newRing); // change the ring to newRing
+    G = idrMoveR(F,baseRing,currRing);
+    idDelete(&F);
+    baseRing = currRing;
+#ifdef TIME_TEST
+    to = clock();
+#endif
+    //G = kStd(F1,NULL,testHomog,NULL,NULL,0,0,NULL);
+#ifdef TIME_TEST
+    tstd = tstd + clock() - to;
+#endif
+    idSkipZeroes(G);
+#ifdef CHECK_IDEAL_MWALK
+    idString(G, "G");
+#endif
+#ifdef TIME_TEST
+    to = clock();
+#endif
+    intvec* next_weight = MwalkNextWeightCC(curr_weight,target_weight,G);
+#ifdef TIME_TEST
+    tnw = tnw + clock() - to;
+#endif
+#ifdef PRINT_VECTORS
+    MivString(curr_weight, target_weight, next_weight);
+#endif
+    if(MivComp(next_weight, ivNull) == 1 || MivComp(target_weight,curr_weight) == 1)// || test_w_in_ConeCC(G, target_weight) == 1 || MivComp(next_weight,curr_weight) == 1)
+    {
+#ifdef CHECK_IDEAL_MWALK
+      PrintS("\n//** Mwalk: entering last cone.\n");
+#endif
+      Gomega = MwalkInitialForm(G, curr_weight); // compute an initial form ideal of <G> w.r.t. "curr_vector"
+      if(target_M->length() == nV)
+      {
+        newRing = VMrDefault(target_weight); // define a new ring with ordering "(a(curr_weight),lp)
+      }
+      else
+      {
+        newRing = VMatrDefault(target_M);
+      }
+      rChangeCurrRing(newRing);
+      Gomega1 = idrMoveR(Gomega, baseRing,currRing);
+      idDelete(&Gomega);
+#ifdef CHECK_IDEAL_MWALK
+      idString(Gomega1, "Gomega");
+#endif
+      M = kStd(Gomega1,NULL,testHomog,NULL,NULL,0,0,NULL);
+#ifdef CHECK_IDEAL_MWALK
+      idString(M,"M");
+#endif
+      rChangeCurrRing(baseRing);
+      M1 =  idrMoveR(M, newRing,currRing);
+      idDelete(&M);
+      Gomega2 = idrMoveR(Gomega1, newRing,currRing);
+      idDelete(&Gomega1);
+      F = MLifttwoIdeal(Gomega2, M1, G);
+#ifdef CHECK_IDEAL_MWALK
+      idString(F,"F");
+#endif
+      idDelete(&Gomega2);
+      idDelete(&M1);
+      rChangeCurrRing(newRing); // change the ring to newRing
+      G = idrMoveR(F,baseRing,currRing);
+      idDelete(&F);
+      baseRing = currRing;
+      si_opt_1 = save1; //set original options, e. g. option(RedSB)
+      idSkipZeroes(G);
+#ifdef TIME_TEST
+      to = clock();
+#endif
+ //     if(si_opt_1 == (Sy_bit(OPT_REDSB)))
+  //    {
+        G = kInterRedCC(G,NULL); //reduce the Groebner basis <G> w.r.t. currRing, if option(redSB) is set
+  //    }
+#ifdef TIME_TEST
+      tred = tred + clock() - to;
+#endif
+      idSkipZeroes(G);
+      delete next_weight;
+      break;
+#ifdef CHECK_IDEAL_MWALK
+      PrintS("\n//** Mwalk: last cone.\n");
+#endif
+    }
+#ifdef CHECK_IDEAL_MWALK
+    PrintS("\n//** Mwalk: update weight vectors.\n");
+#endif
+    for(i=nV-1; i>=0; i--)
+    {
+      (*tmp_weight)[i] = (*curr_weight)[i];
+      (*curr_weight)[i] = (*next_weight)[i];
+    }
+    delete next_weight;
+  }
+  rChangeCurrRing(XXRing);
+  ideal result = idrMoveR(G,baseRing,currRing);
+  idDelete(&G);
+/*#ifdef CHECK_IDEAL_MWALK
+  pDelete(&p);
+#endif*/
+  delete tmp_weight;
+  delete ivNull;
+  delete exivlp;
+#ifndef BUCHBERGER_ALG
+  delete last_omega;
+#endif
+#ifdef TIME_TEST
+  Print("\n//** Mwalk: Groebner Walk took %d steps.\n", nstep);
+  TimeString(tinput, tostd, tif, tstd, tlift, tred, tnw, nstep);
+  Print("\n//** Mwalk: Ergebnis.\n");
+  //Print("\n// pSetm_Error = (%d)", ErrorCheck());
+  //Print("\n// Overflow_Error? (%d)\n", Overflow_Error);
+#endif
+  return(result);
+}
+
+// 07.11.2012
+// THE RANDOM WALK ALGORITHM  ideal Go, intvec* orig_M, intvec* target_M, ring baseRing
+ideal Mrwalk(ideal Go, intvec* orig_M, intvec* target_M, int weight_rad, int pert_deg, ring baseRing)
+{
+  BITSET save1 = si_opt_1; // save current options
+  //si_opt_1 &= (~Sy_bit(OPT_REDSB)); // no reduced Groebner basis
+  //si_opt_1 &= (~Sy_bit(OPT_REDTAIL)); // not tail reductions
+  //si_opt_1|=(Sy_bit(OPT_REDTAIL)|Sy_bit(OPT_REDSB));
+  Set_Error(FALSE);
+  Overflow_Error = FALSE;
+#ifdef TIME_TEST
+  clock_t tinput, tostd, tif=0, tstd=0, tlift=0, tred=0, tnw=0;
+  xtif=0; xtstd=0; xtlift=0; xtred=0; xtnw=0;
+  tinput = clock();
+  clock_t tim;
+#endif
+  nstep=0;
+  int i,nwalk,endwalks = 0;
+  int nV = baseRing->N;
+
+  ideal Gomega, M, F, Gomega1, Gomega2, M1; //, F1;
+  ring newRing;
+  ring XXRing = baseRing;
+  intvec* ivNull = new intvec(nV);
+  intvec* curr_weight = new intvec(nV);
+  intvec* target_weight = new intvec(nV);
+  intvec* exivlp = Mivlp(nV);
+  intvec* tmp_weight = new intvec(nV);
+  for(i=0; i<nV; i++)
+  {
+    (*tmp_weight)[i] = (*target_M)[i];
+  }
+  for(i=0; i<nV; i++)
+  {
+    (*curr_weight)[i] = (*orig_M)[i];
+    (*target_weight)[i] = (*target_M)[i];
+  }
+#ifndef BUCHBERGER_ALG
+  intvec* hilb_func;
+   // to avoid (1,0,...,0) as the target vector
+  intvec* last_omega = new intvec(nV);
+  for(i=nV-1; i>0; i--)
+  {
+    (*last_omega)[i] = 1;
+  }
+  (*last_omega)[0] = 10000;
+#endif
+  rComplete(currRing);
+#ifdef CHECK_IDEAL_MWALK
+    idString(Go,"Go");
+#endif
+#ifdef TIME_TEST
+  to = clock();
+#endif
+     if(orig_M->length() == nV)
+      {
+        newRing = VMrDefault(curr_weight); // define a new ring with ordering "(a(curr_weight),lp)
+      }
+      else
+      {
+        newRing = VMatrDefault(orig_M);
+      }
+  rChangeCurrRing(newRing);
+  ideal G = MstdCC(idrMoveR(Go,baseRing,currRing));
+  baseRing = currRing;
+#ifdef TIME_TEST
+  tostd = clock()-to;
+#endif
+
+  nwalk = 0;
+  while(1)
+  {
+    nwalk ++;
+    nstep ++;
+#ifdef TIME_TEST
+    to = clock();
+#endif
+#ifdef CHECK_IDEAL_MWALK
+    idString(G,"G");
+#endif
+    Gomega = MwalkInitialForm(G, curr_weight); // compute an initial form ideal of <G> w.r.t. "curr_vector"
+#ifdef TIME_TEST
+    tif = tif + clock()-to; //time for computing initial form ideal
+#endif
+#ifdef CHECK_IDEAL_MWALK
+    idString(Gomega,"Gomega");
+#endif
+#ifndef  BUCHBERGER_ALG
+    if(isNolVector(curr_weight) == 0)
+    {
+      hilb_func = hFirstSeries(Gomega,NULL,NULL,curr_weight,currRing);
+    }
+    else
+    {
+      hilb_func = hFirstSeries(Gomega,NULL,NULL,last_omega,currRing);
+    }
+#endif
+    if(nwalk == 1)
+    {
+      if(orig_M->length() == nV)
+      {
+        newRing = VMrDefault(curr_weight); // define a new ring with ordering "(a(curr_weight),lp)
+      }
+      else
+      {
+        newRing = VMatrDefault(orig_M);
+      }
+    }
+    else
+    {
+     if(target_M->length() == nV)
+     {
+       newRing = VMrRefine(curr_weight,target_weight); //define a new ring with ordering "(a(curr_weight),Wp(target_weight))"
+     }
+     else
+     {
+       newRing = VMatrRefine(target_M,curr_weight);
+     }
+    }
+    rChangeCurrRing(newRing);
+    Gomega1 = idrMoveR(Gomega, baseRing,currRing);
+    idDelete(&Gomega);
+    // compute a reduced Groebner basis of <Gomega> w.r.t. "newRing"
+#ifdef TIME_TEST
+    to = clock();
+#endif
+#ifndef  BUCHBERGER_ALG
+    M=kStd(Gomega1,NULL,isHomog,NULL,hilb_func,0,NULL,curr_weight);
+    delete hilb_func;
+#else
+    M = kStd(Gomega1,NULL,testHomog,NULL,NULL,0,0,NULL);
+#endif
+#ifdef TIME_TEST
+    tstd = tstd + clock() - to;
+#endif
+    idSkipZeroes(M);
+#ifdef CHECK_IDEAL_MWALK
+    PrintS("\n//** Mwalk: computed M.\n");
+    idString(M, "M");
+#endif
+    //change the ring to baseRing
+    rChangeCurrRing(baseRing);
+    M1 =  idrMoveR(M, newRing,currRing);
+    idDelete(&M);
+    Gomega2 = idrMoveR(Gomega1, newRing,currRing);
+    idDelete(&Gomega1);
+#ifdef TIME_TEST
+    to = clock();
+#endif
+    // compute a representation of the generators of submod (M) with respect to those of mod (Gomega), where Gomega is a reduced Groebner basis w.r.t. the current ring
+    F = MLifttwoIdeal(Gomega2, M1, G);
+#ifdef TIME_TEST
+    tlift = tlift + clock() - to;
+#endif
+#ifdef CHECK_IDEAL_MWALK
+    idString(F, "F");
+#endif
+    idDelete(&Gomega2);
+    idDelete(&M1);
+    rChangeCurrRing(newRing); // change the ring to newRing
+    G = idrMoveR(F,baseRing,currRing);
+    idDelete(&F);
+    baseRing = currRing;
+#ifdef TIME_TEST
+    to = clock();
+#endif
+    //G = kStd(F1,NULL,testHomog,NULL,NULL,0,0,NULL);
+#ifdef TIME_TEST
+    tstd = tstd + clock() - to;
+#endif
+    idSkipZeroes(G);
+#ifdef CHECK_IDEAL_MWALK
+    idString(G, "G");
+#endif
+#ifdef TIME_TEST
+    to = clock();
+#endif
+    intvec* next_weight = MWalkRandomNextWeight(G, curr_weight, target_weight, weight_rad, pert_deg);//next_weight = MwalkNextWeightCC(curr_weight,target_weight,G);
+#ifdef TIME_TEST
+    tnw = tnw + clock() - to;
+#endif
+#ifdef PRINT_VECTORS
+    MivString(curr_weight, target_weight, next_weight);
+#endif
+    if(MivComp(next_weight, ivNull) == 1 || MivComp(target_weight,curr_weight) == 1)// || test_w_in_ConeCC(G, target_weight) == 1 || MivComp(next_weight,curr_weight) == 1)
+    {
+#ifdef CHECK_IDEAL_MWALK
+      PrintS("\n//** Mwalk: entering last cone.\n");
+#endif
+      Gomega = MwalkInitialForm(G, curr_weight); // compute an initial form ideal of <G> w.r.t. "curr_vector"
+      if(target_M->length() == nV)
+      {
+        newRing = VMrDefault(target_weight); // define a new ring with ordering "(a(curr_weight),lp)
+      }
+      else
+      {
+        newRing = VMatrDefault(target_M);
+      }
+      rChangeCurrRing(newRing);
+      Gomega1 = idrMoveR(Gomega, baseRing,currRing);
+      idDelete(&Gomega);
+#ifdef CHECK_IDEAL_MWALK
+      idString(Gomega1, "Gomega");
+#endif
+      M = kStd(Gomega1,NULL,testHomog,NULL,NULL,0,0,NULL);
+#ifdef CHECK_IDEAL_MWALK
+      idString(M,"M");
+#endif
+      rChangeCurrRing(baseRing);
+      M1 =  idrMoveR(M, newRing,currRing);
+      idDelete(&M);
+      Gomega2 = idrMoveR(Gomega1, newRing,currRing);
+      idDelete(&Gomega1);
+      F = MLifttwoIdeal(Gomega2, M1, G);
+#ifdef CHECK_IDEAL_MWALK
+      idString(F,"F");
+#endif
+      idDelete(&Gomega2);
+      idDelete(&M1);
+      rChangeCurrRing(newRing); // change the ring to newRing
+      G = idrMoveR(F,baseRing,currRing);
+      idDelete(&F);
+      baseRing = currRing;
+      si_opt_1 = save1; //set original options, e. g. option(RedSB)
+      idSkipZeroes(G);
+#ifdef TIME_TEST
+      to = clock();
+#endif
+ //     if(si_opt_1 == (Sy_bit(OPT_REDSB)))
+  //    {
+        //G = kInterRedCC(G,NULL); //reduce the Groebner basis <G> w.r.t. currRing, if option(redSB) is set
+  //    }
+#ifdef TIME_TEST
+      tred = tred + clock() - to;
+#endif
+      idSkipZeroes(G);
+      delete next_weight;
+      break;
+#ifdef CHECK_IDEAL_MWALK
+      PrintS("\n//** Mwalk: last cone.\n");
+#endif
+    }
+#ifdef CHECK_IDEAL_MWALK
+    PrintS("\n//** Mwalk: update weight vectors.\n");
+#endif
+    for(i=nV-1; i>=0; i--)
+    {
+      (*tmp_weight)[i] = (*curr_weight)[i];
+      (*curr_weight)[i] = (*next_weight)[i];
+    }
+    delete next_weight;
+  }
+  rChangeCurrRing(XXRing);
+  ideal result = idrMoveR(G,baseRing,currRing);
+  idDelete(&G);
+/*#ifdef CHECK_IDEAL_MWALK
+  pDelete(&p);
+#endif*/
+  delete tmp_weight;
+  delete ivNull;
+  delete exivlp;
+#ifndef BUCHBERGER_ALG
+  delete last_omega;
+#endif
+#ifdef TIME_TEST
+  Print("\n//** Mwalk: Groebner Walk took %d steps.\n", nstep);
+  TimeString(tinput, tostd, tif, tstd, tlift, tred, tnw, nstep);
+  Print("\n//** Mwalk: Ergebnis.\n");
+  //Print("\n// pSetm_Error = (%d)", ErrorCheck());
+  //Print("\n// Overflow_Error? (%d)\n", Overflow_Error);
+#endif
+  return(result);
+}
+
+//unused
+#if 0
+ideal Mwalk_tst(ideal Go, intvec* curr_weight, intvec* target_weight)
+{
+  //clock_t tinput=clock();
+  //idString(Go,"Ginp");
+  int i, nV = currRing->N;
+  int nwalk=0, endwalks=0;
+
+  ideal Gomega, M, F, Gomega1, Gomega2, M1, F1, G;
+  // ideal G1; ring endRing;
+  ring newRing, oldRing;
+  intvec* ivNull = new intvec(nV);
+  ring XXRing = currRing;
+
+  intvec* tmp_weight = new intvec(nV);
+  for(i=nV-1; i>=0; i--)
+  {
+    (*tmp_weight)[i] = (*curr_weight)[i];
+  }
+  /* the monomial ordering of this current ring would be "dp" */
+  G = MstdCC(Go);
+#ifndef BUCHBERGER_ALG
+  intvec* hilb_func;
+#endif
+  /* to avoid (1,0,...,0) as the target vector */
+  intvec* last_omega = new intvec(nV);
+  for(i=nV-1; i>0; i--)
+    (*last_omega)[i] = 1;
+  (*last_omega)[0] = 10000;
+
+  while(1)
+  {
+    nwalk ++;
+    //Print("\n// Entering the %d-th step:", nwalk);
+    //Print("\n// ring r[%d] = %s;", nwalk, rString(currRing));
+    idString(G,"G");
+    /* compute an initial form ideal of <G> w.r.t. "curr_vector" */
+    Gomega = MwalkInitialForm(G, curr_weight);
+    //ivString(curr_weight, "omega");
+    idString(Gomega,"Gw");
+
+#ifndef  BUCHBERGER_ALG
+    if(isNolVector(curr_weight) == 0)
+      hilb_func = hFirstSeries(Gomega,NULL,NULL,curr_weight,currRing);
+    else
+      hilb_func = hFirstSeries(Gomega,NULL,NULL,last_omega,currRing);
+#endif // BUCHBERGER_ALG
+
+
+    oldRing = currRing;
+
+    /* define a new ring that its ordering is "(a(curr_weight),lp) */
+    VMrDefault(curr_weight);
+    newRing = currRing;
+
+    Gomega1 = idrMoveR(Gomega, oldRing,currRing);
+
+    /* compute a reduced Groebner basis of <Gomega> w.r.t. "newRing" */
+#ifdef  BUCHBERGER_ALG
+    M = MstdhomCC(Gomega1);
+#else
+    M=kStd(Gomega1,NULL,isHomog,NULL,hilb_func,0,NULL,curr_weight);
+    delete hilb_func;
+#endif // BUCHBERGER_ALG
+
+    idString(M,"M");
+
+      /* change the ring to oldRing */
+    rChangeCurrRing(oldRing);
+    M1 =  idrMoveR(M, newRing,currRing);
+    Gomega2 =  idrMoveR(Gomega1, newRing,currRing);
+
+      /* compute a representation of the generators of submod (M)
+         with respect to those of mod (Gomega).
+         Gomega is a reduced Groebner basis w.r.t. the current ring */
+    F = MLifttwoIdeal(Gomega2, M1, G);
+    idDelete(&M1);
+    idDelete(&Gomega2);
+    idDelete(&G);
+    idString(F,"F");
+
+    /* change the ring to newRing */
+    rChangeCurrRing(newRing);
+    F1 = idrMoveR(F, oldRing,currRing);
+
+    /* reduce the Groebner basis <G> w.r.t. new ring */
+    G = kInterRedCC(F1, NULL);
+    //idSkipZeroes(G);//done by kInterRed
+    idDelete(&F1);
+    idString(G,"G");
+    if(endwalks == 1)
+      break;
+
+    /* compute a next weight vector */
+    intvec* next_weight = MkInterRedNextWeight(curr_weight,target_weight,G);
+#ifdef PRINT_VECTORS
+    MivString(curr_weight, target_weight, next_weight);
+#endif
+
+    if(MivComp(next_weight, ivNull) == 1)
+    {
+      delete next_weight;
+      break;
+    }
+    if(MivComp(next_weight, target_weight) == 1)
+      endwalks = 1;
+
+    for(i=nV-1; i>=0; i--)
+      (*tmp_weight)[i] = (*curr_weight)[i];
+
+    /* 06.11.01 to free the memory: NOT Changed!!*/
+    for(i=nV-1; i>=0; i--)
+      (*curr_weight)[i] = (*next_weight)[i];
+    delete next_weight;
+  }
+  rChangeCurrRing(XXRing);
+  G = idrMoveR(G, newRing,currRing);
+
+  delete tmp_weight;
+  delete ivNull;
+  PrintLn();
+  return(G);
+}
+#endif
+
+/**************************************************************/
+/*     Implementation of the perturbation walk algorithm      */
+/**************************************************************/
+/* If the perturbed target weight vector or an intermediate weight vector
+   doesn't stay in the correct Groebner cone, we have only
+   a reduced Groebner basis for the given ideal with respect to
+   a monomial order which differs to the given order.
+   Then we have to compute the wanted  reduced Groebner basis for it.
+   For this, we can use
+   1) the improved Buchberger algorithm or
+   2) the changed perturbation walk algorithm with a decreased degree.
+*/
+// use kStd, if nP = 0, else call LastGB
+ideal Mpwalk(ideal Go, int op_deg, int tp_deg,intvec* curr_weight,
+             intvec* target_weight, int nP)
+{
+  Set_Error(FALSE  );
+  Overflow_Error = FALSE;
+  //Print("// pSetm_Error = (%d)", ErrorCheck());
+
+  clock_t  tinput, tostd, tif=0, tstd=0, tlift=0, tred=0, tnw=0;
+  xtextra=0;
+  xtif=0; xtstd=0; xtlift=0; xtred=0; xtnw=0;
+  tinput = clock();
+
+  clock_t tim;
+
+  nstep = 0;
+  int i, ntwC=1, ntestw=1,  nV = currRing->N;
+  int endwalks=0;
+
+  ideal Gomega, M, F, G, Gomega1, Gomega2, M1,F1,Eresult,ssG;
+  ring newRing, oldRing, TargetRing;
+  intvec* iv_M_dp;
+  intvec* iv_M_lp;
+  intvec* exivlp = Mivlp(nV);
+  intvec* orig_target = target_weight;
+  intvec* pert_target_vector = target_weight;
+  intvec* ivNull = new intvec(nV);
+  intvec* iv_dp = MivUnit(nV);// define (1,1,...,1)
+#ifndef BUCHBERGER_ALG
+  intvec* hilb_func;
+#endif
+  intvec* next_weight;
+
+  // to avoid (1,0,...,0) as the target vector
+  intvec* last_omega = new intvec(nV);
+  for(i=nV-1; i>0; i--)
+    (*last_omega)[i] = 1;
+  (*last_omega)[0] = 10000;
+
+  ring XXRing = currRing;
+
+
+  to = clock();
+  /* perturbs the original vector */
+  if(MivComp(curr_weight, iv_dp) == 1) //rOrdStr(currRing) := "dp"
+  {
+    G = MstdCC(Go);
+    tostd = clock()-to;
+    if(op_deg != 1){
+      iv_M_dp = MivMatrixOrderdp(nV);
+      //ivString(iv_M_dp, "iv_M_dp");
+      curr_weight = MPertVectors(G, iv_M_dp, op_deg);
+    }
+  }
+  else
+  {
+    //define ring order := (a(curr_weight),lp);
+    if (rParameter(currRing) != NULL)
+      DefRingPar(curr_weight);
+    else
+      rChangeCurrRing(VMrDefault(curr_weight)); //Aenderung 1
+
+    G = idrMoveR(Go, XXRing,currRing);
+    G = MstdCC(G);
+    tostd = clock()-to;
+    if(op_deg != 1){
+      iv_M_dp = MivMatrixOrder(curr_weight);
+      curr_weight = MPertVectors(G, iv_M_dp, op_deg);
+    }
+  }
+  delete iv_dp;
+  if(op_deg != 1) delete iv_M_dp;
+
+  ring HelpRing = currRing;
+
+  /* perturbs the target weight vector */
+  if(tp_deg > 1 && tp_deg <= nV)
+  {
+    if (rParameter(currRing) != NULL)
+      DefRingPar(target_weight);
+    else
+      rChangeCurrRing(VMrDefault(target_weight)); // Aenderung 2
+
+    TargetRing = currRing;
+    ssG = idrMoveR(G,HelpRing,currRing);
+    if(MivSame(target_weight, exivlp) == 1)
+    {
+      iv_M_lp = MivMatrixOrderlp(nV);
+      //ivString(iv_M_lp, "iv_M_lp");
+      //target_weight = MPertVectorslp(ssG, iv_M_lp, tp_deg);
+      target_weight = MPertVectors(ssG, iv_M_lp, tp_deg);
+    }
+    else
+    {
+      iv_M_lp = MivMatrixOrder(target_weight);
+      //target_weight = MPertVectorslp(ssG, iv_M_lp, tp_deg);
+      target_weight = MPertVectors(ssG, iv_M_lp, tp_deg);
+    }
+    delete iv_M_lp;
+    pert_target_vector = target_weight;
+    rChangeCurrRing(HelpRing);
+    G = idrMoveR(ssG, TargetRing,currRing);
+  }
+  /*
+    Print("\n// Perturbationwalkalg. vom Gradpaar (%d,%d):",op_deg,tp_deg);
+    ivString(curr_weight, "new sigma");
+    ivString(target_weight, "new tau");
+  */
+  while(1)
+  {
+    nstep ++;
+    to = clock();
+    /* compute an initial form ideal of <G> w.r.t. the weight vector
+       "curr_weight" */
+    Gomega = MwalkInitialForm(G, curr_weight);
+
+
+#ifdef ENDWALKS
+    if(endwalks == 1){
+      Print("\n// ring r%d = %s;\n", nstep, rString(currRing));
+      idElements(G, "G");
+      // idElements(Gomega, "Gw");
+      headidString(G, "G");
+      //headidString(Gomega, "Gw");
+    }
+#endif
+
+    tif = tif + clock()-to;
+
+#ifndef  BUCHBERGER_ALG
+    if(isNolVector(curr_weight) == 0)
+      hilb_func = hFirstSeries(Gomega,NULL,NULL,curr_weight,currRing);
+    else
+      hilb_func = hFirstSeries(Gomega,NULL,NULL,last_omega,currRing);
+#endif // BUCHBERGER_ALG
+
+    oldRing = currRing;
+
+    // define a new ring with ordering "(a(curr_weight),lp)
+    if (rParameter(currRing) != NULL)
+      DefRingPar(curr_weight);
+    else
+      rChangeCurrRing(VMrDefault(curr_weight)); //Aenderung 3
+
+    newRing = currRing;
+    Gomega1 = idrMoveR(Gomega, oldRing,currRing);
+
+#ifdef ENDWALKS
+    if(endwalks==1)
+    {
+      Print("\n// ring r%d = %s;\n", nstep, rString(currRing));
+      idElements(Gomega1, "Gw");
+      headidString(Gomega1, "headGw");
+      PrintS("\n// compute a rGB of Gw:\n");
+
+#ifndef  BUCHBERGER_ALG
+      ivString(hilb_func, "w");
+#endif
+    }
+#endif
+
+    tim = clock();
+    to = clock();
+    /* compute a reduced Groebner basis of <Gomega> w.r.t. "newRing" */
+#ifdef  BUCHBERGER_ALG
+    M = MstdhomCC(Gomega1);
+#else
+    M=kStd(Gomega1,NULL,isHomog,NULL,hilb_func,0,NULL,curr_weight);
+    delete hilb_func;
+#endif // BUCHBERGER_ALG
+
+    if(endwalks == 1){
+      xtstd = xtstd+clock()-to;
+#ifdef ENDWALKS
+      Print("\n// time for the last std(Gw)  = %.2f sec\n",
+            ((double) clock())/1000000 -((double)tim) /1000000);
+#endif
+    }
+    else
+      tstd=tstd+clock()-to;
+
+    /* change the ring to oldRing */
+    rChangeCurrRing(oldRing);
+    M1 =  idrMoveR(M, newRing,currRing);
+    Gomega2 =  idrMoveR(Gomega1, newRing,currRing);
+
+    //if(endwalks==1)  PrintS("\n// Lifting is working:..");
+
+    to=clock();
+    /* compute a representation of the generators of submod (M)
+       with respect to those of mod (Gomega).
+       Gomega is a reduced Groebner basis w.r.t. the current ring */
+    F = MLifttwoIdeal(Gomega2, M1, G);
+    if(endwalks != 1)
+      tlift = tlift+clock()-to;
+    else
+      xtlift=clock()-to;
+
+    idDelete(&M1);
+    idDelete(&Gomega2);
+    idDelete(&G);
+
+    /* change the ring to newRing */
+    rChangeCurrRing(newRing);
+    F1 = idrMoveR(F, oldRing,currRing);
+
+    //if(endwalks==1)PrintS("\n// InterRed is working now:");
+
+    to=clock();
+    /* reduce the Groebner basis <G> w.r.t. new ring */
+    G = kInterRedCC(F1, NULL);
+    if(endwalks != 1)
+      tred = tred+clock()-to;
+    else
+      xtred=clock()-to;
+
+    idDelete(&F1);
+
+    if(endwalks == 1)
+      break;
+
+    to=clock();
+    /* compute a next weight vector */
+    next_weight = MkInterRedNextWeight(curr_weight,target_weight, G);
+    tnw=tnw+clock()-to;
+#ifdef PRINT_VECTORS
+    MivString(curr_weight, target_weight, next_weight);
+#endif
+
+    if(Overflow_Error == TRUE)
+    {
+      ntwC = 0;
+      //ntestomega = 1;
+      //Print("\n// ring r%d = %s;\n", nstep, rString(currRing));
+      //idElements(G, "G");
+      delete next_weight;
+      goto FINISH_160302;
+    }
+    if(MivComp(next_weight, ivNull) == 1){
+      newRing = currRing;
+      delete next_weight;
+      //Print("\n// ring r%d = %s;\n", nstep, rString(currRing));
+      break;
+    }
+    if(MivComp(next_weight, target_weight) == 1)
+      endwalks = 1;
+
+    for(i=nV-1; i>=0; i--)
+      (*curr_weight)[i] = (*next_weight)[i];
+
+    delete next_weight;
+  }//while
+
+  if(tp_deg != 1)
+  {
+  FINISH_160302:
+    if(MivSame(orig_target, exivlp) == 1)
+      if (rParameter(currRing) != NULL)
+        DefRingParlp();
+      else
+        VMrDefaultlp();
+    else
+      if (rParameter(currRing) != NULL)
+        DefRingPar(orig_target);
+      else
+        rChangeCurrRing(VMrDefault(orig_target)); //Aenderung
+
+    TargetRing=currRing;
+    F1 = idrMoveR(G, newRing,currRing);
+#ifdef CHECK_IDEAL
+      headidString(G, "G");
+#endif
+
+
+    // check whether the pertubed target vector stays in the correct cone
+    if(ntwC != 0){
+      ntestw = test_w_in_ConeCC(F1, pert_target_vector);
+    }
+
+    if( ntestw != 1 || ntwC == 0)
+    {
+      /*
+      if(ntestw != 1){
+        ivString(pert_target_vector, "tau");
+        PrintS("\n// ** perturbed target vector doesn't stay in cone!!");
+        Print("\n// ring r%d = %s;\n", nstep, rString(currRing));
+        idElements(F1, "G");
+      }
+      */
+      // LastGB is "better" than the kStd subroutine
+      to=clock();
+      ideal eF1;
+      if(nP == 0 || tp_deg == 1 || MivSame(orig_target, exivlp) != 1){
+        // PrintS("\n// ** calls \"std\" to compute a GB");
+        eF1 = MstdCC(F1);
+        idDelete(&F1);
+      }
+      else {
+        // PrintS("\n// ** calls \"LastGB\" to compute a GB");
+        rChangeCurrRing(newRing);
+        ideal F2 = idrMoveR(F1, TargetRing,currRing);
+        eF1 = LastGB(F2, curr_weight, tp_deg-1);
+        F2=NULL;
+      }
+      xtextra=clock()-to;
+      ring exTargetRing = currRing;
+
+      rChangeCurrRing(XXRing);
+      Eresult = idrMoveR(eF1, exTargetRing,currRing);
+    }
+    else{
+      rChangeCurrRing(XXRing);
+      Eresult = idrMoveR(F1, TargetRing,currRing);
+    }
+  }
+  else {
+    rChangeCurrRing(XXRing);
+    Eresult = idrMoveR(G, newRing,currRing);
+  }
+  delete ivNull;
+  if(tp_deg != 1)
+    delete target_weight;
+
+  if(op_deg != 1 )
+    delete curr_weight;
+
+  delete exivlp;
+  delete last_omega;
+
+#ifdef TIME_TEST
+  TimeStringFractal(tinput, tostd, tif+xtif, tstd+xtstd,0, tlift+xtlift, tred+xtred,
+             tnw+xtnw);
+
+  Print("\n// pSetm_Error = (%d)", ErrorCheck());
+  Print("\n// It took %d steps and Overflow_Error? (%d)\n", nstep,  Overflow_Error);
+#endif
+  return(Eresult);
+}
+
+intvec* XivNull;
+
+// define a matrix (1 ... 1)
+intvec* MMatrixone(int nV)
+{
+  int i,j;
+  intvec* ivM = new intvec(nV*nV);
+
+  for(i=0; i<nV; i++)
+    for(j=0; j<nV; j++)
+    (*ivM)[i*nV + j] = 1;
+
+  return(ivM);
+}
+
+int nnflow;
+int Xcall;
+int Xngleich;
+
+/***********************************************************************
+ * Perturb the start weight vector at the top level, i.e. nlev = 1     *
+ ***********************************************************************/
+static ideal rec_fractal_call(ideal G, int nlev, intvec* omtmp)
+{
+  Overflow_Error =  FALSE;
+  //Print("\n\n// Entering the %d-th recursion:", nlev);
+
+  int i, nV = currRing->N;
+  ring new_ring, testring;
+  //ring extoRing;
+  ideal Gomega, Gomega1, Gomega2, F, F1, Gresult, Gresult1, G1, Gt;
+  int nwalks = 0;
+  intvec* Mwlp;
+#ifndef BUCHBERGER_ALG
+  intvec* hilb_func;
+#endif
+//  intvec* extXtau;
+  intvec* next_vect;
+  intvec* omega2 = new intvec(nV);
+  intvec* altomega = new intvec(nV);
+
+  //BOOLEAN isnewtarget = FALSE;
+
+  // to avoid (1,0,...,0) as the target vector (Hans)
+  intvec* last_omega = new intvec(nV);
+  for(i=nV-1; i>0; i--)
+    (*last_omega)[i] = 1;
+  (*last_omega)[0] = 10000;
+
+  intvec* omega = new intvec(nV);
+  for(i=0; i<nV; i++) {
+    if(Xsigma->length() == nV)
+      (*omega)[i] =  (*Xsigma)[i];
+    else
+      (*omega)[i] = (*Xsigma)[(nV*(nlev-1))+i];
+
+    (*omega2)[i] = (*Xtau)[(nlev-1)*nV+i];
+  }
+
+   if(nlev == 1)  Xcall = 1;
+   else Xcall = 0;
+
+  ring oRing = currRing;
+
+  while(1)
+  {
+#ifdef FIRST_STEP_FRACTAL
+    // perturb the current weight vector only on the top level or
+    // after perturbation of the both vectors, nlev = 2 as the top level
+    if((nlev == 1 && Xcall == 0) || (nlev == 2 && Xngleich == 1))
+      if(islengthpoly2(G) == 1)
+      {
+        Mwlp = MivWeightOrderlp(omega);
+        Xsigma = Mfpertvector(G, Mwlp);
+        delete Mwlp;
+        Overflow_Error = FALSE;
+      }
+#endif
+    nwalks ++;
+    NEXT_VECTOR_FRACTAL:
+    to=clock();
+    /* determine the next border */
+    next_vect = MkInterRedNextWeight(omega,omega2,G);
+    xtnw=xtnw+clock()-to;
+#ifdef PRINT_VECTORS
+    MivString(omega, omega2, next_vect);
+#endif
+    oRing = currRing;
+
+    /* We only perturb the current target vector at the recursion  level 1 */
+    if(Xngleich == 0 && nlev == 1) //(ngleich == 0) important, e.g. ex2, ex3
+      if (MivComp(next_vect, omega2) == 1)
+      {
+        /* to dispense with taking initial (and lifting/interreducing
+           after the call of recursion */
+        //Print("\n\n// ** Perturb the both vectors with degree %d with",nlev);
+        //idElements(G, "G");
+
+        Xngleich = 1;
+        nlev +=1;
+
+        if (rParameter(currRing) != NULL)
+          DefRingPar(omtmp);
+        else
+          rChangeCurrRing(VMrDefault1(omtmp)); //Aenderung3
+
+        testring = currRing;
+        Gt = idrMoveR(G, oRing,currRing);
+
+        /* perturb the original target vector w.r.t. the current GB */
+        delete Xtau;
+        Xtau = NewVectorlp(Gt);
+
+        rChangeCurrRing(oRing);
+        G = idrMoveR(Gt, testring,currRing);
+
+        /* perturb the current vector w.r.t. the current GB */
+        Mwlp = MivWeightOrderlp(omega);
+        Xsigma = Mfpertvector(G, Mwlp);
+        delete Mwlp;
+
+        for(i=nV-1; i>=0; i--) {
+          (*omega2)[i] = (*Xtau)[nV+i];
+          (*omega)[i] = (*Xsigma)[nV+i];
+        }
+
+        delete next_vect;
+        to=clock();
+
+        /* to avoid the value of Overflow_Error that occur in Mfpertvector*/
+        Overflow_Error = FALSE;
+
+        next_vect = MkInterRedNextWeight(omega,omega2,G);
+        xtnw=xtnw+clock()-to;
+
+#ifdef PRINT_VECTORS
+        MivString(omega, omega2, next_vect);
+#endif
+      }
+
+
+    /* check whether the the computed vector is in the correct cone */
+    /* If no, the reduced GB of an omega-homogeneous ideal will be
+       computed by Buchberger algorithm and stop this recursion step*/
+    //if(test_w_in_ConeCC(G, next_vect) != 1) //e.g. Example s7, cyc6
+    if(Overflow_Error == TRUE)
+    {
+      delete next_vect;
+      if (rParameter(currRing) != NULL)
+      {
+        DefRingPar(omtmp);
+      }
+      else
+      {
+        rChangeCurrRing(VMrDefault1(omtmp)); // Aenderung4
+      }
+#ifdef TEST_OVERFLOW
+      Gt = idrMoveR(G, oRing,currRing);
+      Gt = NULL; return(Gt);
+#endif
+
+      //Print("\n\n// apply BB's alg. in ring r = %s;", rString(currRing));
+      to=clock();
+      Gt = idrMoveR(G, oRing,currRing);
+      G1 = MstdCC(Gt);
+      xtextra=xtextra+clock()-to;
+      Gt = NULL;
+
+      delete omega2;
+      delete altomega;
+
+      //Print("\n// Leaving the %d-th recursion with %d steps", nlev, nwalks);
+      //Print("  ** Overflow_Error? (%d)", Overflow_Error);
+      nnflow ++;
+
+      Overflow_Error = FALSE;
+      return (G1);
+    }
+
+
+    /* If the perturbed target vector stays in the correct cone,
+       return the current GB,
+       otherwise, return the computed  GB by the Buchberger-algorithm.
+       Then we update the perturbed target vectors w.r.t. this GB. */
+
+    /* the computed vector is equal to the origin vector, since
+       t is not defined */
+    if (MivComp(next_vect, XivNull) == 1)
+    {
+      if (rParameter(currRing) != NULL)
+        DefRingPar(omtmp);
+      else
+        rChangeCurrRing(VMrDefault1(omtmp)); //Aenderung5
+
+      testring = currRing;
+      Gt = idrMoveR(G, oRing,currRing);
+
+      if(test_w_in_ConeCC(Gt, omega2) == 1) {
+        delete omega2;
+        delete next_vect;
+        delete altomega;
+        //Print("\n// Leaving the %d-th recursion with %d steps ",nlev, nwalks);
+        //Print(" ** Overflow_Error? (%d)", Overflow_Error);
+
+        return (Gt);
+      }
+      else
+      {
+        //ivString(omega2, "tau'");
+        //Print("\n//  tau' doesn't stay in the correct cone!!");
+
+#ifndef  MSTDCC_FRACTAL
+        //07.08.03
+        //ivString(Xtau, "old Xtau");
+        intvec* Xtautmp = Mfpertvector(Gt, MivMatrixOrder(omtmp));
+#ifdef TEST_OVERFLOW
+      if(Overflow_Error == TRUE)
+      Gt = NULL; return(Gt);
+#endif
+
+        if(MivSame(Xtau, Xtautmp) == 1)
+        {
+          //PrintS("\n// Update vectors are equal to the old vectors!!");
+          delete Xtautmp;
+          goto FRACTAL_MSTDCC;
+        }
+
+        Xtau = Xtautmp;
+        Xtautmp = NULL;
+        //ivString(Xtau, "new  Xtau");
+
+        for(i=nV-1; i>=0; i--)
+          (*omega2)[i] = (*Xtau)[(nlev-1)*nV+i];
+
+        //Print("\n//  ring tau = %s;", rString(currRing));
+        rChangeCurrRing(oRing);
+        G = idrMoveR(Gt, testring,currRing);
+
+        goto NEXT_VECTOR_FRACTAL;
+#endif
+
+      FRACTAL_MSTDCC:
+        //Print("\n//  apply BB-Alg in ring = %s;", rString(currRing));
+        to=clock();
+        G = MstdCC(Gt);
+        xtextra=xtextra+clock()-to;
+
+        oRing = currRing;
+
+        // update the original target vector w.r.t. the current GB
+        if(MivSame(Xivinput, Xivlp) == 1)
+          if (rParameter(currRing) != NULL)
+            DefRingParlp();
+          else
+            VMrDefaultlp();
+        else
+          if (rParameter(currRing) != NULL)
+            DefRingPar(Xivinput);
+          else
+            rChangeCurrRing(VMrDefault1(Xivinput)); //Aenderung6
+
+        testring = currRing;
+        Gt = idrMoveR(G, oRing,currRing);
+
+        delete Xtau;
+        Xtau = NewVectorlp(Gt);
+
+        rChangeCurrRing(oRing);
+        G = idrMoveR(Gt, testring,currRing);
+
+        delete omega2;
+        delete next_vect;
+        delete altomega;
+        /*
+          Print("\n// Leaving the %d-th recursion with %d steps,", nlev,nwalks);
+          Print(" ** Overflow_Error? (%d)", Overflow_Error);
+        */
+        if(Overflow_Error == TRUE)
+          nnflow ++;
+
+        Overflow_Error = FALSE;
+        return(G);
+      }
+    }
+
+    for(i=nV-1; i>=0; i--) {
+      (*altomega)[i] = (*omega)[i];
+      (*omega)[i] = (*next_vect)[i];
+    }
+    delete next_vect;
+
+    to=clock();
+    /* Take the initial form of <G> w.r.t. omega */
+    Gomega = MwalkInitialForm(G, omega);
+    xtif=xtif+clock()-to;
+
+#ifndef  BUCHBERGER_ALG
+    if(isNolVector(omega) == 0)
+      hilb_func = hFirstSeries(Gomega,NULL,NULL,omega,currRing);
+    else
+      hilb_func = hFirstSeries(Gomega,NULL,NULL,last_omega,currRing);
+#endif // BUCHBERGER_ALG
+
+    if (rParameter(currRing) != NULL)
+      DefRingPar(omega);
+    else
+      rChangeCurrRing(VMrDefault1(omega)); //Aenderung7
+
+    Gomega1 = idrMoveR(Gomega, oRing,currRing);
+
+    /* Maximal recursion depth, to compute a red. GB */
+    /* Fractal walk with the alternative recursion */
+    /* alternative recursion */
+    // if(nlev == nV || lengthpoly(Gomega1) == 0)
+    if(nlev == Xnlev || lengthpoly(Gomega1) == 0)
+      //if(nlev == nV) // blind recursion
+    {
+      /*
+      if(Xnlev != nV)
+      {
+        Print("\n// ** Xnlev = %d", Xnlev);
+        ivString(Xtau, "Xtau");
+      }
+      */
+      to=clock();
+#ifdef  BUCHBERGER_ALG
+      Gresult = MstdhomCC(Gomega1);
+#else
+      Gresult =kStd(Gomega1,NULL,isHomog,NULL,hilb_func,0,NULL,omega);
+      delete hilb_func;
+#endif // BUCHBERGER_ALG
+      xtstd=xtstd+clock()-to;
+    }
+    else {
+      rChangeCurrRing(oRing);
+      Gomega1 = idrMoveR(Gomega1, oRing,currRing);
+      Gresult = rec_fractal_call(idCopy(Gomega1),nlev+1,omega);
+    }
+
+    //convert a Groebner basis from a ring to another ring,
+    new_ring = currRing;
+
+    rChangeCurrRing(oRing);
+    Gresult1 = idrMoveR(Gresult, new_ring,currRing);
+    Gomega2 = idrMoveR(Gomega1, new_ring,currRing);
+
+    to=clock();
+    /* Lifting process */
+    F = MLifttwoIdeal(Gomega2, Gresult1, G);
+    xtlift=xtlift+clock()-to;
+    idDelete(&Gresult1);
+    idDelete(&Gomega2);
+    idDelete(&G);
+
+    rChangeCurrRing(new_ring);
+    F1 = idrMoveR(F, oRing,currRing);
+
+    to=clock();
+    /* Interreduce G */
+    G = kInterRedCC(F1, NULL);
+    xtred=xtred+clock()-to;
+    idDelete(&F1);
+  }
+}
+
+/************************************************************************
+ * Perturb the start weight vector at the top level with random element *
+ ************************************************************************/
+static ideal rec_r_fractal_call(ideal G, int nlev, intvec* omtmp, int weight_rad)
+{
+  Overflow_Error =  FALSE;
+  //Print("\n\n// Entering the %d-th recursion:", nlev);
+
+  int i, nV = currRing->N;
+  ring new_ring, testring;
+  //ring extoRing;
+  ideal Gomega, Gomega1, Gomega2, F, F1, Gresult, Gresult1, G1, Gt;
+  int nwalks = 0;
+  intvec* Mwlp;
+#ifndef BUCHBERGER_ALG
+  intvec* hilb_func;
+#endif
+//  intvec* extXtau;
+  intvec* next_vect;
+  intvec* omega2 = new intvec(nV);
+  intvec* altomega = new intvec(nV);
+
+  //BOOLEAN isnewtarget = FALSE;
+
+  // to avoid (1,0,...,0) as the target vector (Hans)
+  intvec* last_omega = new intvec(nV);
+  for(i=nV-1; i>0; i--)
+    (*last_omega)[i] = 1;
+  (*last_omega)[0] = 10000;
+
+  intvec* omega = new intvec(nV);
+  for(i=0; i<nV; i++) {
+    if(Xsigma->length() == nV)
+      (*omega)[i] =  (*Xsigma)[i];
+    else
+      (*omega)[i] = (*Xsigma)[(nV*(nlev-1))+i];
+
+    (*omega2)[i] = (*Xtau)[(nlev-1)*nV+i];
+  }
+
+   if(nlev == 1)  Xcall = 1;
+   else Xcall = 0;
+
+  ring oRing = currRing;
+
+  while(1)
+  {
+#ifdef FIRST_STEP_FRACTAL
+    // perturb the current weight vector only on the top level or
+    // after perturbation of the both vectors, nlev = 2 as the top level
+    if((nlev == 1 && Xcall == 0) || (nlev == 2 && Xngleich == 1))
+      if(islengthpoly2(G) == 1)
+      {
+        Mwlp = MivWeightOrderlp(omega);
+        Xsigma = Mfpertvector(G, Mwlp);
+        delete Mwlp;
+        Overflow_Error = FALSE;
+      }
+#endif
+    nwalks ++;
+    NEXT_VECTOR_FRACTAL:
+    to=clock();
+    /* determine the next border */
+    next_vect = MWalkRandomNextWeight(G, omega,omega2, weight_rad, 1+nlev);
+    //next_vect = MkInterRedNextWeight(omega,omega2,G);
+    xtnw=xtnw+clock()-to;
+#ifdef PRINT_VECTORS
+    MivString(omega, omega2, next_vect);
+#endif
+    oRing = currRing;
+
+    /* We only perturb the current target vector at the recursion  level 1 */
+    if(Xngleich == 0 && nlev == 1) //(ngleich == 0) important, e.g. ex2, ex3
+      if (MivComp(next_vect, omega2) == 1)
+      {
+        /* to dispense with taking initial (and lifting/interreducing
+           after the call of recursion */
+        //Print("\n\n// ** Perturb the both vectors with degree %d with",nlev);
+        //idElements(G, "G");
+
+        Xngleich = 1;
+        nlev +=1;
+
+        if (rParameter(currRing) != NULL)
+          DefRingPar(omtmp);
+        else
+          rChangeCurrRing(VMrDefault1(omtmp)); //Aenderung3
+
+        testring = currRing;
+        Gt = idrMoveR(G, oRing,currRing);
+
+        /* perturb the original target vector w.r.t. the current GB */
+        delete Xtau;
+        Xtau = NewVectorlp(Gt);
+
+        rChangeCurrRing(oRing);
+        G = idrMoveR(Gt, testring,currRing);
+
+        /* perturb the current vector w.r.t. the current GB */
+        Mwlp = MivWeightOrderlp(omega);
+        Xsigma = Mfpertvector(G, Mwlp);
+        delete Mwlp;
+
+        for(i=nV-1; i>=0; i--) {
+          (*omega2)[i] = (*Xtau)[nV+i];
+          (*omega)[i] = (*Xsigma)[nV+i];
+        }
+
+        delete next_vect;
+        to=clock();
+
+        /* to avoid the value of Overflow_Error that occur in Mfpertvector*/
+        Overflow_Error = FALSE;
+
+        next_vect = MkInterRedNextWeight(omega,omega2,G);
+        xtnw=xtnw+clock()-to;
+
+#ifdef PRINT_VECTORS
+        MivString(omega, omega2, next_vect);
+#endif
+      }
+
+
+    /* check whether the the computed vector is in the correct cone */
+    /* If no, the reduced GB of an omega-homogeneous ideal will be
+       computed by Buchberger algorithm and stop this recursion step*/
+    //if(test_w_in_ConeCC(G, next_vect) != 1) //e.g. Example s7, cyc6
+    if(Overflow_Error == TRUE)
+    {
+      delete next_vect;
+      if (rParameter(currRing) != NULL)
+      {
+        DefRingPar(omtmp);
+      }
+      else
+      {
+        rChangeCurrRing(VMrDefault1(omtmp)); // Aenderung4
+      }
+#ifdef TEST_OVERFLOW
+      Gt = idrMoveR(G, oRing,currRing);
+      Gt = NULL; return(Gt);
+#endif
+
+      //Print("\n\n// apply BB's alg. in ring r = %s;", rString(currRing));
+      to=clock();
+      Gt = idrMoveR(G, oRing,currRing);
+      G1 = MstdCC(Gt);
+      xtextra=xtextra+clock()-to;
+      Gt = NULL;
+
+      delete omega2;
+      delete altomega;
+
+      //Print("\n// Leaving the %d-th recursion with %d steps", nlev, nwalks);
+      //Print("  ** Overflow_Error? (%d)", Overflow_Error);
+      nnflow ++;
+
+      Overflow_Error = FALSE;
+      return (G1);
+    }
+
+
+    /* If the perturbed target vector stays in the correct cone,
+       return the current GB,
+       otherwise, return the computed  GB by the Buchberger-algorithm.
+       Then we update the perturbed target vectors w.r.t. this GB. */
+
+    /* the computed vector is equal to the origin vector, since
+       t is not defined */
+    if (MivComp(next_vect, XivNull) == 1)
+    {
+      if (rParameter(currRing) != NULL)
+        DefRingPar(omtmp);
+      else
+        rChangeCurrRing(VMrDefault1(omtmp)); //Aenderung5
+
+      testring = currRing;
+      Gt = idrMoveR(G, oRing,currRing);
+
+      if(test_w_in_ConeCC(Gt, omega2) == 1) {
+        delete omega2;
+        delete next_vect;
+        delete altomega;
+        //Print("\n// Leaving the %d-th recursion with %d steps ",nlev, nwalks);
+        //Print(" ** Overflow_Error? (%d)", Overflow_Error);
+
+        return (Gt);
+      }
+      else
+      {
+        //ivString(omega2, "tau'");
+        //Print("\n//  tau' doesn't stay in the correct cone!!");
+
+#ifndef  MSTDCC_FRACTAL
+        //07.08.03
+        //ivString(Xtau, "old Xtau");
+        intvec* Xtautmp = Mfpertvector(Gt, MivMatrixOrder(omtmp));
+#ifdef TEST_OVERFLOW
+      if(Overflow_Error == TRUE)
+      Gt = NULL; return(Gt);
+#endif
+
+        if(MivSame(Xtau, Xtautmp) == 1)
+        {
+          //PrintS("\n// Update vectors are equal to the old vectors!!");
+          delete Xtautmp;
+          goto FRACTAL_MSTDCC;
+        }
+
+        Xtau = Xtautmp;
+        Xtautmp = NULL;
+        //ivString(Xtau, "new  Xtau");
+
+        for(i=nV-1; i>=0; i--)
+          (*omega2)[i] = (*Xtau)[(nlev-1)*nV+i];
+
+        //Print("\n//  ring tau = %s;", rString(currRing));
+        rChangeCurrRing(oRing);
+        G = idrMoveR(Gt, testring,currRing);
+
+        goto NEXT_VECTOR_FRACTAL;
+#endif
+
+      FRACTAL_MSTDCC:
+        //Print("\n//  apply BB-Alg in ring = %s;", rString(currRing));
+        to=clock();
+        G = MstdCC(Gt);
+        xtextra=xtextra+clock()-to;
+
+        oRing = currRing;
+
+        // update the original target vector w.r.t. the current GB
+        if(MivSame(Xivinput, Xivlp) == 1)
+          if (rParameter(currRing) != NULL)
+            DefRingParlp();
+          else
+            VMrDefaultlp();
+        else
+          if (rParameter(currRing) != NULL)
+            DefRingPar(Xivinput);
+          else
+            rChangeCurrRing(VMrDefault1(Xivinput)); //Aenderung6
+
+        testring = currRing;
+        Gt = idrMoveR(G, oRing,currRing);
+
+        delete Xtau;
+        Xtau = NewVectorlp(Gt);
+
+        rChangeCurrRing(oRing);
+        G = idrMoveR(Gt, testring,currRing);
+
+        delete omega2;
+        delete next_vect;
+        delete altomega;
+        /*
+          Print("\n// Leaving the %d-th recursion with %d steps,", nlev,nwalks);
+          Print(" ** Overflow_Error? (%d)", Overflow_Error);
+        */
+        if(Overflow_Error == TRUE)
+          nnflow ++;
+
+        Overflow_Error = FALSE;
+        return(G);
+      }
+    }
+
+    for(i=nV-1; i>=0; i--) {
+      (*altomega)[i] = (*omega)[i];
+      (*omega)[i] = (*next_vect)[i];
+    }
+    delete next_vect;
+
+    to=clock();
+    /* Take the initial form of <G> w.r.t. omega */
+    Gomega = MwalkInitialForm(G, omega);
+    xtif=xtif+clock()-to;
+
+#ifndef  BUCHBERGER_ALG
+    if(isNolVector(omega) == 0)
+      hilb_func = hFirstSeries(Gomega,NULL,NULL,omega,currRing);
+    else
+      hilb_func = hFirstSeries(Gomega,NULL,NULL,last_omega,currRing);
+#endif // BUCHBERGER_ALG
+
+    if (rParameter(currRing) != NULL)
+      DefRingPar(omega);
+    else
+      rChangeCurrRing(VMrDefault1(omega)); //Aenderung7
+
+    Gomega1 = idrMoveR(Gomega, oRing,currRing);
+
+    /* Maximal recursion depth, to compute a red. GB */
+    /* Fractal walk with the alternative recursion */
+    /* alternative recursion */
+    // if(nlev == nV || lengthpoly(Gomega1) == 0)
+    if(nlev == Xnlev || lengthpoly(Gomega1) == 0)
+      //if(nlev == nV) // blind recursion
+    {
+      /*
+      if(Xnlev != nV)
+      {
+        Print("\n// ** Xnlev = %d", Xnlev);
+        ivString(Xtau, "Xtau");
+      }
+      */
+      to=clock();
+#ifdef  BUCHBERGER_ALG
+      Gresult = MstdhomCC(Gomega1);
+#else
+      Gresult =kStd(Gomega1,NULL,isHomog,NULL,hilb_func,0,NULL,omega);
+      delete hilb_func;
+#endif // BUCHBERGER_ALG
+      xtstd=xtstd+clock()-to;
+    }
+    else {
+      rChangeCurrRing(oRing);
+      Gomega1 = idrMoveR(Gomega1, oRing,currRing);
+      Gresult = rec_fractal_call(idCopy(Gomega1),nlev+1,omega);
+    }
+
+    //convert a Groebner basis from a ring to another ring,
+    new_ring = currRing;
+
+    rChangeCurrRing(oRing);
+    Gresult1 = idrMoveR(Gresult, new_ring,currRing);
+    Gomega2 = idrMoveR(Gomega1, new_ring,currRing);
+
+    to=clock();
+    /* Lifting process */
+    F = MLifttwoIdeal(Gomega2, Gresult1, G);
+    xtlift=xtlift+clock()-to;
+    idDelete(&Gresult1);
+    idDelete(&Gomega2);
+    idDelete(&G);
+
+    rChangeCurrRing(new_ring);
+    F1 = idrMoveR(F, oRing,currRing);
+
+    to=clock();
+    /* Interreduce G */
+    G = kInterRedCC(F1, NULL);
+    xtred=xtred+clock()-to;
+    idDelete(&F1);
+  }
+}
+
+
+
+
+/*******************************************************************************
+ * The implementation of the fractal walk algorithm                            *
+ *                                                                             *
+ * The main procedur Mfwalk calls the recursive Subroutine                     *
+ * rec_fractal_call to compute the wanted Gr�bner basis.                       *
+ * At the main procedur we compute the reduced Gr�bner basis w.r.t. a "fast"   *
+ * order, e.g. "dp" and a sequence of weight vectors which are row vectors     *
+ * of a matrix. This matrix defines the given monomial order, e.g. "lp"        *
+ *******************************************************************************/
+ideal Mfwalk(ideal G, intvec* ivstart, intvec* ivtarget)
+{
+  Set_Error(FALSE);
+  Overflow_Error = FALSE;
+  //Print("// pSetm_Error = (%d)", ErrorCheck());
+  //Print("\n// ring ro = %s;", rString(currRing));
+
+  nnflow = 0;
+  Xngleich = 0;
+  Xcall = 0;
+  xtif=0; xtstd=0; xtlift=0; xtred=0; xtnw=0; xtextra=0;
+  xftinput = clock();
+
+  ring  oldRing = currRing;
+  int i, nV = currRing->N;
+  XivNull = new intvec(nV);
+  Xivinput = ivtarget;
+  ngleich = 0;
+  to=clock();
+  ideal I = MstdCC(G);
+  G = NULL;
+  xftostd=clock()-to;
+  Xsigma = ivstart;
+
+  Xnlev=nV;
+
+#ifdef FIRST_STEP_FRACTAL
+  ideal Gw = MwalkInitialForm(I, ivstart);
+  for(i=IDELEMS(Gw)-1; i>=0; i--)
+  {
+    if((Gw->m[i]!=NULL) // len >=0
+    && (Gw->m[i]->next!=NULL) // len >=1
+    && (Gw->m[i]->next->next!=NULL)) // len >=2
+    {
+      intvec* iv_dp = MivUnit(nV); // define (1,1,...,1)
+      intvec* Mdp;
+
+      if(MivSame(ivstart, iv_dp) != 1)
+        Mdp = MivWeightOrderdp(ivstart);
+      else
+        Mdp = MivMatrixOrderdp(nV);
+
+      Xsigma = Mfpertvector(I, Mdp);
+      Overflow_Error = FALSE;
+
+      delete Mdp;
+      delete iv_dp;
+      break;
+    }
+  }
+  idDelete(&Gw);
+#endif
+
+  ideal I1;
+  intvec* Mlp;
+  Xivlp = Mivlp(nV);
+
+  if(MivComp(ivtarget, Xivlp)  != 1)
+  {
+    if (rParameter(currRing) != NULL)
+      DefRingPar(ivtarget);
+    else
+      rChangeCurrRing(VMrDefault1(ivtarget)); //Aenderung1
+
+    I1 = idrMoveR(I, oldRing,currRing);
+    Mlp = MivWeightOrderlp(ivtarget);
+    Xtau = Mfpertvector(I1, Mlp);
+  }
+  else
+  {
+    if (rParameter(currRing) != NULL)
+      DefRingParlp();
+    else
+      VMrDefaultlp();
+
+    I1 = idrMoveR(I, oldRing,currRing);
+    Mlp =  MivMatrixOrderlp(nV);
+    Xtau = Mfpertvector(I1, Mlp);
+  }
+  delete Mlp;
+  Overflow_Error = FALSE;
+
+  //ivString(Xsigma, "Xsigma");
+  //ivString(Xtau, "Xtau");
+
+  id_Delete(&I, oldRing);
+  ring tRing = currRing;
+
+  if (rParameter(currRing) != NULL)
+    DefRingPar(ivstart);
+  else
+    rChangeCurrRing(VMrDefault1(ivstart)); //Aenderung2
+
+  I = idrMoveR(I1,tRing,currRing);
+  to=clock();
+  ideal J = MstdCC(I);
+  idDelete(&I);
+  xftostd=xftostd+clock()-to;
+
+  ideal resF;
+  ring helpRing = currRing;
+
+  J = rec_fractal_call(J, 1, ivtarget);
+
+  rChangeCurrRing(oldRing);
+  resF = idrMoveR(J, helpRing,currRing);
+  idSkipZeroes(resF);
+
+  delete Xivlp;
+  delete Xsigma;
+  delete Xtau;
+  delete XivNull;
+
+#ifdef TIME_TEST
+  TimeStringFractal(xftinput, xftostd, xtif, xtstd, xtextra,
+                    xtlift, xtred, xtnw);
+
+
+  Print("\n// pSetm_Error = (%d)", ErrorCheck());
+  Print("\n// Overflow_Error? (%d)\n", Overflow_Error);
+  Print("\n// the numbers of Overflow_Error (%d)", nnflow);
+#endif
+
+  return(resF);
+}
+
+ideal Mfrwalk(ideal G, intvec* ivstart, intvec* ivtarget,int weight_rad)
+{
+  Set_Error(FALSE);
+  Overflow_Error = FALSE;
+  //Print("// pSetm_Error = (%d)", ErrorCheck());
+  //Print("\n// ring ro = %s;", rString(currRing));
+
+  nnflow = 0;
+  Xngleich = 0;
+  Xcall = 0;
+  xtif=0; xtstd=0; xtlift=0; xtred=0; xtnw=0; xtextra=0;
+  xftinput = clock();
+
+  ring  oldRing = currRing;
+  int i, nV = currRing->N;
+  XivNull = new intvec(nV);
+  Xivinput = ivtarget;
+  ngleich = 0;
+  to=clock();
+  ideal I = MstdCC(G);
+  G = NULL;
+  xftostd=clock()-to;
+  Xsigma = ivstart;
+
+  Xnlev=nV;
+
+#ifdef FIRST_STEP_FRACTAL
+  ideal Gw = MwalkInitialForm(I, ivstart);
+  for(i=IDELEMS(Gw)-1; i>=0; i--)
+  {
+    if((Gw->m[i]!=NULL) // len >=0
+    && (Gw->m[i]->next!=NULL) // len >=1
+    && (Gw->m[i]->next->next!=NULL)) // len >=2
+    {
+      intvec* iv_dp = MivUnit(nV); // define (1,1,...,1)
+      intvec* Mdp;
+
+      if(MivSame(ivstart, iv_dp) != 1)
+        Mdp = MivWeightOrderdp(ivstart);
+      else
+        Mdp = MivMatrixOrderdp(nV);
+
+      Xsigma = Mfpertvector(I, Mdp);
+      Overflow_Error = FALSE;
+
+      delete Mdp;
+      delete iv_dp;
+      break;
+    }
+  }
+  idDelete(&Gw);
+#endif
+
+  ideal I1;
+  intvec* Mlp;
+  Xivlp = Mivlp(nV);
+
+  if(MivComp(ivtarget, Xivlp)  != 1)
+  {
+    if (rParameter(currRing) != NULL)
+      DefRingPar(ivtarget);
+    else
+      rChangeCurrRing(VMrDefault1(ivtarget)); //Aenderung1
+
+    I1 = idrMoveR(I, oldRing,currRing);
+    Mlp = MivWeightOrderlp(ivtarget);
+    Xtau = Mfpertvector(I1, Mlp);
+  }
+  else
+  {
+    if (rParameter(currRing) != NULL)
+      DefRingParlp();
+    else
+      VMrDefaultlp();
+
+    I1 = idrMoveR(I, oldRing,currRing);
+    Mlp =  MivMatrixOrderlp(nV);
+    Xtau = Mfpertvector(I1, Mlp);
+  }
+  delete Mlp;
+  Overflow_Error = FALSE;
+
+  //ivString(Xsigma, "Xsigma");
+  //ivString(Xtau, "Xtau");
+
+  id_Delete(&I, oldRing);
+  ring tRing = currRing;
+
+  if (rParameter(currRing) != NULL)
+    DefRingPar(ivstart);
+  else
+    rChangeCurrRing(VMrDefault1(ivstart)); //Aenderung2
+
+  I = idrMoveR(I1,tRing,currRing);
+  to=clock();
+  ideal J = MstdCC(I);
+  idDelete(&I);
+  xftostd=xftostd+clock()-to;
+
+  ideal resF;
+  ring helpRing = currRing;
+//ideal G, int nlev, intvec* omtmp, int weight_rad)
+  J = rec_r_fractal_call(J, 1, ivtarget,weight_rad);
+
+  rChangeCurrRing(oldRing);
+  resF = idrMoveR(J, helpRing,currRing);
+  idSkipZeroes(resF);
+
+  delete Xivlp;
+  delete Xsigma;
+  delete Xtau;
+  delete XivNull;
+
+#ifdef TIME_TEST
+  TimeStringFractal(xftinput, xftostd, xtif, xtstd, xtextra,
+                    xtlift, xtred, xtnw);
+
+
+  Print("\n// pSetm_Error = (%d)", ErrorCheck());
+  Print("\n// Overflow_Error? (%d)\n", Overflow_Error);
+  Print("\n// the numbers of Overflow_Error (%d)", nnflow);
+#endif
+
+  return(resF);
+}
+
+/*******************************************************
+ * Tran's algorithm                                    *
+ *                                                     *
+ * use kStd, if nP = 0, else call Ab_Rec_Pert (LastGB) *
+ *******************************************************/
+ideal TranMImprovwalk(ideal G,intvec* curr_weight,intvec* target_tmp, int nP)
+{
+#ifdef TIME_TEST
+  clock_t mtim = clock();
+#endif
+  Set_Error(FALSE  );
+  Overflow_Error =  FALSE;
+  //Print("// pSetm_Error = (%d)", ErrorCheck());
+  //Print("\n// ring ro = %s;", rString(currRing));
+
+  clock_t tostd, tif=0, tstd=0, tlift=0, tred=0, tnw=0, textra=0;
+#ifdef TIME_TEST
+  clock_t tinput = clock();
+#endif
+  int nsteppert=0, i, nV = currRing->N, nwalk=0, npert_tmp=0;
+  int *npert=(int*)omAlloc(2*nV*sizeof(int));
+  ideal Gomega, M,F,  G1, Gomega1, Gomega2, M1, F1;
+  //ring endRing;
+  ring newRing, oldRing, lpRing;
+  intvec* next_weight;
+  intvec* ivNull = new intvec(nV); //define (0,...,0)
+  intvec* iv_dp = MivUnit(nV);// define (1,1,...,1)
+  intvec* iv_lp = Mivlp(nV); //define (1,0,...,0)
+  ideal H0;
+  //ideal  H1;
+  ideal H2, Glp;
+  int nGB, endwalks = 0,  nwalkpert=0,  npertstep=0;
+  intvec* Mlp =  MivMatrixOrderlp(nV);
+  intvec* vector_tmp = new intvec(nV);
+#ifndef BUCHBERGER_ALG
+  intvec* hilb_func;
+#endif
+  /* to avoid (1,0,...,0) as the target vector */
+  intvec* last_omega = new intvec(nV);
+  for(i=nV-1; i>0; i--)
+    (*last_omega)[i] = 1;
+  (*last_omega)[0] = 10000;
+
+  //  intvec* extra_curr_weight = new intvec(nV);
+  intvec* target_weight = new intvec(nV);
+  for(i=nV-1; i>=0; i--)
+    (*target_weight)[i] = (*target_tmp)[i];
+
+  ring XXRing = currRing;
+  newRing = currRing;
+
+  to=clock();
+  /* compute a red. GB w.r.t. the help ring */
+  if(MivComp(curr_weight, iv_dp) == 1) //rOrdStr(currRing) = "dp"
+    G = MstdCC(G);
+  else
+  {
+    //rOrdStr(currRing) = (a(.c_w..),lp,C)
+    if (rParameter(currRing) != NULL)
+      DefRingPar(curr_weight);
+    else
+      rChangeCurrRing(VMrDefault(curr_weight)); // Aenderung 4
+    G = idrMoveR(G, XXRing,currRing);
+    G = MstdCC(G);
+  }
+  tostd=clock()-to;
+
+#ifdef REPRESENTATION_OF_SIGMA
+  ideal Gw = MwalkInitialForm(G, curr_weight);
+
+  if(islengthpoly2(Gw)==1)
+  {
+    intvec* MDp;
+    if(MivComp(curr_weight, iv_dp) == 1)
+      MDp = MatrixOrderdp(nV); //MivWeightOrderlp(iv_dp);
+    else
+      MDp = MivWeightOrderlp(curr_weight);
+
+    curr_weight = RepresentationMatrix_Dp(G, MDp);
+
+    delete MDp;
+
+    ring exring = currRing;
+
+    if (rParameter(currRing) != NULL)
+      DefRingPar(curr_weight);
+    else
+      rChangeCurrRing(VMrDefault(curr_weight)); //Aenderung 5
+    to=clock();
+    Gw = idrMoveR(G, exring,currRing);
+    G = MstdCC(Gw);
+    Gw = NULL;
+    tostd=tostd+clock()-to;
+    //ivString(curr_weight,"rep. sigma");
+    goto COMPUTE_NEW_VECTOR;
+  }
+
+  idDelete(&Gw);
+  delete iv_dp;
+#endif
+
+
+  while(1)
+  {
+    to=clock();
+    /* compute an initial form ideal of <G> w.r.t. "curr_vector" */
+    Gomega = MwalkInitialForm(G, curr_weight);
+    tif=tif+clock()-to;
+
+#ifndef  BUCHBERGER_ALG
+    if(isNolVector(curr_weight) == 0)
+      hilb_func = hFirstSeries(Gomega,NULL,NULL,curr_weight,currRing);
+    else
+      hilb_func = hFirstSeries(Gomega,NULL,NULL,last_omega,currRing);
+#endif // BUCHBERGER_ALG
+
+    oldRing = currRing;
+
+    /* define a new ring that its ordering is "(a(curr_weight),lp) */
+    if (rParameter(currRing) != NULL)
+      DefRingPar(curr_weight);
+    else
+      rChangeCurrRing(VMrDefault(curr_weight)); //Aenderung 6
+
+    newRing = currRing;
+    Gomega1 = idrMoveR(Gomega, oldRing,currRing);
+
+    to=clock();
+    /* compute a reduced Groebner basis of <Gomega> w.r.t. "newRing" */
+#ifdef  BUCHBERGER_ALG
+    M = MstdhomCC(Gomega1);
+#else
+    M=kStd(Gomega1,NULL,isHomog,NULL,hilb_func,0,NULL,curr_weight);
+    delete hilb_func;
+#endif // BUCHBERGER_ALG
+    tstd=tstd+clock()-to;
+
+    /* change the ring to oldRing */
+    rChangeCurrRing(oldRing);
+    M1 =  idrMoveR(M, newRing,currRing);
+    Gomega2 =  idrMoveR(Gomega1, newRing,currRing);
+
+    to=clock();
+    /* compute a representation of the generators of submod (M)
+       with respect to those of mod (Gomega).
+       Gomega is a reduced Groebner basis w.r.t. the current ring */
+    F = MLifttwoIdeal(Gomega2, M1, G);
+    tlift=tlift+clock()-to;
+
+    idDelete(&M1);
+    idDelete(&Gomega2);
+    idDelete(&G);
+
+    /* change the ring to newRing */
+    rChangeCurrRing(newRing);
+    F1 = idrMoveR(F, oldRing,currRing);
+
+    to=clock();
+    /* reduce the Groebner basis <G> w.r.t. new ring */
+    G = kInterRedCC(F1, NULL);
+    tred=tred+clock()-to;
+    idDelete(&F1);
+
+
+  COMPUTE_NEW_VECTOR:
+    newRing = currRing;
+    nwalk++;
+    nwalkpert++;
+    to=clock();
+    // compute a next weight vector
+    next_weight = MwalkNextWeightCC(curr_weight,target_weight, G);
+    tnw=tnw+clock()-to;
+#ifdef PRINT_VECTORS
+    MivString(curr_weight, target_weight, next_weight);
+#endif
+
+
+    /* check whether the computed intermediate weight vector is in
+       the correct cone; sometimes it is very big e.g. s7, cyc7.
+       If it is NOT in the correct cone, then compute directly
+       a reduced Groebner basis with respect to the lexicographic ordering
+       for the known Groebner basis that it is computed in the last step.
+    */
+    //if(test_w_in_ConeCC(G, next_weight) != 1)
+    if(Overflow_Error == TRUE)
+    {
+    OMEGA_OVERFLOW_TRAN_NEW:
+      //Print("\n//  takes %d steps!", nwalk-1);
+      //Print("\n//ring lastRing = %s;", rString(currRing));
+#ifdef TEST_OVERFLOW
+      goto  BE_FINISH;
+#endif
+
+#ifdef CHECK_IDEAL_MWALK
+      idElements(G, "G");
+      //headidString(G, "G");
+#endif
+
+      if(MivSame(target_tmp, iv_lp) == 1)
+        if (rParameter(currRing) != NULL)
+          DefRingParlp();
+        else
+          VMrDefaultlp();
+      else
+        if (rParameter(currRing) != NULL)
+          DefRingPar(target_tmp);
+        else
+          rChangeCurrRing(VMrDefault(target_tmp)); // Aenderung 8
+
+      lpRing = currRing;
+      G1 = idrMoveR(G, newRing,currRing);
+
+      to=clock();
+      /*apply kStd or LastGB to compute  a lex. red. Groebner basis of <G>*/
+      if(nP == 0 || MivSame(target_tmp, iv_lp) == 0){
+        //Print("\n\n// calls \"std in ring r_%d = %s;", nwalk, rString(currRing));
+        G = MstdCC(G1);//no result for qnt1
+      }
+      else {
+        rChangeCurrRing(newRing);
+        G1 = idrMoveR(G1, lpRing,currRing);
+
+        //Print("\n\n// calls \"LastGB\" (%d) to compute a GB", nV-1);
+        G = LastGB(G1, curr_weight, nV-1); //no result for kats7
+
+        rChangeCurrRing(lpRing);
+        G = idrMoveR(G, newRing,currRing);
+      }
+      textra=clock()-to;
+      npert[endwalks]=nwalk-npert_tmp;
+      npert_tmp = nwalk;
+      endwalks ++;
+      break;
+    }
+
+    /* check whether the computed Groebner basis is really a Groebner basis.
+       If not, we perturb the target vector with the maximal "perturbation"
+       degree.*/
+    if(MivComp(next_weight, target_weight) == 1 ||
+       MivComp(next_weight, curr_weight) == 1 )
+    {
+      //Print("\n//ring r_%d = %s;", nwalk, rString(currRing));
+
+
+      //compute the number of perturbations and its step
+      npert[endwalks]=nwalk-npert_tmp;
+      npert_tmp = nwalk;
+
+      endwalks ++;
+
+      /*it is very important if the walk only uses one step, e.g. Fate, liu*/
+      if(endwalks == 1 && MivComp(next_weight, curr_weight) == 1){
+        rChangeCurrRing(XXRing);
+        G = idrMoveR(G, newRing,currRing);
+        goto FINISH;
+      }
+      H0 = id_Head(G,currRing);
+
+      if(MivSame(target_tmp, iv_lp) == 1)
+        if (rParameter(currRing) != NULL)
+          DefRingParlp();
+        else
+          VMrDefaultlp();
+      else
+        if (rParameter(currRing) != NULL)
+          DefRingPar(target_tmp);
+        else
+          rChangeCurrRing(VMrDefault(target_tmp)); //Aenderung 9
+
+      lpRing = currRing;
+      Glp = idrMoveR(G, newRing,currRing);
+      H2 = idrMoveR(H0, newRing,currRing);
+
+      /* Apply Lemma 2.2 in Collart et. al (1997) to check whether
+         cone(k-1) is equal to cone(k) */
+      nGB = 1;
+      for(i=IDELEMS(Glp)-1; i>=0; i--)
+      {
+        poly t;
+        if((t=pSub(pHead(Glp->m[i]), pCopy(H2->m[i]))) != NULL)
+        {
+          pDelete(&t);
+          idDelete(&H2);//5.5.02
+          nGB = 0; //i.e. Glp is no reduced Groebner basis
+          break;
+        }
+        pDelete(&t);
+      }
+
+      idDelete(&H2);//5.5.02
+
+      if(nGB == 1)
+      {
+        G = Glp;
+        Glp = NULL;
+        break;
+      }
+
+       /* perturb the target weight vector, if the vector target_tmp
+          stays in many cones */
+      poly p;
+      BOOLEAN plength3 = FALSE;
+      for(i=IDELEMS(Glp)-1; i>=0; i--)
+      {
+        p = MpolyInitialForm(Glp->m[i], target_tmp);
+        if(p->next != NULL &&
+           p->next->next != NULL &&
+           p->next->next->next != NULL)
+        {
+          Overflow_Error = FALSE;
+
+          for(i=0; i<nV; i++)
+            (*vector_tmp)[i] = (*target_weight)[i];
+
+          delete target_weight;
+          target_weight = MPertVectors(Glp, Mlp, nV);
+
+          if(MivComp(vector_tmp, target_weight)==1)
+          {
+            //PrintS("\n// The old and new representaion vector are the same!!");
+            G = Glp;
+            newRing = currRing;
+            goto OMEGA_OVERFLOW_TRAN_NEW;
+           }
+
+          if(Overflow_Error == TRUE)
+          {
+            rChangeCurrRing(newRing);
+            G = idrMoveR(Glp, lpRing,currRing);
+            goto OMEGA_OVERFLOW_TRAN_NEW;
+          }
+
+          plength3 = TRUE;
+          pDelete(&p);
+          break;
+        }
+        pDelete(&p);
+      }
+
+      if(plength3 == FALSE)
+      {
+        rChangeCurrRing(newRing);
+        G = idrMoveR(Glp, lpRing,currRing);
+        goto TRAN_LIFTING;
+      }
+
+
+      npertstep = nwalk;
+      nwalkpert = 1;
+      nsteppert ++;
+
+      /*
+      Print("\n// Subroutine needs (%d) steps.", nwalk);
+      idElements(Glp, "last G in walk:");
+      PrintS("\n// ****************************************");
+      Print("\n// Perturb the original target vector (%d): ", nsteppert);
+      ivString(target_weight, "new target");
+      PrintS("\n// ****************************************\n");
+      */
+      rChangeCurrRing(newRing);
+      G = idrMoveR(Glp, lpRing,currRing);
+
+      delete next_weight;
+
+      //Print("\n// ring rNEW = %s;", rString(currRing));
+      goto COMPUTE_NEW_VECTOR;
+    }
+
+  TRAN_LIFTING:
+    for(i=nV-1; i>=0; i--)
+      (*curr_weight)[i] = (*next_weight)[i];
+
+    delete next_weight;
+  }//while
+#ifdef TEST_OVERFLOW
+ BE_FINISH:
+#endif
+  rChangeCurrRing(XXRing);
+  G = idrMoveR(G, lpRing,currRing);
+
+ FINISH:
+  delete ivNull;
+  delete next_weight;
+  delete iv_lp;
+  omFree(npert);
+
+#ifdef TIME_TEST
+  Print("\n// Computation took %d steps and %.2f sec",
+        nwalk, ((double) (clock()-mtim)/1000000));
+
+  TimeStringFractal(tinput, tostd, tif, tstd, textra, tlift, tred, tnw);
+
+  Print("\n// pSetm_Error = (%d)", ErrorCheck());
+  Print("\n// Overflow_Error? (%d)\n", Overflow_Error);
+#endif
+
+  return(G);
+}
+
+#if 0
+/*******************************************************
+ * Tran's algorithm with random element                *
+ *                                                     *
+ * use kStd, if nP = 0, else call Ab_Rec_Pert (LastGB) *
+ *******************************************************/
+ideal TranMrImprovwalk(ideal G,intvec* curr_weight,intvec* target_tmp, int nP, int weight_rad, int pert_deg)
+{
+#ifdef TIME_TEST
+  clock_t mtim = clock();
+#endif
+  Set_Error(FALSE  );
+  Overflow_Error =  FALSE;
+  //Print("// pSetm_Error = (%d)", ErrorCheck());
+  //Print("\n// ring ro = %s;", rString(currRing));
+
+  clock_t tostd, tif=0, tstd=0, tlift=0, tred=0, tnw=0, textra=0;
+#ifdef TIME_TEST
+  clock_t tinput = clock();
+#endif
+  int nsteppert=0, i, nV = currRing->N, nwalk=0, npert_tmp=0;
+  int *npert=(int*)omAlloc(2*nV*sizeof(int));
+  ideal Gomega, M,F,  G1, Gomega1, Gomega2, M1, F1;
+  //ring endRing;
+  ring newRing, oldRing, lpRing;
+  intvec* next_weight;
+  intvec* ivNull = new intvec(nV); //define (0,...,0)
+  intvec* iv_dp = MivUnit(nV);// define (1,1,...,1)
+  intvec* iv_lp = Mivlp(nV); //define (1,0,...,0)
+  ideal H0;
+  //ideal H1;
+  ideal H2, Glp;
+  int weight_norm, nGB, endwalks = 0,  nwalkpert=0,  npertstep=0;
+  intvec* Mlp =  MivMatrixOrderlp(nV);
+  intvec* vector_tmp = new intvec(nV);
+#ifndef BUCHBERGER_ALG
+  intvec* hilb_func;
+#endif
+  // to avoid (1,0,...,0) as the target vector
+  intvec* last_omega = new intvec(nV);
+  for(i=nV-1; i>0; i--)
+  {
+    (*last_omega)[i] = 1;
+  }
+  (*last_omega)[0] = 10000;
+
+//intvec* extra_curr_weight = new intvec(nV);
+  intvec* target_weight = new intvec(nV);
+  for(i=nV-1; i>=0; i--)
+  {
+    (*target_weight)[i] = (*target_tmp)[i];
+  }
+  ring XXRing = currRing;
+  newRing = currRing;
+
+  to=clock();
+  // compute a red. GB w.r.t. the help ring
+  if(MivComp(curr_weight, iv_dp) == 1)
+  {
+    //rOrdStr(currRing) = "dp"
+    G = MstdCC(G);
+  }
+  else
+  {
+    //rOrdStr(currRing) = (a(.c_w..),lp,C)
+    if (rParameter(currRing) != NULL)
+    {
+      DefRingPar(curr_weight);
+    }
+    else
+    {
+      rChangeCurrRing(VMrDefault(curr_weight)); // Aenderung 10
+    }
+    G = idrMoveR(G, XXRing,currRing);
+    G = MstdCC(G);
+  }
+  tostd=clock()-to;
+
+#ifdef REPRESENTATION_OF_SIGMA
+  ideal Gw = MwalkInitialForm(G, curr_weight);
+
+  if(islengthpoly2(Gw)==1)
+  {
+    intvec* MDp;
+    if(MivComp(curr_weight, iv_dp) == 1)
+    {
+      MDp = MatrixOrderdp(nV); //MivWeightOrderlp(iv_dp);
+    }
+    else
+    {
+      MDp = MivWeightOrderlp(curr_weight);
+    }
+    curr_weight = RepresentationMatrix_Dp(G, MDp);
+
+    delete MDp;
+
+    ring exring = currRing;
+
+    if (rParameter(currRing) != NULL)
+    {
+      DefRingPar(curr_weight);
+    }
+    else
+    {
+      rChangeCurrRing(VMrDefault(curr_weight)); //Aenderung 11
+    }
+    to=clock();
+    Gw = idrMoveR(G, exring,currRing);
+    G = MstdCC(Gw);
+    Gw = NULL;
+    tostd=tostd+clock()-to;
+    //ivString(curr_weight,"rep. sigma");
+    goto COMPUTE_NEW_VECTOR;
+  }
+
+  idDelete(&Gw);
+  delete iv_dp;
+#endif
+
+
+  while(1)
+  {
+    to=clock();
+    // compute an initial form ideal of <G> w.r.t. "curr_vector"
+    Gomega = MwalkInitialForm(G, curr_weight);
+    tif=tif+clock()-to;
+
+#ifndef  BUCHBERGER_ALG
+    if(isNolVector(curr_weight) == 0)
+    {
+      hilb_func = hFirstSeries(Gomega,NULL,NULL,curr_weight,currRing);
+    }
+    else
+    {
+      hilb_func = hFirstSeries(Gomega,NULL,NULL,last_omega,currRing);
+    }
+#endif // BUCHBERGER_ALG
+
+    oldRing = currRing;
+
+    // define a new ring with ordering "(a(curr_weight),lp)
+    if (rParameter(currRing) != NULL)
+    {
+      DefRingPar(curr_weight);
+    }
+    else
+    {
+      rChangeCurrRing(VMrDefault(curr_weight)); // Aenderung 12
+    }
+    newRing = currRing;
+    Gomega1 = idrMoveR(Gomega, oldRing,currRing);
+
+    to=clock();
+    // compute a reduced Groebner basis of <Gomega> w.r.t. "newRing"
+#ifdef  BUCHBERGER_ALG
+    M = MstdhomCC(Gomega1);
+#else
+    M=kStd(Gomega1,NULL,isHomog,NULL,hilb_func,0,NULL,curr_weight);
+    delete hilb_func;
+#endif
+    tstd=tstd+clock()-to;
+
+    // change the ring to oldRing
+    rChangeCurrRing(oldRing);
+    M1 =  idrMoveR(M, newRing,currRing);
+    Gomega2 =  idrMoveR(Gomega1, newRing,currRing);
+
+    to=clock();
+    // compute a representation of the generators of submod (M) with respect to those of mod (Gomega).
+    // Gomega is a reduced Groebner basis w.r.t. the current ring
+    F = MLifttwoIdeal(Gomega2, M1, G);
+    tlift=tlift+clock()-to;
+
+    idDelete(&M1);
+    idDelete(&Gomega2);
+    idDelete(&G);
+
+    // change the ring to newRing
+    rChangeCurrRing(newRing);
+    F1 = idrMoveR(F, oldRing,currRing);
+
+    to=clock();
+    // reduce the Groebner basis <G> w.r.t. new ring
+    G = kInterRedCC(F1, NULL);
+    tred=tred+clock()-to;
+    idDelete(&F1);
+
+  COMPUTE_NEW_VECTOR:
+    newRing = currRing;
+    nwalk++;
+    nwalkpert++;
+    to=clock();
+    // compute a next weight vector
+    //next_weight = MwalkNextWeightCC(curr_weight,target_weight, G);
+    next_weight = MWalkRandomNextWeight(G, curr_weight, target_weight, weight_rad, pert_deg);
+/*
+    next_weight = MkInterRedNextWeight(curr_weight,target_weight,G);
+
+    if(MivComp(next_weight, target_weight) != 1)
+    {
+      // compute a perturbed next weight vector "next_weight1"
+      intvec* next_weight1 = MkInterRedNextWeight(MPertVectors(G, MivMatrixOrder(curr_weight), pert_deg), target_weight, G);
+
+      // compare next_weight and next_weight1
+      ideal G_test = MwalkInitialForm(G, next_weight);
+      ideal G_test1 = MwalkInitialForm(G, next_weight1);
+      if(IDELEMS(G_test1) <= IDELEMS(G_test))
+      {
+        next_weight = ivCopy(next_weight1);
+      }
+      delete next_weight1;
+      // compute a random next weight vector "next_weight2"
+      intvec* next_weight22 = ivCopy(target_weight);
+      // Print("\n//  size of target_weight  = %d", sizeof((*target_weight)));
+      k = 0;
+
+      while(test_w_in_ConeCC(G, next_weight22) == 0 && k < 11)
+      {
+        k++;
+        if(k>10)
+        {
+          break;
+        }
+        weight_norm = 0;
+        while(weight_norm == 0)
+        {
+          for(i=nV-1; i>=0; i--)
+          {
+            // Print("\n//  next_weight[%d]  = %d", i, (*next_weight)[i]);
+            (*next_weight22)[i] = rand() % 60000 - 30000;
+            weight_norm = weight_norm + (*next_weight22)[i]*(*next_weight22)[i];
+          }
+          weight_norm = 1 + floor(sqrt(weight_norm));
+        }
+        for(i=nV-1; i>=0; i--)
+        {
+          if((*next_weight22)[i] < 0)
+          {
+            (*next_weight22)[i] = 1 + (*curr_weight)[i] + floor(weight_rad*(*next_weight22)[i]/weight_norm);
+          }
+          else
+          {
+            (*next_weight22)[i] = (*curr_weight)[i] + floor(weight_rad*(*next_weight22)[i]/weight_norm);
+          }
+          // Print("\n//  next_weight22[%d]  = %d", i, (*next_weight22)[i]);
+        }
+      }
+
+      if(test_w_in_ConeCC(G, next_weight22) == 1)
+      {
+        // compare next_weight and next_weight2
+        // Print("\n// ZUFALL IM KEGEL");
+        intvec* next_weight2 = MkInterRedNextWeight(next_weight22, target_weight, G);
+
+        ideal G_test2 = MwalkInitialForm(G, next_weight2);
+        if(IDELEMS(G_test2) <= IDELEMS(G_test))
+        {
+          if(IDELEMS(G_test2) <= IDELEMS(G_test1))
+          {
+             // Print("\n// ZUFALL BENUTZT!\n");
+            next_weight = ivCopy(next_weight2);
+          }
+        }
+        idDelete(&G_test2);
+        delete next_weight2;
+      }
+      delete next_weight22;
+      idDelete(&G_test);
+      idDelete(&G_test1);
+    }*/
+
+    tnw=tnw+clock()-to;
+#ifdef PRINT_VECTORS
+    MivString(curr_weight, target_weight, next_weight);
+#endif
+
+/*   check whether the computed intermediate weight vector is in
+     the correct cone; sometimes it is very big e.g. s7, cyc7.
+     If it is NOT in the correct cone, then compute directly
+     a reduced Groebner basis with respect to the lexicographic ordering
+     for the known Groebner basis that it is computed in the last step.
+*/
+    //if(test_w_in_ConeCC(G, next_weight) != 1)
+    if(Overflow_Error == TRUE)
+    {
+    OMEGA_OVERFLOW_TRAN_NEW:
+      //Print("\n//  takes %d steps!", nwalk-1);
+      //Print("\n//ring lastRing = %s;", rString(currRing));
+#ifdef TEST_OVERFLOW
+      goto  BE_FINISH;
+#endif
+
+#ifdef CHECK_IDEAL_MWALK
+      idElements(G, "G");
+      //headidString(G, "G");
+#endif
+
+      if(MivSame(target_tmp, iv_lp) == 1)
+      {
+        if (rParameter(currRing) != NULL)
+        {
+          DefRingParlp();
+        }
+        else
+        {
+          VMrDefaultlp();
+        }
+      }
+      else
+      {
+        if (rParameter(currRing) != NULL)
+        {
+          DefRingPar(target_tmp);
+        }
+        else
+        {
+          rChangeCurrRing(VMrDefault(target_tmp)); // Aenderung 13
+        }
+      }
+      lpRing = currRing;
+      G1 = idrMoveR(G, newRing,currRing);
+
+      to=clock();
+      // apply kStd or LastGB to compute  a lex. red. Groebner basis of <G>
+      if(nP == 0 || MivSame(target_tmp, iv_lp) == 0)
+      {
+        //Print("\n\n// calls \"std in ring r_%d = %s;", nwalk, rString(currRing));
+        G = MstdCC(G1);//no result for qnt1
+      }
+      else
+      {
+        rChangeCurrRing(newRing);
+        G1 = idrMoveR(G1, lpRing,currRing);
+
+        //Print("\n\n// calls \"LastGB\" (%d) to compute a GB", nV-1);
+        G = LastGB(G1, curr_weight, nV-1); //no result for kats7
+
+        rChangeCurrRing(lpRing);
+        G = idrMoveR(G, newRing,currRing);
+      }
+      textra=clock()-to;
+      npert[endwalks]=nwalk-npert_tmp;
+      npert_tmp = nwalk;
+      endwalks ++;
+      break;
+    }
+
+    // check whether the computed Groebner basis is really a Groebner basis.
+    // If not, we perturb the target vector with the maximal "perturbation" degree.
+
+    if(MivComp(next_weight, target_weight) == 1 || MivComp(next_weight, curr_weight) == 1 )
+    {
+      //Print("\n//ring r_%d = %s;", nwalk, rString(currRing));
+
+
+      //compute the number of perturbations and its step
+      npert[endwalks]=nwalk-npert_tmp;
+      npert_tmp = nwalk;
+
+      endwalks ++;
+
+      // it is very important if the walk only uses one step, e.g. Fate, liu
+      if(endwalks == 1 && MivComp(next_weight, curr_weight) == 1)
+      {
+        rChangeCurrRing(XXRing);
+        G = idrMoveR(G, newRing,currRing);
+        goto FINISH;
+      }
+      H0 = id_Head(G,currRing);
+
+      if(MivSame(target_tmp, iv_lp) == 1)
+      {
+        if (rParameter(currRing) != NULL)
+        {
+          DefRingParlp();
+        }
+        else
+        {
+          VMrDefaultlp();
+        }
+      }
+      else
+      {
+        if (rParameter(currRing) != NULL)
+        {
+          DefRingPar(target_tmp);
+        }
+        else
+        {
+          rChangeCurrRing(VMrDefault(target_tmp)); // Aenderung 14
+        }
+      }
+      lpRing = currRing;
+      Glp = idrMoveR(G, newRing,currRing);
+      H2 = idrMoveR(H0, newRing,currRing);
+
+      // Apply Lemma 2.2 in Collart et. al (1997) to check whether cone(k-1) is equal to cone(k)
+      nGB = 1;
+      for(i=IDELEMS(Glp)-1; i>=0; i--)
+      {
+        poly t;
+        if((t=pSub(pHead(Glp->m[i]), pCopy(H2->m[i]))) != NULL)
+        {
+          pDelete(&t);
+          idDelete(&H2);//5.5.02
+          nGB = 0; //i.e. Glp is no reduced Groebner basis
+          break;
+        }
+        pDelete(&t);
+      }
+
+      idDelete(&H2);//5.5.02
+
+      if(nGB == 1)
+      {
+        G = Glp;
+        Glp = NULL;
+        break;
+      }
+
+       // perturb the target weight vector, if the vector target_tmp stays in many cones
+      poly p;
+      BOOLEAN plength3 = FALSE;
+      for(i=IDELEMS(Glp)-1; i>=0; i--)
+      {
+        p = MpolyInitialForm(Glp->m[i], target_tmp);
+        if(p->next != NULL &&
+           p->next->next != NULL &&
+           p->next->next->next != NULL)
+        {
+          Overflow_Error = FALSE;
+
+          for(i=0; i<nV; i++)
+          {
+            (*vector_tmp)[i] = (*target_weight)[i];
+          }
+          delete target_weight;
+          target_weight = MPertVectors(Glp, Mlp, nV);
+
+          if(MivComp(vector_tmp, target_weight)==1)
+          {
+            //PrintS("\n// The old and new representaion vector are the same!!");
+            G = Glp;
+            newRing = currRing;
+            goto OMEGA_OVERFLOW_TRAN_NEW;
+           }
+
+          if(Overflow_Error == TRUE)
+          {
+            rChangeCurrRing(newRing);
+            G = idrMoveR(Glp, lpRing,currRing);
+            goto OMEGA_OVERFLOW_TRAN_NEW;
+          }
+
+          plength3 = TRUE;
+          pDelete(&p);
+          break;
+        }
+        pDelete(&p);
+      }
+
+      if(plength3 == FALSE)
+      {
+        rChangeCurrRing(newRing);
+        G = idrMoveR(Glp, lpRing,currRing);
+        goto TRAN_LIFTING;
+      }
+
+
+      npertstep = nwalk;
+      nwalkpert = 1;
+      nsteppert ++;
+
+      /*
+      Print("\n// Subroutine needs (%d) steps.", nwalk);
+      idElements(Glp, "last G in walk:");
+      PrintS("\n// ****************************************");
+      Print("\n// Perturb the original target vector (%d): ", nsteppert);
+      ivString(target_weight, "new target");
+      PrintS("\n// ****************************************\n");
+      */
+      rChangeCurrRing(newRing);
+      G = idrMoveR(Glp, lpRing,currRing);
+
+      delete next_weight;
+
+      //Print("\n// ring rNEW = %s;", rString(currRing));
+      goto COMPUTE_NEW_VECTOR;
+    }
+
+  TRAN_LIFTING:
+    for(i=nV-1; i>=0; i--)
+    {
+      (*curr_weight)[i] = (*next_weight)[i];
+    }
+    delete next_weight;
+  } // end of while
+#ifdef TEST_OVERFLOW
+ BE_FINISH:
+#endif
+  rChangeCurrRing(XXRing);
+  G = idrMoveR(G, lpRing,currRing);
+
+ FINISH:
+  delete ivNull;
+  delete next_weight;
+  delete iv_lp;
+  omFree(npert);
+
+#ifdef TIME_TEST
+  Print("\n// Computation took %d steps and %.2f sec", nwalk, ((double) (clock()-mtim)/1000000));
+
+  TimeStringFractal(tinput, tostd, tif, tstd, textra, tlift, tred, tnw);
+
+  Print("\n// pSetm_Error = (%d)", ErrorCheck());
+  Print("\n// Overflow_Error? (%d)\n", Overflow_Error);
+#endif
+
+  return(G);
+}
+#endif
+
+/*****************************************************************
+ * compute the reduced Groebner basis of an ideal <Go> w.r.t. lp *
+ *****************************************************************/
+static ideal Mpwalk_MAltwalk1(ideal Go, intvec* curr_weight, int tp_deg)
+{
+  Overflow_Error = FALSE;
+ // BOOLEAN nOverflow_Error = FALSE;
+  clock_t tproc=0;
+  clock_t tinput=clock();
+  int i, nV = currRing->N;
+  int nwalk=0, endwalks=0, ntestwinC=1;
+  int tp_deg_tmp = tp_deg;
+  ideal Gomega, M, F, G, M1, F1, Gomega1, Gomega2, G1;
+  ring newRing, oldRing, TargetRing;
+  intvec* next_weight;
+  intvec* ivNull = new intvec(nV);
+
+  ring YXXRing = currRing;
+
+  intvec* iv_M_dpp = MivMatrixOrderlp(nV);
+  intvec* target_weight;// = Mivlp(nV);
+  ideal ssG;
+
+  // perturb the target vector
+  while(1)
+  {
+    if(Overflow_Error == FALSE)
+    {
+      if (rParameter(currRing) != NULL)
+      {
+        DefRingParlp();
+      }
+      else
+      {
+        VMrDefaultlp();
+      }
+      TargetRing = currRing;
+      ssG = idrMoveR(Go,YXXRing,currRing);
+    }
+    Overflow_Error = FALSE;
+    if(tp_deg != 1)
+    {
+      target_weight = MPertVectors(ssG, iv_M_dpp, tp_deg);
+    }
+    else
+    {
+      target_weight = Mivlp(nV);
+      break;
+    }
+    if(Overflow_Error == FALSE)
+    {
+      break;
+    }
+    Overflow_Error = TRUE;
+    tp_deg --;
+  }
+  if(tp_deg != tp_deg_tmp)
+  {
+    Overflow_Error = TRUE;
+    //nOverflow_Error = TRUE;
+  }
+
+  //  Print("\n// tp_deg = %d", tp_deg);
+  // ivString(target_weight, "pert target");
+
+  delete iv_M_dpp;
+#ifndef  BUCHBERGER_ALG
+  intvec* hilb_func;
+#endif
+  // to avoid (1,0,...,0) as the target vector
+  intvec* last_omega = new intvec(nV);
+  for(i=nV-1; i>0; i--)
+  {
+    (*last_omega)[i] = 1;
+  }
+  (*last_omega)[0] = 10000;
+
+  rChangeCurrRing(YXXRing);
+  G = idrMoveR(ssG, TargetRing,currRing);
+
+  while(1)
+  {
+    nwalk ++;
+    nstep ++;
+
+    if(nwalk==1)
+    {
+      goto FIRST_STEP;
+    }
+    to=clock();
+    // compute an initial form ideal of <G> w.r.t. "curr_vector"
+    Gomega = MwalkInitialForm(G, curr_weight);
+    xtif=xtif+clock()-to;
+
+#ifndef  BUCHBERGER_ALG
+    if(isNolVector(curr_weight) == 0)
+      hilb_func = hFirstSeries(Gomega,NULL,NULL,curr_weight,currRing);
+    else
+      hilb_func = hFirstSeries(Gomega,NULL,NULL,last_omega,currRing);
+#endif
+
+    oldRing = currRing;
+
+    // define a new ring that its ordering is "(a(curr_weight),lp)
+    if (rParameter(currRing) != NULL)
+    {
+      DefRingPar(curr_weight);
+    }
+    else
+    {
+      rChangeCurrRing(VMrDefault(curr_weight)); // Aenderung 15
+    }
+    newRing = currRing;
+    Gomega1 = idrMoveR(Gomega, oldRing,currRing);
+
+#ifdef ENDWALKS
+    if(endwalks == 1)
+    {
+      Print("\n//  it is  %d-th step!!", nwalk);
+      idElements(Gomega1, "Gw");
+      PrintS("\n//  compute a rGB of Gw:");
+    }
+#endif
+
+    to=clock();
+    // compute a reduced Groebner basis of <Gomega> w.r.t. "newRing"
+#ifdef  BUCHBERGER_ALG
+    M = MstdhomCC(Gomega1);
+#else
+    M=kStd(Gomega1,NULL,isHomog,NULL,hilb_func,0,NULL,curr_weight);
+    delete hilb_func;
+#endif // BUCHBERGER_ALG
+    xtstd=xtstd+clock()-to;
+
+    // change the ring to oldRing
+    rChangeCurrRing(oldRing);
+    M1 =  idrMoveR(M, newRing,currRing);
+    Gomega2 =  idrMoveR(Gomega1, newRing,currRing);
+    to=clock();
+
+    // if(endwalks == 1){PrintS("\n//  Lifting is still working:");}
+
+    // compute a reduced Groebner basis of <G> w.r.t. "newRing" by the lifting process
+    F = MLifttwoIdeal(Gomega2, M1, G);
+    xtlift=xtlift+clock()-to;
+
+    idDelete(&M1);
+    idDelete(&Gomega2);
+    idDelete(&G);
+
+    // change the ring to newRing
+    rChangeCurrRing(newRing);
+    F1 = idrMoveR(F, oldRing,currRing);
+    to=clock();
+    //if(endwalks == 1){ PrintS("\n//  InterRed is still working:");}
+    // reduce the Groebner basis <G> w.r.t. the new ring
+    G = kInterRedCC(F1, NULL);
+    xtred=xtred+clock()-to;
+    idDelete(&F1);
+
+    if(endwalks == 1)
+      break;
+
+  FIRST_STEP:
+    Overflow_Error=FALSE;
+    to=clock();
+    // compute a next weight vector
+    next_weight = MkInterRedNextWeight(curr_weight,target_weight, G);
+    xtnw=xtnw+clock()-to;
+#ifdef PRINT_VECTORS
+    MivString(curr_weight, target_weight, next_weight);
+#endif
+
+    if(Overflow_Error == TRUE)
+    {
+      delete next_weight;
+      if(tp_deg > 1){
+        //nOverflow_Error = Overflow_Error;
+        tproc = tproc+clock()-tinput;
+        //Print("\n// A subroutine takes %d steps and calls \"Mpwalk\" (1,%d):", nwalk, tp_deg-1);
+        G1 = Mpwalk_MAltwalk1(G, curr_weight, tp_deg-1);
+        goto MPW_Finish;
+      }
+      else {
+        newRing = currRing;
+        ntestwinC = 0;
+        break;
+      }
+    }
+
+    if(MivComp(next_weight, ivNull) == 1)
+    {
+      newRing = currRing;
+      delete next_weight;
+      break;
+    }
+    if(MivComp(next_weight, target_weight) == 1)
+    {
+      endwalks = 1;
+    }
+    for(i=nV-1; i>=0; i--)
+    {
+      //(*extra_curr_weight)[i] = (*curr_weight)[i];
+      (*curr_weight)[i] = (*next_weight)[i];
+    }
+    delete next_weight;
+  }//while
+
+  // check whether the pertubed target vector is correct
+
+  //define and execute ring with lex. order
+  if (rParameter(currRing) != NULL)
+  {
+    DefRingParlp();
+  }
+  else
+  {
+    VMrDefaultlp();
+  }
+  G1 = idrMoveR(G, newRing,currRing);
+
+  if( test_w_in_ConeCC(G1, target_weight) != 1 || ntestwinC == 0)
+  {
+    PrintS("\n// The perturbed target vector doesn't STAY in the correct cone!!");
+    if(tp_deg == 1)
+    {
+      //Print("\n// subroutine takes %d steps and applys \"std\"", nwalk);
+      to=clock();
+      ideal G2 = MstdCC(G1);
+      xtextra=xtextra+clock()-to;
+      idDelete(&G1);
+      G1 = G2;
+      G2 = NULL;
+    }
+    else
+    {
+      //nOverflow_Error = Overflow_Error;
+      tproc = tproc+clock()-tinput;
+      // Print("\n// B subroutine takes %d steps and calls \"Mpwalk\" (1,%d) :", nwalk,  tp_deg-1);
+      G1 = Mpwalk_MAltwalk1(G1, curr_weight, tp_deg-1);
+    }
+  }
+
+ MPW_Finish:
+  newRing = currRing;
+  rChangeCurrRing(YXXRing);
+  ideal result = idrMoveR(G1, newRing,currRing);
+
+  delete ivNull;
+  delete target_weight;
+
+  //Print("\n// \"Mpwalk\" (1,%d) took %d steps and %.2f sec. Overflow_Error (%d)", tp_deg, nwalk, ((double) clock()-tinput)/1000000, nOverflow_Error);
+
+  return(result);
+}
+
+/*******************************************************
+ * THE PERTURBATION WALK ALGORITHM WITH RANDOM ELEMENT *
+ *******************************************************/
+ideal Mprwalk(ideal Go, intvec* curr_weight, intvec* target_weight, int weight_rad, int op_deg, int tp_deg, ring baseRing)
+{
+  BITSET save1 = si_opt_1; // save current options
+  si_opt_1 &= (~Sy_bit(OPT_REDSB)); // no reduced Groebner basis
+  Set_Error(FALSE);
+  Overflow_Error = FALSE;
+#ifdef TIME_TEST
+  clock_t tinput=0, tostd=0, tif=0, tstd=0, tlift=0, tred=0, tnw=0;
+  xtif=0; xtstd=0; xtlift=0; xtred=0; xtnw=0;
+  tinput = clock();
+  clock_t tim;
+#endif
+  int i,nwalk,nV = baseRing->N;
+
+  ideal G, Gomega, M, F, Gomega1, Gomega2, M1;
+  ring newRing;
+  ring XXRing = baseRing;
+  intvec* exivlp = Mivlp(nV);
+  intvec* orig_target = target_weight;
+  intvec* pert_target_vector = target_weight;
+  intvec* ivNull = new intvec(nV);
+  intvec* tmp_weight = new intvec(nV);
+#ifdef CHECK_IDEAL_MWALK
+  poly p;
+#endif
+  for(i=0; i<nV; i++)
+  {
+    (*tmp_weight)[i] = (*curr_weight)[i];
+  }
+#ifndef BUCHBERGER_ALG
+  intvec* hilb_func;
+   // to avoid (1,0,...,0) as the target vector
+  intvec* last_omega = new intvec(nV);
+  for(i=0 i<nV; i++)
+  {
+    (*last_omega)[i] = 1;
+  }
+  (*last_omega)[0] = 10000;
+#endif
+  baseRing = currRing;
+  newRing = VMrDefault(curr_weight);
+  rChangeCurrRing(newRing);
+  G = idrMoveR(Go,baseRing,currRing);
+#ifdef TIME_TEST
+  to = clock();
+#endif
+  G = kStd(G,NULL,testHomog,NULL,NULL,0,0,NULL);
+  idSkipZeroes(G);
+#ifdef TIME_TEST
+  tostd = tostd + to - clock();
+#endif
+#ifdef CHECK_IDEAL_MWALK
+  idString(G,"G");
+#endif
+  if(op_deg >1)
+  {
+    if(MivComp(curr_weight,MivUnit(nV)) == 1) //ring order is "dp"
+    {
+      curr_weight = MPertVectors(G, MivMatrixOrderdp(nV), op_deg);
+    }
+    else //ring order is not "dp"
+    {
+      curr_weight = MPertVectors(G, MivMatrixOrder(curr_weight), op_deg);
+    }
+  }
+  baseRing = currRing;
+  if(tp_deg > 1 && tp_deg <= nV)
+  {
+    pert_target_vector = target_weight;
+  }
+#ifdef CHECK_IDEAL_MWALK
+  ivString(curr_weight, "new curr_weight");
+  ivString(target_weight, "new target_weight");
+#endif
+  nwalk = 0;
+  while(1)
+  {
+    nwalk ++;
+#ifdef TIME_TEST
+    to = clock();
+#endif
+    Gomega = MwalkInitialForm(G, curr_weight); // compute an initial form ideal of <G> w.r.t. "curr_vector"
+#ifdef TIME_TEST
+    tif = tif + clock()-to; //time for computing initial form ideal
+#endif
+#ifdef CHECK_IDEAL_MWALK
+    idString(Gomega,"Gomega");
+#endif
+#ifndef  BUCHBERGER_ALG
+    if(isNolVector(curr_weight) == 0)
+    {
+      hilb_func = hFirstSeries(Gomega,NULL,NULL,curr_weight,currRing);
+    }
+    else
+    {
+      hilb_func = hFirstSeries(Gomega,NULL,NULL,last_omega,currRing);
+    }
+#endif
+    if(nwalk == 1)
+    {
+      newRing = VMrDefault(curr_weight); // define a new ring with ordering "(a(curr_weight),lp)
+    }
+    else
+    {
+      newRing = VMrRefine(curr_weight,target_weight); //define a new ring with ordering "(a(curr_weight),Wp(target_weight))"
+    }
+    rChangeCurrRing(newRing);
+    Gomega1 = idrMoveR(Gomega, baseRing,currRing);
+    idDelete(&Gomega);
+    // compute a Groebner basis of <Gomega> w.r.t. "newRing"
+#ifdef TIME_TEST
+    to = clock();
+#endif
+#ifndef  BUCHBERGER_ALG
+    M=kStd(Gomega1,NULL,isHomog,NULL,hilb_func,0,NULL,curr_weight);
+    delete hilb_func;
+#else
+    M = kStd(Gomega1,NULL,testHomog,NULL,NULL,0,0,NULL);
+#endif
+    idSkipZeroes(M);
+#ifdef TIME_TEST
+    tstd = tstd + clock() - to;
+#endif
+#ifdef CHECK_IDEAL_MWALK
+    idString(M, "M");
+#endif
+    //change the ring to baseRing
+    rChangeCurrRing(baseRing);
+    M1 =  idrMoveR(M, newRing,currRing);
+    idDelete(&M);
+    Gomega2 = idrMoveR(Gomega1, newRing,currRing);
+    idDelete(&Gomega1);
+    to = clock();
+    // compute a representation of the generators of submod (M) with respect to those of mod (Gomega), where Gomega is a reduced Groebner basis w.r.t. the current ring
+    F = MLifttwoIdeal(Gomega2, M1, G);
+    idSkipZeroes(F);
+#ifdef TIME_TEST
+    tlift = tlift + clock() - to;
+#endif
+#ifdef CHECK_IDEAL_MWALK
+    idString(F,"F");
+#endif
+    rChangeCurrRing(newRing); // change the ring to newRing
+    G = idrMoveR(F,baseRing,currRing);
+    idDelete(&F);
+    baseRing = currRing; // set baseRing equal to newRing
+#ifdef CHECK_IDEAL_MWALK
+    idString(G,"G");
+#endif
+#ifdef TIME_TEST
+    to = clock();
+#endif
+    intvec* next_weight = MWalkRandomNextWeight(G, curr_weight, target_weight, weight_rad, op_deg);
+#ifdef TIME_TEST
+    tnw = tnw + clock() - to;
+#endif
+#ifdef PRINT_VECTORS
+    MivString(curr_weight, target_weight, next_weight);
+#endif
+    if(Overflow_Error == TRUE)
+    {
+      PrintS("\n//**Mprwalk: OVERFLOW: The computed vector does not stay in cone, the result may be wrong.\n");
+      delete next_weight;
+      break;
+    }
+
+    if(test_w_in_ConeCC(G,target_weight) == 1 || MivComp(next_weight, ivNull) == 1)
+    {
+      delete next_weight;
+      break;
+    }
+    //update tmp_weight and curr_weight
+    for(i=nV-1; i>=0; i--)
+    {
+      (*tmp_weight)[i] = (*curr_weight)[i];
+      (*curr_weight)[i] = (*next_weight)[i];
+    }
+    delete next_weight;
+  } //end of while-loop
+  Print("\n// Mprwalk took %d steps. Ring= %s;\n", nwalk, rString(currRing));
+  idSkipZeroes(G);
+  si_opt_1 = save1; //set original options, e. g. option(RedSB)
+  baseRing = currRing;
+  rChangeCurrRing(XXRing);
+  ideal Res = idrMoveR(G,baseRing,currRing);
+  delete tmp_weight;
+  delete ivNull;
+  delete exivlp;
+#ifndef BUCHBERGER_ALG
+  delete last_omega;
+#endif
+#ifdef TIME_TEST
+  TimeString(tinput, tostd, tif, tstd, tlift, tred, tnw, nstep);
+#endif
+  return(Res);
+}
+
+/*******************************************************************
+ * Implementation of the first alternative Groebner Walk Algorithm *
+ *******************************************************************/
+ideal MAltwalk1(ideal Go, int op_deg, int tp_deg, intvec* curr_weight,
+                intvec* target_weight)
+{
+  Set_Error(FALSE  );
+  Overflow_Error = FALSE;
+#ifdef TIME_TEST
+  BOOLEAN nOverflow_Error = FALSE;
+#endif
+  // Print("// pSetm_Error = (%d)", ErrorCheck());
+
+  xtif=0; xtstd=0; xtlift=0; xtred=0; xtnw=0; xtextra=0;
+  xftinput = clock();
+  clock_t tostd, tproc;
+
+  nstep = 0;
+  int i, nV = currRing->N;
+  int nwalk=0, endwalks=0;
+  int op_tmp = op_deg;
+  ideal Gomega, M, F, G, Gomega1, Gomega2, M1, F1;
+  ring newRing, oldRing;
+  intvec* next_weight;
+  intvec* iv_M_dp;
+  intvec* ivNull = new intvec(nV);
+  intvec* iv_dp = MivUnit(nV);// define (1,1,...,1)
+  intvec* exivlp = Mivlp(nV);
+  //intvec* extra_curr_weight = new intvec(nV);
+#ifndef  BUCHBERGER_ALG
+  intvec* hilb_func;
+#endif
+  intvec* cw_tmp = curr_weight;
+
+  // to avoid (1,0,...,0) as the target vector
+  intvec* last_omega = new intvec(nV);
+  for(i=nV-1; i>0; i--)
+  {
+    (*last_omega)[i] = 1;
+  }
+  (*last_omega)[0] = 10000;
+
+  ring XXRing = currRing;
+
+  to=clock();
+  /* compute a pertubed weight vector of the original weight vector.
+     The perturbation degree is recursive decrease until that vector
+     stays inn the correct cone. */
+  while(1)
+  {
+    if(Overflow_Error == FALSE)
+    {
+      if(MivComp(curr_weight, iv_dp) == 1)
+      {
+      //rOrdStr(currRing) = "dp"
+        if(op_tmp == op_deg)
+        {
+          G = MstdCC(Go);
+          if(op_deg != 1)
+          {
+            iv_M_dp = MivMatrixOrderdp(nV);
+          }
+        }
+      }
+    }
+    else
+    {
+      if(op_tmp == op_deg)
+      {
+        //rOrdStr(currRing) = (a(...),lp,C)
+        if (rParameter(currRing) != NULL)
+        {
+          DefRingPar(cw_tmp);
+        }
+        else
+        {
+          rChangeCurrRing(VMrDefault(cw_tmp)); // Aenderung 16
+        }
+        G = idrMoveR(Go, XXRing,currRing);
+        G = MstdCC(G);
+        if(op_deg != 1)
+          iv_M_dp = MivMatrixOrder(cw_tmp);
+      }
+    }
+    Overflow_Error = FALSE;
+    if(op_deg != 1)
+    {
+      curr_weight = MPertVectors(G, iv_M_dp, op_deg);
+    }
+    else
+    {
+      curr_weight =  cw_tmp;
+      break;
+    }
+    if(Overflow_Error == FALSE)
+    {
+      break;
+    }
+    Overflow_Error = TRUE;
+    op_deg --;
+  }
+  tostd=clock()-to;
+
+  if(op_tmp != 1 )
+    delete iv_M_dp;
+  delete iv_dp;
+
+  if(currRing->order[0] == ringorder_a)
+    goto NEXT_VECTOR;
+
+  while(1)
+  {
+    nwalk ++;
+    nstep ++;
+
+    to = clock();
+    // compute an initial form ideal of <G> w.r.t. "curr_vector"
+    Gomega = MwalkInitialForm(G, curr_weight);
+    xtif=xtif+clock()-to;
+#if 0
+    if(Overflow_Error == TRUE)
+    {
+      for(i=nV-1; i>=0; i--)
+        (*curr_weight)[i] = (*extra_curr_weight)[i];
+      delete extra_curr_weight;
+
+      newRing = currRing;
+      goto MSTD_ALT1;
+    }
+#endif
+#ifndef  BUCHBERGER_ALG
+    if(isNolVector(curr_weight) == 0)
+    {
+      hilb_func = hFirstSeries(Gomega,NULL,NULL,curr_weight,currRing);
+    }
+    else
+    {
+      hilb_func = hFirstSeries(Gomega,NULL,NULL,last_omega,currRing);
+    }
+#endif // BUCHBERGER_ALG
+
+    oldRing = currRing;
+
+    // define a new ring which ordering is "(a(curr_weight),lp)
+    if (rParameter(currRing) != NULL)
+    {
+      DefRingPar(curr_weight);
+    }
+    else
+    {
+      rChangeCurrRing(VMrDefault(curr_weight)); // Aenderung 17
+    }
+    newRing = currRing;
+    Gomega1 = idrMoveR(Gomega, oldRing,currRing);
+
+    to=clock();
+    // compute a reduced Groebner basis of <Gomega> w.r.t. "newRing"
+#ifdef  BUCHBERGER_ALG
+    M = MstdhomCC(Gomega1);
+#else
+    M=kStd(Gomega1,NULL,isHomog,NULL,hilb_func,0,NULL,curr_weight);
+    delete hilb_func;
+#endif // BUCHBERGER_ALG
+    xtstd=xtstd+clock()-to;
+
+    // change the ring to oldRing
+    rChangeCurrRing(oldRing);
+    M1 =  idrMoveR(M, newRing,currRing);
+    Gomega2 =  idrMoveR(Gomega1, newRing,currRing);
+
+    to=clock();
+    // compute a reduced Groebner basis of <G> w.r.t. "newRing" by the lifting process
+    F = MLifttwoIdeal(Gomega2, M1, G);
+    xtlift=xtlift+clock()-to;
+
+    idDelete(&M1);
+    idDelete(&Gomega2);
+    idDelete(&G);
+
+    // change the ring to newRing
+    rChangeCurrRing(newRing);
+    F1 = idrMoveR(F, oldRing,currRing);
+
+    to=clock();
+    // reduce the Groebner basis <G> w.r.t. new ring
+    G = kInterRedCC(F1, NULL);
+    xtred=xtred+clock()-to;
+    idDelete(&F1);
+
+    if(endwalks == 1)
+    {
+      break;
+    }
+  NEXT_VECTOR:
+    to=clock();
+    // compute a next weight vector
+    next_weight = MkInterRedNextWeight(curr_weight,target_weight, G);
+    xtnw=xtnw+clock()-to;
+#ifdef PRINT_VECTORS
+    MivString(curr_weight, target_weight, next_weight);
+#endif
+
+    if(Overflow_Error == TRUE)
+    {
+      newRing = currRing;
+
+      if (rParameter(currRing) != NULL)
+      {
+        DefRingPar(target_weight);
+      }
+      else
+      {
+        rChangeCurrRing(VMrDefault(target_weight)); // Aenderung 18
+      }
+      F1 = idrMoveR(G, newRing,currRing);
+      G = MstdCC(F1);
+      idDelete(&F1);
+      newRing = currRing;
+      break; //for while
+    }
+
+
+    /* G is the wanted Groebner basis if next_weight == curr_weight */
+    if(MivComp(next_weight, ivNull) == 1)
+    {
+      newRing = currRing;
+      delete next_weight;
+      break; //for while
+    }
+
+    if(MivComp(next_weight, target_weight) == 1)
+    {
+      if(tp_deg == 1 || MivSame(target_weight, exivlp) == 0)
+        endwalks = 1;
+      else
+      {
+       // MSTD_ALT1:
+#ifdef TIME_TEST
+        nOverflow_Error = Overflow_Error;
+#endif
+        tproc = clock()-xftinput;
+
+        //Print("\n//  main routine takes %d steps and calls \"Mpwalk\" (1,%d):", nwalk,  tp_deg);
+
+        // compute the red. GB of <G> w.r.t. the lex order by the "recursive-modified" perturbation walk alg (1,tp_deg)
+        G = Mpwalk_MAltwalk1(G, curr_weight, tp_deg);
+        delete next_weight;
+        break; // for while
+      }
+    }
+
+    //NOT Changed, to free memory
+    for(i=nV-1; i>=0; i--)
+    {
+      //(*extra_curr_weight)[i] = (*curr_weight)[i];
+      (*curr_weight)[i] = (*next_weight)[i];
+    }
+    delete next_weight;
+  }//while
+
+  rChangeCurrRing(XXRing);
+  ideal result = idrMoveR(G, newRing,currRing);
+  id_Delete(&G, newRing);
+
+  delete ivNull;
+  if(op_deg != 1 )
+  {
+    delete curr_weight;
+  }
+  delete exivlp;
+#ifdef TIME_TEST
+
+  Print("\n// \"Main procedure\"  took %d steps, %.2f sec. and Overflow_Error(%d)",
+        nwalk, ((double) tproc)/1000000, nOverflow_Error);
+
+  TimeStringFractal(xftinput, tostd, xtif, xtstd,xtextra, xtlift, xtred, xtnw);
+
+  Print("\n// pSetm_Error = (%d)", ErrorCheck());
+  Print("\n// Overflow_Error? (%d)", Overflow_Error);
+  Print("\n// Awalk1 took %d steps.\n", nstep);
+#endif
+  return(result);
+}
diff --git a/Singular/walk.h b/Singular/walk.h
new file mode 100644
index 0000000..b96bc17
--- /dev/null
+++ b/Singular/walk.h
@@ -0,0 +1,85 @@
+/*****************************************
+*  Computer Algebra System SINGULAR      *
+*****************************************/
+/*
+* ABSTRACT: Declaration of the Groebner walk
+*/
+
+#ifndef WALK_H
+#define WALK_H
+
+#include <kernel/structs.h>
+
+ideal  MwalkInitialForm(ideal G, intvec* curr_weight);
+
+//compute the next weight vector
+intvec* MwalkNextWeight(intvec* curr_weight,intvec* target_weight, ideal G);
+
+int MivSame(intvec* u , intvec* v);
+int M3ivSame(intvec* next_weight, intvec* u , intvec* v);
+
+
+
+intvec* Mivdp(int nR);
+intvec* Mivlp(int nR);
+
+intvec* MivMatrixOrder(intvec* iv);
+intvec* MivMatrixOrderdp(int iv);
+intvec* MPertVectors(ideal G, intvec* ivtarget, int pdeg);
+intvec* MPertVectorslp(ideal G, intvec* ivtarget, int pdeg);
+
+
+intvec* MivMatrixOrderlp(int nV);
+
+intvec* Mfpertvector(ideal G, intvec* iv);
+intvec* MivUnit(int nV);
+
+intvec* MivWeightOrderlp(intvec* ivstart);
+intvec* MivWeightOrderdp(intvec* ivstart);
+
+ideal MidLift(ideal Gomega, ideal M);
+ideal MLiftLmalG(ideal L, ideal G);
+ideal MLiftLmalGNew(ideal Gomega, ideal M, ideal G);
+ideal MLiftLmalGMin(ideal L, ideal G);
+
+
+intvec* MkInterRedNextWeight(intvec* iva, intvec* ivb, ideal G);
+intvec* MPertNextWeight(intvec* iva, ideal G, int deg);
+intvec* Mivperttarget(ideal G, int ndeg);
+
+
+intvec* MSimpleIV(intvec* iv);
+
+/* Okt -- Nov'01 */
+// compute a Groebner basis of an ideal G w.r.t. lexicographic order
+//ideal Mwalk(ideal Go, intvec* orig_M, intvec* target_M);
+ideal Mwalk(ideal Go, intvec* orig_M, intvec* target_M, ring baseRing);
+
+// random walk algorithm to compute a Groebner basis
+ideal Mrwalk(ideal Go, intvec* curr_weight, intvec* target_weight, int weight_rad, int pert_deg, ring baseRing);
+
+/* the perturbation walk algorithm */
+
+ideal Mpwalk(ideal Go, int op_deg, int tp_deg,intvec* curr_weight,intvec* target_weight, int nP);
+
+/* the perturbation walk algorithm with random element */
+
+ideal Mprwalk(ideal Go, intvec* curr_weight, intvec* target_weight, int weight_rad, int op_deg, int tp_deg, ring baseRing);
+
+/* The fractal walk algorithm */
+ideal Mfwalk(ideal G, intvec* ivstart, intvec* ivtarget);
+
+/* The fractal walk algorithm with random element */
+ideal Mfrwalk(ideal G, intvec* ivstart, intvec* ivtarget,int weight_rad);
+
+/* Implement Tran's idea */
+intvec* TranMPertVectorslp(ideal G);
+ideal TranMImprovwalk(ideal Go, intvec* curr_weight,intvec* target_weight, int nP);
+
+/* the first alternative algorithm */
+ideal MAltwalk1(ideal G,int op,int tp,intvec* curr_weight,intvec* target_weight);
+
+/* the second alternative algorithm */
+ideal MAltwalk2(ideal G, intvec* curr_weight, intvec* target_weight);
+
+#endif  //WALK_H
diff --git a/Singular/walk_ip.cc b/Singular/walk_ip.cc
new file mode 100644
index 0000000..aadfe28
--- /dev/null
+++ b/Singular/walk_ip.cc
@@ -0,0 +1,314 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: frwalk: interpreter link
+*/
+
+#include <kernel/mod2.h>
+#include <Singular/tok.h>
+#include <misc/options.h>
+#include <Singular/ipid.h>
+#include <misc/intvec.h>
+#include <omalloc/omalloc.h>
+#include <kernel/polys.h>
+#include <kernel/ideals.h>
+#include <polys/matpol.h>
+#include <kernel/GBEngine/kstd1.h>
+#include <polys/monomials/ring.h>
+#include <Singular/subexpr.h>
+#include <polys/monomials/maps.h>
+#include <kernel/GBEngine/syz.h>
+#include <coeffs/numbers.h>
+#include <Singular/lists.h>
+#include <Singular/attrib.h>
+#include <Singular/ipconv.h>
+#include <Singular/links/silink.h>
+#include <kernel/combinatorics/stairc.h>
+#include <polys/weight.h>
+#include <kernel/spectrum/semic.h>
+#include <kernel/spectrum/splist.h>
+#include <kernel/spectrum/spectrum.h>
+//#include <kernel/gnumpfl.h>
+//#include <kernel/mpr_base.h>
+//#include <kernel/ffields.h>
+#include <polys/clapsing.h>
+#include <kernel/combinatorics/hutil.h>
+#include <Singular/ipshell.h>
+#include <kernel/groebner_walk/walkMain.h>
+#include <kernel/groebner_walk/walkProc.h>
+#include <kernel/groebner_walk/walkSupport.h>
+#include <polys/prCopy.h>
+
+//#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <math.h>
+
+///////////////////////////////////////////////////////////////////
+//walkProc
+///////////////////////////////////////////////////////////////////
+//Description: The main function for the Walk-Algorithm. Checks the
+//input-data, and calls walk64 (see walkMain.cc). Returns the new
+//groebner basis or something else if an error occoured.
+///////////////////////////////////////////////////////////////////
+//Uses: omAlloc0,walkConsistency,rGetGlobalOrderWeightVec,
+//omFreeSize,sizeof,IDIDEAL,walk64,rSetHdl,idrMoveR,Werror,idInit
+///////////////////////////////////////////////////////////////////
+
+ideal
+walkProc(leftv first, leftv second)
+{
+    WalkState state = WalkOk;
+    BITSET save1,save2;
+    SI_SAVE_OPT(save1,save2);
+    si_opt_1 &= (~Sy_bit(OPT_REDSB)); //make sure option noredSB is set
+
+    ring destRing = currRing;
+    ideal destIdeal = NULL;
+    idhdl sourceRingHdl = (idhdl)first->data;
+    ring sourceRing = IDRING(sourceRingHdl);
+    rChangeCurrRing( sourceRing );
+
+    if(state==WalkOk)
+    {
+      int * vperm = (int *)omAlloc0( (currRing->N+1)*sizeof( int ) );
+      state= walkConsistency( sourceRing, destRing, vperm );
+      omFreeSize( (ADDRESS)vperm, (currRing->N+1)*sizeof(int) );
+    }
+
+    int64vec* currw64=rGetGlobalOrderWeightVec(sourceRing);
+    int64vec* destVec64=rGetGlobalOrderWeightVec(destRing);
+
+    ideal sourceIdeal;
+    BOOLEAN sourcIdealIsSB=FALSE;
+    if ( state == WalkOk )
+    {
+      idhdl ih = currRing->idroot->get( second->Name(), myynest );
+      if ( (ih != NULL) && (IDTYP(ih)==IDEAL_CMD) )
+      {
+           sourceIdeal = idCopy(IDIDEAL( ih ));
+           if(hasFlag((leftv)ih,FLAG_STD)){
+              sourcIdealIsSB=TRUE;
+           }
+      }
+      else
+      {
+        state=WalkNoIdeal;
+      }
+    }
+
+    if ( state == WalkOk )
+    {
+      // Now the settings are compatible with Walk
+      state=walk64(sourceIdeal,currw64,destRing,destVec64,
+                   destIdeal,sourcIdealIsSB);
+    }
+
+    SI_RESTORE_OPT(save1,save2);//making sure options are as before function call
+
+    ring almostDestRing=currRing;
+    rChangeCurrRing(destRing);
+
+    switch (state) {
+        case WalkOk:
+          destIdeal=idrMoveR(destIdeal,currRing,almostDestRing);
+          break;
+
+        case WalkIncompatibleRings:
+          Werror("ring %s and current ring are incompatible\n",
+                 first->Name() );
+          destIdeal= NULL;
+          break;
+
+        case WalkIncompatibleDestRing:
+          Werror( "Order of basering not allowed,\n must be a combination of a,A,lp,dp,Dp,wp,Wp,M and C.\n");
+          destIdeal= NULL;
+          break;
+
+        case WalkIncompatibleSourceRing:
+          Werror( "Order of %s not allowed,\n must be a combination of a,A,lp,dp,Dp,wp,Wp,M and C.\n",first->Name());
+          rChangeCurrRing(destRing);
+          destIdeal= NULL;
+          break;
+
+        case WalkNoIdeal:
+          Werror( "Can't find ideal %s in ring %s.\n",
+                   second->Name(), first->Name() );
+          destIdeal= NULL;
+          break;
+
+        case WalkOverFlowError:
+          Werror( "Overflow occured.\n");
+          destIdeal= NULL;
+          break;
+
+        default:
+           destIdeal= NULL;
+    }
+
+    return destIdeal;
+}
+
+///////////////////////////////////////////////////////////////////
+//fractalWalkProc
+///////////////////////////////////////////////////////////////////
+//Description: The main function for the Fractalwalk-Algorithm.
+//Responsible for contact between user and walk64. Checks the
+//input-data, and calls fractalWalk64. Returns the new groebner
+//basis or something else if an error occured.
+///////////////////////////////////////////////////////////////////
+//Uses: omAlloc0,fractalWalkConsistency,omFreeSize,sizeof,IDIDEAL,
+//fractalWalk64,rSetHdl,idrMoveR,Werror,idInit
+///////////////////////////////////////////////////////////////////
+
+ideal
+fractalWalkProc(leftv first, leftv second)
+{
+
+  //unperturbedStartVectorStrategy SHOULD BE SET BY THE USER THROUGH
+  //A THIRD ARGUMENT. TRUE MEANS THAT THE UNPERTURBED START
+  //VECTOR STRATEGY IS USED AND FALSE THAT THE START VECTOR IS
+  //MAXIMALLY PERTURBED
+
+    BOOLEAN unperturbedStartVectorStrategy=TRUE;
+
+    WalkState state = WalkOk;
+    BITSET save1,save2;
+    SI_SAVE_OPT(save1,save2);
+    si_opt_1 &= (~Sy_bit(OPT_REDSB)); //make sure option noredSB is set
+
+    ring destRing = currRing;
+    ideal destIdeal = NULL;
+    idhdl sourceRingHdl = (idhdl)first->data;
+    rSetHdl( sourceRingHdl );
+    ring sourceRing = currRing;
+
+    int * vperm = (int *)omAlloc0( (currRing->N+1)*sizeof( int ) );
+    state= fractalWalkConsistency( sourceRing, destRing, vperm );
+    omFreeSize( (ADDRESS)vperm, (currRing->N+1)*sizeof(int) );
+
+    ideal sourceIdeal;
+    BOOLEAN sourcIdealIsSB=FALSE;
+    if ( state == WalkOk ) {
+      idhdl ih = currRing->idroot->get( second->Name(), myynest );
+      if ( (ih != NULL) && (IDTYP(ih)==IDEAL_CMD) ) {
+           sourceIdeal = IDIDEAL( ih );
+           if(hasFlag((leftv)ih,FLAG_STD)){
+              sourcIdealIsSB=TRUE;
+           }
+      }
+      else {
+        state=WalkNoIdeal;
+      }
+    }
+
+    if ( state == WalkOk ) {
+      // Now the settings are compatible with Walk
+      state=fractalWalk64(sourceIdeal,destRing,destIdeal,
+                          sourcIdealIsSB,
+                          unperturbedStartVectorStrategy);
+    }
+
+    SI_RESTORE_OPT(save1,save2);//making sure options are as before functiocall
+
+     if ( state == WalkOk )
+     {
+       ring almostDestRing=currRing;
+       rChangeCurrRing(destRing);
+       destIdeal=idrMoveR(destIdeal, almostDestRing, destRing);
+     }
+
+
+     switch (state) {
+
+        case WalkOk:
+            destIdeal=sortRedSB(destIdeal);
+            return(destIdeal);
+            break;
+
+        case WalkIncompatibleRings:
+            Werror( "ring %s and current ring are incompatible\n",
+                     first->Name() );
+            rChangeCurrRing(destRing);
+            destIdeal= NULL;
+            return destIdeal;
+            break;
+
+        case WalkIncompatibleDestRing:
+            Werror( "Order of basering not allowed,\n must be a combination of lp,dp,Dp,wp,Wp and C or just M.\n");
+            rChangeCurrRing(destRing);
+            destIdeal= NULL;
+            return destIdeal;
+            break;
+
+        case WalkIncompatibleSourceRing:
+            Werror( "Order of %s not allowed,\n must be a combination of lp,dp,Dp,wp,Wp and C or just M.\n",
+                     first->Name());
+            rChangeCurrRing(destRing);
+            destIdeal= NULL;
+            return destIdeal;
+            break;
+
+        case WalkNoIdeal:
+            Werror( "Can't find ideal %s in ring %s.\n",
+                     second->Name(), first->Name() );
+            rChangeCurrRing(destRing);
+            destIdeal= NULL;
+            return destIdeal;
+            break;
+
+        case WalkOverFlowError:
+            Werror( "Overflow occured in ring %s.\n", first->Name() );
+            rChangeCurrRing(destRing);
+            destIdeal= NULL;
+            return destIdeal;
+            break;
+
+        default:
+            rChangeCurrRing(destRing);
+            destIdeal= idInit(1,1);
+            return destIdeal;
+    }
+
+
+  return NULL;
+}
+
+
+///////////////////////////////////////////////////////////////////
+//getiv64
+///////////////////////////////////////////////////////////////////
+//Description: retrieves the int64vec from input list l
+///////////////////////////////////////////////////////////////////
+//Assumes: that the first entry of l is an int64vec
+///////////////////////////////////////////////////////////////////
+//Uses: none
+///////////////////////////////////////////////////////////////////
+
+int64vec* getiv64(lists l)
+{
+  return (int64vec*)(l->m[0].data);
+}
+
+///////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////
+//getint64
+///////////////////////////////////////////////////////////////////
+//Description: retrieves the int64 from input list l
+///////////////////////////////////////////////////////////////////
+//Assumes: that the second entry of l is an int64
+///////////////////////////////////////////////////////////////////
+//Uses: none
+///////////////////////////////////////////////////////////////////
+
+// not used, bad impl.
+//int64 getint64(lists l)
+//{
+//  return (int64)(long)(l->m[1].data);
+//}
+
+///////////////////////////////////////////////////////////////////
diff --git a/Singular/wrapper.cc b/Singular/wrapper.cc
new file mode 100644
index 0000000..e3bae61
--- /dev/null
+++ b/Singular/wrapper.cc
@@ -0,0 +1,135 @@
+#include <kernel/mod2.h>
+#include <polys/monomials/ring.h>
+
+#include <kernel/polys.h>
+#include <kernel/GBEngine/kstd1.h>
+#include <kernel/ideals.h>
+#include <kernel/GBEngine/janet.h>
+
+#include <Singular/subexpr.h>
+
+#include <string.h>
+
+//extern int (*ListGreatMove)(jList *,jList *,poly);
+
+static BOOLEAN jInitBasis(ideal v, jList **TT,jList **QQ)
+{
+  if (rHasLocalOrMixedOrdering_currRing())
+  {
+    WerrorS("janet only for well-orderings");
+    return TRUE;
+  }
+
+  Initialization(rOrdStr(currRing));
+
+  jList *Q=(jList *)GCM(sizeof(jList));
+  Q->root=NULL;
+
+  jList *T=(jList *)GCM(sizeof(jList));
+  T->root=NULL;
+
+  for (int i=0; i < IDELEMS(v); i++)
+  {
+    if (v->m[i]!=NULL)
+    {
+      Poly *beg=NewPoly(pCopy(v->m[i]));
+
+      InitHistory(beg);
+      InitProl(beg);
+      InitLead(beg);
+
+      InsertInCount(Q,beg);
+    }
+  }
+
+  BOOLEAN r= !(ComputeBasis(T,Q));
+  *TT=T;
+  *QQ=Q;
+  return r;
+}
+
+/// flag: 0: JB, 1: SB
+BOOLEAN jjStdJanetBasis(leftv res, leftv v, int flag)
+{
+  ideal result;
+
+  jList *T;
+  jList *Q;
+  ideal I=(ideal)v->Data();
+  BOOLEAN is_zero=TRUE;
+  for (int i=0; i < IDELEMS(I); i++)
+  {
+    if ((I->m[i]!=NULL)&& (pIsConstant(I->m[i])))
+    {
+      goto zero;
+    }
+    else
+     is_zero=FALSE;
+  }
+  if (is_zero)
+    goto zero;
+  if (!jInitBasis(I,&T,&Q))
+  {
+    int dpO=(strstr(rOrdStr(currRing),"dp")!=NULL);
+    int ideal_length;
+    if (flag==1)
+      ideal_length= dpO ? GB_length() : CountList(T);
+    else
+      ideal_length=CountList(T);
+
+    result=idInit(ideal_length,1);
+
+    int ideal_index=0;
+
+    LCI iT=T->root;
+
+    while(iT)
+    {
+      pTest(iT->info->root);
+      if ((flag==1) && dpO)
+      {
+        //if (pTotaldegree(iT->info->lead) == pTotaldegree(iT->info->history))
+        if (p_Deg(iT->info->lead,currRing) == p_Deg(iT->info->history,currRing))
+        {
+          result->m[ideal_length-ideal_index-1]=pCopy(iT->info->root);
+          if (!nGreaterZero(pGetCoeff(iT->info->root)))
+            result->m[ideal_length-ideal_index-1]
+                                  =pNeg(result->m[ideal_length-ideal_index-1]);
+
+          ideal_index++;
+        }
+      }
+      else
+      {
+        result->m[ideal_length-ideal_index-1]=pCopy(iT->info->root);
+        if (!nGreaterZero(pGetCoeff(iT->info->root)))
+          result->m[ideal_length-ideal_index-1]
+                                  =pNeg(result->m[ideal_length-ideal_index-1]);
+
+        ideal_index++;
+      }
+      iT=iT->next;
+    }
+
+    if ((flag==1) && (dpO==0))
+    {
+      //Print ("interred\n");
+      result=kInterRedOld(result);
+      idSkipZeroes(result);
+    }
+    res->data = (char *)result;
+    res->rtyp = IDEAL_CMD;
+    DestroyList(Q);
+    DestroyList(T);
+    return FALSE;
+  }
+  else
+    return TRUE;
+
+zero:
+  result=idInit(1,1);
+  if (!is_zero) result->m[0]=pOne();
+  res->data = (char *)result;
+  res->rtyp = IDEAL_CMD;
+  return FALSE;
+}
diff --git a/_config.h.in b/_config.h.in
new file mode 100644
index 0000000..d0cafc2
--- /dev/null
+++ b/_config.h.in
@@ -0,0 +1,389 @@
+/* _config.h.in.  Generated from configure.ac by autoheader.  */
+
+/* ac_configure_args */
+#undef AC_CONFIGURE_ARGS
+
+/* bindir */
+#undef BIN_DIR
+
+/* CC */
+#undef CC
+
+/* CFLAGS */
+#undef CFLAGS
+
+/* CPPFLAGS */
+#undef CPPFLAGS
+
+/* CXX */
+#undef CXX
+
+/* CXXFLAGS */
+#undef CXXFLAGS
+
+/* datadir */
+#undef DATA_DIR
+
+/* DEFS */
+#undef DEFS
+
+/* docdir */
+#undef DOC_DIR
+
+/* integrate python */
+#undef EMBED_PYTHON
+
+/* exec_prefix */
+#undef EXEC_PREFIX
+
+/* FLINT_CFLAGS */
+#undef FLINT_CFLAGS
+
+/* FLINT_LIBS */
+#undef FLINT_LIBS
+
+/* GMP_CFLAGS */
+#undef GMP_CFLAGS
+
+/* GMP_LIBS */
+#undef GMP_LIBS
+
+/* Define if GMP is version 3.xxx */
+#undef GMP_VERSION_3
+
+/* whether google perftools support is enabled */
+#undef GOOGLE_PERFTOOLS_ENABLED
+
+/* whether google profiling support is enabled */
+#undef GOOGLE_PROFILE_ENABLED
+
+/* Define to 1 if you have the <asm/sigcontext.h> header file. */
+#undef HAVE_ASM_SIGCONTEXT_H
+
+/* Define to 1 if you have the <cddlib/setoper.h> header file. */
+#undef HAVE_CDDLIB_SETOPER_H
+
+/* Define to 1 if you have the <cdd/setoper.h> header file. */
+#undef HAVE_CDD_SETOPER_H
+
+/* Define to have dbm links */
+#undef HAVE_DBM
+
+/* division using extend euclidian algorithm otherwise using tables of
+   logartihms */
+#undef HAVE_DIV_MOD
+
+/* enable dynamic modules */
+#undef HAVE_DL
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
+
+/* enable dynamic modules */
+#undef HAVE_DYNAMIC_LOADING
+
+/* Use dynamic readline */
+#undef HAVE_DYN_RL
+
+/* Enable factory */
+#undef HAVE_FACTORY
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#undef HAVE_FCNTL_H
+
+/* Define if FLINT is installed */
+#undef HAVE_FLINT
+
+/* use branch for addition in Z/p otherwise it uses a generic add */
+#undef HAVE_GENERIC_ADD
+
+/* Define to 1 if you have the `getcwd' function. */
+#undef HAVE_GETCWD
+
+/* Define to 1 if you have the `getwd' function. */
+#undef HAVE_GETWD
+
+/* whether gfanlib support is enabled */
+#undef HAVE_GFANLIB
+
+/* Define if GMP is installed */
+#undef HAVE_GMP
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the <iostream.h> header file. */
+#undef HAVE_IOSTREAM_H
+
+/* Define to 1 if you have the `curses' library (-lcurses). */
+#undef HAVE_LIBCURSES
+
+/* Define to 1 if you have the `mathic' library (-lmathic). */
+#undef HAVE_LIBMATHIC
+
+/* Define to 1 if you have the `mathicgb' library (-lmathicgb). */
+#undef HAVE_LIBMATHICGB
+
+/* Define to 1 if you have the `memtailor' library (-lmemtailor). */
+#undef HAVE_LIBMEMTAILOR
+
+/* Define to 1 if you have the `ncurses' library (-lncurses). */
+#undef HAVE_LIBNCURSES
+
+/* Define to 1 if you have the `readline' library (-lreadline). */
+#undef HAVE_LIBREADLINE
+
+/* Define to 1 if you have the `rt' library (-lrt). */
+#undef HAVE_LIBRT
+
+/* Define to 1 if you have the `termcap' library (-ltermcap). */
+#undef HAVE_LIBTERMCAP
+
+/* Define to 1 if your system has a GNU libc compatible `malloc' function, and
+   to 0 otherwise. */
+#undef HAVE_MALLOC
+
+/* Define if mathicgb is to be used */
+#undef HAVE_MATHICGB
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* multiplication is fast on the cpu: a*b is with mod otherwise using tables
+   of logartihms */
+#undef HAVE_MULT_MOD
+
+/* Define if NTL is installed */
+#undef HAVE_NTL
+
+/* Enable non-commutative subsystem */
+#undef HAVE_PLURAL
+
+/* Define if POLYMAKE is installed */
+#undef HAVE_POLYMAKE
+
+/* Define if you have POSIX threads libraries and header files. */
+#undef HAVE_PTHREAD
+
+/* Have PTHREAD_PRIO_INHERIT. */
+#undef HAVE_PTHREAD_PRIO_INHERIT
+
+/* Define to 1 if you have the `putenv' function. */
+#undef HAVE_PUTENV
+
+/* Define to 1 if you have the <pwd.h> header file. */
+#undef HAVE_PWD_H
+
+/* compile python-related stuff */
+#undef HAVE_PYTHON
+
+/* Define to 1 if you have the `qsort_r' function. */
+#undef HAVE_QSORT_R
+
+/* Enable RatGB support */
+#undef HAVE_RATGRING
+
+/* Use readline */
+#undef HAVE_READLINE
+
+/* Define to 1 if you have the <readline/history.h> header file. */
+#undef HAVE_READLINE_HISTORY_H
+
+/* Define to 1 if you have the <readline/readline.h> header file. */
+#undef HAVE_READLINE_READLINE_H
+
+/* Define to 1 if you have the `readlink' function. */
+#undef HAVE_READLINK
+
+/* Define to 1 if you have the `setenv' function. */
+#undef HAVE_SETENV
+
+/* Define to 1 if you have the <setoper.h> header file. */
+#undef HAVE_SETOPER_H
+
+/* Enable letterplace */
+#undef HAVE_SHIFTBBA
+
+/* 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/file.h> header file. */
+#undef HAVE_SYS_FILE_H
+
+/* Define to 1 if you have the <sys/ioctl.h> header file. */
+#undef HAVE_SYS_IOCTL_H
+
+/* Define to 1 if you have the <sys/param.h> header file. */
+#undef HAVE_SYS_PARAM_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/times.h> header file. */
+#undef HAVE_SYS_TIMES_H
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+#undef HAVE_SYS_TIME_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 <termcap.h> header file. */
+#undef HAVE_TERMCAP_H
+
+/* Define to 1 if you have the <termios.h> header file. */
+#undef HAVE_TERMIOS_H
+
+/* Define to 1 if you have the <term.h> header file. */
+#undef HAVE_TERM_H
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* LDFLAGS */
+#undef LDFLAGS
+
+/* libexecdir */
+#undef LIBEXEC_DIR
+
+/* LIBS */
+#undef LIBS
+
+/* libdir */
+#undef LIB_DIR
+
+/* Define to the sub-directory in which libtool stores uninstalled libraries.
+   */
+#undef LT_OBJDIR
+
+/* Define to 1 if your C compiler doesn't accept -c and -o together. */
+#undef NO_MINUS_C_MINUS_O
+
+/* NTL_CFLAGS */
+#undef NTL_CFLAGS
+
+/* NTL_LIBS */
+#undef NTL_LIBS
+
+/* "Disable OM Debug" */
+#undef OM_NDEBUG
+
+/* Name of package */
+#undef PACKAGE
+
+/* 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
+
+/* prefix */
+#undef PREFIX
+
+/* Define to necessary symbol if this constant uses a non-standard name on
+   your system. */
+#undef PTHREAD_CREATE_JOINABLE
+
+/* Use readline.h */
+#undef READLINE_READLINE_H_OK
+
+/* SINGULAR_CFLAGS */
+#undef SINGULAR_CFLAGS
+
+/* "Disable Singular Debug" */
+#undef SING_NDEBUG
+
+/* The size of `long', as computed by sizeof. */
+#undef SIZEOF_LONG
+
+/* Refined list of builtin modules */
+#undef SI_BUILTINMODULES
+
+/* Add(list) for Builtin modules */
+#undef SI_BUILTINMODULES_ADD
+
+/* Enable autoloading of reference counted types */
+#undef SI_COUNTEDREF_AUTOLOAD
+
+/* "i686" */
+#undef SI_CPU_I386
+
+/* "ia64" */
+#undef SI_CPU_IA64
+
+/* "PPC" */
+#undef SI_CPU_PPC
+
+/* "SPARC" */
+#undef SI_CPU_SPARC
+
+/* "x86-64" */
+#undef SI_CPU_X86_64
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Singular\'s own uname\ */
+#undef S_UNAME
+
+/* Enable extensions on AIX 3, Interix.  */
+#ifndef _ALL_SOURCE
+# undef _ALL_SOURCE
+#endif
+/* Enable GNU extensions on systems that have them.  */
+#ifndef _GNU_SOURCE
+# undef _GNU_SOURCE
+#endif
+/* Enable threading extensions on Solaris.  */
+#ifndef _POSIX_PTHREAD_SEMANTICS
+# undef _POSIX_PTHREAD_SEMANTICS
+#endif
+/* Enable extensions on HP NonStop.  */
+#ifndef _TANDEM_SOURCE
+# undef _TANDEM_SOURCE
+#endif
+/* Enable general extensions on Solaris.  */
+#ifndef __EXTENSIONS__
+# undef __EXTENSIONS__
+#endif
+
+
+/* Version number of package */
+#undef VERSION
+
+/* release date */
+#undef VERSION_DATE
+
+/* Define to 1 if on MINIX. */
+#undef _MINIX
+
+/* Define to 2 if the system does not provide POSIX.1 features except with
+   this defined. */
+#undef _POSIX_1_SOURCE
+
+/* Define to 1 if you need to in order for `stat' and other things to work. */
+#undef _POSIX_SOURCE
+
+/* Define to rpl_malloc if the replacement function should be used. */
+#undef malloc
diff --git a/aclocal.m4 b/aclocal.m4
new file mode 100644
index 0000000..02929a1
--- /dev/null
+++ b/aclocal.m4
@@ -0,0 +1,1195 @@
+# generated automatically by aclocal 1.13.4 -*- Autoconf -*-
+
+# Copyright (C) 1996-2013 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_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])
+m4_ifndef([AC_AUTOCONF_VERSION],
+  [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],,
+[m4_warning([this file was generated for autoconf 2.69.
+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'.])])
+
+# Copyright (C) 2002-2013 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.13'
+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.13.4], [],
+      [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.13.4])dnl
+m4_ifndef([AC_AUTOCONF_VERSION],
+  [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
+
+# Copyright (C) 2011-2013 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_AR([ACT-IF-FAIL])
+# -------------------------
+# Try to determine the archiver interface, and trigger the ar-lib wrapper
+# if it is needed.  If the detection of archiver interface fails, run
+# ACT-IF-FAIL (default is to abort configure with a proper error message).
+AC_DEFUN([AM_PROG_AR],
+[AC_BEFORE([$0], [LT_INIT])dnl
+AC_BEFORE([$0], [AC_PROG_LIBTOOL])dnl
+AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([ar-lib])dnl
+AC_CHECK_TOOLS([AR], [ar lib "link -lib"], [false])
+: ${AR=ar}
+
+AC_CACHE_CHECK([the archiver ($AR) interface], [am_cv_ar_interface],
+  [am_cv_ar_interface=ar
+   AC_COMPILE_IFELSE([AC_LANG_SOURCE([[int some_variable = 0;]])],
+     [am_ar_try='$AR cru libconftest.a conftest.$ac_objext >&AS_MESSAGE_LOG_FD'
+      AC_TRY_EVAL([am_ar_try])
+      if test "$ac_status" -eq 0; then
+        am_cv_ar_interface=ar
+      else
+        am_ar_try='$AR -NOLOGO -OUT:conftest.lib conftest.$ac_objext >&AS_MESSAGE_LOG_FD'
+        AC_TRY_EVAL([am_ar_try])
+        if test "$ac_status" -eq 0; then
+          am_cv_ar_interface=lib
+        else
+          am_cv_ar_interface=unknown
+        fi
+      fi
+      rm -f conftest.lib libconftest.a
+     ])
+   ])
+
+case $am_cv_ar_interface in
+ar)
+  ;;
+lib)
+  # Microsoft lib, so override with the ar-lib wrapper script.
+  # FIXME: It is wrong to rewrite AR.
+  # But if we don't then we get into trouble of one sort or another.
+  # A longer-term fix would be to have automake use am__AR in this case,
+  # and then we could set am__AR="$am_aux_dir/ar-lib \$(AR)" or something
+  # similar.
+  AR="$am_aux_dir/ar-lib $AR"
+  ;;
+unknown)
+  m4_default([$1],
+             [AC_MSG_ERROR([could not determine $AR interface])])
+  ;;
+esac
+AC_SUBST([AR])dnl
+])
+
+# AM_AUX_DIR_EXPAND                                         -*- Autoconf -*-
+
+# Copyright (C) 2001-2013 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-2013 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_CONDITIONAL(NAME, SHELL-CONDITION)
+# -------------------------------------
+# Define a conditional.
+AC_DEFUN([AM_CONDITIONAL],
+[AC_PREREQ([2.52])dnl
+ m4_if([$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-2013 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.
+
+
+# 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", "OBJC", "OBJCXX", "UPC", or "GJC".
+# 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
+
+m4_if([$1], [CC],   [depcc="$CC"   am_compiler_list=],
+      [$1], [CXX],  [depcc="$CXX"  am_compiler_list=],
+      [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
+      [$1], [OBJCXX], [depcc="$OBJCXX" 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".
+  rm -rf conftest.dir
+  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 10 /bin/sh.
+      echo '/* dummy */' > 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
+      ;;
+    msvc7 | msvc7msys | 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], [dnl
+AS_HELP_STRING(
+  [--enable-dependency-tracking],
+  [do not reject slow dependency extractors])
+AS_HELP_STRING(
+  [--disable-dependency-tracking],
+  [speeds up one-time build])])
+if test "x$enable_dependency_tracking" != xno; then
+  am_depcomp="$ac_aux_dir/depcomp"
+  AMDEPBACKSLASH='\'
+  am__nodep='_no'
+fi
+AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
+AC_SUBST([AMDEPBACKSLASH])dnl
+_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl
+AC_SUBST([am__nodep])dnl
+_AM_SUBST_NOTMAKE([am__nodep])dnl
+])
+
+# Generate code to set up dependency tracking.              -*- Autoconf -*-
+
+# Copyright (C) 1999-2013 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_OUTPUT_DEPENDENCY_COMMANDS
+# ------------------------------
+AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
+[{
+  # Older Autoconf 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"`
+    # 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'`; 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"])
+])
+
+# Do all the work for Automake.                             -*- Autoconf -*-
+
+# Copyright (C) 1996-2013 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 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.65])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],
+[AC_DIAGNOSE([obsolete],
+             [$0: two- and three-arguments forms are deprecated.])
+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], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]),
+  [ok:ok],,
+  [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([AC_PROG_MKDIR_P])dnl
+# For better backward compatibility.  To be removed once Automake 1.9.x
+# dies out for good.  For more background, see:
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
+AC_SUBST([mkdir_p], ['$(MKDIR_P)'])
+# 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])],
+		  [m4_define([AC_PROG_CC],
+			     m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_CXX],
+		  [_AM_DEPENDENCIES([CXX])],
+		  [m4_define([AC_PROG_CXX],
+			     m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_OBJC],
+		  [_AM_DEPENDENCIES([OBJC])],
+		  [m4_define([AC_PROG_OBJC],
+			     m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_OBJCXX],
+		  [_AM_DEPENDENCIES([OBJCXX])],
+		  [m4_define([AC_PROG_OBJCXX],
+			     m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl
+])
+AC_REQUIRE([AM_SILENT_RULES])dnl
+dnl The testsuite driver may need to know about EXEEXT, so add the
+dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen.  This
+dnl macro 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-2013 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-2013 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.
+
+# 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-2013 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_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 enable maintainer-specific portions of Makefiles])
+  dnl maintainer-mode's default is 'disable' unless 'enable' is passed
+  AC_ARG_ENABLE([maintainer-mode],
+    [AS_HELP_STRING([--]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
+]
+)
+
+# Check to see how 'make' treats includes.	            -*- Autoconf -*-
+
+# Copyright (C) 2001-2013 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_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
+])
+
+# Copyright (C) 1999-2013 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_CC_C_O
+# --------------
+# Like AC_PROG_CC_C_O, but changed for automake.
+AC_DEFUN([AM_PROG_CC_C_O],
+[AC_REQUIRE([AC_PROG_CC_C_O])dnl
+AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([compile])dnl
+# FIXME: we rely on the cache variable name because
+# there is no other way.
+set dummy $CC
+am_cc=`echo $[2] | sed ['s/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/']`
+eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o
+if test "$am_t" != yes; then
+   # Losing compiler, so override with the script.
+   # FIXME: It is wrong to rewrite CC.
+   # But if we don't then we get into trouble of one sort or another.
+   # A longer-term fix would be to have automake use am__CC in this case,
+   # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
+   CC="$am_aux_dir/compile $CC"
+fi
+dnl Make sure AC_PROG_CC is never called again, or it will override our
+dnl setting of CC.
+m4_define([AC_PROG_CC],
+          [m4_fatal([AC_PROG_CC cannot be called after AM_PROG_CC_C_O])])
+])
+
+# Fake the existence of programs that GNU maintainers use.  -*- Autoconf -*-
+
+# Copyright (C) 1997-2013 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_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 is modern enough.
+# If it is, 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 --is-lightweight"; then
+  am_missing_run="$MISSING "
+else
+  am_missing_run=
+  AC_MSG_WARN(['missing' script is too old or missing])
+fi
+])
+
+# Helper functions for option handling.                     -*- Autoconf -*-
+
+# Copyright (C) 2001-2013 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_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-2013 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_SANITY_CHECK
+# ---------------
+AC_DEFUN([AM_SANITY_CHECK],
+[AC_MSG_CHECKING([whether build environment is sane])
+# 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 (
+   am_has_slept=no
+   for am_try in 1 2; do
+     echo "timestamp, slept: $am_has_slept" > conftest.file
+     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
+     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
+     if test "$[2]" = conftest.file || test $am_try -eq 2; then
+       break
+     fi
+     # Just in case.
+     sleep 1
+     am_has_slept=yes
+   done
+   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])
+# If we didn't sleep, we still need to ensure time stamps of config.status and
+# generated files are strictly newer.
+am_sleep_pid=
+if grep 'slept: no' conftest.file >/dev/null 2>&1; then
+  ( sleep 1 ) &
+  am_sleep_pid=$!
+fi
+AC_CONFIG_COMMANDS_PRE(
+  [AC_MSG_CHECKING([that generated files are newer than configure])
+   if test -n "$am_sleep_pid"; then
+     # Hide warnings about reused PIDs.
+     wait $am_sleep_pid 2>/dev/null
+   fi
+   AC_MSG_RESULT([done])])
+rm -f conftest.file
+])
+
+# Copyright (C) 2009-2013 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_SILENT_RULES([DEFAULT])
+# --------------------------
+# Enable less verbose build rules; with the default set to DEFAULT
+# ("yes" being less verbose, "no" or empty being verbose).
+AC_DEFUN([AM_SILENT_RULES],
+[AC_ARG_ENABLE([silent-rules], [dnl
+AS_HELP_STRING(
+  [--enable-silent-rules],
+  [less verbose build output (undo: "make V=1")])
+AS_HELP_STRING(
+  [--disable-silent-rules],
+  [verbose build output (undo: "make V=0")])dnl
+])
+case $enable_silent_rules in @%:@ (((
+  yes) AM_DEFAULT_VERBOSITY=0;;
+   no) AM_DEFAULT_VERBOSITY=1;;
+    *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);;
+esac
+dnl
+dnl A few 'make' implementations (e.g., NonStop OS and NextStep)
+dnl do not support nested variable expansions.
+dnl See automake bug#9928 and bug#10237.
+am_make=${MAKE-make}
+AC_CACHE_CHECK([whether $am_make supports nested variables],
+   [am_cv_make_support_nested_variables],
+   [if AS_ECHO([['TRUE=$(BAR$(V))
+BAR0=false
+BAR1=true
+V=1
+am__doit:
+	@$(TRUE)
+.PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then
+  am_cv_make_support_nested_variables=yes
+else
+  am_cv_make_support_nested_variables=no
+fi])
+if test $am_cv_make_support_nested_variables = yes; then
+  dnl Using '$V' instead of '$(V)' breaks IRIX make.
+  AM_V='$(V)'
+  AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
+else
+  AM_V=$AM_DEFAULT_VERBOSITY
+  AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY
+fi
+AC_SUBST([AM_V])dnl
+AM_SUBST_NOTMAKE([AM_V])dnl
+AC_SUBST([AM_DEFAULT_V])dnl
+AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl
+AC_SUBST([AM_DEFAULT_VERBOSITY])dnl
+AM_BACKSLASH='\'
+AC_SUBST([AM_BACKSLASH])dnl
+_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl
+])
+
+# Copyright (C) 2001-2013 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-2013 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_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-2013 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_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.  Yes, it's still used
+# in the wild :-(  We should find a proper way to deprecate it ...
+AC_SUBST([AMTAR], ['$${TAR-tar}'])
+
+# We'll loop over all known methods to create a tar archive until one works.
+_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
+
+m4_if([$1], [v7],
+  [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'],
+
+  [m4_case([$1],
+    [ustar],
+     [# The POSIX 1988 'ustar' format is defined with fixed-size fields.
+      # There is notably a 21 bits limit for the UID and the GID.  In fact,
+      # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343
+      # and bug#13588).
+      am_max_uid=2097151 # 2^21 - 1
+      am_max_gid=$am_max_uid
+      # The $UID and $GID variables are not portable, so we need to resort
+      # to the POSIX-mandated id(1) utility.  Errors in the 'id' calls
+      # below are definitely unexpected, so allow the users to see them
+      # (that is, avoid stderr redirection).
+      am_uid=`id -u || echo unknown`
+      am_gid=`id -g || echo unknown`
+      AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format])
+      if test $am_uid -le $am_max_uid; then
+         AC_MSG_RESULT([yes])
+      else
+         AC_MSG_RESULT([no])
+         _am_tools=none
+      fi
+      AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format])
+      if test $am_gid -le $am_max_gid; then
+         AC_MSG_RESULT([yes])
+      else
+        AC_MSG_RESULT([no])
+        _am_tools=none
+      fi],
+
+  [pax],
+    [],
+
+  [m4_fatal([Unknown tar format])])
+
+  AC_MSG_CHECKING([how to create a $1 tar archive])
+
+  # Go ahead even if we have the value already cached.  We do so because we
+  # need to set the values for the 'am__tar' and 'am__untar' variables.
+  _am_tools=${am_cv_prog_tar_$1-$_am_tools}
+
+  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])
+      AM_RUN_LOG([cat conftest.dir/file])
+      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([m4/ax_append_compile_flags.m4])
+m4_include([m4/ax_append_flag.m4])
+m4_include([m4/ax_append_link_flags.m4])
+m4_include([m4/ax_check_compile_flag.m4])
+m4_include([m4/ax_check_link_flag.m4])
+m4_include([m4/ax_compute_relative_paths.m4])
+m4_include([m4/ax_normalize_path.m4])
+m4_include([m4/ax_prefix_config_h.m4])
+m4_include([m4/ax_pthread.m4])
+m4_include([m4/ax_python_embed.m4])
+m4_include([m4/ax_python_with_version.m4])
+m4_include([m4/cpu-check.m4])
+m4_include([m4/dbm-check.m4])
+m4_include([m4/flags.m4])
+m4_include([m4/flint-check.m4])
+m4_include([m4/gfanlib-check.m4])
+m4_include([m4/gmp-check.m4])
+m4_include([m4/google-perftools.m4])
+m4_include([m4/libtool.m4])
+m4_include([m4/ltoptions.m4])
+m4_include([m4/ltsugar.m4])
+m4_include([m4/ltversion.m4])
+m4_include([m4/lt~obsolete.m4])
+m4_include([m4/mathic-check.m4])
+m4_include([m4/ntl-check.m4])
+m4_include([m4/options.m4])
+m4_include([m4/p-procs.m4])
+m4_include([m4/polymake-check.m4])
+m4_include([m4/readline-check.m4])
diff --git a/autogen.sh b/autogen.sh
new file mode 100755
index 0000000..d027997
--- /dev/null
+++ b/autogen.sh
@@ -0,0 +1,9 @@
+#! /bin/sh
+
+cd `dirname "$0"`
+
+# -d --warnings=all
+autoreconf  -v -f -i
+
+cd -
+
diff --git a/build-aux/ar-lib b/build-aux/ar-lib
new file mode 100755
index 0000000..fe2301e
--- /dev/null
+++ b/build-aux/ar-lib
@@ -0,0 +1,270 @@
+#! /bin/sh
+# Wrapper for Microsoft lib.exe
+
+me=ar-lib
+scriptversion=2012-03-01.08; # UTC
+
+# Copyright (C) 2010-2013 Free Software Foundation, Inc.
+# Written by Peter Rosin <peda at lysator.liu.se>.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+
+# 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>.
+
+
+# func_error message
+func_error ()
+{
+  echo "$me: $1" 1>&2
+  exit 1
+}
+
+file_conv=
+
+# func_file_conv build_file
+# Convert a $build file to $host form and store it in $file
+# Currently only supports Windows hosts.
+func_file_conv ()
+{
+  file=$1
+  case $file in
+    / | /[!/]*) # absolute file, and not a UNC file
+      if test -z "$file_conv"; then
+	# lazily determine how to convert abs files
+	case `uname -s` in
+	  MINGW*)
+	    file_conv=mingw
+	    ;;
+	  CYGWIN*)
+	    file_conv=cygwin
+	    ;;
+	  *)
+	    file_conv=wine
+	    ;;
+	esac
+      fi
+      case $file_conv in
+	mingw)
+	  file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
+	  ;;
+	cygwin)
+	  file=`cygpath -m "$file" || echo "$file"`
+	  ;;
+	wine)
+	  file=`winepath -w "$file" || echo "$file"`
+	  ;;
+      esac
+      ;;
+  esac
+}
+
+# func_at_file at_file operation archive
+# Iterate over all members in AT_FILE performing OPERATION on ARCHIVE
+# for each of them.
+# When interpreting the content of the @FILE, do NOT use func_file_conv,
+# since the user would need to supply preconverted file names to
+# binutils ar, at least for MinGW.
+func_at_file ()
+{
+  operation=$2
+  archive=$3
+  at_file_contents=`cat "$1"`
+  eval set x "$at_file_contents"
+  shift
+
+  for member
+  do
+    $AR -NOLOGO $operation:"$member" "$archive" || exit $?
+  done
+}
+
+case $1 in
+  '')
+     func_error "no command.  Try '$0 --help' for more information."
+     ;;
+  -h | --h*)
+    cat <<EOF
+Usage: $me [--help] [--version] PROGRAM ACTION ARCHIVE [MEMBER...]
+
+Members may be specified in a file named with @FILE.
+EOF
+    exit $?
+    ;;
+  -v | --v*)
+    echo "$me, version $scriptversion"
+    exit $?
+    ;;
+esac
+
+if test $# -lt 3; then
+  func_error "you must specify a program, an action and an archive"
+fi
+
+AR=$1
+shift
+while :
+do
+  if test $# -lt 2; then
+    func_error "you must specify a program, an action and an archive"
+  fi
+  case $1 in
+    -lib | -LIB \
+    | -ltcg | -LTCG \
+    | -machine* | -MACHINE* \
+    | -subsystem* | -SUBSYSTEM* \
+    | -verbose | -VERBOSE \
+    | -wx* | -WX* )
+      AR="$AR $1"
+      shift
+      ;;
+    *)
+      action=$1
+      shift
+      break
+      ;;
+  esac
+done
+orig_archive=$1
+shift
+func_file_conv "$orig_archive"
+archive=$file
+
+# strip leading dash in $action
+action=${action#-}
+
+delete=
+extract=
+list=
+quick=
+replace=
+index=
+create=
+
+while test -n "$action"
+do
+  case $action in
+    d*) delete=yes  ;;
+    x*) extract=yes ;;
+    t*) list=yes    ;;
+    q*) quick=yes   ;;
+    r*) replace=yes ;;
+    s*) index=yes   ;;
+    S*)             ;; # the index is always updated implicitly
+    c*) create=yes  ;;
+    u*)             ;; # TODO: don't ignore the update modifier
+    v*)             ;; # TODO: don't ignore the verbose modifier
+    *)
+      func_error "unknown action specified"
+      ;;
+  esac
+  action=${action#?}
+done
+
+case $delete$extract$list$quick$replace,$index in
+  yes,* | ,yes)
+    ;;
+  yesyes*)
+    func_error "more than one action specified"
+    ;;
+  *)
+    func_error "no action specified"
+    ;;
+esac
+
+if test -n "$delete"; then
+  if test ! -f "$orig_archive"; then
+    func_error "archive not found"
+  fi
+  for member
+  do
+    case $1 in
+      @*)
+        func_at_file "${1#@}" -REMOVE "$archive"
+        ;;
+      *)
+        func_file_conv "$1"
+        $AR -NOLOGO -REMOVE:"$file" "$archive" || exit $?
+        ;;
+    esac
+  done
+
+elif test -n "$extract"; then
+  if test ! -f "$orig_archive"; then
+    func_error "archive not found"
+  fi
+  if test $# -gt 0; then
+    for member
+    do
+      case $1 in
+        @*)
+          func_at_file "${1#@}" -EXTRACT "$archive"
+          ;;
+        *)
+          func_file_conv "$1"
+          $AR -NOLOGO -EXTRACT:"$file" "$archive" || exit $?
+          ;;
+      esac
+    done
+  else
+    $AR -NOLOGO -LIST "$archive" | sed -e 's/\\/\\\\/g' | while read member
+    do
+      $AR -NOLOGO -EXTRACT:"$member" "$archive" || exit $?
+    done
+  fi
+
+elif test -n "$quick$replace"; then
+  if test ! -f "$orig_archive"; then
+    if test -z "$create"; then
+      echo "$me: creating $orig_archive"
+    fi
+    orig_archive=
+  else
+    orig_archive=$archive
+  fi
+
+  for member
+  do
+    case $1 in
+    @*)
+      func_file_conv "${1#@}"
+      set x "$@" "@$file"
+      ;;
+    *)
+      func_file_conv "$1"
+      set x "$@" "$file"
+      ;;
+    esac
+    shift
+    shift
+  done
+
+  if test -n "$orig_archive"; then
+    $AR -NOLOGO -OUT:"$archive" "$orig_archive" "$@" || exit $?
+  else
+    $AR -NOLOGO -OUT:"$archive" "$@" || exit $?
+  fi
+
+elif test -n "$list"; then
+  if test ! -f "$orig_archive"; then
+    func_error "archive not found"
+  fi
+  $AR -NOLOGO -LIST "$archive" || exit $?
+fi
diff --git a/build-aux/compile b/build-aux/compile
new file mode 100755
index 0000000..531136b
--- /dev/null
+++ b/build-aux/compile
@@ -0,0 +1,347 @@
+#! /bin/sh
+# Wrapper for compilers which do not understand '-c -o'.
+
+scriptversion=2012-10-14.11; # UTC
+
+# Copyright (C) 1999-2013 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, see <http://www.gnu.org/licenses/>.
+
+# 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>.
+
+nl='
+'
+
+# We need space, tab and new line, in precisely that order.  Quoting is
+# there to prevent tools from complaining about whitespace usage.
+IFS=" ""	$nl"
+
+file_conv=
+
+# func_file_conv build_file lazy
+# Convert a $build file to $host form and store it in $file
+# Currently only supports Windows hosts. If the determined conversion
+# type is listed in (the comma separated) LAZY, no conversion will
+# take place.
+func_file_conv ()
+{
+  file=$1
+  case $file in
+    / | /[!/]*) # absolute file, and not a UNC file
+      if test -z "$file_conv"; then
+	# lazily determine how to convert abs files
+	case `uname -s` in
+	  MINGW*)
+	    file_conv=mingw
+	    ;;
+	  CYGWIN*)
+	    file_conv=cygwin
+	    ;;
+	  *)
+	    file_conv=wine
+	    ;;
+	esac
+      fi
+      case $file_conv/,$2, in
+	*,$file_conv,*)
+	  ;;
+	mingw/*)
+	  file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
+	  ;;
+	cygwin/*)
+	  file=`cygpath -m "$file" || echo "$file"`
+	  ;;
+	wine/*)
+	  file=`winepath -w "$file" || echo "$file"`
+	  ;;
+      esac
+      ;;
+  esac
+}
+
+# func_cl_dashL linkdir
+# Make cl look for libraries in LINKDIR
+func_cl_dashL ()
+{
+  func_file_conv "$1"
+  if test -z "$lib_path"; then
+    lib_path=$file
+  else
+    lib_path="$lib_path;$file"
+  fi
+  linker_opts="$linker_opts -LIBPATH:$file"
+}
+
+# func_cl_dashl library
+# Do a library search-path lookup for cl
+func_cl_dashl ()
+{
+  lib=$1
+  found=no
+  save_IFS=$IFS
+  IFS=';'
+  for dir in $lib_path $LIB
+  do
+    IFS=$save_IFS
+    if $shared && test -f "$dir/$lib.dll.lib"; then
+      found=yes
+      lib=$dir/$lib.dll.lib
+      break
+    fi
+    if test -f "$dir/$lib.lib"; then
+      found=yes
+      lib=$dir/$lib.lib
+      break
+    fi
+    if test -f "$dir/lib$lib.a"; then
+      found=yes
+      lib=$dir/lib$lib.a
+      break
+    fi
+  done
+  IFS=$save_IFS
+
+  if test "$found" != yes; then
+    lib=$lib.lib
+  fi
+}
+
+# func_cl_wrapper cl arg...
+# Adjust compile command to suit cl
+func_cl_wrapper ()
+{
+  # Assume a capable shell
+  lib_path=
+  shared=:
+  linker_opts=
+  for arg
+  do
+    if test -n "$eat"; then
+      eat=
+    else
+      case $1 in
+	-o)
+	  # configure might choose to run compile as 'compile cc -o foo foo.c'.
+	  eat=1
+	  case $2 in
+	    *.o | *.[oO][bB][jJ])
+	      func_file_conv "$2"
+	      set x "$@" -Fo"$file"
+	      shift
+	      ;;
+	    *)
+	      func_file_conv "$2"
+	      set x "$@" -Fe"$file"
+	      shift
+	      ;;
+	  esac
+	  ;;
+	-I)
+	  eat=1
+	  func_file_conv "$2" mingw
+	  set x "$@" -I"$file"
+	  shift
+	  ;;
+	-I*)
+	  func_file_conv "${1#-I}" mingw
+	  set x "$@" -I"$file"
+	  shift
+	  ;;
+	-l)
+	  eat=1
+	  func_cl_dashl "$2"
+	  set x "$@" "$lib"
+	  shift
+	  ;;
+	-l*)
+	  func_cl_dashl "${1#-l}"
+	  set x "$@" "$lib"
+	  shift
+	  ;;
+	-L)
+	  eat=1
+	  func_cl_dashL "$2"
+	  ;;
+	-L*)
+	  func_cl_dashL "${1#-L}"
+	  ;;
+	-static)
+	  shared=false
+	  ;;
+	-Wl,*)
+	  arg=${1#-Wl,}
+	  save_ifs="$IFS"; IFS=','
+	  for flag in $arg; do
+	    IFS="$save_ifs"
+	    linker_opts="$linker_opts $flag"
+	  done
+	  IFS="$save_ifs"
+	  ;;
+	-Xlinker)
+	  eat=1
+	  linker_opts="$linker_opts $2"
+	  ;;
+	-*)
+	  set x "$@" "$1"
+	  shift
+	  ;;
+	*.cc | *.CC | *.cxx | *.CXX | *.[cC]++)
+	  func_file_conv "$1"
+	  set x "$@" -Tp"$file"
+	  shift
+	  ;;
+	*.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO])
+	  func_file_conv "$1" mingw
+	  set x "$@" "$file"
+	  shift
+	  ;;
+	*)
+	  set x "$@" "$1"
+	  shift
+	  ;;
+      esac
+    fi
+    shift
+  done
+  if test -n "$linker_opts"; then
+    linker_opts="-link$linker_opts"
+  fi
+  exec "$@" $linker_opts
+  exit 1
+}
+
+eat=
+
+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 $?
+    ;;
+  -v | --v*)
+    echo "compile $scriptversion"
+    exit $?
+    ;;
+  cl | *[/\\]cl | cl.exe | *[/\\]cl.exe )
+    func_cl_wrapper "$@"      # Doesn't return...
+    ;;
+esac
+
+ofile=
+cfile=
+
+for arg
+do
+  if test -n "$eat"; then
+    eat=
+  else
+    case $1 in
+      -o)
+	# configure might choose to run compile as 'compile cc -o foo foo.c'.
+	# So we strip '-o arg' only if arg is an object.
+	eat=1
+	case $2 in
+	  *.o | *.obj)
+	    ofile=$2
+	    ;;
+	  *)
+	    set x "$@" -o "$2"
+	    shift
+	    ;;
+	esac
+	;;
+      *.c)
+	cfile=$1
+	set x "$@" "$1"
+	shift
+	;;
+      *)
+	set x "$@" "$1"
+	shift
+	;;
+    esac
+  fi
+  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 "$@"
+fi
+
+# Name of file we expect compiler to create.
+cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; 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.
+"$@"
+ret=$?
+
+if test -f "$cofile"; then
+  test "$cofile" = "$ofile" || mv "$cofile" "$ofile"
+elif test -f "${cofile}bj"; then
+  test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile"
+fi
+
+rmdir "$lockdir"
+exit $ret
+
+# 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-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/build-aux/config.guess b/build-aux/config.guess
new file mode 100755
index 0000000..9c9d05b
--- /dev/null
+++ b/build-aux/config.guess
@@ -0,0 +1,1431 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+#   Copyright 1992-2014 Free Software Foundation, Inc.
+
+timestamp='2014-02-12'
+
+# 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 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
+#
+# 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 Exception is an additional permission under section 7
+# of the GNU General Public License, version 3 ("GPLv3").
+#
+# Originally written by Per Bothner.
+#
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+#
+# Please send patches with a ChangeLog entry to config-patches at gnu.org.
+
+
+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 1992-2014 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
+
+case "${UNAME_SYSTEM}" in
+Linux|GNU|GNU/*)
+	# If the system lacks a compiler, then just pick glibc.
+	# We could probably try harder.
+	LIBC=gnu
+
+	eval $set_cc_for_build
+	cat <<-EOF > $dummy.c
+	#include <features.h>
+	#if defined(__UCLIBC__)
+	LIBC=uclibc
+	#elif defined(__dietlibc__)
+	LIBC=dietlibc
+	#else
+	LIBC=gnu
+	#endif
+	EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`
+	;;
+esac
+
+# 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 tuples: *-*-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 -q __ELF__
+		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 ;;
+    *:Bitrig:*:*)
+	UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
+	echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_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'`
+	# Reset EXIT trap before exiting to avoid spurious non-zero exit code.
+	exitcode=$?
+	trap '' 0
+	exit $exitcode ;;
+    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 ;;
+    s390x:SunOS:*:*)
+	echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    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:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
+	echo i386-pc-auroraux${UNAME_RELEASE}
+	exit ;;
+    i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
+	eval $set_cc_for_build
+	SUN_ARCH="i386"
+	# If there is a compiler, see if it is configured for 64-bit objects.
+	# Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
+	# This test works for both compilers.
+	if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+	    if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
+		(CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+		grep IS_64BIT_ARCH >/dev/null
+	    then
+		SUN_ARCH="x86_64"
+	    fi
+	fi
+	echo ${SUN_ARCH}-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:*:[4567])
+	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 -q __LP64__
+	    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:*:*)
+	UNAME_PROCESSOR=`/usr/bin/uname -p`
+	case ${UNAME_PROCESSOR} in
+	    amd64)
+		echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+	    *)
+		echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+	esac
+	exit ;;
+    i*:CYGWIN*:*)
+	echo ${UNAME_MACHINE}-pc-cygwin
+	exit ;;
+    *:MINGW64*:*)
+	echo ${UNAME_MACHINE}-pc-mingw64
+	exit ;;
+    *:MINGW*:*)
+	echo ${UNAME_MACHINE}-pc-mingw32
+	exit ;;
+    i*:MSYS*:*)
+	echo ${UNAME_MACHINE}-pc-msys
+	exit ;;
+    i*:windows32*:*)
+	# uname -m includes "-pc" on this system.
+	echo ${UNAME_MACHINE}-mingw32
+	exit ;;
+    i*:PW*:*)
+	echo ${UNAME_MACHINE}-pc-pw32
+	exit ;;
+    *:Interix*:*)
+	case ${UNAME_MACHINE} in
+	    x86)
+		echo i586-pc-interix${UNAME_RELEASE}
+		exit ;;
+	    authenticamd | genuineintel | EM64T)
+		echo x86_64-unknown-interix${UNAME_RELEASE}
+		exit ;;
+	    IA64)
+		echo ia64-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 ;;
+    8664:Windows_NT:*)
+	echo x86_64-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-${LIBC}`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/[-(].*//'`-${LIBC}
+	exit ;;
+    i*86:Minix:*:*)
+	echo ${UNAME_MACHINE}-pc-minix
+	exit ;;
+    aarch64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    aarch64_be:Linux:*:*)
+	UNAME_MACHINE=aarch64_be
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	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 -q ld.so.1
+	if test "$?" = 0 ; then LIBC="gnulibc1" ; fi
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    arc:Linux:*:* | arceb:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    arm*:Linux:*:*)
+	eval $set_cc_for_build
+	if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
+	    | grep -q __ARM_EABI__
+	then
+	    echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	else
+	    if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
+		| grep -q __ARM_PCS_VFP
+	    then
+		echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi
+	    else
+		echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf
+	    fi
+	fi
+	exit ;;
+    avr32*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    cris:Linux:*:*)
+	echo ${UNAME_MACHINE}-axis-linux-${LIBC}
+	exit ;;
+    crisv32:Linux:*:*)
+	echo ${UNAME_MACHINE}-axis-linux-${LIBC}
+	exit ;;
+    frv:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    hexagon:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    i*86:Linux:*:*)
+	echo ${UNAME_MACHINE}-pc-linux-${LIBC}
+	exit ;;
+    ia64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    m32r*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    m68*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    mips:Linux:*:* | mips64:Linux:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#undef CPU
+	#undef ${UNAME_MACHINE}
+	#undef ${UNAME_MACHINE}el
+	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+	CPU=${UNAME_MACHINE}el
+	#else
+	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+	CPU=${UNAME_MACHINE}
+	#else
+	CPU=
+	#endif
+	#endif
+EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
+	test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; }
+	;;
+    or1k:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    or32:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    padre:Linux:*:*)
+	echo sparc-unknown-linux-${LIBC}
+	exit ;;
+    parisc64:Linux:*:* | hppa64:Linux:*:*)
+	echo hppa64-unknown-linux-${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-${LIBC} ;;
+	  PA8*) echo hppa2.0-unknown-linux-${LIBC} ;;
+	  *)    echo hppa-unknown-linux-${LIBC} ;;
+	esac
+	exit ;;
+    ppc64:Linux:*:*)
+	echo powerpc64-unknown-linux-${LIBC}
+	exit ;;
+    ppc:Linux:*:*)
+	echo powerpc-unknown-linux-${LIBC}
+	exit ;;
+    ppc64le:Linux:*:*)
+	echo powerpc64le-unknown-linux-${LIBC}
+	exit ;;
+    ppcle:Linux:*:*)
+	echo powerpcle-unknown-linux-${LIBC}
+	exit ;;
+    s390:Linux:*:* | s390x:Linux:*:*)
+	echo ${UNAME_MACHINE}-ibm-linux-${LIBC}
+	exit ;;
+    sh64*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    sh*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    sparc:Linux:*:* | sparc64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    tile*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    vax:Linux:*:*)
+	echo ${UNAME_MACHINE}-dec-linux-${LIBC}
+	exit ;;
+    x86_64:Linux:*:*)
+	eval $set_cc_for_build
+	X86_64_ABI=
+	# If there is a compiler, see if it is configured for 32-bit objects.
+	if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+	    if (echo '#ifdef __ILP32__'; echo IS_X32; echo '#endif') | \
+		(CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+		grep IS_X32 >/dev/null
+	    then
+		X86_64_ABI=x32
+	    fi
+	fi
+	echo x86_64-unknown-linux-gnu${X86_64_ABI}
+	exit ;;
+    xtensa*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	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.[02]*:*)
+	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 i586.
+	# Note: whatever this is, it MUST be the same as what config.sub
+	# prints for the "djgpp" host, or else GDB configury will decide that
+	# this is a cross-build.
+	echo i586-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; } ;;
+    NCR*:*:4.2:* | MPRAS*:*:4.2:*)
+	OS_REL='.3'
+	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; }
+	/bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
+	    && { echo i586-ncr-sysv4.3${OS_REL}; 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.[02]*:*)
+	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 ;;
+    BePC:Haiku:*:*)	# Haiku running on Intel PC compatible.
+	echo i586-pc-haiku
+	exit ;;
+    x86_64:Haiku:*:*)
+	echo x86_64-unknown-haiku
+	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
+	eval $set_cc_for_build
+	if test "$UNAME_PROCESSOR" = unknown ; then
+	    UNAME_PROCESSOR=powerpc
+	fi
+	if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then
+	    if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+		if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
+		    (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+		    grep IS_64BIT_ARCH >/dev/null
+		then
+		    case $UNAME_PROCESSOR in
+			i386) UNAME_PROCESSOR=x86_64 ;;
+			powerpc) UNAME_PROCESSOR=powerpc64 ;;
+		    esac
+		fi
+	    fi
+	elif test "$UNAME_PROCESSOR" = i386 ; then
+	    # Avoid executing cc on OS X 10.9, as it ships with a stub
+	    # that puts up a graphical alert prompting to install
+	    # developer tools.  Any system running Mac OS X 10.7 or
+	    # later (Darwin 11 and later) is required to have a 64-bit
+	    # processor. This is not true of the ARM version of Darwin
+	    # that Apple uses in portable devices.
+	    UNAME_PROCESSOR=x86_64
+	fi
+	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 ;;
+    NEO-?:NONSTOP_KERNEL:*:*)
+	echo neo-tandem-nsk${UNAME_RELEASE}
+	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 ;;
+    i*86:AROS:*:*)
+	echo ${UNAME_MACHINE}-pc-aros
+	exit ;;
+    x86_64:VMkernel:*:*)
+	echo ${UNAME_MACHINE}-unknown-esx
+	exit ;;
+esac
+
+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://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+and
+  http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+
+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/build-aux/config.sub b/build-aux/config.sub
new file mode 100755
index 0000000..34c510d
--- /dev/null
+++ b/build-aux/config.sub
@@ -0,0 +1,1811 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+#   Copyright 1992-2014 Free Software Foundation, Inc.
+
+timestamp='2014-01-01'
+
+# 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 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
+#
+# 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 Exception is an additional permission under section 7
+# of the GNU General Public License, version 3 ("GPLv3").
+
+
+# Please send patches with a ChangeLog entry to config-patches at gnu.org.
+#
+# 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.
+
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+
+# 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 1992-2014 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-android* | linux-dietlibc | linux-newlib* | \
+  linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
+  knetbsd*-gnu* | netbsd*-gnu* | \
+  kopensolaris*-gnu* | \
+  storm-chaos* | os2-emx* | rtmk-nova*)
+    os=-$maybe_os
+    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+    ;;
+  android-linux)
+    os=-linux-android
+    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
+    ;;
+  *)
+    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 | -microblaze*)
+		os=
+		basic_machine=$1
+		;;
+	-bluegene*)
+		os=-cnk
+		;;
+	-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*178)
+		os=-lynxos178
+		;;
+	-lynx*5)
+		os=-lynxos5
+		;;
+	-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 \
+	| aarch64 | aarch64_be \
+	| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+	| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+	| am33_2.0 \
+	| arc | arceb \
+	| arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
+	| avr | avr32 \
+	| be32 | be64 \
+	| bfin \
+	| c4x | c8051 | clipper \
+	| d10v | d30v | dlx | dsp16xx | dvp \
+	| epiphany \
+	| fido | fr30 | frv \
+	| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+	| hexagon \
+	| i370 | i860 | i960 | ia64 \
+	| ip2k | iq2000 \
+	| k1om \
+	| le32 | le64 \
+	| lm32 \
+	| m32c | m32r | m32rle | m68000 | m68k | m88k \
+	| maxq | mb | microblaze | microblazeel | mcore | mep | metag \
+	| mips | mipsbe | mipseb | mipsel | mipsle \
+	| mips16 \
+	| mips64 | mips64el \
+	| mips64octeon | mips64octeonel \
+	| mips64orion | mips64orionel \
+	| mips64r5900 | mips64r5900el \
+	| mips64vr | mips64vrel \
+	| mips64vr4100 | mips64vr4100el \
+	| mips64vr4300 | mips64vr4300el \
+	| mips64vr5000 | mips64vr5000el \
+	| mips64vr5900 | mips64vr5900el \
+	| mipsisa32 | mipsisa32el \
+	| mipsisa32r2 | mipsisa32r2el \
+	| mipsisa64 | mipsisa64el \
+	| mipsisa64r2 | mipsisa64r2el \
+	| mipsisa64sb1 | mipsisa64sb1el \
+	| mipsisa64sr71k | mipsisa64sr71kel \
+	| mipsr5900 | mipsr5900el \
+	| mipstx39 | mipstx39el \
+	| mn10200 | mn10300 \
+	| moxie \
+	| mt \
+	| msp430 \
+	| nds32 | nds32le | nds32be \
+	| nios | nios2 | nios2eb | nios2el \
+	| ns16k | ns32k \
+	| open8 \
+	| or1k | or32 \
+	| pdp10 | pdp11 | pj | pjl \
+	| powerpc | powerpc64 | powerpc64le | powerpcle \
+	| pyramid \
+	| rl78 | rx \
+	| score \
+	| sh | sh[1234] | sh[24]a | sh[24]aeb | 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 \
+	| tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
+	| ubicom32 \
+	| v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
+	| we32k \
+	| x86 | xc16x | xstormy16 | xtensa \
+	| z8k | z80)
+		basic_machine=$basic_machine-unknown
+		;;
+	c54x)
+		basic_machine=tic54x-unknown
+		;;
+	c55x)
+		basic_machine=tic55x-unknown
+		;;
+	c6x)
+		basic_machine=tic6x-unknown
+		;;
+	m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip)
+		basic_machine=$basic_machine-unknown
+		os=-none
+		;;
+	m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+		;;
+	ms1)
+		basic_machine=mt-unknown
+		;;
+
+	strongarm | thumb | xscale)
+		basic_machine=arm-unknown
+		;;
+	xgate)
+		basic_machine=$basic_machine-unknown
+		os=-none
+		;;
+	xscaleeb)
+		basic_machine=armeb-unknown
+		;;
+
+	xscaleel)
+		basic_machine=armel-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-* \
+	| aarch64-* | aarch64_be-* \
+	| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+	| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+	| alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
+	| arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
+	| avr-* | avr32-* \
+	| be32-* | be64-* \
+	| bfin-* | bs2000-* \
+	| c[123]* | c30-* | [cjt]90-* | c4x-* \
+	| c8051-* | 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-* \
+	| hexagon-* \
+	| i*86-* | i860-* | i960-* | ia64-* \
+	| ip2k-* | iq2000-* \
+	| k1om-* \
+	| le32-* | le64-* \
+	| lm32-* \
+	| m32c-* | m32r-* | m32rle-* \
+	| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+	| m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
+	| microblaze-* | microblazeel-* \
+	| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+	| mips16-* \
+	| mips64-* | mips64el-* \
+	| mips64octeon-* | mips64octeonel-* \
+	| mips64orion-* | mips64orionel-* \
+	| mips64r5900-* | mips64r5900el-* \
+	| mips64vr-* | mips64vrel-* \
+	| mips64vr4100-* | mips64vr4100el-* \
+	| mips64vr4300-* | mips64vr4300el-* \
+	| mips64vr5000-* | mips64vr5000el-* \
+	| mips64vr5900-* | mips64vr5900el-* \
+	| mipsisa32-* | mipsisa32el-* \
+	| mipsisa32r2-* | mipsisa32r2el-* \
+	| mipsisa64-* | mipsisa64el-* \
+	| mipsisa64r2-* | mipsisa64r2el-* \
+	| mipsisa64sb1-* | mipsisa64sb1el-* \
+	| mipsisa64sr71k-* | mipsisa64sr71kel-* \
+	| mipsr5900-* | mipsr5900el-* \
+	| mipstx39-* | mipstx39el-* \
+	| mmix-* \
+	| mt-* \
+	| msp430-* \
+	| nds32-* | nds32le-* | nds32be-* \
+	| nios-* | nios2-* | nios2eb-* | nios2el-* \
+	| none-* | np1-* | ns16k-* | ns32k-* \
+	| open8-* \
+	| orion-* \
+	| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+	| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
+	| pyramid-* \
+	| rl78-* | romp-* | rs6000-* | rx-* \
+	| sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | 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-* | sv1-* | sx?-* \
+	| tahoe-* \
+	| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+	| tile*-* \
+	| tron-* \
+	| ubicom32-* \
+	| v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
+	| vax-* \
+	| we32k-* \
+	| x86-* | x86_64-* | xc16x-* | xps100-* \
+	| xstormy16-* | xtensa*-* \
+	| ymp-* \
+	| z8k-* | z80-*)
+		;;
+	# Recognize the basic CPU types without company name, with glob match.
+	xtensa*)
+		basic_machine=$basic_machine-unknown
+		;;
+	# 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
+		;;
+	aros)
+		basic_machine=i386-pc
+		os=-aros
+		;;
+	aux)
+		basic_machine=m68k-apple
+		os=-aux
+		;;
+	balance)
+		basic_machine=ns32k-sequent
+		os=-dynix
+		;;
+	blackfin)
+		basic_machine=bfin-unknown
+		os=-linux
+		;;
+	blackfin-*)
+		basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
+		os=-linux
+		;;
+	bluegene*)
+		basic_machine=powerpc-ibm
+		os=-cnk
+		;;
+	c54x-*)
+		basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	c55x-*)
+		basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	c6x-*)
+		basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	c90)
+		basic_machine=c90-cray
+		os=-unicos
+		;;
+	cegcc)
+		basic_machine=arm-unknown
+		os=-cegcc
+		;;
+	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 | 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
+		;;
+	dicos)
+		basic_machine=i686-pc
+		os=-dicos
+		;;
+	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*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
+		;;
+	m68knommu)
+		basic_machine=m68k-unknown
+		os=-linux
+		;;
+	m68knommu-*)
+		basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
+		os=-linux
+		;;
+	m88k-omron*)
+		basic_machine=m88k-omron
+		;;
+	magnum | m3230)
+		basic_machine=mips-mips
+		os=-sysv
+		;;
+	merlin)
+		basic_machine=ns32k-utek
+		os=-sysv
+		;;
+	microblaze*)
+		basic_machine=microblaze-xilinx
+		;;
+	mingw64)
+		basic_machine=x86_64-pc
+		os=-mingw64
+		;;
+	mingw32)
+		basic_machine=i686-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
+		;;
+	mipsEE* | ee | ps2)
+		basic_machine=mips64r5900el-scei
+		case $os in
+		    -linux*)
+			;;
+		    *)
+			os=-elf
+			;;
+		esac
+		;;
+	iop)
+		basic_machine=mipsel-scei
+		os=-irx
+		;;
+	dvp)
+		basic_machine=dvp-scei
+		os=-elf
+		;;
+	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-/'`
+		;;
+	msys)
+		basic_machine=i686-pc
+		os=-msys
+		;;
+	mvs)
+		basic_machine=i370-ibm
+		os=-mvs
+		;;
+	nacl)
+		basic_machine=le32-unknown
+		os=-nacl
+		;;
+	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
+		;;
+	neo-tandem)
+		basic_machine=neo-tandem
+		;;
+	nse-tandem)
+		basic_machine=nse-tandem
+		;;
+	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
+		;;
+	parisc)
+		basic_machine=hppa-unknown
+		os=-linux
+		;;
+	parisc-*)
+		basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
+		os=-linux
+		;;
+	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 | ppcbe)	basic_machine=powerpc-unknown
+		;;
+	ppc-* | ppcbe-*)
+		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 | rdos64)
+		basic_machine=x86_64-pc
+		os=-rdos
+		;;
+	rdos32)
+		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
+		;;
+	strongarm-* | thumb-*)
+		basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	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
+		;;
+	tile*)
+		basic_machine=$basic_machine-unknown
+		os=-linux-gnu
+		;;
+	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
+		;;
+	xscale-* | xscalee[bl]-*)
+		basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`
+		;;
+	ymp)
+		basic_machine=ymp-cray
+		os=-unicos
+		;;
+	z8k-*-coff)
+		basic_machine=z8k-unknown
+		os=-sim
+		;;
+	z80-*-coff)
+		basic_machine=z80-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[24]aeb | 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.
+	-auroraux)
+		os=-auroraux
+		;;
+	-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* | -cnk* | -sunos | -sunos[34]*\
+	      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
+	      | -sym* | -kopensolaris* | -plan9* \
+	      | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+	      | -aos* | -aros* \
+	      | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+	      | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+	      | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
+	      | -bitrig* | -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* | -cegcc* \
+	      | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+	      | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
+	      | -linux-newlib* | -linux-musl* | -linux-uclibc* \
+	      | -uxpv* | -beos* | -mpeix* | -udk* \
+	      | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+	      | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+	      | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* | -irx* \
+	      | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+	      | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+	      | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
+	      | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*)
+	# 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
+		;;
+	-zvmoe)
+		os=-zvmoe
+		;;
+	-dicos*)
+		os=-dicos
+		;;
+	-nacl*)
+		;;
+	-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
+		;;
+	c8051-*)
+		os=-elf
+		;;
+	hexagon-*)
+		os=-elf
+		;;
+	tic54x-*)
+		os=-coff
+		;;
+	tic55x-*)
+		os=-coff
+		;;
+	tic6x-*)
+		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
+		;;
+	m68*-cisco)
+		os=-aout
+		;;
+	mep-*)
+		os=-elf
+		;;
+	mips*-cisco)
+		os=-elf
+		;;
+	mips*-*)
+		os=-elf
+		;;
+	or1k-*)
+		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
+				;;
+			-cnk*|-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/build-aux/depcomp b/build-aux/depcomp
new file mode 100755
index 0000000..4ebd5b3
--- /dev/null
+++ b/build-aux/depcomp
@@ -0,0 +1,791 @@
+#! /bin/sh
+# depcomp - compile a program generating dependencies as side-effects
+
+scriptversion=2013-05-30.07; # UTC
+
+# Copyright (C) 1999-2013 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, see <http://www.gnu.org/licenses/>.
+
+# 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'.
+  DEPDIR      directory where to store dependencies.
+  depfile     Dependency file to output.
+  tmpdepfile  Temporary file to use when outputting dependencies.
+  libtool     Whether libtool is used (yes/no).
+
+Report bugs to <bug-automake at gnu.org>.
+EOF
+    exit $?
+    ;;
+  -v | --v*)
+    echo "depcomp $scriptversion"
+    exit $?
+    ;;
+esac
+
+# Get the directory component of the given path, and save it in the
+# global variables '$dir'.  Note that this directory component will
+# be either empty or ending with a '/' character.  This is deliberate.
+set_dir_from ()
+{
+  case $1 in
+    */*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;;
+      *) dir=;;
+  esac
+}
+
+# Get the suffix-stripped basename of the given path, and save it the
+# global variable '$base'.
+set_base_from ()
+{
+  base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'`
+}
+
+# If no dependency file was actually created by the compiler invocation,
+# we still have to create a dummy depfile, to avoid errors with the
+# Makefile "include basename.Plo" scheme.
+make_dummy_depfile ()
+{
+  echo "#dummy" > "$depfile"
+}
+
+# Factor out some common post-processing of the generated depfile.
+# Requires the auxiliary global variable '$tmpdepfile' to be set.
+aix_post_process_depfile ()
+{
+  # If the compiler actually managed to produce a dependency file,
+  # post-process it.
+  if test -f "$tmpdepfile"; then
+    # Each line is of the form 'foo.o: dependency.h'.
+    # Do two passes, one to just change these to
+    #   $object: dependency.h
+    # and one to simply output
+    #   dependency.h:
+    # which is needed to avoid the deleted-header problem.
+    { sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile"
+      sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile"
+    } > "$depfile"
+    rm -f "$tmpdepfile"
+  else
+    make_dummy_depfile
+  fi
+}
+
+# A tabulation character.
+tab='	'
+# A newline character.
+nl='
+'
+# Character ranges might be problematic outside the C locale.
+# These definitions help.
+upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ
+lower=abcdefghijklmnopqrstuvwxyz
+digits=0123456789
+alpha=${upper}${lower}
+
+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
+
+# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
+depfile=${depfile-`echo "$object" |
+  sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
+tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
+
+rm -f "$tmpdepfile"
+
+# Avoid interferences from the environment.
+gccflag= dashmflag=
+
+# 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
+
+cygpath_u="cygpath -u -f -"
+if test "$depmode" = msvcmsys; then
+  # This is just like msvisualcpp but w/o cygpath translation.
+  # Just convert the backslash-escaped backslashes to single forward
+  # slashes to satisfy depend.m4
+  cygpath_u='sed s,\\\\,/,g'
+  depmode=msvisualcpp
+fi
+
+if test "$depmode" = msvc7msys; then
+  # This is just like msvc7 but w/o cygpath translation.
+  # Just convert the backslash-escaped backslashes to single forward
+  # slashes to satisfy depend.m4
+  cygpath_u='sed s,\\\\,/,g'
+  depmode=msvc7
+fi
+
+if test "$depmode" = xlc; then
+  # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information.
+  gccflag=-qmakedep=gcc,-MF
+  depmode=gcc
+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.
+## Unfortunately, FreeBSD c89 acceptance of flags depends upon
+## the command line argument order; so add the flags where they
+## appear in depend2.am.  Note that the slowdown incurred here
+## affects only configure: in makefiles, %FASTDEP% shortcuts this.
+  for arg
+  do
+    case $arg in
+    -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;;
+    *)  set fnord "$@" "$arg" ;;
+    esac
+    shift # fnord
+    shift # $arg
+  done
+  "$@"
+  stat=$?
+  if test $stat -ne 0; then
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  mv "$tmpdepfile" "$depfile"
+  ;;
+
+gcc)
+## Note that this doesn't just cater to obsosete pre-3.x GCC compilers.
+## but also to in-use compilers like IMB xlc/xlC and the HP C compiler.
+## (see the conditional assignment to $gccflag above).
+## 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).  Also, it might not be
+##   supported by the other compilers which use the 'gcc' depmode.
+## - 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 -ne 0; then
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  # 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.
+## 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.  hp depmode also adds that space, but also prefixes the VPATH
+## to the object.  Take care to not repeat it in the output.
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly.  Breaking it into two sed invocations is a workaround.
+  tr ' ' "$nl" < "$tmpdepfile" \
+    | sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -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 -ne 0; then
+    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 ' ' "$nl" < "$tmpdepfile" \
+      | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \
+      | tr "$nl" ' ' >> "$depfile"
+    echo >> "$depfile"
+    # The second pass generates a dummy entry for each header file.
+    tr ' ' "$nl" < "$tmpdepfile" \
+      | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
+      >> "$depfile"
+  else
+    make_dummy_depfile
+  fi
+  rm -f "$tmpdepfile"
+  ;;
+
+xlc)
+  # 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
+  ;;
+
+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.
+  set_dir_from "$object"
+  set_base_from "$object"
+  if test "$libtool" = yes; then
+    tmpdepfile1=$dir$base.u
+    tmpdepfile2=$base.u
+    tmpdepfile3=$dir.libs/$base.u
+    "$@" -Wc,-M
+  else
+    tmpdepfile1=$dir$base.u
+    tmpdepfile2=$dir$base.u
+    tmpdepfile3=$dir$base.u
+    "$@" -M
+  fi
+  stat=$?
+  if test $stat -ne 0; then
+    rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+    exit $stat
+  fi
+
+  for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+  do
+    test -f "$tmpdepfile" && break
+  done
+  aix_post_process_depfile
+  ;;
+
+tcc)
+  # tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26
+  # FIXME: That version still under development at the moment of writing.
+  #        Make that this statement remains true also for stable, released
+  #        versions.
+  # It will wrap lines (doesn't matter whether long or short) with a
+  # trailing '\', as in:
+  #
+  #   foo.o : \
+  #    foo.c \
+  #    foo.h \
+  #
+  # It will put a trailing '\' even on the last line, and will use leading
+  # spaces rather than leading tabs (at least since its commit 0394caf7
+  # "Emit spaces for -MD").
+  "$@" -MD -MF "$tmpdepfile"
+  stat=$?
+  if test $stat -ne 0; then
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+  # Each non-empty line is of the form 'foo.o : \' or ' dep.h \'.
+  # We have to change lines of the first kind to '$object: \'.
+  sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile"
+  # And for each line of the second kind, we have to emit a 'dep.h:'
+  # dummy dependency, to avoid the deleted-header problem.
+  sed -n -e 's|^  *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+## The order of this option in the case statement is important, since the
+## shell code in configure will try each of these formats in the order
+## listed in this file.  A plain '-MD' option would be understood by many
+## compilers, so we must ensure this comes after the gcc and icc options.
+pgcc)
+  # Portland's C compiler understands '-MD'.
+  # Will always output deps to 'file.d' where file is the root name of the
+  # source file under compilation, even if file resides in a subdirectory.
+  # The object file name does not affect the name of the '.d' file.
+  # pgcc 10.2 will output
+  #    foo.o: sub/foo.c sub/foo.h
+  # and will wrap long lines using '\' :
+  #    foo.o: sub/foo.c ... \
+  #     sub/foo.h ... \
+  #     ...
+  set_dir_from "$object"
+  # Use the source, not the object, to determine the base name, since
+  # that's sadly what pgcc will do too.
+  set_base_from "$source"
+  tmpdepfile=$base.d
+
+  # For projects that build the same source file twice into different object
+  # files, the pgcc approach of using the *source* file root name can cause
+  # problems in parallel builds.  Use a locking strategy to avoid stomping on
+  # the same $tmpdepfile.
+  lockdir=$base.d-lock
+  trap "
+    echo '$0: caught signal, cleaning up...' >&2
+    rmdir '$lockdir'
+    exit 1
+  " 1 2 13 15
+  numtries=100
+  i=$numtries
+  while test $i -gt 0; do
+    # mkdir is a portable test-and-set.
+    if mkdir "$lockdir" 2>/dev/null; then
+      # This process acquired the lock.
+      "$@" -MD
+      stat=$?
+      # Release the lock.
+      rmdir "$lockdir"
+      break
+    else
+      # If the lock is being held by a different process, wait
+      # until the winning process is done or we timeout.
+      while test -d "$lockdir" && test $i -gt 0; do
+        sleep 1
+        i=`expr $i - 1`
+      done
+    fi
+    i=`expr $i - 1`
+  done
+  trap - 1 2 13 15
+  if test $i -le 0; then
+    echo "$0: failed to acquire lock after $numtries attempts" >&2
+    echo "$0: check lockdir '$lockdir'" >&2
+    exit 1
+  fi
+
+  if test $stat -ne 0; then
+    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"
+  ;;
+
+hp2)
+  # The "hp" stanza above does not work with aCC (C++) and HP's ia64
+  # compilers, which have integrated preprocessors.  The correct option
+  # to use with these is +Maked; it writes dependencies to a file named
+  # 'foo.d', which lands next to the object file, wherever that
+  # happens to be.
+  # Much of this is similar to the tru64 case; see comments there.
+  set_dir_from  "$object"
+  set_base_from "$object"
+  if test "$libtool" = yes; then
+    tmpdepfile1=$dir$base.d
+    tmpdepfile2=$dir.libs/$base.d
+    "$@" -Wc,+Maked
+  else
+    tmpdepfile1=$dir$base.d
+    tmpdepfile2=$dir$base.d
+    "$@" +Maked
+  fi
+  stat=$?
+  if test $stat -ne 0; then
+     rm -f "$tmpdepfile1" "$tmpdepfile2"
+     exit $stat
+  fi
+
+  for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2"
+  do
+    test -f "$tmpdepfile" && break
+  done
+  if test -f "$tmpdepfile"; then
+    sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile"
+    # Add 'dependent.h:' lines.
+    sed -ne '2,${
+               s/^ *//
+               s/ \\*$//
+               s/$/:/
+               p
+             }' "$tmpdepfile" >> "$depfile"
+  else
+    make_dummy_depfile
+  fi
+  rm -f "$tmpdepfile" "$tmpdepfile2"
+  ;;
+
+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.
+  set_dir_from  "$object"
+  set_base_from "$object"
+
+  if test "$libtool" = yes; then
+    # Libtool generates 2 separate objects for the 2 libraries.  These
+    # two compilations output dependencies in $dir.libs/$base.o.d and
+    # in $dir$base.o.d.  We have to check for both files, because
+    # one of the two compilations can be disabled.  We should prefer
+    # $dir$base.o.d over $dir.libs/$base.o.d because the latter is
+    # automatically cleaned when .libs/ is deleted, while ignoring
+    # the former would cause a distcleancheck panic.
+    tmpdepfile1=$dir$base.o.d          # libtool 1.5
+    tmpdepfile2=$dir.libs/$base.o.d    # Likewise.
+    tmpdepfile3=$dir.libs/$base.d      # Compaq CCC V6.2-504
+    "$@" -Wc,-MD
+  else
+    tmpdepfile1=$dir$base.d
+    tmpdepfile2=$dir$base.d
+    tmpdepfile3=$dir$base.d
+    "$@" -MD
+  fi
+
+  stat=$?
+  if test $stat -ne 0; then
+    rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+    exit $stat
+  fi
+
+  for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+  do
+    test -f "$tmpdepfile" && break
+  done
+  # Same post-processing that is required for AIX mode.
+  aix_post_process_depfile
+  ;;
+
+msvc7)
+  if test "$libtool" = yes; then
+    showIncludes=-Wc,-showIncludes
+  else
+    showIncludes=-showIncludes
+  fi
+  "$@" $showIncludes > "$tmpdepfile"
+  stat=$?
+  grep -v '^Note: including file: ' "$tmpdepfile"
+  if test $stat -ne 0; then
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  # The first sed program below extracts the file names and escapes
+  # backslashes for cygpath.  The second sed program outputs the file
+  # name when reading, but also accumulates all include files in the
+  # hold buffer in order to output them again at the end.  This only
+  # works with sed implementations that can handle large buffers.
+  sed < "$tmpdepfile" -n '
+/^Note: including file:  *\(.*\)/ {
+  s//\1/
+  s/\\/\\\\/g
+  p
+}' | $cygpath_u | sort -u | sed -n '
+s/ /\\ /g
+s/\(.*\)/'"$tab"'\1 \\/p
+s/.\(.*\) \\/\1:/
+H
+$ {
+  s/.*/'"$tab"'/
+  G
+  p
+}' >> "$depfile"
+  echo >> "$depfile" # make sure the fragment doesn't end with a backslash
+  rm -f "$tmpdepfile"
+  ;;
+
+msvc7msys)
+  # 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
+  ;;
+
+#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 "X$1" != 'X--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|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile"
+  rm -f "$depfile"
+  cat < "$tmpdepfile" > "$depfile"
+  # Some versions of the HPUX 10.20 sed can't process this sed invocation
+  # correctly.  Breaking it into two sed invocations is a workaround.
+  tr ' ' "$nl" < "$tmpdepfile" \
+    | 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 "X$1" != 'X--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+  # X makedepend
+  shift
+  cleared=no eat=no
+  for arg
+  do
+    case $cleared in
+    no)
+      set ""; shift
+      cleared=yes ;;
+    esac
+    if test $eat = yes; then
+      eat=no
+      continue
+    fi
+    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.
+    -arch)
+      eat=yes ;;
+    -*|$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"
+  # makedepend may prepend the VPATH from the source file name to the object.
+  # No need to regex-escape $object, excess matching of '.' is harmless.
+  sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile"
+  # Some versions of the HPUX 10.20 sed can't process the last invocation
+  # correctly.  Breaking it into two sed invocations is a workaround.
+  sed '1,2d' "$tmpdepfile" \
+    | tr ' ' "$nl" \
+    | 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 "X$1" != 'X--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 -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
+             -e '/^#line [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.
+  "$@" || exit $?
+
+  # Remove the call to Libtool.
+  if test "$libtool" = yes; then
+    while test "X$1" != 'X--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+
+  IFS=" "
+  for arg
+  do
+    case "$arg" in
+    -o)
+      shift
+      ;;
+    $object)
+      shift
+      ;;
+    "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
+        set fnord "$@"
+        shift
+        shift
+        ;;
+    *)
+        set fnord "$@" "$arg"
+        shift
+        shift
+        ;;
+    esac
+  done
+  "$@" -E 2>/dev/null |
+  sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile"
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile"
+  echo "$tab" >> "$depfile"
+  sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+msvcmsys)
+  # 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
+  ;;
+
+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-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/build-aux/install-sh b/build-aux/install-sh
new file mode 100755
index 0000000..377bb86
--- /dev/null
+++ b/build-aux/install-sh
@@ -0,0 +1,527 @@
+#!/bin/sh
+# install - install a program, script, or datafile
+
+scriptversion=2011-11-20.07; # UTC
+
+# 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.
+
+nl='
+'
+IFS=" ""	$nl"
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit=${DOITPROG-}
+if test -z "$doit"; then
+  doit_exec=exec
+else
+  doit_exec=$doit
+fi
+
+# Put in absolute file names if you don't have them in your path;
+# or use environment vars.
+
+chgrpprog=${CHGRPPROG-chgrp}
+chmodprog=${CHMODPROG-chmod}
+chownprog=${CHOWNPROG-chown}
+cmpprog=${CMPPROG-cmp}
+cpprog=${CPPROG-cp}
+mkdirprog=${MKDIRPROG-mkdir}
+mvprog=${MVPROG-mv}
+rmprog=${RMPROG-rm}
+stripprog=${STRIPPROG-strip}
+
+posix_glob='?'
+initialize_posix_glob='
+  test "$posix_glob" != "?" || {
+    if (set -f) 2>/dev/null; then
+      posix_glob=
+    else
+      posix_glob=:
+    fi
+  }
+'
+
+posix_mkdir=
+
+# Desired mode of installed file.
+mode=0755
+
+chgrpcmd=
+chmodcmd=$chmodprog
+chowncmd=
+mvcmd=$mvprog
+rmcmd="$rmprog -f"
+stripcmd=
+
+src=
+dst=
+dir_arg=
+dst_arg=
+
+copy_on_change=false
+no_target_directory=
+
+usage="\
+Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
+   or: $0 [OPTION]... SRCFILES... DIRECTORY
+   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
+   or: $0 [OPTION]... -d DIRECTORIES...
+
+In the 1st form, copy SRCFILE to DSTFILE.
+In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
+In the 4th, create DIRECTORIES.
+
+Options:
+     --help     display this help and exit.
+     --version  display version info and exit.
+
+  -c            (ignored)
+  -C            install only if different (preserve the last data modification time)
+  -d            create directories instead of installing files.
+  -g GROUP      $chgrpprog installed files to GROUP.
+  -m MODE       $chmodprog installed files to MODE.
+  -o USER       $chownprog installed files to USER.
+  -s            $stripprog installed files.
+  -t DIRECTORY  install into DIRECTORY.
+  -T            report an error if DSTFILE is a directory.
+
+Environment variables override the default commands:
+  CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
+  RMPROG STRIPPROG
+"
+
+while test $# -ne 0; do
+  case $1 in
+    -c) ;;
+
+    -C) copy_on_change=true;;
+
+    -d) dir_arg=true;;
+
+    -g) chgrpcmd="$chgrpprog $2"
+	shift;;
+
+    --help) echo "$usage"; exit $?;;
+
+    -m) mode=$2
+	case $mode in
+	  *' '* | *'	'* | *'
+'*	  | *'*'* | *'?'* | *'['*)
+	    echo "$0: invalid mode: $mode" >&2
+	    exit 1;;
+	esac
+	shift;;
+
+    -o) chowncmd="$chownprog $2"
+	shift;;
+
+    -s) stripcmd=$stripprog;;
+
+    -t) dst_arg=$2
+	# Protect names problematic for 'test' and other utilities.
+	case $dst_arg in
+	  -* | [=\(\)!]) dst_arg=./$dst_arg;;
+	esac
+	shift;;
+
+    -T) no_target_directory=true;;
+
+    --version) echo "$0 $scriptversion"; exit $?;;
+
+    --)	shift
+	break;;
+
+    -*)	echo "$0: invalid option: $1" >&2
+	exit 1;;
+
+    *)  break;;
+  esac
+  shift
+done
+
+if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
+  # When -d is used, all remaining arguments are directories to create.
+  # When -t is used, the destination is already specified.
+  # Otherwise, the last argument is the destination.  Remove it from $@.
+  for arg
+  do
+    if test -n "$dst_arg"; then
+      # $@ is not empty: it contains at least $arg.
+      set fnord "$@" "$dst_arg"
+      shift # fnord
+    fi
+    shift # arg
+    dst_arg=$arg
+    # Protect names problematic for 'test' and other utilities.
+    case $dst_arg in
+      -* | [=\(\)!]) dst_arg=./$dst_arg;;
+    esac
+  done
+fi
+
+if test $# -eq 0; 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
+
+if test -z "$dir_arg"; then
+  do_exit='(exit $ret); exit $ret'
+  trap "ret=129; $do_exit" 1
+  trap "ret=130; $do_exit" 2
+  trap "ret=141; $do_exit" 13
+  trap "ret=143; $do_exit" 15
+
+  # Set umask so as not to create temps with too-generous modes.
+  # However, 'strip' requires both read and write access to temps.
+  case $mode in
+    # Optimize common cases.
+    *644) cp_umask=133;;
+    *755) cp_umask=22;;
+
+    *[0-7])
+      if test -z "$stripcmd"; then
+	u_plus_rw=
+      else
+	u_plus_rw='% 200'
+      fi
+      cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
+    *)
+      if test -z "$stripcmd"; then
+	u_plus_rw=
+      else
+	u_plus_rw=,u+rw
+      fi
+      cp_umask=$mode$u_plus_rw;;
+  esac
+fi
+
+for src
+do
+  # Protect names problematic for 'test' and other utilities.
+  case $src in
+    -* | [=\(\)!]) src=./$src;;
+  esac
+
+  if test -n "$dir_arg"; then
+    dst=$src
+    dstdir=$dst
+    test -d "$dstdir"
+    dstdir_status=$?
+  else
+
+    # Waiting for this to be detected by the "$cpprog $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 "$dst_arg"; then
+      echo "$0: no destination specified." >&2
+      exit 1
+    fi
+    dst=$dst_arg
+
+    # If destination is a directory, append the input filename; won't work
+    # if double slashes aren't ignored.
+    if test -d "$dst"; then
+      if test -n "$no_target_directory"; then
+	echo "$0: $dst_arg: Is a directory" >&2
+	exit 1
+      fi
+      dstdir=$dst
+      dst=$dstdir/`basename "$src"`
+      dstdir_status=0
+    else
+      # Prefer dirname, but fall back on a substitute if dirname fails.
+      dstdir=`
+	(dirname "$dst") 2>/dev/null ||
+	expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	     X"$dst" : 'X\(//\)[^/]' \| \
+	     X"$dst" : 'X\(//\)$' \| \
+	     X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
+	echo X"$dst" |
+	    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+		   s//\1/
+		   q
+		 }
+		 /^X\(\/\/\)[^/].*/{
+		   s//\1/
+		   q
+		 }
+		 /^X\(\/\/\)$/{
+		   s//\1/
+		   q
+		 }
+		 /^X\(\/\).*/{
+		   s//\1/
+		   q
+		 }
+		 s/.*/./; q'
+      `
+
+      test -d "$dstdir"
+      dstdir_status=$?
+    fi
+  fi
+
+  obsolete_mkdir_used=false
+
+  if test $dstdir_status != 0; then
+    case $posix_mkdir in
+      '')
+	# Create intermediate dirs using mode 755 as modified by the umask.
+	# This is like FreeBSD 'install' as of 1997-10-28.
+	umask=`umask`
+	case $stripcmd.$umask in
+	  # Optimize common cases.
+	  *[2367][2367]) mkdir_umask=$umask;;
+	  .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
+
+	  *[0-7])
+	    mkdir_umask=`expr $umask + 22 \
+	      - $umask % 100 % 40 + $umask % 20 \
+	      - $umask % 10 % 4 + $umask % 2
+	    `;;
+	  *) mkdir_umask=$umask,go-w;;
+	esac
+
+	# With -d, create the new directory with the user-specified mode.
+	# Otherwise, rely on $mkdir_umask.
+	if test -n "$dir_arg"; then
+	  mkdir_mode=-m$mode
+	else
+	  mkdir_mode=
+	fi
+
+	posix_mkdir=false
+	case $umask in
+	  *[123567][0-7][0-7])
+	    # POSIX mkdir -p sets u+wx bits regardless of umask, which
+	    # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
+	    ;;
+	  *)
+	    tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
+	    trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
+
+	    if (umask $mkdir_umask &&
+		exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
+	    then
+	      if test -z "$dir_arg" || {
+		   # Check for POSIX incompatibilities with -m.
+		   # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
+		   # other-writable bit of parent directory when it shouldn't.
+		   # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
+		   ls_ld_tmpdir=`ls -ld "$tmpdir"`
+		   case $ls_ld_tmpdir in
+		     d????-?r-*) different_mode=700;;
+		     d????-?--*) different_mode=755;;
+		     *) false;;
+		   esac &&
+		   $mkdirprog -m$different_mode -p -- "$tmpdir" && {
+		     ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
+		     test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
+		   }
+		 }
+	      then posix_mkdir=:
+	      fi
+	      rmdir "$tmpdir/d" "$tmpdir"
+	    else
+	      # Remove any dirs left behind by ancient mkdir implementations.
+	      rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
+	    fi
+	    trap '' 0;;
+	esac;;
+    esac
+
+    if
+      $posix_mkdir && (
+	umask $mkdir_umask &&
+	$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
+      )
+    then :
+    else
+
+      # The umask is ridiculous, or mkdir does not conform to POSIX,
+      # or it failed possibly due to a race condition.  Create the
+      # directory the slow way, step by step, checking for races as we go.
+
+      case $dstdir in
+	/*) prefix='/';;
+	[-=\(\)!]*) prefix='./';;
+	*)  prefix='';;
+      esac
+
+      eval "$initialize_posix_glob"
+
+      oIFS=$IFS
+      IFS=/
+      $posix_glob set -f
+      set fnord $dstdir
+      shift
+      $posix_glob set +f
+      IFS=$oIFS
+
+      prefixes=
+
+      for d
+      do
+	test X"$d" = X && continue
+
+	prefix=$prefix$d
+	if test -d "$prefix"; then
+	  prefixes=
+	else
+	  if $posix_mkdir; then
+	    (umask=$mkdir_umask &&
+	     $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
+	    # Don't fail if two instances are running concurrently.
+	    test -d "$prefix" || exit 1
+	  else
+	    case $prefix in
+	      *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
+	      *) qprefix=$prefix;;
+	    esac
+	    prefixes="$prefixes '$qprefix'"
+	  fi
+	fi
+	prefix=$prefix/
+      done
+
+      if test -n "$prefixes"; then
+	# Don't fail if two instances are running concurrently.
+	(umask $mkdir_umask &&
+	 eval "\$doit_exec \$mkdirprog $prefixes") ||
+	  test -d "$dstdir" || exit 1
+	obsolete_mkdir_used=true
+      fi
+    fi
+  fi
+
+  if test -n "$dir_arg"; then
+    { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
+    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
+    { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
+      test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
+  else
+
+    # 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 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
+
+    # Copy the file name to the temp name.
+    (umask $cp_umask && $doit_exec $cpprog "$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 $cpprog $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 $mode "$dsttmp"; } &&
+
+    # If -C, don't bother to copy if it wouldn't change the file.
+    if $copy_on_change &&
+       old=`LC_ALL=C ls -dlL "$dst"	2>/dev/null` &&
+       new=`LC_ALL=C ls -dlL "$dsttmp"	2>/dev/null` &&
+
+       eval "$initialize_posix_glob" &&
+       $posix_glob set -f &&
+       set X $old && old=:$2:$4:$5:$6 &&
+       set X $new && new=:$2:$4:$5:$6 &&
+       $posix_glob set +f &&
+
+       test "$old" = "$new" &&
+       $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
+    then
+      rm -f "$dsttmp"
+    else
+      # Rename the file to the real destination.
+      $doit $mvcmd -f "$dsttmp" "$dst" 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.
+	{
+	  test ! -f "$dst" ||
+	  $doit $rmcmd -f "$dst" 2>/dev/null ||
+	  { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
+	    { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
+	  } ||
+	  { echo "$0: cannot unlink or rename $dst" >&2
+	    (exit 1); exit 1
+	  }
+	} &&
+
+	# Now rename the file to the real destination.
+	$doit $mvcmd "$dsttmp" "$dst"
+      }
+    fi || exit 1
+
+    trap '' 0
+  fi
+done
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/build-aux/ltmain.sh b/build-aux/ltmain.sh
new file mode 100644
index 0000000..63ae69d
--- /dev/null
+++ b/build-aux/ltmain.sh
@@ -0,0 +1,9655 @@
+
+# libtool (GNU libtool) 2.4.2
+# Written by Gordon Matzigkeit <gord at gnu.ai.mit.edu>, 1996
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006,
+# 2007, 2008, 2009, 2010, 2011 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.
+
+# 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.
+
+# Usage: $progname [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
+#       --mode=MODE          use operation mode MODE
+#       --preserve-dup-deps  don't remove duplicate dependency libraries
+#       --quiet, --silent    don't print informational messages
+#       --no-quiet, --no-silent
+#                            print informational messages (default)
+#       --no-warn            don't display warning messages
+#       --tag=TAG            use configuration variables from tag TAG
+#   -v, --verbose            print more informational messages than default
+#       --no-verbose         don't print the extra informational messages
+#       --version            print version information
+#   -h, --help, --help-all   print short, long, or detailed help message
+#
+# 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.  When passed as first option,
+# `--mode=MODE' may be abbreviated as `MODE' or a unique abbreviation of that.
+# Try `$progname --help --mode=MODE' for a more detailed description of MODE.
+#
+# When reporting a bug, please describe a test case to reproduce it and
+# include the following information:
+#
+#         host-triplet:	$host
+#         shell:		$SHELL
+#         compiler:		$LTCC
+#         compiler flags:		$LTCFLAGS
+#         linker:		$LD (gnu? $with_gnu_ld)
+#         $progname:	(GNU libtool) 2.4.2
+#         automake:	$automake_version
+#         autoconf:	$autoconf_version
+#
+# Report bugs to <bug-libtool at gnu.org>.
+# GNU libtool home page: <http://www.gnu.org/software/libtool/>.
+# General help using GNU software: <http://www.gnu.org/gethelp/>.
+
+PROGRAM=libtool
+PACKAGE=libtool
+VERSION=2.4.2
+TIMESTAMP=""
+package_revision=1.3337
+
+# Be 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
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+  eval 'cat <<_LTECHO_EOF
+$1
+_LTECHO_EOF'
+}
+
+# NLS nuisances: We save the old values to restore during execute mode.
+lt_user_locale=
+lt_safe_locale=
+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_var=C
+	  export $lt_var
+	  lt_user_locale=\"$lt_var=\\\$save_\$lt_var; \$lt_user_locale\"
+	  lt_safe_locale=\"$lt_var=C; \$lt_safe_locale\"
+	fi"
+done
+LC_ALL=C
+LANGUAGE=C
+export LANGUAGE LC_ALL
+
+$lt_unset CDPATH
+
+
+# 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"
+
+
+
+: ${CP="cp -f"}
+test "${ECHO+set}" = set || ECHO=${as_echo-'printf %s\n'}
+: ${MAKE="make"}
+: ${MKDIR="mkdir"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+: ${SHELL="${CONFIG_SHELL-/bin/sh}"}
+: ${Xsed="$SED -e 1s/^X//"}
+
+# Global variables:
+EXIT_SUCCESS=0
+EXIT_FAILURE=1
+EXIT_MISMATCH=63  # $? = 63 is used to indicate version mismatch to missing.
+EXIT_SKIP=77	  # $? = 77 is used to indicate a skipped test to automake.
+
+exit_status=$EXIT_SUCCESS
+
+# Make sure IFS has a sensible default
+lt_nl='
+'
+IFS=" 	$lt_nl"
+
+dirname="s,/[^/]*$,,"
+basename="s,^.*/,,"
+
+# 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 ()
+{
+    func_dirname_result=`$ECHO "${1}" | $SED "$dirname"`
+    if test "X$func_dirname_result" = "X${1}"; then
+      func_dirname_result="${3}"
+    else
+      func_dirname_result="$func_dirname_result${2}"
+    fi
+} # func_dirname may be replaced by extended shell implementation
+
+
+# func_basename file
+func_basename ()
+{
+    func_basename_result=`$ECHO "${1}" | $SED "$basename"`
+} # func_basename may be replaced by extended shell implementation
+
+
+# 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 ()
+{
+    # Extract subdirectory from the argument.
+    func_dirname_result=`$ECHO "${1}" | $SED -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_result=`$ECHO "${1}" | $SED -e "$basename"`
+} # func_dirname_and_basename may be replaced by extended shell implementation
+
+
+# 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 "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;;
+      *)  func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;;
+    esac
+} # func_stripname may be replaced by extended shell implementation
+
+
+# These SED scripts presuppose an absolute path with a trailing slash.
+pathcar='s,^/\([^/]*\).*$,\1,'
+pathcdr='s,^/[^/]*,,'
+removedotparts=':dotsl
+		s@/\./@/@g
+		t dotsl
+		s,/\.$,/,'
+collapseslashes='s@/\{1,\}@/@g'
+finalslash='s,/*$,/,'
+
+# func_normal_abspath PATH
+# Remove doubled-up and trailing slashes, "." path components,
+# and cancel out any ".." path components in PATH after making
+# it an absolute path.
+#             value returned in "$func_normal_abspath_result"
+func_normal_abspath ()
+{
+  # Start from root dir and reassemble the path.
+  func_normal_abspath_result=
+  func_normal_abspath_tpath=$1
+  func_normal_abspath_altnamespace=
+  case $func_normal_abspath_tpath in
+    "")
+      # Empty path, that just means $cwd.
+      func_stripname '' '/' "`pwd`"
+      func_normal_abspath_result=$func_stripname_result
+      return
+    ;;
+    # The next three entries are used to spot a run of precisely
+    # two leading slashes without using negated character classes;
+    # we take advantage of case's first-match behaviour.
+    ///*)
+      # Unusual form of absolute path, do nothing.
+    ;;
+    //*)
+      # Not necessarily an ordinary path; POSIX reserves leading '//'
+      # and for example Cygwin uses it to access remote file shares
+      # over CIFS/SMB, so we conserve a leading double slash if found.
+      func_normal_abspath_altnamespace=/
+    ;;
+    /*)
+      # Absolute path, do nothing.
+    ;;
+    *)
+      # Relative path, prepend $cwd.
+      func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath
+    ;;
+  esac
+  # Cancel out all the simple stuff to save iterations.  We also want
+  # the path to end with a slash for ease of parsing, so make sure
+  # there is one (and only one) here.
+  func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \
+        -e "$removedotparts" -e "$collapseslashes" -e "$finalslash"`
+  while :; do
+    # Processed it all yet?
+    if test "$func_normal_abspath_tpath" = / ; then
+      # If we ascended to the root using ".." the result may be empty now.
+      if test -z "$func_normal_abspath_result" ; then
+        func_normal_abspath_result=/
+      fi
+      break
+    fi
+    func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \
+        -e "$pathcar"`
+    func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \
+        -e "$pathcdr"`
+    # Figure out what to do with it
+    case $func_normal_abspath_tcomponent in
+      "")
+        # Trailing empty path component, ignore it.
+      ;;
+      ..)
+        # Parent dir; strip last assembled component from result.
+        func_dirname "$func_normal_abspath_result"
+        func_normal_abspath_result=$func_dirname_result
+      ;;
+      *)
+        # Actual path component, append it.
+        func_normal_abspath_result=$func_normal_abspath_result/$func_normal_abspath_tcomponent
+      ;;
+    esac
+  done
+  # Restore leading double-slash if one was found on entry.
+  func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result
+}
+
+# func_relative_path SRCDIR DSTDIR
+# generates a relative path from SRCDIR to DSTDIR, with a trailing
+# slash if non-empty, suitable for immediately appending a filename
+# without needing to append a separator.
+#             value returned in "$func_relative_path_result"
+func_relative_path ()
+{
+  func_relative_path_result=
+  func_normal_abspath "$1"
+  func_relative_path_tlibdir=$func_normal_abspath_result
+  func_normal_abspath "$2"
+  func_relative_path_tbindir=$func_normal_abspath_result
+
+  # Ascend the tree starting from libdir
+  while :; do
+    # check if we have found a prefix of bindir
+    case $func_relative_path_tbindir in
+      $func_relative_path_tlibdir)
+        # found an exact match
+        func_relative_path_tcancelled=
+        break
+        ;;
+      $func_relative_path_tlibdir*)
+        # found a matching prefix
+        func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir"
+        func_relative_path_tcancelled=$func_stripname_result
+        if test -z "$func_relative_path_result"; then
+          func_relative_path_result=.
+        fi
+        break
+        ;;
+      *)
+        func_dirname $func_relative_path_tlibdir
+        func_relative_path_tlibdir=${func_dirname_result}
+        if test "x$func_relative_path_tlibdir" = x ; then
+          # Have to descend all the way to the root!
+          func_relative_path_result=../$func_relative_path_result
+          func_relative_path_tcancelled=$func_relative_path_tbindir
+          break
+        fi
+        func_relative_path_result=../$func_relative_path_result
+        ;;
+    esac
+  done
+
+  # Now calculate path; take care to avoid doubling-up slashes.
+  func_stripname '' '/' "$func_relative_path_result"
+  func_relative_path_result=$func_stripname_result
+  func_stripname '/' '/' "$func_relative_path_tcancelled"
+  if test "x$func_stripname_result" != x ; then
+    func_relative_path_result=${func_relative_path_result}/${func_stripname_result}
+  fi
+
+  # Normalisation. If bindir is libdir, return empty string,
+  # else relative path ending with a slash; either way, target
+  # file name can be directly appended.
+  if test ! -z "$func_relative_path_result"; then
+    func_stripname './' '' "$func_relative_path_result/"
+    func_relative_path_result=$func_stripname_result
+  fi
+}
+
+# The name of this program:
+func_dirname_and_basename "$progpath"
+progname=$func_basename_result
+
+# Make sure we have an absolute path for reexecution:
+case $progpath in
+  [\\/]*|[A-Za-z]:\\*) ;;
+  *[\\/]*)
+     progdir=$func_dirname_result
+     progdir=`cd "$progdir" && pwd`
+     progpath="$progdir/$progname"
+     ;;
+  *)
+     save_IFS="$IFS"
+     IFS=${PATH_SEPARATOR-:}
+     for progdir in $PATH; do
+       IFS="$save_IFS"
+       test -x "$progdir/$progname" && break
+     done
+     IFS="$save_IFS"
+     test -n "$progdir" || progdir=`pwd`
+     progpath="$progdir/$progname"
+     ;;
+esac
+
+# 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'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\(["`\\]\)/\\\1/g'
+
+# Sed substitution that turns a string into a regex matching for the
+# string literally.
+sed_make_literal_regex='s,[].[^$\\*\/],\\&,g'
+
+# Sed substitution that converts a w32 file name or path
+# which contains forward slashes, into one that contains
+# (escaped) backslashes.  A very naive implementation.
+lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g'
+
+# Re-`\' parameter expansions in output of double_quote_subst that were
+# `\'-ed in input to the same.  If an odd number of `\' preceded a '$'
+# in input to double_quote_subst, that '$' was protected from expansion.
+# Since each input `\' is now two `\'s, look for any number of runs of
+# four `\'s followed by two `\'s and then a '$'.  `\' that '$'.
+bs='\\'
+bs2='\\\\'
+bs4='\\\\\\\\'
+dollar='\$'
+sed_double_backslash="\
+  s/$bs4/&\\
+/g
+  s/^$bs2$dollar/$bs&/
+  s/\\([^$bs]\\)$bs2$dollar/\\1$bs2$bs$dollar/g
+  s/\n//g"
+
+# Standard options:
+opt_dry_run=false
+opt_help=false
+opt_quiet=false
+opt_verbose=false
+opt_warning=:
+
+# func_echo arg...
+# Echo program name prefixed message, along with the current mode
+# name if it has been set yet.
+func_echo ()
+{
+    $ECHO "$progname: ${opt_mode+$opt_mode: }$*"
+}
+
+# func_verbose arg...
+# Echo program name prefixed message in verbose mode only.
+func_verbose ()
+{
+    $opt_verbose && func_echo ${1+"$@"}
+
+    # A bug in bash halts the script if the last line of a function
+    # fails when set -e is in force, so we need another command to
+    # work around that:
+    :
+}
+
+# func_echo_all arg...
+# Invoke $ECHO with all args, space-separated.
+func_echo_all ()
+{
+    $ECHO "$*"
+}
+
+# func_error arg...
+# Echo program name prefixed message to standard error.
+func_error ()
+{
+    $ECHO "$progname: ${opt_mode+$opt_mode: }"${1+"$@"} 1>&2
+}
+
+# func_warning arg...
+# Echo program name prefixed warning message to standard error.
+func_warning ()
+{
+    $opt_warning && $ECHO "$progname: ${opt_mode+$opt_mode: }warning: "${1+"$@"} 1>&2
+
+    # bash bug again:
+    :
+}
+
+# func_fatal_error arg...
+# Echo program name prefixed message to standard error, and exit.
+func_fatal_error ()
+{
+    func_error ${1+"$@"}
+    exit $EXIT_FAILURE
+}
+
+# func_fatal_help arg...
+# Echo program name prefixed message to standard error, followed by
+# a help hint, and exit.
+func_fatal_help ()
+{
+    func_error ${1+"$@"}
+    func_fatal_error "$help"
+}
+help="Try \`$progname --help' for more information."  ## default
+
+
+# func_grep expression filename
+# Check whether EXPRESSION matches any line of FILENAME, without output.
+func_grep ()
+{
+    $GREP "$1" "$2" >/dev/null 2>&1
+}
+
+
+# func_mkdir_p directory-path
+# Make sure the entire path to DIRECTORY-PATH is available.
+func_mkdir_p ()
+{
+    my_directory_path="$1"
+    my_dir_list=
+
+    if test -n "$my_directory_path" && test "$opt_dry_run" != ":"; then
+
+      # Protect directory names starting with `-'
+      case $my_directory_path in
+        -*) my_directory_path="./$my_directory_path" ;;
+      esac
+
+      # While some portion of DIR does not yet exist...
+      while test ! -d "$my_directory_path"; do
+        # ...make a list in topmost first order.  Use a colon delimited
+	# list incase some portion of path contains whitespace.
+        my_dir_list="$my_directory_path:$my_dir_list"
+
+        # If the last portion added has no slash in it, the list is done
+        case $my_directory_path in */*) ;; *) break ;; esac
+
+        # ...otherwise throw away the child directory and loop
+        my_directory_path=`$ECHO "$my_directory_path" | $SED -e "$dirname"`
+      done
+      my_dir_list=`$ECHO "$my_dir_list" | $SED 's,:*$,,'`
+
+      save_mkdir_p_IFS="$IFS"; IFS=':'
+      for my_dir in $my_dir_list; do
+	IFS="$save_mkdir_p_IFS"
+        # mkdir can fail with a `File exist' error if two processes
+        # try to create one of the directories concurrently.  Don't
+        # stop in that case!
+        $MKDIR "$my_dir" 2>/dev/null || :
+      done
+      IFS="$save_mkdir_p_IFS"
+
+      # Bail out if we (or some other process) failed to create a directory.
+      test -d "$my_directory_path" || \
+        func_fatal_error "Failed to create \`$1'"
+    fi
+}
+
+
+# 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 "$opt_dry_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" || \
+        func_fatal_error "cannot create temporary directory \`$my_tmpdir'"
+    fi
+
+    $ECHO "$my_tmpdir"
+}
+
+
+# func_quote_for_eval arg
+# Aesthetically quote ARG to be evaled later.
+# This function returns two values: FUNC_QUOTE_FOR_EVAL_RESULT
+# is double-quoted, suitable for a subsequent eval, whereas
+# FUNC_QUOTE_FOR_EVAL_UNQUOTED_RESULT has merely all characters
+# which are still active within double quotes backslashified.
+func_quote_for_eval ()
+{
+    case $1 in
+      *[\\\`\"\$]*)
+	func_quote_for_eval_unquoted_result=`$ECHO "$1" | $SED "$sed_quote_subst"` ;;
+      *)
+        func_quote_for_eval_unquoted_result="$1" ;;
+    esac
+
+    case $func_quote_for_eval_unquoted_result in
+      # Double-quote args containing shell metacharacters to delay
+      # word splitting, command substitution and and variable
+      # expansion for a subsequent eval.
+      # Many Bourne shells cannot handle close brackets correctly
+      # in scan sets, so we specify it separately.
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+        func_quote_for_eval_result="\"$func_quote_for_eval_unquoted_result\""
+        ;;
+      *)
+        func_quote_for_eval_result="$func_quote_for_eval_unquoted_result"
+    esac
+}
+
+
+# func_quote_for_expand arg
+# Aesthetically quote ARG to be evaled later; same as above,
+# but do not quote variable references.
+func_quote_for_expand ()
+{
+    case $1 in
+      *[\\\`\"]*)
+	my_arg=`$ECHO "$1" | $SED \
+	    -e "$double_quote_subst" -e "$sed_double_backslash"` ;;
+      *)
+        my_arg="$1" ;;
+    esac
+
+    case $my_arg in
+      # Double-quote args containing shell metacharacters to delay
+      # word splitting and command substitution for a subsequent eval.
+      # Many Bourne shells cannot handle close brackets correctly
+      # in scan sets, so we specify it separately.
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+        my_arg="\"$my_arg\""
+        ;;
+    esac
+
+    func_quote_for_expand_result="$my_arg"
+}
+
+
+# func_show_eval cmd [fail_exp]
+# Unless opt_silent is true, then output CMD.  Then, if opt_dryrun is
+# not true, evaluate CMD.  If the evaluation of CMD fails, and FAIL_EXP
+# is given, then evaluate it.
+func_show_eval ()
+{
+    my_cmd="$1"
+    my_fail_exp="${2-:}"
+
+    ${opt_silent-false} || {
+      func_quote_for_expand "$my_cmd"
+      eval "func_echo $func_quote_for_expand_result"
+    }
+
+    if ${opt_dry_run-false}; then :; else
+      eval "$my_cmd"
+      my_status=$?
+      if test "$my_status" -eq 0; then :; else
+	eval "(exit $my_status); $my_fail_exp"
+      fi
+    fi
+}
+
+
+# func_show_eval_locale cmd [fail_exp]
+# Unless opt_silent is true, then output CMD.  Then, if opt_dryrun is
+# not true, evaluate CMD.  If the evaluation of CMD fails, and FAIL_EXP
+# is given, then evaluate it.  Use the saved locale for evaluation.
+func_show_eval_locale ()
+{
+    my_cmd="$1"
+    my_fail_exp="${2-:}"
+
+    ${opt_silent-false} || {
+      func_quote_for_expand "$my_cmd"
+      eval "func_echo $func_quote_for_expand_result"
+    }
+
+    if ${opt_dry_run-false}; then :; else
+      eval "$lt_user_locale
+	    $my_cmd"
+      my_status=$?
+      eval "$lt_safe_locale"
+      if test "$my_status" -eq 0; then :; else
+	eval "(exit $my_status); $my_fail_exp"
+      fi
+    fi
+}
+
+# func_tr_sh
+# Turn $1 into a string suitable for a shell variable name.
+# Result is stored in $func_tr_sh_result.  All characters
+# not in the set a-zA-Z0-9_ are replaced with '_'. Further,
+# if $1 begins with a digit, a '_' is prepended as well.
+func_tr_sh ()
+{
+  case $1 in
+  [0-9]* | *[!a-zA-Z0-9_]*)
+    func_tr_sh_result=`$ECHO "$1" | $SED 's/^\([0-9]\)/_\1/; s/[^a-zA-Z0-9_]/_/g'`
+    ;;
+  * )
+    func_tr_sh_result=$1
+    ;;
+  esac
+}
+
+
+# func_version
+# Echo version message to standard output and exit.
+func_version ()
+{
+    $opt_debug
+
+    $SED -n '/(C)/!b go
+	:more
+	/\./!{
+	  N
+	  s/\n# / /
+	  b more
+	}
+	:go
+	/^# '$PROGRAM' (GNU /,/# warranty; / {
+        s/^# //
+	s/^# *$//
+        s/\((C)\)[ 0-9,-]*\( [1-9][0-9]*\)/\1\2/
+        p
+     }' < "$progpath"
+     exit $?
+}
+
+# func_usage
+# Echo short help message to standard output and exit.
+func_usage ()
+{
+    $opt_debug
+
+    $SED -n '/^# Usage:/,/^#  *.*--help/ {
+        s/^# //
+	s/^# *$//
+	s/\$progname/'$progname'/
+	p
+    }' < "$progpath"
+    echo
+    $ECHO "run \`$progname --help | more' for full usage"
+    exit $?
+}
+
+# func_help [NOEXIT]
+# Echo long help message to standard output and exit,
+# unless 'noexit' is passed as argument.
+func_help ()
+{
+    $opt_debug
+
+    $SED -n '/^# Usage:/,/# Report bugs to/ {
+	:print
+        s/^# //
+	s/^# *$//
+	s*\$progname*'$progname'*
+	s*\$host*'"$host"'*
+	s*\$SHELL*'"$SHELL"'*
+	s*\$LTCC*'"$LTCC"'*
+	s*\$LTCFLAGS*'"$LTCFLAGS"'*
+	s*\$LD*'"$LD"'*
+	s/\$with_gnu_ld/'"$with_gnu_ld"'/
+	s/\$automake_version/'"`(${AUTOMAKE-automake} --version) 2>/dev/null |$SED 1q`"'/
+	s/\$autoconf_version/'"`(${AUTOCONF-autoconf} --version) 2>/dev/null |$SED 1q`"'/
+	p
+	d
+     }
+     /^# .* home page:/b print
+     /^# General help using/b print
+     ' < "$progpath"
+    ret=$?
+    if test -z "$1"; then
+      exit $ret
+    fi
+}
+
+# func_missing_arg argname
+# Echo program name prefixed message to standard error and set global
+# exit_cmd.
+func_missing_arg ()
+{
+    $opt_debug
+
+    func_error "missing argument for $1."
+    exit_cmd=exit
+}
+
+
+# func_split_short_opt shortopt
+# Set func_split_short_opt_name and func_split_short_opt_arg shell
+# variables after splitting SHORTOPT after the 2nd character.
+func_split_short_opt ()
+{
+    my_sed_short_opt='1s/^\(..\).*$/\1/;q'
+    my_sed_short_rest='1s/^..\(.*\)$/\1/;q'
+
+    func_split_short_opt_name=`$ECHO "$1" | $SED "$my_sed_short_opt"`
+    func_split_short_opt_arg=`$ECHO "$1" | $SED "$my_sed_short_rest"`
+} # func_split_short_opt may be replaced by extended shell implementation
+
+
+# func_split_long_opt longopt
+# Set func_split_long_opt_name and func_split_long_opt_arg shell
+# variables after splitting LONGOPT at the `=' sign.
+func_split_long_opt ()
+{
+    my_sed_long_opt='1s/^\(--[^=]*\)=.*/\1/;q'
+    my_sed_long_arg='1s/^--[^=]*=//'
+
+    func_split_long_opt_name=`$ECHO "$1" | $SED "$my_sed_long_opt"`
+    func_split_long_opt_arg=`$ECHO "$1" | $SED "$my_sed_long_arg"`
+} # func_split_long_opt may be replaced by extended shell implementation
+
+exit_cmd=:
+
+
+
+
+
+magic="%%%MAGIC variable%%%"
+magic_exe="%%%MAGIC EXE variable%%%"
+
+# Global variables.
+nonopt=
+preserve_args=
+lo2o="s/\\.lo\$/.${objext}/"
+o2lo="s/\\.${objext}\$/.lo/"
+extracted_archives=
+extracted_serial=0
+
+# 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=
+
+# func_append var value
+# Append VALUE to the end of shell variable VAR.
+func_append ()
+{
+    eval "${1}=\$${1}\${2}"
+} # func_append may be replaced by extended shell implementation
+
+# func_append_quoted var value
+# Quote VALUE and append to the end of shell variable VAR, separated
+# by a space.
+func_append_quoted ()
+{
+    func_quote_for_eval "${2}"
+    eval "${1}=\$${1}\\ \$func_quote_for_eval_result"
+} # func_append_quoted may be replaced by extended shell implementation
+
+
+# func_arith arithmetic-term...
+func_arith ()
+{
+    func_arith_result=`expr "${@}"`
+} # func_arith may be replaced by extended shell implementation
+
+
+# func_len string
+# STRING may not start with a hyphen.
+func_len ()
+{
+    func_len_result=`expr "${1}" : ".*" 2>/dev/null || echo $max_cmd_len`
+} # func_len may be replaced by extended shell implementation
+
+
+# func_lo2o object
+func_lo2o ()
+{
+    func_lo2o_result=`$ECHO "${1}" | $SED "$lo2o"`
+} # func_lo2o may be replaced by extended shell implementation
+
+
+# func_xform libobj-or-source
+func_xform ()
+{
+    func_xform_result=`$ECHO "${1}" | $SED 's/\.[^.]*$/.lo/'`
+} # func_xform may be replaced by extended shell implementation
+
+
+# func_fatal_configuration arg...
+# Echo program name prefixed message to standard error, followed by
+# a configuration failure hint, and exit.
+func_fatal_configuration ()
+{
+    func_error ${1+"$@"}
+    func_error "See the $PACKAGE documentation for more information."
+    func_fatal_error "Fatal configuration error."
+}
+
+
+# func_config
+# Display the configuration for all the tags in this script.
+func_config ()
+{
+    re_begincf='^# ### BEGIN LIBTOOL'
+    re_endcf='^# ### END LIBTOOL'
+
+    # Default configuration.
+    $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath"
+
+    # Now print the configurations for the tags.
+    for tagname in $taglist; do
+      $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath"
+    done
+
+    exit $?
+}
+
+# func_features
+# Display the features supported by this script.
+func_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 $?
+}
+
+# func_enable_tag tagname
+# Verify that TAGNAME is valid, and either flag an error and exit, or
+# enable the TAGNAME tag.  We also add TAGNAME to the global $taglist
+# variable here.
+func_enable_tag ()
+{
+  # Global variable:
+  tagname="$1"
+
+  re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$"
+  re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$"
+  sed_extractcf="/$re_begincf/,/$re_endcf/p"
+
+  # Validate tagname.
+  case $tagname in
+    *[!-_A-Za-z0-9,/]*)
+      func_fatal_error "invalid tag name: $tagname"
+      ;;
+  esac
+
+  # Don't test for the "default" C tag, as we know it's
+  # there but not specially marked.
+  case $tagname in
+    CC) ;;
+    *)
+      if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then
+	taglist="$taglist $tagname"
+
+	# Evaluate the configuration.  Be careful to quote the path
+	# and the sed script, to avoid splitting on whitespace, but
+	# also don't use non-portable quotes within backquotes within
+	# quotes we have to do it in 2 steps:
+	extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"`
+	eval "$extractedcf"
+      else
+	func_error "ignoring unknown tag $tagname"
+      fi
+      ;;
+  esac
+}
+
+# func_check_version_match
+# Ensure that we are using m4 macros, and libtool script from the same
+# release of libtool.
+func_check_version_match ()
+{
+  if test "$package_revision" != "$macro_revision"; then
+    if test "$VERSION" != "$macro_version"; then
+      if test -z "$macro_version"; then
+        cat >&2 <<_LT_EOF
+$progname: Version mismatch error.  This is $PACKAGE $VERSION, but the
+$progname: definition of this LT_INIT comes from an older release.
+$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
+$progname: and run autoconf again.
+_LT_EOF
+      else
+        cat >&2 <<_LT_EOF
+$progname: Version mismatch error.  This is $PACKAGE $VERSION, but the
+$progname: definition of this LT_INIT comes from $PACKAGE $macro_version.
+$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
+$progname: and run autoconf again.
+_LT_EOF
+      fi
+    else
+      cat >&2 <<_LT_EOF
+$progname: Version mismatch error.  This is $PACKAGE $VERSION, revision $package_revision,
+$progname: but the definition of this LT_INIT comes from revision $macro_revision.
+$progname: You should recreate aclocal.m4 with macros from revision $package_revision
+$progname: of $PACKAGE $VERSION and run autoconf again.
+_LT_EOF
+    fi
+
+    exit $EXIT_MISMATCH
+  fi
+}
+
+
+# Shorthand for --mode=foo, only valid as the first argument
+case $1 in
+clean|clea|cle|cl)
+  shift; set dummy --mode clean ${1+"$@"}; shift
+  ;;
+compile|compil|compi|comp|com|co|c)
+  shift; set dummy --mode compile ${1+"$@"}; shift
+  ;;
+execute|execut|execu|exec|exe|ex|e)
+  shift; set dummy --mode execute ${1+"$@"}; shift
+  ;;
+finish|finis|fini|fin|fi|f)
+  shift; set dummy --mode finish ${1+"$@"}; shift
+  ;;
+install|instal|insta|inst|ins|in|i)
+  shift; set dummy --mode install ${1+"$@"}; shift
+  ;;
+link|lin|li|l)
+  shift; set dummy --mode link ${1+"$@"}; shift
+  ;;
+uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u)
+  shift; set dummy --mode uninstall ${1+"$@"}; shift
+  ;;
+esac
+
+
+
+# Option defaults:
+opt_debug=:
+opt_dry_run=false
+opt_config=false
+opt_preserve_dup_deps=false
+opt_features=false
+opt_finish=false
+opt_help=false
+opt_help_all=false
+opt_silent=:
+opt_warning=:
+opt_verbose=:
+opt_silent=false
+opt_verbose=false
+
+
+# Parse options once, thoroughly.  This comes as soon as possible in the
+# script to make things like `--version' happen as quickly as we can.
+{
+  # this just eases exit handling
+  while test $# -gt 0; do
+    opt="$1"
+    shift
+    case $opt in
+      --debug|-x)	opt_debug='set -x'
+			func_echo "enabling shell trace mode"
+			$opt_debug
+			;;
+      --dry-run|--dryrun|-n)
+			opt_dry_run=:
+			;;
+      --config)
+			opt_config=:
+func_config
+			;;
+      --dlopen|-dlopen)
+			optarg="$1"
+			opt_dlopen="${opt_dlopen+$opt_dlopen
+}$optarg"
+			shift
+			;;
+      --preserve-dup-deps)
+			opt_preserve_dup_deps=:
+			;;
+      --features)
+			opt_features=:
+func_features
+			;;
+      --finish)
+			opt_finish=:
+set dummy --mode finish ${1+"$@"}; shift
+			;;
+      --help)
+			opt_help=:
+			;;
+      --help-all)
+			opt_help_all=:
+opt_help=': help-all'
+			;;
+      --mode)
+			test $# = 0 && func_missing_arg $opt && break
+			optarg="$1"
+			opt_mode="$optarg"
+case $optarg in
+  # Valid mode arguments:
+  clean|compile|execute|finish|install|link|relink|uninstall) ;;
+
+  # Catch anything else as an error
+  *) func_error "invalid argument for $opt"
+     exit_cmd=exit
+     break
+     ;;
+esac
+			shift
+			;;
+      --no-silent|--no-quiet)
+			opt_silent=false
+func_append preserve_args " $opt"
+			;;
+      --no-warning|--no-warn)
+			opt_warning=false
+func_append preserve_args " $opt"
+			;;
+      --no-verbose)
+			opt_verbose=false
+func_append preserve_args " $opt"
+			;;
+      --silent|--quiet)
+			opt_silent=:
+func_append preserve_args " $opt"
+        opt_verbose=false
+			;;
+      --verbose|-v)
+			opt_verbose=:
+func_append preserve_args " $opt"
+opt_silent=false
+			;;
+      --tag)
+			test $# = 0 && func_missing_arg $opt && break
+			optarg="$1"
+			opt_tag="$optarg"
+func_append preserve_args " $opt $optarg"
+func_enable_tag "$optarg"
+			shift
+			;;
+
+      -\?|-h)		func_usage				;;
+      --help)		func_help				;;
+      --version)	func_version				;;
+
+      # Separate optargs to long options:
+      --*=*)
+			func_split_long_opt "$opt"
+			set dummy "$func_split_long_opt_name" "$func_split_long_opt_arg" ${1+"$@"}
+			shift
+			;;
+
+      # Separate non-argument short options:
+      -\?*|-h*|-n*|-v*)
+			func_split_short_opt "$opt"
+			set dummy "$func_split_short_opt_name" "-$func_split_short_opt_arg" ${1+"$@"}
+			shift
+			;;
+
+      --)		break					;;
+      -*)		func_fatal_help "unrecognized option \`$opt'" ;;
+      *)		set dummy "$opt" ${1+"$@"};	shift; break  ;;
+    esac
+  done
+
+  # Validate options:
+
+  # save first non-option argument
+  if test "$#" -gt 0; then
+    nonopt="$opt"
+    shift
+  fi
+
+  # preserve --debug
+  test "$opt_debug" = : || func_append preserve_args " --debug"
+
+  case $host in
+    *cygwin* | *mingw* | *pw32* | *cegcc*)
+      # don't eliminate duplications in $postdeps and $predeps
+      opt_duplicate_compiler_generated_deps=:
+      ;;
+    *)
+      opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps
+      ;;
+  esac
+
+  $opt_help || {
+    # Sanity checks first:
+    func_check_version_match
+
+    if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then
+      func_fatal_configuration "not configured to build any kind of library"
+    fi
+
+    # Darwin sucks
+    eval std_shrext=\"$shrext_cmds\"
+
+    # Only execute mode is allowed to have -dlopen flags.
+    if test -n "$opt_dlopen" && test "$opt_mode" != execute; then
+      func_error "unrecognized option \`-dlopen'"
+      $ECHO "$help" 1>&2
+      exit $EXIT_FAILURE
+    fi
+
+    # Change the help message to a mode-specific one.
+    generic_help="$help"
+    help="Try \`$progname --help --mode=$opt_mode' for more information."
+  }
+
+
+  # Bail if the options were screwed
+  $exit_cmd $EXIT_FAILURE
+}
+
+
+
+
+## ----------- ##
+##    Main.    ##
+## ----------- ##
+
+# func_lalib_p file
+# True iff FILE is a libtool `.la' library or `.lo' object file.
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_lalib_p ()
+{
+    test -f "$1" &&
+      $SED -e 4q "$1" 2>/dev/null \
+        | $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1
+}
+
+# func_lalib_unsafe_p file
+# True iff FILE is a libtool `.la' library or `.lo' object file.
+# This function implements the same check as func_lalib_p without
+# resorting to external programs.  To this end, it redirects stdin and
+# closes it afterwards, without saving the original file descriptor.
+# As a safety measure, use it only where a negative result would be
+# fatal anyway.  Works if `file' does not exist.
+func_lalib_unsafe_p ()
+{
+    lalib_p=no
+    if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then
+	for lalib_p_l in 1 2 3 4
+	do
+	    read lalib_p_line
+	    case "$lalib_p_line" in
+		\#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;;
+	    esac
+	done
+	exec 0<&5 5<&-
+    fi
+    test "$lalib_p" = yes
+}
+
+# func_ltwrapper_script_p file
+# True iff FILE is a libtool wrapper script
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_script_p ()
+{
+    func_lalib_p "$1"
+}
+
+# func_ltwrapper_executable_p file
+# True iff FILE is a libtool wrapper executable
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_executable_p ()
+{
+    func_ltwrapper_exec_suffix=
+    case $1 in
+    *.exe) ;;
+    *) func_ltwrapper_exec_suffix=.exe ;;
+    esac
+    $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1
+}
+
+# func_ltwrapper_scriptname file
+# Assumes file is an ltwrapper_executable
+# uses $file to determine the appropriate filename for a
+# temporary ltwrapper_script.
+func_ltwrapper_scriptname ()
+{
+    func_dirname_and_basename "$1" "" "."
+    func_stripname '' '.exe' "$func_basename_result"
+    func_ltwrapper_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper"
+}
+
+# func_ltwrapper_p file
+# True iff FILE is a libtool wrapper script or wrapper executable
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_p ()
+{
+    func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1"
+}
+
+
+# func_execute_cmds commands fail_cmd
+# Execute tilde-delimited COMMANDS.
+# If FAIL_CMD is given, eval that upon failure.
+# FAIL_CMD may read-access the current command in variable CMD!
+func_execute_cmds ()
+{
+    $opt_debug
+    save_ifs=$IFS; IFS='~'
+    for cmd in $1; do
+      IFS=$save_ifs
+      eval cmd=\"$cmd\"
+      func_show_eval "$cmd" "${2-:}"
+    done
+    IFS=$save_ifs
+}
+
+
+# func_source file
+# Source FILE, adding directory component if necessary.
+# Note that it is not necessary on cygwin/mingw to append a dot to
+# FILE even if both FILE 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.
+func_source ()
+{
+    $opt_debug
+    case $1 in
+    */* | *\\*)	. "$1" ;;
+    *)		. "./$1" ;;
+    esac
+}
+
+
+# func_resolve_sysroot PATH
+# Replace a leading = in PATH with a sysroot.  Store the result into
+# func_resolve_sysroot_result
+func_resolve_sysroot ()
+{
+  func_resolve_sysroot_result=$1
+  case $func_resolve_sysroot_result in
+  =*)
+    func_stripname '=' '' "$func_resolve_sysroot_result"
+    func_resolve_sysroot_result=$lt_sysroot$func_stripname_result
+    ;;
+  esac
+}
+
+# func_replace_sysroot PATH
+# If PATH begins with the sysroot, replace it with = and
+# store the result into func_replace_sysroot_result.
+func_replace_sysroot ()
+{
+  case "$lt_sysroot:$1" in
+  ?*:"$lt_sysroot"*)
+    func_stripname "$lt_sysroot" '' "$1"
+    func_replace_sysroot_result="=$func_stripname_result"
+    ;;
+  *)
+    # Including no sysroot.
+    func_replace_sysroot_result=$1
+    ;;
+  esac
+}
+
+# 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 ()
+{
+    $opt_debug
+    if test -n "$available_tags" && test -z "$tagname"; then
+      CC_quoted=
+      for arg in $CC; do
+	func_append_quoted CC_quoted "$arg"
+      done
+      CC_expanded=`func_echo_all $CC`
+      CC_quoted_expanded=`func_echo_all $CC_quoted`
+      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 "* | " $CC_expanded "* | "$CC_expanded "* | \
+      " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;;
+      # 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.
+	      func_append_quoted CC_quoted "$arg"
+	    done
+	    CC_expanded=`func_echo_all $CC`
+	    CC_quoted_expanded=`func_echo_all $CC_quoted`
+	    case "$@ " in
+	    " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \
+	    " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*)
+	      # 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
+	  func_echo "unable to infer tagged configuration"
+	  func_fatal_error "specify a tag with \`--tag'"
+#	else
+#	  func_verbose "using $tagname tagged configuration"
+	fi
+	;;
+      esac
+    fi
+}
+
+
+
+# func_write_libtool_object output_name pic_name nonpic_name
+# Create a libtool object file (analogous to a ".la" file),
+# but don't create it if we're doing a dry run.
+func_write_libtool_object ()
+{
+    write_libobj=${1}
+    if test "$build_libtool_libs" = yes; then
+      write_lobj=\'${2}\'
+    else
+      write_lobj=none
+    fi
+
+    if test "$build_old_libs" = yes; then
+      write_oldobj=\'${3}\'
+    else
+      write_oldobj=none
+    fi
+
+    $opt_dry_run || {
+      cat >${write_libobj}T <<EOF
+# $write_libobj - a libtool object file
+# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# Name of the PIC object.
+pic_object=$write_lobj
+
+# Name of the non-PIC object
+non_pic_object=$write_oldobj
+
+EOF
+      $MV "${write_libobj}T" "${write_libobj}"
+    }
+}
+
+
+##################################################
+# FILE NAME AND PATH CONVERSION HELPER FUNCTIONS #
+##################################################
+
+# func_convert_core_file_wine_to_w32 ARG
+# Helper function used by file name conversion functions when $build is *nix,
+# and $host is mingw, cygwin, or some other w32 environment. Relies on a
+# correctly configured wine environment available, with the winepath program
+# in $build's $PATH.
+#
+# ARG is the $build file name to be converted to w32 format.
+# Result is available in $func_convert_core_file_wine_to_w32_result, and will
+# be empty on error (or when ARG is empty)
+func_convert_core_file_wine_to_w32 ()
+{
+  $opt_debug
+  func_convert_core_file_wine_to_w32_result="$1"
+  if test -n "$1"; then
+    # Unfortunately, winepath does not exit with a non-zero error code, so we
+    # are forced to check the contents of stdout. On the other hand, if the
+    # command is not found, the shell will set an exit code of 127 and print
+    # *an error message* to stdout. So we must check for both error code of
+    # zero AND non-empty stdout, which explains the odd construction:
+    func_convert_core_file_wine_to_w32_tmp=`winepath -w "$1" 2>/dev/null`
+    if test "$?" -eq 0 && test -n "${func_convert_core_file_wine_to_w32_tmp}"; then
+      func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" |
+        $SED -e "$lt_sed_naive_backslashify"`
+    else
+      func_convert_core_file_wine_to_w32_result=
+    fi
+  fi
+}
+# end: func_convert_core_file_wine_to_w32
+
+
+# func_convert_core_path_wine_to_w32 ARG
+# Helper function used by path conversion functions when $build is *nix, and
+# $host is mingw, cygwin, or some other w32 environment. Relies on a correctly
+# configured wine environment available, with the winepath program in $build's
+# $PATH. Assumes ARG has no leading or trailing path separator characters.
+#
+# ARG is path to be converted from $build format to win32.
+# Result is available in $func_convert_core_path_wine_to_w32_result.
+# Unconvertible file (directory) names in ARG are skipped; if no directory names
+# are convertible, then the result may be empty.
+func_convert_core_path_wine_to_w32 ()
+{
+  $opt_debug
+  # unfortunately, winepath doesn't convert paths, only file names
+  func_convert_core_path_wine_to_w32_result=""
+  if test -n "$1"; then
+    oldIFS=$IFS
+    IFS=:
+    for func_convert_core_path_wine_to_w32_f in $1; do
+      IFS=$oldIFS
+      func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f"
+      if test -n "$func_convert_core_file_wine_to_w32_result" ; then
+        if test -z "$func_convert_core_path_wine_to_w32_result"; then
+          func_convert_core_path_wine_to_w32_result="$func_convert_core_file_wine_to_w32_result"
+        else
+          func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result"
+        fi
+      fi
+    done
+    IFS=$oldIFS
+  fi
+}
+# end: func_convert_core_path_wine_to_w32
+
+
+# func_cygpath ARGS...
+# Wrapper around calling the cygpath program via LT_CYGPATH. This is used when
+# when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2)
+# $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or
+# (2), returns the Cygwin file name or path in func_cygpath_result (input
+# file name or path is assumed to be in w32 format, as previously converted
+# from $build's *nix or MSYS format). In case (3), returns the w32 file name
+# or path in func_cygpath_result (input file name or path is assumed to be in
+# Cygwin format). Returns an empty string on error.
+#
+# ARGS are passed to cygpath, with the last one being the file name or path to
+# be converted.
+#
+# Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH
+# environment variable; do not put it in $PATH.
+func_cygpath ()
+{
+  $opt_debug
+  if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then
+    func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null`
+    if test "$?" -ne 0; then
+      # on failure, ensure result is empty
+      func_cygpath_result=
+    fi
+  else
+    func_cygpath_result=
+    func_error "LT_CYGPATH is empty or specifies non-existent file: \`$LT_CYGPATH'"
+  fi
+}
+#end: func_cygpath
+
+
+# func_convert_core_msys_to_w32 ARG
+# Convert file name or path ARG from MSYS format to w32 format.  Return
+# result in func_convert_core_msys_to_w32_result.
+func_convert_core_msys_to_w32 ()
+{
+  $opt_debug
+  # awkward: cmd appends spaces to result
+  func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null |
+    $SED -e 's/[ ]*$//' -e "$lt_sed_naive_backslashify"`
+}
+#end: func_convert_core_msys_to_w32
+
+
+# func_convert_file_check ARG1 ARG2
+# Verify that ARG1 (a file name in $build format) was converted to $host
+# format in ARG2. Otherwise, emit an error message, but continue (resetting
+# func_to_host_file_result to ARG1).
+func_convert_file_check ()
+{
+  $opt_debug
+  if test -z "$2" && test -n "$1" ; then
+    func_error "Could not determine host file name corresponding to"
+    func_error "  \`$1'"
+    func_error "Continuing, but uninstalled executables may not work."
+    # Fallback:
+    func_to_host_file_result="$1"
+  fi
+}
+# end func_convert_file_check
+
+
+# func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH
+# Verify that FROM_PATH (a path in $build format) was converted to $host
+# format in TO_PATH. Otherwise, emit an error message, but continue, resetting
+# func_to_host_file_result to a simplistic fallback value (see below).
+func_convert_path_check ()
+{
+  $opt_debug
+  if test -z "$4" && test -n "$3"; then
+    func_error "Could not determine the host path corresponding to"
+    func_error "  \`$3'"
+    func_error "Continuing, but uninstalled executables may not work."
+    # Fallback.  This is a deliberately simplistic "conversion" and
+    # should not be "improved".  See libtool.info.
+    if test "x$1" != "x$2"; then
+      lt_replace_pathsep_chars="s|$1|$2|g"
+      func_to_host_path_result=`echo "$3" |
+        $SED -e "$lt_replace_pathsep_chars"`
+    else
+      func_to_host_path_result="$3"
+    fi
+  fi
+}
+# end func_convert_path_check
+
+
+# func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG
+# Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT
+# and appending REPL if ORIG matches BACKPAT.
+func_convert_path_front_back_pathsep ()
+{
+  $opt_debug
+  case $4 in
+  $1 ) func_to_host_path_result="$3$func_to_host_path_result"
+    ;;
+  esac
+  case $4 in
+  $2 ) func_append func_to_host_path_result "$3"
+    ;;
+  esac
+}
+# end func_convert_path_front_back_pathsep
+
+
+##################################################
+# $build to $host FILE NAME CONVERSION FUNCTIONS #
+##################################################
+# invoked via `$to_host_file_cmd ARG'
+#
+# In each case, ARG is the path to be converted from $build to $host format.
+# Result will be available in $func_to_host_file_result.
+
+
+# func_to_host_file ARG
+# Converts the file name ARG from $build format to $host format. Return result
+# in func_to_host_file_result.
+func_to_host_file ()
+{
+  $opt_debug
+  $to_host_file_cmd "$1"
+}
+# end func_to_host_file
+
+
+# func_to_tool_file ARG LAZY
+# converts the file name ARG from $build format to toolchain format. Return
+# result in func_to_tool_file_result.  If the conversion in use is listed
+# in (the comma separated) LAZY, no conversion takes place.
+func_to_tool_file ()
+{
+  $opt_debug
+  case ,$2, in
+    *,"$to_tool_file_cmd",*)
+      func_to_tool_file_result=$1
+      ;;
+    *)
+      $to_tool_file_cmd "$1"
+      func_to_tool_file_result=$func_to_host_file_result
+      ;;
+  esac
+}
+# end func_to_tool_file
+
+
+# func_convert_file_noop ARG
+# Copy ARG to func_to_host_file_result.
+func_convert_file_noop ()
+{
+  func_to_host_file_result="$1"
+}
+# end func_convert_file_noop
+
+
+# func_convert_file_msys_to_w32 ARG
+# Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic
+# conversion to w32 is not available inside the cwrapper.  Returns result in
+# func_to_host_file_result.
+func_convert_file_msys_to_w32 ()
+{
+  $opt_debug
+  func_to_host_file_result="$1"
+  if test -n "$1"; then
+    func_convert_core_msys_to_w32 "$1"
+    func_to_host_file_result="$func_convert_core_msys_to_w32_result"
+  fi
+  func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_msys_to_w32
+
+
+# func_convert_file_cygwin_to_w32 ARG
+# Convert file name ARG from Cygwin to w32 format.  Returns result in
+# func_to_host_file_result.
+func_convert_file_cygwin_to_w32 ()
+{
+  $opt_debug
+  func_to_host_file_result="$1"
+  if test -n "$1"; then
+    # because $build is cygwin, we call "the" cygpath in $PATH; no need to use
+    # LT_CYGPATH in this case.
+    func_to_host_file_result=`cygpath -m "$1"`
+  fi
+  func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_cygwin_to_w32
+
+
+# func_convert_file_nix_to_w32 ARG
+# Convert file name ARG from *nix to w32 format.  Requires a wine environment
+# and a working winepath. Returns result in func_to_host_file_result.
+func_convert_file_nix_to_w32 ()
+{
+  $opt_debug
+  func_to_host_file_result="$1"
+  if test -n "$1"; then
+    func_convert_core_file_wine_to_w32 "$1"
+    func_to_host_file_result="$func_convert_core_file_wine_to_w32_result"
+  fi
+  func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_nix_to_w32
+
+
+# func_convert_file_msys_to_cygwin ARG
+# Convert file name ARG from MSYS to Cygwin format.  Requires LT_CYGPATH set.
+# Returns result in func_to_host_file_result.
+func_convert_file_msys_to_cygwin ()
+{
+  $opt_debug
+  func_to_host_file_result="$1"
+  if test -n "$1"; then
+    func_convert_core_msys_to_w32 "$1"
+    func_cygpath -u "$func_convert_core_msys_to_w32_result"
+    func_to_host_file_result="$func_cygpath_result"
+  fi
+  func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_msys_to_cygwin
+
+
+# func_convert_file_nix_to_cygwin ARG
+# Convert file name ARG from *nix to Cygwin format.  Requires Cygwin installed
+# in a wine environment, working winepath, and LT_CYGPATH set.  Returns result
+# in func_to_host_file_result.
+func_convert_file_nix_to_cygwin ()
+{
+  $opt_debug
+  func_to_host_file_result="$1"
+  if test -n "$1"; then
+    # convert from *nix to w32, then use cygpath to convert from w32 to cygwin.
+    func_convert_core_file_wine_to_w32 "$1"
+    func_cygpath -u "$func_convert_core_file_wine_to_w32_result"
+    func_to_host_file_result="$func_cygpath_result"
+  fi
+  func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_nix_to_cygwin
+
+
+#############################################
+# $build to $host PATH CONVERSION FUNCTIONS #
+#############################################
+# invoked via `$to_host_path_cmd ARG'
+#
+# In each case, ARG is the path to be converted from $build to $host format.
+# The result will be available in $func_to_host_path_result.
+#
+# Path separators are also converted from $build format to $host format.  If
+# ARG begins or ends with a path separator character, it is preserved (but
+# converted to $host format) on output.
+#
+# All path conversion functions are named using the following convention:
+#   file name conversion function    : func_convert_file_X_to_Y ()
+#   path conversion function         : func_convert_path_X_to_Y ()
+# where, for any given $build/$host combination the 'X_to_Y' value is the
+# same.  If conversion functions are added for new $build/$host combinations,
+# the two new functions must follow this pattern, or func_init_to_host_path_cmd
+# will break.
+
+
+# func_init_to_host_path_cmd
+# Ensures that function "pointer" variable $to_host_path_cmd is set to the
+# appropriate value, based on the value of $to_host_file_cmd.
+to_host_path_cmd=
+func_init_to_host_path_cmd ()
+{
+  $opt_debug
+  if test -z "$to_host_path_cmd"; then
+    func_stripname 'func_convert_file_' '' "$to_host_file_cmd"
+    to_host_path_cmd="func_convert_path_${func_stripname_result}"
+  fi
+}
+
+
+# func_to_host_path ARG
+# Converts the path ARG from $build format to $host format. Return result
+# in func_to_host_path_result.
+func_to_host_path ()
+{
+  $opt_debug
+  func_init_to_host_path_cmd
+  $to_host_path_cmd "$1"
+}
+# end func_to_host_path
+
+
+# func_convert_path_noop ARG
+# Copy ARG to func_to_host_path_result.
+func_convert_path_noop ()
+{
+  func_to_host_path_result="$1"
+}
+# end func_convert_path_noop
+
+
+# func_convert_path_msys_to_w32 ARG
+# Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic
+# conversion to w32 is not available inside the cwrapper.  Returns result in
+# func_to_host_path_result.
+func_convert_path_msys_to_w32 ()
+{
+  $opt_debug
+  func_to_host_path_result="$1"
+  if test -n "$1"; then
+    # Remove leading and trailing path separator characters from ARG.  MSYS
+    # behavior is inconsistent here; cygpath turns them into '.;' and ';.';
+    # and winepath ignores them completely.
+    func_stripname : : "$1"
+    func_to_host_path_tmp1=$func_stripname_result
+    func_convert_core_msys_to_w32 "$func_to_host_path_tmp1"
+    func_to_host_path_result="$func_convert_core_msys_to_w32_result"
+    func_convert_path_check : ";" \
+      "$func_to_host_path_tmp1" "$func_to_host_path_result"
+    func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
+  fi
+}
+# end func_convert_path_msys_to_w32
+
+
+# func_convert_path_cygwin_to_w32 ARG
+# Convert path ARG from Cygwin to w32 format.  Returns result in
+# func_to_host_file_result.
+func_convert_path_cygwin_to_w32 ()
+{
+  $opt_debug
+  func_to_host_path_result="$1"
+  if test -n "$1"; then
+    # See func_convert_path_msys_to_w32:
+    func_stripname : : "$1"
+    func_to_host_path_tmp1=$func_stripname_result
+    func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"`
+    func_convert_path_check : ";" \
+      "$func_to_host_path_tmp1" "$func_to_host_path_result"
+    func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
+  fi
+}
+# end func_convert_path_cygwin_to_w32
+
+
+# func_convert_path_nix_to_w32 ARG
+# Convert path ARG from *nix to w32 format.  Requires a wine environment and
+# a working winepath.  Returns result in func_to_host_file_result.
+func_convert_path_nix_to_w32 ()
+{
+  $opt_debug
+  func_to_host_path_result="$1"
+  if test -n "$1"; then
+    # See func_convert_path_msys_to_w32:
+    func_stripname : : "$1"
+    func_to_host_path_tmp1=$func_stripname_result
+    func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1"
+    func_to_host_path_result="$func_convert_core_path_wine_to_w32_result"
+    func_convert_path_check : ";" \
+      "$func_to_host_path_tmp1" "$func_to_host_path_result"
+    func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
+  fi
+}
+# end func_convert_path_nix_to_w32
+
+
+# func_convert_path_msys_to_cygwin ARG
+# Convert path ARG from MSYS to Cygwin format.  Requires LT_CYGPATH set.
+# Returns result in func_to_host_file_result.
+func_convert_path_msys_to_cygwin ()
+{
+  $opt_debug
+  func_to_host_path_result="$1"
+  if test -n "$1"; then
+    # See func_convert_path_msys_to_w32:
+    func_stripname : : "$1"
+    func_to_host_path_tmp1=$func_stripname_result
+    func_convert_core_msys_to_w32 "$func_to_host_path_tmp1"
+    func_cygpath -u -p "$func_convert_core_msys_to_w32_result"
+    func_to_host_path_result="$func_cygpath_result"
+    func_convert_path_check : : \
+      "$func_to_host_path_tmp1" "$func_to_host_path_result"
+    func_convert_path_front_back_pathsep ":*" "*:" : "$1"
+  fi
+}
+# end func_convert_path_msys_to_cygwin
+
+
+# func_convert_path_nix_to_cygwin ARG
+# Convert path ARG from *nix to Cygwin format.  Requires Cygwin installed in a
+# a wine environment, working winepath, and LT_CYGPATH set.  Returns result in
+# func_to_host_file_result.
+func_convert_path_nix_to_cygwin ()
+{
+  $opt_debug
+  func_to_host_path_result="$1"
+  if test -n "$1"; then
+    # Remove leading and trailing path separator characters from
+    # ARG. msys behavior is inconsistent here, cygpath turns them
+    # into '.;' and ';.', and winepath ignores them completely.
+    func_stripname : : "$1"
+    func_to_host_path_tmp1=$func_stripname_result
+    func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1"
+    func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result"
+    func_to_host_path_result="$func_cygpath_result"
+    func_convert_path_check : : \
+      "$func_to_host_path_tmp1" "$func_to_host_path_result"
+    func_convert_path_front_back_pathsep ":*" "*:" : "$1"
+  fi
+}
+# end func_convert_path_nix_to_cygwin
+
+
+# func_mode_compile arg...
+func_mode_compile ()
+{
+    $opt_debug
+    # 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=
+    pie_flag=
+
+    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)
+	  test -n "$libobj" && \
+	    func_fatal_error "you cannot specify \`-o' more than once"
+	  arg_mode=target
+	  continue
+	  ;;
+
+	-pie | -fpie | -fPIE)
+          func_append pie_flag " $arg"
+	  continue
+	  ;;
+
+	-shared | -static | -prefer-pic | -prefer-non-pic)
+	  func_append 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,*)
+	  func_stripname '-Wc,' '' "$arg"
+	  args=$func_stripname_result
+	  lastarg=
+	  save_ifs="$IFS"; IFS=','
+	  for arg in $args; do
+	    IFS="$save_ifs"
+	    func_append_quoted lastarg "$arg"
+	  done
+	  IFS="$save_ifs"
+	  func_stripname ' ' '' "$lastarg"
+	  lastarg=$func_stripname_result
+
+	  # Add the arguments to base_compile.
+	  func_append 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.
+      func_append_quoted base_compile "$lastarg"
+    done # for arg
+
+    case $arg_mode in
+    arg)
+      func_fatal_error "you must specify an argument for -Xcompile"
+      ;;
+    target)
+      func_fatal_error "you must specify a target with \`-o'"
+      ;;
+    *)
+      # Get the name of the library object.
+      test -z "$libobj" && {
+	func_basename "$srcfile"
+	libobj="$func_basename_result"
+      }
+      ;;
+    esac
+
+    # Recognize several different file suffixes.
+    # If the user specifies -o file.o, it is replaced with file.lo
+    case $libobj in
+    *.[cCFSifmso] | \
+    *.ada | *.adb | *.ads | *.asm | \
+    *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \
+    *.[fF][09]? | *.for | *.java | *.go | *.obj | *.sx | *.cu | *.cup)
+      func_xform "$libobj"
+      libobj=$func_xform_result
+      ;;
+    esac
+
+    case $libobj in
+    *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;;
+    *)
+      func_fatal_error "cannot determine name of library object from \`$libobj'"
+      ;;
+    esac
+
+    func_infer_tag $base_compile
+
+    for arg in $later; do
+      case $arg in
+      -shared)
+	test "$build_libtool_libs" != yes && \
+	  func_fatal_configuration "can not build a shared library"
+	build_old_libs=no
+	continue
+	;;
+
+      -static)
+	build_libtool_libs=no
+	build_old_libs=yes
+	continue
+	;;
+
+      -prefer-pic)
+	pic_mode=yes
+	continue
+	;;
+
+      -prefer-non-pic)
+	pic_mode=no
+	continue
+	;;
+      esac
+    done
+
+    func_quote_for_eval "$libobj"
+    test "X$libobj" != "X$func_quote_for_eval_result" \
+      && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"'	 &()|`$[]' \
+      && func_warning "libobj name \`$libobj' may not contain shell special characters."
+    func_dirname_and_basename "$obj" "/" ""
+    objname="$func_basename_result"
+    xdir="$func_dirname_result"
+    lobj=${xdir}$objdir/$objname
+
+    test -z "$base_compile" && \
+      func_fatal_help "you must specify a compilation command"
+
+    # 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
+
+    # On Cygwin there's no "real" PIC flag so we must build both object types
+    case $host_os in
+    cygwin* | mingw* | pw32* | os2* | cegcc*)
+      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 "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.${objext}
+      lockfile="$output_obj.lock"
+    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 $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do
+	func_echo "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."
+
+	$opt_dry_run || $RM $removelist
+	exit $EXIT_FAILURE
+      fi
+      func_append removelist " $output_obj"
+      $ECHO "$srcfile" > "$lockfile"
+    fi
+
+    $opt_dry_run || $RM $removelist
+    func_append removelist " $lockfile"
+    trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15
+
+    func_to_tool_file "$srcfile" func_convert_file_msys_to_w32
+    srcfile=$func_to_tool_file_result
+    func_quote_for_eval "$srcfile"
+    qsrcfile=$func_quote_for_eval_result
+
+    # 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
+
+      func_mkdir_p "$xdir$objdir"
+
+      if test -z "$output_obj"; then
+	# Place PIC objects in $objdir
+	func_append command " -o $lobj"
+      fi
+
+      func_show_eval_locale "$command"	\
+          'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE'
+
+      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."
+
+	$opt_dry_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
+	func_show_eval '$MV "$output_obj" "$lobj"' \
+	  'error=$?; $opt_dry_run || $RM $removelist; exit $error'
+      fi
+
+      # Allow error messages only from the first compilation.
+      if test "$suppress_opt" = yes; then
+	suppress_output=' >/dev/null 2>&1'
+      fi
+    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$pie_flag"
+      else
+	command="$base_compile $qsrcfile $pic_flag"
+      fi
+      if test "$compiler_c_o" = yes; then
+	func_append command " -o $obj"
+      fi
+
+      # Suppress compiler output if we already did a PIC compilation.
+      func_append command "$suppress_output"
+      func_show_eval_locale "$command" \
+        '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE'
+
+      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."
+
+	$opt_dry_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
+	func_show_eval '$MV "$output_obj" "$obj"' \
+	  'error=$?; $opt_dry_run || $RM $removelist; exit $error'
+      fi
+    fi
+
+    $opt_dry_run || {
+      func_write_libtool_object "$libobj" "$objdir/$objname" "$objname"
+
+      # Unlock the critical section if it was locked
+      if test "$need_locks" != no; then
+	removelist=$lockfile
+        $RM "$lockfile"
+      fi
+    }
+
+    exit $EXIT_SUCCESS
+}
+
+$opt_help || {
+  test "$opt_mode" = compile && func_mode_compile ${1+"$@"}
+}
+
+func_mode_help ()
+{
+    # We need to display help for each of the modes.
+    case $opt_mode in
+      "")
+        # Generic help is extracted from the usage comments
+        # at the start of this file.
+        func_help
+        ;;
+
+      clean)
+        $ECHO \
+"Usage: $progname [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: $progname [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
+  -no-suppress      do not suppress compiler output for multiple passes
+  -prefer-pic       try to build PIC objects only
+  -prefer-non-pic   try to build non-PIC objects only
+  -shared           do not build a \`.o' file suitable for static linking
+  -static           only build a \`.o' file suitable for static linking
+  -Wc,FLAG          pass FLAG directly to the compiler
+
+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: $progname [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: $progname [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: $progname [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 following components of INSTALL-COMMAND are treated specially:
+
+  -inst-prefix-dir PREFIX-DIR  Use PREFIX-DIR as a staging area for installation
+
+The rest of the components are interpreted as arguments to that command (only
+BSD-compatible install options are recognized)."
+        ;;
+
+      link)
+        $ECHO \
+"Usage: $progname [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
+  -bindir BINDIR    specify path to binaries directory (for systems where
+                    libraries must be found in the PATH setting at runtime)
+  -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
+  -shared           only do dynamic linking of libtool libraries
+  -shrext SUFFIX    override the standard shared library file extension
+  -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]
+  -weak LIBNAME     declare that the target provides the LIBNAME interface
+  -Wc,FLAG
+  -Xcompiler FLAG   pass linker-specific FLAG directly to the compiler
+  -Wl,FLAG
+  -Xlinker FLAG     pass linker-specific FLAG directly to the linker
+  -XCClinker FLAG   pass link-specific FLAG to the compiler driver (CC)
+
+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: $progname [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."
+        ;;
+
+      *)
+        func_fatal_help "invalid operation mode \`$opt_mode'"
+        ;;
+    esac
+
+    echo
+    $ECHO "Try \`$progname --help' for more information about other modes."
+}
+
+# Now that we've collected a possible --mode arg, show help if necessary
+if $opt_help; then
+  if test "$opt_help" = :; then
+    func_mode_help
+  else
+    {
+      func_help noexit
+      for opt_mode in compile link execute install finish uninstall clean; do
+	func_mode_help
+      done
+    } | sed -n '1p; 2,$s/^Usage:/  or: /p'
+    {
+      func_help noexit
+      for opt_mode in compile link execute install finish uninstall clean; do
+	echo
+	func_mode_help
+      done
+    } |
+    sed '1d
+      /^When reporting/,/^Report/{
+	H
+	d
+      }
+      $x
+      /information about other modes/d
+      /more detailed .*MODE/d
+      s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/'
+  fi
+  exit $?
+fi
+
+
+# func_mode_execute arg...
+func_mode_execute ()
+{
+    $opt_debug
+    # The first argument is the command name.
+    cmd="$nonopt"
+    test -z "$cmd" && \
+      func_fatal_help "you must specify a COMMAND"
+
+    # Handle -dlopen flags immediately.
+    for file in $opt_dlopen; do
+      test -f "$file" \
+	|| func_fatal_help "\`$file' is not a file"
+
+      dir=
+      case $file in
+      *.la)
+	func_resolve_sysroot "$file"
+	file=$func_resolve_sysroot_result
+
+	# Check to see that this really is a libtool archive.
+	func_lalib_unsafe_p "$file" \
+	  || func_fatal_help "\`$lib' is not a valid libtool archive"
+
+	# Read the libtool library.
+	dlname=
+	library_names=
+	func_source "$file"
+
+	# Skip this library if it cannot be dlopened.
+	if test -z "$dlname"; then
+	  # Warn if it was a shared library.
+	  test -n "$library_names" && \
+	    func_warning "\`$file' was not linked with \`-export-dynamic'"
+	  continue
+	fi
+
+	func_dirname "$file" "" "."
+	dir="$func_dirname_result"
+
+	if test -f "$dir/$objdir/$dlname"; then
+	  func_append dir "/$objdir"
+	else
+	  if test ! -f "$dir/$dlname"; then
+	    func_fatal_error "cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'"
+	  fi
+	fi
+	;;
+
+      *.lo)
+	# Just add the directory containing the .lo file.
+	func_dirname "$file" "" "."
+	dir="$func_dirname_result"
+	;;
+
+      *)
+	func_warning "\`-dlopen' is ignored for non-libtool libraries and objects"
+	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
+      -* | *.la | *.lo ) ;;
+      *)
+	# Do a test to see if this is really a libtool program.
+	if func_ltwrapper_script_p "$file"; then
+	  func_source "$file"
+	  # Transform arg to wrapped name.
+	  file="$progdir/$program"
+	elif func_ltwrapper_executable_p "$file"; then
+	  func_ltwrapper_scriptname "$file"
+	  func_source "$func_ltwrapper_scriptname_result"
+	  # Transform arg to wrapped name.
+	  file="$progdir/$program"
+	fi
+	;;
+      esac
+      # Quote arguments (to preserve shell metacharacters).
+      func_append_quoted args "$file"
+    done
+
+    if test "X$opt_dry_run" = Xfalse; 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
+	      else
+		$lt_unset $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
+}
+
+test "$opt_mode" = execute && func_mode_execute ${1+"$@"}
+
+
+# func_mode_finish arg...
+func_mode_finish ()
+{
+    $opt_debug
+    libs=
+    libdirs=
+    admincmds=
+
+    for opt in "$nonopt" ${1+"$@"}
+    do
+      if test -d "$opt"; then
+	func_append libdirs " $opt"
+
+      elif test -f "$opt"; then
+	if func_lalib_unsafe_p "$opt"; then
+	  func_append libs " $opt"
+	else
+	  func_warning "\`$opt' is not a valid libtool archive"
+	fi
+
+      else
+	func_fatal_error "invalid argument \`$opt'"
+      fi
+    done
+
+    if test -n "$libs"; then
+      if test -n "$lt_sysroot"; then
+        sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"`
+        sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;"
+      else
+        sysroot_cmd=
+      fi
+
+      # Remove sysroot references
+      if $opt_dry_run; then
+        for lib in $libs; do
+          echo "removing references to $lt_sysroot and \`=' prefixes from $lib"
+        done
+      else
+        tmpdir=`func_mktempdir`
+        for lib in $libs; do
+	  sed -e "${sysroot_cmd} s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \
+	    > $tmpdir/tmp-la
+	  mv -f $tmpdir/tmp-la $lib
+	done
+        ${RM}r "$tmpdir"
+      fi
+    fi
+
+    if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
+      for libdir in $libdirs; do
+	if test -n "$finish_cmds"; then
+	  # Do each command in the finish commands.
+	  func_execute_cmds "$finish_cmds" 'admincmds="$admincmds
+'"$cmd"'"'
+	fi
+	if test -n "$finish_eval"; then
+	  # Do the single finish_eval.
+	  eval cmds=\"$finish_eval\"
+	  $opt_dry_run || eval "$cmds" || func_append admincmds "
+       $cmds"
+	fi
+      done
+    fi
+
+    # Exit here if they wanted silent mode.
+    $opt_silent && exit $EXIT_SUCCESS
+
+    if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
+      echo "----------------------------------------------------------------------"
+      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"
+      case $host in
+	solaris2.[6789]|solaris2.1[0-9])
+	  echo "more information, such as the ld(1), crle(1) and ld.so(8) manual"
+	  echo "pages."
+	  ;;
+	*)
+	  echo "more information, such as the ld(1) and ld.so(8) manual pages."
+	  ;;
+      esac
+      echo "----------------------------------------------------------------------"
+    fi
+    exit $EXIT_SUCCESS
+}
+
+test "$opt_mode" = finish && func_mode_finish ${1+"$@"}
+
+
+# func_mode_install arg...
+func_mode_install ()
+{
+    $opt_debug
+    # 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.
+       case $nonopt in *shtool*) :;; *) false;; esac; then
+      # Aesthetically quote it.
+      func_quote_for_eval "$nonopt"
+      install_prog="$func_quote_for_eval_result "
+      arg=$1
+      shift
+    else
+      install_prog=
+      arg=$nonopt
+    fi
+
+    # The real first argument should be the name of the installation program.
+    # Aesthetically quote it.
+    func_quote_for_eval "$arg"
+    func_append install_prog "$func_quote_for_eval_result"
+    install_shared_prog=$install_prog
+    case " $install_prog " in
+      *[\\\ /]cp\ *) install_cp=: ;;
+      *) install_cp=false ;;
+    esac
+
+    # We need to accept at least all the BSD install flags.
+    dest=
+    files=
+    opts=
+    prev=
+    install_type=
+    isdir=no
+    stripme=
+    no_mode=:
+    for arg
+    do
+      arg2=
+      if test -n "$dest"; then
+	func_append files " $dest"
+	dest=$arg
+	continue
+      fi
+
+      case $arg in
+      -d) isdir=yes ;;
+      -f)
+	if $install_cp; then :; else
+	  prev=$arg
+	fi
+	;;
+      -g | -m | -o)
+	prev=$arg
+	;;
+      -s)
+	stripme=" -s"
+	continue
+	;;
+      -*)
+	;;
+      *)
+	# If the previous option needed an argument, then skip it.
+	if test -n "$prev"; then
+	  if test "x$prev" = x-m && test -n "$install_override_mode"; then
+	    arg2=$install_override_mode
+	    no_mode=false
+	  fi
+	  prev=
+	else
+	  dest=$arg
+	  continue
+	fi
+	;;
+      esac
+
+      # Aesthetically quote the argument.
+      func_quote_for_eval "$arg"
+      func_append install_prog " $func_quote_for_eval_result"
+      if test -n "$arg2"; then
+	func_quote_for_eval "$arg2"
+      fi
+      func_append install_shared_prog " $func_quote_for_eval_result"
+    done
+
+    test -z "$install_prog" && \
+      func_fatal_help "you must specify an install program"
+
+    test -n "$prev" && \
+      func_fatal_help "the \`$prev' option requires an argument"
+
+    if test -n "$install_override_mode" && $no_mode; then
+      if $install_cp; then :; else
+	func_quote_for_eval "$install_override_mode"
+	func_append install_shared_prog " -m $func_quote_for_eval_result"
+      fi
+    fi
+
+    if test -z "$files"; then
+      if test -z "$dest"; then
+	func_fatal_help "no file or destination specified"
+      else
+	func_fatal_help "you must specify a destination"
+      fi
+    fi
+
+    # Strip any trailing slash from the destination.
+    func_stripname '' '/' "$dest"
+    dest=$func_stripname_result
+
+    # Check to see that the destination is a directory.
+    test -d "$dest" && isdir=yes
+    if test "$isdir" = yes; then
+      destdir="$dest"
+      destname=
+    else
+      func_dirname_and_basename "$dest" "" "."
+      destdir="$func_dirname_result"
+      destname="$func_basename_result"
+
+      # Not a directory, so check to see that there is only one file specified.
+      set dummy $files; shift
+      test "$#" -gt 1 && \
+	func_fatal_help "\`$dest' is not a directory"
+    fi
+    case $destdir in
+    [\\/]* | [A-Za-z]:[\\/]*) ;;
+    *)
+      for file in $files; do
+	case $file in
+	*.lo) ;;
+	*)
+	  func_fatal_help "\`$destdir' must be an absolute directory name"
+	  ;;
+	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.
+	func_append staticlibs " $file"
+	;;
+
+      *.la)
+	func_resolve_sysroot "$file"
+	file=$func_resolve_sysroot_result
+
+	# Check to see that this really is a libtool archive.
+	func_lalib_unsafe_p "$file" \
+	  || func_fatal_help "\`$file' is not a valid libtool archive"
+
+	library_names=
+	old_library=
+	relink_command=
+	func_source "$file"
+
+	# Add the libdir to current_libdirs if it is the destination.
+	if test "X$destdir" = "X$libdir"; then
+	  case "$current_libdirs " in
+	  *" $libdir "*) ;;
+	  *) func_append current_libdirs " $libdir" ;;
+	  esac
+	else
+	  # Note the libdir as a future libdir.
+	  case "$future_libdirs " in
+	  *" $libdir "*) ;;
+	  *) func_append future_libdirs " $libdir" ;;
+	  esac
+	fi
+
+	func_dirname "$file" "/" ""
+	dir="$func_dirname_result"
+	func_append 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 -e "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.
+	  test "$inst_prefix_dir" = "$destdir" && \
+	    func_fatal_error "error: cannot install \`$file' to a directory not ending in $libdir"
+
+	  if test -n "$inst_prefix_dir"; then
+	    # Stick the inst_prefix_dir data into the link command.
+	    relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"`
+	  else
+	    relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"`
+	  fi
+
+	  func_warning "relinking \`$file'"
+	  func_show_eval "$relink_command" \
+	    'func_fatal_error "error: relink \`$file'\'' with the above command before installing it"'
+	fi
+
+	# See the names of the shared library.
+	set dummy $library_names; shift
+	if test -n "$1"; then
+	  realname="$1"
+	  shift
+
+	  srcname="$realname"
+	  test -n "$relink_command" && srcname="$realname"T
+
+	  # Install the shared library and build the symlinks.
+	  func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \
+	      'exit $?'
+	  tstripme="$stripme"
+	  case $host_os in
+	  cygwin* | mingw* | pw32* | cegcc*)
+	    case $realname in
+	    *.dll.a)
+	      tstripme=""
+	      ;;
+	    esac
+	    ;;
+	  esac
+	  if test -n "$tstripme" && test -n "$striplib"; then
+	    func_show_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
+	      test "$linkname" != "$realname" \
+		&& func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })"
+	    done
+	  fi
+
+	  # Do each command in the postinstall commands.
+	  lib="$destdir/$realname"
+	  func_execute_cmds "$postinstall_cmds" 'exit $?'
+	fi
+
+	# Install the pseudo-library for information purposes.
+	func_basename "$file"
+	name="$func_basename_result"
+	instname="$dir/$name"i
+	func_show_eval "$install_prog $instname $destdir/$name" 'exit $?'
+
+	# Maybe install the static library, too.
+	test -n "$old_library" && func_append 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
+	  func_basename "$file"
+	  destfile="$func_basename_result"
+	  destfile="$destdir/$destfile"
+	fi
+
+	# Deduce the name of the destination old-style object file.
+	case $destfile in
+	*.lo)
+	  func_lo2o "$destfile"
+	  staticdest=$func_lo2o_result
+	  ;;
+	*.$objext)
+	  staticdest="$destfile"
+	  destfile=
+	  ;;
+	*)
+	  func_fatal_help "cannot copy a libtool object to \`$destfile'"
+	  ;;
+	esac
+
+	# Install the libtool object if requested.
+	test -n "$destfile" && \
+	  func_show_eval "$install_prog $file $destfile" 'exit $?'
+
+	# Install the old object if enabled.
+	if test "$build_old_libs" = yes; then
+	  # Deduce the name of the old-style object file.
+	  func_lo2o "$file"
+	  staticobj=$func_lo2o_result
+	  func_show_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
+	  func_basename "$file"
+	  destfile="$func_basename_result"
+	  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
+	      func_stripname '' '.exe' "$file"
+	      file=$func_stripname_result
+	      stripped_ext=".exe"
+	    fi
+	    ;;
+	esac
+
+	# Do a test to see if this is really a libtool program.
+	case $host in
+	*cygwin* | *mingw*)
+	    if func_ltwrapper_executable_p "$file"; then
+	      func_ltwrapper_scriptname "$file"
+	      wrapper=$func_ltwrapper_scriptname_result
+	    else
+	      func_stripname '' '.exe' "$file"
+	      wrapper=$func_stripname_result
+	    fi
+	    ;;
+	*)
+	    wrapper=$file
+	    ;;
+	esac
+	if func_ltwrapper_script_p "$wrapper"; then
+	  notinst_deplibs=
+	  relink_command=
+
+	  func_source "$wrapper"
+
+	  # Check the variables that should have been set.
+	  test -z "$generated_by_libtool_version" && \
+	    func_fatal_error "invalid libtool wrapper script \`$wrapper'"
+
+	  finalize=yes
+	  for lib in $notinst_deplibs; do
+	    # Check to see that each library is installed.
+	    libdir=
+	    if test -f "$lib"; then
+	      func_source "$lib"
+	    fi
+	    libfile="$libdir/"`$ECHO "$lib" | $SED 's%^.*/%%g'` ### testsuite: skip nested quoting test
+	    if test -n "$libdir" && test ! -f "$libfile"; then
+	      func_warning "\`$lib' has not been installed in \`$libdir'"
+	      finalize=no
+	    fi
+	  done
+
+	  relink_command=
+	  func_source "$wrapper"
+
+	  outputname=
+	  if test "$fast_install" = no && test -n "$relink_command"; then
+	    $opt_dry_run || {
+	      if test "$finalize" = yes; then
+	        tmpdir=`func_mktempdir`
+		func_basename "$file$stripped_ext"
+		file="$func_basename_result"
+	        outputname="$tmpdir/$file"
+	        # Replace the output file specification.
+	        relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'`
+
+	        $opt_silent || {
+	          func_quote_for_expand "$relink_command"
+		  eval "func_echo $func_quote_for_expand_result"
+	        }
+	        if eval "$relink_command"; then :
+	          else
+		  func_error "error: relink \`$file' with the above command before installing it"
+		  $opt_dry_run || ${RM}r "$tmpdir"
+		  continue
+	        fi
+	        file="$outputname"
+	      else
+	        func_warning "cannot relink \`$file'"
+	      fi
+	    }
+	  else
+	    # Install the binary that we compiled earlier.
+	    file=`$ECHO "$file$stripped_ext" | $SED "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)
+	    func_stripname '' '.exe' "$destfile"
+	    destfile=$func_stripname_result
+	    ;;
+	  esac
+	  ;;
+	esac
+	func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?'
+	$opt_dry_run || if test -n "$outputname"; then
+	  ${RM}r "$tmpdir"
+	fi
+	;;
+      esac
+    done
+
+    for file in $staticlibs; do
+      func_basename "$file"
+      name="$func_basename_result"
+
+      # Set up the ranlib parameters.
+      oldlib="$destdir/$name"
+      func_to_tool_file "$oldlib" func_convert_file_msys_to_w32
+      tool_oldlib=$func_to_tool_file_result
+
+      func_show_eval "$install_prog \$file \$oldlib" 'exit $?'
+
+      if test -n "$stripme" && test -n "$old_striplib"; then
+	func_show_eval "$old_striplib $tool_oldlib" 'exit $?'
+      fi
+
+      # Do each command in the postinstall commands.
+      func_execute_cmds "$old_postinstall_cmds" 'exit $?'
+    done
+
+    test -n "$future_libdirs" && \
+      func_warning "remember to run \`$progname --finish$future_libdirs'"
+
+    if test -n "$current_libdirs"; then
+      # Maybe just do a dry run.
+      $opt_dry_run && current_libdirs=" -n$current_libdirs"
+      exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs'
+    else
+      exit $EXIT_SUCCESS
+    fi
+}
+
+test "$opt_mode" = install && func_mode_install ${1+"$@"}
+
+
+# func_generate_dlsyms outputname originator pic_p
+# Extract symbols from dlprefiles and create ${outputname}S.o with
+# a dlpreopen symbol table.
+func_generate_dlsyms ()
+{
+    $opt_debug
+    my_outputname="$1"
+    my_originator="$2"
+    my_pic_p="${3-no}"
+    my_prefix=`$ECHO "$my_originator" | sed 's%[^a-zA-Z0-9]%_%g'`
+    my_dlsyms=
+
+    if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+      if test -n "$NM" && test -n "$global_symbol_pipe"; then
+	my_dlsyms="${my_outputname}S.c"
+      else
+	func_error "not configured to extract global symbols from dlpreopened files"
+      fi
+    fi
+
+    if test -n "$my_dlsyms"; then
+      case $my_dlsyms in
+      "") ;;
+      *.c)
+	# Discover the nlist of each of the dlfiles.
+	nlist="$output_objdir/${my_outputname}.nm"
+
+	func_show_eval "$RM $nlist ${nlist}S ${nlist}T"
+
+	# Parse the name list into a source file.
+	func_verbose "creating $output_objdir/$my_dlsyms"
+
+	$opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\
+/* $my_dlsyms - symbol resolution table for \`$my_outputname' dlsym emulation. */
+/* Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION */
+
+#ifdef __cplusplus
+extern \"C\" {
+#endif
+
+#if defined(__GNUC__) && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4))
+#pragma GCC diagnostic ignored \"-Wstrict-prototypes\"
+#endif
+
+/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests.  */
+#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE)
+/* DATA imports from DLLs on WIN32 con't be const, because runtime
+   relocations are performed -- see ld's documentation on pseudo-relocs.  */
+# define LT_DLSYM_CONST
+#elif defined(__osf__)
+/* This system does not cope well with relocations in const data.  */
+# define LT_DLSYM_CONST
+#else
+# define LT_DLSYM_CONST const
+#endif
+
+/* External symbol declarations for the compiler. */\
+"
+
+	if test "$dlself" = yes; then
+	  func_verbose "generating symbol list for \`$output'"
+
+	  $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist"
+
+	  # Add our own program objects to the symbol list.
+	  progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP`
+	  for progfile in $progfiles; do
+	    func_to_tool_file "$progfile" func_convert_file_msys_to_w32
+	    func_verbose "extracting global C symbols from \`$func_to_tool_file_result'"
+	    $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'"
+	  done
+
+	  if test -n "$exclude_expsyms"; then
+	    $opt_dry_run || {
+	      eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T'
+	      eval '$MV "$nlist"T "$nlist"'
+	    }
+	  fi
+
+	  if test -n "$export_symbols_regex"; then
+	    $opt_dry_run || {
+	      eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T'
+	      eval '$MV "$nlist"T "$nlist"'
+	    }
+	  fi
+
+	  # Prepare the list of exported symbols
+	  if test -z "$export_symbols"; then
+	    export_symbols="$output_objdir/$outputname.exp"
+	    $opt_dry_run || {
+	      $RM $export_symbols
+	      eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
+	      case $host in
+	      *cygwin* | *mingw* | *cegcc* )
+                eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
+                eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"'
+	        ;;
+	      esac
+	    }
+	  else
+	    $opt_dry_run || {
+	      eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"'
+	      eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T'
+	      eval '$MV "$nlist"T "$nlist"'
+	      case $host in
+	        *cygwin* | *mingw* | *cegcc* )
+	          eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
+	          eval 'cat "$nlist" >> "$output_objdir/$outputname.def"'
+	          ;;
+	      esac
+	    }
+	  fi
+	fi
+
+	for dlprefile in $dlprefiles; do
+	  func_verbose "extracting global C symbols from \`$dlprefile'"
+	  func_basename "$dlprefile"
+	  name="$func_basename_result"
+          case $host in
+	    *cygwin* | *mingw* | *cegcc* )
+	      # if an import library, we need to obtain dlname
+	      if func_win32_import_lib_p "$dlprefile"; then
+	        func_tr_sh "$dlprefile"
+	        eval "curr_lafile=\$libfile_$func_tr_sh_result"
+	        dlprefile_dlbasename=""
+	        if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then
+	          # Use subshell, to avoid clobbering current variable values
+	          dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"`
+	          if test -n "$dlprefile_dlname" ; then
+	            func_basename "$dlprefile_dlname"
+	            dlprefile_dlbasename="$func_basename_result"
+	          else
+	            # no lafile. user explicitly requested -dlpreopen <import library>.
+	            $sharedlib_from_linklib_cmd "$dlprefile"
+	            dlprefile_dlbasename=$sharedlib_from_linklib_result
+	          fi
+	        fi
+	        $opt_dry_run || {
+	          if test -n "$dlprefile_dlbasename" ; then
+	            eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"'
+	          else
+	            func_warning "Could not compute DLL name from $name"
+	            eval '$ECHO ": $name " >> "$nlist"'
+	          fi
+	          func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
+	          eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe |
+	            $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'"
+	        }
+	      else # not an import lib
+	        $opt_dry_run || {
+	          eval '$ECHO ": $name " >> "$nlist"'
+	          func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
+	          eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'"
+	        }
+	      fi
+	    ;;
+	    *)
+	      $opt_dry_run || {
+	        eval '$ECHO ": $name " >> "$nlist"'
+	        func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
+	        eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'"
+	      }
+	    ;;
+          esac
+	done
+
+	$opt_dry_run || {
+	  # 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/$my_dlsyms"'
+	  else
+	    echo '/* NONE */' >> "$output_objdir/$my_dlsyms"
+	  fi
+
+	  echo >> "$output_objdir/$my_dlsyms" "\
+
+/* The mapping between symbol names and symbols.  */
+typedef struct {
+  const char *name;
+  void *address;
+} lt_dlsymlist;
+extern LT_DLSYM_CONST lt_dlsymlist
+lt_${my_prefix}_LTX_preloaded_symbols[];
+LT_DLSYM_CONST lt_dlsymlist
+lt_${my_prefix}_LTX_preloaded_symbols[] =
+{\
+  { \"$my_originator\", (void *) 0 },"
+
+	  case $need_lib_prefix in
+	  no)
+	    eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms"
+	    ;;
+	  *)
+	    eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms"
+	    ;;
+	  esac
+	  echo >> "$output_objdir/$my_dlsyms" "\
+  {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+  return lt_${my_prefix}_LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif\
+"
+	} # !$opt_dry_run
+
+	pic_flag_for_symtable=
+	case "$compile_command " in
+	*" -static "*) ;;
+	*)
+	  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*)
+	    pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;;
+	  *-*-hpux*)
+	    pic_flag_for_symtable=" $pic_flag"  ;;
+	  *)
+	    if test "X$my_pic_p" != Xno; then
+	      pic_flag_for_symtable=" $pic_flag"
+	    fi
+	    ;;
+	  esac
+	  ;;
+	esac
+	symtab_cflags=
+	for arg in $LTCFLAGS; do
+	  case $arg in
+	  -pie | -fpie | -fPIE) ;;
+	  *) func_append symtab_cflags " $arg" ;;
+	  esac
+	done
+
+	# Now compile the dynamic symbol file.
+	func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?'
+
+	# Clean up the generated files.
+	func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T"'
+
+	# Transform the symbol file into the correct name.
+	symfileobj="$output_objdir/${my_outputname}S.$objext"
+	case $host in
+	*cygwin* | *mingw* | *cegcc* )
+	  if test -f "$output_objdir/$my_outputname.def"; then
+	    compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"`
+	    finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"`
+	  else
+	    compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+	    finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+	  fi
+	  ;;
+	*)
+	  compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+	  finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+	  ;;
+	esac
+	;;
+      *)
+	func_fatal_error "unknown suffix for \`$my_dlsyms'"
+	;;
+      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 "$compile_command" | $SED "s% @SYMFILE@%%"`
+      finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"`
+    fi
+}
+
+# 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.
+# Despite the name, also deal with 64 bit binaries.
+func_win32_libid ()
+{
+  $opt_debug
+  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
+    # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD.
+    if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null |
+       $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then
+      func_to_tool_file "$1" func_convert_file_msys_to_w32
+      win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" |
+	$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_cygming_dll_for_implib ARG
+#
+# Platform-specific function to extract the
+# name of the DLL associated with the specified
+# import library ARG.
+# Invoked by eval'ing the libtool variable
+#    $sharedlib_from_linklib_cmd
+# Result is available in the variable
+#    $sharedlib_from_linklib_result
+func_cygming_dll_for_implib ()
+{
+  $opt_debug
+  sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"`
+}
+
+# func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs
+#
+# The is the core of a fallback implementation of a
+# platform-specific function to extract the name of the
+# DLL associated with the specified import library LIBNAME.
+#
+# SECTION_NAME is either .idata$6 or .idata$7, depending
+# on the platform and compiler that created the implib.
+#
+# Echos the name of the DLL associated with the
+# specified import library.
+func_cygming_dll_for_implib_fallback_core ()
+{
+  $opt_debug
+  match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"`
+  $OBJDUMP -s --section "$1" "$2" 2>/dev/null |
+    $SED '/^Contents of section '"$match_literal"':/{
+      # Place marker at beginning of archive member dllname section
+      s/.*/====MARK====/
+      p
+      d
+    }
+    # These lines can sometimes be longer than 43 characters, but
+    # are always uninteresting
+    /:[	 ]*file format pe[i]\{,1\}-/d
+    /^In archive [^:]*:/d
+    # Ensure marker is printed
+    /^====MARK====/p
+    # Remove all lines with less than 43 characters
+    /^.\{43\}/!d
+    # From remaining lines, remove first 43 characters
+    s/^.\{43\}//' |
+    $SED -n '
+      # Join marker and all lines until next marker into a single line
+      /^====MARK====/ b para
+      H
+      $ b para
+      b
+      :para
+      x
+      s/\n//g
+      # Remove the marker
+      s/^====MARK====//
+      # Remove trailing dots and whitespace
+      s/[\. \t]*$//
+      # Print
+      /./p' |
+    # we now have a list, one entry per line, of the stringified
+    # contents of the appropriate section of all members of the
+    # archive which possess that section. Heuristic: eliminate
+    # all those which have a first or second character that is
+    # a '.' (that is, objdump's representation of an unprintable
+    # character.) This should work for all archives with less than
+    # 0x302f exports -- but will fail for DLLs whose name actually
+    # begins with a literal '.' or a single character followed by
+    # a '.'.
+    #
+    # Of those that remain, print the first one.
+    $SED -e '/^\./d;/^.\./d;q'
+}
+
+# func_cygming_gnu_implib_p ARG
+# This predicate returns with zero status (TRUE) if
+# ARG is a GNU/binutils-style import library. Returns
+# with nonzero status (FALSE) otherwise.
+func_cygming_gnu_implib_p ()
+{
+  $opt_debug
+  func_to_tool_file "$1" func_convert_file_msys_to_w32
+  func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'`
+  test -n "$func_cygming_gnu_implib_tmp"
+}
+
+# func_cygming_ms_implib_p ARG
+# This predicate returns with zero status (TRUE) if
+# ARG is an MS-style import library. Returns
+# with nonzero status (FALSE) otherwise.
+func_cygming_ms_implib_p ()
+{
+  $opt_debug
+  func_to_tool_file "$1" func_convert_file_msys_to_w32
+  func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'`
+  test -n "$func_cygming_ms_implib_tmp"
+}
+
+# func_cygming_dll_for_implib_fallback ARG
+# Platform-specific function to extract the
+# name of the DLL associated with the specified
+# import library ARG.
+#
+# This fallback implementation is for use when $DLLTOOL
+# does not support the --identify-strict option.
+# Invoked by eval'ing the libtool variable
+#    $sharedlib_from_linklib_cmd
+# Result is available in the variable
+#    $sharedlib_from_linklib_result
+func_cygming_dll_for_implib_fallback ()
+{
+  $opt_debug
+  if func_cygming_gnu_implib_p "$1" ; then
+    # binutils import library
+    sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"`
+  elif func_cygming_ms_implib_p "$1" ; then
+    # ms-generated import library
+    sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"`
+  else
+    # unknown
+    sharedlib_from_linklib_result=""
+  fi
+}
+
+
+# func_extract_an_archive dir oldlib
+func_extract_an_archive ()
+{
+    $opt_debug
+    f_ex_an_ar_dir="$1"; shift
+    f_ex_an_ar_oldlib="$1"
+    if test "$lock_old_archive_extraction" = yes; then
+      lockfile=$f_ex_an_ar_oldlib.lock
+      until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do
+	func_echo "Waiting for $lockfile to be removed"
+	sleep 2
+      done
+    fi
+    func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \
+		   'stat=$?; rm -f "$lockfile"; exit $stat'
+    if test "$lock_old_archive_extraction" = yes; then
+      $opt_dry_run || rm -f "$lockfile"
+    fi
+    if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then
+     :
+    else
+      func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib"
+    fi
+}
+
+
+# func_extract_archives gentop oldlib ...
+func_extract_archives ()
+{
+    $opt_debug
+    my_gentop="$1"; shift
+    my_oldlibs=${1+"$@"}
+    my_oldobjs=""
+    my_xlib=""
+    my_xabs=""
+    my_xdir=""
+
+    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
+      func_basename "$my_xlib"
+      my_xlib="$func_basename_result"
+      my_xlib_u=$my_xlib
+      while :; do
+        case " $extracted_archives " in
+	*" $my_xlib_u "*)
+	  func_arith $extracted_serial + 1
+	  extracted_serial=$func_arith_result
+	  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"
+
+      func_mkdir_p "$my_xdir"
+
+      case $host in
+      *-darwin*)
+	func_verbose "Extracting $my_xabs"
+	# Do not bother doing anything if just a dry run
+	$opt_dry_run || {
+	  darwin_orig_dir=`pwd`
+	  cd $my_xdir || exit $?
+	  darwin_archive=$my_xabs
+	  darwin_curdir=`pwd`
+	  darwin_base_archive=`basename "$darwin_archive"`
+	  darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true`
+	  if test -n "$darwin_arches"; then
+	    darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'`
+	    darwin_arch=
+	    func_verbose "$darwin_base_archive has multiple architectures $darwin_arches"
+	    for darwin_arch in  $darwin_arches ; do
+	      func_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've a bunch of thin objects, gotta fatten them up :)
+	    darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$basename" | sort -u`
+	    darwin_file=
+	    darwin_files=
+	    for darwin_file in $darwin_filelist; do
+	      darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP`
+	      $LIPO -create -output "$darwin_file" $darwin_files
+	    done # $darwin_filelist
+	    $RM -rf unfat-$$
+	    cd "$darwin_orig_dir"
+	  else
+	    cd $darwin_orig_dir
+	    func_extract_an_archive "$my_xdir" "$my_xabs"
+	  fi # $darwin_arches
+	} # !$opt_dry_run
+	;;
+      *)
+        func_extract_an_archive "$my_xdir" "$my_xabs"
+	;;
+      esac
+      my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP`
+    done
+
+    func_extract_archives_result="$my_oldobjs"
+}
+
+
+# func_emit_wrapper [arg=no]
+#
+# Emit a libtool wrapper script on stdout.
+# Don't directly open a file because we may want to
+# incorporate the script contents within a cygwin/mingw
+# wrapper executable.  Must ONLY be called from within
+# func_mode_link because it depends on a number of variables
+# set therein.
+#
+# ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR
+# variable will take.  If 'yes', then the emitted script
+# will assume that the directory in which it is stored is
+# the $objdir directory.  This is a cygwin/mingw-specific
+# behavior.
+func_emit_wrapper ()
+{
+	func_emit_wrapper_arg1=${1-no}
+
+	$ECHO "\
+#! $SHELL
+
+# $output - temporary wrapper script for $objdir/$outputname
+# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
+#
+# 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.
+sed_quote_subst='$sed_quote_subst'
+
+# Be 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 variables:
+  generated_by_libtool_version='$macro_version'
+  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
+    file=\"\$0\""
+
+    qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"`
+    $ECHO "\
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+  eval 'cat <<_LTECHO_EOF
+\$1
+_LTECHO_EOF'
+}
+    ECHO=\"$qECHO\"
+  fi
+
+# Very basic option parsing. These options are (a) specific to
+# the libtool wrapper, (b) are identical between the wrapper
+# /script/ and the wrapper /executable/ which is used only on
+# windows platforms, and (c) all begin with the string "--lt-"
+# (application programs are unlikely to have options which match
+# this pattern).
+#
+# There are only two supported options: --lt-debug and
+# --lt-dump-script. There is, deliberately, no --lt-help.
+#
+# The first argument to this parsing function should be the
+# script's $0 value, followed by "$@".
+lt_option_debug=
+func_parse_lt_options ()
+{
+  lt_script_arg0=\$0
+  shift
+  for lt_opt
+  do
+    case \"\$lt_opt\" in
+    --lt-debug) lt_option_debug=1 ;;
+    --lt-dump-script)
+        lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\`
+        test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=.
+        lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\`
+        cat \"\$lt_dump_D/\$lt_dump_F\"
+        exit 0
+      ;;
+    --lt-*)
+        \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2
+        exit 1
+      ;;
+    esac
+  done
+
+  # Print the debug banner immediately:
+  if test -n \"\$lt_option_debug\"; then
+    echo \"${outputname}:${output}:\${LINENO}: libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\" 1>&2
+  fi
+}
+
+# Used when --lt-debug. Prints its arguments to stdout
+# (redirection is the responsibility of the caller)
+func_lt_dump_args ()
+{
+  lt_dump_args_N=1;
+  for lt_arg
+  do
+    \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[\$lt_dump_args_N]: \$lt_arg\"
+    lt_dump_args_N=\`expr \$lt_dump_args_N + 1\`
+  done
+}
+
+# Core function for launching the target application
+func_exec_program_core ()
+{
+"
+  case $host in
+  # Backslashes separate directories on plain windows
+  *-*-mingw | *-*-os2* | *-cegcc*)
+    $ECHO "\
+      if test -n \"\$lt_option_debug\"; then
+        \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir\\\\\$program\" 1>&2
+        func_lt_dump_args \${1+\"\$@\"} 1>&2
+      fi
+      exec \"\$progdir\\\\\$program\" \${1+\"\$@\"}
+"
+    ;;
+
+  *)
+    $ECHO "\
+      if test -n \"\$lt_option_debug\"; then
+        \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir/\$program\" 1>&2
+        func_lt_dump_args \${1+\"\$@\"} 1>&2
+      fi
+      exec \"\$progdir/\$program\" \${1+\"\$@\"}
+"
+    ;;
+  esac
+  $ECHO "\
+      \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2
+      exit 1
+}
+
+# A function to encapsulate launching the target application
+# Strips options in the --lt-* namespace from \$@ and
+# launches target application with the remaining arguments.
+func_exec_program ()
+{
+  case \" \$* \" in
+  *\\ --lt-*)
+    for lt_wr_arg
+    do
+      case \$lt_wr_arg in
+      --lt-*) ;;
+      *) set x \"\$@\" \"\$lt_wr_arg\"; shift;;
+      esac
+      shift
+    done ;;
+  esac
+  func_exec_program_core \${1+\"\$@\"}
+}
+
+  # Parse options
+  func_parse_lt_options \"\$0\" \${1+\"\$@\"}
+
+  # Find the directory that this script lives in.
+  thisdir=\`\$ECHO \"\$file\" | $SED '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 \"\$file\" | $SED '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 \"\$file\" | $SED 's%^.*/%%'\`
+    file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\`
+  done
+
+  # Usually 'no', except on cygwin/mingw when embedded into
+  # the cwrapper.
+  WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1
+  if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then
+    # special case for '.'
+    if test \"\$thisdir\" = \".\"; then
+      thisdir=\`pwd\`
+    fi
+    # remove .libs from thisdir
+    case \"\$thisdir\" in
+    *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;;
+    $objdir )   thisdir=. ;;
+    esac
+  fi
+
+  # Try to get the absolute directory name.
+  absdir=\`cd \"\$thisdir\" && pwd\`
+  test -n \"\$absdir\" && thisdir=\"\$absdir\"
+"
+
+	if test "$fast_install" = yes; then
+	  $ECHO "\
+  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 "\
+
+    # 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 1
+      fi
+    fi
+
+    $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null ||
+    { $RM \"\$progdir/\$program\";
+      $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; }
+    $RM \"\$progdir/\$file\"
+  fi"
+	else
+	  $ECHO "\
+  program='$outputname'
+  progdir=\"\$thisdir/$objdir\"
+"
+	fi
+
+	$ECHO "\
+
+  if test -f \"\$progdir/\$program\"; then"
+
+	# fixup the dll searchpath if we need to.
+	#
+	# Fix the DLL searchpath if we need to.  Do this before prepending
+	# to shlibpath, because on Windows, both are PATH and uninstalled
+	# libraries must come first.
+	if test -n "$dllsearchpath"; then
+	  $ECHO "\
+    # Add the dll search path components to the executable PATH
+    PATH=$dllsearchpath:\$PATH
+"
+	fi
+
+	# Export our shlibpath_var if we have one.
+	if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+	  $ECHO "\
+    # 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 \"\$$shlibpath_var\" | $SED 's/::*\$//'\`
+
+    export $shlibpath_var
+"
+	fi
+
+	$ECHO "\
+    if test \"\$libtool_execute_magic\" != \"$magic\"; then
+      # Run the actual program with our arguments.
+      func_exec_program \${1+\"\$@\"}
+    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 1
+  fi
+fi\
+"
+}
+
+
+# func_emit_cwrapperexe_src
+# emit the source code for a wrapper executable on stdout
+# Must ONLY be called from within func_mode_link because
+# it depends on a number of variable set therein.
+func_emit_cwrapperexe_src ()
+{
+	cat <<EOF
+
+/* $cwrappersource - temporary wrapper executable for $objdir/$outputname
+   Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
+
+   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.
+*/
+EOF
+	    cat <<"EOF"
+#ifdef _MSC_VER
+# define _CRT_SECURE_NO_DEPRECATE 1
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef _MSC_VER
+# include <direct.h>
+# include <process.h>
+# include <io.h>
+#else
+# include <unistd.h>
+# include <stdint.h>
+# ifdef __CYGWIN__
+#  include <io.h>
+# endif
+#endif
+#include <malloc.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+/* declarations of non-ANSI functions */
+#if defined(__MINGW32__)
+# ifdef __STRICT_ANSI__
+int _putenv (const char *);
+# endif
+#elif defined(__CYGWIN__)
+# ifdef __STRICT_ANSI__
+char *realpath (const char *, char *);
+int putenv (char *);
+int setenv (const char *, const char *, int);
+# endif
+/* #elif defined (other platforms) ... */
+#endif
+
+/* portability defines, excluding path handling macros */
+#if defined(_MSC_VER)
+# define setmode _setmode
+# define stat    _stat
+# define chmod   _chmod
+# define getcwd  _getcwd
+# define putenv  _putenv
+# define S_IXUSR _S_IEXEC
+# ifndef _INTPTR_T_DEFINED
+#  define _INTPTR_T_DEFINED
+#  define intptr_t int
+# endif
+#elif defined(__MINGW32__)
+# define setmode _setmode
+# define stat    _stat
+# define chmod   _chmod
+# define getcwd  _getcwd
+# define putenv  _putenv
+#elif defined(__CYGWIN__)
+# define HAVE_SETENV
+# define FOPEN_WB "wb"
+/* #elif defined (other platforms) ... */
+#endif
+
+#if defined(PATH_MAX)
+# define LT_PATHMAX PATH_MAX
+#elif defined(MAXPATHLEN)
+# define LT_PATHMAX MAXPATHLEN
+#else
+# define LT_PATHMAX 1024
+#endif
+
+#ifndef S_IXOTH
+# define S_IXOTH 0
+#endif
+#ifndef S_IXGRP
+# define S_IXGRP 0
+#endif
+
+/* path handling portability macros */
+#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
+# define FOPEN_WB "wb"
+# 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 */
+
+#ifndef FOPEN_WB
+# define FOPEN_WB "w"
+#endif
+#ifndef _O_BINARY
+# define _O_BINARY 0
+#endif
+
+#define XMALLOC(type, num)      ((type *) xmalloc ((num) * sizeof(type)))
+#define XFREE(stale) do { \
+  if (stale) { free ((void *) stale); stale = 0; } \
+} while (0)
+
+#if defined(LT_DEBUGWRAPPER)
+static int lt_debug = 1;
+#else
+static int lt_debug = 0;
+#endif
+
+const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */
+
+void *xmalloc (size_t num);
+char *xstrdup (const char *string);
+const char *base_name (const char *name);
+char *find_executable (const char *wrapper);
+char *chase_symlinks (const char *pathspec);
+int make_executable (const char *path);
+int check_executable (const char *path);
+char *strendzap (char *str, const char *pat);
+void lt_debugprintf (const char *file, int line, const char *fmt, ...);
+void lt_fatal (const char *file, int line, const char *message, ...);
+static const char *nonnull (const char *s);
+static const char *nonempty (const char *s);
+void lt_setenv (const char *name, const char *value);
+char *lt_extend_str (const char *orig_value, const char *add, int to_end);
+void lt_update_exe_path (const char *name, const char *value);
+void lt_update_lib_path (const char *name, const char *value);
+char **prepare_spawn (char **argv);
+void lt_dump_script (FILE *f);
+EOF
+
+	    cat <<EOF
+volatile const char * MAGIC_EXE = "$magic_exe";
+const char * LIB_PATH_VARNAME = "$shlibpath_var";
+EOF
+
+	    if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+              func_to_host_path "$temp_rpath"
+	      cat <<EOF
+const char * LIB_PATH_VALUE   = "$func_to_host_path_result";
+EOF
+	    else
+	      cat <<"EOF"
+const char * LIB_PATH_VALUE   = "";
+EOF
+	    fi
+
+	    if test -n "$dllsearchpath"; then
+              func_to_host_path "$dllsearchpath:"
+	      cat <<EOF
+const char * EXE_PATH_VARNAME = "PATH";
+const char * EXE_PATH_VALUE   = "$func_to_host_path_result";
+EOF
+	    else
+	      cat <<"EOF"
+const char * EXE_PATH_VARNAME = "";
+const char * EXE_PATH_VALUE   = "";
+EOF
+	    fi
+
+	    if test "$fast_install" = yes; then
+	      cat <<EOF
+const char * TARGET_PROGRAM_NAME = "lt-$outputname"; /* hopefully, no .exe */
+EOF
+	    else
+	      cat <<EOF
+const char * TARGET_PROGRAM_NAME = "$outputname"; /* hopefully, no .exe */
+EOF
+	    fi
+
+
+	    cat <<"EOF"
+
+#define LTWRAPPER_OPTION_PREFIX         "--lt-"
+
+static const char *ltwrapper_option_prefix = LTWRAPPER_OPTION_PREFIX;
+static const char *dumpscript_opt       = LTWRAPPER_OPTION_PREFIX "dump-script";
+static const char *debug_opt            = LTWRAPPER_OPTION_PREFIX "debug";
+
+int
+main (int argc, char *argv[])
+{
+  char **newargz;
+  int  newargc;
+  char *tmp_pathspec;
+  char *actual_cwrapper_path;
+  char *actual_cwrapper_name;
+  char *target_name;
+  char *lt_argv_zero;
+  intptr_t rval = 127;
+
+  int i;
+
+  program_name = (char *) xstrdup (base_name (argv[0]));
+  newargz = XMALLOC (char *, argc + 1);
+
+  /* very simple arg parsing; don't want to rely on getopt
+   * also, copy all non cwrapper options to newargz, except
+   * argz[0], which is handled differently
+   */
+  newargc=0;
+  for (i = 1; i < argc; i++)
+    {
+      if (strcmp (argv[i], dumpscript_opt) == 0)
+	{
+EOF
+	    case "$host" in
+	      *mingw* | *cygwin* )
+		# make stdout use "unix" line endings
+		echo "          setmode(1,_O_BINARY);"
+		;;
+	      esac
+
+	    cat <<"EOF"
+	  lt_dump_script (stdout);
+	  return 0;
+	}
+      if (strcmp (argv[i], debug_opt) == 0)
+	{
+          lt_debug = 1;
+          continue;
+	}
+      if (strcmp (argv[i], ltwrapper_option_prefix) == 0)
+        {
+          /* however, if there is an option in the LTWRAPPER_OPTION_PREFIX
+             namespace, but it is not one of the ones we know about and
+             have already dealt with, above (inluding dump-script), then
+             report an error. Otherwise, targets might begin to believe
+             they are allowed to use options in the LTWRAPPER_OPTION_PREFIX
+             namespace. The first time any user complains about this, we'll
+             need to make LTWRAPPER_OPTION_PREFIX a configure-time option
+             or a configure.ac-settable value.
+           */
+          lt_fatal (__FILE__, __LINE__,
+		    "unrecognized %s option: '%s'",
+                    ltwrapper_option_prefix, argv[i]);
+        }
+      /* otherwise ... */
+      newargz[++newargc] = xstrdup (argv[i]);
+    }
+  newargz[++newargc] = NULL;
+
+EOF
+	    cat <<EOF
+  /* The GNU banner must be the first non-error debug message */
+  lt_debugprintf (__FILE__, __LINE__, "libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\n");
+EOF
+	    cat <<"EOF"
+  lt_debugprintf (__FILE__, __LINE__, "(main) argv[0]: %s\n", argv[0]);
+  lt_debugprintf (__FILE__, __LINE__, "(main) program_name: %s\n", program_name);
+
+  tmp_pathspec = find_executable (argv[0]);
+  if (tmp_pathspec == NULL)
+    lt_fatal (__FILE__, __LINE__, "couldn't find %s", argv[0]);
+  lt_debugprintf (__FILE__, __LINE__,
+                  "(main) found exe (before symlink chase) at: %s\n",
+		  tmp_pathspec);
+
+  actual_cwrapper_path = chase_symlinks (tmp_pathspec);
+  lt_debugprintf (__FILE__, __LINE__,
+                  "(main) found exe (after symlink chase) at: %s\n",
+		  actual_cwrapper_path);
+  XFREE (tmp_pathspec);
+
+  actual_cwrapper_name = xstrdup (base_name (actual_cwrapper_path));
+  strendzap (actual_cwrapper_path, actual_cwrapper_name);
+
+  /* wrapper name transforms */
+  strendzap (actual_cwrapper_name, ".exe");
+  tmp_pathspec = lt_extend_str (actual_cwrapper_name, ".exe", 1);
+  XFREE (actual_cwrapper_name);
+  actual_cwrapper_name = tmp_pathspec;
+  tmp_pathspec = 0;
+
+  /* target_name transforms -- use actual target program name; might have lt- prefix */
+  target_name = xstrdup (base_name (TARGET_PROGRAM_NAME));
+  strendzap (target_name, ".exe");
+  tmp_pathspec = lt_extend_str (target_name, ".exe", 1);
+  XFREE (target_name);
+  target_name = tmp_pathspec;
+  tmp_pathspec = 0;
+
+  lt_debugprintf (__FILE__, __LINE__,
+		  "(main) libtool target name: %s\n",
+		  target_name);
+EOF
+
+	    cat <<EOF
+  newargz[0] =
+    XMALLOC (char, (strlen (actual_cwrapper_path) +
+		    strlen ("$objdir") + 1 + strlen (actual_cwrapper_name) + 1));
+  strcpy (newargz[0], actual_cwrapper_path);
+  strcat (newargz[0], "$objdir");
+  strcat (newargz[0], "/");
+EOF
+
+	    cat <<"EOF"
+  /* stop here, and copy so we don't have to do this twice */
+  tmp_pathspec = xstrdup (newargz[0]);
+
+  /* do NOT want the lt- prefix here, so use actual_cwrapper_name */
+  strcat (newargz[0], actual_cwrapper_name);
+
+  /* DO want the lt- prefix here if it exists, so use target_name */
+  lt_argv_zero = lt_extend_str (tmp_pathspec, target_name, 1);
+  XFREE (tmp_pathspec);
+  tmp_pathspec = NULL;
+EOF
+
+	    case $host_os in
+	      mingw*)
+	    cat <<"EOF"
+  {
+    char* p;
+    while ((p = strchr (newargz[0], '\\')) != NULL)
+      {
+	*p = '/';
+      }
+    while ((p = strchr (lt_argv_zero, '\\')) != NULL)
+      {
+	*p = '/';
+      }
+  }
+EOF
+	    ;;
+	    esac
+
+	    cat <<"EOF"
+  XFREE (target_name);
+  XFREE (actual_cwrapper_path);
+  XFREE (actual_cwrapper_name);
+
+  lt_setenv ("BIN_SH", "xpg4"); /* for Tru64 */
+  lt_setenv ("DUALCASE", "1");  /* for MSK sh */
+  /* Update the DLL searchpath.  EXE_PATH_VALUE ($dllsearchpath) must
+     be prepended before (that is, appear after) LIB_PATH_VALUE ($temp_rpath)
+     because on Windows, both *_VARNAMEs are PATH but uninstalled
+     libraries must come first. */
+  lt_update_exe_path (EXE_PATH_VARNAME, EXE_PATH_VALUE);
+  lt_update_lib_path (LIB_PATH_VARNAME, LIB_PATH_VALUE);
+
+  lt_debugprintf (__FILE__, __LINE__, "(main) lt_argv_zero: %s\n",
+		  nonnull (lt_argv_zero));
+  for (i = 0; i < newargc; i++)
+    {
+      lt_debugprintf (__FILE__, __LINE__, "(main) newargz[%d]: %s\n",
+		      i, nonnull (newargz[i]));
+    }
+
+EOF
+
+	    case $host_os in
+	      mingw*)
+		cat <<"EOF"
+  /* execv doesn't actually work on mingw as expected on unix */
+  newargz = prepare_spawn (newargz);
+  rval = _spawnv (_P_WAIT, lt_argv_zero, (const char * const *) newargz);
+  if (rval == -1)
+    {
+      /* failed to start process */
+      lt_debugprintf (__FILE__, __LINE__,
+		      "(main) failed to launch target \"%s\": %s\n",
+		      lt_argv_zero, nonnull (strerror (errno)));
+      return 127;
+    }
+  return rval;
+EOF
+		;;
+	      *)
+		cat <<"EOF"
+  execv (lt_argv_zero, newargz);
+  return rval; /* =127, but avoids unused variable warning */
+EOF
+		;;
+	    esac
+
+	    cat <<"EOF"
+}
+
+void *
+xmalloc (size_t num)
+{
+  void *p = (void *) malloc (num);
+  if (!p)
+    lt_fatal (__FILE__, __LINE__, "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;
+
+  lt_debugprintf (__FILE__, __LINE__, "(check_executable): %s\n",
+                  nonempty (path));
+  if ((!path) || (!*path))
+    return 0;
+
+  if ((stat (path, &st) >= 0)
+      && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)))
+    return 1;
+  else
+    return 0;
+}
+
+int
+make_executable (const char *path)
+{
+  int rval = 0;
+  struct stat st;
+
+  lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n",
+                  nonempty (path));
+  if ((!path) || (!*path))
+    return 0;
+
+  if (stat (path, &st) >= 0)
+    {
+      rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR);
+    }
+  return rval;
+}
+
+/* Searches for the full path of the wrapper.  Returns
+   newly allocated full path name if found, NULL otherwise
+   Does not chase symlinks, even on platforms that support them.
+*/
+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;
+
+  lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n",
+                  nonempty (wrapper));
+
+  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 (__FILE__, __LINE__, "getcwd failed: %s",
+                              nonnull (strerror (errno)));
+		  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 (__FILE__, __LINE__, "getcwd failed: %s",
+              nonnull (strerror (errno)));
+  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 *
+chase_symlinks (const char *pathspec)
+{
+#ifndef S_ISLNK
+  return xstrdup (pathspec);
+#else
+  char buf[LT_PATHMAX];
+  struct stat s;
+  char *tmp_pathspec = xstrdup (pathspec);
+  char *p;
+  int has_symlinks = 0;
+  while (strlen (tmp_pathspec) && !has_symlinks)
+    {
+      lt_debugprintf (__FILE__, __LINE__,
+		      "checking path component for symlinks: %s\n",
+		      tmp_pathspec);
+      if (lstat (tmp_pathspec, &s) == 0)
+	{
+	  if (S_ISLNK (s.st_mode) != 0)
+	    {
+	      has_symlinks = 1;
+	      break;
+	    }
+
+	  /* search backwards for last DIR_SEPARATOR */
+	  p = tmp_pathspec + strlen (tmp_pathspec) - 1;
+	  while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p)))
+	    p--;
+	  if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p)))
+	    {
+	      /* no more DIR_SEPARATORS left */
+	      break;
+	    }
+	  *p = '\0';
+	}
+      else
+	{
+	  lt_fatal (__FILE__, __LINE__,
+		    "error accessing file \"%s\": %s",
+		    tmp_pathspec, nonnull (strerror (errno)));
+	}
+    }
+  XFREE (tmp_pathspec);
+
+  if (!has_symlinks)
+    {
+      return xstrdup (pathspec);
+    }
+
+  tmp_pathspec = realpath (pathspec, buf);
+  if (tmp_pathspec == 0)
+    {
+      lt_fatal (__FILE__, __LINE__,
+		"could not follow symlinks for %s", pathspec);
+    }
+  return xstrdup (tmp_pathspec);
+#endif
+}
+
+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;
+}
+
+void
+lt_debugprintf (const char *file, int line, const char *fmt, ...)
+{
+  va_list args;
+  if (lt_debug)
+    {
+      (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line);
+      va_start (args, fmt);
+      (void) vfprintf (stderr, fmt, args);
+      va_end (args);
+    }
+}
+
+static void
+lt_error_core (int exit_status, const char *file,
+	       int line, const char *mode,
+	       const char *message, va_list ap)
+{
+  fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode);
+  vfprintf (stderr, message, ap);
+  fprintf (stderr, ".\n");
+
+  if (exit_status >= 0)
+    exit (exit_status);
+}
+
+void
+lt_fatal (const char *file, int line, const char *message, ...)
+{
+  va_list ap;
+  va_start (ap, message);
+  lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap);
+  va_end (ap);
+}
+
+static const char *
+nonnull (const char *s)
+{
+  return s ? s : "(null)";
+}
+
+static const char *
+nonempty (const char *s)
+{
+  return (s && !*s) ? "(empty)" : nonnull (s);
+}
+
+void
+lt_setenv (const char *name, const char *value)
+{
+  lt_debugprintf (__FILE__, __LINE__,
+		  "(lt_setenv) setting '%s' to '%s'\n",
+                  nonnull (name), nonnull (value));
+  {
+#ifdef HAVE_SETENV
+    /* always make a copy, for consistency with !HAVE_SETENV */
+    char *str = xstrdup (value);
+    setenv (name, str, 1);
+#else
+    int len = strlen (name) + 1 + strlen (value) + 1;
+    char *str = XMALLOC (char, len);
+    sprintf (str, "%s=%s", name, value);
+    if (putenv (str) != EXIT_SUCCESS)
+      {
+        XFREE (str);
+      }
+#endif
+  }
+}
+
+char *
+lt_extend_str (const char *orig_value, const char *add, int to_end)
+{
+  char *new_value;
+  if (orig_value && *orig_value)
+    {
+      int orig_value_len = strlen (orig_value);
+      int add_len = strlen (add);
+      new_value = XMALLOC (char, add_len + orig_value_len + 1);
+      if (to_end)
+        {
+          strcpy (new_value, orig_value);
+          strcpy (new_value + orig_value_len, add);
+        }
+      else
+        {
+          strcpy (new_value, add);
+          strcpy (new_value + add_len, orig_value);
+        }
+    }
+  else
+    {
+      new_value = xstrdup (add);
+    }
+  return new_value;
+}
+
+void
+lt_update_exe_path (const char *name, const char *value)
+{
+  lt_debugprintf (__FILE__, __LINE__,
+		  "(lt_update_exe_path) modifying '%s' by prepending '%s'\n",
+                  nonnull (name), nonnull (value));
+
+  if (name && *name && value && *value)
+    {
+      char *new_value = lt_extend_str (getenv (name), value, 0);
+      /* some systems can't cope with a ':'-terminated path #' */
+      int len = strlen (new_value);
+      while (((len = strlen (new_value)) > 0) && IS_PATH_SEPARATOR (new_value[len-1]))
+        {
+          new_value[len-1] = '\0';
+        }
+      lt_setenv (name, new_value);
+      XFREE (new_value);
+    }
+}
+
+void
+lt_update_lib_path (const char *name, const char *value)
+{
+  lt_debugprintf (__FILE__, __LINE__,
+		  "(lt_update_lib_path) modifying '%s' by prepending '%s'\n",
+                  nonnull (name), nonnull (value));
+
+  if (name && *name && value && *value)
+    {
+      char *new_value = lt_extend_str (getenv (name), value, 0);
+      lt_setenv (name, new_value);
+      XFREE (new_value);
+    }
+}
+
+EOF
+	    case $host_os in
+	      mingw*)
+		cat <<"EOF"
+
+/* Prepares an argument vector before calling spawn().
+   Note that spawn() does not by itself call the command interpreter
+     (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") :
+      ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+         GetVersionEx(&v);
+         v.dwPlatformId == VER_PLATFORM_WIN32_NT;
+      }) ? "cmd.exe" : "command.com").
+   Instead it simply concatenates the arguments, separated by ' ', and calls
+   CreateProcess().  We must quote the arguments since Win32 CreateProcess()
+   interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a
+   special way:
+   - Space and tab are interpreted as delimiters. They are not treated as
+     delimiters if they are surrounded by double quotes: "...".
+   - Unescaped double quotes are removed from the input. Their only effect is
+     that within double quotes, space and tab are treated like normal
+     characters.
+   - Backslashes not followed by double quotes are not special.
+   - But 2*n+1 backslashes followed by a double quote become
+     n backslashes followed by a double quote (n >= 0):
+       \" -> "
+       \\\" -> \"
+       \\\\\" -> \\"
+ */
+#define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037"
+#define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037"
+char **
+prepare_spawn (char **argv)
+{
+  size_t argc;
+  char **new_argv;
+  size_t i;
+
+  /* Count number of arguments.  */
+  for (argc = 0; argv[argc] != NULL; argc++)
+    ;
+
+  /* Allocate new argument vector.  */
+  new_argv = XMALLOC (char *, argc + 1);
+
+  /* Put quoted arguments into the new argument vector.  */
+  for (i = 0; i < argc; i++)
+    {
+      const char *string = argv[i];
+
+      if (string[0] == '\0')
+	new_argv[i] = xstrdup ("\"\"");
+      else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL)
+	{
+	  int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL);
+	  size_t length;
+	  unsigned int backslashes;
+	  const char *s;
+	  char *quoted_string;
+	  char *p;
+
+	  length = 0;
+	  backslashes = 0;
+	  if (quote_around)
+	    length++;
+	  for (s = string; *s != '\0'; s++)
+	    {
+	      char c = *s;
+	      if (c == '"')
+		length += backslashes + 1;
+	      length++;
+	      if (c == '\\')
+		backslashes++;
+	      else
+		backslashes = 0;
+	    }
+	  if (quote_around)
+	    length += backslashes + 1;
+
+	  quoted_string = XMALLOC (char, length + 1);
+
+	  p = quoted_string;
+	  backslashes = 0;
+	  if (quote_around)
+	    *p++ = '"';
+	  for (s = string; *s != '\0'; s++)
+	    {
+	      char c = *s;
+	      if (c == '"')
+		{
+		  unsigned int j;
+		  for (j = backslashes + 1; j > 0; j--)
+		    *p++ = '\\';
+		}
+	      *p++ = c;
+	      if (c == '\\')
+		backslashes++;
+	      else
+		backslashes = 0;
+	    }
+	  if (quote_around)
+	    {
+	      unsigned int j;
+	      for (j = backslashes; j > 0; j--)
+		*p++ = '\\';
+	      *p++ = '"';
+	    }
+	  *p = '\0';
+
+	  new_argv[i] = quoted_string;
+	}
+      else
+	new_argv[i] = (char *) string;
+    }
+  new_argv[argc] = NULL;
+
+  return new_argv;
+}
+EOF
+		;;
+	    esac
+
+            cat <<"EOF"
+void lt_dump_script (FILE* f)
+{
+EOF
+	    func_emit_wrapper yes |
+	      $SED -n -e '
+s/^\(.\{79\}\)\(..*\)/\1\
+\2/
+h
+s/\([\\"]\)/\\\1/g
+s/$/\\n/
+s/\([^\n]*\).*/  fputs ("\1", f);/p
+g
+D'
+            cat <<"EOF"
+}
+EOF
+}
+# end: func_emit_cwrapperexe_src
+
+# func_win32_import_lib_p ARG
+# True if ARG is an import lib, as indicated by $file_magic_cmd
+func_win32_import_lib_p ()
+{
+    $opt_debug
+    case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in
+    *import*) : ;;
+    *) false ;;
+    esac
+}
+
+# func_mode_link arg...
+func_mode_link ()
+{
+    $opt_debug
+    case $host in
+    *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+      # 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=
+    new_inherited_linker_flags=
+
+    avoid_version=no
+    bindir=
+    dlfiles=
+    dlprefiles=
+    dlself=no
+    export_dynamic=no
+    export_symbols=
+    export_symbols_regex=
+    generated=
+    libobjs=
+    ltlibs=
+    module=no
+    no_install=no
+    objs=
+    non_pic_objects=
+    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
+    weak_libs=
+    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
+      -shared)
+	test "$build_libtool_libs" != yes && \
+	  func_fatal_configuration "can not build a shared library"
+	build_old_libs=no
+	break
+	;;
+      -all-static | -static | -static-libtool-libs)
+	case $arg in
+	-all-static)
+	  if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then
+	    func_warning "complete static linking is impossible in this configuration"
+	  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
+      func_quote_for_eval "$arg"
+      qarg=$func_quote_for_eval_unquoted_result
+      func_append libtool_args " $func_quote_for_eval_result"
+
+      # If the previous option needs an argument, assign it.
+      if test -n "$prev"; then
+	case $prev in
+	output)
+	  func_append compile_command " @OUTPUT@"
+	  func_append finalize_command " @OUTPUT@"
+	  ;;
+	esac
+
+	case $prev in
+	bindir)
+	  bindir="$arg"
+	  prev=
+	  continue
+	  ;;
+	dlfiles|dlprefiles)
+	  if test "$preload" = no; then
+	    # Add the symbol object into the linking commands.
+	    func_append compile_command " @SYMFILE@"
+	    func_append 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
+	      func_append dlfiles " $arg"
+	    else
+	      func_append dlprefiles " $arg"
+	    fi
+	    prev=
+	    continue
+	    ;;
+	  esac
+	  ;;
+	expsyms)
+	  export_symbols="$arg"
+	  test -f "$arg" \
+	    || func_fatal_error "symbol file \`$arg' does not exist"
+	  prev=
+	  continue
+	  ;;
+	expsyms_regex)
+	  export_symbols_regex="$arg"
+	  prev=
+	  continue
+	  ;;
+	framework)
+	  case $host in
+	    *-*-darwin*)
+	      case "$deplibs " in
+		*" $qarg.ltframework "*) ;;
+		*) func_append deplibs " $qarg.ltframework" # this is fixed later
+		   ;;
+	      esac
+	      ;;
+	  esac
+	  prev=
+	  continue
+	  ;;
+	inst_prefix)
+	  inst_prefix_dir="$arg"
+	  prev=
+	  continue
+	  ;;
+	objectlist)
+	  if test -f "$arg"; then
+	    save_arg=$arg
+	    moreargs=
+	    for fil in `cat "$save_arg"`
+	    do
+#	      func_append moreargs " $fil"
+	      arg=$fil
+	      # A libtool-controlled object.
+
+	      # Check to see that this really is a libtool object.
+	      if func_lalib_unsafe_p "$arg"; then
+		pic_object=
+		non_pic_object=
+
+		# Read the .lo file
+		func_source "$arg"
+
+		if test -z "$pic_object" ||
+		   test -z "$non_pic_object" ||
+		   test "$pic_object" = none &&
+		   test "$non_pic_object" = none; then
+		  func_fatal_error "cannot find name of object for \`$arg'"
+		fi
+
+		# Extract subdirectory from the argument.
+		func_dirname "$arg" "/" ""
+		xdir="$func_dirname_result"
+
+		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
+		      func_append 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.
+		    func_append dlprefiles " $pic_object"
+		    prev=
+		  fi
+
+		  # A PIC object.
+		  func_append 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
+		  func_append 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"
+		  func_append non_pic_objects " $non_pic_object"
+		fi
+	      else
+		# Only an error if not doing a dry-run.
+		if $opt_dry_run; then
+		  # Extract subdirectory from the argument.
+		  func_dirname "$arg" "/" ""
+		  xdir="$func_dirname_result"
+
+		  func_lo2o "$arg"
+		  pic_object=$xdir$objdir/$func_lo2o_result
+		  non_pic_object=$xdir$func_lo2o_result
+		  func_append libobjs " $pic_object"
+		  func_append non_pic_objects " $non_pic_object"
+	        else
+		  func_fatal_error "\`$arg' is not a valid libtool object"
+		fi
+	      fi
+	    done
+	  else
+	    func_fatal_error "link input file \`$arg' does not exist"
+	  fi
+	  arg=$save_arg
+	  prev=
+	  continue
+	  ;;
+	precious_regex)
+	  precious_files_regex="$arg"
+	  prev=
+	  continue
+	  ;;
+	release)
+	  release="-$arg"
+	  prev=
+	  continue
+	  ;;
+	rpath | xrpath)
+	  # We need an absolute path.
+	  case $arg in
+	  [\\/]* | [A-Za-z]:[\\/]*) ;;
+	  *)
+	    func_fatal_error "only absolute run-paths are allowed"
+	    ;;
+	  esac
+	  if test "$prev" = rpath; then
+	    case "$rpath " in
+	    *" $arg "*) ;;
+	    *) func_append rpath " $arg" ;;
+	    esac
+	  else
+	    case "$xrpath " in
+	    *" $arg "*) ;;
+	    *) func_append xrpath " $arg" ;;
+	    esac
+	  fi
+	  prev=
+	  continue
+	  ;;
+	shrext)
+	  shrext_cmds="$arg"
+	  prev=
+	  continue
+	  ;;
+	weak)
+	  func_append weak_libs " $arg"
+	  prev=
+	  continue
+	  ;;
+	xcclinker)
+	  func_append linker_flags " $qarg"
+	  func_append compiler_flags " $qarg"
+	  prev=
+	  func_append compile_command " $qarg"
+	  func_append finalize_command " $qarg"
+	  continue
+	  ;;
+	xcompiler)
+	  func_append compiler_flags " $qarg"
+	  prev=
+	  func_append compile_command " $qarg"
+	  func_append finalize_command " $qarg"
+	  continue
+	  ;;
+	xlinker)
+	  func_append linker_flags " $qarg"
+	  func_append compiler_flags " $wl$qarg"
+	  prev=
+	  func_append compile_command " $wl$qarg"
+	  func_append finalize_command " $wl$qarg"
+	  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
+	  # See comment for -static flag below, for more details.
+	  func_append compile_command " $link_static_flag"
+	  func_append finalize_command " $link_static_flag"
+	fi
+	continue
+	;;
+
+      -allow-undefined)
+	# FIXME: remove this flag sometime in the future.
+	func_fatal_error "\`-allow-undefined' must not be used because it is the default"
+	;;
+
+      -avoid-version)
+	avoid_version=yes
+	continue
+	;;
+
+      -bindir)
+	prev=bindir
+	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
+	  func_fatal_error "more than one -exported-symbols argument is not allowed"
+	fi
+	if test "X$arg" = "X-export-symbols"; then
+	  prev=expsyms
+	else
+	  prev=expsyms_regex
+	fi
+	continue
+	;;
+
+      -framework)
+	prev=framework
+	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*)
+	  func_append compile_command " $arg"
+	  func_append finalize_command " $arg"
+	  ;;
+	esac
+	continue
+	;;
+
+      -L*)
+	func_stripname "-L" '' "$arg"
+	if test -z "$func_stripname_result"; then
+	  if test "$#" -gt 0; then
+	    func_fatal_error "require no space between \`-L' and \`$1'"
+	  else
+	    func_fatal_error "need path for \`-L' option"
+	  fi
+	fi
+	func_resolve_sysroot "$func_stripname_result"
+	dir=$func_resolve_sysroot_result
+	# We need an absolute path.
+	case $dir in
+	[\\/]* | [A-Za-z]:[\\/]*) ;;
+	*)
+	  absdir=`cd "$dir" && pwd`
+	  test -z "$absdir" && \
+	    func_fatal_error "cannot determine absolute directory name of \`$dir'"
+	  dir="$absdir"
+	  ;;
+	esac
+	case "$deplibs " in
+	*" -L$dir "* | *" $arg "*)
+	  # Will only happen for absolute or sysroot arguments
+	  ;;
+	*)
+	  # Preserve sysroot, but never include relative directories
+	  case $dir in
+	    [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;;
+	    *) func_append deplibs " -L$dir" ;;
+	  esac
+	  func_append lib_search_path " $dir"
+	  ;;
+	esac
+	case $host in
+	*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+	  testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'`
+	  case :$dllsearchpath: in
+	  *":$dir:"*) ;;
+	  ::) dllsearchpath=$dir;;
+	  *) func_append dllsearchpath ":$dir";;
+	  esac
+	  case :$dllsearchpath: in
+	  *":$testbindir:"*) ;;
+	  ::) dllsearchpath=$testbindir;;
+	  *) func_append 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* | *-cegcc* | *-*-haiku*)
+	    # 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
+	    func_append deplibs " System.ltframework"
+	    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
+	func_append deplibs " $arg"
+	continue
+	;;
+
+      -module)
+	module=yes
+	continue
+	;;
+
+      # Tru64 UNIX uses -model [arg] to determine the layout of C++
+      # classes, name mangling, and exception handling.
+      # Darwin uses the -arch flag to determine output architecture.
+      -model|-arch|-isysroot|--sysroot)
+	func_append compiler_flags " $arg"
+	func_append compile_command " $arg"
+	func_append finalize_command " $arg"
+	prev=xcompiler
+	continue
+	;;
+
+      -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \
+      |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*)
+	func_append compiler_flags " $arg"
+	func_append compile_command " $arg"
+	func_append finalize_command " $arg"
+	case "$new_inherited_linker_flags " in
+	    *" $arg "*) ;;
+	    * ) func_append new_inherited_linker_flags " $arg" ;;
+	esac
+	continue
+	;;
+
+      -multi_module)
+	single_module="${wl}-multi_module"
+	continue
+	;;
+
+      -no-fast-install)
+	fast_install=no
+	continue
+	;;
+
+      -no-install)
+	case $host in
+	*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*)
+	  # The PATH hackery in wrapper scripts is required on Windows
+	  # and Darwin in order for the loader to find any dlls it needs.
+	  func_warning "\`-no-install' is ignored for $host"
+	  func_warning "assuming \`-no-fast-install' instead"
+	  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*)
+	func_stripname '-R' '' "$arg"
+	dir=$func_stripname_result
+	# We need an absolute path.
+	case $dir in
+	[\\/]* | [A-Za-z]:[\\/]*) ;;
+	=*)
+	  func_stripname '=' '' "$dir"
+	  dir=$lt_sysroot$func_stripname_result
+	  ;;
+	*)
+	  func_fatal_error "only absolute run-paths are allowed"
+	  ;;
+	esac
+	case "$xrpath " in
+	*" $dir "*) ;;
+	*) func_append xrpath " $dir" ;;
+	esac
+	continue
+	;;
+
+      -shared)
+	# The effects of -shared are defined in a previous loop.
+	continue
+	;;
+
+      -shrext)
+	prev=shrext
+	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
+	;;
+
+      -weak)
+        prev=weak
+	continue
+	;;
+
+      -Wc,*)
+	func_stripname '-Wc,' '' "$arg"
+	args=$func_stripname_result
+	arg=
+	save_ifs="$IFS"; IFS=','
+	for flag in $args; do
+	  IFS="$save_ifs"
+          func_quote_for_eval "$flag"
+	  func_append arg " $func_quote_for_eval_result"
+	  func_append compiler_flags " $func_quote_for_eval_result"
+	done
+	IFS="$save_ifs"
+	func_stripname ' ' '' "$arg"
+	arg=$func_stripname_result
+	;;
+
+      -Wl,*)
+	func_stripname '-Wl,' '' "$arg"
+	args=$func_stripname_result
+	arg=
+	save_ifs="$IFS"; IFS=','
+	for flag in $args; do
+	  IFS="$save_ifs"
+          func_quote_for_eval "$flag"
+	  func_append arg " $wl$func_quote_for_eval_result"
+	  func_append compiler_flags " $wl$func_quote_for_eval_result"
+	  func_append linker_flags " $func_quote_for_eval_result"
+	done
+	IFS="$save_ifs"
+	func_stripname ' ' '' "$arg"
+	arg=$func_stripname_result
+	;;
+
+      -Xcompiler)
+	prev=xcompiler
+	continue
+	;;
+
+      -Xlinker)
+	prev=xlinker
+	continue
+	;;
+
+      -XCClinker)
+	prev=xcclinker
+	continue
+	;;
+
+      # -msg_* for osf cc
+      -msg_*)
+	func_quote_for_eval "$arg"
+	arg="$func_quote_for_eval_result"
+	;;
+
+      # Flags to be passed through unchanged, with rationale:
+      # -64, -mips[0-9]      enable 64-bit mode for the SGI compiler
+      # -r[0-9][0-9]*        specify processor for the SGI compiler
+      # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler
+      # +DA*, +DD*           enable 64-bit mode for the HP compiler
+      # -q*                  compiler args for the IBM compiler
+      # -m*, -t[45]*, -txscale* architecture-specific flags for GCC
+      # -F/path              path to uninstalled frameworks, gcc on darwin
+      # -p, -pg, --coverage, -fprofile-*  profiling flags for GCC
+      # @file                GCC response files
+      # -tp=*                Portland pgcc target processor selection
+      # --sysroot=*          for sysroot support
+      # -O*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization
+      -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \
+      -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \
+      -O*|-flto*|-fwhopr*|-fuse-linker-plugin)
+        func_quote_for_eval "$arg"
+	arg="$func_quote_for_eval_result"
+        func_append compile_command " $arg"
+        func_append finalize_command " $arg"
+        func_append compiler_flags " $arg"
+        continue
+        ;;
+
+      # Some other compiler flag.
+      -* | +*)
+        func_quote_for_eval "$arg"
+	arg="$func_quote_for_eval_result"
+	;;
+
+      *.$objext)
+	# A standard object.
+	func_append objs " $arg"
+	;;
+
+      *.lo)
+	# A libtool-controlled object.
+
+	# Check to see that this really is a libtool object.
+	if func_lalib_unsafe_p "$arg"; then
+	  pic_object=
+	  non_pic_object=
+
+	  # Read the .lo file
+	  func_source "$arg"
+
+	  if test -z "$pic_object" ||
+	     test -z "$non_pic_object" ||
+	     test "$pic_object" = none &&
+	     test "$non_pic_object" = none; then
+	    func_fatal_error "cannot find name of object for \`$arg'"
+	  fi
+
+	  # Extract subdirectory from the argument.
+	  func_dirname "$arg" "/" ""
+	  xdir="$func_dirname_result"
+
+	  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
+		func_append 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.
+	      func_append dlprefiles " $pic_object"
+	      prev=
+	    fi
+
+	    # A PIC object.
+	    func_append 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
+	    func_append 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"
+	    func_append non_pic_objects " $non_pic_object"
+	  fi
+	else
+	  # Only an error if not doing a dry-run.
+	  if $opt_dry_run; then
+	    # Extract subdirectory from the argument.
+	    func_dirname "$arg" "/" ""
+	    xdir="$func_dirname_result"
+
+	    func_lo2o "$arg"
+	    pic_object=$xdir$objdir/$func_lo2o_result
+	    non_pic_object=$xdir$func_lo2o_result
+	    func_append libobjs " $pic_object"
+	    func_append non_pic_objects " $non_pic_object"
+	  else
+	    func_fatal_error "\`$arg' is not a valid libtool object"
+	  fi
+	fi
+	;;
+
+      *.$libext)
+	# An archive.
+	func_append deplibs " $arg"
+	func_append old_deplibs " $arg"
+	continue
+	;;
+
+      *.la)
+	# A libtool-controlled library.
+
+	func_resolve_sysroot "$arg"
+	if test "$prev" = dlfiles; then
+	  # This library was specified with -dlopen.
+	  func_append dlfiles " $func_resolve_sysroot_result"
+	  prev=
+	elif test "$prev" = dlprefiles; then
+	  # The library was specified with -dlpreopen.
+	  func_append dlprefiles " $func_resolve_sysroot_result"
+	  prev=
+	else
+	  func_append deplibs " $func_resolve_sysroot_result"
+	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.
+	func_quote_for_eval "$arg"
+	arg="$func_quote_for_eval_result"
+	;;
+      esac # arg
+
+      # Now actually substitute the argument into the commands.
+      if test -n "$arg"; then
+	func_append compile_command " $arg"
+	func_append finalize_command " $arg"
+      fi
+    done # argument parsing loop
+
+    test -n "$prev" && \
+      func_fatal_help "the \`$prevarg' option requires an argument"
+
+    if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then
+      eval arg=\"$export_dynamic_flag_spec\"
+      func_append compile_command " $arg"
+      func_append finalize_command " $arg"
+    fi
+
+    oldlibs=
+    # calculate the name of the file, without its directory
+    func_basename "$output"
+    outputname="$func_basename_result"
+    libobjs_save="$libobjs"
+
+    if test -n "$shlibpath_var"; then
+      # get the directories listed in $shlibpath_var
+      eval shlib_search_path=\`\$ECHO \"\${$shlibpath_var}\" \| \$SED \'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\"
+
+    func_dirname "$output" "/" ""
+    output_objdir="$func_dirname_result$objdir"
+    func_to_tool_file "$output_objdir/"
+    tool_output_objdir=$func_to_tool_file_result
+    # Create the object directory.
+    func_mkdir_p "$output_objdir"
+
+    # Determine the type of output
+    case $output in
+    "")
+      func_fatal_help "you must specify an output file"
+      ;;
+    *.$libext) linkmode=oldlib ;;
+    *.lo | *.$objext) linkmode=obj ;;
+    *.la) linkmode=lib ;;
+    *) linkmode=prog ;; # Anything else should be a program.
+    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 $opt_preserve_dup_deps ; then
+	case "$libs " in
+	*" $deplib "*) func_append specialdeplibs " $deplib" ;;
+	esac
+      fi
+      func_append 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 $opt_duplicate_compiler_generated_deps; then
+	for pre_post_dep in $predeps $postdeps; do
+	  case "$pre_post_deps " in
+	  *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;;
+	  esac
+	  func_append 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
+    notinst_path= # paths that contain not-installed libtool libraries
+
+    case $linkmode in
+    lib)
+	passes="conv dlpreopen link"
+	for file in $dlfiles $dlprefiles; do
+	  case $file in
+	  *.la) ;;
+	  *)
+	    func_fatal_help "libraries can \`-dlopen' only libtool libraries: $file"
+	    ;;
+	  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
+      # The preopen pass in lib mode reverses $deplibs; put it back here
+      # so that -L comes before libs that need it for instance...
+      if test "$linkmode,$pass" = "lib,link"; then
+	## FIXME: Find the place where the list is rebuilt in the wrong
+	##        order, and fix it there properly
+        tmp_deplibs=
+	for deplib in $deplibs; do
+	  tmp_deplibs="$deplib $tmp_deplibs"
+	done
+	deplibs="$tmp_deplibs"
+      fi
+
+      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% $dependency_libs" ;;
+	esac
+      fi
+      if test "$linkmode,$pass" = "lib,dlpreopen"; then
+	# Collect and forward deplibs of preopened libtool libs
+	for lib in $dlprefiles; do
+	  # Ignore non-libtool-libs
+	  dependency_libs=
+	  func_resolve_sysroot "$lib"
+	  case $lib in
+	  *.la)	func_source "$func_resolve_sysroot_result" ;;
+	  esac
+
+	  # Collect preopened libtool deplibs, except any this library
+	  # has declared as weak libs
+	  for deplib in $dependency_libs; do
+	    func_basename "$deplib"
+            deplib_base=$func_basename_result
+	    case " $weak_libs " in
+	    *" $deplib_base "*) ;;
+	    *) func_append deplibs " $deplib" ;;
+	    esac
+	  done
+	done
+	libs="$dlprefiles"
+      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|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*)
+	  if test "$linkmode,$pass" = "prog,link"; then
+	    compile_deplibs="$deplib $compile_deplibs"
+	    finalize_deplibs="$deplib $finalize_deplibs"
+	  else
+	    func_append compiler_flags " $deplib"
+	    if test "$linkmode" = lib ; then
+		case "$new_inherited_linker_flags " in
+		    *" $deplib "*) ;;
+		    * ) func_append new_inherited_linker_flags " $deplib" ;;
+		esac
+	    fi
+	  fi
+	  continue
+	  ;;
+	-l*)
+	  if test "$linkmode" != lib && test "$linkmode" != prog; then
+	    func_warning "\`-l' is ignored for archives/objects"
+	    continue
+	  fi
+	  func_stripname '-l' '' "$deplib"
+	  name=$func_stripname_result
+	  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 func_lalib_p "$lib"; then
+		  library_names=
+		  old_library=
+		  func_source "$lib"
+		  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
+		    func_dirname "$lib" "" "."
+		    ladir="$func_dirname_result"
+		    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
+	*.ltframework)
+	  if test "$linkmode,$pass" = "prog,link"; then
+	    compile_deplibs="$deplib $compile_deplibs"
+	    finalize_deplibs="$deplib $finalize_deplibs"
+	  else
+	    deplibs="$deplib $deplibs"
+	    if test "$linkmode" = lib ; then
+		case "$new_inherited_linker_flags " in
+		    *" $deplib "*) ;;
+		    * ) func_append new_inherited_linker_flags " $deplib" ;;
+		esac
+	    fi
+	  fi
+	  continue
+	  ;;
+	-L*)
+	  case $linkmode in
+	  lib)
+	    deplibs="$deplib $deplibs"
+	    test "$pass" = conv && continue
+	    newdependency_libs="$deplib $newdependency_libs"
+	    func_stripname '-L' '' "$deplib"
+	    func_resolve_sysroot "$func_stripname_result"
+	    func_append newlib_search_path " $func_resolve_sysroot_result"
+	    ;;
+	  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
+	    func_stripname '-L' '' "$deplib"
+	    func_resolve_sysroot "$func_stripname_result"
+	    func_append newlib_search_path " $func_resolve_sysroot_result"
+	    ;;
+	  *)
+	    func_warning "\`-L' is ignored for archives/objects"
+	    ;;
+	  esac # linkmode
+	  continue
+	  ;; # -L
+	-R*)
+	  if test "$pass" = link; then
+	    func_stripname '-R' '' "$deplib"
+	    func_resolve_sysroot "$func_stripname_result"
+	    dir=$func_resolve_sysroot_result
+	    # Make sure the xrpath contains only unique directories.
+	    case "$xrpath " in
+	    *" $dir "*) ;;
+	    *) func_append xrpath " $dir" ;;
+	    esac
+	  fi
+	  deplibs="$deplib $deplibs"
+	  continue
+	  ;;
+	*.la)
+	  func_resolve_sysroot "$deplib"
+	  lib=$func_resolve_sysroot_result
+	  ;;
+	*.$libext)
+	  if test "$pass" = conv; then
+	    deplibs="$deplib $deplibs"
+	    continue
+	  fi
+	  case $linkmode in
+	  lib)
+	    # Linking convenience modules into shared libraries is allowed,
+	    # but linking other static libraries is non-portable.
+	    case " $dlpreconveniencelibs " in
+	    *" $deplib "*) ;;
+	    *)
+	      valid_a_lib=no
+	      case $deplibs_check_method in
+		match_pattern*)
+		  set dummy $deplibs_check_method; shift
+		  match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
+		  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 use here."
+	      else
+		echo
+		$ECHO "*** Warning: Linking the shared library $output against the"
+		$ECHO "*** static library $deplib is not portable!"
+		deplibs="$deplib $deplibs"
+	      fi
+	      ;;
+	    esac
+	    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.
+	      func_append newdlprefiles " $deplib"
+	      compile_deplibs="$deplib $compile_deplibs"
+	      finalize_deplibs="$deplib $finalize_deplibs"
+	    else
+	      func_append newdlfiles " $deplib"
+	    fi
+	  fi
+	  continue
+	  ;;
+	%DEPLIBS%)
+	  alldeplibs=yes
+	  continue
+	  ;;
+	esac # case $deplib
+
+	if test "$found" = yes || test -f "$lib"; then :
+	else
+	  func_fatal_error "cannot find the library \`$lib' or unhandled argument \`$deplib'"
+	fi
+
+	# Check to see that this really is a libtool archive.
+	func_lalib_unsafe_p "$lib" \
+	  || func_fatal_error "\`$lib' is not a valid libtool archive"
+
+	func_dirname "$lib" "" "."
+	ladir="$func_dirname_result"
+
+	dlname=
+	dlopen=
+	dlpreopen=
+	libdir=
+	library_names=
+	old_library=
+	inherited_linker_flags=
+	# 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
+	func_source "$lib"
+
+	# Convert "-framework foo" to "foo.ltframework"
+	if test -n "$inherited_linker_flags"; then
+	  tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'`
+	  for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do
+	    case " $new_inherited_linker_flags " in
+	      *" $tmp_inherited_linker_flag "*) ;;
+	      *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";;
+	    esac
+	  done
+	fi
+	dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+	if test "$linkmode,$pass" = "lib,link" ||
+	   test "$linkmode,$pass" = "prog,scan" ||
+	   { test "$linkmode" != prog && test "$linkmode" != lib; }; then
+	  test -n "$dlopen" && func_append dlfiles " $dlopen"
+	  test -n "$dlpreopen" && func_append 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
+	      func_fatal_error "cannot find name of link library for \`$lib'"
+	    fi
+	    # It is a libtool convenience library, so add in its objects.
+	    func_append convenience " $ladir/$objdir/$old_library"
+	    func_append old_convenience " $ladir/$objdir/$old_library"
+	  elif test "$linkmode" != prog && test "$linkmode" != lib; then
+	    func_fatal_error "\`$lib' is not a convenience library"
+	  fi
+	  tmp_libs=
+	  for deplib in $dependency_libs; do
+	    deplibs="$deplib $deplibs"
+	    if $opt_preserve_dup_deps ; then
+	      case "$tmp_libs " in
+	      *" $deplib "*) func_append specialdeplibs " $deplib" ;;
+	      esac
+	    fi
+	    func_append tmp_libs " $deplib"
+	  done
+	  continue
+	fi # $pass = conv
+
+
+	# Get the name of the library we link against.
+	linklib=
+	if test -n "$old_library" &&
+	   { test "$prefer_static_libs" = yes ||
+	     test "$prefer_static_libs,$installed" = "built,no"; }; then
+	  linklib=$old_library
+	else
+	  for l in $old_library $library_names; do
+	    linklib="$l"
+	  done
+	fi
+	if test -z "$linklib"; then
+	  func_fatal_error "cannot find name of link library for \`$lib'"
+	fi
+
+	# This library was specified with -dlopen.
+	if test "$pass" = dlopen; then
+	  if test -z "$libdir"; then
+	    func_fatal_error "cannot -dlopen a convenience library: \`$lib'"
+	  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.
+	    func_append dlprefiles " $lib $dependency_libs"
+	  else
+	    func_append 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
+	    func_warning "cannot determine absolute directory name of \`$ladir'"
+	    func_warning "passing it literally to the linker, although it might fail"
+	    abs_ladir="$ladir"
+	  fi
+	  ;;
+	esac
+	func_basename "$lib"
+	laname="$func_basename_result"
+
+	# Find the relevant object directory and library name.
+	if test "X$installed" = Xyes; then
+	  if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then
+	    func_warning "library \`$lib' was moved."
+	    dir="$ladir"
+	    absdir="$abs_ladir"
+	    libdir="$abs_ladir"
+	  else
+	    dir="$lt_sysroot$libdir"
+	    absdir="$lt_sysroot$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
+	    func_append notinst_path " $abs_ladir"
+	  else
+	    dir="$ladir/$objdir"
+	    absdir="$abs_ladir/$objdir"
+	    # Remove this search path later
+	    func_append notinst_path " $abs_ladir"
+	  fi
+	fi # $installed = yes
+	func_stripname 'lib' '.la' "$laname"
+	name=$func_stripname_result
+
+	# This library was specified with -dlpreopen.
+	if test "$pass" = dlpreopen; then
+	  if test -z "$libdir" && test "$linkmode" = prog; then
+	    func_fatal_error "only libraries may -dlpreopen a convenience library: \`$lib'"
+	  fi
+	  case "$host" in
+	    # special handling for platforms with PE-DLLs.
+	    *cygwin* | *mingw* | *cegcc* )
+	      # Linker will automatically link against shared library if both
+	      # static and shared are present.  Therefore, ensure we extract
+	      # symbols from the import library if a shared library is present
+	      # (otherwise, the dlopen module name will be incorrect).  We do
+	      # this by putting the import library name into $newdlprefiles.
+	      # We recover the dlopen module name by 'saving' the la file
+	      # name in a special purpose variable, and (later) extracting the
+	      # dlname from the la file.
+	      if test -n "$dlname"; then
+	        func_tr_sh "$dir/$linklib"
+	        eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname"
+	        func_append newdlprefiles " $dir/$linklib"
+	      else
+	        func_append newdlprefiles " $dir/$old_library"
+	        # Keep a list of preopened convenience libraries to check
+	        # that they are being used correctly in the link pass.
+	        test -z "$libdir" && \
+	          func_append dlpreconveniencelibs " $dir/$old_library"
+	      fi
+	    ;;
+	    * )
+	      # Prefer using a static library (so that no silly _DYNAMIC symbols
+	      # are required to link).
+	      if test -n "$old_library"; then
+	        func_append newdlprefiles " $dir/$old_library"
+	        # Keep a list of preopened convenience libraries to check
+	        # that they are being used correctly in the link pass.
+	        test -z "$libdir" && \
+	          func_append dlpreconveniencelibs " $dir/$old_library"
+	      # Otherwise, use the dlname, so that lt_dlopen finds it.
+	      elif test -n "$dlname"; then
+	        func_append newdlprefiles " $dir/$dlname"
+	      else
+	        func_append newdlprefiles " $dir/$linklib"
+	      fi
+	    ;;
+	  esac
+	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
+	  func_append 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*) func_stripname '-L' '' "$deplib"
+	         func_resolve_sysroot "$func_stripname_result"
+	         func_append newlib_search_path " $func_resolve_sysroot_result"
+		 ;;
+	    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 $opt_preserve_dup_deps ; then
+	      case "$tmp_libs " in
+	      *" $deplib "*) func_append specialdeplibs " $deplib" ;;
+	      esac
+	    fi
+	    func_append 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
+	      *"$absdir:"*) ;;
+	      *) func_append 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 "*) ;;
+	      *) func_append compile_rpath " $absdir" ;;
+	      esac
+	      ;;
+	    esac
+	    case " $sys_lib_dlsearch_path " in
+	    *" $libdir "*) ;;
+	    *)
+	      case "$finalize_rpath " in
+	      *" $libdir "*) ;;
+	      *) func_append 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
+	  case $host in
+	  *cygwin* | *mingw* | *cegcc*)
+	      # No point in relinking DLLs because paths are not encoded
+	      func_append notinst_deplibs " $lib"
+	      need_relink=no
+	    ;;
+	  *)
+	    if test "$installed" = no; then
+	      func_append notinst_deplibs " $lib"
+	      need_relink=yes
+	    fi
+	    ;;
+	  esac
+	  # This is a shared library
+
+	  # Warn about portability, can't link against -module's on some
+	  # systems (darwin).  Don't bleat about dlopened modules though!
+	  dlopenmodule=""
+	  for dlpremoduletest in $dlprefiles; do
+	    if test "X$dlpremoduletest" = "X$lib"; then
+	      dlopenmodule="$dlpremoduletest"
+	      break
+	    fi
+	  done
+	  if test -z "$dlopenmodule" && 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 "*) ;;
+	      *) func_append compile_rpath " $absdir" ;;
+	      esac
+	      ;;
+	    esac
+	    case " $sys_lib_dlsearch_path " in
+	    *" $libdir "*) ;;
+	    *)
+	      case "$finalize_rpath " in
+	      *" $libdir "*) ;;
+	      *) func_append finalize_rpath " $libdir" ;;
+	      esac
+	      ;;
+	    esac
+	  fi
+
+	  if test -n "$old_archive_from_expsyms_cmds"; then
+	    # figure out the soname
+	    set dummy $library_names
+	    shift
+	    realname="$1"
+	    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* | *cegcc*)
+	        func_arith $current - $age
+		major=$func_arith_result
+		versuffix="-$major"
+		;;
+	      esac
+	      eval soname=\"$soname_spec\"
+	    else
+	      soname="$realname"
+	    fi
+
+	    # Make a new name for the extract_expsyms_cmds to use
+	    soroot="$soname"
+	    func_basename "$soroot"
+	    soname="$func_basename_result"
+	    func_stripname 'lib' '.dll' "$soname"
+	    newlib=libimp-$func_stripname_result.a
+
+	    # If the library has no export list, then create one now
+	    if test -f "$output_objdir/$soname-def"; then :
+	    else
+	      func_verbose "extracting exported symbol list from \`$soname'"
+	      func_execute_cmds "$extract_expsyms_cmds" 'exit $?'
+	    fi
+
+	    # Create $newlib
+	    if test -f "$output_objdir/$newlib"; then :; else
+	      func_verbose "generating import library for \`$soname'"
+	      func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?'
+	    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 "$opt_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 (non-dlopened) module then we can not
+		    # link against it, someone is ignoring the earlier warnings
+		    if /usr/bin/file -L $add 2> /dev/null |
+			 $GREP ": [^:]* bundle" >/dev/null ; then
+		      if test "X$dlopenmodule" != "X$lib"; 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
+		      elif test -n "$old_library"; then
+			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 &&
+	         test "$hardcode_direct_absolute" = no; then
+		add="$dir/$linklib"
+	      elif test "$hardcode_minus_L" = yes; then
+		add_dir="-L$absdir"
+		# Try looking first in the location we're being installed to.
+		if test -n "$inst_prefix_dir"; then
+		  case $libdir in
+		    [\\/]*)
+		      func_append 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
+	      func_fatal_configuration "unsupported hardcode properties"
+	    fi
+
+	    if test -n "$add_shlibpath"; then
+	      case :$compile_shlibpath: in
+	      *":$add_shlibpath:"*) ;;
+	      *) func_append 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:"*) ;;
+		*) func_append finalize_shlibpath "$libdir:" ;;
+		esac
+	      fi
+	    fi
+	  fi
+
+	  if test "$linkmode" = prog || test "$opt_mode" = relink; then
+	    add_shlibpath=
+	    add_dir=
+	    add=
+	    # Finalize command for both is simple: just hardcode it.
+	    if test "$hardcode_direct" = yes &&
+	       test "$hardcode_direct_absolute" = no; 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:"*) ;;
+	      *) func_append 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
+		  [\\/]*)
+		    func_append 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*) func_stripname '-R' '' "$libdir"
+	           temp_xrpath=$func_stripname_result
+		   case " $xrpath " in
+		   *" $temp_xrpath "*) ;;
+		   *) func_append xrpath " $temp_xrpath";;
+		   esac;;
+	      *) func_append temp_deplibs " $libdir";;
+	      esac
+	    done
+	    dependency_libs="$temp_deplibs"
+	  fi
+
+	  func_append 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"
+	    case $deplib in
+              -L*) func_stripname '-L' '' "$deplib"
+                   func_resolve_sysroot "$func_stripname_result";;
+              *) func_resolve_sysroot "$deplib" ;;
+            esac
+	    if $opt_preserve_dup_deps ; then
+	      case "$tmp_libs " in
+	      *" $func_resolve_sysroot_result "*)
+                func_append specialdeplibs " $func_resolve_sysroot_result" ;;
+	      esac
+	    fi
+	    func_append tmp_libs " $func_resolve_sysroot_result"
+	  done
+
+	  if test "$link_all_deplibs" != no; then
+	    # Add the search paths of all dependency libraries
+	    for deplib in $dependency_libs; do
+	      path=
+	      case $deplib in
+	      -L*) path="$deplib" ;;
+	      *.la)
+	        func_resolve_sysroot "$deplib"
+	        deplib=$func_resolve_sysroot_result
+	        func_dirname "$deplib" "" "."
+		dir=$func_dirname_result
+		# We need an absolute path.
+		case $dir in
+		[\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;;
+		*)
+		  absdir=`cd "$dir" && pwd`
+		  if test -z "$absdir"; then
+		    func_warning "cannot determine absolute directory name of \`$dir'"
+		    absdir="$dir"
+		  fi
+		  ;;
+		esac
+		if $GREP "^installed=no" $deplib > /dev/null; then
+		case $host in
+		*-*-darwin*)
+		  depdepl=
+		  eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib`
+		  if test -n "$deplibrary_names" ; then
+		    for tmp in $deplibrary_names ; do
+		      depdepl=$tmp
+		    done
+		    if test -f "$absdir/$objdir/$depdepl" ; then
+		      depdepl="$absdir/$objdir/$depdepl"
+		      darwin_install_name=`${OTOOL} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'`
+                      if test -z "$darwin_install_name"; then
+                          darwin_install_name=`${OTOOL64} -L $depdepl  | awk '{if (NR == 2) {print $1;exit}}'`
+                      fi
+		      func_append compiler_flags " ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}"
+		      func_append linker_flags " -dylib_file ${darwin_install_name}:${depdepl}"
+		      path=
+		    fi
+		  fi
+		  ;;
+		*)
+		  path="-L$absdir/$objdir"
+		  ;;
+		esac
+		else
+		  eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
+		  test -z "$libdir" && \
+		    func_fatal_error "\`$deplib' is not a valid libtool archive"
+		  test "$absdir" != "$libdir" && \
+		    func_warning "\`$deplib' seems to be moved"
+
+		  path="-L$absdir"
+		fi
+		;;
+	      esac
+	      case " $deplibs " in
+	      *" $path "*) ;;
+	      *) deplibs="$path $deplibs" ;;
+	      esac
+	    done
+	  fi # link_all_deplibs != no
+	fi # linkmode = lib
+      done # for deplib in $libs
+      if test "$pass" = link; then
+	if test "$linkmode" = "prog"; then
+	  compile_deplibs="$new_inherited_linker_flags $compile_deplibs"
+	  finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs"
+	else
+	  compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+	fi
+      fi
+      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 "*) ;;
+	    *) func_append 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 "*) ;;
+	      *) func_append tmp_libs " $deplib" ;;
+	      esac
+	      ;;
+	    *) func_append 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
+	  func_append tmp_libs " $i"
+	fi
+      done
+      dependency_libs=$tmp_libs
+    done # for pass
+    if test "$linkmode" = prog; then
+      dlfiles="$newdlfiles"
+    fi
+    if test "$linkmode" = prog || test "$linkmode" = lib; then
+      dlprefiles="$newdlprefiles"
+    fi
+
+    case $linkmode in
+    oldlib)
+      if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+	func_warning "\`-dlopen' is ignored for archives"
+      fi
+
+      case " $deplibs" in
+      *\ -l* | *\ -L*)
+	func_warning "\`-l' and \`-L' are ignored for archives" ;;
+      esac
+
+      test -n "$rpath" && \
+	func_warning "\`-rpath' is ignored for archives"
+
+      test -n "$xrpath" && \
+	func_warning "\`-R' is ignored for archives"
+
+      test -n "$vinfo" && \
+	func_warning "\`-version-info/-version-number' is ignored for archives"
+
+      test -n "$release" && \
+	func_warning "\`-release' is ignored for archives"
+
+      test -n "$export_symbols$export_symbols_regex" && \
+	func_warning "\`-export-symbols' is ignored for archives"
+
+      # Now set the variables for building old libraries.
+      build_libtool_libs=no
+      oldlibs="$output"
+      func_append objs "$old_deplibs"
+      ;;
+
+    lib)
+      # Make sure we only generate libraries of the form `libNAME.la'.
+      case $outputname in
+      lib*)
+	func_stripname 'lib' '.la' "$outputname"
+	name=$func_stripname_result
+	eval shared_ext=\"$shrext_cmds\"
+	eval libname=\"$libname_spec\"
+	;;
+      *)
+	test "$module" = no && \
+	  func_fatal_help "libtool library \`$output' must begin with \`lib'"
+
+	if test "$need_lib_prefix" != no; then
+	  # Add the "lib" prefix for modules if required
+	  func_stripname '' '.la' "$outputname"
+	  name=$func_stripname_result
+	  eval shared_ext=\"$shrext_cmds\"
+	  eval libname=\"$libname_spec\"
+	else
+	  func_stripname '' '.la' "$outputname"
+	  libname=$func_stripname_result
+	fi
+	;;
+      esac
+
+      if test -n "$objs"; then
+	if test "$deplibs_check_method" != pass_all; then
+	  func_fatal_error "cannot build libtool library \`$output' from non-libtool objects on this host:$objs"
+	else
+	  echo
+	  $ECHO "*** Warning: Linking the shared library $output against the non-libtool"
+	  $ECHO "*** objects $objs is not portable!"
+	  func_append libobjs " $objs"
+	fi
+      fi
+
+      test "$dlself" != no && \
+	func_warning "\`-dlopen self' is ignored for libtool libraries"
+
+      set dummy $rpath
+      shift
+      test "$#" -gt 1 && \
+	func_warning "ignoring multiple \`-rpath's for a libtool library"
+
+      install_libdir="$1"
+
+      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
+
+	test -n "$vinfo" && \
+	  func_warning "\`-version-info/-version-number' is ignored for convenience libraries"
+
+	test -n "$release" && \
+	  func_warning "\`-release' is ignored for convenience libraries"
+      else
+
+	# Parse the version information argument.
+	save_ifs="$IFS"; IFS=':'
+	set dummy $vinfo 0 0 0
+	shift
+	IFS="$save_ifs"
+
+	test -n "$7" && \
+	  func_fatal_help "too many parameters to \`-version-info'"
+
+	# 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="$1"
+	  number_minor="$2"
+	  number_revision="$3"
+	  #
+	  # 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
+	  # correct linux to gnu/linux during the next big refactor
+	  darwin|linux|osf|windows|none)
+	    func_arith $number_major + $number_minor
+	    current=$func_arith_result
+	    age="$number_minor"
+	    revision="$number_revision"
+	    ;;
+	  freebsd-aout|freebsd-elf|qnx|sunos)
+	    current="$number_major"
+	    revision="$number_minor"
+	    age="0"
+	    ;;
+	  irix|nonstopux)
+	    func_arith $number_major + $number_minor
+	    current=$func_arith_result
+	    age="$number_minor"
+	    revision="$number_minor"
+	    lt_irix_increment=no
+	    ;;
+	  esac
+	  ;;
+	no)
+	  current="$1"
+	  revision="$2"
+	  age="$3"
+	  ;;
+	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]) ;;
+	*)
+	  func_error "CURRENT \`$current' must be a nonnegative integer"
+	  func_fatal_error "\`$vinfo' is not valid version information"
+	  ;;
+	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]) ;;
+	*)
+	  func_error "REVISION \`$revision' must be a nonnegative integer"
+	  func_fatal_error "\`$vinfo' is not valid version information"
+	  ;;
+	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]) ;;
+	*)
+	  func_error "AGE \`$age' must be a nonnegative integer"
+	  func_fatal_error "\`$vinfo' is not valid version information"
+	  ;;
+	esac
+
+	if test "$age" -gt "$current"; then
+	  func_error "AGE \`$age' is greater than the current interface number \`$current'"
+	  func_fatal_error "\`$vinfo' is not valid version information"
+	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
+	  func_arith $current - $age
+	  major=.$func_arith_result
+	  versuffix="$major.$age.$revision"
+	  # Darwin ld doesn't like 0 for these options...
+	  func_arith $current + 1
+	  minor_current=$func_arith_result
+	  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
+	    func_arith $current - $age
+	  else
+	    func_arith $current - $age + 1
+	  fi
+	  major=$func_arith_result
+
+	  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
+	    func_arith $revision - $loop
+	    iface=$func_arith_result
+	    func_arith $loop - 1
+	    loop=$func_arith_result
+	    verstring="$verstring_prefix$major.$iface:$verstring"
+	  done
+
+	  # Before this point, $major must not contain `.'.
+	  major=.$major
+	  versuffix="$major.$revision"
+	  ;;
+
+	linux) # correct to gnu/linux during the next big refactor
+	  func_arith $current - $age
+	  major=.$func_arith_result
+	  versuffix="$major.$age.$revision"
+	  ;;
+
+	osf)
+	  func_arith $current - $age
+	  major=.$func_arith_result
+	  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
+	    func_arith $current - $loop
+	    iface=$func_arith_result
+	    func_arith $loop - 1
+	    loop=$func_arith_result
+	    verstring="$verstring:${iface}.0"
+	  done
+
+	  # Make executables depend on our current version.
+	  func_append verstring ":${current}.0"
+	  ;;
+
+	qnx)
+	  major=".$current"
+	  versuffix=".$current"
+	  ;;
+
+	sunos)
+	  major=".$current"
+	  versuffix=".$current.$revision"
+	  ;;
+
+	windows)
+	  # Use '-' rather than '.', since we only want one
+	  # extension on DOS 8.3 filesystems.
+	  func_arith $current - $age
+	  major=$func_arith_result
+	  versuffix="-$major"
+	  ;;
+
+	*)
+	  func_fatal_configuration "unknown library version type \`$version_type'"
+	  ;;
+	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
+	    func_warning "undefined symbols not allowed in $host shared libraries"
+	    build_libtool_libs=no
+	    build_old_libs=yes
+	  fi
+	else
+	  # Don't allow undefined symbols.
+	  allow_undefined_flag="$no_undefined_flag"
+	fi
+
+      fi
+
+      func_generate_dlsyms "$libname" "$libname" "yes"
+      func_append libobjs " $symfileobj"
+      test "X$libobjs" = "X " && libobjs=
+
+      if test "$opt_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 | *.gcno)
+	       ;;
+	    $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
+	       func_append removelist " $p"
+	       ;;
+	    *) ;;
+	  esac
+	done
+	test -n "$removelist" && \
+	  func_show_eval "${RM}r \$removelist"
+      fi
+
+      # Now set the variables for building old libraries.
+      if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then
+	func_append oldlibs " $output_objdir/$libname.$libext"
+
+	# Transform .lo files to .o files.
+	oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; $lo2o" | $NL2SP`
+      fi
+
+      # Eliminate all temporary directories.
+      #for path in $notinst_path; do
+      #	lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"`
+      #	deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"`
+      #	dependency_libs=`$ECHO "$dependency_libs " | $SED "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
+	  func_replace_sysroot "$libdir"
+	  func_append temp_xrpath " -R$func_replace_sysroot_result"
+	  case "$finalize_rpath " in
+	  *" $libdir "*) ;;
+	  *) func_append 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 "*) ;;
+	*) func_append 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 "*) ;;
+	*) func_append dlprefiles " $lib" ;;
+	esac
+      done
+
+      if test "$build_libtool_libs" = yes; then
+	if test -n "$rpath"; then
+	  case $host in
+	  *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*)
+	    # these systems don't actually have a c library (as such)!
+	    ;;
+	  *-*-rhapsody* | *-*-darwin1.[012])
+	    # Rhapsody C library is in the System framework
+	    func_append deplibs " System.ltframework"
+	    ;;
+	  *-*-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
+	      func_append 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.
+	  $opt_dry_run || $RM conftest.c
+	  cat > conftest.c <<EOF
+	  int main() { return 0; }
+EOF
+	  $opt_dry_run || $RM conftest
+	  if $LTCC $LTCFLAGS -o conftest conftest.c $deplibs; then
+	    ldd_output=`ldd conftest`
+	    for i in $deplibs; do
+	      case $i in
+	      -l*)
+		func_stripname -l '' "$i"
+		name=$func_stripname_result
+		if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+		  case " $predeps $postdeps " in
+		  *" $i "*)
+		    func_append 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; shift
+		  deplib_match=$1
+		  if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+		    func_append 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
+		;;
+	      *)
+		func_append newdeplibs " $i"
+		;;
+	      esac
+	    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
+	      case $i in
+	      -l*)
+		func_stripname -l '' "$i"
+		name=$func_stripname_result
+		$opt_dry_run || $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 "*)
+		      func_append 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; shift
+		    deplib_match=$1
+		    if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+		      func_append 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
+		;;
+	      *)
+		func_append newdeplibs " $i"
+		;;
+	      esac
+	    done
+	  fi
+	  ;;
+	file_magic*)
+	  set dummy $deplibs_check_method; shift
+	  file_magic_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
+	  for a_deplib in $deplibs; do
+	    case $a_deplib in
+	    -l*)
+	      func_stripname -l '' "$a_deplib"
+	      name=$func_stripname_result
+	      if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+		case " $predeps $postdeps " in
+		*" $a_deplib "*)
+		  func_append newdeplibs " $a_deplib"
+		  a_deplib=""
+		  ;;
+		esac
+	      fi
+	      if test -n "$a_deplib" ; then
+		libname=`eval "\\$ECHO \"$libname_spec\""`
+		if test -n "$file_magic_glob"; then
+		  libnameglob=`func_echo_all "$libname" | $SED -e $file_magic_glob`
+		else
+		  libnameglob=$libname
+		fi
+		test "$want_nocaseglob" = yes && nocaseglob=`shopt -p nocaseglob`
+		for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
+		  if test "$want_nocaseglob" = yes; then
+		    shopt -s nocaseglob
+		    potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null`
+		    $nocaseglob
+		  else
+		    potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null`
+		  fi
+		  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 "$potlib" | $SED 's,[^/]*$,,'`"$potliblink";;
+			esac
+		      done
+		      if eval $file_magic_cmd \"\$potlib\" 2>/dev/null |
+			 $SED -e 10q |
+			 $EGREP "$file_magic_regex" > /dev/null; then
+			func_append 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
+	      ;;
+	    *)
+	      # Add a -L argument.
+	      func_append newdeplibs " $a_deplib"
+	      ;;
+	    esac
+	  done # Gone through all deplibs.
+	  ;;
+	match_pattern*)
+	  set dummy $deplibs_check_method; shift
+	  match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
+	  for a_deplib in $deplibs; do
+	    case $a_deplib in
+	    -l*)
+	      func_stripname -l '' "$a_deplib"
+	      name=$func_stripname_result
+	      if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+		case " $predeps $postdeps " in
+		*" $a_deplib "*)
+		  func_append 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
+		      func_append 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
+	      ;;
+	    *)
+	      # Add a -L argument.
+	      func_append newdeplibs " $a_deplib"
+	      ;;
+	    esac
+	  done # Gone through all deplibs.
+	  ;;
+	none | unknown | *)
+	  newdeplibs=""
+	  tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; 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 " $tmp_deplibs" | $SED "s,$i,,"`
+	    done
+	  fi
+	  case $tmp_deplibs in
+	  *[!\	\ ]*)
+	    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
+	    ;;
+	  esac
+	  ;;
+	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 with the System framework
+	  newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'`
+	  ;;
+	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
+      # Time to change all our "foo.ltframework" stuff back to "-framework foo"
+      case $host in
+	*-*-darwin*)
+	  newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+	  new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+	  deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+	  ;;
+      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 " $deplibs " in
+	  *" -L$path/$objdir "*)
+	    func_append new_libs " -L$path/$objdir" ;;
+	  esac
+	  ;;
+	esac
+      done
+      for deplib in $deplibs; do
+	case $deplib in
+	-L*)
+	  case " $new_libs " in
+	  *" $deplib "*) ;;
+	  *) func_append new_libs " $deplib" ;;
+	  esac
+	  ;;
+	*) func_append 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
+	# Remove ${wl} instances when linking with ld.
+	# FIXME: should test the right _cmds variable.
+	case $archive_cmds in
+	  *\$LD\ *) wl= ;;
+        esac
+	if test "$hardcode_into_libs" = yes; then
+	  # Hardcode the library paths
+	  hardcode_libdirs=
+	  dep_rpath=
+	  rpath="$finalize_rpath"
+	  test "$opt_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
+		func_replace_sysroot "$libdir"
+		libdir=$func_replace_sysroot_result
+		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"*)
+		    ;;
+		  *)
+		    func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"
+		    ;;
+		  esac
+		fi
+	      else
+		eval flag=\"$hardcode_libdir_flag_spec\"
+		func_append dep_rpath " $flag"
+	      fi
+	    elif test -n "$runpath_var"; then
+	      case "$perm_rpath " in
+	      *" $libdir "*) ;;
+	      *) func_append 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 "dep_rpath=\"$hardcode_libdir_flag_spec\""
+	  fi
+	  if test -n "$runpath_var" && test -n "$perm_rpath"; then
+	    # We should set the runpath_var.
+	    rpath=
+	    for dir in $perm_rpath; do
+	      func_append 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 "$opt_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
+	shift
+	realname="$1"
+	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
+	  func_append linknames " $link"
+	done
+
+	# Use standard objects if they are pic
+	test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP`
+	test "X$libobjs" = "X " && libobjs=
+
+	delfiles=
+	if test -n "$export_symbols" && test -n "$include_expsyms"; then
+	  $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp"
+	  export_symbols="$output_objdir/$libname.uexp"
+	  func_append delfiles " $export_symbols"
+	fi
+
+	orig_export_symbols=
+	case $host_os in
+	cygwin* | mingw* | cegcc*)
+	  if test -n "$export_symbols" && test -z "$export_symbols_regex"; then
+	    # exporting using user supplied symfile
+	    if test "x`$SED 1q $export_symbols`" != xEXPORTS; then
+	      # and it's NOT already a .def file. Must figure out
+	      # which of the given symbols are data symbols and tag
+	      # them as such. So, trigger use of export_symbols_cmds.
+	      # export_symbols gets reassigned inside the "prepare
+	      # the list of exported symbols" if statement, so the
+	      # include_expsyms logic still works.
+	      orig_export_symbols="$export_symbols"
+	      export_symbols=
+	      always_export_symbols=yes
+	    fi
+	  fi
+	  ;;
+	esac
+
+	# Prepare the list of exported symbols
+	if test -z "$export_symbols"; then
+	  if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then
+	    func_verbose "generating symbol list for \`$libname.la'"
+	    export_symbols="$output_objdir/$libname.exp"
+	    $opt_dry_run || $RM $export_symbols
+	    cmds=$export_symbols_cmds
+	    save_ifs="$IFS"; IFS='~'
+	    for cmd1 in $cmds; do
+	      IFS="$save_ifs"
+	      # Take the normal branch if the nm_file_list_spec branch
+	      # doesn't work or if tool conversion is not needed.
+	      case $nm_file_list_spec~$to_tool_file_cmd in
+		*~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*)
+		  try_normal_branch=yes
+		  eval cmd=\"$cmd1\"
+		  func_len " $cmd"
+		  len=$func_len_result
+		  ;;
+		*)
+		  try_normal_branch=no
+		  ;;
+	      esac
+	      if test "$try_normal_branch" = yes \
+		 && { test "$len" -lt "$max_cmd_len" \
+		      || test "$max_cmd_len" -le -1; }
+	      then
+		func_show_eval "$cmd" 'exit $?'
+		skipped_export=false
+	      elif test -n "$nm_file_list_spec"; then
+		func_basename "$output"
+		output_la=$func_basename_result
+		save_libobjs=$libobjs
+		save_output=$output
+		output=${output_objdir}/${output_la}.nm
+		func_to_tool_file "$output"
+		libobjs=$nm_file_list_spec$func_to_tool_file_result
+		func_append delfiles " $output"
+		func_verbose "creating $NM input file list: $output"
+		for obj in $save_libobjs; do
+		  func_to_tool_file "$obj"
+		  $ECHO "$func_to_tool_file_result"
+		done > "$output"
+		eval cmd=\"$cmd1\"
+		func_show_eval "$cmd" 'exit $?'
+		output=$save_output
+		libobjs=$save_libobjs
+		skipped_export=false
+	      else
+		# The command line is too long to execute in one step.
+		func_verbose "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" && test "X$skipped_export" != "X:"; then
+	      func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
+	      func_show_eval '$MV "${export_symbols}T" "$export_symbols"'
+	    fi
+	  fi
+	fi
+
+	if test -n "$export_symbols" && test -n "$include_expsyms"; then
+	  tmp_export_symbols="$export_symbols"
+	  test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols"
+	  $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"'
+	fi
+
+	if test "X$skipped_export" != "X:" && test -n "$orig_export_symbols"; then
+	  # The given exports_symbols file has to be filtered, so filter it.
+	  func_verbose "filter symbol list for \`$libname.la' to tag DATA exports"
+	  # FIXME: $output_objdir/$libname.filter potentially contains lots of
+	  # 's' commands which not all seds can handle. GNU sed should be fine
+	  # though. Also, the filter scales superlinearly with the number of
+	  # global variables. join(1) would be nice here, but unfortunately
+	  # isn't a blessed tool.
+	  $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter
+	  func_append delfiles " $export_symbols $output_objdir/$libname.filter"
+	  export_symbols=$output_objdir/$libname.def
+	  $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols
+	fi
+
+	tmp_deplibs=
+	for test_deplib in $deplibs; do
+	  case " $convenience " in
+	  *" $test_deplib "*) ;;
+	  *)
+	    func_append tmp_deplibs " $test_deplib"
+	    ;;
+	  esac
+	done
+	deplibs="$tmp_deplibs"
+
+	if test -n "$convenience"; then
+	  if test -n "$whole_archive_flag_spec" &&
+	    test "$compiler_needs_object" = yes &&
+	    test -z "$libobjs"; then
+	    # extract the archives, so we have objects to list.
+	    # TODO: could optimize this to just extract one archive.
+	    whole_archive_flag_spec=
+	  fi
+	  if test -n "$whole_archive_flag_spec"; then
+	    save_libobjs=$libobjs
+	    eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+	    test "X$libobjs" = "X " && libobjs=
+	  else
+	    gentop="$output_objdir/${outputname}x"
+	    func_append generated " $gentop"
+
+	    func_extract_archives $gentop $convenience
+	    func_append libobjs " $func_extract_archives_result"
+	    test "X$libobjs" = "X " && libobjs=
+	  fi
+	fi
+
+	if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then
+	  eval flag=\"$thread_safe_flag_spec\"
+	  func_append linker_flags " $flag"
+	fi
+
+	# Make a backup of the uninstalled library when relinking
+	if test "$opt_mode" = relink; then
+	  $opt_dry_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:" &&
+	   func_len " $test_cmds" &&
+	   len=$func_len_result &&
+	   test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+	  :
+	else
+	  # The command line is too long to link in one step, link piecewise
+	  # or, if using GNU ld and skipped_export is not :, use a linker
+	  # script.
+
+	  # 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
+	  func_basename "$output"
+	  output_la=$func_basename_result
+
+	  # Clear the reloadable object creation command queue and
+	  # initialize k to one.
+	  test_cmds=
+	  concat_cmds=
+	  objlist=
+	  last_robj=
+	  k=1
+
+	  if test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "$with_gnu_ld" = yes; then
+	    output=${output_objdir}/${output_la}.lnkscript
+	    func_verbose "creating GNU ld script: $output"
+	    echo 'INPUT (' > $output
+	    for obj in $save_libobjs
+	    do
+	      func_to_tool_file "$obj"
+	      $ECHO "$func_to_tool_file_result" >> $output
+	    done
+	    echo ')' >> $output
+	    func_append delfiles " $output"
+	    func_to_tool_file "$output"
+	    output=$func_to_tool_file_result
+	  elif test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "X$file_list_spec" != X; then
+	    output=${output_objdir}/${output_la}.lnk
+	    func_verbose "creating linker input file list: $output"
+	    : > $output
+	    set x $save_libobjs
+	    shift
+	    firstobj=
+	    if test "$compiler_needs_object" = yes; then
+	      firstobj="$1 "
+	      shift
+	    fi
+	    for obj
+	    do
+	      func_to_tool_file "$obj"
+	      $ECHO "$func_to_tool_file_result" >> $output
+	    done
+	    func_append delfiles " $output"
+	    func_to_tool_file "$output"
+	    output=$firstobj\"$file_list_spec$func_to_tool_file_result\"
+	  else
+	    if test -n "$save_libobjs"; then
+	      func_verbose "creating reloadable object files..."
+	      output=$output_objdir/$output_la-${k}.$objext
+	      eval test_cmds=\"$reload_cmds\"
+	      func_len " $test_cmds"
+	      len0=$func_len_result
+	      len=$len0
+
+	      # Loop over the list of objects to be linked.
+	      for obj in $save_libobjs
+	      do
+		func_len " $obj"
+		func_arith $len + $func_len_result
+		len=$func_arith_result
+		if test "X$objlist" = X ||
+		   test "$len" -lt "$max_cmd_len"; then
+		  func_append 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.
+		    reload_objs=$objlist
+		    eval concat_cmds=\"$reload_cmds\"
+		  else
+		    # All subsequent reloadable object files will link in
+		    # the last one created.
+		    reload_objs="$objlist $last_robj"
+		    eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\"
+		  fi
+		  last_robj=$output_objdir/$output_la-${k}.$objext
+		  func_arith $k + 1
+		  k=$func_arith_result
+		  output=$output_objdir/$output_la-${k}.$objext
+		  objlist=" $obj"
+		  func_len " $last_robj"
+		  func_arith $len0 + $func_len_result
+		  len=$func_arith_result
+		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~
+	      reload_objs="$objlist $last_robj"
+	      eval concat_cmds=\"\${concat_cmds}$reload_cmds\"
+	      if test -n "$last_robj"; then
+	        eval concat_cmds=\"\${concat_cmds}~\$RM $last_robj\"
+	      fi
+	      func_append delfiles " $output"
+
+	    else
+	      output=
+	    fi
+
+	    if ${skipped_export-false}; then
+	      func_verbose "generating symbol list for \`$libname.la'"
+	      export_symbols="$output_objdir/$libname.exp"
+	      $opt_dry_run || $RM $export_symbols
+	      libobjs=$output
+	      # Append the command to create the export file.
+	      test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+	      eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\"
+	      if test -n "$last_robj"; then
+		eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\"
+	      fi
+	    fi
+
+	    test -n "$save_libobjs" &&
+	      func_verbose "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"
+	      $opt_silent || {
+		  func_quote_for_expand "$cmd"
+		  eval "func_echo $func_quote_for_expand_result"
+	      }
+	      $opt_dry_run || eval "$cmd" || {
+		lt_exit=$?
+
+		# Restore the uninstalled library and exit
+		if test "$opt_mode" = relink; then
+		  ( cd "$output_objdir" && \
+		    $RM "${realname}T" && \
+		    $MV "${realname}U" "$realname" )
+		fi
+
+		exit $lt_exit
+	      }
+	    done
+	    IFS="$save_ifs"
+
+	    if test -n "$export_symbols_regex" && ${skipped_export-false}; then
+	      func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
+	      func_show_eval '$MV "${export_symbols}T" "$export_symbols"'
+	    fi
+	  fi
+
+          if ${skipped_export-false}; then
+	    if test -n "$export_symbols" && test -n "$include_expsyms"; then
+	      tmp_export_symbols="$export_symbols"
+	      test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols"
+	      $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"'
+	    fi
+
+	    if test -n "$orig_export_symbols"; then
+	      # The given exports_symbols file has to be filtered, so filter it.
+	      func_verbose "filter symbol list for \`$libname.la' to tag DATA exports"
+	      # FIXME: $output_objdir/$libname.filter potentially contains lots of
+	      # 's' commands which not all seds can handle. GNU sed should be fine
+	      # though. Also, the filter scales superlinearly with the number of
+	      # global variables. join(1) would be nice here, but unfortunately
+	      # isn't a blessed tool.
+	      $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter
+	      func_append delfiles " $export_symbols $output_objdir/$libname.filter"
+	      export_symbols=$output_objdir/$libname.def
+	      $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols
+	    fi
+	  fi
+
+	  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\"
+	    test "X$libobjs" = "X " && libobjs=
+	  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
+	fi
+
+	if test -n "$delfiles"; then
+	  # Append the command to remove temporary files to $cmds.
+	  eval cmds=\"\$cmds~\$RM $delfiles\"
+	fi
+
+	# Add any objects from preloaded convenience libraries
+	if test -n "$dlprefiles"; then
+	  gentop="$output_objdir/${outputname}x"
+	  func_append generated " $gentop"
+
+	  func_extract_archives $gentop $dlprefiles
+	  func_append libobjs " $func_extract_archives_result"
+	  test "X$libobjs" = "X " && libobjs=
+	fi
+
+	save_ifs="$IFS"; IFS='~'
+	for cmd in $cmds; do
+	  IFS="$save_ifs"
+	  eval cmd=\"$cmd\"
+	  $opt_silent || {
+	    func_quote_for_expand "$cmd"
+	    eval "func_echo $func_quote_for_expand_result"
+	  }
+	  $opt_dry_run || eval "$cmd" || {
+	    lt_exit=$?
+
+	    # Restore the uninstalled library and exit
+	    if test "$opt_mode" = relink; then
+	      ( 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 "$opt_mode" = relink; then
+	  $opt_dry_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
+	      func_show_eval '${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
+	    func_show_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)
+      if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+	func_warning "\`-dlopen' is ignored for objects"
+      fi
+
+      case " $deplibs" in
+      *\ -l* | *\ -L*)
+	func_warning "\`-l' and \`-L' are ignored for objects" ;;
+      esac
+
+      test -n "$rpath" && \
+	func_warning "\`-rpath' is ignored for objects"
+
+      test -n "$xrpath" && \
+	func_warning "\`-R' is ignored for objects"
+
+      test -n "$vinfo" && \
+	func_warning "\`-version-info' is ignored for objects"
+
+      test -n "$release" && \
+	func_warning "\`-release' is ignored for objects"
+
+      case $output in
+      *.lo)
+	test -n "$objs$old_deplibs" && \
+	  func_fatal_error "cannot build library object \`$output' from non-libtool objects"
+
+	libobj=$output
+	func_lo2o "$libobj"
+	obj=$func_lo2o_result
+	;;
+      *)
+	libobj=
+	obj="$output"
+	;;
+      esac
+
+      # Delete the old objects.
+      $opt_dry_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 "$tmp_whole_archive_flags" | $SED 's|,| |g'`
+	else
+	  gentop="$output_objdir/${obj}x"
+	  func_append generated " $gentop"
+
+	  func_extract_archives $gentop $convenience
+	  reload_conv_objs="$reload_objs $func_extract_archives_result"
+	fi
+      fi
+
+      # If we're not building shared, we need to use non_pic_objs
+      test "$build_libtool_libs" != yes && libobjs="$non_pic_objects"
+
+      # Create the old-style object.
+      reload_objs="$objs$old_deplibs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; /\.lib$/d; $lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test
+
+      output="$obj"
+      func_execute_cmds "$reload_cmds" 'exit $?'
+
+      # Exit if we aren't doing a library object file.
+      if test -z "$libobj"; then
+	if test -n "$gentop"; then
+	  func_show_eval '${RM}r "$gentop"'
+	fi
+
+	exit $EXIT_SUCCESS
+      fi
+
+      if test "$build_libtool_libs" != yes; then
+	if test -n "$gentop"; then
+	  func_show_eval '${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"
+	# $opt_dry_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"
+	func_execute_cmds "$reload_cmds" 'exit $?'
+      fi
+
+      if test -n "$gentop"; then
+	func_show_eval '${RM}r "$gentop"'
+      fi
+
+      exit $EXIT_SUCCESS
+      ;;
+
+    prog)
+      case $host in
+	*cygwin*) func_stripname '' '.exe' "$output"
+	          output=$func_stripname_result.exe;;
+      esac
+      test -n "$vinfo" && \
+	func_warning "\`-version-info' is ignored for programs"
+
+      test -n "$release" && \
+	func_warning "\`-release' is ignored for programs"
+
+      test "$preload" = yes \
+        && test "$dlopen_support" = unknown \
+	&& test "$dlopen_self" = unknown \
+	&& test "$dlopen_self_static" = unknown && \
+	  func_warning "\`LT_INIT([dlopen])' not used. Assuming no dlopen support."
+
+      case $host in
+      *-*-rhapsody* | *-*-darwin1.[012])
+	# On Rhapsody replace the C library is the System framework
+	compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'`
+	finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'`
+	;;
+      esac
+
+      case $host in
+      *-*-darwin*)
+	# Don't allow lazy linking, it breaks C++ global constructors
+	# But is supposedly fixed on 10.4 or later (yay!).
+	if test "$tagname" = CXX ; then
+	  case ${MACOSX_DEPLOYMENT_TARGET-10.0} in
+	    10.[0123])
+	      func_append compile_command " ${wl}-bind_at_load"
+	      func_append finalize_command " ${wl}-bind_at_load"
+	    ;;
+	  esac
+	fi
+	# Time to change all our "foo.ltframework" stuff back to "-framework foo"
+	compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+	finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+	;;
+      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 "*)
+	    func_append new_libs " -L$path/$objdir" ;;
+	  esac
+	  ;;
+	esac
+      done
+      for deplib in $compile_deplibs; do
+	case $deplib in
+	-L*)
+	  case " $new_libs " in
+	  *" $deplib "*) ;;
+	  *) func_append new_libs " $deplib" ;;
+	  esac
+	  ;;
+	*) func_append new_libs " $deplib" ;;
+	esac
+      done
+      compile_deplibs="$new_libs"
+
+
+      func_append compile_command " $compile_deplibs"
+      func_append 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 "*) ;;
+	  *) func_append 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"*)
+		;;
+	      *)
+		func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"
+		;;
+	      esac
+	    fi
+	  else
+	    eval flag=\"$hardcode_libdir_flag_spec\"
+	    func_append rpath " $flag"
+	  fi
+	elif test -n "$runpath_var"; then
+	  case "$perm_rpath " in
+	  *" $libdir "*) ;;
+	  *) func_append perm_rpath " $libdir" ;;
+	  esac
+	fi
+	case $host in
+	*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+	  testbindir=`${ECHO} "$libdir" | ${SED} -e 's*/lib$*/bin*'`
+	  case :$dllsearchpath: in
+	  *":$libdir:"*) ;;
+	  ::) dllsearchpath=$libdir;;
+	  *) func_append dllsearchpath ":$libdir";;
+	  esac
+	  case :$dllsearchpath: in
+	  *":$testbindir:"*) ;;
+	  ::) dllsearchpath=$testbindir;;
+	  *) func_append 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"*)
+		;;
+	      *)
+		func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"
+		;;
+	      esac
+	    fi
+	  else
+	    eval flag=\"$hardcode_libdir_flag_spec\"
+	    func_append rpath " $flag"
+	  fi
+	elif test -n "$runpath_var"; then
+	  case "$finalize_perm_rpath " in
+	  *" $libdir "*) ;;
+	  *) func_append 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 "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP`
+	finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP`
+      fi
+
+      func_generate_dlsyms "$outputname" "@PROGRAM@" "no"
+
+      # template prelinking step
+      if test -n "$prelink_cmds"; then
+	func_execute_cmds "$prelink_cmds" 'exit $?'
+      fi
+
+      wrappers_required=yes
+      case $host in
+      *cegcc* | *mingw32ce*)
+        # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway.
+        wrappers_required=no
+        ;;
+      *cygwin* | *mingw* )
+        if test "$build_libtool_libs" != yes; then
+          wrappers_required=no
+        fi
+        ;;
+      *)
+        if test "$need_relink" = no || test "$build_libtool_libs" != yes; then
+          wrappers_required=no
+        fi
+        ;;
+      esac
+      if test "$wrappers_required" = no; then
+	# Replace the output file specification.
+	compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'`
+	link_command="$compile_command$compile_rpath"
+
+	# We have no uninstalled library dependencies, so finalize right now.
+	exit_status=0
+	func_show_eval "$link_command" 'exit_status=$?'
+
+	if test -n "$postlink_cmds"; then
+	  func_to_tool_file "$output"
+	  postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`
+	  func_execute_cmds "$postlink_cmds" 'exit $?'
+	fi
+
+	# Delete the generated files.
+	if test -f "$output_objdir/${outputname}S.${objext}"; then
+	  func_show_eval '$RM "$output_objdir/${outputname}S.${objext}"'
+	fi
+
+	exit $exit_status
+      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
+	    func_append 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
+	    func_append 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 "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'`
+	# Delete the old output file.
+	$opt_dry_run || $RM $output
+	# Link the executable and exit
+	func_show_eval "$link_command" 'exit $?'
+
+	if test -n "$postlink_cmds"; then
+	  func_to_tool_file "$output"
+	  postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`
+	  func_execute_cmds "$postlink_cmds" 'exit $?'
+	fi
+
+	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"
+
+	func_warning "this platform does not like uninstalled shared libraries"
+	func_warning "\`$output' will be relinked during installation"
+      else
+	if test "$fast_install" != no; then
+	  link_command="$finalize_var$compile_command$finalize_rpath"
+	  if test "$fast_install" = yes; then
+	    relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'`
+	  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 "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'`
+
+      # Delete the old output files.
+      $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname
+
+      func_show_eval "$link_command" 'exit $?'
+
+      if test -n "$postlink_cmds"; then
+	func_to_tool_file "$output_objdir/$outputname"
+	postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`
+	func_execute_cmds "$postlink_cmds" 'exit $?'
+      fi
+
+      # Now create the wrapper script.
+      func_verbose "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}\" || $lt_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
+	    func_quote_for_eval "$var_value"
+	    relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command"
+	  fi
+	done
+	relink_command="(cd `pwd`; $relink_command)"
+	relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"`
+      fi
+
+      # Only actually do things if not in dry run mode.
+      $opt_dry_run || {
+	# win32 will think the script is a binary if it has
+	# a .exe suffix, so we strip it off here.
+	case $output in
+	  *.exe) func_stripname '' '.exe' "$output"
+	         output=$func_stripname_result ;;
+	esac
+	# test for cygwin because mv fails w/o .exe extensions
+	case $host in
+	  *cygwin*)
+	    exeext=.exe
+	    func_stripname '' '.exe' "$outputname"
+	    outputname=$func_stripname_result ;;
+	  *) exeext= ;;
+	esac
+	case $host in
+	  *cygwin* | *mingw* )
+	    func_dirname_and_basename "$output" "" "."
+	    output_name=$func_basename_result
+	    output_path=$func_dirname_result
+	    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
+
+	    func_emit_cwrapperexe_src > $cwrappersource
+
+	    # The wrapper executable is built using the $host compiler,
+	    # because it contains $host paths and files. If cross-
+	    # compiling, it, like the target executable, must be
+	    # executed on the $host or under an emulation environment.
+	    $opt_dry_run || {
+	      $LTCC $LTCFLAGS -o $cwrapper $cwrappersource
+	      $STRIP $cwrapper
+	    }
+
+	    # Now, create the wrapper script for func_source use:
+	    func_ltwrapper_scriptname $cwrapper
+	    $RM $func_ltwrapper_scriptname_result
+	    trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15
+	    $opt_dry_run || {
+	      # note: this script will not be executed, so do not chmod.
+	      if test "x$build" = "x$host" ; then
+		$cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result
+	      else
+		func_emit_wrapper no > $func_ltwrapper_scriptname_result
+	      fi
+	    }
+	  ;;
+	  * )
+	    $RM $output
+	    trap "$RM $output; exit $EXIT_FAILURE" 1 2 15
+
+	    func_emit_wrapper no > $output
+	    chmod +x $output
+	  ;;
+	esac
+      }
+      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 $symfileobj"
+	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"
+	  if test "$preload" = yes && test -f "$symfileobj"; then
+	    func_append oldobjs " $symfileobj"
+	  fi
+	fi
+	addlibs="$old_convenience"
+      fi
+
+      if test -n "$addlibs"; then
+	gentop="$output_objdir/${outputname}x"
+	func_append generated " $gentop"
+
+	func_extract_archives $gentop $addlibs
+	func_append 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
+
+	# Add any objects from preloaded convenience libraries
+	if test -n "$dlprefiles"; then
+	  gentop="$output_objdir/${outputname}x"
+	  func_append generated " $gentop"
+
+	  func_extract_archives $gentop $dlprefiles
+	  func_append oldobjs " $func_extract_archives_result"
+	fi
+
+	# 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
+	      func_basename "$obj"
+	      $ECHO "$func_basename_result"
+	    done | sort | sort -uc >/dev/null 2>&1); then
+	  :
+	else
+	  echo "copying selected object files to avoid basename conflicts..."
+	  gentop="$output_objdir/${outputname}x"
+	  func_append generated " $gentop"
+	  func_mkdir_p "$gentop"
+	  save_oldobjs=$oldobjs
+	  oldobjs=
+	  counter=1
+	  for obj in $save_oldobjs
+	  do
+	    func_basename "$obj"
+	    objbase="$func_basename_result"
+	    case " $oldobjs " in
+	    " ") oldobjs=$obj ;;
+	    *[\ /]"$objbase "*)
+	      while :; do
+		# Make sure we don't pick an alternate name that also
+		# overlaps.
+		newobj=lt$counter-$objbase
+		func_arith $counter + 1
+		counter=$func_arith_result
+		case " $oldobjs " in
+		*[\ /]"$newobj "*) ;;
+		*) if test ! -f "$gentop/$newobj"; then break; fi ;;
+		esac
+	      done
+	      func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj"
+	      func_append oldobjs " $gentop/$newobj"
+	      ;;
+	    *) func_append oldobjs " $obj" ;;
+	    esac
+	  done
+	fi
+	func_to_tool_file "$oldlib" func_convert_file_msys_to_w32
+	tool_oldlib=$func_to_tool_file_result
+	eval cmds=\"$old_archive_cmds\"
+
+	func_len " $cmds"
+	len=$func_len_result
+	if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+	  cmds=$old_archive_cmds
+	elif test -n "$archiver_list_spec"; then
+	  func_verbose "using command file archive linking..."
+	  for obj in $oldobjs
+	  do
+	    func_to_tool_file "$obj"
+	    $ECHO "$func_to_tool_file_result"
+	  done > $output_objdir/$libname.libcmd
+	  func_to_tool_file "$output_objdir/$libname.libcmd"
+	  oldobjs=" $archiver_list_spec$func_to_tool_file_result"
+	  cmds=$old_archive_cmds
+	else
+	  # the command line is too long to link in one step, link in parts
+	  func_verbose "using piecewise archive linking..."
+	  save_RANLIB=$RANLIB
+	  RANLIB=:
+	  objlist=
+	  concat_cmds=
+	  save_oldobjs=$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
+	  eval test_cmds=\"$old_archive_cmds\"
+	  func_len " $test_cmds"
+	  len0=$func_len_result
+	  len=$len0
+	  for obj in $save_oldobjs
+	  do
+	    func_len " $obj"
+	    func_arith $len + $func_len_result
+	    len=$func_arith_result
+	    func_append objlist " $obj"
+	    if test "$len" -lt "$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=
+	      len=$len0
+	    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
+      func_execute_cmds "$cmds" 'exit $?'
+    done
+
+    test -n "$generated" && \
+      func_show_eval "${RM}r$generated"
+
+    # Now create the libtool archive.
+    case $output in
+    *.la)
+      old_library=
+      test "$build_old_libs" = yes && old_library="$libname.$libext"
+      func_verbose "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}\" || $lt_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
+	  func_quote_for_eval "$var_value"
+	  relink_command="$var=$func_quote_for_eval_result; 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 "$relink_command" | $SED "$sed_quote_subst"`
+      if test "$hardcode_automatic" = yes ; then
+	relink_command=
+      fi
+
+      # Only create the output if not a dry run.
+      $opt_dry_run || {
+	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)
+		func_basename "$deplib"
+		name="$func_basename_result"
+		func_resolve_sysroot "$deplib"
+		eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result`
+		test -z "$libdir" && \
+		  func_fatal_error "\`$deplib' is not a valid libtool archive"
+		func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name"
+		;;
+	      -L*)
+		func_stripname -L '' "$deplib"
+		func_replace_sysroot "$func_stripname_result"
+		func_append newdependency_libs " -L$func_replace_sysroot_result"
+		;;
+	      -R*)
+		func_stripname -R '' "$deplib"
+		func_replace_sysroot "$func_stripname_result"
+		func_append newdependency_libs " -R$func_replace_sysroot_result"
+		;;
+	      *) func_append newdependency_libs " $deplib" ;;
+	      esac
+	    done
+	    dependency_libs="$newdependency_libs"
+	    newdlfiles=
+
+	    for lib in $dlfiles; do
+	      case $lib in
+	      *.la)
+	        func_basename "$lib"
+		name="$func_basename_result"
+		eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+		test -z "$libdir" && \
+		  func_fatal_error "\`$lib' is not a valid libtool archive"
+		func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name"
+		;;
+	      *) func_append newdlfiles " $lib" ;;
+	      esac
+	    done
+	    dlfiles="$newdlfiles"
+	    newdlprefiles=
+	    for lib in $dlprefiles; do
+	      case $lib in
+	      *.la)
+		# Only pass preopened files to the pseudo-archive (for
+		# eventual linking with the app. that links it) if we
+		# didn't already link the preopened objects directly into
+		# the library:
+		func_basename "$lib"
+		name="$func_basename_result"
+		eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+		test -z "$libdir" && \
+		  func_fatal_error "\`$lib' is not a valid libtool archive"
+		func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name"
+		;;
+	      esac
+	    done
+	    dlprefiles="$newdlprefiles"
+	  else
+	    newdlfiles=
+	    for lib in $dlfiles; do
+	      case $lib in
+		[\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;;
+		*) abs=`pwd`"/$lib" ;;
+	      esac
+	      func_append newdlfiles " $abs"
+	    done
+	    dlfiles="$newdlfiles"
+	    newdlprefiles=
+	    for lib in $dlprefiles; do
+	      case $lib in
+		[\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;;
+		*) abs=`pwd`"/$lib" ;;
+	      esac
+	      func_append newdlprefiles " $abs"
+	    done
+	    dlprefiles="$newdlprefiles"
+	  fi
+	  $RM $output
+	  # place dlname in correct position for cygwin
+	  # In fact, it would be nice if we could use this code for all target
+	  # systems that can't hard-code library paths into their executables
+	  # and that have no shared library path variable independent of PATH,
+	  # but it turns out we can't easily determine that from inspecting
+	  # libtool variables, so we have to hard-code the OSs to which it
+	  # applies here; at the moment, that means platforms that use the PE
+	  # object format with DLL files.  See the long comment at the top of
+	  # tests/bindir.at for full details.
+	  tdlname=$dlname
+	  case $host,$output,$installed,$module,$dlname in
+	    *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll)
+	      # If a -bindir argument was supplied, place the dll there.
+	      if test "x$bindir" != x ;
+	      then
+		func_relative_path "$install_libdir" "$bindir"
+		tdlname=$func_relative_path_result$dlname
+	      else
+		# Otherwise fall back on heuristic.
+		tdlname=../bin/$dlname
+	      fi
+	      ;;
+	  esac
+	  $ECHO > $output "\
+# $outputname - a libtool library file
+# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
+#
+# 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'
+
+# Linker flags that can not go in dependency_libs.
+inherited_linker_flags='$new_inherited_linker_flags'
+
+# Libraries that this one depends upon.
+dependency_libs='$dependency_libs'
+
+# Names of additional weak libraries provided by this library
+weak_library_names='$weak_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
+      }
+
+      # Do a symbolic link so that the libtool archive can be found in
+      # LD_LIBRARY_PATH before the program is installed.
+      func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?'
+      ;;
+    esac
+    exit $EXIT_SUCCESS
+}
+
+{ test "$opt_mode" = link || test "$opt_mode" = relink; } &&
+    func_mode_link ${1+"$@"}
+
+
+# func_mode_uninstall arg...
+func_mode_uninstall ()
+{
+    $opt_debug
+    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) func_append RM " $arg"; rmforce=yes ;;
+      -*) func_append RM " $arg" ;;
+      *) func_append files " $arg" ;;
+      esac
+    done
+
+    test -z "$RM" && \
+      func_fatal_help "you must specify an RM program"
+
+    rmdirs=
+
+    for file in $files; do
+      func_dirname "$file" "" "."
+      dir="$func_dirname_result"
+      if test "X$dir" = X.; then
+	odir="$objdir"
+      else
+	odir="$dir/$objdir"
+      fi
+      func_basename "$file"
+      name="$func_basename_result"
+      test "$opt_mode" = uninstall && odir="$dir"
+
+      # Remember odir for removal later, being careful to avoid duplicates
+      if test "$opt_mode" = clean; then
+	case " $rmdirs " in
+	  *" $odir "*) ;;
+	  *) func_append rmdirs " $odir" ;;
+	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 func_lalib_p "$file"; then
+	  func_source $dir/$name
+
+	  # Delete the libtool libraries and symlinks.
+	  for n in $library_names; do
+	    func_append rmfiles " $odir/$n"
+	  done
+	  test -n "$old_library" && func_append rmfiles " $odir/$old_library"
+
+	  case "$opt_mode" in
+	  clean)
+	    case " $library_names " in
+	    *" $dlname "*) ;;
+	    *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;;
+	    esac
+	    test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i"
+	    ;;
+	  uninstall)
+	    if test -n "$library_names"; then
+	      # Do each command in the postuninstall commands.
+	      func_execute_cmds "$postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1'
+	    fi
+
+	    if test -n "$old_library"; then
+	      # Do each command in the old_postuninstall commands.
+	      func_execute_cmds "$old_postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1'
+	    fi
+	    # FIXME: should reinstall the best remaining shared library.
+	    ;;
+	  esac
+	fi
+	;;
+
+      *.lo)
+	# Possibly a libtool object, so verify it.
+	if func_lalib_p "$file"; then
+
+	  # Read the .lo file
+	  func_source $dir/$name
+
+	  # Add PIC object to the list of files to remove.
+	  if test -n "$pic_object" &&
+	     test "$pic_object" != none; then
+	    func_append 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
+	    func_append rmfiles " $dir/$non_pic_object"
+	  fi
+	fi
+	;;
+
+      *)
+	if test "$opt_mode" = clean ; then
+	  noexename=$name
+	  case $file in
+	  *.exe)
+	    func_stripname '' '.exe' "$file"
+	    file=$func_stripname_result
+	    func_stripname '' '.exe' "$name"
+	    noexename=$func_stripname_result
+	    # $file with .exe has already been added to rmfiles,
+	    # add $file without .exe
+	    func_append rmfiles " $file"
+	    ;;
+	  esac
+	  # Do a test to see if this is a libtool program.
+	  if func_ltwrapper_p "$file"; then
+	    if func_ltwrapper_executable_p "$file"; then
+	      func_ltwrapper_scriptname "$file"
+	      relink_command=
+	      func_source $func_ltwrapper_scriptname_result
+	      func_append rmfiles " $func_ltwrapper_scriptname_result"
+	    else
+	      relink_command=
+	      func_source $dir/$noexename
+	    fi
+
+	    # note $name still contains .exe if it was in $file originally
+	    # as does the version of $file that was added into $rmfiles
+	    func_append rmfiles " $odir/$name $odir/${name}S.${objext}"
+	    if test "$fast_install" = yes && test -n "$relink_command"; then
+	      func_append rmfiles " $odir/lt-$name"
+	    fi
+	    if test "X$noexename" != "X$name" ; then
+	      func_append rmfiles " $odir/lt-${noexename}.c"
+	    fi
+	  fi
+	fi
+	;;
+      esac
+      func_show_eval "$RM $rmfiles" 'exit_status=1'
+    done
+
+    # Try to remove the ${objdir}s in the directories where we deleted files
+    for dir in $rmdirs; do
+      if test -d "$dir"; then
+	func_show_eval "rmdir $dir >/dev/null 2>&1"
+      fi
+    done
+
+    exit $exit_status
+}
+
+{ test "$opt_mode" = uninstall || test "$opt_mode" = clean; } &&
+    func_mode_uninstall ${1+"$@"}
+
+test -z "$opt_mode" && {
+  help="$generic_help"
+  func_fatal_help "you must specify a MODE"
+}
+
+test -z "$exec_cmd" && \
+  func_fatal_help "invalid operation mode \`$opt_mode'"
+
+if test -n "$exec_cmd"; then
+  eval exec "$exec_cmd"
+  exit $EXIT_FAILURE
+fi
+
+exit $exit_status
+
+
+# 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
+build_libtool_libs=no
+build_old_libs=yes
+# ### END LIBTOOL TAG CONFIG: disable-shared
+
+# ### BEGIN LIBTOOL TAG CONFIG: disable-static
+build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac`
+# ### END LIBTOOL TAG CONFIG: disable-static
+
+# Local Variables:
+# mode:shell-script
+# sh-indentation:2
+# End:
+# vi:sw=2
+
diff --git a/build-aux/missing b/build-aux/missing
new file mode 100755
index 0000000..cdea514
--- /dev/null
+++ b/build-aux/missing
@@ -0,0 +1,215 @@
+#! /bin/sh
+# Common wrapper for a few potentially missing GNU programs.
+
+scriptversion=2012-06-26.16; # UTC
+
+# Copyright (C) 1996-2013 Free Software Foundation, Inc.
+# Originally written 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, see <http://www.gnu.org/licenses/>.
+
+# 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
+
+case $1 in
+
+  --is-lightweight)
+    # Used by our autoconf macros to check whether the available missing
+    # script is modern enough.
+    exit 0
+    ;;
+
+  --run)
+    # Back-compat with the calling convention used by older automake.
+    shift
+    ;;
+
+  -h|--h|--he|--hel|--help)
+    echo "\
+$0 [OPTION]... PROGRAM [ARGUMENT]...
+
+Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due
+to PROGRAM being missing or too old.
+
+Options:
+  -h, --help      display this help and exit
+  -v, --version   output version information and exit
+
+Supported PROGRAM values:
+  aclocal   autoconf  autoheader   autom4te  automake  makeinfo
+  bison     yacc      flex         lex       help2man
+
+Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and
+'g' are ignored when checking the name.
+
+Send bug reports to <bug-automake at gnu.org>."
+    exit $?
+    ;;
+
+  -v|--v|--ve|--ver|--vers|--versi|--versio|--version)
+    echo "missing $scriptversion (GNU Automake)"
+    exit $?
+    ;;
+
+  -*)
+    echo 1>&2 "$0: unknown '$1' option"
+    echo 1>&2 "Try '$0 --help' for more information"
+    exit 1
+    ;;
+
+esac
+
+# Run the given program, remember its exit status.
+"$@"; st=$?
+
+# If it succeeded, we are done.
+test $st -eq 0 && exit 0
+
+# Also exit now if we it failed (or wasn't found), and '--version' was
+# passed; such an option is passed most likely to detect whether the
+# program is present and works.
+case $2 in --version|--help) exit $st;; esac
+
+# Exit code 63 means version mismatch.  This often happens when the user
+# tries to use an ancient version of a tool on a file that requires a
+# minimum version.
+if test $st -eq 63; then
+  msg="probably too old"
+elif test $st -eq 127; then
+  # Program was missing.
+  msg="missing on your system"
+else
+  # Program was found and executed, but failed.  Give up.
+  exit $st
+fi
+
+perl_URL=http://www.perl.org/
+flex_URL=http://flex.sourceforge.net/
+gnu_software_URL=http://www.gnu.org/software
+
+program_details ()
+{
+  case $1 in
+    aclocal|automake)
+      echo "The '$1' program is part of the GNU Automake package:"
+      echo "<$gnu_software_URL/automake>"
+      echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:"
+      echo "<$gnu_software_URL/autoconf>"
+      echo "<$gnu_software_URL/m4/>"
+      echo "<$perl_URL>"
+      ;;
+    autoconf|autom4te|autoheader)
+      echo "The '$1' program is part of the GNU Autoconf package:"
+      echo "<$gnu_software_URL/autoconf/>"
+      echo "It also requires GNU m4 and Perl in order to run:"
+      echo "<$gnu_software_URL/m4/>"
+      echo "<$perl_URL>"
+      ;;
+  esac
+}
+
+give_advice ()
+{
+  # Normalize program name to check for.
+  normalized_program=`echo "$1" | sed '
+    s/^gnu-//; t
+    s/^gnu//; t
+    s/^g//; t'`
+
+  printf '%s\n' "'$1' is $msg."
+
+  configure_deps="'configure.ac' or m4 files included by 'configure.ac'"
+  case $normalized_program in
+    autoconf*)
+      echo "You should only need it if you modified 'configure.ac',"
+      echo "or m4 files included by it."
+      program_details 'autoconf'
+      ;;
+    autoheader*)
+      echo "You should only need it if you modified 'acconfig.h' or"
+      echo "$configure_deps."
+      program_details 'autoheader'
+      ;;
+    automake*)
+      echo "You should only need it if you modified 'Makefile.am' or"
+      echo "$configure_deps."
+      program_details 'automake'
+      ;;
+    aclocal*)
+      echo "You should only need it if you modified 'acinclude.m4' or"
+      echo "$configure_deps."
+      program_details 'aclocal'
+      ;;
+   autom4te*)
+      echo "You might have modified some maintainer files that require"
+      echo "the 'automa4te' program to be rebuilt."
+      program_details 'autom4te'
+      ;;
+    bison*|yacc*)
+      echo "You should only need it if you modified a '.y' file."
+      echo "You may want to install the GNU Bison package:"
+      echo "<$gnu_software_URL/bison/>"
+      ;;
+    lex*|flex*)
+      echo "You should only need it if you modified a '.l' file."
+      echo "You may want to install the Fast Lexical Analyzer package:"
+      echo "<$flex_URL>"
+      ;;
+    help2man*)
+      echo "You should only need it if you modified a dependency" \
+           "of a man page."
+      echo "You may want to install the GNU Help2man package:"
+      echo "<$gnu_software_URL/help2man/>"
+    ;;
+    makeinfo*)
+      echo "You should only need it if you modified a '.texi' file, or"
+      echo "any other file indirectly affecting the aspect of the manual."
+      echo "You might want to install the Texinfo package:"
+      echo "<$gnu_software_URL/texinfo/>"
+      echo "The spurious makeinfo call might also be the consequence of"
+      echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might"
+      echo "want to install GNU make:"
+      echo "<$gnu_software_URL/make/>"
+      ;;
+    *)
+      echo "You might have modified some files without having the proper"
+      echo "tools for further handling them.  Check the 'README' file, it"
+      echo "often tells you about the needed prerequisites for installing"
+      echo "this package.  You may also peek at any GNU archive site, in"
+      echo "case some other package contains this missing '$1' program."
+      ;;
+  esac
+}
+
+give_advice "$1" | sed -e '1s/^/WARNING: /' \
+                       -e '2,$s/^/         /' >&2
+
+# Propagate the correct exit status (expected to be 127 for a program
+# not found, 63 for a program that failed due to version mismatch).
+exit $st
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/build-aux/test-driver b/build-aux/test-driver
new file mode 100755
index 0000000..32bf39e
--- /dev/null
+++ b/build-aux/test-driver
@@ -0,0 +1,127 @@
+#! /bin/sh
+# test-driver - basic testsuite driver script.
+
+scriptversion=2012-06-27.10; # UTC
+
+# Copyright (C) 2011-2013 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, see <http://www.gnu.org/licenses/>.
+
+# 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>.
+
+# Make unconditional expansion of undefined variables an error.  This
+# helps a lot in preventing typo-related bugs.
+set -u
+
+usage_error ()
+{
+  echo "$0: $*" >&2
+  print_usage >&2
+  exit 2
+}
+
+print_usage ()
+{
+  cat <<END
+Usage:
+  test-driver --test-name=NAME --log-file=PATH --trs-file=PATH
+              [--expect-failure={yes|no}] [--color-tests={yes|no}]
+              [--enable-hard-errors={yes|no}] [--] TEST-SCRIPT
+The '--test-name', '--log-file' and '--trs-file' options are mandatory.
+END
+}
+
+# TODO: better error handling in option parsing (in particular, ensure
+# TODO: $log_file, $trs_file and $test_name are defined).
+test_name= # Used for reporting.
+log_file=  # Where to save the output of the test script.
+trs_file=  # Where to save the metadata of the test run.
+expect_failure=no
+color_tests=no
+enable_hard_errors=yes
+while test $# -gt 0; do
+  case $1 in
+  --help) print_usage; exit $?;;
+  --version) echo "test-driver $scriptversion"; exit $?;;
+  --test-name) test_name=$2; shift;;
+  --log-file) log_file=$2; shift;;
+  --trs-file) trs_file=$2; shift;;
+  --color-tests) color_tests=$2; shift;;
+  --expect-failure) expect_failure=$2; shift;;
+  --enable-hard-errors) enable_hard_errors=$2; shift;;
+  --) shift; break;;
+  -*) usage_error "invalid option: '$1'";;
+  esac
+  shift
+done
+
+if test $color_tests = yes; then
+  # Keep this in sync with 'lib/am/check.am:$(am__tty_colors)'.
+  red='' # Red.
+  grn='' # Green.
+  lgn='' # Light green.
+  blu='' # Blue.
+  mgn='' # Magenta.
+  std=''     # No color.
+else
+  red= grn= lgn= blu= mgn= std=
+fi
+
+do_exit='rm -f $log_file $trs_file; (exit $st); exit $st'
+trap "st=129; $do_exit" 1
+trap "st=130; $do_exit" 2
+trap "st=141; $do_exit" 13
+trap "st=143; $do_exit" 15
+
+# Test script is run here.
+"$@" >$log_file 2>&1
+estatus=$?
+if test $enable_hard_errors = no && test $estatus -eq 99; then
+  estatus=1
+fi
+
+case $estatus:$expect_failure in
+  0:yes) col=$red res=XPASS recheck=yes gcopy=yes;;
+  0:*)   col=$grn res=PASS  recheck=no  gcopy=no;;
+  77:*)  col=$blu res=SKIP  recheck=no  gcopy=yes;;
+  99:*)  col=$mgn res=ERROR recheck=yes gcopy=yes;;
+  *:yes) col=$lgn res=XFAIL recheck=no  gcopy=yes;;
+  *:*)   col=$red res=FAIL  recheck=yes gcopy=yes;;
+esac
+
+# Report outcome to console.
+echo "${col}${res}${std}: $test_name"
+
+# Register the test result, and other relevant metadata.
+echo ":test-result: $res" > $trs_file
+echo ":global-test-result: $res" >> $trs_file
+echo ":recheck: $recheck" >> $trs_file
+echo ":copy-in-global-log: $gcopy" >> $trs_file
+
+# 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-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/build-aux/ylwrap b/build-aux/ylwrap
new file mode 100755
index 0000000..1c4d776
--- /dev/null
+++ b/build-aux/ylwrap
@@ -0,0 +1,249 @@
+#! /bin/sh
+# ylwrap - wrapper for lex/yacc invocations.
+
+scriptversion=2012-12-21.17; # UTC
+
+# Copyright (C) 1996-2013 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, see <http://www.gnu.org/licenses/>.
+
+# 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>.
+
+get_dirname ()
+{
+  case $1 in
+    */*|*\\*) printf '%s\n' "$1" | sed -e 's|\([\\/]\)[^\\/]*$|\1|';;
+    # Otherwise,  we want the empty string (not ".").
+  esac
+}
+
+# guard FILE
+# ----------
+# The CPP macro used to guard inclusion of FILE.
+guard()
+{
+  printf '%s\n' "$1"                                                    \
+    | sed                                                               \
+        -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'   \
+        -e 's/[^ABCDEFGHIJKLMNOPQRSTUVWXYZ]/_/g'                        \
+        -e 's/__*/_/g'
+}
+
+# quote_for_sed [STRING]
+# ----------------------
+# Return STRING (or stdin) quoted to be used as a sed pattern.
+quote_for_sed ()
+{
+  case $# in
+    0) cat;;
+    1) printf '%s\n' "$1";;
+  esac \
+    | sed -e 's|[][\\.*]|\\&|g'
+}
+
+case "$1" in
+  '')
+    echo "$0: No files given.  Try '$0 --help' for more information." 1>&2
+    exit 1
+    ;;
+  --basedir)
+    basedir=$2
+    shift 2
+    ;;
+  -h|--h*)
+    cat <<\EOF
+Usage: ylwrap [--help|--version] INPUT [OUTPUT DESIRED]... -- PROGRAM [ARGS]...
+
+Wrapper for lex/yacc invocations, renaming files as desired.
+
+  INPUT is the input file
+  OUTPUT is one file PROG generates
+  DESIRED is the file we actually want instead of OUTPUT
+  PROGRAM is program to run
+  ARGS are passed to PROG
+
+Any number of OUTPUT,DESIRED pairs may be used.
+
+Report bugs to <bug-automake at gnu.org>.
+EOF
+    exit $?
+    ;;
+  -v|--v*)
+    echo "ylwrap $scriptversion"
+    exit $?
+    ;;
+esac
+
+
+# The input.
+input="$1"
+shift
+# We'll later need for a correct munging of "#line" directives.
+input_sub_rx=`get_dirname "$input" | quote_for_sed`
+case "$input" in
+  [\\/]* | ?:[\\/]*)
+    # Absolute path; do nothing.
+    ;;
+  *)
+    # Relative path.  Make it absolute.
+    input="`pwd`/$input"
+    ;;
+esac
+input_rx=`get_dirname "$input" | quote_for_sed`
+
+# Since DOS filename conventions don't allow two dots,
+# the DOS version of Bison writes out y_tab.c instead of y.tab.c
+# and y_tab.h instead of y.tab.h. Test to see if this is the case.
+y_tab_nodot=false
+if test -f y_tab.c || test -f y_tab.h; then
+  y_tab_nodot=true
+fi
+
+# The parser itself, the first file, is the destination of the .y.c
+# rule in the Makefile.
+parser=$1
+
+# A sed program to s/FROM/TO/g for all the FROM/TO so that, for
+# instance, we rename #include "y.tab.h" into #include "parse.h"
+# during the conversion from y.tab.c to parse.c.
+sed_fix_filenames=
+
+# Also rename header guards, as Bison 2.7 for instance uses its header
+# guard in its implementation file.
+sed_fix_header_guards=
+
+while test "$#" -ne 0; do
+  if test "$1" = "--"; then
+    shift
+    break
+  fi
+  from=$1
+  # Handle y_tab.c and y_tab.h output by DOS
+  if $y_tab_nodot; then
+    case $from in
+      "y.tab.c") from=y_tab.c;;
+      "y.tab.h") from=y_tab.h;;
+    esac
+  fi
+  shift
+  to=$1
+  shift
+  sed_fix_filenames="${sed_fix_filenames}s|"`quote_for_sed "$from"`"|$to|g;"
+  sed_fix_header_guards="${sed_fix_header_guards}s|"`guard "$from"`"|"`guard "$to"`"|g;"
+done
+
+# The program to run.
+prog="$1"
+shift
+# Make any relative path in $prog absolute.
+case "$prog" in
+  [\\/]* | ?:[\\/]*) ;;
+  *[\\/]*) prog="`pwd`/$prog" ;;
+esac
+
+# FIXME: add hostname here for parallel makes that run commands on
+# other machines.  But that might take us over the 14-char limit.
+dirname=ylwrap$$
+do_exit="cd '`pwd`' && rm -rf $dirname > /dev/null 2>&1;"' (exit $ret); exit $ret'
+trap "ret=129; $do_exit" 1
+trap "ret=130; $do_exit" 2
+trap "ret=141; $do_exit" 13
+trap "ret=143; $do_exit" 15
+mkdir $dirname || exit 1
+
+cd $dirname
+
+case $# in
+  0) "$prog" "$input" ;;
+  *) "$prog" "$@" "$input" ;;
+esac
+ret=$?
+
+if test $ret -eq 0; then
+  for from in *
+  do
+    to=`printf '%s\n' "$from" | sed "$sed_fix_filenames"`
+    if test -f "$from"; then
+      # If $2 is an absolute path name, then just use that,
+      # otherwise prepend '../'.
+      case $to in
+        [\\/]* | ?:[\\/]*) target=$to;;
+        *) target="../$to";;
+      esac
+
+      # Do not overwrite unchanged header files to avoid useless
+      # recompilations.  Always update the parser itself: it is the
+      # destination of the .y.c rule in the Makefile.  Divert the
+      # output of all other files to a temporary file so we can
+      # compare them to existing versions.
+      if test $from != $parser; then
+        realtarget="$target"
+        target=tmp-`printf '%s\n' "$target" | sed 's|.*[\\/]||g'`
+      fi
+
+      # Munge "#line" or "#" directives.  Don't let the resulting
+      # debug information point at an absolute srcdir.  Use the real
+      # output file name, not yy.lex.c for instance.  Adjust the
+      # include guards too.
+      sed -e "/^#/!b"                           \
+          -e "s|$input_rx|$input_sub_rx|"       \
+          -e "$sed_fix_filenames"               \
+          -e "$sed_fix_header_guards"           \
+        "$from" >"$target" || ret=$?
+
+      # Check whether files must be updated.
+      if test "$from" != "$parser"; then
+        if test -f "$realtarget" && cmp -s "$realtarget" "$target"; then
+          echo "$to is unchanged"
+          rm -f "$target"
+        else
+          echo "updating $to"
+          mv -f "$target" "$realtarget"
+        fi
+      fi
+    else
+      # A missing file is only an error for the parser.  This is a
+      # blatant hack to let us support using "yacc -d".  If -d is not
+      # specified, don't fail when the header file is "missing".
+      if test "$from" = "$parser"; then
+        ret=1
+      fi
+    fi
+  done
+fi
+
+# Remove the directory.
+cd ..
+rm -rf $dirname
+
+exit $ret
+
+# 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-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/configure b/configure
new file mode 100755
index 0000000..c2d9b34
--- /dev/null
+++ b/configure
@@ -0,0 +1,25721 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.69 for singular 4.0.1.
+#
+# Report bugs to <singular at mathematik.uni-kl.de>.
+#
+#
+# Copyright (C) 1992-1996, 1998-2012 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.
+as_myself=
+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
+
+# Use a proper internal environment variable to ensure we don't fall
+  # into an infinite loop, continuously re-executing ourselves.
+  if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then
+    _as_can_reexec=no; export _as_can_reexec;
+    # 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.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+  *v*x* | *x*v* ) as_opts=-vx ;;
+  *v* ) as_opts=-v ;;
+  *x* ) as_opts=-x ;;
+  * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+as_fn_exit 255
+  fi
+  # We don't want this to propagate to other subprocesses.
+          { _as_can_reexec=; unset _as_can_reexec;}
+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
+test -x / || 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
+
+  test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || (
+    ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+    ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO
+    ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO
+    PATH=/empty FPATH=/empty; export PATH FPATH
+    test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\
+      || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || 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 :
+  export CONFIG_SHELL
+             # 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.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+  *v*x* | *x*v* ) as_opts=-vx ;;
+  *v* ) as_opts=-v ;;
+  *x* ) as_opts=-x ;;
+  * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+exit 255
+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 and
+$0: singular at mathematik.uni-kl.de 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_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+  test -f "$1" && test -x "$1"
+} # as_fn_executable_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 STATUS 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=$1; test $as_status -eq 0 && as_status=1
+  if test "$4"; then
+    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+  fi
+  $as_echo "$as_me: error: $2" >&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; }
+
+  # If we had to re-execute with $CONFIG_SHELL, we're ensured to have
+  # already done that, so ensure we don't try to do so again and fall
+  # in an infinite loop.  This has already happened in practice.
+  _as_can_reexec=no; export _as_can_reexec
+  # 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 -pR'.
+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+      as_ln_s='cp -pR'
+  elif ln conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s=ln
+  else
+    as_ln_s='cp -pR'
+  fi
+else
+  as_ln_s='cp -pR'
+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
+
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
+
+# 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'"
+
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+
+test -n "$DJDIR" || exec 7<&0 </dev/null
+exec 6>&1
+
+# Name of the host.
+# hostname on some systems (SVR3.2, old GNU/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='singular'
+PACKAGE_TARNAME='singular'
+PACKAGE_VERSION='4.0.1'
+PACKAGE_STRING='singular 4.0.1'
+PACKAGE_BUGREPORT='singular at mathematik.uni-kl.de'
+PACKAGE_URL=''
+
+ac_unique_file="Singular/tesths.cc"
+# 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"
+
+enable_option_checking=no
+ac_subst_vars='am__EXEEXT_FALSE
+am__EXEEXT_TRUE
+LTLIBOBJS
+subdirs
+DOC_DIR
+DATA_DIR
+SI_COUNTEDREF_AUTOLOAD
+SI_BUILTIN_ORDER_FALSE
+SI_BUILTIN_ORDER_TRUE
+SI_BUILTIN_BIGINTM_FALSE
+SI_BUILTIN_BIGINTM_TRUE
+SI_BUILTIN_SINGMATHIC_FALSE
+SI_BUILTIN_SINGMATHIC_TRUE
+SI_BUILTIN_POLYMAKE_FALSE
+SI_BUILTIN_POLYMAKE_TRUE
+SI_BUILTIN_GFANLIB_FALSE
+SI_BUILTIN_GFANLIB_TRUE
+SI_BUILTIN_PYOBJECT_FALSE
+SI_BUILTIN_PYOBJECT_TRUE
+SI_BUILTIN_SYZEXTRA_FALSE
+SI_BUILTIN_SYZEXTRA_TRUE
+SI_BUILTIN_STATICDEMO_FALSE
+SI_BUILTIN_STATICDEMO_TRUE
+BUILTIN_LIBS
+ENABLE_PLURAL_FALSE
+ENABLE_PLURAL_TRUE
+SING_HAVE_POLYMAKE_FALSE
+SING_HAVE_POLYMAKE_TRUE
+PM_LDFLAGS
+PM_LIBS
+PM_CFLAGS
+PM_INC
+PMCONFIG
+HAVE_GFANLIB_FALSE
+HAVE_GFANLIB_TRUE
+CDDGMPCPPFLAGS
+CDDGMPLDFLAGS
+ENABLE_P_PROCS_STATIC_FALSE
+ENABLE_P_PROCS_STATIC_TRUE
+ENABLE_P_PROCS_DYNAMIC_FALSE
+ENABLE_P_PROCS_DYNAMIC_TRUE
+USEPPROCSDYNAMICLD
+USEPPROCSDYNAMICLDFLAGS
+ENABLE_FACTORY_FALSE
+ENABLE_FACTORY_TRUE
+FACTORY_LIBS
+FACTORY_INCLUDES
+ENABLE_RESOURCES_FALSE
+ENABLE_RESOURCES_TRUE
+RESOURCES_LIBS
+RESOURCES_INCLUDES
+ENABLE_OMALLOC_FALSE
+ENABLE_OMALLOC_TRUE
+OMALLOC_LIBS
+OMALLOC_INCLUDES
+PKG_REQUIRE
+SI_CPU_PPC
+SI_CPU_SPARC
+SI_CPU_IA64
+SI_CPU_X86_64
+SI_CPU_I386
+LIBOBJS
+PYTHON_MODULE_FALSE
+PYTHON_MODULE_TRUE
+SI_EMBED_PYTHON_FALSE
+SI_EMBED_PYTHON_TRUE
+PYTHON_CSPEC
+PYTHON_LSPEC
+PYTHON_EXECPREFIX
+PYTHON_PREFIX
+PYTHON
+PYTHON_USE_FALSE
+PYTHON_USE_TRUE
+SING_HAVE_FLINT_FALSE
+SING_HAVE_FLINT_TRUE
+FLINT_HOME
+FLINT_LIBS
+FLINT_CFLAGS
+SING_HAVE_NTL_FALSE
+SING_HAVE_NTL_TRUE
+NTL_LIBS
+NTL_CFLAGS
+SING_HAVE_GMP_FALSE
+SING_HAVE_GMP_TRUE
+GMP_VERSION
+GMP_HOME
+GMP_LIBS
+GMP_CFLAGS
+PTHREAD_LDFLAGS
+PTHREAD_CFLAGS
+PTHREAD_LIBS
+PTHREAD_CC
+ax_pthread_config
+OTOOL64
+OTOOL
+LIPO
+NMEDIT
+DSYMUTIL
+MANIFEST_TOOL
+RANLIB
+DLLTOOL
+OBJDUMP
+NM
+ac_ct_DUMPBIN
+DUMPBIN
+LD
+FGREP
+SED
+host_os
+host_vendor
+host_cpu
+host
+build_os
+build_vendor
+build_cpu
+build
+LIBTOOL
+HAVE_DOXYGEN_FALSE
+HAVE_DOXYGEN_TRUE
+DOXYGEN
+ac_ct_AR
+AR
+LN_S
+CXXCPP
+POLYMAKE_CXXFLAGS
+am__fastdepCXX_FALSE
+am__fastdepCXX_TRUE
+CXXDEPMODE
+ac_ct_CXX
+CXXFLAGS
+CXX
+SINGULAR_CFLAGS
+WANT_OPTIMIZATIONFLAGS_FALSE
+WANT_OPTIMIZATIONFLAGS_TRUE
+WANT_DEBUG_FALSE
+WANT_DEBUG_TRUE
+AM_BACKSLASH
+AM_DEFAULT_VERBOSITY
+AM_DEFAULT_V
+AM_V
+am__fastdepCC_FALSE
+am__fastdepCC_TRUE
+CCDEPMODE
+am__nodep
+AMDEPBACKSLASH
+AMDEP_FALSE
+AMDEP_TRUE
+am__quote
+am__include
+DEPDIR
+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
+MAINT
+MAINTAINER_MODE_FALSE
+MAINTAINER_MODE_TRUE
+EGREP
+GREP
+CPP
+OBJEXT
+EXEEXT
+ac_ct_CC
+CPPFLAGS
+LDFLAGS
+CFLAGS
+CC
+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
+enable_dependency_tracking
+enable_silent_rules
+enable_debug
+enable_optimizationflags
+enable_shared
+enable_static
+with_pic
+enable_fast_install
+with_gnu_ld
+with_sysroot
+enable_libtool_lock
+with_gmp
+with_ntl
+with_flint
+with_google_perftools
+enable_google_profiling
+with_python
+with_mathicgb
+enable_omalloc
+enable_resources
+enable_factory
+enable_p_procs_static
+enable_p_procs_dynamic
+with_readline
+with_dbm
+enable_gfanlib
+enable_polymake
+enable_plural
+with_RatGB
+with_builtinmodules
+enable_countedref
+'
+      ac_precious_vars='build_alias
+host_alias
+target_alias
+CC
+CFLAGS
+LDFLAGS
+LIBS
+CPPFLAGS
+CPP
+CXX
+CXXFLAGS
+CCC
+CXXCPP
+PYTHON
+BUILTIN_LIBS'
+ac_subdirs_all='resources
+omalloc
+factory
+libpolys
+gfanlib'
+
+# 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_TARNAME}'
+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= ;;
+  *)    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
+  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 singular 4.0.1 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/singular]
+  --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
+  case $ac_init_help in
+     short | recursive ) echo "Configuration of singular 4.0.1:";;
+   esac
+  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]
+  --disable-maintainer-mode
+                          disable make rules and dependencies not useful (and
+                          sometimes confusing) to the casual installer
+  --enable-dependency-tracking
+                          do not reject slow dependency extractors
+  --disable-dependency-tracking
+                          speeds up one-time build
+  --enable-silent-rules   less verbose build output (undo: "make V=1")
+  --disable-silent-rules  verbose build output (undo: "make V=0")
+  --enable-debug          build the debugging version of the libraries
+  --disable-optimizationflags
+                          build the without default optimization flags
+  --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-google-profiling
+                          compile with google profiling
+  --disable-omalloc       do NOT use omalloc within the factory
+  --disable-resources     do NOT use libresources within the factory
+  --disable-factory       Disable factory
+  --enable-p-procs-static Enable statically compiled p_Procs-modules
+
+  --enable-p-procs-dynamic Enable dynamically compiled p_Procs-modules
+
+  --enable-gfanlib        Enables gfanlib, a package for basic convex geometry
+  --enable-polymake       Enables interface for Singular to Polymake (needs
+                          gfanlib)
+  --disable-plural        Disable non-commutative subsystem
+  --enable-countedref     Enable autoloading of reference counted types
+
+Optional Packages:
+  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
+  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
+  --with-pic[=PKGS]       try to use only PIC/non-PIC objects [default=use
+                          both]
+  --with-gnu-ld           assume the C compiler uses GNU ld [default=no]
+  --with-sysroot=DIR Search for dependent libraries within DIR
+                        (or the compiler's sysroot if not specified).
+  --with-gmp= <path>|yes Use GMP library. This library is mandatory for Singular
+	                 compilation. If argument is yes or <empty> that means
+   	       		 the library is reachable with the standard search path
+			 "/usr" or "/usr/local" (set as default). Otherwise you
+			 give the <path> to the directory which contain the
+			 library.
+
+  --with-ntl=<path>|yes|no  Use NTL library. If argument is no, you do not have
+                            the library installed on your machine (set as
+			    default). If argument is yes or <empty> that means
+			    the library is reachable with the standard search
+			    path (/usr or /usr/local). Otherwise you give the
+			    <path> to the directory which contain the library.
+
+  --with-flint=<path>|yes|no  Use FLINT library. If argument is no, you do not have
+                            the library installed on your machine (set as
+			    default). If argument is yes or <empty> that means
+			    the library is reachable with the standard search
+			    path (/usr or /usr/local). Otherwise you give the
+			    <path> to the directory which contain the library.
+
+  --with-google-perftools=DIR
+                          location of a google perftools installation (default
+                          none)
+  --with-python           absolute path name of Python executable
+  --with-mathicgb=yes|no  Use the MathicGB library. Default is no.
+  --with-readline=dynamic,static,no
+                        do use dynamic/static/no readline for fancy display
+  --without-dbm           do not use dbm (no DBM links)
+  --with-ratGB            do compile with ratGB support (experimental)
+  --with-builtinmodules   List of builtin modules (experimental), default:
+                          staticdemo,bigintm,syzextra
+
+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    (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
+              you have headers in a nonstandard directory <include dir>
+  CPP         C preprocessor
+  CXX         C++ compiler command
+  CXXFLAGS    C++ compiler flags
+  CXXCPP      C++ preprocessor
+  PYTHON      Python Executable Path
+  BUILTIN_LIBS
+              LIB FLAGS for buildins
+
+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 <singular at mathematik.uni-kl.de>.
+_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
+singular configure 4.0.1
+generated by GNU Autoconf 2.69
+
+Copyright (C) 2012 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; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_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; } > conftest.i && {
+	 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; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_cpp
+
+# 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 eval \${$3+:} false; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; 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.i 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;}
+( $as_echo "## -------------------------------------------- ##
+## Report this to singular at mathematik.uni-kl.de ##
+## -------------------------------------------- ##"
+     ) | sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; 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; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_header_mongrel
+
+# 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; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_run
+
+# 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 eval \${$3+:} false; 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; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_header_compile
+
+# ac_fn_cxx_try_compile LINENO
+# ----------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_cxx_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_cxx_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; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_cxx_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 ||
+	 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; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_link
+
+# ac_fn_cxx_try_cpp LINENO
+# ------------------------
+# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
+ac_fn_cxx_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; } > conftest.i && {
+	 test -z "$ac_cxx_preproc_warn_flag$ac_cxx_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; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_cxx_try_cpp
+
+# 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 eval \${$3+:} false; 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; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_func
+
+# ac_fn_cxx_try_link LINENO
+# -------------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded.
+ac_fn_cxx_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_cxx_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext && {
+	 test "$cross_compiling" = yes ||
+	 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; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_cxx_try_link
+
+# ac_fn_cxx_try_run LINENO
+# ------------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes
+# that executables *can* be run.
+ac_fn_cxx_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; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_cxx_try_run
+
+# ac_fn_cxx_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_cxx_check_header_mongrel ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if eval \${$3+:} false; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; 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_cxx_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_cxx_try_cpp "$LINENO"; then :
+  ac_header_preproc=yes
+else
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.i 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_cxx_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;}
+( $as_echo "## -------------------------------------------- ##
+## Report this to singular at mathematik.uni-kl.de ##
+## -------------------------------------------- ##"
+     ) | sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; 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; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_cxx_check_header_mongrel
+
+# ac_fn_c_compute_int LINENO EXPR VAR INCLUDES
+# --------------------------------------------
+# Tries to find the compile-time value of EXPR in a program that includes
+# INCLUDES, setting VAR accordingly. Returns whether the value could be
+# computed
+ac_fn_c_compute_int ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if test "$cross_compiling" = yes; then
+    # Depending upon the size, compute the lo and hi bounds.
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) >= 0)];
+test_array [0] = 0;
+return test_array [0];
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_lo=0 ac_mid=0
+  while :; do
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) <= $ac_mid)];
+test_array [0] = 0;
+return test_array [0];
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_hi=$ac_mid; break
+else
+  as_fn_arith $ac_mid + 1 && ac_lo=$as_val
+			if test $ac_lo -le $ac_mid; then
+			  ac_lo= ac_hi=
+			  break
+			fi
+			as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) < 0)];
+test_array [0] = 0;
+return test_array [0];
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_hi=-1 ac_mid=-1
+  while :; do
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) >= $ac_mid)];
+test_array [0] = 0;
+return test_array [0];
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_lo=$ac_mid; break
+else
+  as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val
+			if test $ac_mid -le $ac_hi; then
+			  ac_lo= ac_hi=
+			  break
+			fi
+			as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
+else
+  ac_lo= ac_hi=
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+# Binary search between lo and hi bounds.
+while test "x$ac_lo" != "x$ac_hi"; do
+  as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) <= $ac_mid)];
+test_array [0] = 0;
+return test_array [0];
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_hi=$ac_mid
+else
+  as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+case $ac_lo in #((
+?*) eval "$3=\$ac_lo"; ac_retval=0 ;;
+'') ac_retval=1 ;;
+esac
+  else
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+static long int longval () { return $2; }
+static unsigned long int ulongval () { return $2; }
+#include <stdio.h>
+#include <stdlib.h>
+int
+main ()
+{
+
+  FILE *f = fopen ("conftest.val", "w");
+  if (! f)
+    return 1;
+  if (($2) < 0)
+    {
+      long int i = longval ();
+      if (i != ($2))
+	return 1;
+      fprintf (f, "%ld", i);
+    }
+  else
+    {
+      unsigned long int i = ulongval ();
+      if (i != ($2))
+	return 1;
+      fprintf (f, "%lu", i);
+    }
+  /* Do not output a trailing newline, as this causes \r\n confusion
+     on some platforms.  */
+  return ferror (f) || fclose (f) != 0;
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  echo >>conftest.val; read $3 <conftest.val; ac_retval=0
+else
+  ac_retval=1
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+rm -f conftest.val
+
+  fi
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_compute_int
+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 singular $as_me 4.0.1, which was
+generated by GNU Autoconf 2.69.  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
+
+    $as_echo "## ---------------- ##
+## Cache variables. ##
+## ---------------- ##"
+    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
+
+    $as_echo "## ----------------- ##
+## Output variables. ##
+## ----------------- ##"
+    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
+      $as_echo "## ------------------- ##
+## File substitutions. ##
+## ------------------- ##"
+      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
+      $as_echo "## ----------- ##
+## confdefs.h. ##
+## ----------- ##"
+      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
+  # We do not want a PATH search for config.site.
+  case $CONFIG_SITE in #((
+    -*)  ac_site_file1=./$CONFIG_SITE;;
+    */*) ac_site_file1=$CONFIG_SITE;;
+    *)   ac_site_file1=./$CONFIG_SITE;;
+  esac
+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 /dev/null != "$ac_site_file" && 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" \
+      || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "failed to load site script $ac_site_file
+See \`config.log' for more details" "$LINENO" 5; }
+  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.  DJGPP emulates it as a regular file.
+  if test /dev/null != "$cache_file" && 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
+
+
+
+$as_echo "#define VERSION_DATE \"Sep 2014\"" >>confdefs.h
+
+
+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
+
+
+
+ac_aux_dir=
+for ac_dir in build-aux "$srcdir"/build-aux; do
+  if test -f "$ac_dir/install-sh"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install-sh -c"
+    break
+  elif test -f "$ac_dir/install.sh"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install.sh -c"
+    break
+  elif test -f "$ac_dir/shtool"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/shtool install -c"
+    break
+  fi
+done
+if test -z "$ac_aux_dir"; then
+  as_fn_error $? "cannot find install-sh, install.sh, or shtool in build-aux \"$srcdir\"/build-aux" "$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.
+
+
+
+
+
+ac_config_headers="$ac_config_headers _config.h"
+
+# Add pre'prefixed config
+
+ac_config_commands="$ac_config_commands singularconfig.h"
+
+
+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 ${ac_cv_prog_CC+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_CC+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_CC+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_CC+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_CC+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_CC+:} false; 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 as_fn_executable_p "$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
+  fi
+  rm -f conftest.er1 conftest.err
+  $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.  */
+
+int
+main ()
+{
+
+  ;
+  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"
+# 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 whether the C compiler works" >&5
+$as_echo_n "checking whether the C compiler works... " >&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
+if test -z "$ac_file"; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+$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 77 "C compiler cannot create executables
+See \`config.log' for more details" "$LINENO" 5; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+fi
+{ $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; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
+$as_echo "$ac_file" >&6; }
+ac_exeext=$ac_cv_exeext
+
+rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+{ $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 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
+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="$ac_clean_files conftest.out"
+# 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; }
+if test "$cross_compiling" != yes; then
+  { { 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; }
+  if { ac_try='./conftest$ac_cv_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
+    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: $cross_compiling" >&5
+$as_echo "$cross_compiling" >&6; }
+
+rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out
+ac_clean_files=$ac_clean_files_save
+{ $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 ${ac_cv_objext+:} false; 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 ${ac_cv_c_compiler_gnu+:} false; 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 ${ac_cv_prog_cc_g+:} false; 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 ${ac_cv_prog_cc_c89+:} false; 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>
+struct stat;
+/* 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
+
+
+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 ${ac_cv_prog_CPP+:} false; 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.i 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.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i 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.i 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.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i 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 grep that handles long lines and -e" >&5
+$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
+if ${ac_cv_path_GREP+:} false; 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"
+      as_fn_executable_p "$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 ${ac_cv_path_EGREP+:} false; 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"
+      as_fn_executable_p "$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 ANSI C header files" >&5
+$as_echo_n "checking for ANSI C header files... " >&6; }
+if ${ac_cv_header_stdc+:} false; 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
+"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+
+  ac_fn_c_check_header_mongrel "$LINENO" "minix/config.h" "ac_cv_header_minix_config_h" "$ac_includes_default"
+if test "x$ac_cv_header_minix_config_h" = xyes; then :
+  MINIX=yes
+else
+  MINIX=
+fi
+
+
+  if test "$MINIX" = yes; then
+
+$as_echo "#define _POSIX_SOURCE 1" >>confdefs.h
+
+
+$as_echo "#define _POSIX_1_SOURCE 2" >>confdefs.h
+
+
+$as_echo "#define _MINIX 1" >>confdefs.h
+
+  fi
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether it is safe to define __EXTENSIONS__" >&5
+$as_echo_n "checking whether it is safe to define __EXTENSIONS__... " >&6; }
+if ${ac_cv_safe_to_define___extensions__+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#         define __EXTENSIONS__ 1
+          $ac_includes_default
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_safe_to_define___extensions__=yes
+else
+  ac_cv_safe_to_define___extensions__=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_safe_to_define___extensions__" >&5
+$as_echo "$ac_cv_safe_to_define___extensions__" >&6; }
+  test $ac_cv_safe_to_define___extensions__ = yes &&
+    $as_echo "#define __EXTENSIONS__ 1" >>confdefs.h
+
+  $as_echo "#define _ALL_SOURCE 1" >>confdefs.h
+
+  $as_echo "#define _GNU_SOURCE 1" >>confdefs.h
+
+  $as_echo "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h
+
+  $as_echo "#define _TANDEM_SOURCE 1" >>confdefs.h
+
+
+
+
+{ $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=yes
+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
+
+
+am__api_version='1.13'
+
+# 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 ${ac_cv_path_install+:} false; 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 as_fn_executable_p "$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; }
+# 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 (
+   am_has_slept=no
+   for am_try in 1 2; do
+     echo "timestamp, slept: $am_has_slept" > conftest.file
+     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
+     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
+     if test "$2" = conftest.file || test $am_try -eq 2; then
+       break
+     fi
+     # Just in case.
+     sleep 1
+     am_has_slept=yes
+   done
+   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; }
+# If we didn't sleep, we still need to ensure time stamps of config.status and
+# generated files are strictly newer.
+am_sleep_pid=
+if grep 'slept: no' conftest.file >/dev/null 2>&1; then
+  ( sleep 1 ) &
+  am_sleep_pid=$!
+fi
+
+rm -f conftest.file
+
+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 --is-lightweight"; then
+  am_missing_run="$MISSING "
+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 ${ac_cv_prog_STRIP+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_STRIP+:} false; 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 as_fn_executable_p "$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 ${ac_cv_path_mkdir+:} false; 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
+	   as_fn_executable_p "$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
+
+  test -d ./--version && rmdir ./--version
+  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.
+    MKDIR_P="$ac_install_sh -d"
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5
+$as_echo "$MKDIR_P" >&6; }
+
+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 ${ac_cv_prog_AWK+:} false; 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 as_fn_executable_p "$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 eval \${ac_cv_prog_make_${ac_make}_set+:} false; 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
+
+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='\'
+  am__nodep='_no'
+fi
+ if test "x$enable_dependency_tracking" != xno; then
+  AMDEP_TRUE=
+  AMDEP_FALSE='#'
+else
+  AMDEP_TRUE='#'
+  AMDEP_FALSE=
+fi
+
+
+# Check whether --enable-silent-rules was given.
+if test "${enable_silent_rules+set}" = set; then :
+  enableval=$enable_silent_rules;
+fi
+
+case $enable_silent_rules in # (((
+  yes) AM_DEFAULT_VERBOSITY=0;;
+   no) AM_DEFAULT_VERBOSITY=1;;
+    *) AM_DEFAULT_VERBOSITY=1;;
+esac
+am_make=${MAKE-make}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5
+$as_echo_n "checking whether $am_make supports nested variables... " >&6; }
+if ${am_cv_make_support_nested_variables+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if $as_echo 'TRUE=$(BAR$(V))
+BAR0=false
+BAR1=true
+V=1
+am__doit:
+	@$(TRUE)
+.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then
+  am_cv_make_support_nested_variables=yes
+else
+  am_cv_make_support_nested_variables=no
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5
+$as_echo "$am_cv_make_support_nested_variables" >&6; }
+if test $am_cv_make_support_nested_variables = yes; then
+    AM_V='$(V)'
+  AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
+else
+  AM_V=$AM_DEFAULT_VERBOSITY
+  AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY
+fi
+AM_BACKSLASH='\'
+
+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='singular'
+ VERSION='4.0.1'
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE "$PACKAGE"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define VERSION "$VERSION"
+_ACEOF
+
+# 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"}
+
+# For better backward compatibility.  To be removed once Automake 1.9.x
+# dies out for good.  For more background, see:
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
+mkdir_p='$(MKDIR_P)'
+
+# We need awk for the "check" target.  The system "awk" is bad on
+# some platforms.
+# Always define AMTAR for backward compatibility.  Yes, it's still used
+# in the wild :-(  We should find a proper way to deprecate it ...
+AMTAR='$${TAR-tar}'
+
+
+# We'll loop over all known methods to create a tar archive until one works.
+_am_tools='gnutar  pax cpio none'
+
+am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'
+
+
+
+
+
+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 ${am_cv_CC_dependencies_compiler_type+:} false; 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".
+  rm -rf conftest.dir
+  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 10 /bin/sh.
+      echo '/* dummy */' > 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
+      ;;
+    msvc7 | msvc7msys | 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
+
+
+ # -Wno-extra-portability -Werror silent-rules
+
+# Check whether --enable-silent-rules was given.
+if test "${enable_silent_rules+set}" = set; then :
+  enableval=$enable_silent_rules;
+fi
+
+case $enable_silent_rules in # (((
+  yes) AM_DEFAULT_VERBOSITY=0;;
+   no) AM_DEFAULT_VERBOSITY=1;;
+    *) AM_DEFAULT_VERBOSITY=0;;
+esac
+am_make=${MAKE-make}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5
+$as_echo_n "checking whether $am_make supports nested variables... " >&6; }
+if ${am_cv_make_support_nested_variables+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if $as_echo 'TRUE=$(BAR$(V))
+BAR0=false
+BAR1=true
+V=1
+am__doit:
+	@$(TRUE)
+.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then
+  am_cv_make_support_nested_variables=yes
+else
+  am_cv_make_support_nested_variables=no
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5
+$as_echo "$am_cv_make_support_nested_variables" >&6; }
+if test $am_cv_make_support_nested_variables = yes; then
+    AM_V='$(V)'
+  AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
+else
+  AM_V=$AM_DEFAULT_VERBOSITY
+  AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY
+fi
+AM_BACKSLASH='\'
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5
+$as_echo_n "checking whether build environment is sane... " >&6; }
+# 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 (
+   am_has_slept=no
+   for am_try in 1 2; do
+     echo "timestamp, slept: $am_has_slept" > conftest.file
+     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
+     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
+     if test "$2" = conftest.file || test $am_try -eq 2; then
+       break
+     fi
+     # Just in case.
+     sleep 1
+     am_has_slept=yes
+   done
+   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; }
+# If we didn't sleep, we still need to ensure time stamps of config.status and
+# generated files are strictly newer.
+am_sleep_pid=
+if grep 'slept: no' conftest.file >/dev/null 2>&1; then
+  ( sleep 1 ) &
+  am_sleep_pid=$!
+fi
+
+rm -f conftest.file
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Please note that we set empty defaults for \`CFLAGS' and \`CXXFLAGS' (instead of \`-g -O')" >&5
+$as_echo "$as_me: WARNING: Please note that we set empty defaults for \`CFLAGS' and \`CXXFLAGS' (instead of \`-g -O')" >&2;}
+ : ${CFLAGS:=""}
+ : ${CXXFLAGS:=""}
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts " >&5
+$as_echo_n "checking whether C compiler accepts ... " >&6; }
+if ${ax_cv_check_cflags__+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$CFLAGS
+  CFLAGS="$CFLAGS   -Werror"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ax_cv_check_cflags__=yes
+else
+  ax_cv_check_cflags__=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  CFLAGS=$ax_check_save_flags
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags__" >&5
+$as_echo "$ax_cv_check_cflags__" >&6; }
+if test x"$ax_cv_check_cflags__" = xyes; then :
+  :
+else
+  :
+fi
+
+if ${CFLAGS+:} false; then :
+  case " $CFLAGS " in
+    *"  "*)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS already contains "; } >&5
+  (: CFLAGS already contains ) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      ;;
+    *)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS=\"\$CFLAGS \""; } >&5
+  (: CFLAGS="$CFLAGS ") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      CFLAGS="$CFLAGS "
+      ;;
+   esac
+else
+  CFLAGS=""
+fi
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+if test -z "$CXX"; then
+  if test -n "$CCC"; then
+    CXX=$CCC
+  else
+    if test -n "$ac_tool_prefix"; then
+  for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+  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 ${ac_cv_prog_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CXX"; then
+  ac_cv_prog_CXX="$CXX" # 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CXX="$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
+CXX=$ac_cv_prog_CXX
+if test -n "$CXX"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5
+$as_echo "$CXX" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+    test -n "$CXX" && break
+  done
+fi
+if test -z "$CXX"; then
+  ac_ct_CXX=$CXX
+  for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+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 ${ac_cv_prog_ac_ct_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_CXX"; then
+  ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CXX="$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_CXX=$ac_cv_prog_ac_ct_CXX
+if test -n "$ac_ct_CXX"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5
+$as_echo "$ac_ct_CXX" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$ac_ct_CXX" && break
+done
+
+  if test "x$ac_ct_CXX" = x; then
+    CXX="g++"
+  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
+    CXX=$ac_ct_CXX
+  fi
+fi
+
+  fi
+fi
+# 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
+  fi
+  rm -f conftest.er1 conftest.err
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+done
+
+{ $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 ${ac_cv_cxx_compiler_gnu+:} false; 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_cxx_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_cxx_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5
+$as_echo "$ac_cv_cxx_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+  GXX=yes
+else
+  GXX=
+fi
+ac_test_CXXFLAGS=${CXXFLAGS+set}
+ac_save_CXXFLAGS=$CXXFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5
+$as_echo_n "checking whether $CXX accepts -g... " >&6; }
+if ${ac_cv_prog_cxx_g+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_save_cxx_werror_flag=$ac_cxx_werror_flag
+   ac_cxx_werror_flag=yes
+   ac_cv_prog_cxx_g=no
+   CXXFLAGS="-g"
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ac_cv_prog_cxx_g=yes
+else
+  CXXFLAGS=""
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+
+else
+  ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+	 CXXFLAGS="-g"
+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ac_cv_prog_cxx_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_cxx_werror_flag=$ac_save_cxx_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5
+$as_echo "$ac_cv_prog_cxx_g" >&6; }
+if test "$ac_test_CXXFLAGS" = set; then
+  CXXFLAGS=$ac_save_CXXFLAGS
+elif test $ac_cv_prog_cxx_g = yes; then
+  if test "$GXX" = yes; then
+    CXXFLAGS="-g -O2"
+  else
+    CXXFLAGS="-g"
+  fi
+else
+  if test "$GXX" = yes; then
+    CXXFLAGS="-O2"
+  else
+    CXXFLAGS=
+  fi
+fi
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+depcc="$CXX"  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 ${am_cv_CXX_dependencies_compiler_type+:} false; 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".
+  rm -rf conftest.dir
+  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_CXX_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 10 /bin/sh.
+      echo '/* dummy */' > 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
+      ;;
+    msvc7 | msvc7msys | 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_CXX_dependencies_compiler_type=$depmode
+        break
+      fi
+    fi
+  done
+
+  cd ..
+  rm -rf conftest.dir
+else
+  am_cv_CXX_dependencies_compiler_type=none
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5
+$as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; }
+CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type
+
+ if
+  test "x$enable_dependency_tracking" != xno \
+  && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then
+  am__fastdepCXX_TRUE=
+  am__fastdepCXX_FALSE='#'
+else
+  am__fastdepCXX_TRUE='#'
+  am__fastdepCXX_FALSE=
+fi
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the linker accepts " >&5
+$as_echo_n "checking whether the linker accepts ... " >&6; }
+if ${ax_cv_check_ldflags__+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$LDFLAGS
+  LDFLAGS="$LDFLAGS  "
+  _save_cflags="$CFLAGS"
+  CFLAGS="$CFLAGS -Werror"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ax_cv_check_ldflags__=yes
+else
+  ax_cv_check_ldflags__=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+  CFLAGS="$_save_cflags"
+  LDFLAGS=$ax_check_save_flags
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_ldflags__" >&5
+$as_echo "$ax_cv_check_ldflags__" >&6; }
+if test x"$ax_cv_check_ldflags__" = xyes; then :
+  :
+else
+  :
+fi
+
+
+#  SING_SHOW_FLAGS([Initial state?...])dnl
+
+ # Check whether --enable-debug was given.
+if test "${enable_debug+set}" = set; then :
+  enableval=$enable_debug; ENABLE_DEBUG="$enableval"
+else
+  ENABLE_DEBUG=""
+fi
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking debugging checks should be embedded" >&5
+$as_echo_n "checking debugging checks should be embedded... " >&6; }
+ if test "x${ENABLE_DEBUG}" != xyes; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ fi
+
+ # Check whether --enable-optimizationflags was given.
+if test "${enable_optimizationflags+set}" = set; then :
+  enableval=$enable_optimizationflags; ENABLE_OPTIMIZATION="$enableval"
+else
+  ENABLE_OPTIMIZATION="yeah"
+fi
+
+
+ if test "x${ENABLE_DEBUG}" = xyes; then
+  SINGULAR_CFLAGS=""
+  if test "x${ENABLE_OPTIMIZATION}" = xyeah; then
+   ENABLE_OPTIMIZATION="no"
+   { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Please note that we disable implicit (default) optimization flags since you have enabled the debug flags... " >&5
+$as_echo "$as_me: WARNING: Please note that we disable implicit (default) optimization flags since you have enabled the debug flags... " >&2;}
+  fi
+ else
+  SINGULAR_CFLAGS="-DSING_NDEBUG -DOM_NDEBUG"
+  # for now let '-DSING_NDEBUG -DOM_NDEBUG' be here...
+
+$as_echo "#define OM_NDEBUG 1" >>confdefs.h
+
+
+$as_echo "#define SING_NDEBUG 1" >>confdefs.h
+
+ fi
+
+ if test "x${ENABLE_OPTIMIZATION}" = xyeah; then
+   ENABLE_OPTIMIZATION="yes"
+ fi
+
+ if test "x${ENABLE_OPTIMIZATION}" = xyes; then
+  if test "x${ENABLE_DEBUG}" = xyes; then
+   { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Please note that you will be using our optimization flags together with debug flags... " >&5
+$as_echo "$as_me: WARNING: Please note that you will be using our optimization flags together with debug flags... " >&2;}
+  fi
+ fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether optimization flags should be used" >&5
+$as_echo_n "checking whether optimization flags should be used... " >&6; }
+ if test "x${ENABLE_OPTIMIZATION}" = xyes; 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; }
+ fi
+
+
+  if test x"${ENABLE_DEBUG}" = xyes; then
+  WANT_DEBUG_TRUE=
+  WANT_DEBUG_FALSE='#'
+else
+  WANT_DEBUG_TRUE='#'
+  WANT_DEBUG_FALSE=
+fi
+
+  if test x"${ENABLE_OPTIMIZATION}" = xyes; then
+  WANT_OPTIMIZATIONFLAGS_TRUE=
+  WANT_OPTIMIZATIONFLAGS_FALSE='#'
+else
+  WANT_OPTIMIZATIONFLAGS_TRUE='#'
+  WANT_OPTIMIZATIONFLAGS_FALSE=
+fi
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SINGULAR_CFLAGS "$SINGULAR_CFLAGS"
+_ACEOF
+
+
+
+# SING_SHOW_FLAGS([checking flags....])
+
+ FLAGS="-pipe -fno-common"
+ 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
+
+
+
+for flag in ${FLAGS}; do
+  as_CACHEVAR=`$as_echo "ax_cv_check_cflags__$flag" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts $flag" >&5
+$as_echo_n "checking whether C compiler accepts $flag... " >&6; }
+if eval \${$as_CACHEVAR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$CFLAGS
+  CFLAGS="$CFLAGS  $flag -Werror"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  eval "$as_CACHEVAR=yes"
+else
+  eval "$as_CACHEVAR=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  CFLAGS=$ax_check_save_flags
+fi
+eval ac_res=\$$as_CACHEVAR
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if test x"`eval 'as_val=${'$as_CACHEVAR'};$as_echo "$as_val"'`" = xyes; then :
+  if ${CFLAGS+:} false; then :
+  case " $CFLAGS " in
+    *" $flag "*)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS already contains \$flag"; } >&5
+  (: CFLAGS already contains $flag) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      ;;
+    *)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS=\"\$CFLAGS \$flag\""; } >&5
+  (: CFLAGS="$CFLAGS $flag") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      CFLAGS="$CFLAGS $flag"
+      ;;
+   esac
+else
+  CFLAGS="$flag"
+fi
+
+else
+  :
+fi
+
+done
+
+ 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=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+
+for flag in ${FLAGS}; do
+  as_CACHEVAR=`$as_echo "ax_cv_check_cxxflags__$flag" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C++ compiler accepts $flag" >&5
+$as_echo_n "checking whether C++ compiler accepts $flag... " >&6; }
+if eval \${$as_CACHEVAR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$CXXFLAGS
+  CXXFLAGS="$CXXFLAGS  $flag -Werror"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  eval "$as_CACHEVAR=yes"
+else
+  eval "$as_CACHEVAR=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  CXXFLAGS=$ax_check_save_flags
+fi
+eval ac_res=\$$as_CACHEVAR
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if test x"`eval 'as_val=${'$as_CACHEVAR'};$as_echo "$as_val"'`" = xyes; then :
+  if ${CXXFLAGS+:} false; then :
+  case " $CXXFLAGS " in
+    *" $flag "*)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CXXFLAGS already contains \$flag"; } >&5
+  (: CXXFLAGS already contains $flag) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      ;;
+    *)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CXXFLAGS=\"\$CXXFLAGS \$flag\""; } >&5
+  (: CXXFLAGS="$CXXFLAGS $flag") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      CXXFLAGS="$CXXFLAGS $flag"
+      ;;
+   esac
+else
+  CXXFLAGS="$flag"
+fi
+
+else
+  :
+fi
+
+done
+
+
+
+for flag in -fexceptions -frtti; do
+  as_CACHEVAR=`$as_echo "ax_cv_check_cxxflags__$flag" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C++ compiler accepts $flag" >&5
+$as_echo_n "checking whether C++ compiler accepts $flag... " >&6; }
+if eval \${$as_CACHEVAR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$CXXFLAGS
+  CXXFLAGS="$CXXFLAGS  $flag -Werror"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  eval "$as_CACHEVAR=yes"
+else
+  eval "$as_CACHEVAR=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  CXXFLAGS=$ax_check_save_flags
+fi
+eval ac_res=\$$as_CACHEVAR
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if test x"`eval 'as_val=${'$as_CACHEVAR'};$as_echo "$as_val"'`" = xyes; then :
+  if ${POLYMAKE_CXXFLAGS+:} false; then :
+  case " $POLYMAKE_CXXFLAGS " in
+    *" $flag "*)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : POLYMAKE_CXXFLAGS already contains \$flag"; } >&5
+  (: POLYMAKE_CXXFLAGS already contains $flag) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      ;;
+    *)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : POLYMAKE_CXXFLAGS=\"\$POLYMAKE_CXXFLAGS \$flag\""; } >&5
+  (: POLYMAKE_CXXFLAGS="$POLYMAKE_CXXFLAGS $flag") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      POLYMAKE_CXXFLAGS="$POLYMAKE_CXXFLAGS $flag"
+      ;;
+   esac
+else
+  POLYMAKE_CXXFLAGS="$flag"
+fi
+
+else
+  :
+fi
+
+done
+
+ 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
+
+
+
+
+for flag in ${FLAGS}; do
+  as_CACHEVAR=`$as_echo "ax_cv_check_ldflags__$flag" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the linker accepts $flag" >&5
+$as_echo_n "checking whether the linker accepts $flag... " >&6; }
+if eval \${$as_CACHEVAR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$LDFLAGS
+  LDFLAGS="$LDFLAGS  $flag"
+  _save_cflags="$CFLAGS"
+  CFLAGS="$CFLAGS -Werror"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "$as_CACHEVAR=yes"
+else
+  eval "$as_CACHEVAR=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+  CFLAGS="$_save_cflags"
+  LDFLAGS=$ax_check_save_flags
+fi
+eval ac_res=\$$as_CACHEVAR
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if test x"`eval 'as_val=${'$as_CACHEVAR'};$as_echo "$as_val"'`" = xyes; then :
+  if ${LDFLAGS+:} false; then :
+  case " $LDFLAGS " in
+    *" $flag "*)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : LDFLAGS already contains \$flag"; } >&5
+  (: LDFLAGS already contains $flag) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      ;;
+    *)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : LDFLAGS=\"\$LDFLAGS \$flag\""; } >&5
+  (: LDFLAGS="$LDFLAGS $flag") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      LDFLAGS="$LDFLAGS $flag"
+      ;;
+   esac
+else
+  LDFLAGS="$flag"
+fi
+
+else
+  :
+fi
+
+done
+
+
+
+
+ if test "x${ENABLE_DEBUG}" = xyes; then
+  DBGFLAGS="-g -ftrapv -fdiagnostics-show-option -Wall -Wextra"
+  #  -pedantic too strict ??? -Wvla -Wno-long-long ???
+  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
+
+
+
+for flag in ${DBGFLAGS}; do
+  as_CACHEVAR=`$as_echo "ax_cv_check_cflags__$flag" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts $flag" >&5
+$as_echo_n "checking whether C compiler accepts $flag... " >&6; }
+if eval \${$as_CACHEVAR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$CFLAGS
+  CFLAGS="$CFLAGS  $flag -Werror"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  eval "$as_CACHEVAR=yes"
+else
+  eval "$as_CACHEVAR=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  CFLAGS=$ax_check_save_flags
+fi
+eval ac_res=\$$as_CACHEVAR
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if test x"`eval 'as_val=${'$as_CACHEVAR'};$as_echo "$as_val"'`" = xyes; then :
+  if ${CFLAGS+:} false; then :
+  case " $CFLAGS " in
+    *" $flag "*)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS already contains \$flag"; } >&5
+  (: CFLAGS already contains $flag) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      ;;
+    *)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS=\"\$CFLAGS \$flag\""; } >&5
+  (: CFLAGS="$CFLAGS $flag") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      CFLAGS="$CFLAGS $flag"
+      ;;
+   esac
+else
+  CFLAGS="$flag"
+fi
+
+else
+  :
+fi
+
+done
+
+  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=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+
+for flag in ${DBGFLAGS}; do
+  as_CACHEVAR=`$as_echo "ax_cv_check_cxxflags__$flag" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C++ compiler accepts $flag" >&5
+$as_echo_n "checking whether C++ compiler accepts $flag... " >&6; }
+if eval \${$as_CACHEVAR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$CXXFLAGS
+  CXXFLAGS="$CXXFLAGS  $flag -Werror"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  eval "$as_CACHEVAR=yes"
+else
+  eval "$as_CACHEVAR=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  CXXFLAGS=$ax_check_save_flags
+fi
+eval ac_res=\$$as_CACHEVAR
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if test x"`eval 'as_val=${'$as_CACHEVAR'};$as_echo "$as_val"'`" = xyes; then :
+  if ${CXXFLAGS+:} false; then :
+  case " $CXXFLAGS " in
+    *" $flag "*)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CXXFLAGS already contains \$flag"; } >&5
+  (: CXXFLAGS already contains $flag) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      ;;
+    *)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CXXFLAGS=\"\$CXXFLAGS \$flag\""; } >&5
+  (: CXXFLAGS="$CXXFLAGS $flag") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      CXXFLAGS="$CXXFLAGS $flag"
+      ;;
+   esac
+else
+  CXXFLAGS="$flag"
+fi
+
+else
+  :
+fi
+
+done
+
+  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
+
+
+
+for flag in ${DBGFLAGS}; do
+  as_CACHEVAR=`$as_echo "ax_cv_check_ldflags__$flag" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the linker accepts $flag" >&5
+$as_echo_n "checking whether the linker accepts $flag... " >&6; }
+if eval \${$as_CACHEVAR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$LDFLAGS
+  LDFLAGS="$LDFLAGS  $flag"
+  _save_cflags="$CFLAGS"
+  CFLAGS="$CFLAGS -Werror"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "$as_CACHEVAR=yes"
+else
+  eval "$as_CACHEVAR=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+  CFLAGS="$_save_cflags"
+  LDFLAGS=$ax_check_save_flags
+fi
+eval ac_res=\$$as_CACHEVAR
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if test x"`eval 'as_val=${'$as_CACHEVAR'};$as_echo "$as_val"'`" = xyes; then :
+  if ${LDFLAGS+:} false; then :
+  case " $LDFLAGS " in
+    *" $flag "*)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : LDFLAGS already contains \$flag"; } >&5
+  (: LDFLAGS already contains $flag) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      ;;
+    *)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : LDFLAGS=\"\$LDFLAGS \$flag\""; } >&5
+  (: LDFLAGS="$LDFLAGS $flag") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      LDFLAGS="$LDFLAGS $flag"
+      ;;
+   esac
+else
+  LDFLAGS="$flag"
+fi
+
+else
+  :
+fi
+
+done
+
+ fi
+
+ ## for clang: -Wunneeded-internal-declaration
+
+ if test "x${ENABLE_OPTIMIZATION}" != xno; then
+  OPTFLAGS="-O3 -Wno-unused-function -Wno-trigraphs -Wno-unused-parameter -Wunknown-pragmas -Wno-unused-variable -fomit-frame-pointer -fwrapv -fvisibility=default -finline-functions -fno-exceptions -fno-rtti -fno-threadsafe-statics -fno-enforce-eh-specs -fconserve-space -funroll-loops"
+  #  -O3 - crashes gcc???!!!
+  # -fpermissive
+  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
+
+
+
+for flag in ${OPTFLAGS}; do
+  as_CACHEVAR=`$as_echo "ax_cv_check_cflags__$flag" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts $flag" >&5
+$as_echo_n "checking whether C compiler accepts $flag... " >&6; }
+if eval \${$as_CACHEVAR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$CFLAGS
+  CFLAGS="$CFLAGS  $flag -Werror"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  eval "$as_CACHEVAR=yes"
+else
+  eval "$as_CACHEVAR=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  CFLAGS=$ax_check_save_flags
+fi
+eval ac_res=\$$as_CACHEVAR
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if test x"`eval 'as_val=${'$as_CACHEVAR'};$as_echo "$as_val"'`" = xyes; then :
+  if ${CFLAGS+:} false; then :
+  case " $CFLAGS " in
+    *" $flag "*)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS already contains \$flag"; } >&5
+  (: CFLAGS already contains $flag) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      ;;
+    *)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS=\"\$CFLAGS \$flag\""; } >&5
+  (: CFLAGS="$CFLAGS $flag") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      CFLAGS="$CFLAGS $flag"
+      ;;
+   esac
+else
+  CFLAGS="$flag"
+fi
+
+else
+  :
+fi
+
+done
+
+  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=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+
+for flag in ${OPTFLAGS}; do
+  as_CACHEVAR=`$as_echo "ax_cv_check_cxxflags__$flag" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C++ compiler accepts $flag" >&5
+$as_echo_n "checking whether C++ compiler accepts $flag... " >&6; }
+if eval \${$as_CACHEVAR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$CXXFLAGS
+  CXXFLAGS="$CXXFLAGS  $flag -Werror"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  eval "$as_CACHEVAR=yes"
+else
+  eval "$as_CACHEVAR=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  CXXFLAGS=$ax_check_save_flags
+fi
+eval ac_res=\$$as_CACHEVAR
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if test x"`eval 'as_val=${'$as_CACHEVAR'};$as_echo "$as_val"'`" = xyes; then :
+  if ${CXXFLAGS+:} false; then :
+  case " $CXXFLAGS " in
+    *" $flag "*)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CXXFLAGS already contains \$flag"; } >&5
+  (: CXXFLAGS already contains $flag) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      ;;
+    *)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CXXFLAGS=\"\$CXXFLAGS \$flag\""; } >&5
+  (: CXXFLAGS="$CXXFLAGS $flag") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      CXXFLAGS="$CXXFLAGS $flag"
+      ;;
+   esac
+else
+  CXXFLAGS="$flag"
+fi
+
+else
+  :
+fi
+
+done
+
+#   AX_APPEND_COMPILE_FLAGS([-fno-threadsafe-statics -fno-enforce-eh-specs -fconserve-space], [CXXFLAGS])
+###  AX_APPEND_COMPILE_FLAGS([-fno-implicit-templates], [CXXFLAGS]) # problems due to STL
+  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
+
+
+
+for flag in ${OPTFLAGS}; do
+  as_CACHEVAR=`$as_echo "ax_cv_check_ldflags__$flag" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the linker accepts $flag" >&5
+$as_echo_n "checking whether the linker accepts $flag... " >&6; }
+if eval \${$as_CACHEVAR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$LDFLAGS
+  LDFLAGS="$LDFLAGS  $flag"
+  _save_cflags="$CFLAGS"
+  CFLAGS="$CFLAGS -Werror"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "$as_CACHEVAR=yes"
+else
+  eval "$as_CACHEVAR=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+  CFLAGS="$_save_cflags"
+  LDFLAGS=$ax_check_save_flags
+fi
+eval ac_res=\$$as_CACHEVAR
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if test x"`eval 'as_val=${'$as_CACHEVAR'};$as_echo "$as_val"'`" = xyes; then :
+  if ${LDFLAGS+:} false; then :
+  case " $LDFLAGS " in
+    *" $flag "*)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : LDFLAGS already contains \$flag"; } >&5
+  (: LDFLAGS already contains $flag) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      ;;
+    *)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : LDFLAGS=\"\$LDFLAGS \$flag\""; } >&5
+  (: LDFLAGS="$LDFLAGS $flag") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      LDFLAGS="$LDFLAGS $flag"
+      ;;
+   esac
+else
+  LDFLAGS="$flag"
+fi
+
+else
+  :
+fi
+
+done
+
+#  AX_APPEND_LINK_FLAGS([-fno-threadsafe-statics -fno-enforce-eh-specs -fconserve-space])
+###  AX_APPEND_LINK_FLAGS([-fno-implicit-templates]) # see above :(
+#  AX_APPEND_LINK_FLAGS([ ])
+ fi
+
+ FLAGS2="-Qunused-arguments"
+ 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
+
+
+
+for flag in ${FLAGS2}; do
+  as_CACHEVAR=`$as_echo "ax_cv_check_cflags__$flag" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts $flag" >&5
+$as_echo_n "checking whether C compiler accepts $flag... " >&6; }
+if eval \${$as_CACHEVAR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$CFLAGS
+  CFLAGS="$CFLAGS  $flag -Werror"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  eval "$as_CACHEVAR=yes"
+else
+  eval "$as_CACHEVAR=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  CFLAGS=$ax_check_save_flags
+fi
+eval ac_res=\$$as_CACHEVAR
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if test x"`eval 'as_val=${'$as_CACHEVAR'};$as_echo "$as_val"'`" = xyes; then :
+  if ${CFLAGS+:} false; then :
+  case " $CFLAGS " in
+    *" $flag "*)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS already contains \$flag"; } >&5
+  (: CFLAGS already contains $flag) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      ;;
+    *)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS=\"\$CFLAGS \$flag\""; } >&5
+  (: CFLAGS="$CFLAGS $flag") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      CFLAGS="$CFLAGS $flag"
+      ;;
+   esac
+else
+  CFLAGS="$flag"
+fi
+
+else
+  :
+fi
+
+done
+
+ 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=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+
+for flag in ${FLAGS2}; do
+  as_CACHEVAR=`$as_echo "ax_cv_check_cxxflags__$flag" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C++ compiler accepts $flag" >&5
+$as_echo_n "checking whether C++ compiler accepts $flag... " >&6; }
+if eval \${$as_CACHEVAR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$CXXFLAGS
+  CXXFLAGS="$CXXFLAGS  $flag -Werror"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  eval "$as_CACHEVAR=yes"
+else
+  eval "$as_CACHEVAR=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  CXXFLAGS=$ax_check_save_flags
+fi
+eval ac_res=\$$as_CACHEVAR
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if test x"`eval 'as_val=${'$as_CACHEVAR'};$as_echo "$as_val"'`" = xyes; then :
+  if ${CXXFLAGS+:} false; then :
+  case " $CXXFLAGS " in
+    *" $flag "*)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CXXFLAGS already contains \$flag"; } >&5
+  (: CXXFLAGS already contains $flag) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      ;;
+    *)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CXXFLAGS=\"\$CXXFLAGS \$flag\""; } >&5
+  (: CXXFLAGS="$CXXFLAGS $flag") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      CXXFLAGS="$CXXFLAGS $flag"
+      ;;
+   esac
+else
+  CXXFLAGS="$flag"
+fi
+
+else
+  :
+fi
+
+done
+
+ 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
+
+
+
+
+for flag in ${FLAGS2}; do
+  as_CACHEVAR=`$as_echo "ax_cv_check_ldflags__$flag" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the linker accepts $flag" >&5
+$as_echo_n "checking whether the linker accepts $flag... " >&6; }
+if eval \${$as_CACHEVAR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$LDFLAGS
+  LDFLAGS="$LDFLAGS  $flag"
+  _save_cflags="$CFLAGS"
+  CFLAGS="$CFLAGS -Werror"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "$as_CACHEVAR=yes"
+else
+  eval "$as_CACHEVAR=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+  CFLAGS="$_save_cflags"
+  LDFLAGS=$ax_check_save_flags
+fi
+eval ac_res=\$$as_CACHEVAR
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if test x"`eval 'as_val=${'$as_CACHEVAR'};$as_echo "$as_val"'`" = xyes; then :
+  if ${LDFLAGS+:} false; then :
+  case " $LDFLAGS " in
+    *" $flag "*)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : LDFLAGS already contains \$flag"; } >&5
+  (: LDFLAGS already contains $flag) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      ;;
+    *)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : LDFLAGS=\"\$LDFLAGS \$flag\""; } >&5
+  (: LDFLAGS="$LDFLAGS $flag") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      LDFLAGS="$LDFLAGS $flag"
+      ;;
+   esac
+else
+  LDFLAGS="$flag"
+fi
+
+else
+  :
+fi
+
+done
+
+
+# SING_SHOW_FLAGS([before PROG_C_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
+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 ${ac_cv_prog_CC+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_CC+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_CC+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_CC+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_CC+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_CC+:} false; 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 as_fn_executable_p "$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
+  fi
+  rm -f conftest.er1 conftest.err
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+done
+
+{ $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 ${ac_cv_c_compiler_gnu+:} false; 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 ${ac_cv_prog_cc_g+:} false; 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 ${ac_cv_prog_cc_c89+:} false; 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>
+struct stat;
+/* 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
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+if test -z "$CXX"; then
+  if test -n "$CCC"; then
+    CXX=$CCC
+  else
+    if test -n "$ac_tool_prefix"; then
+  for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+  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 ${ac_cv_prog_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CXX"; then
+  ac_cv_prog_CXX="$CXX" # 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CXX="$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
+CXX=$ac_cv_prog_CXX
+if test -n "$CXX"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5
+$as_echo "$CXX" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+    test -n "$CXX" && break
+  done
+fi
+if test -z "$CXX"; then
+  ac_ct_CXX=$CXX
+  for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+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 ${ac_cv_prog_ac_ct_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_CXX"; then
+  ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CXX="$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_CXX=$ac_cv_prog_ac_ct_CXX
+if test -n "$ac_ct_CXX"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5
+$as_echo "$ac_ct_CXX" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$ac_ct_CXX" && break
+done
+
+  if test "x$ac_ct_CXX" = x; then
+    CXX="g++"
+  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
+    CXX=$ac_ct_CXX
+  fi
+fi
+
+  fi
+fi
+# 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
+  fi
+  rm -f conftest.er1 conftest.err
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+done
+
+{ $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 ${ac_cv_cxx_compiler_gnu+:} false; 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_cxx_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_cxx_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5
+$as_echo "$ac_cv_cxx_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+  GXX=yes
+else
+  GXX=
+fi
+ac_test_CXXFLAGS=${CXXFLAGS+set}
+ac_save_CXXFLAGS=$CXXFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5
+$as_echo_n "checking whether $CXX accepts -g... " >&6; }
+if ${ac_cv_prog_cxx_g+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_save_cxx_werror_flag=$ac_cxx_werror_flag
+   ac_cxx_werror_flag=yes
+   ac_cv_prog_cxx_g=no
+   CXXFLAGS="-g"
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ac_cv_prog_cxx_g=yes
+else
+  CXXFLAGS=""
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+
+else
+  ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+	 CXXFLAGS="-g"
+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ac_cv_prog_cxx_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_cxx_werror_flag=$ac_save_cxx_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5
+$as_echo "$ac_cv_prog_cxx_g" >&6; }
+if test "$ac_test_CXXFLAGS" = set; then
+  CXXFLAGS=$ac_save_CXXFLAGS
+elif test $ac_cv_prog_cxx_g = yes; then
+  if test "$GXX" = yes; then
+    CXXFLAGS="-g -O2"
+  else
+    CXXFLAGS="-g"
+  fi
+else
+  if test "$GXX" = yes; then
+    CXXFLAGS="-O2"
+  else
+    CXXFLAGS=
+  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
+
+depcc="$CXX"  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 ${am_cv_CXX_dependencies_compiler_type+:} false; 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".
+  rm -rf conftest.dir
+  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_CXX_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 10 /bin/sh.
+      echo '/* dummy */' > 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
+      ;;
+    msvc7 | msvc7msys | 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_CXX_dependencies_compiler_type=$depmode
+        break
+      fi
+    fi
+  done
+
+  cd ..
+  rm -rf conftest.dir
+else
+  am_cv_CXX_dependencies_compiler_type=none
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5
+$as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; }
+CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type
+
+ if
+  test "x$enable_dependency_tracking" != xno \
+  && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then
+  am__fastdepCXX_TRUE=
+  am__fastdepCXX_FALSE='#'
+else
+  am__fastdepCXX_TRUE='#'
+  am__fastdepCXX_FALSE=
+fi
+
+
+
+
+#!
+# AC_PROG_CC
+# AC_PROG_CXX
+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 ${ac_cv_prog_CPP+:} false; 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.i 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.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i 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.i 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.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i 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
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_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; }
+if test -z "$CXXCPP"; then
+  if ${ac_cv_prog_CXXCPP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+      # Double quotes because CXXCPP needs to be expanded
+    for CXXCPP in "$CXX -E" "/lib/cpp"
+    do
+      ac_preproc_ok=false
+for ac_cxx_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_cxx_try_cpp "$LINENO"; then :
+
+else
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i 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_cxx_try_cpp "$LINENO"; then :
+  # Broken: success on invalid input.
+continue
+else
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+  break
+fi
+
+    done
+    ac_cv_prog_CXXCPP=$CXXCPP
+
+fi
+  CXXCPP=$ac_cv_prog_CXXCPP
+else
+  ac_cv_prog_CXXCPP=$CXXCPP
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5
+$as_echo "$CXXCPP" >&6; }
+ac_preproc_ok=false
+for ac_cxx_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_cxx_try_cpp "$LINENO"; then :
+
+else
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i 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_cxx_try_cpp "$LINENO"; then :
+  # Broken: success on invalid input.
+continue
+else
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i 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 \"$CXXCPP\" 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
+
+if test "x$CC" != xcc; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC and cc understand -c and -o together" >&5
+$as_echo_n "checking whether $CC and cc understand -c and -o together... " >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether cc understands -c and -o together" >&5
+$as_echo_n "checking whether cc understands -c and -o together... " >&6; }
+fi
+set dummy $CC; ac_cc=`$as_echo "$2" |
+		      sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'`
+if eval \${ac_cv_prog_cc_${ac_cc}_c_o+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+# Make sure it works both with $CC and with simple cc.
+# We do the test twice because some compilers refuse to overwrite an
+# existing .o file with -o, though they will create one.
+ac_try='$CC -c conftest.$ac_ext -o conftest2.$ac_objext >&5'
+rm -f conftest2.*
+if { { 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; } &&
+   test -f conftest2.$ac_objext && { { 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
+  eval ac_cv_prog_cc_${ac_cc}_c_o=yes
+  if test "x$CC" != xcc; then
+    # Test first that cc exists at all.
+    if { ac_try='cc -c conftest.$ac_ext >&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_try") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then
+      ac_try='cc -c conftest.$ac_ext -o conftest2.$ac_objext >&5'
+      rm -f conftest2.*
+      if { { 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; } &&
+	 test -f conftest2.$ac_objext && { { 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
+	# cc works too.
+	:
+      else
+	# cc exists but doesn't like -o.
+	eval ac_cv_prog_cc_${ac_cc}_c_o=no
+      fi
+    fi
+  fi
+else
+  eval ac_cv_prog_cc_${ac_cc}_c_o=no
+fi
+rm -f core conftest*
+
+fi
+if eval test \$ac_cv_prog_cc_${ac_cc}_c_o = yes; 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; }
+
+$as_echo "#define NO_MINUS_C_MINUS_O 1" >>confdefs.h
+
+fi
+
+# FIXME: we rely on the cache variable name because
+# there is no other way.
+set dummy $CC
+am_cc=`echo $2 | sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'`
+eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o
+if test "$am_t" != yes; then
+   # Losing compiler, so override with the script.
+   # FIXME: It is wrong to rewrite CC.
+   # But if we don't then we get into trouble of one sort or another.
+   # A longer-term fix would be to have automake use am__CC in this case,
+   # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
+   CC="$am_aux_dir/compile $CC"
+fi
+
+
+### AM_PROG_LEX
+{ $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
+
+
+if test -n "$ac_tool_prefix"; then
+  for ac_prog in ar lib "link -lib"
+  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 ${ac_cv_prog_AR+:} false; 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_AR="$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
+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
+
+
+    test -n "$AR" && break
+  done
+fi
+if test -z "$AR"; then
+  ac_ct_AR=$AR
+  for ac_prog in ar lib "link -lib"
+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 ${ac_cv_prog_ac_ct_AR+:} false; 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_AR="$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_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
+
+
+  test -n "$ac_ct_AR" && break
+done
+
+  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
+fi
+
+: ${AR=ar}
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the archiver ($AR) interface" >&5
+$as_echo_n "checking the archiver ($AR) interface... " >&6; }
+if ${am_cv_ar_interface+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  am_cv_ar_interface=ar
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+int some_variable = 0;
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  am_ar_try='$AR cru libconftest.a conftest.$ac_objext >&5'
+      { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$am_ar_try\""; } >&5
+  (eval $am_ar_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      if test "$ac_status" -eq 0; then
+        am_cv_ar_interface=ar
+      else
+        am_ar_try='$AR -NOLOGO -OUT:conftest.lib conftest.$ac_objext >&5'
+        { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$am_ar_try\""; } >&5
+  (eval $am_ar_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+        if test "$ac_status" -eq 0; then
+          am_cv_ar_interface=lib
+        else
+          am_cv_ar_interface=unknown
+        fi
+      fi
+      rm -f conftest.lib libconftest.a
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_ar_interface" >&5
+$as_echo "$am_cv_ar_interface" >&6; }
+
+case $am_cv_ar_interface in
+ar)
+  ;;
+lib)
+  # Microsoft lib, so override with the ar-lib wrapper script.
+  # FIXME: It is wrong to rewrite AR.
+  # But if we don't then we get into trouble of one sort or another.
+  # A longer-term fix would be to have automake use am__AR in this case,
+  # and then we could set am__AR="$am_aux_dir/ar-lib \$(AR)" or something
+  # similar.
+  AR="$am_aux_dir/ar-lib $AR"
+  ;;
+unknown)
+  as_fn_error $? "could not determine $AR interface" "$LINENO" 5
+  ;;
+esac
+
+
+{ $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 ${ac_cv_header_stdc+:} false; 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
+
+for ac_header in unistd.h iostream.h sys/time.h sys/times.h asm/sigcontext.h
+do :
+  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+for ac_func in readlink getcwd getwd setenv putenv qsort_r
+do :
+  as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+for ac_prog in doxygen
+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 ${ac_cv_prog_DOXYGEN+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$DOXYGEN"; then
+  ac_cv_prog_DOXYGEN="$DOXYGEN" # 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_DOXYGEN="$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
+DOXYGEN=$ac_cv_prog_DOXYGEN
+if test -n "$DOXYGEN"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DOXYGEN" >&5
+$as_echo "$DOXYGEN" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$DOXYGEN" && break
+done
+
+if test -z "$DOXYGEN";
+   then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Doxygen not found - continuing without Doxygen support" >&5
+$as_echo "$as_me: WARNING: Doxygen not found - continuing without Doxygen support" >&2;}
+fi
+ if test -n "$DOXYGEN"; then
+  HAVE_DOXYGEN_TRUE=
+  HAVE_DOXYGEN_FALSE='#'
+else
+  HAVE_DOXYGEN_TRUE='#'
+  HAVE_DOXYGEN_FALSE=
+fi
+
+
+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.4.2'
+macro_revision='1.3337'
+
+
+
+
+
+
+
+
+
+
+
+
+
+ltmain="$ac_aux_dir/ltmain.sh"
+
+# 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 ${ac_cv_build+:} false; 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 ${ac_cv_host+:} false; 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
+
+
+# Backslashify 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'
+
+ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5
+$as_echo_n "checking how to print strings... " >&6; }
+# Test print first, because it will be a builtin if present.
+if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \
+   test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then
+  ECHO='print -r --'
+elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then
+  ECHO='printf %s\n'
+else
+  # Use this function as a fallback that always works.
+  func_fallback_echo ()
+  {
+    eval 'cat <<_LTECHO_EOF
+$1
+_LTECHO_EOF'
+  }
+  ECHO='func_fallback_echo'
+fi
+
+# func_echo_all arg...
+# Invoke $ECHO with all args, space-separated.
+func_echo_all ()
+{
+    $ECHO ""
+}
+
+case "$ECHO" in
+  printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5
+$as_echo "printf" >&6; } ;;
+  print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5
+$as_echo "print -r" >&6; } ;;
+  *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5
+$as_echo "cat" >&6; } ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+{ $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 ${ac_cv_path_SED+:} false; 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"
+      as_fn_executable_p "$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 fgrep" >&5
+$as_echo_n "checking for fgrep... " >&6; }
+if ${ac_cv_path_FGREP+:} false; 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"
+      as_fn_executable_p "$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 ${lt_cv_path_LD+:} false; 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 ${lt_cv_prog_gnu_ld+:} false; 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 ${lt_cv_path_NM+:} false; 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 "$DUMPBIN"; then :
+    # Let the user override the test.
+  else
+    if test -n "$ac_tool_prefix"; then
+  for ac_prog in dumpbin "link -dump"
+  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 ${ac_cv_prog_DUMPBIN+:} false; 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 as_fn_executable_p "$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 "link -dump"
+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 ${ac_cv_prog_ac_ct_DUMPBIN+:} false; 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 as_fn_executable_p "$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
+
+    case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in
+    *COFF*)
+      DUMPBIN="$DUMPBIN -symbols"
+      ;;
+    *)
+      DUMPBIN=:
+      ;;
+    esac
+  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 ${lt_cv_nm_interface+:} false; 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:$LINENO: $ac_compile\"" >&5)
+  (eval "$ac_compile" 2>conftest.err)
+  cat conftest.err >&5
+  (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
+  (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
+  cat conftest.err >&5
+  (eval echo "\"\$as_me:$LINENO: 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; }
+
+# 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 ${lt_cv_sys_max_cmd_len+:} false; 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;
+    ;;
+
+  mint*)
+    # On MiNT this can take a long time and run out of memory.
+    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
+    ;;
+
+  os2*)
+    # The test takes a long time on OS/2.
+    lt_cv_sys_max_cmd_len=8192
+    ;;
+
+  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"`env echo "$teststring$teststring" 2>/dev/null` \
+	         = "X$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%"$_lt_dummy"}, \
+      = c,a/b,b/c, \
+    && 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 how to convert $build file names to $host format" >&5
+$as_echo_n "checking how to convert $build file names to $host format... " >&6; }
+if ${lt_cv_to_host_file_cmd+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $host in
+  *-*-mingw* )
+    case $build in
+      *-*-mingw* ) # actually msys
+        lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32
+        ;;
+      *-*-cygwin* )
+        lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32
+        ;;
+      * ) # otherwise, assume *nix
+        lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32
+        ;;
+    esac
+    ;;
+  *-*-cygwin* )
+    case $build in
+      *-*-mingw* ) # actually msys
+        lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin
+        ;;
+      *-*-cygwin* )
+        lt_cv_to_host_file_cmd=func_convert_file_noop
+        ;;
+      * ) # otherwise, assume *nix
+        lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin
+        ;;
+    esac
+    ;;
+  * ) # unhandled hosts (and "normal" native builds)
+    lt_cv_to_host_file_cmd=func_convert_file_noop
+    ;;
+esac
+
+fi
+
+to_host_file_cmd=$lt_cv_to_host_file_cmd
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5
+$as_echo "$lt_cv_to_host_file_cmd" >&6; }
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5
+$as_echo_n "checking how to convert $build file names to toolchain format... " >&6; }
+if ${lt_cv_to_tool_file_cmd+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  #assume ordinary cross tools, or native build.
+lt_cv_to_tool_file_cmd=func_convert_file_noop
+case $host in
+  *-*-mingw* )
+    case $build in
+      *-*-mingw* ) # actually msys
+        lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32
+        ;;
+    esac
+    ;;
+esac
+
+fi
+
+to_tool_file_cmd=$lt_cv_to_tool_file_cmd
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5
+$as_echo "$lt_cv_to_tool_file_cmd" >&6; }
+
+
+
+
+
+{ $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 ${lt_cv_ld_reload_flag+:} false; 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
+  cygwin* | mingw* | pw32* | cegcc*)
+    if test "$GCC" != yes; then
+      reload_cmds=false
+    fi
+    ;;
+  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 ${ac_cv_prog_OBJDUMP+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_OBJDUMP+:} false; 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 as_fn_executable_p "$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 ${lt_cv_deplibs_check_method+:} false; 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.
+  # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin.
+  if ( test "$lt_cv_nm_interface" = "BSD nm" && 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
+    # Keep this pattern in sync with the one in func_win32_libid.
+    lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)'
+    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
+  ;;
+
+haiku*)
+  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])(-bit)?( [LM]SB)? 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 glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+netbsd*)
+  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_glob=
+want_nocaseglob=no
+if test "$build" = "$host"; then
+  case $host_os in
+  mingw* | pw32*)
+    if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then
+      want_nocaseglob=yes
+    else
+      file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"`
+    fi
+    ;;
+  esac
+fi
+
+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}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 ${ac_cv_prog_DLLTOOL+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_DLLTOOL+:} false; 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 as_fn_executable_p "$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
+
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5
+$as_echo_n "checking how to associate runtime and link libraries... " >&6; }
+if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_sharedlib_from_linklib_cmd='unknown'
+
+case $host_os in
+cygwin* | mingw* | pw32* | cegcc*)
+  # two different shell functions defined in ltmain.sh
+  # decide which to use based on capabilities of $DLLTOOL
+  case `$DLLTOOL --help 2>&1` in
+  *--identify-strict*)
+    lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib
+    ;;
+  *)
+    lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback
+    ;;
+  esac
+  ;;
+*)
+  # fallback: assume linklib IS sharedlib
+  lt_cv_sharedlib_from_linklib_cmd="$ECHO"
+  ;;
+esac
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5
+$as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; }
+sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd
+test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+  for ac_prog in ar
+  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 ${ac_cv_prog_AR+:} false; 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_AR="$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
+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
+
+
+    test -n "$AR" && break
+  done
+fi
+if test -z "$AR"; then
+  ac_ct_AR=$AR
+  for ac_prog in ar
+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 ${ac_cv_prog_ac_ct_AR+:} false; 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_AR="$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_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
+
+
+  test -n "$ac_ct_AR" && break
+done
+
+  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
+fi
+
+: ${AR=ar}
+: ${AR_FLAGS=cru}
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5
+$as_echo_n "checking for archiver @FILE support... " >&6; }
+if ${lt_cv_ar_at_file+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_ar_at_file=no
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  echo conftest.$ac_objext > conftest.lst
+      lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5'
+      { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5
+  (eval $lt_ar_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      if test "$ac_status" -eq 0; then
+	# Ensure the archiver fails upon bogus file names.
+	rm -f conftest.$ac_objext libconftest.a
+	{ { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5
+  (eval $lt_ar_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+	if test "$ac_status" -ne 0; then
+          lt_cv_ar_at_file=@
+        fi
+      fi
+      rm -f conftest.* libconftest.a
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5
+$as_echo "$lt_cv_ar_at_file" >&6; }
+
+if test "x$lt_cv_ar_at_file" = xno; then
+  archiver_list_spec=
+else
+  archiver_list_spec=$lt_cv_ar_at_file
+fi
+
+
+
+
+
+
+
+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 ${ac_cv_prog_STRIP+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_STRIP+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_RANLIB+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_RANLIB+:} false; 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 as_fn_executable_p "$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 \$tool_oldlib"
+    ;;
+  *)
+    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib"
+    ;;
+  esac
+  old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib"
+fi
+
+case $host_os in
+  darwin*)
+    lock_old_archive_extraction=yes ;;
+  *)
+    lock_old_archive_extraction=no ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 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 ${lt_cv_sys_global_symbol_pipe+:} false; 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};"\
+"     /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\
+"     /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
+  lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'"
+
+  # 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
+/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests.  */
+#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE)
+/* DATA imports from DLLs on WIN32 con't be const, because runtime
+   relocations are performed -- see ld's documentation on pseudo-relocs.  */
+# define LT_DLSYM_CONST
+#elif defined(__osf__)
+/* This system does not cope well with relocations in const data.  */
+# define LT_DLSYM_CONST
+#else
+# define LT_DLSYM_CONST const
+#endif
+
+#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.  */
+LT_DLSYM_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_globsym_save_LIBS=$LIBS
+	  lt_globsym_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_globsym_save_LIBS
+	  CFLAGS=$lt_globsym_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
+
+# Response file support.
+if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+  nm_file_list_spec='@'
+elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then
+  nm_file_list_spec='@'
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5
+$as_echo_n "checking for sysroot... " >&6; }
+
+# Check whether --with-sysroot was given.
+if test "${with_sysroot+set}" = set; then :
+  withval=$with_sysroot;
+else
+  with_sysroot=no
+fi
+
+
+lt_sysroot=
+case ${with_sysroot} in #(
+ yes)
+   if test "$GCC" = yes; then
+     lt_sysroot=`$CC --print-sysroot 2>/dev/null`
+   fi
+   ;; #(
+ /*)
+   lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"`
+   ;; #(
+ no|'')
+   ;; #(
+ *)
+   { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${with_sysroot}" >&5
+$as_echo "${with_sysroot}" >&6; }
+   as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5
+   ;;
+esac
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5
+$as_echo "${lt_sysroot:-no}" >&6; }
+
+
+
+
+
+# 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 '$LINENO' "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 ${lt_cv_cc_needs_belf+:} false; 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
+  ;;
+*-*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*)
+        case $host in
+        i?86-*-solaris*)
+          LD="${LD-ld} -m elf_x86_64"
+          ;;
+        sparc*-*-solaris*)
+          LD="${LD-ld} -m elf64_sparc"
+          ;;
+        esac
+        # GNU ld 2.21 introduced _sol2 emulations.  Use them if available.
+        if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then
+          LD="${LD-ld}_sol2"
+        fi
+        ;;
+      *)
+	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"
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args.
+set dummy ${ac_tool_prefix}mt; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_MANIFEST_TOOL+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$MANIFEST_TOOL"; then
+  ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt"
+    $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
+MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL
+if test -n "$MANIFEST_TOOL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5
+$as_echo "$MANIFEST_TOOL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_MANIFEST_TOOL"; then
+  ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL
+  # Extract the first word of "mt", so it can be a program name with args.
+set dummy mt; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_MANIFEST_TOOL"; then
+  ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_MANIFEST_TOOL="mt"
+    $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_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL
+if test -n "$ac_ct_MANIFEST_TOOL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5
+$as_echo "$ac_ct_MANIFEST_TOOL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_MANIFEST_TOOL" = x; then
+    MANIFEST_TOOL=":"
+  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
+    MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL
+  fi
+else
+  MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL"
+fi
+
+test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5
+$as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; }
+if ${lt_cv_path_mainfest_tool+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_path_mainfest_tool=no
+  echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5
+  $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out
+  cat conftest.err >&5
+  if $GREP 'Manifest Tool' conftest.out > /dev/null; then
+    lt_cv_path_mainfest_tool=yes
+  fi
+  rm -f conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5
+$as_echo "$lt_cv_path_mainfest_tool" >&6; }
+if test "x$lt_cv_path_mainfest_tool" != xyes; then
+  MANIFEST_TOOL=:
+fi
+
+
+
+
+
+
+  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 ${ac_cv_prog_DSYMUTIL+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_NMEDIT+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_NMEDIT+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_LIPO+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_LIPO+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_OTOOL+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_OTOOL+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_OTOOL64+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_OTOOL64+:} false; 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 as_fn_executable_p "$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 ${lt_cv_apple_cc_single_mod+:} false; 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 there is a non-empty error log, and "single_module"
+	# appears in it, assume the flag caused a linker warning
+        if test -s conftest.err && $GREP single_module conftest.err; then
+	  cat conftest.err >&5
+	# Otherwise, if the output was created with a 0 exit code from
+	# the compiler, it worked.
+	elif test -f libconftest.dylib && test $_lt_result -eq 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 ${lt_cv_ld_exported_symbols_list+:} false; 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; }
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5
+$as_echo_n "checking for -force_load linker flag... " >&6; }
+if ${lt_cv_ld_force_load+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_ld_force_load=no
+      cat > conftest.c << _LT_EOF
+int forced_loaded() { return 2;}
+_LT_EOF
+      echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5
+      $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5
+      echo "$AR cru libconftest.a conftest.o" >&5
+      $AR cru libconftest.a conftest.o 2>&5
+      echo "$RANLIB libconftest.a" >&5
+      $RANLIB libconftest.a 2>&5
+      cat > conftest.c << _LT_EOF
+int main() { return 0;}
+_LT_EOF
+      echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5
+      $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err
+      _lt_result=$?
+      if test -s conftest.err && $GREP force_load conftest.err; then
+	cat conftest.err >&5
+      elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then
+	lt_cv_ld_force_load=yes
+      else
+	cat conftest.err >&5
+      fi
+        rm -f conftest.err libconftest.a conftest conftest.c
+        rm -rf conftest.dSYM
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5
+$as_echo "$lt_cv_ld_force_load" >&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" != ":" && test "$lt_cv_ld_force_load" = "no"; then
+      _lt_dsymutil='~$DSYMUTIL $lib || :'
+    else
+      _lt_dsymutil=
+    fi
+    ;;
+  esac
+
+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" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_DLFCN_H 1
+_ACEOF
+
+fi
+
+done
+
+
+
+func_stripname_cnf ()
+{
+  case ${2} in
+  .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;;
+  *)  func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;;
+  esac
+} # func_stripname_cnf
+
+
+
+
+
+# Set options
+
+
+
+        enable_dlopen=no
+
+
+  enable_win32_dll=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; lt_p=${PACKAGE-default}
+    case $withval in
+    yes|no) pic_mode=$withval ;;
+    *)
+      pic_mode=default
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for lt_pkg in $withval; do
+	IFS="$lt_save_ifs"
+	if test "X$lt_pkg" = "X$lt_p"; then
+	  pic_mode=yes
+	fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac
+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 ${lt_cv_objdir+:} false; 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
+
+# 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 "$cc_temp" | $SED "s%.*/%%; 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 ${lt_cv_path_MAGIC_CMD+:} false; 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 ${lt_cv_path_MAGIC_CMD+:} false; 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*
+
+
+## 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...
+if test -n "$compiler"; then
+
+lt_prog_compiler_no_builtin_flag=
+
+if test "$GCC" = yes; then
+  case $cc_basename in
+  nvcc*)
+    lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;;
+  *)
+    lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;;
+  esac
+
+  { $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 ${lt_cv_prog_compiler_rtti_exceptions+:} false; 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:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $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 "$_lt_compiler_boilerplate" | $SED '/^$/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=
+
+
+  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'
+      ;;
+
+    haiku*)
+      # PIC is the default for Haiku.
+      # The "-static" flag exists, but is broken.
+      lt_prog_compiler_static=
+      ;;
+
+    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
+
+    case $cc_basename in
+    nvcc*) # Cuda Compiler Driver 2.2
+      lt_prog_compiler_wl='-Xlinker '
+      if test -n "$lt_prog_compiler_pic"; then
+        lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic"
+      fi
+      ;;
+    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 | kopensolaris*-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'
+	;;
+      nagfor*)
+	# NAG Fortran compiler
+	lt_prog_compiler_wl='-Wl,-Wl,,'
+	lt_prog_compiler_pic='-PIC'
+	lt_prog_compiler_static='-Bstatic'
+	;;
+      pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
+        # 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* | bgxl* | bgf* | mpixl*)
+	# IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene
+	lt_prog_compiler_wl='-Wl,'
+	lt_prog_compiler_pic='-qpic'
+	lt_prog_compiler_static='-qstaticlink'
+	;;
+      *)
+	case `$CC -V 2>&1 | sed 5q` in
+	*Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*)
+	  # 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=''
+	  ;;
+	*Sun\ F* | *Sun*Fortran*)
+	  lt_prog_compiler_pic='-KPIC'
+	  lt_prog_compiler_static='-Bstatic'
+	  lt_prog_compiler_wl='-Qoption ld '
+	  ;;
+	*Sun\ C*)
+	  # Sun C 5.9
+	  lt_prog_compiler_pic='-KPIC'
+	  lt_prog_compiler_static='-Bstatic'
+	  lt_prog_compiler_wl='-Wl,'
+	  ;;
+        *Intel*\ [CF]*Compiler*)
+	  lt_prog_compiler_wl='-Wl,'
+	  lt_prog_compiler_pic='-fPIC'
+	  lt_prog_compiler_static='-static'
+	  ;;
+	*Portland\ Group*)
+	  lt_prog_compiler_wl='-Wl,'
+	  lt_prog_compiler_pic='-fpic'
+	  lt_prog_compiler_static='-Bstatic'
+	  ;;
+	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* | sunf77* | sunf90* | sunf95*)
+	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}: checking for $compiler option to produce PIC" >&5
+$as_echo_n "checking for $compiler option to produce PIC... " >&6; }
+if ${lt_cv_prog_compiler_pic+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_pic=$lt_prog_compiler_pic
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5
+$as_echo "$lt_cv_prog_compiler_pic" >&6; }
+lt_prog_compiler_pic=$lt_cv_prog_compiler_pic
+
+#
+# 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 ${lt_cv_prog_compiler_pic_works+:} false; 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:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $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 "$_lt_compiler_boilerplate" | $SED '/^$/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 ${lt_cv_prog_compiler_static_works+:} false; 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 "$_lt_linker_boilerplate" | $SED '/^$/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 ${lt_cv_prog_compiler_c_o+:} false; 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:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $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 "$_lt_compiler_boilerplate" | $SED '/^$/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 ${lt_cv_prog_compiler_c_o+:} false; 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:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $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 "$_lt_compiler_boilerplate" | $SED '/^$/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_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
+    ;;
+  esac
+
+  ld_shlibs=yes
+
+  # On some targets, GNU ld is compatible enough with the native linker
+  # that we're better off using the native interface for both.
+  lt_use_gnu_ld_interface=no
+  if test "$with_gnu_ld" = yes; then
+    case $host_os in
+      aix*)
+	# The AIX port of GNU ld has always aspired to compatibility
+	# with the native linker.  However, as the warning in the GNU ld
+	# block says, versions before 2.19.5* couldn't really create working
+	# shared libraries, regardless of the interface used.
+	case `$LD -v 2>&1` in
+	  *\ \(GNU\ Binutils\)\ 2.19.5*) ;;
+	  *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;;
+	  *\ \(GNU\ Binutils\)\ [3-9]*) ;;
+	  *)
+	    lt_use_gnu_ld_interface=yes
+	    ;;
+	esac
+	;;
+      *)
+	lt_use_gnu_ld_interface=yes
+	;;
+    esac
+  fi
+
+  if test "$lt_use_gnu_ld_interface" = 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
+      *GNU\ gold*) supports_anon_versioning=yes ;;
+      *\ [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.19, 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 install binutils
+*** 2.20 or above, or modify your PATH so that a non-GNU linker is found.
+*** You will then need to restart the configuration process.
+
+_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'
+      export_dynamic_flag_spec='${wl}--export-all-symbols'
+      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/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols'
+      exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'
+
+      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
+      ;;
+
+    haiku*)
+      archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+      link_all_deplibs=yes
+      ;;
+
+    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 | kopensolaris*-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=' $pic_flag'
+	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; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+	  tmp_addflag=' $pic_flag'
+	  ;;
+	pgf77* | pgf90* | pgf95* | pgfortran*)
+					# 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; func_echo_all \"$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]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below)
+	  tmp_sharedflag='-qmkshrobj'
+	  tmp_addflag= ;;
+	nvcc*)	# Cuda Compiler Driver 2.2
+	  whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+	  compiler_needs_object=yes
+	  ;;
+	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; func_echo_all \"$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* | bgf* | bgxlf* | mpixlf*)
+	  # 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='${wl}-rpath ${wl}$libdir'
+	  archive_cmds='$LD -shared $libobjs $deplibs $linker_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 $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+	  fi
+	  ;;
+	esac
+      else
+        ld_shlibs=no
+      fi
+      ;;
+
+    netbsd*)
+      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 $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	archive_expsym_cmds='$CC -shared $pic_flag $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 $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	archive_expsym_cmds='$CC -shared $pic_flag $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 $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	archive_expsym_cmds='$CC -shared $pic_flag $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
+	# Also, AIX nm treats weak defined symbols like other global
+	# defined symbols, whereas GNU nm marks them as "W".
+	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") || (\$ 2 == "W")) && (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
+      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.
+        if test "${lt_cv_aix_libpath+set}" = set; then
+  aix_libpath=$lt_cv_aix_libpath
+else
+  if ${lt_cv_aix_libpath_+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  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
+	  }
+      }'
+  lt_cv_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 "$lt_cv_aix_libpath_"; then
+    lt_cv_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 "$lt_cv_aix_libpath_"; then
+    lt_cv_aix_libpath_="/usr/lib:/lib"
+  fi
+
+fi
+
+  aix_libpath=$lt_cv_aix_libpath_
+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 func_echo_all "${wl}${allow_undefined_flag}"; 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.
+	 if test "${lt_cv_aix_libpath+set}" = set; then
+  aix_libpath=$lt_cv_aix_libpath
+else
+  if ${lt_cv_aix_libpath_+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  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
+	  }
+      }'
+  lt_cv_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 "$lt_cv_aix_libpath_"; then
+    lt_cv_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 "$lt_cv_aix_libpath_"; then
+    lt_cv_aix_libpath_="/usr/lib:/lib"
+  fi
+
+fi
+
+  aix_libpath=$lt_cv_aix_libpath_
+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'
+	  if test "$with_gnu_ld" = yes; then
+	    # We only use this code for GNU lds that support --whole-archive.
+	    whole_archive_flag_spec='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+	  else
+	    # Exported symbols can be pulled into shared objects from archives
+	    whole_archive_flag_spec='$convenience'
+	  fi
+	  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.
+      case $cc_basename in
+      cl*)
+	# Native MSVC
+	hardcode_libdir_flag_spec=' '
+	allow_undefined_flag=unsupported
+	always_export_symbols=yes
+	file_list_spec='@'
+	# 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 $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
+	archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	    sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
+	  else
+	    sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
+	  fi~
+	  $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+	  linknames='
+	# The linker will not automatically build a static lib if we build a DLL.
+	# _LT_TAGVAR(old_archive_from_new_cmds, )='true'
+	enable_shared_with_static_runtimes=yes
+	exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
+	export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols'
+	# Don't use ranlib
+	old_postinstall_cmds='chmod 644 $oldlib'
+	postlink_cmds='lt_outputfile="@OUTPUT@"~
+	  lt_tool_outputfile="@TOOL_OUTPUT@"~
+	  case $lt_outputfile in
+	    *.exe|*.EXE) ;;
+	    *)
+	      lt_outputfile="$lt_outputfile.exe"
+	      lt_tool_outputfile="$lt_tool_outputfile.exe"
+	      ;;
+	  esac~
+	  if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
+	    $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+	    $RM "$lt_outputfile.manifest";
+	  fi'
+	;;
+      *)
+	# Assume MSVC wrapper
+	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 `func_echo_all "$deplibs" | $SED '\''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'
+	enable_shared_with_static_runtimes=yes
+	;;
+      esac
+      ;;
+
+    darwin* | rhapsody*)
+
+
+  archive_cmds_need_lc=no
+  hardcode_direct=no
+  hardcode_automatic=yes
+  hardcode_shlibpath_var=unsupported
+  if test "$lt_cv_ld_force_load" = "yes"; then
+    whole_archive_flag_spec='`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+
+  else
+    whole_archive_flag_spec=''
+  fi
+  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=func_echo_all
+    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
+      ;;
+
+    # 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 $pic_flag -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 $pic_flag ${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 && test "$with_gnu_ld" = no; then
+	archive_cmds='$CC -shared $pic_flag ${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_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 && test "$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 $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	*)
+	  archive_cmds='$CC -shared $pic_flag ${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'
+	  ;;
+	*)
+
+	  # Older versions of the 11.00 compiler do not understand -b yet
+	  # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does)
+	  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5
+$as_echo_n "checking if $CC understands -b... " >&6; }
+if ${lt_cv_prog_compiler__b+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler__b=no
+   save_LDFLAGS="$LDFLAGS"
+   LDFLAGS="$LDFLAGS -b"
+   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 "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
+       $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+       if diff conftest.exp conftest.er2 >/dev/null; then
+         lt_cv_prog_compiler__b=yes
+       fi
+     else
+       lt_cv_prog_compiler__b=yes
+     fi
+   fi
+   $RM -r conftest*
+   LDFLAGS="$save_LDFLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5
+$as_echo "$lt_cv_prog_compiler__b" >&6; }
+
+if test x"$lt_cv_prog_compiler__b" = xyes; then
+    archive_cmds='$CC -b ${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
+
+	  ;;
+	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 $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${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.
+	# This should be the same for all languages, so no per-tag cache variable.
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5
+$as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; }
+if ${lt_cv_irix_exported_symbol+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  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) { return 0; }
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  lt_cv_irix_exported_symbol=yes
+else
+  lt_cv_irix_exported_symbol=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_irix_exported_symbol" >&5
+$as_echo "$lt_cv_irix_exported_symbol" >&6; }
+	if test "$lt_cv_irix_exported_symbol" = yes; then
+          archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
+	fi
+      else
+	archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+	archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -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*)
+      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" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${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" && func_echo_all "-set_version $verstring"` -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} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${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" && func_echo_all "-set_version $verstring"` -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 "-set_version $verstring"` -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 $pic_flag ${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 $pic_flag ${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; }
+if ${lt_cv_archive_cmds_need_lc+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  $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
+	    lt_cv_archive_cmds_need_lc=no
+	  else
+	    lt_cv_archive_cmds_need_lc=yes
+	  fi
+	  allow_undefined_flag=$lt_save_allow_undefined_flag
+	else
+	  cat conftest.err 1>&5
+	fi
+	$RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5
+$as_echo "$lt_cv_archive_cmds_need_lc" >&6; }
+      archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc
+      ;;
+    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
+  case $host_os in
+    mingw* | cegcc*) lt_sed_strip_eq="s,=\([A-Za-z]:\),\1,g" ;;
+    *) lt_sed_strip_eq="s,=/,/,g" ;;
+  esac
+  lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq`
+  case $lt_search_path_spec in
+  *\;*)
+    # 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 's/;/ /g'`
+    ;;
+  *)
+    lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"`
+    ;;
+  esac
+  # 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; }
+}'`
+  # AWK program above erroneously prepends '/' to C:/dos/paths
+  # for these hosts.
+  case $host_os in
+    mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\
+      $SED 's,/\([A-Za-z]:\),\1,g'` ;;
+  esac
+  sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP`
+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 # correct to gnu/linux during the next big refactor
+  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 # correct to gnu/linux during the next big refactor
+  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=`func_echo_all "$lib" | $SED '\''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 # correct to gnu/linux during the next big refactor
+  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,$cc_basename in
+  yes,*)
+    # gcc
+    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="$sys_lib_search_path_spec /usr/lib/w32api"
+      ;;
+    mingw* | cegcc*)
+      # MinGW DLLs use traditional 'lib' prefix
+      soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      ;;
+    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
+    dynamic_linker='Win32 ld.exe'
+    ;;
+
+  *,cl*)
+    # Native MSVC
+    libname_spec='$name'
+    soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+    library_names_spec='${libname}.dll.lib'
+
+    case $build_os in
+    mingw*)
+      sys_lib_search_path_spec=
+      lt_save_ifs=$IFS
+      IFS=';'
+      for lt_path in $LIB
+      do
+        IFS=$lt_save_ifs
+        # Let DOS variable expansion print the short 8.3 style file name.
+        lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"`
+        sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path"
+      done
+      IFS=$lt_save_ifs
+      # Convert to MSYS style.
+      sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'`
+      ;;
+    cygwin*)
+      # Convert to unix form, then to dos form, then back to unix form
+      # but this time dos style (no spaces!) so that the unix form looks
+      # like /cygdrive/c/PROGRA~1:/cygdr...
+      sys_lib_search_path_spec=`cygpath --path --unix "$LIB"`
+      sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null`
+      sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+      ;;
+    *)
+      sys_lib_search_path_spec="$LIB"
+      if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then
+        # It is most probably a Windows format PATH.
+        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
+      # FIXME: find the short name or the path components, as spaces are
+      # common. (e.g. "Program Files" -> "PROGRA~1")
+      ;;
+    esac
+
+    # 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'
+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+      dlpath=$dir/\$dldll~
+       $RM \$dlpath'
+    shlibpath_overrides_runpath=yes
+    dynamic_linker='Win32 link.exe'
+    ;;
+
+  *)
+    # Assume MSVC wrapper
+    library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
+    dynamic_linker='Win32 ld.exe'
+    ;;
+  esac
+  # 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 # correct to gnu/linux during the next big refactor
+  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
+  ;;
+
+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[23].*) objformat=aout ;;
+    *) objformat=elf ;;
+    esac
+  fi
+  # Handle Gentoo/FreeBSD as it was Linux
+  case $host_vendor in
+    gentoo)
+      version_type=linux ;;
+    *)
+      version_type=freebsd-$objformat ;;
+  esac
+
+  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
+      ;;
+    linux)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+      soname_spec='${libname}${release}${shared_ext}$major'
+      need_lib_prefix=no
+      need_version=no
+      ;;
+  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 # correct to gnu/linux during the next big refactor
+  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
+  ;;
+
+haiku*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  dynamic_linker="$host_os runtime_loader"
+  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=LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
+  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'
+  # or fails outright, so override atomically:
+  install_override_mode=555
+  ;;
+
+interix[3-9]*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  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 # correct to gnu/linux during the next big refactor
+	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 glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  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
+  if ${lt_cv_shlibpath_overrides_runpath+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_shlibpath_overrides_runpath=no
+    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 :
+  lt_cv_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
+
+fi
+
+  shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath
+
+  # 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;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'
+  ;;
+
+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 # correct to gnu/linux during the next big refactor
+  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 # correct to gnu/linux during the next big refactor
+  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 # correct to gnu/linux during the next big refactor
+  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 # correct to gnu/linux during the next big refactor
+    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 # correct to gnu/linux during the next big refactor
+  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 # correct to gnu/linux during the next big refactor
+  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 ${ac_cv_lib_dl_dlopen+:} false; 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" = xyes; 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" = xyes; 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 ${ac_cv_lib_dld_shl_load+:} false; 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" = xyes; 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" = xyes; 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 ${ac_cv_lib_dl_dlopen+:} false; 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" = xyes; 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 ${ac_cv_lib_svld_dlopen+:} false; 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" = xyes; 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 ${ac_cv_lib_dld_dld_link+:} false; 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" = xyes; 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 ${lt_cv_dlopen_self+:} false; 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 $LINENO "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
+
+/* When -fvisbility=hidden is used, assume the code has been annotated
+   correspondingly for the symbols needed.  */
+#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+int fnord () __attribute__((visibility("default")));
+#endif
+
+int fnord () { return 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;
+          else puts (dlerror ());
+	}
+      /* 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 ${lt_cv_dlopen_self_static+:} false; 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 $LINENO "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
+
+/* When -fvisbility=hidden is used, assume the code has been annotated
+   correspondingly for the symbols needed.  */
+#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+int fnord () __attribute__((visibility("default")));
+#endif
+
+int fnord () { return 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;
+          else puts (dlerror ());
+	}
+      /* 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"
+
+      if test -n "$CXX" && ( test "X$CXX" != "Xno" &&
+    ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) ||
+    (test "X$CXX" != "Xg++"))) ; then
+  ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_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; }
+if test -z "$CXXCPP"; then
+  if ${ac_cv_prog_CXXCPP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+      # Double quotes because CXXCPP needs to be expanded
+    for CXXCPP in "$CXX -E" "/lib/cpp"
+    do
+      ac_preproc_ok=false
+for ac_cxx_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_cxx_try_cpp "$LINENO"; then :
+
+else
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i 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_cxx_try_cpp "$LINENO"; then :
+  # Broken: success on invalid input.
+continue
+else
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+  break
+fi
+
+    done
+    ac_cv_prog_CXXCPP=$CXXCPP
+
+fi
+  CXXCPP=$ac_cv_prog_CXXCPP
+else
+  ac_cv_prog_CXXCPP=$CXXCPP
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5
+$as_echo "$CXXCPP" >&6; }
+ac_preproc_ok=false
+for ac_cxx_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_cxx_try_cpp "$LINENO"; then :
+
+else
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i 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_cxx_try_cpp "$LINENO"; then :
+  # Broken: success on invalid input.
+continue
+else
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i 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 \"$CXXCPP\" 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
+
+else
+  _lt_caught_CXX_error=yes
+fi
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+archive_cmds_need_lc_CXX=no
+allow_undefined_flag_CXX=
+always_export_symbols_CXX=no
+archive_expsym_cmds_CXX=
+compiler_needs_object_CXX=no
+export_dynamic_flag_spec_CXX=
+hardcode_direct_CXX=no
+hardcode_direct_absolute_CXX=no
+hardcode_libdir_flag_spec_CXX=
+hardcode_libdir_separator_CXX=
+hardcode_minus_L_CXX=no
+hardcode_shlibpath_var_CXX=unsupported
+hardcode_automatic_CXX=no
+inherit_rpath_CXX=no
+module_cmds_CXX=
+module_expsym_cmds_CXX=
+link_all_deplibs_CXX=unknown
+old_archive_cmds_CXX=$old_archive_cmds
+reload_flag_CXX=$reload_flag
+reload_cmds_CXX=$reload_cmds
+no_undefined_flag_CXX=
+whole_archive_flag_spec_CXX=
+enable_shared_with_static_runtimes_CXX=no
+
+# Source file extension for C++ test sources.
+ac_ext=cpp
+
+# Object file extension for compiled C++ test sources.
+objext=o
+objext_CXX=$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.
+
+
+
+
+
+
+# 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_CFLAGS=$CFLAGS
+  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++"}
+  CFLAGS=$CXXFLAGS
+  compiler=$CC
+  compiler_CXX=$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 "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
+
+
+  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_prog_compiler_no_builtin_flag_CXX=' -fno-builtin'
+    else
+      lt_prog_compiler_no_builtin_flag_CXX=
+    fi
+
+    if test "$GXX" = yes; then
+      # Set up default GNU C++ configuration
+
+
+
+# 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 ${lt_cv_path_LD+:} false; 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 ${lt_cv_prog_gnu_ld+:} false; 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
+
+
+
+
+
+
+
+      # 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
+        archive_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+        archive_expsym_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+
+        hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+        export_dynamic_flag_spec_CXX='${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
+          whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+        else
+          whole_archive_flag_spec_CXX=
+        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.
+        archive_cmds_CXX='$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 -v "^Configured with:" | $GREP "\-L"'
+
+    else
+      GXX=no
+      with_gnu_ld=no
+      wlarc=
+    fi
+
+    # PORTME: fill in a description of your system's C++ link characteristics
+    { $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; }
+    ld_shlibs_CXX=yes
+    case $host_os in
+      aix3*)
+        # FIXME: insert proper C++ library support
+        ld_shlibs_CXX=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.
+
+        archive_cmds_CXX=''
+        hardcode_direct_CXX=yes
+        hardcode_direct_absolute_CXX=yes
+        hardcode_libdir_separator_CXX=':'
+        link_all_deplibs_CXX=yes
+        file_list_spec_CXX='${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
+	    hardcode_direct_CXX=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_CXX=yes
+	    hardcode_libdir_flag_spec_CXX='-L$libdir'
+	    hardcode_libdir_separator_CXX=
+	  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
+
+        export_dynamic_flag_spec_CXX='${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_CXX=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_CXX='-berok'
+          # Determine the default libpath from the value encoded in an empty
+          # executable.
+          if test "${lt_cv_aix_libpath+set}" = set; then
+  aix_libpath=$lt_cv_aix_libpath
+else
+  if ${lt_cv_aix_libpath__CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+
+  lt_aix_libpath_sed='
+      /Import File Strings/,/^$/ {
+	  /^0/ {
+	      s/^0  *\([^ ]*\) *$/\1/
+	      p
+	  }
+      }'
+  lt_cv_aix_libpath__CXX=`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 "$lt_cv_aix_libpath__CXX"; then
+    lt_cv_aix_libpath__CXX=`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 "$lt_cv_aix_libpath__CXX"; then
+    lt_cv_aix_libpath__CXX="/usr/lib:/lib"
+  fi
+
+fi
+
+  aix_libpath=$lt_cv_aix_libpath__CXX
+fi
+
+          hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath"
+
+          archive_expsym_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+        else
+          if test "$host_cpu" = ia64; then
+	    hardcode_libdir_flag_spec_CXX='${wl}-R $libdir:/usr/lib:/lib'
+	    allow_undefined_flag_CXX="-z nodefs"
+	    archive_expsym_cmds_CXX="\$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.
+	    if test "${lt_cv_aix_libpath+set}" = set; then
+  aix_libpath=$lt_cv_aix_libpath
+else
+  if ${lt_cv_aix_libpath__CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+
+  lt_aix_libpath_sed='
+      /Import File Strings/,/^$/ {
+	  /^0/ {
+	      s/^0  *\([^ ]*\) *$/\1/
+	      p
+	  }
+      }'
+  lt_cv_aix_libpath__CXX=`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 "$lt_cv_aix_libpath__CXX"; then
+    lt_cv_aix_libpath__CXX=`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 "$lt_cv_aix_libpath__CXX"; then
+    lt_cv_aix_libpath__CXX="/usr/lib:/lib"
+  fi
+
+fi
+
+  aix_libpath=$lt_cv_aix_libpath__CXX
+fi
+
+	    hardcode_libdir_flag_spec_CXX='${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_CXX=' ${wl}-bernotok'
+	    allow_undefined_flag_CXX=' ${wl}-berok'
+	    if test "$with_gnu_ld" = yes; then
+	      # We only use this code for GNU lds that support --whole-archive.
+	      whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+	    else
+	      # Exported symbols can be pulled into shared objects from archives
+	      whole_archive_flag_spec_CXX='$convenience'
+	    fi
+	    archive_cmds_need_lc_CXX=yes
+	    # This is similar to how AIX traditionally builds its shared
+	    # libraries.
+	    archive_expsym_cmds_CXX="\$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
+	  allow_undefined_flag_CXX=unsupported
+	  # Joseph Beckenbach <jrb3 at best.com> says some releases of gcc
+	  # support --undefined.  This deserves some investigation.  FIXME
+	  archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	else
+	  ld_shlibs_CXX=no
+	fi
+	;;
+
+      chorus*)
+        case $cc_basename in
+          *)
+	  # FIXME: insert proper C++ library support
+	  ld_shlibs_CXX=no
+	  ;;
+        esac
+        ;;
+
+      cygwin* | mingw* | pw32* | cegcc*)
+	case $GXX,$cc_basename in
+	,cl* | no,cl*)
+	  # Native MSVC
+	  # hardcode_libdir_flag_spec is actually meaningless, as there is
+	  # no search path for DLLs.
+	  hardcode_libdir_flag_spec_CXX=' '
+	  allow_undefined_flag_CXX=unsupported
+	  always_export_symbols_CXX=yes
+	  file_list_spec_CXX='@'
+	  # 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_CXX='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
+	  archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	      $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
+	    else
+	      $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
+	    fi~
+	    $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+	    linknames='
+	  # The linker will not automatically build a static lib if we build a DLL.
+	  # _LT_TAGVAR(old_archive_from_new_cmds, CXX)='true'
+	  enable_shared_with_static_runtimes_CXX=yes
+	  # Don't use ranlib
+	  old_postinstall_cmds_CXX='chmod 644 $oldlib'
+	  postlink_cmds_CXX='lt_outputfile="@OUTPUT@"~
+	    lt_tool_outputfile="@TOOL_OUTPUT@"~
+	    case $lt_outputfile in
+	      *.exe|*.EXE) ;;
+	      *)
+		lt_outputfile="$lt_outputfile.exe"
+		lt_tool_outputfile="$lt_tool_outputfile.exe"
+		;;
+	    esac~
+	    func_to_tool_file "$lt_outputfile"~
+	    if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
+	      $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+	      $RM "$lt_outputfile.manifest";
+	    fi'
+	  ;;
+	*)
+	  # g++
+	  # _LT_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless,
+	  # as there is no search path for DLLs.
+	  hardcode_libdir_flag_spec_CXX='-L$libdir'
+	  export_dynamic_flag_spec_CXX='${wl}--export-all-symbols'
+	  allow_undefined_flag_CXX=unsupported
+	  always_export_symbols_CXX=no
+	  enable_shared_with_static_runtimes_CXX=yes
+
+	  if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+	    archive_cmds_CXX='$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...
+	    archive_expsym_cmds_CXX='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
+	    ld_shlibs_CXX=no
+	  fi
+	  ;;
+	esac
+	;;
+      darwin* | rhapsody*)
+
+
+  archive_cmds_need_lc_CXX=no
+  hardcode_direct_CXX=no
+  hardcode_automatic_CXX=yes
+  hardcode_shlibpath_var_CXX=unsupported
+  if test "$lt_cv_ld_force_load" = "yes"; then
+    whole_archive_flag_spec_CXX='`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+
+  else
+    whole_archive_flag_spec_CXX=''
+  fi
+  link_all_deplibs_CXX=yes
+  allow_undefined_flag_CXX="$_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=func_echo_all
+    archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
+    module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
+    archive_expsym_cmds_CXX="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_CXX="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}"
+       if test "$lt_cv_apple_cc_single_mod" != "yes"; then
+      archive_cmds_CXX="\$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}"
+      archive_expsym_cmds_CXX="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
+  ld_shlibs_CXX=no
+  fi
+
+	;;
+
+      dgux*)
+        case $cc_basename in
+          ec++*)
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+          ghcx*)
+	    # Green Hills C++ Compiler
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+          *)
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+        esac
+        ;;
+
+      freebsd2.*)
+        # C++ shared libraries reported to be fairly broken before
+	# switch to ELF
+        ld_shlibs_CXX=no
+        ;;
+
+      freebsd-elf*)
+        archive_cmds_need_lc_CXX=no
+        ;;
+
+      freebsd* | dragonfly*)
+        # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF
+        # conventions
+        ld_shlibs_CXX=yes
+        ;;
+
+      gnu*)
+        ;;
+
+      haiku*)
+        archive_cmds_CXX='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+        link_all_deplibs_CXX=yes
+        ;;
+
+      hpux9*)
+        hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir'
+        hardcode_libdir_separator_CXX=:
+        export_dynamic_flag_spec_CXX='${wl}-E'
+        hardcode_direct_CXX=yes
+        hardcode_minus_L_CXX=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
+            ld_shlibs_CXX=no
+            ;;
+          aCC*)
+            archive_cmds_CXX='$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; func_echo_all "$list"'
+            ;;
+          *)
+            if test "$GXX" = yes; then
+              archive_cmds_CXX='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${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
+              ld_shlibs_CXX=no
+            fi
+            ;;
+        esac
+        ;;
+
+      hpux10*|hpux11*)
+        if test $with_gnu_ld = no; then
+	  hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir'
+	  hardcode_libdir_separator_CXX=:
+
+          case $host_cpu in
+            hppa*64*|ia64*)
+              ;;
+            *)
+	      export_dynamic_flag_spec_CXX='${wl}-E'
+              ;;
+          esac
+        fi
+        case $host_cpu in
+          hppa*64*|ia64*)
+            hardcode_direct_CXX=no
+            hardcode_shlibpath_var_CXX=no
+            ;;
+          *)
+            hardcode_direct_CXX=yes
+            hardcode_direct_absolute_CXX=yes
+            hardcode_minus_L_CXX=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
+	    ld_shlibs_CXX=no
+	    ;;
+          aCC*)
+	    case $host_cpu in
+	      hppa*64*)
+	        archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	        ;;
+	      ia64*)
+	        archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	        ;;
+	      *)
+	        archive_cmds_CXX='$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; func_echo_all "$list"'
+	    ;;
+          *)
+	    if test "$GXX" = yes; then
+	      if test $with_gnu_ld = no; then
+	        case $host_cpu in
+	          hppa*64*)
+	            archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	            ;;
+	          ia64*)
+	            archive_cmds_CXX='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	            ;;
+	          *)
+	            archive_cmds_CXX='$CC -shared -nostdlib $pic_flag ${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
+	      ld_shlibs_CXX=no
+	    fi
+	    ;;
+        esac
+        ;;
+
+      interix[3-9]*)
+	hardcode_direct_CXX=no
+	hardcode_shlibpath_var_CXX=no
+	hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+	export_dynamic_flag_spec_CXX='${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_CXX='$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_CXX='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++
+	    archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -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.
+	    old_archive_cmds_CXX='$CC -ar -WR,-u -o $oldlib $oldobjs'
+	    ;;
+          *)
+	    if test "$GXX" = yes; then
+	      if test "$with_gnu_ld" = no; then
+	        archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+	      else
+	        archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib'
+	      fi
+	    fi
+	    link_all_deplibs_CXX=yes
+	    ;;
+        esac
+        hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+        hardcode_libdir_separator_CXX=:
+        inherit_rpath_CXX=yes
+        ;;
+
+      linux* | k*bsd*-gnu | kopensolaris*-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.
+	    archive_cmds_CXX='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'
+	    archive_expsym_cmds_CXX='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; func_echo_all "$list"'
+
+	    hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+	    export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+
+	    # Archives containing C++ object files must be created using
+	    # "CC -Bstatic", where "CC" is the KAI C++ compiler.
+	    old_archive_cmds_CXX='$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."*)
+	        archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+		archive_expsym_cmds_CXX='$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
+	        archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+		archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+		;;
+	    esac
+	    archive_cmds_need_lc_CXX=no
+	    hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+	    export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+	    whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+	    ;;
+          pgCC* | pgcpp*)
+            # Portland Group C++ compiler
+	    case `$CC -V` in
+	    *pgCC\ [1-5].* | *pgcpp\ [1-5].*)
+	      prelink_cmds_CXX='tpldir=Template.dir~
+		rm -rf $tpldir~
+		$CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~
+		compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"'
+	      old_archive_cmds_CXX='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 | sort | $NL2SP`~
+		$RANLIB $oldlib'
+	      archive_cmds_CXX='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 | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+	      archive_expsym_cmds_CXX='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 | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
+	      ;;
+	    *) # Version 6 and above use weak symbols
+	      archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+	      archive_expsym_cmds_CXX='$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
+
+	    hardcode_libdir_flag_spec_CXX='${wl}--rpath ${wl}$libdir'
+	    export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+	    whole_archive_flag_spec_CXX='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+            ;;
+	  cxx*)
+	    # Compaq C++
+	    archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	    archive_expsym_cmds_CXX='$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
+	    hardcode_libdir_flag_spec_CXX='-rpath $libdir'
+	    hardcode_libdir_separator_CXX=:
+
+	    # 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=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed'
+	    ;;
+	  xl* | mpixl* | bgxl*)
+	    # IBM XL 8.0 on PPC, with GNU ld
+	    hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+	    export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+	    archive_cmds_CXX='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	    if test "x$supports_anon_versioning" = xyes; then
+	      archive_expsym_cmds_CXX='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
+	      no_undefined_flag_CXX=' -zdefs'
+	      archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	      archive_expsym_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols'
+	      hardcode_libdir_flag_spec_CXX='-R$libdir'
+	      whole_archive_flag_spec_CXX='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+	      compiler_needs_object_CXX=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='func_echo_all'
+
+	      # 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.
+	      old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs'
+	      ;;
+	    esac
+	    ;;
+	esac
+	;;
+
+      lynxos*)
+        # FIXME: insert proper C++ library support
+	ld_shlibs_CXX=no
+	;;
+
+      m88k*)
+        # FIXME: insert proper C++ library support
+        ld_shlibs_CXX=no
+	;;
+
+      mvs*)
+        case $cc_basename in
+          cxx*)
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+	  *)
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+	esac
+	;;
+
+      netbsd*)
+        if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+	  archive_cmds_CXX='$LD -Bshareable  -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags'
+	  wlarc=
+	  hardcode_libdir_flag_spec_CXX='-R$libdir'
+	  hardcode_direct_CXX=yes
+	  hardcode_shlibpath_var_CXX=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*)
+        ld_shlibs_CXX=yes
+	;;
+
+      openbsd2*)
+        # C++ shared libraries are fairly broken
+	ld_shlibs_CXX=no
+	;;
+
+      openbsd*)
+	if test -f /usr/libexec/ld.so; then
+	  hardcode_direct_CXX=yes
+	  hardcode_shlibpath_var_CXX=no
+	  hardcode_direct_absolute_CXX=yes
+	  archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+	  hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+	  if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+	    archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib'
+	    export_dynamic_flag_spec_CXX='${wl}-E'
+	    whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+	  fi
+	  output_verbose_link_cmd=func_echo_all
+	else
+	  ld_shlibs_CXX=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.
+	    archive_cmds_CXX='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'
+
+	    hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+	    hardcode_libdir_separator_CXX=:
+
+	    # Archives containing C++ object files must be created using
+	    # the KAI C++ compiler.
+	    case $host in
+	      osf3*) old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ;;
+	      *) old_archive_cmds_CXX='$CC -o $oldlib $oldobjs' ;;
+	    esac
+	    ;;
+          RCC*)
+	    # Rational C++ 2.4.1
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+          cxx*)
+	    case $host in
+	      osf3*)
+	        allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*'
+	        archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+	        hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+		;;
+	      *)
+	        allow_undefined_flag_CXX=' -expect_unresolved \*'
+	        archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+	        archive_expsym_cmds_CXX='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 "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~
+	          $RM $lib.exp'
+	        hardcode_libdir_flag_spec_CXX='-rpath $libdir'
+		;;
+	    esac
+
+	    hardcode_libdir_separator_CXX=:
+
+	    # 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=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+	    ;;
+	  *)
+	    if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+	      allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*'
+	      case $host in
+	        osf3*)
+	          archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+		  ;;
+	        *)
+	          archive_cmds_CXX='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+		  ;;
+	      esac
+
+	      hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+	      hardcode_libdir_separator_CXX=:
+
+	      # 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 -v "^Configured with:" | $GREP "\-L"'
+
+	    else
+	      # FIXME: insert proper C++ library support
+	      ld_shlibs_CXX=no
+	    fi
+	    ;;
+        esac
+        ;;
+
+      psos*)
+        # FIXME: insert proper C++ library support
+        ld_shlibs_CXX=no
+        ;;
+
+      sunos4*)
+        case $cc_basename in
+          CC*)
+	    # Sun C++ 4.x
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+          lcc*)
+	    # Lucid
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+          *)
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+        esac
+        ;;
+
+      solaris*)
+        case $cc_basename in
+          CC* | sunCC*)
+	    # Sun C++ 4.2, 5.x and Centerline C++
+            archive_cmds_need_lc_CXX=yes
+	    no_undefined_flag_CXX=' -zdefs'
+	    archive_cmds_CXX='$CC -G${allow_undefined_flag}  -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	    archive_expsym_cmds_CXX='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'
+
+	    hardcode_libdir_flag_spec_CXX='-R$libdir'
+	    hardcode_shlibpath_var_CXX=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?)
+		whole_archive_flag_spec_CXX='-z allextract$convenience -z defaultextract'
+	        ;;
+	    esac
+	    link_all_deplibs_CXX=yes
+
+	    output_verbose_link_cmd='func_echo_all'
+
+	    # 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.
+	    old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs'
+	    ;;
+          gcx*)
+	    # Green Hills C++ Compiler
+	    archive_cmds_CXX='$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.
+	    old_archive_cmds_CXX='$CC $LDFLAGS -archive -o $oldlib $oldobjs'
+	    ;;
+          *)
+	    # GNU C++ compiler with Solaris linker
+	    if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+	      no_undefined_flag_CXX=' ${wl}-z ${wl}defs'
+	      if $CC --version | $GREP -v '^2\.7' > /dev/null; then
+	        archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+	        archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+		  $CC -shared $pic_flag -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 -v "^Configured with:" | $GREP "\-L"'
+	      else
+	        # g++ 2.7 appears to require `-G' NOT `-shared' on this
+	        # platform.
+	        archive_cmds_CXX='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+	        archive_expsym_cmds_CXX='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 -v "^Configured with:" | $GREP "\-L"'
+	      fi
+
+	      hardcode_libdir_flag_spec_CXX='${wl}-R $wl$libdir'
+	      case $host_os in
+		solaris2.[0-5] | solaris2.[0-5].*) ;;
+		*)
+		  whole_archive_flag_spec_CXX='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+		  ;;
+	      esac
+	    fi
+	    ;;
+        esac
+        ;;
+
+    sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
+      no_undefined_flag_CXX='${wl}-z,text'
+      archive_cmds_need_lc_CXX=no
+      hardcode_shlibpath_var_CXX=no
+      runpath_var='LD_RUN_PATH'
+
+      case $cc_basename in
+        CC*)
+	  archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	*)
+	  archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  archive_expsym_cmds_CXX='$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.
+	no_undefined_flag_CXX='${wl}-z,text'
+	allow_undefined_flag_CXX='${wl}-z,nodefs'
+	archive_cmds_need_lc_CXX=no
+	hardcode_shlibpath_var_CXX=no
+	hardcode_libdir_flag_spec_CXX='${wl}-R,$libdir'
+	hardcode_libdir_separator_CXX=':'
+	link_all_deplibs_CXX=yes
+	export_dynamic_flag_spec_CXX='${wl}-Bexport'
+	runpath_var='LD_RUN_PATH'
+
+	case $cc_basename in
+          CC*)
+	    archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    old_archive_cmds_CXX='$CC -Tprelink_objects $oldobjs~
+	      '"$old_archive_cmds_CXX"
+	    reload_cmds_CXX='$CC -Tprelink_objects $reload_objs~
+	      '"$reload_cmds_CXX"
+	    ;;
+	  *)
+	    archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    archive_expsym_cmds_CXX='$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
+	    ld_shlibs_CXX=no
+	    ;;
+          *)
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+        esac
+        ;;
+
+      vxworks*)
+        # FIXME: insert proper C++ library support
+        ld_shlibs_CXX=no
+        ;;
+
+      *)
+        # FIXME: insert proper C++ library support
+        ld_shlibs_CXX=no
+        ;;
+    esac
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5
+$as_echo "$ld_shlibs_CXX" >&6; }
+    test "$ld_shlibs_CXX" = no && can_build_shared=no
+
+    GCC_CXX="$GXX"
+    LD_CXX="$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...
+    # Dependencies to place before and after the object being linked:
+predep_objects_CXX=
+postdep_objects_CXX=
+predeps_CXX=
+postdeps_CXX=
+compiler_lib_search_path_CXX=
+
+cat > conftest.$ac_ext <<_LT_EOF
+class Foo
+{
+public:
+  Foo (void) { a = 0; }
+private:
+  int a;
+};
+_LT_EOF
+
+
+_lt_libdeps_save_CFLAGS=$CFLAGS
+case "$CC $CFLAGS " in #(
+*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;;
+*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;;
+*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;;
+esac
+
+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
+  # 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 ${prev}${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
+       fi
+
+       # Expand the sysroot to ease extracting the directories later.
+       if test -z "$prev"; then
+         case $p in
+         -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;;
+         -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;;
+         -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;;
+         esac
+       fi
+       case $p in
+       =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;;
+       esac
+       if test "$pre_test_object_deps_done" = no; then
+	 case ${prev} 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 "$compiler_lib_search_path_CXX"; then
+	     compiler_lib_search_path_CXX="${prev}${p}"
+	   else
+	     compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} ${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 "$postdeps_CXX"; then
+	   postdeps_CXX="${prev}${p}"
+	 else
+	   postdeps_CXX="${postdeps_CXX} ${prev}${p}"
+	 fi
+       fi
+       prev=
+       ;;
+
+    *.lto.$objext) ;; # Ignore GCC LTO objects
+    *.$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 "$predep_objects_CXX"; then
+	   predep_objects_CXX="$p"
+	 else
+	   predep_objects_CXX="$predep_objects_CXX $p"
+	 fi
+       else
+	 if test -z "$postdep_objects_CXX"; then
+	   postdep_objects_CXX="$p"
+	 else
+	   postdep_objects_CXX="$postdep_objects_CXX $p"
+	 fi
+       fi
+       ;;
+
+    *) ;; # Ignore the rest.
+
+    esac
+  done
+
+  # Clean up.
+  rm -f a.out a.exe
+else
+  echo "libtool.m4: error: problem compiling CXX test program"
+fi
+
+$RM -f confest.$objext
+CFLAGS=$_lt_libdeps_save_CFLAGS
+
+# PORTME: override above test on systems where it is broken
+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.
+  predep_objects_CXX=
+  postdep_objects_CXX=
+  postdeps_CXX=
+  ;;
+
+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
+      postdeps_CXX='-library=Cstd -library=Crun'
+    fi
+    ;;
+  esac
+  ;;
+
+solaris*)
+  case $cc_basename in
+  CC* | sunCC*)
+    # 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
+      postdeps_CXX='-library=Cstd -library=Crun'
+    fi
+    ;;
+  esac
+  ;;
+esac
+
+
+case " $postdeps_CXX " in
+*" -lc "*) archive_cmds_need_lc_CXX=no ;;
+esac
+ compiler_lib_search_dirs_CXX=
+if test -n "${compiler_lib_search_path_CXX}"; then
+ compiler_lib_search_dirs_CXX=`echo " ${compiler_lib_search_path_CXX}" | ${SED} -e 's! -L! !g' -e 's!^ !!'`
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    lt_prog_compiler_wl_CXX=
+lt_prog_compiler_pic_CXX=
+lt_prog_compiler_static_CXX=
+
+
+  # C++ specific cases for pic, static, wl, etc.
+  if test "$GXX" = yes; then
+    lt_prog_compiler_wl_CXX='-Wl,'
+    lt_prog_compiler_static_CXX='-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_CXX='-Bstatic'
+      fi
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            lt_prog_compiler_pic_CXX='-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_CXX='-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
+      lt_prog_compiler_pic_CXX='-DDLL_EXPORT'
+      ;;
+    darwin* | rhapsody*)
+      # PIC is the default on this platform
+      # Common symbols not allowed in MH_DYLIB files
+      lt_prog_compiler_pic_CXX='-fno-common'
+      ;;
+    *djgpp*)
+      # DJGPP does not support shared libraries at all
+      lt_prog_compiler_pic_CXX=
+      ;;
+    haiku*)
+      # PIC is the default for Haiku.
+      # The "-static" flag exists, but is broken.
+      lt_prog_compiler_static_CXX=
+      ;;
+    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_prog_compiler_pic_CXX=-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_prog_compiler_pic_CXX='-fPIC'
+	;;
+      esac
+      ;;
+    *qnx* | *nto*)
+      # QNX uses GNU C++, but need to define -shared option too, otherwise
+      # it will coredump.
+      lt_prog_compiler_pic_CXX='-fPIC -shared'
+      ;;
+    *)
+      lt_prog_compiler_pic_CXX='-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_prog_compiler_static_CXX='-Bstatic'
+	else
+	  lt_prog_compiler_static_CXX='-bnso -bI:/lib/syscalls.exp'
+	fi
+	;;
+      chorus*)
+	case $cc_basename in
+	cxch68*)
+	  # Green Hills C++ Compiler
+	  # _LT_TAGVAR(lt_prog_compiler_static, CXX)="--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
+	;;
+      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).
+	lt_prog_compiler_pic_CXX='-DDLL_EXPORT'
+	;;
+      dgux*)
+	case $cc_basename in
+	  ec++*)
+	    lt_prog_compiler_pic_CXX='-KPIC'
+	    ;;
+	  ghcx*)
+	    # Green Hills C++ Compiler
+	    lt_prog_compiler_pic_CXX='-pic'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      freebsd* | dragonfly*)
+	# FreeBSD uses GNU C++
+	;;
+      hpux9* | hpux10* | hpux11*)
+	case $cc_basename in
+	  CC*)
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_static_CXX='${wl}-a ${wl}archive'
+	    if test "$host_cpu" != ia64; then
+	      lt_prog_compiler_pic_CXX='+Z'
+	    fi
+	    ;;
+	  aCC*)
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_static_CXX='${wl}-a ${wl}archive'
+	    case $host_cpu in
+	    hppa*64*|ia64*)
+	      # +Z the default
+	      ;;
+	    *)
+	      lt_prog_compiler_pic_CXX='+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_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_static_CXX='-non_shared'
+	    # CC pic flag -KPIC is the default.
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      linux* | k*bsd*-gnu | kopensolaris*-gnu)
+	case $cc_basename in
+	  KCC*)
+	    # KAI C++ Compiler
+	    lt_prog_compiler_wl_CXX='--backend -Wl,'
+	    lt_prog_compiler_pic_CXX='-fPIC'
+	    ;;
+	  ecpc* )
+	    # old Intel C++ for x86_64 which still supported -KPIC.
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_pic_CXX='-KPIC'
+	    lt_prog_compiler_static_CXX='-static'
+	    ;;
+	  icpc* )
+	    # Intel C++, used to be incompatible with GCC.
+	    # ICC 10 doesn't accept -KPIC any more.
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_pic_CXX='-fPIC'
+	    lt_prog_compiler_static_CXX='-static'
+	    ;;
+	  pgCC* | pgcpp*)
+	    # Portland Group C++ compiler
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_pic_CXX='-fpic'
+	    lt_prog_compiler_static_CXX='-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_prog_compiler_pic_CXX=
+	    lt_prog_compiler_static_CXX='-non_shared'
+	    ;;
+	  xlc* | xlC* | bgxl[cC]* | mpixl[cC]*)
+	    # IBM XL 8.0, 9.0 on PPC and BlueGene
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_pic_CXX='-qpic'
+	    lt_prog_compiler_static_CXX='-qstaticlink'
+	    ;;
+	  *)
+	    case `$CC -V 2>&1 | sed 5q` in
+	    *Sun\ C*)
+	      # Sun C++ 5.9
+	      lt_prog_compiler_pic_CXX='-KPIC'
+	      lt_prog_compiler_static_CXX='-Bstatic'
+	      lt_prog_compiler_wl_CXX='-Qoption ld '
+	      ;;
+	    esac
+	    ;;
+	esac
+	;;
+      lynxos*)
+	;;
+      m88k*)
+	;;
+      mvs*)
+	case $cc_basename in
+	  cxx*)
+	    lt_prog_compiler_pic_CXX='-W c,exportall'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      netbsd*)
+	;;
+      *qnx* | *nto*)
+        # QNX uses GNU C++, but need to define -shared option too, otherwise
+        # it will coredump.
+        lt_prog_compiler_pic_CXX='-fPIC -shared'
+        ;;
+      osf3* | osf4* | osf5*)
+	case $cc_basename in
+	  KCC*)
+	    lt_prog_compiler_wl_CXX='--backend -Wl,'
+	    ;;
+	  RCC*)
+	    # Rational C++ 2.4.1
+	    lt_prog_compiler_pic_CXX='-pic'
+	    ;;
+	  cxx*)
+	    # Digital/Compaq C++
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    # Make sure the PIC flag is empty.  It appears that all Alpha
+	    # Linux and Compaq Tru64 Unix objects are PIC.
+	    lt_prog_compiler_pic_CXX=
+	    lt_prog_compiler_static_CXX='-non_shared'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      psos*)
+	;;
+      solaris*)
+	case $cc_basename in
+	  CC* | sunCC*)
+	    # Sun C++ 4.2, 5.x and Centerline C++
+	    lt_prog_compiler_pic_CXX='-KPIC'
+	    lt_prog_compiler_static_CXX='-Bstatic'
+	    lt_prog_compiler_wl_CXX='-Qoption ld '
+	    ;;
+	  gcx*)
+	    # Green Hills C++ Compiler
+	    lt_prog_compiler_pic_CXX='-PIC'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      sunos4*)
+	case $cc_basename in
+	  CC*)
+	    # Sun C++ 4.x
+	    lt_prog_compiler_pic_CXX='-pic'
+	    lt_prog_compiler_static_CXX='-Bstatic'
+	    ;;
+	  lcc*)
+	    # Lucid
+	    lt_prog_compiler_pic_CXX='-pic'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+	case $cc_basename in
+	  CC*)
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_pic_CXX='-KPIC'
+	    lt_prog_compiler_static_CXX='-Bstatic'
+	    ;;
+	esac
+	;;
+      tandem*)
+	case $cc_basename in
+	  NCC*)
+	    # NonStop-UX NCC 3.20
+	    lt_prog_compiler_pic_CXX='-KPIC'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      vxworks*)
+	;;
+      *)
+	lt_prog_compiler_can_build_shared_CXX=no
+	;;
+    esac
+  fi
+
+case $host_os in
+  # For platforms which do not support PIC, -DPIC is meaningless:
+  *djgpp*)
+    lt_prog_compiler_pic_CXX=
+    ;;
+  *)
+    lt_prog_compiler_pic_CXX="$lt_prog_compiler_pic_CXX -DPIC"
+    ;;
+esac
+
+{ $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 ${lt_cv_prog_compiler_pic_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_pic_CXX=$lt_prog_compiler_pic_CXX
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_CXX" >&5
+$as_echo "$lt_cv_prog_compiler_pic_CXX" >&6; }
+lt_prog_compiler_pic_CXX=$lt_cv_prog_compiler_pic_CXX
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$lt_prog_compiler_pic_CXX"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5
+$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... " >&6; }
+if ${lt_cv_prog_compiler_pic_works_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_pic_works_CXX=no
+   ac_outfile=conftest.$ac_objext
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+   lt_compiler_flag="$lt_prog_compiler_pic_CXX -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:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $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 "$_lt_compiler_boilerplate" | $SED '/^$/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_CXX=yes
+     fi
+   fi
+   $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works_CXX" >&5
+$as_echo "$lt_cv_prog_compiler_pic_works_CXX" >&6; }
+
+if test x"$lt_cv_prog_compiler_pic_works_CXX" = xyes; then
+    case $lt_prog_compiler_pic_CXX in
+     "" | " "*) ;;
+     *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;;
+     esac
+else
+    lt_prog_compiler_pic_CXX=
+     lt_prog_compiler_can_build_shared_CXX=no
+fi
+
+fi
+
+
+
+
+
+#
+# Check to make sure the static flag actually works.
+#
+wl=$lt_prog_compiler_wl_CXX eval lt_tmp_static_flag=\"$lt_prog_compiler_static_CXX\"
+{ $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 ${lt_cv_prog_compiler_static_works_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_static_works_CXX=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 "$_lt_linker_boilerplate" | $SED '/^$/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_CXX=yes
+       fi
+     else
+       lt_cv_prog_compiler_static_works_CXX=yes
+     fi
+   fi
+   $RM -r conftest*
+   LDFLAGS="$save_LDFLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works_CXX" >&5
+$as_echo "$lt_cv_prog_compiler_static_works_CXX" >&6; }
+
+if test x"$lt_cv_prog_compiler_static_works_CXX" = xyes; then
+    :
+else
+    lt_prog_compiler_static_CXX=
+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 ${lt_cv_prog_compiler_c_o_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_c_o_CXX=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:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $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 "$_lt_compiler_boilerplate" | $SED '/^$/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_CXX=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_CXX" >&5
+$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&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 ${lt_cv_prog_compiler_c_o_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_c_o_CXX=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:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $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 "$_lt_compiler_boilerplate" | $SED '/^$/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_CXX=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_CXX" >&5
+$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; }
+
+
+
+
+hard_links="nottested"
+if test "$lt_cv_prog_compiler_c_o_CXX" = 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; }
+
+  export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  exclude_expsyms_CXX='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'
+  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
+    # Also, AIX nm treats weak defined symbols like other global defined
+    # symbols, whereas GNU nm marks them as "W".
+    if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+      export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+    else
+      export_symbols_cmds_CXX='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+    fi
+    ;;
+  pw32*)
+    export_symbols_cmds_CXX="$ltdll_cmds"
+    ;;
+  cygwin* | mingw* | cegcc*)
+    case $cc_basename in
+    cl*)
+      exclude_expsyms_CXX='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
+      ;;
+    *)
+      export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols'
+      exclude_expsyms_CXX='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'
+      ;;
+    esac
+    ;;
+  *)
+    export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+    ;;
+  esac
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5
+$as_echo "$ld_shlibs_CXX" >&6; }
+test "$ld_shlibs_CXX" = no && can_build_shared=no
+
+with_gnu_ld_CXX=$with_gnu_ld
+
+
+
+
+
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$archive_cmds_need_lc_CXX" in
+x|xyes)
+  # Assume -lc should be added
+  archive_cmds_need_lc_CXX=yes
+
+  if test "$enable_shared" = yes && test "$GCC" = yes; then
+    case $archive_cmds_CXX 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; }
+if ${lt_cv_archive_cmds_need_lc_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  $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_CXX
+	  pic_flag=$lt_prog_compiler_pic_CXX
+	  compiler_flags=-v
+	  linker_flags=-v
+	  verstring=
+	  output_objdir=.
+	  libname=conftest
+	  lt_save_allow_undefined_flag=$allow_undefined_flag_CXX
+	  allow_undefined_flag_CXX=
+	  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5
+  (eval $archive_cmds_CXX 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
+	    lt_cv_archive_cmds_need_lc_CXX=no
+	  else
+	    lt_cv_archive_cmds_need_lc_CXX=yes
+	  fi
+	  allow_undefined_flag_CXX=$lt_save_allow_undefined_flag
+	else
+	  cat conftest.err 1>&5
+	fi
+	$RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc_CXX" >&5
+$as_echo "$lt_cv_archive_cmds_need_lc_CXX" >&6; }
+      archive_cmds_need_lc_CXX=$lt_cv_archive_cmds_need_lc_CXX
+      ;;
+    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 # correct to gnu/linux during the next big refactor
+  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 # correct to gnu/linux during the next big refactor
+  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=`func_echo_all "$lib" | $SED '\''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 # correct to gnu/linux during the next big refactor
+  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,$cc_basename in
+  yes,*)
+    # gcc
+    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}'
+
+      ;;
+    mingw* | cegcc*)
+      # MinGW DLLs use traditional 'lib' prefix
+      soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      ;;
+    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
+    dynamic_linker='Win32 ld.exe'
+    ;;
+
+  *,cl*)
+    # Native MSVC
+    libname_spec='$name'
+    soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+    library_names_spec='${libname}.dll.lib'
+
+    case $build_os in
+    mingw*)
+      sys_lib_search_path_spec=
+      lt_save_ifs=$IFS
+      IFS=';'
+      for lt_path in $LIB
+      do
+        IFS=$lt_save_ifs
+        # Let DOS variable expansion print the short 8.3 style file name.
+        lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"`
+        sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path"
+      done
+      IFS=$lt_save_ifs
+      # Convert to MSYS style.
+      sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'`
+      ;;
+    cygwin*)
+      # Convert to unix form, then to dos form, then back to unix form
+      # but this time dos style (no spaces!) so that the unix form looks
+      # like /cygdrive/c/PROGRA~1:/cygdr...
+      sys_lib_search_path_spec=`cygpath --path --unix "$LIB"`
+      sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null`
+      sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+      ;;
+    *)
+      sys_lib_search_path_spec="$LIB"
+      if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then
+        # It is most probably a Windows format PATH.
+        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
+      # FIXME: find the short name or the path components, as spaces are
+      # common. (e.g. "Program Files" -> "PROGRA~1")
+      ;;
+    esac
+
+    # 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'
+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+      dlpath=$dir/\$dldll~
+       $RM \$dlpath'
+    shlibpath_overrides_runpath=yes
+    dynamic_linker='Win32 link.exe'
+    ;;
+
+  *)
+    # Assume MSVC wrapper
+    library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
+    dynamic_linker='Win32 ld.exe'
+    ;;
+  esac
+  # 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 # correct to gnu/linux during the next big refactor
+  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
+  ;;
+
+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[23].*) objformat=aout ;;
+    *) objformat=elf ;;
+    esac
+  fi
+  # Handle Gentoo/FreeBSD as it was Linux
+  case $host_vendor in
+    gentoo)
+      version_type=linux ;;
+    *)
+      version_type=freebsd-$objformat ;;
+  esac
+
+  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
+      ;;
+    linux)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+      soname_spec='${libname}${release}${shared_ext}$major'
+      need_lib_prefix=no
+      need_version=no
+      ;;
+  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 # correct to gnu/linux during the next big refactor
+  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
+  ;;
+
+haiku*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  dynamic_linker="$host_os runtime_loader"
+  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=LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
+  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'
+  # or fails outright, so override atomically:
+  install_override_mode=555
+  ;;
+
+interix[3-9]*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  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 # correct to gnu/linux during the next big refactor
+	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 glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  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
+  if ${lt_cv_shlibpath_overrides_runpath+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_shlibpath_overrides_runpath=no
+    save_LDFLAGS=$LDFLAGS
+    save_libdir=$libdir
+    eval "libdir=/foo; wl=\"$lt_prog_compiler_wl_CXX\"; \
+	 LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec_CXX\""
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+  if  ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then :
+  lt_cv_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
+
+fi
+
+  shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath
+
+  # 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;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'
+  ;;
+
+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 # correct to gnu/linux during the next big refactor
+  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 # correct to gnu/linux during the next big refactor
+  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 # correct to gnu/linux during the next big refactor
+  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 # correct to gnu/linux during the next big refactor
+    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 # correct to gnu/linux during the next big refactor
+  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 # correct to gnu/linux during the next big refactor
+  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_CXX=
+if test -n "$hardcode_libdir_flag_spec_CXX" ||
+   test -n "$runpath_var_CXX" ||
+   test "X$hardcode_automatic_CXX" = "Xyes" ; then
+
+  # We can hardcode non-existent directories.
+  if test "$hardcode_direct_CXX" != 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, CXX)" != no &&
+     test "$hardcode_minus_L_CXX" != no; then
+    # Linking always hardcodes the temporary library directory.
+    hardcode_action_CXX=relink
+  else
+    # We can link without hardcoding, and we can hardcode nonexisting dirs.
+    hardcode_action_CXX=immediate
+  fi
+else
+  # We cannot hardcode anything, or else we can only hardcode existing
+  # directories.
+  hardcode_action_CXX=unsupported
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action_CXX" >&5
+$as_echo "$hardcode_action_CXX" >&6; }
+
+if test "$hardcode_action_CXX" = relink ||
+   test "$inherit_rpath_CXX" = 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"
+
+  CC=$lt_save_CC
+  CFLAGS=$lt_save_CFLAGS
+  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_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_config_commands="$ac_config_commands libtool"
+
+
+
+
+# Only expand once:
+
+
+
+link_all_deplibs=yes
+link_all_deplibs_CXX=yes
+
+# Checks for libraries.
+
+# This test for -lpthread etc has to come before AX_PTHREAD,
+# because libtool tends to ignore -pthread in linking shared C++-libs
+# see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=25460
+# (happens with ubuntu 14.04)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing sem_wait" >&5
+$as_echo_n "checking for library containing sem_wait... " >&6; }
+if ${ac_cv_search_sem_wait+:} false; 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 sem_wait ();
+int
+main ()
+{
+return sem_wait ();
+  ;
+  return 0;
+}
+_ACEOF
+for ac_lib in '' rt pthreads pthread; 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_sem_wait=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext
+  if ${ac_cv_search_sem_wait+:} false; then :
+  break
+fi
+done
+if ${ac_cv_search_sem_wait+:} false; then :
+
+else
+  ac_cv_search_sem_wait=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_sem_wait" >&5
+$as_echo "$ac_cv_search_sem_wait" >&6; }
+ac_res=$ac_cv_search_sem_wait
+if test "$ac_res" != no; then :
+  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+else
+
+  as_fn_error $? "sem_wait not found in rt,pthreads,pthread" "$LINENO" 5
+
+fi
+
+
+#AC_CHECK_LIB(pthread,pthread_create)
+
+
+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
+
+ax_pthread_ok=no
+
+# We used to check for pthread.h first, but this fails if pthread.h
+# requires special compiler flags (e.g. on True64 or Sequent).
+# It gets checked for in the link test anyway.
+
+# First of all, check if the user has set any of the PTHREAD_LIBS,
+# etcetera environment variables, and if threads linking works using
+# them:
+if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then
+        save_CFLAGS="$CFLAGS"
+        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+        save_LIBS="$LIBS"
+        LIBS="$PTHREAD_LIBS $LIBS"
+        { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS" >&5
+$as_echo_n "checking for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS... " >&6; }
+        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 pthread_join ();
+int
+main ()
+{
+return pthread_join ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ax_pthread_ok=yes
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_pthread_ok" >&5
+$as_echo "$ax_pthread_ok" >&6; }
+        if test x"$ax_pthread_ok" = xno; then
+                PTHREAD_LIBS=""
+                PTHREAD_CFLAGS=""
+        fi
+        LIBS="$save_LIBS"
+        CFLAGS="$save_CFLAGS"
+fi
+
+# We must check for the threads library under a number of different
+# names; the ordering is very important because some systems
+# (e.g. DEC) have both -lpthread and -lpthreads, where one of the
+# libraries is broken (non-POSIX).
+
+# Create a list of thread flags to try.  Items starting with a "-" are
+# C compiler flags, and other items are library names, except for "none"
+# which indicates that we try without any flags at all, and "pthread-config"
+# which is a program returning the flags for the Pth emulation library.
+
+ax_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
+
+# The ordering *is* (sometimes) important.  Some notes on the
+# individual items follow:
+
+# pthreads: AIX (must check this before -lpthread)
+# none: in case threads are in libc; should be tried before -Kthread and
+#       other compiler flags to prevent continual compiler warnings
+# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
+# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
+# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
+# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads)
+# -pthreads: Solaris/gcc
+# -mthreads: Mingw32/gcc, Lynx/gcc
+# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
+#      doesn't hurt to check since this sometimes defines pthreads too;
+#      also defines -D_REENTRANT)
+#      ... -mt is also the pthreads flag for HP/aCC
+# pthread: Linux, etcetera
+# --thread-safe: KAI C++
+# pthread-config: use pthread-config program (for GNU Pth library)
+
+case ${host_os} in
+        solaris*)
+
+        # On Solaris (at least, for some versions), libc contains stubbed
+        # (non-functional) versions of the pthreads routines, so link-based
+        # tests will erroneously succeed.  (We need to link with -pthreads/-mt/
+        # -lpthread.)  (The stubs are missing pthread_cleanup_push, or rather
+        # a function called by this macro, so we could check for that, but
+        # who knows whether they'll stub that too in a future libc.)  So,
+        # we'll just look for -pthreads and -lpthread first:
+
+        ax_pthread_flags="-pthreads pthread -mt -pthread $ax_pthread_flags"
+        ;;
+
+        darwin*)
+        ax_pthread_flags="-pthread $ax_pthread_flags"
+        ;;
+esac
+
+# Clang doesn't consider unrecognized options an error unless we specify
+# -Werror. We throw in some extra Clang-specific options to ensure that
+# this doesn't happen for GCC, which also accepts -Werror.
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiler needs -Werror to reject unknown flags" >&5
+$as_echo_n "checking if compiler needs -Werror to reject unknown flags... " >&6; }
+save_CFLAGS="$CFLAGS"
+ax_pthread_extra_flags="-Werror"
+CFLAGS="$CFLAGS $ax_pthread_extra_flags -Wunknown-warning-option -Wsizeof-array-argument"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+int foo(void);
+int
+main ()
+{
+foo()
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+  ax_pthread_extra_flags=
+                   { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+CFLAGS="$save_CFLAGS"
+
+if test x"$ax_pthread_ok" = xno; then
+for flag in $ax_pthread_flags; do
+
+        case $flag in
+                none)
+                { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pthreads work without any flags" >&5
+$as_echo_n "checking whether pthreads work without any flags... " >&6; }
+                ;;
+
+                -*)
+                { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pthreads work with $flag" >&5
+$as_echo_n "checking whether pthreads work with $flag... " >&6; }
+                PTHREAD_CFLAGS="$flag"
+                ;;
+
+                pthread-config)
+                # Extract the first word of "pthread-config", so it can be a program name with args.
+set dummy pthread-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 ${ac_cv_prog_ax_pthread_config+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ax_pthread_config"; then
+  ac_cv_prog_ax_pthread_config="$ax_pthread_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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ax_pthread_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_ax_pthread_config" && ac_cv_prog_ax_pthread_config="no"
+fi
+fi
+ax_pthread_config=$ac_cv_prog_ax_pthread_config
+if test -n "$ax_pthread_config"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_pthread_config" >&5
+$as_echo "$ax_pthread_config" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+                if test x"$ax_pthread_config" = xno; then continue; fi
+                PTHREAD_CFLAGS="`pthread-config --cflags`"
+                PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
+                ;;
+
+                *)
+                { $as_echo "$as_me:${as_lineno-$LINENO}: checking for the pthreads library -l$flag" >&5
+$as_echo_n "checking for the pthreads library -l$flag... " >&6; }
+                PTHREAD_LIBS="-l$flag"
+                ;;
+        esac
+
+        save_LIBS="$LIBS"
+        save_CFLAGS="$CFLAGS"
+        LIBS="$PTHREAD_LIBS $LIBS"
+        CFLAGS="$CFLAGS $PTHREAD_CFLAGS $ax_pthread_extra_flags"
+
+        # Check for various functions.  We must include pthread.h,
+        # since some functions may be macros.  (On the Sequent, we
+        # need a special flag -Kthread to make this header compile.)
+        # We check for pthread_join because it is in -lpthread on IRIX
+        # while pthread_create is in libc.  We check for pthread_attr_init
+        # due to DEC craziness with -lpthreads.  We check for
+        # pthread_cleanup_push because it is one of the few pthread
+        # functions on Solaris that doesn't have a non-functional libc stub.
+        # We try pthread_create on general principles.
+        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <pthread.h>
+                        static void routine(void *a) { a = 0; }
+                        static void *start_routine(void *a) { return a; }
+int
+main ()
+{
+pthread_t th; pthread_attr_t attr;
+                        pthread_create(&th, 0, start_routine, 0);
+                        pthread_join(th, 0);
+                        pthread_attr_init(&attr);
+                        pthread_cleanup_push(routine, 0);
+                        pthread_cleanup_pop(0) /* ; */
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ax_pthread_ok=yes
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+
+        LIBS="$save_LIBS"
+        CFLAGS="$save_CFLAGS"
+
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_pthread_ok" >&5
+$as_echo "$ax_pthread_ok" >&6; }
+        if test "x$ax_pthread_ok" = xyes; then
+                break;
+        fi
+
+        PTHREAD_LIBS=""
+        PTHREAD_CFLAGS=""
+done
+fi
+
+# Various other checks:
+if test "x$ax_pthread_ok" = xyes; then
+        save_LIBS="$LIBS"
+        LIBS="$PTHREAD_LIBS $LIBS"
+        save_CFLAGS="$CFLAGS"
+        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+
+        # Detect AIX lossage: JOINABLE attribute is called UNDETACHED.
+        { $as_echo "$as_me:${as_lineno-$LINENO}: checking for joinable pthread attribute" >&5
+$as_echo_n "checking for joinable pthread attribute... " >&6; }
+        attr_name=unknown
+        for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
+            cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <pthread.h>
+int
+main ()
+{
+int attr = $attr; return attr /* ; */
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  attr_name=$attr; break
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+        done
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: $attr_name" >&5
+$as_echo "$attr_name" >&6; }
+        if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then
+
+cat >>confdefs.h <<_ACEOF
+#define PTHREAD_CREATE_JOINABLE $attr_name
+_ACEOF
+
+        fi
+
+        { $as_echo "$as_me:${as_lineno-$LINENO}: checking if more special flags are required for pthreads" >&5
+$as_echo_n "checking if more special flags are required for pthreads... " >&6; }
+        flag=no
+        case ${host_os} in
+            aix* | freebsd* | darwin*) flag="-D_THREAD_SAFE";;
+            osf* | hpux*) flag="-D_REENTRANT";;
+            solaris*)
+            if test "$GCC" = "yes"; then
+                flag="-D_REENTRANT"
+            else
+                # TODO: What about Clang on Solaris?
+                flag="-mt -D_REENTRANT"
+            fi
+            ;;
+        esac
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: $flag" >&5
+$as_echo "$flag" >&6; }
+        if test "x$flag" != xno; then
+            PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS"
+        fi
+
+        { $as_echo "$as_me:${as_lineno-$LINENO}: checking for PTHREAD_PRIO_INHERIT" >&5
+$as_echo_n "checking for PTHREAD_PRIO_INHERIT... " >&6; }
+if ${ax_cv_PTHREAD_PRIO_INHERIT+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+                cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <pthread.h>
+int
+main ()
+{
+int i = PTHREAD_PRIO_INHERIT;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ax_cv_PTHREAD_PRIO_INHERIT=yes
+else
+  ax_cv_PTHREAD_PRIO_INHERIT=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_PTHREAD_PRIO_INHERIT" >&5
+$as_echo "$ax_cv_PTHREAD_PRIO_INHERIT" >&6; }
+        if test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes"; then :
+
+$as_echo "#define HAVE_PTHREAD_PRIO_INHERIT 1" >>confdefs.h
+
+fi
+
+        LIBS="$save_LIBS"
+        CFLAGS="$save_CFLAGS"
+
+        # More AIX lossage: compile with *_r variant
+        if test "x$GCC" != xyes; then
+            case $host_os in
+                aix*)
+                case "x/$CC" in #(
+  x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6) :
+    #handle absolute path differently from PATH based program lookup
+                   case "x$CC" in #(
+  x/*) :
+    if as_fn_executable_p ${CC}_r; then :
+  PTHREAD_CC="${CC}_r"
+fi ;; #(
+  *) :
+    for ac_prog in ${CC}_r
+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 ${ac_cv_prog_PTHREAD_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$PTHREAD_CC"; then
+  ac_cv_prog_PTHREAD_CC="$PTHREAD_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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_PTHREAD_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
+PTHREAD_CC=$ac_cv_prog_PTHREAD_CC
+if test -n "$PTHREAD_CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PTHREAD_CC" >&5
+$as_echo "$PTHREAD_CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$PTHREAD_CC" && break
+done
+test -n "$PTHREAD_CC" || PTHREAD_CC="$CC"
+ ;;
+esac ;; #(
+  *) :
+     ;;
+esac
+                ;;
+            esac
+        fi
+fi
+
+test -n "$PTHREAD_CC" || PTHREAD_CC="$CC"
+
+
+
+
+
+# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
+if test x"$ax_pthread_ok" = xyes; then
+
+$as_echo "#define HAVE_PTHREAD 1" >>confdefs.h
+
+        :
+else
+        ax_pthread_ok=no
+
+  as_fn_error $? "Pthread library not found. Please set PTHREAD_CFLAGS and PTHREAD_LIBS correctly for your setup" "$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 Found Pthread, PTHREAD_CC:" >&5
+$as_echo_n "checking Found Pthread, PTHREAD_CC:... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${PTHREAD_CC:-unset}" >&5
+$as_echo "${PTHREAD_CC:-unset}" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking                PTHREAD_CFLAGS:" >&5
+$as_echo_n "checking                PTHREAD_CFLAGS:... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${PTHREAD_CFLAGS:-unset}" >&5
+$as_echo "${PTHREAD_CFLAGS:-unset}" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking                PTHREAD_LIBS:" >&5
+$as_echo_n "checking                PTHREAD_LIBS:... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${PTHREAD_LIBS:-unset}" >&5
+$as_echo "${PTHREAD_LIBS:-unset}" >&6; }
+
+# Set the correct PTHREAD flags and, if needed, change the compiler to one that is pthread-enabled.
+CC="$PTHREAD_CC"
+CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+LDFLAGS="$LDFLAGS $PTHREAD_LDFLAGS"
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for clock_gettime in -lrt" >&5
+$as_echo_n "checking for clock_gettime in -lrt... " >&6; }
+if ${ac_cv_lib_rt_clock_gettime+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lrt  $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 clock_gettime ();
+int
+main ()
+{
+return clock_gettime ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_rt_clock_gettime=yes
+else
+  ac_cv_lib_rt_clock_gettime=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_rt_clock_gettime" >&5
+$as_echo "$ac_cv_lib_rt_clock_gettime" >&6; }
+if test "x$ac_cv_lib_rt_clock_gettime" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBRT 1
+_ACEOF
+
+  LIBS="-lrt $LIBS"
+
+fi
+
+
+
+DEFAULT_CHECKING_PATH="/usr /usr/local /sw /opt/local"
+
+
+# Check whether --with-gmp was given.
+if test "${with_gmp+set}" = set; then :
+  withval=$with_gmp; if test "$withval" = yes ; then
+			GMP_HOME_PATH="${DEFAULT_CHECKING_PATH}"
+	         elif test "$withval" != no ; then
+			GMP_HOME_PATH="$withval ${DEFAULT_CHECKING_PATH}"
+	        fi
+else
+  GMP_HOME_PATH="${DEFAULT_CHECKING_PATH}"
+fi
+
+
+min_gmp_version=4.0
+
+BACKUP_CFLAGS=${CFLAGS}
+BACKUP_LIBS=${LIBS}
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GMP >= $min_gmp_version" >&5
+$as_echo_n "checking for GMP >= $min_gmp_version... " >&6; }
+
+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
+
+
+for GMP_HOME in ${GMP_HOME_PATH}
+  do
+#	if test -r "$GMP_HOME/include/gmp.h"; then
+
+		if test "x$GMP_HOME" != "x/usr"; then
+			GMP_CFLAGS="-I${GMP_HOME}/include"
+			GMP_LIBS="-L${GMP_HOME}/lib -Wl,-rpath -Wl,${GMP_HOME}/lib -lgmp"
+		else
+			GMP_CFLAGS=""
+			GMP_LIBS="-lgmp"
+		fi
+
+		CFLAGS="${BACKUP_CFLAGS} ${GMP_CFLAGS}"
+		LIBS="${BACKUP_LIBS} ${GMP_LIBS}"
+
+    # According to C. Fieker this would link but would not RUN
+    # (AC_TRY_RUN) due to missing SHARED libgmp.so :(
+    # TODO: set LD_LIBRARY_PATH???
+		cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <gmp.h>
+int
+main ()
+{
+mpz_t a; mpz_init (a);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+        		if test "$cross_compiling" = yes; then :
+
+				{ $as_echo "$as_me:${as_lineno-$LINENO}: result: unknown" >&5
+$as_echo "unknown" >&6; }
+				echo "WARNING: You appear to be cross compiling, so there is no way to determine"
+				echo "whether your GMP version is new enough. I am assuming it is."
+
+
+
+				HAVE_GMP=yes
+
+$as_echo "#define HAVE_GMP 1" >>confdefs.h
+
+				:
+				break
+
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <gmp.h>
+			 int main () {  if (__GNU_MP_VERSION < 3) return -1; else return 0; }
+
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+				{ $as_echo "$as_me:${as_lineno-$LINENO}: result: found" >&5
+$as_echo "found" >&6; }
+
+
+
+$as_echo "#define HAVE_GMP 1" >>confdefs.h
+
+				# See if we are running GMP 4.0
+	   			{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether GMP is 4.0 or greater" >&5
+$as_echo_n "checking whether GMP is 4.0 or greater... " >&6; }
+		   		if test "$cross_compiling" = yes; then :
+
+										{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <gmp.h>
+	    			int main () { if (__GNU_MP_VERSION < 4) return -1; else return 0; }
+
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+					gmp_found="yes"
+					{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+					GMP_VERSION=""
+
+
+else
+
+					{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+$as_echo "#define GMP_VERSION_3 1" >>confdefs.h
+
+					GMP_VERSION="-DGMP_VERSION_3"
+
+
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+				:
+				break
+
+else
+
+				gmp_problem="$gmp_problem $GMP_HOME"
+				unset GMP_CFLAGS
+				unset GMP_LIBS
+
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+
+else
+
+		gmp_found="no"
+		unset GMP_CFLAGS
+		unset GMP_LIBS
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+
+#	else
+#		gmp_found="no"
+#	fi
+done
+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
+
+
+CFLAGS=${BACKUP_CFLAGS}
+LIBS=${BACKUP_LIBS}
+#unset LD_LIBRARY_PATH
+
+
+if test "x$gmp_found" != "xyes"; then
+	if test -n "$gmp_problem"; then
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: problem" >&5
+$as_echo "problem" >&6; }
+		echo "Sorry, your GMP version is too old. Disabling."
+	elif test "x$gmp_found" != "xno"; then
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5
+$as_echo "not found" >&6; }
+	fi
+	as_fn_error $? "Unable to find GMP on your machine: please use --with-gmp=PATH_TO_DIR_CONTAINING_LIB_AND_INCLUDE (see also ./configure --help if you do not understand what we are talking about)" "$LINENO" 5
+fi
+
+ if test "x$HAVE_GMP" = "xyes"; then
+  SING_HAVE_GMP_TRUE=
+  SING_HAVE_GMP_FALSE='#'
+else
+  SING_HAVE_GMP_TRUE='#'
+  SING_HAVE_GMP_FALSE=
+fi
+
+
+
+DEFAULT_CHECKING_PATH="/usr /usr/local /sw /opt/local"
+
+
+# Check whether --with-ntl was given.
+if test "${with_ntl+set}" = set; then :
+  withval=$with_ntl; if test "$withval" = yes ; then
+			NTL_HOME_PATH="${DEFAULT_CHECKING_PATH}"
+	      elif test "$withval" != no ; then
+			NTL_HOME_PATH="$withval"
+	     fi
+else
+  NTL_HOME_PATH="${DEFAULT_CHECKING_PATH}"
+fi
+
+
+min_ntl_version=5.0
+
+
+BACKUP_CXXFLAGS=${CXXFLAGS}
+BACKUP_CFLAGS=${CFLAGS}
+BACKUP_LIBS=${LIBS}
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+if test -n "$NTL_HOME_PATH"; then
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for NTL >= $min_ntl_version" >&5
+$as_echo_n "checking for NTL >= $min_ntl_version... " >&6; }
+fi
+
+for NTL_HOME in ${NTL_HOME_PATH}
+ do
+if test -r "$NTL_HOME/include/NTL/ZZ.h"; then
+
+	if test "x$NTL_HOME" != "x/usr"; then
+		NTL_CFLAGS="-I${NTL_HOME}/include"
+		NTL_LIBS="-L${NTL_HOME}/lib -lntl"
+	else
+		NTL_CFLAGS=
+		NTL_LIBS="-lntl"
+	fi
+###	CFLAGS="${BACKUP_CFLAGS} ${NTL_CFLAGS} ${GMP_CFLAGS}"
+	CXXFLAGS="${BACKUP_CFLAGS} ${BACKUP_CXXFLAGS} ${NTL_CFLAGS} ${GMP_CFLAGS}"
+	LIBS="${BACKUP_LIBS} ${NTL_LIBS} ${GMP_LIBS}"
+
+	cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <NTL/ZZ.h>
+int
+main ()
+{
+NTL::ZZ a;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+
+	if test "$cross_compiling" = yes; then :
+
+	ntl_found="yes"
+	ntl_cross="yes"
+	break
+
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <NTL/version.h>
+	#include <NTL/config.h>
+	#ifndef NTL_GMP_LIP
+	int main() {return -1;}
+	#else
+	int main () { if (NTL_MAJOR_VERSION < 5) return -1; else return 0;}
+	#endif
+
+_ACEOF
+if ac_fn_cxx_try_run "$LINENO"; then :
+
+	ntl_found="yes"
+	break
+
+else
+
+	ntl_problem="$problem $NTL_HOME"
+	unset NTL_CFLAGS
+	unset NTL_LIBS
+
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+
+else
+
+	ntl_found="no"
+	ntl_checked="$checked $NTL_HOME"
+	unset NTL_CFLAGS
+	unset NTL_LIBS
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+else
+	ntl_found="no"
+fi
+done
+
+if test "x$ntl_found" = "xyes" ; then
+
+
+
+$as_echo "#define HAVE_NTL 1" >>confdefs.h
+
+	HAVE_NTL=yes
+	if test "x$ntl_cross" != "xyes"; then
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: found" >&5
+$as_echo "found" >&6; }
+	else
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: unknown" >&5
+$as_echo "unknown" >&6; }
+		echo "WARNING: You appear to be cross compiling, so there is no way to determine"
+		echo "whether your NTL version is new enough. I am assuming it is."
+	fi
+	:
+elif test -n "$ntl_problem"; then
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: problem" >&5
+$as_echo "problem" >&6; }
+	echo "Sorry, your NTL version is too old or not configured with NTL_GMP_LIP=on. Disabling."
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to find NTL (which is strongly recommended) on your machine: please use --with-ntl=PATH_TO_DIR_CONTAINING_LIB_AND_INCLUDE (see also ./configure --help if you do not understand what we are talking about)" >&5
+$as_echo "$as_me: WARNING: Unable to find NTL (which is strongly recommended) on your machine: please use --with-ntl=PATH_TO_DIR_CONTAINING_LIB_AND_INCLUDE (see also ./configure --help if you do not understand what we are talking about)" >&2;}
+elif test   "x$ntl_found" = "xno";  then
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5
+$as_echo "not found" >&6; }
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to find NTL (which is strongly recommended) on your machine: please use --with-ntl=PATH_TO_DIR_CONTAINING_LIB_AND_INCLUDE (see also ./configure --help if you do not understand what we are talking about)" >&5
+$as_echo "$as_me: WARNING: Unable to find NTL (which is strongly recommended) on your machine: please use --with-ntl=PATH_TO_DIR_CONTAINING_LIB_AND_INCLUDE (see also ./configure --help if you do not understand what we are talking about)" >&2;}
+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 "x$HAVE_NTL" = "xyes"; then
+  SING_HAVE_NTL_TRUE=
+  SING_HAVE_NTL_FALSE='#'
+else
+  SING_HAVE_NTL_TRUE='#'
+  SING_HAVE_NTL_FALSE=
+fi
+
+
+# TODO: The following seems to set CXXFLAGS even if it was not defined previously!!!!
+CXXFLAGS=${BACKUP_CXXFLAGS}
+LIBS=${BACKUP_LIBS}
+#unset LD_LIBRARY_PATH
+
+
+
+DEFAULT_CHECKING_PATH="/usr /usr/local /sw /opt/local"
+
+
+# Check whether --with-flint was given.
+if test "${with_flint+set}" = set; then :
+  withval=$with_flint; if test "$withval" = yes ; then
+			FLINT_HOME_PATH="${DEFAULT_CHECKING_PATH}"
+	      elif test "$withval" != no ; then
+			FLINT_HOME_PATH="$withval"
+	     fi
+else
+  FLINT_HOME_PATH="${DEFAULT_CHECKING_PATH}"
+fi
+
+
+min_flint_version=2.3
+
+
+BACKUP_CFLAGS=${CFLAGS}
+BACKUP_LIBS=${LIBS}
+
+if test -n "$FLINT_HOME_PATH"; then
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for FLINT >= $min_flint_version" >&5
+$as_echo_n "checking for FLINT >= $min_flint_version... " >&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
+
+
+for FLINT_HOME in ${FLINT_HOME_PATH}
+ do
+## if test -r "$FLINT_HOME/include/flint/fmpz.h"; then
+
+	if test "x$FLINT_HOME" != "x/usr"; then
+		FLINT_CFLAGS="-I${FLINT_HOME}/include/"
+		FLINT_LIBS="-L${FLINT_HOME}/lib"
+	else
+		FLINT_CFLAGS=""
+		FLINT_LIBS=""
+	fi
+
+	# we suppose that mpfr and mpir to be in the same place or available by default
+	FLINT_LIBS="$FLINT_LIBS -lflint -lmpfr"
+
+	CFLAGS="${BACKUP_CFLAGS} ${FLINT_CFLAGS} ${GMP_CFLAGS}"
+	LIBS="${BACKUP_LIBS} ${FLINT_LIBS} ${GMP_LIBS}"
+
+	cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <flint/fmpz.h>
+int
+main ()
+{
+fmpz_t a; fmpz_init (a);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+	if test "$cross_compiling" = yes; then :
+
+	flint_found="yes"
+	flint_cross="yes"
+	break
+
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <flint/flint.h>
+	int main () { if ((int) version[0] < 2) return -1; else return 0; }
+
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+	flint_found="yes"
+	break
+
+else
+
+	flint_problem="$problem $FLINT_HOME"
+	unset FLINT_CFLAGS
+	unset FLINT_LIBS
+
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+
+else
+
+	flint_found="no"
+	flint_checked="$checked $FLINT_HOME"
+	unset FLINT_CFLAGS
+	unset FLINT_LIBS
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+#else
+#	flint_found="no"
+#fi
+done
+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
+
+
+CFLAGS=${BACKUP_CFLAGS}
+LIBS=${BACKUP_LIBS}
+#unset LD_LIBRARY_PATH
+
+
+if test "x$flint_found" = "xyes" ; then
+
+
+
+
+$as_echo "#define HAVE_FLINT 1" >>confdefs.h
+
+	HAVE_FLINT=yes
+	if test "x$flint_cross" != "xyes"; then
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: found" >&5
+$as_echo "found" >&6; }
+	else
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: unknown" >&5
+$as_echo "unknown" >&6; }
+		echo "WARNING: You appear to be cross compiling, so there is no way to determine"
+		echo "whether your FLINT version is new enough. I am assuming it is."
+	fi
+	:
+elif test -n "$flint_problem"; then
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: problem" >&5
+$as_echo "problem" >&6; }
+	echo "Sorry, your FLINT version is too old. Disabling."
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to find FLINT (which is strongly recommended) on your machine: please use --with-flint=PATH_TO_DIR_CONTAINING_LIB_AND_INCLUDE (see also ./configure --help if you do not understand what we are talking about)" >&5
+$as_echo "$as_me: WARNING: Unable to find FLINT (which is strongly recommended) on your machine: please use --with-flint=PATH_TO_DIR_CONTAINING_LIB_AND_INCLUDE (see also ./configure --help if you do not understand what we are talking about)" >&2;}
+elif test   "x$flint_found" = "xno";  then
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5
+$as_echo "not found" >&6; }
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to find FLINT (which is strongly recommended) on your machine: please use --with-flint=PATH_TO_DIR_CONTAINING_LIB_AND_INCLUDE (see also ./configure --help if you do not understand what we are talking about)" >&5
+$as_echo "$as_me: WARNING: Unable to find FLINT (which is strongly recommended) on your machine: please use --with-flint=PATH_TO_DIR_CONTAINING_LIB_AND_INCLUDE (see also ./configure --help if you do not understand what we are talking about)" >&2;}
+fi
+
+ if test "x$HAVE_FLINT" = "xyes"; then
+  SING_HAVE_FLINT_TRUE=
+  SING_HAVE_FLINT_FALSE='#'
+else
+  SING_HAVE_FLINT_TRUE='#'
+  SING_HAVE_FLINT_FALSE=
+fi
+
+
+
+
+
+    ac_google_perfdir='no'
+
+# Check whether --with-google-perftools was given.
+if test "${with_google_perftools+set}" = set; then :
+  withval=$with_google_perftools; ac_google_perfdir=$withval
+fi
+
+
+    # Check whether --enable-google-profiling was given.
+if test "${enable_google_profiling+set}" = set; then :
+  enableval=$enable_google_profiling; google_profile=$enableval
+else
+  google_profile=no
+fi
+
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to compile with google profiling" >&5
+$as_echo_n "checking whether to compile with google profiling... " >&6; }
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $google_profile" >&5
+$as_echo "$google_profile" >&6; }
+
+    GOOGLE_PROFILE_ENABLED=0
+    if test $google_profile = yes ; then
+        if test $ac_google_perfdir = no ; then
+	   as_fn_error $? "must specify --with-google-perftools to use google profiling" "$LINENO" 5
+	fi
+        GOOGLE_PROFILE_ENABLED=1
+    fi
+
+
+cat >>confdefs.h <<_ACEOF
+#define GOOGLE_PROFILE_ENABLED $GOOGLE_PROFILE_ENABLED
+_ACEOF
+
+
+                if test "$ac_google_perfdir" = no; then
+    GOOGLE_PERFTOOLS_ENABLED=0
+    else
+
+    GOOGLE_PERFTOOLS_ENABLED=1
+
+cat >>confdefs.h <<_ACEOF
+#define GOOGLE_PERFTOOLS_ENABLED 1
+_ACEOF
+
+
+                            if test "$ac_google_perfdir" = yes -a \
+	    ! "$oasys_cv_path_google_perf_h" = "" ; then
+        echo "checking for google_perf installation... (cached)"
+    else
+
+    oasys_cv_path_google_perf_h=
+    oasys_cv_path_google_perf_lib=
+
+    ac_save_CPPFLAGS="$CPPFLAGS"
+    ac_save_LDFLAGS="$LDFLAGS"
+    ac_save_LIBS="$LIBS"
+
+    ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+    if test "$ac_google_perfdir" = system -o \
+            "$ac_google_perfdir" = yes -o \
+            "$ac_google_perfdir" = "" ;
+    then
+        ac_google_perfincdirs="/usr/local/include \
+	                       /usr/local/google-perftools/include"
+        ac_google_perflibdirs="/usr/local/lib \
+	                       /usr/local/google-perftools/lib"
+    else
+        ac_google_perfincdirs="$ac_google_perfdir/include"
+        ac_google_perflibdirs="$ac_google_perfdir/lib"
+    fi
+
+    for ac_google_perfincdir in $ac_google_perfincdirs; do
+
+	CPPFLAGS="$ac_save_CPPFLAGS -I$ac_google_perfincdir"
+	LDFLAGS="$ac_save_LDFLAGS"
+	LIBS="$ac_save_LIBS"
+
+					        { $as_echo "$as_me:${as_lineno-$LINENO}: checking for google perftools header profiler.h in $ac_google_perfincdir" >&5
+$as_echo_n "checking for google perftools header profiler.h in $ac_google_perfincdir... " >&6; }
+	cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+                #include <google/profiler.h>
+
+int
+main ()
+{
+
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+
+	      { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+              oasys_cv_path_google_perf_h=$ac_google_perfincdir
+	      break
+
+else
+
+              { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+	      continue
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+    done
+
+    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$oasys_cv_path_google_perf_h = x ; then
+        as_fn_error $? "can't find usable google perftools installation" "$LINENO" 5
+    fi
+
+    ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+    for ac_google_perflibdir in $ac_google_perflibdirs; do
+
+	LDFLAGS="$ac_save_LDFLAGS -L$ac_google_perflibdir"
+        LIBS="$ac_save_LIBS -lprofiler"
+
+        { $as_echo "$as_me:${as_lineno-$LINENO}: checking for google perftolos library libprofiler in $ac_google_perflibdir" >&5
+$as_echo_n "checking for google perftolos library libprofiler in $ac_google_perflibdir... " >&6; }
+	cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+                #include <google/profiler.h>
+
+int
+main ()
+{
+
+		ProfilerStart("test");
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+
+              { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+              oasys_cv_path_google_perf_lib=$ac_google_perflibdir
+              break
+
+else
+
+              { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+    done
+
+    CPPFLAGS="$ac_save_CPPFLAGS"
+    LDFLAGS="$ac_save_LDFLAGS"
+    LIBS="$ac_save_LIBS"
+
+    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$oasys_cv_path_google_perf_lib = x ; then
+        as_fn_error $? "can't find usable google perftools library" "$LINENO" 5
+    fi
+
+    fi
+
+    if test ! $oasys_cv_path_google_perf_h = /usr/include ; then
+        GOOGLE_PERFTOOLS_CFLAGS="-I$oasys_cv_path_google_perf_h"
+    fi
+
+    if test ! $oasys_cv_path_google_perf_lib = /usr/lib ; then
+        GOOGLE_PERFTOOLS_LDFLAGS="-L$oasys_cv_path_google_perf_lib"
+    fi
+
+    GOOGLE_PERFTOOL_LDFLAGS="$GOOGLE_PERFTOOLS_LDFLAGS -Wl,-Bstatic -lprofiler -Wl,-Bdynamic"
+
+    fi # GOOGLE_PERF_ENABLED
+
+
+
+    ax_python_use=false
+     if test x"$ax_python_use" = x"true"; then
+  PYTHON_USE_TRUE=
+  PYTHON_USE_FALSE='#'
+else
+  PYTHON_USE_TRUE='#'
+  PYTHON_USE_FALSE=
+fi
+
+
+
+
+
+    # unless PYTHON was supplied to us (as a precious variable),
+    # see if --with-python[=PythonExecutablePath], --with-python,
+    # --without-python or --with-python=no was given.
+    if test -z "$PYTHON"
+    then
+        { $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-python" >&5
+$as_echo_n "checking for --with-python... " >&6; }
+# [=[embed,]PYTHON]
+
+# Check whether --with-python was given.
+if test "${with_python+set}" = set; then :
+  withval=$with_python;
+else
+  withval="yes"
+
+fi
+
+        si_try_embed="no"
+        py_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+        for elt in $withval; do
+          IFS="$py_save_ifs"
+          case $elt in
+            embed|embedding)
+              si_try_embed="yes"
+            ;;
+            static|dynamic|shared|module)
+            ;;
+            *)
+            si_withval=$elt
+          esac
+        done
+        IFS="$py_save_ifs"
+        if test x"$si_withval" = x""
+        then
+           withval="yes"
+        else
+	   withval="$si_withval"
+        fi
+
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: $withval" >&5
+$as_echo "$withval" >&6; }
+        if test "$withval" = "no"
+        then
+            ax_python_use=false
+        else
+            if test "$withval" = "yes"
+            then
+                # "yes" was specified, but we don't have a path
+                # for the executable.
+                # So, let's search the PATH Environment Variable.
+                for ac_prog in python2.7 python2.6 python2.5 python2.4 python2.3 python2.2 python2.1 python2 python
+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 ${ac_cv_path_PYTHON+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $PYTHON in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_PYTHON="$PYTHON" # 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_PYTHON="$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
+
+  ;;
+esac
+fi
+PYTHON=$ac_cv_path_PYTHON
+if test -n "$PYTHON"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYTHON" >&5
+$as_echo "$PYTHON" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$PYTHON" && break
+done
+
+            else
+                # $withval must be the executable path then.
+                PYTHON="${withval}"
+
+            fi
+            if test -z "$PYTHON"
+            then
+                { $as_echo "$as_me:${as_lineno-$LINENO}: result: no path to python found, skipping python interface!" >&5
+$as_echo "no path to python found, skipping python interface!" >&6; }
+            else
+
+
+    if test -n "$PYTHON"
+    then
+        { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $PYTHON version >= 2.4" >&5
+$as_echo_n "checking whether $PYTHON version >= 2.4... " >&6; }
+
+
+    if test -z "$PYTHON"
+    then
+        as_fn_error $? "Python Executable not found" "$LINENO" 5
+    else
+        cat >conftest.py <<_ACEOF
+
+import sys, string
+# split strings by '.' and convert to numeric.  Append some zeros
+# because we need at least 4 digits for the hex conversion.
+minver = map(int, string.split('2.4', '.')) + [0, 0, 0]
+minverhex = 0
+for i in xrange(0, 4): minverhex = (minverhex << 8) + minver[i]
+if sys.hexversion >= minverhex:
+    sys.exit( 0 )
+else:
+    sys.exit( 1 )
+
+_ACEOF
+        ax_python_output=`$PYTHON conftest.py`
+        ax_python_cc=$?
+        rm conftest.py
+        if test -f "conftest.pyc"
+        then
+            rm conftest.pyc
+        fi
+    fi
+
+        if test $ax_python_cc -eq 0
+        then
+             { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+
+    if test -n "$PYTHON"
+    then
+        { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $PYTHON version >= 3" >&5
+$as_echo_n "checking whether $PYTHON version >= 3... " >&6; }
+
+
+    if test -z "$PYTHON"
+    then
+        as_fn_error $? "Python Executable not found" "$LINENO" 5
+    else
+        cat >conftest.py <<_ACEOF
+
+import sys, string
+# split strings by '.' and convert to numeric.  Append some zeros
+# because we need at least 4 digits for the hex conversion.
+minver = map(int, string.split('3', '.')) + [0, 0, 0]
+minverhex = 0
+for i in xrange(0, 4): minverhex = (minverhex << 8) + minver[i]
+if sys.hexversion >= minverhex:
+    sys.exit( 0 )
+else:
+    sys.exit( 1 )
+
+_ACEOF
+        ax_python_output=`$PYTHON conftest.py`
+        ax_python_cc=$?
+        rm conftest.py
+        if test -f "conftest.pyc"
+        then
+            rm conftest.pyc
+        fi
+    fi
+
+        if test $ax_python_cc -eq 0
+        then
+             ax_python_use=false
+                      { $as_echo "$as_me:${as_lineno-$LINENO}: result: too recent, skipping python interface!" >&5
+$as_echo "too recent, skipping python interface!" >&6; }
+
+        else  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no (ok)" >&5
+$as_echo "no (ok)" >&6; }
+                      ax_python_version=`$PYTHON -c "import sys; print '.'.join(sys.version.split('.')[:2])"`
+                      as_ac_Lib=`$as_echo "ac_cv_lib_python${ax_python_version}''_main" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lpython${ax_python_version}" >&5
+$as_echo_n "checking for main in -lpython${ax_python_version}... " >&6; }
+if eval \${$as_ac_Lib+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lpython${ax_python_version}  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+return main ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "$as_ac_Lib=yes"
+else
+  eval "$as_ac_Lib=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+eval ac_res=\$$as_ac_Lib
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+
+                          ax_python_use=true
+                          si_embed_python=$si_try_embed
+                          { $as_echo "$as_me:${as_lineno-$LINENO}: checking embedding python interface module" >&5
+$as_echo_n "checking embedding python interface module... " >&6; }
+                          { $as_echo "$as_me:${as_lineno-$LINENO}: result: $si_try_embed" >&5
+$as_echo "$si_try_embed" >&6; }
+
+    if test -z "$PYTHON"
+    then
+        as_fn_error $? "Python Executable Path is not known" "$LINENO" 5
+    fi
+    ax_python_prefix=`${PYTHON} -c "import sys; print sys.prefix"`
+    ax_python_execprefix=`${PYTHON} -c "import sys; print sys.exec_prefix"`
+    PYTHON_PREFIX="${ax_python_prefix}"
+
+    PYTHON_EXECPREFIX="${ax_python_execprefix}"
+
+
+
+
+
+    if test -n "$PYTHON"
+    then
+
+
+
+    if test -z "$PYTHON"
+    then
+        as_fn_error $? "Python Executable not found" "$LINENO" 5
+    else
+        cat >conftest.py <<_ACEOF
+
+import sys
+import distutils.sysconfig
+strUseFrameWork = "--enable-framework"
+dictConfig = distutils.sysconfig.get_config_vars( )
+strConfigArgs = dictConfig.get("CONFIG_ARGS")
+strLinkSpec =  dictConfig.get('LDFLAGS')
+if -1 ==  strConfigArgs.find(strUseFrameWork):
+    strLibPL = dictConfig.get("LIBPL")
+    if strLibPL and (strLibPL != ""):
+        strLinkSpec += " -L%s" % (strLibPL)
+    strSys = dictConfig.get("SYSLIBS")
+    if strSys and (strSys != ""):
+        strLinkSpec += " %s" % (strSys)
+    strSHL = dictConfig.get("SHLIBS")
+    if strSHL and (strSHL != ""):
+        strLinkSpec += " %s" % (strSHL)
+    # Construct the Python Library Name.
+    strTmplte = " -lpython%d.%d"
+    if (sys.platform == "win32") or (sys.platform == "os2emx"):
+        strTmplte = " -lpython%d%d"
+    strWrk = strTmplte % ( (sys.hexversion >> 24),
+                            ((sys.hexversion >> 16) & 0xff))
+    strLinkSpec += strWrk
+else:
+    # This is not ideal since it changes the search path
+    # for Frameworks which could have side-effects on
+    # other included Frameworks.  However, it is necessary
+    # where someone has installed more than one frameworked
+    # Python.  Frameworks are really only used in Mac OS X.
+    strLibFW = dictConfig.get("PYTHONFRAMEWORKPREFIX")
+    if strLibFW and (strLibFW != ""):
+        strLinkSpec += " -F%s" % (strLibFW)
+strLinkSpec += " %s" % (dictConfig.get('LINKFORSHARED'))
+print strLinkSpec
+
+_ACEOF
+        ax_python_output=`$PYTHON conftest.py`
+        ax_python_cc=$?
+        rm conftest.py
+        if test -f "conftest.pyc"
+        then
+            rm conftest.pyc
+        fi
+    fi
+
+
+#        AC_SUBST([PYTHON_LSPEC], [${ax_python_output}])
+#        AC_MSG_NOTICE([PYTHON_LSPEC=${ax_python_output}])
+
+        ax_python_lspec=`${PYTHON}-config --ldflags`
+        PYTHON_LSPEC=${ax_python_lspec}
+
+        { $as_echo "$as_me:${as_lineno-$LINENO}: PYTHON_LSPEC=${ax_python_lspec}" >&5
+$as_echo "$as_me: PYTHON_LSPEC=${ax_python_lspec}" >&6;}
+
+    fi
+
+
+
+    if test -n "$PYTHON"
+    then
+        ax_python_prefix=`${PYTHON}-config --prefix`
+        if test -z "$ax_python_prefix"
+        then
+            as_fn_error $? "Python Prefix is not known" "$LINENO" 5
+        fi
+#        ax_python_execprefix=`${PYTHON}-config --exec-prefix`
+#        ax_python_version=`$PYTHON -c "import sys; print sys.version[[:3]]"`
+#        ax_python_includespec="-I${ax_python_prefix}/include/python${ax_python_version}"
+#        if test x"$python_prefix" != x"$python_execprefix"; then
+#            ax_python_execspec="-I${ax_python_execprefix}/include/python${ax_python_version}"
+#            ax_python_includespec="${ax_python_includespec} $ax_python_execspec"
+#        fi
+        ax_python_cspec=`${PYTHON}-config --cflags | sed -e 's@ -mno-fused-madd @ @g'`
+        #   or -Qunused-arguments / clang :(
+#        ax_python_cspec="${ax_python_ccshared} ${ax_python_includespec}"
+        PYTHON_CSPEC=${ax_python_cspec}
+
+        { $as_echo "$as_me:${as_lineno-$LINENO}: PYTHON_CSPEC=${ax_python_cspec}" >&5
+$as_echo "$as_me: PYTHON_CSPEC=${ax_python_cspec}" >&6;}
+    fi
+
+
+else
+   ax_python_use=false
+                          { $as_echo "$as_me:${as_lineno-$LINENO}: result: Cannot link to python, skipping python interface!" >&5
+$as_echo "Cannot link to python, skipping python interface!" >&6; }
+
+
+fi
+
+
+
+
+        fi
+    fi
+
+
+        else  ax_python_use=false
+                    { $as_echo "$as_me:${as_lineno-$LINENO}: result: too old, skipping python interface!" >&5
+$as_echo "too old, skipping python interface!" >&6; }
+
+
+
+        fi
+    fi
+
+            fi
+        fi
+
+        if  test x"$si_embed_python" = x"yes"
+        then
+
+$as_echo "#define EMBED_PYTHON 1" >>confdefs.h
+
+#          AC_SUBST(EMBED_PYOBJECT_CFLAGS,"\${PYTHON_CSPEC}")
+#          AC_SUBST(EMBED_PYOBJECT_LDFLAGS,"\${PYTHON_LSPEC}")
+        fi
+	if test x"$ax_python_use" = x"true"
+	then
+
+$as_echo "#define HAVE_PYTHON 1" >>confdefs.h
+
+        fi
+    fi
+
+     if test x"$ax_python_use" = x"true"; then
+  PYTHON_USE_TRUE=
+  PYTHON_USE_FALSE='#'
+else
+  PYTHON_USE_TRUE='#'
+  PYTHON_USE_FALSE=
+fi
+
+     if test x"$ax_python_use$si_embed_python" = x"trueyes"; then
+  SI_EMBED_PYTHON_TRUE=
+  SI_EMBED_PYTHON_FALSE='#'
+else
+  SI_EMBED_PYTHON_TRUE='#'
+  SI_EMBED_PYTHON_FALSE=
+fi
+
+     if test x"$ax_python_use" = x"true" -a x"$si_embed_python" != x"yes" ; then
+  PYTHON_MODULE_TRUE=
+  PYTHON_MODULE_FALSE='#'
+else
+  PYTHON_MODULE_TRUE='#'
+  PYTHON_MODULE_FALSE=
+fi
+
+
+
+
+
+
+#
+
+# Check whether --with-mathicgb was given.
+if test "${with_mathicgb+set}" = set; then :
+  withval=$with_mathicgb;
+else
+  with_mathicgb="no"
+
+fi
+
+ #
+ # MathicGB
+   if test "x$with_mathicgb" = xyes; then :
+
+  ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libmemtailorIsPresent in -lmemtailor" >&5
+$as_echo_n "checking for libmemtailorIsPresent in -lmemtailor... " >&6; }
+if ${ac_cv_lib_memtailor_libmemtailorIsPresent+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lmemtailor  $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 libmemtailorIsPresent ();
+int
+main ()
+{
+return libmemtailorIsPresent ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+  ac_cv_lib_memtailor_libmemtailorIsPresent=yes
+else
+  ac_cv_lib_memtailor_libmemtailorIsPresent=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_memtailor_libmemtailorIsPresent" >&5
+$as_echo "$ac_cv_lib_memtailor_libmemtailorIsPresent" >&6; }
+if test "x$ac_cv_lib_memtailor_libmemtailorIsPresent" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBMEMTAILOR 1
+_ACEOF
+
+  LIBS="-lmemtailor $LIBS"
+
+else
+  as_fn_error $? "Cannot find libmemtailor, which is required for MathicGB." "$LINENO" 5
+fi
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libmathicIsPresent in -lmathic" >&5
+$as_echo_n "checking for libmathicIsPresent in -lmathic... " >&6; }
+if ${ac_cv_lib_mathic_libmathicIsPresent+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lmathic  $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 libmathicIsPresent ();
+int
+main ()
+{
+return libmathicIsPresent ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+  ac_cv_lib_mathic_libmathicIsPresent=yes
+else
+  ac_cv_lib_mathic_libmathicIsPresent=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_mathic_libmathicIsPresent" >&5
+$as_echo "$ac_cv_lib_mathic_libmathicIsPresent" >&6; }
+if test "x$ac_cv_lib_mathic_libmathicIsPresent" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBMATHIC 1
+_ACEOF
+
+  LIBS="-lmathic $LIBS"
+
+else
+  as_fn_error $? "Cannot find libmathic, which is required for MathicGB." "$LINENO" 5
+fi
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libmathicgbIsPresent in -lmathicgb" >&5
+$as_echo_n "checking for libmathicgbIsPresent in -lmathicgb... " >&6; }
+if ${ac_cv_lib_mathicgb_libmathicgbIsPresent+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lmathicgb  $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 libmathicgbIsPresent ();
+int
+main ()
+{
+return libmathicgbIsPresent ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+  ac_cv_lib_mathicgb_libmathicgbIsPresent=yes
+else
+  ac_cv_lib_mathicgb_libmathicgbIsPresent=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_mathicgb_libmathicgbIsPresent" >&5
+$as_echo "$ac_cv_lib_mathicgb_libmathicgbIsPresent" >&6; }
+if test "x$ac_cv_lib_mathicgb_libmathicgbIsPresent" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBMATHICGB 1
+_ACEOF
+
+  LIBS="-lmathicgb $LIBS"
+
+else
+  as_fn_error $? "Cannot find the MathicGB library." "$LINENO" 5
+fi
+
+  ac_fn_cxx_check_header_mongrel "$LINENO" "mathicgb.h" "ac_cv_header_mathicgb_h" "$ac_includes_default"
+if test "x$ac_cv_header_mathicgb_h" = xyes; 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
+
+
+$as_echo "#define HAVE_MATHICGB 1" >>confdefs.h
+
+#  AC_SUBST(HAVE_MATHICGB_VALUE, 1)
+
+fi
+ #
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for error_at_line" >&5
+$as_echo_n "checking for error_at_line... " >&6; }
+if ${ac_cv_lib_error_at_line+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <error.h>
+int
+main ()
+{
+error_at_line (0, 0, "", 0, "an error occurred");
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_error_at_line=yes
+else
+  ac_cv_lib_error_at_line=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_error_at_line" >&5
+$as_echo "$ac_cv_lib_error_at_line" >&6; }
+if test $ac_cv_lib_error_at_line = no; then
+  case " $LIBOBJS " in
+  *" error.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS error.$ac_objext"
+ ;;
+esac
+
+fi
+
+for ac_header in stdlib.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "stdlib.h" "ac_cv_header_stdlib_h" "$ac_includes_default"
+if test "x$ac_cv_header_stdlib_h" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_STDLIB_H 1
+_ACEOF
+
+fi
+
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU libc compatible malloc" >&5
+$as_echo_n "checking for GNU libc compatible malloc... " >&6; }
+if ${ac_cv_func_malloc_0_nonnull+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test "$cross_compiling" = yes; then :
+  ac_cv_func_malloc_0_nonnull=no
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#if defined STDC_HEADERS || defined HAVE_STDLIB_H
+# include <stdlib.h>
+#else
+char *malloc ();
+#endif
+
+int
+main ()
+{
+return ! malloc (0);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  ac_cv_func_malloc_0_nonnull=yes
+else
+  ac_cv_func_malloc_0_nonnull=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
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_malloc_0_nonnull" >&5
+$as_echo "$ac_cv_func_malloc_0_nonnull" >&6; }
+if test $ac_cv_func_malloc_0_nonnull = yes; then :
+
+$as_echo "#define HAVE_MALLOC 1" >>confdefs.h
+
+else
+  $as_echo "#define HAVE_MALLOC 0" >>confdefs.h
+
+   case " $LIBOBJS " in
+  *" malloc.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS malloc.$ac_objext"
+ ;;
+esac
+
+
+$as_echo "#define malloc rpl_malloc" >>confdefs.h
+
+fi
+
+
+
+# check for cpu properties
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long" >&5
+$as_echo_n "checking size of long... " >&6; }
+if ${ac_cv_sizeof_long+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long))" "ac_cv_sizeof_long"        "$ac_includes_default"; then :
+
+else
+  if test "$ac_cv_type_long" = yes; then
+     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (long)
+See \`config.log' for more details" "$LINENO" 5; }
+   else
+     ac_cv_sizeof_long=0
+   fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long" >&5
+$as_echo "$ac_cv_sizeof_long" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_LONG $ac_cv_sizeof_long
+_ACEOF
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking CPU for singular" >&5
+$as_echo_n "checking CPU for singular... " >&6; }
+
+# CPUUNAME and PATH
+ac_cv_singcpuname=`uname -m`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_singcpuname" >&5
+$as_echo "$ac_cv_singcpuname" >&6; }
+
+if test "$ac_cv_singcpuname" = i386; then
+
+$as_echo "#define SI_CPU_I386 1" >>confdefs.h
+
+
+fi
+if test "$ac_cv_singcpuname" = i686; then
+
+$as_echo "#define SI_CPU_I386 1" >>confdefs.h
+
+
+fi
+if test "$ac_cv_singcpuname" = x86_64; then
+
+$as_echo "#define SI_CPU_X86_64 1" >>confdefs.h
+
+
+fi
+if test "$ac_cv_singcpuname" = ia64; then
+
+$as_echo "#define SI_CPU_IA64 1" >>confdefs.h
+
+
+fi
+if test "$ac_cv_singcpuname" = sparc; then
+
+$as_echo "#define SI_CPU_SPARC 1" >>confdefs.h
+
+
+fi
+if test "$ac_cv_singcpuname" = ppc; then
+
+$as_echo "#define SI_CPU_PPC 1" >>confdefs.h
+
+
+fi
+
+# UNAME and PATH
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking uname for Singular" >&5
+$as_echo_n "checking uname for Singular... " >&6; }
+
+#ac_cv_singuname=`./config.guess`
+ac_cv_singuname=`uname -m`-`uname -s`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_singuname" >&5
+$as_echo "$ac_cv_singuname" >&6; }
+
+cat >>confdefs.h <<_ACEOF
+#define S_UNAME "$ac_cv_singuname"
+_ACEOF
+
+
+
+case $host_cpu in #(
+    i*86*|x86_64*) :
+
+$as_echo "#define HAVE_MULT_MOD 1" >>confdefs.h
+ ;; #(
+    ia64*) :
+
+$as_echo "#define HAVE_GENERIC_ADD 1" >>confdefs.h
+ ;; #(
+    sparc*) :
+
+
+$as_echo "#define HAVE_MULT_MOD 1" >>confdefs.h
+
+
+$as_echo "#define HAVE_DIV_MOD 1" >>confdefs.h
+
+	     ;; #(
+    powerpc*|ppc*) :
+
+$as_echo "#define HAVE_MULT_MOD 1" >>confdefs.h
+ ;; #(
+  *) :
+
+ ;;
+esac
+
+
+
+#check for host:
+
+
+case $host_os in
+  *cygwin* )
+
+for flag in -Wl,-Bdynamic; do
+  as_CACHEVAR=`$as_echo "ax_cv_check_ldflags__$flag" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the linker accepts $flag" >&5
+$as_echo_n "checking whether the linker accepts $flag... " >&6; }
+if eval \${$as_CACHEVAR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$LDFLAGS
+  LDFLAGS="$LDFLAGS  $flag"
+  _save_cflags="$CFLAGS"
+  CFLAGS="$CFLAGS -Werror"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "$as_CACHEVAR=yes"
+else
+  eval "$as_CACHEVAR=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+  CFLAGS="$_save_cflags"
+  LDFLAGS=$ax_check_save_flags
+fi
+eval ac_res=\$$as_CACHEVAR
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if test x"`eval 'as_val=${'$as_CACHEVAR'};$as_echo "$as_val"'`" = xyes; then :
+  if ${LDFLAGS+:} false; then :
+  case " $LDFLAGS " in
+    *" $flag "*)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : LDFLAGS already contains \$flag"; } >&5
+  (: LDFLAGS already contains $flag) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      ;;
+    *)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : LDFLAGS=\"\$LDFLAGS \$flag\""; } >&5
+  (: LDFLAGS="$LDFLAGS $flag") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      LDFLAGS="$LDFLAGS $flag"
+      ;;
+   esac
+else
+  LDFLAGS="$flag"
+fi
+
+else
+  :
+fi
+
+done
+;;
+esac
+
+PKG_REQUIRE="$PKG_REQUIRE"
+
+
+
+ # Check whether --enable-omalloc was given.
+if test "${enable_omalloc+set}" = set; then :
+  enableval=$enable_omalloc; if test "x$enableval"  = "xyes"; then
+    ENABLE_OMALLOC=yes
+   fi
+else
+  ENABLE_OMALLOC=add
+fi
+
+
+ ENABLE_OMALLOC_ARG=""
+
+ if test "x$ENABLE_OMALLOC" = xadd; then
+   ENABLE_OMALLOC=yes
+   ENABLE_OMALLOC_ARG="--enable-omalloc $ENABLE_OMALLOC_ARG"
+ fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use omalloc in factory and co." >&5
+$as_echo_n "checking whether to use omalloc in factory and co.... " >&6; }
+
+ if test "x$ENABLE_OMALLOC" = xyes; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+  OMALLOC_INCLUDES="-I$ac_abs_top_srcdir"
+
+  if test "x$ac_abs_top_srcdir" != "x$ac_abs_top_builddir"; then
+    OMALLOC_INCLUDES="$OMALLOC_INCLUDES -I$ac_abs_top_builddir"
+  fi
+
+  OMALLOC_LIBS="$ac_abs_top_builddir/omalloc/libomalloc.la"
+
+
+
+
+  ENABLE_OMALLOC_ARG="$ENABLE_OMALLOC_ARG OMALLOC_LIBS='$OMALLOC_LIBS' OMALLOC_INCLUDES='$OMALLOC_INCLUDES'"
+  ac_configure_args="$ac_configure_args $ENABLE_OMALLOC_ARG"
+
+  PKG_REQUIRE="$PKG_REQUIRE omalloc"
+
+ else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ fi
+
+
+  if test "x$ENABLE_OMALLOC" = xyes; then
+  ENABLE_OMALLOC_TRUE=
+  ENABLE_OMALLOC_FALSE='#'
+else
+  ENABLE_OMALLOC_TRUE='#'
+  ENABLE_OMALLOC_FALSE=
+fi
+
+
+
+ # Check whether --enable-resources was given.
+if test "${enable_resources+set}" = set; then :
+  enableval=$enable_resources; if test "x$enableval"  = "xyes"; then
+    ENABLE_RESOURCES=yes
+   fi
+else
+  ENABLE_RESOURCES=yes
+fi
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use libresources in factory and co." >&5
+$as_echo_n "checking whether to use libresources in factory and co.... " >&6; }
+ if test "x$ENABLE_RESOURCES" = xyes; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+  RESOURCES_INCLUDES="-I$ac_abs_top_srcdir "
+
+  RESOURCES_LIBS="$ac_abs_top_builddir/resources/libresources.la"
+
+
+
+
+  ENABLE_ARG="--with-Singular RESOURCES_LIBS='$RESOURCES_LIBS' RESOURCES_INCLUDES='$RESOURCES_INCLUDES'"
+
+  ac_configure_args="$ac_configure_args $ENABLE_ARG"
+
+  PKG_REQUIRE="$PKG_REQUIRE resources"
+
+ else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ fi
+
+  if test "x$ENABLE_RESOURCES" = xyes; then
+  ENABLE_RESOURCES_TRUE=
+  ENABLE_RESOURCES_FALSE='#'
+else
+  ENABLE_RESOURCES_TRUE='#'
+  ENABLE_RESOURCES_FALSE=
+fi
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether factory should be enabled" >&5
+$as_echo_n "checking whether factory should be enabled... " >&6; }
+
+ # Check whether --enable-factory was given.
+if test "${enable_factory+set}" = set; then :
+  enableval=$enable_factory; if test $enableval = yes; then
+     ENABLE_FACTORY="yes"
+  else
+     ENABLE_FACTORY="no"
+  fi
+else
+  ENABLE_FACTORY="yes"
+fi
+
+
+ if test x$ENABLE_FACTORY = xyes; then
+
+  FACTORY_INCLUDES="-I$ac_abs_top_srcdir -I$ac_abs_top_srcdir/factory/include"
+  if test "x$ac_abs_top_srcdir" != "x$ac_abs_top_builddir"; then
+    FACTORY_INCLUDES="$FACTORY_INCLUDES -I$ac_abs_top_builddir -I$ac_abs_top_builddir/factory/include"
+  fi
+
+  FACTORY_LIBS="$ac_abs_top_builddir/factory/libfactory.la"
+
+
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking   FACTORY_INCLUDES?.." >&5
+$as_echo_n "checking   FACTORY_INCLUDES?..... " >&6; }
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${FACTORY_INCLUDES:-unset}" >&5
+$as_echo "${FACTORY_INCLUDES:-unset}" >&6; }
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking   FACTORY_LIBS?.." >&5
+$as_echo_n "checking   FACTORY_LIBS?..... " >&6; }
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${FACTORY_LIBS:-unset}" >&5
+$as_echo "${FACTORY_LIBS:-unset}" >&6; }
+
+
+$as_echo "#define HAVE_FACTORY 1" >>confdefs.h
+
+
+  ENABLE_ARG="FACTORY_LIBS='$FACTORY_LIBS' FACTORY_INCLUDES='$FACTORY_INCLUDES'"
+
+  ac_configure_args="$ac_configure_args $ENABLE_ARG"
+
+  PKG_REQUIRE="$PKG_REQUIRE factory"
+
+ fi
+
+
+  if test x$ENABLE_FACTORY = xyes; then
+  ENABLE_FACTORY_TRUE=
+  ENABLE_FACTORY_FALSE='#'
+else
+  ENABLE_FACTORY_TRUE='#'
+  ENABLE_FACTORY_FALSE=
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ENABLE_FACTORY" >&5
+$as_echo "$ENABLE_FACTORY" >&6; }
+
+
+
+
+USEPPROCSDYNAMICLDFLAGS=""
+USEPPROCSDYNAMICLD=""
+
+# Check whether --enable-p-procs-static was given.
+if test "${enable_p_procs_static+set}" = set; then :
+  enableval=$enable_p_procs_static; if test $enableval = yes; then
+     ENABLE_P_PROCS_STATIC="yes"
+     ENABLE_P_PROCS_DYNAMIC="no"
+ else
+     ENABLE_P_PROCS_STATIC="no"
+ fi
+
+else
+  NO_P_PROCS_STATIC_GIVEN=yes
+fi
+
+
+# Check whether --enable-p-procs-dynamic was given.
+if test "${enable_p_procs_dynamic+set}" = set; then :
+  enableval=$enable_p_procs_dynamic; if test $enableval = yes; then
+     ENABLE_P_PROCS_DYNAMIC="yes"
+     ENABLE_P_PROCS_STATIC="no"
+ else
+     ENABLE_P_PROCS_DYNAMIC="no"
+ fi
+
+else
+  NO_P_PROCS_DYNAMIC_GIVEN=yes
+fi
+
+
+if test x$ENABLE_P_PROCS_DYNAMIC = xyes; then
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether system supports dynamic modules" >&5
+$as_echo_n "checking whether system supports dynamic modules... " >&6; }
+case $host in #(
+  *linux*) :
+    SUPPORTS_DYNAMIC_MODULES=yes ;; #(
+  *freebsd*) :
+    SUPPORTS_DYNAMIC_MODULES=yes ;; #(
+  *-sun-solaris2*) :
+    SUPPORTS_DYNAMIC_MODULES=yes ;; #(
+  *-apple-darwin*) :
+    SUPPORTS_DYNAMIC_MODULES=yes ;; #(
+  *) :
+    SUPPORTS_DYNAMIC_MODULES=no
+ ;;
+esac
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $SUPPORTS_DYNAMIC_MODULES" >&5
+$as_echo "$SUPPORTS_DYNAMIC_MODULES" >&6; }
+
+  if test $SUPPORTS_DYNAMIC_MODULES = no; then
+    as_fn_error $? "--enable-pprocs-dynamic requested but your system appears not to support dynamic modules properly" "$LINENO" 5
+  fi
+
+  ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen"
+if test "x$ac_cv_func_dlopen" = xyes; then :
+
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
+$as_echo_n "checking for dlopen in -ldl... " >&6; }
+if ${ac_cv_lib_dl_dlopen+:} false; 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" = xyes; then :
+  USEPPROCSDYNAMICLD="-ldl"
+else
+
+   { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Could not use dlopen" >&5
+$as_echo "$as_me: WARNING: Could not use dlopen" >&2;}
+
+fi
+
+fi
+
+
+elif test x$NO_P_PROCS_DYNAMIC_GIVEN = xyes -a x$NO_P_PROCS_STATIC_GIVEN = xyes; then
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether system supports dynamic modules" >&5
+$as_echo_n "checking whether system supports dynamic modules... " >&6; }
+case $host in #(
+  *linux*) :
+    SUPPORTS_DYNAMIC_MODULES=yes ;; #(
+  *freebsd*) :
+    SUPPORTS_DYNAMIC_MODULES=yes ;; #(
+  *-sun-solaris2*) :
+    SUPPORTS_DYNAMIC_MODULES=yes ;; #(
+  *-apple-darwin*) :
+    SUPPORTS_DYNAMIC_MODULES=yes ;; #(
+  *) :
+    SUPPORTS_DYNAMIC_MODULES=no
+ ;;
+esac
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $SUPPORTS_DYNAMIC_MODULES" >&5
+$as_echo "$SUPPORTS_DYNAMIC_MODULES" >&6; }
+
+  if test $SUPPORTS_DYNAMIC_MODULES = yes; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: Enabling dynamic modules and disabling static modules" >&5
+$as_echo "$as_me: Enabling dynamic modules and disabling static modules" >&6;}
+    ENABLE_P_PROCS_DYNAMIC="yes"
+    ENABLE_P_PROCS_STATIC="no"
+    USEPPROCSDYNAMICLDFLAGS=""
+    ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen"
+if test "x$ac_cv_func_dlopen" = xyes; then :
+
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
+$as_echo_n "checking for dlopen in -ldl... " >&6; }
+if ${ac_cv_lib_dl_dlopen+:} false; 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" = xyes; then :
+  USEPPROCSDYNAMICLD="-ldl"
+else
+
+      { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Could not use dlopen" >&5
+$as_echo "$as_me: WARNING: Could not use dlopen" >&2;}
+
+fi
+
+fi
+
+  elif test $SUPPORTS_DYNAMIC_MODULES = no; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: Enabling static modules and disabling dynamic modules" >&5
+$as_echo "$as_me: Enabling static modules and disabling dynamic modules" >&6;}
+    ENABLE_P_PROCS_DYNAMIC="no"
+    ENABLE_P_PROCS_STATIC="yes"
+  else
+    as_fn_error $? "Unknown whether system supports dynamic modules or not. This should not have happened." "$LINENO" 5
+  fi
+fi
+
+if test x$ENABLE_P_PROCS_DYNAMIC = xyes; then
+
+$as_echo "#define HAVE_DL 1" >>confdefs.h
+
+
+$as_echo "#define HAVE_DYNAMIC_LOADING 1" >>confdefs.h
+
+
+
+
+for flag in -rdynamic -flat_namespace -Wl,-bind_at_load -Wl,-undefined,dynamic_lookup; do
+  as_CACHEVAR=`$as_echo "ax_cv_check_ldflags__$flag" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the linker accepts $flag" >&5
+$as_echo_n "checking whether the linker accepts $flag... " >&6; }
+if eval \${$as_CACHEVAR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$LDFLAGS
+  LDFLAGS="$LDFLAGS  $flag"
+  _save_cflags="$CFLAGS"
+  CFLAGS="$CFLAGS -Werror"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "$as_CACHEVAR=yes"
+else
+  eval "$as_CACHEVAR=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+  CFLAGS="$_save_cflags"
+  LDFLAGS=$ax_check_save_flags
+fi
+eval ac_res=\$$as_CACHEVAR
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if test x"`eval 'as_val=${'$as_CACHEVAR'};$as_echo "$as_val"'`" = xyes; then :
+  if ${LDFLAGS+:} false; then :
+  case " $LDFLAGS " in
+    *" $flag "*)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : LDFLAGS already contains \$flag"; } >&5
+  (: LDFLAGS already contains $flag) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      ;;
+    *)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : LDFLAGS=\"\$LDFLAGS \$flag\""; } >&5
+  (: LDFLAGS="$LDFLAGS $flag") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      LDFLAGS="$LDFLAGS $flag"
+      ;;
+   esac
+else
+  LDFLAGS="$flag"
+fi
+
+else
+  :
+fi
+
+done
+
+fi
+
+
+
+
+ if test x$ENABLE_P_PROCS_DYNAMIC = xyes; then
+  ENABLE_P_PROCS_DYNAMIC_TRUE=
+  ENABLE_P_PROCS_DYNAMIC_FALSE='#'
+else
+  ENABLE_P_PROCS_DYNAMIC_TRUE='#'
+  ENABLE_P_PROCS_DYNAMIC_FALSE=
+fi
+
+ if test x$ENABLE_P_PROCS_STATIC = xyes; then
+  ENABLE_P_PROCS_STATIC_TRUE=
+  ENABLE_P_PROCS_STATIC_FALSE='#'
+else
+  ENABLE_P_PROCS_STATIC_TRUE='#'
+  ENABLE_P_PROCS_STATIC_FALSE=
+fi
+
+
+
+
+## DEFAULT_CHECKING_PATH="/usr /usr/local /sw /opt/local"
+
+#AC_ARG_WITH([readline],
+#  [AS_HELP_STRING([--without-readline],
+#    [disable support for readline])],
+#  [],
+#  [with_readline=yes])
+
+
+for ac_header in sys/file.h sys/ioctl.h sys/time.h sys/times.h sys/types.h \
+ sys/stat.h fcntl.h sys/param.h pwd.h asm/sigcontext.h pwd.h termcap.h \
+ termios.h term.h readline/readline.h
+do :
+  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+
+# Check whether --with-readline was given.
+if test "${with_readline+set}" = set; then :
+  withval=$with_readline;
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for tgetent in -lncurses" >&5
+$as_echo_n "checking for tgetent in -lncurses... " >&6; }
+if ${ac_cv_lib_ncurses_tgetent+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lncurses  $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 tgetent ();
+int
+main ()
+{
+return tgetent ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_ncurses_tgetent=yes
+else
+  ac_cv_lib_ncurses_tgetent=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_ncurses_tgetent" >&5
+$as_echo "$ac_cv_lib_ncurses_tgetent" >&6; }
+if test "x$ac_cv_lib_ncurses_tgetent" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBNCURSES 1
+_ACEOF
+
+  LIBS="-lncurses $LIBS"
+
+else
+  \
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for tgetent in -lcurses" >&5
+$as_echo_n "checking for tgetent in -lcurses... " >&6; }
+if ${ac_cv_lib_curses_tgetent+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcurses  $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 tgetent ();
+int
+main ()
+{
+return tgetent ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_curses_tgetent=yes
+else
+  ac_cv_lib_curses_tgetent=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_curses_tgetent" >&5
+$as_echo "$ac_cv_lib_curses_tgetent" >&6; }
+if test "x$ac_cv_lib_curses_tgetent" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBCURSES 1
+_ACEOF
+
+  LIBS="-lcurses $LIBS"
+
+else
+  \
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for tgetent in -ltermcap" >&5
+$as_echo_n "checking for tgetent in -ltermcap... " >&6; }
+if ${ac_cv_lib_termcap_tgetent+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ltermcap  $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 tgetent ();
+int
+main ()
+{
+return tgetent ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_termcap_tgetent=yes
+else
+  ac_cv_lib_termcap_tgetent=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_termcap_tgetent" >&5
+$as_echo "$ac_cv_lib_termcap_tgetent" >&6; }
+if test "x$ac_cv_lib_termcap_tgetent" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBTERMCAP 1
+_ACEOF
+
+  LIBS="-ltermcap $LIBS"
+
+fi
+
+fi
+
+fi
+
+
+# readline
+if test "$with_readline" = dynamic && test "$ac_have_dl" != yes; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: can not build dynamic readline without dynamic linking" >&5
+$as_echo "$as_me: WARNING: can not build dynamic readline without dynamic linking" >&2;}
+  with_readline=static
+fi
+
+
+if test "$with_readline" != dynamic && test "$with_readline" != no; then
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for readline in -lreadline" >&5
+$as_echo_n "checking for readline in -lreadline... " >&6; }
+if ${ac_cv_lib_readline_readline+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lreadline  $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 readline ();
+int
+main ()
+{
+return readline ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+  ac_cv_lib_readline_readline=yes
+else
+  ac_cv_lib_readline_readline=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_readline_readline" >&5
+$as_echo "$ac_cv_lib_readline_readline" >&6; }
+if test "x$ac_cv_lib_readline_readline" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBREADLINE 1
+_ACEOF
+
+  LIBS="-lreadline $LIBS"
+
+fi
+
+   for ac_header in readline/readline.h readline/history.h
+do :
+  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_cxx_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+   if test "$ac_cv_lib_readline_readline" = yes && \
+      test "$ac_cv_header_readline_readline_h" = yes; then
+     { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether readline.h is ok" >&5
+$as_echo_n "checking whether readline.h is ok... " >&6; }
+     if ${ac_cv_header_readline_readline_h_ok+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include<unistd.h>
+#include<stdio.h>
+#include<readline/readline.h>
+#ifdef HAVE_READLINE_HISTORY_H
+#include<readline/history.h>
+#endif
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+  ac_cv_header_readline_readline_h_ok="yes"
+else
+  ac_cv_header_readline_readline_h_ok="no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_readline_readline_h_ok" >&5
+$as_echo "$ac_cv_header_readline_readline_h_ok" >&6; }
+    if test "$ac_cv_header_readline_readline_h_ok" != yes; then
+#not ok -- try once more with explicitly declaring everything
+      { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether or not we nevertheless can use readline" >&5
+$as_echo_n "checking whether or not we nevertheless can use readline... " >&6; }
+      if ${ac_cv_have_readline+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdio.h>
+extern "C"
+{
+extern char * rl_readline_name;
+extern char *rl_line_buffer;
+char *filename_completion_function();
+typedef char **CPPFunction ();
+extern char ** completion_matches ();
+extern CPPFunction * rl_attempted_completion_function;
+extern FILE * rl_outstream;
+char * readline ();
+void add_history ();
+int write_history ();
+int read_history();
+}
+#ifndef NULL
+#define NULL 0
+#endif
+
+int
+main ()
+{
+rl_readline_name=NULL;
+*rl_line_buffer=1;
+completion_matches(NULL, filename_completion_function);
+rl_attempted_completion_function = (CPPFunction *) NULL;
+rl_outstream=NULL;
+readline(NULL);
+add_history(NULL);
+read_history(NULL);
+write_history(NULL);
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+  ac_cv_have_readline="yes"
+
+else
+  ac_cv_have_readline="no"
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_readline" >&5
+$as_echo "$ac_cv_have_readline" >&6; }
+    else
+
+$as_echo "#define READLINE_READLINE_H_OK 1" >>confdefs.h
+
+      ac_cv_have_readline="yes"
+    fi
+  fi
+  if test "$ac_cv_have_readline" = yes; then
+
+$as_echo "#define HAVE_READLINE 1" >>confdefs.h
+
+  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
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking which readline to use" >&5
+$as_echo_n "checking which readline to use... " >&6; }
+if test "$ac_cv_with_readline" = dynamic; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: dynamic" >&5
+$as_echo "dynamic" >&6; }
+
+$as_echo "#define HAVE_DYN_RL 1" >>confdefs.h
+
+elif test "$ac_cv_have_readline" = yes; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: static" >&5
+$as_echo "static" >&6; }
+elif test "$ac_cv_singuname" = PowerMacintosh-darwin; then
+  as_fn_error $? "building without readline impossible on PowerMacintosh-darwin" "$LINENO" 5
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5
+$as_echo "none" >&6; }
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: building without readline: disabling fancy display" >&5
+$as_echo "$as_me: WARNING: building without readline: disabling fancy display" >&2;}
+fi
+
+
+
+
+
+# Check whether --with-dbm was given.
+if test "${with_dbm+set}" = set; then :
+  withval=$with_dbm;
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to have dbm links" >&5
+$as_echo_n "checking whether to have dbm links... " >&6; }
+
+if test "$with_dbm" != no; then
+
+$as_echo "#define HAVE_DBM 1" >>confdefs.h
+
+  { $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
+
+
+
+
+
+# Check whether --enable-gfanlib was given.
+if test "${enable_gfanlib+set}" = set; then :
+  enableval=$enable_gfanlib; ENABLE_GFANLIB="$enableval"
+else
+  ENABLE_GFANLIB=""
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to check for gfanlib" >&5
+$as_echo_n "checking whether to check for gfanlib... " >&6; }
+
+if test "x$ENABLE_GFANLIB" != "xno"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+ for ac_header in setoper.h cdd/setoper.h cddlib/setoper.h
+do :
+  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+ if test "x$ac_cv_header_setoper_h" = xno -a "x$ac_cv_header_cdd_setoper_h" = xno -a "x$ac_cv_header_cddlib_setoper_h" = xno; then
+   { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Note that setoper.h is missing!" >&5
+$as_echo "$as_me: WARNING: Note that setoper.h is missing!" >&2;}
+ fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether libcddgmp is usable" >&5
+$as_echo_n "checking whether libcddgmp is usable... " >&6; }
+
+ BACKUP_LIBS=$LIBS
+
+ LIBS="$LIBS -lcddgmp $GMP_LIBS "
+
+ 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.  */
+
+
+    #define GMPRATIONAL
+     #ifdef HAVE_SETOPER_H
+     # include <setoper.h>
+     # include <cdd.h>
+     #endif
+     #ifdef HAVE_CDD_SETOPER_H
+     # include <cdd/setoper.h>
+     # include <cdd/cdd.h>
+     #endif
+     #ifdef HAVE_CDDLIB_SETOPER_H
+     # include <cddlib/setoper.h>
+     # include <cddlib/cdd.h>
+     #endif
+
+int
+main ()
+{
+dd_set_global_constants(); dd_log=dd_FALSE;
+
+  ;
+  return 0;
+}
+
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  PASSED_ALL_TESTS_FOR_GFANLIB="1" CDDGMPLDFLAGS="-lcddgmp $GMP_LIBS"  CDDGMPCPPFLAGS="-DGMPRATIONAL"
+else
+  PASSED_ALL_TESTS_FOR_GFANLIB="0"
+
+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
+
+
+ LIBS=$BACKUP_LIBS
+
+ if test "x$PASSED_ALL_TESTS_FOR_GFANLIB" = x1; 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 "x$ENABLE_GFANLIB" = "xyes"; then
+   as_fn_error $? "Error, could not use libcddgmp" "$LINENO" 5
+  fi
+ fi
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ PASSED_ALL_TESTS_FOR_GFANLIB="0"
+fi
+
+
+
+ if test "x$PASSED_ALL_TESTS_FOR_GFANLIB" = x1; then
+  HAVE_GFANLIB_TRUE=
+  HAVE_GFANLIB_FALSE='#'
+else
+  HAVE_GFANLIB_TRUE='#'
+  HAVE_GFANLIB_FALSE=
+fi
+
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_GFANLIB ${PASSED_ALL_TESTS_FOR_GFANLIB}
+_ACEOF
+
+
+
+
+
+# Check whether --enable-polymake was given.
+if test "${enable_polymake+set}" = set; then :
+  enableval=$enable_polymake; ENABLE_POLYMAKE="$enableval"
+else
+  ENABLE_POLYMAKE=""
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to check for polymake interface" >&5
+$as_echo_n "checking whether to check for polymake interface... " >&6; }
+
+if test "x$ENABLE_POLYMAKE" != xno; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+
+  if test "x$PASSED_ALL_TESTS_FOR_GFANLIB" != x1; then
+
+   PASSED_ALL_TEST_FOR_POLYMAKE="no";
+
+   if test "x$ENABLE_POLYMAKE" = xyes; then
+    as_fn_error $? "gfanlib was not enabled" "$LINENO" 5
+   else
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: gfanlib was not enabled" >&5
+$as_echo "$as_me: WARNING: gfanlib was not enabled" >&2;}
+   fi
+
+  else
+
+##  AC_MSG_CHECKING(whether polymake is properly installed)
+   # Extract the first word of "polymake-config", so it can be a program name with args.
+set dummy polymake-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 ${ac_cv_prog_PMCONFIG+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$PMCONFIG"; then
+  ac_cv_prog_PMCONFIG="$PMCONFIG" # 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_PMCONFIG="1"
+    $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_PMCONFIG" && ac_cv_prog_PMCONFIG="0"
+fi
+fi
+PMCONFIG=$ac_cv_prog_PMCONFIG
+if test -n "$PMCONFIG"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PMCONFIG" >&5
+$as_echo "$PMCONFIG" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+   if test $PMCONFIG = "1"; then
+##    AC_MSG_CHECKING([whether polymake is up-to-date])
+    SUPPORTEDPOLYMAKEVERSION="212"
+    CURRENTPOLYMAKEVERSION=`polymake-config --version | cut -c -4 -| sed s'/\.//'`
+    if test $CURRENTPOLYMAKEVERSION -ge $SUPPORTEDPOLYMAKEVERSION; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+      PM_INC=`polymake-config --includes`
+      PM_CFLAGS=`polymake-config --cflags`
+      PM_LIBS=`polymake-config --libs`
+      PM_LDFLAGS=`polymake-config --ldflags`
+
+
+
+
+
+
+
+$as_echo "#define HAVE_POLYMAKE 1" >>confdefs.h
+
+
+      { $as_echo "$as_me:${as_lineno-$LINENO}: checking polymake includes" >&5
+$as_echo_n "checking polymake includes... " >&6; }
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PM_INC" >&5
+$as_echo "$PM_INC" >&6; }
+      { $as_echo "$as_me:${as_lineno-$LINENO}: checking polymake cflags" >&5
+$as_echo_n "checking polymake cflags... " >&6; }
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PM_CFLAGS" >&5
+$as_echo "$PM_CFLAGS" >&6; }
+      { $as_echo "$as_me:${as_lineno-$LINENO}: checking polymake libs" >&5
+$as_echo_n "checking polymake libs... " >&6; }
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PM_LIBS" >&5
+$as_echo "$PM_LIBS" >&6; }
+      { $as_echo "$as_me:${as_lineno-$LINENO}: checking polymake ldflags" >&5
+$as_echo_n "checking polymake ldflags... " >&6; }
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PM_LDFLAGS" >&5
+$as_echo "$PM_LDFLAGS" >&6; }
+
+      PASSED_ALL_TEST_FOR_POLYMAKE="yes";
+    else
+      PASSED_ALL_TEST_FOR_POLYMAKE="no";
+
+      if test "x$ENABLE_POLYMAKE" = xyes; then
+        as_fn_error $? "outdated polymake version" "$LINENO" 5
+      fi
+    fi
+   else
+    PASSED_ALL_TEST_FOR_POLYMAKE="no";
+
+    if test "x$ENABLE_POLYMAKE" = xyes; then
+     as_fn_error $? "polymake not installed" "$LINENO" 5
+    fi
+   fi
+  fi
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+  PASSED_ALL_TEST_FOR_POLYMAKE="no";
+fi
+
+ if test "x$PASSED_ALL_TEST_FOR_POLYMAKE" != xno; then
+  SING_HAVE_POLYMAKE_TRUE=
+  SING_HAVE_POLYMAKE_FALSE='#'
+else
+  SING_HAVE_POLYMAKE_TRUE='#'
+  SING_HAVE_POLYMAKE_FALSE=
+fi
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether non-commutative subsystem should be enabled" >&5
+$as_echo_n "checking whether non-commutative subsystem should be enabled... " >&6; }
+
+# Check whether --enable-plural was given.
+if test "${enable_plural+set}" = set; then :
+  enableval=$enable_plural; ENABLE_PLURAL="$enableval"
+else
+  ENABLE_PLURAL="yes"
+fi
+
+
+if test "x$ENABLE_PLURAL" != xno; then
+
+$as_echo "#define HAVE_PLURAL 1" >>confdefs.h
+
+  #TODO make a seperate switch
+
+$as_echo "#define HAVE_SHIFTBBA 1" >>confdefs.h
+
+fi
+
+ if test x$ENABLE_PLURAL != xno; then
+  ENABLE_PLURAL_TRUE=
+  ENABLE_PLURAL_FALSE='#'
+else
+  ENABLE_PLURAL_TRUE='#'
+  ENABLE_PLURAL_FALSE=
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ENABLE_PLURAL" >&5
+$as_echo "$ENABLE_PLURAL" >&6; }
+
+
+
+# Check whether --with-RatGB was given.
+if test "${with_RatGB+set}" = set; then :
+  withval=$with_RatGB;
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to have ratGB" >&5
+$as_echo_n "checking whether to have ratGB... " >&6; }
+if test "x$with_ratGB" != xyes && test "x$enable_ratGB" != xyes; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+else
+
+$as_echo "#define HAVE_RATGRING 1" >>confdefs.h
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+fi
+
+
+
+
+
+## m4_pushdef([_symbol],[m4_cr_Letters[]m4_cr_digits[]_])dnl
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking built-in modules" >&5
+$as_echo_n "checking built-in modules... " >&6; }
+
+
+
+# Check whether --with-builtinmodules was given.
+if test "${with_builtinmodules+set}" = set; then :
+  withval=$with_builtinmodules; if test "x$with_builtinmodules" = "xyes"; then
+    with_builtinmodules=syzextra
+   fi
+else
+  with_builtinmodules=""
+
+fi
+
+ # staticdemo,bigintm,
+ # ,pyobject,gfanlib,polymake,singmathic
+
+
+
+ #### TODO Dynamic Modules???
+  L=""
+  bi_staticdemo=false
+  bi_syzextra=false
+  bi_pyobject=false
+  bi_gfanlib=false
+  bi_polymake=false
+  bi_singmathic=false
+  bi_bigintm=false
+  bi_Order=false
+
+
+ if test -z "$with_builtinmodules"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+  LL=""
+
+  for a in `echo ${with_builtinmodules}|tr ',' ' '`;
+  do
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build-in '$a'?" >&5
+$as_echo_n "checking whether to build-in '$a'?... " >&6; }
+
+      L="${L} add($a)"
+      LL="${LL} $a"
+      BUILTIN_LIBS="${BUILTIN_LIBS} dyn_modules/$a/$a.la"
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+# *) AC_MSG_ERROR([bad value ${enableval} for	    --enable-debug]) ;;
+
+      case "${a}" in
+       staticdemo ) bi_staticdemo=true;;
+       syzextra ) bi_syzextra=true ;;
+       pyobject ) bi_pyobject=true ;;
+       gfanlib ) bi_gfanlib=true ;;
+       polymake ) bi_polymake=true ;;
+       singmathic ) bi_singmathic=true ;;
+       bigintm ) bi_bigintm=true ;;
+       Order ) bi_Order=true ;;
+      esac
+
+###### In case of out-of tree building: the build dir is empty in configure time!!!
+    if test ! -d "Singular/dyn_modules/$a"; then
+        { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: The directory 'Singular/dyn_modules/$a' is missing :(" >&5
+$as_echo "$as_me: WARNING: The directory 'Singular/dyn_modules/$a' is missing :(" >&2;}
+##    else
+##      AC_MSG_RESULT(no)
+    fi
+
+#    A=`echo "SI_BUILTIN_$a" | sed -e "y:m4_cr_letters-:m4_cr_LETTERS[]_:"  -e "/^[m4_cr_digits]/s/^/_/"`
+#    echo "A:: $A"
+#    AM_CONDITIONAL(m4_unquote([A]),[test -d "Singular/dyn_modules/$a"]) ## :(((
+  done # for
+
+
+cat >>confdefs.h <<_ACEOF
+#define SI_BUILTINMODULES "$LL"
+_ACEOF
+
+
+ fi # else ("x$with_builtinmodules" != xno)
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking SI_BUILTINMODULES_ADD(add)..." >&5
+$as_echo_n "checking SI_BUILTINMODULES_ADD(add)...... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${L:-unset}" >&5
+$as_echo "${L:-unset}" >&6; }
+
+
+cat >>confdefs.h <<_ACEOF
+#define SI_BUILTINMODULES_ADD(add) $L
+_ACEOF
+
+
+
+  if test x$bi_staticdemo = xtrue; then
+  SI_BUILTIN_STATICDEMO_TRUE=
+  SI_BUILTIN_STATICDEMO_FALSE='#'
+else
+  SI_BUILTIN_STATICDEMO_TRUE='#'
+  SI_BUILTIN_STATICDEMO_FALSE=
+fi
+
+  if test x$bi_syzextra = xtrue; then
+  SI_BUILTIN_SYZEXTRA_TRUE=
+  SI_BUILTIN_SYZEXTRA_FALSE='#'
+else
+  SI_BUILTIN_SYZEXTRA_TRUE='#'
+  SI_BUILTIN_SYZEXTRA_FALSE=
+fi
+
+  if test x$bi_pyobject = xtrue; then
+  SI_BUILTIN_PYOBJECT_TRUE=
+  SI_BUILTIN_PYOBJECT_FALSE='#'
+else
+  SI_BUILTIN_PYOBJECT_TRUE='#'
+  SI_BUILTIN_PYOBJECT_FALSE=
+fi
+
+  if test x$bi_gfanlib = xtrue; then
+  SI_BUILTIN_GFANLIB_TRUE=
+  SI_BUILTIN_GFANLIB_FALSE='#'
+else
+  SI_BUILTIN_GFANLIB_TRUE='#'
+  SI_BUILTIN_GFANLIB_FALSE=
+fi
+
+  if test x$bi_polymake = xtrue; then
+  SI_BUILTIN_POLYMAKE_TRUE=
+  SI_BUILTIN_POLYMAKE_FALSE='#'
+else
+  SI_BUILTIN_POLYMAKE_TRUE='#'
+  SI_BUILTIN_POLYMAKE_FALSE=
+fi
+
+  if test x$bi_singmathic = xtrue; then
+  SI_BUILTIN_SINGMATHIC_TRUE=
+  SI_BUILTIN_SINGMATHIC_FALSE='#'
+else
+  SI_BUILTIN_SINGMATHIC_TRUE='#'
+  SI_BUILTIN_SINGMATHIC_FALSE=
+fi
+
+  if test x$bi_bigintm = xtrue; then
+  SI_BUILTIN_BIGINTM_TRUE=
+  SI_BUILTIN_BIGINTM_FALSE='#'
+else
+  SI_BUILTIN_BIGINTM_TRUE='#'
+  SI_BUILTIN_BIGINTM_FALSE=
+fi
+
+  if test x$bi_Order = xtrue; then
+  SI_BUILTIN_ORDER_TRUE=
+  SI_BUILTIN_ORDER_FALSE='#'
+else
+  SI_BUILTIN_ORDER_TRUE='#'
+  SI_BUILTIN_ORDER_FALSE=
+fi
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking BUILTIN_LIBS..." >&5
+$as_echo_n "checking BUILTIN_LIBS...... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${BUILTIN_LIBS:-unset}" >&5
+$as_echo "${BUILTIN_LIBS:-unset}" >&6; }
+
+
+### the following is needed due to the use of om_sing_opt_show_mem in misc_ip.cc...
+#ac_configure_args="$ac_configure_args --with-external-config_h=../Singular/omSingularConfig.h"
+
+# Check whether --enable-countedref was given.
+if test "${enable_countedref+set}" = set; then :
+  enableval=$enable_countedref; if test "x$enableval" = "xyes"; then
+ENABLE_COUNTEDREF_AUTOLOAD=yes
+fi
+else
+  ENABLE_COUNTEDREF_AUTOLOAD=no
+fi
+
+
+if test x"${ENABLE_COUNTEDREF_AUTOLOAD}" == xyes; then
+
+$as_echo "#define SI_COUNTEDREF_AUTOLOAD 1" >>confdefs.h
+
+
+fi
+
+
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define CC "$CC"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define CXX "$CXX"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define CFLAGS "$CFLAGS"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define CXXFLAGS "$CXXFLAGS"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define DEFS "$DEFS"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define CPPFLAGS "$CPPFLAGS"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define LDFLAGS "$LDFLAGS"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define LIBS "$LIBS"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define AC_CONFIGURE_ARGS "$ac_configure_args"
+_ACEOF
+
+# AC_DEFINE_UNQUOTED([AC_CT_CC], "$ac_ct_CC",[ac_ct_CC])
+
+
+cat >>confdefs.h <<_ACEOF
+#define NTL_CFLAGS "$NTL_CFLAGS"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define NTL_LIBS "$NTL_LIBS"
+_ACEOF
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define GMP_CFLAGS "$GMP_CFLAGS"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define GMP_LIBS "$GMP_LIBS"
+_ACEOF
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define FLINT_CFLAGS "$FLINT_CFLAGS"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define FLINT_LIBS "$FLINT_LIBS"
+_ACEOF
+
+
+##### SEE http://www.gnu.org/prep/standards/html_node/Directory-Variables.html
+
+_lcl_receval="$prefix"
+config_prefix=`(test "x$prefix" = xNONE && prefix="$ac_default_prefix"
+     test "x$exec_prefix" = xNONE && exec_prefix="${prefix}"
+     _lcl_receval_old=''
+     while test "$_lcl_receval_old" != "$_lcl_receval"; do
+       _lcl_receval_old="$_lcl_receval"
+       eval _lcl_receval="\"$_lcl_receval\""
+     done
+     echo "$_lcl_receval")`
+case ":$config_prefix:" in
+# change empty paths to '.'
+  ::) config_prefix='.' ;;
+# strip trailing slashes
+  :*[\\/]:) config_prefix=`echo "$config_prefix" | sed 's,[\\/]*$,,'` ;;
+  :*:) ;;
+esac
+# squeze repeated slashes
+case '/' in
+# if the path contains any backslashes, turn slashes into backslashes
+ *\\*) config_prefix=`echo "$config_prefix" | sed 's,\(.\)[\\/][\\/]*,\1\\\\,g'` ;;
+# if the path contains slashes, also turn backslashes into slashes
+ *) config_prefix=`echo "$config_prefix" | sed 's,\(.\)[\\/][\\/]*,\1/,g'` ;;
+esac
+
+cat >>confdefs.h <<_ACEOF
+#define PREFIX "$config_prefix"
+_ACEOF
+
+
+_lcl_receval="$exec_prefix"
+config_exec_prefix=`(test "x$prefix" = xNONE && prefix="$ac_default_prefix"
+     test "x$exec_prefix" = xNONE && exec_prefix="${prefix}"
+     _lcl_receval_old=''
+     while test "$_lcl_receval_old" != "$_lcl_receval"; do
+       _lcl_receval_old="$_lcl_receval"
+       eval _lcl_receval="\"$_lcl_receval\""
+     done
+     echo "$_lcl_receval")`
+case ":$config_exec_prefix:" in
+# change empty paths to '.'
+  ::) config_exec_prefix='.' ;;
+# strip trailing slashes
+  :*[\\/]:) config_exec_prefix=`echo "$config_exec_prefix" | sed 's,[\\/]*$,,'` ;;
+  :*:) ;;
+esac
+# squeze repeated slashes
+case '/' in
+# if the path contains any backslashes, turn slashes into backslashes
+ *\\*) config_exec_prefix=`echo "$config_exec_prefix" | sed 's,\(.\)[\\/][\\/]*,\1\\\\,g'` ;;
+# if the path contains slashes, also turn backslashes into slashes
+ *) config_exec_prefix=`echo "$config_exec_prefix" | sed 's,\(.\)[\\/][\\/]*,\1/,g'` ;;
+esac
+
+cat >>confdefs.h <<_ACEOF
+#define EXEC_PREFIX "$config_exec_prefix"
+_ACEOF
+
+
+_lcl_receval="$libexecdir"
+config_libexecdir=`(test "x$prefix" = xNONE && prefix="$ac_default_prefix"
+     test "x$exec_prefix" = xNONE && exec_prefix="${prefix}"
+     _lcl_receval_old=''
+     while test "$_lcl_receval_old" != "$_lcl_receval"; do
+       _lcl_receval_old="$_lcl_receval"
+       eval _lcl_receval="\"$_lcl_receval\""
+     done
+     echo "$_lcl_receval")`
+case ":$config_libexecdir:" in
+# change empty paths to '.'
+  ::) config_libexecdir='.' ;;
+# strip trailing slashes
+  :*[\\/]:) config_libexecdir=`echo "$config_libexecdir" | sed 's,[\\/]*$,,'` ;;
+  :*:) ;;
+esac
+# squeze repeated slashes
+case '/' in
+# if the path contains any backslashes, turn slashes into backslashes
+ *\\*) config_libexecdir=`echo "$config_libexecdir" | sed 's,\(.\)[\\/][\\/]*,\1\\\\,g'` ;;
+# if the path contains slashes, also turn backslashes into slashes
+ *) config_libexecdir=`echo "$config_libexecdir" | sed 's,\(.\)[\\/][\\/]*,\1/,g'` ;;
+esac
+
+cat >>confdefs.h <<_ACEOF
+#define LIBEXEC_DIR "$config_libexecdir"
+_ACEOF
+
+
+_lcl_receval="$libdir"
+config_libdir=`(test "x$prefix" = xNONE && prefix="$ac_default_prefix"
+     test "x$exec_prefix" = xNONE && exec_prefix="${prefix}"
+     _lcl_receval_old=''
+     while test "$_lcl_receval_old" != "$_lcl_receval"; do
+       _lcl_receval_old="$_lcl_receval"
+       eval _lcl_receval="\"$_lcl_receval\""
+     done
+     echo "$_lcl_receval")`
+case ":$config_libdir:" in
+# change empty paths to '.'
+  ::) config_libdir='.' ;;
+# strip trailing slashes
+  :*[\\/]:) config_libdir=`echo "$config_libdir" | sed 's,[\\/]*$,,'` ;;
+  :*:) ;;
+esac
+# squeze repeated slashes
+case '/' in
+# if the path contains any backslashes, turn slashes into backslashes
+ *\\*) config_libdir=`echo "$config_libdir" | sed 's,\(.\)[\\/][\\/]*,\1\\\\,g'` ;;
+# if the path contains slashes, also turn backslashes into slashes
+ *) config_libdir=`echo "$config_libdir" | sed 's,\(.\)[\\/][\\/]*,\1/,g'` ;;
+esac
+
+cat >>confdefs.h <<_ACEOF
+#define LIB_DIR "$config_libdir"
+_ACEOF
+
+
+_lcl_receval="$bindir"
+config_bindir=`(test "x$prefix" = xNONE && prefix="$ac_default_prefix"
+     test "x$exec_prefix" = xNONE && exec_prefix="${prefix}"
+     _lcl_receval_old=''
+     while test "$_lcl_receval_old" != "$_lcl_receval"; do
+       _lcl_receval_old="$_lcl_receval"
+       eval _lcl_receval="\"$_lcl_receval\""
+     done
+     echo "$_lcl_receval")`
+case ":$config_bindir:" in
+# change empty paths to '.'
+  ::) config_bindir='.' ;;
+# strip trailing slashes
+  :*[\\/]:) config_bindir=`echo "$config_bindir" | sed 's,[\\/]*$,,'` ;;
+  :*:) ;;
+esac
+# squeze repeated slashes
+case '/' in
+# if the path contains any backslashes, turn slashes into backslashes
+ *\\*) config_bindir=`echo "$config_bindir" | sed 's,\(.\)[\\/][\\/]*,\1\\\\,g'` ;;
+# if the path contains slashes, also turn backslashes into slashes
+ *) config_bindir=`echo "$config_bindir" | sed 's,\(.\)[\\/][\\/]*,\1/,g'` ;;
+esac
+
+cat >>confdefs.h <<_ACEOF
+#define BIN_DIR "$config_bindir"
+_ACEOF
+
+
+_lcl_receval="$datadir"
+config_datadir=`(test "x$prefix" = xNONE && prefix="$ac_default_prefix"
+     test "x$exec_prefix" = xNONE && exec_prefix="${prefix}"
+     _lcl_receval_old=''
+     while test "$_lcl_receval_old" != "$_lcl_receval"; do
+       _lcl_receval_old="$_lcl_receval"
+       eval _lcl_receval="\"$_lcl_receval\""
+     done
+     echo "$_lcl_receval")`
+case ":$config_datadir:" in
+# change empty paths to '.'
+  ::) config_datadir='.' ;;
+# strip trailing slashes
+  :*[\\/]:) config_datadir=`echo "$config_datadir" | sed 's,[\\/]*$,,'` ;;
+  :*:) ;;
+esac
+# squeze repeated slashes
+case '/' in
+# if the path contains any backslashes, turn slashes into backslashes
+ *\\*) config_datadir=`echo "$config_datadir" | sed 's,\(.\)[\\/][\\/]*,\1\\\\,g'` ;;
+# if the path contains slashes, also turn backslashes into slashes
+ *) config_datadir=`echo "$config_datadir" | sed 's,\(.\)[\\/][\\/]*,\1/,g'` ;;
+esac
+
+cat >>confdefs.h <<_ACEOF
+#define DATA_DIR "$config_datadir"
+_ACEOF
+
+
+
+_lcl_receval="$docdir"
+config_docdir=`(test "x$prefix" = xNONE && prefix="$ac_default_prefix"
+     test "x$exec_prefix" = xNONE && exec_prefix="${prefix}"
+     _lcl_receval_old=''
+     while test "$_lcl_receval_old" != "$_lcl_receval"; do
+       _lcl_receval_old="$_lcl_receval"
+       eval _lcl_receval="\"$_lcl_receval\""
+     done
+     echo "$_lcl_receval")`
+case ":$config_docdir:" in
+# change empty paths to '.'
+  ::) config_docdir='.' ;;
+# strip trailing slashes
+  :*[\\/]:) config_docdir=`echo "$config_docdir" | sed 's,[\\/]*$,,'` ;;
+  :*:) ;;
+esac
+# squeze repeated slashes
+case '/' in
+# if the path contains any backslashes, turn slashes into backslashes
+ *\\*) config_docdir=`echo "$config_docdir" | sed 's,\(.\)[\\/][\\/]*,\1\\\\,g'` ;;
+# if the path contains slashes, also turn backslashes into slashes
+ *) config_docdir=`echo "$config_docdir" | sed 's,\(.\)[\\/][\\/]*,\1/,g'` ;;
+esac
+
+cat >>confdefs.h <<_ACEOF
+#define DOC_DIR "$config_docdir"
+_ACEOF
+
+
+
+
+
+echo "/* --------------- Compiler/linker flags:  --------------- */";
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking   CFLAGS?.." >&5
+$as_echo_n "checking   CFLAGS?..... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${CFLAGS:-unset}" >&5
+$as_echo "${CFLAGS:-unset}" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking CXXFLAGS?.." >&5
+$as_echo_n "checking CXXFLAGS?..... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${CXXFLAGS:-unset}" >&5
+$as_echo "${CXXFLAGS:-unset}" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking CPPFLAGS?.." >&5
+$as_echo_n "checking CPPFLAGS?..... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${CPPFLAGS:-unset}" >&5
+$as_echo "${CPPFLAGS:-unset}" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking     DEFS?.." >&5
+$as_echo_n "checking     DEFS?..... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${DEFS:-unset}" >&5
+$as_echo "${DEFS:-unset}" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking  LDFLAGS?.." >&5
+$as_echo_n "checking  LDFLAGS?..... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${LDFLAGS:-unset}" >&5
+$as_echo "${LDFLAGS:-unset}" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking     LIBS?.." >&5
+$as_echo_n "checking     LIBS?..... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${LIBS:-unset}" >&5
+$as_echo "${LIBS:-unset}" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking      GCC?.." >&5
+$as_echo_n "checking      GCC?..... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${GCC:-unset}" >&5
+$as_echo "${GCC:-unset}" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking       CC?.." >&5
+$as_echo_n "checking       CC?..... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${CC:-unset}" >&5
+$as_echo "${CC:-unset}" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking      GXX?.." >&5
+$as_echo_n "checking      GXX?..... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${GXX:-unset}" >&5
+$as_echo "${GXX:-unset}" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking      CXX?.." >&5
+$as_echo_n "checking      CXX?..... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${CXX:-unset}" >&5
+$as_echo "${CXX:-unset}" >&6; }
+
+# echo "/* =============== Compiler/linker flags:  =============== */";
+
+
+
+## AM_COND_IF([HAVE_DOXYGEN], [AC_CONFIG_FILES([dox/Doxyfile])])
+
+ac_config_files="$ac_config_files dox/Makefile"
+
+
+
+
+subdirs="$subdirs resources"
+
+subdirs="$subdirs omalloc"
+
+
+if test "x$ENABLE_FACTORY" = xyes; then
+ subdirs="$subdirs factory"
+
+fi
+
+subdirs="$subdirs libpolys"
+
+
+ac_config_files="$ac_config_files Makefile"
+
+ac_config_files="$ac_config_files xalloc/Makefile"
+
+ac_config_files="$ac_config_files kernel/Makefile"
+
+ac_config_files="$ac_config_files kernel/numeric/Makefile"
+
+ac_config_files="$ac_config_files kernel/fglm/Makefile"
+
+ac_config_files="$ac_config_files kernel/groebner_walk/Makefile"
+
+ac_config_files="$ac_config_files kernel/combinatorics/Makefile"
+
+ac_config_files="$ac_config_files kernel/spectrum/Makefile"
+
+ac_config_files="$ac_config_files kernel/linear_algebra/Makefile"
+
+ac_config_files="$ac_config_files kernel/maps/Makefile"
+
+ac_config_files="$ac_config_files kernel/GBEngine/Makefile"
+
+ac_config_files="$ac_config_files kernel/oswrapper/Makefile"
+
+
+subdirs="$subdirs gfanlib"
+
+
+ac_config_files="$ac_config_files Singular/dyn_modules/Makefile"
+
+ac_config_files="$ac_config_files Singular/dyn_modules/bigintm/Makefile"
+
+ac_config_files="$ac_config_files Singular/dyn_modules/Order/Makefile"
+
+ac_config_files="$ac_config_files Singular/dyn_modules/syzextra/Makefile"
+
+ac_config_files="$ac_config_files Singular/dyn_modules/gfanlib/Makefile"
+
+ac_config_files="$ac_config_files Singular/dyn_modules/polymake/Makefile"
+
+ac_config_files="$ac_config_files Singular/dyn_modules/pyobject/Makefile"
+
+ac_config_files="$ac_config_files Singular/dyn_modules/singmathic/Makefile"
+
+ac_config_files="$ac_config_files Singular/dyn_modules/staticdemo/Makefile"
+
+
+ac_config_files="$ac_config_files Singular/Makefile"
+
+
+ac_config_files="$ac_config_files IntegerProgramming/Makefile"
+
+
+ac_config_files="$ac_config_files libsingular-config Singular.pc"
+
+
+ac_config_files="$ac_config_files emacs/Makefile"
+
+
+ac_config_files="$ac_config_files desktop/Makefile desktop/Singular.desktop desktop/Singular-manual.desktop"
+
+
+ac_config_files="$ac_config_files singular.spec"
+
+
+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
+    if test "x$cache_file" != "x/dev/null"; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
+$as_echo "$as_me: updating cache $cache_file" >&6;}
+      if test ! -f "$cache_file" || test -h "$cache_file"; then
+	cat confcache >"$cache_file"
+      else
+        case $cache_file in #(
+        */* | ?:*)
+	  mv -f confcache "$cache_file"$$ &&
+	  mv -f "$cache_file"$$ "$cache_file" ;; #(
+        *)
+	  mv -f confcache "$cache_file" ;;
+	esac
+      fi
+    fi
+  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=
+U=
+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 -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
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5
+$as_echo_n "checking that generated files are newer than configure... " >&6; }
+   if test -n "$am_sleep_pid"; then
+     # Hide warnings about reused PIDs.
+     wait $am_sleep_pid 2>/dev/null
+   fi
+   { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5
+$as_echo "done" >&6; }
+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 -n "$EXEEXT"; then
+  am__EXEEXT_TRUE=
+  am__EXEEXT_FALSE='#'
+else
+  am__EXEEXT_TRUE='#'
+  am__EXEEXT_FALSE=
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5
+$as_echo_n "checking that generated files are newer than configure... " >&6; }
+   if test -n "$am_sleep_pid"; then
+     # Hide warnings about reused PIDs.
+     wait $am_sleep_pid 2>/dev/null
+   fi
+   { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5
+$as_echo "done" >&6; }
+if test -z "${WANT_DEBUG_TRUE}" && test -z "${WANT_DEBUG_FALSE}"; then
+  as_fn_error $? "conditional \"WANT_DEBUG\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${WANT_OPTIMIZATIONFLAGS_TRUE}" && test -z "${WANT_OPTIMIZATIONFLAGS_FALSE}"; then
+  as_fn_error $? "conditional \"WANT_OPTIMIZATIONFLAGS\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then
+  as_fn_error $? "conditional \"am__fastdepCXX\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then
+  as_fn_error $? "conditional \"am__fastdepCXX\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${HAVE_DOXYGEN_TRUE}" && test -z "${HAVE_DOXYGEN_FALSE}"; then
+  as_fn_error $? "conditional \"HAVE_DOXYGEN\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${SING_HAVE_GMP_TRUE}" && test -z "${SING_HAVE_GMP_FALSE}"; then
+  as_fn_error $? "conditional \"SING_HAVE_GMP\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${SING_HAVE_NTL_TRUE}" && test -z "${SING_HAVE_NTL_FALSE}"; then
+  as_fn_error $? "conditional \"SING_HAVE_NTL\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${SING_HAVE_FLINT_TRUE}" && test -z "${SING_HAVE_FLINT_FALSE}"; then
+  as_fn_error $? "conditional \"SING_HAVE_FLINT\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${PYTHON_USE_TRUE}" && test -z "${PYTHON_USE_FALSE}"; then
+  as_fn_error $? "conditional \"PYTHON_USE\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${PYTHON_USE_TRUE}" && test -z "${PYTHON_USE_FALSE}"; then
+  as_fn_error $? "conditional \"PYTHON_USE\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${SI_EMBED_PYTHON_TRUE}" && test -z "${SI_EMBED_PYTHON_FALSE}"; then
+  as_fn_error $? "conditional \"SI_EMBED_PYTHON\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${PYTHON_MODULE_TRUE}" && test -z "${PYTHON_MODULE_FALSE}"; then
+  as_fn_error $? "conditional \"PYTHON_MODULE\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${ENABLE_OMALLOC_TRUE}" && test -z "${ENABLE_OMALLOC_FALSE}"; then
+  as_fn_error $? "conditional \"ENABLE_OMALLOC\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${ENABLE_RESOURCES_TRUE}" && test -z "${ENABLE_RESOURCES_FALSE}"; then
+  as_fn_error $? "conditional \"ENABLE_RESOURCES\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${ENABLE_FACTORY_TRUE}" && test -z "${ENABLE_FACTORY_FALSE}"; then
+  as_fn_error $? "conditional \"ENABLE_FACTORY\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${ENABLE_P_PROCS_DYNAMIC_TRUE}" && test -z "${ENABLE_P_PROCS_DYNAMIC_FALSE}"; then
+  as_fn_error $? "conditional \"ENABLE_P_PROCS_DYNAMIC\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${ENABLE_P_PROCS_STATIC_TRUE}" && test -z "${ENABLE_P_PROCS_STATIC_FALSE}"; then
+  as_fn_error $? "conditional \"ENABLE_P_PROCS_STATIC\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${HAVE_GFANLIB_TRUE}" && test -z "${HAVE_GFANLIB_FALSE}"; then
+  as_fn_error $? "conditional \"HAVE_GFANLIB\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${SING_HAVE_POLYMAKE_TRUE}" && test -z "${SING_HAVE_POLYMAKE_FALSE}"; then
+  as_fn_error $? "conditional \"SING_HAVE_POLYMAKE\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${ENABLE_PLURAL_TRUE}" && test -z "${ENABLE_PLURAL_FALSE}"; then
+  as_fn_error $? "conditional \"ENABLE_PLURAL\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${SI_BUILTIN_STATICDEMO_TRUE}" && test -z "${SI_BUILTIN_STATICDEMO_FALSE}"; then
+  as_fn_error $? "conditional \"SI_BUILTIN_STATICDEMO\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${SI_BUILTIN_SYZEXTRA_TRUE}" && test -z "${SI_BUILTIN_SYZEXTRA_FALSE}"; then
+  as_fn_error $? "conditional \"SI_BUILTIN_SYZEXTRA\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${SI_BUILTIN_PYOBJECT_TRUE}" && test -z "${SI_BUILTIN_PYOBJECT_FALSE}"; then
+  as_fn_error $? "conditional \"SI_BUILTIN_PYOBJECT\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${SI_BUILTIN_GFANLIB_TRUE}" && test -z "${SI_BUILTIN_GFANLIB_FALSE}"; then
+  as_fn_error $? "conditional \"SI_BUILTIN_GFANLIB\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${SI_BUILTIN_POLYMAKE_TRUE}" && test -z "${SI_BUILTIN_POLYMAKE_FALSE}"; then
+  as_fn_error $? "conditional \"SI_BUILTIN_POLYMAKE\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${SI_BUILTIN_SINGMATHIC_TRUE}" && test -z "${SI_BUILTIN_SINGMATHIC_FALSE}"; then
+  as_fn_error $? "conditional \"SI_BUILTIN_SINGMATHIC\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${SI_BUILTIN_BIGINTM_TRUE}" && test -z "${SI_BUILTIN_BIGINTM_FALSE}"; then
+  as_fn_error $? "conditional \"SI_BUILTIN_BIGINTM\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${SI_BUILTIN_ORDER_TRUE}" && test -z "${SI_BUILTIN_ORDER_FALSE}"; then
+  as_fn_error $? "conditional \"SI_BUILTIN_ORDER\" 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.
+as_myself=
+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 STATUS 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=$1; test $as_status -eq 0 && as_status=1
+  if test "$4"; then
+    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+  fi
+  $as_echo "$as_me: error: $2" >&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 -pR'.
+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+      as_ln_s='cp -pR'
+  elif ln conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s=ln
+  else
+    as_ln_s='cp -pR'
+  fi
+else
+  as_ln_s='cp -pR'
+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
+
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+  test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
+
+# 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 singular $as_me 4.0.1, which was
+generated by GNU Autoconf 2.69.  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
+      --config     print configuration, 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 <singular at mathematik.uni-kl.de>."
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
+ac_cs_version="\\
+singular config.status 4.0.1
+configured by $0, generated by GNU Autoconf 2.69,
+  with options \\"\$ac_cs_config\\"
+
+Copyright (C) 2012 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=`expr "X$1" : 'X\([^=]*\)='`
+    ac_optarg=
+    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 ;;
+  --config | --confi | --conf | --con | --co | --c )
+    $as_echo "$ac_cs_config"; 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"` ;;
+    '') as_fn_error $? "missing file argument" ;;
+    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
+#
+PACKAGE="$PACKAGE"
+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'
+macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`'
+macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`'
+enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`'
+enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`'
+pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`'
+enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`'
+SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`'
+ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`'
+PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`'
+host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`'
+host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`'
+host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`'
+build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`'
+build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`'
+build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`'
+SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`'
+Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`'
+GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`'
+EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`'
+FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`'
+LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`'
+NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`'
+LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`'
+max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`'
+ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`'
+exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`'
+lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`'
+lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`'
+lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`'
+lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`'
+lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`'
+reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`'
+reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`'
+OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`'
+deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`'
+file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`'
+file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`'
+want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`'
+DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`'
+sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`'
+AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`'
+AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`'
+archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`'
+STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`'
+RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`'
+old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`'
+old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`'
+old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`'
+lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`'
+CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`'
+CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`'
+compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`'
+GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`'
+nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`'
+lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`'
+objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`'
+MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`'
+lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`'
+need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`'
+MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`'
+DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`'
+NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`'
+LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`'
+OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`'
+OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`'
+libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`'
+shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`'
+extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`'
+archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`'
+enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`'
+export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`'
+whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`'
+compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`'
+old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`'
+old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`'
+archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`'
+archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`'
+module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`'
+module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`'
+with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`'
+allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`'
+no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`'
+hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`'
+hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`'
+hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`'
+hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`'
+hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`'
+inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`'
+link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`'
+always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`'
+export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`'
+exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`'
+include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`'
+prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`'
+postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`'
+file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`'
+variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`'
+need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`'
+need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`'
+version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`'
+runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`'
+shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`'
+shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`'
+libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`'
+library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`'
+soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`'
+install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`'
+postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`'
+postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`'
+finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`'
+finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`'
+hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`'
+sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`'
+sys_lib_dlsearch_path_spec='`$ECHO "$sys_lib_dlsearch_path_spec" | $SED "$delay_single_quote_subst"`'
+hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`'
+enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`'
+enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`'
+enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`'
+old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`'
+striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`'
+compiler_lib_search_dirs='`$ECHO "$compiler_lib_search_dirs" | $SED "$delay_single_quote_subst"`'
+predep_objects='`$ECHO "$predep_objects" | $SED "$delay_single_quote_subst"`'
+postdep_objects='`$ECHO "$postdep_objects" | $SED "$delay_single_quote_subst"`'
+predeps='`$ECHO "$predeps" | $SED "$delay_single_quote_subst"`'
+postdeps='`$ECHO "$postdeps" | $SED "$delay_single_quote_subst"`'
+compiler_lib_search_path='`$ECHO "$compiler_lib_search_path" | $SED "$delay_single_quote_subst"`'
+LD_CXX='`$ECHO "$LD_CXX" | $SED "$delay_single_quote_subst"`'
+reload_flag_CXX='`$ECHO "$reload_flag_CXX" | $SED "$delay_single_quote_subst"`'
+reload_cmds_CXX='`$ECHO "$reload_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+old_archive_cmds_CXX='`$ECHO "$old_archive_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+compiler_CXX='`$ECHO "$compiler_CXX" | $SED "$delay_single_quote_subst"`'
+GCC_CXX='`$ECHO "$GCC_CXX" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_no_builtin_flag_CXX='`$ECHO "$lt_prog_compiler_no_builtin_flag_CXX" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_pic_CXX='`$ECHO "$lt_prog_compiler_pic_CXX" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_wl_CXX='`$ECHO "$lt_prog_compiler_wl_CXX" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_static_CXX='`$ECHO "$lt_prog_compiler_static_CXX" | $SED "$delay_single_quote_subst"`'
+lt_cv_prog_compiler_c_o_CXX='`$ECHO "$lt_cv_prog_compiler_c_o_CXX" | $SED "$delay_single_quote_subst"`'
+archive_cmds_need_lc_CXX='`$ECHO "$archive_cmds_need_lc_CXX" | $SED "$delay_single_quote_subst"`'
+enable_shared_with_static_runtimes_CXX='`$ECHO "$enable_shared_with_static_runtimes_CXX" | $SED "$delay_single_quote_subst"`'
+export_dynamic_flag_spec_CXX='`$ECHO "$export_dynamic_flag_spec_CXX" | $SED "$delay_single_quote_subst"`'
+whole_archive_flag_spec_CXX='`$ECHO "$whole_archive_flag_spec_CXX" | $SED "$delay_single_quote_subst"`'
+compiler_needs_object_CXX='`$ECHO "$compiler_needs_object_CXX" | $SED "$delay_single_quote_subst"`'
+old_archive_from_new_cmds_CXX='`$ECHO "$old_archive_from_new_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+old_archive_from_expsyms_cmds_CXX='`$ECHO "$old_archive_from_expsyms_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+archive_cmds_CXX='`$ECHO "$archive_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+archive_expsym_cmds_CXX='`$ECHO "$archive_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+module_cmds_CXX='`$ECHO "$module_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+module_expsym_cmds_CXX='`$ECHO "$module_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+with_gnu_ld_CXX='`$ECHO "$with_gnu_ld_CXX" | $SED "$delay_single_quote_subst"`'
+allow_undefined_flag_CXX='`$ECHO "$allow_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`'
+no_undefined_flag_CXX='`$ECHO "$no_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_flag_spec_CXX='`$ECHO "$hardcode_libdir_flag_spec_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_separator_CXX='`$ECHO "$hardcode_libdir_separator_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_direct_CXX='`$ECHO "$hardcode_direct_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_direct_absolute_CXX='`$ECHO "$hardcode_direct_absolute_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_minus_L_CXX='`$ECHO "$hardcode_minus_L_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_shlibpath_var_CXX='`$ECHO "$hardcode_shlibpath_var_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_automatic_CXX='`$ECHO "$hardcode_automatic_CXX" | $SED "$delay_single_quote_subst"`'
+inherit_rpath_CXX='`$ECHO "$inherit_rpath_CXX" | $SED "$delay_single_quote_subst"`'
+link_all_deplibs_CXX='`$ECHO "$link_all_deplibs_CXX" | $SED "$delay_single_quote_subst"`'
+always_export_symbols_CXX='`$ECHO "$always_export_symbols_CXX" | $SED "$delay_single_quote_subst"`'
+export_symbols_cmds_CXX='`$ECHO "$export_symbols_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+exclude_expsyms_CXX='`$ECHO "$exclude_expsyms_CXX" | $SED "$delay_single_quote_subst"`'
+include_expsyms_CXX='`$ECHO "$include_expsyms_CXX" | $SED "$delay_single_quote_subst"`'
+prelink_cmds_CXX='`$ECHO "$prelink_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+postlink_cmds_CXX='`$ECHO "$postlink_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+file_list_spec_CXX='`$ECHO "$file_list_spec_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_action_CXX='`$ECHO "$hardcode_action_CXX" | $SED "$delay_single_quote_subst"`'
+compiler_lib_search_dirs_CXX='`$ECHO "$compiler_lib_search_dirs_CXX" | $SED "$delay_single_quote_subst"`'
+predep_objects_CXX='`$ECHO "$predep_objects_CXX" | $SED "$delay_single_quote_subst"`'
+postdep_objects_CXX='`$ECHO "$postdep_objects_CXX" | $SED "$delay_single_quote_subst"`'
+predeps_CXX='`$ECHO "$predeps_CXX" | $SED "$delay_single_quote_subst"`'
+postdeps_CXX='`$ECHO "$postdeps_CXX" | $SED "$delay_single_quote_subst"`'
+compiler_lib_search_path_CXX='`$ECHO "$compiler_lib_search_path_CXX" | $SED "$delay_single_quote_subst"`'
+
+LTCC='$LTCC'
+LTCFLAGS='$LTCFLAGS'
+compiler='$compiler_DEFAULT'
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+  eval 'cat <<_LTECHO_EOF
+\$1
+_LTECHO_EOF'
+}
+
+# Quote evaled strings.
+for var in SHELL \
+ECHO \
+PATH_SEPARATOR \
+SED \
+GREP \
+EGREP \
+FGREP \
+LD \
+NM \
+LN_S \
+lt_SP2NL \
+lt_NL2SP \
+reload_flag \
+OBJDUMP \
+deplibs_check_method \
+file_magic_cmd \
+file_magic_glob \
+want_nocaseglob \
+DLLTOOL \
+sharedlib_from_linklib_cmd \
+AR \
+AR_FLAGS \
+archiver_list_spec \
+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 \
+nm_file_list_spec \
+lt_prog_compiler_no_builtin_flag \
+lt_prog_compiler_pic \
+lt_prog_compiler_wl \
+lt_prog_compiler_static \
+lt_cv_prog_compiler_c_o \
+need_locks \
+MANIFEST_TOOL \
+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_separator \
+exclude_expsyms \
+include_expsyms \
+file_list_spec \
+variables_saved_for_relink \
+libname_spec \
+library_names_spec \
+soname_spec \
+install_override_mode \
+finish_eval \
+old_striplib \
+striplib \
+compiler_lib_search_dirs \
+predep_objects \
+postdep_objects \
+predeps \
+postdeps \
+compiler_lib_search_path \
+LD_CXX \
+reload_flag_CXX \
+compiler_CXX \
+lt_prog_compiler_no_builtin_flag_CXX \
+lt_prog_compiler_pic_CXX \
+lt_prog_compiler_wl_CXX \
+lt_prog_compiler_static_CXX \
+lt_cv_prog_compiler_c_o_CXX \
+export_dynamic_flag_spec_CXX \
+whole_archive_flag_spec_CXX \
+compiler_needs_object_CXX \
+with_gnu_ld_CXX \
+allow_undefined_flag_CXX \
+no_undefined_flag_CXX \
+hardcode_libdir_flag_spec_CXX \
+hardcode_libdir_separator_CXX \
+exclude_expsyms_CXX \
+include_expsyms_CXX \
+file_list_spec_CXX \
+compiler_lib_search_dirs_CXX \
+predep_objects_CXX \
+postdep_objects_CXX \
+predeps_CXX \
+postdeps_CXX \
+compiler_lib_search_path_CXX; do
+    case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+    *[\\\\\\\`\\"\\\$]*)
+      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$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 \
+postlink_cmds \
+postinstall_cmds \
+postuninstall_cmds \
+finish_cmds \
+sys_lib_search_path_spec \
+sys_lib_dlsearch_path_spec \
+reload_cmds_CXX \
+old_archive_cmds_CXX \
+old_archive_from_new_cmds_CXX \
+old_archive_from_expsyms_cmds_CXX \
+archive_cmds_CXX \
+archive_expsym_cmds_CXX \
+module_cmds_CXX \
+module_expsym_cmds_CXX \
+export_symbols_cmds_CXX \
+prelink_cmds_CXX \
+postlink_cmds_CXX; do
+    case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+    *[\\\\\\\`\\"\\\$]*)
+      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\""
+      ;;
+    *)
+      eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+      ;;
+    esac
+done
+
+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'
+
+
+
+
+
+
+_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" ;;
+    "singularconfig.h") CONFIG_COMMANDS="$CONFIG_COMMANDS singularconfig.h" ;;
+    "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
+    "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;;
+    "dox/Makefile") CONFIG_FILES="$CONFIG_FILES dox/Makefile" ;;
+    "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+    "xalloc/Makefile") CONFIG_FILES="$CONFIG_FILES xalloc/Makefile" ;;
+    "kernel/Makefile") CONFIG_FILES="$CONFIG_FILES kernel/Makefile" ;;
+    "kernel/numeric/Makefile") CONFIG_FILES="$CONFIG_FILES kernel/numeric/Makefile" ;;
+    "kernel/fglm/Makefile") CONFIG_FILES="$CONFIG_FILES kernel/fglm/Makefile" ;;
+    "kernel/groebner_walk/Makefile") CONFIG_FILES="$CONFIG_FILES kernel/groebner_walk/Makefile" ;;
+    "kernel/combinatorics/Makefile") CONFIG_FILES="$CONFIG_FILES kernel/combinatorics/Makefile" ;;
+    "kernel/spectrum/Makefile") CONFIG_FILES="$CONFIG_FILES kernel/spectrum/Makefile" ;;
+    "kernel/linear_algebra/Makefile") CONFIG_FILES="$CONFIG_FILES kernel/linear_algebra/Makefile" ;;
+    "kernel/maps/Makefile") CONFIG_FILES="$CONFIG_FILES kernel/maps/Makefile" ;;
+    "kernel/GBEngine/Makefile") CONFIG_FILES="$CONFIG_FILES kernel/GBEngine/Makefile" ;;
+    "kernel/oswrapper/Makefile") CONFIG_FILES="$CONFIG_FILES kernel/oswrapper/Makefile" ;;
+    "Singular/dyn_modules/Makefile") CONFIG_FILES="$CONFIG_FILES Singular/dyn_modules/Makefile" ;;
+    "Singular/dyn_modules/bigintm/Makefile") CONFIG_FILES="$CONFIG_FILES Singular/dyn_modules/bigintm/Makefile" ;;
+    "Singular/dyn_modules/Order/Makefile") CONFIG_FILES="$CONFIG_FILES Singular/dyn_modules/Order/Makefile" ;;
+    "Singular/dyn_modules/syzextra/Makefile") CONFIG_FILES="$CONFIG_FILES Singular/dyn_modules/syzextra/Makefile" ;;
+    "Singular/dyn_modules/gfanlib/Makefile") CONFIG_FILES="$CONFIG_FILES Singular/dyn_modules/gfanlib/Makefile" ;;
+    "Singular/dyn_modules/polymake/Makefile") CONFIG_FILES="$CONFIG_FILES Singular/dyn_modules/polymake/Makefile" ;;
+    "Singular/dyn_modules/pyobject/Makefile") CONFIG_FILES="$CONFIG_FILES Singular/dyn_modules/pyobject/Makefile" ;;
+    "Singular/dyn_modules/singmathic/Makefile") CONFIG_FILES="$CONFIG_FILES Singular/dyn_modules/singmathic/Makefile" ;;
+    "Singular/dyn_modules/staticdemo/Makefile") CONFIG_FILES="$CONFIG_FILES Singular/dyn_modules/staticdemo/Makefile" ;;
+    "Singular/Makefile") CONFIG_FILES="$CONFIG_FILES Singular/Makefile" ;;
+    "IntegerProgramming/Makefile") CONFIG_FILES="$CONFIG_FILES IntegerProgramming/Makefile" ;;
+    "libsingular-config") CONFIG_FILES="$CONFIG_FILES libsingular-config" ;;
+    "Singular.pc") CONFIG_FILES="$CONFIG_FILES Singular.pc" ;;
+    "emacs/Makefile") CONFIG_FILES="$CONFIG_FILES emacs/Makefile" ;;
+    "desktop/Makefile") CONFIG_FILES="$CONFIG_FILES desktop/Makefile" ;;
+    "desktop/Singular.desktop") CONFIG_FILES="$CONFIG_FILES desktop/Singular.desktop" ;;
+    "desktop/Singular-manual.desktop") CONFIG_FILES="$CONFIG_FILES desktop/Singular-manual.desktop" ;;
+    "singular.spec") CONFIG_FILES="$CONFIG_FILES singular.spec" ;;
+
+  *) 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= ac_tmp=
+  trap 'exit_status=$?
+  : "${ac_tmp:=$tmp}"
+  { test ! -d "$ac_tmp" || rm -fr "$ac_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 -d "$tmp"
+}  ||
+{
+  tmp=./conf$$-$RANDOM
+  (umask 077 && mkdir "$tmp")
+} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
+ac_tmp=$tmp
+
+# 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 {' >"$ac_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 >>"\$ac_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 >>"\$ac_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 < "$ac_tmp/subs1.awk" > "$ac_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 sole $(srcdir),
+# ${srcdir} and @srcdir@ entries 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[	 ]*=[	 ]*/{
+h
+s///
+s/^/:/
+s/[	 ]*$/:/
+s/:\$(srcdir):/:/g
+s/:\${srcdir}:/:/g
+s/:@srcdir@:/:/g
+s/^:*//
+s/:*$//
+x
+s/\(=[	 ]*\).*/\1/
+G
+s/\n//
+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 >"$ac_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_tt=`sed -n "/$ac_delim/p" confdefs.h`
+  if test -z "$ac_tt"; 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="$ac_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 1 "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 >"$ac_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 "$ac_tmp/subs.awk" \
+  >$ac_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' "$ac_tmp/out"`; test -n "$ac_out"; } &&
+  { ac_out=`sed -n '/^[	 ]*datarootdir[	 ]*:*=/p' \
+      "$ac_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 "$ac_tmp/stdin"
+  case $ac_file in
+  -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";;
+  *) rm -f "$ac_file" && mv "$ac_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 "$ac_tmp/defines.awk"' "$ac_file_inputs"
+    } >"$ac_tmp/config.h" \
+      || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+    if diff "$ac_file" "$ac_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 "$ac_tmp/config.h" "$ac_file" \
+	|| as_fn_error $? "could not create $ac_file" "$LINENO" 5
+    fi
+  else
+    $as_echo "/* $configure_input  */" \
+      && eval '$AWK -f "$ac_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
+    "singularconfig.h":C)
+ac_prefix_conf_OUT=`echo singularconfig.h`
+ac_prefix_conf_PKG=`echo `
+ac_prefix_conf_LOW=`echo $ac_prefix_conf_PKG | sed -e "y:ABCDEFGHIJKLMNOPQRSTUVWXYZ-:abcdefghijklmnopqrstuvwxyz_:"`
+ac_prefix_conf_UPP=`echo $ac_prefix_conf_PKG | sed -e "y:abcdefghijklmnopqrstuvwxyz-:ABCDEFGHIJKLMNOPQRSTUVWXYZ_:"  -e "/^[0123456789]/s/^/_/"`
+ac_prefix_conf_INP=`echo "_config.h" | sed -e 's/ *//'`
+ac_prefix_conf_DEF=`echo "$ac_prefix_conf_UPP $PACKAGE $ac_prefix_conf_OUT" | sed -e "y:abcdefghijklmnopqrstuvwxyz:ABCDEFGHIJKLMNOPQRSTUVWXYZ:" -e "s/[^abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ]/_/g"`
+
+if test ".$ac_prefix_conf_INP" = "."; then
+   for ac_file in : $CONFIG_HEADERS; do test "_$ac_file" = _: && continue
+     case "$ac_file" in
+        *.h) ac_prefix_conf_INP=$ac_file ;;
+        *)
+     esac
+     test ".$ac_prefix_conf_INP" != "." && break
+   done
+fi
+if test ".$ac_prefix_conf_INP" = "."; then
+   case "$ac_prefix_conf_OUT" in
+      */*) ac_prefix_conf_INP=`basename "$ac_prefix_conf_OUT"`
+      ;;
+      *-*) ac_prefix_conf_INP=`echo "$ac_prefix_conf_OUT" | sed -e "s/[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_]*-//"`
+      ;;
+      *) ac_prefix_conf_INP=config.h
+      ;;
+   esac
+fi
+#if test -z "$_PKG" ; then
+#   AC_MSG_ERROR([no prefix for AX_PREFIX_PKG_CONFIG_H])
+#else
+  if test ! -f "$ac_prefix_conf_INP" ; then if test -f "$srcdir/$ac_prefix_conf_INP" ; then
+     ac_prefix_conf_INP="$srcdir/$ac_prefix_conf_INP"
+  fi fi
+  { $as_echo "$as_me:${as_lineno-$LINENO}: creating '$ac_prefix_conf_OUT' - prefix '$ac_prefix_conf_UPP' for '$ac_prefix_conf_INP' defines" >&5
+$as_echo "$as_me: creating '$ac_prefix_conf_OUT' - prefix '$ac_prefix_conf_UPP' for '$ac_prefix_conf_INP' defines" >&6;}
+  if test -f $ac_prefix_conf_INP ; then
+    $as_echo "s/^#undef  *\\([ABCDEFGHIJKLMNOPQRSTUVWXYZ_]\\)/#undef $ac_prefix_conf_UPP""\\1/" > conftest.prefix
+    $as_echo "s/^#undef  *\\([abcdefghijklmnopqrstuvwxyz]\\)/#undef $ac_prefix_conf_LOW""\\1/" >> conftest.prefix
+    $as_echo "s/^#define  *\\([ABCDEFGHIJKLMNOPQRSTUVWXYZ_][abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_]*\\)\\(.*\\)/#ifndef $ac_prefix_conf_UPP""\\1\\" >> conftest.prefix
+    $as_echo "#define $ac_prefix_conf_UPP""\\1\\2\\" >> conftest.prefix
+    $as_echo "#endif/" >> conftest.prefix
+    $as_echo "s/^#define  *\\([abcdefghijklmnopqrstuvwxyz][abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_]*\\)\\(.*\\)/#ifndef $ac_prefix_conf_LOW""\\1\\" >> conftest.prefix
+    $as_echo "#define $ac_prefix_conf_LOW""\\1\\2\\" >> conftest.prefix
+    $as_echo "#endif/" >> conftest.prefix
+
+    # now executing _script on _DEF input to create _OUT output file
+    echo "#ifndef $ac_prefix_conf_DEF"      >$tmp/pconfig.h
+    echo "#define $ac_prefix_conf_DEF 1" >>$tmp/pconfig.h
+    echo ' ' >>$tmp/pconfig.h
+
+    echo /'*' $ac_prefix_conf_OUT. Generated automatically at end of configure. '*'/ >>$tmp/pconfig.h
+    echo ' ' >>$tmp/pconfig.h
+
+    sed -f conftest.prefix $ac_prefix_conf_INP >>$tmp/pconfig.h
+    echo ' ' >>$tmp/pconfig.h
+    echo '/* once:' $ac_prefix_conf_DEF '*/' >>$tmp/pconfig.h
+    echo "#endif" >>$tmp/pconfig.h
+    if cmp -s $ac_prefix_conf_OUT $tmp/pconfig.h 2>/dev/null; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_prefix_conf_OUT is unchanged" >&5
+$as_echo "$as_me: $ac_prefix_conf_OUT is unchanged" >&6;}
+    else
+      ac_dir=`$as_dirname -- "$ac_prefix_conf_OUT" ||
+$as_expr X"$ac_prefix_conf_OUT" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$ac_prefix_conf_OUT" : 'X\(//\)[^/]' \| \
+	 X"$ac_prefix_conf_OUT" : 'X\(//\)$' \| \
+	 X"$ac_prefix_conf_OUT" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$ac_prefix_conf_OUT" |
+    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
+      rm -f "$ac_prefix_conf_OUT"
+      mv $tmp/pconfig.h "$ac_prefix_conf_OUT"
+    fi
+    cp conftest.prefix _configs.sed
+    rm _configs.sed
+  else
+    as_fn_error $? "input file $ac_prefix_conf_INP does not exist - skip generating $ac_prefix_conf_OUT" "$LINENO" 5
+  fi
+  rm -f conftest.*
+#fi
+ ;;
+    "depfiles":C) test x"$AMDEP_TRUE" != x"" || {
+  # Older Autoconf 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"`
+    # 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'`; 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, 2009, 2010, 2011 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="CXX "
+
+# ### BEGIN LIBTOOL CONFIG
+
+# 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
+
+# Shell to use when invoking shell scripts.
+SHELL=$lt_SHELL
+
+# An echo program that protects backslashes.
+ECHO=$lt_ECHO
+
+# The PATH separator for the build system.
+PATH_SEPARATOR=$lt_PATH_SEPARATOR
+
+# 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
+
+# convert \$build file names to \$host format.
+to_host_file_cmd=$lt_cv_to_host_file_cmd
+
+# convert \$build files to toolchain format.
+to_tool_file_cmd=$lt_cv_to_tool_file_cmd
+
+# An object symbol dumper.
+OBJDUMP=$lt_OBJDUMP
+
+# 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
+
+# How to find potential files when deplibs_check_method = "file_magic".
+file_magic_glob=$lt_file_magic_glob
+
+# Find potential files using nocaseglob when deplibs_check_method = "file_magic".
+want_nocaseglob=$lt_want_nocaseglob
+
+# DLL creation program.
+DLLTOOL=$lt_DLLTOOL
+
+# Command to associate shared and link libraries.
+sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd
+
+# The archiver.
+AR=$lt_AR
+
+# Flags to create an archive.
+AR_FLAGS=$lt_AR_FLAGS
+
+# How to feed a file listing to the archiver.
+archiver_list_spec=$lt_archiver_list_spec
+
+# 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
+
+# Whether to use a lock for old archive extraction.
+lock_old_archive_extraction=$lock_old_archive_extraction
+
+# 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
+
+# Specify filename containing input files for \$NM.
+nm_file_list_spec=$lt_nm_file_list_spec
+
+# The root where to search for dependent libraries,and in which our libraries should be installed.
+lt_sysroot=$lt_sysroot
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# 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
+
+# Manifest tool.
+MANIFEST_TOOL=$lt_MANIFEST_TOOL
+
+# 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
+
+# Permission mode override for installation of shared libraries.
+install_override_mode=$lt_install_override_mode
+
+# 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
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag
+reload_cmds=$lt_reload_cmds
+
+# 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
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_lt_prog_compiler_pic
+
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl
+
+# 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
+
+# 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
+
+# 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
+
+# Commands necessary for finishing linking programs.
+postlink_cmds=$lt_postlink_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
+
+# The directories searched by this compiler when creating a shared library.
+compiler_lib_search_dirs=$lt_compiler_lib_search_dirs
+
+# Dependencies to place before and after the objects being linked to
+# create a shared library.
+predep_objects=$lt_predep_objects
+postdep_objects=$lt_postdep_objects
+predeps=$lt_predeps
+postdeps=$lt_postdeps
+
+# The library search path used internally by the compiler when linking
+# a shared library.
+compiler_lib_search_path=$lt_compiler_lib_search_path
+
+# ### 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 '$q' "$ltmain" >> "$cfgfile" \
+     || (rm -f "$cfgfile"; exit 1)
+
+  if test x"$xsi_shell" = xyes; then
+  sed -e '/^func_dirname ()$/,/^} # func_dirname /c\
+func_dirname ()\
+{\
+\    case ${1} in\
+\      */*) func_dirname_result="${1%/*}${2}" ;;\
+\      *  ) func_dirname_result="${3}" ;;\
+\    esac\
+} # Extended-shell func_dirname implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_basename ()$/,/^} # func_basename /c\
+func_basename ()\
+{\
+\    func_basename_result="${1##*/}"\
+} # Extended-shell func_basename implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_dirname_and_basename ()$/,/^} # func_dirname_and_basename /c\
+func_dirname_and_basename ()\
+{\
+\    case ${1} in\
+\      */*) func_dirname_result="${1%/*}${2}" ;;\
+\      *  ) func_dirname_result="${3}" ;;\
+\    esac\
+\    func_basename_result="${1##*/}"\
+} # Extended-shell func_dirname_and_basename implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_stripname ()$/,/^} # func_stripname /c\
+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}"}\
+} # Extended-shell func_stripname implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_split_long_opt ()$/,/^} # func_split_long_opt /c\
+func_split_long_opt ()\
+{\
+\    func_split_long_opt_name=${1%%=*}\
+\    func_split_long_opt_arg=${1#*=}\
+} # Extended-shell func_split_long_opt implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_split_short_opt ()$/,/^} # func_split_short_opt /c\
+func_split_short_opt ()\
+{\
+\    func_split_short_opt_arg=${1#??}\
+\    func_split_short_opt_name=${1%"$func_split_short_opt_arg"}\
+} # Extended-shell func_split_short_opt implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_lo2o ()$/,/^} # func_lo2o /c\
+func_lo2o ()\
+{\
+\    case ${1} in\
+\      *.lo) func_lo2o_result=${1%.lo}.${objext} ;;\
+\      *)    func_lo2o_result=${1} ;;\
+\    esac\
+} # Extended-shell func_lo2o implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_xform ()$/,/^} # func_xform /c\
+func_xform ()\
+{\
+    func_xform_result=${1%.*}.lo\
+} # Extended-shell func_xform implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_arith ()$/,/^} # func_arith /c\
+func_arith ()\
+{\
+    func_arith_result=$(( $* ))\
+} # Extended-shell func_arith implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_len ()$/,/^} # func_len /c\
+func_len ()\
+{\
+    func_len_result=${#1}\
+} # Extended-shell func_len implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+fi
+
+if test x"$lt_shell_append" = xyes; then
+  sed -e '/^func_append ()$/,/^} # func_append /c\
+func_append ()\
+{\
+    eval "${1}+=\\${2}"\
+} # Extended-shell func_append implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_append_quoted ()$/,/^} # func_append_quoted /c\
+func_append_quoted ()\
+{\
+\    func_quote_for_eval "${2}"\
+\    eval "${1}+=\\\\ \\$func_quote_for_eval_result"\
+} # Extended-shell func_append_quoted implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  # Save a `func_append' function call where possible by direct use of '+='
+  sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \
+    && mv -f "$cfgfile.tmp" "$cfgfile" \
+      || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+  test 0 -eq $? || _lt_function_replace_fail=:
+else
+  # Save a `func_append' function call even when '+=' is not available
+  sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \
+    && mv -f "$cfgfile.tmp" "$cfgfile" \
+      || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+  test 0 -eq $? || _lt_function_replace_fail=:
+fi
+
+if test x"$_lt_function_replace_fail" = x":"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to substitute extended shell functions in $ofile" >&5
+$as_echo "$as_me: WARNING: Unable to substitute extended shell functions in $ofile" >&2;}
+fi
+
+
+   mv -f "$cfgfile" "$ofile" ||
+    (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
+  chmod +x "$ofile"
+
+
+    cat <<_LT_EOF >> "$ofile"
+
+# ### BEGIN LIBTOOL TAG CONFIG: CXX
+
+# The linker used to build libraries.
+LD=$lt_LD_CXX
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag_CXX
+reload_cmds=$lt_reload_cmds_CXX
+
+# Commands used to build an old-style archive.
+old_archive_cmds=$lt_old_archive_cmds_CXX
+
+# A language specific compiler.
+CC=$lt_compiler_CXX
+
+# Is the compiler the GNU compiler?
+with_gcc=$GCC_CXX
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_CXX
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_lt_prog_compiler_pic_CXX
+
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl_CXX
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_lt_prog_compiler_static_CXX
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_lt_cv_prog_compiler_c_o_CXX
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$archive_cmds_need_lc_CXX
+
+# Whether or not to disallow shared libs when runtime libs are static.
+allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_CXX
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_CXX
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_whole_archive_flag_spec_CXX
+
+# Whether the compiler copes with passing no objects directly.
+compiler_needs_object=$lt_compiler_needs_object_CXX
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_CXX
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_CXX
+
+# Commands used to build a shared archive.
+archive_cmds=$lt_archive_cmds_CXX
+archive_expsym_cmds=$lt_archive_expsym_cmds_CXX
+
+# Commands used to build a loadable module if different from building
+# a shared archive.
+module_cmds=$lt_module_cmds_CXX
+module_expsym_cmds=$lt_module_expsym_cmds_CXX
+
+# Whether we are building with GNU ld or not.
+with_gnu_ld=$lt_with_gnu_ld_CXX
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_allow_undefined_flag_CXX
+
+# Flag that enforces no undefined symbols.
+no_undefined_flag=$lt_no_undefined_flag_CXX
+
+# 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_CXX
+
+# Whether we need a single "-rpath" flag with a separated argument.
+hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX
+
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
+# DIR into the resulting binary.
+hardcode_direct=$hardcode_direct_CXX
+
+# 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_CXX
+
+# Set to "yes" if using the -LDIR flag during linking hardcodes DIR
+# into the resulting binary.
+hardcode_minus_L=$hardcode_minus_L_CXX
+
+# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
+# into the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var_CXX
+
+# 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_CXX
+
+# Set to yes if linker adds runtime paths of dependent libraries
+# to runtime path list.
+inherit_rpath=$inherit_rpath_CXX
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$link_all_deplibs_CXX
+
+# Set to "yes" if exported symbols are required.
+always_export_symbols=$always_export_symbols_CXX
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_export_symbols_cmds_CXX
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_exclude_expsyms_CXX
+
+# Symbols that must always be exported.
+include_expsyms=$lt_include_expsyms_CXX
+
+# Commands necessary for linking programs (against libraries) with templates.
+prelink_cmds=$lt_prelink_cmds_CXX
+
+# Commands necessary for finishing linking programs.
+postlink_cmds=$lt_postlink_cmds_CXX
+
+# Specify filename containing input files.
+file_list_spec=$lt_file_list_spec_CXX
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action_CXX
+
+# The directories searched by this compiler when creating a shared library.
+compiler_lib_search_dirs=$lt_compiler_lib_search_dirs_CXX
+
+# Dependencies to place before and after the objects being linked to
+# create a shared library.
+predep_objects=$lt_predep_objects_CXX
+postdep_objects=$lt_postdep_objects_CXX
+predeps=$lt_predeps_CXX
+postdeps=$lt_postdeps_CXX
+
+# The library search path used internally by the compiler when linking
+# a shared library.
+compiler_lib_search_path=$lt_compiler_lib_search_path_CXX
+
+# ### END LIBTOOL TAG CONFIG: CXX
+_LT_EOF
+
+ ;;
+
+  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 1
+fi
+
+#
+# CONFIG_SUBDIRS section.
+#
+if test "$no_recursion" != yes; then
+
+  # Remove --cache-file, --srcdir, and --disable-option-checking arguments
+  # so they do not pile up.
+  ac_sub_configure_args=
+  ac_prev=
+  eval "set x $ac_configure_args"
+  shift
+  for ac_arg
+  do
+    if test -n "$ac_prev"; then
+      ac_prev=
+      continue
+    fi
+    case $ac_arg in
+    -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=*)
+      ;;
+    --config-cache | -C)
+      ;;
+    -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+      ac_prev=srcdir ;;
+    -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+      ;;
+    -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+      ac_prev=prefix ;;
+    -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+      ;;
+    --disable-option-checking)
+      ;;
+    *)
+      case $ac_arg in
+      *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+      esac
+      as_fn_append ac_sub_configure_args " '$ac_arg'" ;;
+    esac
+  done
+
+  # Always prepend --prefix to ensure using the same prefix
+  # in subdir configurations.
+  ac_arg="--prefix=$prefix"
+  case $ac_arg in
+  *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+  esac
+  ac_sub_configure_args="'$ac_arg' $ac_sub_configure_args"
+
+  # Pass --silent
+  if test "$silent" = yes; then
+    ac_sub_configure_args="--silent $ac_sub_configure_args"
+  fi
+
+  # Always prepend --disable-option-checking to silence warnings, since
+  # different subdirs can have different --enable and --with options.
+  ac_sub_configure_args="--disable-option-checking $ac_sub_configure_args"
+
+  ac_popdir=`pwd`
+  for ac_dir in : $subdirs; do test "x$ac_dir" = x: && continue
+
+    # Do not complain, so a configure script can configure whichever
+    # parts of a large source tree are present.
+    test -d "$srcdir/$ac_dir" || continue
+
+    ac_msg="=== configuring in $ac_dir (`pwd`/$ac_dir)"
+    $as_echo "$as_me:${as_lineno-$LINENO}: $ac_msg" >&5
+    $as_echo "$ac_msg" >&6
+    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
+
+
+    cd "$ac_dir"
+
+    # Check for guested configure; otherwise get Cygnus style configure.
+    if test -f "$ac_srcdir/configure.gnu"; then
+      ac_sub_configure=$ac_srcdir/configure.gnu
+    elif test -f "$ac_srcdir/configure"; then
+      ac_sub_configure=$ac_srcdir/configure
+    elif test -f "$ac_srcdir/configure.in"; then
+      # This should be Cygnus configure.
+      ac_sub_configure=$ac_aux_dir/configure
+    else
+      { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: no configuration information is in $ac_dir" >&5
+$as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2;}
+      ac_sub_configure=
+    fi
+
+    # The recursion is here.
+    if test -n "$ac_sub_configure"; then
+      # Make the cache file name correct relative to the subdirectory.
+      case $cache_file in
+      [\\/]* | ?:[\\/]* ) ac_sub_cache_file=$cache_file ;;
+      *) # Relative name.
+	ac_sub_cache_file=$ac_top_build_prefix$cache_file ;;
+      esac
+
+      { $as_echo "$as_me:${as_lineno-$LINENO}: running $SHELL $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_srcdir" >&5
+$as_echo "$as_me: running $SHELL $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_srcdir" >&6;}
+      # The eval makes quoting arguments work.
+      eval "\$SHELL \"\$ac_sub_configure\" $ac_sub_configure_args \
+	   --cache-file=\"\$ac_sub_cache_file\" --srcdir=\"\$ac_srcdir\"" ||
+	as_fn_error $? "$ac_sub_configure failed for $ac_dir" "$LINENO" 5
+    fi
+
+    cd "$ac_popdir"
+  done
+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.ac b/configure.ac
new file mode 100644
index 0000000..0a99032
--- /dev/null
+++ b/configure.ac
@@ -0,0 +1,269 @@
+AC_INIT([singular], [4.0.1], [singular at mathematik.uni-kl.de])
+AC_DEFINE([VERSION_DATE],["Sep 2014"],[release date])
+
+_AC_SRCDIRS(["$ac_dir"])
+
+AC_CONFIG_MACRO_DIR([m4])
+AC_CONFIG_AUX_DIR([build-aux])
+
+AC_CONFIG_SRCDIR([Singular/tesths.cc])
+
+AC_CONFIG_HEADER([_config.h])
+# Add pre'prefixed config
+AX_PREFIX_CONFIG_H([singularconfig.h],[],[_config.h])
+
+dnl Apparently, this is required for using an AC_CHECK_HEADER within AS_IF(...), at least on Cygwin.
+AC_USE_SYSTEM_EXTENSIONS
+
+AM_MAINTAINER_MODE([enable])
+AM_INIT_AUTOMAKE([-Wall foreign subdir-objects]) # -Wno-extra-portability -Werror silent-rules
+
+m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
+
+dnl Check if build env is sane
+AM_SANITY_CHECK
+
+
+SING_RESET_FLAGS()
+SING_CHECK_SET_ARGS()
+
+#!
+# AC_PROG_CC
+# AC_PROG_CXX
+AC_PROG_CPP
+AC_PROG_CXXCPP
+AM_PROG_CC_C_O
+### AM_PROG_LEX
+AC_PROG_LN_S
+AC_PROG_INSTALL
+m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
+
+AC_HEADER_STDC
+AC_CHECK_HEADERS(unistd.h iostream.h sys/time.h sys/times.h asm/sigcontext.h)
+
+AC_CHECK_FUNCS(readlink getcwd getwd setenv putenv qsort_r)
+
+AC_CHECK_PROGS([DOXYGEN], [doxygen])
+if test -z "$DOXYGEN";
+   then AC_MSG_WARN([Doxygen not found - continuing without Doxygen support])
+fi
+AM_CONDITIONAL([HAVE_DOXYGEN], [test -n "$DOXYGEN"])
+
+LT_INIT
+
+link_all_deplibs=yes
+link_all_deplibs_CXX=yes
+
+# Checks for libraries.
+
+# This test for -lpthread etc has to come before AX_PTHREAD,
+# because libtool tends to ignore -pthread in linking shared C++-libs
+# see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=25460
+# (happens with ubuntu 14.04)
+AC_SEARCH_LIBS(sem_wait,[rt pthreads pthread],[],[
+  AC_MSG_ERROR([sem_wait not found in rt,pthreads,pthread])
+])
+
+#AC_CHECK_LIB(pthread,pthread_create)
+AX_PTHREAD([], [
+  AC_MSG_ERROR([Pthread library not found. Please set PTHREAD_CFLAGS and PTHREAD_LIBS correctly for your setup])
+])
+
+AC_MSG_CHECKING([Found Pthread, PTHREAD_CC:])
+AC_MSG_RESULT(${PTHREAD_CC:-unset})
+AC_MSG_CHECKING([               PTHREAD_CFLAGS:])
+AC_MSG_RESULT(${PTHREAD_CFLAGS:-unset})
+AC_MSG_CHECKING([               PTHREAD_LIBS:])
+AC_MSG_RESULT(${PTHREAD_LIBS:-unset})
+
+# Set the correct PTHREAD flags and, if needed, change the compiler to one that is pthread-enabled.
+CC="$PTHREAD_CC"
+CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+LDFLAGS="$LDFLAGS $PTHREAD_LDFLAGS"
+
+AC_SUBST(PTHREAD_CFLAGS)
+AC_SUBST(PTHREAD_LDFLAGS)
+AC_SUBST(PTHREAD_LIBS)
+AC_SUBST(CC)
+
+
+AC_CHECK_LIB(rt,clock_gettime)
+
+LB_CHECK_GMP(4.0,,AC_MSG_ERROR([Unable to find GMP on your machine: please use --with-gmp=PATH_TO_DIR_CONTAINING_LIB_AND_INCLUDE (see also ./configure --help if you do not understand what we are talking about)]))
+LB_CHECK_NTL(5.0,,AC_MSG_WARN([Unable to find NTL (which is strongly recommended) on your machine: please use --with-ntl=PATH_TO_DIR_CONTAINING_LIB_AND_INCLUDE (see also ./configure --help if you do not understand what we are talking about)]))
+LB_CHECK_FLINT(2.3,,AC_MSG_WARN([Unable to find FLINT (which is strongly recommended) on your machine: please use --with-flint=PATH_TO_DIR_CONTAINING_LIB_AND_INCLUDE (see also ./configure --help if you do not understand what we are talking about)]))
+
+AC_CONFIG_GOOGLE_PERFTOOLS()
+
+AX_PYTHON_DEFAULT()
+AX_PYTHON_WITH_VERSION([2.4])
+
+LB_CHECK_MATHICGB
+
+AC_FUNC_ERROR_AT_LINE
+AC_FUNC_MALLOC
+
+# check for cpu properties
+AC_CHECK_SIZEOF(long,4)
+SING_CHECK_CPU
+
+#check for host:
+AC_CANONICAL_HOST
+
+case $host_os in
+  *cygwin* ) AX_APPEND_LINK_FLAGS([-Wl,-Bdynamic]);;
+esac
+
+PKG_REQUIRE="$PKG_REQUIRE"
+AC_SUBST(PKG_REQUIRE)
+
+SING_USE_OMALLOC()
+SING_USE_RESOURCES()
+SING_USE_FACTORY()
+
+SING_CHECK_P_PROCS
+SING_CHECK_READLINE
+SING_CHECK_DBM
+
+SING_CHECK_GFANLIB
+SING_CHECK_POLYMAKE
+
+SING_CHECK_PLURAL
+
+SING_BUILTIN_MODULES
+
+### the following is needed due to the use of om_sing_opt_show_mem in misc_ip.cc...
+#ac_configure_args="$ac_configure_args --with-external-config_h=../Singular/omSingularConfig.h"
+
+AC_ARG_ENABLE(countedref, AS_HELP_STRING([--enable-countedref], [Enable autoloading of reference counted types]),
+[if test "x$enableval" = "xyes"; then
+ENABLE_COUNTEDREF_AUTOLOAD=yes
+fi], ENABLE_COUNTEDREF_AUTOLOAD=no)
+
+if test x"${ENABLE_COUNTEDREF_AUTOLOAD}" == xyes; then
+  AC_DEFINE([SI_COUNTEDREF_AUTOLOAD],1,[Enable autoloading of reference counted types])
+  AC_SUBST(SI_COUNTEDREF_AUTOLOAD)
+fi
+
+dnl AC_CONFIG_FILES conditionalization requires using AM_COND_IF, however
+dnl AM_COND_IF is new to Automake 1.11.  To use it on new Automake without
+dnl requiring same, a fallback implementation for older Autoconf is provided.
+dnl Note that disabling of AC_CONFIG_FILES requires Automake 1.11, this code
+dnl is correct only in terms of m4sh generated script.
+m4_ifndef([AM_COND_IF], [AC_DEFUN([AM_COND_IF], [
+if test -z "$$1_TRUE"; then :
+  m4_n([$2])[]dnl
+m4_ifval([$3],
+[else
+    $3
+])dnl
+fi[]dnl
+])])
+
+
+AC_DEFINE_UNQUOTED([CC],"$CC",[CC])
+AC_DEFINE_UNQUOTED([CXX],"$CXX",[CXX])
+AC_DEFINE_UNQUOTED([CFLAGS],"$CFLAGS",[CFLAGS])
+AC_DEFINE_UNQUOTED([CXXFLAGS],"$CXXFLAGS",[CXXFLAGS])
+AC_DEFINE_UNQUOTED([DEFS],"$DEFS",[DEFS])
+AC_DEFINE_UNQUOTED([CPPFLAGS],"$CPPFLAGS",[CPPFLAGS])
+AC_DEFINE_UNQUOTED([LDFLAGS],"$LDFLAGS",[LDFLAGS])
+AC_DEFINE_UNQUOTED([LIBS],"$LIBS",[LIBS])
+AC_DEFINE_UNQUOTED([AC_CONFIGURE_ARGS],"$ac_configure_args",[ac_configure_args])
+# AC_DEFINE_UNQUOTED([AC_CT_CC], "$ac_ct_CC",[ac_ct_CC])
+
+AC_DEFINE_UNQUOTED([NTL_CFLAGS],"$NTL_CFLAGS",[NTL_CFLAGS])
+AC_DEFINE_UNQUOTED([NTL_LIBS],"$NTL_LIBS",[NTL_LIBS])
+
+AC_DEFINE_UNQUOTED([GMP_CFLAGS],"$GMP_CFLAGS",[GMP_CFLAGS])
+AC_DEFINE_UNQUOTED([GMP_LIBS],"$GMP_LIBS",[GMP_LIBS])
+
+AC_DEFINE_UNQUOTED([FLINT_CFLAGS],"$FLINT_CFLAGS",[FLINT_CFLAGS])
+AC_DEFINE_UNQUOTED([FLINT_LIBS],"$FLINT_LIBS",[FLINT_LIBS])
+
+##### SEE http://www.gnu.org/prep/standards/html_node/Directory-Variables.html
+
+AX_RECURSIVE_EVAL([[$]prefix], [config_prefix])
+AX_NORMALIZE_PATH([config_prefix],['/'])
+AC_DEFINE_UNQUOTED([PREFIX],"$config_prefix",[prefix])
+
+AX_RECURSIVE_EVAL([[$]exec_prefix], [config_exec_prefix])
+AX_NORMALIZE_PATH([config_exec_prefix],['/'])
+AC_DEFINE_UNQUOTED([EXEC_PREFIX],"$config_exec_prefix",[exec_prefix])
+
+AX_RECURSIVE_EVAL([[$]libexecdir], [config_libexecdir])
+AX_NORMALIZE_PATH([config_libexecdir],['/'])
+AC_DEFINE_UNQUOTED([LIBEXEC_DIR],"$config_libexecdir",[libexecdir])
+
+AX_RECURSIVE_EVAL([[$]libdir], [config_libdir])
+AX_NORMALIZE_PATH([config_libdir],['/'])
+AC_DEFINE_UNQUOTED([LIB_DIR],"$config_libdir",[libdir])
+
+AX_RECURSIVE_EVAL([[$]bindir], [config_bindir])
+AX_NORMALIZE_PATH([config_bindir],['/'])
+AC_DEFINE_UNQUOTED([BIN_DIR],"$config_bindir",[bindir])
+
+AX_RECURSIVE_EVAL([[$]datadir], [config_datadir])
+AX_NORMALIZE_PATH([config_datadir],['/'])
+AC_DEFINE_UNQUOTED([DATA_DIR],"$config_datadir",[datadir])
+AC_SUBST(DATA_DIR)
+
+AX_RECURSIVE_EVAL([[$]docdir], [config_docdir])
+AX_NORMALIZE_PATH([config_docdir],['/'])
+AC_DEFINE_UNQUOTED([DOC_DIR],"$config_docdir",[docdir])
+AC_SUBST(DOC_DIR)
+
+SING_SHOW_FLAGS([Compiler/linker flags: ])
+
+
+## AM_COND_IF([HAVE_DOXYGEN], [AC_CONFIG_FILES([dox/Doxyfile])])
+
+AC_CONFIG_FILES([dox/Makefile])
+
+AC_CONFIG_SUBDIRS([resources])
+AC_CONFIG_SUBDIRS([omalloc])
+
+if test "x$ENABLE_FACTORY" = xyes; then
+ AC_CONFIG_SUBDIRS([factory])
+fi
+
+AC_CONFIG_SUBDIRS([libpolys])
+
+AC_CONFIG_FILES([Makefile])
+AC_CONFIG_FILES([xalloc/Makefile])
+AC_CONFIG_FILES([kernel/Makefile])
+AC_CONFIG_FILES([kernel/numeric/Makefile])
+AC_CONFIG_FILES([kernel/fglm/Makefile])
+AC_CONFIG_FILES([kernel/groebner_walk/Makefile])
+AC_CONFIG_FILES([kernel/combinatorics/Makefile])
+AC_CONFIG_FILES([kernel/spectrum/Makefile])
+AC_CONFIG_FILES([kernel/linear_algebra/Makefile])
+AC_CONFIG_FILES([kernel/maps/Makefile])
+AC_CONFIG_FILES([kernel/GBEngine/Makefile])
+AC_CONFIG_FILES([kernel/oswrapper/Makefile])
+
+AC_CONFIG_SUBDIRS([gfanlib])
+
+AC_CONFIG_FILES([Singular/dyn_modules/Makefile])
+AC_CONFIG_FILES([Singular/dyn_modules/bigintm/Makefile])
+AC_CONFIG_FILES([Singular/dyn_modules/Order/Makefile])
+AC_CONFIG_FILES([Singular/dyn_modules/syzextra/Makefile])
+AC_CONFIG_FILES([Singular/dyn_modules/gfanlib/Makefile])
+AC_CONFIG_FILES([Singular/dyn_modules/polymake/Makefile])
+AC_CONFIG_FILES([Singular/dyn_modules/pyobject/Makefile])
+AC_CONFIG_FILES([Singular/dyn_modules/singmathic/Makefile])
+AC_CONFIG_FILES([Singular/dyn_modules/staticdemo/Makefile])
+
+AC_CONFIG_FILES([Singular/Makefile])
+
+AC_CONFIG_FILES([IntegerProgramming/Makefile])
+
+AC_CONFIG_FILES([libsingular-config Singular.pc])
+
+AC_CONFIG_FILES([emacs/Makefile])
+
+AC_CONFIG_FILES([desktop/Makefile desktop/Singular.desktop desktop/Singular-manual.desktop])
+
+AC_CONFIG_FILES([singular.spec])
+
+AC_OUTPUT
diff --git a/desktop/Makefile.am b/desktop/Makefile.am
new file mode 100644
index 0000000..711e41e
--- /dev/null
+++ b/desktop/Makefile.am
@@ -0,0 +1,10 @@
+ACLOCAL_AMFLAGS = -I ../m4
+
+iconsdir = $(datadir)/icons
+icons_DATA = Singular.png
+
+desktopdir = $(datadir)/applications
+desktop_DATA = Singular.desktop Singular-manual.desktop
+
+desktop_in = Singular.desktop.in Singular-manual.desktop.in
+EXTRA_DIST = $(icons_DATA) $(desktop_in)
diff --git a/desktop/Makefile.in b/desktop/Makefile.in
new file mode 100644
index 0000000..19a87f9
--- /dev/null
+++ b/desktop/Makefile.in
@@ -0,0 +1,583 @@
+# Makefile.in generated by automake 1.13.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 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@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+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.in $(srcdir)/Makefile.am \
+	$(srcdir)/Singular.desktop.in \
+	$(srcdir)/Singular-manual.desktop.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_append_compile_flags.m4 \
+	$(top_srcdir)/m4/ax_append_flag.m4 \
+	$(top_srcdir)/m4/ax_append_link_flags.m4 \
+	$(top_srcdir)/m4/ax_check_compile_flag.m4 \
+	$(top_srcdir)/m4/ax_check_link_flag.m4 \
+	$(top_srcdir)/m4/ax_compute_relative_paths.m4 \
+	$(top_srcdir)/m4/ax_normalize_path.m4 \
+	$(top_srcdir)/m4/ax_prefix_config_h.m4 \
+	$(top_srcdir)/m4/ax_pthread.m4 \
+	$(top_srcdir)/m4/ax_python_embed.m4 \
+	$(top_srcdir)/m4/ax_python_with_version.m4 \
+	$(top_srcdir)/m4/cpu-check.m4 $(top_srcdir)/m4/dbm-check.m4 \
+	$(top_srcdir)/m4/flags.m4 $(top_srcdir)/m4/flint-check.m4 \
+	$(top_srcdir)/m4/gfanlib-check.m4 \
+	$(top_srcdir)/m4/gmp-check.m4 \
+	$(top_srcdir)/m4/google-perftools.m4 \
+	$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+	$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+	$(top_srcdir)/m4/lt~obsolete.m4 \
+	$(top_srcdir)/m4/mathic-check.m4 $(top_srcdir)/m4/ntl-check.m4 \
+	$(top_srcdir)/m4/options.m4 $(top_srcdir)/m4/p-procs.m4 \
+	$(top_srcdir)/m4/polymake-check.m4 \
+	$(top_srcdir)/m4/readline-check.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/_config.h
+CONFIG_CLEAN_FILES = Singular.desktop Singular-manual.desktop
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_ at AM_V@)
+am__v_P_ = $(am__v_P_ at AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_ at AM_V@)
+am__v_GEN_ = $(am__v_GEN_ at AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_ at AM_V@)
+am__v_at_ = $(am__v_at_ at AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+SOURCES =
+DIST_SOURCES =
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+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__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
+am__installdirs = "$(DESTDIR)$(desktopdir)" "$(DESTDIR)$(iconsdir)"
+DATA = $(desktop_DATA) $(icons_DATA)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BUILTIN_LIBS = @BUILTIN_LIBS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CDDGMPCPPFLAGS = @CDDGMPCPPFLAGS@
+CDDGMPLDFLAGS = @CDDGMPLDFLAGS@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATA_DIR = @DATA_DIR@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DOC_DIR = @DOC_DIR@
+DOXYGEN = @DOXYGEN@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FACTORY_INCLUDES = @FACTORY_INCLUDES@
+FACTORY_LIBS = @FACTORY_LIBS@
+FGREP = @FGREP@
+FLINT_CFLAGS = @FLINT_CFLAGS@
+FLINT_HOME = @FLINT_HOME@
+FLINT_LIBS = @FLINT_LIBS@
+GMP_CFLAGS = @GMP_CFLAGS@
+GMP_HOME = @GMP_HOME@
+GMP_LIBS = @GMP_LIBS@
+GMP_VERSION = @GMP_VERSION@
+GREP = @GREP@
+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@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NTL_CFLAGS = @NTL_CFLAGS@
+NTL_LIBS = @NTL_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OMALLOC_INCLUDES = @OMALLOC_INCLUDES@
+OMALLOC_LIBS = @OMALLOC_LIBS@
+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@
+PKG_REQUIRE = @PKG_REQUIRE@
+PMCONFIG = @PMCONFIG@
+PM_CFLAGS = @PM_CFLAGS@
+PM_INC = @PM_INC@
+PM_LDFLAGS = @PM_LDFLAGS@
+PM_LIBS = @PM_LIBS@
+POLYMAKE_CXXFLAGS = @POLYMAKE_CXXFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LDFLAGS = @PTHREAD_LDFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
+PYTHON = @PYTHON@
+PYTHON_CSPEC = @PYTHON_CSPEC@
+PYTHON_EXECPREFIX = @PYTHON_EXECPREFIX@
+PYTHON_LSPEC = @PYTHON_LSPEC@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+RANLIB = @RANLIB@
+RESOURCES_INCLUDES = @RESOURCES_INCLUDES@
+RESOURCES_LIBS = @RESOURCES_LIBS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SINGULAR_CFLAGS = @SINGULAR_CFLAGS@
+SI_COUNTEDREF_AUTOLOAD = @SI_COUNTEDREF_AUTOLOAD@
+SI_CPU_I386 = @SI_CPU_I386@
+SI_CPU_IA64 = @SI_CPU_IA64@
+SI_CPU_PPC = @SI_CPU_PPC@
+SI_CPU_SPARC = @SI_CPU_SPARC@
+SI_CPU_X86_64 = @SI_CPU_X86_64@
+STRIP = @STRIP@
+USEPPROCSDYNAMICLD = @USEPPROCSDYNAMICLD@
+USEPPROCSDYNAMICLDFLAGS = @USEPPROCSDYNAMICLDFLAGS@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
+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@
+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@
+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@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+ACLOCAL_AMFLAGS = -I ../m4
+iconsdir = $(datadir)/icons
+icons_DATA = Singular.png
+desktopdir = $(datadir)/applications
+desktop_DATA = Singular.desktop Singular-manual.desktop
+desktop_in = Singular.desktop.in Singular-manual.desktop.in
+EXTRA_DIST = $(icons_DATA) $(desktop_in)
+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) --foreign desktop/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign 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):
+Singular.desktop: $(top_builddir)/config.status $(srcdir)/Singular.desktop.in
+	cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+Singular-manual.desktop: $(top_builddir)/config.status $(srcdir)/Singular-manual.desktop.in
+	cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+install-desktopDATA: $(desktop_DATA)
+	@$(NORMAL_INSTALL)
+	@list='$(desktop_DATA)'; test -n "$(desktopdir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(desktopdir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(desktopdir)" || exit 1; \
+	fi; \
+	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)$(desktopdir)'"; \
+	  $(INSTALL_DATA) $$files "$(DESTDIR)$(desktopdir)" || exit $$?; \
+	done
+
+uninstall-desktopDATA:
+	@$(NORMAL_UNINSTALL)
+	@list='$(desktop_DATA)'; test -n "$(desktopdir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	dir='$(DESTDIR)$(desktopdir)'; $(am__uninstall_files_from_dir)
+install-iconsDATA: $(icons_DATA)
+	@$(NORMAL_INSTALL)
+	@list='$(icons_DATA)'; test -n "$(iconsdir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(iconsdir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(iconsdir)" || exit 1; \
+	fi; \
+	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|^.*/||'`; \
+	dir='$(DESTDIR)$(iconsdir)'; $(am__uninstall_files_from_dir)
+tags TAGS:
+
+ctags CTAGS:
+
+cscope cscopelist:
+
+
+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)$(desktopdir)" "$(DESTDIR)$(iconsdir)"; 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:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+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-desktopDATA install-iconsDATA
+
+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-desktopDATA uninstall-iconsDATA
+
+.MAKE: install-am install-strip
+
+.PHONY: all all-am check check-am clean clean-generic clean-libtool \
+	cscopelist-am ctags-am distclean distclean-generic \
+	distclean-libtool distdir dvi dvi-am html html-am info info-am \
+	install install-am install-data install-data-am \
+	install-desktopDATA 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-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 tags-am uninstall \
+	uninstall-am uninstall-desktopDATA uninstall-iconsDATA
+
+
+# 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/Singular-manual.desktop.in b/desktop/Singular-manual.desktop.in
new file mode 100644
index 0000000..38d0763
--- /dev/null
+++ b/desktop/Singular-manual.desktop.in
@@ -0,0 +1,15 @@
+[Desktop Entry]
+Version=@PACKAGE_VERSION@
+Name=Singular Manual
+Name[de]=Singular-Handbuch
+Comment=read the user manual for Singular @PACKAGE_VERSION@
+Comment[de]=im Benutzerhandbuch zu Singular @PACKAGE_VERSION@ lesen
+Comment[es]=
+Comment[fr]=lire le manuel d'utilisation de Singular @PACKAGE_VERSION@
+Comment[ru]=
+Type=Link
+URL=file://@DOC_DIR@/html/index.htm
+Icon=@DATA_DIR@/icons/Singular.png
+Categories=Math;Science;Development;Education;Documentation;
+Encoding=UTF-8
+
diff --git a/desktop/Singular.desktop.in b/desktop/Singular.desktop.in
new file mode 100644
index 0000000..b7b5f56
--- /dev/null
+++ b/desktop/Singular.desktop.in
@@ -0,0 +1,15 @@
+[Desktop Entry]
+Version=@PACKAGE_VERSION@
+Name=Singular
+Comment=run Singular @PACKAGE_VERSION@ in a terminal
+Comment[de]=Singular @PACKAGE_VERSION@ in einem Terminal starten
+Comment[es]=
+Comment[fr]=d�marrer Singular @PACKAGE_VERSION@ dans un terminal
+Comment[ru]=
+Type=Application
+Exec=Singular
+Terminal=true
+Categories=Math;Science;Education;
+Icon=@DATA_DIR@/icons/Singular.png
+Encoding=UTF-8
+
diff --git a/desktop/Singular.png b/desktop/Singular.png
new file mode 100644
index 0000000..b26d700
Binary files /dev/null and b/desktop/Singular.png differ
diff --git a/doc/ESingular.man b/doc/ESingular.man
new file mode 100644
index 0000000..59452df
--- /dev/null
+++ b/doc/ESingular.man
@@ -0,0 +1,43 @@
+.\" DO NOT MODIFY THIS FILE!  It was generated by help2man 1.40.11.
+.TH ESINGULAR "1" "January 2014" "ESingular 4.0.0" "User Commands"
+.SH NAME
+ESingular \- manual page for ESingular 4.0.0
+.SH DESCRIPTION
+ESingular: A Program that starts\-up Singular within emacs, for
+Singular version 4.0.0 \fB\-\-\fR a CAS for polynomial computations. Usage:
+.IP
+ESingular [options] [file]
+.SH OPTIONS
+.TP
+\-
 \fB\-\-emacs\fR=\fIEMACS\fR
+Use EMACS as emacs program to run Singular
+.TP
+\-
 \fB\-\-emacs\-dir\fR=\fIDIR\fR
+Use DIR as directory to look for emacs lisp files
+.TP
+\-
 \fB\-\-emacs\-load\fR=\fIFILE\fR
+Load FILE on emacs start\-up, instead of default
+.TP
+\-
 \fB\-\-singular\fR=\fIPROG\fR
+Start PROG as Singular program within emacs
+.TP
+\-
 \fB\-\-no\-call\fR
+Do not start program. Print call to stdout
+.TP
+all other options are passed to Singular.
+.PP
+For more information, type `help;' from within Singular or visit
+http://www.singular.uni\-kl.de or consult the
+Singular manual (available as on\-line info or html manual).
+.SH "SEE ALSO"
+The full documentation for
+.B Singular
+is maintained as a Texinfo manual.  If the
+.B info
+and
+.B Singular
+programs are properly installed at your site, the command
+.IP
+.B info Singular
+.PP
+should give you access to the complete manual.
diff --git a/doc/Singular.man b/doc/Singular.man
new file mode 100644
index 0000000..28d092f
--- /dev/null
+++ b/doc/Singular.man
@@ -0,0 +1,101 @@
+.\" DO NOT MODIFY THIS FILE!  It was generated by help2man 1.36.
+.TH SINGULAR "1" "2013" "Singular" "User Commands"
+.SH NAME
+Singular \- manual page for Singular for version 4-x-x
+.SH DESCRIPTION
+.SS "Singular -- a CAS for polynomial computations."
+.SS "ESingular: starts-up Singular within emacs."
+.SS "TSingular: starts-up Singular within a new terminal"
+.IP
+.SH SYNTAX
+.B \&Singular [options] [file1 [file2 ...]]
+
+.B \&ESingular [options] [file1 [file2 ...]]
+
+.B \&TSingular [options] [file1 [file2 ...]]
+
+.SH OPTIONS
+.TP
+\fB\-b\fR \fB\-\-batch\fR
+Run in MP batch mode
+.TP
+\fB\-c\fR \fB\-\-execute\fR=\fISTRING\fR
+Execute STRING on start\-up
+.TP
+\fB\-d\fR \fB\-\-sdb\fR
+Enable source code debugger (experimental)
+.TP
+\fB\-e\fR \fB\-\-echo\fR[=\fIVAL\fR]
+Set value of variable `echo' to (integer) VAL
+.TP
+\fB\-h\fR \fB\-\-help\fR
+Print help message and exit
+.TP
+\fB\-q\fR \fB\-\-quiet\fR
+Do not print start\-up banner and lib load messages
+.TP
+\fB\-r\fR \fB\-\-random\fR=\fISEED\fR
+Seed random generator with integer (integer) SEED
+.TP
+\fB\-t\fR \fB\-\-no\-tty\fR
+Do not redefine the terminal characteristics
+.TP
+\fB\-u\fR \fB\-\-user\-option\fR=\fISTRING\fR
+Return STRING on `system("\-\-user\-option")'
+.TP
+\fB\-v\fR \fB\-\-version\fR
+Print extended version and configuration info
+.TP
+\fB\-\-allow\-net\fR
+Allow to fetch (html) help pages from the net
+.TP
+\fB\-\-browser\fR=\fIBROWSER\fR
+Display help in BROWSER ([x,tk]info, firefox, ...)
+.TP
+\fB\-\-cntrlc\fR=\fIC\fR
+non-interactive interrupt handling: C is the answer to (a)bort, (c)ontinue, (q)uit
+.TP
+\fB\-\-emacs\fR
+Set defaults for running within emacs
+.TP
+\fB\-\-no\-stdlib\fR
+Do not load `standard.lib' on start\-up
+.TP
+\fB\-\-no\-rc\fR
+Do not execute `.singularrc' file(s) on start\-up
+.TP
+\fB\-\-no\-warn\fR
+Do not display warning messages
+.TP
+\fB\-\-no\-out\fR
+Suppress all output
+.TP
+\fB\-\-no\-shell\fR
+Restricted mode: Prohibit shell escape commands and links
+.TP
+\fB\-\-min\-time\fR=\fISECS\fR
+Do not display times smaller than SECS (in seconds)
+.TP
+\fB\-\-MPport\fR=\fIPORT\fR
+Use PORT number for connections
+.TP
+\fB\-\-MPhost\fR=\fIHOST\fR
+Use HOST for connections
+.TP
+\fB\-\-link\fR=\fILINKTYPE\fR
+Use LINKTYPE for connections
+.TP
+\fB\-\-ticks\-per\-sec\fR=\fITICKS\fR
+Sets unit of timer to TICKS per second
+.TP
+\fB\-\-cpus\fR=\fICPUS\fR
+maximal number of CPUs to use
+.PP
+For more information, type `help;' from within Singular or visit
+http://www.singular.uni\-kl.de or consult the
+Singular manual (available as on\-line info or html manual).
+.PP
+.SH "SEE ALSO"
+The full documentation for
+.B Singular
+is maintained as a Texinfo manual.
diff --git a/doc/TSingular.man b/doc/TSingular.man
new file mode 100644
index 0000000..492ec12
--- /dev/null
+++ b/doc/TSingular.man
@@ -0,0 +1,37 @@
+.\" DO NOT MODIFY THIS FILE!  It was generated by help2man 1.40.11.
+.TH TSINGULAR "1" "January 2014" "TSingular 4.0.0" "User Commands"
+.SH NAME
+TSingular \- manual page for TSingular 4.0.0
+.SH DESCRIPTION
+TSingular: A Program that starts\-up Singular within a terminal window, for
+Singular version 4.0.0 -- a CAS for polynomial computations. Usage:
+.IP
+TSingular [options] [file]
+.SH OPTIONS
+.TP
+\-
 \fB\-\-xterm\fR=\fIXTERM\fR
+Use XTERM as terminal program to run Singular
+.TP
+\-
 \fB\-\-singular\fR=\fIPROG\fR
+Start PROG as Singular program within emacs
+.TP
+\-
 \fB\-\-no\-call\fR
+Do not start program. Print call to stdout
+.TP
+all other options are apssed to Singular.
+.PP
+For more information, type `help;' from within Singular or visit
+http://www.singular.uni\-kl.de or consult the
+Singular manual (available as on\-line info or html manual).
+.SH "SEE ALSO"
+The full documentation for
+.B Singular
+is maintained as a Texinfo manual.  If the
+.B info
+and
+.B Singular
+programs are properly installed at your site, the command
+.IP
+.B info Singular
+.PP
+should give you access to the complete manual.
diff --git a/dox/Doxyfile.in b/dox/Doxyfile.in
new file mode 100644
index 0000000..fbbb1c4
--- /dev/null
+++ b/dox/Doxyfile.in
@@ -0,0 +1,2418 @@
+# Doxyfile 1.8.7
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project.
+#
+# All text after a double hash (##) is considered a comment and is placed in
+# front of the TAG it is preceding.
+#
+# All text after a single hash (#) is considered a comment and will be ignored.
+# The format is:
+# TAG = value [value, ...]
+# For lists, items can also be appended using:
+# TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (\" \").
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file
+# that follow. The default is UTF-8 which is also the encoding used for all text
+# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv
+# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv
+# for the list of possible encodings.
+# The default value is: UTF-8.
+
+DOXYFILE_ENCODING      = UTF-8
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by
+# double-quotes, unless you are using Doxywizard) that should identify the
+# project for which the documentation is generated. This name is used in the
+# title of most generated pages and in a few other places.
+# The default value is: My Project.
+
+PROJECT_NAME           =
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number. This
+# could be handy for archiving the generated documentation or if some version
+# control system is used.
+
+PROJECT_NUMBER         =$(git_version)
+
+# Using the PROJECT_BRIEF tag one can provide an optional one line description
+# for a project that appears at the top of each page and should give viewer a
+# quick idea about the purpose of the project. Keep the description short.
+
+PROJECT_BRIEF          =
+
+# With the PROJECT_LOGO tag one can specify an logo or icon that is included in
+# the documentation. The maximum height of the logo should not exceed 55 pixels
+# and the maximum width should not exceed 200 pixels. Doxygen will copy the logo
+# to the output directory.
+
+PROJECT_LOGO           = $(abs_top_srcdir)/dox/logo.png
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
+# into which the generated documentation will be written. If a relative path is
+# entered, it will be relative to the location where doxygen was started. If
+# left blank the current directory will be used.
+
+OUTPUT_DIRECTORY       =
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 4096 sub-
+# directories (in 2 levels) under the output directory of each output format and
+# will distribute the generated files over these directories. Enabling this
+# option can be useful when feeding doxygen a huge amount of source files, where
+# putting all generated files in the same directory would otherwise causes
+# performance problems for the file system.
+# The default value is: NO.
+
+CREATE_SUBDIRS         = NO
+
+# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII
+# characters to appear in the names of generated files. If set to NO, non-ASCII
+# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode
+# U+3044.
+# The default value is: NO.
+
+ALLOW_UNICODE_NAMES    = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese,
+# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States),
+# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian,
+# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages),
+# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian,
+# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian,
+# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish,
+# Ukrainian and Vietnamese.
+# The default value is: English.
+
+OUTPUT_LANGUAGE        = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES doxygen will include brief member
+# descriptions after the members that are listed in the file and class
+# documentation (similar to Javadoc). Set to NO to disable this.
+# The default value is: YES.
+
+BRIEF_MEMBER_DESC      = YES
+
+# If the REPEAT_BRIEF tag is set to YES doxygen will prepend the brief
+# description of a member or function before the detailed description
+#
+# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+# The default value is: YES.
+
+REPEAT_BRIEF           = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator that is
+# used to form the text in various listings. Each string in this list, if found
+# as the leading text of the brief description, will be stripped from the text
+# and the result, after processing the whole list, is used as the annotated
+# text. Otherwise, the brief description is used as-is. If left blank, the
+# following values are used ($name is automatically replaced with the name of
+# the entity):The $name class, The $name widget, The $name file, is, provides,
+# specifies, contains, represents, a, an and the.
+
+ABBREVIATE_BRIEF       =
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# doxygen will generate a detailed section even if there is only a brief
+# description.
+# The default value is: NO.
+
+ALWAYS_DETAILED_SEC    = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and assignment
+# operators of the base classes will not be shown.
+# The default value is: NO.
+
+INLINE_INHERITED_MEMB  = NO
+
+# If the FULL_PATH_NAMES tag is set to YES doxygen will prepend the full path
+# before files name in the file list and in the header files. If set to NO the
+# shortest path that makes the file name unique will be used
+# The default value is: YES.
+
+FULL_PATH_NAMES        = YES
+
+# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path.
+# Stripping is only done if one of the specified strings matches the left-hand
+# part of the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the path to
+# strip.
+#
+# Note that you can specify absolute paths here, but also relative paths, which
+# will be relative from the directory where doxygen is started.
+# This tag requires that the tag FULL_PATH_NAMES is set to YES.
+
+STRIP_FROM_PATH        = $(abs_top_srcdir) $(abs_top_builddir)
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the
+# path mentioned in the documentation of a class, which tells the reader which
+# header file to include in order to use a class. If left blank only the name of
+# the header file containing the class definition is used. Otherwise one should
+# specify the list of include paths that are normally passed to the compiler
+# using the -I flag.
+
+STRIP_FROM_INC_PATH    =
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but
+# less readable) file names. This can be useful is your file systems doesn't
+# support long names like on DOS, Mac, or CD-ROM.
+# The default value is: NO.
+
+SHORT_NAMES            = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the
+# first line (until the first dot) of a Javadoc-style comment as the brief
+# description. If set to NO, the Javadoc-style will behave just like regular Qt-
+# style comments (thus requiring an explicit @brief command for a brief
+# description.)
+# The default value is: NO.
+
+JAVADOC_AUTOBRIEF      = YES
+
+# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first
+# line (until the first dot) of a Qt-style comment as the brief description. If
+# set to NO, the Qt-style will behave just like regular Qt-style comments (thus
+# requiring an explicit \brief command for a brief description.)
+# The default value is: NO.
+
+QT_AUTOBRIEF           = YES
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a
+# multi-line C++ special comment block (i.e. a block of //! or /// comments) as
+# a brief description. This used to be the default behavior. The new default is
+# to treat a multi-line C++ comment block as a detailed description. Set this
+# tag to YES if you prefer the old behavior instead.
+#
+# Note that setting this tag to YES also means that rational rose comments are
+# not recognized any more.
+# The default value is: NO.
+
+MULTILINE_CPP_IS_BRIEF = YES
+
+# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the
+# documentation from any documented member that it re-implements.
+# The default value is: YES.
+
+INHERIT_DOCS           = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce a
+# new page for each member. If set to NO, the documentation of a member will be
+# part of the file/class/namespace that contains it.
+# The default value is: NO.
+
+SEPARATE_MEMBER_PAGES  = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen
+# uses this value to replace tabs by spaces in code fragments.
+# Minimum value: 1, maximum value: 16, default value: 4.
+
+TAB_SIZE               = 8
+
+# This tag can be used to specify a number of aliases that act as commands in
+# the documentation. An alias has the form:
+# name=value
+# For example adding
+# "sideeffect=@par Side Effects:\n"
+# will allow you to put the command \sideeffect (or @sideeffect) in the
+# documentation, which will result in a user-defined paragraph with heading
+# "Side Effects:". You can put \n's in the value part of an alias to insert
+# newlines.
+
+ALIASES                =
+
+# This tag can be used to specify a number of word-keyword mappings (TCL only).
+# A mapping has the form "name=value". For example adding "class=itcl::class"
+# will allow you to use the command class in the itcl::class meaning.
+
+TCL_SUBST              =
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
+# only. Doxygen will then generate output that is more tailored for C. For
+# instance, some of the names that are used will be different. The list of all
+# members will be omitted, etc.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_FOR_C  = YES
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or
+# Python sources only. Doxygen will then generate output that is more tailored
+# for that language. For instance, namespaces will be presented as packages,
+# qualified scopes will look different, etc.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_JAVA   = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
+# sources. Doxygen will then generate output that is tailored for Fortran.
+# The default value is: NO.
+
+OPTIMIZE_FOR_FORTRAN   = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
+# sources. Doxygen will then generate output that is tailored for VHDL.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_VHDL   = NO
+
+# Doxygen selects the parser to use depending on the extension of the files it
+# parses. With this tag you can assign which parser to use for a given
+# extension. Doxygen has a built-in mapping, but you can override or extend it
+# using this tag. The format is ext=language, where ext is a file extension, and
+# language is one of the parsers supported by doxygen: IDL, Java, Javascript,
+# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran:
+# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran:
+# Fortran. In the later case the parser tries to guess whether the code is fixed
+# or free formatted code, this is the default for Fortran type files), VHDL. For
+# instance to make doxygen treat .inc files as Fortran files (default is PHP),
+# and .f files as C (default is Fortran), use: inc=Fortran f=C.
+#
+# Note For files without extension you can use no_extension as a placeholder.
+#
+# Note that for custom extensions you also need to set FILE_PATTERNS otherwise
+# the files are not read by doxygen.
+
+EXTENSION_MAPPING      =
+
+# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments
+# according to the Markdown format, which allows for more readable
+# documentation. See http://daringfireball.net/projects/markdown/ for details.
+# The output of markdown processing is further processed by doxygen, so you can
+# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in
+# case of backward compatibilities issues.
+# The default value is: YES.
+
+MARKDOWN_SUPPORT       = YES
+
+# When enabled doxygen tries to link words that correspond to documented
+# classes, or namespaces to their corresponding documentation. Such a link can
+# be prevented in individual cases by by putting a % sign in front of the word
+# or globally by setting AUTOLINK_SUPPORT to NO.
+# The default value is: YES.
+
+AUTOLINK_SUPPORT       = YES
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
+# to include (a tag file for) the STL sources as input, then you should set this
+# tag to YES in order to let doxygen match functions declarations and
+# definitions whose arguments contain STL classes (e.g. func(std::string);
+# versus func(std::string) {}). This also make the inheritance and collaboration
+# diagrams that involve STL classes more complete and accurate.
+# The default value is: NO.
+
+BUILTIN_STL_SUPPORT    = YES
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+# The default value is: NO.
+
+CPP_CLI_SUPPORT        = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip (see:
+# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen
+# will parse them like normal C++ but will assume all classes use public instead
+# of private inheritance when no explicit protection keyword is present.
+# The default value is: NO.
+
+SIP_SUPPORT            = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate
+# getter and setter methods for a property. Setting this option to YES will make
+# doxygen to replace the get and set methods by a property in the documentation.
+# This will only work if the methods are indeed getting or setting a simple
+# type. If this is not the case, or you want to show the methods anyway, you
+# should set this option to NO.
+# The default value is: YES.
+
+IDL_PROPERTY_SUPPORT   = NO
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES, then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+# The default value is: NO.
+
+DISTRIBUTE_GROUP_DOC   = YES
+
+# Set the SUBGROUPING tag to YES to allow class member groups of the same type
+# (for instance a group of public functions) to be put as a subgroup of that
+# type (e.g. under the Public Functions section). Set it to NO to prevent
+# subgrouping. Alternatively, this can be done per class using the
+# \nosubgrouping command.
+# The default value is: YES.
+
+SUBGROUPING            = YES
+
+# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions
+# are shown inside the group in which they are included (e.g. using \ingroup)
+# instead of on a separate page (for HTML and Man pages) or section (for LaTeX
+# and RTF).
+#
+# Note that this feature does not work in combination with
+# SEPARATE_MEMBER_PAGES.
+# The default value is: NO.
+
+INLINE_GROUPED_CLASSES = YES
+
+# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions
+# with only public data fields or simple typedef fields will be shown inline in
+# the documentation of the scope in which they are defined (i.e. file,
+# namespace, or group documentation), provided this scope is documented. If set
+# to NO, structs, classes, and unions are shown on a separate page (for HTML and
+# Man pages) or section (for LaTeX and RTF).
+# The default value is: NO.
+
+INLINE_SIMPLE_STRUCTS  = YES
+
+# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or
+# enum is documented as struct, union, or enum with the name of the typedef. So
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
+# with name TypeT. When disabled the typedef will appear as a member of a file,
+# namespace, or class. And the struct will be named TypeS. This can typically be
+# useful for C code in case the coding convention dictates that all compound
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+# The default value is: NO.
+
+TYPEDEF_HIDES_STRUCT   = YES
+
+# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This
+# cache is used to resolve symbols given their name and scope. Since this can be
+# an expensive process and often the same symbol appears multiple times in the
+# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small
+# doxygen will become slower. If the cache is too large, memory is wasted. The
+# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range
+# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536
+# symbols. At the end of a run doxygen will report the cache usage and suggest
+# the optimal cache size from a speed point of view.
+# Minimum value: 0, maximum value: 9, default value: 0.
+
+LOOKUP_CACHE_SIZE      = 0
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
+# documentation are documented, even if no documentation was available. Private
+# class members and static file members will be hidden unless the
+# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES.
+# Note: This will also disable the warnings about undocumented members that are
+# normally produced when WARNINGS is set to YES.
+# The default value is: NO.
+
+EXTRACT_ALL            = YES
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class will
+# be included in the documentation.
+# The default value is: NO.
+
+EXTRACT_PRIVATE        = YES
+
+# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal
+# scope will be included in the documentation.
+# The default value is: NO.
+
+EXTRACT_PACKAGE        = YES
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file will be
+# included in the documentation.
+# The default value is: NO.
+
+EXTRACT_STATIC         = YES
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) defined
+# locally in source files will be included in the documentation. If set to NO
+# only classes defined in header files are included. Does not have any effect
+# for Java sources.
+# The default value is: YES.
+
+EXTRACT_LOCAL_CLASSES  = YES
+
+# This flag is only useful for Objective-C code. When set to YES local methods,
+# which are defined in the implementation section but not in the interface are
+# included in the documentation. If set to NO only methods in the interface are
+# included.
+# The default value is: NO.
+
+EXTRACT_LOCAL_METHODS  = YES
+
+# If this flag is set to YES, the members of anonymous namespaces will be
+# extracted and appear in the documentation as a namespace called
+# 'anonymous_namespace{file}', where file will be replaced with the base name of
+# the file that contains the anonymous namespace. By default anonymous namespace
+# are hidden.
+# The default value is: NO.
+
+EXTRACT_ANON_NSPACES   = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all
+# undocumented members inside documented classes or files. If set to NO these
+# members will be included in the various overviews, but no documentation
+# section is generated. This option has no effect if EXTRACT_ALL is enabled.
+# The default value is: NO.
+
+HIDE_UNDOC_MEMBERS     = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy. If set
+# to NO these classes will be included in the various overviews. This option has
+# no effect if EXTRACT_ALL is enabled.
+# The default value is: NO.
+
+HIDE_UNDOC_CLASSES     = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend
+# (class|struct|union) declarations. If set to NO these declarations will be
+# included in the documentation.
+# The default value is: NO.
+
+HIDE_FRIEND_COMPOUNDS  = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any
+# documentation blocks found inside the body of a function. If set to NO these
+# blocks will be appended to the function's detailed documentation block.
+# The default value is: NO.
+
+HIDE_IN_BODY_DOCS      = NO
+
+# The INTERNAL_DOCS tag determines if documentation that is typed after a
+# \internal command is included. If the tag is set to NO then the documentation
+# will be excluded. Set it to YES to include the internal documentation.
+# The default value is: NO.
+
+INTERNAL_DOCS          = YES
+
+# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file
+# names in lower-case letters. If set to YES upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# and Mac users are advised to set this option to NO.
+# The default value is: system dependent.
+
+CASE_SENSE_NAMES       = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with
+# their full class and namespace scopes in the documentation. If set to YES the
+# scope will be hidden.
+# The default value is: NO.
+
+HIDE_SCOPE_NAMES       = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of
+# the files that are included by a file in the documentation of that file.
+# The default value is: YES.
+
+SHOW_INCLUDE_FILES     = YES
+
+# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each
+# grouped member an include statement to the documentation, telling the reader
+# which file to include in order to use the member.
+# The default value is: NO.
+
+SHOW_GROUPED_MEMB_INC  = YES
+
+# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include
+# files with double quotes in the documentation rather than with sharp brackets.
+# The default value is: NO.
+
+FORCE_LOCAL_INCLUDES   = NO
+
+# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the
+# documentation for inline members.
+# The default value is: YES.
+
+INLINE_INFO            = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the
+# (detailed) documentation of file and class members alphabetically by member
+# name. If set to NO the members will appear in declaration order.
+# The default value is: YES.
+
+SORT_MEMBER_DOCS       = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief
+# descriptions of file, namespace and class members alphabetically by member
+# name. If set to NO the members will appear in declaration order. Note that
+# this will also influence the order of the classes in the class list.
+# The default value is: NO.
+
+SORT_BRIEF_DOCS        = NO
+
+# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the
+# (brief and detailed) documentation of class members so that constructors and
+# destructors are listed first. If set to NO the constructors will appear in the
+# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS.
+# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief
+# member documentation.
+# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting
+# detailed member documentation.
+# The default value is: NO.
+
+SORT_MEMBERS_CTORS_1ST = NO
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy
+# of group names into alphabetical order. If set to NO the group names will
+# appear in their defined order.
+# The default value is: NO.
+
+SORT_GROUP_NAMES       = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by
+# fully-qualified names, including namespaces. If set to NO, the class list will
+# be sorted only by class name, not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the alphabetical
+# list.
+# The default value is: NO.
+
+SORT_BY_SCOPE_NAME     = NO
+
+# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper
+# type resolution of all parameters of a function it will reject a match between
+# the prototype and the implementation of a member function even if there is
+# only one candidate or it is obvious which candidate to choose by doing a
+# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still
+# accept a match between prototype and implementation in such cases.
+# The default value is: NO.
+
+STRICT_PROTO_MATCHING  = NO
+
+# The GENERATE_TODOLIST tag can be used to enable ( YES) or disable ( NO) the
+# todo list. This list is created by putting \todo commands in the
+# documentation.
+# The default value is: YES.
+
+GENERATE_TODOLIST      = NO
+
+# The GENERATE_TESTLIST tag can be used to enable ( YES) or disable ( NO) the
+# test list. This list is created by putting \test commands in the
+# documentation.
+# The default value is: YES.
+
+GENERATE_TESTLIST      = NO
+
+# The GENERATE_BUGLIST tag can be used to enable ( YES) or disable ( NO) the bug
+# list. This list is created by putting \bug commands in the documentation.
+# The default value is: YES.
+
+GENERATE_BUGLIST       = NO
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable ( YES) or disable ( NO)
+# the deprecated list. This list is created by putting \deprecated commands in
+# the documentation.
+# The default value is: YES.
+
+GENERATE_DEPRECATEDLIST= NO
+
+# The ENABLED_SECTIONS tag can be used to enable conditional documentation
+# sections, marked by \if <section_label> ... \endif and \cond <section_label>
+# ... \endcond blocks.
+
+ENABLED_SECTIONS       =
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the
+# initial value of a variable or macro / define can have for it to appear in the
+# documentation. If the initializer consists of more lines than specified here
+# it will be hidden. Use a value of 0 to hide initializers completely. The
+# appearance of the value of individual variables and macros / defines can be
+# controlled using \showinitializer or \hideinitializer command in the
+# documentation regardless of this setting.
+# Minimum value: 0, maximum value: 10000, default value: 30.
+
+MAX_INITIALIZER_LINES  = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at
+# the bottom of the documentation of classes and structs. If set to YES the list
+# will mention the files that were used to generate the documentation.
+# The default value is: YES.
+
+SHOW_USED_FILES        = YES
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This
+# will remove the Files entry from the Quick Index and from the Folder Tree View
+# (if specified).
+# The default value is: YES.
+
+SHOW_FILES             = YES
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces
+# page. This will remove the Namespaces entry from the Quick Index and from the
+# Folder Tree View (if specified).
+# The default value is: YES.
+
+SHOW_NAMESPACES        = NO
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically from
+# the version control system). Doxygen will invoke the program by executing (via
+# popen()) the command command input-file, where command is the value of the
+# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided
+# by doxygen. Whatever the program writes to standard output is used as the file
+# version. For an example see the documentation.
+
+FILE_VERSION_FILTER    =
+
+# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
+# by doxygen. The layout file controls the global structure of the generated
+# output files in an output format independent way. To create the layout file
+# that represents doxygen's defaults, run doxygen with the -l option. You can
+# optionally specify a file name after the option, if omitted DoxygenLayout.xml
+# will be used as the name of the layout file.
+#
+# Note that if you run doxygen from a directory containing a file called
+# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE
+# tag is left empty.
+
+LAYOUT_FILE            = $(abs_top_srcdir)/dox/DoxygenLayout.xml
+
+# The CITE_BIB_FILES tag can be used to specify one or more bib files containing
+# the reference definitions. This must be a list of .bib files. The .bib
+# extension is automatically appended if omitted. This requires the bibtex tool
+# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info.
+# For LaTeX the style of the bibliography can be controlled using
+# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the
+# search path. Do not use file names with spaces, bibtex cannot handle them. See
+# also \cite for info how to create references.
+
+CITE_BIB_FILES         =
+
+#---------------------------------------------------------------------------
+# Configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated to
+# standard output by doxygen. If QUIET is set to YES this implies that the
+# messages are off.
+# The default value is: NO.
+
+QUIET                  = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated to standard error ( stderr) by doxygen. If WARNINGS is set to YES
+# this implies that the warnings are on.
+#
+# Tip: Turn warnings on while writing the documentation.
+# The default value is: YES.
+
+WARNINGS               = YES
+
+# If the WARN_IF_UNDOCUMENTED tag is set to YES, then doxygen will generate
+# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag
+# will automatically be disabled.
+# The default value is: YES.
+
+WARN_IF_UNDOCUMENTED   = NO
+
+# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some parameters
+# in a documented function, or documenting parameters that don't exist or using
+# markup commands wrongly.
+# The default value is: YES.
+
+WARN_IF_DOC_ERROR      = YES
+
+# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that
+# are documented, but have no documentation for their parameters or return
+# value. If set to NO doxygen will only warn about wrong or incomplete parameter
+# documentation, but not about the absence of documentation.
+# The default value is: NO.
+
+WARN_NO_PARAMDOC       = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that doxygen
+# can produce. The string should contain the $file, $line, and $text tags, which
+# will be replaced by the file and line number from which the warning originated
+# and the warning text. Optionally the format may contain $version, which will
+# be replaced by the version of the file (if it could be obtained via
+# FILE_VERSION_FILTER)
+# The default value is: $file:$line: $text.
+
+WARN_FORMAT            = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning and error
+# messages should be written. If left blank the output is written to standard
+# error (stderr).
+
+WARN_LOGFILE           = html_dox.log
+
+#---------------------------------------------------------------------------
+# Configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag is used to specify the files and/or directories that contain
+# documented source files. You may enter file names like myfile.cpp or
+# directories like /usr/src/myproject. Separate the files or directories with
+# spaces.
+# Note: If this tag is empty the current directory is searched.
+
+INPUT                  = \
+                         $(abs_top_srcdir)/README.md \
+                         $(abs_top_srcdir)/main.dox \
+                         $(abs_top_srcdir)/doc/ \
+			 $(abs_top_srcdir)/omalloc/ \
+                         $(abs_top_srcdir)/resources/ \
+                         $(abs_top_srcdir)/kernel/ \
+                         $(abs_top_srcdir)/libpolys/ \
+                         $(abs_top_srcdir)/Singular/ \
+                         $(abs_top_srcdir)/templates/ \
+                         $(abs_top_srcdir)/factory/
+
+# This tag can be used to specify the character encoding of the source files
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
+# libiconv (or the iconv built into libc) for the transcoding. See the libiconv
+# documentation (see: http://www.gnu.org/software/libiconv) for the list of
+# possible encodings.
+# The default value is: UTF-8.
+
+INPUT_ENCODING         = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and
+# *.h) to filter out the source-files in the directories. If left blank the
+# following patterns are tested:*.c, *.cc, *.cxx, *.cpp, *.c++, *.java, *.ii,
+# *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, *.hh, *.hxx, *.hpp,
+# *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, *.m, *.markdown,
+# *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf,
+# *.qsf, *.as and *.js.
+
+FILE_PATTERNS          = *.h \
+                         *.cc \
+                         *.c \
+                         *.cpp \
+                         *.cxx \
+                         *.dox \
+                         *.md
+
+# The RECURSIVE tag can be used to specify whether or not subdirectories should
+# be searched for input files as well.
+# The default value is: NO.
+
+RECURSIVE              = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should be
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+#
+# Note that relative paths are relative to the directory from which doxygen is
+# run.
+
+EXCLUDE                = $(abs_top_srcdir)/factory/examples \
+                         $(abs_top_srcdir)/kernel/old \
+                         $(abs_top_srcdir)/omalloc/Misc
+
+# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
+# directories that are symbolic links (a Unix file system feature) are excluded
+# from the input.
+# The default value is: NO.
+
+EXCLUDE_SYMLINKS       = YES
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories.
+#
+# Note that the wildcards are matched against the file with absolute path, so to
+# exclude all test directories for example use the pattern */test/*
+
+EXCLUDE_PATTERNS       = \
+*/test.cc \
+*[Cc]onfig.h \
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
+# (namespaces, classes, functions, etc.) that should be excluded from the
+# output. The symbol name can be a fully qualified name, a word, or if the
+# wildcard * is used, a substring. Examples: ANamespace, AClass,
+# AClass::ANamespace, ANamespace::*Test
+#
+# Note that the wildcards are matched against the file with absolute path, so to
+# exclude all test directories use the pattern */test/*
+
+EXCLUDE_SYMBOLS        =
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or directories
+# that contain example code fragments that are included (see the \include
+# command).
+
+EXAMPLE_PATH           = $(abs_top_srcdir)
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and
+# *.h) to filter out the source-files in the directories. If left blank all
+# files are included.
+
+EXAMPLE_PATTERNS       =
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude commands
+# irrespective of the value of the RECURSIVE tag.
+# The default value is: NO.
+
+EXAMPLE_RECURSIVE      = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or directories
+# that contain images that are to be included in the documentation (see the
+# \image command).
+
+IMAGE_PATH             = $(abs_top_srcdir)
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command:
+#
+# <filter> <input-file>
+#
+# where <filter> is the value of the INPUT_FILTER tag, and <input-file> is the
+# name of an input file. Doxygen will then use the output that the filter
+# program writes to standard output. If FILTER_PATTERNS is specified, this tag
+# will be ignored.
+#
+# Note that the filter must not add or remove lines; it is applied before the
+# code is scanned, but not when the output code is generated. If lines are added
+# or removed, the anchors will not be placed correctly.
+
+INPUT_FILTER           =
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis. Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match. The filters are a list of the form: pattern=filter
+# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how
+# filters are used. If the FILTER_PATTERNS tag is empty or if none of the
+# patterns match the file name, INPUT_FILTER is applied.
+
+FILTER_PATTERNS        =
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER ) will also be used to filter the input files that are used for
+# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES).
+# The default value is: NO.
+
+FILTER_SOURCE_FILES    = NO
+
+# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file
+# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and
+# it is also possible to disable source filtering for a specific pattern using
+# *.ext= (so without naming a filter).
+# This tag requires that the tag FILTER_SOURCE_FILES is set to YES.
+
+FILTER_SOURCE_PATTERNS =
+
+# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that
+# is part of the input, its contents will be placed on the main page
+# (index.html). This can be useful if you have a project on for instance GitHub
+# and want to reuse the introduction page also for the doxygen output.
+
+USE_MDFILE_AS_MAINPAGE =
+
+#---------------------------------------------------------------------------
+# Configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will be
+# generated. Documented entities will be cross-referenced with these sources.
+#
+# Note: To get rid of all source code in the generated output, make sure that
+# also VERBATIM_HEADERS is set to NO.
+# The default value is: NO.
+
+SOURCE_BROWSER         = YES
+
+# Setting the INLINE_SOURCES tag to YES will include the body of functions,
+# classes and enums directly into the documentation.
+# The default value is: NO.
+
+INLINE_SOURCES         = YES
+
+# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any
+# special comment blocks from generated source code fragments. Normal C, C++ and
+# Fortran comments will always remain visible.
+# The default value is: YES.
+
+STRIP_CODE_COMMENTS    = NO
+
+# If the REFERENCED_BY_RELATION tag is set to YES then for each documented
+# function all documented functions referencing it will be listed.
+# The default value is: NO.
+
+REFERENCED_BY_RELATION = NO
+
+# If the REFERENCES_RELATION tag is set to YES then for each documented function
+# all documented entities called/used by that function will be listed.
+# The default value is: NO.
+
+REFERENCES_RELATION    = NO
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set
+# to YES, then the hyperlinks from functions in REFERENCES_RELATION and
+# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will
+# link to the documentation.
+# The default value is: YES.
+
+REFERENCES_LINK_SOURCE = NO
+
+# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the
+# source code will show a tooltip with additional information such as prototype,
+# brief description and links to the definition and documentation. Since this
+# will make the HTML file larger and loading of large files a bit slower, you
+# can opt to disable this feature.
+# The default value is: YES.
+# This tag requires that the tag SOURCE_BROWSER is set to YES.
+
+SOURCE_TOOLTIPS        = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code will
+# point to the HTML generated by the htags(1) tool instead of doxygen built-in
+# source browser. The htags tool is part of GNU's global source tagging system
+# (see http://www.gnu.org/software/global/global.html). You will need version
+# 4.8.6 or higher.
+#
+# To use it do the following:
+# - Install the latest version of global
+# - Enable SOURCE_BROWSER and USE_HTAGS in the config file
+# - Make sure the INPUT points to the root of the source tree
+# - Run doxygen as normal
+#
+# Doxygen will invoke htags (and that will in turn invoke gtags), so these
+# tools must be available from the command line (i.e. in the search path).
+#
+# The result: instead of the source browser generated by doxygen, the links to
+# source code will now point to the output of htags.
+# The default value is: NO.
+# This tag requires that the tag SOURCE_BROWSER is set to YES.
+
+USE_HTAGS              = NO
+
+# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a
+# verbatim copy of the header file for each class for which an include is
+# specified. Set to NO to disable this.
+# See also: Section \class.
+# The default value is: YES.
+
+VERBATIM_HEADERS       = YES
+
+#---------------------------------------------------------------------------
+# Configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all
+# compounds will be generated. Enable this if the project contains a lot of
+# classes, structs, unions or interfaces.
+# The default value is: YES.
+
+ALPHABETICAL_INDEX     = YES
+
+# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in
+# which the alphabetical index list will be split.
+# Minimum value: 1, maximum value: 20, default value: 5.
+# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
+
+COLS_IN_ALPHA_INDEX    = 5
+
+# In case all classes in a project start with a common prefix, all classes will
+# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag
+# can be used to specify a prefix (or a list of prefixes) that should be ignored
+# while generating the index headers.
+# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
+
+IGNORE_PREFIX          =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES doxygen will generate HTML output
+# The default value is: YES.
+
+GENERATE_HTML          = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: html.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_OUTPUT            = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each
+# generated HTML page (for example: .htm, .php, .asp).
+# The default value is: .html.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_FILE_EXTENSION    = .html
+
+# The HTML_HEADER tag can be used to specify a user-defined HTML header file for
+# each generated HTML page. If the tag is left blank doxygen will generate a
+# standard header.
+#
+# To get valid HTML the header file that includes any scripts and style sheets
+# that doxygen needs, which is dependent on the configuration options used (e.g.
+# the setting GENERATE_TREEVIEW). It is highly recommended to start with a
+# default header using
+# doxygen -w html new_header.html new_footer.html new_stylesheet.css
+# YourConfigFile
+# and then modify the file new_header.html. See also section "Doxygen usage"
+# for information on how to generate the default header that doxygen normally
+# uses.
+# Note: The header is subject to change so you typically have to regenerate the
+# default header when upgrading to a newer version of doxygen. For a description
+# of the possible markers and block names see the documentation.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_HEADER            = $(abs_top_srcdir)/dox/header.html
+
+# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each
+# generated HTML page. If the tag is left blank doxygen will generate a standard
+# footer. See HTML_HEADER for more information on how to generate a default
+# footer and what special commands can be used inside the footer. See also
+# section "Doxygen usage" for information on how to generate the default footer
+# that doxygen normally uses.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_FOOTER            = $(abs_top_srcdir)/dox/footer.html
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style
+# sheet that is used by each HTML page. It can be used to fine-tune the look of
+# the HTML output. If left blank doxygen will generate a default style sheet.
+# See also section "Doxygen usage" for information on how to generate the style
+# sheet that doxygen normally uses.
+# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as
+# it is more robust and this tag (HTML_STYLESHEET) will in the future become
+# obsolete.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_STYLESHEET        =
+
+# The HTML_EXTRA_STYLESHEET tag can be used to specify an additional user-
+# defined cascading style sheet that is included after the standard style sheets
+# created by doxygen. Using this option one can overrule certain style aspects.
+# This is preferred over using HTML_STYLESHEET since it does not replace the
+# standard style sheet and is therefor more robust against future updates.
+# Doxygen will copy the style sheet file to the output directory. For an example
+# see the documentation.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_EXTRA_STYLESHEET  = $(abs_top_srcdir)/dox/stylesheet.css
+
+# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the HTML output directory. Note
+# that these files will be copied to the base HTML output directory. Use the
+# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
+# files. In the HTML_STYLESHEET file, use the file name only. Also note that the
+# files will be copied as-is; there are no commands or markers available.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_EXTRA_FILES       =
+
+# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
+# will adjust the colors in the stylesheet and background images according to
+# this color. Hue is specified as an angle on a colorwheel, see
+# http://en.wikipedia.org/wiki/Hue for more information. For instance the value
+# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300
+# purple, and 360 is red again.
+# Minimum value: 0, maximum value: 359, default value: 220.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_HUE    = 200
+
+# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors
+# in the HTML output. For a value of 0 the output will use grayscales only. A
+# value of 255 will produce the most vivid colors.
+# Minimum value: 0, maximum value: 255, default value: 100.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_SAT    = 0
+
+# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the
+# luminance component of the colors in the HTML output. Values below 100
+# gradually make the output lighter, whereas values above 100 make the output
+# darker. The value divided by 100 is the actual gamma applied, so 80 represents
+# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not
+# change the gamma.
+# Minimum value: 40, maximum value: 240, default value: 80.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_GAMMA  = 190
+
+# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
+# page will contain the date and time when the page was generated. Setting this
+# to NO can help when comparing the output of multiple runs.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_TIMESTAMP         = YES
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
+# documentation will contain sections that can be hidden and shown after the
+# page has loaded.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_DYNAMIC_SECTIONS  = YES
+
+# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries
+# shown in the various tree structured indices initially; the user can expand
+# and collapse entries dynamically later on. Doxygen will expand the tree to
+# such a level that at most the specified number of entries are visible (unless
+# a fully collapsed tree already exceeds this amount). So setting the number of
+# entries 1 will produce a full collapsed tree by default. 0 is a special value
+# representing an infinite number of entries and will result in a full expanded
+# tree by default.
+# Minimum value: 0, maximum value: 9999, default value: 100.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_INDEX_NUM_ENTRIES = 100
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files will be
+# generated that can be used as input for Apple's Xcode 3 integrated development
+# environment (see: http://developer.apple.com/tools/xcode/), introduced with
+# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a
+# Makefile in the HTML output directory. Running make will produce the docset in
+# that directory and running make install will install the docset in
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at
+# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
+# for more information.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_DOCSET        = NO
+
+# This tag determines the name of the docset feed. A documentation feed provides
+# an umbrella under which multiple documentation sets from a single provider
+# (such as a company or product suite) can be grouped.
+# The default value is: Doxygen generated docs.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_FEEDNAME        = "Doxygen generated docs"
+
+# This tag specifies a string that should uniquely identify the documentation
+# set bundle. This should be a reverse domain-name style string, e.g.
+# com.mycompany.MyDocSet. Doxygen will append .docset to the name.
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_BUNDLE_ID       = org.doxygen.Project
+
+# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify
+# the documentation publisher. This should be a reverse domain-name style
+# string, e.g. com.mycompany.MyDocSet.documentation.
+# The default value is: org.doxygen.Publisher.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_PUBLISHER_ID    = org.doxygen.Publisher
+
+# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher.
+# The default value is: Publisher.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_PUBLISHER_NAME  = Publisher
+
+# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three
+# additional HTML index files: index.hhp, index.hhc, and index.hhk. The
+# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop
+# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on
+# Windows.
+#
+# The HTML Help Workshop contains a compiler that can convert all HTML output
+# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML
+# files are now used as the Windows 98 help format, and will replace the old
+# Windows help format (.hlp) on all Windows platforms in the future. Compressed
+# HTML files also contain an index, a table of contents, and you can search for
+# words in the documentation. The HTML workshop also contains a viewer for
+# compressed HTML files.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_HTMLHELP      = NO
+
+# The CHM_FILE tag can be used to specify the file name of the resulting .chm
+# file. You can add a path in front of the file if the result should not be
+# written to the html output directory.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+CHM_FILE               =
+
+# The HHC_LOCATION tag can be used to specify the location (absolute path
+# including file name) of the HTML help compiler ( hhc.exe). If non-empty
+# doxygen will try to run the HTML help compiler on the generated index.hhp.
+# The file has to be specified with full path.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+HHC_LOCATION           =
+
+# The GENERATE_CHI flag controls if a separate .chi index file is generated (
+# YES) or that it should be included in the master .chm file ( NO).
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+GENERATE_CHI           = NO
+
+# The CHM_INDEX_ENCODING is used to encode HtmlHelp index ( hhk), content ( hhc)
+# and project file content.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+CHM_INDEX_ENCODING     =
+
+# The BINARY_TOC flag controls whether a binary table of contents is generated (
+# YES) or a normal table of contents ( NO) in the .chm file. Furthermore it
+# enables the Previous and Next buttons.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+BINARY_TOC             = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members to
+# the table of contents of the HTML help documentation and to the tree view.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+TOC_EXPAND             = NO
+
+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
+# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that
+# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help
+# (.qch) of the generated HTML documentation.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_QHP           = NO
+
+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify
+# the file name of the resulting .qch file. The path specified is relative to
+# the HTML output folder.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QCH_FILE               =
+
+# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help
+# Project output. For more information please see Qt Help Project / Namespace
+# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace).
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_NAMESPACE          = org.doxygen.Project
+
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt
+# Help Project output. For more information please see Qt Help Project / Virtual
+# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual-
+# folders).
+# The default value is: doc.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_VIRTUAL_FOLDER     = doc
+
+# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom
+# filter to add. For more information please see Qt Help Project / Custom
+# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
+# filters).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_CUST_FILTER_NAME   =
+
+# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the
+# custom filter to add. For more information please see Qt Help Project / Custom
+# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
+# filters).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_CUST_FILTER_ATTRS  =
+
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
+# project's filter section matches. Qt Help Project / Filter Attributes (see:
+# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_SECT_FILTER_ATTRS  =
+
+# The QHG_LOCATION tag can be used to specify the location of Qt's
+# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the
+# generated .qhp file.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHG_LOCATION           =
+
+# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be
+# generated, together with the HTML files, they form an Eclipse help plugin. To
+# install this plugin and make it available under the help contents menu in
+# Eclipse, the contents of the directory containing the HTML and XML files needs
+# to be copied into the plugins directory of eclipse. The name of the directory
+# within the plugins directory should be the same as the ECLIPSE_DOC_ID value.
+# After copying Eclipse needs to be restarted before the help appears.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_ECLIPSEHELP   = NO
+
+# A unique identifier for the Eclipse help plugin. When installing the plugin
+# the directory name containing the HTML and XML files should also have this
+# name. Each documentation set should have its own identifier.
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES.
+
+ECLIPSE_DOC_ID         = org.doxygen.Project
+
+# If you want full control over the layout of the generated HTML pages it might
+# be necessary to disable the index and replace it with your own. The
+# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top
+# of each HTML page. A value of NO enables the index and the value YES disables
+# it. Since the tabs in the index contain the same information as the navigation
+# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+DISABLE_INDEX          = NO
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
+# structure should be generated to display hierarchical information. If the tag
+# value is set to YES, a side panel will be generated containing a tree-like
+# index structure (just like the one that is generated for HTML Help). For this
+# to work a browser that supports JavaScript, DHTML, CSS and frames is required
+# (i.e. any modern browser). Windows users are probably better off using the
+# HTML help feature. Via custom stylesheets (see HTML_EXTRA_STYLESHEET) one can
+# further fine-tune the look of the index. As an example, the default style
+# sheet generated by doxygen has an example that shows how to put an image at
+# the root of the tree instead of the PROJECT_NAME. Since the tree basically has
+# the same information as the tab index, you could consider setting
+# DISABLE_INDEX to YES when enabling this option.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_TREEVIEW      = NO
+
+# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that
+# doxygen will group on one line in the generated HTML documentation.
+#
+# Note that a value of 0 will completely suppress the enum values from appearing
+# in the overview section.
+# Minimum value: 0, maximum value: 20, default value: 4.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+ENUM_VALUES_PER_LINE   = 4
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used
+# to set the initial width (in pixels) of the frame in which the tree is shown.
+# Minimum value: 0, maximum value: 1500, default value: 250.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+TREEVIEW_WIDTH         = 250
+
+# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open links to
+# external symbols imported via tag files in a separate window.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+EXT_LINKS_IN_WINDOW    = NO
+
+# Use this tag to change the font size of LaTeX formulas included as images in
+# the HTML documentation. When you change the font size after a successful
+# doxygen run you need to manually remove any form_*.png images from the HTML
+# output directory to force them to be regenerated.
+# Minimum value: 8, maximum value: 50, default value: 10.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+FORMULA_FONTSIZE       = 10
+
+# Use the FORMULA_TRANPARENT tag to determine whether or not the images
+# generated for formulas are transparent PNGs. Transparent PNGs are not
+# supported properly for IE 6.0, but are supported on all modern browsers.
+#
+# Note that when changing this option you need to delete any form_*.png files in
+# the HTML output directory before the changes have effect.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+FORMULA_TRANSPARENT    = YES
+
+# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see
+# http://www.mathjax.org) which uses client side Javascript for the rendering
+# instead of using prerendered bitmaps. Use this if you do not have LaTeX
+# installed or if you want to formulas look prettier in the HTML output. When
+# enabled you may also need to install MathJax separately and configure the path
+# to it using the MATHJAX_RELPATH option.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+USE_MATHJAX            = NO
+
+# When MathJax is enabled you can set the default output format to be used for
+# the MathJax output. See the MathJax site (see:
+# http://docs.mathjax.org/en/latest/output.html) for more details.
+# Possible values are: HTML-CSS (which is slower, but has the best
+# compatibility), NativeMML (i.e. MathML) and SVG.
+# The default value is: HTML-CSS.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_FORMAT         = HTML-CSS
+
+# When MathJax is enabled you need to specify the location relative to the HTML
+# output directory using the MATHJAX_RELPATH option. The destination directory
+# should contain the MathJax.js script. For instance, if the mathjax directory
+# is located at the same level as the HTML output directory, then
+# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax
+# Content Delivery Network so you can quickly see the result without installing
+# MathJax. However, it is strongly recommended to install a local copy of
+# MathJax from http://www.mathjax.org before deployment.
+# The default value is: http://cdn.mathjax.org/mathjax/latest.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_RELPATH        = http://www.mathjax.org/mathjax
+
+# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax
+# extension names that should be enabled during MathJax rendering. For example
+# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_EXTENSIONS     =
+
+# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces
+# of code that will be used on startup of the MathJax code. See the MathJax site
+# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an
+# example see the documentation.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_CODEFILE       =
+
+# When the SEARCHENGINE tag is enabled doxygen will generate a search box for
+# the HTML output. The underlying search engine uses javascript and DHTML and
+# should work on any modern browser. Note that when using HTML help
+# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET)
+# there is already a search function so this one should typically be disabled.
+# For large projects the javascript based search engine can be slow, then
+# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to
+# search using the keyboard; to jump to the search box use <access key> + S
+# (what the <access key> is depends on the OS and browser, but it is typically
+# <CTRL>, <ALT>/<option>, or both). Inside the search box use the <cursor down
+# key> to jump into the search results window, the results can be navigated
+# using the <cursor keys>. Press <Enter> to select an item or <escape> to cancel
+# the search. The filter options can be selected when the cursor is inside the
+# search box by pressing <Shift>+<cursor down>. Also here use the <cursor keys>
+# to select a filter and <Enter> or <escape> to activate or cancel the filter
+# option.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+SEARCHENGINE           = YES
+
+# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
+# implemented using a web server instead of a web client using Javascript. There
+# are two flavors of web server based searching depending on the EXTERNAL_SEARCH
+# setting. When disabled, doxygen will generate a PHP script for searching and
+# an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing
+# and searching needs to be provided by external tools. See the section
+# "External Indexing and Searching" for details.
+# The default value is: NO.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SERVER_BASED_SEARCH    = NO
+
+# When EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP
+# script for searching. Instead the search results are written to an XML file
+# which needs to be processed by an external indexer. Doxygen will invoke an
+# external search engine pointed to by the SEARCHENGINE_URL option to obtain the
+# search results.
+#
+# Doxygen ships with an example indexer ( doxyindexer) and search engine
+# (doxysearch.cgi) which are based on the open source search engine library
+# Xapian (see: http://xapian.org/).
+#
+# See the section "External Indexing and Searching" for details.
+# The default value is: NO.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTERNAL_SEARCH        = NO
+
+# The SEARCHENGINE_URL should point to a search engine hosted by a web server
+# which will return the search results when EXTERNAL_SEARCH is enabled.
+#
+# Doxygen ships with an example indexer ( doxyindexer) and search engine
+# (doxysearch.cgi) which are based on the open source search engine library
+# Xapian (see: http://xapian.org/). See the section "External Indexing and
+# Searching" for details.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SEARCHENGINE_URL       =
+
+# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed
+# search data is written to a file for indexing by an external tool. With the
+# SEARCHDATA_FILE tag the name of this file can be specified.
+# The default file is: searchdata.xml.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SEARCHDATA_FILE        = searchdata.xml
+
+# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the
+# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is
+# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple
+# projects and redirect the results back to the right project.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTERNAL_SEARCH_ID     =
+
+# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen
+# projects other than the one defined by this configuration file, but that are
+# all added to the same external search index. Each project needs to have a
+# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id of
+# to a relative location where the documentation can be found. The format is:
+# EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ...
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTRA_SEARCH_MAPPINGS  =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES doxygen will generate LaTeX output.
+# The default value is: YES.
+
+GENERATE_LATEX         = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: latex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_OUTPUT           = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked.
+#
+# Note that when enabling USE_PDFLATEX this option is only used for generating
+# bitmaps for formulas in the HTML output, but not in the Makefile that is
+# written to the output directory.
+# The default file is: latex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_CMD_NAME         = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate
+# index for LaTeX.
+# The default file is: makeindex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+MAKEINDEX_CMD_NAME     = makeindex
+
+# If the COMPACT_LATEX tag is set to YES doxygen generates more compact LaTeX
+# documents. This may be useful for small projects and may help to save some
+# trees in general.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+COMPACT_LATEX          = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used by the
+# printer.
+# Possible values are: a4 (210 x 297 mm), letter (8.5 x 11 inches), legal (8.5 x
+# 14 inches) and executive (7.25 x 10.5 inches).
+# The default value is: a4.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+PAPER_TYPE             = a4
+
+# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names
+# that should be included in the LaTeX output. To get the times font for
+# instance you can specify
+# EXTRA_PACKAGES=times
+# If left blank no extra packages will be included.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+EXTRA_PACKAGES         =
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the
+# generated LaTeX document. The header should contain everything until the first
+# chapter. If it is left blank doxygen will generate a standard header. See
+# section "Doxygen usage" for information on how to let doxygen write the
+# default header to a separate file.
+#
+# Note: Only use a user-defined header if you know what you are doing! The
+# following commands have a special meaning inside the header: $title,
+# $datetime, $date, $doxygenversion, $projectname, $projectnumber,
+# $projectbrief, $projectlogo. Doxygen will replace $title with the empy string,
+# for the replacement values of the other commands the user is refered to
+# HTML_HEADER.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_HEADER           =
+
+# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the
+# generated LaTeX document. The footer should contain everything after the last
+# chapter. If it is left blank doxygen will generate a standard footer. See
+# LATEX_HEADER for more information on how to generate a default footer and what
+# special commands can be used inside the footer.
+#
+# Note: Only use a user-defined footer if you know what you are doing!
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_FOOTER           =
+
+# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the LATEX_OUTPUT output
+# directory. Note that the files will be copied as-is; there are no commands or
+# markers available.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_EXTRA_FILES      =
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is
+# prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will
+# contain links (just like the HTML output) instead of page references. This
+# makes the output suitable for online browsing using a PDF viewer.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+PDF_HYPERLINKS         = YES
+
+# If the USE_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate
+# the PDF file directly from the LaTeX files. Set this option to YES to get a
+# higher quality PDF documentation.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+USE_PDFLATEX           = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode
+# command to the generated LaTeX files. This will instruct LaTeX to keep running
+# if errors occur, instead of asking the user for help. This option is also used
+# when generating formulas in HTML.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_BATCHMODE        = YES
+
+# If the LATEX_HIDE_INDICES tag is set to YES then doxygen will not include the
+# index chapters (such as File Index, Compound Index, etc.) in the output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_HIDE_INDICES     = NO
+
+# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source
+# code with syntax highlighting in the LaTeX output.
+#
+# Note that which sources are shown also depends on other settings such as
+# SOURCE_BROWSER.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_SOURCE_CODE      = NO
+
+# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
+# bibliography, e.g. plainnat, or ieeetr. See
+# http://en.wikipedia.org/wiki/BibTeX and \cite for more info.
+# The default value is: plain.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_BIB_STYLE        = plain
+
+#---------------------------------------------------------------------------
+# Configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES doxygen will generate RTF output. The
+# RTF output is optimized for Word 97 and may not look too pretty with other RTF
+# readers/editors.
+# The default value is: NO.
+
+GENERATE_RTF           = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: rtf.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_OUTPUT             = rtf
+
+# If the COMPACT_RTF tag is set to YES doxygen generates more compact RTF
+# documents. This may be useful for small projects and may help to save some
+# trees in general.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+COMPACT_RTF            = YES
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated will
+# contain hyperlink fields. The RTF file will contain links (just like the HTML
+# output) instead of page references. This makes the output suitable for online
+# browsing using Word or some other Word compatible readers that support those
+# fields.
+#
+# Note: WordPad (write) and others do not support links.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_HYPERLINKS         = YES
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's config
+# file, i.e. a series of assignments. You only have to provide replacements,
+# missing definitions are set to their default value.
+#
+# See also section "Doxygen usage" for information on how to generate the
+# default style sheet that doxygen normally uses.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_STYLESHEET_FILE    =
+
+# Set optional variables used in the generation of an RTF document. Syntax is
+# similar to doxygen's config file. A template extensions file can be generated
+# using doxygen -e rtf extensionFile.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_EXTENSIONS_FILE    =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES doxygen will generate man pages for
+# classes and files.
+# The default value is: NO.
+
+GENERATE_MAN           = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it. A directory man3 will be created inside the directory specified by
+# MAN_OUTPUT.
+# The default directory is: man.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_OUTPUT             = man
+
+# The MAN_EXTENSION tag determines the extension that is added to the generated
+# man pages. In case the manual section does not start with a number, the number
+# 3 is prepended. The dot (.) at the beginning of the MAN_EXTENSION tag is
+# optional.
+# The default value is: .3.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_EXTENSION          = .3
+
+# The MAN_SUBDIR tag determines the name of the directory created within
+# MAN_OUTPUT in which the man pages are placed. If defaults to man followed by
+# MAN_EXTENSION with the initial . removed.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_SUBDIR             =
+
+# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it
+# will generate one additional man file for each entity documented in the real
+# man page(s). These additional files only source the real man page, but without
+# them the man command would be unable to find the correct page.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_LINKS              = YES
+
+#---------------------------------------------------------------------------
+# Configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES doxygen will generate an XML file that
+# captures the structure of the code including all documentation.
+# The default value is: NO.
+
+GENERATE_XML           = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: xml.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_OUTPUT             = xml
+
+# If the XML_PROGRAMLISTING tag is set to YES doxygen will dump the program
+# listings (including syntax highlighting and cross-referencing information) to
+# the XML output. Note that enabling this will significantly increase the size
+# of the XML output.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_PROGRAMLISTING     = YES
+
+#---------------------------------------------------------------------------
+# Configuration options related to the DOCBOOK output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_DOCBOOK tag is set to YES doxygen will generate Docbook files
+# that can be used to generate PDF.
+# The default value is: NO.
+
+GENERATE_DOCBOOK       = NO
+
+# The DOCBOOK_OUTPUT tag is used to specify where the Docbook pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in
+# front of it.
+# The default directory is: docbook.
+# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
+
+DOCBOOK_OUTPUT         = docbook
+
+# If the DOCBOOK_PROGRAMLISTING tag is set to YES doxygen will include the
+# program listings (including syntax highlighting and cross-referencing
+# information) to the DOCBOOK output. Note that enabling this will significantly
+# increase the size of the DOCBOOK output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
+
+DOCBOOK_PROGRAMLISTING = NO
+
+#---------------------------------------------------------------------------
+# Configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES doxygen will generate an AutoGen
+# Definitions (see http://autogen.sf.net) file that captures the structure of
+# the code including all documentation. Note that this feature is still
+# experimental and incomplete at the moment.
+# The default value is: NO.
+
+GENERATE_AUTOGEN_DEF   = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES doxygen will generate a Perl module
+# file that captures the structure of the code including all documentation.
+#
+# Note that this feature is still experimental and incomplete at the moment.
+# The default value is: NO.
+
+GENERATE_PERLMOD       = NO
+
+# If the PERLMOD_LATEX tag is set to YES doxygen will generate the necessary
+# Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI
+# output from the Perl module output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_LATEX          = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be nicely
+# formatted so it can be parsed by a human reader. This is useful if you want to
+# understand what is going on. On the other hand, if this tag is set to NO the
+# size of the Perl module output will be much smaller and Perl will parse it
+# just the same.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_PRETTY         = YES
+
+# The names of the make variables in the generated doxyrules.make file are
+# prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. This is useful
+# so different doxyrules.make files included by the same Makefile don't
+# overwrite each other's variables.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_MAKEVAR_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES doxygen will evaluate all
+# C-preprocessor directives found in the sources and include files.
+# The default value is: YES.
+
+ENABLE_PREPROCESSING   = YES
+
+# If the MACRO_EXPANSION tag is set to YES doxygen will expand all macro names
+# in the source code. If set to NO only conditional compilation will be
+# performed. Macro expansion can be done in a controlled way by setting
+# EXPAND_ONLY_PREDEF to YES.
+# The default value is: NO.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+MACRO_EXPANSION        = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then
+# the macro expansion is limited to the macros specified with the PREDEFINED and
+# EXPAND_AS_DEFINED tags.
+# The default value is: NO.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+EXPAND_ONLY_PREDEF     = NO
+
+# If the SEARCH_INCLUDES tag is set to YES the includes files in the
+# INCLUDE_PATH will be searched if a #include is found.
+# The default value is: YES.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+SEARCH_INCLUDES        = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by the
+# preprocessor.
+# This tag requires that the tag SEARCH_INCLUDES is set to YES.
+
+INCLUDE_PATH           = \
+                         $(abs_top_builddir)/ \
+                         $(abs_top_builddir)/factory \
+                         $(abs_top_builddir)/libpolys \
+                         $(abs_top_srcdir)/ \
+                         $(abs_top_srcdir)/factory \
+                         $(abs_top_srcdir)/libpolys
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will be
+# used.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+INCLUDE_FILE_PATTERNS  = *.h *.inc
+
+# The PREDEFINED tag can be used to specify one or more macro names that are
+# defined before the preprocessor is started (similar to the -D option of e.g.
+# gcc). The argument of the tag is a list of macros of the form: name or
+# name=definition (no spaces). If the definition and the "=" are omitted, "=1"
+# is assumed. To prevent a macro definition from being undefined via #undef or
+# recursively expanded use the := operator instead of the = operator.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+PREDEFINED             = \
+"SIZEOF_LONG=8" \
+"HAVE_GFANLIB=1" \
+"HAVE_RINGS=1" \
+"HAVE_MORE_FIELDS_IMPLEMENTED=1" \
+"__FLINT_RELEASE=20400" \
+"__GMP_BITS_PER_MP_LIMB=100" \
+__cplusplus \
+GENTABLE \
+HAVE_ASSUME \
+HAVE_ATEXIT \
+HAVE_BIGINTM \
+HAVE_CDD_SETOPER_H \
+HAVE_DBM \
+HAVE_DL \
+HAVE_DLD \
+HAVE_DYN_RL \
+HAVE_DYNAMIC_LOADING \
+HAVE_EIGENVAL \
+HAVE_ELF_SYSTEM \
+HAVE_EXPLICIT_CONSTR \
+HAVE_EXTENDED_SYSTEM \
+HAVE_F4 \
+HAVE_F5 \
+HAVE_F5C \
+HAVE_FEREAD \
+HAVE_FLINT \
+HAVE_GENERIC_ADD \
+HAVE_GMS \
+HAVE_IOSTREAM \
+HAVE_LENGTH_DIFF \
+HAVE_LIBPARSER \
+HAVE_LM_BIN \
+HAVE_MATHICGB \
+HAVE_NAMESPACES \
+HAVE_NEWTON \
+HAVE_NTL \
+HAVE_OM_ASSUME \
+HAVE_OMALLOC \
+HAVE_PCV \
+HAVE_PLURAL \
+HAVE_POLYEXTENSIONS \
+HAVE_POLYMAKE \
+HAVE_PSEUDO_BUCKETS \
+HAVE_PYTHON \
+HAVE_RATGRING \
+HAVE_RING2TOM \
+HAVE_RINGS_LOC \
+HAVE_SBRK \
+HAVE_SDB \
+HAVE_SHEAFCOH_TRICKS \
+HAVE_SHIFTBBA \
+HAVE_SPECTRUM \
+HAVE_SUMMATOR \
+HAVE_SVD \
+HAVE_TAIL_BIN \
+HAVE_TAIL_RING \
+HAVE_VANIDEAL \
+HAVE_WALK \
+HAVE_ZERODIVISORS \
+IPARITH \
+IPASSIGN \
+IPCONV \
+OLD_RES \
+OMALLOC_USES_SYSTEM_MALLOC \
+PLURAL_INTERNAL_DECLARATIONS \
+PLURAL_INTERNAL_DECLARATIONS_GB_HACK \
+SEMIC_PRINT \
+SI_COUNTEDREF_AUTOLOAD \
+SINGULAR \
+SINGULAR_4_1
+
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
+# tag can be used to specify a list of macro names that should be expanded. The
+# macro definition that is found in the sources will be used. Use the PREDEFINED
+# tag if you want to use a different macro definition that overrules the
+# definition found in the source code.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+EXPAND_AS_DEFINED      = SINGULAR_DOXYGEN
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will
+# remove all references to function-like macros that are alone on a line, have
+# an all uppercase name, and do not end with a semicolon. Such function macros
+# are typically used for boiler-plate code, and will confuse the parser if not
+# removed.
+# The default value is: YES.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+SKIP_FUNCTION_MACROS   = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES tag can be used to specify one or more tag files. For each tag
+# file the location of the external documentation should be added. The format of
+# a tag file without this location is as follows:
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where loc1 and loc2 can be relative or absolute paths or URLs. See the
+# section "Linking to external documentation" for more information about the use
+# of tag files.
+# Note: Each tag file must have a unique name (where the name does NOT include
+# the path). If a tag file is not located in the directory in which doxygen is
+# run, you must also specify the path to the tagfile here.
+
+TAGFILES               =
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create a
+# tag file that is based on the input files it reads. See section "Linking to
+# external documentation" for more information about the usage of tag files.
+
+GENERATE_TAGFILE       = tags
+
+# If the ALLEXTERNALS tag is set to YES all external class will be listed in the
+# class index. If set to NO only the inherited external classes will be listed.
+# The default value is: NO.
+
+ALLEXTERNALS           = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed in
+# the modules index. If set to NO, only the current project's groups will be
+# listed.
+# The default value is: YES.
+
+EXTERNAL_GROUPS        = YES
+
+# If the EXTERNAL_PAGES tag is set to YES all external pages will be listed in
+# the related pages index. If set to NO, only the current project's pages will
+# be listed.
+# The default value is: YES.
+
+EXTERNAL_PAGES         = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of 'which perl').
+# The default file (with absolute path) is: /usr/bin/perl.
+
+PERL_PATH              = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES doxygen will generate a class diagram
+# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to
+# NO turns the diagrams off. Note that this option also works with HAVE_DOT
+# disabled, but it is recommended to install and use dot, since it yields more
+# powerful graphs.
+# The default value is: YES.
+
+CLASS_DIAGRAMS         = YES
+
+# You can define message sequence charts within doxygen comments using the \msc
+# command. Doxygen will then run the mscgen tool (see:
+# http://www.mcternan.me.uk/mscgen/)) to produce the chart and insert it in the
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where
+# the mscgen tool resides. If left empty the tool is assumed to be found in the
+# default search path.
+
+MSCGEN_PATH            =
+
+# You can include diagrams made with dia in doxygen documentation. Doxygen will
+# then run dia to produce the diagram and insert it in the documentation. The
+# DIA_PATH tag allows you to specify the directory where the dia binary resides.
+# If left empty dia is assumed to be found in the default search path.
+
+DIA_PATH               =
+
+# If set to YES, the inheritance and collaboration graphs will hide inheritance
+# and usage relations if the target is undocumented or is not a class.
+# The default value is: YES.
+
+HIDE_UNDOC_RELATIONS   = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz (see:
+# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent
+# Bell Labs. The other options in this section have no effect if this option is
+# set to NO
+# The default value is: NO.
+
+HAVE_DOT               = YES
+
+# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed
+# to run in parallel. When set to 0 doxygen will base this on the number of
+# processors available in the system. You can set it explicitly to a value
+# larger than 0 to get control over the balance between CPU load and processing
+# speed.
+# Minimum value: 0, maximum value: 32, default value: 0.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_NUM_THREADS        = 0
+
+# When you want a differently looking font in the dot files that doxygen
+# generates you can specify the font name using DOT_FONTNAME. You need to make
+# sure dot is able to find the font, which can be done by putting it in a
+# standard location or by setting the DOTFONTPATH environment variable or by
+# setting DOT_FONTPATH to the directory containing the font.
+# The default value is: Helvetica.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTNAME           = Helvetica
+
+# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of
+# dot graphs.
+# Minimum value: 4, maximum value: 24, default value: 10.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTSIZE           = 10
+
+# By default doxygen will tell dot to use the default font as specified with
+# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set
+# the path where dot can find it using this tag.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTPATH           =
+
+# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for
+# each documented class showing the direct and indirect inheritance relations.
+# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CLASS_GRAPH            = NO
+
+# If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a
+# graph for each documented class showing the direct and indirect implementation
+# dependencies (inheritance, containment, and class references variables) of the
+# class with other documented classes.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+COLLABORATION_GRAPH    = NO
+
+# If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for
+# groups, showing the direct groups dependencies.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GROUP_GRAPHS           = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+UML_LOOK               = NO
+
+# If the UML_LOOK tag is enabled, the fields and methods are shown inside the
+# class node. If there are many fields or methods and many nodes the graph may
+# become too big to be useful. The UML_LIMIT_NUM_FIELDS threshold limits the
+# number of items for each type to make the size more manageable. Set this to 0
+# for no limit. Note that the threshold may be exceeded by 50% before the limit
+# is enforced. So when you set the threshold to 10, up to 15 fields may appear,
+# but if the number exceeds 15, the total amount of fields shown is limited to
+# 10.
+# Minimum value: 0, maximum value: 100, default value: 10.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+UML_LIMIT_NUM_FIELDS   = 10
+
+# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and
+# collaboration graphs will show the relations between templates and their
+# instances.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+TEMPLATE_RELATIONS     = NO
+
+# If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to
+# YES then doxygen will generate a graph for each documented file showing the
+# direct and indirect include dependencies of the file with other documented
+# files.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INCLUDE_GRAPH          = NO
+
+# If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are
+# set to YES then doxygen will generate a graph for each documented file showing
+# the direct and indirect include dependencies of the file with other documented
+# files.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INCLUDED_BY_GRAPH      = NO
+
+# If the CALL_GRAPH tag is set to YES then doxygen will generate a call
+# dependency graph for every global function or class method.
+#
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable call graphs for selected
+# functions only using the \callgraph command.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CALL_GRAPH             = NO
+
+# If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller
+# dependency graph for every global function or class method.
+#
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable caller graphs for selected
+# functions only using the \callergraph command.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CALLER_GRAPH           = NO
+
+# If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical
+# hierarchy of all classes instead of a textual one.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GRAPHICAL_HIERARCHY    = NO
+
+# If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the
+# dependencies a directory has on other directories in a graphical way. The
+# dependency relations are determined by the #include relations between the
+# files in the directories.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DIRECTORY_GRAPH        = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot.
+# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order
+# to make the SVG files visible in IE 9+ (other browsers do not have this
+# requirement).
+# Possible values are: png, jpg, gif and svg.
+# The default value is: png.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_IMAGE_FORMAT       = png
+
+# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to
+# enable generation of interactive SVG images that allow zooming and panning.
+#
+# Note that this requires a modern browser other than Internet Explorer. Tested
+# and working are Firefox, Chrome, Safari, and Opera.
+# Note: For IE 9+ you need to set HTML_FILE_EXTENSION to xhtml in order to make
+# the SVG files visible. Older versions of IE do not have SVG support.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INTERACTIVE_SVG        = YES
+
+# The DOT_PATH tag can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found in the path.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_PATH               =
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the \dotfile
+# command).
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOTFILE_DIRS           = $(abs_top_srcdir)
+
+# The MSCFILE_DIRS tag can be used to specify one or more directories that
+# contain msc files that are included in the documentation (see the \mscfile
+# command).
+
+MSCFILE_DIRS           =
+
+# The DIAFILE_DIRS tag can be used to specify one or more directories that
+# contain dia files that are included in the documentation (see the \diafile
+# command).
+
+DIAFILE_DIRS           =
+
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes
+# that will be shown in the graph. If the number of nodes in a graph becomes
+# larger than this value, doxygen will truncate the graph, which is visualized
+# by representing a node as a red box. Note that doxygen if the number of direct
+# children of the root node in a graph is already larger than
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note that
+# the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+# Minimum value: 0, maximum value: 10000, default value: 50.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_GRAPH_MAX_NODES    = 30
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the graphs
+# generated by dot. A depth value of 3 means that only nodes reachable from the
+# root by following a path via at most 3 edges will be shown. Nodes that lay
+# further from the root node will be omitted. Note that setting this option to 1
+# or 2 may greatly reduce the computation time needed for large code bases. Also
+# note that the size of a graph can be further restricted by
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+# Minimum value: 0, maximum value: 1000, default value: 0.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+MAX_DOT_GRAPH_DEPTH    = 3
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
+# background. This is disabled by default, because dot on Windows does not seem
+# to support this out of the box.
+#
+# Warning: Depending on the platform used, enabling this option may lead to
+# badly anti-aliased labels on the edges of a graph (i.e. they become hard to
+# read).
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_TRANSPARENT        = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
+# files in one run (i.e. multiple -o and -T options on the command line). This
+# makes dot run faster, but since only newer versions of dot (>1.8.10) support
+# this, this feature is disabled by default.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_MULTI_TARGETS      = YES
+
+# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page
+# explaining the meaning of the various boxes and arrows in the dot generated
+# graphs.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GENERATE_LEGEND        = NO
+
+# If the DOT_CLEANUP tag is set to YES doxygen will remove the intermediate dot
+# files that are used to generate the various graphs.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_CLEANUP            = YES
diff --git a/dox/DoxygenLayout.xml b/dox/DoxygenLayout.xml
new file mode 100644
index 0000000..e727c10
--- /dev/null
+++ b/dox/DoxygenLayout.xml
@@ -0,0 +1,194 @@
+<doxygenlayout version="1.0">
+  <!-- Generated by doxygen 1.8.7 -->
+  <!-- Navigation index tabs for HTML output -->
+  <navindex>
+    <tab type="mainpage" visible="yes" title=""/>
+    <tab type="pages" visible="yes" title="" intro=""/>
+    <tab type="modules" visible="yes" title="" intro=""/>
+    <tab type="namespaces" visible="yes" title="">
+      <tab type="namespacelist" visible="yes" title="" intro=""/>
+      <tab type="namespacemembers" visible="yes" title="" intro=""/>
+    </tab>
+    <tab type="classes" visible="yes" title="">
+      <tab type="classlist" visible="yes" title="" intro=""/>
+      <tab type="classindex" visible="$ALPHABETICAL_INDEX" title=""/>
+      <tab type="hierarchy" visible="yes" title="" intro=""/>
+      <tab type="classmembers" visible="yes" title="" intro=""/>
+    </tab>
+    <tab type="files" visible="yes" title="">
+      <tab type="filelist" visible="yes" title="" intro=""/>
+      <tab type="globals" visible="yes" title="" intro=""/>
+    </tab>
+    <tab type="examples" visible="yes" title="" intro=""/>
+  </navindex>
+
+  <!-- Layout definition for a class page -->
+  <class>
+    <briefdescription visible="yes"/>
+    <includes visible="$SHOW_INCLUDE_FILES"/>
+    <inheritancegraph visible="$CLASS_GRAPH"/>
+    <collaborationgraph visible="$COLLABORATION_GRAPH"/>
+    <memberdecl>
+      <nestedclasses visible="yes" title=""/>
+      <publictypes title=""/>
+      <services title=""/>
+      <interfaces title=""/>
+      <publicslots title=""/>
+      <signals title=""/>
+      <publicmethods title=""/>
+      <publicstaticmethods title=""/>
+      <publicattributes title=""/>
+      <publicstaticattributes title=""/>
+      <protectedtypes title=""/>
+      <protectedslots title=""/>
+      <protectedmethods title=""/>
+      <protectedstaticmethods title=""/>
+      <protectedattributes title=""/>
+      <protectedstaticattributes title=""/>
+      <packagetypes title=""/>
+      <packagemethods title=""/>
+      <packagestaticmethods title=""/>
+      <packageattributes title=""/>
+      <packagestaticattributes title=""/>
+      <properties title=""/>
+      <events title=""/>
+      <privatetypes title=""/>
+      <privateslots title=""/>
+      <privatemethods title=""/>
+      <privatestaticmethods title=""/>
+      <privateattributes title=""/>
+      <privatestaticattributes title=""/>
+      <friends title=""/>
+      <related title="" subtitle=""/>
+      <membergroups visible="yes"/>
+    </memberdecl>
+    <detaileddescription title=""/>
+    <memberdef>
+      <inlineclasses title=""/>
+      <typedefs title=""/>
+      <enums title=""/>
+      <services title=""/>
+      <interfaces title=""/>
+      <constructors title=""/>
+      <functions title=""/>
+      <related title=""/>
+      <variables title=""/>
+      <properties title=""/>
+      <events title=""/>
+    </memberdef>
+    <allmemberslink visible="yes"/>
+    <usedfiles visible="$SHOW_USED_FILES"/>
+    <authorsection visible="yes"/>
+  </class>
+
+  <!-- Layout definition for a namespace page -->
+  <namespace>
+    <briefdescription visible="yes"/>
+    <memberdecl>
+      <nestednamespaces visible="yes" title=""/>
+      <constantgroups visible="yes" title=""/>
+      <classes visible="yes" title=""/>
+      <typedefs title=""/>
+      <enums title=""/>
+      <functions title=""/>
+      <variables title=""/>
+      <membergroups visible="yes"/>
+    </memberdecl>
+    <detaileddescription title=""/>
+    <memberdef>
+      <inlineclasses title=""/>
+      <typedefs title=""/>
+      <enums title=""/>
+      <functions title=""/>
+      <variables title=""/>
+    </memberdef>
+    <authorsection visible="yes"/>
+  </namespace>
+
+  <!-- Layout definition for a file page -->
+  <file>
+    <briefdescription visible="yes"/>
+    <includes visible="$SHOW_INCLUDE_FILES"/>
+    <includegraph visible="$INCLUDE_GRAPH"/>
+    <includedbygraph visible="$INCLUDED_BY_GRAPH"/>
+    <sourcelink visible="yes"/>
+    <memberdecl>
+      <classes visible="yes" title=""/>
+      <namespaces visible="yes" title=""/>
+      <constantgroups visible="yes" title=""/>
+      <defines title=""/>
+      <typedefs title=""/>
+      <enums title=""/>
+      <functions title=""/>
+      <variables title=""/>
+      <membergroups visible="yes"/>
+    </memberdecl>
+    <detaileddescription title=""/>
+    <memberdef>
+      <inlineclasses title=""/>
+      <defines title=""/>
+      <typedefs title=""/>
+      <enums title=""/>
+      <functions title=""/>
+      <variables title=""/>
+    </memberdef>
+    <authorsection/>
+  </file>
+
+  <!-- Layout definition for a group page -->
+  <group>
+    <briefdescription visible="yes"/>
+    <groupgraph visible="$GROUP_GRAPHS"/>
+    <memberdecl>
+      <nestedgroups visible="yes" title=""/>
+      <dirs visible="yes" title=""/>
+      <files visible="yes" title=""/>
+      <namespaces visible="yes" title=""/>
+      <classes visible="yes" title=""/>
+      <defines title=""/>
+      <typedefs title=""/>
+      <enums title=""/>
+      <enumvalues title=""/>
+      <functions title=""/>
+      <variables title=""/>
+      <signals title=""/>
+      <publicslots title=""/>
+      <protectedslots title=""/>
+      <privateslots title=""/>
+      <events title=""/>
+      <properties title=""/>
+      <friends title=""/>
+      <membergroups visible="yes"/>
+    </memberdecl>
+    <detaileddescription title=""/>
+    <memberdef>
+      <pagedocs/>
+      <inlineclasses title=""/>
+      <defines title=""/>
+      <typedefs title=""/>
+      <enums title=""/>
+      <enumvalues title=""/>
+      <functions title=""/>
+      <variables title=""/>
+      <signals title=""/>
+      <publicslots title=""/>
+      <protectedslots title=""/>
+      <privateslots title=""/>
+      <events title=""/>
+      <properties title=""/>
+      <friends title=""/>
+    </memberdef>
+    <authorsection visible="yes"/>
+  </group>
+
+  <!-- Layout definition for a directory page -->
+  <directory>
+    <briefdescription visible="yes"/>
+    <directorygraph visible="yes"/>
+    <memberdecl>
+      <dirs visible="yes"/>
+      <files visible="yes"/>
+    </memberdecl>
+    <detaileddescription title=""/>
+  </directory>
+</doxygenlayout>
diff --git a/dox/Makefile.am b/dox/Makefile.am
new file mode 100644
index 0000000..295a7ab
--- /dev/null
+++ b/dox/Makefile.am
@@ -0,0 +1,41 @@
+GIT_VERSION := $(shell $(top_srcdir)/git-version-gen $(top_srcdir)/.tarball-git-version)
+
+doxyrun:
+	if [ -z "$(DOXYGEN)" ]; then \
+		which -s doxygen || (echo Please add 'doxygen' to your PATH; exit 1;); \
+		export DOXYGEN=`which -s doxygen`; \
+	fi
+	if [ -z "$(DOXYGEN_CONFIG)" ]; then \
+		echo Please set 'DOXYGEN_CONFIG' env. var!; \
+		exit 1; \
+	fi
+	if [ ! -r "$(DOXYGEN_CONFIG)" ]; then \
+		echo Please make the doxygen configuration readable: "$(DOXYGEN_CONFIG)"!; \
+		exit 1; \
+	fi
+	export abs_top_srcdir="$(abs_top_srcdir)"; \
+	export abs_top_builddir="$(abs_top_builddir)"; \
+	export git_version="$(GIT_VERSION)"; \
+ 	echo Running "$(DOXYGEN)" "$(DOXYGEN_CONFIG)" with abs_top_srcdir: "$(abs_top_srcdir)", abs_top_builddir: "$(abs_top_builddir)", GIT_VERSION: "$(git_version)"...; \
+	$(DOXYGEN) $(DOXYGEN_CONFIG) ; \
+ 	echo Finished running "$(DOXYGEN)" "$(DOXYGEN_CONFIG)" with abs_top_srcdir: "$(abs_top_srcdir)", abs_top_builddir: "$(abs_top_builddir)", GIT_VERSION: "$(git_version)"...;
+
+if HAVE_DOXYGEN
+
+## doxyfile.stamp:
+html:
+	$(MAKE) doxyrun abs_top_srcdir="$(abs_top_srcdir)" abs_top_builddir="$(abs_top_builddir)" \
+	DOXYGEN_CONFIG="$(abs_srcdir)/Doxyfile.in" DOXYGEN="$(DOXYGEN)"
+##	echo Timestamp > doxyfile.stamp
+
+## CLEANFILES = doxyfile.stamp
+
+# all-local: doxyfile.stamp
+
+## html: doxyfile.stamp
+
+clean-local:
+	rm -rf html
+endif
+
+EXTRA_DIST = Doxyfile.in logo.png DoxygenLayout.xml header.html footer.html stylesheet.css
diff --git a/dox/Makefile.in b/dox/Makefile.in
new file mode 100644
index 0000000..2700141
--- /dev/null
+++ b/dox/Makefile.in
@@ -0,0 +1,526 @@
+# Makefile.in generated by automake 1.13.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 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@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+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 = dox
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_append_compile_flags.m4 \
+	$(top_srcdir)/m4/ax_append_flag.m4 \
+	$(top_srcdir)/m4/ax_append_link_flags.m4 \
+	$(top_srcdir)/m4/ax_check_compile_flag.m4 \
+	$(top_srcdir)/m4/ax_check_link_flag.m4 \
+	$(top_srcdir)/m4/ax_compute_relative_paths.m4 \
+	$(top_srcdir)/m4/ax_normalize_path.m4 \
+	$(top_srcdir)/m4/ax_prefix_config_h.m4 \
+	$(top_srcdir)/m4/ax_pthread.m4 \
+	$(top_srcdir)/m4/ax_python_embed.m4 \
+	$(top_srcdir)/m4/ax_python_with_version.m4 \
+	$(top_srcdir)/m4/cpu-check.m4 $(top_srcdir)/m4/dbm-check.m4 \
+	$(top_srcdir)/m4/flags.m4 $(top_srcdir)/m4/flint-check.m4 \
+	$(top_srcdir)/m4/gfanlib-check.m4 \
+	$(top_srcdir)/m4/gmp-check.m4 \
+	$(top_srcdir)/m4/google-perftools.m4 \
+	$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+	$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+	$(top_srcdir)/m4/lt~obsolete.m4 \
+	$(top_srcdir)/m4/mathic-check.m4 $(top_srcdir)/m4/ntl-check.m4 \
+	$(top_srcdir)/m4/options.m4 $(top_srcdir)/m4/p-procs.m4 \
+	$(top_srcdir)/m4/polymake-check.m4 \
+	$(top_srcdir)/m4/readline-check.m4 $(top_srcdir)/configure.ac
+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_V_P = $(am__v_P_ at AM_V@)
+am__v_P_ = $(am__v_P_ at AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_ at AM_V@)
+am__v_GEN_ = $(am__v_GEN_ at AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_ at AM_V@)
+am__v_at_ = $(am__v_at_ at AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+SOURCES =
+DIST_SOURCES =
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BUILTIN_LIBS = @BUILTIN_LIBS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CDDGMPCPPFLAGS = @CDDGMPCPPFLAGS@
+CDDGMPLDFLAGS = @CDDGMPLDFLAGS@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATA_DIR = @DATA_DIR@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DOC_DIR = @DOC_DIR@
+DOXYGEN = @DOXYGEN@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FACTORY_INCLUDES = @FACTORY_INCLUDES@
+FACTORY_LIBS = @FACTORY_LIBS@
+FGREP = @FGREP@
+FLINT_CFLAGS = @FLINT_CFLAGS@
+FLINT_HOME = @FLINT_HOME@
+FLINT_LIBS = @FLINT_LIBS@
+GMP_CFLAGS = @GMP_CFLAGS@
+GMP_HOME = @GMP_HOME@
+GMP_LIBS = @GMP_LIBS@
+GMP_VERSION = @GMP_VERSION@
+GREP = @GREP@
+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@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NTL_CFLAGS = @NTL_CFLAGS@
+NTL_LIBS = @NTL_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OMALLOC_INCLUDES = @OMALLOC_INCLUDES@
+OMALLOC_LIBS = @OMALLOC_LIBS@
+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@
+PKG_REQUIRE = @PKG_REQUIRE@
+PMCONFIG = @PMCONFIG@
+PM_CFLAGS = @PM_CFLAGS@
+PM_INC = @PM_INC@
+PM_LDFLAGS = @PM_LDFLAGS@
+PM_LIBS = @PM_LIBS@
+POLYMAKE_CXXFLAGS = @POLYMAKE_CXXFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LDFLAGS = @PTHREAD_LDFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
+PYTHON = @PYTHON@
+PYTHON_CSPEC = @PYTHON_CSPEC@
+PYTHON_EXECPREFIX = @PYTHON_EXECPREFIX@
+PYTHON_LSPEC = @PYTHON_LSPEC@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+RANLIB = @RANLIB@
+RESOURCES_INCLUDES = @RESOURCES_INCLUDES@
+RESOURCES_LIBS = @RESOURCES_LIBS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SINGULAR_CFLAGS = @SINGULAR_CFLAGS@
+SI_COUNTEDREF_AUTOLOAD = @SI_COUNTEDREF_AUTOLOAD@
+SI_CPU_I386 = @SI_CPU_I386@
+SI_CPU_IA64 = @SI_CPU_IA64@
+SI_CPU_PPC = @SI_CPU_PPC@
+SI_CPU_SPARC = @SI_CPU_SPARC@
+SI_CPU_X86_64 = @SI_CPU_X86_64@
+STRIP = @STRIP@
+USEPPROCSDYNAMICLD = @USEPPROCSDYNAMICLD@
+USEPPROCSDYNAMICLDFLAGS = @USEPPROCSDYNAMICLDFLAGS@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
+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@
+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@
+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@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+GIT_VERSION := $(shell $(top_srcdir)/git-version-gen $(top_srcdir)/.tarball-git-version)
+EXTRA_DIST = Doxyfile.in logo.png DoxygenLayout.xml header.html footer.html stylesheet.css
+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) --foreign dox/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign dox/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:
+
+ctags CTAGS:
+
+cscope cscopelist:
+
+
+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:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+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."
+ at HAVE_DOXYGEN_FALSE@clean-local:
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-local mostlyclean-am
+
+distclean: distclean-am
+	-rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+ at HAVE_DOXYGEN_FALSE@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 \
+	clean-local cscopelist-am ctags-am 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 \
+	tags-am uninstall uninstall-am
+
+
+doxyrun:
+	if [ -z "$(DOXYGEN)" ]; then \
+		which -s doxygen || (echo Please add 'doxygen' to your PATH; exit 1;); \
+		export DOXYGEN=`which -s doxygen`; \
+	fi
+	if [ -z "$(DOXYGEN_CONFIG)" ]; then \
+		echo Please set 'DOXYGEN_CONFIG' env. var!; \
+		exit 1; \
+	fi
+	if [ ! -r "$(DOXYGEN_CONFIG)" ]; then \
+		echo Please make the doxygen configuration readable: "$(DOXYGEN_CONFIG)"!; \
+		exit 1; \
+	fi
+	export abs_top_srcdir="$(abs_top_srcdir)"; \
+	export abs_top_builddir="$(abs_top_builddir)"; \
+	export git_version="$(GIT_VERSION)"; \
+ 	echo Running "$(DOXYGEN)" "$(DOXYGEN_CONFIG)" with abs_top_srcdir: "$(abs_top_srcdir)", abs_top_builddir: "$(abs_top_builddir)", GIT_VERSION: "$(git_version)"...; \
+	$(DOXYGEN) $(DOXYGEN_CONFIG) ; \
+ 	echo Finished running "$(DOXYGEN)" "$(DOXYGEN_CONFIG)" with abs_top_srcdir: "$(abs_top_srcdir)", abs_top_builddir: "$(abs_top_builddir)", GIT_VERSION: "$(git_version)"...;
+
+ at HAVE_DOXYGEN_TRUE@html:
+ at HAVE_DOXYGEN_TRUE@	$(MAKE) doxyrun abs_top_srcdir="$(abs_top_srcdir)" abs_top_builddir="$(abs_top_builddir)" \
+ at HAVE_DOXYGEN_TRUE@	DOXYGEN_CONFIG="$(abs_srcdir)/Doxyfile.in" DOXYGEN="$(DOXYGEN)"
+
+# all-local: doxyfile.stamp
+
+ at HAVE_DOXYGEN_TRUE@clean-local:
+ at HAVE_DOXYGEN_TRUE@	rm -rf html
+
+# 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/dox/footer.html b/dox/footer.html
new file mode 100644
index 0000000..3065f86
--- /dev/null
+++ b/dox/footer.html
@@ -0,0 +1,19 @@
+<!-- HTML footer for doxygen 1.8.7-->
+<!-- start footer part -->
+<!--BEGIN GENERATE_TREEVIEW-->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    $navpath
+    <li class="footer">$generatedby<a
+href="http://www.doxygen.org/index.html">doxygen $doxygenversion</a> for <a href="https://github.com/Singular/Sources/commit/$projectnumber">Singular <!--BEGIN PROJECT_NUMBER-->$projectnumber<!--END PROJECT_NUMBER--></a></li>
+  </ul>
+</div>
+<!--END GENERATE_TREEVIEW-->
+<!--BEGIN !GENERATE_TREEVIEW-->
+<hr class="footer"/><address class="footer"><small>
+$generatedby  
+<a href="http://www.doxygen.org/index.html">doxygen $doxygenversion</a> for <a href="https://github.com/Singular/Sources/commit/$projectnumber">Singular <!--BEGIN PROJECT_NUMBER-->$projectnumber<!--END PROJECT_NUMBER--></a>
+</small></address>
+<!--END !GENERATE_TREEVIEW-->
+</body>
+</html>
diff --git a/dox/header.html b/dox/header.html
new file mode 100644
index 0000000..59b73e9
--- /dev/null
+++ b/dox/header.html
@@ -0,0 +1,55 @@
+<!-- HTML header for doxygen 1.8.7-->
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=9"/>
+<meta name="generator" content="Doxygen $doxygenversion"/>
+<!--BEGIN PROJECT_NAME--><title>$projectname: $title</title><!--END PROJECT_NAME-->
+<!--BEGIN !PROJECT_NAME--><title>$title</title><!--END !PROJECT_NAME-->
+<link href="$relpath^tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="$relpath^jquery.js"></script>
+<script type="text/javascript" src="$relpath^dynsections.js"></script>
+$treeview
+$search
+$mathjax
+<link href="$relpath^$stylesheet" rel="stylesheet" type="text/css" />
+$extrastylesheet
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+
+<!--BEGIN TITLEAREA-->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr style="height: 56px;">
+  <!--BEGIN PROJECT_LOGO-->
+  <td id="projectlogo"><img alt="Singular $projectnumber" src="$relpath^$projectlogo"/></td>
+  <!--END PROJECT_LOGO-->
+  <!--BEGIN PROJECT_NAME-->
+  <td style="padding-left: 0.5em;">
+   <div id="projectname">$projectname
+   <!--BEGIN PROJECT_NUMBER--> <span id="projectnumber">$projectnumber</span><!--END PROJECT_NUMBER-->
+   </div>
+   <!--BEGIN PROJECT_BRIEF--><div id="projectbrief">$projectbrief</div><!--END PROJECT_BRIEF-->
+  </td>
+  <!--END PROJECT_NAME-->
+  <!--BEGIN !PROJECT_NAME-->
+   <!--BEGIN PROJECT_BRIEF-->
+    <td style="padding-left: 0.5em;">
+    <div id="projectbrief">$projectbrief</div>
+    </td>
+   <!--END PROJECT_BRIEF-->
+  <!--END !PROJECT_NAME-->
+  <!--BEGIN DISABLE_INDEX-->
+   <!--BEGIN SEARCHENGINE-->
+   <td>$searchbox</td>
+   <!--END SEARCHENGINE-->
+  <!--END DISABLE_INDEX-->
+ </tr>
+ </tbody>
+</table>
+</div>
+<!--END TITLEAREA-->
+<!-- end header part -->
diff --git a/dox/logo.png b/dox/logo.png
new file mode 100644
index 0000000..ea781f4
Binary files /dev/null and b/dox/logo.png differ
diff --git a/dox/stylesheet.css b/dox/stylesheet.css
new file mode 100644
index 0000000..7f7f973
--- /dev/null
+++ b/dox/stylesheet.css
@@ -0,0 +1,1442 @@
+/* The standard CSS for doxygen 1.8.7 */
+
+body, table, div, p, dl {
+	font: 400 14px/22px Roboto,sans-serif;
+}
+
+/* @group Heading Levels */
+
+h1.groupheader {
+	font-size: 150%;
+}
+
+.title {
+	font: 400 14px/28px Roboto,sans-serif;
+	font-size: 150%;
+	font-weight: bold;
+	margin: 10px 2px;
+}
+
+h2.groupheader {
+	border-bottom: 1px solid #879ECB;
+	color: #354C7B;
+	font-size: 150%;
+	font-weight: normal;
+	margin-top: 1.75em;
+	padding-top: 8px;
+	padding-bottom: 4px;
+	width: 100%;
+}
+
+h3.groupheader {
+	font-size: 100%;
+}
+
+h1, h2, h3, h4, h5, h6 {
+	-webkit-transition: text-shadow 0.5s linear;
+	-moz-transition: text-shadow 0.5s linear;
+	-ms-transition: text-shadow 0.5s linear;
+	-o-transition: text-shadow 0.5s linear;
+	transition: text-shadow 0.5s linear;
+	margin-right: 15px;
+}
+
+h1.glow, h2.glow, h3.glow, h4.glow, h5.glow, h6.glow {
+	text-shadow: 0 0 15px cyan;
+}
+
+dt {
+	font-weight: bold;
+}
+
+div.multicol {
+	-moz-column-gap: 1em;
+	-webkit-column-gap: 1em;
+	-moz-column-count: 3;
+	-webkit-column-count: 3;
+}
+
+p.startli, p.startdd {
+	margin-top: 2px;
+}
+
+p.starttd {
+	margin-top: 0px;
+}
+
+p.endli {
+	margin-bottom: 0px;
+}
+
+p.enddd {
+	margin-bottom: 4px;
+}
+
+p.endtd {
+	margin-bottom: 2px;
+}
+
+/* @end */
+
+caption {
+	font-weight: bold;
+}
+
+span.legend {
+        font-size: 70%;
+        text-align: center;
+}
+
+h3.version {
+        font-size: 90%;
+        text-align: center;
+}
+
+div.qindex, div.navtab{
+	background-color: #EBEFF6;
+	border: 1px solid #A3B4D7;
+	text-align: center;
+}
+
+div.qindex, div.navpath {
+	width: 100%;
+	line-height: 140%;
+}
+
+div.navtab {
+	margin-right: 15px;
+}
+
+/* @group Link Styling */
+
+a {
+	color: #3D578C;
+	font-weight: normal;
+	text-decoration: none;
+}
+
+.contents a:visited {
+	color: #4665A2;
+}
+
+a:hover {
+	text-decoration: underline;
+}
+
+a.qindex {
+	font-weight: bold;
+}
+
+a.qindexHL {
+	font-weight: bold;
+	background-color: #9CAFD4;
+	color: #ffffff;
+	border: 1px double #869DCA;
+}
+
+.contents a.qindexHL:visited {
+        color: #ffffff;
+}
+
+a.el {
+	font-weight: bold;
+}
+
+a.elRef {
+}
+
+a.code, a.code:visited, a.line, a.line:visited {
+	color: #4665A2;
+}
+
+a.codeRef, a.codeRef:visited, a.lineRef, a.lineRef:visited {
+	color: #4665A2;
+}
+
+/* @end */
+
+dl.el {
+	margin-left: -1cm;
+}
+
+pre.fragment {
+        border: 1px solid #C4CFE5;
+        background-color: #FBFCFD;
+        padding: 4px 6px;
+        margin: 4px 8px 4px 2px;
+        overflow: auto;
+        word-wrap: break-word;
+        font-size:  9pt;
+        line-height: 125%;
+        font-family: monospace, fixed;
+        font-size: 105%;
+}
+
+div.fragment {
+        padding: 4px 6px;
+        margin: 4px 8px 4px 2px;
+	background-color: #FBFCFD;
+	border: 1px solid #C4CFE5;
+}
+
+div.line {
+	font-family: monospace, fixed;
+        font-size: 13px;
+	min-height: 13px;
+	line-height: 1.0;
+	text-wrap: unrestricted;
+	white-space: -moz-pre-wrap; /* Moz */
+	white-space: -pre-wrap;     /* Opera 4-6 */
+	white-space: -o-pre-wrap;   /* Opera 7 */
+	white-space: pre-wrap;      /* CSS3  */
+	word-wrap: break-word;      /* IE 5.5+ */
+	text-indent: -53px;
+	padding-left: 53px;
+	padding-bottom: 0px;
+	margin: 0px;
+	-webkit-transition-property: background-color, box-shadow;
+	-webkit-transition-duration: 0.5s;
+	-moz-transition-property: background-color, box-shadow;
+	-moz-transition-duration: 0.5s;
+	-ms-transition-property: background-color, box-shadow;
+	-ms-transition-duration: 0.5s;
+	-o-transition-property: background-color, box-shadow;
+	-o-transition-duration: 0.5s;
+	transition-property: background-color, box-shadow;
+	transition-duration: 0.5s;
+}
+
+div.line.glow {
+	background-color: cyan;
+	box-shadow: 0 0 10px cyan;
+}
+
+
+span.lineno {
+	padding-right: 4px;
+	text-align: right;
+	border-right: 2px solid #0F0;
+	background-color: #E8E8E8;
+        white-space: pre;
+}
+span.lineno a {
+	background-color: #D8D8D8;
+}
+
+span.lineno a:hover {
+	background-color: #C8C8C8;
+}
+
+div.ah {
+	background-color: black;
+	font-weight: bold;
+	color: #ffffff;
+	margin-bottom: 3px;
+	margin-top: 3px;
+	padding: 0.2em;
+	border: solid thin #333;
+	border-radius: 0.5em;
+	-webkit-border-radius: .5em;
+	-moz-border-radius: .5em;
+	box-shadow: 2px 2px 3px #999;
+	-webkit-box-shadow: 2px 2px 3px #999;
+	-moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px;
+	background-image: -webkit-gradient(linear, left top, left bottom, from(#eee), to(#000),color-stop(0.3, #444));
+	background-image: -moz-linear-gradient(center top, #eee 0%, #444 40%, #000);
+}
+
+div.groupHeader {
+	margin-left: 16px;
+	margin-top: 12px;
+	font-weight: bold;
+}
+
+div.groupText {
+	margin-left: 16px;
+	font-style: italic;
+}
+
+body {
+	background-color: white;
+	color: black;
+        margin: 0;
+}
+
+div.contents {
+	margin-top: 10px;
+	margin-left: 12px;
+	margin-right: 8px;
+}
+
+td.indexkey {
+	background-color: #EBEFF6;
+	font-weight: bold;
+	border: 1px solid #C4CFE5;
+	margin: 2px 0px 2px 0;
+	padding: 2px 10px;
+        white-space: nowrap;
+        vertical-align: top;
+}
+
+td.indexvalue {
+	background-color: #EBEFF6;
+	border: 1px solid #C4CFE5;
+	padding: 2px 10px;
+	margin: 2px 0px;
+}
+
+tr.memlist {
+	background-color: #EEF1F7;
+}
+
+p.formulaDsp {
+	text-align: center;
+}
+
+img.formulaDsp {
+
+}
+
+img.formulaInl {
+	vertical-align: middle;
+}
+
+div.center {
+	text-align: center;
+        margin-top: 0px;
+        margin-bottom: 0px;
+        padding: 0px;
+}
+
+div.center img {
+	border: 0px;
+}
+
+address.footer {
+	text-align: right;
+	padding-right: 12px;
+}
+
+img.footer {
+	border: 0px;
+	vertical-align: middle;
+}
+
+/* @group Code Colorization */
+
+span.keyword {
+	color: #008000
+}
+
+span.keywordtype {
+	color: #604020
+}
+
+span.keywordflow {
+	color: #e08000
+}
+
+span.comment {
+	color: #800000
+}
+
+span.preprocessor {
+	color: #806020
+}
+
+span.stringliteral {
+	color: #002080
+}
+
+span.charliteral {
+	color: #008080
+}
+
+span.vhdldigit {
+	color: #ff00ff
+}
+
+span.vhdlchar {
+	color: #000000
+}
+
+span.vhdlkeyword {
+	color: #700070
+}
+
+span.vhdllogic {
+	color: #ff0000
+}
+
+blockquote {
+        background-color: #F7F8FB;
+        border-left: 2px solid #9CAFD4;
+        margin: 0 24px 0 4px;
+        padding: 0 12px 0 16px;
+}
+
+/* @end */
+
+/*
+.search {
+	color: #003399;
+	font-weight: bold;
+}
+
+form.search {
+	margin-bottom: 0px;
+	margin-top: 0px;
+}
+
+input.search {
+	font-size: 75%;
+	color: #000080;
+	font-weight: normal;
+	background-color: #e8eef2;
+}
+*/
+
+td.tiny {
+	font-size: 75%;
+}
+
+.dirtab {
+	padding: 4px;
+	border-collapse: collapse;
+	border: 1px solid #A3B4D7;
+}
+
+th.dirtab {
+	background: #EBEFF6;
+	font-weight: bold;
+}
+
+hr {
+	height: 0px;
+	border: none;
+	border-top: 1px solid #4A6AAA;
+}
+
+hr.footer {
+	height: 1px;
+}
+
+/* @group Member Descriptions */
+
+table.memberdecls {
+	border-spacing: 0px;
+	padding: 0px;
+}
+
+.memberdecls td, .fieldtable tr {
+	-webkit-transition-property: background-color, box-shadow;
+	-webkit-transition-duration: 0.5s;
+	-moz-transition-property: background-color, box-shadow;
+	-moz-transition-duration: 0.5s;
+	-ms-transition-property: background-color, box-shadow;
+	-ms-transition-duration: 0.5s;
+	-o-transition-property: background-color, box-shadow;
+	-o-transition-duration: 0.5s;
+	transition-property: background-color, box-shadow;
+	transition-duration: 0.5s;
+}
+
+.memberdecls td.glow, .fieldtable tr.glow {
+	background-color: cyan;
+	box-shadow: 0 0 15px cyan;
+}
+
+.mdescLeft, .mdescRight,
+.memItemLeft, .memItemRight,
+.memTemplItemLeft, .memTemplItemRight, .memTemplParams {
+	background-color: #F9FAFC;
+	border: none;
+	margin: 4px;
+	padding: 1px 0 0 8px;
+}
+
+.mdescLeft, .mdescRight {
+	padding: 0px 8px 4px 8px;
+	color: #555;
+}
+
+.memSeparator {
+        border-bottom: 1px solid #DEE4F0;
+        line-height: 1px;
+        margin: 0px;
+        padding: 0px;
+}
+
+.memItemLeft, .memTemplItemLeft {
+        white-space: nowrap;
+}
+
+.memItemRight {
+	width: 100%;
+}
+
+.memTemplParams {
+	color: #4665A2;
+        white-space: nowrap;
+	font-size: 80%;
+}
+
+/* @end */
+
+/* @group Member Details */
+
+/* Styles for detailed member documentation */
+
+.memtemplate {
+	font-size: 80%;
+	color: #4665A2;
+	font-weight: normal;
+	margin-left: 9px;
+}
+
+.memnav {
+	background-color: #EBEFF6;
+	border: 1px solid #A3B4D7;
+	text-align: center;
+	margin: 2px;
+	margin-right: 15px;
+	padding: 2px;
+}
+
+.mempage {
+	width: 100%;
+}
+
+.memitem {
+	padding: 0;
+	margin-bottom: 10px;
+	margin-right: 5px;
+        -webkit-transition: box-shadow 0.5s linear;
+        -moz-transition: box-shadow 0.5s linear;
+        -ms-transition: box-shadow 0.5s linear;
+        -o-transition: box-shadow 0.5s linear;
+        transition: box-shadow 0.5s linear;
+        display: table !important;
+        width: 100%;
+}
+
+.memitem.glow {
+         box-shadow: 0 0 15px cyan;
+}
+
+.memname {
+        font-weight: bold;
+        margin-left: 6px;
+}
+
+.memname td {
+	vertical-align: bottom;
+}
+
+.memproto, dl.reflist dt {
+        border-top: 1px solid #A8B8D9;
+        border-left: 1px solid #A8B8D9;
+        border-right: 1px solid #A8B8D9;
+        padding: 6px 0px 6px 0px;
+        color: #253555;
+        font-weight: bold;
+        text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9);
+        background-image:url('nav_f.png');
+        background-repeat:repeat-x;
+        background-color: #E2E8F2;
+        /* opera specific markup */
+        box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
+        border-top-right-radius: 4px;
+        border-top-left-radius: 4px;
+        /* firefox specific markup */
+        -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px;
+        -moz-border-radius-topright: 4px;
+        -moz-border-radius-topleft: 4px;
+        /* webkit specific markup */
+        -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
+        -webkit-border-top-right-radius: 4px;
+        -webkit-border-top-left-radius: 4px;
+
+}
+
+.memdoc, dl.reflist dd {
+        border-bottom: 1px solid #A8B8D9;
+        border-left: 1px solid #A8B8D9;
+        border-right: 1px solid #A8B8D9;
+        padding: 6px 10px 2px 10px;
+        background-color: #FBFCFD;
+        border-top-width: 0;
+        background-image:url('nav_g.png');
+        background-repeat:repeat-x;
+        background-color: #FFFFFF;
+        /* opera specific markup */
+        border-bottom-left-radius: 4px;
+        border-bottom-right-radius: 4px;
+        box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
+        /* firefox specific markup */
+        -moz-border-radius-bottomleft: 4px;
+        -moz-border-radius-bottomright: 4px;
+        -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px;
+        /* webkit specific markup */
+        -webkit-border-bottom-left-radius: 4px;
+        -webkit-border-bottom-right-radius: 4px;
+        -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
+}
+
+dl.reflist dt {
+        padding: 5px;
+}
+
+dl.reflist dd {
+        margin: 0px 0px 10px 0px;
+        padding: 5px;
+}
+
+.paramkey {
+	text-align: right;
+}
+
+.paramtype {
+	white-space: nowrap;
+}
+
+.paramname {
+	color: #602020;
+	white-space: nowrap;
+}
+.paramname em {
+	font-style: normal;
+}
+.paramname code {
+        line-height: 14px;
+}
+
+.params, .retval, .exception, .tparams {
+        margin-left: 0px;
+        padding-left: 0px;
+}
+
+.params .paramname, .retval .paramname {
+        font-weight: bold;
+        vertical-align: top;
+}
+
+.params .paramtype {
+        font-style: italic;
+        vertical-align: top;
+}
+
+.params .paramdir {
+        font-family: "courier new",courier,monospace;
+        vertical-align: top;
+}
+
+table.mlabels {
+	border-spacing: 0px;
+}
+
+td.mlabels-left {
+	width: 100%;
+	padding: 0px;
+}
+
+td.mlabels-right {
+	vertical-align: bottom;
+	padding: 0px;
+	white-space: nowrap;
+}
+
+span.mlabels {
+        margin-left: 8px;
+}
+
+span.mlabel {
+        background-color: #728DC1;
+        border-top:1px solid #5373B4;
+        border-left:1px solid #5373B4;
+        border-right:1px solid #C4CFE5;
+        border-bottom:1px solid #C4CFE5;
+	text-shadow: none;
+	color: white;
+	margin-right: 4px;
+	padding: 2px 3px;
+	border-radius: 3px;
+	font-size: 7pt;
+	white-space: nowrap;
+	vertical-align: middle;
+}
+
+
+
+/* @end */
+
+/* these are for tree view inside a (index) page */
+
+div.directory {
+        margin: 10px 0px;
+        border-top: 1px solid #9CAFD4;
+        border-bottom: 1px solid #9CAFD4;
+        width: 100%;
+}
+
+.directory table {
+        border-collapse:collapse;
+}
+
+.directory td {
+        margin: 0px;
+        padding: 0px;
+	vertical-align: top;
+}
+
+.directory td.entry {
+        white-space: nowrap;
+        padding-right: 6px;
+	padding-top: 3px;
+}
+
+.directory td.entry a {
+        outline:none;
+}
+
+.directory td.entry a img {
+        border: none;
+}
+
+.directory td.desc {
+        width: 100%;
+        padding-left: 6px;
+	padding-right: 6px;
+	padding-top: 3px;
+	border-left: 1px solid rgba(0,0,0,0.05);
+}
+
+.directory tr.even {
+	padding-left: 6px;
+	background-color: #F7F8FB;
+}
+
+.directory img {
+	vertical-align: -30%;
+}
+
+.directory .levels {
+        white-space: nowrap;
+        width: 100%;
+        text-align: right;
+        font-size: 9pt;
+}
+
+.directory .levels span {
+        cursor: pointer;
+        padding-left: 2px;
+        padding-right: 2px;
+	color: #3D578C;
+}
+
+.arrow {
+    color: #9CAFD4;
+    -webkit-user-select: none;
+    -khtml-user-select: none;
+    -moz-user-select: none;
+    -ms-user-select: none;
+    user-select: none;
+    cursor: pointer;
+    font-size: 80%;
+    display: inline-block;
+    width: 16px;
+    height: 22px;
+}
+
+.icon {
+    font-family: Arial, Helvetica;
+    font-weight: bold;
+    font-size: 12px;
+    height: 14px;
+    width: 16px;
+    display: inline-block;
+    background-color: #728DC1;
+    color: white;
+    text-align: center;
+    border-radius: 4px;
+    margin-left: 2px;
+    margin-right: 2px;
+}
+
+.icona {
+    width: 24px;
+    height: 22px;
+    display: inline-block;
+}
+
+.iconfopen {
+    width: 24px;
+    height: 18px;
+    margin-bottom: 4px;
+    background-image:url('ftv2folderopen.png');
+    background-position: 0px -4px;
+    background-repeat: repeat-y;
+    vertical-align:top;
+    display: inline-block;
+}
+
+.iconfclosed {
+    width: 24px;
+    height: 18px;
+    margin-bottom: 4px;
+    background-image:url('ftv2folderclosed.png');
+    background-position: 0px -4px;
+    background-repeat: repeat-y;
+    vertical-align:top;
+    display: inline-block;
+}
+
+.icondoc {
+    width: 24px;
+    height: 18px;
+    margin-bottom: 4px;
+    background-image:url('ftv2doc.png');
+    background-position: 0px -4px;
+    background-repeat: repeat-y;
+    vertical-align:top;
+    display: inline-block;
+}
+
+table.directory {
+    font: 400 14px Roboto,sans-serif;
+}
+
+/* @end */
+
+div.dynheader {
+        margin-top: 8px;
+	-webkit-touch-callout: none;
+	-webkit-user-select: none;
+	-khtml-user-select: none;
+	-moz-user-select: none;
+	-ms-user-select: none;
+	user-select: none;
+}
+
+address {
+	font-style: normal;
+	color: #2A3D61;
+}
+
+table.doxtable {
+	border-collapse:collapse;
+        margin-top: 4px;
+        margin-bottom: 4px;
+}
+
+table.doxtable td, table.doxtable th {
+	border: 1px solid #2D4068;
+	padding: 3px 7px 2px;
+}
+
+table.doxtable th {
+	background-color: #374F7F;
+	color: #FFFFFF;
+	font-size: 110%;
+	padding-bottom: 4px;
+	padding-top: 5px;
+}
+
+table.fieldtable {
+        /*width: 100%;*/
+        margin-bottom: 10px;
+        border: 1px solid #A8B8D9;
+        border-spacing: 0px;
+        -moz-border-radius: 4px;
+        -webkit-border-radius: 4px;
+        border-radius: 4px;
+        -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px;
+        -webkit-box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15);
+        box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15);
+}
+
+.fieldtable td, .fieldtable th {
+        padding: 3px 7px 2px;
+}
+
+.fieldtable td.fieldtype, .fieldtable td.fieldname {
+        white-space: nowrap;
+        border-right: 1px solid #A8B8D9;
+        border-bottom: 1px solid #A8B8D9;
+        vertical-align: top;
+}
+
+.fieldtable td.fieldname {
+        padding-top: 3px;
+}
+
+.fieldtable td.fielddoc {
+        border-bottom: 1px solid #A8B8D9;
+        /*width: 100%;*/
+}
+
+.fieldtable td.fielddoc p:first-child {
+        margin-top: 0px;
+}
+
+.fieldtable td.fielddoc p:last-child {
+        margin-bottom: 2px;
+}
+
+.fieldtable tr:last-child td {
+        border-bottom: none;
+}
+
+.fieldtable th {
+        background-image:url('nav_f.png');
+        background-repeat:repeat-x;
+        background-color: #E2E8F2;
+        font-size: 90%;
+        color: #253555;
+        padding-bottom: 4px;
+        padding-top: 5px;
+        text-align:left;
+        -moz-border-radius-topleft: 4px;
+        -moz-border-radius-topright: 4px;
+        -webkit-border-top-left-radius: 4px;
+        -webkit-border-top-right-radius: 4px;
+        border-top-left-radius: 4px;
+        border-top-right-radius: 4px;
+        border-bottom: 1px solid #A8B8D9;
+}
+
+
+.tabsearch {
+	top: 0px;
+	left: 10px;
+	height: 36px;
+	background-image: url('tab_b.png');
+	z-index: 101;
+	overflow: hidden;
+	font-size: 13px;
+}
+
+.navpath ul
+{
+	font-size: 11px;
+	background-image:url('tab_b.png');
+	background-repeat:repeat-x;
+	background-position: 0 -5px;
+	height:30px;
+	line-height:30px;
+	color:#8AA0CC;
+	border:solid 1px #C2CDE4;
+	overflow:hidden;
+	margin:0px;
+	padding:0px;
+}
+
+.navpath li
+{
+	list-style-type:none;
+	float:left;
+	padding-left:10px;
+	padding-right:15px;
+	background-image:url('bc_s.png');
+	background-repeat:no-repeat;
+	background-position:right;
+	color:#364D7C;
+}
+
+.navpath li.navelem a
+{
+	height:32px;
+	display:block;
+	text-decoration: none;
+	outline: none;
+	color: #283A5D;
+	font-family: 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif;
+	text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9);
+	text-decoration: none;
+}
+
+.navpath li.navelem a:hover
+{
+	color:#6884BD;
+}
+
+.navpath li.footer
+{
+        list-style-type:none;
+        float:right;
+        padding-left:10px;
+        padding-right:15px;
+        background-image:none;
+        background-repeat:no-repeat;
+        background-position:right;
+        color:#364D7C;
+        font-size: 8pt;
+}
+
+
+div.summary
+{
+	float: right;
+	font-size: 8pt;
+	padding-right: 5px;
+	width: 50%;
+	text-align: right;
+}
+
+div.summary a
+{
+	white-space: nowrap;
+}
+
+div.ingroups
+{
+	font-size: 8pt;
+	width: 50%;
+	text-align: left;
+}
+
+div.ingroups a
+{
+	white-space: nowrap;
+}
+
+div.header
+{
+        background-image:url('nav_h.png');
+        background-repeat:repeat-x;
+	background-color: #F9FAFC;
+	margin:  0px;
+	border-bottom: 1px solid #C4CFE5;
+}
+
+div.headertitle
+{
+	padding: 5px 5px 5px 10px;
+}
+
+dl
+{
+        padding: 0 0 0 10px;
+}
+
+/* dl.note, dl.warning, dl.attention, dl.pre, dl.post, dl.invariant, dl.deprecated, dl.todo, dl.test, dl.bug */
+dl.section
+{
+	margin-left: 0px;
+	padding-left: 0px;
+}
+
+dl.note
+{
+        margin-left:-7px;
+        padding-left: 3px;
+        border-left:4px solid;
+        border-color: #D0C000;
+}
+
+dl.warning, dl.attention
+{
+        margin-left:-7px;
+        padding-left: 3px;
+        border-left:4px solid;
+        border-color: #FF0000;
+}
+
+dl.pre, dl.post, dl.invariant
+{
+        margin-left:-7px;
+        padding-left: 3px;
+        border-left:4px solid;
+        border-color: #00D000;
+}
+
+dl.deprecated
+{
+        margin-left:-7px;
+        padding-left: 3px;
+        border-left:4px solid;
+        border-color: #505050;
+}
+
+dl.todo
+{
+        margin-left:-7px;
+        padding-left: 3px;
+        border-left:4px solid;
+        border-color: #00C0E0;
+}
+
+dl.test
+{
+        margin-left:-7px;
+        padding-left: 3px;
+        border-left:4px solid;
+        border-color: #3030E0;
+}
+
+dl.bug
+{
+        margin-left:-7px;
+        padding-left: 3px;
+        border-left:4px solid;
+        border-color: #C08050;
+}
+
+dl.section dd {
+	margin-bottom: 6px;
+}
+
+
+#projectlogo
+{
+	text-align: center;
+	vertical-align: bottom;
+	border-collapse: separate;
+}
+
+#projectlogo img
+{
+	border: 0px none;
+}
+
+#projectname
+{
+	font: 300% Tahoma, Arial,sans-serif;
+	margin: 0px;
+	padding: 2px 0px;
+}
+
+#projectbrief
+{
+	font: 120% Tahoma, Arial,sans-serif;
+	margin: 0px;
+	padding: 0px;
+}
+
+#projectnumber
+{
+	font: 50% Tahoma, Arial,sans-serif;
+	margin: 0px;
+	padding: 0px;
+}
+
+#titlearea
+{
+	padding: 0px;
+	margin: 0px;
+	width: 100%;
+	border-bottom: 1px solid #5373B4;
+	color: #FFFFFF;
+	background: #006699;
+}
+
+.image
+{
+        text-align: center;
+}
+
+.dotgraph
+{
+        text-align: center;
+}
+
+.mscgraph
+{
+        text-align: center;
+}
+
+.diagraph
+{
+        text-align: center;
+}
+
+.caption
+{
+	font-weight: bold;
+}
+
+div.zoom
+{
+	border: 1px solid #90A5CE;
+}
+
+dl.citelist {
+        margin-bottom:50px;
+}
+
+dl.citelist dt {
+        color:#334975;
+        float:left;
+        font-weight:bold;
+        margin-right:10px;
+        padding:5px;
+}
+
+dl.citelist dd {
+        margin:2px 0;
+        padding:5px 0;
+}
+
+div.toc {
+        padding: 14px 25px;
+        background-color: #F4F6FA;
+        border: 1px solid #D8DFEE;
+        border-radius: 7px 7px 7px 7px;
+        float: right;
+        height: auto;
+        margin: 0 20px 10px 10px;
+        width: 200px;
+}
+
+div.toc li {
+        background: url("bdwn.png") no-repeat scroll 0 5px transparent;
+        font: 10px/1.2 Verdana,DejaVu Sans,Geneva,sans-serif;
+        margin-top: 5px;
+        padding-left: 10px;
+        padding-top: 2px;
+}
+
+div.toc h3 {
+        font: bold 12px/1.2 Arial,FreeSans,sans-serif;
+	color: #4665A2;
+        border-bottom: 0 none;
+        margin: 0;
+}
+
+div.toc ul {
+        list-style: none outside none;
+        border: medium none;
+        padding: 0px;
+}
+
+div.toc li.level1 {
+        margin-left: 0px;
+}
+
+div.toc li.level2 {
+        margin-left: 15px;
+}
+
+div.toc li.level3 {
+        margin-left: 30px;
+}
+
+div.toc li.level4 {
+        margin-left: 45px;
+}
+
+.inherit_header {
+        font-weight: bold;
+        color: gray;
+        cursor: pointer;
+	-webkit-touch-callout: none;
+	-webkit-user-select: none;
+	-khtml-user-select: none;
+	-moz-user-select: none;
+	-ms-user-select: none;
+	user-select: none;
+}
+
+.inherit_header td {
+        padding: 6px 0px 2px 5px;
+}
+
+.inherit {
+        display: none;
+}
+
+tr.heading h2 {
+        margin-top: 12px;
+        margin-bottom: 4px;
+}
+
+/* tooltip related style info */
+
+.ttc {
+        position: absolute;
+        display: none;
+}
+
+#powerTip {
+	cursor: default;
+	white-space: nowrap;
+	background-color: white;
+	border: 1px solid gray;
+	border-radius: 4px 4px 4px 4px;
+	box-shadow: 1px 1px 7px gray;
+	display: none;
+	font-size: smaller;
+	max-width: 80%;
+	opacity: 0.9;
+	padding: 1ex 1em 1em;
+	position: absolute;
+	z-index: 2147483647;
+}
+
+#powerTip div.ttdoc {
+        color: grey;
+	font-style: italic;
+}
+
+#powerTip div.ttname a {
+        font-weight: bold;
+}
+
+#powerTip div.ttname {
+        font-weight: bold;
+}
+
+#powerTip div.ttdeci {
+        color: #006318;
+}
+
+#powerTip div {
+        margin: 0px;
+        padding: 0px;
+        font: 12px/16px Roboto,sans-serif;
+}
+
+#powerTip:before, #powerTip:after {
+	content: "";
+	position: absolute;
+	margin: 0px;
+}
+
+#powerTip.n:after,  #powerTip.n:before,
+#powerTip.s:after,  #powerTip.s:before,
+#powerTip.w:after,  #powerTip.w:before,
+#powerTip.e:after,  #powerTip.e:before,
+#powerTip.ne:after, #powerTip.ne:before,
+#powerTip.se:after, #powerTip.se:before,
+#powerTip.nw:after, #powerTip.nw:before,
+#powerTip.sw:after, #powerTip.sw:before {
+	border: solid transparent;
+	content: " ";
+	height: 0;
+	width: 0;
+	position: absolute;
+}
+
+#powerTip.n:after,  #powerTip.s:after,
+#powerTip.w:after,  #powerTip.e:after,
+#powerTip.nw:after, #powerTip.ne:after,
+#powerTip.sw:after, #powerTip.se:after {
+	border-color: rgba(255, 255, 255, 0);
+}
+
+#powerTip.n:before,  #powerTip.s:before,
+#powerTip.w:before,  #powerTip.e:before,
+#powerTip.nw:before, #powerTip.ne:before,
+#powerTip.sw:before, #powerTip.se:before {
+	border-color: rgba(128, 128, 128, 0);
+}
+
+#powerTip.n:after,  #powerTip.n:before,
+#powerTip.ne:after, #powerTip.ne:before,
+#powerTip.nw:after, #powerTip.nw:before {
+	top: 100%;
+}
+
+#powerTip.n:after, #powerTip.ne:after, #powerTip.nw:after {
+	border-top-color: #ffffff;
+	border-width: 10px;
+	margin: 0px -10px;
+}
+#powerTip.n:before {
+	border-top-color: #808080;
+	border-width: 11px;
+	margin: 0px -11px;
+}
+#powerTip.n:after, #powerTip.n:before {
+	left: 50%;
+}
+
+#powerTip.nw:after, #powerTip.nw:before {
+	right: 14px;
+}
+
+#powerTip.ne:after, #powerTip.ne:before {
+	left: 14px;
+}
+
+#powerTip.s:after,  #powerTip.s:before,
+#powerTip.se:after, #powerTip.se:before,
+#powerTip.sw:after, #powerTip.sw:before {
+	bottom: 100%;
+}
+
+#powerTip.s:after, #powerTip.se:after, #powerTip.sw:after {
+	border-bottom-color: #ffffff;
+	border-width: 10px;
+	margin: 0px -10px;
+}
+
+#powerTip.s:before, #powerTip.se:before, #powerTip.sw:before {
+	border-bottom-color: #808080;
+	border-width: 11px;
+	margin: 0px -11px;
+}
+
+#powerTip.s:after, #powerTip.s:before {
+	left: 50%;
+}
+
+#powerTip.sw:after, #powerTip.sw:before {
+	right: 14px;
+}
+
+#powerTip.se:after, #powerTip.se:before {
+	left: 14px;
+}
+
+#powerTip.e:after, #powerTip.e:before {
+	left: 100%;
+}
+#powerTip.e:after {
+	border-left-color: #ffffff;
+	border-width: 10px;
+	top: 50%;
+	margin-top: -10px;
+}
+#powerTip.e:before {
+	border-left-color: #808080;
+	border-width: 11px;
+	top: 50%;
+	margin-top: -11px;
+}
+
+#powerTip.w:after, #powerTip.w:before {
+	right: 100%;
+}
+#powerTip.w:after {
+	border-right-color: #ffffff;
+	border-width: 10px;
+	top: 50%;
+	margin-top: -10px;
+}
+#powerTip.w:before {
+	border-right-color: #808080;
+	border-width: 11px;
+	top: 50%;
+	margin-top: -11px;
+}
+
+ at media print
+{
+  #top { display: none; }
+  #side-nav { display: none; }
+  #nav-path { display: none; }
+  body { overflow:visible; }
+  h1, h2, h3, h4, h5, h6 { page-break-after: avoid; }
+  .summary { display: none; }
+  .memitem { page-break-inside: avoid; }
+  #doc-content
+  {
+    margin-left:0 !important;
+    height:auto !important;
+    width:auto !important;
+    overflow:inherit;
+    display:inline;
+  }
+}
+
diff --git a/doxy b/doxy
new file mode 100755
index 0000000..8bab477
--- /dev/null
+++ b/doxy
@@ -0,0 +1,92 @@
+#!/usr/bin/env bash
+
+#!/bin/sh
+if [ "$#" -le 0 ]; then
+  echo "Usage: $0 input_file(s)" >&2
+  exit 1
+fi
+
+INPUT="$@"
+
+P=`pwd`
+
+# basename $0
+C="$0"
+C=`dirname "$C"`
+C=`ls -d1 "$C"`
+
+TARGET_FILE="$C"
+
+cd `dirname "$TARGET_FILE"`
+TARGET_FILE=`basename "$TARGET_FILE"`
+
+# Iterate down a (possible) chain of symlinks
+while [ -L "$TARGET_FILE" ]
+do
+    TARGET_FILE=`readlink "$TARGET_FILE"`
+    cd `dirname "$TARGET_FILE"`
+    TARGET_FILE=`basename "$TARGET_FILE"`
+done
+
+SRCDIR=`pwd -P`
+SRCDIR="$SRCDIR/$TARGET_FILE"
+# echo $SRCDIR
+
+
+if [ -z "$DOXYGEN" ]; then
+	DOXYGEN=`which doxygen`
+
+	if [ $? -ne 0 ]; then
+	        echo Please add 'doxygen' to your PATH
+		exit 1
+	fi
+
+	export DOXYGEN
+fi
+
+if [ ! -x "$DOXYGEN" ]; then
+	echo Please make "$DOXYGEN" - executable!;
+	exit 1;
+fi
+
+if [ -z "$DOXYGEN_CONFIG" ]; then
+	export DOXYGEN_CONFIG="$SRCDIR/dox/Doxyfile.in1"
+fi
+
+if [ ! -r "$DOXYGEN_CONFIG" ]; then
+	echo Please make the doxygen configuration readable: "$DOXYGEN_CONFIG"!;
+	exit 1;
+fi
+
+cd "$P"
+
+INPUTTXT=`echo "$INPUT" | sed -e 's@[ :]@_ at g' -e 's@[\\\/]@__ at g'`
+
+OUTPUT="./DOXY.$INPUTTXT"
+# `mktemp -d -q "./DOXY.$INPUTTXT.XXX"`
+#if [ $? -ne 0 ]; then
+#    echo "$0: Can't create temp dir name, exiting..."
+#    exit 1
+#fi
+
+if [ -d "$OUTPUT" ]; then
+    echo "Directory '$OUTPUT' exists! Deleting..."
+    rm -Rf "$OUTPUT/*"
+else
+    mkdir -p "$OUTPUT/"
+fi
+
+export OUTPUT
+
+export INPUT
+
+export GENERATE_HTML=YES GENERATE_LATEX=YES GENERATE_RTF=YES GENERATE_MAN=YES GENERATE_XML=YES \
+       HTML_OUTPUT=htm  LATEX_OUTPUT=tex   RTF_OUTPUT=rtf   MAN_OUTPUT=man   XML_OUTPUT=xml
+
+export abs_top_srcdir="$SRCDIR" abs_top_builddir="$SRCDIR"
+
+echo Running "$DOXYGEN" "$DOXYGEN_CONFIG" with a bunch of exported variables
+
+$DOXYGEN $DOXYGEN_CONFIG
+
+echo Result for "$INPUT" is in "[$OUTPUT/]", under "[$P/]"...
diff --git a/emacs/.emacs-general b/emacs/.emacs-general
new file mode 100644
index 0000000..5cc62b2
--- /dev/null
+++ b/emacs/.emacs-general
@@ -0,0 +1,184 @@
+;;; Emacs edit mode for this file is  -*- Emacs-Lisp -*-
+
+;;;
+;;; .emacs-general - Emacs initialization file for general emacs
+;;;                  settings which have nothing to do with the
+;;;                  singular-emacs mode, but which we recommend
+;;;                  nevertheless, so that your emacs is more useful.
+;;;
+;;; This file is loaded by .emacs-singular, if it exists in your home directory
+;;; or in the singular-emacs directory.
+;;;
+;;; If you have your own .emacs file, you might consider copying
+;;; this file to your home directory and then load it from your .emacs
+;;; file with: (load-file "~/.emacs-general")
+;;;
+;;;
+
+;; a handy function for customizing the face of point
+(defun customize-face-at-point ()
+  "Customize face which point is at."
+  (interactive)
+  (let ((face (get-text-property (point) 'face)))
+    (if face
+	(customize-face face)
+      (message "No face defined at point"))))
+
+;; I love font-lock mode
+(add-hook 'emacs-lisp-mode-hook	'turn-on-font-lock)
+(add-hook 'lisp-mode-hook	'turn-on-font-lock)
+(add-hook 'c-mode-hook		'turn-on-font-lock)
+(add-hook 'c++-mode-hook		'turn-on-font-lock)
+(add-hook 'perl-mode-hook	'turn-on-font-lock)
+(add-hook 'tex-mode-hook		'turn-on-font-lock)
+(add-hook 'texinfo-mode-hook	'turn-on-font-lock)
+(add-hook 'postscript-mode-hook	'turn-on-font-lock)
+(add-hook 'dired-mode-hook	'turn-on-font-lock)
+(add-hook 'ada-mode-hook		'turn-on-font-lock)
+(add-hook 'TeX-mode-hook  'turn-on-font-lock)
+(add-hook 'shell-mode-hook 'turn-on-font-lock)
+
+;;;
+;;; settings for both Emacs and XEmacs
+;;;
+(custom-set-variables
+ '(next-line-add-newlines nil)
+ '(require-final-newline nil)
+ '(line-number-mode t)
+ '(kill-whole-line t)
+ '(truncate-lines t)
+ ; I like unique buffer names based on dirs
+ '(uniquify-buffer-name-style 'post-forward-angle-brackets))
+
+(require 'uniquify)
+
+(cond ((string-match "XEmacs\\|Lucid" emacs-version)
+       ;;
+       ;; XEmacs specific stuff
+       ;;
+
+       ;; I like some more  keybindings for better moving
+       (define-key global-map '(control up)
+	 '(lambda () (interactive) (scroll-up -1)))
+       ;; control-, scrolls up
+       (define-key global-map '(control down)
+	 '(lambda () (interactive) (scroll-up 1)))
+
+       ;; a function which on C-= reload a file automatically without
+       ;; asking for confirmation got it from From: Richard Mlynarik
+       ;; <mly at adoc.xerox.com> on 1/18/95
+       ;; find-alternate-file (C-x C-v) is almost equivalent
+       (global-set-key [(control =)] '(lambda ()
+					(interactive)
+					(or (verify-visited-file-modtime
+					     (current-buffer))
+					    (revert-buffer t t))))
+       ;; turn on auto-compression of gz files
+       (toggle-auto-compression 1)
+
+       ;; Use the "Describe Variable..." option on the "Help" menu
+       ;; or C-h v to find out what these variables mean.
+       (custom-set-variables
+	'(complex-buffers-menu-p t)
+	'(kill-whole-line t))
+
+       (setq minibuffer-confirm-incomplete t)
+
+       ;; show matching parantheses
+       (paren-set-mode 'paren)
+
+       ;; func-menu is a package that scans your source file for function
+       ;; definitions and makes a menubar entry that lets you jump to any
+       ;; particular function definition by selecting it from the menu.  The
+       ;; following code turns this on for all of the recognized languages.
+       (require 'func-menu)
+       (define-key global-map 'f8 'function-menu)
+       (add-hook 'find-file-hooks 'fume-add-menubar-entry)
+       (define-key global-map "\C-cl" 'fume-list-functions)
+       (define-key global-map "\C-cg" 'fume-prompt-function-goto)
+
+       ;; The Hyperbole information manager package uses (shift button2) and
+       ;; (shift button3) to provide context-sensitive mouse keys.  If you
+       ;; use this next binding, it will conflict with Hyperbole's setup.
+       ;; Choose another mouse key if you use Hyperbole.
+       (define-key global-map '(shift button3) 'mouse-function-menu)
+
+       ;; For descriptions of the following user-customizable variables,
+       ;; type C-h v <variable>
+       (setq fume-max-items 25
+             fume-fn-window-position 3
+             fume-auto-position-popup t
+             fume-display-in-modeline-p t
+             fume-menubar-menu-location "File"
+             fume-buffer-name "*Function List*"
+             fume-no-prompt-on-valid-default nil)
+
+       ;; end Xemacs stuff
+       )
+      (t
+       ;;
+       ;; Emcas stuff
+       ;;
+
+       ;; show matching parantheses
+       (show-paren-mode t)
+
+       ;; turn on auto (de)compression of files
+       (auto-compression-mode t)
+
+       ;; End Emcas stuff
+       )
+      )
+
+;; use auctex as default mode for editing latex stuff
+(let ((auctex-filename (locate-library "tex-site")))
+  (if auctex-filename
+      (require 'tex-site auctex-filename)))
+
+;; put stuff here which should not be/only be executed under
+;; mswindows/unix
+(cond ((or (eq system-type 'cygwin32)
+	   (eq system-type 'windows-nt))
+;;; mswindows stuff
+
+       ;; Let shell be /bin/bash, if it exists
+       (cond ((file-exists-p "/bin/bash")
+	      (setq explicit-shell-filename "/bin/bash")
+	      (setq explicit-bash-args (list "--login"  "-i"))))
+
+; patch these function so that they do not use ~ for backup under
+; mswindows
+(defun make-backup-file-name (file)
+  "Create the non-numeric backup file name for FILE.
+This is a separate function so you can redefine it for customization."
+  (if (eq system-type 'ms-dos)
+      (let ((fn (file-name-nondirectory file)))
+	(concat (file-name-directory file)
+		(if (string-match "\\([^.]*\\)\\(\\..*\\)?" fn)
+		    (substring fn 0 (match-end 1)))
+		".bak"))
+    (if (or (eq system-type 'cygwin32)
+	    (eq system-type 'windows-nt))
+	(concat file ".bak")
+      (concat file "~"))))
+
+(defun backup-file-name-p (file)
+  "Return non-nil if FILE is a backup file name (numeric or not).
+This is a separate function so you can redefine it for customization.
+You may need to redefine `file-name-sans-versions' as well."
+  (if (or (eq system-type 'ms-dos)
+	  (eq system-type 'cygwin32)
+	  (eq system-type 'windows-nt))
+      (string-match "\\.bak\\'" file)
+      (string-match "~\\'" file)))
+
+;;; end mswindows stuff
+)
+(t
+;;; stuff for unix only
+
+;;; end stuff for unix only
+))
+
+
+
diff --git a/emacs/.emacs-singular b/emacs/.emacs-singular
new file mode 100644
index 0000000..e2a1be0
--- /dev/null
+++ b/emacs/.emacs-singular
@@ -0,0 +1,234 @@
+;;; Emacs edit mode for this file is  -*- Emacs-Lisp -*-
+
+;;;
+;;; .emacs-singular - Emacs initialization file to use for
+;;;                   Singular interactive mode.
+;;;
+;;; If you run ESingular, then this file is loaded instead of the
+;;; default ~/.emacs initialization file.
+;;;
+;;; How you use this file very much depends on your attitude
+;;; towards Emacs:
+;;;
+;;; 1) If you are going to use Emacs solely as frontend to
+;;;    Singular you do not have to worry at all about this file.
+;;; 2) If you are already an experienced Emacs user you may
+;;;    want to copy this file's contents to your .emacs file.
+;;; 3) If you are planning to become an experienced Emacs user
+;;;    you may use this file as starting point for your .emacs
+;;;    file, that is, for your Emacs initialization file.  Simply
+;;;    copy it to your home directory and rename it to ".emacs"
+;;;    (without the quotes, of course).  Then edit it as
+;;;    described below.
+;;;
+;;; In cases 2) and 3) you should be careful what exactly to copy
+;;; to your .emacs file.  In general, you need the following:
+;;;
+;;; o the hook-customizations with `add-hook';
+;;; o the pre-customized settings with `custom-set-variables' and
+;;;   `custom-set-faces';
+;;; o the code which creates menus for starting Singular;
+;;; o the code which loads singular.el (located at the end of
+;;;   this file) you have to replace by something else, for
+;;;   example, an `autoload'.
+;;; o the code which is in .emacs-general
+;;;
+;;; Here is how the Singular customization in your .emacs may
+;;; look like:
+;;;
+;;; ;; extra key bindings
+;;; (add-hook 'singular-interactive-mode-hook
+;;;            <... code omitted, see below for details ...>)
+;;;
+;;; ;; other, "non-customizable" settings
+;;; (add-hook 'singular-interactive-mode-hook
+;;;            <... code omitted, see below for details ...>)
+;;;
+;;; ;; pre-customized settings
+;;; (custom-set-variables
+;;;  <... code omitted, see below for details ...>)
+;;; (custom-set-faces
+;;;  <... code omitted, see below for details ...>)
+;;;
+;;; ;; add global menus for Singular
+;;; <... choose your version for either Emacs or XEmacs, see below ...>
+;;;
+;;; ;; add Singular toolbar for XEmacs
+;;; <... insert the code below if you are running XEmacs ...>
+;;;
+;;; ;; add Singular Emacs home directory to `load-path'
+;;; (setq load-path (cons "<your-singular-emacs-home-directory>" load-path))
+;;; (autoload 'singular "singular"
+;;;   "Start Singular using default values." t)
+;;; (autoload 'singular-other "singular"
+;;;   "Ask for arguments and start Singular." t)
+;;;
+
+;; extra key bindings
+(add-hook 'singular-interactive-mode-hook
+	  (function (lambda ()
+		      ;; control cursor keys
+		      (cond
+		       ;; Emacs
+		       ((eq singular-emacs-flavor 'emacs)
+			(local-set-key [C-prior] 'singular-scroll-right)
+			(local-set-key [C-next] 'singular-scroll-left)
+			(local-set-key [C-up] 'comint-previous-prompt)
+			(local-set-key [C-down] 'comint-next-prompt))
+		       ;; XEmacs
+		       (t
+			(local-set-key [(control prior)] 'singular-scroll-right)
+			(local-set-key [(control next)] 'singular-scroll-left)
+			(local-set-key [(control up)] 'comint-previous-prompt)
+			(local-set-key [(control down)] 'comint-next-prompt))))))
+
+;; other, "non-customizable" settings
+
+;; put stuff here which should not be/only be executed under
+;; mswindows/unix
+(cond ((or (eq system-type 'cygwin32)
+	   (eq system-type 'windows-nt))
+       ;; mswindows stuff
+
+       )
+      (t
+       ;; unix stuff
+
+       ;; lazy-lock seems to be broken under mswindows:
+       ;; causes delay of input (only reacts after mouse click), or even total
+       ;; hang
+       ;(add-hook 'font-lock-mode-hook 'lazy-lock-mode)
+       ;(setq font-lock-support-mode 'lazy-lock-mode)
+
+       ;; somewhat nicer scrolling This causes a core dump with 21.1.9
+       ;; under cygwin, when a file is opened with a button
+       ;; Fixed it with a simmple patch, by working around the
+       ;; assertion in file indent.c line 517 (or so). This was
+       ;; officially fixed in 21.1.10 -- still sometimes
+       ;; interactive windows disappeared. Hence, do not set it under
+       ;; Windows
+       (setq scroll-step 10)
+
+       )
+      )
+
+(add-hook 'singular-interactive-mode-hook
+	  (function (lambda () (font-lock-mode 1))))
+
+;; turn on c++-mode for files ending in ".sing" and ".lib"
+(setq auto-mode-alist (cons '("\\.sing\\'" . c++-mode) auto-mode-alist))
+(setq auto-mode-alist (cons '("\\.lib\\'" .  c++-mode) auto-mode-alist))
+(add-hook 'c++-mode-hook
+	  (function (lambda () (font-lock-mode 1))))
+
+
+
+;; this is a work-around for early version of Font Lock mode
+;; which do not use `defface' to define faces.  It forces
+;; `custom-set-faces' to define the faces immediately.
+(make-face 'font-lock-comment-face)
+(make-face 'font-lock-string-face)
+
+;; tricky stuff: these customization settings are not used any
+;; longer as soon as user saved her own to ~/.emacs-singular-cust
+(setq custom-file "~/.emacs-singular-cust")
+(if (file-exists-p custom-file)
+    (load-file custom-file)
+
+;; pre-customized settings
+(custom-set-variables
+ '(mouse-yank-at-point t)
+ '(font-lock-maximum-decoration t t)
+ '(next-line-add-newlines nil)
+ '(paren-mode (quote paren) nil (paren))
+ '(show-paren-mode t nil (paren))
+ '(singular-help-same-window t)
+ '(singular-cursor-key-model (quote terminal))
+ '(transient-mark-mode t)
+ '(Info-button1-follows-hyperlink t)
+ '(singular-section-face-alist (quote ((input . singular-section-input-face) (output)))))
+
+(custom-set-faces
+ '(info-xref ((t (:foreground "blue" :bold t))))
+ '(info-node ((t (:foreground "blue" :bold t :italic t))))
+ '(show-paren-match-face ((((class color)) (:foreground "Red"))))
+ '(font-lock-variable-name-face ((t (:foreground "black"))) t)
+ '(paren-match ((t (:foreground "Red"))) t)
+ '(singular-section-input-face ((t (:bold t))))
+ '(font-lock-string-face ((((class color) (background light)) (:foreground "green4"))))
+ '(font-lock-doc-string-face ((((class color) (background light)) (:foreground "green4"))))
+ '(font-lock-keyword-face ((t (:bold t :foreground "violet"))) t)
+ '(singular-section-output-face ((t (:bold nil))))
+ '(font-lock-type-face ((t (:bold t :foreground "violet"))) t)
+ '(font-lock-comment-face ((t (:bold nil :foreground "Red"))) t)
+ '(font-lock-function-name-face ((t (:bold t :foreground "blue3"))) t))
+ '(info-xref ((t (:foreground "blue" :bold t))))
+ '(info-node ((t (:foreground "blue" :bold t :italic nil))))
+;; obachman: played around a little bit, found this better
+;;  '(singular-section-input-face ((t (:bold t))))
+;;  '(singular-section-output-face ((t (:bold nil))))
+;;  '(font-lock-comment-face ((t (:bold nil :foreground "Grey30"))) t)
+;;  '(font-lock-string-face ((((class color) (background light)) (:foreground "Blue")) (((class color) (background dark)) (:foreground "LightSkyBlue"))) t)
+;;  '(paren-match ((t (:foreground "Red"))) t)
+;;  '(show-paren-match-face ((((class color)) (:foreground "Red")))))
+)
+
+;; update singular-emacs-home-directory
+(setq singular-emacs-home-directory
+      (concat singular-emacs-home-directory
+	      ;; we check for trailing slash and backslash
+	      ;; but unconditionally insert a slash.
+	      ;; Hopefully that works on NT, too.
+	      (if (memq (aref singular-emacs-home-directory
+			      (1- (length singular-emacs-home-directory)))
+			'(?/ ?\\))
+		  "" "/")))
+
+;; add global menus for Singular, Emacs version
+(unless (fboundp 'add-submenu)
+  (setq singular-start-map (make-sparse-keymap))
+  (define-key singular-start-map [menu-bar singular]
+    (cons "Singular" (make-sparse-keymap "Singular")))
+  (define-key singular-start-map [menu-bar singular restart]
+    '("Start..." . singular-other))
+  (define-key singular-start-map [menu-bar singular start-default]
+    '("Start default" . singular))
+  (setq menu-bar-final-item (append '(singular) menu-bar-final-items))
+  (use-local-map singular-start-map))
+
+;; add global menus for Singular, XEmacs version
+(when (fboundp 'add-submenu)
+  (add-submenu nil
+	       '("Singular"
+		 ["Start default" singular t]
+		 ["Start..." singular-other t]))
+  (setq-default current-menubar current-menubar))
+
+;; add Singular button to toolbar for XEmacs
+;(if (fboundp 'toolbar-add-item)
+;    (toolbar-add-item
+;     (vector
+;      (toolbar-make-button-list (concat singular-emacs-home-directory
+;					"singular.xpm"))
+;      'singular t "Start Singular")
+;     (length (specifier-instance default-toolbar))))
+;
+;;;
+;;; - load singular.el and .emacs-general
+;;;
+
+; get rid of superfluous "Load .emacs" menu entry on XEmacs
+(when (fboundp 'delete-menu-item)
+  (delete-menu-item '("Load .emacs"))		; that is for the current buffer
+  (let ((current-menubar (default-value 'current-menubar)))
+    (delete-menu-item '("Load .emacs"))		; that is for all other buffers
+    (set-default 'current-menubar current-menubar)))
+
+; load singular.el from `singular-emacs-home-directory'
+(load-file (concat singular-emacs-home-directory "singular.el"))
+
+; load .emacs-general from home or `singular-emacs-home-directory'
+(if (file-exists-p "~/.emacs-general")
+    (load-file "~/.emacs-general")
+  (if (file-exists-p (concat singular-emacs-home-directory ".emacs-general"))
+      (load-file (concat singular-emacs-home-directory ".emacs-general"))))
diff --git a/emacs/COPYING b/emacs/COPYING
new file mode 100644
index 0000000..681acc0
--- /dev/null
+++ b/emacs/COPYING
@@ -0,0 +1,44 @@
+                        SINGULAR version 4-0
+			   Singular-ESingular
+
+                     University of Kaiserslautern
+
+      Department of Mathematics and  Centre for Computer Algebra
+
+           Authors: G.-M. Greuel, G. Pfister, H. Schoenemann
+
+                        Copyright (C) 1986-2014
+
+
+
+                               *NOTICE*
+
+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 ( version 2 or version 3 of the License );
+with the following additional remarks:
+
+This package is part of the software SINGULAR. The GPL is valid for
+this package, other packages may have other copyrights.
+
+Their copyrights and licences can be found in the accompanying files
+which are distributed along with these packages.
+
+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 (see GPL)
+
+Please send any comments or bug reports to
+<singular at mathematik.uni-kl.de>.
+
+Availability
+============
+
+The latest information about SINGULAR is always available from
+`http://www.singular.uni-kl.de'.
+
diff --git a/emacs/ChangeLog b/emacs/ChangeLog
new file mode 100644
index 0000000..884d6dd
--- /dev/null
+++ b/emacs/ChangeLog
@@ -0,0 +1,1001 @@
+2000-05-19  T. Wichmann  <wichmann at arboretum.itwm.uni-kl.de>
+
+	* singular.el (singular-exec): Remove empty strings from SWITCHES
+
+1999-12-06  T. Wichmann  <wichmann at arboretum.itwm.uni-kl.de>
+
+	* singular.el (singular-internal): Removed bug: Adding of trailing
+	slash crashed if directory was nil
+	(singular-completion-do): Added completion of examples
+	(singular-example): Added (including key-binding and menu item)
+
+1999-09-14  T. Wichmann  <wichmann at arboretum.itwm.uni-kl.de>
+
+	* singular.el (singular-exit-singular): New strategy for the
+	communication between `singular-exit-singular' and
+	`singular-exit-sentinel'. Some new functions and variables
+	introduced.
+	(singular-restart): now deletes a running singular process
+	(singular-exit-sentinel): On demand inserts a string indicating
+	that the process was killed
+
+1999-09-08  T. Wichmann  <wichmann at arboretum.itwm.uni-kl.de>
+
+	* singular.el (singular-interactive-mode-menu-init): Also remove
+	  "Singular"-start menu
+	  (singular-interactive-mode-map): corrected key for
+	  singular-exit-singular
+	  (singular-help): added new version of Jens
+
+	* .emacs-singular Singular start menu for XEmacs appears now
+	  in every buffer
+
+1999-09-01  T. Wichmann  <wichmann at arboretum.itwm.uni-kl.de>
+
+	* singular.el (singular-interactive-mode): added
+          (singular-exec-init) and (singular-comint-init)
+
+1999-08-31  T. Wichmann  <wichmann at arboretum.itwm.uni-kl.de>
+
+	* .emacs-singular added template for Singular button in toolbar
+
+	* singular.el (singular-dynamic-complete): regexp
+	  singular-prompt-regexp now is obsolete. Used
+	  (singular-prompt-skip-forward) instead
+	  key pattern for "C-c $" and "C-c <" changed (did not work
+	  for emacs20)
+	  (singular-interactive-mode-menu-1/2): updated
+	  (singular-expand-emacs-file-name): conditionally append "/" to
+	  singular-emacs-home-directory
+
+1999-08-30  T. Wichmann  <wichmann at itwm.uni-kl.de>
+
+	* singular.el (singular, singular-restart, singular-other): Doc
+	  strings rewritten
+
+1999-08-25  T. Wichmann  <wichmann at arboretum.itwm.uni-kl.de>
+
+	* singular.el (singular-other) now has 4 arguments
+
+	* singular.el Added "-t" to singular-switches-magic
+
+1999-08-23  T. Wichmann  <wichmann at arboretum.itwm.uni-kl.de>
+
+	* singular.el (singular-interactive-mode-menu-init): Any menu
+          installed by comint-mode is removed
+
+	* singular.el (singular-exit-sentinel): remove libraries menu only if buffer is
+	  existent
+
+	* singular.el Added a "*" to some variables` doc string
+
+1999-08-27  Jens Schmidt  <schmidt at de.oracle.com>
+
+	* .bashrc (STARTUP): load `cmpl-hlp.el' now
+
+	* singular.el: `Online help' folding finished
+
+1999-08-26  Jens Schmidt  <schmidt at de.oracle.com>
+
+	* singular.el (singular-error): new function
+
+	* .bashrc: adapted to new Singular version
+
+	* .emacs-singular: code removed that starts Singular
+
+	* .emacs-singular: code added to add global menus for Emacs and
+	  XEmacs
+
+	* .emacs-singular: settings for `singular-help-same-window'
+	  added.  Settings for `singular-history-keys' and
+	  `singular-cursor-keys' removed.
+
+1999-08-24  Jens Schmidt  <schmidt at de.oracle.com>
+
+	* singular.el (singular-same-window): new defcustom
+	  (singular): uses the above variable to pop to buffer
+
+	* singular.el: Folding `Starting Singular' renamed to `Starting
+	  and stopping Singular'
+	  (singular-exit-singular): moved to that folding
+
+	* singular.el (singular-move-on-send): marked as user option
+
+	* singular.el (singular-demo-last-directory): new variable
+	  (singular-demo-mode-init): makes the above variable buffer-local
+	  (singular-demo-load): uses and sets the above variable in
+	  interactive specifier
+
+	* singular.el (singular-demo-print-messages,
+	  singular-demo-exit-on-load): default values changed
+
+	* singular.el (singular-demo-chunk-regexp,
+	  singular-demo-print-messages, singular-demo-exit-on-load,
+	  singular-demo-load-directory): marked as user options
+
+	* singular.el: Lots of changes to `Online help' folding.  Is still
+	  quiet experimental.
+
+	* singular.el (singular-history-ignoredups, singular-history-size,
+	  singular-history-filter-regexp,
+	  singular-history-explicit-file-name): marked as user options
+
+	* singular.el (singular-beginning-of-line): new function
+
+	* singular.el (singular-toggle-truncate-lines): bug fix.  Does
+	  frame refresh now after toggling value.
+
+	* singular.el (singular-pop-to-buffer): new function.  Used in
+	  `singular-help' and `singular'.
+
+	* singular.el (singular-cursor-key-model): new defcustom replacing
+	  former `singular-history-keys' and `singular-cursor-keys'
+	  (singular-cursor-key-model-set): new function replacing former
+	  `singular-history-cursor-keys-set' and
+	  `singular-history-cursor-key-set'
+	  static initialization removed
+
+	* singular.el (singular-interactive-mode-map): key bindings added
+	  for:
+	  `singular-help'
+	  `singular-beginning-of-line'
+	  `singular-toggle-truncate-lines'
+	  `singular-demo-load'
+	  `singular-load-library'
+	  `singular-load-file'
+	  `singular-restart'
+	  `singular-exit-singular'
+
+	* singular.el (singular): new customizing group
+	  (singular-interactive): made a subgroup of the above group
+
+1999-08-20  Jens Schmidt  <schmidt at de.oracle.com>
+
+	* singular.el (singular-move-on-send): new defcustom
+	  (singular-get-old-input, singular-send-or-copy-input): slightly
+	  rewritten
+
+	* singular.el (singular-demo-chunk-regexp,
+	  singular-demo-print-messages, singular-demo-exit-on-load,
+	  singular-demo-load-directory): `:initialize' tags added
+
+	* singular.el: folding `Skipping and stripping prompts and
+	  newlines ...' completely rewritten.  Almost all variables
+	  and constants removed.  Functions and variables renamed:
+
+	  singular-skip-prompt-forward to singular-prompt-skip-forward
+	  singular-skip-prompt-backward to singular-prompt-skip-backward
+	  singular-strip-leading-prompt to singular-prompt-remove-string
+	  singular-remove-prompt to singular-prompt-remove-region
+	  singular-remove-prompt-filter to singular-prompt-remove-filter
+	  singular-strip-white-space to singular-white-space-strip
+	  singular-prompt-regexp to singular-comint-prompt-regexp
+
+	  All references changed.  New function `singular-prompt-init'
+	  added which is called in `singular-interactive-mode'
+
+	* .emacs-singular: loads customization from ~/.emacs-singular-cust
+	  if present
+
+	* .emacs-singular: loads singular.el from
+	  `singular-emacs-home-directory'
+
+	* .emacs-singular: code added to remove "Load .emacs" menu entry
+	  on XEmacs
+
+	* .emacs-singular: doc fixes
+
+	* .bashrc: variables `singular-emacs-home-directory' and
+	  `singular-help-file-name' added to commandlines
+
+1999-08-18  T. Wichmann  <wichmann at arboretum.itwm.uni-kl.de>
+        * singular.el singular-help-file-name variable introduced
+	  added section for singular-*-alists
+	  some defvars changed to defconsts
+	  (singular-scan-header-exit) introduced
+	  fancier calculation of singular-scan-header-scan-for
+	  (singular-scan-header-got-emacs-home) introduced
+	  singular-executable-default, ... are now defcustom
+	  (singular-exit-sentinel) now call (singular-scan-header-exit)
+
+	* singular.el: added (singular-comint-init)
+	  improved dynamical generation of library menu
+	  scan header functionality improved
+	  scan header now gets initialized on every start of Singular
+	  singular-completion-* variables renamed
+	  (singular) renamed to (singular-internal)
+	  new functions (singular), (singular-restart), (singular-other)
+	  new variables for last singular arguments incl. history
+
+1999-08-15  Jens Schmidt  <schmidt at de.oracle.com>
+
+	* singular.el: new folding `Sending input interactive'.  Functions
+	  `singular-get-old-input' and `singular-send-or-copy-input' moved
+	  to that folding.
+
+	* singular.el: folding `Skipping and stripping prompts and
+	  newlines ...' renamed to `Skipping and stripping prompts and
+	  whitespace ...'
+
+	* singular.el (singular-interactive-mode): slightly re-organized
+
+	* singular.el (singular-demo-show-next-chunk): bug fix
+
+	* singular.el (singular-section-kill): new function
+	  (singular-interactive-mode-map): key binding added for the
+	  aforementioned function
+
+	* singular.el (singular-section-to-string): renamed from
+	  `singular-input-section-to-string'.  Optional argument END
+	  removed.  All callers changed.
+
+	* singular.el (singular-section-check): new function
+	  singular.el (singular-folding-fold, singular-folding-unfold):
+	  use `singular-section-check'
+
+1999-08-11  T. Wichmann  <wichmann at arboretum.itwm.uni-kl.de>
+
+	* singular.el: code for menu support rewritten
+	  scanning of singular header implemented
+	  dynamic completion implemented
+
+1999-08-10  Jens Schmidt  <schmidt at de.oracle.com>
+
+	* singular.el (singular-history-insert): does not check
+	  `singular-demo-insert-into-history' any longer
+	  (singular-demo-insert-into-history): variable removed
+
+1999-08-09  Jens Schmidt  <schmidt at de.oracle.com>
+
+	* singular.el: doc fixes
+
+1999-08-08  Jens Schmidt  <schmidt at de.oracle.com>
+
+	* .emacs (singular-interactive-mode-hook): key bindings for
+	  scrolling commands changed
+
+	* singular.el (singular-current-output-section): bug fix.
+	  `save-restriction' added.
+
+	* singular.el (singular-folding-toggle-fold-latest-output):
+	  completely rewritten
+	  (singular-folding-toggle-fold-at-point,
+	  singular-folding-toggle-fold-all-output): removed
+	  (singular-folding-toggle-fold-at-point-or-all): new function
+
+	* singular.el (singular-folding-fold): checks that section is
+	  unfolded before folding
+	  (singular-folding-unfold): checks that section is folded before
+	  unfolding.  Uses optional argument
+	  INVISIBILITY-OVERLAY-OR-EXTENT.
+
+	* singular.el (singular-xemacs-folding-unfold-internal): assumes
+	  that section is folded and uses optional argument
+	  INVISIBILITY-EXTENT
+	  (singular-xemacs-folding-fold-internal): assumes that section is
+	  unfolded
+	  (singular-emacs-folding-fold-internal,
+	  singular-emacs-folding-unfold-internal):  same changes as for
+	  XEmacs
+
+	* singular.el (singular-xemacs-folding-foldedp-internal,
+	  singular-emacs-folding-foldedp-internal):  cosmetical changes
+
+	* singular.el (singular-font-lock-singular-types): initialization
+	  moved out of `defconst' for Byte Compiler to recognize
+
+	* singular.el (singular-keep-region-active): new function
+	  (singular-section-goto-beginning, singular-section-goto-end,
+	  singular-section-backward, singular-section-forward): calls to
+	  that function added
+
+	* singular.el: new folding `Miscellaneous' in folding `Code common
+	  to both modes' added
+
+	* singular.el: Folding `Simple section stuff ...' and `Section
+	  stuff' renamed to `Simple section API ...' and `Section API',
+	  respectively.  New foldings `Section miscellaneous' and `Section
+	  miscellaneous interactive'.  Folding `Getting section contents'
+	  removed, contents moved to `Section miscellaneous'.  Folding
+	  `Input and output filters' removed, contents moved to `Skipping
+	  and stripping ...'.
+	* singular.el.decl: changed accordingly
+
+	* singular.el.decl: docu on access specifiers and types added,
+	  declarations re-checked and updated.
+
+1999-08-07  Jens Schmidt  <schmidt at de.oracle.com>
+
+	* singular.el: preliminary and experimental version of online help
+	  stuff added
+
+	* singular.el: doc fixes.  I almost forgot about them.
+
+	* singular.el (singular-time-stamp-difference): new function
+
+	* singular.el (singular-interactive-mode-map): bindings added for
+	  `singular-folding-toggle-fold-at-point',
+	  `singular-folding-toggle-fold-latest-output', and
+	  `singular-folding-toggle-fold-all-output'
+	* singular.el (singular-folding-unfold): new function
+	  (singular-folding-toggle-fold-at-point,
+	  singular-folding-toggle-fold-latest-output,
+	  singular-folding-toggle-fold-all-output): new functions
+
+	* singular.el (singular-interactive-mode-map): bindings added for
+	  `comint-previous-matching-input' and
+	  `comint-next-matching-input'
+
+1999-08-01  Jens Schmidt  <schmidt at de.oracle.com>
+
+	* .emacs (singular-interactive-mode-hook): Font Lock mode turned
+	  on for Singular interactive mode
+
+	* .emacs (singular-interactive-mode-hook): key-bindings added
+
+1999-07-31  Jens Schmidt  <schmidt at de.oracle.com>
+
+	* singular.el: `Skipping and stripping prompts and newlines and
+	  other things' moved
+
+	* singular.el (singular-exit-sentinel): bug fix.
+
+	* singular.el (singular-prompt-skip-forward): renamed from
+	  `singular-prompt-skip-forward'.  All references replaced.
+
+	* singular.el (singular-history-ignoredups, singular-history-size,
+	  singular-history-filter-regexp,
+	  singular-history-explicit-file-name): new defcustoms
+	  (singular-history-read, singular-history-write,
+	  singular-history-insert, singular-history-init): new functions.
+	  Calls added to the necessary functions.
+
+	* singular.el: new folding `Miscellaneous interactive' introduced
+
+	* singular.el (singular-recenter,
+	  singular-reposition-point-and-window): new functions
+	  (singular-toggle-truncate-lines): uses
+	  `singular-reposition-point-and-window' instead of recenter
+	  (singular-scroll-previous-amount): new variable
+	  (singular-scroll-right, singular-scroll-left): new variables
+
+	* singular.el (singular-process, singular-process-mark): accept
+	  optional argument NO-ERROR now and throw an error if Singular is
+	  not alive
+	  (singular-load-file, singular-load-library): rely on errors from
+	  `singular-process' to catch dead processes
+
+	* singular.el (singular-buffer-name-to-process-name,
+	  singular-process-name-to-buffer-name,
+	  singular-run-hook-with-arg-and-value, singular-process,
+	  singular-process-mark): declared as `defsubst'
+
+	* singular.el: almost all key bindings thrown out.  Needs to be
+	  re-designed.
+
+	* singular.el: more doc fixes
+
+	* singular.el: doc fixes and cosmetical changes
+
+1999-07-29  Jens Schmidt  <schmidt at de.oracle.com>
+
+	* singular.el: Folding `Last input and output section' moved
+
+	* singular.el.decl: changes from singular.el included
+
+	* singular.el (singular-demo-load): uses
+	  `singular-demo-load-directory' to load files
+	  (singular-demo-load): behaviour on running new demo if there is
+	  old one made customizable
+	  (singular-demo-load): bug fix for Emacs which moves pointers on
+	  file insertion
+
+	* singular.el (singular-demo-command-on-enter,
+	  singular-demo-command-on-leave): variables removed.  Instead,
+	  hooks are run now in `singular-demo-exit-internal' and
+	  `singular-demo-load'.
+
+	* singular.el (singular-demo-mode): function disolved to a number
+	  of smaller functions.  See below.
+	  (singular-demo-exit-internal): new function
+	  (singular-demo-exit): completely rewritten
+
+	* singular.el (singular-demo-show-next-chunk): bug fix in white
+	  space stripping at end of demo
+
+	* singular.el (singular-demo-mode-init): new function.  Call added
+	  to `singular-interactive-mode'.
+
+	* singular.el (singular-demo-chunk-regexp): made a defcustom
+	  (singular-demo-insert-into-history): new custom
+	  (singular-demo-print-messages): made a defcustom
+	  (singular-demo-exit-on-load): new custom
+	  (singular-demo-load-directory): new custom
+
+	* singular.el (singular-interactive-mode): sets `comint-mode-hook'
+	  to nil before calling `comint-mode'
+	  (singular-exec): does not run hooks on `comint-exec-hook' any
+	  longer
+
+	* singular.el: new folding for Comint stuff
+	  folding `Customizing variables of comint' removed
+	  folding `History' added
+
+	* singular.el (singular-demo-mode): new group
+
+	* singular.el: doc fixes
+
+1999-07-25  Jens Schmidt  <schmidt at de.oracle.com>
+
+	* .emacs (transient-mark-mode): switched on
+
+	* singular.el.decl: all foldings updated to revision 1.38.
+	  Section stuff and Key map revised.
+
+	* singular.el: doc fixes and cosmetical changes
+
+1999-07-25-b  Jens Schmidt  <schmidt at de.oracle.com>
+
+	* singular.el: Key binding stuff almost completely rewritten.
+	  Features now: new customs `singular-history-keys',
+	  `singular-cursor-keys' and back-end functions
+	  `singular-history-cursor-keys-set' and
+	  `singular-history-cursor-key-set'.  New function
+	  `singular-interactive-mode-map-init' added and call to that
+	  function in `singular-interactive-mode'.  Key map does not
+	  inherit keymap from `comint-mode' any longer.  New prefix maps
+	  used.
+
+	* singular.el (singular-demo-load): uses
+	  `insert-file-contents-literally' now
+
+	* singular.el (singular-section-goto-beginning,
+	  singular-section-goto-end, singular-section-backward,
+	  singular-section-forward: new functions
+
+	* singular.el (singular-section-face-alist,
+	  singular-folding-ellipsis,
+	  singular-folding-line-move-ignore-folding): cosmetical changes
+
+	* singular.el: menu and logo stuff moved to respective folding
+	  (singular-interactive-mode-menu-init): new function
+	  (singular-interactive-mode): call to that function added
+
+	* singular.el (singular-interactive-font-lock-defaults):
+	  SYNTAX-BEGIN set to `singular-section-goto-beginning'
+
+	* singular.el (singular-interactive-miscellaneous): new group
+	* singular.el (singular-map-buffer): moved to Customization
+	  folding
+
+	* singular.el: doc fixes
+
+	* .emacs (singular-cursor-keys, singular-history-keys): settings
+	  added
+
+	* .emacs: work around for face problems on XEmacs added
+
+1999-07-25-a  Jens Schmidt  <schmidt at de.oracle.com>
+
+	* singular.el (singular-section-face-alist,
+	  singular-section-input-face, singular-section-output-face): new
+	  customs
+
+	* singular.el (singular-emacs-simple-sec-in,
+	  singular-section-mapsection): rewritten.  Much more beautiful
+	  now
+
+	* singular.el: doc fixes
+
+1999-07-24  Jens Schmidt  <schmidt at de.oracle.com>
+
+	* singular.el (singular-debug-pre-input-filter,
+	  singular-debug-post-input-filter,
+	  singular-debug-pre-output-filter,
+	  singular-debug-post-output-filter): cosmetical changes
+	  (singular-debug-filter-init): new function.
+	  (singular-interactive-mode): calls that function instead of
+	  initializing the filters on itself
+
+	* .bashrc: new file
+
+	* .emacs (custom-file): set
+
+	* .emacs: loads and starts Singular interactive mode
+
+	* .emacs-customize: renamed to .emacs
+
+1999-07-24-b  Jens Schmidt  <schmidt at de.oracle.com>
+
+	* singular.el: Font Lock mode support completely re-written:
+	  Faces defined with `defface', regular expressions simplified,
+	  call to `regexp-opt' added, `eval-when-compile' hack included,
+	  doc strings re-written to official wording, function
+	  `singular-interactive-font-lock-init' added, everything (except
+	  faces) renamed to prefix "singular-interactive-font-lock", etc.
+
+	* singular.el (singular-simple-sec-lookup-face): new subst.  Calls
+	  added in `singular-emacs-simple-sec-create' and
+	  `singular-xemacs-simple-sec-create'
+	  (singular-section-face-alist): new custom
+	  (singular-section-input-face, singular-section-input-face): new
+	  faces
+
+	* singular.el: doc fixes
+
+	* .emacs-customize (show-paren-mode): new file
+
+1999-07-24-a  Jens Schmidt  <schmidt at de.oracle.com>
+
+	* singular.el (singular-xemacs-simple-sec-create): slightly
+	  rewritten
+	  (singular-xemacs-simple-sec-start-at): Handles imagenary clear
+	  simple section at eob correctly now
+	  (singular-xemacs-simple-sec-end-at,
+	  singular-xemacs-simple-sec-at): cosmetical changes
+	  (singular-xemacs-simple-sec-in): completely rewritten
+
+	* singular.el (singular-faces, singular-sections-and-foldings):
+	  new groups
+	* singular.el (singular-folding-ellipsis,
+	  singular-folding-line-move-ignore-folding): moved to group
+	  `singular-sections-and-foldings'
+
+	* singular.el: doc fixes, of course
+
+1999-07-23  Jens Schmidt  <schmidt at de.oracle.com>
+
+	* singular.el (singular-folding-fold-at-point,
+	  singular-folding-unfold-at-point,
+	  singular-folding-fold-latest-output,
+	  singular-folding-unfold-latest-output,
+	  singular-folding-fold-all-output,
+	  singular-folding-unfold-all-output): (re-)new functions
+
+	* singular.el (singular-folding-fold): accepts optional argument
+	  NO-ERROR
+
+	* singular.el (singular-folding-line-move-ignore-folding): new
+	  defcustom
+
+	* singular.el (singular-section-mapsection): new function
+
+	* singular.el (singular-map-buffer): new function
+
+	* singular.el (singular-folding-init): adapted to XEmacs
+	  (singular-xemacs-folding-fold-internal,
+	  singular-xemacs-folding-foldedp-internal,
+	  singular-xemacs-folding-unfold-internal): new functions
+
+	* singular.el: doc fixes (what else?)
+
+1999-07-22  Jens Schmidt  <schmidt at de.oracle.com>
+
+	* singular.el-07-22 (singular-emacs-folding-fold-internal): bug
+	  fix
+
+	* singular.el-07-22 (singular-folding-ellipsis): sets ellipsis in
+	  already running Singulars
+	  (singular-folding-set-ellipsis-in-singular-buffers,
+	  singular-folding-set-ellipsis): new
+	  functions
+
+	* singular.el-07-22 (singular-section-in): restriction algorithm
+	  changed.  Restricts to whole sections now.
+	  (singular-section-in-internal): new function used by
+	  `singular-section-in'
+
+	* singular.el-07-22 (singular-emacs-simple-sec-in): bug fix
+
+	* singular.el-07-22: doc fixes, of course
+
+1999-07-19  Jens Schmidt  <schmidt at de.oracle.com>
+
+	* singular.el: Folding stuff completely rewritten.
+	  (singular-interactive-mode): Folding stuff initialization moved
+	  to new function `singular-folding-init'
+
+	* singular.el (singular-process, singular-process-mark,
+	  singular-simple-sec-last-end-position): bug fixes
+
+	* singular.el (singular-interactive): new group
+
+	* singular.el: face initialization for XEmacs slightly
+	  re-organized
+
+	* singular.el (singular-mode-syntax-table-init): new function.
+	  Called from `singular-interactive-mode'.
+
+	* singular.el: doc fixes, of course.
+
+1999-07-18-a  Jens Schmidt  <schmidt at de.oracle.com>
+
+	* singular.el (singular-section-in): completely rewritten.
+	  Handles restrictions now.
+
+	* singular.el (singular-section-at): handles degenerate
+	  restriction cases correctly now
+
+	* singular.el (singular-section-simple-sec, singular-section-type,
+	  singular-section-start, singular-section-end): defined as subst
+
+	* singular.el (singular-section-create): new subst.  Used in all
+	  instances where new sections are generated.
+
+	* singular.el: A number of changes in the XEmacs simple section
+	  stuff.  However, there are still some changes from the Emacs
+	  simple section stuff that have to be re-done for the XEmacs
+	  stuff, too.
+
+	* singular.el (singular-emacs-simple-sec-in): implemented
+
+	* singular.el (singular-simple-sec-end,
+	  singular-simple-sec-start, singular-simple-sec-type,
+	  singular-simple-sec-before): defined as subst
+
+	* singular.el (singular-emacs-simple-sec-create): slightly
+	  rewritten.  Should be a little bit faster now.
+
+	* singular.el (singular-simple-sec-reset-last,
+	  singular-xemacs-simple-sec-reset-last,
+	  singular-emacs-simple-sec-reset-last): removed
+
+	* singular.el (singular-simple-sec-last-end-position): new macro.
+	  Used whenever position of last simple section is accessed.
+
+	* singular.el (singular-input-section-to-string): cosmetical
+	  changes
+
+	* singular.el (singular-mode-syntax-table): (my own) bug fixed in
+	  initialization
+
+	* singular.el: doc fixes.  A *lot* of doc fixes.
+
+1999-07-17  Jens Schmidt  <schmidt at de.oracle.com>
+
+	* singular.el (singular-load-file, singular-load-library): checks
+	  added whether process is running
+
+	* singular.el (singular-interactive-mode-map): settings for
+	  singular-demo-exit uncommented.  Does not work on Emacs.
+
+	* singular.el (font-lock-singular-prompt-face): bug fix.  Was
+	  font-lock-singular-warn-face.
+
+	* singular.el (singular-interactive-mode-syntax-table,
+	  singular-mode-syntax-table): renamed and moved to common code
+	  section, same for initialization of syntax table
+	  (singular-mode-syntax-table): back tics added as strings
+
+	* singular.el (singular-fset): support for Emacs 19 removed
+	  (singular-set-version): ditto
+
+	* singular.el: doc fixes
+
+1998-08-14  T. Wichmann  <wichmann at itwm.uni-kl.de>
+
+	* singular.el : commented code for singular-logo on startup in
+	XEmacs. This code needs some rethinking...
+
+1998-08-10  T. Wichmann  <wichmann at itwm.uni-kl.de>
+
+	* singular.el (singular-toggle-truncate-lines): Added (recenter)
+	according to function definition in XEmacs.
+	(singular-other): Added check on unique buffer name.
+	Added comments to functions and variables.
+
+1998-08-07  T. Wichmann  <wichmann at itwm.uni-kl.de>
+	*singular (singular-send-or-copy-input): Print message if demo
+	mode is active
+	Added variable singular-demo-mode-print-messages
+
+	* singular.el (singular-demo-mode): changed message text
+	(singular-other): if singular options are read from minibuffer, do
+	not display the "-t" option. Add it automatically.
+	(singular-other): Changed minibuffer text
+	(singular-exit-singular): Added (kill-buffer)
+
+	* singular.el (singular-do-folding): Added (recenter) to prevent
+	error in subst-char-in-region. Temporary?
+
+	* singular.el (singular-other): Added
+
+1998-08-06  T. Wichmann  <wichmann at itwm.uni-kl.de>
+
+        * singular.el: added key-bindings
+	Introduced new variable singular-start-menu (temporary)
+	Updated submenu "load library"
+
+        * singular.el: set-face for new font-lock faces now uses argument
+	'append for XEmacs
+	Changed (get-buffer-process (cur...)) to (singular-process)
+	(singular-demo-mode): added message on enter
+
+	* singular.el (singular-emacs-simple-sec-start-at): Removed error:
+       	(point) was used instead of pos
+	(singular-emacs-simple-sec-end-at): Removed error: (point) was
+	used instead of pos
+
+	* singular.el (singular-interactive-mode-syntax-table): Added
+	additional entries
+
+	* singular.el (singular-font-lock-keywords-1): Added new regexps
+	(font-lock-singular-error-face): Added new face
+	(font-lock-singular-warn-face): Added new face
+	(font-lock-singular-prompt-face): Added new face
+
+	*singular.el: set-face for section faces put in comments
+
+	* singular.el (singular-xemacs-simple-sec-in): Written
+	(singular-section-in): Written
+	(singular-do-folding): Finished
+
+Thu Jul 30 11:45:28 1998  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* singular.el (singular-process): new macro
+
+	* singular.el (singular-demo-command-on-enter,
+	  singular-demo-command-on-exit): new variables
+ 	  (singular-demo-mode): sends commands on entering and exiting
+
+	* singular.el (singular-demo-mode-init): function removed.
+	  Functionality moved to `singular-demo-mode'.
+	  (singular-demo-mode): more versatile.  Knows how to enter and to
+	  exit, too.  All callers adapted.
+	  (singular-demo-exit): new function
+	  (singular-demo-show-next-chunk): leaves demo mode after showing
+	  last chunk
+	  (singular-demo-load): does not show first chunk on startup
+
+	* singular.el (singular-remove-prompt-regexp): new variable
+	  (singular-remove-prompt): new function
+
+	* singular.el (singular-string-start-anchored-prompt-regexp):
+	  renamed to `singular-strip-leading-prompt-regexp'
+	  (singular-strip-prompts): renamed to
+	  `singular-strip-leading-prompt'
+	  (singular-prompt-sequence-regexp): renamed to
+	  `singular-skip-prompt-forward-regexp'
+
+	* singular.el (singular-fold-internal): bug fix.  Keeping undo
+	  information not up-to-date leads to a corrupt undo list.
+	  (singular-demo-show-next-chunk): ditto
+	  (singular-exit-sentinel): switches off demo mode on exit
+
+1998-07-31  T. Wichmann  <wichmann at itwm.uni-kl.de>
+
+	* singular.el: simple-secs for XEmacs, second version
+
+1998-07-29  T. Wichmann  <wichmann at itwm.uni-kl.de>
+
+	* singular.el : simple-secs for XEmacs partially implemented
+
+Wed Jul 29 10:50:47 1998  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* singular.el (singular-extended-prompt-regexp,
+	  singular-string-start-anchored-prompt-regexp,
+	  singular-prompt-sequence-regexp): new constants
+	  (singular-strip-white-space, singular-strip-prompts,
+	  singular-skip-prompt-forward): new functions
+
+	* singular.el (singular-emacs-simple-sec-end-at): bug fix
+	  (singular-fold-internal, singular-demo-show-next-chunk): do not
+	  save buffer-modified flag and do not switch off read only state
+	  (singular-output-filter): does not switch off read only state
+	  (singular-input-section-to-string): new function
+
+	* singular.el (singular-send-input): sends old input sections
+	  (singular-send-input): renamed to
+	  `singular-send-or-copy-input'.  All references changed.
+	  (singular-get-old-input): new function
+
+	* singular.el (singular-demo-end): new variable
+	  (singular-demo-mode-init, singular-interactive-mode): new
+	  function.  Call added in mode initialization.
+	  (singular-demo-load): sets `singular-demo-end'
+	  (singular-demo-show-next-chunk): is smarter concerning end of
+	  demo file
+
+	* singular.el (singular-demo-chunk-regexp): new variable
+	  (singular-demo-mode, singular-demo-old-mode-name,
+	  singular-interactive-mode): new local variables.  Localization
+	  added.
+	  (singular-demo-mode, singular-demo-show-next-chunk,
+	  singular-demo-load): new function
+	  (singular-send-input): supports demo mode
+
+	* singular.el (singular-fold-internal, singular-fold-section):
+	  again takes only a single region instead of a list.  All callers
+	  changed.
+
+	* singular.el (singular-fold-section): doc fix
+	  (singular-exec): takes care about undo information when
+	  retrieving start file
+	  (singular-emacs-simple-sec-before): doc fix
+	  (singular-exec): cosmetic changes
+	  (singular-output-filter): cosmetic changes
+	  (singular-simple-sec-last-end): doc fix
+	  (singular-send-input): argument STRING changed to
+	  SEND-FULL-SECTION.  Semantics not implemented yet.
+
+	* singular.el (singular-section-before): new function
+
+Tue Jul 28 08:49:05 1998  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* singular.el (singular-emacs-simple-sec-start-at,
+	  singular-emacs-simple-sec-end-at):  assume that buffer is
+	  already widened
+	  (singular-section-at): widens buffer before determining start
+ 	  and end of clear simple sections
+
+	* singular.el (singular-fold-section): doc fix
+	  (singular-emacs-simple-sec-create): doc fix
+	  (singular-simple-sec-last-end): doc fix
+	  explanations for sections and simple sections added
+
+	* singular.el (singular-fold-internal, singular-fold-section):
+	  uses a list of regions instead of one region.  All callers
+ 	  changed.
+
+	* singular.el (singular-fold-internal): doc fix
+	  (singular-section-foldedp): doc fix
+	  (singular-fold-section): saves restrictions before folding
+
+	* singular.el (singular-section-at): argument `raw-section'
+	  renamed to `restricted' and its semantic inverted
+
+	* singular.el (singular-emacs-simple-sec-start-at,
+	  singular-emacs-simple-sec-end-at): new functions.  `fset's for
+ 	  the flavor-independent functions added.
+
+	* singular.el (singular-emacs-simple-sec-reset-last): new argument
+	  `pos'.  Resets `singular-simple-sec-last-end', too.
+	  (singular-output-filter): does not set
+	  `singular-simple-sec-last-end'
+
+	* singular.el (singular-simple-sec-last-end): new variable
+	  (singular-debug-format): wrapped by a `save-match-data'
+	  (singular-simple-sec-clear-type): doc fix
+	  (singular-emacs-simple-sec-create): doc fix
+	  (singular-emacs-simple-sec-create): cosmetic changes
+	  (singular-fold-internal): cosmetic changes
+	  (singular-fold-internal): bug fix.  Order of `delete-char' and
+	  `subst-char-in-region' exchanged.
+
+	* singular.el (singular-section-at): new function
+	  (singular-section-simple-sec, singular-section-start,
+	  singular-section-end, singular-section-type): new macros
+
+	* singular.el (singular-fold-internal, singular-fold-section,
+	  singular-section-foldedp): new functions
+
+	* singular.el (singular-output-filter): sets `inhibit-read-only'
+	  instead of `buffer-read-only'
+
+	* singular.el (singular-simple-sec-clear-type): new variable
+	  (singular-simple-sec-init): new function
+	  (singular-emacs-simple-sec-create,
+ 	  singular-emacs-simple-sec-reset-last,
+ 	  singular-emacs-simple-sec-start, singular-emacs-simple-sec-end,
+ 	  singular-emacs-simple-sec-type, singular-emacs-simple-sec-at,
+ 	  singular-emacs-simple-sec-before, singular-emacs-simple-sec-in
+ 	  ): new functions.  `fset's for the flavor-independent functions
+	  added.
+
+Mon Jul 27 12:39:04 1998  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* singular.el (singular-output-filter): new function
+	  (singular-send-input): new function
+	  (singular-interactive-mode-map): `singular-send-input' bound to
+	  `"\C-m"'
+
+	* singular.el (singular-debug-input-filter,
+	  singular-debug-output-filter):  completely rewritten.  Bogus
+	  call counting removed.  Debug checks added.
+	  (singular-debug-bogus-output-filter-cnt): variable removed
+
+	* singular.el (singular): code for creation of new singular
+	  process moved to `singular-exec'
+	  (singular-exec): new function
+
+	* singular.el (singular-process-mark): new macro
+	  (singular-exit-sentinel): debug message fix
+	  (singular): arguments names changed
+	  (singular-set-version): message fix
+	  (singular-bogus-output-filter-calls): variable removed
+	  (singular-debug): optional argument `else-form' added
+	  (singular-debug-format): uses `replace-match' to replace
+	  newlines
+
+	* singular.el (singular-folding-ellipsis): new variable
+	  (singular-interactive-mode): selective display stuff added
+
+	* singular.el (singular-input-face, singular-output-face): new
+	  variables
+	  (singular-lookup-face): new function
+
+Thu Jul 23 10:28:53 1998  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* singular.el (singular): initializes the markers
+	  `comint-last-input-start', `comint-last-input-end', and
+	  `comint-last-output-start'
+	  (singular): goes to point max after Singular startup
+
+	* singular.el (singular-interactive-mode):
+	  `comint-truncate-buffer' is not longer added unconditionally to
+	  `comint-output-filter-functions'
+	  (singular): runs `comint-exec' instead of `make-comint'
+
+	* singular.el (comint-mode): advice removed
+	  (singular-interactive-mode): `comint-mode' is called now in a
+	  more regular way
+
+	* singular.el (singular-debug-output-filter): doc fix
+
+	* singular.el (singular-bogus-output-filter-calls): new variable
+
+	* singular.el (singular-interactive-mode-map): code for XEmacs
+	  added
+
+	* singular.el (singular-emacs-flavor,
+	  singular-emacs-major-version, singular-emacs-minor-version): new
+ 	  variables
+	  (singular-set-version, singular-fset): new functions
+
+	* singular.el (singular-debug-format): new function
+	  (singular-debug-bogus-output-filter-cnt): new variable
+	  (singular-debug-input-filter, singular-debug-output-filter): new
+	  variables
+	  (singular-interactive-mode): conditionally adds debugging
+	  filters
+
+	* singular.el: style and coding conventions added
+
+Wed Jul 22 11:45:56 1998  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* singular.el (singular-interactive-mode):
+	  `comint-truncate-buffer' is added to `comint-truncate-buffer'
+	  via a local `add-hook'
+	  (singular-interactive-mode): doc fix
+	  (singular-interactive-mode): `mode-name' fixed
+	  (singular): doc fix
+
+	* singular.el (comint-mode): new advice
+	  `singular-interactive-mode'
+	  (singular-interactive-mode): call to `comint-mode' re-added
+	  (singular-interactive-mode): call to `comint-read-input-ring'
+	  moved to `singular'
+	  (singular): almost completely rewritten.  Runs
+	  `singular-interactive-mode' only on creation of a new buffer.
+	  Runs hooks on `singular-exec-hook'.  Reads input ring on
+	  creation of a new process.
+
+	* singular.el (singular-prompt-regexp): doc fix
+	  (singular-input-ignoredups, singular-maximum-buffer-size):
+	  unmade customizable
+
+	* singular.el (singular-history-filter-regexp): new variable
+	  (singular-history-filter): new variable
+	  (singular-interactive-mode): sets `comint-input-filter' to
+	  `singular-history-filter'
+
+	* singular.el (singular-interactive-mode): adds
+	  `comint-truncate-buffer' to `comint-output-filter-functions'.
+	  `singular-buffer-maximum-size' unmade buffer local.
+
+	* singular.el (singular-interactive-mode): does not run
+	  `comint-mode'.  Mode name changed to `"Singular Interactive".
+
+	* singular.el (singular-debug): doc fix
+	  (singular-debug): recognition of mode `all' added
+	  (singular-interactive-mode): `singular-debug' unmade buffer
+	  local
+
+	* singular.el (singular-exit-sentinel): debug messages added
+
+	* singular.el (singular-start-file): doc fix
+	  (singular-default-executable, singular-default-name,
+	  singular-default-switches): doc fix
+	  (singular, singular-interactive-mode): doc fix
+	  (singular-delimiter-argument-list, singular-input-ignoredups,
+	  singular-buffer-maximum-size, singular-input-ring-size): doc fix
diff --git a/emacs/Makefile.am b/emacs/Makefile.am
new file mode 100644
index 0000000..da41f8c
--- /dev/null
+++ b/emacs/Makefile.am
@@ -0,0 +1,24 @@
+ACLOCAL_AMFLAGS = -I ../m4
+
+emacsdir=$(datadir)/singular/emacs
+
+EMACS = \
+    ChangeLog \
+    COPYING \
+    NEWS \
+    singular.el \
+    singular.xpm  .emacs-general  .emacs-singular \
+    cmd-cmpl.el ex-cmpl.el hlp-cmpl.el lib-cmpl.el
+#++ hlp-cmpl.el lib-cmpl.el ex-cmpl.el cmd-cmpl.el: for now from Master Singular
+
+
+#-- BUGS     cmpl.pl     ESingular.emacs21     lib.pl     Makefile.in     singular.el.decl
+
+dist_emacs_DATA = $(EMACS)
+
+# test.sing
+# TODO: remove this!
+#all-local:
+#	[ -d ${builddir} ] || ln -s ${srcdir} ${builddir}
+
+EXTRA_DIST = $(EMACS)
diff --git a/emacs/Makefile.in b/emacs/Makefile.in
new file mode 100644
index 0000000..958429f
--- /dev/null
+++ b/emacs/Makefile.in
@@ -0,0 +1,570 @@
+# Makefile.in generated by automake 1.13.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 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@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+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 = emacs
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(dist_emacs_DATA) COPYING ChangeLog NEWS
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_append_compile_flags.m4 \
+	$(top_srcdir)/m4/ax_append_flag.m4 \
+	$(top_srcdir)/m4/ax_append_link_flags.m4 \
+	$(top_srcdir)/m4/ax_check_compile_flag.m4 \
+	$(top_srcdir)/m4/ax_check_link_flag.m4 \
+	$(top_srcdir)/m4/ax_compute_relative_paths.m4 \
+	$(top_srcdir)/m4/ax_normalize_path.m4 \
+	$(top_srcdir)/m4/ax_prefix_config_h.m4 \
+	$(top_srcdir)/m4/ax_pthread.m4 \
+	$(top_srcdir)/m4/ax_python_embed.m4 \
+	$(top_srcdir)/m4/ax_python_with_version.m4 \
+	$(top_srcdir)/m4/cpu-check.m4 $(top_srcdir)/m4/dbm-check.m4 \
+	$(top_srcdir)/m4/flags.m4 $(top_srcdir)/m4/flint-check.m4 \
+	$(top_srcdir)/m4/gfanlib-check.m4 \
+	$(top_srcdir)/m4/gmp-check.m4 \
+	$(top_srcdir)/m4/google-perftools.m4 \
+	$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+	$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+	$(top_srcdir)/m4/lt~obsolete.m4 \
+	$(top_srcdir)/m4/mathic-check.m4 $(top_srcdir)/m4/ntl-check.m4 \
+	$(top_srcdir)/m4/options.m4 $(top_srcdir)/m4/p-procs.m4 \
+	$(top_srcdir)/m4/polymake-check.m4 \
+	$(top_srcdir)/m4/readline-check.m4 $(top_srcdir)/configure.ac
+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_V_P = $(am__v_P_ at AM_V@)
+am__v_P_ = $(am__v_P_ at AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_ at AM_V@)
+am__v_GEN_ = $(am__v_GEN_ at AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_ at AM_V@)
+am__v_at_ = $(am__v_at_ at AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+SOURCES =
+DIST_SOURCES =
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+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__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
+am__installdirs = "$(DESTDIR)$(emacsdir)"
+DATA = $(dist_emacs_DATA)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BUILTIN_LIBS = @BUILTIN_LIBS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CDDGMPCPPFLAGS = @CDDGMPCPPFLAGS@
+CDDGMPLDFLAGS = @CDDGMPLDFLAGS@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATA_DIR = @DATA_DIR@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DOC_DIR = @DOC_DIR@
+DOXYGEN = @DOXYGEN@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FACTORY_INCLUDES = @FACTORY_INCLUDES@
+FACTORY_LIBS = @FACTORY_LIBS@
+FGREP = @FGREP@
+FLINT_CFLAGS = @FLINT_CFLAGS@
+FLINT_HOME = @FLINT_HOME@
+FLINT_LIBS = @FLINT_LIBS@
+GMP_CFLAGS = @GMP_CFLAGS@
+GMP_HOME = @GMP_HOME@
+GMP_LIBS = @GMP_LIBS@
+GMP_VERSION = @GMP_VERSION@
+GREP = @GREP@
+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@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NTL_CFLAGS = @NTL_CFLAGS@
+NTL_LIBS = @NTL_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OMALLOC_INCLUDES = @OMALLOC_INCLUDES@
+OMALLOC_LIBS = @OMALLOC_LIBS@
+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@
+PKG_REQUIRE = @PKG_REQUIRE@
+PMCONFIG = @PMCONFIG@
+PM_CFLAGS = @PM_CFLAGS@
+PM_INC = @PM_INC@
+PM_LDFLAGS = @PM_LDFLAGS@
+PM_LIBS = @PM_LIBS@
+POLYMAKE_CXXFLAGS = @POLYMAKE_CXXFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LDFLAGS = @PTHREAD_LDFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
+PYTHON = @PYTHON@
+PYTHON_CSPEC = @PYTHON_CSPEC@
+PYTHON_EXECPREFIX = @PYTHON_EXECPREFIX@
+PYTHON_LSPEC = @PYTHON_LSPEC@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+RANLIB = @RANLIB@
+RESOURCES_INCLUDES = @RESOURCES_INCLUDES@
+RESOURCES_LIBS = @RESOURCES_LIBS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SINGULAR_CFLAGS = @SINGULAR_CFLAGS@
+SI_COUNTEDREF_AUTOLOAD = @SI_COUNTEDREF_AUTOLOAD@
+SI_CPU_I386 = @SI_CPU_I386@
+SI_CPU_IA64 = @SI_CPU_IA64@
+SI_CPU_PPC = @SI_CPU_PPC@
+SI_CPU_SPARC = @SI_CPU_SPARC@
+SI_CPU_X86_64 = @SI_CPU_X86_64@
+STRIP = @STRIP@
+USEPPROCSDYNAMICLD = @USEPPROCSDYNAMICLD@
+USEPPROCSDYNAMICLDFLAGS = @USEPPROCSDYNAMICLDFLAGS@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
+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@
+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@
+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@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+ACLOCAL_AMFLAGS = -I ../m4
+emacsdir = $(datadir)/singular/emacs
+EMACS = \
+    ChangeLog \
+    COPYING \
+    NEWS \
+    singular.el \
+    singular.xpm  .emacs-general  .emacs-singular \
+    cmd-cmpl.el ex-cmpl.el hlp-cmpl.el lib-cmpl.el
+
+#++ hlp-cmpl.el lib-cmpl.el ex-cmpl.el cmd-cmpl.el: for now from Master Singular
+
+#-- BUGS     cmpl.pl     ESingular.emacs21     lib.pl     Makefile.in     singular.el.decl
+dist_emacs_DATA = $(EMACS)
+
+# test.sing
+# TODO: remove this!
+#all-local:
+#	[ -d ${builddir} ] || ln -s ${srcdir} ${builddir}
+EXTRA_DIST = $(EMACS)
+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) --foreign emacs/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign emacs/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-dist_emacsDATA: $(dist_emacs_DATA)
+	@$(NORMAL_INSTALL)
+	@list='$(dist_emacs_DATA)'; test -n "$(emacsdir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(emacsdir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(emacsdir)" || exit 1; \
+	fi; \
+	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)$(emacsdir)'"; \
+	  $(INSTALL_DATA) $$files "$(DESTDIR)$(emacsdir)" || exit $$?; \
+	done
+
+uninstall-dist_emacsDATA:
+	@$(NORMAL_UNINSTALL)
+	@list='$(dist_emacs_DATA)'; test -n "$(emacsdir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	dir='$(DESTDIR)$(emacsdir)'; $(am__uninstall_files_from_dir)
+tags TAGS:
+
+ctags CTAGS:
+
+cscope cscopelist:
+
+
+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)$(emacsdir)"; 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:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+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-dist_emacsDATA
+
+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-dist_emacsDATA
+
+.MAKE: install-am install-strip
+
+.PHONY: all all-am check check-am clean clean-generic clean-libtool \
+	cscopelist-am ctags-am distclean distclean-generic \
+	distclean-libtool distdir dvi dvi-am html html-am info info-am \
+	install install-am install-data install-data-am \
+	install-dist_emacsDATA 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 tags-am uninstall \
+	uninstall-am uninstall-dist_emacsDATA
+
+
+# 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/emacs/NEWS b/emacs/NEWS
new file mode 100644
index 0000000..8a752ce
--- /dev/null
+++ b/emacs/NEWS
@@ -0,0 +1,34 @@
+
+News up to revision 1.30
+========================
+
+* Customizing added.  There are the groups
+  - singular-faces
+
+* Section folding completely redesigned.  Uses overlays now.
+  Code splitted up into Emacs and XEmacs specific foldings.
+
+* Comint interface documented.  Old folding concerning
+  customizing of Comint's variables completely removed.  History
+  stuff simplified, modularized, moved to its own folding.
+  Chunks of a demo file are not inserted into history unless
+  user explicitly requests so.
+
+General news
+------------
+
+* Key map and menu folding splitted.  Logo stuff (mostly
+  commented) moved to menu folding.
+
+* Faces and Font Lock mode foldings moved to Singular interactive
+  mode specific code.  Syntax table folding moved to code common
+  to both modes.
+
+* Most of the foldings modularized.  That is, everything that
+  belongs logically to a folding moved into it.  In particular,
+  much code moved from Singular interactive mode initialization
+  to foldings.
+
+* Emacs 19 de-supported.
+
+* Some new style and coding conventions added.
diff --git a/emacs/cmd-cmpl.el b/emacs/cmd-cmpl.el
new file mode 100644
index 0000000..caeb6fa
--- /dev/null
+++ b/emacs/cmd-cmpl.el
@@ -0,0 +1,241 @@
+; Do not edit this file: It was automatically generated by cmpl.pl
+(setq singular-commands-alist
+  '(
+    ("ERROR")
+    ("insert")
+    ("parstr")
+    ("GCD")
+    ("int")
+    ("poly")
+    ("IN")
+    ("interpolation")
+    ("preimage")
+    ("LIB")
+    ("interred")
+    ("prime")
+    ("NF")
+    ("intersect")
+    ("primefactors")
+    ("RETURN")
+    ("intmat")
+    ("print")
+    ("TRACE")
+    ("intvec")
+    ("printlevel")
+    ("alias")
+    ("jacob")
+    ("proc")
+    ("and")
+    ("janet")
+    ("prune")
+    ("attrib")
+    ("jet")
+    ("qhweight")
+    ("bareiss")
+    ("kbase")
+    ("qrds")
+    ("betti")
+    ("keepring")
+    ("qring")
+    ("bigint")
+    ("kernel")
+    ("quote")
+    ("bigintmat")
+    ("kill")
+    ("quotient")
+    ("bracket")
+    ("killattrib")
+    ("random")
+    ("break")
+    ("koszul")
+    ("rank")
+    ("breakpoint")
+    ("kres")
+    ("read")
+    ("char")
+    ("laguerre")
+    ("reduce")
+    ("char_series")
+    ("lead")
+    ("regularity")
+    ("charstr")
+    ("leadcoef")
+    ("repart")
+    ("chinrem")
+    ("leadexp")
+    ("reservedName")
+    ("cleardenom")
+    ("leadmonom")
+    ("resolution")
+    ("close")
+    ("lift")
+    ("resultant")
+    ("coef")
+    ("liftstd")
+    ("return")
+    ("coeffs")
+    ("link")
+    ("ring")
+    ("continue")
+    ("list")
+    ("ringlist")
+    ("contract")
+    ("listvar")
+    ("rtimer")
+    ("convhull")
+    ("load")
+    ("rvar")
+    ("dbprint")
+    ("lres")
+    ("setring")
+    ("def")
+    ("ludecomp")
+    ("short")
+    ("defined")
+    ("luinverse")
+    ("simplex")
+    ("deg")
+    ("lusolve")
+    ("simplify")
+    ("degBound")
+    ("map")
+    ("size")
+    ("degree")
+    ("matrix")
+    ("slimgb")
+    ("delete")
+    ("maxideal")
+    ("sortvec")
+    ("det")
+    ("memory")
+    ("sqrfree")
+    ("diff")
+    ("minbase")
+    ("sres")
+    ("dim")
+    ("minor")
+    ("status")
+    ("div")
+    ("minpoly")
+    ("std")
+    ("division")
+    ("minres")
+    ("string")
+    ("dump")
+    ("mod")
+    ("subst")
+    ("echo")
+    ("module")
+    ("system")
+    ("eliminate")
+    ("modulo")
+    ("syz")
+    ("else")
+    ("monitor")
+    ("test")
+    ("envelope")
+    ("monomial")
+    ("timer")
+    ("eval")
+    ("mpresmat")
+    ("trace")
+    ("example")
+    ("mres")
+    ("transpose")
+    ("execute")
+    ("mstd")
+    ("twostd")
+    ("export")
+    ("mult")
+    ("type")
+    ("exportto")
+    ("multBound")
+    ("typeof")
+    ("extgcd")
+    ("multiplicity")
+    ("univariate")
+    ("facstd")
+    ("nameof")
+    ("uressolve")
+    ("factmodd")
+    ("names")
+    ("vandermonde")
+    ("factorize")
+    ("nc_algebra")
+    ("var")
+    ("farey")
+    ("ncalgebra")
+    ("variables")
+    ("fetch")
+    ("ncols")
+    ("varstr")
+    ("fglm")
+    ("newstruct")
+    ("vdim")
+    ("fglmquot")
+    ("noether")
+    ("vector")
+    ("find")
+    ("not")
+    ("verbose")
+    ("finduni")
+    ("npars")
+    ("voice")
+    ("forif")
+    ("nres")
+    ("waitall")
+    ("freemodule")
+    ("nrows")
+    ("waitfirst")
+    ("frwalk")
+    ("number")
+    ("wedge")
+    ("gcd")
+    ("nvars")
+    ("weight")
+    ("gen")
+    ("open")
+    ("whileif")
+    ("getdump")
+    ("oppose")
+    ("write")
+    ("highcorner")
+    ("opposite")
+    ("exit")
+    ("hilb")
+    ("option")
+    ("for")
+    ("homog")
+    ("or")
+    ("help")
+    ("hres")
+    ("ord")
+    ("newline")
+    ("ideal")
+    ("ordstr")
+    ("pause")
+    ("if")
+    ("package")
+    ("quit")
+    ("imap")
+    ("pagewidth")
+    ("while")
+    ("impart")
+    ("par")
+    ("importfrom")
+    ("parameter")
+    ("indepSet")
+    ("pardeg")
+    ("type")
+    ("3:")
+    ("fan")
+    ("type")
+    ("2:")
+    ("polytope")
+    ("type")
+    ("1:")
+    ("cone")
+    ("type")
+    ("0:")
+    ("pyobject")
+))
diff --git a/emacs/ex-cmpl.el b/emacs/ex-cmpl.el
new file mode 100644
index 0000000..fff392f
--- /dev/null
+++ b/emacs/ex-cmpl.el
@@ -0,0 +1,1681 @@
+; Do not edit this file: It was automatically generated by cmpl.pl
+(setq singular-examples-alist
+  '(
+    ("A_L")
+    ("A_Z")
+    ("absFactorize")
+    ("absPrimdecGTZ")
+    ("abstractR")
+    ("absValue")
+    ("Access_to_elements_of_a_user_defined_type")
+    ("actionIsProper")
+    ("addcol")
+    ("addRat")
+    ("addrow")
+    ("ademRelations")
+    ("Adj_div")
+    ("adjoint")
+    ("adjointIdeal")
+    ("admissibleSub")
+    ("afaces")
+    ("AG_codes")
+    ("AGcode_L")
+    ("AGcode_Omega")
+    ("alexanderpolynomial")
+    ("alg_kernel")
+    ("algDependent")
+    ("algebra_containment")
+    ("Algebraic_dependence")
+    ("algebraicDependence")
+    ("all_lib")
+    ("allDoubleExt")
+    ("allExtOfLeft")
+    ("allExtOfRight")
+    ("allPositive")
+    ("allprint")
+    ("allreal")
+    ("allrealst")
+    ("allsquarefree")
+    ("AltVarEnd")
+    ("AltVarStart")
+    ("ambientDimension")
+    ("Ann")
+    ("annfs")
+    ("annfs0")
+    ("annfs2")
+    ("annfsBMI")
+    ("annfsParamBM")
+    ("annfspecial")
+    ("annfsRB")
+    ("annil")
+    ("annPoly")
+    ("annRat")
+    ("annRatSyz")
+    ("appelF1")
+    ("appelF2")
+    ("appelF4")
+    ("appendWeight2Ord")
+    ("applyAdF")
+    ("areZeroElements")
+    ("ArnoldAction")
+    ("arrange")
+    ("ASCII")
+    ("ASCII_links")
+    ("ask")
+    ("Assignments_for_user_defined_types")
+    ("assPrimes")
+    ("Atkin")
+    ("attrib")
+    ("attrib_1")
+    ("attrib_2")
+    ("autonom")
+    ("autonomDim")
+    ("awalk1")
+    ("awalk2")
+    ("babyGiant")
+    ("backward")
+    ("bareiss")
+    ("Basic_programming")
+    ("basicinvariants")
+    ("belongSemigroup")
+    ("bernstein")
+    ("bernsteinBM")
+    ("bernsteinLift")
+    ("betti")
+    ("betti_BR_PLURAL_BR")
+    ("Betti_numbers_and_regularity")
+    ("bFactor")
+    ("bfct")
+    ("bfctAnn")
+    ("bfctBound")
+    ("bfctIdeal")
+    ("bfctOneGB")
+    ("bfctSyz")
+    ("bfctVarAnn")
+    ("bfctVarIn")
+    ("bigint_declarations")
+    ("bigint_expressions")
+    ("bigint_operations")
+    ("bigintmat_declarations")
+    ("bigintmat_expressions")
+    ("bigintmat_operations")
+    ("bigintmat_type_cast")
+    ("binomial")
+    ("binomials2intmat")
+    ("BINresol")
+    ("bistd")
+    ("bitrinity")
+    ("BlowingUp")
+    ("blowUp")
+    ("blowup0")
+    ("blowUp2")
+    ("blowUpBO")
+    ("Blowupcenter")
+    ("boolean_constant")
+    ("boolean_ideal")
+    ("boolean_operations")
+    ("boolean_poly")
+    ("boolean_set")
+    ("boolean_std")
+    ("BorelCheck")
+    ("boundBuFou")
+    ("boundDes")
+    ("boundposDes")
+    ("bracket")
+    ("Branches_of_space_curve_singularities")
+    ("breakpoint")
+    ("BrillNoether")
+    ("bubblesort")
+    ("busadj")
+    ("bvar")
+    ("calculateI")
+    ("canonicalizeCone")
+    ("canonize")
+    ("canonMap")
+    ("cantoradd")
+    ("cantormult")
+    ("cantorred")
+    ("cardGroup")
+    ("CenCharDec")
+    ("Center")
+    ("center")
+    ("CenterBO")
+    ("centerRed")
+    ("centerVS")
+    ("central1st")
+    ("central2nd")
+    ("centralizer")
+    ("centralizerRed")
+    ("centralizerVS")
+    ("centralizeSet")
+    ("CentralQuot")
+    ("CentralSaturation")
+    ("cgs")
+    ("cgsdr")
+    ("chaincrit")
+    ("changechar")
+    ("changeDenominator")
+    ("changeord")
+    ("changevar")
+    ("char")
+    ("char_series")
+    ("Characteristic_sets")
+    ("CharacteristicExponents")
+    ("charexp2conductor")
+    ("charexp2generators")
+    ("charexp2inter")
+    ("charexp2multseq")
+    ("charexp2poly")
+    ("charInfo")
+    ("charpoly")
+    ("charstr")
+    ("charVariety")
+    ("checkFactor")
+    ("checkRoot")
+    ("chineseRem")
+    ("chinrem")
+    ("chinrestp")
+    ("Classification_of_hypersurface_singularities")
+    ("classify")
+    ("classifyCeq")
+    ("cleanunit")
+    ("cleardenom")
+    ("closed_points")
+    ("closetex")
+    ("closureFrac")
+    ("CM_regularity")
+    ("CMtype")
+    ("codim")
+    ("codimension")
+    ("coef")
+    ("coeffmod")
+    ("coeffs")
+    ("coeffs_1")
+    ("coHom")
+    ("collectDiv")
+    ("colrank")
+    ("colred")
+    ("Command_line_options")
+    ("Commands_for_user_defined_types")
+    ("commRing")
+    ("CompDecomp")
+    ("completeReduction")
+    ("complexSingType")
+    ("ComplexValue")
+    ("compress")
+    ("Computation_of_Ext")
+    ("computemcm")
+    ("concat")
+    ("coneLink")
+    ("coneViaInequalities")
+    ("coneViaPoints")
+    ("constructblwup")
+    ("constructH")
+    ("constructlastblwup")
+    ("ContactMatrix")
+    ("containsAsFace")
+    ("containsInCollection")
+    ("containsInSupport")
+    ("containsPositiveVector")
+    ("containsRelatively")
+    ("content")
+    ("contract")
+    ("contraHom")
+    ("control")
+    ("controlDim")
+    ("controlExample")
+    ("convertdata")
+    ("convexHull")
+    ("convexIntersection")
+    ("convloc")
+    ("coords")
+    ("corank")
+    ("Cornacchia")
+    ("CornacchiaModified")
+    ("cornerMonomials")
+    ("countPoints")
+    ("createBO")
+    ("createGradedRingHomomorphism")
+    ("createGroup")
+    ("createlist")
+    ("createQuotientGroup")
+    ("createTorsionFreeGroup")
+    ("Critical_points")
+    ("cup")
+    ("cupproduct")
+    ("CurveParam")
+    ("CurveRes")
+    ("cyclic")
+    ("cyclotomic")
+    ("datetime")
+    ("DBM_links")
+    ("dbprint")
+    ("debug_log")
+    ("dec1var")
+    ("decimal")
+    ("Declaration_of_objects_of_a_user_defined_type")
+    ("decode")
+    ("decodeCode")
+    ("decodeRandom")
+    ("decodeRandomFL")
+    ("decodeSV")
+    ("decoef")
+    ("def")
+    ("def_declarations")
+    ("defined")
+    ("defineHomogeneous")
+    ("Definition_of_a_user_defined_type")
+    ("deform")
+    ("Deformations")
+    ("defring")
+    ("defringp")
+    ("defrings")
+    ("deg")
+    ("degree")
+    ("degreeDivisor")
+    ("degreeFormalDivisor")
+    ("degreepart")
+    ("delete")
+    ("deleteGenerator")
+    ("deleteSublist")
+    ("Delta")
+    ("delta")
+    ("DeltaList")
+    ("deltaLoc")
+    ("denominator")
+    ("Depth")
+    ("depth")
+    ("depthIdeal")
+    ("deRhamCohom")
+    ("deRhamCohomIdeal")
+    ("derivate")
+    ("det")
+    ("det_B")
+    ("detadj")
+    ("determinacy")
+    ("determinecenter")
+    ("develop")
+    ("diag")
+    ("diag_test")
+    ("diagInvariants")
+    ("diff")
+    ("diffRat")
+    ("difpoly2tex")
+    ("dim")
+    ("dim_BR_PLURAL_BR")
+    ("dim_slocus")
+    ("dimension")
+    ("dimGradedPart")
+    ("dimH")
+    ("dimMon")
+    ("direct_boolean_poly")
+    ("direct_from_boolean_poly")
+    ("disc")
+    ("discr")
+    ("discrepancy")
+    ("disp_zdd")
+    ("displayHNE")
+    ("displayInvariants")
+    ("displayMultsequence")
+    ("dividelist")
+    ("divideUnits")
+    ("division")
+    ("division_BR_PLURAL_BR")
+    ("divisor")
+    ("divisorplus")
+    ("DLoc")
+    ("DLoc0")
+    ("Dlocalization")
+    ("dmodAction")
+    ("dmodActionRat")
+    ("dmodGeneralAssumptionCheck")
+    ("dmodoublext")
+    ("double")
+    ("doubleExt")
+    ("DsingularLocus")
+    ("dsum")
+    ("dual_code")
+    ("dualCone")
+    ("dualPolytope")
+    ("dump")
+    ("Dynamic_modules")
+    ("ecart")
+    ("ECoef")
+    ("ECPP")
+    ("Edatalist")
+    ("eexgcdN")
+    ("effective")
+    ("ehrhartRing")
+    ("eigenvals")
+    ("eigenvalues")
+    ("elemSymmId")
+    ("elim")
+    ("elim1")
+    ("elim2")
+    ("eliminate")
+    ("eliminate_BR_PLURAL_BR")
+    ("eliminateNC")
+    ("Elimination")
+    ("elimlinearpart")
+    ("elimpart")
+    ("elimpartanyr")
+    ("elimrep")
+    ("elimRing")
+    ("elimWeight")
+    ("ellipticAdd")
+    ("ellipticAllPoints")
+    ("ellipticMult")
+    ("ellipticRandomCurve")
+    ("ellipticRandomPoint")
+    ("Emaxcont")
+    ("embedMat")
+    ("emptyFan")
+    ("encode")
+    ("endvfilt")
+    ("engine")
+    ("envelope")
+    ("EOrdlist")
+    ("equalJinI")
+    ("equalMultiDeg")
+    ("equations")
+    ("equidim")
+    ("equidimMax")
+    ("equidimMaxEHV")
+    ("equidimZ")
+    ("equiRadical")
+    ("Eresol")
+    ("ERROR")
+    ("errorInsert")
+    ("errormap")
+    ("errorRand")
+    ("esIdeal")
+    ("esStratum")
+    ("euler")
+    ("eval")
+    ("evaluate_reynolds")
+    ("evaluateFormalDivisor")
+    ("evaluatePDivisor")
+    ("Example_of_a_procedure_definition_in_a_library:")
+    ("Example_of_an_interactive_procedure_definition_and_its_execution:")
+    ("Example_of_use_of_ at sc{Letterplace}")
+    ("execute")
+    ("exgcdN")
+    ("exp2pt")
+    ("expo")
+    ("exportNuminvs")
+    ("exportto")
+    ("Ext")
+    ("Ext_R")
+    ("extcurve")
+    ("extdevelop")
+    ("extend")
+    ("extendedTensor")
+    ("extendring")
+    ("extendWeyl")
+    ("Exterior")
+    ("exteriorBasis")
+    ("exteriorPower")
+    ("extgcd")
+    ("facets")
+    ("facFirstShift")
+    ("facFirstWeyl")
+    ("facGBIdeal")
+    ("facstd")
+    ("facSubWeyl")
+    ("factmodd")
+    ("factorgroup")
+    ("factorH")
+    ("factorial")
+    ("Factorization")
+    ("factorize")
+    ("factorLenstraECM")
+    ("fanViaCones")
+    ("farey")
+    ("fastelim")
+    ("fastExpt")
+    ("fetch")
+    ("fetch_BR_PLURAL_BR")
+    ("fetchall")
+    ("ffsolve")
+    ("fglm")
+    ("fglm_solve")
+    ("fglmquot")
+    ("fibonacci")
+    ("find")
+    ("findAuto")
+    ("findifs_example")
+    ("findimAlgebra")
+    ("findInvo")
+    ("findInvoDiag")
+    ("findTorsion")
+    ("finduni")
+    ("findvars")
+    ("Finite_fields")
+    ("finiteDiagInvariants")
+    ("finitenessTest")
+    ("First_index_is_1")
+    ("firstoct")
+    ("fitting")
+    ("fl2poly")
+    ("flatten")
+    ("flatteningStrat")
+    ("formaldivisorplus")
+    ("Formatting_output")
+    ("forward")
+    ("fourier")
+    ("fouriersystem")
+    ("fprintf")
+    ("Free_resolution")
+    ("Free_resolutions")
+    ("freeGBasis")
+    ("freemodule")
+    ("freerank")
+    ("from_boolean_constant")
+    ("from_boolean_ideal")
+    ("from_boolean_poly")
+    ("from_boolean_set")
+    ("frwalk")
+    ("fullFan")
+    ("fullFan_1")
+    ("fullSerreRelations")
+    ("Function_without_return_value")
+    ("further_hn_proc")
+    ("furtherInvar")
+    ("fwalk")
+    ("G_a_-Invariants")
+    ("Gamma")
+    ("Gauss-Manin_connection")
+    ("Gauss-Manin_connection_1")
+    ("Gauss-Manin_connection_2")
+    ("gauss_col")
+    ("gauss_nf")
+    ("gauss_row")
+    ("gaussred")
+    ("gaussred_pivot")
+    ("GBsolve")
+    ("GBWeight")
+    ("gcd")
+    ("gcddivisor")
+    ("gcdMon")
+    ("gcdN")
+    ("gen")
+    ("Generalized_Hilbert_Syzygy_Theorem")
+    ("generalOrder")
+    ("generateG")
+    ("generatorsOfLinealitySpace")
+    ("generatorsOfSpan")
+    ("genericid")
+    ("genericity")
+    ("genericmat")
+    ("genMDSMat")
+    ("genoutput")
+    ("genSymId")
+    ("genus")
+    ("getCone")
+    ("getdump")
+    ("getGradingGroup")
+    ("getLattice")
+    ("getLinearForms")
+    ("getModuleGrading")
+    ("getMultiplicity")
+    ("getOneVar")
+    ("getSmallest")
+    ("getVariableWeights")
+    ("gitCone")
+    ("gitFan")
+    ("GKdim")
+    ("gkzFan")
+    ("GKZsystem")
+    ("globalSections")
+    ("gmscoeffs")
+    ("gmsnf")
+    ("gmsring")
+    ("goodBasis")
+    ("Graded_commutative_algebras__SCA_")
+    ("gradeNumber")
+    ("gradiator")
+    ("graver4ti2")
+    ("grobcov")
+    ("groebner")
+    ("groebner_and_std")
+    ("Groebner_basis_conversion")
+    ("group_reynolds")
+    ("GTZmod")
+    ("GTZopt")
+    ("gwalk")
+    ("Gweights")
+    ("H2basis")
+    ("Handling_graded_modules")
+    ("Hcode")
+    ("headStand")
+    ("heightZ")
+    ("hermiteNormalForm")
+    ("hessenberg")
+    ("highcorner")
+    ("hilb")
+    ("hilbert4ti2")
+    ("HilbertClassPoly")
+    ("hilbertSeries")
+    ("hilbPoly")
+    ("hilbvec")
+    ("hnexpansion")
+    ("holonomicRank")
+    ("Hom")
+    ("hom_kernel")
+    ("HomJJ")
+    ("homog")
+    ("homogfacFirstQWeyl")
+    ("homogfacFirstQWeyl_all")
+    ("homology")
+    ("How_to_use_links")
+    ("How_to_use_links_1")
+    ("hres")
+    ("id2mod")
+    ("ideal_declarations")
+    ("ideal_declarations_BR_PLURAL_BR")
+    ("ideal_expressions")
+    ("ideal_expressions_BR_PLURAL_BR")
+    ("ideal_operations")
+    ("ideal_operations_BR_PLURAL_BR")
+    ("idealsimplify")
+    ("idealSplit")
+    ("Identifier_resolution")
+    ("Identifier_resolution_1")
+    ("identifyvar")
+    ("image_of_variety")
+    ("ImageGroup")
+    ("imageLattice")
+    ("ImageVariety")
+    ("imap")
+    ("imap_BR_PLURAL_BR")
+    ("imapall")
+    ("impart")
+    ("importfrom")
+    ("iMult")
+    ("inCenter")
+    ("inCentralizer")
+    ("indepSet")
+    ("indSet")
+    ("inequalities")
+    ("inForm")
+    ("iniD")
+    ("init_debug")
+    ("initialIdealW")
+    ("initialMalgrange")
+    ("insert")
+    ("insertCone")
+    ("insertGenerator")
+    ("inSubring")
+    ("int_declarations")
+    ("int_expressions")
+    ("int_operations")
+    ("intclMonIdeal")
+    ("intclToricRing")
+    ("integralBasis")
+    ("integralIdeal")
+    ("integralModule")
+    ("integralSection")
+    ("internalfunctions")
+    ("interpolate")
+    ("interpolation")
+    ("interred")
+    ("intersect")
+    ("intersect_BR_PLURAL_BR")
+    ("intersection")
+    ("intersectionDiv")
+    ("IntersectionMatrix")
+    ("intersectionValRingIdeals")
+    ("intersectionValRings")
+    ("intersectLattices")
+    ("intersectMon")
+    ("IntersectWithSub")
+    ("intersectZ")
+    ("intInverse")
+    ("intmat2mons")
+    ("intmat_declarations")
+    ("intmat_expressions")
+    ("intmat_operations")
+    ("intmat_type_cast")
+    ("intPart")
+    ("intRank")
+    ("intRoot")
+    ("intRoots")
+    ("intvec_declarations")
+    ("intvec_expressions")
+    ("intvec_operations")
+    ("invariant_algebra_perm")
+    ("invariant_algebra_reynolds")
+    ("invariant_basis")
+    ("invariant_basis_reynolds")
+    ("invariant_ring")
+    ("invariant_ring_random")
+    ("InvariantRing")
+    ("invariantRing")
+    ("invariants")
+    ("Invariants_of_a_finite_group")
+    ("Invariants_of_plane_curve_singularities")
+    ("inverse")
+    ("inverse_B")
+    ("inverse_L")
+    ("inverseFourier")
+    ("invertBirMap")
+    ("involution")
+    ("invunit")
+    ("iostruct")
+    ("irred_secondary_char0")
+    ("irred_secondary_no_molien")
+    ("irreddecMon")
+    ("irrRealizationDim")
+    ("is_active")
+    ("is_bijective")
+    ("is_cenBimodule")
+    ("is_cenSubbimodule")
+    ("is_ci")
+    ("is_complex")
+    ("is_injective")
+    ("is_irred")
+    ("is_is")
+    ("is_nested")
+    ("is_NND")
+    ("is_NP")
+    ("is_pure")
+    ("is_reg")
+    ("is_regs")
+    ("is_surjective")
+    ("is_zero")
+    ("isAface")
+    ("isAntiEndo")
+    ("isartinianMon")
+    ("isCartan")
+    ("isCentral")
+    ("isCI")
+    ("isCM")
+    ("isCMcod2")
+    ("isCommutative")
+    ("isCompatible")
+    ("isEqualDivisor")
+    ("isEquising")
+    ("isFlat")
+    ("isFsat")
+    ("isFullSpace")
+    ("isgenericMon")
+    ("isGradedRingHomomorphism")
+    ("isGroup")
+    ("isGroupHomomorphism")
+    ("isHolonomic")
+    ("isHomogeneous")
+    ("ishyper")
+    ("isInt")
+    ("isIntegralSurjective")
+    ("isInvolution")
+    ("isirreducibleMon")
+    ("isLocallyFree")
+    ("isMonomial")
+    ("isNC")
+    ("isOnCurve")
+    ("isoncurve")
+    ("isOrigin")
+    ("isparam")
+    ("isPositive")
+    ("isprimaryMon")
+    ("isprimeMon")
+    ("isPrimitiveSublattice")
+    ("isPure")
+    ("isPureTensor")
+    ("isRational")
+    ("isReg")
+    ("IsSCA")
+    ("isSimplicial")
+    ("isSublattice")
+    ("isSymmetric")
+    ("isTame")
+    ("isTorsionFree")
+    ("isTwoSidedGB")
+    ("isuni")
+    ("isUpperTriangular")
+    ("isVar")
+    ("isWeyl")
+    ("isZeroElement")
+    ("iv2lp")
+    ("iv2lpList")
+    ("iv2lpMat")
+    ("ivDHilbert")
+    ("ivDHilbertSickle")
+    ("ivDimCheck")
+    ("ivHilbert")
+    ("ivKDim")
+    ("ivL2lpI")
+    ("ivMis2Base")
+    ("ivMis2Dim")
+    ("ivOrdMisLex")
+    ("ivSickle")
+    ("ivSickleDim")
+    ("ivSickleHil")
+    ("jacob")
+    ("Jacobi")
+    ("jacoblift")
+    ("jacobson")
+    ("janet")
+    ("jet")
+    ("JMarkedScheme")
+    ("jOft")
+    ("jordan")
+    ("jordanbasis")
+    ("jordanmatrix")
+    ("jordannf")
+    ("jungfib")
+    ("jungnormal")
+    ("jungresolve")
+    ("katsura")
+    ("kbase")
+    ("kbase_BR_PLURAL_BR")
+    ("kernel")
+    ("Kernel_of_module_homomorphisms")
+    ("kernelLattice")
+    ("kill")
+    ("killall")
+    ("killattrib")
+    ("kmemory")
+    ("kohom")
+    ("kontrahom")
+    ("koszul")
+    ("KoszulHomology")
+    ("KScoef")
+    ("KSconvert")
+    ("KSker")
+    ("KSlinear")
+    ("KSpencerKernel")
+    ("laguerre")
+    ("laguerre_solve")
+    ("lastvarGeneral")
+    ("latticeBasis")
+    ("laxfrT")
+    ("laxfrX")
+    ("lcm")
+    ("lcmMon")
+    ("lcmN")
+    ("lcmofall")
+    ("lead")
+    ("leadcoef")
+    ("leadexp")
+    ("leadmonom")
+    ("leadmonomial")
+    ("Left_and_two-sided_Groebner_bases")
+    ("leftInverse")
+    ("leftKernel")
+    ("LengthSym")
+    ("LengthSymElement")
+    ("letplaceGBasis")
+    ("lex_solve")
+    ("LIB")
+    ("lieBracket")
+    ("lift")
+    ("lift_BR_PLURAL_BR")
+    ("lift_kbase")
+    ("lift_rel_kb")
+    ("liftenvelope")
+    ("liftstd")
+    ("liftstd_BR_PLURAL_BR")
+    ("linealityDimension")
+    ("linealitySpace")
+    ("linear_relations")
+    ("LinearActionQ")
+    ("linearCombinations")
+    ("LinearizeAction")
+    ("linearlyEquivalent")
+    ("linearMapKernel")
+    ("linearpart")
+    ("link_declarations")
+    ("linReduce")
+    ("linReduceIdeal")
+    ("linSyzSolve")
+    ("list_declarations")
+    ("list_expressions")
+    ("list_operations")
+    ("listvar")
+    ("LLL")
+    ("lll")
+    ("load")
+    ("load_1")
+    ("Loading_a_library")
+    ("localInvar")
+    ("localstd")
+    ("locAtZero")
+    ("locNormal")
+    ("locstd")
+    ("log2")
+    ("Long_coefficients")
+    ("lp2iv")
+    ("lp2ivId")
+    ("lp2lstr")
+    ("lpDHilbert")
+    ("lpDHilbertSickle")
+    ("lpDimCheck")
+    ("lpHilbert")
+    ("lpId2ivLi")
+    ("lpKDim")
+    ("lpMis2Base")
+    ("lpMis2Dim")
+    ("lpMult")
+    ("lpNF")
+    ("lpOrdMisLex")
+    ("lpPower")
+    ("lprint")
+    ("lpSickle")
+    ("lpSickleDim")
+    ("lpSickleHil")
+    ("lres")
+    ("lst2str")
+    ("ludecomp")
+    ("luinverse")
+    ("lusolve")
+    ("magnitude")
+    ("makeDivisor")
+    ("makeFormalDivisor")
+    ("makeHeisenberg")
+    ("makeLetterplaceRing")
+    ("makeMalgrange")
+    ("makeModElimRing")
+    ("makePDivisor")
+    ("makeQsl2")
+    ("makeQsl3")
+    ("makeQso3")
+    ("makeUe6")
+    ("makeUe7")
+    ("makeUe8")
+    ("makeUf4")
+    ("makeUg2")
+    ("makeUgl")
+    ("makeUsl")
+    ("makeUsl2")
+    ("makeUso10")
+    ("makeUso11")
+    ("makeUso12")
+    ("makeUso5")
+    ("makeUso6")
+    ("makeUso7")
+    ("makeUso8")
+    ("makeUso9")
+    ("makeUsp1")
+    ("makeUsp2")
+    ("makeUsp3")
+    ("makeUsp4")
+    ("makeUsp5")
+    ("makeWeyl")
+    ("map_BR_PLURAL_BR_operations")
+    ("map_declarations")
+    ("map_declarations_BR_PLURAL_BR")
+    ("map_operations")
+    ("mapall")
+    ("mapIsFinite")
+    ("mapToRatNormCurve")
+    ("markov4ti2")
+    ("mat_rk")
+    ("matbil")
+    ("matmult")
+    ("matrix_declarations")
+    ("matrix_expressions")
+    ("matrix_operations")
+    ("Matrix_orderings")
+    ("Matrix_orderings_1")
+    ("matrix_type_cast")
+    ("matrixExp")
+    ("matrixLog")
+    ("matrixsystem")
+    ("matrixT1")
+    ("Max")
+    ("maxabs")
+    ("maxcoef")
+    ("maxdeg")
+    ("maxdeg1")
+    ("maxEord")
+    ("maxideal")
+    ("maximum")
+    ("Maximus")
+    ("maxIntRoot")
+    ("Maxord")
+    ("maxZeros")
+    ("mdouble")
+    ("membershipMon")
+    ("memory")
+    ("midpoint")
+    ("MillerRabin")
+    ("milnor")
+    ("Milnor_and_Tjurina_number")
+    ("milnorcode")
+    ("milnornumber")
+    ("Min")
+    ("minAssChar")
+    ("minAssGTZ")
+    ("minAssZ")
+    ("minbase")
+    ("minbaseMon")
+    ("mindeg")
+    ("mindeg1")
+    ("mindist")
+    ("minEcart")
+    ("MinimalDecomposition")
+    ("Minimus")
+    ("minIntRoot")
+    ("minIntRoot2")
+    ("minipoly")
+    ("minMult")
+    ("minor")
+    ("minpoly")
+    ("minres")
+    ("minres_BR_PLURAL_BR")
+    ("Miscellaneous_oddities")
+    ("Miscellaneous_oddities_1")
+    ("Miscellaneous_oddities_2")
+    ("Miscellaneous_oddities_3")
+    ("Miscellaneous_oddities_4")
+    ("mod2id")
+    ("mod2str")
+    ("mod_versal")
+    ("modality")
+    ("modDec")
+    ("ModEqn")
+    ("modHenselStd")
+    ("modNormal")
+    ("modS")
+    ("modStd")
+    ("module_containment")
+    ("module_declarations")
+    ("module_declarations_BR_PLURAL_BR")
+    ("module_operations")
+    ("module_operations_BR_PLURAL_BR")
+    ("Module_orderings")
+    ("Module_orderings_1")
+    ("Module_orderings_2")
+    ("Module_orderings_3")
+    ("modulo")
+    ("modulo_BR_PLURAL_BR")
+    ("moduloSlim")
+    ("molien")
+    ("monodromy")
+    ("monodromyB")
+    ("monomial")
+    ("monomialInIdeal")
+    ("monomialLcm")
+    ("mons2intmat")
+    ("morsesplit")
+    ("mp_res_mat")
+    ("MPfile_links")
+    ("mpresmat")
+    ("MPtcp_links")
+    ("mres")
+    ("mres_BR_PLURAL_BR")
+    ("mstd")
+    ("msum")
+    ("mtriple")
+    ("mult")
+    ("multBound")
+    ("multcol")
+    ("multdivisor")
+    ("multformaldivisor")
+    ("multi")
+    ("multiDeg")
+    ("multiDegBasis")
+    ("multiDegGroebner")
+    ("multiDegModulo")
+    ("multiDegPartition")
+    ("multiDegResolution")
+    ("multiDegSyzygy")
+    ("multiDegTensor")
+    ("MultiplicitySequence")
+    ("multiplylist")
+    ("multRat")
+    ("multrow")
+    ("multseq2charexp")
+    ("multsequence")
+    ("nameof")
+    ("Names")
+    ("names")
+    ("Names_1")
+    ("Names_2")
+    ("Names_3")
+    ("Names_in_procedures")
+    ("nashmult")
+    ("nc_algebra")
+    ("ncdetection")
+    ("ncExt_R")
+    ("ncHom")
+    ("ncols")
+    ("ncones")
+    ("ncRelations")
+    ("ndcond")
+    ("negatedCone")
+    ("negativedivisor")
+    ("negativeformaldivisor")
+    ("newTest")
+    ("newtonDiag")
+    ("newtonpoly")
+    ("newtonPolytope")
+    ("nf_icis")
+    ("NFMora")
+    ("nmaxcones")
+    ("noether")
+    ("noetherNormal")
+    ("NoetherPosition")
+    ("Nonhyp")
+    ("nonMonomials")
+    ("nonZeroEntry")
+    ("norm")
+    ("normal")
+    ("normalC")
+    ("normalForm")
+    ("normalform")
+    ("normalI")
+    ("normaliz")
+    ("Normalization")
+    ("normalize")
+    ("normalP")
+    ("normalToricRing")
+    ("normalToricRingFromBinomials")
+    ("norTest")
+    ("npar")
+    ("npars")
+    ("nres")
+    ("nres_BR_PLURAL_BR")
+    ("nrows")
+    ("nrroots")
+    ("nrRootsDeterm")
+    ("nrRootsProbab")
+    ("nselect")
+    ("NSplaces")
+    ("nt_solve")
+    ("NullCone")
+    ("number_declarations")
+    ("number_e")
+    ("number_expressions")
+    ("number_operations")
+    ("number_pi")
+    ("numberOfConesOfDimension")
+    ("numerator")
+    ("nvars")
+    ("Objects")
+    ("oneDimBelongSemigroup")
+    ("opentex")
+    ("operatorBM")
+    ("operatorModulo")
+    ("oppose")
+    ("opposite")
+    ("option")
+    ("orbit_variety")
+    ("orbitCones")
+    ("ord")
+    ("ord_test")
+    ("ordstr")
+    ("orthogonalize")
+    ("outer")
+    ("package_declarations")
+    ("pairset")
+    ("par")
+    ("par2varRing")
+    ("paraConic")
+    ("Parallelization_with_MPtcp_links")
+    ("parallelWaitAll")
+    ("parallelWaitFirst")
+    ("parallelWaitN")
+    ("param")
+    ("Parameters")
+    ("parametrizeOrbit")
+    ("paraPlaneCurve")
+    ("pardeg")
+    ("parstr")
+    ("partial_molien")
+    ("PartitionVar")
+    ("ParToVar")
+    ("pause")
+    ("PBW_eqDeg")
+    ("PBW_maxDeg")
+    ("PBW_maxMonom")
+    ("pdivi")
+    ("pdivisorplus")
+    ("PerfectPowerTest")
+    ("permcol")
+    ("permrow")
+    ("permute_L")
+    ("perron")
+    ("PEsolve")
+    ("pFactor")
+    ("PH_ais")
+    ("PH_nais")
+    ("pIntersect")
+    ("pIntersectSyz")
+    ("Pipe_links")
+    ("plainInvariants")
+    ("pmat")
+    ("pnormalf")
+    ("PocklingtonLehmer")
+    ("Polar_curves")
+    ("PollardRho")
+    ("polSol")
+    ("polSolFiniteRank")
+    ("poly")
+    ("poly2list")
+    ("poly2zdd")
+    ("poly_BR_PLURAL_BR")
+    ("poly_declarations")
+    ("poly_declarations_BR_PLURAL_BR")
+    ("poly_expressions")
+    ("poly_expressions_BR_PLURAL_BR")
+    ("poly_operations")
+    ("polytopeViaInequalities")
+    ("polytopeViaPoints")
+    ("polyVars")
+    ("pos_def")
+    ("posweight")
+    ("power")
+    ("power_products")
+    ("powerN")
+    ("powerpolyX")
+    ("powersums")
+    ("powerX")
+    ("preComp")
+    ("preimage")
+    ("preimage_BR_PLURAL_BR")
+    ("preimageLattice")
+    ("preimageLoc")
+    ("preimageNC")
+    ("prepareAss")
+    ("prepEmbDiv")
+    ("prepRealclassify")
+    ("prepSV")
+    ("primary_char0")
+    ("primary_char0_no_molien")
+    ("primary_char0_no_molien_random")
+    ("primary_char0_random")
+    ("primary_charp")
+    ("primary_charp_no_molien")
+    ("primary_charp_no_molien_random")
+    ("primary_charp_random")
+    ("primary_charp_without")
+    ("primary_charp_without_random")
+    ("Primary_decomposition")
+    ("primary_invariants")
+    ("primary_invariants_random")
+    ("PrimdecA")
+    ("PrimdecB")
+    ("primdecGTZ")
+    ("primdecMon")
+    ("primdecSY")
+    ("primdecZ")
+    ("prime")
+    ("primeClosure")
+    ("primecoeffs")
+    ("primefactors")
+    ("primes")
+    ("primitive")
+    ("primitive_extra")
+    ("primitiveSpan")
+    ("primL")
+    ("primList")
+    ("primparam")
+    ("primRoot")
+    ("primTest")
+    ("print")
+    ("Print_command")
+    ("printf")
+    ("printGroup")
+    ("printlevel")
+    ("proc_declaration")
+    ("prodcrit")
+    ("product")
+    ("productgroup")
+    ("projectiveDimension")
+    ("projectLattice")
+    ("proximitymatrix")
+    ("prune")
+    ("psigncnd")
+    ("puiseux2generators")
+    ("purelist")
+    ("purityFiltration")
+    ("purityTriang")
+    ("pushForward")
+    ("pwalk")
+    ("pyobject")
+    ("pyobject_declarations")
+    ("pyobject_expressions")
+    ("pyobject_operations")
+    ("pyobject_related_functions")
+    ("pyobject_related_functions_1")
+    ("pyramid")
+    ("python_eval")
+    ("python_import")
+    ("python_run")
+    ("qbase")
+    ("qepcad")
+    ("qepcadsystem")
+    ("qhmatrix")
+    ("qhspectrum")
+    ("qhweight")
+    ("qminor")
+    ("qrds")
+    ("qring_declaration")
+    ("qring_declaration_BR_PLURAL_BR")
+    ("qslimgb")
+    ("Qso3Casimir")
+    ("quadraticSieve")
+    ("quantMat")
+    ("quickclass")
+    ("quote")
+    ("Quotient")
+    ("quotient")
+    ("quotient_BR_PLURAL_BR")
+    ("Quotient_rings")
+    ("quotientLatticeBasis")
+    ("quotientMon")
+    ("rad_con")
+    ("radical")
+    ("radicalEHV")
+    ("radicalMon")
+    ("radicalZ")
+    ("randcharpoly")
+    ("randlinpoly")
+    ("random")
+    ("randomBinomial")
+    ("randomCheck")
+    ("randomid")
+    ("randomLast")
+    ("randommat")
+    ("randomPoint")
+    ("rank")
+    ("rationalPointConic")
+    ("ratSol")
+    ("ratstd")
+    ("rays")
+    ("read")
+    ("readNmzData")
+    ("realclassify")
+    ("realizationDim")
+    ("realizationDimPoly")
+    ("realmorsesplit")
+    ("realpoly")
+    ("realrad")
+    ("realzero")
+    ("recursive_boolean_poly")
+    ("recursive_from_boolean_poly")
+    ("reduce")
+    ("reduce_BR_PLURAL_BR")
+    ("reduction")
+    ("ReesAlgebra")
+    ("reference_and_shared__experimental_")
+    ("reference_and_shared__experimental__1")
+    ("reference_and_shared__experimental__2")
+    ("reference_and_shared__experimental__3")
+    ("reference_and_shared_operations")
+    ("reference_and_shared_operations_1")
+    ("reference_and_shared_operations_2")
+    ("reference_and_shared_related_functions")
+    ("reference_and_shared_related_functions_1")
+    ("reference_and_shared_related_functions_2")
+    ("reference_declarations")
+    ("reference_expressions")
+    ("regIdeal")
+    ("regMonCurve")
+    ("regularity")
+    ("reiffen")
+    ("rel_orbit_variety")
+    ("relative_orbit_variety")
+    ("relativeInteriorPoint")
+    ("relweight")
+    ("remainder")
+    ("removeCone")
+    ("removepower")
+    ("repart")
+    ("replace")
+    ("res")
+    ("reservedName")
+    ("resfunction")
+    ("reslist")
+    ("resolution_declarations")
+    ("resolution_declarations_BR_PLURAL_BR")
+    ("Resolution_of_singularities")
+    ("resolutiongraph")
+    ("resolve")
+    ("restrictionIdeal")
+    ("restrictionModule")
+    ("resultant")
+    ("Return_type_of_procedures")
+    ("Return_type_of_procedures_1")
+    ("reverse")
+    ("reynolds_molien")
+    ("rho")
+    ("Right_Groebner_bases_and_syzygies")
+    ("rightInverse")
+    ("rightKernel")
+    ("rightModulo")
+    ("rightNF")
+    ("rightNFWeyl")
+    ("rightStd")
+    ("ring_operations")
+    ("ring_operations_BR_PLURAL_BR")
+    ("ringlist")
+    ("ringlist_BR_PLURAL_BR")
+    ("Rings_and_standard_bases")
+    ("Rings_associated_to_monomial_orderings")
+    ("ringtensor")
+    ("ringweights")
+    ("rm_unitcol")
+    ("rm_unitrow")
+    ("rMacaulay")
+    ("rmNmzFiles")
+    ("rmx")
+    ("rncAntiCanonicalMap")
+    ("rncItProjEven")
+    ("rncItProjOdd")
+    ("rootofUnity")
+    ("roots")
+    ("rootsModp")
+    ("round")
+    ("rowred")
+    ("rvar")
+    ("sa_poly_reduce")
+    ("sa_reduce")
+    ("safeVarName")
+    ("sagbi")
+    ("sagbiPart")
+    ("sagbiReduce")
+    ("sagbiSPoly")
+    ("salida")
+    ("sameComponent")
+    ("Sannfs")
+    ("SannfsBFCT")
+    ("Sannfslog")
+    ("SannfsVar")
+    ("sat")
+    ("satiety")
+    ("Saturation")
+    ("scalarProd")
+    ("scheme")
+    ("Schoof")
+    ("SDLoc")
+    ("secondary_and_irreducibles_no_molien")
+    ("secondary_char0")
+    ("secondary_charp")
+    ("secondary_no_molien")
+    ("secondary_not_cohen_macaulay")
+    ("select")
+    ("select1")
+    ("semiCMcod2")
+    ("semidiv")
+    ("semigroup")
+    ("semigroupGenerator")
+    ("separateHNE")
+    ("separator")
+    ("serreRelations")
+    ("setBaseMultigrading")
+    ("setglobalrings")
+    ("setinitials")
+    ("setLetterplaceAttributes")
+    ("setLinearForms")
+    ("setModuleGrading")
+    ("setMultiplicity")
+    ("setNmzDataPath")
+    ("setNmzExecPath")
+    ("setNmzFilename")
+    ("setNmzOption")
+    ("setring")
+    ("ShanksMestre")
+    ("shared_declarations")
+    ("shared_expressions")
+    ("sheafCoh")
+    ("sheafCohBGG")
+    ("sheafCohBGG2")
+    ("shiftPoly")
+    ("short")
+    ("show")
+    ("showgrades")
+    ("showNmzOptions")
+    ("showNuminvs")
+    ("showrecursive")
+    ("sickle")
+    ("signatureBrieskorn")
+    ("signatureL")
+    ("signatureLqf")
+    ("signatureNemethi")
+    ("signaturePuiseux")
+    ("signcnd")
+    ("simplesolver")
+    ("simplex")
+    ("simplexOut")
+    ("simplify")
+    ("simplifyRat")
+    ("singularity")
+    ("size")
+    ("skewmat")
+    ("slim_Groebner_bases")
+    ("slimgb")
+    ("slimgb_BR_PLURAL_BR")
+    ("slocus")
+    ("smith")
+    ("smithNormalForm")
+    ("SolowayStrassen")
+    ("solutionsMod2")
+    ("solve")
+    ("solve_IP")
+    ("solvelinearpart")
+    ("Solving_systems_of_polynomial_equations")
+    ("sort")
+    ("sortandmap")
+    ("sortier")
+    ("sortIntvec")
+    ("sortvars")
+    ("sortvec")
+    ("spadd")
+    ("span")
+    ("sparseHomogIdeal")
+    ("sparseid")
+    ("sparsemat")
+    ("sparsematrix")
+    ("sparsepoly")
+    ("sparsetriag")
+    ("spectralNeg")
+    ("spectrum")
+    ("spectrumnd")
+    ("spgamma")
+    ("spgeomgenus")
+    ("spissemicont")
+    ("split")
+    ("splitring")
+    ("splitting")
+    ("spmilnor")
+    ("spmul")
+    ("spnf")
+    ("spoly")
+    ("sppairs")
+    ("sppnf")
+    ("sppprint")
+    ("spprint")
+    ("sprintf")
+    ("spsemicont")
+    ("spsub")
+    ("sqfrNorm")
+    ("sqr")
+    ("sqrfree")
+    ("squarefree")
+    ("squareRoot")
+    ("sres")
+    ("Ssi_file_links")
+    ("Ssi_tcp_links")
+    ("StabEqn")
+    ("StabEqnId")
+    ("standard")
+    ("startNmz")
+    ("StartOrderingV")
+    ("status")
+    ("std")
+    ("std_BR_PLURAL_BR")
+    ("stdfglm")
+    ("stdhilb")
+    ("string")
+    ("string_declarations")
+    ("string_expressions")
+    ("string_operations")
+    ("string_type_cast")
+    ("StringF")
+    ("stripHNE")
+    ("sturm")
+    ("sturmha")
+    ("sturmhaseq")
+    ("sturmquery")
+    ("sturmseq")
+    ("submat")
+    ("subrInterred")
+    ("subst")
+    ("subst_BR_PLURAL_BR")
+    ("substitute")
+    ("sum")
+    ("sumlist")
+    ("superCommutative")
+    ("swap")
+    ("sym_gauss")
+    ("SymGroup")
+    ("symmat")
+    ("symmetricBasis")
+    ("symmetricPower")
+    ("symmfunc")
+    ("symmStd")
+    ("syModStd")
+    ("symsignature")
+    ("syndrome")
+    ("sys_code")
+    ("sysBin")
+    ("sysCRHT")
+    ("sysCRHTMindist")
+    ("sysFL")
+    ("sysNewton")
+    ("sysQE")
+    ("system")
+    ("syz")
+    ("syz_BR_PLURAL_BR")
+    ("Syzygies")
+    ("T1_and_T2")
+    ("T_1")
+    ("T_12")
+    ("T_2")
+    ("tab")
+    ("tail")
+    ("tangentcone")
+    ("tangentGens")
+    ("tau_es")
+    ("tau_es2")
+    ("tensor")
+    ("tensorMod")
+    ("TestJMark")
+    ("testNCfac")
+    ("testParametrization")
+    ("testPointConic")
+    ("testPrimary")
+    ("tex")
+    ("texcoef")
+    ("texfactorize")
+    ("texmap")
+    ("texname")
+    ("texobj")
+    ("texpoly")
+    ("texproc")
+    ("texring")
+    ("timeFactorize")
+    ("timer")
+    ("timeStd")
+    ("timestep")
+    ("Tjurina")
+    ("tjurina")
+    ("tmatrix")
+    ("tolessvars")
+    ("Tor")
+    ("toric_ideal")
+    ("toric_std")
+    ("torusInvariants")
+    ("totalmultiplicities")
+    ("TRACE")
+    ("trace")
+    ("tracemult")
+    ("Tracing_of_procedures")
+    ("transpose")
+    ("trapezoid")
+    ("triagmatrix")
+    ("triang_solve")
+    ("triangL_solve")
+    ("triangLf_solve")
+    ("triangM_solve")
+    ("triMNewton")
+    ("truncate")
+    ("truncateFast")
+    ("tst_ncfactor")
+    ("twalk")
+    ("twostd")
+    ("type")
+    ("Type_casting")
+    ("typeof")
+    ("u")
+    ("U_D_O")
+    ("uniquePoint")
+    ("unitmat")
+    ("univariate")
+    ("univarpoly")
+    ("updatePairs")
+    ("UpOneMatrix")
+    ("UpperMonomials")
+    ("ures_solve")
+    ("valvars")
+    ("vandermonde")
+    ("vanishId")
+    ("var")
+    ("variables")
+    ("variablesSorted")
+    ("variablesStandard")
+    ("varNum")
+    ("vars2pars")
+    ("varsigns")
+    ("varstr")
+    ("VarToPar")
+    ("vct2str")
+    ("vdim")
+    ("vdim_BR_PLURAL_BR")
+    ("vec2poly")
+    ("vector_declarations")
+    ("vector_expressions")
+    ("vector_operations")
+    ("verify")
+    ("versal")
+    ("vertices")
+    ("vfilt")
+    ("view")
+    ("visualize")
+    ("voice")
+    ("vwfilt")
+    ("waitall")
+    ("waitfirst")
+    ("watchdog")
+    ("wedge")
+    ("Weierstrass")
+    ("weierstrDiv")
+    ("weierstrPrep")
+    ("weight")
+    ("weightedRing")
+    ("weightKB")
+    ("Weyl")
+    ("WeylClosure")
+    ("WeylClosure1")
+    ("whichvariable")
+    ("writeNmzData")
+    ("writeNmzPaths")
+    ("Writing_procedures_and_libraries")
+    ("WSemigroup")
+    ("wUnit")
+    ("wurzel")
+    ("xchange")
+    ("xdvi")
+    ("XLsolve")
+    ("zdd2poly")
+    ("zerodec")
+    ("zeroMod")
+    ("zeroOpt")
+    ("zeroRadical")
+    ("zeroSet")
+    ("zetaDL")
+    ("ZZsolve")
+))
diff --git a/emacs/hlp-cmpl.el b/emacs/hlp-cmpl.el
new file mode 100644
index 0000000..9dcf273
--- /dev/null
+++ b/emacs/hlp-cmpl.el
@@ -0,0 +1,2869 @@
+; Do not edit this file: It was automatically generated by cmpl.pl
+(setq singular-help-topics-alist
+  '(
+    ("!" . "Special characters.  (line  68")
+    ("!=" . "boolean expressions. (line   6")
+    ("\"" . "Special characters.  (line  77")
+    ("\#" . "Special characters.  (line 122")
+    ("$" . "Special characters.  (line 125")
+    ("%" . "intvec expressions.  (line   6")
+    ("&&" . "boolean operations.  (line   6")
+    ("(" . "Special characters.  (line  14")
+    (")" . "Special characters.  (line  14")
+    ("*" . "intvec expressions.  (line   6")
+    ("**" . "Special characters.  (line  46")
+    ("+" . "intvec expressions.  (line   6")
+    ("++" . "Special characters.  (line  26")
+    ("-" . "intvec expressions.  (line   6")
+    ("-allow-net" . "Command line options")
+    ("-b" . "Command line options")
+    ("-batch" . "Command line options")
+    ("-browser" . "Command line options")
+    ("-c" . "Command line options")
+    ("-d" . "Command line options")
+    ("-e" . "Command line options")
+    ("-echo" . "Command line options")
+    ("-emacs" . "Command line options")
+    ("-emacs-dir" . "Command line options")
+    ("-emacs-load" . "Command line options")
+    ("-execute" . "Command line options")
+    ("-h" . "Command line options")
+    ("-help" . "Command line options")
+    ("-min-time" . "Command line options")
+    ("-MPhost" . "Command line options")
+    ("-MPport" . "Command line options")
+    ("-no-out" . "Command line options")
+    ("-no-rc" . "Command line options")
+    ("-no-stdlib" . "Command line options")
+    ("-no-tty" . "Command line options")
+    ("-no-warn" . "Command line options")
+    ("-q" . "Command line options")
+    ("-quiet" . "Command line options")
+    ("-r" . "Command line options")
+    ("-random" . "Command line options")
+    ("-sdb" . "Command line options")
+    ("-singular" . "Command line options")
+    ("-ticks-per-sec" . "Command line options")
+    ("-u" . "Command line options")
+    ("-user-option" . "Command line options")
+    ("-v" . "Command line options")
+    ("-verbose" . "Command line options")
+    (".." . "Special characters.  (line 104")
+    (".singularrc file" . "Startup sequence.    (line  10")
+    (".singularrc file, no loading" . "Command line options")
+    ("/" . "intvec expressions.  (line   6")
+    ("//" . "Special characters.  (line  86")
+    (":" . "intvec expressions.  (line   6")
+    ("::" . "package.             (line   6")
+    (";" . "Special characters.  (line  95")
+    ("<" . "filecmd.             (line   6")
+    ("<=" . "boolean expressions. (line   6")
+    ("<>" . "boolean expressions. (line   6")
+    ("=" . "Special characters.  (line   8")
+    ("==" . "boolean expressions. (line   6")
+    (">" . "Special characters.  (line  58")
+    (">=" . "boolean expressions. (line   6")
+    ("?" . "help.                (line  19")
+    ("[" . "Special characters.  (line  17")
+    ("\\" . "Special characters.  (line 101")
+    ("]" . "Special characters.  (line  17")
+    ("^" . "ideal operations.    (line   6")
+    ("_" . "Special characters.  (line 116")
+    ("`" . "Special characters.  (line  80")
+    ("a, ordering" . "Extra weight vector. (line   6")
+    ("A_L" . "A_L.                 (line   6")
+    ("A_Z" . "A_Z.                 (line   6")
+    ("absfact.lib" . "absfact_lib.         (line   6")
+    ("absfact_lib" . "absfact_lib.         (line   6")
+    ("absFactorize" . "absFactorize.        (line   6")
+    ("absolute factorization." . "absfact_lib.         (line  31")
+    ("absPrimdecGTZ" . "absPrimdecGTZ.       (line   6")
+    ("abstractR" . "abstractR.           (line   6")
+    ("absValue" . "absValue.            (line   6")
+    ("Access to elements of a user defined type" . "Access to elements of a user defined type")
+    ("actionIsProper" . "actionIsProper.      (line   6")
+    ("addcol" . "addcol.              (line   6")
+    ("addRat" . "addRat.              (line   6")
+    ("addrow" . "addrow.              (line   6")
+    ("ademRelations" . "ademRelations.       (line   6")
+    ("Adj_div" . "Adj_div.             (line   6")
+    ("adjoint" . "adjoint.             (line   6")
+    ("Adjoint ideal" . "paraplanecurves_lib. (line  73")
+    ("adjointIdeal" . "adjointIdeal.        (line   6")
+    ("adjunction divisor" . "Adj_div.             (line  64")
+    ("admissibleSub" . "admissibleSub.       (line   6")
+    ("afaces" . "afaces.              (line   6")
+    ("affine code" . "Fitzgerald-Lax method")
+    ("AG codes" . "AG codes.            (line   6")
+    ("AGcode_L" . "AGcode_L.            (line   6")
+    ("AGcode_Omega" . "AGcode_Omega.        (line   6")
+    ("ainvar.lib" . "ainvar_lib.          (line   6")
+    ("ainvar_lib" . "ainvar_lib.          (line   6")
+    ("aksaka.lib" . "aksaka_lib.          (line   6")
+    ("aksaka_lib" . "aksaka_lib.          (line   6")
+    ("Alexander polynomial" . "alexpoly_lib.        (line  40")
+    ("alexanderpolynomial" . "alexanderpolynomial. (line   6")
+    ("alexpoly.lib" . "alexpoly_lib.        (line   6")
+    ("alexpoly_lib" . "alexpoly_lib.        (line   6")
+    ("alg_kernel" . "alg_kernel.          (line   6")
+    ("algDependent" . "algDependent.        (line   6")
+    ("algebra.lib" . "algebra_lib.         (line   6")
+    ("algebra_containment" . "algebra_containment. (line   6")
+    ("algebra_lib" . "algebra_lib.         (line   6")
+    ("Algebraic dependence" . "Algebraic dependence")
+    ("algebraic dependence" . "perron_lib.          (line  21")
+    ("algebraic field extension" . "splitring.           (line  32")
+    ("Algebraic geometry" . "Algebraic geometry.  (line   6")
+    ("Algebraic Geometry codes" . "brnoeth_lib.         (line  43")
+    ("algebraicDependence" . "algebraicDependence. (line   6")
+    ("algorithm of Bigatti, La Scala and Robbiano" . "Bigatti and La Scala and Robbiano")
+    ("algorithm of Conti and Traverso" . "Conti and Traverso.  (line   6")
+    ("algorithm of Di Biase and Urbanke" . "Di Biase and Urbanke")
+    ("algorithm of Hosten and Sturmfels" . "Hosten and Sturmfels")
+    ("algorithm of Pottier" . "Pottier.             (line   6")
+    ("all.lib" . "all_lib.             (line   6")
+    ("all_lib" . "all_lib.             (line   6")
+    ("allDoubleExt" . "allDoubleExt.        (line   6")
+    ("allExtOfLeft" . "allExtOfLeft.        (line   6")
+    ("allExtOfRight" . "allExtOfRight.       (line   6")
+    ("allowing net access" . "Command line options")
+    ("allPositive" . "allPositive.         (line   6")
+    ("allprint" . "allprint.            (line   6")
+    ("allreal" . "allreal.             (line   6")
+    ("allrealst" . "allrealst.           (line   6")
+    ("allsquarefree" . "allsquarefree.       (line   6")
+    ("AltVarEnd" . "AltVarEnd.           (line   6")
+    ("AltVarStart" . "AltVarStart.         (line   6")
+    ("ambientDimension" . "ambientDimension.    (line   6")
+    ("and" . "Evaluation of logical expressions")
+    ("Ann" . "Ann.                 (line   6")
+    ("annfs" . "annfs.               (line   6")
+    ("annfs0" . "annfs0.              (line   6")
+    ("annfs2" . "annfs2.              (line   6")
+    ("annfsBMI" . "annfsBMI.            (line   6")
+    ("annfsParamBM" . "annfsParamBM.        (line   6")
+    ("annfspecial" . "annfspecial.         (line   6")
+    ("annfsRB" . "annfsRB.             (line   6")
+    ("annihilator of polynomial" . "dmodapp_lib.         (line 104")
+    ("annihilator of rational function" . "dmodloc_lib.         (line  93")
+    ("annil" . "annil.               (line   6")
+    ("annPoly" . "annPoly.             (line   6")
+    ("annRat" . "annRat.              (line   6")
+    ("annRatSyz" . "annRatSyz.           (line   6")
+    ("Appel function" . "dmodapp_lib.         (line 104")
+    ("Appel hypergeometric function" . "dmodapp_lib.         (line 104")
+    ("appelF1" . "appelF1.             (line   6")
+    ("appelF2" . "appelF2.             (line   6")
+    ("appelF4" . "appelF4.             (line   6")
+    ("appendWeight2Ord" . "appendWeight2Ord.    (line   6")
+    ("Applications" . "Applications.        (line   6")
+    ("applyAdF" . "applyAdF.            (line   6")
+    ("arcpoint.lib" . "arcpoint_lib.        (line   6")
+    ("arcpoint_lib" . "arcpoint_lib.        (line   6")
+    ("areZeroElements" . "areZeroElements.     (line   6")
+    ("argument, default" . "Parameter list.      (line   6")
+    ("argument, optional" . "Parameter list.      (line   6")
+    ("ArnoldAction" . "ArnoldAction.        (line   6")
+    ("arrange" . "arrange.             (line   6")
+    ("ASCII" . "ASCII.               (line   6")
+    ("ASCII links" . "ASCII links.         (line   6")
+    ("ask" . "ask.                 (line   6")
+    ("assignment,custom" . "Assignments for user defined types")
+    ("Assignments for user defined types" . "Assignments for user defined types")
+    ("assPrimes" . "assPrimes.           (line   6")
+    ("assprimeszerodim.lib" . "assprimeszerodim_lib")
+    ("assprimeszerodim_lib" . "assprimeszerodim_lib")
+    ("Atkin" . "Atkin.               (line   6")
+    ("atkins.lib" . "atkins_lib.          (line   6")
+    ("atkins_lib" . "atkins_lib.          (line   6")
+    ("attrib" . "attrib.              (line   6")
+    ("Authors" . "Preface.             (line 144")
+    ("autonom" . "autonom.             (line   6")
+    ("autonomDim" . "autonomDim.          (line   6")
+    ("awalk1" . "awalk1.              (line   6")
+    ("awalk2" . "awalk2.              (line   6")
+    ("b-function" . "bfun_lib.            (line  68")
+    ("babyGiant" . "babyGiant.           (line   6")
+    ("Background" . "Background.          (line   6")
+    ("backward" . "backward.            (line   6")
+    ("bareiss" . "bareiss.             (line   6")
+    ("base2str" . "base2str.            (line   6")
+    ("basering" . "def.                 (line   6")
+    ("Basic programming" . "Basic programming.   (line   6")
+    ("basicinvariants" . "basicinvariants.     (line   6")
+    ("belongSemigroup" . "belongSemigroup.     (line   6")
+    ("bernstein" . "bernstein.           (line   6")
+    ("Bernstein operator" . "dmod_lib.            (line 109")
+    ("Bernstein-Sato polynomial" . "bernstein.           (line  22")
+    ("Bernstein-Sato polynomial for variety" . "dmodvar_lib.         (line  59")
+    ("bernsteinBM" . "bernsteinBM.         (line   6")
+    ("bernsteinLift" . "bernsteinLift.       (line   6")
+    ("bertini2Singular" . "bertini2Singular.    (line   6")
+    ("betti" . "betti.               (line   6")
+    ("betti (plural)" . "betti (plural).      (line   6")
+    ("Betti number" . "Syzygies and resolutions")
+    ("bFactor" . "bFactor.             (line   6")
+    ("bfct" . "bfct.                (line   6")
+    ("bfctAnn" . "bfctAnn.             (line   6")
+    ("bfctBound" . "bfctBound.           (line   6")
+    ("bfctIdeal" . "bfctIdeal.           (line   6")
+    ("bfctOneGB" . "bfctOneGB.           (line   6")
+    ("bfctSyz" . "bfctSyz.             (line   6")
+    ("bfctVarAnn" . "bfctVarAnn.          (line   6")
+    ("bfctVarIn" . "bfctVarIn.           (line   6")
+    ("bfun.lib" . "bfun_lib.            (line   6")
+    ("bfun_lib" . "bfun_lib.            (line   6")
+    ("Bigatti-La Scala-Robbiano algorithm" . "Bigatti and La Scala and Robbiano")
+    ("bigint" . "bigint.              (line   6")
+    ("bigint declarations" . "bigint declarations. (line   6")
+    ("bigint expressions" . "bigint expressions.  (line   6")
+    ("bigint operations" . "bigint operations.   (line   6")
+    ("bigint related functions" . "bigint related functions")
+    ("bigintmat" . "bigintmat.           (line   6")
+    ("bigintmat declarations" . "bigintmat declarations")
+    ("bigintmat expressions" . "bigintmat expressions")
+    ("bigintmat operations" . "bigintmat operations")
+    ("bigintmat type cast" . "bigintmat type cast. (line   6")
+    ("binomial" . "binomial.            (line   6")
+    ("binomials2intmat" . "binomials2intmat.    (line   6")
+    ("BINresol" . "BINresol.            (line   6")
+    ("birational map, image, inverse." . "invertBirMap.        (line  33")
+    ("blackbox" . "countedref.          (line   6")
+    ("block" . "Control structures.  (line   6")
+    ("BlowingUp" . "BlowingUp.           (line   6")
+    ("blowUp" . "blowUp.              (line   6")
+    ("blowup0" . "blowup0.             (line   6")
+    ("blowUp2" . "blowUp2.             (line   6")
+    ("blowUpBO" . "blowUpBO.            (line   6")
+    ("Blowupcenter" . "Blowupcenter.        (line   6")
+    ("boolean expressions" . "boolean expressions. (line   6")
+    ("boolean operations" . "boolean operations.  (line   6")
+    ("boolean_constant" . "boolean_constant.    (line   6")
+    ("boolean_ideal" . "boolean_ideal.       (line   6")
+    ("boolean_poly" . "boolean_poly.        (line   6")
+    ("boolean_poly_ring" . "boolean_poly_ring.   (line   6")
+    ("boolean_set" . "boolean_set.         (line   6")
+    ("boolean_std" . "boolean_std.         (line   6")
+    ("BorelCheck" . "BorelCheck.          (line   6")
+    ("boundaryLatticePoints" . "boundaryLatticePoints")
+    ("boundBuFou" . "boundBuFou.          (line   6")
+    ("boundDes" . "boundDes.            (line   6")
+    ("boundposDes" . "boundposDes.         (line   6")
+    ("bracket" . "bracket.             (line   6")
+    ("Branches of space curve singularities" . "Branches of space curve singularities")
+    ("break" . "break.               (line   6")
+    ("break point" . "~.                   (line   6")
+    ("breakpoint" . "breakpoint.          (line   6")
+    ("Briancon-Maisonobe algorithm" . "dmod_lib.            (line 109")
+    ("Brieskorn lattice" . "mondromy_lib.        (line  34")
+    ("Brill-Noether algorithm" . "brnoeth_lib.         (line  43")
+    ("BrillNoether" . "BrillNoether.        (line   6")
+    ("brnoeth.lib" . "brnoeth_lib.         (line   6")
+    ("brnoeth_lib" . "brnoeth_lib.         (line   6")
+    ("browser, command line option" . "Command line options")
+    ("browser, setting the" . "system.              (line  88")
+    ("browsers" . "The online help system")
+    ("browsers, setting the" . "system.              (line  88")
+    ("bubblesort" . "bubblesort.          (line   6")
+    ("Buchberger algorithm for toric ideals" . "Buchberger algorithm")
+    ("Budur-Mustata-Saito approach" . "dmodvar_lib.         (line  59")
+    ("bug, ESingular" . "Unix installation instructions")
+    ("busadj" . "busadj.              (line   6")
+    ("bvar" . "bvar.                (line   6")
+    ("C programming language" . "Major differences to the C programming language")
+    ("c, module ordering" . "Module orderings.    (line  49")
+    ("C, module ordering" . "Module orderings.    (line  19")
+    ("calculateI" . "calculateI.          (line   6")
+    ("cancelunit, option" . "option.              (line 134")
+    ("canonicalizeCone" . "canonicalizeCone.    (line   6")
+    ("canonize" . "canonize.            (line   6")
+    ("canonMap" . "canonMap.            (line   6")
+    ("cantoradd" . "cantoradd.           (line   6")
+    ("cantormult" . "cantormult.          (line   6")
+    ("cantorred" . "cantorred.           (line   6")
+    ("cardGroup" . "cardGroup.           (line   6")
+    ("case" . "No case or switch statement")
+    ("Castelnuovo-Mumford regularity" . "CM_regularity.       (line  21")
+    ("Category string" . "Category string.     (line   6")
+    ("cdd" . "Preface.             (line   6")
+    ("cddlib" . "Preface.             (line   6")
+    ("CenCharDec" . "CenCharDec.          (line   6")
+    ("Center" . "Center.              (line   6")
+    ("center" . "center.              (line   6")
+    ("CenterBO" . "CenterBO.            (line   6")
+    ("centerRed" . "centerRed.           (line   6")
+    ("centerVS" . "centerVS.            (line   6")
+    ("central.lib" . "central_lib.         (line   6")
+    ("central1st" . "central1st.          (line   6")
+    ("central2nd" . "central2nd.          (line   6")
+    ("central_lib" . "central_lib.         (line   6")
+    ("centralize" . "central_lib.         (line  19")
+    ("centralizer" . "centralizer.         (line   6")
+    ("centralizerRed" . "centralizerRed.      (line   6")
+    ("centralizerVS" . "centralizerVS.       (line   6")
+    ("centralizeSet" . "centralizeSet.       (line   6")
+    ("CentralQuot" . "CentralQuot.         (line   6")
+    ("CentralSaturation" . "CentralSaturation.   (line   6")
+    ("cgs" . "cgs.                 (line   6")
+    ("CGS, disjoint, reduced, Comprehensive Groebner System" . "cgsdr")
+    ("cgsdr" . "cgsdr.               (line   6")
+    ("chaincrit" . "chaincrit.           (line   6")
+    ("Change of rings" . "Change of rings.     (line   6")
+    ("changechar" . "changechar.          (line   6")
+    ("changeDenominator" . "changeDenominator.   (line   6")
+    ("changeord" . "changeord.           (line   6")
+    ("changes" . "News and changes.    (line   6")
+    ("changevar" . "changevar.           (line   6")
+    ("char" . "char.                (line   6")
+    ("char_series" . "char_series.         (line   6")
+    ("characteristic exponents" . "invariants.          (line  47")
+    ("Characteristic sets" . "Characteristic sets. (line   6")
+    ("characteristic variety" . "dmodloc_lib.         (line  93")
+    ("CharacteristicExponents" . "CharacteristicExponents")
+    ("charexp2conductor" . "charexp2conductor.   (line   6")
+    ("charexp2generators" . "charexp2generators.  (line   6")
+    ("charexp2inter" . "charexp2inter.       (line   6")
+    ("charexp2multseq" . "charexp2multseq.     (line   6")
+    ("charexp2poly" . "charexp2poly.        (line   6")
+    ("charInfo" . "charInfo.            (line   6")
+    ("charpoly" . "charpoly.            (line   6")
+    ("charstr" . "charstr.             (line   6")
+    ("charVariety" . "charVariety.         (line   6")
+    ("checkFactor" . "checkFactor.         (line   6")
+    ("checkRoot" . "checkRoot.           (line   6")
+    ("Chevalley-Rosenlicht theorem" . "tangentGens.         (line  34")
+    ("chineseRem" . "chineseRem.          (line   6")
+    ("chinrem" . "chinrem.             (line   6")
+    ("chinrestp" . "chinrestp.           (line   6")
+    ("cisimplicial.lib" . "cisimplicial_lib.    (line   6")
+    ("cisimplicial_lib" . "cisimplicial_lib.    (line   6")
+    ("Classification of hypersurface singularities" . "Classification of hypersurface singularities")
+    ("Classification of singularities" . "realclassify.        (line  38")
+    ("classify" . "classify.            (line   6")
+    ("classify.lib" . "classify_lib.        (line   6")
+    ("classify_lib" . "classify_lib.        (line   6")
+    ("classifyCeq" . "classifyCeq.         (line   6")
+    ("classifyceq.lib" . "classifyceq_lib.     (line   6")
+    ("classifyceq_lib" . "classifyceq_lib.     (line   6")
+    ("cleanTmp" . "cleanTmp.            (line   6")
+    ("cleanunit" . "cleanunit.           (line   6")
+    ("cleardenom" . "cleardenom.          (line   6")
+    ("close" . "close.               (line   6")
+    ("closed_points" . "closed_points.       (line   6")
+    ("closetex" . "closetex.            (line   6")
+    ("closureFrac" . "closureFrac.         (line   6")
+    ("CM_regularity" . "CM_regularity.       (line   6")
+    ("CMtype" . "CMtype.              (line   6")
+    ("Code" . "Codes and the decoding problem")
+    ("Codes and the decoding problem" . "Codes and the decoding problem")
+    ("codim" . "codim.               (line   6")
+    ("codimension" . "codimension.         (line   6")
+    ("Coding theory" . "Coding theory.       (line   6")
+    ("coding theory" . "AG codes.            (line   6")
+    ("coef" . "coef.                (line   6")
+    ("coefficient field" . "number.              (line   6")
+    ("coefficient rings, ring of integers, zero divisors, p-adic numbers" . "Coefficient rings")
+    ("coefficients, long" . "Long coefficients.   (line   6")
+    ("coeffmod" . "coeffmod.            (line   6")
+    ("coeffs" . "coeffs.              (line   6")
+    ("coHom" . "coHom.               (line   6")
+    ("collectDiv" . "collectDiv.          (line   6")
+    ("colrank" . "colrank.             (line   6")
+    ("colred" . "colred.              (line   6")
+    ("comma" . "Usage of commas.     (line   6")
+    ("Command line options" . "Command line options")
+    ("command,custom" . "Commands for user defined types")
+    ("command-line option, setting value of" . "system.              (line  88")
+    ("command-line option, value of" . "system.              (line  83")
+    ("command-line options, print all values of" . "system.          (line  80")
+    ("command-line options, short help" . "Command line options")
+    ("Commands" . "Functions and system variables")
+    ("commands (plural)" . "Functions (plural).  (line   6")
+    ("Commands for user defined types" . "Commands for user defined types")
+    ("comment" . "Special characters.  (line  86")
+    ("commRing" . "commRing.            (line   6")
+    ("Commutative Algebra" . "Commutative Algebra. (line   6")
+    ("completeReduction" . "completeReduction.   (line   6")
+    ("complex" . "Rings and orderings. (line  26")
+    ("complexSingType" . "complexSingType.     (line   6")
+    ("ComplexValue" . "ComplexValue.        (line   6")
+    ("compregb.lib" . "compregb_lib.        (line   6")
+    ("compregb_lib" . "compregb_lib.        (line   6")
+    ("comprehensive Groebner system" . "compregb_lib.        (line  27")
+    ("compress" . "compress.            (line   6")
+    ("computemcm" . "computemcm.          (line   6")
+    ("Computing Groebner and Standard Bases" . "Computing Groebner and Standard Bases")
+    ("concat" . "concat.              (line   6")
+    ("conductor" . "charexp2conductor.   (line  18")
+    ("conductor, degree" . "invariants.          (line  47")
+    ("cone" . "cone.                (line   6")
+    ("cone related functions" . "cone related functions")
+    ("coneLink" . "coneLink.            (line   6")
+    ("coneViaInequalities" . "coneViaInequalities. (line   6")
+    ("coneViaPoints" . "coneViaPoints.       (line   6")
+    ("conic, parametrization, rational point." . "paraConic.         (line  31")
+    ("conicWithTangents" . "conicWithTangents.   (line   6")
+    ("constructblwup" . "constructblwup.      (line   6")
+    ("constructH" . "constructH.          (line   6")
+    ("constructlastblwup" . "constructlastblwup.  (line   6")
+    ("contact matrix" . "charexp2inter.       (line  19")
+    ("ContactMatrix" . "ContactMatrix.       (line   6")
+    ("containedQ" . "containedQ.          (line   6")
+    ("containsAsFace" . "containsAsFace.      (line   6")
+    ("containsInCollection" . "containsInCollection")
+    ("containsInSupport" . "containsInSupport.   (line   6")
+    ("containsPositiveVector" . "containsPositiveVector")
+    ("containsRelatively" . "containsRelatively.  (line   6")
+    ("content" . "content.             (line   6")
+    ("contentSB, option" . "option.              (line 138")
+    ("Conti-Traverso algorithm" . "Conti and Traverso.  (line   6")
+    ("continue" . "Behavior of continue")
+    ("contract" . "contract.            (line   6")
+    ("contraHom" . "contraHom.           (line   6")
+    ("contributors" . "system.              (line  56")
+    ("Contributors" . "Preface.             (line 144")
+    ("control" . "control.             (line   6")
+    ("Control structures" . "Control structures.  (line   6")
+    ("Control theory" . "System and Control Theory")
+    ("control.lib" . "control_lib.         (line   6")
+    ("control_lib" . "control_lib.         (line   6")
+    ("control_Matrix" . "control_Matrix.      (line   6")
+    ("controlDim" . "controlDim.          (line   6")
+    ("controlExample" . "controlExample.      (line   6")
+    ("convertdata" . "convertdata.         (line   6")
+    ("convex geometry" . "convex geometry.     (line   6")
+    ("convexHull" . "convexHull.          (line   6")
+    ("convexIntersection" . "convexIntersection.  (line   6")
+    ("convloc" . "convloc.             (line   6")
+    ("Cooper philosophy" . "Cooper philosophy.   (line   6")
+    ("coordinates" . "coords.              (line  19")
+    ("coords" . "coords.              (line   6")
+    ("copyright" . "Preface.             (line   6")
+    ("corank" . "corank.              (line   6")
+    ("Cornacchia" . "Cornacchia.          (line   6")
+    ("CornacchiaModified" . "CornacchiaModified.  (line   6")
+    ("cornerMonomials" . "cornerMonomials.     (line   6")
+    ("countPoints" . "countPoints.         (line   6")
+    ("cpu" . "system.              (line  33")
+    ("createBO" . "createBO.            (line   6")
+    ("createGradedRingHomomorphism" . "createGradedRingHomomorphism")
+    ("createGroup" . "createGroup.         (line   6")
+    ("createlist" . "createlist.          (line   6")
+    ("createQuotientGroup" . "createQuotientGroup. (line   6")
+    ("createTorsionFreeGroup" . "createTorsionFreeGroup")
+    ("CRHT-ideal" . "Cooper philosophy.   (line  25")
+    ("Critical points" . "Critical points.     (line   6")
+    ("crypto.lib" . "crypto_lib.          (line   6")
+    ("crypto_lib" . "crypto_lib.          (line   6")
+    ("cup" . "cup.                 (line   6")
+    ("cupproduct" . "cupproduct.          (line   6")
+    ("curve singularities" . "hnoether_lib.        (line  49")
+    ("curvepar.lib" . "curvepar_lib.        (line   6")
+    ("curvepar_lib" . "curvepar_lib.        (line   6")
+    ("CurveParam" . "CurveParam.          (line   6")
+    ("CurveRes" . "CurveRes.            (line   6")
+    ("Curves" . "paraplanecurves_lib. (line  73")
+    ("custom assignment" . "Assignments for user defined types")
+    ("custom command" . "Commands for user defined types")
+    ("custom type" . "Definition of a user defined type")
+    ("Customization of the Emacs interface" . "Customization of the Emacs interface")
+    ("cycleLength" . "cycleLength.         (line   6")
+    ("cyclePoints" . "cyclePoints.         (line   6")
+    ("cyclic" . "cyclic.              (line   6")
+    ("Cyclic code" . "decodegb_lib.        (line  50")
+    ("cyclic code" . "Codes and the decoding problem")
+    ("Cyclic roots" . "Cyclic roots.        (line   6")
+    ("cyclotomic" . "cyclotomic.          (line   6")
+    ("D-integration" . "dmodapp_lib.         (line 104")
+    ("D-localization" . "dmodloc_lib.         (line  93")
+    ("D-module" . "dmodloc_lib.         (line  93")
+    ("D-module structure" . "dmodvar_lib.         (line  59")
+    ("D-restriction" . "dmodapp_lib.         (line 104")
+    ("Data types" . "Data types.          (line   6")
+    ("Data types (plural)" . "Data types (plural). (line   6")
+    ("datetime" . "datetime.            (line   6")
+    ("DBM links" . "DBM links.           (line   6")
+    ("dbprint" . "dbprint.             (line   6")
+    ("debug_log" . "debug_log.           (line   6")
+    ("debugger" . "Source code debugger")
+    ("debugging library code" . "Source code debugger")
+    ("Debugging tools" . "Debugging tools.     (line   6")
+    ("debugLib, option" . "option.              (line 169")
+    ("dec1var" . "dec1var.             (line   6")
+    ("decimal" . "decimal.             (line   6")
+    ("Decker, Wolfram" . "Preface.             (line 144")
+    ("Declaration of objects of a user defined type" . "Declaration of objects of a user defined type")
+    ("decode" . "decode.              (line   6")
+    ("decodeCode" . "decodeCode.          (line   6")
+    ("decodegb.lib" . "decodegb_lib.        (line   6")
+    ("decodegb_lib" . "decodegb_lib.        (line   6")
+    ("decodeRandom" . "decodeRandom.        (line   6")
+    ("decodeRandomFL" . "decodeRandomFL.      (line   6")
+    ("decodeSV" . "decodeSV.            (line   6")
+    ("Decoding" . "decodegb_lib.        (line  50")
+    ("Decoding codes with Groebner bases" . "Decoding codes with Groebner bases")
+    ("Decoding method based on quadratic equations" . "Decoding method based on quadratic equations")
+    ("decoding, decoding problem" . "Codes and the decoding problem")
+    ("decoef" . "decoef.              (line   6")
+    ("def" . "def.                 (line   6")
+    ("def declarations" . "def declarations.    (line   6")
+    ("default argument" . "Parameter list.      (line   6")
+    ("defined" . "defined.             (line   6")
+    ("defineHomogeneous" . "defineHomogeneous.   (line   6")
+    ("Definition of a user defined type" . "Definition of a user defined type")
+    ("defl" . "defl.                (line   6")
+    ("deform" . "deform.              (line   6")
+    ("deform.lib" . "deform_lib.          (line   6")
+    ("deform_lib" . "deform_lib.          (line   6")
+    ("Deformations" . "Deformations.        (line   6")
+    ("Deformations, T1 and T2" . "T1 and T2.           (line   6")
+    ("defRes, option" . "option.              (line 172")
+    ("defring" . "defring.             (line   6")
+    ("defringp" . "defringp.            (line   6")
+    ("defrings" . "defrings.            (line   6")
+    ("deg" . "deg.                 (line   6")
+    ("degBound" . "degBound.            (line   6")
+    ("Degree" . "Degree.              (line   6")
+    ("degree" . "Miscellaneous oddities")
+    ("degree lexicographical ordering" . "Global orderings.    (line  28")
+    ("degree of a polynomial" . "Miscellaneous oddities")
+    ("degree reverse lexicographical ordering" . "Global orderings.  (line  19")
+    ("degreeDivisor" . "degreeDivisor.       (line   6")
+    ("degreeFormalDivisor" . "degreeFormalDivisor. (line   6")
+    ("degreepart" . "degreepart.          (line   6")
+    ("delete" . "delete.              (line   6")
+    ("deleteGenerator" . "deleteGenerator.     (line   6")
+    ("deleteSublist" . "deleteSublist.       (line   6")
+    ("delta" . "delta.               (line   6")
+    ("Delta" . "Delta.               (line   6")
+    ("delta invariant" . "delta.               (line  25")
+    ("delta invariant." . "normalC.             (line  99")
+    ("DeltaList" . "DeltaList.           (line   6")
+    ("deltaLoc" . "deltaLoc.            (line   6")
+    ("Demo mode" . "Demo mode.           (line   6")
+    ("denominator" . "denominator.         (line   6")
+    ("depth" . "depth.               (line   6")
+    ("Depth" . "Depth.               (line   6")
+    ("depthIdeal" . "depthIdeal.          (line   6")
+    ("derham.lib" . "derham_lib.          (line   9")
+    ("derham_lib" . "derham_lib.          (line   9")
+    ("deRhamCohom" . "deRhamCohom.         (line   6")
+    ("deRhamCohomIdeal" . "deRhamCohomIdeal.    (line   6")
+    ("deRhamCohomology" . "deRhamCohomology.    (line   6")
+    ("derivate" . "derivate.            (line   6")
+    ("det" . "det.                 (line   6")
+    ("det_B" . "det_B.               (line   6")
+    ("detadj" . "detadj.              (line   6")
+    ("Determinacy" . "determinacy.         (line  21")
+    ("determinacy" . "determinacy.         (line   6")
+    ("determinecenter" . "determinecenter.     (line   6")
+    ("detropicalise" . "detropicalise.       (line   6")
+    ("develop" . "develop.             (line   6")
+    ("Di Biase-Urbanke algorithm" . "Di Biase and Urbanke")
+    ("diag" . "diag.                (line   6")
+    ("diag_test" . "diag_test.           (line   6")
+    ("diagInvariants" . "diagInvariants.      (line   6")
+    ("diff" . "diff.                (line   6")
+    ("diffRat" . "diffRat.             (line   6")
+    ("difpoly2tex" . "difpoly2tex.         (line   6")
+    ("dim" . "dim.                 (line   6")
+    ("dim (plural)" . "dim (plural).        (line   6")
+    ("dim_slocus" . "dim_slocus.          (line   6")
+    ("dimension" . "dimension.           (line   6")
+    ("dimGradedPart" . "dimGradedPart.       (line   6")
+    ("dimH" . "dimH.                (line   6")
+    ("dimMon" . "dimMon.              (line   6")
+    ("direct_boolean_poly" . "direct_boolean_poly. (line   6")
+    ("direct_from_boolean_poly" . "direct_from_boolean_poly")
+    ("disc" . "disc.                (line   6")
+    ("discr" . "discr.               (line   6")
+    ("discrepancy" . "discrepancy.         (line   6")
+    ("disp_zdd" . "disp_zdd.            (line   6")
+    ("DISPLAY environment variable" . "The online help system")
+    ("displayCohom" . "displayCohom.        (line   6")
+    ("displayHNE" . "displayHNE.          (line   6")
+    ("displayInvariants" . "displayInvariants.   (line   6")
+    ("displayMultsequence" . "displayMultsequence. (line   6")
+    ("displayPuiseuxExpansion" . "displayPuiseuxExpansion")
+    ("displayTropicalLifting" . "displayTropicalLifting")
+    ("Distributed computing" . "parallelWaitAll.     (line  23")
+    ("div" . "Miscellaneous oddities")
+    ("dividelist" . "dividelist.          (line   6")
+    ("divideUnits" . "divideUnits.         (line   6")
+    ("division" . "division.            (line   6")
+    ("division (plural)" . "division (plural).   (line   6")
+    ("division, pdivi, reduce" . "pnormalf.            (line  24")
+    ("division, reduce" . "pdivi.               (line  23")
+    ("divisor" . "divisor.             (line   6")
+    ("divisorplus" . "divisorplus.         (line   6")
+    ("divisors" . "degreeFormalDivisor. (line  19")
+    ("divisors, polyhedra" . "pdivisorplus.        (line  20")
+    ("divisors.lib" . "divisors_lib.        (line   6")
+    ("divisors_lib" . "divisors_lib.        (line   6")
+    ("DLoc" . "DLoc.                (line   6")
+    ("DLoc0" . "DLoc0.               (line   6")
+    ("Dlocalization" . "Dlocalization.       (line   6")
+    ("dmod.lib" . "dmod_lib.            (line   6")
+    ("dmod_lib" . "dmod_lib.            (line   6")
+    ("dmodAction" . "dmodAction.          (line   6")
+    ("dmodActionRat" . "dmodActionRat.       (line   6")
+    ("dmodapp.lib" . "dmodapp_lib.         (line   6")
+    ("dmodapp_lib" . "dmodapp_lib.         (line   6")
+    ("dmodGeneralAssumptionCheck" . "dmodGeneralAssumptionCheck")
+    ("dmodloc.lib" . "dmodloc_lib.         (line   6")
+    ("dmodloc_lib" . "dmodloc_lib.         (line   6")
+    ("dmodoublext" . "dmodoublext.         (line   6")
+    ("dmodvar.lib" . "dmodvar_lib.         (line   6")
+    ("dmodvar_lib" . "dmodvar_lib.         (line   6")
+    ("Documentation Tool" . "Documentation Tool.  (line   6")
+    ("double" . "double.              (line   6")
+    ("doubleExt" . "doubleExt.           (line   6")
+    ("downloading" . "Download instructions")
+    ("Dp, global ordering" . "Global orderings.    (line  28")
+    ("dp, global ordering" . "Global orderings.    (line  19")
+    ("drawNewtonSubdivision" . "drawNewtonSubdivision")
+    ("drawTropicalCurve" . "drawTropicalCurve.   (line   6")
+    ("Ds, local ordering" . "Local orderings.     (line  25")
+    ("ds, local ordering" . "Local orderings.     (line  16")
+    ("DsingularLocus" . "DsingularLocus.      (line   6")
+    ("dsum" . "dsum.                (line   6")
+    ("dual_code" . "dual_code.           (line   6")
+    ("dualCone" . "dualCone.            (line   6")
+    ("dualConic" . "dualConic.           (line   6")
+    ("dualPolytope" . "dualPolytope.        (line   6")
+    ("dump" . "dump.                (line   6")
+    ("Dynamic loading" . "Dynamic loading.     (line   6")
+    ("Dynamic modules" . "Dynamic modules.     (line   6")
+    ("ecart" . "ecart.               (line   6")
+    ("echo" . "echo.                (line   6")
+    ("ECoef" . "ECoef.               (line   6")
+    ("ECPP" . "ECPP.                (line   6")
+    ("Edatalist" . "Edatalist.           (line   6")
+    ("Editing input" . "Editing input.       (line   6")
+    ("Editing SINGULAR input files with Emacs" . "Editing SINGULAR input files with Emacs")
+    ("eexgcdN" . "eexgcdN.             (line   6")
+    ("effective" . "effective.           (line   6")
+    ("egcdMain" . "egcdMain.            (line   6")
+    ("ehrhartPolynomialCoeff" . "ehrhartPolynomialCoeff")
+    ("ehrhartRing" . "ehrhartRing.         (line   6")
+    ("eigenvals" . "eigenvals.           (line   6")
+    ("eigenvalues" . "eigenvalues.         (line   6")
+    ("elemSymmId" . "elemSymmId.          (line   6")
+    ("elim" . "elim.                (line   6")
+    ("elim.lib" . "elim_lib.            (line   6")
+    ("elim1" . "elim1.               (line   6")
+    ("elim2" . "elim2.               (line   6")
+    ("elim_lib" . "elim_lib.            (line   6")
+    ("eliminate" . "eliminate.           (line   6")
+    ("eliminate (plural)" . "eliminate (plural).  (line   6")
+    ("eliminateNC" . "eliminateNC.         (line   6")
+    ("Elimination" . "Elimination.         (line   6")
+    ("elimination" . "ncpreim_lib.         (line  62")
+    ("elimlinearpart" . "elimlinearpart.      (line   6")
+    ("elimpart" . "elimpart.            (line   6")
+    ("elimpartanyr" . "elimpartanyr.        (line   6")
+    ("elimrep" . "elimrep.             (line   6")
+    ("elimRing" . "elimRing.            (line   6")
+    ("elimWeight" . "elimWeight.          (line   6")
+    ("ellipticAdd" . "ellipticAdd.         (line   6")
+    ("ellipticAllPoints" . "ellipticAllPoints.   (line   6")
+    ("ellipticMult" . "ellipticMult.        (line   6")
+    ("ellipticNF" . "ellipticNF.          (line   6")
+    ("ellipticNFDB" . "ellipticNFDB.        (line   6")
+    ("ellipticRandomCurve" . "ellipticRandomCurve. (line   6")
+    ("ellipticRandomPoint" . "ellipticRandomPoint. (line   6")
+    ("else" . "if.                  (line   6")
+    ("Emacs" . "Emacs user interface")
+    ("Emacs, a quick guide" . "A quick guide to Emacs")
+    ("Emacs, customization of Singular mode" . "Customization of the Emacs interface")
+    ("Emacs, editing Singular input files" . "Editing SINGULAR input files with Emacs")
+    ("Emacs, important commands" . "Top 20 Emacs commands")
+    ("Emacs, overview" . "A quick guide to Emacs")
+    ("Emacs, running Singular under" . "Running SINGULAR under Emacs")
+    ("Emacs, Singular demo mode" . "Demo mode.           (line   6")
+    ("Emacs, user interface" . "Emacs user interface")
+    ("Emaxcont" . "Emaxcont.            (line   6")
+    ("embedMat" . "embedMat.            (line   6")
+    ("emptyFan" . "emptyFan.            (line   6")
+    ("encode" . "encode.              (line   6")
+    ("endomorphism filtration" . "endvfilt.            (line  25")
+    ("endvfilt" . "endvfilt.            (line   6")
+    ("engine" . "engine.              (line   6")
+    ("envelope" . "envelope.            (line   6")
+    ("environment variable, DISPLAY" . "The online help system")
+    ("EOrdlist" . "EOrdlist.            (line   6")
+    ("Equal" . "Equal.               (line   6")
+    ("equalJinI" . "equalJinI.           (line   6")
+    ("equalMultiDeg" . "equalMultiDeg.       (line   6")
+    ("equations" . "equations.           (line   6")
+    ("equidim" . "equidim.             (line   6")
+    ("equidimMax" . "equidimMax.          (line   6")
+    ("equidimMaxEHV" . "equidimMaxEHV.       (line   6")
+    ("equidimZ" . "equidimZ.            (line   6")
+    ("equiRadical" . "equiRadical.         (line   6")
+    ("equising.lib" . "equising_lib.        (line   6")
+    ("equising_lib" . "equising_lib.        (line   6")
+    ("equisingular Tjurina number" . "alexpoly_lib.        (line  40")
+    ("equisingularity ideal" . "esIdeal.             (line  33")
+    ("equisingularity stratum" . "esStratum.           (line  43")
+    ("Eresol" . "Eresol.              (line   6")
+    ("ERROR" . "ERROR.               (line   6")
+    ("error recovery" . "The SINGULAR prompt. (line   6")
+    ("errorInsert" . "errorInsert.         (line   6")
+    ("errormap" . "errormap.            (line   6")
+    ("errorRand" . "errorRand.           (line   6")
+    ("esIdeal" . "esIdeal.             (line   6")
+    ("ESingular, no prompt" . "Unix installation instructions")
+    ("esStratum" . "esStratum.           (line   6")
+    ("eta" . "eta.                 (line   6")
+    ("euler" . "euler.               (line   6")
+    ("eval" . "eval.                (line   6")
+    ("evaluate_reynolds" . "evaluate_reynolds.   (line   6")
+    ("evaluateFormalDivisor" . "evaluateFormalDivisor")
+    ("evaluatePDivisor" . "evaluatePDivisor.    (line   6")
+    ("Evaluation of logical expressions" . "Evaluation of logical expressions")
+    ("example" . "example.             (line   6")
+    ("Examples" . "Examples.            (line   6")
+    ("Examples of ring declarations" . "Examples of ring declarations")
+    ("execute" . "execute.             (line   6")
+    ("exgcdN" . "exgcdN.              (line   6")
+    ("exit" . "quit.                (line   6")
+    ("Exp for matrices" . "matrixExp.           (line  22")
+    ("exp2pt" . "exp2pt.              (line   6")
+    ("Experimental libraries" . "Experimental libraries")
+    ("expo" . "expo.                (line   6")
+    ("export" . "export.              (line   6")
+    ("exportNuminvs" . "exportNuminvs.       (line   6")
+    ("exportto" . "exportto.            (line   6")
+    ("expression list" . "Data types (plural). (line   6")
+    ("Ext" . "Ext.                 (line   6")
+    ("Ext, computation of" . "Computation of Ext.  (line   6")
+    ("ext-module" . "purityfiltration_lib")
+    ("Ext_R" . "Ext_R.               (line   6")
+    ("extcurve" . "extcurve.            (line   6")
+    ("extdevelop" . "extdevelop.          (line   6")
+    ("extend" . "extend.              (line   6")
+    ("extendedTensor" . "extendedTensor.      (line   6")
+    ("extendring" . "extendring.          (line   6")
+    ("extendWeyl" . "extendWeyl.          (line   6")
+    ("extension of rings" . "splitring.           (line  32")
+    ("Exterior" . "Exterior.            (line   6")
+    ("exterior basis" . "exteriorBasis.       (line  18")
+    ("exterior power" . "exteriorPower.       (line  18")
+    ("exteriorBasis" . "exteriorBasis.       (line   6")
+    ("exteriorPower" . "exteriorPower.       (line   6")
+    ("extgcd" . "extgcd.              (line   6")
+    ("Extra weight vector" . "Extra weight vector. (line   6")
+    ("facets" . "facets.              (line   6")
+    ("facetVertexLatticeDistances" . "facetVertexLatticeDistances")
+    ("facetWidth" . "facetWidth.          (line   6")
+    ("facetWidths" . "facetWidths.         (line   6")
+    ("facFirstShift" . "facFirstShift.       (line   6")
+    ("facFirstWeyl" . "facFirstWeyl.        (line   6")
+    ("facGBIdeal" . "facGBIdeal.          (line   6")
+    ("facstd" . "facstd.              (line   6")
+    ("facSubWeyl" . "facSubWeyl.          (line   6")
+    ("factmodd" . "factmodd.            (line   6")
+    ("factorgroup" . "factorgroup.         (line   6")
+    ("factorH" . "factorH.             (line   6")
+    ("factorial" . "factorial.           (line   6")
+    ("factorization" . "absfact_lib.         (line  31")
+    ("Factorization" . "Factorization.       (line   6")
+    ("factorize" . "factorize.           (line   6")
+    ("factorLenstraECM" . "factorLenstraECM.    (line   6")
+    ("factorMain" . "factorMain.          (line   6")
+    ("factory" . "Preface.             (line   6")
+    ("fan" . "oldpolymake_lib.     (line  69")
+    ("fan related functions" . "fan related functions")
+    ("fanViaCones" . "fanViaCones.         (line   6")
+    ("farey" . "farey.               (line   6")
+    ("fastelim" . "fastelim.            (line   6")
+    ("fastExpt" . "fastExpt.            (line   6")
+    ("fastHC, option" . "option.              (line  57")
+    ("fetch" . "fetch.               (line   6")
+    ("fetch (plural)" . "fetch (plural).      (line   6")
+    ("fetchall" . "fetchall.            (line   6")
+    ("ffsolve" . "ffsolve.             (line   6")
+    ("ffsolve.lib" . "ffsolve_lib.         (line   6")
+    ("ffsolve_lib" . "ffsolve_lib.         (line   6")
+    ("fglm" . "stdfglm.             (line  23")
+    ("fglm_solve" . "fglm_solve.          (line   6")
+    ("fglmquot" . "fglmquot.            (line   6")
+    ("fibonacci" . "fibonacci.           (line   6")
+    ("field" . "number.              (line   6")
+    ("file, .singularrc" . "Startup sequence.    (line  10")
+    ("filecmd" . "filecmd.             (line   6")
+    ("filtration" . "purityfiltration_lib")
+    ("finalCharts" . "finalCharts.         (line   6")
+    ("find" . "find.                (line   6")
+    ("findAuto" . "findAuto.            (line   6")
+    ("findifs.lib" . "findifs_lib.         (line   6")
+    ("findifs_example" . "findifs_example.     (line   6")
+    ("findifs_lib" . "findifs_lib.         (line   6")
+    ("findimAlgebra" . "findimAlgebra.       (line   6")
+    ("findInvo" . "findInvo.            (line   6")
+    ("findInvoDiag" . "findInvoDiag.        (line   6")
+    ("findOrientedBoundary" . "findOrientedBoundary")
+    ("findTorsion" . "findTorsion.         (line   6")
+    ("finduni" . "finduni.             (line   6")
+    ("findvars" . "findvars.            (line   6")
+    ("finite field" . "ffsolve_lib.         (line  15")
+    ("Finite fields" . "Finite fields.       (line   6")
+    ("finiteDiagInvariants" . "finiteDiagInvariants")
+    ("finitediff.lib" . "finitediff_lib.      (line  22")
+    ("finitediff_lib" . "finitediff_lib.      (line  22")
+    ("finitenessTest" . "finitenessTest.      (line   6")
+    ("finvar.lib" . "finvar_lib.          (line   6")
+    ("finvar_lib" . "finvar_lib.          (line   6")
+    ("first index is 1" . "First index is 1.    (line   6")
+    ("First steps" . "First steps.         (line   6")
+    ("firstoct" . "firstoct.            (line   6")
+    ("fitting" . "fitting.             (line   6")
+    ("Fitzgerald-Lax method" . "Fitzgerald-Lax method")
+    ("fl2poly" . "fl2poly.             (line   6")
+    ("flatten" . "flatten.             (line   6")
+    ("flatteningStrat" . "flatteningStrat.     (line   6")
+    ("Flow control" . "Flow control.        (line   6")
+    ("for" . "for.                 (line   6")
+    ("Formal Checker" . "Formal Checker.      (line   6")
+    ("formaldivisorplus" . "formaldivisorplus.   (line   6")
+    ("Formatting output" . "Formatting output.   (line   6")
+    ("forward" . "forward.             (line   6")
+    ("fourier" . "fourier.             (line   6")
+    ("fouriersystem" . "fouriersystem.       (line   6")
+    ("fpadim.lib" . "fpadim_lib.          (line   6")
+    ("fpadim_lib" . "fpadim_lib.          (line   6")
+    ("fprintf" . "fprintf.             (line   6")
+    ("free associative algebra, tensor algebra" . "Free associative algebras")
+    ("Free resolution" . "Free resolution.     (line   6")
+    ("Free resolution, graded" . "Handling graded modules")
+    ("freegb.lib" . "freegb_lib.          (line   6")
+    ("freegb_lib" . "freegb_lib.          (line   6")
+    ("freeGBasis" . "freeGBasis.          (line   6")
+    ("freemodule" . "freemodule.          (line   6")
+    ("freerank" . "freerank.            (line   6")
+    ("from_boolean_constant" . "from_boolean_constant")
+    ("from_boolean_ideal" . "from_boolean_ideal.  (line   6")
+    ("from_boolean_poly" . "from_boolean_poly.   (line   6")
+    ("from_boolean_set" . "from_boolean_set.    (line   6")
+    ("frwalk" . "frwalk.              (line   6")
+    ("fullFan" . "fullFan.             (line   6")
+    ("fullSerreRelations" . "fullSerreRelations.  (line   6")
+    ("Functions" . "Functions.           (line   6")
+    ("further_hn_proc" . "further_hn_proc.     (line   6")
+    ("furtherInvar" . "furtherInvar.        (line   6")
+    ("fVector" . "fVector.             (line   6")
+    ("fVector(polymake)" . "fVector(polymake).   (line   6")
+    ("fwalk" . "fwalk.               (line   6")
+    ("G-algebra" . "G-algebras.          (line   6")
+    ("G-algebra, setup" . "G-algebras.          (line  51")
+    ("G_a -Invariants" . "G_a -Invariants.     (line   6")
+    ("galois field" . "number.              (line   6")
+    ("Gamma" . "Gamma.               (line   6")
+    ("Gauss-Manin connection" . "spectrumnd.          (line  26")
+    ("Gauss-Manin system" . "goodBasis.           (line  22")
+    ("gauss_col" . "gauss_col.           (line   6")
+    ("gauss_nf" . "gauss_nf.            (line   6")
+    ("gauss_row" . "gauss_row.           (line   6")
+    ("gaussred" . "gaussred.            (line   6")
+    ("gaussred_pivot" . "gaussred_pivot.      (line   6")
+    ("GBsolve" . "GBsolve.             (line   6")
+    ("GBWeight" . "GBWeight.            (line   6")
+    ("gcd" . "gcd.                 (line   6")
+    ("gcddivisor" . "gcddivisor.          (line   6")
+    ("gcdMon" . "gcdMon.              (line   6")
+    ("gcdN" . "gcdN.                (line   6")
+    ("gen" . "gen.                 (line   6")
+    ("General command syntax" . "General command syntax")
+    ("General concepts" . "General concepts.    (line   6")
+    ("general error-locator polynomial" . "Cooper philosophy.   (line  46")
+    ("General purpose" . "General purpose.     (line   6")
+    ("General syntax of a ring declaration" . "General syntax of a ring declaration")
+    ("general weighted lexicographical ordering" . "Local orderings. (line  39")
+    ("general weighted reverse lexicographical ordering" . "Local orderings")
+    ("general.lib" . "general_lib.         (line   6")
+    ("general_lib" . "general_lib.         (line   6")
+    ("Generalized Hilbert Syzygy Theorem" . "Syzygies and resolutions (plural)")
+    ("Generalized Newton identities" . "Generalized Newton identities")
+    ("generalOrder" . "generalOrder.        (line   6")
+    ("generateG" . "generateG.           (line   6")
+    ("generators" . "charexp2generators.  (line  19")
+    ("generatorsOfLinealitySpace" . "generatorsOfLinealitySpace")
+    ("generatorsOfSpan" . "generatorsOfSpan.    (line   6")
+    ("genericid" . "genericid.           (line   6")
+    ("genericity" . "genericity.          (line   6")
+    ("genericmat" . "genericmat.          (line   6")
+    ("genMDSMat" . "genMDSMat.           (line   6")
+    ("genoutput" . "genoutput.           (line   6")
+    ("genSymId" . "genSymId.            (line   6")
+    ("genus" . "genus.               (line   6")
+    ("Geometric genus" . "paraplanecurves_lib. (line  73")
+    ("geometric invariant theory" . "gitfan_lib.          (line  24")
+    ("German Umlaute" . "Limitations.         (line  53")
+    ("getCone" . "getCone.             (line   6")
+    ("getdump" . "getdump.             (line   6")
+    ("getenv" . "system.              (line  41")
+    ("getGradingGroup" . "getGradingGroup.     (line   6")
+    ("getLattice" . "getLattice.          (line   6")
+    ("getLinearForms" . "getLinearForms.      (line   6")
+    ("getModuleGrading" . "getModuleGrading.    (line   6")
+    ("getMultiplicity" . "getMultiplicity.     (line   6")
+    ("getOneVar" . "getOneVar.           (line   6")
+    ("getSmallest" . "getSmallest.         (line   6")
+    ("Getting started" . "Getting started.     (line   6")
+    ("getVariableWeights" . "getVariableWeights.  (line   6")
+    ("gfanlib" . "Preface.             (line   6")
+    ("GIT" . "gitfan_lib.          (line  24")
+    ("gitCone" . "gitCone.             (line   6")
+    ("gitFan" . "gitFan.              (line   6")
+    ("gitfan" . "gitfan_lib.          (line  24")
+    ("gitfan.lib" . "gitfan_lib.          (line   6")
+    ("gitfan_lib" . "gitfan_lib.          (line   6")
+    ("GKdim" . "GKdim.               (line   6")
+    ("gkdim.lib" . "gkdim_lib.           (line   6")
+    ("gkdim_lib" . "gkdim_lib.           (line   6")
+    ("gkzFan" . "gkzFan.              (line   6")
+    ("GKZsystem" . "GKZsystem.           (line   6")
+    ("global Bernstein-Sato polynomial" . "dmod_lib.            (line 109")
+    ("global Bernstein-Sato polynomial for variety" . "dmodvar_lib.  (line  59")
+    ("Global orderings" . "Global orderings.    (line   6")
+    ("globalSections" . "globalSections.      (line   6")
+    ("GMP" . "Preface.             (line   6")
+    ("gmscoeffs" . "gmscoeffs.           (line   6")
+    ("gmsnf" . "gmsnf.               (line   6")
+    ("gmspoly.lib" . "gmspoly_lib.         (line   6")
+    ("gmspoly_lib" . "gmspoly_lib.         (line   6")
+    ("gmsring" . "gmsring.             (line   6")
+    ("gmssing.lib" . "gmssing_lib.         (line   6")
+    ("gmssing_lib" . "gmssing_lib.         (line   6")
+    ("good basis" . "goodBasis.           (line  22")
+    ("goodBasis" . "goodBasis.           (line   6")
+    ("gorensteinIndex" . "gorensteinIndex.     (line   6")
+    ("gorensteinVector" . "gorensteinVector.    (line   6")
+    ("Graded commutative algebras" . "Graded commutative algebras (SCA)")
+    ("graded module, graded piece" . "dimGradedPart.       (line  22")
+    ("graded modules, handling of" . "Handling graded modules")
+    ("graded Weyl algebra" . "bfun_lib.            (line  68")
+    ("gradeNumber" . "gradeNumber.         (line   6")
+    ("gradiator" . "gradiator.           (line   6")
+    ("graphics.lib" . "graphics_lib.        (line   6")
+    ("graphics_lib" . "graphics_lib.        (line   6")
+    ("graphviz" . "Preface.             (line   6")
+    ("graver4ti2" . "graver4ti2.          (line   6")
+    ("Greuel, Gert-Martin" . "Preface.             (line 144")
+    ("grobcov" . "grobcov.             (line   6")
+    ("grobcov.lib" . "grobcov_lib.         (line   6")
+    ("grobcov_lib" . "grobcov_lib.         (line   6")
+    ("groebner" . "groebner and std.    (line   6")
+    ("Groebner Bases" . "Computing Groebner and Standard Bases")
+    ("Groebner bases in free associative algebras" . "Groebner bases for two-sided ideals in free associative algebras")
+    ("Groebner bases in G-algebras" . "Groebner bases in G-algebras")
+    ("Groebner bases, decodeGB" . "decodegb_lib.        (line  50")
+    ("Groebner bases, slim" . "slim Groebner bases. (line   6")
+    ("Groebner basis conversion" . "Groebner basis conversion")
+    ("Groebner cover, parametric ideal, canonical, discussion of" . "extend")
+    ("Groebner fan" . "oldpolymake_lib.     (line  69")
+    ("Groebner walk" . "gwalk.               (line  21")
+    ("groebnerFan" . "groebnerFan.         (line   6")
+    ("ground field" . "number.              (line   6")
+    ("group_reynolds" . "group_reynolds.      (line   6")
+    ("grwalk.lib" . "grwalk_lib.          (line   6")
+    ("grwalk_lib" . "grwalk_lib.          (line   6")
+    ("GTZmod" . "GTZmod.              (line   6")
+    ("GTZopt" . "GTZopt.              (line   6")
+    ("gwalk" . "gwalk.               (line   6")
+    ("Gweights" . "Gweights.            (line   6")
+    ("H2basis" . "H2basis.             (line   6")
+    ("Hamburger-Noether expansion" . "hnoether_lib.        (line  49")
+    ("Hamburger-Noether expansions" . "Adj_div.             (line  64")
+    ("Handling graded modules" . "Handling graded modules")
+    ("hardware platform" . "system.              (line  37")
+    ("Hcode" . "Hcode.               (line   6")
+    ("headStand" . "headStand.           (line   6")
+    ("heightZ" . "heightZ.             (line   6")
+    ("help" . "help.                (line   6")
+    ("help browsers" . "The online help system")
+    ("help browsers, dummy" . "The online help system")
+    ("help browsers, emacs" . "The online help system")
+    ("help browsers, html" . "The online help system")
+    ("help browsers, setting command to use" . "The online help system")
+    ("help browsers, setting the" . "system.              (line  88")
+    ("Help string" . "Help string.         (line   6")
+    ("help, accessing over the net" . "Command line options")
+    ("help, online help system" . "The online help system")
+    ("hermiteNormalForm" . "hermiteNormalForm.   (line   6")
+    ("hessenberg" . "hessenberg.          (line   6")
+    ("highcorner" . "highcorner.          (line   6")
+    ("hilb" . "hilb.                (line   6")
+    ("Hilbert function" . "Hilbert function.    (line   6")
+    ("Hilbert series" . "Hilbert function.    (line   6")
+    ("Hilbert-driven GB algorithm" . "Groebner basis conversion")
+    ("hilbert4ti2" . "hilbert4ti2.         (line   6")
+    ("hilbertBasis" . "hilbertBasis.        (line   6")
+    ("HilbertClassPoly" . "HilbertClassPoly.    (line   6")
+    ("hilbertSeries" . "hilbertSeries.       (line   6")
+    ("HilbertSeries" . "HilbertSeries.       (line   6")
+    ("HilbertWeights" . "HilbertWeights.      (line   6")
+    ("hilbPoly" . "hilbPoly.            (line   6")
+    ("hilbvec" . "hilbvec.             (line   6")
+    ("hnexpansion" . "hnexpansion.         (line   6")
+    ("hnoether.lib" . "hnoether_lib.        (line   6")
+    ("hnoether_lib" . "hnoether_lib.        (line   6")
+    ("holonomic rank" . "dmodloc_lib.         (line  93")
+    ("holonomicRank" . "holonomicRank.       (line   6")
+    ("Hom" . "Hom.                 (line   6")
+    ("hom_kernel" . "hom_kernel.          (line   6")
+    ("HomJJ" . "HomJJ.               (line   6")
+    ("homog" . "homog.               (line   6")
+    ("homogfacFirstQWeyl" . "homogfacFirstQWeyl.  (line   6")
+    ("homogfacFirstQWeyl_all" . "homogfacFirstQWeyl_all")
+    ("homolog.lib" . "homolog_lib.         (line   6")
+    ("homolog_lib" . "homolog_lib.         (line   6")
+    ("homology" . "homology.            (line   6")
+    ("Hosten-Sturmfels algorithm" . "Hosten and Sturmfels")
+    ("How to enter and exit" . "How to enter and exit")
+    ("How to use this manual" . "How to use this manual")
+    ("howto, download" . "Download instructions")
+    ("howto, install on Macintosh" . "Macintosh installation instructions")
+    ("howto, install on Unix" . "Unix installation instructions")
+    ("howto, install on Windows" . "Windows installation instructions")
+    ("hres" . "hres.                (line   6")
+    ("hStarVector" . "hStarVector.         (line   6")
+    ("html, default help" . "The online help system")
+    ("hVector" . "hVector.             (line   6")
+    ("hyperel.lib" . "hyperel_lib.         (line   6")
+    ("hyperel_lib" . "hyperel_lib.         (line   6")
+    ("hyperplane arrangement" . "dmod_lib.            (line 109")
+    ("Hypersurface singularities, classification of" . "Classification of hypersurface singularities")
+    ("hypersurface singularity" . "mondromy_lib.        (line  34")
+    ("id2mod" . "id2mod.              (line   6")
+    ("ideal" . "ideal.               (line   6")
+    ("ideal declarations" . "ideal declarations.  (line   6")
+    ("ideal declarations (plural)" . "ideal declarations (plural)")
+    ("ideal expressions" . "ideal expressions.   (line   6")
+    ("ideal expressions (plural)" . "ideal expressions (plural)")
+    ("Ideal membership" . "Standard bases.      (line  26")
+    ("ideal operations" . "ideal operations.    (line   6")
+    ("ideal operations (plural)" . "ideal operations (plural)")
+    ("ideal related functions" . "ideal related functions")
+    ("ideal related functions (plural)" . "ideal related functions (plural)")
+    ("ideal, toric" . "Toric ideals.        (line   6")
+    ("ideals" . "Miscellaneous oddities")
+    ("idealsimplify" . "idealsimplify.       (line   6")
+    ("idealSplit" . "idealSplit.          (line   6")
+    ("identifier" . "Identifier resolution")
+    ("Identifiers, syntax of" . "Names.               (line   6")
+    ("identifyvar" . "identifyvar.         (line   6")
+    ("if" . "if.                  (line   6")
+    ("image_of_variety" . "image_of_variety.    (line   6")
+    ("ImageGroup" . "ImageGroup.          (line   6")
+    ("imageLattice" . "imageLattice.        (line   6")
+    ("ImageVariety" . "ImageVariety.        (line   6")
+    ("imap" . "imap.                (line   6")
+    ("imap (plural)" . "imap (plural).       (line   6")
+    ("Imap, option" . "option.              (line 165")
+    ("imapall" . "imapall.             (line   6")
+    ("impart" . "impart.              (line   6")
+    ("Implemented algorithms" . "Implemented algorithms")
+    ("importfrom" . "importfrom.          (line   6")
+    ("iMult" . "iMult.               (line   6")
+    ("IN" . "lead.                (line  18")
+    ("inCenter" . "inCenter.            (line   6")
+    ("inCentralizer" . "inCentralizer.       (line   6")
+    ("Incl" . "Incl.                (line   6")
+    ("indepSet" . "indepSet.            (line   6")
+    ("Index" . "Index.               (line   6")
+    ("indexed names" . "Names.               (line   6")
+    ("indSet" . "indSet.              (line   6")
+    ("inequalities" . "inequalities.        (line   6")
+    ("info" . "The online help system")
+    ("Info string" . "Info string.         (line   6")
+    ("inForm" . "inForm.              (line   6")
+    ("infRedTail, option" . "option.              (line  62")
+    ("iniD" . "iniD.                (line   6")
+    ("init_debug" . "init_debug.          (line   6")
+    ("initial form" . "bfun_lib.            (line  68")
+    ("initial ideal" . "bfun_lib.            (line  68")
+    ("initial ideal approach" . "dmodvar_lib.         (line  59")
+    ("initialForm" . "initialForm.         (line   6")
+    ("initialIdeal" . "initialIdeal.        (line   6")
+    ("initialIdealW" . "initialIdealW.       (line   6")
+    ("initialMalgrange" . "initialMalgrange.    (line   6")
+    ("inout.lib" . "inout_lib.           (line   6")
+    ("inout_lib" . "inout_lib.           (line   6")
+    ("input" . "Input and output.    (line   6")
+    ("insert" . "insert.              (line   6")
+    ("insertCone" . "insertCone.          (line   6")
+    ("insertGenerator" . "insertGenerator.     (line   6")
+    ("instructions, downloading" . "Download instructions")
+    ("instructions, Macintosh installation" . "Macintosh installation instructions")
+    ("instructions, Unix installation" . "Unix installation instructions")
+    ("instructions, Windows installation" . "Windows installation instructions")
+    ("inSubring" . "inSubring.           (line   6")
+    ("int" . "int.                 (line   6")
+    ("int declarations" . "int declarations.    (line   6")
+    ("int expressions" . "int expressions.     (line   6")
+    ("int operations" . "int operations.      (line   6")
+    ("int related functions" . "int related functions")
+    ("intclMonIdeal" . "intclMonIdeal.       (line   6")
+    ("intclToricRing" . "intclToricRing.      (line   6")
+    ("integer division" . "Miscellaneous oddities")
+    ("integer programming" . "Integer programming. (line   6")
+    ("integral basis" . "adjointIdeal.        (line  50")
+    ("integral closure" . "normaliz_lib.        (line  50")
+    ("integralBasis" . "integralBasis.       (line   6")
+    ("integralbasis.lib" . "integralbasis_lib.   (line   6")
+    ("integralbasis_lib" . "integralbasis_lib.   (line   6")
+    ("integralIdeal" . "integralIdeal.       (line   6")
+    ("integralModule" . "integralModule.      (line   6")
+    ("integralSection" . "integralSection.     (line   6")
+    ("integration of D-module" . "dmodapp_lib.         (line 104")
+    ("Interactive use" . "Interactive use.     (line   6")
+    ("InterDiv" . "InterDiv.            (line   6")
+    ("interface, Emacs" . "Emacs user interface")
+    ("interiorLatticePoints" . "interiorLatticePoints")
+    ("internalfunctions" . "internalfunctions.   (line   6")
+    ("interpolate" . "interpolate.         (line   6")
+    ("interpolation" . "interpolation.       (line   6")
+    ("interred" . "interred.            (line   6")
+    ("Interrupting SINGULAR" . "Interrupting SINGULAR")
+    ("intersect" . "intersect.           (line   6")
+    ("intersect (plural)" . "intersect (plural).  (line   6")
+    ("intersectElim, option" . "option.              (line 142")
+    ("intersection" . "intersection.        (line   6")
+    ("intersection multiplicity" . "intersection.        (line  21")
+    ("intersectionDiv" . "intersectionDiv.     (line   6")
+    ("IntersectionMatrix" . "IntersectionMatrix.  (line   6")
+    ("intersectionValRingIdeals" . "intersectionValRingIdeals")
+    ("intersectionValRings" . "intersectionValRings")
+    ("intersectLattices" . "intersectLattices.   (line   6")
+    ("intersectMon" . "intersectMon.        (line   6")
+    ("intersectSyz, option" . "option.              (line 147")
+    ("IntersectWithSub" . "IntersectWithSub.    (line   6")
+    ("intersectZ" . "intersectZ.          (line   6")
+    ("intInverse" . "intInverse.          (line   6")
+    ("intmat" . "intmat.              (line   6")
+    ("intmat declarations" . "intmat declarations. (line   6")
+    ("intmat expressions" . "intmat expressions.  (line   6")
+    ("intmat operations" . "intmat operations.   (line   6")
+    ("intmat related functions" . "intmat related functions")
+    ("intmat type cast" . "intmat type cast.    (line   6")
+    ("intmat2mons" . "intmat2mons.         (line   6")
+    ("intmatToPolymake" . "intmatToPolymake.    (line   6")
+    ("intPart" . "intPart.             (line   6")
+    ("intprog.lib" . "intprog_lib.         (line   6")
+    ("intprog_lib" . "intprog_lib.         (line   6")
+    ("intRank" . "intRank.             (line   6")
+    ("Introduction" . "Introduction.        (line   6")
+    ("intRoot" . "intRoot.             (line   6")
+    ("intRoots" . "intRoots.            (line   6")
+    ("intStrategy, option" . "option.              (line  69")
+    ("intvec" . "intvec.              (line   6")
+    ("intvec declarations" . "intvec declarations. (line   6")
+    ("intvec expressions" . "intvec expressions.  (line   6")
+    ("intvec operations" . "intvec operations.   (line   6")
+    ("intvec related functions" . "intvec related functions")
+    ("invariant ring minimal generating set matrix group" . "invariant_algebra_reynolds")
+    ("invariant ring minimal generating set permutation group" . "invariant_algebra_perm")
+    ("Invariant theory" . "Invariant theory.    (line   6")
+    ("Invariant Theory" . "Invariant Theory.    (line   6")
+    ("invariant_algebra_perm" . "invariant_algebra_perm")
+    ("invariant_algebra_reynolds" . "invariant_algebra_reynolds")
+    ("invariant_basis" . "invariant_basis.     (line   6")
+    ("invariant_basis_reynolds" . "invariant_basis_reynolds")
+    ("invariant_ring" . "invariant_ring.      (line   6")
+    ("invariant_ring_random" . "invariant_ring_random")
+    ("InvariantQ" . "InvariantQ.          (line   6")
+    ("InvariantRing" . "InvariantRing.       (line   6")
+    ("invariantRing" . "invariantRing.       (line   6")
+    ("invariants" . "invariants.          (line   6")
+    ("Invariants of a finite group" . "Invariants of a finite group")
+    ("Invariants of plane curve singularities" . "Invariants of plane curve singularities")
+    ("inverse" . "inverse.             (line   6")
+    ("inverse of a matrix via its LU-decomposition" . "luinverse.    (line   6")
+    ("inverse_B" . "inverse_B.           (line   6")
+    ("inverse_L" . "inverse_L.           (line   6")
+    ("inverseFourier" . "inverseFourier.      (line   6")
+    ("invertBirMap" . "invertBirMap.        (line   6")
+    ("invertNumberMain" . "invertNumberMain.    (line   6")
+    ("involut.lib" . "involut_lib.         (line   6")
+    ("involut_lib" . "involut_lib.         (line   6")
+    ("involution" . "involution.          (line   6")
+    ("invunit" . "invunit.             (line   6")
+    ("iostruct" . "iostruct.            (line   6")
+    ("irred_secondary_char0" . "irred_secondary_char0")
+    ("irred_secondary_no_molien" . "irred_secondary_no_molien")
+    ("irreddecMon" . "irreddecMon.         (line   6")
+    ("irreducible power series" . "is_irred.            (line  26")
+    ("irreducible secondary invariant" . "irred_secondary_char0")
+    ("irrRealizationDim" . "irrRealizationDim.   (line   6")
+    ("is_active" . "is_active.           (line   6")
+    ("is_bijective" . "is_bijective.        (line   6")
+    ("is_cenBimodule" . "is_cenBimodule.      (line   6")
+    ("is_cenSubbimodule" . "is_cenSubbimodule.   (line   6")
+    ("is_ci" . "is_ci.               (line   6")
+    ("is_complex" . "is_complex.          (line   6")
+    ("is_injective" . "is_injective.        (line   6")
+    ("is_irred" . "is_irred.            (line   6")
+    ("is_is" . "is_is.               (line   6")
+    ("is_nested" . "is_nested.           (line   6")
+    ("is_NND" . "is_NND.              (line   6")
+    ("is_NP" . "is_NP.               (line   6")
+    ("is_pure" . "is_pure.             (line   6")
+    ("is_reg" . "is_reg.              (line   6")
+    ("is_regs" . "is_regs.             (line   6")
+    ("is_surjective" . "is_surjective.       (line   6")
+    ("is_zero" . "is_zero.             (line   6")
+    ("isAface" . "isAface.             (line   6")
+    ("isAntiEndo" . "isAntiEndo.          (line   6")
+    ("isartinianMon" . "isartinianMon.       (line   6")
+    ("isBounded" . "isBounded.           (line   6")
+    ("isCanonical" . "isCanonical.         (line   6")
+    ("isCartan" . "isCartan.            (line   6")
+    ("isCentral" . "isCentral.           (line   6")
+    ("isCI" . "isCI.                (line   6")
+    ("isCM" . "isCM.                (line   6")
+    ("isCMcod2" . "isCMcod2.            (line   6")
+    ("isCommutative" . "isCommutative.       (line   6")
+    ("isCompatible" . "isCompatible.        (line   6")
+    ("isCompressed" . "isCompressed.        (line   6")
+    ("isEqualDivisor" . "isEqualDivisor.      (line   6")
+    ("isEquising" . "isEquising.          (line   6")
+    ("isFlat" . "isFlat.              (line   6")
+    ("isFsat" . "isFsat.              (line   6")
+    ("isFullSpace" . "isFullSpace.         (line   6")
+    ("isgenericMon" . "isgenericMon.        (line   6")
+    ("isGorenstein" . "isGorenstein.        (line   6")
+    ("isGradedRingHomomorphism" . "isGradedRingHomomorphism")
+    ("isGroup" . "isGroup.             (line   6")
+    ("isGroupHomomorphism" . "isGroupHomomorphism. (line   6")
+    ("isHolonomic" . "isHolonomic.         (line   6")
+    ("isHomogeneous" . "isHomogeneous.       (line   6")
+    ("ishyper" . "ishyper.             (line   6")
+    ("isInt" . "isInt.               (line   6")
+    ("isIntegralSurjective" . "isIntegralSurjective")
+    ("isInvolution" . "isInvolution.        (line   6")
+    ("isirreducibleMon" . "isirreducibleMon.    (line   6")
+    ("isLatticeEmpty" . "isLatticeEmpty.      (line   6")
+    ("isLocallyFree" . "isLocallyFree.       (line   6")
+    ("isMonomial" . "isMonomial.          (line   6")
+    ("isNC" . "isNC.                (line   6")
+    ("isNormal" . "isNormal.            (line   6")
+    ("isoncurve" . "isoncurve.           (line   6")
+    ("isOnCurve" . "isOnCurve.           (line   6")
+    ("isOrigin" . "isOrigin.            (line   6")
+    ("isparam" . "isparam.             (line   6")
+    ("isPositive" . "isPositive.          (line   6")
+    ("isprimaryMon" . "isprimaryMon.        (line   6")
+    ("isprimeMon" . "isprimeMon.          (line   6")
+    ("isPrimitiveSublattice" . "isPrimitiveSublattice")
+    ("isPure" . "isPure.              (line   6")
+    ("isRational" . "isRational.          (line   6")
+    ("isReflexive" . "isReflexive.         (line   6")
+    ("isReg" . "isReg.               (line   6")
+    ("IsSCA" . "IsSCA.               (line   6")
+    ("isSimplicial" . "isSimplicial.        (line   6")
+    ("isSmooth" . "isSmooth.            (line   6")
+    ("isSublattice" . "isSublattice.        (line   6")
+    ("isSymmetric" . "isSymmetric.         (line   6")
+    ("isTame" . "isTame.              (line   6")
+    ("isTerminal" . "isTerminal.          (line   6")
+    ("isTorsionFree" . "isTorsionFree.       (line   6")
+    ("isuni" . "isuni.               (line   6")
+    ("isUpperTriangular" . "isUpperTriangular.   (line   6")
+    ("isVar" . "isVar.               (line   6")
+    ("isVeryAmple" . "isVeryAmple.         (line   6")
+    ("isWeyl" . "isWeyl.              (line   6")
+    ("isZeroElement" . "isZeroElement.       (line   6")
+    ("iv2lp" . "iv2lp.               (line   6")
+    ("iv2lpList" . "iv2lpList.           (line   6")
+    ("iv2lpMat" . "iv2lpMat.            (line   6")
+    ("ivDHilbert" . "ivDHilbert.          (line   6")
+    ("ivDHilbertSickle" . "ivDHilbertSickle.    (line   6")
+    ("ivDimCheck" . "ivDimCheck.          (line   6")
+    ("ivHilbert" . "ivHilbert.           (line   6")
+    ("ivKDim" . "ivKDim.              (line   6")
+    ("ivL2lpI" . "ivL2lpI.             (line   6")
+    ("ivMis2Base" . "ivMis2Base.          (line   6")
+    ("ivMis2Dim" . "ivMis2Dim.           (line   6")
+    ("ivOrdMisLex" . "ivOrdMisLex.         (line   6")
+    ("ivSickle" . "ivSickle.            (line   6")
+    ("ivSickleDim" . "ivSickleDim.         (line   6")
+    ("ivSickleHil" . "ivSickleHil.         (line   6")
+    ("J-marked schemes" . "JMBTest_lib.         (line  15")
+    ("J-marked schemes, Borel ideals" . "JMSConst_lib.        (line  15")
+    ("jacob" . "jacob.               (line   6")
+    ("Jacobi" . "Jacobi.              (line   6")
+    ("jacoblift" . "jacoblift.           (line   6")
+    ("jacobson" . "jacobson.            (line   6")
+    ("Jacobson form" . "jacobson_lib.        (line  58")
+    ("Jacobson normal form" . "jacobson_lib.        (line  58")
+    ("jacobson.lib" . "jacobson_lib.        (line   6")
+    ("jacobson_lib" . "jacobson_lib.        (line   6")
+    ("janet" . "janet.               (line   6")
+    ("jet" . "jet.                 (line   6")
+    ("jInvariant" . "jInvariant.          (line   6")
+    ("JMarkedScheme" . "JMarkedScheme.       (line   6")
+    ("JMBTest.lib" . "JMBTest_lib.         (line   6")
+    ("JMBTest_lib" . "JMBTest_lib.         (line   6")
+    ("JMSConst.lib" . "JMSConst_lib.        (line   6")
+    ("JMSConst_lib" . "JMSConst_lib.        (line   6")
+    ("jOft" . "jOft.                (line   6")
+    ("jordan" . "jordan.              (line   6")
+    ("jordanbasis" . "jordanbasis.         (line   6")
+    ("jordanmatrix" . "jordanmatrix.        (line   6")
+    ("jordannf" . "jordannf.            (line   6")
+    ("jungfib" . "jungfib.             (line   6")
+    ("jungnormal" . "jungnormal.          (line   6")
+    ("jungresolve" . "jungresolve.         (line   6")
+    ("JuReTopDim" . "JuReTopDim.          (line   6")
+    ("JuReZeroDim" . "JuReZeroDim.         (line   6")
+    ("katsura" . "katsura.             (line   6")
+    ("kbase" . "kbase.               (line   6")
+    ("kbase (plural)" . "kbase (plural).      (line   6")
+    ("keepring" . "keepring.            (line   6")
+    ("kernel" . "kernel.              (line   6")
+    ("Kernel of module homomorphisms" . "Kernel of module homomorphisms")
+    ("kernelLattice" . "kernelLattice.       (line   6")
+    ("kill" . "kill.                (line   6")
+    ("killall" . "killall.             (line   6")
+    ("killattrib" . "killattrib.          (line   6")
+    ("kmemory" . "kmemory.             (line   6")
+    ("kohom" . "kohom.               (line   6")
+    ("kontrahom" . "kontrahom.           (line   6")
+    ("koszul" . "koszul.              (line   6")
+    ("KoszulHomology" . "KoszulHomology.      (line   6")
+    ("KScoef" . "KScoef.              (line   6")
+    ("KSconvert" . "KSconvert.           (line   6")
+    ("KSker" . "KSker.               (line   6")
+    ("kskernel.lib" . "kskernel_lib.        (line   6")
+    ("kskernel_lib" . "kskernel_lib.        (line   6")
+    ("KSlinear" . "KSlinear.            (line   6")
+    ("KSpencerKernel" . "KSpencerKernel.      (line   6")
+    ("laguerre" . "laguerre.            (line   6")
+    ("laguerre_solve" . "laguerre_solve.      (line   6")
+    ("lastvarGeneral" . "lastvarGeneral.      (line   6")
+    ("latex.lib" . "latex_lib.           (line   6")
+    ("latex_lib" . "latex_lib.           (line   6")
+    ("latticeArea" . "latticeArea.         (line   6")
+    ("latticeBasis" . "latticeBasis.        (line   6")
+    ("latticeCodegree" . "latticeCodegree.     (line   6")
+    ("latticeDegree" . "latticeDegree.       (line   6")
+    ("latticePoints" . "latticePoints.       (line   6")
+    ("latticeVolume" . "latticeVolume.       (line   6")
+    ("laxfrT" . "laxfrT.              (line   6")
+    ("laxfrX" . "laxfrX.              (line   6")
+    ("lazy, option" . "option.              (line  75")
+    ("lcm" . "lcm.                 (line   6")
+    ("lcmMon" . "lcmMon.              (line   6")
+    ("lcmN" . "lcmN.                (line   6")
+    ("lcmofall" . "lcmofall.            (line   6")
+    ("lead" . "lead.                (line   6")
+    ("leadcoef" . "leadcoef.            (line   6")
+    ("leadexp" . "leadexp.             (line   6")
+    ("leadmonom" . "leadmonom.           (line   6")
+    ("leadmonomial" . "leadmonomial.        (line   6")
+    ("Left and two-sided Groebner bases" . "Left and two-sided Groebner bases")
+    ("left annihilator ideal" . "dmod_lib.            (line 109")
+    ("Left ideal membership" . "Groebner bases in G-algebras")
+    ("Left normal form" . "Groebner bases in G-algebras")
+    ("leftInverse" . "leftInverse.         (line   6")
+    ("leftKernel" . "leftKernel.          (line   6")
+    ("length, option" . "option.              (line  80")
+    ("LengthSym" . "LengthSym.           (line   6")
+    ("LengthSymElement" . "LengthSymElement.    (line   6")
+    ("letplaceGBasis" . "letplaceGBasis.      (line   6")
+    ("Letterplace" . "LETTERPLACE.         (line   6")
+    ("LETTERPLACE" . "LETTERPLACE.         (line   6")
+    ("letterplace correspondence" . "Letterplace correspondence")
+    ("lex_solve" . "lex_solve.           (line   6")
+    ("Lexicographic Groebner bases, computation of" . "Groebner basis conversion")
+    ("lexicographical ordering" . "Global orderings.    (line   9")
+    ("LIB" . "LIB.                 (line   6")
+    ("LIB commands" . "LIB commands.        (line   6")
+    ("lib2doc" . "Documentation Tool.  (line   6")
+    ("libcdd" . "Preface.             (line   6")
+    ("libfac" . "Preface.             (line   6")
+    ("libparse" . "libparse.            (line   6")
+    ("Libraries" . "Writing procedures and libraries")
+    ("Libraries in the SINGULAR Documentation" . "Libraries in the SINGULAR Documentation")
+    ("library" . "gitfan_lib.          (line  24")
+    ("library, info string" . "template_lib.        (line 137")
+    ("library, polybori.lib" . "polybori_lib.        (line  94")
+    ("library, template" . "template_lib.        (line   6")
+    ("library, template.lib" . "template_lib.        (line 137")
+    ("LIBs" . "SINGULAR libraries.  (line   6")
+    ("Lie algebra" . "tangentGens.         (line  34")
+    ("Lie group" . "maxZeros.            (line  33")
+    ("lieBracket" . "lieBracket.          (line   6")
+    ("lift" . "lift.                (line   6")
+    ("lift (plural)" . "lift (plural).       (line   6")
+    ("lift_kbase" . "lift_kbase.          (line   6")
+    ("lift_rel_kb" . "lift_rel_kb.         (line   6")
+    ("liftstd" . "liftstd.             (line   6")
+    ("liftstd (plural)" . "liftstd (plural).    (line   6")
+    ("Limitations" . "Limitations.         (line   6")
+    ("linalg.lib" . "linalg_lib.          (line   6")
+    ("linalg_lib" . "linalg_lib.          (line   6")
+    ("linealityDimension" . "linealityDimension.  (line   6")
+    ("linealitySpace" . "linealitySpace.      (line   6")
+    ("Linear algebra" . "Linear algebra.      (line   6")
+    ("Linear code" . "decodegb_lib.        (line  50")
+    ("linear code, dual" . "dual_code.           (line  18")
+    ("linear code, systematic" . "sys_code.            (line  27")
+    ("linear interreduction" . "bfun_lib.            (line  68")
+    ("linear_relations" . "linear_relations.    (line   6")
+    ("LinearActionQ" . "LinearActionQ.       (line   6")
+    ("LinearCombinationQ" . "LinearCombinationQ.  (line   6")
+    ("linearCombinations" . "linearCombinations.  (line   6")
+    ("LinearizeAction" . "LinearizeAction.     (line   6")
+    ("linearlyEquivalent" . "linearlyEquivalent.  (line   6")
+    ("linearMapKernel" . "linearMapKernel.     (line   6")
+    ("linearpart" . "linearpart.          (line   6")
+    ("link" . "Parallelization with MPtcp links")
+    ("link declarations" . "link declarations.   (line   6")
+    ("link expressions" . "link expressions.    (line   6")
+    ("link related functions" . "link related functions")
+    ("Links, user interface" . "parallelWaitAll.     (line  23")
+    ("linReduce" . "linReduce.           (line   6")
+    ("linReduceIdeal" . "linReduceIdeal.      (line   6")
+    ("linSyzSolve" . "linSyzSolve.         (line   6")
+    ("list" . "list.                (line   6")
+    ("list declarations" . "list declarations.   (line   6")
+    ("list expressions" . "list expressions.    (line   6")
+    ("list operations" . "list operations.     (line   6")
+    ("list related functions" . "list related functions")
+    ("listvar" . "listvar.             (line   6")
+    ("lll" . "lll.                 (line   6")
+    ("LLL" . "LLL.                 (line   6")
+    ("lll.lib" . "lll_lib.             (line   6")
+    ("lll_lib" . "lll_lib.             (line   6")
+    ("load" . "load.                (line   6")
+    ("Loading a library" . "Loading a library.   (line   6")
+    ("loadLib, option" . "option.              (line 176")
+    ("loadProc, option" . "option.              (line 179")
+    ("local methods" . "locNormal.           (line  50")
+    ("local names" . "Names in procedures. (line   6")
+    ("Local orderings" . "Local orderings.     (line   6")
+    ("local rings, computing in" . "Rings associated to monomial orderings")
+    ("local weighted lexicographical ordering" . "Local orderings.   (line  39")
+    ("local weighted reverse lexicographical ordering" . "Local orderings")
+    ("localInvar" . "localInvar.          (line   6")
+    ("localization" . "Rings associated to monomial orderings")
+    ("localization of D-module" . "dmodloc_lib.         (line  93")
+    ("localstd" . "localstd.            (line   6")
+    ("locAtZero" . "locAtZero.           (line   6")
+    ("locNormal" . "locNormal.           (line   6")
+    ("locnormal.lib" . "locnormal_lib.       (line   6")
+    ("locnormal_lib" . "locnormal_lib.       (line   6")
+    ("locstd" . "locstd.              (line   6")
+    ("Log for matrices" . "matrixLog.           (line  23")
+    ("log2" . "log2.                (line   6")
+    ("logarithmic annihilator ideal" . "dmod_lib.            (line 109")
+    ("Long coefficients" . "Long coefficients.   (line   6")
+    ("LOT algorithm" . "dmod_lib.            (line 109")
+    ("lp, global ordering" . "Global orderings.    (line   9")
+    ("lp2iv" . "lp2iv.               (line   6")
+    ("lp2ivId" . "lp2ivId.             (line   6")
+    ("lp2lstr" . "lp2lstr.             (line   6")
+    ("lpDHilbert" . "lpDHilbert.          (line   6")
+    ("lpDHilbertSickle" . "lpDHilbertSickle.    (line   6")
+    ("lpDimCheck" . "lpDimCheck.          (line   6")
+    ("lpHilbert" . "lpHilbert.           (line   6")
+    ("lpId2ivLi" . "lpId2ivLi.           (line   6")
+    ("lpKDim" . "lpKDim.              (line   6")
+    ("lpMis2Base" . "lpMis2Base.          (line   6")
+    ("lpMis2Dim" . "lpMis2Dim.           (line   6")
+    ("lpMult" . "lpMult.              (line   6")
+    ("lpNF" . "lpNF.                (line   6")
+    ("lpOrdMisLex" . "lpOrdMisLex.         (line   6")
+    ("lpPower" . "lpPower.             (line   6")
+    ("lprint" . "lprint.              (line   6")
+    ("lpSickle" . "lpSickle.            (line   6")
+    ("lpSickleDim" . "lpSickleDim.         (line   6")
+    ("lpSickleHil" . "lpSickleHil.         (line   6")
+    ("lres" . "lres.                (line   6")
+    ("ls, local ordering" . "Local orderings.     (line  11")
+    ("lst2str" . "lst2str.             (line   6")
+    ("LU-decomposition of a matrix of numbers" . "ludecomp.          (line   6")
+    ("ludecomp" . "ludecomp.            (line   6")
+    ("luinverse" . "luinverse.           (line   6")
+    ("lusolve" . "lusolve.             (line   6")
+    ("M, ordering" . "Matrix orderings.    (line   6")
+    ("Macintosh installation" . "Macintosh installation instructions")
+    ("magnitude" . "magnitude.           (line   6")
+    ("makeDivisor" . "makeDivisor.         (line   6")
+    ("makeFormalDivisor" . "makeFormalDivisor.   (line   6")
+    ("makeHeisenberg" . "makeHeisenberg.      (line   6")
+    ("makeLetterplaceRing" . "makeLetterplaceRing. (line   6")
+    ("makeMalgrange" . "makeMalgrange.       (line   6")
+    ("makeModElimRing" . "makeModElimRing.     (line   6")
+    ("makePDivisor" . "makePDivisor.        (line   6")
+    ("makeQsl2" . "makeQsl2.            (line   6")
+    ("makeQsl3" . "makeQsl3.            (line   6")
+    ("makeQso3" . "makeQso3.            (line   6")
+    ("makeUe6" . "makeUe6.             (line   6")
+    ("makeUe7" . "makeUe7.             (line   6")
+    ("makeUe8" . "makeUe8.             (line   6")
+    ("makeUf4" . "makeUf4.             (line   6")
+    ("makeUg2" . "makeUg2.             (line   6")
+    ("makeUgl" . "makeUgl.             (line   6")
+    ("makeUsl" . "makeUsl.             (line   6")
+    ("makeUsl2" . "makeUsl2.            (line   6")
+    ("makeUso10" . "makeUso10.           (line   6")
+    ("makeUso11" . "makeUso11.           (line   6")
+    ("makeUso12" . "makeUso12.           (line   6")
+    ("makeUso5" . "makeUso5.            (line   6")
+    ("makeUso6" . "makeUso6.            (line   6")
+    ("makeUso7" . "makeUso7.            (line   6")
+    ("makeUso8" . "makeUso8.            (line   6")
+    ("makeUso9" . "makeUso9.            (line   6")
+    ("makeUsp1" . "makeUsp1.            (line   6")
+    ("makeUsp2" . "makeUsp2.            (line   6")
+    ("makeUsp3" . "makeUsp3.            (line   6")
+    ("makeUsp4" . "makeUsp4.            (line   6")
+    ("makeUsp5" . "makeUsp5.            (line   6")
+    ("makeWeyl" . "makeWeyl.            (line   6")
+    ("map" . "map.                 (line   6")
+    ("map (plural)" . "map (plural).        (line   6")
+    ("map declarations" . "map declarations.    (line   6")
+    ("map declarations (plural)" . "map declarations (plural)")
+    ("map expressions" . "map expressions.     (line   6")
+    ("map expressions (plural)" . "map expressions (plural)")
+    ("map operations" . "map operations.      (line   6")
+    ("map operations (plural)" . "map operations (plural)")
+    ("map related functions" . "map related functions")
+    ("map related functions  (plural)" . "map related functions (plural)")
+    ("mapall" . "mapall.              (line   6")
+    ("mapIsFinite" . "mapIsFinite.         (line   6")
+    ("mapToRatNormCurve" . "mapToRatNormCurve.   (line   6")
+    ("markov4ti2" . "markov4ti2.          (line   6")
+    ("mat_rk" . "mat_rk.              (line   6")
+    ("matbil" . "matbil.              (line   6")
+    ("Mathematical background" . "Mathematical background")
+    ("Mathematical background (plural)" . "Mathematical background (plural)")
+    ("mathematical objects" . "Representation of mathematical objects")
+    ("mathinit" . "mathinit.            (line   6")
+    ("matmult" . "matmult.             (line   6")
+    ("matrix" . "matrix.              (line   6")
+    ("matrix declarations" . "matrix declarations. (line   6")
+    ("matrix diagonalization" . "jacobson_lib.        (line  58")
+    ("matrix expressions" . "matrix expressions.  (line   6")
+    ("matrix operations" . "matrix operations.   (line   6")
+    ("Matrix orderings" . "Matrix orderings.    (line   6")
+    ("matrix related functions" . "matrix related functions")
+    ("matrix type cast" . "matrix type cast.    (line   6")
+    ("matrix.lib" . "matrix_lib.          (line   6")
+    ("matrix_lib" . "matrix_lib.          (line   6")
+    ("matrixExp" . "matrixExp.           (line   6")
+    ("matrixLog" . "matrixLog.           (line   6")
+    ("matrixsystem" . "matrixsystem.        (line   6")
+    ("matrixT1" . "matrixT1.            (line   6")
+    ("Max" . "Max.                 (line   6")
+    ("maxabs" . "maxabs.              (line   6")
+    ("maxcoef" . "maxcoef.             (line   6")
+    ("maxdeg" . "maxdeg.              (line   6")
+    ("maxdeg1" . "maxdeg1.             (line   6")
+    ("maxEord" . "maxEord.             (line   6")
+    ("maxideal" . "maxideal.            (line   6")
+    ("maximalFace" . "maximalFace.         (line   6")
+    ("maximalValue" . "maximalValue.        (line   6")
+    ("maximum" . "maximum.             (line   6")
+    ("maximum number of zeroes" . "maxZeros.            (line  33")
+    ("Maximus" . "Maximus.             (line   6")
+    ("maxIntRoot" . "maxIntRoot.          (line   6")
+    ("Maxord" . "Maxord.              (line   6")
+    ("maxZeros" . "maxZeros.            (line   6")
+    ("mdouble" . "mdouble.             (line   6")
+    ("mem, option" . "option.              (line 182")
+    ("membershipMon" . "membershipMon.       (line   6")
+    ("memory" . "memory.              (line   6")
+    ("memory managment" . "memory.              (line   6")
+    ("midpoint" . "midpoint.            (line   6")
+    ("MillerRabin" . "MillerRabin.         (line   6")
+    ("milnor" . "milnor.              (line   6")
+    ("Milnor number" . "milnornumber.        (line  14")
+    ("milnorcode" . "milnorcode.          (line   6")
+    ("milnornumber" . "milnornumber.        (line   6")
+    ("Min" . "Min.                 (line   6")
+    ("minAssChar" . "minAssChar.          (line   6")
+    ("minAssGTZ" . "minAssGTZ.           (line   6")
+    ("minAssZ" . "minAssZ.             (line   6")
+    ("minbase" . "minbase.             (line   6")
+    ("minbaseMon" . "minbaseMon.          (line   6")
+    ("mindeg" . "mindeg.              (line   6")
+    ("mindeg1" . "mindeg1.             (line   6")
+    ("mindist" . "mindist.             (line   6")
+    ("minEcart" . "minEcart.            (line   6")
+    ("minimal display time, setting the" . "system.              (line  88")
+    ("MinimalDecomposition" . "MinimalDecomposition")
+    ("minimalFace" . "minimalFace.         (line   6")
+    ("minimalValue" . "minimalValue.        (line   6")
+    ("Minimum distance" . "decodegb_lib.        (line  50")
+    ("Minimus" . "Minimus.             (line   6")
+    ("minIntRoot" . "minIntRoot.          (line   6")
+    ("minIntRoot2" . "minIntRoot2.         (line   6")
+    ("minipoly" . "minipoly.            (line   6")
+    ("minkowskiSum" . "minkowskiSum.        (line   6")
+    ("minMult" . "minMult.             (line   6")
+    ("minor" . "minor.               (line   6")
+    ("minpoly" . "minpoly.             (line   6")
+    ("minres" . "minres.              (line   6")
+    ("minres (plural)" . "minres (plural).     (line   6")
+    ("Miscellaneous libraries" . "Miscellaneous libraries")
+    ("mixed Hodge structure" . "goodBasis.           (line  22")
+    ("mod" . "number operations.   (line   6")
+    ("mod2id" . "mod2id.              (line   6")
+    ("mod2str" . "mod2str.             (line   6")
+    ("mod_versal" . "mod_versal.          (line   6")
+    ("modality" . "modality.            (line   6")
+    ("modDec" . "modDec.              (line   6")
+    ("ModEqn" . "ModEqn.              (line   6")
+    ("modHenselStd" . "modHenselStd.        (line   6")
+    ("modNormal" . "modNormal.           (line   6")
+    ("modnormal.lib" . "modnormal_lib.       (line   6")
+    ("modnormal_lib" . "modnormal_lib.       (line   6")
+    ("modNPos" . "modNPos.             (line   6")
+    ("modNpos_test" . "modNpos_test.        (line   6")
+    ("modregCM" . "modregCM.            (line   6")
+    ("modS" . "modS.                (line   6")
+    ("modsatiety" . "modsatiety.          (line   6")
+    ("modStd" . "modStd.              (line   6")
+    ("modstd.lib" . "modstd_lib.          (line   6")
+    ("modstd_lib" . "modstd_lib.          (line   6")
+    ("modular methods" . "modnormal_lib.       (line  41")
+    ("modular methods." . "locNormal.           (line  50")
+    ("modular techniques." . "modNormal.           (line  37")
+    ("module" . "module.              (line   6")
+    ("module (plural)" . "module (plural).     (line   6")
+    ("module declarations" . "module declarations. (line   6")
+    ("module declarations (plural)" . "module declarations (plural)")
+    ("module expressions" . "module expressions.  (line   6")
+    ("module expressions (plural)" . "module expressions (plural)")
+    ("module operations" . "module operations.   (line   6")
+    ("module operations (plural)" . "module operations (plural)")
+    ("module ordering c" . "Module orderings.    (line  49")
+    ("module ordering C" . "Module orderings.    (line  19")
+    ("Module orderings" . "Module orderings.    (line   6")
+    ("module related functions" . "module related functions")
+    ("module related functions (plural)" . "module related functions (plural)")
+    ("module_containment" . "module_containment.  (line   6")
+    ("Modules and and their annihilator" . "Modules and their annihilator")
+    ("modulo" . "modulo.              (line   6")
+    ("modulo (plural)" . "modulo (plural).     (line   6")
+    ("moduloSlim" . "moduloSlim.          (line   6")
+    ("molien" . "molien.              (line   6")
+    ("mondromy.lib" . "mondromy_lib.        (line   6")
+    ("mondromy_lib" . "mondromy_lib.        (line   6")
+    ("monitor" . "monitor.             (line   6")
+    ("Monodromy" . "mondromy_lib.        (line  34")
+    ("monodromy" . "goodBasis.           (line  22")
+    ("monodromyB" . "monodromyB.          (line   6")
+    ("monomial" . "monomial.            (line   6")
+    ("monomial orderings" . "General definitions for orderings")
+    ("Monomial orderings" . "Monomial orderings.  (line   6")
+    ("monomial orderings" . "Rings associated to monomial orderings")
+    ("monomial orderings introduction" . "Introduction to orderings")
+    ("Monomial orderings, Term orderings" . "Term orderings.      (line   6")
+    ("monomialideal.lib" . "monomialideal_lib.   (line   6")
+    ("monomialideal_lib" . "monomialideal_lib.   (line   6")
+    ("monomialInIdeal" . "monomialInIdeal.     (line   6")
+    ("monomialLcm" . "monomialLcm.         (line   6")
+    ("monomials and precedence" . "Miscellaneous oddities")
+    ("mons2intmat" . "mons2intmat.         (line   6")
+    ("Morse lemma" . "realmorsesplit.      (line  23")
+    ("morsesplit" . "morsesplit.          (line   6")
+    ("MP" . "Preface.             (line   6")
+    ("MP links" . "MP links.            (line   6")
+    ("MP, groebner basis computations" . "groebner.            (line  52")
+    ("mp_res_mat" . "mp_res_mat.          (line   6")
+    ("MPfile links" . "MPfile links.        (line   6")
+    ("mplot" . "mplot.               (line   6")
+    ("mpresmat" . "mpresmat.            (line   6")
+    ("mprimdec.lib" . "mprimdec_lib.        (line   6")
+    ("mprimdec_lib" . "mprimdec_lib.        (line   6")
+    ("MPtcp" . "Parallelization with MPtcp links")
+    ("MPtcp links" . "MPtcp links.         (line   6")
+    ("mregular.lib" . "mregular_lib.        (line   6")
+    ("mregular_lib" . "mregular_lib.        (line   6")
+    ("mres" . "mres.                (line   6")
+    ("mres (plural)" . "mres (plural).       (line   6")
+    ("mstd" . "mstd.                (line   6")
+    ("msum" . "msum.                (line   6")
+    ("mtriple" . "mtriple.             (line   6")
+    ("mult" . "Miscellaneous oddities")
+    ("multBound" . "multBound.           (line   6")
+    ("multcol" . "multcol.             (line   6")
+    ("multdivisor" . "multdivisor.         (line   6")
+    ("multformaldivisor" . "multformaldivisor.   (line   6")
+    ("multi" . "multi.               (line   6")
+    ("multi indices" . "Names.               (line   6")
+    ("multiDeg" . "multiDeg.            (line   6")
+    ("multiDegBasis" . "multiDegBasis.       (line   6")
+    ("multiDegGroebner" . "multiDegGroebner.    (line   6")
+    ("multiDegModulo" . "multiDegModulo.      (line   6")
+    ("multiDegPartition" . "multiDegPartition.   (line   6")
+    ("multiDegResolution" . "multiDegResolution.  (line   6")
+    ("multiDegSyzygy" . "multiDegSyzygy.      (line   6")
+    ("multiDegTensor" . "multiDegTensor.      (line   6")
+    ("multiDegTor" . "multiDegTor.         (line   6")
+    ("multigrading, multidegree, multiweights, multigraded-homogeneous, integral linear algebra" . "multigrading_lib")
+    ("multigrading.lib" . "multigrading_lib.    (line   9")
+    ("multigrading_lib" . "multigrading_lib.    (line   9")
+    ("multiplicities, sequence of" . "invariants.          (line  47")
+    ("multiplicity sequence" . "multsequence.        (line  57")
+    ("MultiplicitySequence" . "MultiplicitySequence")
+    ("multiplylist" . "multiplylist.        (line   6")
+    ("multivariate equations" . "ffsolve_lib.         (line  15")
+    ("multRat" . "multRat.             (line   6")
+    ("multrow" . "multrow.             (line   6")
+    ("multseq2charexp" . "multseq2charexp.     (line   6")
+    ("multsequence" . "multsequence.        (line   6")
+    ("MVComplex" . "MVComplex.           (line   6")
+    ("nameof" . "nameof.              (line   6")
+    ("names" . "names.               (line   6")
+    ("Names" . "Names.               (line   6")
+    ("Names in procedures" . "Names in procedures. (line   6")
+    ("Names, indexed" . "Names.               (line   6")
+    ("nashmult" . "nashmult.            (line   6")
+    ("nblocks" . "system.              (line  67")
+    ("nBoundaryLatticePoints" . "nBoundaryLatticePoints")
+    ("nc_algebra" . "nc_algebra.          (line   6")
+    ("ncalg.lib" . "ncalg_lib.           (line   6")
+    ("ncalg_lib" . "ncalg_lib.           (line   6")
+    ("ncalgebra" . "ncalgebra.           (line   6")
+    ("ncdecomp.lib" . "ncdecomp_lib.        (line   6")
+    ("ncdecomp_lib" . "ncdecomp_lib.        (line   6")
+    ("ncdetection" . "ncdetection.         (line   6")
+    ("ncExt_R" . "ncExt_R.             (line   6")
+    ("ncfactor.lib" . "ncfactor_lib.        (line   6")
+    ("ncfactor_lib" . "ncfactor_lib.        (line   6")
+    ("ncHom" . "ncHom.               (line   6")
+    ("nchomolog.lib" . "nchomolog_lib.       (line   6")
+    ("nchomolog_lib" . "nchomolog_lib.       (line   6")
+    ("ncols" . "ncols.               (line   6")
+    ("ncones" . "ncones.              (line   6")
+    ("ncpreim.lib" . "ncpreim_lib.         (line   6")
+    ("ncpreim_lib" . "ncpreim_lib.         (line   6")
+    ("ncRelations" . "ncRelations.         (line   6")
+    ("nctools.lib" . "nctools_lib.         (line   6")
+    ("nctools_lib" . "nctools_lib.         (line   6")
+    ("ndcond" . "ndcond.              (line   6")
+    ("negatedCone" . "negatedCone.         (line   6")
+    ("negative degree lexicographical ordering" . "Local orderings.  (line  25")
+    ("negative degree reverse lexicographical ordering" . "Local orderings")
+    ("negative lexicographical ordering" . "Local orderings.     (line  11")
+    ("negativedivisor" . "negativedivisor.     (line   6")
+    ("negativeformaldivisor" . "negativeformaldivisor")
+    ("net access" . "Command line options")
+    ("newline" . "string.              (line   6")
+    ("news" . "News and changes.    (line   6")
+    ("newstruct" . "polybori_lib.        (line  94")
+    ("newTest" . "newTest.             (line   6")
+    ("Newton non-degenerate" . "is_NND.              (line  19")
+    ("Newton polygon" . "is_NND.              (line  19")
+    ("Newton polytope" . "oldpolymake_lib.     (line  69")
+    ("newtonDiag" . "newtonDiag.          (line   6")
+    ("newtonpoly" . "newtonpoly.          (line   6")
+    ("newtonPolytope" . "newtonPolytope.      (line   6")
+    ("newtonPolytopeLP" . "newtonPolytopeLP.    (line   6")
+    ("newtonPolytopeP" . "newtonPolytopeP.     (line   6")
+    ("NF" . "reduce (plural).     (line   6")
+    ("nf_icis" . "nf_icis.             (line   6")
+    ("NFMora" . "NFMora.              (line   6")
+    ("nHilbertBasis" . "nHilbertBasis.       (line   6")
+    ("nilpotent Lie algebras" . "orbitparam_lib.      (line  49")
+    ("nInteriorLatticePoints" . "nInteriorLatticePoints")
+    ("nLatticePoints" . "nLatticePoints.      (line   6")
+    ("nmaxcones" . "nmaxcones.           (line   6")
+    ("noether" . "noether.             (line   6")
+    ("noether.lib" . "noether_lib.         (line   6")
+    ("noether_lib" . "noether_lib.         (line   6")
+    ("noetherNormal" . "noetherNormal.       (line   6")
+    ("NoetherPosition" . "NoetherPosition.     (line   6")
+    ("Non-commutative algebra" . "Non-commutative algebra")
+    ("Non-commutative libraries" . "Non-commutative libraries")
+    ("Non-commutative LIBs" . "Non-commutative libraries")
+    ("Non-commutative subsystem" . "Non-commutative subsystem")
+    ("non-english special characters" . "Limitations.         (line  53")
+    ("none, option" . "option.              (line  49")
+    ("Nonhyp" . "Nonhyp.              (line   6")
+    ("nonMonomials" . "nonMonomials.        (line   6")
+    ("nonZeroEntry" . "nonZeroEntry.        (line   6")
+    ("norm" . "norm.                (line   6")
+    ("normal" . "normal.              (line   6")
+    ("Normal form" . "Standard bases.      (line  18")
+    ("normal.lib" . "normal_lib.          (line   6")
+    ("normal_lib" . "normal_lib.          (line   6")
+    ("normalC" . "normalC.             (line   6")
+    ("normalFan" . "normalFan(polymake). (line   6")
+    ("normalForm" . "normalForm.          (line   6")
+    ("normalform" . "normalform.          (line   6")
+    ("normalI" . "normalI.             (line   6")
+    ("normaliz" . "normaliz.            (line   6")
+    ("normaliz.lib" . "normaliz_lib.        (line   6")
+    ("normaliz_lib" . "normaliz_lib.        (line   6")
+    ("normalization" . "modNormal.           (line  37")
+    ("Normalization" . "Normalization.       (line   6")
+    ("normalization." . "adjointIdeal.        (line  50")
+    ("normalize" . "normalize.           (line   6")
+    ("normalP" . "normalP.             (line   6")
+    ("normalToricRing" . "normalToricRing.     (line   6")
+    ("normalToricRingFromBinomials" . "normalToricRingFromBinomials")
+    ("norTest" . "norTest.             (line   6")
+    ("not" . "boolean operations.  (line   6")
+    ("notBuckets, option" . "option.              (line  91")
+    ("notRegularity, option" . "option.              (line  83")
+    ("notSugar, option" . "option.              (line  87")
+    ("notWarnSB, option" . "option.              (line 185")
+    ("npar" . "npar.                (line   6")
+    ("npars" . "npars.               (line   6")
+    ("NPos" . "NPos.                (line   6")
+    ("NPos_test" . "NPos_test.           (line   6")
+    ("nres" . "nres.                (line   6")
+    ("nres (plural)" . "nres (plural).       (line   6")
+    ("nrows" . "nrows.               (line   6")
+    ("nrroots" . "nrroots.             (line   6")
+    ("nrRootsDeterm" . "nrRootsDeterm.       (line   6")
+    ("nrRootsProbab" . "nrRootsProbab.       (line   6")
+    ("nsatiety" . "nsatiety.            (line   6")
+    ("nselect" . "nselect.             (line   6")
+    ("NSplaces" . "NSplaces.            (line   6")
+    ("nt_solve" . "nt_solve.            (line   6")
+    ("NTL" . "Preface.             (line   6")
+    ("ntsolve.lib" . "ntsolve_lib.         (line   6")
+    ("ntsolve_lib" . "ntsolve_lib.         (line   6")
+    ("NullCone" . "NullCone.            (line   6")
+    ("number" . "number.              (line   6")
+    ("number declarations" . "number declarations. (line   6")
+    ("number expressions" . "number expressions.  (line   6")
+    ("number operations" . "number operations.   (line   6")
+    ("number related functions" . "number related functions")
+    ("number_e" . "number_e.            (line   6")
+    ("number_pi" . "number_pi.           (line   6")
+    ("numberOfConesOfDimension" . "numberOfConesOfDimension")
+    ("numerAlg.lib" . "numerAlg_lib.        (line  13")
+    ("numerAlg_lib" . "numerAlg_lib.        (line  13")
+    ("numerator" . "numerator.           (line   6")
+    ("numerDecom.lib" . "numerDecom_lib.      (line  13")
+    ("numerDecom_lib" . "numerDecom_lib.      (line  13")
+    ("NumIrrDecom" . "NumIrrDecom.         (line   6")
+    ("NumLocalDim" . "NumLocalDim.         (line   6")
+    ("NumPrimDecom" . "NumPrimDecom.        (line   6")
+    ("nvars" . "nvars.               (line   6")
+    ("Oaku-Takayama algorithm" . "dmod_lib.            (line 109")
+    ("Objects" . "Objects.             (line   6")
+    ("oldpolymake.lib" . "oldpolymake_lib.     (line   6")
+    ("oldpolymake_lib" . "oldpolymake_lib.     (line   6")
+    ("oneDimBelongSemigroup" . "oneDimBelongSemigroup")
+    ("online help" . "The online help system")
+    ("open" . "open.                (line   6")
+    ("opentex" . "opentex.             (line   6")
+    ("operatorBM" . "operatorBM.          (line   6")
+    ("operatorModulo" . "operatorModulo.      (line   6")
+    ("oppose" . "oppose.              (line   6")
+    ("opposite" . "opposite.            (line   6")
+    ("option" . "option.              (line   6")
+    ("or" . "Evaluation of logical expressions")
+    ("orbit" . "maxZeros.            (line  33")
+    ("orbit_variety" . "orbit_variety.       (line   6")
+    ("orbitCones" . "orbitCones.          (line   6")
+    ("orbitparam.lib" . "orbitparam_lib.      (line   6")
+    ("orbitparam_lib" . "orbitparam_lib.      (line   6")
+    ("ord" . "ord.                 (line   6")
+    ("ord_test" . "ord_test.            (line   6")
+    ("orderings" . "General definitions for orderings")
+    ("orderings introduction" . "Introduction to orderings")
+    ("orderings, a" . "Extra weight vector. (line   6")
+    ("orderings, global" . "Global orderings.    (line   6")
+    ("orderings, local" . "Local orderings.     (line   6")
+    ("orderings, M" . "Matrix orderings.    (line   6")
+    ("orderings, product" . "Product orderings.   (line   6")
+    ("ordstr" . "ordstr.              (line   6")
+    ("orthogonalize" . "orthogonalize.       (line   6")
+    ("outer" . "outer.               (line   6")
+    ("output" . "Input and output.    (line   6")
+    ("Output, formatting of" . "Formatting output.   (line   6")
+    ("p-adic numbers, l-adic numbers, projective limes" . "Coefficient rings")
+    ("package" . "package.             (line   6")
+    ("package declarations" . "package declarations")
+    ("package related functions" . "package related functions")
+    ("pairset" . "pairset.             (line   6")
+    ("par" . "par.                 (line   6")
+    ("par2varRing" . "par2varRing.         (line   6")
+    ("paraConic" . "paraConic.           (line   6")
+    ("parallel.lib" . "parallel_lib.        (line   6")
+    ("parallel_lib" . "parallel_lib.        (line   6")
+    ("Parallelization" . "parallelWaitAll.     (line  23")
+    ("parallelWaitAll" . "parallelWaitAll.     (line   6")
+    ("parallelWaitFirst" . "parallelWaitFirst.   (line   6")
+    ("parallelWaitN" . "parallelWaitN.       (line   6")
+    ("param" . "param.               (line   6")
+    ("Parameter list" . "Parameter list.      (line   6")
+    ("parameter, as numbers" . "number.              (line   6")
+    ("Parameters" . "Parameters.          (line   6")
+    ("parameterSubstitute" . "parameterSubstitute. (line   6")
+    ("parametric annihilator" . "dmod_lib.            (line 109")
+    ("parametric annihilator for variety" . "dmodvar_lib.         (line  59")
+    ("parametrization" . "parametrizeOrbit.    (line  34")
+    ("Parametrization" . "paraplanecurves_lib. (line  73")
+    ("Parametrization, image." . "testParametrization. (line  26")
+    ("parametrizeOrbit" . "parametrizeOrbit.    (line   6")
+    ("paraPlaneCurve" . "paraPlaneCurve.      (line   6")
+    ("paraplanecurves.lib" . "paraplanecurves_lib. (line   6")
+    ("paraplanecurves_lib" . "paraplanecurves_lib. (line   6")
+    ("pardeg" . "pardeg.              (line   6")
+    ("parstr" . "parstr.              (line   6")
+    ("partial_molien" . "partial_molien.      (line   6")
+    ("PartitionVar" . "PartitionVar.        (line   6")
+    ("ParToVar" . "ParToVar.            (line   6")
+    ("pause" . "pause.               (line   6")
+    ("PBW" . "central_lib.         (line  19")
+    ("PBW basis" . "G-algebras.          (line   9")
+    ("PBW_eqDeg" . "PBW_eqDeg.           (line   6")
+    ("PBW_maxDeg" . "PBW_maxDeg.          (line   6")
+    ("PBW_maxMonom" . "PBW_maxMonom.        (line   6")
+    ("pdivi" . "pdivi.               (line   6")
+    ("pdivisorplus" . "pdivisorplus.        (line   6")
+    ("PerfectPowerTest" . "PerfectPowerTest.    (line   6")
+    ("permcol" . "permcol.             (line   6")
+    ("permrow" . "permrow.             (line   6")
+    ("permute_L" . "permute_L.           (line   6")
+    ("perron" . "perron.              (line   6")
+    ("perron.lib" . "perron_lib.          (line   6")
+    ("perron_lib" . "perron_lib.          (line   6")
+    ("Perturbation walk" . "pwalk.               (line  22")
+    ("PEsolve" . "PEsolve.             (line   6")
+    ("pFactor" . "pFactor.             (line   6")
+    ("Pfister, Gerhard" . "Preface.             (line 144")
+    ("PH_ais" . "PH_ais.              (line   6")
+    ("PH_nais" . "PH_nais.             (line   6")
+    ("phindex.lib" . "phindex_lib.         (line   6")
+    ("phindex_lib" . "phindex_lib.         (line   6")
+    ("picksFormula" . "picksFormula.        (line   6")
+    ("pid" . "system.              (line  30")
+    ("pIntersect" . "pIntersect.          (line   6")
+    ("pIntersectSyz" . "pIntersectSyz.       (line   6")
+    ("Pipe links" . "Pipe links.          (line   6")
+    ("plainInvariants" . "plainInvariants.     (line   6")
+    ("plot" . "plot.                (line   6")
+    ("plotRot" . "plotRot.             (line   6")
+    ("plotRotated" . "plotRotated.         (line   6")
+    ("plotRotatedDirect" . "plotRotatedDirect.   (line   6")
+    ("plotRotatedList" . "plotRotatedList.     (line   6")
+    ("plotRotatedListFromSpecifyList" . "plotRotatedListFromSpecifyList")
+    ("PLURAL" . "PLURAL.              (line   6")
+    ("PLURAL LIBs" . "Non-commutative libraries")
+    ("pmat" . "pmat.                (line   6")
+    ("pnormalf" . "pnormalf.            (line   6")
+    ("PocklingtonLehmer" . "PocklingtonLehmer.   (line   6")
+    ("pointid.lib" . "pointid_lib.         (line   6")
+    ("pointid_lib" . "pointid_lib.         (line   6")
+    ("Polar curves" . "Polar curves.        (line   6")
+    ("PollardRho" . "PollardRho.          (line   6")
+    ("polSol" . "polSol.              (line   6")
+    ("polSolFiniteRank" . "polSolFiniteRank.    (line   6")
+    ("poly" . "poly.                (line   6")
+    ("poly (plural)" . "poly (plural).       (line   6")
+    ("poly declarations" . "poly declarations.   (line   6")
+    ("poly declarations (plural)" . "poly declarations (plural)")
+    ("poly expressions" . "poly expressions.    (line   6")
+    ("poly expressions (plural)" . "poly expressions (plural)")
+    ("poly operations" . "poly operations.     (line   6")
+    ("poly operations (plural)" . "poly operations (plural)")
+    ("poly related functions" . "poly related functions")
+    ("poly related functions (plural)" . "poly related functions (plural)")
+    ("poly.lib" . "poly_lib.            (line   6")
+    ("poly2list" . "poly2list.           (line   6")
+    ("poly2zdd" . "poly2zdd.            (line   6")
+    ("poly_lib" . "poly_lib.            (line   6")
+    ("polybori" . "polybori_lib.        (line  94")
+    ("Polybori, Boolean Groebner Basis" . "disp_zdd.            (line  20")
+    ("PolyBoRi, Boolean Groebner Basis" . "zdd2poly.            (line  14")
+    ("PolyBoRi, zero-supressed decision diagram" . "poly2zdd.        (line  14")
+    ("polybori.lib" . "polybori_lib.        (line   6")
+    ("polybori_lib" . "polybori_lib.        (line   6")
+    ("polymake" . "oldpolymake_lib.     (line  69")
+    ("polymake_so" . "polymake_so.         (line   6")
+    ("polymakeKeepTmpFiles" . "polymakeKeepTmpFiles")
+    ("polymakePolytope" . "polymakePolytope.    (line   6")
+    ("polymakeToIntmat" . "polymakeToIntmat.    (line   6")
+    ("Polynomial data" . "Polynomial data.     (line   6")
+    ("polynomial solutions" . "dmodloc_lib.         (line  93")
+    ("polytope" . "oldpolymake_lib.     (line  69")
+    ("polytope related functions" . "polytope related functions")
+    ("polytopeViaInequalities" . "polytopeViaInequalities")
+    ("polytopeViaPoints" . "polytopeViaPoints.   (line   6")
+    ("polyVars" . "polyVars.            (line   6")
+    ("pos_def" . "pos_def.             (line   6")
+    ("posweight" . "posweight.           (line   6")
+    ("Pottier algorithm" . "Pottier.             (line   6")
+    ("power" . "power.               (line   6")
+    ("power_products" . "power_products.      (line   6")
+    ("powerN" . "powerN.              (line   6")
+    ("powerpolyX" . "powerpolyX.          (line   6")
+    ("powersums" . "powersums.           (line   6")
+    ("powerX" . "powerX.              (line   6")
+    ("preComp" . "preComp.             (line   6")
+    ("Preface" . "Preface.             (line   6")
+    ("preimage" . "ncpreim_lib.         (line  62")
+    ("preimage (plural)" . "preimage (plural).   (line   6")
+    ("preimage under a map between local rings, map between local rings, map between local and global rings" . "preimageLoc")
+    ("preimageLattice" . "preimageLattice.     (line   6")
+    ("preimageLoc" . "preimageLoc.         (line   6")
+    ("preimageNC" . "preimageNC.          (line   6")
+    ("prepareAss" . "prepareAss.          (line   6")
+    ("prepEmbDiv" . "prepEmbDiv.          (line   6")
+    ("prepMat" . "prepMat.             (line   6")
+    ("prepRealclassify" . "prepRealclassify.    (line   6")
+    ("prepSV" . "prepSV.              (line   6")
+    ("presentTree" . "presentTree.         (line   6")
+    ("presolve.lib" . "presolve_lib.        (line   6")
+    ("presolve_lib" . "presolve_lib.        (line   6")
+    ("Primary decomposition" . "Primary decomposition")
+    ("primary_char0" . "primary_char0.       (line   6")
+    ("primary_char0_no_molien" . "primary_char0_no_molien")
+    ("primary_char0_no_molien_random" . "primary_char0_no_molien_random")
+    ("primary_char0_random" . "primary_char0_random")
+    ("primary_charp" . "primary_charp.       (line   6")
+    ("primary_charp_no_molien" . "primary_charp_no_molien")
+    ("primary_charp_no_molien_random" . "primary_charp_no_molien_random")
+    ("primary_charp_random" . "primary_charp_random")
+    ("primary_charp_without" . "primary_charp_without")
+    ("primary_charp_without_random" . "primary_charp_without_random")
+    ("primary_invariants" . "primary_invariants.  (line   6")
+    ("primary_invariants_random" . "primary_invariants_random")
+    ("primdec.lib" . "primdec_lib.         (line   6")
+    ("primdec_lib" . "primdec_lib.         (line   6")
+    ("PrimdecA" . "PrimdecA.            (line   6")
+    ("PrimdecB" . "PrimdecB.            (line   6")
+    ("primdecGTZ" . "primdecGTZ.          (line   6")
+    ("primdecint.lib" . "primdecint_lib.      (line   6")
+    ("primdecint_lib" . "primdecint_lib.      (line   6")
+    ("primdecMon" . "primdecMon.          (line   6")
+    ("primdecSY" . "primdecSY.           (line   6")
+    ("primdecZ" . "primdecZ.            (line   6")
+    ("prime" . "prime.               (line   6")
+    ("primeClosure" . "primeClosure.        (line   6")
+    ("primecoeffs" . "primecoeffs.         (line   6")
+    ("primefactors" . "primefactors.        (line   6")
+    ("primes" . "primes.              (line   6")
+    ("primitiv.lib" . "primitiv_lib.        (line   6")
+    ("primitiv_lib" . "primitiv_lib.        (line   6")
+    ("primitive" . "primitive.           (line   6")
+    ("primitive element" . "primitive.           (line  34")
+    ("primitive_extra" . "primitive_extra.     (line   6")
+    ("primitiveSpan" . "primitiveSpan.       (line   6")
+    ("primL" . "primL.               (line   6")
+    ("primList" . "primList.            (line   6")
+    ("primparam" . "primparam.           (line   6")
+    ("primRoot" . "primRoot.            (line   6")
+    ("primTest" . "primTest.            (line   6")
+    ("principal intersection" . "bfun_lib.            (line  68")
+    ("print" . "print.               (line   6")
+    ("printf" . "printf.              (line   6")
+    ("printGroup" . "printGroup.          (line   6")
+    ("printlevel" . "printlevel.          (line   6")
+    ("proc" . "proc.                (line   6")
+    ("proc declaration" . "proc declaration.    (line   6")
+    ("Procedure definition" . "Procedure definition")
+    ("procedure, ASCII help" . "mdouble.             (line  19")
+    ("procedure, ASCII/Texinfo help" . "msum.                (line  32")
+    ("procedure, texinfo help" . "mtriple.             (line  21")
+    ("Procedure-specific commands" . "Procedure-specific commands")
+    ("Procedures" . "Procedures.          (line   6")
+    ("Procedures and libraries" . "Writing procedures and libraries")
+    ("Procedures in a library" . "Procedures in a library")
+    ("procedures, help string" . "Help string.         (line   6")
+    ("procedures, static" . "Procedure definition")
+    ("prodcrit" . "prodcrit.            (line   6")
+    ("product" . "product.             (line   6")
+    ("Product orderings" . "Product orderings.   (line   6")
+    ("productgroup" . "productgroup.        (line   6")
+    ("Programming" . "Programming.         (line   6")
+    ("progress watch" . "option.              (line  98")
+    ("projective dimension" . "purityfiltration_lib")
+    ("projectiveDimension" . "projectiveDimension. (line   6")
+    ("projectLattice" . "projectLattice.      (line   6")
+    ("prompt" . "The SINGULAR prompt. (line   6")
+    ("prompt, option" . "option.              (line 189")
+    ("prot, option" . "option.              (line  98")
+    ("protocol of computations" . "option.              (line  98")
+    ("proximitymatrix" . "proximitymatrix.     (line   6")
+    ("prune" . "prune.               (line   6")
+    ("psigncnd" . "psigncnd.            (line   6")
+    ("Puiseux expansion" . "hnoether_lib.        (line  49")
+    ("Puiseux pairs" . "invariants.          (line  47")
+    ("puiseux2generators" . "puiseux2generators.  (line   6")
+    ("puiseuxExpansion" . "puiseuxExpansion.    (line   6")
+    ("purelist" . "purelist.            (line   6")
+    ("purity" . "purityfiltration_lib")
+    ("purityFiltration" . "purityFiltration.    (line   6")
+    ("purityfiltration.lib" . "purityfiltration_lib")
+    ("purityfiltration_lib" . "purityfiltration_lib")
+    ("purityTriang" . "purityTriang.        (line   6")
+    ("pushForward" . "pushForward.         (line   6")
+    ("pwalk" . "pwalk.               (line   6")
+    ("pyobject" . "polybori_lib.        (line  94")
+    ("pyobject declarations" . "pyobject declarations")
+    ("pyobject expressions" . "pyobject expressions")
+    ("pyobject operations" . "pyobject operations. (line   6")
+    ("pyobject related functions" . "pyobject related functions")
+    ("pyramid" . "pyramid.             (line   6")
+    ("python_eval" . "python_eval.         (line   6")
+    ("python_import" . "python_import.       (line   6")
+    ("python_run" . "python_run.          (line   6")
+    ("qbase" . "qbase.               (line   6")
+    ("qepcad" . "qepcad.              (line   6")
+    ("qepcadsystem" . "qepcadsystem.        (line   6")
+    ("qhmatrix" . "qhmatrix.            (line   6")
+    ("qhmoduli.lib" . "qhmoduli_lib.        (line   6")
+    ("qhmoduli_lib" . "qhmoduli_lib.        (line   6")
+    ("qhspectrum" . "qhspectrum.          (line   6")
+    ("qhweight" . "qhweight.            (line   6")
+    ("qmatrix.lib" . "qmatrix_lib.         (line   6")
+    ("qmatrix_lib" . "qmatrix_lib.         (line   6")
+    ("qminor" . "qminor.              (line   6")
+    ("qrds" . "qrds.                (line   6")
+    ("qring" . "Miscellaneous oddities")
+    ("qring (plural)" . "qring (plural).      (line   6")
+    ("qring declaration" . "qring declaration.   (line   6")
+    ("qring declaration (plural)" . "qring declaration (plural)")
+    ("qring related functions (plural)" . "qring related functions (plural)")
+    ("qringNF, option" . "option.              (line 105")
+    ("qslimgb" . "qslimgb.             (line   6")
+    ("Qso3Casimir" . "Qso3Casimir.         (line   6")
+    ("quadraticSieve" . "quadraticSieve.      (line   6")
+    ("quantMat" . "quantMat.            (line   6")
+    ("quickclass" . "quickclass.          (line   6")
+    ("quit" . "quit.                (line   6")
+    ("quote" . "quote.               (line   6")
+    ("Quotient" . "Quotient.            (line   6")
+    ("quotient" . "quotient.            (line   6")
+    ("quotient (plural)" . "quotient (plural).   (line   6")
+    ("QuotientEquations" . "QuotientEquations.   (line   6")
+    ("quotientLatticeBasis" . "quotientLatticeBasis")
+    ("quotientMain" . "quotientMain.        (line   6")
+    ("quotientMon" . "quotientMon.         (line   6")
+    ("quotients" . "gitfan_lib.          (line  24")
+    ("rad_con" . "rad_con.             (line   6")
+    ("radical" . "radical.             (line   6")
+    ("radicalEHV" . "radicalEHV.          (line   6")
+    ("radicalMemberShip" . "radicalMemberShip.   (line   6")
+    ("radicalMon" . "radicalMon.          (line   6")
+    ("radicalZ" . "radicalZ.            (line   6")
+    ("randcharpoly" . "randcharpoly.        (line   6")
+    ("randlinpoly" . "randlinpoly.         (line   6")
+    ("random" . "random.              (line   6")
+    ("random number generator, seed" . "system.              (line  88")
+    ("random.lib" . "random_lib.          (line   6")
+    ("random_lib" . "random_lib.          (line   6")
+    ("randomBinomial" . "randomBinomial.      (line   6")
+    ("randomCheck" . "randomCheck.         (line   6")
+    ("randomid" . "randomid.            (line   6")
+    ("randomLast" . "randomLast.          (line   6")
+    ("randommat" . "randommat.           (line   6")
+    ("randomPoint" . "randomPoint.         (line   6")
+    ("randomPoly" . "randomPoly.          (line   6")
+    ("rank" . "rank.                (line   6")
+    ("ratgb.lib" . "ratgb_lib.           (line   6")
+    ("ratgb_lib" . "ratgb_lib.           (line   6")
+    ("Rational curves" . "paraplanecurves_lib. (line  73")
+    ("rational curves, rational parametrization of rational curves." . "paraPlaneCurve")
+    ("rational normal curve, projection." . "rncItProjEven.      (line  30")
+    ("rational solutions" . "dmodloc_lib.         (line  93")
+    ("rational univariate projection" . "randcharpoly.        (line  24")
+    ("rationalPointConic" . "rationalPointConic.  (line   6")
+    ("ratSol" . "ratSol.              (line   6")
+    ("ratstd" . "ratstd.              (line   6")
+    ("rays" . "rays.                (line   6")
+    ("re2squ" . "re2squ.              (line   6")
+    ("read" . "read.                (line   6")
+    ("reading, option" . "option.              (line 192")
+    ("readline" . "Preface.             (line   6")
+    ("readNmzData" . "readNmzData.         (line   6")
+    ("real" . "Rings and orderings. (line  26")
+    ("real roots, univariate polynomial" . "rootsur_lib.         (line  48")
+    ("real roots, univariate projection" . "rootsmr_lib.         (line  45")
+    ("real roots,sign conditions" . "signcond_lib.        (line  29")
+    ("realclassify" . "realclassify.        (line   6")
+    ("realclassify.lib" . "realclassify_lib.    (line   6")
+    ("realclassify_lib" . "realclassify_lib.    (line   6")
+    ("realizationDim" . "realizationDim.      (line   6")
+    ("realizationDimPoly" . "realizationDimPoly.  (line   6")
+    ("realizationMatroids.lib" . "realizationMatroids_lib")
+    ("realizationMatroids_lib" . "realizationMatroids_lib")
+    ("realmorsesplit" . "realmorsesplit.      (line   6")
+    ("realpoly" . "realpoly.            (line   6")
+    ("realrad" . "realrad.             (line   6")
+    ("realrad.lib" . "realrad_lib.         (line   6")
+    ("realrad_lib" . "realrad_lib.         (line   6")
+    ("realzero" . "realzero.            (line   6")
+    ("recursive_boolean_poly" . "recursive_boolean_poly")
+    ("recursive_from_boolean_poly" . "recursive_from_boolean_poly")
+    ("redefine, option" . "option.              (line 195")
+    ("redSB, option" . "option.              (line 108")
+    ("redTail, option" . "option.              (line 112")
+    ("redThrough, option" . "option.              (line 118")
+    ("reduce" . "central_lib.         (line  19")
+    ("reduce (plural)" . "reduce (plural).     (line   6")
+    ("reduced standard basis" . "option.              (line 108")
+    ("reduction" . "reduction.           (line   6")
+    ("ReesAlgebra" . "ReesAlgebra.         (line   6")
+    ("reesclos.lib" . "reesclos_lib.        (line   6")
+    ("reesclos_lib" . "reesclos_lib.        (line   6")
+    ("reference" . "countedref.          (line   6")
+    ("reference declarations" . "reference declarations")
+    ("reference expressions" . "reference expressions")
+    ("reference operations" . "reference and shared operations")
+    ("reference related functions" . "reference and shared related functions")
+    ("References" . "References.          (line   6")
+    ("References (plural)" . "References (plural). (line   6")
+    ("regCM" . "regCM.               (line   6")
+    ("regIdeal" . "regIdeal.            (line   6")
+    ("regMonCurve" . "regMonCurve.         (line   6")
+    ("regularity" . "Syzygies and resolutions")
+    ("reiffen" . "reiffen.             (line   6")
+    ("ReJunkUseHomo" . "ReJunkUseHomo.       (line   6")
+    ("rel_orbit_variety" . "rel_orbit_variety.   (line   6")
+    ("relations" . "perron_lib.          (line  21")
+    ("relative_orbit_variety" . "relative_orbit_variety")
+    ("relativeInteriorPoint" . "relativeInteriorPoint")
+    ("Release Notes" . "Release Notes.       (line   6")
+    ("relweight" . "relweight.           (line   6")
+    ("remainder" . "remainder.           (line   6")
+    ("remainderMain" . "remainderMain.       (line   6")
+    ("removeCone" . "removeCone.          (line   6")
+    ("removepower" . "removepower.         (line   6")
+    ("repart" . "repart.              (line   6")
+    ("replace" . "replace.             (line   6")
+    ("representation, math objects" . "Representation of mathematical objects")
+    ("res" . "res.                 (line   6")
+    ("resbinomial.lib" . "resbinomial_lib.     (line  15")
+    ("resbinomial_lib" . "resbinomial_lib.     (line  15")
+    ("reservedName" . "reservedName.        (line   6")
+    ("resfunction" . "resfunction.         (line   6")
+    ("resgraph.lib" . "resgraph_lib.        (line   6")
+    ("resgraph_lib" . "resgraph_lib.        (line   6")
+    ("resjung.lib" . "resjung_lib.         (line   6")
+    ("resjung_lib" . "resjung_lib.         (line   6")
+    ("reslist" . "reslist.             (line   6")
+    ("resolution" . "purityfiltration_lib")
+    ("Resolution" . "Resolution.          (line   6")
+    ("resolution (plural)" . "resolution (plural). (line   6")
+    ("resolution declarations" . "resolution declarations")
+    ("resolution declarations (plural)" . "resolution declarations (plural)")
+    ("resolution expressions" . "resolution expressions")
+    ("resolution expressions (plural)" . "resolution expressions (plural)")
+    ("resolution graph" . "alexpoly_lib.        (line  40")
+    ("Resolution of singularities" . "Resolution of singularities")
+    ("resolution related functions" . "resolution related functions")
+    ("resolution related functions (plural)" . "resolution related functions (plural)")
+    ("resolution, computation of" . "res.                 (line   8")
+    ("Resolution, free" . "Free resolution.     (line   6")
+    ("resolution, hilbert-driven" . "hres.                (line   6")
+    ("resolution, La Scala's method" . "lres.                (line   6")
+    ("resolutiongraph" . "resolutiongraph.     (line   6")
+    ("resolve" . "resolve.             (line   6")
+    ("resolve.lib" . "resolve_lib.         (line   6")
+    ("resolve_lib" . "resolve_lib.         (line   6")
+    ("ResTree" . "ResTree.             (line   6")
+    ("restriction of" . "dmodapp_lib.         (line 104")
+    ("restrictionIdeal" . "restrictionIdeal.    (line   6")
+    ("restrictionModule" . "restrictionModule.   (line   6")
+    ("resultant" . "resultant.           (line   6")
+    ("reszeta.lib" . "reszeta_lib.         (line   6")
+    ("reszeta_lib" . "reszeta_lib.         (line   6")
+    ("return" . "return.              (line   6")
+    ("return type of procedures" . "Return type of procedures")
+    ("returnSB, option" . "option.              (line  52")
+    ("reverse" . "reverse.             (line   6")
+    ("reverse lexicographical ordering" . "Global orderings.    (line  14")
+    ("reynolds_molien" . "reynolds_molien.     (line   6")
+    ("ReynoldsImage" . "ReynoldsImage.       (line   6")
+    ("ReynoldsOperator" . "ReynoldsOperator.    (line   6")
+    ("rho" . "rho.                 (line   6")
+    ("Right Groebner bases and syzygies" . "Right Groebner bases and syzygies")
+    ("rightInverse" . "rightInverse.        (line   6")
+    ("rightKernel" . "rightKernel.         (line   6")
+    ("rightModulo" . "rightModulo.         (line   6")
+    ("rightNF" . "rightNF.             (line   6")
+    ("rightNFWeyl" . "rightNFWeyl.         (line   6")
+    ("rightStd" . "rightStd.            (line   6")
+    ("ring" . "ring.                (line   6")
+    ("ring (plural)" . "ring (plural).       (line   6")
+    ("ring declarations" . "ring declarations.   (line   6")
+    ("ring declarations (plural)" . "ring declarations (plural)")
+    ("ring operations" . "ring operations.     (line   6")
+    ("ring operations (plural)" . "ring operations (plural)")
+    ("ring related functions" . "ring related functions")
+    ("ring related functions (plural)" . "ring related functions (plural)")
+    ("ring, rings" . "setglobalrings.      (line  26")
+    ("ring.lib" . "ring_lib.            (line   6")
+    ("ring_lib" . "ring_lib.            (line   6")
+    ("ringlist" . "ringlist.            (line   6")
+    ("ringlist (plural)" . "ringlist (plural).   (line   6")
+    ("Rings and orderings" . "Rings and orderings. (line   6")
+    ("Rings and standard bases" . "Rings and standard bases")
+    ("ringtensor" . "ringtensor.          (line   6")
+    ("ringweights" . "ringweights.         (line   6")
+    ("rinvar.lib" . "rinvar_lib.          (line   6")
+    ("rinvar_lib" . "rinvar_lib.          (line   6")
+    ("rm_unitcol" . "rm_unitcol.          (line   6")
+    ("rm_unitrow" . "rm_unitrow.          (line   6")
+    ("rMacaulay" . "rMacaulay.           (line   6")
+    ("rmNmzFiles" . "rmNmzFiles.          (line   6")
+    ("rmx" . "rmx.                 (line   6")
+    ("rncAntiCanonicalMap" . "rncAntiCanonicalMap. (line   6")
+    ("rncItProjEven" . "rncItProjEven.       (line   6")
+    ("rncItProjOdd" . "rncItProjOdd.        (line   6")
+    ("root of Bernstein-Sato polynomial" . "dmod_lib.            (line 109")
+    ("rootofUnity" . "rootofUnity.         (line   6")
+    ("roots" . "roots.               (line   6")
+    ("rootsMain" . "rootsMain.           (line   6")
+    ("rootsModp" . "rootsModp.           (line   6")
+    ("rootsmr.lib" . "rootsmr_lib.         (line   6")
+    ("rootsmr_lib" . "rootsmr_lib.         (line   6")
+    ("rootsur.lib" . "rootsur_lib.         (line   6")
+    ("rootsur_lib" . "rootsur_lib.         (line   6")
+    ("round" . "round.               (line   6")
+    ("rowred" . "rowred.              (line   6")
+    ("rp, global ordering" . "Global orderings.    (line  14")
+    ("rtimer" . "rtimer.              (line   6")
+    ("Running SINGULAR under Emacs" . "Running SINGULAR under Emacs")
+    ("rvalue" . "No rvalue of increments and assignments")
+    ("rvar" . "rvar.                (line   6")
+    ("sa_poly_reduce" . "sa_poly_reduce.      (line   6")
+    ("sa_reduce" . "sa_reduce.           (line   6")
+    ("safeVarName" . "safeVarName.         (line   6")
+    ("sagbi" . "sagbi.               (line   6")
+    ("sagbi.lib" . "sagbi_lib.           (line   6")
+    ("sagbi_lib" . "sagbi_lib.           (line   6")
+    ("sagbiPart" . "sagbiPart.           (line   6")
+    ("sagbiReduce" . "sagbiReduce.         (line   6")
+    ("sagbiSPoly" . "sagbiSPoly.          (line   6")
+    ("salida" . "salida.              (line   6")
+    ("sameComponent" . "sameComponent.       (line   6")
+    ("sameQ" . "sameQ.               (line   6")
+    ("Sannfs" . "Sannfs.              (line   6")
+    ("SannfsBFCT" . "SannfsBFCT.          (line   6")
+    ("Sannfslog" . "Sannfslog.           (line   6")
+    ("SannfsVar" . "SannfsVar.           (line   6")
+    ("sat" . "sat.                 (line   6")
+    ("satiety" . "satiety.             (line   6")
+    ("Saturation" . "Saturation.          (line   6")
+    ("SCA" . "Graded commutative algebras (SCA)")
+    ("scalarProd" . "scalarProd.          (line   6")
+    ("scheme" . "scheme.              (line   6")
+    ("Scho\"nemann, Hans" . "Preface.             (line 144")
+    ("Schoof" . "Schoof.              (line   6")
+    ("SDB breakpoint" . "Source code debugger")
+    ("SDB debugger" . "Source code debugger")
+    ("sdb, source code debugger" . "Source code debugger")
+    ("SDLoc" . "SDLoc.               (line   6")
+    ("secondary fan" . "oldpolymake_lib.     (line  69")
+    ("secondary polytope" . "oldpolymake_lib.     (line  69")
+    ("secondary_and_irreducibles_no_molien" . "secondary_and_irreducibles_no_molien")
+    ("secondary_char0" . "secondary_char0.     (line   6")
+    ("secondary_charp" . "secondary_charp.     (line   6")
+    ("secondary_no_molien" . "secondary_no_molien. (line   6")
+    ("secondary_not_cohen_macaulay" . "secondary_not_cohen_macaulay")
+    ("secondaryFan" . "secondaryFan.        (line   6")
+    ("secondaryPolytope" . "secondaryPolytope.   (line   6")
+    ("select" . "select.              (line   6")
+    ("select1" . "select1.             (line   6")
+    ("semiCMcod2" . "semiCMcod2.          (line   6")
+    ("semidiv" . "semidiv.             (line   6")
+    ("semigroup" . "charexp2generators.  (line  19")
+    ("semigroup of values" . "invariants.          (line  47")
+    ("semigroupGenerator" . "semigroupGenerator.  (line   6")
+    ("separateHNE" . "separateHNE.         (line   6")
+    ("separator" . "separator.           (line   6")
+    ("serreRelations" . "serreRelations.      (line   6")
+    ("setBaseMultigrading" . "setBaseMultigrading. (line   6")
+    ("setenv" . "system.              (line  45")
+    ("setglobalrings" . "setglobalrings.      (line   6")
+    ("setinitials" . "setinitials.         (line   6")
+    ("setLetterplaceAttributes" . "setLetterplaceAttributes")
+    ("setLinearForms" . "setLinearForms.      (line   6")
+    ("setModuleGrading" . "setModuleGrading.    (line   6")
+    ("setMultiplicity" . "setMultiplicity.     (line   6")
+    ("setNmzDataPath" . "setNmzDataPath.      (line   6")
+    ("setNmzExecPath" . "setNmzExecPath.      (line   6")
+    ("setNmzFilename" . "setNmzFilename.      (line   6")
+    ("setNmzOption" . "setNmzOption.        (line   6")
+    ("setring" . "setring.             (line   6")
+    ("Setting up a G-algebra" . "G-algebras.          (line  51")
+    ("sh" . "system.              (line  26")
+    ("ShanksMestre" . "ShanksMestre.        (line   6")
+    ("shared" . "countedref.          (line   6")
+    ("shared declarations" . "shared declarations. (line   6")
+    ("shared expressions" . "shared expressions.  (line   6")
+    ("shared operations" . "reference and shared operations")
+    ("shared related functions" . "reference and shared related functions")
+    ("sheaf cohomology" . "sheafcoh_lib.        (line  32")
+    ("sheafCoh" . "sheafCoh.            (line   6")
+    ("sheafcoh.lib" . "sheafcoh_lib.        (line   6")
+    ("sheafcoh_lib" . "sheafcoh_lib.        (line   6")
+    ("sheafCohBGG" . "sheafCohBGG.         (line   6")
+    ("sheafCohBGG2" . "sheafCohBGG2.        (line   6")
+    ("shiftPoly" . "shiftPoly.           (line   6")
+    ("short" . "short.               (line   6")
+    ("show" . "show.                (line   6")
+    ("showBO" . "showBO.              (line   6")
+    ("showDataTypes" . "showDataTypes.       (line   6")
+    ("showgrades" . "showgrades.          (line   6")
+    ("showNmzOptions" . "showNmzOptions.      (line   6")
+    ("showNuminvs" . "showNuminvs.         (line   6")
+    ("showrecursive" . "showrecursive.       (line   6")
+    ("sickle" . "sickle.              (line   6")
+    ("signatureBrieskorn" . "signatureBrieskorn.  (line   6")
+    ("signatureL" . "signatureL.          (line   6")
+    ("signatureLqf" . "signatureLqf.        (line   6")
+    ("signatureNemethi" . "signatureNemethi.    (line   6")
+    ("signaturePuiseux" . "signaturePuiseux.    (line   6")
+    ("signcnd" . "signcnd.             (line   6")
+    ("signcond.lib" . "signcond_lib.        (line   6")
+    ("signcond_lib" . "signcond_lib.        (line   6")
+    ("simplesolver" . "simplesolver.        (line   6")
+    ("simplex" . "simplex.             (line   6")
+    ("simplexOut" . "simplexOut.          (line   6")
+    ("simplify" . "simplify.            (line   6")
+    ("SimplifyIdeal" . "SimplifyIdeal.       (line   6")
+    ("simplifyRat" . "simplifyRat.         (line   6")
+    ("sing.lib" . "sing_lib.            (line   6")
+    ("sing4ti2.lib" . "sing4ti2_lib.        (line   6")
+    ("sing4ti2_lib" . "sing4ti2_lib.        (line   6")
+    ("sing_lib" . "sing_lib.            (line   6")
+    ("Singular" . "system.              (line  72")
+    ("SINGULAR libraries" . "SINGULAR libraries.  (line   6")
+    ("singular locus of D-module" . "dmodloc_lib.         (line  93")
+    ("Singular, customization of Emacs user interface" . "Customization of the Emacs interface")
+    ("Singular, demo mode" . "Demo mode.           (line   6")
+    ("Singular, editing input files with Emacs" . "Editing SINGULAR input files with Emacs")
+    ("Singular, important commands of Emacs interface" . "Top 20 Emacs commands")
+    ("Singular, running within Emacs" . "Running SINGULAR under Emacs")
+    ("Singular2bertini" . "Singular2bertini.    (line   6")
+    ("SINGULARHIST" . "Editing input.       (line   6")
+    ("singularities" . "spectrumnd.          (line  26")
+    ("Singularities" . "Singularities.       (line   6")
+    ("singularities, resolution of" . "Resolution of singularities")
+    ("singularity" . "singularity.         (line   6")
+    ("Singularity Theory" . "Singularity Theory.  (line   6")
+    ("SingularLib" . "system.              (line  76")
+    ("singularrc" . "Startup sequence.    (line  10")
+    ("size" . "Miscellaneous oddities")
+    ("Skeletons for parallelization" . "parallelWaitAll.     (line  23")
+    ("skewmat" . "skewmat.             (line   6")
+    ("sleep" . "status.              (line   6")
+    ("slimgb" . "slim Groebner bases. (line   6")
+    ("slimgb (plural)" . "slimgb (plural).     (line   6")
+    ("slocus" . "slocus.              (line   6")
+    ("smith" . "smith.               (line   6")
+    ("Smith form" . "jacobson_lib.        (line  58")
+    ("Smith normal form" . "jacobson_lib.        (line  58")
+    ("smithNormalForm" . "smithNormalForm.     (line   6")
+    ("SolowayStrassen" . "SolowayStrassen.     (line   6")
+    ("solutionsMod2" . "solutionsMod2.       (line   6")
+    ("solve" . "solve.               (line   6")
+    ("solve a linear equation system A*x = b via the LU-decomposition of A" . "lusolve")
+    ("solve.lib" . "solve_lib.           (line   6")
+    ("solve_IP" . "solve_IP.            (line   6")
+    ("solve_lib" . "solve_lib.           (line   6")
+    ("solvelinearpart" . "solvelinearpart.     (line   6")
+    ("solveTInitialFormPar" . "solveTInitialFormPar")
+    ("Solving systems of polynomial equations" . "Solving systems of polynomial equations")
+    ("sort" . "sort.                (line   6")
+    ("sortandmap" . "sortandmap.          (line   6")
+    ("sortier" . "sortier.             (line   6")
+    ("sortIntvec" . "sortIntvec.          (line   6")
+    ("sortvars" . "sortvars.            (line   6")
+    ("sortvec" . "sortvec.             (line   6")
+    ("Source code debugger, invocation" . "Command line options")
+    ("source code debugger, sdb" . "Source code debugger")
+    ("Space curve singularities, branches of" . "Branches of space curve singularities")
+    ("spadd" . "spadd.               (line   6")
+    ("span" . "span.                (line   6")
+    ("sparseHomogIdeal" . "sparseHomogIdeal.    (line   6")
+    ("sparseid" . "sparseid.            (line   6")
+    ("sparsemat" . "sparsemat.           (line   6")
+    ("sparsematrix" . "sparsematrix.        (line   6")
+    ("sparsepoly" . "sparsepoly.          (line   6")
+    ("sparsetriag" . "sparsetriag.         (line   6")
+    ("spcurve.lib" . "spcurve_lib.         (line   6")
+    ("spcurve_lib" . "spcurve_lib.         (line   6")
+    ("Special characters" . "Special characters.  (line   6")
+    ("special characters, non-english" . "Limitations.         (line  53")
+    ("spectral pairs" . "goodBasis.           (line  22")
+    ("spectralNeg" . "spectralNeg.         (line   6")
+    ("spectrum" . "spectrumnd.          (line  26")
+    ("spectrum.lib" . "spectrum_lib.        (line   6")
+    ("spectrum_lib" . "spectrum_lib.        (line   6")
+    ("spectrumnd" . "spectrumnd.          (line   6")
+    ("spgamma" . "spgamma.             (line   6")
+    ("spgeomgenus" . "spgeomgenus.         (line   6")
+    ("spissemicont" . "spissemicont.        (line   6")
+    ("split" . "split.               (line   6")
+    ("splitPolygon" . "splitPolygon.        (line   6")
+    ("splitring" . "splitring.           (line   6")
+    ("splitting" . "splitting.           (line   6")
+    ("Splitting lemma" . "realmorsesplit.      (line  23")
+    ("spmilnor" . "spmilnor.            (line   6")
+    ("spmul" . "spmul.               (line   6")
+    ("spnf" . "spnf.                (line   6")
+    ("spoly" . "spoly.               (line   6")
+    ("sppairs" . "sppairs.             (line   6")
+    ("sppnf" . "sppnf.               (line   6")
+    ("sppprint" . "sppprint.            (line   6")
+    ("spprint" . "spprint.             (line   6")
+    ("sprintf" . "sprintf.             (line   6")
+    ("spsemicont" . "spsemicont.          (line   6")
+    ("spsub" . "spsub.               (line   6")
+    ("sqfrNorm" . "sqfrNorm.            (line   6")
+    ("sqfrNormMain" . "sqfrNormMain.        (line   6")
+    ("sqr" . "sqr.                 (line   6")
+    ("sqrfree" . "sqrfree.             (line   6")
+    ("squarefree" . "squarefree.          (line   6")
+    ("squareRoot" . "squareRoot.          (line   6")
+    ("sres" . "sres.                (line   6")
+    ("Ssi file links" . "Ssi file links.      (line   6")
+    ("Ssi links" . "Ssi links.           (line   6")
+    ("Ssi tcp links" . "Ssi tcp links.       (line   6")
+    ("StabEqn" . "StabEqn.             (line   6")
+    ("StabEqnId" . "StabEqnId.           (line   6")
+    ("StabOrder" . "StabOrder.           (line   6")
+    ("staircase" . "staircase.           (line   6")
+    ("standard" . "standard.            (line   6")
+    ("Standard bases" . "Standard bases.      (line   6")
+    ("Standard Bases" . "Computing Groebner and Standard Bases")
+    ("standard.lib" . "standard_lib.        (line  11")
+    ("standard_lib" . "standard_lib.        (line  11")
+    ("startNmz" . "startNmz.            (line   6")
+    ("StartOrderingV" . "StartOrderingV.      (line   6")
+    ("Startup sequence" . "Startup sequence.    (line   6")
+    ("static procedures" . "Procedure definition")
+    ("status" . "status.              (line   6")
+    ("std" . "groebner and std.    (line   6")
+    ("std (plural)" . "std (plural).        (line   6")
+    ("stdfglm" . "stdfglm.             (line   6")
+    ("stdhilb" . "stdhilb.             (line   6")
+    ("stratify" . "stratify.            (line   6")
+    ("stratify.lib" . "stratify_lib.        (line   6")
+    ("stratify_lib" . "stratify_lib.        (line   6")
+    ("string" . "Miscellaneous oddities")
+    ("string declarations" . "string declarations. (line   6")
+    ("string expressions" . "string expressions.  (line   6")
+    ("string operations" . "string operations.   (line   6")
+    ("string related functions" . "string related functions")
+    ("string type cast" . "string type cast.    (line   6")
+    ("StringF" . "StringF.             (line   6")
+    ("stripHNE" . "stripHNE.            (line   6")
+    ("sturm" . "sturm.               (line   6")
+    ("sturmha" . "sturmha.             (line   6")
+    ("sturmhaseq" . "sturmhaseq.          (line   6")
+    ("sturmquery" . "sturmquery.          (line   6")
+    ("sturmseq" . "sturmseq.            (line   6")
+    ("submat" . "submat.              (line   6")
+    ("subrInterred" . "subrInterred.        (line   6")
+    ("subst" . "subst.               (line   6")
+    ("subst (plural)" . "subst (plural).      (line   6")
+    ("substitute" . "substitute.          (line   6")
+    ("sugarCrit, option" . "option.              (line 125")
+    ("sum" . "sum.                 (line   6")
+    ("sumlist" . "sumlist.             (line   6")
+    ("super-commutative algebras" . "Graded commutative algebras (SCA)")
+    ("superCommutative" . "superCommutative.    (line   6")
+    ("surf.lib" . "surf_lib.            (line   6")
+    ("surf_lib" . "surf_lib.            (line   6")
+    ("surfacesignature.lib" . "surfacesignature_lib")
+    ("surfacesignature_lib" . "surfacesignature_lib")
+    ("surfer" . "surfer.              (line   6")
+    ("surfex" . "Preface.             (line   6")
+    ("surfex.lib" . "surfex_lib.          (line   6")
+    ("surfex_lib" . "surfex_lib.          (line   6")
+    ("SuSE, ESingular bug" . "Unix installation instructions")
+    ("suspend" . "status.              (line   6")
+    ("SV-decoding algorithm" . "decodeSV.            (line  25")
+    ("SV-decoding algorithm, preprocessing" . "prepSV.              (line  51")
+    ("swap" . "swap.                (line   6")
+    ("switch" . "No case or switch statement")
+    ("sym_gauss" . "sym_gauss.           (line   6")
+    ("Symbolic-numerical solving" . "Symbolic-numerical solving")
+    ("SymGroup" . "SymGroup.            (line   6")
+    ("symmat" . "symmat.              (line   6")
+    ("symmetric basis" . "symmetricBasis.      (line  18")
+    ("symmetric power" . "symmetricPower.      (line  18")
+    ("symmetricBasis" . "symmetricBasis.      (line   6")
+    ("symmetricPower" . "symmetricPower.      (line   6")
+    ("symmfunc" . "symmfunc.            (line   6")
+    ("symmStd" . "symmStd.             (line   6")
+    ("syModStd" . "syModStd.            (line   6")
+    ("symodstd.lib" . "symodstd_lib.        (line   6")
+    ("symodstd_lib" . "symodstd_lib.        (line   6")
+    ("symsignature" . "symsignature.        (line   6")
+    ("syndrome" . "syndrome.            (line   6")
+    ("sys_code" . "sys_code.            (line   6")
+    ("sysBin" . "sysBin.              (line   6")
+    ("sysCRHT" . "sysCRHT.             (line   6")
+    ("sysCRHTMindist" . "sysCRHTMindist.      (line   6")
+    ("sysFL" . "sysFL.               (line   6")
+    ("sysNewton" . "sysNewton.           (line   6")
+    ("sysQE" . "sysQE.               (line   6")
+    ("system" . "system.              (line   6")
+    ("System and Control Theory" . "System and Control Theory")
+    ("System dependent limitations" . "System dependent limitations")
+    ("System variables" . "System variables.    (line   6")
+    ("system, -" . "system.              (line  80")
+    ("system, -long_option_name" . "system.              (line  83")
+    ("system, -long_option_name=value" . "system.              (line  88")
+    ("system, browsers" . "system.              (line  96")
+    ("system, contributors" . "system.              (line  56")
+    ("system, cpu" . "system.              (line  33")
+    ("system, gen" . "system.              (line  60")
+    ("system, getenv" . "system.              (line  41")
+    ("system, nblocks" . "system.              (line  67")
+    ("system, pid" . "system.              (line  30")
+    ("system, setenv" . "system.              (line  45")
+    ("system, sh" . "system.              (line  26")
+    ("system, Singular" . "system.              (line  72")
+    ("system, SingularLib" . "system.              (line  76")
+    ("system, tty" . "system.              (line  50")
+    ("system, uname" . "system.              (line  37")
+    ("system, version" . "system.              (line  53")
+    ("syz" . "syz.                 (line   6")
+    ("syz (plural)" . "syz (plural).        (line   6")
+    ("Syzygies and resolutions" . "Syzygies and resolutions")
+    ("Syzygies and resolutions (plural)" . "Syzygies and resolutions (plural)")
+    ("T1" . "T1 and T2.           (line   6")
+    ("T2" . "T1 and T2.           (line   6")
+    ("T_1" . "T_1.                 (line   6")
+    ("T_12" . "T_12.                (line   6")
+    ("T_2" . "T_2.                 (line   6")
+    ("tab" . "tab.                 (line   6")
+    ("tail" . "tail.                (line   6")
+    ("tame polynomial" . "goodBasis.           (line  22")
+    ("tangentcone" . "tangentcone.         (line   6")
+    ("tangentGens" . "tangentGens.         (line   6")
+    ("tau_es" . "tau_es.              (line   6")
+    ("tau_es2" . "tau_es2.             (line   6")
+    ("tDetropicalise" . "tDetropicalise.      (line   6")
+    ("Teaching" . "Teaching.            (line   6")
+    ("teachstd.lib" . "teachstd_lib.        (line   6")
+    ("teachstd_lib" . "teachstd_lib.        (line   6")
+    ("Template for writing a library" . "template_lib.        (line   6")
+    ("template.lib" . "template_lib.        (line 128")
+    ("template_lib" . "template_lib.        (line   6")
+    ("tensor" . "tensor.              (line   6")
+    ("tensorMod" . "tensorMod.           (line   6")
+    ("term orderings" . "General definitions for orderings")
+    ("term orderings introduction" . "Introduction to orderings")
+    ("TestJMark" . "TestJMark.           (line   6")
+    ("testNCfac" . "testNCfac.           (line   6")
+    ("testParametrization" . "testParametrization. (line   6")
+    ("testPointConic" . "testPointConic.      (line   6")
+    ("testPrimary" . "testPrimary.         (line   6")
+    ("tex" . "tex.                 (line   6")
+    ("texcoef" . "texcoef.             (line   6")
+    ("texdemo" . "texdemo.             (line   6")
+    ("texDrawBasic" . "texDrawBasic.        (line   6")
+    ("texDrawNewtonSubdivision" . "texDrawNewtonSubdivision")
+    ("texDrawTriangulation" . "texDrawTriangulation")
+    ("texDrawTropical" . "texDrawTropical.     (line   6")
+    ("texfactorize" . "texfactorize.        (line   6")
+    ("texmap" . "texmap.              (line   6")
+    ("texMatrix" . "texMatrix.           (line   6")
+    ("texname" . "texname.             (line   6")
+    ("texNumber" . "texNumber.           (line   6")
+    ("texobj" . "texobj.              (line   6")
+    ("texpoly" . "texpoly.             (line   6")
+    ("texPolynomial" . "texPolynomial.       (line   6")
+    ("texproc" . "texproc.             (line   6")
+    ("texring" . "texring.             (line   6")
+    ("the first alternative algorithm" . "awalk1.              (line  24")
+    ("The fractal walk algorithm" . "fwalk.               (line  20")
+    ("The online help system" . "The online help system")
+    ("The SINGULAR language" . "The SINGULAR language")
+    ("The Tran algorithm" . "twalk.               (line  20")
+    ("time limit on computations" . "groebner.            (line  52")
+    ("timeFactorize" . "timeFactorize.       (line   6")
+    ("timer" . "timer.               (line   6")
+    ("timer resolution, setting the" . "system.              (line  88")
+    ("timeStd" . "timeStd.             (line   6")
+    ("timestep" . "timestep.            (line   6")
+    ("tInitialForm" . "tInitialForm.        (line   6")
+    ("tInitialFormPar" . "tInitialFormPar.     (line   6")
+    ("tInitialFormParMax" . "tInitialFormParMax.  (line   6")
+    ("tInitialIdeal" . "tInitialIdeal.       (line   6")
+    ("tjurina" . "tjurina.             (line   6")
+    ("Tjurina" . "Tjurina.             (line   6")
+    ("Tjurina number" . "deltaLoc.            (line  36")
+    ("tmatrix" . "tmatrix.             (line   6")
+    ("tolessvars" . "tolessvars.          (line   6")
+    ("Top 20 Emacs commands" . "Top 20 Emacs commands")
+    ("topological invariants" . "charexp2conductor.   (line  18")
+    ("Tor" . "Tor.                 (line   6")
+    ("toric ideals" . "Toric ideals.        (line   6")
+    ("Toric ideals and integer programming" . "Toric ideals and integer programming")
+    ("toric.lib" . "toric_lib.           (line   6")
+    ("toric_ideal" . "toric_ideal.         (line   6")
+    ("toric_lib" . "toric_lib.           (line   6")
+    ("toric_std" . "toric_std.           (line   6")
+    ("torusInvariants" . "torusInvariants.     (line   6")
+    ("total multiplicities" . "alexpoly_lib.        (line  40")
+    ("totalmultiplicities" . "totalmultiplicities. (line   6")
+    ("TRACE" . "TRACE var.           (line   6")
+    ("trace" . "trace.               (line   6")
+    ("tracemult" . "tracemult.           (line   6")
+    ("transpose" . "transpose.           (line   6")
+    ("trapezoid" . "trapezoid.           (line   6")
+    ("triagmatrix" . "triagmatrix.         (line   6")
+    ("triang.lib" . "triang_lib.          (line   6")
+    ("triang_lib" . "triang_lib.          (line   6")
+    ("triang_solve" . "triang_solve.        (line   6")
+    ("triangL" . "triangL.             (line   6")
+    ("triangL_solve" . "triangL_solve.       (line   6")
+    ("triangLf_solve" . "triangLf_solve.      (line   6")
+    ("triangLfak" . "triangLfak.          (line   6")
+    ("triangM" . "triangM.             (line   6")
+    ("triangM_solve" . "triangM_solve.       (line   6")
+    ("triangMH" . "triangMH.            (line   6")
+    ("triangulations" . "triangulations.      (line   6")
+    ("Tricks and pitfalls" . "Tricks and pitfalls. (line   6")
+    ("triMNewton" . "triMNewton.          (line   6")
+    ("tropical curves" . "tropical_lib.        (line 165")
+    ("Tropical Geometry" . "Tropical Geometry.   (line   6")
+    ("tropical polynomials" . "tropical_lib.        (line 165")
+    ("tropical.lib" . "tropical_lib.        (line   6")
+    ("tropical_lib" . "tropical_lib.        (line   6")
+    ("tropicalCurve" . "tropicalCurve.       (line   6")
+    ("tropicalise" . "tropicalise.         (line   6")
+    ("tropicaliseSet" . "tropicaliseSet.      (line   6")
+    ("tropicalJInvariant" . "tropicalJInvariant.  (line   6")
+    ("tropicalLifting" . "tropicalLifting.     (line   6")
+    ("tropicalSubst" . "tropicalSubst.       (line   6")
+    ("truncate" . "truncate.            (line   6")
+    ("truncated module" . "truncateFast.        (line  28")
+    ("truncateFast" . "truncateFast.        (line   6")
+    ("tst_ncfactor" . "tst_ncfactor.        (line   6")
+    ("tty" . "system.              (line  50")
+    ("twalk" . "twalk.               (line   6")
+    ("twostd" . "twostd.              (line   6")
+    ("type" . "type.                (line   6")
+    ("Type casting" . "Type conversion and casting")
+    ("Type conversion" . "Type conversion and casting")
+    ("type,custom" . "Definition of a user defined type")
+    ("typeof" . "typeof.              (line   6")
+    ("Typesetting of help and info strings" . "Typesetting of help and info strings")
+    ("u" . "u.                   (line   6")
+    ("U_D_O" . "U_D_O.               (line   6")
+    ("uname" . "system.              (line  37")
+    ("unipotent groups" . "orbitparam_lib.      (line  49")
+    ("uniquePoint" . "uniquePoint.         (line   6")
+    ("unitmat" . "unitmat.             (line   6")
+    ("univariate" . "univariate.          (line   6")
+    ("univarpoly" . "univarpoly.          (line   6")
+    ("Unix installation" . "Unix installation instructions")
+    ("unknown syndrome" . "Decoding method based on quadratic equations")
+    ("untyped definitions" . "ideal (plural).      (line   6")
+    ("updatePairs" . "updatePairs.         (line   6")
+    ("UpOneMatrix" . "UpOneMatrix.         (line   6")
+    ("UpperMonomials" . "UpperMonomials.      (line   6")
+    ("ures_solve" . "ures_solve.          (line   6")
+    ("uressolve" . "uressolve.           (line   6")
+    ("usage, option" . "option.              (line 198")
+    ("UseBertini" . "UseBertini.          (line   6")
+    ("User defined types" . "User defined types.  (line   6")
+    ("user interface, Emacs" . "Emacs user interface")
+    ("V-filtration" . "goodBasis.           (line  22")
+    ("valvars" . "valvars.             (line   6")
+    ("vandermonde" . "vandermonde.         (line   6")
+    ("vanishId" . "vanishId.            (line   6")
+    ("var" . "var.                 (line   6")
+    ("variables" . "variables.           (line   6")
+    ("Variables, indexed" . "Names.               (line   6")
+    ("variablesSorted" . "variablesSorted.     (line   6")
+    ("variablesStandard" . "variablesStandard.   (line   6")
+    ("varNum" . "varNum.              (line   6")
+    ("vars2pars" . "vars2pars.           (line   6")
+    ("varsigns" . "varsigns.            (line   6")
+    ("varstr" . "varstr.              (line   6")
+    ("VarToPar" . "VarToPar.            (line   6")
+    ("vct2str" . "vct2str.             (line   6")
+    ("vdim" . "vdim.                (line   6")
+    ("vdim (plural)" . "vdim (plural).       (line   6")
+    ("vec2poly" . "vec2poly.            (line   6")
+    ("vector" . "vector.              (line   6")
+    ("vector declarations" . "vector declarations. (line   6")
+    ("vector expressions" . "vector expressions.  (line   6")
+    ("vector operations" . "vector operations.   (line   6")
+    ("vector related functions" . "vector related functions")
+    ("verify" . "verify.              (line   6")
+    ("versal" . "versal.              (line   6")
+    ("version" . "system.              (line  53")
+    ("Version string" . "Version string.      (line   6")
+    ("vertices" . "vertices.            (line   6")
+    ("vfilt" . "vfilt.               (line   6")
+    ("view" . "view.                (line   6")
+    ("visual" . "visual.              (line   6")
+    ("Visualization" . "Visualization.       (line   6")
+    ("visualize" . "visualize.           (line   6")
+    ("voice" . "voice.               (line   6")
+    ("vwfilt" . "vwfilt.              (line   6")
+    ("waitall" . "waitall.             (line   6")
+    ("waitfirst" . "waitfirst.           (line   6")
+    ("watchdog" . "watchdog.            (line   6")
+    ("wedge" . "wedge.               (line   6")
+    ("weierstr.lib" . "weierstr_lib.        (line   6")
+    ("weierstr_lib" . "weierstr_lib.        (line   6")
+    ("Weierstrass" . "Weierstrass.         (line   6")
+    ("Weierstrass semigroup" . "brnoeth_lib.         (line  43")
+    ("weierstrassForm" . "weierstrassForm.     (line   6")
+    ("weierstrDiv" . "weierstrDiv.         (line   6")
+    ("weierstrPrep" . "weierstrPrep.        (line   6")
+    ("weight" . "weight.              (line   6")
+    ("weight filtration" . "goodBasis.           (line  22")
+    ("weighted lexicographical ordering" . "Global orderings.    (line  42")
+    ("weighted reverse lexicographical ordering" . "Global orderings")
+    ("weightedRing" . "weightedRing.        (line   6")
+    ("weightKB" . "weightKB.            (line   6")
+    ("weightM, option" . "option.              (line 130")
+    ("Weyl" . "Weyl.                (line   6")
+    ("Weyl algebra" . "dmodvar_lib.         (line  59")
+    ("Weyl closure" . "dmodloc_lib.         (line  93")
+    ("WeylClosure" . "WeylClosure.         (line   6")
+    ("WeylClosure1" . "WeylClosure1.        (line   6")
+    ("whichvariable" . "whichvariable.       (line   6")
+    ("while" . "while.               (line   6")
+    ("Windows installation" . "Windows installation instructions")
+    ("WitSet" . "WitSet.              (line   6")
+    ("WitSupSet" . "WitSupSet.           (line   6")
+    ("WP, global ordering" . "Global orderings.    (line  42")
+    ("wp, global ordering" . "Global orderings.    (line  37")
+    ("write" . "write.               (line   6")
+    ("writeNmzData" . "writeNmzData.        (line   6")
+    ("writeNmzPaths" . "writeNmzPaths.       (line   6")
+    ("Ws, local ordering" . "Local orderings.     (line  39")
+    ("ws, local ordering" . "Local orderings.     (line  33")
+    ("WSemigroup" . "WSemigroup.          (line   6")
+    ("wUnit" . "wUnit.               (line   6")
+    ("wurzel" . "wurzel.              (line   6")
+    ("xchange" . "xchange.             (line   6")
+    ("xdvi" . "xdvi.                (line   6")
+    ("XLsolve" . "XLsolve.             (line   6")
+    ("zdd" . "polybori_lib.        (line  94")
+    ("zdd2poly" . "zdd2poly.            (line   6")
+    ("zero-dimensional" . "qbase.               (line  15")
+    ("zerodec" . "zerodec.             (line   6")
+    ("zeroMod" . "zeroMod.             (line   6")
+    ("zeroOpt" . "zeroOpt.             (line   6")
+    ("zeroRadical" . "zeroRadical.         (line   6")
+    ("zeroSet" . "zeroSet.             (line   6")
+    ("zeroset.lib" . "zeroset_lib.         (line   6")
+    ("zeroset_lib" . "zeroset_lib.         (line   6")
+    ("zetaDL" . "zetaDL.              (line   6")
+    ("ZZsolve" . "ZZsolve.             (line   6")
+    ("{" . "Special characters.  (line  11")
+    ("||" . "boolean operations.  (line   6")
+    ("}" . "Special characters.  (line  11")
+    ("~" . "~.                   (line   6")
+))
diff --git a/emacs/lib-cmpl.el b/emacs/lib-cmpl.el
new file mode 100644
index 0000000..766d7e3
--- /dev/null
+++ b/emacs/lib-cmpl.el
@@ -0,0 +1,180 @@
+(setq singular-standard-libraries-with-categories
+  '(
+     ("real algebra"
+       ("realrad.lib")
+     )
+     ("general"
+       ("decomp.lib")
+     )
+     ("Visualization"
+       ("surfex.lib")
+       ("surf.lib")
+       ("resgraph.lib")
+       ("latex.lib")
+       ("graphics.lib")
+     )
+     ("Tropical Geometry"
+       ("tropical.lib")
+       ("realizationMatroids.lib")
+       ("oldpolymake.lib")
+     )
+     ("Teaching"
+       ("weierstr.lib")
+       ("teachstd.lib")
+       ("rootsur.lib")
+       ("rootsmr.lib")
+       ("hyperel.lib")
+       ("finitediff.lib")
+       ("crypto.lib")
+       ("atkins.lib")
+       ("aksaka.lib")
+     )
+     ("System and Control Theory"
+       ("jacobson.lib")
+       ("control.lib")
+     )
+     ("Symbolic-numerical solving"
+       ("zeroset.lib")
+       ("triang.lib")
+       ("solve.lib")
+       ("signcond.lib")
+       ("presolve.lib")
+       ("ntsolve.lib")
+       ("ffsolve.lib")
+     )
+     ("Singularity Theory"
+       ("curvepar.lib")
+     )
+     ("Singularities"
+       ("surfacesignature.lib")
+       ("spectrum.lib")
+       ("spcurve.lib")
+       ("sing.lib")
+       ("realclassify.lib")
+       ("qhmoduli.lib")
+       ("mondromy.lib")
+       ("hnoether.lib")
+       ("gmssing.lib")
+       ("gmspoly.lib")
+       ("equising.lib")
+       ("deform.lib")
+       ("classifyceq.lib")
+       ("classify.lib")
+       ("arcpoint.lib")
+       ("alexpoly.lib")
+     )
+     ("Resolution of singularities"
+       ("resbinomial.lib")
+     )
+     ("Noncommutative"
+       ("ratgb.lib")
+       ("qmatrix.lib")
+       ("purityfiltration.lib")
+       ("perron.lib")
+       ("nctools.lib")
+       ("ncpreim.lib")
+       ("nchomolog.lib")
+       ("ncfactor.lib")
+       ("ncdecomp.lib")
+       ("ncalg.lib")
+       ("involut.lib")
+       ("gkdim.lib")
+       ("freegb.lib")
+       ("fpadim.lib")
+       ("dmodvar.lib")
+       ("dmodloc.lib")
+       ("dmodapp.lib")
+       ("dmod.lib")
+       ("central.lib")
+       ("bfun.lib")
+     )
+     ("Miscellaneous"
+       ("standard.lib")
+       ("ringgb.lib")
+       ("polybori.lib")
+       ("makedbm.lib")
+       ("help.cnf")
+       ("COPYING")
+     )
+     ("Linear Algebra"
+       ("matrix.lib")
+       ("linalg.lib")
+     )
+     ("Invariant theory"
+       ("stratify.lib")
+       ("rinvar.lib")
+       ("finvar.lib")
+       ("ainvar.lib")
+     )
+     ("General purpose"
+       ("ring.lib")
+       ("random.lib")
+       ("poly.lib")
+       ("parallel.lib")
+       ("kskernel.lib")
+       ("inout.lib")
+       ("grobcov.lib")
+       ("general.lib")
+       ("compregb.lib")
+       ("all.lib")
+     )
+     ("Factorization"
+       ("absfact.lib")
+     )
+     ("Commutative Algebra"
+       ("pointid.lib")
+       ("normaliz.lib")
+       ("monomialideal.lib")
+       ("toric.lib")
+       ("symodstd.lib")
+       ("sing4ti2.lib")
+       ("sheafcoh.lib")
+       ("sagbi.lib")
+       ("resjung.lib")
+       ("reesclos.lib")
+       ("primitiv.lib")
+       ("primdecint.lib")
+       ("primdec.lib")
+       ("normal.lib")
+       ("noether.lib")
+       ("mregular.lib")
+       ("mprimdec.lib")
+       ("modstd.lib")
+       ("modnormal.lib")
+       ("locnormal.lib")
+       ("lll.lib")
+       ("intprog.lib")
+       ("integralbasis.lib")
+       ("homolog.lib")
+       ("grwalk.lib")
+       ("elim.lib")
+       ("divisors.lib")
+       ("cisimplicial.lib")
+       ("assprimeszerodim.lib")
+       ("algebra.lib")
+     )
+     ("Combinatorial Commutative Algebra"
+       ("multigrading.lib")
+     )
+     ("Coding theory"
+       ("decodegb.lib")
+       ("brnoeth.lib")
+     )
+     ("Applications"
+       ("groups.lib")
+       ("findifs.lib")
+     )
+     ("Algebraic Geometry"
+       ("reszeta.lib")
+       ("resolve.lib")
+       ("paraplanecurves.lib")
+       ("orbitparam.lib")
+       ("numerDecom.lib")
+       ("numerAlg.lib")
+       ("JMSConst.lib")
+       ("JMBTest.lib")
+     )
+     (" "
+       ("phindex.lib")
+     )
+))
diff --git a/emacs/singular.el b/emacs/singular.el
new file mode 100644
index 0000000..e7602bd
--- /dev/null
+++ b/emacs/singular.el
@@ -0,0 +1,4273 @@
+;;; singular.el --- Emacs support for Computer Algebra System Singular
+
+
+;;; Commentary:
+
+

+;;; Code:
+
+;;{{{ Style and coding conventions
+
+;; Style and coding conventions:
+;;
+;; - "Singular" is written with an upper-case `S' in comments, doc
+;;   strings, and messages.  As part of symbols, it is written with
+;;   a lower-case `s'.
+;; - When referring to the Singular interactive mode, do it in that
+;;   wording.  Use the notation `singular-interactive-mode' only when
+;;   really referring to the lisp object.
+;; - use a `fill-column' of 75 for doc strings and comments
+;; - mark incomplete doc strings or code with `NOT READY' optionally
+;;   followed by an explanation what exactly is missing
+;;
+;; - use foldings to structure the source code but try not to exceed a
+;;   maximum depth of two foldings
+;; - use lowercase folding titles except for first word
+;; - folding-marks are `;;{{{' and `;;}}}' resp., for sake of standard
+;;   conformity
+;; - use the foldings to modularize code.  That is, each folding should be,
+;;   as far as possible, self-content.  Define a function `singular-*-init'
+;;   in the folding to do the initialization of the module contained in
+;;   that folding.  Call that function from `singular-interactive-mode',
+;;   for example, instead of initializing the module directly from
+;;   `singular-interactive-mode'.  Look at the code how it is done for the
+;;   simple section or for the folding stuff.
+;;
+;; - use `singular' as prefix for all global symbols
+;; - use `singular-debug' as prefix for all global symbols concerning
+;;   debugging.
+;; - use, whenever possible without names becoming too clumsy, some unique
+;;   prefix inside a folding
+;;
+;; - mark dependencies on Emacs flavor/version with a comment of the form
+;;   `;; Emacs[ <version> ]'     resp.
+;;   `;; XEmacs[ <version> ][ <nasty comment> ]'
+;;   specified in that order, if possible
+;; - use a `cond' statement to execute Emacs flavor/version-dependent code,
+;;   not `if'.  This is to make such checks more extensible.
+;; - try to define different functions for different flavors/version and
+;;   use `singular-fset' at library-loading time to set the function you
+;;   really need.  If the function is named `singular-<basename>', the
+;;   flavor/version-dependent functions should be named
+;;   `singular-<flavor>[-<version>]-<basename>'.
+;;
+;; - use `singular-debug' for debugging output/actions
+;; - to switch between buffer and process names, use the functions
+;;   `singular-process-name-to-buffer-name' and
+;;   `singular-buffer-name-to-process-name'
+;; - call the function `singular-keep-region-active' as last statement in
+;;   an interactive function that should keep the region active (for
+;;   example, in functions that move the point).  This is necessary to keep
+;;   XEmacs' zmacs regions active.
+;; - to get the process of the current buffer, use `singular-process'.  To
+;;   get the current process mark, use `singular-process-mark'.  Both
+;;   functions check whether Singular is alive and throw an error if not,
+;;   so you do not have to care about that yourself.  If you do not want an
+;;   error specify non-nil argument NO-ERROR.  But use them anyway.
+;; - we assume that the buffer is *not* read-only
+;; - use `=' instead of `eq' when comparing buffer locations.  Even if you
+;;   are sure that both operands are integers.
+
+;;}}}
+
+;;{{{ Code common to both modes
+;;{{{ Customizing
+(defgroup singular nil
+  "Emacs interface to Singular.
+By now, the Emacs interface to Singular consists of Singular interactive
+mode only.  Singular interactive mode provides a convenient front end to
+interactive Singular sessions running inside Emacs.
+In far future maybe there will be a mode for editing Singular source code
+such as libraries or procedures."
+  :group 'external)
+
+(defgroup singular-faces nil
+  "Faces in Singular mode and Singular interactive mode."
+  :group 'faces
+  :group 'singular-interactive)
+;;}}}
+
+;;{{{ Debugging stuff
+(defvar singular-debug nil
+  "List of modes to debug or t to debug all modes.
+Currently, the following modes are supported:
+  `interactive',
+  `interactive-filter'.")
+
+(defun singular-debug-format (string)
+  "Return STRING in a nicer format."
+  (save-match-data
+    (while (string-match "\n" string)
+      (setq string (replace-match "^J" nil nil string)))
+
+    (if (> (length string) 16)
+	(concat "<" (substring string 0 7) ">...<" (substring string -8) ">")
+      (concat "<" string ">"))))
+
+(defmacro singular-debug (mode form &optional else-form)
+  "Major debugging hook for singular.el.
+Evaluates FORM if `singular-debug' equals t or if MODE is an element
+of `singular-debug', othwerwise ELSE-FORM."
+  `(if (or (eq singular-debug t)
+	   (memq ,mode singular-debug))
+       ,form
+     ,else-form))
+;;}}}
+
+;;{{{ Determining version
+(defvar singular-emacs-flavor nil
+  "A symbol describing the current Emacs.
+Currently, only Emacs \(`emacs') and XEmacs \(`xemacs') are supported.")
+
+(defvar singular-emacs-major-version nil
+  "An integer describing the major version of the current emacs.")
+
+(defvar singular-emacs-minor-version nil
+  "An integer describing the minor version of the current emacs.")
+
+(defun singular-fset (real-function emacs-function xemacs-function)
+  "Set REAL-FUNCTION to one of the functions, in dependency on Emacs flavor and version.
+Sets REAL-FUNCTION to XEMACS-FUNCTION if `singular-emacs-flavor' is
+`xemacs', otherwise sets REAL-FUNCTION to EMACS-FUNCTION.
+
+This is not as common as it would be desirable.  But it is sufficient so
+far."
+  (cond
+   ;; XEmacs
+   ((eq singular-emacs-flavor 'xemacs)
+    (fset real-function xemacs-function))
+   ;; Emacs
+   (t
+    (fset real-function emacs-function))))
+
+(defun singular-set-version ()
+  "Determine flavor, major version, and minor version of current emacs.
+singular.el is guaranteed to run on Emacs 20.3 and XEmacs 20.3.
+It should run on newer version and on slightly older ones, too.
+
+This function is called exactly once when singular.el is loaded."
+  ;; get major and minor versions first
+  (if (and (boundp 'emacs-major-version)
+	   (boundp 'emacs-minor-version))
+      (setq singular-emacs-major-version emacs-major-version
+	    singular-emacs-minor-version emacs-minor-version)
+    (with-output-to-temp-buffer "*singular warnings*"
+      (princ
+"You seem to have quite an old Emacs or XEmacs version.  Some of the
+features from singular.el will not work properly.  Consider upgrading to a
+more recent version of Emacs or XEmacs.  singular.el is guaranteed to run
+on Emacs 20.3 and XEmacs 20.3."))
+    ;; assume the oldest version we support
+    (setq singular-emacs-major-version 20
+	  singular-emacs-minor-version 3))
+
+  ;; get flavor
+  (if (string-match "XEmacs\\|Lucid" emacs-version)
+      (setq singular-emacs-flavor 'xemacs)
+    (setq singular-emacs-flavor 'emacs)))
+
+(singular-set-version)
+;;}}}
+
+;;{{{ Syntax table
+(defvar singular-mode-syntax-table nil
+  "Syntax table for `singular-interactive-mode' resp. `singular-mode'.")
+
+(if singular-mode-syntax-table
+    ()
+  (setq singular-mode-syntax-table (make-syntax-table))
+  ;; stolen from cc-mode.el except for back-tics which are special to Singular
+  (modify-syntax-entry ?_  "_"     	singular-mode-syntax-table)
+  (modify-syntax-entry ?\\ "\\"    	singular-mode-syntax-table)
+  (modify-syntax-entry ?+  "."     	singular-mode-syntax-table)
+  (modify-syntax-entry ?-  "."     	singular-mode-syntax-table)
+  (modify-syntax-entry ?=  "."     	singular-mode-syntax-table)
+  (modify-syntax-entry ?%  "."     	singular-mode-syntax-table)
+  (modify-syntax-entry ?<  "."     	singular-mode-syntax-table)
+  (modify-syntax-entry ?>  "."     	singular-mode-syntax-table)
+  (modify-syntax-entry ?&  "."     	singular-mode-syntax-table)
+  (modify-syntax-entry ?|  "."     	singular-mode-syntax-table)
+  (modify-syntax-entry ?\' "\""    	singular-mode-syntax-table)
+  (modify-syntax-entry ?\` "\""    	singular-mode-syntax-table)
+  ;; block and line-oriented comments
+  (cond
+   ;; Emacs
+   ((eq singular-emacs-flavor 'emacs)
+    (modify-syntax-entry ?/  ". 124b" 	singular-mode-syntax-table)
+    (modify-syntax-entry ?*  ". 23"   	singular-mode-syntax-table))
+   ;; XEmacs
+   (t
+    (modify-syntax-entry ?/  ". 1456" 	singular-mode-syntax-table)
+    (modify-syntax-entry ?*  ". 23"   	singular-mode-syntax-table)))
+  (modify-syntax-entry ?\n "> b"    	singular-mode-syntax-table)
+  (modify-syntax-entry ?\^m "> b"    	singular-mode-syntax-table))
+
+(defun singular-mode-syntax-table-init ()
+  "Initialize syntax table of current buffer.
+
+This function is called at mode initialization time."
+  (set-syntax-table singular-mode-syntax-table))
+;;}}}
+
+;;{{{ Miscellaneous
+(defsubst singular-keep-region-active ()
+  "Do whatever is necessary to keep the region active in XEmacs.
+Ignore byte-compiler warnings you might see.  This is not needed for
+Emacs."
+  ;; XEmacs.  We do not use the standard way here to test for flavor
+  ;; because it is presumably faster with that test on `boundp'.
+  (and (boundp 'zmacs-region-stays)
+       (setq zmacs-region-stays t)))
+;;}}}
+;;}}}
+
+;;{{{ Singular interactive mode
+;;{{{ Customizing
+
+;; Note:
+;;
+;; Some notes on Customize:
+;;
+;; - The documentation states that for the `:initialize' option of
+;;   `defcustom' the default value is `custom-initialize-set'.  However, in
+;;   the source code of Customize `custom-initialize-reset' is used.  So
+;;   better always specify the `:initialize' option explicitly.
+;; - Customize is bad at setting buffer-local variables or properties.
+;;   This is quite natural since Customize itself uses its own buffer.  So
+;;   changing buffer-local variables and properties with Customize is
+;;   possible only at a "Singular-global" level.  That is, for all buffers
+;;   currently having Singular interactive mode as major mode.  The function
+;;   `singular-map-buffer' helps to do such customization.
+;; - Important note: Customizable variables are not automatically marked as
+;;   user options.  This has to be done as usual by marking them with a '*'
+;;   as first character of the documentation string.  Without that, the
+;;   variables are not accessible to, for example, `set-variable'.
+;;
+;; Some common customizing patterns:
+;;
+;; - How to customize buffer-local properties?
+;;   First, the `defcustom' itself must not set anything buffer-local since
+;;   at time of its definition (most likely) no Singular buffers will be
+;;   around.  If there are Singular buffers we do not care about them.  But
+;;   anyhow, at definition of the `defcustom' the global default has to be
+;;   set.  Hence, the `:initialize' option should be set to
+;;   `custom-initialize-default'.
+;;   The buffer-local initialization has to be done at mode initialization
+;;   time.  The global default value should then be used to set the local
+;;   properties.
+;;   At last, the function specified with the `:set' option should set the
+;;   local properties in all Singular buffers to the new, customized value.
+;;   Most likely, the function `singular-map-buffer' may be used for that.
+;;   In addition, the function should, of course, set the global value via
+;;   `set-default'.
+;;   For an example, see `singular-folding-line-move-ignore-folding'.
+;;
+;; - How to encapsulate other mode's global variables into Singular
+;;   interactive mode variables?
+;;   Set them always.  That is, set them if the `defcustom' is evaluated
+;;   (use `custom-initialize-reset' as `:initial' function) and set them
+;;   when the Singular interactive mode variable is customized (by means
+;;   of an appropriate `:set' function).
+;;   For an example, see `singular-section-face-alist' (which does not
+;;   encapsulate another mode's variable, but Singular interactive mode's
+;;   own variable `singular-simple-sec-clear-type').
+
+(defgroup singular-interactive nil
+  "Running interactive Singular sessions inside Emacs."
+  :group 'singular
+  :group 'processes)
+
+(defgroup singular-sections-and-foldings nil
+  "Sections and foldings in Singular interactive mode."
+  :group 'singular-interactive)
+
+(defgroup singular-interactive-miscellaneous nil
+  "Miscellaneous settings for Singular interactive mode."
+  :group 'singular-interactive)
+
+(defgroup singular-demo-mode nil
+  "Settings concerning Singular demo mode."
+  :group 'singular-interactive)
+
+(defun singular-map-buffer (func &rest args)
+  "Apply FUNC to ARGS in all existing Singular buffers.
+That is, in all buffers having Singular interactive major mode.  The
+function is executed in the context of the buffer.  This is a must-have for
+the customizing stuff to change buffer-local properties."
+  (save-excursion
+    (mapcar (function
+	     (lambda (buffer)
+	       (set-buffer buffer)
+	       (if (eq major-mode 'singular-interactive-mode)
+		   (apply func args))))
+	    (buffer-list))))
+;;}}}
+
+;;{{{ Comint
+
+;; Note:
+;;
+;; We require Comint, but we really do not use it too much.  One may argue
+;; that this is bad since Comint is a standardized way to communicate with
+;; external processes.  One may argue further that many experienced Emacs
+;; users are forced now to re-do their Comint customization for Singular
+;; interactive mode.  However, we believe that the intersection between
+;; experienced Emacs users and users of Singular interactive mode is almost
+;; empty.
+;;
+;; In fact, we used Comint really much in the beginning of this project.
+;; Later during development it turned at that using Comint's input and
+;; output processing is to inflexible and not appropriate for Singular
+;; interactive mode with its input and output sections.  So we begun to
+;; rewrite large portions of Comint to adapt it to our needs.  At some
+;; point it came clear that it would be best to throw out Comint
+;; alltogether, would not have been there some auxilliary functions which
+;; are really useful but annoying to rewrite.  These are, for example, the
+;; command line history functions or the completion stuff offered by
+;; Comint.
+;;
+;; Our policy with regard to these remainders of Comint is: Use the
+;; functions to bind them to keys, but do not use them internally.
+;; Encapsulate Comint customization into Singular interactive mode
+;; customization.  In particular, do not take care about Comint settings
+;; which already may be present, overwrite them.  Hide Comint from the
+;; user.
+;;
+;; Here is how exactly we use Comint:
+;;
+;; - All variables necessary to use Comint's input ring are properly
+;;   initialized.  One may find this in the `History' folding.
+;; - `comint-prompt-regexp' is initialized since it is used in some
+;;   of the functions regarding input ring handling.  Furthermore, its
+;;   initialization enables us to use functions as `comint-bol', etc.
+;;   Initialization is done in the `Skipping and stripping prompts ...'
+;;   folding.
+;; - We call `comint-mode' as first step in `singular-interactive-mode'.
+;;   Most of the work done there is to initialize the local variables as
+;;   necessary.  Besides that, the function does nothing that interferes
+;;   with Singular interactive mode.  To be consequent we set
+;;   `comint-mode-hook' temporarily to nil when calling `comint-mode'.
+;; - In `singular-exec', we use `comint-exec-1' to fire up the process.
+;;   Furthermore, we set `comint-ptyp' there as it is used in the signal
+;;   sending commands of Comint.  All that `comint-exec-1' does is that it
+;;   sets up the process environment (it adds or modifies the setting of
+;;   the 'TERM' variable), sets the execution directory, and does some
+;;   magic with the process coding stuff.
+;; - One more time the most important point: we do *not* use Comint's
+;;   output and input processing.  In particular, we do not run any of
+;;   Comint's hooks on input or output.  Anyway, we do better, don't we?
+
+(require 'comint)
+
+(defun singular-comint-init ()
+  "Initialize comint stuff for Singular interactive mode.
+
+This function is called at mode initialization time."
+  (setq comint-completion-addsuffix '("/" . "")))
+;;}}}
+
+;;{{{ Font-locking
+(defvar singular-font-lock-error-face 'singular-font-lock-error-face
+  "Face name to use for Singular errors.")
+
+(defvar singular-font-lock-warning-face 'singular-font-lock-warning-face
+  "Face name to use for Singular warnings.")
+
+(defvar singular-font-lock-prompt-face 'singular-font-lock-prompt-face
+  "Face name to use for Singular prompts.")
+
+(defface singular-font-lock-error-face
+  '((((class color)) (:foreground "Red" :bold t))
+    (t (:inverse-video t :bold t)))
+  "*Font Lock mode face used to highlight Singular errors."
+  :group 'singular-faces)
+
+(defface singular-font-lock-warning-face
+  '((((class color)) (:foreground "OrangeRed" :bold nil))
+    (t (:inverse-video t :bold t)))
+  "*Font Lock mode face used to highlight Singular warnings."
+  :group 'singular-faces)
+
+(defface singular-font-lock-prompt-face
+  '((((class color) (background light)) (:foreground "Blue" :bold t))
+    (((class color) (background dark)) (:foreground "LightSkyBlue" :bold t))
+    (t (:inverse-video t :bold t)))
+  "*Font Lock mode face used to highlight Singular prompts."
+  :group 'singular-faces)
+
+(defconst singular-font-lock-singular-types nil
+  "List of Singular types.")
+
+(eval-when-compile
+  (setq singular-font-lock-singular-types
+	'("def" "bigint" "ideal" "int" "intmat" "intvec" "link" "list" "map"
+	  "matrix" "module" "number" "poly" "proc" "qring" "resolution" "ring"
+	  "string" "vector")))
+
+(defconst singular-interactive-font-lock-keywords-1
+  '(
+    ("^\\([>.]\\) " 1 singular-font-lock-prompt-face t)
+    ("^   [\\?].*" 0 singular-font-lock-error-face t)
+    ("^// \\*\\*.*" 0 singular-font-lock-warning-face t)
+    )
+  "Subdued level highlighting for Singular interactive mode")
+
+(defconst singular-interactive-font-lock-keywords-2
+  (append
+   singular-interactive-font-lock-keywords-1
+   (eval-when-compile
+     (list
+      (cons
+       (concat "\\<" (regexp-opt singular-font-lock-singular-types t) "\\>")
+       'font-lock-type-face))))
+  "Medium level highlighting for Singular interactive mode")
+
+(defconst singular-interactive-font-lock-keywords-3
+  (append
+   singular-interactive-font-lock-keywords-2
+   '(
+     ;; note: we use font-lock-reference-face here even Emacs says that
+     ;; this face is obsolete and suggests to use font-lock-constant-face,
+     ;; since XEmacs20/21 does not know the constant-face but the
+     ;; reference-face.
+     ("^   [\\?].*`\\(\\sw\\sw+;?\\)`" 1 font-lock-reference-face t)
+     ))
+  "Gaudy level highlighting for Singular interactive mode.")
+
+(defconst singular-interactive-font-lock-keywords singular-interactive-font-lock-keywords-1
+  "Default highlighting for Singular interactive mode.")
+
+(defconst singular-interactive-font-lock-defaults
+  '((singular-interactive-font-lock-keywords
+     singular-interactive-font-lock-keywords-1
+     singular-interactive-font-lock-keywords-2
+     singular-interactive-font-lock-keywords-3)
+    ;; KEYWORDS-ONLY (do not fontify strings & comments if non-nil)
+    nil
+    ;; CASE-FOLD (ignore case if non-nil)
+    nil
+    ;; SYNTAX-ALIST (add this to Font Lock's syntax table)
+    ((?_ . "w"))
+    ;; SYNTAX-BEGIN
+    singular-section-goto-beginning)
+  "Default expressions to highlight in Singular interactive mode.")
+
+(defun singular-interactive-font-lock-init ()
+  "Initialize Font Lock mode for Singular interactive mode.
+
+For XEmacs, this function is called exactly once when singular.el is
+loaded.
+For Emacs, this function is called  at mode initialization time."
+  (cond
+   ;; Emacs
+   ((eq singular-emacs-flavor 'emacs)
+    (singular-debug 'interactive (message "Setting up Font Lock mode for Emacs"))
+    (set (make-local-variable 'font-lock-defaults)
+	 singular-interactive-font-lock-defaults))
+   ;; XEmacs
+   ((eq singular-emacs-flavor 'xemacs)
+    (singular-debug 'interactive (message "Setting up Font Lock mode for XEmacs"))
+    (put 'singular-interactive-mode
+	 'font-lock-defaults singular-interactive-font-lock-defaults))))
+
+;; XEmacs Font Lock mode initialization
+(cond
+ ;; XEmacs
+ ((eq singular-emacs-flavor 'xemacs)
+  (singular-interactive-font-lock-init)))
+;;}}}
+
+;;{{{ Key map
+(defvar singular-interactive-mode-map nil
+  "Key map to use in Singular interactive mode.")
+
+(if singular-interactive-mode-map
+    ()
+  ;; create empty keymap first
+  (cond
+   ;; Emacs
+   ((eq singular-emacs-flavor 'emacs)
+    (setq singular-interactive-mode-map (make-sparse-keymap)))
+   ;; XEmacs
+   (t
+    (setq singular-interactive-mode-map (make-keymap))
+    (set-keymap-name singular-interactive-mode-map
+		     'singular-interactive-mode-map)))
+
+  ;; global settings
+  (define-key help-map [?\C-s]                                'singular-help)
+
+  ;; settings for `singular-interactive-map'
+  (substitute-key-definition 'beginning-of-line 'singular-beginning-of-line
+			     singular-interactive-mode-map global-map)
+
+  (define-key singular-interactive-mode-map "\t"              'singular-dynamic-complete)
+  (define-key singular-interactive-mode-map [?\C-m]	      'singular-send-or-copy-input)
+  (define-key singular-interactive-mode-map [?\C-l]           'singular-recenter)
+
+  ;; Comint functions
+  (define-key singular-interactive-mode-map [?\M-r]	      'comint-previous-matching-input)
+  (define-key singular-interactive-mode-map [?\M-s]	      'comint-next-matching-input)
+
+  ;; C-c prefix
+  (define-key singular-interactive-mode-map [?\C-c ?\C-e]     'singular-example)
+  (define-key singular-interactive-mode-map [?\C-c ?\C-t]     'singular-toggle-truncate-lines)
+
+  (define-key singular-interactive-mode-map [?\C-c ?\C-f]     'singular-folding-toggle-fold-at-point-or-all)
+  (define-key singular-interactive-mode-map [?\C-c ?\C-o]     'singular-folding-toggle-fold-latest-output)
+  (define-key singular-interactive-mode-map [?\C-c ?\C-w]     'singular-section-kill)
+
+  (define-key singular-interactive-mode-map [?\C-c ?\C-d]     'singular-demo-load)
+  (define-key singular-interactive-mode-map [?\C-c ?\C-l]     'singular-load-library)
+  (define-key singular-interactive-mode-map [(control c) (<)] 'singular-load-file)
+
+  (define-key singular-interactive-mode-map [?\C-c ?\C-r]     'singular-restart)
+  (define-key singular-interactive-mode-map [?\C-c ?\$] 'singular-exit-singular)
+  (define-key singular-interactive-mode-map [?\C-c ?\C-c] 'singular-control-c))
+
+(defun singular-cursor-key-model-set (key-model)
+  "Set keys according to KEY-MODEL.
+KEY-MODEL should be one of the valid values of `singular-cursor-key-model'."
+  ;; convert symbols to list
+  (cond ((eq key-model 'emacs)
+	 (setq key-model '(cursor cursor history)))
+	((eq key-model 'terminal)
+	 (setq key-model '(history history cursor))))
+
+  ;; work through list
+  (mapcar (function (lambda (spec)
+		      (let ((key-description (nth 0 spec))
+			    (prev-key (nth 1 spec))
+			    (next-key (nth 2 spec)))
+			(cond ((eq key-description 'cursor)
+			       (define-key singular-interactive-mode-map prev-key 'previous-line)
+			       (define-key singular-interactive-mode-map next-key 'next-line))
+			      ((eq key-description 'history)
+			       (define-key singular-interactive-mode-map prev-key 'comint-previous-input)
+			       (define-key singular-interactive-mode-map next-key 'comint-next-input))
+			      (t
+			       (define-key singular-interactive-mode-map prev-key nil)
+			       (define-key singular-interactive-mode-map next-key nil))))))
+
+	  ;; here is where list position are mapped to keys
+	  (list (list (nth 0 key-model) [up] [down])
+		(list (nth 1 key-model) [?\C-p] [?\C-n])
+		(list (nth 2 key-model) [?\M-p] [?\M-n]))))
+
+(defcustom singular-cursor-key-model 'emacs
+  "*Keys to use for cursor movement and history access, respectively.
+An experienced Emacs user would prefer setting `singular-cursor-key-model'
+to `emacs'.  This means that C-p, C-n, and the cursor keys move the cursor,
+whereas M-p and M-n scroll through the history of Singular commands.
+
+On the other hand, an user used to running Singular in a, say, xterm, would
+prefer setting `singular-cursor-key-model' to `terminal'.  This means that
+C-p, C-n, and the cursor keys scroll through the history of Singular
+commands, whereas M-p and M-n move the cursor.
+
+For those who do not like neither standard setting, there is the
+possibility to set this variable to a list of three elements where
+- the first element specifies the key bindings for the cursor keys,
+- the second element specifies the key bindings for C-p and C-n, and
+- the third element specifies the key bindings for M-p and M-n.
+Each list element should be one of
+- `cursor', meaning that the corresponding keys are bound to cursor movement,
+- `history', meaning that the corresponding keys are bound to history access,
+  or
+- nil, meaning that the corresponding keys are not bound at all.
+
+Changing this variable has an immediate effect only if one uses
+\\[customize] to do so."
+  :type '(choice (const :tag "Emacs-like" emacs)
+		 (const :tag "Terminal-like" terminal)
+		 (list :tag "User-defined"
+		      (choice :format "Cursor keys: %[Value Menu%] %v"
+			      :value cursor
+			      (const :tag "Cursor movement" cursor)
+			      (const :tag "History access" history)
+			      (const :tag "No binding" nil))
+		      (choice :format "C-p, C-n:    %[Value Menu%] %v"
+			      :value cursor
+			      (const :tag "Cursor movement" cursor)
+			      (const :tag "History access" history)
+			      (const :tag "No binding" nil))
+		      (choice :format "M-p, M-n:    %[Value Menu%] %v"
+			      :value history
+			      (const :tag "Cursor movement" cursor)
+			      (const :tag "History access" history)
+			      (const :tag "No binding" nil))))
+  :initialize 'custom-initialize-reset
+  :set (function
+	(lambda (var value)
+	  (singular-cursor-key-model-set value)
+	  (set-default var value)))
+  :group 'singular-interactive-miscellaneous)
+
+(defun singular-interactive-mode-map-init ()
+  "Initialize key map for Singular interactive mode.
+
+This function is called  at mode initialization time."
+  (use-local-map singular-interactive-mode-map))
+;;}}}
+
+;;{{{ Menus and logos
+(defvar singular-interactive-mode-menu-1 nil
+  "NOT READY [docu]")
+
+(defvar singular-interactive-mode-menu-2 nil
+  "NOT READY [docu]")
+
+(defconst singular-menu-initial-library-menu
+  '(["other..." (singular-load-library t) t])
+  "Menu definition for the inital library sub menu.
+This should be a list of vectors.")
+
+(defun singular-menu-build-libraries-menu (definition)
+  "Given a description of the libraries and their categories, builds up a
+menu definition including submenus which can be given to
+`easy-menu-change'.  By side effect sets the variable
+`singular-standard-libraries-alist' to the alist of all library names.
+This alist can be used for completion."
+  (let ((menudef ())
+        (libs definition)
+        elem)
+    (while libs
+      (setq elem (car libs))
+      (if (> (length elem) 1)
+          (setq menudef
+                (append
+		 (list
+		  (append (list (car elem))
+			  (singular-menu-build-libraries-menu (cdr elem))))
+		 menudef))
+        (setq menudef
+	      (append (list (vector (car elem)
+				    (list 'singular-load-library nil
+					  (car elem))
+                                    t))
+		      menudef))
+        (setq singular-standard-libraries-alist
+	      (append (list elem) singular-standard-libraries-alist)))
+      (setq libs (cdr libs)))
+    menudef))
+
+(defun singular-menu-install-libraries ()
+  "Update the singular command menu with libraries.
+Scans the variable `singular-standard-libraries-with-categories' and builds
+up a menu with submenues for each category in the submenu (\"Commands\"
+\"Libraries\")."
+  (singular-debug 'interactive (message "Installing library menu"))
+  ;; To be compatible with older versions of singular.el (resp. of lib-cmpl.el)
+  ;; we check whether the variable
+  ;; `singular-standard-libraries-with-categories' is set.  If not, we use the
+  ;; value of `singular-standard-libraries-alist' instead.
+  (if (not singular-standard-libraries-with-categories)
+      (setq singular-standard-libraries-with-categories
+            singular-standard-libraries-alist))
+  (easy-menu-change '("Commands")
+		    "Libraries"
+		    (append
+		     (singular-menu-build-libraries-menu
+		      singular-standard-libraries-with-categories)
+		     (append '("---") singular-menu-initial-library-menu))))
+
+(defun singular-menu-init ()
+  "Initialize menu stuff for Singular interactive mode.
+
+This function is called by `singular-exec'."
+  (singular-debug 'interactive (message "Initializing menue stuff"))
+  (make-local-variable 'singular-standard-libraries-alist)
+  (make-local-variable 'singular-standard-libraries-with-categories))
+
+(defun singular-menu-deinstall-libraries ()
+  "Initialize library submenu from singular command menu.
+Sets the submenu (\"Commands\" \"Libraries\") to the value of
+`singular-menu-initial-library-menu'."
+  (singular-debug 'interactive
+		  (message "Removing libraries from menu"))
+  (easy-menu-change '("Commands") "Libraries" singular-menu-initial-library-menu))
+
+;; For some reasons emacs inserts new menus in the oppsite order.
+;; Defining menu-2 prior to menu-1 will result in the follwoing menu:
+;;   Singular   Commands
+;; That's what we want. So DO NOT exchange both (or ..) statements!
+(or singular-interactive-mode-menu-2
+    (easy-menu-define
+     singular-interactive-mode-menu-2
+     singular-interactive-mode-map ""
+     (list
+      "Commands"
+      ["Fold/Unfold Latest Output" singular-folding-toggle-fold-latest-output t]
+      ["Fold/Unfold At Point" singular-folding-toggle-fold-at-point-or-all t]
+      ["Fold All Output" singular-folding-fold-all-output t]
+      ["Unfold All Output" singular-folding-unfold-all-output t]
+      "---"
+      ["Truncate Lines" singular-toggle-truncate-lines
+       :style toggle :selected truncate-lines]
+      "--"
+      (append
+       '("Libraries")
+       singular-menu-initial-library-menu)
+      ["Load File..." singular-load-file t]
+      "---"
+      ["Load Demo..." singular-demo-load (or singular-demo-exit-on-load
+					     (not singular-demo-mode))]
+      ["Exit Demo" singular-demo-exit singular-demo-mode]
+      )))
+
+(or singular-interactive-mode-menu-1
+    (easy-menu-define singular-interactive-mode-menu-1
+		      singular-interactive-mode-map ""
+		      '("Singular"
+			["Start Default" singular t]
+			["Start..." singular-other t]
+			["Restart" singular-restart t]
+			"---"
+			["Interrupt" singular-control-c t]
+			["Exit" singular-exit-singular t]
+			"---"
+			["Preferences" (customize-group 'singular-interactive) t]
+			["Singular Example" singular-example t]
+			["Singular Help" singular-help t])))
+
+(defun customize-singular-interactive ()
+  (interactive)
+  (customize-group 'singular-interactive))
+
+(defun singular-interactive-mode-menu-init ()
+  "Initialize menus for Singular interactive mode.
+
+This function is called  at mode initialization time."
+  ;; Remove any potential menu which comint-mode might has added.
+  (cond
+   ;; Emacs
+   ((eq singular-emacs-flavor 'emacs)
+    ;; Note that easy-menu-remove is a nop in emacs.
+    (define-key comint-mode-map [menu-bar signals] nil)
+    (define-key comint-mode-map [menu-bar inout] nil)
+    (define-key comint-mode-map [menu-bar completion] nil))
+   ;;Xemacs
+   (t
+    (easy-menu-remove '("Singular"))
+    (easy-menu-remove '("Comint1"))	; XEmacs 20
+    (easy-menu-remove '("Comint2"))	; XEmacs 20
+    (easy-menu-remove '("History"))	; XEmacs 20
+    (easy-menu-remove '("Complete"))	; XEmacs 21
+    (easy-menu-remove '("In/Out"))	; XEmacs 21
+    (easy-menu-remove '("Signals"))))	; XEmacs 21
+
+  ;; Note: easy-menu-add is not necessary in emacs, since the menu
+  ;; is added automatically with the keymap.
+  ;; See help on `easy-menu-add'
+  (easy-menu-add singular-interactive-mode-menu-1)
+  (easy-menu-add singular-interactive-mode-menu-2))
+;;}}}
+
+;;{{{ Skipping and stripping prompts and whitespace and other things
+
+;; Note:
+;;
+;; Most of these functions handle prompt recognition, prompt skipping,
+;; prompt stripping, and so on.  It turned out that it would be very
+;; inefficient to use one generic regular expression to do so.  Hence, we
+;; decided to hardcode the prompt skipping and stripping in an API.  If one
+;; decides to use some other prompt the whole API has to be changed.
+;; Hopefully, the Singular prompt does not change in near future ...
+;;
+;; In addition to the API, the Comint mode variable `comint-mode-regexp' is
+;; set on initialization of Singular interactive mode.  Singular
+;; interactive mode seems to do quite well without that, but for safety the
+;; variable is set nonetheless.
+
+(defsubst singular-prompt-skip-forward ()
+  "Skip forward over prompts."
+  (if (looking-at "\\([>.] \\)+")
+      (goto-char (match-end 0))))
+
+(defsubst singular-prompt-skip-backward ()
+  "Skip backward over prompts."
+  ;; is that really the simplest and fastest method?  The problem is that
+  ;; `re-search-backward' is not greedy so on an regexp as "\\([>.] \\)+"
+  ;; it stops right after the first occurence of the sub-expression.
+  ;; Anyway, the `(- (point) 2)' expression is OK, even at bob.
+  (while (re-search-backward "[>.] " (- (point) 2) t)))
+
+(defun singular-prompt-remove-string (string)
+  "Remove all prompts from STRING."
+  (while (string-match "^\\([>.] \\)+" string)
+    (setq string (replace-match "" t t string)))
+  string)
+
+(defun singular-prompt-remove-region (beg end)
+  "Remove all superfluous prompts from region between BEG and END.
+Removes only sequences of prompts that start at beginning of line.  Removes
+all but the last prompt of a sequence if that sequence ends at END,
+otherwise removes all prompts.
+The region between BEG and END should be accessible.  BEG should be less
+than or equal to END.
+Leaves point at the position of the last sequence of prompts which has been
+deleted or at BEG if nothing has been deleted."
+  ;; we cannot exclude this case, I think
+  (if (/= beg end)
+      ;; that's a nice trick to keep the last prompt if it ends at END: we
+      ;; set `(1- END)' as search limit.  Since BEG /= END there can be no
+      ;; problems with the `1-'.
+      (let ((end (copy-marker (1- end))))
+	(goto-char beg)
+	(while (re-search-forward "^\\([>.] \\)+" end t)
+	  (delete-region (match-beginning 0) (match-end 0)))
+	(set-marker end nil))))
+
+(defun singular-prompt-remove-filter (beg end simple-sec-start)
+  "Remove all superfluous prompts from text inserted into buffer."
+  (cond (;; if a new simple section has been created remove all
+	 ;; prompts from that simple section
+	 simple-sec-start
+	 (singular-prompt-remove-region simple-sec-start end))
+	(;; if no simple section has been created check whether maybe the
+	 ;; region between beg and end consists of prompts only.  This in
+	 ;; case that the user issued a command that did not output any
+	 ;; text.
+	 (and (goto-char beg)
+	      (re-search-forward "\\([>.] \\)+" end t)
+	      (= (match-end 0) end))
+	 (singular-prompt-remove-region (progn (beginning-of-line) (point))
+					end))))
+
+(defun singular-white-space-strip (string &optional trailing leading)
+  "Strip off trailing or leading whitespace from STRING.
+Strips off trailing whitespace if optional argument TRAILING is non-nil.
+Strips off leading whitespace if optional argument LEADING is non-nil."
+  (let (beg end)
+    (and leading
+	 (string-match "\\`[ \t\n\r\f]+" string)
+	 (setq beg (match-end 0)))
+    (and trailing
+	 (string-match "[ \t\n\r\f]+\\'" string)
+	 (setq end (match-beginning 0)))
+    (if (or beg end)
+	(substring string (or beg 0) (or end (length string)))
+      string)))
+
+(defconst singular-comint-prompt-regexp "^\\([>.] \\)+"
+  "Regexp to match prompt patterns in Singular.
+This variable is used to initialize `comint-prompt-regexp' when Singular
+interactive mode starts up.  It is not used in Singular interactive mode
+itself!  One should refer to the source code for more information on how to
+adapt Singular interactive mode to some other prompt.")
+
+(defun singular-prompt-init ()
+  "Initialize prompt skipping and stripping for Singular interactive mode.
+
+This function is called at mode initialization time."
+  ;; remove superfluous prompts in singular output
+  (add-hook 'singular-post-output-filter-functions 'singular-prompt-remove-filter nil t)
+
+  ;; some relict from Comint mode
+  (setq comint-prompt-regexp singular-comint-prompt-regexp))
+  ;; required to use prompt-regexp
+  (setq comint-use-prompt-regexp t)
+;;}}}
+
+;;{{{ Miscellaneous
+
+;; Note:
+;;
+;; We assume a one-to-one correspondence between Singular buffers and
+;; Singular processes.  We always have (equal buffer-name (concat "*"
+;; process-name "*")).
+
+(defsubst singular-buffer-name-to-process-name (buffer-name)
+  "Create the process name for BUFFER-NAME.
+The process name is the buffer name with surrounding `*' stripped off."
+  (substring buffer-name 1 -1))
+
+(defsubst singular-process-name-to-buffer-name (process-name)
+  "Create the buffer name for PROCESS-NAME.
+The buffer name is the process name with surrounding `*'."
+  (concat "*" process-name "*"))
+
+(defsubst singular-run-hook-with-arg-and-value (hook value)
+  "Call functions on HOOK.
+Provides argument VALUE to the functions.  If a function returns a non-nil
+value it replaces VALUE as new argument to the remaining functions.
+Returns final VALUE."
+  (while hook
+    (setq value (or (funcall (car hook) value) value)
+	  hook (cdr hook)))
+  value)
+
+(defsubst singular-process (&optional no-error)
+  "Return process of current buffer.
+If no process is active this function silently returns nil if optional
+argument NO-ERROR is non-nil, otherwise it throws an error."
+  (cond ((get-buffer-process (current-buffer)))
+	(no-error nil)
+	(t (error "No Singular running in this buffer"))))
+
+(defsubst singular-process-mark (&optional no-error)
+  "Return process mark of current buffer.
+If no process is active this function silently returns nil if optional
+argument NO-ERROR is non-nil, otherwise it throws an error."
+  (let ((process (singular-process no-error)))
+    (and process
+	 (process-mark process))))
+
+(defun singular-time-stamp-difference (new-time-stamp old-time-stamp)
+  "Return the number of seconds between NEW-TIME-STAMP and OLD-TIME-STAMP.
+Both NEW-TIME-STAMP and OLD-TIME-STAMP should be in the format
+that is returned, for example, by `current-time'.
+Does not return a difference larger than 2^17 seconds."
+  (let ((high-difference (min 1 (- (car new-time-stamp) (car old-time-stamp))))
+	(low-difference (- (cadr new-time-stamp) (cadr old-time-stamp))))
+    (+ (* high-difference 131072) low-difference)))
+
+(defun singular-error (&rest message-args)
+  "Apply `message' on MESSAGE-ARGS and do a `ding'.
+This function should be used instead of `error' in hooks where calling
+`error' is not a good idea."
+  (apply 'message message-args)
+  (ding))
+
+(defun singular-pop-to-buffer (same-window &rest pop-to-buffer-args)
+  "Pop to buffer in same or other window.
+Pops to buffer in same window if SAME-WINDOW equals t.  Pops to buffer in
+other window if SAME-WINDOW equals nil.  If SAME-WINDOW equals neither t
+nor nil the default behaviour of `pop-to-buffer' is used.  The rest of the
+arguments is passed unchanged to `pop-to-buffer'."
+  (let ((same-window-buffer-names
+	 (cond
+	  ((null same-window)
+	   nil)
+	  ((eq same-window t)
+	   (let* ((buffer-or-name (car pop-to-buffer-args))
+		  (buffer-name (if (bufferp buffer-or-name)
+				   (buffer-name buffer-or-name)
+				 buffer-or-name)))
+	     (list buffer-name)))
+	  (t
+	   same-window-buffer-names))))
+    (apply 'pop-to-buffer pop-to-buffer-args)))
+;;}}}
+
+;;{{{ Miscellaneous interactive
+(defun singular-recenter (&optional arg)
+  "Center point in window and redisplay frame.  With ARG, put point on line ARG.
+The desired position of point is always relative to the current window.
+Just C-u as prefix means put point in the center of the window.
+If ARG is omitted or nil, erases the entire frame and then redraws with
+point in the center of the current window.
+Scrolls window to the left margin and moves point to beginning of line."
+  (interactive "P")
+  (singular-reposition-point-and-window)
+  (recenter arg))
+
+(defun singular-reposition-point-and-window ()
+  "Scroll window to the left margin and move point to beginning of line."
+  (interactive)
+  (set-window-hscroll (selected-window) 0)
+  (move-to-column 0)
+  ;; be careful where to place point
+  (singular-prompt-skip-forward))
+
+(defun singular-toggle-truncate-lines ()
+  "Toggle `truncate-lines'.
+A non-nil value of `truncate-lines' means do not display continuation
+lines\; give each line of text one screen line.
+Repositions window and point after toggling `truncate-lines'."
+  (interactive)
+  (setq truncate-lines (not truncate-lines))
+  ;; reposition so that user does not get confused
+  (singular-reposition-point-and-window)
+  ;; avoid calling `recenter' since it changes window layout more than
+  ;; necessary
+  (redraw-frame (selected-frame)))
+
+;; this is not a buffer-local variable even if at first glance it seems
+;; that it should be one.  But if one changes buffer the contents of this
+;; variable becomes irrelevant since the last command is no longer a
+;; horizontal scroll command.  The same is true for the initial value, so
+;; we set it to nil.
+(defvar singular-scroll-previous-amount nil
+  "Amount of previous horizontal scroll command.")
+
+(defun singular-scroll-right (&optional scroll-amount)
+  "Scroll selected window SCROLL-AMOUNT columns right.
+SCROLL-AMOUNT defaults to amount of previous horizontal scroll command.  If
+the command immediately preceding this command has not been a horizontal
+scroll command SCROLL-AMOUNT defaults to window width minus 2.
+Moves point to leftmost visible column."
+  (interactive "P")
+
+  ;; get amount to scroll
+  (setq singular-scroll-previous-amount
+	(cond (scroll-amount (prefix-numeric-value scroll-amount))
+	      ((eq last-command 'singular-scroll-horizontal)
+	       singular-scroll-previous-amount)
+	      (t (- (frame-width) 2)))
+	this-command 'singular-scroll-horizontal)
+
+  ;; scroll
+  (scroll-right singular-scroll-previous-amount)
+  (move-to-column (window-hscroll))
+  ;; be careful where to place point.  But what if `(current-column)'
+  ;; equals, say, one?  Well, we simply do not care about that case.
+  ;; Should not happen to often.
+  (if (eq (current-column) 0)
+      (singular-prompt-skip-forward)))
+
+(defun singular-scroll-left (&optional scroll-amount)
+  "Scroll selected window SCROLL-AMOUNT columns left.
+SCROLL-AMOUNT defaults to amount of previous horizontal scroll command.  If
+the command immediately preceding this command has not been a horizontal
+scroll command SCROLL-AMOUNT defaults to window width minus 2.
+Moves point to leftmost visible column."
+  (interactive "P")
+
+  ;; get amount to scroll
+  (setq singular-scroll-previous-amount
+	(cond (scroll-amount (prefix-numeric-value scroll-amount))
+	      ((eq last-command 'singular-scroll-horizontal)
+	       singular-scroll-previous-amount)
+	      (t (- (frame-width) 2)))
+	this-command 'singular-scroll-horizontal)
+
+  ;; scroll
+  (scroll-left singular-scroll-previous-amount)
+  (move-to-column (window-hscroll))
+  ;; be careful where to place point.  But what if `(current-column)'
+  ;; equals, say, one?  Well, we simply do not care about that case.
+  ;; Should not happen to often.
+  (if (eq (current-column) 0)
+      (singular-prompt-skip-forward)))
+
+(defun singular-beginning-of-line  (arg)
+  "Move point to the beginning of line, then skip past prompt, if any.
+If prefix argument is given the prompt is not skipped."
+  (interactive "P")
+  (beginning-of-line)
+  (if (not arg) (singular-prompt-skip-forward)))
+
+(defun singular-load-file (file &optional noexpand)
+  "Read a file into Singular (via '< \"FILE\";').
+If optional argument NOEXPAND is non-nil, FILE is left as it is entered by
+the user, otherwise it is expanded using `expand-file-name'."
+  (interactive "fLoad file: ")
+  (let* ((filename (if noexpand file (expand-file-name file)))
+	 (string (concat "< \"" filename "\";"))
+	 (process (singular-process)))
+    (singular-input-filter process string)
+    (singular-send-string process string)))
+
+(defvar singular-load-library-history nil
+  "History list for loading of Singular libraries.
+Is used by `singular-load-library'.")
+
+(defun singular-load-library (nonstdlib &optional file)
+  "Read a Singular library (via 'LIB \"FILE\";').
+If called interactively asks for the name of a standard Singular
+library. If called interactively with a prefix argument asks for a file
+name of a Singular library."
+  (interactive "P")
+  (let ((string (or file
+		    (if nonstdlib
+			(read-file-name "Library file: ")
+		      (completing-read "Library: " singular-standard-libraries-alist
+				       nil nil nil 'singular-load-library-history))))
+	(process (singular-process)))
+    (setq string (concat "LIB \"" string "\";"))
+    (singular-input-filter process string)
+    (singular-send-string process string)))
+;;}}}
+
+;;{{{ History
+(defcustom singular-history-ignoredups t
+  "*If non-nil, do not add input matching the last on the input history."
+  :type 'boolean
+  :initialize 'custom-initialize-default
+  :group 'singular-interactive-miscellaneous)
+
+;; this variable is used to set Comint's `comint-input-ring-size'
+(defcustom singular-history-size 64
+  "*Size of the input history.
+
+Changing this variable has no immediate effect even if one uses
+\\[customize] to do so.  The new value will be used only in new Singular
+interactive mode buffers."
+  :type 'integer
+  :initialize 'custom-initialize-default
+  :group 'singular-interactive-miscellaneous)
+
+(defcustom singular-history-filter-regexp "\\`\\(..?\\|\\s *\\)\\'"
+  "*Regular expression to filter strings *not* to insert in the input history.
+By default, input consisting of less than three characters and input
+consisting of white-space only is not inserted into the input history."
+  :type 'regexp
+  :initialize 'custom-initialize-default
+  :group 'singular-interactive-miscellaneous)
+
+(defcustom singular-history-explicit-file-name nil
+  "*If non-nil, use this as file name to load and save the input history.
+If this variable equals nil, the `SINGULARHIST' environment variable is
+used to determine the file name.
+One should note that the input history is saved to file only on regular
+termination of Singular; that is, if one leaves Singular using the commands
+`quit\;' or `exit\;'."
+  :type '(choice (const nil) file)
+  :initialize 'custom-initialize-default
+  :group 'singular-interactive-miscellaneous)
+
+(defun singular-history-read ()
+  "Read the input history from file.
+If `singular-history-explicit-file-name' is non-nil, uses that as file
+name, otherwise tries environment variable `SINGULARHIST'.
+This function is called from `singular-exec' every time a new Singular
+process is started."
+  (singular-debug 'interactive (message "Reading input ring"))
+  (let ((comint-input-ring-file-name (or singular-history-explicit-file-name
+					 (getenv "SINGULARHIST"))))
+    ;; `comint-read-input-ring' does nothing if
+    ;; `comint-input-ring-file-name' equals nil
+    (comint-read-input-ring t)))
+
+(defun singular-history-write ()
+  "Write back the input history to file.
+If `singular-history-explicit-file-name' is non-nil, uses that as file
+name, otherwise tries environment variable `SINGULARHIST'.
+This function is called either by `singular-exit-singular' or by
+`singular-exit-sentinel' every time a Singular process terminates
+regularly."
+  (singular-debug 'interactive (message "Writing input ring back"))
+  (let ((comint-input-ring-file-name (or singular-history-explicit-file-name
+					 (getenv "SINGULARHIST"))))
+    ;; `comint-write-input-ring' does nothing if
+    ;; `comint-input-ring-file-name' equals nil
+    (comint-write-input-ring)))
+
+(defun singular-history-insert (input)
+  "Insert string INPUT into the input history if necessary."
+  (if (and (not (string-match singular-history-filter-regexp input))
+	   (or (not singular-history-ignoredups)
+	       (not (ring-p comint-input-ring))
+	       (ring-empty-p comint-input-ring)
+	       (not (string-equal (ring-ref comint-input-ring 0) input))))
+      (ring-insert comint-input-ring input))
+  (setq comint-input-ring-index nil))
+
+(defun singular-history-init ()
+  "Initialize variables concerning the input history.
+
+This function is called at mode initialization time."
+  (setq comint-input-ring-size singular-history-size))
+;;}}}
+
+;;{{{ Simple section API for both Emacs and XEmacs
+
+;; Note:
+;;
+;; Sections and simple sections are used to mark Singular's input and
+;; output for further access.  Here are some general notes on simple
+;; sections.  Sections are explained in the respective folding.
+;;
+;; In general, simple sections are more or less Emacs' overlays or XEmacs
+;; extents, resp.  But they are more than simply an interface to overlays
+;; or extents.
+;;
+;; - Simple sections are non-empty portions of text.  They are interpreted
+;;   as left-closed, right-opened intervals, i.e., the start point of a
+;;   simple sections belongs to it whereas the end point does not.
+;; - Simple sections start and end at line borders only.
+;; - Simple sections do not overlap.  Thus, any point in the buffer may be
+;;   covered by at most one simple section.
+;; - Besides from their start and their end, simple sections have some type
+;;   associated.
+;; - Simple sections are realized using overlays (extents for XEmacs)
+;;   which define the start and, end, and type (via properties) of the
+;;   simple section.  Actually, as a lisp object a simple section is
+;;   nothing else but the underlying overlay.
+;; - There may be so-called clear simple sections.  Clear simple sections
+;;   have not an underlying overlay.  Instead, they start at the end of the
+;;   preceding non-clear simple section, end at the beginning of the next
+;;   non-clear simple section, and have the type defined by
+;;   `singular-simple-sec-clear-type'.  Clear simple sections are
+;;   represented by nil.
+;; - Buffer narrowing does not restrict the extent of completely or
+;;   partially inaccessible simple sections.  But one should note that
+;;   some of the functions assume that there is no narrowing in
+;;   effect.
+;; - After creation, simple sections are not modified any further.
+;; - There is one nasty little corner case: what if a non-clear simple
+;;   section spans up to end of buffer?  By definition, eob is not included
+;;   in that section since they are right-opened intervals.  Most of the
+;;   functions react as if there is an imagenary empty clear simple section
+;;   at eob.
+;; - Even though by now there are only two types of different simple
+;;   sections there may be an arbitrary number of them.  Furthermore,
+;;   simple sections of different types may appear in arbitrary order.
+;;
+;; - In `singular-interactive-mode', the whole buffer is covered with
+;;   simple sections from the very beginning of the file up to the
+;;   beginning of the line containing the last input or output.  The
+;;   remaining text up to `(point-max)' may be interpreted as covered by
+;;   one clear simple section.  Thus, it is most reasonable to define
+;;   `input' to be the type of clear simple sections.
+
+(defvar singular-simple-sec-clear-type 'input
+  "Type of clear simple sections.
+If nil no clear simple sections are used.
+
+One should not set this variable directly.  Rather, one should customize
+`singular-section-face-alist'.")
+
+(defvar singular-simple-sec-last-end nil
+  "Marker at the end of the last simple section.
+Should be initialized by `singular-simple-sec-init' before any calls to
+`singular-simple-sec-create' are done.  Instead of accessing this variable
+directly one should use the macro `singular-simple-sec-last-end-position'.
+
+This variable is buffer-local.")
+
+(defun singular-simple-sec-init (pos)
+  "Initialize variables belonging to simple section management.
+Creates the buffer-local marker `singular-simple-sec-last-end' and
+initializes it to POS.  POS should be at beginning of a line.
+
+This function is called every time a new Singular session is started."
+  (make-local-variable 'singular-simple-sec-last-end)
+  (if (not (markerp singular-simple-sec-last-end))
+      (setq singular-simple-sec-last-end (make-marker)))
+  (set-marker singular-simple-sec-last-end pos))
+
+(defmacro singular-simple-sec-last-end-position ()
+  "Return the marker position of `singular-simple-sec-last-end'.
+This macro exists more or less for purposes of information hiding only."
+  '(marker-position singular-simple-sec-last-end))
+
+(defsubst singular-simple-sec-lookup-face (type)
+  "Return the face to use for simple sections of type TYPE.
+This accesses the `singular-section-type-alist'.  It does not harm if nil
+is associated with TYPE in that alist: In this case, this function will
+never be called for that TYPE."
+  (cdr (assq type singular-section-face-alist)))
+
+;; Note:
+;;
+;; The rest of the folding is either marked as
+;; Emacs
+;; or
+;; XEmacs
+
+(singular-fset 'singular-simple-sec-create
+	       'singular-emacs-simple-sec-create
+	       'singular-xemacs-simple-sec-create)
+
+(singular-fset 'singular-simple-sec-at
+	       'singular-emacs-simple-sec-at
+	       'singular-xemacs-simple-sec-at)
+
+(singular-fset 'singular-simple-sec-start
+	       'singular-emacs-simple-sec-start
+	       'singular-xemacs-simple-sec-start)
+
+(singular-fset 'singular-simple-sec-end
+	       'singular-emacs-simple-sec-end
+	       'singular-xemacs-simple-sec-end)
+
+(singular-fset 'singular-simple-sec-type
+	       'singular-emacs-simple-sec-type
+	       'singular-xemacs-simple-sec-type)
+
+(singular-fset 'singular-simple-sec-before
+	       'singular-emacs-simple-sec-before
+	       'singular-xemacs-simple-sec-before)
+
+(singular-fset 'singular-simple-sec-start-at
+	       'singular-emacs-simple-sec-start-at
+	       'singular-xemacs-simple-sec-start-at)
+
+(singular-fset 'singular-simple-sec-end-at
+	       'singular-emacs-simple-sec-end-at
+	       'singular-xemacs-simple-sec-end-at)
+
+(singular-fset 'singular-simple-sec-in
+	       'singular-emacs-simple-sec-in
+	       'singular-xemacs-simple-sec-in)
+;;}}}
+
+;;{{{ Simple section API for Emacs
+(defsubst singular-emacs-simple-sec-start (simple-sec)
+  "Return start of non-clear simple section SIMPLE-SEC.
+Narrowing has no effect on this function."
+  (overlay-start simple-sec))
+
+(defsubst singular-emacs-simple-sec-end (simple-sec)
+  "Return end of non-clear simple section SIMPLE-SEC.
+Narrowing has no effect on this function."
+  (overlay-end simple-sec))
+
+(defsubst singular-emacs-simple-sec-type (simple-sec)
+  "Return type of SIMPLE-SEC.
+Returns nil if SIMPLE-SEC happens to be an overlay but not a simple
+section.
+Narrowing has no effect on this function."
+  (if simple-sec
+      (overlay-get simple-sec 'singular-type)
+    singular-simple-sec-clear-type))
+
+(defsubst singular-emacs-simple-sec-before (pos)
+  "Return simple section before buffer position POS.
+This is the same as `singular-simple-sec-at' except if POS falls on a
+section border.  In this case `singular-simple-section-before' returns the
+previous simple section instead of the current one.  If POS falls on
+beginning of buffer, the simple section at beginning of buffer is returned.
+Narrowing has no effect on this function."
+  (singular-emacs-simple-sec-at (max 1 (1- pos))))
+
+(defun singular-emacs-simple-sec-create (type end)
+  "Create a new simple section of type TYPE.
+Creates the section from end of previous simple section up to the first
+beginning of line before END.  That position should be larger than or equal
+to `singular-simple-sec-last-end'.  Updates `singular-simple-sec-last-end'.
+Returns the new simple section or `empty' if no simple section has been
+created.
+Assumes that no narrowing is in effect."
+  (let ((last-end (singular-simple-sec-last-end-position))
+	;; `simple-sec' is the new simple section or `empty'
+	simple-sec)
+
+    ;; get beginning of line before END.  At this point we need that there
+    ;; are no restrictions.
+    (setq end (let ((old-point (point)))
+		(goto-char end) (beginning-of-line)
+		(prog1 (point) (goto-char old-point))))
+
+    (cond
+     ;; do not create empty sections
+     ((eq end last-end)
+      'empty)
+     ;; non-clear simple sections
+     ((not (eq type singular-simple-sec-clear-type))
+      ;; if type has not changed we only have to extend the previous simple
+      ;; section.  If `last-end' happens to be 1 (meaning that we are
+      ;; creating the first non-clear simple section in the buffer), then
+      ;; `singular-simple-sec-before' returns nil,
+      ;; `singular-simple-sec-type' returns the type of clear simple
+      ;; sections that definitely does not equal TYPE, and a new simple
+      ;; section is created as necessary.
+      (setq simple-sec (singular-emacs-simple-sec-before last-end))
+      (if (eq type (singular-emacs-simple-sec-type simple-sec))
+	  ;; move existing overlay
+	  (setq simple-sec (move-overlay simple-sec (overlay-start simple-sec) end))
+	;; create new overlay
+	(setq simple-sec (make-overlay last-end end))
+	;; set type property
+	(overlay-put simple-sec 'singular-type type)
+	;; set face
+	(overlay-put simple-sec 'face (singular-simple-sec-lookup-face type))
+	;; evaporate empty sections
+	(overlay-put simple-sec 'evaporate t))
+      ;; update `singular-simple-sec-last-end' and return new simple
+      ;; section
+      (set-marker singular-simple-sec-last-end end)
+      simple-sec)
+     ;; clear simple sections
+     (t
+      ;; update `singular-simple-sec-last-end' and return nil
+      (set-marker singular-simple-sec-last-end end)
+      nil))))
+
+(defun singular-emacs-simple-sec-start-at (pos)
+  "Return start of clear simple section at position POS.
+Assumes the existence of an imagenary empty clear simple section if POS is
+at end of buffer and there is non-clear simple section immediately ending
+at POS.
+Assumes that no narrowing is in effect (since `previous-overlay-change'
+imlicitly does so)."
+  ;; yes, this `(1+ pos)' is OK at eob for
+  ;; `singular-emacs-simple-sec-before' as well as
+  ;; `previous-overlay-change'
+  (let ((previous-overlay-change-pos (1+ pos)))
+    ;; this `while' loop at last will run into the end of the next
+    ;; non-clear simple section or stop at bob.  Since POS may be right at
+    ;; the end of a previous non-clear location, we have to search at least
+    ;; one time from POS+1 backwards.
+    (while (not (or (singular-emacs-simple-sec-before previous-overlay-change-pos)
+		    (eq previous-overlay-change-pos 1)))
+      (setq previous-overlay-change-pos
+	    (previous-overlay-change previous-overlay-change-pos)))
+    previous-overlay-change-pos))
+
+(defun singular-emacs-simple-sec-end-at (pos)
+  "Return end of clear simple section at position POS.
+Assumes the existence of an imagenary empty clear simple section if POS is
+at end of buffer and there is non-clear simple section immediately ending
+at POS.
+Assumes that no narrowing is in effect (since `next-overlay-change'
+imlicitly does so)."
+  (let ((next-overlay-change-pos (next-overlay-change pos)))
+    ;; this `while' loop at last will run into the beginning of the next
+    ;; non-clear simple section or stop at eob.  Since POS may not be at
+    ;; the beginning of a non-clear simple section we may start searching
+    ;; immediately.
+    (while (not (or (singular-emacs-simple-sec-at next-overlay-change-pos)
+		    (eq next-overlay-change-pos (point-max))))
+      (setq next-overlay-change-pos
+	    (next-overlay-change next-overlay-change-pos)))
+    next-overlay-change-pos))
+
+(defun singular-emacs-simple-sec-at (pos)
+  "Return simple section at buffer position POS.
+Assumes the existence of an imagenary empty clear simple section if POS is
+at end of buffer and there is non-clear simple section immediately ending
+at POS.
+Narrowing has no effect on this function."
+  ;; at eob, `overlays-at' always returns nil so everything is OK for this
+  ;; case, too
+  (let ((overlays (overlays-at pos)) simple-sec)
+    ;; be careful, there may be other overlays!
+    (while (and overlays (not simple-sec))
+      (if (singular-emacs-simple-sec-type (car overlays))
+	  (setq simple-sec (car overlays)))
+      (setq overlays (cdr overlays)))
+    simple-sec))
+
+(defun singular-emacs-simple-sec-in (beg end)
+  "Return a list of all simple sections intersecting with the region from BEG to END.
+A simple section intersects the region if the section and the region have
+at least one character in common.  The sections are returned with
+startpoints in increasing order and clear simple sections (that is, nil's)
+inserted as necessary.  BEG is assumed to be less than or equal to END.
+The imagenary empty clear simple section at end of buffer is never included
+in the result.
+Narrowing has no effect on this function."
+  (let (overlays overlay-cursor)
+    (if (= beg end)
+	;; `overlays-in' seems not be correct with respect to this case
+	nil
+      ;; go to END since chances are good that the overlays come in correct
+      ;; order, then
+      (setq overlays (let ((old-point (point)))
+		       (goto-char end)
+		       (prog1 (overlays-in beg end)
+			 (goto-char old-point)))
+
+      ;; now, turn overlays that are not simple sections into nils
+	    overlays (mapcar (function
+			      (lambda (overlay)
+				(and (singular-emacs-simple-sec-type overlay)
+				     overlay)))
+			     overlays)
+      ;; then, remove nils from list
+	    overlays (delq nil overlays)
+      ;; now, we have to sort the list since documentation of `overlays-in'
+      ;; does not state anything about the order the overlays are returned in
+	    overlays
+	    (sort overlays
+		  (function
+		   (lambda (a b)
+		     (< (overlay-start a) (overlay-start b))))))
+
+      ;; at last, we have the list of non-clear simple sections.  Now, go and
+      ;; insert clear simple sections as necessary.
+      (if (null overlays)
+	  ;; if there are no non-clear simple sections at all there can be
+	  ;; only one large clear simple section
+	  '(nil)
+	;; we care about inside clear simple section first
+	(setq overlay-cursor overlays)
+	(while (cdr overlay-cursor)
+	  (if (eq (overlay-end (car overlay-cursor))
+		  (overlay-start (cadr overlay-cursor)))
+	      (setq overlay-cursor (cdr overlay-cursor))
+	    ;; insert nil
+	    (setcdr overlay-cursor
+		    (cons nil (cdr overlay-cursor)))
+	    (setq overlay-cursor (cddr overlay-cursor))))
+	;; now, check BEG and END for clear simple sections
+	(if (> (overlay-start (car overlays)) beg)
+	    (setq overlays (cons nil overlays)))
+	;; `overlay-cursor' still points to the end
+	(if (< (overlay-end (car overlay-cursor)) end)
+	    (setcdr overlay-cursor (cons nil nil)))
+	overlays))))
+;;}}}
+
+;;{{{ Simple section API for XEmacs
+(defsubst singular-xemacs-simple-sec-start (simple-sec)
+  "Return start of non-clear simple section SIMPLE-SEC.
+Narrowing has no effect on this function."
+  (extent-start-position simple-sec))
+
+(defsubst singular-xemacs-simple-sec-end (simple-sec)
+  "Return end of non-clear simple section SIMPLE-SEC.
+Narrowing has no effect on this function."
+  (extent-end-position simple-sec))
+
+(defsubst singular-xemacs-simple-sec-type (simple-sec)
+  "Return type of SIMPLE-SEC.
+Returns nil if SIMPLE-SEC happens to be an extent but not a simple
+section.
+Narrowing has no effect on this function."
+  (if simple-sec
+      (extent-property simple-sec 'singular-type)
+    singular-simple-sec-clear-type))
+
+(defsubst singular-xemacs-simple-sec-before (pos)
+  "Return simple section before buffer position POS.
+This is the same as `singular-simple-sec-at' except if POS falls on a
+section border.  In this case `singular-simple-section-before' returns the
+previous simple section instead of the current one.  If POS falls on
+beginning of buffer, the simple section at beginning of buffer is returned.
+Narrowing has no effect on this function."
+  (singular-xemacs-simple-sec-at (max 1 (1- pos))))
+
+(defun singular-xemacs-simple-sec-create (type end)
+  "Create a new simple section of type TYPE.
+Creates the section from end of previous simple section up to the first
+beginning of line before END.  That position should be larger than or equal
+to `singular-simple-sec-last-end'.  Updates `singular-simple-sec-last-end'.
+Returns the new simple section or `empty' if no simple section has been
+created.
+Assumes that no narrowing is in effect."
+  (let ((last-end (singular-simple-sec-last-end-position))
+	;; `simple-sec' is the new simple section or `empty'
+	simple-sec)
+
+    ;; get beginning of line before END.  At this point we need that there
+    ;; are no restrictions.
+    (setq end (let ((old-point (point)))
+		(goto-char end) (beginning-of-line)
+		(prog1 (point) (goto-char old-point))))
+
+    (cond
+     ;; do not create empty sections
+     ((eq end last-end)
+      'empty)
+     ;; non-clear simple sections
+     ((not (eq type singular-simple-sec-clear-type))
+      ;; if type has not changed we only have to extend the previous simple
+      ;; section.  If `last-end' happens to be 1 (meaning that we are
+      ;; creating the first non-clear simple section in the buffer), then
+      ;; `singular-simple-sec-before' returns nil,
+      ;; `singular-simple-sec-type' returns the type of clear simple
+      ;; sections that definitely does not equal TYPE, and a new simple
+      ;; section is created as necessary.
+      (setq simple-sec (singular-xemacs-simple-sec-before last-end))
+      (if (eq type (singular-xemacs-simple-sec-type simple-sec))
+	  ;; move existing extent
+	  (setq simple-sec (set-extent-endpoints simple-sec
+						 (extent-start-position simple-sec) end))
+	;; create new extent
+	(setq simple-sec (make-extent last-end end))
+	;; set type property
+	(set-extent-property simple-sec 'singular-type type)
+	;; set face.  In contrast to Emacs, we do not need to set somethin
+	;; like `evaporate'.  `detachable' is set by XEmacs by default.
+	(set-extent-property simple-sec 'face (singular-simple-sec-lookup-face type)))
+      ;; update `singular-simple-sec-last-end' and return new simple
+      ;; section
+      (set-marker singular-simple-sec-last-end end)
+      simple-sec)
+     ;; clear simple sections
+     (t
+      ;; update `singular-simple-sec-last-end' and return nil
+      (set-marker singular-simple-sec-last-end end)
+      nil))))
+
+(defun singular-xemacs-simple-sec-start-at (pos)
+  "Return start of clear simple section at position POS.
+Assumes the existence of an imagenary empty clear simple section if POS is
+at end of buffer and there is non-clear simple section immediately ending
+at POS.
+Assumes that no narrowing is in effect (since `previous-extent-change'
+imlicitly does so)."
+  ;; get into some hairy details at end of buffer.  Look if there is a
+  ;; non-clear simple section immediately ending at end of buffer and
+  ;; return the start of the imagenary empty clear simple section in that
+  ;; case.  If buffer is empty this test fails since
+  ;; `singular-xemacs-simple-sec-before' (corretly) returns nil.  But in
+  ;; that case the following loop returns the correct result.
+  (if (and (eq pos (point-max))
+	   (singular-xemacs-simple-sec-before pos))
+      pos
+    (let ((previous-extent-change-pos (min (1+ pos) (point-max))))
+      ;; this `while' loop at last will run into the end of the next
+      ;; non-clear simple section or stop at bob.  Since POS may be right at
+      ;; the end of a previous non-clear location, we have to search at least
+      ;; one time from POS+1 backwards.
+      (while (not (or (singular-xemacs-simple-sec-before previous-extent-change-pos)
+		      (eq previous-extent-change-pos 1)))
+	(setq previous-extent-change-pos
+	      (previous-extent-change previous-extent-change-pos)))
+      previous-extent-change-pos)))
+
+(defun singular-xemacs-simple-sec-end-at (pos)
+  "Return end of clear simple section at position POS.
+Assumes the existence of an imagenary empty clear simple section if POS is
+at end of buffer and there is non-clear simple section immediately ending
+at POS.
+Assumes that no narrowing is in effect (since `next-extent-change'
+imlicitly does so)."
+  (let ((next-extent-change-pos (next-extent-change pos)))
+    ;; this `while' loop at last will run into the beginning of the next
+    ;; non-clear simple section or stop at eob.  Since POS may not be at
+    ;; the beginning of a non-clear simple section we may start searching
+    ;; immediately.
+    (while (not (or (singular-xemacs-simple-sec-at next-extent-change-pos)
+		    (eq next-extent-change-pos (point-max))))
+      (setq next-extent-change-pos
+	    (next-extent-change next-extent-change-pos)))
+    next-extent-change-pos))
+
+(defun singular-xemacs-simple-sec-at (pos)
+  "Return simple section at buffer position POS.
+Assumes the existence of an imagenary empty clear simple section if POS is
+at end of buffer and there is non-clear simple section immediately ending
+at POS.
+Narrowing has no effect on this function."
+  ;; at eob, `map-extent' always returns nil so everything is OK for this
+  ;; case, too.  Do not try to use `extent-at' at this point.  `extent-at'
+  ;; does not return extents outside narrowed text.
+  (map-extents (function (lambda (ext args) ext))
+	       nil pos pos nil nil 'singular-type))
+
+(defun singular-xemacs-simple-sec-in (beg end)
+  "Return a list of all simple sections intersecting with the region from BEG to END.
+A simple section intersects the region if the section and the region have
+at least one character in common.  The sections are returned with
+startpoints in increasing order and clear simple sections (that is, nil's)
+inserted as necessary.  BEG is assumed to be less than or equal to END.
+The imagenary empty clear simple section at end of buffer is never included
+in the result.
+Narrowing has no effect on this function."
+  (let (extents extent-cursor)
+    (if (= beg end)
+	;; `mapcar-extents' may return some extents in this case, so
+	;; exclude it
+	nil
+      ;; OK, that's a little bit easier than for Emacs ...
+      (setq extents (mapcar-extents 'identity nil nil beg end nil 'singular-type))
+
+      ;; now we have the list of non-clear simple sections.  Go and
+      ;; insert clear simple sections as necessary.
+      (if (null extents)
+	  ;; if there are no non-clear simple sections at all there can be
+	  ;; only one large clear simple section
+	  '(nil)
+	;; we care about inside clear simple section first
+	(setq extent-cursor extents)
+	(while (cdr extent-cursor)
+	  (if (eq (extent-end-position (car extent-cursor))
+		  (extent-start-position (cadr extent-cursor)))
+	      (setq extent-cursor (cdr extent-cursor))
+	    ;; insert nil
+	    (setcdr extent-cursor
+		    (cons nil (cdr extent-cursor)))
+	    (setq extent-cursor (cddr extent-cursor))))
+	;; now, check BEG and END for clear simple sections
+	(if (> (extent-start-position (car extents)) beg)
+	    (setq extents (cons nil extents)))
+	;; `extent-cursor' still points to the end
+	(if (< (extent-end-position (car extent-cursor)) end)
+	    (setcdr extent-cursor (cons nil nil)))
+	extents))))
+;;}}}
+
+;;{{{ Section API
+
+;; Note:
+;;
+;; Sections are built on simple sections.  Their purpose is to cover the
+;; difference between clear and non-clear simple sections.
+;;
+;; - Sections consist of a simple section, its type, and its start and end
+;;   points.  This is redundant information only in the case of non-clear
+;;   simple section.
+;; - Sections are read-only objects, neither are they modified nor are they
+;;   created.
+;; - Buffer narrowing does not restrict the extent of completely or
+;;   partially inaccessible sections.  In contrast to simple sections the
+;;   functions concerning sections do not assume that there is no narrowing
+;;   in effect.  However, most functions provide an optional argument
+;;   RESTRICTED that restricts the start and end point of the returned
+;;   sections to the currently active restrictions.  Of course, that does
+;;   not affect the range of the underlying simple sections, only the
+;;   additional start and end points being returned.  One should note that
+;;   by restricting sections one may get empty sections, that is, sections
+;;   for which the additional start and end point are equal.
+;; - In many cases it is not desirable that the user operates on sections
+;;   which are not completely accessible.  To check that a section is
+;;   completely accessible the `singular-section-check' function should be
+;;   used.
+;; - Sections are independent from implementation dependencies.  There are
+;;   no different versions of the functions for Emacs and XEmacs.
+;; - Whenever possible, one should not access simple section directly.
+;;   Instead, one should use the section API.
+
+(defcustom singular-section-face-alist '((input . nil)
+					 (output . singular-section-output-face))
+  "*Alist that maps section types to faces.
+Should be a list consisting of elements (SECTION-TYPE . FACE-OR-NIL), where
+SECTION-TYPE is either `input' or `output'.
+
+At any time, the Singular interactive mode buffer is completely covered by
+sections of two different types: input sections and output sections.  This
+variable determines which faces are used to display the different sections.
+
+If for type SECTION-TYPE the value FACE-OR-NIL is a face it is used to
+display the contents of all sections of that particular type.
+If instead FACE-OR-NIL equals nil sections of that type become so-called
+clear sections.  The content of clear sections is displayed as regular
+text, with no faces at all attached to them.
+
+Some notes and restrictions on this variable (believe them or not):
+o Changing this variable during a Singular session may cause unexpected
+  results (but not too serious ones, though).
+o There may be only one clear section type defined at a time.
+o Choosing clear input sections is a good idea.
+o Choosing clear output sections is a bad idea.
+o Consequence: Not to change this variable is a good idea."
+  ;; to add new section types, simply extend the `list' widget.
+  ;; The rest should work unchanged.  Do not forget to update docu.
+  :type '(list (cons :tag "Input sections"
+		     (const :format "" input)
+		     (choice :format
+"Choose either clear or non-clear input sections.  For non-clear sections,
+select or modify a face (preferably `singular-section-input-face') used to
+display the sections.
+%[Choice%]
+%v
+"
+			     (const :tag "Clear sections" nil)
+			     (face :tag "Non-clear sections")))
+	       (cons :tag "Output sections"
+		     (const :format "" output)
+		     (choice :format
+"Choose either clear or non-clear ouput sections.  For non-clear sections,
+select or modify a face (preferably `singular-section-output-face') used to
+display the sections.
+%[Choice%]
+%v
+"
+			     (const :tag "Clear sections" nil)
+			     (face :tag "Non-clear sections"))))
+  :initialize 'custom-initialize-reset
+  ;; this function checks for validity (only one clear section
+  ;; type) and sets `singular-simple-sec-clear-type' accordingly.
+  ;; In case of an error, nothing is set or modified.
+  :set (function (lambda (var value)
+		   (let* ((cdrs-with-nils (mapcar 'cdr value))
+			  (cdrs-without-nils (delq nil (copy-sequence cdrs-with-nils))))
+		     (if (> (- (length cdrs-with-nils) (length cdrs-without-nils)) 1)
+			 (error "Only one clear section type allowed (see `singular-section-face-alist')")
+		       (set-default var value)
+		       (setq singular-simple-sec-clear-type (car (rassq nil value)))))))
+  :group 'singular-faces
+  :group 'singular-sections-and-foldings)
+
+(defface singular-section-input-face '((t nil))
+  "*Face to use for input sections.
+It may be not sufficient to modify this face to change the appearance of
+input sections.  See `singular-section-face-alist' for more information."
+  :group 'singular-faces
+  :group 'singular-sections-and-foldings)
+
+(defface singular-section-output-face '((t (:bold t)))
+  "*Face to use for output sections.
+It may be not sufficient to modify this face to change the appearance of
+output sections.  See `singular-section-face-alist' for more information."
+  :group 'singular-faces
+  :group 'singular-sections-and-foldings)
+
+(defsubst singular-section-create (simple-sec type start end)
+  "Create and return a new section."
+  (vector simple-sec type start end))
+
+(defsubst singular-section-simple-sec (section)
+  "Return underlying simple section of SECTION."
+  (aref section 0))
+
+(defsubst singular-section-type (section)
+  "Return type of SECTION."
+  (aref section 1))
+
+(defsubst singular-section-start (section)
+  "Return start of SECTION."
+  (aref section 2))
+
+(defsubst singular-section-end (section)
+  "Return end of SECTION."
+  (aref section 3))
+
+(defun singular-section-at (pos &optional restricted)
+  "Return section at position POS.
+Returns section intersected with current restriction if RESTRICTED is
+non-nil."
+  (let* ((simple-sec (singular-simple-sec-at pos))
+	 (type (singular-simple-sec-type simple-sec))
+	 start end)
+    (if simple-sec
+	(setq start (singular-simple-sec-start simple-sec)
+	      end  (singular-simple-sec-end simple-sec))
+      (save-restriction
+	(widen)
+	(setq start (singular-simple-sec-start-at pos)
+	      end (singular-simple-sec-end-at pos))))
+    (cond
+     ;; not restricted first
+     ((not restricted)
+      (singular-section-create simple-sec type start end))
+     ;; restricted and degenerated
+     ((and restricted
+	   (< end (point-min)))
+      (singular-section-create simple-sec type (point-min) (point-min)))
+     ;; restricted and degenerated
+     ((and restricted
+	   (> start (point-max)))
+      (singular-section-create simple-sec type (point-max) (point-max)))
+     ;; restricted but not degenrated
+     (t
+      (singular-section-create simple-sec type
+			       (max start (point-min))
+			       (min end (point-max)))))))
+
+(defun singular-section-before (pos &optional restricted)
+  "Return section before position POS.
+This is the same as `singular-section-at' except if POS falls on a section
+border.  In this case `singular-section-before' returns the previous
+section instead of the current one.  If POS falls on beginning of buffer,
+the section at beginning of buffer is returned.
+Returns section intersected with current restriction if RESTRICTED is
+non-nil."
+  (singular-section-at (max 1 (1- pos)) restricted))
+
+(defun singular-section-in (beg end &optional restricted)
+  "Return a list of all sections intersecting with the region from BEG to END.
+A section intersects with the region if the section and the region have at
+least one character in common.  The sections are returned in increasing
+order.
+If optional argument RESTRICTED is non-nil only sections which are
+completely in the intersection of the region and the current restriction
+are returned."
+  ;; exchange BEG and END if necessary as a special service to our users
+  (let* ((reg-beg (min beg end))
+	 (reg-end (max beg end))
+	 ;; we need these since we widen the buffer later on
+	 (point-min (point-min))
+	 (point-max (point-max))
+	 simple-sections)
+    (if (and restricted
+	     (or (> reg-beg point-max) (< reg-end point-min)))
+	;; degenerate restrictions
+	nil
+      ;; do the intersection if necessary and get simple sections
+      (setq reg-beg (if restricted (max reg-beg point-min) reg-beg)
+	    reg-end (if restricted (min reg-end point-max) reg-end)
+	    simple-sections (singular-simple-sec-in reg-beg reg-end))
+      ;; we still have REG-BEG <= REG-END in any case.  SIMPLE-SECTIONS
+      ;; contains the list of simple sections intersecting with the region
+      ;; from REG-BEG and REG-END.
+
+      (if (null simple-sections)
+	  nil
+	;; and here we even have REG-BEG < REG-END
+	(save-restriction
+	  (widen)
+	  ;; get sections intersecting with the region from REG-BEG to
+	  ;; REG-END
+	  (let* ((sections (singular-section-in-internal simple-sections
+							 reg-beg reg-end))
+		 first-section-start last-section-end)
+	    (if (not restricted)
+		sections
+	      (setq first-section-start (singular-section-start (car sections))
+		    last-section-end (singular-section-end (car (last sections))))
+	      ;; popping off first element is easy ...
+	      (if (< first-section-start point-min)
+		  (setq sections (cdr sections)))
+	      ;; ... but last element is harder to pop off
+	      (cond
+	       (;; no elements left
+		(null sections)
+		nil)
+	       (;; one element left
+		(null (cdr sections))
+		(if (> last-section-end point-max)
+		    nil
+		  sections))
+	       (;; more than one element left
+		t
+		(if (> last-section-end point-max)
+		    (setcdr (last sections 2) nil))
+		sections)))))))))
+
+(defun singular-section-in-internal (simple-sections reg-beg reg-end)
+  "Create a list of sections from SIMPLE-SECTIONS.
+This is the back-end for `singular-section-in'.
+First simple section should be such that it contains REG-BEG, last simple
+section should be such that it contains or ends at REG-END.  These
+arguments are used to find the start resp. end of clear simple sections of
+terminal clear simple sections in SIMPLE-SECTIONS.
+Assumes that REG-BEG < REG-END.
+Assumes that SIMPLE-SECTIONS is not empty.
+Assumes that no narrowing is in effect."
+  (let* (;; we pop off the extra nil at the end of the loop
+	 (sections (cons nil nil))
+	 (sections-end sections)
+	 (simple-section (car simple-sections))
+	 type start end)
+
+    ;; first, get unrestricted start
+    (setq start (if simple-section
+		    (singular-simple-sec-start simple-section)
+		  ;; here we need that no narrowing is in effect
+		  (singular-simple-sec-start-at reg-beg)))
+
+    ;; loop through all simple sections but last
+    (while (cdr simple-sections)
+      (setq simple-section (car simple-sections)
+	    type (singular-simple-sec-type simple-section)
+	    end (if simple-section
+		    (singular-simple-sec-end simple-section)
+		  (singular-simple-sec-start (cadr simple-sections)))
+
+	    ;; append the new section to `sections-end'
+	    sections-end
+	    (setcdr sections-end
+		    (cons (singular-section-create simple-section type start end) nil))
+
+	    ;; get next simple section and its start
+	    simple-sections (cdr simple-sections)
+	    start end))
+
+    ;; care about last simple section
+    (setq simple-section (car simple-sections)
+	  type (singular-simple-sec-type simple-section)
+	  end (if simple-section
+		  (singular-simple-sec-end simple-section)
+		;; the `1-' is OK since REG-BEG < REG-END.
+		;; here we need that no narrowing is in effect
+		(singular-simple-sec-end-at (1- reg-end))))
+    (setcdr sections-end
+	    (cons (singular-section-create simple-section type start end) nil))
+
+    ;; we should not forget to pop off our auxilliary cons-cell
+    (cdr sections)))
+
+(defun singular-section-mapsection (func sections &optional type-filter negate-filter)
+  "Apply FUNC to each section in SECTIONS, and make a list of the results.
+If optional argument TYPE-FILTER is non-nil it should be a list of section
+types.  FUNC is then applied only to those sections with type occuring in
+TYPE-FILTER.  If in addition optional argument NEGATE-FILTER is non-nil
+FUNC is applied only to those sections with type not occuring in
+TYPE-FILTER.
+
+In any case the length of the list this function returns equals the
+number of sections actually processed."
+  (if (not type-filter)
+      (mapcar func sections)
+    ;; copy the list first
+    (let ((sections (copy-sequence sections)))
+      ;; filter elements and turn them to t's
+      (setq sections
+	    (mapcar (function
+		     (lambda (section)
+		       ;; that strange expression evaluates to t iff the
+		       ;; section should be removed.  The `not' is to
+		       ;; canonize boolean values to t or nil, resp.
+		       (or (eq (not (memq (singular-section-type section) type-filter))
+			       (not negate-filter))
+			   section)))
+		    sections)
+
+      ;; remove t's now
+	    sections (delq t sections))
+
+      ;; call function for remaining sections
+      (mapcar func sections))))
+;;}}}
+
+;;{{{ Section miscellaneous
+(defun singular-section-check (section &optional no-error)
+  "Check whether SECTION is completely accessible and return t if so.
+If otherwise SECTION is restricted either in part or as a whole, this
+function fails with an error or returns nil if optional argument NO-ERROR
+is non-nil."
+  (cond ((and (>= (singular-section-start section) (point-min))
+	      (<= (singular-section-end section) (point-max))) t)
+	(no-error nil)
+	(t (error "section is restricted either in part or as a whole"))))
+
+(defun singular-section-to-string (section &optional raw)
+  "Get contents of SECTION as a string.
+Returns text between start and end of SECTION.
+Removes prompts from section contents unless optional argument RAW is
+non-nil.
+Narrowing has no effect on this function."
+  (save-restriction
+    (widen)
+    (let ((string (buffer-substring (singular-section-start section)
+				    (singular-section-end section))))
+      (if raw
+	  string
+	(singular-prompt-remove-string string)))))
+;;}}}
+
+;;{{{ Section miscellaneous interactive
+(defun singular-section-goto-beginning ()
+  "Move point to beginning of current section."
+  (interactive)
+  (goto-char (singular-section-start (singular-section-at (point))))
+  (singular-keep-region-active))
+
+(defun singular-section-goto-end ()
+  "Move point to end of current section."
+  (interactive)
+  (goto-char (singular-section-end (singular-section-at (point))))
+  (singular-keep-region-active))
+
+(defun singular-section-backward (n)
+  "Move backward until encountering the beginning of a section.
+With argument, do this that many times.  With N less than zero, call
+`singular-section-forward' with argument -N."
+  (interactive "p")
+  (while (> n 0)
+    (goto-char (singular-section-start (singular-section-before (point))))
+    (setq n (1- n)))
+  (if (< n 0)
+      (singular-section-forward (- n))
+    (singular-keep-region-active)))
+
+(defun singular-section-forward (n)
+  "Move forward until encountering the end of a section.
+With argument, do this that many times.  With N less than zero, call
+`singular-section-backward' with argument -N."
+  (interactive "p")
+  (while (> n 0)
+    (goto-char (singular-section-end (singular-section-at (point))))
+    (setq n (1- n)))
+  (if (< n 0)
+      (singular-section-backward (- n))
+    (singular-keep-region-active)))
+
+(defun singular-section-kill (section &optional raw no-error)
+  "Kill SECTION.
+Puts the contents of SECTION into the kill ring.  Removes prompts from
+contents unless optional argument RAW is non-nil.
+If called interactively, kills section point currently is in.  Does a raw
+section kill if called with a prefix argument, otherwise strips prompts.
+Does not kill sections that are restricted either in part or as a whole.
+Rather fails with an error in such cases or silently fails if optional
+argument NO-ERROR is non-nil."
+  (interactive (list (singular-section-at (point))
+		     current-prefix-arg nil))
+  (when (singular-section-check section no-error)
+    (kill-new (singular-section-to-string section raw))
+    (delete-region (singular-section-start section)
+		   (singular-section-end section))))
+;;}}}
+
+;;{{{ Folding sections for both Emacs and XEmacs
+(defcustom singular-folding-ellipsis "Singular I/O ..."
+  "*Ellipsis to show for folded input or output.
+Changing this variable has an immediate effect only if one uses
+\\[customize] to do so.
+However, even then it may be necessary to refresh display completely (using
+\\[recenter], for example) for the new settings to be visible."
+  :type 'string
+  :initialize 'custom-initialize-default
+  :set (function
+	(lambda (var value)
+	  ;; set in all singular buffers
+	  (singular-map-buffer 'singular-folding-set-ellipsis value)
+	  (set-default var value)))
+  :group 'singular-sections-and-foldings)
+
+(defcustom singular-folding-line-move-ignore-folding t
+  "*If non-nil, ignore folded sections when moving point up or down.
+This variable is used to initialize `line-move-ignore-invisible'.  However,
+documentation states that setting `line-move-ignore-invisible' to a non-nil
+value may result in a slow-down when moving the point up or down.  One
+should try to set this variable to nil if point motion seems too slow.
+
+Changing this variable has an immediate effect only if one uses
+\\[customize] to do so."
+  :type 'boolean
+  :initialize 'custom-initialize-default
+  :set (function
+	(lambda (var value)
+	  ;; set in all singular buffers
+	  (singular-map-buffer 'set 'line-move-ignore-invisible value)
+	  (set-default var value)))
+  :group 'singular-sections-and-foldings)
+
+(defun singular-folding-set-ellipsis (ellipsis)
+  "Set ellipsis to show for folded input or output in current buffer."
+  (cond
+   ;; Emacs
+   ((eq singular-emacs-flavor 'emacs)
+    (setq buffer-display-table (or (copy-sequence standard-display-table)
+				   (make-display-table)))
+    (set-display-table-slot buffer-display-table
+			    'selective-display (vconcat ellipsis)))
+   ;; XEmacs
+   (t
+    (set-glyph-image invisible-text-glyph ellipsis (current-buffer)))))
+
+(defun singular-folding-init ()
+  "Initializes folding of sections for the current buffer.
+That includes setting `buffer-invisibility-spec' and the ellipsis to show
+for hidden text.
+
+This function is called at mode initialization time."
+  ;; initialize `buffer-invisibility-spec' first
+  (let ((singular-invisibility-spec (cons 'singular-interactive-mode t)))
+    (if (and (listp buffer-invisibility-spec)
+	     (not (member singular-invisibility-spec buffer-invisibility-spec)))
+	(setq buffer-invisibility-spec
+	      (cons singular-invisibility-spec buffer-invisibility-spec))
+      (setq buffer-invisibility-spec (list singular-invisibility-spec))))
+  ;; ignore invisible lines on movements
+  (set (make-local-variable 'line-move-ignore-invisible)
+       singular-folding-line-move-ignore-folding)
+  ;; now for the ellipsis
+  (singular-folding-set-ellipsis singular-folding-ellipsis))
+
+(defun singular-folding-fold (section &optional no-error)
+  "Fold section SECTION if it is not already folded.
+Does not fold sections that do not end in a newline or that are restricted
+either in part or as a whole.  Rather fails with an error in such cases
+or silently fails if optional argument NO-ERROR is non-nil.
+This is for safety only: In both cases the result may be confusing to the
+user."
+  (let* ((start (singular-section-start section))
+	 (end (singular-section-end section)))
+    (cond ((not (singular-section-check section no-error))
+	   nil)
+	  ((not (eq (char-before end) ?\n))
+	   (unless no-error
+	     (error "Section does not end in a newline")))
+	  ((not (singular-folding-foldedp section))
+	   ;; fold but only if not already folded
+	   (singular-folding-fold-internal section)))))
+
+(defun singular-folding-unfold (section &optional no-error invisibility-overlay-or-extent)
+  "Unfold section SECTION if it is not already unfolded.
+Does not unfold sections that are restricted either in part or as a whole.
+Rather fails with an error in such cases or silently fails if optional
+argument NO-ERROR is non-nil.
+This is for safety only: The result may be confusing to the user.
+If optional argument INVISIBILITY-OVERLAY-OR-EXTENT is non-nil it should be
+the invisibility overlay or extent, respectively, of the section to
+unfold."
+  (let* ((start (singular-section-start section))
+	 (end (singular-section-end section)))
+    (cond ((not (singular-section-check section no-error))
+	   nil)
+	  ((or invisibility-overlay-or-extent
+	       (setq invisibility-overlay-or-extent (singular-folding-foldedp section)))
+	   ;; unfold but only if not already unfolded
+	   (singular-folding-unfold-internal section invisibility-overlay-or-extent)))))
+
+(defun singular-folding-fold-at-point ()
+  "Fold section point currently is in.
+Does not fold sections that do not end in a newline or that are restricted
+either in part or as a whole.  Rather fails with an error in such cases."
+  (interactive)
+  (singular-folding-fold (singular-section-at (point))))
+
+(defun singular-folding-unfold-at-point ()
+  "Unfold section point currently is in.
+Does not unfold sections that are restricted either in part or as a whole.
+Rather fails with an error in such cases."
+  (interactive)
+  (singular-folding-unfold (singular-section-at (point))))
+
+(defun singular-folding-fold-latest-output ()
+  "Fold latest output section.
+Does not fold sections that do not end in a newline or that are restricted
+either in part or as a whole.  Rather fails with an error in such cases."
+  (interactive)
+  (singular-folding-fold (singular-latest-output-section)))
+
+(defun singular-folding-unfold-latest-output ()
+  "Unfolds latest output section.
+Does not unfold sections that are restricted either in part or as a whole.
+Rather fails with an error in such cases."
+  (interactive)
+  (singular-folding-unfold (singular-latest-output-section)))
+
+(defun singular-folding-fold-all-output ()
+  "Fold all complete, unfolded output sections.
+That is, all output sections that are not restricted in part or as a whole
+and that end in a newline."
+  (interactive)
+  (singular-section-mapsection (function (lambda (section) (singular-folding-fold section t)))
+			       (singular-section-in (point-min) (point-max) t)
+			       '(output)))
+
+(defun singular-folding-unfold-all-output ()
+  "Unfold all complete, folded output sections.
+That is, all output sections that are not restricted in part or as a whole."
+  (interactive)
+  (singular-section-mapsection (function (lambda (section) (singular-folding-unfold section t)))
+			       (singular-section-in (point-min) (point-max) t)
+			       '(output)))
+
+(defun singular-folding-toggle-fold-at-point-or-all (&optional arg)
+  "Fold or unfold section point currently is in or all output sections.
+Without prefix argument, folds unfolded sections and unfolds folded
+sections.  With prefix argument, folds all output sections if argument is
+positive, otherwise unfolds all output sections.
+Does neither fold nor unfold sections that do not end in a newline or that
+are restricted either in part or as a whole.  Rather fails with an error in
+such cases."
+  (interactive "P")
+    (cond ((not arg)
+	   ;; fold or unfold section at point
+	   (let* ((section (singular-section-at (point)))
+		  (invisibility-overlay-or-extent (singular-folding-foldedp section)))
+	     (if invisibility-overlay-or-extent
+		 (singular-folding-unfold section nil invisibility-overlay-or-extent)
+	       (singular-folding-fold section))))
+	  ((> (prefix-numeric-value arg) 0)
+	   (singular-folding-fold-all-output))
+	  (t
+	   (singular-folding-unfold-all-output))))
+
+(defun singular-folding-toggle-fold-latest-output (&optional arg)
+  "Fold or unfold latest output section.
+Folds unfolded sections and unfolds folded sections.
+Does neither fold nor unfold sections that do not end in a newline or that
+are restricted either in part or as a whole.  Rather fails with an error in
+such cases."
+  (interactive)
+  (let* ((section (singular-latest-output-section))
+	 (invisibility-overlay-or-extent (singular-folding-foldedp section)))
+    (if invisibility-overlay-or-extent
+	(singular-folding-unfold section nil invisibility-overlay-or-extent)
+      (singular-folding-fold section))))
+
+;; Note:
+;;
+;; The rest of the folding is either marked as
+;; Emacs
+;; or
+;; XEmacs
+
+(singular-fset 'singular-folding-fold-internal
+	       'singular-emacs-folding-fold-internal
+	       'singular-xemacs-folding-fold-internal)
+
+(singular-fset 'singular-folding-unfold-internal
+	       'singular-emacs-folding-unfold-internal
+	       'singular-xemacs-folding-unfold-internal)
+
+(singular-fset 'singular-folding-foldedp
+	       'singular-emacs-folding-foldedp-internal
+	       'singular-xemacs-folding-foldedp-internal)
+;;}}}
+
+;;{{{ Folding sections for Emacs
+
+;; Note:
+;;
+;; For Emacs, we use overlays to hide text (so-called "invisibility
+;; overlays").  In addition to their `invisible' property, they have the
+;; `singular-invisible' property set.  Setting the intangible property does
+;; not work very well for Emacs.  We use the variable
+;; `line-move-ignore-invisible' which works quite well.
+
+(defun singular-emacs-folding-fold-internal (section)
+  "Fold section SECTION.
+SECTION should end in a newline.  That terminal newline is not
+folded or otherwise ellipsis does not appear.
+SECTION should be unfolded."
+  (let* ((start (singular-section-start section))
+	 ;; do not make trailing newline invisible
+	 (end (1- (singular-section-end section)))
+	 invisibility-overlay)
+    ;; create new overlay and add properties
+    (setq invisibility-overlay (make-overlay start end))
+    ;; mark them as invisibility overlays
+    (overlay-put invisibility-overlay 'singular-invisible t)
+    ;; set invisible properties
+    (overlay-put invisibility-overlay 'invisible 'singular-interactive-mode)
+    ;; evaporate empty invisibility overlays
+    (overlay-put invisibility-overlay 'evaporate t)))
+
+(defun singular-emacs-folding-unfold-internal (section &optional invisibility-overlay)
+  "Unfold section SECTION.
+SECTION should be folded.
+If optional argument INVISIBILITY-OVERLAY is non-nil it should be the
+invisibility overlay of the section to unfold."
+  (let ((invisibility-overlay
+	 (or invisibility-overlay
+	     (singular-emacs-folding-foldedp-internal section))))
+    ;; to keep number of overlays low we delete it
+    (delete-overlay invisibility-overlay)))
+
+(defun singular-emacs-folding-foldedp-internal (section)
+  "Returns non-nil iff SECTION is folded.
+More specifically, returns the invisibility overlay if there is one.
+Narrowing has no effect on this function."
+  (let* ((start (singular-section-start section))
+	 (overlays (overlays-at start))
+	 invisibility-overlay)
+    ;; check for invisibility overlay
+    (while (and overlays (not invisibility-overlay))
+      (if (overlay-get (car overlays) 'singular-invisible)
+	  (setq invisibility-overlay (car overlays))
+	(setq overlays (cdr overlays))))
+    invisibility-overlay))
+;;}}}
+
+;;{{{ Folding sections for XEmacs
+
+;; Note:
+;;
+;; For XEmacs, we use extents to hide text (so-called "invisibility
+;; extents").  In addition to their `invisible' property, they have the
+;; `singular-invisible' property set.  To ignore invisible text we use the
+;; variable `line-move-ignore-invisible' which works quite well.
+
+(defun singular-xemacs-folding-fold-internal (section)
+  "Fold section SECTION.
+SECTION should end in a newline.  That terminal newline is not
+folded or otherwise ellipsis does not appear.
+SECTION should be unfolded."
+  (let* ((start (singular-section-start section))
+	 ;; do not make trailing newline invisible
+	 (end (1- (singular-section-end section)))
+	 invisibility-extent)
+    ;; create new extent and add properties
+    (setq invisibility-extent (make-extent start end))
+    ;; mark them as invisibility extents
+    (set-extent-property invisibility-extent 'singular-invisible t)
+    ;; set invisible properties
+    (set-extent-property invisibility-extent 'invisible 'singular-interactive-mode)))
+
+(defun singular-xemacs-folding-unfold-internal (section &optional invisibility-extent)
+  "Unfold section SECTION.
+SECTION should be folded.
+If optional argument INVISIBILITY-EXTENT is non-nil it should be the
+invisibility extent of the section to unfold."
+  (let ((invisibility-extent
+	 (or invisibility-extent
+	     (singular-xemacs-folding-foldedp-internal section))))
+    ;; to keep number of extents low we delete it
+    (delete-extent invisibility-extent)))
+
+(defun singular-xemacs-folding-foldedp-internal (section)
+  "Returns non-nil iff SECTION is folded.
+More specifically, returns the invisibility extent if there is one.
+Narrowing has no effect on this function."
+  ;; do not try to use `extent-at' at this point.  `extent-at' does not
+  ;; return extents outside narrowed text.
+  (let* ((start (singular-section-start section))
+	 (invisibility-extent (map-extents
+			    (function (lambda (ext args) ext))
+			    nil start start nil nil 'singular-invisible)))
+    invisibility-extent))
+;;}}}
+
+;;{{{ Online help
+
+;; Note:
+;;
+;; Catching user's help commands to Singular and translating them to calls
+;; to `info' is quite a difficult task due to the asynchronous nature of
+;; communication with Singular.  We use an heuristic approach which should
+;; work in most cases:
+;;
+;; - `singular-help-pre-input-filter' scans user's input for help commands.
+;;   If user issues a help command the filter sets a time stamp and passes
+;;   the input unchanged to Singular.
+;; - Singular receives the help command and barfs that it could not process
+;;   it.  We call that error message "Singular's response".  That response
+;;   in particular contains the help topic the user requested.  If the
+;;   response for some reasons is not recognized and filtered in the later
+;;   steps the user gets some reasonable response on her command that way.
+;; - `singular-help-pre-output-filter' on each output from Singular checks
+;;   (using the time stamp set by `singular-help-pre-input-filter') whether
+;;   the user issued a help command at most one second ago.  If so,
+;;   `singular-help-pre-output-filter' starts checking Singular's output
+;;   for the response on the help command.  If it finds one it remembers
+;;   the help topic in `singular-help-topic' and removes the response from
+;;   Singular's output.
+;;   There is some extra magic built into the filter to handle responses
+;;   from Singular which are received by emacs not in one string but in
+;;   more than one piece (we call that pending output).
+;; - As the last step step of this procedure, `singular-post-output-filter'
+;;   fires up an Info buffer using `singular-help' if the variable
+;;   `singular-help-topic' is non-nil.  This step is separated from the
+;;   previous one since joining both leads to some trouble in point
+;;   management.  This is mainly due to the fact that `singular-help' opens
+;;   a new window.
+;;
+;; To show some online help, the online help manual has to be available, of
+;; course.  There is a number of possibilites for the user to set the file
+;; name of the manual explicitly, as described in the documentation string
+;; to `singular-help'.  But in general the file name should be recognized
+;; automatically by Singular interactive mode.  For that to work, Singular
+;; prints the file name when it comes up and option `--emacs' is specified.
+;; This is recognized by `singular-scan-header-pre-output-filter' which
+;; sets the variable `singular-help-file-name' accordingly.  For more
+;; information one should refer to the `Header scanning ...' folding.
+;;
+;; Another variable which needs to be set for proper operation is
+;; `singular-help-topics-alist' for completion of help topics and for
+;; recognition of help topics around point.  It is no error for this
+;; variable not to be set: simply the features do not work then.
+
+;; this `require' is necessary since we use functions from the Info package
+;; which are not declared as `autoload'
+(require 'info)
+
+(defcustom singular-help-same-window 'default
+  "*Specifies how to open the window for Singular online help.
+If this variable equals t, Singular online help comes up in the selected
+window.
+If this variable equals nil, Singular online help comes up in another
+window.
+If this variable equals neither t nor nil, the standard Emacs behaviour to
+open the Info buffer is adopted (which very much depends on the settings of
+`same-window-buffer-names')."
+  :initialize 'custom-initialize-default
+  :type '(choice (const :tag "This window" t)
+		 (const :tag "Other window" nil)
+		 (const :tag "Default" default))
+  :group 'singular-interactive-miscellaneous)
+
+(defcustom singular-help-explicit-file-name nil
+  "*Specifies the file name of the Singular online manual.
+If non-nil, used as file name of the Singular online manual.
+
+This variable should be customized only if all other attempts of Singular
+interactive mode fail to determine the file name of the Singular online
+manual.  For more information one should refer to the `singular-help'
+function."
+  :initialize 'custom-initialize-default
+  :type '(choice (const nil) file)
+  :group 'singular-interactive-miscellaneous)
+
+(defvar singular-help-file-name nil
+  "File name of the Singular online manual.
+This variable should not be modified by the user.
+
+This variable is buffer-local.")
+
+(defconst singular-help-fall-back-file-name "singular.hlp"
+  "Fall-back file name of the Singular online manual.
+This variable is used if the file name of the Singular online manual cannot
+be determined otherwise.")
+
+(defvar singular-help-time-stamp '(0 0)
+  "The time stamp that is set when the user issues a help command.
+
+This variable is buffer-local.")
+
+(defvar singular-help-response-pending nil
+  "If non-nil, Singular's response has not been completely received.
+
+This variable is buffer-local.")
+
+(defvar singular-help-topic nil
+  "If non-nil, contains help topic to show in post output filter.
+
+This variable is buffer-local.")
+
+(defconst singular-help-command-regexp "^\\s-*\\(help\\|\?\\)"
+  "Regular expression to match Singular help commands.")
+
+(defconst singular-help-response-line-1
+  "^// \\*\\* Your help command could not be executed\\. Use\n"
+  "Regular expression that matches the first line of Singular's response.")
+
+(defconst singular-help-response-line-2
+  "^// \\*\\* C-h C-s \\(.*\\)\n"
+  "Regular expression that matches the second line of Singular's response.
+First subexpression matches help topic.")
+
+(defconst singular-help-response-line-3
+  "^// \\*\\* to enter the Singular online help\\. For general\n"
+  "Regular expression that matches the third line of Singular's response.")
+
+(defconst singular-help-response-line-4
+  "^// \\*\\* information on Singular running under Emacs, type C-h m\\.\n"
+  "Regular expression that matches the fourth line of Singular's response.")
+
+(defun singular-help-pre-input-filter (input)
+  "Check user's input for help commands.
+Sets time stamp if one is found.  Passes user's input on to Singular
+unchanged."
+  (if (string-match singular-help-command-regexp input)
+      (setq singular-help-time-stamp (current-time)))
+  ;; return nil so that input passes unchanged
+  nil)
+
+(defun singular-help-pre-output-filter (output)
+  "Check for Singular's response on a help command.
+Removes it and sets `singular-help-topic' accordingly."
+  ;; check first
+  ;; - whether a help statement has been issued at most one second ago, or
+  ;; - whether there is a pending response.
+  ;; Only if one of these conditions is met we go on and check text for a
+  ;; response on a help command.  Checking uncoditionally every piece of
+  ;; output would be far too expensive.
+  ;; If check fails nil is returned, what is exactly what we need for the
+  ;; filter.
+  (if (or (= (cadr (current-time)) (cadr singular-help-time-stamp))
+	  singular-help-response-pending)
+      ;; if response is pending for more than five seconds, give up
+      (if (and singular-help-response-pending
+	       (> (singular-time-stamp-difference (current-time) singular-help-time-stamp) 5))
+	  ;; this command returns nil, what is exactly what we need for the filter
+	  (setq singular-help-response-pending nil)
+	;; go through output, removing the response.  If there is a
+	;; pending response we nevertheless check for all lines, not only
+	;; for the pending one.  At last, pending responses should not
+	;; occur to often.
+	(when (string-match singular-help-response-line-1 output)
+	  (setq output (replace-match "" t t output))
+	  (setq singular-help-response-pending t))
+	(when (string-match singular-help-response-line-2 output)
+	  ;; after all, we found what we are looking for
+	  (setq singular-help-topic (substring output (match-beginning 1) (match-end 1)))
+	  (setq output (replace-match "" t t output))
+	  (setq singular-help-response-pending t))
+	(when (string-match singular-help-response-line-3 output)
+	  (setq output (replace-match "" t t output))
+	  (setq singular-help-response-pending t))
+	(when (string-match singular-help-response-line-4 output)
+	  (setq output (replace-match "" t t output))
+	  ;; we completely removed the help from output!
+	  (setq singular-help-response-pending nil))
+
+	;; return modified OUTPUT
+	output)))
+
+(defun singular-help-post-output-filter (&rest ignore)
+  "Call `singular-help' if `singular-help-topic' is non-nil."
+  (when singular-help-topic
+    (save-excursion
+      (singular-help singular-help-topic))
+    (setq singular-help-topic nil)))
+
+(defvar singular-help-topic-history nil
+  "History of help topics used as arguments to `singular-help'.")
+
+(defun singular-help (&optional help-topic)
+  "Show help on HELP-TOPIC in Singular online manual.
+
+The file name of the Singular online manual is determined in the following
+manner:
+o if the \(customizable) variable `singular-help-explicit-file-name' is
+  non-nil, it is used as file name;
+o otherwise, if the variable `singular-help-file-name' is non-nil, is is
+  used as file name.  This variable should be set by Singular interactive
+  mode itself, but there may be instances where this fails.  Anyway, it
+  should be not set by the user.
+o otherwise, if the environment variable SINGULAR_INFO_FILE is set, it is
+  used as file name;
+o otherwise, the constant `singular-help-fall-back-file-name' is used
+  as file name."
+  (interactive
+   (list (completing-read "Help topic: " singular-help-topics-alist
+			  nil nil nil 'singular-help-topic-history)))
+
+  ;; get help file and topic
+  (let ((help-file-name (or singular-help-explicit-file-name
+			    singular-help-file-name
+			    (getenv "SINGULAR_INFO_FILE")
+			    singular-help-fall-back-file-name))
+	(help-topic (cond ((or (null help-topic)
+			       (string= help-topic ""))
+			   "Top")
+			  ;; try to get the real topic from the alist.
+			  ;; It's OK if the alist is empty.
+			  ((cdr (assoc help-topic
+				       singular-help-topics-alist)))
+			  (t help-topic)))
+	(continue t))
+
+    ;; pop to Info buffer
+    (singular-pop-to-buffer singular-help-same-window "*info*")
+
+    ;; test whether we are already in Singular's online manual
+    (unless (and (boundp 'Info-current-file)
+		 (equal Info-current-file help-file-name))
+      ;; jump to Singular's top node
+      (condition-case signal
+	  (Info-find-node help-file-name "Top")
+	;; in case of an error jump to info directory
+	(error
+	 (Info-directory)
+	 ;; if we have been called interactively we pass the error down,
+	 ;; otherwise we assumes that we have been called from a hook and
+	 ;; call `singular-error'
+	 (if (interactive-p)
+	     (signal (car signal) (cdr signal))
+	   (singular-error "Singular online manual %s not found"
+			   help-file-name))
+	 ;; do not continue
+	 (setq continue nil))))
+
+    (when continue
+      ;; jump to desired node
+      (condition-case signal
+	  (Info-goto-node help-topic)
+	;; in case of an error jump to Singular's top node
+	(error
+	 (Info-goto-node "Top")
+	 ;; if we have been called interactively we pass the error down,
+	 ;; otherwise we assumes that we have been called from a hook and
+	 ;; call `singular-error'
+	 (if (interactive-p)
+	     (signal (car signal) (cdr signal))
+	   (singular-error "Singular help topic %s not found"
+			   help-topic)))))))
+
+;; This might not be the best place for singular-example, but this function
+;; is some kind of singular help, so the place is not too bad.
+;; Note: We use singular-help-topic-history for singular-example, too
+(defun singular-example (&optional command)
+  "Show Singular example on COMMAND."
+  (interactive
+   (list (completing-read "Example for: " singular-examples-alist
+			  nil nil nil 'singular-help-topic-history)))
+  (let ((process (singular-process))
+	(string (concat "example " command ";")))
+    (singular-input-filter process string)
+    (singular-send-string process string)))
+
+(defun singular-help-init ()
+  "Initialize online help support for Singular interactive mode.
+
+This function is called at mode initialization time."
+  (make-local-variable 'singular-help-file-name)
+  (make-local-variable 'singular-help-time-stamp)
+  (make-local-variable 'singular-help-response-pending)
+  (make-local-variable 'singular-help-topic)
+  (add-hook 'singular-pre-input-filter-functions 'singular-help-pre-input-filter)
+  (add-hook 'singular-pre-output-filter-functions 'singular-help-pre-output-filter)
+  (add-hook 'singular-post-output-filter-functions 'singular-help-post-output-filter))
+;;}}}
+
+;;{{{ Singular commands, help topics and standard libraries alists
+(defvar singular-commands-alist nil
+  "An alist containing all Singular commands to complete.
+
+This variable is buffer-local.")
+
+(defvar singular-help-topics-alist nil
+  "An alist containg all Singular help topics to complete.
+
+This variable is buffer-local.")
+
+(defvar singular-standard-libraries-with-categories nil
+  "A list containing all Singular standard library names and their category.
+
+This variable is buffer-local.")
+
+(defvar singular-standard-libraries-alist nil
+  "An alist containing all Singular standard library names.
+This variable is set automatically by `singular-menu-install-libraries'
+using the value of `singular-standard-libraries-with-categories'.
+
+This variable is buffer-local.")
+;;}}}
+
+;;{{{ Scanning of header and handling of emacs home directory
+;;
+;; Scanning of header
+;;
+(defconst singular-scan-header-emacs-home-regexp "^// \\*\\* EmacsDir: \\(.+\\)\n"
+  "Regular expression matching the location of emacs home in Singular
+header.")
+
+(defconst singular-scan-header-info-file-regexp "^// \\*\\* InfoFile: \\(.+\\)\n"
+  "Regular expression matching the location of Singular info file in
+Singular header.")
+
+(defconst singular-scan-header-time-stamp 0
+  "A time stamp set by singular-scan-header.
+
+This variable is buffer-local.")
+
+(defvar singular-scan-header-scan-for '()
+  "List of things to scan for in Singular header.
+If `singular-scan-header-pre-output-filter' finds one thing in the current
+output, it removes the corresponding value from the list.
+If this variable gets nil, `singular-scan-header-pre-output-filter' is
+removed from the pre-output-filter.
+This variable is initialized in `singular-scan-header-init'. Possible
+values of this list are up to now `help-file' and `emacs-home'.
+
+This variable is buffer-local.")
+
+(defun singular-scan-header-got-emacs-home ()
+  "Load Singular completion and libraries files.
+Assumes that `singular-emacs-home-directory' is set to the appropriate
+value and loads the files \"cmd-cmpl.el\", \"hlp-cmpl.el\", \"ex-cmpl.el\",
+and \"lib-cmpl.el\".
+On success calls `singular-menu-install-libraries'."
+  (or (load (singular-expand-emacs-file-name "cmd-cmpl.el" t) t t t)
+      (message "Can't find command completion file! Command completion disabled."))
+  (or (load (singular-expand-emacs-file-name "hlp-cmpl.el" t) t t t)
+      (message "Can't find help topic completion file! Help completion disabled."))
+  (or (load (singular-expand-emacs-file-name "ex-cmpl.el" t) t t t)
+      (message "Can't find examples completion file! Examples completion disabled."))
+  (if (load (singular-expand-emacs-file-name "lib-cmpl.el" t) t t t)
+      (singular-menu-install-libraries)
+    (message "Can't find library index file!")))
+
+
+(defun singular-scan-header-pre-output-filter (output)
+  "Filter function for hook `singular-pro-output-filter-functions'.
+Scans the Singular header for special markers using the regexps
+`singular-scan-header-info-file-regexp' and
+`singular-scan-header-emacs-home-regexp', removes them, loads the
+completion files, the library-list file, calls
+`singular-menu-install-libraries' and sets `singular-help-file-name'.
+Removes itself from the hook if all special markers were found or if it has
+been searching for more than 20 seconds."
+  (singular-debug 'interactive (message "scanning header"))
+  (let ((changed nil))
+
+    ;; Search for emacs home directory
+    (when (string-match singular-scan-header-emacs-home-regexp output)
+      (let ((emacs-home (substring output (match-beginning 1) (match-end 1))))
+	(singular-debug 'interactive
+			(message "scan header: emacs home path found"))
+	;; in any case, remove marker from output
+	(setq output (replace-match "" t t output))
+	(setq changed t)
+	;; if not already done, do action an singular-emacs-home
+	(when (memq 'emacs-home singular-scan-header-scan-for)
+	  (singular-debug 'interactive (message "scan header: initializing emacs-home-directory"))
+	  (setq singular-scan-header-scan-for (delq 'emacs-home singular-scan-header-scan-for))
+	  (setq singular-emacs-home-directory emacs-home)
+	  (singular-scan-header-got-emacs-home))))
+
+    ;; Search for Singular info file
+    (when (string-match singular-scan-header-info-file-regexp output)
+      (let ((file-name (substring output (match-beginning 1) (match-end 1))))
+	(singular-debug 'interactive
+			(message "scan header: singular.hlp path found"))
+	;; in any case, remove marker from output
+	(setq output (replace-match "" t t output))
+	(setq changed t)
+	;; if not already done, do action on help-file-name
+	(when (memq 'info-file singular-scan-header-scan-for)
+	  (singular-debug 'interactive (message "scan header: initializing help-file-name"))
+	  (setq singular-scan-header-scan-for (delq 'info-file singular-scan-header-scan-for))
+	  (setq singular-help-file-name file-name))))
+
+    ;; Remove from hook if everything is found or if we already waited
+    ;; too long.
+    (if (or (eq singular-scan-header-scan-for nil)
+	    (> (singular-time-stamp-difference (current-time) singular-scan-header-time-stamp) 20))
+	(remove-hook 'singular-pre-output-filter-functions 'singular-scan-header-pre-output-filter))
+
+    ;; Return new output string if we changed it, nil otherwise
+    (and changed output)))
+
+(defun singular-scan-header-init ()
+  "Initialize scanning of header for Singular interactive mode.
+
+This function is called by `singular-exec'."
+  (singular-debug 'interactive (message "Initializing scan-header"))
+  (set (make-local-variable 'singular-scan-header-time-stamp) (current-time))
+  (set (make-local-variable 'singular-scan-header-scan-for) '())
+
+  (make-local-variable 'singular-emacs-home-directory)
+  ;; if singular-emacs-home is set try to load the completion files.
+  ;; Otherwise set marker that we still have to search for it.
+  (if singular-emacs-home-directory
+      (singular-scan-header-got-emacs-home)
+    (setq singular-scan-header-scan-for (append singular-scan-header-scan-for '(emacs-home))))
+
+  ;; Up to now this seems to be the best place to initialize
+  ;; `singular-help-file-name' since singular-help gets initialized
+  ;; only on mode start-up, not on Singular start-up
+  ;;
+  ;; if singular-help-file-name is not set, mark, that we have to scan for it
+  (make-local-variable 'singular-help-file-name)
+  (or singular-help-file-name
+      (setq singular-scan-header-scan-for (append singular-scan-header-scan-for '(info-file))))
+
+  (add-hook 'singular-pre-output-filter-functions 'singular-scan-header-pre-output-filter))
+
+(defun singular-scan-header-exit ()
+  "Reinitialize scanning of header for Singular interactive mode.
+
+This function is called by `singular-exit-sentinel'."
+  ;; unset variables so that all subsequent calls of Singular will
+  ;; scan the header.
+  (singular-debug 'interactive (message "Deinitializing scan-header"))
+  (setq singular-emacs-home-directory nil)
+  (setq singular-help-file-name nil))
+
+;;
+;; handling of emacs home directory
+;;
+;; A note on `singular-emacs-home-directory': If this variable is set
+;; before singular.el is evaluated, the header of the first Singular
+;; started is NOT searched for the singular-emacs-home-directory.
+;; Anyhow, all subsequent calls of Singular will scan the header
+;; regardless of the initial state of this variable. (The exit-sentinel
+;; will set this variable back to nil.)
+;; See also `singular-scan-header-exit'.
+(defvar singular-emacs-home-directory nil
+  "Path to the emacs sub-directory of Singular as string.
+`singular-scan-header-pre-output-filter' searches the Singular header for
+the path and sets this variable to the corresponding value.
+Its value is redifined on every start of Singular.
+
+This variable is buffer-local.")
+
+(defun singular-expand-emacs-file-name (file &optional noerror)
+  "Add absolute path of emacs home directory.
+Adds the content of `singular-emacs-home-directory' to the string FILE.
+If `singular-emacs-home-directory' is nil, return nil and signal
+an error unless optional argument NOERROR is not nil."
+  (if singular-emacs-home-directory
+      (concat singular-emacs-home-directory
+	      (if (memq (aref singular-emacs-home-directory
+			      (1- (length singular-emacs-home-directory)))
+			'(?/ ?\\))
+		  "" "/")
+	      file)
+    (if noerror
+	nil
+      (error "Variable singular-emacs-home-directory not set"))))
+;;}}}
+
+;;{{{ Filename, Command, and Help Completion
+(defun singular-completion-init ()
+  "Initialize completion for Singular interactive mode.
+Initializes completion of file names, commands, examples, and help topics.
+
+This function is called by `singular-exec'."
+  (singular-debug 'interactive (message "Initializing completion"))
+  (set (make-local-variable 'singular-commands-alist) nil)
+  (set (make-local-variable 'singular-examples-alist) nil)
+  (set (make-local-variable 'singular-help-topics-alist) nil))
+
+(defun singular-completion-do (pattern beg end completion-alist)
+  "Try completion on string PATTERN using alist COMPLETION-ALIST.
+Inserts completed version of PATTERN as new text between BEG and END.
+Assumes the COMPLETION-ALIST is not nil."
+  (let ((completion (try-completion pattern completion-alist)))
+    (cond ((eq completion t)
+	   (message "[Sole completion]"))  ;; nothing to complete
+	  ((null completion)               ;; no completion found
+	   (message "Can't find completion for \"%s\"" pattern)
+	   (ding))
+	  ((not (string= pattern completion))
+	   (delete-region beg end)
+	   (insert completion))
+	  (t
+	   (message "Making completion list...")
+	   (let ((list (all-completions pattern
+					completion-alist)))
+	     (with-output-to-temp-buffer "*Completions*"
+	       (display-completion-list list)))
+	   (message "Making completion list...%s" "done")))))
+
+(defun singular-dynamic-complete ()
+  "Dynamic complete word before point.
+Performs file name completion if point is inside a string.
+Performs completion of Singular help topics if point is at the end of a
+help command (\"help\" or \"?\").
+Performs completion of Singular examples if point is at the end of an
+example command (\"example\").
+Otherwise performs completion of Singular commands."
+  (interactive)
+  ;; Check if we are inside a string.  The search is done back to the
+  ;; process-mark which should be the beginning of the current input.
+  ;; No check at this point whether there is a process!
+  (if (save-excursion
+	(nth 3 (parse-partial-sexp (singular-process-mark) (point))))
+      ;; then: inside string, thus expand filename
+      (comint-dynamic-complete-as-filename)
+    ;; else: expand command or help
+    (let ((end (point))
+	  (post-prompt (save-excursion
+			 (beginning-of-line)
+			 (singular-prompt-skip-forward)))
+	  beg)
+      (cond
+       ((save-excursion
+	  (goto-char post-prompt)
+	  (looking-at "[ \t]*\\([\\?]\\|help \\)[ \t]*\\(.*\\)"))
+	;; then: help completion
+	(if singular-help-topics-alist
+	    (singular-completion-do (match-string 2) (match-beginning 2)
+				    end singular-help-topics-alist)
+	  (message "Completion of Singular help topics disabled.")
+	  (ding)))
+       ((save-excursion
+	  (goto-char post-prompt)
+	  (looking-at "[ \t]*\\(example \\)[ \t]*\\(.*\\)"))
+	;; then: example completion
+	(if singular-examples-alist
+	    (singular-completion-do (match-string 2) (match-beginning 2)
+				    end singular-examples-alist)
+	  (message "Completion of Singular examples disabled.")
+	  (ding)))
+       (t
+	;; else: command completion
+	(save-excursion
+	  (skip-chars-backward "a-zA-Z0-9")
+	  (setq beg (point)))
+	(if singular-commands-alist
+	    (singular-completion-do (buffer-substring beg end) beg
+				    end singular-commands-alist)
+	  (message "Completion of Singular commands disabled.")
+	  (ding)))))))
+;;}}}
+
+;;{{{ Debugging filters
+(defun singular-debug-pre-input-filter (string)
+  "Display STRING and some markers in mini-buffer."
+  (singular-debug 'interactive-filter
+		  (message "Pre-input filter: %s (li %S ci %S lo %S co %S)"
+			   (singular-debug-format string)
+			   (marker-position singular-last-input-section-start)
+			   (marker-position singular-current-input-section-start)
+			   (marker-position singular-last-output-section-start)
+			   (marker-position singular-current-output-section-start)))
+  nil)
+
+(defun singular-debug-post-input-filter (beg end)
+  "Display BEG, END, and some markers in mini-buffer."
+  (singular-debug 'interactive-filter
+		  (message "Post-input filter: (beg %S end %S) (li %S ci %S lo %S co %S)"
+			   beg end
+			   (marker-position singular-last-input-section-start)
+			   (marker-position singular-current-input-section-start)
+			   (marker-position singular-last-output-section-start)
+			   (marker-position singular-current-output-section-start))))
+
+(defun singular-debug-pre-output-filter (string)
+  "Display STRING and some markers in mini-buffer."
+  (singular-debug 'interactive-filter
+		  (message "Pre-output filter: %s (li %S ci %S lo %S co %S)"
+			   (singular-debug-format string)
+			   (marker-position singular-last-input-section-start)
+			   (marker-position singular-current-input-section-start)
+			   (marker-position singular-last-output-section-start)
+			   (marker-position singular-current-output-section-start)))
+  nil)
+
+(defun singular-debug-post-output-filter (beg end simple-sec-start)
+  "Display BEG, END, SIMPLE-SEC-START, and some markers in mini-buffer."
+  (singular-debug 'interactive-filter
+		  (message "Post-output filter: (beg %S end %S sss %S) (li %S ci %S lo %S co %S)"
+			   beg end simple-sec-start
+			   (marker-position singular-last-input-section-start)
+			   (marker-position singular-current-input-section-start)
+			   (marker-position singular-last-output-section-start)
+			   (marker-position singular-current-output-section-start))))
+
+(defun singular-debug-filter-init ()
+  "Add debug filters to the necessary hooks.
+
+This function is called at mode initialization time."
+  (add-hook 'singular-pre-input-filter-functions
+	    'singular-debug-pre-input-filter nil t)
+  (add-hook 'singular-post-input-filter-functions
+	    'singular-debug-post-input-filter nil t)
+  (add-hook 'singular-pre-output-filter-functions
+	    'singular-debug-pre-output-filter nil t)
+  (add-hook 'singular-post-output-filter-functions
+	    'singular-debug-post-output-filter nil t))
+;;}}}
+
+;;{{{ Demo mode
+
+;; Note:
+;;
+;; For documentation on Singular demo mode one should refer to the doc
+;; string of `singular-demo-load'.
+;; Singular demo mode should have been implemented as a minor mode but it
+;; did not seem worth it.
+
+(defcustom singular-demo-chunk-regexp "\\(\n\\s *\n\\)"
+  "*Regular expressions to recognize chunks of a demo file.
+If there is a subexpression specified its contents is removed after the
+chunk has been displayed.
+The default value is \"\\\\(\\n\\\\s *\\n\\\\)\" which means that chunks are
+separated by one blank line which is removed after the chunks have been
+displayed."
+  :type 'regexp
+  :initialize 'custom-initialize-default
+  :group 'singular-demo-mode)
+
+(defcustom singular-demo-print-messages t
+  "*If non-nil, print message on how to continue demo mode."
+  :type 'boolean
+  :initialize 'custom-initialize-default
+  :group 'singular-demo-mode)
+
+(defcustom singular-demo-exit-on-load t
+  "*If non-nil, an active demo is automatically discarded when a new one is loaded.
+Otherwise, the load is aborted with an error."
+  :type 'boolean
+  :initialize 'custom-initialize-default
+  :group 'singular-demo-mode)
+
+(defcustom singular-demo-load-directory nil
+  "*Directory where demo files usually reside.
+If non-nil, this directory is offered as a starting point to search for
+demo files when `singular-demo-load' is called interactively for the first
+time.  (In further calls, `singular-demo-load' offers the directory where
+the last demo file has been loaded from as starting point).
+
+If this variable equals nil whatever Emacs offers by default is used as
+first-time starting point.  In general, this is the directory where
+Singular has been started in."
+  :type '(choice (const nil) (file))
+  :initialize 'custom-initialize-default
+  :group 'singular-demo-mode)
+
+(defvar singular-demo-mode nil
+  "Non-nil if Singular demo mode is on.
+
+This variable is buffer-local.")
+
+(defvar singular-demo-old-mode-name nil
+  "Used to store previous `mode-name' before switching to demo mode.
+
+This variable is buffer-local.")
+
+(defvar singular-demo-end nil
+  "Marker pointing to end of demo file.
+
+This variable is buffer-local.")
+
+(defvar singular-demo-last-directory nil
+  "If non-nil, directory from which the last demo file has been loaded.
+
+This variable is buffer-local.")
+
+(defun singular-demo-load (demo-file)
+  "Load demo file DEMO-FILE and enter Singular demo mode.
+
+The Singular demo mode allows to step conveniently through a prepared demo
+file.  The contents of the demo file is made visible and executed in
+portions called chunks.  How the chunks have to be marked in the demo file
+is described below.
+
+After loading the demo file with this function, \\[singular-send-or-copy-input] displays the first
+chunk of the demo file at the Singular prompt.  This chunk may be modified
+\(or even deleted) and then sent to Singular entering \\[singular-send-or-copy-input] as any command
+would have been sent to Singular.  The next time \\[singular-send-or-copy-input] is entered, the next
+chunk of the demo file is displayed, and so on.
+
+One may interrupt this sequence and enter commands at the Singular input
+prompt as usual.  As soon as \\[singular-send-or-copy-input] is entered directly after the input
+prompt, the next chunk of the demo file is displayed.  Here is the exact
+algorithm how this magic works: If point is located at the very end of the
+buffer *and* immediately after Singular's last input prompt, the next chunk
+of the demo file is displayed.  In particular, if there is any text after
+the last input prompt that text is sent to Singular as usual and no new
+chunks are displayed.
+
+After displaying the last chunk of DEMO-FILE, Singular demo mode
+automatically terminates and normal operation is resumed.  To prematurely
+exit Singular demo mode \\[singular-demo-exit] may be used.
+
+DEMO-FILE should consist of regular Singular commands.  Portions of text
+separated by a blank line are taken to be the chunks of the demo file.
+
+There is a number of variables to configure Singular demo mode.  Refer to
+the `singular-demo-mode' customization group for more information.
+
+Important note: The unprocessed contents of DEMO-FILE is hidden using
+buffer narrowing.  Emacs gets terribly confused when during demo mode the
+buffer is either narrowed to some other region or if the buffer is widened.
+The safest thing to do if that happens by accident is to explicitly exit
+the demo by means of \\[singular-demo-exit] and to try to resume somehow
+normal operation.
+
+`singular-demo-load' runs the functions on `singular-demo-mode-enter-hook'
+just after demo mode has been entered.  The functions on
+`singular-demo-mode-exit-hook' are executed after Singular demo mode has
+been exited, either prematurely or due to the end of the demo file.
+However, it its important to note that in the latter case the last chunk of
+the demo file is still waiting to be sent to Singular."
+  (interactive
+   (list
+    (let ((demo-file-name
+	   (cond
+	    ;; Emacs
+	    ((eq singular-emacs-flavor 'emacs)
+	     (read-file-name "Load demo file: "
+			     (or singular-demo-last-directory
+				 singular-demo-load-directory)
+			     nil t))
+	    ;; XEmacs
+	    (t
+	     ;; there are some problems with the window being popped up when this
+	     ;; function is called from a menu.  It does not display the contents
+	     ;; of `singular-demo-load-directory' but of `default-directory'.
+	     (let ((default-directory (or singular-demo-last-directory
+					  singular-demo-load-directory
+					  default-directory)))
+	       (read-file-name "Load demo file: "
+			       (or singular-demo-last-directory
+				   singular-demo-load-directory)
+			       nil t))))))
+
+      (setq singular-demo-last-directory (file-name-directory demo-file-name))
+      demo-file-name)))
+
+  ;; check for running demo
+  (if singular-demo-mode
+      (if singular-demo-exit-on-load
+	  ;; silently exit running demo
+	  (singular-demo-exit t)
+	(error "There already is a demo running, exit with `singular-demo-exit' first")))
+
+  ;; load new demo
+  (let ((old-point-min (point-min)))
+    (unwind-protect
+	(progn
+	  (goto-char (point-max))
+	  (widen)
+	  (cond
+	   ;; XEmacs
+	   ((eq singular-emacs-flavor 'xemacs)
+	    ;; load file and remember its end
+	    (set-marker singular-demo-end
+			(+ (point) (nth 1 (insert-file-contents-literally demo-file)))))
+	   ;; Emacs
+	   (t
+	    ;; Emacs does something like an `insert-before-markers' so
+	    ;; save all essential markers
+	    (let ((pmark-pos (marker-position (singular-process-mark)))
+		  (sliss-pos (marker-position singular-last-input-section-start))
+		  (sciss-pos (marker-position singular-current-input-section-start))
+		  (sloss-pos (marker-position singular-last-output-section-start))
+		  (scoss-pos (marker-position singular-current-output-section-start)))
+
+	      (unwind-protect
+		  ;; load file and remember its end
+		  (set-marker singular-demo-end
+			      (+ (point) (nth 1 (insert-file-contents-literally demo-file))))
+
+		;; restore markers.
+		;; This is unwind-protected.
+		(set-marker (singular-process-mark) pmark-pos)
+		(set-marker singular-last-input-section-start sliss-pos)
+		(set-marker singular-current-input-section-start sciss-pos)
+		(set-marker singular-last-output-section-start sloss-pos)
+		(set-marker singular-current-output-section-start scoss-pos))))))
+
+      ;; completely hide demo file.
+      ;; This is unwind-protected.
+      (narrow-to-region old-point-min (point))))
+
+  ;; switch demo mode on
+  (setq singular-demo-old-mode-name mode-name
+	mode-name "Singular Demo"
+	singular-demo-mode t)
+  (run-hooks 'singular-demo-mode-enter-hook)
+  (if singular-demo-print-messages (message "Hit RET to start demo"))
+  (force-mode-line-update))
+
+(defun singular-demo-exit-internal ()
+  "Exit Singular demo mode.
+Recovers the old mode name, sets `singular-demo-mode' to nil, runs
+the hooks on `singular-demo-mode-exit-hook'."
+  (setq mode-name singular-demo-old-mode-name
+	singular-demo-mode nil)
+  (run-hooks 'singular-demo-mode-exit-hook)
+  (force-mode-line-update))
+
+(defun singular-demo-exit (&optional no-message)
+  "Prematurely exit Singular demo mode.
+Cleans up everything that is left from the demo.
+Runs the hooks on `singular-demo-mode-exit-hook'.
+Does nothing when Singular demo mode is not active."
+  (interactive)
+  (when singular-demo-mode
+    ;; clean up hidden rest of demo file
+    (let ((old-point-min (point-min))
+	  (old-point-max (point-max)))
+      (unwind-protect
+	  (progn
+	    (widen)
+	    (delete-region old-point-max singular-demo-end))
+	;; this is unwind-protected
+	(narrow-to-region old-point-min old-point-max)))
+    (singular-demo-exit-internal)
+    (or no-message
+	(if singular-demo-print-messages (message "Demo exited")))))
+
+(defun singular-demo-show-next-chunk ()
+  "Show next chunk of demo file at input prompt.
+Assumes that Singular demo mode is active.
+Moves point to end of buffer and widenes the buffer such that the next
+chunk of the demo file becomes visible.
+Finds and removes chunk separators as specified by
+`singular-demo-chunk-regexp'.
+Leaves demo mode after showing last chunk.  In that case runs hooks on
+`singular-demo-mode-exit-hook'."
+  (let ((old-point-min (point-min)))
+    (unwind-protect
+	(progn
+	  (goto-char (point-max))
+	  (widen)
+	  (if (re-search-forward singular-demo-chunk-regexp singular-demo-end 'limit)
+	      (if (match-beginning 1)
+		  (delete-region (match-beginning 1) (match-end 1)))
+	    ;; remove trailing white-space.  We may not use
+	    ;; `(skip-syntax-backward "-")' since newline is has no white
+	    ;; space syntax.  The solution down below should suffice in
+	    ;; almost all cases ...
+	    (skip-chars-backward " \t\n\r\f")
+	    (delete-region (point) singular-demo-end)
+	    (singular-demo-exit-internal)))
+
+      ;; this is unwind-protected
+      (narrow-to-region old-point-min (point)))))
+
+(defun singular-demo-mode-init ()
+  "Initialize variables belonging to Singular demo mode.
+Creates some buffer-local variables and the buffer-local marker
+`singular-demo-end'.
+
+This function is called  at mode initialization time."
+  (make-local-variable 'singular-demo-mode)
+  (make-local-variable 'singular-demo-mode-old-name)
+  (make-local-variable 'singular-demo-mode-end)
+  (if (not (and (boundp 'singular-demo-end)
+		singular-demo-end))
+      (setq singular-demo-end (make-marker)))
+  (make-local-variable 'singular-demo-last-directory))
+;;}}}
+
+;;{{{ Some lengthy notes on input and output
+
+;; NOT READY[so sorry]!
+
+;;}}}
+
+;;{{{ Last input and output section
+(defun singular-last-input-section (&optional no-error)
+  "Return last input section.
+Returns nil if optional argument NO-ERROR is non-nil and there is no
+last input section defined, throws an error otherwise."
+  (let ((last-input-start (marker-position singular-last-input-section-start))
+	(last-input-end (marker-position singular-current-output-section-start)))
+    (cond ((and last-input-start last-input-end)
+	   (singular-section-create (singular-simple-sec-at last-input-start) 'input
+				    last-input-start last-input-end))
+	  (no-error nil)
+	  (t (error "No last input section defined")))))
+
+(defun singular-current-output-section (&optional no-error)
+  "Return current output section.
+Returns nil if optional argument NO-ERROR is non-nil and there is no
+current output section defined, throws an error otherwise."
+  (let ((current-output-start (marker-position singular-current-output-section-start))
+	(current-output-end (save-excursion
+			      (save-restriction
+				(widen)
+				(goto-char (singular-process-mark))
+				(singular-prompt-skip-backward)
+				(and (bolp) (point))))))
+    (cond ((and current-output-start current-output-end)
+	   (singular-section-create (singular-simple-sec-at current-output-start) 'output
+				    current-output-start current-output-end))
+	  (no-error nil)
+	  (t (error "No current output section defined")))))
+
+(defun singular-last-output-section (&optional no-error)
+  "Return last output section.
+Returns nil if optional argument NO-ERROR is non-nil and there is no
+last output section defined, throws an error otherwise."
+  (let ((last-output-start (marker-position singular-last-output-section-start))
+	(last-output-end (marker-position singular-last-input-section-start)))
+    (cond ((and last-output-start last-output-end)
+	   (singular-section-create (singular-simple-sec-at last-output-start) 'output
+				    last-output-start last-output-end))
+	  (no-error nil)
+	  (t (error "No last output section defined")))))
+
+(defun singular-latest-output-section (&optional no-error)
+  "Return latest output section.
+This is the current output section if it is defined, otherwise the
+last output section.
+Returns nil if optional argument NO-ERROR is non-nil and there is no
+latest output section defined, throws an error otherwise."
+  (or (singular-current-output-section t)
+      (singular-last-output-section t)
+      (if no-error
+	  nil
+	(error "No latest output section defined"))))
+;;}}}
+
+;;{{{ Sending input
+(defvar singular-pre-input-filter-functions nil
+  "Functions to call before input is sent to process.
+These functions get one argument, a string containing the text which
+is to be sent to process.  The functions should return either nil
+or a string.  In the latter case the returned string replaces the
+string to be sent to process.
+
+This is a buffer-local variable, not a buffer-local hook!
+
+`singular-run-hook-with-arg-and-value' is used to run the functions in
+the list.")
+
+(defvar singular-post-input-filter-functions nil
+  "Functions to call after input is sent to process.
+These functions get two arguments BEG and END.
+If `singular-input-filter' has been called with a string as argument
+BEG and END gives the position of this string after insertion into the
+buffer.
+If `singular-input-filter' has been called with a position as argument
+BEG and END equal process mark and that position, resp.
+The functions may assume that no narrowing is in effect and may change
+point at will.
+
+This hook is buffer-local.")
+
+(defvar singular-current-input-section-start nil
+  "Marker to the start of the current input section.
+This marker points nowhere on startup or if there is no current input
+section.
+
+This variable is buffer-local.")
+
+(defvar singular-last-input-section-start nil
+  "Marker to the start of the last input section.
+This marker points nowhere on startup.
+
+This variable is buffer-local.")
+
+(defun singular-input-filter-init (pos)
+  "Initialize all variables concerning input.
+POS is the position of the process mark."
+  ;; localize variables not yet localized in `singular-interactive-mode'
+  (make-local-variable 'singular-current-input-section-start)
+  (make-local-variable 'singular-last-input-section-start)
+
+  ;; initialize markers
+  (if (not (markerp singular-current-input-section-start))
+      (setq singular-current-input-section-start (make-marker)))
+  (if (not (markerp singular-last-input-section-start))
+      (setq singular-last-input-section-start (make-marker))))
+
+(defun singular-send-string (process string)
+  "Send newline terminated STRING to to process PROCESS.
+Runs the hooks on `singular-pre-input-filter-functions' in the buffer
+associated to PROCESS.  The functions get the non-terminated string."
+  (let ((process-buffer (process-buffer process)))
+
+    ;; check whether buffer is still alive
+    (if (and process-buffer (buffer-name process-buffer))
+	(save-excursion
+	  (set-buffer process-buffer)
+	  (process-send-string
+	   process
+	   (concat (singular-run-hook-with-arg-and-value
+		    singular-pre-input-filter-functions string)
+		   "\n"))))))
+
+(defun singular-input-filter (process string-or-pos)
+  "Insert/update input from user in buffer associated to PROCESS.
+Inserts STRING-OR-POS followed by a newline at process mark if it is a
+string.
+Assumes that the input is already inserted and that it is placed
+between process mark and STRING-OR-POS if the latter is a position.
+Inserts a newline after STRING-OR-POS.
+
+Takes care off:
+- current buffer as well as point and restriction in buffer associated
+  with process, even against non-local exits.
+Updates:
+- process mark;
+- current and last sections;
+- simple sections;
+- mode line.
+
+Runs the hooks on `singular-pre-input-filter-functions' and
+`singular-post-input-filter-functions'.
+
+For a more detailed descriptions of the input filter, the markers it
+sets, and input filter functions refer to the section \"Some lengthy
+notes on input and output\" in singular.el."
+  (let ((process-buffer (process-buffer process)))
+
+    ;; check whether buffer is still alive
+    (if (and process-buffer (buffer-name process-buffer))
+	(let ((old-buffer (current-buffer))
+	      (old-pmark (marker-position (process-mark process)))
+	      old-point old-point-min old-point-max)
+	  (unwind-protect
+	      (let (simple-sec-start)
+		(set-buffer process-buffer)
+		;; the following lines are not protected since the
+		;; unwind-forms refer the variables being set here
+		(setq old-point (point-marker)
+		      old-point-min (point-min-marker)
+		      old-point-max (point-max-marker)
+
+		;; get end of last simple section (equals start of
+		;; current)
+		      simple-sec-start (singular-simple-sec-last-end-position))
+
+		;; prepare for insertion
+		(widen)
+		(set-marker-insertion-type old-point t)
+		(set-marker-insertion-type old-point-max t)
+
+		;; insert string at process mark and advance process
+		;; mark after insertion.  If it not a string simply
+		;; jump to desired position and insrt a newline.
+		(if (stringp string-or-pos)
+		    (progn
+		      (goto-char old-pmark)
+		      (insert string-or-pos))
+		  (goto-char string-or-pos))
+		(insert ?\n)
+		(set-marker (process-mark process) (point))
+
+		;; create new simple section and update section markers
+		(cond
+		 ((eq (singular-simple-sec-create 'input (point)) 'empty)
+		  nil)
+		 ;; a new simple section has been created ...
+		 ((null (marker-position singular-current-input-section-start))
+		  ;; ... and even a new input section has been created!
+		  (set-marker singular-current-input-section-start
+			      simple-sec-start)
+		  (set-marker singular-last-output-section-start
+			      singular-current-output-section-start)
+		  (set-marker singular-current-output-section-start nil)))
+
+		;; run post-output hooks and force mode-line update
+		(run-hook-with-args 'singular-post-input-filter-functions
+				    old-pmark (point)))
+
+	    ;; restore buffer, restrictions and point
+	    (narrow-to-region old-point-min old-point-max)
+	    (set-marker old-point-min nil)
+	    (set-marker old-point-max nil)
+	    (goto-char old-point)
+	    (set-marker old-point nil)
+	    (set-buffer old-buffer))))))
+;;}}}
+
+;;{{{ Sending input interactive
+(defcustom singular-move-on-send 'eob
+  "*Where to move point before sending input to Singular.
+Should be one of:
+`eob' which means to move point to end of buffer,
+`eol' which means to move point to end of line, or
+ nil  which means to not move point at all."
+  :type '(choice (const :tag "End of buffer" eob)
+		 (const :tag "End of line" eol)
+		 (const :tag "Do not move" nil))
+  :initialize 'custom-initialize-default
+  :group 'singular-interactive-miscellaneous)
+
+(defun singular-get-old-input (get-section)
+  "Get and return old input.
+Retrivies on a per-section base if GET-SECTION is non-nil, otherwise on a
+per-line base."
+  (if get-section
+      ;; get input from input section
+      (let ((section (singular-section-at (point))))
+	(if (eq (singular-section-type section) 'input)
+	    (singular-white-space-strip (singular-section-to-string section) t)
+	  (error "Not on an input section")))
+    ;; get input from line
+    (save-excursion
+      (beginning-of-line)
+      (singular-prompt-skip-forward)
+      (let ((old-point (point)))
+	(end-of-line)
+	(buffer-substring old-point (point))))))
+
+(defun singular-send-or-copy-input (get-section)
+  "Send input to Singular.
+
+The behavior of this function very much depends on the current position of
+point relative to the process mark, that is, the position, where Singular
+expects next input.
+
+If point is located before process mark, old input is copied to the process
+mark.  With prefix argument, the whole input section point currently is in
+is copied, without prefix argument only the current line.  One should note
+that the input is *not* sent to Singular, it is only copied to the process
+mark.  Another time entering \\[singular-send-or-copy-input] sends it to Singular.
+
+If point is located after process mark, point is moved as determined by the
+`singular-move-on-send' variable: either it is moved to the end of the
+current line, or to the end of the buffer, or it is not moved at all.  The
+default is to move point to the end of the buffer which most closely
+resembles regular terminal behaviour.  At last, the text of the region
+between process mark and point is sent to Singular.
+
+Any input to Singular is stored in an input history where it may be
+retrieved with \\[comint-previous-input] or \\[comint-next-input], respectively.  For more information on the input
+history one should refer to the documentation of
+`singular-interactive-mode'.
+
+If Singular demo mode is active and point is at process mark and if that
+position is at the end of the buffer the next chunk of the demo file is
+displayed.  One should refer to the documentation of `singular-demo-load'
+for more information on Singular demo mode.
+
+The Singular process should be running."
+  (interactive "P")
+  (let ((process (singular-process))
+	(pmark (singular-process-mark)))
+    (cond
+     (;; check for demo mode and show next chunk if necessary
+      (and singular-demo-mode
+	   (= (point) pmark)
+	   (= pmark (point-max)))
+      (singular-demo-show-next-chunk))
+
+     (;; get old input
+      (< (point) pmark)
+      (let ((old-input (singular-get-old-input get-section)))
+	(goto-char pmark)
+	(insert old-input)))
+
+     (;; send input from pmark to point
+      t
+      ;; print message if demo mode is active.  We print it before we do
+      ;; anything else so that the message will not hide any further
+      ;; (error) messages.
+      (and singular-demo-mode
+	   singular-demo-print-messages
+	   (message "Hit RET to continue demo"))
+
+      ;; go to desired position
+      (cond ((eq singular-move-on-send 'eol)
+	     (end-of-line))
+	    ((eq singular-move-on-send 'eob)
+	     (goto-char (point-max))))
+
+      (let* ((input (buffer-substring pmark (point))))
+	;; insert string into history
+	(singular-history-insert input)
+	;; send string to process
+	(singular-send-string process input)
+	;; "insert" it into buffer
+	(singular-input-filter process (point)))))))
+;;}}}
+
+;;{{{ Receiving output
+(defvar singular-pre-output-filter-functions nil
+  "Functions to call before output is inserted into the buffer.
+These functions get one argument, a string containing the text sent
+from process.  The functions should return either nil or a string.
+In the latter case the returned string replaces the string sent from
+process.
+
+This is a buffer-local variable, not a buffer-local hook!
+
+`singular-run-hook-with-arg-and-value' is used to run the functions in
+this list.")
+
+(defvar singular-post-output-filter-functions nil
+  "Functions to call after output is inserted into the buffer.
+These functions get three arguments BEG, END, and SIMPLE-SEC-START.
+The region between BEG and END is what has been inserted into the
+buffer.
+SIMPLE-SEC-START is the start of the simple section which has been
+created on insertion or nil if no simple section has been created.
+The functions may assume that no narrowing is in effect and may change
+point at will.
+
+This hook is buffer-local.")
+
+(defvar singular-current-output-section-start nil
+  "Marker to the start of the current output section.
+This marker points nowhere on startup or if there is no current output
+section.
+
+This variable is buffer-local.")
+
+(defvar singular-last-output-section-start nil
+  "Marker to the start of the last output section.
+This marker points nowhere on startup.
+
+This variable is buffer-local.")
+
+(defun singular-output-filter-init (pos)
+  "Initialize all variables concerning output including process mark.
+Set process mark to POS."
+
+  ;; localize variables not yet localized in `singular-interactive-mode'
+  (make-local-variable 'singular-current-output-section-start)
+  (make-local-variable 'singular-last-output-section-start)
+
+  ;; initialize markers
+  (if (not (markerp singular-current-output-section-start))
+      (setq singular-current-output-section-start (make-marker)))
+  (if (not (markerp singular-last-output-section-start))
+      (setq singular-last-output-section-start (make-marker)))
+  (set-marker (singular-process-mark) pos))
+
+(defun singular-output-filter (process string)
+  "Insert STRING containing output from PROCESS into its associated buffer.
+Takes care off:
+- current buffer as well as point and restriction in buffer associated
+  with process, even against non-local exits.
+Updates:
+- process mark;
+- current and last sections;
+- simple sections;
+- mode line.
+Runs the hooks on `singular-pre-output-filter-functions' and
+`singular-post-output-filter-functions'.
+
+For a more detailed descriptions of the output filter, the markers it
+sets, and output filter functions refer to the section \"Some lengthy
+notes on input and output\" in singular.el."
+  (let ((process-buffer (process-buffer process)))
+
+    ;; check whether buffer is still alive
+    (if (and process-buffer (buffer-name process-buffer))
+	(let ((old-buffer (current-buffer))
+	      (old-pmark (marker-position (process-mark process)))
+	      old-point old-point-min old-point-max)
+	  (unwind-protect
+	      (let (simple-sec-start)
+		(set-buffer process-buffer)
+		;; the following lines are not protected since the
+		;; unwind-forms refer the variables being set here
+		(setq old-point (point-marker)
+		      old-point-min (point-min-marker)
+		      old-point-max (point-max-marker)
+
+		;; get end of last simple section (equals start of
+		;; current)
+		      simple-sec-start (singular-simple-sec-last-end-position)
+
+		;; get string to insert
+		      string (singular-run-hook-with-arg-and-value
+			      singular-pre-output-filter-functions
+			      string))
+
+		;; prepare for insertion
+		(widen)
+		(set-marker-insertion-type old-point t)
+		(set-marker-insertion-type old-point-max t)
+
+		;; insert string at process mark and advance process
+		;; mark after insertion
+		(goto-char old-pmark)
+		(insert string)
+		(set-marker (process-mark process) (point))
+
+		;; create new simple section and update section markers
+		(cond
+		 ((eq (singular-simple-sec-create 'output (point)) 'empty)
+		  (setq simple-sec-start nil))
+		 ;; a new simple section has been created ...
+		 ((null (marker-position singular-current-output-section-start))
+		  ;; ... and even a new output section has been created!
+		  (set-marker singular-current-output-section-start
+			      simple-sec-start)
+		  (set-marker singular-last-input-section-start
+			      singular-current-input-section-start)
+		  (set-marker singular-current-input-section-start nil)))
+
+		;; run post-output hooks and force mode-line update
+		(run-hook-with-args 'singular-post-output-filter-functions
+				    old-pmark (point) simple-sec-start)
+		(force-mode-line-update))
+
+	    ;; restore buffer, restrictions and point
+	    (narrow-to-region old-point-min old-point-max)
+	    (set-marker old-point-min nil)
+	    (set-marker old-point-max nil)
+	    (goto-char old-point)
+	    (set-marker old-point nil)
+	    (set-buffer old-buffer))))))
+;;}}}
+
+;;{{{ Singular interactive mode
+(defun singular-interactive-mode ()
+  "Major mode for interacting with Singular.
+
+NOT READY [how to send input]!
+NOT READY [in particular: input history!]
+
+NOT READY [multiple Singulars]!
+
+\\{singular-interactive-mode-map}
+
+
+For \"backward compatibility\" with the terminal version of Singular there
+is some extra magic built into Singular interactive mode which catches help
+commands issued at the command prompt and executes this function instead.
+However, this magic is really not too magic and easily may be fooled.  If
+this magic if fooled Singular prints some error message starting like this:
+
+// ** Your help command could not be executed. ...
+
+However, the most common case should be recognized: If one issues a help
+command to a non-busy Singular, where the help command comes on one line
+and is properly terminated with a semicolon.  Like that:
+
+help ring;
+
+Customization: Entry to this mode runs the hooks on
+`singular-interactive-mode-hook'.
+
+NOT READY [much more to come.  See shell.el.]!"
+  (interactive)
+
+  ;; uh-oh, we have to set `comint-input-ring-size' before we call
+  ;; `comint-mode'
+  (singular-history-init)
+
+  ;; run comint mode and do basic mode setup
+  (let (comint-mode-hook)
+    (comint-mode)
+    (singular-comint-init))
+  (setq major-mode 'singular-interactive-mode)
+  (setq mode-name "Singular Interaction")
+
+  ;; some other initialization found in no folding
+  (setq comment-start "// ")
+  (setq comment-start-skip "// *")
+  (setq comment-end "")
+
+  ;; initialize singular input and output filters.  This should be done
+  ;; first as the filters are accessed in the following initialization
+  ;; functions.  NOT READY [should be moved to the respective foldings]
+  (make-local-variable 'singular-pre-input-filter-functions)
+  ;;make-local-hook is obsolete in emcas >=21.1
+  ;;(make-local-hook 'singular-post-input-filter-functions)
+  (make-local-variable 'singular-pre-output-filter-functions)
+  ;;(make-local-hook 'singular-post-output-filter-functions)
+
+  (singular-interactive-mode-map-init)
+  (singular-mode-syntax-table-init)
+  (singular-interactive-mode-menu-init)
+  (singular-demo-mode-init)
+  (singular-folding-init)
+  (singular-help-init)
+  (singular-prompt-init)
+  (singular-exec-init)
+
+  ;; Font Lock mode initialization for Emacs.  For XEmacs, it is done at
+  ;; singular.el loading time.
+  (cond
+   ;; Emacs
+   ((eq singular-emacs-flavor 'emacs)
+    (singular-interactive-font-lock-init)))
+
+  ;; debugging filter initialization
+  (singular-debug 'interactive-filter
+   (singular-debug-filter-init))
+
+  (run-hooks 'singular-interactive-mode-hook))
+;;}}}
+
+;;{{{ Starting singular
+(defcustom singular-same-window t
+  "*Specifies how to open the window for Singular sessions.
+If this variable equals t, Singular comes up in the selected window.
+If this variable equals nil, Singular comes up in another window.
+If this variable equals neither t nor nil, the standard Emacs behaviour to
+open the window is adopted (which very much depends on the settings of
+`same-window-buffer-names')."
+  :initialize 'custom-initialize-default
+  :type '(choice (const :tag "This window" t)
+		 (const :tag "Other window" nil)
+		 (const :tag "Default" default))
+  :group 'singular-interactive-miscellaneous)
+
+(defcustom singular-start-file "~/.emacs_singularrc"
+  "*Name of start-up file to pass to Singular.
+If the file named by this variable exists it is given as initial input
+to any Singular process being started.  Note that this may lose due to
+a timing error if Singular discards input when it starts up."
+  :type 'file
+  :initialize 'custom-initialize-default
+  :group 'singular-interactive-miscellaneous)
+
+(defcustom singular-executable-default "Singular"
+  "*Default name of Singular executable.
+Used by `singular' when new Singular processes are started.
+If the name is given without path the executable is searched using the
+`PATH' environment variable."
+  :type 'file
+  :initialize 'custom-initialize-default
+  :group 'singular-interactive-miscellaneous)
+
+(defvar singular-executable-last singular-executable-default
+  "Singular executable name of the last Singular command used.
+
+This variable is buffer-local.")
+
+(defcustom singular-directory-default nil
+  "*Default working directory of Singular buffer.
+Should be either nil (which means do not set the default directory) or an
+existing directory."
+  :type '(choice (const nil) (directory :value "~/"))
+  :initialize 'custom-initialize-default
+  :group 'singular-interactive-miscellaneous)
+
+(defvar singular-directory-last singular-directory-default
+  "Working directory of last Singular command used.
+
+This variable is buffer-local.")
+
+;; no singular-directory-history here. Usual file history is used.
+
+(defcustom singular-switches-default '()
+  "*List of default switches for Singular processes.
+Should be a list of strings, one string for each switch.
+Used by `singular' when new Singular processes are started."
+  :type '(repeat string)
+  :initialize 'custom-initialize-default
+  :group 'singular-interactive-miscellaneous)
+
+(defvar singular-switches-last singular-switches-default
+  "Switches of last Singular command used.
+
+This variable is buffer-local.")
+
+(defvar singular-switches-history nil
+  "History list of Singular switches.")
+
+; (defvar singular-switches-magic '("-t" "--exec" "if (system(\"version\") > 1304){system(\"--emacs\", 1);};")
+(defvar singular-switches-magic '("-t" "--emacs")
+  "Additional magic switches for Singular process.
+List of switch-strings which are automagically added when new Singular
+processes are started, one string for each command line argument.
+This list should at least contain the options \"--emacs\" and \"-t\". If
+you are running a Singular with version < 1.2 , remove option \"--exec\"
+from the list.")
+
+(defcustom singular-name-default "singular"
+  "*Default process name for Singular process.
+Used by `singular' when new Singular processes are started.
+This string surrounded by \"*\" will also be the buffer name."
+  :type 'string
+  :initialize 'custom-initialize-default
+  :group 'singular-interactive-miscellaneous)
+
+(defvar singular-name-last singular-name-default
+  "process name of the last Singular command used.
+
+This variable is buffer-local.")
+
+(defvar singular-name-history nil
+  "History list of Singular process names.")
+
+(defun singular-exec-init ()
+  "Initialize defaults for starting Singular.
+
+This function is called at mode initialization time."
+  (singular-debug 'interactive (message "Initializing exec"))
+  (set (make-local-variable 'singular-executable-last)
+       singular-executable-default)
+  (set (make-local-variable 'singular-directory-last)
+       singular-directory-default)
+  (set (make-local-variable 'singular-name-last)
+       singular-name-default)
+  (set (make-local-variable 'singular-switches-last)
+       singular-switches-default)
+  (set (make-local-variable 'singular-exit-insert-killed-marker)
+       nil)
+  (set (make-local-variable 'singular-exit-cleanup-done)
+       nil))
+
+(defvar singular-exit-cleanup-done nil
+  "Switch indicating if cleanup after Singular exit is already done.
+Initial value is nil. Is set to t by `singular-exit-cleanup' and to nil by
+`singular-exit-sentinel'.
+
+This variable is buffer-local.")
+
+(defun singular-exit-cleanup ()
+  "Clean up after termination of Singular.
+Writes back input ring after regular termination of Singular if process
+buffer is still alive, deinstalls the library menu und calls several other
+exit procedures.
+Assumes that the current buffer is a Singular buffer.
+Sets the variable `singular-exit-cleanup-done' to t.
+
+This function is called by `singular-kill-singular' or by
+`singular-exit-sentinel'."
+  (singular-debug 'interactive
+		  (message "exit-cleanup called"))
+  (singular-demo-exit t)
+  (singular-scan-header-exit)
+  (singular-menu-deinstall-libraries)
+  (singular-history-write)
+  (setq singular-exit-cleanup-done t))
+
+(defun singular-exit-sentinel (process message)
+  "Clean up after termination of Singular.
+Calls `singular-exit-cleanup' if `singular-exit-cleanup-done' is nil."
+  (save-excursion
+    (singular-debug 'interactive
+		    (message "Sentinel: %s" (substring message 0 -1)))
+
+    (if (string-match "finished\\|exited\\|killed" message)
+	(let ((process-buffer (process-buffer process)))
+	  (if (and (not singular-exit-cleanup-done)
+		   process-buffer
+		   (buffer-name process-buffer)
+		   (set-buffer process-buffer))
+	      (singular-exit-cleanup))))
+    (setq singular-exit-cleanup-done nil)))
+
+(defun singular-kill-singular ()
+  "Delete the Singular process running in the current buffer.
+Calls `singular-exit-cleanup' and deletes the Singular process.
+Inserts a string indicating that the Singular process is killed."
+  (let* ((process (singular-process))
+	 (mark (marker-position (process-mark process))))
+    (singular-exit-cleanup)
+    (delete-process process)
+    (save-excursion
+      ;; Because of timing problems it would be better if
+      ;; singular-exit-sentinel would insert this string (see Version 1.41)
+      ;; but this is not possible for XEmacs: The function (process-mark)
+      ;; called within singular-exit-sentinel returns a mark with no
+      ;; associated buffer!
+      (goto-char mark)
+      (insert "// ** Singular process killed **\n"))))
+
+(defun singular-control-c (mode)
+  "Interrupt the Singular process running in the current buffer.
+If called interactiveley, asks whether to (a)bort the current Singular
+command, (q)uit or (r) restart the current Singular process, or (c)ontinue
+without doing anything (default).
+
+If called non-interactiveley, MODE should be one of 'abort, 'quit, 'restart,
+or 'continue."
+  (interactive
+   (let (answer)
+     (while (not answer)
+       (setq answer (read-from-minibuffer
+		   "(a)bort current command, (q)uit, (r)estart Singular or (c)ontinue? "))
+       (setq answer
+	     (cond ((equal answer "a") 'abort)
+		   ((equal answer "c") 'continue)
+		   ((equal answer "r") 'restart)
+		   ((equal answer "q") 'quit)
+		   ((equal answer "") 'continue) ; default: continue
+		   (t nil))))
+     (list answer)))
+   (cond
+    ((eq mode 'quit) (singular-kill-singular))
+    ((eq mode 'restart) (singular-restart))
+    ((eq mode 'abort) (interrupt-process (singular-process)))))
+
+(defun singular-exec (buffer name executable start-file switches)
+  "Start a new Singular process NAME in BUFFER, running EXECUTABLE.
+EXECUTABLE should be a string denoting an executable program.
+SWITCHES should be a list of strings that are passed as command line
+switches.  START-FILE should be the name of a file which contents is
+sent to the process.
+
+Deletes any old processes running in that buffer.
+Removes any empty string in SWITCHES befor passing to Singular.
+Moves point to the end of BUFFER.
+Initializes all important markers and the simple sections.
+Runs the hooks on `singular-exec-hook'.
+Returns BUFFER."
+  (let ((old-buffer (current-buffer)))
+    (unwind-protect
+	(progn
+	  (set-buffer buffer)
+
+	  ;; delete any old processes
+	  (let ((process (get-buffer-process buffer)))
+	    (if process (delete-process process)))
+
+	  ;; create new process
+	  (singular-debug 'interactive
+			  (message "Starting new Singular: %s %s"
+				   executable switches))
+	  ;; before passing SWITCHES to Singuar we remove any empty strings
+	  ;; because otherwise Singular tries to open a file with an empty
+	  ;; file name.
+	  (let ((process (comint-exec-1 name buffer
+					executable (delete "" switches))))
+	    ;; set process filter and sentinel
+	    (set-process-filter process 'singular-output-filter)
+	    (set-process-sentinel process 'singular-exit-sentinel)
+	    (make-local-variable 'comint-ptyp)
+	    (setq comint-ptyp process-connection-type) ; T if pty, NIL if pipe.
+
+	    ;; go to the end of the buffer, initialize I/O and simple
+	    ;; sections
+	    (goto-char (point-max))
+	    (singular-input-filter-init (point))
+	    (singular-output-filter-init (point))
+	    (singular-simple-sec-init (point))
+
+	    ;; completion should be initialized before scan header!
+	    (singular-completion-init)
+	    (singular-scan-header-init)
+            (singular-menu-init)
+
+	    ;; feed process with start file and read input ring.  Take
+	    ;; care about the undo information.
+	    (if start-file
+		(let ((buffer-undo-list t) start-string)
+		  (singular-debug 'interactive (message "Feeding start file"))
+		  (sleep-for 1)			; try to avoid timing errors
+		  (insert-file-contents start-file)
+		  (setq start-string (buffer-substring (point) (point-max)))
+		  (delete-region (point) (point-max))
+		  (process-send-string process start-string)))
+
+	    ;; read history if present
+	    (singular-history-read)
+
+	    ;; execute hooks
+	    (run-hooks 'singular-exec-hook))
+
+	  buffer)
+      ;; this code is unwide-protected
+      (set-buffer old-buffer))))
+
+
+;; TODO: Documentation!
+;; Note:
+;;
+;; In contrast to shell.el, `singular' does not run
+;; `singular-interactive-mode' every time a new Singular process is
+;; started, but only when a new buffer is created.  This behaviour seems
+;; more intuitive w.r.t. local variables and hooks.
+
+(defun singular-internal (executable directory switches name)
+  "Run an inferior Singular process, with I/O through an Emacs buffer.
+
+Appends `singular-switches-magic' to switches.
+Sets default-directory if directory is not-nil.
+Sets singular-*-last values."
+  (singular-debug 'interactive
+		  (message "singular-internal: %s %s %s %s"
+			   executable directory name switches))
+  (let* ((buffer-name (singular-process-name-to-buffer-name name))
+	 ;; buffer associated with Singular, nil if there is none
+	 (buffer (get-buffer buffer-name)))
+
+    ;; If directory is set, make sure that it ends in a "/" at the end.
+    ;; The check is done on both slash and backslash, but we unconditionally
+    ;; insert a slash. Hopefully that works on NT, too.
+    (and directory
+	 (not (memq (aref directory (1- (length directory))) '(?/ ?\\)))
+	 (setq directory (concat directory "/")))
+
+    (if (not buffer)
+	(progn
+	  ;; create new buffer and call `singular-interactive-mode'
+	  (singular-debug 'interactive (message "Creating new buffer"))
+	  (setq buffer (get-buffer-create buffer-name))
+	  (set-buffer buffer)
+	  (and directory
+	       (setq default-directory directory))
+
+	  (singular-debug 'interactive (message "Calling `singular-interactive-mode'"))
+	  (singular-interactive-mode)))
+
+    (if (not (comint-check-proc buffer))
+	;; create new process if there is none
+	(singular-exec buffer name executable
+		       (if (file-exists-p singular-start-file)
+			   singular-start-file)
+		       (append switches singular-switches-magic)))
+
+    ;; pop to buffer
+    (singular-debug 'interactive (message "Calling `pop-to-buffer'"))
+    (singular-pop-to-buffer singular-same-window buffer))
+
+  ;; Set buffer local singular-*-last-values
+  (setq singular-executable-last executable)
+  (setq singular-directory-last directory)
+  (setq singular-switches-last switches)
+  (setq singular-name-last name)
+  ;; Set global values, too
+  (set-default 'singular-executable-last executable)
+  (set-default 'singular-directory-last directory)
+  (set-default 'singular-switches-last switches)
+  (set-default 'singular-name-last name))
+
+(defun singular-generate-new-buffer-name (name)
+  "Generate a unique buffer name for a singular interactive buffer.
+The string NAME is the desired name for the singular interactive
+buffer, without surrounding stars.
+The string returned is surrounded by stars.
+
+If no buffer with name \"*NAME*\" exists, return \"*NAME*\".
+Otherwise check for buffer called \"*NAME<n>*\" where n is a
+increasing number and return \"*NAME<n>*\" if no such buffer
+exists."
+  (let ((new-name (singular-process-name-to-buffer-name name))
+	(count 2))
+    (while (get-buffer new-name)
+      (setq new-name (singular-process-name-to-buffer-name
+		      (concat name "<" (format "%d" count) ">")))
+      (setq count (1+ count)))
+    new-name))
+
+(defun singular ()
+  "Run an inferior Singular process using default arguments.
+Starts a Singular process, with I/O through an Emacs buffer, using the
+values of `singular-executable-default', `singular-directory-default',
+`singular-switches-default', and `singular-name-default'.
+
+For more information on starting a Singular process and on the arguments
+see the documentation of `singular-other'. To restart a previously started
+Singular process use `singular-restart'.
+
+Every time `singular' starts a new Singular process it runs the hooks
+on `singular-exec-hook'.
+
+Type \\[describe-mode] in the Singular buffer for a list of commands."
+  (interactive)
+  (singular-internal singular-executable-default
+		     singular-directory-default
+		     singular-switches-default
+		     singular-name-default))
+
+(defun singular-restart ()
+  "Run an inferior Singular process using the last arguments used.
+Starts a Singular process, with I/O through an Emacs buffer, using the
+previously used arguments.
+If called within a Singular buffer, uses the arguments of the most recent
+Singular process started in this buffer. If there is a Singular process
+running in this buffer, it is deleted without warning!
+If called outside a Singular buffer, uses the arguments of the most recent
+Singular process started in any Singular buffer (and does not delete any
+Singular process).
+If no last values are available, uses the default values (see documentation
+of `singular').
+
+For more information on starting a Singular process and on the arguments
+see the documentation of `singular-other'.
+
+Every time `singular-restarts' starts a new Singular process it runs the
+hooks on `singular-exec-hook'.
+
+Type \\[describe-mode] in the Singular buffer for a list of commands."
+  (interactive)
+
+  (if (singular-process t)
+      (singular-kill-singular))
+
+  (singular-internal singular-executable-last
+		     singular-directory-last
+		     singular-switches-last
+		     singular-name-last))
+
+(defun singular-other (executable directory switches name)
+  "Run an inferior Singular process.
+Starts a Singular process, with I/O through an Emacs buffer.
+
+If called interactively, the user is asked in the minibuffer area for an
+existing executable (with or without path), an exisiting directory or nil
+(if non-nil, sets the buffers default directory to this directory), the
+complete command line arguments to be passed to Singular (as a single
+string) and the buffer name of the singular buffer, which is surrounded by
+\"*\", if not already. (The process name of the singular process is then
+given by the buffer name with the surrounding stars stripped.)
+
+If called non-interactiveley, EXECUTABLE is the name of an existing
+Singular executable (with or without path), DIRECTORY is the name of an
+existing directory or nil. If non-nil, sets the buffers default directory
+to DIRECTORY. SWITCHES is a list of strings where each string contains one
+command line argument which is passed to Singular, and NAME is the process
+name of the Singular process (that is, the singular buffer name is given by
+NAME surrounded by \"*\").
+
+If buffer exists but Singular is not running, starts new Singular.
+If buffer exists and Singular is running, just switches to buffer.
+If a file `~/.emacs_singularrc' exists, it is given as initial input.
+Note that this may lose due to a timing error if Singular discards
+input when it starts up.
+
+If a new buffer is created it is put in Singular interactive mode,
+giving commands for sending input and handling output of Singular.  See
+`singular-interactive-mode'.
+
+Every time `singular-other' starts a new Singular process it runs the hooks
+on `singular-exec-hook'.
+
+Type \\[describe-mode] in the Singular buffer for a list of commands."
+  (interactive
+   (let* ((exec (read-file-name "Singular executable: "))
+	 ;; Remark: Do NOT call `expand-file-name' after the
+	 ;; above read-file-name! It has to be possible to enter a command
+	 ;; without path which should be searched for in $PATH.
+	 ;; `start-process' is intelligent enough to start commands with
+	 ;; not-expanded name.
+	  (dir (file-name-directory (read-file-name "Default directory: "
+						    nil
+						    (or singular-directory-default
+							default-directory)
+						    t)))
+	 (switch "")
+	 (bufname (singular-generate-new-buffer-name
+		   (downcase (file-name-nondirectory exec)))))
+
+     ;; Get command line arguments and append magic switches
+     ;; TODO: Think about default value: Up to now:
+     ;; Use singular-switches-default as init value for read-from-minibuffer
+     (let ((switches-default singular-switches-default))
+       (while switches-default
+	 (setq switch (concat switch (car switches-default) " "))
+	 (setq switches-default (cdr switches-default))))
+     ;; note: magic switches are appended by `singular-internal'
+     (setq switch (split-string (read-from-minibuffer "Singular options: "
+						      switch nil nil
+						      singular-switches-history)
+				" "))
+     ;; Generate new buffer name
+     (let (done)
+       (while (not done)
+	 (setq bufname (read-from-minibuffer "Singular buffer name: " bufname))
+	 (setq done (or (not (get-buffer bufname))
+			(y-or-n-p "Buffer exists. Switch to that buffer? ")))))
+     (if (string-match "^\\*\\(.*\\)\\*$" bufname)
+	 (setq bufname (substring bufname (match-beginning 1) (match-end 1))))
+     (list exec dir switch bufname)))
+
+  (singular-internal executable directory switches name))
+
+(defun singular-exit-singular (&optional kill-singular-buffer)
+  "Delete Singular process and kill Singular buffer.
+Deletes the buffers Singular process without warning and writes back the input
+history to file.
+If called with prefix argument, kills the Singular buffer."
+  (interactive "P")
+  (singular-debug 'interactive
+		  (message "exit singular called"))
+
+  (singular-kill-singular)
+  (if kill-singular-buffer
+      (kill-buffer (current-buffer))))
+;;}}}
+;;}}}
+
+(provide 'singular)
+
+;;; Local Variables:
+;;; fill-column: 75
+;;; End:
+
+;;; singular.el ends here.
diff --git a/emacs/singular.xpm b/emacs/singular.xpm
new file mode 100644
index 0000000..828c57d
--- /dev/null
+++ b/emacs/singular.xpm
@@ -0,0 +1,39 @@
+/* XPM */
+static char * sing_xpm[] = {
+"33 33 3 1",
+" 	c #BDBDBEBEBDBD",
+".	c #000000000000",
+"X	c #FFFFFFFFFFFF",
+"                                 ",
+"                          ..     ",
+"                         ..XX    ",
+"                        ..XX     ",
+"                       ..XX      ",
+"                      ..XX       ",
+"                     ..XX        ",
+"                    ..XX         ",
+"                   ..XX          ",
+"     ....         ..XX           ",
+"    ..XX...      ..XX            ",
+"   ..XX X ...   ..X              ",
+"   .X       .. ..X               ",
+"   .X        ....                ",
+"   .X      ..XXX..               ",
+"    .XX  ...X  XX..              ",
+"     .....XX    XX..             ",
+"         X       XX..            ",
+"                  XX..           ",
+"                   XX..          ",
+"                    XX..         ",
+"                     XX..        ",
+"                      XX..       ",
+"                       XX..      ",
+"                        XX..     ",
+"                         XXX.    ",
+"                           XX    ",
+"                                 ",
+"                                 ",
+"                                 ",
+"                                 ",
+"                                 ",
+"                                 "};
diff --git a/factory/AUTHORS b/factory/AUTHORS
new file mode 100644
index 0000000..e69de29
diff --git a/factory/COPYING b/factory/COPYING
new file mode 100644
index 0000000..5caad92
--- /dev/null
+++ b/factory/COPYING
@@ -0,0 +1,51 @@
+                        SINGULAR version 4-0
+			   Singular-Factory
+
+                     University of Kaiserslautern
+
+      Department of Mathematics and  Centre for Computer Algebra
+
+  Authors: G.-M. Greuel, R. Stobbe, J. Schmidt, M. Lee,
+           G. Pfister, H. Schoenemann
+                        Copyright (C) 1991-2014
+
+  Characteristic sets and factorization over algebraic function fields:
+                   Michael Messollen <mmessollen at web.de>
+                        Copyright (C) 1996-2010
+
+
+
+                               *NOTICE*
+
+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 ( version 2 or version 3 of the License );
+with the following additional remarks:
+
+This package is part of the software SINGULAR. The GPL is valid for
+this package, other packages may have other copyrights.
+
+Their copyrights and licences can be found in the accompanying files
+which are distributed along with these packages.
+
+Files which contain code written by M. Messollen or contain code derived from
+code written by M. Messollen contain respective details.
+
+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 (see GPL)
+
+Please send any comments or bug reports to
+<singular at mathematik.uni-kl.de>.
+
+Availability
+============
+
+The latest information about SINGULAR is always available from
+`http://www.singular.uni-kl.de'.
+
diff --git a/factory/ChangeLog b/factory/ChangeLog
new file mode 100644
index 0000000..29a7dc9
--- /dev/null
+++ b/factory/ChangeLog
@@ -0,0 +1,1829 @@
+Mi 13. Okt 15:52:56 CEST 2010
+- release 3-1-2
+- removed macos 9 stuff
+- factorize for Z/p, Z/p(a) improved
+- windows port improved (.h files instead of .inc)
+
+Fri Feb 14 16:53:42 CET 2003 * hannes: bugfix
+       could not factorize x2+xy+y2 in Fp(a)[x,y], a2+a+1=0
+       added tests in factorize(f,a) (isPurePoly(f,a))
+       added sort option to FpFactorizeUnivariateCZ and to NTL factor routines
+       (NTLconvert.cc cf_factor.cc fac_cantzass.cc)
+
+Thu Nov  7 11:29:33 MET 2002 Hans Schoenemann <hannes at mathematik.uni-kl.de>
+        * interface to NTL
+	* many fixes
+
+Wed Aug 22 16:25:16 MET DST 2001 Hans Schoenemann <hannes at mathematik.uni-kl.de>
+        * Version 1.3c: some utility functions for libfac
+	* search for main var in factorize (experimental)
+
+2000-09-02  Olaf Bachmann  <obachman at mathematik.uni-kl.de>
+
+	* configure.in, etc: support for omalloc
+
+2000-08-04  Olaf Bachmann  <obachman at mathematik.uni-kl.de>
+
+	* ffops.cc: initialize ff_prime to 0, so that first call to
+	ff_setprime always initializes ff_invtab.
+
+Tue Feb 16 19:00:03 1999  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* GNUmakefile.in (basefactorysrc): `imm.cc' added
+	  (ftestm4src): `divrem.m4' added
+	  (distfiles): `factory.cfg' added
+
+	* factory.cfg: new file
+
+	* GNUmakefile.in (.PHONY): dependencies `doxy', `doxyclean' added
+	  (doxy, doxyclean): new targets
+	  (mostlyclean): dependency `doxyclean' added
+
+	* GNUmakefile.in (doxysrc, doxyincl): new variables
+	  (doxyfiles): new variable
+
+	* GNUmakefile.in (ftestm4src): `sqrfree.m4' added
+
+	* GNUmakefile.in (ftestsrc, ftestincl): ntl-stuff added
+	  (ftestm4src): `gcd.ntl.m4', `revert.m4' added
+
+Wed Sep 23 19:05:47 1998  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* fac_ezgcd.cc (ezgcd_specialcase): bug fix (???).  See comments
+	  in the file for more information.
+
+Tue Jul  7 18:34:39 1998  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* GNUmakefile.in (ftestm4src): `extgcd.m4' added to distribution
+
+Wed Jul  1 10:57:53 1998      <pohl at FUECHSE>
+
+	* int_intdiv.cc (modulocoeff): extra call added for `mpz_mod_ui()'
+	  with void return value.  Wrapped by #define `__MWERKS__'.
+
+Tue Jun 30 16:38:41 1998  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* cf_algorithm.cc: doc fixes
+
+	* cf_algorithm.cc (divides): bug fix.  Works for zero f and g.
+	  More heuristic added.
+
+	* cf_algorithm.cc (psr, psq, psqr): bug fix.  Work for `x' with
+	  level lower than `level(f)' or `level(g)'.
+
+	* cf_algorithm.h: doc fixes
+
+	* ftmpl_inst.cc (tmax, tmin(Var, Var)): instantiations added
+
+	* GNUmakefile.in (ftestm4src): `divides.m4' added to distribution
+
+Mon Jun 29 12:41:40 1998  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* templates/ftmpl_functions.h: doc fixes
+
+	* GNUmakefile.in (basefactorysrc): `cf_inline.cc' and
+	  `cf_iter_inline.cc' added to distribution
+
+	* canonicalform.h (class CanonicalForm): friend declarations for
+	  `operator -', `operator +', `operator *', `operator /',
+ 	  `operator %', `div', `mod' replaced by ordinary declarations
+
+	* canonicalform.cc, canonicalform.h (CanonicalForm,
+	  ~CanonicalForm, isOne, isZero, operator =): definitions of
+ 	  methods moved to `cf_inline.cc'.  Declarations marked as
+ 	  `CF_INLINE' or `CF_NO_INLINE', resp.
+	  (operator -, operator +, operator *, operator /, operator %,
+	  div, mod): definitions of operators moved to `cf_inline.cc'.
+  	  Declarations marked as `CF_INLINE' or `CF_NO_INLINE', resp.
+	* canonicalform.h (CF_INLINE, CF_NO_INLINE): new #defines.
+	  `cf_iter_inline.cc' (conditionally) #included.
+
+	* cf_iter.cc, cf_iter.h (operator++, coeff, hasTerms, exp):
+	  definitions moved to `cf_iter_inline.cc'.  Declarations marked
+ 	  as `CF_INLINE' or `CF_NO_INLINE', resp.
+	* cf_iter.h (CF_INLINE, CF_NO_INLINE): new #defines.
+	  `cf_iter_inline.cc' (conditionally) #included.
+
+	* configure.in (enable_cf_inline): new `--enable'-option
+	* config.h.in (CF_USE_INLINE): new #define
+
+	* cf_inline.cc (CanonicalForm(Variable, int))): assertion added
+
+	* cf_inline.cc (isOne, isZero, operator -(CF)): order of immediate
+	  checks changed
+
+	* cf_inline.cc: new file
+
+	* cf_iter_inline.cc (operator ++, coeff, exp): assertions fixed
+
+	* cf_iter_inline.cc: new file
+
+Fri Jun 26 12:24:34 1998  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* int_cf.cc, int_cf.h (isOne, isZero): pure virtual methods
+	  implemented.  Declarations adapted.
+	* int_rat.cc, int_int.cc, int_rat.h, int_int.h, int_poly.h
+	  (isZero, isOne): methods removed.  Declarations adapted.
+	* int_pp.cc (isOne, isZero): slightly speeded up.  Doc fixes.
+	* imm.h (imm_isone, imm_isone_p, imm_isone_gf): doc fixes
+	* imm.h (imm_iszero, imm_iszero_p, imm_iszero_gf): doc fixes
+
+	* int_poly.cc, int_pp.cc, int_rat.cc (neg): doc fixes
+	* int_int.cc (neg): doc fixes.  Slightly speeded up.
+	* imm.h (imm_neg, imm_neg_p, imm_neg_gf): doc fixes
+
+Mon Jun 15 16:04:26 1998  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* configure.in: doc fixes
+
+	* configure.in: explicit path name generated slightly rewritten to
+	  work on HP's.  Absolute path names are generated already by
+	  Makefile to keep `configure.in' more readable.
+
+Fri Jun 12 16:28:48 1998  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* int_intdiv.cc: `canonicalform.h' included
+
+	* gfops.cc, int_int.cc, readcf.y: order of includes fixed
+
+	* timing.h: bug fix.  Test on `WINNT' negated.
+
+Tue Jun  9 11:52:45 1998  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* configure.in (ac_save_path): renamed to `$save_path'.  All
+	  references changed
+	  (expl_datadir, expl_gftabledir): renamed to `$explicit_datadir',
+	  `$explicit_gftabledir', resp.  All references changed.
+
+	* configure.in: checks for gmp.h and libgmp.a search in
+	  `$includedir' and `$libdir', resp.
+
+	* configure.in: new section added to get a safer explicit path
+	  expansion
+
+	* configure.in: `$gftabledir' is not longer handled in a special
+	  way for Singular
+
+Mon Jun  8 17:26:55 1998  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* singext.h: doc fix
+
+	* gfops.cc, singext.h (cf_get_table): use `feFopen()' to load
+	  GF(q) tables if built with Singular.  Declaration added to
+	  `singext.h' (by Hannes).
+
+	* configure.in: calls to `AC_PATH_PROG' ``fixed''.  Necessary
+	  because of some old autoconf version (by Olaf)
+
+	* ftmpl_inst.cc: test on `WINNT' disabled with gcc
+
+Wed Jun 03 16:47:54 1998    <pohl at FUECHSE>
+
+	* ftmpl_factor.h (template <class T> class Factor):
+	  `operator == ( const Factor<T> &, const Factor<T> &)'
+	  removed as friend and added as extra operator
+
+Wed Jun 03 14:47:41 1998    <pohl at FUECHSE>
+
+	* timing.h, readcf.y, int_poly.cc, imm.h: test on WINNT
+	  disabled with gcc
+
+Mon May 11 11:36:22 1998  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* config.h.in (FACTORY_INT64): unused declarations for MetroWerks removed
+
+	* imm.cc (imm_mul): wrapped by `#ifdef __MWERKS__'
+
+	* ffops.h (ff_bignorm): definition of `ff_bignorm' removed for
+	  MetroWerks
+	  (ff_mul): made a declaration for MetroWerks.  Defined in
+	  `ffops.cc'.
+
+	* imm.cc (imm_mul): new file for MetroWerks
+
+	* imm.h (MINIMMEDIATELL, MAXIMMEDIATELL): definition of long long
+	  constants removed for mac
+	  (imm_mul): made a declaration for MetroWerks.  Defined in
+	  `imm.cc'.
+
+	* fac_cantzass.cc (CantorZassenhausFactorFFGF,
+	  CantorZassenhausFactorExt): new local variables `firstFactor',
+	  `secondFactor' introduced to fix order of evaluation of
+	  recursive factorizations
+
+Mon Apr 20 16:34:14 1998  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* .cvsignore (stamp-h): entry re-added.  After all, its
+	  necessary.
+
+	* configure.in (MKINSTALLDIRS, MAKEHEADER): instead of using an
+	  absolute path, use relativ path and our own variables
+	  `FACTORY_MKINSTALLDIRS' and `FACTORY_MAKEHEADER'.  Do not use
+	  cache to get the variables' values.
+	* GNUmakefile.in (MKINSTALLDIRS, MAKEHEADER): use the values from
+	  `FACTORY_MKINSTALLDIRS' and `FACTORY_MAKEHEADER', resp.
+
+Tue Apr 14 14:05:47 1998  Wilfred Pohl  <pohl at mathematik.uni-kl.de>
+
+	* fac_univar.cc (UnivariateQuadraticLift): type for `log()' must
+	  be float, hence constant `2' replaced by `2.0'
+
+	* config.h.in (FACTORY_INT64): new typedef for Metroworks compiler
+
+Mon Apr  6 14:06:49 MET DST 1998  Jens Schmidt
+
+	* int_intdiv.cc:
+	  ***** merge from branch `factory-gcd' to main trunk
+
+	* ftmpl_inst.cc: instantiations for `tabs( int )' added
+
+	* fac_univar.cc (UnivariateQuadraticLift, UnivariateLinearLift):
+	  call to `div( CF, CF )' replaced by call to `operator / ( CF, CF )'
+
+Mon Mar 23 17:00:00 1998  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* GNUmakefile.in (ftestm4src): references `$(ftestm4develsrc)'
+	  instead of `$(ftestm4src)' from development `GNUmakefile' to
+	  avoid problems when building distributions
+
+Tue Mar 17 16:57:10 MET 1998  Jens Schmidt
+
+	* int_int.cc, int_int.h, int_poly.cc, int_poly.h, int_intdiv.cc,
+	* ChangeLog:
+	  ***** merge from branch `factory-gcd' to main trunk
+
+	* GNUmakefile.in:
+	  ***** merge from branch `factory-gcd' to main trunk
+
+	* timing.h, examples/application.cc:
+	  ***** merge from branch `factory-gcd' to main trunk
+
+Tue Mar 17 14:22:56 1998  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+    **************** <<< changes in branch `factory-gcd' ****************
+
+	* int_poly.cc (dividecoeff, divremcoeff): use `divideTermList()'
+	  to do their work
+	  (divideTermList): new function copied from former
+	  `divTermList()'.  Declaration added.
+
+	* int_poly.cc (divTermList): uses `div()' to divide coefficients
+
+	* int_int.cc (dividesame, dividecoeff, divsame, divcoeff,
+	  modulosame, modulocoeff, modsame, modcoeff, divremsame,
+	  divremcoeff, divremsamet, divremcoefft): methods moved to
+	  int_intdiv.cc.  Slightly speeded up.
+
+	* int_int.h (normalizeMPI, uiNormalizeMPI, normalizeMyself,
+	  uiNormalizeMyself): new `InternalIntger' methods.  Declarations
+	  added.
+
+	* int_int.h (class InternalInteger): static member `initialized' removed
+
+	* int_intdiv.cc: new file
+
+	* GNUmakefile.in (basefactorysrc): int_intdiv.cc added to
+	  distribution
+
+	* timing.h (TIMING_END_AND_PRINT): added for windows
+
+	  (TIMING_DEFINE_PRINTPROTO, TIMING_PRINT): macros common to all
+	  platforms extracted from `#ifdef' directive
+
+	* timing.h (TIMING_RESET): new macro
+
+Fri Mar 13 17:05:10 1998  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* examples/application.cc (main): cosmetic changes
+
+	* canonicalform.cc, canonicalform.h, cf_algorithm.cc, cf_factor.cc,
+	* cf_map.cc, cf_map.h, fac_ezgcd.cc, fac_multivar.cc,
+	* fac_univar.cc, fac_util.cc, fac_util.h, ffops.cc, ftmpl_array.h,
+	* ftmpl_factor.h, ftmpl_functions.h, ftmpl_list.h, ftmpl_matrix.h,
+	* sm_sparsemod.cc, sm_util.cc, sm_util.h, ftest/ChangeLog,
+	* ftest/commonden.m4, ftest/norm.m4, templates/ftmpl_array.cc,
+	* templates/ftmpl_factor.cc, templates/ftmpl_functions.h,
+	* templates/ftmpl_list.cc, templates/ftmpl_matrix.cc, ChangeLog,
+	* GNUmakefile.in, cf_algorithm.h, cf_gcd.cc, factory.template,
+	* ftmpl_inst.cc:
+	  ***** merge from main trunk to branch `factory-gcd'
+
+    **************** >>> changes in branch `factory-gcd' ****************
+
+Thu Mar 12 12:21:33 1998  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* cf_gcd.cc (maxnorm): function removed.  All references replaced
+	  by `maxNorm()'.
+
+	* fac_univar.cc (norm): function removed.  All references replaced
+	  by `euclideanNorm()'.
+
+	* fac_util.cc (maxCoeff): function removed.  Declarations
+	  adapted.  All references replaced by `maxNorm()'.
+
+	* cf_algorithm.cc (divides): slightly speeded up.
+
+	* canonicalform.h (sign): new function
+
+	* canonicalform.cc (blcm): new function.  Declaration added.
+
+Wed Mar 11 10:39:33 1998  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* cf_algorithm.cc (cden, common_den): renamed to
+	  `internalBCommonDen()' and `bCommonDen()', resp.  Declarations
+	  adapted. All references changed.
+
+	* cf_algorithm.h (abs): function `abs()' moved from
+	  `canonicalform.h' to `cf_algorithm.h'.  All referring files
+	  include `cf_algorithm.h'.
+
+	* cf_algorithm.cc (maxNorm, euclideanNorm): new functions.
+	  Declarations added.
+
+	* cf_algorithm.cc (internalBCommonDen): uses `blcm()' instead of
+	  `lcm()'
+
+	* GNUmakefile.in (ftestm4src): `norm.m4' and `commonden.m4' added
+	  to distribution
+
+	* templates/ftmpl_functions.h (tabs): new function
+
+	* ffops.cc (ff_setprime): uses `memset()' to clear inversion
+	  table
+
+	* ftest/ChangeLog, ftest/ftest_io.cc, ftest/ftest_io.h,
+ 	* ftest/ftest_util.cc, ftest/ftest_util.h, ftest/ftest_util.m4,
+ 	* ftest/gcd.fex, ftest/runfex:
+  	  ***** merge from branch `factory-gcd' to main trunk
+
+Tue Mar 10 15:44:06 1998  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* factory.template, ftmpl_inst.cc, templates/ftmpl_array.cc,
+	  templates/ftmpl_factor.cc, templates/ftmpl_list.cc,
+	  templates/ftmp_matrix.cc: #include directives for mac fixed
+
+	* ftmpl_array.h, ftmpl_factor.h, ftmpl_functions.h, ftmpl_list.h,
+	  ftmpl_matrix.h: new files.  #include of `templates/ftmpl_xxx.h'
+	  changed to include of `ftmpl_xxx.h'.
+	* GNUmakefile.in (basefactoryincl): new header files added to
+	  distribution
+
+Fri Feb 27 10:24:22 1998  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+    **************** <<< changes in branch `factory-gcd' ****************
+
+	* var_intglobal.cc, var_intglobal.h: files removed (do not belong
+	  to this branch!)
+
+	* cf_primetab.h: file removed
+
+	* cf_defs.h (SW_QUOTIENT, SW_FAC_USE_BIG_PRIMES): switches removed
+
+	* cf_linsys.cc (linearSystemSolve, solve, bound determinant2):
+	  incorrect respective unused code removed
+
+	* cf_char.cc (setCharacteristic): adapted to new prime generation
+	  scheme
+	* cf_char.cc (setCharacteristic): previous adaption slightly
+	  changed.  The largest small prime is now looked up only once.
+
+	* cf_gcd.cc (gcd_poly_univar0): adapted to new prime generation
+	  scheme
+	* fac_ezgcd.cc (findBound): adapted to new prime generation
+	  scheme
+	* cf_linsys.cc (determinant): adapted to prime generation
+	  scheme
+	* sm_sparsemod.cc (internalSparsemod): adapted to new prime
+	  generation scheme
+	* fac_univar.cc (choosePrimes): adapted to new prime generation
+	  scheme
+
+	* sm_sparsemod.cc (sparsemod): debug output added
+
+	* fac_univar.cc (cf2double): function removed
+
+	* fac_univar.cc (UnivariateQuadraticLift, UnivariateLinearLift):
+	  argument `Gamma' removed.  All callers changed.
+
+	* fac_univar.cc (UnivariateQuadraticLift, UnivariateLinearLift): call to
+	  `div( CF, CF )' replaced by call to `operator / ( CF, CF )'
+
+Thu Feb 26 17:58:31 1998  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* gcd_pmultiv.h (class CFPrimitiveMultivariateGCD): renamed to
+	  `CFPrimitiveMultivariateGcd'.  All references changed.
+	  (class CFSubResGCD): renamed to `CFSubResGcd'.  All references
+	  changed.
+
+	* gcd_pmultiv.h (class CFPrimitiveMultivariateGCD): does no longer
+	  inherit virtual from `CFPrimitiveGcd'
+	  (class CFSubResGcd): does no longer inherit from
+	  `CFPrimitiveUnivariateGCD'
+
+	* gcd_pmultiv.h (class CFSubResGcd): new method `clone()'
+
+	* gcd_pmultiv.h: new file
+
+	* gcd_pmultiv.cc (CFSubResGcd::execute): bug fix.  Superfluous
+	  break removed.
+	  (execute): bug fix.  Assertion fixed.
+
+	* gcd_pmultiv.cc: new file
+
+    **************** >>> changes in branch `factory-gcd' ****************
+
+Fri Feb 20 17:41:23 1998  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* GNUmakefile.in (installcf, installmem): `ranlib' libraries after
+	  installing them for SUN machines
+
+Tue Feb 10 10:47:04 1998  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* cf_switches.h: doc fix
+
+Mon Feb  9 15:57:07 1998  Ruediger Stobbe  <rstobbe at de.oracle.com>
+
+	* cf_factor.cc (factorize): factorize now handles characteristic
+	  0 correct, e.g. rational coefficients and SW_RATIONAL = ON.
+
+Mon Feb  9 11:40:41 1998  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* cf_primetab.cc: new file
+
+Thu Feb  5 16:53:21 1998  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* configure.in (enable_timing, enable_debugoutput): extra timing
+	  and debugoutput magic removed
+	* GNUmakefile.in (@timingtargets@, @debouttargets@,
+	  @debtimingtargets@): extra timing and debugoutput magic removed
+
+Tue Feb  3 14:03:00 1998  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* GNUmakefile.in (ftestm4src): `bextgcd.m4' and `bgcd.m4'
+	  removed.  References variable `ftestm4src' instead.
+
+Mon Feb  2 09:55:16 1998  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* cf_chinese.cc (chineseRemainder( const CanonicalForm & ...)):
+	  completely rewritten
+
+Fri Jan 30 15:06:26 1998  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* cf_chinese.cc (chineseRemainder): debug output added
+
+	* cf_chinese.cc	(chineseRemainder( const CFArray & ...)): slightly
+	  speeded up
+
+	* cf_gcd.cc (iextgcd, igcd): functions removed.  All references
+	  replaced by `bextgcd()' and `bgcd()', resp.
+
+	* canonicalform.h (iextgcd): declaration removed
+
+Thu Jan 22 10:38:34 1998  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* int_cf.cc, int_int.cc int_rat.cc (bgcdsame, bgcdcoeff,
+	  bextgcdsame, bextgcdcoeff): new methods.  Declarations added.
+
+	* GNUmakefile.in (ftestm4src): `bgcd.m4' and `bextgcd.m4' added to
+	  distribution
+
+	* canonicalform.h (mvar): bug fix.  Declared as `Variable mvar
+	  (...)'.
+
+	* canonicalform.cc (bgcd, bextgcd): new functions.  Declarations
+	  added.
+
+Fri Jan 16 09:08:17 1998  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* cf_switches.h: doc fix
+
+	* cf_algorithm.h (divides): declaration moved from canonicalform.h
+	  to cf_algorithm.h
+
+	* cf_switches.cc: doc fix
+
+Tue Jan 13 14:56:42 1998  Olaf Bachmann  <obachman at mathematik.uni-kl.de>
+
+	* configure.in: changed order of library checks (-lm before
+	  -lgmp); check for atof in -lm check, to work around a bug on
+ 	  some linux machines.
+
+Tue Jan  6 11:01:23 1998  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* .cvsignore (stamp-h): entry removed
+
+Wed Dec 17 09:56:25 1997  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* canonicalform.cc (operator ==, operator !=): rewritten and
+	  speeded up
+	  (operator >): slightly speeded up
+
+	* int_cf.h (class InternalCF): `sign()' declared as const
+
+	* int_poly.cc (comparesame): doc and assertion fix
+
+	* int_int.cc (sqrt, ilog2): assertion fixes
+
+	* int_pp.cc (comparecoeff): assertion fix
+
+	* int_rat.cc (comparesame): doc fix
+
+	* int_cf.cc (InternalCF::sign): method made pure virtual.
+	  Declaration adapted.
+
+	* int_cf.cc (taildegree): bug fix.  Did not check whether CO is
+	  zero.
+
+	* imm.h (imm_cmp): doc fix
+
+	* canonicalform.cc (CanonicalForm::gcd): method removed.
+	  Declaration adapted.
+
+	* canonicalform.cc (degree, taildegree): one more time slightly
+	  speeded up.  Hopefully for the last time.
+
+Fri Dec 12 10:06:33 1997  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* imm.h (imm_cmp_p, imm_cmp_gf): comparisons fulfill law of
+	  trichitomy
+
+	* readcf.y (yylex): parser reads generator from GF(q) correctly
+
+Tue Dec  9 10:03:07 1997  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* GNUmakefile.in (.PHONY): dependencies `$(srcdir)/winnt/factory.h'
+	  and `$(srcdir)/winnt/factoryconf.h' added
+
+	* winnt/factory.h:  automatically created from `factory.template'
+	  using `makeheader'
+
+	* winnt/factoryconf.h: automatically created from
+	  `factoryconf.template' using `makeheader'
+
+	* GNUmakefile.in (dist): dependencies `$(srcdir)/winnt/factory.h'
+	  and `$(srcdir)/winnt/factoryconf.h' added
+	  ($(srcdir)/winnt/factory.h): new target
+	  ($(srcdir)/winnt/factoryconf.h): new target
+
+	* GNUmakefile.in (distntfile): new variable
+	  (distfiles): `$distntfiles' added to distribution
+	  (dist): creates directory `winnt/'
+	  (distfiles): `bin/makeheader.pl' added to distribution
+
+	* config.h.in (FACTORY_INT64): new define
+
+	* bin/makeheader.pl: new file
+
+	* int_poly.cc (comparecoeff): unused argument `acoeff' removed
+
+Mon Dec  8 18:56:39 1997  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* INSTALL, README: doc fixes for the Windows NT port
+
+Thu Nov 27 21:00:00 1997  Ruediger Stobbe  <rstobbe at de.oracle.com>
+
+	* winnt: new directory containing configuration files for
+	  Microsoft Windows NT port using MS Visual C++ 5.0
+
+	* winnt/INSTALL.nt: new file that describes the make process on
+	  Windows NT
+
+	* winnt/nt.mak: Makefile for Windoes NT
+
+	* winnt/config.h: preconfigured file for Windows NT
+
+	* winnt/factoryconf.h: for the first time this file is a hand-made
+	  version of factoryconf.h for Windows NT
+
+	* winnt/factory.h: for the first time this file is a hand-made
+	  version of factory.h for Windows NT
+
+	* config.h.in: new typedef FACTORY_INT64 for 64 bit integer type of various
+	  platforms (currently 'long long int' for gcc and '__int64' for
+	  MS VC++)
+
+	* readcf.y: malloc.h and memory.h are included in the case of WINNT
+	  to have prototypes for alloca and memcpy
+
+	* ffops.h: now uses FACTORY_INT64 instead of long long int
+
+	* ffops.cc: now uses FACTORY_INT64 instead of long long int
+
+	* imm.h: now uses FACTORY_INT64 instead of long long int
+
+	* int_poly.cc: includes strstrea.h instead of strstream.h in the
+	  case of WINNT (a typical Microsoft 8.3 problem - its a pity)
+
+	* cf_random.cc: the way const data members were used was not
+          conforming to the C++ standard. Now there is a version of
+	  RandomGenerator that should run the same way on gcc as well as on
+	  CodeWarrior (mac) and MS VC++ (nt) and every other compiler
+	  conforming to the C++ standard
+
+	* fac_iterfor.cc: fixed assertion that refers to a variable that
+	  was not in the scope. Wondering why gcc compiled it
+
+	* fac_sqrfree.cc: isSqrFreeZ now returns a bool, as declared in
+	  the prototype. Again wondering about gcc's behaviour
+
+	* sm_sparsemod.cc: array declaration of varf, varg and schnitt on
+	  on the heap instead on the stack because the array size is not
+	  a constant. delete [] is called at a suitable place
+
+	* fac_cantzass.h: MS VC++ does not like a default value for a
+	  parameter that is a reference (in some sense this is good behaviour)
+	  Therefore there are now no default values for the parameter list
+	  of FpFactorizeUnivariateCZ
+
+	* fac_cantzass.cc: No reference parameters for FpFactorizeUnivariateCZ
+
+	* cf_factor.cc: FpFactorizeUnivariateCZ is called with full parameter
+	  list
+
+	* fac_univar.cc: FpFactorizeUnivariateCZ is called with full parameter
+	  list
+
+	* ftmpl_inst.cc: MS VC++ does not like to explicitly instantiate
+	  template functions - tmax and tmin are therefore not instatiated in
+	  the case of WINNT
+	  Anyway it is not clear if this file is needed when using MS VC++
+	  since the handling of templates in MS VC++ done in the spirit of
+	  AT&T's Cfront compilers which do a more automatic job
+
+	* templates/ftmpl_list.h: MS VC++ wants a forward declaration of
+	  template class List<T> and template class ListIterator<T>. This
+	  should be no problem for gcc
+
+	* timing.h: changes in the case of WINNT
+
+Fri Nov 21 15:25:27 1997  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* canonicalform.h (class CanonicalForm): inline method hasGcd()
+	  removed.
+
+	* int_poly.cc (coeff): explicit cast to CanonicalForm added
+	  (coeff): cosmetic change
+
+	* int_rat.cc (comparecoeff): bug fix.  Did not calculate dummy
+	  correctly.
+	  (comparecoeff): assertion moved into `if' branch
+
+	* int_pp.cc (comparesame): assertion added
+
+	* int_int.cc (comparesame): assertion added
+
+	* int_cf.cc (coeff): explicit cast to CanonicalForm added
+
+	* int_cf.cc (comparecoeff): function made pure virtual.
+	  Declarations adapted.
+	* int_cf.h (class InternalCF): new pure virtual function
+	  comparecoeff()
+
+	* imm.h: doc fix
+
+	* GNUmakefile.in (ftestm4src): fbinops.m4 added to distribution
+
+Thu Nov 20 16:21:51 1997  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* imm.h: functions rereordered
+
+Wed Nov 19 12:21:27 1997  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* gfops.h: functions reordered
+
+	* imm.h (imm_sign): doc fix
+
+	* imm.h: functions reordered
+
+Thu Nov 13 09:10:53 1997  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* cf_chinese.cc (chineseRemainder): `const CF' in arguments
+	  changed to `const CF &'.  Declaration adapted.
+
+	* configure.in: doc fix
+
+	* GNUmakefile.in (ftestall): new target
+	  (.PHONY): dependencies `ftestall' `ftestclean' `ftestdistclean'
+	  added
+
+	* GNUmakefile.in (%.d): dependency generation uses temporary files
+	  (clean): removes these temporary files
+
+	* GNUmakefile.in ($(ftestexec)): dependecy `factoryconf.h' added
+
+Wed Nov 12 18:08:51 1997  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* configure.in: check for `GetOpt.h' removed
+
+Thu Nov  6 16:43:17 1997  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* configure.in: check for `libg++.a' commented out
+
+Wed Nov  5 14:48:46 1997  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* GNUmakefile.in (conftest): new target
+	  ($(ftestexec), gengftables.o): dependency `conftest' added
+
+	* GNUmakefile.in (gengftables.o): some dependencies removed
+	  (gengftables): dependencies slightly changed
+
+	* configure.in: exits with error on absence of libgmp.a or libm.a
+
+	* configure.in: check for `unistd.h' added
+
+	* configure.in: check for `libg++.a' added
+
+Wed Oct 29 12:41:04 1997  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* configure.in: check for `ln -s' added
+
+	* configure.in: checks for header files necessary for the FTE
+	  added
+
+	* GNUmakefile.in (LN_S): new variable
+
+	* GNUmakefile.in ($(ftestexec)): new target
+
+	* GNUmakefile.in (ftestsrc, ftestincl, ftestm4src, ftestdistfiles,
+	  ftestexec): new variables
+	  (distsrc, distincl, distfiles, dist): FTE added to distribution
+	  (ftestclean, ftestdistclean): new targets
+	  (clean, distclean): dependencies ftestclean and ftestdistclean,
+	  resp., added
+
+	* GNUmakefile.in (ftest/GNUmakefile): new target
+
+	* GNUmakefile.in (gengftables): rule slightly simplified
+
+	* test_install.cc (main): calls to `operator<<()' replaced by
+	  calls to `printf()'
+
+	* configure.in (M4FLAGS): new output variable
+	* configure.in (M4): check for `m4' added
+
+	* configure.in: creates `ftest/GNUmakefile'
+
+Tue Oct 28 14:46:08 1997  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+
+    **************** Factory Version 1.3b released ****************
+
+
+	* NEWS: updated to 1.3b
+
+	* README: doc fix.  Updated to 1.3b.
+
+	* INSTALL: doc fix.  Updated to 1.3b.
+
+	* configure.in (factory_version): updated to 1.3b
+
+	* examples/GNUmakefile: doc fix
+
+	* configure.in (factory_configuration): new variable
+	* config.h.in (FACTORYCONFIGURATION): new #define
+
+	* configure.in (ac_cv_shift): set to `yes' in case of cross
+	  compiling
+
+	* examples/application.cc (main): check on existence of GF(q)
+	  tables removed
+
+Mon Oct 27 15:14:19 1997  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* examples, examples/GNUmakefile, examples/application.cc,
+ 	  examples/gcd.cc, examples/factorize.cc: new files
+	* GNUmakefile.in (distfiles, dist): `examples/' and `examples/*'
+	  added to distribution
+
+	* canonicalform.cc (operator >, operator <): bug fix.  Calls
+	  `comparecoeff()' in the right way.
+
+Fri Oct 24 18:44:37 1997  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* GNUmakefile.in (TMPLCXXFLAGS): set to `$(LIBCXXFLAGS)'
+
+	* cf_gcd.cc (gcd): bug fix.  Handles polynomials with rational
+	  coefficients correctly
+
+Thu Oct 23 14:13:42 1997  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* ftmpl_inst.cc: implicit instantiations of `ListItem<T>' changed
+	  to explicit instantiations
+
+	* factory.template, factoryconf.template, gengftables.cc,
+	  ftmpl_inst.cc: doc fix
+
+	* cf_globals.cc (factoryConfiguration): new external variable.
+	  Declaration added.
+	* test_install.cc (main): prints factoryConfiguration
+
+Wed Oct 22 15:41:30 1997  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* configure.in: doc fixes
+
+	* canonicalform.cc (operator ()): speeded up
+
+	* cf_random.cc (factoryrandom): returns a random number without
+	  calculating any remainder if n equals zero
+
+	* ffops.cc (ff_setprime): does not clear table of primes if the
+	  prime number used last time equals new one
+
+Tue Oct 21 13:24:48 1997  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* test_install.cc: new file
+	* GNUmakefile.in (distsrc): distribution file test_install.cc
+	  added
+	  (installtest, test_install, iftmpl_inst.o, test_install.o): new
+	  targets
+	  (clean): removes test_install
+	  (.PHONY): phony target installtest added
+
+Wed Oct 15 16:31:53 1997  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* canonicalform.cc (taildegree): slightly speeded up
+
+	* canonicalform.cc (operator []): assertion added.  Bug fix (did
+	  not work for immediates).
+
+	* canonicalform.cc (den, deriv, operator []): explicit casts to
+	  CanonicalForm added
+	  (sqrt): explicit calls to CFFactory::basic removed
+
+Tue Oct 14 16:47:28 1997  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* canonicalform.cc (mvar, degree): slightly speeded up
+
+Fri Oct 10 10:19:07 1997  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* gfops.cc (gf_get_table): casts to 'char *' added to avoid
+	  warnings
+
+	* int_pp.cc: superfluous arguments removed
+
+	* int_int.cc: doc fix
+
+	* int_cf.cc: doc fix
+
+	* int_rat.cc: doc fix
+
+	* int_cf.cc (den): returns 'CFFactory::basic( 1 )' instead of
+	  'genOne()'
+
+	* canonicalform.cc (LC, degree( v ), tailcoeff, deriv): slightly
+	  speeded up
+
+	* canonicalform.cc (Lc): new method.  Declaration added.
+	* int_cf.cc (Lc): new method.  Declaration added.
+	* int_poly.cc (Lc): new method.  Declaration added.
+
+Thu Oct  9 10:20:56 1997  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* cf_algorithm.cc (divides): moved from canonicalform.cc to
+	  cf_algorithm.cc.  Declaration moved, too.  In all files which
+ 	  refer to this function #include of cf_algorithm.h added.
+	  (divides): doc fix
+	* canonicalform.cc (divides): moved to cf_algorithm.cc.
+	  Declaration moved, too.
+
+	* canonicalform.h (Lc): new function
+
+Wed Oct  1 14:21:53 1997  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* cf_random.h: (factoryrandom): n defaults to zero
+
+	* cf_random.cc (factoryrandom): checks for n = zero added
+
+Tue Sep 30 10:22:43 1997  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* GNUmakefile.in (%.d): order of dependencies changed
+
+Mon Sep 29 08:11:42 1997  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* GNUmakefile.in (%.d): `factoryconf.h' added as dependency
+
+	* canonicalform.h: doc fix
+
+	* cf_ops.cc (size( CF ), size( CF, Var )): new functions.
+	  Declarations added.
+
+	* fac_univar.cc: doc fix
+
+	* cf_chinese.cc: doc fix
+
+	* cf_resultant.cc: doc fix
+
+	* cf_gcd.cc (maxnorm): spurious variable `h' removed
+
+	* cf_gcd.cc (balance): slightly speeded up
+
+Fri Sep 26 12:54:41 1997  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* cf_assert.h: prints the function now where the assrtion occured if
+	  we are translating with gcc
+
+Thu Sep 25 13:51:01 1997  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* cf_gcd.cc (chinesePoly): function removed
+	  (gcd_poly_univar0): slightly speeded up
+
+	* cf_gcd.cc (lcm): bug fix.  Returns zero now if f or g equals
+	  zero.
+
+	* cf_gcd.cc (gcd_poly): does not call sparsemod on univariate
+	  polynomials an longer
+
+	* cf_gcd.cc (vcontent): assertion added.
+
+	* cf_gcd.cc (content( CF, Variable )): slightly speeded up.
+	  Assertion added.
+
+Wed Sep 24 12:35:40 1997  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* canonicalform.cc (deriv): speeded up
+
+Tue Sep 23 17:24:24 1997  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* int_int.cc: doc fix
+
+	* canonicalform.cc: doc fix
+
+Fri Sep 12 17:25:14 1997  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* cf_gcd.cc (isqrt): function removed
+
+	* canonicalform.cc: doc fix
+
+Wed Sep 10 15:36:15 1997  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* int_cf.cc (InternalCF::sign): assertion added
+
+	* int_rat.cc (InternalRational::sign): call to mpz_cmp_si()
+	  replaced by call to mpz_sgn()
+	* int_pp.cc (InternalPrimePower::sign): call to mpz_cmp_si()
+	  replaced by call to mpz_sgn()
+	* int_int.cc (InternalInteger::sign): call to mpz_cmp_si()
+	  replaced by call to mpz_sgn()
+
+	* int_pp.cc, int_int.cc, int_rat.cc, int_poly.cc, int_cf.cc,
+	  canonicalform.cc (sign): doc fix
+
+	* imm.h (imm_sign): bug fix.  imm_sign() returned 0 for sign(1)
+	  when calculating in GF(q).
+	* imm.h (imm_sign): bug bug fix
+
+	* gfops.h (gf_sign): doc fix
+
+	* configure.in (expl_datadir): initialization fixed.  If
+	  $expl_datadir is relative we prepend the current working
+	  directory now.
+
+	* cf_gcd.cc (isqrt): function removed
+
+Tue Sep  9 09:06:17 1997  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* README: doc fix
+
+	* INSTALL: doc fix
+
+	* cf_globals.h: doc fix
+
+	* cf_globals.cc: #include fix, doc fix
+
+	* cf_primes.cc, fac_cantzass.cc, int_pp.cc, int_rat.cc: #include
+	  fix
+
+	* cf_factor.cc: #include fix
+	  (factorize): cf_glob_switches.isOn() replaced by isOn() for
+	  sake of uniformity
+
+	* cf_ops.cc (swapvar_between): arguments to operator * swapped
+
+	* cf_ops.cc (swapvar_between, swapvar_rec): functions reordered
+	  and declarations removed
+
+	* cf_ops.cc (swapvar_between1, swapvar_rec1, swapvar1): new
+	  experimental functions, to be removed in future
+
+	* cf_chinese.cc: doc fix
+
+	* fac_multihensel.cc: #include fix
+
+	* fac_berlekamp.cc: #include fix
+
+	* cf_util.cc: #include fix
+
+	* ffops.h: #include fix
+
+Mon Sep  8 12:39:09 1997  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* cf_algorithm.cc (psr, psq, psqr): assertions added
+
+	* cf_algorithm.cc (psq, psqr): return correct values now if deg(f)
+	  < deg(g)
+	  (psr, psq, psqr): return correct values now if f = 0
+
+	* cf_algorithm.cc (cden): recursion terminates now for f in base
+	  domain instead for f in coefficient domain
+
+	* cf_map.h: doc fix
+
+	* cf_map.cc: doc fix
+
+	* cf_algorithm.h: doc fix
+
+	* cf_switches.h: doc fix
+
+	* cf_switches.cc: doc fix
+
+Thu Sep  4 10:19:25 1997  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* cf_ops.cc: (replacevar, replacevar_between): new functions
+	* canonicalform.h (replacevar): new declaration
+
+	* cf_algorithm.cc: doc fix
+
+	* cf_resultant.cc: doc fix
+
+	* cf_algorithm.cc: new file
+	  (psr, psq, psqr, cden, common_den): functions moved from
+	  cf_ops.cc to cf_algorithm.cc
+	* cf_ops.cc (psr, psq, psqr, cden, common_den): functions moved
+	  to cf_algorithm.cc
+	* cf_algorithm.h: declarations of functions from cf_algorithm.cc
+	  moved from canonicalform.h to cf_algorithm.h
+	* canonicalform.h: declarations of functions from cf_algorithm.cc
+	  moved to cf_algorithm.h.  In all files which refer to these
+ 	  functions #include of cf_algorithm.h added.
+	* GNUmakefile.in (basefactorysrc): cf_algorithm.cc added to
+	  distribution
+
+	* cf_ops.cc (apply): bug fix.  In case f.inCoeffDomain() result is
+	  now initialized to f.
+
+Mon Sep  1 10:47:41 1997  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* canonicalform.h (resultant): declaration moved to cf_algorithm.h
+	* cf_algorithm.h (resultant): declaration moved from
+	  canonicalform.h to cf_algorithm.h
+
+	* cf_ops.cc (resultant): function moved to cf_resultant.cc
+	* cf_resultant.cc (trivialResultant): new function
+	* cf_resultant.cc (resultant): moved from cf_ops.cc to
+	  cf_resultant.cc.  Completely rewritten.
+
+	* cf_ops.cc (psr): returns f now if deg(f) < deg(g)
+
+	* cf_resultant.cc (subResChain): new function
+	* cf_algorithm.h (subResChain): new declaration
+
+	* cf_factor.cc (factorize( CanonicalFormn, bool ), sqrFree):
+	  default argument initializer from definition removed
+
+Fri Aug 29 09:10:28 1997  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* canonicalform.cc (degree( Variable )): slightly speeded up
+	  (deriv( Variable )): slightly speeded up
+
+	* canonicalform.h (deriv): doc fix
+
+	* canonicalform.cc (deriv( Variable )): assertion added
+	  (deriv( Variable )): bug fix
+
+	* cf_algorithm.h: declarations of functions from cf_linsys.cc
+	  moved from canonicalform.h to cf_algorithm.h
+	* canonicalform.h: declarations of functions from cf_linsys.cc
+	  moved to cf_algorithm.h
+
+	* cf_factor.cc (sqrFree( CF )): removed
+	  (sqrFree( CF, bool )): default argument initializer added
+	  (factorize( CF, bool )): default argument initializer added
+	* cf_algorithm.h  (sqrFree( CF )): declaration removed
+	  (sqrFree( CF, bool )): default argument initializer added to
+	  declaration
+	  (factorize( CF, bool )): default argument initializer added to
+	  declaration
+
+	* GNUmakefile.in (basefactorysrc): cf_resultant.cc added to
+	  distribution
+
+	* cf_algorithm.h: declarations from cf_factor.h moved to
+	  cf_algorithm.h
+	* cf_factor.h: declarations moved to cf_algorithm.h.  cf_factor.h
+	  removed.  All #include statements changed.
+	* GNUmakefile.in (basefactoryincl): cf_factor.h removed from
+	  distribution
+	* canonicalform.h: declarations of functions from cf_factor.cc
+	  removed.  In all files which refer to these functions #include
+	  of cf_algorithm.h added.
+
+	* cf_algorithm.h: new file
+	* cf_algorithm.h: declarations from cf_chinese.h moved to
+	  cf_algorithm.h
+	* cf_chinese.h: declarations moved to cf_algorithm.h.
+	  cf_chinese.h removed.  All #include statements changed.
+	* GNUmakefile.in (basefactoryincl): cf_chinese.h removed from
+	  distribution.  cf_algorithm.h added to distribution.
+
+Thu Aug 28 09:21:15 1997  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* cf_map.h: superfluous '#include "templates/ftmpl_functions.h"'
+	  removed
+
+Mon Aug  4 16:57:27 1997  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* canonicalform.cc (sqrt): doc fix
+
+Fri Aug  1 11:06:58 1997  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* cf_map.cc (operator << ( ostream& s, const CFMap & m )):
+	  rewritten
+
+	* configure.in: checks for compiler characteristic are done with C
+	  instead of C++
+
+Thu Jul 31 14:59:07 1997  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* fac_univar.cc (kBound): bound fixed
+
+	* canonicalform.h (sqrt): doc fix
+
+	* canonicalform.cc (sqrt): immediate case completely rewritten
+
+Wed Jul 30 09:40:08 1997  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* cf_linsys.cc (bound): off by one errors fixed
+	(linearSystemSolve): off by one errors fixed
+
+	* cf_linsys.cc (bound): debug output added
+
+	* cf_linsys.cc (bound): returns now bound + 1
+
+	* canonicalform.cc (sqrt): sqrt(0) works now
+	(sqrt): assertion added
+	(sqrt): 'int h' changed to 'long long h'.  Casts added.
+
+	* cf_defs.h (SW_RATIONAL, SW_QUOTIENT, SW_SYMMETRIC_FF,
+	  SW_BERLEKAMP, SW_FAC_USE_BIG_PRIMES, SW_FAC_QUADRATICLIFT,
+	  SW_USE_EZGCD, SW_USE_SPARSEMOD): #defines replaced by 'const
+	  int's
+
+	* canonicalform.cc (fillVarsRec, getNumVars, getVars): moved to
+	  cf_ops.cc
+	* cf_ops.cc (fillVarsRec, getNumVars, getVars): moved from
+	  canonicalform.cc to cf_ops.cc
+
+	* cf_ops.cc: doc fix
+
+Thu Jul 24 12:44:46 1997  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* GNUmakefile.in (distfiles): bin/folding.el and bin/fold-docu.el
+	  added
+
+Wed Jul 23 09:45:35 1997  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* cf_map.h (class CFMap): references to List<CanonicalForm>
+	  replaced by CFList
+
+	* cf_map.cc (CFMap( CFList )): 'P.append()' replaced by 'P.insert()'
+
+	* cf_chinese.cc (chineseRemainder( CF, ... )): operator % replaced
+	  by function mod()
+
+	* README: doc fix
+
+Tue Jul 22 11:04:30 1997  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* cf_map.cc (CFList, CFListIterator, MPListIterator): references to
+	  List<CanonicalForm>, ListIterator<CanonicalForm>, and
+ 	  ListIterator<MapPair> replaced by their respective typedefs
+
+	* canonicalform.cc (initCanonicalForm): initialization of switches
+	  removed since they are initialized by constructor
+
+	* bin/folding.el: new file
+	* bin/fold-docu.el: new file
+	* bin/fold-docu.el (fold-docu): works now for all fold marks
+	* README: doc fix
+
+	* cf_switches.h (CFSwitchesMax): new constant
+	* cf_switches.h (class CFSwitches): number of switches replaced by
+	  references to 'const int CFSwitchesMax'
+	* cf_switches.cc (CFSwitches): number of switches replaced by
+	  references to 'const int CFSwitchesMax'
+
+
+    **************** Factory Version 1.3a released ****************
+
+
+	* configure.in: doc fix
+
+	* INSTALL: doc fix
+
+	* NEWS: doc fix
+
+	* README: doc fix
+
+Mon Jul 21 12:58:04 1997  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* sm_sparsemod.cc (internalSparsemod): sparsemod() renamed to
+	  internalSparsemod()
+	  (sparsemod): new function which is a simple wrapper around
+	  internalSparsemod()
+
+	* GNUmakefile.in (distfiles): NEWS and INSTALL added to
+	  distribution
+
+	* configure.in (factory_version): version number incremented
+	* INSTALL: version number incremented
+	* README: version number incremented
+
+	* configure.in: doc fix
+
+	* GNUmakefile.in (dist): changed suffix of distribution suffix
+	  (distclean): changed suffix of distribution suffix
+
+	* NEWS: doc fix
+
+	* INSTALL: doc fix
+
+	* INSTALL: new file
+
+	* README: doc fix
+
+	* GNUmakefile.in (installgftables): bug fixes undone
+	(installgftables): completely rewritten
+
+Sat Jul 19 08:57:34 1997  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* GNUmakefile.in (installgftables): bug fix
+
+	* GNUmakefile.in (dist): output is more beautyful now
+
+	* cf_gcd.cc (gcd_poly): call to sparsemod() added
+
+	* cf_ops.cc (resultant): assertion added
+	(resultant): new variable flipFactor
+	(resultant): handling of trivial cases fixed
+	(resultant): some other minor bug fixes
+
+	* cf_ops.cc (resultant): doc fix
+
+	* README: doc fix
+
+	* NEWS: doc fix
+
+	* GNUmakefile.in (uninstallgftables): brute force ('rm -rf')
+	  replaced by a safer variant
+
+Thu Jul 17 11:05:04 1997  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* sm_util.cc: doc fix
+	(interpol): doc fix
+
+	* sm_util.h (REArray): bug fix
+
+	* sm_sparsemod.cc: new file
+
+	* GNUmakefile.in (basefactoryincl): files sm_util.h and
+	  sm_sparsemod.h added
+	  (basefactorysrc): files sm_util.cc and sm_sparsemod.cc added
+
+	* NEWS: new file
+
+Wed Jul 16 11:35:06 1997  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* .cvsignore (config.cache): new entry
+
+	* canonicalform.cc (CanonicalForm::ilog2): new method
+	* canonicalform.h (class CanonicalForm): new declaration of ilog2
+	(ilog2): new function
+	* int_cf.cc (InternalCF::ilog2): new method
+	* int_cf.h (class InternalCF): new declaration of ilog2
+	* int_int.cc (InternalInteger::ilog2): new method
+	* int_int.h (class InternalInteger): new declaration of ilog2
+	* fac_univar.cc (norm, dnorm): function dnorm replaced by norm
+	(kBound): uses ilog2() and norm() now
+
+Tue Jul 15 14:47:53 1997  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* sm_util.h (REArray): new typedef.  All references to
+	  Array<REvaluation> changed to REArray.
+
+	* sm_sparsemod.h: new file
+
+Mon Jul 14 10:00:59 1997  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* sm_util.h: doc fix
+
+	* sm_util.h (dinterpol): bug fix of declaration
+
+	* sm_util.cc: doc fix
+
+	* sm_util.cc: new file
+
+	* sm_util.h: new file
+
+	* int_cf.h (OBJDEL): spurious macro OBJDEL removed
+
+	* README: new file
+	* GNUmakefile.in (distfiles): README added to distribution
+
+	* canonicalform.cc (initCanonicalForm): initialization of
+	  SW_USE_SPARSEMOD added
+
+	* canonicalform.cc (CanonicalForm::degree( Variable )): doc fix
+
+	* configure.in: doc fix
+
+	* configure.in (libmem, headerfactory, factoryconf): output
+	  variables removed
+
+	* configure.in (templatedir): initialization fixed
+
+Fri Jul 11 09:48:26 1997  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* canonicalform.cc (CanonicalForm::degree): doc fix
+
+	* GNUmakefile.in: dependencies checked
+
+	* GNUmakefile.in: doc fix
+
+	* GNUmakefile.in (.PHONY): phony targets updated
+
+	* GNUmakefile.in (clean): core and *~ will not be removed any
+	  longer
+
+	* GNUmakefile.in (depend): dependencies config.h and factoryconf.h
+	  removed
+
+	* GNUmakefile.in (dist): 'chmod 777' removed
+
+	* GNUmakefile.in (gengftables): dependency on 'all' replaced by
+	  dependency on $(libfactory) and libcfmem.a
+
+	* GNUmakefile.in (gengftables.o): dependency cf_util.h removed
+	(gengftables.o): dependencies factoryconf.h and config.h added
+
+	* GNUmakefile.in (installcf, installgftables): bug fix
+	(uninstallcf): bug fix
+
+	* GNUmakefile.in (libmem, headerfactory, factoryconf): variables
+	  removed.  All references changed (to 'libcfmem.a', 'factory.h',
+ 	  and 'factoryconf.h', resp.).
+
+	* GNUmakefile.in (realmaintainer-clean): target removed
+
+	* GNUmakefile.in (templatesrc, templateincl): file
+	  ftmpl_functions.h moved from $(templateincl) to $(templatesrc)
+
+	* GNUmakefile.in (TESTLDFLAGS): flag '-L.' moved to target
+	  gengftables
+	(gengftables): '-L.' moved from $(TESTLDFLAGS) to command
+
+	* GNUmakefile.in (TESTCXXFLAGS): new variable
+	(gengftables.o): references to $(LIBCXXFLAGS) replaced by
+	  references to $(TESTCXXFLAGS)
+
+Tue Jul  1 14:26:29 1997  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* GNUmakefile.in (dist): use ln instead of cp to build
+	  distribution
+
+	* canonicalform.cc (initCanonicalForm, mmInit): initialize memory
+	  managment if compiled with Singular.  New declaration of
+	  mmInit().
+
+	* cf_random.cc (RandomGenerator): definitions of 'const long int'
+	  in class for mac removed.  Instead, they are initialized in the
+ 	  constructor.
+
+	* cf_random.h (factoryrandom, factoryseed): declarations marked as
+	  public
+
+Mon Jun 30 15:38:08 1997  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* GNUmakefile.in (LIBCFLAGS, LIBCXXFLAGS, TMPLCXXFLAGS): option
+	  -Wall replaced by references to $(WARNFLAGS)
+	  (WARNFLAGS): new variable
+
+	* imm.h (MINIMMEDIATELL, MAXIMMEDIATELL): initialization for mac
+	  added which does not like a 'LL' suffix
+
+	* templates/ftmpl_matrix.cc: include paths for mac added
+	* templates/ftmpl_list.cc: include paths for mac added
+	* templates/ftmpl_factor.cc: include paths for mac added
+	* templates/ftmpl_array.cc: include paths for mac added
+	* factory.template: include paths for mac added
+	* canonicalform.h: include paths for mac added
+	* ftmpl_inst.cc: include paths for mac added
+	* cf_gcd.cc: include paths for mac added
+	* cf_map.cc: include paths for mac added
+	* cf_map.h: include paths for mac added
+	* fac_ezgcd.cc: include paths for mac added
+
+	* configure: checked into RCS
+	* readcf.cc: checked into RCS
+
+Fri Jun 27 10:33:29 1997  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* bin/makeheader: checked into RCS
+	* bin/install-sh: checked into RCS
+	* bin/mkinstalldirs: checked into RCS
+
+Thu Jun 26 16:06:39 1997  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* GNUmakefile.in: doc fix
+
+Wed Jun 25 10:02:51 1997  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* configure.in (enable_gmp): bug fix
+	(CPPFLAGS, LDFLAGS): bug fix
+
+Tue Jun 24 11:15:25 1997  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* configure.in (with_builtingmp): command line option
+	  --with-builtingmp removed.  All references to with_builtingmp
+ 	  and some additional code to deal with the command line options
+ 	  --with-gmp and --with-builtin-gmp removed, too.
+
+	* configure.in (enable_assertions): disabled by default
+
+	* configure.in (enable_gmp): with_gmp and with_builtin_gmp are set
+	  to '$(includedir)' if command line option --enable-gmp is given
+
+	* configure.in: fixes in configure's messages
+
+	* configure.in: doc fix
+
+Mon Jun 23 12:44:50 1997  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* config.h.in: doc fix
+
+	* factory.template: doc fix
+
+	* factoryconf.template: doc fix
+
+Fri Jun 20 12:09:00 1997  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* templates/: all files prefixed with 'ftmpl_'.  All #include
+	  statements changed.
+	* GNUmakefile.in (templatesrc, templateincl): all files prefixed
+	  with 'ftmpl_'
+
+	* ftmpl_inst.cc, tmpl_inst.cc: tmpl_inst.cc renamed to
+	  ftmpl_inst.cc
+	* GNUmakefile.in: all references to tmpl_inst replaced by
+	  references to ftmpl_inst
+
+Thu Jun 19 14:33:17 1997  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* config.h.in: doc fix
+
+	* factoryconf.template: doc fix
+
+	* headers of almost all source files fixed
+
+Thu Jun 12 13:12:49 1997  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* cf_globals.cc: doc fix
+
+Fri Jun  6 09:38:05 1997  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* configure.in: some stupid warnings removed if "dangerous"
+	  combinations of with's/enable's are specified on commandline.
+ 	  Some other fixes in configure's messages.
+
+	* configure.in (enable_memdebug): code removed which sets
+	  enable_memdebug to 'normal' since this is really never tested
+
+	* configure.in (with_gmp, with_builtingmp): new command line
+	  options.  Rest of configure.in adapted to new scheme of
+ 	  specifying where gmp lives.
+
+	* configure.in: doc fix
+
+	* GNUmakefile.in (distsrc, clean): gengftables added to
+	  distribution
+	  (distfiles): ChangeLog added to distribution
+
+Thu Jun  5 15:03:48 1997  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+	* configure.in (enable_debugoutput, enable_timing): dependency on
+	  with_Singular removed so '--with-Singular --enable-debugoutput'
+	  and '--with-Singular --enable-timing' are possible
+
+	* GNUmakefile.in (gengftables.o): check added which makes make
+	  complain if factory was not configured in the right way
+
+	* configure.in: checks on sizeof(int) == sizeof(void *) == 4
+	  removed
+
+	* debug.h: dependency on #define SING_NDEBUG removed
+
+	* factoryconf.template: doc fix
+
+	* config.h.in: added to distribution as source file.  config.h.in
+	  is not created from acconfig.h any longer.
+	* acconfig.h: removed from distribution
+	* GNUmakefile.in: ($(srcdir)/config.h.in, $(srcdir)/stamp-h.in,
+ 	  realmaintainerclean, dist, distfiles): changed to reflect the
+	  changes described above
+
+	* config.h.in (INCL_CONFIG_H): new #define to prevent multiple
+	  inclusion of config.h
+
+	* GNUmakefile.in ($(srcdir)/configure): make will not complain
+	  about a missing autoconf any longer
+
+	* canonicalform.cc (operator>>): returns 0 again if #define
+	  SINGULAR and #define NOSTREAMIO are switched on
+
+Before Mon Jun  4 1997 Jens Schmidt <schmidt at mathematik.uni-kl.de>
+
+	This is a list of most of the changes I made after I took the
+	responsibility for factory development and before I started to
+	update the ChangeLog regularily.  It is unlikely to be complete.
+
+	Besides minor changes at "source code level" (bug fixes, new
+ 	features) which are not really visible to the user in general
+ 	there are quite a lot of changes at "organization level" (aka
+ 	preprocessor level) and at "distribution level" (configure,
+	Makefile).
+
+
+	First, the changes at distribution level:
+
+	* bin: some useful/necessary scripts added to distribution
+	* install-sh: moved to bin
+
+	* ChangeLog: added to distribution
+
+	* configure.in: totally rewritten
+
+	* config.h.in, conf.h.in: conf.h.in replaced by a totally
+	  rewritten config.h.in.  Furthermore, config.h is now explicitly
+ 	  included in allmost every source file of the distribution.
+	* factoryconf.template: new file. factoyconf.h is included instead
+	  of config.h in all source files which are not translated but
+ 	  installed (e.g. templates).
+
+	* factory.template, factory.h: factory.h replaced by
+	  factory.template since makeheader is now included in
+	  the distribution
+	* factory.template: rewritten to new makeheader syntax
+
+	* factory.template, singfactory.h: Singular stuff moved from
+	  singfactory.h to factory.template.  Wrapped by #ifdef
+	  SINGULAR.
+	* singfactory.h: removed from distribution
+
+	* gengftables.cc: code for generating gftables added to
+	  distribution
+
+	* GNUmakefile.in, Makefile.in: Makefile.in replaced by a totally
+	  rewritten GNUmakefile.in
+
+	* INSTALL: removed from distribution since not up to date
+
+	* memman.h, mmalloc.c, mmallocs.c, mmheap.c, mmprivate.h,
+	  mmutil.c, mmallocb.c, mmblock.c, mminit.c, mmspec.c: new memory
+	  manager added to distribution
+
+	* mpext.cc, mpext.h, mpfactory.h: removed from distribution.  No
+	  more MP support.
+	* config.h.in (MULTIPROTOCOL): #define MULTIPROTOCOL removed
+	* int_int.h (class InternalInteger): declarations dependent on
+	  #define MULTIPROTOCOL removed
+	* int_rat.h (class InternalRational): declarations dependent on
+	  #define MULTIPROTOCOL removed
+
+	* readcf.cc: added to distribution since not all users have
+	  bison available
+
+
+	Now for the changes at organization level:
+	If we refer to the "DEBOUT macros", the "ASSERT macros", or the
+	"TIMING macros" we mean one (or more) of the macros defined in
+	debug.h, cf_assert.h, and timing.h, resp.
+
+	* cf_assert.h (NOASSERT, SING_NDEBUG): #define SING_NDEBUG to switch off
+	  assertions replaced by #define NOASSERT.  For sake of backward
+	  compatibility SING_NDEBUG works, too.
+
+	* cf_assert.h (DEBINCLEVEL, DEBDECLEVEL, DEBOUTSL, DEBOUT, DEBOUTLN):
+	  DEBOUT macros moved to debug.h
+	* assert.cc: renamed to debug.cc
+	* debug.h, debug.cc: new files.  DEBOUT macros moved from
+	  cf_assert.h/assert.cc to debug.h/debug.cc.  All source files which
+ 	  need these macros include debug.h.
+
+	* cf_assert.h (PVIRT_VOID, PVIRT_INTCF, PVIRT_BOOL, PVIRT_INT,
+	  PVIRT_CHARCC): PVIRT_*-macros moved from int_cf.h to cf_assert.h
+	* int_cf.h (PVIRT_VOID, PVIRT_INTCF, PVIRT_BOOL, PVIRT_INT,
+	  PVIRT_CHARCC): PVIRT_*-macros moved to cf_assert.h
+
+	* cf_assert.h (__ASSERT, __STICKYASSERT): the preprocessor instead of
+ 	  fprintf() pastes the message into the format string now
+
+	* cf_assert.h (__ASSERT1, ASSERT1, STICKYASSERT1): new macros
+
+	* cf_assert.h (__WARN, WARN, STICKYWARN): new macros
+
+	* canonicalform.cc (operator>>): dependency on #define SINGULAR
+	  removed
+
+	* cf_defs.h (INCL_CF_DEFS_H, incl_cf_defs_H): #define
+	  incl_cf_defs_H renamed to #define INCL_CF_DEFS_H so
+	  cf_defs.h is included only once
+
+	* cf_factor.cc (factorize): dependency on #define MULTIFACTOR
+	  removed
+
+	* cf_factory.cc (CFFactory::basic( int, int )): error message
+	  changed to call of ASSERT macros
+	* fac_util.cc: (crossprod): error message changed to call of
+	  ASSERT macros
+	* int_cf.cc: several error messages changed to calls of ASSERT
+	  macros
+	* int_cf.h (InternalCF::InternalCF( InternalCF& )): error message
+	  changed to call of ASSERT macros
+	* int_poly.cc (InternalPoly::InternalPoly( InternalPoly& )): error
+	  message changed to call of ASSERT macros
+	* templates/array.cc (Array<T>::operator[], Array<T>::operator+=):
+	  error messages changed to calls of ASSERT macros
+	* templates/list.cc (List<T>::getFirst, List<T>::getLast,
+	  ListIterator<T>::getItem): error messages changed to calls of
+	  ASSERT macros
+
+	* cf_gcd.cc: debug output changed to calls of DEBOUT macros
+	* cf_linsys.cc: debug output rewritten and changed to calls of
+	  DEBOUT macros
+	* fac_berlekamp.cc (QPrintFF, QPrintGF): definition and calls of
+	  QPrintFF(), QPrintGF() wrapped by #ifdef DEBUGOUTPUT
+	* fac_univar.cc: debug output rewritten
+	  (hprint): calls to hprint() wrapped by calls to #define
+ 	  DEBOUTHPRINT, which definition depends on #define DEBUGOUTPUT
+	  (instead of SING_NDEBUG, as before).  All callers changed.
+
+	* cf_linsys.cc: superfluous #define TIMING removed
+	* fac_distrib.cc: superfluous #undef DEBUGOUTPUT removed
+	* fac_ezgcd.cc: some superfluous #defines (DEBUGOUTPUT, TIMING)
+	  and #includes removed
+	* fac_multihensel.cc: some superfluous #defines (DEBUGOUTPUT, TIMING)
+	  removed
+	* fac_multivar.cc: some superfluous #defines (DEBUGOUTPUT, TIMING)
+	  removed
+	* fac_univar.cc: some superfluous #defines (DEBUGOUTPUT, TIMING)
+	  and #includes removed
+
+	* config.h.in (GFTABLEDIR): new #define
+	* gfops.cc (gf_get_table): uses #define GFTABLEDIR to get path
+	  to the GF(q) tables
+
+	* config.h.in (MDEBUG, NOASSERT, TIMING, DEBUGOUTPUT): new
+	  #defines
+
+	* config.h.in (NOSTREAMIO): new #define NOSTREAMIO to switch off
+	  stream IO.  Operators <<, >>, and related stuff wrapped by
+ 	  #ifndef NOSTREAMIO.
+
+	* debug.cc (deb_level, level_msg, deb_inc_level):
+	  deb_inc_level()'s output made more pretty at time of first call
+
+	* debug.h (DEBOUT, DEBOUTLN): slightly modified so they print
+	  "objects" instead of only one "msg" and one "object".  All
+ 	  callers changed.
+
+	* debug.h (DEBUGOUTPUT): #define DEBUGOUTPUT is switched off now
+	  if #define SING_NDEBUG is switched on
+
+	* fac_univar.cc (ZFactorizeUnivariate): timing stuff changed to
+	  calls of TIMING macros
+
+	* gmpext.h: references to #define INCL_GCDEXT_H replaced by
+	  references to #define INCL_GMPEXT_H
+
+	* initgmp.cc (initializeGMP): dependency on #define SINGULAR
+	  removed
+
+	* mmallocb.c (MM_TEST, TEST): references to #define TEST
+	  replaced by references to #define MM_TEST
+
+	* readcf.h: '#include <stdio.h>' replaced by '#include <iostream.h>'
+
+	* readcf.y: dependency on #define COMEAU removed
+
+	* templates/matrix.cc (ASSERT): definition of ASSERT macros
+	  replaced by inclusion of factoryconf.h
+
+	* timing.h (HZ): new #define to calculate ticks per second in a
+	  more portable way.  All references changed.
+
+	* timing.h (TIMING_DEFINE_PRINT, TIMING_END_AND_PRINT): stream IO
+	  changed to std IO
+
+	* timing.h (TIMING_END_AND_PRINT): new macro
+
+
+	Last not least, changes at source code level:
+
+	* canonicalform.cc (mapinto): fixed mapping from int to GF(q)
+
+	* cf_factor.cc (sqrFree( CanonicalForm, boolean )): new
+	  function which sorts output if desired
+	* cf_factor.cc (sqrFree( CanonicalForm )): changed to call new
+	  sqrFree()
+	* canonicalform.h, cf_factor.h (sqrFree( CanonicalForm, boolean )):
+	  new declaration
+	* fac_sqrfree.cc (compareFactors, sortCFFList): new functions used
+	  by new sqrFree()
+	* fac_sqrfee.h (sortCFFList): new declaration
+
+	* cf_defs.h (SW_USE_SPARSEMOD): new switch
+
+	* cf_globals.cc (factoryVersion): new external
+	* cf_globals.h (factoryVersion): new declaration
+	* config.h.in (FACTORYVERSION): new #define
+	* factory.template: '#include cf_globals.h' added because of
+	  version string
+
+	* cf_linsys.cc (linearSystemSolve, determinant, determinant2):
+	  typedef int_ptr added
+	  (linearSystemSolve, determinant, determinant2): 'new (int*)[..]'
+	  replaced by 'new int_ptr[..]'
+	* templates/matrix.h (Matrix<T>::T_ptr): new typedef
+	* templates/matrix.cc (Matrix<T>::Matrix( int, int ),
+	  Matrix<T>::Matrix( Matrix<T> ), Matrix<T>::operator=): 'new (T*)[..]'
+	  replaced by 'new T_ptr[..]'
+
+	* cf_iter.h: superfluous '#include <iostream.h>' removed
+	* cf_factor.h: superfluous '#include <iostream.h>' removed
+	* cf_reval.h: superfluous '#include <iostream.h>' removed
+	* memutil.c: superfluous '#include <stdio.h>' removed
+	* mmalloc.c: superfluous '#include <stdio.h>' removed
+
+	* cf_random.cc (RandomGenerator): new class
+	  (RanGen): new static
+	  (factoryrandom, factoryseed): calls to stdlib random generator
+	  replaced by methods of class RandomGenerator
+
+	* cf_switches.h (RATIONAL): superfluous #define RATIONAL removed
+	* int_int.cc (IntInt): superfluous #define IntInt removed
+	* int_pp.cc (IntPP): superfluous #define IntPP removed
+
+  	* fac_univar.cc (initHG, ZFactorizeUnivariate): STICKYWARNings
+	  added because of some strange errors which occur in these
+ 	  functions
+
+	* fac_univar.cc (kBound): cast to double added in calculation of
+	  the bound
+	  (UnivariateQuadraticLift): cast to double added in calculation
+	  of no_iter
+
+	* fac_univar.cc (max_fp_fac, MAX_FP_FAC): '#define MAX_FP_FAC'
+	  replaced by 'const int max_fp_fac'.  All references changed.
+
+	* fac_univar.cc (ZFactorizeUnivariate): superfluous declaration of
+	  'CFFList G' removed.  Some trivial structural changes.  Test on
+ 	  'D != 0' (before deleting D) removed.
+
+	* gfops.h (gf_gf2ff, gf_isff): declarations marked as public for
+	  Singular
+	* factory.template: '#include "gfops.h"' added
+
+	* gfops.cc (gf_get_table): gf_table[gf_q] is guaranteed to be 0
+
+	* gfops.cc (gf_get_table): rewritten.  Major changes: copies
+	  Singulars tables if these are present instead of reading from
+	  disk.  Uses standard IO instead of stream IO to read the tables.
+	* singext.h (nfCharQ, nfM1, nfMinPoly, nfPlus1Table): declarations
+	  of Singular objects added to copy Singulars GF(q) tables
+
+	* gfops.cc (gf_get_table): length of temporary buffer replaced by
+	  'const int gf_maxbuffer'
+
+	* gfops.cc (gf_isff): rewritten
+
+	* gfops.cc (gf_maxtable, MAXTABLE): '#define MAXTABLE' replaced by
+	  'const int gf_maxtable'.  All references changed.
+	* gfops.cc (gf_valid_combination): 'int m' replaced by references
+	  to gf_maxtable
+
+	* gfops.cc (intVec2CF): new function
+
+	* gfops.h (gf_mipo): new declaration
+
+	* imm.h (class InternalCF): superfluous declaration of class
+	  InternalCF removed
+
+	* imm.h (imm_intval): convertion from GF(q) to integer added
+
+	* int_int.cc (InternalInteger::genOne): Ruedigers last fryday
+	  afternoon fix
+
+	* variable.cc (Variable::name): casts to int added
+
+	* variable.cc (Variable::Variable( char ),
+	  Variable::Variable( int, char ), rootOf): 'delete ...' changed
+	  to 'delete [] ...' where necessary
diff --git a/factory/DegreePattern.cc b/factory/DegreePattern.cc
new file mode 100644
index 0000000..34c565e
--- /dev/null
+++ b/factory/DegreePattern.cc
@@ -0,0 +1,148 @@
+/*****************************************************************************\
+ * Computer Algebra System SINGULAR
+\*****************************************************************************/
+/** @file DegreePattern.cc
+ *
+ * This file provides functions for manipulating DegreePatterns
+ *
+ * @author Martin Lee
+ *
+ **/
+/*****************************************************************************/
+
+
+#include "config.h"
+
+
+#include "DegreePattern.h"
+#include "cf_iter.h"
+#include "templates/ftmpl_functions.h"
+#include "gfops.h"
+#include "cf_factory.h"
+
+
+DegreePattern::DegreePattern (const CFList& l)
+{
+  m_data = NULL;
+
+  if (l.length() == 0)
+    m_data = new Pattern();
+  else
+  {
+
+  Variable x= Variable (1);
+  int p= getCharacteristic();
+  int d= 0;
+  char cGFName= 'Z';
+  if (CFFactory::gettype() == GaloisFieldDomain)
+  {
+    d= getGFDegree();
+    cGFName= gf_name;
+  }
+  setCharacteristic(0);
+  CanonicalForm buf= 1;
+  CFListIterator k= l;
+  for (int i= 0; i < l.length(); i++, k++)
+    buf *= (power (x, degree (k.getItem(), x)) + 1);
+
+  int j= 0;
+  for (CFIterator i= buf; i.hasTerms(); i++, j++)
+    ;
+
+  ASSERT ( j > 1, "j > 1 expected" );
+
+  m_data = new Pattern( j - 1 );
+
+  int i= 0;
+  for (CFIterator m = buf; i < getLength(); i++, m++)
+    (*this) [i]= m.exp();
+
+  if (d > 1)
+    setCharacteristic (p, d, cGFName);
+  else
+    setCharacteristic (p);
+  }
+}
+
+
+void DegreePattern::intersect (const DegreePattern& degPat)
+{
+  if (degPat.getLength() < getLength())
+  {
+    DegreePattern bufDeg= *this;
+    *this= degPat;
+    return (*this).intersect (bufDeg);
+  }
+
+  int count= 0;
+  int length= tmin (getLength(), degPat.getLength());
+  int* buf= new int [length];
+  for (int i= 0; i < length; i++)
+  {
+    if (degPat.find ((*this)[i]))
+    {
+      buf[i]= (*this)[i];
+      count++;
+    }
+    else
+      buf[i]= -1;
+  }
+  ASSERT ( count > 0, "count > 0 expected" );
+
+  init (count);
+  count= 0;
+  for (int i= 0; i < length; i++)
+  {
+    if (buf[i] != -1)
+    {
+      (*this) [count]= buf[i];
+      count++;
+    }
+  }
+  delete[] buf;
+}
+
+void DegreePattern::refine ()
+{
+  if (getLength() <= 1)
+    return;
+  int count= 0;
+  int* buf= new int [getLength()];
+  int d= (*this) [0];
+  int pos;
+  for (int i= 0; i < getLength(); i++)
+    buf[i]= -1;
+  for (int i= 1; i < getLength(); i++)
+  {
+    pos= (*this).find (d - (*this)[i]);
+    if (pos)
+    {
+      buf[i]= (*this)[i];
+      count++;
+    }
+  }
+  buf[0]= d;
+  count++;
+  if (count == getLength())
+  {
+    delete [] buf;
+    return;
+  }
+  int length= getLength();
+
+  ASSERT ( count > 0, "count > 0 expected" );
+  init (count);
+  count= 0;
+  for (int i= 0; i < length; i++)
+  {
+    if (buf[i] != -1)
+    {
+      (*this)[count]= buf[i];
+      count++;
+    }
+  }
+
+  delete[] buf;
+  return;
+}
+
diff --git a/factory/DegreePattern.h b/factory/DegreePattern.h
new file mode 100644
index 0000000..c3df650
--- /dev/null
+++ b/factory/DegreePattern.h
@@ -0,0 +1,180 @@
+/*****************************************************************************\
+ * Computer Algebra System SINGULAR
+\*****************************************************************************/
+/** @file DegreePattern.h
+ *
+ * This file provides a class to handle degree patterns.
+ *
+ * @author Martin Lee
+ *
+ **/
+/*****************************************************************************/
+#ifndef DEGREE_PATTERN_H
+#define DEGREE_PATTERN_H
+
+// #include "config.h"
+
+#include "cf_assert.h"
+
+#include "canonicalform.h"
+#include "cf_iter.h"
+#include "templates/ftmpl_functions.h"
+#include "gfops.h"
+
+/** @class DegreePattern DegreePattern.h "factory/DegreePattern.h"
+ *
+ * DegreePattern provides a functionality to create, intersect and refine
+ * degree patterns.
+ *
+ *
+ */
+class DegreePattern
+{
+private:
+  struct Pattern
+  {
+    int  m_refCounter; ///< reference counter
+    int  m_length;     ///< length of m_pattern
+    int* m_pattern;    ///< some array containing the degree pattern
+
+    /// construct a Pattern from an int
+    Pattern(int n): m_refCounter(1), m_length(n), m_pattern( new int[n]) {};
+    /// default constructor
+    Pattern(): m_refCounter(1), m_length(0), m_pattern(NULL) {};
+
+  }* m_data;
+
+  /// clear m_data
+  void release()
+  {
+    ASSERT ( m_data != NULL, "non-null pointer expected");
+    ASSERT ( m_data->m_refCounter == 0, "ref count of 0 expected");
+    if( m_data->m_pattern != NULL )
+      delete[] m_data->m_pattern;
+    m_data->m_pattern = NULL;
+
+    delete m_data;
+    m_data = NULL;
+  }
+  /// initialise a DegreePattern
+  void init( int n )
+  {
+    ASSERT ( m_data != NULL, "non-null pointer expected" );
+    ASSERT( m_data->m_refCounter > 0, "ref count > 0 expected" );
+
+    if( (--m_data->m_refCounter) < 1 )
+      release();
+
+    m_data = new Pattern(n);
+  }
+
+  /// getter
+  ///
+  /// @return @a getPattern returns a degree pattern
+  inline int* getPattern() const
+  {
+    ASSERT( m_data != NULL, "non-null pointer expected" );
+    ASSERT( m_data->m_pattern != NULL, "non-null pointer expected" );
+    return m_data->m_pattern;
+  }
+
+
+public:
+  /// getter
+  ///
+  /// @return @a getLength returns the length of the degree pattern
+  inline int getLength() const
+  {
+    ASSERT( m_data != NULL, "non-null pointer expected" );
+    return m_data->m_length;
+  }
+
+  /// operator []
+  ///
+  /// @return @a operator[] returns the element at @a index
+  inline int operator[] (const int index ///< [in] some int >= 0, < getLength()
+                        ) const
+  {
+    ASSERT( m_data != NULL, "non-null pointer expected" );
+    ASSERT( index >= 0 && index < getLength(), "bad index" );
+    ASSERT( getPattern() != NULL, "non-null pointer expected" );
+    return getPattern()[index];
+  }
+
+  /// operator []
+  ///
+  /// @return @a operator[] sets the element at @a index
+  inline int& operator[] (const int index ///< [in] some int >= 0, < getLength()
+                         )
+  {
+    ASSERT( m_data != NULL, "non-null pointer expected" );
+    ASSERT( index >= 0 && index < getLength(), "bad index" );
+    ASSERT( getPattern() != NULL, "non-null pointer expected" );
+    return getPattern()[index];
+  }
+
+  /// default constructor
+  DegreePattern(): m_data( new Pattern() ){}
+
+  /// copy constructor
+  DegreePattern (const DegreePattern& degPat ///< [in] some degree pattern
+                ): m_data( degPat.m_data )
+  {
+    ASSERT( degPat.m_data != NULL, "non-null pointer expected"  );
+    m_data->m_refCounter++;
+  };
+
+  /// construct a degree pattern from a list of (univariate) polys
+  DegreePattern (const CFList& l ///< [in] some list of (univariate) polys
+                );
+
+  /// assignment
+  DegreePattern& operator= (const DegreePattern& degPat ///< [in] some degree
+                                                        ///< pattern
+                           )
+  {
+    ASSERT( m_data != NULL, "non-null pointer expected"  );
+    ASSERT( degPat.m_data != NULL, "non-null pointer expected" );
+    if( m_data != degPat.m_data )
+    {
+      m_data = degPat.m_data;
+      m_data->m_refCounter++;
+    }
+
+    return *this;
+  }
+
+  /// destructor
+  ~DegreePattern ()
+  {
+    ASSERT( m_data !=  NULL, "non-null pointer expected"  );
+    if( (--m_data->m_refCounter) < 1 )
+      release();
+  }
+
+  /// find an element @a x
+  ///
+  /// @return @a find returns the index + 1 of @a x, if @a x is an element of
+  ///         the degree pattern, 0 otherwise
+  int find (const int x ///< [in] some int
+           ) const
+  {
+    if (getLength() == 0) return 0;
+    for (int i= 0; i < getLength(); i++)
+      if ((*this)[i] == x) return i + 1;
+    return 0;
+  };
+
+  /// intersect two degree patterns
+  void intersect (const DegreePattern& degPat ///< [in] some degree pattern
+                 );
+  /// Refine a degree pattern. Assumes that (*this)[0]:= @a d is the degree
+  /// of the poly to be factored. Now for every other entry @a a there should be
+  /// some entry @a b such that @a a+b= d. Elements which do not satisfy this
+  /// relation are removed.
+  void refine ();
+};
+
+#endif
+/* DEGREE_PATTERN_H */
+
diff --git a/factory/ExtensionInfo.cc b/factory/ExtensionInfo.cc
new file mode 100644
index 0000000..1b553b9
--- /dev/null
+++ b/factory/ExtensionInfo.cc
@@ -0,0 +1,90 @@
+/*****************************************************************************\
+ * Computer Algebra System SINGULAR
+\*****************************************************************************/
+/** @file ExtensionInfo.cc
+ *
+ * This file provides member functions for ExtensionInfo
+ *
+ * @author Martin Lee
+ *
+ **/
+/*****************************************************************************/
+
+
+#include "config.h"
+
+
+#include "ExtensionInfo.h"
+
+ExtensionInfo::ExtensionInfo (const bool extension)
+{
+  m_alpha= Variable (1);
+  m_beta= Variable (1);
+  m_gamma= CanonicalForm ();
+  m_delta= CanonicalForm ();
+  m_GFDegree= 1;
+  m_GFName= 'Z';
+  m_extension= extension;
+}
+
+ExtensionInfo::ExtensionInfo (const Variable& alpha, const Variable& beta,
+                              const CanonicalForm& gamma, const CanonicalForm&
+                              delta, const int nGFDegree, const char cGFName,
+                              const bool extension)
+{
+  m_alpha= alpha;
+  m_beta= beta;
+  m_gamma= gamma;
+  m_delta= delta;
+  m_GFDegree= nGFDegree;
+  m_GFName= cGFName;
+  m_extension= extension;
+}
+
+ExtensionInfo::ExtensionInfo (const Variable& alpha, const Variable& beta,
+                              const CanonicalForm& gamma, const CanonicalForm&
+                              delta)
+{
+  m_alpha= alpha;
+  m_beta= beta;
+  m_gamma= gamma;
+  m_delta= delta;
+  m_GFDegree= 0;
+  m_GFName= 'Z';
+  m_extension= true;
+}
+
+ExtensionInfo::ExtensionInfo (const Variable& alpha, const bool extension)
+{
+  m_alpha= alpha;
+  m_beta= Variable (1);
+  m_gamma= CanonicalForm ();
+  m_delta= CanonicalForm ();
+  m_GFDegree= 0;
+  m_GFName= 'Z';
+  m_extension= extension;
+}
+
+ExtensionInfo::ExtensionInfo (const Variable& alpha)
+{
+  m_alpha= alpha;
+  m_beta=  Variable (1);
+  m_gamma= CanonicalForm ();
+  m_delta= CanonicalForm ();
+  m_GFDegree= 1;
+  m_GFName= 'Z';
+  m_extension= true;
+}
+
+ExtensionInfo::ExtensionInfo (const int nGFDegree, const char cGFName, const
+                              bool extension)
+{
+  m_alpha= Variable (1);
+  m_beta= Variable (1);
+  m_gamma= CanonicalForm ();
+  m_delta= CanonicalForm ();
+  m_GFDegree= nGFDegree;
+  m_GFName= cGFName;
+  m_extension= extension;
+}
+
diff --git a/factory/ExtensionInfo.h b/factory/ExtensionInfo.h
new file mode 100644
index 0000000..089fb80
--- /dev/null
+++ b/factory/ExtensionInfo.h
@@ -0,0 +1,161 @@
+/*****************************************************************************\
+ * Computer Algebra System SINGULAR
+\*****************************************************************************/
+/** @file ExtensionInfo.h
+ *
+ * This file provides a class to store information about finite fields and
+ * extensions thereof.
+ *
+ *
+ * @author Martin Lee
+ *
+ **/
+/*****************************************************************************/
+
+#ifndef EXTENSION_INFO_H
+#define EXTENSION_INFO_H
+
+// #include "config.h"
+
+#include "canonicalform.h"
+
+/** @class ExtensionInfo ExtensionInfo.h "factory/ExtensionInfo.h"
+ *  ExtensionInfo contains information about extension.
+ *  If @a m_extension is true we are in an extension of some initial field.
+ *  If the initial field is \f$ F_p \f$ and we pass to \f$ F_p (\alpha) \f$
+ *  then @a m_alpha is an algebraic variable, @a m_beta= Variable(1),
+ *  @a m_gamma= @a m_delta= 1, @a m_GFDegree= 0, @a m_GFName= 'Z'. If we pass
+ *  to some GF (p^k) then @a m_alpha= Variable (1), @a m_beta= Variable(1),
+ *  @a m_gamma= @a m_delta= 1, @a m_GFDegree= 1, @a m_GFName= 'Z'.
+ *  @n If the initial field is \f$ F_p (\epsilon) \f$, then @a m_beta=
+ *  \f$ \epsilon \f$, @a m_alpha an algebraic variable defining an extension of
+ *  \f$ F_p (\epsilon) \f$, @a m_gamma is a primitive element of
+ *  \f$ F_p (\alpha) \f$, @a m_delta is a primitive element of
+ *  \f$ F_p (\beta) \f$, @a m_GFDegree= 0, @a m_GFName= 'Z'.
+ *  @n If the initial field is GF(p^k), then @a m_alpha= Variable (1),
+ *  @a m_beta= Variable (1), @a m_gamma= 1, @a m_delta= 1, @a m_GFDegree()= k,
+ *  @a m_GFName= gf_name of the initial field.
+ *  @n If @a m_extension is false and the current field is \f$ F_p \f$ then
+ *  @a m_alpha= Variable (1), @a m_beta= Variable (1), @a m_gamma= 1,
+ *  @a m_delta= 1, @a m_GFDegree= 1, @a m_GFName= 'Z'.
+ *  @n If the current field is \f$ F_p (\alpha) \f$ then
+ *  @a m_alpha is some algebraic variable, @a m_beta= Variable (1),
+ *  @a m_gamma= 1, @a m_delta= 1, @a m_GFDegree= 0, @a m_GFName= 'Z'.
+ *  @n If the current field is GF then @a m_alpha= Variable (1),
+ *  @a m_beta= Variable (1),  @a m_gamma= 1, @a m_delta= 1,
+ *  @a m_GFDegree= getGFDegree(), @a m_GFName= gf_name.
+ *
+ *  @sa facFqBivar.h, facFqFactorize.h
+ */
+class ExtensionInfo
+{
+private:
+  /// an algebraic variable or Variable (1)
+  Variable m_alpha;
+  /// an algebraic variable or Variable (1)
+  Variable m_beta;
+  /// a primitive element of \f$ F_p (\alpha) \f$ or 1
+  CanonicalForm m_gamma;
+  /// a primitive element of \f$ F_p (\beta) \f$ or 1
+  CanonicalForm m_delta;
+  /// GF degree or 1
+  int m_GFDegree;
+  /// name of GF variable
+  char m_GFName;
+  /// indicates if we are in an extension of some initial field
+  bool m_extension;
+public:
+  /// \f$ F_p \f$ as initial field, if @a extension is true we are in some GF
+  ExtensionInfo (const bool extension  ///< [in] some bool
+                );
+  /// Construct an @a ExtensionInfo
+  ExtensionInfo (const Variable& alpha,      ///< [in] some algebraic variable
+                 const Variable& beta,       ///< [in] some algebraic variable
+                 const CanonicalForm& gamma, ///< [in] some primitive element
+                                             ///< of \f$ F_p (\alpha) \f$
+                 const CanonicalForm& delta, ///< [in] some primitive element
+                                             ///< of \f$ F_p (\beta) \f$
+                 const int nGFDegree,        ///< [in] GFDegree of initial field
+                 const char cGFName,         ///< [in] name of GF variable of
+                                             ///< initial field
+                 const bool extension        ///< [in] some bool
+                );
+  /// \f$ F_p (\beta) \f$ as initial field and switch to an extension given by
+  /// @a alpha, needs primitive elements @a gamma and @a delta for maps
+  /// between \f$ F_p (\alpha) \subset F_p (\beta) \f$
+  ExtensionInfo (const Variable& alpha,      ///< [in] some algebraic variable
+                 const Variable& beta,       ///< [in] some algebraic variable
+                 const CanonicalForm& gamma, ///< [in] some primitive element
+                                             ///< of \f$ F_p (\alpha) \f$
+                 const CanonicalForm& delta  ///< [in] some primitive element
+                                             ///< of \f$ F_p (\beta) \f$
+                );
+  /// \f$ F_p (\alpha) \f$ as initial field, if @a extension is false.
+  /// Else initial field is \f$ F_p \f$
+  ExtensionInfo (const Variable& alpha, ///< [in] some algebraic variable
+                 const bool extension   ///< [in] some bool
+                );
+
+  ExtensionInfo (const Variable& alpha ///< [in] some algebraic variable
+                );
+
+  /// GF as initial field
+  ExtensionInfo (const int nGFDegree,   ///< [in] GF degree of initial field
+                 const char cGFName,    ///< [in] name of GF variable
+                 const bool extension   ///< [in] some bool
+                );
+
+  /// getter
+  ///
+  /// @return @a getAlpha() returns @a m_alpha
+  Variable getAlpha () const
+  {
+    return m_alpha;
+  }
+  /// getter
+  ///
+  /// @return @a getBeta() returns @a m_beta
+  Variable getBeta () const
+  {
+    return m_beta;
+  }
+  /// getter
+  ///
+  /// @return @a getGamma() returns @a m_gamma
+  CanonicalForm getGamma() const
+  {
+    return m_gamma;
+  }
+  /// getter
+  ///
+  /// @return @a getDelta() returns @a m_delta
+  CanonicalForm getDelta() const
+  {
+    return m_delta;
+  }
+  /// getter
+  ///
+  /// @return @a getGFDegree() returns @a m_GFDegree
+  int getGFDegree() const
+  {
+    return m_GFDegree;
+  }
+  /// getter
+  ///
+  /// @return @a getGFName() returns @a m_GFName
+  char getGFName() const
+  {
+    return m_GFName;
+  }
+  /// getter
+  ///
+  /// @return @a isInextension() returns @a m_extension
+  bool isInExtension() const
+  {
+    return m_extension;
+  }
+};
+
+#endif
+/* EXTENSION_INFO_H */
+
diff --git a/factory/FLINTconvert.cc b/factory/FLINTconvert.cc
new file mode 100644
index 0000000..1ab3b2b
--- /dev/null
+++ b/factory/FLINTconvert.cc
@@ -0,0 +1,541 @@
+/*****************************************************************************\
+ * Computer Algebra System SINGULAR
+\*****************************************************************************/
+/** @file FLINTconvert.cc
+ *
+ * This file implements functions for conversion to FLINT (www.flintlib.org)
+ * and back.
+ *
+ * @author Martin Lee
+ *
+ **/
+/*****************************************************************************/
+
+
+
+#include <config.h>
+
+
+#include "canonicalform.h"
+#include "fac_util.h"
+#include "cf_iter.h"
+#include "cf_factory.h"
+#include "gmpext.h"
+#include "singext.h"
+#include "cf_algorithm.h"
+
+#ifdef HAVE_FLINT
+#ifdef HAVE_CSTDIO
+#include <cstdio>
+#else
+#include <stdio.h>
+#endif
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+#ifndef __GMP_BITS_PER_MP_LIMB
+#define __GMP_BITS_PER_MP_LIMB GMP_LIMB_BITS
+#endif
+#include <flint/fmpz.h>
+#include <flint/fmpq.h>
+#include <flint/fmpz_poly.h>
+#include <flint/fmpz_mod_poly.h>
+#include <flint/nmod_poly.h>
+#include <flint/fmpq_poly.h>
+#include <flint/nmod_mat.h>
+#include <flint/fmpz_mat.h>
+#if ( __FLINT_RELEASE >= 20400)
+#include <flint/fq.h>
+#include <flint/fq_poly.h>
+#include <flint/fq_nmod.h>
+#include <flint/fq_nmod_poly.h>
+#include <flint/fq_nmod_mat.h>
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+#include "FLINTconvert.h"
+
+void convertCF2Fmpz (fmpz_t result, const CanonicalForm& f)
+{
+  if (f.isImm())
+    fmpz_set_si (result, f.intval());
+  else
+  {
+    mpz_t gmp_val;
+    f.mpzval(gmp_val);
+    fmpz_set_mpz (result, gmp_val);
+    mpz_clear (gmp_val);
+  }
+}
+
+void convertFacCF2Fmpz_poly_t (fmpz_poly_t result, const CanonicalForm& f)
+{
+  fmpz_poly_init2 (result, degree (f)+1);
+  _fmpz_poly_set_length(result, degree(f)+1);
+  for (CFIterator i= f; i.hasTerms(); i++)
+    convertCF2Fmpz (fmpz_poly_get_coeff_ptr(result, i.exp()), i.coeff());
+}
+
+CanonicalForm convertFmpz2CF (const fmpz_t coefficient)
+{
+  if (fmpz_cmp_si (coefficient, MINIMMEDIATE) >= 0 &&
+      fmpz_cmp_si (coefficient, MAXIMMEDIATE) <= 0)
+  {
+    long coeff= fmpz_get_si (coefficient);
+    return CanonicalForm (coeff);
+  }
+  else
+  {
+    mpz_t gmp_val;
+    mpz_init (gmp_val);
+    fmpz_get_mpz (gmp_val, coefficient);
+    CanonicalForm result= CanonicalForm (CFFactory::basic (gmp_val));
+    return result;
+  }
+}
+
+CanonicalForm
+convertFmpz_poly_t2FacCF (const fmpz_poly_t poly, const Variable& x)
+{
+  CanonicalForm result= 0;
+  fmpz* coeff;
+  for (int i= 0; i < fmpz_poly_length (poly); i++)
+  {
+    coeff= fmpz_poly_get_coeff_ptr (poly, i);
+    if (!fmpz_is_zero (coeff))
+      result += convertFmpz2CF (coeff)*power (x,i);
+  }
+  return result;
+}
+
+void
+convertFacCF2nmod_poly_t (nmod_poly_t result, const CanonicalForm& f)
+{
+  bool save_sym_ff= isOn (SW_SYMMETRIC_FF);
+  if (save_sym_ff) Off (SW_SYMMETRIC_FF);
+  nmod_poly_init2 (result, getCharacteristic(), degree (f)+1);
+  for (CFIterator i= f; i.hasTerms(); i++)
+  {
+    CanonicalForm c= i.coeff();
+    if (!c.isImm()) c=c.mapinto(); //c%= getCharacteristic();
+    if (!c.isImm())
+    {  //This case will never happen if the characteristic is in fact a prime
+       // number, since all coefficients are represented as immediates
+       printf("convertCF2nmod_poly_t: coefficient not immediate!, char=%d\n",
+              getCharacteristic());
+    }
+    else
+      nmod_poly_set_coeff_ui (result, i.exp(), c.intval());
+  }
+  if (save_sym_ff) On (SW_SYMMETRIC_FF);
+}
+
+CanonicalForm
+convertnmod_poly_t2FacCF (const nmod_poly_t poly, const Variable& x)
+{
+  CanonicalForm result= 0;
+  for (int i= 0; i < nmod_poly_length (poly); i++)
+  {
+    ulong coeff= nmod_poly_get_coeff_ui (poly, i);
+    if (coeff != 0)
+      result += CanonicalForm ((long)coeff)*power (x,i);
+  }
+  return result;
+}
+
+void convertCF2Fmpq (fmpq_t result, const CanonicalForm& f)
+{
+  //ASSERT (isOn (SW_RATIONAL), "expected rational");
+  fmpz_t tmp1, tmp2;
+  fmpz_init (tmp1);
+  fmpz_init (tmp2);
+  if (f.isImm ())
+  {
+    fmpz_set_si (tmp1, f.num().intval());
+    fmpz_set_si (tmp2, f.den().intval());
+  }
+  else
+  {
+    mpz_t gmp_val;
+    gmp_numerator (f, gmp_val);
+    fmpz_set_mpz (tmp1, gmp_val);
+    mpz_clear (gmp_val);
+    gmp_denominator (f, gmp_val);
+    fmpz_set_mpz (tmp2, gmp_val);
+    mpz_clear (gmp_val);
+  }
+
+  fmpz_set (fmpq_numref (result), tmp1);
+  fmpz_set (fmpq_denref (result), tmp2);
+  fmpz_clear (tmp1);
+  fmpz_clear (tmp2);
+}
+
+CanonicalForm convertFmpq_t2CF (const fmpq_t q)
+{
+  bool isRat= isOn (SW_RATIONAL);
+  if (!isRat)
+    On (SW_RATIONAL);
+
+  CanonicalForm num, den;
+  mpz_t nnum, nden;
+  mpz_init (nnum);
+  mpz_init (nden);
+  fmpz_get_mpz (nnum, fmpq_numref (q));
+  fmpz_get_mpz (nden, fmpq_denref (q));
+
+  CanonicalForm result;
+  if (mpz_is_imm (nnum) && mpz_is_imm (nden))
+  {
+    num= CanonicalForm (mpz_get_si(nnum));
+    den= CanonicalForm (mpz_get_si(nden));
+    mpz_clear (nnum);
+    mpz_clear (nden);
+    result= num/den;
+    if (!isRat)
+      Off (SW_RATIONAL);
+    return result;
+  }
+  else
+  {
+    result= make_cf (nnum, nden, false);
+    if (!isRat)
+      Off (SW_RATIONAL);
+    return result;
+  }
+}
+
+CanonicalForm
+convertFmpq_poly_t2FacCF (const fmpq_poly_t p, const Variable& x)
+{
+  CanonicalForm result= 0;
+  fmpq_t coeff;
+  long n= p->length;
+  for (long i= 0; i < n; i++)
+  {
+    fmpq_init (coeff);
+    fmpq_poly_get_coeff_fmpq (coeff, p, i);
+    if (fmpq_is_zero (coeff))
+    {
+      fmpq_clear (coeff);
+      continue;
+    }
+    result += convertFmpq_t2CF (coeff)*power (x, i);
+    fmpq_clear (coeff);
+  }
+  return result;
+}
+
+void convertFacCF2Fmpz_array (fmpz* result, const CanonicalForm& f)
+{
+  for (CFIterator i= f; i.hasTerms(); i++)
+    convertCF2Fmpz (&result[i.exp()], i.coeff());
+}
+
+void convertFacCF2Fmpq_poly_t (fmpq_poly_t result, const CanonicalForm& f)
+{
+  bool isRat= isOn (SW_RATIONAL);
+  if (!isRat)
+    On (SW_RATIONAL);
+
+  fmpq_poly_init2 (result, degree (f)+1);
+  _fmpq_poly_set_length (result, degree (f) + 1);
+  CanonicalForm den= bCommonDen (f);
+  convertFacCF2Fmpz_array (fmpq_poly_numref (result), f*den);
+  convertCF2Fmpz (fmpq_poly_denref (result), den);
+
+  if (!isRat)
+    Off (SW_RATIONAL);
+}
+
+CFFList
+convertFLINTnmod_poly_factor2FacCFFList (const nmod_poly_factor_t fac,
+                                          const mp_limb_t leadingCoeff,
+                                          const Variable& x
+                                         )
+{
+  CFFList result;
+  if (leadingCoeff != 1)
+    result.insert (CFFactor (CanonicalForm ((long) leadingCoeff), 1));
+
+  long i;
+
+  for (i = 0; i < fac->num; i++)
+    result.append (CFFactor (convertnmod_poly_t2FacCF (
+                             (nmod_poly_t &)fac->p[i],x),
+                             fac->exp[i]));
+  return result;
+}
+
+#if __FLINT_RELEASE >= 20400
+CFFList
+convertFLINTFq_nmod_poly_factor2FacCFFList (const fq_nmod_poly_factor_t fac,
+                                       const Variable& x, const Variable& alpha,
+                                       const fq_nmod_ctx_t fq_con
+                                         )
+{
+  CFFList result;
+
+  long i;
+
+  for (i = 0; i < fac->num; i++)
+    result.append (CFFactor (convertFq_nmod_poly_t2FacCF (
+                             (fq_nmod_poly_t &)fac->poly[i], x, alpha, fq_con),
+                             fac->exp[i]));
+  return result;
+}
+#endif
+
+void
+convertFacCF2Fmpz_mod_poly_t (fmpz_mod_poly_t result, const CanonicalForm& f,
+                              const fmpz_t p)
+{
+  fmpz_mod_poly_init2 (result, p, degree (f) + 1);
+  fmpz_poly_t buf;
+  convertFacCF2Fmpz_poly_t (buf, f);
+  fmpz_mod_poly_set_fmpz_poly (result, buf);
+  fmpz_poly_clear (buf);
+}
+
+CanonicalForm
+convertFmpz_mod_poly_t2FacCF (const fmpz_mod_poly_t poly, const Variable& x,
+                              const modpk& b)
+{
+  fmpz_poly_t buf;
+  fmpz_poly_init (buf);
+  fmpz_mod_poly_get_fmpz_poly (buf, poly);
+  CanonicalForm result= convertFmpz_poly_t2FacCF (buf, x);
+  fmpz_poly_clear (buf);
+  return b (result);
+}
+
+#if __FLINT_RELEASE >= 20400
+void
+convertFacCF2Fq_nmod_t (fq_nmod_t result, const CanonicalForm& f,
+                        const fq_nmod_ctx_t ctx)
+{
+  bool save_sym_ff= isOn (SW_SYMMETRIC_FF);
+  if (save_sym_ff) Off (SW_SYMMETRIC_FF);
+  for (CFIterator i= f; i.hasTerms(); i++)
+  {
+    CanonicalForm c= i.coeff();
+    if (!c.isImm()) c=c.mapinto(); //c%= getCharacteristic();
+    if (!c.isImm())
+    {  //This case will never happen if the characteristic is in fact a prime
+       // number, since all coefficients are represented as immediates
+       printf("convertFacCF2Fq_nmod_t: coefficient not immediate!, char=%d\n",
+              getCharacteristic());
+    }
+    else
+    {
+      STICKYASSERT (i.exp() <= fq_nmod_ctx_degree(ctx), "convertFacCF2Fq_nmod_t: element is not reduced");
+      nmod_poly_set_coeff_ui (result, i.exp(), c.intval());
+    }
+  }
+  if (save_sym_ff) On (SW_SYMMETRIC_FF);
+}
+
+CanonicalForm
+convertFq_nmod_t2FacCF (const fq_nmod_t poly, const Variable& alpha)
+{
+  return convertnmod_poly_t2FacCF (poly, alpha);
+}
+
+void
+convertFacCF2Fq_t (fq_t result, const CanonicalForm& f, const fq_ctx_t ctx)
+{
+  fmpz_poly_init2 (result, fq_ctx_degree(ctx));
+  ASSERT (degree (f) < fq_ctx_degree (ctx), "input is not reduced");
+  _fmpz_poly_set_length(result, degree(f)+1);
+  for (CFIterator i= f; i.hasTerms(); i++)
+    convertCF2Fmpz (fmpz_poly_get_coeff_ptr(result, i.exp()), i.coeff());
+  _fmpz_vec_scalar_mod_fmpz (result->coeffs, result->coeffs, degree (f) + 1,
+                             &ctx->p);
+  _fmpz_poly_normalise (result);
+}
+
+CanonicalForm
+convertFq_t2FacCF (const fq_t poly, const Variable& alpha)
+{
+  return convertFmpz_poly_t2FacCF (poly, alpha);
+}
+
+void
+convertFacCF2Fq_poly_t (fq_poly_t result, const CanonicalForm& f,
+                        const fq_ctx_t ctx)
+{
+  fq_poly_init2 (result, degree (f)+1, ctx);
+  _fq_poly_set_length (result, degree (f) + 1, ctx);
+  fmpz_poly_t buf;
+  for (CFIterator i= f; i.hasTerms(); i++)
+  {
+    convertFacCF2Fmpz_poly_t (buf, i.coeff());
+    _fmpz_vec_scalar_mod_fmpz (buf->coeffs, buf->coeffs, degree (i.coeff()) + 1,
+                               &ctx->p);
+    _fmpz_poly_normalise (buf);
+    fq_poly_set_coeff (result, i.exp(), buf, ctx);
+    fmpz_poly_clear (buf);
+  }
+}
+
+void
+convertFacCF2Fq_nmod_poly_t (fq_nmod_poly_t result, const CanonicalForm& f,
+                             const fq_nmod_ctx_t ctx)
+{
+  fq_nmod_poly_init2 (result, degree (f)+1, ctx);
+  _fq_nmod_poly_set_length (result, degree (f) + 1, ctx);
+  fq_nmod_t buf;
+  fq_nmod_init2 (buf, ctx);
+  for (CFIterator i= f; i.hasTerms(); i++)
+  {
+    convertFacCF2Fq_nmod_t (buf, i.coeff(), ctx);
+    fq_nmod_poly_set_coeff (result, i.exp(), buf, ctx);
+    fq_nmod_zero (buf, ctx);
+  }
+  fq_nmod_clear (buf, ctx);
+}
+
+CanonicalForm
+convertFq_poly_t2FacCF (const fq_poly_t p, const Variable& x,
+                        const Variable& alpha, const fq_ctx_t ctx)
+{
+  CanonicalForm result= 0;
+  fq_t coeff;
+  long n= fq_poly_length (p, ctx);
+  fq_init2 (coeff, ctx);
+  for (long i= 0; i < n; i++)
+  {
+    fq_poly_get_coeff (coeff, p, i, ctx);
+    if (fq_is_zero (coeff, ctx))
+      continue;
+    result += convertFq_t2FacCF (coeff, alpha)*power (x, i);
+    fq_zero (coeff, ctx);
+  }
+  fq_clear (coeff, ctx);
+
+  return result;
+}
+
+CanonicalForm
+convertFq_nmod_poly_t2FacCF (const fq_nmod_poly_t p, const Variable& x,
+                             const Variable& alpha, const fq_nmod_ctx_t ctx)
+{
+  CanonicalForm result= 0;
+  fq_nmod_t coeff;
+  long n= fq_nmod_poly_length (p, ctx);
+  fq_nmod_init2 (coeff, ctx);
+  for (long i= 0; i < n; i++)
+  {
+    fq_nmod_poly_get_coeff (coeff, p, i, ctx);
+    if (fq_nmod_is_zero (coeff, ctx))
+      continue;
+    result += convertFq_nmod_t2FacCF (coeff, alpha)*power (x, i);
+    fq_nmod_zero (coeff, ctx);
+  }
+  fq_nmod_clear (coeff, ctx);
+
+  return result;
+}
+#endif
+
+void convertFacCFMatrix2Fmpz_mat_t (fmpz_mat_t M, const CFMatrix &m)
+{
+  fmpz_mat_init (M, (long) m.rows(), (long) m.columns());
+
+  int i,j;
+  for(i=m.rows();i>0;i--)
+  {
+    for(j=m.columns();j>0;j--)
+    {
+      convertCF2Fmpz (fmpz_mat_entry (M,i-1,j-1), m(i,j));
+    }
+  }
+}
+CFMatrix* convertFmpz_mat_t2FacCFMatrix(const fmpz_mat_t m)
+{
+  CFMatrix *res=new CFMatrix(fmpz_mat_nrows (m),fmpz_mat_ncols (m));
+  int i,j;
+  for(i=res->rows();i>0;i--)
+  {
+    for(j=res->columns();j>0;j--)
+    {
+      (*res)(i,j)=convertFmpz2CF(fmpz_mat_entry (m,i-1,j-1));
+    }
+  }
+  return res;
+}
+
+void convertFacCFMatrix2nmod_mat_t (nmod_mat_t M, const CFMatrix &m)
+{
+  nmod_mat_init (M, (long) m.rows(), (long) m.columns(), getCharacteristic());
+
+  bool save_sym_ff= isOn (SW_SYMMETRIC_FF);
+  if (save_sym_ff) Off (SW_SYMMETRIC_FF);
+  int i,j;
+  for(i=m.rows();i>0;i--)
+  {
+    for(j=m.columns();j>0;j--)
+    {
+      if(!(m(i,j)).isImm()) printf("convertFacCFMatrix2FLINTmat_zz_p: not imm.\n");
+      nmod_mat_entry (M,i-1,j-1)= (m(i,j)).intval();
+    }
+  }
+  if (save_sym_ff) On (SW_SYMMETRIC_FF);
+}
+
+CFMatrix* convertNmod_mat_t2FacCFMatrix(const nmod_mat_t m)
+{
+  CFMatrix *res=new CFMatrix(nmod_mat_nrows (m), nmod_mat_ncols (m));
+  int i,j;
+  for(i=res->rows();i>0;i--)
+  {
+    for(j=res->columns();j>0;j--)
+    {
+      (*res)(i,j)=CanonicalForm((long) nmod_mat_entry (m, i-1, j-1));
+    }
+  }
+  return res;
+}
+
+#if __FLINT_RELEASE >= 20400
+void
+convertFacCFMatrix2Fq_nmod_mat_t (fq_nmod_mat_t M,
+                                  const fq_nmod_ctx_t fq_con, const CFMatrix &m)
+{
+  fq_nmod_mat_init (M, (long) m.rows(), (long) m.columns(), fq_con);
+  int i,j;
+  for(i=m.rows();i>0;i--)
+  {
+    for(j=m.columns();j>0;j--)
+    {
+      convertFacCF2nmod_poly_t (M->rows[i-1]+j-1, m (i,j));
+    }
+  }
+}
+
+CFMatrix*
+convertFq_nmod_mat_t2FacCFMatrix(const fq_nmod_mat_t m,
+                                 const fq_nmod_ctx_t& fq_con,
+                                 const Variable& alpha)
+{
+  CFMatrix *res=new CFMatrix(fq_nmod_mat_nrows (m, fq_con),
+                             fq_nmod_mat_ncols (m, fq_con));
+  int i,j;
+  for(i=res->rows();i>0;i--)
+  {
+    for(j=res->columns();j>0;j--)
+    {
+      (*res)(i,j)=convertFq_nmod_t2FacCF (fq_nmod_mat_entry (m, i-1, j-1),
+                                          alpha);
+    }
+  }
+  return res;
+}
+#endif
+
+#endif
+
+
diff --git a/factory/FLINTconvert.h b/factory/FLINTconvert.h
new file mode 100644
index 0000000..81ac784
--- /dev/null
+++ b/factory/FLINTconvert.h
@@ -0,0 +1,253 @@
+/*****************************************************************************\
+ * Computer Algebra System SINGULAR
+\*****************************************************************************/
+/** @file FLINTconvert.h
+ *
+ * This file defines functions for conversion to FLINT (www.flintlib.org)
+ * and back.
+ *
+ * @author Martin Lee
+ *
+ **/
+/*****************************************************************************/
+
+#ifndef FLINT_CONVERT_H
+#define FLINT_CONVERT_H
+
+// #include "config.h"
+#include "canonicalform.h"
+#include "fac_util.h"
+
+#ifdef HAVE_FLINT
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+#ifndef __GMP_BITS_PER_MP_LIMB
+#define __GMP_BITS_PER_MP_LIMB GMP_LIMB_BITS
+#endif
+#include <flint/fmpz.h>
+#include <flint/fmpq.h>
+#include <flint/fmpz_poly.h>
+#include <flint/fmpz_mod_poly.h>
+#include <flint/fmpq_poly.h>
+#include <flint/nmod_poly.h>
+#include <flint/nmod_mat.h>
+#include <flint/fmpz_mat.h>
+#if ( __FLINT_RELEASE >= 20400)
+#include <flint/fq.h>
+#include <flint/fq_poly.h>
+#include <flint/fq_nmod.h>
+#include <flint/fq_nmod_poly.h>
+#include <flint/fq_nmod_mat.h>
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+#include <factory/cf_gmp.h>
+
+/// conversion of a factory integer to fmpz_t
+void
+convertCF2Fmpz (fmpz_t result,         ///< [in,out] an fmpz_t
+                const CanonicalForm& f ///< [in] a CanonicalForm wrapping an
+                                       ///< integer
+               );
+
+/// conversion of a factory univariate polynomial over Z to a fmpz_poly_t
+void
+convertFacCF2Fmpz_poly_t (fmpz_poly_t result,    ///< [in,out] an fmpz_poly_t
+                          const CanonicalForm& f ///< [in] univariate poly over
+                                                 ///< Z
+                         );
+
+/// conversion of a FLINT integer to CanonicalForm
+CanonicalForm
+convertFmpz2CF (const fmpz_t coefficient ///< [in] a FLINT integer
+               );
+
+/// conversion of a FLINT poly over Z to CanonicalForm
+CanonicalForm
+convertFmpz_poly_t2FacCF (const fmpz_poly_t poly, ///< [in] an fmpz_poly_t
+                          const Variable& x ///< [in] variable the result should
+                                            ///< have
+                         );
+
+/// conversion of a factory univariate polynomials over Z/p (for word size p)
+/// to nmod_poly_t
+void
+convertFacCF2nmod_poly_t (nmod_poly_t result,    ///< [in, out] a nmod_poly_t
+                          const CanonicalForm& f ///< [in] univariate poly over
+                                                 ///< Z/p
+                         );
+
+/// conversion of a FLINT poly over Z/p to CanonicalForm
+CanonicalForm
+convertnmod_poly_t2FacCF (const nmod_poly_t poly, ///< [in] a nmod_poly_t
+                          const Variable& x ///< [in] variable the result should
+                                            ///< have
+                         );
+
+/// conversion of a factory rationals to fmpq_t
+void
+convertCF2Fmpq (fmpq_t result,         ///< [in,out] an fmpq_t
+                const CanonicalForm& f ///< [in] a CanonicalForm wrapping a
+                                       ///< rational
+               );
+
+/// conversion of a factory univariate polynomials over Q to fmpq_poly_t
+void
+convertFacCF2Fmpq_poly_t (fmpq_poly_t result,    ///< [in,out] an fmpq_poly_t
+                          const CanonicalForm& f ///< [in] univariate poly over
+                                                 ///< Q
+                         );
+
+/// conversion of a FLINT poly over Q to CanonicalForm
+CanonicalForm
+convertFmpq_poly_t2FacCF (const fmpq_poly_t p,    ///< [in] an fmpq_poly_t
+                          const Variable& x ///< [in] variable the result should
+                                            ///< have
+                         );
+
+/// conversion of a FLINT factorization over Z/p (for word size p) to a
+/// CFFList
+CFFList
+convertFLINTnmod_poly_factor2FacCFFList (
+                   const nmod_poly_factor_t fac, ///< [in] a nmod_poly_factor_t
+                   const mp_limb_t leadingCoeff, ///< [in] leading coefficient
+                   const Variable& x       ///< [in] variable the result should
+                                           ///< have
+                                        );
+
+/// conversion of a factory univariate poly over Z to a FLINT poly over
+/// Z/p (for non word size p)
+void
+convertFacCF2Fmpz_mod_poly_t (
+                          fmpz_mod_poly_t result, ///< [in,out] fmpz_mod_poly_t
+                          const CanonicalForm& f, ///< [in] univariate poly over
+                                                  ///< Z
+                          const fmpz_t p          ///< [in] some integer p
+                             );
+
+/// conversion of a FLINT poly over Z/p (for non word size p) to a CanonicalForm
+/// over Z
+CanonicalForm
+convertFmpz_mod_poly_t2FacCF (
+                          const fmpz_mod_poly_t poly, ///< [in] fmpz_mod_poly_t
+                          const Variable& x,    ///< [in] variable the result
+                                                ///< should have
+                          const modpk& b        ///< [in] coeff bound to map
+                                                ///< coeffs in (-p/2,p/2)
+                             );
+
+#if __FLINT_RELEASE >= 20400
+/// conversion of a FLINT element of F_q to a CanonicalForm with alg. variable
+/// alpha
+CanonicalForm
+convertFq_nmod_t2FacCF (const fq_nmod_t poly, ///< [in] fq_nmod_t
+                        const Variable& alpha ///< [in] algebraic variable
+                       );
+
+/// conversion of a FLINT element of F_q with non-word size p to a CanonicalForm
+/// with alg. variable alpha
+CanonicalForm
+convertFq_t2FacCF (const fq_t poly,      ///< [in] fq_t
+                   const Variable& alpha ///< [in] algebraic variable
+                  );
+
+/// conversion of a factory element of F_q to a FLINT fq_nmod_t, does not do any
+/// memory allocation for poly
+void
+convertFacCF2Fq_nmod_t (fq_nmod_t result,       ///< [in,out] fq_nmod_t
+                        const CanonicalForm& f, ///< [in] element of Fq
+                        const fq_nmod_ctx_t ctx ///< [in] Fq context
+                       );
+
+/// conversion of a factory element of F_q (for non-word size p) to a FLINT fq_t
+void
+convertFacCF2Fq_t (fq_t result,            ///< [in,out] fq_t
+                   const CanonicalForm& f, ///< [in] element of Fq
+                   const fq_ctx_t ctx      ///< [in] Fq context
+                  );
+
+/// conversion of a factory univariate poly over F_q (for non-word size p) to a
+/// FLINT fq_poly_t
+void
+convertFacCF2Fq_poly_t (fq_poly_t result,      ///< [in,out] fq_poly_t
+                        const CanonicalForm& f,///< [in] univariate poly over Fq
+                        const fq_ctx_t ctx     ///< [in] Fq context
+                       );
+
+/// conversion of a factory univariate poly over F_q to a FLINT fq_nmod_poly_t
+void
+convertFacCF2Fq_nmod_poly_t (fq_nmod_poly_t result, ///< [in,out] fq_nmod_poly_t
+                             const CanonicalForm& f,///< [in] univariate poly
+                                                    ///< over Fq
+                             const fq_nmod_ctx_t ctx///< [in] Fq context
+                            );
+
+/// conversion of a FLINT poly over Fq (for non-word size p) to a CanonicalForm
+/// with alg. variable alpha and polynomial variable x
+CanonicalForm
+convertFq_poly_t2FacCF (const fq_poly_t p,     ///< [in] fq_poly_t
+                        const Variable& x,     ///< [in] polynomial variable
+                        const Variable& alpha, ///< [in] algebraic variable
+                        const fq_ctx_t ctx     ///< [in] Fq context
+                       );
+
+/// conversion of a FLINT poly over Fq to a CanonicalForm with alg. variable
+/// alpha and polynomial variable x
+CanonicalForm
+convertFq_nmod_poly_t2FacCF (const fq_nmod_poly_t p, ///< [in] fq_nmod_poly_t
+                             const Variable& x,      ///< [in] polynomial var.
+                             const Variable& alpha,  ///< [in] algebraic var.
+                             const fq_nmod_ctx_t ctx ///< [in] Fq context
+                            );
+#endif
+
+/// conversion of a factory matrix over Z to a fmpz_mat_t
+void convertFacCFMatrix2Fmpz_mat_t (fmpz_mat_t M,      ///<[in,out] fmpz_mat_t
+                                    const CFMatrix &m  ///<[in] matrix over Z
+                                   );
+
+/// conversion of a FLINT matrix over Z to a factory matrix
+CFMatrix* convertFmpz_mat_t2FacCFMatrix(const fmpz_mat_t m ///<[in] fmpz_mat_t
+                                       );
+
+/// conversion of a factory matrix over Z/p to a nmod_mat_t
+void convertFacCFMatrix2nmod_mat_t (nmod_mat_t M,     ///<[in,out] nmod_mat_t
+                                    const CFMatrix &m ///<[in] matrix over Z/p
+                                   );
+
+/// conversion of a FLINT matrix over Z/p to a factory matrix
+CFMatrix* convertNmod_mat_t2FacCFMatrix(const nmod_mat_t m ///<[in] nmod_mat_t
+                                       );
+
+#if __FLINT_RELEASE >= 20400
+/// conversion of a FLINT matrix over F_q to a factory matrix
+CFMatrix*
+convertFq_nmod_mat_t2FacCFMatrix(const fq_nmod_mat_t m,       ///< [in] fq_nmod_mat_t
+                                 const fq_nmod_ctx_t& fq_con, ///< [in] Fq context
+                                 const Variable& alpha ///< [in] algebraic variable
+                                );
+
+/// conversion of a factory matrix over F_q to a fq_nmod_mat_t
+void
+convertFacCFMatrix2Fq_nmod_mat_t (fq_nmod_mat_t M,            ///< [in, out] fq_nmod_mat_t
+                                  const fq_nmod_ctx_t fq_con, ///< [in] Fq context
+                                  const CFMatrix &m           ///< [in] matrix over Fq
+                                 );
+
+/// conversion of a FLINT factorization over Fq (for word size p) to a
+/// CFFList
+CFFList
+convertFLINTFq_nmod_poly_factor2FacCFFList (const fq_nmod_poly_factor_t fac, ///< [in] fq_nmod_poly_factor_t
+                                          const Variable& x,     ///< [in] polynomial variable
+                                          const Variable& alpha, ///< [in] algebraic variable
+                                          const fq_nmod_ctx_t fq_con ///< [in] Fq context
+                                           );
+#endif
+
+
+#endif
+#endif
diff --git a/factory/Makefile.am b/factory/Makefile.am
new file mode 100644
index 0000000..8ff16bd
--- /dev/null
+++ b/factory/Makefile.am
@@ -0,0 +1,293 @@
+ACLOCAL_AMFLAGS = -I ../m4
+
+SUBDIRS=include/factory
+
+AM_CPPFLAGS = -I${builddir}/include -I${srcdir}/include -I${srcdir} \
+$(OMALLOC_INCLUDES) $(RESOURCES_INCLUDES) \
+$(FLINT_CFLAGS) $(NTL_CFLAGS) $(GMP_CFLAGS)
+
+lib_LTLIBRARIES = libfactory.la
+
+libfactory_la_LIBADD     =$(RESOURCES_LIBS) $(OMALLOC_LIBS) \
+$(FLINT_LIBS) $(NTL_LIBS) $(GMP_LIBS)
+
+libfactory_la_LDFLAGS    = -release ${PACKAGE_VERSION}
+
+# factory source files
+SOURCES = \
+		canonicalform.cc \
+		cf_algorithm.cc \
+		cf_char.cc \
+		cfCharSets.cc \
+		cfCharSetsUtil.cc \
+		cf_chinese.cc \
+		cf_cyclo.cc \
+		cf_eval.cc \
+		cfEzgcd.cc \
+		cf_factor.cc \
+		cf_factory.cc \
+		cf_gcd.cc \
+		cfGcdAlgExt.cc \
+		cfGcdUtil.cc \
+		cf_generator.cc \
+		cf_globals.cc \
+		cf_hnf.cc \
+		cf_inline.cc \
+		cf_irred.cc \
+		cf_iter.cc \
+		cf_iter_inline.cc \
+		cf_linsys.cc \
+		cf_map.cc \
+		cf_map_ext.cc \
+		cfModGcd.cc \
+		cfNewtonPolygon.cc \
+		cfNTLzzpEXGCD.cc \
+		cfModResultant.cc \
+		cf_ops.cc \
+		cf_primes.cc \
+		cf_random.cc \
+		cf_resultant.cc \
+		cf_reval.cc \
+		cfSubResGcd.cc \
+		cf_switches.cc \
+		cf_util.cc \
+		cfUnivarGcd.cc \
+		debug.cc \
+		DegreePattern.cc \
+		ExtensionInfo.cc \
+		facAbsBiFact.cc \
+		facAbsFact.cc \
+		facAlgExt.cc \
+		facAlgFunc.cc \
+		facAlgFuncUtil.cc \
+		facBivar.cc \
+		facFactorize.cc \
+		fac_sqrfree.cc \
+		fac_util.cc \
+		facFqBivar.cc \
+		facFqBivarUtil.cc \
+		facFqFactorize.cc \
+		facFqFactorizeUtil.cc \
+		facFqSquarefree.cc \
+		facHensel.cc \
+		facIrredTest.cc \
+		facMul.cc \
+		facSparseHensel.cc \
+		ffops.cc \
+		FLINTconvert.cc \
+		gf_tabutil.cc \
+		gfops.cc \
+		imm.cc \
+		int_cf.cc \
+		int_int.cc \
+		int_intdiv.cc \
+		int_poly.cc \
+		int_rat.cc \
+		variable.cc \
+		NTLconvert.cc \
+		singext.cc \
+		parseutil.cc \
+		ftmpl_inst.cc
+
+if WITH_PARSER_FOR_CANONICAL_FORM
+    SOURCES +=  readcf.yy
+endif
+
+libfactory_la_SOURCES = $(SOURCES)
+
+nodist_libfactory_la_SOURCES = cplusplus.h factory.h factoryconf.h
+
+# factory header files
+factory_headers = \
+		cf_assert.h \
+		canonicalform.h \
+		cf_algorithm.h \
+		cfCharSets.h \
+		cfCharSetsUtil.h \
+		cf_cyclo.h \
+		cf_defs.h \
+		cf_eval.h \
+		cfEzgcd.h \
+		cf_factory.h \
+		cf_generator.h \
+		cf_globals.h \
+		cfGcdAlgExt.h \
+		cfGcdUtil.h \
+		cf_hnf.h \
+		cf_irred.h \
+		cf_iter.h \
+		cf_map.h \
+		cf_map_ext.h \
+		cfModGcd.h \
+		cfNewtonPolygon.h \
+		cfNTLzzpEXGCD.h \
+		cfModResultant.h \
+		cf_primes.h \
+		cf_primetab.h \
+		cf_random.h \
+		cf_reval.h \
+		cfSubResGcd.h \
+		cf_switches.h \
+		cf_util.h \
+		cfUnivarGcd.h \
+		debug.h \
+		DegreePattern.h \
+		ExtensionInfo.h \
+		facAbsBiFact.h \
+		facAbsFact.h \
+		facAlgExt.h \
+		facAlgFunc.h \
+		facAlgFuncUtil.h \
+		facBivar.h \
+		facFactorize.h \
+		fac_sqrfree.h \
+		fac_util.h \
+		facFqBivar.h \
+		facFqBivarUtil.h \
+		facFqFactorize.h \
+		facFqFactorizeUtil.h \
+		facFqSquarefree.h \
+		facHensel.h \
+		facIrredTest.h \
+		facMul.h \
+		facSparseHensel.h \
+		ffops.h \
+		FLINTconvert.h \
+		gf_tabutil.h \
+		gfops.h \
+		gmpext.h \
+		imm.h \
+		int_cf.h \
+		int_int.h \
+		int_poly.h \
+		int_rat.h \
+		timing.h \
+		variable.h \
+		NTLconvert.h \
+		singext.h \
+		parseutil.h
+
+noinst_HEADERS = $(factory_headers)
+
+libfactory_includedir = ${includedir}/factory
+
+nodist_libfactory_include_HEADERS = cplusplus.h factory.h factoryconf.h
+
+
+####################################################
+# Documentation
+include $(srcdir)/aminclude.am
+
+####################################################
+# the precomputed GF(q)-tables
+
+gftablesdir=$(datadir)/factory/gftables
+dist_gftables_DATA = gftables/10201 gftables/1024 gftables/10609 gftables/11449 \
+gftables/11881 gftables/121 gftables/12167 gftables/125 gftables/12769 \
+gftables/128 gftables/1331 gftables/1369 gftables/14641 \
+gftables/15625 gftables/16 gftables/16129 gftables/16384 \
+gftables/16807 gftables/1681 gftables/169 gftables/17161 gftables/1849 \
+gftables/18769 gftables/19321 gftables/19683 gftables/2048 \
+gftables/2187 gftables/2197 gftables/2209 gftables/22201 \
+gftables/22801 gftables/2401 gftables/243 gftables/24389 \
+gftables/24649 gftables/25 gftables/256 gftables/26569 gftables/27 \
+gftables/27889 gftables/2809 gftables/28561 gftables/289 \
+gftables/29791 gftables/29929 gftables/3125 gftables/32 gftables/32041 \
+gftables/32761 gftables/32768 gftables/343 gftables/3481 gftables/361 \
+gftables/36481 gftables/3721 gftables/37249 gftables/38809 \
+gftables/39601 gftables/4 gftables/4096 gftables/44521 gftables/4489 \
+gftables/49 gftables/4913 gftables/49729 gftables/5041 \
+gftables/50653 gftables/512 gftables/51529 gftables/52441 gftables/529 \
+gftables/5329 gftables/54289 gftables/57121 gftables/58081 \
+gftables/59049 gftables/6241 gftables/625 gftables/63001 \
+gftables/64 gftables/6561 gftables/6859 gftables/6889 gftables/729 \
+gftables/7921 gftables/8 gftables/81 gftables/8192 gftables/841 \
+gftables/9 gftables/9409 gftables/961
+
+
+####################################################
+# Support for building GF(q)-tables
+#
+# gengftables needs libfactory.la and factory.h AND is needed for
+# generating gftable but the tables are not necessarily needed to
+# compile and use libfactory (though it will be a lot slower).
+
+EXTRA_PROGRAMS = gengftables
+gengftables_SOURCES = gengftables-conway.cc
+gengftables_LDADD = libfactory.la $(FLINT_LIBS) $(GMP_LIBS) $(NTL_LIBS)
+
+
+####################################################
+# These files listed below are not used anywhere but are included in
+# the distribution. So they will be tacked on to EXTRA_DIST.
+
+templatesrc =	templates/ftmpl_array.cc \
+		templates/ftmpl_afactor.cc \
+		templates/ftmpl_factor.cc \
+		templates/ftmpl_functions.h \
+		templates/ftmpl_list.cc \
+		templates/ftmpl_matrix.cc
+
+# header templates
+hdrtemplsrc = 	factoryconf.template \
+		factory.template
+
+EXTRA_DIST =	test_install.cc \
+		$(templatesrc) $(hdrtemplsrc) \
+		doxygen.cfg \
+		examples/application.cc \
+		examples/factorize.cc examples/gcd.cc \
+		bin/folding.el bin/fold-docu.el \
+		bin/makeheader bin/gen-readcf readcf.yy \
+		make_factory_dist
+
+##################################################
+# autogenerated sources
+
+noinst_PROGRAMS = cplusplus
+
+BUILT_SOURCES = cplusplus.h factory.h factoryconf.h
+
+CLEANFILES = $(BUILT_SOURCES) include/factory/factory.h include/factory/factoryconf.h include/factory/cplusplus.h
+
+DISTCLEANFILES =  config.h readcf.cc
+
+#distclean-local:
+#	-rm -f readcf.cc
+
+cplusplus_SOURCES = cplusplus.cc
+
+cplusplus.h: cplusplus$(EXEEXT)
+	./cplusplus$(EXEEXT)  >$@
+	cp $@ include/factory/
+
+.template.h:
+	${srcdir}/bin/makeheader $< $@
+	cp $@ include/factory/
+
+# factory/gfops.cc has the gftables path hardcoded in, so we create a
+# symlink. Remove this rule once gfopts.cc has been fixed. Note that
+# check-local would run in parallel with check, so we can't use it
+# here!
+all-local:
+	[ -d ${builddir}/gftables ] || ln -s ${srcdir}/gftables ${builddir}
+
+
+####################################################
+## Test program
+##
+
+TESTS = test
+
+check_PROGRAMS = $(TESTS)
+
+test_SOURCES = test.cc
+test_LDADD   = libfactory.la $(libfactory_la_LIBADD)
+
+####################################################
+## PKG config
+##
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = factory.pc
+
diff --git a/factory/Makefile.in b/factory/Makefile.in
new file mode 100644
index 0000000..5398c12
--- /dev/null
+++ b/factory/Makefile.in
@@ -0,0 +1,1938 @@
+# Makefile.in generated by automake 1.13.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 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@
+
+# Copyright (C) 2004 Oren Ben-Kiki
+# This file is distributed under the same terms as the Automake macro files.
+
+# Generate automatic documentation using Doxygen. Goals and variables values
+# are controlled by the various DX_COND_??? conditionals set by autoconf.
+#
+# The provided goals are:
+# doxygen-doc: Generate all doxygen documentation.
+# doxygen-run: Run doxygen, which will generate some of the documentation
+#              (HTML, CHM, CHI, MAN, RTF, XML) but will not do the post
+#              processing required for the rest of it (PS, PDF, and some MAN).
+# doxygen-man: Rename some doxygen generated man pages.
+# doxygen-ps: Generate doxygen PostScript documentation.
+# doxygen-pdf: Generate doxygen PDF documentation.
+#
+# Note that by default these are not integrated into the automake goals. If
+# doxygen is used to generate man pages, you can achieve this integration by
+# setting man3_MANS to the list of man pages generated and then adding the
+# dependency:
+#
+#   $(man3_MANS): doxygen-doc
+#
+# This will cause make to run doxygen and generate all the documentation.
+#
+# The following variable is intended for use in Makefile.am:
+#
+# DX_CLEANFILES = everything to clean.
+#
+# This is usually added to MOSTLYCLEANFILES.
+
+
+
+
+VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+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@
+ at WITH_PARSER_FOR_CANONICAL_FORM_TRUE@am__append_1 = readcf.yy
+DIST_COMMON = $(srcdir)/aminclude.am $(srcdir)/Makefile.in \
+	$(srcdir)/Makefile.am $(top_srcdir)/configure \
+	$(am__configure_deps) $(srcdir)/_config.h.in \
+	$(srcdir)/factory.pc.in readcf.cc \
+	$(top_srcdir)/../build-aux/depcomp \
+	$(top_srcdir)/../build-aux/ylwrap $(dist_gftables_DATA) \
+	$(noinst_HEADERS) $(top_srcdir)/../build-aux/test-driver \
+	AUTHORS COPYING ChangeLog NEWS README ../build-aux/ar-lib \
+	../build-aux/compile ../build-aux/config.guess \
+	../build-aux/config.sub ../build-aux/depcomp \
+	../build-aux/install-sh ../build-aux/missing \
+	../build-aux/ylwrap ../build-aux/ltmain.sh \
+	$(top_srcdir)/../build-aux/ar-lib \
+	$(top_srcdir)/../build-aux/config.guess \
+	$(top_srcdir)/../build-aux/config.sub \
+	$(top_srcdir)/../build-aux/install-sh \
+	$(top_srcdir)/../build-aux/ltmain.sh \
+	$(top_srcdir)/../build-aux/missing
+EXTRA_PROGRAMS = gengftables$(EXEEXT)
+noinst_PROGRAMS = cplusplus$(EXEEXT)
+TESTS = test$(EXEEXT)
+check_PROGRAMS = $(am__EXEEXT_1)
+subdir = .
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/../m4/ax_append_compile_flags.m4 \
+	$(top_srcdir)/../m4/ax_append_flag.m4 \
+	$(top_srcdir)/../m4/ax_append_link_flags.m4 \
+	$(top_srcdir)/../m4/ax_check_compile_flag.m4 \
+	$(top_srcdir)/../m4/ax_check_link_flag.m4 \
+	$(top_srcdir)/../m4/ax_prefix_config_h.m4 \
+	$(top_srcdir)/../m4/flags.m4 \
+	$(top_srcdir)/../m4/flint-check.m4 \
+	$(top_srcdir)/../m4/gmp-check.m4 \
+	$(top_srcdir)/../m4/libtool.m4 \
+	$(top_srcdir)/../m4/ltoptions.m4 \
+	$(top_srcdir)/../m4/ltsugar.m4 \
+	$(top_srcdir)/../m4/ltversion.m4 \
+	$(top_srcdir)/../m4/lt~obsolete.m4 \
+	$(top_srcdir)/../m4/ntl-check.m4 \
+	$(top_srcdir)/../m4/options.m4 $(top_srcdir)/acinclude.m4 \
+	$(top_srcdir)/configure.ac
+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 = factory.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__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
+am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(gftablesdir)" \
+	"$(DESTDIR)$(pkgconfigdir)" \
+	"$(DESTDIR)$(libfactory_includedir)"
+LTLIBRARIES = $(lib_LTLIBRARIES)
+am__DEPENDENCIES_1 =
+libfactory_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \
+	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
+am__libfactory_la_SOURCES_DIST = canonicalform.cc cf_algorithm.cc \
+	cf_char.cc cfCharSets.cc cfCharSetsUtil.cc cf_chinese.cc \
+	cf_cyclo.cc cf_eval.cc cfEzgcd.cc cf_factor.cc cf_factory.cc \
+	cf_gcd.cc cfGcdAlgExt.cc cfGcdUtil.cc cf_generator.cc \
+	cf_globals.cc cf_hnf.cc cf_inline.cc cf_irred.cc cf_iter.cc \
+	cf_iter_inline.cc cf_linsys.cc cf_map.cc cf_map_ext.cc \
+	cfModGcd.cc cfNewtonPolygon.cc cfNTLzzpEXGCD.cc \
+	cfModResultant.cc cf_ops.cc cf_primes.cc cf_random.cc \
+	cf_resultant.cc cf_reval.cc cfSubResGcd.cc cf_switches.cc \
+	cf_util.cc cfUnivarGcd.cc debug.cc DegreePattern.cc \
+	ExtensionInfo.cc facAbsBiFact.cc facAbsFact.cc facAlgExt.cc \
+	facAlgFunc.cc facAlgFuncUtil.cc facBivar.cc facFactorize.cc \
+	fac_sqrfree.cc fac_util.cc facFqBivar.cc facFqBivarUtil.cc \
+	facFqFactorize.cc facFqFactorizeUtil.cc facFqSquarefree.cc \
+	facHensel.cc facIrredTest.cc facMul.cc facSparseHensel.cc \
+	ffops.cc FLINTconvert.cc gf_tabutil.cc gfops.cc imm.cc \
+	int_cf.cc int_int.cc int_intdiv.cc int_poly.cc int_rat.cc \
+	variable.cc NTLconvert.cc singext.cc parseutil.cc \
+	ftmpl_inst.cc readcf.yy
+ at WITH_PARSER_FOR_CANONICAL_FORM_TRUE@am__objects_1 = readcf.lo
+am__objects_2 = canonicalform.lo cf_algorithm.lo cf_char.lo \
+	cfCharSets.lo cfCharSetsUtil.lo cf_chinese.lo cf_cyclo.lo \
+	cf_eval.lo cfEzgcd.lo cf_factor.lo cf_factory.lo cf_gcd.lo \
+	cfGcdAlgExt.lo cfGcdUtil.lo cf_generator.lo cf_globals.lo \
+	cf_hnf.lo cf_inline.lo cf_irred.lo cf_iter.lo \
+	cf_iter_inline.lo cf_linsys.lo cf_map.lo cf_map_ext.lo \
+	cfModGcd.lo cfNewtonPolygon.lo cfNTLzzpEXGCD.lo \
+	cfModResultant.lo cf_ops.lo cf_primes.lo cf_random.lo \
+	cf_resultant.lo cf_reval.lo cfSubResGcd.lo cf_switches.lo \
+	cf_util.lo cfUnivarGcd.lo debug.lo DegreePattern.lo \
+	ExtensionInfo.lo facAbsBiFact.lo facAbsFact.lo facAlgExt.lo \
+	facAlgFunc.lo facAlgFuncUtil.lo facBivar.lo facFactorize.lo \
+	fac_sqrfree.lo fac_util.lo facFqBivar.lo facFqBivarUtil.lo \
+	facFqFactorize.lo facFqFactorizeUtil.lo facFqSquarefree.lo \
+	facHensel.lo facIrredTest.lo facMul.lo facSparseHensel.lo \
+	ffops.lo FLINTconvert.lo gf_tabutil.lo gfops.lo imm.lo \
+	int_cf.lo int_int.lo int_intdiv.lo int_poly.lo int_rat.lo \
+	variable.lo NTLconvert.lo singext.lo parseutil.lo \
+	ftmpl_inst.lo $(am__objects_1)
+am_libfactory_la_OBJECTS = $(am__objects_2)
+nodist_libfactory_la_OBJECTS =
+libfactory_la_OBJECTS = $(am_libfactory_la_OBJECTS) \
+	$(nodist_libfactory_la_OBJECTS)
+AM_V_lt = $(am__v_lt_ at AM_V@)
+am__v_lt_ = $(am__v_lt_ at AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 = 
+libfactory_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
+	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
+	$(AM_CXXFLAGS) $(CXXFLAGS) $(libfactory_la_LDFLAGS) $(LDFLAGS) \
+	-o $@
+am__EXEEXT_1 = test$(EXEEXT)
+PROGRAMS = $(noinst_PROGRAMS)
+am_cplusplus_OBJECTS = cplusplus.$(OBJEXT)
+cplusplus_OBJECTS = $(am_cplusplus_OBJECTS)
+cplusplus_LDADD = $(LDADD)
+am_gengftables_OBJECTS = gengftables-conway.$(OBJEXT)
+gengftables_OBJECTS = $(am_gengftables_OBJECTS)
+gengftables_DEPENDENCIES = libfactory.la $(am__DEPENDENCIES_1) \
+	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
+am_test_OBJECTS = test.$(OBJEXT)
+test_OBJECTS = $(am_test_OBJECTS)
+am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+	$(am__DEPENDENCIES_1)
+test_DEPENDENCIES = libfactory.la $(am__DEPENDENCIES_2)
+AM_V_P = $(am__v_P_ at AM_V@)
+am__v_P_ = $(am__v_P_ at AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_ at AM_V@)
+am__v_GEN_ = $(am__v_GEN_ at AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_ at AM_V@)
+am__v_at_ = $(am__v_at_ at AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+DEFAULT_INCLUDES = -I. at am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/../build-aux/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \
+	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+	$(AM_CXXFLAGS) $(CXXFLAGS)
+AM_V_CXX = $(am__v_CXX_ at AM_V@)
+am__v_CXX_ = $(am__v_CXX_ at AM_DEFAULT_V@)
+am__v_CXX_0 = @echo "  CXX     " $@;
+am__v_CXX_1 = 
+CXXLD = $(CXX)
+CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+	$(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CXXLD = $(am__v_CXXLD_ at AM_V@)
+am__v_CXXLD_ = $(am__v_CXXLD_ at AM_DEFAULT_V@)
+am__v_CXXLD_0 = @echo "  CXXLD   " $@;
+am__v_CXXLD_1 = 
+ at MAINTAINER_MODE_FALSE@am__skipyacc = test -f $@ ||
+am__yacc_c2h = sed -e s/cc$$/hh/ -e s/cpp$$/hpp/ -e s/cxx$$/hxx/ \
+		   -e s/c++$$/h++/ -e s/c$$/h/
+YACCCOMPILE = $(YACC) $(AM_YFLAGS) $(YFLAGS)
+LTYACCCOMPILE = $(LIBTOOL) $(AM_V_lt) $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=compile $(YACC) $(AM_YFLAGS) $(YFLAGS)
+AM_V_YACC = $(am__v_YACC_ at AM_V@)
+am__v_YACC_ = $(am__v_YACC_ at AM_DEFAULT_V@)
+am__v_YACC_0 = @echo "  YACC    " $@;
+am__v_YACC_1 = 
+YLWRAP = $(top_srcdir)/../build-aux/ylwrap
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+	$(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_ at AM_V@)
+am__v_CC_ = $(am__v_CC_ at AM_DEFAULT_V@)
+am__v_CC_0 = @echo "  CC      " $@;
+am__v_CC_1 = 
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+	$(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_ at AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_ at AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo "  CCLD    " $@;
+am__v_CCLD_1 = 
+DIST_SOURCES = $(am__libfactory_la_SOURCES_DIST) $(cplusplus_SOURCES) \
+	$(gengftables_SOURCES) $(test_SOURCES)
+RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
+	ctags-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 \
+	tags-recursive uninstall-recursive
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+DATA = $(dist_gftables_DATA) $(pkgconfig_DATA)
+HEADERS = $(nodist_libfactory_include_HEADERS) $(noinst_HEADERS)
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive	\
+  distclean-recursive maintainer-clean-recursive
+am__recursive_targets = \
+  $(RECURSIVE_TARGETS) \
+  $(RECURSIVE_CLEAN_TARGETS) \
+  $(am__extra_recursive_targets)
+AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
+	cscope check recheck distdir dist dist-all distcheck
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \
+	$(LISP)_config.h.in
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+CSCOPE = cscope
+am__tty_colors_dummy = \
+  mgn= red= grn= lgn= blu= brg= std=; \
+  am__color_tests=no
+am__tty_colors = { \
+  $(am__tty_colors_dummy); \
+  if test "X$(AM_COLOR_TESTS)" = Xno; then \
+    am__color_tests=no; \
+  elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+    am__color_tests=yes; \
+  elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+    am__color_tests=yes; \
+  fi; \
+  if test $$am__color_tests = yes; then \
+    red=''; \
+    grn=''; \
+    lgn=''; \
+    blu=''; \
+    mgn=''; \
+    brg=''; \
+    std=''; \
+  fi; \
+}
+am__recheck_rx = ^[ 	]*:recheck:[ 	]*
+am__global_test_result_rx = ^[ 	]*:global-test-result:[ 	]*
+am__copy_in_global_log_rx = ^[ 	]*:copy-in-global-log:[ 	]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+  recheck = 1; \
+  while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+    { \
+      if (rc < 0) \
+        { \
+          if ((getline line2 < ($$0 ".log")) < 0) \
+	    recheck = 0; \
+          break; \
+        } \
+      else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+        { \
+          recheck = 0; \
+          break; \
+        } \
+      else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+        { \
+          break; \
+        } \
+    }; \
+  if (recheck) \
+    print $$0; \
+  close ($$0 ".trs"); \
+  close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+  print "fatal: making $@: " msg | "cat >&2"; \
+  exit 1; \
+} \
+function rst_section(header) \
+{ \
+  print header; \
+  len = length(header); \
+  for (i = 1; i <= len; i = i + 1) \
+    printf "="; \
+  printf "\n\n"; \
+} \
+{ \
+  copy_in_global_log = 1; \
+  global_test_result = "RUN"; \
+  while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+    { \
+      if (rc < 0) \
+         fatal("failed to read from " $$0 ".trs"); \
+      if (line ~ /$(am__global_test_result_rx)/) \
+        { \
+          sub("$(am__global_test_result_rx)", "", line); \
+          sub("[ 	]*$$", "", line); \
+          global_test_result = line; \
+        } \
+      else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+        copy_in_global_log = 0; \
+    }; \
+  if (copy_in_global_log) \
+    { \
+      rst_section(global_test_result ": " $$0); \
+      while ((rc = (getline line < ($$0 ".log"))) != 0) \
+      { \
+        if (rc < 0) \
+          fatal("failed to read from " $$0 ".log"); \
+        print line; \
+      }; \
+      printf "\n"; \
+    }; \
+  close ($$0 ".trs"); \
+  close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/   &   /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this.  Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+  --color-tests "$$am__color_tests" \
+  --enable-hard-errors "$$am__enable_hard_errors" \
+  --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test.  Creates the
+# directory for the log if needed.  Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log.  Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT.  Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup);					\
+$(am__vpath_adj_setup) $(am__vpath_adj)			\
+$(am__tty_colors);					\
+srcdir=$(srcdir); export srcdir;			\
+case "$@" in						\
+  */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;;	\
+    *) am__odir=.;; 					\
+esac;							\
+test "x$$am__odir" = x"." || test -d "$$am__odir" 	\
+  || $(MKDIR_P) "$$am__odir" || exit $$?;		\
+if test -f "./$$f"; then dir=./;			\
+elif test -f "$$f"; then dir=;				\
+else dir="$(srcdir)/"; fi;				\
+tst=$$dir$$f; log='$@'; 				\
+if test -n '$(DISABLE_HARD_ERRORS)'; then		\
+  am__enable_hard_errors=no; 				\
+else							\
+  am__enable_hard_errors=yes; 				\
+fi; 							\
+case " $(XFAIL_TESTS) " in				\
+  *[\ \	]$$f[\ \	]* | *[\ \	]$$dir$$f[\ \	]*) \
+    am__expect_failure=yes;;				\
+  *)							\
+    am__expect_failure=no;;				\
+esac; 							\
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed).  The result is saved in the shell variable
+# '$bases'.  This honors runtime overriding of TESTS and TEST_LOGS.  Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+  bases='$(TEST_LOGS)'; \
+  bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+  bases=`echo $$bases`
+RECHECK_LOGS = $(TEST_LOGS)
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_DRIVER = $(SHELL) $(top_srcdir)/../build-aux/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+  case '$@' in \
+    */*) \
+      case '$*' in \
+        */*) b='$*';; \
+          *) b=`echo '$@' | sed 's/\.log$$//'`; \
+       esac;; \
+    *) \
+      b='$*';; \
+  esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT at .log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/../build-aux/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+	$(TEST_LOG_FLAGS)
+DIST_SUBDIRS = $(SUBDIRS)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+distdir = $(PACKAGE)-$(VERSION)
+top_distdir = $(distdir)
+am__remove_distdir = \
+  if test -d "$(distdir)"; then \
+    find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \
+      && rm -rf "$(distdir)" \
+      || { sleep 5 && rm -rf "$(distdir)"; }; \
+  else :; fi
+am__post_remove_distdir = $(am__remove_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
+DIST_TARGETS = dist-gzip
+distuninstallcheck_listfiles = find . -type f -print
+am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \
+  | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$'
+distcleancheck_listfiles = find . -type f -print
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BISON = @BISON@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DOXYGEN_PAPER_SIZE = @DOXYGEN_PAPER_SIZE@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+DX_CONFIG = @DX_CONFIG@
+DX_DOCDIR = @DX_DOCDIR@
+DX_DOT = @DX_DOT@
+DX_DOXYGEN = @DX_DOXYGEN@
+DX_DVIPS = @DX_DVIPS@
+DX_EGREP = @DX_EGREP@
+DX_ENV = @DX_ENV@
+DX_FLAG_DX_CURRENT_FEATURE = @DX_FLAG_DX_CURRENT_FEATURE@
+DX_FLAG_chi = @DX_FLAG_chi@
+DX_FLAG_chm = @DX_FLAG_chm@
+DX_FLAG_doc = @DX_FLAG_doc@
+DX_FLAG_dot = @DX_FLAG_dot@
+DX_FLAG_html = @DX_FLAG_html@
+DX_FLAG_man = @DX_FLAG_man@
+DX_FLAG_pdf = @DX_FLAG_pdf@
+DX_FLAG_ps = @DX_FLAG_ps@
+DX_FLAG_rtf = @DX_FLAG_rtf@
+DX_FLAG_xml = @DX_FLAG_xml@
+DX_HHC = @DX_HHC@
+DX_LATEX = @DX_LATEX@
+DX_MAKEINDEX = @DX_MAKEINDEX@
+DX_PDFLATEX = @DX_PDFLATEX@
+DX_PERL = @DX_PERL@
+DX_PROJECT = @DX_PROJECT@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+FLINT_CFLAGS = @FLINT_CFLAGS@
+FLINT_HOME = @FLINT_HOME@
+FLINT_LIBS = @FLINT_LIBS@
+GMP_CFLAGS = @GMP_CFLAGS@
+GMP_HOME = @GMP_HOME@
+GMP_LIBS = @GMP_LIBS@
+GMP_VERSION = @GMP_VERSION@
+GREP = @GREP@
+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@
+M4 = @M4@
+MAINT = @MAINT@
+MAKEHEADERFLAGS = @MAKEHEADERFLAGS@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NTL_CFLAGS = @NTL_CFLAGS@
+NTL_LIBS = @NTL_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OMALLOC_INCLUDES = @OMALLOC_INCLUDES@
+OMALLOC_LIBS = @OMALLOC_LIBS@
+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@
+PKG_REQUIRE = @PKG_REQUIRE@
+POLYMAKE_CXXFLAGS = @POLYMAKE_CXXFLAGS@
+RANLIB = @RANLIB@
+RESOURCES_INCLUDES = @RESOURCES_INCLUDES@
+RESOURCES_LIBS = @RESOURCES_LIBS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SINGULAR_CFLAGS = @SINGULAR_CFLAGS@
+STRIP = @STRIP@
+VERSION = @VERSION@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+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@
+factory_version = @factory_version@
+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@
+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@
+ACLOCAL_AMFLAGS = -I ../m4
+SUBDIRS = include/factory
+AM_CPPFLAGS = -I${builddir}/include -I${srcdir}/include -I${srcdir} \
+$(OMALLOC_INCLUDES) $(RESOURCES_INCLUDES) \
+$(FLINT_CFLAGS) $(NTL_CFLAGS) $(GMP_CFLAGS)
+
+lib_LTLIBRARIES = libfactory.la
+libfactory_la_LIBADD = $(RESOURCES_LIBS) $(OMALLOC_LIBS) \
+$(FLINT_LIBS) $(NTL_LIBS) $(GMP_LIBS)
+
+libfactory_la_LDFLAGS = -release ${PACKAGE_VERSION}
+
+# factory source files
+SOURCES = canonicalform.cc cf_algorithm.cc cf_char.cc cfCharSets.cc \
+	cfCharSetsUtil.cc cf_chinese.cc cf_cyclo.cc cf_eval.cc \
+	cfEzgcd.cc cf_factor.cc cf_factory.cc cf_gcd.cc cfGcdAlgExt.cc \
+	cfGcdUtil.cc cf_generator.cc cf_globals.cc cf_hnf.cc \
+	cf_inline.cc cf_irred.cc cf_iter.cc cf_iter_inline.cc \
+	cf_linsys.cc cf_map.cc cf_map_ext.cc cfModGcd.cc \
+	cfNewtonPolygon.cc cfNTLzzpEXGCD.cc cfModResultant.cc \
+	cf_ops.cc cf_primes.cc cf_random.cc cf_resultant.cc \
+	cf_reval.cc cfSubResGcd.cc cf_switches.cc cf_util.cc \
+	cfUnivarGcd.cc debug.cc DegreePattern.cc ExtensionInfo.cc \
+	facAbsBiFact.cc facAbsFact.cc facAlgExt.cc facAlgFunc.cc \
+	facAlgFuncUtil.cc facBivar.cc facFactorize.cc fac_sqrfree.cc \
+	fac_util.cc facFqBivar.cc facFqBivarUtil.cc facFqFactorize.cc \
+	facFqFactorizeUtil.cc facFqSquarefree.cc facHensel.cc \
+	facIrredTest.cc facMul.cc facSparseHensel.cc ffops.cc \
+	FLINTconvert.cc gf_tabutil.cc gfops.cc imm.cc int_cf.cc \
+	int_int.cc int_intdiv.cc int_poly.cc int_rat.cc variable.cc \
+	NTLconvert.cc singext.cc parseutil.cc ftmpl_inst.cc \
+	$(am__append_1)
+libfactory_la_SOURCES = $(SOURCES)
+nodist_libfactory_la_SOURCES = cplusplus.h factory.h factoryconf.h
+
+# factory header files
+factory_headers = \
+		cf_assert.h \
+		canonicalform.h \
+		cf_algorithm.h \
+		cfCharSets.h \
+		cfCharSetsUtil.h \
+		cf_cyclo.h \
+		cf_defs.h \
+		cf_eval.h \
+		cfEzgcd.h \
+		cf_factory.h \
+		cf_generator.h \
+		cf_globals.h \
+		cfGcdAlgExt.h \
+		cfGcdUtil.h \
+		cf_hnf.h \
+		cf_irred.h \
+		cf_iter.h \
+		cf_map.h \
+		cf_map_ext.h \
+		cfModGcd.h \
+		cfNewtonPolygon.h \
+		cfNTLzzpEXGCD.h \
+		cfModResultant.h \
+		cf_primes.h \
+		cf_primetab.h \
+		cf_random.h \
+		cf_reval.h \
+		cfSubResGcd.h \
+		cf_switches.h \
+		cf_util.h \
+		cfUnivarGcd.h \
+		debug.h \
+		DegreePattern.h \
+		ExtensionInfo.h \
+		facAbsBiFact.h \
+		facAbsFact.h \
+		facAlgExt.h \
+		facAlgFunc.h \
+		facAlgFuncUtil.h \
+		facBivar.h \
+		facFactorize.h \
+		fac_sqrfree.h \
+		fac_util.h \
+		facFqBivar.h \
+		facFqBivarUtil.h \
+		facFqFactorize.h \
+		facFqFactorizeUtil.h \
+		facFqSquarefree.h \
+		facHensel.h \
+		facIrredTest.h \
+		facMul.h \
+		facSparseHensel.h \
+		ffops.h \
+		FLINTconvert.h \
+		gf_tabutil.h \
+		gfops.h \
+		gmpext.h \
+		imm.h \
+		int_cf.h \
+		int_int.h \
+		int_poly.h \
+		int_rat.h \
+		timing.h \
+		variable.h \
+		NTLconvert.h \
+		singext.h \
+		parseutil.h
+
+noinst_HEADERS = $(factory_headers)
+libfactory_includedir = ${includedir}/factory
+nodist_libfactory_include_HEADERS = cplusplus.h factory.h factoryconf.h
+ at DX_COND_doc_TRUE@@DX_COND_html_TRUE at DX_CLEAN_HTML = @DX_DOCDIR@/html
+ at DX_COND_chm_TRUE@@DX_COND_doc_TRUE at DX_CLEAN_CHM = @DX_DOCDIR@/chm
+ at DX_COND_chi_TRUE@@DX_COND_chm_TRUE@@DX_COND_doc_TRUE at DX_CLEAN_CHI = @DX_DOCDIR@/@PACKAGE at .chi
+ at DX_COND_doc_TRUE@@DX_COND_man_TRUE at DX_CLEAN_MAN = @DX_DOCDIR@/man
+ at DX_COND_doc_TRUE@@DX_COND_rtf_TRUE at DX_CLEAN_RTF = @DX_DOCDIR@/rtf
+ at DX_COND_doc_TRUE@@DX_COND_xml_TRUE at DX_CLEAN_XML = @DX_DOCDIR@/xml
+ at DX_COND_doc_TRUE@@DX_COND_ps_TRUE at DX_CLEAN_PS = @DX_DOCDIR@/@PACKAGE at .ps
+ at DX_COND_doc_TRUE@@DX_COND_ps_TRUE at DX_PS_GOAL = doxygen-ps
+ at DX_COND_doc_TRUE@@DX_COND_pdf_TRUE at DX_CLEAN_PDF = @DX_DOCDIR@/@PACKAGE at .pdf
+ at DX_COND_doc_TRUE@@DX_COND_pdf_TRUE at DX_PDF_GOAL = doxygen-pdf
+ at DX_COND_doc_TRUE@@DX_COND_latex_TRUE at DX_CLEAN_LATEX = @DX_DOCDIR@/latex
+ at DX_COND_doc_TRUE@DX_CLEANFILES = \
+ at DX_COND_doc_TRUE@    @DX_DOCDIR@/@PACKAGE at .tag \
+ at DX_COND_doc_TRUE@    -r \
+ at DX_COND_doc_TRUE@    $(DX_CLEAN_HTML) \
+ at DX_COND_doc_TRUE@    $(DX_CLEAN_CHM) \
+ at DX_COND_doc_TRUE@    $(DX_CLEAN_CHI) \
+ at DX_COND_doc_TRUE@    $(DX_CLEAN_MAN) \
+ at DX_COND_doc_TRUE@    $(DX_CLEAN_RTF) \
+ at DX_COND_doc_TRUE@    $(DX_CLEAN_XML) \
+ at DX_COND_doc_TRUE@    $(DX_CLEAN_PS) \
+ at DX_COND_doc_TRUE@    $(DX_CLEAN_PDF) \
+ at DX_COND_doc_TRUE@    $(DX_CLEAN_LATEX)
+
+
+####################################################
+# Documentation
+
+####################################################
+# the precomputed GF(q)-tables
+gftablesdir = $(datadir)/factory/gftables
+dist_gftables_DATA = gftables/10201 gftables/1024 gftables/10609 gftables/11449 \
+gftables/11881 gftables/121 gftables/12167 gftables/125 gftables/12769 \
+gftables/128 gftables/1331 gftables/1369 gftables/14641 \
+gftables/15625 gftables/16 gftables/16129 gftables/16384 \
+gftables/16807 gftables/1681 gftables/169 gftables/17161 gftables/1849 \
+gftables/18769 gftables/19321 gftables/19683 gftables/2048 \
+gftables/2187 gftables/2197 gftables/2209 gftables/22201 \
+gftables/22801 gftables/2401 gftables/243 gftables/24389 \
+gftables/24649 gftables/25 gftables/256 gftables/26569 gftables/27 \
+gftables/27889 gftables/2809 gftables/28561 gftables/289 \
+gftables/29791 gftables/29929 gftables/3125 gftables/32 gftables/32041 \
+gftables/32761 gftables/32768 gftables/343 gftables/3481 gftables/361 \
+gftables/36481 gftables/3721 gftables/37249 gftables/38809 \
+gftables/39601 gftables/4 gftables/4096 gftables/44521 gftables/4489 \
+gftables/49 gftables/4913 gftables/49729 gftables/5041 \
+gftables/50653 gftables/512 gftables/51529 gftables/52441 gftables/529 \
+gftables/5329 gftables/54289 gftables/57121 gftables/58081 \
+gftables/59049 gftables/6241 gftables/625 gftables/63001 \
+gftables/64 gftables/6561 gftables/6859 gftables/6889 gftables/729 \
+gftables/7921 gftables/8 gftables/81 gftables/8192 gftables/841 \
+gftables/9 gftables/9409 gftables/961
+
+gengftables_SOURCES = gengftables-conway.cc
+gengftables_LDADD = libfactory.la $(FLINT_LIBS) $(GMP_LIBS) $(NTL_LIBS)
+
+####################################################
+# These files listed below are not used anywhere but are included in
+# the distribution. So they will be tacked on to EXTRA_DIST.
+templatesrc = templates/ftmpl_array.cc \
+		templates/ftmpl_afactor.cc \
+		templates/ftmpl_factor.cc \
+		templates/ftmpl_functions.h \
+		templates/ftmpl_list.cc \
+		templates/ftmpl_matrix.cc
+
+
+# header templates
+hdrtemplsrc = factoryconf.template \
+		factory.template
+
+EXTRA_DIST = test_install.cc \
+		$(templatesrc) $(hdrtemplsrc) \
+		doxygen.cfg \
+		examples/application.cc \
+		examples/factorize.cc examples/gcd.cc \
+		bin/folding.el bin/fold-docu.el \
+		bin/makeheader bin/gen-readcf readcf.yy \
+		make_factory_dist
+
+BUILT_SOURCES = cplusplus.h factory.h factoryconf.h
+CLEANFILES = $(BUILT_SOURCES) include/factory/factory.h include/factory/factoryconf.h include/factory/cplusplus.h
+DISTCLEANFILES = config.h readcf.cc
+
+#distclean-local:
+#	-rm -f readcf.cc
+cplusplus_SOURCES = cplusplus.cc
+test_SOURCES = test.cc
+test_LDADD = libfactory.la $(libfactory_la_LIBADD)
+
+####################################################
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = factory.pc
+all: $(BUILT_SOURCES) _config.h
+	$(MAKE) $(AM_MAKEFLAGS) all-recursive
+
+.SUFFIXES:
+.SUFFIXES: .cc .h .lo .log .o .obj .template .test .test$(EXEEXT) .trs .yy
+am--refresh: Makefile
+	@:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(srcdir)/aminclude.am $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \
+	      $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \
+		&& exit 0; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign 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;
+$(srcdir)/aminclude.am:
+
+$(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; else :; fi
+	@if test ! -f $@; then $(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
+factory.pc: $(top_builddir)/config.status $(srcdir)/factory.pc.in
+	cd $(top_builddir) && $(SHELL) ./config.status $@
+
+install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+	@$(NORMAL_INSTALL)
+	@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 " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \
+	  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)'; \
+	locs=`for p in $$list; do echo $$p; done | \
+	      sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+	      sort -u`; \
+	test -z "$$locs" || { \
+	  echo rm -f $${locs}; \
+	  rm -f $${locs}; \
+	}
+
+libfactory.la: $(libfactory_la_OBJECTS) $(libfactory_la_DEPENDENCIES) $(EXTRA_libfactory_la_DEPENDENCIES) 
+	$(AM_V_CXXLD)$(libfactory_la_LINK) -rpath $(libdir) $(libfactory_la_OBJECTS) $(libfactory_la_LIBADD) $(LIBS)
+
+clean-checkPROGRAMS:
+	@list='$(check_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
+
+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
+
+cplusplus$(EXEEXT): $(cplusplus_OBJECTS) $(cplusplus_DEPENDENCIES) $(EXTRA_cplusplus_DEPENDENCIES) 
+	@rm -f cplusplus$(EXEEXT)
+	$(AM_V_CXXLD)$(CXXLINK) $(cplusplus_OBJECTS) $(cplusplus_LDADD) $(LIBS)
+
+gengftables$(EXEEXT): $(gengftables_OBJECTS) $(gengftables_DEPENDENCIES) $(EXTRA_gengftables_DEPENDENCIES) 
+	@rm -f gengftables$(EXEEXT)
+	$(AM_V_CXXLD)$(CXXLINK) $(gengftables_OBJECTS) $(gengftables_LDADD) $(LIBS)
+
+test$(EXEEXT): $(test_OBJECTS) $(test_DEPENDENCIES) $(EXTRA_test_DEPENDENCIES) 
+	@rm -f test$(EXEEXT)
+	$(AM_V_CXXLD)$(CXXLINK) $(test_OBJECTS) $(test_LDADD) $(LIBS)
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/DegreePattern.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ExtensionInfo.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/FLINTconvert.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/NTLconvert.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/canonicalform.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cfCharSets.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cfCharSetsUtil.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cfEzgcd.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cfGcdAlgExt.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cfGcdUtil.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cfModGcd.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cfModResultant.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cfNTLzzpEXGCD.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cfNewtonPolygon.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cfSubResGcd.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cfUnivarGcd.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cf_algorithm.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cf_char.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cf_chinese.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cf_cyclo.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cf_eval.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cf_factor.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cf_factory.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cf_gcd.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cf_generator.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cf_globals.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cf_hnf.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cf_inline.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cf_irred.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cf_iter.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cf_iter_inline.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cf_linsys.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cf_map.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cf_map_ext.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cf_ops.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cf_primes.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cf_random.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cf_resultant.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cf_reval.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cf_switches.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cf_util.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cplusplus.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/debug.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/facAbsBiFact.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/facAbsFact.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/facAlgExt.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/facAlgFunc.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/facAlgFuncUtil.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/facBivar.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/facFactorize.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/facFqBivar.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/facFqBivarUtil.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/facFqFactorize.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/facFqFactorizeUtil.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/facFqSquarefree.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/facHensel.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/facIrredTest.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/facMul.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/facSparseHensel.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/fac_sqrfree.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/fac_util.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ffops.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ftmpl_inst.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/gengftables-conway.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/gf_tabutil.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/gfops.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/imm.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/int_cf.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/int_int.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/int_intdiv.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/int_poly.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/int_rat.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/parseutil.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/readcf.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/singext.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/test.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/variable.Plo at am__quote@
+
+.cc.o:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+ at am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXXCOMPILE) -c -o $@ $<
+
+.cc.obj:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+ at am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.cc.lo:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+ at am__fastdepCXX_TRUE@	$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LTCXXCOMPILE) -c -o $@ $<
+
+.yy.cc:
+	$(AM_V_YACC)$(am__skipyacc) $(SHELL) $(YLWRAP) $< y.tab.c $@ y.tab.h `echo $@ | $(am__yacc_c2h)` y.output $*.output -- $(YACCCOMPILE)
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+
+distclean-libtool:
+	-rm -f libtool config.lt
+install-dist_gftablesDATA: $(dist_gftables_DATA)
+	@$(NORMAL_INSTALL)
+	@list='$(dist_gftables_DATA)'; test -n "$(gftablesdir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(gftablesdir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(gftablesdir)" || exit 1; \
+	fi; \
+	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)$(gftablesdir)'"; \
+	  $(INSTALL_DATA) $$files "$(DESTDIR)$(gftablesdir)" || exit $$?; \
+	done
+
+uninstall-dist_gftablesDATA:
+	@$(NORMAL_UNINSTALL)
+	@list='$(dist_gftables_DATA)'; test -n "$(gftablesdir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	dir='$(DESTDIR)$(gftablesdir)'; $(am__uninstall_files_from_dir)
+install-pkgconfigDATA: $(pkgconfig_DATA)
+	@$(NORMAL_INSTALL)
+	@list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(pkgconfigdir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" || exit 1; \
+	fi; \
+	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|^.*/||'`; \
+	dir='$(DESTDIR)$(pkgconfigdir)'; $(am__uninstall_files_from_dir)
+install-nodist_libfactory_includeHEADERS: $(nodist_libfactory_include_HEADERS)
+	@$(NORMAL_INSTALL)
+	@list='$(nodist_libfactory_include_HEADERS)'; test -n "$(libfactory_includedir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(libfactory_includedir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(libfactory_includedir)" || exit 1; \
+	fi; \
+	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)$(libfactory_includedir)'"; \
+	  $(INSTALL_HEADER) $$files "$(DESTDIR)$(libfactory_includedir)" || exit $$?; \
+	done
+
+uninstall-nodist_libfactory_includeHEADERS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(nodist_libfactory_include_HEADERS)'; test -n "$(libfactory_includedir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	dir='$(DESTDIR)$(libfactory_includedir)'; $(am__uninstall_files_from_dir)
+
+# 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.
+$(am__recursive_targets):
+	@fail=; \
+	if $(am__make_keepgoing); then \
+	  failcom='fail=yes'; \
+	else \
+	  failcom='exit 1'; \
+	fi; \
+	dot_seen=no; \
+	target=`echo $@ | sed s/-recursive//`; \
+	case "$@" in \
+	  distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+	  *) list='$(SUBDIRS)' ;; \
+	esac; \
+	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"
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-recursive
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	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; \
+	$(am__define_uniq_tagged_files); \
+	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-recursive
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	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"
+cscope: cscope.files
+	test ! -s cscope.files \
+	  || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS)
+clean-cscope:
+	-rm -f cscope.files
+cscope.files: clean-cscope cscopelist
+cscopelist: cscopelist-recursive
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+	-rm -f cscope.out cscope.in.out cscope.po.out cscope.files
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'.  Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+	rm -f $< $@
+	$(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+	@:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+	@$(am__set_TESTS_bases); \
+	am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+	redo_bases=`for i in $$bases; do \
+	              am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+	            done`; \
+	if test -n "$$redo_bases"; then \
+	  redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+	  redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+	  if $(am__make_dryrun); then :; else \
+	    rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+	  fi; \
+	fi; \
+	if test -n "$$am__remaking_logs"; then \
+	  echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+	       "recursion detected" >&2; \
+	else \
+	  am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+	fi; \
+	if $(am__make_dryrun); then :; else \
+	  st=0;  \
+	  errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+	  for i in $$redo_bases; do \
+	    test -f $$i.trs && test -r $$i.trs \
+	      || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+	    test -f $$i.log && test -r $$i.log \
+	      || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+	  done; \
+	  test $$st -eq 0 || exit 1; \
+	fi
+	@$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+	ws='[ 	]'; \
+	results=`for b in $$bases; do echo $$b.trs; done`; \
+	test -n "$$results" || results=/dev/null; \
+	all=`  grep "^$$ws*:test-result:"           $$results | wc -l`; \
+	pass=` grep "^$$ws*:test-result:$$ws*PASS"  $$results | wc -l`; \
+	fail=` grep "^$$ws*:test-result:$$ws*FAIL"  $$results | wc -l`; \
+	skip=` grep "^$$ws*:test-result:$$ws*SKIP"  $$results | wc -l`; \
+	xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+	xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+	error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+	if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+	  success=true; \
+	else \
+	  success=false; \
+	fi; \
+	br='==================='; br=$$br$$br$$br$$br; \
+	result_count () \
+	{ \
+	    if test x"$$1" = x"--maybe-color"; then \
+	      maybe_colorize=yes; \
+	    elif test x"$$1" = x"--no-color"; then \
+	      maybe_colorize=no; \
+	    else \
+	      echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+	    fi; \
+	    shift; \
+	    desc=$$1 count=$$2; \
+	    if test $$maybe_colorize = yes && test $$count -gt 0; then \
+	      color_start=$$3 color_end=$$std; \
+	    else \
+	      color_start= color_end=; \
+	    fi; \
+	    echo "$${color_start}# $$desc $$count$${color_end}"; \
+	}; \
+	create_testsuite_report () \
+	{ \
+	  result_count $$1 "TOTAL:" $$all   "$$brg"; \
+	  result_count $$1 "PASS: " $$pass  "$$grn"; \
+	  result_count $$1 "SKIP: " $$skip  "$$blu"; \
+	  result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+	  result_count $$1 "FAIL: " $$fail  "$$red"; \
+	  result_count $$1 "XPASS:" $$xpass "$$red"; \
+	  result_count $$1 "ERROR:" $$error "$$mgn"; \
+	}; \
+	{								\
+	  echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" |	\
+	    $(am__rst_title);						\
+	  create_testsuite_report --no-color;				\
+	  echo;								\
+	  echo ".. contents:: :depth: 2";				\
+	  echo;								\
+	  for b in $$bases; do echo $$b; done				\
+	    | $(am__create_global_log);					\
+	} >$(TEST_SUITE_LOG).tmp || exit 1;				\
+	mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG);			\
+	if $$success; then						\
+	  col="$$grn";							\
+	 else								\
+	  col="$$red";							\
+	  test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG);		\
+	fi;								\
+	echo "$${col}$$br$${std}"; 					\
+	echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}";	\
+	echo "$${col}$$br$${std}"; 					\
+	create_testsuite_report --maybe-color;				\
+	echo "$$col$$br$$std";						\
+	if $$success; then :; else					\
+	  echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}";		\
+	  if test -n "$(PACKAGE_BUGREPORT)"; then			\
+	    echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}";	\
+	  fi;								\
+	  echo "$$col$$br$$std";					\
+	fi;								\
+	$$success || exit 1
+
+check-TESTS:
+	@list='$(RECHECK_LOGS)';           test -z "$$list" || rm -f $$list
+	@list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+	@test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+	@set +e; $(am__set_TESTS_bases); \
+	log_list=`for i in $$bases; do echo $$i.log; done`; \
+	trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+	log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+	$(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+	exit $$?;
+recheck: all $(check_PROGRAMS)
+	@test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+	@set +e; $(am__set_TESTS_bases); \
+	bases=`for i in $$bases; do echo $$i; done \
+	         | $(am__list_recheck_tests)` || exit 1; \
+	log_list=`for i in $$bases; do echo $$i.log; done`; \
+	log_list=`echo $$log_list`; \
+	$(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+	        am__force_recheck=am--force-recheck \
+	        TEST_LOGS="$$log_list"; \
+	exit $$?
+test.log: test$(EXEEXT)
+	@p='test$(EXEEXT)'; \
+	b='test'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+.test.log:
+	@p='$<'; \
+	$(am__set_b); \
+	$(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+ at am__EXEEXT_TRUE@.test$(EXEEXT).log:
+ at am__EXEEXT_TRUE@	@p='$<'; \
+ at am__EXEEXT_TRUE@	$(am__set_b); \
+ at am__EXEEXT_TRUE@	$(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ at am__EXEEXT_TRUE@	--log-file $$b.log --trs-file $$b.trs \
+ at am__EXEEXT_TRUE@	$(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ at am__EXEEXT_TRUE@	"$$tst" $(AM_TESTS_FD_REDIRECT)
+
+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 \
+	    $(am__make_dryrun) \
+	      || test -d "$(distdir)/$$subdir" \
+	      || $(MKDIR_P) "$(distdir)/$$subdir" \
+	      || exit 1; \
+	    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 -755 \
+		-exec chmod u+rwx,go+rx {} \; -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__post_remove_distdir)
+
+dist-bzip2: distdir
+	tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2
+	$(am__post_remove_distdir)
+
+dist-lzip: distdir
+	tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz
+	$(am__post_remove_distdir)
+
+dist-xz: distdir
+	tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz
+	$(am__post_remove_distdir)
+
+dist-tarZ: distdir
+	tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
+	$(am__post_remove_distdir)
+
+dist-shar: distdir
+	shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
+	$(am__post_remove_distdir)
+
+dist-zip: distdir
+	-rm -f $(distdir).zip
+	zip -rq $(distdir).zip $(distdir)
+	$(am__post_remove_distdir)
+
+dist dist-all:
+	$(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:'
+	$(am__post_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) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\
+	*.tar.bz2*) \
+	  bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
+	*.tar.lz*) \
+	  lzip -dc $(distdir).tar.lz | $(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) gzip -dc $(distdir).shar.gz | unshar ;;\
+	*.zip*) \
+	  unzip $(distdir).zip ;;\
+	esac
+	chmod -R a-w $(distdir)
+	chmod u+w $(distdir)
+	mkdir $(distdir)/_build $(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" \
+	    $(AM_DISTCHECK_CONFIGURE_FLAGS) \
+	    $(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__post_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:
+	@test -n '$(distuninstallcheck_dir)' || { \
+	  echo 'ERROR: trying to run $@ with an empty' \
+	       '$$(distuninstallcheck_dir)' >&2; \
+	  exit 1; \
+	}; \
+	$(am__cd) '$(distuninstallcheck_dir)' || { \
+	  echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \
+	  exit 1; \
+	}; \
+	test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \
+	   || { 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
+	$(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS)
+	$(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: $(BUILT_SOURCES)
+	$(MAKE) $(AM_MAKEFLAGS) check-recursive
+all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(DATA) $(HEADERS) \
+		_config.h all-local
+installdirs: installdirs-recursive
+installdirs-am:
+	for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(gftablesdir)" "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(libfactory_includedir)"; 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:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+	-test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+	-test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+	-test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+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)
+	-test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+	-rm -f readcf.cc
+	-test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
+clean: clean-recursive
+
+clean-am: clean-checkPROGRAMS clean-generic clean-libLTLIBRARIES \
+	clean-libtool clean-noinstPROGRAMS mostlyclean-am
+
+distclean: distclean-recursive
+	-rm -f $(am__CONFIG_DISTCLEAN_FILES)
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+distclean-am: clean-am distclean-compile 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-dist_gftablesDATA \
+	install-nodist_libfactory_includeHEADERS install-pkgconfigDATA
+
+install-dvi: install-dvi-recursive
+
+install-dvi-am:
+
+install-exec-am: install-libLTLIBRARIES
+
+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 -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-dist_gftablesDATA uninstall-libLTLIBRARIES \
+	uninstall-nodist_libfactory_includeHEADERS \
+	uninstall-pkgconfigDATA
+
+.MAKE: $(am__recursive_targets) all check check-am install install-am \
+	install-strip
+
+.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am all-local \
+	am--refresh check check-TESTS check-am clean \
+	clean-checkPROGRAMS clean-cscope clean-generic \
+	clean-libLTLIBRARIES clean-libtool clean-noinstPROGRAMS cscope \
+	cscopelist-am ctags ctags-am dist dist-all dist-bzip2 \
+	dist-gzip dist-lzip dist-shar dist-tarZ dist-xz dist-zip \
+	distcheck distclean distclean-compile 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-dist_gftablesDATA install-dvi install-dvi-am \
+	install-exec install-exec-am install-html install-html-am \
+	install-info install-info-am install-libLTLIBRARIES \
+	install-man install-nodist_libfactory_includeHEADERS \
+	install-pdf install-pdf-am install-pkgconfigDATA 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 \
+	recheck tags tags-am uninstall uninstall-am \
+	uninstall-dist_gftablesDATA uninstall-libLTLIBRARIES \
+	uninstall-nodist_libfactory_includeHEADERS \
+	uninstall-pkgconfigDATA
+
+
+ at DX_COND_doc_TRUE@@DX_COND_ps_TRUE at doxygen-ps: @DX_DOCDIR@/@PACKAGE at .ps
+
+ at DX_COND_doc_TRUE@@DX_COND_ps_TRUE@@DX_DOCDIR@/@PACKAGE at .ps: @DX_DOCDIR@/@PACKAGE at .tag
+ at DX_COND_doc_TRUE@@DX_COND_ps_TRUE@	cd @DX_DOCDIR@/latex; \
+ at DX_COND_doc_TRUE@@DX_COND_ps_TRUE@	rm -f *.aux *.toc *.idx *.ind *.ilg *.log *.out; \
+ at DX_COND_doc_TRUE@@DX_COND_ps_TRUE@	$(DX_LATEX) refman.tex; \
+ at DX_COND_doc_TRUE@@DX_COND_ps_TRUE@	$(MAKEINDEX_PATH) refman.idx; \
+ at DX_COND_doc_TRUE@@DX_COND_ps_TRUE@	$(DX_LATEX) refman.tex; \
+ at DX_COND_doc_TRUE@@DX_COND_ps_TRUE@	countdown=5; \
+ at DX_COND_doc_TRUE@@DX_COND_ps_TRUE@	while $(DX_EGREP) 'Rerun (LaTeX|to get cross-references right)' \
+ at DX_COND_doc_TRUE@@DX_COND_ps_TRUE@	                  refman.log > /dev/null 2>&1 \
+ at DX_COND_doc_TRUE@@DX_COND_ps_TRUE@	   && test $$countdown -gt 0; do \
+ at DX_COND_doc_TRUE@@DX_COND_ps_TRUE@	    $(DX_LATEX) refman.tex; \
+ at DX_COND_doc_TRUE@@DX_COND_ps_TRUE@	    countdown=`expr $$countdown - 1`; \
+ at DX_COND_doc_TRUE@@DX_COND_ps_TRUE@	done; \
+ at DX_COND_doc_TRUE@@DX_COND_ps_TRUE@	$(DX_DVIPS) -o ../@PACKAGE at .ps refman.dvi
+
+ at DX_COND_doc_TRUE@@DX_COND_pdf_TRUE at doxygen-pdf: @DX_DOCDIR@/@PACKAGE at .pdf
+
+ at DX_COND_doc_TRUE@@DX_COND_pdf_TRUE@@DX_DOCDIR@/@PACKAGE at .pdf: @DX_DOCDIR@/@PACKAGE at .tag
+ at DX_COND_doc_TRUE@@DX_COND_pdf_TRUE@	cd @DX_DOCDIR@/latex; \
+ at DX_COND_doc_TRUE@@DX_COND_pdf_TRUE@	rm -f *.aux *.toc *.idx *.ind *.ilg *.log *.out; \
+ at DX_COND_doc_TRUE@@DX_COND_pdf_TRUE@	$(DX_PDFLATEX) refman.tex; \
+ at DX_COND_doc_TRUE@@DX_COND_pdf_TRUE@	$(DX_MAKEINDEX) refman.idx; \
+ at DX_COND_doc_TRUE@@DX_COND_pdf_TRUE@	$(DX_PDFLATEX) refman.tex; \
+ at DX_COND_doc_TRUE@@DX_COND_pdf_TRUE@	countdown=5; \
+ at DX_COND_doc_TRUE@@DX_COND_pdf_TRUE@	while $(DX_EGREP) 'Rerun (LaTeX|to get cross-references right)' \
+ at DX_COND_doc_TRUE@@DX_COND_pdf_TRUE@	                  refman.log > /dev/null 2>&1 \
+ at DX_COND_doc_TRUE@@DX_COND_pdf_TRUE@	   && test $$countdown -gt 0; do \
+ at DX_COND_doc_TRUE@@DX_COND_pdf_TRUE@	    $(DX_PDFLATEX) refman.tex; \
+ at DX_COND_doc_TRUE@@DX_COND_pdf_TRUE@	    countdown=`expr $$countdown - 1`; \
+ at DX_COND_doc_TRUE@@DX_COND_pdf_TRUE@	done; \
+ at DX_COND_doc_TRUE@@DX_COND_pdf_TRUE@	mv refman.pdf ../@PACKAGE at .pdf
+
+ at DX_COND_doc_TRUE@.PHONY: doxygen-run doxygen-doc $(DX_PS_GOAL) $(DX_PDF_GOAL)
+
+ at DX_COND_doc_TRUE@.INTERMEDIATE: doxygen-run $(DX_PS_GOAL) $(DX_PDF_GOAL)
+
+ at DX_COND_doc_TRUE@doxygen-run: @DX_DOCDIR@/@PACKAGE at .tag
+
+ at DX_COND_doc_TRUE@doxygen-doc: doxygen-run $(DX_PS_GOAL) $(DX_PDF_GOAL)
+
+ at DX_COND_doc_TRUE@@DX_DOCDIR@/@PACKAGE at .tag: $(DX_CONFIG) $(pkginclude_HEADERS)
+ at DX_COND_doc_TRUE@	rm -rf @DX_DOCDIR@
+ at DX_COND_doc_TRUE@	$(DX_ENV) $(DX_DOXYGEN) $(srcdir)/$(DX_CONFIG)
+
+cplusplus.h: cplusplus$(EXEEXT)
+	./cplusplus$(EXEEXT)  >$@
+	cp $@ include/factory/
+
+.template.h:
+	${srcdir}/bin/makeheader $< $@
+	cp $@ include/factory/
+
+# factory/gfops.cc has the gftables path hardcoded in, so we create a
+# symlink. Remove this rule once gfopts.cc has been fixed. Note that
+# check-local would run in parallel with check, so we can't use it
+# here!
+all-local:
+	[ -d ${builddir}/gftables ] || ln -s ${srcdir}/gftables ${builddir}
+
+# 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/factory/NEWS b/factory/NEWS
new file mode 100644
index 0000000..24e6f26
--- /dev/null
+++ b/factory/NEWS
@@ -0,0 +1,137 @@
+Thu Nov  7 11:31:58 MET 2002  Hans Schoenemann <hannes at mathematik.uni-kl.de>
+interface to NTL (optional, recommended): tested with NTL 5.2, 5.3
+bug fixes for multivariate factorization
+
+Tue Apr 10 15:24:49 CEST 2001 Hans Schoenemann <hannes at mathematik.uni-kl.de>
+several small bugs fixed (mostly memory leaks)
+changed copyright to GPL
+
+Tue Oct 28 14:46:08 1997  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+New features in Factory, version 1.3b:
+======================================
+Distribution and organization level:
+------------------------------------
+o The new external variable `factoryConfiguration' describes the
+  configuration Factory has been translated with.
+o If configuring for cross compiling `configure' assumes that the target
+  machine has arithmetic shift.
+o Parts of Factory are written using `folding-mode' for GNU Emacs.  Since
+  this is a really useful feature `folding.el' has been added to the
+  distribution.
+o The new `make' target `installtest' in the top level `GNUmakefile' tests
+  whether the installation has been successful.
+o The new directory `examples/' contains some example applications for
+  Factory and a `GNUmakefile' to build them.
+
+Source code level:
+------------------
+o The main interface to Factory, the class `CanonicalForm' has been (almost
+  completely) revised.  During this process, a number of smaller bugs has
+  been fixed (most of the bugs concerning some more or less exceptional
+  cases).  Furthermore, many of the methods became a little bit faster,
+  some of them became a lot faster (e.g., the evaluation-`operator() ()' uses
+  Horner's rule now, `degree( const & Variable )' and `deriv( const &
+  Variable)' do not use expensive calls to `swapvar()' any longer).
+o In the same way, I have begun to revise the gcd calculations, but there is
+  still is a lot of work to do.  As a first result, gcd calculations over Z
+  became faster (up to a factor of two for large examples).
+
+Other bug fixes:
+o A serious bug in `resultant()' has been fixed.
+o `gcd()' works correctly now for polynomials with rational coefficients.
+  However, `factorize()' still does not, and you have to multiply with the
+  common denominator before factorizing.
+o `psr( CF f, CF g, Var x )', `psq()', `psrq()' work correctly now if
+  degree(f) < degree(g).  However, they still do not work correctly if
+  either in divisor or dividend occur variables with level higher than
+  x's level.
+o A bug in `CanonicalForm::sqrt()' has been fixed which in some cases made
+  `factorize()' crash.
+
+Changes:
+o If CO has not a denominator `CanonicalForm::den()' returns now the unity
+  from the current domain, not the unity from the domain of CO.
+o `chineseRemainder()' works now for polynomials over Z instead for elements
+  of Z only.
+o `cden()' computes the common denominator with respect to algebraic
+  variables, too, so multiplying with `cden()' in any case results in an
+  object with integral coefficients
+
+New features:
+o The new function `subResChain()' returns the extended subresultant chain
+  of two polynomials.
+o The new function `replacevar()' replaces one variable with another.  In
+  contrast to `swapvar()', this works for algebraic variables, too.
+o The new function `size()' returns the number of monomials occuring in a
+  `CanonicalForm'.
+o The new method `CanonicalForm::Lc()' returns the leading coefficient of
+  CO, where elements from an algebraic extension are considered
+  coefficients, and not polynomials.
+

+Thu Jul 17 10:15:59 1997  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+New features in Factory, version 1.3a:
+======================================
+  Besides minor changes at "source code level" (bug fixes, new features)
+which are not really visible to the user in general there are quite a lot
+of changes at "organization level" (aka "preprocessor level") and at
+"distribution level" (`configure', `GNUmakefile').
+
+
+Source code level:
+------------------
+o Serious bug in univariate factorization in characterstic 0 fixed (by
+  Ruediger Stobbe).
+
+o New gcd algorithm (sparse modular), not fully tested by now (contributed
+  by Marion Bruder).  Switch on with `SW_USE_SPARSEMOD'.
+
+o Various minor bug fixes.
+
+
+Organization level:
+-------------------
+o Factory translates now on Macintosh with Metroworks
+  CodeWarrior Academic Pro 11 (changes by Wilfred Pohl)
+
+o So called "new" memory manager (written by Ruediger Stobbe) added to
+  distribution.  So far no timigs available which memory manager is faster.
+
+o "ASSERT", "DEBOUT", "TIMING macros" streamlined
+
+o Factory's IO completely re-organized (that was a mess!).  It is now
+  possible to switch off everything which is related to stream IO (use
+  `--disbale-streamio' option to `configure').  This way it is possible to
+  link Factory without `libg++.a' or `libiostream.a'.  Changes include:
+
+  - everything related to stream IO wrapped by `#ifndef NOSTREAMIO'
+  - all error messages/debug output messages rewritten so that they use the
+    "ASSERT" and "DEBOUT macros"
+  - furthermore, it was necessary to change the way the GF(q) tables are
+    read.  As a consequence, the format of the GF(q) tables slightly
+    changed, too.  You have to generate/get them from net by new.
+
+
+Distribution level:
+-------------------
+o The organization of the distribution as well as the compile/install
+  procedure totally changed.  It is now more GNU-like.  See the `INSTALL'
+  file and the `README' file for more information.
+
+o The file names of the template sources changed.  To make them less
+  canonical, all names are prefixed with `ftmpl_' ("Factory template") now.
+
+o The installation target directories and their structure changed a little
+  bit.  See the `INSTALL' file for more information.
+
+
+

+Before May 3 1997  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+New features in Factory, version 1.2c:
+======================================
+  Version 1.2c is a more or less inofficial version distributed with
+Singular 1.0.  I hope it does not distribute too far...  The description of
+new features to version 1.3a cope the description of new features to this
+version.
diff --git a/factory/NTLconvert.cc b/factory/NTLconvert.cc
new file mode 100644
index 0000000..41ce9b2
--- /dev/null
+++ b/factory/NTLconvert.cc
@@ -0,0 +1,1219 @@
+
+#include "config.h"
+
+
+#include "cf_assert.h"
+
+#include "cf_defs.h"
+#include "canonicalform.h"
+#include "cf_iter.h"
+#include "fac_sqrfree.h"
+#include "cf_algorithm.h"
+
+#include <factory/cf_gmp.h>
+
+#ifdef HAVE_NTL
+#ifndef NOSTREAMIO
+#ifdef HAVE_CSTDIO
+#include <cstdio>
+#else
+#include <stdio.h>
+#endif
+#endif
+#include <string.h>
+#include <NTL/ZZXFactoring.h>
+#include <NTL/ZZ_pXFactoring.h>
+#include <NTL/lzz_pXFactoring.h>
+#include <NTL/GF2XFactoring.h>
+#include <NTL/ZZ_pEXFactoring.h>
+#include <NTL/lzz_pEXFactoring.h>
+#include <NTL/GF2EXFactoring.h>
+#include <NTL/tools.h>
+#include <NTL/mat_ZZ.h>
+#include "int_int.h"
+#include <limits.h>
+#include "NTLconvert.h"
+
+#define Alloc(L) malloc(L)
+#define Free(A,L) free(A)
+
+void out_cf(const char *s1,const CanonicalForm &f,const char *s2);
+
+
+long fac_NTL_char = -1;         // the current characterstic for NTL calls
+                                // -1: undefined
+#ifdef NTL_CLIENT               // in <NTL/tools.h>: using of name space NTL
+NTL_CLIENT
+#endif
+
+////////////////////////////////////////////////////////////////////////////////
+/// NAME: convertFacCF2NTLZZpX
+///
+/// DESCRIPTION:
+/// Conversion routine for Factory-type canonicalform into ZZpX of NTL,
+/// i.e. polynomials over F_p. As a precondition for correct execution,
+/// the characteristic has to a a prime number.
+///
+/// INPUT:  A canonicalform f
+/// OUTPUT: The converted NTL-polynomial over F_p of type ZZpX
+////////////////////////////////////////////////////////////////////////////////
+
+ZZ_pX convertFacCF2NTLZZpX(const CanonicalForm & f)
+{
+  ZZ_pX ntl_poly;
+
+  CFIterator i;
+  i=f;
+
+  int NTLcurrentExp=i.exp();
+  int largestExp=i.exp();
+  int k;
+
+  // we now build up the NTL-polynomial
+  ntl_poly.SetMaxLength(largestExp+1);
+
+  for (;i.hasTerms();i++)
+  {
+    for (k=NTLcurrentExp;k>i.exp();k--)
+    {
+      SetCoeff(ntl_poly,k,0);
+    }
+    NTLcurrentExp=i.exp();
+
+    SetCoeff(ntl_poly,NTLcurrentExp,to_ZZ_p (convertFacCF2NTLZZ (i.coeff())));
+    NTLcurrentExp--;
+  }
+
+  //Set the remaining coefficients of ntl_poly to zero.
+  // This is necessary, because NTL internally
+  // also stores powers with zero coefficient,
+  // whereas factory stores tuples of degree and coefficient
+  //leaving out tuples if the coefficient equals zero
+  for (k=NTLcurrentExp;k>=0;k--)
+  {
+    SetCoeff(ntl_poly,k,0);
+  }
+
+  //normalize the polynomial and return it
+  ntl_poly.normalize();
+
+  return ntl_poly;
+}
+zz_pX convertFacCF2NTLzzpX(const CanonicalForm & f)
+{
+  zz_pX ntl_poly;
+
+  CFIterator i;
+  i=f;
+
+  int NTLcurrentExp=i.exp();
+  int largestExp=i.exp();
+  int k;
+
+  // we now build up the NTL-polynomial
+  ntl_poly.SetMaxLength(largestExp+1);
+
+  for (;i.hasTerms();i++)
+  {
+    for (k=NTLcurrentExp;k>i.exp();k--)
+    {
+      SetCoeff(ntl_poly,k,0);
+    }
+    NTLcurrentExp=i.exp();
+
+    CanonicalForm c=i.coeff();
+    if (!c.isImm()) c=c.mapinto(); //c%= getCharacteristic();
+    if (!c.isImm())
+    {  //This case will never happen if the characteristic is in fact a prime
+       // number, since all coefficients are represented as immediates
+       #ifndef NOSTREAMIO
+       cout<<"convertFacCF2NTLzz_pX: coefficient not immediate! : "<<f<<"\n";
+       #else
+       //NTL_SNS
+       printf("convertFacCF2NTLzz_pX: coefficient not immediate!, char=%d\n",
+              getCharacteristic());
+       #endif
+       NTL_SNS exit(1);
+    }
+    else
+    {
+      SetCoeff(ntl_poly,NTLcurrentExp,c.intval());
+    }
+    NTLcurrentExp--;
+  }
+
+  //Set the remaining coefficients of ntl_poly to zero.
+  // This is necessary, because NTL internally
+  // also stores powers with zero coefficient,
+  // whereas factory stores tuples of degree and coefficient
+  //leaving out tuples if the coefficient equals zero
+  for (k=NTLcurrentExp;k>=0;k--)
+  {
+    SetCoeff(ntl_poly,k,0);
+  }
+
+  //normalize the polynomial and return it
+  ntl_poly.normalize();
+
+  return ntl_poly;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/// NAME: convertFacCF2NTLGF2X
+///
+/// DESCRIPTION:
+/// Conversion routine for Factory-type canonicalform into GF2X of NTL,
+/// i.e. polynomials over F_2. As precondition for correct execution,
+/// the characteristic must equal two.
+/// This is a special case of the more general conversion routine for
+/// canonicalform to ZZpX. It is included because NTL provides additional
+/// support and faster algorithms over F_2, moreover the conversion code
+/// can be optimized, because certain steps are either completely obsolent
+/// (like normalizing the polynomial) or they can be made significantly
+/// faster (like building up the NTL-polynomial).
+///
+/// INPUT:  A canonicalform f
+/// OUTPUT: The converted NTL-polynomial over F_2 of type GF2X
+////////////////////////////////////////////////////////////////////////////////
+
+GF2X convertFacCF2NTLGF2X(const CanonicalForm & f)
+{
+  //printf("convertFacCF2NTLGF2X\n");
+  GF2X ntl_poly;
+
+  CFIterator i;
+  i=f;
+
+  int NTLcurrentExp=i.exp();
+  int largestExp=i.exp();
+  int k;
+
+  //building the NTL-polynomial
+  ntl_poly.SetMaxLength(largestExp+1);
+
+  for (;i.hasTerms();i++)
+  {
+
+    for (k=NTLcurrentExp;k>i.exp();k--)
+    {
+      SetCoeff(ntl_poly,k,0);
+    }
+    NTLcurrentExp=i.exp();
+
+    if (!i.coeff().isImm()) i.coeff()=i.coeff().mapinto();
+    if (!i.coeff().isImm())
+    {
+      #ifndef NOSTREAMIO
+      cout<<"convertFacCF2NTLGF2X: coefficient not immidiate! : " << f << "\n";
+      #else
+      //NTL_SNS
+      printf("convertFacCF2NTLGF2X: coefficient not immidiate!");
+      #endif
+      NTL_SNS exit(1);
+    }
+    else
+    {
+      SetCoeff(ntl_poly,NTLcurrentExp,i.coeff().intval());
+    }
+    NTLcurrentExp--;
+  }
+  for (k=NTLcurrentExp;k>=0;k--)
+  {
+    SetCoeff(ntl_poly,k,0);
+  }
+  //normalization is not necessary of F_2
+
+  return ntl_poly;
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+/// NAME: convertNTLZZpX2CF
+///
+/// DESCRIPTION:
+/// Conversion routine for NTL-Type ZZpX to Factory-Type canonicalform.
+/// Additionally a variable x is needed as a parameter indicating the
+/// main variable of the computed canonicalform. To guarantee the correct
+/// execution of the algorithm, the characteristic has a be an arbitrary
+/// prime number.
+///
+/// INPUT:  A canonicalform f, a variable x
+/// OUTPUT: The converted Factory-polynomial of type canonicalform,
+///         built by the main variable x
+////////////////////////////////////////////////////////////////////////////////
+
+CanonicalForm convertNTLZZpX2CF(const ZZ_pX & poly,const Variable & x)
+{
+  return convertNTLZZX2CF (to_ZZX (poly), x);
+}
+
+CanonicalForm convertNTLzzpX2CF(const zz_pX & poly,const Variable & x)
+{
+  //printf("convertNTLzzpX2CF\n");
+  CanonicalForm bigone;
+
+
+  if (deg(poly)>0)
+  {
+    // poly is non-constant
+    bigone=0;
+    bigone.mapinto();
+    // Compute the canonicalform coefficient by coefficient,
+    // bigone summarizes the result.
+    for (int j=0;j<=deg(poly);j++)
+    {
+      if (coeff(poly,j)!=0)
+      {
+        bigone+=(power(x,j)*CanonicalForm(to_long(rep(coeff(poly,j)))));
+      }
+    }
+  }
+  else
+  {
+    // poly is immediate
+    bigone=CanonicalForm(to_long(rep(coeff(poly,0))));
+    bigone.mapinto();
+  }
+  return bigone;
+}
+
+CanonicalForm convertNTLZZX2CF(const ZZX & polynom,const Variable & x)
+{
+  //printf("convertNTLZZX2CF\n");
+  CanonicalForm bigone;
+
+  // Go through the vector e and build up the CFFList
+  // As usual bigone summarizes the result
+  bigone=0;
+  ZZ coefficient;
+
+  for (int j=0;j<=deg(polynom);j++)
+  {
+    coefficient=coeff(polynom,j);
+    if (!IsZero(coefficient))
+    {
+      bigone += (power(x,j)*convertZZ2CF(coefficient));
+    }
+  }
+  return bigone;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/// NAME: convertNTLGF2X2CF
+///
+/// DESCRIPTION:
+/// Conversion routine for NTL-Type GF2X to Factory-Type canonicalform,
+/// the routine is again an optimized special case of the more general
+/// conversion to ZZpX. Additionally a variable x is needed as a
+/// parameter indicating the main variable of the computed canonicalform.
+/// To guarantee the correct execution of the algorithm the characteristic
+/// has a be an arbitrary prime number.
+///
+/// INPUT:  A canonicalform f, a variable x
+/// OUTPUT: The converted Factory-polynomial of type canonicalform,
+///         built by the main variable x
+////////////////////////////////////////////////////////////////////////////////
+
+CanonicalForm convertNTLGF2X2CF(const GF2X & poly,const Variable & x)
+{
+  //printf("convertNTLGF2X2CF\n");
+  CanonicalForm bigone;
+
+  if (deg(poly)>0)
+  {
+    // poly is non-constant
+    bigone=0;
+    bigone.mapinto();
+    // Compute the canonicalform coefficient by coefficient,
+    // bigone summarizes the result.
+    // In constrast to the more general conversion to ZZpX
+    // the only possible coefficients are zero
+    // and one yielding the following simplified loop
+    for (int j=0;j<=deg(poly);j++)
+    {
+      if (coeff(poly,j)!=0) bigone+=power(x,j);
+     // *CanonicalForm(to_long(rep(coeff(poly,j))))) is not necessary any more;
+    }
+  }
+  else
+  {
+    // poly is immediate
+    bigone=CanonicalForm(to_long(rep(coeff(poly,0))));
+    bigone.mapinto();
+  }
+
+  return bigone;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/// NAME: convertNTLvec_pair_ZZpX_long2FacCFFList
+///
+/// DESCRIPTION:
+/// Routine for converting a vector of polynomials from ZZpX to
+/// a CFFList of Factory. This routine will be used after a successful
+/// factorization of NTL to convert the result back to Factory.
+///
+/// Additionally a variable x and the computed multiplicity, as a type ZZp
+/// of NTL, is needed as parameters indicating the main variable of the
+/// computed canonicalform and the multiplicity of the original polynomial.
+/// To guarantee the correct execution of the algorithm the characteristic
+/// has a be an arbitrary prime number.
+///
+/// INPUT:  A vector of polynomials over ZZp of type vec_pair_ZZ_pX_long and
+///         a variable x and a multiplicity of type ZZp
+/// OUTPUT: The converted list of polynomials of type CFFList, all polynomials
+///         have x as their main variable
+////////////////////////////////////////////////////////////////////////////////
+
+CFFList convertNTLvec_pair_ZZpX_long2FacCFFList
+                                  (const vec_pair_ZZ_pX_long & e,const ZZ_p & multi,const Variable & x)
+{
+  //printf("convertNTLvec_pair_ZZpX_long2FacCFFList\n");
+  CFFList result;
+  ZZ_pX polynom;
+  CanonicalForm bigone;
+
+  // Maybe, e may additionally be sorted with respect to increasing degree of x
+  // but this is not
+  //important for the factorization, but nevertheless would take computing time,
+  // so it is omitted
+
+
+  // Go through the vector e and compute the CFFList
+  // again bigone summarizes the result
+  for (int i=e.length()-1;i>=0;i--)
+  {
+    result.append(CFFactor(convertNTLZZpX2CF(e[i].a,x),e[i].b));
+  }
+  // the multiplicity at pos 1
+  if (!IsOne(multi))
+    result.insert(CFFactor(CanonicalForm(to_long(rep(multi))),1));
+  return result;
+}
+CFFList convertNTLvec_pair_zzpX_long2FacCFFList
+                                  (const vec_pair_zz_pX_long & e,const zz_p multi,const Variable & x)
+{
+  //printf("convertNTLvec_pair_zzpX_long2FacCFFList\n");
+  CFFList result;
+  zz_pX polynom;
+  CanonicalForm bigone;
+
+  // Maybe, e may additionally be sorted with respect to increasing degree of x
+  // but this is not
+  //important for the factorization, but nevertheless would take computing time,
+  // so it is omitted
+
+
+  // Go through the vector e and compute the CFFList
+  // again bigone summarizes the result
+  for (int i=e.length()-1;i>=0;i--)
+  {
+    result.append(CFFactor(convertNTLzzpX2CF(e[i].a,x),e[i].b));
+  }
+  // the multiplicity at pos 1
+  if (!IsOne(multi))
+    result.insert(CFFactor(CanonicalForm(to_long(rep(multi))),1));
+  return result;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/// NAME: convertNTLvec_pair_GF2X_long2FacCFFList
+///
+/// DESCRIPTION:
+/// Routine for converting a vector of polynomials of type GF2X from
+/// NTL to a list CFFList of Factory. This routine will be used after a
+/// successful factorization of NTL to convert the result back to Factory.
+/// As usual this is simply a special case of the more general conversion
+/// routine but again speeded up by leaving out unnecessary steps.
+/// Additionally a variable x and the computed multiplicity, as type
+/// GF2 of NTL, are needed as parameters indicating the main variable of the
+/// computed canonicalform and the multiplicity of the original polynomial.
+/// To guarantee the correct execution of the algorithm the characteristic
+/// has a be an arbitrary prime number.
+///
+/// INPUT:  A vector of polynomials over GF2 of type vec_pair_GF2X_long and
+///         a variable x and a multiplicity of type GF2
+/// OUTPUT: The converted list of polynomials of type CFFList, all
+///         polynomials have x as their main variable
+////////////////////////////////////////////////////////////////////////////////
+
+CFFList convertNTLvec_pair_GF2X_long2FacCFFList
+    (const vec_pair_GF2X_long& e, GF2 /*multi*/, const Variable & x)
+{
+  //printf("convertNTLvec_pair_GF2X_long2FacCFFList\n");
+  CFFList result;
+  GF2X polynom;
+  long exponent;
+  CanonicalForm bigone;
+
+  // Maybe, e may additionally be sorted with respect to increasing degree of x
+  // but this is not
+  //important for the factorization, but nevertheless would take computing time
+  // so it is omitted.
+
+  //We do not have to worry about the multiplicity in GF2 since it equals one.
+
+  // Go through the vector e and compute the CFFList
+  // bigone summarizes the result again
+  for (int i=e.length()-1;i>=0;i--)
+  {
+    bigone=0;
+
+    polynom=e[i].a;
+    exponent=e[i].b;
+    for (int j=0;j<=deg(polynom);j++)
+    {
+      if (coeff(polynom,j)!=0)
+        bigone += (power(x,j)*CanonicalForm(to_long(rep(coeff(polynom,j)))));
+    }
+
+    //append the converted polynomial to the CFFList
+    result.append(CFFactor(bigone,exponent));
+  }
+  return result;
+}
+
+static unsigned char *cf_stringtemp;
+static unsigned long cf_stringtemp_l=0L;
+////////////////////////////////////////////////////////////////////////////////
+/// NAME: convertZZ2CF
+///
+/// DESCRIPTION:
+/// Routine for conversion of integers represented in NTL as Type ZZ to
+/// integers in Factory represented as canonicalform.
+/// To guarantee the correct execution of the algorithm the characteristic
+/// has to equal zero.
+///
+/// INPUT:  The value coefficient of type ZZ that has to be converted
+/// OUTPUT: The converted Factory-integer of type canonicalform
+////////////////////////////////////////////////////////////////////////////////
+CanonicalForm
+convertZZ2CF (const ZZ & a)
+{
+  long coeff_long=to_long(a);
+
+  CanonicalForm result;
+  if ( (NumBits(a)<((long)NTL_ZZ_NBITS))
+  && (coeff_long>((long)MINIMMEDIATE))
+  && (coeff_long<((long)MAXIMMEDIATE)))
+  {
+    return CanonicalForm(coeff_long);
+  }
+  else
+  {
+    long sizeofrep= ((long *) a.rep) [1];
+    bool lessZero= false;
+    if (sizeofrep < 0)
+    {
+      lessZero= true;
+      sizeofrep= -sizeofrep;
+    }
+    if (cf_stringtemp_l == 0)
+    {
+      cf_stringtemp_l= sizeofrep*sizeof(mp_limb_t)*2;
+      cf_stringtemp= (unsigned char*) Alloc (cf_stringtemp_l);
+    }
+    else if (cf_stringtemp_l < sizeofrep*sizeof(mp_limb_t)*2)
+    {
+      Free (cf_stringtemp, cf_stringtemp_l);
+      cf_stringtemp_l= sizeofrep*sizeof(mp_limb_t)*2;
+      cf_stringtemp= (unsigned char*) Alloc (cf_stringtemp_l);
+    }
+    int cc= mpn_get_str (cf_stringtemp, 16, (mp_limb_t *) (((long *) (a.rep)) + 2), sizeofrep);
+
+    char* cf_stringtemp2;
+    if (lessZero)
+    {
+      cf_stringtemp2= new char [cc + 2];
+      cf_stringtemp2[0]='-';
+      for (int j= 1; j <= cc; j++)
+        cf_stringtemp2[j]= IntValToChar ((int) cf_stringtemp [j-1]);
+      cf_stringtemp2[cc+1]='\0';
+    }
+    else
+    {
+      cf_stringtemp2= new char [cc + 1];
+      for (int j= 0; j < cc; j++)
+        cf_stringtemp2[j]= IntValToChar ((int) cf_stringtemp [j]);
+      cf_stringtemp2[cc]='\0';
+    }
+
+    result= CanonicalForm (cf_stringtemp2, 16);
+    delete [] cf_stringtemp2;
+    return result;
+  }
+  return result;
+}
+
+/*static char *cf_stringtemp;
+static char *cf_stringtemp2;
+static int cf_stringtemp_l=0;
+CanonicalForm convertZZ2CF(const ZZ & coefficient)
+{
+  long coeff_long;
+  //CanonicalForm tmp=0;
+  char dummy[2];
+  int minusremainder=0;
+  char numbers[]="0123456789abcdef";
+
+  coeff_long=to_long(coefficient);
+
+  //Test whether coefficient can be represented as an immediate integer in Factory
+  if ( (NumBits(coefficient)<((long)NTL_ZZ_NBITS))
+  && (coeff_long>((long)MINIMMEDIATE))
+  && (coeff_long<((long)MAXIMMEDIATE)))
+  {
+    // coefficient is immediate --> return the coefficient as canonicalform
+    return CanonicalForm(coeff_long);
+  }
+  else
+  {
+    // coefficient is not immediate (gmp-number)
+    if (cf_stringtemp_l==0)
+    {
+      cf_stringtemp=(char *)Alloc(1023);
+      cf_stringtemp2=(char *)Alloc(1023);
+      cf_stringtemp[0]='\0';
+      cf_stringtemp2[0]='\0';
+      cf_stringtemp_l=1023;
+    }
+
+    // convert coefficient to char* (input for gmp)
+    dummy[1]='\0';
+
+    if (coefficient<0)
+    {
+      // negate coefficient, but store the sign in minusremainder
+      minusremainder=1;
+      coefficient=-coefficient;
+    }
+
+    int l=0;
+    while (coefficient>15)
+    {
+      ZZ quotient,remaind;
+      ZZ ten;ten=16;
+      DivRem(quotient,remaind,coefficient,ten);
+      dummy[0]=numbers[to_long(remaind)];
+      //tmp*=10; tmp+=to_long(remaind);
+
+      l++;
+      if (l>=cf_stringtemp_l-2)
+      {
+        Free(cf_stringtemp2,cf_stringtemp_l);
+        char *p=(char *)Alloc(cf_stringtemp_l*2);
+        //NTL_SNS
+        memcpy(p,cf_stringtemp,cf_stringtemp_l);
+        Free(cf_stringtemp,cf_stringtemp_l);
+        cf_stringtemp_l*=2;
+        cf_stringtemp=p;
+        cf_stringtemp2=(char *)Alloc(cf_stringtemp_l);
+      }
+      cf_stringtemp[l-1]=dummy[0];
+      cf_stringtemp[l]='\0';
+      //strcat(stringtemp,dummy);
+
+      coefficient=quotient;
+    }
+    //built up the string in dummy[0]
+    dummy[0]=numbers[to_long(coefficient)];
+    //NTL_SNS
+    l++;
+    cf_stringtemp[l-1]=dummy[0];
+    cf_stringtemp[l]='\0';
+    //tmp*=10; tmp+=to_long(coefficient);
+
+    if (minusremainder==1)
+    {
+      //Check whether coefficient has been negative at the start of the procedure
+      cf_stringtemp2[0]='-';
+      //tmp*=(-1);
+    }
+
+    //reverse the list to obtain the correct string
+    //NTL_SNS
+    for (int i=l-1;i>=0;i--) // l ist the position of \0
+    {
+      cf_stringtemp2[l-i-1+minusremainder]=cf_stringtemp[i];
+    }
+    cf_stringtemp2[l+minusremainder]='\0';
+  }
+
+  //convert the string to canonicalform using the char*-Constructor
+  return CanonicalForm(cf_stringtemp2,16);
+  //return tmp;
+}*/
+
+////////////////////////////////////////////////////////////////////////////////
+/// NAME: convertFacCF2NTLZZX
+///
+/// DESCRIPTION:
+/// Routine for conversion of canonicalforms in Factory to polynomials
+/// of type ZZX of NTL. To guarantee the correct execution of the
+/// algorithm the characteristic has to equal zero.
+///
+/// INPUT:  The canonicalform that has to be converted
+/// OUTPUT: The converted NTL-polynom of type ZZX
+////////////////////////////////////////////////////////////////////////////////
+
+ZZ convertFacCF2NTLZZ(const CanonicalForm & f)
+{
+  ZZ temp;
+  if (f.isImm()) temp=f.intval();
+  else
+  {
+    //Coefficient is a gmp-number
+    mpz_t gmp_val;
+    char* stringtemp;
+
+    f.mpzval (gmp_val);
+    int l=mpz_sizeinbase(gmp_val,10)+2;
+    stringtemp=(char*)Alloc(l);
+    stringtemp=mpz_get_str(stringtemp,10,gmp_val);
+    mpz_clear(gmp_val);
+    conv(temp,stringtemp);
+    Free(stringtemp,l);
+  }
+  return temp;
+}
+
+ZZX convertFacCF2NTLZZX(const CanonicalForm & f)
+{
+    ZZX ntl_poly;
+
+    CFIterator i;
+    i=f;
+
+    int NTLcurrentExp=i.exp();
+    int largestExp=i.exp();
+    int k;
+
+    //set the length of the NTL-polynomial
+    ntl_poly.SetMaxLength(largestExp+1);
+
+    //Go through the coefficients of the canonicalform and build up the NTL-polynomial
+    for (;i.hasTerms();i++)
+    {
+      for (k=NTLcurrentExp;k>i.exp();k--)
+      {
+        SetCoeff(ntl_poly,k,0);
+      }
+      NTLcurrentExp=i.exp();
+
+      //Coefficient is a gmp-number
+      ZZ temp=convertFacCF2NTLZZ(i.coeff());
+
+      //set the computed coefficient
+      SetCoeff(ntl_poly,NTLcurrentExp,temp);
+
+      NTLcurrentExp--;
+    }
+    for (k=NTLcurrentExp;k>=0;k--)
+    {
+      SetCoeff(ntl_poly,k,0);
+    }
+
+    //normalize the polynomial
+    ntl_poly.normalize();
+
+    return ntl_poly;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/// NAME: convertNTLvec_pair_ZZX_long2FacCFFList
+///
+/// DESCRIPTION:
+/// Routine for converting a vector of polynomials from ZZ to a list
+/// CFFList of Factory. This routine will be used after a successful
+/// factorization of NTL to convert the result back to Factory.
+/// Additionally a variable x and the computed multiplicity, as a type
+/// ZZ of NTL, is needed as parameters indicating the main variable of the
+/// computed canonicalform and the multiplicity of the original polynomial.
+/// To guarantee the correct execution of the algorithm the characteristic
+/// has to equal zero.
+///
+/// INPUT:  A vector of polynomials over ZZ of type vec_pair_ZZX_long and
+///         a variable x and a multiplicity of type ZZ
+/// OUTPUT: The converted list of polynomials of type CFFList, all
+///         have x as their main variable
+////////////////////////////////////////////////////////////////////////////////
+
+CFFList
+convertNTLvec_pair_ZZX_long2FacCFFList (const vec_pair_ZZX_long & e,const ZZ & multi,const Variable & x)
+{
+  CFFList result;
+  ZZX polynom;
+  long exponent;
+  CanonicalForm bigone;
+
+  // Go through the vector e and build up the CFFList
+  // As usual bigone summarizes the result
+  for (int i=e.length()-1;i>=0;i--)
+  {
+    ZZ coefficient;
+    polynom=e[i].a;
+    exponent=e[i].b;
+    bigone=convertNTLZZX2CF(polynom,x);
+    //append the converted polynomial to the list
+    result.append(CFFactor(bigone,exponent));
+  }
+  // the multiplicity at pos 1
+  //if (!IsOne(multi))
+    result.insert(CFFactor(convertZZ2CF(multi),1));
+
+  //return the converted list
+  return result;
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+/// NAME: convertNTLZZpX2CF
+///
+/// DESCRIPTION:
+/// Routine for conversion of elements of arbitrary extensions of ZZp,
+/// having type ZZpE, of NTL to their corresponding values of type
+/// canonicalform in Factory.
+/// To guarantee the correct execution of the algorithm the characteristic
+/// has to be an arbitrary prime number and Factory has to compute in an
+/// extension of F_p.
+///
+/// INPUT:  The coefficient of type ZZpE and the variable x indicating the main//
+///         variable of the computed canonicalform
+/// OUTPUT: The converted value of coefficient as type canonicalform
+////////////////////////////////////////////////////////////////////////////////
+
+CanonicalForm convertNTLZZpE2CF(const ZZ_pE & coefficient,const Variable & x)
+{
+  return convertNTLZZpX2CF(rep(coefficient),x);
+}
+CanonicalForm convertNTLzzpE2CF(const zz_pE & coefficient,const Variable & x)
+{
+  return convertNTLzzpX2CF(rep(coefficient),x);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/// NAME: convertNTLvec_pair_ZZpEX_long2FacCFFList
+///
+/// DESCRIPTION:
+/// Routine for converting a vector of polynomials from ZZpEX to a CFFList
+/// of Factory. This routine will be used after a successful factorization
+/// of NTL to convert the result back to Factory.
+/// Additionally a variable x and the computed multiplicity, as a type
+/// ZZpE of NTL, is needed as parameters indicating the main variable of the
+/// computed canonicalform and the multiplicity of the original polynomial.
+/// To guarantee the correct execution of the algorithm the characteristic
+/// has a be an arbitrary prime number p and computations have to be done
+/// in an extention of F_p.
+///
+/// INPUT:  A vector of polynomials over ZZpE of type vec_pair_ZZ_pEX_long and
+///         a variable x and a multiplicity of type ZZpE
+/// OUTPUT: The converted list of polynomials of type CFFList, all polynomials
+///         have x as their main variable
+////////////////////////////////////////////////////////////////////////////////
+
+CFFList
+convertNTLvec_pair_ZZpEX_long2FacCFFList(const vec_pair_ZZ_pEX_long & e,const ZZ_pE & multi,const Variable & x,const Variable & alpha)
+{
+  CFFList result;
+  ZZ_pEX polynom;
+  long exponent;
+  CanonicalForm bigone;
+
+  // Maybe, e may additionally be sorted with respect to increasing degree of x, but this is not
+  //important for the factorization, but nevertheless would take computing time, so it is omitted
+
+  // Go through the vector e and build up the CFFList
+  // As usual bigone summarizes the result during every loop
+  for (int i=e.length()-1;i>=0;i--)
+  {
+    bigone=0;
+
+    polynom=e[i].a;
+    exponent=e[i].b;
+
+    for (int j=0;j<=deg(polynom);j++)
+    {
+      if (IsOne(coeff(polynom,j)))
+      {
+        bigone+=power(x,j);
+      }
+      else
+      {
+        CanonicalForm coefficient=convertNTLZZpE2CF(coeff(polynom,j),alpha);
+        if (coeff(polynom,j)!=0)
+        {
+          bigone += (power(x,j)*coefficient);
+        }
+      }
+    }
+    //append the computed polynomials together with its exponent to the CFFList
+    result.append(CFFactor(bigone,exponent));
+  }
+  // Start by appending the multiplicity
+  if (!IsOne(multi))
+    result.insert(CFFactor(convertNTLZZpE2CF(multi,alpha),1));
+
+  //return the computed CFFList
+  return result;
+}
+CFFList
+convertNTLvec_pair_zzpEX_long2FacCFFList(const vec_pair_zz_pEX_long & e,const zz_pE & multi,const Variable & x,const Variable & alpha)
+{
+  CFFList result;
+  zz_pEX polynom;
+  long exponent;
+  CanonicalForm bigone;
+
+  // Maybe, e may additionally be sorted with respect to increasing degree of x, but this is not
+  //important for the factorization, but nevertheless would take computing time, so it is omitted
+
+  // Go through the vector e and build up the CFFList
+  // As usual bigone summarizes the result during every loop
+  for (int i=e.length()-1;i>=0;i--)
+  {
+    bigone=0;
+
+    polynom=e[i].a;
+    exponent=e[i].b;
+
+    for (int j=0;j<=deg(polynom);j++)
+    {
+      if (IsOne(coeff(polynom,j)))
+      {
+        bigone+=power(x,j);
+      }
+      else
+      {
+        CanonicalForm coefficient=convertNTLzzpE2CF(coeff(polynom,j),alpha);
+        if (coeff(polynom,j)!=0)
+        {
+          bigone += (power(x,j)*coefficient);
+        }
+      }
+    }
+    //append the computed polynomials together with its exponent to the CFFList
+    result.append(CFFactor(bigone,exponent));
+  }
+  // Start by appending the multiplicity
+  if (!IsOne(multi))
+    result.insert(CFFactor(convertNTLzzpE2CF(multi,alpha),1));
+
+  //return the computed CFFList
+  return result;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/// NAME: convertNTLGF2E2CF
+///
+/// DESCRIPTION:
+/// Routine for conversion of elements of extensions of GF2, having type
+/// GF2E, of NTL to their corresponding values of type canonicalform in
+/// Factory.
+/// To guarantee the correct execution of the algorithm, the characteristic
+/// must equal two and Factory has to compute in an extension of F_2.
+/// As usual this is an optimized special case of the more general conversion
+/// routine from ZZpE to Factory.
+///
+/// INPUT:  The coefficient of type GF2E and the variable x indicating the
+///         main variable of the computed canonicalform
+/// OUTPUT: The converted value of coefficient as type canonicalform
+////////////////////////////////////////////////////////////////////////////////
+
+CanonicalForm convertNTLGF2E2CF(const GF2E & coefficient,const Variable & x)
+{
+  return convertNTLGF2X2CF(rep(coefficient),x);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/// NAME: convertNTLvec_pair_GF2EX_long2FacCFFList
+///
+/// DESCRIPTION:
+/// Routine for converting a vector of polynomials from GF2EX to a CFFList
+/// of Factory. This routine will be used after a successful factorization
+/// of NTL to convert the result back to Factory.
+/// This is a special, but optimized case of the more general conversion
+/// from ZZpE to canonicalform.
+/// Additionally a variable x and the computed multiplicity, as a type GF2E
+/// of NTL, is needed as parameters indicating the main variable of the
+/// computed canonicalform and the multiplicity of the original polynomial.
+/// To guarantee the correct execution of the algorithm the characteristic
+/// has to equal two and computations have to be done in an extention of F_2.
+///
+/// INPUT:  A vector of polynomials over GF2E of type vec_pair_GF2EX_long and
+///         a variable x and a multiplicity of type GF2E
+/// OUTPUT: The converted list of polynomials of type CFFList, all polynomials
+///         have x as their main variable
+////////////////////////////////////////////////////////////////////////////////
+
+CFFList convertNTLvec_pair_GF2EX_long2FacCFFList
+    (const vec_pair_GF2EX_long & e, const GF2E & multi, const Variable & x, const Variable & alpha)
+{
+  CFFList result;
+  GF2EX polynom;
+  long exponent;
+  CanonicalForm bigone;
+
+  // Maybe, e may additionally be sorted with respect to increasing degree of x, but this is not
+  //important for the factorization, but nevertheless would take computing time, so it is omitted
+
+  // multiplicity is always one, so we do not have to worry about that
+
+  // Go through the vector e and build up the CFFList
+  // As usual bigone summarizes the result during every loop
+  for (int i=e.length()-1;i>=0;i--)
+  {
+    bigone=0;
+
+    polynom=e[i].a;
+    exponent=e[i].b;
+
+    for (int j=0;j<=deg(polynom);j++)
+    {
+      if (IsOne(coeff(polynom,j)))
+      {
+        bigone+=power(x,j);
+      }
+      else
+      {
+        CanonicalForm coefficient=convertNTLGF2E2CF(coeff(polynom,j),alpha);
+        if (coeff(polynom,j)!=0)
+        {
+          bigone += (power(x,j)*coefficient);
+        }
+      }
+    }
+
+    // append the computed polynomial together with its multiplicity
+    result.append(CFFactor(bigone,exponent));
+
+  }
+
+  if (!IsOne(multi))
+    result.insert(CFFactor(convertNTLGF2E2CF(multi,alpha),1));
+
+  // return the computed CFFList
+  return result;
+}
+
+////////////////////////////////////////////////////
+/// CanonicalForm in Z_2(a)[X] to NTL GF2EX
+////////////////////////////////////////////////////
+GF2EX convertFacCF2NTLGF2EX(const CanonicalForm & f,const GF2X & mipo)
+{
+  GF2E::init(mipo);
+  GF2EX result;
+  CFIterator i;
+  i=f;
+
+  int NTLcurrentExp=i.exp();
+  int largestExp=i.exp();
+  int k;
+
+  result.SetMaxLength(largestExp+1);
+  for(;i.hasTerms();i++)
+  {
+    for(k=NTLcurrentExp;k>i.exp();k--) SetCoeff(result,k,0);
+    NTLcurrentExp=i.exp();
+    CanonicalForm c=i.coeff();
+    GF2X cc=convertFacCF2NTLGF2X(c);
+    //ZZ_pE ccc;
+    //conv(ccc,cc);
+    SetCoeff(result,NTLcurrentExp,to_GF2E(cc));
+    NTLcurrentExp--;
+  }
+  for(k=NTLcurrentExp;k>=0;k--) SetCoeff(result,k,0);
+  result.normalize();
+  return result;
+}
+////////////////////////////////////////////////////
+/// CanonicalForm in Z_p(a)[X] to NTL ZZ_pEX
+////////////////////////////////////////////////////
+ZZ_pEX convertFacCF2NTLZZ_pEX(const CanonicalForm & f, const ZZ_pX & mipo)
+{
+  ZZ_pE::init(mipo);
+  ZZ_pEX result;
+  CFIterator i;
+  i=f;
+
+  int NTLcurrentExp=i.exp();
+  int largestExp=i.exp();
+  int k;
+
+  result.SetMaxLength(largestExp+1);
+  for(;i.hasTerms();i++)
+  {
+    for(k=NTLcurrentExp;k>i.exp();k--) SetCoeff(result,k,0);
+    NTLcurrentExp=i.exp();
+    CanonicalForm c=i.coeff();
+    ZZ_pX cc=convertFacCF2NTLZZpX(c);
+    //ZZ_pE ccc;
+    //conv(ccc,cc);
+    SetCoeff(result,NTLcurrentExp,to_ZZ_pE(cc));
+    NTLcurrentExp--;
+  }
+  for(k=NTLcurrentExp;k>=0;k--) SetCoeff(result,k,0);
+  result.normalize();
+  return result;
+}
+zz_pEX convertFacCF2NTLzz_pEX(const CanonicalForm & f, const zz_pX & mipo)
+{
+  zz_pE::init(mipo);
+  zz_pEX result;
+  CFIterator i;
+  i=f;
+
+  int NTLcurrentExp=i.exp();
+  int largestExp=i.exp();
+  int k;
+
+  result.SetMaxLength(largestExp+1);
+  for(;i.hasTerms();i++)
+  {
+    for(k=NTLcurrentExp;k>i.exp();k--) SetCoeff(result,k,0);
+    NTLcurrentExp=i.exp();
+    CanonicalForm c=i.coeff();
+    zz_pX cc=convertFacCF2NTLzzpX(c);
+    //ZZ_pE ccc;
+    //conv(ccc,cc);
+    SetCoeff(result,NTLcurrentExp,to_zz_pE(cc));
+    NTLcurrentExp--;
+  }
+  for(k=NTLcurrentExp;k>=0;k--) SetCoeff(result,k,0);
+  result.normalize();
+  return result;
+}
+
+CanonicalForm convertNTLzz_pEX2CF (const zz_pEX& f, const Variable & x, const Variable & alpha)
+{
+  CanonicalForm bigone;
+  if (deg (f) > 0)
+  {
+    bigone= 0;
+    bigone.mapinto();
+    for (int j=0;j<deg(f)+1;j++)
+    {
+      if (coeff(f,j)!=0)
+      {
+        bigone+=(power(x,j)*convertNTLzzpE2CF(coeff(f,j),alpha));
+      }
+    }
+  }
+  else
+  {
+    bigone= convertNTLzzpE2CF(coeff(f,0),alpha);
+    bigone.mapinto();
+  }
+  return bigone;
+}
+
+CanonicalForm convertNTLZZ_pEX2CF (const ZZ_pEX& f, const Variable & x, const Variable & alpha)
+{
+  CanonicalForm bigone;
+  if (deg (f) > 0)
+  {
+    bigone= 0;
+    bigone.mapinto();
+    for (int j=0;j<deg(f)+1;j++)
+    {
+      if (coeff(f,j)!=0)
+      {
+        bigone+=(power(x,j)*convertNTLZZpE2CF(coeff(f,j),alpha));
+      }
+    }
+  }
+  else
+  {
+    bigone= convertNTLZZpE2CF(coeff(f,0),alpha);
+    bigone.mapinto();
+  }
+  return bigone;
+}
+//----------------------------------------------------------------------
+mat_ZZ* convertFacCFMatrix2NTLmat_ZZ(const CFMatrix &m)
+{
+  mat_ZZ *res=new mat_ZZ;
+  res->SetDims(m.rows(),m.columns());
+
+  int i,j;
+  for(i=m.rows();i>0;i--)
+  {
+    for(j=m.columns();j>0;j--)
+    {
+      (*res)(i,j)=convertFacCF2NTLZZ(m(i,j));
+    }
+  }
+  return res;
+}
+CFMatrix* convertNTLmat_ZZ2FacCFMatrix(const mat_ZZ &m)
+{
+  CFMatrix *res=new CFMatrix(m.NumRows(),m.NumCols());
+  int i,j;
+  for(i=res->rows();i>0;i--)
+  {
+    for(j=res->columns();j>0;j--)
+    {
+      (*res)(i,j)=convertZZ2CF(m(i,j));
+    }
+  }
+  return res;
+}
+
+mat_zz_p* convertFacCFMatrix2NTLmat_zz_p(const CFMatrix &m)
+{
+  mat_zz_p *res=new mat_zz_p;
+  res->SetDims(m.rows(),m.columns());
+
+  int i,j;
+  for(i=m.rows();i>0;i--)
+  {
+    for(j=m.columns();j>0;j--)
+    {
+      if(!(m(i,j)).isImm()) printf("convertFacCFMatrix2NTLmat_zz_p: not imm.\n");
+      (*res)(i,j)=(m(i,j)).intval();
+    }
+  }
+  return res;
+}
+CFMatrix* convertNTLmat_zz_p2FacCFMatrix(const mat_zz_p &m)
+{
+  CFMatrix *res=new CFMatrix(m.NumRows(),m.NumCols());
+  int i,j;
+  for(i=res->rows();i>0;i--)
+  {
+    for(j=res->columns();j>0;j--)
+    {
+      (*res)(i,j)=CanonicalForm(to_long(rep(m(i,j))));
+    }
+  }
+  return res;
+}
+mat_zz_pE* convertFacCFMatrix2NTLmat_zz_pE(const CFMatrix &m)
+{
+  mat_zz_pE *res=new mat_zz_pE;
+  res->SetDims(m.rows(),m.columns());
+
+  int i,j;
+  for(i=m.rows();i>0;i--)
+  {
+    for(j=m.columns();j>0;j--)
+    {
+      zz_pX cc=convertFacCF2NTLzzpX(m(i,j));
+      (*res)(i,j)=to_zz_pE(cc);
+    }
+  }
+  return res;
+}
+CFMatrix* convertNTLmat_zz_pE2FacCFMatrix(const mat_zz_pE &m, const Variable & alpha)
+{
+  CFMatrix *res=new CFMatrix(m.NumRows(),m.NumCols());
+  int i,j;
+  for(i=res->rows();i>0;i--)
+  {
+    for(j=res->columns();j>0;j--)
+    {
+      (*res)(i,j)=convertNTLzzpE2CF(m(i,j), alpha);
+    }
+  }
+  return res;
+}
+#endif
diff --git a/factory/NTLconvert.h b/factory/NTLconvert.h
new file mode 100644
index 0000000..c874543
--- /dev/null
+++ b/factory/NTLconvert.h
@@ -0,0 +1,95 @@
+/**
+ * @file NTLconvert.h
+ *
+ * Conversion to and from NTL
+**/
+
+#ifndef INCL_NTLCONVERT_H
+#define INCL_NTLCONVERT_H
+
+#ifdef HAVE_NTL
+
+// #include <factory/cf_gmp.h>
+
+#include "cf_defs.h"
+#include "canonicalform.h"
+#include "cf_iter.h"
+#include "fac_sqrfree.h"
+#include "cf_algorithm.h"
+
+#include <NTL/config.h>
+
+#ifdef NTL_STD_CXX
+#ifdef NOSTREAMIO
+#  ifdef HAVE_IOSTREAM
+#    include <iostream>
+#    define OSTREAM std::ostream
+#    define ISTREAM std::istream
+#  elif defined(HAVE_IOSTREAM_H)
+#    include <iostream.h>
+#    define OSTREAM ostream
+#    define ISTREAM istream
+#  endif
+#endif /* ! NOSTREAMIO */
+#endif
+
+
+#include <NTL/ZZXFactoring.h>
+#include <NTL/ZZ_pXFactoring.h>
+#include <NTL/lzz_pXFactoring.h>
+#include <NTL/GF2XFactoring.h>
+#include <NTL/ZZ_pEXFactoring.h>
+#include <NTL/lzz_pEXFactoring.h>
+#include <NTL/GF2EXFactoring.h>
+#include <NTL/mat_ZZ.h>
+#include <NTL/mat_lzz_p.h>
+#include <NTL/mat_lzz_pE.h>
+
+#ifdef NTL_CLIENT               // in <NTL/tools.h>: using of name space NTL
+NTL_CLIENT
+#endif
+
+
+
+
+#include "int_int.h"
+#include "cf_assert.h"
+
+
+ZZ_pX convertFacCF2NTLZZpX(const CanonicalForm & f);
+zz_pX convertFacCF2NTLzzpX(const CanonicalForm & f);
+GF2X convertFacCF2NTLGF2X(const CanonicalForm & f);
+CanonicalForm convertNTLZZpX2CF(const ZZ_pX & poly,const Variable & x);
+CanonicalForm convertNTLzzpX2CF(const zz_pX & poly,const Variable & x);
+CanonicalForm convertNTLGF2X2CF(const GF2X & poly,const Variable & x);
+CanonicalForm convertNTLZZX2CF(const ZZX & polynom,const Variable & x);
+CFFList convertNTLvec_pair_ZZpX_long2FacCFFList(const vec_pair_ZZ_pX_long& e,const ZZ_p & multi,const Variable & x);
+CFFList convertNTLvec_pair_zzpX_long2FacCFFList(const vec_pair_zz_pX_long& e,const zz_p multi,const Variable & x);
+
+CFFList convertNTLvec_pair_GF2X_long2FacCFFList(const vec_pair_GF2X_long& e,const GF2 multi,const Variable & x);
+CanonicalForm convertZZ2CF(const ZZ & coefficient);
+ZZ convertFacCF2NTLZZ(const CanonicalForm & f);
+ZZX convertFacCF2NTLZZX(const CanonicalForm & f);
+CFFList convertNTLvec_pair_ZZX_long2FacCFFList(const vec_pair_ZZX_long& e,const ZZ & multi,const Variable & x);
+CanonicalForm convertNTLZZpE2CF(const ZZ_pE & coefficient,const Variable & x);
+CFFList convertNTLvec_pair_ZZpEX_long2FacCFFList(const vec_pair_ZZ_pEX_long & e,const ZZ_pE & multi,const Variable & x,const Variable & alpha);
+CanonicalForm convertNTLGF2E2CF(const GF2E & coefficient,const Variable & x);
+CFFList convertNTLvec_pair_GF2EX_long2FacCFFList(const vec_pair_GF2EX_long& e,const GF2E & multi,const Variable & x,const Variable & alpha);
+GF2EX convertFacCF2NTLGF2EX(const CanonicalForm & f,const GF2X & mipo);
+ZZ_pEX convertFacCF2NTLZZ_pEX(const CanonicalForm & f,const ZZ_pX & mipo);
+zz_pEX convertFacCF2NTLzz_pEX(const CanonicalForm & f,const zz_pX & mipo);
+CanonicalForm convertNTLzzpE2CF(const zz_pE & f, const Variable & x);
+CFFList convertNTLvec_pair_zzpEX_long2FacCFFList(const vec_pair_zz_pEX_long & e,const zz_pE & multi,const Variable & x,const Variable & alpha);
+CanonicalForm convertNTLzz_pEX2CF(const zz_pEX & f, const Variable & x, const Variable & alpha);
+CanonicalForm convertNTLZZ_pEX2CF(const ZZ_pEX & f, const Variable & x, const Variable & alpha);
+
+mat_ZZ* convertFacCFMatrix2NTLmat_ZZ(const CFMatrix &m);
+CFMatrix* convertNTLmat_ZZ2FacCFMatrix(const mat_ZZ &m);
+mat_zz_p* convertFacCFMatrix2NTLmat_zz_p(const CFMatrix &m);
+CFMatrix* convertNTLmat_zz_p2FacCFMatrix(const mat_zz_p &m);
+mat_zz_pE* convertFacCFMatrix2NTLmat_zz_pE(const CFMatrix &m);
+CFMatrix* convertNTLmat_zz_pE2FacCFMatrix(const mat_zz_pE &m, const Variable & alpha);
+
+extern long fac_NTL_char;
+#endif
+#endif
diff --git a/factory/README b/factory/README
new file mode 100644
index 0000000..e4885e7
--- /dev/null
+++ b/factory/README
@@ -0,0 +1,241 @@
+
+
+  --- This `README' file corresponds to Singular-Factory version 4.0 ---
+
+
+		  README file for Singular-Factory
+		  ================================
+
+NOTE: The copyright of Singular-Factory is described in the
+      file COPYING
+
+Overview
+========
+1.  What is Factory?
+2.  Comments, Questions, Bug Reports
+3.  Installation
+4.  Distribution
+5.  Prerequisites
+6.  Stream IO
+7.  Diagnostic Messages
+8.  GF(q) Tables
+9.  A Note on Singular
+10. Factory Template Instantiation
+11. Documentation
+12. Examples and Tests
+13. Remark on Characteristic Sets
+14. Adding new code
+15. Nomenclature
+16. Limitations
+
+1. What is Factory?
+===================
+  Factory is a C++ class library that implements a recursive representation
+of multivariate polynomial data.  It was developed by Ruediger Stobbe
+and Jens Schmidt at the University of Kaiserslautern as an independent and
+self-contained part of the computer algebra system Singular (developed by
+G.-M. Greuel, G. Pfister and H. Schoenemann) and is now developed by Martin Lee.
+
+  Factory handles sparse multivariate polynomials over different
+coefficient domains, such as Z, Q and GF(q), as well as algebraic
+extensions over Q and GF(q) in an efficient way.  Factory includes
+algorithms for computing univariate and multivariate gcds, resultants,
+chinese remainders, and algorithms to factorize multivariate polynomials
+and to compute the absolute factorization of multivariate polynomials with integer
+coefficients.
+
+  The interface to the polynomial system of Factory is provided by a single
+class `CanonicalForm' which can deal with elements of the coefficient
+domain as well as polynomials.  Using operator overloading, you can handle
+polynomial data similarly to built-in types such as the machine integers.
+For example, to add two polynomials one simply uses the `+' operator.
+Because of this, Factory is easy to use even if you are not familiar with
+C++ programming.
+
+  There are a couple of utility classes provided by Factory such as lists,
+arrays, polynomial maps, etc.  These make the usage more comfortable.
+
+2. Comments, Questions, Bug Reports
+====================================
+  Factory is a project in evolution.  That means there is no guarantee that
+Factory is bug free.  I am sure that there are bugs or at least features.
+If you find bugs or if you find a strange behavior of the library, please
+let me know (e-mail: singular at mathematik.uni-kl.de>).
+Comments and questions are welcome, too.
+
+  Factory version 1.2c and newer define an external variable
+`factoryVersion' describing the version of the library.  The external
+variable `factoryConfiguration' (not present in versions 1.2c and 1.3a)
+describes the options Factory has been configured with.  Please include the
+version number and the configuration options in your bug reports.  You may
+either use the UNIX utility `what' to get this information (`what libcf.a')
+or compile and run something similar to this:
+
+  #include <factory.h>
+  main() { cout << factoryVersion << "; " << factoryConfiguration << endl; }
+
+3. Installation
+===============
+NOTE: If you have received this Factory distribution together with Singular
+you do not have to worry about compilation or installation at all.  The
+installation procedure for Singular should do everything for you.  For more
+information, see the section "A Note on Singular".
+
+  For further information on factory's configure options see also ./configure --help.
+
+  The installation procedure on UNIX platforms conforms more or less to the GNU
+standard:
+
+  ./configure --without-Singular; make; make check; make install;
+
+  In general, this `README' as well as the `INSTALL' file are written for
+UNIX platforms.  However, you may find less specific information on the
+configuration and installation process which is useful for other platforms,
+too.
+
+4. Distribution
+===============
+  The latest stable version of Factory is always available from
+
+		www.singular.uni-kl.de
+
+  For the latest development version visit
+
+               www.github.com/Singular
+
+5. Prerequisites
+================
+  You need GNU make to build and install Factory.  Furthermore, I strongly
+recommend to build Factory with GNU CC.  To build
+Factory and to link your programs with Factory you need the GNU Multiple
+Precision Library (GMP).
+
+Configure options:
+------------------
+  --with-gmp=<path to GMP> enabled by default
+
+  For full functionality NTL (www.shoup.net/ntl) is required.
+
+Configure options:
+------------------
+  --with-ntl=<path to NTL> enabled by default
+
+  For optimal preformance we recommend to use FLINT (www.flintlib.org) and to use
+  Singular's memory manager omalloc
+
+Configure options:
+------------------
+  --with-flint=<path to FLINT> enabled by default
+  --with-omalloc               disabled by default
+  --with-omalloc-dir=<path to omalloc>
+
+6. Stream IO
+============
+  For use with other systems which have their own IO routines to print
+polynomials it is possible to switch off Factory's stream IO.
+
+Configure options:
+------------------
+  --disable-streamio      build Factory without stream IO
+
+
+7. Diagnostic Messages
+======================
+Factory has three types of diagnostic messages:
+o Assertions (implemented by the "ASSERT macros" in `cf_assert.h') are used to
+  ensure preconditions before running some algorithm.  A typical example is
+  to test f != 0 before dividing by f.
+o Debug output (implemented by the "DEBOUT macros" in `debug.h'/`debug.cc')
+  is used to trace complex algorithms, e.g. factorization.
+o Timing information may be accumulated and printed using the "TIMING macros"
+  in `timing.h'.
+
+  Since all diagnostic messages are implemented using preprocessor macros,
+they will completely cease when disabled, thus avoiding any impact on
+speed.  By default, all diagnostic messages are disabled.
+
+Configure options:
+------------------
+  --enable-assertions     build Factory with assertions activated
+  --enable-timing         build Factory so it will print timing information
+  --enable-debugoutput    build Factory so it will print debugging information
+
+8. GF(q) Tables
+===============
+
+  Factory uses addition tables to calculate in GF(p^n) in an efficient way.
+
+  They can be created with `make gengftables'.  Building the tables takes quite
+   a while!
+
+9. A Note on Singular
+=====================
+  If you have received this Factory distribution together with Singular you
+do not have to worry about compilation or installation at all.  The
+installation procedure for Singular should do everything for you.
+
+10. Factory Template Instantiation
+==================================
+  There are a couple of classes provided by Factory such as lists, arrays,
+etc, which may be used to derive new abstract data types from already
+existing ones.  Factory uses them itself, e.g. to return the result of a
+factorization (a list of factors), and you may use them to create new
+derived abstract data types.  These classes are realized using C++
+templates, which are instantiated in one single file namely ftmpl_inst.cc .
+
+11. Documentation
+=================
+  So far there are only preliminary versions of a user/reference manual and
+a tutorial ("A quick start into Factory").  Please do not expect them to
+be error-free or even complete.  For this reason, the documentation is not
+included in the source code archive (`factory-<version>.tgz').  Instead, the
+sources and compiled DVI files reside in `factory-doc-prelim.tgz'. They will
+unpack into a directory `factory-doc-prelim/'.
+
+
+12. Examples and Tests
+======================
+  The directory `examples/' in the Factory source directory contains some
+example applications for Factory.
+
+  'make check' will run some simple test as well.
+
+13. Remark on Characteristic Sets
+=================================
+Algorithms for manipulation of polynomial ideals via the characteristic set
+methods (e.g., calculating the characteristic set and the irreducible
+characteristic series) are now incorpareted into factory.
+If you want to learn about characteristic sets, the next is a good point
+to start with:
+    Dongming Wang:
+    An Implementation of the Characteristic Set Method in Maple.
+    In: Automated Practical Reasoning: Algebraic Approaches
+    (J. Pfalzgraf and D. Wang, eds.), Springer-Verlag,
+    Wien-New York, 1995, pp. 187-201.
+
+14. Adding new code
+===================
+  If you like to add new code 'foo.cc/foo.h' add 'foo.cc' to 'Makefile.am' under
+'SOURCES' and 'foo.h' under 'factory_headers'. If your new functions should be
+available via factory's global interface 'factory.h' add
+
+/*MAKEHEADER PUBLIC ONLY*/
+foo.h
+
+to 'factory.template' and enclose the functions in 'foo.h', that you like to
+add, by '/*BEGINPUBLIC*/' and '/*ENDPUBLIC*/'.
+
+15. Nomenclature
+================
+  Factorization related functions are contained in files with the prefix 'fac'.
+Functions operating on CanonicalForm's are contained in files with the prefix
+'cf'. Functions operating on the internal structures of a CanonicalForm are
+contained in files with the prefix 'int'. Exceptions are gfops.cc/.h,
+ffops.cc/.h, imm.cc/.h as they use intrinsic data types.
+
+16. Limitations
+===============
+  The largest characteristic of a finite field is limited to 536870909. The
+number of elements of a finite fields represented by Conway polynomials has to
+be < 2^16 (see gfops.cc).
+
diff --git a/factory/_config.h.in b/factory/_config.h.in
new file mode 100644
index 0000000..12c0a64
--- /dev/null
+++ b/factory/_config.h.in
@@ -0,0 +1,182 @@
+/* _config.h.in.  Generated from configure.ac by autoheader.  */
+
+/* define to use "configurable inline methods" (see cf_inline.cc) */
+#undef CF_USE_INLINE
+
+/* define if you want to have debugging output */
+#undef DEBUGOUTPUT
+
+/* DISABLE_GMP_CPP */
+#undef DISABLE_GMP_CPP
+
+/* factory configuration */
+#undef FACTORYCONFIGURATION
+
+/* factory version */
+#undef FACTORYVERSION
+
+/* Defenition for FACTORY_INT64 */
+#undef FACTORY_INT64
+
+/* Define if GMP is version 3.xxx */
+#undef GMP_VERSION_3
+
+/* Define to 1 if you have the <cstdio> header file. */
+#undef HAVE_CSTDIO
+
+/* Define to 1 if you have the <ctype.h> header file. */
+#undef HAVE_CTYPE_H
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
+
+/* Define to 1 if you have the <errno.h> header file. */
+#undef HAVE_ERRNO_H
+
+/* Define if FLINT is installed */
+#undef HAVE_FLINT
+
+/* Define to 1 if you have the <fstream> header file. */
+#undef HAVE_FSTREAM
+
+/* Define to 1 if you have the <fstream.h> header file. */
+#undef HAVE_FSTREAM_H
+
+/* Define if GMP is installed */
+#undef HAVE_GMP
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the <iostream> header file. */
+#undef HAVE_IOSTREAM
+
+/* Define to 1 if you have the <iostream.h> header file. */
+#undef HAVE_IOSTREAM_H
+
+/* Define to 1 if you have the `m' library (-lm). */
+#undef HAVE_LIBM
+
+/* Define to 1 if you have the <math.h> header file. */
+#undef HAVE_MATH_H
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define if NTL is installed */
+#undef HAVE_NTL
+
+/* define if build with OMALLOC */
+#undef HAVE_OMALLOC
+
+/* Define to 1 if you have the <omalloc/omalloc.h> header file. */
+#undef HAVE_OMALLOC_OMALLOC_H
+
+/* Define to 1 if you have the <signal.h> header file. */
+#undef HAVE_SIGNAL_H
+
+/* Define to 1 if you have the <stdarg.h> header file. */
+#undef HAVE_STDARG_H
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdio.h> header file. */
+#undef HAVE_STDIO_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the <string> header file. */
+#undef HAVE_STRING
+
+/* 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 <strstream.h> header file. */
+#undef HAVE_STRSTREAM_H
+
+/* Define to 1 if you have the <sys/param.h> header file. */
+#undef HAVE_SYS_PARAM_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/times.h> header file. */
+#undef HAVE_SYS_TIMES_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 <time.h> header file. */
+#undef HAVE_TIME_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
+
+/* define if you do not want to activate assertions */
+#undef NOASSERT
+
+/* define to build factory without stream IO */
+#undef NOSTREAMIO
+
+/* "Disable OM Debug" */
+#undef OM_NDEBUG
+
+/* Name of package */
+#undef PACKAGE
+
+/* 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 if linked to Singular */
+#undef SINGULAR
+
+/* SINGULAR_CFLAGS */
+#undef SINGULAR_CFLAGS
+
+/* "Disable Singular Debug" */
+#undef SING_NDEBUG
+
+/* The size of `long', as computed by sizeof. */
+#undef SIZEOF_LONG
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* define if you want to activate the timing stuff */
+#undef TIMING
+
+/* Version number of package */
+#undef VERSION
+
+/* Define to empty if `const' does not conform to ANSI C. */
+#undef const
+
+/* Define to `__inline__' or `__inline' if that's what the C compiler
+   calls it, or to nothing if 'inline' is not supported under any name.  */
+#ifndef __cplusplus
+#undef inline
+#endif
diff --git a/factory/acinclude.m4 b/factory/acinclude.m4
new file mode 100644
index 0000000..f7425bd
--- /dev/null
+++ b/factory/acinclude.m4
@@ -0,0 +1,321 @@
+# This file is part of Autoconf.                       -*- Autoconf -*-
+
+# Copyright (C) 2004 Oren Ben-Kiki
+# This file is distributed under the same terms as the Autoconf macro files.
+
+########## CHANGELOG ##################
+# 2009-01-14 Martin Mann
+# * DX_ARG_ABLE : new variable 'DX_FLAG_DX_CURRENT_FEATURE'
+# * DX_CLEAR_DEPEND : use of explicit variable 'DX_FLAG_DX_CURRENT_FEATURE'
+#   in AC_SUBST instead of 'DX_FLAG[]DX_CURRENT_FEATURE' which is rejected by
+#   newer autotools
+
+# Generate automatic documentation using Doxygen. Works in concert with the
+# aminclude.m4 file and a compatible doxygen configuration file. Defines the
+# following public macros:
+#
+# DX_???_FEATURE(ON|OFF) - control the default setting fo a Doxygen feature.
+# Supported features are 'DOXYGEN' itself, 'DOT' for generating graphics,
+# 'HTML' for plain HTML, 'CHM' for compressed HTML help (for MS users), 'CHI'
+# for generating a seperate .chi file by the .chm file, and 'MAN', 'RTF',
+# 'XML', 'PDF' and 'PS' for the appropriate output formats. The environment
+# variable DOXYGEN_PAPER_SIZE may be specified to override the default 'a4wide'
+# paper size.
+#
+# By default, HTML, PDF and PS documentation is generated as this seems to be
+# the most popular and portable combination. MAN pages created by Doxygen are
+# usually problematic, though by picking an appropriate subset and doing some
+# massaging they might be better than nothing. CHM and RTF are specific for MS
+# (note that you can't generate both HTML and CHM at the same time). The XML is
+# rather useless unless you apply specialized post-processing to it.
+#
+# The macro mainly controls the default state of the feature. The use can
+# override the default by specifying --enable or --disable. The macros ensure
+# that contradictory flags are not given (e.g., --enable-doxygen-html and
+# --enable-doxygen-chm, --enable-doxygen-anything with --disable-doxygen, etc.)
+# Finally, each feature will be automatically disabled (with a warning) if the
+# required programs are missing.
+#
+# Once all the feature defaults have been specified, call DX_INIT_DOXYGEN with
+# the following parameters: a one-word name for the project for use as a
+# filename base etc., an optional configuration file name (the default is
+# 'Doxyfile', the same as Doxygen's default), and an optional output directory
+# name (the default is 'doxygen-doc').
+
+## ----------##
+## Defaults. ##
+## ----------##
+
+DX_ENV=""
+AC_DEFUN([DX_FEATURE_doc],  ON)
+AC_DEFUN([DX_FEATURE_dot],  ON)
+AC_DEFUN([DX_FEATURE_man],  OFF)
+AC_DEFUN([DX_FEATURE_html], ON)
+AC_DEFUN([DX_FEATURE_chm],  OFF)
+AC_DEFUN([DX_FEATURE_chi],  OFF)
+AC_DEFUN([DX_FEATURE_rtf],  OFF)
+AC_DEFUN([DX_FEATURE_xml],  OFF)
+AC_DEFUN([DX_FEATURE_pdf],  OFF)
+AC_DEFUN([DX_FEATURE_ps],   OFF)
+
+## --------------- ##
+## Private macros. ##
+## --------------- ##
+
+# DX_ENV_APPEND(VARIABLE, VALUE)
+# ------------------------------
+# Append VARIABLE="VALUE" to DX_ENV for invoking doxygen.
+AC_DEFUN([DX_ENV_APPEND], [AC_SUBST([DX_ENV], ["$DX_ENV $1='$2'"])])
+
+# DX_DIRNAME_EXPR
+# ---------------
+# Expand into a shell expression prints the directory part of a path.
+AC_DEFUN([DX_DIRNAME_EXPR],
+         [[expr ".$1" : '\(\.\)[^/]*$' \| "x$1" : 'x\(.*\)/[^/]*$']])
+
+# DX_IF_FEATURE(FEATURE, IF-ON, IF-OFF)
+# -------------------------------------
+# Expands according to the M4 (static) status of the feature.
+AC_DEFUN([DX_IF_FEATURE], [ifelse(DX_FEATURE_$1, ON, [$2], [$3])])
+
+# DX_REQUIRE_PROG(VARIABLE, PROGRAM)
+# ----------------------------------
+# Require the specified program to be found for the DX_CURRENT_FEATURE to work.
+AC_DEFUN([DX_REQUIRE_PROG], [
+AC_PATH_TOOL([$1], [$2])
+if test "$DX_FLAG_DX_CURRENT_FEATURE$$1" = 1; then
+    AC_MSG_WARN([$2 not found - will not DX_CURRENT_DESCRIPTION])
+    AC_SUBST([DX_FLAG_DX_CURRENT_FEATURE], 0)
+fi
+])
+
+# DX_TEST_FEATURE(FEATURE)
+# ------------------------
+# Expand to a shell expression testing whether the feature is active.
+AC_DEFUN([DX_TEST_FEATURE], [test "$DX_FLAG_$1" = 1])
+
+# DX_CHECK_DEPEND(REQUIRED_FEATURE, REQUIRED_STATE)
+# -------------------------------------------------
+# Verify that a required features has the right state before trying to turn on
+# the DX_CURRENT_FEATURE.
+AC_DEFUN([DX_CHECK_DEPEND], [
+test "$DX_FLAG_$1" = "$2" \
+|| AC_MSG_ERROR([doxygen-DX_CURRENT_FEATURE ifelse([$2], 1,
+                            requires, contradicts) doxygen-DX_CURRENT_FEATURE])
+])
+
+# DX_CLEAR_DEPEND(FEATURE, REQUIRED_FEATURE, REQUIRED_STATE)
+# ----------------------------------------------------------
+# Turn off the DX_CURRENT_FEATURE if the required feature is off.
+AC_DEFUN([DX_CLEAR_DEPEND], [
+test "$DX_FLAG_$1" = "$2" || AC_SUBST([DX_FLAG_DX_CURRENT_FEATURE], 0)
+])
+
+
+# DX_FEATURE_ARG(FEATURE, DESCRIPTION,
+#                CHECK_DEPEND, CLEAR_DEPEND,
+#                REQUIRE, DO-IF-ON, DO-IF-OFF)
+# --------------------------------------------
+# Parse the command-line option controlling a feature. CHECK_DEPEND is called
+# if the user explicitly turns the feature on (and invokes DX_CHECK_DEPEND),
+# otherwise CLEAR_DEPEND is called to turn off the default state if a required
+# feature is disabled (using DX_CLEAR_DEPEND). REQUIRE performs additional
+# requirement tests (DX_REQUIRE_PROG). Finally, an automake flag is set and
+# DO-IF-ON or DO-IF-OFF are called according to the final state of the feature.
+AC_DEFUN([DX_ARG_ABLE], [
+    AC_DEFUN([DX_CURRENT_FEATURE], [$1])
+    AC_DEFUN([DX_FLAG_DX_CURRENT_FEATURE], [DX_FLAG_$1])
+    AC_DEFUN([DX_CURRENT_DESCRIPTION], [$2])
+    AC_ARG_ENABLE(doxygen-$1,
+                  [AS_HELP_STRING(DX_IF_FEATURE([$1], [--disable-doxygen-$1],
+                                                      [--enable-doxygen-$1]),
+                                  DX_IF_FEATURE([$1], [don't $2], [$2]))],
+                  [
+case "$enableval" in
+#(
+y|Y|yes|Yes|YES)
+    AC_SUBST([DX_FLAG_$1], 1)
+    $3
+;; #(
+n|N|no|No|NO)
+    AC_SUBST([DX_FLAG_$1], 0)
+;; #(
+*)
+    AC_MSG_ERROR([invalid value '$enableval' given to doxygen-$1])
+;;
+esac
+], [
+AC_SUBST([DX_FLAG_$1], [DX_IF_FEATURE([$1], 1, 0)])
+$4
+])
+if DX_TEST_FEATURE([$1]); then
+    $5
+    :
+fi
+if DX_TEST_FEATURE([$1]); then
+    AM_CONDITIONAL(DX_COND_$1, :)
+    $6
+    :
+else
+    AM_CONDITIONAL(DX_COND_$1, false)
+    $7
+    :
+fi
+])
+
+## -------------- ##
+## Public macros. ##
+## -------------- ##
+
+# DX_XXX_FEATURE(DEFAULT_STATE)
+# -----------------------------
+AC_DEFUN([DX_DOXYGEN_FEATURE], [AC_DEFUN([DX_FEATURE_doc],  [$1])])
+AC_DEFUN([DX_MAN_FEATURE],     [AC_DEFUN([DX_FEATURE_man],  [$1])])
+AC_DEFUN([DX_HTML_FEATURE],    [AC_DEFUN([DX_FEATURE_html], [$1])])
+AC_DEFUN([DX_CHM_FEATURE],     [AC_DEFUN([DX_FEATURE_chm],  [$1])])
+AC_DEFUN([DX_CHI_FEATURE],     [AC_DEFUN([DX_FEATURE_chi],  [$1])])
+AC_DEFUN([DX_RTF_FEATURE],     [AC_DEFUN([DX_FEATURE_rtf],  [$1])])
+AC_DEFUN([DX_XML_FEATURE],     [AC_DEFUN([DX_FEATURE_xml],  [$1])])
+AC_DEFUN([DX_XML_FEATURE],     [AC_DEFUN([DX_FEATURE_xml],  [$1])])
+AC_DEFUN([DX_PDF_FEATURE],     [AC_DEFUN([DX_FEATURE_pdf],  [$1])])
+AC_DEFUN([DX_PS_FEATURE],      [AC_DEFUN([DX_FEATURE_ps],   [$1])])
+
+# DX_INIT_DOXYGEN(PROJECT, [CONFIG-FILE], [OUTPUT-DOC-DIR])
+# ---------------------------------------------------------
+# PROJECT also serves as the base name for the documentation files.
+# The default CONFIG-FILE is "Doxyfile" and OUTPUT-DOC-DIR is "doxygen-doc".
+AC_DEFUN([DX_INIT_DOXYGEN], [
+
+# Files:
+AC_SUBST([DX_PROJECT], [$1])
+AC_SUBST([DX_CONFIG], [ifelse([$2], [], Doxyfile, [$2])])
+AC_SUBST([DX_DOCDIR], [ifelse([$3], [], doxygen-doc, [$3])])
+
+# Environment variables used inside doxygen.cfg:
+DX_ENV_APPEND(SRCDIR, $srcdir)
+DX_ENV_APPEND(PROJECT, $DX_PROJECT)
+DX_ENV_APPEND(DOCDIR, $DX_DOCDIR)
+DX_ENV_APPEND(VERSION, $PACKAGE_VERSION)
+
+# Doxygen itself:
+DX_ARG_ABLE(doc, [generate any doxygen documentation],
+            [],
+            [],
+            [DX_REQUIRE_PROG([DX_DOXYGEN], doxygen)
+             DX_REQUIRE_PROG([DX_PERL], perl)],
+            [DX_ENV_APPEND(PERL_PATH, $DX_PERL)])
+
+# Dot for graphics:
+DX_ARG_ABLE(dot, [generate graphics for doxygen documentation],
+            [DX_CHECK_DEPEND(doc, 1)],
+            [DX_CLEAR_DEPEND(doc, 1)],
+            [DX_REQUIRE_PROG([DX_DOT], dot)],
+            [DX_ENV_APPEND(HAVE_DOT, YES)
+             DX_ENV_APPEND(DOT_PATH, [`DX_DIRNAME_EXPR($DX_DOT)`])],
+            [DX_ENV_APPEND(HAVE_DOT, NO)])
+
+# Man pages generation:
+DX_ARG_ABLE(man, [generate doxygen manual pages],
+            [DX_CHECK_DEPEND(doc, 1)],
+            [DX_CLEAR_DEPEND(doc, 1)],
+            [],
+            [DX_ENV_APPEND(GENERATE_MAN, YES)],
+            [DX_ENV_APPEND(GENERATE_MAN, NO)])
+
+# RTF file generation:
+DX_ARG_ABLE(rtf, [generate doxygen RTF documentation],
+            [DX_CHECK_DEPEND(doc, 1)],
+            [DX_CLEAR_DEPEND(doc, 1)],
+            [],
+            [DX_ENV_APPEND(GENERATE_RTF, YES)],
+            [DX_ENV_APPEND(GENERATE_RTF, NO)])
+
+# XML file generation:
+DX_ARG_ABLE(xml, [generate doxygen XML documentation],
+            [DX_CHECK_DEPEND(doc, 1)],
+            [DX_CLEAR_DEPEND(doc, 1)],
+            [],
+            [DX_ENV_APPEND(GENERATE_XML, YES)],
+            [DX_ENV_APPEND(GENERATE_XML, NO)])
+
+# (Compressed) HTML help generation:
+DX_ARG_ABLE(chm, [generate doxygen compressed HTML help documentation],
+            [DX_CHECK_DEPEND(doc, 1)],
+            [DX_CLEAR_DEPEND(doc, 1)],
+            [DX_REQUIRE_PROG([DX_HHC], hhc)],
+            [DX_ENV_APPEND(HHC_PATH, $DX_HHC)
+             DX_ENV_APPEND(GENERATE_HTML, YES)
+             DX_ENV_APPEND(GENERATE_HTMLHELP, YES)],
+            [DX_ENV_APPEND(GENERATE_HTMLHELP, NO)])
+
+# Seperate CHI file generation.
+DX_ARG_ABLE(chi, [generate doxygen seperate compressed HTML help index file],
+            [DX_CHECK_DEPEND(chm, 1)],
+            [DX_CLEAR_DEPEND(chm, 1)],
+            [],
+            [DX_ENV_APPEND(GENERATE_CHI, YES)],
+            [DX_ENV_APPEND(GENERATE_CHI, NO)])
+
+# Plain HTML pages generation:
+DX_ARG_ABLE(html, [generate doxygen plain HTML documentation],
+            [DX_CHECK_DEPEND(doc, 1) DX_CHECK_DEPEND(chm, 0)],
+            [DX_CLEAR_DEPEND(doc, 1) DX_CLEAR_DEPEND(chm, 0)],
+            [],
+            [DX_ENV_APPEND(GENERATE_HTML, YES)],
+            [DX_TEST_FEATURE(chm) || DX_ENV_APPEND(GENERATE_HTML, NO)])
+
+# PostScript file generation:
+DX_ARG_ABLE(ps, [generate doxygen PostScript documentation],
+            [DX_CHECK_DEPEND(doc, 1)],
+            [DX_CLEAR_DEPEND(doc, 1)],
+            [DX_REQUIRE_PROG([DX_LATEX], latex)
+             DX_REQUIRE_PROG([DX_MAKEINDEX], makeindex)
+             DX_REQUIRE_PROG([DX_DVIPS], dvips)
+             DX_REQUIRE_PROG([DX_EGREP], egrep)])
+
+# PDF file generation:
+DX_ARG_ABLE(pdf, [generate doxygen PDF documentation],
+            [DX_CHECK_DEPEND(doc, 1)],
+            [DX_CLEAR_DEPEND(doc, 1)],
+            [DX_REQUIRE_PROG([DX_PDFLATEX], pdflatex)
+             DX_REQUIRE_PROG([DX_MAKEINDEX], makeindex)
+             DX_REQUIRE_PROG([DX_EGREP], egrep)])
+
+# LaTeX generation for PS and/or PDF:
+if DX_TEST_FEATURE(ps) || DX_TEST_FEATURE(pdf); then
+    AM_CONDITIONAL(DX_COND_latex, :)
+    DX_ENV_APPEND(GENERATE_LATEX, YES)
+else
+    AM_CONDITIONAL(DX_COND_latex, false)
+    DX_ENV_APPEND(GENERATE_LATEX, NO)
+fi
+
+# Paper size for PS and/or PDF:
+AC_ARG_VAR(DOXYGEN_PAPER_SIZE,
+           [a4wide (default), a4, letter, legal or executive])
+case "$DOXYGEN_PAPER_SIZE" in
+#(
+"")
+    AC_SUBST(DOXYGEN_PAPER_SIZE, "")
+;; #(
+a4wide|a4|letter|legal|executive)
+    DX_ENV_APPEND(PAPER_SIZE, $DOXYGEN_PAPER_SIZE)
+;; #(
+*)
+    AC_MSG_ERROR([unknown DOXYGEN_PAPER_SIZE='$DOXYGEN_PAPER_SIZE'])
+;;
+esac
+
+#For debugging:
+#echo DX_FLAG_doc=$DX_FLAG_doc
+#echo DX_FLAG_dot=$DX_FLAG_dot
+#echo DX_FLAG_man=$DX_FLAG_man
+#echo DX_FLAG_html=$DX_FLAG_html
+#echo DX_FLAG_chm=$DX_FLAG_chm
+#echo DX_FLAG_chi=$DX_FLAG_chi
+#echo DX_FLAG_rtf=$DX_FLAG_rtf
+#echo DX_FLAG_xml=$DX_FLAG_xml
+#echo DX_FLAG_pdf=$DX_FLAG_pdf
+#echo DX_FLAG_ps=$DX_FLAG_ps
+#echo DX_ENV=$DX_ENV
+])
diff --git a/factory/aclocal.m4 b/factory/aclocal.m4
new file mode 100644
index 0000000..15bb53b
--- /dev/null
+++ b/factory/aclocal.m4
@@ -0,0 +1,1151 @@
+# generated automatically by aclocal 1.13.4 -*- Autoconf -*-
+
+# Copyright (C) 1996-2013 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_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])
+m4_ifndef([AC_AUTOCONF_VERSION],
+  [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],,
+[m4_warning([this file was generated for autoconf 2.69.
+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'.])])
+
+# Copyright (C) 2002-2013 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.13'
+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.13.4], [],
+      [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.13.4])dnl
+m4_ifndef([AC_AUTOCONF_VERSION],
+  [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
+
+# Copyright (C) 2011-2013 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_AR([ACT-IF-FAIL])
+# -------------------------
+# Try to determine the archiver interface, and trigger the ar-lib wrapper
+# if it is needed.  If the detection of archiver interface fails, run
+# ACT-IF-FAIL (default is to abort configure with a proper error message).
+AC_DEFUN([AM_PROG_AR],
+[AC_BEFORE([$0], [LT_INIT])dnl
+AC_BEFORE([$0], [AC_PROG_LIBTOOL])dnl
+AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([ar-lib])dnl
+AC_CHECK_TOOLS([AR], [ar lib "link -lib"], [false])
+: ${AR=ar}
+
+AC_CACHE_CHECK([the archiver ($AR) interface], [am_cv_ar_interface],
+  [am_cv_ar_interface=ar
+   AC_COMPILE_IFELSE([AC_LANG_SOURCE([[int some_variable = 0;]])],
+     [am_ar_try='$AR cru libconftest.a conftest.$ac_objext >&AS_MESSAGE_LOG_FD'
+      AC_TRY_EVAL([am_ar_try])
+      if test "$ac_status" -eq 0; then
+        am_cv_ar_interface=ar
+      else
+        am_ar_try='$AR -NOLOGO -OUT:conftest.lib conftest.$ac_objext >&AS_MESSAGE_LOG_FD'
+        AC_TRY_EVAL([am_ar_try])
+        if test "$ac_status" -eq 0; then
+          am_cv_ar_interface=lib
+        else
+          am_cv_ar_interface=unknown
+        fi
+      fi
+      rm -f conftest.lib libconftest.a
+     ])
+   ])
+
+case $am_cv_ar_interface in
+ar)
+  ;;
+lib)
+  # Microsoft lib, so override with the ar-lib wrapper script.
+  # FIXME: It is wrong to rewrite AR.
+  # But if we don't then we get into trouble of one sort or another.
+  # A longer-term fix would be to have automake use am__AR in this case,
+  # and then we could set am__AR="$am_aux_dir/ar-lib \$(AR)" or something
+  # similar.
+  AR="$am_aux_dir/ar-lib $AR"
+  ;;
+unknown)
+  m4_default([$1],
+             [AC_MSG_ERROR([could not determine $AR interface])])
+  ;;
+esac
+AC_SUBST([AR])dnl
+])
+
+# AM_AUX_DIR_EXPAND                                         -*- Autoconf -*-
+
+# Copyright (C) 2001-2013 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-2013 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_CONDITIONAL(NAME, SHELL-CONDITION)
+# -------------------------------------
+# Define a conditional.
+AC_DEFUN([AM_CONDITIONAL],
+[AC_PREREQ([2.52])dnl
+ m4_if([$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-2013 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.
+
+
+# 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", "OBJC", "OBJCXX", "UPC", or "GJC".
+# 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
+
+m4_if([$1], [CC],   [depcc="$CC"   am_compiler_list=],
+      [$1], [CXX],  [depcc="$CXX"  am_compiler_list=],
+      [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
+      [$1], [OBJCXX], [depcc="$OBJCXX" 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".
+  rm -rf conftest.dir
+  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 10 /bin/sh.
+      echo '/* dummy */' > 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
+      ;;
+    msvc7 | msvc7msys | 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], [dnl
+AS_HELP_STRING(
+  [--enable-dependency-tracking],
+  [do not reject slow dependency extractors])
+AS_HELP_STRING(
+  [--disable-dependency-tracking],
+  [speeds up one-time build])])
+if test "x$enable_dependency_tracking" != xno; then
+  am_depcomp="$ac_aux_dir/depcomp"
+  AMDEPBACKSLASH='\'
+  am__nodep='_no'
+fi
+AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
+AC_SUBST([AMDEPBACKSLASH])dnl
+_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl
+AC_SUBST([am__nodep])dnl
+_AM_SUBST_NOTMAKE([am__nodep])dnl
+])
+
+# Generate code to set up dependency tracking.              -*- Autoconf -*-
+
+# Copyright (C) 1999-2013 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_OUTPUT_DEPENDENCY_COMMANDS
+# ------------------------------
+AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
+[{
+  # Older Autoconf 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"`
+    # 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'`; 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"])
+])
+
+# Do all the work for Automake.                             -*- Autoconf -*-
+
+# Copyright (C) 1996-2013 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 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.65])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],
+[AC_DIAGNOSE([obsolete],
+             [$0: two- and three-arguments forms are deprecated.])
+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], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]),
+  [ok:ok],,
+  [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([AC_PROG_MKDIR_P])dnl
+# For better backward compatibility.  To be removed once Automake 1.9.x
+# dies out for good.  For more background, see:
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
+AC_SUBST([mkdir_p], ['$(MKDIR_P)'])
+# 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])],
+		  [m4_define([AC_PROG_CC],
+			     m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_CXX],
+		  [_AM_DEPENDENCIES([CXX])],
+		  [m4_define([AC_PROG_CXX],
+			     m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_OBJC],
+		  [_AM_DEPENDENCIES([OBJC])],
+		  [m4_define([AC_PROG_OBJC],
+			     m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_OBJCXX],
+		  [_AM_DEPENDENCIES([OBJCXX])],
+		  [m4_define([AC_PROG_OBJCXX],
+			     m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl
+])
+AC_REQUIRE([AM_SILENT_RULES])dnl
+dnl The testsuite driver may need to know about EXEEXT, so add the
+dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen.  This
+dnl macro 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-2013 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-2013 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.
+
+# 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-2013 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_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 enable maintainer-specific portions of Makefiles])
+  dnl maintainer-mode's default is 'disable' unless 'enable' is passed
+  AC_ARG_ENABLE([maintainer-mode],
+    [AS_HELP_STRING([--]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
+]
+)
+
+# Check to see how 'make' treats includes.	            -*- Autoconf -*-
+
+# Copyright (C) 2001-2013 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_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-2013 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_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 is modern enough.
+# If it is, 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 --is-lightweight"; then
+  am_missing_run="$MISSING "
+else
+  am_missing_run=
+  AC_MSG_WARN(['missing' script is too old or missing])
+fi
+])
+
+# Helper functions for option handling.                     -*- Autoconf -*-
+
+# Copyright (C) 2001-2013 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_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-2013 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_SANITY_CHECK
+# ---------------
+AC_DEFUN([AM_SANITY_CHECK],
+[AC_MSG_CHECKING([whether build environment is sane])
+# 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 (
+   am_has_slept=no
+   for am_try in 1 2; do
+     echo "timestamp, slept: $am_has_slept" > conftest.file
+     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
+     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
+     if test "$[2]" = conftest.file || test $am_try -eq 2; then
+       break
+     fi
+     # Just in case.
+     sleep 1
+     am_has_slept=yes
+   done
+   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])
+# If we didn't sleep, we still need to ensure time stamps of config.status and
+# generated files are strictly newer.
+am_sleep_pid=
+if grep 'slept: no' conftest.file >/dev/null 2>&1; then
+  ( sleep 1 ) &
+  am_sleep_pid=$!
+fi
+AC_CONFIG_COMMANDS_PRE(
+  [AC_MSG_CHECKING([that generated files are newer than configure])
+   if test -n "$am_sleep_pid"; then
+     # Hide warnings about reused PIDs.
+     wait $am_sleep_pid 2>/dev/null
+   fi
+   AC_MSG_RESULT([done])])
+rm -f conftest.file
+])
+
+# Copyright (C) 2009-2013 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_SILENT_RULES([DEFAULT])
+# --------------------------
+# Enable less verbose build rules; with the default set to DEFAULT
+# ("yes" being less verbose, "no" or empty being verbose).
+AC_DEFUN([AM_SILENT_RULES],
+[AC_ARG_ENABLE([silent-rules], [dnl
+AS_HELP_STRING(
+  [--enable-silent-rules],
+  [less verbose build output (undo: "make V=1")])
+AS_HELP_STRING(
+  [--disable-silent-rules],
+  [verbose build output (undo: "make V=0")])dnl
+])
+case $enable_silent_rules in @%:@ (((
+  yes) AM_DEFAULT_VERBOSITY=0;;
+   no) AM_DEFAULT_VERBOSITY=1;;
+    *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);;
+esac
+dnl
+dnl A few 'make' implementations (e.g., NonStop OS and NextStep)
+dnl do not support nested variable expansions.
+dnl See automake bug#9928 and bug#10237.
+am_make=${MAKE-make}
+AC_CACHE_CHECK([whether $am_make supports nested variables],
+   [am_cv_make_support_nested_variables],
+   [if AS_ECHO([['TRUE=$(BAR$(V))
+BAR0=false
+BAR1=true
+V=1
+am__doit:
+	@$(TRUE)
+.PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then
+  am_cv_make_support_nested_variables=yes
+else
+  am_cv_make_support_nested_variables=no
+fi])
+if test $am_cv_make_support_nested_variables = yes; then
+  dnl Using '$V' instead of '$(V)' breaks IRIX make.
+  AM_V='$(V)'
+  AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
+else
+  AM_V=$AM_DEFAULT_VERBOSITY
+  AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY
+fi
+AC_SUBST([AM_V])dnl
+AM_SUBST_NOTMAKE([AM_V])dnl
+AC_SUBST([AM_DEFAULT_V])dnl
+AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl
+AC_SUBST([AM_DEFAULT_VERBOSITY])dnl
+AM_BACKSLASH='\'
+AC_SUBST([AM_BACKSLASH])dnl
+_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl
+])
+
+# Copyright (C) 2001-2013 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-2013 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_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-2013 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_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.  Yes, it's still used
+# in the wild :-(  We should find a proper way to deprecate it ...
+AC_SUBST([AMTAR], ['$${TAR-tar}'])
+
+# We'll loop over all known methods to create a tar archive until one works.
+_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
+
+m4_if([$1], [v7],
+  [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'],
+
+  [m4_case([$1],
+    [ustar],
+     [# The POSIX 1988 'ustar' format is defined with fixed-size fields.
+      # There is notably a 21 bits limit for the UID and the GID.  In fact,
+      # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343
+      # and bug#13588).
+      am_max_uid=2097151 # 2^21 - 1
+      am_max_gid=$am_max_uid
+      # The $UID and $GID variables are not portable, so we need to resort
+      # to the POSIX-mandated id(1) utility.  Errors in the 'id' calls
+      # below are definitely unexpected, so allow the users to see them
+      # (that is, avoid stderr redirection).
+      am_uid=`id -u || echo unknown`
+      am_gid=`id -g || echo unknown`
+      AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format])
+      if test $am_uid -le $am_max_uid; then
+         AC_MSG_RESULT([yes])
+      else
+         AC_MSG_RESULT([no])
+         _am_tools=none
+      fi
+      AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format])
+      if test $am_gid -le $am_max_gid; then
+         AC_MSG_RESULT([yes])
+      else
+        AC_MSG_RESULT([no])
+        _am_tools=none
+      fi],
+
+  [pax],
+    [],
+
+  [m4_fatal([Unknown tar format])])
+
+  AC_MSG_CHECKING([how to create a $1 tar archive])
+
+  # Go ahead even if we have the value already cached.  We do so because we
+  # need to set the values for the 'am__tar' and 'am__untar' variables.
+  _am_tools=${am_cv_prog_tar_$1-$_am_tools}
+
+  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])
+      AM_RUN_LOG([cat conftest.dir/file])
+      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([../m4/ax_append_compile_flags.m4])
+m4_include([../m4/ax_append_flag.m4])
+m4_include([../m4/ax_append_link_flags.m4])
+m4_include([../m4/ax_check_compile_flag.m4])
+m4_include([../m4/ax_check_link_flag.m4])
+m4_include([../m4/ax_prefix_config_h.m4])
+m4_include([../m4/flags.m4])
+m4_include([../m4/flint-check.m4])
+m4_include([../m4/gmp-check.m4])
+m4_include([../m4/libtool.m4])
+m4_include([../m4/ltoptions.m4])
+m4_include([../m4/ltsugar.m4])
+m4_include([../m4/ltversion.m4])
+m4_include([../m4/lt~obsolete.m4])
+m4_include([../m4/ntl-check.m4])
+m4_include([../m4/options.m4])
+m4_include([acinclude.m4])
diff --git a/factory/aminclude.am b/factory/aminclude.am
new file mode 100644
index 0000000..420049e
--- /dev/null
+++ b/factory/aminclude.am
@@ -0,0 +1,186 @@
+# Copyright (C) 2004 Oren Ben-Kiki
+# This file is distributed under the same terms as the Automake macro files.
+
+# Generate automatic documentation using Doxygen. Goals and variables values
+# are controlled by the various DX_COND_??? conditionals set by autoconf.
+#
+# The provided goals are:
+# doxygen-doc: Generate all doxygen documentation.
+# doxygen-run: Run doxygen, which will generate some of the documentation
+#              (HTML, CHM, CHI, MAN, RTF, XML) but will not do the post
+#              processing required for the rest of it (PS, PDF, and some MAN).
+# doxygen-man: Rename some doxygen generated man pages.
+# doxygen-ps: Generate doxygen PostScript documentation.
+# doxygen-pdf: Generate doxygen PDF documentation.
+#
+# Note that by default these are not integrated into the automake goals. If
+# doxygen is used to generate man pages, you can achieve this integration by
+# setting man3_MANS to the list of man pages generated and then adding the
+# dependency:
+#
+#   $(man3_MANS): doxygen-doc
+#
+# This will cause make to run doxygen and generate all the documentation.
+#
+# The following variable is intended for use in Makefile.am:
+#
+# DX_CLEANFILES = everything to clean.
+#
+# This is usually added to MOSTLYCLEANFILES.
+
+## --------------------------------- ##
+## Format-independent Doxygen rules. ##
+## --------------------------------- ##
+
+if DX_COND_doc
+
+## ------------------------------- ##
+## Rules specific for HTML output. ##
+## ------------------------------- ##
+
+if DX_COND_html
+
+DX_CLEAN_HTML = @DX_DOCDIR@/html
+
+endif DX_COND_html
+
+## ------------------------------ ##
+## Rules specific for CHM output. ##
+## ------------------------------ ##
+
+if DX_COND_chm
+
+DX_CLEAN_CHM = @DX_DOCDIR@/chm
+
+if DX_COND_chi
+
+DX_CLEAN_CHI = @DX_DOCDIR@/@PACKAGE at .chi
+
+endif DX_COND_chi
+
+endif DX_COND_chm
+
+## ------------------------------ ##
+## Rules specific for MAN output. ##
+## ------------------------------ ##
+
+if DX_COND_man
+
+DX_CLEAN_MAN = @DX_DOCDIR@/man
+
+endif DX_COND_man
+
+## ------------------------------ ##
+## Rules specific for RTF output. ##
+## ------------------------------ ##
+
+if DX_COND_rtf
+
+DX_CLEAN_RTF = @DX_DOCDIR@/rtf
+
+endif DX_COND_rtf
+
+## ------------------------------ ##
+## Rules specific for XML output. ##
+## ------------------------------ ##
+
+if DX_COND_xml
+
+DX_CLEAN_XML = @DX_DOCDIR@/xml
+
+endif DX_COND_xml
+
+## ----------------------------- ##
+## Rules specific for PS output. ##
+## ----------------------------- ##
+
+if DX_COND_ps
+
+DX_CLEAN_PS = @DX_DOCDIR@/@PACKAGE at .ps
+
+DX_PS_GOAL = doxygen-ps
+
+doxygen-ps: @DX_DOCDIR@/@PACKAGE at .ps
+
+ at DX_DOCDIR@/@PACKAGE at .ps: @DX_DOCDIR@/@PACKAGE at .tag
+	cd @DX_DOCDIR@/latex; \
+	rm -f *.aux *.toc *.idx *.ind *.ilg *.log *.out; \
+	$(DX_LATEX) refman.tex; \
+	$(MAKEINDEX_PATH) refman.idx; \
+	$(DX_LATEX) refman.tex; \
+	countdown=5; \
+	while $(DX_EGREP) 'Rerun (LaTeX|to get cross-references right)' \
+	                  refman.log > /dev/null 2>&1 \
+	   && test $$countdown -gt 0; do \
+	    $(DX_LATEX) refman.tex; \
+	    countdown=`expr $$countdown - 1`; \
+	done; \
+	$(DX_DVIPS) -o ../@PACKAGE at .ps refman.dvi
+
+endif DX_COND_ps
+
+## ------------------------------ ##
+## Rules specific for PDF output. ##
+## ------------------------------ ##
+
+if DX_COND_pdf
+
+DX_CLEAN_PDF = @DX_DOCDIR@/@PACKAGE at .pdf
+
+DX_PDF_GOAL = doxygen-pdf
+
+doxygen-pdf: @DX_DOCDIR@/@PACKAGE at .pdf
+
+ at DX_DOCDIR@/@PACKAGE at .pdf: @DX_DOCDIR@/@PACKAGE at .tag
+	cd @DX_DOCDIR@/latex; \
+	rm -f *.aux *.toc *.idx *.ind *.ilg *.log *.out; \
+	$(DX_PDFLATEX) refman.tex; \
+	$(DX_MAKEINDEX) refman.idx; \
+	$(DX_PDFLATEX) refman.tex; \
+	countdown=5; \
+	while $(DX_EGREP) 'Rerun (LaTeX|to get cross-references right)' \
+	                  refman.log > /dev/null 2>&1 \
+	   && test $$countdown -gt 0; do \
+	    $(DX_PDFLATEX) refman.tex; \
+	    countdown=`expr $$countdown - 1`; \
+	done; \
+	mv refman.pdf ../@PACKAGE at .pdf
+
+endif DX_COND_pdf
+
+## ------------------------------------------------- ##
+## Rules specific for LaTeX (shared for PS and PDF). ##
+## ------------------------------------------------- ##
+
+if DX_COND_latex
+
+DX_CLEAN_LATEX = @DX_DOCDIR@/latex
+
+endif DX_COND_latex
+
+.PHONY: doxygen-run doxygen-doc $(DX_PS_GOAL) $(DX_PDF_GOAL)
+
+.INTERMEDIATE: doxygen-run $(DX_PS_GOAL) $(DX_PDF_GOAL)
+
+doxygen-run: @DX_DOCDIR@/@PACKAGE at .tag
+
+doxygen-doc: doxygen-run $(DX_PS_GOAL) $(DX_PDF_GOAL)
+
+ at DX_DOCDIR@/@PACKAGE at .tag: $(DX_CONFIG) $(pkginclude_HEADERS)
+	rm -rf @DX_DOCDIR@
+	$(DX_ENV) $(DX_DOXYGEN) $(srcdir)/$(DX_CONFIG)
+
+DX_CLEANFILES = \
+    @DX_DOCDIR@/@PACKAGE at .tag \
+    -r \
+    $(DX_CLEAN_HTML) \
+    $(DX_CLEAN_CHM) \
+    $(DX_CLEAN_CHI) \
+    $(DX_CLEAN_MAN) \
+    $(DX_CLEAN_RTF) \
+    $(DX_CLEAN_XML) \
+    $(DX_CLEAN_PS) \
+    $(DX_CLEAN_PDF) \
+    $(DX_CLEAN_LATEX)
+
+endif DX_COND_doc
diff --git a/factory/bin/fold-docu.el b/factory/bin/fold-docu.el
new file mode 100644
index 0000000..82da1fc
--- /dev/null
+++ b/factory/bin/fold-docu.el
@@ -0,0 +1,21 @@
+;; emacs edit mode for this file is -*- Emacs-Lisp -*-
+
+;;{{{ docu
+;;
+;; fold-docu.el - fold all documentation foldings in a file.
+;;
+;; To unfold all documentation, call fold-open-buffer.
+;;
+;;}}}
+
+(require 'folding)
+
+(defun fold-docu ()
+  "Fold all documentation foldings in a file."
+  (interactive)
+  (goto-char (point-min))
+  (save-excursion
+    (while (re-search-forward "{{{ .*docu$" nil t)
+      (fold-hide))))
+
+(provide 'fold-docu)
diff --git a/factory/bin/folding.el b/factory/bin/folding.el
new file mode 100644
index 0000000..172df53
--- /dev/null
+++ b/factory/bin/folding.el
@@ -0,0 +1,1806 @@
+;; @(#) folding.el -- A folding-editor-like minor mode 1.7
+
+;; Copyright (C) 1992, 1993, Jamie Lokier.  All rights reserved.
+
+;; This file is intended to be used with GNU Emacs.
+
+;; 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 GNU Emacs; see the file COPYING.  If not, write to
+;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+;; ---------------------------------------------------------------------
+
+;; This is version 1.7 of Folding mode, under development.
+
+;; This file has been edited with a folding editor (itself! :-).
+
+;; Send suggestions and/or bug fixes to "u90jl at ecs.ox.ac.uk".
+
+;; If you can, please check the most recent version of Folding mode
+;; before reporting bugs.  If you can't, don't be afraid of reporting
+;; bugs anyway.
+
+;;{{{ Information
+
+;; ----------------------- Archive information --------------------------
+
+;; LCD Archive Entry:
+;; folding|Jamie Lokier|u90jl at ecs.ox.ac.uk|
+;; A folding-editor-like minor mode|
+;; 06-Jul-1993|1.7|~/modes/folding.el.Z|
+
+;; -------------------------- Installation ------------------------------
+
+;; To install Folding mode, put this file (folding.el) on you Emacs-Lisp
+;; load path, and put the following in your .emacs:
+;;
+;; (autoload 'folding-mode "folding"
+;;  "Minor mode that simulates a folding editor" t)
+;;
+;; To have Folding mode start automatically when opening folded files,
+;; add the following to your .emacs as well:
+;;
+;; (defun folding-mode-find-file-hook ()
+;;   "One of the hooks called whenever a `find-file' is successful."
+;;   (and (assq 'folded-file (buffer-local-variables))
+;;        folded-file
+;;        (folding-mode 1)
+;;        (kill-local-variable 'folded-file)))
+;;
+;; (or (memq 'folding-mode-find-file-hook find-file-hooks)
+;;     (setq find-file-hooks (append find-file-hooks
+;;                                   '(folding-mode-find-file-hook))))
+;;
+;; If you load folding.el all the time during startup, none of the above
+;; is necessary; it can be replaced with this after loading folding.el:
+;;
+;; (folding-mode-add-find-file-hook)
+;;
+;; Brief documentation for Folding mode (what it is, how you use it) is
+;; provided with the definition of the function `folding-mode'.
+;;
+;; The best way to learn how to use Folding mode after installing it is
+;; to find-file the source, M-x eval-current-buffer, M-x folding-mode,
+;; and move in and out of the folds.  Keys are documented under the
+;; function `folding-mode', though you might want to customize them.
+;; Keys in folding mode are bound in the keymap `folding-mode-map'.
+
+;; --------------------------- And the rest -----------------------------
+
+;; There are is no real documentation yet; I haven't had time.  I intend
+;; to write some one day, but I will refrain from predicting when.  Read
+;; the documentation for the function `folding-mode' for the most useful
+;; tips.
+
+;; Emacs 18:
+;; Folding mode has been tested with versions 18.55 and 18.58 of Emacs.
+
+;; Epoch:
+;; Folding mode has been tested on Epoch 4.0p2.
+
+;; Lucid Emacs:
+;; There is code in here to handle some aspects of Lucid Emacs.
+;; However, up to version 19.6, there appears to be no way to display
+;; folds.  Selective-display does not work, and neither do invisible
+;; extents, so Folding mode has no chance of working.  This is likely to
+;; change in future versions of Lucid Emacs.
+
+;; Emacs 19:
+;; Tested on version 19.8, appears to be fine.
+;; Minor bug: display the buffer in several different frames, then move
+;; in and out of folds in the buffer.  The frames are automatically
+;; moved to the top of the stacking order.
+
+;; Some of the code is quite horrible, generally in order to avoid some
+;; Emacs display "features".  Some of it is specific to certain versions
+;; of Emacs.  By the time Emacs 19 is around and everyone is using it,
+;; hopefully most of it won't be necessary.
+
+;; ------------------------ More known bugs -----------------------------
+
+;; *** Needs fold-fold-region to be more intelligent about
+;; finding a good region.  Check folding a whole current fold.
+
+;; *** Now works with 19!  But check out what happens when you exit a
+;; fold with the file displayed in two frames.  Both windows get
+;; fronted.  Better fix that sometime.
+
+;; ------------------------- Future features ----------------------------
+
+;; *** I will add a `fold-next-error' sometime.  It will only work with
+;; Emacs versions later than 18.58, because compile.el in earlier
+;; versions does not count line-numbers in the right way, when selective
+;; display is active.
+
+;; *** Fold titles should be optionally allowed on the closing fold
+;; marks, and `fold-tidy-inside' should check that the opening title
+;; matches the closing title.
+
+;; *** `folded-file' set in the local variables at the end of a file
+;; could encode the type of fold marks used in that file, and other
+;; things, like the margins inside folds.
+
+;; *** I can see a lot of use for the newer features of Emacs 19:
+;;
+;;   Using invisible text-properties (I hope they are intended to
+;;   make text invisible; it isn't implemented like that yet), it
+;;   will be possible to hide folded text without affecting the
+;;   text of the buffer.  At the moment, Folding mode uses
+;;   selective display to hide text, which involves substituting
+;;   carriage-returns for line-feeds in the buffer.  This isn't
+;;   such a good way.  It may also be possible to display
+;;   different folds in different windows in Emacs 19.
+;;
+;;   Using even more text-properties, it may be possible to track
+;;   pointer movements in and out of folds, and have Folding mode
+;;   automatically enter or exit folds as necessary to maintain a
+;;   sensible display.  Because the text itself is not modified
+;;   (if overlays are used to hide text), this is quite safe.  It
+;;   would make it unnecessary to provide functions like
+;;   `fold-forward-char', `fold-goto-line' or `fold-next-error',
+;;   and things like I-search would automatically move in and out
+;;   of folds as necessary.
+;;
+;;   Yet more text-properties/overlays might make it possible to
+;;   avoid using narrowing.  This might allow some major modes to
+;;   indent text properly, e.g., C++ mode.
+
+
+;; ------------------------- History ------------------------------------
+;; Dec 1 1994 Jari Aalto , <jaalto at tre.tele.nokia.fi>
+;; - Only minor change. Made the folding mode string user configurable.
+;;   Added these variables:
+;;   o	   folding-mode-v-str , fold-v-inside-in-str,fold-v-inside-in-fold-str
+;; - Changed revision number from 1.6.2 to 1.7 , so that people know
+;;   this el has changed.
+;; - Advertise: I made couple of extra functions for this module, please
+;;   look at the goodies in tinyfold.el.
+
+;;}}}
+;;{{{ Declare `folding' as a feature
+
+(provide 'folding)
+
+;;}}}
+;;{{{ Check Emacs version and set some constants.
+
+;; Sets `fold-emacs-version' to `epoch, `lucid, or the numbers 18 or 19,
+;; as appropriate, and sets a few related variables.
+
+(setq fold-epoch-screens-p nil
+      fold-lucid-screens-p nil
+      fold-lucid-keymaps-p nil
+      fold-emacs-frames-p nil)
+
+(let ((case-fold-search t))
+  (cond ((boundp 'epoch::version)		;; Epoch
+	 (setq fold-epoch-screens-p t))
+	((string-match "lucid" emacs-version)	;; Lucid Emacs
+	 (setq fold-lucid-screens-p t
+	       fold-lucid-keymaps-p t))
+	((string< emacs-version "19"))		;; Emacs 18.x (or less)
+	(t					;; Emacs 19+
+	 (setq fold-emacs-frames-p t))))
+
+;;}}}
+
+;;{{{ Start Folding mode, and related items.  Documentation is here
+
+;;{{{ folding-mode the variable
+
+(defvar folding-mode nil
+  "Non-nil means Folding mode is active in the current buffer.")
+
+(make-variable-buffer-local 'folding-mode)
+(set-default 'folding-mode nil)
+
+(defvar folding-mode-v-str "Fld"
+  "*The minor mode string displayed when it's on.")
+
+;;}}}
+;;{{{ folding-mode the function
+
+(defun folding-mode (&optional arg inter)
+  "Turns Folding mode (a minor mode) on and off.
+
+These are the basic commands that Folding mode provides:
+\\<folding-mode-map>
+fold-enter:	    `\\[fold-enter]'
+     Enters the fold that the point is on.
+
+fold-exit:	    `\\[fold-exit]'
+     Exits the current fold.
+
+fold-fold-region:   `\\[fold-fold-region]'
+     Surrounds the region with a new fold.
+
+fold-top-level:	    `\\[fold-top-level]'
+     Exits all folds.
+
+fold-show:	    `\\[fold-show]'
+     Opens the fold that the point is on, but does not enter it.
+
+fold-hide:	    `\\[fold-hide]'
+     Closes the fold that the point is in, exiting it if necessary.
+
+fold-whole-buffer:  `\\[fold-whole-buffer]'
+     Folds the whole buffer.
+
+fold-open-buffer:   `\\[fold-open-buffer]'
+     Unfolds the whole buffer; good to do just before a search.
+
+fold-remove-folds:  `\\[fold-remove-folds]'
+     Makes a ready-to-print, formatted, unfolded copy in another buffer.
+
+Read the documentation for the above functions for more information.
+
+Folds are a way of hierarchically organising the text in a file, so that
+the text can be viewed and edited at different levels.  It is similar to
+Outline mode in that parts of the text can be hidden from view.  A fold
+is a region of text, surrounded by special \"fold marks\", which act
+like brackets, grouping the text.  Fold mark pairs can be nested, and
+they can have titles.  When a fold is folded, the text is hidden from
+view, except for the first line, which acts like a title for the fold.
+
+Folding mode is a minor mode, designed to cooperate with many other
+major modes, so that many types of text can be folded while they are
+being edited (eg., plain text, program source code, Texinfo, etc.).
+
+For most types of folded file, lines representing folds have \"{{{\"
+near the beginning.  To enter a fold, move the point to the folded line
+and type `\\[fold-enter]'.  You should no longer be able to see the rest
+of the file, just the contents of the fold, which you couldn't see
+before.  You can use `\\[fold-exit]' to leave a fold, and you can enter
+and exit folds to move around the structure of the file.
+
+All of the text is present in a folded file all of the time.  It is just
+hidden.  Folded text shows up as a line (the top fold mark) with \"...\"
+at the end.  If you are in a fold, the mode line displays \"inside n
+folds Narrow\", and because the buffer is narrowed you can't see outside
+of the current fold's text.
+
+By arranging sections of a large file in folds, and maybe subsections in
+sub-folds, you can move around a file quickly and easily, and only have
+to scroll through a couple of pages at a time.  If you pick the titles
+for the folds carefully, they can be a useful form of documentation, and
+make moving though the file a lot easier.  In general, searching through
+a folded file for a particular item is much easier than without folds.
+
+To make a new fold, set the mark at one end of the text you want in the
+new fold, and move the point to the other end.  Then type
+`\\[fold-fold-region]'.  The text you selected will be made into a fold,
+and the fold will be entered.  If you just want a new, empty fold, set
+the mark where you want the fold, and then create a new fold there
+without moving the point.  Don't worry if the point is in the middle of
+a line of text, `fold-fold-region' will not break text in the middle of
+a line.  After making a fold, the fold is entered and the point is
+positioned ready to enter a title for the fold.  Do not delete the fold
+marks, which are usually something like \"{{{\" and \"}}}\".  There may
+also be a bit of fold mark which goes after the fold title.
+
+If the fold markers get messed up, or you just want to see the whole
+unfolded file, use `\\[fold-open-buffer]' to unfolded the whole file, so
+you can see all the text and all the marks.  This is useful for
+checking/correcting unbalanced fold markers, and for searching for
+things.  Use `\\[fold-whole-file]' to fold the buffer again.
+
+`fold-exit' will attempt to tidy the current fold just before exiting
+it.  It will remove any extra blank lines at the top and bottom,
+\(outside the fold marks).  It will then ensure that fold marks exists,
+and if they are not, will add them (after asking).  Finally, the number
+of blank lines between the fold marks and the contents of the fold is
+set to 1 (by default).
+
+You can make folded files start Folding mode automatically when they are
+visited by setting `folded-file' to t in the file's local variables.
+For example, having the following at the end of an Emacs-Lisp file
+causes it to be folded when visited:
+
+;; Local variables:
+;; folded-file: t
+;; end:
+
+This only works if you have the appropriate hook set up.  Look up the
+function `folding-mode-add-find-file-hook' for details.
+
+If the fold marks are not set on entry to Folding mode, they are set to
+a default for current major mode, as defined by `fold-mode-marks-alist'
+or to \"{{{ \" and \"}}}\" if none are specified.
+
+To bind different commands to keys in Folding mode, set the bindings in
+the keymap `folding-mode-map'.
+
+The hooks `folding-mode-hook' and `<major-mode-name>-folding-hook' are
+called before folding the buffer and applying the key bindings in
+`folding-mode-map'.  This is a good hook to set extra or different key
+bindings in `folding-mode-map'.  Note that key bindings in
+`folding-mode-map' are only examined just after calling these hooks; new
+bindings in those maps only take effect when Folding mode is being
+started.
+
+If Folding mode is not called interactively (`(interactive-p)' is nil),
+and it is called with two or less arguments, all of which are nil, then
+the point will not be altered if `fold-fold-on-startup' is set and
+`fold-whole-buffer' is called.  This is generally not a good thing, as
+it can leave the point inside a hidden region of a fold, but it is
+required if the local variables set \"mode: folding\" when the file is
+first read (see `hack-local-variables').
+
+Not that you should ever want to, but to call Folding mode from a
+program with the default behaviour (toggling the mode), call it with
+something like `(folding-mode nil t)'.
+
+Here is the full list of keys bound in Folding mode:
+\\{folding-mode-map}"
+  (interactive)
+  (let ((new-folding-mode
+	 (if (not arg) (not folding-mode)
+	   (> (prefix-numeric-value arg) 0))))
+    (or (eq new-folding-mode
+	    folding-mode)
+	(if folding-mode
+	    (progn
+	      (setq selective-display nil)
+	      (fold-clear-stack)
+	      (widen)
+	      (fold-subst-regions (list 1 (point-max)) ?\r ?\n)
+	      (and (boundp 'fold-saved-local-keymap)
+		   (progn
+		     (use-local-map fold-saved-local-keymap)
+		     (kill-local-variable 'fold-saved-local-keymap)
+		     (makunbound 'fold-saved-local-keymap))))
+	  (make-local-variable 'fold-saved-local-keymap)
+	  (setq fold-saved-local-keymap (current-local-map))
+	  (setq selective-display t)
+	  (setq selective-display-ellipses t)
+	  (widen)
+	  (set (make-local-variable 'fold-stack) nil)
+	  (make-local-variable 'fold-top-mark)
+	  (make-local-variable 'fold-secondary-top-mark)
+	  (make-local-variable 'fold-top-regexp)
+	  (make-local-variable 'fold-bottom-mark)
+	  (make-local-variable 'fold-bottom-regexp)
+	  (make-local-variable 'fold-regexp)
+	  (or (and (boundp 'fold-top-regexp)
+		   fold-top-regexp
+		   (boundp 'fold-bottom-regexp)
+		   fold-bottom-regexp)
+	      (let ((fold-marks (assq major-mode
+				      fold-mode-marks-alist)))
+		(if fold-marks
+		    (setq fold-marks (cdr fold-marks))
+		  (setq fold-marks '("{{{ " "}}}")))
+		(apply 'fold-set-marks fold-marks)))
+	  (unwind-protect
+	      (let ((hook-symbol (intern-soft
+				  (concat
+				   (symbol-name major-mode)
+				   "-folding-hook"))))
+		(run-hooks 'folding-mode-hook)
+		(and hook-symbol
+		     (run-hooks hook-symbol)))
+	    (fold-set-mode-line)
+	    (use-local-map
+	     (fold-merge-keymaps (current-local-map) folding-mode-map)))
+	  (and fold-fold-on-startup
+	       (if (or (interactive-p)
+		       arg
+		       inter)
+		   (fold-whole-buffer)
+		 (save-excursion
+		   (fold-whole-buffer))))
+	  (fold-narrow-to-region nil nil t)))
+    (setq folding-mode new-folding-mode)))
+
+;;}}}
+;;{{{ keys: folding-mode-map
+
+(defvar folding-mode-map nil
+  "Keymap used in Folding mode (a minor mode).")
+
+(and fold-lucid-keymaps-p
+     (set-keymap-name folding-mode-map 'folding-mode-map))
+
+(if folding-mode-map
+    nil
+  (setq folding-mode-map (make-sparse-keymap))
+  (define-key folding-mode-map "\M-g" 'fold-goto-line)
+  (define-key folding-mode-map "\C-c>" 'fold-enter)
+  (define-key folding-mode-map "\C-c<" 'fold-exit)
+  (define-key folding-mode-map "\C-c\C-t" 'fold-top-level)
+  (define-key folding-mode-map "\C-c\C-f" 'fold-fold-region)
+  (define-key folding-mode-map "\C-c\C-s" 'fold-show)
+  (define-key folding-mode-map "\C-c\C-x" 'fold-hide)
+  (define-key folding-mode-map "\C-c\C-o" 'fold-open-buffer)
+  (define-key folding-mode-map "\C-c\C-w" 'fold-whole-buffer)
+  (define-key folding-mode-map "\C-c\C-r" 'fold-remove-folds)
+  (define-key folding-mode-map "\C-f" 'fold-forward-char)
+  (define-key folding-mode-map "\C-b" 'fold-backward-char)
+  (define-key folding-mode-map "\C-e" 'fold-end-of-line))
+
+;;}}}
+;;{{{ fold-stack
+
+;; This is a list of structures which keep track of folds being entered
+;; and exited. It is a list of (MARKER . MARKER) pairs, followed by the
+;; symbol `folded'.  The first of these represents the fold containing
+;; the current one.  If the view is currently outside all folds, this
+;; variable has value nil.
+
+(defvar fold-stack nil
+  "A list of marker pairs representing folds entered so far.")
+
+;;}}}
+;;{{{ fold-clear-stack
+
+;; Clear the fold stack, and release all the markers it refers to.
+
+(defun fold-clear-stack ()
+  (let ((stack fold-stack))
+    (setq fold-stack nil)
+    (while (and stack (not (eq 'folded (car stack))))
+      (set-marker (car (car stack)) nil)
+      (set-marker (cdr (car stack)) nil)
+      (setq stack (cdr stack)))))
+
+;;}}}
+;;{{{ fold-mode-string
+
+(defvar fold-mode-string nil
+  "Buffer-local variable that holds the fold depth description.")
+
+(set-default 'fold-mode-string " Fld")  ; to save space...
+
+;;}}}
+;;{{{ fold-set-mode-line
+
+;; Sets `fold-mode-string' appropriately.  This allows the Folding mode
+;; description in the mode line to reflect the current fold depth."
+
+(defconst fold-v-inside-in-str " "      ; normally ' inside ', but save space..
+  "*Mode line addition to show 'inside' levels of fold.")
+
+(defconst fold-v-inside-in-fold-str "Fld"   ; normally 'fold', but save space..
+  "*Mode line addition to show inside levels of 'fold' .")
+
+(defun fold-set-mode-line ()
+  (if (null fold-stack)
+      (kill-local-variable 'fold-mode-string)
+    (make-local-variable 'fold-mode-string)
+    (setq fold-mode-string
+	  (if (eq 'folded (car fold-stack))
+	      (concat
+	       fold-v-inside-in-str "1" fold-v-inside-in-fold-str)
+	    (concat
+	     fold-v-inside-in-str
+	     (length fold-stack)
+	     fold-v-inside-in-fold-str)
+	    ))))
+
+;;}}}
+;;{{{ Update minor-mode-alist
+
+(or (assq 'folding-mode minor-mode-alist)
+    (setq minor-mode-alist
+		(cons '(folding-mode fold-mode-string)
+		      minor-mode-alist)))
+
+;;}}}
+
+;;}}}
+;;{{{ Hooks and variables
+
+;;{{{ folding-mode-hook
+
+(defvar folding-mode-hook nil
+  "Hook called when Folding mode is entered.
+
+A hook named `<major-mode>-folding-hook' is also called, if it
+exists.  Eg., `c-mode-folding-hook' is called whenever Folding mode is
+started in C mode.")
+
+;;}}}
+;;{{{ fold-fold-on-startup
+
+(defvar fold-fold-on-startup t
+  "*If non-nil, buffers are folded when starting Folding mode.")
+
+;;}}}
+;;{{{ fold-internal-margins
+
+(defvar fold-internal-margins 1
+  "*Number of blank lines left next to fold marks when tidying folds.
+
+This variable is local to each buffer.  To set the default value for all
+buffers, use `set-default'.
+
+When exiting a fold, and at other times, `fold-tidy-inside' is invoked
+to ensure that the fold is in the correct form before leaving it.  This
+variable specifies the number of blank lines to leave between the
+enclosing fold marks and the enclosed text.
+
+If this value is nil or negative, no blank lines are added or removed
+inside the fold marks.  A value of 0 (zero) is valid, meaning leave no
+blank lines.
+
+See also `fold-tidy-inside'.")
+
+(make-variable-buffer-local 'fold-internal-margins)
+
+;;}}}
+;;{{{ fold-mode-marks-alist
+
+(defvar fold-mode-marks-alist nil
+  "List of (major-mode . fold marks) default combinations to use.
+When Folding mode is started, the major mode is checked, and if there
+are fold marks for that major mode stored in `fold-mode-marks-alist',
+those marks are used by default.  If none are found, the default values
+of \"{{{ \" and \"}}}\" are used.")
+
+;;}}}
+
+;;}}}
+;;{{{ Regular expressions for matching fold marks
+
+;;{{{ fold-set-marks
+
+;; You think those "\\(\\)" pairs are peculiar?  Me too.  Emacs regexp
+;; stuff has a bug; sometimes "\\(.*\\)" fails when ".*" succeeds, but
+;; only in a folded file!  Strange bug!  Must check it out sometime.
+
+(defun fold-set-marks (top bottom &optional secondary)
+  "Sets the folding top and bottom marks for the current buffer.
+
+The fold top mark is set to TOP, and the fold bottom mark is set to
+BOTTOM.  And optional SECONDARY top mark can also be specified -- this
+is inserted by `fold-fold-region' after the fold top mark, and is
+presumed to be put after the title of the fold.  This is not necessary
+with the bottom mark because it has no title.
+
+Various regular expressions are set with this function, so don't set the
+mark variables directly."
+  (set (make-local-variable 'fold-top-mark)
+       top)
+  (set (make-local-variable 'fold-bottom-mark)
+       bottom)
+  (set (make-local-variable 'fold-secondary-top-mark)
+       secondary)
+  (set (make-local-variable 'fold-top-regexp)
+       (concat "\\(^\\|\r+\\)[ \t]*"
+	       (regexp-quote fold-top-mark)))
+  (set (make-local-variable 'fold-bottom-regexp)
+       (concat "\\(^\\|\r+\\)[ \t]*"
+	       (regexp-quote fold-bottom-mark)))
+  (set (make-local-variable 'fold-regexp)
+       (concat "\\(^\\|\r\\)\\([ \t]*\\)\\(\\("
+	       (regexp-quote fold-top-mark)
+	       "\\)\\|\\("
+	       (regexp-quote fold-bottom-mark)
+	       "[ \t]*\\(\\)\\($\\|\r\\)\\)\\)")))
+
+;;}}}
+
+;;}}}
+;;{{{ Cursor movement that skips folded regions
+
+;;{{{ fold-forward-char
+
+(defun fold-forward-char (&optional arg)
+  "Move point right ARG characters, skipping hidden folded regions.
+Moves left if ARG is negative.  On reaching end of buffer, stop and
+signal error."
+  (interactive "p")
+  (if (eq arg 1)
+      ;; Do it a faster way for arg = 1.
+      (if (eq (following-char) ?\r)
+	  (let ((saved (point))
+		(inhibit-quit t))
+	    (end-of-line)
+	    (if (not (eobp))
+		(forward-char)
+	      (goto-char saved)
+	      (error "End of buffer")))
+	;; `forward-char' here will do its own error if (eobp).
+	(forward-char))
+    (if (> 0 (or arg (setq arg 1)))
+	(fold-backward-char (- arg))
+      (let (goal saved)
+	(while (< 0 arg)
+	  (skip-chars-forward "^\r" (setq goal (+ (point) arg)))
+	  (if (eq goal (point))
+	      (setq arg 0)
+	    (if (eobp)
+		(error "End of buffer")
+	      (setq arg (- goal 1 (point))
+		    saved (point))
+	      (let ((inhibit-quit t))
+		(end-of-line)
+		(if (not (eobp))
+		    (forward-char)
+		  (goto-char saved)
+		  (error "End of buffer"))))))))))
+
+;;}}}
+;;{{{ fold-backward-char
+
+(defun fold-backward-char (&optional arg)
+  "Move point left ARG characters, skipping hidden folded regions.
+Moves right if ARG is negative.  On reaching beginning of buffer, stop
+and signal error."
+  (interactive "p")
+  (if (eq arg 1)
+      ;; Do it a faster way for arg = 1.
+      ;; Catch the case where we are in a hidden region, and bump into a \r.
+      (if (or (eq (preceding-char) ?\n)
+	      (eq (preceding-char) ?\r))
+	  (let ((pos (1- (point)))
+		(inhibit-quit t))
+	    (forward-char -1)
+	    (beginning-of-line)
+	    (skip-chars-forward "^\r" pos))
+	(forward-char -1))
+    (if (> 0 (or arg (setq arg 1)))
+	(fold-forward-char (- arg))
+      (let (goal)
+	(while (< 0 arg)
+	  (skip-chars-backward "^\r\n" (max (point-min)
+					    (setq goal (- (point) arg))))
+	  (if (eq goal (point))
+	      (setq arg 0)
+	    (if (bobp)
+		(error "Beginning of buffer")
+	      (setq arg (- (point) 1 goal)
+		    goal (point))
+	      (let ((inhibit-quit t))
+		(forward-char -1)
+		(beginning-of-line)
+		(skip-chars-forward "^\r" goal)))))))))
+
+;;}}}
+;;{{{ fold-end-of-line
+
+(defun fold-end-of-line (&optional arg)
+  "Move point to end of current line, but before hidden folded region.
+
+Has the same behavior as `end-of-line', except that if the current line
+ends with some hidden folded text (represented by an ellipsis), the
+point is positioned just before it.  This prevents the point from being
+placed inside the folded text, which is not normally useful."
+  (interactive "p")
+  (if (or (eq arg 1)
+	  (not arg))
+      (beginning-of-line)
+    ;; `forward-line' also moves point to beginning of line.
+    (forward-line (1- arg)))
+  (skip-chars-forward "^\r\n"))
+
+;;}}}
+;;{{{ fold-skip-ellipsis-backward
+
+(defun fold-skip-ellipsis-backward ()
+  "Moves the point backwards out of folded text.
+
+If the point is inside a folded region, the cursor is displayed at the
+end of the ellipsis representing the folded part.  This function checks
+to see if this is the case, and if so, moves the point backwards until
+it is just outside the hidden region, and just before the ellipsis.
+
+Returns t if the point was moved, nil otherwise."
+  (interactive)
+  (let ((pos (point))
+	result)
+    (save-excursion
+      (beginning-of-line)
+      (skip-chars-forward "^\r" pos)
+      (or (eq pos (point))
+	  (setq pos (point)
+		result t)))
+    (goto-char pos)
+    result))
+
+;;}}}
+
+;;}}}
+
+;;{{{ Moving in and out of folds
+
+;;{{{ fold-enter
+
+(defun fold-enter (&optional noerror)
+  "Open and enter the fold at or around the point.
+
+Enters the fold that the point is inside, wherever the point is inside
+the fold, provided it is a valid fold with balanced top and bottom
+marks.  Returns nil if the fold entered contains no sub-folds, t
+otherwise.  If an optional argument NOERROR is non-nil, returns nil if
+there are no folds to enter, instead of causing an error.
+
+If the point is inside a folded, hidden region (as represented by an
+ellipsis), the position of the point in the buffer is preserved, and as
+many folds as necessary are entered to make the surrounding text
+visible.  This is useful after some commands eg., search commands."
+  (interactive)
+  (let ((goal (point)))
+    (if (fold-skip-ellipsis-backward)
+	(while (prog2 (beginning-of-line)
+		      (fold-enter t)
+		      (goto-char goal)))
+      (let ((data (fold-show noerror t)))
+	(and data
+	     (progn
+	       (setq fold-stack
+		     (if fold-stack
+			 (cons (cons (point-min-marker) (point-max-marker))
+			       fold-stack)
+		       '(folded)))
+	       (fold-set-mode-line)
+	       (fold-narrow-to-region (car data) (nth 1 data))
+	       (nth 2 data)))))))
+
+;;}}}
+;;{{{ fold-exit
+
+(defun fold-exit ()
+  "Exits the current fold."
+  (interactive)
+  (if fold-stack
+      (progn
+	(fold-tidy-inside)
+	(fold-subst-regions (list (point-min) (point-max)) ?\n ?\r)
+	(goto-char (point-min))	       ;; So point is correct in other windows.
+	(if (eq (car fold-stack) 'folded)
+	    (fold-narrow-to-region nil nil t)
+	  (fold-narrow-to-region (marker-position (car (car fold-stack)))
+				 (marker-position (cdr (car fold-stack))) t))
+	(and (consp (car fold-stack))
+	     (set-marker (car (car fold-stack)) nil)
+	     (set-marker (cdr (car fold-stack)) nil))
+	(setq fold-stack (cdr fold-stack)))
+    (error "Outside all folds"))
+  (fold-set-mode-line))
+
+;;}}}
+;;{{{ fold-show
+
+(defun fold-show (&optional noerror noskip)
+  "Opens the fold that the point is on, but does not enter it.
+Optional arg NOERROR means don't signal an error if there is no fold,
+just return nil.  NOSKIP means don't jump out of a hidden region first.
+
+Returns ((START END SUBFOLDS-P).  START and END indicate the extents of
+the fold that was shown.  If SUBFOLDS-P is non-nil, the fold contains
+subfolds."
+  (interactive "p")
+  (or noskip
+      (fold-skip-ellipsis-backward))
+  (let ((point (point))
+	backward forward start end subfolds-not-p)
+    (unwind-protect
+	(or (and (integerp (car-safe (setq backward (fold-skip-folds t))))
+		 (integerp (car-safe (setq forward (fold-skip-folds nil))))
+		 (progn
+		   (goto-char (car forward))
+		   (skip-chars-forward "^\r\n")
+		   (setq end (point))
+		   (skip-chars-forward "\r\n")
+		   (not (and fold-stack (eobp))))
+		 (progn
+		   (goto-char (car backward))
+		   (skip-chars-backward "^\r\n")
+		   (setq start (point))
+		   (skip-chars-backward "\r\n")
+		   (not (and fold-stack (bobp))))
+		 (progn
+		   (setq point start)
+		   (setq subfolds-not-p	; Avoid holding the list through a GC.
+			 (not (or (cdr backward) (cdr forward))))
+		   (fold-subst-regions (append backward (nreverse forward))
+				       ?\r ?\n)
+		   (list start end (not subfolds-not-p))))
+	    (if noerror
+		nil
+	      (error "Not on a fold")))
+      (goto-char point))))
+
+;;}}}
+;;{{{ fold-hide
+
+(defun fold-hide ()
+  "Close the fold around the point, undoes effect of `fold-show'."
+  (interactive)
+  (fold-skip-ellipsis-backward)
+  (if (and (integerp (setq start (car-safe (fold-skip-folds t))))
+	   (integerp (setq end (car-safe (fold-skip-folds nil)))))
+      (if (and fold-stack
+	       (or (eq start (point-min))
+		   (eq end (point-max))))
+	  (error "Cannot hide current fold")
+	(goto-char start)
+	(skip-chars-backward "^\r\n")
+	(fold-subst-regions (list start end) ?\n ?\r))
+    (error "Not on a fold")))
+
+;;}}}
+;;{{{ fold-top-level
+
+(defun fold-top-level ()
+  "Exits all folds, to the top level."
+  (interactive)
+  (while fold-stack
+    (fold-exit)))
+
+;;}}}
+;;{{{ fold-goto-line
+
+(defun fold-goto-line (line)
+  "Go to line ARG, entering as many folds as possible."
+  (interactive "nGoto line: ")
+  (fold-top-level)
+  (goto-char 1)
+  (and (< 1 line)
+       (re-search-forward "[\n\C-m]" nil 0 (1- line)))
+  (let ((goal (point)))
+    (while (prog2 (beginning-of-line)
+		  (fold-enter t)
+		  (goto-char goal))))
+  (fold-narrow-to-region (point-min) (point-max) t))
+
+;;}}}
+
+;;}}}
+;;{{{ Searching for fold boundaries
+
+;;{{{ fold-skip-folds
+
+;; Skips forward through the buffer (backward if BACKWARD is non-nil)
+;; until it finds a closing fold mark or the end of the buffer.  The
+;; point is not moved.  Jumps over balanced fold-mark pairs on the way.
+;; Returns t if the end of buffer was found in an unmatched fold-mark
+;; pair, otherwise a list.
+
+;; If the point is actually on an fold start mark, the mark is ignored;
+;; if it is on an end mark, the mark is noted.  This decision is
+;; reversed if BACKWARD is non-nil.  If optional OUTSIDE is non-nil and
+;; BACKWARD is nil, either mark is noted.
+
+;; The first element of the list is a position in the end of the closing
+;; fold mark if one was found, or nil.  It is followed by (END START)
+;; pairs (flattened, not a list of pairs).  The pairs indicating the
+;; positions of folds skipped over; they are positions in the fold
+;; marks, not necessarily at the ends of the fold marks.  They are in
+;; the opposite order to that in which they were skipped.  The point is
+;; left in a meaningless place.  If going backwards, the pairs are
+;; (START END) pairs, as the fold marks are scanned in the opposite
+;; order.
+
+;; Works by maintaining the position of the top and bottom marks found
+;; so far.  They are found separately using a normal string search for
+;; the fixed part of a fold mark (because it is faster than a regexp
+;; search if the string does not occur often outside of fold marks),
+;; checking that it really is a proper fold mark, then considering the
+;; earliest one found.  The position of the other (if found) is
+;; maintained to avoid an unnecessary search at the next iteration.
+
+(defun fold-skip-folds (backward &optional outside)
+  (save-excursion
+    (let ((depth 0) pairs point temp start first last
+	  (first-mark (if backward fold-bottom-mark fold-top-mark))
+	  (last-mark (if backward fold-top-mark fold-bottom-mark))
+	  (search (if backward 'search-backward 'search-forward)))
+      (skip-chars-backward "^\r\n")
+      (if outside
+	  nil
+	(and (eq (preceding-char) ?\r)
+	     (forward-char -1))
+	(if (looking-at fold-top-regexp)
+	    (if backward
+		(setq last (match-end 1))
+	      (skip-chars-forward "^\r\n"))))
+      (while (progn
+	       ;; Find last first, prevents unnecessary searching for first.
+	       (setq point (point))
+	       (or last
+		   (while (and (funcall search last-mark first t)
+			       (progn
+				 (setq temp (point))
+				 (goto-char (match-beginning 0))
+				 (skip-chars-backward " \t")
+				 (and (not (setq last
+						 (if (eq (preceding-char) ?\r)
+						     temp
+						   (and (bolp) temp))))
+				      (goto-char temp)))))
+		   (goto-char point))
+	       (or first
+		   (while (and (funcall search first-mark last t)
+			       (progn
+				 (setq temp (point))
+				 (goto-char (match-beginning 0))
+				 (skip-chars-backward " \t")
+				 (and (not (setq first
+						 (if (eq (preceding-char) ?\r)
+						     temp
+						   (and (bolp) temp))))
+				      (goto-char temp))))))
+	       ;; Return value of conditional says whether to iterate again.
+	       (if (not last)
+		   ;; Return from this with the result.
+		   (not (setq pairs (if first t (cons nil pairs))))
+		 (if (and first (if backward (> first last) (< first last)))
+		     (progn
+		       (goto-char first)
+		       (if (eq 0 depth)
+			   (setq start first
+				 first nil
+				 depth 1) ;; non-nil value, loop again.
+			 (setq first nil
+			       depth (1+ depth)))) ;; non-nil value, loop again
+		   (goto-char last)
+		   (if (eq 0 depth)
+		       (not (setq pairs (cons last pairs)))
+		     (or (< 0 (setq depth (1- depth)))
+			 (setq pairs (cons last (cons start pairs))))
+		     (setq last nil)
+		     t)))))
+      pairs)))
+
+;;}}}
+
+;;}}}
+;;{{{ Functions that actually modify the buffer
+
+;;{{{ fold-fold-region
+
+(defun fold-fold-region (start end)
+  "Places fold marks at the beginning and end of a specified region.
+The region is specified by two arguments START and END.  The point is
+left at a suitable place ready to insert the title of the fold."
+  (interactive "r")
+  (and (< end start)
+       (setq start (prog1 end
+		     (setq end start))))
+  (setq end (set-marker (make-marker) end))
+  (goto-char start)
+  (beginning-of-line)
+  (setq start (point))
+  (insert-before-markers fold-top-mark)
+  (let ((saved-point (point)))
+    (and fold-secondary-top-mark
+	 (insert-before-markers fold-secondary-top-mark))
+    (insert-before-markers ?\n)
+    (goto-char (marker-position end))
+    (set-marker end nil)
+    (and (not (bolp))
+	 (eq 0 (forward-line))
+	 (eobp)
+	 (insert ?\n))
+    (insert fold-bottom-mark)
+    (insert ?\n)
+    (setq fold-stack (if fold-stack
+			    (cons (cons (point-min-marker)
+					(point-max-marker))
+				  fold-stack)
+			  '(folded)))
+    (fold-narrow-to-region start (1- (point)))
+    (goto-char saved-point)
+    (fold-set-mode-line))
+  (save-excursion (fold-tidy-inside)))
+
+;;}}}
+;;{{{ fold-tidy-inside
+
+;; Note to self: The long looking code for checking and modifying those
+;; blank lines is to make sure the text isn't modified unnecessarily.
+;; Don't remove it again!
+
+(defun fold-tidy-inside ()
+  "Adds or removes blank lines at the top and bottom of the current fold.
+Also adds fold marks at the top and bottom (after asking), if they are not
+there already.  The amount of space left depends on the variable
+`fold-internal-margins', which is one by default."
+  (interactive)
+  (if buffer-read-only nil
+    (goto-char (point-min))
+    (and (eolp)
+	 (progn (skip-chars-forward "\n\t ")
+		(delete-region (point-min) (point))))
+    (and (if (looking-at fold-top-regexp)
+	     (progn (forward-line 1)
+		    (and (eobp) (insert ?\n))
+		    t)
+	   (and (y-or-n-p "Insert missing fold-top-mark? ")
+		(progn (insert (concat fold-top-mark
+				       "<Replaced missing fold top mark>"
+				       (or fold-secondary-top-mark "")
+				       "\n"))
+		       t)))
+	 fold-internal-margins
+	 (<= 0 fold-internal-margins)
+	 (let* ((p1 (point))
+		(p2 (progn (skip-chars-forward "\n") (point)))
+		(p3 (progn (skip-chars-forward "\n\t ")
+			   (skip-chars-backward "\t " p2) (point))))
+	   (if (eq p2 p3)
+	       (or (eq p2 (setq p3 (+ p1 fold-internal-margins)))
+		   (if (< p2 p3)
+		       (newline (- p3 p2))
+		     (delete-region p3 p2)))
+	     (delete-region p1 p3)
+	     (or (eq 0 fold-internal-margins)
+		 (newline fold-internal-margins)))))
+    (goto-char (point-max))
+    (and (bolp)
+	 (progn (skip-chars-backward "\n")
+		(delete-region (point) (point-max))))
+    (beginning-of-line)
+    (and (or (looking-at fold-bottom-regexp)
+	     (progn (goto-char (point-max)) nil)
+	     (and (y-or-n-p "Insert missing fold-bottom-mark? ")
+		  (progn
+		    (insert (concat "\n" fold-bottom-mark))
+		    (beginning-of-line)
+		    t)))
+	 fold-internal-margins
+	 (<= 0 fold-internal-margins)
+	 (let* ((p1 (point))
+		(p2 (progn (skip-chars-backward "\n") (point)))
+		(p3 (progn (skip-chars-backward "\n\t ")
+			   (skip-chars-forward "\t " p2) (point))))
+	   (if (eq p2 p3)
+	       (or (eq p2 (setq p3 (- p1 1 fold-internal-margins)))
+		   (if (> p2 p3)
+		       (newline (- p2 p3))
+		     (delete-region p2 p3)))
+	     (delete-region p3 p1)
+	     (newline (1+ fold-internal-margins)))))))
+
+;;}}}
+
+;;}}}
+;;{{{ Operations on the whole buffer
+
+;;{{{ fold-whole-buffer
+
+(defun fold-whole-buffer ()
+  "Folds every fold in the current buffer.
+Fails if the fold markers are not balanced correctly.
+
+If the buffer is being viewed in a fold, folds are repeatedly exited to
+get to the top level first (this allows the folds to be tidied on the
+way out).  The buffer modification flag is not affected, and this
+function will work on read-only buffers."
+
+  (interactive)
+  (message "Folding buffer...")
+  (let ((narrow-min (point-min))
+	(narrow-max (point-max))
+	fold-list fold)
+    (save-excursion
+      (widen)
+      (goto-char 1)
+      (setq fold-list (fold-skip-folds nil t))
+      (narrow-to-region narrow-min narrow-max)
+      (and (eq t fold-list)
+	   (error "Cannot fold whole buffer -- unmatched begin-fold mark"))
+      (and (integerp (car fold-list))
+	   (error "Cannot fold whole buffer -- extraneous end-fold mark"))
+      (fold-top-level)
+      (widen)
+      (goto-char 1)
+      ;; Do the modifications forwards.
+      (fold-subst-regions (nreverse (cdr fold-list)) ?\n ?\r))
+    (beginning-of-line)
+    (fold-narrow-to-region nil nil t)
+    (message "Folding buffer... done")))
+
+;;}}}
+;;{{{ fold-open-buffer
+
+(defun fold-open-buffer ()
+  "Unfolds the entire buffer, leaving the point where it is.
+Does not affect the buffer-modified flag, and can be used on read-only
+buffers."
+  (interactive)
+  (message "Unfolding buffer...")
+  (fold-clear-stack)
+  (fold-set-mode-line)
+  (unwind-protect
+      (progn
+	(widen)
+	(fold-subst-regions (list 1 (point-max)) ?\r ?\n))
+    (fold-narrow-to-region nil nil t))
+  (message "Unfolding buffer... done"))
+
+;;}}}
+;;{{{ fold-remove-folds
+
+(defun fold-remove-folds (&optional buffer pre-title post-title pad)
+  "Removes folds from a buffer, for printing.
+
+It copies the contents of the (hopefully) folded buffer BUFFER into a
+buffer called `*Unfolded: <Original-name>*', removing all of the fold
+marks.  It keeps the titles of the folds, however, and numbers them.
+Subfolds are numbered in the form 5.1, 5.2, 5.3 etc., and the titles are
+indented to eleven characters.
+
+It accepts four arguments.  BUFFER is the name of the buffer to be
+operated on, or a buffer.  nil means use the current buffer.  PRE-TITLE
+is the text to go before the replacement fold titles, POST-TITLE is the
+text to go afterwards.  Finally, if PAD is non-nil, the titles are all
+indented to the same column, which is eleven plus the length of
+PRE-TITLE.  Otherwise just one space is placed between the number and
+the title."
+  (interactive (list (read-buffer "Remove folds from buffer: "
+				  (buffer-name)
+				  t)
+		     (read-string "String to go before enumerated titles: ")
+		     (read-string "String to go after enumerated titles: ")
+		     (y-or-n-p "Pad section numbers with spaces? ")))
+  (set-buffer (setq buffer (get-buffer buffer)))
+  (setq pre-title (or pre-title "")
+	post-title (or post-title ""))
+  (or folding-mode
+      (error "Must be in Folding mode before removing folds"))
+  (let ((new-buffer (get-buffer-create (concat "*Unfolded: "
+					       (buffer-name buffer)
+					       "*")))
+	(section-list '(1))
+	(section-prefix-list '(""))
+	title
+	(secondary-mark-length (length fold-secondary-top-mark))
+	(regexp fold-regexp)
+	(secondary-mark fold-secondary-top-mark)
+	prefix
+	(mode major-mode))
+    (buffer-flush-undo new-buffer)
+    (save-excursion
+      (set-buffer new-buffer)
+      (delete-region (point-min)
+		     (point-max)))
+    (save-restriction
+      (widen)
+      (copy-to-buffer new-buffer (point-min) (point-max)))
+    (display-buffer new-buffer t)
+    (set-buffer new-buffer)
+    (subst-char-in-region (point-min) (point-max) ?\r ?\n)
+    (funcall mode)
+    (while (re-search-forward regexp nil t)
+      (if (match-beginning 4)
+	  (progn
+	    (goto-char (match-end 4))
+	    (setq title
+		  (buffer-substring (point)
+				    (progn (end-of-line)
+					   (point))))
+	    (delete-region (save-excursion
+			     (goto-char (match-beginning 4))
+			     (skip-chars-backward "\n\r")
+			     (point))
+			   (progn
+			     (skip-chars-forward "\n\r")
+			     (point)))
+	    (and (<= secondary-mark-length
+		     (length title))
+		 (string-equal secondary-mark
+			       (substring title
+					  (- secondary-mark-length)))
+		 (setq title (substring title
+					0
+					(- secondary-mark-length))))
+	    (setq section-prefix-list
+		  (cons (setq prefix (concat (car section-prefix-list)
+					     (int-to-string (car section-list))
+					     "."))
+			section-prefix-list))
+	    (or (cdr section-list)
+		(insert ?\n))
+	    (setq section-list
+		  (cons 1
+			(cons (1+ (car section-list))
+			      (cdr section-list))))
+	    (setq title (concat prefix
+				(if pad
+				    (make-string
+				     (max 2 (- 8 (length prefix))) ? )
+				  " ")
+				title))
+	    (message "Reformatting: %s%s%s"
+		     pre-title
+		     title
+		     post-title)
+	    (insert "\n\n"
+		    pre-title
+		    title
+		    post-title
+		    "\n\n"))
+	(goto-char (match-beginning 5))
+	(or (setq section-list (cdr section-list))
+	    (error "Too many bottom-of-fold marks"))
+	(setq section-prefix-list (cdr section-prefix-list))
+	(delete-region (point)
+		       (progn
+			 (forward-line 1)
+			 (point)))))
+    (and (cdr section-list)
+	 (error
+	  "Too many top-of-fold marks -- reached end of file prematurely"))
+    (goto-char (point-min))
+    (buffer-enable-undo)
+    (set-buffer-modified-p nil)
+    (message "All folds reformatted.")))
+
+;;}}}
+;;}}}
+
+;;{{{ Standard fold marks for various major modes
+
+;;{{{ A function to set default marks, `fold-add-to-marks-list'
+
+(defun fold-add-to-marks-list (mode top bottom
+				    &optional secondary noforce message)
+  "Add/set fold marks for a particular major mode.
+When called interactively, asks for a major-mode name, and for
+fold marks to be used in that mode.  It adds the new set to
+`fold-mode-marks-alist', and if the mode name is the same as the current
+major mode for the current buffer, the marks in use are also changed.
+
+If called non-interactively, arguments are MODE, TOP, BOTTOM and
+SECONDARY.  MODE is the symbol for the major mode for which marks are
+being set.  TOP, BOTTOM and SECONDARY are strings, the three fold marks
+to be used.  SECONDARY may be nil (as opposed to the empty string), but
+the other two must be non-empty strings, and is an optional argument.
+
+Two other optional arguments are NOFORCE, meaning do not change the
+marks if marks are already set for the specified mode if non-nil, and
+MESSAGE, which causes a message to be displayed if it is non-nil.  This
+is also the message displayed if the function is called interactively.
+
+To set default fold marks for a particular mode, put something like the
+following in your .emacs:
+
+\(fold-add-to-marks-list 'major-mode \"(** {{{ \" \"(** }}} **)\" \" **)\")
+
+Look at the variable `fold-mode-marks-alist' to see what default settings
+already apply.
+
+`fold-set-marks' can be used to set the fold marks in use in the current
+buffer without affecting the default value for a particular mode."
+  (interactive
+   (let* ((mode (completing-read
+		 (concat "Add fold marks for major mode ("
+			 (symbol-name major-mode)
+			 "): ")
+		 obarray
+		 (function
+		  (lambda (arg)
+		    (and (commandp arg)
+			 (string-match "-mode\\'"
+				       (symbol-name arg)))))
+		 t))
+	  (mode (if (equal mode "")
+		    major-mode
+		  (intern mode)))
+	  (object (assq mode fold-mode-marks-alist))
+	  (old-top (and object
+		   (nth 1 object)))
+	  top
+	  (old-bottom (and object
+		      (nth 2 object)))
+	  bottom
+	  (secondary (and object
+			 (nth 3 object)))
+	  (prompt "Top fold marker: "))
+     (and (equal secondary "")
+	  (setq secondary nil))
+     (while (not top)
+       (setq top (read-string prompt (or old-top "{{{ ")))
+       (and (equal top "")
+	    (setq top nil)))
+     (setq prompt (concat prompt
+			  top
+			  ", Bottom marker: "))
+     (while (not bottom)
+       (setq bottom (read-string prompt (or old-bottom "}}}")))
+       (and (equal bottom "")
+	    (setq bottom nil)))
+     (setq prompt (concat prompt
+			  bottom
+			  (if secondary
+			      ", Secondary marker: "
+			    ", Secondary marker (none): "))
+	   secondary (read-string prompt secondary))
+     (and (equal secondary "")
+	  (setq secondary nil))
+     (list mode top bottom secondary nil t)))
+  (let ((object (assq mode fold-mode-marks-alist)))
+    (if (and object
+	     noforce
+	     message)
+	(message "Fold markers for `%s' are already set."
+		 (symbol-name mode))
+      (if object
+	  (or noforce
+	      (setcdr object (if secondary
+				 (list top bottom secondary)
+			       (list top bottom))))
+	(setq fold-mode-marks-alist
+	      (cons (if secondary
+			(list mode top bottom secondary)
+		      (list mode top bottom))
+		    fold-mode-marks-alist)))
+      (and message
+	     (message "Set fold marks for `%s' to \"%s\" and \"%s\"."
+		      (symbol-name mode)
+		      (if secondary
+			  (concat top "name" secondary)
+			(concat top "name"))
+		      bottom)
+	     (and (eq major-mode mode)
+		  (fold-set-marks top bottom secondary))))))
+
+;;}}}
+;;{{{ Set some useful default fold marks
+
+(fold-add-to-marks-list 'c-mode "/* {{{ " "/* }}} */" " */" t)
+(fold-add-to-marks-list 'emacs-lisp-mode ";;{{{ " ";;}}}" nil t)
+(fold-add-to-marks-list 'lisp-interaction-mode ";;{{{ " ";;}}}" nil t)
+(fold-add-to-marks-list 'plain-tex-mode "%{{{ " "%}}}" nil t)
+(fold-add-to-marks-list 'plain-TeX-mode "%{{{ " "%}}}" nil t)
+(fold-add-to-marks-list 'latex-mode "%{{{ " "%}}}" nil t)
+(fold-add-to-marks-list 'LaTeX-mode "%{{{ " "%}}}" nil t)
+(fold-add-to-marks-list 'orwell-mode "{{{ " "}}}" nil t)
+(fold-add-to-marks-list 'modula-2-mode "(* {{{ " "(* }}} *)" " *)" t)
+(fold-add-to-marks-list 'shellscript-mode "# {{{ " "# }}}" nil t)
+(fold-add-to-marks-list 'perl-mode "# {{{ " "# }}}" nil t)
+(fold-add-to-marks-list 'texinfo-mode "@c {{{ " "@c {{{endfold}}}" " }}}" t)
+(fold-add-to-marks-list 'occam-mode "-- {{{ " "-- }}}" nil t)
+(fold-add-to-marks-list 'lisp-mode ";;{{{ " ";;}}}" nil t)
+(fold-add-to-marks-list 'tex-mode "%{{{ " "%}}}" nil t)
+(fold-add-to-marks-list 'TeX-mode "%{{{ " "%}}}" nil t)
+(fold-add-to-marks-list 'c++-mode "// {{{ " "// }}}" nil t)
+(fold-add-to-marks-list 'bison-mode "/* {{{ " "/* }}} */" " */" t)
+(fold-add-to-marks-list 'Bison-mode "/* {{{ " "/* }}} */" " */" t)
+(fold-add-to-marks-list 'gofer-mode "-- {{{ " "-- }}}" nil t)
+(fold-add-to-marks-list 'ml-mode "(* {{{ " "(* }}} *)" " *)" t)
+(fold-add-to-marks-list 'sml-mode "(* {{{ " "(* }}} *)" " *)" t)
+
+;;; my changes (Jari Aalto ssjaaa at uta.fi)
+;;; heavy shell-perl-awk programmer need # prefix...
+(fold-add-to-marks-list 'fundamental-mode "# {{{ " "# }}}" nil t)
+(fold-add-to-marks-list 'text-mode "{{{ " "}}}" nil t)
+
+
+;;}}}
+
+;;}}}
+;;{{{ Start Folding mode automatically for folded files
+
+;;{{{ folding-mode-find-file-hook
+
+(defun folding-mode-find-file-hook ()
+  "One of the hooks called whenever a `find-file' is successful.
+It checks to see if `folded-file' has been set as a buffer-local
+variable, and automatically starts Folding mode if it has.
+
+This allows folded files to be automatically folded when opened.
+
+To make this hook effective, the symbol `folding-mode-find-file-hook'
+should be placed at the end of `find-file-hooks'.  If you have
+some other hook in the list, for example a hook to automatically
+uncompress or decrypt a buffer, it should go earlier on in the list.
+
+See also `folding-mode-add-find-file-hook'."
+  (and (assq 'folded-file (buffer-local-variables))
+       folded-file
+       (folding-mode 1)
+       (kill-local-variable 'folded-file)))
+
+;;}}}
+;;{{{ folding-mode-add-find-file-hook
+
+(defun folding-mode-add-find-file-hook ()
+  "Appends `folding-mode-find-file-hook' to the list `find-file-hooks'.
+
+This has the effect that afterwards, when a folded file is visited, if
+appropriate Emacs local variable entries are recognised at the end of
+the file, Folding mode is started automatically.
+
+If `inhibit-local-variables' is non-nil, this will not happen regardless
+of the setting of `find-file-hooks'.
+
+To declare a file to be folded, put `folded-file: t' in the file's
+local variables.  eg., at the end of a C source file, put:
+
+/*
+Local variables:
+folded-file: t
+*/
+
+The local variables can be inside a fold."
+  (interactive)
+  (or (memq 'folding-mode-find-file-hook find-file-hooks)
+      (setq find-file-hooks (append find-file-hooks
+				    '(folding-mode-find-file-hook)))))
+
+;;}}}
+
+;;}}}
+;;{{{ Gross, crufty hacks that seem necessary
+
+;; The functions here have been tested with Emacs 18.55, Emacs 18.58,
+;; Epoch 4.0p2 (based on Emacs 18.58) and Lucid Emacs 19.6.
+
+;; Note that Lucid Emacs 19.6 can't do selective-display, and its
+;; "invisible extents" don't work either, so Folding mode just won't
+;; work with that version.
+
+;; They shouldn't do the wrong thing with later versions of Emacs, but
+;; they might not have the special effects either.  They may appear to
+;; be excessive; that is not the case.  All of the peculiar things these
+;; functions do is done to avoid some side-effect of Emacs' internal
+;; logic that I have met.  Some of them work around bugs or unfortunate
+;; (lack of) features in Emacs.  In most cases, it would be better to
+;; move this into the Emacs C code.
+
+;; Folding mode is designed to be simple to cooperate with as many
+;; things as possible.  These functions go against that principle at the
+;; coding level, but make life for the user bearable.
+
+;;{{{ fold-merge-keymaps
+
+;; Merge keymaps, because miner-mode keymaps aren't available in Emacs
+;; 18.  In Lucid Emacs, keymaps can have parent keymaps, so that
+;; mechanism is used instead and MAP isn't copied.
+
+;; Takes two keymaps, MAP and EXTRA.  Merges each binding in EXTRA into
+;; a copy of MAP, and returns the new keymap (bindings in EXTRA override
+;; those in MAP).  MAP or EXTRA may be nil, indicating an empty keymap.
+;; If they are both nil, nil is returned.  Sub-keymaps and even cons
+;; cells containing bindings are not copied unnecessarily (well,
+;; sometimes they are).  This means that if you modify the local map
+;; when Folding mode is active, the effects are unpredictable: you may
+;; also affect the keymap that was active before Folding mdoe was
+;; started, and you may affect folding-mode-map.
+
+(defun fold-merge-keymaps (map extra)
+  (or map (setq map extra extra nil))
+  (if (null extra)
+      (and map (copy-keymap map))
+    (if fold-lucid-keymaps-p
+	(let ((new (copy-keymap extra)))
+	  (set-keymap-parent new map)
+	  new)
+      (or (keymapp extra)
+	  (signal 'wrong-type-argument (list 'keymapp extra)))
+      (or (keymapp map)
+	  (signal 'wrong-type-argument (list 'keymapp map)))
+      (and (vectorp extra)
+	   (let ((key (length extra))
+		 (oldextra extra))
+	     (setq extra nil)
+	     (while (<= 0 (setq key (1- key)))
+	       (and (aref oldextra key)
+		    (setq extra (cons (cons key (aref oldextra key)) extra))))
+	     (setq extra (cons 'keymap extra))))
+      (and (cdr extra)
+	   (let (key keycode cons-binding realdef def submap)
+
+	     ;; Note that this copy-sequence will copy the spine of the
+	     ;; sparse keymap, but it will not copy the cons cell used
+	     ;; for each binding.  This is important; define-key does a
+	     ;; setcdr to rebind a key, if that key was bound already,
+	     ;; so define-key can't be used to change a binding.  Using
+	     ;; copy-keymap instead would be excessive and slow, because
+	     ;; it would be repeatedly invoked, as this function is
+	     ;; called recursively.
+
+	     (setq map (copy-sequence map))
+	     (while (setq extra (cdr extra))
+	       (setq keycode (car (car extra))
+		     key (char-to-string keycode)
+		     def (cdr (car extra))
+		     realdef def)
+	       (while (and def (if (symbolp def)
+				   (setq def (symbol-function def))
+				 (and (consp def)
+				      (integerp (cdr def))
+				      (keymapp (car def))
+				      (setq def (lookup-key (car def)
+							    (char-to-string
+							     (cdr def))))))))
+	       (if (and (keymapp def)
+			(setq submap (lookup-key map key)))
+		   (progn
+		     (while (and submap
+				 (if (symbolp submap)
+				     (setq submap (symbol-function submap))
+				   (and (consp submap)
+					(integerp (cdr submap))
+					(keymapp (car submap))
+					(setq submap (lookup-key
+						      (car submap)
+						      (char-to-string
+						       (cdr submap))))))))
+		     (if (keymapp submap)
+			 (if (vectorp map)
+			     (aset map keycode
+				   (fold-merge-keymaps submap def))
+			   (setcdr (setq map (delq (assq keycode map) map))
+				   (cons (cons keycode
+					       (fold-merge-keymaps submap def))
+					 (cdr map))))
+		       (if (vectorp map)
+			   (aset map keycode realdef)
+			 (setcdr (setq map (delq (assq keycode map) map))
+				 (cons (cons keycode realdef) (cdr map))))))
+		 (and def
+		      (if (vectorp map)
+			  (aset map keycode realdef)
+			(and (setq cons-binding (assq keycode map))
+			     (setq map (delq cons-binding map)))
+			(setcdr map (cons (cons keycode realdef)
+					  (cdr map)))))))))
+      map)))
+
+;;}}}
+;;{{{ fold-subst-regions
+
+;; Substitute newlines for carriage returns or vice versa.
+;; Avoid excessive file locking.
+
+;; Substitutes characters in the buffer, even in a read-only buffer.
+;; Takes LIST, a list of regions specified as sequence in the form
+;; (START1 END1 START2 END2 ...).  In every region specified by each
+;; pair, substitutes each occurence of character FIND by REPLACE.
+
+;; The buffer-modified flag is not affected, undo information is not
+;; kept for the change, and the function works on read-only files.  This
+;; function is much more efficient called with a long sequence than
+;; called for each region in the sequence.
+
+;; If the buffer is not modified when the function is called, the
+;; modified-flag is set before performing all the substitutions, and
+;; locking is temporarily disabled.  This prevents Emacs from trying to
+;; make then delete a lock file for *every* substitution, which slows
+;; folding considerably, especially on a slow networked filesystem.
+;; Without this, on my system, folding files on startup (and reading
+;; other peoples' folded files) takes about five times longer.  Emacs
+;; still locks the file once for this call under those circumstances; I
+;; can't think of a way around that, but it isn't really a problem.
+
+;; I consider these problems to be a bug in `subst-char-in-region'.
+
+(defun fold-subst-regions (list find replace)
+  (let ((buffer-read-only buffer-read-only) ;; Protect read-only flag.
+	(modified (buffer-modified-p))
+	(ask1 (symbol-function 'ask-user-about-supersession-threat))
+	(ask2 (symbol-function 'ask-user-about-lock)))
+    (unwind-protect
+	(progn
+	  (setq buffer-read-only nil)
+	  (or modified
+	      (progn
+		(fset 'ask-user-about-supersession-threat
+		      '(lambda (&rest x) nil))
+		(fset 'ask-user-about-lock
+		      '(lambda (&rest x) nil))
+		(set-buffer-modified-p t))) ; Prevent file locking in the loop
+	  (while list
+	    (subst-char-in-region (car list) (nth 1 list) find replace t)
+	    (setq list (cdr (cdr list)))))
+      ;; buffer-read-only is restored by the let.
+      ;; Don't want to change MODIFF time if it was modified before.
+      (or modified
+	  (unwind-protect
+	      (set-buffer-modified-p nil)
+	    (fset 'ask-user-about-supersession-threat ask1)
+	    (fset 'ask-user-about-lock ask2))))))
+
+;;}}}
+;;{{{ fold-narrow-to-region
+
+;; Narrow to region, without surprising displays.
+
+;; Similar to `narrow-to-region', but also adjusts window-start to be
+;; the start of the narrowed region.  If an optional argument CENTRE is
+;; non-nil, the window-start is positioned to leave the point at the
+;; centre of the window, like `recenter'.  START may be nil, in which
+;; case the function acts more like `widen'.
+
+;; Actually, all the window-starts for every window displaying the
+;; buffer, as well as the last_window_start for the buffer are set.  The
+;; points in every window are set to the point in the current buffer.
+;; All this logic is necessary to prevent the display getting really
+;; weird occasionally, even if there is only one window.  Try making
+;; this function like normal `narrow-to-region' with a touch of
+;; `recenter', then moving around lots of folds in a buffer displayed in
+;; several windows.  You'll see what I mean.
+
+;; last_window_start is set by making sure that the selected window is
+;; displaying the current buffer, then setting the window-start, then
+;; making the selected window display another buffer (which sets
+;; last_window_start), then setting the selected window to redisplay the
+;; buffer it displayed originally.
+
+;; Note that whenever window-start is set, the point cannot be moved
+;; outside the displayed area until after a proper redisplay.  If this
+;; is possible, centre the display on the point.
+
+;; In Emacs 19; Epoch or Lucid Emacs, searches all screens for all
+;; windows.  In Emacs 19, they are called "frames".
+
+(defun fold-narrow-to-region (&optional start end centre)
+  (let* ((the-window (selected-window))
+	 (the-screen (and fold-epoch-screens-p (epoch::current-screen)))
+	 (screens (and fold-epoch-screens-p (epoch::screens-of-buffer)))
+	 (selected-buffer (window-buffer the-window))
+	 (window-ring the-window)
+	 (window the-window)
+	 (point (point))
+	 (buffer (current-buffer))
+	 temp)
+    (unwind-protect
+	(progn
+	  (unwind-protect
+	      (progn
+		(if start
+		    (narrow-to-region start end)
+		  (widen))
+		(setq point (point))
+		(set-window-buffer window buffer)
+		(while (progn
+			 (and (eq buffer (window-buffer window))
+			      (if centre
+				  (progn
+				    (select-window window)
+				    (goto-char point)
+				    (vertical-motion
+				     (- (lsh (window-height window) -1)))
+				    (set-window-start window (point))
+				    (set-window-point window point))
+				(set-window-start window (or start 1))
+				(set-window-point window point)))
+			 (or (not (eq (setq window
+					    (if fold-emacs-frames-p
+						(next-window window nil t)
+					      (if fold-lucid-screens-p
+						  (next-window window nil t t)
+						(next-window window))))
+				      window-ring))
+			     (and (setq screens (cdr screens))
+				  (setq window (epoch::first-window (car screens))
+					window-ring window))))))
+	    (and the-screen (epoch::select-screen the-screen))
+	    (select-window the-window))
+	  ;; Set last_window_start.
+	  (unwind-protect
+	      (if (not (eq buffer selected-buffer))
+		  (set-window-buffer the-window selected-buffer)
+		(if (get-buffer "*scratch*")
+		    (set-window-buffer the-window (get-buffer "*scratch*"))
+		  (set-window-buffer
+		   the-window (setq temp (generate-new-buffer " *temp*"))))
+		(set-window-buffer the-window buffer))
+	    (and temp
+		 (kill-buffer temp))))
+      ;; Undo this side-effect of set-window-buffer.
+      (set-buffer buffer)
+      (goto-char (point)))))
+
+;;}}}
+
+;;}}}
+;;{{{ Miscellaneous
+
+;;{{{ kill-all-local-variables-hooks
+
+;; This does not normally have any effect in Emacs.  In my setup,
+;; this hook is called when the major mode changes, and it gives
+;; Folding mode a chance to clear up first.
+
+(and (boundp 'kill-all-local-variables-hooks)
+     (or (memq 'fold-end-mode-quickly
+	       kill-all-local-variables-hooks)
+	 (setq kill-all-local-variables-hooks
+	       (cons 'fold-end-mode-quickly
+		     kill-all-local-variables-hooks))))
+
+;;}}}
+;;{{{ list-buffers-mode-alist
+
+;; Also has no effect in standard Emacs.  With this variable set,
+;; my setup shows "Folding" in the mode name part of the buffer list,
+;; which looks nice :-).
+
+(and (boundp 'list-buffers-mode-alist)
+     (or (assq 'folding-mode list-buffers-mode-alist)
+	 (setq list-buffers-mode-alist
+	       (cons '(folding-mode folding-mode-v-str)
+		     list-buffers-mode-alist))))
+
+;;}}}
+;;{{{ fold-end-mode-quickly
+
+(defun fold-end-mode-quickly ()
+  "Replaces all ^M's with linefeeds and widen a folded buffer.
+Only has any effect if Folding mode is active.
+
+This should not in general be used for anything.  It is used when changing
+major modes, by being placed in kill-mode-tidy-alist, to tidy the buffer
+slightly.  It is similar to `(folding-mode 0)', except that it does not
+restore saved keymaps etc.  Repeat: Do not use this function.  Its
+behaviour is liable to change."
+  (and (boundp 'folding-mode)
+       (assq 'folding-mode
+	     (buffer-local-variables))
+       folding-mode
+       (progn
+	 (widen)
+	 (fold-clear-stack)
+	 (fold-subst-regions (list 1 (point-max)) ?\r ?\n))))
+
+;;}}}
+;;{{{ eval-current-buffer-open-folds
+
+(defun eval-current-buffer-open-folds (&optional printflag)
+  "Evaluate all of a folded buffer as Lisp code.
+Unlike `eval-current-buffer', this function will evaluate all of a
+buffer, even if it is folded.  It will also work correctly on non-folded
+buffers, so is a good candidate for being bound to a key if you program
+in Emacs-Lisp.
+
+It works by making a copy of the current buffer in another buffer,
+unfolding it and evaluating it.  It then deletes the copy.
+
+Programs can pass argument PRINTFLAG which controls printing of output:
+nil means discard it; anything else is stream for print."
+  (interactive)
+  (if (or (and (boundp 'folding-mode-flag)
+	       folding-mode-flag)
+	  (and (boundp 'folding-mode)
+	       folding-mode))
+      (let ((temp-buffer
+	     (generate-new-buffer (buffer-name))))
+	(message "Evaluating unfolded buffer...")
+	(save-restriction
+	  (widen)
+	  (copy-to-buffer temp-buffer 1 (point-max)))
+	(set-buffer temp-buffer)
+	(subst-char-in-region 1 (point-max) ?\r ?\n)
+	(let ((real-message-def (symbol-function 'message))
+	      (suppress-eval-message))
+	  (fset 'message
+		(function
+		 (lambda (&rest args)
+		   (setq suppress-eval-message t)
+		   (fset 'message real-message-def)
+		   (apply 'message args))))
+	  (unwind-protect
+	      (eval-current-buffer printflag)
+	    (fset 'message real-message-def)
+	    (kill-buffer temp-buffer))
+	  (or suppress-eval-message
+	      (message "Evaluating unfolded buffer... Done"))))
+    (eval-current-buffer printflag)))
+
+;;}}}
+
+;;}}}
+
+;;{{{ Emacs local variables
+
+;; Local variables:
+;; folded-file: t
+;; end:
+
+;;}}}
diff --git a/factory/bin/gen-readcf b/factory/bin/gen-readcf
new file mode 100755
index 0000000..e7085f0
--- /dev/null
+++ b/factory/bin/gen-readcf
@@ -0,0 +1,14 @@
+#!/bin/sh
+BISON=$1
+if test -r readcf.cc
+then
+   touch readcf.cc
+else
+   if test "$BISON" = where-is-your-bison
+   then
+      echo Error: no bison given, could not rebuilt readcf.cc
+      exit 1
+   fi
+   $BISON readcf.y -o readcf.cc
+fi
+
diff --git a/factory/bin/makeheader b/factory/bin/makeheader
new file mode 100755
index 0000000..2fa1f86
--- /dev/null
+++ b/factory/bin/makeheader
@@ -0,0 +1,145 @@
+#! /bin/sh
+
+#
+# makeheader.sh - generate a header file out of several header files.
+#
+# Type 'makeheader -?' for instructions on syntax/usage.
+#
+
+# print usage if necessary
+if test "$#" = 0 || test "$1" = "-?" || test "$1" = "-help"; then
+    cat 1>&2 << \EOT
+usage: makeheader [-?] {-I<includedir>} <templatefile> <outfile>
+
+This is makeheader, a header file generation tool.
+With makeheader it is possible to generate a single header
+file out of several other header files.
+
+To include a header file into the generated header file
+(= <outfile>) use the two lines
+
+/*MAKEHEADER*/
+#include "<includefile>"
+
+in <templatefile>.
+
+If you use the alternate form
+
+/*MAKEHEADER PUBLIC ONLY*/
+#include "<includefile>"
+
+only sections marked with /*BEGINPUBLIC*/ and /*ENDPUBLIC*/ are
+pasted from <includefile> into <outfile>.
+
+<includefile> is looked up in all <includedir>s, then in the
+current directory, then in the base directory of <templatefile>.
+EOT
+    exit 1
+fi
+
+# get list of include directories
+includes=""
+while echo "$1" | grep '^-I' > /dev/null 2> /dev/null; do
+    # get argument to option -I
+    if test "$1" = "-I"; then
+        shift
+        includes="$includes$1:"
+    else
+        include=`echo "$1" | sed 's/^-I//'`
+        includes="$includes$include:"
+    fi
+    shift
+done
+includes="$includes.:"
+
+# check for rest of arguments
+if test "$#" -lt 2; then
+    echo "usage: makeheader [-?] {-I<includedir>} <templatefile> <outfile>" 1>&2
+    exit 1
+fi
+
+infile="$1"
+outfile="makeheader.$$"
+final_outfile="$2"
+
+# get basename of $infile
+if echo "$infile" | grep '.*/' > /dev/null 2> /dev/null; then
+    include=`echo "$infile" | sed 's/\/[^\/]*$//'`
+    includes="$includes$include:"
+fi
+
+if test ! -r "$infile"; then
+    echo "makeheader: Cannot open template file $infile for reading" 1>&2
+    exit 1
+fi
+
+# try to create $outfile if it does not exist
+if test -w "$outfile" || cp /dev/null "$outfile" > /dev/null 2> /dev/null; then
+    :
+else
+    echo "makeheader: Cannot open header file $outfile for writing" 1>&2
+    exit 1
+fi
+
+echo "/* $final_outfile automatically generated by makeheader from $infile */" > "$outfile"
+
+# scan through template
+while read line; do
+    if test "$line" = '/*MAKEHEADER*/'; then
+	readmode=1
+    elif test "$line" = '/*MAKEHEADER PUBLIC ONLY*/'; then
+	readmode=2
+    else
+	echo "$line"
+	continue
+    fi
+
+    # get include file from next line
+    read line
+#    if echo "$line" | grep -v '^#include <factory/.*>$' > /dev/null 2> /dev/null; then
+    if echo "$line" | grep -v '^#include ".*"$' > /dev/null 2> /dev/null; then
+    	echo "makeheader: Invalid include statement $line" 1>&2
+	exit 1
+    fi
+    includefile=`echo "$line" | sed 's/^#include "//; s/"$//'`
+#    includefile=`echo "$line" | sed 's/^#include <factory//; s/>$//'`
+
+    # search for includefile
+    found=0
+    saveIFS="$IFS"; IFS=:
+    for dir in $includes; do
+	if test -r "$dir/$includefile"; then
+	    found=1
+	    break
+	fi
+    done
+    IFS="$saveIFS"
+
+    if test $found = 0; then
+	echo "makeheader: Include file $includefile not found" 1>&2
+	exit 1
+    else
+	includefile="$dir/$includefile"
+    fi
+
+    # now paste includefile into outfile
+    echo "/* stuff included from $includefile */"
+    echo
+    if test $readmode = 1; then
+	# read whole includefile
+	cat "$includefile"
+    elif test $readmode = 2; then
+	# read only public sections of includefile
+	sed -n '
+	  \@^/\*BEGINPUBLIC\*/$@!d
+	  \@^/\*BEGINPUBLIC\*/$@{
+	    : loop
+	    n
+	    \@^/\*ENDPUBLIC\*/$@d
+	    p
+	    b loop
+	  }' "$includefile"
+    fi
+
+done < "$infile" >> "$outfile"
+mv "$outfile" "$final_outfile"
diff --git a/factory/canonicalform.cc b/factory/canonicalform.cc
new file mode 100644
index 0000000..6d82385
--- /dev/null
+++ b/factory/canonicalform.cc
@@ -0,0 +1,1917 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+
+#include "config.h"
+
+
+#include "cf_assert.h"
+#include "cf_factory.h"
+
+#include "cf_defs.h"
+#include "cf_globals.h"
+#include "canonicalform.h"
+#include "cf_iter.h"
+#include "int_cf.h"
+#include "cf_algorithm.h"
+#include "imm.h"
+#include "gfops.h"
+#include "facMul.h"
+#include "FLINTconvert.h"
+
+#include <factory/cf_gmp.h>
+
+#ifndef NOSTREAMIO
+CanonicalForm readCF( ISTREAM& );
+#endif /* NOSTREAMIO */
+
+/** constructors, destructors, selectors **/
+CanonicalForm::CanonicalForm( const char * str, const int base ) : value( CFFactory::basic( str, base ) )
+{
+}
+
+InternalCF*
+CanonicalForm::getval() const
+{
+    if ( is_imm( value ) )
+        return value;
+    else
+        return value->copyObject();
+}
+
+CanonicalForm
+CanonicalForm::deepCopy() const
+{
+    if ( is_imm( value ) )
+        return *this;
+    else
+        return CanonicalForm( value->deepCopyObject() );
+}
+
+void
+CanonicalForm::mpzval(mpz_t val) const
+{
+    ASSERT (!is_imm (value) && value->levelcoeff() == IntegerDomain, "non-immediate integer expected");
+    getmpi (value, val);
+}
+
+
+/** predicates **/
+#if 0
+bool
+CanonicalForm::isImm() const
+{
+    return is_imm( value );
+}
+#endif
+
+bool
+CanonicalForm::inZ() const
+{
+    if ( is_imm( value ) == INTMARK )
+        return true;
+    else if ( is_imm( value ) )
+        return false;
+    else
+        return value->levelcoeff() == IntegerDomain;
+}
+
+bool
+CanonicalForm::inQ() const
+{
+    if ( is_imm( value ) == INTMARK )
+        return true;
+    else if ( is_imm( value ) )
+        return false;
+    else
+        return value->levelcoeff() == IntegerDomain ||
+            value->levelcoeff() == RationalDomain;
+}
+
+bool
+CanonicalForm::inFF() const
+{
+    return is_imm( value ) == FFMARK;
+}
+
+bool
+CanonicalForm::inGF() const
+{
+    return is_imm( value ) == GFMARK;
+}
+
+bool
+CanonicalForm::inBaseDomain() const
+{
+    if ( is_imm( value ) )
+        return true;
+    else
+        return value->inBaseDomain();
+}
+
+bool
+CanonicalForm::inExtension() const
+{
+    if ( is_imm( value ) )
+        return false;
+    else
+        return value->inExtension();
+}
+
+bool
+CanonicalForm::inCoeffDomain() const
+{
+    if ( is_imm( value ) )
+        return true;
+    else
+        return value->inCoeffDomain();
+}
+
+bool
+CanonicalForm::inPolyDomain() const
+{
+    if ( is_imm( value ) )
+        return false;
+    else
+        return value->inPolyDomain();
+}
+
+bool
+CanonicalForm::inQuotDomain() const
+{
+    if ( is_imm( value ) )
+        return false;
+    else
+        return value->inQuotDomain();
+}
+
+bool
+CanonicalForm::isFFinGF() const
+{
+    return is_imm( value ) == GFMARK && gf_isff( imm2int( value ) );
+}
+
+bool
+CanonicalForm::isUnivariate() const
+{
+    if ( is_imm( value ) )
+        return false;
+    else
+        return value->isUnivariate();
+}
+
+// is_homogeneous returns 1 iff f is homogeneous, 0 otherwise//
+bool
+CanonicalForm::isHomogeneous() const
+{
+  if (this->isZero()) return true;
+  else if (this->inCoeffDomain()) return true;
+  else
+  {
+#if 0
+    CFIterator i;
+    int cdeg = -2, dummy;
+    for ( i = *this; i.hasTerms(); i++ )
+    {
+      if (!(i.coeff().isHomogeneous())) return false;
+      if ( (dummy = totaldegree( i.coeff() ) + i.exp()) != cdeg )
+      {
+         if (cdeg == -2) cdeg = dummy;
+         else return false;
+      }
+    }
+    return true;
+#else
+    CFList termlist= get_Terms(*this);
+    CFListIterator i;
+    int deg= totaldegree(termlist.getFirst());
+
+    for ( i=termlist; i.hasItem(); i++ )
+      if ( totaldegree(i.getItem()) != deg ) return false;
+    return true;
+#endif
+  }
+}
+
+
+
+/** conversion functions **/
+long
+CanonicalForm::intval() const
+{
+    if ( is_imm( value ) )
+        return imm_intval( value );
+    else
+        return value->intval();
+}
+
+CanonicalForm
+CanonicalForm::mapinto () const
+{
+    //ASSERT( is_imm( value ) ||  ! value->inExtension(), "cannot map into different Extension" );
+    if ( is_imm( value ) )
+        if ( getCharacteristic() == 0 )
+            if ( is_imm( value ) == FFMARK )
+                return CanonicalForm( int2imm( ff_symmetric( imm2int( value ) ) ) );
+            else  if ( is_imm( value ) == GFMARK )
+                return CanonicalForm( int2imm( ff_symmetric( gf_gf2ff( imm2int( value ) ) ) ) );
+            else
+                return *this;
+        else  if ( getGFDegree() == 1 )
+            return CanonicalForm( int2imm_p( ff_norm( imm2int( value ) ) ) );
+        else
+            return CanonicalForm( int2imm_gf( gf_int2gf( imm2int( value ) ) ) );
+    else  if ( value->inBaseDomain() )
+        if ( getCharacteristic() == 0 )
+             return *this;
+        else
+        {
+            int val;
+            if ( value->levelcoeff() == IntegerDomain )
+                val = value->intmod( ff_prime );
+            else  if ( value->levelcoeff() == RationalDomain )
+                return num().mapinto() / den().mapinto();
+            else {
+                ASSERT( 0, "illegal domain" );
+                return 0;
+            }
+            if ( getGFDegree() > 1 )
+                return CanonicalForm( int2imm_gf( gf_int2gf( val ) ) );
+            else
+                return CanonicalForm( int2imm_p( val ) );
+        }
+    else
+    {
+        Variable x = value->variable();
+        CanonicalForm result;
+        for ( CFIterator i = *this; i.hasTerms(); i++ )
+            result += (power( x, i.exp() ) * i.coeff().mapinto());
+        return result;
+    }
+}
+
+/** CanonicalForm CanonicalForm::lc (), Lc (), LC (), LC ( v ) const
+ *
+ * lc(), Lc(), LC() - leading coefficient functions.
+ *
+ * All methods return CO if CO is in a base domain.
+ *
+ * lc() returns the leading coefficient of CO with respect to
+ * lexicographic ordering.  Elements in an algebraic extension
+ * are considered polynomials so lc() always returns a leading
+ * coefficient in a base domain.  This method is useful to get
+ * the base domain over which CO is defined.
+ *
+ * Lc() returns the leading coefficient of CO with respect to
+ * lexicographic ordering.  In contrast to lc() elements in an
+ * algebraic extension are considered coefficients so Lc() always
+ * returns a leading coefficient in a coefficient domain.
+ *
+ * LC() returns the leading coefficient of CO where CO is
+ * considered a univariate polynomial in its main variable.  An
+ * element of an algebraic extension is considered an univariate
+ * polynomial, too.
+ *
+ * LC( v ) returns the leading coefficient of CO where CO is
+ * considered an univariate polynomial in the polynomial variable
+ * v.
+ * Note: If v is less than the main variable of CO we have to
+ * swap variables which may be quite expensive.
+ *
+ * Examples:
+ * > Let x < y be polynomial variables, a an algebraic variable.
+ *
+ * > (3*a*x*y^2+y+x).lc() = 3
+ *
+ * > (3*a*x*y^2+y+x).Lc() = 3*a
+ *
+ * > (3*a*x*y^2+y+x).LC() = 3*a*x
+ *
+ * > (3*a*x*y^2+y+x).LC( x ) = 3*a*y^2+1
+ *
+ *
+ * > (3*a^2+4*a).lc() = 3
+ *
+ * > (3*a^2+4*a).Lc() = 3*a^2+4*a
+ *
+ * > (3*a^2+4*a).LC() = 3
+ *
+ * > (3*a^2+4*a).LC( x ) = 3*a^2+4*a
+ *
+ * @sa InternalCF::lc(), InternalCF::Lc(), InternalCF::LC(),
+ * InternalPoly::lc(), InternalPoly::Lc(), InternalPoly::LC(),
+ * ::lc(), ::Lc(), ::LC(), ::LC( v )
+ *
+**/
+CanonicalForm
+CanonicalForm::lc () const
+{
+    if ( is_imm( value ) )
+        return *this;
+    else
+        return value->lc();
+}
+
+/**
+ * @sa CanonicalForm::lc(), CanonicalForm::LC(), InternalCF::lc(),
+ * InternalCF::Lc(), InternalCF::LC(),
+ * InternalPoly::lc(), InternalPoly::Lc(), InternalPoly::LC(),
+ * ::lc(), ::Lc(), ::LC(), ::LC( v )
+**/
+CanonicalForm
+CanonicalForm::Lc () const
+{
+    if ( is_imm( value ) || value->inCoeffDomain() )
+        return *this;
+    else
+        return value->Lc();
+}
+
+/**
+ * @sa CanonicalForm::lc(), CanonicalForm::Lc(), InternalCF::lc(),
+ * InternalCF::Lc(), InternalCF::LC(),
+ * InternalPoly::lc(), InternalPoly::Lc(), InternalPoly::LC(),
+ * ::lc(), ::Lc(), ::LC(), ::LC( v )
+**/
+CanonicalForm
+CanonicalForm::LC () const
+{
+    if ( is_imm( value ) )
+        return *this;
+    else
+        return value->LC();
+}
+
+/**
+ * @sa CanonicalForm::lc(), CanonicalForm::Lc(), InternalCF::lc(),
+ * InternalCF::Lc(), InternalCF::LC(),
+ * InternalPoly::lc(), InternalPoly::Lc(), InternalPoly::LC(),
+ * ::lc(), ::Lc(), ::LC(), ::LC( v )
+**/
+CanonicalForm
+CanonicalForm::LC ( const Variable & v ) const
+{
+    if ( is_imm( value ) || value->inCoeffDomain() )
+        return *this;
+
+    Variable x = value->variable();
+    if ( v > x )
+        return *this;
+    else if ( v == x )
+        return value->LC();
+    else {
+        CanonicalForm f = swapvar( *this, v, x );
+         if ( f.mvar() == x )
+             return swapvar( f.value->LC(), v, x );
+         else
+            // v did not occur in f
+            return *this;
+    }
+}
+
+/**
+ * Returns -1 for the zero polynomial and 0 if
+ * CO is in a base domain.
+ *
+ * degree() returns the degree of CO in its main variable.
+ * Elements in an algebraic extension are considered polynomials.
+ *
+ * @sa InternalCF::degree(), InternalPoly::degree(),
+ * ::degree(), ::degree( v )
+ *
+**/
+int
+CanonicalForm::degree() const
+{
+    int what = is_imm( value );
+    if ( what )
+        if ( what == FFMARK )
+            return imm_iszero_p( value ) ? -1 : 0;
+        else if ( what == INTMARK )
+            return imm_iszero( value ) ? -1 : 0;
+        else
+            return imm_iszero_gf( value ) ? -1 : 0;
+    else
+        return value->degree();
+}
+
+/**
+ * returns -1 for the zero polynomial and 0 if
+ * CO is in a base domain.
+ *
+ * degree( v ) returns the degree of CO with respect to v.
+ * Elements in an algebraic extension are considered polynomials,
+ * and v may be algebraic.
+ *
+ * @sa InternalCF::degree(), InternalPoly::degree(),
+ * ::degree(), ::degree( v )
+**/
+int
+CanonicalForm::degree( const Variable & v ) const
+{
+    int what = is_imm( value );
+#if 0
+    if ( what )
+        if ( what == FFMARK )
+            return imm_iszero_p( value ) ? -1 : 0;
+        else if ( what == INTMARK )
+            return imm_iszero( value ) ? -1 : 0;
+        else
+            return imm_iszero_gf( value ) ? -1 : 0;
+    else if ( value->inBaseDomain() )
+        return value->degree();
+#else
+    switch(what)
+    {
+      case FFMARK: return imm_iszero_p( value ) ? -1 : 0;
+      case INTMARK: return imm_iszero( value ) ? -1 : 0;
+      case GFMARK:  return imm_iszero_gf( value ) ? -1 : 0;
+      case 0: if ( value->inBaseDomain() )
+              return value->degree();
+	      break;
+    }
+#endif
+
+    Variable x = value->variable();
+    if ( v == x )
+        return value->degree();
+    else  if ( v > x )
+        // relatively to v, f is in a coefficient ring
+        return 0;
+    else {
+        int coeffdeg, result = 0;
+        // search for maximum of coefficient degree
+        for ( CFIterator i = *this; i.hasTerms(); i++ ) {
+            coeffdeg = i.coeff().degree( v );
+            if ( coeffdeg > result )
+                result = coeffdeg;
+        }
+        return result;
+    }
+}
+
+/**
+ *
+ * tailcoeff() - return least coefficient
+ *
+ * tailcoeff() returns the coefficient of the term with the least
+ * degree in CO where CO is considered an univariate polynomial
+ * in its main variable.  Elements in an algebraic extension are
+ * considered coefficients.
+ *
+ * @sa CanonicalForm::taildegree(), InternalCF::tailcoeff(), InternalCF::tailcoeff(),
+ * InternalPoly::tailcoeff(), InternalPoly::taildegree,
+ * ::tailcoeff(), ::taildegree()
+ *
+**/
+CanonicalForm
+CanonicalForm::tailcoeff () const
+{
+    if ( is_imm( value ) || value->inCoeffDomain() )
+        return *this;
+    else
+        return value->tailcoeff();
+}
+
+/**
+ * tailcoeff( v ) returns the tail coefficient of CO where CO is
+ * considered an univariate polynomial in the polynomial variable
+ * v.
+ * Note: If v is less than the main variable of CO we have to
+ * swap variables which may be quite expensive.
+ *
+ * @sa CanonicalForm::taildegree(), InternalCF::tailcoeff(), InternalCF::tailcoeff(),
+ * InternalPoly::tailcoeff(), InternalPoly::taildegree,
+ * ::tailcoeff(), ::taildegree()
+**/
+CanonicalForm
+CanonicalForm::tailcoeff (const Variable& v) const
+{
+    if ( is_imm( value ) || value->inCoeffDomain() )
+        return *this;
+
+    Variable x = value->variable();
+    if ( v > x )
+        return *this;
+    else if ( v == x )
+        return value->tailcoeff();
+    else {
+        CanonicalForm f = swapvar( *this, v, x );
+         if ( f.mvar() == x )
+             return swapvar( f.value->tailcoeff(), v, x );
+         else
+            // v did not occur in f
+            return *this;
+    }
+}
+
+
+/**
+ * taildegree() returns -1 for the zero polynomial, 0 if CO is in
+ * a base domain, otherwise the least degree of CO where CO is
+ * considered a univariate polynomial in its main variable.  In
+ * contrast to tailcoeff(), elements in an algebraic extension
+ * are considered polynomials, not coefficients, and such may
+ * have a taildegree larger than zero.
+ *
+ * @sa CanonicalForm::tailcoeff(), InternalCF::tailcoeff(), InternalCF::tailcoeff(),
+ * InternalPoly::tailcoeff(), InternalPoly::taildegree,
+ * ::tailcoeff(), ::taildegree()
+**/
+int
+CanonicalForm::taildegree () const
+{
+    int what = is_imm( value );
+    if ( what )
+        if ( what == FFMARK )
+            return imm_iszero_p( value ) ? -1 : 0;
+        else if ( what == INTMARK )
+            return imm_iszero( value ) ? -1 : 0;
+        else
+            return imm_iszero_gf( value ) ? -1 : 0;
+    else
+        return value->taildegree();
+}
+
+/**
+ * level() returns the level of CO.  For a list of the levels and
+ * their meanings, see cf_defs.h.
+ *
+ * @sa InternalCF::level(), InternalCF::variable(),
+ * InternalPoly::level(), InternalPoly::variable(), ::level(),
+ * ::mvar()
+ *
+**/
+int
+CanonicalForm::level () const
+{
+    if ( is_imm( value ) )
+        return LEVELBASE;
+    else
+        return value->level();
+}
+
+/**
+ * mvar() returns the main variable of CO or Variable() if CO is
+ * in a base domain.
+ *
+ * @sa InternalCF::level(), InternalCF::variable(),
+ * InternalPoly::level(), InternalPoly::variable(), ::level(),
+ * ::mvar()
+**/
+Variable
+CanonicalForm::mvar () const
+{
+    if ( is_imm( value ) )
+        return Variable();
+    else
+        return value->variable();
+}
+
+/**
+ * num() returns the numerator of CO if CO is a rational number,
+ * CO itself otherwise.
+ *
+ * @sa InternalCF::num(), InternalCF::den(),
+ * InternalRational::num(), InternalRational::den(), ::num(),
+ * ::den()
+ *
+**/
+CanonicalForm
+CanonicalForm::num () const
+{
+    if ( is_imm( value ) )
+        return *this;
+    else
+        return CanonicalForm( value->num() );
+}
+
+/**
+ * den() returns the denominator of CO if CO is a rational
+ * number, 1 (from the current domain!) otherwise.
+ *
+ * @sa InternalCF::num(), InternalCF::den(),
+ * InternalRational::num(), InternalRational::den(), ::num(),
+ * ::den()
+**/
+CanonicalForm
+CanonicalForm::den () const
+{
+    if ( is_imm( value ) )
+        return CanonicalForm( 1 );
+    else
+        return CanonicalForm( value->den() );
+}
+
+/** assignment operators **/
+CanonicalForm &
+CanonicalForm::operator += ( const CanonicalForm & cf )
+{
+    int what = is_imm( value );
+    if ( what ) {
+        ASSERT ( ! is_imm( cf.value ) || (what==is_imm( cf.value )), "illegal base coefficients" );
+        if ( (what = is_imm( cf.value )) == FFMARK )
+            value = imm_add_p( value, cf.value );
+        else  if ( what == GFMARK )
+            value = imm_add_gf( value, cf.value );
+        else  if ( what )
+            value = imm_add( value, cf.value );
+        else {
+            InternalCF * dummy = cf.value->copyObject();
+            value = dummy->addcoeff( value );
+        }
+    }
+    else  if ( is_imm( cf.value ) )
+        value = value->addcoeff( cf.value );
+    else  if ( value->level() == cf.value->level() ) {
+        if ( value->levelcoeff() == cf.value->levelcoeff() )
+            value = value->addsame( cf.value );
+        else  if ( value->levelcoeff() > cf.value->levelcoeff() )
+            value = value->addcoeff( cf.value );
+        else {
+            InternalCF * dummy = cf.value->copyObject();
+            dummy = dummy->addcoeff( value );
+            if ( value->deleteObject() ) delete value;
+            value = dummy;
+        }
+    }
+    else  if ( level() > cf.level() )
+        value = value->addcoeff( cf.value );
+    else {
+        InternalCF * dummy = cf.value->copyObject();
+        dummy = dummy->addcoeff( value );
+        if ( value->deleteObject() ) delete value;
+        value = dummy;
+    }
+    return *this;
+}
+
+CanonicalForm &
+CanonicalForm::operator -= ( const CanonicalForm & cf )
+{
+    int what = is_imm( value );
+    if ( what ) {
+        ASSERT ( ! is_imm( cf.value ) || (what==is_imm( cf.value )), "illegal base coefficients" );
+        if ( (what = is_imm( cf.value )) == FFMARK )
+            value = imm_sub_p( value, cf.value );
+        else  if ( what == GFMARK )
+            value = imm_sub_gf( value, cf.value );
+        else  if ( what )
+            value = imm_sub( value, cf.value );
+        else {
+            InternalCF * dummy = cf.value->copyObject();
+            value = dummy->subcoeff( value, true );
+        }
+    }
+    else  if ( is_imm( cf.value ) )
+        value = value->subcoeff( cf.value, false );
+    else  if ( value->level() == cf.value->level() ) {
+        if ( value->levelcoeff() == cf.value->levelcoeff() )
+            value = value->subsame( cf.value );
+        else  if ( value->levelcoeff() > cf.value->levelcoeff() )
+            value = value->subcoeff( cf.value, false );
+        else {
+            InternalCF * dummy = cf.value->copyObject();
+            dummy = dummy->subcoeff( value, true );
+            if ( value->deleteObject() ) delete value;
+            value = dummy;
+        }
+    }
+    else  if ( level() > cf.level() )
+        value = value->subcoeff( cf.value, false );
+    else {
+        InternalCF * dummy = cf.value->copyObject();
+        dummy = dummy->subcoeff( value, true );
+        if ( value->deleteObject() ) delete value;
+        value = dummy;
+    }
+    return *this;
+}
+
+CanonicalForm &
+CanonicalForm::operator *= ( const CanonicalForm & cf )
+{
+    int what = is_imm( value );
+    if ( what ) {
+        ASSERT ( ! is_imm( cf.value ) || (what==is_imm( cf.value )), "illegal base coefficients" );
+        if ( (what = is_imm( cf.value )) == FFMARK )
+            value = imm_mul_p( value, cf.value );
+        else  if ( what == GFMARK )
+            value = imm_mul_gf( value, cf.value );
+        else  if ( what )
+            value = imm_mul( value, cf.value );
+        else {
+            InternalCF * dummy = cf.value->copyObject();
+            value = dummy->mulcoeff( value );
+        }
+    }
+    else  if ( is_imm( cf.value ) )
+        value = value->mulcoeff( cf.value );
+    else  if ( value->level() == cf.value->level() ) {
+#if (HAVE_NTL && HAVE_FLINT && __FLINT_RELEASE >= 20400)
+        if (value->levelcoeff() == cf.value->levelcoeff() && cf.isUnivariate() && (*this).isUnivariate())
+        {
+          if (value->level() < 0 || CFFactory::gettype() == GaloisFieldDomain || (size (cf) <= 10 || size (*this) <= 10) )
+            value = value->mulsame( cf.value );
+          else
+            *this= mulNTL (*this, cf);
+        }
+        else if (value->levelcoeff() == cf.value->levelcoeff() && (!cf.isUnivariate() || !(*this).isUnivariate()))
+            value = value->mulsame( cf.value );
+#else
+        if ( value->levelcoeff() == cf.value->levelcoeff() )
+            value = value->mulsame( cf.value );
+#endif
+        else  if ( value->levelcoeff() > cf.value->levelcoeff() )
+            value = value->mulcoeff( cf.value );
+        else {
+            InternalCF * dummy = cf.value->copyObject();
+            dummy = dummy->mulcoeff( value );
+            if ( value->deleteObject() ) delete value;
+            value = dummy;
+        }
+    }
+    else  if ( level() > cf.level() )
+        value = value->mulcoeff( cf.value );
+    else {
+        InternalCF * dummy = cf.value->copyObject();
+        dummy = dummy->mulcoeff( value );
+        if ( value->deleteObject() ) delete value;
+        value = dummy;
+    }
+    return *this;
+}
+
+CanonicalForm &
+CanonicalForm::operator /= ( const CanonicalForm & cf )
+{
+    int what = is_imm( value );
+    if ( what ) {
+        ASSERT ( ! is_imm( cf.value ) || (what==is_imm( cf.value )), "illegal base coefficients" );
+        if ( (what = is_imm( cf.value )) == FFMARK )
+            value = imm_div_p( value, cf.value );
+        else  if ( what == GFMARK )
+            value = imm_div_gf( value, cf.value );
+        else  if ( what )
+            value = imm_divrat( value, cf.value );
+        else {
+            InternalCF * dummy = cf.value->copyObject();
+            value = dummy->dividecoeff( value, true );
+        }
+    }
+    else  if ( is_imm( cf.value ) )
+        value = value->dividecoeff( cf.value, false );
+    else  if ( value->level() == cf.value->level() ) {
+#if (HAVE_NTL && HAVE_FLINT && __FLINT_RELEASE >= 20400)
+        if ( value->levelcoeff() == cf.value->levelcoeff() && (*this).isUnivariate() && cf.isUnivariate())
+        {
+            if (value->level() < 0 || CFFactory::gettype() == GaloisFieldDomain)
+              value = value->dividesame( cf.value );
+            else
+              *this= divNTL (*this, cf);
+        }
+        else if (value->levelcoeff() == cf.value->levelcoeff() && (!cf.isUnivariate() || !(*this).isUnivariate()))
+            value = value->dividesame( cf.value );
+#else
+        if (value->levelcoeff() == cf.value->levelcoeff() )
+            value = value->dividesame( cf.value );
+#endif
+        else  if ( value->levelcoeff() > cf.value->levelcoeff() )
+            value = value->dividecoeff( cf.value, false );
+        else {
+            InternalCF * dummy = cf.value->copyObject();
+            dummy = dummy->dividecoeff( value, true );
+            if ( value->deleteObject() ) delete value;
+            value = dummy;
+        }
+    }
+    else  if ( level() > cf.level() )
+        value = value->dividecoeff( cf.value, false );
+    else {
+        InternalCF * dummy = cf.value->copyObject();
+        dummy = dummy->dividecoeff( value, true );
+        if ( value->deleteObject() ) delete value;
+        value = dummy;
+    }
+    return *this;
+}
+
+CanonicalForm &
+CanonicalForm::div ( const CanonicalForm & cf )
+{
+    int what = is_imm( value );
+    if ( what ) {
+        ASSERT ( ! is_imm( cf.value ) || (what==is_imm( cf.value )), "illegal base coefficients" );
+        if ( (what = is_imm( cf.value )) == FFMARK )
+            value = imm_div_p( value, cf.value );
+        else  if ( what == GFMARK )
+            value = imm_div_gf( value, cf.value );
+        else  if ( what )
+            value = imm_div( value, cf.value );
+        else {
+            InternalCF * dummy = cf.value->copyObject();
+            value = dummy->divcoeff( value, true );
+        }
+    }
+    else  if ( is_imm( cf.value ) )
+        value = value->divcoeff( cf.value, false );
+    else  if ( value->level() == cf.value->level() ) {
+        if ( value->levelcoeff() == cf.value->levelcoeff() )
+            value = value->divsame( cf.value );
+        else  if ( value->levelcoeff() > cf.value->levelcoeff() )
+            value = value->divcoeff( cf.value, false );
+        else {
+            InternalCF * dummy = cf.value->copyObject();
+            dummy = dummy->divcoeff( value, true );
+            if ( value->deleteObject() ) delete value;
+            value = dummy;
+        }
+    }
+    else  if ( level() > cf.level() )
+        value = value->divcoeff( cf.value, false );
+    else {
+        InternalCF * dummy = cf.value->copyObject();
+        dummy = dummy->divcoeff( value, true );
+        if ( value->deleteObject() ) delete value;
+        value = dummy;
+    }
+    return *this;
+}
+
+///same as divremt but handles zero divisors in case we are in Z_p[x]/(f) where f is not irreducible
+CanonicalForm &
+CanonicalForm::tryDiv ( const CanonicalForm & cf, const CanonicalForm& M, bool& fail )
+{
+    ASSERT (getCharacteristic() > 0, "expected positive characteristic");
+    ASSERT (!getReduce (M.mvar()), "do not reduce modulo M");
+    fail= false;
+    int what = is_imm( value );
+    if ( what ) {
+        ASSERT ( ! is_imm( cf.value ) || (what==is_imm( cf.value )), "illegal base coefficients" );
+        if ( (what = is_imm( cf.value )) == FFMARK )
+            value = imm_div_p( value, cf.value );
+        else  if ( what == GFMARK )
+            value = imm_div_gf( value, cf.value );
+        else {
+            InternalCF * dummy = cf.value->copyObject();
+            value = dummy->divcoeff( value, true );
+        }
+    }
+    else  if ( is_imm( cf.value ) )
+        value = value->tryDivcoeff (cf.value, false, M, fail);
+    else  if ( value->level() == cf.value->level() ) {
+        if ( value->levelcoeff() == cf.value->levelcoeff() )
+            value = value->tryDivsame( cf.value, M, fail );
+        else  if ( value->levelcoeff() > cf.value->levelcoeff() )
+            value = value->tryDivcoeff( cf.value, false, M, fail );
+        else {
+            InternalCF * dummy = cf.value->copyObject();
+            dummy = dummy->tryDivcoeff( value, true, M, fail );
+            if ( value->deleteObject() ) delete value;
+            value = dummy;
+        }
+    }
+    else  if ( level() > cf.level() )
+        value = value->tryDivcoeff( cf.value, false, M, fail );
+    else {
+        InternalCF * dummy = cf.value->copyObject();
+        dummy = dummy->tryDivcoeff( value, true, M, fail );
+        if ( value->deleteObject() ) delete value;
+        value = dummy;
+    }
+    return *this;
+}
+
+CanonicalForm &
+CanonicalForm::operator %= ( const CanonicalForm & cf )
+{
+    int what = is_imm( value );
+    if ( what ) {
+        ASSERT ( ! is_imm( cf.value ) || (what==is_imm( cf.value )), "illegal base coefficients" );
+        if ( (what = is_imm( cf.value )) == FFMARK )
+            value = imm_mod_p( value, cf.value );
+        else  if ( what == GFMARK )
+            value = imm_mod_gf( value, cf.value );
+        else  if ( what )
+            value = imm_mod( value, cf.value );
+        else {
+            InternalCF * dummy = cf.value->copyObject();
+            value = dummy->modulocoeff( value, true );
+        }
+    }
+    else  if ( is_imm( cf.value ) )
+        value = value->modulocoeff( cf.value, false );
+    else  if ( value->level() == cf.value->level() ) {
+        if ( value->levelcoeff() == cf.value->levelcoeff() )
+            value = value->modulosame( cf.value );
+        else  if ( value->levelcoeff() > cf.value->levelcoeff() )
+            value = value->modulocoeff( cf.value, false );
+        else {
+            InternalCF * dummy = cf.value->copyObject();
+            dummy = dummy->modulocoeff( value, true );
+            if ( value->deleteObject() ) delete value;
+            value = dummy;
+        }
+    }
+    else  if ( level() > cf.level() )
+        value = value->modulocoeff( cf.value, false );
+    else {
+        InternalCF * dummy = cf.value->copyObject();
+        dummy = dummy->modulocoeff( value, true );
+        if ( value->deleteObject() ) delete value;
+        value = dummy;
+    }
+    return *this;
+}
+
+CanonicalForm &
+CanonicalForm::mod ( const CanonicalForm & cf )
+{
+    int what = is_imm( value );
+    if ( what ) {
+        ASSERT ( ! is_imm( cf.value ) || (what==is_imm( cf.value )), "illegal base coefficients" );
+        if ( (what = is_imm( cf.value )) == FFMARK )
+            value = imm_mod_p( value, cf.value );
+        else  if ( what == GFMARK )
+            value = imm_mod_gf( value, cf.value );
+        else  if ( what )
+            value = imm_mod( value, cf.value );
+        else {
+            InternalCF * dummy = cf.value->copyObject();
+            value = dummy->modcoeff( value, true );
+        }
+    }
+    else  if ( is_imm( cf.value ) )
+        value = value->modcoeff( cf.value, false );
+    else  if ( value->level() == cf.value->level() ) {
+        if ( value->levelcoeff() == cf.value->levelcoeff() )
+            value = value->modsame( cf.value );
+        else  if ( value->levelcoeff() > cf.value->levelcoeff() )
+            value = value->modcoeff( cf.value, false );
+        else {
+            InternalCF * dummy = cf.value->copyObject();
+            dummy = dummy->modcoeff( value, true );
+            if ( value->deleteObject() ) delete value;
+            value = dummy;
+        }
+    }
+    else  if ( level() > cf.level() )
+        value = value->modcoeff( cf.value, false );
+    else {
+        InternalCF * dummy = cf.value->copyObject();
+        dummy = dummy->modcoeff( value, true );
+        if ( value->deleteObject() ) delete value;
+        value = dummy;
+    }
+    return *this;
+}
+
+void
+divrem ( const CanonicalForm & f, const CanonicalForm & g, CanonicalForm & q, CanonicalForm & r )
+{
+    InternalCF * qq = 0, * rr = 0;
+    int what = is_imm( f.value );
+    if ( what )
+        if ( is_imm( g.value ) ) {
+            if ( what == FFMARK )
+                imm_divrem_p( f.value, g.value, qq, rr );
+            else  if ( what == GFMARK )
+                imm_divrem_gf( f.value, g.value, qq, rr );
+            else
+                imm_divrem( f.value, g.value, qq, rr );
+        }
+        else
+            g.value->divremcoeff( f.value, qq, rr, true );
+    else  if ( (what=is_imm( g.value )) )
+        f.value->divremcoeff( g.value, qq, rr, false );
+    else  if ( f.value->level() == g.value->level() )
+        if ( f.value->levelcoeff() == g.value->levelcoeff() )
+            f.value->divremsame( g.value, qq, rr );
+        else  if ( f.value->levelcoeff() > g.value->levelcoeff() )
+            f.value->divremcoeff( g.value, qq, rr, false );
+        else
+            g.value->divremcoeff( f.value, qq, rr, true );
+    else  if ( f.value->level() > g.value->level() )
+        f.value->divremcoeff( g.value, qq, rr, false );
+    else
+        g.value->divremcoeff( f.value, qq, rr, true );
+    ASSERT( qq != 0 && rr != 0, "error in divrem" );
+    q = CanonicalForm( qq );
+    r = CanonicalForm( rr );
+}
+
+bool
+divremt ( const CanonicalForm & f, const CanonicalForm & g, CanonicalForm & q, CanonicalForm & r )
+{
+    InternalCF * qq = 0, * rr = 0;
+    int what = is_imm( f.value );
+    bool result = true;
+    if ( what )
+        if ( is_imm( g.value ) ) {
+            if ( what == FFMARK )
+                imm_divrem_p( f.value, g.value, qq, rr );
+            else  if ( what == GFMARK )
+                imm_divrem_gf( f.value, g.value, qq, rr );
+            else
+                imm_divrem( f.value, g.value, qq, rr );
+        }
+        else
+            result = g.value->divremcoefft( f.value, qq, rr, true );
+    else  if ( (what=is_imm( g.value )) )
+        result = f.value->divremcoefft( g.value, qq, rr, false );
+    else  if ( f.value->level() == g.value->level() )
+        if ( f.value->levelcoeff() == g.value->levelcoeff() )
+            result = f.value->divremsamet( g.value, qq, rr );
+        else  if ( f.value->levelcoeff() > g.value->levelcoeff() )
+            result = f.value->divremcoefft( g.value, qq, rr, false );
+        else
+            result = g.value->divremcoefft( f.value, qq, rr, true );
+    else  if ( f.value->level() > g.value->level() )
+        result = f.value->divremcoefft( g.value, qq, rr, false );
+    else
+        result = g.value->divremcoefft( f.value, qq, rr, true );
+    if ( result ) {
+        ASSERT( qq != 0 && rr != 0, "error in divrem" );
+        q = CanonicalForm( qq );
+        r = CanonicalForm( rr );
+    }
+    else {
+        q = 0; r = 0;
+    }
+    return result;
+}
+
+///same as divremt but handles zero divisors in case we are in Z_p[x]/(f) where f is not irreducible
+bool
+tryDivremt ( const CanonicalForm & f, const CanonicalForm & g, CanonicalForm & q, CanonicalForm & r, const CanonicalForm& M, bool& fail )
+{
+    ASSERT (getCharacteristic() > 0, "expected positive characteristic");
+    ASSERT (!getReduce (M.mvar()), "do not reduce modulo M");
+    fail= false;
+    InternalCF * qq = 0, * rr = 0;
+    int what = is_imm( f.value );
+    bool result = true;
+    if ( what )
+        if ( is_imm( g.value ) ) {
+            if ( what == FFMARK )
+                imm_divrem_p( f.value, g.value, qq, rr );
+            else  if ( what == GFMARK )
+                imm_divrem_gf( f.value, g.value, qq, rr );
+        }
+        else
+            result = g.value->tryDivremcoefft( f.value, qq, rr, true, M, fail );
+    else  if ( (what=is_imm( g.value )) )
+        result = f.value->tryDivremcoefft( g.value, qq, rr, false, M, fail );
+    else  if ( f.value->level() == g.value->level() )
+        if ( f.value->levelcoeff() == g.value->levelcoeff() )
+            result = f.value->tryDivremsamet( g.value, qq, rr, M, fail );
+        else  if ( f.value->levelcoeff() > g.value->levelcoeff() )
+            result = f.value->tryDivremcoefft( g.value, qq, rr, false, M, fail );
+        else
+            result = g.value->tryDivremcoefft( f.value, qq, rr, true, M, fail );
+    else  if ( f.value->level() > g.value->level() )
+        result = f.value->tryDivremcoefft( g.value, qq, rr, false, M, fail );
+    else
+        result = g.value->tryDivremcoefft( f.value, qq, rr, true, M, fail );
+    if (fail)
+    {
+      q= 0;
+      r= 0;
+      return false;
+    }
+    if ( result ) {
+        ASSERT( qq != 0 && rr != 0, "error in divrem" );
+        q = CanonicalForm( qq );
+        r = CanonicalForm( rr );
+        q= reduce (q, M);
+        r= reduce (r, M);
+    }
+    else {
+        q = 0; r = 0;
+    }
+    return result;
+}
+
+/**
+ *
+ * operator ()() - evaluation operator.
+ *
+ * Returns CO if CO is in a base domain.
+ *
+ * operator () ( f ) returns CO with f inserted for the main
+ * variable.  Elements in an algebraic extension are considered
+ * polynomials.
+ *
+**/
+CanonicalForm
+CanonicalForm::operator () ( const CanonicalForm & f ) const
+{
+    if ( is_imm( value ) || value->inBaseDomain() )
+        return *this;
+    else {
+#if 0
+        CFIterator i = *this;
+        int lastExp = i.exp();
+        CanonicalForm result = i.coeff();
+        i++;
+        while ( i.hasTerms() ) {
+            if ( (lastExp - i.exp()) == 1 )
+                result *= f;
+            else
+                result *= power( f, lastExp - i.exp() );
+            result += i.coeff();
+            lastExp = i.exp();
+            i++;
+        }
+        if ( lastExp != 0 )
+            result *= power( f, lastExp );
+#else
+        CFIterator i = *this;
+        int lastExp = i.exp();
+        CanonicalForm result = i.coeff();
+        i++;
+        while ( i.hasTerms() )
+        {
+            int i_exp=i.exp();
+            if ( (lastExp - i_exp /* i.exp()*/) == 1 )
+                result *= f;
+            else
+                result *= power( f, lastExp - i_exp /*i.exp()*/ );
+            result += i.coeff();
+            lastExp = i_exp /*i.exp()*/;
+            i++;
+        }
+        if ( lastExp != 0 )
+            result *= power( f, lastExp );
+#endif
+        return result;
+    }
+}
+
+/**
+ * Returns CO if CO is in a base domain.
+ *
+ * operator () ( f, v ) returns CO with f inserted for v.
+ * Elements in an algebraic extension are considered polynomials
+ * and v may be an algebraic variable.
+**/
+CanonicalForm
+CanonicalForm::operator () ( const CanonicalForm & f, const Variable & v ) const
+{
+    if ( is_imm( value ) || value->inBaseDomain() )
+        return *this;
+
+    Variable x = value->variable();
+    if ( v > x )
+        return *this;
+    else  if ( v == x )
+        return (*this)( f );
+    else {
+        // v is less than main variable of f
+        CanonicalForm result = 0;
+        for ( CFIterator i = *this; i.hasTerms(); i++ )
+            result += i.coeff()( f, v ) * power( x, i.exp() );
+        return result;
+    }
+}
+
+/**
+ *
+ * operator []() - return i'th coefficient from CO.
+ *
+ * Returns CO if CO is in a base domain and i equals zero.
+ * Returns zero (from the current domain) if CO is in a base
+ * domain and i is larger than zero.  Otherwise, returns the
+ * coefficient to x^i in CO (if x denotes the main variable of
+ * CO) or zero if CO does not contain x^i.  Elements in an
+ * algebraic extension are considered polynomials.  i should be
+ * larger or equal zero.
+ *
+ * Note: Never use a loop like
+ *
+~~~~~~~~~~~~~~~~~~~~~{.c}
+    for ( int i = degree( f ); i >= 0; i-- )
+         foo( i, f[ i ] );
+~~~~~~~~~~~~~~~~~~~~~
+ *
+ * which is much slower than
+ *
+~~~~~~~~~~~~~~~~~~~~~{.c}
+ * for ( int i = degree( f ), CFIterator I = f; I.hasTerms(); I++ ) {
+ *     // fill gap with zeroes
+ *     for ( ; i > I.exp(); i-- )
+ *         foo( i, 0 );
+ *     // at this point, i == I.exp()
+ *     foo( i, i.coeff() );
+ *     i--;
+ * }
+ * // work through trailing zeroes
+ * for ( ; i >= 0; i-- )
+ *     foo( i, 0 );
+~~~~~~~~~~~~~~~~~~~~~
+ *
+**/
+CanonicalForm
+CanonicalForm::operator [] ( int i ) const
+{
+    ASSERT( i >= 0, "index to operator [] less than zero" );
+    if ( is_imm( value ) )
+        if ( i == 0 )
+            return *this;
+        else
+            return CanonicalForm( 0 );
+    else
+        return value->coeff( i );
+}
+
+/**
+ *
+ * deriv() - return the formal derivation of CO.
+ *
+ * deriv() derives CO with respect to its main variable.  Returns
+ * zero from the current domain if f is in a coefficient domain.
+ *
+ * @sa  CanonicalForm::deriv ( const Variable & x )
+ *
+**/
+CanonicalForm
+CanonicalForm::deriv () const
+{
+    if ( is_imm( value ) || value->inCoeffDomain() )
+        return CanonicalForm( 0 );
+    else {
+        CanonicalForm result = 0;
+        Variable x = value->variable();
+        for ( CFIterator i = *this; i.hasTerms(); i++ )
+            if ( i.exp() > 0 )
+                result += power( x, i.exp()-1 ) * i.coeff() * i.exp();
+        return result;
+    }
+}
+
+/**
+ * deriv( x ) derives CO with respect to x.  x should be a
+ * polynomial variable.  Returns zero from the current domain if
+ * f is in a coefficient domain.
+**/
+CanonicalForm
+CanonicalForm::deriv ( const Variable & x ) const
+{
+    ASSERT( x.level() > 0, "cannot derive with respect to algebraic variables" );
+    if ( is_imm( value ) || value->inCoeffDomain() )
+        return CanonicalForm( 0 );
+
+    Variable y = value->variable();
+    if ( x > y )
+        return CanonicalForm( 0 );
+    else if ( x == y )
+        return deriv();
+    else {
+        CanonicalForm result = 0;
+        for ( CFIterator i = *this; i.hasTerms(); i++ )
+            result += i.coeff().deriv( x ) * power( y, i.exp() );
+        return result;
+    }
+}
+
+/** int CanonicalForm::sign () const
+ *
+ * sign() - return sign of CO.
+ *
+ * If CO is an integer or a rational number, the sign is defined
+ * as usual.  If CO is an element of a prime power domain or of
+ * FF(p) and SW_SYMMETRIC_FF is on, the sign of CO is the sign of
+ * the symmetric representation of CO.  If CO is in GF(q) or in
+ * FF(p) and SW_SYMMETRIC_FF is off, the sign of CO is zero iff
+ * CO is zero, otherwise the sign is one.
+ *
+ * If CO is a polynomial or in an extension of one of the base
+ * domains, the sign of CO is the sign of its leading
+ * coefficient.
+ *
+ * @sa InternalCF::sign(), InternalInteger::sign(),
+ * InternalRational::sign(),
+ * InternalPoly::sign(), imm_sign(), gf_sign()
+ *
+**/
+int
+CanonicalForm::sign () const
+{
+    if ( is_imm( value ) )
+        return imm_sign( value );
+    else
+        return value->sign();
+}
+
+/** CanonicalForm CanonicalForm::sqrt () const
+ *
+ * sqrt() - calculate integer square root.
+ *
+ * CO has to be an integer greater or equal zero.  Returns the
+ * largest integer less or equal sqrt(CO).
+ *
+ * In the immediate case, we use the newton method to find the
+ * root.  The algorithm is from H. Cohen - 'A Course in
+ * Computational Algebraic Number Theory', ch. 1.7.1.
+ *
+ * @sa InternalCF::sqrt(), InternalInteger::sqrt(), ::sqrt()
+ *
+**/
+CanonicalForm
+CanonicalForm::sqrt () const
+{
+    if ( is_imm( value ) ) {
+        ASSERT( is_imm( value ) == INTMARK, "sqrt() not implemented" );
+        long n = imm2int( value );
+        ASSERT( n >= 0, "arg to sqrt() less than zero" );
+        if ( n == 0 || n == 1 )
+            return CanonicalForm( n );
+        else {
+            long x, y = n;
+            do {
+                x = y;
+                // the intermediate result may not fit into an
+                // integer, but the result does
+                y = (unsigned long)(x + n/x)/2;
+            } while ( y < x );
+            return CanonicalForm( x );
+        }
+    }
+    else
+        return CanonicalForm( value->sqrt() );
+}
+
+/** int CanonicalForm::ilog2 () const
+ *
+ * ilog2() - integer logarithm to base 2.
+ *
+ * Returns the largest integer less or equal logarithm of CO to
+ * base 2.  CO should be a positive integer.
+ *
+ * @sa InternalCF::ilog2(), InternalInteger::ilog2(), ::ilog2()
+ *
+**/
+int
+CanonicalForm::ilog2 () const
+{
+    if ( is_imm( value ) )
+    {
+        ASSERT( is_imm( value ) == INTMARK, "ilog2() not implemented" );
+        long a = imm2int( value );
+        ASSERT( a > 0, "arg to ilog2() less or equal zero" );
+        int n = -1;
+        while ( a > 0 )
+        {
+          n++;
+          a /=2;
+        }
+        return n;
+    }
+    else
+        return value->ilog2();
+}
+
+/**
+ *
+ * operator ==() - compare canonical forms on
+ *   (in)equality.
+ *
+ * operator ==() returns true iff lhs equals rhs.
+ *
+ * This is the point in factory where we essentially use that
+ * CanonicalForms in fact are canonical.  There must not be two
+ * different representations of the same mathematical object,
+ * otherwise, such (in)equality will not be recognized by these
+ * operators.  In other word, we rely on the fact that structural
+ * different factory objects in any case represent different
+ * mathematical objects.
+ *
+ * So we use the following procedure to test on equality (and
+ * analogously on inequality).  First, we check whether lhs.value
+ * equals rhs.value.  If so we are ready and return true.
+ * Second, if one of the operands is immediate, but the other one
+ * not, we return false.  Third, if the operand's levels differ
+ * we return false.  Fourth, if the operand's levelcoeffs differ
+ * we return false.  At last, we call the corresponding internal
+ * method to compare both operands.
+ *
+ * Both operands should have coefficients from the same base domain.
+ *
+ * Note: To compare with the zero or the unit of the current domain,
+ * you better use the methods `CanonicalForm::isZero()' or
+ * `CanonicalForm::isOne()', resp., than something like `f == 0',
+ * since the latter is quite a lot slower.
+ *
+ * @sa CanonicalForm::operator !=(), InternalCF::comparesame(),
+ * InternalInteger::comparesame(), InternalRational::comparesame(),
+ * InternalPoly::comparesame()
+ *
+**/
+bool
+operator == ( const CanonicalForm & lhs, const CanonicalForm & rhs )
+{
+    if ( lhs.value == rhs.value )
+        return true;
+    else if ( is_imm( rhs.value ) || is_imm( lhs.value ) ) {
+        ASSERT( ! is_imm( rhs.value ) ||
+                ! is_imm( lhs.value ) ||
+                is_imm( rhs.value ) == is_imm( lhs.value ),
+                "incompatible operands" );
+        return false;
+    }
+    else  if ( lhs.value->level() != rhs.value->level() )
+        return false;
+    else  if ( lhs.value->levelcoeff() != rhs.value->levelcoeff() )
+        return false;
+    else
+        return rhs.value->comparesame( lhs.value ) == 0;
+}
+
+/**
+ * operator !=() returns true iff lhs does not equal rhs.
+ *
+ * @sa CanonicalForm::operator ==()
+**/
+bool
+operator != ( const CanonicalForm & lhs, const CanonicalForm & rhs )
+{
+    if ( lhs.value == rhs.value )
+        return false;
+    else if ( is_imm( rhs.value ) || is_imm( lhs.value ) ) {
+        ASSERT( ! is_imm( rhs.value ) ||
+                ! is_imm( lhs.value ) ||
+                is_imm( rhs.value ) == is_imm( lhs.value ),
+                "incompatible operands" );
+        return true;
+    }
+    else  if ( lhs.value->level() != rhs.value->level() )
+        return true;
+    else  if ( lhs.value->levelcoeff() != rhs.value->levelcoeff() )
+        return true;
+    else        return rhs.value->comparesame( lhs.value ) != 0;
+}
+
+/**
+ *
+ * operator >() - compare canonical forms. on size or
+ *   level.
+ *
+ * The most common and most useful application of these operators
+ * is to compare two integers or rationals, of course.  However,
+ * these operators are defined on all other base domains and on
+ * polynomials, too.  From a mathematical point of view this may
+ * seem meaningless, since there is no ordering on finite fields
+ * or on polynomials respecting the algebraic structure.
+ * Nevertheless, from a programmer's point of view it may be
+ * sensible to order these objects, e.g. to sort them.
+ *
+ * Therefore, the ordering defined by these operators in any case
+ * is a total ordering which fulfills the law of trichotomy.
+ *
+ * It is clear how this is done in the case of the integers and
+ * the rationals.  For finite fields, all you can say is that
+ * zero is the minimal element w.r.t. the ordering, the other
+ * elements are ordered in an arbitrary (but total!)  way.  For
+ * polynomials, you have an ordering derived from the
+ * lexicographical ordering of monomials.  E.g. if lm(f) < lm(g)
+ * w.r.t. lexicographic ordering, then f < g.  For more details,
+ * refer to the documentation of `InternalPoly::operator <()'.
+ *
+ * Both operands should have coefficients from the same base domain.
+ *
+ * The scheme how both operators are implemented is allmost the
+ * same as for the assignment operators (check for immediates,
+ * then check levels, then check levelcoeffs, then call the
+ * appropriate internal comparesame()/comparecoeff() method).
+ * For more information, confer to the overview for the
+ * arithmetic operators.
+ *
+ * @sa CanonicalForm::operator <(), InternalCF::comparesame(),
+ * InternalInteger::comparesame(), InternalRational::comparesame(),
+ * InternalPoly::comparesame(),
+ * InternalCF::comparecoeff(), InternalInteger::comparecoeff(),
+ * InternalRational::comparecoeff(),
+ * InternalPoly::comparecoeff(),
+ * imm_cmp(), imm_cmp_p(), imm_cmp_gf()
+ *
+**/
+bool
+operator > ( const CanonicalForm & lhs, const CanonicalForm & rhs )
+{
+    int what = is_imm( rhs.value );
+    if ( is_imm( lhs.value ) ) {
+        ASSERT( ! what || (what == is_imm( lhs.value )), "incompatible operands" );
+        if ( what == 0 )
+            return rhs.value->comparecoeff( lhs.value ) < 0;
+        else if ( what == INTMARK )
+            return imm_cmp( lhs.value, rhs.value ) > 0;
+        else if ( what == FFMARK )
+            return imm_cmp_p( lhs.value, rhs.value ) > 0;
+        else
+            return imm_cmp_gf( lhs.value, rhs.value ) > 0;
+    }
+    else  if ( what )
+        return lhs.value->comparecoeff( rhs.value ) > 0;
+    else  if ( lhs.value->level() == rhs.value->level() )
+        if ( lhs.value->levelcoeff() == rhs.value->levelcoeff() )
+            return lhs.value->comparesame( rhs.value ) > 0;
+        else  if ( lhs.value->levelcoeff() > rhs.value->levelcoeff() )
+            return lhs.value->comparecoeff( rhs.value ) > 0;
+        else
+            return rhs.value->comparecoeff( lhs.value ) < 0;
+    else
+        return lhs.value->level() > rhs.value->level();
+}
+
+/**
+ * @sa CanonicalForm::operator >()
+**/
+bool
+operator < ( const CanonicalForm & lhs, const CanonicalForm & rhs )
+{
+    int what = is_imm( rhs.value );
+    if ( is_imm( lhs.value ) ) {
+        ASSERT( ! what || (what == is_imm( lhs.value )), "incompatible operands" );
+        if ( what == 0 )
+            return rhs.value->comparecoeff( lhs.value ) > 0;
+        else if ( what == INTMARK )
+            return imm_cmp( lhs.value, rhs.value ) < 0;
+        else if ( what == FFMARK )
+            return imm_cmp_p( lhs.value, rhs.value ) < 0;
+        else
+            return imm_cmp_gf( lhs.value, rhs.value ) < 0;
+    }
+    else  if ( what )
+        return lhs.value->comparecoeff( rhs.value ) < 0;
+    else  if ( lhs.value->level() == rhs.value->level() )
+        if ( lhs.value->levelcoeff() == rhs.value->levelcoeff() )
+            return lhs.value->comparesame( rhs.value ) < 0;
+        else  if ( lhs.value->levelcoeff() > rhs.value->levelcoeff() )
+            return lhs.value->comparecoeff( rhs.value ) < 0;
+        else
+            return rhs.value->comparecoeff( lhs.value ) > 0;
+    else
+        return lhs.value->level() < rhs.value->level();
+}
+
+/** CanonicalForm bgcd ( const CanonicalForm & f, const CanonicalForm & g )
+ *
+ * bgcd() - return base coefficient gcd.
+ *
+ * If both f and g are integers and `SW_RATIONAL' is off the
+ * positive greatest common divisor of f and g is returned.
+ * Otherwise, if `SW_RATIONAL' is on or one of f and g is not an
+ * integer, the greatest common divisor is trivial: either zero
+ * if f and g equal zero or one (both from the current domain).
+ *
+ * f and g should come from one base domain which should be not
+ * the prime power domain.
+ *
+ * Implementation:
+ *
+ * CanonicalForm::bgcd() handles the immediate case with a
+ *   standard euclidean algorithm.  For the non-immediate cases
+ *   `InternalCF::bgcdsame()' or `InternalCF::bgcdcoeff()', resp. are
+ *   called following the usual level/levelcoeff approach.
+ *
+ * InternalCF::bgcdsame() and
+ * InternalCF::bgcdcoeff() throw an assertion ("not implemented")
+ *
+ * InternalInteger::bgcdsame() is a wrapper around `mpz_gcd()'
+ *   which takes some care about immediate results and the sign
+ *   of the result
+ * InternalInteger::bgcdcoeff() is a wrapper around
+ *   `mpz_gcd_ui()' which takes some care about the sign
+ *   of the result
+ *
+ * InternalRational::bgcdsame() and
+ * InternalRational::bgcdcoeff() always return one
+ *
+**/
+CanonicalForm
+bgcd ( const CanonicalForm & f, const CanonicalForm & g )
+{
+    // check immediate cases
+    int what = is_imm( g.value );
+    if ( is_imm( f.value ) )
+    {
+        ASSERT( ! what || (what == is_imm( f.value )), "incompatible operands" );
+        if ( what == 0 )
+            return g.value->bgcdcoeff( f.value );
+        else if ( what == INTMARK && ! cf_glob_switches.isOn( SW_RATIONAL ) )
+        {
+            // calculate gcd using standard integer
+            // arithmetic
+            long fInt = imm2int( f.value );
+            long gInt = imm2int( g.value );
+
+            if ( fInt < 0 ) fInt = -fInt;
+            if ( gInt < 0 ) gInt = -gInt;
+            // swap fInt and gInt
+            if ( gInt > fInt )
+            {
+                long swap = gInt;
+                gInt = fInt;
+                fInt = swap;
+            }
+
+            // now, 0 <= gInt <= fInt.  Start the loop.
+            while ( gInt )
+            {
+                // calculate (fInt, gInt) = (gInt, fInt%gInt)
+                long r = fInt % gInt;
+                fInt = gInt;
+                gInt = r;
+            }
+
+            return CanonicalForm( fInt );
+        }
+        else
+            // we do not go for maximal speed for these stupid
+            // special cases
+            return CanonicalForm( f.isZero() && g.isZero() ? 0 : 1 );
+    }
+    else if ( what )
+        return f.value->bgcdcoeff( g.value );
+
+    int fLevel = f.value->level();
+    int gLevel = g.value->level();
+
+    // check levels
+    if ( fLevel == gLevel )
+    {
+        fLevel = f.value->levelcoeff();
+        gLevel = g.value->levelcoeff();
+
+        // check levelcoeffs
+        if ( fLevel == gLevel )
+            return f.value->bgcdsame( g.value );
+        else if ( fLevel < gLevel )
+            return g.value->bgcdcoeff( f.value );
+        else
+            return f.value->bgcdcoeff( g.value );
+    }
+    else if ( fLevel < gLevel )
+        return g.value->bgcdcoeff( f.value );
+    else
+        return f.value->bgcdcoeff( g.value );
+}
+
+/** CanonicalForm bextgcd ( const CanonicalForm & f, const CanonicalForm & g, CanonicalForm & a, CanonicalForm & b )
+ *
+ * bextgcd() - return base coefficient extended gcd.
+ *
+**/
+CanonicalForm
+bextgcd ( const CanonicalForm & f, const CanonicalForm & g, CanonicalForm & a, CanonicalForm & b )
+{
+    // check immediate cases
+    int what = is_imm( g.value );
+    if ( is_imm( f.value ) ) {
+        ASSERT( ! what || (what == is_imm( f.value )), "incompatible operands" );
+        if ( what == 0 )
+            return g.value->bextgcdcoeff( f.value, b, a );
+        else if ( what == INTMARK && ! cf_glob_switches.isOn( SW_RATIONAL ) ) {
+            // calculate extended gcd using standard integer
+            // arithmetic
+            long fInt = imm2int( f.value );
+            long gInt = imm2int( g.value );
+
+            // to avoid any system dpendencies with `%', we work
+            // with positive numbers only.  To a pity, we have to
+            // redo all the checks when assigning to a and b.
+            if ( fInt < 0 ) fInt = -fInt;
+            if ( gInt < 0 ) gInt = -gInt;
+            // swap fInt and gInt
+            if ( gInt > fInt ) {
+                long swap = gInt;
+                gInt = fInt;
+                fInt = swap;
+            }
+
+            long u = 1; long v = 0;
+            long uNext = 0; long vNext = 1;
+
+            // at any step, we have:
+            // fInt_0 * u + gInt_0 * v = fInt
+            // fInt_0 * uNext + gInt_0 * vNext = gInt
+            // where fInt_0 and gInt_0 denote the values of fint
+            // and gInt, resp., at the beginning
+            while ( gInt ) {
+                long r = fInt % gInt;
+                long q = fInt / gInt;
+                long uSwap = u - q * uNext;
+                long vSwap = v - q * vNext;
+
+                // update variables
+                fInt = gInt;
+                gInt = r;
+                u = uNext; v = vNext;
+                uNext = uSwap; vNext = vSwap;
+            }
+
+            // now, assign to a and b
+            long fTest = imm2int( f.value );
+            long gTest = imm2int( g.value );
+            if ( gTest > fTest ) {
+                a = v; b = u;
+            } else {
+                a = u; b = v;
+            }
+            if ( fTest < 0 ) a = -a;
+            if ( gTest < 0 ) b = -b;
+            return CanonicalForm( fInt );
+        } else
+            // stupid special cases
+            if ( ! f.isZero() ) {
+                a = 1/f; b = 0; return CanonicalForm( 1 );
+            } else if ( ! g.isZero() ) {
+                a = 0; b = 1/g; return CanonicalForm( 1 );
+            } else {
+                a = 0; b = 0; return CanonicalForm( 0 );
+            }
+    }
+    else if ( what )
+        return f.value->bextgcdcoeff( g.value, a, b );
+
+    int fLevel = f.value->level();
+    int gLevel = g.value->level();
+
+    // check levels
+    if ( fLevel == gLevel ) {
+        fLevel = f.value->levelcoeff();
+        gLevel = g.value->levelcoeff();
+
+        // check levelcoeffs
+        if ( fLevel == gLevel )
+            return f.value->bextgcdsame( g.value, a, b );
+        else if ( fLevel < gLevel )
+            return g.value->bextgcdcoeff( f.value, b, a );
+        else
+            return f.value->bextgcdcoeff( g.value, a, b );
+    }
+    else if ( fLevel < gLevel )
+        return g.value->bextgcdcoeff( f.value, b, a );
+    else
+        return f.value->bextgcdcoeff( g.value, a, b );
+}
+
+CanonicalForm
+blcm ( const CanonicalForm & f, const CanonicalForm & g )
+{
+    if ( f.isZero() || g.isZero() )
+        return CanonicalForm( 0 );
+/*
+    else if (f.isOne())
+        return g;
+    else if (g.isOne())
+        return f;
+*/
+    else
+        return (f / bgcd( f, g )) * g;
+}
+
+/** input/output **/
+#ifndef NOSTREAMIO
+void
+CanonicalForm::print( OSTREAM & os, char * str ) const
+{
+    if ( is_imm( value ) )
+        imm_print( os, value, str );
+    else
+        value->print( os, str );
+}
+
+void
+CanonicalForm::print( OSTREAM & os ) const
+{
+    if ( is_imm( value ) )
+        imm_print( os, value, "" );
+    else
+        value->print( os, "" );
+}
+
+OSTREAM&
+operator << ( OSTREAM & os, const CanonicalForm & cf )
+{
+    cf.print( os, "" );
+    return os;
+}
+
+ISTREAM&
+operator >> ( ISTREAM & is, CanonicalForm & cf )
+{
+    cf = readCF( is );
+    return is;
+}
+#endif /* NOSTREAMIO */
+
+/** genOne(), genZero() **/
+CanonicalForm
+CanonicalForm::genZero() const
+{
+    int what = is_imm( value );
+    if ( what == FFMARK )
+        return CanonicalForm( CFFactory::basic( FiniteFieldDomain, 0L ) );
+    else  if ( what == GFMARK )
+        return CanonicalForm( CFFactory::basic( GaloisFieldDomain, 0L ) );
+    else  if ( what )
+        return CanonicalForm( CFFactory::basic( IntegerDomain, 0L ) );
+    else
+        return CanonicalForm( value->genZero() );
+}
+
+CanonicalForm
+CanonicalForm::genOne() const
+{
+    int what = is_imm( value );
+    if ( what == FFMARK )
+        return CanonicalForm( CFFactory::basic( FiniteFieldDomain, 1L ) );
+    else  if ( what == GFMARK )
+        return CanonicalForm( CFFactory::basic( GaloisFieldDomain, 1L ) );
+    else  if ( what )
+        return CanonicalForm( CFFactory::basic( IntegerDomain, 1L ) );
+    else
+        return CanonicalForm( value->genOne() );
+}
+
+/** exponentiation **/
+CanonicalForm
+power ( const CanonicalForm & f, int n )
+{
+  ASSERT( n >= 0, "illegal exponent" );
+  if ( f.isZero() )
+    return 0;
+  else  if ( f.isOne() )
+    return f;
+  else  if ( f == -1 )
+  {
+    if ( n % 2 == 0 )
+      return 1;
+    else
+      return -1;
+  }
+  else  if ( n == 0 )
+    return 1;
+
+  //else if (f.inGF())
+  //{
+  //}
+  else
+  {
+    CanonicalForm g,h;
+    h=f;
+    while(n%2==0)
+    {
+      h*=h;
+      n/=2;
+    }
+    g=h;
+    while(1)
+    {
+      n/=2;
+      if(n==0)
+        return g;
+      h*=h;
+      if(n%2!=0) g*=h;
+    }
+  }
+}
+
+/** exponentiation **/
+CanonicalForm
+power ( const Variable & v, int n )
+{
+    //ASSERT( n >= 0, "illegal exponent" );
+    if ( n == 0 )
+        return 1;
+    else  if ( n == 1 )
+        return v;
+    else  if (( v.level() < 0 ) && (hasMipo(v)))
+    {
+        CanonicalForm result( v, n-1 );
+        return result * v;
+    }
+    else
+        return CanonicalForm( v, n );
+}
+
+/** switches **/
+void
+On( int sw )
+{
+    cf_glob_switches.On( sw );
+}
+
+/** switches **/
+void
+Off( int sw )
+{
+    cf_glob_switches.Off( sw );
+}
+
+/** switches **/
+bool
+isOn( int sw )
+{
+    return cf_glob_switches.isOn( sw );
+}
diff --git a/factory/canonicalform.h b/factory/canonicalform.h
new file mode 100644
index 0000000..0af59f5
--- /dev/null
+++ b/factory/canonicalform.h
@@ -0,0 +1,393 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+/**
+ * @file canonicalform.h
+ *
+ * Header for factory's main class CanonicalForm
+**/
+#ifndef INCL_CANONICALFORM_H
+#define INCL_CANONICALFORM_H
+
+// #include "config.h"
+
+#ifndef NOSTREAMIO
+# ifdef HAVE_IOSTREAM
+#  include <iostream>
+#  define OSTREAM std::ostream
+#  define ISTREAM std::istream
+# elif defined(HAVE_IOSTREAM_H)
+#  include <iostream.h>
+#  define OSTREAM ostream
+#  define ISTREAM istream
+# endif
+#endif /* NOSTREAMIO */
+
+#include <stdint.h>
+
+#include "cf_defs.h"
+#include "variable.h"
+#include <factory/cf_gmp.h>
+#include <factory/templates/ftmpl_list.h>
+#include <factory/templates/ftmpl_array.h>
+#include <factory/templates/ftmpl_afactor.h>
+#include <factory/templates/ftmpl_factor.h>
+#include <factory/templates/ftmpl_matrix.h>
+
+/*BEGINPUBLIC*/
+
+#undef CF_INLINE
+#define CF_INLINE
+#undef CF_NO_INLINE
+#define CF_NO_INLINE
+
+/*ENDPUBLIC*/
+
+#ifdef CF_USE_INLINE
+#undef CF_INLINE
+#define CF_INLINE inline
+#else
+#undef CF_INLINE
+#define CF_INLINE
+#endif
+
+/*BEGINPUBLIC*/
+
+class InternalCF;
+
+inline int is_imm ( const InternalCF * const ptr )
+{
+    // returns 0 if ptr is not immediate
+    return ( ((int)((intptr_t)ptr)) & 3 );
+}
+
+
+/**
+ * factory's main class
+ *
+ * a CanonicalForm can represent a polynomial over or a constant in F_p,
+ * F_p(alpha), GF (F_p[t]/(Conway polynomial)), Z, or Q
+ *
+ * @sa int_poly.h, variable.h, ffops.h, gfops.h, imm.h, int_int.h, int_rat.h
+**/
+class CanonicalForm
+{
+private:
+    InternalCF *value;
+public:
+    // constructors, destructors, selectors
+    CF_INLINE CanonicalForm();
+    CF_INLINE CanonicalForm( const CanonicalForm& );
+    CF_INLINE CanonicalForm( InternalCF* );
+    CF_INLINE CanonicalForm( const int );
+    CF_INLINE CanonicalForm( const long );
+    CF_INLINE CanonicalForm( const Variable & );
+    CF_INLINE CanonicalForm( const Variable &, int );
+    CanonicalForm( const char *, const int base=10 ); // use with caution - does only handle integers !!!
+
+    CF_NO_INLINE ~CanonicalForm();
+
+    InternalCF* getval() const; // use with caution !!!
+
+    CanonicalForm deepCopy() const;
+
+    void mpzval(mpz_t val) const;
+    // predicates
+    CF_NO_INLINE bool isOne() const;
+    CF_NO_INLINE bool isZero() const;
+    inline bool isImm() const { return is_imm( value ); };
+
+    bool inZ() const;
+    bool inQ() const;
+    bool inFF() const;
+    bool inGF() const;
+    bool inBaseDomain() const;
+    bool inExtension() const;
+    bool inCoeffDomain() const;
+    bool inPolyDomain() const;
+    bool inQuotDomain() const;
+
+    bool isFFinGF() const;
+    bool isUnivariate() const;
+    bool isHomogeneous() const;
+
+    // conversion functions
+    long intval() const;
+    CanonicalForm mapinto () const;
+
+    CanonicalForm lc () const;
+    CanonicalForm Lc () const;
+    CanonicalForm LC () const;
+    CanonicalForm LC ( const Variable & v ) const;
+
+    int degree () const;
+    int degree ( const Variable & v ) const;
+
+    CanonicalForm tailcoeff () const;
+    CanonicalForm tailcoeff ( const Variable & v ) const;
+    int taildegree () const;
+
+    int level () const;
+    Variable mvar () const;
+
+    CanonicalForm num () const;
+    CanonicalForm den () const;
+
+    // assignment operators
+    CF_NO_INLINE CanonicalForm& operator = ( const CanonicalForm& );
+    CF_NO_INLINE CanonicalForm& operator = ( const long );
+
+    CanonicalForm& operator += ( const CanonicalForm& );
+    CanonicalForm& operator -= ( const CanonicalForm& );
+    CanonicalForm& operator *= ( const CanonicalForm& );
+    CanonicalForm& operator /= ( const CanonicalForm& );
+    CanonicalForm& operator %= ( const CanonicalForm& );
+    CanonicalForm& div ( const CanonicalForm& );
+    CanonicalForm& tryDiv (const CanonicalForm&, const CanonicalForm&, bool& );
+    CanonicalForm& mod ( const CanonicalForm& );
+
+    // evaluation operators
+    CanonicalForm operator () ( const CanonicalForm & f ) const;
+    CanonicalForm operator () ( const CanonicalForm & f, const Variable & v ) const;
+
+    CanonicalForm operator [] ( int i ) const;
+
+    CanonicalForm deriv() const;
+    CanonicalForm deriv( const Variable & x ) const;
+
+    int sign() const;
+    CanonicalForm sqrt() const;
+    int ilog2() const;
+
+    // comparison operators
+    friend bool operator == ( const CanonicalForm&, const CanonicalForm& );
+    friend bool operator != ( const CanonicalForm&, const CanonicalForm& );
+    friend bool operator > ( const CanonicalForm&, const CanonicalForm& );
+    friend bool operator < ( const CanonicalForm&, const CanonicalForm& );
+
+    // arithmetic operators
+    friend CF_NO_INLINE CanonicalForm operator - ( const CanonicalForm& );
+
+    friend void divrem ( const CanonicalForm&, const CanonicalForm&, CanonicalForm&, CanonicalForm& );
+    friend bool divremt ( const CanonicalForm&, const CanonicalForm&, CanonicalForm&, CanonicalForm& );
+    friend bool tryDivremt ( const CanonicalForm&, const CanonicalForm&, CanonicalForm&, CanonicalForm&, const CanonicalForm&, bool& );
+
+    friend CanonicalForm bgcd ( const CanonicalForm &, const CanonicalForm & );
+    friend CanonicalForm bextgcd ( const CanonicalForm &, const CanonicalForm &, CanonicalForm &, CanonicalForm & );
+
+    // input/output
+#ifndef NOSTREAMIO
+   void print( OSTREAM&, char * ) const;
+   void print( OSTREAM& ) const;
+   friend OSTREAM& operator << ( OSTREAM&, const CanonicalForm& );
+   friend ISTREAM& operator >> ( ISTREAM&, CanonicalForm& );
+#endif /* NOSTREAMIO */
+
+    // obsolete methods
+    CanonicalForm genZero() const;
+    CanonicalForm genOne() const;
+
+    friend class CFIterator;
+};
+
+CF_INLINE CanonicalForm
+operator + ( const CanonicalForm&, const CanonicalForm& );
+
+CF_NO_INLINE CanonicalForm
+operator - ( const CanonicalForm&, const CanonicalForm& );
+
+CF_INLINE CanonicalForm
+operator * ( const CanonicalForm&, const CanonicalForm& );
+
+CF_NO_INLINE CanonicalForm
+operator / ( const CanonicalForm&, const CanonicalForm& );
+
+CF_NO_INLINE CanonicalForm
+operator % ( const CanonicalForm&, const CanonicalForm& );
+
+CF_NO_INLINE CanonicalForm
+div ( const CanonicalForm&, const CanonicalForm& );
+
+CF_NO_INLINE CanonicalForm
+mod ( const CanonicalForm&, const CanonicalForm& );
+
+/*ENDPUBLIC*/
+
+#ifdef CF_USE_INLINE
+#include "cf_inline.cc"
+#endif
+
+/*BEGINPUBLIC*/
+
+//{{{ function declarations from canonicalform.cc
+CanonicalForm blcm ( const CanonicalForm & f, const CanonicalForm & g );
+
+CanonicalForm power ( const CanonicalForm & f, int n );
+
+CanonicalForm power ( const Variable & v, int n );
+//}}}
+
+//{{{ function declarations from cf_gcd.cc
+CanonicalForm gcd ( const CanonicalForm&, const CanonicalForm& );
+
+CanonicalForm gcd_poly ( const CanonicalForm & f, const CanonicalForm & g );
+
+CanonicalForm lcm ( const CanonicalForm&, const CanonicalForm& );
+
+CanonicalForm pp ( const CanonicalForm& );
+
+CanonicalForm content ( const CanonicalForm& );
+
+CanonicalForm content ( const CanonicalForm&, const Variable& );
+
+CanonicalForm icontent ( const CanonicalForm & f );
+
+CanonicalForm vcontent ( const CanonicalForm & f, const Variable & x );
+//}}}
+
+//{{{ function declarations from cf_ops.cc
+CanonicalForm swapvar ( const CanonicalForm &, const Variable &, const Variable & );
+
+CanonicalForm replacevar ( const CanonicalForm &, const Variable &, const Variable & );
+
+int getNumVars( const CanonicalForm & f );
+
+CanonicalForm getVars( const CanonicalForm & f );
+
+CanonicalForm apply ( const CanonicalForm & f, void (*mf)( CanonicalForm &, int & ) );
+
+CanonicalForm mapdomain ( const CanonicalForm & f, CanonicalForm (*mf)( const CanonicalForm & ) );
+
+int * degrees ( const CanonicalForm & f, int * degs = 0 );
+
+int totaldegree ( const CanonicalForm & f );
+
+int totaldegree ( const CanonicalForm & f, const Variable & v1, const Variable & v2 );
+
+int size ( const CanonicalForm & f, const Variable & v );
+
+int size ( const CanonicalForm & f );
+
+CanonicalForm reduce ( const CanonicalForm& f, const CanonicalForm & M);
+
+bool hasFirstAlgVar( const CanonicalForm & f, Variable & a);
+
+CanonicalForm leftShift (const CanonicalForm& F, int n);
+//}}}
+
+//{{{ inline functions corresponding to CanonicalForm methods
+//{{{ docu
+//
+// - inline functions corresponding to CanonicalForm methods.
+//
+// These function exist for convenience only and because it is
+// more beautiful to write 'degree( f )' than 'f.degree()'.
+//
+//}}}
+inline CanonicalForm
+lc ( const CanonicalForm & f ) { return f.lc(); }
+
+inline CanonicalForm
+Lc ( const CanonicalForm & f ) { return f.Lc(); }
+
+inline CanonicalForm
+LC ( const CanonicalForm & f ) { return f.LC(); }
+
+inline CanonicalForm
+LC ( const CanonicalForm & f, const Variable & v ) { return f.LC( v ); }
+
+inline int
+degree ( const CanonicalForm & f ) { return f.degree(); }
+
+inline int
+degree ( const CanonicalForm & f, const Variable & v ) { return f.degree( v ); }
+
+inline int
+taildegree ( const CanonicalForm & f ) { return f.taildegree(); }
+
+inline CanonicalForm
+tailcoeff ( const CanonicalForm & f ) { return f.tailcoeff(); }
+
+inline CanonicalForm
+tailcoeff (const CanonicalForm& f, const Variable& v) { return f.tailcoeff(v); }
+
+inline int
+level ( const CanonicalForm & f ) { return f.level(); }
+
+inline Variable
+mvar ( const CanonicalForm & f ) { return f.mvar(); }
+
+inline CanonicalForm
+num ( const CanonicalForm & f ) { return f.num(); }
+
+inline CanonicalForm
+den ( const CanonicalForm & f ) { return f.den(); }
+
+inline int
+sign ( const CanonicalForm & a ) { return a.sign(); }
+
+inline CanonicalForm
+deriv ( const CanonicalForm & f, const Variable & x ) { return f.deriv( x ); }
+
+inline CanonicalForm
+sqrt ( const CanonicalForm & a ) { return a.sqrt(); }
+
+inline int
+ilog2 ( const CanonicalForm & a ) { return a.ilog2(); }
+
+inline CanonicalForm
+mapinto ( const CanonicalForm & f ) { return f.mapinto(); }
+//}}}
+
+//{{{ inline functions
+inline CanonicalForm
+head ( const CanonicalForm & f )
+{
+    if ( f.level() > 0 )
+        return power( f.mvar(), f.degree() ) * f.LC();
+    else
+        return f;
+}
+
+inline int
+headdegree ( const CanonicalForm & f ) { return totaldegree( head( f ) ); }
+
+
+//}}}
+
+//{{{ other function declarations
+void setCharacteristic( int c ); // -> Fp && Q
+void setCharacteristic( int c, int n ); // -> PrimePower
+void setCharacteristic( int c, int n, char name ); // -> GF(q)
+
+int getCharacteristic();
+int getGFDegree();
+CanonicalForm getGFGenerator();
+
+void On( int );
+void Off( int );
+bool isOn( int );
+//}}}
+
+//{{{ type definitions
+typedef AFactor<CanonicalForm> CFAFactor;
+typedef List <CFAFactor> CFAFList;
+typedef ListIterator<CFAFactor> CFAFListIterator;
+typedef Factor<CanonicalForm> CFFactor;
+typedef List<CFFactor> CFFList;
+typedef ListIterator<CFFactor> CFFListIterator;
+typedef List<CanonicalForm> CFList;
+typedef ListIterator<CanonicalForm> CFListIterator;
+typedef Array<CanonicalForm> CFArray;
+typedef Matrix<CanonicalForm> CFMatrix;
+typedef List<CFList> ListCFList;
+typedef ListIterator<CFList> ListCFListIterator ;
+typedef List<int> IntList;
+typedef ListIterator<int> IntListIterator;
+typedef List<Variable> Varlist;
+typedef ListIterator<Variable> VarlistIterator;
+typedef Array<int> Intarray;
+//}}}
+
+/*ENDPUBLIC*/
+
+#endif /* ! INCL_CANONICALFORM_H */
diff --git a/factory/cfCharSets.cc b/factory/cfCharSets.cc
new file mode 100644
index 0000000..7ea4d88
--- /dev/null
+++ b/factory/cfCharSets.cc
@@ -0,0 +1,694 @@
+/*****************************************************************************\
+ * Computer Algebra System SINGULAR
+\*****************************************************************************/
+/** @file cfCharSets.cc
+ *
+ * This file provides functions to compute characteristic sets
+ *
+ * @note some of the code is code from libfac or derived from code from libfac.
+ * Libfac is written by M. Messollen. See also COPYING for license information
+ * and README for general information on characteristic sets.
+ *
+ * ABSTRACT: Descriptions can be found in Wang "On the Parallelization of
+ * characteristic-set based algorithms" or Greuel/Pfister "A Singular
+ * Introduction to Commutative Algebra".
+ *
+ * @authors Martin Lee
+ *
+ **/
+/*****************************************************************************/
+
+#include "config.h"
+
+#include "timing.h"
+
+#include "canonicalform.h"
+#include "cfCharSets.h"
+#include "cfCharSetsUtil.h"
+#include "cf_algorithm.h"
+#include "facAlgFunc.h"
+
+TIMING_DEFINE_PRINT(neworder_time)
+
+// set up a new orderd list of Variables.
+// we try to reorder the variables heuristically optimal.
+Varlist
+neworder (const CFList & PolyList)
+{
+  CFList PS= PolyList, PS1=PolyList;
+  Varlist oldorder, reorder, difference;
+
+  TIMING_START (neworder_time);
+
+  int highest_level= level (get_max_var (PS));
+
+  // set up oldorder and first criterion: only_in_one
+  for (int i= highest_level; i>=1; i--)
+  {
+    oldorder.insert (Variable (i));
+    CFList is_one= only_in_one (PS1, Variable (i));
+    if (is_one.length() == 1)
+    {
+      reorder.insert (Variable (i));
+      PS1= Difference (PS1, is_one);
+    }
+    else if (is_one.length() == 0)
+    {
+      reorder.append (Variable (i)); // assigne it the highest level
+      PS1= Difference (PS1, is_one);
+    }
+  }
+  difference= Difference (oldorder, reorder);
+
+  // rearrange the ordering of the variables!
+  difference= reorderb (difference, PS, highest_level);
+  reorder= Union (reorder, difference);
+  TIMING_END(neworder_time);
+
+  TIMING_PRINT(neworder_time, "\ntime used for neworder   : ");
+
+  return Union (reorder, Difference (oldorder, reorder));
+}
+
+// the same as above, only returning a list of CanonicalForms
+CFList
+newordercf (const CFList & PolyList)
+{
+  Varlist reorder= neworder (PolyList);
+  CFList output;
+
+  for (VarlistIterator i=reorder; i.hasItem(); i++)
+    output.append (CanonicalForm (i.getItem()));
+
+  return output;
+}
+
+// the same as above, only returning a list of ints
+IntList
+neworderint (const CFList & PolyList)
+{
+  Varlist reorder= neworder (PolyList);
+  IntList output;
+
+  for (VarlistIterator i= reorder; i.hasItem(); i++)
+    output.append (level (i.getItem()));
+
+  return output;
+}
+
+// a library function: we reorganize the global variable ordering
+CFList
+reorder (const Varlist & betterorder, const CFList & PS)
+{
+  int i= 1, n= betterorder.length();
+  Intarray v (1, n);
+  CFList ps= PS;
+
+  //initalize:
+  for (VarlistIterator j= betterorder; j.hasItem(); j++)
+  {
+    v[i]= level (j.getItem());
+    i++;
+  }
+  // reorder:
+  for (i= 1; i <= n; i++)
+    ps= swapvar (ps, Variable (v[i]), Variable (n + i));
+  return ps;
+}
+
+CFFList
+reorder (const Varlist & betterorder, const CFFList & PS)
+{
+  int i= 1, n= betterorder.length();
+  Intarray v (1, n);
+  CFFList ps= PS;
+
+  //initalize:
+  for (VarlistIterator j= betterorder; j.hasItem(); j++)
+  {
+    v[i]= level (j.getItem());
+    i++;
+  }
+
+  // reorder:
+  for (i= 1; i <= n; i++)
+    ps= swapvar (ps, Variable (v[i]), Variable (n + i));
+  return ps;
+}
+
+ListCFList
+reorder (const Varlist & betterorder, const ListCFList & Q)
+{
+  ListCFList Q1;
+
+  for (ListCFListIterator i= Q; i.hasItem(); i++)
+    Q1.append (reorder (betterorder, i.getItem()));
+  return Q1;
+}
+
+CFList
+basicSet (const CFList &PS)
+{
+  CFList QS= PS, BS, RS;
+  CanonicalForm b;
+  int cb, degb;
+
+  if (PS.length() < 2)
+    return PS;
+
+  CFListIterator i;
+
+  while (!QS.isEmpty())
+  {
+    b= lowestRank (QS);
+    cb= b.level();
+
+    BS= Union(CFList (b), BS);
+
+    if (cb <= 0)
+      return CFList();
+    else
+    {
+      degb= degree (b);
+      RS= CFList();
+      for (i= QS; i.hasItem(); i++)
+      {
+        if (degree (i.getItem(), cb) < degb)
+          RS= Union (CFList (i.getItem()), RS);
+      }
+      QS= RS;
+    }
+  }
+
+  return BS;
+}
+
+CFList
+charSet (const CFList &PS)
+{
+  CFList QS= PS, RS= PS, CSet, tmp;
+  CFListIterator i;
+  CanonicalForm r;
+
+  while (!RS.isEmpty())
+  {
+    CSet= basicSet (QS);
+
+    RS= CFList();
+    if (CSet.length() > 0 && CSet.getFirst().level() > 0)
+    {
+      tmp= Difference (QS, CSet);
+      for (i= tmp; i.hasItem(); i++)
+      {
+        r= Prem (i.getItem(), CSet);
+        if (r != 0)
+          RS= Union (RS, CFList (r));
+      }
+      QS= Union (QS, RS);
+    }
+  }
+
+  return CSet;
+}
+
+/// medial set
+CFList
+charSetN (const CFList &PS)
+{
+  CFList QS= PS, RS= PS, CSet, tmp;
+  CFListIterator i;
+  CanonicalForm r;
+
+  while (!RS.isEmpty())
+  {
+    QS= uniGcd (QS);
+    CSet= basicSet (QS);
+
+    RS= CFList();
+    if (CSet.length() > 0 && CSet.getFirst().level() > 0)
+    {
+      tmp= Difference (QS, CSet);
+      for (i= tmp; i.hasItem(); i++)
+      {
+        r= Prem (i.getItem(), CSet);
+        if (!r.isZero())
+          RS= Union (RS, CFList (r));
+      }
+      QS= Union (CSet, RS);
+    }
+  }
+
+  return CSet;
+}
+
+/// compute a characteristic set via medial set
+CFList
+charSetViaCharSetN (const CFList& PS)
+{
+  CFList L;
+  CFFList sqrfFactors;
+  CanonicalForm sqrf;
+  CFFListIterator iter2;
+  for (CFListIterator iter= PS; iter.hasItem(); iter++)
+  {
+    sqrf= 1;
+    sqrfFactors= sqrFree (iter.getItem());
+    for (iter2= sqrfFactors; iter2.hasItem(); iter2++)
+      sqrf *= iter2.getItem().factor();
+    L= Union (L, CFList (normalize (sqrf)));
+  }
+
+  CFList result= charSetN (L);
+
+  if (result.isEmpty() || result.getFirst().inCoeffDomain())
+    return CFList(1);
+
+  CanonicalForm r;
+  CFList RS;
+  CFList tmp= Difference (L, result);
+
+  for (CFListIterator i= tmp; i.hasItem(); i++)
+  {
+    r= Premb (i.getItem(), result);
+    if (!r.isZero())
+      RS= Union (RS, CFList (r));
+  }
+  if (RS.isEmpty())
+    return result;
+
+  return charSetViaCharSetN (Union (L, Union (RS, result)));
+}
+
+/// modified medial set
+CFList
+modCharSet (const CFList& L, StoreFactors& StoredFactors, bool removeContents)
+{
+  CFList QS, RS= L, CSet, tmp, contents, initial, removedFactors;
+  CFListIterator i;
+  CanonicalForm r, cF;
+  bool noRemainder= true;
+  StoreFactors StoredFactors2;
+
+  QS= uniGcd (L);
+
+  while (!RS.isEmpty())
+  {
+    noRemainder= true;
+    CSet= basicSet (QS);
+
+    initial= factorsOfInitials (CSet);
+
+    StoredFactors2.FS1= StoredFactors.FS1;
+    StoredFactors2.FS2= Union (StoredFactors2.FS2, initial);
+
+    RS= CFList();
+
+    if (CSet.length() > 0 && CSet.getFirst().level() > 0)
+    {
+      tmp= Difference (QS, CSet);
+
+      for (i= tmp; i.hasItem(); i++)
+      {
+        r= Prem (i.getItem(), CSet);
+        if (!r.isZero())
+        {
+          noRemainder= false;
+          if (removeContents)
+          {
+            removeContent (r, cF);
+
+            if (!cF.isZero())
+              contents= Union (contents, factorPSet (CFList(cF))); //factorPSet maybe too much it should suffice to do a squarefree factorization instead
+          }
+
+          removeFactors (r, StoredFactors2, removedFactors);
+          StoredFactors2.FS1= Union (StoredFactors2.FS1, removedFactors);
+          StoredFactors2.FS2= Difference (StoredFactors2.FS2, removedFactors);
+
+          removedFactors= CFList();
+
+          RS= Union (RS, CFList (r));
+        }
+      }
+
+      if (removeContents && !noRemainder)
+      {
+        StoredFactors.FS1= Union (StoredFactors2.FS1, contents);
+        StoredFactors.FS2= StoredFactors2.FS2;
+      }
+      else
+        StoredFactors= StoredFactors2;
+
+      QS= Union (CSet, RS);
+
+      contents= CFList();
+      removedFactors= CFList();
+    }
+    else
+      StoredFactors= StoredFactors2;
+  }
+
+  return CSet;
+}
+
+/// characteristic set via modified medial set
+CFList
+charSetViaModCharSet (const CFList& PS, StoreFactors& StoredFactors,
+                      bool removeContents)
+{
+  CFList L;
+  CFFList sqrfFactors;
+  CanonicalForm sqrf;
+  CFFListIterator iter2;
+  for (CFListIterator iter= PS; iter.hasItem(); iter++)
+  {
+    sqrf= 1;
+    sqrfFactors= sqrFree (iter.getItem());
+    for (iter2= sqrfFactors; iter2.hasItem(); iter2++)
+      sqrf *= iter2.getItem().factor();
+    L= Union (L, CFList (normalize (sqrf)));
+  }
+
+  L= uniGcd (L);
+
+  CFList result= modCharSet (L, StoredFactors, removeContents);
+
+  if (result.isEmpty() || result.getFirst().inCoeffDomain())
+    return CFList(1);
+
+  CanonicalForm r;
+  CFList RS;
+  CFList tmp= Difference (L, result);
+
+  for (CFListIterator i= tmp; i.hasItem(); i++)
+  {
+    r= Premb (i.getItem(), result);
+    if (!r.isZero())
+      RS= Union (RS, CFList (r));
+  }
+  if (RS.isEmpty())
+    return result;
+
+  return charSetViaModCharSet (Union (L, Union (RS, result)), StoredFactors,
+                               removeContents);
+}
+
+CFList
+charSetViaModCharSet (const CFList& PS, bool removeContents)
+{
+  StoreFactors tmp;
+  return charSetViaModCharSet (PS, tmp, removeContents);
+}
+
+CFList
+modCharSet (const CFList& PS, bool removeContents)
+{
+  StoreFactors tmp;
+  return modCharSet (PS, tmp, removeContents);
+}
+
+ListCFList
+charSeries (const CFList& L)
+{
+  ListCFList tmp, result, tmp2, ppi1, ppi2, qqi, ppi, alreadyConsidered;
+  CFList l, charset, ini;
+
+  int count= 0;
+  int highestLevel= 1;
+  CFListIterator iter;
+
+  StoreFactors StoredFactors;
+
+  l= L;
+
+  for (iter= l; iter.hasItem(); iter++)
+  {
+    iter.getItem()= normalize (iter.getItem());
+    if (highestLevel < iter.getItem().level())
+      highestLevel= iter.getItem().level();
+  }
+
+  tmp= ListCFList (l);
+
+  while (!tmp.isEmpty())
+  {
+    sortListCFList (tmp);
+
+    l= tmp.getFirst();
+
+    tmp= Difference (tmp, l);
+
+    select (ppi, l.length(), ppi1, ppi2);
+
+    inplaceUnion (ppi2, qqi);
+
+    if (count > 0)
+      ppi= Union (ppi1, ListCFList (l));
+    else
+      ppi= ListCFList();
+
+    if (l.length() - 3 < highestLevel)
+      charset= charSetViaModCharSet (l, StoredFactors);
+    else
+      charset= charSetViaCharSetN (l);
+
+    if (charset.length() > 0 && charset.getFirst().level() > 0)
+    {
+      result= Union (ListCFList (charset), result);
+      ini= factorsOfInitials (charset);
+
+      ini= Union (ini, factorPSet (StoredFactors.FS1));
+      sortCFListByLevel (ini);
+    }
+    else
+    {
+      ini= factorPSet (StoredFactors.FS1);
+      sortCFListByLevel (ini);
+    }
+
+    tmp2= adjoin (ini, l, qqi);
+    tmp= Union (tmp2, tmp);
+
+    StoredFactors.FS1= CFList();
+    StoredFactors.FS2= CFList();
+
+    ppi1= ListCFList();
+    ppi2= ListCFList();
+
+    count++;
+  }
+
+  //TODO need to remove superflous components
+
+  return result;
+}
+
+static bool
+irreducible (const CFList & AS)
+{
+// AS is given by AS = { A1, A2, .. Ar }, d_i = degree(Ai)
+
+// 1) we test: if d_i > 1, d_j =1 for all j<>i, then AS is irreducible.
+  bool deg1= true;
+  for (CFListIterator i= AS ; i.hasItem(); i++)
+  {
+    if (degree (i.getItem()) > 1)
+    {
+      if (deg1)
+        deg1= false;
+      else
+        return false; // found 2nd poly with deg > 1
+    }
+  }
+  return true;
+}
+
+static CFList
+irredAS (CFList & AS, int & indexRed, CanonicalForm & reducible)
+{
+  CFFList qs;
+  CFList ts, as;
+  CanonicalForm elem;
+  bool ind= true;
+  int nr= 0;
+  CFListIterator i;
+
+  indexRed= 0;
+  for (i= AS; i.hasItem(); i++ )
+  {
+    nr += 1;
+    qs= factorize (i.getItem());
+    if (qs.getFirst().factor().inCoeffDomain())
+      qs.removeFirst();
+
+    if ((qs.length() >= 2 ) || (qs.getFirst().exp() > 1))
+    {
+      indexRed= nr;
+      ind= false;
+      reducible= i.getItem();
+      break;
+    }
+  }
+
+  if (ind)
+  {
+    if (irreducible (AS))  // as quasilinear? => irreducible!
+      indexRed= 0;
+    else
+    {
+      i= AS;
+      for (nr= 1; nr< AS.length(); nr++)
+      {
+        as.append (i.getItem());
+        i++;
+        if (degree (i.getItem()) > 1)
+        {  // search for a non linear elem
+          qs= facAlgFunc2 (i.getItem(), as);
+          if (qs.length() > 0)
+	  {
+	    if (qs.getFirst().factor().inCoeffDomain())
+              qs.removeFirst();
+            if (qs.length() > 1 || qs.getFirst().exp() > 1)
+            { //found elem is reducible
+              reducible= i.getItem();
+              indexRed= nr + 1;
+              break;
+            }
+	  }
+        }
+      }
+    }
+  }
+  for (CFFListIterator k= qs; k.hasItem(); k++)
+    ts.append (normalize (k.getItem().factor()));
+  return ts;
+}
+
+ListCFList
+irrCharSeries (const CFList & PS)
+{
+  CanonicalForm reducible, reducible2;
+  CFList qs, cs, factorset, is, ts, L;
+  CanonicalForm sqrf;
+  CFFList sqrfFactors;
+  CFFListIterator iter2;
+  for (CFListIterator iter= PS; iter.hasItem(); iter++)
+  {
+    sqrf= 1;
+    sqrfFactors= sqrFree (iter.getItem());
+    if (sqrfFactors.getFirst().factor().inCoeffDomain())
+      sqrfFactors.removeFirst();
+    for (iter2= sqrfFactors; iter2.hasItem(); iter2++)
+      sqrf *= iter2.getItem().factor();
+    sqrf= normalize (sqrf);
+    L= Union (CFList (sqrf), L);
+  }
+
+  ListCFList pi, ppi, qqi, qsi, iss, qhi= ListCFList(L);
+
+  int nr_of_iteration= 0, indexRed, highestlevel= 0;
+
+  for (CFListIterator iter= PS; iter.hasItem(); iter++)
+  {
+    if (level (iter.getItem()) > highestlevel)
+      highestlevel= level(iter.getItem());
+  }
+
+  while (!qhi.isEmpty())
+  {
+    sortListCFList (qhi);
+
+    qs= qhi.getFirst();
+
+    ListCFList ppi1,ppi2;
+    select (ppi, qs.length(), ppi1, ppi2);
+
+    inplaceUnion (ppi2, qqi);
+
+    if (nr_of_iteration == 0)
+    {
+      nr_of_iteration += 1;
+      ppi= ListCFList();
+    }
+    else
+    {
+      nr_of_iteration += 1;
+      ppi= Union (ppi1, ListCFList (qs));
+    }
+
+    StoreFactors StoredFactors;
+    if (qs.length() - 3 < highestlevel)
+      cs= modCharSet (qs, StoredFactors, false);
+    else
+      cs= charSetN (qs);
+    cs= removeContent (cs, StoredFactors);
+
+    factorset= StoredFactors.FS1;
+
+    if (!cs.isEmpty() && cs.getFirst().level() > 0)
+    {
+      ts= irredAS (cs, indexRed, reducible);
+
+      if (indexRed <= 0) // irreducible
+      {
+        if (!isSubset (cs,qs))
+          cs= charSetViaCharSetN (Union (qs,cs));
+        if (!find (pi, cs))
+        {
+          pi= Union (ListCFList (cs), pi);
+          if (cs.getFirst().level() > 0)
+          {
+            ts= irredAS (cs, indexRed, reducible);
+
+            if (indexRed <= 0) //irreducible
+            {
+              qsi= Union (ListCFList(cs), qsi);
+              if (cs.length() == highestlevel)
+                is= factorPSet (factorset);
+              else
+                is= Union (factorsOfInitials (cs), factorPSet (factorset));
+              iss= adjoin (is, qs, qqi);
+            }
+          }
+          else
+            iss= adjoin (factorPSet (factorset), qs, qqi);
+        }
+        else
+          iss= adjoin (factorPSet (factorset), qs, qqi);
+      }
+
+      if (indexRed > 0)
+      {
+        is= factorPSet (factorset);
+        if (indexRed > 1)
+        {
+          CFList cst;
+          for (CFListIterator i= cs ; i.hasItem(); i++)
+          {
+            if (i.getItem() == reducible)
+              break;
+            else
+              cst.append (i.getItem());
+          }
+          is= Union (factorsOfInitials (Union (cst,  CFList (reducible))), is);
+          iss= Union (adjoinb (ts, qs, qqi, cst), adjoin (is, qs, qqi));
+        }
+        else
+          iss= adjoin (Union (is, ts), qs, qqi);
+      }
+    }
+    else
+      iss= adjoin (factorPSet (factorset), qs, qqi);
+    if (qhi.length() > 1)
+    {
+      qhi.removeFirst();
+      qhi= Union (iss, qhi);
+    }
+    else
+      qhi= iss;
+  }
+  if (!qsi.isEmpty())
+    return contract (qsi);
+  return ListCFList(CFList (1)) ;
+}
+
diff --git a/factory/cfCharSets.h b/factory/cfCharSets.h
new file mode 100644
index 0000000..34c69c0
--- /dev/null
+++ b/factory/cfCharSets.h
@@ -0,0 +1,103 @@
+/*****************************************************************************\
+ * Computer Algebra System SINGULAR
+\*****************************************************************************/
+/** @file cfCharSets.h
+ *
+ * This file provides functions to compute characteristic sets
+ *
+ * @note some of the code is code from libfac or derived from code from libfac.
+ * Libfac is written by M. Messollen. See also COPYING for license information
+ * and README for general information on characteristic sets.
+ *
+ * ABSTRACT: Descriptions can be found in Wang "On the Parallelization of
+ * characteristic-set based algorithms" or Greuel/Pfister "A Singular
+ * Introduction to Commutative Algebra".
+ *
+ * @author Martin Lee
+ *
+ **/
+/*****************************************************************************/
+
+#ifndef CF_CHARSETS
+#define CF_CHARSETS
+
+#include "cfCharSetsUtil.h"
+
+/*BEGINPUBLIC*/
+
+/// basic set in the sense of Wang a.k.a. minimal ascending set in the sense of
+/// Greuel/Pfister
+CFList
+basicSet (const CFList& PS);
+
+/// characteristic set
+CFList
+charSet (const CFList& PS);
+
+/// modified medial set
+CFList
+modCharSet (const CFList& PS, StoreFactors& StoredFactors,
+            bool removeContents= true);
+
+CFList
+modCharSet (const CFList& PS, bool removeContents);
+
+CFList
+charSetViaCharSetN (const CFList& PS);
+
+CFList
+charSetN (const CFList &PS);
+
+/// modified characteristic set, i.e. a characteristic set with certain
+/// factors removed
+CFList
+charSetViaModCharSet (const CFList& PS, StoreFactors& StoredFactors,
+                      bool removeContents= true);
+
+/// modified characteristic set, i.e. a characteristic set with certain
+/// factors removed
+CFList
+charSetViaModCharSet (const CFList& PS, bool removeContents= true);
+
+/// characteristic series
+ListCFList
+charSeries (const CFList& L);
+
+/// irreducible characteristic series
+ListCFList
+irrCharSeries (const CFList & PS);
+
+// the next three give you a heuristically optimal reorderd list of the
+// variables. For internal and external (e.g. Singular/Macaulay2) library use.
+// This is really experimental!
+// See the comments in reorder.cc.
+//
+// this gives you a heuristically optimal ordering for the ring variables
+// if you use the irreducible characteristic series.
+Varlist neworder (const CFList & PolyList);
+
+// the same as neworder(...) only returning a list of CanonicalForm 's
+// (i.e. the variables as CanonicalForms)
+CFList newordercf (const CFList & PolyList);
+
+// the same as neworder(...) only returning a list of int 's (i.e. the levels)
+IntList neworderint (const CFList & PolyList);
+
+// for library internal use only:
+// next function reorders the variables in PS:
+// a code segment to use:
+// ...
+// #include <tmpl_inst.h> // for typedef's
+// CFList PS= <setup-your-list-of-CanonicalForms>;
+// Varlist betterorder= neworder(PS);
+// PS= reorder(betterorder,PS); // reorder variables in PS from oldorder
+//                                 to betterorder
+// ListCFList Q= IrrCharSeries( PS );
+// Q= reorder(betterorder,Q);   // revert ordering to oldorder
+//
+CFList reorder (const Varlist & betterorder, const CFList & PS);
+CFFList reorder (const Varlist & betterorder, const CFFList & PS);
+ListCFList reorder (const Varlist & betterorder, const ListCFList & Q);
+/*ENDPUBLIC*/
+
+#endif
diff --git a/factory/cfCharSetsUtil.cc b/factory/cfCharSetsUtil.cc
new file mode 100644
index 0000000..5dc3d4f
--- /dev/null
+++ b/factory/cfCharSetsUtil.cc
@@ -0,0 +1,964 @@
+/*****************************************************************************\
+ * Computer Algebra System SINGULAR
+\*****************************************************************************/
+/** @file cfCharSetsUtil.cc
+ *
+ * This file provides utility functions to compute characteristic sets
+ *
+ * @note some of the code is code from libfac or derived from code from libfac.
+ * Libfac is written by M. Messollen. See also COPYING for license information
+ * and README for general information on characteristic sets.
+ *
+ * @authors Martin Lee
+ *
+ **/
+/*****************************************************************************/
+
+#include "config.h"
+
+#include "canonicalform.h"
+#include "cf_algorithm.h"
+#include "cfCharSetsUtil.h"
+
+#define __ARRAY_INIT__ -1
+
+// the maximal degree of polys in PS wrt. variable x
+int
+degpsmax (const CFList & PS, const Variable & x,
+          Intarray & A, Intarray & C)
+{
+  int varlevel= level(x);
+  if (A[varlevel] != __ARRAY_INIT__)
+    return A[varlevel];
+  int max= 0, temp, count= 0;
+
+  for (CFListIterator i= PS; i.hasItem(); i++)
+  {
+    temp= degree (i.getItem(), x);
+    if (temp > max)
+    {
+      max= temp;
+      count = 0;
+    }
+    if (temp == max)
+      count += max;  // we count the number of polys
+  }
+  A[varlevel]= max;
+  C[varlevel]= count;
+  return max;
+}
+
+// the minimal non-zero degree of polys in PS wrt. x
+// returns 0 if variable x doesn't occure in any of the polys
+int
+degpsmin (const CFList & PS, const Variable & x, Intarray & A, Intarray & B,
+          Intarray & C, Intarray & D)
+{
+  int varlevel= level(x);
+  if (B[varlevel] != __ARRAY_INIT__ )
+    return B[varlevel];
+  int min= degpsmax (PS, x, A, C), temp, count= 0;
+
+  if (min == 0)
+  {
+    B[varlevel]= min;
+    D[varlevel]= min;
+    return min;
+  }
+  else
+  {
+    for (CFListIterator i= PS; i.hasItem(); i++)
+    {
+      temp= degree (i.getItem(), x);
+      if (temp < min && temp != 0)
+      {
+        min= temp;
+        count= 0;
+      }
+      if (temp == min)
+        count += min; // we count the number of polys
+    }
+  }
+  B[varlevel]= min;
+  D[varlevel]= count;
+  return min;
+}
+
+// the minimal total degree of lcoeffs of polys in PS wrt. x
+// for those polys having degree degpsmin in x.
+// F will be assigned the minimal number of terms of those lcoeffs
+int
+Tdeg (const CFList & PS, const Variable & x, Intarray & A, Intarray & B,
+      Intarray & C, Intarray & D, Intarray & E, Intarray & F)
+{
+  int k= degpsmin (PS, x, A, B, C, D), varlevel= level(x), min= 0;
+
+  if (E[varlevel] != __ARRAY_INIT__)
+    return E [varlevel];
+  if (k == 0)
+  {
+    E[varlevel]= 0;
+    F[varlevel]= 0;
+  }
+  else
+  {
+    int nopslc= 0;
+    CFList LCdegList;
+    CanonicalForm elem;
+    CFListIterator i;
+
+    for (i= PS; i.hasItem(); i++)
+    {
+      elem= i.getItem();
+      if (degree (elem, x) == k)
+        LCdegList.append (LC (elem, x));
+    }
+
+    if (LCdegList.length() > 0)
+    {
+      CFList TermList;
+      int newmin, newnopslc;
+
+      min= totaldegree (LCdegList.getFirst());
+      TermList= get_Terms (LCdegList.getFirst());
+      nopslc= TermList.length();
+      for (i= LCdegList; i.hasItem(); i++)
+      {
+        elem= i.getItem();
+        newmin= totaldegree(elem);
+        TermList= get_Terms(elem);
+        newnopslc= TermList.length();
+        if (newmin < min)
+          min= newmin;
+        if (newnopslc < nopslc)
+          nopslc= newnopslc;
+      }
+
+    }
+    E[varlevel]= min;
+    F[varlevel]= nopslc;
+  }
+  return min;
+}
+
+// The number of the poly in which Variable x first occures
+int
+nr_of_poly( const CFList & PS, const Variable & x, Intarray & G)
+{
+  int min= 0, varlevel= level(x);
+  if (G[varlevel] != __ARRAY_INIT__)
+    return G[varlevel];
+  for (CFListIterator i= PS; i.hasItem(); i++)
+  {
+    min += 1;
+    if (degree (i.getItem(), x) > 0)
+      break;
+  }
+  G[varlevel]= min;
+  return min;
+}
+
+int
+degord (const Variable & x, const Variable & y, const CFList & PS,
+        Intarray & A, Intarray & B, Intarray & C, Intarray & D,
+        Intarray & E, Intarray & F, Intarray & G)
+{
+  int xlevel= level(x), ylevel= level(y);
+
+  if      (degpsmax(PS,y,A,C) < degpsmax(PS,x,A,C))         return 1;
+  else if (degpsmax(PS,x,A,C) < degpsmax(PS,y,A,C) )        return 0;
+  else if (C[ylevel] < C[xlevel])                           return 1;
+  else if (C[xlevel] < C[ylevel])                           return 0;
+  else if (degpsmin(PS,x,A,B,C,D) < degpsmin(PS,y,A,B,C,D)) return 1;
+  else if (degpsmin(PS,y,A,B,C,D) < degpsmin(PS,x,A,B,C,D)) return 0;
+  else if (D[ylevel] < D[xlevel])                           return 1;
+  else if (D[xlevel] < D[ylevel])                           return 0;
+  else if (Tdeg(PS,y,A,B,C,D,E,F) < Tdeg(PS,x,A,B,C,D,E,F)) return 1;
+  else if (Tdeg(PS,x,A,B,C,D,E,F) < Tdeg(PS,y,A,B,C,D,E,F)) return 0;
+  else if (F[ylevel] < F[xlevel])                           return 1;
+  else if (F[xlevel] < F[ylevel])                           return 0;
+  else if (nr_of_poly(PS,x,G) <= nr_of_poly(PS,y,G))        return 1;
+  else return 0;
+}
+
+// determine the highest variable of all involved Variables in PS
+// NOTE:
+//    this doesn't give always the correct answer:
+//    If a variable is assigned the highest level in the definition of the
+//    original ring, but doesn't occure in any of the
+//    polynomials, get_max_var returns the variable with a level lower than
+//    the highest level.
+//    Is there a workaround?
+// But for the redefinition of the ring this doesn't matter due to the
+// implementation of neworder().
+
+Variable
+get_max_var (const CFList & PS)
+{
+  Variable x= PS.getFirst().mvar(), y;
+  for (CFListIterator i= PS; i.hasItem(); i++)
+  {
+    y= i.getItem().mvar();
+    if (y > x)
+      x= y;
+  }
+  return x;
+}
+
+
+// determine if variable x is in one and only one of the polynomials in PS
+// first criterion for neworder
+CFList
+only_in_one (const CFList & PS, const Variable & x)
+{
+  CFList output;
+
+  for (CFListIterator i= PS; i.hasItem(); i++ )
+  {
+    if (degree (i.getItem(), x) >= 1)
+      output.insert (i.getItem());
+    if (output.length() >= 2)
+      break;
+  }
+  return output;
+}
+
+// initialize all Arrays (of same range) with __ARRAY_INIT__
+void
+initArray (const int highest_level, Intarray & A, Intarray & B, Intarray & C,
+           Intarray & D, Intarray & E, Intarray & F, Intarray & G)
+{
+  for (int i=1 ; i <= highest_level; i ++)
+  {
+    A[i]= __ARRAY_INIT__;
+    B[i]= __ARRAY_INIT__;
+    C[i]= __ARRAY_INIT__;
+    D[i]= __ARRAY_INIT__;
+    E[i]= __ARRAY_INIT__;
+    F[i]= __ARRAY_INIT__;
+    G[i]= __ARRAY_INIT__;
+  }
+}
+
+// now for the second criterion; a little more complex
+//
+// idea: set up seven arrays of lenth highest_level
+//       (of which some entries may be empty, because of only_in_one!)
+//   A saves maxdegree of Variable x in A(level(x))
+//   B saves mindegree of Variable x in B(level(x))
+//   C saves the number of polys in PS which have degree A(level(x)) in
+//     D(level(x))
+//   D saves the number of polys in PS which have degree B(level(x)) in
+//     D(level(x))
+//   E saves the minimal total degree of lcoeffs of polys wrt x in E(level(x))
+//   F saves the minimal number of terms of lcoeffs of E(level(x)) in F(~)
+//   G saves nr of poly Variable x has first deg <> 0
+
+#define __INIT_GAP__ 3
+Varlist
+reorderb (const Varlist & difference, const CFList & PS,
+          const int highest_level)
+{
+  Intarray A(1, highest_level), B(1, highest_level), C(1, highest_level),
+           D(1, highest_level), E(1, highest_level), F(1, highest_level),
+           G(1, highest_level);
+  initArray (highest_level, A, B, C, D, E, F, G);
+  int i= 0, j, n= difference.length(), gap= 1 + __INIT_GAP__;
+  Variable temp;
+  Array<Variable> v(0, n);
+  VarlistIterator J;
+
+  for (J= difference; J.hasItem(); J++ )
+  {
+    v[i]= J.getItem();
+    i++;
+  }
+
+  while (gap <= n)
+    gap = __INIT_GAP__ * gap + 1;
+  gap /= __INIT_GAP__;
+
+  while (gap > 0)
+  {
+    for (i= gap; i <= n - 1; i++)
+    {
+      temp= v[i];
+      for (j= i - gap; j >=0 ; j -= gap)
+      {
+        if (degord (v[j], temp, PS, A, B, C, D, E, F, G))
+          break;
+        v[j + gap]= v[j];
+      }
+      v[j + gap]= temp;
+    }
+    gap /= __INIT_GAP__;
+  }
+  Varlist output;
+  for (i= 0; i <= n - 1; i++)
+    output.append (v[i]);
+  return output;
+}
+
+/// swapvar a whole list of CanonicalForms
+CFList
+swapvar (const CFList & PS, const Variable & x, const Variable & y)
+{
+  CFList ps;
+
+  for (CFListIterator i= PS; i.hasItem(); i++)
+    ps.append (swapvar (i.getItem(), x, y));
+  return ps;
+}
+
+CFFList
+swapvar (const CFFList & PS, const Variable & x, const Variable & y)
+{
+  CFFList ps;
+
+  for (CFFListIterator i= PS; i.hasItem(); i++)
+    ps.append (CFFactor (swapvar (i.getItem().factor(), x, y),
+                         i.getItem().exp()));
+  return ps;
+}
+
+bool
+lowerRank (const CanonicalForm & F, const CanonicalForm & G, int & ind)
+{
+  int degF, degG, levelF, levelG;
+
+  levelF= F.level();
+  levelG= G.level();
+  if (F.inCoeffDomain())
+  {
+    if (G.inCoeffDomain())
+      ind= 1;
+    return true;
+  }
+  else if (G.inCoeffDomain())
+    return false;
+  else if (levelF < levelG)
+    return true;
+  else if (levelF == levelG)
+  {
+    degF= degree(F);
+    degG= degree(G);
+    if (degF < degG)
+      return true;
+    else if (degF == degG)
+      return lowerRank (LC (F), LC (G), ind);
+    else
+      return false;
+  }
+  return false;
+}
+
+
+CanonicalForm
+lowestRank (const CFList & L)
+{
+  CFListIterator i= L;
+  CanonicalForm f;
+  int ind= 0;
+  if (!i.hasItem())
+    return f;
+
+  f= i.getItem();
+  i++;
+
+  while (i.hasItem())
+  {
+    if (lowerRank (i.getItem(), f, ind))
+    {
+      if (ind)
+      {
+        if (size (i.getItem()) < size (f))
+          f= i.getItem();
+        ind= 0;
+      }
+      else
+        f= i.getItem();
+    }
+    i++;
+  }
+  return f;
+}
+
+int minLevel (const CFList& L)
+{
+  if (L.isEmpty())
+    return 0;
+  int min= size (L.getFirst());
+  return min;
+}
+
+/// sort in descending order of length of elements
+void
+sortListCFList (ListCFList& list)
+{
+  int l= 1;
+  int k= 1;
+  CFList buf;
+  ListCFListIterator m;
+  for (ListCFListIterator i= list; l <= list.length(); i++, l++)
+  {
+    for (ListCFListIterator j= list; k <= list.length() - l; k++)
+    {
+      m= j;
+      m++;
+      if ((j.getItem().length() < m.getItem().length()) ||
+          (j.getItem().length() == m.getItem().length() &&
+           minLevel (j.getItem()) > minLevel (m.getItem())))
+      {
+        buf= m.getItem();
+        m.getItem()= j.getItem();
+        j.getItem()= buf;
+        j++;
+        j.getItem()= m.getItem();
+      }
+      else
+        j++;
+    }
+    k= 1;
+  }
+}
+
+
+/// sort in descending order of level of elements
+void
+sortCFListByLevel (CFList& list)
+{
+  int l= 1;
+  int k= 1;
+  CanonicalForm buf;
+  CFListIterator m;
+  for (CFListIterator i= list; l <= list.length(); i++, l++)
+  {
+    for (CFListIterator j= list; k <= list.length() - l; k++)
+    {
+      m= j;
+      m++;
+      if ((size (j.getItem()) < size (m.getItem())) ||
+          ((size (j.getItem()) == size (m.getItem()))
+            && (j.getItem().level() < m.getItem().level())))
+      {
+        buf= m.getItem();
+        m.getItem()= j.getItem();
+        j.getItem()= buf;
+        j++;
+        j.getItem()= m.getItem();
+      }
+      else
+        j++;
+    }
+    k= 1;
+  }
+}
+
+
+/* basic operations on lists */
+/// is PS a subset of Cset ?
+bool
+isSubset (const CFList &PS, const CFList& Cset)
+{
+  for (CFListIterator i= PS; i.hasItem(); i++)
+  {
+    if (!find (Cset, i.getItem()))
+      return 0;
+  }
+  return 1;
+}
+
+/// Union of a and b stored in b
+void
+inplaceUnion (const ListCFList& a, ListCFList& b)
+{
+  if (a.isEmpty())
+    return;
+  if (b.isEmpty())
+  {
+    b= a;
+    return;
+  }
+
+  ListCFListIterator i;
+  CFList elem;
+
+  for (i= a; i.hasItem(); i++)
+  {
+    elem= i.getItem();
+    if ((!elem.isEmpty()) && (!find (b, elem)))
+      b.insert(elem);
+  }
+}
+
+ListCFList
+adjoin (const CFList& is, const CFList& qs, const ListCFList& qh)
+{
+  ListCFList iss, qhi;
+  ListCFListIterator j;
+  CFList iscopy, itt;
+  CFListIterator i;
+  int ind, length;
+
+  for (i= is; i.hasItem(); i++)
+  {
+    if (i.getItem().level() > 0)
+      iscopy= Union (CFList (i.getItem()), iscopy);
+  }
+  if (iscopy.isEmpty())
+    return iss;
+
+  qhi= Difference (qh, qs);
+  length= qhi.length();
+
+  for (i= iscopy; i.hasItem(); i++)
+  {
+    itt= Union (qs, CFList (i.getItem()));
+    ind= 0;
+    if (length > 0)
+    {
+      for (j= qhi; j.hasItem(); j++)
+      {
+        if (isSubset (j.getItem(), itt))
+          ind= 1;
+      }
+    }
+    if (ind == 0)
+      iss.append (itt);
+  }
+  return iss;
+}
+
+ListCFList
+adjoinb (const CFList & is, const CFList & qs, const ListCFList & qh,
+         const CFList & cs)
+{
+  ListCFList iss, qhi;
+  ListCFListIterator j;
+  CFList iscopy, itt;
+  CFListIterator i;
+  int ind, length;
+
+  for (i= is ; i.hasItem(); i++)
+  {
+    if (i.getItem().level() > 0)
+      iscopy= Union (CFList (i.getItem()), iscopy);
+  }
+  if (iscopy.isEmpty())
+    return iss;
+  qhi= Difference (qh, qs);
+  length= qhi.length();
+  for (i= iscopy; i.hasItem(); i++)
+  {
+    itt= Union (Union (qs, CFList (i.getItem())), cs);
+    ind= 0;
+    if (length > 0)
+    {
+      for (j= qhi; j.hasItem(); j++)
+      {
+        if (isSubset (j.getItem(), itt))
+          ind= 1;
+      }
+    }
+    if (ind == 0)
+      iss.append(itt);
+  }
+  return iss;
+}
+
+void
+select (const ListCFList& ppi, int length, ListCFList& ppi1, ListCFList& ppi2)
+{
+  CFList elem;
+  for (ListCFListIterator i= ppi; i.hasItem(); i++)
+  {
+    elem= i.getItem();
+    if (!elem.isEmpty())
+    {
+      if (length <= elem.length())
+        ppi2.append(elem);
+      else
+        ppi1.append(elem);
+    }
+  }
+}
+
+/* end basic operations on lists */
+
+/// normalize a poly, i.e. in char 0 clear denominators, remove integer content
+/// in char p divide by leading coeff
+CanonicalForm normalize (const CanonicalForm& F)
+{
+  if (F.isZero())
+    return F;
+  if (getCharacteristic() == 0)
+  {
+    CanonicalForm G;
+    bool isRat= isOn (SW_RATIONAL);
+    if (!isRat)
+      On (SW_RATIONAL);
+    G= F;
+    G *= bCommonDen (G);
+    Off (SW_RATIONAL);
+    G /= icontent (G);
+    if (isRat)
+      On (SW_RATIONAL);
+    if (lc(G) < 0)
+      G= -G;
+    return G;
+  }
+
+  return F/lc (F);
+}
+
+/// pseudo remainder of F by G with certain factors of LC (g) cancelled
+CanonicalForm
+Prem (const CanonicalForm& F, const CanonicalForm& G)
+{
+  CanonicalForm f, g, l, test, lu, lv, t, retvalue;
+  int degF, degG, levelF, levelG;
+  bool reord;
+  Variable v, vg= G.mvar();
+
+  if ( (levelF= F.level()) < (levelG= G.level()))
+    return F;
+  else
+  {
+    if ( levelF == levelG )
+    {
+      f= F;
+      g= G;
+      reord= false;
+      v= F.mvar();
+    }
+    else
+    {
+      v= Variable (levelF + 1);
+      f= swapvar (F, vg, v);
+      g= swapvar (G, vg, v);
+      reord= true;
+    }
+    degG= degree (g, v );
+    degF= degree (f, v );
+    if (degG <= degF)
+    {
+      l= LC (g);
+      g= g - l*power (v, degG);
+    }
+    else
+      l= 1;
+    while ((degG <= degF) && (!f.isZero()))
+    {
+      test= gcd (l, LC(f));
+      lu= l / test;
+      lv= LC(f) / test;
+      t= g*lv*power (v, degF - degG);
+
+      if (degF == 0)
+        f= 0;
+      else
+        f= f - LC (f)*power (v, degF);
+
+      f= f*lu - t;
+      degF= degree (f, v);
+    }
+
+    if (reord)
+      retvalue= swapvar (f, vg, v);
+    else
+      retvalue= f;
+
+    return retvalue;
+  }
+}
+
+/// pseudo remainder of f by L with faster test for remainder being zero
+CanonicalForm
+Premb (const CanonicalForm &f, const CFList &L)
+{
+  CanonicalForm rem= f;
+  CFList l= L;
+  l.removeFirst();
+  CFListIterator i= l;
+
+  for (i.lastItem(); i.hasItem(); i--)
+    rem= normalize (Prem (rem, i.getItem()));
+
+  CanonicalForm tmp= L.getFirst()/content (L.getFirst());
+
+  bool isRat= isOn (SW_RATIONAL);
+  if (getCharacteristic() == 0 && !isRat)
+    On (SW_RATIONAL);
+  if (fdivides (tmp, rem))
+  {
+    if (getCharacteristic() == 0 && !isRat)
+      Off (SW_RATIONAL);
+    return 0;
+  }
+
+  if (getCharacteristic() == 0 && !isRat)
+    Off (SW_RATIONAL);
+
+  rem= normalize (Prem (rem, L.getFirst()));
+
+  return rem;
+}
+
+/// pseudo remainder of f by L
+CanonicalForm
+Prem (const CanonicalForm &f, const CFList &L)
+{
+  CanonicalForm rem= f;
+  CFListIterator i= L;
+
+  for (i.lastItem(); i.hasItem(); i--)
+    rem= normalize (Prem (rem, i.getItem()));
+
+  return rem;
+}
+
+CFList uniGcd (const CFList& L)
+{
+  CFList tmp;
+  CanonicalForm g;
+  CFListIterator i;
+  for (i= L; i.hasItem(); i++)
+  {
+    if (i.getItem().isUnivariate() && i.getItem().level() == 1)
+      tmp.append (i.getItem());
+  }
+  if (tmp.length() <= 2)
+    return L;
+  i= tmp;
+  g= i.getItem();
+  i++;
+  g= gcd (g,i.getItem());
+  i++;
+  for (; i.hasItem(); i++)
+    g= gcd (g, i.getItem());
+  return Union (Difference (L, tmp), CFList (g));
+}
+
+CFList initials (const CFList& L)
+{
+  CFList result;
+  for (CFListIterator iter= L; iter.hasItem(); iter++)
+  {
+    if (!LC(iter.getItem()).inCoeffDomain())
+      result.append (LC (iter.getItem()));
+  }
+  return result;
+}
+
+CFList
+factorsOfInitials(const CFList & L)
+{
+  CFList result;
+  CFFList factors;
+  CanonicalForm tmp;
+
+  for (CFListIterator i= L; i.hasItem(); i++)
+  {
+    factors= factorize (LC (i.getItem()));
+    for (CFFListIterator j= factors; j.hasItem(); j++)
+    {
+      tmp= j.getItem().factor();
+      if (!tmp.inCoeffDomain())
+        result= Union (result, CFList (normalize (tmp)));
+    }
+  }
+
+  return result;
+}
+
+void
+removeContent (CanonicalForm& F, CanonicalForm& cF)
+{
+  if (size (F) == 1)
+  {
+    CanonicalForm tmp= F;
+    F= F.mvar();
+    cF= tmp/F;
+    if (!cF.inCoeffDomain())
+      cF= normalize (cF);
+    else
+      cF= 0;
+    F= normalize (F);
+
+    return;
+  }
+
+  cF= content (F);
+
+  if (cF.inCoeffDomain())
+    cF= 0;
+  else
+  {
+    cF= normalize (cF);
+    F /= cF;
+    F= normalize (F);
+  }
+}
+
+CFList
+factorPSet (const CFList& PS)
+{
+  CFList result;
+  CFFList factors;
+  CFFListIterator j;
+
+  for (CFListIterator i= PS; i. hasItem(); i++)
+  {
+    factors= factorize (i.getItem());
+    if (factors.getFirst().factor().inCoeffDomain())
+      factors.removeFirst();
+    for (j= factors; j.hasItem(); j++ )
+      result= Union (result, CFList (normalize (j.getItem().factor())));
+  }
+  return result;
+}
+
+void
+removeFactors (CanonicalForm& r, StoreFactors& StoredFactors,
+               CFList& removedFactors)
+{
+  CanonicalForm quot;
+  CFList testlist;
+  int n= level(r);
+  bool divides;
+  CFListIterator j;
+
+  for (int i=1; i<= n; i++)
+    testlist.append (CanonicalForm (Variable (i)));
+
+  // remove already removed factors
+  for (j= StoredFactors.FS1; j.hasItem(); j++)
+  {
+    while (fdivides (j.getItem(), r, quot))
+    {
+      r= quot;
+    }
+  }
+
+  for (j= StoredFactors.FS2; j.hasItem(); j++)
+  {
+    divides= false;
+    if (j.getItem() != r)
+    {
+      while (fdivides (j.getItem(), r, quot))
+      {
+        divides= true;
+        r= quot;
+      }
+      if (divides)
+        removedFactors= Union (removedFactors, CFList (j.getItem()));
+    }
+  }
+  r= normalize (r);
+
+  // remove variables
+  for (j= testlist; j.hasItem() && !r.isOne(); j++)
+  {
+    divides= false;
+    if (j.getItem() != r)
+    {
+      while (fdivides (j.getItem(), r, quot))
+      {
+        divides= true;
+        r= quot;
+      }
+      if (divides)
+        removedFactors= Union (removedFactors, CFList (j.getItem()));
+     }
+  }
+  r= normalize (r);
+}
+
+CFList
+removeContent (const CFList & PS, StoreFactors & StoredFactors)
+{
+  CFListIterator i= PS;
+  if ((!i.hasItem()) || (PS.getFirst().level() == 0 ))
+    return PS;
+
+  CFList output;
+  CanonicalForm cc,elem;
+
+  for (; i.hasItem(); i++)
+  {
+    elem= i.getItem();
+    cc= content (elem, elem.mvar());
+    if (cc.level() > 0 )
+    {
+      output.append (normalize (elem / cc));
+      StoredFactors.FS1 = Union (CFList (normalize (cc)), StoredFactors.FS1);
+    }
+    else
+      output.append(normalize (elem));
+  }
+  return output;
+}
+
+bool
+contractsub (const CFList& cs1, const CFList& cs2)
+{
+  CFListIterator i;
+
+  CanonicalForm r;
+  for (i= cs1; i.hasItem(); i++)
+  {
+    if (Prem (i.getItem(), cs2) != 0)
+      return false;
+  }
+
+  CFList is= factorsOfInitials (cs1);
+
+  for (i= is; i.hasItem(); i++)
+  {
+    if (Prem (i.getItem(), cs2) == 0)
+      return false;
+  }
+  return true;
+}
+
+ListCFList
+contract (const ListCFList& cs)
+{
+  ListCFList mem, ts;
+  CFList iitem, jitem;
+
+  if (cs.length() < 2)
+    return cs;
+
+  int l= cs.length();
+  int ii= 1;
+  ListCFListIterator j;
+  for (ListCFListIterator i= cs; i.hasItem() && ii < l; i++, ii++)
+  {
+    iitem= i.getItem();
+    if (!find (mem, iitem))
+    {
+      j= i;
+      j++;
+      for (; j.hasItem(); j++)
+      {
+        jitem= j.getItem();
+        if (!find (mem, jitem))
+        {
+          if (contractsub (iitem, jitem))
+          {
+            ts.append (jitem);
+            mem.append (jitem);
+          }
+          else
+          {
+            if (contractsub (jitem, iitem))
+              ts.append (iitem); // no mem.append (item) because we assume cs does not contain duplicate entries
+          }
+        }
+      }
+    }
+  }
+  return Difference (cs,ts);
+}
+
diff --git a/factory/cfCharSetsUtil.h b/factory/cfCharSetsUtil.h
new file mode 100644
index 0000000..2962d94
--- /dev/null
+++ b/factory/cfCharSetsUtil.h
@@ -0,0 +1,120 @@
+/*****************************************************************************\
+ * Computer Algebra System SINGULAR
+\*****************************************************************************/
+/** @file cfCharSetsUtil.h
+ *
+ * This file provides utility functions to compute characteristic sets
+ *
+ * @note some of the code is code from libfac or derived from code from libfac.
+ * Libfac is written by M. Messollen. See also COPYING for license information
+ * and README for general information on characteristic sets.
+ *
+ * ABSTRACT: Descriptions can be found in Wang "On the Parallelization of
+ * characteristic-set based algorithms" or Greuel/Pfister "A Singular
+ * Introduction to Commutative Algebra".
+ *
+ * @author Martin Lee
+ *
+ **/
+/*****************************************************************************/
+
+#ifndef CF_CHARSETS_UTIL
+#define CF_CHARSETS_UTIL
+
+/*BEGINPUBLIC*/
+/**
+ * class to store factors that get removed during char set computation
+**/
+class StoreFactors
+{
+  public:
+    CFList FS1; ///< factors that were removed
+    CFList FS2; ///< candidate factors that might get removed
+    inline StoreFactors& operator= (const StoreFactors& value)
+    {
+      if ( this != &value )
+      {
+        FS1 = value.FS1;
+        FS2 = value.FS2;
+      }
+      return *this;
+    }
+};
+/*ENDPUBLIC*/
+
+Variable
+get_max_var (const CFList & PS);
+
+CFList
+only_in_one (const CFList & PS, const Variable & x);
+
+Varlist
+reorderb (const Varlist & difference, const CFList & PS,
+          const int highest_level);
+
+CFList
+swapvar (const CFList & PS, const Variable & x, const Variable & y);
+
+CFFList
+swapvar (const CFFList & PS, const Variable & x, const Variable & y);
+
+CanonicalForm
+lowestRank (const CFList & L);
+
+CFList initials (const CFList& L);
+
+void
+sortListCFList (ListCFList& list);
+
+void
+sortCFListByLevel (CFList& list);
+
+CanonicalForm
+Prem (const CanonicalForm& F, const CanonicalForm& G);
+
+CanonicalForm
+Premb (const CanonicalForm &f, const CFList &L);
+
+CanonicalForm
+Prem (const CanonicalForm &f, const CFList &L);
+
+CFList uniGcd (const CFList& L);
+
+CFList
+factorsOfInitials(const CFList & L);
+
+void
+removeContent (CanonicalForm& F, CanonicalForm& cF);
+
+CFList
+factorPSet (const CFList& PS);
+
+void
+removeFactors (CanonicalForm& r, StoreFactors& StoredFactors,
+               CFList& removedFactors);
+
+CFList
+removeContent (const CFList & PS, StoreFactors & StoredFactors);
+
+ListCFList
+contract (const ListCFList& cs);
+
+bool
+isSubset (const CFList &PS, const CFList& Cset);
+
+ListCFList
+adjoin (const CFList& is, const CFList& qs, const ListCFList& qh);
+
+ListCFList
+adjoinb (const CFList & is, const CFList & qs, const ListCFList & qh,
+         const CFList & cs);
+
+void
+inplaceUnion (const ListCFList& a, ListCFList& b);
+
+void
+select (const ListCFList& ppi, int length, ListCFList& ppi1, ListCFList& ppi2);
+
+CanonicalForm normalize (const CanonicalForm& F);
+
+#endif
diff --git a/factory/cfEzgcd.cc b/factory/cfEzgcd.cc
new file mode 100644
index 0000000..0f783d5
--- /dev/null
+++ b/factory/cfEzgcd.cc
@@ -0,0 +1,1396 @@
+/*****************************************************************************\
+ * Computer Algebra System SINGULAR
+\*****************************************************************************/
+/** @file cfEzgcd.cc
+ *
+ * This file implements the GCD of two multivariate polynomials over Q or F_q
+ * using EZ-GCD as described in "Algorithms for Computer Algebra" by Geddes,
+ * Czapor, Labahnn
+ *
+ * @author Martin Lee
+ *
+ **/
+/*****************************************************************************/
+
+
+#include "config.h"
+
+
+#include "timing.h"
+#include "cf_assert.h"
+#include "debug.h"
+
+#include "cf_defs.h"
+#include "canonicalform.h"
+#include "cfEzgcd.h"
+#include "cfModGcd.h"
+#include "cf_util.h"
+#include "cf_map_ext.h"
+#include "cf_algorithm.h"
+#include "cf_reval.h"
+#include "cf_random.h"
+#include "cf_primes.h"
+#include "templates/ftmpl_functions.h"
+#include "cf_map.h"
+#include "facHensel.h"
+
+#ifdef HAVE_NTL
+#include "NTLconvert.h"
+
+static const double log2exp= 1.442695041;
+
+TIMING_DEFINE_PRINT(ez_eval)
+TIMING_DEFINE_PRINT(ez_compress)
+TIMING_DEFINE_PRINT(ez_hensel_lift)
+TIMING_DEFINE_PRINT(ez_content)
+TIMING_DEFINE_PRINT(ez_termination)
+
+static
+int compress4EZGCD (const CanonicalForm& F, const CanonicalForm& G, CFMap & M,
+                    CFMap & N, int& both_non_zero)
+{
+  int n= tmax (F.level(), G.level());
+  int * degsf= new int [n + 1];
+  int * degsg= new int [n + 1];
+
+  for (int i = 0; i <= n; i++)
+    degsf[i]= degsg[i]= 0;
+
+  degsf= degrees (F, degsf);
+  degsg= degrees (G, degsg);
+
+  both_non_zero= 0;
+  int f_zero= 0;
+  int g_zero= 0;
+
+  for (int i= 1; i <= n; i++)
+  {
+    if (degsf[i] != 0 && degsg[i] != 0)
+    {
+      both_non_zero++;
+      continue;
+    }
+    if (degsf[i] == 0 && degsg[i] != 0 && i <= G.level())
+    {
+      f_zero++;
+      continue;
+    }
+    if (degsg[i] == 0 && degsf[i] && i <= F.level())
+    {
+      g_zero++;
+      continue;
+    }
+  }
+
+  if (both_non_zero == 0)
+  {
+    delete [] degsf;
+    delete [] degsg;
+    return 0;
+  }
+
+  // map Variables which do not occur in both polynomials to higher levels
+  int k= 1;
+  int l= 1;
+  for (int i= 1; i <= n; i++)
+  {
+    if (degsf[i] != 0 && degsg[i] == 0 && i <= F.level())
+    {
+      if (k + both_non_zero != i)
+      {
+        M.newpair (Variable (i), Variable (k + both_non_zero));
+        N.newpair (Variable (k + both_non_zero), Variable (i));
+      }
+      k++;
+    }
+    if (degsf[i] == 0 && degsg[i] != 0 && i <= G.level())
+    {
+      if (l + g_zero + both_non_zero != i)
+      {
+        M.newpair (Variable (i), Variable (l + g_zero + both_non_zero));
+        N.newpair (Variable (l + g_zero + both_non_zero), Variable (i));
+      }
+      l++;
+    }
+  }
+
+  // sort Variables x_{i} in decreasing order of
+  // min(deg_{x_{i}}(f),deg_{x_{i}}(g))
+  int m= tmin (F.level(), G.level());
+  int max_min_deg;
+  k= both_non_zero;
+  l= 0;
+  int i= 1;
+  while (k > 0)
+  {
+    max_min_deg= tmin (degsf[i], degsg[i]);
+    while (max_min_deg == 0)
+    {
+      i++;
+      max_min_deg= tmin (degsf[i], degsg[i]);
+    }
+    for (int j= i + 1; j <= m; j++)
+    {
+      if ((tmin (degsf[j],degsg[j]) < max_min_deg) &&
+          (tmin (degsf[j], degsg[j]) != 0))
+      {
+        max_min_deg= tmin (degsf[j], degsg[j]);
+        l= j;
+      }
+    }
+
+    if (l != 0)
+    {
+      if (l != k)
+      {
+        M.newpair (Variable (l), Variable(k));
+        N.newpair (Variable (k), Variable(l));
+        degsf[l]= 0;
+        degsg[l]= 0;
+        l= 0;
+      }
+      else
+      {
+        degsf[l]= 0;
+        degsg[l]= 0;
+        l= 0;
+      }
+    }
+    else if (l == 0)
+    {
+      if (i != k)
+      {
+        M.newpair (Variable (i), Variable (k));
+        N.newpair (Variable (k), Variable (i));
+        degsf[i]= 0;
+        degsg[i]= 0;
+      }
+      else
+      {
+        degsf[i]= 0;
+        degsg[i]= 0;
+      }
+      i++;
+    }
+    k--;
+  }
+
+  delete [] degsf;
+  delete [] degsg;
+
+  return both_non_zero;
+}
+
+static inline
+CanonicalForm myShift2Zero (const CanonicalForm& F, CFList& Feval,
+                            const CFList& evaluation)
+{
+  CanonicalForm A= F;
+  int k= 2;
+  for (CFListIterator i= evaluation; i.hasItem(); i++, k++)
+    A= A (Variable (k) + i.getItem(), k);
+
+  CanonicalForm buf= A;
+  Feval= CFList();
+  Feval.append (buf);
+  for (k= evaluation.length() + 1; k > 2; k--)
+  {
+    buf= mod (buf, Variable (k));
+    Feval.insert (buf);
+  }
+  return A;
+}
+
+static inline
+CanonicalForm myReverseShift (const CanonicalForm& F, const CFList& evaluation)
+{
+  int l= evaluation.length() + 1;
+  CanonicalForm result= F;
+  CFListIterator j= evaluation;
+  for (int i= 2; i < l + 1; i++, j++)
+  {
+    if (F.level() < i)
+      continue;
+    result= result (Variable (i) - j.getItem(), i);
+  }
+  return result;
+}
+
+static inline
+Evaluation optimize4Lift (const CanonicalForm& F, CFMap & M,
+                    CFMap & N, const Evaluation& A)
+{
+  int n= F.level();
+  int * degsf= new int [n + 1];
+
+  for (int i = 0; i <= n; i++)
+    degsf[i]= 0;
+
+  degsf= degrees (F, degsf);
+
+  Evaluation result= Evaluation (A.min(), A.max());
+  ASSERT (A.min() == 2, "expected A.min() == 2");
+  int max_deg;
+  int k= n;
+  int l= 1;
+  int i= 2;
+  int pos= 2;
+  while (k > 1)
+  {
+    max_deg= degsf [i];
+    while (max_deg == 0)
+    {
+      i++;
+      max_deg= degsf [i];
+    }
+    l= i;
+    for (int j= i + 1; j <=  n; j++)
+    {
+      if (degsf[j] > max_deg)
+      {
+        max_deg= degsf[j];
+        l= j;
+      }
+    }
+
+    if (l <= n)
+    {
+      if (l != pos)
+      {
+        result.setValue (pos, A [l]);
+        M.newpair (Variable (l), Variable (pos));
+        N.newpair (Variable (pos), Variable (l));
+        degsf[l]= 0;
+        l= 2;
+        if (k == 2 && n == 3)
+        {
+          result.setValue (l, A [pos]);
+          M.newpair (Variable (pos), Variable (l));
+          N.newpair (Variable (l), Variable (pos));
+          degsf[pos]= 0;
+        }
+      }
+      else
+      {
+        result.setValue (l, A [l]);
+        degsf [l]= 0;
+      }
+    }
+    pos++;
+    k--;
+    l= 2;
+  }
+
+  delete [] degsf;
+
+  return result;
+}
+
+static inline
+int Hensel (const CanonicalForm & UU, CFArray & G, const Evaluation & AA,
+            const CFArray& LeadCoeffs )
+{
+  CFList factors;
+  factors.append (G[1]);
+  factors.append (G[2]);
+
+  CFMap NN, MM;
+  Evaluation A= optimize4Lift (UU, MM, NN, AA);
+
+  CanonicalForm U= MM (UU);
+  CFArray LCs= CFArray (1,2);
+  LCs [1]= MM (LeadCoeffs [1]);
+  LCs [2]= MM (LeadCoeffs [2]);
+
+  CFList evaluation;
+  long termEstimate= size (U);
+  for (int i= A.min(); i <= A.max(); i++)
+  {
+    if (!A[i].isZero() &&
+        ((getCharacteristic() > degree (U,i)) || getCharacteristic() == 0))
+    {
+      termEstimate *= degree (U,i)*2;
+      termEstimate /= 3;
+    }
+    evaluation.append (A [i]);
+  }
+  if (termEstimate/getNumVars(U) > 500)
+    return -1;
+  CFList UEval;
+  CanonicalForm shiftedU= myShift2Zero (U, UEval, evaluation);
+
+  if (size (shiftedU)/getNumVars (U) > 500)
+    return -1;
+
+  CFArray shiftedLCs= CFArray (2);
+  CFList shiftedLCsEval1, shiftedLCsEval2;
+  shiftedLCs[0]= myShift2Zero (LCs[1], shiftedLCsEval1, evaluation);
+  shiftedLCs[1]= myShift2Zero (LCs[2], shiftedLCsEval2, evaluation);
+  factors.insert (1);
+  int liftBound= degree (UEval.getLast(), 2) + 1;
+  CFArray Pi;
+  CFMatrix M= CFMatrix (liftBound, factors.length() - 1);
+  CFList diophant;
+  CFArray lcs= CFArray (2);
+  lcs [0]= shiftedLCsEval1.getFirst();
+  lcs [1]= shiftedLCsEval2.getFirst();
+  nonMonicHenselLift12 (UEval.getFirst(), factors, liftBound, Pi, diophant, M,
+                        lcs, false);
+
+  for (CFListIterator i= factors; i.hasItem(); i++)
+  {
+    if (!fdivides (i.getItem(), UEval.getFirst()))
+      return 0;
+  }
+
+  int * liftBounds;
+  bool noOneToOne= false;
+  if (U.level() > 2)
+  {
+    liftBounds= new int [U.level() - 1]; /* index: 0.. U.level()-2 */
+    liftBounds[0]= liftBound;
+    for (int i= 1; i < U.level() - 1; i++)
+      liftBounds[i]= degree (shiftedU, Variable (i + 2)) + 1;
+    factors= nonMonicHenselLift2 (UEval, factors, liftBounds, U.level() - 1,
+                                  false, shiftedLCsEval1, shiftedLCsEval2, Pi,
+                                  diophant, noOneToOne);
+    delete [] liftBounds;
+    if (noOneToOne)
+      return 0;
+  }
+  G[1]= factors.getFirst();
+  G[2]= factors.getLast();
+  G[1]= myReverseShift (G[1], evaluation);
+  G[2]= myReverseShift (G[2], evaluation);
+  G[1]= NN (G[1]);
+  G[2]= NN (G[2]);
+  return 1;
+}
+
+static
+bool findeval (const CanonicalForm & F, const CanonicalForm & G,
+               CanonicalForm & Fb, CanonicalForm & Gb, CanonicalForm & Db,
+               REvaluation & b, int delta, int degF, int degG, int maxeval,
+               int & count, int& k, int bound, int& l)
+{
+  if( count == 0 && delta != 0)
+  {
+    if( count++ > maxeval )
+      return false;
+  }
+  if (count > 0)
+  {
+    b.nextpoint(k);
+    if (k == 0)
+      k++;
+    l++;
+    if (l > bound)
+    {
+      l= 1;
+      k++;
+      if (k > tmax (F.level(), G.level()) - 1)
+        return false;
+      b.nextpoint (k);
+    }
+    if (count++ > maxeval)
+      return false;
+  }
+  while( true )
+  {
+    Fb = b( F );
+    if( degree( Fb, 1 ) == degF )
+    {
+      Gb = b( G );
+      if( degree( Gb, 1 ) == degG )
+      {
+        Db = gcd( Fb, Gb );
+        if( delta > 0 )
+        {
+          if( degree( Db, 1 ) <= delta )
+            return true;
+        }
+        else
+        {
+          k++;
+          return true;
+        }
+      }
+    }
+    if (k == 0)
+      k++;
+    b.nextpoint(k);
+    l++;
+    if (l > bound)
+    {
+      l= 1;
+      k++;
+      if (k > tmax (F.level(), G.level()) - 1)
+        return false;
+      b.nextpoint (k);
+    }
+    if( count++ > maxeval )
+      return false;
+  }
+}
+
+/// real implementation of EZGCD over Z
+static CanonicalForm
+ezgcd ( const CanonicalForm & FF, const CanonicalForm & GG, REvaluation & b,
+        bool internal )
+{
+  bool isRat= isOn (SW_RATIONAL);
+
+  int maxNumVars= tmax (getNumVars (FF), getNumVars (GG));
+  int sizeF= size (FF);
+  int sizeG= size (GG);
+
+
+  if (!isRat)
+    On (SW_RATIONAL);
+  if (sizeF/maxNumVars > 500 && sizeG/maxNumVars > 500)
+  {
+    Off(SW_USE_EZGCD);
+    CanonicalForm result=gcd( FF, GG );
+    On(SW_USE_EZGCD);
+    if (!isRat)
+      Off (SW_RATIONAL);
+    result /= icontent (result);
+    DEBDECLEVEL( cerr, "ezgcd" );
+    return result;
+  }
+
+
+  CanonicalForm F, G, f, g, d, Fb, Gb, Db, Fbt, Gbt, Dbt, B0, B, D0, lcF, lcG,
+                lcD, cand, contcand, result;
+  CFArray DD( 1, 2 ), lcDD( 1, 2 );
+  int degF, degG, delta, t, count, maxeval;
+  REvaluation bt;
+  int gcdfound = 0;
+  Variable x = Variable(1);
+  count= 0;
+  maxeval= 200;
+  int o, l;
+  o= 0;
+  l= 1;
+
+  if (!isRat)
+    On (SW_RATIONAL);
+  F= FF*bCommonDen (FF);
+  G= GG*bCommonDen (GG);
+  if (!isRat)
+    Off (SW_RATIONAL);
+
+  TIMING_START (ez_compress)
+  CFMap M,N;
+  int smallestDegLev;
+  int best_level= compress4EZGCD (F, G, M, N, smallestDegLev);
+
+  if (best_level == 0)
+  {
+    DEBDECLEVEL( cerr, "ezgcd" );
+    return G.genOne();
+  }
+
+  F= M (F);
+  G= M (G);
+  TIMING_END_AND_PRINT (ez_compress, "time for compression in EZ: ")
+
+  DEBINCLEVEL( cerr, "ezgcd" );
+  DEBOUTLN( cerr, "FF = " << FF );
+  DEBOUTLN( cerr, "GG = " << GG );
+  TIMING_START (ez_content)
+  f = content( F, x ); g = content( G, x ); d = gcd( f, g );
+  DEBOUTLN( cerr, "f = " << f );
+  DEBOUTLN( cerr, "g = " << g );
+  F /= f; G /= g;
+  TIMING_END_AND_PRINT (ez_content, "time to extract content in EZ: ")
+  if ( F.isUnivariate() && G.isUnivariate() )
+  {
+    DEBDECLEVEL( cerr, "ezgcd" );
+    if(F.mvar()==G.mvar())
+      d*=gcd(F,G);
+    else
+      return N (d);
+    return N (d);
+  }
+  if ( F.isUnivariate())
+  {
+    g= content (G,G.mvar());
+    return N(d*gcd(F,g));
+  }
+  if ( G.isUnivariate())
+  {
+    f= content (F,F.mvar());
+    return N(d*gcd(G,f));
+  }
+
+  maxNumVars= tmax (getNumVars (F), getNumVars (G));
+  sizeF= size (F);
+  sizeG= size (G);
+
+  if (!isRat)
+    On (SW_RATIONAL);
+  if (sizeF/maxNumVars > 500 && sizeG/maxNumVars > 500)
+  {
+    Off(SW_USE_EZGCD);
+    result=gcd( F, G );
+    On(SW_USE_EZGCD);
+    if (!isRat)
+      Off (SW_RATIONAL);
+    result /= icontent (result);
+    DEBDECLEVEL( cerr, "ezgcd" );
+    return N (d*result);
+  }
+
+  int dummy= 0;
+  if ( gcd_test_one( F, G, false, dummy ) )
+  {
+    DEBDECLEVEL( cerr, "ezgcd" );
+    if (!isRat)
+      Off (SW_RATIONAL);
+    return N (d);
+  }
+  lcF = LC( F, x ); lcG = LC( G, x );
+  lcD = gcd( lcF, lcG );
+  delta = 0;
+  degF = degree( F, x ); degG = degree( G, x );
+  t = tmax( F.level(), G.level() );
+  if ( ! internal )
+    b = REvaluation( 2, t, IntRandom( 25 ) );
+  while ( ! gcdfound )
+  {
+    /// ---> A2
+    DEBOUTLN( cerr, "search for evaluation, delta = " << delta );
+    DEBOUTLN( cerr, "F = " << F );
+    DEBOUTLN( cerr, "G = " << G );
+    TIMING_START (ez_eval)
+    if (!findeval( F, G, Fb, Gb, Db, b, delta, degF, degG, maxeval, count,
+                   o, 25, l))
+    {
+      Off(SW_USE_EZGCD);
+      result=gcd( F, G );
+      On(SW_USE_EZGCD);
+      if (!isRat)
+        Off (SW_RATIONAL);
+      DEBDECLEVEL( cerr, "ezgcd" );
+      result /= icontent (result);
+      return N (d*result);
+    }
+    TIMING_END_AND_PRINT (ez_eval, "time to find eval point in EZ1: ")
+    DEBOUTLN( cerr, "found evaluation b = " << b );
+    DEBOUTLN( cerr, "F(b) = " << Fb );
+    DEBOUTLN( cerr, "G(b) = " << Gb );
+    DEBOUTLN( cerr, "D(b) = " << Db );
+    delta = degree( Db );
+    /// ---> A3
+    if (delta == degF)
+    {
+      if (degF <= degG  && fdivides (F, G))
+      {
+        DEBDECLEVEL( cerr, "ezgcd" );
+        if (!isRat)
+          Off (SW_RATIONAL);
+        return N (d*F);
+      }
+      else
+        delta--;
+    }
+    else if (delta == degG)
+    {
+      if (degG <= degF && fdivides( G, F ))
+      {
+        DEBDECLEVEL( cerr, "ezgcd" );
+        if (!isRat)
+          Off (SW_RATIONAL);
+        return N (d*G);
+      }
+      else
+        delta--;
+    }
+    if ( delta == 0 )
+    {
+      DEBDECLEVEL( cerr, "ezgcd" );
+      if (!isRat)
+        Off (SW_RATIONAL);
+      return N (d);
+    }
+    /// ---> A4
+    //deltaold = delta;
+    while ( 1 )
+    {
+      bt = b;
+      TIMING_START (ez_eval)
+      if (!findeval( F, G, Fbt, Gbt, Dbt, bt, delta, degF, degG, maxeval, count,
+                     o, 25,l ))
+      {
+        Off(SW_USE_EZGCD);
+        result=gcd( F, G );
+        On(SW_USE_EZGCD);
+        if (!isRat)
+          Off (SW_RATIONAL);
+        DEBDECLEVEL( cerr, "ezgcd" );
+        result /= icontent (result);
+        return N (d*result);
+      }
+      TIMING_END_AND_PRINT (ez_eval, "time to find eval point in EZ2: ")
+      int dd=degree( Dbt );
+      if ( dd /*degree( Dbt )*/ == 0 )
+      {
+        DEBDECLEVEL( cerr, "ezgcd" );
+        if (!isRat)
+          Off (SW_RATIONAL);
+        return N (d);
+      }
+      if ( dd /*degree( Dbt )*/ == delta )
+        break;
+      else  if ( dd /*degree( Dbt )*/ < delta )
+      {
+        delta = dd /*degree( Dbt )*/;
+        b = bt;
+        Db = Dbt; Fb = Fbt; Gb = Gbt;
+      }
+      DEBOUTLN( cerr, "now after A4, delta = " << delta );
+      /// ---> A5
+      if (delta == degF)
+      {
+        if (degF <= degG  && fdivides (F, G))
+        {
+          DEBDECLEVEL( cerr, "ezgcd" );
+          if (!isRat)
+            Off (SW_RATIONAL);
+          return N (d*F);
+        }
+        else
+          delta--;
+      }
+      else if (delta == degG)
+      {
+        if (degG <= degF && fdivides( G, F ))
+        {
+          DEBDECLEVEL( cerr, "ezgcd" );
+          if (!isRat)
+            Off (SW_RATIONAL);
+          return N (d*G);
+        }
+        else
+          delta--;
+      }
+      if ( delta == 0 )
+      {
+        DEBDECLEVEL( cerr, "ezgcd" );
+        if (!isRat)
+          Off (SW_RATIONAL);
+        return N (d);
+      }
+    }
+    if ( delta != degF && delta != degG )
+    {
+      /// ---> A6
+      bool B_is_F;
+      CanonicalForm xxx1, xxx2;
+      CanonicalForm buf;
+      DD[1] = Fb / Db;
+      buf= Gb/Db;
+      xxx1 = gcd( DD[1], Db );
+      xxx2 = gcd( buf, Db );
+      if (((xxx1.inCoeffDomain() && xxx2.inCoeffDomain()) &&
+          (size (F) <= size (G)))
+            || (xxx1.inCoeffDomain() && !xxx2.inCoeffDomain()))
+      {
+        B = F;
+        DD[2] = Db;
+        lcDD[1] = lcF;
+        lcDD[2] = lcD;
+        B_is_F = true;
+      }
+      else if (((xxx1.inCoeffDomain() && xxx2.inCoeffDomain()) &&
+                (size (G) < size (F)))
+                || (!xxx1.inCoeffDomain() && xxx2.inCoeffDomain()))
+      {
+        DD[1] = buf;
+        B = G;
+        DD[2] = Db;
+        lcDD[1] = lcG;
+        lcDD[2] = lcD;
+        B_is_F = false;
+      }
+      else
+      {
+        //special case
+        Off(SW_USE_EZGCD);
+        result=gcd( F, G );
+        On(SW_USE_EZGCD);
+        if (!isRat)
+          Off (SW_RATIONAL);
+        DEBDECLEVEL( cerr, "ezgcd" );
+        result /= icontent (result);
+        return N (d*result);
+      }
+      /// ---> A7
+      DD[2] = DD[2] * ( b( lcDD[2] ) / lc( DD[2] ) );
+      DD[1] = DD[1] * ( b( lcDD[1] ) / lc( DD[1] ) );
+      DEBOUTLN( cerr, "(hensel) B    = " << B );
+      DEBOUTLN( cerr, "(hensel) lcB  = " << LC( B, Variable(1) ) );
+      DEBOUTLN( cerr, "(hensel) b(B) = " << b(B) );
+      DEBOUTLN( cerr, "(hensel) DD   = " << DD );
+      DEBOUTLN( cerr, "(hensel) lcDD = " << lcDD );
+      TIMING_START (ez_hensel_lift)
+      gcdfound= Hensel (B*lcD, DD, b, lcDD);
+      TIMING_END_AND_PRINT (ez_hensel_lift, "time to hensel lift in EZ: ")
+      DEBOUTLN( cerr, "(hensel finished) DD   = " << DD );
+
+      if (gcdfound == -1)
+      {
+        Off (SW_USE_EZGCD);
+        result= gcd (F,G);
+        On (SW_USE_EZGCD);
+        if (!isRat)
+          Off (SW_RATIONAL);
+        DEBDECLEVEL( cerr, "ezgcd" );
+        result /= icontent (result);
+        return N (d*result);
+      }
+
+      if (gcdfound)
+      {
+        TIMING_START (ez_termination)
+        contcand= content (DD[2], Variable (1));
+        cand = DD[2] / contcand;
+        if (B_is_F)
+          gcdfound = fdivides( cand, G ) && cand*(DD[1]/(lcD/contcand)) == F;
+        else
+          gcdfound = fdivides( cand, F ) && cand*(DD[1]/(lcD/contcand)) == G;
+        TIMING_END_AND_PRINT (ez_termination,
+                              "time for termination test in EZ: ")
+      }
+      /// ---> A8 (gcdfound)
+    }
+    delta--;
+  }
+  /// ---> A9
+  DEBDECLEVEL( cerr, "ezgcd" );
+  cand *= bCommonDen (cand);
+  if (!isRat)
+    Off (SW_RATIONAL);
+  cand /= icontent (cand);
+  return N (d*cand);
+}
+#endif
+
+/// Extended Zassenhaus GCD over Z.
+/// In case things become too dense we switch to a modular algorithm.
+CanonicalForm
+ezgcd ( const CanonicalForm & FF, const CanonicalForm & GG )
+{
+#ifdef HAVE_NTL
+  REvaluation b;
+  return ezgcd( FF, GG, b, false );
+#else
+  Off (SW_USE_EZGCD);
+  return gcd (FF, GG);
+  On (SW_USE_EZGCD);
+#endif
+}
+
+#ifdef HAVE_NTL
+// parameters for heuristic
+static int maxNumEval= 200;
+static int sizePerVars1= 500; //try dense gcd if size/#variables is bigger
+
+/// Extended Zassenhaus GCD for finite fields.
+/// In case things become too dense we switch to a modular algorithm.
+CanonicalForm EZGCD_P( const CanonicalForm & FF, const CanonicalForm & GG )
+{
+  if (FF.isZero() && degree(GG) > 0) return GG/Lc(GG);
+  else if (GG.isZero() && degree (FF) > 0) return FF/Lc(FF);
+  else if (FF.isZero() && GG.isZero()) return FF.genOne();
+  if (FF.inBaseDomain() || GG.inBaseDomain()) return FF.genOne();
+  if (FF.isUnivariate() && fdivides(FF, GG)) return FF/Lc(FF);
+  if (GG.isUnivariate() && fdivides(GG, FF)) return GG/Lc(GG);
+  if (FF == GG) return FF/Lc(FF);
+
+  int maxNumVars= tmax (getNumVars (FF), getNumVars (GG));
+  Variable a, oldA;
+  int sizeF= size (FF);
+  int sizeG= size (GG);
+
+  if (sizeF/maxNumVars > sizePerVars1 && sizeG/maxNumVars > sizePerVars1)
+  {
+    if (hasFirstAlgVar (FF, a) || hasFirstAlgVar (GG, a))
+      return modGCDFq (FF, GG, a);
+    else if (CFFactory::gettype() == GaloisFieldDomain)
+      return modGCDGF (FF, GG);
+    else
+      return modGCDFp (FF, GG);
+  }
+
+  CanonicalForm F, G, f, g, d, Fb, Gb, Db, Fbt, Gbt, Dbt, B0, B, D0, lcF, lcG,
+                lcD;
+  CFArray DD( 1, 2 ), lcDD( 1, 2 );
+  int degF, degG, delta, count;
+  int maxeval;
+  maxeval= tmin((getCharacteristic()/
+                (int)(ilog2(getCharacteristic())*log2exp))*2, maxNumEval);
+  count= 0; // number of eval. used
+  REvaluation b, bt;
+  int gcdfound = 0;
+  Variable x = Variable(1);
+
+  F= FF;
+  G= GG;
+
+  CFMap M,N;
+  int smallestDegLev;
+  TIMING_START (ez_p_compress)
+  int best_level= compress4EZGCD (F, G, M, N, smallestDegLev);
+
+  if (best_level == 0) return G.genOne();
+
+  F= M (F);
+  G= M (G);
+  TIMING_END_AND_PRINT (ez_p_compress, "time for compression in EZ_P: ")
+
+  TIMING_START (ez_p_content)
+  f = content( F, x ); g = content( G, x );
+  d = gcd( f, g );
+  F /= f; G /= g;
+  TIMING_END_AND_PRINT (ez_p_content, "time to extract content in EZ_P: ")
+
+  if( F.isUnivariate() && G.isUnivariate() )
+  {
+    if( F.mvar() == G.mvar() )
+      d *= gcd( F, G );
+    else
+      return N (d);
+    return N (d);
+  }
+  if ( F.isUnivariate())
+  {
+    g= content (G,G.mvar());
+    return N(d*gcd(F,g));
+  }
+  if ( G.isUnivariate())
+  {
+    f= content (F,F.mvar());
+    return N(d*gcd(G,f));
+  }
+
+  maxNumVars= tmax (getNumVars (F), getNumVars (G));
+  sizeF= size (F);
+  sizeG= size (G);
+
+  if (sizeF/maxNumVars > sizePerVars1 && sizeG/maxNumVars > sizePerVars1)
+  {
+    if (hasFirstAlgVar (F, a) || hasFirstAlgVar (G, a))
+      return N (d*modGCDFq (F, G, a));
+    else if (CFFactory::gettype() == GaloisFieldDomain)
+      return N (d*modGCDGF (F, G));
+    else
+      return N (d*modGCDFp (F, G));
+  }
+
+  int dummy= 0;
+  if( gcd_test_one( F, G, false, dummy ) )
+  {
+    return N (d);
+  }
+
+  bool passToGF= false;
+  bool extOfExt= false;
+  int p= getCharacteristic();
+  bool algExtension= (hasFirstAlgVar(F,a) || hasFirstAlgVar(G,a));
+  int k= 1;
+  CanonicalForm primElem, imPrimElem;
+  CFList source, dest;
+  if (p < 50 && CFFactory::gettype() != GaloisFieldDomain && !algExtension)
+  {
+    if (p == 2)
+      setCharacteristic (2, 12, 'Z');
+    else if (p == 3)
+      setCharacteristic (3, 4, 'Z');
+    else if (p == 5 || p == 7)
+      setCharacteristic (p, 3, 'Z');
+    else
+      setCharacteristic (p, 2, 'Z');
+    passToGF= true;
+    F= F.mapinto();
+    G= G.mapinto();
+    maxeval= 2*ipower (p, getGFDegree());
+  }
+  else if (CFFactory::gettype() == GaloisFieldDomain &&
+           ipower (p , getGFDegree()) < 50)
+  {
+    k= getGFDegree();
+    if (ipower (p, 2*k) > 50)
+      setCharacteristic (p, 2*k, gf_name);
+    else
+      setCharacteristic (p, 3*k, gf_name);
+    F= GFMapUp (F, k);
+    G= GFMapUp (G, k);
+    maxeval= tmin (2*ipower (p, getGFDegree()), maxNumEval);
+  }
+  else if (p < 50 && algExtension && CFFactory::gettype() != GaloisFieldDomain)
+  {
+    int d= degree (getMipo (a));
+    oldA= a;
+    Variable v2;
+    if (p == 2 && d < 6)
+    {
+      if (fac_NTL_char != p)
+      {
+        fac_NTL_char= p;
+        zz_p::init (p);
+      }
+      bool primFail= false;
+      Variable vBuf;
+      primElem= primitiveElement (a, vBuf, primFail);
+      ASSERT (!primFail, "failure in integer factorizer");
+      if (d < 3)
+      {
+        zz_pX NTLIrredpoly;
+        BuildIrred (NTLIrredpoly, d*3);
+        CanonicalForm newMipo= convertNTLzzpX2CF (NTLIrredpoly, Variable (1));
+        v2= rootOf (newMipo);
+      }
+      else
+      {
+        zz_pX NTLIrredpoly;
+        BuildIrred (NTLIrredpoly, d*2);
+        CanonicalForm newMipo= convertNTLzzpX2CF (NTLIrredpoly, Variable (1));
+        v2= rootOf (newMipo);
+      }
+      imPrimElem= mapPrimElem (primElem, a, v2);
+      extOfExt= true;
+    }
+    else if ((p == 3 && d < 4) || ((p == 5 || p == 7) && d < 3))
+    {
+      if (fac_NTL_char != p)
+      {
+        fac_NTL_char= p;
+        zz_p::init (p);
+      }
+      bool primFail= false;
+      Variable vBuf;
+      primElem= primitiveElement (a, vBuf, primFail);
+      ASSERT (!primFail, "failure in integer factorizer");
+      zz_pX NTLIrredpoly;
+      BuildIrred (NTLIrredpoly, d*2);
+      CanonicalForm newMipo= convertNTLzzpX2CF (NTLIrredpoly, Variable (1));
+      v2= rootOf (newMipo);
+      imPrimElem= mapPrimElem (primElem, a, v2);
+      extOfExt= true;
+    }
+    if (extOfExt)
+    {
+      maxeval= tmin (2*ipower (p, degree (getMipo (v2))), maxNumEval);
+      F= mapUp (F, a, v2, primElem, imPrimElem, source, dest);
+      G= mapUp (G, a, v2, primElem, imPrimElem, source, dest);
+      a= v2;
+    }
+  }
+
+  lcF = LC( F, x ); lcG = LC( G, x );
+  lcD = gcd( lcF, lcG );
+
+  delta = 0;
+  degF = degree( F, x ); degG = degree( G, x );
+
+  if (algExtension)
+    b = REvaluation( 2, tmax(F.level(), G.level()), AlgExtRandomF( a ) );
+  else
+  { // both not in extension given by algebraic variable
+    if (CFFactory::gettype() != GaloisFieldDomain)
+      b = REvaluation( 2, tmax(F.level(), G.level()), FFRandom() );
+    else
+      b = REvaluation( 2, tmax(F.level(), G.level()), GFRandom() );
+  }
+
+  CanonicalForm cand, contcand;
+  CanonicalForm result;
+  int o, t;
+  o= 0;
+  t= 1;
+  int goodPointCount= 0;
+  while( !gcdfound )
+  {
+    TIMING_START (ez_p_eval);
+    if( !findeval( F, G, Fb, Gb, Db, b, delta, degF, degG, maxeval, count, o,
+         maxeval/maxNumVars, t ))
+    { // too many eval. used --> try another method
+      Off (SW_USE_EZGCD_P);
+      result= gcd (F,G);
+      On (SW_USE_EZGCD_P);
+      if (passToGF)
+      {
+        CanonicalForm mipo= gf_mipo;
+        setCharacteristic (p);
+        Variable alpha= rootOf (mipo.mapinto());
+        result= GF2FalphaRep (result, alpha);
+        prune (alpha);
+      }
+      if (k > 1)
+      {
+        result= GFMapDown (result, k);
+        setCharacteristic (p, k, gf_name);
+      }
+      if (extOfExt)
+      {
+        result= mapDown (result, primElem, imPrimElem, oldA, dest, source);
+        prune1 (oldA);
+      }
+      return N (d*result);
+    }
+    TIMING_END_AND_PRINT (ez_p_eval, "time for eval point search in EZ_P1: ");
+    delta = degree( Db );
+    if (delta == degF)
+    {
+      if (degF <= degG && fdivides (F, G))
+      {
+        if (passToGF)
+        {
+          CanonicalForm mipo= gf_mipo;
+          setCharacteristic (p);
+          Variable alpha= rootOf (mipo.mapinto());
+          F= GF2FalphaRep (F, alpha);
+          prune (alpha);
+        }
+        if (k > 1)
+        {
+          F= GFMapDown (F, k);
+          setCharacteristic (p, k, gf_name);
+        }
+        if (extOfExt)
+        {
+          F= mapDown (F, primElem, imPrimElem, oldA, dest, source);
+          prune1 (oldA);
+        }
+        return N (d*F);
+      }
+      else
+        delta--;
+    }
+    else if (delta == degG)
+    {
+      if (degG <= degF && fdivides (G, F))
+      {
+        if (passToGF)
+        {
+          CanonicalForm mipo= gf_mipo;
+          setCharacteristic (p);
+          Variable alpha= rootOf (mipo.mapinto());
+          G= GF2FalphaRep (G, alpha);
+          prune (alpha);
+        }
+        if (k > 1)
+        {
+          G= GFMapDown (G, k);
+          setCharacteristic (p, k, gf_name);
+        }
+        if (extOfExt)
+        {
+          G= mapDown (G, primElem, imPrimElem, oldA, dest, source);
+          prune1 (oldA);
+        }
+        return N (d*G);
+      }
+      else
+        delta--;
+    }
+    if( delta == 0 )
+    {
+      if (passToGF)
+        setCharacteristic (p);
+      if (k > 1)
+        setCharacteristic (p, k, gf_name);
+      return N (d);
+    }
+    while( true )
+    {
+      bt = b;
+      TIMING_START (ez_p_eval);
+      if( !findeval(F,G,Fbt,Gbt,Dbt, bt, delta, degF, degG, maxeval, count, o,
+           maxeval/maxNumVars, t ))
+      { // too many eval. used --> try another method
+        Off (SW_USE_EZGCD_P);
+        result= gcd (F,G);
+        On (SW_USE_EZGCD_P);
+        if (passToGF)
+        {
+          CanonicalForm mipo= gf_mipo;
+          setCharacteristic (p);
+          Variable alpha= rootOf (mipo.mapinto());
+          result= GF2FalphaRep (result, alpha);
+          prune (alpha);
+        }
+        if (k > 1)
+        {
+          result= GFMapDown (result, k);
+          setCharacteristic (p, k, gf_name);
+        }
+        if (extOfExt)
+        {
+          result= mapDown (result, primElem, imPrimElem, oldA, dest, source);
+          prune1 (oldA);
+        }
+        return N (d*result);
+      }
+      TIMING_END_AND_PRINT (ez_p_eval, "time for eval point search in EZ_P2: ");
+      int dd = degree( Dbt );
+      if( dd == 0 )
+      {
+        if (passToGF)
+          setCharacteristic (p);
+        if (k > 1)
+          setCharacteristic (p, k, gf_name);
+        return N (d);
+      }
+      if( dd == delta )
+      {
+        goodPointCount++;
+        if (goodPointCount == 5)
+          break;
+      }
+      if( dd < delta )
+      {
+        goodPointCount= 0;
+        delta = dd;
+        b = bt;
+        Db = Dbt; Fb = Fbt; Gb = Gbt;
+      }
+      if (delta == degF)
+      {
+        if (degF <= degG && fdivides (F, G))
+        {
+          if (passToGF)
+          {
+            CanonicalForm mipo= gf_mipo;
+            setCharacteristic (p);
+            Variable alpha= rootOf (mipo.mapinto());
+            F= GF2FalphaRep (F, alpha);
+            prune (alpha);
+          }
+          if (k > 1)
+          {
+            F= GFMapDown (F, k);
+            setCharacteristic (p, k, gf_name);
+          }
+          if (extOfExt)
+          {
+            F= mapDown (F, primElem, imPrimElem, oldA, dest, source);
+            prune1 (oldA);
+          }
+          return N (d*F);
+        }
+        else
+          delta--;
+      }
+      else if (delta == degG)
+      {
+        if (degG <= degF && fdivides (G, F))
+        {
+          if (passToGF)
+          {
+            CanonicalForm mipo= gf_mipo;
+            setCharacteristic (p);
+            Variable alpha= rootOf (mipo.mapinto());
+            G= GF2FalphaRep (G, alpha);
+            prune (alpha);
+          }
+          if (k > 1)
+          {
+            G= GFMapDown (G, k);
+            setCharacteristic (p, k, gf_name);
+          }
+          if (extOfExt)
+          {
+            G= mapDown (G, primElem, imPrimElem, oldA, dest, source);
+            prune1 (oldA);
+          }
+          return N (d*G);
+        }
+        else
+          delta--;
+      }
+      if( delta == 0 )
+      {
+        if (passToGF)
+          setCharacteristic (p);
+        if (k > 1)
+          setCharacteristic (p, k, gf_name);
+        return N (d);
+      }
+    }
+    if( delta != degF && delta != degG )
+    {
+      bool B_is_F;
+      CanonicalForm xxx1, xxx2;
+      CanonicalForm buf;
+      DD[1] = Fb / Db;
+      buf= Gb/Db;
+      xxx1 = gcd( DD[1], Db );
+      xxx2 = gcd( buf, Db );
+      if (((xxx1.inCoeffDomain() && xxx2.inCoeffDomain()) &&
+          (size (F) <= size (G)))
+          || (xxx1.inCoeffDomain() && !xxx2.inCoeffDomain()))
+      {
+        B = F;
+        DD[2] = Db;
+        lcDD[1] = lcF;
+        lcDD[2] = lcD;
+        B_is_F = true;
+      }
+      else if (((xxx1.inCoeffDomain() && xxx2.inCoeffDomain()) &&
+               (size (G) < size (F)))
+               || (!xxx1.inCoeffDomain() && xxx2.inCoeffDomain()))
+      {
+        DD[1] = buf;
+        B = G;
+        DD[2] = Db;
+        lcDD[1] = lcG;
+        lcDD[2] = lcD;
+        B_is_F = false;
+      }
+      else // special case handling
+      {
+        Off (SW_USE_EZGCD_P);
+        result= gcd (F,G);
+        On (SW_USE_EZGCD_P);
+        if (passToGF)
+        {
+          CanonicalForm mipo= gf_mipo;
+          setCharacteristic (p);
+          Variable alpha= rootOf (mipo.mapinto());
+          result= GF2FalphaRep (result, alpha);
+          prune (alpha);
+        }
+        if (k > 1)
+        {
+          result= GFMapDown (result, k);
+          setCharacteristic (p, k, gf_name);
+        }
+        if (extOfExt)
+        {
+          result= mapDown (result, primElem, imPrimElem, oldA, dest, source);
+          prune1 (oldA);
+        }
+        return N (d*result);
+      }
+      DD[2] = DD[2] * ( b( lcDD[2] ) / lc( DD[2] ) );
+      DD[1] = DD[1] * ( b( lcDD[1] ) / lc( DD[1] ) );
+
+      if (size (B*lcDD[2])/maxNumVars > sizePerVars1)
+      {
+        if (algExtension)
+        {
+          result= modGCDFq (F, G, a);
+          if (extOfExt)
+          {
+            result= mapDown (result, primElem, imPrimElem, oldA, dest, source);
+            prune1 (oldA);
+          }
+          return N (d*result);
+        }
+        if (CFFactory::gettype() == GaloisFieldDomain)
+        {
+          result= modGCDGF (F, G);
+          if (passToGF)
+          {
+            CanonicalForm mipo= gf_mipo;
+            setCharacteristic (p);
+            Variable alpha= rootOf (mipo.mapinto());
+            result= GF2FalphaRep (result, alpha);
+            prune (alpha);
+          }
+          if (k > 1)
+          {
+            result= GFMapDown (result, k);
+            setCharacteristic (p, k, gf_name);
+          }
+          return N (d*result);
+        }
+        else
+          return N (d*modGCDFp (F,G));
+      }
+
+      TIMING_START (ez_p_hensel_lift);
+      gcdfound= Hensel (B*lcD, DD, b, lcDD);
+      TIMING_END_AND_PRINT (ez_p_hensel_lift, "time for Hensel lift in EZ_P: ");
+
+      if (gcdfound == -1) //things became dense
+      {
+        if (algExtension)
+        {
+          result= modGCDFq (F, G, a);
+          if (extOfExt)
+          {
+            result= mapDown (result, primElem, imPrimElem, oldA, dest, source);
+            prune1 (oldA);
+          }
+          return N (d*result);
+        }
+        if (CFFactory::gettype() == GaloisFieldDomain)
+        {
+          result= modGCDGF (F, G);
+          if (passToGF)
+          {
+            CanonicalForm mipo= gf_mipo;
+            setCharacteristic (p);
+            Variable alpha= rootOf (mipo.mapinto());
+            result= GF2FalphaRep (result, alpha);
+            prune (alpha);
+          }
+          if (k > 1)
+          {
+            result= GFMapDown (result, k);
+            setCharacteristic (p, k, gf_name);
+          }
+          return N (d*result);
+        }
+        else
+        {
+          if (p >= cf_getBigPrime(0))
+            return N (d*sparseGCDFp (F,G));
+          else
+            return N (d*modGCDFp (F,G));
+        }
+      }
+
+      if (gcdfound == 1)
+      {
+        TIMING_START (termination_test);
+        contcand= content (DD[2], Variable (1));
+        cand = DD[2] / contcand;
+        if (B_is_F)
+          gcdfound = fdivides( cand, G ) && cand*(DD[1]/(lcD/contcand)) == F;
+        else
+          gcdfound = fdivides( cand, F ) && cand*(DD[1]/(lcD/contcand)) == G;
+        TIMING_END_AND_PRINT (termination_test,
+                              "time for termination test EZ_P: ");
+
+        if (passToGF && gcdfound)
+        {
+          CanonicalForm mipo= gf_mipo;
+          setCharacteristic (p);
+          Variable alpha= rootOf (mipo.mapinto());
+          cand= GF2FalphaRep (cand, alpha);
+          prune (alpha);
+        }
+        if (k > 1 && gcdfound)
+        {
+          cand= GFMapDown (cand, k);
+          setCharacteristic (p, k, gf_name);
+        }
+        if (extOfExt && gcdfound)
+        {
+          cand= mapDown (cand, primElem, imPrimElem, oldA, dest, source);
+          prune1 (oldA);
+        }
+      }
+    }
+    delta--;
+    goodPointCount= 0;
+  }
+  return N (d*cand);
+}
+#endif
+
diff --git a/factory/cfEzgcd.h b/factory/cfEzgcd.h
new file mode 100644
index 0000000..b1e17dc
--- /dev/null
+++ b/factory/cfEzgcd.h
@@ -0,0 +1,13 @@
+/**
+ * @file cfEzgcd.h
+ *
+ * Extended Zassenhaus GCD over finite fields and Z
+**/
+
+#ifndef CF_EZ_GCD_H
+#define CF_EZ_GCD_H
+CanonicalForm
+EZGCD_P (const CanonicalForm& A, const CanonicalForm& B);
+
+CanonicalForm ezgcd ( const CanonicalForm & f, const CanonicalForm & g );
+#endif
diff --git a/factory/cfGcdAlgExt.cc b/factory/cfGcdAlgExt.cc
new file mode 100644
index 0000000..b750520
--- /dev/null
+++ b/factory/cfGcdAlgExt.cc
@@ -0,0 +1,1077 @@
+
+#include "config.h"
+
+
+#ifndef NOSTREAMIO
+#ifdef HAVE_CSTDIO
+#include <cstdio>
+#else
+#include <stdio.h>
+#endif
+#ifdef HAVE_IOSTREAM_H
+#include <iostream.h>
+#elif defined(HAVE_IOSTREAM)
+#include <iostream>
+#endif
+#endif
+
+#include "cf_assert.h"
+#include "timing.h"
+
+#include "templates/ftmpl_functions.h"
+#include "cf_defs.h"
+#include "canonicalform.h"
+#include "cf_iter.h"
+#include "cf_primes.h"
+#include "cf_algorithm.h"
+#include "cfGcdAlgExt.h"
+#include "cfUnivarGcd.h"
+#include "cf_map.h"
+#include "cf_generator.h"
+#include "facMul.h"
+#include "cfNTLzzpEXGCD.h"
+
+#ifdef HAVE_NTL
+#include "NTLconvert.h"
+#endif
+
+#ifdef HAVE_FLINT
+#include "FLINTconvert.h"
+#endif
+
+TIMING_DEFINE_PRINT(alg_content_p)
+TIMING_DEFINE_PRINT(alg_content)
+TIMING_DEFINE_PRINT(alg_compress)
+TIMING_DEFINE_PRINT(alg_termination)
+TIMING_DEFINE_PRINT(alg_termination_p)
+TIMING_DEFINE_PRINT(alg_reconstruction)
+TIMING_DEFINE_PRINT(alg_newton_p)
+TIMING_DEFINE_PRINT(alg_recursion_p)
+TIMING_DEFINE_PRINT(alg_gcd_p)
+TIMING_DEFINE_PRINT(alg_euclid_p)
+
+/// compressing two polynomials F and G, M is used for compressing,
+/// N to reverse the compression
+static
+int myCompress (const CanonicalForm& F, const CanonicalForm& G, CFMap & M,
+                CFMap & N, bool topLevel)
+{
+  int n= tmax (F.level(), G.level());
+  int * degsf= new int [n + 1];
+  int * degsg= new int [n + 1];
+
+  for (int i = 0; i <= n; i++)
+    degsf[i]= degsg[i]= 0;
+
+  degsf= degrees (F, degsf);
+  degsg= degrees (G, degsg);
+
+  int both_non_zero= 0;
+  int f_zero= 0;
+  int g_zero= 0;
+  int both_zero= 0;
+
+  if (topLevel)
+  {
+    for (int i= 1; i <= n; i++)
+    {
+      if (degsf[i] != 0 && degsg[i] != 0)
+      {
+        both_non_zero++;
+        continue;
+      }
+      if (degsf[i] == 0 && degsg[i] != 0 && i <= G.level())
+      {
+        f_zero++;
+        continue;
+      }
+      if (degsg[i] == 0 && degsf[i] && i <= F.level())
+      {
+        g_zero++;
+        continue;
+      }
+    }
+
+    if (both_non_zero == 0)
+    {
+      delete [] degsf;
+      delete [] degsg;
+      return 0;
+    }
+
+    // map Variables which do not occur in both polynomials to higher levels
+    int k= 1;
+    int l= 1;
+    for (int i= 1; i <= n; i++)
+    {
+      if (degsf[i] != 0 && degsg[i] == 0 && i <= F.level())
+      {
+        if (k + both_non_zero != i)
+        {
+          M.newpair (Variable (i), Variable (k + both_non_zero));
+          N.newpair (Variable (k + both_non_zero), Variable (i));
+        }
+        k++;
+      }
+      if (degsf[i] == 0 && degsg[i] != 0 && i <= G.level())
+      {
+        if (l + g_zero + both_non_zero != i)
+        {
+          M.newpair (Variable (i), Variable (l + g_zero + both_non_zero));
+          N.newpair (Variable (l + g_zero + both_non_zero), Variable (i));
+        }
+        l++;
+      }
+    }
+
+    // sort Variables x_{i} in increasing order of
+    // min(deg_{x_{i}}(f),deg_{x_{i}}(g))
+    int m= tmax (F.level(), G.level());
+    int min_max_deg;
+    k= both_non_zero;
+    l= 0;
+    int i= 1;
+    while (k > 0)
+    {
+      if (degsf [i] != 0 && degsg [i] != 0)
+        min_max_deg= tmax (degsf[i], degsg[i]);
+      else
+        min_max_deg= 0;
+      while (min_max_deg == 0)
+      {
+        i++;
+        min_max_deg= tmax (degsf[i], degsg[i]);
+        if (degsf [i] != 0 && degsg [i] != 0)
+          min_max_deg= tmax (degsf[i], degsg[i]);
+        else
+          min_max_deg= 0;
+      }
+      for (int j= i + 1; j <=  m; j++)
+      {
+        if (tmax (degsf[j],degsg[j]) <= min_max_deg && degsf[j] != 0 && degsg [j] != 0)
+        {
+          min_max_deg= tmax (degsf[j], degsg[j]);
+          l= j;
+        }
+      }
+      if (l != 0)
+      {
+        if (l != k)
+        {
+          M.newpair (Variable (l), Variable(k));
+          N.newpair (Variable (k), Variable(l));
+          degsf[l]= 0;
+          degsg[l]= 0;
+          l= 0;
+        }
+        else
+        {
+          degsf[l]= 0;
+          degsg[l]= 0;
+          l= 0;
+        }
+      }
+      else if (l == 0)
+      {
+        if (i != k)
+        {
+          M.newpair (Variable (i), Variable (k));
+          N.newpair (Variable (k), Variable (i));
+          degsf[i]= 0;
+          degsg[i]= 0;
+        }
+        else
+        {
+          degsf[i]= 0;
+          degsg[i]= 0;
+        }
+        i++;
+      }
+      k--;
+    }
+  }
+  else
+  {
+    //arrange Variables such that no gaps occur
+    for (int i= 1; i <= n; i++)
+    {
+      if (degsf[i] == 0 && degsg[i] == 0)
+      {
+        both_zero++;
+        continue;
+      }
+      else
+      {
+        if (both_zero != 0)
+        {
+          M.newpair (Variable (i), Variable (i - both_zero));
+          N.newpair (Variable (i - both_zero), Variable (i));
+        }
+      }
+    }
+  }
+
+  delete [] degsf;
+  delete [] degsg;
+
+  return 1;
+}
+
+void tryInvert( const CanonicalForm & F, const CanonicalForm & M, CanonicalForm & inv, bool & fail )
+{ // F, M are required to be "univariate" polynomials in an algebraic variable
+  // we try to invert F modulo M
+  if(F.inBaseDomain())
+  {
+    if(F.isZero())
+    {
+      fail = true;
+      return;
+    }
+    inv = 1/F;
+    return;
+  }
+  CanonicalForm b;
+  Variable a = M.mvar();
+  Variable x = Variable(1);
+  if(!extgcd( replacevar( F, a, x ), replacevar( M, a, x ), inv, b ).isOne())
+    fail = true;
+  else
+    inv = replacevar( inv, x, a ); // change back to alg var
+}
+
+#ifndef HAVE_NTL
+void tryDivrem (const CanonicalForm& F, const CanonicalForm& G, CanonicalForm& Q,
+                CanonicalForm& R, CanonicalForm& inv, const CanonicalForm& mipo,
+                bool& fail)
+{
+  if (F.inCoeffDomain())
+  {
+    Q= 0;
+    R= F;
+    return;
+  }
+
+  CanonicalForm A, B;
+  Variable x= F.mvar();
+  A= F;
+  B= G;
+  int degA= degree (A, x);
+  int degB= degree (B, x);
+
+  if (degA < degB)
+  {
+    R= A;
+    Q= 0;
+    return;
+  }
+
+  tryInvert (Lc (B), mipo, inv, fail);
+  if (fail)
+    return;
+
+  R= A;
+  Q= 0;
+  CanonicalForm Qi;
+  for (int i= degA -degB; i >= 0; i--)
+  {
+    if (degree (R, x) == i + degB)
+    {
+      Qi= Lc (R)*inv*power (x, i);
+      Qi= reduce (Qi, mipo);
+      R -= Qi*B;
+      R= reduce (R, mipo);
+      Q += Qi;
+    }
+  }
+}
+
+void tryEuclid( const CanonicalForm & A, const CanonicalForm & B, const CanonicalForm & M, CanonicalForm & result, bool & fail )
+{
+  CanonicalForm P;
+  if(A.inCoeffDomain())
+  {
+    tryInvert( A, M, P, fail );
+    if(fail)
+      return;
+    result = 1;
+    return;
+  }
+  if(B.inCoeffDomain())
+  {
+    tryInvert( B, M, P, fail );
+    if(fail)
+      return;
+    result = 1;
+    return;
+  }
+  // here: both not inCoeffDomain
+  if( A.degree() > B.degree() )
+  {
+    P = A; result = B;
+  }
+  else
+  {
+    P = B; result = A;
+  }
+  CanonicalForm inv;
+  if( result.isZero() )
+  {
+    tryInvert( Lc(P), M, inv, fail );
+    if(fail)
+      return;
+    result = inv*P; // monify result (not reduced, yet)
+    result= reduce (result, M);
+    return;
+  }
+  Variable x = P.mvar();
+  CanonicalForm rem, Q;
+  // here: degree(P) >= degree(result)
+  while(true)
+  {
+    tryDivrem (P, result, Q, rem, inv, M, fail);
+    if (fail)
+      return;
+    if( rem.isZero() )
+    {
+      result *= inv;
+      result= reduce (result, M);
+      return;
+    }
+    if(result.degree(x) >= rem.degree(x))
+    {
+      P = result;
+      result = rem;
+    }
+    else
+      P = rem;
+  }
+}
+#endif
+
+CanonicalForm QGCD( const CanonicalForm & F, const CanonicalForm & G );
+int * leadDeg(const CanonicalForm & f, int *degs);
+bool isLess(int *a, int *b, int lower, int upper);
+bool isEqual(int *a, int *b, int lower, int upper);
+CanonicalForm firstLC(const CanonicalForm & f);
+static CanonicalForm trycontent ( const CanonicalForm & f, const Variable & x, const CanonicalForm & M, bool & fail );
+static CanonicalForm tryvcontent ( const CanonicalForm & f, const Variable & x, const CanonicalForm & M, bool & fail );
+static CanonicalForm trycf_content ( const CanonicalForm & f, const CanonicalForm & g, const CanonicalForm & M, bool & fail );
+
+static inline CanonicalForm
+tryNewtonInterp (const CanonicalForm & alpha, const CanonicalForm & u,
+              const CanonicalForm & newtonPoly, const CanonicalForm & oldInterPoly,
+              const Variable & x, const CanonicalForm& M, bool& fail)
+{
+  CanonicalForm interPoly;
+
+  CanonicalForm inv;
+  tryInvert (newtonPoly (alpha, x), M, inv, fail);
+  if (fail)
+    return 0;
+
+  interPoly= oldInterPoly+reduce ((u - oldInterPoly (alpha, x))*inv*newtonPoly, M);
+  return interPoly;
+}
+
+void tryBrownGCD( const CanonicalForm & F, const CanonicalForm & G, const CanonicalForm & M, CanonicalForm & result, bool & fail, bool topLevel )
+{ // assume F,G are multivariate polys over Z/p(a) for big prime p, M "univariate" polynomial in an algebraic variable
+  // M is assumed to be monic
+  if(F.isZero())
+  {
+    if(G.isZero())
+    {
+      result = G; // G is zero
+      return;
+    }
+    if(G.inCoeffDomain())
+    {
+      tryInvert(G,M,result,fail);
+      if(fail)
+        return;
+      result = 1;
+      return;
+    }
+    // try to make G monic modulo M
+    CanonicalForm inv;
+    tryInvert(Lc(G),M,inv,fail);
+    if(fail)
+      return;
+    result = inv*G;
+    result= reduce (result, M);
+    return;
+  }
+  if(G.isZero()) // F is non-zero
+  {
+    if(F.inCoeffDomain())
+    {
+      tryInvert(F,M,result,fail);
+      if(fail)
+        return;
+      result = 1;
+      return;
+    }
+    // try to make F monic modulo M
+    CanonicalForm inv;
+    tryInvert(Lc(F),M,inv,fail);
+    if(fail)
+      return;
+    result = inv*F;
+    result= reduce (result, M);
+    return;
+  }
+  // here: F,G both nonzero
+  if(F.inCoeffDomain())
+  {
+    tryInvert(F,M,result,fail);
+    if(fail)
+      return;
+    result = 1;
+    return;
+  }
+  if(G.inCoeffDomain())
+  {
+    tryInvert(G,M,result,fail);
+    if(fail)
+      return;
+    result = 1;
+    return;
+  }
+  TIMING_START (alg_compress)
+  CFMap MM,NN;
+  int lev= myCompress (F, G, MM, NN, topLevel);
+  if (lev == 0)
+  {
+    result= 1;
+    return;
+  }
+  CanonicalForm f=MM(F);
+  CanonicalForm g=MM(G);
+  TIMING_END_AND_PRINT (alg_compress, "time to compress in alg gcd: ")
+  // here: f,g are compressed
+  // compute largest variable in f or g (least one is Variable(1))
+  int mv = f.level();
+  if(g.level() > mv)
+    mv = g.level();
+  // here: mv is level of the largest variable in f, g
+  Variable v1= Variable (1);
+#ifdef HAVE_NTL
+  Variable v= M.mvar();
+  if (fac_NTL_char != getCharacteristic())
+  {
+    fac_NTL_char= getCharacteristic();
+    zz_p::init (getCharacteristic());
+  }
+  zz_pX NTLMipo= convertFacCF2NTLzzpX (M);
+  zz_pE::init (NTLMipo);
+  zz_pEX NTLResult;
+  zz_pEX NTLF;
+  zz_pEX NTLG;
+#endif
+  if(mv == 1) // f,g univariate
+  {
+    TIMING_START (alg_euclid_p)
+#ifdef HAVE_NTL
+    NTLF= convertFacCF2NTLzz_pEX (f, NTLMipo);
+    NTLG= convertFacCF2NTLzz_pEX (g, NTLMipo);
+    tryNTLGCD (NTLResult, NTLF, NTLG, fail);
+    if (fail)
+      return;
+    result= convertNTLzz_pEX2CF (NTLResult, f.mvar(), v);
+#else
+    tryEuclid(f,g,M,result,fail);
+    if(fail)
+      return;
+#endif
+    TIMING_END_AND_PRINT (alg_euclid_p, "time for euclidean alg mod p: ")
+    result= NN (reduce (result, M)); // do not forget to map back
+    return;
+  }
+  TIMING_START (alg_content_p)
+  // here: mv > 1
+  CanonicalForm cf = tryvcontent(f, Variable(2), M, fail); // cf is univariate poly in var(1)
+  if(fail)
+    return;
+  CanonicalForm cg = tryvcontent(g, Variable(2), M, fail);
+  if(fail)
+    return;
+  CanonicalForm c;
+#ifdef HAVE_NTL
+  NTLF= convertFacCF2NTLzz_pEX (cf, NTLMipo);
+  NTLG= convertFacCF2NTLzz_pEX (cg, NTLMipo);
+  tryNTLGCD (NTLResult, NTLF, NTLG, fail);
+  if (fail)
+    return;
+  c= convertNTLzz_pEX2CF (NTLResult, v1, v);
+#else
+  tryEuclid(cf,cg,M,c,fail);
+  if(fail)
+    return;
+#endif
+  // f /= cf
+  f.tryDiv (cf, M, fail);
+  if(fail)
+    return;
+  // g /= cg
+  g.tryDiv (cg, M, fail);
+  if(fail)
+    return;
+  TIMING_END_AND_PRINT (alg_content_p, "time for content in alg gcd mod p: ")
+  if(f.inCoeffDomain())
+  {
+    tryInvert(f,M,result,fail);
+    if(fail)
+      return;
+    result = NN(c);
+    return;
+  }
+  if(g.inCoeffDomain())
+  {
+    tryInvert(g,M,result,fail);
+    if(fail)
+      return;
+    result = NN(c);
+    return;
+  }
+  int *L = new int[mv+1]; // L is addressed by i from 2 to mv
+  int *N = new int[mv+1];
+  for(int i=2; i<=mv; i++)
+    L[i] = N[i] = 0;
+  L = leadDeg(f, L);
+  N = leadDeg(g, N);
+  CanonicalForm gamma;
+  TIMING_START (alg_euclid_p)
+#ifdef HAVE_NTL
+  NTLF= convertFacCF2NTLzz_pEX (firstLC (f), NTLMipo);
+  NTLG= convertFacCF2NTLzz_pEX (firstLC (g), NTLMipo);
+  tryNTLGCD (NTLResult, NTLF, NTLG, fail);
+  if (fail)
+    return;
+  gamma= convertNTLzz_pEX2CF (NTLResult, v1, v);
+#else
+  tryEuclid( firstLC(f), firstLC(g), M, gamma, fail );
+  if(fail)
+    return;
+#endif
+  TIMING_END_AND_PRINT (alg_euclid_p, "time for gcd of lcs in alg mod p: ")
+  for(int i=2; i<=mv; i++) // entries at i=0,1 not visited
+    if(N[i] < L[i])
+      L[i] = N[i];
+  // L is now upper bound for degrees of gcd
+  int *dg_im = new int[mv+1]; // for the degree vector of the image we don't need any entry at i=1
+  for(int i=2; i<=mv; i++)
+    dg_im[i] = 0; // initialize
+  CanonicalForm gamma_image, m=1;
+  CanonicalForm gm=0;
+  CanonicalForm g_image, alpha, gnew;
+  FFGenerator gen = FFGenerator();
+  Variable x= Variable (1);
+  bool divides= true;
+  for(FFGenerator gen = FFGenerator(); gen.hasItems(); gen.next())
+  {
+    alpha = gen.item();
+    gamma_image = reduce(gamma(alpha, x),M); // plug in alpha for var(1)
+    if(gamma_image.isZero()) // skip lc-bad points var(1)-alpha
+      continue;
+    TIMING_START (alg_recursion_p)
+    tryBrownGCD( f(alpha, x), g(alpha, x), M, g_image, fail, false ); // recursive call with one var less
+    TIMING_END_AND_PRINT (alg_recursion_p,
+                         "time for recursive calls in alg gcd mod p: ")
+    if(fail)
+      return;
+    g_image = reduce(g_image, M);
+    if(g_image.inCoeffDomain()) // early termination
+    {
+      tryInvert(g_image,M,result,fail);
+      if(fail)
+        return;
+      result = NN(c);
+      return;
+    }
+    for(int i=2; i<=mv; i++)
+      dg_im[i] = 0; // reset (this is necessary, because some entries may not be updated by call to leadDeg)
+    dg_im = leadDeg(g_image, dg_im); // dg_im cannot be NIL-pointer
+    if(isEqual(dg_im, L, 2, mv))
+    {
+      CanonicalForm inv;
+      tryInvert (firstLC (g_image), M, inv, fail);
+      if (fail)
+        return;
+      g_image *= inv;
+      g_image *= gamma_image; // multiply by multiple of image lc(gcd)
+      g_image= reduce (g_image, M);
+      TIMING_START (alg_newton_p)
+      gnew= tryNewtonInterp (alpha, g_image, m, gm, x, M, fail);
+      TIMING_END_AND_PRINT (alg_newton_p,
+                            "time for Newton interpolation in alg gcd mod p: ")
+      // gnew = gm mod m
+      // gnew = g_image mod var(1)-alpha
+      // mnew = m * (var(1)-alpha)
+      if(fail)
+        return;
+      m *= (x - alpha);
+      if((firstLC(gnew) == gamma) || (gnew == gm)) // gnew did not change
+      {
+        TIMING_START (alg_termination_p)
+        cf = tryvcontent(gnew, Variable(2), M, fail);
+        if(fail)
+          return;
+        divides = true;
+        g_image= gnew;
+        g_image.tryDiv (cf, M, fail);
+        if(fail)
+          return;
+        divides= tryFdivides (g_image,f, M, fail); // trial division (f)
+        if(fail)
+          return;
+        if(divides)
+        {
+          bool divides2= tryFdivides (g_image,g, M, fail); // trial division (g)
+          if(fail)
+            return;
+          if(divides2)
+          {
+            result = NN(reduce (c*g_image, M));
+            TIMING_END_AND_PRINT (alg_termination_p,
+                      "time for successful termination test in alg gcd mod p: ")
+            return;
+          }
+        }
+        TIMING_END_AND_PRINT (alg_termination_p,
+                    "time for unsuccessful termination test in alg gcd mod p: ")
+      }
+      gm = gnew;
+      continue;
+    }
+
+    if(isLess(L, dg_im, 2, mv)) // dg_im > L --> current point unlucky
+      continue;
+
+    // here: isLess(dg_im, L, 2, mv) --> all previous points were unlucky
+    m = CanonicalForm(1); // reset
+    gm = 0; // reset
+    for(int i=2; i<=mv; i++) // tighten bound
+      L[i] = dg_im[i];
+  }
+  // we are out of evaluation points
+  fail = true;
+}
+
+static CanonicalForm
+myicontent ( const CanonicalForm & f, const CanonicalForm & c )
+{
+#ifdef HAVE_NTL
+    if (f.isOne() || c.isOne())
+      return 1;
+    if ( f.inBaseDomain() && c.inBaseDomain())
+    {
+      if (c.isZero()) return abs(f);
+      return bgcd( f, c );
+    }
+    else if ( (f.inCoeffDomain() && c.inCoeffDomain()) ||
+              (f.inCoeffDomain() && c.inBaseDomain()) ||
+              (f.inBaseDomain() && c.inCoeffDomain()))
+    {
+      if (c.isZero()) return abs (f);
+#ifdef HAVE_FLINT
+      fmpz_poly_t FLINTf, FLINTc;
+      convertFacCF2Fmpz_poly_t (FLINTf, f);
+      convertFacCF2Fmpz_poly_t (FLINTc, c);
+      fmpz_poly_gcd (FLINTc, FLINTc, FLINTf);
+      CanonicalForm result;
+      if (f.inCoeffDomain())
+        result= convertFmpz_poly_t2FacCF (FLINTc, f.mvar());
+      else
+        result= convertFmpz_poly_t2FacCF (FLINTc, c.mvar());
+      fmpz_poly_clear (FLINTc);
+      fmpz_poly_clear (FLINTf);
+      return result;
+#else
+      ZZX NTLf= convertFacCF2NTLZZX (f);
+      ZZX NTLc= convertFacCF2NTLZZX (c);
+      NTLc= GCD (NTLc, NTLf);
+      if (f.inCoeffDomain())
+        return convertNTLZZX2CF(NTLc,f.mvar());
+      else
+        return convertNTLZZX2CF(NTLc,c.mvar());
+#endif
+    }
+    else
+    {
+        CanonicalForm g = c;
+        for ( CFIterator i = f; i.hasTerms() && ! g.isOne(); i++ )
+            g = myicontent( i.coeff(), g );
+        return g;
+    }
+#else
+    return 1;
+#endif
+}
+
+CanonicalForm
+myicontent ( const CanonicalForm & f )
+{
+#ifdef HAVE_NTL
+    return myicontent( f, 0 );
+#else
+    return 1;
+#endif
+}
+
+CanonicalForm QGCD( const CanonicalForm & F, const CanonicalForm & G )
+{ // f,g in Q(a)[x1,...,xn]
+  if(F.isZero())
+  {
+    if(G.isZero())
+      return G; // G is zero
+    if(G.inCoeffDomain())
+      return CanonicalForm(1);
+    CanonicalForm lcinv= 1/Lc (G);
+    return G*lcinv; // return monic G
+  }
+  if(G.isZero()) // F is non-zero
+  {
+    if(F.inCoeffDomain())
+      return CanonicalForm(1);
+    CanonicalForm lcinv= 1/Lc (F);
+    return F*lcinv; // return monic F
+  }
+  if(F.inCoeffDomain() || G.inCoeffDomain())
+    return CanonicalForm(1);
+  // here: both NOT inCoeffDomain
+  CanonicalForm f, g, tmp, M, q, D, Dp, cl, newq, mipo;
+  int p, i;
+  int *bound, *other; // degree vectors
+  bool fail;
+  bool off_rational=!isOn(SW_RATIONAL);
+  On( SW_RATIONAL ); // needed by bCommonDen
+  f = F * bCommonDen(F);
+  g = G * bCommonDen(G);
+  TIMING_START (alg_content)
+  CanonicalForm contf= myicontent (f);
+  CanonicalForm contg= myicontent (g);
+  f /= contf;
+  g /= contg;
+  CanonicalForm gcdcfcg= myicontent (contf, contg);
+  TIMING_END_AND_PRINT (alg_content, "time for content in alg gcd: ")
+  Variable a, b;
+  if(hasFirstAlgVar(f,a))
+  {
+    if(hasFirstAlgVar(g,b))
+    {
+      if(b.level() > a.level())
+        a = b;
+    }
+  }
+  else
+  {
+    if(!hasFirstAlgVar(g,a))// both not in extension
+    {
+      Off( SW_RATIONAL );
+      Off( SW_USE_QGCD );
+      tmp = gcdcfcg*gcd( f, g );
+      On( SW_USE_QGCD );
+      if (off_rational) Off(SW_RATIONAL);
+      return tmp;
+    }
+  }
+  // here: a is the biggest alg. var in f and g AND some of f,g is in extension
+  setReduce(a,false); // do not reduce expressions modulo mipo
+  tmp = getMipo(a);
+  M = tmp * bCommonDen(tmp);
+  // here: f, g in Z[a][x1,...,xn], M in Z[a] not necessarily monic
+  Off( SW_RATIONAL ); // needed by mod
+  // calculate upper bound for degree vector of gcd
+  int mv = f.level(); i = g.level();
+  if(i > mv)
+    mv = i;
+  // here: mv is level of the largest variable in f, g
+  bound = new int[mv+1]; // 'bound' could be indexed from 0 to mv, but we will only use from 1 to mv
+  other = new int[mv+1];
+  for(int i=1; i<=mv; i++) // initialize 'bound', 'other' with zeros
+    bound[i] = other[i] = 0;
+  bound = leadDeg(f,bound); // 'bound' is set the leading degree vector of f
+  other = leadDeg(g,other);
+  for(int i=1; i<=mv; i++) // entry at i=0 not visited
+    if(other[i] < bound[i])
+      bound[i] = other[i];
+  // now 'bound' is the smaller vector
+  cl = lc(M) * lc(f) * lc(g);
+  q = 1;
+  D = 0;
+  CanonicalForm test= 0;
+  bool equal= false;
+  for( i=cf_getNumBigPrimes()-1; i>-1; i-- )
+  {
+    p = cf_getBigPrime(i);
+    if( mod( cl, p ).isZero() ) // skip lc-bad primes
+      continue;
+    fail = false;
+    setCharacteristic(p);
+    mipo = mapinto(M);
+    mipo /= mipo.lc();
+    // here: mipo is monic
+    TIMING_START (alg_gcd_p)
+    tryBrownGCD( mapinto(f), mapinto(g), mipo, Dp, fail );
+    TIMING_END_AND_PRINT (alg_gcd_p, "time for alg gcd mod p: ")
+    if( fail ) // mipo splits in char p
+      continue;
+    if( Dp.inCoeffDomain() ) // early termination
+    {
+      tryInvert(Dp,mipo,tmp,fail); // check if zero divisor
+      if(fail)
+        continue;
+      setReduce(a,true);
+      if (off_rational) Off(SW_RATIONAL); else On(SW_RATIONAL);
+      setCharacteristic(0);
+      return gcdcfcg;
+    }
+    setCharacteristic(0);
+    // here: Dp NOT inCoeffDomain
+    for(int i=1; i<=mv; i++)
+      other[i] = 0; // reset (this is necessary, because some entries may not be updated by call to leadDeg)
+    other = leadDeg(Dp,other);
+
+    if(isEqual(bound, other, 1, mv)) // equal
+    {
+      chineseRemainder( D, q, mapinto(Dp), p, tmp, newq );
+      // tmp = Dp mod p
+      // tmp = D mod q
+      // newq = p*q
+      q = newq;
+      if( D != tmp )
+        D = tmp;
+      On( SW_RATIONAL );
+      TIMING_START (alg_reconstruction)
+      tmp = Farey( D, q ); // Farey
+      tmp *= bCommonDen (tmp);
+      TIMING_END_AND_PRINT (alg_reconstruction,
+                            "time for rational reconstruction in alg gcd: ")
+      setReduce(a,true); // reduce expressions modulo mipo
+      On( SW_RATIONAL ); // needed by fdivides
+      if (test != tmp)
+        test= tmp;
+      else
+        equal= true; // modular image did not add any new information
+      TIMING_START (alg_termination)
+#ifdef HAVE_NTL
+#ifdef HAVE_FLINT
+      if (equal && tmp.isUnivariate() && f.isUnivariate() && g.isUnivariate()
+          && f.level() == tmp.level() && tmp.level() == g.level())
+      {
+        CanonicalForm Q, R;
+        newtonDivrem (f, tmp, Q, R);
+        if (R.isZero())
+        {
+          newtonDivrem (g, tmp, Q, R);
+          if (R.isZero())
+          {
+            Off (SW_RATIONAL);
+            setReduce (a,true);
+            if (off_rational) Off(SW_RATIONAL); else On(SW_RATIONAL);
+            TIMING_END_AND_PRINT (alg_termination,
+                                 "time for successful termination test in alg gcd: ")
+            return tmp*gcdcfcg;
+          }
+        }
+      }
+      else
+#endif
+#endif
+      if(equal && fdivides( tmp, f ) && fdivides( tmp, g )) // trial division
+      {
+        Off( SW_RATIONAL );
+        setReduce(a,true);
+        if (off_rational) Off(SW_RATIONAL); else On(SW_RATIONAL);
+        TIMING_END_AND_PRINT (alg_termination,
+                            "time for successful termination test in alg gcd: ")
+        return tmp*gcdcfcg;
+      }
+      TIMING_END_AND_PRINT (alg_termination,
+                          "time for unsuccessful termination test in alg gcd: ")
+      Off( SW_RATIONAL );
+      setReduce(a,false); // do not reduce expressions modulo mipo
+      continue;
+    }
+    if( isLess(bound, other, 1, mv) ) // current prime unlucky
+      continue;
+    // here: isLess(other, bound, 1, mv) ) ==> all previous primes unlucky
+    q = p;
+    D = mapinto(Dp); // shortcut CRA // shortcut CRA
+    for(int i=1; i<=mv; i++) // tighten bound
+      bound[i] = other[i];
+  }
+  // hopefully, we never reach this point
+  setReduce(a,true);
+  Off( SW_USE_QGCD );
+  D = gcdcfcg*gcd( f, g );
+  On( SW_USE_QGCD );
+  if (off_rational) Off(SW_RATIONAL); else On(SW_RATIONAL);
+  return D;
+}
+
+
+int * leadDeg(const CanonicalForm & f, int *degs)
+{ // leading degree vector w.r.t. lex. monomial order x(i+1) > x(i)
+  // if f is in a coeff domain, the zero pointer is returned
+  // 'a' should point to an array of sufficient size level(f)+1
+  if(f.inCoeffDomain())
+    return 0;
+  CanonicalForm tmp = f;
+  do
+  {
+    degs[tmp.level()] = tmp.degree();
+    tmp = LC(tmp);
+  }
+  while(!tmp.inCoeffDomain());
+  return degs;
+}
+
+
+bool isLess(int *a, int *b, int lower, int upper)
+{ // compares the degree vectors a,b on the specified part. Note: x(i+1) > x(i)
+  for(int i=upper; i>=lower; i--)
+    if(a[i] == b[i])
+      continue;
+    else
+      return a[i] < b[i];
+  return true;
+}
+
+
+bool isEqual(int *a, int *b, int lower, int upper)
+{ // compares the degree vectors a,b on the specified part. Note: x(i+1) > x(i)
+  for(int i=lower; i<=upper; i++)
+    if(a[i] != b[i])
+      return false;
+  return true;
+}
+
+
+CanonicalForm firstLC(const CanonicalForm & f)
+{ // returns the leading coefficient (LC) of level <= 1
+  CanonicalForm ret = f;
+  while(ret.level() > 1)
+    ret = LC(ret);
+  return ret;
+}
+
+#ifndef HAVE_NTL
+void tryExtgcd( const CanonicalForm & F, const CanonicalForm & G, const CanonicalForm & M, CanonicalForm & result, CanonicalForm & s, CanonicalForm & t, bool & fail )
+{ // F, G are univariate polynomials (i.e. they have exactly one polynomial variable)
+  // F and G must have the same level AND level > 0
+  // we try to calculate gcd(F,G) = s*F + t*G
+  // if a zero divisor is encountered, 'fail' is set to one
+  // M is assumed to be monic
+  CanonicalForm P;
+  if(F.inCoeffDomain())
+  {
+    tryInvert( F, M, P, fail );
+    if(fail)
+      return;
+    result = 1;
+    s = P; t = 0;
+    return;
+  }
+  if(G.inCoeffDomain())
+  {
+    tryInvert( G, M, P, fail );
+    if(fail)
+      return;
+    result = 1;
+    s = 0; t = P;
+    return;
+  }
+  // here: both not inCoeffDomain
+  CanonicalForm inv, rem, tmp, u, v, q, sum=0;
+  if( F.degree() > G.degree() )
+  {
+    P = F; result = G;  s=v=0; t=u=1;
+  }
+  else
+  {
+    P = G; result = F; s=v=1; t=u=0;
+  }
+  Variable x = P.mvar();
+  // here: degree(P) >= degree(result)
+  while(true)
+  {
+    tryDivrem (P, result, q, rem, inv, M, fail);
+    if(fail)
+      return;
+    if( rem.isZero() )
+    {
+      s*=inv;
+      s= reduce (s, M);
+      t*=inv;
+      t= reduce (t, M);
+      result *= inv; // monify result
+      result= reduce (result, M);
+      return;
+    }
+    sum += q;
+    if(result.degree(x) >= rem.degree(x))
+    {
+      P=result;
+      result=rem;
+      tmp=u-sum*s;
+      u=s;
+      s=tmp;
+      tmp=v-sum*t;
+      v=t;
+      t=tmp;
+      sum = 0; // reset
+    }
+    else
+      P = rem;
+  }
+}
+#endif
+
+static CanonicalForm trycontent ( const CanonicalForm & f, const Variable & x, const CanonicalForm & M, bool & fail )
+{ // as 'content', but takes care of zero divisors
+  ASSERT( x.level() > 0, "cannot calculate content with respect to algebraic variable" );
+  Variable y = f.mvar();
+  if ( y == x )
+    return trycf_content( f, 0, M, fail );
+  if ( y < x )
+     return f;
+  return swapvar( trycontent( swapvar( f, y, x ), y, M, fail ), y, x );
+}
+
+
+static CanonicalForm tryvcontent ( const CanonicalForm & f, const Variable & x, const CanonicalForm & M, bool & fail )
+{ // as vcontent, but takes care of zero divisors
+  ASSERT( x.level() > 0, "cannot calculate vcontent with respect to algebraic variable" );
+  if ( f.mvar() <= x )
+    return trycontent( f, x, M, fail );
+  CFIterator i;
+  CanonicalForm d = 0, e, ret;
+  for ( i = f; i.hasTerms() && ! d.isOne() && ! fail; i++ )
+  {
+    e = tryvcontent( i.coeff(), x, M, fail );
+    if(fail)
+      break;
+    tryBrownGCD( d, e, M, ret, fail );
+    d = ret;
+  }
+  return d;
+}
+
+
+static CanonicalForm trycf_content ( const CanonicalForm & f, const CanonicalForm & g, const CanonicalForm & M, bool & fail )
+{ // as cf_content, but takes care of zero divisors
+  if ( f.inPolyDomain() || ( f.inExtension() && ! getReduce( f.mvar() ) ) )
+  {
+    CFIterator i = f;
+    CanonicalForm tmp = g, result;
+    while ( i.hasTerms() && ! tmp.isOne() && ! fail )
+    {
+      tryBrownGCD( i.coeff(), tmp, M, result, fail );
+      tmp = result;
+      i++;
+    }
+    return result;
+  }
+  return abs( f );
+}
+
diff --git a/factory/cfGcdAlgExt.h b/factory/cfGcdAlgExt.h
new file mode 100644
index 0000000..4d04da3
--- /dev/null
+++ b/factory/cfGcdAlgExt.h
@@ -0,0 +1,43 @@
+/**
+ * @file cfGcdAlgExt.h
+ *
+ * GCD over Q(a)
+ *
+ * ABSTRACT: Implementation of Encarnacion's GCD algorithm over number fields,
+ * see M.J. Encarnacion "Computing GCDs of polynomials over number fields",
+ * extended to the multivariate case.
+ *
+ * @sa cfNTLzzpEXGCD.h
+**/
+
+#ifndef CF_GCD_ALGEXT_H
+#define CF_GCD_ALGEXT_H
+
+// #include "config.h"
+
+#include "canonicalform.h"
+#include "variable.h"
+
+/// gcd over Q(a)
+CanonicalForm QGCD( const CanonicalForm &, const CanonicalForm & );
+
+#ifndef HAVE_NTL
+void tryDivrem (const CanonicalForm&, const CanonicalForm&, CanonicalForm&,
+                CanonicalForm&, CanonicalForm&, const CanonicalForm&,
+                bool&);
+void tryEuclid( const CanonicalForm &, const CanonicalForm &, const CanonicalForm &, CanonicalForm &, bool & );
+void tryExtgcd( const CanonicalForm & F, const CanonicalForm & G, const CanonicalForm& M, CanonicalForm & result, CanonicalForm & s, CanonicalForm & t, bool & fail );
+#endif
+void tryInvert( const CanonicalForm &, const CanonicalForm &, CanonicalForm &, bool & );
+
+/// modular gcd over F_p[x]/(M) for not necessarily irreducible M.
+/// If a zero divisor is encountered fail is set to true.
+void tryBrownGCD( const CanonicalForm & F, const CanonicalForm & G, const CanonicalForm & M, CanonicalForm & result, bool & fail, bool topLevel= true );
+
+int * leadDeg(const CanonicalForm & f, int *degs);
+bool isLess(int *a, int *b, int lower, int upper);
+bool isEqual(int *a, int *b, int lower, int upper);
+CanonicalForm firstLC(const CanonicalForm & f);
+
+#endif
+
diff --git a/factory/cfGcdUtil.cc b/factory/cfGcdUtil.cc
new file mode 100644
index 0000000..cad7b35
--- /dev/null
+++ b/factory/cfGcdUtil.cc
@@ -0,0 +1,281 @@
+#include "config.h"
+
+#include "canonicalform.h"
+#include "cf_factory.h"
+#include "cf_reval.h"
+#include "cf_util.h"
+#include "cf_iter.h"
+#include "gfops.h"
+#include "cf_map_ext.h"
+#include "templates/ftmpl_functions.h"
+
+#ifdef HAVE_NTL
+#include "NTLconvert.h"
+#endif
+
+/// Coprimality Check. f and g are assumed to have the same level. If swap is
+/// true, the main variables of f and g are swapped with Variable(1). If the
+/// result is false, d is set to the degree of the gcd of f and g evaluated at a
+/// random point in K^n-1. This gcd is a gcd of univariate polynomials.
+bool
+gcd_test_one ( const CanonicalForm & f, const CanonicalForm & g, bool swap, int & d )
+{
+    d= 0;
+    int count = 0;
+    // assume polys have same level;
+
+    Variable v= Variable (1);
+    bool algExtension= (hasFirstAlgVar (f, v) || hasFirstAlgVar (g, v));
+    CanonicalForm lcf, lcg;
+    if ( swap )
+    {
+        lcf = swapvar( LC( f ), Variable(1), f.mvar() );
+        lcg = swapvar( LC( g ), Variable(1), f.mvar() );
+    }
+    else
+    {
+        lcf = LC( f, Variable(1) );
+        lcg = LC( g, Variable(1) );
+    }
+
+    CanonicalForm F, G;
+    if ( swap )
+    {
+        F=swapvar( f, Variable(1), f.mvar() );
+        G=swapvar( g, Variable(1), g.mvar() );
+    }
+    else
+    {
+        F = f;
+        G = g;
+    }
+
+    #define TEST_ONE_MAX 50
+    int p= getCharacteristic();
+    bool passToGF= false;
+    int k= 1;
+    bool extOfExt= false;
+    Variable v3;
+    if (p > 0 && p < TEST_ONE_MAX && CFFactory::gettype() != GaloisFieldDomain && !algExtension)
+    {
+      if (p == 2)
+        setCharacteristic (2, 6, 'Z');
+      else if (p == 3)
+        setCharacteristic (3, 4, 'Z');
+      else if (p == 5 || p == 7)
+        setCharacteristic (p, 3, 'Z');
+      else
+        setCharacteristic (p, 2, 'Z');
+      passToGF= true;
+    }
+    else if (p > 0 && CFFactory::gettype() == GaloisFieldDomain && ipower (p , getGFDegree()) < TEST_ONE_MAX)
+    {
+      k= getGFDegree();
+      if (ipower (p, 2*k) > TEST_ONE_MAX)
+        setCharacteristic (p, 2*k, gf_name);
+      else
+        setCharacteristic (p, 3*k, gf_name);
+      F= GFMapUp (F, k);
+      G= GFMapUp (G, k);
+      lcf= GFMapUp (lcf, k);
+      lcg= GFMapUp (lcg, k);
+    }
+    else if (p > 0 && p < TEST_ONE_MAX && algExtension)
+    {
+#ifdef HAVE_NTL
+      int d= degree (getMipo (v));
+      CFList source, dest;
+      Variable v2;
+      CanonicalForm primElem, imPrimElem;
+      if (p == 2 && d < 6)
+      {
+        if (fac_NTL_char != 2)
+        {
+          fac_NTL_char= 2;
+          zz_p::init (p);
+        }
+        bool primFail= false;
+        Variable vBuf;
+        primElem= primitiveElement (v, vBuf, primFail);
+        ASSERT (!primFail, "failure in integer factorizer");
+        if (d < 3)
+        {
+          zz_pX NTLIrredpoly;
+          BuildIrred (NTLIrredpoly, d*3);
+          CanonicalForm newMipo= convertNTLzzpX2CF (NTLIrredpoly, Variable (1));
+          v2= rootOf (newMipo);
+        }
+        else
+        {
+          zz_pX NTLIrredpoly;
+          BuildIrred (NTLIrredpoly, d*2);
+          CanonicalForm newMipo= convertNTLzzpX2CF (NTLIrredpoly, Variable (1));
+          v2= rootOf (newMipo);
+        }
+        imPrimElem= mapPrimElem (primElem, v, v2);
+        extOfExt= true;
+      }
+      else if ((p == 3 && d < 4) || ((p == 5 || p == 7) && d < 3))
+      {
+        if (fac_NTL_char != p)
+        {
+          fac_NTL_char= p;
+          zz_p::init (p);
+        }
+        bool primFail= false;
+        Variable vBuf;
+        primElem= primitiveElement (v, vBuf, primFail);
+        ASSERT (!primFail, "failure in integer factorizer");
+        zz_pX NTLIrredpoly;
+        BuildIrred (NTLIrredpoly, d*2);
+        CanonicalForm newMipo= convertNTLzzpX2CF (NTLIrredpoly, Variable (1));
+        v2= rootOf (newMipo);
+        imPrimElem= mapPrimElem (primElem, v, v2);
+        extOfExt= true;
+      }
+      if (extOfExt)
+      {
+        v3= v;
+        F= mapUp (F, v, v2, primElem, imPrimElem, source, dest);
+        G= mapUp (G, v, v2, primElem, imPrimElem, source, dest);
+        lcf= mapUp (lcf, v, v2, primElem, imPrimElem, source, dest);
+        lcg= mapUp (lcg, v, v2, primElem, imPrimElem, source, dest);
+        v= v2;
+      }
+#endif
+    }
+
+    CFRandom * sample;
+    if ((!algExtension && p > 0) || p == 0)
+      sample = CFRandomFactory::generate();
+    else
+      sample = AlgExtRandomF (v).clone();
+
+    REvaluation e( 2, tmax( f.level(), g.level() ), *sample );
+    delete sample;
+
+    if (passToGF)
+    {
+      lcf= lcf.mapinto();
+      lcg= lcg.mapinto();
+    }
+
+    CanonicalForm eval1, eval2;
+    if (passToGF)
+    {
+      eval1= e (lcf);
+      eval2= e (lcg);
+    }
+    else
+    {
+      eval1= e (lcf);
+      eval2= e (lcg);
+    }
+
+    while ( ( eval1.isZero() || eval2.isZero() ) && count < TEST_ONE_MAX )
+    {
+        e.nextpoint();
+        count++;
+        eval1= e (lcf);
+        eval2= e (lcg);
+    }
+    if ( count >= TEST_ONE_MAX )
+    {
+        if (passToGF)
+          setCharacteristic (p);
+        if (k > 1)
+          setCharacteristic (p, k, gf_name);
+        if (extOfExt)
+          prune1 (v3);
+        return false;
+    }
+
+
+    if (passToGF)
+    {
+      F= F.mapinto();
+      G= G.mapinto();
+      eval1= e (F);
+      eval2= e (G);
+    }
+    else
+    {
+      eval1= e (F);
+      eval2= e (G);
+    }
+
+    CanonicalForm c= gcd (eval1, eval2);
+    d= c.degree();
+    bool result= d < 1;
+    if (d < 0)
+      d= 0;
+
+    if (passToGF)
+      setCharacteristic (p);
+    if (k > 1)
+      setCharacteristic (p, k, gf_name);
+    if (extOfExt)
+      prune1 (v3);
+    return result;
+}
+
+/**
+ * same as balance_p ( const CanonicalForm & f, const CanonicalForm & q )
+ * but qh= q/2 is provided, too.
+**/
+CanonicalForm
+balance_p ( const CanonicalForm & f, const CanonicalForm & q, const CanonicalForm & qh )
+{
+    Variable x = f.mvar();
+    CanonicalForm result = 0;
+    CanonicalForm c;
+    CFIterator i;
+    for ( i = f; i.hasTerms(); i++ )
+    {
+        c = i.coeff();
+        if ( c.inCoeffDomain())
+        {
+          if ( c > qh )
+            result += power( x, i.exp() ) * (c - q);
+          else
+            result += power( x, i.exp() ) * c;
+        }
+        else
+          result += power( x, i.exp() ) * balance_p(c,q,qh);
+    }
+    return result;
+}
+
+/** static CanonicalForm balance_p ( const CanonicalForm & f, const CanonicalForm & q )
+ *
+ * balance_p() - map f from positive to symmetric representation
+ *   mod q.
+ *
+ * This makes sense for polynomials over Z only.
+ * q should be an integer.
+ *
+**/
+CanonicalForm
+balance_p ( const CanonicalForm & f, const CanonicalForm & q )
+{
+    CanonicalForm qh = q / 2;
+    return balance_p (f, q, qh);
+}
+
+
+/*static CanonicalForm
+balance ( const CanonicalForm & f, const CanonicalForm & q )
+{
+    Variable x = f.mvar();
+    CanonicalForm result = 0, qh = q / 2;
+    CanonicalForm c;
+    CFIterator i;
+    for ( i = f; i.hasTerms(); i++ ) {
+        c = mod( i.coeff(), q );
+        if ( c > qh )
+            result += power( x, i.exp() ) * (c - q);
+        else
+            result += power( x, i.exp() ) * c;
+    }
+    return result;
+}*/
diff --git a/factory/cfGcdUtil.h b/factory/cfGcdUtil.h
new file mode 100644
index 0000000..95f3276
--- /dev/null
+++ b/factory/cfGcdUtil.h
@@ -0,0 +1,17 @@
+/**
+ * @file cfGcdUtil.h
+ *
+ * coprimality check and change of representation mod n
+**/
+
+#ifndef CF_GCD_UTIL_H
+#define CF_GCD_UTIL_H
+bool
+gcd_test_one ( const CanonicalForm & f, const CanonicalForm & g, bool swap, int & d );
+
+CanonicalForm
+balance_p ( const CanonicalForm & f, const CanonicalForm & q, const CanonicalForm & qh );
+
+CanonicalForm
+balance_p ( const CanonicalForm & f, const CanonicalForm & q );
+#endif
diff --git a/factory/cfModGcd.cc b/factory/cfModGcd.cc
new file mode 100644
index 0000000..28448f6
--- /dev/null
+++ b/factory/cfModGcd.cc
@@ -0,0 +1,4202 @@
+// -*- c++ -*-
+//*****************************************************************************
+/** @file cfModGcd.cc
+ *
+ * This file implements the GCD of two polynomials over \f$ F_{p} \f$ ,
+ * \f$ F_{p}(\alpha ) \f$, GF or Z based on Alg. 7.1. and 7.2. as described in
+ * "Algorithms for Computer Algebra" by Geddes, Czapor, Labahn via modular
+ * computations. And sparse modular variants as described in Zippel
+ * "Effective Polynomial Computation", deKleine, Monagan, Wittkopf
+ * "Algorithms for the non-monic case of the sparse modular GCD algorithm" and
+ * Javadi "A new solution to the normalization problem"
+ *
+ * @author Martin Lee
+ * @date 22.10.2009
+ *
+ * @par Copyright:
+ *   (c) by The SINGULAR Team, see LICENSE file
+ *
+**/
+//*****************************************************************************
+
+
+#include "config.h"
+
+
+#include "cf_assert.h"
+#include "debug.h"
+#include "timing.h"
+
+#include "canonicalform.h"
+#include "cfGcdUtil.h"
+#include "cf_map.h"
+#include "cf_util.h"
+#include "cf_irred.h"
+#include "templates/ftmpl_functions.h"
+#include "cf_random.h"
+#include "cf_reval.h"
+#include "facHensel.h"
+#include "cf_iter.h"
+#include "cfNewtonPolygon.h"
+#include "cf_algorithm.h"
+#include "cf_primes.h"
+
+// inline helper functions:
+#include "cf_map_ext.h"
+
+#ifdef HAVE_NTL
+#include <NTLconvert.h>
+#endif
+
+#ifdef HAVE_FLINT
+#include "FLINTconvert.h"
+#endif
+
+#include "cfModGcd.h"
+
+TIMING_DEFINE_PRINT(gcd_recursion)
+TIMING_DEFINE_PRINT(newton_interpolation)
+TIMING_DEFINE_PRINT(termination_test)
+TIMING_DEFINE_PRINT(ez_p_compress)
+TIMING_DEFINE_PRINT(ez_p_hensel_lift)
+TIMING_DEFINE_PRINT(ez_p_eval)
+TIMING_DEFINE_PRINT(ez_p_content)
+
+bool
+terminationTest (const CanonicalForm& F, const CanonicalForm& G,
+                 const CanonicalForm& coF, const CanonicalForm& coG,
+                 const CanonicalForm& cand)
+{
+  CanonicalForm LCCand= abs (LC (cand));
+  if (LCCand*abs (LC (coF)) == abs (LC (F)))
+  {
+    if (LCCand*abs (LC (coG)) == abs (LC (G)))
+    {
+      if (abs (cand)*abs (coF) == abs (F))
+      {
+        if (abs (cand)*abs (coG) == abs (G))
+          return true;
+      }
+      return false;
+    }
+    return false;
+  }
+  return false;
+}
+
+#ifdef HAVE_NTL
+
+static const double log2exp= 1.442695041;
+
+/// compressing two polynomials F and G, M is used for compressing,
+/// N to reverse the compression
+int myCompress (const CanonicalForm& F, const CanonicalForm& G, CFMap & M,
+                CFMap & N, bool topLevel)
+{
+  int n= tmax (F.level(), G.level());
+  int * degsf= new int [n + 1];
+  int * degsg= new int [n + 1];
+
+  for (int i = 0; i <= n; i++)
+    degsf[i]= degsg[i]= 0;
+
+  degsf= degrees (F, degsf);
+  degsg= degrees (G, degsg);
+
+  int both_non_zero= 0;
+  int f_zero= 0;
+  int g_zero= 0;
+  int both_zero= 0;
+
+  if (topLevel)
+  {
+    for (int i= 1; i <= n; i++)
+    {
+      if (degsf[i] != 0 && degsg[i] != 0)
+      {
+        both_non_zero++;
+        continue;
+      }
+      if (degsf[i] == 0 && degsg[i] != 0 && i <= G.level())
+      {
+        f_zero++;
+        continue;
+      }
+      if (degsg[i] == 0 && degsf[i] && i <= F.level())
+      {
+        g_zero++;
+        continue;
+      }
+    }
+
+    if (both_non_zero == 0)
+    {
+      delete [] degsf;
+      delete [] degsg;
+      return 0;
+    }
+
+    // map Variables which do not occur in both polynomials to higher levels
+    int k= 1;
+    int l= 1;
+    for (int i= 1; i <= n; i++)
+    {
+      if (degsf[i] != 0 && degsg[i] == 0 && i <= F.level())
+      {
+        if (k + both_non_zero != i)
+        {
+          M.newpair (Variable (i), Variable (k + both_non_zero));
+          N.newpair (Variable (k + both_non_zero), Variable (i));
+        }
+        k++;
+      }
+      if (degsf[i] == 0 && degsg[i] != 0 && i <= G.level())
+      {
+        if (l + g_zero + both_non_zero != i)
+        {
+          M.newpair (Variable (i), Variable (l + g_zero + both_non_zero));
+          N.newpair (Variable (l + g_zero + both_non_zero), Variable (i));
+        }
+        l++;
+      }
+    }
+
+    // sort Variables x_{i} in increasing order of
+    // min(deg_{x_{i}}(f),deg_{x_{i}}(g))
+    int m= tmax (F.level(), G.level());
+    int min_max_deg;
+    k= both_non_zero;
+    l= 0;
+    int i= 1;
+    while (k > 0)
+    {
+      if (degsf [i] != 0 && degsg [i] != 0)
+        min_max_deg= tmax (degsf[i], degsg[i]);
+      else
+        min_max_deg= 0;
+      while (min_max_deg == 0)
+      {
+        i++;
+        if (degsf [i] != 0 && degsg [i] != 0)
+          min_max_deg= tmax (degsf[i], degsg[i]);
+        else
+          min_max_deg= 0;
+      }
+      for (int j= i + 1; j <=  m; j++)
+      {
+        if (degsf[j] != 0 && degsg [j] != 0 &&
+            tmax (degsf[j],degsg[j]) <= min_max_deg)
+        {
+          min_max_deg= tmax (degsf[j], degsg[j]);
+          l= j;
+        }
+      }
+      if (l != 0)
+      {
+        if (l != k)
+        {
+          M.newpair (Variable (l), Variable(k));
+          N.newpair (Variable (k), Variable(l));
+          degsf[l]= 0;
+          degsg[l]= 0;
+          l= 0;
+        }
+        else
+        {
+          degsf[l]= 0;
+          degsg[l]= 0;
+          l= 0;
+        }
+      }
+      else if (l == 0)
+      {
+        if (i != k)
+        {
+          M.newpair (Variable (i), Variable (k));
+          N.newpair (Variable (k), Variable (i));
+          degsf[i]= 0;
+          degsg[i]= 0;
+        }
+        else
+        {
+          degsf[i]= 0;
+          degsg[i]= 0;
+        }
+        i++;
+      }
+      k--;
+    }
+  }
+  else
+  {
+    //arrange Variables such that no gaps occur
+    for (int i= 1; i <= n; i++)
+    {
+      if (degsf[i] == 0 && degsg[i] == 0)
+      {
+        both_zero++;
+        continue;
+      }
+      else
+      {
+        if (both_zero != 0)
+        {
+          M.newpair (Variable (i), Variable (i - both_zero));
+          N.newpair (Variable (i - both_zero), Variable (i));
+        }
+      }
+    }
+  }
+
+  delete [] degsf;
+  delete [] degsg;
+
+  return 1;
+}
+
+static inline CanonicalForm
+uni_content (const CanonicalForm & F);
+
+CanonicalForm
+uni_content (const CanonicalForm& F, const Variable& x)
+{
+  if (F.inCoeffDomain())
+    return F.genOne();
+  if (F.level() == x.level() && F.isUnivariate())
+    return F;
+  if (F.level() != x.level() && F.isUnivariate())
+    return F.genOne();
+
+  if (x.level() != 1)
+  {
+    CanonicalForm f= swapvar (F, x, Variable (1));
+    CanonicalForm result= uni_content (f);
+    return swapvar (result, x, Variable (1));
+  }
+  else
+    return uni_content (F);
+}
+
+/// compute the content of F, where F is considered as an element of
+/// \f$ R[x_{1}][x_{2},\ldots ,x_{n}] \f$
+static inline CanonicalForm
+uni_content (const CanonicalForm & F)
+{
+  if (F.inBaseDomain())
+    return F.genOne();
+  if (F.level() == 1 && F.isUnivariate())
+    return F;
+  if (F.level() != 1 && F.isUnivariate())
+    return F.genOne();
+  if (degree (F,1) == 0) return F.genOne();
+
+  int l= F.level();
+  if (l == 2)
+    return content(F);
+  else
+  {
+    CanonicalForm pol, c = 0;
+    CFIterator i = F;
+    for (; i.hasTerms(); i++)
+    {
+      pol= i.coeff();
+      pol= uni_content (pol);
+      c= gcd (c, pol);
+      if (c.isOne())
+        return c;
+    }
+    return c;
+  }
+}
+
+CanonicalForm
+extractContents (const CanonicalForm& F, const CanonicalForm& G,
+                 CanonicalForm& contentF, CanonicalForm& contentG,
+                 CanonicalForm& ppF, CanonicalForm& ppG, const int d)
+{
+  CanonicalForm uniContentF, uniContentG, gcdcFcG;
+  contentF= 1;
+  contentG= 1;
+  ppF= F;
+  ppG= G;
+  CanonicalForm result= 1;
+  for (int i= 1; i <= d; i++)
+  {
+    uniContentF= uni_content (F, Variable (i));
+    uniContentG= uni_content (G, Variable (i));
+    gcdcFcG= gcd (uniContentF, uniContentG);
+    contentF *= uniContentF;
+    contentG *= uniContentG;
+    ppF /= uniContentF;
+    ppG /= uniContentG;
+    result *= gcdcFcG;
+  }
+  return result;
+}
+
+/// compute the leading coefficient of F, where F is considered as an element
+/// of \f$ R[x_{1}][x_{2},\ldots ,x_{n}] \f$, order on
+/// \f$ Mon (x_{2},\ldots ,x_{n}) \f$ is dp.
+static inline
+CanonicalForm uni_lcoeff (const CanonicalForm& F)
+{
+  if (F.level() > 1)
+  {
+    Variable x= Variable (2);
+    int deg= totaldegree (F, x, F.mvar());
+    for (CFIterator i= F; i.hasTerms(); i++)
+    {
+      if (i.exp() + totaldegree (i.coeff(), x, i.coeff().mvar()) == deg)
+        return uni_lcoeff (i.coeff());
+    }
+  }
+  return F;
+}
+
+/// Newton interpolation - Incremental algorithm.
+/// Given a list of values alpha_i and a list of polynomials u_i, 1 <= i <= n,
+/// computes the interpolation polynomial assuming that
+/// the polynomials in u are the results of evaluating the variabe x
+/// of the unknown polynomial at the alpha values.
+/// This incremental version receives only the values of alpha_n and u_n and
+/// the previous interpolation polynomial for points 1 <= i <= n-1, and computes
+/// the polynomial interpolating in all the points.
+/// newtonPoly must be equal to (x - alpha_1) * ... * (x - alpha_{n-1})
+static inline CanonicalForm
+newtonInterp(const CanonicalForm & alpha, const CanonicalForm & u,
+             const CanonicalForm & newtonPoly, const CanonicalForm & oldInterPoly,
+             const Variable & x)
+{
+  CanonicalForm interPoly;
+
+  interPoly= oldInterPoly + ((u - oldInterPoly(alpha, x))/newtonPoly(alpha, x))
+             *newtonPoly;
+  return interPoly;
+}
+
+/// compute a random element a of \f$ F_{p}(\alpha ) \f$ ,
+/// s.t. F(a) \f$ \neq 0 \f$ , F is a univariate polynomial, returns
+/// fail if there are no field elements left which have not been used before
+static inline CanonicalForm
+randomElement (const CanonicalForm & F, const Variable & alpha, CFList & list,
+               bool & fail)
+{
+  fail= false;
+  Variable x= F.mvar();
+  AlgExtRandomF genAlgExt (alpha);
+  FFRandom genFF;
+  CanonicalForm random, mipo;
+  mipo= getMipo (alpha);
+  int p= getCharacteristic ();
+  int d= degree (mipo);
+  double bound= pow ((double) p, (double) d);
+  do
+  {
+    if (list.length() == bound)
+    {
+      fail= true;
+      break;
+    }
+    if (list.length() < p)
+    {
+      random= genFF.generate();
+      while (find (list, random))
+        random= genFF.generate();
+    }
+    else
+    {
+      random= genAlgExt.generate();
+      while (find (list, random))
+        random= genAlgExt.generate();
+    }
+    if (F (random, x) == 0)
+    {
+      list.append (random);
+      continue;
+    }
+  } while (find (list, random));
+  return random;
+}
+
+static inline
+Variable chooseExtension (const Variable & alpha)
+{
+  if (fac_NTL_char != getCharacteristic())
+  {
+    fac_NTL_char= getCharacteristic();
+    zz_p::init (getCharacteristic());
+  }
+  zz_pX NTLIrredpoly;
+  int i, m;
+  // extension of F_p needed
+  if (alpha.level() == 1)
+  {
+    i= 1;
+    m= 2;
+  } //extension of F_p(alpha)
+  if (alpha.level() != 1)
+  {
+    i= 4;
+    m= degree (getMipo (alpha));
+  }
+  BuildIrred (NTLIrredpoly, i*m);
+  CanonicalForm newMipo= convertNTLzzpX2CF (NTLIrredpoly, Variable (1));
+  return rootOf (newMipo);
+}
+
+CanonicalForm
+modGCDFq (const CanonicalForm& F, const CanonicalForm& G,
+                  CanonicalForm& coF, CanonicalForm& coG,
+                  Variable & alpha, CFList& l, bool& topLevel);
+
+CanonicalForm
+modGCDFq (const CanonicalForm& F, const CanonicalForm& G,
+                  Variable & alpha, CFList& l, bool& topLevel)
+{
+  CanonicalForm dummy1, dummy2;
+  CanonicalForm result= modGCDFq (F, G, dummy1, dummy2, alpha, l,
+                                          topLevel);
+  return result;
+}
+
+/// GCD of F and G over \f$ F_{p}(\alpha ) \f$ ,
+/// l and topLevel are only used internally, output is monic
+/// based on Alg. 7.2. as described in "Algorithms for
+/// Computer Algebra" by Geddes, Czapor, Labahn
+CanonicalForm
+modGCDFq (const CanonicalForm& F, const CanonicalForm& G,
+                  CanonicalForm& coF, CanonicalForm& coG,
+                  Variable & alpha, CFList& l, bool& topLevel)
+{
+  CanonicalForm A= F;
+  CanonicalForm B= G;
+  if (F.isZero() && degree(G) > 0)
+  {
+    coF= 0;
+    coG= Lc (G);
+    return G/Lc(G);
+  }
+  else if (G.isZero() && degree (F) > 0)
+  {
+    coF= Lc (F);
+    coG= 0;
+    return F/Lc(F);
+  }
+  else if (F.isZero() && G.isZero())
+  {
+    coF= coG= 0;
+    return F.genOne();
+  }
+  if (F.inBaseDomain() || G.inBaseDomain())
+  {
+    coF= F;
+    coG= G;
+    return F.genOne();
+  }
+  if (F.isUnivariate() && fdivides(F, G, coG))
+  {
+    coF= Lc (F);
+    return F/Lc(F);
+  }
+  if (G.isUnivariate() && fdivides(G, F, coF))
+  {
+    coG= Lc (G);
+    return G/Lc(G);
+  }
+  if (F == G)
+  {
+    coF= coG= Lc (F);
+    return F/Lc(F);
+  }
+
+  CFMap M,N;
+  int best_level= myCompress (A, B, M, N, topLevel);
+
+  if (best_level == 0)
+  {
+    coF= F;
+    coG= G;
+    return B.genOne();
+  }
+
+  A= M(A);
+  B= M(B);
+
+  Variable x= Variable(1);
+
+  //univariate case
+  if (A.isUnivariate() && B.isUnivariate())
+  {
+    CanonicalForm result= gcd (A, B);
+    coF= N (A/result);
+    coG= N (B/result);
+    return N (result);
+  }
+
+  CanonicalForm cA, cB;    // content of A and B
+  CanonicalForm ppA, ppB;    // primitive part of A and B
+  CanonicalForm gcdcAcB;
+
+  cA = uni_content (A);
+  cB = uni_content (B);
+  gcdcAcB= gcd (cA, cB);
+  ppA= A/cA;
+  ppB= B/cB;
+
+  CanonicalForm lcA, lcB;  // leading coefficients of A and B
+  CanonicalForm gcdlcAlcB;
+
+  lcA= uni_lcoeff (ppA);
+  lcB= uni_lcoeff (ppB);
+
+  gcdlcAlcB= gcd (lcA, lcB);
+
+  int d= totaldegree (ppA, Variable(2), Variable (ppA.level()));
+
+  if (d == 0)
+  {
+    coF= N (ppA*(cA/gcdcAcB));
+    coG= N (ppB*(cB/gcdcAcB));
+    return N(gcdcAcB);
+  }
+
+  int d0= totaldegree (ppB, Variable(2), Variable (ppB.level()));
+  if (d0 < d)
+    d= d0;
+  if (d == 0)
+  {
+    coF= N (ppA*(cA/gcdcAcB));
+    coG= N (ppB*(cB/gcdcAcB));
+    return N(gcdcAcB);
+  }
+
+  CanonicalForm m, random_element, G_m, G_random_element, H, cH, ppH;
+  CanonicalForm newtonPoly, coF_random_element, coG_random_element, coF_m,
+                coG_m, ppCoF, ppCoG;
+
+  newtonPoly= 1;
+  m= gcdlcAlcB;
+  G_m= 0;
+  coF= 0;
+  coG= 0;
+  H= 0;
+  bool fail= false;
+  topLevel= false;
+  bool inextension= false;
+  Variable V_buf= alpha, V_buf4= alpha;
+  CanonicalForm prim_elem, im_prim_elem;
+  CanonicalForm prim_elem_alpha, im_prim_elem_alpha;
+  CFList source, dest;
+  int bound1= degree (ppA, 1);
+  int bound2= degree (ppB, 1);
+  do
+  {
+    random_element= randomElement (m*lcA*lcB, V_buf, l, fail);
+    if (fail)
+    {
+      source= CFList();
+      dest= CFList();
+
+      Variable V_buf3= V_buf;
+      V_buf= chooseExtension (V_buf);
+      bool prim_fail= false;
+      Variable V_buf2;
+      prim_elem= primitiveElement (V_buf4, V_buf2, prim_fail);
+      if (V_buf4 == alpha)
+        prim_elem_alpha= prim_elem;
+
+      if (V_buf3 != V_buf4)
+      {
+        m= mapDown (m, prim_elem, im_prim_elem, V_buf4, source, dest);
+        G_m= mapDown (G_m, prim_elem, im_prim_elem, V_buf4, source, dest);
+        coF_m= mapDown (coF_m, prim_elem, im_prim_elem, V_buf4, source, dest);
+        coG_m= mapDown (coG_m, prim_elem, im_prim_elem, V_buf4, source, dest);
+        newtonPoly= mapDown (newtonPoly, prim_elem, im_prim_elem, V_buf4,
+                             source, dest);
+        ppA= mapDown (ppA, prim_elem, im_prim_elem, V_buf4, source, dest);
+        ppB= mapDown (ppB, prim_elem, im_prim_elem, V_buf4, source, dest);
+        gcdlcAlcB= mapDown (gcdlcAlcB, prim_elem, im_prim_elem, V_buf4,
+                            source, dest);
+        lcA= mapDown (lcA, prim_elem, im_prim_elem, V_buf4, source, dest);
+        lcB= mapDown (lcB, prim_elem, im_prim_elem, V_buf4, source, dest);
+        for (CFListIterator i= l; i.hasItem(); i++)
+          i.getItem()= mapDown (i.getItem(), prim_elem, im_prim_elem, V_buf4,
+                                source, dest);
+      }
+
+      ASSERT (!prim_fail, "failure in integer factorizer");
+      if (prim_fail)
+        ; //ERROR
+      else
+        im_prim_elem= mapPrimElem (prim_elem, V_buf4, V_buf);
+
+      if (V_buf4 == alpha)
+        im_prim_elem_alpha= im_prim_elem;
+      else
+        im_prim_elem_alpha= mapUp (im_prim_elem_alpha, V_buf4, V_buf, prim_elem,
+                                   im_prim_elem, source, dest);
+      DEBOUTLN (cerr, "getMipo (V_buf4)= " << getMipo (V_buf4));
+      DEBOUTLN (cerr, "getMipo (V_buf2)= " << getMipo (V_buf2));
+      inextension= true;
+      for (CFListIterator i= l; i.hasItem(); i++)
+        i.getItem()= mapUp (i.getItem(), V_buf4, V_buf, prim_elem,
+                             im_prim_elem, source, dest);
+      m= mapUp (m, V_buf4, V_buf, prim_elem, im_prim_elem, source, dest);
+      G_m= mapUp (G_m, V_buf4, V_buf, prim_elem, im_prim_elem, source, dest);
+      coF_m= mapUp (coF_m, V_buf4, V_buf, prim_elem, im_prim_elem, source, dest);
+      coG_m= mapUp (coG_m, V_buf4, V_buf, prim_elem, im_prim_elem, source, dest);
+      newtonPoly= mapUp (newtonPoly, V_buf4, V_buf, prim_elem, im_prim_elem,
+                          source, dest);
+      ppA= mapUp (ppA, V_buf4, V_buf, prim_elem, im_prim_elem, source, dest);
+      ppB= mapUp (ppB, V_buf4, V_buf, prim_elem, im_prim_elem, source, dest);
+      gcdlcAlcB= mapUp (gcdlcAlcB, V_buf4, V_buf, prim_elem, im_prim_elem,
+                         source, dest);
+      lcA= mapUp (lcA, V_buf4, V_buf, prim_elem, im_prim_elem, source, dest);
+      lcB= mapUp (lcB, V_buf4, V_buf, prim_elem, im_prim_elem, source, dest);
+
+      fail= false;
+      random_element= randomElement (m*lcA*lcB, V_buf, l, fail );
+      DEBOUTLN (cerr, "fail= " << fail);
+      CFList list;
+      TIMING_START (gcd_recursion);
+      G_random_element=
+      modGCDFq (ppA (random_element, x), ppB (random_element, x),
+                        coF_random_element, coG_random_element, V_buf,
+                        list, topLevel);
+      TIMING_END_AND_PRINT (gcd_recursion,
+                            "time for recursive call: ");
+      DEBOUTLN (cerr, "G_random_element= " << G_random_element);
+      V_buf4= V_buf;
+    }
+    else
+    {
+      CFList list;
+      TIMING_START (gcd_recursion);
+      G_random_element=
+      modGCDFq (ppA(random_element, x), ppB(random_element, x),
+                        coF_random_element, coG_random_element, V_buf,
+                        list, topLevel);
+      TIMING_END_AND_PRINT (gcd_recursion,
+                            "time for recursive call: ");
+      DEBOUTLN (cerr, "G_random_element= " << G_random_element);
+    }
+
+    if (!G_random_element.inCoeffDomain())
+      d0= totaldegree (G_random_element, Variable(2),
+                       Variable (G_random_element.level()));
+    else
+      d0= 0;
+
+    if (d0 == 0)
+    {
+      if (inextension)
+      {
+        CFList u, v;
+        ppA= mapDown (ppA, prim_elem_alpha, im_prim_elem_alpha, alpha, u, v);
+        ppB= mapDown (ppB, prim_elem_alpha, im_prim_elem_alpha, alpha, u, v);
+        prune1 (alpha);
+      }
+      coF= N (ppA*(cA/gcdcAcB));
+      coG= N (ppB*(cB/gcdcAcB));
+      return N(gcdcAcB);
+    }
+    if (d0 >  d)
+    {
+      if (!find (l, random_element))
+        l.append (random_element);
+      continue;
+    }
+
+    G_random_element=
+    (gcdlcAlcB(random_element, x)/uni_lcoeff (G_random_element))
+    * G_random_element;
+    coF_random_element= (lcA(random_element,x)/uni_lcoeff(coF_random_element))
+                        *coF_random_element;
+    coG_random_element= (lcB(random_element,x)/uni_lcoeff(coG_random_element))
+                        *coG_random_element;
+
+    if (!G_random_element.inCoeffDomain())
+      d0= totaldegree (G_random_element, Variable(2),
+                       Variable (G_random_element.level()));
+    else
+      d0= 0;
+
+    if (d0 <  d)
+    {
+      m= gcdlcAlcB;
+      newtonPoly= 1;
+      G_m= 0;
+      d= d0;
+      coF_m= 0;
+      coG_m= 0;
+    }
+
+    TIMING_START (newton_interpolation);
+    H= newtonInterp (random_element, G_random_element, newtonPoly, G_m, x);
+    coF= newtonInterp (random_element, coF_random_element, newtonPoly, coF_m,x);
+    coG= newtonInterp (random_element, coG_random_element, newtonPoly, coG_m,x);
+    TIMING_END_AND_PRINT (newton_interpolation,
+                          "time for newton interpolation: ");
+
+    //termination test
+    if ((uni_lcoeff (H) == gcdlcAlcB) || (G_m == H))
+    {
+      TIMING_START (termination_test);
+      if (gcdlcAlcB.isOne())
+        cH= 1;
+      else
+        cH= uni_content (H);
+      ppH= H/cH;
+      ppH /= Lc (ppH);
+      CanonicalForm lcppH= gcdlcAlcB/cH;
+      CanonicalForm ccoF= lcppH/Lc (lcppH);
+      CanonicalForm ccoG= lcppH/Lc (lcppH);
+      ppCoF= coF/ccoF;
+      ppCoG= coG/ccoG;
+      if (inextension)
+      {
+        if (((degree (ppCoF,1)+degree (ppH,1) == bound1) &&
+             (degree (ppCoG,1)+degree (ppH,1) == bound2) &&
+             terminationTest (ppA, ppB, ppCoF, ppCoG, ppH)) ||
+             (fdivides (ppH, ppA, ppCoF) && fdivides (ppH, ppB, ppCoG)))
+        {
+          CFList u, v;
+          DEBOUTLN (cerr, "ppH before mapDown= " << ppH);
+          ppH= mapDown (ppH, prim_elem_alpha, im_prim_elem_alpha, alpha, u, v);
+          ppCoF= mapDown (ppCoF, prim_elem_alpha, im_prim_elem_alpha, alpha, u, v);
+          ppCoG= mapDown (ppCoG, prim_elem_alpha, im_prim_elem_alpha, alpha, u, v);
+          DEBOUTLN (cerr, "ppH after mapDown= " << ppH);
+          coF= N ((cA/gcdcAcB)*ppCoF);
+          coG= N ((cB/gcdcAcB)*ppCoG);
+          TIMING_END_AND_PRINT (termination_test,
+                                "time for successful termination test Fq: ");
+          prune1 (alpha);
+          return N(gcdcAcB*ppH);
+        }
+      }
+      else if (((degree (ppCoF,1)+degree (ppH,1) == bound1) &&
+                (degree (ppCoG,1)+degree (ppH,1) == bound2) &&
+                terminationTest (ppA, ppB, ppCoF, ppCoG, ppH)) ||
+                (fdivides (ppH, ppA, ppCoF) && fdivides (ppH, ppB, ppCoG)))
+      {
+        coF= N ((cA/gcdcAcB)*ppCoF);
+        coG= N ((cB/gcdcAcB)*ppCoG);
+        TIMING_END_AND_PRINT (termination_test,
+                              "time for successful termination test Fq: ");
+        return N(gcdcAcB*ppH);
+      }
+      TIMING_END_AND_PRINT (termination_test,
+                            "time for unsuccessful termination test Fq: ");
+    }
+
+    G_m= H;
+    coF_m= coF;
+    coG_m= coG;
+    newtonPoly= newtonPoly*(x - random_element);
+    m= m*(x - random_element);
+    if (!find (l, random_element))
+      l.append (random_element);
+  } while (1);
+}
+
+/// compute a random element a of GF, s.t. F(a) \f$ \neq 0 \f$ , F is a
+/// univariate polynomial, returns fail if there are no field elements left
+/// which have not been used before
+static inline
+CanonicalForm
+GFRandomElement (const CanonicalForm& F, CFList& list, bool& fail)
+{
+  fail= false;
+  Variable x= F.mvar();
+  GFRandom genGF;
+  CanonicalForm random;
+  int p= getCharacteristic();
+  int d= getGFDegree();
+  int bound= ipower (p, d);
+  do
+  {
+    if (list.length() == bound)
+    {
+      fail= true;
+      break;
+    }
+    if (list.length() < 1)
+      random= 0;
+    else
+    {
+      random= genGF.generate();
+      while (find (list, random))
+        random= genGF.generate();
+    }
+    if (F (random, x) == 0)
+    {
+      list.append (random);
+      continue;
+    }
+  } while (find (list, random));
+  return random;
+}
+
+CanonicalForm
+modGCDGF (const CanonicalForm& F, const CanonicalForm& G,
+        CanonicalForm& coF, CanonicalForm& coG,
+        CFList& l, bool& topLevel);
+
+CanonicalForm
+modGCDGF (const CanonicalForm& F, const CanonicalForm& G, CFList& l,
+        bool& topLevel)
+{
+  CanonicalForm dummy1, dummy2;
+  CanonicalForm result= modGCDGF (F, G, dummy1, dummy2, l, topLevel);
+  return result;
+}
+
+/// GCD of F and G over GF, based on Alg. 7.2. as described in "Algorithms for
+/// Computer Algebra" by Geddes, Czapor, Labahn
+/// Usually this algorithm will be faster than modGCDFq since GF has
+/// faster field arithmetics, however it might fail if the input is large since
+/// the size of the base field is bounded by 2^16, output is monic
+CanonicalForm
+modGCDGF (const CanonicalForm& F, const CanonicalForm& G,
+        CanonicalForm& coF, CanonicalForm& coG,
+        CFList& l, bool& topLevel)
+{
+  CanonicalForm A= F;
+  CanonicalForm B= G;
+  if (F.isZero() && degree(G) > 0)
+  {
+    coF= 0;
+    coG= Lc (G);
+    return G/Lc(G);
+  }
+  else if (G.isZero() && degree (F) > 0)
+  {
+    coF= Lc (F);
+    coG= 0;
+    return F/Lc(F);
+  }
+  else if (F.isZero() && G.isZero())
+  {
+    coF= coG= 0;
+    return F.genOne();
+  }
+  if (F.inBaseDomain() || G.inBaseDomain())
+  {
+    coF= F;
+    coG= G;
+    return F.genOne();
+  }
+  if (F.isUnivariate() && fdivides(F, G, coG))
+  {
+    coF= Lc (F);
+    return F/Lc(F);
+  }
+  if (G.isUnivariate() && fdivides(G, F, coF))
+  {
+    coG= Lc (G);
+    return G/Lc(G);
+  }
+  if (F == G)
+  {
+    coF= coG= Lc (F);
+    return F/Lc(F);
+  }
+
+  CFMap M,N;
+  int best_level= myCompress (A, B, M, N, topLevel);
+
+  if (best_level == 0)
+  {
+    coF= F;
+    coG= G;
+    return B.genOne();
+  }
+
+  A= M(A);
+  B= M(B);
+
+  Variable x= Variable(1);
+
+  //univariate case
+  if (A.isUnivariate() && B.isUnivariate())
+  {
+    CanonicalForm result= gcd (A, B);
+    coF= N (A/result);
+    coG= N (B/result);
+    return N (result);
+  }
+
+  CanonicalForm cA, cB;    // content of A and B
+  CanonicalForm ppA, ppB;    // primitive part of A and B
+  CanonicalForm gcdcAcB;
+
+  cA = uni_content (A);
+  cB = uni_content (B);
+  gcdcAcB= gcd (cA, cB);
+  ppA= A/cA;
+  ppB= B/cB;
+
+  CanonicalForm lcA, lcB;  // leading coefficients of A and B
+  CanonicalForm gcdlcAlcB;
+
+  lcA= uni_lcoeff (ppA);
+  lcB= uni_lcoeff (ppB);
+
+  gcdlcAlcB= gcd (lcA, lcB);
+
+  int d= totaldegree (ppA, Variable(2), Variable (ppA.level()));
+  if (d == 0)
+  {
+    coF= N (ppA*(cA/gcdcAcB));
+    coG= N (ppB*(cB/gcdcAcB));
+    return N(gcdcAcB);
+  }
+  int d0= totaldegree (ppB, Variable(2), Variable (ppB.level()));
+  if (d0 < d)
+    d= d0;
+  if (d == 0)
+  {
+    coF= N (ppA*(cA/gcdcAcB));
+    coG= N (ppB*(cB/gcdcAcB));
+    return N(gcdcAcB);
+  }
+
+  CanonicalForm m, random_element, G_m, G_random_element, H, cH, ppH;
+  CanonicalForm newtonPoly, coF_random_element, coG_random_element, coF_m,
+                coG_m, ppCoF, ppCoG;
+
+  newtonPoly= 1;
+  m= gcdlcAlcB;
+  G_m= 0;
+  coF= 0;
+  coG= 0;
+  H= 0;
+  bool fail= false;
+  topLevel= false;
+  bool inextension= false;
+  int p=-1;
+  int k= getGFDegree();
+  int kk;
+  int expon;
+  char gf_name_buf= gf_name;
+  int bound1= degree (ppA, 1);
+  int bound2= degree (ppB, 1);
+  do
+  {
+    random_element= GFRandomElement (m*lcA*lcB, l, fail);
+    if (fail)
+    {
+      p= getCharacteristic();
+      expon= 2;
+      kk= getGFDegree();
+      if (ipower (p, kk*expon) < (1 << 16))
+        setCharacteristic (p, kk*(int)expon, 'b');
+      else
+      {
+        expon= (int) floor((log ((double)((1<<16) - 1)))/(log((double)p)*kk));
+        ASSERT (expon >= 2, "not enough points in modGCDGF");
+        setCharacteristic (p, (int)(kk*expon), 'b');
+      }
+      inextension= true;
+      fail= false;
+      for (CFListIterator i= l; i.hasItem(); i++)
+        i.getItem()= GFMapUp (i.getItem(), kk);
+      m= GFMapUp (m, kk);
+      G_m= GFMapUp (G_m, kk);
+      newtonPoly= GFMapUp (newtonPoly, kk);
+      coF_m= GFMapUp (coF_m, kk);
+      coG_m= GFMapUp (coG_m, kk);
+      ppA= GFMapUp (ppA, kk);
+      ppB= GFMapUp (ppB, kk);
+      gcdlcAlcB= GFMapUp (gcdlcAlcB, kk);
+      lcA= GFMapUp (lcA, kk);
+      lcB= GFMapUp (lcB, kk);
+      random_element= GFRandomElement (m*lcA*lcB, l, fail);
+      DEBOUTLN (cerr, "fail= " << fail);
+      CFList list;
+      TIMING_START (gcd_recursion);
+      G_random_element= modGCDGF (ppA(random_element, x), ppB(random_element, x),
+                                coF_random_element, coG_random_element,
+                                list, topLevel);
+      TIMING_END_AND_PRINT (gcd_recursion,
+                            "time for recursive call: ");
+      DEBOUTLN (cerr, "G_random_element= " << G_random_element);
+    }
+    else
+    {
+      CFList list;
+      TIMING_START (gcd_recursion);
+      G_random_element= modGCDGF (ppA(random_element, x), ppB(random_element, x),
+                                coF_random_element, coG_random_element,
+                                list, topLevel);
+      TIMING_END_AND_PRINT (gcd_recursion,
+                            "time for recursive call: ");
+      DEBOUTLN (cerr, "G_random_element= " << G_random_element);
+    }
+
+    if (!G_random_element.inCoeffDomain())
+      d0= totaldegree (G_random_element, Variable(2),
+                       Variable (G_random_element.level()));
+    else
+      d0= 0;
+
+    if (d0 == 0)
+    {
+      if (inextension)
+      {
+        ppA= GFMapDown (ppA, k);
+        ppB= GFMapDown (ppB, k);
+        setCharacteristic (p, k, gf_name_buf);
+      }
+      coF= N (ppA*(cA/gcdcAcB));
+      coG= N (ppB*(cB/gcdcAcB));
+      return N(gcdcAcB);
+    }
+    if (d0 >  d)
+    {
+      if (!find (l, random_element))
+        l.append (random_element);
+      continue;
+    }
+
+    G_random_element=
+    (gcdlcAlcB(random_element, x)/uni_lcoeff(G_random_element)) *
+     G_random_element;
+
+    coF_random_element= (lcA(random_element,x)/uni_lcoeff(coF_random_element))
+                        *coF_random_element;
+    coG_random_element= (lcB(random_element,x)/uni_lcoeff(coG_random_element))
+                        *coG_random_element;
+
+    if (!G_random_element.inCoeffDomain())
+      d0= totaldegree (G_random_element, Variable(2),
+                       Variable (G_random_element.level()));
+    else
+      d0= 0;
+
+    if (d0 < d)
+    {
+      m= gcdlcAlcB;
+      newtonPoly= 1;
+      G_m= 0;
+      d= d0;
+      coF_m= 0;
+      coG_m= 0;
+    }
+
+    TIMING_START (newton_interpolation);
+    H= newtonInterp (random_element, G_random_element, newtonPoly, G_m, x);
+    coF= newtonInterp (random_element, coF_random_element, newtonPoly, coF_m,x);
+    coG= newtonInterp (random_element, coG_random_element, newtonPoly, coG_m,x);
+    TIMING_END_AND_PRINT (newton_interpolation,
+                          "time for newton interpolation: ");
+
+    //termination test
+    if ((uni_lcoeff (H) == gcdlcAlcB) || (G_m == H))
+    {
+      TIMING_START (termination_test);
+      if (gcdlcAlcB.isOne())
+        cH= 1;
+      else
+        cH= uni_content (H);
+      ppH= H/cH;
+      ppH /= Lc (ppH);
+      CanonicalForm lcppH= gcdlcAlcB/cH;
+      CanonicalForm ccoF= lcppH/Lc (lcppH);
+      CanonicalForm ccoG= lcppH/Lc (lcppH);
+      ppCoF= coF/ccoF;
+      ppCoG= coG/ccoG;
+      if (inextension)
+      {
+        if (((degree (ppCoF,1)+degree (ppH,1) == bound1) &&
+             (degree (ppCoG,1)+degree (ppH,1) == bound2) &&
+             terminationTest (ppA, ppB, ppCoF, ppCoG, ppH)) ||
+             (fdivides (ppH, ppA, ppCoF) && fdivides (ppH, ppB, ppCoG)))
+        {
+          DEBOUTLN (cerr, "ppH before mapDown= " << ppH);
+          ppH= GFMapDown (ppH, k);
+          ppCoF= GFMapDown (ppCoF, k);
+          ppCoG= GFMapDown (ppCoG, k);
+          DEBOUTLN (cerr, "ppH after mapDown= " << ppH);
+          coF= N ((cA/gcdcAcB)*ppCoF);
+          coG= N ((cB/gcdcAcB)*ppCoG);
+          setCharacteristic (p, k, gf_name_buf);
+          TIMING_END_AND_PRINT (termination_test,
+                                "time for successful termination GF: ");
+          return N(gcdcAcB*ppH);
+        }
+      }
+      else
+      {
+      if (((degree (ppCoF,1)+degree (ppH,1) == bound1) &&
+           (degree (ppCoG,1)+degree (ppH,1) == bound2) &&
+           terminationTest (ppA, ppB, ppCoF, ppCoG, ppH)) ||
+           (fdivides (ppH, ppA, ppCoF) && fdivides (ppH, ppB, ppCoG)))
+        {
+          coF= N ((cA/gcdcAcB)*ppCoF);
+          coG= N ((cB/gcdcAcB)*ppCoG);
+          TIMING_END_AND_PRINT (termination_test,
+                                "time for successful termination GF: ");
+          return N(gcdcAcB*ppH);
+        }
+      }
+      TIMING_END_AND_PRINT (termination_test,
+                            "time for unsuccessful termination GF: ");
+    }
+
+    G_m= H;
+    coF_m= coF;
+    coG_m= coG;
+    newtonPoly= newtonPoly*(x - random_element);
+    m= m*(x - random_element);
+    if (!find (l, random_element))
+      l.append (random_element);
+  } while (1);
+}
+
+static inline
+CanonicalForm
+FpRandomElement (const CanonicalForm& F, CFList& list, bool& fail)
+{
+  fail= false;
+  Variable x= F.mvar();
+  FFRandom genFF;
+  CanonicalForm random;
+  int p= getCharacteristic();
+  int bound= p;
+  do
+  {
+    if (list.length() == bound)
+    {
+      fail= true;
+      break;
+    }
+    if (list.length() < 1)
+      random= 0;
+    else
+    {
+      random= genFF.generate();
+      while (find (list, random))
+        random= genFF.generate();
+    }
+    if (F (random, x) == 0)
+    {
+      list.append (random);
+      continue;
+    }
+  } while (find (list, random));
+  return random;
+}
+
+CanonicalForm
+modGCDFp (const CanonicalForm& F, const CanonicalForm&  G,
+             CanonicalForm& coF, CanonicalForm& coG,
+             bool& topLevel, CFList& l);
+
+CanonicalForm
+modGCDFp (const CanonicalForm& F, const CanonicalForm& G,
+             bool& topLevel, CFList& l)
+{
+  CanonicalForm dummy1, dummy2;
+  CanonicalForm result= modGCDFp (F, G, dummy1, dummy2, topLevel, l);
+  return result;
+}
+
+CanonicalForm
+modGCDFp (const CanonicalForm& F, const CanonicalForm&  G,
+             CanonicalForm& coF, CanonicalForm& coG,
+             bool& topLevel, CFList& l)
+{
+  CanonicalForm A= F;
+  CanonicalForm B= G;
+  if (F.isZero() && degree(G) > 0)
+  {
+    coF= 0;
+    coG= Lc (G);
+    return G/Lc(G);
+  }
+  else if (G.isZero() && degree (F) > 0)
+  {
+    coF= Lc (F);
+    coG= 0;
+    return F/Lc(F);
+  }
+  else if (F.isZero() && G.isZero())
+  {
+    coF= coG= 0;
+    return F.genOne();
+  }
+  if (F.inBaseDomain() || G.inBaseDomain())
+  {
+    coF= F;
+    coG= G;
+    return F.genOne();
+  }
+  if (F.isUnivariate() && fdivides(F, G, coG))
+  {
+    coF= Lc (F);
+    return F/Lc(F);
+  }
+  if (G.isUnivariate() && fdivides(G, F, coF))
+  {
+    coG= Lc (G);
+    return G/Lc(G);
+  }
+  if (F == G)
+  {
+    coF= coG= Lc (F);
+    return F/Lc(F);
+  }
+  CFMap M,N;
+  int best_level= myCompress (A, B, M, N, topLevel);
+
+  if (best_level == 0)
+  {
+    coF= F;
+    coG= G;
+    return B.genOne();
+  }
+
+  A= M(A);
+  B= M(B);
+
+  Variable x= Variable (1);
+
+  //univariate case
+  if (A.isUnivariate() && B.isUnivariate())
+  {
+    CanonicalForm result= gcd (A, B);
+    coF= N (A/result);
+    coG= N (B/result);
+    return N (result);
+  }
+
+  CanonicalForm cA, cB;    // content of A and B
+  CanonicalForm ppA, ppB;    // primitive part of A and B
+  CanonicalForm gcdcAcB;
+
+  cA = uni_content (A);
+  cB = uni_content (B);
+  gcdcAcB= gcd (cA, cB);
+  ppA= A/cA;
+  ppB= B/cB;
+
+  CanonicalForm lcA, lcB;  // leading coefficients of A and B
+  CanonicalForm gcdlcAlcB;
+  lcA= uni_lcoeff (ppA);
+  lcB= uni_lcoeff (ppB);
+
+  gcdlcAlcB= gcd (lcA, lcB);
+
+  int d= totaldegree (ppA, Variable (2), Variable (ppA.level()));
+  int d0;
+
+  if (d == 0)
+  {
+    coF= N (ppA*(cA/gcdcAcB));
+    coG= N (ppB*(cB/gcdcAcB));
+    return N(gcdcAcB);
+  }
+
+  d0= totaldegree (ppB, Variable (2), Variable (ppB.level()));
+
+  if (d0 < d)
+    d= d0;
+
+  if (d == 0)
+  {
+    coF= N (ppA*(cA/gcdcAcB));
+    coG= N (ppB*(cB/gcdcAcB));
+    return N(gcdcAcB);
+  }
+
+  CanonicalForm m, random_element, G_m, G_random_element, H, cH, ppH;
+  CanonicalForm newtonPoly, coF_random_element, coG_random_element,
+                coF_m, coG_m, ppCoF, ppCoG;
+
+  newtonPoly= 1;
+  m= gcdlcAlcB;
+  H= 0;
+  coF= 0;
+  coG= 0;
+  G_m= 0;
+  Variable alpha, V_buf, cleanUp;
+  bool fail= false;
+  bool inextension= false;
+  topLevel= false;
+  CFList source, dest;
+  int bound1= degree (ppA, 1);
+  int bound2= degree (ppB, 1);
+  do
+  {
+    if (inextension)
+      random_element= randomElement (m*lcA*lcB, V_buf, l, fail);
+    else
+      random_element= FpRandomElement (m*lcA*lcB, l, fail);
+
+    if (!fail && !inextension)
+    {
+      CFList list;
+      TIMING_START (gcd_recursion);
+      G_random_element=
+      modGCDFp (ppA (random_element,x), ppB (random_element,x),
+                   coF_random_element, coG_random_element, topLevel,
+                   list);
+      TIMING_END_AND_PRINT (gcd_recursion,
+                            "time for recursive call: ");
+      DEBOUTLN (cerr, "G_random_element= " << G_random_element);
+    }
+    else if (!fail && inextension)
+    {
+      CFList list;
+      TIMING_START (gcd_recursion);
+      G_random_element=
+      modGCDFq (ppA (random_element, x), ppB (random_element, x),
+                        coF_random_element, coG_random_element, V_buf,
+                        list, topLevel);
+      TIMING_END_AND_PRINT (gcd_recursion,
+                            "time for recursive call: ");
+      DEBOUTLN (cerr, "G_random_element= " << G_random_element);
+    }
+    else if (fail && !inextension)
+    {
+      source= CFList();
+      dest= CFList();
+      CFList list;
+      CanonicalForm mipo;
+      int deg= 2;
+      bool initialized= false;
+      do
+      {
+        mipo= randomIrredpoly (deg, x);
+        if (initialized)
+          setMipo (alpha, mipo);
+        else
+          alpha= rootOf (mipo);
+        inextension= true;
+        initialized= true;
+        fail= false;
+        random_element= randomElement (m*lcA*lcB, alpha, l, fail);
+        deg++;
+      } while (fail);
+      list= CFList();
+      V_buf= alpha;
+      cleanUp= alpha;
+      TIMING_START (gcd_recursion);
+      G_random_element=
+      modGCDFq (ppA (random_element, x), ppB (random_element, x),
+                        coF_random_element, coG_random_element, alpha,
+                        list, topLevel);
+      TIMING_END_AND_PRINT (gcd_recursion,
+                            "time for recursive call: ");
+      DEBOUTLN (cerr, "G_random_element= " << G_random_element);
+    }
+    else if (fail && inextension)
+    {
+      source= CFList();
+      dest= CFList();
+
+      Variable V_buf3= V_buf;
+      V_buf= chooseExtension (V_buf);
+      bool prim_fail= false;
+      Variable V_buf2;
+      CanonicalForm prim_elem, im_prim_elem;
+      prim_elem= primitiveElement (alpha, V_buf2, prim_fail);
+
+      if (V_buf3 != alpha)
+      {
+        m= mapDown (m, prim_elem, im_prim_elem, alpha, source, dest);
+        G_m= mapDown (G_m, prim_elem, im_prim_elem, alpha, source, dest);
+        coF_m= mapDown (coF_m, prim_elem, im_prim_elem, alpha, source, dest);
+        coG_m= mapDown (coG_m, prim_elem, im_prim_elem, alpha, source, dest);
+        newtonPoly= mapDown (newtonPoly, prim_elem, im_prim_elem, alpha,
+                             source, dest);
+        ppA= mapDown (ppA, prim_elem, im_prim_elem, alpha, source, dest);
+        ppB= mapDown (ppB, prim_elem, im_prim_elem, alpha, source, dest);
+        gcdlcAlcB= mapDown (gcdlcAlcB, prim_elem, im_prim_elem, alpha, source,
+                            dest);
+        lcA= mapDown (lcA, prim_elem, im_prim_elem, alpha, source, dest);
+        lcB= mapDown (lcB, prim_elem, im_prim_elem, alpha, source, dest);
+        for (CFListIterator i= l; i.hasItem(); i++)
+          i.getItem()= mapDown (i.getItem(), prim_elem, im_prim_elem, alpha,
+                                source, dest);
+      }
+
+      ASSERT (!prim_fail, "failure in integer factorizer");
+      if (prim_fail)
+        ; //ERROR
+      else
+        im_prim_elem= mapPrimElem (prim_elem, alpha, V_buf);
+
+      DEBOUTLN (cerr, "getMipo (alpha)= " << getMipo (alpha));
+      DEBOUTLN (cerr, "getMipo (alpha)= " << getMipo (V_buf2));
+
+      for (CFListIterator i= l; i.hasItem(); i++)
+        i.getItem()= mapUp (i.getItem(), alpha, V_buf, prim_elem,
+                             im_prim_elem, source, dest);
+      m= mapUp (m, alpha, V_buf, prim_elem, im_prim_elem, source, dest);
+      G_m= mapUp (G_m, alpha, V_buf, prim_elem, im_prim_elem, source, dest);
+      coF_m= mapUp (coF_m, alpha, V_buf, prim_elem, im_prim_elem, source, dest);
+      coG_m= mapUp (coG_m, alpha, V_buf, prim_elem, im_prim_elem, source, dest);
+      newtonPoly= mapUp (newtonPoly, alpha, V_buf, prim_elem, im_prim_elem,
+                          source, dest);
+      ppA= mapUp (ppA, alpha, V_buf, prim_elem, im_prim_elem, source, dest);
+      ppB= mapUp (ppB, alpha, V_buf, prim_elem, im_prim_elem, source, dest);
+      gcdlcAlcB= mapUp (gcdlcAlcB, alpha, V_buf, prim_elem, im_prim_elem,
+                         source, dest);
+      lcA= mapUp (lcA, alpha, V_buf, prim_elem, im_prim_elem, source, dest);
+      lcB= mapUp (lcB, alpha, V_buf, prim_elem, im_prim_elem, source, dest);
+      fail= false;
+      random_element= randomElement (m*lcA*lcB, V_buf, l, fail );
+      DEBOUTLN (cerr, "fail= " << fail);
+      CFList list;
+      TIMING_START (gcd_recursion);
+      G_random_element=
+      modGCDFq (ppA (random_element, x), ppB (random_element, x),
+                        coF_random_element, coG_random_element, V_buf,
+                        list, topLevel);
+      TIMING_END_AND_PRINT (gcd_recursion,
+                            "time for recursive call: ");
+      DEBOUTLN (cerr, "G_random_element= " << G_random_element);
+      alpha= V_buf;
+    }
+
+    if (!G_random_element.inCoeffDomain())
+      d0= totaldegree (G_random_element, Variable(2),
+                       Variable (G_random_element.level()));
+    else
+      d0= 0;
+
+    if (d0 == 0)
+    {
+      if (inextension)
+        prune (cleanUp);
+      coF= N (ppA*(cA/gcdcAcB));
+      coG= N (ppB*(cB/gcdcAcB));
+      return N(gcdcAcB);
+    }
+
+    if (d0 >  d)
+    {
+      if (!find (l, random_element))
+        l.append (random_element);
+      continue;
+    }
+
+    G_random_element= (gcdlcAlcB(random_element,x)/uni_lcoeff(G_random_element))
+                       *G_random_element;
+
+    coF_random_element= (lcA(random_element,x)/uni_lcoeff(coF_random_element))
+                        *coF_random_element;
+    coG_random_element= (lcB(random_element,x)/uni_lcoeff(coG_random_element))
+                        *coG_random_element;
+
+    if (!G_random_element.inCoeffDomain())
+      d0= totaldegree (G_random_element, Variable(2),
+                       Variable (G_random_element.level()));
+    else
+      d0= 0;
+
+    if (d0 <  d)
+    {
+      m= gcdlcAlcB;
+      newtonPoly= 1;
+      G_m= 0;
+      d= d0;
+      coF_m= 0;
+      coG_m= 0;
+    }
+
+    TIMING_START (newton_interpolation);
+    H= newtonInterp (random_element, G_random_element, newtonPoly, G_m, x);
+    coF= newtonInterp (random_element, coF_random_element, newtonPoly, coF_m,x);
+    coG= newtonInterp (random_element, coG_random_element, newtonPoly, coG_m,x);
+    TIMING_END_AND_PRINT (newton_interpolation,
+                          "time for newton_interpolation: ");
+
+    //termination test
+    if ((uni_lcoeff (H) == gcdlcAlcB) || (G_m == H))
+    {
+      TIMING_START (termination_test);
+      if (gcdlcAlcB.isOne())
+        cH= 1;
+      else
+        cH= uni_content (H);
+      ppH= H/cH;
+      ppH /= Lc (ppH);
+      CanonicalForm lcppH= gcdlcAlcB/cH;
+      CanonicalForm ccoF= lcppH/Lc (lcppH);
+      CanonicalForm ccoG= lcppH/Lc (lcppH);
+      ppCoF= coF/ccoF;
+      ppCoG= coG/ccoG;
+      DEBOUTLN (cerr, "ppH= " << ppH);
+      if (((degree (ppCoF,1)+degree (ppH,1) == bound1) &&
+           (degree (ppCoG,1)+degree (ppH,1) == bound2) &&
+           terminationTest (ppA, ppB, ppCoF, ppCoG, ppH)) ||
+           (fdivides (ppH, ppA, ppCoF) && fdivides (ppH, ppB, ppCoG)))
+      {
+        if (inextension)
+          prune (cleanUp);
+        coF= N ((cA/gcdcAcB)*ppCoF);
+        coG= N ((cB/gcdcAcB)*ppCoG);
+        TIMING_END_AND_PRINT (termination_test,
+                              "time for successful termination Fp: ");
+        return N(gcdcAcB*ppH);
+      }
+      TIMING_END_AND_PRINT (termination_test,
+                            "time for unsuccessful termination Fp: ");
+    }
+
+    G_m= H;
+    coF_m= coF;
+    coG_m= coG;
+    newtonPoly= newtonPoly*(x - random_element);
+    m= m*(x - random_element);
+    if (!find (l, random_element))
+      l.append (random_element);
+  } while (1);
+}
+
+CFArray
+solveVandermonde (const CFArray& M, const CFArray& A)
+{
+  int r= M.size();
+  ASSERT (A.size() == r, "vector does not have right size");
+
+  if (r == 1)
+  {
+    CFArray result= CFArray (1);
+    result [0]= A [0] / M [0];
+    return result;
+  }
+  // check solvability
+  bool notDistinct= false;
+  for (int i= 0; i < r - 1; i++)
+  {
+    for (int j= i + 1; j < r; j++)
+    {
+      if (M [i] == M [j])
+      {
+        notDistinct= true;
+        break;
+      }
+    }
+  }
+  if (notDistinct)
+    return CFArray();
+
+  CanonicalForm master= 1;
+  Variable x= Variable (1);
+  for (int i= 0; i < r; i++)
+    master *= x - M [i];
+  CFList Pj;
+  CanonicalForm tmp;
+  for (int i= 0; i < r; i++)
+  {
+    tmp= master/(x - M [i]);
+    tmp /= tmp (M [i], 1);
+    Pj.append (tmp);
+  }
+  CFArray result= CFArray (r);
+
+  CFListIterator j= Pj;
+  for (int i= 1; i <= r; i++, j++)
+  {
+    tmp= 0;
+    for (int l= 0; l < A.size(); l++)
+      tmp += A[l]*j.getItem()[l];
+    result[i - 1]= tmp;
+  }
+  return result;
+}
+
+CFArray
+solveGeneralVandermonde (const CFArray& M, const CFArray& A)
+{
+  int r= M.size();
+  ASSERT (A.size() == r, "vector does not have right size");
+  if (r == 1)
+  {
+    CFArray result= CFArray (1);
+    result [0]= A[0] / M [0];
+    return result;
+  }
+  // check solvability
+  bool notDistinct= false;
+  for (int i= 0; i < r - 1; i++)
+  {
+    for (int j= i + 1; j < r; j++)
+    {
+      if (M [i] == M [j])
+      {
+        notDistinct= true;
+        break;
+      }
+    }
+  }
+  if (notDistinct)
+    return CFArray();
+
+  CanonicalForm master= 1;
+  Variable x= Variable (1);
+  for (int i= 0; i < r; i++)
+    master *= x - M [i];
+  master *= x;
+  CFList Pj;
+  CanonicalForm tmp;
+  for (int i= 0; i < r; i++)
+  {
+    tmp= master/(x - M [i]);
+    tmp /= tmp (M [i], 1);
+    Pj.append (tmp);
+  }
+
+  CFArray result= CFArray (r);
+
+  CFListIterator j= Pj;
+  for (int i= 1; i <= r; i++, j++)
+  {
+    tmp= 0;
+
+    for (int l= 1; l <= A.size(); l++)
+      tmp += A[l - 1]*j.getItem()[l];
+    result[i - 1]= tmp;
+  }
+  return result;
+}
+
+/// M in row echolon form, rk rank of M
+CFArray
+readOffSolution (const CFMatrix& M, const long rk)
+{
+  CFArray result= CFArray (rk);
+  CanonicalForm tmp1, tmp2, tmp3;
+  for (int i= rk; i >= 1; i--)
+  {
+    tmp3= 0;
+    tmp1= M (i, M.columns());
+    for (int j= M.columns() - 1; j >= 1; j--)
+    {
+      tmp2= M (i, j);
+      if (j == i)
+        break;
+      else
+        tmp3 += tmp2*result[j - 1];
+    }
+    result[i - 1]= (tmp1 - tmp3)/tmp2;
+  }
+  return result;
+}
+
+CFArray
+readOffSolution (const CFMatrix& M, const CFArray& L, const CFArray& partialSol)
+{
+  CFArray result= CFArray (M.rows());
+  CanonicalForm tmp1, tmp2, tmp3;
+  int k;
+  for (int i= M.rows(); i >= 1; i--)
+  {
+    tmp3= 0;
+    tmp1= L[i - 1];
+    k= 0;
+    for (int j= M.columns(); j >= 1; j--, k++)
+    {
+      tmp2= M (i, j);
+      if (j == i)
+        break;
+      else
+      {
+        if (k > partialSol.size() - 1)
+          tmp3 += tmp2*result[j - 1];
+        else
+          tmp3 += tmp2*partialSol[partialSol.size() - k - 1];
+      }
+    }
+    result [i - 1]= (tmp1 - tmp3)/tmp2;
+  }
+  return result;
+}
+
+long
+gaussianElimFp (CFMatrix& M, CFArray& L)
+{
+  ASSERT (L.size() <= M.rows(), "dimension exceeded");
+  CFMatrix *N;
+  N= new CFMatrix (M.rows(), M.columns() + 1);
+
+  for (int i= 1; i <= M.rows(); i++)
+    for (int j= 1; j <= M.columns(); j++)
+      (*N) (i, j)= M (i, j);
+
+  int j= 1;
+  for (int i= 0; i < L.size(); i++, j++)
+    (*N) (j, M.columns() + 1)= L[i];
+#ifdef HAVE_FLINT
+  nmod_mat_t FLINTN;
+  convertFacCFMatrix2nmod_mat_t (FLINTN, *N);
+  long rk= nmod_mat_rref (FLINTN);
+
+  delete N;
+  N= convertNmod_mat_t2FacCFMatrix (FLINTN);
+  nmod_mat_clear (FLINTN);
+#else
+  int p= getCharacteristic ();
+  if (fac_NTL_char != p)
+  {
+    fac_NTL_char= p;
+    zz_p::init (p);
+  }
+  mat_zz_p *NTLN= convertFacCFMatrix2NTLmat_zz_p(*N);
+  delete N;
+  long rk= gauss (*NTLN);
+
+  N= convertNTLmat_zz_p2FacCFMatrix (*NTLN);
+  delete NTLN;
+#endif
+
+  L= CFArray (M.rows());
+  for (int i= 0; i < M.rows(); i++)
+    L[i]= (*N) (i + 1, M.columns() + 1);
+  M= (*N) (1, M.rows(), 1, M.columns());
+  delete N;
+  return rk;
+}
+
+long
+gaussianElimFq (CFMatrix& M, CFArray& L, const Variable& alpha)
+{
+  ASSERT (L.size() <= M.rows(), "dimension exceeded");
+  CFMatrix *N;
+  N= new CFMatrix (M.rows(), M.columns() + 1);
+
+  for (int i= 1; i <= M.rows(); i++)
+    for (int j= 1; j <= M.columns(); j++)
+      (*N) (i, j)= M (i, j);
+
+  int j= 1;
+  for (int i= 0; i < L.size(); i++, j++)
+    (*N) (j, M.columns() + 1)= L[i];
+  int p= getCharacteristic ();
+  if (fac_NTL_char != p)
+  {
+    fac_NTL_char= p;
+    zz_p::init (p);
+  }
+  zz_pX NTLMipo= convertFacCF2NTLzzpX (getMipo (alpha));
+  zz_pE::init (NTLMipo);
+  mat_zz_pE *NTLN= convertFacCFMatrix2NTLmat_zz_pE(*N);
+  long rk= gauss (*NTLN);
+
+  delete N;
+  N= convertNTLmat_zz_pE2FacCFMatrix (*NTLN, alpha);
+
+  delete NTLN;
+
+  M= (*N) (1, M.rows(), 1, M.columns());
+  L= CFArray (M.rows());
+  for (int i= 0; i < M.rows(); i++)
+    L[i]= (*N) (i + 1, M.columns() + 1);
+
+  delete N;
+  return rk;
+}
+
+CFArray
+solveSystemFp (const CFMatrix& M, const CFArray& L)
+{
+  ASSERT (L.size() <= M.rows(), "dimension exceeded");
+  CFMatrix *N;
+  N= new CFMatrix (M.rows(), M.columns() + 1);
+
+  for (int i= 1; i <= M.rows(); i++)
+    for (int j= 1; j <= M.columns(); j++)
+      (*N) (i, j)= M (i, j);
+
+  int j= 1;
+  for (int i= 0; i < L.size(); i++, j++)
+    (*N) (j, M.columns() + 1)= L[i];
+
+#ifdef HAVE_FLINT
+  nmod_mat_t FLINTN;
+  convertFacCFMatrix2nmod_mat_t (FLINTN, *N);
+  long rk= nmod_mat_rref (FLINTN);
+#else
+  int p= getCharacteristic ();
+  if (fac_NTL_char != p)
+  {
+    fac_NTL_char= p;
+    zz_p::init (p);
+  }
+  mat_zz_p *NTLN= convertFacCFMatrix2NTLmat_zz_p(*N);
+  long rk= gauss (*NTLN);
+#endif
+  delete N;
+  if (rk != M.columns())
+  {
+#ifdef HAVE_FLINT
+    nmod_mat_clear (FLINTN);
+#else
+    delete NTLN;
+#endif
+    return CFArray();
+  }
+#ifdef HAVE_FLINT
+  N= convertNmod_mat_t2FacCFMatrix (FLINTN);
+  nmod_mat_clear (FLINTN);
+#else
+  N= convertNTLmat_zz_p2FacCFMatrix (*NTLN);
+  delete NTLN;
+#endif
+  CFArray A= readOffSolution (*N, rk);
+
+  delete N;
+  return A;
+}
+
+CFArray
+solveSystemFq (const CFMatrix& M, const CFArray& L, const Variable& alpha)
+{
+  ASSERT (L.size() <= M.rows(), "dimension exceeded");
+  CFMatrix *N;
+  N= new CFMatrix (M.rows(), M.columns() + 1);
+
+  for (int i= 1; i <= M.rows(); i++)
+    for (int j= 1; j <= M.columns(); j++)
+      (*N) (i, j)= M (i, j);
+  int j= 1;
+  for (int i= 0; i < L.size(); i++, j++)
+    (*N) (j, M.columns() + 1)= L[i];
+  int p= getCharacteristic ();
+  if (fac_NTL_char != p)
+  {
+    fac_NTL_char= p;
+    zz_p::init (p);
+  }
+  zz_pX NTLMipo= convertFacCF2NTLzzpX (getMipo (alpha));
+  zz_pE::init (NTLMipo);
+  mat_zz_pE *NTLN= convertFacCFMatrix2NTLmat_zz_pE(*N);
+  long rk= gauss (*NTLN);
+
+  delete N;
+  if (rk != M.columns())
+  {
+    delete NTLN;
+    return CFArray();
+  }
+  N= convertNTLmat_zz_pE2FacCFMatrix (*NTLN, alpha);
+
+  delete NTLN;
+
+  CFArray A= readOffSolution (*N, rk);
+
+  delete N;
+  return A;
+}
+#endif
+
+CFArray
+getMonoms (const CanonicalForm& F)
+{
+  if (F.inCoeffDomain())
+  {
+    CFArray result= CFArray (1);
+    result [0]= 1;
+    return result;
+  }
+  if (F.isUnivariate())
+  {
+    CFArray result= CFArray (size(F));
+    int j= 0;
+    for (CFIterator i= F; i.hasTerms(); i++, j++)
+      result[j]= power (F.mvar(), i.exp());
+    return result;
+  }
+  int numMon= size (F);
+  CFArray result= CFArray (numMon);
+  int j= 0;
+  CFArray recResult;
+  Variable x= F.mvar();
+  CanonicalForm powX;
+  for (CFIterator i= F; i.hasTerms(); i++)
+  {
+    powX= power (x, i.exp());
+    recResult= getMonoms (i.coeff());
+    for (int k= 0; k < recResult.size(); k++)
+      result[j+k]= powX*recResult[k];
+    j += recResult.size();
+  }
+  return result;
+}
+
+#ifdef HAVE_NTL
+CFArray
+evaluateMonom (const CanonicalForm& F, const CFList& evalPoints)
+{
+  if (F.inCoeffDomain())
+  {
+    CFArray result= CFArray (1);
+    result [0]= F;
+    return result;
+  }
+  if (F.isUnivariate())
+  {
+    ASSERT (evalPoints.length() == 1,
+            "expected an eval point with only one component");
+    CFArray result= CFArray (size(F));
+    int j= 0;
+    CanonicalForm evalPoint= evalPoints.getLast();
+    for (CFIterator i= F; i.hasTerms(); i++, j++)
+      result[j]= power (evalPoint, i.exp());
+    return result;
+  }
+  int numMon= size (F);
+  CFArray result= CFArray (numMon);
+  int j= 0;
+  CanonicalForm evalPoint= evalPoints.getLast();
+  CFList buf= evalPoints;
+  buf.removeLast();
+  CFArray recResult;
+  CanonicalForm powEvalPoint;
+  for (CFIterator i= F; i.hasTerms(); i++)
+  {
+    powEvalPoint= power (evalPoint, i.exp());
+    recResult= evaluateMonom (i.coeff(), buf);
+    for (int k= 0; k < recResult.size(); k++)
+      result[j+k]= powEvalPoint*recResult[k];
+    j += recResult.size();
+  }
+  return result;
+}
+
+CFArray
+evaluate (const CFArray& A, const CFList& evalPoints)
+{
+  CFArray result= A.size();
+  CanonicalForm tmp;
+  int k;
+  for (int i= 0; i < A.size(); i++)
+  {
+    tmp= A[i];
+    k= 1;
+    for (CFListIterator j= evalPoints; j.hasItem(); j++, k++)
+      tmp= tmp (j.getItem(), k);
+    result[i]= tmp;
+  }
+  return result;
+}
+
+CFList
+evaluationPoints (const CanonicalForm& F, const CanonicalForm& G,
+                  CanonicalForm& Feval, CanonicalForm& Geval,
+                  const CanonicalForm& LCF, const bool& GF,
+                  const Variable& alpha, bool& fail, CFList& list
+                 )
+{
+  int k= tmax (F.level(), G.level()) - 1;
+  Variable x= Variable (1);
+  CFList result;
+  FFRandom genFF;
+  GFRandom genGF;
+  int p= getCharacteristic ();
+  double bound;
+  if (alpha != Variable (1))
+  {
+    bound= pow ((double) p, (double) degree (getMipo(alpha)));
+    bound= pow (bound, (double) k);
+  }
+  else if (GF)
+  {
+    bound= pow ((double) p, (double) getGFDegree());
+    bound= pow ((double) bound, (double) k);
+  }
+  else
+    bound= pow ((double) p, (double) k);
+
+  CanonicalForm random;
+  int j;
+  bool zeroOneOccured= false;
+  bool allEqual= false;
+  CanonicalForm buf;
+  do
+  {
+    random= 0;
+    // possible overflow if list.length() does not fit into a int
+    if (list.length() >= bound)
+    {
+      fail= true;
+      break;
+    }
+    for (int i= 0; i < k; i++)
+    {
+      if (GF)
+      {
+        result.append (genGF.generate());
+        random += result.getLast()*power (x, i);
+      }
+      else if (alpha.level() != 1)
+      {
+        AlgExtRandomF genAlgExt (alpha);
+        result.append (genAlgExt.generate());
+        random += result.getLast()*power (x, i);
+      }
+      else
+      {
+        result.append (genFF.generate());
+        random += result.getLast()*power (x, i);
+      }
+      if (result.getLast().isOne() || result.getLast().isZero())
+        zeroOneOccured= true;
+    }
+    if (find (list, random))
+    {
+      zeroOneOccured= false;
+      allEqual= false;
+      result= CFList();
+      continue;
+    }
+    if (zeroOneOccured)
+    {
+      list.append (random);
+      zeroOneOccured= false;
+      allEqual= false;
+      result= CFList();
+      continue;
+    }
+    // no zero at this point
+    if (k > 1)
+    {
+      allEqual= true;
+      CFIterator iter= random;
+      buf= iter.coeff();
+      iter++;
+      for (; iter.hasTerms(); iter++)
+        if (buf != iter.coeff())
+          allEqual= false;
+    }
+    if (allEqual)
+    {
+      list.append (random);
+      allEqual= false;
+      zeroOneOccured= false;
+      result= CFList();
+      continue;
+    }
+
+    Feval= F;
+    Geval= G;
+    CanonicalForm LCeval= LCF;
+    j= 1;
+    for (CFListIterator i= result; i.hasItem(); i++, j++)
+    {
+      Feval= Feval (i.getItem(), j);
+      Geval= Geval (i.getItem(), j);
+      LCeval= LCeval (i.getItem(), j);
+    }
+
+    if (LCeval.isZero())
+    {
+      if (!find (list, random))
+        list.append (random);
+      zeroOneOccured= false;
+      allEqual= false;
+      result= CFList();
+      continue;
+    }
+
+    if (list.length() >= bound)
+    {
+      fail= true;
+      break;
+    }
+  } while (find (list, random));
+
+  return result;
+}
+
+/// multiply two lists componentwise
+void mult (CFList& L1, const CFList& L2)
+{
+  ASSERT (L1.length() == L2.length(), "lists of the same size expected");
+
+  CFListIterator j= L2;
+  for (CFListIterator i= L1; i.hasItem(); i++, j++)
+    i.getItem() *= j.getItem();
+}
+
+void eval (const CanonicalForm& A, const CanonicalForm& B, CanonicalForm& Aeval,
+           CanonicalForm& Beval, const CFList& L)
+{
+  Aeval= A;
+  Beval= B;
+  int j= 1;
+  for (CFListIterator i= L; i.hasItem(); i++, j++)
+  {
+    Aeval= Aeval (i.getItem(), j);
+    Beval= Beval (i.getItem(), j);
+  }
+}
+
+CanonicalForm
+monicSparseInterpol (const CanonicalForm& F, const CanonicalForm& G,
+                     const CanonicalForm& skeleton, const Variable& alpha,
+                     bool& fail, CFArray*& coeffMonoms, CFArray& Monoms
+                    )
+{
+  CanonicalForm A= F;
+  CanonicalForm B= G;
+  if (F.isZero() && degree(G) > 0) return G/Lc(G);
+  else if (G.isZero() && degree (F) > 0) return F/Lc(F);
+  else if (F.isZero() && G.isZero()) return F.genOne();
+  if (F.inBaseDomain() || G.inBaseDomain()) return F.genOne();
+  if (F.isUnivariate() && fdivides(F, G)) return F/Lc(F);
+  if (G.isUnivariate() && fdivides(G, F)) return G/Lc(G);
+  if (F == G) return F/Lc(F);
+
+  ASSERT (degree (A, 1) == 0, "expected degree (F, 1) == 0");
+  ASSERT (degree (B, 1) == 0, "expected degree (G, 1) == 0");
+
+  CFMap M,N;
+  int best_level= myCompress (A, B, M, N, false);
+
+  if (best_level == 0)
+    return B.genOne();
+
+  A= M(A);
+  B= M(B);
+
+  Variable x= Variable (1);
+
+  //univariate case
+  if (A.isUnivariate() && B.isUnivariate())
+    return N (gcd (A, B));
+
+  CanonicalForm skel= M(skeleton);
+  CanonicalForm cA, cB;    // content of A and B
+  CanonicalForm ppA, ppB;    // primitive part of A and B
+  CanonicalForm gcdcAcB;
+  cA = uni_content (A);
+  cB = uni_content (B);
+  gcdcAcB= gcd (cA, cB);
+  ppA= A/cA;
+  ppB= B/cB;
+
+  CanonicalForm lcA, lcB;  // leading coefficients of A and B
+  CanonicalForm gcdlcAlcB;
+  lcA= uni_lcoeff (ppA);
+  lcB= uni_lcoeff (ppB);
+
+  if (fdivides (lcA, lcB))
+  {
+    if (fdivides (A, B))
+      return F/Lc(F);
+  }
+  if (fdivides (lcB, lcA))
+  {
+    if (fdivides (B, A))
+      return G/Lc(G);
+  }
+
+  gcdlcAlcB= gcd (lcA, lcB);
+  int skelSize= size (skel, skel.mvar());
+
+  int j= 0;
+  int biggestSize= 0;
+
+  for (CFIterator i= skel; i.hasTerms(); i++, j++)
+    biggestSize= tmax (biggestSize, size (i.coeff()));
+
+  CanonicalForm g, Aeval, Beval;
+
+  CFList evalPoints;
+  bool evalFail= false;
+  CFList list;
+  bool GF= false;
+  CanonicalForm LCA= LC (A);
+  CanonicalForm tmp;
+  CFArray gcds= CFArray (biggestSize);
+  CFList * pEvalPoints= new CFList [biggestSize];
+  Variable V_buf= alpha, V_buf4= alpha;
+  CFList source, dest;
+  CanonicalForm prim_elem, im_prim_elem;
+  CanonicalForm prim_elem_alpha, im_prim_elem_alpha;
+  for (int i= 0; i < biggestSize; i++)
+  {
+    if (i == 0)
+      evalPoints= evaluationPoints (A, B, Aeval, Beval, LCA, GF, V_buf, evalFail,
+                                    list);
+    else
+    {
+      mult (evalPoints, pEvalPoints [0]);
+      eval (A, B, Aeval, Beval, evalPoints);
+    }
+
+    if (evalFail)
+    {
+      if (V_buf.level() != 1)
+      {
+        do
+        {
+          Variable V_buf3= V_buf;
+          V_buf= chooseExtension (V_buf);
+          source= CFList();
+          dest= CFList();
+
+          bool prim_fail= false;
+          Variable V_buf2;
+          prim_elem= primitiveElement (V_buf4, V_buf2, prim_fail);
+          if (V_buf4 == alpha && alpha.level() != 1)
+            prim_elem_alpha= prim_elem;
+
+          ASSERT (!prim_fail, "failure in integer factorizer");
+          if (prim_fail)
+            ; //ERROR
+          else
+            im_prim_elem= mapPrimElem (prim_elem, V_buf4, V_buf);
+
+          DEBOUTLN (cerr, "getMipo (alpha)= " << getMipo (V_buf));
+          DEBOUTLN (cerr, "getMipo (alpha)= " << getMipo (V_buf2));
+
+          if (V_buf4 == alpha && alpha.level() != 1)
+            im_prim_elem_alpha= im_prim_elem;
+          else if (alpha.level() != 1)
+            im_prim_elem_alpha= mapUp (im_prim_elem_alpha, V_buf4, V_buf,
+                                       prim_elem, im_prim_elem, source, dest);
+
+          for (CFListIterator j= list; j.hasItem(); j++)
+            j.getItem()= mapUp (j.getItem(), V_buf4, V_buf, prim_elem,
+                                im_prim_elem, source, dest);
+          for (int k= 0; k < i; k++)
+          {
+            for (CFListIterator j= pEvalPoints[k]; j.hasItem(); j++)
+              j.getItem()= mapUp (j.getItem(), V_buf4, V_buf, prim_elem,
+                                  im_prim_elem, source, dest);
+            gcds[k]= mapUp (gcds[k], V_buf4, V_buf, prim_elem, im_prim_elem,
+                            source, dest);
+          }
+
+          if (alpha.level() != 1)
+          {
+            A= mapUp (A, V_buf4, V_buf, prim_elem, im_prim_elem, source,dest);
+            B= mapUp (B, V_buf4, V_buf, prim_elem, im_prim_elem, source,dest);
+          }
+          V_buf4= V_buf;
+          evalFail= false;
+          evalPoints= evaluationPoints (A, B, Aeval, Beval, LCA, GF, V_buf,
+                                        evalFail, list);
+        } while (evalFail);
+      }
+      else
+      {
+        CanonicalForm mipo;
+        int deg= 2;
+        bool initialized= false;
+        do
+        {
+          mipo= randomIrredpoly (deg, x);
+          if (initialized)
+            setMipo (V_buf, mipo);
+          else
+            V_buf= rootOf (mipo);
+          evalFail= false;
+          initialized= true;
+          evalPoints= evaluationPoints (A, B, Aeval, Beval, LCA, GF, V_buf,
+                                        evalFail, list);
+          deg++;
+        } while (evalFail);
+        V_buf4= V_buf;
+      }
+    }
+
+    g= gcd (Aeval, Beval);
+    g /= Lc (g);
+
+    if (degree (g) != degree (skel) || (skelSize != size (g)))
+    {
+      delete[] pEvalPoints;
+      fail= true;
+      if (alpha.level() != 1 && V_buf != alpha)
+        prune1 (alpha);
+      return 0;
+    }
+    CFIterator l= skel;
+    for (CFIterator k= g; k.hasTerms(); k++, l++)
+    {
+      if (k.exp() != l.exp())
+      {
+        delete[] pEvalPoints;
+        fail= true;
+        if (alpha.level() != 1 && V_buf != alpha)
+          prune1 (alpha);
+        return 0;
+      }
+    }
+    pEvalPoints[i]= evalPoints;
+    gcds[i]= g;
+
+    tmp= 0;
+    int j= 0;
+    for (CFListIterator k= evalPoints; k.hasItem(); k++, j++)
+      tmp += k.getItem()*power (x, j);
+    list.append (tmp);
+  }
+
+  if (Monoms.size() == 0)
+    Monoms= getMonoms (skel);
+
+  coeffMonoms= new CFArray [skelSize];
+  j= 0;
+  for (CFIterator i= skel; i.hasTerms(); i++, j++)
+    coeffMonoms[j]= getMonoms (i.coeff());
+
+  CFArray* pL= new CFArray [skelSize];
+  CFArray* pM= new CFArray [skelSize];
+  for (int i= 0; i < biggestSize; i++)
+  {
+    CFIterator l= gcds [i];
+    evalPoints= pEvalPoints [i];
+    for (int k= 0; k < skelSize; k++, l++)
+    {
+      if (i == 0)
+        pL[k]= CFArray (biggestSize);
+      pL[k] [i]= l.coeff();
+
+      if (i == 0)
+        pM[k]= evaluate (coeffMonoms [k], evalPoints);
+    }
+  }
+
+  CFArray solution;
+  CanonicalForm result= 0;
+  int ind= 0;
+  CFArray bufArray;
+  CFMatrix Mat;
+  for (int k= 0; k < skelSize; k++)
+  {
+    if (biggestSize != coeffMonoms[k].size())
+    {
+      bufArray= CFArray (coeffMonoms[k].size());
+      for (int i= 0; i < coeffMonoms[k].size(); i++)
+        bufArray [i]= pL[k] [i];
+      solution= solveGeneralVandermonde (pM [k], bufArray);
+    }
+    else
+      solution= solveGeneralVandermonde (pM [k], pL[k]);
+
+    if (solution.size() == 0)
+    {
+      delete[] pEvalPoints;
+      delete[] pM;
+      delete[] pL;
+      delete[] coeffMonoms;
+      fail= true;
+      if (alpha.level() != 1 && V_buf != alpha)
+        prune1 (alpha);
+      return 0;
+    }
+    for (int l= 0; l < solution.size(); l++)
+      result += solution[l]*Monoms [ind + l];
+    ind += solution.size();
+  }
+
+  delete[] pEvalPoints;
+  delete[] pM;
+  delete[] pL;
+  delete[] coeffMonoms;
+
+  if (alpha.level() != 1 && V_buf != alpha)
+  {
+    CFList u, v;
+    result= mapDown (result, prim_elem_alpha, im_prim_elem_alpha, alpha, u, v);
+    prune1 (alpha);
+  }
+
+  result= N(result);
+  if (fdivides (result, F) && fdivides (result, G))
+    return result;
+  else
+  {
+    fail= true;
+    return 0;
+  }
+}
+
+CanonicalForm
+nonMonicSparseInterpol (const CanonicalForm& F, const CanonicalForm& G,
+                        const CanonicalForm& skeleton, const Variable& alpha,
+                        bool& fail, CFArray*& coeffMonoms, CFArray& Monoms
+                       )
+{
+  CanonicalForm A= F;
+  CanonicalForm B= G;
+  if (F.isZero() && degree(G) > 0) return G/Lc(G);
+  else if (G.isZero() && degree (F) > 0) return F/Lc(F);
+  else if (F.isZero() && G.isZero()) return F.genOne();
+  if (F.inBaseDomain() || G.inBaseDomain()) return F.genOne();
+  if (F.isUnivariate() && fdivides(F, G)) return F/Lc(F);
+  if (G.isUnivariate() && fdivides(G, F)) return G/Lc(G);
+  if (F == G) return F/Lc(F);
+
+  ASSERT (degree (A, 1) == 0, "expected degree (F, 1) == 0");
+  ASSERT (degree (B, 1) == 0, "expected degree (G, 1) == 0");
+
+  CFMap M,N;
+  int best_level= myCompress (A, B, M, N, false);
+
+  if (best_level == 0)
+    return B.genOne();
+
+  A= M(A);
+  B= M(B);
+
+  Variable x= Variable (1);
+
+  //univariate case
+  if (A.isUnivariate() && B.isUnivariate())
+    return N (gcd (A, B));
+
+  CanonicalForm skel= M(skeleton);
+
+  CanonicalForm cA, cB;    // content of A and B
+  CanonicalForm ppA, ppB;    // primitive part of A and B
+  CanonicalForm gcdcAcB;
+  cA = uni_content (A);
+  cB = uni_content (B);
+  gcdcAcB= gcd (cA, cB);
+  ppA= A/cA;
+  ppB= B/cB;
+
+  CanonicalForm lcA, lcB;  // leading coefficients of A and B
+  CanonicalForm gcdlcAlcB;
+  lcA= uni_lcoeff (ppA);
+  lcB= uni_lcoeff (ppB);
+
+  if (fdivides (lcA, lcB))
+  {
+    if (fdivides (A, B))
+      return F/Lc(F);
+  }
+  if (fdivides (lcB, lcA))
+  {
+    if (fdivides (B, A))
+      return G/Lc(G);
+  }
+
+  gcdlcAlcB= gcd (lcA, lcB);
+  int skelSize= size (skel, skel.mvar());
+
+  int j= 0;
+  int biggestSize= 0;
+  int bufSize;
+  int numberUni= 0;
+  for (CFIterator i= skel; i.hasTerms(); i++, j++)
+  {
+    bufSize= size (i.coeff());
+    biggestSize= tmax (biggestSize, bufSize);
+    numberUni += bufSize;
+  }
+  numberUni--;
+  numberUni= (int) ceil ( (double) numberUni / (skelSize - 1));
+  biggestSize= tmax (biggestSize , numberUni);
+
+  numberUni= biggestSize + size (LC(skel)) - 1;
+  int biggestSize2= tmax (numberUni, biggestSize);
+
+  CanonicalForm g, Aeval, Beval;
+
+  CFList evalPoints;
+  CFArray coeffEval;
+  bool evalFail= false;
+  CFList list;
+  bool GF= false;
+  CanonicalForm LCA= LC (A);
+  CanonicalForm tmp;
+  CFArray gcds= CFArray (biggestSize);
+  CFList * pEvalPoints= new CFList [biggestSize];
+  Variable V_buf= alpha, V_buf4= alpha;
+  CFList source, dest;
+  CanonicalForm prim_elem, im_prim_elem;
+  CanonicalForm prim_elem_alpha, im_prim_elem_alpha;
+  for (int i= 0; i < biggestSize; i++)
+  {
+    if (i == 0)
+    {
+      if (getCharacteristic() > 3)
+        evalPoints= evaluationPoints (A, B, Aeval, Beval, LCA, GF, V_buf,
+                                    evalFail, list);
+      else
+        evalFail= true;
+
+      if (evalFail)
+      {
+        if (V_buf.level() != 1)
+        {
+          do
+          {
+            Variable V_buf3= V_buf;
+            V_buf= chooseExtension (V_buf);
+            source= CFList();
+            dest= CFList();
+
+            bool prim_fail= false;
+            Variable V_buf2;
+            prim_elem= primitiveElement (V_buf4, V_buf2, prim_fail);
+            if (V_buf4 == alpha && alpha.level() != 1)
+              prim_elem_alpha= prim_elem;
+
+            ASSERT (!prim_fail, "failure in integer factorizer");
+            if (prim_fail)
+              ; //ERROR
+            else
+              im_prim_elem= mapPrimElem (prim_elem, V_buf4, V_buf);
+
+            DEBOUTLN (cerr, "getMipo (V_buf)= " << getMipo (V_buf));
+            DEBOUTLN (cerr, "getMipo (V_buf2)= " << getMipo (V_buf2));
+
+            if (V_buf4 == alpha && alpha.level() != 1)
+              im_prim_elem_alpha= im_prim_elem;
+            else if (alpha.level() != 1)
+              im_prim_elem_alpha= mapUp (im_prim_elem_alpha, V_buf4, V_buf,
+                                         prim_elem, im_prim_elem, source, dest);
+
+            for (CFListIterator i= list; i.hasItem(); i++)
+              i.getItem()= mapUp (i.getItem(), V_buf4, V_buf, prim_elem,
+                                im_prim_elem, source, dest);
+            if (alpha.level() != 1)
+            {
+              A= mapUp (A, V_buf4, V_buf, prim_elem, im_prim_elem, source,dest);
+              B= mapUp (B, V_buf4, V_buf, prim_elem, im_prim_elem, source,dest);
+            }
+            evalFail= false;
+            V_buf4= V_buf;
+            evalPoints= evaluationPoints (A, B, Aeval, Beval, LCA, GF, V_buf,
+                                          evalFail, list);
+          } while (evalFail);
+        }
+        else
+        {
+          CanonicalForm mipo;
+          int deg= 2;
+          bool initialized= false;
+          do
+          {
+            mipo= randomIrredpoly (deg, x);
+            if (initialized)
+              setMipo (V_buf, mipo);
+            else
+              V_buf= rootOf (mipo);
+            evalFail= false;
+            initialized= true;
+            evalPoints= evaluationPoints (A, B, Aeval, Beval, LCA, GF, V_buf,
+                                          evalFail, list);
+            deg++;
+          } while (evalFail);
+          V_buf4= V_buf;
+        }
+      }
+    }
+    else
+    {
+      mult (evalPoints, pEvalPoints[0]);
+      eval (A, B, Aeval, Beval, evalPoints);
+    }
+
+    g= gcd (Aeval, Beval);
+    g /= Lc (g);
+
+    if (degree (g) != degree (skel) || (skelSize != size (g)))
+    {
+      delete[] pEvalPoints;
+      fail= true;
+      if (alpha.level() != 1 && V_buf != alpha)
+        prune1 (alpha);
+      return 0;
+    }
+    CFIterator l= skel;
+    for (CFIterator k= g; k.hasTerms(); k++, l++)
+    {
+      if (k.exp() != l.exp())
+      {
+        delete[] pEvalPoints;
+        fail= true;
+        if (alpha.level() != 1 && V_buf != alpha)
+          prune1 (alpha);
+        return 0;
+      }
+    }
+    pEvalPoints[i]= evalPoints;
+    gcds[i]= g;
+
+    tmp= 0;
+    int j= 0;
+    for (CFListIterator k= evalPoints; k.hasItem(); k++, j++)
+      tmp += k.getItem()*power (x, j);
+    list.append (tmp);
+  }
+
+  if (Monoms.size() == 0)
+    Monoms= getMonoms (skel);
+
+  coeffMonoms= new CFArray [skelSize];
+
+  j= 0;
+  for (CFIterator i= skel; i.hasTerms(); i++, j++)
+    coeffMonoms[j]= getMonoms (i.coeff());
+
+  int minimalColumnsIndex;
+  if (skelSize > 1)
+    minimalColumnsIndex= 1;
+  else
+    minimalColumnsIndex= 0;
+  int minimalColumns=-1;
+
+  CFArray* pM= new CFArray [skelSize];
+  CFMatrix Mat;
+  // find the Matrix with minimal number of columns
+  for (int i= 0; i < skelSize; i++)
+  {
+    pM[i]= CFArray (coeffMonoms[i].size());
+    if (i == 1)
+      minimalColumns= coeffMonoms[i].size();
+    if (i > 1)
+    {
+      if (minimalColumns > coeffMonoms[i].size())
+      {
+        minimalColumns= coeffMonoms[i].size();
+        minimalColumnsIndex= i;
+      }
+    }
+  }
+  CFMatrix* pMat= new CFMatrix [2];
+  pMat[0]= CFMatrix (biggestSize, coeffMonoms[0].size());
+  pMat[1]= CFMatrix (biggestSize, coeffMonoms[minimalColumnsIndex].size());
+  CFArray* pL= new CFArray [skelSize];
+  for (int i= 0; i < biggestSize; i++)
+  {
+    CFIterator l= gcds [i];
+    evalPoints= pEvalPoints [i];
+    for (int k= 0; k < skelSize; k++, l++)
+    {
+      if (i == 0)
+        pL[k]= CFArray (biggestSize);
+      pL[k] [i]= l.coeff();
+
+      if (i == 0 && k != 0 && k != minimalColumnsIndex)
+        pM[k]= evaluate (coeffMonoms[k], evalPoints);
+      else if (i == 0 && (k == 0 || k == minimalColumnsIndex))
+        coeffEval= evaluate (coeffMonoms[k], evalPoints);
+      if (i > 0 && (k == 0 || k == minimalColumnsIndex))
+        coeffEval= evaluate (coeffMonoms[k], evalPoints);
+
+      if (k == 0)
+      {
+        if (pMat[k].rows() >= i + 1)
+        {
+          for (int ind= 1; ind < coeffEval.size() + 1; ind++)
+            pMat[k] (i + 1, ind)= coeffEval[ind - 1];
+        }
+      }
+      if (k == minimalColumnsIndex)
+      {
+        if (pMat[1].rows() >= i + 1)
+        {
+          for (int ind= 1; ind < coeffEval.size() + 1; ind++)
+            pMat[1] (i + 1, ind)= coeffEval[ind - 1];
+        }
+      }
+    }
+  }
+
+  CFArray solution;
+  CanonicalForm result= 0;
+  int ind= 1;
+  int matRows, matColumns;
+  matRows= pMat[1].rows();
+  matColumns= pMat[0].columns() - 1;
+  matColumns += pMat[1].columns();
+
+  Mat= CFMatrix (matRows, matColumns);
+  for (int i= 1; i <= matRows; i++)
+    for (int j= 1; j <= pMat[1].columns(); j++)
+      Mat (i, j)= pMat[1] (i, j);
+
+  for (int j= pMat[1].columns() + 1; j <= matColumns;
+       j++, ind++)
+  {
+    for (int i= 1; i <= matRows; i++)
+      Mat (i, j)= (-pMat [0] (i, ind + 1))*pL[minimalColumnsIndex] [i - 1];
+  }
+
+  CFArray firstColumn= CFArray (pMat[0].rows());
+  for (int i= 0; i < pMat[0].rows(); i++)
+    firstColumn [i]= pMat[0] (i + 1, 1);
+
+  CFArray bufArray= pL[minimalColumnsIndex];
+
+  for (int i= 0; i < biggestSize; i++)
+    pL[minimalColumnsIndex] [i] *= firstColumn[i];
+
+  CFMatrix bufMat= pMat[1];
+  pMat[1]= Mat;
+
+  if (V_buf.level() != 1)
+    solution= solveSystemFq (pMat[1],
+                             pL[minimalColumnsIndex], V_buf);
+  else
+    solution= solveSystemFp (pMat[1],
+                             pL[minimalColumnsIndex]);
+
+  if (solution.size() == 0)
+  { //Javadi's method failed, try deKleine, Monagan, Wittkopf instead
+    CFMatrix bufMat0= pMat[0];
+    delete [] pMat;
+    pMat= new CFMatrix [skelSize];
+    pL[minimalColumnsIndex]= bufArray;
+    CFList* bufpEvalPoints= NULL;
+    CFArray bufGcds;
+    if (biggestSize != biggestSize2)
+    {
+      bufpEvalPoints= pEvalPoints;
+      pEvalPoints= new CFList [biggestSize2];
+      bufGcds= gcds;
+      gcds= CFArray (biggestSize2);
+      for (int i= 0; i < biggestSize; i++)
+      {
+        pEvalPoints[i]= bufpEvalPoints [i];
+        gcds[i]= bufGcds[i];
+      }
+      for (int i= 0; i < biggestSize2 - biggestSize; i++)
+      {
+        mult (evalPoints, pEvalPoints[0]);
+        eval (A, B, Aeval, Beval, evalPoints);
+        g= gcd (Aeval, Beval);
+        g /= Lc (g);
+        if (degree (g) != degree (skel) || (skelSize != size (g)))
+        {
+          delete[] pEvalPoints;
+          delete[] pMat;
+          delete[] pL;
+          delete[] coeffMonoms;
+          delete[] pM;
+          if (bufpEvalPoints != NULL)
+            delete [] bufpEvalPoints;
+          fail= true;
+          if (alpha.level() != 1 && V_buf != alpha)
+            prune1 (alpha);
+          return 0;
+        }
+        CFIterator l= skel;
+        for (CFIterator k= g; k.hasTerms(); k++, l++)
+        {
+          if (k.exp() != l.exp())
+          {
+            delete[] pEvalPoints;
+            delete[] pMat;
+            delete[] pL;
+            delete[] coeffMonoms;
+            delete[] pM;
+            if (bufpEvalPoints != NULL)
+              delete [] bufpEvalPoints;
+            fail= true;
+            if (alpha.level() != 1 && V_buf != alpha)
+              prune1 (alpha);
+            return 0;
+          }
+        }
+        pEvalPoints[i + biggestSize]= evalPoints;
+        gcds[i + biggestSize]= g;
+      }
+    }
+    for (int i= 0; i < biggestSize; i++)
+    {
+      CFIterator l= gcds [i];
+      evalPoints= pEvalPoints [i];
+      for (int k= 1; k < skelSize; k++, l++)
+      {
+        if (i == 0)
+          pMat[k]= CFMatrix (biggestSize2,coeffMonoms[k].size()+biggestSize2-1);
+        if (k == minimalColumnsIndex)
+          continue;
+        coeffEval= evaluate (coeffMonoms[k], evalPoints);
+        if (pMat[k].rows() >= i + 1)
+        {
+          for (int ind= 1; ind < coeffEval.size() + 1; ind++)
+            pMat[k] (i + 1, ind)= coeffEval[ind - 1];
+        }
+      }
+    }
+    Mat= bufMat0;
+    pMat[0]= CFMatrix (biggestSize2, coeffMonoms[0].size() + biggestSize2 - 1);
+    for (int j= 1; j <= Mat.rows(); j++)
+      for (int k= 1; k <= Mat.columns(); k++)
+        pMat [0] (j,k)= Mat (j,k);
+    Mat= bufMat;
+    for (int j= 1; j <= Mat.rows(); j++)
+      for (int k= 1; k <= Mat.columns(); k++)
+        pMat [minimalColumnsIndex] (j,k)= Mat (j,k);
+    // write old matrix entries into new matrices
+    for (int i= 0; i < skelSize; i++)
+    {
+      bufArray= pL[i];
+      pL[i]= CFArray (biggestSize2);
+      for (int j= 0; j < bufArray.size(); j++)
+        pL[i] [j]= bufArray [j];
+    }
+    //write old vector entries into new and add new entries to old matrices
+    for (int i= 0; i < biggestSize2 - biggestSize; i++)
+    {
+      CFIterator l= gcds [i + biggestSize];
+      evalPoints= pEvalPoints [i + biggestSize];
+      for (int k= 0; k < skelSize; k++, l++)
+      {
+        pL[k] [i + biggestSize]= l.coeff();
+        coeffEval= evaluate (coeffMonoms[k], evalPoints);
+        if (pMat[k].rows() >= i + biggestSize + 1)
+        {
+          for (int ind= 1; ind < coeffEval.size() + 1; ind++)
+            pMat[k] (i + biggestSize + 1, ind)= coeffEval[ind - 1];
+        }
+      }
+    }
+    // begin new
+    for (int i= 0; i < skelSize; i++)
+    {
+      if (pL[i].size() > 1)
+      {
+        for (int j= 2; j <= pMat[i].rows(); j++)
+          pMat[i] (j, coeffMonoms[i].size() + j - 1)=
+              -pL[i] [j - 1];
+      }
+    }
+
+    matColumns= biggestSize2 - 1;
+    matRows= 0;
+    for (int i= 0; i < skelSize; i++)
+    {
+      if (V_buf.level() == 1)
+        (void) gaussianElimFp (pMat[i], pL[i]);
+      else
+        (void) gaussianElimFq (pMat[i], pL[i], V_buf);
+
+      if (pMat[i] (coeffMonoms[i].size(), coeffMonoms[i].size()) == 0)
+      {
+        delete[] pEvalPoints;
+        delete[] pMat;
+        delete[] pL;
+        delete[] coeffMonoms;
+        delete[] pM;
+        if (bufpEvalPoints != NULL)
+          delete [] bufpEvalPoints;
+        fail= true;
+        if (alpha.level() != 1 && V_buf != alpha)
+          prune1 (alpha);
+        return 0;
+      }
+      matRows += pMat[i].rows() - coeffMonoms[i].size();
+    }
+
+    CFMatrix bufMat;
+    Mat= CFMatrix (matRows, matColumns);
+    ind= 0;
+    bufArray= CFArray (matRows);
+    CFArray bufArray2;
+    for (int i= 0; i < skelSize; i++)
+    {
+      if (coeffMonoms[i].size() + 1 >= pMat[i].rows() || coeffMonoms[i].size() + 1 >= pMat[i].columns())
+      {
+        delete[] pEvalPoints;
+        delete[] pMat;
+        delete[] pL;
+        delete[] coeffMonoms;
+        delete[] pM;
+        if (bufpEvalPoints != NULL)
+          delete [] bufpEvalPoints;
+        fail= true;
+        if (alpha.level() != 1 && V_buf != alpha)
+          prune1 (alpha);
+        return 0;
+      }
+      bufMat= pMat[i] (coeffMonoms[i].size() + 1, pMat[i].rows(),
+                       coeffMonoms[i].size() + 1, pMat[i].columns());
+
+      for (int j= 1; j <= bufMat.rows(); j++)
+        for (int k= 1; k <= bufMat.columns(); k++)
+          Mat (j + ind, k)= bufMat(j, k);
+      bufArray2= coeffMonoms[i].size();
+      for (int j= 1; j <= pMat[i].rows(); j++)
+      {
+        if (j > coeffMonoms[i].size())
+          bufArray [j-coeffMonoms[i].size() + ind - 1]= pL[i] [j - 1];
+        else
+          bufArray2 [j - 1]= pL[i] [j - 1];
+      }
+      pL[i]= bufArray2;
+      ind += bufMat.rows();
+      pMat[i]= pMat[i] (1, coeffMonoms[i].size(), 1, pMat[i].columns());
+    }
+
+    if (V_buf.level() != 1)
+      solution= solveSystemFq (Mat, bufArray, V_buf);
+    else
+      solution= solveSystemFp (Mat, bufArray);
+
+    if (solution.size() == 0)
+    {
+      delete[] pEvalPoints;
+      delete[] pMat;
+      delete[] pL;
+      delete[] coeffMonoms;
+      delete[] pM;
+      if (bufpEvalPoints != NULL)
+        delete [] bufpEvalPoints;
+      fail= true;
+      if (alpha.level() != 1 && V_buf != alpha)
+        prune1 (alpha);
+      return 0;
+    }
+
+    ind= 0;
+    result= 0;
+    CFArray bufSolution;
+    for (int i= 0; i < skelSize; i++)
+    {
+      bufSolution= readOffSolution (pMat[i], pL[i], solution);
+      for (int i= 0; i < bufSolution.size(); i++, ind++)
+        result += Monoms [ind]*bufSolution[i];
+    }
+    if (alpha.level() != 1 && V_buf != alpha)
+    {
+      CFList u, v;
+      result= mapDown (result,prim_elem_alpha, im_prim_elem_alpha, alpha, u, v);
+      prune1 (alpha);
+    }
+    result= N(result);
+    delete[] pEvalPoints;
+    delete[] pMat;
+    delete[] pL;
+    delete[] coeffMonoms;
+    delete[] pM;
+
+    if (bufpEvalPoints != NULL)
+      delete [] bufpEvalPoints;
+    if (fdivides (result, F) && fdivides (result, G))
+      return result;
+    else
+    {
+      fail= true;
+      return 0;
+    }
+  } // end of deKleine, Monagan & Wittkopf
+
+  result += Monoms[0];
+  int ind2= 0, ind3= 2;
+  ind= 0;
+  for (int l= 0; l < minimalColumnsIndex; l++)
+    ind += coeffMonoms[l].size();
+  for (int l= solution.size() - pMat[0].columns() + 1; l < solution.size();
+       l++, ind2++, ind3++)
+  {
+    result += solution[l]*Monoms [1 + ind2];
+    for (int i= 0; i < pMat[0].rows(); i++)
+      firstColumn[i] += solution[l]*pMat[0] (i + 1, ind3);
+  }
+  for (int l= 0; l < solution.size() + 1 - pMat[0].columns(); l++)
+    result += solution[l]*Monoms [ind + l];
+  ind= coeffMonoms[0].size();
+  for (int k= 1; k < skelSize; k++)
+  {
+    if (k == minimalColumnsIndex)
+    {
+      ind += coeffMonoms[k].size();
+      continue;
+    }
+    if (k != minimalColumnsIndex)
+    {
+      for (int i= 0; i < biggestSize; i++)
+        pL[k] [i] *= firstColumn [i];
+    }
+
+    if (biggestSize != coeffMonoms[k].size() && k != minimalColumnsIndex)
+    {
+      bufArray= CFArray (coeffMonoms[k].size());
+      for (int i= 0; i < bufArray.size(); i++)
+        bufArray [i]= pL[k] [i];
+      solution= solveGeneralVandermonde (pM[k], bufArray);
+    }
+    else
+      solution= solveGeneralVandermonde (pM[k], pL[k]);
+
+    if (solution.size() == 0)
+    {
+      delete[] pEvalPoints;
+      delete[] pMat;
+      delete[] pL;
+      delete[] coeffMonoms;
+      delete[] pM;
+      fail= true;
+      if (alpha.level() != 1 && V_buf != alpha)
+        prune1 (alpha);
+      return 0;
+    }
+    if (k != minimalColumnsIndex)
+    {
+      for (int l= 0; l < solution.size(); l++)
+        result += solution[l]*Monoms [ind + l];
+      ind += solution.size();
+    }
+  }
+
+  delete[] pEvalPoints;
+  delete[] pMat;
+  delete[] pL;
+  delete[] pM;
+  delete[] coeffMonoms;
+
+  if (alpha.level() != 1 && V_buf != alpha)
+  {
+    CFList u, v;
+    result= mapDown (result, prim_elem, im_prim_elem, alpha, u, v);
+    prune1 (alpha);
+  }
+  result= N(result);
+
+  if (fdivides (result, F) && fdivides (result, G))
+    return result;
+  else
+  {
+    fail= true;
+    return 0;
+  }
+}
+
+CanonicalForm sparseGCDFq (const CanonicalForm& F, const CanonicalForm& G,
+                           const Variable & alpha, CFList& l, bool& topLevel)
+{
+  CanonicalForm A= F;
+  CanonicalForm B= G;
+  if (F.isZero() && degree(G) > 0) return G/Lc(G);
+  else if (G.isZero() && degree (F) > 0) return F/Lc(F);
+  else if (F.isZero() && G.isZero()) return F.genOne();
+  if (F.inBaseDomain() || G.inBaseDomain()) return F.genOne();
+  if (F.isUnivariate() && fdivides(F, G)) return F/Lc(F);
+  if (G.isUnivariate() && fdivides(G, F)) return G/Lc(G);
+  if (F == G) return F/Lc(F);
+
+  CFMap M,N;
+  int best_level= myCompress (A, B, M, N, topLevel);
+
+  if (best_level == 0) return B.genOne();
+
+  A= M(A);
+  B= M(B);
+
+  Variable x= Variable (1);
+
+  //univariate case
+  if (A.isUnivariate() && B.isUnivariate())
+    return N (gcd (A, B));
+
+  CanonicalForm cA, cB;    // content of A and B
+  CanonicalForm ppA, ppB;    // primitive part of A and B
+  CanonicalForm gcdcAcB;
+
+  cA = uni_content (A);
+  cB = uni_content (B);
+  gcdcAcB= gcd (cA, cB);
+  ppA= A/cA;
+  ppB= B/cB;
+
+  CanonicalForm lcA, lcB;  // leading coefficients of A and B
+  CanonicalForm gcdlcAlcB;
+  lcA= uni_lcoeff (ppA);
+  lcB= uni_lcoeff (ppB);
+
+  if (fdivides (lcA, lcB))
+  {
+    if (fdivides (A, B))
+      return F/Lc(F);
+  }
+  if (fdivides (lcB, lcA))
+  {
+    if (fdivides (B, A))
+      return G/Lc(G);
+  }
+
+  gcdlcAlcB= gcd (lcA, lcB);
+
+  int d= totaldegree (ppA, Variable (2), Variable (ppA.level()));
+  int d0;
+
+  if (d == 0)
+    return N(gcdcAcB);
+  d0= totaldegree (ppB, Variable (2), Variable (ppB.level()));
+
+  if (d0 < d)
+    d= d0;
+
+  if (d == 0)
+    return N(gcdcAcB);
+
+  CanonicalForm m, random_element, G_m, G_random_element, H, cH, ppH, skeleton;
+  CanonicalForm newtonPoly= 1;
+  m= gcdlcAlcB;
+  G_m= 0;
+  H= 0;
+  bool fail= false;
+  topLevel= false;
+  bool inextension= false;
+  Variable V_buf= alpha, V_buf4= alpha;
+  CanonicalForm prim_elem, im_prim_elem;
+  CanonicalForm prim_elem_alpha, im_prim_elem_alpha;
+  CFList source, dest;
+  do // first do
+  {
+    random_element= randomElement (m, V_buf, l, fail);
+    if (random_element == 0 && !fail)
+    {
+      if (!find (l, random_element))
+        l.append (random_element);
+      continue;
+    }
+    if (fail)
+    {
+      source= CFList();
+      dest= CFList();
+
+      Variable V_buf3= V_buf;
+      V_buf= chooseExtension (V_buf);
+      bool prim_fail= false;
+      Variable V_buf2;
+      prim_elem= primitiveElement (V_buf4, V_buf2, prim_fail);
+      if (V_buf4 == alpha)
+        prim_elem_alpha= prim_elem;
+
+      if (V_buf3 != V_buf4)
+      {
+        m= mapDown (m, prim_elem, im_prim_elem, V_buf4, source, dest);
+        G_m= mapDown (m, prim_elem, im_prim_elem, V_buf4, source, dest);
+        newtonPoly= mapDown (newtonPoly, prim_elem, im_prim_elem, V_buf4,
+                             source, dest);
+        ppA= mapDown (ppA, prim_elem, im_prim_elem, V_buf4, source, dest);
+        ppB= mapDown (ppB, prim_elem, im_prim_elem, V_buf4, source, dest);
+        gcdlcAlcB= mapDown (gcdlcAlcB, prim_elem, im_prim_elem, V_buf4, source,
+                            dest);
+        for (CFListIterator i= l; i.hasItem(); i++)
+          i.getItem()= mapDown (i.getItem(), prim_elem, im_prim_elem, V_buf4,
+                                source, dest);
+      }
+
+      ASSERT (!prim_fail, "failure in integer factorizer");
+      if (prim_fail)
+        ; //ERROR
+      else
+        im_prim_elem= mapPrimElem (prim_elem, V_buf4, V_buf);
+
+      if (V_buf4 == alpha)
+        im_prim_elem_alpha= im_prim_elem;
+      else
+        im_prim_elem_alpha= mapUp (im_prim_elem_alpha, V_buf4, V_buf, prim_elem,
+                                   im_prim_elem, source, dest);
+
+      DEBOUTLN (cerr, "getMipo (V_buf4)= " << getMipo (V_buf4));
+      DEBOUTLN (cerr, "getMipo (V_buf2)= " << getMipo (V_buf2));
+      inextension= true;
+      for (CFListIterator i= l; i.hasItem(); i++)
+        i.getItem()= mapUp (i.getItem(), V_buf4, V_buf, prim_elem,
+                             im_prim_elem, source, dest);
+      m= mapUp (m, V_buf4, V_buf, prim_elem, im_prim_elem, source, dest);
+      G_m= mapUp (G_m, V_buf4, V_buf, prim_elem, im_prim_elem, source, dest);
+      newtonPoly= mapUp (newtonPoly, V_buf4, V_buf, prim_elem, im_prim_elem,
+                          source, dest);
+      ppA= mapUp (ppA, V_buf4, V_buf, prim_elem, im_prim_elem, source, dest);
+      ppB= mapUp (ppB, V_buf4, V_buf, prim_elem, im_prim_elem, source, dest);
+      gcdlcAlcB= mapUp (gcdlcAlcB, V_buf4, V_buf, prim_elem, im_prim_elem,
+                         source, dest);
+
+      fail= false;
+      random_element= randomElement (m, V_buf, l, fail );
+      DEBOUTLN (cerr, "fail= " << fail);
+      CFList list;
+      TIMING_START (gcd_recursion);
+      G_random_element=
+      sparseGCDFq (ppA (random_element, x), ppB (random_element, x), V_buf,
+                        list, topLevel);
+      TIMING_END_AND_PRINT (gcd_recursion,
+                            "time for recursive call: ");
+      DEBOUTLN (cerr, "G_random_element= " << G_random_element);
+      V_buf4= V_buf;
+    }
+    else
+    {
+      CFList list;
+      TIMING_START (gcd_recursion);
+      G_random_element=
+      sparseGCDFq (ppA(random_element, x), ppB(random_element, x), V_buf,
+                        list, topLevel);
+      TIMING_END_AND_PRINT (gcd_recursion,
+                            "time for recursive call: ");
+      DEBOUTLN (cerr, "G_random_element= " << G_random_element);
+    }
+
+    if (!G_random_element.inCoeffDomain())
+      d0= totaldegree (G_random_element, Variable(2),
+                       Variable (G_random_element.level()));
+    else
+      d0= 0;
+
+    if (d0 == 0)
+    {
+      if (inextension)
+        prune1 (alpha);
+      return N(gcdcAcB);
+    }
+    if (d0 >  d)
+    {
+      if (!find (l, random_element))
+        l.append (random_element);
+      continue;
+    }
+
+    G_random_element=
+    (gcdlcAlcB(random_element, x)/uni_lcoeff (G_random_element))
+    * G_random_element;
+
+    skeleton= G_random_element;
+    if (!G_random_element.inCoeffDomain())
+      d0= totaldegree (G_random_element, Variable(2),
+                       Variable (G_random_element.level()));
+    else
+      d0= 0;
+
+    if (d0 <  d)
+    {
+      m= gcdlcAlcB;
+      newtonPoly= 1;
+      G_m= 0;
+      d= d0;
+    }
+
+    H= newtonInterp (random_element, G_random_element, newtonPoly, G_m, x);
+    if (uni_lcoeff (H) == gcdlcAlcB)
+    {
+      cH= uni_content (H);
+      ppH= H/cH;
+      if (inextension)
+      {
+        CFList u, v;
+        //maybe it's better to test if ppH is an element of F(\alpha) before
+        //mapping down
+        if (fdivides (ppH, ppA) && fdivides (ppH, ppB))
+        {
+          DEBOUTLN (cerr, "ppH before mapDown= " << ppH);
+          ppH= mapDown (ppH, prim_elem_alpha, im_prim_elem_alpha, alpha, u, v);
+          ppH /= Lc(ppH);
+          DEBOUTLN (cerr, "ppH after mapDown= " << ppH);
+          prune1 (alpha);
+          return N(gcdcAcB*ppH);
+        }
+      }
+      else if (fdivides (ppH, ppA) && fdivides (ppH, ppB))
+        return N(gcdcAcB*ppH);
+    }
+    G_m= H;
+    newtonPoly= newtonPoly*(x - random_element);
+    m= m*(x - random_element);
+    if (!find (l, random_element))
+      l.append (random_element);
+
+    if (getCharacteristic () > 3 && size (skeleton) < 100)
+    {
+      CFArray Monoms;
+      CFArray *coeffMonoms;
+      do //second do
+      {
+        random_element= randomElement (m, V_buf, l, fail);
+        if (random_element == 0 && !fail)
+        {
+          if (!find (l, random_element))
+            l.append (random_element);
+          continue;
+        }
+        if (fail)
+        {
+          source= CFList();
+          dest= CFList();
+
+          Variable V_buf3= V_buf;
+          V_buf= chooseExtension (V_buf);
+          bool prim_fail= false;
+          Variable V_buf2;
+          prim_elem= primitiveElement (V_buf4, V_buf2, prim_fail);
+          if (V_buf4 == alpha)
+            prim_elem_alpha= prim_elem;
+
+          if (V_buf3 != V_buf4)
+          {
+            m= mapDown (m, prim_elem, im_prim_elem, V_buf4, source, dest);
+            G_m= mapDown (m, prim_elem, im_prim_elem, V_buf4, source, dest);
+            newtonPoly= mapDown (newtonPoly, prim_elem, im_prim_elem, V_buf4,
+                                 source, dest);
+            ppA= mapDown (ppA, prim_elem, im_prim_elem, V_buf4, source, dest);
+            ppB= mapDown (ppB, prim_elem, im_prim_elem, V_buf4, source, dest);
+            gcdlcAlcB= mapDown (gcdlcAlcB, prim_elem, im_prim_elem, V_buf4,
+                                source, dest);
+            for (CFListIterator i= l; i.hasItem(); i++)
+              i.getItem()= mapDown (i.getItem(), prim_elem, im_prim_elem, V_buf4,
+                                    source, dest);
+          }
+
+          ASSERT (!prim_fail, "failure in integer factorizer");
+          if (prim_fail)
+            ; //ERROR
+          else
+            im_prim_elem= mapPrimElem (prim_elem, V_buf4, V_buf);
+
+          if (V_buf4 == alpha)
+            im_prim_elem_alpha= im_prim_elem;
+          else
+            im_prim_elem_alpha= mapUp (im_prim_elem_alpha, V_buf4, V_buf,
+                                       prim_elem, im_prim_elem, source, dest);
+
+          DEBOUTLN (cerr, "getMipo (V_buf4)= " << getMipo (V_buf4));
+          DEBOUTLN (cerr, "getMipo (V_buf2)= " << getMipo (V_buf2));
+          inextension= true;
+          for (CFListIterator i= l; i.hasItem(); i++)
+            i.getItem()= mapUp (i.getItem(), V_buf4, V_buf, prim_elem,
+                                im_prim_elem, source, dest);
+          m= mapUp (m, V_buf4, V_buf, prim_elem, im_prim_elem, source, dest);
+          G_m= mapUp (G_m, V_buf4, V_buf, prim_elem, im_prim_elem, source, dest);
+          newtonPoly= mapUp (newtonPoly, V_buf4, V_buf, prim_elem, im_prim_elem,
+                              source, dest);
+          ppA= mapUp (ppA, V_buf4, V_buf, prim_elem, im_prim_elem, source, dest);
+          ppB= mapUp (ppB, V_buf4, V_buf, prim_elem, im_prim_elem, source, dest);
+
+          gcdlcAlcB= mapUp (gcdlcAlcB, V_buf4, V_buf, prim_elem, im_prim_elem,
+                            source, dest);
+
+          fail= false;
+          random_element= randomElement (m, V_buf, l, fail);
+          DEBOUTLN (cerr, "fail= " << fail);
+          CFList list;
+          TIMING_START (gcd_recursion);
+
+          V_buf4= V_buf;
+
+          //sparseInterpolation
+          bool sparseFail= false;
+          if (LC (skeleton).inCoeffDomain())
+            G_random_element=
+            monicSparseInterpol (ppA (random_element, x), ppB(random_element,x),
+                                skeleton,V_buf, sparseFail, coeffMonoms,Monoms);
+          else
+            G_random_element=
+            nonMonicSparseInterpol (ppA(random_element,x),ppB(random_element,x),
+                                    skeleton, V_buf, sparseFail, coeffMonoms,
+                                    Monoms);
+          if (sparseFail)
+            break;
+
+          TIMING_END_AND_PRINT (gcd_recursion,
+                                "time for recursive call: ");
+          DEBOUTLN (cerr, "G_random_element= " << G_random_element);
+        }
+        else
+        {
+          CFList list;
+          TIMING_START (gcd_recursion);
+          bool sparseFail= false;
+          if (LC (skeleton).inCoeffDomain())
+            G_random_element=
+            monicSparseInterpol (ppA (random_element, x),ppB(random_element, x),
+                                skeleton,V_buf, sparseFail,coeffMonoms, Monoms);
+          else
+            G_random_element=
+            nonMonicSparseInterpol (ppA(random_element,x),ppB(random_element,x),
+                                    skeleton, V_buf, sparseFail, coeffMonoms,
+                                    Monoms);
+          if (sparseFail)
+            break;
+
+          TIMING_END_AND_PRINT (gcd_recursion,
+                                "time for recursive call: ");
+          DEBOUTLN (cerr, "G_random_element= " << G_random_element);
+        }
+
+        if (!G_random_element.inCoeffDomain())
+          d0= totaldegree (G_random_element, Variable(2),
+                           Variable (G_random_element.level()));
+        else
+          d0= 0;
+
+        if (d0 == 0)
+        {
+          if (inextension)
+            prune1 (alpha);
+          return N(gcdcAcB);
+        }
+        if (d0 >  d)
+        {
+          if (!find (l, random_element))
+            l.append (random_element);
+          continue;
+        }
+
+        G_random_element=
+        (gcdlcAlcB(random_element, x)/uni_lcoeff (G_random_element))
+        * G_random_element;
+
+        if (!G_random_element.inCoeffDomain())
+          d0= totaldegree (G_random_element, Variable(2),
+                          Variable (G_random_element.level()));
+        else
+          d0= 0;
+
+        if (d0 <  d)
+        {
+          m= gcdlcAlcB;
+          newtonPoly= 1;
+          G_m= 0;
+          d= d0;
+        }
+
+        TIMING_START (newton_interpolation);
+        H= newtonInterp (random_element, G_random_element, newtonPoly, G_m, x);
+        TIMING_END_AND_PRINT (newton_interpolation,
+                              "time for newton interpolation: ");
+
+        //termination test
+        if (uni_lcoeff (H) == gcdlcAlcB)
+        {
+          cH= uni_content (H);
+          ppH= H/cH;
+          if (inextension)
+          {
+            CFList u, v;
+            //maybe it's better to test if ppH is an element of F(\alpha) before
+            //mapping down
+            if (fdivides (ppH, ppA) && fdivides (ppH, ppB))
+            {
+              DEBOUTLN (cerr, "ppH before mapDown= " << ppH);
+              ppH= mapDown (ppH, prim_elem_alpha, im_prim_elem_alpha, alpha, u, v);
+              ppH /= Lc(ppH);
+              DEBOUTLN (cerr, "ppH after mapDown= " << ppH);
+              prune1 (alpha);
+              return N(gcdcAcB*ppH);
+            }
+          }
+          else if (fdivides (ppH, ppA) && fdivides (ppH, ppB))
+          {
+            return N(gcdcAcB*ppH);
+          }
+        }
+
+        G_m= H;
+        newtonPoly= newtonPoly*(x - random_element);
+        m= m*(x - random_element);
+        if (!find (l, random_element))
+          l.append (random_element);
+
+      } while (1);
+    }
+  } while (1);
+}
+
+CanonicalForm sparseGCDFp (const CanonicalForm& F, const CanonicalForm& G,
+                           bool& topLevel, CFList& l)
+{
+  CanonicalForm A= F;
+  CanonicalForm B= G;
+  if (F.isZero() && degree(G) > 0) return G/Lc(G);
+  else if (G.isZero() && degree (F) > 0) return F/Lc(F);
+  else if (F.isZero() && G.isZero()) return F.genOne();
+  if (F.inBaseDomain() || G.inBaseDomain()) return F.genOne();
+  if (F.isUnivariate() && fdivides(F, G)) return F/Lc(F);
+  if (G.isUnivariate() && fdivides(G, F)) return G/Lc(G);
+  if (F == G) return F/Lc(F);
+
+  CFMap M,N;
+  int best_level= myCompress (A, B, M, N, topLevel);
+
+  if (best_level == 0) return B.genOne();
+
+  A= M(A);
+  B= M(B);
+
+  Variable x= Variable (1);
+
+  //univariate case
+  if (A.isUnivariate() && B.isUnivariate())
+    return N (gcd (A, B));
+
+  CanonicalForm cA, cB;    // content of A and B
+  CanonicalForm ppA, ppB;    // primitive part of A and B
+  CanonicalForm gcdcAcB;
+
+  cA = uni_content (A);
+  cB = uni_content (B);
+  gcdcAcB= gcd (cA, cB);
+  ppA= A/cA;
+  ppB= B/cB;
+
+  CanonicalForm lcA, lcB;  // leading coefficients of A and B
+  CanonicalForm gcdlcAlcB;
+  lcA= uni_lcoeff (ppA);
+  lcB= uni_lcoeff (ppB);
+
+  if (fdivides (lcA, lcB))
+  {
+    if (fdivides (A, B))
+      return F/Lc(F);
+  }
+  if (fdivides (lcB, lcA))
+  {
+    if (fdivides (B, A))
+      return G/Lc(G);
+  }
+
+  gcdlcAlcB= gcd (lcA, lcB);
+
+  int d= totaldegree (ppA, Variable (2), Variable (ppA.level()));
+  int d0;
+
+  if (d == 0)
+    return N(gcdcAcB);
+
+  d0= totaldegree (ppB, Variable (2), Variable (ppB.level()));
+
+  if (d0 < d)
+    d= d0;
+
+  if (d == 0)
+    return N(gcdcAcB);
+
+  CanonicalForm m, random_element, G_m, G_random_element, H, cH, ppH, skeleton;
+  CanonicalForm newtonPoly= 1;
+  m= gcdlcAlcB;
+  G_m= 0;
+  H= 0;
+  bool fail= false;
+  topLevel= false;
+  bool inextension= false;
+  Variable V_buf, alpha, cleanUp;
+  CanonicalForm prim_elem, im_prim_elem;
+  CFList source, dest;
+  do //first do
+  {
+    if (inextension)
+      random_element= randomElement (m, V_buf, l, fail);
+    else
+      random_element= FpRandomElement (m, l, fail);
+    if (random_element == 0 && !fail)
+    {
+      if (!find (l, random_element))
+        l.append (random_element);
+      continue;
+    }
+
+    if (!fail && !inextension)
+    {
+      CFList list;
+      TIMING_START (gcd_recursion);
+      G_random_element=
+      sparseGCDFp (ppA (random_element,x), ppB (random_element,x), topLevel,
+                   list);
+      TIMING_END_AND_PRINT (gcd_recursion,
+                            "time for recursive call: ");
+      DEBOUTLN (cerr, "G_random_element= " << G_random_element);
+    }
+    else if (!fail && inextension)
+    {
+      CFList list;
+      TIMING_START (gcd_recursion);
+      G_random_element=
+      sparseGCDFq (ppA (random_element, x), ppB (random_element, x), alpha,
+                        list, topLevel);
+      TIMING_END_AND_PRINT (gcd_recursion,
+                            "time for recursive call: ");
+      DEBOUTLN (cerr, "G_random_element= " << G_random_element);
+    }
+    else if (fail && !inextension)
+    {
+      source= CFList();
+      dest= CFList();
+      CFList list;
+      CanonicalForm mipo;
+      int deg= 2;
+      bool initialized= false;
+      do
+      {
+        mipo= randomIrredpoly (deg, x);
+        if (initialized)
+          setMipo (alpha, mipo);
+        else
+          alpha= rootOf (mipo);
+        inextension= true;
+        fail= false;
+        initialized= true;
+        random_element= randomElement (m, alpha, l, fail);
+        deg++;
+      } while (fail);
+      cleanUp= alpha;
+      V_buf= alpha;
+      list= CFList();
+      TIMING_START (gcd_recursion);
+      G_random_element=
+      sparseGCDFq (ppA (random_element, x), ppB (random_element, x), alpha,
+                        list, topLevel);
+      TIMING_END_AND_PRINT (gcd_recursion,
+                            "time for recursive call: ");
+      DEBOUTLN (cerr, "G_random_element= " << G_random_element);
+    }
+    else if (fail && inextension)
+    {
+      source= CFList();
+      dest= CFList();
+
+      Variable V_buf3= V_buf;
+      V_buf= chooseExtension (V_buf);
+      bool prim_fail= false;
+      Variable V_buf2;
+      CanonicalForm prim_elem, im_prim_elem;
+      prim_elem= primitiveElement (alpha, V_buf2, prim_fail);
+
+      if (V_buf3 != alpha)
+      {
+        m= mapDown (m, prim_elem, im_prim_elem, alpha, source, dest);
+        G_m= mapDown (m, prim_elem, im_prim_elem, alpha, source, dest);
+        newtonPoly= mapDown (newtonPoly, prim_elem, im_prim_elem, alpha, source,
+                             dest);
+        ppA= mapDown (ppA, prim_elem, im_prim_elem, alpha, source, dest);
+        ppB= mapDown (ppB, prim_elem, im_prim_elem, alpha, source, dest);
+        gcdlcAlcB= mapDown (gcdlcAlcB, prim_elem, im_prim_elem, alpha, source,
+                            dest);
+        for (CFListIterator i= l; i.hasItem(); i++)
+          i.getItem()= mapDown (i.getItem(), prim_elem, im_prim_elem, alpha,
+                                source, dest);
+      }
+
+      ASSERT (!prim_fail, "failure in integer factorizer");
+      if (prim_fail)
+        ; //ERROR
+      else
+        im_prim_elem= mapPrimElem (prim_elem, alpha, V_buf);
+
+      DEBOUTLN (cerr, "getMipo (alpha)= " << getMipo (alpha));
+      DEBOUTLN (cerr, "getMipo (alpha)= " << getMipo (V_buf2));
+
+      for (CFListIterator i= l; i.hasItem(); i++)
+        i.getItem()= mapUp (i.getItem(), alpha, V_buf, prim_elem,
+                             im_prim_elem, source, dest);
+      m= mapUp (m, alpha, V_buf, prim_elem, im_prim_elem, source, dest);
+      G_m= mapUp (G_m, alpha, V_buf, prim_elem, im_prim_elem, source, dest);
+      newtonPoly= mapUp (newtonPoly, alpha, V_buf, prim_elem, im_prim_elem,
+                          source, dest);
+      ppA= mapUp (ppA, alpha, V_buf, prim_elem, im_prim_elem, source, dest);
+      ppB= mapUp (ppB, alpha, V_buf, prim_elem, im_prim_elem, source, dest);
+      gcdlcAlcB= mapUp (gcdlcAlcB, alpha, V_buf, prim_elem, im_prim_elem,
+                         source, dest);
+      fail= false;
+      random_element= randomElement (m, V_buf, l, fail );
+      DEBOUTLN (cerr, "fail= " << fail);
+      CFList list;
+      TIMING_START (gcd_recursion);
+      G_random_element=
+      sparseGCDFq (ppA (random_element, x), ppB (random_element, x), V_buf,
+                        list, topLevel);
+      TIMING_END_AND_PRINT (gcd_recursion,
+                            "time for recursive call: ");
+      DEBOUTLN (cerr, "G_random_element= " << G_random_element);
+      alpha= V_buf;
+    }
+
+    if (!G_random_element.inCoeffDomain())
+      d0= totaldegree (G_random_element, Variable(2),
+                       Variable (G_random_element.level()));
+    else
+      d0= 0;
+
+    if (d0 == 0)
+    {
+      if (inextension)
+        prune (cleanUp);
+      return N(gcdcAcB);
+    }
+    if (d0 >  d)
+    {
+      if (!find (l, random_element))
+        l.append (random_element);
+      continue;
+    }
+
+    G_random_element=
+    (gcdlcAlcB(random_element, x)/uni_lcoeff (G_random_element))
+    * G_random_element;
+
+    skeleton= G_random_element;
+
+    if (!G_random_element.inCoeffDomain())
+      d0= totaldegree (G_random_element, Variable(2),
+                       Variable (G_random_element.level()));
+    else
+      d0= 0;
+
+    if (d0 <  d)
+    {
+      m= gcdlcAlcB;
+      newtonPoly= 1;
+      G_m= 0;
+      d= d0;
+    }
+
+    H= newtonInterp (random_element, G_random_element, newtonPoly, G_m, x);
+
+    if (uni_lcoeff (H) == gcdlcAlcB)
+    {
+      cH= uni_content (H);
+      ppH= H/cH;
+      ppH /= Lc (ppH);
+      DEBOUTLN (cerr, "ppH= " << ppH);
+
+      if (fdivides (ppH, ppA) && fdivides (ppH, ppB))
+      {
+        if (inextension)
+          prune (cleanUp);
+        return N(gcdcAcB*ppH);
+      }
+    }
+    G_m= H;
+    newtonPoly= newtonPoly*(x - random_element);
+    m= m*(x - random_element);
+    if (!find (l, random_element))
+      l.append (random_element);
+
+    if ((getCharacteristic() > 3 && size (skeleton) < 200))
+    {
+      CFArray Monoms;
+      CFArray* coeffMonoms;
+
+      do //second do
+      {
+        if (inextension)
+          random_element= randomElement (m, alpha, l, fail);
+        else
+          random_element= FpRandomElement (m, l, fail);
+        if (random_element == 0 && !fail)
+        {
+          if (!find (l, random_element))
+            l.append (random_element);
+          continue;
+        }
+
+        bool sparseFail= false;
+        if (!fail && !inextension)
+        {
+          CFList list;
+          TIMING_START (gcd_recursion);
+          if (LC (skeleton).inCoeffDomain())
+            G_random_element=
+            monicSparseInterpol(ppA(random_element, x), ppB (random_element, x),
+                                skeleton, x, sparseFail, coeffMonoms,
+                                Monoms);
+          else
+            G_random_element=
+            nonMonicSparseInterpol(ppA(random_element,x), ppB(random_element,x),
+                                    skeleton, x, sparseFail,
+                                    coeffMonoms, Monoms);
+          TIMING_END_AND_PRINT (gcd_recursion,
+                                "time for recursive call: ");
+          DEBOUTLN (cerr, "G_random_element= " << G_random_element);
+        }
+        else if (!fail && inextension)
+        {
+          CFList list;
+          TIMING_START (gcd_recursion);
+          if (LC (skeleton).inCoeffDomain())
+            G_random_element=
+            monicSparseInterpol(ppA (random_element,x), ppB (random_element, x),
+                                skeleton, alpha, sparseFail, coeffMonoms,
+                                Monoms);
+          else
+            G_random_element=
+            nonMonicSparseInterpol(ppA(random_element,x), ppB(random_element,x),
+                                   skeleton, alpha, sparseFail, coeffMonoms,
+                                   Monoms);
+          TIMING_END_AND_PRINT (gcd_recursion,
+                                "time for recursive call: ");
+          DEBOUTLN (cerr, "G_random_element= " << G_random_element);
+        }
+        else if (fail && !inextension)
+        {
+          source= CFList();
+          dest= CFList();
+          CFList list;
+          CanonicalForm mipo;
+          int deg= 2;
+          bool initialized= false;
+          do
+          {
+            mipo= randomIrredpoly (deg, x);
+            if (initialized)
+              setMipo (alpha, mipo);
+            else
+              alpha= rootOf (mipo);
+            inextension= true;
+            fail= false;
+            initialized= true;
+            random_element= randomElement (m, alpha, l, fail);
+            deg++;
+          } while (fail);
+          cleanUp= alpha;
+          V_buf= alpha;
+          list= CFList();
+          TIMING_START (gcd_recursion);
+          if (LC (skeleton).inCoeffDomain())
+            G_random_element=
+            monicSparseInterpol (ppA (random_element,x), ppB (random_element,x),
+                                skeleton, alpha, sparseFail, coeffMonoms,
+                                Monoms);
+          else
+            G_random_element=
+            nonMonicSparseInterpol(ppA(random_element,x), ppB(random_element,x),
+                                   skeleton, alpha, sparseFail, coeffMonoms,
+                                   Monoms);
+          TIMING_END_AND_PRINT (gcd_recursion,
+                                "time for recursive call: ");
+          DEBOUTLN (cerr, "G_random_element= " << G_random_element);
+        }
+        else if (fail && inextension)
+        {
+          source= CFList();
+          dest= CFList();
+
+          Variable V_buf3= V_buf;
+          V_buf= chooseExtension (V_buf);
+          bool prim_fail= false;
+          Variable V_buf2;
+          CanonicalForm prim_elem, im_prim_elem;
+          prim_elem= primitiveElement (alpha, V_buf2, prim_fail);
+
+          if (V_buf3 != alpha)
+          {
+            m= mapDown (m, prim_elem, im_prim_elem, alpha, source, dest);
+            G_m= mapDown (m, prim_elem, im_prim_elem, alpha, source, dest);
+            newtonPoly= mapDown (newtonPoly, prim_elem, im_prim_elem, alpha,
+                                 source, dest);
+            ppA= mapDown (ppA, prim_elem, im_prim_elem, alpha, source, dest);
+            ppB= mapDown (ppB, prim_elem, im_prim_elem, alpha, source, dest);
+            gcdlcAlcB= mapDown (gcdlcAlcB, prim_elem, im_prim_elem, alpha,
+                                source, dest);
+            for (CFListIterator i= l; i.hasItem(); i++)
+              i.getItem()= mapDown (i.getItem(), prim_elem, im_prim_elem, alpha,
+                                    source, dest);
+          }
+
+          ASSERT (!prim_fail, "failure in integer factorizer");
+          if (prim_fail)
+            ; //ERROR
+          else
+            im_prim_elem= mapPrimElem (prim_elem, alpha, V_buf);
+
+          DEBOUTLN (cerr, "getMipo (alpha)= " << getMipo (alpha));
+          DEBOUTLN (cerr, "getMipo (alpha)= " << getMipo (V_buf2));
+
+          for (CFListIterator i= l; i.hasItem(); i++)
+            i.getItem()= mapUp (i.getItem(), alpha, V_buf, prim_elem,
+                                im_prim_elem, source, dest);
+          m= mapUp (m, alpha, V_buf, prim_elem, im_prim_elem, source, dest);
+          G_m= mapUp (G_m, alpha, V_buf, prim_elem, im_prim_elem, source, dest);
+          newtonPoly= mapUp (newtonPoly, alpha, V_buf, prim_elem, im_prim_elem,
+                              source, dest);
+          ppA= mapUp (ppA, alpha, V_buf, prim_elem, im_prim_elem, source, dest);
+          ppB= mapUp (ppB, alpha, V_buf, prim_elem, im_prim_elem, source, dest);
+          gcdlcAlcB= mapUp (gcdlcAlcB, alpha, V_buf, prim_elem, im_prim_elem,
+                            source, dest);
+          fail= false;
+          random_element= randomElement (m, V_buf, l, fail );
+          DEBOUTLN (cerr, "fail= " << fail);
+          CFList list;
+          TIMING_START (gcd_recursion);
+          if (LC (skeleton).inCoeffDomain())
+            G_random_element=
+            monicSparseInterpol (ppA (random_element, x), ppB (random_element, x),
+                                skeleton, V_buf, sparseFail, coeffMonoms,
+                                Monoms);
+          else
+            G_random_element=
+            nonMonicSparseInterpol (ppA(random_element,x), ppB(random_element,x),
+                                    skeleton, V_buf, sparseFail,
+                                    coeffMonoms, Monoms);
+          TIMING_END_AND_PRINT (gcd_recursion,
+                                "time for recursive call: ");
+          DEBOUTLN (cerr, "G_random_element= " << G_random_element);
+          alpha= V_buf;
+        }
+
+        if (sparseFail)
+          break;
+
+        if (!G_random_element.inCoeffDomain())
+          d0= totaldegree (G_random_element, Variable(2),
+                           Variable (G_random_element.level()));
+        else
+          d0= 0;
+
+        if (d0 == 0)
+        {
+          if (inextension)
+            prune (cleanUp);
+          return N(gcdcAcB);
+        }
+        if (d0 >  d)
+        {
+          if (!find (l, random_element))
+            l.append (random_element);
+          continue;
+        }
+
+        G_random_element=
+        (gcdlcAlcB(random_element, x)/uni_lcoeff (G_random_element))
+        * G_random_element;
+
+        if (!G_random_element.inCoeffDomain())
+          d0= totaldegree (G_random_element, Variable(2),
+                           Variable (G_random_element.level()));
+        else
+          d0= 0;
+
+        if (d0 <  d)
+        {
+          m= gcdlcAlcB;
+          newtonPoly= 1;
+          G_m= 0;
+          d= d0;
+        }
+
+        TIMING_START (newton_interpolation);
+        H= newtonInterp (random_element, G_random_element, newtonPoly, G_m, x);
+        TIMING_END_AND_PRINT (newton_interpolation,
+                              "time for newton interpolation: ");
+
+        //termination test
+        if (uni_lcoeff (H) == gcdlcAlcB)
+        {
+          cH= uni_content (H);
+          ppH= H/cH;
+          ppH /= Lc (ppH);
+          DEBOUTLN (cerr, "ppH= " << ppH);
+          if (fdivides (ppH, ppA) && fdivides (ppH, ppB))
+          {
+            if (inextension)
+              prune (cleanUp);
+            return N(gcdcAcB*ppH);
+          }
+        }
+
+        G_m= H;
+        newtonPoly= newtonPoly*(x - random_element);
+        m= m*(x - random_element);
+        if (!find (l, random_element))
+          l.append (random_element);
+
+      } while (1); //end of second do
+    }
+    else
+    {
+      if (inextension)
+        prune (cleanUp);
+      return N(gcdcAcB*modGCDFp (ppA, ppB));
+    }
+  } while (1); //end of first do
+}
+
+TIMING_DEFINE_PRINT(modZ_termination)
+TIMING_DEFINE_PRINT(modZ_recursion)
+
+/// modular gcd algorithm, see Keith, Czapor, Geddes "Algorithms for Computer
+/// Algebra", Algorithm 7.1
+CanonicalForm modGCDZ ( const CanonicalForm & FF, const CanonicalForm & GG )
+{
+  CanonicalForm f, g, cl, q(0), Dp, newD, D, newq, newqh;
+  int p, i, dp_deg, d_deg=-1;
+
+  CanonicalForm cd ( bCommonDen( FF ));
+  f=cd*FF;
+  Variable x= Variable (1);
+  CanonicalForm cf, cg;
+  cf= icontent (f);
+  f /= cf;
+  //cd = bCommonDen( f ); f *=cd;
+  //f /=vcontent(f,Variable(1));
+
+  cd = bCommonDen( GG );
+  g=cd*GG;
+  cg= icontent (g);
+  g /= cg;
+  //cd = bCommonDen( g ); g *=cd;
+  //g /=vcontent(g,Variable(1));
+
+  CanonicalForm Dn, test= 0;
+  CanonicalForm lcf, lcg;
+  lcf= f.lc();
+  lcg= g.lc();
+  cl =  gcd (f.lc(),g.lc());
+  CanonicalForm gcdcfcg= gcd (cf, cg);
+  CanonicalForm fp, gp;
+  CanonicalForm b= 1;
+  int minCommonDeg= 0;
+  for (i= tmax (f.level(), g.level()); i > 0; i--)
+  {
+    if (degree (f, i) <= 0 || degree (g, i) <= 0)
+      continue;
+    else
+    {
+      minCommonDeg= tmin (degree (g, i), degree (f, i));
+      break;
+    }
+  }
+  if (i == 0)
+    return gcdcfcg;
+  for (; i > 0; i--)
+  {
+    if (degree (f, i) <= 0 || degree (g, i) <= 0)
+      continue;
+    else
+      minCommonDeg= tmin (minCommonDeg, tmin (degree (g, i), degree (f, i)));
+  }
+  b= 2*tmin (maxNorm (f), maxNorm (g))*abs (cl)*
+     power (CanonicalForm (2), minCommonDeg);
+  bool equal= false;
+  i = cf_getNumBigPrimes() - 1;
+
+  CanonicalForm cof, cog, cofp, cogp, newCof, newCog, cofn, cogn, cDn;
+  int maxNumVars= tmax (getNumVars (f), getNumVars (g));
+  //Off (SW_RATIONAL);
+  while ( true )
+  {
+    p = cf_getBigPrime( i );
+    i--;
+    while ( i >= 0 && mod( cl*(lc(f)/cl)*(lc(g)/cl), p ) == 0 )
+    {
+      p = cf_getBigPrime( i );
+      i--;
+    }
+    //printf("try p=%d\n",p);
+    setCharacteristic( p );
+    fp= mapinto (f);
+    gp= mapinto (g);
+    TIMING_START (modZ_recursion)
+#ifdef HAVE_NTL
+    if (size (fp)/maxNumVars > 500 && size (gp)/maxNumVars > 500)
+      Dp = modGCDFp (fp, gp, cofp, cogp);
+    else
+    {
+      Dp= gcd_poly (fp, gp);
+      cofp= fp/Dp;
+      cogp= gp/Dp;
+    }
+#else
+    Dp= gcd_poly (fp, gp);
+    cofp= fp/Dp;
+    cogp= gp/Dp;
+#endif
+    TIMING_END_AND_PRINT (modZ_recursion,
+                          "time for gcd mod p in modular gcd: ");
+    Dp /=Dp.lc();
+    Dp *= mapinto (cl);
+    cofp /= lc (cofp);
+    cofp *= mapinto (lcf);
+    cogp /= lc (cogp);
+    cogp *= mapinto (lcg);
+    setCharacteristic( 0 );
+    dp_deg=totaldegree(Dp);
+    if ( dp_deg == 0 )
+    {
+      //printf(" -> 1\n");
+      return CanonicalForm(gcdcfcg);
+    }
+    if ( q.isZero() )
+    {
+      D = mapinto( Dp );
+      cof= mapinto (cofp);
+      cog= mapinto (cogp);
+      d_deg=dp_deg;
+      q = p;
+      Dn= balance_p (D, p);
+      cofn= balance_p (cof, p);
+      cogn= balance_p (cog, p);
+    }
+    else
+    {
+      if ( dp_deg == d_deg )
+      {
+        chineseRemainder( D, q, mapinto( Dp ), p, newD, newq );
+        chineseRemainder( cof, q, mapinto (cofp), p, newCof, newq);
+        chineseRemainder( cog, q, mapinto (cogp), p, newCog, newq);
+        cof= newCof;
+        cog= newCog;
+        newqh= newq/2;
+        Dn= balance_p (newD, newq, newqh);
+        cofn= balance_p (newCof, newq, newqh);
+        cogn= balance_p (newCog, newq, newqh);
+        if (test != Dn) //balance_p (newD, newq))
+          test= balance_p (newD, newq);
+        else
+          equal= true;
+        q = newq;
+        D = newD;
+      }
+      else if ( dp_deg < d_deg )
+      {
+        //printf(" were all bad, try more\n");
+        // all previous p's are bad primes
+        q = p;
+        D = mapinto( Dp );
+        cof= mapinto (cof);
+        cog= mapinto (cog);
+        d_deg=dp_deg;
+        test= 0;
+        equal= false;
+        Dn= balance_p (D, p);
+        cofn= balance_p (cof, p);
+        cogn= balance_p (cog, p);
+      }
+      else
+      {
+        //printf(" was bad, try more\n");
+      }
+      //else dp_deg > d_deg: bad prime
+    }
+    if ( i >= 0 )
+    {
+      cDn= icontent (Dn);
+      Dn /= cDn;
+      cofn /= cl/cDn;
+      //cofn /= icontent (cofn);
+      cogn /= cl/cDn;
+      //cogn /= icontent (cogn);
+      TIMING_START (modZ_termination);
+      if ((terminationTest (f,g, cofn, cogn, Dn)) ||
+          ((equal || q > b) && fdivides (Dn, f) && fdivides (Dn, g)))
+      {
+        TIMING_END_AND_PRINT (modZ_termination,
+                            "time for successful termination in modular gcd: ");
+        //printf(" -> success\n");
+        return Dn*gcdcfcg;
+      }
+      TIMING_END_AND_PRINT (modZ_termination,
+                          "time for unsuccessful termination in modular gcd: ");
+      equal= false;
+      //else: try more primes
+    }
+    else
+    { // try other method
+      //printf("try other gcd\n");
+      Off(SW_USE_CHINREM_GCD);
+      D=gcd_poly( f, g );
+      On(SW_USE_CHINREM_GCD);
+      return D*gcdcfcg;
+    }
+  }
+}
+
+
+#endif
diff --git a/factory/cfModGcd.h b/factory/cfModGcd.h
new file mode 100644
index 0000000..9e0f23a
--- /dev/null
+++ b/factory/cfModGcd.h
@@ -0,0 +1,133 @@
+#ifndef CF_MOD_GCD_H
+#define CF_MOD_GCD_H
+// -*- c++ -*-
+//*****************************************************************************
+/** @file cfModGcd.h
+ *
+ * modular and sparse modular GCD algorithms over finite fields and Z.
+ *
+ * @author Martin Lee
+ * @date   22.10.2009
+ *
+ * @par Copyright:
+ *   (c) by The SINGULAR Team, see LICENSE file
+ *
+**/
+//*****************************************************************************
+
+// #include "config.h"
+#include "cf_assert.h"
+
+#include "cf_factory.h"
+
+CanonicalForm modGCDFq (const CanonicalForm& F, const CanonicalForm& G,
+                        Variable & alpha, CFList& l, bool& top_level);
+
+/// GCD of A and B over \f$ F_{p}(\alpha ) \f$
+static inline
+CanonicalForm modGCDFq (const CanonicalForm& A, ///<[in] poly over F_q
+                        const CanonicalForm& B, ///<[in] poly over F_q
+                        Variable & alpha        ///<[in] algebraic variable
+                       )
+{
+  CFList list;
+  bool top_level= true;
+  return modGCDFq (A, B, alpha, list, top_level);
+}
+
+
+CanonicalForm
+modGCDFp (const CanonicalForm& F, const CanonicalForm& G, bool& top_level,
+          CFList& l);
+
+CanonicalForm
+modGCDFp (const CanonicalForm& F, const CanonicalForm& G,
+          CanonicalForm& coF, CanonicalForm& coG,
+          bool& topLevel, CFList& l);
+
+///GCD of A and B over \f$ F_{p} \f$
+static inline
+CanonicalForm modGCDFp (const CanonicalForm& A, ///<[in] poly over F_p
+                        const CanonicalForm& B  ///<[in] poly over F_p
+                       )
+{
+  CFList list;
+  bool top_level= true;
+  return modGCDFp (A, B, top_level, list);
+}
+
+static inline
+CanonicalForm modGCDFp (const CanonicalForm& A, const CanonicalForm& B,
+                        CanonicalForm& coA, CanonicalForm& coB)
+{
+  CFList list;
+  bool top_level= true;
+  return modGCDFp (A, B, coA, coB, top_level, list);
+}
+
+CanonicalForm
+modGCDGF (const CanonicalForm& F, const CanonicalForm& G, CFList& l,
+          bool& top_level);
+
+/// GCD of A and B over GF
+static inline
+CanonicalForm modGCDGF (const CanonicalForm& A, ///<[in] poly over GF
+                        const CanonicalForm& B  ///<[in] poly over GF
+                       )
+{
+  ASSERT (CFFactory::gettype() == GaloisFieldDomain,
+          "GF as base field expected");
+  CFList list;
+  bool top_level= true;
+  return modGCDGF (A, B, list, top_level);
+}
+
+CanonicalForm sparseGCDFp (const CanonicalForm& F, const CanonicalForm& G,
+                           bool& topLevel, CFList& l);
+
+/// Zippel's sparse GCD over Fp
+static inline
+CanonicalForm sparseGCDFp (const CanonicalForm& A, ///<[in] poly over F_p
+                           const CanonicalForm& B  ///<[in] poly over F_p
+                          )
+{
+  ASSERT (CFFactory::gettype() == FiniteFieldDomain,
+          "Fp as base field expected");
+  CFList list;
+  bool topLevel= true;
+  return sparseGCDFp (A, B, topLevel, list);
+}
+
+
+CanonicalForm
+sparseGCDFq (const CanonicalForm& F, const CanonicalForm& G,
+             const Variable& alpha, CFList& l, bool& topLevel);
+
+/// Zippel's sparse GCD over Fq
+static inline
+CanonicalForm sparseGCDFq (const CanonicalForm& A, ///<[in] poly over F_q
+                           const CanonicalForm& B, ///<[in] poly over F_q
+                           const Variable& alpha   ///<[in] algebraic variable
+                          )
+{
+  CFList list;
+  bool topLevel= true;
+  return sparseGCDFq (A, B, alpha, list, topLevel);
+}
+
+/// extract monomials of F, parts in algebraic variable are considered
+/// coefficients
+CFArray
+getMonoms (const CanonicalForm& F ///<[in] some poly
+          );
+
+bool
+terminationTest (const CanonicalForm& F, const CanonicalForm& G,
+                 const CanonicalForm& coF, const CanonicalForm& coG,
+                 const CanonicalForm& cand);
+
+/// modular GCD over Z
+CanonicalForm modGCDZ (const CanonicalForm & FF, ///<[in] poly over Z
+                       const CanonicalForm & GG  ///<[in] poly over Z
+                      );
+#endif
diff --git a/factory/cfModResultant.cc b/factory/cfModResultant.cc
new file mode 100644
index 0000000..8a03864
--- /dev/null
+++ b/factory/cfModResultant.cc
@@ -0,0 +1,685 @@
+/*****************************************************************************\
+ * Computer Algebra System SINGULAR
+\*****************************************************************************/
+/** @file cfModResultant.cc
+ *
+ * modular resultant algorithm
+ *
+ * @author Martin Lee
+ *
+ **/
+/*****************************************************************************/
+
+
+#include "config.h"
+
+
+#include "cf_assert.h"
+#include "timing.h"
+
+#include "cfModResultant.h"
+#include "cf_primes.h"
+#include "templates/ftmpl_functions.h"
+#include "cf_map.h"
+#include "cf_algorithm.h"
+#include "cf_iter.h"
+#include "cf_irred.h"
+#include "cf_generator.h"
+#include "cf_random.h"
+#include "cf_map_ext.h"
+#include "facFqBivarUtil.h"
+
+#ifdef HAVE_NTL
+#include "NTLconvert.h"
+#endif
+
+#ifdef HAVE_FLINT
+#include "FLINTconvert.h"
+#endif
+
+#ifdef HAVE_NTL
+TIMING_DEFINE_PRINT(fac_resultant_p)
+
+//TODO arrange by bound= deg (F,xlevel)*deg (G,i)+deg (G,xlevel)*deg (F, i)
+static inline
+void myCompress (const CanonicalForm& F, const CanonicalForm& G, CFMap & M,
+                  CFMap & N, const Variable& x)
+{
+  int n= tmax (F.level(), G.level());
+  int * degsf= new int [n + 1];
+  int * degsg= new int [n + 1];
+
+  for (int i = 0; i <= n; i++)
+    degsf[i]= degsg[i]= 0;
+
+  degsf= degrees (F, degsf);
+  degsg= degrees (G, degsg);
+
+  int both_non_zero= 0;
+  int f_zero= 0;
+  int g_zero= 0;
+  int both_zero= 0;
+  int degsfx, degsgx;
+
+  if (x.level() != 1)
+  {
+    int xlevel= x.level();
+
+    for (int i= 1; i <= n; i++)
+    {
+      if (degsf[i] != 0 && degsg[i] != 0)
+      {
+        both_non_zero++;
+        continue;
+      }
+      if (degsf[i] == 0 && degsg[i] != 0 && i <= G.level())
+      {
+        f_zero++;
+        continue;
+      }
+      if (degsg[i] == 0 && degsf[i] && i <= F.level())
+      {
+        g_zero++;
+        continue;
+      }
+    }
+
+    M.newpair (Variable (xlevel), Variable (1));
+    N.newpair (Variable (1), Variable (xlevel));
+    degsfx= degsf [xlevel];
+    degsgx= degsg [xlevel];
+    degsf [xlevel]= 0;
+    degsg [xlevel]= 0;
+    if ((getNumVars (F) == 2 && getNumVars (G) == 1) ||
+        (getNumVars (G) == 2 && getNumVars (F) == 1) ||
+        (getNumVars (F) == 2 && getNumVars (F) == getNumVars (G)
+         && getVars (F) == getVars (G)))
+    {
+      int pos= 2;
+      for (int i= 1; i <= n; i++)
+      {
+        if (i != xlevel)
+        {
+          if (i != pos && (degsf[i] != 0 || degsg [i] != 0))
+          {
+            M.newpair (Variable (i), Variable (pos));
+            N.newpair (Variable (pos), Variable (i));
+            pos++;
+          }
+        }
+      }
+      delete [] degsf;
+      delete [] degsg;
+      return;
+    }
+
+    if (both_non_zero == 0)
+    {
+      delete [] degsf;
+      delete [] degsg;
+      return;
+    }
+
+    // map Variables which do not occur in both polynomials to higher levels
+    int k= 1;
+    int l= 1;
+    for (int i= 1; i <= n; i++)
+    {
+      if (i == xlevel)
+        continue;
+      if (degsf[i] != 0 && degsg[i] == 0 && i <= F.level())
+      {
+        if (k + both_non_zero != i)
+        {
+          M.newpair (Variable (i), Variable (k + both_non_zero));
+          N.newpair (Variable (k + both_non_zero), Variable (i));
+        }
+        k++;
+      }
+      if (degsf[i] == 0 && degsg[i] != 0 && i <= G.level())
+      {
+        if (l + g_zero + both_non_zero != i)
+        {
+          M.newpair (Variable (i), Variable (l + g_zero + both_non_zero));
+          N.newpair (Variable (l + g_zero + both_non_zero), Variable (i));
+        }
+        l++;
+      }
+    }
+
+    int m= n;
+    int min_max_deg;
+    k= both_non_zero;
+    l= 0;
+    int i= 1;
+    while (k > 0)
+    {
+      if (degsf [i] != 0 && degsg [i] != 0)
+        min_max_deg= degsgx*degsf[i] + degsfx*degsg[i];
+      else
+        min_max_deg= 0;
+      while (min_max_deg == 0 && i < m + 1)
+      {
+        i++;
+        if (degsf [i] != 0 && degsg [i] != 0)
+          min_max_deg= degsgx*degsf[i] + degsfx*degsg[i];
+        else
+          min_max_deg= 0;
+      }
+      for (int j= i + 1; j <= m; j++)
+      {
+        if (degsgx*degsf[j] + degsfx*degsg[j] <= min_max_deg &&
+            degsf[j] != 0 && degsg [j] != 0)
+        {
+          min_max_deg= degsgx*degsf[j] + degsfx*degsg[j];
+          l= j;
+        }
+      }
+      if (l != 0)
+      {
+        if (l != k && l != xlevel && k != 1)
+        {
+          M.newpair (Variable (l), Variable(k));
+          N.newpair (Variable (k), Variable(l));
+          degsf[l]= 0;
+          degsg[l]= 0;
+          l= 0;
+        }
+        else if (l < m + 1)
+        {
+          degsf[l]= 0;
+          degsg[l]= 0;
+          l= 0;
+        }
+      }
+      else if (l == 0)
+      {
+        if (i != k && i != xlevel && k != 1)
+        {
+          M.newpair (Variable (i), Variable (k));
+          N.newpair (Variable (k), Variable (i));
+          degsf[i]= 0;
+          degsg[i]= 0;
+        }
+        else if (i < m + 1)
+        {
+          degsf[i]= 0;
+          degsg[i]= 0;
+        }
+        i++;
+      }
+      k--;
+    }
+  }
+  else
+  {
+    //arrange Variables such that no gaps occur
+    for (int i= 1; i <= n; i++)
+    {
+      if (degsf[i] == 0 && degsg[i] == 0)
+      {
+        both_zero++;
+        continue;
+      }
+      else
+      {
+        if (both_zero != 0 && i != 1)
+        {
+          M.newpair (Variable (i), Variable (i - both_zero));
+          N.newpair (Variable (i - both_zero), Variable (i));
+        }
+      }
+    }
+  }
+
+  delete [] degsf;
+  delete [] degsg;
+}
+
+static inline
+CanonicalForm oneNorm (const CanonicalForm& F)
+{
+  if (F.inZ())
+    return abs (F);
+
+  CanonicalForm result= 0;
+  for (CFIterator i= F; i.hasTerms(); i++)
+    result += oneNorm (i.coeff());
+  return result;
+}
+
+// if F and G are both non constant, make sure their level is equal
+static inline
+CanonicalForm uniResultant (const CanonicalForm& F, const CanonicalForm& G)
+{
+#ifdef HAVE_NTL
+  ASSERT (getCharacteristic() > 0, "characteristic > 0 expected");
+  if (F.inCoeffDomain() && G.inCoeffDomain())
+    return 1;
+  if (F.isZero() || G.isZero())
+    return 0;
+  Variable alpha;
+
+#ifdef HAVE_FLINT
+  if (!hasFirstAlgVar (F, alpha) && !hasFirstAlgVar (G,alpha))
+  {
+    nmod_poly_t FLINTF, FLINTG;
+    convertFacCF2nmod_poly_t (FLINTF, F);
+    convertFacCF2nmod_poly_t (FLINTG, G);
+    mp_limb_t FLINTresult= nmod_poly_resultant (FLINTF, FLINTG);
+    nmod_poly_clear (FLINTF);
+    nmod_poly_clear (FLINTG);
+    return CanonicalForm ((long) FLINTresult);
+  }
+#else
+  if (!hasFirstAlgVar (F, alpha) && !hasFirstAlgVar (G,alpha))
+  {
+    if (fac_NTL_char != getCharacteristic())
+    {
+      fac_NTL_char= getCharacteristic();
+      zz_p::init (getCharacteristic());
+    }
+    zz_pX NTLF= convertFacCF2NTLzzpX (F);
+    zz_pX NTLG= convertFacCF2NTLzzpX (G);
+
+    zz_p NTLResult= resultant (NTLF, NTLG);
+
+    return CanonicalForm (to_long (rep (NTLResult)));
+  }
+#endif
+  //at this point F or G has an algebraic var.
+  if (fac_NTL_char != getCharacteristic())
+  {
+    fac_NTL_char= getCharacteristic();
+    zz_p::init (getCharacteristic());
+  }
+  zz_pX NTLMipo= convertFacCF2NTLzzpX (getMipo (alpha));
+  zz_pE::init (NTLMipo);
+  zz_pEX NTLF= convertFacCF2NTLzz_pEX (F, NTLMipo);
+  zz_pEX NTLG= convertFacCF2NTLzz_pEX (G, NTLMipo);
+  zz_pE NTLResult= resultant (NTLF, NTLG);
+
+  return convertNTLzzpE2CF (NTLResult, alpha);
+#else
+  return resultant (F, G, F.mvar());
+#endif
+}
+
+static inline
+void evalPoint (const CanonicalForm& F, const CanonicalForm& G,
+                CanonicalForm& FEval, CanonicalForm& GEval,
+                CFGenerator& evalPoint)
+{
+  int degF, degG;
+  Variable x= Variable (1);
+  degF= degree (F, x);
+  degG= degree (G, x);
+  do
+  {
+    if (!evalPoint.hasItems())
+      break;
+    FEval= F (evalPoint.item(), 2);
+    GEval= G (evalPoint.item(), 2);
+    if (degree (FEval, 1) < degF || degree (GEval, 1) < degG)
+    {
+      evalPoint.next();
+      continue;
+    }
+    else
+      return;
+  }
+  while (evalPoint.hasItems());
+}
+
+static inline CanonicalForm
+newtonInterp (const CanonicalForm & alpha, const CanonicalForm & u,
+              const CanonicalForm & newtonPoly, const CanonicalForm & oldInterPoly,
+              const Variable & x)
+{
+  CanonicalForm interPoly;
+
+  interPoly= oldInterPoly+((u - oldInterPoly (alpha, x))/newtonPoly (alpha, x))
+                            *newtonPoly;
+  return interPoly;
+}
+
+CanonicalForm
+resultantFp (const CanonicalForm& A, const CanonicalForm& B, const Variable& x,
+             bool prob)
+{
+  ASSERT (getCharacteristic() > 0, "characteristic > 0 expected");
+
+  if (A.isZero() || B.isZero())
+    return 0;
+
+  int degAx= degree (A, x);
+  int degBx= degree (B, x);
+  if (A.level() < x.level())
+    return power (A, degBx);
+  if (B.level() < x.level())
+    return power (B, degAx);
+
+  if (degAx == 0)
+    return power (A, degBx);
+  else if (degBx == 0)
+    return power (B, degAx);
+
+  if (A.isUnivariate() && B.isUnivariate() && A.level() == B.level())
+    return uniResultant (A, B);
+
+  CanonicalForm F= A;
+  CanonicalForm G= B;
+
+  CFMap M, N;
+  myCompress (F, G, M, N, x);
+
+  F= M (F);
+  G= M (G);
+
+  Variable y= Variable (2);
+
+  CanonicalForm GEval, FEval, recResult, H;
+  CanonicalForm newtonPoly= 1;
+  CanonicalForm modResult= 0;
+
+  Variable z= Variable (1);
+  int bound= degAx*degree (G, 2) + degree (F, 2)*degBx;
+
+  int p= getCharacteristic();
+  CanonicalForm minpoly;
+  Variable alpha= Variable (tmax (F.level(), G.level()) + 1);
+  bool algExt= hasFirstAlgVar (F, alpha) || hasFirstAlgVar (G, alpha);
+  CFGenerator * gen;
+  bool extOfExt= false;
+  Variable v= alpha;
+  CanonicalForm primElemAlpha, imPrimElemAlpha;
+  CFList source,dest;
+  if (!algExt && (p < (1 << 28)))
+  {
+    // pass to an extension of size at least 2^29
+    // for very very large input that is maybe too small though
+    int deg= ceil (29.0*((double) log (2)/log (p)))+1;
+    minpoly= randomIrredpoly (deg, z);
+    alpha= rootOf (minpoly);
+    AlgExtGenerator AlgExtGen (alpha);
+    gen= AlgExtGen.clone();
+    for (int i= 0; i < p; i++) // skip values from the prime field
+      (*gen).next();
+  }
+  else if (!algExt)
+  {
+    FFGenerator FFGen;
+    gen= FFGen.clone();
+  }
+  else
+  {
+    int deg= ceil (29.0*((double) log (2)/log (p)));
+    if (degree (getMipo (alpha)) < deg)
+    {
+      mpz_t field_size;
+      mpz_init (field_size);
+      mpz_ui_pow_ui (field_size, p,
+                 deg + degree (getMipo (alpha)) - deg%degree (getMipo (alpha)));
+
+      // field_size needs to fit in an int because of mapUp, mapDown, length of lists etc.
+      if (mpz_fits_sint_p (field_size))
+      {
+        minpoly= randomIrredpoly (deg + degree (getMipo (alpha))
+                                  - deg%degree (getMipo (alpha)), z);
+        v= rootOf (minpoly);
+        Variable V_buf2;
+        bool primFail= false;
+        extOfExt= true;
+        primElemAlpha= primitiveElement (alpha, V_buf2, primFail);
+        ASSERT (!primFail, "failure in integer factorizer");
+        if (primFail)
+          ; //ERROR
+        else
+          imPrimElemAlpha= mapPrimElem (primElemAlpha, alpha, v);
+        F= mapUp (F, alpha, v, primElemAlpha, imPrimElemAlpha, source, dest);
+        G= mapUp (G, alpha, v, primElemAlpha, imPrimElemAlpha, source, dest);
+      }
+      else
+      {
+        deg= deg - deg % degree (getMipo (alpha));
+        mpz_ui_pow_ui (field_size, p, deg);
+        while (deg / degree (getMipo (alpha)) >= 2 && !mpz_fits_sint_p (field_size))
+        {
+          deg -= degree (getMipo (alpha));
+          mpz_ui_pow_ui (field_size, p, deg);
+        }
+        if (deg != degree (getMipo (alpha)))
+        {
+           minpoly= randomIrredpoly (deg, z);
+           v= rootOf (minpoly);
+           Variable V_buf2;
+           bool primFail= false;
+           extOfExt= true;
+           primElemAlpha= primitiveElement (alpha, V_buf2, primFail);
+           ASSERT (!primFail, "failure in integer factorizer");
+           if (primFail)
+             ; //ERROR
+           else
+             imPrimElemAlpha= mapPrimElem (primElemAlpha, alpha, v);
+           F= mapUp (F, alpha, v, primElemAlpha, imPrimElemAlpha, source, dest);
+           G= mapUp (G, alpha, v, primElemAlpha, imPrimElemAlpha, source, dest);
+        }
+      }
+      mpz_clear (field_size);
+    }
+    AlgExtGenerator AlgExtGen (v);
+    gen= AlgExtGen.clone();
+    for (int i= 0; i < p; i++)
+      (*gen).next();
+  }
+  int count= 0;
+  int equalCount= 0;
+  CanonicalForm point;
+  do
+  {
+    evalPoint (F, G, FEval, GEval, *gen);
+
+    recResult= resultantFp (FEval, GEval, z, prob);
+
+    H= newtonInterp ((*gen).item(), recResult, newtonPoly, modResult, y);
+
+    if (H == modResult)
+      equalCount++;
+    else
+      equalCount= 0;
+
+    count++;
+    if (count > bound || (prob && equalCount == 2 && !H.inCoeffDomain()))
+    {
+      if (!algExt && degree (H, alpha) <= 0)
+        break;
+      else if (algExt)
+      {
+        if (extOfExt && !isInExtension (H, imPrimElemAlpha, 1, primElemAlpha,
+                                        dest, source))
+        {
+          H= mapDown (H, primElemAlpha, imPrimElemAlpha, alpha, dest, source);
+          prune (v);
+          break;
+        }
+        else if (!extOfExt)
+          break;
+      }
+    }
+
+    modResult= H;
+    newtonPoly *= (y - (*gen).item());
+    if ((*gen).hasItems())
+        (*gen).next();
+    else
+      STICKYASSERT (0, "out of evaluation points");
+  } while (1);
+
+  delete gen;
+
+  return N (H);
+}
+
+static inline
+CanonicalForm
+balanceUni ( const CanonicalForm & f, const CanonicalForm & q )
+{
+    Variable x = f.mvar();
+    CanonicalForm result = 0, qh = q / 2;
+    CanonicalForm c;
+    CFIterator i;
+    for ( i = f; i.hasTerms(); i++ ) {
+        c = mod( i.coeff(), q );
+        if ( c > qh )
+            result += power( x, i.exp() ) * (c - q);
+        else
+            result += power( x, i.exp() ) * c;
+    }
+    return result;
+}
+
+static inline
+CanonicalForm
+symmetricRemainder (const CanonicalForm& f, const CanonicalForm& q)
+{
+  CanonicalForm result= 0;
+  if (f.isUnivariate() || f.inCoeffDomain())
+    return balanceUni (f, q);
+  else
+  {
+    Variable x= f.mvar();
+    for (CFIterator i= f; i.hasTerms(); i++)
+      result += power (x, i.exp())*symmetricRemainder (i.coeff(), q);
+  }
+  return result;
+}
+
+CanonicalForm
+resultantZ (const CanonicalForm& A, const CanonicalForm& B, const Variable& x,
+            bool prob)
+{
+  ASSERT (getCharacteristic() == 0, "characteristic > 0 expected");
+#ifndef NOASSERT
+  bool isRat= isOn (SW_RATIONAL);
+  On (SW_RATIONAL);
+  ASSERT (bCommonDen (A).isOne(), "input A is rational");
+  ASSERT (bCommonDen (B).isOne(), "input B is rational");
+  if (!isRat)
+    Off (SW_RATIONAL);
+#endif
+
+  int degAx= degree (A, x);
+  int degBx= degree (B, x);
+  if (A.level() < x.level())
+    return power (A, degBx);
+  if (B.level() < x.level())
+    return power (B, degAx);
+
+  if (degAx == 0)
+    return power (A, degBx);
+  else if (degBx == 0)
+    return power (B, degAx);
+
+  CanonicalForm F= A;
+  CanonicalForm G= B;
+
+  Variable X= x;
+  if (F.level() != x.level() || G.level() != x.level())
+  {
+    if (F.level() > G.level())
+      X= F.mvar();
+    else
+      X= G.mvar();
+    F= swapvar (F, X, x);
+    G= swapvar (G, X, x);
+  }
+
+  // now X is the main variable
+
+  CanonicalForm d= 0;
+  CanonicalForm dd= 0;
+  CanonicalForm buf;
+  for (CFIterator i= F; i.hasTerms(); i++)
+  {
+    buf= oneNorm (i.coeff());
+    d= (buf > d) ? buf : d;
+  }
+  CanonicalForm e= 0, ee= 0;
+  for (CFIterator i= G; i.hasTerms(); i++)
+  {
+    buf= oneNorm (i.coeff());
+    e= (buf > e) ? buf : e;
+  }
+  d= power (d, degBx);
+  e= power (e, degAx);
+  CanonicalForm bound= 1;
+  for (int i= degBx + degAx; i > 1; i--)
+    bound *= i;
+  bound *= d*e;
+  bound *= 2;
+
+  bool onRational= isOn (SW_RATIONAL);
+  if (onRational)
+    Off (SW_RATIONAL);
+  int i = cf_getNumBigPrimes() - 1;
+  int p;
+  CanonicalForm l= lc (F)*lc(G);
+  CanonicalForm resultModP, q (0), newResult, newQ;
+  CanonicalForm result;
+  int equalCount= 0;
+  CanonicalForm test, newTest;
+  int count= 0;
+  do
+  {
+    p = cf_getBigPrime( i );
+    i--;
+    while ( i >= 0 && mod( l, p ) == 0)
+    {
+      p = cf_getBigPrime( i );
+      i--;
+    }
+
+    if (i <= 0)
+      return resultant (A, B, x);
+
+    setCharacteristic (p);
+
+    TIMING_START (fac_resultant_p);
+    resultModP= resultantFp (mapinto (F), mapinto (G), X, prob);
+    TIMING_END_AND_PRINT (fac_resultant_p, "time to compute resultant mod p: ");
+
+    setCharacteristic (0);
+
+    count++;
+    if ( q.isZero() )
+    {
+      result= mapinto(resultModP);
+      q= p;
+    }
+    else
+    {
+      chineseRemainder( result, q, mapinto (resultModP), p, newResult, newQ );
+      q= newQ;
+      result= newResult;
+      test= symmetricRemainder (result,q);
+      if (test != newTest)
+      {
+        newTest= test;
+        equalCount= 0;
+      }
+      else
+        equalCount++;
+      if (newQ > bound || (prob && equalCount == 2))
+      {
+        result= test;
+        break;
+      }
+    }
+  } while (1);
+
+  if (onRational)
+    On (SW_RATIONAL);
+  return swapvar (result, X, x);
+}
+#endif
+
diff --git a/factory/cfModResultant.h b/factory/cfModResultant.h
new file mode 100644
index 0000000..dfcb704
--- /dev/null
+++ b/factory/cfModResultant.h
@@ -0,0 +1,42 @@
+/*****************************************************************************\
+ * Computer Algebra System SINGULAR
+\*****************************************************************************/
+/** @file cfModResultant.h
+ *
+ * modular resultant algorithm as described by G. E. Collins in "The Calculation
+ * of multivariate polynomial resultants"
+ *
+ * @author Martin Lee
+ *
+ **/
+/*****************************************************************************/
+
+#ifndef CF_MOD_RESULTANT_H
+#define CF_MOD_RESULTANT_H
+
+#include "canonicalform.h"
+
+/// modular resultant algorihtm over Fp
+///
+/// @return @a resultantFp returns the resultant of A and B wrt. x
+CanonicalForm
+resultantFp (const CanonicalForm& A,///<[in] some poly
+             const CanonicalForm& B,///<[in] some poly
+             const Variable& x,     ///<[in] some polynomial variable
+             bool prob= true        ///<[in] if true use probabilistic algorithm
+            );
+
+/*BEGINPUBLIC*/
+/// modular resultant algorihtm over Z
+///
+/// @return @a resultantZ returns the resultant of A and B wrt. x
+CanonicalForm
+resultantZ (const CanonicalForm& A, ///<[in] some poly
+            const CanonicalForm& B, ///<[in] some poly
+            const Variable& x,      ///<[in] some polynomial variable
+            bool prob= true         ///<[in] if true use probabilistic algorithm
+           );
+/*ENDPUBLIC*/
+
+#endif
+
diff --git a/factory/cfNTLzzpEXGCD.cc b/factory/cfNTLzzpEXGCD.cc
new file mode 100644
index 0000000..9dbf4fd
--- /dev/null
+++ b/factory/cfNTLzzpEXGCD.cc
@@ -0,0 +1,344 @@
+// -*- c++ -*-
+//*****************************************************************************
+/** @file cfNTLzzpEXGCD.cc
+ *
+ * @author Martin Lee
+ *
+ * Univariate GCD and extended GCD over Z/p[t]/(f)[x] for reducible f
+ *
+ * @note the following code is slightly modified code out of
+ * lzz_pEX.c from Victor Shoup's NTL. Below is NTL's copyright notice.
+ *
+ * @par Copyright:
+ *   (c) by The SINGULAR Team, see LICENSE file
+ *
+
+                  COPYRIGHT NOTICE
+		    for NTL 5.5
+	  (modified for Singular 2-0-6 - 3-1)
+
+NTL -- A Library for Doing Number Theory
+Copyright (C) 1996-2009  Victor Shoup
+
+The most recent version of NTL is available at http://www.shoup.net
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 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.
+
+This entire copyright notice should be placed in an appropriately
+conspicuous place accompanying all distributions of software that
+make use of NTL.
+
+The above terms apply to all of the software modules distributed with NTL,
+i.e., all source files in either the ntl-xxx.tar.gz or WinNTL-xxx.zip
+distributions.  In general, the individual files do not contain
+copyright notices.
+
+Note that the quad_float package is derived from the doubledouble package,
+originally developed by Keith Briggs, and also licensed unger the GNU GPL.
+The files quad_float.c and quad_float.h contain more detailed copyright
+notices.
+
+Note that the traditional long integer package used by NTL, lip.c, is derived
+from---and represents an extensive modification of---
+a package originally developed and copyrighted by Arjen Lenstra,
+who has agreed to renounce any copyright claims on the particular
+version of the long integer package appearing in NTL, so that the
+this package now is covered by the GNU GPL as well.
+
+Note that the alternative long integer package used by NTL is GMP,
+which is written by Torbjorn Granlund <tege at swox.com>.
+GMP is licensed under the terms of the GNU Lesser General Public License.
+
+Note that NTL makes use of the RSA Data Security, Inc. MD5 Message
+Digest Algorithm.
+
+Note that prior to version 4.0, NTL was distributed under the following terms:
+   NTL is freely available for research and educational purposes.
+   I don't want to attach any legalistic licensing restrictions on
+   users of NTL.
+   However, NTL should not be linked in a commercial program
+   (although using data in a commercial
+   product produced by a program that used NTL is fine).
+
+The hope is that the GNU GPL is actually less restrictive than these
+older terms;  however, in any circumstances such that GNU GPL is more
+restrictive, then the following rule is in force:
+versions prior to 4.0 may continue to be used under the old terms,
+but users of versions 4.0 or later should adhere to the terms of the GNU GPL.
+**/
+
+
+
+#include "config.h"
+
+
+#include "cfNTLzzpEXGCD.h"
+
+#ifdef HAVE_NTL
+#include "NTLconvert.h"
+#endif
+
+#ifdef HAVE_NTL
+
+long InvModStatus (zz_pE& x, const zz_pE& a)
+{
+   return InvModStatus(x._zz_pE__rep, a._zz_pE__rep, zz_pE::modulus());
+}
+
+static
+void SetSize(vec_zz_pX& x, long n, long m)
+{
+   x.SetLength(n);
+   long i;
+   for (i = 0; i < n; i++)
+      x[i].rep.SetMaxLength(m);
+}
+
+void tryPlainRem(zz_pEX& r, const zz_pEX& a, const zz_pEX& b, vec_zz_pX& x,
+                 bool& fail)
+{
+   long da, db, dq, i, j, LCIsOne;
+   const zz_pE *bp;
+   zz_pX *xp;
+
+
+   zz_pE LCInv, t;
+   zz_pX s;
+
+   da = deg(a);
+   db = deg(b);
+
+   if (db < 0) Error("zz_pEX: division by zero");
+
+   if (da < db) {
+      r = a;
+      return;
+   }
+
+   bp = b.rep.elts();
+
+   if (IsOne(bp[db]))
+      LCIsOne = 1;
+   else {
+      LCIsOne = 0;
+      fail= InvModStatus (LCInv, bp[db]);
+      //inv(LCInv, bp[db]);
+      if (fail)
+        return;
+   }
+
+   for (i = 0; i <= da; i++)
+      x[i] = rep(a.rep[i]);
+
+   xp = x.elts();
+
+   dq = da - db;
+
+   for (i = dq; i >= 0; i--) {
+      conv(t, xp[i+db]);
+      if (!LCIsOne)
+	 mul(t, t, LCInv);
+      NTL::negate(t, t);
+
+      for (j = db-1; j >= 0; j--) {
+	 mul(s, rep(t), rep(bp[j]));
+	 add(xp[i+j], xp[i+j], s);
+      }
+   }
+
+   r.rep.SetLength(db);
+   for (i = 0; i < db; i++)
+      conv(r.rep[i], xp[i]);
+   r.normalize();
+}
+
+void tryPlainDivRem(zz_pEX& q, zz_pEX& r, const zz_pEX& a, const zz_pEX& b,
+                    bool& fail)
+{
+   long da, db, dq, i, j, LCIsOne;
+   const zz_pE *bp;
+   zz_pE *qp;
+   zz_pX *xp;
+
+
+   zz_pE LCInv, t;
+   zz_pX s;
+
+   da = deg(a);
+   db = deg(b);
+
+   if (db < 0) Error("zz_pEX: division by zero");
+
+   if (da < db) {
+      r = a;
+      clear(q);
+      return;
+   }
+
+   zz_pEX lb;
+
+   if (&q == &b) {
+      lb = b;
+      bp = lb.rep.elts();
+   }
+   else
+      bp = b.rep.elts();
+
+   if (IsOne(bp[db]))
+      LCIsOne = 1;
+   else {
+      LCIsOne = 0;
+      fail= InvModStatus (LCInv, bp[db]);
+      //inv(LCInv, bp[db]);
+      if (fail)
+        return;
+   }
+
+   vec_zz_pX x;
+
+   SetSize(x, da+1, 2*zz_pE::degree());
+
+   for (i = 0; i <= da; i++)
+      x[i] = rep(a.rep[i]);
+
+   xp = x.elts();
+
+   dq = da - db;
+   q.rep.SetLength(dq+1);
+   qp = q.rep.elts();
+
+   for (i = dq; i >= 0; i--) {
+      conv(t, xp[i+db]);
+      if (!LCIsOne)
+	 mul(t, t, LCInv);
+      qp[i] = t;
+      NTL::negate(t, t);
+
+      for (j = db-1; j >= 0; j--) {
+	 mul(s, rep(t), rep(bp[j]));
+	 add(xp[i+j], xp[i+j], s);
+      }
+   }
+
+   r.rep.SetLength(db);
+   for (i = 0; i < db; i++)
+      conv(r.rep[i], xp[i]);
+   r.normalize();
+}
+
+
+void tryNTLGCD(zz_pEX& x, const zz_pEX& a, const zz_pEX& b, bool& fail)
+{
+   zz_pE t;
+
+   if (IsZero(b))
+      x = a;
+   else if (IsZero(a))
+      x = b;
+   else {
+      long n = max(deg(a),deg(b)) + 1;
+      zz_pEX u(INIT_SIZE, n), v(INIT_SIZE, n);
+
+      vec_zz_pX tmp;
+      SetSize(tmp, n, 2*zz_pE::degree());
+
+      u = a;
+      v = b;
+      do {
+         tryPlainRem(u, u, v, tmp, fail);
+         if (fail)
+           return;
+         swap(u, v);
+      } while (!IsZero(v));
+
+      x = u;
+   }
+
+   if (IsZero(x)) return;
+   if (IsOne(LeadCoeff(x))) return;
+
+   /* make gcd monic */
+
+
+   fail= InvModStatus (t, LeadCoeff(x));
+   if (fail)
+     return;
+   mul(x, x, t);
+}
+
+void tryNTLXGCD(zz_pEX& d, zz_pEX& s, zz_pEX& t, const zz_pEX& a,
+                const zz_pEX& b, bool& fail)
+{
+   zz_pE z;
+
+
+   if (IsZero(b)) {
+      set(s);
+      clear(t);
+      d = a;
+   }
+   else if (IsZero(a)) {
+      clear(s);
+      set(t);
+      d = b;
+   }
+   else {
+      long e = max(deg(a), deg(b)) + 1;
+
+      zz_pEX temp(INIT_SIZE, e), u(INIT_SIZE, e), v(INIT_SIZE, e),
+            u0(INIT_SIZE, e), v0(INIT_SIZE, e),
+            u1(INIT_SIZE, e), v1(INIT_SIZE, e),
+            u2(INIT_SIZE, e), v2(INIT_SIZE, e), q(INIT_SIZE, e);
+
+
+      set(u1); clear(v1);
+      clear(u2); set(v2);
+      u = a; v = b;
+
+      do {
+         fail= InvModStatus (z, LeadCoeff(v));
+         if (fail)
+           return;
+         DivRem(q, u, u, v);
+         swap(u, v);
+         u0 = u2;
+         v0 = v2;
+         mul(temp, q, u2);
+         sub(u2, u1, temp);
+         mul(temp, q, v2);
+         sub(v2, v1, temp);
+         u1 = u0;
+         v1 = v0;
+      } while (!IsZero(v));
+
+      d = u;
+      s = u1;
+      t = v1;
+   }
+
+   if (IsZero(d)) return;
+   if (IsOne(LeadCoeff(d))) return;
+
+   /* make gcd monic */
+
+   fail= InvModStatus (z, LeadCoeff(d));
+   if (fail)
+     return;
+   mul(d, d, z);
+   mul(s, s, z);
+   mul(t, t, z);
+}
+#endif
+
diff --git a/factory/cfNTLzzpEXGCD.h b/factory/cfNTLzzpEXGCD.h
new file mode 100644
index 0000000..0716aad
--- /dev/null
+++ b/factory/cfNTLzzpEXGCD.h
@@ -0,0 +1,115 @@
+/*****************************************************************************\
+ * Computer Algebra System SINGULAR
+\*****************************************************************************/
+/** @file cfNTLzzpEXGCD.h
+ *
+ * This file defines functions for univariate GCD and extended GCD
+ * over Z/p[t]/(f)[x] for reducible f
+ *
+ * @note the following code is slightly modified code out of
+ * lzz_pEX.h from Victor Shoup's NTL. Below is NTL's copyright notice.
+ *
+ * ABSTRACT: Langemyr, McCallum "The Computation of Polynomial Greatest Common
+ * Divisors over an algebraic number fields"
+ *
+ * @author Martin Lee
+ *
+
+
+                  COPYRIGHT NOTICE
+		    for NTL 5.5
+	  (modified for Singular 2-0-6 - 3-1)
+
+NTL -- A Library for Doing Number Theory
+Copyright (C) 1996-2009  Victor Shoup
+
+The most recent version of NTL is available at http://www.shoup.net
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 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.
+
+This entire copyright notice should be placed in an appropriately
+conspicuous place accompanying all distributions of software that
+make use of NTL.
+
+The above terms apply to all of the software modules distributed with NTL,
+i.e., all source files in either the ntl-xxx.tar.gz or WinNTL-xxx.zip
+distributions.  In general, the individual files do not contain
+copyright notices.
+
+Note that the quad_float package is derived from the doubledouble package,
+originally developed by Keith Briggs, and also licensed unger the GNU GPL.
+The files quad_float.c and quad_float.h contain more detailed copyright
+notices.
+
+Note that the traditional long integer package used by NTL, lip.c, is derived
+from---and represents an extensive modification of---
+a package originally developed and copyrighted by Arjen Lenstra,
+who has agreed to renounce any copyright claims on the particular
+version of the long integer package appearing in NTL, so that the
+this package now is covered by the GNU GPL as well.
+
+Note that the alternative long integer package used by NTL is GMP,
+which is written by Torbjorn Granlund <tege at swox.com>.
+GMP is licensed under the terms of the GNU Lesser General Public License.
+
+Note that NTL makes use of the RSA Data Security, Inc. MD5 Message
+Digest Algorithm.
+
+Note that prior to version 4.0, NTL was distributed under the following terms:
+   NTL is freely available for research and educational purposes.
+   I don't want to attach any legalistic licensing restrictions on
+   users of NTL.
+   However, NTL should not be linked in a commercial program
+   (although using data in a commercial
+   product produced by a program that used NTL is fine).
+
+The hope is that the GNU GPL is actually less restrictive than these
+older terms;  however, in any circumstances such that GNU GPL is more
+restrictive, then the following rule is in force:
+versions prior to 4.0 may continue to be used under the old terms,
+but users of versions 4.0 or later should adhere to the terms of the GNU GPL.
+**/
+
+
+#ifndef CF_NTL_ZZ_PEX_GCD_H
+#define CF_NTL_ZZ_PEX_GCD_H
+
+// #include "config.h"
+
+#ifdef HAVE_NTL
+#include "NTLconvert.h"
+#endif
+
+#ifdef HAVE_NTL
+/// compute the GCD x of a and b, fail is set to true if a zero divisor is
+/// encountered
+void tryNTLGCD(zz_pEX& x,      ///<[in,out] GCD of a and b
+               const zz_pEX& a,///<[in]     s.a.
+               const zz_pEX& b,///<[in]     s.a.
+               bool& fail      ///<[in,out] s.a.
+              );
+
+/// compute the extended GCD d=s*a+t*b, fail is set to true if a zero divisor is
+/// encountered
+void tryNTLXGCD(zz_pEX& d,      ///<[in,out] GCD of a and b
+                zz_pEX& s,      ///<[in,out] s. a.
+                zz_pEX& t,      ///<[in,out] s. a.
+                const zz_pEX& a,///<[in]     s. a.
+                const zz_pEX& b,///<[in]     s. a.
+                bool& fail      ///<[in,out] s. a.
+               );
+#endif
+
+#endif
diff --git a/factory/cfNewtonPolygon.cc b/factory/cfNewtonPolygon.cc
new file mode 100644
index 0000000..8d37902
--- /dev/null
+++ b/factory/cfNewtonPolygon.cc
@@ -0,0 +1,1375 @@
+/*****************************************************************************\
+ * Computer Algebra System SINGULAR
+\*****************************************************************************/
+/** @file cfNewtonPolygon.cc
+ *
+ * This file provides functions to compute the Newton polygon of a bivariate
+ * polynomial
+ *
+ * @author Martin Lee
+ *
+ **/
+/*****************************************************************************/
+
+
+#include "config.h"
+
+
+#include "cf_assert.h"
+
+#include <stdlib.h>
+
+#include "canonicalform.h"
+#include "cf_iter.h"
+#include "cf_algorithm.h"
+#include "cf_primes.h"
+#include "cf_reval.h"
+#include "cf_factory.h"
+#include "gfops.h"
+#include "cfNewtonPolygon.h"
+#include "templates/ftmpl_functions.h"
+
+static
+void translate (int** points, int* point, int sizePoints) //make point to 0
+{
+  for (int i= 0; i < sizePoints; i++)
+  {
+    points[i] [0] -= point [0];
+    points[i] [1] -= point [1];
+  }
+}
+
+static
+int smallestPointIndex (int** points, int sizePoints)
+{
+  int min= 0;
+  for (int i= 1; i < sizePoints; i++)
+  {
+    if (points[i][0] < points[min][0] ||
+        (points[i] [0] == points[min] [0] && points[i] [1] < points[min] [1]))
+      min= i;
+  }
+  return min;
+}
+
+static
+void swap (int** points, int i, int j)
+{
+  int* tmp= points[i];
+  points[i]= points[j];
+  points[j]= tmp;
+}
+
+static
+bool isLess (int* point1, int* point2)
+{
+  long area= point1[0]*point2[1]- point1[1]*point2[0];
+  if (area > 0) return true;
+  if (area == 0)
+  {
+    return (abs (point1[0]) + abs (point1[1]) >
+            abs (point2[0]) + abs (point2[1]));
+  }
+  return false;
+}
+
+static
+void quickSort (int lo, int hi, int** points)
+{
+  int i= lo, j= hi;
+  int* point= new int [2];
+  point [0]= points [(lo+hi)/2] [0];
+  point [1]= points [(lo+hi)/2] [1];
+  while (i <= j)
+  {
+    while (isLess (points [i], point) && i < hi) i++;
+    while (isLess (point, points[j]) && j > lo) j--;
+    if (i <= j)
+    {
+      swap (points, i, j);
+      i++;
+      j--;
+    }
+  }
+  delete [] point;
+  if (lo < j) quickSort (lo, j, points);
+  if (i < hi) quickSort (i, hi, points);
+}
+
+static
+void sort (int** points, int sizePoints)
+{
+  quickSort (1, sizePoints - 1, points);
+}
+
+// check whether p2 is convex
+static
+bool isConvex (int* point1, int* point2, int* point3)
+{
+  long relArea= (point1[0] - point2[0])*(point3[1] - point2[1]) -
+                (point1[1] - point2[1])*(point3[0] - point2[0]);
+  if (relArea < 0)
+    return true;
+  if (relArea == 0)
+  {
+    return !(abs (point1[0] - point3[0]) + abs (point1[1] - point3[1]) >=
+             (abs (point2[0] - point1[0]) + abs (point2[1] - point1[1]) +
+             abs (point2[0] - point3[0]) + abs (point2[1] - point3[1])));
+  }
+  return false;
+}
+
+static
+bool isConvex (int** points, int i)
+{
+  return isConvex (points[i - 1], points [i], points [i + 1]);
+}
+
+int grahamScan (int** points, int sizePoints)
+{
+  swap (points, 0, smallestPointIndex (points, sizePoints));
+  int * minusPoint= new int [2];
+  minusPoint [0]= points[0] [0];
+  minusPoint [1]= points[0] [1];
+  translate (points, minusPoint, sizePoints);
+  sort (points, sizePoints);
+  minusPoint[0]= - minusPoint[0];
+  minusPoint[1]= - minusPoint[1];
+  translate (points, minusPoint, sizePoints); //reverse translation
+  delete [] minusPoint;
+  int i= 3, k= 3;
+  while (k < sizePoints)
+  {
+    swap (points, i, k);
+    while (!isConvex (points, i - 1))
+    {
+      swap (points, i - 1, i);
+      i--;
+    }
+    k++;
+    i++;
+  }
+  if (i + 1 <= sizePoints || i == sizePoints)
+  {
+    long relArea=
+    (points [i-2][0] - points [i-1][0])*(points [0][1] - points [i-1][1])-
+    (points [i-2][1] - points [i-1][1])*(points [0][0] - points [i-1][0]);
+    if (relArea == 0)
+    {
+      if (abs (points [i-2][0] - points [0][0]) +
+          abs (points [i-2][1] - points [0][1]) >=
+          abs (points [i-1][0] - points [i-2][0]) +
+          abs (points [i-1][1] - points [i-2][1]) +
+          abs (points [i-1][0] - points [0][0]) +
+          abs (points [i-1][1] - points [0][1]))
+          i--;
+    }
+  }
+  return i;
+}
+
+//points[i] [0] is x-coordinate, points [i] [1] is y-coordinate
+int polygon (int** points, int sizePoints)
+{
+  if (sizePoints < 3) return sizePoints;
+  return grahamScan (points, sizePoints);
+}
+
+static
+int* getDegrees (const CanonicalForm& F, int& sizeOfOutput)
+{
+  if (F.inCoeffDomain())
+  {
+    int* result= new int [1];
+    result [0]= 0;
+    sizeOfOutput= 1;
+    return result;
+  }
+  sizeOfOutput= size (F);
+  int* result= new int [sizeOfOutput];
+  int j= 0;
+  for (CFIterator i= F; i.hasTerms(); i++, j++)
+    result [j]= i.exp();
+  return result;
+}
+
+//get points in Z^2 whose convex hull is the Newton polygon
+int ** getPoints (const CanonicalForm& F, int& n)
+{
+  n= size (F);
+  int ** points= new int* [n];
+  for (int i= 0; i < n; i++)
+    points [i]= new int [2];
+
+  int j= 0;
+  int * buf;
+  int bufSize;
+  if (F.isUnivariate() && F.level() == 1)
+  {
+    for (CFIterator i= F; i.hasTerms(); i++, j++)
+    {
+      points [j] [0]= i.exp();
+      points [j] [1]= 0;
+    }
+    return points;
+  }
+  for (CFIterator i= F; i.hasTerms(); i++)
+  {
+    buf= getDegrees (i.coeff(), bufSize);
+    for (int k= 0; k < bufSize; k++, j++)
+    {
+      points [j] [0]= i.exp();
+      points [j] [1]= buf [k];
+    }
+    delete [] buf;
+  }
+  return points;
+}
+
+int **
+merge (int ** points1, int sizePoints1, int ** points2, int sizePoints2,
+       int& sizeResult)
+{
+  int i, j;
+  sizeResult= sizePoints1+sizePoints2;
+  for (i= 0; i < sizePoints1; i++)
+  {
+    for (j= 0; j < sizePoints2; j++)
+    {
+      if (points1[i][0] != points2[j][0])
+        continue;
+      else
+      {
+        if (points1[i][1] != points2[j][1])
+          continue;
+        else
+        {
+          points2[j][0]= -1;
+          points2[j][1]= -1;
+          sizeResult--;
+        }
+      }
+    }
+  }
+  if (sizeResult == 0)
+    return points1;
+
+  int ** result= new int *[sizeResult];
+  for (i= 0; i < sizeResult; i++)
+    result [i]= new int [2];
+
+  int k= 0;
+  for (i= 0; i < sizePoints1; i++, k++)
+  {
+    result[k][0]= points1[i][0];
+    result[k][1]= points1[i][1];
+  }
+  for (i= 0; i < sizePoints2; i++)
+  {
+    if (points2[i][0] < 0)
+      continue;
+    else
+    {
+      result[k][0]= points2[i][0];
+      result[k][1]= points2[i][1];
+      k++;
+    }
+  }
+  return result;
+}
+
+// assumes a bivariate poly as input
+int ** newtonPolygon (const CanonicalForm& F, int& sizeOfNewtonPoly)
+{
+  int sizeF= size (F);
+  int ** points= new int* [sizeF];
+  for (int i= 0; i < sizeF; i++)
+    points [i]= new int [2];
+  int j= 0;
+  int * buf;
+  int bufSize;
+  for (CFIterator i= F; i.hasTerms(); i++)
+  {
+    buf= getDegrees (i.coeff(), bufSize);
+    for (int k= 0; k < bufSize; k++, j++)
+    {
+      points [j] [0]= i.exp();
+      points [j] [1]= buf [k];
+    }
+    delete [] buf;
+  }
+
+  int n= polygon (points, sizeF);
+
+  int ** result= new int* [n];
+  for (int i= 0; i < n; i++)
+  {
+    result [i]= new int [2];
+    result [i] [0]= points [i] [0];
+    result [i] [1]= points [i] [1];
+  }
+
+  sizeOfNewtonPoly= n;
+  for (int i= 0; i < sizeF; i++)
+    delete [] points[i];
+  delete [] points;
+
+  return result;
+}
+
+// assumes a bivariate polys as input
+int ** newtonPolygon (const CanonicalForm& F, const CanonicalForm& G,
+                      int& sizeOfNewtonPoly)
+{
+  int sizeF= size (F);
+  int ** pointsF= new int* [sizeF];
+  for (int i= 0; i < sizeF; i++)
+    pointsF [i]= new int [2];
+  int j= 0;
+  int * buf;
+  int bufSize;
+  for (CFIterator i= F; i.hasTerms(); i++)
+  {
+    buf= getDegrees (i.coeff(), bufSize);
+    for (int k= 0; k < bufSize; k++, j++)
+    {
+      pointsF [j] [0]= i.exp();
+      pointsF [j] [1]= buf [k];
+    }
+    delete [] buf;
+  }
+
+  int sizeG= size (G);
+  int ** pointsG= new int* [sizeG];
+  for (int i= 0; i < sizeG; i++)
+    pointsG [i]= new int [2];
+  j= 0;
+  for (CFIterator i= G; i.hasTerms(); i++)
+  {
+    buf= getDegrees (i.coeff(), bufSize);
+    for (int k= 0; k < bufSize; k++, j++)
+    {
+      pointsG [j] [0]= i.exp();
+      pointsG [j] [1]= buf [k];
+    }
+    delete [] buf;
+  }
+
+  int sizePoints;
+  int ** points= merge (pointsF, sizeF, pointsG, sizeG, sizePoints);
+
+  int n= polygon (points, sizePoints);
+
+  int ** result= new int* [n];
+  for (int i= 0; i < n; i++)
+  {
+    result [i]= new int [2];
+    result [i] [0]= points [i] [0];
+    result [i] [1]= points [i] [1];
+  }
+
+  sizeOfNewtonPoly= n;
+  for (int i= 0; i < sizeF; i++)
+    delete [] pointsF[i];
+  delete [] pointsF;
+  for (int i= 0; i < sizeG; i++)
+    delete [] pointsG[i];
+  delete [] pointsG;
+
+  return result;
+}
+
+// assumes first sizePoints entries of points form a Newton polygon
+bool isInPolygon (int ** points, int sizePoints, int* point)
+{
+  int ** buf= new int* [sizePoints + 1];
+  for (int i= 0; i < sizePoints; i++)
+  {
+    buf [i]= new int [2];
+    buf [i] [0]= points [i] [0];
+    buf [i] [1]= points [i] [1];
+  }
+  buf [sizePoints]= new int [2];
+  buf [sizePoints] [0]= point [0];
+  buf [sizePoints] [1]= point [1];
+  int sizeBuf= sizePoints + 1;
+
+  swap (buf, 0, smallestPointIndex (buf, sizeBuf));
+  int * minusPoint= new int [2];
+  minusPoint [0]= buf[0] [0];
+  minusPoint [1]= buf[0] [1];
+  translate (buf, minusPoint, sizeBuf);
+  sort (buf, sizeBuf);
+  minusPoint[0]= - minusPoint[0];
+  minusPoint[1]= - minusPoint[1];
+  translate (buf, minusPoint, sizeBuf); //reverse translation
+  delete [] minusPoint;
+
+  if (buf [0] [0] == point [0] && buf [0] [1] == point [1])
+  {
+    for (int i= 0; i < sizeBuf; i++)
+      delete [] buf[i];
+    delete [] buf;
+    return false;
+  }
+
+  for (int i= 1; i < sizeBuf-1; i++)
+  {
+    if (buf [i] [0] == point [0] && buf [i] [1] == point [1])
+    {
+      bool result= !isConvex (buf, i);
+      for (int i= 0; i < sizeBuf; i++)
+        delete [] buf [i];
+      delete [] buf;
+      return result;
+    }
+  }
+
+  if (buf [sizeBuf - 1] [0] == point [0] && buf [sizeBuf-1] [1] == point [1])
+  {
+    buf [1] [0]= point [0];
+    buf [1] [1]= point [1];
+    buf [2] [0]= buf [0] [0];
+    buf [2] [1]= buf [0] [1];
+    buf [0] [0]= buf [sizeBuf-2] [0];
+    buf [0] [1]= buf [sizeBuf-2] [1];
+    bool result= !isConvex (buf, 1);
+    for (int i= 0; i < sizeBuf; i++)
+      delete [] buf [i];
+    delete [] buf;
+    return result;
+  }
+  for (int i= 0; i < sizeBuf; i++)
+    delete [] buf [i];
+  delete [] buf;
+
+  return false;
+}
+
+void lambda (int** points, int sizePoints)
+{
+  for (int i= 0; i < sizePoints; i++)
+    points [i] [1]= points [i] [1] - points [i] [0];
+}
+
+void lambdaInverse (int** points, int sizePoints)
+{
+  for (int i= 0; i < sizePoints; i++)
+    points [i] [1]= points [i] [1] + points [i] [0];
+}
+
+void tau (int** points, int sizePoints, int k)
+{
+  for (int i= 0; i < sizePoints; i++)
+    points [i] [1]= points [i] [1] + k;
+}
+
+void mu (int** points, int sizePoints)
+{
+  int tmp;
+  for (int i= 0; i < sizePoints; i++)
+  {
+    tmp= points [i] [0];
+    points [i] [0]= points [i] [1];
+    points [i] [1]= tmp;
+  }
+}
+
+void getMaxMin (int** points, int sizePoints, int& minDiff, int& minSum,
+                int& maxDiff, int& maxSum, int& maxX, int& maxY
+               )
+{
+  minDiff= points [0] [1] - points [0] [0];
+  minSum= points [0] [1] + points [0] [0];
+  maxDiff= points [0] [1] - points [0] [0];
+  maxSum= points [0] [1] + points [0] [0];
+  maxX= points [0] [1];
+  maxY= points [0] [0];
+  int diff, sum;
+  for (int i= 1; i < sizePoints; i++)
+  {
+    diff= points [i] [1] - points [i] [0];
+    sum= points [i] [1] + points [i] [0];
+    minDiff= tmin (minDiff, diff);
+    minSum= tmin (minSum, sum);
+    maxDiff= tmax (maxDiff, diff);
+    maxSum= tmax (maxSum, sum);
+    maxX= tmax (maxX, points [i] [1]);
+    maxY= tmax (maxY, points [i] [0]);
+  }
+}
+
+void mpz_mat_mul (const mpz_t* N, mpz_t*& M)
+{
+  mpz_t * tmp= new mpz_t[4];
+
+  mpz_init_set (tmp[0], N[0]);
+  mpz_mul (tmp[0], tmp[0], M[0]);
+  mpz_addmul (tmp[0], N[1], M[2]);
+
+  mpz_init_set (tmp[1], N[0]);
+  mpz_mul (tmp[1], tmp[1], M[1]);
+  mpz_addmul (tmp[1], N[1], M[3]);
+
+  mpz_init_set (tmp[2], N[2]);
+  mpz_mul (tmp[2], tmp[2], M[0]);
+  mpz_addmul (tmp[2], N[3], M[2]);
+
+  mpz_init_set (tmp[3], N[2]);
+  mpz_mul (tmp[3], tmp[3], M[1]);
+  mpz_addmul (tmp[3], N[3], M[3]);
+
+  mpz_set (M[0], tmp[0]);
+  mpz_set (M[1], tmp[1]);
+  mpz_set (M[2], tmp[2]);
+  mpz_set (M[3], tmp[3]);
+
+  mpz_clear (tmp[0]);
+  mpz_clear (tmp[1]);
+  mpz_clear (tmp[2]);
+  mpz_clear (tmp[3]);
+
+  delete [] tmp;
+}
+
+void mpz_mat_inv (mpz_t*& M)
+{
+  mpz_t det;
+  mpz_init_set (det, M[0]);
+  mpz_mul (det, det, M[3]);
+  mpz_submul (det, M[1], M[2]);
+
+  mpz_t tmp;
+  mpz_init_set (tmp, M[0]);
+  mpz_divexact (tmp, tmp, det);
+  mpz_set (M[0], M[3]);
+  mpz_divexact (M[0], M[0], det);
+  mpz_set (M[3], tmp);
+
+  mpz_neg (M[1], M[1]);
+  mpz_divexact (M[1], M[1], det);
+  mpz_neg (M[2], M[2]);
+  mpz_divexact (M[2], M[2], det);
+
+  mpz_clear (det);
+  mpz_clear (tmp);
+}
+
+void convexDense(int** points, int sizePoints, mpz_t*& M, mpz_t*& A)
+{
+  if (sizePoints < 3)
+  {
+    if (sizePoints == 2)
+    {
+      mpz_t u,v,g,maxX,maxY;
+      mpz_init (u);
+      mpz_init (v);
+      mpz_init (g);
+      mpz_init_set_si (maxX,
+                       (points[1][1] < points[0][1])?points[0][1]:points[1][1]);
+      mpz_init_set_si (maxY,
+                       (points[1][0] < points[0][0])?points[0][0]:points[1][0]);
+      mpz_gcdext (g, u, v, maxX, maxY);
+      if (points [0] [1] != points [0] [0] && points [1] [0] != points [1] [1])
+      {
+        mpz_set (A[0], u);
+        mpz_mul (A[0], A[0], maxX);
+        mpz_set (M[2], maxY);
+        mpz_divexact (M[2], M[2], g);
+        mpz_set (A[1], M[2]);
+        mpz_neg (A[1], A[1]);
+        mpz_mul (A[1], A[1], maxX);
+        mpz_neg (u, u);
+        mpz_set (M[0], u);
+        mpz_set (M[1], v);
+        mpz_set (M[3], maxX);
+        mpz_divexact (M[3], M[3], g);
+      }
+      else
+      {
+        mpz_set (M[0], u);
+        mpz_set (M[1], v);
+        mpz_set (M[2], maxY);
+        mpz_divexact (M[2], M[2], g);
+        mpz_neg (M[2], M[2]);
+        mpz_set (M[3], maxX);
+        mpz_divexact (M[3], M[3], g);
+      }
+      mpz_clear (u);
+      mpz_clear (v);
+      mpz_clear (g);
+      mpz_clear (maxX);
+      mpz_clear (maxY);
+    }
+    else if (sizePoints == 1)
+    {
+      mpz_set_si (M[0], 1);
+      mpz_set_si (M[3], 1);
+    }
+    return;
+  }
+  mpz_set_si (M[0], 1);
+  mpz_set_si (M[3], 1);
+
+  mpz_t * Mu= new mpz_t[4];
+  mpz_init_set_si (Mu[1], 1);
+  mpz_init_set_si (Mu[2], 1);
+  mpz_init (Mu[0]);
+  mpz_init (Mu[3]);
+
+  mpz_t * Lambda= new mpz_t[4];
+  mpz_init_set_si (Lambda[0], 1);
+  mpz_init_set_si (Lambda[1], -1);
+  mpz_init_set_si (Lambda[3], 1);
+  mpz_init (Lambda[2]);
+
+  mpz_t * InverseLambda= new mpz_t[4];
+  mpz_init_set_si (InverseLambda[0], 1);
+  mpz_init_set_si (InverseLambda[1], 1);
+  mpz_init_set_si (InverseLambda[3], 1);
+  mpz_init (InverseLambda[2]);
+
+  mpz_t tmp;
+  mpz_init (tmp);
+  int minDiff, minSum, maxDiff, maxSum, maxX, maxY, b, d, f, h;
+  getMaxMin(points, sizePoints, minDiff, minSum, maxDiff, maxSum, maxX, maxY);
+  do
+  {
+    if (maxX < maxY)
+    {
+      mu (points, sizePoints);
+
+      mpz_mat_mul (Mu, M);
+
+      mpz_set (tmp, A[0]);
+      mpz_set (A[0], A[1]);
+      mpz_set (A[1], tmp);
+    }
+    getMaxMin(points, sizePoints, minDiff, minSum, maxDiff, maxSum, maxX, maxY);
+    b= maxX - maxDiff;
+    d= maxX + maxY - maxSum;
+    f= maxY + minDiff;
+    h= minSum;
+    if (b + f > maxY)
+    {
+      lambda (points, sizePoints);
+      tau (points, sizePoints, maxY - f);
+
+      mpz_mat_mul (Lambda, M);
+
+      if (maxY-f > 0)
+        mpz_add_ui (A[0], A[0], maxY-f);
+      else
+        mpz_add_ui (A[0], A[0], f-maxY);
+      maxX= maxX + maxY - b - f;
+    }
+    else if (d + h > maxY)
+    {
+      lambdaInverse (points, sizePoints);
+      tau (points, sizePoints, -h);
+
+      mpz_mat_mul (InverseLambda, M);
+
+      if (h < 0)
+        mpz_add_ui (A[0], A[0], -h);
+      else
+        mpz_sub_ui (A[0], A[0], h);
+      maxX= maxX + maxY - d - h;
+    }
+    else
+    {
+      mpz_clear (tmp);
+      mpz_clear (Mu[0]);
+      mpz_clear (Mu[1]);
+      mpz_clear (Mu[2]);
+      mpz_clear (Mu[3]);
+      delete [] Mu;
+
+      mpz_clear (Lambda[0]);
+      mpz_clear (Lambda[1]);
+      mpz_clear (Lambda[2]);
+      mpz_clear (Lambda[3]);
+      delete [] Lambda;
+
+      mpz_clear (InverseLambda[0]);
+      mpz_clear (InverseLambda[1]);
+      mpz_clear (InverseLambda[2]);
+      mpz_clear (InverseLambda[3]);
+      delete [] InverseLambda;
+
+      return;
+    }
+  } while (1);
+}
+
+CanonicalForm
+compress (const CanonicalForm& F, mpz_t*& M, mpz_t*& A, bool computeMA)
+{
+  int n;
+  int ** newtonPolyg= NULL;
+  if (computeMA)
+  {
+    newtonPolyg= newtonPolygon (F, n);
+    convexDense (newtonPolyg, n, M, A);
+  }
+
+  CanonicalForm result= 0;
+  Variable x= Variable (1);
+  Variable y= Variable (2);
+
+  mpz_t expX, expY, minExpX, minExpY;
+  mpz_init (expX);
+  mpz_init (expY);
+  mpz_init (minExpX);
+  mpz_init (minExpY);
+
+  int k= 0;
+  Variable alpha;
+  mpz_t * exps= new mpz_t [2*size (F)];
+  int count= 0;
+  for (CFIterator i= F; i.hasTerms(); i++)
+  {
+    if (i.coeff().inCoeffDomain() && hasFirstAlgVar (i.coeff(), alpha))
+    {
+      mpz_set (expX, A[0]);
+      mpz_set (expY, A[1]);
+      mpz_addmul_ui (expX, M[1], i.exp());
+      mpz_addmul_ui (expY, M[3], i.exp());
+
+      if (k == 0)
+      {
+        mpz_set (minExpX, expX);
+        mpz_set (minExpY, expY);
+        k= 1;
+      }
+      else
+      {
+        if (mpz_cmp (minExpY, expY) > 0)
+          mpz_set (minExpY, expY);
+        if (mpz_cmp (minExpX, expX) > 0)
+          mpz_set (minExpX, expX);
+      }
+      mpz_init_set (exps[count], expX);
+      count++;
+      mpz_init_set (exps[count], expY);
+      count++;
+      continue;
+    }
+    CFIterator j= i.coeff();
+    if (k == 0)
+    {
+      mpz_set (expX, A[0]);
+      mpz_addmul_ui (expX, M[1], i.exp());
+      mpz_addmul_ui (expX, M[0], j.exp());
+
+      mpz_set (expY, A[1]);
+      mpz_addmul_ui (expY, M[3], i.exp());
+      mpz_addmul_ui (expY, M[2], j.exp());
+
+      mpz_set (minExpX, expX);
+      mpz_set (minExpY, expY);
+      mpz_init_set (exps[count], expX);
+      count++;
+      mpz_init_set (exps[count], expY);
+      count++;
+      j++;
+      k= 1;
+    }
+
+    for (; j.hasTerms(); j++)
+    {
+      mpz_set (expX, A[0]);
+      mpz_addmul_ui (expX, M[1], i.exp());
+      mpz_addmul_ui (expX, M[0], j.exp());
+
+      mpz_set (expY, A[1]);
+      mpz_addmul_ui (expY, M[3], i.exp());
+      mpz_addmul_ui (expY, M[2], j.exp());
+
+      mpz_init_set (exps[count], expX);
+      count++;
+      mpz_init_set (exps[count], expY);
+      count++;
+      if (mpz_cmp (minExpY, expY) > 0)
+        mpz_set (minExpY, expY);
+      if (mpz_cmp (minExpX, expX) > 0)
+        mpz_set (minExpX, expX);
+    }
+  }
+
+  count= 0;
+  int mExpX= mpz_get_si (minExpX);
+  int mExpY= mpz_get_si (minExpY);
+  for (CFIterator i= F; i.hasTerms(); i++)
+  {
+    if (i.coeff().inCoeffDomain() && hasFirstAlgVar (i.coeff(), alpha))
+    {
+      result += i.coeff()*power (x, mpz_get_si (exps[count])-mExpX)*
+                power (y, mpz_get_si (exps[count+1])-mExpY);
+      count += 2;
+      continue;
+    }
+    CFIterator j= i.coeff();
+    for (; j.hasTerms(); j++)
+    {
+      result += j.coeff()*power (x, mpz_get_si (exps[count])-mExpX)*
+                power (y, mpz_get_si (exps[count+1])-mExpY);
+      count += 2;
+    }
+  }
+
+  CanonicalForm tmp= LC (result);
+  if (tmp.inPolyDomain() && degree (tmp) <= 0)
+  {
+    int d= degree (result);
+    Variable x= result.mvar();
+    result -= tmp*power (x, d);
+    result += Lc (tmp)*power (x, d);
+  }
+
+  if (computeMA)
+  {
+    for (int i= 0; i < n; i++)
+      delete [] newtonPolyg [i];
+    delete [] newtonPolyg;
+    mpz_mat_inv (M);
+  }
+
+  delete [] exps;
+  mpz_clear (expX);
+  mpz_clear (expY);
+  mpz_clear (minExpX);
+  mpz_clear (minExpY);
+
+  return result;
+}
+
+CanonicalForm
+decompress (const CanonicalForm& F, const mpz_t* inverseM, const mpz_t * A)
+{
+  CanonicalForm result= 0;
+  Variable x= Variable (1);
+  Variable y= Variable (2);
+
+  mpz_t expX, expY, minExpX, minExpY;
+  mpz_init (expX);
+  mpz_init (expY);
+  mpz_init (minExpX);
+  mpz_init (minExpY);
+
+  mpz_t * exps= new mpz_t [2*size(F)];
+  int count= 0;
+  if (F.isUnivariate() && F.level() == 1)
+  {
+    CFIterator i= F;
+
+    mpz_set_si (expX, i.exp());
+    mpz_sub (expX, expX, A[0]);
+    mpz_mul (expX, expX, inverseM[0]);
+    mpz_submul (expX, inverseM[1], A[1]);
+
+    mpz_set_si (expY, i.exp());
+    mpz_sub (expY, expY, A[0]);
+    mpz_mul (expY, expY, inverseM[2]);
+    mpz_submul (expY, inverseM[3], A[1]);
+
+    mpz_set (minExpX, expX);
+    mpz_set (minExpY, expY);
+
+    mpz_init_set (exps[count], expX);
+    mpz_init_set (exps[count+1], expY);
+    count += 2;
+
+    i++;
+    for (; i.hasTerms(); i++)
+    {
+      mpz_set_si (expX, i.exp());
+      mpz_sub (expX, expX, A[0]);
+      mpz_mul (expX, expX, inverseM[0]);
+      mpz_submul (expX, inverseM[1], A[1]);
+
+      mpz_set_si (expY, i.exp());
+      mpz_sub (expY, expY, A[0]);
+      mpz_mul (expY, expY, inverseM[2]);
+      mpz_submul (expY, inverseM[3], A[1]);
+
+      mpz_init_set (exps[count], expX);
+      mpz_init_set (exps[count+1], expY);
+      count += 2;
+
+      if (mpz_cmp (minExpY, expY) > 0)
+        mpz_set (minExpY, expY);
+      if (mpz_cmp (minExpX, expX) > 0)
+        mpz_set (minExpX, expX);
+    }
+
+    int mExpX= mpz_get_si (minExpX);
+    int mExpY= mpz_get_si (minExpY);
+    count= 0;
+    for (i= F; i.hasTerms(); i++)
+    {
+      result += i.coeff()*power (x, mpz_get_si (exps[count])-mExpX)*
+                power (y, mpz_get_si (exps[count+1])-mExpY);
+      count += 2;
+    }
+
+    mpz_clear (expX);
+    mpz_clear (expY);
+    mpz_clear (minExpX);
+    mpz_clear (minExpY);
+
+    delete [] exps;
+    return result/ Lc (result); //normalize
+  }
+
+  mpz_t tmp;
+  mpz_init (tmp);
+  int k= 0;
+  Variable alpha;
+  for (CFIterator i= F; i.hasTerms(); i++)
+  {
+    if (i.coeff().inCoeffDomain() && hasFirstAlgVar (i.coeff(), alpha))
+    {
+      mpz_set_si (expX, i.exp());
+      mpz_sub (expX, expX, A[1]);
+      mpz_mul (expX, expX, inverseM[1]);
+      mpz_submul (expX, A[0], inverseM[0]);
+
+      mpz_set_si (expY, i.exp());
+      mpz_sub (expY, expY, A[1]);
+      mpz_mul (expY, expY, inverseM[3]);
+      mpz_submul (expY, A[0], inverseM[2]);
+
+      if (k == 0)
+      {
+        mpz_set (minExpX, expX);
+        mpz_set (minExpY, expY);
+        k= 1;
+      }
+      else
+      {
+        if (mpz_cmp (minExpY, expY) > 0)
+          mpz_set (minExpY, expY);
+        if (mpz_cmp (minExpX, expX) > 0)
+          mpz_set (minExpX, expX);
+      }
+      mpz_init_set (exps[count], expX);
+      mpz_init_set (exps[count+1], expY);
+      count += 2;
+      continue;
+    }
+    CFIterator j= i.coeff();
+    if (k == 0)
+    {
+      mpz_set_si (expX, j.exp());
+      mpz_sub (expX, expX, A[0]);
+      mpz_mul (expX, expX, inverseM[0]);
+      mpz_set_si (tmp, i.exp());
+      mpz_sub (tmp, tmp, A[1]);
+      mpz_addmul (expX, tmp, inverseM[1]);
+
+      mpz_set_si (expY, j.exp());
+      mpz_sub (expY, expY, A[0]);
+      mpz_mul (expY, expY, inverseM[2]);
+      mpz_set_si (tmp, i.exp());
+      mpz_sub (tmp, tmp, A[1]);
+      mpz_addmul (expY, tmp, inverseM[3]);
+
+      mpz_set (minExpX, expX);
+      mpz_set (minExpY, expY);
+
+      mpz_init_set (exps[count], expX);
+      mpz_init_set (exps[count+1], expY);
+      count += 2;
+
+      j++;
+      k= 1;
+    }
+
+    for (; j.hasTerms(); j++)
+    {
+      mpz_set_si (expX, j.exp());
+      mpz_sub (expX, expX, A[0]);
+      mpz_mul (expX, expX, inverseM[0]);
+      mpz_set_si (tmp, i.exp());
+      mpz_sub (tmp, tmp, A[1]);
+      mpz_addmul (expX, tmp, inverseM[1]);
+
+      mpz_set_si (expY, j.exp());
+      mpz_sub (expY, expY, A[0]);
+      mpz_mul (expY, expY, inverseM[2]);
+      mpz_set_si (tmp, i.exp());
+      mpz_sub (tmp, tmp, A[1]);
+      mpz_addmul (expY, tmp, inverseM[3]);
+
+      mpz_init_set (exps[count], expX);
+      mpz_init_set (exps[count+1], expY);
+      count += 2;
+
+      if (mpz_cmp (minExpY, expY) > 0)
+        mpz_set (minExpY, expY);
+      if (mpz_cmp (minExpX, expX) > 0)
+        mpz_set (minExpX, expX);
+    }
+  }
+
+  int mExpX= mpz_get_si (minExpX);
+  int mExpY= mpz_get_si (minExpY);
+  count= 0;
+  for (CFIterator i= F; i.hasTerms(); i++)
+  {
+    if (i.coeff().inCoeffDomain() && hasFirstAlgVar (i.coeff(), alpha))
+    {
+      result += i.coeff()*power (x, mpz_get_si (exps[count])-mExpX)*
+                power (y, mpz_get_si (exps[count+1])-mExpY);
+      count += 2;
+      continue;
+    }
+    for (CFIterator j= i.coeff(); j.hasTerms(); j++)
+    {
+      result += j.coeff()*power (x, mpz_get_si (exps[count])-mExpX)*
+                power (y, mpz_get_si (exps[count+1])-mExpY);
+      count += 2;
+    }
+  }
+
+  mpz_clear (expX);
+  mpz_clear (expY);
+  mpz_clear (minExpX);
+  mpz_clear (minExpY);
+  mpz_clear (tmp);
+
+  delete [] exps;
+
+  return result/Lc (result); //normalize
+}
+
+//assumes the input is a Newton polygon of a bivariate polynomial which is
+//primitive wrt. x and y, i.e. there is at least one point of the polygon lying
+//on the x-axis and one lying on the y-axis
+int* getRightSide (int** polygon, int sizeOfPolygon, int& sizeOfOutput)
+{
+  int maxY= polygon [0][0];
+  int indexY= 0;
+  for (int i= 1; i < sizeOfPolygon; i++)
+  {
+    if (maxY < polygon [i][0])
+    {
+      maxY= polygon [i][0];
+      indexY= i;
+    }
+    else if (maxY == polygon [i][0])
+    {
+      if (polygon [indexY][1] < polygon[i][1])
+        indexY= i;
+    }
+    if (maxY > polygon [i][0])
+      break;
+  }
+
+  int count= -1;
+  for (int i= indexY; i < sizeOfPolygon; i++)
+  {
+    if (polygon[i][0] == 0)
+    {
+      count= i - indexY;
+      break;
+    }
+  }
+
+  int * result;
+  int index= 0;
+  if (count < 0)
+  {
+    result= new int [sizeOfPolygon - indexY];
+    sizeOfOutput= sizeOfPolygon - indexY;
+    count= sizeOfPolygon - indexY - 1;
+    result [0]= polygon[sizeOfPolygon - 1][0] - polygon [0] [0];
+    index= 1;
+  }
+  else
+  {
+    sizeOfOutput= count;
+    result= new int [count];
+  }
+
+  for (int i= indexY + count; i > indexY; i--, index++)
+    result [index]= polygon [i - 1] [0] - polygon [i] [0];
+
+  return result;
+}
+
+bool irreducibilityTest (const CanonicalForm& F)
+{
+  ASSERT (getNumVars (F) == 2, "expected bivariate polynomial");
+  ASSERT (getCharacteristic() == 0, "expected polynomial over integers or rationals");
+
+  int sizeOfNewtonPolygon;
+  int ** newtonPolyg= newtonPolygon (F, sizeOfNewtonPolygon);
+  if (sizeOfNewtonPolygon == 3)
+  {
+    bool check1=
+        (newtonPolyg[0][0]==0 || newtonPolyg[1][0]==0 || newtonPolyg[2][0]==0);
+    if (check1)
+    {
+      bool check2=
+        (newtonPolyg[0][1]==0 || newtonPolyg[1][1]==0 || newtonPolyg[2][0]==0);
+      if (check2)
+      {
+        bool isRat= isOn (SW_RATIONAL);
+        if (isRat)
+          Off (SW_RATIONAL);
+        CanonicalForm tmp= gcd (newtonPolyg[0][0],newtonPolyg[0][1]); // maybe it's better to use plain intgcd
+        tmp= gcd (tmp, newtonPolyg[1][0]);
+        tmp= gcd (tmp, newtonPolyg[1][1]);
+        tmp= gcd (tmp, newtonPolyg[2][0]);
+        tmp= gcd (tmp, newtonPolyg[2][1]);
+        if (isRat)
+          On (SW_RATIONAL);
+        for (int i= 0; i < sizeOfNewtonPolygon; i++)
+          delete [] newtonPolyg [i];
+        delete [] newtonPolyg;
+        return (tmp==1);
+      }
+    }
+  }
+  for (int i= 0; i < sizeOfNewtonPolygon; i++)
+    delete [] newtonPolyg [i];
+  delete [] newtonPolyg;
+  return false;
+}
+
+bool absIrredTest (const CanonicalForm& F)
+{
+  ASSERT (getNumVars (F) == 2, "expected bivariate polynomial");
+  ASSERT (factorize (F).length() <= 2, " expected irreducible polynomial");
+
+  int sizeOfNewtonPolygon;
+  int ** newtonPolyg= newtonPolygon (F, sizeOfNewtonPolygon);
+  bool isRat= isOn (SW_RATIONAL);
+  if (isRat)
+    Off (SW_RATIONAL);
+  int p=getCharacteristic();
+  int d=1;
+  char bufGFName='Z';
+  bool GF= (CFFactory::gettype()==GaloisFieldDomain);
+  if (GF)
+  {
+    d= getGFDegree();
+    bufGFName=gf_name;
+  }
+
+  setCharacteristic(0);
+
+  CanonicalForm g= gcd (newtonPolyg[0][0], newtonPolyg[0][1]); //maybe it's better to use plain intgcd
+
+  int i= 1;
+  while (!g.isOne() && i < sizeOfNewtonPolygon)
+  {
+    g= gcd (g, newtonPolyg[i][0]);
+    g= gcd (g, newtonPolyg[i][1]);
+    i++;
+  }
+
+  bool result= g.isOne();
+
+  if (GF)
+    setCharacteristic (p, d, bufGFName);
+  else
+    setCharacteristic(p);
+
+  if (isRat)
+    On (SW_RATIONAL);
+
+  for (int i= 0; i < sizeOfNewtonPolygon; i++)
+    delete [] newtonPolyg[i];
+
+  delete [] newtonPolyg;
+
+  return result;
+}
+
+bool modularIrredTest (const CanonicalForm& F)
+{
+  ASSERT (getNumVars (F) == 2, "expected bivariate polynomial");
+  ASSERT (factorize (F).length() <= 2, " expected irreducible polynomial");
+
+  bool isRat= isOn (SW_RATIONAL);
+  if (isRat)
+    Off (SW_RATIONAL);
+
+  if (isRat)
+  {
+    ASSERT (bCommonDen (F).isOne(), "poly over Z expected");
+  }
+
+  CanonicalForm Fp, N= maxNorm (F);
+  int tdeg= totaldegree (F);
+
+  int i= 0;
+  //TODO: maybe it's better to choose the characteristic as large as possible
+  //      as factorization over large finite field will be faster
+  //TODO: handle those cases where our factory primes are not enough
+  //TODO: factorize coefficients corresponding to the vertices of the Newton
+  //      polygon and only try the obtained factors
+  if (N < cf_getSmallPrime (cf_getNumSmallPrimes()-1))
+  {
+    while (i < cf_getNumSmallPrimes() && N > cf_getSmallPrime(i))
+    {
+      setCharacteristic (cf_getSmallPrime (i));
+      Fp= F.mapinto();
+      i++;
+      if (totaldegree (Fp) == tdeg)
+      {
+        if (absIrredTest (Fp))
+        {
+          CFFList factors= factorize (Fp);
+          if (factors.length() == 2 && factors.getLast().exp() == 1)
+          {
+            if (isRat)
+              On (SW_RATIONAL);
+            setCharacteristic (0);
+            return true;
+          }
+        }
+      }
+      setCharacteristic (0);
+    }
+  }
+  else
+  {
+    while (i < cf_getNumPrimes() && N > cf_getPrime (i))
+    {
+      setCharacteristic (cf_getPrime (i));
+      Fp= F.mapinto();
+      i++;
+      if (totaldegree (Fp) == tdeg)
+      {
+        if (absIrredTest (Fp))
+        {
+          CFFList factors= factorize (Fp);
+          if (factors.length() == 2 && factors.getLast().exp() == 1)
+          {
+            if (isRat)
+              On (SW_RATIONAL);
+            setCharacteristic (0);
+            return true;
+          }
+        }
+      }
+      setCharacteristic (0);
+    }
+  }
+
+  if (isRat)
+    On (SW_RATIONAL);
+
+  return false;
+}
+
+bool
+modularIrredTestWithShift (const CanonicalForm& F)
+{
+  ASSERT (getNumVars (F) == 2, "expected bivariate polynomial");
+  ASSERT (factorize (F).length() <= 2, " expected irreducible polynomial");
+
+  bool isRat= isOn (SW_RATIONAL);
+  if (isRat)
+    Off (SW_RATIONAL);
+
+  if (isRat)
+  {
+    ASSERT (bCommonDen (F).isOne(), "poly over Z expected");
+  }
+
+  Variable x= Variable (1);
+  Variable y= Variable (2);
+  CanonicalForm Fp;
+  int tdeg= totaldegree (F);
+
+  REvaluation E;
+
+  setCharacteristic (2);
+  Fp= F.mapinto();
+
+  E= REvaluation (1,2, FFRandom());
+
+  E.nextpoint();
+
+  Fp= Fp (x+E[1], x);
+  Fp= Fp (y+E[2], y);
+
+  if (tdeg == totaldegree (Fp))
+  {
+    if (absIrredTest (Fp))
+    {
+      CFFList factors= factorize (Fp);
+      if (factors.length() == 2 && factors.getLast().exp() == 1)
+      {
+        if (isRat)
+          On (SW_RATIONAL);
+        setCharacteristic (0);
+        return true;
+      }
+    }
+  }
+
+  E.nextpoint();
+
+  Fp= Fp (x+E[1], x);
+  Fp= Fp (y+E[2], y);
+
+  if (tdeg == totaldegree (Fp))
+  {
+    if (absIrredTest (Fp))
+    {
+      CFFList factors= factorize (Fp);
+      if (factors.length() == 2 && factors.getLast().exp() == 1)
+      {
+        if (isRat)
+          On (SW_RATIONAL);
+        setCharacteristic (0);
+        return true;
+      }
+    }
+  }
+
+  int i= 0;
+  while (cf_getSmallPrime (i) < 102)
+  {
+    setCharacteristic (cf_getSmallPrime (i));
+    i++;
+    E= REvaluation (1, 2, FFRandom());
+
+    for (int j= 0; j < 3; j++)
+    {
+      Fp= F.mapinto();
+      E.nextpoint();
+      Fp= Fp (x+E[1], x);
+      Fp= Fp (y+E[2], y);
+
+      if (tdeg == totaldegree (Fp))
+      {
+        if (absIrredTest (Fp))
+        {
+          CFFList factors= factorize (Fp);
+          if (factors.length() == 2 && factors.getLast().exp() == 1)
+          {
+            if (isRat)
+              On (SW_RATIONAL);
+            setCharacteristic (0);
+            return true;
+          }
+        }
+      }
+    }
+  }
+
+  setCharacteristic (0);
+  if (isRat)
+    On (SW_RATIONAL);
+
+  return false;
+}
+
+
diff --git a/factory/cfNewtonPolygon.h b/factory/cfNewtonPolygon.h
new file mode 100644
index 0000000..68af345
--- /dev/null
+++ b/factory/cfNewtonPolygon.h
@@ -0,0 +1,136 @@
+/*****************************************************************************\
+ * Computer Algebra System SINGULAR
+\*****************************************************************************/
+/** @file cfNewtonPolygon.h
+ *
+ * This file provides functions to compute the Newton polygon of a bivariate
+ * polynomial
+ *
+ * @author Martin Lee
+ *
+ **/
+/*****************************************************************************/
+
+#ifndef CF_NEWTON_POLYGON_H
+#define CF_NEWTON_POLYGON_H
+
+// #include "config.h"
+
+/// compute a polygon
+///
+/// @return an integer n such that the first n entries of @a points are the
+///         vertices of the convex hull of @a points
+int polygon (int** points, ///< [in,out] an array of points in the plane
+             int sizePoints///< [in] number of elements in @a points
+            );
+
+/// compute the Newton polygon of a bivariate polynomial
+///
+/// @return an array of points in the plane which are the vertices of the Newton
+///         polygon of F
+int ** newtonPolygon (const CanonicalForm& F,///< [in] a bivariate polynomial
+                      int& sizeOfNewtonPoly  ///< [in, out] size of the result
+                     );
+
+/// compute the convex hull of the support of two bivariate polynomials
+///
+/// @return an array of points in the plane which are the vertices of the convex
+///         hull of the support of F and G
+int ** newtonPolygon (const CanonicalForm& F,///< [in] a bivariate polynomial
+                      const CanonicalForm& G,///< [in] a bivariate polynomial
+                      int& sizeOfNewtonPoly  ///< [in, out] size of the result
+                     );
+
+/// check if @a point is inside a polygon described by points
+///
+/// @return true if @a point is inside a polygon described by points
+bool isInPolygon (int ** points, ///< [in] an array of points in the
+                                 ///< plane describing a polygon
+                  int sizePoints,///< [in] size of @a points
+                  int* point     ///< [in] a point in the plane
+                 );
+
+/// get the y-direction slopes of all edges with positive slope in y-direction
+/// of a convex polygon with at least one point of the polygon lying on the
+/// x-axis and one lying on the y-axis
+///
+/// @return an array containing the slopes as described above
+int* getRightSide (int** polygon,     ///<[in] vertices of a polygon
+                   int sizeOfPolygon, ///<[in] number of vertices
+                   int& sizeOfOutput  ///<[in,out] size of the output
+                  );
+
+/// computes the Newton polygon of F and checks if it satisfies the
+/// irreducibility criterion from S.Gao "Absolute irreducibility of polynomials
+/// via polytopes", Example 1
+///
+/// @return true if it satisfies the above criterion, false otherwise
+bool
+irreducibilityTest (const CanonicalForm& F ///<[in] a bivariate polynomial
+                   );
+
+/// absolute irreducibility test as described in "Modular Las Vegas Algorithms
+/// for Polynomial Absolute Factorization" by C. Bertone, G. Cheze, A. Galligo
+///
+/// @return true if F satisfies condition (C) from the above paper and thus
+/// is absolutely irreducible, false otherwise
+bool
+absIrredTest (const CanonicalForm& F ///< [in] a bivariate polynomial
+                                     ///< irreducible over ground field
+             );
+
+/// modular absolute irreducibility test as described in "Modular Las Vegas
+/// Algorithms for Polynomial Absolute Factorization" by C. Bertone, G. Cheze,
+/// A. Galligo
+///
+/// @return true if F is absolutely irreducible, false otherwise
+bool
+modularIrredTest (const CanonicalForm& F ///< [in] a bivariate polynomial
+                                         ///< irreducible over Z
+                 );
+
+/// modular absolute irreducibility test with shift as described in "Modular Las
+/// Vegas Algorithms for Polynomial Absolute Factorization" by C. Bertone,
+/// G. Cheze, A. Galligo
+///
+/// @return true if F is absolutely irreducible, false otherwise
+bool
+modularIrredTestWithShift (const CanonicalForm& F ///< [in] a bivariate polynomial
+                                                  ///< irreducible over Z
+                          );
+
+/// Algorithm 5 as described in Convex-Dense Bivariate Polynomial Factorization
+/// by Berthomieu, Lecerf
+void convexDense (int** points,  ///< [in, out] a set of points in Z^2, returns
+                                 ///< M (points)+A
+                  int sizePoints,///< [in] size of points
+                  mpz_t*& M,     ///< [in,out] returns an invertible 2x2 matrix
+                  mpz_t*& A      ///< [in,out] returns translation
+                 );
+
+/// compress a bivariate poly
+///
+/// @return @a compress returns a compressed bivariate poly
+/// @sa convexDense, decompress
+CanonicalForm
+compress (const CanonicalForm& F, ///< [in] compressed, i.e. F.level()==2,
+                                  ///< bivariate poly
+          mpz_t*& inverseM,       ///< [in,out] returns the inverse of M,
+                                  ///< if computeMA==true, M otherwise
+          mpz_t*& A,              ///< [in,out] returns translation
+          bool computeMA= true    ///< [in] whether to compute M and A
+         );
+
+/// decompress a bivariate poly
+///
+/// @return @a decompress returns a decompressed bivariate poly
+/// @sa convexDense, decompress
+CanonicalForm
+decompress (const CanonicalForm& F,///< [in] compressed, i.e. F.level()<= 2,
+                                   ///< uni- or bivariate poly
+            const mpz_t* M,       ///< [in] matrix M obtained from compress
+            const mpz_t* A        ///< [in] vector A obtained from compress
+           );
+
+#endif
+
diff --git a/factory/cfSubResGcd.cc b/factory/cfSubResGcd.cc
new file mode 100644
index 0000000..b58d3f5
--- /dev/null
+++ b/factory/cfSubResGcd.cc
@@ -0,0 +1,225 @@
+#include "config.h"
+
+#include "cf_defs.h"
+#include "cf_algorithm.h"
+#include "cfEzgcd.h"
+#include "cfGcdUtil.h"
+#include "templates/ftmpl_functions.h"
+#include "cf_factory.h"
+#include "cfUnivarGcd.h"
+
+CanonicalForm
+subResGCD_p( const CanonicalForm & f, const CanonicalForm & g )
+{
+    if (f.inCoeffDomain() || g.inCoeffDomain()) //zero case should be caught by gcd
+      return 1;
+    CanonicalForm pi, pi1;
+    CanonicalForm C, Ci, Ci1, Hi, bi, pi2;
+    bool bpure, ezgcdon= isOn (SW_USE_EZGCD_P);
+    int delta = degree( f ) - degree( g );
+
+    if ( delta >= 0 )
+    {
+        pi = f; pi1 = g;
+    }
+    else
+    {
+        pi = g; pi1 = f; delta = -delta;
+    }
+    if (pi.isUnivariate())
+      Ci= 1;
+    else
+    {
+      if (!ezgcdon)
+        On (SW_USE_EZGCD_P);
+      Ci = content( pi );
+      if (!ezgcdon)
+        Off (SW_USE_EZGCD_P);
+      pi = pi / Ci;
+    }
+    if (pi1.isUnivariate())
+      Ci1= 1;
+    else
+    {
+      if (!ezgcdon)
+        On (SW_USE_EZGCD_P);
+      Ci1 = content( pi1 );
+      if (!ezgcdon)
+        Off (SW_USE_EZGCD_P);
+      pi1 = pi1 / Ci1;
+    }
+    C = gcd( Ci, Ci1 );
+    int d= 0;
+    if ( !( pi.isUnivariate() && pi1.isUnivariate() ) )
+    {
+        if ( gcd_test_one( pi1, pi, true, d ) )
+        {
+          C=abs(C);
+          //out_cf("GCD:",C,"\n");
+          return C;
+        }
+        bpure = false;
+    }
+    else
+    {
+        bpure = isPurePoly(pi) && isPurePoly(pi1);
+#ifdef HAVE_FLINT
+        if (bpure && (CFFactory::gettype() != GaloisFieldDomain))
+          return gcd_univar_flintp(pi,pi1)*C;
+#else
+#ifdef HAVE_NTL
+        if (bpure && (CFFactory::gettype() != GaloisFieldDomain))
+            return gcd_univar_ntlp(pi, pi1 ) * C;
+#endif
+#endif
+    }
+    Variable v = f.mvar();
+    Hi = power( LC( pi1, v ), delta );
+    int maxNumVars= tmax (getNumVars (pi), getNumVars (pi1));
+
+    if (!(pi.isUnivariate() && pi1.isUnivariate()))
+    {
+      if (size (Hi)*size (pi)/(maxNumVars*3) > 500) //maybe this needs more tuning
+      {
+        On (SW_USE_FF_MOD_GCD);
+        C *= gcd (pi, pi1);
+        Off (SW_USE_FF_MOD_GCD);
+        return C;
+      }
+    }
+
+    if ( (delta+1) % 2 )
+        bi = 1;
+    else
+        bi = -1;
+    CanonicalForm oldPi= pi, oldPi1= pi1, powHi;
+    while ( degree( pi1, v ) > 0 )
+    {
+        if (!(pi.isUnivariate() && pi1.isUnivariate()))
+        {
+          if (size (pi)/maxNumVars > 500 || size (pi1)/maxNumVars > 500)
+          {
+            On (SW_USE_FF_MOD_GCD);
+            C *= gcd (oldPi, oldPi1);
+            Off (SW_USE_FF_MOD_GCD);
+            return C;
+          }
+        }
+        pi2 = psr( pi, pi1, v );
+        pi2 = pi2 / bi;
+        pi = pi1; pi1 = pi2;
+        maxNumVars= tmax (getNumVars (pi), getNumVars (pi1));
+        if (!pi1.isUnivariate() && (size (pi1)/maxNumVars > 500))
+        {
+            On (SW_USE_FF_MOD_GCD);
+            C *= gcd (oldPi, oldPi1);
+            Off (SW_USE_FF_MOD_GCD);
+            return C;
+        }
+        if ( degree( pi1, v ) > 0 )
+        {
+            delta = degree( pi, v ) - degree( pi1, v );
+            powHi= power (Hi, delta-1);
+            if ( (delta+1) % 2 )
+                bi = LC( pi, v ) * powHi*Hi;
+            else
+                bi = -LC( pi, v ) * powHi*Hi;
+            Hi = power( LC( pi1, v ), delta ) / powHi;
+            if (!(pi.isUnivariate() && pi1.isUnivariate()))
+            {
+              if (size (Hi)*size (pi)/(maxNumVars*3) > 1500) //maybe this needs more tuning
+              {
+                On (SW_USE_FF_MOD_GCD);
+                C *= gcd (oldPi, oldPi1);
+                Off (SW_USE_FF_MOD_GCD);
+                return C;
+              }
+            }
+        }
+    }
+    if ( degree( pi1, v ) == 0 )
+    {
+      C=abs(C);
+      //out_cf("GCD:",C,"\n");
+      return C;
+    }
+    if (!pi.isUnivariate())
+    {
+      if (!ezgcdon)
+        On (SW_USE_EZGCD_P);
+      Ci= gcd (LC (oldPi,v), LC (oldPi1,v));
+      pi /= LC (pi,v)/Ci;
+      Ci= content (pi);
+      pi /= Ci;
+      if (!ezgcdon)
+        Off (SW_USE_EZGCD_P);
+    }
+    if ( bpure )
+        pi /= pi.lc();
+    C=abs(C*pi);
+    //out_cf("GCD:",C,"\n");
+    return C;
+}
+
+CanonicalForm
+subResGCD_0( const CanonicalForm & f, const CanonicalForm & g )
+{
+    CanonicalForm pi, pi1;
+    CanonicalForm C, Ci, Ci1, Hi, bi, pi2;
+    int delta = degree( f ) - degree( g );
+
+    if ( delta >= 0 )
+    {
+        pi = f; pi1 = g;
+    }
+    else
+    {
+        pi = g; pi1 = f; delta = -delta;
+    }
+    Ci = content( pi ); Ci1 = content( pi1 );
+    pi1 = pi1 / Ci1; pi = pi / Ci;
+    C = gcd( Ci, Ci1 );
+    int d= 0;
+    if ( pi.isUnivariate() && pi1.isUnivariate() )
+    {
+#ifdef HAVE_FLINT
+        if (isPurePoly(pi) && isPurePoly(pi1) )
+            return gcd_univar_flint0(pi, pi1 ) * C;
+#else
+#ifdef HAVE_NTL
+        if (isPurePoly(pi) && isPurePoly(pi1) )
+            return gcd_univar_ntl0(pi, pi1 ) * C;
+#endif
+#endif
+#ifndef HAVE_NTL
+        return gcd_poly_univar0( pi, pi1, true ) * C;
+#endif
+    }
+    else if ( gcd_test_one( pi1, pi, true, d ) )
+      return C;
+    Variable v = f.mvar();
+    Hi = power( LC( pi1, v ), delta );
+    if ( (delta+1) % 2 )
+        bi = 1;
+    else
+        bi = -1;
+    while ( degree( pi1, v ) > 0 )
+    {
+        pi2 = psr( pi, pi1, v );
+        pi2 = pi2 / bi;
+        pi = pi1; pi1 = pi2;
+        if ( degree( pi1, v ) > 0 )
+        {
+            delta = degree( pi, v ) - degree( pi1, v );
+            if ( (delta+1) % 2 )
+                bi = LC( pi, v ) * power( Hi, delta );
+            else
+                bi = -LC( pi, v ) * power( Hi, delta );
+            Hi = power( LC( pi1, v ), delta ) / power( Hi, delta-1 );
+        }
+    }
+    if ( degree( pi1, v ) == 0 )
+        return C;
+    else
+        return C * pp( pi );
+}
diff --git a/factory/cfSubResGcd.h b/factory/cfSubResGcd.h
new file mode 100644
index 0000000..331f02e
--- /dev/null
+++ b/factory/cfSubResGcd.h
@@ -0,0 +1,19 @@
+/**
+ * @file cfSubResGcd.h
+ *
+ * subresultant pseudo remainder sequence GCD over finite fields and Z
+**/
+#ifndef CF_SUB_RES_GCD_H
+#define CF_SUB_RES_GCD_H
+
+/// subresultant GCD over finite fields.
+/// In case things become too dense we switch to a modular algorithm
+CanonicalForm
+subResGCD_p( const CanonicalForm & f, const CanonicalForm & g );
+
+/// subresultant GCD over Z.
+/// @note in contrast to subResGCD_p we do not switch to a modular algorithm
+///       in case things become too dense
+CanonicalForm
+subResGCD_0( const CanonicalForm & f, const CanonicalForm & g );
+#endif
diff --git a/factory/cfUnivarGcd.cc b/factory/cfUnivarGcd.cc
new file mode 100644
index 0000000..9d87b44
--- /dev/null
+++ b/factory/cfUnivarGcd.cc
@@ -0,0 +1,332 @@
+#include "config.h"
+
+#include "debug.h"
+
+#include "cf_algorithm.h"
+#include "templates/ftmpl_functions.h"
+#include "cf_primes.h"
+#include "cfGcdUtil.h"
+
+#ifdef HAVE_NTL
+#include "NTLconvert.h"
+#endif
+
+#ifdef HAVE_FLINT
+#include "FLINTconvert.h"
+#endif
+
+#ifdef HAVE_NTL
+#ifndef HAVE_FLINT
+CanonicalForm
+gcd_univar_ntl0( const CanonicalForm & F, const CanonicalForm & G )
+{
+    ZZX F1=convertFacCF2NTLZZX(F);
+    ZZX G1=convertFacCF2NTLZZX(G);
+    ZZX R=GCD(F1,G1);
+    return convertNTLZZX2CF(R,F.mvar());
+}
+
+CanonicalForm
+gcd_univar_ntlp( const CanonicalForm & F, const CanonicalForm & G )
+{
+  if (fac_NTL_char!=getCharacteristic())
+  {
+    fac_NTL_char=getCharacteristic();
+    zz_p::init(getCharacteristic());
+  }
+  zz_pX F1=convertFacCF2NTLzzpX(F);
+  zz_pX G1=convertFacCF2NTLzzpX(G);
+  zz_pX R=GCD(F1,G1);
+  return  convertNTLzzpX2CF(R,F.mvar());
+}
+#endif
+#endif
+
+#ifdef HAVE_FLINT
+CanonicalForm
+gcd_univar_flintp (const CanonicalForm& F, const CanonicalForm& G)
+{
+  nmod_poly_t F1, G1;
+  convertFacCF2nmod_poly_t (F1, F);
+  convertFacCF2nmod_poly_t (G1, G);
+  nmod_poly_gcd (F1, F1, G1);
+  CanonicalForm result= convertnmod_poly_t2FacCF (F1, F.mvar());
+  nmod_poly_clear (F1);
+  nmod_poly_clear (G1);
+  return result;
+}
+
+CanonicalForm
+gcd_univar_flint0( const CanonicalForm & F, const CanonicalForm & G )
+{
+  fmpz_poly_t F1, G1;
+  convertFacCF2Fmpz_poly_t(F1, F);
+  convertFacCF2Fmpz_poly_t(G1, G);
+  fmpz_poly_gcd (F1, F1, G1);
+  CanonicalForm result= convertFmpz_poly_t2FacCF (F1, F.mvar());
+  fmpz_poly_clear (F1);
+  fmpz_poly_clear (G1);
+  return result;
+}
+#endif
+
+#ifndef HAVE_NTL
+CanonicalForm gcd_poly_univar0( const CanonicalForm & F, const CanonicalForm & G, bool primitive )
+{
+  CanonicalForm f, g, c, cg, cl, BB, B, M, q, Dp, newD, D, newq;
+  int p, i;
+
+  if ( primitive )
+  {
+    f = F;
+    g = G;
+    c = 1;
+  }
+  else
+  {
+    CanonicalForm cF = content( F ), cG = content( G );
+    f = F / cF;
+    g = G / cG;
+    c = bgcd( cF, cG );
+  }
+  cg = gcd( f.lc(), g.lc() );
+  cl = ( f.lc() / cg ) * g.lc();
+//     B = 2 * cg * tmin(
+//         maxnorm(f)*power(CanonicalForm(2),f.degree())*isqrt(f.degree()+1),
+//         maxnorm(g)*power(CanonicalForm(2),g.degree())*isqrt(g.degree()+1)
+//         )+1;
+  M = tmin( maxNorm(f), maxNorm(g) );
+  BB = power(CanonicalForm(2),tmin(f.degree(),g.degree()))*M;
+  q = 0;
+  i = cf_getNumSmallPrimes() - 1;
+  while ( true )
+  {
+    B = BB;
+    while ( i >= 0 && q < B )
+    {
+      p = cf_getSmallPrime( i );
+      i--;
+      while ( i >= 0 && mod( cl, p ) == 0 )
+      {
+        p = cf_getSmallPrime( i );
+        i--;
+      }
+      setCharacteristic( p );
+      Dp = gcd( mapinto( f ), mapinto( g ) );
+      Dp = ( Dp / Dp.lc() ) * mapinto( cg );
+      setCharacteristic( 0 );
+      if ( Dp.degree() == 0 )
+        return c;
+      if ( q.isZero() )
+      {
+        D = mapinto( Dp );
+        q = p;
+        B = power(CanonicalForm(2),D.degree())*M+1;
+      }
+      else
+      {
+        if ( Dp.degree() == D.degree() )
+        {
+          chineseRemainder( D, q, mapinto( Dp ), p, newD, newq );
+          q = newq;
+          D = newD;
+        }
+        else if ( Dp.degree() < D.degree() )
+        {
+          // all previous p's are bad primes
+          q = p;
+          D = mapinto( Dp );
+          B = power(CanonicalForm(2),D.degree())*M+1;
+        }
+        // else p is a bad prime
+      }
+    }
+    if ( i >= 0 )
+    {
+      // now balance D mod q
+      D = pp( balance_p( D, q ) );
+      if ( fdivides( D, f ) && fdivides( D, g ) )
+        return D * c;
+      else
+        q = 0;
+    }
+    else
+      return gcd_poly( F, G );
+    DEBOUTLN( cerr, "another try ..." );
+  }
+}
+#endif
+
+/** CanonicalForm extgcd ( const CanonicalForm & f, const CanonicalForm & g, CanonicalForm & a, CanonicalForm & b )
+ *
+ * extgcd() - returns polynomial extended gcd of f and g.
+ *
+ * Returns gcd(f, g) and a and b sucht that f*a+g*b=gcd(f, g).
+ * The gcd is calculated using an extended euclidean polynomial
+ * remainder sequence, so f and g should be polynomials over an
+ * euclidean domain.  Normalizes result.
+ *
+ * Note: be sure that f and g have the same level!
+ *
+**/
+CanonicalForm
+extgcd ( const CanonicalForm & f, const CanonicalForm & g, CanonicalForm & a, CanonicalForm & b )
+{
+  if (f.isZero())
+  {
+    a= 0;
+    b= 1;
+    return g;
+  }
+  else if (g.isZero())
+  {
+    a= 1;
+    b= 0;
+    return f;
+  }
+#ifdef HAVE_NTL
+#ifdef HAVE_FLINT
+  if (( getCharacteristic() > 0 ) && (CFFactory::gettype() != GaloisFieldDomain)
+  &&  (f.level()==g.level()) && isPurePoly(f) && isPurePoly(g))
+  {
+    nmod_poly_t F1, G1, A, B, R;
+    convertFacCF2nmod_poly_t (F1, f);
+    convertFacCF2nmod_poly_t (G1, g);
+    nmod_poly_init (R, getCharacteristic());
+    nmod_poly_init (A, getCharacteristic());
+    nmod_poly_init (B, getCharacteristic());
+    nmod_poly_xgcd (R, A, B, F1, G1);
+    a= convertnmod_poly_t2FacCF (A, f.mvar());
+    b= convertnmod_poly_t2FacCF (B, f.mvar());
+    CanonicalForm r= convertnmod_poly_t2FacCF (R, f.mvar());
+    nmod_poly_clear (F1);
+    nmod_poly_clear (G1);
+    nmod_poly_clear (A);
+    nmod_poly_clear (B);
+    nmod_poly_clear (R);
+    return r;
+  }
+#else
+  if (( getCharacteristic() > 0 ) && (CFFactory::gettype() != GaloisFieldDomain)
+  &&  (f.level()==g.level()) && isPurePoly(f) && isPurePoly(g))
+  {
+    if (fac_NTL_char!=getCharacteristic())
+    {
+      fac_NTL_char=getCharacteristic();
+      zz_p::init(getCharacteristic());
+    }
+    zz_pX F1=convertFacCF2NTLzzpX(f);
+    zz_pX G1=convertFacCF2NTLzzpX(g);
+    zz_pX R;
+    zz_pX A,B;
+    XGCD(R,A,B,F1,G1);
+    a=convertNTLzzpX2CF(A,f.mvar());
+    b=convertNTLzzpX2CF(B,f.mvar());
+    return convertNTLzzpX2CF(R,f.mvar());
+  }
+#endif
+#ifdef HAVE_FLINT
+  if (( getCharacteristic() ==0) && (f.level()==g.level())
+       && isPurePoly(f) && isPurePoly(g))
+  {
+    fmpq_poly_t F1, G1;
+    convertFacCF2Fmpq_poly_t (F1, f);
+    convertFacCF2Fmpq_poly_t (G1, g);
+    fmpq_poly_t R, A, B;
+    fmpq_poly_init (R);
+    fmpq_poly_init (A);
+    fmpq_poly_init (B);
+    fmpq_poly_xgcd (R, A, B, F1, G1);
+    a= convertFmpq_poly_t2FacCF (A, f.mvar());
+    b= convertFmpq_poly_t2FacCF (B, f.mvar());
+    CanonicalForm r= convertFmpq_poly_t2FacCF (R, f.mvar());
+    fmpq_poly_clear (F1);
+    fmpq_poly_clear (G1);
+    fmpq_poly_clear (A);
+    fmpq_poly_clear (B);
+    fmpq_poly_clear (R);
+    return r;
+  }
+#else
+  if (( getCharacteristic() ==0)
+  && (f.level()==g.level()) && isPurePoly(f) && isPurePoly(g))
+  {
+    CanonicalForm fc=bCommonDen(f);
+    CanonicalForm gc=bCommonDen(g);
+    ZZX F1=convertFacCF2NTLZZX(f*fc);
+    ZZX G1=convertFacCF2NTLZZX(g*gc);
+    ZZX R=GCD(F1,G1);
+    CanonicalForm r=convertNTLZZX2CF(R,f.mvar());
+    ZZ RR;
+    ZZX A,B;
+    if (r.inCoeffDomain())
+    {
+      XGCD(RR,A,B,F1,G1,1);
+      CanonicalForm rr=convertZZ2CF(RR);
+      if(!rr.isZero())
+      {
+        a=convertNTLZZX2CF(A,f.mvar())*fc/rr;
+        b=convertNTLZZX2CF(B,f.mvar())*gc/rr;
+        return CanonicalForm(1);
+      }
+      else
+      {
+        F1 /= R;
+        G1 /= R;
+        XGCD (RR, A,B,F1,G1,1);
+        rr=convertZZ2CF(RR);
+        a=convertNTLZZX2CF(A,f.mvar())*(fc/rr);
+        b=convertNTLZZX2CF(B,f.mvar())*(gc/rr);
+      }
+    }
+    else
+    {
+      XGCD(RR,A,B,F1,G1,1);
+      CanonicalForm rr=convertZZ2CF(RR);
+      if (!rr.isZero())
+      {
+        a=convertNTLZZX2CF(A,f.mvar())*fc;
+        b=convertNTLZZX2CF(B,f.mvar())*gc;
+      }
+      else
+      {
+        F1 /= R;
+        G1 /= R;
+        XGCD (RR, A,B,F1,G1,1);
+        rr=convertZZ2CF(RR);
+        a=convertNTLZZX2CF(A,f.mvar())*(fc/rr);
+        b=convertNTLZZX2CF(B,f.mvar())*(gc/rr);
+      }
+      return r;
+    }
+  }
+#endif
+#endif
+  // may contain bug in the co-factors, see track 107
+  CanonicalForm contf = content( f );
+  CanonicalForm contg = content( g );
+
+  CanonicalForm p0 = f / contf, p1 = g / contg;
+  CanonicalForm f0 = 1, f1 = 0, g0 = 0, g1 = 1, q, r;
+
+  while ( ! p1.isZero() )
+  {
+      divrem( p0, p1, q, r );
+      p0 = p1; p1 = r;
+      r = g0 - g1 * q;
+      g0 = g1; g1 = r;
+      r = f0 - f1 * q;
+      f0 = f1; f1 = r;
+  }
+  CanonicalForm contp0 = content( p0 );
+  a = f0 / ( contf * contp0 );
+  b = g0 / ( contg * contp0 );
+  p0 /= contp0;
+  if ( p0.sign() < 0 )
+  {
+      p0 = -p0;
+      a = -a;
+      b = -b;
+  }
+  return p0;
+}
diff --git a/factory/cfUnivarGcd.h b/factory/cfUnivarGcd.h
new file mode 100644
index 0000000..4f3053f
--- /dev/null
+++ b/factory/cfUnivarGcd.h
@@ -0,0 +1,38 @@
+/**
+ * @file cfUnivarGcd.h
+ *
+ * univariate Gcd over finite fields and Z, extended GCD over finite fields
+ * and Q
+ *
+ * @note if NTL or FLINT are available they are used to compute the (ext)Gcd
+**/
+
+#ifndef CF_UNIVAR_GCD_H
+#define CF_UNIVAR_GCD_H
+
+#ifdef HAVE_NTL
+#include <NTL/ZZX.h>
+#include "NTLconvert.h"
+bool isPurePoly(const CanonicalForm & );
+#ifndef HAVE_FLINT
+CanonicalForm gcd_univar_ntl0( const CanonicalForm &, const CanonicalForm & );
+CanonicalForm gcd_univar_ntlp( const CanonicalForm &, const CanonicalForm & );
+#endif
+#endif
+
+#ifdef HAVE_FLINT
+#include "FLINTconvert.h"
+CanonicalForm gcd_univar_flint0 (const CanonicalForm &, const CanonicalForm &);
+CanonicalForm gcd_univar_flintp (const CanonicalForm &, const CanonicalForm &);
+#endif
+
+#ifndef HAVE_NTL
+CanonicalForm gcd_poly_univar0( const CanonicalForm & F, const CanonicalForm & G, bool primitive );
+#endif
+
+/*BEGINPUBLIC*/
+CanonicalForm
+extgcd ( const CanonicalForm & f, const CanonicalForm & g, CanonicalForm & a, CanonicalForm & b );
+/*ENDPUBLIC*/
+
+#endif
diff --git a/factory/cf_algorithm.cc b/factory/cf_algorithm.cc
new file mode 100644
index 0000000..5333244
--- /dev/null
+++ b/factory/cf_algorithm.cc
@@ -0,0 +1,574 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+/**
+ *
+ *
+ * cf_algorithm.cc - simple mathematical algorithms.
+ *
+ * Hierarchy: mathematical algorithms on canonical forms
+ *
+ * Developers note:
+ * ----------------
+ * A "mathematical" algorithm is an algorithm which calculates
+ * some mathematical function in contrast to a "structural"
+ * algorithm which gives structural information on polynomials.
+ *
+ * Compare these functions to the functions in `cf_ops.cc', which
+ * are structural algorithms.
+ *
+**/
+
+
+#include "config.h"
+
+
+#include "cf_assert.h"
+
+#include "cf_factory.h"
+#include "cf_defs.h"
+#include "canonicalform.h"
+#include "cf_algorithm.h"
+#include "variable.h"
+#include "cf_iter.h"
+#include "templates/ftmpl_functions.h"
+#include "cfGcdAlgExt.h"
+
+void out_cf(const char *s1,const CanonicalForm &f,const char *s2);
+
+/** CanonicalForm psr ( const CanonicalForm & f, const CanonicalForm & g, const Variable & x )
+ *
+ *
+ * psr() - return pseudo remainder of `f' and `g' with respect
+ *   to `x'.
+ *
+ * `g' must not equal zero.
+ *
+ * For f and g in R[x], R an arbitrary ring, g != 0, there is a
+ * representation
+ *
+ *   LC(g)^s*f = g*q + r
+ *
+ * with r = 0 or deg(r) < deg(g) and s = 0 if f = 0 or
+ * s = max( 0, deg(f)-deg(g)+1 ) otherwise.
+ * r = psr(f, g) and q = psq(f, g) are called "pseudo remainder"
+ * and "pseudo quotient", resp.  They are uniquely determined if
+ * LC(g) is not a zero divisor in R.
+ *
+ * See H.-J. Reiffen/G. Scheja/U. Vetter - "Algebra", 2nd ed.,
+ * par. 15, for a reference.
+ *
+ * Type info:
+ * ----------
+ * f, g: Current
+ * x: Polynomial
+ *
+ * Polynomials over prime power domains are admissible if
+ * lc(LC(`g',`x')) is not a zero divisor.  This is a slightly
+ * stronger precondition than mathematically necessary since
+ * pseudo remainder and quotient are well-defined if LC(`g',`x')
+ * is not a zero divisor.
+ *
+ * For example, psr(y^2, (13*x+1)*y) is well-defined in
+ * (Z/13^2[x])[y] since (13*x+1) is not a zero divisor.  But
+ * calculating it with Factory would fail since 13 is a zero
+ * divisor in Z/13^2.
+ *
+ * Due to this inconsistency with mathematical notion, we decided
+ * not to declare type `CurrentPP' for `f' and `g'.
+ *
+ * Developers note:
+ * ----------------
+ * This is not an optimal implementation.  Better would have been
+ * an implementation in `InternalPoly' avoiding the
+ * exponentiation of the leading coefficient of `g'.  In contrast
+ * to `psq()' and `psqr()' it definitely seems worth to implement
+ * the pseudo remainder on the internal level.
+ *
+ * @sa psq(), psqr()
+**/
+CanonicalForm
+#if 0
+psr ( const CanonicalForm & f, const CanonicalForm & g, const Variable & x )
+{
+
+    ASSERT( x.level() > 0, "type error: polynomial variable expected" );
+    ASSERT( ! g.isZero(), "math error: division by zero" );
+
+    // swap variables such that x's level is larger or equal
+    // than both f's and g's levels.
+    Variable X = tmax( tmax( f.mvar(), g.mvar() ), x );
+    CanonicalForm F = swapvar( f, x, X );
+    CanonicalForm G = swapvar( g, x, X );
+
+    // now, we have to calculate the pseudo remainder of F and G
+    // w.r.t. X
+    int fDegree = degree( F, X );
+    int gDegree = degree( G, X );
+    if ( (fDegree < 0) || (fDegree < gDegree) )
+        return f;
+    else
+    {
+        CanonicalForm xresult = (power( LC( G, X ), fDegree-gDegree+1 ) * F) ;
+        CanonicalForm result = xresult -(xresult/G)*G;
+        return swapvar( result, x, X );
+    }
+}
+#else
+psr ( const CanonicalForm &rr, const CanonicalForm &vv, const Variable & x )
+{
+  CanonicalForm r=rr, v=vv, l, test, lu, lv, t, retvalue;
+  int dr, dv, d,n=0;
+
+
+  dr = degree( r, x );
+  if (dr>0)
+  {
+    dv = degree( v, x );
+    if (dv <= dr) {l=LC(v,x); v = v -l*power(x,dv);}
+    else { l = 1; }
+    d= dr-dv+1;
+    //out_cf("psr(",rr," ");
+    //out_cf("",vv," ");
+    //printf(" var=%d\n",x.level());
+    while ( ( dv <= dr  ) && ( !r.isZero()) )
+    {
+      test = power(x,dr-dv)*v*LC(r,x);
+      if ( dr == 0 ) { r= CanonicalForm(0); }
+      else { r= r - LC(r,x)*power(x,dr); }
+      r= l*r -test;
+      dr= degree(r,x);
+      n+=1;
+    }
+    r= power(l, d-n)*r;
+  }
+  return r;
+}
+#endif
+
+/** CanonicalForm psq ( const CanonicalForm & f, const CanonicalForm & g, const Variable & x )
+ *
+ *
+ * psq() - return pseudo quotient of `f' and `g' with respect
+ *   to `x'.
+ *
+ * `g' must not equal zero.
+ *
+ * Type info:
+ * ----------
+ * f, g: Current
+ * x: Polynomial
+ *
+ * Developers note:
+ * ----------------
+ * This is not an optimal implementation.  Better would have been
+ * an implementation in `InternalPoly' avoiding the
+ * exponentiation of the leading coefficient of `g'.  It seemed
+ * not worth to do so.
+ *
+ * @sa psr(), psqr()
+ *
+**/
+CanonicalForm
+psq ( const CanonicalForm & f, const CanonicalForm & g, const Variable & x )
+{
+    ASSERT( x.level() > 0, "type error: polynomial variable expected" );
+    ASSERT( ! g.isZero(), "math error: division by zero" );
+
+    // swap variables such that x's level is larger or equal
+    // than both f's and g's levels.
+    Variable X = tmax( tmax( f.mvar(), g.mvar() ), x );
+    CanonicalForm F = swapvar( f, x, X );
+    CanonicalForm G = swapvar( g, x, X );
+
+    // now, we have to calculate the pseudo remainder of F and G
+    // w.r.t. X
+    int fDegree = degree( F, X );
+    int gDegree = degree( G, X );
+    if ( fDegree < 0 || fDegree < gDegree )
+        return 0;
+    else {
+        CanonicalForm result = (power( LC( G, X ), fDegree-gDegree+1 ) * F) / G;
+        return swapvar( result, x, X );
+    }
+}
+
+/** void psqr ( const CanonicalForm & f, const CanonicalForm & g, CanonicalForm & q, CanonicalForm & r, const Variable & x )
+ *
+ *
+ * psqr() - calculate pseudo quotient and remainder of `f' and
+ *   `g' with respect to `x'.
+ *
+ * Returns the pseudo quotient of `f' and `g' in `q', the pseudo
+ * remainder in `r'.  `g' must not equal zero.
+ *
+ * See `psr()' for more detailed information.
+ *
+ * Type info:
+ * ----------
+ * f, g: Current
+ * q, r: Anything
+ * x: Polynomial
+ *
+ * Developers note:
+ * ----------------
+ * This is not an optimal implementation.  Better would have been
+ * an implementation in `InternalPoly' avoiding the
+ * exponentiation of the leading coefficient of `g'.  It seemed
+ * not worth to do so.
+ *
+ * @sa psr(), psq()
+ *
+**/
+void
+psqr ( const CanonicalForm & f, const CanonicalForm & g, CanonicalForm & q, CanonicalForm & r, const Variable& x )
+{
+    ASSERT( x.level() > 0, "type error: polynomial variable expected" );
+    ASSERT( ! g.isZero(), "math error: division by zero" );
+
+    // swap variables such that x's level is larger or equal
+    // than both f's and g's levels.
+    Variable X = tmax( tmax( f.mvar(), g.mvar() ), x );
+    CanonicalForm F = swapvar( f, x, X );
+    CanonicalForm G = swapvar( g, x, X );
+
+    // now, we have to calculate the pseudo remainder of F and G
+    // w.r.t. X
+    int fDegree = degree( F, X );
+    int gDegree = degree( G, X );
+    if ( fDegree < 0 || fDegree < gDegree ) {
+        q = 0; r = f;
+    } else {
+        divrem( power( LC( G, X ), fDegree-gDegree+1 ) * F, G, q, r );
+        q = swapvar( q, x, X );
+        r = swapvar( r, x, X );
+    }
+}
+
+/** static CanonicalForm internalBCommonDen ( const CanonicalForm & f )
+ *
+ *
+ * internalBCommonDen() - recursively calculate multivariate
+ *   common denominator of coefficients of `f'.
+ *
+ * Used by: bCommonDen()
+ *
+ * Type info:
+ * ----------
+ * f: Poly( Q )
+ * Switches: isOff( SW_RATIONAL )
+ *
+**/
+static CanonicalForm
+internalBCommonDen ( const CanonicalForm & f )
+{
+    if ( f.inBaseDomain() )
+        return f.den();
+    else {
+        CanonicalForm result = 1;
+        for ( CFIterator i = f; i.hasTerms(); i++ )
+            result = blcm( result, internalBCommonDen( i.coeff() ) );
+        return result;
+    }
+}
+
+/** CanonicalForm bCommonDen ( const CanonicalForm & f )
+ *
+ *
+ * bCommonDen() - calculate multivariate common denominator of
+ *   coefficients of `f'.
+ *
+ * The common denominator is calculated with respect to all
+ * coefficients of `f' which are in a base domain.  In other
+ * words, common_den( `f' ) * `f' is guaranteed to have integer
+ * coefficients only.  The common denominator of zero is one.
+ *
+ * Returns something non-trivial iff the current domain is Q.
+ *
+ * Type info:
+ * ----------
+ * f: CurrentPP
+ *
+**/
+CanonicalForm
+bCommonDen ( const CanonicalForm & f )
+{
+    if ( getCharacteristic() == 0 && isOn( SW_RATIONAL ) ) {
+        // otherwise `bgcd()' returns one
+        Off( SW_RATIONAL );
+        CanonicalForm result = internalBCommonDen( f );
+        On( SW_RATIONAL );
+        return result;
+    } else
+        return CanonicalForm( 1 );
+}
+
+/** bool fdivides ( const CanonicalForm & f, const CanonicalForm & g )
+ *
+ *
+ * fdivides() - check whether `f' divides `g'.
+ *
+ * Returns true iff `f' divides `g'.  Uses some extra heuristic
+ * to avoid polynomial division.  Without the heuristic, the test
+ * essentialy looks like `divremt(g, f, q, r) && r.isZero()'.
+ *
+ * Type info:
+ * ----------
+ * f, g: Current
+ *
+ * Elements from prime power domains (or polynomials over such
+ * domains) are admissible if `f' (or lc(`f'), resp.) is not a
+ * zero divisor.  This is a slightly stronger precondition than
+ * mathematically necessary since divisibility is a well-defined
+ * notion in arbitrary rings.  Hence, we decided not to declare
+ * the weaker type `CurrentPP'.
+ *
+ * Developers note:
+ * ----------------
+ * One may consider the the test `fdivides( f.LC(), g.LC() )' in
+ * the main `if'-test superfluous since `divremt()' in the
+ * `if'-body repeats the test.  However, `divremt()' does not use
+ * any heuristic to do so.
+ *
+ * It seems not reasonable to call `fdivides()' from `divremt()'
+ * to check divisibility of leading coefficients.  `fdivides()' is
+ * on a relatively high level compared to `divremt()'.
+ *
+**/
+bool
+fdivides ( const CanonicalForm & f, const CanonicalForm & g )
+{
+    // trivial cases
+    if ( g.isZero() )
+        return true;
+    else if ( f.isZero() )
+        return false;
+
+    if ( (f.inCoeffDomain() || g.inCoeffDomain())
+         && ((getCharacteristic() == 0 && isOn( SW_RATIONAL ))
+             || (getCharacteristic() > 0) ))
+    {
+        // if we are in a field all elements not equal to zero are units
+        if ( f.inCoeffDomain() )
+            return true;
+        else
+            // g.inCoeffDomain()
+            return false;
+    }
+
+    // we may assume now that both levels either equal LEVELBASE
+    // or are greater zero
+    int fLevel = f.level();
+    int gLevel = g.level();
+    if ( (gLevel > 0) && (fLevel == gLevel) )
+        // f and g are polynomials in the same main variable
+        if ( degree( f ) <= degree( g )
+             && fdivides( f.tailcoeff(), g.tailcoeff() )
+             && fdivides( f.LC(), g.LC() ) )
+        {
+            CanonicalForm q, r;
+            return divremt( g, f, q, r ) && r.isZero();
+        }
+        else
+            return false;
+    else if ( gLevel < fLevel )
+        // g is a coefficient w.r.t. f
+        return false;
+    else
+    {
+        // either f is a coefficient w.r.t. polynomial g or both
+        // f and g are from a base domain (should be Z or Z/p^n,
+        // then)
+        CanonicalForm q, r;
+        return divremt( g, f, q, r ) && r.isZero();
+    }
+}
+
+/// same as fdivides if true returns quotient quot of g by f otherwise quot == 0
+bool
+fdivides ( const CanonicalForm & f, const CanonicalForm & g, CanonicalForm& quot )
+{
+    quot= 0;
+    // trivial cases
+    if ( g.isZero() )
+        return true;
+    else if ( f.isZero() )
+        return false;
+
+    if ( (f.inCoeffDomain() || g.inCoeffDomain())
+         && ((getCharacteristic() == 0 && isOn( SW_RATIONAL ))
+             || (getCharacteristic() > 0) ))
+    {
+        // if we are in a field all elements not equal to zero are units
+        if ( f.inCoeffDomain() )
+        {
+            quot= g/f;
+            return true;
+        }
+        else
+            // g.inCoeffDomain()
+            return false;
+    }
+
+    // we may assume now that both levels either equal LEVELBASE
+    // or are greater zero
+    int fLevel = f.level();
+    int gLevel = g.level();
+    if ( (gLevel > 0) && (fLevel == gLevel) )
+        // f and g are polynomials in the same main variable
+        if ( degree( f ) <= degree( g )
+             && fdivides( f.tailcoeff(), g.tailcoeff() )
+             && fdivides( f.LC(), g.LC() ) )
+        {
+            CanonicalForm q, r;
+            if (divremt( g, f, q, r ) && r.isZero())
+            {
+              quot= q;
+              return true;
+            }
+            else
+              return false;
+        }
+        else
+            return false;
+    else if ( gLevel < fLevel )
+        // g is a coefficient w.r.t. f
+        return false;
+    else
+    {
+        // either f is a coefficient w.r.t. polynomial g or both
+        // f and g are from a base domain (should be Z or Z/p^n,
+        // then)
+        CanonicalForm q, r;
+        if (divremt( g, f, q, r ) && r.isZero())
+        {
+          quot= q;
+          return true;
+        }
+        else
+          return false;
+    }
+}
+
+/// same as fdivides but handles zero divisors in Z_p[t]/(f)[x1,...,xn] for reducible f
+bool
+tryFdivides ( const CanonicalForm & f, const CanonicalForm & g, const CanonicalForm& M, bool& fail )
+{
+    fail= false;
+    // trivial cases
+    if ( g.isZero() )
+        return true;
+    else if ( f.isZero() )
+        return false;
+
+    if (f.inCoeffDomain() || g.inCoeffDomain())
+    {
+        // if we are in a field all elements not equal to zero are units
+        if ( f.inCoeffDomain() )
+        {
+            CanonicalForm inv;
+            tryInvert (f, M, inv, fail);
+            return !fail;
+        }
+        else
+        {
+            return false;
+        }
+    }
+
+    // we may assume now that both levels either equal LEVELBASE
+    // or are greater zero
+    int fLevel = f.level();
+    int gLevel = g.level();
+    if ( (gLevel > 0) && (fLevel == gLevel) )
+    {
+        if (degree( f ) > degree( g ))
+          return false;
+        bool dividestail= tryFdivides (f.tailcoeff(), g.tailcoeff(), M, fail);
+
+        if (fail || !dividestail)
+          return false;
+        bool dividesLC= tryFdivides (f.LC(),g.LC(), M, fail);
+        if (fail || !dividesLC)
+          return false;
+        CanonicalForm q,r;
+        bool divides= tryDivremt (g, f, q, r, M, fail);
+        if (fail || !divides)
+          return false;
+        return r.isZero();
+    }
+    else if ( gLevel < fLevel )
+    {
+        // g is a coefficient w.r.t. f
+        return false;
+    }
+    else
+    {
+        // either f is a coefficient w.r.t. polynomial g or both
+        // f and g are from a base domain (should be Z or Z/p^n,
+        // then)
+        CanonicalForm q, r;
+        bool divides= tryDivremt (g, f, q, r, M, fail);
+        if (fail || !divides)
+          return false;
+        return r.isZero();
+    }
+}
+
+/** CanonicalForm maxNorm ( const CanonicalForm & f )
+ *
+ *
+ * maxNorm() - return maximum norm of `f'.
+ *
+ * That is, the base coefficient of `f' with the largest absolute
+ * value.
+ *
+ * Valid for arbitrary polynomials over arbitrary domains, but
+ * most useful for multivariate polynomials over Z.
+ *
+ * Type info:
+ * ----------
+ * f: CurrentPP
+ *
+**/
+CanonicalForm
+maxNorm ( const CanonicalForm & f )
+{
+    if ( f.inBaseDomain() )
+        return abs( f );
+    else {
+        CanonicalForm result = 0;
+        for ( CFIterator i = f; i.hasTerms(); i++ ) {
+            CanonicalForm coeffMaxNorm = maxNorm( i.coeff() );
+            if ( coeffMaxNorm > result )
+                result = coeffMaxNorm;
+        }
+        return result;
+    }
+}
+
+/** CanonicalForm euclideanNorm ( const CanonicalForm & f )
+ *
+ *
+ * euclideanNorm() - return Euclidean norm of `f'.
+ *
+ * Returns the largest integer smaller or equal norm(`f') =
+ * sqrt(sum( `f'[i]^2 )).
+ *
+ * Type info:
+ * ----------
+ * f: UVPoly( Z )
+ *
+**/
+CanonicalForm
+euclideanNorm ( const CanonicalForm & f )
+{
+    ASSERT( (f.inBaseDomain() || f.isUnivariate()) && f.LC().inZ(),
+            "type error: univariate poly over Z expected" );
+
+    CanonicalForm result = 0;
+    for ( CFIterator i = f; i.hasTerms(); i++ ) {
+        CanonicalForm coeff = i.coeff();
+        result += coeff*coeff;
+    }
+    return sqrt( result );
+}
diff --git a/factory/cf_algorithm.h b/factory/cf_algorithm.h
new file mode 100644
index 0000000..d2bfd4d
--- /dev/null
+++ b/factory/cf_algorithm.h
@@ -0,0 +1,126 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+/**
+ * @file cf_algorithm.h
+ * declarations of higher level algorithms.
+ *
+ * Header file corresponds to: cf_algorithm.cc, cf_chinese.cc,
+ *   cf_factor.cc, cf_linsys.cc, cf_resultant.cc
+ *
+ * Hierarchy: mathematical algorithms on canonical forms
+ *
+ * Developers note:
+ * ----------------
+ * This header file collects declarations of most of the
+ * functions in Factory which implement higher level algorithms
+ * on canonical forms (factorization, gcd, etc.) and declarations
+ * of some low level mathematical functions, too (absolute value,
+ * euclidean norm, etc.).
+ *
+**/
+
+#ifndef INCL_CF_ALGORITHM_H
+#define INCL_CF_ALGORITHM_H
+
+// #include "config.h"
+
+#include "canonicalform.h"
+#include "variable.h"
+
+/*BEGINPUBLIC*/
+
+//{{{ function declarations from cf_algorithm.cc
+CanonicalForm psr ( const CanonicalForm & f, const CanonicalForm & g, const Variable & x );
+
+CanonicalForm psq ( const CanonicalForm & f, const CanonicalForm & g, const Variable & x );
+
+void psqr ( const CanonicalForm & f, const CanonicalForm & g, CanonicalForm & q, CanonicalForm & r, const Variable & x );
+
+CanonicalForm bCommonDen ( const CanonicalForm & f );
+
+bool fdivides ( const CanonicalForm & f, const CanonicalForm & g );
+
+bool fdivides ( const CanonicalForm & f, const CanonicalForm & g, CanonicalForm& quot );
+
+bool tryFdivides ( const CanonicalForm & f, const CanonicalForm & g, const CanonicalForm& M, bool& fail );
+
+CanonicalForm maxNorm ( const CanonicalForm & f );
+
+CanonicalForm euclideanNorm ( const CanonicalForm & f );
+//}}}
+
+//{{{ function declarations from cf_chinese.cc
+void chineseRemainder ( const CanonicalForm & x1, const CanonicalForm & q1, const CanonicalForm & x2, const CanonicalForm & q2, CanonicalForm & xnew, CanonicalForm & qnew );
+
+void chineseRemainder ( const CFArray & x, const CFArray & q, CanonicalForm & xnew, CanonicalForm & qnew );
+
+CanonicalForm Farey ( const CanonicalForm & f, const CanonicalForm & q );
+//}}}
+
+//{{{ function declarations from cf_factor.cc
+extern int singular_homog_flag;
+
+bool isPurePoly(const CanonicalForm & f);
+
+bool isPurePoly_m(const CanonicalForm & f);
+
+CFFList factorize ( const CanonicalForm & f, bool issqrfree = false );
+
+CFFList factorize ( const CanonicalForm & f, const Variable & alpha );
+
+CFFList sqrFree ( const CanonicalForm & f, bool sort= false );
+
+CanonicalForm homogenize( const CanonicalForm & f, const Variable & x);
+CanonicalForm homogenize( const CanonicalForm & f, const Variable & x,
+                                const Variable & v1, const Variable & v2);
+Variable get_max_degree_Variable(const CanonicalForm & f);
+CFList get_Terms( const CanonicalForm & f );
+void getTerms( const CanonicalForm & f, const CanonicalForm & t, CFList & result );
+
+
+//}}}
+
+//{{{ function declarations from cf_linsys.cc
+bool linearSystemSolve ( CFMatrix & M );
+
+CanonicalForm determinant ( const CFMatrix & M, int n );
+//}}}
+
+//{{{ function declarations from cf_resultant.cc
+CFArray subResChain ( const CanonicalForm & f, const CanonicalForm & g, const Variable & x );
+
+CanonicalForm resultant ( const CanonicalForm & f, const CanonicalForm & g, const Variable & x );
+//}}}
+
+/** inline CanonicalForm abs ( const CanonicalForm & f )
+ *
+ * abs() - return absolute value of `f'.
+ *
+ * The absolute value is defined in terms of the function
+ * `sign()'.  If it reports negative sign for `f' than -`f' is
+ * returned, otherwise `f'.
+ *
+ * This behaviour is most useful for integers and rationals.  But
+ * it may be used to sign-normalize the leading coefficient of
+ * arbitrary polynomials, too.
+ *
+ * Type info:
+ * ----------
+ * f: CurrentPP
+ *
+**/
+inline CanonicalForm
+abs ( const CanonicalForm & f )
+{
+    // it is not only more general to use `sign()' instead of a
+    // direct comparison `f < 0', it is faster, too
+    if ( sign( f ) < 0 )
+        return -f;
+    else
+        return f;
+}
+//}}}
+
+/*ENDPUBLIC*/
+
+#endif /* ! INCL_CF_ALGORITHM_H */
diff --git a/factory/cf_assert.h b/factory/cf_assert.h
new file mode 100644
index 0000000..3287000
--- /dev/null
+++ b/factory/cf_assert.h
@@ -0,0 +1,139 @@
+/* emacs edit mode for this file is -*- C -*- */
+
+/**
+ * @file cf_assert.h
+ *
+ * assertions for Factory
+ *
+ * @note needs --enable-assertions at configure
+**/
+
+/* This is for compatibility with standard cf_assert.h */
+#if defined (SING_NDEBUG) && ! defined (NOASSERT)
+#define NOASSERT
+#endif
+
+/* It should be possible to include this file multiple times for different */
+/* settings of NOASSERT */
+
+/* {{{ undefines */
+#undef __ASSERT
+#undef __ASSERT1
+#undef STICKYASSERT
+#undef STICKYASSERT1
+#undef ASSERT
+#undef ASSERT1
+
+#undef __WARN
+#undef STICKYWARN
+#undef WARN
+
+#undef PVIRT_VOID
+#undef PVIRT_INTCF
+#undef PVIRT_BOOL
+#undef PVIRT_INT
+#undef PVIRT_CHARCC
+/* }}} */
+
+#ifdef __cplusplus
+#ifndef NOSTREAMIO
+#ifdef HAVE_CSTDIO
+#include <cstdio>
+#include <cstdlib>
+#else
+extern "C" {
+#include <stdio.h>
+#include <stdlib.h>
+}
+#endif
+#else
+#include <stdio.h>
+#include <stdlib.h>
+#endif
+#endif
+
+/* {{{ permanent macro definitions */
+#ifndef __GNUC__
+#define __ASSERT(expression, message, file, line) \
+(fprintf( stderr, "error: " message "\n%s:%u: failed assertion `%s'\n", \
+ file, line, expression ), abort(), 0 )
+#define __ASSERT1(expression, message, parameter1, file, line)  \
+(fprintf( stderr, "error: " message "\n%s:%u: failed assertion `%s'\n", \
+ parameter1, file, line, expression ), abort(), 0 )
+
+#define STICKYASSERT(expression, message) \
+((void)((expression) ? 0 : __ASSERT(#expression, message, __FILE__, __LINE__)))
+#define STICKYASSERT1(expression, message, parameter1) \
+((void)((expression) ? 0 : __ASSERT1(#expression, message, parameter1, __FILE__, __LINE__)))
+
+#define __WARN(expression, message, file, line)  \
+(fprintf( stderr, "warning: " message "\n%s:%u: failed assertion `%s'\n", \
+ file, line, expression ), 0 )
+#define STICKYWARN(expression, message) \
+((void)((expression) ? 0 : __WARN(#expression, message, __FILE__, __LINE__)))
+#else /* __GNUCC__ */
+/* use preprocessor macro __PRETTY_FUNCTION__ for more informative output */
+#define __ASSERT(expression, message, file, line, function) \
+(fprintf( stderr, "error: " message "\n%s:%u: In function `%s':\nfailed assertion `%s'\n", \
+ file, line, function, expression ), abort(), 0 )
+#define __ASSERT1(expression, message, parameter1, file, line, function)  \
+(fprintf( stderr, "error: " message "\n%s:%u: In function `%s':\nfailed assertion `%s'\n", \
+ parameter1, file, line, function, expression ), abort(), 0 )
+
+#define STICKYASSERT(expression, message) \
+((void)((expression) ? 0 : __ASSERT(#expression, message, __FILE__, __LINE__, __PRETTY_FUNCTION__)))
+#define STICKYASSERT1(expression, message, parameter1) \
+((void)((expression) ? 0 : __ASSERT1(#expression, message, parameter1, __FILE__, __LINE__, __PRETTY_FUNCTION__)))
+
+#define __WARN(expression, message, file, line, function)  \
+(fprintf( stderr, "warning: " message "\n%s:%u: In function `%s':\nfailed assertion `%s'\n", \
+ file, line, function, expression ), 0 )
+#define STICKYWARN(expression, message) \
+((void)((expression) ? 0 : __WARN(#expression, message, __FILE__, __LINE__, __PRETTY_FUNCTION__)))
+#endif /* __GNUCC__ */
+/* }}} */
+
+/* {{{ macro definitions dependent on NOASSERT */
+#ifndef NOASSERT
+#ifndef __GNUC__
+#define ASSERT(expression, message) \
+((void)((expression) ? 0 : __ASSERT(#expression, message, __FILE__, __LINE__)))
+#define ASSERT1(expression, message, parameter1) \
+((void)((expression) ? 0 : __ASSERT1(#expression, message, parameter1, __FILE__, __LINE__)))
+
+#define WARN(expression, message) \
+((void)((expression) ? 0 : __WARN(#expression, message, __FILE__, __LINE__)))
+#else /* __GNUCC__ */
+/* use preprocessor macro __PRETTY_FUNCTION__ for more informative output */
+#define ASSERT(expression, message) \
+((void)((expression) ? 0 : __ASSERT(#expression, message, __FILE__, __LINE__, __PRETTY_FUNCTION__)))
+#define ASSERT1(expression, message, parameter1) \
+((void)((expression) ? 0 : __ASSERT1(#expression, message, parameter1, __FILE__, __LINE__, __PRETTY_FUNCTION__)))
+
+#define WARN(expression, message) \
+((void)((expression) ? 0 : __WARN(#expression, message, __FILE__, __LINE__, __PRETTY_FUNCTION__)))
+#endif /* __GNUCC__ */
+
+#define PVIRT_VOID(msg) \
+{ fprintf( stderr, "pure method( " msg " ) called\n" ); abort(); }
+#define PVIRT_INTCF(msg) \
+{ fprintf( stderr, "pure method( " msg " ) called\n" ); abort(); return 0; }
+#define PVIRT_BOOL(msg) \
+{ fprintf( stderr, "pure method( " msg " ) called\n" ); abort(); return false; }
+#define PVIRT_INT(msg) \
+{ fprintf( stderr, "pure method( " msg " ) called\n" ); abort(); return 0; }
+#define PVIRT_CHARCC(msg) \
+{ fprintf( stderr, "pure method( " msg " ) called\n" ); abort(); return 0; }
+#else /* NOASSERT */
+#define ASSERT(expression, message) do {} while (0)
+#define ASSERT1(expression, message, parameter1) do {} while (0)
+
+#define WARN(expression, message) do {} while (0)
+
+#define PVIRT_VOID(msg) = 0
+#define PVIRT_INTCF(msg) = 0
+#define PVIRT_BOOL(msg) = 0
+#define PVIRT_INT(msg) = 0
+#define PVIRT_CHARCC(msg) = 0
+#endif /* NOASSERT */
+/* }}} */
diff --git a/factory/cf_char.cc b/factory/cf_char.cc
new file mode 100644
index 0000000..02d34a8
--- /dev/null
+++ b/factory/cf_char.cc
@@ -0,0 +1,66 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+/**
+ * @file cf_char.cc
+ *
+ * getting and setting the characteristic of a finite field
+**/
+
+#include "config.h"
+
+
+#include "cf_assert.h"
+
+#include "cf_defs.h"
+#include "canonicalform.h"
+#include "imm.h"
+#include "cf_primes.h"
+#include "cf_util.h"
+
+static int theCharacteristic = 0;
+static int theDegree = 1;
+
+void setCharacteristic( int c )
+{
+    if ( c == 0 )
+    {
+        theDegree = 0;
+        CFFactory::settype( IntegerDomain );
+        theCharacteristic = 0;
+    }
+    else
+    {
+        theDegree = 1;
+        CFFactory::settype( FiniteFieldDomain );
+        theCharacteristic = c;
+        ff_big = c > cf_getSmallPrime( cf_getNumSmallPrimes()-1 );
+        if (c > 536870909) factoryError("characteristic is too large(max is 2^29)");
+        ff_setprime( c );
+    }
+}
+
+void setCharacteristic( int c, int n, char name )
+{
+    ASSERT( c != 0 && n > 1, "illegal GF(q)" );
+    setCharacteristic( c );
+    gf_setcharacteristic( c, n, name );
+    theDegree = n;
+    CFFactory::settype( GaloisFieldDomain );
+}
+
+int getCharacteristic()
+{
+    return theCharacteristic;
+}
+
+int getGFDegree()
+{
+    //ASSERT( theDegree > 0, "not in GF(q)" );
+    return theDegree;
+}
+
+CanonicalForm getGFGenerator()
+{
+    ASSERT( theDegree > 1, "not in GF(q)" );
+    return int2imm_gf( 1 );
+}
diff --git a/factory/cf_chinese.cc b/factory/cf_chinese.cc
new file mode 100644
index 0000000..ad89e16
--- /dev/null
+++ b/factory/cf_chinese.cc
@@ -0,0 +1,249 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+/**
+ * @file cf_chinese.cc
+ *
+ * algorithms for chinese remaindering and rational reconstruction
+ *
+ * Used by: cf_gcd.cc, cf_linsys.cc
+ *
+ * Header file: cf_algorithm.h
+ *
+**/
+
+
+#include "config.h"
+
+
+#ifdef HAVE_NTL
+#include "NTLconvert.h"
+#endif
+
+#include "cf_assert.h"
+#include "debug.h"
+
+#include "canonicalform.h"
+#include "cf_iter.h"
+
+
+/** void chineseRemainder ( const CanonicalForm & x1, const CanonicalForm & q1, const CanonicalForm & x2, const CanonicalForm & q2, CanonicalForm & xnew, CanonicalForm & qnew )
+ *
+ * chineseRemainder - integer chinese remaindering.
+ *
+ * Calculate xnew such that xnew=x1 (mod q1) and xnew=x2 (mod q2)
+ * and qnew = q1*q2.  q1 and q2 should be positive integers,
+ * pairwise prime, x1 and x2 should be polynomials with integer
+ * coefficients.  If x1 and x2 are polynomials with positive
+ * coefficients, the result is guaranteed to have positive
+ * coefficients, too.
+ *
+ * Note: This algorithm is optimized for the case q1>>q2.
+ *
+ * This is a standard algorithm.  See, for example,
+ * Geddes/Czapor/Labahn - 'Algorithms for Computer Algebra',
+ * par. 5.6 and 5.8, or the article of M. Lauer - 'Computing by
+ * Homomorphic Images' in B. Buchberger - 'Computer Algebra -
+ * Symbolic and Algebraic Computation'.
+ *
+ * Note: Be sure you are calculating in Z, and not in Q!
+ *
+**/
+void
+chineseRemainder ( const CanonicalForm & x1, const CanonicalForm & q1, const CanonicalForm & x2, const CanonicalForm & q2, CanonicalForm & xnew, CanonicalForm & qnew )
+{
+    DEBINCLEVEL( cerr, "chineseRemainder" );
+
+    DEBOUTLN( cerr, "log(q1) = " << q1.ilog2() );
+    DEBOUTLN( cerr, "log(q2) = " << q2.ilog2() );
+
+    // We calculate xnew as follows:
+    //     xnew = v1 + v2 * q1
+    // where
+    //     v1 = x1 (mod q1)
+    //     v2 = (x2-v1)/q1 (mod q2)  (*)
+    //
+    // We do one extra test to check whether x2-v1 vanishes (mod
+    // q2) in (*) since it is not costly and may save us
+    // from calculating the inverse of q1 (mod q2).
+    //
+    // u: v1 (mod q2)
+    // d: x2-v1 (mod q2)
+    // s: 1/q1 (mod q2)
+    //
+    CanonicalForm v2, v1;
+    CanonicalForm u, d, s, dummy;
+
+    v1 = mod( x1, q1 );
+    u = mod( v1, q2 );
+    d = mod( x2-u, q2 );
+    if ( d.isZero() )
+    {
+        xnew = v1;
+        qnew = q1 * q2;
+        DEBDECLEVEL( cerr, "chineseRemainder" );
+        return;
+    }
+    (void)bextgcd( q1, q2, s, dummy );
+    v2 = mod( d*s, q2 );
+    xnew = v1 + v2*q1;
+
+    // After all, calculate new modulus.  It is important that
+    // this is done at the very end of the algorithm, since q1
+    // and qnew may refer to the same object (same is true for x1
+    // and xnew).
+    qnew = q1 * q2;
+
+    DEBDECLEVEL( cerr, "chineseRemainder" );
+}
+//}}}
+
+/** void chineseRemainder ( const CFArray & x, const CFArray & q, CanonicalForm & xnew, CanonicalForm & qnew )
+ *
+ * chineseRemainder - integer chinese remaindering.
+ *
+ * Calculate xnew such that xnew=x[i] (mod q[i]) and qnew is the
+ * product of all q[i].  q[i] should be positive integers,
+ * pairwise prime.  x[i] should be polynomials with integer
+ * coefficients.  If all coefficients of all x[i] are positive
+ * integers, the result is guaranteed to have positive
+ * coefficients, too.
+ *
+ * This is a standard algorithm, too, except for the fact that we
+ * use a divide-and-conquer method instead of a linear approach
+ * to calculate the remainder.
+ *
+ * Note: Be sure you are calculating in Z, and not in Q!
+ *
+**/
+void
+chineseRemainder ( const CFArray & x, const CFArray & q, CanonicalForm & xnew, CanonicalForm & qnew )
+{
+    DEBINCLEVEL( cerr, "chineseRemainder( ... CFArray ... )" );
+
+    ASSERT( x.min() == q.min() && x.size() == q.size(), "incompatible arrays" );
+    CFArray X(x), Q(q);
+    int i, j, n = x.size(), start = x.min();
+
+    DEBOUTLN( cerr, "array size = " << n );
+
+    while ( n != 1 )
+    {
+        i = j = start;
+        while ( i < start + n - 1 )
+        {
+            // This is a little bit dangerous: X[i] and X[j] (and
+            // Q[i] and Q[j]) may refer to the same object.  But
+            // xnew and qnew in the above function are modified
+            // at the very end of the function, so we do not
+            // modify x1 and q1, resp., by accident.
+            chineseRemainder( X[i], Q[i], X[i+1], Q[i+1], X[j], Q[j] );
+            i += 2;
+            j++;
+        }
+
+        if ( n & 1 )
+        {
+            X[j] = X[i];
+            Q[j] = Q[i];
+        }
+        // Maybe we would get some memory back at this point if
+        // we would set X[j+1, ..., n] and Q[j+1, ..., n] to zero
+        // at this point?
+
+        n = ( n + 1) / 2;
+    }
+    xnew = X[start];
+    qnew = Q[q.min()];
+
+    DEBDECLEVEL( cerr, "chineseRemainder( ... CFArray ... )" );
+}
+
+#ifndef HAVE_NTL
+CanonicalForm Farey_n (CanonicalForm N, const CanonicalForm P)
+//"USAGE:  Farey_n (N,P); P, N number;
+//RETURN:  a rational number a/b such that a/b=N mod P
+//         and |a|,|b|<(P/2)^{1/2}
+{
+   //assume(P>0);
+   // assume !isOn(SW_RATIONAL): mod is a no-op otherwise
+   if (N<0) N +=P;
+   CanonicalForm A,B,C,D,E;
+   E=P;
+   B=1;
+   while (!N.isZero())
+   {
+        if (2*N*N<P)
+        {
+           On(SW_RATIONAL);
+           N /=B;
+           Off(SW_RATIONAL);
+           return(N);
+        }
+        D=mod(E , N);
+        C=A-(E-mod(E , N))/N*B;
+        E=N;
+        N=D;
+        A=B;
+        B=C;
+   }
+   return(0);
+}
+#endif
+
+/**
+ * Farey rational reconstruction. If NTL is available it uses the fast algorithm
+ * from NTL, i.e. Encarnacion, Collins.
+**/
+CanonicalForm Farey ( const CanonicalForm & f, const CanonicalForm & q )
+{
+    int is_rat=isOn(SW_RATIONAL);
+    Off(SW_RATIONAL);
+    Variable x = f.mvar();
+    CanonicalForm result = 0;
+    CanonicalForm c;
+    CFIterator i;
+#ifdef HAVE_NTL
+    ZZ NTLq= convertFacCF2NTLZZ (q);
+    ZZ bound;
+    SqrRoot (bound, NTLq/2);
+#endif
+    for ( i = f; i.hasTerms(); i++ )
+    {
+        c = i.coeff();
+        if ( c.inCoeffDomain())
+        {
+#ifdef HAVE_NTL
+          if (c.inZ())
+          {
+            ZZ NTLc= convertFacCF2NTLZZ (c);
+            bool lessZero= (sign (NTLc) == -1);
+            if (lessZero)
+              NTL::negate (NTLc, NTLc);
+            ZZ NTLnum, NTLden;
+            if (ReconstructRational (NTLnum, NTLden, NTLc, NTLq, bound, bound))
+            {
+              if (lessZero)
+                NTL::negate (NTLnum, NTLnum);
+              CanonicalForm num= convertNTLZZX2CF (to_ZZX (NTLnum), Variable (1));
+              CanonicalForm den= convertNTLZZX2CF (to_ZZX (NTLden), Variable (1));
+              On (SW_RATIONAL);
+              result += power (x, i.exp())*(num/den);
+              Off (SW_RATIONAL);
+            }
+          }
+          else
+            result += power( x, i.exp() ) * Farey(c,q);
+#else
+          if (c.inZ())
+            result += power( x, i.exp() ) * Farey_n(c,q);
+          else
+            result += power( x, i.exp() ) * Farey(c,q);
+#endif
+        }
+        else
+          result += power( x, i.exp() ) * Farey(c,q);
+    }
+    if (is_rat) On(SW_RATIONAL);
+    return result;
+}
+
diff --git a/factory/cf_cyclo.cc b/factory/cf_cyclo.cc
new file mode 100644
index 0000000..97ceca1
--- /dev/null
+++ b/factory/cf_cyclo.cc
@@ -0,0 +1,148 @@
+// -*- c++ -*-
+//*****************************************************************************
+/** @file cf_cyclo.cc
+ *
+ * Compute cyclotomic polynomials and factorize integers by brute force
+ *
+ * @par Copyright:
+ *   (c) by The SINGULAR Team, see LICENSE file
+ *
+ * @author Martin Lee
+ * @date 29.01.2010
+**/
+//*****************************************************************************
+
+
+#include "config.h"
+
+
+#include "canonicalform.h"
+#include "cf_primes.h"
+#include "cf_util.h"
+#include "cf_assert.h"
+
+#ifdef HAVE_NTL
+#include <NTL/ZZ.h>
+#endif
+
+int* integerFactorizer (const long integer, int& length, bool& fail)
+{
+  ASSERT (integer != 0 && integer != 1 && integer != -1,
+          "non-zero non-unit expected");
+  int* result=NULL;
+  length= 0;
+  fail= false;
+  int i= integer;
+  if (integer < 0)
+    i = -integer;
+
+  int exp= 0;
+  while ((i != 1) && (i%2 == 0))
+  {
+    i /= 2;
+    exp++;
+  }
+  if (exp != 0)
+  {
+    result= new int [exp];
+    for (int k= 0; k < exp; k++)
+      result[k]= 2;
+    length += exp;
+  }
+  if (i == 1) return result;
+
+  long j= 0;
+  exp= 0;
+  int* buf;
+  int next_prime;
+  while ((i != 1) && (j < 31937))
+  {
+    next_prime= cf_getPrime (j);
+    while ((i != 1) && (i%next_prime == 0))
+    {
+      i /= next_prime;
+      exp++;
+    }
+    if (exp != 0)
+    {
+      buf= result;
+      result= new int [length + exp];
+      for (int k= 0; k < length; k++)
+        result [k]= buf[k];
+      for (int k= 0; k < exp; k++)
+        result [k + length]= next_prime;
+      length += exp;
+    }
+    exp= 0;
+    j++;
+  }
+  if (j >= 31397)
+    fail= true;
+  ASSERT (j < 31397, "integer factorizer ran out of primes"); //sic
+  return result;
+}
+
+/// make prime factorization distinct
+static inline
+int* makeDistinct (int* factors, const int factors_length, int& length)
+{
+  length= 1;
+  int* result= new int [length];
+  int* buf;
+  result[0]= factors [0];
+  for (int i= 1; i < factors_length; i++)
+  {
+    if (factors[i - 1] != factors[i])
+    {
+      buf= result;
+      result= new int [length + 1];
+      for (int j= 0; j < length; j++)
+        result[j]= buf [j];
+      result[length]= factors[i];
+      length++;
+    }
+  }
+  return result;
+}
+
+CanonicalForm cyclotomicPoly (int n, bool& fail)
+{
+  fail= false;
+  Variable x= Variable (1);
+  CanonicalForm result= x - 1;
+  if (n == 1)
+    return result;
+  int* prime_factors;
+  int prime_factors_length;
+  int distinct_factors_length;
+  prime_factors= integerFactorizer (n, prime_factors_length, fail);
+  int* distinct_factors= makeDistinct (prime_factors, prime_factors_length,
+                                        distinct_factors_length);
+  if (fail)
+    return 1;
+  CanonicalForm buf;
+  int prod= 1;
+  for (int i= 0; i < distinct_factors_length; i++)
+  {
+    result= leftShift (result, distinct_factors[i])/result;
+    prod *= distinct_factors[i];
+  }
+  return leftShift (result, n/prod);
+}
+
+#ifdef HAVE_NTL
+bool isPrimitive (const Variable& alpha, bool& fail)
+{
+  int p= getCharacteristic();
+  CanonicalForm mipo= getMipo (alpha);
+  int order= ipower(p, degree(mipo)) - 1;
+  CanonicalForm cyclo= cyclotomicPoly (order, fail);
+  if (fail)
+    return false;
+  if (mod(cyclo, mipo (Variable(1), alpha)) == 0)
+    return true;
+  else
+    return false;
+}
+
+#endif
diff --git a/factory/cf_cyclo.h b/factory/cf_cyclo.h
new file mode 100644
index 0000000..e922a98
--- /dev/null
+++ b/factory/cf_cyclo.h
@@ -0,0 +1,41 @@
+// -*- c++ -*-
+//*****************************************************************************
+/** @file cf_cyclo.h
+ *
+ * Compute cyclotomic polynomials and factorize integers by brute force
+ *
+ * @par Copyright:
+ *   (c) by The SINGULAR Team, see LICENSE file
+ *
+ * @author Martin Lee
+**/
+//*****************************************************************************
+
+#ifndef CF_CYCLO_H
+#define CF_CYCLO_H
+
+// #include "config.h"
+
+/// integer factorization using table look-ups,
+/// function may fail if integer contains primes which exceed the largest prime
+/// in our table
+int* integerFactorizer (const long integer, ///< [in] some integer
+                        int& length,        ///< [in,out] number of factors
+                        bool& fail          ///< [in,out] failure?
+                       );
+
+/// compute the n-th cyclotomic polynomial,
+/// function may fail if integer_factorizer fails to factorize n
+CanonicalForm
+cyclotomicPoly (int n,     ///< [in] some integer
+                bool& fail ///< [in,out] failure?
+               );
+
+/// checks if alpha is a primitive element, alpha is assumed to be an algebraic
+/// variable over some finite prime field
+bool isPrimitive (const Variable& alpha, ///< [in] some algebraic variable
+                  bool& fail             ///< [in,out] failure?
+                 );
+
+#endif
+
diff --git a/factory/cf_defs.h b/factory/cf_defs.h
new file mode 100644
index 0000000..9c97203
--- /dev/null
+++ b/factory/cf_defs.h
@@ -0,0 +1,46 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+/**
+ * @file cf_defs.h
+ *
+ * factory switches.
+**/
+
+#ifndef INCL_CF_DEFS_H
+#define INCL_CF_DEFS_H
+
+// #include "config.h"
+
+/*BEGINPUBLIC*/
+
+#define LEVELBASE -1000000
+#define LEVELTRANS -500000
+#define LEVELQUOT 1000000
+#define LEVELEXPR 1000001
+
+#define UndefinedDomain 32000
+#define GaloisFieldDomain 4
+#define FiniteFieldDomain 3
+#define RationalDomain 2
+#define IntegerDomain 1
+
+/// set to 1 for computations over Q
+static const int SW_RATIONAL = 0;
+/// set to 1 for symmetric representation over F_q
+static const int SW_SYMMETRIC_FF = 1;
+/// set to 1 to use EZGCD over Z
+static const int SW_USE_EZGCD = 2;
+/// set to 1 to use EZGCD over F_q
+static const int SW_USE_EZGCD_P = 3;
+/// set to 1 to sort factors in a factorization
+static const int SW_USE_NTL_SORT=4;
+/// set to 1 to use modular gcd over Z
+static const int SW_USE_CHINREM_GCD=5;
+/// set to 1 to use Encarnacion GCD over Q(a)
+static const int SW_USE_QGCD=6;
+/// set to 1 to use modular GCD over F_q
+static const int SW_USE_FF_MOD_GCD=7;
+
+/*ENDPUBLIC*/
+
+#endif /* ! INCL_CF_DEFS_H */
diff --git a/factory/cf_eval.cc b/factory/cf_eval.cc
new file mode 100644
index 0000000..ccaa3e8
--- /dev/null
+++ b/factory/cf_eval.cc
@@ -0,0 +1,82 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+
+#include "config.h"
+
+
+#include "cf_assert.h"
+
+#include "cf_defs.h"
+#include "cf_eval.h"
+
+static CanonicalForm evalCF ( const CanonicalForm & f, const CFArray & a, int m, int n );
+
+
+Evaluation& Evaluation::operator= ( const Evaluation & e )
+{
+    if ( this != &e ) {
+        values = e.values;
+    }
+    return *this;
+}
+
+CanonicalForm
+Evaluation::operator() ( const CanonicalForm & f ) const
+{
+    if ( f.inCoeffDomain() || f.level() < values.min() )
+        return f;
+    else  if ( f.level() < values.max() )
+        return evalCF( f, values, values.min(), f.level() );
+    else
+        return evalCF( f, values, values.min(), values.max() );
+}
+
+CanonicalForm
+Evaluation::operator() ( const CanonicalForm & f, int i, int j ) const
+{
+    if ( i > j )
+        return f;
+    return evalCF( f, values, i, j );
+}
+
+void
+Evaluation::nextpoint()
+{
+    int n = values.max();
+    for ( int i = values.min(); i <= n; i++ )
+        values[i] += 1;
+}
+
+void
+Evaluation::setValue(int i, const CanonicalForm& f)
+{
+  if (i < values.min() || i > values.max())
+    return;
+  values[i]= f;
+}
+
+#ifndef NOSTREAMIO
+OSTREAM&
+operator<< ( OSTREAM& s, const Evaluation &e )
+{
+    e.values.print(s);
+    return s;
+}
+#endif /* NOSTREAMIO */
+
+CanonicalForm
+evalCF ( const CanonicalForm & f, const CFArray & a, int m, int n )
+{
+    if ( m > n )
+        return f;
+    else {
+        CanonicalForm result = f;
+        while ( n >= m ) {
+            result = result( a[n], Variable( n ) );
+            n--;
+        }
+        return result;
+    }
+//    iterated method turned out to be faster than
+//    return evalCF( f( a[n], Variable( n ) ), a, m, n-1 );
+}
diff --git a/factory/cf_eval.h b/factory/cf_eval.h
new file mode 100644
index 0000000..ece4b5e
--- /dev/null
+++ b/factory/cf_eval.h
@@ -0,0 +1,56 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+/**
+ * @file cf_eval.h
+ *
+ * evaluate polynomials at points
+**/
+
+#ifndef INCL_CF_EVAL_H
+#define INCL_CF_EVAL_H
+
+// #include "config.h"
+
+#ifndef NOSTREAMIO
+#ifdef HAVE_IOSTREAM
+#include <iostream>
+#define OSTREAM std::ostream
+#elif defined(HAVE_IOSTREAM_H)
+#include <iostream.h>
+#define OSTREAM ostream
+#endif
+#endif /* NOSTREAMIO */
+
+#include "canonicalform.h"
+
+/*BEGINPUBLIC*/
+
+/**
+ * class to evaluate a polynomial at points
+**/
+class Evaluation
+{
+protected:
+    CFArray values;
+public:
+    Evaluation() : values() {}
+    Evaluation( int min0, int max0 ) : values( min0, max0 ) {}
+    Evaluation( const Evaluation & e ) : values( e.values ) {}
+    virtual ~Evaluation() {}
+    Evaluation& operator= ( const Evaluation & e );
+    int min() const { return values.min(); }
+    int max() const { return values.max(); }
+    CanonicalForm operator[] ( int i ) const { return values[i]; }
+    CanonicalForm operator[] ( const Variable & v ) const { return operator[](v.level()); }
+    CanonicalForm operator() ( const CanonicalForm& f ) const;
+    CanonicalForm operator() ( const CanonicalForm & f, int i, int j ) const;
+    void setValue (int i, const CanonicalForm& f);
+    virtual void nextpoint();
+#ifndef NOSTREAMIO
+    friend OSTREAM& operator<< ( OSTREAM& s, const Evaluation &e );
+#endif /* NOSTREAMIO */
+};
+
+/*ENDPUBLIC*/
+
+#endif /* ! INCL_CF_EVAL_H */
diff --git a/factory/cf_factor.cc b/factory/cf_factor.cc
new file mode 100644
index 0000000..79275fc
--- /dev/null
+++ b/factory/cf_factor.cc
@@ -0,0 +1,781 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+/**
+ *
+ * @file cf_factor.cc
+ *
+ * Interface to factorization and square free factorization algorithms.
+ *
+ * Used by: cf_irred.cc
+ *
+ * Header file: cf_algorithm.h
+ *
+**/
+
+
+#include "config.h"
+
+
+#include "cf_assert.h"
+
+#include "cf_defs.h"
+#include "canonicalform.h"
+#include "cf_iter.h"
+#include "fac_sqrfree.h"
+#include "cf_algorithm.h"
+#include "facFqFactorize.h"
+#include "facFqSquarefree.h"
+#include "cf_map.h"
+#include "facAlgExt.h"
+#include "facFactorize.h"
+#include "singext.h"
+#include "cf_util.h"
+
+#include "int_int.h"
+#ifdef HAVE_NTL
+#include "NTLconvert.h"
+#endif
+
+#include <factory/cf_gmp.h>
+#ifdef HAVE_FLINT
+#include "FLINTconvert.h"
+#endif
+
+//static bool isUnivariateBaseDomain( const CanonicalForm & f )
+//{
+//    CFIterator i = f;
+//    bool ok = i.coeff().inBaseDomain();
+//    i++;
+//    while ( i.hasTerms() && ( ok = ok && i.coeff().inBaseDomain() ) ) i++;
+//    return ok;
+//}
+
+void find_exp(const CanonicalForm & f, int * exp_f)
+{
+  if ( ! f.inCoeffDomain() )
+  {
+    int e=f.level();
+    CFIterator i = f;
+    if (e>=0)
+    {
+      if (i.exp() > exp_f[e]) exp_f[e]=i.exp();
+    }
+    for (; i.hasTerms(); i++ )
+    {
+      find_exp(i.coeff(), exp_f);
+    }
+  }
+}
+
+int find_mvar(const CanonicalForm & f)
+{
+  int mv=f.level();
+  int *exp_f=new int[mv+1];
+  int i;
+  for(i=mv;i>0;i--) exp_f[i]=0;
+  find_exp(f,exp_f);
+  for(i=mv;i>0;i--)
+  {
+    if ((exp_f[i]>0) && (exp_f[i]<exp_f[mv]))
+    {
+      mv=i;
+    }
+  }
+  delete[] exp_f;
+  return mv;
+}
+
+#if 1
+//#ifndef NOSTREAMIO
+void out_cf(const char *s1,const CanonicalForm &f,const char *s2)
+{
+  printf("%s",s1);
+  if (f.isZero()) printf("+0");
+  //else if (! f.inCoeffDomain() )
+  else if (! f.inBaseDomain() )
+  {
+    int l = f.level();
+    for ( CFIterator i = f; i.hasTerms(); i++ )
+    {
+      int e=i.exp();
+      if (i.coeff().isOne())
+      {
+        printf("+");
+        if (e==0) printf("1");
+        else
+        {
+          printf("v(%d)",l);
+          if (e!=1) printf("^%d",e);
+        }
+      }
+      else
+      {
+        out_cf("+(",i.coeff(),")");
+        if (e!=0)
+        {
+          printf("*v(%d)",l);
+          if (e!=1) printf("^%d",e);
+        }
+      }
+    }
+  }
+  else
+  {
+    if ( f.isImm() )
+    {
+      if (CFFactory::gettype()==GaloisFieldDomain)
+      {
+         long a= imm2int (f.getval());
+         if ( a == gf_q )
+           printf ("+%ld", a);
+         else  if ( a == 0L )
+           printf ("+1");
+         else  if ( a == 1L )
+           printf ("+%c",gf_name);
+         else
+         {
+           printf ("+%c",gf_name);
+           printf ("^%ld",a);
+         }
+      }
+      else
+        printf("+%ld",f.intval());
+    }
+    else
+    {
+    #ifdef NOSTREAMIO
+      if (f.inZ())
+      {
+        mpz_t m;
+        gmp_numerator(f,m);
+        char * str = new char[mpz_sizeinbase( m, 10 ) + 2];
+        str = mpz_get_str( str, 10, m );
+        printf("%s",str);
+        delete[] str;
+        mpz_clear(m);
+      }
+      else if (f.inQ())
+      {
+        mpz_t m;
+        gmp_numerator(f,m);
+        char * str = new char[mpz_sizeinbase( m, 10 ) + 2];
+        str = mpz_get_str( str, 10, m );
+        printf("%s/",str);
+        delete[] str;
+        mpz_clear(m);
+        gmp_denominator(f,m);
+        str = new char[mpz_sizeinbase( m, 10 ) + 2];
+        str = mpz_get_str( str, 10, m );
+        printf("%s",str);
+        delete[] str;
+        mpz_clear(m);
+      }
+    #else
+       std::cout << f;
+    #endif
+    }
+    //if (f.inZ()) printf("(Z)");
+    //else if (f.inQ()) printf("(Q)");
+    //else if (f.inFF()) printf("(FF)");
+    //else if (f.inPP()) printf("(PP)");
+    //else if (f.inGF()) printf("(PP)");
+    //else
+    if (f.inExtension()) printf("E(%d)",f.level());
+  }
+  printf("%s",s2);
+}
+void out_cff(CFFList &L)
+{
+  //int n = L.length();
+  CFFListIterator J=L;
+  int j=0;
+  for ( ; J.hasItem(); J++, j++ )
+  {
+    printf("F%d",j);out_cf(":",J.getItem().factor()," ^ ");
+    printf("%d\n", J.getItem().exp());
+  }
+}
+void test_cff(CFFList &L,const CanonicalForm & f)
+{
+  //int n = L.length();
+  CFFListIterator J=L;
+  CanonicalForm t=1;
+  int j=0;
+  if (!(L.getFirst().factor().inCoeffDomain()))
+    printf("first entry is not const\n");
+  for ( ; J.hasItem(); J++, j++ )
+  {
+    CanonicalForm tt=J.getItem().factor();
+    if (tt.inCoeffDomain() && (j!=0))
+      printf("other entry is const\n");
+    j=J.getItem().exp();
+    while(j>0) { t*=tt; j--; }
+  }
+  if (!(f-t).isZero()) { printf("problem:\n");out_cf("factor:",f," has problems\n");}
+}
+//#endif
+#endif
+
+bool isPurePoly_m(const CanonicalForm & f)
+{
+  if (f.inBaseDomain()) return true;
+  if (f.level()<0) return false;
+  for (CFIterator i=f;i.hasTerms();i++)
+  {
+    if (!isPurePoly_m(i.coeff())) return false;
+  }
+  return true;
+}
+bool isPurePoly(const CanonicalForm & f)
+{
+  if (f.level()<=0) return false;
+  for (CFIterator i=f;i.hasTerms();i++)
+  {
+    if (!(i.coeff().inBaseDomain())) return false;
+  }
+  return true;
+}
+
+
+/**
+ * get_max_degree_Variable returns Variable with
+ * highest degree. We assume f is *not* a constant!
+**/
+Variable
+get_max_degree_Variable(const CanonicalForm & f)
+{
+  ASSERT( ( ! f.inCoeffDomain() ), "no constants" );
+  int max=0, maxlevel=0, n=level(f);
+  for ( int i=1; i<=n; i++ )
+  {
+    if (degree(f,Variable(i)) >= max)
+    {
+      max= degree(f,Variable(i)); maxlevel= i;
+    }
+  }
+  return Variable(maxlevel);
+}
+
+/**
+ * get_Terms: Split the polynomial in the containing terms.
+ * getTerms: the real work is done here.
+**/
+void
+getTerms( const CanonicalForm & f, const CanonicalForm & t, CFList & result )
+{
+  if ( getNumVars(f) == 0 ) result.append(f*t);
+  else{
+    Variable x(level(f));
+    for ( CFIterator i=f; i.hasTerms(); i++ )
+      getTerms( i.coeff(), t*power(x,i.exp()), result);
+  }
+}
+CFList
+get_Terms( const CanonicalForm & f ){
+  CFList result,dummy,dummy2;
+  CFIterator i;
+  CFListIterator j;
+
+  if ( getNumVars(f) == 0 ) result.append(f);
+  else{
+    Variable _x(level(f));
+    for ( i=f; i.hasTerms(); i++ ){
+      getTerms(i.coeff(), 1, dummy);
+      for ( j=dummy; j.hasItem(); j++ )
+        result.append(j.getItem() * power(_x, i.exp()));
+
+      dummy= dummy2; // have to initalize new
+    }
+  }
+  return result;
+}
+
+
+/**
+ * homogenize homogenizes f with Variable x
+**/
+CanonicalForm
+homogenize( const CanonicalForm & f, const Variable & x)
+{
+#if 0
+  int maxdeg=totaldegree(f), deg;
+  CFIterator i;
+  CanonicalForm elem, result(0);
+
+  for (i=f; i.hasTerms(); i++)
+  {
+    elem= i.coeff()*power(f.mvar(),i.exp());
+    deg = totaldegree(elem);
+    if ( deg < maxdeg )
+      result += elem * power(x,maxdeg-deg);
+    else
+      result+=elem;
+  }
+  return result;
+#else
+  CFList Newlist, Termlist= get_Terms(f);
+  int maxdeg=totaldegree(f), deg;
+  CFListIterator i;
+  CanonicalForm elem, result(0);
+
+  for (i=Termlist; i.hasItem(); i++)
+  {
+    elem= i.getItem();
+    deg = totaldegree(elem);
+    if ( deg < maxdeg )
+      Newlist.append(elem * power(x,maxdeg-deg));
+    else
+      Newlist.append(elem);
+  }
+  for (i=Newlist; i.hasItem(); i++) // rebuild
+    result += i.getItem();
+
+  return result;
+#endif
+}
+
+CanonicalForm
+homogenize( const CanonicalForm & f, const Variable & x, const Variable & v1, const Variable & v2)
+{
+#if 0
+  int maxdeg=totaldegree(f), deg;
+  CFIterator i;
+  CanonicalForm elem, result(0);
+
+  for (i=f; i.hasTerms(); i++)
+  {
+    elem= i.coeff()*power(f.mvar(),i.exp());
+    deg = totaldegree(elem);
+    if ( deg < maxdeg )
+      result += elem * power(x,maxdeg-deg);
+    else
+      result+=elem;
+  }
+  return result;
+#else
+  CFList Newlist, Termlist= get_Terms(f);
+  int maxdeg=totaldegree(f), deg;
+  CFListIterator i;
+  CanonicalForm elem, result(0);
+
+  for (i=Termlist; i.hasItem(); i++)
+  {
+    elem= i.getItem();
+    deg = totaldegree(elem,v1,v2);
+    if ( deg < maxdeg )
+      Newlist.append(elem * power(x,maxdeg-deg));
+    else
+      Newlist.append(elem);
+  }
+  for (i=Newlist; i.hasItem(); i++) // rebuild
+    result += i.getItem();
+
+  return result;
+#endif
+}
+
+int singular_homog_flag=1;
+
+int cmpCF( const CFFactor & f, const CFFactor & g )
+{
+  if (f.exp() > g.exp()) return 1;
+  if (f.exp() < g.exp()) return 0;
+  if (f.factor() > g.factor()) return 1;
+  return 0;
+}
+
+/**
+ * factorization over \f$ F_p \f$ or \f$ Q \f$
+**/
+CFFList factorize ( const CanonicalForm & f, bool issqrfree )
+{
+  if ( f.inCoeffDomain() )
+        return CFFList( f );
+#ifndef NOASSERT
+  Variable a;
+  ASSERT (!hasFirstAlgVar (f, a), "f has an algebraic variable use factorize \
+          ( const CanonicalForm & f, const Variable & alpha ) instead");
+#endif
+  //out_cf("factorize:",f,"==================================\n");
+  if (! f.isUnivariate() )
+  {
+    if ( singular_homog_flag && f.isHomogeneous())
+    {
+      Variable xn = get_max_degree_Variable(f);
+      int d_xn = degree(f,xn);
+      CFMap n;
+      CanonicalForm F = compress(f(1,xn),n);
+      CFFList Intermediatelist;
+      Intermediatelist = factorize(F);
+      CFFList Homoglist;
+      CFFListIterator j;
+      for ( j=Intermediatelist; j.hasItem(); j++ )
+      {
+        Homoglist.append(
+            CFFactor( n(j.getItem().factor()), j.getItem().exp()) );
+      }
+      CFFList Unhomoglist;
+      CanonicalForm unhomogelem;
+      for ( j=Homoglist; j.hasItem(); j++ )
+      {
+        unhomogelem= homogenize(j.getItem().factor(),xn);
+        Unhomoglist.append(CFFactor(unhomogelem,j.getItem().exp()));
+        d_xn -= (degree(unhomogelem,xn)*j.getItem().exp());
+      }
+      if ( d_xn != 0 ) // have to append xn^(d_xn)
+        Unhomoglist.append(CFFactor(CanonicalForm(xn),d_xn));
+      if(isOn(SW_USE_NTL_SORT)) Unhomoglist.sort(cmpCF);
+      return Unhomoglist;
+    }
+  }
+  CFFList F;
+  if ( getCharacteristic() > 0 )
+  {
+    if (f.isUnivariate())
+    {
+#ifdef HAVE_NTL
+#ifdef HAVE_FLINT
+      if (degree (f) < 300)
+      {
+        nmod_poly_t f1;
+        convertFacCF2nmod_poly_t (f1, f);
+        nmod_poly_factor_t result;
+        nmod_poly_factor_init (result);
+        mp_limb_t leadingCoeff= nmod_poly_factor (result, f1);
+        F= convertFLINTnmod_poly_factor2FacCFFList (result, leadingCoeff, f.mvar());
+        nmod_poly_factor_clear (result);
+        nmod_poly_clear (f1);
+      }
+      else
+#endif
+      {
+        // USE NTL
+        if (getCharacteristic()!=2)
+        {
+          if (fac_NTL_char != getCharacteristic())
+          {
+            fac_NTL_char = getCharacteristic();
+            zz_p::init(getCharacteristic());
+          }
+
+          // convert to NTL
+          zz_pX f1=convertFacCF2NTLzzpX(f);
+          zz_p leadcoeff = LeadCoeff(f1);
+
+          //make monic
+          f1=f1 / LeadCoeff(f1);
+          // factorize
+          vec_pair_zz_pX_long factors;
+          CanZass(factors,f1);
+
+          F=convertNTLvec_pair_zzpX_long2FacCFFList(factors,leadcoeff,f.mvar());
+          //test_cff(F,f);
+        }
+        else /*getCharacteristic()==2*/
+        {
+          // Specialcase characteristic==2
+          if (fac_NTL_char != 2)
+          {
+            fac_NTL_char = 2;
+            zz_p::init(2);
+          }
+          // convert to NTL using the faster conversion routine for characteristic 2
+          GF2X f1=convertFacCF2NTLGF2X(f);
+          // no make monic necessary in GF2
+          //factorize
+          vec_pair_GF2X_long factors;
+          CanZass(factors,f1);
+
+          // convert back to factory again using the faster conversion routine for vectors over GF2X
+          F=convertNTLvec_pair_GF2X_long2FacCFFList(factors,LeadCoeff(f1),f.mvar());
+        }
+      }
+#else
+      // Use Factory without NTL
+      factoryError ("univariate factorization depends on NTL(missing)");
+      return CFFList (CFFactor (f, 1));
+#endif //HAVE_NTL
+    }
+    else
+    {
+      #ifdef HAVE_NTL
+      if (issqrfree)
+      {
+        CFList factors;
+        Variable alpha;
+        if (CFFactory::gettype() == GaloisFieldDomain)
+          factors= GFSqrfFactorize (f);
+        else
+          factors= FpSqrfFactorize (f);
+        for (CFListIterator i= factors; i.hasItem(); i++)
+          F.append (CFFactor (i.getItem(), 1));
+      }
+      else
+      {
+        Variable alpha;
+        if (CFFactory::gettype() == GaloisFieldDomain)
+          F= GFFactorize (f);
+        else
+          F= FpFactorize (f);
+      }
+      #else
+      ASSERT( f.isUnivariate(), "multivariate factorization depends on NTL(missing)" );
+      factoryError ("multivariate factorization depends on NTL(missing)");
+      return CFFList (CFFactor (f, 1));
+      #endif
+    }
+  }
+  else
+  {
+    bool on_rational = isOn(SW_RATIONAL);
+    On(SW_RATIONAL);
+    CanonicalForm cd = bCommonDen( f );
+    CanonicalForm fz = f * cd;
+    Off(SW_RATIONAL);
+    if ( f.isUnivariate() )
+    {
+      #ifdef HAVE_NTL
+      //USE NTL
+      CanonicalForm ic=icontent(fz);
+      fz/=ic;
+      ZZ c;
+      vec_pair_ZZX_long factors;
+      //factorize the converted polynomial
+      factor(c,factors,convertFacCF2NTLZZX(fz));
+
+      //convert the result back to Factory
+      F=convertNTLvec_pair_ZZX_long2FacCFFList(factors,c,fz.mvar());
+      if ( ! ic.isOne() )
+      {
+        if ( F.getFirst().factor().inCoeffDomain() )
+        {
+          CFFactor new_first( F.getFirst().factor() * ic );
+          F.removeFirst();
+          F.insert( new_first );
+        }
+        else
+          F.insert( CFFactor( ic ) );
+      }
+      else
+      {
+        if ( !F.getFirst().factor().inCoeffDomain() )
+        {
+          CFFactor new_first( 1 );
+          F.insert( new_first );
+        }
+      }
+      #else
+      factoryError ("univariate factorization over Z depends on NTL(missing)");
+      return CFFList (CFFactor (f, 1));
+      #endif
+    }
+    else
+    {
+      #ifdef HAVE_NTL
+      On (SW_RATIONAL);
+      if (issqrfree)
+      {
+        CFList factors;
+        factors= ratSqrfFactorize (fz);
+        for (CFListIterator i= factors; i.hasItem(); i++)
+          F.append (CFFactor (i.getItem(), 1));
+      }
+      else
+        F = ratFactorize (fz);
+      Off (SW_RATIONAL);
+      #else
+      factoryError ("multivariate factorization  depends on NTL(missing)");
+      return CFFList (CFFactor (f, 1));
+      #endif
+    }
+
+    if ( on_rational )
+      On(SW_RATIONAL);
+    if ( ! cd.isOne() )
+    {
+      if ( F.getFirst().factor().inCoeffDomain() )
+      {
+        CFFactor new_first( F.getFirst().factor() / cd );
+        F.removeFirst();
+        F.insert( new_first );
+      }
+      else
+      {
+        F.insert( CFFactor( 1/cd ) );
+      }
+    }
+  }
+
+  //out_cff(F);
+  if(isOn(SW_USE_NTL_SORT)) F.sort(cmpCF);
+  return F;
+}
+
+/**
+ * factorization over \f$ F_p(\alpha) \f$ or \f$ Q(\alpha) \f$
+**/
+CFFList factorize ( const CanonicalForm & f, const Variable & alpha )
+{
+  if ( f.inCoeffDomain() )
+    return CFFList( f );
+  //out_cf("factorize:",f,"==================================\n");
+  //out_cf("mipo:",getMipo(alpha),"\n");
+
+  CFFList F;
+  ASSERT( alpha.level() < 0 && getReduce (alpha), "not an algebraic extension" );
+#ifndef NOASSERT
+  Variable beta;
+  if (hasFirstAlgVar(f, beta))
+    ASSERT (beta == alpha, "f has an algebraic variable that \
+                            does not coincide with alpha");
+#endif
+  int ch=getCharacteristic();
+  if (f.isUnivariate()&& (ch>0))
+  {
+#ifdef HAVE_NTL
+    //USE NTL
+    if (ch>2)
+    {
+#if (HAVE_FLINT && __FLINT_RELEASE >= 20400)
+      nmod_poly_t FLINTmipo, leadingCoeff;
+      fq_nmod_ctx_t fq_con;
+
+      nmod_poly_init (FLINTmipo, getCharacteristic());
+      nmod_poly_init (leadingCoeff, getCharacteristic());
+      convertFacCF2nmod_poly_t (FLINTmipo, getMipo (alpha));
+
+      fq_nmod_ctx_init_modulus (fq_con, FLINTmipo, "Z");
+      fq_nmod_poly_t FLINTF;
+      convertFacCF2Fq_nmod_poly_t (FLINTF, f, fq_con);
+      fq_nmod_poly_factor_t res;
+      fq_nmod_poly_factor_init (res, fq_con);
+      fq_nmod_poly_factor (res, leadingCoeff, FLINTF, fq_con);
+      F= convertFLINTFq_nmod_poly_factor2FacCFFList (res, f.mvar(), alpha, fq_con);
+      F.insert (CFFactor (Lc (f), 1));
+
+      fq_nmod_poly_factor_clear (res, fq_con);
+      fq_nmod_poly_clear (FLINTF, fq_con);
+      nmod_poly_clear (FLINTmipo);
+      nmod_poly_clear (leadingCoeff);
+      fq_nmod_ctx_clear (fq_con);
+#else
+      // First all cases with characteristic !=2
+      // set remainder
+      if (fac_NTL_char != getCharacteristic())
+      {
+        fac_NTL_char = getCharacteristic();
+        zz_p::init(getCharacteristic());
+      }
+
+      // set minimal polynomial in NTL
+      zz_pX minPo=convertFacCF2NTLzzpX(getMipo(alpha));
+      zz_pE::init (minPo);
+
+      // convert to NTL
+      zz_pEX f1=convertFacCF2NTLzz_pEX(f,minPo);
+      zz_pE leadcoeff= LeadCoeff(f1);
+
+      //make monic
+      f1=f1 / leadcoeff;
+
+      // factorize using NTL
+      vec_pair_zz_pEX_long factors;
+      CanZass(factors,f1);
+
+      // return converted result
+      F=convertNTLvec_pair_zzpEX_long2FacCFFList(factors,leadcoeff,f.mvar(),alpha);
+#endif
+    }
+    else if (/*getCharacteristic()*/ch==2)
+    {
+      // special case : GF2
+
+      // remainder is two ==> nothing to do
+
+      // set minimal polynomial in NTL using the optimized conversion routines for characteristic 2
+      GF2X minPo=convertFacCF2NTLGF2X(getMipo(alpha,f.mvar()));
+      GF2E::init (minPo);
+
+      // convert to NTL again using the faster conversion routines
+      GF2EX f1;
+      if (isPurePoly(f))
+      {
+        GF2X f_tmp=convertFacCF2NTLGF2X(f);
+        f1=to_GF2EX(f_tmp);
+      }
+      else
+        f1=convertFacCF2NTLGF2EX(f,minPo);
+
+      // make monic (in Z/2(a))
+      GF2E f1_coef=LeadCoeff(f1);
+      MakeMonic(f1);
+
+      // factorize using NTL
+      vec_pair_GF2EX_long factors;
+      CanZass(factors,f1);
+
+      // return converted result
+      F=convertNTLvec_pair_GF2EX_long2FacCFFList(factors,f1_coef,f.mvar(),alpha);
+    }
+#else
+    factoryError ("univariate factorization  depends on NTL(missing)");
+    return CFFList (CFFactor (f, 1));
+#endif //HAVE_NTL
+  }
+  else if (ch>0)
+  {
+    #ifdef HAVE_NTL
+    F= FqFactorize (f, alpha);
+    #else
+    ASSERT( f.isUnivariate(), "multivariate factorization depends on NTL(missing)" );
+    factoryError ("multivariate factorization  depends on NTL(missing)");
+    return CFFList (CFFactor (f, 1));
+    #endif
+
+  }
+  else if (f.isUnivariate() && (ch == 0)) // Q(a)[x]
+  {
+    F= AlgExtFactorize (f, alpha);
+  }
+  else //Q(a)[x1,...,xn]
+  {
+#ifdef HAVE_NTL
+    F= ratFactorize (f, alpha);
+#else
+    ASSERT( f.isUnivariate(), "multivariate factorization  depends on NTL(missing)" );
+    factoryError ("multivariate factorization  depends on NTL(missing)");
+    return CFFList (CFFactor (f, 1));
+#endif
+  }
+  if(isOn(SW_USE_NTL_SORT)) F.sort(cmpCF);
+  return F;
+}
+
+/**
+ * squarefree factorization
+**/
+CFFList sqrFree ( const CanonicalForm & f, bool sort )
+{
+//    ASSERT( f.isUnivariate(), "multivariate factorization not implemented" );
+    CFFList result;
+
+    if ( getCharacteristic() == 0 )
+        result = sqrFreeZ( f );
+    else
+    {
+        Variable alpha;
+        if (hasFirstAlgVar (f, alpha))
+          result = FqSqrf( f, alpha );
+        else
+          result= FpSqrf (f);
+    }
+    if (sort)
+    {
+      CFFactor buf= result.getFirst();
+      result.removeFirst();
+      result= sortCFFList (result);
+      result.insert (buf);
+    }
+    return result;
+}
+
diff --git a/factory/cf_factory.cc b/factory/cf_factory.cc
new file mode 100644
index 0000000..a0da5b8
--- /dev/null
+++ b/factory/cf_factory.cc
@@ -0,0 +1,260 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+
+#include "config.h"
+
+
+#include "cf_assert.h"
+
+#include "cf_defs.h"
+#include "cf_factory.h"
+#include "canonicalform.h"
+#include "int_cf.h"
+#include "int_int.h"
+#include "int_rat.h"
+#include "int_poly.h"
+#include "imm.h"
+
+int CFFactory::currenttype = IntegerDomain;
+
+void
+CFFactory::settype ( int type )
+{
+    ASSERT( type==FiniteFieldDomain || type==GaloisFieldDomain || type==IntegerDomain || type==RationalDomain, "illegal basic domain!" );
+    currenttype = type;
+}
+
+InternalCF *
+CFFactory::basic ( long value )
+{
+    if ( currenttype == IntegerDomain )
+        if ( value >= MINIMMEDIATE && value <= MAXIMMEDIATE )
+            return int2imm( value );
+        else
+            return new InternalInteger( value );
+//     else  if ( currenttype == RationalDomain )
+//         if ( value >= MINIMMEDIATE && value <= MAXIMMEDIATE )
+//             return int2imm( value );
+//         else
+//             return new InternalRational( value );
+    else  if ( currenttype == FiniteFieldDomain )
+        return int2imm_p( ff_norm( value ) );
+    else  if ( currenttype == GaloisFieldDomain )
+        return int2imm_gf( gf_int2gf( value ) );
+    else {
+        ASSERT( 0, "illegal basic domain!" );
+        return 0;
+    }
+}
+
+InternalCF *
+CFFactory::basic ( int type, long value )
+{
+    if ( type == IntegerDomain )
+        if ( value >= MINIMMEDIATE && value <= MAXIMMEDIATE )
+            return int2imm( value );
+        else
+            return new InternalInteger( value );
+//     else  if ( type == RationalDomain )
+//         if ( value >= MINIMMEDIATE && value <= MAXIMMEDIATE )
+//             return int2imm( value );
+//         else
+//             return new InternalRational( value );
+    else  if ( type == FiniteFieldDomain )
+        return int2imm_p( ff_norm( value ) );
+    else  if ( type == GaloisFieldDomain )
+        return int2imm_gf( gf_int2gf( value ) );
+    else {
+        ASSERT1( 0, "illegal basic domain (type = %d)!", type );
+        return 0;
+    }
+}
+
+InternalCF *
+CFFactory::basic ( const char * str )
+{
+    if ( currenttype == IntegerDomain ) {
+        InternalInteger * dummy = new InternalInteger( str );
+        if ( dummy->is_imm() ) {
+            InternalCF * res = int2imm( dummy->intval() );
+            delete dummy;
+            return res;
+        }
+        else
+            return dummy;
+    }
+//     else  if ( currenttype == RationalDomain ) {
+//         InternalRational * dummy = new InternalRational( str );
+//         if ( dummy->is_imm() ) {
+//             InternalCF * res = int2imm( dummy->intval() );
+//             delete dummy;
+//             return res;
+//         }
+//         else
+//             return dummy;
+//     }
+    else  if ( currenttype == FiniteFieldDomain ) {
+        InternalInteger * dummy = new InternalInteger( str );
+        InternalCF * res = int2imm_p( dummy->intmod( ff_prime ) );
+        delete dummy;
+        return res;
+    }
+    else  if ( currenttype == GaloisFieldDomain ) {
+        InternalInteger * dummy = new InternalInteger( str );
+        InternalCF * res = int2imm_gf( gf_int2gf( dummy->intmod( ff_prime ) ) );
+        delete dummy;
+        return res;
+    }
+    else {
+        ASSERT( 0, "illegal basic domain!" );
+        return 0;
+    }
+}
+
+InternalCF *
+CFFactory::basic ( const char * str, int base )
+{
+    if ( currenttype == IntegerDomain ) {
+        InternalInteger * dummy = new InternalInteger( str, base );
+        if ( dummy->is_imm() ) {
+            InternalCF * res = int2imm( dummy->intval() );
+            delete dummy;
+            return res;
+        }
+        else
+            return dummy;
+    }
+//     else  if ( currenttype == RationalDomain ) {
+//         InternalRational * dummy = new InternalRational( str );
+//         if ( dummy->is_imm() ) {
+//             InternalCF * res = int2imm( dummy->intval() );
+//             delete dummy;
+//             return res;
+//         }
+//         else
+//             return dummy;
+//     }
+    else  if ( currenttype == FiniteFieldDomain ) {
+        InternalInteger * dummy = new InternalInteger( str, base );
+        InternalCF * res = int2imm_p( dummy->intmod( ff_prime ) );
+        delete dummy;
+        return res;
+    }
+    else  if ( currenttype == GaloisFieldDomain ) {
+        InternalInteger * dummy = new InternalInteger( str, base );
+        InternalCF * res = int2imm_gf( gf_int2gf( dummy->intmod( ff_prime ) ) );
+        delete dummy;
+        return res;
+    }
+    else {
+        ASSERT( 0, "illegal basic domain!" );
+        return 0;
+    }
+}
+
+InternalCF *
+CFFactory::basic ( int type, const char * const str )
+{
+    if ( type == IntegerDomain ) {
+        InternalInteger * dummy = new InternalInteger( str );
+        if ( dummy->is_imm() ) {
+            InternalCF * res = int2imm( dummy->intval() );
+            delete dummy;
+            return res;
+        }
+        else
+            return dummy;
+    }
+//     else  if ( type == RationalDomain ) {
+//         InternalRational * dummy = new InternalRational( str );
+//         if ( dummy->is_imm() ) {
+//             InternalCF * res = int2imm( dummy->intval() );
+//             delete dummy;
+//             return res;
+//         }
+//         else
+//             return dummy;
+//     }
+    else  if ( type == FiniteFieldDomain ) {
+        InternalInteger * dummy = new InternalInteger( str );
+        InternalCF * res = int2imm( dummy->intmod( ff_prime ) );
+        delete dummy;
+        return res;
+    }
+    else  if ( type == GaloisFieldDomain ) {
+        InternalInteger * dummy = new InternalInteger( str );
+        InternalCF * res = int2imm_gf( gf_int2gf( dummy->intmod( ff_prime ) ) );
+        delete dummy;
+        return res;
+    }
+    else {
+        ASSERT( 0, "illegal basic domain!" );
+        return 0;
+    }
+}
+
+InternalCF *
+CFFactory::basic ( int type, long value, bool nonimm )
+{
+    if ( nonimm )
+        if ( type == IntegerDomain )
+            return new InternalInteger( value );
+         else  if ( type == RationalDomain )
+             return new InternalRational( value );
+        else {
+            ASSERT( 0, "illegal basic domain!" );
+            return 0;
+        }
+    else
+        return CFFactory::basic( type, value );
+}
+
+InternalCF *
+CFFactory::basic ( const mpz_ptr num )
+{
+  ASSERT (currenttype == IntegerDomain, "Integer domain expected");
+  return new InternalInteger( num );
+}
+
+InternalCF *
+CFFactory::rational ( long num, long den )
+{
+    InternalRational * res = new InternalRational( num, den );
+    return res->normalize_myself();
+}
+
+InternalCF *
+CFFactory::rational ( const mpz_ptr num, const mpz_ptr den, bool normalize )
+{
+    if ( normalize ) {
+        InternalRational * result = new InternalRational( num, den );
+        return result->normalize_myself();
+    }
+    else
+        return new InternalRational( num, den );
+}
+
+InternalCF *
+CFFactory::poly (  const Variable & v, int exp, const CanonicalForm & c )
+{
+    if ( v.level() == LEVELBASE )
+        return c.getval();
+    else
+        return new InternalPoly( v, exp, c );
+}
+
+InternalCF *
+CFFactory::poly ( const Variable & v, int exp )
+{
+    if ( v.level() == LEVELBASE )
+        return CFFactory::basic( 1L );
+    else
+        return new InternalPoly( v, exp, 1 );
+}
+
+void getmpi ( InternalCF * value, mpz_t mpi)
+{
+    ASSERT( ! is_imm( value ) && (value->levelcoeff() == IntegerDomain ), "illegal operation" );
+    mpz_init_set (mpi, ((InternalInteger*)value)->thempi);
+}
+
diff --git a/factory/cf_factory.h b/factory/cf_factory.h
new file mode 100644
index 0000000..6465614
--- /dev/null
+++ b/factory/cf_factory.h
@@ -0,0 +1,44 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+/**
+ * @file cf_factory.h
+ *
+ * Interface to generate InternalCF's over various domains from intrinsic types
+ * or mpz_t's
+**/
+#ifndef INCL_CF_FACTORY_H
+#define INCL_CF_FACTORY_H
+
+// #include "config.h"
+
+#include "cf_defs.h"
+#include "variable.h"
+
+#include <factory/cf_gmp.h>
+
+class InternalCF;
+class CanonicalForm;
+
+class CFFactory
+{
+private:
+    static int currenttype;
+public:
+    static int gettype () { return currenttype; }
+    static void settype ( int type );
+    static InternalCF * basic ( long value );
+    static InternalCF * basic ( int type, long value );
+    static InternalCF * basic ( const char * str );
+    static InternalCF * basic ( const char * str, int base );
+    static InternalCF * basic ( int type, const char * const str );
+    static InternalCF * basic ( int type, long value, bool nonimm );
+    static InternalCF * basic ( const mpz_ptr num );
+    static InternalCF * rational ( long num, long den );
+    static InternalCF * rational ( const mpz_ptr num, const mpz_ptr den, bool normalize );
+    static InternalCF * poly ( const Variable & v, int exp, const CanonicalForm & c );
+    static InternalCF * poly ( const Variable & v, int exp = 1 );
+};
+
+void getmpi ( InternalCF * value, mpz_t mpi);
+
+#endif /* ! INCL_CF_FACTORY_H */
diff --git a/factory/cf_gcd.cc b/factory/cf_gcd.cc
new file mode 100644
index 0000000..c9c2bee
--- /dev/null
+++ b/factory/cf_gcd.cc
@@ -0,0 +1,350 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+/**
+ * @file cf_gcd.cc
+ *
+ * gcd/content/lcm of polynomials
+ *
+ * To compute the GCD different variants are chosen automatically
+**/
+
+#include "config.h"
+
+
+#include "timing.h"
+#include "cf_assert.h"
+#include "debug.h"
+
+#include "cf_defs.h"
+#include "canonicalform.h"
+#include "cf_iter.h"
+#include "cf_reval.h"
+#include "cf_primes.h"
+#include "cf_algorithm.h"
+#include "cfEzgcd.h"
+#include "cfGcdAlgExt.h"
+#include "cfSubResGcd.h"
+#include "cfModGcd.h"
+
+#ifdef HAVE_NTL
+#include <NTL/ZZX.h>
+#include "NTLconvert.h"
+bool isPurePoly(const CanonicalForm & );
+#endif
+
+void out_cf(const char *s1,const CanonicalForm &f,const char *s2);
+
+/** static CanonicalForm icontent ( const CanonicalForm & f, const CanonicalForm & c )
+ *
+ * icontent() - return gcd of c and all coefficients of f which
+ *   are in a coefficient domain.
+ *
+ * @sa icontent().
+ *
+**/
+static CanonicalForm
+icontent ( const CanonicalForm & f, const CanonicalForm & c )
+{
+    if ( f.inBaseDomain() )
+    {
+      if (c.isZero()) return abs(f);
+      return bgcd( f, c );
+    }
+    //else if ( f.inCoeffDomain() )
+    //   return gcd(f,c);
+    else
+    {
+        CanonicalForm g = c;
+        for ( CFIterator i = f; i.hasTerms() && ! g.isOne(); i++ )
+            g = icontent( i.coeff(), g );
+        return g;
+    }
+}
+
+/** CanonicalForm icontent ( const CanonicalForm & f )
+ *
+ * icontent() - return gcd over all coefficients of f which are
+ *   in a coefficient domain.
+ *
+**/
+CanonicalForm
+icontent ( const CanonicalForm & f )
+{
+    return icontent( f, 0 );
+}
+
+/** CanonicalForm gcd_poly ( const CanonicalForm & f, const CanonicalForm & g )
+ *
+ * gcd_poly() - calculate polynomial gcd.
+ *
+ * This is the dispatcher for polynomial gcd calculation.
+ * Different gcd variants get called depending the input, characteristic, and
+ * on switches (cf_defs.h)
+ *
+ * With the current settings from Singular (i.e. SW_USE_EZGCD= on,
+ * SW_USE_EZGCD_P= on, SW_USE_CHINREM_GCD= on, the EZ GCD variants are the
+ * default algorithms for multivariate polynomial GCD computations)
+ *
+ * @sa gcd(), cf_defs.h
+ *
+**/
+#if 0
+int si_factor_reminder=1;
+#endif
+CanonicalForm gcd_poly ( const CanonicalForm & f, const CanonicalForm & g )
+{
+  CanonicalForm fc, gc, d1;
+  bool fc_isUnivariate=f.isUnivariate();
+  bool gc_isUnivariate=g.isUnivariate();
+  bool fc_and_gc_Univariate=fc_isUnivariate && gc_isUnivariate;
+  fc = f;
+  gc = g;
+  if ( getCharacteristic() != 0 )
+  {
+    #ifdef HAVE_NTL
+    if ((!fc_and_gc_Univariate) && (isOn( SW_USE_EZGCD_P )))
+    {
+      fc= EZGCD_P (fc, gc);
+    }
+    else if (isOn(SW_USE_FF_MOD_GCD) && !fc_and_gc_Univariate)
+    {
+      Variable a;
+      if (hasFirstAlgVar (fc, a) || hasFirstAlgVar (gc, a))
+        fc=modGCDFq (fc, gc, a);
+      else if (CFFactory::gettype() == GaloisFieldDomain)
+        fc=modGCDGF (fc, gc);
+      else
+        fc=modGCDFp (fc, gc);
+    }
+    else
+    #endif
+    fc = subResGCD_p( fc, gc );
+  }
+  else if (!fc_and_gc_Univariate)
+  {
+    if ( isOn( SW_USE_EZGCD ) )
+      fc= ezgcd (fc, gc);
+#ifdef HAVE_NTL
+    else if (isOn(SW_USE_CHINREM_GCD))
+      fc = modGCDZ( fc, gc);
+#endif
+    else
+    {
+       fc = subResGCD_0( fc, gc );
+    }
+  }
+  else
+  {
+    fc = subResGCD_0( fc, gc );
+  }
+  if ( d1.degree() > 0 )
+    fc *= d1;
+  return fc;
+}
+
+/** static CanonicalForm cf_content ( const CanonicalForm & f, const CanonicalForm & g )
+ *
+ * cf_content() - return gcd(g, content(f)).
+ *
+ * content(f) is calculated with respect to f's main variable.
+ *
+ * @sa gcd(), content(), content( CF, Variable ).
+ *
+**/
+static CanonicalForm
+cf_content ( const CanonicalForm & f, const CanonicalForm & g )
+{
+    if ( f.inPolyDomain() || ( f.inExtension() && ! getReduce( f.mvar() ) ) )
+    {
+        CFIterator i = f;
+        CanonicalForm result = g;
+        while ( i.hasTerms() && ! result.isOne() )
+        {
+            result = gcd( i.coeff(), result );
+            i++;
+        }
+        return result;
+    }
+    else
+        return abs( f );
+}
+
+/** CanonicalForm content ( const CanonicalForm & f )
+ *
+ * content() - return content(f) with respect to main variable.
+ *
+ * Normalizes result.
+ *
+**/
+CanonicalForm
+content ( const CanonicalForm & f )
+{
+    if ( f.inPolyDomain() || ( f.inExtension() && ! getReduce( f.mvar() ) ) )
+    {
+        CFIterator i = f;
+        CanonicalForm result = abs( i.coeff() );
+        i++;
+        while ( i.hasTerms() && ! result.isOne() )
+        {
+            result = gcd( i.coeff(), result );
+            i++;
+        }
+        return result;
+    }
+    else
+        return abs( f );
+}
+
+/** CanonicalForm content ( const CanonicalForm & f, const Variable & x )
+ *
+ * content() - return content(f) with respect to x.
+ *
+ * x should be a polynomial variable.
+ *
+**/
+CanonicalForm
+content ( const CanonicalForm & f, const Variable & x )
+{
+    if (f.inBaseDomain()) return f;
+    ASSERT( x.level() > 0, "cannot calculate content with respect to algebraic variable" );
+    Variable y = f.mvar();
+
+    if ( y == x )
+        return cf_content( f, 0 );
+    else  if ( y < x )
+        return f;
+    else
+        return swapvar( content( swapvar( f, y, x ), y ), y, x );
+}
+
+/** CanonicalForm vcontent ( const CanonicalForm & f, const Variable & x )
+ *
+ * vcontent() - return content of f with repect to variables >= x.
+ *
+ * The content is recursively calculated over all coefficients in
+ * f having level less than x.  x should be a polynomial
+ * variable.
+ *
+**/
+CanonicalForm
+vcontent ( const CanonicalForm & f, const Variable & x )
+{
+    ASSERT( x.level() > 0, "cannot calculate vcontent with respect to algebraic variable" );
+
+    if ( f.mvar() <= x )
+        return content( f, x );
+    else {
+        CFIterator i;
+        CanonicalForm d = 0;
+        for ( i = f; i.hasTerms() && ! d.isOne(); i++ )
+            d = gcd( d, vcontent( i.coeff(), x ) );
+        return d;
+    }
+}
+
+/** CanonicalForm pp ( const CanonicalForm & f )
+ *
+ * pp() - return primitive part of f.
+ *
+ * Returns zero if f equals zero, otherwise f / content(f).
+ *
+**/
+CanonicalForm
+pp ( const CanonicalForm & f )
+{
+    if ( f.isZero() )
+        return f;
+    else
+        return f / content( f );
+}
+
+CanonicalForm
+gcd ( const CanonicalForm & f, const CanonicalForm & g )
+{
+    bool b = f.isZero();
+    if ( b || g.isZero() )
+    {
+        if ( b )
+            return abs( g );
+        else
+            return abs( f );
+    }
+    if ( f.inPolyDomain() || g.inPolyDomain() )
+    {
+        if ( f.mvar() != g.mvar() )
+        {
+            if ( f.mvar() > g.mvar() )
+                return cf_content( f, g );
+            else
+                return cf_content( g, f );
+        }
+        if (isOn(SW_USE_QGCD))
+        {
+          Variable m;
+          if (
+          (getCharacteristic() == 0) &&
+          (hasFirstAlgVar(f,m) || hasFirstAlgVar(g,m))
+          )
+          {
+            bool on_rational = isOn(SW_RATIONAL);
+            CanonicalForm r=QGCD(f,g);
+            On(SW_RATIONAL);
+            CanonicalForm cdF = bCommonDen( r );
+            if (!on_rational) Off(SW_RATIONAL);
+            return cdF*r;
+          }
+        }
+
+        if ( f.inExtension() && getReduce( f.mvar() ) )
+            return CanonicalForm(1);
+        else
+        {
+            if ( fdivides( f, g ) )
+                return abs( f );
+            else  if ( fdivides( g, f ) )
+                return abs( g );
+            if ( !( getCharacteristic() == 0 && isOn( SW_RATIONAL ) ) )
+            {
+                CanonicalForm d;
+                d = gcd_poly( f, g );
+                return abs( d );
+            }
+            else
+            {
+                CanonicalForm cdF = bCommonDen( f );
+                CanonicalForm cdG = bCommonDen( g );
+                Off( SW_RATIONAL );
+                CanonicalForm l = lcm( cdF, cdG );
+                On( SW_RATIONAL );
+                CanonicalForm F = f * l, G = g * l;
+                Off( SW_RATIONAL );
+                l = gcd_poly( F, G );
+                On( SW_RATIONAL );
+                return abs( l );
+            }
+        }
+    }
+    if ( f.inBaseDomain() && g.inBaseDomain() )
+        return bgcd( f, g );
+    else
+        return 1;
+}
+
+/** CanonicalForm lcm ( const CanonicalForm & f, const CanonicalForm & g )
+ *
+ * lcm() - return least common multiple of f and g.
+ *
+ * The lcm is calculated using the formula lcm(f, g) = f * g / gcd(f, g).
+ *
+ * Returns zero if one of f or g equals zero.
+ *
+**/
+CanonicalForm
+lcm ( const CanonicalForm & f, const CanonicalForm & g )
+{
+    if ( f.isZero() || g.isZero() )
+        return 0;
+    else
+        return ( f / gcd( f, g ) ) * g;
+}
+
diff --git a/factory/cf_generator.cc b/factory/cf_generator.cc
new file mode 100644
index 0000000..1526506
--- /dev/null
+++ b/factory/cf_generator.cc
@@ -0,0 +1,229 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+
+#include "config.h"
+
+
+#include "cf_assert.h"
+
+#include "cf_defs.h"
+#include "cf_generator.h"
+#include "imm.h"
+#include "gfops.h"
+#include "ffops.h"
+
+bool IntGenerator::hasItems() const
+{
+    return 1;
+}
+
+CanonicalForm IntGenerator::item() const
+{
+  return mapinto (CanonicalForm (current));
+}
+
+void IntGenerator::next()
+{
+    current++;
+}
+
+CFGenerator * IntGenerator::clone () const
+{
+    return new IntGenerator();
+}
+
+bool FFGenerator::hasItems() const
+{
+    return current < ff_prime;
+}
+
+CanonicalForm FFGenerator::item() const
+{
+    ASSERT( current < ff_prime, "no more items" );
+    return CanonicalForm( int2imm_p( current ) );
+}
+
+void FFGenerator::next()
+{
+    ASSERT( current < ff_prime, "no more items" );
+    current++;
+}
+
+CFGenerator * FFGenerator::clone () const
+{
+    return new FFGenerator();
+}
+
+GFGenerator::GFGenerator()
+{
+    current = gf_zero();
+}
+
+bool GFGenerator::hasItems() const
+{
+    return ( current != gf_q + 1 );
+}
+
+void GFGenerator::reset()
+{
+    current = gf_zero();
+}
+
+CanonicalForm GFGenerator::item() const
+{
+    ASSERT( current != gf_q + 1, "no more items" );
+    return CanonicalForm( int2imm_gf( current ) );
+}
+
+void GFGenerator::next()
+{
+    ASSERT( current != gf_q + 1, "no more items" );
+    if ( gf_iszero( current ) )
+        current = 0;
+    else  if ( current == gf_q1 - 1 )
+        current = gf_q + 1;
+    else
+        current++;
+}
+
+CFGenerator * GFGenerator::clone () const
+{
+    return new GFGenerator();
+}
+
+AlgExtGenerator::AlgExtGenerator()
+{
+    ASSERT( 0, "not a valid generator" );
+}
+
+AlgExtGenerator::AlgExtGenerator( const AlgExtGenerator & )
+{
+    ASSERT( 0, "not a valid generator" );
+}
+
+AlgExtGenerator& AlgExtGenerator::operator= ( const AlgExtGenerator & )
+{
+    ASSERT( 0, "not a valid generator" );
+    return *this;
+}
+
+AlgExtGenerator::AlgExtGenerator( const Variable & a )
+{
+    ASSERT( a.level() < 0, "not an algebraic extension" );
+    ASSERT( getCharacteristic() > 0, "not a finite field" );
+    algext = a;
+    n = degree( getMipo( a ) );
+    if ( getGFDegree() > 1 )
+    {
+      gensg = new GFGenerator * [n];
+      for ( int i = 0; i < n; i++ )
+        gensg[i] = new GFGenerator();
+    }
+    else
+    {
+      gensf = new FFGenerator * [n];
+      for ( int i = 0; i < n; i++ )
+        gensf[i] = new FFGenerator();
+    }
+    nomoreitems = false;
+}
+
+AlgExtGenerator::~AlgExtGenerator()
+{
+    if ( getGFDegree() > 1 )
+    {
+      for ( int i = 0; i < n; i++ )
+        delete gensg[i];
+      delete [] gensg;
+    }
+    else
+    {
+      for ( int i = 0; i < n; i++ )
+        delete gensf[i];
+      delete [] gensf;
+    }
+}
+
+void AlgExtGenerator::reset()
+{
+    if ( getGFDegree() > 1 )
+    {
+      for ( int i = 0; i < n; i++ )
+        gensg[i]->reset();
+    }
+    else
+    {
+      for ( int i = 0; i < n; i++ )
+        gensf[i]->reset();
+    }
+    nomoreitems = false;
+}
+
+CanonicalForm AlgExtGenerator::item() const
+{
+    ASSERT( ! nomoreitems, "no more items" );
+    CanonicalForm result = 0;
+    if ( getGFDegree() > 1 )
+    {
+      for ( int i = 0; i < n; i++ )
+            result += power( algext, i ) * gensg[i]->item();
+    }
+    else
+    {
+      for ( int i = 0; i < n; i++ )
+            result += power( algext, i ) * gensf[i]->item();
+    }
+    return result;
+}
+
+void AlgExtGenerator::next()
+{
+    ASSERT( ! nomoreitems, "no more items" );
+    int i = 0;
+    bool stop = false;
+    if ( getGFDegree() > 1 )
+    {
+      while ( ! stop && i < n )
+      {
+            gensg[i]->next();
+            if ( ! gensg[i]->hasItems() )
+        {
+              gensg[i]->reset();
+              i++;
+            }
+            else
+              stop = true;
+      }
+    }
+    else
+    {
+      while ( ! stop && i < n )
+      {
+            gensf[i]->next();
+            if ( ! gensf[i]->hasItems() )
+        {
+              gensf[i]->reset();
+              i++;
+            }
+            else
+              stop = true;
+      }
+    }
+    if ( ! stop )
+        nomoreitems = true;
+}
+
+CFGenerator * AlgExtGenerator::clone () const
+{
+    return new AlgExtGenerator(algext);
+}
+
+CFGenerator * CFGenFactory::generate()
+{
+    if (getCharacteristic() == 0)
+        return new IntGenerator();
+    else if ( getGFDegree() > 1 )
+        return new GFGenerator();
+    else
+        return new FFGenerator();
+}
diff --git a/factory/cf_generator.h b/factory/cf_generator.h
new file mode 100644
index 0000000..8af5e39
--- /dev/null
+++ b/factory/cf_generator.h
@@ -0,0 +1,125 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+/**
+ * @file cf_generator.h
+ *
+ * generate integers, elements of finite fields
+**/
+
+#ifndef INCL_CF_GENERATOR_H
+#define INCL_CF_GENERATOR_H
+
+// #include "config.h"
+
+#include "canonicalform.h"
+
+/*BEGINPUBLIC*/
+
+/**
+ * virtual class for generators
+**/
+class CFGenerator
+{
+public:
+    CFGenerator() {}
+    virtual ~CFGenerator() {}
+    virtual bool hasItems() const { return false; }
+    virtual void reset() {};
+    virtual CanonicalForm item() const { return 0; }
+    virtual void next() {};
+    virtual CFGenerator * clone() const { return new CFGenerator();}
+};
+
+/**
+ * generate integers starting from 0
+**/
+class IntGenerator : public CFGenerator
+{
+private:
+    int current;
+public:
+    IntGenerator() : current(0) {}
+    ~IntGenerator() {}
+    bool hasItems() const;
+    void reset() { current = 0; }
+    CanonicalForm item() const;
+    void next();
+    void operator++ () { next(); }
+    void operator++ ( int ) { next(); }
+    CFGenerator * clone() const;
+};
+
+/**
+ * generate all elements in F_p starting from 0
+**/
+class FFGenerator : public CFGenerator
+{
+private:
+    int current;
+public:
+    FFGenerator() : current(0) {}
+    ~FFGenerator() {}
+    bool hasItems() const;
+    void reset() { current = 0; }
+    CanonicalForm item() const;
+    void next();
+    void operator++ () { next(); }
+    void operator++ ( int ) { next(); }
+    CFGenerator * clone() const;
+};
+
+/**
+ * generate all elements in GF starting from 0
+**/
+class GFGenerator : public CFGenerator
+{
+private:
+    int current;
+public:
+    GFGenerator();
+    ~GFGenerator() {}
+    bool hasItems() const;
+    void reset();
+    CanonicalForm item() const;
+    void next();
+    void operator++ () { next(); }
+    void operator++ ( int ) { next(); }
+    CFGenerator * clone() const;
+};
+
+/**
+ * generate all elements in F_p(alpha) starting from 0
+**/
+class AlgExtGenerator: public CFGenerator
+{
+private:
+    Variable algext;
+    FFGenerator **gensf;
+    GFGenerator **gensg;
+    int n;
+    bool nomoreitems;
+    AlgExtGenerator();
+    AlgExtGenerator( const AlgExtGenerator & );
+    AlgExtGenerator& operator= ( const AlgExtGenerator & );
+public:
+    AlgExtGenerator( const Variable & a );
+    ~AlgExtGenerator();
+
+    bool hasItems() const { return ! nomoreitems; }
+    void reset();
+    CanonicalForm item() const;
+    void next();
+    void operator++ () { next(); }
+    void operator++ ( int ) { next(); }
+    CFGenerator * clone() const;
+};
+
+class CFGenFactory
+{
+public:
+    static CFGenerator* generate();
+};
+
+/*ENDPUBLIC*/
+
+#endif /* ! INCL_CF_GENERATOR_H */
diff --git a/factory/cf_globals.cc b/factory/cf_globals.cc
new file mode 100644
index 0000000..cc267ac
--- /dev/null
+++ b/factory/cf_globals.cc
@@ -0,0 +1,39 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+/**
+ *
+ * @file cf_globals.cc
+ *
+ * definitions of global variables.
+ *
+ * Used by: canonicalform.cc, int_int.cc, ffops.h, imm.h
+ *
+**/
+
+
+#include "config.h"
+
+
+
+/** extern const char factoryVersion[];
+ *
+ * factoryVersion - factory version string.
+ *
+ * factoryVersion is initialized from #define FACTORYVERSION
+ * which is defined in config.h.  It is not used in factory
+ * itself.
+ *
+**/
+extern const char factoryVersion[] = "@(#) factoryVersion = " FACTORYVERSION;
+
+/** extern const char factoryConfiguration[];
+ *
+ * factoryConfiguration - factory configuration.
+ *
+ * factoryConfiguration is initialized from #define
+ * FACTORYCONFIGURATION which is defined in config.h.  It is set
+ * to the option configure was called with plus the directory it
+ * was called in.  It is not used in factory itself.
+ *
+**/
+extern const char factoryConfiguration[] = "@(#) factoryConfiguration = " FACTORYCONFIGURATION;
diff --git a/factory/cf_globals.h b/factory/cf_globals.h
new file mode 100644
index 0000000..142eed7
--- /dev/null
+++ b/factory/cf_globals.h
@@ -0,0 +1,24 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+#ifndef INCL_CF_GLOBALS_H
+#define INCL_CF_GLOBALS_H
+
+//{{{ docu
+//
+// cf_globals.h - header to cf_globals.cc.
+//
+//}}}
+
+// #include "config.h"
+
+#include "cf_switches.h"
+
+/*BEGINPUBLIC*/
+
+extern const char factoryVersion[];
+extern const char factoryConfiguration[];
+
+/*ENDPUBLIC*/
+
+
+#endif /* ! INCL_CF_GLOBALS_H */
diff --git a/factory/cf_hnf.cc b/factory/cf_hnf.cc
new file mode 100644
index 0000000..9e8382e
--- /dev/null
+++ b/factory/cf_hnf.cc
@@ -0,0 +1,61 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+/**
+ *
+ * @file cf_hnf.cc
+ *
+ * HNF/LLL of NTL
+ *
+ * Header file: cf_hnf.h
+ *
+**/
+
+
+#include "config.h"
+
+
+#ifdef HAVE_NTL
+#include "NTLconvert.h"
+#include "canonicalform.h"
+#include "cf_defs.h"
+#include "cf_hnf.h"
+#include <NTL/mat_ZZ.h>
+#include <NTL/HNF.h>
+#include <NTL/LLL.h>
+
+/**
+ * The input matrix A is an n x m matrix of rank m (so n >= m), and D
+ * is a multiple of the determinant of the lattice L spanned by the
+ * rows of A.  W is computed as the Hermite Normal Form of A; that is,
+ * W is the unique m x m matrix whose rows span L, such that
+ *
+ * - W is lower triangular,
+ * - the diagonal entries are positive,
+ * - any entry below the diagonal is a non-negative number
+ *   strictly less than the diagonal entry in its column.
+ *
+**/
+CFMatrix* cf_HNF(CFMatrix& A)
+{
+  mat_ZZ *AA=convertFacCFMatrix2NTLmat_ZZ(A);
+  ZZ DD=convertFacCF2NTLZZ(determinant(A,A.rows()));
+  mat_ZZ WW;
+  HNF(WW,*AA,DD);
+  delete AA;
+  return convertNTLmat_ZZ2FacCFMatrix(WW);
+}
+
+CFMatrix* cf_LLL(CFMatrix& A)
+{
+  mat_ZZ *AA=convertFacCFMatrix2NTLmat_ZZ(A);
+  #if 0
+  LLL_RR(*AA);
+  #else
+  ZZ det2;
+  LLL(det2,*AA,0L);
+  #endif
+  CFMatrix *r= convertNTLmat_ZZ2FacCFMatrix(*AA);
+  delete AA;
+  return r;
+}
+#endif
diff --git a/factory/cf_hnf.h b/factory/cf_hnf.h
new file mode 100644
index 0000000..fc0a8d2
--- /dev/null
+++ b/factory/cf_hnf.h
@@ -0,0 +1,52 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+#ifndef CF_HNF_H
+#define CF_HNF_H
+
+/*BEGINPUBLIC*/
+
+#ifdef HAVE_NTL
+
+/**
+ *
+ * The input matrix A is square matrix of integers
+ * output: the Hermite Normal Form of A; that is,
+ * the unique m x m matrix whose rows span L, such that
+ *
+ * - lower triangular,
+ * - the diagonal entries are positive,
+ * - any entry below the diagonal is a non-negative number
+ *   strictly less than the diagonal entry in its column.
+ *
+ * @note: uses NTL
+ *
+**/
+
+CFMatrix* cf_HNF(CFMatrix& A);
+
+/**
+ * performs LLL reduction.
+ *
+ * B is an m x n matrix, viewed as m rows of n-vectors.  m may be less
+ * than, equal to, or greater than n, and the rows need not be
+ * linearly independent.  B is transformed into an LLL-reduced basis,
+ * and the return value is the rank r of B.  The first m-r rows of B
+ * are zero.
+ *
+ * More specifically, elementary row transformations are performed on
+ * B so that the non-zero rows of new-B form an LLL-reduced basis
+ * for the lattice spanned by the rows of old-B.
+ * The default reduction parameter is delta=3/4, which means
+ * that the squared length of the first non-zero basis vector
+ * is no more than 2^{r-1} times that of the shortest vector in
+ * the lattice.
+ *
+ * @note: uses NTL
+**/
+
+CFMatrix* cf_LLL(CFMatrix& A);
+
+#endif
+
+/*ENDPUBLIC*/
+
+#endif
diff --git a/factory/cf_inline.cc b/factory/cf_inline.cc
new file mode 100644
index 0000000..50b9f31
--- /dev/null
+++ b/factory/cf_inline.cc
@@ -0,0 +1,570 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+/**
+ *
+ * @file cf_inline.cc
+ *
+ * definition of configurable inline
+ *   `CanonicalForm' methods.
+ *
+ * Hierarchy: canonicalform
+ *
+ * Header file: canonicalform.h
+ *
+ * Developers note:
+ * ----------------
+ * The central class in Factory is, of course, `CanonicalForm'.
+ * Hence it is a quiet reasonable to assume that inlining its
+ * most important methods will improve execution speed.  The same
+ * holds for some methods of the `CFIterator' class.  Everything
+ * on configurable inline `CanonicalForm' methods explained here
+ * applies mutatis mutandis to the `CFIterator' methods.
+ *
+ * However, inlining `CanonicalForm' methods has two major
+ * drawbacks:
+ *
+ * o If `CanonicalForm' methods simply would have been declared
+ *   `inline' it would have been necessary to include the
+ *   definition of `InternalCF' in `factory.h'.  This would have
+ *   been quite a contradiction to the internal nature of the
+ *   class.
+ *   Hence it seemed desirable to introduce a mechanism to have
+ *   both the inlined versions for internal use and compiled
+ *   versions for the library.
+ *
+ * o Second, inlining in most cases leads to larger object code.
+ *   E.g., inlining `CanonicalForm::~CanonicalForm()' increases the
+ *   object code by approx. 15% without any effect on computation
+ *   speed.
+ *   Thus another design aim was to keep things configurable.
+ *   That is why the methods defined here are called
+ *   "configurable inline methods".
+ *
+ * The low level solution to both problems is the macro
+ * `CF_INLINE' which either expands to `inline' or nothing.  The
+ * counterpart `CF_NO_INLINE' exists only for convenience, it
+ * always expands to nothing.  `CF_INLINE' is set immediately
+ * before defining resp. declaring the methods to exclude any
+ * esoteric influences from included files.
+ *
+ * The high level interface is the macro `CF_USE_INLINE'.  If it
+ * is defined any header file that uses configurable inline
+ * methods defines them to be `inline', otherwise they are
+ * defined as ordinary methods.  `CF_USE_INLINE' is defined in
+ * `config.h' only.
+ *
+ * To switch on (off) all configurable inline methods, it is
+ * sufficient to define (undefine) `CF_USE_INLINE' in `config.h'.
+ * To switch off separate configurable inline methods it is
+ * necessary to prefix their declaration in `canonicalform.h' by
+ * `CF_NO_INLINE' instead of `CF_INLINE'.  Furthermore, to avoid
+ * duplicate symbols at link time, their definition in this file
+ * has to be wrapped by an `#ifndef INCL_CF_INLINE_CC'.
+ *
+ * It turned out that inlining the following methods (and only
+ * them) results in the best time to size ratio on Linux and HP
+ * machines:
+ * o all `CanonicalForm' constructors
+ * o the binary `CanonicalForm' operators `+' and `*'
+ *
+**/
+
+// check whether we are included or translated and
+// define `INCL_CF_INLINE_CC' if we are included
+#ifdef INCL_CANONICALFORM_H
+#define INCL_CF_INLINE_CC
+#endif
+
+
+#include "config.h"
+
+
+#include "cf_assert.h"
+
+// temporarily switch off `CF_USE_INLINE' and include
+// `canonicalform.h' if we are being translated.
+// `CF_USE_INLINE_SAVE' is used to save the state of
+// `CF_USE_INLINE'.  It is unset after use.
+#ifndef INCL_CF_INLINE_CC
+#ifdef CF_USE_INLINE
+#define CF_USE_INLINE_SAVE
+#undef CF_USE_INLINE
+#endif
+#include "canonicalform.h"
+#ifdef CF_USE_INLINE_SAVE
+#define CF_USE_INLINE
+#undef CF_USE_INLINE_SAVE
+#endif
+#endif /* ! INCL_CF_INLINE_CC */
+
+// regular include files
+#include "int_cf.h"
+#include "imm.h"
+#include "cf_factory.h"
+
+// set the value of `CF_INLINE' for the following methods and
+// functions
+#if defined( CF_USE_INLINE ) && defined( INCL_CF_INLINE_CC )
+#undef CF_INLINE
+#define CF_INLINE inline
+#else
+#undef CF_INLINE
+#define CF_INLINE
+#endif /* ! defined( CF_USE_INLINE ) && defined( INCL_CF_INLINE_CC ) */
+
+// constructors, destructors, assignment
+/** CF_INLINE CanonicalForm::CanonicalForm ()
+ *
+ *
+ * CanonicalForm() - create the default canonical form.
+ *
+ * The canonical form is initialized to zero from the current
+ * domain.
+ *
+**/
+CF_INLINE
+CanonicalForm::CanonicalForm ()
+    : value( CFFactory::basic( (long)0 ) )
+{
+}
+
+/** CF_INLINE CanonicalForm::CanonicalForm ( const int i )
+ *
+ *
+ * CanonicalForm() - create a canonical form from an integer.
+ *
+ * The canonical form is initialized to the "canonical image" of
+ * `i' in the current domain.  This is `i' itself for
+ * characteristic zero, `i' mod p for finite fields of
+ * characteristic p, and `i' mod p^n for prime power domains with
+ * p^n elements.
+ *
+**/
+CF_INLINE
+CanonicalForm::CanonicalForm ( const int i )
+    : value( CFFactory::basic( (long)i ) )
+{
+}
+
+CF_INLINE
+CanonicalForm::CanonicalForm ( const long i )
+    : value( CFFactory::basic( i ) )
+{
+}
+
+/** CF_INLINE CanonicalForm::CanonicalForm ( const CanonicalForm & cf )
+ *
+ *
+ * CanonicalForm() - create a copy of a canonical form.
+ *
+ * Type info:
+ * ----------
+ * cf: Anything
+ *
+**/
+CF_INLINE
+CanonicalForm::CanonicalForm ( const CanonicalForm & cf )
+    : value( is_imm( cf.value ) ? cf.value : cf.value->copyObject() )
+{
+}
+
+/** CF_INLINE CanonicalForm::CanonicalForm ( InternalCF * cf )
+ *
+ *
+ * CanonicalForm() - create a canonical form from a pointer to an
+ *   internal canonical form.
+ *
+ * This constructor is reserved for internal usage.
+ *
+ * Developers note:
+ * ----------------
+ * The canonical form gets its value immediately from `cf'.
+ * `cf's reference counter is not incremented, so be careful with
+ * this constructor.
+ *
+**/
+CF_INLINE
+CanonicalForm::CanonicalForm ( InternalCF * cf )
+    : value( cf )
+{
+}
+
+/** CF_INLINE CanonicalForm::CanonicalForm ( const Variable & v )
+ *
+ *
+ * CanonicalForm() - create a canonical form from a variable.
+ *
+ * If `v' is a polynomial variable or an algebraic element the
+ * resulting polynomial (or algebraic element) is 1*`v'^1, the
+ * one being from the current domain.
+ *
+ * Variables of level `LEVELBASE' are transformed to one from the
+ * current domain.
+ *
+ * Type info:
+ * ----------
+ * v: Anything
+ *
+**/
+CF_INLINE
+CanonicalForm::CanonicalForm ( const Variable & v )
+    : value( CFFactory::poly( v ) )
+{
+}
+
+/** CF_INLINE CanonicalForm::CanonicalForm ( const Variable & v, int e )
+ *
+ *
+ * CanonicalForm() - create a canonical form from a power of a
+ *   variable.
+ *
+ * If `v' is a polynomial variable or an algebraic element the
+ * resulting polynomial (or algebraic element) is 1*`v'^`e', the
+ * one being from the current domain.  Algebraic elements are
+ * reduced modulo their minimal polynomial.
+ *
+ * Variables of level `LEVELBASE' are transformed to one from the
+ * current domain.
+ *
+ * Type info:
+ * ----------
+ * v: Anything
+ *
+**/
+CF_INLINE
+CanonicalForm::CanonicalForm ( const Variable & v, int e )
+    : value( CFFactory::poly( v, e ) )
+{
+    //ASSERT( e > 0, "math error: exponent has to be positive" );
+}
+
+#ifndef INCL_CF_INLINE_CC
+/** CF_INLINE CanonicalForm::~CanonicalForm ()
+ *
+ *
+ * ~CanonicalForm() - delete CO.
+ *
+ * Type info:
+ * ----------
+ * CO: Anything
+ *
+**/
+CF_INLINE
+CanonicalForm::~CanonicalForm ()
+{
+    if ( (! is_imm( value )) && value->deleteObject() )
+        delete value;
+}
+#endif
+
+#ifndef INCL_CF_INLINE_CC
+/** CF_INLINE CanonicalForm & CanonicalForm::operator = ( const CanonicalForm & cf )
+ *
+ *
+ * operator =() - assign `cf' to CO.
+ *
+ * Type info:
+ * ----------
+ * CO, cf: Anything
+ *
+**/
+CF_INLINE CanonicalForm &
+CanonicalForm::operator = ( const CanonicalForm & cf )
+{
+    if ( this != &cf ) {
+        if ( (! is_imm( value )) && value->deleteObject() )
+            delete value;
+        value = (is_imm( cf.value )) ? cf.value : cf.value->copyObject();
+    }
+    return *this;
+}
+
+/**
+ *
+ * operator =() - assign long `cf' to CO.
+ *
+ * `cf' converted to a canonical form as described in the
+ * canonical form constructor which creates a canonical form from
+ * an integer.
+ *
+ * Type info:
+ * ----------
+ * CO: Anything
+ *
+ * Developers note:
+ * ----------------
+ * Strictly speaking, this operator is superfluous.  The ordinary
+ * assignment operator together with automatic conversion from
+ * `int' to `CanonicalForm' would do the job, too.  But this way
+ * the common operation of assigning an integer is faster.
+ *
+**/
+CF_INLINE CanonicalForm &
+CanonicalForm::operator = ( const long cf )
+{
+    if ( (! is_imm( value )) && value->deleteObject() )
+        delete value;
+    value = CFFactory::basic( cf );
+    return *this;
+}
+#endif
+
+// predicates
+#ifndef INCL_CF_INLINE_CC
+/** CF_INLINE bool CanonicalForm::isOne, isZero () const
+ *
+ *
+ * isOne(), isZero() - test whether a `CanonicalForm' equals one
+ *   or zero, resp.
+ *
+ * The predicates `isOne()' and `isZero()' are much faster than
+ * the comparison operators.  Furthermore, a test `f.isZero()' is
+ * independent from the current domain, whereas an expression
+ * `f == 0' is not.
+ *
+ * Type info:
+ * ----------
+ * CO: Anything
+ *
+ * Internal implementation:
+ * ------------------------
+ * Note that only immediate objects and objects of class
+ * `InternalPrimePower' may equal one or zero, resp.
+ *
+ * imm_isone(), imm_iszero()
+ * Trivial.
+ *
+ * imm_isone_p(), imm_iszero_p()
+ * Trivial.
+ *
+ * imm_isone_gf(), imm_iszero_gf()
+ * Use `gf_isone()' and `gf_iszero()', resp., to test whether CO
+ * equals zero or one, resp.
+ *
+ * InternalCF::isOne(), isZero()
+ * Always return false.
+ *
+ * InternalPrimePower::isOne(), isZero()
+ * Use `mpz_cpm_ui()' resp. `mpz_sgn()' to check the underlying
+ * mpi.
+ *
+ * @sa CanonicalForm::isZero()
+**/
+CF_INLINE bool
+CanonicalForm::isOne () const
+{
+    int what = is_imm( value );
+
+    if ( ! what )
+        return value->isOne();
+    else  if ( what == INTMARK )
+        return imm_isone( value );
+    else if ( what == FFMARK )
+        return imm_isone_p( value );
+    else
+        return imm_isone_gf( value );
+}
+
+/**
+ * @sa CanonicalForm::isOne()
+**/
+CF_INLINE bool
+CanonicalForm::isZero () const
+{
+    int what = is_imm( value );
+
+    if ( what == 0 )
+        return value->isZero();
+    else  if ( what == INTMARK )
+        return imm_iszero( value );
+    else if ( what == FFMARK )
+        return imm_iszero_p( value );
+    else
+        return imm_iszero_gf( value );
+}
+#endif
+
+// arithmetic operators
+#ifndef INCL_CF_INLINE_CC
+/** CF_INLINE CanonicalForm operator - ( const CanonicalForm & cf )
+ *
+ *
+ * operator -() - return additive inverse of `cf'.
+ *
+ * Returns the additive inverse of `cf'.  One should keep in mind
+ * that to negate a canonical form a complete (deep) copy of it
+ * has to be created.
+ *
+ * Type info:
+ * ----------
+ * cf: CurrentPP
+ *
+ * In fact, the type is almost `Anything', but it is, e.g., not
+ * possible to invert an element from a finite field when the
+ * characteristic of the current domain has changed.
+ *
+ * Internal implementation:
+ * ------------------------
+ * All internal methods check whether the reference counter
+ * equals one.  If so CO is negated in-place.  Otherwise, a new
+ * copy of CO is created and negated.
+ *
+ * imm_neg()
+ * Trivial.
+ *
+ * imm_neg_p()
+ * Use `ff_neg()' to negate CO.
+ *
+ * imm_neg_gf()
+ * Use `gf_neg()' to negate CO.
+ *
+ * InternalInteger::neg()
+ * Use `mpz_neg()' to negate the underlying mpi.
+ *
+ * InternalRational::neg ()
+ * Use `mpz_neg()' to negate the denominator.
+ *
+ * InternalPrimePower::neg()
+ * Subtract CO from `primepow' using `mpz_sub'.
+ *
+ * InternalPoly::neg()
+ * If reference counter is one use `negateTermList()' to negate
+ * the terms, otherwise create a negated copy using
+ * `copyTermList()'.
+ *
+ * @sa CanonicalForm::operator -=()
+**/
+CF_INLINE CanonicalForm
+operator - ( const CanonicalForm & cf )
+{
+    CanonicalForm result( cf );
+    int what = is_imm( result.value );
+
+    if ( ! what )
+        result.value = result.value->neg();
+    else  if ( what == INTMARK )
+        result.value = imm_neg( result.value );
+    else if ( what == FFMARK )
+        result.value = imm_neg_p( result.value );
+    else
+        result.value = imm_neg_gf( result.value );
+
+    return result;
+}
+#endif
+
+// binary arithmetic operators and functions
+/** CF_INLINE CanonicalForm operator +, -, *, /, % ( const CanonicalForm & lhs, const CanonicalForm & rhs )
+ *
+ *
+ * operators +, -, *, /, %(), div(), mod() - binary arithmetic
+ *   operators.
+ *
+ * The binary operators have their standard (mathematical)
+ * semantics.  As explained for the corresponding arithmetic
+ * assignment operators, the operators `/' and `%' return the
+ * quotient resp. remainder of (polynomial) division with
+ * remainder, whereas `div()' and `mod()' may be used for exact
+ * division and term-wise remaindering, resp.
+ *
+ * It is faster to use the arithmetic assignment operators (e.g.,
+ * `f += g;') instead of the binary operators (`f = f+g;' ).
+ *
+ * Type info:
+ * ----------
+ * lhs, rhs: CurrentPP
+ *
+ * There are weaker preconditions for some cases (e.g.,
+ * arithmetic operations with elements from Q or Z work in any
+ * domain), but type `CurrentPP' is the only one guaranteed to
+ * work for all cases.
+ *
+ * Developers note:
+ * ----------------
+ * All binary operators have their corresponding `CanonicalForm'
+ * assignment operators (e.g., `operator +()' corresponds to
+ * `CanonicalForm::operator +=()', `div()' corresponds to
+ * `CanonicalForm::div()).
+ *
+ * And that is how they are implemented, too: Each of the binary
+ * operators first creates a copy of `lhs', adds `rhs' to this
+ * copy using the assignment operator, and returns the result.
+ *
+ * @sa CanonicalForm::operator +=()
+**/
+CF_INLINE CanonicalForm
+operator + ( const CanonicalForm & lhs, const CanonicalForm & rhs )
+{
+    CanonicalForm result( lhs );
+    result += rhs;
+    return result;
+}
+
+#ifndef INCL_CF_INLINE_CC
+CF_INLINE CanonicalForm
+operator - ( const CanonicalForm & lhs, const CanonicalForm & rhs )
+{
+    CanonicalForm result( lhs );
+    result -= rhs;
+    return result;
+}
+#endif
+
+/**
+ * @sa CanonicalForm::operator *=()
+**/
+CF_INLINE CanonicalForm
+operator * ( const CanonicalForm & lhs, const CanonicalForm & rhs )
+{
+    CanonicalForm result( lhs );
+    result *= rhs;
+    return result;
+}
+
+#ifndef INCL_CF_INLINE_CC
+/**
+ * @sa CanonicalForm::operator /=()
+**/
+CF_INLINE CanonicalForm
+operator / ( const CanonicalForm & lhs, const CanonicalForm & rhs )
+{
+    CanonicalForm result( lhs );
+    result /= rhs;
+    return result;
+}
+
+/**
+ * @sa CanonicalForm::operator %=()
+**/
+CF_INLINE CanonicalForm
+operator % ( const CanonicalForm & lhs, const CanonicalForm & rhs )
+{
+    CanonicalForm result( lhs );
+    result %= rhs;
+    return result;
+}
+#endif
+
+#ifndef INCL_CF_INLINE_CC
+/** CF_INLINE CanonicalForm div, mod ( const CanonicalForm & lhs, const CanonicalForm & rhs )
+ * @sa mod(), operator/(), CanonicalForm::operator /=()
+**/
+CF_INLINE CanonicalForm
+div ( const CanonicalForm & lhs, const CanonicalForm & rhs )
+{
+    CanonicalForm result( lhs );
+    result.div( rhs );
+    return result;
+}
+
+/**
+ * @sa div(), operator%(), CanonicalForm::operator %=()
+**/
+CF_INLINE CanonicalForm
+mod ( const CanonicalForm & lhs, const CanonicalForm & rhs )
+{
+    CanonicalForm result( lhs );
+    result.mod( rhs );
+    return result;
+}
+#endif
diff --git a/factory/cf_irred.cc b/factory/cf_irred.cc
new file mode 100644
index 0000000..433d05c
--- /dev/null
+++ b/factory/cf_irred.cc
@@ -0,0 +1,56 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+
+#include "config.h"
+
+
+#include "cf_assert.h"
+
+#include "cf_defs.h"
+#include "canonicalform.h"
+#include "cf_algorithm.h"
+#include "cf_random.h"
+
+#ifdef HAVE_NTL
+#include "NTLconvert.h"
+#endif
+
+static bool
+is_irreducible ( const CanonicalForm & f )
+{
+    CFFList F = factorize( f );
+    return F.length() == 1 && F.getFirst().exp() == 1;
+}
+
+CanonicalForm
+find_irreducible ( int deg, CFRandom & gen, const Variable & x )
+{
+    CanonicalForm result;
+    int i;
+    do {
+        result = power( x, deg );
+        for ( i = deg-1; i >= 0; i-- )
+            result += gen.generate() * power( x, i );
+    } while ( ! is_irreducible( result ) );
+    return result;
+}
+
+#ifdef HAVE_NTL
+/// computes a random monic irreducible univariate polynomial in x over Fp of
+/// degree i via NTL
+CanonicalForm
+randomIrredpoly (int i, const Variable & x)
+{
+  int p= getCharacteristic();
+  if (fac_NTL_char != p)
+  {
+    fac_NTL_char= p;
+    zz_p::init (p);
+  }
+  zz_pX NTLirredpoly;
+  CanonicalForm CFirredpoly;
+  BuildIrred (NTLirredpoly, i);
+  CFirredpoly= convertNTLzzpX2CF (NTLirredpoly, x);
+  return CFirredpoly;
+}
+#endif
diff --git a/factory/cf_irred.h b/factory/cf_irred.h
new file mode 100644
index 0000000..7d717c7
--- /dev/null
+++ b/factory/cf_irred.h
@@ -0,0 +1,27 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+/**
+ * @file cf_irred.h
+ *
+ * generate random irreducible univariate polynomials
+**/
+
+#ifndef INCL_CF_IRRED_H
+#define INCL_CF_IRRED_H
+
+// #include "config.h"
+
+#include "canonicalform.h"
+#include "cf_random.h"
+
+/** generate a random irreducible polynomial in x of degree deg
+ *
+ * @warning this is done in the most naive way, i.e. a random is generated and
+ * then factorized
+**/
+CanonicalForm find_irreducible ( int deg, CFRandom & gen, const Variable & x );
+
+CanonicalForm
+randomIrredpoly (int i, const Variable & x);
+
+#endif /* ! INCL_CF_IRRED_H */
diff --git a/factory/cf_iter.cc b/factory/cf_iter.cc
new file mode 100644
index 0000000..d6cbe34
--- /dev/null
+++ b/factory/cf_iter.cc
@@ -0,0 +1,116 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+
+#include "config.h"
+
+
+#include "cf_assert.h"
+
+#include "cf_defs.h"
+#include "cf_iter.h"
+#include "int_cf.h"
+#include "int_poly.h"
+
+
+CFIterator::CFIterator()
+{
+    data = 0; cursor = 0;
+    ispoly = false; hasterms = false;
+}
+
+CFIterator::CFIterator( const CFIterator & i )
+{
+    data = i.data;
+    cursor = i.cursor;
+    ispoly = i.ispoly;
+    hasterms = i.hasterms;
+}
+
+CFIterator::CFIterator( const CanonicalForm & f )
+{
+    if ( f.inBaseDomain() || f.inQuotDomain() )
+    {
+        data = f; cursor = 0;
+        ispoly = false; hasterms = true;
+    }
+    else
+    {
+        data = f;
+        cursor = ((InternalPoly*)(f.value))->firstTerm;
+        ispoly = true; hasterms = true;
+    }
+}
+
+CFIterator::CFIterator( const CanonicalForm & f, const Variable & v )
+{
+    ASSERT( !f.inQuotDomain(), "illegal iterator" );
+    ASSERT( v.level() > 0, "illegal iterator" );
+    if ( f.inBaseDomain() )
+    {
+        data = f; cursor = 0;
+        ispoly = false; hasterms = true;
+    }
+    else
+    {
+        if ( f.mvar() == v )
+        {
+            data = f;
+            cursor = ((InternalPoly*)(f.value))->firstTerm;
+            ispoly = true; hasterms = true;
+        }
+        else  if ( v > f.mvar() )
+        {
+            data = f; cursor = 0;
+            ispoly = false; hasterms = true;
+        }
+        else
+        {
+            data = swapvar( f, v, f.mvar().next() );
+            if ( data.mvar() == f.mvar().next() )
+            {
+                cursor = ((InternalPoly*)(data.value))->firstTerm;
+                ispoly = true; hasterms = true;
+            }
+            else
+            {
+                cursor = 0;
+                ispoly = false; hasterms = true;
+            }
+        }
+    }
+}
+
+CFIterator::~CFIterator()
+{
+    data = 0; cursor = 0;
+}
+
+CFIterator&
+CFIterator::operator= ( const CFIterator & i )
+{
+    if ( this != &i )
+    {
+        data = i.data;
+        cursor = i.cursor;
+        ispoly = i.ispoly;
+        hasterms = i.hasterms;
+    }
+    return *this;
+}
+
+CFIterator&
+CFIterator::operator= ( const CanonicalForm & f )
+{
+    if ( f.inBaseDomain() || f.inQuotDomain() )
+    {
+        data = f; cursor = 0;
+        ispoly = false; hasterms = true;
+    }
+    else
+    {
+        data = f;
+        cursor = ((InternalPoly*)(f.value))->firstTerm;
+        ispoly = true; hasterms = true;
+    }
+    return *this;
+}
diff --git a/factory/cf_iter.h b/factory/cf_iter.h
new file mode 100644
index 0000000..9e95fbd
--- /dev/null
+++ b/factory/cf_iter.h
@@ -0,0 +1,74 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+/**
+ * @file cf_iter.h
+ *
+ * Iterators for CanonicalForm's
+**/
+
+#ifndef INCL_CF_ITER_H
+#define INCL_CF_ITER_H
+
+// #include "config.h"
+
+#include "canonicalform.h"
+
+/*BEGINPUBLIC*/
+
+#undef CF_INLINE
+#define CF_INLINE
+#undef CF_NO_INLINE
+#define CF_NO_INLINE
+
+/*ENDPUBLIC*/
+
+#ifdef CF_USE_INLINE
+#undef CF_INLINE
+#define CF_INLINE inline
+#else
+#undef CF_INLINE
+#define CF_INLINE
+#endif
+
+/*BEGINPUBLIC*/
+
+class term;
+typedef term * termList;
+
+/**
+ * class to iterate through CanonicalForm's
+ *
+ * @note a (multivariate) polynomial is viewed as a univariate poly in its main
+ *       variable
+**/
+class CFIterator {
+private:
+    CanonicalForm data;
+    termList cursor;
+    bool ispoly, hasterms;
+public:
+    CFIterator ();
+    CFIterator ( const CFIterator& );
+    CFIterator ( const CanonicalForm& );
+    CFIterator ( const CanonicalForm&, const Variable& );
+
+    ~CFIterator ();
+
+    CFIterator& operator= ( const CFIterator& );
+    CFIterator& operator= ( const CanonicalForm& );
+
+    CF_NO_INLINE CFIterator& operator++ ();
+    CF_NO_INLINE CFIterator& operator++ ( int );
+    CF_NO_INLINE int hasTerms () const;       ///< check if iterator has reached
+                                              ///< the end of CanonicalForm
+    CF_NO_INLINE CanonicalForm coeff () const;///< get the current coefficient
+    CF_NO_INLINE int exp () const;            ///< get the current exponent
+};
+
+/*ENDPUBLIC*/
+
+#ifdef CF_USE_INLINE
+#include "cf_iter_inline.cc"
+#endif
+
+#endif /* ! INCL_CF_ITER_H */
diff --git a/factory/cf_iter_inline.cc b/factory/cf_iter_inline.cc
new file mode 100644
index 0000000..290edc8
--- /dev/null
+++ b/factory/cf_iter_inline.cc
@@ -0,0 +1,153 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+/**
+ *
+ * @file cf_iter_inline.cc
+ *
+ * definition of configurable inline
+ * `CFIterator' methods.
+ *
+ * Hierarchy: canonicalform, utility class
+ *
+ * Header file: cf_iter.h
+ *
+ * See `cf_inline.cc' for a description of "configurable inline
+ * methods".
+ *
+**/
+
+// check whether we are included or translated and
+// define `INCL_CF_ITER_INLINE_CC' if we are included
+#ifdef INCL_CF_ITER_H
+#define INCL_CF_ITER_INLINE_CC
+#endif
+
+
+#include "config.h"
+
+
+#include "cf_assert.h"
+
+// regular include file
+#include "canonicalform.h"
+
+// temporarily switch off `CF_USE_INLINE' and include
+// `cf_iter.h' if we are being translated.
+// `CF_USE_INLINE_SAVE' is used to save the state of
+// `CF_USE_INLINE'.  It is unset after use.
+#ifndef INCL_CF_ITER_INLINE_CC
+#ifdef CF_USE_INLINE
+#define CF_USE_INLINE_SAVE
+#undef CF_USE_INLINE
+#endif
+#include "cf_iter.h"
+#ifdef CF_USE_INLINE_SAVE
+#define CF_USE_INLINE
+#undef CF_USE_INLINE_SAVE
+#endif
+#endif /* ! INCL_CF_ITER_INLINE_CC */
+
+// more regular include files
+#include "int_cf.h"
+#include "int_poly.h"
+
+// set the value of `CF_INLINE' for the following methods and
+// functions
+#if defined( CF_USE_INLINE ) && defined( INCL_CF_ITER_INLINE_CC )
+#undef CF_INLINE
+#define CF_INLINE inline
+#else
+#undef CF_INLINE
+#define CF_INLINE
+#endif /* ! defined( CF_USE_INLINE ) && defined( INCL_CF_ITER_INLINE_CC ) */
+
+#ifndef INCL_CF_ITER_INLINE_CC
+// selectors
+/** CF_INLINE int CFIterator::hasTerms () const
+ *
+ * hasTerm() - check whether CO points to a valid term.
+ *
+ * Return true if CO points to a valid term, false if CO points
+ * to the end of the sequence of terms.
+ *
+**/
+CF_INLINE int
+CFIterator::hasTerms () const
+{
+    return hasterms;
+}
+
+/** CF_INLINE CanonicalForm CFIterator::coeff () const
+ *
+ * coeff() - return coefficient of current term of CO.
+ *
+ * CO has to point to a valid term.
+ *
+**/
+CF_INLINE CanonicalForm
+CFIterator::coeff () const
+{
+    ASSERT( hasterms, "lib error: iterator out of terms" );
+    if ( ispoly )
+        return cursor->coeff;
+    else
+        return data;
+}
+
+/** CF_INLINE int CFIterator::exp () const
+ *
+ * exp() - return exponent of current term of CO.
+ *
+ * CO has to point to a valid term.
+ *
+**/
+CF_INLINE int
+CFIterator::exp () const
+{
+    ASSERT( hasterms, "lib error: iterator out of terms" );
+    if ( ispoly )
+        return cursor->exp;
+    else
+        return 0;
+}
+
+// implementor methods
+/** CFIterator::operator ++ (), operator ++ ( int )
+ *
+ * operator ++() - advance CO to next term.
+ *
+ * Advance current term to next term in the sequence of terms or
+ * to end of sequence.  CO has to point to a valid term.
+ *
+ * The postfix and prefix operator are identical.
+ *
+**/
+CF_INLINE CFIterator &
+CFIterator::operator ++ ()
+{
+    ASSERT( hasterms, "lib error: iterator out of terms" );
+    if ( ispoly ) {
+        cursor = cursor->next;
+        hasterms = cursor != 0;
+    } else
+        hasterms = false;
+
+    return *this;
+}
+
+/**
+ * @sa CFIterator::operator
+**/
+CF_INLINE CFIterator &
+CFIterator::operator ++ ( int )
+{
+    ASSERT( hasterms, "lib error: iterator out of terms" );
+    if ( ispoly ) {
+        cursor = cursor->next;
+        hasterms = cursor != 0;
+    } else
+        hasterms = false;
+
+    return *this;
+}
+#endif
diff --git a/factory/cf_linsys.cc b/factory/cf_linsys.cc
new file mode 100644
index 0000000..9a2f391
--- /dev/null
+++ b/factory/cf_linsys.cc
@@ -0,0 +1,609 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+/**
+ * @file cf_linsys.cc
+ *
+ * solve linear systems and compute determinants of matrices
+**/
+
+#include "config.h"
+
+
+#include "cf_assert.h"
+#include "debug.h"
+#include "timing.h"
+
+#include "cf_defs.h"
+#include "cf_primes.h"
+#include "canonicalform.h"
+#include "cf_iter.h"
+#include "cf_algorithm.h"
+#include "ffops.h"
+#include "cf_primes.h"
+
+
+TIMING_DEFINE_PRINT(det_mapping)
+TIMING_DEFINE_PRINT(det_determinant)
+TIMING_DEFINE_PRINT(det_chinese)
+TIMING_DEFINE_PRINT(det_bound)
+TIMING_DEFINE_PRINT(det_numprimes)
+
+
+static bool solve ( int **extmat, int nrows, int ncols );
+int determinant ( int **extmat, int n );
+
+static CanonicalForm bound ( const CFMatrix & M );
+CanonicalForm detbound ( const CFMatrix & M, int rows );
+
+bool
+matrix_in_Z( const CFMatrix & M, int rows )
+{
+    int i, j;
+    for ( i = 1; i <= rows; i++ )
+        for ( j = 1; j <= rows; j++ )
+            if ( ! M(i,j).inZ() )
+                return false;
+    return true;
+}
+
+bool
+matrix_in_Z( const CFMatrix & M )
+{
+    int i, j, rows = M.rows(), cols = M.columns();
+    for ( i = 1; i <= rows; i++ )
+        for ( j = 1; j <= cols; j++ )
+            if ( ! M(i,j).inZ() )
+                return false;
+    return true;
+}
+
+bool
+betterpivot ( const CanonicalForm & oldpivot, const CanonicalForm & newpivot )
+{
+    if ( newpivot.isZero() )
+        return false;
+    else  if ( oldpivot.isZero() )
+        return true;
+    else  if ( level( oldpivot ) > level( newpivot ) )
+        return true;
+    else  if ( level( oldpivot ) < level( newpivot ) )
+        return false;
+    else
+        return ( newpivot.lc() < oldpivot.lc() );
+}
+
+bool fuzzy_result;
+
+bool
+linearSystemSolve( CFMatrix & M )
+{
+    typedef int* int_ptr;
+
+    if ( ! matrix_in_Z( M ) ) {
+        int nrows = M.rows(), ncols = M.columns();
+        int i, j, k;
+        CanonicalForm rowpivot, pivotrecip;
+        // triangularization
+        for ( i = 1; i <= nrows; i++ ) {
+            //find "pivot"
+            for (j = i; j <= nrows; j++ )
+                if ( M(j,i) != 0 ) break;
+            if ( j > nrows ) return false;
+            if ( j != i )
+                M.swapRow( i, j );
+            pivotrecip = 1 / M(i,i);
+            for ( j = 1; j <= ncols; j++ )
+                M(i,j) *= pivotrecip;
+            for ( j = i+1; j <= nrows; j++ ) {
+                rowpivot = M(j,i);
+                if ( rowpivot == 0 ) continue;
+                for ( k = i; k <= ncols; k++ )
+                    M(j,k) -= M(i,k) * rowpivot;
+            }
+        }
+        // matrix is now upper triangular with 1s down the diagonal
+        // back-substitute
+        for ( i = nrows-1; i > 0; i-- ) {
+            for ( j = nrows+1; j <= ncols; j++ ) {
+                for ( k = i+1; k <= nrows; k++ )
+                    M(i,j) -= M(k,j) * M(i,k);
+            }
+        }
+        return true;
+    }
+    else {
+        int rows = M.rows(), cols = M.columns();
+        CFMatrix MM( rows, cols );
+        int ** mm = new int_ptr[rows];
+        CanonicalForm Q, Qhalf, mnew, qnew, B;
+        int i, j, p, pno;
+        bool ok;
+
+        // initialize room to hold the result and the result mod p
+        for ( i = 0; i < rows; i++ ) {
+            mm[i] = new int[cols];
+        }
+
+        // calculate the bound for the result
+        B = bound( M );
+        DEBOUTLN( cerr, "bound = " <<  B );
+
+        // find a first solution mod p
+        pno = 0;
+        do {
+            DEBOUTSL( cerr );
+            DEBOUT( cerr, "trying prime(" << pno << ") = " );
+            p = cf_getBigPrime( pno );
+            DEBOUT( cerr, p );
+            DEBOUTENDL( cerr );
+            setCharacteristic( p );
+            // map matrix into char p
+            for ( i = 1; i <= rows; i++ )
+                for ( j = 1; j <= cols; j++ )
+                    mm[i-1][j-1] = mapinto( M(i,j) ).intval();
+            // solve mod p
+            ok = solve( mm, rows, cols );
+            pno++;
+        } while ( ! ok );
+
+        // initialize the result matrix with first solution
+        setCharacteristic( 0 );
+        for ( i = 1; i <= rows; i++ )
+            for ( j = rows+1; j <= cols; j++ )
+                MM(i,j) = mm[i-1][j-1];
+
+        // Q so far
+        Q = p;
+        while ( Q < B && pno < cf_getNumBigPrimes() ) {
+            do {
+                DEBOUTSL( cerr );
+                DEBOUT( cerr, "trying prime(" << pno << ") = " );
+                p = cf_getBigPrime( pno );
+                DEBOUT( cerr, p );
+                DEBOUTENDL( cerr );
+                setCharacteristic( p );
+                for ( i = 1; i <= rows; i++ )
+                    for ( j = 1; j <= cols; j++ )
+                        mm[i-1][j-1] = mapinto( M(i,j) ).intval();
+                // solve mod p
+                ok = solve( mm, rows, cols );
+                pno++;
+            } while ( ! ok );
+            // found a solution mod p
+            // now chinese remainder it to a solution mod Q*p
+            setCharacteristic( 0 );
+            for ( i = 1; i <= rows; i++ )
+                for ( j = rows+1; j <= cols; j++ )
+                {
+                    chineseRemainder( MM[i][j], Q, CanonicalForm(mm[i-1][j-1]), CanonicalForm(p), mnew, qnew );
+                    MM(i, j) = mnew;
+                }
+            Q = qnew;
+        }
+        if ( pno == cf_getNumBigPrimes() )
+            fuzzy_result = true;
+        else
+            fuzzy_result = false;
+        // store the result in M
+        Qhalf = Q / 2;
+        for ( i = 1; i <= rows; i++ ) {
+            for ( j = rows+1; j <= cols; j++ )
+                if ( MM(i,j) > Qhalf )
+                    M(i,j) = MM(i,j) - Q;
+                else
+                    M(i,j) = MM(i,j);
+            delete [] mm[i-1];
+        }
+        delete [] mm;
+        return ! fuzzy_result;
+    }
+}
+
+static bool
+fill_int_mat( const CFMatrix & M, int ** m, int rows )
+{
+    int i, j;
+    bool ok = true;
+    for ( i = 0; i < rows && ok; i++ )
+        for ( j = 0; j < rows && ok; j++ )
+        {
+            if ( M(i+1,j+1).isZero() )
+                m[i][j] = 0;
+            else
+            {
+                m[i][j] = mapinto( M(i+1,j+1) ).intval();
+//                ok = m[i][j] != 0;
+            }
+        }
+    return ok;
+}
+
+CanonicalForm
+determinant( const CFMatrix & M, int rows )
+{
+    typedef int* int_ptr;
+
+    ASSERT( rows <= M.rows() && rows <= M.columns() && rows > 0, "undefined determinant" );
+    if ( rows == 1 )
+        return M(1,1);
+    else  if ( rows == 2 )
+        return M(1,1)*M(2,2)-M(2,1)*M(1,2);
+    else  if ( matrix_in_Z( M, rows ) )
+    {
+        int ** mm = new int_ptr[rows];
+        CanonicalForm x, q, Qhalf, B;
+        int n, i, intdet, p, pno;
+        for ( i = 0; i < rows; i++ )
+        {
+            mm[i] = new int[rows];
+        }
+        pno = 0; n = 0;
+        TIMING_START(det_bound);
+        B = detbound( M, rows );
+        TIMING_END(det_bound);
+        q = 1;
+        TIMING_START(det_numprimes);
+        while ( B > q && n < cf_getNumBigPrimes() )
+        {
+            q *= cf_getBigPrime( n );
+            n++;
+        }
+        TIMING_END(det_numprimes);
+
+        CFArray X(1,n), Q(1,n);
+
+        while ( pno < n )
+        {
+            p = cf_getBigPrime( pno );
+            setCharacteristic( p );
+            // map matrix into char p
+            TIMING_START(det_mapping);
+            fill_int_mat( M, mm, rows );
+            TIMING_END(det_mapping);
+            pno++;
+            DEBOUT( cerr, "." );
+            TIMING_START(det_determinant);
+            intdet = determinant( mm, rows );
+            TIMING_END(det_determinant);
+            setCharacteristic( 0 );
+            X[pno] = intdet;
+            Q[pno] = p;
+        }
+        TIMING_START(det_chinese);
+        chineseRemainder( X, Q, x, q );
+        TIMING_END(det_chinese);
+        Qhalf = q / 2;
+        if ( x > Qhalf )
+            x = x - q;
+        for ( i = 0; i < rows; i++ )
+            delete [] mm[i];
+        delete [] mm;
+        return x;
+    }
+    else
+    {
+        CFMatrix m( M );
+        CanonicalForm divisor = 1, pivot, mji;
+        int i, j, k, sign = 1;
+        for ( i = 1; i <= rows; i++ ) {
+            pivot = m(i,i); k = i;
+            for ( j = i+1; j <= rows; j++ ) {
+                if ( betterpivot( pivot, m(j,i) ) ) {
+                    pivot = m(j,i);
+                    k = j;
+                }
+            }
+            if ( pivot.isZero() )
+                return 0;
+            if ( i != k )
+            {
+                m.swapRow( i, k );
+                sign = -sign;
+            }
+            for ( j = i+1; j <= rows; j++ )
+            {
+                if ( ! m(j,i).isZero() )
+                {
+                    divisor *= pivot;
+                    mji = m(j,i);
+                    m(j,i) = 0;
+                    for ( k = i+1; k <= rows; k++ )
+                        m(j,k) = m(j,k) * pivot - m(i,k)*mji;
+                }
+            }
+        }
+        pivot = sign;
+        for ( i = 1; i <= rows; i++ )
+            pivot *= m(i,i);
+        return pivot / divisor;
+    }
+}
+
+CanonicalForm
+determinant2( const CFMatrix & M, int rows )
+{
+    typedef int* int_ptr;
+
+    ASSERT( rows <= M.rows() && rows <= M.columns() && rows > 0, "undefined determinant" );
+    if ( rows == 1 )
+        return M(1,1);
+    else  if ( rows == 2 )
+        return M(1,1)*M(2,2)-M(2,1)*M(1,2);
+    else  if ( matrix_in_Z( M, rows ) ) {
+        int ** mm = new int_ptr[rows];
+        CanonicalForm QQ, Q, Qhalf, mnew, q, qnew, B;
+        CanonicalForm det, detnew, qdet;
+        int i, p, pcount, pno, intdet;
+        bool ok;
+
+        // initialize room to hold the result and the result mod p
+        for ( i = 0; i < rows; i++ ) {
+            mm[i] = new int[rows];
+        }
+
+        // calculate the bound for the result
+        B = detbound( M, rows );
+
+        // find a first solution mod p
+        pno = 0;
+        do {
+            p = cf_getBigPrime( pno );
+            setCharacteristic( p );
+            // map matrix into char p
+            ok = fill_int_mat( M, mm, rows );
+            pno++;
+        } while ( ! ok && pno < cf_getNumPrimes() );
+        // initialize the result matrix with first solution
+        // solve mod p
+        DEBOUT( cerr, "." );
+        intdet = determinant( mm, rows );
+        setCharacteristic( 0 );
+        det = intdet;
+        // Q so far
+        Q = p;
+        QQ = p;
+        while ( Q < B && cf_getNumPrimes() > pno ) {
+            // find a first solution mod p
+            do {
+                p = cf_getBigPrime( pno );
+                setCharacteristic( p );
+                // map matrix into char p
+                ok = fill_int_mat( M, mm, rows );
+                pno++;
+            } while ( ! ok && pno < cf_getNumPrimes() );
+            // initialize the result matrix with first solution
+            // solve mod p
+            DEBOUT( cerr, "." );
+            intdet = determinant( mm, rows );
+            setCharacteristic( 0 );
+            qdet = intdet;
+            // Q so far
+            q = p;
+            QQ *= p;
+            pcount = 0;
+            while ( QQ < B && cf_getNumPrimes() > pno && pcount < 500 ) {
+                do {
+                    p = cf_getBigPrime( pno );
+                    setCharacteristic( p );
+                    ok = true;
+                    // map matrix into char p
+                    ok = fill_int_mat( M, mm, rows );
+                    pno++;
+                } while ( ! ok && cf_getNumPrimes() > pno );
+                // solve mod p
+                DEBOUT( cerr, "." );
+                intdet = determinant( mm, rows );
+                // found a solution mod p
+                // now chinese remainder it to a solution mod Q*p
+                setCharacteristic( 0 );
+                chineseRemainder( qdet, q, intdet, p, detnew, qnew );
+                qdet = detnew;
+                q = qnew;
+                QQ *= p;
+                pcount++;
+            }
+            DEBOUT( cerr, "*" );
+            chineseRemainder( det, Q, qdet, q, detnew, qnew );
+            Q = qnew;
+            QQ = Q;
+            det = detnew;
+        }
+        if ( ! ok )
+            fuzzy_result = true;
+        else
+            fuzzy_result = false;
+        // store the result in M
+        Qhalf = Q / 2;
+        if ( det > Qhalf )
+            det = det - Q;
+        for ( i = 0; i < rows; i++ )
+            delete [] mm[i];
+        delete [] mm;
+        return det;
+    }
+    else {
+        CFMatrix m( M );
+        CanonicalForm divisor = 1, pivot, mji;
+        int i, j, k, sign = 1;
+        for ( i = 1; i <= rows; i++ ) {
+            pivot = m(i,i); k = i;
+            for ( j = i+1; j <= rows; j++ ) {
+                if ( betterpivot( pivot, m(j,i) ) ) {
+                    pivot = m(j,i);
+                    k = j;
+                }
+            }
+            if ( pivot.isZero() )
+                return 0;
+            if ( i != k ) {
+                m.swapRow( i, k );
+                sign = -sign;
+            }
+            for ( j = i+1; j <= rows; j++ ) {
+                if ( ! m(j,i).isZero() ) {
+                    divisor *= pivot;
+                    mji = m(j,i);
+                    m(j,i) = 0;
+                    for ( k = i+1; k <= rows; k++ )
+                        m(j,k) = m(j,k) * pivot - m(i,k)*mji;
+                }
+            }
+        }
+        pivot = sign;
+        for ( i = 1; i <= rows; i++ )
+            pivot *= m(i,i);
+        return pivot / divisor;
+    }
+}
+
+static CanonicalForm
+bound ( const CFMatrix & M )
+{
+    DEBINCLEVEL( cerr, "bound" );
+    int rows = M.rows(), cols = M.columns();
+    CanonicalForm sum = 0;
+    int i, j;
+    for ( i = 1; i <= rows; i++ )
+        for ( j = 1; j <= rows; j++ )
+            sum += M(i,j) * M(i,j);
+    DEBOUTLN( cerr, "bound(matrix)^2 = " << sum );
+    CanonicalForm vmax = 0, vsum;
+    for ( j = rows+1; j <= cols; j++ ) {
+        vsum = 0;
+        for ( i = 1; i <= rows; i++ )
+            vsum += M(i,j) * M(i,j);
+        if ( vsum > vmax ) vmax = vsum;
+    }
+    DEBOUTLN( cerr, "bound(lhs)^2 = " << vmax );
+    sum += vmax;
+    DEBOUTLN( cerr, "bound(overall)^2 = " << sum );
+    DEBDECLEVEL( cerr, "bound" );
+    return sqrt( sum ) + 1;
+}
+
+
+CanonicalForm
+detbound ( const CFMatrix & M, int rows )
+{
+    CanonicalForm sum = 0, prod = 2;
+    int i, j;
+    for ( i = 1; i <= rows; i++ ) {
+        sum = 0;
+        for ( j = 1; j <= rows; j++ )
+            sum += M(i,j) * M(i,j);
+        prod *= 1 + sqrt(sum);
+    }
+    return prod;
+}
+
+
+// solve returns false if computation failed
+// extmat is overwritten: output is Id mat followed by solution(s)
+
+bool
+solve ( int **extmat, int nrows, int ncols )
+{
+    DEBINCLEVEL( cerr, "solve" );
+    int i, j, k;
+    int rowpivot, pivotrecip; // all FF
+    int * rowi; // FF
+    int * rowj; // FF
+    int * swap; // FF
+    // triangularization
+    for ( i = 0; i < nrows; i++ ) {
+        //find "pivot"
+        for (j = i; j < nrows; j++ )
+            if ( extmat[j][i] != 0 ) break;
+        if ( j == nrows ) {
+            DEBOUTLN( cerr, "solve failed" );
+            DEBDECLEVEL( cerr, "solve" );
+            return false;
+        }
+        if ( j != i ) {
+            swap = extmat[i]; extmat[i] = extmat[j]; extmat[j] = swap;
+        }
+        pivotrecip = ff_inv( extmat[i][i] );
+        rowi = extmat[i];
+        for ( j = 0; j < ncols; j++ )
+            rowi[j] = ff_mul( pivotrecip, rowi[j] );
+        for ( j = i+1; j < nrows; j++ ) {
+            rowj = extmat[j];
+            rowpivot = rowj[i];
+            if ( rowpivot == 0 ) continue;
+            for ( k = i; k < ncols; k++ )
+                rowj[k] = ff_sub( rowj[k], ff_mul( rowpivot, rowi[k] ) );
+        }
+    }
+    // matrix is now upper triangular with 1s down the diagonal
+    // back-substitute
+    for ( i = nrows-1; i >= 0; i-- ) {
+        rowi = extmat[i];
+        for ( j = 0; j < i; j++ ) {
+            rowj = extmat[j];
+            rowpivot = rowj[i];
+            if ( rowpivot == 0 ) continue;
+            for ( k = i; k < ncols; k++ )
+                rowj[k] = ff_sub( rowj[k], ff_mul( rowpivot, rowi[k] ) );
+            // for (k=nrows; k<ncols; k++) rowj[k] = ff_sub(rowj[k], ff_mul(rowpivot, rowi[k]));
+        }
+    }
+    DEBOUTLN( cerr, "solve succeeded" );
+    DEBDECLEVEL( cerr, "solve" );
+    return true;
+}
+
+int
+determinant ( int **extmat, int n )
+{
+    int i, j, k;
+    int divisor, multiplier, rowii, rowji; // all FF
+    int * rowi; // FF
+    int * rowj; // FF
+    int * swap; // FF
+    // triangularization
+    multiplier = 1;
+    divisor = 1;
+
+    for ( i = 0; i < n; i++ ) {
+        //find "pivot"
+        for (j = i; j < n; j++ )
+            if ( extmat[j][i] != 0 ) break;
+        if ( j == n ) return 0;
+        if ( j != i ) {
+            multiplier = ff_neg( multiplier );
+            swap = extmat[i]; extmat[i] = extmat[j]; extmat[j] = swap;
+        }
+        rowi = extmat[i];
+        rowii = rowi[i];
+        for ( j = i+1; j < n; j++ ) {
+            rowj = extmat[j];
+            rowji = rowj[i];
+            if ( rowji == 0 ) continue;
+            divisor = ff_mul( divisor, rowii );
+            for ( k = i; k < n; k++ )
+                rowj[k] = ff_sub( ff_mul( rowj[k], rowii ), ff_mul( rowi[k], rowji ) );
+        }
+    }
+    multiplier = ff_mul( multiplier, ff_inv( divisor ) );
+    for ( i = 0; i < n; i++ )
+        multiplier = ff_mul( multiplier, extmat[i][i] );
+    return multiplier;
+}
+
+void
+solveVandermondeT ( const CFArray & a, const CFArray & w, CFArray & x, const Variable & z )
+{
+    CanonicalForm Q = 1, q, p;
+    CFIterator j;
+    int i, n = a.size();
+
+    for ( i = 1; i <= n; i++ )
+        Q *= ( z - a[i] );
+    for ( i = 1; i <= n; i++ ) {
+        q = Q / ( z - a[i] );
+        p = q / q( a[i], z );
+        x[i] = 0;
+        for ( j = p; j.hasTerms(); j++ )
+            x[i] += w[j.exp()+1] * j.coeff();
+    }
+}
diff --git a/factory/cf_map.cc b/factory/cf_map.cc
new file mode 100644
index 0000000..f8ab987
--- /dev/null
+++ b/factory/cf_map.cc
@@ -0,0 +1,411 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+/**
+ *
+ * @file cf_map.cc
+ *
+ * definition of class CFMap.
+ *
+ * Used by: cf_gcd.cc, fac_multivar.cc
+ *
+**/
+
+
+#include "config.h"
+
+
+#include "canonicalform.h"
+#include "cf_map.h"
+#include "cf_iter.h"
+#include "templates/ftmpl_functions.h"
+
+/** MapPair & MapPair::operator = ( const MapPair & p )
+ *
+ * MapPair::operator = - assignment operator.
+ *
+**/
+MapPair &
+MapPair::operator = ( const MapPair & p )
+{
+    if ( this != &p ) {
+        V = p.V;
+        S = p.S;
+    }
+    return *this;
+}
+
+#ifndef NOSTREAMIO
+/** OSTREAM & operator << ( OSTREAM & s, const MapPair & p )
+ *
+ * operator << - print a map pair ("V -> S").
+ *
+**/
+OSTREAM &
+operator << ( OSTREAM & s, const MapPair & p )
+{
+    s << p.var() << " -> " << p.subst();
+    return s;
+}
+
+void MapPair::print( OSTREAM&) const
+{
+}
+#endif /* NOSTREAMIO */
+
+/** CFMap::CFMap ( const CFList & L )
+ *
+ * CFMap::CFMap() - construct a CFMap from a CFList.
+ *
+ * Variable[i] will be mapped to CFList[i] under the resulting
+ * map.
+ *
+**/
+CFMap::CFMap ( const CFList & L )
+{
+    CFListIterator i;
+    int j;
+    for ( i = L, j = 1; i.hasItem(); i++, j++ )
+        P.insert( MapPair( Variable(j), i.getItem() ) );
+}
+
+/** CFMap & CFMap::operator = ( const CFMap & m )
+ *
+ * CFMap::operator = - assignment operator.
+ *
+**/
+CFMap &
+CFMap::operator = ( const CFMap & m )
+{
+    if ( this != &m )
+        P = m.P;
+    return *this;
+}
+
+/** static int cmpfunc ( const MapPair & p1, const MapPair & p2 )
+ *
+ * cmpfunc() - compare two map pairs.
+ *
+ * Return -1 if p2's variable is less than p1's, 0 if they are
+ * equal, 1 if p2's level is greater than p1's.
+ *
+**/
+static int
+cmpfunc ( const MapPair & p1, const MapPair & p2 )
+{
+    if ( p1.var() > p2.var() ) return -1;
+    else if ( p1.var() == p2.var() ) return 0;
+    else return 1;
+}
+
+/** static void insfunc ( MapPair & orgp, const MapPair & newp )
+ *
+ * insfunc() - assign newp to orgp.
+ *
+ * cmpfunc() and insfunc() are used as functions for inserting a
+ * map pair into a map by CFMap::newpair().
+ *
+**/
+static void
+insfunc ( MapPair & orgp, const MapPair & newp )
+{
+    orgp = newp;
+}
+
+/** void CFMap::newpair ( const Variable & v, const CanonicalForm & s )
+ *
+ * CFMap::newpair() - insert a MapPair into a CFMap.
+ *
+**/
+void
+CFMap::newpair ( const Variable & v, const CanonicalForm & s )
+{
+    P.insert( MapPair( v, s ), cmpfunc, insfunc );
+}
+
+/** static CanonicalForm subsrec ( const CanonicalForm & f, const MPListIterator & i )
+ *
+ * subsrec() - recursively apply the substitutions in i to f.
+ *
+ * Substitutes algebraic variables, too.  The substituted
+ * expression are not subject to further substitutions.
+ *
+ * Used by: CFMap::operator ()().
+ *
+**/
+static CanonicalForm
+subsrec ( const CanonicalForm & f, const MPListIterator & i )
+{
+    if ( f.inBaseDomain() ) return f;
+    MPListIterator j = i;
+
+    // skip MapPairs larger than the main variable of f
+    while ( j.hasItem() && j.getItem().var() > f.mvar() ) j++;
+
+    if ( j.hasItem() )
+        if ( j.getItem().var() != f.mvar() ) {
+            // simply descend if the current MapPair variable is
+            // not the main variable of f
+            CanonicalForm result = 0;
+            CFIterator I;
+            for ( I = f; I.hasTerms(); I++ )
+                result += power( f.mvar(), I.exp() ) * subsrec( I.coeff(), j );
+            return result;
+        }
+        else {
+            // replace the main variable of f with the image of
+            // the current variable under MapPair
+            CanonicalForm result = 0;
+            CanonicalForm s = j.getItem().subst();
+            CFIterator I;
+            // move on to the next MapPair
+            j++;
+            for ( I = f; I.hasTerms(); I++ )
+                result += subsrec( I.coeff(), j ) * power( s, I.exp() );
+            return result;
+        }
+    else
+        return f;
+}
+
+/** CanonicalForm CFMap::operator () ( const CanonicalForm & f ) const
+ *
+ * CFMap::operator () - apply CO to f.
+ *
+ * See subsrec() for more detailed information.
+ *
+**/
+CanonicalForm
+CFMap::operator () ( const CanonicalForm & f ) const
+{
+    MPListIterator i = P;
+    return subsrec( f, i );
+}
+
+#ifndef NOSTREAMIO
+/** OSTREAM & operator << ( OSTREAM & s, const CFMap & m )
+ *
+ * operator << - print a CFMap ("( V[1] -> S[1], ..., V[n] ->  * S[n] )".
+ *
+**/
+OSTREAM &
+operator << ( OSTREAM & s, const CFMap & m )
+{
+    m.P.print(s);
+    return s;
+}
+#endif /* NOSTREAMIO */
+
+/** CanonicalForm compress ( const CanonicalForm & f, CFMap & m )
+ *
+ * compress() - compress the canonical form f.
+ *
+ * Compress the polynomial f such that the levels of its
+ * polynomial variables are ordered without any gaps starting
+ * from level 1.  Return the compressed polynomial and a map m to
+ * undo the compression.  That is, if f' = compress(f, m), than f
+ * = m(f').
+ *
+**/
+CanonicalForm
+compress ( const CanonicalForm & f, CFMap & m )
+{
+    CanonicalForm result = f;
+    int i, n;
+    int * degs = degrees( f );
+
+    m = CFMap();
+    n = i = 1;
+    while ( i <= level( f ) ) {
+        while( degs[i] == 0 ) i++;
+        if ( i != n ) {
+            // swap variables and remember the swap in the map
+            m.newpair( Variable( n ), Variable( i ) );
+            result = swapvar( result, Variable( i ), Variable( n ) );
+        }
+        n++; i++;
+    }
+    delete [] degs;
+    return result;
+}
+
+/** void compress ( const CFArray & a, CFMap & M, CFMap & N )
+ *
+ * compress() - compress the variables occuring in an a.
+ *
+ * Compress the polynomial variables occuring in a so that their
+ * levels are ordered without any gaps starting from level 1.
+ * Return the CFMap M to realize the compression and its inverse,
+ * the CFMap N.  Note that if you compress a member of a using M
+ * the result of the compression is not necessarily compressed,
+ * since the map is constructed using all variables occuring in
+ * a.
+ *
+**/
+void
+compress ( const CFArray & a, CFMap & M, CFMap & N )
+{
+    M = N = CFMap();
+    if ( a.size() == 0 )
+        return;
+    int maxlevel = level( a[a.min()] );
+    int i, j;
+
+    // get the maximum of levels in a
+    for ( i = a.min() + 1; i <= a.max(); i++ )
+        if ( level( a[i] ) > maxlevel )
+            maxlevel = level( a[i] );
+    if ( maxlevel <= 0 )
+        return;
+
+    int * degs = new int[maxlevel+1];
+    int * tmp = new int[maxlevel+1];
+    for ( i = 1; i <= maxlevel; i++ )
+        degs[i] = 0;
+
+    // calculate the union of all levels occuring in a
+    for ( i = a.min(); i <= a.max(); i++ ) {
+        tmp = degrees( a[i], tmp );
+        for ( j = 1; j <= level( a[i] ); j++ )
+            if ( tmp[j] != 0 )
+                degs[j] = 1;
+    }
+
+    // create the maps
+    i = 1; j = 1;
+    while ( i <= maxlevel ) {
+        if ( degs[i] != 0 ) {
+            M.newpair( Variable(i), Variable(j) );
+            N.newpair( Variable(j), Variable(i) );
+            j++;
+        }
+        i++;
+    }
+    delete [] tmp;
+    delete [] degs;
+}
+
+/*
+*  compute positions p1 and pe of optimal variables:
+*    pe is used in "ezgcd" and
+*    p1 in "gcd_poly1"
+*/
+static
+void optvalues ( const int * df, const int * dg, const int n, int & p1, int &pe )
+{
+    int i, o1, oe;
+    i = p1 = pe = 0;
+    do
+    {
+        i++;
+        if ( i > n ) return;
+    } while ( ( df[i] == 0 ) || ( dg[i] == 0 ) );
+    p1 = pe = i;
+    if ( df[i] > dg[i] )
+    {
+        o1 = df[i]; oe = dg[i];
+    }
+    else
+    {
+        o1 = dg[i]; oe = df[i];
+    }
+    while ( i < n )
+    {
+        i++;
+        if ( ( df[i] != 0 ) && ( dg[i] != 0 ) )
+        {
+            if ( df[i] > dg[i] )
+            {
+                if ( o1 >= df[i]) { o1 = df[i]; p1 = i; }
+                if ( oe < dg[i]) { oe = dg[i]; pe = i; }
+            }
+            else
+            {
+                if ( o1 >= dg[i]) { o1 = dg[i]; p1 = i; }
+                if ( oe < df[i]) { oe = df[i]; pe = i; }
+            }
+        }
+    }
+}
+
+
+/** void compress ( const CanonicalForm & f, const CanonicalForm & g, CFMap & M, CFMap & N )
+ *
+ * compress() - compress the variables occurring in f and g with respect
+ * to optimal variables
+ *
+ * Compress the polynomial variables occurring in f and g so that
+ * the levels of variables common to f and g are ordered without
+ * any gaps starting from level 1, whereas the variables occuring
+ * in only one of f or g are moved to levels higher than the
+ * levels of the common variables.  Return the CFMap M to realize
+ * the compression and its inverse, the CFMap N.
+ * N needs only variables common to f and g.
+ *
+**/
+void
+compress ( const CanonicalForm & f, const CanonicalForm & g, CFMap & M, CFMap & N )
+{
+    int n = tmax( f.level(), g.level() );
+    int i, k, p1, pe;
+    int * degsf = new int[n+1];
+    int * degsg = new int[n+1];
+
+    for ( i = 0; i <= n; i++ )
+    {
+        degsf[i] = degsg[i] = 0;
+    }
+
+    degsf = degrees( f, degsf );
+    degsg = degrees( g, degsg );
+    optvalues( degsf, degsg, n, p1, pe );
+
+    i = 1; k = 1;
+    if ( pe > 1 )
+    {
+        M.newpair( Variable(pe), Variable(k) );
+        N.newpair( Variable(k), Variable(pe) );
+        k++;
+    }
+    while ( i <= n )
+    {
+        if ( degsf[i] > 0 && degsg[i] > 0 )
+        {
+            if ( ( i != k ) && ( i != pe ) && ( i != p1 ) )
+            {
+                M.newpair( Variable(i), Variable(k) );
+                N.newpair( Variable(k), Variable(i) );
+            }
+            k++;
+        }
+        i++;
+    }
+    if ( p1 != pe )
+    {
+        M.newpair( Variable(p1), Variable(k) );
+        N.newpair( Variable(k), Variable(p1) );
+        k++;
+    }
+    i = 1;
+    while ( i <= n )
+    {
+        if ( degsf[i] > 0 && degsg[i] == 0 ) {
+            if ( i != k )
+            {
+                M.newpair( Variable(i), Variable(k) );
+                k++;
+            }
+        }
+        else if ( degsf[i] == 0 && degsg[i] > 0 )
+        {
+            if ( i != k )
+            {
+                M.newpair( Variable(i), Variable(k) );
+                k++;
+            }
+        }
+        i++;
+    }
+
+    delete [] degsf;
+    delete [] degsg;
+}
diff --git a/factory/cf_map.h b/factory/cf_map.h
new file mode 100644
index 0000000..21f2c16
--- /dev/null
+++ b/factory/cf_map.h
@@ -0,0 +1,110 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+#ifndef INCL_CF_MAP_H
+#define INCL_CF_MAP_H
+
+/**
+ * @file cf_map.h
+ *
+ * map polynomials
+ *
+**/
+
+// #include "config.h"
+
+#ifndef NOSTREAMIO
+#ifdef HAVE_IOSTREAM
+#include <iostream>
+#define OSTREAM std::ostream
+#elif defined(HAVE_IOSTREAM_H)
+#include <iostream.h>
+#define OSTREAM ostream
+#endif
+#endif /* NOSTREAMIO */
+
+#include "variable.h"
+#include "canonicalform.h"
+#include <factory/templates/ftmpl_list.h>
+
+/*BEGINPUBLIC*/
+
+/** class MapPair
+ *
+ * class MapPair - stores one mapping pair (Variable -> CanonicalForm).
+ *
+ * This class is only used to store such pairs.  It has no
+ * methods to transform a CanonicalForm as the class CFMap has.
+ *
+ * V, S: the pair (V -> S)
+ *
+**/
+/** inline method
+ *
+ * Variable var () const
+ * CanonicalForm subst () const
+ *
+ * var(), subst() - selectors, return V and P, resp.
+ *
+**/
+class MapPair
+{
+private:
+    Variable V;
+    CanonicalForm S;
+public:
+    MapPair ( const Variable & v, const CanonicalForm & s ) : V(v), S(s) {}
+    MapPair () : V(), S(1) {}
+    MapPair ( const MapPair & p ) : V(p.V), S(p.S) {}
+    ~MapPair () {}
+    MapPair & operator = ( const MapPair & p );
+    Variable var () const { return V; }
+    CanonicalForm subst () const { return S; }
+#ifndef NOSTREAMIO
+    void print( OSTREAM&) const;
+    friend OSTREAM & operator << ( OSTREAM & s, const MapPair & p );
+#endif /* NOSTREAMIO */
+};
+
+typedef List<MapPair> MPList;
+typedef ListIterator<MapPair> MPListIterator;
+
+/** class CFMap
+ *
+ * class CFMap - class to map canonical forms.
+ *
+ * Use an object of class CFMap to insert 'values' into canonical
+ * form.  Such a mapping is defined by a list of MapPairs (V -> S)
+ * describing which canonical form S to insert for variable V.
+ * Hereby, the substituted canonical forms are not subject to
+ * further substitutions.
+ *
+ * P: list of MapPairs, sorted by level in descending order
+ *
+**/
+class CFMap
+{
+private:
+  MPList P;
+public:
+  CFMap () {}
+  CFMap ( const CanonicalForm & s ) : P( MapPair( Variable(), s ) ) {}
+  CFMap ( const Variable & v ) : P( MapPair( v, 1 ) ) {}
+  CFMap ( const Variable & v, const CanonicalForm & s ) : P( MapPair( v, s ) ) {}
+  ~CFMap () {}
+  CFMap ( const CFList & L );
+  CFMap ( const CFMap & m ) : P( m.P ) {}
+  CFMap & operator = ( const CFMap & m );
+  void newpair ( const Variable & v, const CanonicalForm & s );
+  CanonicalForm operator () ( const CanonicalForm & f ) const;
+#ifndef NOSTREAMIO
+  friend OSTREAM & operator << ( OSTREAM & s, const CFMap & m );
+#endif /* NOSTREAMIO */
+};
+
+CanonicalForm compress ( const CanonicalForm & f, CFMap & m );
+void compress ( const CFArray & a, CFMap & M, CFMap & N );
+void compress ( const CanonicalForm & f, const CanonicalForm & g, CFMap & M, CFMap & N );
+
+/*ENDPUBLIC*/
+
+#endif /* ! INCL_CF_MAP_H */
diff --git a/factory/cf_map_ext.cc b/factory/cf_map_ext.cc
new file mode 100644
index 0000000..c09860e
--- /dev/null
+++ b/factory/cf_map_ext.cc
@@ -0,0 +1,469 @@
+// -*- c++ -*-
+//*****************************************************************************
+/** @file cf_map_ext.cc
+ *
+ * This file implements functions to map between extensions of finite fields
+ *
+ * @par Copyright:
+ *   (c) by The SINGULAR Team, see LICENSE file
+ *
+ * @author Martin Lee
+ * @date   16.11.2009
+**/
+//*****************************************************************************
+
+
+#include "config.h"
+
+
+#include "cf_assert.h"
+#include "debug.h"
+
+#include "canonicalform.h"
+#include "cf_util.h"
+#include "imm.h"
+#include "cf_iter.h"
+
+#ifdef HAVE_NTL
+#include "NTLconvert.h"
+#endif
+
+// cyclotomoic polys:
+#include "cf_cyclo.h"
+
+#include "cf_map_ext.h"
+
+/// helper function
+int findItem (const CFList& list, const CanonicalForm& item)
+{
+  int result= 1;
+  for (CFListIterator i= list; i.hasItem(); i++, result++)
+  {
+    if (i.getItem() == item)
+      return result;
+  }
+  return 0;
+}
+
+/// helper function
+CanonicalForm getItem (const CFList& list, const int& pos)
+{
+  int j= 1;
+  if ((pos > 0) && (pos <= list.length()))
+  {
+    for (CFListIterator i= list; j <= pos; i++, j++)
+    {
+      if (j == pos)
+        return i.getItem();
+    }
+  }
+  return 0;
+}
+
+#ifdef HAVE_NTL
+/// \f$ F_{p} (\alpha ) \subset F_{p}(\beta ) \f$ and \f$ \alpha \f$ is a
+/// primitive element, returns the image of \f$ \alpha \f$
+static inline
+CanonicalForm mapUp (const Variable& alpha, const Variable& beta)
+{
+  int p= getCharacteristic ();
+  if (fac_NTL_char != p)
+  {
+    fac_NTL_char= p;
+    zz_p::init (p);
+  }
+  zz_pX NTL_mipo= convertFacCF2NTLzzpX (getMipo (beta));
+  zz_pE::init (NTL_mipo);
+  zz_pEX NTL_alpha_mipo= convertFacCF2NTLzz_pEX (getMipo(alpha), NTL_mipo);
+  zz_pE root= FindRoot (NTL_alpha_mipo);
+  return convertNTLzzpE2CF (root, beta);
+}
+
+#endif
+
+/// the CanonicalForm G is the output of map_up, returns F considered as an
+/// element over \f$ F_{p}(\alpha ) \f$, WARNING: make sure coefficients of F
+/// are really elements of a subfield of \f$ F_{p}(\beta ) \f$ which is
+/// isomorphic to \f$ F_{p}(\alpha ) \f$
+static inline
+CanonicalForm
+mapDown (const CanonicalForm& F, const Variable& alpha, const
+          CanonicalForm& G, CFList& source, CFList& dest)
+{
+  CanonicalForm buf, buf2;
+  int counter= 0;
+  int pos;
+  int p= getCharacteristic();
+  int d= degree(getMipo(alpha));
+  int bound= ipower(p, d);
+  CanonicalForm result= 0;
+  CanonicalForm remainder;
+  CanonicalForm alpha_power;
+  if (degree(F) == 0) return F;
+  if (F.level() < 0 && F.isUnivariate())
+  {
+    buf= F;
+    remainder= mod (buf, G);
+    ASSERT (remainder.isZero(), "alpha is not primitive");
+    pos= findItem (source, buf);
+    if (pos == 0)
+      source.append (buf);
+    buf2= buf;
+    while (degree (buf) != 0 && counter < bound)
+    {
+      buf /= G;
+      counter++;
+      if (buf == buf2) break;
+    }
+    ASSERT (counter >= bound, "alpha is not primitive");
+    if (pos == 0)
+    {
+      alpha_power= power (alpha, counter);
+      dest.append (alpha_power);
+    }
+    else
+      alpha_power= getItem (dest, pos);
+    result = alpha_power;
+    return result;
+  }
+  else
+  {
+    for (CFIterator i= F; i.hasTerms(); i++)
+    {
+      buf= mapDown (i.coeff(), alpha, G, source, dest);
+      result += buf*power(F.mvar(), i.exp());
+    }
+    return result;
+  }
+}
+
+/// helper function
+static inline
+CanonicalForm GF2FalphaHelper (const CanonicalForm& F, const Variable& alpha)
+{
+  if (F.isZero())
+    return 0;
+  int exp;
+  CanonicalForm result= 0;
+  InternalCF* buf;
+  if (F.inBaseDomain())
+  {
+    if (F.isOne()) return 1;
+    buf= F.getval();
+    exp= imm2int(buf);
+    result= power (alpha, exp).mapinto();
+    return result;
+  }
+  for (CFIterator i= F; i.hasTerms(); i++)
+    result += GF2FalphaHelper (i.coeff(), alpha)*power (F.mvar(), i.exp());
+  return result;
+}
+
+CanonicalForm GF2FalphaRep (const CanonicalForm& F, const Variable& alpha)
+{
+  Variable beta= rootOf (gf_mipo);
+  CanonicalForm result= GF2FalphaHelper (F, beta) (alpha, beta);
+  prune (beta);
+  return result;
+}
+
+CanonicalForm Falpha2GFRep (const CanonicalForm& F)
+{
+  CanonicalForm result= 0;
+  InternalCF* buf;
+
+  if (F.inCoeffDomain())
+  {
+    if (F.inBaseDomain())
+      return F.mapinto();
+    else
+    {
+      for (CFIterator i= F; i.hasTerms(); i++)
+      {
+        buf= int2imm_gf (i.exp());
+        result += i.coeff().mapinto()*CanonicalForm (buf);
+      }
+    }
+    return result;
+  }
+  for (CFIterator i= F; i.hasTerms(); i++)
+    result += Falpha2GFRep (i.coeff())*power (F.mvar(), i.exp());
+  return result;
+}
+
+/// GF_map_up helper
+static inline
+CanonicalForm GFPowUp (const CanonicalForm & F, int k)
+{
+  if (F.isOne()) return F;
+  CanonicalForm result= 0;
+  if (F.inBaseDomain())
+    return power(F, k);
+  for (CFIterator i= F; i.hasTerms(); i++)
+    result += GFPowUp (i.coeff(), k)*power (F.mvar(), i.exp());
+  return result;
+}
+
+CanonicalForm GFMapUp (const CanonicalForm & F, int k)
+{
+  int d= getGFDegree();
+  ASSERT (d%k == 0, "multiple of GF degree expected");
+  int p= getCharacteristic();
+  int ext_field_size= ipower (p, d);
+  int field_size= ipower ( p, k);
+  int diff= (ext_field_size - 1)/(field_size - 1);
+  return GFPowUp (F, diff);
+}
+
+/// GFMapDown helper
+static inline
+CanonicalForm GFPowDown (const CanonicalForm & F, int k)
+{
+  if (F.isOne()) return F;
+  CanonicalForm result= 0;
+  int exp;
+  InternalCF* buf;
+  if (F.inBaseDomain())
+  {
+    buf= F.getval();
+    exp= imm2int (buf);
+    if ((exp % k) == 0)
+      exp= exp/k;
+    else
+      return -1;
+
+    buf= int2imm_gf (exp);
+    return CanonicalForm (buf);
+  }
+  for (CFIterator i= F; i.hasTerms(); i++)
+    result += GFPowDown (i.coeff(), k)*power (F.mvar(), i.exp());
+  return result;
+}
+
+CanonicalForm GFMapDown (const CanonicalForm & F, int k)
+{
+  int d= getGFDegree();
+  ASSERT (d % k == 0, "multiple of GF degree expected");
+  int p= getCharacteristic();
+  int ext_field_size= ipower (p, d);
+  int field_size= ipower ( p, k);
+  int diff= (ext_field_size - 1)/(field_size - 1);
+  return GFPowDown (F, diff);
+}
+
+/// map F in \f$ F_{p} (\alpha ) \f$ which is generated by G into some
+/// \f$ F_{p}(\beta ) \f$ which is generated by H
+static inline
+CanonicalForm mapUp (const CanonicalForm& F, const CanonicalForm& G,
+                      const Variable& alpha, const CanonicalForm& H,
+                      CFList& source, CFList& dest)
+{
+  CanonicalForm buf, buf2;
+  int counter= 0;
+  int pos;
+  int p= getCharacteristic();
+  int d= degree (getMipo(alpha));
+  int bound= ipower(p, d);
+  CanonicalForm result= 0;
+  CanonicalForm remainder;
+  CanonicalForm H_power;
+  if (degree(F) <= 0) return F;
+  if (F.level() < 0 && F.isUnivariate())
+  {
+    buf= F;
+    remainder= mod (buf, G);
+    ASSERT (remainder.isZero(), "alpha is not primitive");
+    pos= findItem (source, buf);
+    if (pos == 0)
+      source.append (buf);
+    buf2= buf;
+    while (degree (buf) != 0 && counter < bound)
+    {
+      buf /= G;
+      counter++;
+      if (buf == buf2) break;
+    }
+    ASSERT (counter <= bound, "alpha is not primitive");
+    if (pos == 0)
+    {
+      H_power= buf*power (H, counter);
+      dest.append (H_power);
+    }
+    else
+      H_power= getItem (dest, pos);
+    result = H_power;
+    return result;
+  }
+  else
+  {
+    for (CFIterator i= F; i.hasTerms(); i++)
+    {
+      buf= mapUp (i.coeff(), G, alpha, H, source, dest);
+      result += buf*power(F.mvar(), i.exp());
+    }
+    return result;
+  }
+}
+
+#ifdef HAVE_NTL
+CanonicalForm
+primitiveElement (const Variable& alpha, Variable& beta, bool& fail)
+{
+  bool primitive= false;
+  fail= false;
+  primitive= isPrimitive (alpha, fail);
+  if (fail)
+    return 0;
+  if (primitive)
+  {
+    beta= alpha;
+    return alpha;
+  }
+  CanonicalForm mipo= getMipo (alpha);
+  int d= degree (mipo);
+  int p= getCharacteristic ();
+  if (fac_NTL_char != p)
+  {
+    fac_NTL_char= p;
+    zz_p::init (p);
+  }
+  zz_pX NTL_mipo;
+  CanonicalForm mipo2;
+  primitive= false;
+  fail= false;
+  bool initialized= false;
+  do
+  {
+    BuildIrred (NTL_mipo, d);
+    mipo2= convertNTLzzpX2CF (NTL_mipo, Variable (1));
+    if (!initialized)
+      beta= rootOf (mipo2);
+    else
+      setMipo (beta, mipo2);
+    primitive= isPrimitive (beta, fail);
+    if (primitive)
+      break;
+    if (fail)
+      return 0;
+  } while (1);
+  zz_pX alpha_mipo= convertFacCF2NTLzzpX (mipo);
+  zz_pE::init (alpha_mipo);
+  zz_pEX NTL_beta_mipo= to_zz_pEX (NTL_mipo);
+  zz_pE root= FindRoot (NTL_beta_mipo);
+  return convertNTLzzpE2CF (root, alpha);
+}
+#endif
+
+CanonicalForm
+mapDown (const CanonicalForm& F, const CanonicalForm& prim_elem, const
+          CanonicalForm& im_prim_elem, const Variable& alpha, CFList& source,
+          CFList& dest)
+{
+  return mapUp (F, im_prim_elem, alpha, prim_elem, dest, source);
+}
+
+CanonicalForm
+mapUp (const CanonicalForm& F, const Variable& alpha, const Variable& /*beta*/,
+        const CanonicalForm& prim_elem, const CanonicalForm& im_prim_elem,
+        CFList& source, CFList& dest)
+{
+  if (prim_elem == alpha)
+    return F (im_prim_elem, alpha);
+  return mapUp (F, prim_elem, alpha, im_prim_elem, source, dest);
+}
+
+#ifdef HAVE_NTL
+CanonicalForm
+mapPrimElem (const CanonicalForm& primElem, const Variable& alpha,
+             const Variable& beta)
+{
+  if (primElem == alpha)
+    return mapUp (alpha, beta);
+  else
+  {
+    CanonicalForm primElemMipo= findMinPoly (primElem, alpha);
+    int p= getCharacteristic ();
+    if (fac_NTL_char != p)
+    {
+      fac_NTL_char= p;
+      zz_p::init (p);
+    }
+    zz_pX NTLMipo= convertFacCF2NTLzzpX (getMipo (beta));
+    zz_pE::init (NTLMipo);
+    zz_pEX NTLPrimElemMipo= convertFacCF2NTLzz_pEX (primElemMipo, NTLMipo);
+    zz_pE root= FindRoot (NTLPrimElemMipo);
+    return convertNTLzzpE2CF (root, beta);
+  }
+}
+
+CanonicalForm
+map (const CanonicalForm& primElem, const Variable& alpha,
+     const CanonicalForm& F, const Variable& beta)
+{
+  CanonicalForm G= F;
+  int order= 0;
+  while (!G.isOne())
+  {
+    G /= primElem;
+    order++;
+  }
+  int p= getCharacteristic ();
+  if (fac_NTL_char != p)
+  {
+    fac_NTL_char= p;
+    zz_p::init (p);
+  }
+  zz_pX NTL_mipo= convertFacCF2NTLzzpX (getMipo (beta));
+  zz_pE::init (NTL_mipo);
+  zz_pEX NTL_alpha_mipo= convertFacCF2NTLzz_pEX (getMipo(alpha), NTL_mipo);
+  zz_pE NTLBeta= to_zz_pE (convertFacCF2NTLzzpX (beta));
+  vec_zz_pE roots= FindRoots (NTL_alpha_mipo);
+  long ind=-1;
+  for (long i= 0; i < roots.length(); i++)
+  {
+    if (power (roots [i], order)== NTLBeta)
+    {
+      ind= i;
+      break;
+    }
+  }
+  return (convertNTLzzpE2CF (roots[ind], beta));
+}
+
+CanonicalForm
+findMinPoly (const CanonicalForm& F, const Variable& alpha)
+{
+  ASSERT (F.isUnivariate() && F.mvar()==alpha,"expected element of F_p(alpha)");
+
+  if (fac_NTL_char != getCharacteristic())
+  {
+    fac_NTL_char= getCharacteristic();
+    zz_p::init (getCharacteristic());
+  }
+  zz_pX NTLF= convertFacCF2NTLzzpX (F);
+  int d= degree (getMipo (alpha));
+
+  zz_pX NTLMipo= convertFacCF2NTLzzpX (getMipo(alpha));
+  zz_pE::init (NTLMipo);
+  vec_zz_p pows;
+  pows.SetLength (2*d);
+
+  zz_pE powNTLF;
+  set (powNTLF);
+  zz_pE NTLFE= to_zz_pE (NTLF);
+  zz_pX buf;
+  for (int i= 0; i < 2*d; i++)
+  {
+    buf= rep (powNTLF);
+    buf.rep.SetLength (d);
+    pows [i]= buf.rep[0];
+    powNTLF *= NTLFE;
+  }
+
+  zz_pX NTLMinPoly;
+  MinPolySeq (NTLMinPoly, pows, d);
+
+  return convertNTLzzpX2CF (NTLMinPoly, Variable (1));
+}
+
+#endif
diff --git a/factory/cf_map_ext.h b/factory/cf_map_ext.h
new file mode 100644
index 0000000..e1fa159
--- /dev/null
+++ b/factory/cf_map_ext.h
@@ -0,0 +1,116 @@
+// -*- c++ -*-
+//*****************************************************************************
+/** @file cf_map_ext.h
+ *
+ * This file implements functions to map between extensions of finite fields
+ *
+ * @par Copyright:
+ *   (c) by The SINGULAR Team, see LICENSE file
+ *
+ * @author Martin Lee
+ * @date   16.11.2009
+**/
+//*****************************************************************************
+
+#ifndef CF_MAP_EXT_H
+#define CF_MAP_EXT_H
+
+// #include "config.h"
+
+int findItem (const CFList& list, const CanonicalForm& item);
+
+CanonicalForm getItem (const CFList& list, const int& pos);
+
+/// maps a polynomial over \f$ GF(p^{k}) \f$ to a polynomial over
+/// \f$ GF(p^{d}) \f$ , d needs to be a multiple of k
+CanonicalForm GFMapUp (const CanonicalForm & F, int k);
+
+/// maps a polynomial over \f$ GF(p^{d}) \f$ to a polynomial over
+/// \f$ GF(p^{k})\f$ , d needs to be a multiple of k
+CanonicalForm GFMapDown (const CanonicalForm & F, int k);
+
+/// map F from \f$ F_{p} (\alpha ) \f$ to \f$ F_{p}(\beta ) \f$.
+/// We assume \f$ F_{p} (\alpha ) \subset F_{p}(\beta ) \f$.
+CanonicalForm
+mapUp (const CanonicalForm& F,           ///<[in] poly over \f$ F_{p} (\alpha ) \f$
+       const Variable& alpha,            ///<[in] alg. variable
+       const Variable& beta,             ///<[in] alg. variable
+       const CanonicalForm& prim_elem,   ///<[in] primitive element of \f$ F_{p} (\alpha ) \f$
+       const CanonicalForm& im_prim_elem,///<[in] image of prim_elem in \f$ F_{p} (\beta ) \f$
+       CFList& source,                   ///<[in,out] look up lists
+       CFList& dest                      ///<[in,out] look up lists
+      );
+
+/// map F from \f$ F_{p} (\beta ) \f$ to \f$ F_{p}(\alpha ) \f$.
+/// We assume \f$ F_{p} (\alpha ) \subset F_{p}(\beta ) \f$ and F in
+/// \f$ F_{p}(\alpha ) \f$.
+CanonicalForm
+mapDown (const CanonicalForm& F,           ///<[in] poly over \f$ F_{p} (\beta ) \f$
+         const CanonicalForm& prim_elem,   ///<[in] primitive element of \f$ F_{p} (\alpha ) \f$
+         const CanonicalForm& im_prim_elem,///<[in] image of prim_elem in \f$ F_{p} (\beta ) \f$
+         const Variable& alpha,            ///<[in] alg. variable
+         CFList& source,                   ///<[in,out] look up lists
+         CFList& dest                      ///<[in,out] look up lists
+        );
+
+/// determine a primitive element of \f$ F_{p} (\alpha ) \f$,
+/// \f$ \beta \f$ is a primitive element of a field which is isomorphic to
+/// \f$ F_{p}(\alpha ) \f$
+CanonicalForm
+primitiveElement (const Variable& alpha, ///< [in] some algebraic variable
+                  Variable& beta,        ///< [in,out] s.a.
+                  bool& fail             ///< [in,out] failure due to integer
+                                         ///< factorization failure?
+                 );
+
+/// compute the image of a primitive element of \f$ F_{p} (\alpha ) \f$
+/// in \f$ F_{p}(\beta ) \f$.
+/// We assume \f$ F_{p} (\alpha ) \subset F_{p}(\beta ) \f$.
+CanonicalForm
+mapPrimElem (const CanonicalForm& prim_elem, ///< [in] primitive element
+             const Variable& alpha,          ///< [in] algebraic variable
+             const Variable& beta            ///< [in] algebraic variable
+            );
+
+/// changes representation by primitive element to representation by residue
+/// classes modulo a Conway polynomial
+CanonicalForm GF2FalphaRep (const CanonicalForm& F, ///< [in] some poly over GF
+                            const Variable& alpha   ///< [in] root of a Conway
+                                                    ///< poly
+                           );
+
+/// change representation by residue classes modulo a Conway polynomial
+/// to representation by primitive element
+CanonicalForm Falpha2GFRep (const CanonicalForm& F ///<[in] some poly over
+                                                   ///< F_p(alpha) where alpha
+                                                   ///< is a root of a Conway
+                                                   ///< poly
+                           );
+
+/// map from \f$ F_p(\alpha) \f$ to \f$ F_p(\beta) \f$ such that
+/// \f$ F\in F_p(\alpha) \f$ is mapped onto \f$ \beta \f$
+///
+/// @return @a map returns the image of @a primElem such that the above
+/// described properties hold
+CanonicalForm
+map (const CanonicalForm& primElem,///< [in] primitive element of
+                                   ///< \f$ F_p (\alpha) \f$
+     const Variable& alpha,        ///< [in] algebraic variable
+     const CanonicalForm& F,       ///< [in] an element of \f$ F_p (\alpha) \f$,
+                                   ///< whose minimal polynomial defines a field
+                                   ///< extension of \f$ F_p \f$ of degree
+                                   ///< \f$ F_p (\alpha):F_p \f$
+     const Variable& beta          ///< [in] algebraic variable, root of \a F's
+                                   ///< minimal polynomial
+    );
+
+/// compute minimal polynomial of \f$ F\in F_p(\alpha)\backslash F_p \f$ via NTL
+///
+/// @return @a findMinPoly computes the minimal polynomial of F
+CanonicalForm
+findMinPoly (const CanonicalForm& F, ///< [in] an element of
+                                     ///< \f$ F_p(\alpha)\backslash F_p \f$
+             const Variable& alpha   ///< [in] algebraic variable
+            );
+
+#endif
diff --git a/factory/cf_ops.cc b/factory/cf_ops.cc
new file mode 100644
index 0000000..e41e606
--- /dev/null
+++ b/factory/cf_ops.cc
@@ -0,0 +1,695 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+/**
+ *
+ * @file cf_ops.cc
+ *
+ * simple structural algorithms.
+ *
+ * A 'structural' algorithm is an algorithm which gives
+ * structural information on polynomials in contrast to a
+ * 'mathematical' algorithm which calculates some mathematical
+ * function.
+ *
+ * Compare these functions with the functions in cf_algorithm.cc,
+ * which are mathematical algorithms.
+ *
+ *
+ * Header file: canonicalform.h
+ *
+**/
+
+
+#include "config.h"
+
+
+#include "cf_assert.h"
+
+#include "canonicalform.h"
+#include "variable.h"
+#include "cf_iter.h"
+
+/** static Variable sv_x1, sv_x2;
+ *
+ * sv_x1, sv_x2 - variables to swap by swapvar() and replacevar.
+ *
+ * These variables are initialized by swapvar() such that sv_x1 <
+ * sv_x2.  They are used by swapvar_between() and swapvar_rec()
+ * to swap variables efficiently.
+ * Furthermore, sv_x1 and sv_x2 are used by replacevar() and
+ * replacevar_between().
+ *
+**/
+static Variable sv_x1, sv_x2;
+
+/** static void swapvar_between ( const CanonicalForm & f, CanonicalForm & result, const CanonicalForm & term, int expx2 )
+ *
+ * swapvar_between() - replace occurences of sv_x1 in f with sv_x2.
+ *
+ * If Psi denotes the map which maps sv_x1 to sv_x2, this
+ * function returns
+ *
+ *   result + Psi(f) * term * sv_x1^expx2
+ *
+ * Used by: swapvar()
+ *
+**/
+static void
+swapvar_between ( const CanonicalForm & f, CanonicalForm & result, const CanonicalForm & term, int expx2 )
+{
+    if ( f.inCoeffDomain() || f.mvar() < sv_x1 )
+        // in this case, we do not have to replace anything
+        result += term * power( sv_x1, expx2 ) * f;
+    else  if ( f.mvar() == sv_x1 )
+        // this is where the real work is done: this iterator
+        // replaces sv_x1 with sv_x2
+        for ( CFIterator i = f; i.hasTerms(); i++ )
+            result += power( sv_x2, i.exp() ) * term * power( sv_x1, expx2 ) * i.coeff();
+    else
+        // f's level is larger than sv_x1: descend down
+        for ( CFIterator i = f; i.hasTerms(); i++ )
+            swapvar_between( i.coeff(), result, term * power( f.mvar(), i.exp() ), expx2 );
+}
+#if 0
+static CanonicalForm
+swapvar_between1 ( const CanonicalForm & f )
+{
+    if ( f.inCoeffDomain() || f.mvar() < sv_x1 )
+        // in this case, we do not have to replace anything
+        return f;
+    else  if ( f.mvar() == sv_x1 )
+    {
+        // this is where the real work is done: this iterator
+        // replaces sv_x1 with sv_x2
+        CanonicalForm result;
+        for ( CFIterator i = f; i.hasTerms(); i++ )
+            result += power( sv_x2, i.exp() ) * i.coeff();
+        return result;
+    }
+    else
+    {
+        // f's level is larger than sv_x1: descend down
+        CanonicalForm result;
+        for ( CFIterator i = f; i.hasTerms(); i++ )
+            result += swapvar_between1( i.coeff() ) * power( f.mvar(), i.exp() );
+        return result;
+    }
+}
+#endif
+
+/**
+ *
+ * swapvar_between() - swap occurences of sv_x1 and sv_x2 in f.
+ *
+ * If Psi denotes the map which swaps sv_x1 and sv_x2, this
+ * function returns
+ *
+ *   result + Psi(f) * term
+ *
+ * Used by: swapvar()
+ *
+**/
+static void
+swapvar_rec ( const CanonicalForm & f, CanonicalForm & result, const CanonicalForm & term )
+{
+    if ( f.inCoeffDomain() || f.mvar() < sv_x1 )
+        // in this case, we do not have to swap anything
+        result += term * f;
+    else  if ( f.mvar() == sv_x2 )
+        // this is where the real work is done: this iterator
+        // replaces sv_x1 with sv_x2 in the coefficients of f and
+        // remembers the exponents of sv_x2 in the last argument
+        // of the call to swapvar_between()
+        for ( CFIterator i = f; i.hasTerms(); i++ )
+            swapvar_between( i.coeff(), result, term, i.exp() );
+    else  if ( f.mvar() < sv_x2 )
+        // sv_x2 does not occur in f, but sv_x1 does.  Replace it.
+        swapvar_between( f, result, term, 0 );
+    else
+        // f's level is larger than sv_x2: descend down
+        for ( CFIterator i = f; i.hasTerms(); i++ )
+            swapvar_rec( i.coeff(), result, term * power( f.mvar(), i.exp() ) );
+}
+#if 0
+static CanonicalForm
+swapvar_rec1 ( const CanonicalForm & f )
+{
+    if ( f.inCoeffDomain() || f.mvar() < sv_x1 )
+        return f;
+    else  if ( f.mvar() == sv_x2 )
+    {
+        CanonicalForm result;
+        for ( CFIterator i = f; i.hasTerms(); i++ )
+            result += swapvar_between1( i.coeff() ) * power( sv_x1, i.exp() );
+        return result;
+    }
+    else  if ( f.mvar() < sv_x2 )
+        return swapvar_between1( f );
+    else
+    {
+        CanonicalForm result;
+        for ( CFIterator i = f; i.hasTerms(); i++ )
+            result += swapvar_rec1( i.coeff() ) * power( f.mvar(), i.exp() );
+        return result;
+    }
+}
+#endif
+
+/**
+ *
+ * swapvar() - swap variables x1 and x2 in f.
+ *
+ * Returns the image of f under the map which maps x1 to x2 and
+ * x2 to x1.  This is done quite efficiently because it is used
+ * really often.  x1 and x2 should be polynomial variables.
+ *
+**/
+CanonicalForm
+swapvar ( const CanonicalForm & f, const Variable & x1, const Variable & x2 )
+{
+    ASSERT( x1.level() > 0 && x2.level() > 0, "cannot swap algebraic Variables" );
+    if ( f.inCoeffDomain() || x1 == x2 || ( x1 > f.mvar() && x2 > f.mvar() ) )
+        return f;
+    else
+    {
+        CanonicalForm result = 0;
+        if ( x1 > x2 )
+        {
+            sv_x1 = x2; sv_x2 = x1;
+        }
+        else
+        {
+            sv_x1 = x1; sv_x2 = x2;
+        }
+        if ( f.mvar() < sv_x2 )
+            // we only have to replace sv_x1 by sv_x2
+            swapvar_between( f, result, 1, 0 );
+        else
+            // we really have to swap variables
+            swapvar_rec( f, result, 1 );
+        return result;
+    }
+}
+#if 0
+CanonicalForm
+swapvar1 ( const CanonicalForm & f, const Variable & x1, const Variable & x2 )
+{
+    ASSERT( x1.level() > 0 && x2.level() > 0, "cannot swap algebraic variables" );
+    if ( f.inCoeffDomain() || x1 == x2 || ( x1 > f.mvar() && x2 > f.mvar() ) )
+        return f;
+    else
+    {
+        CanonicalForm result = 0;
+        if ( x1 > x2 ) {
+            sv_x1 = x2; sv_x2 = x1;
+        }
+        else
+        {
+            sv_x1 = x1; sv_x2 = x2;
+        }
+        if ( f.mvar() < sv_x2 )
+            // we only have to replace sv_x1 by sv_x2
+            return swapvar_between1( f );
+        else
+            // we really have to swap variables
+            return swapvar_rec1( f );
+    }
+}
+#endif
+
+/**
+ *
+ * replacevar_between() - replace occurences of sv_x1 in f with sv_x2.
+ *
+ * This is allmost the same as swapvar_between() except that
+ * sv_x1 may be an algebraic variable, so we have to test on
+ * 'f.inBaseDomain()' instead of 'f.inCoeffDomain()' in the
+ * beginning.
+ *
+ * Used by: replacevar()
+ *
+**/
+static CanonicalForm
+replacevar_between ( const CanonicalForm & f )
+{
+    if ( f.inBaseDomain() )
+        return f;
+
+    Variable x = f.mvar();
+
+    if ( x < sv_x1 )
+        // in this case, we do not have to replace anything
+        return f;
+    else  if ( x == sv_x1 )
+    {
+        // this is where the real work is done: this iterator
+        // replaces sv_x1 with sv_x2
+        CanonicalForm result;
+        for ( CFIterator i = f; i.hasTerms(); i++ )
+            result += power( sv_x2, i.exp() ) * i.coeff();
+        return result;
+    }
+    else
+    {
+        // f's level is larger than sv_x1: descend down
+        CanonicalForm result;
+        for ( CFIterator i = f; i.hasTerms(); i++ )
+            result += replacevar_between( i.coeff() ) * power( x, i.exp() );
+        return result;
+    }
+}
+
+/** CanonicalForm replacevar ( const CanonicalForm & f, const Variable & x1, const Variable & x2 )
+ *
+ * replacevar() - replace all occurences of x1 in f by x2.
+ *
+ * In contrast to swapvar(), x1 may be an algebraic variable, but
+ * x2 must be a polynomial variable.
+ *
+**/
+CanonicalForm
+replacevar ( const CanonicalForm & f, const Variable & x1, const Variable & x2 )
+{
+    //ASSERT( x2.level() > 0, "cannot replace with algebraic variable" );
+    if ( f.inBaseDomain() || x1 == x2 || ( x1 > f.mvar() ) )
+        return f;
+    else
+    {
+        sv_x1 = x1;
+        sv_x2 = x2;
+        return replacevar_between( f );
+    }
+}
+
+/** static void fillVarsRec ( const CanonicalForm & f, int * vars )
+ *
+ * fillVarsRec - fill array describing occurences of variables in f.
+ *
+ * Only polynomial variables are looked up.  The information is
+ * stored in the arrary vars.  vars should be large enough to
+ * hold all information, i.e. larger than the level of f.
+ *
+ * Used by getVars() and getNumVars().
+ *
+**/
+static void
+fillVarsRec ( const CanonicalForm & f, int * vars )
+{
+    int n;
+    if ( (n = f.level()) > 0 )
+    {
+        vars[n] = 1;
+        CFIterator i;
+        for ( i = f; i.hasTerms(); ++i )
+            fillVarsRec( i.coeff(), vars );
+    }
+}
+
+/** int getNumVars ( const CanonicalForm & f )
+ *
+ * getNumVars() - get number of polynomial variables in f.
+ *
+**/
+int
+getNumVars ( const CanonicalForm & f )
+{
+    int n;
+    if ( f.inCoeffDomain() )
+        return 0;
+    else  if ( (n = f.level()) == 1 )
+        return 1;
+    else
+    {
+        int * vars = new int[ n+1 ];
+        int i;
+        for ( i = 0; i < n; i++ ) vars[i] = 0;
+
+        // look for variables
+        for ( CFIterator I = f; I.hasTerms(); ++I )
+            fillVarsRec( I.coeff(), vars );
+
+        // count them
+        int m = 0;
+        for ( i = 1; i < n; i++ )
+            if ( vars[i] != 0 ) m++;
+
+        delete [] vars;
+        // do not forget to count our own variable
+        return m+1;
+    }
+}
+
+/** CanonicalForm getVars ( const CanonicalForm & f )
+ *
+ * getVars() - get polynomial variables of f.
+ *
+ * Return the product of all of them, 1 if there are not any.
+ *
+**/
+CanonicalForm
+getVars ( const CanonicalForm & f )
+{
+    int n;
+    if ( f.inCoeffDomain() )
+        return 1;
+    else  if ( (n = f.level()) == 1 )
+        return Variable( 1 );
+    else
+    {
+        int * vars = new int[ n+1 ];
+        int i;
+        for ( i = 0; i <= n; i++ ) vars[i] = 0;
+
+        // look for variables
+        for ( CFIterator I = f; I.hasTerms(); ++I )
+            fillVarsRec( I.coeff(), vars );
+
+        // multiply them all
+        CanonicalForm result = 1;
+        for ( i = n; i > 0; i-- )
+            if ( vars[i] != 0 ) result *= Variable( i );
+
+        delete [] vars;
+        // do not forget our own variable
+        return f.mvar() * result;
+    }
+}
+
+/** CanonicalForm apply ( const CanonicalForm & f, void (*mf)( CanonicalForm &, int & ) )
+ *
+ * apply() - apply mf to terms of f.
+ *
+ * Calls mf( f[i], i ) for each term f[i]*x^i of f and builds a
+ * new term from the result.  If f is in a coefficient domain,
+ * mf( f, i ) should result in an i == 0, since otherwise it is
+ * not clear which variable to use for the resulting term.
+ *
+ * An example:
+ *
+~~~~~~~~~~~~~~~~~~~~~{.c}
+   void
+   diff( CanonicalForm & f, int & i )
+   {
+      f = f * i;
+      if ( i > 0 ) i--;
+   }
+~~~~~~~~~~~~~~~~~~~~~
+ * Then apply( f, diff ) is differentation of f with respect to the
+ * main variable of f.
+ *
+**/
+CanonicalForm
+apply ( const CanonicalForm & f, void (*mf)( CanonicalForm &, int & ) )
+{
+    if ( f.inCoeffDomain() )
+    {
+        int exp = 0;
+        CanonicalForm result = f;
+        mf( result, exp );
+        ASSERT( exp == 0, "illegal result, do not know what variable to use" );
+        return result;
+    }
+    else
+    {
+        CanonicalForm result, coeff;
+        CFIterator i;
+        int exp;
+        Variable x = f.mvar();
+        for ( i = f; i.hasTerms(); i++ )
+        {
+            coeff = i.coeff();
+            exp = i.exp();
+            mf( coeff, exp );
+            if ( ! coeff.isZero() )
+                result += power( x, exp ) * coeff;
+        }
+        return result;
+    }
+}
+
+/** CanonicalForm mapdomain ( const CanonicalForm & f, CanonicalForm (*mf)( const CanonicalForm & ) )
+ *
+ * mapdomain() - map all coefficients of f through mf.
+ *
+ * Recursively descends down through f to the coefficients which
+ * are in a coefficient domain mapping each such coefficient
+ * through mf and returns the result.
+ *
+**/
+CanonicalForm
+mapdomain ( const CanonicalForm & f, CanonicalForm (*mf)( const CanonicalForm & ) )
+{
+    if ( f.inBaseDomain() )
+        return mf( f );
+    else
+    {
+        CanonicalForm result = 0;
+        CFIterator i;
+        Variable x = f.mvar();
+        for ( i = f; i.hasTerms(); i++ )
+            result += power( x, i.exp() ) * mapdomain( i.coeff(), mf );
+        return result;
+    }
+}
+
+/** static void degreesRec ( const CanonicalForm & f, int * degs )
+ *
+ * degreesRec() - recursively get degrees of f.
+ *
+ * Used by degrees().
+ *
+**/
+static void
+degreesRec ( const CanonicalForm & f, int * degs )
+{
+    if ( ! f.inCoeffDomain() )
+    {
+        int level = f.level();
+        int deg = f.degree();
+        // calculate the maximum degree of all coefficients which
+        // are in the same level
+        if ( degs[level] < deg )
+            degs[level] = f.degree();
+        for ( CFIterator i = f; i.hasTerms(); i++ )
+            degreesRec( i.coeff(), degs );
+    }
+}
+
+/** int * degrees ( const CanonicalForm & f, int * degs )
+ *
+ * degress() - return the degrees of all polynomial variables in f.
+ *
+ * Returns 0 if f is in a coefficient domain, the degrees of f in
+ * all its polynomial variables in an array of int otherwise:
+ *
+ *   degrees( f, 0 )[i] = degree( f, Variable(i) )
+ *
+ * If degs is not the zero pointer the degrees are stored in this
+ * array.  In this case degs should be larger than the level of
+ * f.  If degs is the zero pointer, an array of sufficient size
+ * is allocated automatically.
+ *
+**/
+int * degrees ( const CanonicalForm & f, int * degs )
+{
+    if ( f.inCoeffDomain() )
+    {
+        if (degs != 0)
+          return degs;
+        else
+          return 0;
+    }
+    else
+    {
+        int level = f.level();
+        if ( degs == 0 )
+            degs = new int[level+1];
+        for ( int i = 0; i <= level; i++ )
+            degs[i] = 0;
+        degreesRec( f, degs );
+        return degs;
+    }
+}
+
+/** int totaldegree ( const CanonicalForm & f )
+ *
+ * totaldegree() - return the total degree of f.
+ *
+ * If f is zero, return -1.  If f is in a coefficient domain,
+ * return 0.  Otherwise return the total degree of f in all
+ * polynomial variables.
+ *
+**/
+int totaldegree ( const CanonicalForm & f )
+{
+    if ( f.isZero() )
+        return -1;
+    else if ( f.inCoeffDomain() )
+        return 0;
+    else
+    {
+        CFIterator i;
+        int cdeg = 0, dummy;
+        // calculate maximum over all coefficients of f, taking
+        // in account our own exponent
+        for ( i = f; i.hasTerms(); i++ )
+            if ( (dummy = totaldegree( i.coeff() ) + i.exp()) > cdeg )
+                cdeg = dummy;
+        return cdeg;
+    }
+}
+
+/** int totaldegree ( const CanonicalForm & f, const Variable & v1, const Variable & v2 )
+ *
+ * totaldegree() - return the total degree of f as a polynomial
+ *   in the polynomial variables between v1 and v2 (inclusively).
+ *
+ * If f is zero, return -1.  If f is in a coefficient domain,
+ * return 0.  Also, return 0 if v1 > v2.  Otherwise, take f to be
+ * a polynomial in the polynomial variables between v1 and v2 and
+ * return its total degree.
+ *
+**/
+int
+totaldegree ( const CanonicalForm & f, const Variable & v1, const Variable & v2 )
+{
+    if ( f.isZero() )
+        return -1;
+    else if ( v1 > v2 )
+        return 0;
+    else if ( f.inCoeffDomain() )
+        return 0;
+    else if ( f.mvar() < v1 )
+        return 0;
+    else if ( f.mvar() == v1 )
+        return f.degree();
+    else if ( f.mvar() > v2 )
+    {
+        // v2's level is larger than f's level, descend down
+        CFIterator i;
+        int cdeg = 0, dummy;
+        // calculate maximum over all coefficients of f
+        for ( i = f; i.hasTerms(); i++ )
+            if ( (dummy = totaldegree( i.coeff(), v1, v2 )) > cdeg )
+                cdeg = dummy;
+        return cdeg;
+    }
+    else
+    {
+        // v1 < f.mvar() <= v2
+        CFIterator i;
+        int cdeg = 0, dummy;
+        // calculate maximum over all coefficients of f, taking
+        // in account our own exponent
+        for ( i = f; i.hasTerms(); i++ )
+            if ( (dummy = totaldegree( i.coeff(), v1, v2 ) + i.exp()) > cdeg )
+                cdeg = dummy;
+        return cdeg;
+    }
+}
+
+/** int size ( const CanonicalForm & f, const Variable & v )
+ *
+ * size() - count number of monomials of f with level higher
+ *   or equal than level of v.
+ *
+ * Returns one if f is in an base domain.
+ *
+**/
+int
+size ( const CanonicalForm & f, const Variable & v )
+{
+    if ( f.inBaseDomain() )
+        return 1;
+
+    if ( f.mvar() < v )
+        // polynomials with level < v1 are counted as coefficients
+        return 1;
+    else
+    {
+        CFIterator i;
+        int result = 0;
+        // polynomials with level > v2 are not counted al all
+        for ( i = f; i.hasTerms(); i++ )
+            result += size( i.coeff(), v );
+        return result;
+    }
+}
+
+/** int size ( const CanonicalForm & f )
+ *
+ * size() - return number of monomials in f which are in an
+ *   coefficient domain.
+ *
+ * Returns one if f is in an coefficient domain.
+ *
+**/
+int
+size ( const CanonicalForm & f )
+{
+    if ( f.inCoeffDomain() )
+        return 1;
+    else
+    {
+        int result = 0;
+        CFIterator i;
+        for ( i = f; i.hasTerms(); i++ )
+            result += size( i.coeff() );
+        return result;
+    }
+}
+
+/** polynomials in M.mvar() are considered coefficients
+ *  M univariate monic polynomial
+ *  the coefficients of f are reduced modulo M
+**/
+CanonicalForm reduce(const CanonicalForm & f, const CanonicalForm & M)
+{
+  if(f.inBaseDomain() || f.level() < M.level())
+    return f;
+  if(f.level() == M.level())
+  {
+    if(f.degree() < M.degree())
+      return f;
+    CanonicalForm tmp = mod (f, M);
+    return tmp;
+  }
+  // here: f.level() > M.level()
+  CanonicalForm result = 0;
+  for(CFIterator i=f; i.hasTerms(); i++)
+    result += reduce(i.coeff(),M) * power(f.mvar(),i.exp());
+  return result;
+}
+
+/** check if poly f contains an algebraic variable a **/
+bool hasFirstAlgVar( const CanonicalForm & f, Variable & a )
+{
+  if( f.inBaseDomain() ) // f has NO alg. variable
+    return false;
+  if( f.level()<0 ) // f has only alg. vars, so take the first one
+  {
+    a = f.mvar();
+    return true;
+  }
+  for(CFIterator i=f; i.hasTerms(); i++)
+    if( hasFirstAlgVar( i.coeff(), a ))
+      return true; // 'a' is already set
+  return false;
+}
+
+/** left shift the main variable of F by n
+ *  @return if x is the main variable of F the result is F(x^n)
+ **/
+CanonicalForm leftShift (const CanonicalForm& F, int n)
+{
+  ASSERT (n >= 0, "cannot left shift by negative number");
+  if (F.inBaseDomain())
+    return F;
+  if (n == 0)
+    return F;
+  Variable x=F.mvar();
+  CanonicalForm result= 0;
+  for (CFIterator i= F; i.hasTerms(); i++)
+    result += i.coeff()*power (x, i.exp()*n);
+  return result;
+}
diff --git a/factory/cf_primes.cc b/factory/cf_primes.cc
new file mode 100644
index 0000000..3599031
--- /dev/null
+++ b/factory/cf_primes.cc
@@ -0,0 +1,48 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+
+#include "config.h"
+
+
+#include "cf_assert.h"
+
+#include "cf_defs.h"
+#include "cf_primes.h"
+#include "cf_primetab.h"
+
+
+int cf_getPrime( int i )
+{
+    ASSERT( i >= 0 && i < NUMPRIMES, "index to primes too high" );
+    if ( i >= NUMSMALLPRIMES )
+        return bigprimes[i-NUMSMALLPRIMES];
+    else
+        return smallprimes[i];
+}
+
+int cf_getNumPrimes()
+{
+    return NUMPRIMES;
+}
+
+int cf_getSmallPrime( int i )
+{
+    ASSERT( i >= 0 && i < NUMSMALLPRIMES, "index to primes too high" );
+    return smallprimes[i];
+}
+
+int cf_getNumSmallPrimes()
+{
+    return NUMSMALLPRIMES;
+}
+
+int cf_getBigPrime( int i )
+{
+    ASSERT( i >= 0 && i < NUMBIGPRIMES, "index to primes too high" );
+    return bigprimes[i];
+}
+
+int cf_getNumBigPrimes()
+{
+    return NUMBIGPRIMES;
+}
diff --git a/factory/cf_primes.h b/factory/cf_primes.h
new file mode 100644
index 0000000..3323e0e
--- /dev/null
+++ b/factory/cf_primes.h
@@ -0,0 +1,30 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+/**
+ * @file cf_primes.h
+ *
+ * access to prime tables
+**/
+
+#ifndef INCL_CF_PRIMES_H
+#define INCL_CF_PRIMES_H
+
+// #include "config.h"
+
+/*BEGINPUBLIC*/
+
+int cf_getPrime( int i );
+
+int cf_getNumPrimes();
+
+int cf_getSmallPrime( int i );
+
+int cf_getNumSmallPrimes();
+
+int cf_getBigPrime( int i );
+
+int cf_getNumBigPrimes();
+
+/*ENDPUBLIC*/
+
+#endif /* ! INCL_CF_PRIMES_H */
diff --git a/factory/cf_primetab.h b/factory/cf_primetab.h
new file mode 100644
index 0000000..75df989
--- /dev/null
+++ b/factory/cf_primetab.h
@@ -0,0 +1,5342 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+#ifndef INCL_CF_PRIMETAB_H
+#define INCL_CF_PRIMETAB_H
+
+// #include "config.h"
+
+#define NUMSMALLPRIMES 3511
+#define NUMBIGPRIMES 28427
+#define NUMPRIMES NUMSMALLPRIMES+NUMBIGPRIMES
+
+static const int smallprimes [] = {
+    3, 5, 7, 11, 13, 17,
+    19, 23, 29, 31, 37, 41,
+    43, 47, 53, 59, 61, 67,
+    71, 73, 79, 83, 89, 97,
+    101, 103, 107, 109, 113, 127,
+    131, 137, 139, 149, 151, 157,
+    163, 167, 173, 179, 181, 191,
+    193, 197, 199, 211, 223, 227,
+    229, 233, 239, 241, 251, 257,
+    263, 269, 271, 277, 281, 283,
+    293, 307, 311, 313, 317, 331,
+    337, 347, 349, 353, 359, 367,
+    373, 379, 383, 389, 397, 401,
+    409, 419, 421, 431, 433, 439,
+    443, 449, 457, 461, 463, 467,
+    479, 487, 491, 499, 503, 509,
+    521, 523, 541, 547, 557, 563,
+    569, 571, 577, 587, 593, 599,
+    601, 607, 613, 617, 619, 631,
+    641, 643, 647, 653, 659, 661,
+    673, 677, 683, 691, 701, 709,
+    719, 727, 733, 739, 743, 751,
+    757, 761, 769, 773, 787, 797,
+    809, 811, 821, 823, 827, 829,
+    839, 853, 857, 859, 863, 877,
+    881, 883, 887, 907, 911, 919,
+    929, 937, 941, 947, 953, 967,
+    971, 977, 983, 991, 997, 1009,
+    1013, 1019, 1021, 1031, 1033, 1039,
+    1049, 1051, 1061, 1063, 1069, 1087,
+    1091, 1093, 1097, 1103, 1109, 1117,
+    1123, 1129, 1151, 1153, 1163, 1171,
+    1181, 1187, 1193, 1201, 1213, 1217,
+    1223, 1229, 1231, 1237, 1249, 1259,
+    1277, 1279, 1283, 1289, 1291, 1297,
+    1301, 1303, 1307, 1319, 1321, 1327,
+    1361, 1367, 1373, 1381, 1399, 1409,
+    1423, 1427, 1429, 1433, 1439, 1447,
+    1451, 1453, 1459, 1471, 1481, 1483,
+    1487, 1489, 1493, 1499, 1511, 1523,
+    1531, 1543, 1549, 1553, 1559, 1567,
+    1571, 1579, 1583, 1597, 1601, 1607,
+    1609, 1613, 1619, 1621, 1627, 1637,
+    1657, 1663, 1667, 1669, 1693, 1697,
+    1699, 1709, 1721, 1723, 1733, 1741,
+    1747, 1753, 1759, 1777, 1783, 1787,
+    1789, 1801, 1811, 1823, 1831, 1847,
+    1861, 1867, 1871, 1873, 1877, 1879,
+    1889, 1901, 1907, 1913, 1931, 1933,
+    1949, 1951, 1973, 1979, 1987, 1993,
+    1997, 1999, 2003, 2011, 2017, 2027,
+    2029, 2039, 2053, 2063, 2069, 2081,
+    2083, 2087, 2089, 2099, 2111, 2113,
+    2129, 2131, 2137, 2141, 2143, 2153,
+    2161, 2179, 2203, 2207, 2213, 2221,
+    2237, 2239, 2243, 2251, 2267, 2269,
+    2273, 2281, 2287, 2293, 2297, 2309,
+    2311, 2333, 2339, 2341, 2347, 2351,
+    2357, 2371, 2377, 2381, 2383, 2389,
+    2393, 2399, 2411, 2417, 2423, 2437,
+    2441, 2447, 2459, 2467, 2473, 2477,
+    2503, 2521, 2531, 2539, 2543, 2549,
+    2551, 2557, 2579, 2591, 2593, 2609,
+    2617, 2621, 2633, 2647, 2657, 2659,
+    2663, 2671, 2677, 2683, 2687, 2689,
+    2693, 2699, 2707, 2711, 2713, 2719,
+    2729, 2731, 2741, 2749, 2753, 2767,
+    2777, 2789, 2791, 2797, 2801, 2803,
+    2819, 2833, 2837, 2843, 2851, 2857,
+    2861, 2879, 2887, 2897, 2903, 2909,
+    2917, 2927, 2939, 2953, 2957, 2963,
+    2969, 2971, 2999, 3001, 3011, 3019,
+    3023, 3037, 3041, 3049, 3061, 3067,
+    3079, 3083, 3089, 3109, 3119, 3121,
+    3137, 3163, 3167, 3169, 3181, 3187,
+    3191, 3203, 3209, 3217, 3221, 3229,
+    3251, 3253, 3257, 3259, 3271, 3299,
+    3301, 3307, 3313, 3319, 3323, 3329,
+    3331, 3343, 3347, 3359, 3361, 3371,
+    3373, 3389, 3391, 3407, 3413, 3433,
+    3449, 3457, 3461, 3463, 3467, 3469,
+    3491, 3499, 3511, 3517, 3527, 3529,
+    3533, 3539, 3541, 3547, 3557, 3559,
+    3571, 3581, 3583, 3593, 3607, 3613,
+    3617, 3623, 3631, 3637, 3643, 3659,
+    3671, 3673, 3677, 3691, 3697, 3701,
+    3709, 3719, 3727, 3733, 3739, 3761,
+    3767, 3769, 3779, 3793, 3797, 3803,
+    3821, 3823, 3833, 3847, 3851, 3853,
+    3863, 3877, 3881, 3889, 3907, 3911,
+    3917, 3919, 3923, 3929, 3931, 3943,
+    3947, 3967, 3989, 4001, 4003, 4007,
+    4013, 4019, 4021, 4027, 4049, 4051,
+    4057, 4073, 4079, 4091, 4093, 4099,
+    4111, 4127, 4129, 4133, 4139, 4153,
+    4157, 4159, 4177, 4201, 4211, 4217,
+    4219, 4229, 4231, 4241, 4243, 4253,
+    4259, 4261, 4271, 4273, 4283, 4289,
+    4297, 4327, 4337, 4339, 4349, 4357,
+    4363, 4373, 4391, 4397, 4409, 4421,
+    4423, 4441, 4447, 4451, 4457, 4463,
+    4481, 4483, 4493, 4507, 4513, 4517,
+    4519, 4523, 4547, 4549, 4561, 4567,
+    4583, 4591, 4597, 4603, 4621, 4637,
+    4639, 4643, 4649, 4651, 4657, 4663,
+    4673, 4679, 4691, 4703, 4721, 4723,
+    4729, 4733, 4751, 4759, 4783, 4787,
+    4789, 4793, 4799, 4801, 4813, 4817,
+    4831, 4861, 4871, 4877, 4889, 4903,
+    4909, 4919, 4931, 4933, 4937, 4943,
+    4951, 4957, 4967, 4969, 4973, 4987,
+    4993, 4999, 5003, 5009, 5011, 5021,
+    5023, 5039, 5051, 5059, 5077, 5081,
+    5087, 5099, 5101, 5107, 5113, 5119,
+    5147, 5153, 5167, 5171, 5179, 5189,
+    5197, 5209, 5227, 5231, 5233, 5237,
+    5261, 5273, 5279, 5281, 5297, 5303,
+    5309, 5323, 5333, 5347, 5351, 5381,
+    5387, 5393, 5399, 5407, 5413, 5417,
+    5419, 5431, 5437, 5441, 5443, 5449,
+    5471, 5477, 5479, 5483, 5501, 5503,
+    5507, 5519, 5521, 5527, 5531, 5557,
+    5563, 5569, 5573, 5581, 5591, 5623,
+    5639, 5641, 5647, 5651, 5653, 5657,
+    5659, 5669, 5683, 5689, 5693, 5701,
+    5711, 5717, 5737, 5741, 5743, 5749,
+    5779, 5783, 5791, 5801, 5807, 5813,
+    5821, 5827, 5839, 5843, 5849, 5851,
+    5857, 5861, 5867, 5869, 5879, 5881,
+    5897, 5903, 5923, 5927, 5939, 5953,
+    5981, 5987, 6007, 6011, 6029, 6037,
+    6043, 6047, 6053, 6067, 6073, 6079,
+    6089, 6091, 6101, 6113, 6121, 6131,
+    6133, 6143, 6151, 6163, 6173, 6197,
+    6199, 6203, 6211, 6217, 6221, 6229,
+    6247, 6257, 6263, 6269, 6271, 6277,
+    6287, 6299, 6301, 6311, 6317, 6323,
+    6329, 6337, 6343, 6353, 6359, 6361,
+    6367, 6373, 6379, 6389, 6397, 6421,
+    6427, 6449, 6451, 6469, 6473, 6481,
+    6491, 6521, 6529, 6547, 6551, 6553,
+    6563, 6569, 6571, 6577, 6581, 6599,
+    6607, 6619, 6637, 6653, 6659, 6661,
+    6673, 6679, 6689, 6691, 6701, 6703,
+    6709, 6719, 6733, 6737, 6761, 6763,
+    6779, 6781, 6791, 6793, 6803, 6823,
+    6827, 6829, 6833, 6841, 6857, 6863,
+    6869, 6871, 6883, 6899, 6907, 6911,
+    6917, 6947, 6949, 6959, 6961, 6967,
+    6971, 6977, 6983, 6991, 6997, 7001,
+    7013, 7019, 7027, 7039, 7043, 7057,
+    7069, 7079, 7103, 7109, 7121, 7127,
+    7129, 7151, 7159, 7177, 7187, 7193,
+    7207, 7211, 7213, 7219, 7229, 7237,
+    7243, 7247, 7253, 7283, 7297, 7307,
+    7309, 7321, 7331, 7333, 7349, 7351,
+    7369, 7393, 7411, 7417, 7433, 7451,
+    7457, 7459, 7477, 7481, 7487, 7489,
+    7499, 7507, 7517, 7523, 7529, 7537,
+    7541, 7547, 7549, 7559, 7561, 7573,
+    7577, 7583, 7589, 7591, 7603, 7607,
+    7621, 7639, 7643, 7649, 7669, 7673,
+    7681, 7687, 7691, 7699, 7703, 7717,
+    7723, 7727, 7741, 7753, 7757, 7759,
+    7789, 7793, 7817, 7823, 7829, 7841,
+    7853, 7867, 7873, 7877, 7879, 7883,
+    7901, 7907, 7919, 7927, 7933, 7937,
+    7949, 7951, 7963, 7993, 8009, 8011,
+    8017, 8039, 8053, 8059, 8069, 8081,
+    8087, 8089, 8093, 8101, 8111, 8117,
+    8123, 8147, 8161, 8167, 8171, 8179,
+    8191, 8209, 8219, 8221, 8231, 8233,
+    8237, 8243, 8263, 8269, 8273, 8287,
+    8291, 8293, 8297, 8311, 8317, 8329,
+    8353, 8363, 8369, 8377, 8387, 8389,
+    8419, 8423, 8429, 8431, 8443, 8447,
+    8461, 8467, 8501, 8513, 8521, 8527,
+    8537, 8539, 8543, 8563, 8573, 8581,
+    8597, 8599, 8609, 8623, 8627, 8629,
+    8641, 8647, 8663, 8669, 8677, 8681,
+    8689, 8693, 8699, 8707, 8713, 8719,
+    8731, 8737, 8741, 8747, 8753, 8761,
+    8779, 8783, 8803, 8807, 8819, 8821,
+    8831, 8837, 8839, 8849, 8861, 8863,
+    8867, 8887, 8893, 8923, 8929, 8933,
+    8941, 8951, 8963, 8969, 8971, 8999,
+    9001, 9007, 9011, 9013, 9029, 9041,
+    9043, 9049, 9059, 9067, 9091, 9103,
+    9109, 9127, 9133, 9137, 9151, 9157,
+    9161, 9173, 9181, 9187, 9199, 9203,
+    9209, 9221, 9227, 9239, 9241, 9257,
+    9277, 9281, 9283, 9293, 9311, 9319,
+    9323, 9337, 9341, 9343, 9349, 9371,
+    9377, 9391, 9397, 9403, 9413, 9419,
+    9421, 9431, 9433, 9437, 9439, 9461,
+    9463, 9467, 9473, 9479, 9491, 9497,
+    9511, 9521, 9533, 9539, 9547, 9551,
+    9587, 9601, 9613, 9619, 9623, 9629,
+    9631, 9643, 9649, 9661, 9677, 9679,
+    9689, 9697, 9719, 9721, 9733, 9739,
+    9743, 9749, 9767, 9769, 9781, 9787,
+    9791, 9803, 9811, 9817, 9829, 9833,
+    9839, 9851, 9857, 9859, 9871, 9883,
+    9887, 9901, 9907, 9923, 9929, 9931,
+    9941, 9949, 9967, 9973, 10007, 10009,
+    10037, 10039, 10061, 10067, 10069, 10079,
+    10091, 10093, 10099, 10103, 10111, 10133,
+    10139, 10141, 10151, 10159, 10163, 10169,
+    10177, 10181, 10193, 10211, 10223, 10243,
+    10247, 10253, 10259, 10267, 10271, 10273,
+    10289, 10301, 10303, 10313, 10321, 10331,
+    10333, 10337, 10343, 10357, 10369, 10391,
+    10399, 10427, 10429, 10433, 10453, 10457,
+    10459, 10463, 10477, 10487, 10499, 10501,
+    10513, 10529, 10531, 10559, 10567, 10589,
+    10597, 10601, 10607, 10613, 10627, 10631,
+    10639, 10651, 10657, 10663, 10667, 10687,
+    10691, 10709, 10711, 10723, 10729, 10733,
+    10739, 10753, 10771, 10781, 10789, 10799,
+    10831, 10837, 10847, 10853, 10859, 10861,
+    10867, 10883, 10889, 10891, 10903, 10909,
+    10937, 10939, 10949, 10957, 10973, 10979,
+    10987, 10993, 11003, 11027, 11047, 11057,
+    11059, 11069, 11071, 11083, 11087, 11093,
+    11113, 11117, 11119, 11131, 11149, 11159,
+    11161, 11171, 11173, 11177, 11197, 11213,
+    11239, 11243, 11251, 11257, 11261, 11273,
+    11279, 11287, 11299, 11311, 11317, 11321,
+    11329, 11351, 11353, 11369, 11383, 11393,
+    11399, 11411, 11423, 11437, 11443, 11447,
+    11467, 11471, 11483, 11489, 11491, 11497,
+    11503, 11519, 11527, 11549, 11551, 11579,
+    11587, 11593, 11597, 11617, 11621, 11633,
+    11657, 11677, 11681, 11689, 11699, 11701,
+    11717, 11719, 11731, 11743, 11777, 11779,
+    11783, 11789, 11801, 11807, 11813, 11821,
+    11827, 11831, 11833, 11839, 11863, 11867,
+    11887, 11897, 11903, 11909, 11923, 11927,
+    11933, 11939, 11941, 11953, 11959, 11969,
+    11971, 11981, 11987, 12007, 12011, 12037,
+    12041, 12043, 12049, 12071, 12073, 12097,
+    12101, 12107, 12109, 12113, 12119, 12143,
+    12149, 12157, 12161, 12163, 12197, 12203,
+    12211, 12227, 12239, 12241, 12251, 12253,
+    12263, 12269, 12277, 12281, 12289, 12301,
+    12323, 12329, 12343, 12347, 12373, 12377,
+    12379, 12391, 12401, 12409, 12413, 12421,
+    12433, 12437, 12451, 12457, 12473, 12479,
+    12487, 12491, 12497, 12503, 12511, 12517,
+    12527, 12539, 12541, 12547, 12553, 12569,
+    12577, 12583, 12589, 12601, 12611, 12613,
+    12619, 12637, 12641, 12647, 12653, 12659,
+    12671, 12689, 12697, 12703, 12713, 12721,
+    12739, 12743, 12757, 12763, 12781, 12791,
+    12799, 12809, 12821, 12823, 12829, 12841,
+    12853, 12889, 12893, 12899, 12907, 12911,
+    12917, 12919, 12923, 12941, 12953, 12959,
+    12967, 12973, 12979, 12983, 13001, 13003,
+    13007, 13009, 13033, 13037, 13043, 13049,
+    13063, 13093, 13099, 13103, 13109, 13121,
+    13127, 13147, 13151, 13159, 13163, 13171,
+    13177, 13183, 13187, 13217, 13219, 13229,
+    13241, 13249, 13259, 13267, 13291, 13297,
+    13309, 13313, 13327, 13331, 13337, 13339,
+    13367, 13381, 13397, 13399, 13411, 13417,
+    13421, 13441, 13451, 13457, 13463, 13469,
+    13477, 13487, 13499, 13513, 13523, 13537,
+    13553, 13567, 13577, 13591, 13597, 13613,
+    13619, 13627, 13633, 13649, 13669, 13679,
+    13681, 13687, 13691, 13693, 13697, 13709,
+    13711, 13721, 13723, 13729, 13751, 13757,
+    13759, 13763, 13781, 13789, 13799, 13807,
+    13829, 13831, 13841, 13859, 13873, 13877,
+    13879, 13883, 13901, 13903, 13907, 13913,
+    13921, 13931, 13933, 13963, 13967, 13997,
+    13999, 14009, 14011, 14029, 14033, 14051,
+    14057, 14071, 14081, 14083, 14087, 14107,
+    14143, 14149, 14153, 14159, 14173, 14177,
+    14197, 14207, 14221, 14243, 14249, 14251,
+    14281, 14293, 14303, 14321, 14323, 14327,
+    14341, 14347, 14369, 14387, 14389, 14401,
+    14407, 14411, 14419, 14423, 14431, 14437,
+    14447, 14449, 14461, 14479, 14489, 14503,
+    14519, 14533, 14537, 14543, 14549, 14551,
+    14557, 14561, 14563, 14591, 14593, 14621,
+    14627, 14629, 14633, 14639, 14653, 14657,
+    14669, 14683, 14699, 14713, 14717, 14723,
+    14731, 14737, 14741, 14747, 14753, 14759,
+    14767, 14771, 14779, 14783, 14797, 14813,
+    14821, 14827, 14831, 14843, 14851, 14867,
+    14869, 14879, 14887, 14891, 14897, 14923,
+    14929, 14939, 14947, 14951, 14957, 14969,
+    14983, 15013, 15017, 15031, 15053, 15061,
+    15073, 15077, 15083, 15091, 15101, 15107,
+    15121, 15131, 15137, 15139, 15149, 15161,
+    15173, 15187, 15193, 15199, 15217, 15227,
+    15233, 15241, 15259, 15263, 15269, 15271,
+    15277, 15287, 15289, 15299, 15307, 15313,
+    15319, 15329, 15331, 15349, 15359, 15361,
+    15373, 15377, 15383, 15391, 15401, 15413,
+    15427, 15439, 15443, 15451, 15461, 15467,
+    15473, 15493, 15497, 15511, 15527, 15541,
+    15551, 15559, 15569, 15581, 15583, 15601,
+    15607, 15619, 15629, 15641, 15643, 15647,
+    15649, 15661, 15667, 15671, 15679, 15683,
+    15727, 15731, 15733, 15737, 15739, 15749,
+    15761, 15767, 15773, 15787, 15791, 15797,
+    15803, 15809, 15817, 15823, 15859, 15877,
+    15881, 15887, 15889, 15901, 15907, 15913,
+    15919, 15923, 15937, 15959, 15971, 15973,
+    15991, 16001, 16007, 16033, 16057, 16061,
+    16063, 16067, 16069, 16073, 16087, 16091,
+    16097, 16103, 16111, 16127, 16139, 16141,
+    16183, 16187, 16189, 16193, 16217, 16223,
+    16229, 16231, 16249, 16253, 16267, 16273,
+    16301, 16319, 16333, 16339, 16349, 16361,
+    16363, 16369, 16381, 16411, 16417, 16421,
+    16427, 16433, 16447, 16451, 16453, 16477,
+    16481, 16487, 16493, 16519, 16529, 16547,
+    16553, 16561, 16567, 16573, 16603, 16607,
+    16619, 16631, 16633, 16649, 16651, 16657,
+    16661, 16673, 16691, 16693, 16699, 16703,
+    16729, 16741, 16747, 16759, 16763, 16787,
+    16811, 16823, 16829, 16831, 16843, 16871,
+    16879, 16883, 16889, 16901, 16903, 16921,
+    16927, 16931, 16937, 16943, 16963, 16979,
+    16981, 16987, 16993, 17011, 17021, 17027,
+    17029, 17033, 17041, 17047, 17053, 17077,
+    17093, 17099, 17107, 17117, 17123, 17137,
+    17159, 17167, 17183, 17189, 17191, 17203,
+    17207, 17209, 17231, 17239, 17257, 17291,
+    17293, 17299, 17317, 17321, 17327, 17333,
+    17341, 17351, 17359, 17377, 17383, 17387,
+    17389, 17393, 17401, 17417, 17419, 17431,
+    17443, 17449, 17467, 17471, 17477, 17483,
+    17489, 17491, 17497, 17509, 17519, 17539,
+    17551, 17569, 17573, 17579, 17581, 17597,
+    17599, 17609, 17623, 17627, 17657, 17659,
+    17669, 17681, 17683, 17707, 17713, 17729,
+    17737, 17747, 17749, 17761, 17783, 17789,
+    17791, 17807, 17827, 17837, 17839, 17851,
+    17863, 17881, 17891, 17903, 17909, 17911,
+    17921, 17923, 17929, 17939, 17957, 17959,
+    17971, 17977, 17981, 17987, 17989, 18013,
+    18041, 18043, 18047, 18049, 18059, 18061,
+    18077, 18089, 18097, 18119, 18121, 18127,
+    18131, 18133, 18143, 18149, 18169, 18181,
+    18191, 18199, 18211, 18217, 18223, 18229,
+    18233, 18251, 18253, 18257, 18269, 18287,
+    18289, 18301, 18307, 18311, 18313, 18329,
+    18341, 18353, 18367, 18371, 18379, 18397,
+    18401, 18413, 18427, 18433, 18439, 18443,
+    18451, 18457, 18461, 18481, 18493, 18503,
+    18517, 18521, 18523, 18539, 18541, 18553,
+    18583, 18587, 18593, 18617, 18637, 18661,
+    18671, 18679, 18691, 18701, 18713, 18719,
+    18731, 18743, 18749, 18757, 18773, 18787,
+    18793, 18797, 18803, 18839, 18859, 18869,
+    18899, 18911, 18913, 18917, 18919, 18947,
+    18959, 18973, 18979, 19001, 19009, 19013,
+    19031, 19037, 19051, 19069, 19073, 19079,
+    19081, 19087, 19121, 19139, 19141, 19157,
+    19163, 19181, 19183, 19207, 19211, 19213,
+    19219, 19231, 19237, 19249, 19259, 19267,
+    19273, 19289, 19301, 19309, 19319, 19333,
+    19373, 19379, 19381, 19387, 19391, 19403,
+    19417, 19421, 19423, 19427, 19429, 19433,
+    19441, 19447, 19457, 19463, 19469, 19471,
+    19477, 19483, 19489, 19501, 19507, 19531,
+    19541, 19543, 19553, 19559, 19571, 19577,
+    19583, 19597, 19603, 19609, 19661, 19681,
+    19687, 19697, 19699, 19709, 19717, 19727,
+    19739, 19751, 19753, 19759, 19763, 19777,
+    19793, 19801, 19813, 19819, 19841, 19843,
+    19853, 19861, 19867, 19889, 19891, 19913,
+    19919, 19927, 19937, 19949, 19961, 19963,
+    19973, 19979, 19991, 19993, 19997, 20011,
+    20021, 20023, 20029, 20047, 20051, 20063,
+    20071, 20089, 20101, 20107, 20113, 20117,
+    20123, 20129, 20143, 20147, 20149, 20161,
+    20173, 20177, 20183, 20201, 20219, 20231,
+    20233, 20249, 20261, 20269, 20287, 20297,
+    20323, 20327, 20333, 20341, 20347, 20353,
+    20357, 20359, 20369, 20389, 20393, 20399,
+    20407, 20411, 20431, 20441, 20443, 20477,
+    20479, 20483, 20507, 20509, 20521, 20533,
+    20543, 20549, 20551, 20563, 20593, 20599,
+    20611, 20627, 20639, 20641, 20663, 20681,
+    20693, 20707, 20717, 20719, 20731, 20743,
+    20747, 20749, 20753, 20759, 20771, 20773,
+    20789, 20807, 20809, 20849, 20857, 20873,
+    20879, 20887, 20897, 20899, 20903, 20921,
+    20929, 20939, 20947, 20959, 20963, 20981,
+    20983, 21001, 21011, 21013, 21017, 21019,
+    21023, 21031, 21059, 21061, 21067, 21089,
+    21101, 21107, 21121, 21139, 21143, 21149,
+    21157, 21163, 21169, 21179, 21187, 21191,
+    21193, 21211, 21221, 21227, 21247, 21269,
+    21277, 21283, 21313, 21317, 21319, 21323,
+    21341, 21347, 21377, 21379, 21383, 21391,
+    21397, 21401, 21407, 21419, 21433, 21467,
+    21481, 21487, 21491, 21493, 21499, 21503,
+    21517, 21521, 21523, 21529, 21557, 21559,
+    21563, 21569, 21577, 21587, 21589, 21599,
+    21601, 21611, 21613, 21617, 21647, 21649,
+    21661, 21673, 21683, 21701, 21713, 21727,
+    21737, 21739, 21751, 21757, 21767, 21773,
+    21787, 21799, 21803, 21817, 21821, 21839,
+    21841, 21851, 21859, 21863, 21871, 21881,
+    21893, 21911, 21929, 21937, 21943, 21961,
+    21977, 21991, 21997, 22003, 22013, 22027,
+    22031, 22037, 22039, 22051, 22063, 22067,
+    22073, 22079, 22091, 22093, 22109, 22111,
+    22123, 22129, 22133, 22147, 22153, 22157,
+    22159, 22171, 22189, 22193, 22229, 22247,
+    22259, 22271, 22273, 22277, 22279, 22283,
+    22291, 22303, 22307, 22343, 22349, 22367,
+    22369, 22381, 22391, 22397, 22409, 22433,
+    22441, 22447, 22453, 22469, 22481, 22483,
+    22501, 22511, 22531, 22541, 22543, 22549,
+    22567, 22571, 22573, 22613, 22619, 22621,
+    22637, 22639, 22643, 22651, 22669, 22679,
+    22691, 22697, 22699, 22709, 22717, 22721,
+    22727, 22739, 22741, 22751, 22769, 22777,
+    22783, 22787, 22807, 22811, 22817, 22853,
+    22859, 22861, 22871, 22877, 22901, 22907,
+    22921, 22937, 22943, 22961, 22963, 22973,
+    22993, 23003, 23011, 23017, 23021, 23027,
+    23029, 23039, 23041, 23053, 23057, 23059,
+    23063, 23071, 23081, 23087, 23099, 23117,
+    23131, 23143, 23159, 23167, 23173, 23189,
+    23197, 23201, 23203, 23209, 23227, 23251,
+    23269, 23279, 23291, 23293, 23297, 23311,
+    23321, 23327, 23333, 23339, 23357, 23369,
+    23371, 23399, 23417, 23431, 23447, 23459,
+    23473, 23497, 23509, 23531, 23537, 23539,
+    23549, 23557, 23561, 23563, 23567, 23581,
+    23593, 23599, 23603, 23609, 23623, 23627,
+    23629, 23633, 23663, 23669, 23671, 23677,
+    23687, 23689, 23719, 23741, 23743, 23747,
+    23753, 23761, 23767, 23773, 23789, 23801,
+    23813, 23819, 23827, 23831, 23833, 23857,
+    23869, 23873, 23879, 23887, 23893, 23899,
+    23909, 23911, 23917, 23929, 23957, 23971,
+    23977, 23981, 23993, 24001, 24007, 24019,
+    24023, 24029, 24043, 24049, 24061, 24071,
+    24077, 24083, 24091, 24097, 24103, 24107,
+    24109, 24113, 24121, 24133, 24137, 24151,
+    24169, 24179, 24181, 24197, 24203, 24223,
+    24229, 24239, 24247, 24251, 24281, 24317,
+    24329, 24337, 24359, 24371, 24373, 24379,
+    24391, 24407, 24413, 24419, 24421, 24439,
+    24443, 24469, 24473, 24481, 24499, 24509,
+    24517, 24527, 24533, 24547, 24551, 24571,
+    24593, 24611, 24623, 24631, 24659, 24671,
+    24677, 24683, 24691, 24697, 24709, 24733,
+    24749, 24763, 24767, 24781, 24793, 24799,
+    24809, 24821, 24841, 24847, 24851, 24859,
+    24877, 24889, 24907, 24917, 24919, 24923,
+    24943, 24953, 24967, 24971, 24977, 24979,
+    24989, 25013, 25031, 25033, 25037, 25057,
+    25073, 25087, 25097, 25111, 25117, 25121,
+    25127, 25147, 25153, 25163, 25169, 25171,
+    25183, 25189, 25219, 25229, 25237, 25243,
+    25247, 25253, 25261, 25301, 25303, 25307,
+    25309, 25321, 25339, 25343, 25349, 25357,
+    25367, 25373, 25391, 25409, 25411, 25423,
+    25439, 25447, 25453, 25457, 25463, 25469,
+    25471, 25523, 25537, 25541, 25561, 25577,
+    25579, 25583, 25589, 25601, 25603, 25609,
+    25621, 25633, 25639, 25643, 25657, 25667,
+    25673, 25679, 25693, 25703, 25717, 25733,
+    25741, 25747, 25759, 25763, 25771, 25793,
+    25799, 25801, 25819, 25841, 25847, 25849,
+    25867, 25873, 25889, 25903, 25913, 25919,
+    25931, 25933, 25939, 25943, 25951, 25969,
+    25981, 25997, 25999, 26003, 26017, 26021,
+    26029, 26041, 26053, 26083, 26099, 26107,
+    26111, 26113, 26119, 26141, 26153, 26161,
+    26171, 26177, 26183, 26189, 26203, 26209,
+    26227, 26237, 26249, 26251, 26261, 26263,
+    26267, 26293, 26297, 26309, 26317, 26321,
+    26339, 26347, 26357, 26371, 26387, 26393,
+    26399, 26407, 26417, 26423, 26431, 26437,
+    26449, 26459, 26479, 26489, 26497, 26501,
+    26513, 26539, 26557, 26561, 26573, 26591,
+    26597, 26627, 26633, 26641, 26647, 26669,
+    26681, 26683, 26687, 26693, 26699, 26701,
+    26711, 26713, 26717, 26723, 26729, 26731,
+    26737, 26759, 26777, 26783, 26801, 26813,
+    26821, 26833, 26839, 26849, 26861, 26863,
+    26879, 26881, 26891, 26893, 26903, 26921,
+    26927, 26947, 26951, 26953, 26959, 26981,
+    26987, 26993, 27011, 27017, 27031, 27043,
+    27059, 27061, 27067, 27073, 27077, 27091,
+    27103, 27107, 27109, 27127, 27143, 27179,
+    27191, 27197, 27211, 27239, 27241, 27253,
+    27259, 27271, 27277, 27281, 27283, 27299,
+    27329, 27337, 27361, 27367, 27397, 27407,
+    27409, 27427, 27431, 27437, 27449, 27457,
+    27479, 27481, 27487, 27509, 27527, 27529,
+    27539, 27541, 27551, 27581, 27583, 27611,
+    27617, 27631, 27647, 27653, 27673, 27689,
+    27691, 27697, 27701, 27733, 27737, 27739,
+    27743, 27749, 27751, 27763, 27767, 27773,
+    27779, 27791, 27793, 27799, 27803, 27809,
+    27817, 27823, 27827, 27847, 27851, 27883,
+    27893, 27901, 27917, 27919, 27941, 27943,
+    27947, 27953, 27961, 27967, 27983, 27997,
+    28001, 28019, 28027, 28031, 28051, 28057,
+    28069, 28081, 28087, 28097, 28099, 28109,
+    28111, 28123, 28151, 28163, 28181, 28183,
+    28201, 28211, 28219, 28229, 28277, 28279,
+    28283, 28289, 28297, 28307, 28309, 28319,
+    28349, 28351, 28387, 28393, 28403, 28409,
+    28411, 28429, 28433, 28439, 28447, 28463,
+    28477, 28493, 28499, 28513, 28517, 28537,
+    28541, 28547, 28549, 28559, 28571, 28573,
+    28579, 28591, 28597, 28603, 28607, 28619,
+    28621, 28627, 28631, 28643, 28649, 28657,
+    28661, 28663, 28669, 28687, 28697, 28703,
+    28711, 28723, 28729, 28751, 28753, 28759,
+    28771, 28789, 28793, 28807, 28813, 28817,
+    28837, 28843, 28859, 28867, 28871, 28879,
+    28901, 28909, 28921, 28927, 28933, 28949,
+    28961, 28979, 29009, 29017, 29021, 29023,
+    29027, 29033, 29059, 29063, 29077, 29101,
+    29123, 29129, 29131, 29137, 29147, 29153,
+    29167, 29173, 29179, 29191, 29201, 29207,
+    29209, 29221, 29231, 29243, 29251, 29269,
+    29287, 29297, 29303, 29311, 29327, 29333,
+    29339, 29347, 29363, 29383, 29387, 29389,
+    29399, 29401, 29411, 29423, 29429, 29437,
+    29443, 29453, 29473, 29483, 29501, 29527,
+    29531, 29537, 29567, 29569, 29573, 29581,
+    29587, 29599, 29611, 29629, 29633, 29641,
+    29663, 29669, 29671, 29683, 29717, 29723,
+    29741, 29753, 29759, 29761, 29789, 29803,
+    29819, 29833, 29837, 29851, 29863, 29867,
+    29873, 29879, 29881, 29917, 29921, 29927,
+    29947, 29959, 29983, 29989, 30011, 30013,
+    30029, 30047, 30059, 30071, 30089, 30091,
+    30097, 30103, 30109, 30113, 30119, 30133,
+    30137, 30139, 30161, 30169, 30181, 30187,
+    30197, 30203, 30211, 30223, 30241, 30253,
+    30259, 30269, 30271, 30293, 30307, 30313,
+    30319, 30323, 30341, 30347, 30367, 30389,
+    30391, 30403, 30427, 30431, 30449, 30467,
+    30469, 30491, 30493, 30497, 30509, 30517,
+    30529, 30539, 30553, 30557, 30559, 30577,
+    30593, 30631, 30637, 30643, 30649, 30661,
+    30671, 30677, 30689, 30697, 30703, 30707,
+    30713, 30727, 30757, 30763, 30773, 30781,
+    30803, 30809, 30817, 30829, 30839, 30841,
+    30851, 30853, 30859, 30869, 30871, 30881,
+    30893, 30911, 30931, 30937, 30941, 30949,
+    30971, 30977, 30983, 31013, 31019, 31033,
+    31039, 31051, 31063, 31069, 31079, 31081,
+    31091, 31121, 31123, 31139, 31147, 31151,
+    31153, 31159, 31177, 31181, 31183, 31189,
+    31193, 31219, 31223, 31231, 31237, 31247,
+    31249, 31253, 31259, 31267, 31271, 31277,
+    31307, 31319, 31321, 31327, 31333, 31337,
+    31357, 31379, 31387, 31391, 31393, 31397,
+    31469, 31477, 31481, 31489, 31511, 31513,
+    31517, 31531, 31541, 31543, 31547, 31567,
+    31573, 31583, 31601, 31607, 31627, 31643,
+    31649, 31657, 31663, 31667, 31687, 31699,
+    31721, 31723, 31727, 31729, 31741, 31751,
+    31769, 31771, 31793, 31799, 31817, 31847,
+    31849, 31859, 31873, 31883, 31891, 31907,
+    31957, 31963, 31973, 31981, 31991, 32003,
+    32009, 32027, 32029, 32051, 32057, 32059,
+    32063, 32069, 32077, 32083, 32089, 32099,
+    32117, 32119, 32141, 32143, 32159, 32173,
+    32183, 32189, 32191, 32203, 32213, 32233,
+    32237, 32251, 32257, 32261, 32297, 32299,
+    32303, 32309, 32321, 32323, 32327, 32341,
+    32353, 32359, 32363, 32369, 32371, 32377,
+    32381, 32401, 32411, 32413, 32423, 32429,
+    32441, 32443, 32467, 32479, 32491, 32497,
+    32503, 32507, 32531, 32533, 32537, 32561,
+    32563, 32569, 32573, 32579, 32587, 32603,
+    32609, 32611, 32621, 32633, 32647, 32653,
+    32687, 32693, 32707, 32713, 32717, 32719,
+    32749, 0
+};
+
+static const int bigprimes [] = {
+    536300041, 536300047, 536300053, 536300069, 536300081, 536300117,
+    536300119, 536300129, 536300143, 536300153, 536300159, 536300179,
+    536300197, 536300231, 536300239, 536300249, 536300287, 536300321,
+    536300339, 536300357, 536300419, 536300431, 536300437, 536300447,
+    536300477, 536300489, 536300521, 536300537, 536300563, 536300573,
+    536300579, 536300621, 536300641, 536300657, 536300663, 536300731,
+    536300747, 536300759, 536300761, 536300767, 536300777, 536300801,
+    536300803, 536300813, 536300861, 536300881, 536300909, 536300911,
+    536300927, 536300939, 536300969, 536301001, 536301041, 536301043,
+    536301149, 536301169, 536301179, 536301187, 536301191, 536301221,
+    536301229, 536301253, 536301287, 536301317, 536301341, 536301343,
+    536301377, 536301401, 536301407, 536301497, 536301523, 536301527,
+    536301539, 536301583, 536301587, 536301589, 536301613, 536301641,
+    536301673, 536301713, 536301743, 536301751, 536301769, 536301781,
+    536301793, 536301827, 536301841, 536301851, 536301863, 536301881,
+    536301889, 536301919, 536301929, 536301943, 536301947, 536301967,
+    536302001, 536302003, 536302027, 536302051, 536302061, 536302069,
+    536302073, 536302141, 536302157, 536302183, 536302229, 536302231,
+    536302253, 536302279, 536302313, 536302369, 536302381, 536302397,
+    536302421, 536302433, 536302439, 536302441, 536302447, 536302463,
+    536302513, 536302517, 536302541, 536302549, 536302567, 536302577,
+    536302589, 536302681, 536302687, 536302691, 536302733, 536302783,
+    536302801, 536302817, 536302847, 536302867, 536302889, 536302903,
+    536302909, 536302931, 536302957, 536302969, 536302993, 536302997,
+    536303021, 536303039, 536303071, 536303087, 536303099, 536303107,
+    536303143, 536303179, 536303191, 536303263, 536303281, 536303297,
+    536303303, 536303359, 536303363, 536303371, 536303377, 536303381,
+    536303401, 536303407, 536303413, 536303447, 536303459, 536303477,
+    536303483, 536303497, 536303501, 536303507, 536303513, 536303527,
+    536303623, 536303681, 536303693, 536303701, 536303707, 536303731,
+    536303737, 536303759, 536303809, 536303819, 536303827, 536303843,
+    536303849, 536303881, 536303891, 536303893, 536303921, 536303927,
+    536303939, 536303941, 536303951, 536303959, 536303987, 536304001,
+    536304007, 536304017, 536304019, 536304029, 536304037, 536304059,
+    536304091, 536304103, 536304143, 536304161, 536304187, 536304239,
+    536304269, 536304283, 536304311, 536304319, 536304331, 536304359,
+    536304361, 536304401, 536304413, 536304443, 536304449, 536304463,
+    536304473, 536304479, 536304481, 536304487, 536304499, 536304523,
+    536304539, 536304541, 536304551, 536304553, 536304589, 536304611,
+    536304653, 536304683, 536304761, 536304779, 536304803, 536304877,
+    536304911, 536304913, 536304941, 536304953, 536304959, 536304971,
+    536305013, 536305027, 536305057, 536305097, 536305123, 536305157,
+    536305163, 536305181, 536305193, 536305201, 536305213, 536305219,
+    536305261, 536305277, 536305279, 536305291, 536305313, 536305327,
+    536305333, 536305369, 536305423, 536305489, 536305501, 536305519,
+    536305537, 536305577, 536305591, 536305607, 536305621, 536305631,
+    536305661, 536305691, 536305699, 536305703, 536305711, 536305727,
+    536305751, 536305753, 536305769, 536305793, 536305831, 536305843,
+    536305849, 536305873, 536305879, 536305897, 536305909, 536305937,
+    536305949, 536305967, 536305997, 536305999, 536306003, 536306011,
+    536306039, 536306081, 536306087, 536306101, 536306129, 536306159,
+    536306161, 536306167, 536306171, 536306213, 536306219, 536306227,
+    536306233, 536306317, 536306333, 536306339, 536306347, 536306357,
+    536306371, 536306473, 536306489, 536306503, 536306513, 536306539,
+    536306569, 536306579, 536306581, 536306587, 536306593, 536306653,
+    536306669, 536306671, 536306677, 536306717, 536306753, 536306761,
+    536306767, 536306777, 536306783, 536306809, 536306821, 536306839,
+    536306843, 536306887, 536306917, 536306921, 536306933, 536306987,
+    536306999, 536307017, 536307029, 536307043, 536307047, 536307067,
+    536307097, 536307113, 536307131, 536307139, 536307197, 536307217,
+    536307229, 536307241, 536307251, 536307259, 536307283, 536307293,
+    536307311, 536307349, 536307367, 536307383, 536307389, 536307397,
+    536307427, 536307437, 536307451, 536307539, 536307589, 536307599,
+    536307613, 536307649, 536307691, 536307749, 536307797, 536307799,
+    536307833, 536307847, 536307899, 536307917, 536307953, 536307971,
+    536307977, 536308021, 536308033, 536308051, 536308063, 536308093,
+    536308099, 536308103, 536308109, 536308121, 536308139, 536308141,
+    536308147, 536308177, 536308217, 536308243, 536308261, 536308291,
+    536308313, 536308343, 536308363, 536308387, 536308391, 536308403,
+    536308417, 536308447, 536308453, 536308471, 536308481, 536308501,
+    536308517, 536308519, 536308529, 536308547, 536308559, 536308601,
+    536308603, 536308613, 536308637, 536308651, 536308691, 536308697,
+    536308699, 536308723, 536308739, 536308753, 536308769, 536308783,
+    536308807, 536308813, 536308847, 536308849, 536308853, 536308859,
+    536308873, 536308909, 536308921, 536308933, 536308951, 536308967,
+    536309003, 536309041, 536309051, 536309063, 536309087, 536309099,
+    536309107, 536309113, 536309119, 536309129, 536309131, 536309141,
+    536309161, 536309167, 536309171, 536309197, 536309203, 536309227,
+    536309303, 536309369, 536309401, 536309419, 536309429, 536309437,
+    536309453, 536309467, 536309497, 536309503, 536309507, 536309549,
+    536309623, 536309629, 536309633, 536309651, 536309663, 536309671,
+    536309681, 536309687, 536309689, 536309707, 536309737, 536309747,
+    536309759, 536309797, 536309801, 536309819, 536309821, 536309833,
+    536309843, 536309849, 536309867, 536309869, 536309887, 536309911,
+    536309923, 536309933, 536309989, 536310023, 536310043, 536310077,
+    536310083, 536310097, 536310119, 536310133, 536310139, 536310149,
+    536310161, 536310179, 536310191, 536310197, 536310221, 536310241,
+    536310259, 536310263, 536310293, 536310331, 536310337, 536310347,
+    536310349, 536310403, 536310409, 536310433, 536310461, 536310493,
+    536310563, 536310569, 536310581, 536310583, 536310589, 536310613,
+    536310617, 536310653, 536310661, 536310673, 536310689, 536310703,
+    536310793, 536310809, 536310811, 536310821, 536310823, 536310839,
+    536310851, 536310871, 536310877, 536310889, 536310911, 536310959,
+    536310961, 536310977, 536310989, 536311021, 536311051, 536311091,
+    536311109, 536311133, 536311141, 536311159, 536311163, 536311199,
+    536311213, 536311229, 536311277, 536311301, 536311327, 536311333,
+    536311339, 536311379, 536311397, 536311403, 536311417, 536311429,
+    536311481, 536311513, 536311541, 536311549, 536311553, 536311561,
+    536311583, 536311603, 536311619, 536311621, 536311639, 536311663,
+    536311747, 536311757, 536311759, 536311771, 536311793, 536311799,
+    536311807, 536311847, 536311849, 536311859, 536311913, 536311943,
+    536311949, 536311973, 536311987, 536311991, 536312009, 536312011,
+    536312017, 536312033, 536312047, 536312057, 536312081, 536312083,
+    536312089, 536312099, 536312113, 536312129, 536312143, 536312171,
+    536312173, 536312197, 536312207, 536312251, 536312269, 536312291,
+    536312333, 536312339, 536312377, 536312389, 536312401, 536312437,
+    536312473, 536312477, 536312479, 536312507, 536312509, 536312519,
+    536312533, 536312587, 536312627, 536312659, 536312681, 536312683,
+    536312737, 536312779, 536312801, 536312831, 536312849, 536312879,
+    536312897, 536312939, 536312951, 536312971, 536313023, 536313061,
+    536313079, 536313119, 536313143, 536313179, 536313221, 536313223,
+    536313227, 536313233, 536313301, 536313313, 536313341, 536313347,
+    536313389, 536313397, 536313451, 536313461, 536313469, 536313473,
+    536313499, 536313527, 536313529, 536313539, 536313581, 536313593,
+    536313641, 536313677, 536313683, 536313689, 536313749, 536313781,
+    536313809, 536313829, 536313859, 536313871, 536313881, 536313889,
+    536313913, 536313917, 536313923, 536313937, 536313941, 536313949,
+    536313971, 536313983, 536314003, 536314019, 536314021, 536314063,
+    536314087, 536314109, 536314123, 536314127, 536314151, 536314157,
+    536314171, 536314199, 536314201, 536314217, 536314241, 536314271,
+    536314279, 536314301, 536314319, 536314369, 536314417, 536314421,
+    536314423, 536314433, 536314531, 536314547, 536314549, 536314567,
+    536314591, 536314613, 536314631, 536314637, 536314651, 536314673,
+    536314679, 536314687, 536314763, 536314783, 536314817, 536314841,
+    536314853, 536314879, 536314903, 536314907, 536314913, 536314927,
+    536314939, 536314969, 536315027, 536315029, 536315047, 536315069,
+    536315077, 536315093, 536315113, 536315141, 536315161, 536315189,
+    536315239, 536315243, 536315257, 536315291, 536315293, 536315309,
+    536315363, 536315387, 536315389, 536315401, 536315411, 536315419,
+    536315431, 536315443, 536315447, 536315453, 536315459, 536315471,
+    536315497, 536315551, 536315561, 536315569, 536315573, 536315581,
+    536315623, 536315653, 536315671, 536315701, 536315713, 536315729,
+    536315749, 536315789, 536315807, 536315827, 536315833, 536315849,
+    536315891, 536315921, 536315929, 536315951, 536315963, 536315971,
+    536315977, 536316019, 536316023, 536316061, 536316091, 536316163,
+    536316191, 536316197, 536316217, 536316233, 536316241, 536316251,
+    536316269, 536316281, 536316299, 536316311, 536316353, 536316373,
+    536316427, 536316433, 536316467, 536316481, 536316491, 536316499,
+    536316509, 536316541, 536316587, 536316601, 536316617, 536316631,
+    536316637, 536316643, 536316653, 536316673, 536316689, 536316713,
+    536316727, 536316763, 536316779, 536316811, 536316827, 536316839,
+    536316841, 536316863, 536316899, 536316917, 536316929, 536316947,
+    536316973, 536316997, 536317043, 536317073, 536317079, 536317091,
+    536317121, 536317129, 536317147, 536317153, 536317157, 536317163,
+    536317219, 536317231, 536317261, 536317283, 536317297, 536317319,
+    536317321, 536317337, 536317361, 536317363, 536317367, 536317399,
+    536317409, 536317417, 536317451, 536317469, 536317477, 536317501,
+    536317511, 536317567, 536317591, 536317609, 536317643, 536317681,
+    536317687, 536317709, 536317721, 536317783, 536317811, 536317861,
+    536317879, 536317891, 536317897, 536317907, 536317913, 536317927,
+    536317931, 536317939, 536317963, 536317981, 536318047, 536318051,
+    536318053, 536318093, 536318099, 536318113, 536318143, 536318173,
+    536318177, 536318207, 536318213, 536318221, 536318239, 536318249,
+    536318297, 536318303, 536318311, 536318351, 536318353, 536318381,
+    536318401, 536318407, 536318413, 536318429, 536318459, 536318467,
+    536318473, 536318483, 536318509, 536318543, 536318557, 536318591,
+    536318611, 536318621, 536318633, 536318647, 536318683, 536318707,
+    536318711, 536318767, 536318773, 536318777, 536318789, 536318801,
+    536318891, 536318903, 536318929, 536318933, 536318957, 536318999,
+    536319001, 536319013, 536319041, 536319059, 536319067, 536319089,
+    536319139, 536319143, 536319149, 536319151, 536319187, 536319193,
+    536319239, 536319253, 536319257, 536319283, 536319299, 536319317,
+    536319323, 536319337, 536319353, 536319361, 536319373, 536319409,
+    536319431, 536319463, 536319467, 536319493, 536319529, 536319541,
+    536319559, 536319577, 536319599, 536319601, 536319611, 536319613,
+    536319629, 536319659, 536319671, 536319673, 536319677, 536319697,
+    536319701, 536319709, 536319733, 536319737, 536319739, 536319803,
+    536319827, 536319829, 536319877, 536319907, 536319913, 536319919,
+    536319923, 536319943, 536319967, 536319989, 536320033, 536320051,
+    536320067, 536320121, 536320153, 536320159, 536320219, 536320249,
+    536320271, 536320283, 536320289, 536320307, 536320331, 536320349,
+    536320361, 536320387, 536320397, 536320399, 536320423, 536320427,
+    536320457, 536320459, 536320481, 536320501, 536320517, 536320523,
+    536320531, 536320537, 536320567, 536320579, 536320597, 536320627,
+    536320637, 536320643, 536320649, 536320669, 536320699, 536320717,
+    536320747, 536320769, 536320783, 536320787, 536320793, 536320817,
+    536320819, 536320927, 536320931, 536320937, 536320951, 536320963,
+    536320973, 536320991, 536321003, 536321039, 536321057, 536321063,
+    536321077, 536321087, 536321141, 536321207, 536321231, 536321237,
+    536321249, 536321251, 536321267, 536321293, 536321339, 536321419,
+    536321449, 536321459, 536321473, 536321479, 536321503, 536321509,
+    536321551, 536321579, 536321581, 536321587, 536321603, 536321629,
+    536321651, 536321657, 536321663, 536321693, 536321711, 536321749,
+    536321789, 536321809, 536321813, 536321833, 536321837, 536321867,
+    536321869, 536321879, 536321881, 536321887, 536321897, 536321923,
+    536321957, 536322011, 536322023, 536322049, 536322091, 536322097,
+    536322113, 536322131, 536322161, 536322169, 536322191, 536322197,
+    536322209, 536322229, 536322287, 536322301, 536322343, 536322377,
+    536322383, 536322419, 536322463, 536322467, 536322497, 536322509,
+    536322541, 536322559, 536322581, 536322583, 536322637, 536322643,
+    536322667, 536322679, 536322697, 536322707, 536322727, 536322757,
+    536322767, 536322769, 536322779, 536322793, 536322799, 536322877,
+    536322883, 536322887, 536322923, 536322929, 536322979, 536323001,
+    536323003, 536323027, 536323037, 536323061, 536323097, 536323153,
+    536323181, 536323213, 536323237, 536323283, 536323289, 536323297,
+    536323313, 536323321, 536323349, 536323351, 536323357, 536323423,
+    536323441, 536323457, 536323471, 536323519, 536323537, 536323561,
+    536323597, 536323609, 536323631, 536323643, 536323657, 536323661,
+    536323679, 536323681, 536323699, 536323717, 536323751, 536323757,
+    536323787, 536323789, 536323813, 536323831, 536323841, 536323859,
+    536323873, 536323889, 536323897, 536323933, 536323937, 536323943,
+    536323967, 536323979, 536323981, 536324027, 536324053, 536324069,
+    536324071, 536324093, 536324099, 536324147, 536324161, 536324197,
+    536324203, 536324207, 536324209, 536324227, 536324237, 536324291,
+    536324297, 536324317, 536324323, 536324351, 536324359, 536324387,
+    536324401, 536324407, 536324417, 536324441, 536324479, 536324489,
+    536324491, 536324513, 536324597, 536324623, 536324629, 536324671,
+    536324693, 536324743, 536324771, 536324779, 536324797, 536324801,
+    536324839, 536324851, 536324863, 536324911, 536324923, 536324963,
+    536324969, 536325011, 536325019, 536325047, 536325071, 536325077,
+    536325121, 536325133, 536325161, 536325221, 536325227, 536325239,
+    536325269, 536325287, 536325289, 536325329, 536325337, 536325353,
+    536325403, 536325443, 536325463, 536325473, 536325479, 536325487,
+    536325509, 536325527, 536325529, 536325533, 536325563, 536325599,
+    536325617, 536325631, 536325641, 536325667, 536325679, 536325689,
+    536325697, 536325701, 536325719, 536325731, 536325743, 536325763,
+    536325851, 536325887, 536325893, 536325917, 536325929, 536325931,
+    536325949, 536325967, 536326001, 536326003, 536326019, 536326033,
+    536326039, 536326069, 536326097, 536326111, 536326117, 536326127,
+    536326139, 536326151, 536326159, 536326177, 536326187, 536326249,
+    536326267, 536326279, 536326283, 536326303, 536326321, 536326327,
+    536326337, 536326391, 536326411, 536326429, 536326501, 536326519,
+    536326529, 536326537, 536326597, 536326607, 536326621, 536326631,
+    536326639, 536326643, 536326649, 536326669, 536326717, 536326733,
+    536326751, 536326793, 536326799, 536326801, 536326837, 536326849,
+    536326853, 536326873, 536326937, 536326963, 536327009, 536327021,
+    536327039, 536327053, 536327059, 536327093, 536327119, 536327147,
+    536327149, 536327153, 536327171, 536327219, 536327243, 536327257,
+    536327263, 536327303, 536327329, 536327333, 536327369, 536327399,
+    536327411, 536327447, 536327503, 536327531, 536327557, 536327567,
+    536327579, 536327581, 536327587, 536327629, 536327651, 536327663,
+    536327707, 536327717, 536327767, 536327783, 536327789, 536327791,
+    536327819, 536327843, 536327879, 536327881, 536327923, 536327927,
+    536327933, 536327947, 536327959, 536327971, 536327983, 536328031,
+    536328047, 536328049, 536328083, 536328097, 536328103, 536328119,
+    536328127, 536328161, 536328167, 536328173, 536328187, 536328203,
+    536328259, 536328263, 536328269, 536328301, 536328307, 536328311,
+    536328337, 536328343, 536328347, 536328361, 536328383, 536328413,
+    536328449, 536328469, 536328497, 536328509, 536328553, 536328593,
+    536328601, 536328643, 536328647, 536328649, 536328671, 536328679,
+    536328691, 536328701, 536328721, 536328731, 536328773, 536328781,
+    536328829, 536328839, 536328847, 536328851, 536328853, 536328857,
+    536328893, 536328901, 536328907, 536328997, 536329007, 536329009,
+    536329021, 536329063, 536329069, 536329081, 536329091, 536329181,
+    536329193, 536329223, 536329229, 536329247, 536329253, 536329271,
+    536329273, 536329279, 536329309, 536329363, 536329403, 536329459,
+    536329463, 536329489, 536329513, 536329517, 536329531, 536329559,
+    536329601, 536329603, 536329621, 536329627, 536329681, 536329687,
+    536329697, 536329699, 536329723, 536329757, 536329861, 536329877,
+    536329879, 536329909, 536329919, 536329933, 536329943, 536329987,
+    536329993, 536329999, 536330009, 536330021, 536330027, 536330029,
+    536330057, 536330063, 536330071, 536330083, 536330129, 536330149,
+    536330153, 536330159, 536330189, 536330213, 536330231, 536330299,
+    536330323, 536330339, 536330381, 536330383, 536330393, 536330419,
+    536330453, 536330507, 536330513, 536330533, 536330539, 536330567,
+    536330617, 536330653, 536330681, 536330699, 536330713, 536330741,
+    536330749, 536330777, 536330791, 536330819, 536330831, 536330867,
+    536330869, 536330887, 536330891, 536330911, 536330939, 536330941,
+    536330953, 536330957, 536331023, 536331041, 536331049, 536331071,
+    536331091, 536331097, 536331137, 536331167, 536331179, 536331193,
+    536331233, 536331277, 536331353, 536331359, 536331377, 536331407,
+    536331421, 536331431, 536331437, 536331443, 536331461, 536331463,
+    536331469, 536331473, 536331479, 536331491, 536331559, 536331571,
+    536331577, 536331599, 536331661, 536331673, 536331709, 536331737,
+    536331743, 536331767, 536331769, 536331781, 536331797, 536331811,
+    536331823, 536331833, 536331839, 536331853, 536331863, 536331877,
+    536331881, 536331893, 536331919, 536331923, 536331953, 536331959,
+    536331967, 536331977, 536332037, 536332039, 536332051, 536332063,
+    536332079, 536332117, 536332123, 536332127, 536332157, 536332169,
+    536332189, 536332217, 536332259, 536332273, 536332283, 536332289,
+    536332297, 536332319, 536332339, 536332373, 536332403, 536332411,
+    536332417, 536332441, 536332451, 536332477, 536332483, 536332487,
+    536332499, 536332543, 536332553, 536332571, 536332619, 536332631,
+    536332633, 536332721, 536332739, 536332781, 536332787, 536332799,
+    536332843, 536332859, 536332861, 536332879, 536332903, 536332919,
+    536332921, 536332961, 536332967, 536332981, 536332999, 536333003,
+    536333009, 536333011, 536333041, 536333053, 536333087, 536333101,
+    536333107, 536333131, 536333137, 536333183, 536333233, 536333243,
+    536333249, 536333269, 536333339, 536333351, 536333381, 536333401,
+    536333443, 536333477, 536333489, 536333507, 536333521, 536333531,
+    536333543, 536333549, 536333563, 536333579, 536333621, 536333639,
+    536333641, 536333657, 536333689, 536333713, 536333719, 536333789,
+    536333813, 536333839, 536333851, 536333857, 536333869, 536333887,
+    536333893, 536333911, 536333927, 536333933, 536333939, 536333953,
+    536333971, 536333989, 536333999, 536334011, 536334023, 536334041,
+    536334067, 536334077, 536334101, 536334103, 536334119, 536334163,
+    536334179, 536334199, 536334209, 536334221, 536334233, 536334247,
+    536334257, 536334283, 536334301, 536334311, 536334319, 536334347,
+    536334353, 536334389, 536334457, 536334511, 536334517, 536334523,
+    536334529, 536334551, 536334583, 536334599, 536334607, 536334637,
+    536334691, 536334707, 536334709, 536334791, 536334797, 536334803,
+    536334809, 536334859, 536334893, 536334913, 536334977, 536334979,
+    536335003, 536335031, 536335069, 536335073, 536335081, 536335147,
+    536335157, 536335169, 536335181, 536335231, 536335243, 536335273,
+    536335279, 536335301, 536335337, 536335339, 536335343, 536335357,
+    536335379, 536335381, 536335441, 536335463, 536335493, 536335511,
+    536335529, 536335537, 536335549, 536335559, 536335573, 536335577,
+    536335649, 536335663, 536335691, 536335721, 536335727, 536335733,
+    536335741, 536335747, 536335769, 536335777, 536335799, 536335823,
+    536335841, 536335903, 536335927, 536335931, 536335937, 536335939,
+    536335951, 536335963, 536335967, 536335993, 536335997, 536336023,
+    536336051, 536336069, 536336071, 536336083, 536336093, 536336117,
+    536336131, 536336147, 536336153, 536336167, 536336173, 536336191,
+    536336209, 536336219, 536336221, 536336233, 536336249, 536336257,
+    536336261, 536336263, 536336267, 536336299, 536336321, 536336387,
+    536336399, 536336419, 536336431, 536336453, 536336459, 536336467,
+    536336477, 536336483, 536336513, 536336531, 536336557, 536336573,
+    536336597, 536336629, 536336639, 536336651, 536336653, 536336657,
+    536336659, 536336681, 536336683, 536336687, 536336711, 536336741,
+    536336753, 536336803, 536336887, 536336903, 536336909, 536336929,
+    536336947, 536336981, 536336987, 536336989, 536337013, 536337019,
+    536337037, 536337047, 536337091, 536337127, 536337173, 536337247,
+    536337283, 536337287, 536337343, 536337349, 536337413, 536337421,
+    536337433, 536337457, 536337481, 536337499, 536337509, 536337511,
+    536337563, 536337577, 536337623, 536337631, 536337647, 536337653,
+    536337673, 536337677, 536337691, 536337721, 536337731, 536337751,
+    536337761, 536337773, 536337779, 536337797, 536337799, 536337827,
+    536337883, 536337953, 536337979, 536337983, 536338001, 536338013,
+    536338027, 536338043, 536338057, 536338063, 536338067, 536338073,
+    536338079, 536338091, 536338141, 536338163, 536338181, 536338193,
+    536338207, 536338241, 536338247, 536338279, 536338303, 536338367,
+    536338391, 536338393, 536338427, 536338433, 536338477, 536338493,
+    536338501, 536338513, 536338531, 536338549, 536338553, 536338577,
+    536338603, 536338619, 536338637, 536338639, 536338651, 536338687,
+    536338709, 536338711, 536338741, 536338801, 536338813, 536338823,
+    536338837, 536338841, 536338849, 536338877, 536338879, 536338883,
+    536338903, 536338919, 536338921, 536338927, 536338931, 536338937,
+    536338951, 536338981, 536338991, 536339003, 536339071, 536339077,
+    536339099, 536339101, 536339107, 536339113, 536339117, 536339123,
+    536339159, 536339173, 536339261, 536339263, 536339291, 536339299,
+    536339303, 536339317, 536339333, 536339351, 536339393, 536339399,
+    536339411, 536339449, 536339497, 536339501, 536339521, 536339539,
+    536339563, 536339567, 536339597, 536339641, 536339719, 536339759,
+    536339761, 536339777, 536339779, 536339801, 536339813, 536339821,
+    536339831, 536339861, 536339887, 536339933, 536339977, 536340011,
+    536340017, 536340023, 536340029, 536340041, 536340043, 536340053,
+    536340061, 536340073, 536340109, 536340131, 536340143, 536340163,
+    536340173, 536340187, 536340193, 536340209, 536340221, 536340241,
+    536340283, 536340317, 536340377, 536340403, 536340449, 536340491,
+    536340523, 536340533, 536340551, 536340583, 536340613, 536340619,
+    536340643, 536340647, 536340653, 536340659, 536340661, 536340691,
+    536340719, 536340733, 536340737, 536340767, 536340781, 536340799,
+    536340809, 536340811, 536340821, 536340823, 536340851, 536340881,
+    536340907, 536340929, 536340941, 536340983, 536340991, 536340997,
+    536341027, 536341037, 536341061, 536341073, 536341081, 536341087,
+    536341123, 536341133, 536341181, 536341217, 536341243, 536341259,
+    536341297, 536341321, 536341331, 536341343, 536341361, 536341363,
+    536341373, 536341391, 536341469, 536341489, 536341543, 536341567,
+    536341583, 536341621, 536341639, 536341643, 536341651, 536341661,
+    536341697, 536341699, 536341723, 536341733, 536341763, 536341777,
+    536341811, 536341831, 536341837, 536341847, 536341859, 536341879,
+    536341907, 536341913, 536341931, 536341961, 536341997, 536342011,
+    536342029, 536342041, 536342057, 536342063, 536342087, 536342111,
+    536342113, 536342117, 536342119, 536342141, 536342159, 536342179,
+    536342189, 536342227, 536342237, 536342243, 536342249, 536342281,
+    536342291, 536342329, 536342341, 536342347, 536342369, 536342371,
+    536342381, 536342383, 536342399, 536342423, 536342459, 536342473,
+    536342489, 536342519, 536342539, 536342549, 536342567, 536342593,
+    536342603, 536342629, 536342657, 536342663, 536342693, 536342701,
+    536342767, 536342797, 536342857, 536342869, 536342903, 536342909,
+    536342959, 536342977, 536342993, 536343011, 536343019, 536343029,
+    536343053, 536343079, 536343097, 536343127, 536343131, 536343133,
+    536343151, 536343161, 536343163, 536343169, 536343193, 536343209,
+    536343253, 536343259, 536343277, 536343317, 536343397, 536343413,
+    536343433, 536343449, 536343491, 536343499, 536343503, 536343551,
+    536343553, 536343559, 536343589, 536343653, 536343697, 536343707,
+    536343721, 536343757, 536343791, 536343793, 536343809, 536343811,
+    536343833, 536343851, 536343887, 536343889, 536343901, 536343947,
+    536343953, 536343961, 536344007, 536344019, 536344021, 536344057,
+    536344097, 536344099, 536344111, 536344121, 536344129, 536344139,
+    536344157, 536344181, 536344219, 536344243, 536344273, 536344283,
+    536344309, 536344327, 536344343, 536344399, 536344409, 536344421,
+    536344439, 536344453, 536344463, 536344481, 536344507, 536344511,
+    536344537, 536344541, 536344553, 536344591, 536344603, 536344607,
+    536344619, 536344621, 536344639, 536344649, 536344687, 536344693,
+    536344703, 536344709, 536344717, 536344727, 536344759, 536344771,
+    536344799, 536344829, 536344847, 536344867, 536344957, 536344961,
+    536344967, 536344979, 536344993, 536345041, 536345057, 536345071,
+    536345077, 536345101, 536345113, 536345137, 536345171, 536345197,
+    536345203, 536345207, 536345209, 536345221, 536345233, 536345237,
+    536345267, 536345339, 536345351, 536345363, 536345371, 536345387,
+    536345389, 536345399, 536345413, 536345429, 536345437, 536345473,
+    536345479, 536345497, 536345501, 536345503, 536345561, 536345567,
+    536345569, 536345587, 536345603, 536345609, 536345627, 536345647,
+    536345651, 536345681, 536345683, 536345687, 536345701, 536345707,
+    536345731, 536345779, 536345791, 536345867, 536345899, 536345933,
+    536345939, 536345941, 536345963, 536345983, 536345987, 536346007,
+    536346023, 536346037, 536346059, 536346091, 536346103, 536346119,
+    536346137, 536346149, 536346197, 536346199, 536346203, 536346263,
+    536346319, 536346331, 536346347, 536346367, 536346401, 536346409,
+    536346479, 536346491, 536346511, 536346523, 536346533, 536346571,
+    536346607, 536346641, 536346731, 536346737, 536346743, 536346761,
+    536346799, 536346827, 536346847, 536346887, 536346901, 536346907,
+    536346911, 536346919, 536346947, 536346949, 536346961, 536346973,
+    536347001, 536347013, 536347057, 536347061, 536347073, 536347087,
+    536347103, 536347129, 536347139, 536347159, 536347247, 536347271,
+    536347303, 536347307, 536347313, 536347321, 536347351, 536347393,
+    536347417, 536347423, 536347429, 536347453, 536347457, 536347463,
+    536347481, 536347531, 536347549, 536347573, 536347589, 536347613,
+    536347619, 536347633, 536347657, 536347687, 536347711, 536347733,
+    536347769, 536347783, 536347793, 536347813, 536347817, 536347831,
+    536347843, 536347853, 536347859, 536347871, 536347913, 536347919,
+    536347951, 536347963, 536347991, 536347993, 536348027, 536348039,
+    536348047, 536348053, 536348083, 536348123, 536348149, 536348167,
+    536348177, 536348179, 536348203, 536348209, 536348213, 536348231,
+    536348233, 536348237, 536348251, 536348257, 536348273, 536348299,
+    536348311, 536348363, 536348377, 536348381, 536348383, 536348399,
+    536348401, 536348441, 536348471, 536348479, 536348497, 536348509,
+    536348543, 536348551, 536348567, 536348629, 536348671, 536348699,
+    536348713, 536348717, 536348719, 536348741, 536348749, 536348789,
+    536348797, 536348801, 536348803, 536348807, 536348821, 536348831,
+    536348833, 536348849, 536348863, 536348867, 536348903, 536348947,
+    536348951, 536349001, 536349041, 536349059, 536349083, 536349089,
+    536349139, 536349179, 536349193, 536349199, 536349257, 536349301,
+    536349311, 536349343, 536349349, 536349389, 536349419, 536349427,
+    536349467, 536349479, 536349481, 536349487, 536349493, 536349497,
+    536349503, 536349533, 536349553, 536349557, 536349563, 536349599,
+    536349607, 536349623, 536349629, 536349647, 536349661, 536349679,
+    536349683, 536349721, 536349731, 536349733, 536349767, 536349769,
+    536349797, 536349851, 536349859, 536349871, 536349883, 536349887,
+    536349899, 536349911, 536349937, 536349953, 536349959, 536349971,
+    536350013, 536350021, 536350049, 536350057, 536350141, 536350147,
+    536350159, 536350163, 536350201, 536350207, 536350219, 536350231,
+    536350237, 536350253, 536350267, 536350279, 536350307, 536350327,
+    536350333, 536350351, 536350361, 536350387, 536350403, 536350429,
+    536350433, 536350453, 536350471, 536350489, 536350531, 536350609,
+    536350669, 536350687, 536350691, 536350693, 536350709, 536350721,
+    536350751, 536350781, 536350847, 536350861, 536350877, 536350883,
+    536350921, 536350931, 536350949, 536350951, 536350957, 536350963,
+    536350967, 536350993, 536350999, 536351009, 536351017, 536351029,
+    536351041, 536351047, 536351051, 536351059, 536351077, 536351087,
+    536351117, 536351129, 536351131, 536351141, 536351159, 536351183,
+    536351197, 536351261, 536351267, 536351273, 536351293, 536351311,
+    536351351, 536351363, 536351419, 536351423, 536351441, 536351447,
+    536351489, 536351503, 536351507, 536351531, 536351567, 536351579,
+    536351587, 536351623, 536351657, 536351681, 536351687, 536351693,
+    536351737, 536351747, 536351749, 536351773, 536351807, 536351813,
+    536351843, 536351903, 536351917, 536351923, 536351929, 536351957,
+    536351983, 536352017, 536352041, 536352043, 536352079, 536352101,
+    536352139, 536352143, 536352149, 536352169, 536352217, 536352239,
+    536352293, 536352367, 536352371, 536352403, 536352437, 536352473,
+    536352491, 536352503, 536352541, 536352559, 536352581, 536352667,
+    536352679, 536352683, 536352689, 536352697, 536352701, 536352721,
+    536352727, 536352763, 536352779, 536352787, 536352797, 536352863,
+    536352899, 536352911, 536352953, 536352997, 536353019, 536353039,
+    536353087, 536353093, 536353177, 536353183, 536353189, 536353211,
+    536353217, 536353243, 536353277, 536353283, 536353309, 536353313,
+    536353333, 536353343, 536353373, 536353379, 536353459, 536353469,
+    536353501, 536353507, 536353511, 536353529, 536353547, 536353711,
+    536353729, 536353747, 536353777, 536353817, 536353819, 536353877,
+    536353889, 536353891, 536353901, 536353903, 536353913, 536353931,
+    536353943, 536353967, 536353969, 536353981, 536353991, 536353999,
+    536354017, 536354057, 536354081, 536354107, 536354113, 536354129,
+    536354197, 536354213, 536354237, 536354261, 536354293, 536354303,
+    536354311, 536354321, 536354341, 536354359, 536354381, 536354407,
+    536354431, 536354443, 536354473, 536354491, 536354501, 536354521,
+    536354537, 536354557, 536354561, 536354563, 536354603, 536354669,
+    536354677, 536354711, 536354737, 536354747, 536354759, 536354773,
+    536354809, 536354831, 536354837, 536354873, 536354893, 536354911,
+    536354921, 536354969, 536354993, 536354999, 536355007, 536355011,
+    536355019, 536355041, 536355059, 536355067, 536355077, 536355089,
+    536355109, 536355121, 536355133, 536355173, 536355221, 536355223,
+    536355227, 536355233, 536355241, 536355257, 536355271, 536355277,
+    536355289, 536355343, 536355359, 536355361, 536355409, 536355451,
+    536355499, 536355509, 536355553, 536355557, 536355581, 536355619,
+    536355623, 536355629, 536355637, 536355643, 536355719, 536355733,
+    536355739, 536355751, 536355761, 536355773, 536355793, 536355817,
+    536355823, 536355889, 536355949, 536355979, 536355983, 536355991,
+    536356003, 536356019, 536356031, 536356049, 536356063, 536356087,
+    536356091, 536356129, 536356147, 536356193, 536356207, 536356217,
+    536356229, 536356231, 536356253, 536356267, 536356277, 536356291,
+    536356321, 536356333, 536356349, 536356351, 536356357, 536356361,
+    536356367, 536356369, 536356397, 536356399, 536356417, 536356423,
+    536356427, 536356441, 536356463, 536356519, 536356531, 536356543,
+    536356559, 536356577, 536356651, 536356663, 536356693, 536356721,
+    536356727, 536356729, 536356753, 536356771, 536356789, 536356813,
+    536356829, 536356861, 536356883, 536356901, 536356907, 536356927,
+    536356969, 536356973, 536356981, 536356999, 536357011, 536357047,
+    536357051, 536357093, 536357161, 536357183, 536357219, 536357231,
+    536357243, 536357267, 536357299, 536357317, 536357321, 536357351,
+    536357363, 536357383, 536357399, 536357411, 536357453, 536357473,
+    536357477, 536357527, 536357543, 536357557, 536357573, 536357597,
+    536357621, 536357641, 536357651, 536357659, 536357671, 536357761,
+    536357819, 536357831, 536357903, 536357917, 536357993, 536358013,
+    536358029, 536358037, 536358061, 536358073, 536358107, 536358113,
+    536358149, 536358157, 536358169, 536358181, 536358197, 536358209,
+    536358223, 536358227, 536358281, 536358323, 536358337, 536358341,
+    536358349, 536358397, 536358443, 536358481, 536358503, 536358523,
+    536358527, 536358539, 536358547, 536358553, 536358577, 536358607,
+    536358617, 536358659, 536358661, 536358677, 536358703, 536358709,
+    536358749, 536358763, 536358817, 536358821, 536358833, 536358839,
+    536358841, 536358859, 536358871, 536358899, 536358937, 536358947,
+    536358983, 536359013, 536359051, 536359073, 536359111, 536359127,
+    536359157, 536359183, 536359193, 536359199, 536359207, 536359211,
+    536359249, 536359261, 536359273, 536359277, 536359309, 536359331,
+    536359337, 536359349, 536359357, 536359381, 536359391, 536359409,
+    536359423, 536359451, 536359477, 536359507, 536359513, 536359541,
+    536359547, 536359559, 536359561, 536359567, 536359583, 536359627,
+    536359643, 536359651, 536359661, 536359667, 536359687, 536359729,
+    536359739, 536359751, 536359753, 536359757, 536359777, 536359781,
+    536359783, 536359801, 536359819, 536359867, 536359871, 536359933,
+    536359937, 536359939, 536359961, 536359963, 536359969, 536359997,
+    536360039, 536360059, 536360089, 536360093, 536360107, 536360117,
+    536360119, 536360147, 536360173, 536360179, 536360189, 536360203,
+    536360257, 536360261, 536360267, 536360347, 536360411, 536360417,
+    536360471, 536360479, 536360491, 536360509, 536360533, 536360537,
+    536360567, 536360581, 536360599, 536360623, 536360653, 536360677,
+    536360707, 536360743, 536360749, 536360753, 536360777, 536360779,
+    536360807, 536360809, 536360831, 536360833, 536360849, 536360873,
+    536360879, 536360911, 536360939, 536360947, 536360953, 536360969,
+    536361011, 536361017, 536361019, 536361041, 536361047, 536361071,
+    536361073, 536361103, 536361109, 536361131, 536361143, 536361187,
+    536361191, 536361233, 536361239, 536361251, 536361263, 536361269,
+    536361283, 536361289, 536361299, 536361307, 536361323, 536361341,
+    536361347, 536361379, 536361383, 536361401, 536361421, 536361451,
+    536361461, 536361487, 536361493, 536361499, 536361517, 536361547,
+    536361559, 536361563, 536361613, 536361629, 536361653, 536361677,
+    536361703, 536361719, 536361737, 536361751, 536361797, 536361803,
+    536361823, 536361851, 536361857, 536361871, 536361901, 536361911,
+    536361913, 536361929, 536361983, 536361997, 536362033, 536362037,
+    536362049, 536362061, 536362111, 536362157, 536362159, 536362201,
+    536362213, 536362241, 536362243, 536362331, 536362357, 536362391,
+    536362399, 536362423, 536362441, 536362469, 536362487, 536362493,
+    536362531, 536362559, 536362639, 536362643, 536362681, 536362709,
+    536362741, 536362753, 536362759, 536362789, 536362817, 536362843,
+    536362847, 536362891, 536362907, 536362927, 536362933, 536362963,
+    536362969, 536362973, 536362979, 536362987, 536362993, 536363017,
+    536363071, 536363081, 536363101, 536363111, 536363117, 536363161,
+    536363213, 536363231, 536363237, 536363263, 536363279, 536363309,
+    536363363, 536363393, 536363411, 536363417, 536363431, 536363441,
+    536363459, 536363461, 536363489, 536363533, 536363563, 536363593,
+    536363677, 536363689, 536363713, 536363741, 536363747, 536363761,
+    536363783, 536363797, 536363809, 536363813, 536363851, 536363857,
+    536363909, 536363959, 536363987, 536364007, 536364043, 536364067,
+    536364079, 536364083, 536364097, 536364109, 536364113, 536364131,
+    536364137, 536364149, 536364151, 536364181, 536364223, 536364233,
+    536364239, 536364271, 536364299, 536364379, 536364383, 536364391,
+    536364401, 536364473, 536364497, 536364527, 536364559, 536364581,
+    536364589, 536364593, 536364607, 536364613, 536364649, 536364659,
+    536364667, 536364677, 536364683, 536364707, 536364709, 536364767,
+    536364781, 536364797, 536364809, 536364827, 536364859, 536364869,
+    536364877, 536364953, 536364967, 536364971, 536364989, 536365019,
+    536365031, 536365043, 536365051, 536365099, 536365127, 536365153,
+    536365171, 536365177, 536365199, 536365201, 536365241, 536365289,
+    536365303, 536365331, 536365369, 536365381, 536365387, 536365397,
+    536365409, 536365429, 536365433, 536365447, 536365471, 536365481,
+    536365513, 536365517, 536365597, 536365601, 536365631, 536365633,
+    536365667, 536365673, 536365693, 536365717, 536365723, 536365733,
+    536365747, 536365771, 536365787, 536365799, 536365811, 536365829,
+    536365859, 536365871, 536365891, 536365897, 536365901, 536365909,
+    536365919, 536365931, 536365943, 536365979, 536365981, 536365987,
+    536365993, 536366041, 536366053, 536366063, 536366081, 536366101,
+    536366119, 536366179, 536366183, 536366189, 536366231, 536366267,
+    536366297, 536366321, 536366323, 536366329, 536366353, 536366357,
+    536366359, 536366377, 536366399, 536366401, 536366407, 536366419,
+    536366443, 536366483, 536366521, 536366539, 536366543, 536366549,
+    536366573, 536366587, 536366639, 536366651, 536366653, 536366707,
+    536366729, 536366771, 536366819, 536366849, 536366851, 536366891,
+    536366917, 536366933, 536366947, 536367019, 536367047, 536367067,
+    536367077, 536367089, 536367109, 536367113, 536367179, 536367191,
+    536367211, 536367217, 536367229, 536367233, 536367257, 536367263,
+    536367277, 536367313, 536367319, 536367341, 536367343, 536367373,
+    536367379, 536367401, 536367437, 536367463, 536367479, 536367523,
+    536367539, 536367547, 536367551, 536367569, 536367589, 536367599,
+    536367649, 536367653, 536367679, 536367691, 536367737, 536367743,
+    536367749, 536367757, 536367773, 536367787, 536367817, 536367857,
+    536367869, 536367877, 536367959, 536367991, 536368033, 536368039,
+    536368061, 536368067, 536368069, 536368093, 536368099, 536368127,
+    536368141, 536368153, 536368159, 536368171, 536368219, 536368229,
+    536368247, 536368267, 536368307, 536368319, 536368333, 536368337,
+    536368361, 536368373, 536368397, 536368409, 536368457, 536368463,
+    536368477, 536368523, 536368531, 536368571, 536368597, 536368607,
+    536368631, 536368633, 536368643, 536368661, 536368663, 536368691,
+    536368697, 536368709, 536368733, 536368769, 536368771, 536368787,
+    536368801, 536368813, 536368829, 536368831, 536368843, 536368849,
+    536368867, 536368927, 536368933, 536368939, 536368951, 536368961,
+    536368981, 536369017, 536369047, 536369081, 536369083, 536369087,
+    536369089, 536369129, 536369153, 536369167, 536369173, 536369191,
+    536369201, 536369233, 536369291, 536369293, 536369299, 536369369,
+    536369377, 536369423, 536369443, 536369459, 536369467, 536369507,
+    536369569, 536369579, 536369599, 536369651, 536369689, 536369693,
+    536369711, 536369731, 536369747, 536369759, 536369777, 536369783,
+    536369809, 536369849, 536369851, 536369857, 536369863, 536369879,
+    536369881, 536369903, 536369929, 536369963, 536369971, 536369989,
+    536370007, 536370047, 536370049, 536370061, 536370067, 536370071,
+    536370083, 536370101, 536370103, 536370137, 536370169, 536370181,
+    536370187, 536370217, 536370223, 536370257, 536370269, 536370293,
+    536370299, 536370311, 536370313, 536370343, 536370379, 536370397,
+    536370409, 536370469, 536370473, 536370503, 536370509, 536370539,
+    536370607, 536370613, 536370619, 536370661, 536370673, 536370697,
+    536370713, 536370727, 536370761, 536370763, 536370811, 536370839,
+    536370841, 536370853, 536370881, 536370883, 536370917, 536370929,
+    536370937, 536370943, 536370953, 536370977, 536370997, 536371027,
+    536371039, 536371067, 536371081, 536371093, 536371117, 536371127,
+    536371139, 536371141, 536371151, 536371163, 536371229, 536371249,
+    536371259, 536371271, 536371279, 536371313, 536371333, 536371343,
+    536371361, 536371391, 536371397, 536371399, 536371427, 536371441,
+    536371453, 536371487, 536371519, 536371609, 536371621, 536371631,
+    536371639, 536371643, 536371657, 536371679, 536371727, 536371747,
+    536371757, 536371763, 536371793, 536371831, 536371853, 536371867,
+    536371873, 536371883, 536371903, 536371921, 536371933, 536371973,
+    536371991, 536372003, 536372021, 536372027, 536372069, 536372077,
+    536372087, 536372093, 536372101, 536372129, 536372149, 536372183,
+    536372231, 536372279, 536372293, 536372327, 536372341, 536372359,
+    536372393, 536372401, 536372407, 536372471, 536372479, 536372483,
+    536372533, 536372563, 536372579, 536372597, 536372611, 536372647,
+    536372653, 536372657, 536372671, 536372677, 536372723, 536372741,
+    536372743, 536372779, 536372801, 536372803, 536372807, 536372839,
+    536372867, 536372873, 536372887, 536372891, 536372909, 536372911,
+    536372929, 536372957, 536372981, 536372987, 536373017, 536373023,
+    536373049, 536373083, 536373113, 536373119, 536373139, 536373151,
+    536373169, 536373199, 536373209, 536373217, 536373247, 536373283,
+    536373293, 536373337, 536373361, 536373367, 536373373, 536373379,
+    536373403, 536373407, 536373419, 536373437, 536373449, 536373463,
+    536373479, 536373517, 536373527, 536373557, 536373569, 536373577,
+    536373583, 536373623, 536373653, 536373707, 536373713, 536373737,
+    536373791, 536373797, 536373829, 536373847, 536373853, 536373863,
+    536373883, 536373889, 536373911, 536373923, 536373947, 536373967,
+    536374001, 536374019, 536374073, 536374117, 536374147, 536374187,
+    536374193, 536374229, 536374249, 536374271, 536374273, 536374277,
+    536374291, 536374309, 536374357, 536374367, 536374381, 536374409,
+    536374417, 536374439, 536374477, 536374507, 536374511, 536374519,
+    536374543, 536374549, 536374571, 536374589, 536374603, 536374627,
+    536374637, 536374739, 536374771, 536374781, 536374799, 536374879,
+    536374901, 536374907, 536374919, 536374931, 536374961, 536374963,
+    536375009, 536375017, 536375027, 536375093, 536375129, 536375153,
+    536375171, 536375173, 536375207, 536375221, 536375297, 536375303,
+    536375351, 536375383, 536375429, 536375447, 536375459, 536375467,
+    536375473, 536375513, 536375519, 536375527, 536375537, 536375557,
+    536375629, 536375633, 536375639, 536375641, 536375683, 536375711,
+    536375731, 536375747, 536375767, 536375771, 536375773, 536375779,
+    536375837, 536375839, 536375869, 536375887, 536375911, 536375923,
+    536375929, 536375933, 536375977, 536376007, 536376017, 536376067,
+    536376089, 536376091, 536376121, 536376131, 536376149, 536376179,
+    536376193, 536376221, 536376223, 536376241, 536376283, 536376287,
+    536376301, 536376331, 536376343, 536376371, 536376433, 536376437,
+    536376481, 536376521, 536376523, 536376557, 536376569, 536376619,
+    536376623, 536376647, 536376649, 536376661, 536376689, 536376697,
+    536376751, 536376773, 536376781, 536376791, 536376811, 536376817,
+    536376823, 536376829, 536376851, 536376881, 536376887, 536376913,
+    536376949, 536376961, 536376977, 536376991, 536377001, 536377067,
+    536377073, 536377111, 536377157, 536377169, 536377187, 536377223,
+    536377229, 536377241, 536377249, 536377253, 536377297, 536377307,
+    536377327, 536377333, 536377339, 536377343, 536377349, 536377351,
+    536377363, 536377379, 536377393, 536377397, 536377427, 536377433,
+    536377441, 536377459, 536377477, 536377481, 536377483, 536377507,
+    536377511, 536377559, 536377561, 536377601, 536377603, 536377651,
+    536377711, 536377741, 536377747, 536377763, 536377811, 536377837,
+    536377843, 536377873, 536377889, 536377921, 536377927, 536377957,
+    536377969, 536377979, 536377993, 536378041, 536378071, 536378077,
+    536378093, 536378099, 536378137, 536378177, 536378191, 536378197,
+    536378221, 536378251, 536378257, 536378273, 536378291, 536378309,
+    536378327, 536378329, 536378389, 536378393, 536378413, 536378471,
+    536378473, 536378489, 536378501, 536378503, 536378533, 536378537,
+    536378539, 536378567, 536378597, 536378599, 536378651, 536378671,
+    536378681, 536378707, 536378719, 536378761, 536378767, 536378807,
+    536378813, 536378827, 536378891, 536378893, 536378903, 536378959,
+    536378963, 536378977, 536379007, 536379013, 536379017, 536379071,
+    536379131, 536379149, 536379167, 536379169, 536379187, 536379191,
+    536379197, 536379241, 536379301, 536379307, 536379317, 536379341,
+    536379409, 536379433, 536379439, 536379457, 536379497, 536379499,
+    536379521, 536379541, 536379553, 536379559, 536379581, 536379611,
+    536379629, 536379643, 536379673, 536379677, 536379719, 536379773,
+    536379841, 536379847, 536379859, 536379863, 536379871, 536379881,
+    536379919, 536379929, 536379989, 536380007, 536380037, 536380043,
+    536380067, 536380069, 536380153, 536380189, 536380211, 536380261,
+    536380283, 536380333, 536380337, 536380349, 536380391, 536380423,
+    536380451, 536380459, 536380463, 536380477, 536380487, 536380489,
+    536380499, 536380501, 536380513, 536380519, 536380531, 536380541,
+    536380547, 536380553, 536380577, 536380597, 536380639, 536380657,
+    536380673, 536380681, 536380687, 536380699, 536380709, 536380711,
+    536380721, 536380727, 536380729, 536380739, 536380751, 536380759,
+    536380771, 536380799, 536380837, 536380891, 536380903, 536380921,
+    536380939, 536380951, 536380961, 536380969, 536380987, 536381051,
+    536381107, 536381117, 536381171, 536381173, 536381207, 536381221,
+    536381233, 536381239, 536381243, 536381273, 536381309, 536381347,
+    536381353, 536381387, 536381423, 536381471, 536381513, 536381519,
+    536381537, 536381543, 536381581, 536381591, 536381653, 536381663,
+    536381687, 536381693, 536381707, 536381717, 536381737, 536381759,
+    536381777, 536381831, 536381849, 536381861, 536381863, 536381869,
+    536381887, 536381903, 536381953, 536381987, 536382017, 536382019,
+    536382029, 536382031, 536382059, 536382083, 536382107, 536382127,
+    536382167, 536382169, 536382193, 536382199, 536382247, 536382277,
+    536382281, 536382299, 536382391, 536382401, 536382421, 536382449,
+    536382461, 536382529, 536382571, 536382593, 536382661, 536382683,
+    536382751, 536382767, 536382799, 536382823, 536382829, 536382851,
+    536382859, 536382871, 536382877, 536382881, 536382887, 536382893,
+    536382907, 536382923, 536382953, 536382961, 536382967, 536382971,
+    536382991, 536383007, 536383021, 536383093, 536383123, 536383139,
+    536383171, 536383229, 536383249, 536383259, 536383271, 536383273,
+    536383301, 536383321, 536383327, 536383343, 536383369, 536383381,
+    536383387, 536383399, 536383409, 536383417, 536383447, 536383451,
+    536383481, 536383489, 536383493, 536383501, 536383511, 536383543,
+    536383597, 536383619, 536383649, 536383657, 536383697, 536383717,
+    536383753, 536383769, 536383777, 536383781, 536383801, 536383807,
+    536383817, 536383829, 536383867, 536383871, 536383873, 536383879,
+    536383901, 536383909, 536383973, 536383997, 536383999, 536384011,
+    536384027, 536384039, 536384053, 536384077, 536384083, 536384113,
+    536384131, 536384141, 536384143, 536384171, 536384201, 536384207,
+    536384209, 536384213, 536384273, 536384287, 536384293, 536384309,
+    536384341, 536384369, 536384389, 536384441, 536384467, 536384501,
+    536384521, 536384533, 536384549, 536384557, 536384669, 536384699,
+    536384707, 536384743, 536384791, 536384803, 536384809, 536384851,
+    536384869, 536384879, 536384903, 536384911, 536384917, 536384921,
+    536384923, 536384941, 536384983, 536384987, 536385007, 536385019,
+    536385023, 536385079, 536385089, 536385119, 536385127, 536385137,
+    536385149, 536385163, 536385167, 536385217, 536385221, 536385233,
+    536385253, 536385299, 536385331, 536385341, 536385347, 536385361,
+    536385401, 536385449, 536385469, 536385481, 536385497, 536385503,
+    536385539, 536385557, 536385587, 536385593, 536385601, 536385611,
+    536385613, 536385659, 536385709, 536385721, 536385763, 536385779,
+    536385799, 536385809, 536385833, 536385841, 536385907, 536385911,
+    536385937, 536385953, 536385961, 536385973, 536386009, 536386049,
+    536386061, 536386073, 536386139, 536386141, 536386163, 536386177,
+    536386217, 536386241, 536386259, 536386267, 536386339, 536386369,
+    536386439, 536386451, 536386453, 536386489, 536386531, 536386547,
+    536386561, 536386573, 536386589, 536386619, 536386633, 536386649,
+    536386661, 536386679, 536386691, 536386709, 536386727, 536386787,
+    536386793, 536386801, 536386819, 536386843, 536386849, 536386901,
+    536386927, 536386957, 536386973, 536386993, 536387021, 536387053,
+    536387107, 536387123, 536387177, 536387191, 536387207, 536387221,
+    536387227, 536387263, 536387329, 536387333, 536387339, 536387351,
+    536387353, 536387377, 536387407, 536387419, 536387431, 536387437,
+    536387441, 536387443, 536387447, 536387471, 536387477, 536387521,
+    536387539, 536387563, 536387581, 536387591, 536387639, 536387647,
+    536387671, 536387713, 536387717, 536387737, 536387767, 536387771,
+    536387773, 536387809, 536387827, 536387851, 536387911, 536387933,
+    536387941, 536387963, 536387987, 536388007, 536388049, 536388077,
+    536388079, 536388091, 536388103, 536388113, 536388119, 536388161,
+    536388163, 536388169, 536388179, 536388197, 536388211, 536388239,
+    536388253, 536388269, 536388271, 536388289, 536388323, 536388329,
+    536388337, 536388341, 536388343, 536388383, 536388431, 536388439,
+    536388499, 536388509, 536388521, 536388569, 536388571, 536388583,
+    536388631, 536388649, 536388653, 536388661, 536388683, 536388701,
+    536388703, 536388707, 536388719, 536388731, 536388733, 536388821,
+    536388823, 536388833, 536388851, 536388857, 536388869, 536388871,
+    536388893, 536388899, 536388917, 536388949, 536388953, 536388961,
+    536388971, 536388973, 536388989, 536388997, 536389013, 536389093,
+    536389157, 536389159, 536389169, 536389193, 536389201, 536389207,
+    536389213, 536389261, 536389277, 536389283, 536389291, 536389303,
+    536389349, 536389367, 536389391, 536389397, 536389459, 536389489,
+    536389499, 536389507, 536389517, 536389519, 536389523, 536389541,
+    536389543, 536389547, 536389549, 536389613, 536389639, 536389657,
+    536389669, 536389673, 536389681, 536389691, 536389717, 536389747,
+    536389769, 536389781, 536389801, 536389859, 536389871, 536389879,
+    536389927, 536389937, 536389949, 536389963, 536390009, 536390021,
+    536390047, 536390077, 536390087, 536390189, 536390191, 536390201,
+    536390219, 536390233, 536390237, 536390243, 536390269, 536390287,
+    536390339, 536390353, 536390359, 536390363, 536390377, 536390399,
+    536390401, 536390411, 536390453, 536390509, 536390527, 536390531,
+    536390549, 536390609, 536390623, 536390633, 536390639, 536390663,
+    536390671, 536390689, 536390711, 536390779, 536390791, 536390809,
+    536390909, 536390927, 536390941, 536390963, 536390983, 536391017,
+    536391019, 536391059, 536391091, 536391133, 536391161, 536391169,
+    536391181, 536391187, 536391199, 536391253, 536391263, 536391269,
+    536391301, 536391311, 536391313, 536391353, 536391367, 536391379,
+    536391391, 536391407, 536391433, 536391461, 536391467, 536391521,
+    536391523, 536391529, 536391587, 536391601, 536391607, 536391629,
+    536391631, 536391659, 536391673, 536391689, 536391707, 536391719,
+    536391731, 536391781, 536391787, 536391799, 536391827, 536391851,
+    536391857, 536391887, 536391893, 536391949, 536391953, 536391979,
+    536392009, 536392037, 536392049, 536392061, 536392063, 536392081,
+    536392099, 536392117, 536392121, 536392123, 536392133, 536392139,
+    536392141, 536392159, 536392183, 536392201, 536392229, 536392237,
+    536392267, 536392301, 536392309, 536392327, 536392331, 536392333,
+    536392369, 536392387, 536392399, 536392403, 536392421, 536392427,
+    536392511, 536392547, 536392559, 536392561, 536392567, 536392573,
+    536392583, 536392607, 536392609, 536392643, 536392657, 536392669,
+    536392673, 536392679, 536392697, 536392711, 536392733, 536392757,
+    536392837, 536392841, 536392877, 536392889, 536392897, 536392919,
+    536392937, 536392939, 536392951, 536392963, 536392973, 536392981,
+    536392991, 536393003, 536393021, 536393057, 536393059, 536393063,
+    536393071, 536393083, 536393087, 536393141, 536393149, 536393171,
+    536393177, 536393213, 536393233, 536393257, 536393293, 536393303,
+    536393321, 536393339, 536393359, 536393381, 536393399, 536393437,
+    536393471, 536393521, 536393531, 536393573, 536393609, 536393623,
+    536393629, 536393659, 536393677, 536393743, 536393749, 536393783,
+    536393791, 536393849, 536393863, 536393881, 536393887, 536393903,
+    536393909, 536393927, 536393981, 536393983, 536393989, 536393993,
+    536394031, 536394037, 536394049, 536394059, 536394071, 536394077,
+    536394119, 536394139, 536394151, 536394197, 536394203, 536394211,
+    536394227, 536394239, 536394323, 536394329, 536394337, 536394343,
+    536394359, 536394361, 536394371, 536394373, 536394401, 536394403,
+    536394473, 536394493, 536394497, 536394499, 536394511, 536394517,
+    536394539, 536394541, 536394601, 536394613, 536394629, 536394637,
+    536394641, 536394647, 536394667, 536394679, 536394689, 536394713,
+    536394731, 536394743, 536394751, 536394763, 536394769, 536394797,
+    536394811, 536394869, 536394893, 536394913, 536394917, 536394919,
+    536394967, 536394979, 536395007, 536395009, 536395051, 536395063,
+    536395081, 536395091, 536395103, 536395117, 536395151, 536395157,
+    536395177, 536395193, 536395231, 536395241, 536395243, 536395247,
+    536395291, 536395297, 536395303, 536395309, 536395319, 536395361,
+    536395399, 536395411, 536395417, 536395427, 536395439, 536395451,
+    536395477, 536395481, 536395529, 536395567, 536395589, 536395603,
+    536395621, 536395633, 536395663, 536395667, 536395721, 536395757,
+    536395789, 536395793, 536395799, 536395807, 536395813, 536395837,
+    536395843, 536395877, 536395879, 536395927, 536395961, 536395967,
+    536396009, 536396023, 536396027, 536396033, 536396039, 536396051,
+    536396059, 536396083, 536396111, 536396167, 536396183, 536396191,
+    536396207, 536396213, 536396221, 536396227, 536396249, 536396269,
+    536396321, 536396347, 536396369, 536396431, 536396449, 536396453,
+    536396459, 536396489, 536396507, 536396513, 536396519, 536396527,
+    536396579, 536396587, 536396617, 536396633, 536396647, 536396701,
+    536396717, 536396719, 536396723, 536396747, 536396761, 536396821,
+    536396837, 536396849, 536396867, 536396909, 536396953, 536396981,
+    536397013, 536397023, 536397089, 536397097, 536397131, 536397139,
+    536397161, 536397167, 536397181, 536397187, 536397193, 536397203,
+    536397221, 536397223, 536397263, 536397271, 536397299, 536397317,
+    536397347, 536397359, 536397409, 536397431, 536397469, 536397479,
+    536397539, 536397541, 536397551, 536397593, 536397613, 536397637,
+    536397643, 536397647, 536397677, 536397689, 536397703, 536397739,
+    536397751, 536397761, 536397767, 536397773, 536397791, 536397811,
+    536397839, 536397847, 536397859, 536397899, 536397931, 536397937,
+    536397947, 536397959, 536398003, 536398021, 536398043, 536398067,
+    536398073, 536398117, 536398153, 536398189, 536398217, 536398223,
+    536398237, 536398259, 536398271, 536398307, 536398309, 536398327,
+    536398333, 536398337, 536398339, 536398391, 536398403, 536398411,
+    536398417, 536398439, 536398453, 536398459, 536398463, 536398477,
+    536398493, 536398517, 536398523, 536398537, 536398547, 536398591,
+    536398601, 536398619, 536398631, 536398649, 536398669, 536398693,
+    536398699, 536398721, 536398741, 536398769, 536398771, 536398787,
+    536398789, 536398829, 536398843, 536398873, 536398901, 536398931,
+    536398969, 536398997, 536399033, 536399041, 536399057, 536399063,
+    536399099, 536399117, 536399131, 536399141, 536399153, 536399179,
+    536399189, 536399207, 536399209, 536399219, 536399257, 536399309,
+    536399321, 536399327, 536399371, 536399377, 536399407, 536399429,
+    536399459, 536399483, 536399489, 536399509, 536399519, 536399527,
+    536399569, 536399593, 536399599, 536399653, 536399663, 536399711,
+    536399713, 536399723, 536399741, 536399771, 536399797, 536399869,
+    536399873, 536399933, 536399953, 536399957, 536399971, 536399977,
+    536399987, 536399993, 536400041, 536400061, 536400079, 536400083,
+    536400107, 536400119, 536400127, 536400157, 536400173, 536400187,
+    536400217, 536400287, 536400289, 536400341, 536400349, 536400379,
+    536400401, 536400407, 536400421, 536400451, 536400479, 536400481,
+    536400509, 536400521, 536400547, 536400587, 536400589, 536400607,
+    536400611, 536400653, 536400691, 536400703, 536400713, 536400751,
+    536400817, 536400841, 536400857, 536400899, 536400901, 536400937,
+    536400941, 536400947, 536400971, 536401039, 536401069, 536401079,
+    536401087, 536401093, 536401097, 536401123, 536401157, 536401163,
+    536401189, 536401211, 536401213, 536401223, 536401241, 536401249,
+    536401279, 536401363, 536401381, 536401409, 536401433, 536401441,
+    536401447, 536401451, 536401471, 536401501, 536401507, 536401511,
+    536401577, 536401589, 536401633, 536401643, 536401667, 536401709,
+    536401721, 536401727, 536401757, 536401763, 536401783, 536401793,
+    536401819, 536401849, 536401903, 536401967, 536401979, 536402033,
+    536402039, 536402047, 536402059, 536402063, 536402077, 536402093,
+    536402107, 536402147, 536402149, 536402171, 536402177, 536402197,
+    536402203, 536402227, 536402239, 536402249, 536402263, 536402287,
+    536402291, 536402327, 536402333, 536402351, 536402353, 536402359,
+    536402387, 536402401, 536402413, 536402417, 536402441, 536402443,
+    536402507, 536402551, 536402567, 536402569, 536402591, 536402593,
+    536402599, 536402611, 536402627, 536402651, 536402701, 536402719,
+    536402749, 536402753, 536402761, 536402767, 536402773, 536402837,
+    536402861, 536402873, 536402897, 536402899, 536402939, 536402953,
+    536402981, 536403019, 536403031, 536403067, 536403071, 536403121,
+    536403143, 536403157, 536403173, 536403229, 536403233, 536403247,
+    536403251, 536403253, 536403271, 536403277, 536403289, 536403299,
+    536403313, 536403337, 536403347, 536403377, 536403379, 536403389,
+    536403391, 536403403, 536403419, 536403521, 536403529, 536403551,
+    536403563, 536403583, 536403587, 536403599, 536403613, 536403643,
+    536403653, 536403667, 536403701, 536403719, 536403739, 536403773,
+    536403821, 536403853, 536403859, 536403863, 536403871, 536403883,
+    536403929, 536403961, 536403971, 536404007, 536404019, 536404027,
+    536404061, 536404069, 536404081, 536404087, 536404093, 536404117,
+    536404153, 536404177, 536404199, 536404201, 536404237, 536404261,
+    536404273, 536404289, 536404313, 536404331, 536404339, 536404357,
+    536404487, 536404493, 536404571, 536404579, 536404633, 536404639,
+    536404667, 536404697, 536404703, 536404711, 536404721, 536404777,
+    536404807, 536404837, 536404849, 536404861, 536404867, 536404889,
+    536404907, 536404933, 536404951, 536404963, 536404969, 536404987,
+    536404993, 536405039, 536405087, 536405113, 536405117, 536405123,
+    536405153, 536405161, 536405171, 536405189, 536405197, 536405203,
+    536405227, 536405281, 536405297, 536405329, 536405341, 536405347,
+    536405381, 536405393, 536405399, 536405423, 536405447, 536405491,
+    536405557, 536405579, 536405591, 536405599, 536405629, 536405651,
+    536405657, 536405699, 536405711, 536405713, 536405717, 536405719,
+    536405773, 536405801, 536405809, 536405851, 536405861, 536405867,
+    536405869, 536405897, 536405939, 536405959, 536405999, 536406019,
+    536406041, 536406053, 536406061, 536406067, 536406077, 536406089,
+    536406139, 536406173, 536406179, 536406187, 536406191, 536406223,
+    536406281, 536406307, 536406313, 536406317, 536406329, 536406371,
+    536406373, 536406379, 536406397, 536406401, 536406463, 536406503,
+    536406509, 536406517, 536406523, 536406539, 536406551, 536406557,
+    536406569, 536406683, 536406691, 536406709, 536406719, 536406749,
+    536406751, 536406779, 536406853, 536406869, 536406877, 536406887,
+    536406901, 536406907, 536406929, 536406931, 536406961, 536406991,
+    536407009, 536407021, 536407049, 536407051, 536407063, 536407073,
+    536407121, 536407133, 536407147, 536407169, 536407243, 536407283,
+    536407349, 536407351, 536407367, 536407369, 536407379, 536407423,
+    536407439, 536407447, 536407481, 536407493, 536407523, 536407549,
+    536407559, 536407589, 536407603, 536407609, 536407621, 536407637,
+    536407657, 536407661, 536407687, 536407691, 536407727, 536407733,
+    536407813, 536407847, 536407877, 536407889, 536407891, 536407931,
+    536407933, 536407957, 536407967, 536407979, 536408003, 536408009,
+    536408023, 536408051, 536408113, 536408137, 536408141, 536408143,
+    536408149, 536408153, 536408219, 536408233, 536408237, 536408239,
+    536408261, 536408269, 536408287, 536408291, 536408297, 536408317,
+    536408357, 536408363, 536408381, 536408413, 536408419, 536408423,
+    536408443, 536408449, 536408459, 536408501, 536408557, 536408569,
+    536408591, 536408597, 536408611, 536408623, 536408651, 536408659,
+    536408681, 536408723, 536408749, 536408773, 536408797, 536408819,
+    536408833, 536408857, 536408867, 536408881, 536408897, 536408941,
+    536408981, 536408987, 536409043, 536409067, 536409101, 536409103,
+    536409193, 536409217, 536409227, 536409233, 536409241, 536409253,
+    536409281, 536409287, 536409299, 536409301, 536409353, 536409359,
+    536409361, 536409373, 536409397, 536409407, 536409413, 536409439,
+    536409451, 536409469, 536409547, 536409553, 536409583, 536409589,
+    536409623, 536409631, 536409667, 536409673, 536409677, 536409689,
+    536409719, 536409733, 536409737, 536409739, 536409751, 536409779,
+    536409793, 536409817, 536409883, 536409901, 536409911, 536409931,
+    536409947, 536409949, 536409961, 536409967, 536410003, 536410051,
+    536410057, 536410067, 536410103, 536410141, 536410151, 536410169,
+    536410177, 536410207, 536410213, 536410229, 536410279, 536410289,
+    536410309, 536410327, 536410331, 536410363, 536410373, 536410397,
+    536410409, 536410417, 536410429, 536410471, 536410487, 536410493,
+    536410499, 536410519, 536410541, 536410549, 536410561, 536410573,
+    536410583, 536410597, 536410601, 536410619, 536410649, 536410687,
+    536410723, 536410757, 536410781, 536410783, 536410813, 536410837,
+    536410891, 536410943, 536410993, 536410997, 536411053, 536411093,
+    536411119, 536411123, 536411153, 536411189, 536411191, 536411201,
+    536411209, 536411219, 536411243, 536411257, 536411263, 536411273,
+    536411327, 536411389, 536411399, 536411411, 536411471, 536411531,
+    536411549, 536411573, 536411587, 536411597, 536411639, 536411671,
+    536411683, 536411699, 536411717, 536411719, 536411723, 536411731,
+    536411737, 536411741, 536411747, 536411767, 536411783, 536411797,
+    536411807, 536411809, 536411831, 536411833, 536411851, 536411873,
+    536411881, 536411899, 536411917, 536411921, 536411929, 536412001,
+    536412013, 536412053, 536412073, 536412109, 536412131, 536412137,
+    536412179, 536412181, 536412193, 536412211, 536412241, 536412301,
+    536412329, 536412341, 536412353, 536412397, 536412413, 536412473,
+    536412479, 536412493, 536412497, 536412521, 536412529, 536412557,
+    536412581, 536412593, 536412641, 536412683, 536412689, 536412697,
+    536412707, 536412733, 536412749, 536412761, 536412763, 536412803,
+    536412829, 536412847, 536412857, 536412869, 536412887, 536412889,
+    536412893, 536412931, 536412937, 536412967, 536412977, 536412991,
+    536413001, 536413039, 536413043, 536413049, 536413051, 536413063,
+    536413067, 536413069, 536413079, 536413091, 536413099, 536413103,
+    536413117, 536413123, 536413139, 536413151, 536413183, 536413211,
+    536413217, 536413249, 536413253, 536413259, 536413279, 536413351,
+    536413357, 536413369, 536413379, 536413399, 536413403, 536413411,
+    536413421, 536413441, 536413447, 536413459, 536413469, 536413489,
+    536413513, 536413517, 536413541, 536413561, 536413571, 536413573,
+    536413601, 536413621, 536413627, 536413673, 536413721, 536413723,
+    536413729, 536413747, 536413763, 536413771, 536413807, 536413817,
+    536413819, 536413849, 536413883, 536413897, 536413907, 536413919,
+    536413921, 536413963, 536413967, 536414041, 536414057, 536414069,
+    536414071, 536414077, 536414083, 536414129, 536414167, 536414191,
+    536414233, 536414237, 536414267, 536414279, 536414323, 536414339,
+    536414383, 536414387, 536414401, 536414407, 536414449, 536414471,
+    536414519, 536414563, 536414573, 536414587, 536414609, 536414611,
+    536414621, 536414623, 536414629, 536414639, 536414687, 536414693,
+    536414741, 536414759, 536414771, 536414779, 536414803, 536414831,
+    536414881, 536414899, 536414909, 536414911, 536414927, 536414929,
+    536414933, 536414941, 536414953, 536414987, 536414999, 536415007,
+    536415017, 536415031, 536415053, 536415073, 536415083, 536415091,
+    536415097, 536415109, 536415133, 536415167, 536415203, 536415221,
+    536415241, 536415251, 536415281, 536415311, 536415329, 536415337,
+    536415359, 536415367, 536415377, 536415389, 536415409, 536415419,
+    536415421, 536415431, 536415449, 536415457, 536415469, 536415479,
+    536415511, 536415521, 536415527, 536415541, 536415547, 536415553,
+    536415557, 536415563, 536415643, 536415647, 536415673, 536415689,
+    536415701, 536415707, 536415731, 536415749, 536415779, 536415811,
+    536415851, 536415877, 536415889, 536415937, 536415941, 536415947,
+    536415953, 536415967, 536415989, 536415991, 536416007, 536416031,
+    536416073, 536416087, 536416093, 536416117, 536416129, 536416159,
+    536416169, 536416187, 536416201, 536416207, 536416213, 536416229,
+    536416273, 536416291, 536416297, 536416369, 536416409, 536416423,
+    536416427, 536416459, 536416469, 536416471, 536416523, 536416553,
+    536416579, 536416597, 536416637, 536416679, 536416733, 536416747,
+    536416753, 536416801, 536416813, 536416819, 536416823, 536416883,
+    536416897, 536416919, 536416931, 536416943, 536416957, 536416961,
+    536417041, 536417047, 536417093, 536417107, 536417111, 536417143,
+    536417183, 536417221, 536417243, 536417257, 536417261, 536417279,
+    536417281, 536417317, 536417327, 536417341, 536417369, 536417377,
+    536417417, 536417419, 536417461, 536417489, 536417491, 536417501,
+    536417503, 536417509, 536417551, 536417587, 536417593, 536417599,
+    536417603, 536417617, 536417653, 536417681, 536417683, 536417699,
+    536417701, 536417743, 536417759, 536417771, 536417773, 536417789,
+    536417839, 536417887, 536417933, 536417989, 536418007, 536418019,
+    536418023, 536418049, 536418059, 536418061, 536418083, 536418107,
+    536418109, 536418139, 536418143, 536418199, 536418229, 536418263,
+    536418313, 536418359, 536418361, 536418371, 536418401, 536418403,
+    536418427, 536418437, 536418521, 536418569, 536418601, 536418607,
+    536418613, 536418643, 536418677, 536418691, 536418763, 536418767,
+    536418803, 536418809, 536418821, 536418853, 536418907, 536418913,
+    536418959, 536418991, 536419033, 536419043, 536419049, 536419057,
+    536419067, 536419069, 536419097, 536419099, 536419151, 536419157,
+    536419187, 536419217, 536419223, 536419237, 536419259, 536419283,
+    536419291, 536419313, 536419337, 536419369, 536419391, 536419393,
+    536419417, 536419423, 536419427, 536419463, 536419469, 536419483,
+    536419529, 536419553, 536419561, 536419577, 536419579, 536419589,
+    536419619, 536419633, 536419661, 536419721, 536419729, 536419733,
+    536419739, 536419759, 536419781, 536419813, 536419831, 536419903,
+    536419907, 536419957, 536419963, 536420009, 536420029, 536420039,
+    536420077, 536420081, 536420111, 536420113, 536420149, 536420197,
+    536420231, 536420251, 536420263, 536420281, 536420299, 536420309,
+    536420327, 536420341, 536420359, 536420371, 536420387, 536420411,
+    536420459, 536420461, 536420471, 536420477, 536420491, 536420527,
+    536420539, 536420551, 536420587, 536420603, 536420609, 536420629,
+    536420681, 536420723, 536420777, 536420803, 536420813, 536420837,
+    536420879, 536420891, 536420959, 536420987, 536421023, 536421029,
+    536421037, 536421047, 536421049, 536421059, 536421107, 536421131,
+    536421133, 536421143, 536421161, 536421191, 536421209, 536421211,
+    536421257, 536421269, 536421311, 536421317, 536421329, 536421331,
+    536421337, 536421343, 536421419, 536421443, 536421461, 536421467,
+    536421493, 536421503, 536421511, 536421541, 536421559, 536421577,
+    536421583, 536421629, 536421637, 536421643, 536421649, 536421653,
+    536421659, 536421667, 536421673, 536421701, 536421703, 536421727,
+    536421731, 536421761, 536421773, 536421793, 536421797, 536421811,
+    536421839, 536421841, 536421881, 536421887, 536421911, 536421959,
+    536421973, 536421979, 536422001, 536422037, 536422049, 536422067,
+    536422069, 536422091, 536422093, 536422099, 536422129, 536422141,
+    536422151, 536422157, 536422181, 536422213, 536422259, 536422283,
+    536422297, 536422303, 536422333, 536422343, 536422361, 536422373,
+    536422409, 536422429, 536422457, 536422477, 536422489, 536422507,
+    536422511, 536422519, 536422531, 536422547, 536422553, 536422567,
+    536422571, 536422597, 536422603, 536422637, 536422651, 536422693,
+    536422697, 536422717, 536422739, 536422741, 536422759, 536422769,
+    536422771, 536422829, 536422883, 536422897, 536422919, 536422933,
+    536422937, 536422969, 536422973, 536422987, 536423011, 536423021,
+    536423023, 536423051, 536423059, 536423071, 536423087, 536423119,
+    536423137, 536423141, 536423149, 536423159, 536423161, 536423177,
+    536423183, 536423197, 536423201, 536423243, 536423263, 536423269,
+    536423281, 536423291, 536423359, 536423369, 536423413, 536423417,
+    536423429, 536423431, 536423449, 536423453, 536423467, 536423477,
+    536423497, 536423501, 536423533, 536423557, 536423567, 536423579,
+    536423603, 536423639, 536423651, 536423663, 536423683, 536423689,
+    536423707, 536423731, 536423747, 536423761, 536423773, 536423791,
+    536423801, 536423807, 536423809, 536423837, 536423843, 536423857,
+    536423861, 536423887, 536423939, 536423947, 536423977, 536424013,
+    536424037, 536424059, 536424061, 536424071, 536424079, 536424139,
+    536424143, 536424151, 536424167, 536424173, 536424191, 536424209,
+    536424233, 536424247, 536424257, 536424293, 536424313, 536424319,
+    536424323, 536424337, 536424347, 536424349, 536424373, 536424379,
+    536424389, 536424407, 536424419, 536424461, 536424463, 536424503,
+    536424509, 536424521, 536424529, 536424563, 536424593, 536424661,
+    536424683, 536424697, 536424703, 536424727, 536424731, 536424743,
+    536424751, 536424761, 536424797, 536424799, 536424827, 536424829,
+    536424839, 536424857, 536424859, 536424869, 536424881, 536424913,
+    536424923, 536424937, 536424971, 536424979, 536424989, 536425009,
+    536425061, 536425063, 536425069, 536425103, 536425111, 536425117,
+    536425121, 536425139, 536425171, 536425187, 536425193, 536425199,
+    536425207, 536425213, 536425217, 536425261, 536425273, 536425303,
+    536425363, 536425367, 536425391, 536425411, 536425447, 536425451,
+    536425453, 536425459, 536425469, 536425489, 536425501, 536425567,
+    536425649, 536425657, 536425679, 536425691, 536425693, 536425739,
+    536425783, 536425807, 536425823, 536425861, 536425867, 536425927,
+    536425949, 536425961, 536425979, 536425999, 536426017, 536426027,
+    536426039, 536426063, 536426071, 536426113, 536426123, 536426167,
+    536426227, 536426249, 536426269, 536426273, 536426281, 536426291,
+    536426299, 536426339, 536426383, 536426431, 536426441, 536426467,
+    536426477, 536426489, 536426503, 536426507, 536426519, 536426531,
+    536426549, 536426567, 536426581, 536426603, 536426609, 536426633,
+    536426647, 536426699, 536426719, 536426729, 536426743, 536426771,
+    536426773, 536426819, 536426881, 536426911, 536426951, 536426971,
+    536426977, 536426983, 536427013, 536427049, 536427079, 536427113,
+    536427127, 536427167, 536427179, 536427211, 536427217, 536427253,
+    536427263, 536427277, 536427289, 536427319, 536427329, 536427337,
+    536427373, 536427377, 536427383, 536427389, 536427467, 536427491,
+    536427523, 536427539, 536427569, 536427581, 536427583, 536427599,
+    536427601, 536427607, 536427629, 536427659, 536427677, 536427713,
+    536427719, 536427743, 536427757, 536427763, 536427803, 536427833,
+    536427841, 536427869, 536427889, 536427907, 536427923, 536427943,
+    536427949, 536427989, 536428001, 536428003, 536428019, 536428033,
+    536428037, 536428073, 536428093, 536428097, 536428153, 536428169,
+    536428171, 536428201, 536428219, 536428231, 536428259, 536428267,
+    536428303, 536428313, 536428339, 536428357, 536428369, 536428381,
+    536428441, 536428447, 536428513, 536428547, 536428589, 536428597,
+    536428603, 536428637, 536428667, 536428679, 536428699, 536428703,
+    536428759, 536428777, 536428787, 536428807, 536428817, 536428819,
+    536428873, 536428889, 536428901, 536428909, 536428943, 536428969,
+    536428973, 536428993, 536429009, 536429011, 536429027, 536429029,
+    536429041, 536429087, 536429093, 536429099, 536429107, 536429119,
+    536429123, 536429129, 536429137, 536429141, 536429167, 536429209,
+    536429273, 536429297, 536429317, 536429321, 536429323, 536429347,
+    536429351, 536429393, 536429449, 536429479, 536429507, 536429521,
+    536429533, 536429539, 536429561, 536429567, 536429591, 536429599,
+    536429633, 536429639, 536429681, 536429693, 536429741, 536429767,
+    536429771, 536429783, 536429807, 536429809, 536429813, 536429819,
+    536429827, 536429857, 536429893, 536429953, 536429977, 536430001,
+    536430007, 536430047, 536430049, 536430113, 536430143, 536430151,
+    536430161, 536430163, 536430199, 536430239, 536430241, 536430259,
+    536430263, 536430361, 536430373, 536430379, 536430407, 536430431,
+    536430443, 536430491, 536430497, 536430509, 536430533, 536430539,
+    536430581, 536430589, 536430637, 536430647, 536430677, 536430683,
+    536430689, 536430701, 536430707, 536430709, 536430749, 536430751,
+    536430779, 536430793, 536430821, 536430823, 536430827, 536430833,
+    536430841, 536430859, 536430899, 536430907, 536430919, 536430929,
+    536430931, 536430941, 536430953, 536431013, 536431019, 536431031,
+    536431061, 536431079, 536431081, 536431097, 536431121, 536431153,
+    536431169, 536431177, 536431187, 536431193, 536431201, 536431219,
+    536431253, 536431261, 536431267, 536431283, 536431289, 536431303,
+    536431319, 536431327, 536431333, 536431373, 536431387, 536431393,
+    536431403, 536431411, 536431421, 536431429, 536431433, 536431457,
+    536431459, 536431463, 536431501, 536431517, 536431559, 536431601,
+    536431663, 536431703, 536431729, 536431733, 536431757, 536431759,
+    536431793, 536431799, 536431817, 536431867, 536431897, 536431901,
+    536431927, 536431943, 536431963, 536431969, 536431993, 536432003,
+    536432021, 536432023, 536432063, 536432077, 536432087, 536432107,
+    536432173, 536432191, 536432203, 536432261, 536432287, 536432321,
+    536432341, 536432359, 536432363, 536432371, 536432389, 536432417,
+    536432437, 536432441, 536432461, 536432489, 536432497, 536432509,
+    536432527, 536432531, 536432551, 536432563, 536432581, 536432591,
+    536432599, 536432609, 536432621, 536432627, 536432683, 536432713,
+    536432717, 536432731, 536432737, 536432791, 536432797, 536432801,
+    536432803, 536432839, 536432843, 536432849, 536432863, 536432873,
+    536432879, 536432881, 536432921, 536432951, 536432987, 536432999,
+    536433013, 536433017, 536433019, 536433031, 536433049, 536433059,
+    536433077, 536433089, 536433091, 536433101, 536433103, 536433143,
+    536433169, 536433173, 536433179, 536433203, 536433211, 536433223,
+    536433259, 536433263, 536433353, 536433367, 536433371, 536433397,
+    536433421, 536433427, 536433431, 536433433, 536433509, 536433533,
+    536433539, 536433551, 536433647, 536433661, 536433673, 536433679,
+    536433697, 536433727, 536433743, 536433749, 536433757, 536433767,
+    536433773, 536433809, 536433839, 536433917, 536433949, 536433971,
+    536433977, 536434007, 536434009, 536434021, 536434033, 536434051,
+    536434079, 536434091, 536434117, 536434139, 536434193, 536434207,
+    536434211, 536434231, 536434243, 536434271, 536434273, 536434279,
+    536434291, 536434319, 536434351, 536434357, 536434471, 536434477,
+    536434487, 536434511, 536434513, 536434517, 536434519, 536434531,
+    536434559, 536434573, 536434583, 536434627, 536434631, 536434649,
+    536434669, 536434687, 536434697, 536434699, 536434729, 536434739,
+    536434753, 536434781, 536434807, 536434831, 536434841, 536434849,
+    536434859, 536434963, 536434973, 536434979, 536434981, 536435023,
+    536435063, 536435071, 536435077, 536435083, 536435087, 536435089,
+    536435093, 536435131, 536435147, 536435161, 536435177, 536435183,
+    536435203, 536435327, 536435351, 536435353, 536435369, 536435381,
+    536435401, 536435407, 536435411, 536435413, 536435423, 536435447,
+    536435489, 536435491, 536435507, 536435519, 536435539, 536435579,
+    536435597, 536435617, 536435633, 536435689, 536435717, 536435719,
+    536435777, 536435803, 536435813, 536435821, 536435849, 536435869,
+    536435903, 536435917, 536435927, 536435941, 536435983, 536436001,
+    536436023, 536436041, 536436049, 536436067, 536436091, 536436119,
+    536436127, 536436157, 536436191, 536436203, 536436209, 536436227,
+    536436259, 536436269, 536436289, 536436293, 536436347, 536436353,
+    536436361, 536436389, 536436419, 536436421, 536436449, 536436451,
+    536436457, 536436469, 536436487, 536436499, 536436503, 536436529,
+    536436541, 536436559, 536436583, 536436611, 536436643, 536436763,
+    536436779, 536436787, 536436793, 536436821, 536436833, 536436881,
+    536436917, 536436931, 536436941, 536436961, 536436977, 536437003,
+    536437007, 536437039, 536437043, 536437123, 536437133, 536437151,
+    536437177, 536437201, 536437267, 536437277, 536437289, 536437313,
+    536437339, 536437351, 536437357, 536437373, 536437387, 536437409,
+    536437463, 536437523, 536437553, 536437591, 536437597, 536437619,
+    536437633, 536437637, 536437663, 536437667, 536437687, 536437777,
+    536437787, 536437789, 536437793, 536437801, 536437807, 536437813,
+    536437817, 536437829, 536437831, 536437871, 536437879, 536437897,
+    536437921, 536437927, 536437939, 536437961, 536437999, 536438017,
+    536438041, 536438059, 536438083, 536438101, 536438107, 536438141,
+    536438239, 536438261, 536438303, 536438311, 536438323, 536438339,
+    536438341, 536438347, 536438351, 536438363, 536438393, 536438411,
+    536438429, 536438431, 536438449, 536438467, 536438479, 536438489,
+    536438527, 536438531, 536438537, 536438557, 536438563, 536438597,
+    536438627, 536438633, 536438641, 536438653, 536438659, 536438671,
+    536438701, 536438713, 536438719, 536438741, 536438743, 536438753,
+    536438759, 536438789, 536438827, 536438869, 536438873, 536438879,
+    536438923, 536439011, 536439019, 536439037, 536439041, 536439047,
+    536439073, 536439089, 536439091, 536439107, 536439109, 536439149,
+    536439161, 536439173, 536439227, 536439287, 536439289, 536439317,
+    536439329, 536439383, 536439413, 536439433, 536439443, 536439451,
+    536439457, 536439473, 536439481, 536439493, 536439499, 536439517,
+    536439523, 536439569, 536439581, 536439601, 536439619, 536439643,
+    536439647, 536439661, 536439679, 536439689, 536439691, 536439703,
+    536439713, 536439733, 536439773, 536439791, 536439793, 536439809,
+    536439821, 536439829, 536439877, 536439881, 536439887, 536439889,
+    536439907, 536439919, 536439923, 536439983, 536439997, 536440031,
+    536440061, 536440087, 536440147, 536440159, 536440169, 536440181,
+    536440183, 536440199, 536440207, 536440211, 536440217, 536440237,
+    536440241, 536440273, 536440277, 536440301, 536440343, 536440363,
+    536440369, 536440381, 536440409, 536440439, 536440447, 536440459,
+    536440481, 536440501, 536440517, 536440529, 536440589, 536440631,
+    536440633, 536440643, 536440651, 536440673, 536440691, 536440733,
+    536440757, 536440783, 536440787, 536440819, 536440823, 536440829,
+    536440901, 536440903, 536440909, 536440913, 536440999, 536441021,
+    536441027, 536441051, 536441053, 536441063, 536441071, 536441099,
+    536441119, 536441123, 536441153, 536441189, 536441197, 536441209,
+    536441261, 536441291, 536441299, 536441357, 536441387, 536441471,
+    536441491, 536441501, 536441509, 536441531, 536441551, 536441557,
+    536441561, 536441569, 536441599, 536441617, 536441657, 536441671,
+    536441677, 536441693, 536441729, 536441761, 536441767, 536441771,
+    536441791, 536441803, 536441809, 536441831, 536441833, 536441861,
+    536441863, 536441881, 536441923, 536441933, 536441951, 536441959,
+    536441963, 536441977, 536441981, 536441993, 536442013, 536442019,
+    536442037, 536442043, 536442047, 536442059, 536442091, 536442103,
+    536442119, 536442139, 536442173, 536442199, 536442211, 536442217,
+    536442239, 536442251, 536442289, 536442341, 536442343, 536442359,
+    536442397, 536442419, 536442421, 536442461, 536442481, 536442499,
+    536442503, 536442553, 536442619, 536442649, 536442653, 536442659,
+    536442707, 536442719, 536442721, 536442743, 536442749, 536442787,
+    536442833, 536442853, 536442877, 536442887, 536442901, 536442917,
+    536442971, 536442989, 536442997, 536443001, 536443009, 536443013,
+    536443031, 536443049, 536443069, 536443079, 536443087, 536443097,
+    536443129, 536443133, 536443147, 536443151, 536443181, 536443183,
+    536443213, 536443217, 536443253, 536443309, 536443343, 536443357,
+    536443393, 536443423, 536443429, 536443433, 536443441, 536443459,
+    536443469, 536443487, 536443507, 536443547, 536443591, 536443601,
+    536443603, 536443613, 536443669, 536443679, 536443717, 536443727,
+    536443729, 536443781, 536443783, 536443799, 536443807, 536443813,
+    536443819, 536443829, 536443841, 536443867, 536443889, 536443907,
+    536443961, 536443981, 536443987, 536443997, 536444011, 536444039,
+    536444089, 536444099, 536444137, 536444149, 536444159, 536444171,
+    536444177, 536444191, 536444213, 536444219, 536444257, 536444327,
+    536444383, 536444399, 536444437, 536444453, 536444473, 536444483,
+    536444509, 536444591, 536444609, 536444621, 536444647, 536444659,
+    536444669, 536444683, 536444717, 536444773, 536444789, 536444819,
+    536444827, 536444837, 536444873, 536444903, 536444927, 536444941,
+    536444971, 536444977, 536444989, 536445011, 536445023, 536445043,
+    536445053, 536445061, 536445073, 536445109, 536445127, 536445137,
+    536445187, 536445191, 536445193, 536445197, 536445199, 536445223,
+    536445229, 536445241, 536445289, 536445311, 536445331, 536445361,
+    536445397, 536445433, 536445439, 536445577, 536445589, 536445593,
+    536445649, 536445667, 536445671, 536445703, 536445737, 536445739,
+    536445757, 536445817, 536445821, 536445823, 536445851, 536445883,
+    536445887, 536445907, 536445929, 536445947, 536445953, 536445983,
+    536446003, 536446013, 536446021, 536446037, 536446039, 536446063,
+    536446093, 536446187, 536446193, 536446201, 536446217, 536446219,
+    536446223, 536446241, 536446243, 536446291, 536446303, 536446307,
+    536446357, 536446363, 536446409, 536446433, 536446439, 536446459,
+    536446481, 536446483, 536446499, 536446507, 536446511, 536446597,
+    536446601, 536446613, 536446621, 536446633, 536446639, 536446643,
+    536446657, 536446663, 536446667, 536446681, 536446693, 536446697,
+    536446717, 536446739, 536446759, 536446769, 536446777, 536446789,
+    536446837, 536446873, 536446891, 536446903, 536446907, 536446913,
+    536446921, 536446943, 536446987, 536446991, 536447003, 536447027,
+    536447039, 536447089, 536447123, 536447137, 536447141, 536447179,
+    536447207, 536447221, 536447251, 536447267, 536447279, 536447297,
+    536447299, 536447309, 536447323, 536447333, 536447339, 536447347,
+    536447363, 536447383, 536447413, 536447419, 536447437, 536447447,
+    536447449, 536447453, 536447459, 536447473, 536447477, 536447521,
+    536447543, 536447573, 536447579, 536447617, 536447621, 536447623,
+    536447629, 536447633, 536447657, 536447669, 536447693, 536447711,
+    536447741, 536447753, 536447789, 536447797, 536447819, 536447831,
+    536447851, 536447893, 536447897, 536447909, 536447911, 536447917,
+    536447953, 536447983, 536448041, 536448043, 536448047, 536448053,
+    536448169, 536448181, 536448191, 536448193, 536448197, 536448203,
+    536448217, 536448233, 536448247, 536448257, 536448281, 536448287,
+    536448317, 536448323, 536448329, 536448359, 536448361, 536448373,
+    536448377, 536448383, 536448391, 536448401, 536448439, 536448461,
+    536448499, 536448503, 536448511, 536448529, 536448541, 536448547,
+    536448557, 536448581, 536448613, 536448637, 536448659, 536448667,
+    536448697, 536448713, 536448743, 536448761, 536448763, 536448767,
+    536448817, 536448839, 536448851, 536448883, 536448901, 536448919,
+    536448937, 536448943, 536449007, 536449019, 536449031, 536449057,
+    536449073, 536449087, 536449099, 536449103, 536449139, 536449153,
+    536449157, 536449183, 536449223, 536449231, 536449237, 536449259,
+    536449267, 536449271, 536449313, 536449349, 536449357, 536449387,
+    536449391, 536449409, 536449457, 536449489, 536449519, 536449523,
+    536449531, 536449549, 536449561, 536449577, 536449583, 536449597,
+    536449607, 536449619, 536449621, 536449633, 536449657, 536449687,
+    536449703, 536449709, 536449747, 536449763, 536449783, 536449787,
+    536449813, 536449817, 536449829, 536449843, 536449871, 536449877,
+    536449883, 536449913, 536449951, 536449967, 536449981, 536449993,
+    536450017, 536450029, 536450041, 536450051, 536450107, 536450129,
+    536450141, 536450143, 536450177, 536450179, 536450197, 536450203,
+    536450219, 536450221, 536450231, 536450263, 536450269, 536450279,
+    536450311, 536450333, 536450353, 536450357, 536450359, 536450363,
+    536450377, 536450423, 536450429, 536450483, 536450507, 536450533,
+    536450539, 536450573, 536450581, 536450587, 536450639, 536450669,
+    536450687, 536450701, 536450737, 536450741, 536450743, 536450771,
+    536450773, 536450777, 536450851, 536450869, 536450911, 536450987,
+    536450989, 536451023, 536451067, 536451127, 536451131, 536451143,
+    536451151, 536451163, 536451169, 536451173, 536451191, 536451203,
+    536451217, 536451277, 536451343, 536451347, 536451361, 536451389,
+    536451397, 536451401, 536451403, 536451427, 536451431, 536451449,
+    536451451, 536451463, 536451479, 536451521, 536451533, 536451569,
+    536451589, 536451611, 536451623, 536451661, 536451689, 536451697,
+    536451733, 536451737, 536451763, 536451767, 536451787, 536451823,
+    536451829, 536451857, 536451899, 536451901, 536451917, 536451919,
+    536451941, 536451967, 536451973, 536452027, 536452057, 536452087,
+    536452109, 536452129, 536452141, 536452151, 536452181, 536452193,
+    536452211, 536452223, 536452229, 536452243, 536452261, 536452271,
+    536452283, 536452351, 536452363, 536452393, 536452417, 536452421,
+    536452463, 536452481, 536452513, 536452537, 536452541, 536452559,
+    536452577, 536452601, 536452607, 536452619, 536452627, 536452633,
+    536452661, 536452711, 536452753, 536452757, 536452789, 536452801,
+    536452831, 536452841, 536452883, 536452921, 536452949, 536452951,
+    536452967, 536452997, 536453017, 536453023, 536453059, 536453083,
+    536453089, 536453101, 536453119, 536453131, 536453147, 536453179,
+    536453191, 536453221, 536453237, 536453249, 536453257, 536453263,
+    536453279, 536453297, 536453317, 536453327, 536453387, 536453399,
+    536453413, 536453431, 536453453, 536453473, 536453507, 536453539,
+    536453551, 536453557, 536453579, 536453591, 536453597, 536453611,
+    536453627, 536453647, 536453663, 536453669, 536453693, 536453707,
+    536453741, 536453779, 536453821, 536453839, 536453849, 536453851,
+    536453867, 536453917, 536453971, 536454029, 536454041, 536454067,
+    536454071, 536454089, 536454103, 536454131, 536454133, 536454167,
+    536454187, 536454239, 536454241, 536454263, 536454271, 536454293,
+    536454299, 536454361, 536454367, 536454371, 536454377, 536454389,
+    536454407, 536454409, 536454419, 536454421, 536454433, 536454437,
+    536454439, 536454467, 536454469, 536454521, 536454539, 536454551,
+    536454559, 536454637, 536454649, 536454661, 536454697, 536454739,
+    536454781, 536454791, 536454803, 536454811, 536454827, 536454857,
+    536454869, 536454871, 536454899, 536454901, 536454917, 536454929,
+    536454937, 536454943, 536454973, 536455001, 536455061, 536455091,
+    536455103, 536455123, 536455141, 536455187, 536455189, 536455207,
+    536455223, 536455237, 536455259, 536455301, 536455313, 536455327,
+    536455343, 536455351, 536455363, 536455373, 536455379, 536455457,
+    536455459, 536455463, 536455499, 536455501, 536455511, 536455531,
+    536455537, 536455547, 536455597, 536455663, 536455681, 536455691,
+    536455693, 536455721, 536455729, 536455739, 536455753, 536455769,
+    536455781, 536455793, 536455807, 536455811, 536455883, 536455897,
+    536455901, 536455919, 536455943, 536455951, 536455957, 536455973,
+    536455991, 536455993, 536456009, 536456017, 536456047, 536456077,
+    536456093, 536456111, 536456113, 536456149, 536456197, 536456237,
+    536456251, 536456299, 536456351, 536456381, 536456383, 536456399,
+    536456411, 536456419, 536456429, 536456441, 536456521, 536456533,
+    536456549, 536456561, 536456563, 536456579, 536456593, 536456611,
+    536456653, 536456663, 536456671, 536456699, 536456717, 536456729,
+    536456737, 536456749, 536456797, 536456803, 536456839, 536456909,
+    536456927, 536456959, 536456983, 536456989, 536457041, 536457059,
+    536457073, 536457091, 536457113, 536457127, 536457169, 536457193,
+    536457199, 536457209, 536457211, 536457227, 536457281, 536457301,
+    536457319, 536457329, 536457353, 536457371, 536457391, 536457421,
+    536457499, 536457517, 536457529, 536457541, 536457547, 536457563,
+    536457587, 536457599, 536457601, 536457617, 536457619, 536457629,
+    536457641, 536457667, 536457673, 536457703, 536457721, 536457731,
+    536457737, 536457739, 536457751, 536457781, 536457787, 536457791,
+    536457793, 536457829, 536457833, 536457869, 536457871, 536457877,
+    536457881, 536457893, 536457907, 536457917, 536457923, 536457937,
+    536458099, 536458127, 536458147, 536458159, 536458163, 536458177,
+    536458229, 536458261, 536458271, 536458297, 536458313, 536458333,
+    536458337, 536458357, 536458451, 536458471, 536458499, 536458513,
+    536458543, 536458547, 536458553, 536458567, 536458589, 536458607,
+    536458639, 536458649, 536458661, 536458667, 536458679, 536458691,
+    536458729, 536458759, 536458771, 536458789, 536458807, 536458837,
+    536458843, 536458859, 536458873, 536458913, 536458957, 536459029,
+    536459069, 536459083, 536459101, 536459113, 536459137, 536459149,
+    536459207, 536459213, 536459227, 536459249, 536459299, 536459359,
+    536459369, 536459389, 536459393, 536459479, 536459491, 536459503,
+    536459543, 536459563, 536459579, 536459593, 536459647, 536459653,
+    536459657, 536459669, 536459711, 536459747, 536459753, 536459767,
+    536459771, 536459789, 536459809, 536459827, 536459831, 536459839,
+    536459863, 536459879, 536459881, 536459909, 536459921, 536459941,
+    536459983, 536460013, 536460017, 536460061, 536460091, 536460107,
+    536460157, 536460181, 536460203, 536460233, 536460251, 536460311,
+    536460317, 536460341, 536460377, 536460427, 536460433, 536460437,
+    536460467, 536460479, 536460493, 536460539, 536460559, 536460563,
+    536460577, 536460581, 536460599, 536460641, 536460689, 536460707,
+    536460709, 536460713, 536460719, 536460737, 536460739, 536460751,
+    536460767, 536460787, 536460803, 536460811, 536460889, 536460913,
+    536460929, 536460931, 536460971, 536460973, 536460979, 536460989,
+    536460997, 536461001, 536461103, 536461147, 536461151, 536461153,
+    536461171, 536461193, 536461207, 536461213, 536461253, 536461259,
+    536461273, 536461279, 536461291, 536461327, 536461349, 536461363,
+    536461403, 536461439, 536461441, 536461463, 536461477, 536461489,
+    536461493, 536461553, 536461559, 536461567, 536461577, 536461649,
+    536461657, 536461661, 536461669, 536461693, 536461699, 536461771,
+    536461781, 536461787, 536461817, 536461819, 536461823, 536461837,
+    536461841, 536461847, 536461859, 536461873, 536461943, 536461967,
+    536461969, 536462009, 536462027, 536462083, 536462107, 536462123,
+    536462141, 536462153, 536462167, 536462231, 536462239, 536462263,
+    536462287, 536462291, 536462293, 536462317, 536462389, 536462411,
+    536462413, 536462417, 536462467, 536462483, 536462497, 536462513,
+    536462567, 536462579, 536462629, 536462669, 536462681, 536462743,
+    536462791, 536462809, 536462827, 536462837, 536462881, 536462887,
+    536462893, 536462917, 536462923, 536462933, 536462959, 536462977,
+    536462989, 536463023, 536463047, 536463049, 536463073, 536463131,
+    536463173, 536463197, 536463211, 536463241, 536463251, 536463281,
+    536463283, 536463289, 536463299, 536463329, 536463337, 536463391,
+    536463413, 536463427, 536463443, 536463451, 536463457, 536463467,
+    536463469, 536463479, 536463511, 536463553, 536463643, 536463647,
+    536463667, 536463673, 536463701, 536463709, 536463731, 536463737,
+    536463749, 536463751, 536463757, 536463761, 536463791, 536463817,
+    536463833, 536463839, 536463847, 536463857, 536463871, 536463911,
+    536463919, 536463923, 536463979, 536463989, 536464007, 536464043,
+    536464099, 536464153, 536464163, 536464217, 536464231, 536464237,
+    536464241, 536464249, 536464261, 536464277, 536464289, 536464309,
+    536464343, 536464349, 536464361, 536464363, 536464433, 536464457,
+    536464469, 536464471, 536464477, 536464493, 536464501, 536464543,
+    536464567, 536464573, 536464613, 536464651, 536464657, 536464679,
+    536464693, 536464697, 536464717, 536464727, 536464759, 536464769,
+    536464777, 536464783, 536464793, 536464871, 536464879, 536464883,
+    536464919, 536464931, 536464979, 536464991, 536465009, 536465023,
+    536465029, 536465071, 536465129, 536465161, 536465201, 536465203,
+    536465207, 536465213, 536465219, 536465231, 536465233, 536465297,
+    536465299, 536465339, 536465351, 536465381, 536465407, 536465441,
+    536465453, 536465459, 536465467, 536465477, 536465483, 536465497,
+    536465521, 536465533, 536465543, 536465557, 536465591, 536465609,
+    536465687, 536465723, 536465737, 536465773, 536465789, 536465791,
+    536465857, 536465861, 536465887, 536465899, 536465911, 536465939,
+    536465953, 536465959, 536465987, 536465999, 536466019, 536466079,
+    536466097, 536466113, 536466143, 536466179, 536466211, 536466223,
+    536466239, 536466317, 536466347, 536466473, 536466479, 536466481,
+    536466487, 536466493, 536466503, 536466523, 536466529, 536466571,
+    536466607, 536466613, 536466629, 536466631, 536466659, 536466661,
+    536466703, 536466713, 536466761, 536466769, 536466793, 536466803,
+    536466817, 536466823, 536466869, 536466871, 536466893, 536466913,
+    536466937, 536466967, 536466979, 536466989, 536467037, 536467081,
+    536467159, 536467163, 536467171, 536467187, 536467193, 536467229,
+    536467231, 536467271, 536467279, 536467301, 536467313, 536467333,
+    536467381, 536467391, 536467417, 536467427, 536467439, 536467469,
+    536467483, 536467513, 536467567, 536467577, 536467601, 536467609,
+    536467639, 536467649, 536467667, 536467669, 536467681, 536467697,
+    536467747, 536467753, 536467777, 536467787, 536467819, 536467829,
+    536467837, 536467843, 536467853, 536467879, 536467889, 536467931,
+    536467979, 536468017, 536468027, 536468033, 536468047, 536468063,
+    536468083, 536468087, 536468131, 536468159, 536468183, 536468203,
+    536468209, 536468213, 536468239, 536468311, 536468321, 536468323,
+    536468327, 536468333, 536468341, 536468347, 536468351, 536468357,
+    536468389, 536468407, 536468417, 536468431, 536468467, 536468503,
+    536468509, 536468551, 536468561, 536468623, 536468633, 536468657,
+    536468659, 536468707, 536468719, 536468741, 536468747, 536468759,
+    536468791, 536468797, 536468839, 536468861, 536468869, 536468893,
+    536468899, 536468917, 536468929, 536469029, 536469061, 536469071,
+    536469097, 536469107, 536469151, 536469211, 536469251, 536469257,
+    536469317, 536469331, 536469337, 536469343, 536469361, 536469371,
+    536469377, 536469383, 536469413, 536469443, 536469449, 536469473,
+    536469491, 536469533, 536469547, 536469553, 536469569, 536469607,
+    536469649, 536469653, 536469667, 536469671, 536469679, 536469683,
+    536469691, 536469709, 536469721, 536469727, 536469841, 536469851,
+    536469877, 536469889, 536469893, 536469907, 536469937, 536469977,
+    536469979, 536470013, 536470019, 536470027, 536470031, 536470057,
+    536470087, 536470127, 536470133, 536470157, 536470163, 536470169,
+    536470171, 536470177, 536470189, 536470201, 536470213, 536470223,
+    536470313, 536470379, 536470381, 536470387, 536470433, 536470447,
+    536470457, 536470463, 536470471, 536470483, 536470577, 536470589,
+    536470603, 536470621, 536470631, 536470663, 536470667, 536470673,
+    536470721, 536470723, 536470747, 536470763, 536470789, 536470793,
+    536470799, 536470811, 536470813, 536470843, 536470861, 536470867,
+    536470873, 536470901, 536470919, 536470927, 536470951, 536470973,
+    536470981, 536470997, 536470999, 536471009, 536471051, 536471063,
+    536471093, 536471107, 536471123, 536471153, 536471161, 536471167,
+    536471179, 536471191, 536471209, 536471219, 536471249, 536471269,
+    536471279, 536471281, 536471317, 536471339, 536471381, 536471423,
+    536471437, 536471447, 536471449, 536471491, 536471503, 536471521,
+    536471539, 536471591, 536471623, 536471629, 536471641, 536471653,
+    536471713, 536471723, 536471753, 536471791, 536471801, 536471809,
+    536471813, 536471851, 536471867, 536471869, 536471879, 536471927,
+    536471939, 536471951, 536472007, 536472017, 536472023, 536472031,
+    536472037, 536472047, 536472059, 536472061, 536472071, 536472091,
+    536472107, 536472113, 536472119, 536472127, 536472161, 536472193,
+    536472199, 536472203, 536472253, 536472259, 536472269, 536472289,
+    536472311, 536472317, 536472319, 536472341, 536472367, 536472373,
+    536472389, 536472403, 536472407, 536472437, 536472439, 536472457,
+    536472473, 536472529, 536472533, 536472571, 536472589, 536472593,
+    536472667, 536472697, 536472707, 536472709, 536472779, 536472787,
+    536472799, 536472817, 536472829, 536472877, 536472883, 536472889,
+    536472901, 536472917, 536472919, 536472931, 536472941, 536472967,
+    536472973, 536472977, 536473009, 536473013, 536473051, 536473061,
+    536473081, 536473103, 536473111, 536473123, 536473127, 536473153,
+    536473177, 536473187, 536473193, 536473207, 536473211, 536473213,
+    536473241, 536473297, 536473309, 536473313, 536473319, 536473339,
+    536473361, 536473381, 536473387, 536473391, 536473393, 536473409,
+    536473411, 536473429, 536473433, 536473447, 536473499, 536473513,
+    536473517, 536473529, 536473541, 536473583, 536473621, 536473649,
+    536473661, 536473681, 536473723, 536473727, 536473739, 536473741,
+    536473771, 536473783, 536473787, 536473789, 536473793, 536473829,
+    536473837, 536473859, 536473901, 536473907, 536473909, 536473937,
+    536473939, 536473943, 536473967, 536473969, 536473997, 536474009,
+    536474017, 536474033, 536474051, 536474087, 536474119, 536474123,
+    536474131, 536474203, 536474209, 536474231, 536474233, 536474269,
+    536474273, 536474317, 536474339, 536474363, 536474369, 536474371,
+    536474399, 536474417, 536474431, 536474447, 536474473, 536474483,
+    536474489, 536474513, 536474527, 536474569, 536474621, 536474657,
+    536474663, 536474677, 536474711, 536474749, 536474753, 536474759,
+    536474761, 536474767, 536474789, 536474819, 536474821, 536474843,
+    536474921, 536474929, 536474941, 536474971, 536474987, 536474989,
+    536475011, 536475059, 536475067, 536475073, 536475091, 536475113,
+    536475133, 536475139, 536475157, 536475167, 536475187, 536475193,
+    536475197, 536475257, 536475287, 536475319, 536475349, 536475371,
+    536475389, 536475403, 536475463, 536475473, 536475479, 536475481,
+    536475497, 536475509, 536475547, 536475571, 536475601, 536475619,
+    536475623, 536475631, 536475671, 536475673, 536475679, 536475701,
+    536475703, 536475707, 536475757, 536475763, 536475803, 536475827,
+    536475847, 536475853, 536475859, 536475871, 536475889, 536475899,
+    536475917, 536475923, 536475931, 536475937, 536475949, 536475983,
+    536475991, 536476007, 536476019, 536476043, 536476121, 536476163,
+    536476177, 536476181, 536476211, 536476223, 536476231, 536476271,
+    536476289, 536476301, 536476313, 536476331, 536476351, 536476373,
+    536476399, 536476453, 536476459, 536476469, 536476487, 536476561,
+    536476583, 536476627, 536476631, 536476637, 536476657, 536476673,
+    536476691, 536476709, 536476739, 536476741, 536476747, 536476757,
+    536476807, 536476823, 536476861, 536476873, 536476931, 536476933,
+    536476937, 536476981, 536476999, 536477009, 536477059, 536477063,
+    536477069, 536477089, 536477099, 536477101, 536477111, 536477167,
+    536477197, 536477209, 536477213, 536477233, 536477237, 536477243,
+    536477261, 536477267, 536477269, 536477273, 536477287, 536477299,
+    536477329, 536477339, 536477363, 536477401, 536477419, 536477423,
+    536477429, 536477441, 536477453, 536477471, 536477479, 536477549,
+    536477581, 536477593, 536477603, 536477621, 536477639, 536477651,
+    536477659, 536477677, 536477717, 536477731, 536477741, 536477791,
+    536477807, 536477813, 536477827, 536477831, 536477947, 536477951,
+    536477969, 536477999, 536478023, 536478037, 536478043, 536478079,
+    536478097, 536478101, 536478109, 536478121, 536478139, 536478149,
+    536478161, 536478181, 536478193, 536478211, 536478223, 536478227,
+    536478247, 536478259, 536478269, 536478287, 536478301, 536478307,
+    536478323, 536478361, 536478377, 536478379, 536478391, 536478431,
+    536478463, 536478479, 536478491, 536478541, 536478559, 536478583,
+    536478587, 536478599, 536478601, 536478617, 536478629, 536478641,
+    536478643, 536478659, 536478697, 536478757, 536478781, 536478791,
+    536478797, 536478827, 536478829, 536478857, 536478869, 536478881,
+    536478907, 536478937, 536478949, 536478953, 536478989, 536478997,
+    536479063, 536479093, 536479121, 536479133, 536479159, 536479171,
+    536479199, 536479213, 536479247, 536479249, 536479261, 536479297,
+    536479327, 536479357, 536479367, 536479373, 536479457, 536479469,
+    536479477, 536479483, 536479487, 536479501, 536479513, 536479529,
+    536479543, 536479553, 536479561, 536479589, 536479597, 536479609,
+    536479627, 536479631, 536479637, 536479673, 536479679, 536479709,
+    536479717, 536479721, 536479733, 536479771, 536479789, 536479843,
+    536479871, 536479873, 536479883, 536479891, 536479913, 536479919,
+    536479967, 536479969, 536480003, 536480011, 536480041, 536480051,
+    536480059, 536480089, 536480099, 536480111, 536480117, 536480149,
+    536480167, 536480173, 536480179, 536480201, 536480209, 536480249,
+    536480261, 536480297, 536480381, 536480393, 536480411, 536480437,
+    536480443, 536480459, 536480467, 536480471, 536480507, 536480521,
+    536480533, 536480587, 536480597, 536480603, 536480621, 536480627,
+    536480641, 536480663, 536480729, 536480731, 536480741, 536480767,
+    536480779, 536480783, 536480837, 536480851, 536480873, 536480881,
+    536480891, 536480927, 536480933, 536480939, 536480953, 536480969,
+    536481037, 536481047, 536481059, 536481073, 536481083, 536481103,
+    536481109, 536481137, 536481139, 536481163, 536481191, 536481193,
+    536481199, 536481217, 536481247, 536481251, 536481259, 536481271,
+    536481289, 536481299, 536481313, 536481331, 536481367, 536481383,
+    536481391, 536481431, 536481457, 536481479, 536481487, 536481493,
+    536481499, 536481557, 536481559, 536481571, 536481593, 536481623,
+    536481677, 536481713, 536481727, 536481809, 536481839, 536481859,
+    536481947, 536481949, 536481961, 536481983, 536482013, 536482021,
+    536482069, 536482091, 536482097, 536482139, 536482151, 536482159,
+    536482181, 536482189, 536482201, 536482207, 536482217, 536482229,
+    536482279, 536482283, 536482321, 536482327, 536482363, 536482381,
+    536482399, 536482411, 536482439, 536482553, 536482579, 536482591,
+    536482637, 536482643, 536482649, 536482669, 536482673, 536482691,
+    536482697, 536482717, 536482729, 536482763, 536482781, 536482789,
+    536482799, 536482873, 536482883, 536482927, 536482951, 536483021,
+    536483053, 536483099, 536483113, 536483147, 536483153, 536483177,
+    536483197, 536483231, 536483273, 536483279, 536483309, 536483317,
+    536483327, 536483359, 536483393, 536483407, 536483413, 536483419,
+    536483447, 536483473, 536483477, 536483491, 536483527, 536483573,
+    536483587, 536483641, 536483653, 536483669, 536483767, 536483777,
+    536483797, 536483833, 536483851, 536483891, 536483951, 536483957,
+    536483971, 536483999, 536484059, 536484061, 536484077, 536484103,
+    536484107, 536484121, 536484149, 536484161, 536484163, 536484187,
+    536484199, 536484217, 536484239, 536484241, 536484251, 536484259,
+    536484271, 536484281, 536484313, 536484329, 536484331, 536484353,
+    536484359, 536484371, 536484397, 536484401, 536484439, 536484457,
+    536484479, 536484491, 536484493, 536484503, 536484517, 536484523,
+    536484577, 536484587, 536484607, 536484617, 536484643, 536484653,
+    536484701, 536484731, 536484737, 536484749, 536484757, 536484761,
+    536484769, 536484797, 536484803, 536484869, 536484881, 536484887,
+    536484901, 536484911, 536484917, 536484943, 536484947, 536484979,
+    536484983, 536484989, 536485003, 536485043, 536485069, 536485073,
+    536485091, 536485109, 536485127, 536485139, 536485153, 536485199,
+    536485219, 536485223, 536485231, 536485253, 536485259, 536485343,
+    536485351, 536485361, 536485393, 536485427, 536485429, 536485441,
+    536485483, 536485487, 536485489, 536485519, 536485559, 536485571,
+    536485601, 536485613, 536485627, 536485669, 536485679, 536485699,
+    536485717, 536485723, 536485739, 536485751, 536485753, 536485771,
+    536485811, 536485823, 536485837, 536485867, 536485883, 536485897,
+    536485921, 536485987, 536486009, 536486023, 536486029, 536486039,
+    536486053, 536486081, 536486099, 536486131, 536486143, 536486161,
+    536486183, 536486191, 536486231, 536486243, 536486257, 536486263,
+    536486267, 536486297, 536486311, 536486317, 536486329, 536486359,
+    536486387, 536486429, 536486441, 536486453, 536486471, 536486473,
+    536486497, 536486501, 536486537, 536486581, 536486591, 536486677,
+    536486759, 536486761, 536486777, 536486801, 536486827, 536486849,
+    536486861, 536486893, 536486911, 536486917, 536486947, 536486957,
+    536486971, 536486987, 536487011, 536487031, 536487079, 536487089,
+    536487101, 536487113, 536487137, 536487143, 536487151, 536487163,
+    536487191, 536487197, 536487233, 536487239, 536487257, 536487277,
+    536487299, 536487317, 536487323, 536487353, 536487373, 536487389,
+    536487403, 536487437, 536487451, 536487481, 536487491, 536487493,
+    536487533, 536487577, 536487599, 536487607, 536487613, 536487631,
+    536487661, 536487701, 536487703, 536487709, 536487739, 536487769,
+    536487793, 536487797, 536487803, 536487821, 536487851, 536487893,
+    536487899, 536487929, 536487937, 536487943, 536487979, 536488021,
+    536488031, 536488037, 536488079, 536488093, 536488109, 536488129,
+    536488213, 536488217, 536488219, 536488241, 536488243, 536488297,
+    536488331, 536488369, 536488391, 536488439, 536488471, 536488481,
+    536488531, 536488549, 536488553, 536488559, 536488577, 536488591,
+    536488613, 536488627, 536488633, 536488637, 536488643, 536488651,
+    536488657, 536488723, 536488727, 536488747, 536488783, 536488793,
+    536488819, 536488831, 536488837, 536488859, 536488877, 536488889,
+    536488963, 536488969, 536488991, 536488999, 536489017, 536489039,
+    536489071, 536489117, 536489137, 536489143, 536489197, 536489203,
+    536489227, 536489231, 536489269, 536489287, 536489293, 536489347,
+    536489351, 536489489, 536489501, 536489533, 536489557, 536489573,
+    536489579, 536489581, 536489599, 536489663, 536489699, 536489717,
+    536489729, 536489731, 536489749, 536489803, 536489809, 536489827,
+    536489843, 536489857, 536489861, 536489867, 536489897, 536489917,
+    536489929, 536489939, 536489957, 536489963, 536489969, 536490001,
+    536490011, 536490041, 536490049, 536490091, 536490109, 536490113,
+    536490151, 536490167, 536490173, 536490191, 536490193, 536490197,
+    536490209, 536490223, 536490257, 536490259, 536490263, 536490319,
+    536490323, 536490329, 536490347, 536490379, 536490389, 536490391,
+    536490421, 536490431, 536490497, 536490523, 536490529, 536490551,
+    536490583, 536490587, 536490629, 536490649, 536490653, 536490683,
+    536490701, 536490739, 536490803, 536490809, 536490881, 536490883,
+    536490887, 536490901, 536490937, 536490959, 536490967, 536490971,
+    536490979, 536491003, 536491051, 536491061, 536491073, 536491099,
+    536491139, 536491183, 536491223, 536491283, 536491297, 536491339,
+    536491357, 536491409, 536491411, 536491441, 536491447, 536491477,
+    536491513, 536491541, 536491567, 536491591, 536491603, 536491609,
+    536491621, 536491643, 536491679, 536491727, 536491759, 536491777,
+    536491789, 536491807, 536491829, 536491849, 536491853, 536491867,
+    536491883, 536491903, 536491919, 536491927, 536491931, 536491937,
+    536491957, 536491973, 536491979, 536492003, 536492039, 536492051,
+    536492059, 536492071, 536492087, 536492153, 536492161, 536492167,
+    536492179, 536492183, 536492197, 536492207, 536492221, 536492237,
+    536492309, 536492311, 536492321, 536492371, 536492387, 536492389,
+    536492399, 536492423, 536492449, 536492459, 536492471, 536492483,
+    536492497, 536492513, 536492521, 536492527, 536492557, 536492587,
+    536492599, 536492611, 536492653, 536492689, 536492729, 536492753,
+    536492777, 536492791, 536492807, 536492839, 536492843, 536492849,
+    536492861, 536492927, 536492939, 536492941, 536492951, 536492989,
+    536493017, 536493049, 536493073, 536493079, 536493103, 536493107,
+    536493119, 536493121, 536493131, 536493137, 536493143, 536493149,
+    536493169, 536493179, 536493247, 536493263, 536493281, 536493317,
+    536493371, 536493407, 536493421, 536493457, 536493467, 536493509,
+    536493521, 536493523, 536493527, 536493541, 536493563, 536493583,
+    536493611, 536493637, 536493647, 536493739, 536493743, 536493773,
+    536493787, 536493809, 536493817, 536493833, 536493901, 536493907,
+    536493913, 536493943, 536493961, 536494003, 536494027, 536494031,
+    536494081, 536494087, 536494103, 536494121, 536494129, 536494163,
+    536494169, 536494181, 536494201, 536494213, 536494219, 536494223,
+    536494243, 536494261, 536494303, 536494333, 536494367, 536494369,
+    536494379, 536494397, 536494417, 536494421, 536494429, 536494433,
+    536494477, 536494513, 536494537, 536494549, 536494571, 536494579,
+    536494589, 536494597, 536494627, 536494639, 536494643, 536494657,
+    536494691, 536494727, 536494741, 536494747, 536494769, 536494787,
+    536494793, 536494831, 536494837, 536494841, 536494853, 536494873,
+    536494883, 536494909, 536494943, 536494979, 536494999, 536495009,
+    536495053, 536495059, 536495119, 536495123, 536495143, 536495149,
+    536495213, 536495221, 536495233, 536495237, 536495243, 536495249,
+    536495257, 536495261, 536495321, 536495339, 536495369, 536495423,
+    536495461, 536495473, 536495501, 536495513, 536495527, 536495543,
+    536495551, 536495581, 536495591, 536495633, 536495657, 536495693,
+    536495717, 536495731, 536495759, 536495767, 536495797, 536495801,
+    536495831, 536495833, 536495857, 536495881, 536495923, 536495957,
+    536496007, 536496043, 536496049, 536496061, 536496101, 536496109,
+    536496131, 536496167, 536496197, 536496209, 536496223, 536496227,
+    536496241, 536496277, 536496283, 536496329, 536496341, 536496379,
+    536496419, 536496431, 536496437, 536496449, 536496461, 536496481,
+    536496487, 536496503, 536496511, 536496517, 536496529, 536496533,
+    536496553, 536496563, 536496589, 536496619, 536496677, 536496691,
+    536496703, 536496731, 536496739, 536496743, 536496791, 536496797,
+    536496817, 536496833, 536496841, 536496847, 536496859, 536496871,
+    536496887, 536496889, 536496893, 536496911, 536496937, 536496953,
+    536496973, 536497063, 536497099, 536497121, 536497133, 536497141,
+    536497147, 536497193, 536497211, 536497223, 536497231, 536497261,
+    536497277, 536497289, 536497301, 536497321, 536497349, 536497399,
+    536497411, 536497427, 536497459, 536497469, 536497483, 536497487,
+    536497537, 536497553, 536497567, 536497573, 536497579, 536497583,
+    536497601, 536497667, 536497681, 536497693, 536497697, 536497727,
+    536497729, 536497837, 536497859, 536497861, 536497909, 536497919,
+    536497933, 536497967, 536497987, 536497993, 536498029, 536498047,
+    536498051, 536498077, 536498101, 536498129, 536498167, 536498197,
+    536498219, 536498227, 536498267, 536498323, 536498399, 536498423,
+    536498447, 536498449, 536498503, 536498509, 536498513, 536498527,
+    536498533, 536498539, 536498581, 536498591, 536498593, 536498609,
+    536498647, 536498657, 536498693, 536498723, 536498731, 536498737,
+    536498747, 536498789, 536498821, 536498849, 536498857, 536498861,
+    536498873, 536498909, 536498951, 536498957, 536498959, 536498999,
+    536499011, 536499037, 536499053, 536499059, 536499071, 536499077,
+    536499109, 536499133, 536499157, 536499163, 536499169, 536499211,
+    536499233, 536499239, 536499259, 536499269, 536499287, 536499307,
+    536499319, 536499323, 536499329, 536499367, 536499419, 536499427,
+    536499451, 536499461, 536499463, 536499487, 536499493, 536499503,
+    536499533, 536499539, 536499571, 536499589, 536499629, 536499631,
+    536499647, 536499653, 536499659, 536499661, 536499683, 536499721,
+    536499737, 536499757, 536499763, 536499767, 536499811, 536499851,
+    536499869, 536499947, 536499961, 536499967, 536500007, 536500009,
+    536500031, 536500057, 536500073, 536500103, 536500123, 536500163,
+    536500171, 536500187, 536500189, 536500213, 536500241, 536500249,
+    536500267, 536500301, 536500309, 536500337, 536500339, 536500351,
+    536500361, 536500373, 536500381, 536500387, 536500409, 536500417,
+    536500453, 536500483, 536500487, 536500499, 536500519, 536500543,
+    536500561, 536500649, 536500669, 536500681, 536500687, 536500709,
+    536500711, 536500717, 536500721, 536500733, 536500763, 536500781,
+    536500793, 536500819, 536500823, 536500831, 536500837, 536500843,
+    536500847, 536500859, 536500903, 536500919, 536501003, 536501023,
+    536501041, 536501051, 536501117, 536501143, 536501183, 536501191,
+    536501201, 536501209, 536501257, 536501267, 536501291, 536501321,
+    536501323, 536501341, 536501377, 536501387, 536501393, 536501431,
+    536501477, 536501491, 536501501, 536501503, 536501507, 536501533,
+    536501549, 536501587, 536501599, 536501617, 536501621, 536501639,
+    536501671, 536501677, 536501683, 536501699, 536501729, 536501731,
+    536501741, 536501743, 536501761, 536501789, 536501831, 536501863,
+    536501869, 536501873, 536501899, 536501923, 536501951, 536501969,
+    536501989, 536502007, 536502011, 536502017, 536502019, 536502023,
+    536502037, 536502047, 536502049, 536502139, 536502143, 536502157,
+    536502283, 536502353, 536502359, 536502361, 536502377, 536502397,
+    536502401, 536502403, 536502409, 536502419, 536502431, 536502451,
+    536502493, 536502497, 536502569, 536502587, 536502611, 536502653,
+    536502683, 536502689, 536502719, 536502727, 536502731, 536502739,
+    536502749, 536502773, 536502793, 536502821, 536502851, 536502877,
+    536502893, 536502907, 536502913, 536502931, 536502937, 536502961,
+    536502973, 536502977, 536503007, 536503013, 536503039, 536503043,
+    536503049, 536503067, 536503109, 536503127, 536503139, 536503157,
+    536503181, 536503183, 536503189, 536503223, 536503229, 536503241,
+    536503249, 536503273, 536503291, 536503339, 536503349, 536503369,
+    536503379, 536503417, 536503423, 536503433, 536503439, 536503483,
+    536503489, 536503501, 536503507, 536503519, 536503537, 536503571,
+    536503603, 536503613, 536503657, 536503687, 536503757, 536503769,
+    536503787, 536503813, 536503823, 536503843, 536503861, 536503871,
+    536503879, 536503883, 536503927, 536503939, 536503943, 536503951,
+    536503997, 536504009, 536504053, 536504063, 536504069, 536504113,
+    536504117, 536504119, 536504123, 536504167, 536504179, 536504183,
+    536504191, 536504209, 536504219, 536504251, 536504299, 536504303,
+    536504323, 536504351, 536504363, 536504369, 536504399, 536504401,
+    536504413, 536504459, 536504461, 536504473, 536504489, 536504543,
+    536504561, 536504567, 536504587, 536504599, 536504621, 536504651,
+    536504713, 536504723, 536504777, 536504783, 536504789, 536504791,
+    536504797, 536504807, 536504827, 536504861, 536504863, 536504869,
+    536504893, 536504929, 536504951, 536504977, 536504981, 536504993,
+    536505001, 536505007, 536505059, 536505103, 536505121, 536505149,
+    536505173, 536505197, 536505239, 536505241, 536505257, 536505287,
+    536505301, 536505311, 536505331, 536505401, 536505407, 536505421,
+    536505427, 536505449, 536505461, 536505479, 536505493, 536505503,
+    536505523, 536505547, 536505631, 536505643, 536505677, 536505701,
+    536505707, 536505709, 536505719, 536505721, 536505727, 536505733,
+    536505743, 536505757, 536505763, 536505773, 536505779, 536505817,
+    536505833, 536505841, 536505847, 536505859, 536505899, 536505911,
+    536505943, 536505979, 536505989, 536505997, 536506001, 536506049,
+    536506063, 536506079, 536506099, 536506109, 536506123, 536506133,
+    536506153, 536506169, 536506199, 536506207, 536506219, 536506231,
+    536506241, 536506283, 536506309, 536506331, 536506379, 536506381,
+    536506387, 536506391, 536506403, 536506423, 536506427, 536506433,
+    536506463, 536506469, 536506493, 536506541, 536506543, 536506561,
+    536506567, 536506573, 536506603, 536506609, 536506627, 536506631,
+    536506643, 536506673, 536506693, 536506703, 536506741, 536506777,
+    536506793, 536506807, 536506813, 536506871, 536506891, 536506897,
+    536506907, 536506951, 536506973, 536506979, 536507071, 536507089,
+    536507093, 536507129, 536507143, 536507159, 536507171, 536507189,
+    536507201, 536507203, 536507227, 536507273, 536507333, 536507341,
+    536507347, 536507357, 536507371, 536507401, 536507417, 536507443,
+    536507467, 536507479, 536507501, 536507513, 536507519, 536507527,
+    536507537, 536507557, 536507567, 536507581, 536507599, 536507611,
+    536507663, 536507687, 536507717, 536507747, 536507759, 536507789,
+    536507809, 536507819, 536507833, 536507843, 536507863, 536507869,
+    536507953, 536507957, 536507969, 536507977, 536507989, 536507999,
+    536508013, 536508017, 536508019, 536508023, 536508053, 536508101,
+    536508121, 536508139, 536508173, 536508191, 536508209, 536508211,
+    536508257, 536508307, 536508311, 536508331, 536508353, 536508361,
+    536508383, 536508391, 536508433, 536508487, 536508499, 536508503,
+    536508517, 536508601, 536508611, 536508629, 536508641, 536508647,
+    536508659, 536508689, 536508697, 536508751, 536508761, 536508767,
+    536508793, 536508799, 536508823, 536508839, 536508857, 536508881,
+    536508923, 536508937, 536508949, 536508953, 536509027, 536509031,
+    536509049, 536509079, 536509093, 536509111, 536509117, 536509147,
+    536509187, 536509229, 536509241, 536509283, 536509291, 536509319,
+    536509381, 536509397, 536509417, 536509433, 536509451, 536509453,
+    536509459, 536509481, 536509487, 536509499, 536509507, 536509537,
+    536509549, 536509553, 536509573, 536509601, 536509607, 536509609,
+    536509639, 536509691, 536509709, 536509741, 536509763, 536509781,
+    536509789, 536509801, 536509819, 536509843, 536509871, 536509903,
+    536509913, 536509927, 536509957, 536509991, 536510003, 536510017,
+    536510041, 536510057, 536510059, 536510113, 536510119, 536510147,
+    536510159, 536510171, 536510173, 536510197, 536510263, 536510267,
+    536510279, 536510309, 536510383, 536510407, 536510413, 536510419,
+    536510449, 536510477, 536510479, 536510503, 536510509, 536510563,
+    536510609, 536510621, 536510647, 536510651, 536510683, 536510729,
+    536510731, 536510747, 536510761, 536510773, 536510797, 536510801,
+    536510813, 536510839, 536510851, 536510867, 536510869, 536510879,
+    536510917, 536510929, 536510951, 536510959, 536510963, 536510983,
+    536510993, 536511023, 536511071, 536511089, 536511097, 536511167,
+    536511181, 536511193, 536511197, 536511229, 536511257, 536511259,
+    536511289, 536511299, 536511307, 536511319, 536511337, 536511427,
+    536511431, 536511467, 536511487, 536511557, 536511583, 536511617,
+    536511631, 536511649, 536511659, 536511667, 536511709, 536511719,
+    536511727, 536511743, 536511749, 536511757, 536511769, 536511791,
+    536511793, 536511799, 536511809, 536511827, 536511841, 536511851,
+    536511853, 536511863, 536511883, 536511889, 536511893, 536511923,
+    536511929, 536511953, 536511973, 536512001, 536512037, 536512051,
+    536512069, 536512073, 536512087, 536512111, 536512117, 536512121,
+    536512153, 536512157, 536512189, 536512199, 536512213, 536512243,
+    536512289, 536512331, 536512343, 536512351, 536512357, 536512363,
+    536512387, 536512393, 536512397, 536512451, 536512517, 536512573,
+    536512577, 536512589, 536512601, 536512607, 536512609, 536512637,
+    536512649, 536512657, 536512663, 536512729, 536512733, 536512771,
+    536512817, 536512819, 536512841, 536512859, 536512871, 536512883,
+    536512903, 536512931, 536512957, 536512969, 536512997, 536513017,
+    536513027, 536513041, 536513053, 536513057, 536513059, 536513077,
+    536513101, 536513113, 536513123, 536513161, 536513171, 536513177,
+    536513191, 536513207, 536513231, 536513291, 536513297, 536513303,
+    536513363, 536513399, 536513401, 536513407, 536513423, 536513437,
+    536513441, 536513443, 536513447, 536513459, 536513501, 536513531,
+    536513533, 536513563, 536513599, 536513603, 536513629, 536513639,
+    536513651, 536513669, 536513707, 536513711, 536513723, 536513749,
+    536513759, 536513779, 536513827, 536513867, 536513899, 536513903,
+    536513921, 536513933, 536513953, 536513981, 536514049, 536514073,
+    536514079, 536514107, 536514113, 536514119, 536514133, 536514163,
+    536514193, 536514211, 536514221, 536514247, 536514263, 536514287,
+    536514289, 536514301, 536514367, 536514379, 536514383, 536514409,
+    536514431, 536514439, 536514481, 536514487, 536514499, 536514521,
+    536514527, 536514593, 536514599, 536514619, 536514623, 536514637,
+    536514653, 536514659, 536514661, 536514683, 536514697, 536514701,
+    536514733, 536514749, 536514757, 536514779, 536514787, 536514817,
+    536514829, 536514871, 536514943, 536514973, 536514977, 536514983,
+    536515009, 536515061, 536515093, 536515097, 536515127, 536515129,
+    536515139, 536515193, 536515201, 536515241, 536515247, 536515253,
+    536515271, 536515277, 536515279, 536515289, 536515327, 536515363,
+    536515373, 536515391, 536515417, 536515433, 536515453, 536515493,
+    536515501, 536515517, 536515519, 536515541, 536515561, 536515589,
+    536515619, 536515621, 536515649, 536515657, 536515663, 536515697,
+    536515717, 536515739, 536515783, 536515789, 536515813, 536515817,
+    536515849, 536515867, 536515883, 536515933, 536515957, 536515981,
+    536515999, 536516003, 536516023, 536516033, 536516041, 536516047,
+    536516051, 536516063, 536516081, 536516131, 536516159, 536516161,
+    536516179, 536516207, 536516213, 536516237, 536516251, 536516303,
+    536516329, 536516333, 536516353, 536516381, 536516389, 536516401,
+    536516419, 536516437, 536516467, 536516489, 536516527, 536516531,
+    536516557, 536516567, 536516593, 536516599, 536516627, 536516641,
+    536516671, 536516681, 536516711, 536516749, 536516759, 536516789,
+    536516801, 536516807, 536516809, 536516819, 536516833, 536516843,
+    536516861, 536516863, 536516873, 536516951, 536516963, 536516971,
+    536516987, 536517011, 536517013, 536517017, 536517019, 536517053,
+    536517061, 536517073, 536517083, 536517101, 536517167, 536517169,
+    536517211, 536517227, 536517253, 536517257, 536517277, 536517323,
+    536517409, 536517437, 536517473, 536517479, 536517491, 536517517,
+    536517521, 536517523, 536517529, 536517533, 536517551, 536517557,
+    536517563, 536517577, 536517617, 536517623, 536517629, 536517659,
+    536517689, 536517691, 536517697, 536517701, 536517799, 536517811,
+    536517823, 536517853, 536517869, 536517889, 536517907, 536517911,
+    536517913, 536517931, 536518007, 536518027, 536518051, 536518063,
+    536518069, 536518091, 536518117, 536518121, 536518139, 536518189,
+    536518193, 536518201, 536518243, 536518259, 536518261, 536518277,
+    536518289, 536518319, 536518327, 536518331, 536518337, 536518343,
+    536518361, 536518369, 536518397, 536518399, 536518403, 536518469,
+    536518471, 536518501, 536518517, 536518559, 536518603, 536518613,
+    536518627, 536518663, 536518673, 536518693, 536518709, 536518711,
+    536518727, 536518817, 536518823, 536518831, 536518837, 536518847,
+    536518859, 536518877, 536518921, 536518943, 536518951, 536518991,
+    536519003, 536519029, 536519057, 536519101, 536519117, 536519119,
+    536519161, 536519189, 536519197, 536519209, 536519219, 536519251,
+    536519281, 536519327, 536519353, 536519363, 536519369, 536519383,
+    536519407, 536519519, 536519521, 536519531, 536519561, 536519591,
+    536519603, 536519611, 536519623, 536519629, 536519639, 536519651,
+    536519653, 536519713, 536519717, 536519741, 536519747, 536519849,
+    536519861, 536519887, 536519927, 536519933, 536519939, 536519941,
+    536519947, 536519953, 536520041, 536520059, 536520077, 536520079,
+    536520133, 536520151, 536520161, 536520163, 536520197, 536520199,
+    536520227, 536520247, 536520253, 536520269, 536520277, 536520293,
+    536520319, 536520343, 536520353, 536520367, 536520377, 536520403,
+    536520407, 536520433, 536520443, 536520449, 536520451, 536520487,
+    536520529, 536520533, 536520539, 536520617, 536520637, 536520641,
+    536520661, 536520671, 536520709, 536520713, 536520737, 536520763,
+    536520767, 536520773, 536520779, 536520811, 536520821, 536520827,
+    536520863, 536520869, 536520877, 536520913, 536520983, 536520991,
+    536521009, 536521021, 536521033, 536521049, 536521079, 536521081,
+    536521087, 536521133, 536521157, 536521163, 536521211, 536521229,
+    536521231, 536521243, 536521261, 536521289, 536521319, 536521333,
+    536521361, 536521387, 536521399, 536521409, 536521417, 536521421,
+    536521439, 536521463, 536521471, 536521477, 536521499, 536521561,
+    536521567, 536521589, 536521669, 536521679, 536521693, 536521723,
+    536521763, 536521807, 536521813, 536521831, 536521847, 536521883,
+    536521907, 536521913, 536521927, 536521939, 536521949, 536521957,
+    536522009, 536522017, 536522047, 536522059, 536522099, 536522117,
+    536522123, 536522141, 536522179, 536522197, 536522291, 536522299,
+    536522321, 536522387, 536522401, 536522407, 536522419, 536522443,
+    536522489, 536522491, 536522501, 536522521, 536522561, 536522563,
+    536522579, 536522593, 536522603, 536522621, 536522641, 536522663,
+    536522671, 536522677, 536522687, 536522699, 536522711, 536522729,
+    536522731, 536522747, 536522837, 536522879, 536522887, 536522923,
+    536522927, 536522933, 536522951, 536522953, 536522957, 536522971,
+    536522981, 536522989, 536523037, 536523041, 536523079, 536523101,
+    536523103, 536523131, 536523133, 536523149, 536523151, 536523161,
+    536523173, 536523191, 536523217, 536523227, 536523233, 536523257,
+    536523259, 536523263, 536523269, 536523271, 536523289, 536523307,
+    536523313, 536523319, 536523409, 536523431, 536523433, 536523439,
+    536523457, 536523497, 536523503, 536523509, 536523571, 536523619,
+    536523649, 536523667, 536523677, 536523679, 536523683, 536523709,
+    536523721, 536523733, 536523761, 536523763, 536523803, 536523811,
+    536523899, 536523917, 536523947, 536523973, 536523979, 536524003,
+    536524031, 536524049, 536524057, 536524127, 536524133, 536524159,
+    536524171, 536524193, 536524211, 536524213, 536524217, 536524249,
+    536524253, 536524277, 536524283, 536524333, 536524357, 536524393,
+    536524433, 536524453, 536524529, 536524537, 536524561, 536524567,
+    536524577, 536524589, 536524591, 536524619, 536524627, 536524633,
+    536524649, 536524661, 536524691, 536524697, 536524739, 536524759,
+    536524763, 536524771, 536524783, 536524817, 536524847, 536524867,
+    536524871, 536524873, 536524897, 536524909, 536524927, 536524931,
+    536524939, 536524949, 536524991, 536524999, 536525009, 536525023,
+    536525039, 536525047, 536525081, 536525111, 536525131, 536525137,
+    536525149, 536525177, 536525179, 536525189, 536525239, 536525281,
+    536525323, 536525357, 536525369, 536525371, 536525377, 536525411,
+    536525417, 536525441, 536525443, 536525459, 536525461, 536525489,
+    536525503, 536525533, 536525543, 536525551, 536525557, 536525573,
+    536525599, 536525651, 536525653, 536525659, 536525681, 536525687,
+    536525699, 536525701, 536525753, 536525767, 536525783, 536525809,
+    536525813, 536525849, 536525879, 536525887, 536525903, 536525929,
+    536525939, 536525981, 536525993, 536526019, 536526043, 536526059,
+    536526119, 536526121, 536526127, 536526131, 536526139, 536526157,
+    536526217, 536526229, 536526251, 536526257, 536526271, 536526283,
+    536526317, 536526323, 536526329, 536526343, 536526377, 536526379,
+    536526383, 536526391, 536526413, 536526433, 536526499, 536526509,
+    536526521, 536526527, 536526539, 536526581, 536526629, 536526631,
+    536526637, 536526673, 536526689, 536526701, 536526719, 536526733,
+    536526737, 536526743, 536526763, 536526787, 536526797, 536526829,
+    536526853, 536526863, 536526869, 536526901, 536526917, 536526929,
+    536526931, 536526961, 536526967, 536526971, 536526979, 536526983,
+    536526989, 536527007, 536527027, 536527067, 536527081, 536527087,
+    536527129, 536527133, 536527139, 536527153, 536527163, 536527169,
+    536527193, 536527207, 536527217, 536527237, 536527241, 536527249,
+    536527307, 536527319, 536527337, 536527373, 536527393, 536527403,
+    536527441, 536527457, 536527471, 536527477, 536527507, 536527543,
+    536527547, 536527549, 536527591, 536527603, 536527669, 536527679,
+    536527699, 536527709, 536527711, 536527723, 536527793, 536527799,
+    536527807, 536527891, 536527903, 536527919, 536527921, 536527931,
+    536527949, 536527961, 536527967, 536527987, 536527997, 536528021,
+    536528033, 536528039, 536528087, 536528089, 536528093, 536528141,
+    536528183, 536528197, 536528203, 536528219, 536528273, 536528309,
+    536528323, 536528341, 536528357, 536528393, 536528417, 536528431,
+    536528467, 536528491, 536528513, 536528537, 536528539, 536528543,
+    536528549, 536528557, 536528569, 536528581, 536528599, 536528609,
+    536528617, 536528647, 536528711, 536528719, 536528723, 536528743,
+    536528761, 536528771, 536528807, 536528809, 536528813, 536528819,
+    536528833, 536528893, 536528917, 536528921, 536528933, 536528939,
+    536528947, 536528969, 536528983, 536529013, 536529031, 536529041,
+    536529047, 536529089, 536529101, 536529139, 536529143, 536529173,
+    536529241, 536529269, 536529281, 536529293, 536529373, 536529419,
+    536529437, 536529439, 536529451, 536529509, 536529517, 536529523,
+    536529559, 536529569, 536529577, 536529583, 536529599, 536529607,
+    536529611, 536529613, 536529641, 536529677, 536529683, 536529701,
+    536529703, 536529737, 536529739, 536529743, 536529787, 536529817,
+    536529823, 536529827, 536529869, 536529871, 536529883, 536529907,
+    536529913, 536529943, 536529991, 536529997, 536530021, 536530103,
+    536530109, 536530117, 536530123, 536530133, 536530153, 536530219,
+    536530231, 536530259, 536530277, 536530301, 536530349, 536530391,
+    536530459, 536530471, 536530481, 536530513, 536530567, 536530597,
+    536530619, 536530627, 536530649, 536530663, 536530723, 536530739,
+    536530763, 536530777, 536530793, 536530817, 536530831, 536530843,
+    536530871, 536530877, 536530901, 536530979, 536530993, 536531041,
+    536531057, 536531077, 536531123, 536531129, 536531131, 536531161,
+    536531209, 536531213, 536531231, 536531251, 536531257, 536531279,
+    536531293, 536531341, 536531351, 536531357, 536531381, 536531383,
+    536531389, 536531393, 536531399, 536531431, 536531459, 536531483,
+    536531497, 536531507, 536531537, 536531551, 536531621, 536531627,
+    536531651, 536531659, 536531689, 536531707, 536531711, 536531753,
+    536531759, 536531771, 536531789, 536531791, 536531803, 536531819,
+    536531839, 536531869, 536531887, 536531909, 536531953, 536531977,
+    536531981, 536531999, 536532001, 536532011, 536532041, 536532049,
+    536532107, 536532131, 536532151, 536532187, 536532193, 536532229,
+    536532239, 536532299, 536532323, 536532383, 536532419, 536532439,
+    536532497, 536532499, 536532527, 536532547, 536532551, 536532613,
+    536532617, 536532643, 536532653, 536532713, 536532719, 536532721,
+    536532739, 536532743, 536532749, 536532769, 536532791, 536532803,
+    536532809, 536532817, 536532853, 536532863, 536532877, 536532883,
+    536532889, 536532917, 536532923, 536532959, 536533007, 536533009,
+    536533021, 536533033, 536533037, 536533043, 536533097, 536533099,
+    536533111, 536533133, 536533139, 536533159, 536533171, 536533177,
+    536533187, 536533201, 536533219, 536533241, 536533273, 536533279,
+    536533289, 536533301, 536533409, 536533423, 536533427, 536533441,
+    536533453, 536533463, 536533493, 536533507, 536533519, 536533531,
+    536533567, 536533579, 536533597, 536533601, 536533603, 536533619,
+    536533639, 536533649, 536533703, 536533733, 536533801, 536533807,
+    536533817, 536533819, 536533853, 536533859, 536533891, 536533909,
+    536533931, 536533937, 536533969, 536534039, 536534071, 536534083,
+    536534111, 536534147, 536534171, 536534189, 536534213, 536534227,
+    536534239, 536534261, 536534269, 536534279, 536534287, 536534303,
+    536534347, 536534353, 536534381, 536534393, 536534443, 536534489,
+    536534491, 536534503, 536534513, 536534533, 536534543, 536534561,
+    536534573, 536534591, 536534599, 536534611, 536534617, 536534623,
+    536534629, 536534653, 536534689, 536534707, 536534729, 536534737,
+    536534753, 536534767, 536534797, 536534813, 536534827, 536534837,
+    536534893, 536534959, 536534969, 536534983, 536534989, 536535017,
+    536535029, 536535031, 536535047, 536535071, 536535121, 536535151,
+    536535229, 536535239, 536535257, 536535269, 536535277, 536535289,
+    536535299, 536535301, 536535313, 536535347, 536535359, 536535361,
+    536535367, 536535379, 536535401, 536535437, 536535469, 536535479,
+    536535481, 536535511, 536535529, 536535541, 536535551, 536535563,
+    536535577, 536535613, 536535667, 536535707, 536535709, 536535719,
+    536535751, 536535761, 536535773, 536535803, 536535829, 536535841,
+    536535859, 536535863, 536535893, 536535913, 536535917, 536535919,
+    536535943, 536535959, 536535971, 536536009, 536536027, 536536051,
+    536536087, 536536093, 536536103, 536536109, 536536129, 536536151,
+    536536171, 536536181, 536536207, 536536229, 536536243, 536536271,
+    536536283, 536536289, 536536361, 536536367, 536536379, 536536417,
+    536536471, 536536493, 536536513, 536536523, 536536529, 536536531,
+    536536549, 536536577, 536536601, 536536661, 536536669, 536536681,
+    536536691, 536536697, 536536703, 536536723, 536536727, 536536753,
+    536536807, 536536829, 536536849, 536536853, 536536873, 536536883,
+    536536937, 536536943, 536536951, 536536961, 536536969, 536536993,
+    536536999, 536537003, 536537021, 536537041, 536537063, 536537069,
+    536537087, 536537107, 536537117, 536537137, 536537147, 536537159,
+    536537161, 536537171, 536537189, 536537191, 536537249, 536537263,
+    536537279, 536537293, 536537297, 536537317, 536537321, 536537329,
+    536537369, 536537377, 536537431, 536537437, 536537501, 536537539,
+    536537543, 536537549, 536537569, 536537581, 536537587, 536537591,
+    536537623, 536537633, 536537641, 536537653, 536537693, 536537717,
+    536537741, 536537773, 536537779, 536537803, 536537819, 536537831,
+    536537839, 536537843, 536537857, 536537861, 536537873, 536537887,
+    536537893, 536537927, 536537929, 536538007, 536538011, 536538053,
+    536538097, 536538109, 536538143, 536538157, 536538179, 536538199,
+    536538203, 536538253, 536538281, 536538293, 536538307, 536538313,
+    536538329, 536538347, 536538383, 536538407, 536538413, 536538419,
+    536538463, 536538469, 536538487, 536538521, 536538559, 536538589,
+    536538593, 536538601, 536538617, 536538623, 536538631, 536538637,
+    536538659, 536538703, 536538713, 536538757, 536538763, 536538781,
+    536538791, 536538799, 536538811, 536538823, 536538829, 536538839,
+    536538883, 536538911, 536538923, 536538931, 536539001, 536539013,
+    536539067, 536539111, 536539151, 536539163, 536539177, 536539181,
+    536539187, 536539207, 536539229, 536539231, 536539247, 536539249,
+    536539253, 536539273, 536539277, 536539291, 536539303, 536539321,
+    536539343, 536539349, 536539361, 536539369, 536539387, 536539427,
+    536539441, 536539447, 536539457, 536539459, 536539483, 536539513,
+    536539517, 536539519, 536539541, 536539543, 536539609, 536539657,
+    536539667, 536539709, 536539739, 536539741, 536539753, 536539763,
+    536539769, 536539777, 536539781, 536539799, 536539811, 536539831,
+    536539889, 536539903, 536539919, 536539937, 536539961, 536539963,
+    536539973, 536540003, 536540023, 536540029, 536540057, 536540099,
+    536540117, 536540129, 536540131, 536540143, 536540161, 536540167,
+    536540177, 536540189, 536540261, 536540267, 536540299, 536540317,
+    536540341, 536540351, 536540353, 536540371, 536540377, 536540399,
+    536540423, 536540447, 536540471, 536540533, 536540561, 536540603,
+    536540617, 536540633, 536540647, 536540651, 536540657, 536540701,
+    536540789, 536540857, 536540869, 536540887, 536540923, 536540929,
+    536540969, 536541017, 536541041, 536541043, 536541053, 536541067,
+    536541127, 536541179, 536541191, 536541227, 536541259, 536541277,
+    536541283, 536541287, 536541319, 536541353, 536541367, 536541409,
+    536541413, 536541443, 536541469, 536541479, 536541541, 536541553,
+    536541569, 536541587, 536541601, 536541623, 536541637, 536541647,
+    536541653, 536541667, 536541697, 536541713, 536541749, 536541757,
+    536541767, 536541821, 536541827, 536541833, 536541839, 536541857,
+    536541877, 536541881, 536541883, 536541899, 536541919, 536541923,
+    536541937, 536541961, 536542001, 536542051, 536542057, 536542087,
+    536542147, 536542169, 536542207, 536542301, 536542309, 536542339,
+    536542351, 536542379, 536542399, 536542403, 536542417, 536542453,
+    536542469, 536542511, 536542537, 536542549, 536542561, 536542571,
+    536542607, 536542613, 536542631, 536542639, 536542663, 536542681,
+    536542693, 536542711, 536542723, 536542733, 536542751, 536542757,
+    536542801, 536542807, 536542817, 536542829, 536542841, 536542861,
+    536542889, 536542907, 536542913, 536542921, 536542927, 536542931,
+    536542961, 536542999, 536543027, 536543041, 536543053, 536543087,
+    536543113, 536543143, 536543173, 536543191, 536543219, 536543233,
+    536543243, 536543309, 536543311, 536543321, 536543347, 536543363,
+    536543389, 536543393, 536543417, 536543419, 536543509, 536543597,
+    536543599, 536543621, 536543633, 536543669, 536543713, 536543743,
+    536543759, 536543773, 536543803, 536543807, 536543837, 536543873,
+    536543893, 536543897, 536543899, 536543927, 536544037, 536544079,
+    536544119, 536544133, 536544137, 536544143, 536544149, 536544209,
+    536544269, 536544271, 536544301, 536544343, 536544347, 536544383,
+    536544389, 536544419, 536544427, 536544431, 536544443, 536544451,
+    536544469, 536544473, 536544479, 536544521, 536544557, 536544571,
+    536544577, 536544601, 536544607, 536544611, 536544637, 536544641,
+    536544653, 536544661, 536544719, 536544721, 536544727, 536544751,
+    536544763, 536544779, 536544791, 536544793, 536544797, 536544839,
+    536544847, 536544859, 536544887, 536544889, 536544907, 536544919,
+    536544923, 536544929, 536544949, 536545001, 536545033, 536545043,
+    536545049, 536545057, 536545069, 536545151, 536545159, 536545171,
+    536545183, 536545213, 536545253, 536545267, 536545277, 536545291,
+    536545297, 536545309, 536545337, 536545349, 536545369, 536545411,
+    536545417, 536545439, 536545441, 536545463, 536545507, 536545531,
+    536545577, 536545601, 536545637, 536545649, 536545657, 536545661,
+    536545697, 536545727, 536545747, 536545753, 536545811, 536545831,
+    536545837, 536545853, 536545901, 536545903, 536545913, 536545927,
+    536545957, 536545973, 536545981, 536546009, 536546033, 536546039,
+    536546041, 536546051, 536546071, 536546089, 536546099, 536546141,
+    536546147, 536546159, 536546173, 536546183, 536546191, 536546207,
+    536546237, 536546249, 536546267, 536546273, 536546281, 536546327,
+    536546341, 536546347, 536546363, 536546393, 536546411, 536546443,
+    536546449, 536546477, 536546489, 536546497, 536546513, 536546551,
+    536546573, 536546627, 536546651, 536546671, 536546677, 536546701,
+    536546797, 536546827, 536546863, 536546891, 536546897, 536546903,
+    536546917, 536546963, 536546987, 536547017, 536547019, 536547043,
+    536547073, 536547097, 536547139, 536547191, 536547199, 536547203,
+    536547227, 536547257, 536547281, 536547283, 536547293, 536547307,
+    536547313, 536547329, 536547337, 536547371, 536547379, 536547383,
+    536547409, 536547419, 536547433, 536547437, 536547439, 536547467,
+    536547493, 536547511, 536547547, 536547551, 536547553, 536547569,
+    536547587, 536547601, 536547677, 536547691, 536547731, 536547733,
+    536547769, 536547793, 536547827, 536547839, 536547889, 536547901,
+    536547919, 536547929, 536547943, 536547953, 536547961, 536547967,
+    536547983, 536547997, 536548007, 536548039, 536548073, 536548079,
+    536548123, 536548153, 536548213, 536548231, 536548267, 536548273,
+    536548283, 536548289, 536548357, 536548379, 536548387, 536548399,
+    536548417, 536548477, 536548483, 536548501, 536548513, 536548549,
+    536548643, 536548681, 536548697, 536548699, 536548703, 536548751,
+    536548787, 536548801, 536548819, 536548823, 536548829, 536548843,
+    536548879, 536548889, 536548897, 536548907, 536548921, 536548963,
+    536548967, 536548993, 536548997, 536549011, 536549029, 536549033,
+    536549063, 536549077, 536549093, 536549159, 536549161, 536549171,
+    536549183, 536549191, 536549203, 536549207, 536549261, 536549281,
+    536549309, 536549311, 536549323, 536549353, 536549383, 536549401,
+    536549423, 536549441, 536549443, 536549491, 536549501, 536549527,
+    536549537, 536549539, 536549609, 536549621, 536549623, 536549633,
+    536549641, 536549653, 536549693, 536549701, 536549737, 536549747,
+    536549779, 536549789, 536549803, 536549807, 536549809, 536549813,
+    536549887, 536549917, 536549947, 536549989, 536550011, 536550013,
+    536550019, 536550041, 536550059, 536550089, 536550143, 536550151,
+    536550163, 536550191, 536550221, 536550247, 536550251, 536550281,
+    536550293, 536550299, 536550317, 536550319, 536550349, 536550361,
+    536550389, 536550397, 536550409, 536550437, 536550439, 536550451,
+    536550467, 536550503, 536550529, 536550533, 536550577, 536550613,
+    536550631, 536550691, 536550701, 536550733, 536550757, 536550799,
+    536550841, 536550851, 536550863, 536550871, 536550881, 536550901,
+    536550907, 536550913, 536550967, 536550977, 536550983, 536551019,
+    536551021, 536551027, 536551031, 536551039, 536551049, 536551079,
+    536551109, 536551117, 536551121, 536551123, 536551129, 536551139,
+    536551177, 536551187, 536551271, 536551273, 536551333, 536551349,
+    536551373, 536551381, 536551391, 536551397, 536551403, 536551409,
+    536551423, 536551439, 536551481, 536551511, 536551559, 536551571,
+    536551573, 536551579, 536551643, 536551657, 536551667, 536551681,
+    536551699, 536551727, 536551733, 536551747, 536551777, 536551781,
+    536551783, 536551787, 536551793, 536551801, 536551819, 536551861,
+    536551867, 536551901, 536551903, 536551919, 536551931, 536551987,
+    536551991, 536552017, 536552033, 536552099, 536552161, 536552179,
+    536552197, 536552201, 536552221, 536552227, 536552239, 536552243,
+    536552293, 536552333, 536552339, 536552347, 536552353, 536552399,
+    536552411, 536552413, 536552447, 536552449, 536552477, 536552491,
+    536552507, 536552531, 536552537, 536552543, 536552593, 536552603,
+    536552663, 536552669, 536552707, 536552713, 536552741, 536552749,
+    536552777, 536552791, 536552801, 536552833, 536552851, 536552959,
+    536552969, 536552977, 536552999, 536553007, 536553013, 536553067,
+    536553071, 536553089, 536553109, 536553113, 536553119, 536553161,
+    536553163, 536553181, 536553203, 536553211, 536553221, 536553233,
+    536553253, 536553271, 536553289, 536553307, 536553341, 536553349,
+    536553359, 536553419, 536553421, 536553497, 536553547, 536553553,
+    536553557, 536553617, 536553649, 536553659, 536553671, 536553691,
+    536553727, 536553733, 536553763, 536553767, 536553781, 536553793,
+    536553803, 536553811, 536553841, 536553893, 536553907, 536553923,
+    536553929, 536553931, 536553947, 536553967, 536553971, 536553989,
+    536553991, 536554009, 536554013, 536554037, 536554079, 536554093,
+    536554121, 536554127, 536554147, 536554177, 536554181, 536554217,
+    536554219, 536554229, 536554237, 536554267, 536554297, 536554309,
+    536554321, 536554339, 536554349, 536554393, 536554399, 536554429,
+    536554463, 536554477, 536554481, 536554507, 536554537, 536554573,
+    536554583, 536554619, 536554637, 536554639, 536554651, 536554687,
+    536554721, 536554729, 536554757, 536554769, 536554783, 536554831,
+    536554853, 536554877, 536554933, 536554937, 536554951, 536554999,
+    536555009, 536555021, 536555039, 536555053, 536555057, 536555111,
+    536555137, 536555147, 536555177, 536555179, 536555191, 536555197,
+    536555213, 536555237, 536555251, 536555287, 536555291, 536555311,
+    536555317, 536555323, 536555353, 536555359, 536555399, 536555401,
+    536555417, 536555441, 536555483, 536555489, 536555491, 536555599,
+    536555603, 536555609, 536555627, 536555639, 536555647, 536555671,
+    536555681, 536555689, 536555711, 536555749, 536555797, 536555837,
+    536555917, 536555947, 536555951, 536555963, 536555977, 536556011,
+    536556103, 536556127, 536556133, 536556191, 536556197, 536556221,
+    536556233, 536556247, 536556269, 536556287, 536556313, 536556343,
+    536556359, 536556367, 536556379, 536556403, 536556413, 536556457,
+    536556467, 536556469, 536556473, 536556491, 536556511, 536556563,
+    536556589, 536556593, 536556607, 536556611, 536556613, 536556659,
+    536556667, 536556689, 536556697, 536556739, 536556803, 536556817,
+    536556829, 536556859, 536556863, 536556871, 536556887, 536556893,
+    536556899, 536556929, 536556931, 536556953, 536556983, 536556989,
+    536556991, 536557003, 536557039, 536557057, 536557067, 536557117,
+    536557163, 536557181, 536557183, 536557193, 536557199, 536557211,
+    536557253, 536557279, 536557291, 536557297, 536557309, 536557361,
+    536557367, 536557379, 536557423, 536557459, 536557471, 536557487,
+    536557523, 536557577, 536557627, 536557633, 536557643, 536557657,
+    536557669, 536557673, 536557699, 536557711, 536557727, 536557783,
+    536557799, 536557817, 536557829, 536557837, 536557843, 536557871,
+    536557877, 536557919, 536557921, 536557933, 536557963, 536557991,
+    536557993, 536557997, 536558017, 536558069, 536558083, 536558101,
+    536558111, 536558123, 536558153, 536558161, 536558179, 536558207,
+    536558263, 536558279, 536558291, 536558299, 536558339, 536558353,
+    536558357, 536558383, 536558401, 536558419, 536558453, 536558489,
+    536558521, 536558543, 536558557, 536558569, 536558593, 536558629,
+    536558639, 536558683, 536558707, 536558723, 536558741, 536558747,
+    536558767, 536558779, 536558791, 536558801, 536558807, 536558821,
+    536558837, 536558843, 536558851, 536558903, 536558929, 536558933,
+    536558951, 536558959, 536558963, 536559029, 536559047, 536559053,
+    536559077, 536559091, 536559109, 536559119, 536559173, 536559193,
+    536559197, 536559217, 536559223, 536559229, 536559269, 536559299,
+    536559307, 536559313, 536559319, 536559337, 536559343, 536559347,
+    536559403, 536559407, 536559431, 536559467, 536559469, 536559523,
+    536559539, 536559553, 536559577, 536559613, 536559619, 536559643,
+    536559689, 536559691, 536559731, 536559761, 536559799, 536559809,
+    536559823, 536559833, 536559841, 536559853, 536559889, 536559913,
+    536559917, 536559923, 536559941, 536560009, 536560027, 536560049,
+    536560061, 536560099, 536560111, 536560139, 536560151, 536560159,
+    536560249, 536560259, 536560267, 536560301, 536560313, 536560327,
+    536560373, 536560417, 536560463, 536560483, 536560487, 536560543,
+    536560571, 536560597, 536560603, 536560621, 536560631, 536560667,
+    536560669, 536560693, 536560709, 536560729, 536560733, 536560747,
+    536560753, 536560763, 536560777, 536560799, 536560807, 536560831,
+    536560861, 536560889, 536560901, 536560909, 536560933, 536560963,
+    536560967, 536561027, 536561101, 536561107, 536561141, 536561167,
+    536561203, 536561209, 536561213, 536561257, 536561297, 536561303,
+    536561323, 536561341, 536561357, 536561371, 536561401, 536561407,
+    536561449, 536561471, 536561477, 536561479, 536561483, 536561579,
+    536561581, 536561617, 536561639, 536561651, 536561681, 536561689,
+    536561699, 536561719, 536561747, 536561789, 536561791, 536561801,
+    536561807, 536561819, 536561821, 536561833, 536561849, 536561867,
+    536561897, 536561941, 536561959, 536562029, 536562067, 536562119,
+    536562137, 536562139, 536562151, 536562157, 536562163, 536562179,
+    536562181, 536562217, 536562227, 536562251, 536562277, 536562289,
+    536562311, 536562319, 536562371, 536562401, 536562421, 536562457,
+    536562463, 536562473, 536562491, 536562497, 536562503, 536562529,
+    536562541, 536562563, 536562569, 536562673, 536562683, 536562709,
+    536562737, 536562749, 536562773, 536562781, 536562797, 536562809,
+    536562811, 536562827, 536562841, 536562853, 536562877, 536562899,
+    536562931, 536562979, 536562991, 536562997, 536563003, 536563009,
+    536563033, 536563057, 536563063, 536563081, 536563087, 536563091,
+    536563109, 536563141, 536563147, 536563193, 536563201, 536563217,
+    536563219, 536563229, 536563253, 536563273, 536563303, 536563309,
+    536563319, 536563387, 536563397, 536563399, 536563427, 536563441,
+    536563471, 536563483, 536563487, 536563493, 536563549, 536563583,
+    536563613, 536563627, 536563631, 536563637, 536563691, 536563721,
+    536563789, 536563801, 536563861, 536563873, 536563879, 536563901,
+    536563931, 536563957, 536563961, 536563999, 536564023, 536564029,
+    536564051, 536564059, 536564069, 536564107, 536564141, 536564167,
+    536564219, 536564243, 536564279, 536564311, 536564317, 536564333,
+    536564339, 536564377, 536564411, 536564423, 536564437, 536564443,
+    536564471, 536564477, 536564513, 536564533, 536564543, 536564551,
+    536564573, 536564593, 536564597, 536564627, 536564653, 536564657,
+    536564669, 536564671, 536564683, 536564711, 536564753, 536564779,
+    536564803, 536564813, 536564837, 536564849, 536564869, 536564923,
+    536564933, 536564947, 536564969, 536564971, 536564993, 536565013,
+    536565017, 536565041, 536565053, 536565097, 536565131, 536565167,
+    536565173, 536565179, 536565191, 536565199, 536565251, 536565299,
+    536565311, 536565313, 536565347, 536565353, 536565397, 536565409,
+    536565431, 536565433, 536565451, 536565457, 536565467, 536565473,
+    536565479, 536565487, 536565503, 536565521, 536565553, 536565559,
+    536565563, 536565581, 536565593, 536565599, 536565619, 536565649,
+    536565661, 536565683, 536565691, 536565727, 536565761, 536565767,
+    536565769, 536565773, 536565779, 536565793, 536565803, 536565817,
+    536565829, 536565851, 536565853, 536565857, 536565863, 536565899,
+    536565937, 536565941, 536565989, 536566003, 536566013, 536566039,
+    536566109, 536566153, 536566181, 536566201, 536566229, 536566231,
+    536566249, 536566253, 536566301, 536566307, 536566319, 536566397,
+    536566453, 536566463, 536566477, 536566501, 536566543, 536566577,
+    536566579, 536566603, 536566627, 536566633, 536566643, 536566651,
+    536566663, 536566673, 536566739, 536566757, 536566763, 536566799,
+    536566813, 536566819, 536566831, 536566847, 536566871, 536566889,
+    536566907, 536566949, 536566957, 536566969, 536566981, 536566991,
+    536567033, 536567047, 536567051, 536567089, 536567099, 536567111,
+    536567113, 536567117, 536567137, 536567147, 536567153, 536567173,
+    536567179, 536567183, 536567191, 536567257, 536567261, 536567281,
+    536567329, 536567333, 536567351, 536567363, 536567371, 536567393,
+    536567401, 536567419, 536567453, 536567489, 536567497, 536567501,
+    536567513, 536567567, 536567573, 536567597, 536567627, 536567663,
+    536567687, 536567699, 536567701, 536567737, 536567741, 536567749,
+    536567783, 536567789, 536567791, 536567807, 536567833, 536567849,
+    536567873, 536567887, 536567893, 536567953, 536567987, 536568023,
+    536568029, 536568041, 536568077, 536568167, 536568169, 536568203,
+    536568209, 536568211, 536568223, 536568239, 536568247, 536568251,
+    536568281, 536568287, 536568293, 536568301, 536568359, 536568377,
+    536568407, 536568419, 536568421, 536568443, 536568457, 536568463,
+    536568481, 536568521, 536568547, 536568559, 536568563, 536568581,
+    536568589, 536568601, 536568631, 536568649, 536568653, 536568691,
+    536568713, 536568719, 536568731, 536568737, 536568751, 536568803,
+    536568811, 536568827, 536568847, 536568853, 536568883, 536568887,
+    536568899, 536568913, 536568917, 536568937, 536568947, 536568961,
+    536568971, 536569013, 536569037, 536569039, 536569109, 536569123,
+    536569133, 536569141, 536569157, 536569217, 536569247, 536569261,
+    536569273, 536569279, 536569331, 536569349, 536569357, 536569373,
+    536569391, 536569399, 536569417, 536569441, 536569459, 536569463,
+    536569489, 536569493, 536569499, 536569543, 536569547, 536569559,
+    536569577, 536569601, 536569619, 536569639, 536569651, 536569667,
+    536569673, 536569681, 536569729, 536569739, 536569753, 536569771,
+    536569799, 536569801, 536569811, 536569837, 536569853, 536569877,
+    536569879, 536569883, 536569897, 536569909, 536569931, 536569949,
+    536569987, 536570063, 536570071, 536570077, 536570087, 536570107,
+    536570117, 536570119, 536570137, 536570141, 536570149, 536570159,
+    536570161, 536570173, 536570261, 536570273, 536570299, 536570311,
+    536570327, 536570401, 536570417, 536570429, 536570453, 536570467,
+    536570509, 536570521, 536570527, 536570539, 536570561, 536570563,
+    536570581, 536570591, 536570597, 536570623, 536570663, 536570689,
+    536570717, 536570747, 536570777, 536570791, 536570821, 536570831,
+    536570857, 536570861, 536570869, 536570873, 536570897, 536570917,
+    536570939, 536570953, 536570959, 536570987, 536570989, 536571011,
+    536571019, 536571029, 536571031, 536571037, 536571047, 536571053,
+    536571089, 536571107, 536571109, 536571131, 536571149, 536571169,
+    536571173, 536571197, 536571247, 536571257, 536571263, 536571293,
+    536571307, 536571319, 536571367, 536571379, 536571401, 536571449,
+    536571463, 536571479, 536571487, 536571517, 536571559, 536571589,
+    536571593, 536571619, 536571667, 536571689, 536571703, 536571719,
+    536571733, 536571757, 536571767, 536571769, 536571803, 536571821,
+    536571823, 536571829, 536571857, 536571877, 536571883, 536571887,
+    536571923, 536571953, 536571977, 536572061, 536572067, 536572081,
+    536572111, 536572117, 536572193, 536572219, 536572237, 536572243,
+    536572271, 536572303, 536572307, 536572321, 536572327, 536572363,
+    536572433, 536572469, 536572523, 536572571, 536572573, 536572577,
+    536572601, 536572613, 536572627, 536572637, 536572651, 536572709,
+    536572741, 536572747, 536572753, 536572759, 536572843, 536572847,
+    536572867, 536572879, 536572909, 536572937, 536572973, 536572979,
+    536573029, 536573047, 536573069, 536573071, 536573087, 536573111,
+    536573119, 536573131, 536573161, 536573173, 536573183, 536573201,
+    536573207, 536573209, 536573231, 536573237, 536573239, 536573267,
+    536573299, 536573309, 536573311, 536573321, 536573339, 536573347,
+    536573351, 536573353, 536573383, 536573413, 536573423, 536573441,
+    536573447, 536573461, 536573489, 536573497, 536573501, 536573539,
+    536573551, 536573563, 536573591, 536573599, 536573627, 536573641,
+    536573657, 536573663, 536573677, 536573701, 536573717, 536573743,
+    536573783, 536573809, 536573867, 536573879, 536573893, 536573911,
+    536574019, 536574091, 536574113, 536574131, 536574149, 536574169,
+    536574187, 536574287, 536574323, 536574343, 536574377, 536574403,
+    536574413, 536574461, 536574523, 536574583, 536574589, 536574637,
+    536574641, 536574653, 536574673, 536574677, 536574679, 536574707,
+    536574739, 536574781, 536574799, 536574811, 536574817, 536574823,
+    536574833, 536574847, 536574853, 536574881, 536574887, 536574911,
+    536574917, 536574949, 536574979, 536574989, 536575003, 536575009,
+    536575019, 536575049, 536575057, 536575079, 536575103, 536575129,
+    536575153, 536575157, 536575177, 536575183, 536575201, 536575217,
+    536575229, 536575357, 536575363, 536575379, 536575397, 536575399,
+    536575411, 536575421, 536575423, 536575483, 536575489, 536575519,
+    536575531, 536575541, 536575549, 536575553, 536575577, 536575583,
+    536575601, 536575639, 536575643, 536575649, 536575667, 536575673,
+    536575681, 536575691, 536575747, 536575841, 536575847, 536575877,
+    536575909, 536575939, 536575943, 536575997, 536576021, 536576023,
+    536576041, 536576057, 536576063, 536576071, 536576077, 536576087,
+    536576101, 536576107, 536576141, 536576203, 536576251, 536576263,
+    536576273, 536576297, 536576311, 536576329, 536576333, 536576363,
+    536576377, 536576419, 536576429, 536576441, 536576483, 536576497,
+    536576501, 536576527, 536576533, 536576561, 536576563, 536576569,
+    536576597, 536576609, 536576629, 536576693, 536576713, 536576723,
+    536576731, 536576767, 536576779, 536576783, 536576809, 536576827,
+    536576851, 536576893, 536576921, 536576939, 536576947, 536576993,
+    536577011, 536577017, 536577029, 536577037, 536577049, 536577061,
+    536577079, 536577089, 536577163, 536577187, 536577191, 536577199,
+    536577221, 536577277, 536577299, 536577323, 536577389, 536577397,
+    536577403, 536577407, 536577421, 536577463, 536577491, 536577493,
+    536577527, 536577553, 536577563, 536577593, 536577599, 536577659,
+    536577697, 536577733, 536577761, 536577763, 536577773, 536577781,
+    536577793, 536577799, 536577809, 536577823, 536577827, 536577857,
+    536577869, 536577871, 536577893, 536577913, 536577931, 536577949,
+    536577983, 536578013, 536578067, 536578087, 536578099, 536578153,
+    536578171, 536578177, 536578199, 536578243, 536578261, 536578267,
+    536578279, 536578283, 536578291, 536578303, 536578309, 536578313,
+    536578319, 536578321, 536578337, 536578351, 536578379, 536578409,
+    536578417, 536578423, 536578457, 536578459, 536578481, 536578517,
+    536578541, 536578577, 536578607, 536578621, 536578643, 536578657,
+    536578673, 536578681, 536578711, 536578727, 536578733, 536578739,
+    536578747, 536578759, 536578789, 536578807, 536578853, 536578859,
+    536578919, 536578927, 536578979, 536578993, 536579027, 536579033,
+    536579047, 536579063, 536579077, 536579123, 536579149, 536579159,
+    536579161, 536579203, 536579227, 536579231, 536579237, 536579293,
+    536579311, 536579317, 536579321, 536579339, 536579357, 536579389,
+    536579429, 536579441, 536579509, 536579573, 536579599, 536579611,
+    536579647, 536579677, 536579707, 536579717, 536579723, 536579759,
+    536579761, 536579773, 536579783, 536579801, 536579831, 536579881,
+    536579941, 536579947, 536579971, 536580001, 536580029, 536580047,
+    536580049, 536580073, 536580089, 536580113, 536580119, 536580131,
+    536580167, 536580173, 536580193, 536580203, 536580221, 536580229,
+    536580257, 536580259, 536580263, 536580281, 536580307, 536580329,
+    536580347, 536580371, 536580413, 536580437, 536580467, 536580479,
+    536580553, 536580559, 536580589, 536580599, 536580601, 536580637,
+    536580647, 536580661, 536580679, 536580683, 536580739, 536580743,
+    536580749, 536580761, 536580763, 536580773, 536580787, 536580799,
+    536580859, 536580871, 536580883, 536580887, 536580943, 536580977,
+    536580991, 536581043, 536581057, 536581079, 536581103, 536581117,
+    536581159, 536581163, 536581181, 536581207, 536581231, 536581271,
+    536581273, 536581307, 536581313, 536581321, 536581327, 536581361,
+    536581379, 536581393, 536581417, 536581429, 536581447, 536581453,
+    536581501, 536581537, 536581553, 536581607, 536581613, 536581663,
+    536581691, 536581723, 536581729, 536581763, 536581769, 536581777,
+    536581823, 536581841, 536581849, 536581873, 536581879, 536581889,
+    536581891, 536581909, 536581933, 536581937, 536581943, 536581961,
+    536582077, 536582089, 536582093, 536582113, 536582119, 536582143,
+    536582153, 536582159, 536582191, 536582231, 536582261, 536582279,
+    536582281, 536582359, 536582381, 536582411, 536582443, 536582461,
+    536582483, 536582489, 536582491, 536582531, 536582561, 536582567,
+    536582569, 536582587, 536582593, 536582609, 536582623, 536582677,
+    536582701, 536582719, 536582749, 536582789, 536582791, 536582861,
+    536582899, 536582927, 536582941, 536582947, 536582957, 536582983,
+    536582987, 536582989, 536583011, 536583013, 536583029, 536583037,
+    536583043, 536583049, 536583059, 536583079, 536583097, 536583119,
+    536583127, 536583133, 536583149, 536583193, 536583221, 536583227,
+    536583239, 536583251, 536583263, 536583293, 536583319, 536583323,
+    536583331, 536583337, 536583391, 536583409, 536583413, 536583457,
+    536583497, 536583517, 536583569, 536583571, 536583589, 536583599,
+    536583613, 536583647, 536583659, 536583667, 536583703, 536583739,
+    536583757, 536583779, 536583787, 536583793, 536583809, 536583823,
+    536583829, 536583841, 536583857, 536583871, 536583881, 536583889,
+    536583911, 536583917, 536583941, 536583947, 536583967, 536583973,
+    536583977, 536583979, 536584019, 536584051, 536584067, 536584159,
+    536584163, 536584171, 536584199, 536584207, 536584211, 536584231,
+    536584241, 536584259, 536584297, 536584333, 536584337, 536584369,
+    536584381, 536584387, 536584421, 536584423, 536584439, 536584493,
+    536584519, 536584523, 536584547, 536584553, 536584579, 536584613,
+    536584627, 536584661, 536584679, 536584717, 536584729, 536584751,
+    536584771, 536584781, 536584793, 536584823, 536584849, 536584877,
+    536584913, 536584933, 536584973, 536584987, 536585011, 536585029,
+    536585047, 536585069, 536585167, 536585171, 536585177, 536585201,
+    536585209, 536585221, 536585233, 536585267, 536585311, 536585317,
+    536585333, 536585339, 536585351, 536585369, 536585383, 536585389,
+    536585407, 536585447, 536585531, 536585537, 536585591, 536585611,
+    536585639, 536585641, 536585657, 536585663, 536585677, 536585689,
+    536585711, 536585713, 536585723, 536585743, 536585747, 536585759,
+    536585771, 536585779, 536585801, 536585849, 536585857, 536585873,
+    536585893, 536585921, 536585923, 536585941, 536585947, 536585957,
+    536585999, 536586007, 536586023, 536586031, 536586077, 536586097,
+    536586107, 536586109, 536586139, 536586143, 536586191, 536586203,
+    536586221, 536586301, 536586313, 536586329, 536586359, 536586361,
+    536586367, 536586371, 536586373, 536586377, 536586403, 536586473,
+    536586529, 536586541, 536586553, 536586559, 536586563, 536586569,
+    536586601, 536586653, 536586707, 536586731, 536586737, 536586763,
+    536586767, 536586779, 536586821, 536586829, 536586857, 536586863,
+    536586877, 536586977, 536586991, 536587001, 536587003, 536587013,
+    536587021, 536587069, 536587081, 536587111, 536587169, 536587193,
+    536587229, 536587231, 536587237, 536587243, 536587279, 536587301,
+    536587307, 536587313, 536587349, 536587369, 536587421, 536587433,
+    536587483, 536587487, 536587501, 536587511, 536587547, 536587553,
+    536587561, 536587567, 536587577, 536587589, 536587663, 536587679,
+    536587691, 536587697, 536587703, 536587739, 536587747, 536587771,
+    536587789, 536587817, 536587819, 536587837, 536587871, 536587879,
+    536587937, 536587963, 536587969, 536588011, 536588029, 536588069,
+    536588089, 536588149, 536588191, 536588203, 536588219, 536588249,
+    536588263, 536588267, 536588281, 536588293, 536588317, 536588341,
+    536588347, 536588369, 536588407, 536588441, 536588453, 536588489,
+    536588509, 536588567, 536588573, 536588627, 536588681, 536588683,
+    536588693, 536588719, 536588807, 536588809, 536588813, 536588821,
+    536588839, 536588849, 536588881, 536588887, 536588891, 536588929,
+    536588933, 536588939, 536588947, 536588971, 536588977, 536588993,
+    536588999, 536589019, 536589023, 536589041, 536589047, 536589049,
+    536589061, 536589073, 536589077, 536589113, 536589143, 536589187,
+    536589197, 536589211, 536589259, 536589269, 536589289, 536589307,
+    536589311, 536589329, 536589373, 536589401, 536589413, 536589421,
+    536589461, 536589463, 536589491, 536589497, 536589527, 536589539,
+    536589541, 536589551, 536589589, 536589593, 536589607, 536589617,
+    536589619, 536589629, 536589631, 536589707, 536589731, 536589737,
+    536589743, 536589787, 536589797, 536589817, 536589829, 536589847,
+    536589863, 536589869, 536589917, 536589923, 536589961, 536589971,
+    536589973, 536590007, 536590049, 536590051, 536590063, 536590079,
+    536590081, 536590123, 536590147, 536590189, 536590213, 536590217,
+    536590231, 536590283, 536590297, 536590319, 536590321, 536590349,
+    536590423, 536590433, 536590447, 536590463, 536590489, 536590547,
+    536590553, 536590559, 536590577, 536590583, 536590589, 536590591,
+    536590619, 536590633, 536590643, 536590693, 536590699, 536590721,
+    536590751, 536590753, 536590763, 536590787, 536590793, 536590829,
+    536590841, 536590849, 536590861, 536590867, 536590883, 536590927,
+    536590931, 536590979, 536590987, 536591021, 536591039, 536591047,
+    536591053, 536591087, 536591189, 536591191, 536591221, 536591227,
+    536591243, 536591249, 536591257, 536591261, 536591267, 536591269,
+    536591299, 536591309, 536591317, 536591323, 536591347, 536591351,
+    536591387, 536591399, 536591401, 536591423, 536591479, 536591509,
+    536591533, 536591579, 536591593, 536591609, 536591647, 536591651,
+    536591707, 536591729, 536591773, 536591813, 536591819, 536591827,
+    536591879, 536591933, 536591941, 536591953, 536591963, 536592013,
+    536592031, 536592071, 536592103, 536592107, 536592149, 536592179,
+    536592181, 536592187, 536592211, 536592223, 536592239, 536592257,
+    536592269, 536592271, 536592283, 536592293, 536592317, 536592337,
+    536592341, 536592401, 536592431, 536592439, 536592443, 536592449,
+    536592451, 536592487, 536592493, 536592521, 536592527, 536592541,
+    536592587, 536592601, 536592629, 536592647, 536592649, 536592673,
+    536592677, 536592697, 536592703, 536592731, 536592739, 536592751,
+    536592757, 536592767, 536592779, 536592799, 536592809, 536592821,
+    536592839, 536592863, 536592893, 536592911, 536592923, 536592941,
+    536592949, 536592971, 536592989, 536593019, 536593033, 536593051,
+    536593063, 536593069, 536593093, 536593121, 536593139, 536593171,
+    536593217, 536593223, 536593241, 536593249, 536593283, 536593297,
+    536593301, 536593303, 536593319, 536593333, 536593349, 536593403,
+    536593411, 536593429, 536593441, 536593451, 536593469, 536593481,
+    536593483, 536593493, 536593579, 536593591, 536593619, 536593643,
+    536593667, 536593679, 536593693, 536593711, 536593777, 536593781,
+    536593807, 536593817, 536593819, 536593823, 536593843, 536593859,
+    536593891, 536593901, 536593907, 536593909, 536593913, 536593949,
+    536593961, 536593963, 536593969, 536593987, 536593997, 536593999,
+    536594027, 536594057, 536594077, 536594099, 536594111, 536594153,
+    536594189, 536594243, 536594249, 536594251, 536594263, 536594269,
+    536594281, 536594287, 536594293, 536594297, 536594299, 536594309,
+    536594323, 536594327, 536594381, 536594389, 536594423, 536594437,
+    536594467, 536594473, 536594479, 536594483, 536594501, 536594521,
+    536594537, 536594563, 536594567, 536594659, 536594687, 536594689,
+    536594693, 536594699, 536594711, 536594731, 536594741, 536594753,
+    536594771, 536594777, 536594797, 536594803, 536594819, 536594833,
+    536594879, 536594909, 536594951, 536594957, 536594963, 536594983,
+    536595011, 536595019, 536595043, 536595061, 536595109, 536595121,
+    536595139, 536595179, 536595181, 536595203, 536595247, 536595251,
+    536595253, 536595271, 536595299, 536595307, 536595347, 536595377,
+    536595379, 536595403, 536595421, 536595443, 536595457, 536595469,
+    536595503, 536595517, 536595533, 536595541, 536595557, 536595623,
+    536595707, 536595713, 536595721, 536595743, 536595767, 536595791,
+    536595799, 536595809, 536595811, 536595817, 536595841, 536595877,
+    536595893, 536595923, 536595937, 536595953, 536596031, 536596033,
+    536596051, 536596057, 536596111, 536596117, 536596127, 536596129,
+    536596169, 536596189, 536596201, 536596231, 536596241, 536596253,
+    536596261, 536596273, 536596297, 536596301, 536596303, 536596339,
+    536596343, 536596369, 536596373, 536596387, 536596399, 536596409,
+    536596429, 536596439, 536596457, 536596471, 536596481, 536596493,
+    536596507, 536596513, 536596579, 536596589, 536596591, 536596637,
+    536596661, 536596703, 536596777, 536596783, 536596787, 536596811,
+    536596813, 536596817, 536596847, 536596867, 536596883, 536596927,
+    536596943, 536596967, 536596981, 536597021, 536597029, 536597057,
+    536597077, 536597093, 536597099, 536597101, 536597123, 536597137,
+    536597207, 536597209, 536597249, 536597293, 536597311, 536597323,
+    536597329, 536597357, 536597359, 536597363, 536597393, 536597417,
+    536597437, 536597491, 536597533, 536597561, 536597587, 536597591,
+    536597603, 536597641, 536597657, 536597683, 536597689, 536597767,
+    536597773, 536597777, 536597801, 536597807, 536597813, 536597819,
+    536597833, 536597837, 536597839, 536597851, 536597857, 536597863,
+    536597891, 536597927, 536597947, 536597969, 536597993, 536598001,
+    536598011, 536598059, 536598061, 536598077, 536598089, 536598103,
+    536598137, 536598143, 536598163, 536598169, 536598187, 536598193,
+    536598197, 536598199, 536598229, 536598233, 536598287, 536598299,
+    536598317, 536598329, 536598331, 536598343, 536598347, 536598367,
+    536598373, 536598409, 536598427, 536598431, 536598481, 536598493,
+    536598497, 536598509, 536598527, 536598541, 536598613, 536598619,
+    536598641, 536598661, 536598707, 536598709, 536598719, 536598721,
+    536598739, 536598743, 536598757, 536598773, 536598793, 536598841,
+    536598877, 536598899, 536598911, 536598917, 536598941, 536598967,
+    536598971, 536598973, 536598991, 536599013, 536599051, 536599061,
+    536599069, 536599073, 536599109, 536599157, 536599201, 536599289,
+    536599309, 536599313, 536599319, 536599331, 536599337, 536599351,
+    536599369, 536599379, 536599381, 536599397, 536599403, 536599417,
+    536599439, 536599471, 536599477, 536599487, 536599519, 536599523,
+    536599549, 536599559, 536599561, 536599571, 536599579, 536599603,
+    536599607, 536599627, 536599639, 536599643, 536599667, 536599669,
+    536599703, 536599727, 536599733, 536599751, 536599831, 536599871,
+    536599927, 536599939, 536599961, 536599969, 536599991, 536599997,
+    536600017, 536600039, 536600089, 536600101, 536600123, 536600161,
+    536600167, 536600177, 536600201, 536600209, 536600243, 536600377,
+    536600423, 536600429, 536600431, 536600437, 536600447, 536600459,
+    536600473, 536600479, 536600503, 536600539, 536600573, 536600611,
+    536600621, 536600633, 536600653, 536600681, 536600689, 536600737,
+    536600749, 536600761, 536600797, 536600803, 536600807, 536600821,
+    536600839, 536600843, 536600849, 536600863, 536600941, 536600951,
+    536600959, 536600963, 536600969, 536601029, 536601049, 536601067,
+    536601113, 536601119, 536601133, 536601161, 536601217, 536601313,
+    536601341, 536601347, 536601361, 536601383, 536601407, 536601419,
+    536601421, 536601427, 536601449, 536601467, 536601473, 536601479,
+    536601487, 536601497, 536601503, 536601509, 536601511, 536601547,
+    536601551, 536601607, 536601613, 536601623, 536601641, 536601649,
+    536601671, 536601673, 536601701, 536601739, 536601817, 536601827,
+    536601833, 536601851, 536601853, 536601869, 536601887, 536601893,
+    536601911, 536601917, 536601929, 536601977, 536601997, 536602019,
+    536602021, 536602037, 536602039, 536602043, 536602057, 536602091,
+    536602141, 536602153, 536602159, 536602169, 536602201, 536602247,
+    536602277, 536602291, 536602303, 536602307, 536602321, 536602373,
+    536602393, 536602403, 536602439, 536602459, 536602481, 536602511,
+    536602513, 536602567, 536602621, 536602667, 536602669, 536602691,
+    536602709, 536602721, 536602757, 536602771, 536602819, 536602853,
+    536602873, 536602879, 536602907, 536602919, 536602931, 536602951,
+    536602973, 536602991, 536602993, 536602999, 536603003, 536603027,
+    536603029, 536603047, 536603057, 536603059, 536603069, 536603077,
+    536603099, 536603101, 536603167, 536603191, 536603209, 536603219,
+    536603233, 536603237, 536603251, 536603311, 536603329, 536603387,
+    536603393, 536603399, 536603401, 536603411, 536603413, 536603437,
+    536603461, 536603467, 536603479, 536603503, 536603527, 536603533,
+    536603537, 536603581, 536603633, 536603647, 536603677, 536603687,
+    536603701, 536603723, 536603773, 536603779, 536603797, 536603807,
+    536603813, 536603819, 536603857, 536603867, 536603887, 536603917,
+    536603989, 536603993, 536604001, 536604041, 536604043, 536604059,
+    536604071, 536604091, 536604109, 536604113, 536604149, 536604161,
+    536604193, 536604199, 536604209, 536604223, 536604227, 536604241,
+    536604253, 536604287, 536604301, 536604317, 536604323, 536604347,
+    536604361, 536604391, 536604401, 536604413, 536604437, 536604443,
+    536604449, 536604463, 536604511, 536604521, 536604529, 536604533,
+    536604583, 536604613, 536604641, 536604647, 536604659, 536604667,
+    536604683, 536604721, 536604737, 536604767, 536604769, 536604773,
+    536604791, 536604811, 536604829, 536604833, 536604841, 536604851,
+    536604857, 536604863, 536604889, 536604911, 536604917, 536604919,
+    536604923, 536604961, 536604997, 536605001, 536605031, 536605079,
+    536605093, 536605129, 536605169, 536605207, 536605259, 536605301,
+    536605313, 536605327, 536605331, 536605343, 536605351, 536605379,
+    536605393, 536605403, 536605409, 536605411, 536605423, 536605453,
+    536605477, 536605481, 536605501, 536605547, 536605577, 536605579,
+    536605591, 536605609, 536605631, 536605673, 536605679, 536605681,
+    536605687, 536605711, 536605723, 536605759, 536605777, 536605787,
+    536605789, 536605793, 536605807, 536605819, 536605889, 536605891,
+    536605913, 536605919, 536605957, 536605967, 536606011, 536606017,
+    536606023, 536606041, 536606089, 536606107, 536606131, 536606141,
+    536606167, 536606197, 536606209, 536606251, 536606267, 536606297,
+    536606347, 536606359, 536606381, 536606407, 536606423, 536606431,
+    536606437, 536606443, 536606507, 536606519, 536606533, 536606561,
+    536606563, 536606579, 536606591, 536606611, 536606627, 536606639,
+    536606641, 536606677, 536606701, 536606713, 536606723, 536606731,
+    536606747, 536606779, 536606783, 536606801, 536606803, 536606827,
+    536606831, 536606843, 536606881, 536606897, 536606909, 536606969,
+    536606977, 536607011, 536607017, 536607059, 536607061, 536607067,
+    536607079, 536607107, 536607119, 536607157, 536607163, 536607167,
+    536607173, 536607187, 536607199, 536607283, 536607287, 536607299,
+    536607307, 536607311, 536607347, 536607361, 536607377, 536607391,
+    536607403, 536607439, 536607469, 536607473, 536607493, 536607497,
+    536607509, 536607527, 536607541, 536607553, 536607581, 536607583,
+    536607607, 536607637, 536607661, 536607683, 536607689, 536607727,
+    536607739, 536607761, 536607769, 536607791, 536607803, 536607809,
+    536607817, 536607901, 536607931, 536607943, 536607947, 536607983,
+    536608021, 536608057, 536608069, 536608157, 536608183, 536608207,
+    536608231, 536608243, 536608271, 536608283, 536608291, 536608301,
+    536608321, 536608333, 536608337, 536608343, 536608367, 536608379,
+    536608381, 536608421, 536608433, 536608439, 536608441, 536608453,
+    536608483, 536608487, 536608493, 536608511, 536608571, 536608603,
+    536608609, 536608613, 536608649, 536608651, 536608687, 536608711,
+    536608727, 536608733, 536608763, 536608769, 536608783, 536608801,
+    536608819, 536608847, 536608871, 536608889, 536608907, 536608931,
+    536608957, 536608973, 536608979, 536608987, 536608999, 536609023,
+    536609053, 536609093, 536609111, 536609149, 536609167, 536609197,
+    536609209, 536609237, 536609273, 536609299, 536609321, 536609327,
+    536609347, 536609351, 536609371, 536609377, 536609383, 536609393,
+    536609401, 536609431, 536609449, 536609453, 536609459, 536609467,
+    536609477, 536609501, 536609519, 536609531, 536609611, 536609621,
+    536609627, 536609651, 536609677, 536609699, 536609729, 536609753,
+    536609797, 536609807, 536609813, 536609819, 536609839, 536609963,
+    536609999, 536610007, 536610037, 536610043, 536610047, 536610097,
+    536610101, 536610163, 536610187, 536610241, 536610247, 536610259,
+    536610289, 536610307, 536610323, 536610343, 536610397, 536610409,
+    536610413, 536610439, 536610443, 536610449, 536610511, 536610523,
+    536610587, 536610611, 536610629, 536610647, 536610649, 536610689,
+    536610691, 536610709, 536610727, 536610731, 536610761, 536610793,
+    536610799, 536610817, 536610857, 536610859, 536610917, 536610923,
+    536610929, 536610979, 536610989, 536611003, 536611007, 536611013,
+    536611067, 536611073, 536611093, 536611121, 536611139, 536611181,
+    536611193, 536611219, 536611223, 536611249, 536611277, 536611297,
+    536611303, 536611337, 536611343, 536611363, 536611373, 536611417,
+    536611421, 536611441, 536611451, 536611463, 536611489, 536611499,
+    536611507, 536611513, 536611531, 536611541, 536611553, 536611561,
+    536611583, 536611589, 536611609, 536611633, 536611639, 536611651,
+    536611657, 536611709, 536611717, 536611721, 536611739, 536611753,
+    536611759, 536611771, 536611841, 536611847, 536611861, 536611897,
+    536611939, 536611961, 536611963, 536611979, 536611991, 536611993,
+    536612029, 536612033, 536612039, 536612047, 536612081, 536612099,
+    536612101, 536612159, 536612171, 536612183, 536612233, 536612243,
+    536612267, 536612273, 536612291, 536612299, 536612309, 536612311,
+    536612389, 536612393, 536612411, 536612413, 536612467, 536612501,
+    536612539, 536612579, 536612639, 536612641, 536612647, 536612653,
+    536612731, 536612873, 536612893, 536612911, 536612929, 536612933,
+    536613019, 536613061, 536613097, 536613139, 536613191, 536613199,
+    536613221, 536613223, 536613247, 536613263, 536613269, 536613271,
+    536613373, 536613487, 536613521, 536613547, 536613557, 536613601,
+    536613607, 536613611, 536613613, 536613631, 536613643, 536613647,
+    536613659, 536613691, 536613697, 536613703, 536613731, 536613743,
+    536613799, 536613853, 536613871, 536613877, 536613893, 536613901,
+    536613929, 536613947, 536613949, 536613977, 536613983, 536614003,
+    536614031, 536614049, 536614073, 536614079, 536614103, 536614147,
+    536614171, 536614193, 536614217, 536614223, 536614229, 536614259,
+    536614279, 536614291, 536614297, 536614301, 536614307, 536614327,
+    536614349, 536614361, 536614387, 536614423, 536614471, 536614493,
+    536614627, 536614669, 536614693, 536614703, 536614711, 536614721,
+    536614733, 536614763, 536614781, 536614783, 536614787, 536614807,
+    536614823, 536614831, 536614849, 536614861, 536614913, 536614937,
+    536614999, 536615021, 536615039, 536615063, 536615069, 536615099,
+    536615113, 536615117, 536615137, 536615201, 536615221, 536615227,
+    536615263, 536615267, 536615269, 536615273, 536615279, 536615281,
+    536615291, 536615293, 536615297, 536615311, 536615357, 536615371,
+    536615383, 536615413, 536615419, 536615459, 536615473, 536615509,
+    536615531, 536615539, 536615567, 536615579, 536615581, 536615617,
+    536615633, 536615641, 536615671, 536615707, 536615759, 536615777,
+    536615789, 536615801, 536615813, 536615819, 536615843, 536615851,
+    536615861, 536615927, 536615939, 536615951, 536616007, 536616019,
+    536616097, 536616103, 536616121, 536616137, 536616139, 536616187,
+    536616191, 536616209, 536616229, 536616239, 536616247, 536616251,
+    536616263, 536616281, 536616287, 536616349, 536616359, 536616391,
+    536616397, 536616413, 536616433, 536616461, 536616469, 536616481,
+    536616491, 536616499, 536616523, 536616527, 536616539, 536616557,
+    536616571, 536616583, 536616593, 536616607, 536616629, 536616637,
+    536616643, 536616653, 536616709, 536616767, 536616779, 536616797,
+    536616811, 536616881, 536616893, 536616911, 536616929, 536616931,
+    536616937, 536616947, 536616961, 536616973, 536616991, 536617013,
+    536617033, 536617063, 536617069, 536617079, 536617097, 536617111,
+    536617129, 536617139, 536617153, 536617157, 536617177, 536617181,
+    536617199, 536617229, 536617241, 536617261, 536617267, 536617297,
+    536617309, 536617313, 536617321, 536617349, 536617381, 536617387,
+    536617429, 536617441, 536617447, 536617453, 536617457, 536617507,
+    536617547, 536617561, 536617591, 536617607, 536617619, 536617621,
+    536617651, 536617663, 536617681, 536617687, 536617723, 536617751,
+    536617777, 536617811, 536617819, 536617859, 536617867, 536617891,
+    536617897, 536617997, 536617999, 536618011, 536618023, 536618041,
+    536618077, 536618081, 536618087, 536618111, 536618123, 536618149,
+    536618167, 536618179, 536618183, 536618207, 536618231, 536618237,
+    536618279, 536618287, 536618293, 536618297, 536618321, 536618333,
+    536618419, 536618443, 536618471, 536618473, 536618479, 536618491,
+    536618507, 536618531, 536618557, 536618603, 536618623, 536618669,
+    536618671, 536618689, 536618699, 536618777, 536618791, 536618833,
+    536618857, 536618867, 536618903, 536618933, 536618941, 536618981,
+    536618989, 536619001, 536619007, 536619019, 536619023, 536619037,
+    536619047, 536619053, 536619067, 536619073, 536619079, 536619089,
+    536619133, 536619143, 536619157, 536619173, 536619211, 536619217,
+    536619227, 536619247, 536619253, 536619283, 536619287, 536619289,
+    536619367, 536619383, 536619401, 536619431, 536619449, 536619469,
+    536619481, 536619493, 536619511, 536619533, 536619571, 536619607,
+    536619613, 536619667, 536619673, 536619697, 536619701, 536619731,
+    536619749, 536619763, 536619781, 536619791, 536619823, 536619829,
+    536619851, 536619883, 536619899, 536619901, 536619929, 536619949,
+    536619953, 536619959, 536619997, 536620027, 536620037, 536620043,
+    536620069, 536620127, 536620129, 536620141, 536620157, 536620159,
+    536620169, 536620187, 536620207, 536620229, 536620289, 536620307,
+    536620309, 536620313, 536620333, 536620367, 536620387, 536620411,
+    536620457, 536620499, 536620501, 536620523, 536620529, 536620531,
+    536620537, 536620543, 536620559, 536620577, 536620597, 536620619,
+    536620639, 536620649, 536620687, 536620697, 536620709, 536620723,
+    536620741, 536620771, 536620787, 536620789, 536620801, 536620811,
+    536620829, 536620853, 536620891, 536620913, 536620927, 536620937,
+    536620991, 536620999, 536621021, 536621051, 536621081, 536621083,
+    536621089, 536621093, 536621147, 536621149, 536621159, 536621171,
+    536621177, 536621207, 536621219, 536621251, 536621263, 536621287,
+    536621329, 536621333, 536621339, 536621341, 536621357, 536621359,
+    536621399, 536621413, 536621443, 536621509, 536621521, 536621537,
+    536621543, 536621551, 536621573, 536621581, 536621587, 536621611,
+    536621629, 536621647, 536621689, 536621699, 536621707, 536621753,
+    536621791, 536621797, 536621801, 536621843, 536621849, 536621867,
+    536621909, 536621929, 536621951, 536621977, 536622041, 536622043,
+    536622089, 536622101, 536622133, 536622143, 536622167, 536622209,
+    536622239, 536622253, 536622257, 536622259, 536622277, 536622313,
+    536622319, 536622329, 536622337, 536622349, 536622353, 536622379,
+    536622397, 536622419, 536622421, 536622439, 536622487, 536622503,
+    536622511, 536622539, 536622553, 536622571, 536622613, 536622623,
+    536622659, 536622677, 536622701, 536622707, 536622739, 536622787,
+    536622809, 536622817, 536622839, 536622851, 536622857, 536622907,
+    536622943, 536622953, 536622967, 536623001, 536623013, 536623049,
+    536623057, 536623067, 536623069, 536623081, 536623093, 536623117,
+    536623121, 536623141, 536623169, 536623249, 536623259, 536623397,
+    536623421, 536623427, 536623433, 536623471, 536623481, 536623499,
+    536623501, 536623519, 536623523, 536623541, 536623559, 536623573,
+    536623579, 536623589, 536623597, 536623601, 536623613, 536623699,
+    536623723, 536623727, 536623729, 536623739, 536623753, 536623757,
+    536623777, 536623811, 536623847, 536623849, 536623883, 536623891,
+    536623907, 536623909, 536623963, 536623979, 536623991, 536623999,
+    536624003, 536624069, 536624093, 536624119, 536624171, 536624183,
+    536624191, 536624213, 536624237, 536624251, 536624267, 536624287,
+    536624303, 536624321, 536624351, 536624371, 536624377, 536624393,
+    536624401, 536624423, 536624437, 536624449, 536624453, 536624471,
+    536624513, 536624527, 536624531, 536624537, 536624551, 536624573,
+    536624593, 536624597, 536624609, 536624617, 536624659, 536624677,
+    536624701, 536624713, 536624731, 536624749, 536624783, 536624791,
+    536624827, 536624861, 536624951, 536624969, 536624981, 536624987,
+    536624989, 536625013, 536625059, 536625073, 536625107, 536625149,
+    536625161, 536625163, 536625169, 536625181, 536625209, 536625217,
+    536625241, 536625253, 536625293, 536625317, 536625347, 536625359,
+    536625373, 536625377, 536625431, 536625457, 536625487, 536625491,
+    536625517, 536625521, 536625527, 536625559, 536625577, 536625611,
+    536625613, 536625619, 536625623, 536625629, 536625641, 536625647,
+    536625653, 536625659, 536625697, 536625707, 536625731, 536625737,
+    536625781, 536625821, 536625823, 536625863, 536625883, 536625899,
+    536625923, 536625977, 536625979, 536625997, 536626009, 536626021,
+    536626037, 536626049, 536626061, 536626067, 536626093, 536626109,
+    536626127, 536626141, 536626147, 536626169, 536626171, 536626183,
+    536626201, 536626243, 536626273, 536626351, 536626357, 536626361,
+    536626393, 536626421, 536626423, 536626439, 536626477, 536626529,
+    536626553, 536626561, 536626579, 536626583, 536626603, 536626609,
+    536626613, 536626619, 536626637, 536626661, 536626679, 536626703,
+    536626711, 536626751, 536626757, 536626763, 536626781, 536626787,
+    536626801, 536626829, 536626841, 536626843, 536626847, 536626877,
+    536626891, 536626903, 536626907, 536626949, 536626969, 536626973,
+    536626997, 536627011, 536627023, 536627071, 536627087, 536627093,
+    536627111, 536627129, 536627131, 536627137, 536627141, 536627167,
+    536627177, 536627209, 536627213, 536627233, 536627251, 536627263,
+    536627303, 536627327, 536627353, 536627359, 536627381, 536627387,
+    536627407, 536627411, 536627419, 536627447, 536627471, 536627473,
+    536627477, 536627503, 536627549, 536627551, 536627591, 536627603,
+    536627617, 536627647, 536627657, 536627677, 536627699, 536627719,
+    536627731, 536627753, 536627759, 536627771, 536627779, 536627783,
+    536627827, 536627843, 536627851, 536627863, 536627879, 536627911,
+    536627921, 536627941, 536627957, 536627969, 536627989, 536628031,
+    536628047, 536628109, 536628121, 536628133, 536628143, 536628161,
+    536628173, 536628199, 536628221, 536628289, 536628311, 536628331,
+    536628349, 536628359, 536628397, 536628401, 536628413, 536628431,
+    536628461, 536628487, 536628503, 536628523, 536628539, 536628559,
+    536628601, 536628607, 536628643, 536628667, 536628671, 536628683,
+    536628689, 536628727, 536628733, 536628737, 536628739, 536628779,
+    536628809, 536628811, 536628877, 536628887, 536628889, 536628923,
+    536628931, 536628959, 536629007, 536629061, 536629087, 536629111,
+    536629133, 536629183, 536629193, 536629199, 536629231, 536629243,
+    536629273, 536629277, 536629309, 536629319, 536629339, 536629349,
+    536629391, 536629393, 536629433, 536629441, 536629451, 536629459,
+    536629469, 536629477, 536629481, 536629487, 536629517, 536629519,
+    536629529, 536629657, 536629679, 536629703, 536629757, 536629763,
+    536629811, 536629937, 536629979, 536630009, 536630011, 536630027,
+    536630111, 536630147, 536630179, 536630183, 536630209, 536630231,
+    536630249, 536630291, 536630317, 536630321, 536630363, 536630371,
+    536630383, 536630387, 536630389, 536630401, 536630407, 536630417,
+    536630467, 536630531, 536630533, 536630569, 536630579, 536630581,
+    536630599, 536630609, 536630617, 536630629, 536630639, 536630651,
+    536630659, 536630663, 536630681, 536630711, 536630713, 536630729,
+    536630741, 536630747, 536630749, 536630797, 536630807, 536630821,
+    536630827, 536630839, 536630873, 536630923, 536630947, 536630971,
+    536630981, 536630999, 536631023, 536631031, 536631071, 536631131,
+    536631143, 536631157, 536631169, 536631187, 536631191, 536631209,
+    536631211, 536631217, 536631229, 536631253, 536631259, 536631343,
+    536631379, 536631391, 536631479, 536631509, 536631517, 536631533,
+    536631581, 536631587, 536631593, 536631637, 536631661, 536631691,
+    536631709, 536631713, 536631749, 536631827, 536631829, 536631841,
+    536631899, 536631913, 536631941, 536631967, 536631973, 536631989,
+    536632003, 536632007, 536632027, 536632043, 536632051, 536632073,
+    536632079, 536632091, 536632093, 536632097, 536632099, 536632139,
+    536632147, 536632177, 536632193, 536632223, 536632237, 536632247,
+    536632249, 536632253, 536632309, 536632321, 536632331, 536632337,
+    536632357, 536632361, 536632363, 536632373, 536632379, 536632391,
+    536632399, 536632427, 536632429, 536632441, 536632457, 536632471,
+    536632487, 536632519, 536632529, 536632541, 536632549, 536632609,
+    536632627, 536632631, 536632633, 536632651, 536632667, 536632721,
+    536632739, 536632763, 536632769, 536632813, 536632823, 536632843,
+    536632919, 536632933, 536632937, 536632939, 536632951, 536632961,
+    536632997, 536633047, 536633057, 536633059, 536633063, 536633087,
+    536633113, 536633117, 536633129, 536633137, 536633159, 536633183,
+    536633189, 536633191, 536633213, 536633233, 536633239, 536633257,
+    536633267, 536633303, 536633329, 536633369, 536633381, 536633413,
+    536633417, 536633423, 536633431, 536633477, 536633527, 536633551,
+    536633561, 536633563, 536633597, 536633633, 536633659, 536633683,
+    536633729, 536633737, 536633813, 536633819, 536633821, 536633837,
+    536633863, 536633869, 536633873, 536633941, 536633983, 536633987,
+    536634001, 536634013, 536634029, 536634037, 536634041, 536634127,
+    536634143, 536634151, 536634179, 536634187, 536634193, 536634209,
+    536634227, 536634239, 536634269, 536634283, 536634337, 536634341,
+    536634349, 536634353, 536634389, 536634403, 536634407, 536634433,
+    536634443, 536634451, 536634463, 536634467, 536634493, 536634541,
+    536634547, 536634599, 536634611, 536634701, 536634719, 536634731,
+    536634799, 536634809, 536634851, 536634907, 536634929, 536634977,
+    536634979, 536634983, 536634991, 536635003, 536635007, 536635027,
+    536635063, 536635091, 536635097, 536635109, 536635129, 536635139,
+    536635157, 536635171, 536635181, 536635193, 536635207, 536635213,
+    536635223, 536635247, 536635249, 536635279, 536635301, 536635349,
+    536635357, 536635367, 536635381, 536635397, 536635433, 536635453,
+    536635469, 536635499, 536635501, 536635529, 536635573, 536635591,
+    536635643, 536635681, 536635733, 536635751, 536635783, 536635817,
+    536635873, 536635877, 536635903, 536635909, 536635933, 536635949,
+    536635951, 536635961, 536635969, 536635973, 536635993, 536635997,
+    536635999, 536636029, 536636033, 536636063, 536636101, 536636117,
+    536636119, 536636131, 536636141, 536636143, 536636153, 536636159,
+    536636231, 536636279, 536636281, 536636291, 536636293, 536636311,
+    536636339, 536636357, 536636369, 536636377, 536636407, 536636449,
+    536636461, 536636473, 536636521, 536636537, 536636549, 536636557,
+    536636563, 536636591, 536636593, 536636599, 536636609, 536636623,
+    536636663, 536636687, 536636707, 536636719, 536636743, 536636767,
+    536636777, 536636783, 536636791, 536636827, 536636839, 536636857,
+    536636873, 536636879, 536636899, 536636911, 536636917, 536636927,
+    536636941, 536636953, 536636983, 536637019, 536637043, 536637053,
+    536637067, 536637071, 536637133, 536637163, 536637169, 536637203,
+    536637217, 536637223, 536637253, 536637263, 536637281, 536637289,
+    536637293, 536637329, 536637347, 536637379, 536637389, 536637427,
+    536637443, 536637469, 536637481, 536637499, 536637553, 536637581,
+    536637593, 536637637, 536637649, 536637671, 536637697, 536637709,
+    536637713, 536637719, 536637737, 536637797, 536637799, 536637811,
+    536637821, 536637823, 536637839, 536637877, 536637961, 536637989,
+    536637991, 536638009, 536638019, 536638027, 536638051, 536638079,
+    536638153, 536638163, 536638169, 536638183, 536638189, 536638229,
+    536638247, 536638279, 536638307, 536638321, 536638331, 536638363,
+    536638379, 536638391, 536638397, 536638477, 536638481, 536638493,
+    536638499, 536638511, 536638513, 536638523, 536638537, 536638579,
+    536638589, 536638601, 536638637, 536638657, 536638673, 536638693,
+    536638703, 536638789, 536638801, 536638811, 536638819, 536638853,
+    536638871, 536638877, 536638901, 536638909, 536638913, 536638951,
+    536638981, 536639003, 536639023, 536639039, 536639041, 536639093,
+    536639099, 536639141, 536639149, 536639177, 536639219, 536639237,
+    536639251, 536639293, 536639297, 536639321, 536639329, 536639339,
+    536639359, 536639399, 536639417, 536639429, 536639437, 536639449,
+    536639483, 536639489, 536639491, 536639533, 536639557, 536639569,
+    536639581, 536639617, 536639627, 536639639, 536639641, 536639669,
+    536639671, 536639689, 536639713, 536639723, 536639759, 536639767,
+    536639773, 536639813, 536639837, 536639839, 536639879, 536639881,
+    536639921, 536639927, 536639953, 536639963, 536639981, 536640001,
+    536640023, 536640029, 536640053, 536640061, 536640073, 536640089,
+    536640113, 536640179, 536640187, 536640217, 536640233, 536640239,
+    536640253, 536640263, 536640271, 536640289, 536640329, 536640353,
+    536640359, 536640373, 536640413, 536640421, 536640437, 536640449,
+    536640451, 536640457, 536640469, 536640487, 536640491, 536640523,
+    536640527, 536640551, 536640557, 536640571, 536640589, 536640619,
+    536640647, 536640653, 536640673, 536640757, 536640773, 536640779,
+    536640781, 536640799, 536640829, 536640901, 536640943, 536640967,
+    536641009, 536641019, 536641069, 536641097, 536641099, 536641109,
+    536641139, 536641141, 536641211, 536641213, 536641223, 536641283,
+    536641291, 536641321, 536641337, 536641349, 536641361, 536641367,
+    536641379, 536641387, 536641411, 536641459, 536641471, 536641481,
+    536641519, 536641531, 536641537, 536641597, 536641613, 536641627,
+    536641649, 536641667, 536641687, 536641691, 536641697, 536641753,
+    536641759, 536641789, 536641811, 536641841, 536641843, 536641867,
+    536641877, 536641883, 536641891, 536641913, 536641933, 536641939,
+    536641967, 536641999, 536642011, 536642017, 536642033, 536642081,
+    536642083, 536642087, 536642089, 536642131, 536642159, 536642167,
+    536642173, 536642237, 536642243, 536642269, 536642299, 536642377,
+    536642387, 536642401, 536642411, 536642453, 536642459, 536642473,
+    536642489, 536642501, 536642521, 536642539, 536642551, 536642567,
+    536642573, 536642591, 536642609, 536642611, 536642633, 536642641,
+    536642657, 536642671, 536642683, 536642747, 536642753, 536642773,
+    536642789, 536642807, 536642833, 536642863, 536642867, 536642917,
+    536642947, 536642957, 536642993, 536643001, 536643007, 536643013,
+    536643017, 536643043, 536643067, 536643071, 536643083, 536643089,
+    536643109, 536643157, 536643161, 536643193, 536643197, 536643229,
+    536643241, 536643257, 536643259, 536643269, 536643293, 536643323,
+    536643329, 536643361, 536643377, 536643379, 536643431, 536643469,
+    536643491, 536643529, 536643551, 536643553, 536643571, 536643577,
+    536643587, 536643589, 536643599, 536643623, 536643647, 536643739,
+    536643749, 536643769, 536643799, 536643829, 536643871, 536643931,
+    536643949, 536643953, 536643959, 536643997, 536644001, 536644021,
+    536644033, 536644051, 536644063, 536644103, 536644109, 536644139,
+    536644181, 536644247, 536644271, 536644301, 536644307, 536644309,
+    536644331, 536644363, 536644397, 536644439, 536644477, 536644517,
+    536644519, 536644553, 536644567, 536644597, 536644609, 536644621,
+    536644631, 536644639, 536644657, 536644679, 536644727, 536644733,
+    536644753, 536644811, 536644819, 536644841, 536644847, 536644853,
+    536644861, 536644891, 536644897, 536644907, 536644921, 536644931,
+    536645071, 536645093, 536645099, 536645113, 536645173, 536645189,
+    536645191, 536645209, 536645227, 536645237, 536645257, 536645287,
+    536645293, 536645321, 536645323, 536645357, 536645363, 536645437,
+    536645441, 536645449, 536645467, 536645471, 536645497, 536645507,
+    536645513, 536645531, 536645539, 536645567, 536645569, 536645573,
+    536645621, 536645639, 536645653, 536645663, 536645717, 536645741,
+    536645773, 536645777, 536645797, 536645801, 536645819, 536645831,
+    536645839, 536645873, 536645909, 536645969, 536645971, 536646031,
+    536646043, 536646079, 536646107, 536646109, 536646137, 536646161,
+    536646163, 536646167, 536646197, 536646221, 536646263, 536646269,
+    536646277, 536646323, 536646413, 536646427, 536646457, 536646491,
+    536646521, 536646541, 536646547, 536646563, 536646577, 536646629,
+    536646641, 536646647, 536646679, 536646703, 536646739, 536646743,
+    536646749, 536646757, 536646793, 536646809, 536646821, 536646823,
+    536646839, 536646857, 536646863, 536646883, 536646899, 536646911,
+    536646917, 536646941, 536646953, 536646959, 536646967, 536646977,
+    536646989, 536646997, 536647049, 536647091, 536647093, 536647121,
+    536647147, 536647183, 536647187, 536647213, 536647219, 536647249,
+    536647253, 536647259, 536647261, 536647271, 536647273, 536647277,
+    536647289, 536647301, 536647351, 536647361, 536647367, 536647379,
+    536647387, 536647399, 536647403, 536647429, 536647451, 536647459,
+    536647481, 536647487, 536647511, 536647513, 536647567, 536647583,
+    536647591, 536647627, 536647637, 536647663, 536647679, 536647681,
+    536647717, 536647733, 536647751, 536647763, 536647801, 536647829,
+    536647831, 536647841, 536647847, 536647873, 536647879, 536647883,
+    536647901, 536647999, 536648009, 536648023, 536648051, 536648107,
+    536648131, 536648149, 536648153, 536648173, 536648183, 536648191,
+    536648201, 536648239, 536648243, 536648251, 536648257, 536648261,
+    536648269, 536648297, 536648309, 536648353, 536648363, 536648377,
+    536648381, 536648389, 536648417, 536648473, 536648507, 536648513,
+    536648531, 536648543, 536648569, 536648579, 536648599, 536648611,
+    536648633, 536648641, 536648647, 536648677, 536648687, 536648753,
+    536648771, 536648779, 536648789, 536648807, 536648821, 536648873,
+    536648899, 536648921, 536648929, 536648953, 536648963, 536648969,
+    536648993, 536649007, 536649019, 536649037, 536649049, 536649067,
+    536649097, 536649101, 536649107, 536649137, 536649181, 536649187,
+    536649203, 536649227, 536649283, 536649313, 536649329, 536649343,
+    536649349, 536649361, 536649371, 536649403, 536649439, 536649457,
+    536649497, 536649511, 536649563, 536649569, 536649571, 536649577,
+    536649583, 536649599, 536649601, 536649637, 536649643, 536649653,
+    536649677, 536649683, 536649689, 536649703, 536649709, 536649721,
+    536649749, 536649793, 536649809, 536649811, 536649853, 536649859,
+    536649877, 536649913, 536649917, 536649929, 536649983, 536650013,
+    536650043, 536650063, 536650091, 536650111, 536650141, 536650199,
+    536650201, 536650223, 536650243, 536650333, 536650349, 536650357,
+    536650381, 536650403, 536650417, 536650451, 536650483, 536650507,
+    536650519, 536650523, 536650529, 536650537, 536650547, 536650601,
+    536650603, 536650613, 536650633, 536650661, 536650729, 536650753,
+    536650759, 536650817, 536650837, 536650867, 536650897, 536650913,
+    536650921, 536650943, 536650949, 536650999, 536651021, 536651033,
+    536651069, 536651081, 536651083, 536651113, 536651147, 536651153,
+    536651161, 536651179, 536651201, 536651207, 536651233, 536651267,
+    536651287, 536651347, 536651377, 536651383, 536651389, 536651407,
+    536651413, 536651417, 536651449, 536651471, 536651477, 536651497,
+    536651513, 536651537, 536651573, 536651603, 536651611, 536651623,
+    536651651, 536651671, 536651681, 536651693, 536651701, 536651711,
+    536651719, 536651729, 536651741, 536651777, 536651779, 536651839,
+    536651851, 536651923, 536651963, 536651987, 536652001, 536652007,
+    536652013, 536652043, 536652049, 536652059, 536652071, 536652079,
+    536652091, 536652097, 536652113, 536652119, 536652143, 536652211,
+    536652229, 536652247, 536652269, 536652299, 536652313, 536652331,
+    536652349, 536652383, 536652437, 536652449, 536652461, 536652463,
+    536652469, 536652497, 536652499, 536652539, 536652541, 536652559,
+    536652607, 536652661, 536652667, 536652679, 536652703, 536652709,
+    536652713, 536652737, 536652761, 536652793, 536652817, 536652827,
+    536652841, 536652877, 536652901, 536652953, 536652971, 536652983,
+    536652989, 536653021, 536653063, 536653079, 536653099, 536653111,
+    536653133, 536653147, 536653153, 536653171, 536653189, 536653193,
+    536653199, 536653259, 536653261, 536653333, 536653339, 536653343,
+    536653361, 536653409, 536653427, 536653477, 536653483, 536653529,
+    536653531, 536653561, 536653573, 536653591, 536653609, 536653657,
+    536653693, 536653699, 536653709, 536653721, 536653723, 536653751,
+    536653753, 536653759, 536653763, 536653769, 536653771, 536653781,
+    536653823, 536653829, 536653907, 536653913, 536653919, 536653933,
+    536653937, 536653939, 536653951, 536653967, 536653969, 536654021,
+    536654059, 536654087, 536654093, 536654117, 536654137, 536654141,
+    536654143, 536654161, 536654177, 536654213, 536654219, 536654227,
+    536654243, 536654269, 536654291, 536654303, 536654323, 536654329,
+    536654341, 536654353, 536654357, 536654387, 536654399, 536654431,
+    536654441, 536654467, 536654471, 536654519, 536654527, 536654533,
+    536654543, 536654551, 536654557, 536654579, 536654581, 536654593,
+    536654611, 536654647, 536654659, 536654669, 536654719, 536654743,
+    536654747, 536654761, 536654779, 536654803, 536654809, 536654819,
+    536654879, 536654887, 536654891, 536654933, 536654971, 536654999,
+    536655017, 536655061, 536655083, 536655101, 536655103, 536655107,
+    536655131, 536655139, 536655143, 536655173, 536655181, 536655199,
+    536655233, 536655241, 536655271, 536655281, 536655293, 536655299,
+    536655307, 536655311, 536655347, 536655403, 536655409, 536655433,
+    536655451, 536655463, 536655499, 536655503, 536655533, 536655547,
+    536655569, 536655593, 536655653, 536655719, 536655737, 536655739,
+    536655761, 536655773, 536655797, 536655811, 536655827, 536655841,
+    536655851, 536655887, 536655901, 536655907, 536655913, 536655937,
+    536655943, 536655961, 536656009, 536656019, 536656031, 536656067,
+    536656117, 536656139, 536656157, 536656181, 536656201, 536656213,
+    536656247, 536656259, 536656261, 536656277, 536656279, 536656321,
+    536656381, 536656403, 536656409, 536656427, 536656433, 536656441,
+    536656451, 536656487, 536656529, 536656541, 536656583, 536656597,
+    536656609, 536656619, 536656639, 536656643, 536656649, 536656709,
+    536656741, 536656759, 536656781, 536656793, 536656807, 536656817,
+    536656819, 536656823, 536656847, 536656849, 536656871, 536656873,
+    536656877, 536656921, 536656931, 536656933, 536656937, 536656961,
+    536656963, 536656973, 536657021, 536657039, 536657041, 536657063,
+    536657083, 536657087, 536657101, 536657117, 536657123, 536657129,
+    536657131, 536657179, 536657197, 536657201, 536657269, 536657279,
+    536657347, 536657371, 536657417, 536657437, 536657449, 536657491,
+    536657497, 536657503, 536657519, 536657521, 536657543, 536657567,
+    536657617, 536657623, 536657663, 536657669, 536657699, 536657729,
+    536657741, 536657749, 536657767, 536657783, 536657791, 536657801,
+    536657813, 536657837, 536657843, 536657867, 536657881, 536657893,
+    536657909, 536657911, 536657917, 536657951, 536657969, 536657977,
+    536657999, 536658043, 536658047, 536658049, 536658151, 536658167,
+    536658229, 536658233, 536658251, 536658263, 536658281, 536658301,
+    536658359, 536658373, 536658403, 536658413, 536658433, 536658449,
+    536658469, 536658481, 536658491, 536658503, 536658527, 536658547,
+    536658569, 536658571, 536658589, 536658637, 536658641, 536658649,
+    536658653, 536658713, 536658721, 536658751, 536658757, 536658797,
+    536658803, 536658817, 536658823, 536658847, 536658937, 536658961,
+    536659001, 536659033, 536659037, 536659051, 536659061, 536659091,
+    536659117, 536659129, 536659141, 536659163, 536659169, 536659171,
+    536659187, 536659223, 536659229, 536659243, 536659267, 536659309,
+    536659327, 536659337, 536659367, 536659369, 536659379, 536659381,
+    536659421, 536659477, 536659493, 536659499, 536659531, 536659547,
+    536659559, 536659567, 536659589, 536659597, 536659601, 536659633,
+    536659649, 536659661, 536659681, 536659699, 536659741, 536659777,
+    536659793, 536659847, 536659867, 536659873, 536659901, 536659913,
+    536659919, 536659967, 536659987, 536659999, 536660009, 536660021,
+    536660023, 536660039, 536660041, 536660057, 536660071, 536660101,
+    536660107, 536660119, 536660123, 536660161, 536660171, 536660197,
+    536660207, 536660221, 536660227, 536660231, 536660261, 536660291,
+    536660297, 536660317, 536660323, 536660329, 536660353, 536660393,
+    536660407, 536660413, 536660417, 536660431, 536660447, 536660479,
+    536660483, 536660489, 536660497, 536660503, 536660549, 536660557,
+    536660609, 536660629, 536660651, 536660699, 536660713, 536660717,
+    536660731, 536660753, 536660779, 536660783, 536660857, 536660869,
+    536660897, 536660903, 536660911, 536660923, 536660959, 536660963,
+    536661007, 536661031, 536661053, 536661067, 536661079, 536661091,
+    536661127, 536661131, 536661143, 536661149, 536661157, 536661161,
+    536661221, 536661241, 536661247, 536661313, 536661331, 536661337,
+    536661361, 536661373, 536661383, 536661401, 536661421, 536661439,
+    536661467, 536661473, 536661497, 536661529, 536661539, 536661551,
+    536661569, 536661607, 536661637, 536661647, 536661659, 536661679,
+    536661731, 536661761, 536661767, 536661779, 536661799, 536661803,
+    536661841, 536661857, 536661877, 536661883, 536661929, 536661959,
+    536661977, 536661989, 536661991, 536662019, 536662039, 536662051,
+    536662109, 536662123, 536662129, 536662141, 536662177, 536662183,
+    536662193, 536662223, 536662229, 536662237, 536662261, 536662271,
+    536662303, 536662333, 536662337, 536662351, 536662363, 536662367,
+    536662369, 536662387, 536662433, 536662447, 536662463, 536662513,
+    536662531, 536662549, 536662559, 536662573, 536662583, 536662627,
+    536662691, 536662729, 536662741, 536662751, 536662769, 536662807,
+    536662813, 536662829, 536662859, 536662871, 536662891, 536662901,
+    536662921, 536662927, 536662949, 536662957, 536662963, 536663003,
+    536663033, 536663053, 536663093, 536663111, 536663129, 536663159,
+    536663173, 536663201, 536663203, 536663219, 536663261, 536663279,
+    536663287, 536663291, 536663321, 536663359, 536663363, 536663383,
+    536663389, 536663411, 536663419, 536663431, 536663441, 536663443,
+    536663447, 536663453, 536663467, 536663527, 536663539, 536663557,
+    536663563, 536663573, 536663579, 536663593, 536663597, 536663609,
+    536663627, 536663663, 536663707, 536663711, 536663717, 536663747,
+    536663749, 536663839, 536663851, 536663921, 536663923, 536664067,
+    536664077, 536664091, 536664103, 536664113, 536664119, 536664131,
+    536664133, 536664179, 536664217, 536664229, 536664239, 536664257,
+    536664259, 536664263, 536664307, 536664311, 536664319, 536664341,
+    536664361, 536664383, 536664389, 536664437, 536664461, 536664463,
+    536664493, 536664521, 536664523, 536664559, 536664631, 536664673,
+    536664677, 536664679, 536664731, 536664781, 536664797, 536664853,
+    536664881, 536664889, 536664893, 536664929, 536664943, 536664971,
+    536664979, 536665009, 536665079, 536665081, 536665099, 536665111,
+    536665139, 536665153, 536665177, 536665289, 536665291, 536665331,
+    536665343, 536665379, 536665391, 536665433, 536665447, 536665453,
+    536665489, 536665513, 536665541, 536665553, 536665603, 536665631,
+    536665637, 536665663, 536665681, 536665691, 536665709, 536665729,
+    536665771, 536665777, 536665781, 536665819, 536665859, 536665867,
+    536665873, 536665897, 536665931, 536665957, 536665981, 536665993,
+    536666063, 536666071, 536666087, 536666089, 536666147, 536666159,
+    536666161, 536666213, 536666219, 536666281, 536666321, 536666329,
+    536666399, 536666413, 536666441, 536666467, 536666483, 536666509,
+    536666527, 536666549, 536666551, 536666563, 536666569, 536666597,
+    536666639, 536666651, 536666657, 536666681, 536666729, 536666731,
+    536666737, 536666749, 536666791, 536666813, 536666831, 536666857,
+    536666861, 536666899, 536666903, 536666927, 536666929, 536666939,
+    536666941, 536666957, 536666969, 536666971, 536667023, 536667031,
+    536667037, 536667049, 536667083, 536667107, 536667113, 536667149,
+    536667151, 536667191, 536667193, 536667221, 536667251, 536667323,
+    536667337, 536667343, 536667361, 536667377, 536667427, 536667431,
+    536667433, 536667493, 536667529, 536667539, 536667541, 536667553,
+    536667581, 536667589, 536667613, 536667689, 536667697, 536667743,
+    536667751, 536667757, 536667767, 536667773, 536667779, 536667793,
+    536667797, 536667811, 536667827, 536667851, 536667871, 536667893,
+    536667941, 536667961, 536668031, 536668037, 536668061, 536668081,
+    536668103, 536668109, 536668133, 536668163, 536668193, 536668211,
+    536668217, 536668219, 536668241, 536668259, 536668267, 536668271,
+    536668283, 536668303, 536668331, 536668343, 536668351, 536668369,
+    536668397, 536668399, 536668411, 536668421, 536668441, 536668477,
+    536668493, 536668511, 536668523, 536668537, 536668541, 536668579,
+    536668687, 536668697, 536668711, 536668723, 536668747, 536668763,
+    536668777, 536668819, 536668823, 536668837, 536668841, 536668877,
+    536668919, 536668933, 536668961, 536668969, 536668973, 536668981,
+    536668997, 536668999, 536669017, 536669047, 536669059, 536669083,
+    536669137, 536669227, 536669233, 536669261, 536669323, 536669339,
+    536669381, 536669407, 536669411, 536669417, 536669429, 536669437,
+    536669443, 536669479, 536669519, 536669527, 536669533, 536669543,
+    536669579, 536669629, 536669633, 536669659, 536669663, 536669671,
+    536669677, 536669681, 536669729, 536669743, 536669747, 536669779,
+    536669797, 536669807, 536669813, 536669843, 536669873, 536669897,
+    536669899, 536669921, 536669981, 536669983, 536669999, 536670007,
+    536670011, 536670019, 536670023, 536670041, 536670061, 536670073,
+    536670083, 536670097, 536670107, 536670119, 536670133, 536670139,
+    536670149, 536670151, 536670187, 536670191, 536670193, 536670203,
+    536670223, 536670269, 536670287, 536670301, 536670307, 536670341,
+    536670349, 536670373, 536670383, 536670389, 536670391, 536670397,
+    536670403, 536670427, 536670439, 536670457, 536670473, 536670493,
+    536670499, 536670509, 536670517, 536670551, 536670553, 536670571,
+    536670583, 536670593, 536670601, 536670643, 536670649, 536670677,
+    536670679, 536670683, 536670721, 536670727, 536670809, 536670811,
+    536670821, 536670847, 536670851, 536670857, 536670859, 536670877,
+    536670887, 536670923, 536670929, 536670989, 536670991, 536671001,
+    536671043, 536671087, 536671103, 536671123, 536671133, 536671151,
+    536671183, 536671193, 536671217, 536671231, 536671243, 536671271,
+    536671297, 536671301, 536671319, 536671337, 536671379, 536671381,
+    536671403, 536671439, 536671441, 536671501, 536671507, 536671559,
+    536671561, 536671567, 536671579, 536671601, 536671621, 536671631,
+    536671753, 536671781, 536671787, 536671801, 536671813, 536671841,
+    536671843, 536671867, 536671879, 536671973, 536671979, 536671981,
+    536672021, 536672029, 536672033, 536672039, 536672053, 536672063,
+    536672111, 536672137, 536672183, 536672203, 536672221, 536672249,
+    536672261, 536672267, 536672299, 536672351, 536672377, 536672399,
+    536672407, 536672419, 536672483, 536672491, 536672497, 536672503,
+    536672519, 536672557, 536672561, 536672597, 536672611, 536672623,
+    536672641, 536672681, 536672687, 536672699, 536672707, 536672729,
+    536672761, 536672767, 536672839, 536672849, 536672863, 536672887,
+    536672891, 536672897, 536672911, 536672921, 536672933, 536672957,
+    536672959, 536672963, 536672971, 536672989, 536673013, 536673041,
+    536673061, 536673073, 536673083, 536673127, 536673133, 536673143,
+    536673169, 536673199, 536673227, 536673233, 536673253, 536673281,
+    536673287, 536673331, 536673337, 536673341, 536673343, 536673353,
+    536673367, 536673383, 536673407, 536673427, 536673433, 536673437,
+    536673463, 536673469, 536673481, 536673503, 536673517, 536673541,
+    536673607, 536673653, 536673667, 536673691, 536673719, 536673721,
+    536673733, 536673769, 536673773, 536673803, 536673847, 536673859,
+    536673889, 536673899, 536673911, 536673923, 536673931, 536673941,
+    536673961, 536673967, 536673979, 536673989, 536673997, 536674007,
+    536674031, 536674043, 536674063, 536674091, 536674093, 536674123,
+    536674129, 536674141, 536674169, 536674181, 536674211, 536674213,
+    536674217, 536674219, 536674223, 536674267, 536674273, 536674277,
+    536674321, 536674331, 536674337, 536674349, 536674367, 536674409,
+    536674417, 536674423, 536674429, 536674451, 536674483, 536674507,
+    536674517, 536674549, 536674583, 536674591, 536674639, 536674681,
+    536674693, 536674753, 536674769, 536674771, 536674781, 536674807,
+    536674813, 536674829, 536674843, 536674861, 536674867, 536674909,
+    536674927, 536674961, 536674967, 536674981, 536674987, 536674993,
+    536674997, 536675003, 536675017, 536675039, 536675053, 536675063,
+    536675129, 536675137, 536675143, 536675147, 536675149, 536675171,
+    536675177, 536675213, 536675219, 536675221, 536675231, 536675239,
+    536675323, 536675351, 536675369, 536675393, 536675401, 536675407,
+    536675411, 536675413, 536675467, 536675471, 536675483, 536675497,
+    536675507, 536675549, 536675551, 536675599, 536675617, 536675641,
+    536675687, 536675693, 536675701, 536675719, 536675753, 536675837,
+    536675879, 536675891, 536675899, 536675969, 536676011, 536676029,
+    536676031, 536676067, 536676073, 536676103, 536676131, 536676139,
+    536676167, 536676169, 536676209, 536676229, 536676253, 536676269,
+    536676271, 536676277, 536676289, 536676293, 536676307, 536676313,
+    536676317, 536676367, 536676391, 536676401, 536676431, 536676443,
+    536676461, 536676479, 536676493, 536676521, 536676541, 536676559,
+    536676577, 536676611, 536676617, 536676643, 536676649, 536676661,
+    536676671, 536676677, 536676709, 536676713, 536676737, 536676761,
+    536676769, 536676799, 536676809, 536676821, 536676857, 536676863,
+    536676883, 536676911, 536676919, 536676949, 536676977, 536676989,
+    536676997, 536677007, 536677051, 536677069, 536677117, 536677151,
+    536677153, 536677159, 536677187, 536677213, 536677217, 536677279,
+    536677307, 536677343, 536677391, 536677397, 536677399, 536677441,
+    536677481, 536677499, 536677517, 536677529, 536677543, 536677597,
+    536677613, 536677619, 536677627, 536677633, 536677639, 536677649,
+    536677681, 536677717, 536677723, 536677753, 536677763, 536677769,
+    536677789, 536677829, 536677849, 536677861, 536677871, 536677877,
+    536677901, 536677907, 536677927, 536677957, 536677961, 536677963,
+    536678003, 536678017, 536678029, 536678033, 536678039, 536678041,
+    536678057, 536678171, 536678173, 536678201, 536678209, 536678239,
+    536678257, 536678269, 536678273, 536678291, 536678327, 536678339,
+    536678341, 536678353, 536678357, 536678447, 536678449, 536678473,
+    536678489, 536678531, 536678533, 536678543, 536678551, 536678557,
+    536678567, 536678683, 536678749, 536678761, 536678771, 536678783,
+    536678827, 536678833, 536678881, 536678897, 536678929, 536678951,
+    536678957, 536678963, 536678983, 536679029, 536679061, 536679089,
+    536679107, 536679109, 536679119, 536679181, 536679193, 536679233,
+    536679251, 536679329, 536679343, 536679349, 536679361, 536679379,
+    536679419, 536679421, 536679427, 536679499, 536679547, 536679551,
+    536679587, 536679593, 536679599, 536679607, 536679623, 536679629,
+    536679653, 536679659, 536679679, 536679683, 536679707, 536679739,
+    536679779, 536679823, 536679853, 536679859, 536679863, 536679889,
+    536679893, 536679959, 536679991, 536680009, 536680069, 536680087,
+    536680093, 536680097, 536680103, 536680141, 536680163, 536680171,
+    536680211, 536680247, 536680253, 536680273, 536680363, 536680369,
+    536680381, 536680387, 536680411, 536680423, 536680433, 536680453,
+    536680471, 536680477, 536680483, 536680489, 536680493, 536680499,
+    536680511, 536680553, 536680559, 536680589, 536680601, 536680609,
+    536680619, 536680637, 536680657, 536680663, 536680673, 536680679,
+    536680681, 536680717, 536680801, 536680811, 536680813, 536680817,
+    536680831, 536680841, 536680847, 536680909, 536680913, 536680961,
+    536680981, 536681003, 536681009, 536681017, 536681023, 536681039,
+    536681113, 536681137, 536681141, 536681147, 536681153, 536681209,
+    536681227, 536681231, 536681251, 536681281, 536681293, 536681329,
+    536681351, 536681399, 536681401, 536681407, 536681459, 536681489,
+    536681491, 536681521, 536681549, 536681557, 536681567, 536681611,
+    536681617, 536681623, 536681689, 536681711, 536681713, 536681723,
+    536681731, 536681741, 536681749, 536681777, 536681779, 536681851,
+    536681863, 536681921, 536681927, 536681941, 536681969, 536681987,
+    536682017, 536682053, 536682059, 536682071, 536682073, 536682089,
+    536682103, 536682119, 536682121, 536682131, 536682173, 536682217,
+    536682229, 536682239, 536682247, 536682257, 536682277, 536682353,
+    536682413, 536682457, 536682481, 536682499, 536682547, 536682551,
+    536682593, 536682623, 536682637, 536682649, 536682691, 536682701,
+    536682737, 536682799, 536682827, 536682829, 536682857, 536682869,
+    536682889, 536682899, 536682917, 536682967, 536682997, 536683009,
+    536683073, 536683093, 536683097, 536683099, 536683157, 536683171,
+    536683201, 536683223, 536683241, 536683267, 536683283, 536683313,
+    536683321, 536683327, 536683337, 536683351, 536683363, 536683369,
+    536683373, 536683379, 536683393, 536683447, 536683463, 536683487,
+    536683507, 536683571, 536683573, 536683597, 536683603, 536683607,
+    536683661, 536683699, 536683703, 536683723, 536683739, 536683757,
+    536683769, 536683789, 536683837, 536683841, 536683843, 536683871,
+    536683877, 536683879, 536683907, 536683913, 536683921, 536683943,
+    536683949, 536683993, 536684009, 536684017, 536684041, 536684077,
+    536684081, 536684107, 536684123, 536684129, 536684153, 536684167,
+    536684189, 536684221, 536684249, 536684263, 536684327, 536684359,
+    536684363, 536684381, 536684387, 536684389, 536684437, 536684471,
+    536684479, 536684497, 536684531, 536684563, 536684567, 536684581,
+    536684623, 536684627, 536684633, 536684641, 536684647, 536684651,
+    536684671, 536684719, 536684749, 536684779, 536684789, 536684791,
+    536684851, 536684857, 536684867, 536684903, 536684909, 536684923,
+    536684947, 536684959, 536684971, 536684983, 536685011, 536685031,
+    536685043, 536685067, 536685073, 536685089, 536685101, 536685131,
+    536685169, 536685199, 536685239, 536685241, 536685263, 536685283,
+    536685287, 536685293, 536685313, 536685319, 536685337, 536685389,
+    536685437, 536685469, 536685493, 536685509, 536685599, 536685637,
+    536685697, 536685701, 536685739, 536685769, 536685781, 536685833,
+    536685847, 536685899, 536685911, 536685917, 536685923, 536686069,
+    536686123, 536686127, 536686181, 536686193, 536686219, 536686237,
+    536686247, 536686253, 536686303, 536686343, 536686349, 536686399,
+    536686417, 536686429, 536686453, 536686463, 536686489, 536686529,
+    536686537, 536686603, 536686621, 536686637, 536686649, 536686687,
+    536686697, 536686721, 536686747, 536686757, 536686781, 536686811,
+    536686837, 536686861, 536686877, 536686907, 536686921, 536686949,
+    536686979, 536686981, 536686993, 536687003, 536687009, 536687071,
+    536687077, 536687087, 536687111, 536687227, 536687233, 536687251,
+    536687273, 536687299, 536687303, 536687317, 536687329, 536687339,
+    536687383, 536687401, 536687449, 536687453, 536687483, 536687491,
+    536687507, 536687519, 536687521, 536687537, 536687539, 536687563,
+    536687579, 536687609, 536687611, 536687617, 536687707, 536687791,
+    536687861, 536687863, 536687873, 536687887, 536687917, 536687929,
+    536687941, 536687951, 536687969, 536688059, 536688107, 536688137,
+    536688161, 536688169, 536688179, 536688199, 536688241, 536688247,
+    536688259, 536688287, 536688311, 536688343, 536688389, 536688391,
+    536688403, 536688437, 536688457, 536688491, 536688511, 536688517,
+    536688533, 536688557, 536688569, 536688599, 536688617, 536688619,
+    536688637, 536688661, 536688667, 536688679, 536688701, 536688727,
+    536688743, 536688767, 536688769, 536688809, 536688829, 536688853,
+    536688857, 536688899, 536688931, 536688937, 536688947, 536688967,
+    536688973, 536688989, 536689001, 536689007, 536689037, 536689117,
+    536689123, 536689129, 536689169, 536689217, 536689243, 536689273,
+    536689277, 536689297, 536689301, 536689327, 536689331, 536689379,
+    536689421, 536689441, 536689451, 536689459, 536689463, 536689471,
+    536689499, 536689511, 536689553, 536689583, 536689693, 536689697,
+    536689709, 536689717, 536689721, 536689729, 536689753, 536689799,
+    536689807, 536689817, 536689823, 536689831, 536689841, 536689849,
+    536689859, 536689871, 536689873, 536689891, 536689913, 536689927,
+    536689939, 536689963, 536689987, 536690023, 536690029, 536690047,
+    536690053, 536690057, 536690083, 536690107, 536690111, 536690117,
+    536690129, 536690171, 536690177, 536690183, 536690191, 536690263,
+    536690293, 536690299, 536690317, 536690333, 536690387, 536690389,
+    536690411, 536690417, 536690423, 536690431, 536690471, 536690477,
+    536690489, 536690503, 536690543, 536690551, 536690573, 536690591,
+    536690593, 536690599, 536690639, 536690641, 536690653, 536690657,
+    536690659, 536690689, 536690719, 536690723, 536690729, 536690741,
+    536690743, 536690753, 536690761, 536690767, 536690789, 536690797,
+    536690801, 536690813, 536690851, 536690863, 536690897, 536690899,
+    536690911, 536690923, 536690927, 536690933, 536690977, 536690983,
+    536690989, 536691007, 536691019, 536691049, 536691083, 536691097,
+    536691121, 536691137, 536691151, 536691187, 536691191, 536691193,
+    536691209, 536691229, 536691277, 536691283, 536691289, 536691329,
+    536691341, 536691403, 536691413, 536691427, 536691431, 536691433,
+    536691439, 536691509, 536691511, 536691521, 536691539, 536691541,
+    536691559, 536691569, 536691587, 536691619, 536691629, 536691677,
+    536691721, 536691737, 536691761, 536691773, 536691781, 536691791,
+    536691823, 536691829, 536691863, 536691899, 536691931, 536691937,
+    536691943, 536691971, 536691973, 536691977, 536691997, 536692001,
+    536692081, 536692133, 536692139, 536692153, 536692171, 536692217,
+    536692223, 536692231, 536692249, 536692253, 536692271, 536692279,
+    536692283, 536692301, 536692307, 536692309, 536692313, 536692319,
+    536692361, 536692381, 536692421, 536692441, 536692451, 536692463,
+    536692477, 536692493, 536692523, 536692547, 536692571, 536692573,
+    536692613, 536692661, 536692687, 536692711, 536692769, 536692777,
+    536692811, 536692831, 536692841, 536692853, 536692901, 536692931,
+    536692939, 536692957, 536693021, 536693107, 536693117, 536693119,
+    536693123, 536693137, 536693159, 536693167, 536693197, 536693233,
+    536693257, 536693279, 536693291, 536693303, 536693309, 536693341,
+    536693347, 536693371, 536693429, 536693461, 536693501, 536693503,
+    536693533, 536693557, 536693561, 536693593, 536693623, 536693657,
+    536693681, 536693693, 536693701, 536693711, 536693777, 536693803,
+    536693819, 536693837, 536693881, 536693897, 536693909, 536693929,
+    536693939, 536693947, 536694001, 536694047, 536694049, 536694061,
+    536694101, 536694107, 536694157, 536694161, 536694203, 536694211,
+    536694229, 536694241, 536694251, 536694283, 536694331, 536694341,
+    536694359, 536694371, 536694391, 536694401, 536694419, 536694427,
+    536694449, 536694533, 536694553, 536694569, 536694601, 536694617,
+    536694649, 536694667, 536694671, 536694679, 536694689, 536694701,
+    536694721, 536694727, 536694749, 536694757, 536694779, 536694827,
+    536694853, 536694869, 536694883, 536694887, 536694901, 536694929,
+    536694931, 536694989, 536695037, 536695057, 536695069, 536695091,
+    536695099, 536695121, 536695123, 536695127, 536695129, 536695193,
+    536695217, 536695279, 536695297, 536695301, 536695309, 536695339,
+    536695387, 536695417, 536695433, 536695459, 536695463, 536695483,
+    536695487, 536695493, 536695553, 536695561, 536695567, 536695573,
+    536695597, 536695613, 536695631, 536695657, 536695667, 536695703,
+    536695711, 536695727, 536695741, 536695759, 536695787, 536695799,
+    536695813, 536695847, 536695853, 536695871, 536695889, 536695891,
+    536695937, 536695949, 536695979, 536695987, 536696071, 536696081,
+    536696093, 536696101, 536696113, 536696119, 536696131, 536696159,
+    536696207, 536696221, 536696227, 536696261, 536696269, 536696291,
+    536696297, 536696311, 536696317, 536696323, 536696339, 536696353,
+    536696357, 536696371, 536696393, 536696399, 536696411, 536696423,
+    536696449, 536696453, 536696471, 536696491, 536696543, 536696557,
+    536696569, 536696593, 536696609, 536696617, 536696621, 536696639,
+    536696701, 536696711, 536696747, 536696761, 536696773, 536696791,
+    536696843, 536696899, 536696903, 536696917, 536696969, 536696983,
+    536696989, 536697041, 536697059, 536697071, 536697097, 536697137,
+    536697163, 536697169, 536697179, 536697181, 536697193, 536697211,
+    536697221, 536697251, 536697263, 536697281, 536697283, 536697289,
+    536697299, 536697347, 536697349, 536697353, 536697367, 536697373,
+    536697379, 536697383, 536697401, 536697407, 536697439, 536697457,
+    536697467, 536697523, 536697529, 536697547, 536697587, 536697593,
+    536697611, 536697619, 536697641, 536697643, 536697649, 536697659,
+    536697673, 536697677, 536697697, 536697719, 536697737, 536697743,
+    536697757, 536697767, 536697773, 536697781, 536697787, 536697793,
+    536697827, 536697829, 536697853, 536697859, 536697869, 536697901,
+    536697923, 536697929, 536697937, 536697943, 536697949, 536697991,
+    536698013, 536698021, 536698033, 536698037, 536698039, 536698049,
+    536698103, 536698139, 536698147, 536698153, 536698163, 536698171,
+    536698181, 536698189, 536698219, 536698247, 536698259, 536698277,
+    536698291, 536698297, 536698333, 536698361, 536698363, 536698387,
+    536698433, 536698469, 536698471, 536698493, 536698507, 536698541,
+    536698549, 536698559, 536698573, 536698601, 536698627, 536698649,
+    536698663, 536698699, 536698709, 536698711, 536698717, 536698739,
+    536698759, 536698777, 536698787, 536698807, 536698861, 536698873,
+    536698889, 536698901, 536698913, 536698927, 536698931, 536698961,
+    536698991, 536699077, 536699083, 536699087, 536699173, 536699221,
+    536699239, 536699257, 536699269, 536699287, 536699309, 536699321,
+    536699353, 536699357, 536699369, 536699399, 536699407, 536699419,
+    536699453, 536699461, 536699473, 536699507, 536699509, 536699519,
+    536699539, 536699543, 536699551, 536699563, 536699573, 536699599,
+    536699659, 536699671, 536699701, 536699729, 536699749, 536699767,
+    536699771, 536699773, 536699791, 536699819, 536699833, 536699857,
+    536699879, 536699893, 536699903, 536699921, 536699927, 536699929,
+    536699951, 536699953, 536699957, 536699971, 536699983, 536700007,
+    536700019, 536700023, 536700037, 536700041, 536700067, 536700079,
+    536700107, 536700137, 536700169, 536700173, 536700181, 536700211,
+    536700221, 536700223, 536700247, 536700253, 536700257, 536700271,
+    536700287, 536700323, 536700347, 536700443, 536700449, 536700457,
+    536700481, 536700487, 536700491, 536700517, 536700529, 536700539,
+    536700547, 536700559, 536700583, 536700611, 536700629, 536700667,
+    536700677, 536700679, 536700707, 536700719, 536700743, 536700751,
+    536700817, 536700833, 536700839, 536700851, 536700859, 536700869,
+    536700877, 536700911, 536700937, 536700959, 536700973, 536700977,
+    536701007, 536701027, 536701043, 536701063, 536701069, 536701091,
+    536701127, 536701133, 536701163, 536701177, 536701181, 536701211,
+    536701213, 536701223, 536701247, 536701261, 536701301, 536701309,
+    536701327, 536701331, 536701337, 536701369, 536701387, 536701397,
+    536701409, 536701411, 536701421, 536701433, 536701453, 536701471,
+    536701483, 536701511, 536701519, 536701547, 536701549, 536701559,
+    536701591, 536701597, 536701639, 536701681, 536701699, 536701727,
+    536701751, 536701771, 536701783, 536701793, 536701799, 536701813,
+    536701817, 536701829, 536701843, 536701861, 536701889, 536701943,
+    536701969, 536702003, 536702011, 536702017, 536702027, 536702029,
+    536702051, 536702069, 536702081, 536702119, 536702123, 536702137,
+    536702141, 536702143, 536702161, 536702197, 536702209, 536702251,
+    536702273, 536702293, 536702297, 536702303, 536702311, 536702347,
+    536702357, 536702371, 536702377, 536702389, 536702399, 536702407,
+    536702417, 536702431, 536702437, 536702483, 536702489, 536702503,
+    536702513, 536702521, 536702533, 536702549, 536702591, 536702599,
+    536702611, 536702641, 536702657, 536702689, 536702701, 536702713,
+    536702731, 536702741, 536702743, 536702753, 536702759, 536702779,
+    536702819, 536702839, 536702893, 536702921, 536702927, 536702977,
+    536703001, 536703007, 536703023, 536703059, 536703077, 536703113,
+    536703121, 536703163, 536703173, 536703239, 536703257, 536703287,
+    536703313, 536703329, 536703337, 536703347, 536703421, 536703443,
+    536703457, 536703467, 536703473, 536703487, 536703491, 536703499,
+    536703509, 536703521, 536703523, 536703529, 536703533, 536703539,
+    536703631, 536703641, 536703649, 536703691, 536703721, 536703733,
+    536703751, 536703757, 536703767, 536703779, 536703809, 536703911,
+    536703913, 536703929, 536703931, 536703967, 536703977, 536703989,
+    536703997, 536704019, 536704097, 536704111, 536704121, 536704183,
+    536704187, 536704193, 536704211, 536704303, 536704307, 536704367,
+    536704369, 536704373, 536704387, 536704409, 536704417, 536704423,
+    536704429, 536704439, 536704451, 536704459, 536704463, 536704481,
+    536704513, 536704523, 536704529, 536704547, 536704559, 536704561,
+    536704579, 536704627, 536704631, 536704669, 536704699, 536704717,
+    536704759, 536704771, 536704787, 536704811, 536704823, 536704849,
+    536704867, 536704873, 536704877, 536704897, 536704937, 536704957,
+    536704967, 536704969, 536704997, 536704999, 536705033, 536705051,
+    536705053, 536705063, 536705089, 536705093, 536705119, 536705131,
+    536705153, 536705159, 536705203, 536705227, 536705237, 536705243,
+    536705251, 536705261, 536705287, 536705341, 536705353, 536705357,
+    536705371, 536705383, 536705441, 536705447, 536705479, 536705497,
+    536705503, 536705537, 536705551, 536705557, 536705579, 536705593,
+    536705641, 536705651, 536705669, 536705671, 536705723, 536705773,
+    536705791, 536705803, 536705839, 536705887, 536705891, 536705893,
+    536705909, 536705921, 536705993, 536706011, 536706041, 536706089,
+    536706097, 536706101, 536706151, 536706169, 536706197, 536706199,
+    536706229, 536706241, 536706251, 536706257, 536706307, 536706341,
+    536706361, 536706367, 536706419, 536706463, 536706481, 536706491,
+    536706589, 536706593, 536706601, 536706617, 536706641, 536706671,
+    536706691, 536706697, 536706701, 536706707, 536706727, 536706733,
+    536706739, 536706743, 536706749, 536706761, 536706763, 536706767,
+    536706773, 536706787, 536706839, 536706883, 536706887, 536706899,
+    536706931, 536706943, 536706979, 536707009, 536707019, 536707021,
+    536707027, 536707043, 536707049, 536707057, 536707063, 536707109,
+    536707121, 536707151, 536707159, 536707177, 536707181, 536707183,
+    536707229, 536707253, 536707279, 536707313, 536707333, 536707351,
+    536707361, 536707363, 536707373, 536707417, 536707427, 536707447,
+    536707477, 536707481, 536707487, 536707511, 536707541, 536707583,
+    536707651, 536707657, 536707741, 536707781, 536707789, 536707807,
+    536707817, 536707823, 536707861, 536707879, 536707889, 536707891,
+    536707937, 536707949, 536707973, 536707979, 536708009, 536708047,
+    536708057, 536708063, 536708083, 536708089, 536708093, 536708101,
+    536708113, 536708141, 536708153, 536708167, 536708171, 536708189,
+    536708201, 536708287, 536708297, 536708311, 536708321, 536708399,
+    536708401, 536708407, 536708429, 536708437, 536708443, 536708449,
+    536708467, 536708503, 536708521, 536708527, 536708533, 536708551,
+    536708563, 536708639, 536708707, 536708719, 536708729, 536708747,
+    536708761, 536708801, 536708803, 536708807, 536708833, 536708881,
+    536708911, 536708917, 536708923, 536708947, 536708969, 536708999,
+    536709037, 536709059, 536709073, 536709077, 536709083, 536709127,
+    536709143, 536709149, 536709179, 536709181, 536709203, 536709211,
+    536709221, 536709263, 536709269, 536709281, 536709307, 536709337,
+    536709343, 536709379, 536709421, 536709469, 536709529, 536709559,
+    536709571, 536709599, 536709629, 536709637, 536709643, 536709653,
+    536709671, 536709673, 536709683, 536709689, 536709697, 536709749,
+    536709791, 536709829, 536709857, 536709863, 536709869, 536709871,
+    536709883, 536709893, 536709911, 536709917, 536709919, 536709977,
+    536710039, 536710051, 536710067, 536710093, 536710103, 536710117,
+    536710127, 536710151, 536710169, 536710189, 536710193, 536710201,
+    536710217, 536710243, 536710253, 536710259, 536710261, 536710289,
+    536710303, 536710327, 536710373, 536710393, 536710403, 536710457,
+    536710463, 536710483, 536710487, 536710507, 536710549, 536710561,
+    536710579, 536710591, 536710597, 536710631, 536710633, 536710679,
+    536710687, 536710693, 536710711, 536710717, 536710721, 536710747,
+    536710771, 536710777, 536710829, 536710871, 536710883, 536710897,
+    536710903, 536710921, 536710973, 536710987, 536711027, 536711039,
+    536711051, 536711057, 536711059, 536711083, 536711089, 536711099,
+    536711101, 536711137, 536711167, 536711179, 536711209, 536711237,
+    536711243, 536711249, 536711269, 536711291, 536711293, 536711317,
+    536711321, 536711333, 536711353, 536711359, 536711393, 536711407,
+    536711419, 536711431, 536711453, 536711459, 536711501, 536711503,
+    536711519, 536711533, 536711569, 536711621, 536711629, 536711653,
+    536711657, 536711687, 536711699, 536711713, 536711737, 536711783,
+    536711789, 536711803, 536711807, 536711809, 536711837, 536711839,
+    536711863, 536711869, 536711873, 536711881, 536711909, 536711911,
+    536711921, 536711927, 536711957, 536711971, 536711993, 536711999,
+    536712037, 536712041, 536712067, 536712073, 536712089, 536712103,
+    536712131, 536712139, 536712149, 536712157, 536712161, 536712167,
+    536712191, 536712233, 536712257, 536712289, 536712299, 536712301,
+    536712329, 536712373, 536712377, 536712391, 536712409, 536712413,
+    536712461, 536712487, 536712493, 536712511, 536712563, 536712577,
+    536712581, 536712601, 536712623, 536712647, 536712667, 536712689,
+    536712691, 536712697, 536712719, 536712721, 536712727, 536712731,
+    536712769, 536712811, 536712853, 536712887, 536712901, 536712949,
+    536712961, 536712977, 536712991, 536712997, 536713031, 536713039,
+    536713087, 536713127, 536713141, 536713183, 536713201, 536713207,
+    536713213, 536713223, 536713241, 536713249, 536713253, 536713259,
+    536713267, 536713279, 536713321, 536713339, 536713357, 536713361,
+    536713363, 536713367, 536713381, 536713417, 536713423, 536713433,
+    536713481, 536713517, 536713519, 536713531, 536713559, 536713589,
+    536713621, 536713627, 536713673, 536713679, 536713687, 536713693,
+    536713733, 536713741, 536713747, 536713777, 536713781, 536713789,
+    536713829, 536713841, 536713847, 536713861, 536713867, 536713873,
+    536713907, 536713909, 536713927, 536713949, 536713963, 536713967,
+    536713979, 536713981, 536713997, 536713999, 536714023, 536714041,
+    536714081, 536714083, 536714111, 536714117, 536714141, 536714201,
+    536714203, 536714207, 536714221, 536714237, 536714251, 536714263,
+    536714309, 536714317, 536714329, 536714359, 536714363, 536714419,
+    536714441, 536714443, 536714509, 536714543, 536714557, 536714569,
+    536714579, 536714597, 536714609, 536714621, 536714627, 536714653,
+    536714669, 536714671, 536714713, 536714719, 536714807, 536714813,
+    536714819, 536714833, 536714851, 536714881, 536714947, 536714989,
+    536714993, 536714999, 536715013, 536715029, 536715071, 536715073,
+    536715079, 536715119, 536715131, 536715163, 536715167, 536715169,
+    536715187, 536715197, 536715203, 536715217, 536715227, 536715239,
+    536715251, 536715269, 536715323, 536715331, 536715353, 536715367,
+    536715391, 536715397, 536715407, 536715427, 536715463, 536715467,
+    536715469, 536715497, 536715523, 536715533, 536715541, 536715547,
+    536715563, 536715581, 536715601, 536715611, 536715623, 536715659,
+    536715661, 536715677, 536715703, 536715713, 536715737, 536715749,
+    536715757, 536715763, 536715769, 536715793, 536715827, 536715859,
+    536715863, 536715887, 536715911, 536715937, 536715943, 536716073,
+    536716087, 536716093, 536716099, 536716139, 536716181, 536716183,
+    536716189, 536716249, 536716259, 536716261, 536716273, 536716277,
+    536716289, 536716291, 536716331, 536716337, 536716357, 536716373,
+    536716381, 536716393, 536716403, 536716409, 536716421, 536716459,
+    536716483, 536716489, 536716501, 536716511, 536716529, 536716549,
+    536716559, 536716567, 536716573, 536716633, 536716651, 536716679,
+    536716729, 536716751, 536716759, 536716771, 536716819, 536716823,
+    536716853, 536716861, 536716889, 536716897, 536716913, 536716933,
+    536716969, 536716991, 536717011, 536717021, 536717023, 536717033,
+    536717039, 536717053, 536717057, 536717059, 536717119, 536717143,
+    536717161, 536717173, 536717189, 536717191, 536717197, 536717249,
+    536717257, 536717261, 536717267, 536717287, 536717303, 536717317,
+    536717371, 536717381, 536717411, 536717431, 536717479, 536717483,
+    536717497, 536717521, 536717537, 536717543, 536717561, 536717563,
+    536717579, 536717603, 536717617, 536717647, 536717651, 536717669,
+    536717683, 536717743, 536717747, 536717809, 536717821, 536717851,
+    536717869, 536717879, 536717917, 536717927, 536717933, 536717941,
+    536717981, 536717989, 536718019, 536718031, 536718043, 536718047,
+    536718073, 536718079, 536718107, 536718113, 536718151, 536718191,
+    536718211, 536718229, 536718233, 536718241, 536718253, 536718257,
+    536718277, 536718293, 536718311, 536718349, 536718359, 536718361,
+    536718367, 536718431, 536718463, 536718503, 536718551, 536718569,
+    536718599, 536718601, 536718617, 536718643, 536718649, 536718661,
+    536718691, 536718701, 536718769, 536718773, 536718797, 536718799,
+    536718827, 536718857, 536718881, 536718887, 536718901, 536718913,
+    536718937, 536718947, 536718953, 536718967, 536718971, 536718997,
+    536719013, 536719061, 536719063, 536719097, 536719103, 536719109,
+    536719123, 536719133, 536719147, 536719159, 536719177, 536719187,
+    536719219, 536719231, 536719243, 536719247, 536719259, 536719321,
+    536719349, 536719361, 536719363, 536719387, 536719411, 536719453,
+    536719457, 536719471, 536719487, 536719489, 536719553, 536719577,
+    536719591, 536719607, 536719609, 536719613, 536719621, 536719633,
+    536719691, 536719753, 536719763, 536719769, 536719787, 536719819,
+    536719861, 536719879, 536719901, 536719933, 536719951, 536720003,
+    536720011, 536720057, 536720087, 536720099, 536720101, 536720117,
+    536720137, 536720147, 536720153, 536720179, 536720221, 536720237,
+    536720257, 536720263, 536720269, 536720287, 536720291, 536720293,
+    536720297, 536720321, 536720333, 536720339, 536720351, 536720399,
+    536720411, 536720419, 536720423, 536720449, 536720461, 536720491,
+    536720501, 536720521, 536720593, 536720609, 536720677, 536720689,
+    536720713, 536720731, 536720809, 536720827, 536720831, 536720837,
+    536720851, 536720869, 536720897, 536720917, 536720941, 536720953,
+    536720963, 536720999, 536721007, 536721013, 536721019, 536721043,
+    536721047, 536721049, 536721061, 536721091, 536721137, 536721179,
+    536721187, 536721271, 536721287, 536721337, 536721377, 536721379,
+    536721391, 536721401, 536721421, 536721457, 536721461, 536721463,
+    536721469, 536721487, 536721499, 536721509, 536721517, 536721539,
+    536721547, 536721551, 536721587, 536721599, 536721617, 536721641,
+    536721649, 536721677, 536721697, 536721707, 536721781, 536721793,
+    536721827, 536721833, 536721847, 536721853, 536721869, 536721881,
+    536721883, 536721917, 536721923, 536721929, 536721961, 536721967,
+    536721973, 536722007, 536722057, 536722063, 536722091, 536722099,
+    536722117, 536722133, 536722139, 536722159, 536722163, 536722171,
+    536722201, 536722223, 536722237, 536722253, 536722261, 536722301,
+    536722309, 536722321, 536722331, 536722357, 536722367, 536722369,
+    536722387, 536722399, 536722423, 536722429, 536722463, 536722471,
+    536722489, 536722493, 536722523, 536722531, 536722547, 536722567,
+    536722577, 536722601, 536722607, 536722661, 536722673, 536722699,
+    536722727, 536722783, 536722799, 536722829, 536722859, 536722873,
+    536722889, 536722897, 536722909, 536722943, 536722951, 536722961,
+    536722969, 536722973, 536723023, 536723051, 536723071, 536723081,
+    536723093, 536723129, 536723203, 536723237, 536723263, 536723279,
+    536723281, 536723287, 536723321, 536723339, 536723347, 536723351,
+    536723353, 536723357, 536723417, 536723431, 536723437, 536723461,
+    536723477, 536723483, 536723563, 536723573, 536723581, 536723617,
+    536723639, 536723641, 536723657, 536723659, 536723687, 536723713,
+    536723729, 536723731, 536723741, 536723749, 536723771, 536723809,
+    536723819, 536723903, 536723923, 536723963, 536723969, 536724007,
+    536724029, 536724031, 536724073, 536724077, 536724079, 536724101,
+    536724127, 536724143, 536724169, 536724191, 536724193, 536724211,
+    536724229, 536724233, 536724263, 536724271, 536724277, 536724313,
+    536724361, 536724367, 536724401, 536724413, 536724437, 536724449,
+    536724457, 536724467, 536724469, 536724497, 536724509, 536724511,
+    536724541, 536724569, 536724577, 536724599, 536724637, 536724649,
+    536724653, 536724659, 536724677, 536724719, 536724751, 536724761,
+    536724781, 536724791, 536724817, 536724847, 536724857, 536724869,
+    536724883, 536724919, 536724931, 536724943, 536724949, 536724961,
+    536724971, 536724983, 536724989, 536725039, 536725043, 536725051,
+    536725073, 536725081, 536725099, 536725157, 536725159, 536725169,
+    536725177, 536725187, 536725229, 536725297, 536725303, 536725307,
+    536725313, 536725327, 536725333, 536725339, 536725349, 536725361,
+    536725439, 536725451, 536725457, 536725459, 536725489, 536725499,
+    536725507, 536725517, 536725531, 536725561, 536725577, 536725597,
+    536725619, 536725621, 536725627, 536725633, 536725643, 536725669,
+    536725691, 536725703, 536725729, 536725741, 536725771, 536725801,
+    536725807, 536725829, 536725831, 536725841, 536725873, 536725879,
+    536725913, 536725961, 536725963, 536725979, 536726059, 536726077,
+    536726081, 536726087, 536726119, 536726131, 536726147, 536726153,
+    536726173, 536726191, 536726207, 536726209, 536726279, 536726297,
+    536726299, 536726341, 536726353, 536726357, 536726419, 536726501,
+    536726503, 536726527, 536726539, 536726621, 536726623, 536726629,
+    536726633, 536726647, 536726651, 536726657, 536726683, 536726713,
+    536726759, 536726779, 536726797, 536726803, 536726807, 536726821,
+    536726837, 536726851, 536726891, 536726893, 536726909, 536726987,
+    536727001, 536727013, 536727097, 536727119, 536727167, 536727193,
+    536727203, 536727209, 536727239, 536727251, 536727271, 536727277,
+    536727299, 536727311, 536727337, 536727341, 536727407, 536727413,
+    536727461, 536727467, 536727469, 536727509, 536727533, 536727547,
+    536727557, 536727577, 536727589, 536727601, 536727619, 536727629,
+    536727649, 536727691, 536727727, 536727731, 536727787, 536727799,
+    536727803, 536727811, 536727823, 536727847, 536727857, 536727871,
+    536727907, 536727913, 536728001, 536728019, 536728061, 536728103,
+    536728151, 536728177, 536728187, 536728211, 536728229, 536728249,
+    536728271, 536728277, 536728307, 536728333, 536728337, 536728351,
+    536728373, 536728393, 536728411, 536728429, 536728441, 536728453,
+    536728501, 536728541, 536728567, 536728603, 536728609, 536728613,
+    536728627, 536728639, 536728649, 536728657, 536728669, 536728681,
+    536728711, 536728729, 536728757, 536728769, 536728783, 536728807,
+    536728817, 536728849, 536728883, 536728889, 536728921, 536728939,
+    536728949, 536728979, 536729003, 536729107, 536729159, 536729177,
+    536729183, 536729197, 536729201, 536729209, 536729267, 536729279,
+    536729293, 536729317, 536729339, 536729353, 536729371, 536729383,
+    536729393, 536729411, 536729447, 536729471, 536729489, 536729527,
+    536729539, 536729551, 536729573, 536729579, 536729581, 536729597,
+    536729621, 536729639, 536729657, 536729693, 536729717, 536729723,
+    536729747, 536729759, 536729761, 536729779, 536729819, 536729833,
+    536729839, 536729861, 536729873, 536729891, 536729929, 536729957,
+    536729959, 536729983, 536730011, 536730023, 536730037, 536730043,
+    536730113, 536730119, 536730143, 536730163, 536730169, 536730193,
+    536730211, 536730223, 536730281, 536730283, 536730301, 536730317,
+    536730329, 536730353, 536730371, 536730401, 536730419, 536730433,
+    536730479, 536730533, 536730541, 536730583, 536730653, 536730659,
+    536730673, 536730697, 536730709, 536730721, 536730731, 536730739,
+    536730743, 536730757, 536730763, 536730767, 536730781, 536730793,
+    536730809, 536730839, 536730853, 536730893, 536730907, 536730911,
+    536730941, 536731049, 536731067, 536731073, 536731079, 536731087,
+    536731093, 536731099, 536731177, 536731183, 536731193, 536731199,
+    536731219, 536731229, 536731231, 536731277, 536731297, 536731309,
+    536731331, 536731373, 536731379, 536731397, 536731417, 536731423,
+    536731469, 536731471, 536731483, 536731523, 536731541, 536731549,
+    536731561, 536731567, 536731571, 536731579, 536731603, 536731607,
+    536731651, 536731669, 536731687, 536731691, 536731709, 536731711,
+    536731721, 536731751, 536731753, 536731771, 536731801, 536731849,
+    536731873, 536731889, 536731903, 536731919, 536731999, 536732017,
+    536732059, 536732069, 536732081, 536732089, 536732093, 536732123,
+    536732129, 536732173, 536732179, 536732221, 536732227, 536732257,
+    536732267, 536732291, 536732297, 536732303, 536732309, 536732341,
+    536732447, 536732461, 536732491, 536732503, 536732519, 536732533,
+    536732549, 536732561, 536732563, 536732569, 536732587, 536732591,
+    536732593, 536732597, 536732639, 536732663, 536732683, 536732699,
+    536732701, 536732723, 536732731, 536732747, 536732759, 536732821,
+    536732827, 536732831, 536732879, 536732893, 536732909, 536732939,
+    536732953, 536732981, 536733013, 536733023, 536733053, 536733059,
+    536733077, 536733097, 536733121, 536733143, 536733187, 536733203,
+    536733227, 536733251, 536733259, 536733271, 536733289, 536733317,
+    536733341, 536733343, 536733383, 536733403, 536733427, 536733437,
+    536733481, 536733511, 536733521, 536733529, 536733539, 536733551,
+    536733557, 536733569, 536733607, 536733661, 536733671, 536733677,
+    536733733, 536733737, 536733761, 536733763, 536733779, 536733787,
+    536733823, 536733839, 536733863, 536733871, 536733929, 536733947,
+    536733949, 536733971, 536733997, 536734027, 536734039, 536734073,
+    536734091, 536734103, 536734129, 536734153, 536734193, 536734223,
+    536734229, 536734259, 536734277, 536734333, 536734343, 536734399,
+    536734423, 536734427, 536734441, 536734507, 536734529, 536734531,
+    536734537, 536734571, 536734579, 536734607, 536734609, 536734613,
+    536734619, 536734621, 536734633, 536734637, 536734663, 536734673,
+    536734699, 536734717, 536734733, 536734747, 536734753, 536734771,
+    536734777, 536734799, 536734811, 536734823, 536734841, 536734883,
+    536734889, 536734921, 536734943, 536734949, 536734951, 536734963,
+    536734973, 536734981, 536734997, 536735029, 536735041, 536735053,
+    536735077, 536735099, 536735113, 536735117, 536735131, 536735179,
+    536735183, 536735189, 536735233, 536735239, 536735249, 536735261,
+    536735263, 536735299, 536735323, 536735327, 536735359, 536735447,
+    536735453, 536735477, 536735483, 536735489, 536735491, 536735531,
+    536735533, 536735539, 536735561, 536735597, 536735609, 536735627,
+    536735677, 536735701, 536735711, 536735791, 536735813, 536735831,
+    536735833, 536735863, 536735873, 536735893, 536735897, 536735957,
+    536735999, 536736001, 536736007, 536736041, 536736059, 536736061,
+    536736091, 536736113, 536736131, 536736169, 536736173, 536736181,
+    536736199, 536736203, 536736217, 536736229, 536736259, 536736269,
+    536736283, 536736329, 536736331, 536736341, 536736373, 536736391,
+    536736413, 536736419, 536736433, 536736443, 536736463, 536736481,
+    536736521, 536736559, 536736587, 536736589, 536736619, 536736647,
+    536736649, 536736653, 536736709, 536736721, 536736749, 536736769,
+    536736797, 536736817, 536736877, 536736881, 536736919, 536736923,
+    536736943, 536736973, 536736997, 536737001, 536737021, 536737057,
+    536737063, 536737079, 536737081, 536737087, 536737121, 536737127,
+    536737151, 536737163, 536737199, 536737211, 536737247, 536737291,
+    536737303, 536737319, 536737363, 536737381, 536737463, 536737477,
+    536737507, 536737529, 536737571, 536737589, 536737609, 536737633,
+    536737639, 536737667, 536737673, 536737679, 536737681, 536737699,
+    536737703, 536737727, 536737801, 536737807, 536737823, 536737879,
+    536737891, 536737933, 536737987, 536738017, 536738023, 536738029,
+    536738057, 536738063, 536738117, 536738129, 536738131, 536738141,
+    536738159, 536738171, 536738173, 536738197, 536738219, 536738221,
+    536738227, 536738233, 536738249, 536738291, 536738303, 536738333,
+    536738369, 536738393, 536738437, 536738491, 536738497, 536738591,
+    536738611, 536738623, 536738669, 536738689, 536738693, 536738701,
+    536738707, 536738729, 536738759, 536738767, 536738777, 536738801,
+    536738803, 536738819, 536738821, 536738837, 536738861, 536738863,
+    536738869, 536738887, 536738893, 536738903, 536738933, 536738963,
+    536738981, 536739001, 536739059, 536739083, 536739089, 536739097,
+    536739101, 536739179, 536739191, 536739209, 536739257, 536739263,
+    536739311, 536739319, 536739347, 536739361, 536739367, 536739377,
+    536739403, 536739433, 536739443, 536739449, 536739451, 536739547,
+    536739551, 536739557, 536739587, 536739601, 536739629, 536739641,
+    536739659, 536739737, 536739751, 536739757, 536739761, 536739767,
+    536739769, 536739773, 536739787, 536739811, 536739821, 536739839,
+    536739883, 536739899, 536739923, 536739967, 536739977, 536739989,
+    536740003, 536740007, 536740079, 536740103, 536740109, 536740117,
+    536740151, 536740153, 536740187, 536740199, 536740219, 536740249,
+    536740297, 536740301, 536740363, 536740387, 536740409, 536740441,
+    536740459, 536740483, 536740511, 536740513, 536740531, 536740543,
+    536740573, 536740579, 536740583, 536740591, 536740597, 536740619,
+    536740637, 536740639, 536740649, 536740661, 536740669, 536740679,
+    536740681, 536740691, 536740693, 536740697, 536740723, 536740739,
+    536740741, 536740793, 536740801, 536740807, 536740829, 536740837,
+    536740843, 536740849, 536740859, 536740871, 536740879, 536740909,
+    536740943, 536740951, 536740991, 536740999, 536741003, 536741011,
+    536741047, 536741063, 536741071, 536741131, 536741141, 536741143,
+    536741189, 536741207, 536741213, 536741267, 536741281, 536741311,
+    536741339, 536741341, 536741369, 536741377, 536741383, 536741389,
+    536741399, 536741417, 536741419, 536741461, 536741519, 536741531,
+    536741539, 536741581, 536741603, 536741627, 536741641, 536741651,
+    536741707, 536741749, 536741797, 536741801, 536741813, 536741819,
+    536741873, 536741893, 536741903, 536741911, 536741921, 536741941,
+    536741951, 536741981, 536741983, 536741999, 536742043, 536742047,
+    536742083, 536742097, 536742113, 536742119, 536742131, 536742163,
+    536742169, 536742197, 536742221, 536742251, 536742257, 536742307,
+    536742317, 536742319, 536742331, 536742341, 536742347, 536742359,
+    536742389, 536742391, 536742413, 536742431, 536742497, 536742517,
+    536742541, 536742617, 536742629, 536742631, 536742653, 536742659,
+    536742673, 536742677, 536742733, 536742769, 536742779, 536742781,
+    536742797, 536742803, 536742841, 536742859, 536742901, 536742907,
+    536742917, 536742919, 536742929, 536742949, 536742953, 536742967,
+    536742977, 536743007, 536743099, 536743117, 536743133, 536743153,
+    536743183, 536743199, 536743219, 536743267, 536743271, 536743297,
+    536743303, 536743307, 536743309, 536743327, 536743343, 536743421,
+    536743429, 536743447, 536743463, 536743469, 536743489, 536743507,
+    536743531, 536743541, 536743547, 536743621, 536743631, 536743661,
+    536743679, 536743681, 536743717, 536743721, 536743723, 536743733,
+    536743799, 536743849, 536743877, 536743897, 536743927, 536743937,
+    536743957, 536743979, 536744003, 536744023, 536744027, 536744051,
+    536744057, 536744069, 536744071, 536744141, 536744177, 536744203,
+    536744233, 536744251, 536744269, 536744287, 536744293, 536744347,
+    536744393, 536744419, 536744431, 536744501, 536744503, 536744531,
+    536744539, 536744561, 536744569, 536744573, 536744581, 536744599,
+    536744617, 536744641, 536744651, 536744669, 536744683, 536744693,
+    536744711, 536744749, 536744753, 536744759, 536744777, 536744779,
+    536744797, 536744801, 536744807, 536744861, 536744863, 536744909,
+    536744911, 536744921, 536744933, 536744947, 536744969, 536744987,
+    536745023, 536745031, 536745047, 536745059, 536745061, 536745071,
+    536745101, 536745113, 536745119, 536745127, 536745149, 536745173,
+    536745179, 536745203, 536745247, 536745263, 536745281, 536745289,
+    536745299, 536745337, 536745343, 536745353, 536745373, 536745397,
+    536745401, 536745409, 536745413, 536745467, 536745481, 536745487,
+    536745533, 536745553, 536745577, 536745617, 536745619, 536745631,
+    536745689, 536745721, 536745731, 536745761, 536745799, 536745841,
+    536745863, 536745899, 536745929, 536745943, 536745967, 536745971,
+    536745973, 536746027, 536746037, 536746051, 536746079, 536746097,
+    536746103, 536746109, 536746141, 536746159, 536746163, 536746201,
+    536746207, 536746247, 536746277, 536746319, 536746337, 536746349,
+    536746351, 536746363, 536746387, 536746391, 536746403, 536746417,
+    536746429, 536746433, 536746453, 536746477, 536746487, 536746499,
+    536746519, 536746543, 536746547, 536746583, 536746591, 536746601,
+    536746603, 536746633, 536746643, 536746649, 536746663, 536746669,
+    536746681, 536746709, 536746711, 536746757, 536746781, 536746829,
+    536746841, 536746843, 536746853, 536746871, 536746913, 536746919,
+    536746943, 536747011, 536747023, 536747033, 536747053, 536747077,
+    536747083, 536747129, 536747147, 536747153, 536747177, 536747179,
+    536747209, 536747213, 536747219, 536747221, 536747261, 536747279,
+    536747287, 536747293, 536747303, 536747311, 536747329, 536747381,
+    536747411, 536747413, 536747429, 536747437, 536747459, 536747461,
+    536747467, 536747503, 536747513, 536747521, 536747531, 536747539,
+    536747557, 536747569, 536747591, 536747597, 536747599, 536747639,
+    536747693, 536747767, 536747773, 536747791, 536747797, 536747807,
+    536747819, 536747821, 536747837, 536747867, 536747881, 536747909,
+    536747917, 536747927, 536747947, 536747971, 536747999, 536748071,
+    536748077, 536748109, 536748127, 536748133, 536748137, 536748151,
+    536748169, 536748209, 536748221, 536748227, 536748241, 536748283,
+    536748299, 536748313, 536748337, 536748379, 536748397, 536748431,
+    536748451, 536748469, 536748481, 536748503, 536748533, 536748551,
+    536748557, 536748581, 536748593, 536748683, 536748703, 536748713,
+    536748739, 536748743, 536748767, 536748811, 536748827, 536748847,
+    536748887, 536748929, 536748959, 536748997, 536749013, 536749033,
+    536749039, 536749043, 536749061, 536749063, 536749067, 536749093,
+    536749123, 536749133, 536749201, 536749219, 536749243, 536749247,
+    536749253, 536749267, 536749289, 536749333, 536749361, 536749379,
+    536749387, 536749399, 536749439, 536749457, 536749471, 536749481,
+    536749489, 536749519, 536749547, 536749571, 536749589, 536749637,
+    536749679, 536749691, 536749711, 536749723, 536749739, 536749747,
+    536749769, 536749783, 536749793, 536749813, 536749859, 536749883,
+    536749933, 536749979, 536749987, 536750003, 536750017, 536750021,
+    536750023, 536750047, 536750059, 536750063, 536750077, 536750087,
+    536750101, 536750107, 536750119, 536750141, 536750153, 536750167,
+    536750173, 536750219, 536750233, 536750243, 536750257, 536750303,
+    536750321, 536750341, 536750363, 536750377, 536750419, 536750429,
+    536750443, 536750449, 536750479, 536750507, 536750579, 536750587,
+    536750603, 536750611, 536750629, 536750633, 536750659, 536750689,
+    536750713, 536750737, 536750743, 536750759, 536750777, 536750783,
+    536750801, 536750899, 536750909, 536750927, 536750939, 536750941,
+    536750947, 536750953, 536750993, 536751031, 536751037, 536751071,
+    536751091, 536751107, 536751109, 536751113, 536751133, 536751167,
+    536751199, 536751203, 536751209, 536751247, 536751263, 536751361,
+    536751367, 536751389, 536751431, 536751451, 536751569, 536751581,
+    536751583, 536751599, 536751601, 536751619, 536751629, 536751641,
+    536751661, 536751689, 536751707, 536751737, 536751769, 536751773,
+    536751779, 536751781, 536751821, 536751827, 536751841, 536751877,
+    536751883, 536751959, 536751961, 536751967, 536751973, 536751983,
+    536752001, 536752009, 536752037, 536752043, 536752057, 536752091,
+    536752093, 536752103, 536752129, 536752133, 536752141, 536752193,
+    536752199, 536752201, 536752241, 536752243, 536752277, 536752309,
+    536752327, 536752367, 536752379, 536752393, 536752399, 536752409,
+    536752417, 536752421, 536752459, 536752487, 536752523, 536752589,
+    536752597, 536752613, 536752621, 536752637, 536752663, 536752709,
+    536752729, 536752739, 536752751, 536752753, 536752759, 536752837,
+    536752841, 536752873, 536752877, 536752891, 536752897, 536752901,
+    536752919, 536752921, 536752933, 536752943, 536752963, 536752999,
+    536753011, 536753027, 536753029, 536753033, 536753069, 536753081,
+    536753111, 536753123, 536753137, 536753167, 536753183, 536753237,
+    536753293, 536753299, 536753303, 536753309, 536753311, 536753317,
+    536753351, 536753377, 536753389, 536753407, 536753411, 536753417,
+    536753423, 536753429, 536753467, 536753473, 536753501, 536753519,
+    536753543, 536753587, 536753603, 536753611, 536753617, 536753627,
+    536753653, 536753687, 536753741, 536753759, 536753761, 536753773,
+    536753803, 536753839, 536753851, 536753863, 536753873, 536753879,
+    536753923, 536753939, 536753941, 536753957, 536753963, 536754007,
+    536754017, 536754061, 536754091, 536754103, 536754109, 536754131,
+    536754157, 536754167, 536754187, 536754191, 536754193, 536754223,
+    536754263, 536754287, 536754319, 536754331, 536754343, 536754347,
+    536754349, 536754401, 536754403, 536754419, 536754431, 536754457,
+    536754469, 536754499, 536754557, 536754563, 536754571, 536754587,
+    536754601, 536754607, 536754613, 536754637, 536754653, 536754697,
+    536754727, 536754761, 536754763, 536754791, 536754917, 536754929,
+    536754947, 536754961, 536754973, 536754983, 536754989, 536755001,
+    536755013, 536755031, 536755039, 536755069, 536755081, 536755091,
+    536755099, 536755103, 536755133, 536755147, 536755169, 536755199,
+    536755207, 536755259, 536755277, 536755333, 536755363, 536755447,
+    536755487, 536755493, 536755507, 536755517, 536755553, 536755621,
+    536755679, 536755691, 536755697, 536755699, 536755711, 536755717,
+    536755741, 536755759, 536755777, 536755847, 536755873, 536755883,
+    536755907, 536755913, 536755927, 536755931, 536755939, 536755949,
+    536755951, 536755993, 536756021, 536756029, 536756039, 536756047,
+    536756053, 536756071, 536756089, 536756111, 536756167, 536756173,
+    536756183, 536756197, 536756219, 536756243, 536756261, 536756287,
+    536756291, 536756323, 536756333, 536756393, 536756399, 536756417,
+    536756431, 536756443, 536756471, 536756489, 536756503, 536756509,
+    536756527, 536756533, 536756567, 536756569, 536756639, 536756653,
+    536756677, 536756683, 536756699, 536756711, 536756729, 536756771,
+    536756797, 536756813, 536756837, 536756849, 536756851, 536756863,
+    536756879, 536756921, 536756939, 536756977, 536757007, 536757037,
+    536757041, 536757059, 536757107, 536757121, 536757139, 536757149,
+    536757217, 536757223, 536757229, 536757241, 536757271, 536757283,
+    536757313, 536757323, 536757359, 536757383, 536757401, 536757407,
+    536757443, 536757449, 536757469, 536757479, 536757493, 536757497,
+    536757503, 536757517, 536757547, 536757583, 536757587, 536757589,
+    536757623, 536757629, 536757707, 536757713, 536757721, 536757731,
+    536757757, 536757791, 536757811, 536757827, 536757829, 536757841,
+    536757857, 536757887, 536757899, 536757919, 536757953, 536758043,
+    536758069, 536758081, 536758099, 536758109, 536758111, 536758147,
+    536758177, 536758181, 536758193, 536758213, 536758219, 536758231,
+    536758241, 536758247, 536758279, 536758301, 536758307, 536758363,
+    536758381, 536758393, 536758423, 536758447, 536758457, 536758463,
+    536758489, 536758543, 536758559, 536758591, 536758603, 536758631,
+    536758679, 536758681, 536758699, 536758727, 536758763, 536758771,
+    536758777, 536758787, 536758819, 536758841, 536758861, 536758877,
+    536758879, 536758897, 536758907, 536758913, 536758961, 536758967,
+    536759009, 536759011, 536759029, 536759033, 536759053, 536759081,
+    536759137, 536759189, 536759213, 536759261, 536759263, 536759281,
+    536759339, 536759369, 536759381, 536759383, 536759387, 536759393,
+    536759429, 536759449, 536759453, 536759473, 536759477, 536759501,
+    536759507, 536759527, 536759569, 536759609, 536759647, 536759653,
+    536759681, 536759687, 536759719, 536759723, 536759749, 536759771,
+    536759791, 536759807, 536759813, 536759833, 536759843, 536759863,
+    536759893, 536759903, 536759911, 536759917, 536759941, 536759969,
+    536760001, 536760017, 536760019, 536760031, 536760047, 536760053,
+    536760079, 536760121, 536760137, 536760139, 536760143, 536760173,
+    536760181, 536760197, 536760239, 536760281, 536760307, 536760337,
+    536760349, 536760373, 536760377, 536760401, 536760409, 536760437,
+    536760451, 536760463, 536760481, 536760487, 536760491, 536760493,
+    536760527, 536760541, 536760551, 536760563, 536760613, 536760617,
+    536760641, 536760647, 536760649, 536760661, 536760673, 536760713,
+    536760761, 536760803, 536760817, 536760823, 536760853, 536760859,
+    536760893, 536760947, 536760977, 536760989, 536761007, 536761013,
+    536761019, 536761031, 536761037, 536761061, 536761067, 536761073,
+    536761079, 536761123, 536761259, 536761271, 536761273, 536761283,
+    536761297, 536761333, 536761367, 536761397, 536761399, 536761411,
+    536761483, 536761487, 536761499, 536761507, 536761529, 536761543,
+    536761549, 536761567, 536761579, 536761583, 536761591, 536761597,
+    536761601, 536761613, 536761619, 536761661, 536761679, 536761681,
+    536761721, 536761727, 536761739, 536761777, 536761781, 536761789,
+    536761811, 536761829, 536761831, 536761853, 536761871, 536761877,
+    536761891, 536761903, 536761909, 536761933, 536761963, 536761987,
+    536762033, 536762047, 536762069, 536762087, 536762099, 536762101,
+    536762113, 536762129, 536762173, 536762221, 536762243, 536762273,
+    536762299, 536762309, 536762311, 536762327, 536762341, 536762351,
+    536762371, 536762377, 536762389, 536762399, 536762449, 536762461,
+    536762491, 536762497, 536762531, 536762533, 536762557, 536762563,
+    536762599, 536762621, 536762623, 536762651, 536762719, 536762741,
+    536762773, 536762801, 536762813, 536762819, 536762843, 536762867,
+    536762903, 536762917, 536762953, 536762957, 536762969, 536762999,
+    536763013, 536763041, 536763131, 536763133, 536763137, 536763163,
+    536763191, 536763193, 536763211, 536763223, 536763247, 536763257,
+    536763299, 536763307, 536763323, 536763343, 536763347, 536763391,
+    536763421, 536763427, 536763463, 536763473, 536763497, 536763499,
+    536763527, 536763529, 536763571, 536763587, 536763589, 536763607,
+    536763613, 536763649, 536763653, 536763659, 536763707, 536763713,
+    536763743, 536763749, 536763761, 536763767, 536763779, 536763781,
+    536763803, 536763809, 536763839, 536763881, 536763893, 536763901,
+    536763907, 536763911, 536763917, 536763943, 536763947, 536763959,
+    536763961, 536763971, 536763979, 536763991, 536764021, 536764027,
+    536764037, 536764043, 536764049, 536764099, 536764121, 536764139,
+    536764177, 536764181, 536764187, 536764211, 536764213, 536764223,
+    536764259, 536764301, 536764303, 536764309, 536764339, 536764433,
+    536764441, 536764447, 536764453, 536764463, 536764469, 536764471,
+    536764507, 536764517, 536764561, 536764609, 536764619, 536764651,
+    536764667, 536764717, 536764727, 536764733, 536764759, 536764807,
+    536764843, 536764849, 536764859, 536764873, 536764897, 536764903,
+    536764909, 536764927, 536764951, 536764967, 536764981, 536764993,
+    536764999, 536765003, 536765011, 536765027, 536765057, 536765059,
+    536765077, 536765107, 536765111, 536765137, 536765167, 536765171,
+    536765227, 536765269, 536765323, 536765407, 536765443, 536765459,
+    536765461, 536765477, 536765479, 536765507, 536765519, 536765587,
+    536765591, 536765629, 536765653, 536765717, 536765767, 536765773,
+    536765783, 536765797, 536765833, 536765909, 536765917, 536766001,
+    536766049, 536766059, 536766071, 536766079, 536766089, 536766127,
+    536766163, 536766173, 536766227, 536766239, 536766259, 536766311,
+    536766317, 536766337, 536766379, 536766401, 536766409, 536766421,
+    536766497, 536766499, 536766509, 536766521, 536766553, 536766569,
+    536766577, 536766599, 536766613, 536766623, 536766647, 536766673,
+    536766679, 536766691, 536766749, 536766751, 536766761, 536766779,
+    536766781, 536766787, 536766799, 536766803, 536766809, 536766821,
+    536766827, 536766869, 536766871, 536766889, 536766899, 536766911,
+    536766913, 536766943, 536766961, 536766983, 536767037, 536767051,
+    536767067, 536767079, 536767111, 536767117, 536767183, 536767193,
+    536767219, 536767241, 536767247, 536767249, 536767291, 536767369,
+    536767379, 536767397, 536767403, 536767433, 536767453, 536767463,
+    536767481, 536767489, 536767501, 536767523, 536767529, 536767549,
+    536767591, 536767601, 536767607, 536767661, 536767681, 536767691,
+    536767709, 536767717, 536767783, 536767787, 536767789, 536767793,
+    536767799, 536767801, 536767807, 536767817, 536767823, 536767849,
+    536767867, 536767901, 536767921, 536767927, 536767937, 536767939,
+    536767943, 536767981, 536768003, 536768033, 536768053, 536768077,
+    536768083, 536768087, 536768119, 536768129, 536768147, 536768161,
+    536768189, 536768201, 536768231, 536768233, 536768257, 536768327,
+    536768333, 536768339, 536768347, 536768363, 536768383, 536768417,
+    536768437, 536768447, 536768459, 536768497, 536768501, 536768521,
+    536768537, 536768539, 536768567, 536768587, 536768593, 536768611,
+    536768621, 536768633, 536768651, 536768653, 536768663, 536768671,
+    536768747, 536768767, 536768783, 536768797, 536768821, 536768831,
+    536768851, 536768861, 536768899, 536768909, 536768923, 536768941,
+    536768977, 536768987, 536768993, 536769047, 536769071, 536769109,
+    536769119, 536769127, 536769131, 536769137, 536769157, 536769161,
+    536769179, 536769199, 536769221, 536769223, 536769257, 536769263,
+    536769283, 536769293, 536769307, 536769313, 536769347, 536769353,
+    536769379, 536769403, 536769427, 536769461, 536769463, 536769479,
+    536769503, 536769533, 536769539, 536769593, 536769601, 536769631,
+    536769659, 536769661, 536769707, 536769721, 536769733, 536769757,
+    536769811, 536769833, 536769859, 536769889, 536769899, 536769913,
+    536769923, 536769953, 536769983, 536770009, 536770043, 536770051,
+    536770081, 536770103, 536770109, 536770111, 536770123, 536770147,
+    536770151, 536770181, 536770217, 536770219, 536770229, 536770243,
+    536770261, 536770271, 536770307, 536770313, 536770327, 536770357,
+    536770361, 536770397, 536770411, 536770441, 536770447, 536770469,
+    536770471, 536770511, 536770517, 536770519, 536770607, 536770627,
+    536770643, 536770649, 536770669, 536770681, 536770687, 536770709,
+    536770777, 536770789, 536770799, 536770813, 536770823, 536770841,
+    536770933, 536770943, 536770979, 536771017, 536771023, 536771041,
+    536771047, 536771051, 536771087, 536771089, 536771111, 536771119,
+    536771153, 536771239, 536771273, 536771317, 536771363, 536771377,
+    536771381, 536771399, 536771429, 536771471, 536771503, 536771507,
+    536771561, 536771581, 536771591, 536771593, 536771621, 536771657,
+    536771659, 536771689, 536771737, 536771743, 536771761, 536771791,
+    536771797, 536771801, 536771827, 536771843, 536771849, 536771903,
+    536771909, 536771929, 536771941, 536771947, 536771951, 536771981,
+    536772011, 536772031, 536772077, 536772079, 536772113, 536772143,
+    536772163, 536772169, 536772193, 536772199, 536772221, 536772227,
+    536772253, 536772259, 536772293, 536772317, 536772319, 536772329,
+    536772337, 536772349, 536772359, 536772361, 536772389, 536772391,
+    536772403, 536772427, 536772437, 536772469, 536772497, 536772541,
+    536772581, 536772583, 536772601, 536772641, 536772673, 536772679,
+    536772701, 536772707, 536772751, 536772757, 536772791, 536772823,
+    536772829, 536772833, 536772881, 536772917, 536772941, 536772953,
+    536772959, 536772961, 536772991, 536773001, 536773019, 536773033,
+    536773049, 536773063, 536773073, 536773087, 536773117, 536773169,
+    536773177, 536773217, 536773219, 536773231, 536773243, 536773297,
+    536773357, 536773373, 536773397, 536773399, 536773411, 536773451,
+    536773469, 536773537, 536773553, 536773591, 536773597, 536773607,
+    536773613, 536773619, 536773631, 536773639, 536773669, 536773697,
+    536773717, 536773751, 536773823, 536773829, 536773889, 536773901,
+    536773903, 536773943, 536773967, 536773969, 536774027, 536774039,
+    536774053, 536774071, 536774081, 536774093, 536774101, 536774113,
+    536774123, 536774131, 536774171, 536774177, 536774179, 536774209,
+    536774233, 536774243, 536774257, 536774291, 536774309, 536774323,
+    536774327, 536774333, 536774351, 536774383, 536774387, 536774401,
+    536774411, 536774423, 536774431, 536774467, 536774477, 536774479,
+    536774531, 536774597, 536774599, 536774629, 536774653, 536774657,
+    536774669, 536774687, 536774723, 536774741, 536774761, 536774789,
+    536774801, 536774837, 536774857, 536774893, 536774899, 536774923,
+    536774933, 536774939, 536774957, 536774971, 536775053, 536775079,
+    536775103, 536775133, 536775143, 536775163, 536775223, 536775233,
+    536775247, 536775259, 536775263, 536775269, 536775277, 536775293,
+    536775299, 536775347, 536775419, 536775427, 536775431, 536775461,
+    536775511, 536775521, 536775557, 536775559, 536775583, 536775607,
+    536775619, 536775637, 536775641, 536775647, 536775671, 536775677,
+    536775689, 536775709, 536775719, 536775763, 536775779, 536775791,
+    536775803, 536775829, 536775839, 536775851, 536775919, 536775931,
+    536775937, 536775989, 536775991, 536776013, 536776063, 536776091,
+    536776127, 536776147, 536776151, 536776153, 536776169, 536776171,
+    536776183, 536776187, 536776211, 536776213, 536776217, 536776321,
+    536776327, 536776333, 536776381, 536776397, 536776403, 536776423,
+    536776483, 536776489, 536776511, 536776529, 536776531, 536776567,
+    536776579, 536776589, 536776607, 536776609, 536776651, 536776663,
+    536776673, 536776727, 536776741, 536776813, 536776817, 536776837,
+    536776859, 536776861, 536776883, 536776897, 536776909, 536776937,
+    536776939, 536776973, 536777027, 536777029, 536777047, 536777053,
+    536777069, 536777089, 536777099, 536777123, 536777141, 536777147,
+    536777161, 536777173, 536777201, 536777209, 536777237, 536777239,
+    536777257, 536777309, 536777317, 536777323, 536777333, 536777357,
+    536777383, 536777387, 536777399, 536777441, 536777447, 536777467,
+    536777489, 536777513, 536777561, 536777573, 536777581, 536777621,
+    536777627, 536777629, 536777641, 536777651, 536777663, 536777671,
+    536777707, 536777719, 536777723, 536777743, 536777753, 536777767,
+    536777777, 536777789, 536777827, 536777837, 536777851, 536777893,
+    536777909, 536777939, 536777953, 536778007, 536778049, 536778059,
+    536778089, 536778097, 536778103, 536778119, 536778127, 536778169,
+    536778241, 536778293, 536778343, 536778353, 536778373, 536778379,
+    536778391, 536778413, 536778433, 536778461, 536778479, 536778497,
+    536778511, 536778611, 536778653, 536778677, 536778701, 536778707,
+    536778727, 536778731, 536778751, 536778769, 536778779, 536778793,
+    536778817, 536778821, 536778839, 536778841, 536778871, 536778887,
+    536778901, 536778917, 536778923, 536778989, 536778997, 536779027,
+    536779031, 536779069, 536779073, 536779081, 536779121, 536779123,
+    536779141, 536779153, 536779157, 536779163, 536779189, 536779207,
+    536779253, 536779259, 536779261, 536779297, 536779319, 536779351,
+    536779361, 536779417, 536779423, 536779427, 536779429, 536779447,
+    536779459, 536779489, 536779553, 536779571, 536779619, 536779657,
+    536779717, 536779753, 536779769, 536779781, 536779807, 536779823,
+    536779829, 536779843, 536779847, 536779871, 536779889, 536779891,
+    536779907, 536779909, 536779927, 536779939, 536780029, 536780119,
+    536780143, 536780147, 536780149, 536780183, 536780203, 536780207,
+    536780239, 536780243, 536780261, 536780263, 536780291, 536780327,
+    536780329, 536780341, 536780347, 536780369, 536780393, 536780429,
+    536780441, 536780471, 536780477, 536780513, 536780521, 536780537,
+    536780539, 536780557, 536780591, 536780599, 536780641, 536780683,
+    536780687, 536780701, 536780731, 536780759, 536780821, 536780833,
+    536780857, 536780863, 536780917, 536780929, 536780947, 536780953,
+    536780957, 536781059, 536781067, 536781071, 536781079, 536781109,
+    536781127, 536781131, 536781149, 536781181, 536781187, 536781209,
+    536781227, 536781247, 536781263, 536781269, 536781281, 536781283,
+    536781317, 536781359, 536781361, 536781373, 536781391, 536781431,
+    536781433, 536781437, 536781451, 536781491, 536781499, 536781547,
+    536781551, 536781571, 536781577, 536781601, 536781617, 536781631,
+    536781643, 536781649, 536781671, 536781701, 536781703, 536781743,
+    536781767, 536781769, 536781781, 536781803, 536781841, 536781859,
+    536781913, 536781923, 536781989, 536781991, 536782009, 536782031,
+    536782069, 536782109, 536782117, 536782121, 536782171, 536782219,
+    536782283, 536782297, 536782307, 536782321, 536782343, 536782417,
+    536782423, 536782427, 536782447, 536782481, 536782517, 536782541,
+    536782553, 536782559, 536782567, 536782573, 536782607, 536782613,
+    536782621, 536782679, 536782681, 536782691, 536782709, 536782711,
+    536782751, 536782777, 536782787, 536782789, 536782811, 536782819,
+    536782861, 536782867, 536782877, 536782891, 536782907, 536782921,
+    536782931, 536782937, 536782951, 536782957, 536782963, 536782991,
+    536782997, 536783017, 536783021, 536783033, 536783047, 536783059,
+    536783063, 536783101, 536783113, 536783123, 536783141, 536783167,
+    536783179, 536783209, 536783227, 536783249, 536783251, 536783281,
+    536783293, 536783323, 536783393, 536783413, 536783441, 536783477,
+    536783503, 536783509, 536783537, 536783549, 536783563, 536783627,
+    536783651, 536783657, 536783671, 536783761, 536783771, 536783777,
+    536783783, 536783887, 536783977, 536783981, 536784019, 536784037,
+    536784041, 536784071, 536784077, 536784089, 536784091, 536784103,
+    536784119, 536784121, 536784139, 536784161, 536784167, 536784217,
+    536784233, 536784263, 536784289, 536784293, 536784319, 536784329,
+    536784337, 536784349, 536784359, 536784379, 536784427, 536784433,
+    536784449, 536784481, 536784487, 536784491, 536784527, 536784529,
+    536784541, 536784559, 536784581, 536784617, 536784629, 536784667,
+    536784719, 536784733, 536784739, 536784757, 536784761, 536784763,
+    536784767, 536784793, 536784817, 536784823, 536784847, 536784869,
+    536784887, 536784893, 536784907, 536784929, 536784947, 536784949,
+    536784959, 536784977, 536785019, 536785037, 536785049, 536785087,
+    536785103, 536785111, 536785129, 536785141, 536785231, 536785241,
+    536785267, 536785289, 536785313, 536785349, 536785351, 536785357,
+    536785373, 536785391, 536785393, 536785411, 536785423, 536785453,
+    536785471, 536785507, 536785517, 536785519, 536785531, 536785583,
+    536785619, 536785699, 536785703, 536785721, 536785729, 536785741,
+    536785747, 536785759, 536785771, 536785783, 536785793, 536785819,
+    536785831, 536785849, 536785859, 536785861, 536785867, 536785889,
+    536785903, 536785979, 536786011, 536786017, 536786023, 536786053,
+    536786077, 536786137, 536786171, 536786179, 536786197, 536786287,
+    536786333, 536786353, 536786363, 536786377, 536786387, 536786399,
+    536786527, 536786533, 536786557, 536786563, 536786567, 536786573,
+    536786599, 536786603, 536786609, 536786617, 536786623, 536786629,
+    536786681, 536786683, 536786693, 536786699, 536786711, 536786749,
+    536786753, 536786791, 536786797, 536786837, 536786851, 536786881,
+    536786891, 536786893, 536786923, 536786927, 536786941, 536786947,
+    536786977, 536786983, 536786989, 536787001, 536787011, 536787059,
+    536787109, 536787137, 536787143, 536787149, 536787151, 536787161,
+    536787197, 536787269, 536787299, 536787301, 536787337, 536787343,
+    536787353, 536787371, 536787389, 536787397, 536787401, 536787421,
+    536787439, 536787463, 536787467, 536787473, 536787479, 536787499,
+    536787521, 536787523, 536787557, 536787577, 536787583, 536787607,
+    536787637, 536787653, 536787683, 536787697, 536787701, 536787721,
+    536787781, 536787787, 536787803, 536787821, 536787859, 536787871,
+    536787917, 536787919, 536787931, 536787947, 536787967, 536787991,
+    536788001, 536788003, 536788097, 536788117, 536788123, 536788127,
+    536788159, 536788201, 536788211, 536788223, 536788229, 536788249,
+    536788253, 536788271, 536788279, 536788309, 536788321, 536788337,
+    536788381, 536788387, 536788411, 536788423, 536788477, 536788493,
+    536788507, 536788531, 536788543, 536788597, 536788621, 536788673,
+    536788727, 536788793, 536788807, 536788831, 536788867, 536788877,
+    536788891, 536788919, 536788939, 536788951, 536788999, 536789027,
+    536789041, 536789047, 536789051, 536789063, 536789069, 536789089,
+    536789107, 536789117, 536789129, 536789207, 536789213, 536789233,
+    536789237, 536789291, 536789293, 536789299, 536789329, 536789359,
+    536789369, 536789371, 536789389, 536789401, 536789413, 536789423,
+    536789443, 536789489, 536789531, 536789537, 536789543, 536789551,
+    536789557, 536789563, 536789579, 536789581, 536789587, 536789593,
+    536789609, 536789621, 536789629, 536789711, 536789717, 536789719,
+    536789723, 536789779, 536789809, 536789819, 536789833, 536789837,
+    536789849, 536789857, 536789887, 536789899, 536789921, 536789927,
+    536789983, 536789993, 536790013, 536790019, 536790041, 536790127,
+    536790139, 536790151, 536790167, 536790253, 536790257, 536790259,
+    536790311, 536790329, 536790349, 536790383, 536790407, 536790439,
+    536790467, 536790469, 536790473, 536790517, 536790539, 536790563,
+    536790587, 536790689, 536790697, 536790733, 536790757, 536790763,
+    536790803, 536790809, 536790811, 536790833, 536790847, 536790853,
+    536790889, 536790913, 536790923, 536790937, 536790959, 536790977,
+    536790979, 536791001, 536791039, 536791067, 536791081, 536791103,
+    536791117, 536791121, 536791127, 536791139, 536791141, 536791163,
+    536791187, 536791193, 536791207, 536791217, 536791237, 536791267,
+    536791271, 536791279, 536791289, 536791291, 536791327, 536791331,
+    536791349, 536791351, 536791369, 536791373, 536791379, 536791391,
+    536791429, 536791433, 536791441, 536791447, 536791459, 536791469,
+    536791481, 536791487, 536791511, 536791513, 536791547, 536791573,
+    536791589, 536791601, 536791613, 536791621, 536791657, 536791681,
+    536791709, 536791741, 536791777, 536791799, 536791811, 536791817,
+    536791831, 536791861, 536791867, 536791891, 536791901, 536791903,
+    536791951, 536791987, 536792023, 536792027, 536792107, 536792159,
+    536792171, 536792173, 536792219, 536792227, 536792257, 536792279,
+    536792293, 536792303, 536792309, 536792329, 536792353, 536792359,
+    536792369, 536792401, 536792413, 536792461, 536792479, 536792489,
+    536792491, 536792513, 536792519, 536792567, 536792569, 536792573,
+    536792587, 536792591, 536792611, 536792647, 536792671, 536792681,
+    536792689, 536792713, 536792771, 536792777, 536792783, 536792803,
+    536792819, 536792849, 536792887, 536792899, 536792939, 536793011,
+    536793013, 536793109, 536793167, 536793181, 536793199, 536793221,
+    536793233, 536793253, 536793259, 536793307, 536793311, 536793317,
+    536793331, 536793379, 536793391, 536793401, 536793407, 536793431,
+    536793463, 536793497, 536793503, 536793511, 536793557, 536793559,
+    536793563, 536793577, 536793589, 536793599, 536793629, 536793637,
+    536793659, 536793707, 536793709, 536793713, 536793727, 536793779,
+    536793787, 536793791, 536793797, 536793809, 536793823, 536793827,
+    536793863, 536793869, 536793899, 536793931, 536793967, 536793991,
+    536794127, 536794133, 536794207, 536794211, 536794253, 536794259,
+    536794267, 536794273, 536794277, 536794301, 536794303, 536794337,
+    536794351, 536794369, 536794399, 536794417, 536794421, 536794429,
+    536794439, 536794469, 536794501, 536794507, 536794519, 536794529,
+    536794537, 536794541, 536794603, 536794619, 536794637, 536794649,
+    536794679, 536794681, 536794691, 536794721, 536794747, 536794751,
+    536794789, 536794801, 536794813, 536794823, 536794829, 536794847,
+    536794871, 536794877, 536794879, 536794889, 536794931, 536794933,
+    536794939, 536794957, 536794969, 536794981, 536794991, 536794997,
+    536795029, 536795053, 536795071, 536795099, 536795141, 536795153,
+    536795159, 536795173, 536795177, 536795209, 536795219, 536795221,
+    536795227, 536795267, 536795269, 536795291, 536795317, 536795327,
+    536795341, 536795431, 536795477, 536795489, 536795509, 536795527,
+    536795537, 536795549, 536795561, 536795563, 536795569, 536795603,
+    536795627, 536795681, 536795683, 536795719, 536795737, 536795773,
+    536795803, 536795839, 536795851, 536795867, 536795869, 536795891,
+    536795921, 536795951, 536795957, 536795993, 536796019, 536796023,
+    536796049, 536796079, 536796089, 536796121, 536796163, 536796187,
+    536796203, 536796223, 536796257, 536796269, 536796289, 536796317,
+    536796319, 536796329, 536796343, 536796373, 536796427, 536796431,
+    536796433, 536796451, 536796479, 536796499, 536796511, 536796553,
+    536796571, 536796577, 536796581, 536796599, 536796643, 536796677,
+    536796679, 536796727, 536796731, 536796751, 536796761, 536796779,
+    536796847, 536796857, 536796859, 536796901, 536796943, 536796983,
+    536797039, 536797057, 536797067, 536797087, 536797103, 536797109,
+    536797111, 536797141, 536797189, 536797201, 536797213, 536797243,
+    536797267, 536797273, 536797319, 536797361, 536797363, 536797403,
+    536797411, 536797441, 536797463, 536797477, 536797487, 536797489,
+    536797523, 536797531, 536797553, 536797561, 536797571, 536797607,
+    536797649, 536797663, 536797687, 536797693, 536797697, 536797711,
+    536797717, 536797733, 536797741, 536797757, 536797771, 536797777,
+    536797819, 536797837, 536797867, 536797879, 536797883, 536797949,
+    536798029, 536798047, 536798057, 536798099, 536798147, 536798153,
+    536798159, 536798177, 536798189, 536798191, 536798209, 536798261,
+    536798293, 536798333, 536798347, 536798351, 536798359, 536798371,
+    536798407, 536798441, 536798447, 536798459, 536798473, 536798491,
+    536798501, 536798533, 536798539, 536798557, 536798567, 536798593,
+    536798651, 536798683, 536798693, 536798723, 536798737, 536798741,
+    536798747, 536798753, 536798767, 536798803, 536798827, 536798833,
+    536798879, 536798881, 536798921, 536798989, 536799031, 536799037,
+    536799041, 536799049, 536799061, 536799073, 536799083, 536799113,
+    536799119, 536799161, 536799181, 536799187, 536799223, 536799227,
+    536799253, 536799269, 536799271, 536799299, 536799311, 536799331,
+    536799337, 536799353, 536799359, 536799397, 536799421, 536799437,
+    536799443, 536799449, 536799481, 536799499, 536799509, 536799517,
+    536799521, 536799559, 536799583, 536799619, 536799629, 536799661,
+    536799671, 536799677, 536799743, 536799827, 536799841, 536799859,
+    536799881, 536799919, 536799929, 536799931, 536799941, 536799943,
+    536799983, 536799997, 536800001, 536800009, 536800021, 536800031,
+    536800051, 536800067, 536800081, 536800097, 536800111, 536800127,
+    536800139, 536800157, 536800163, 536800189, 536800213, 536800219,
+    536800241, 536800273, 536800283, 536800307, 536800351, 536800391,
+    536800409, 536800417, 536800423, 536800457, 536800493, 536800499,
+    536800507, 536800543, 536800567, 536800573, 536800601, 536800633,
+    536800637, 536800651, 536800697, 536800727, 536800729, 536800829,
+    536800861, 536800871, 536800937, 536800969, 536800973, 536800981,
+    536801003, 536801009, 536801017, 536801021, 536801033, 536801051,
+    536801077, 536801081, 536801113, 536801123, 536801171, 536801249,
+    536801261, 536801269, 536801273, 536801327, 536801329, 536801341,
+    536801351, 536801359, 536801381, 536801383, 536801389, 536801399,
+    536801467, 536801497, 536801519, 536801539, 536801563, 536801581,
+    536801591, 536801593, 536801597, 536801599, 536801609, 536801633,
+    536801653, 536801659, 536801689, 536801719, 536801731, 536801767,
+    536801821, 536801827, 536801833, 536801849, 536801857, 536801893,
+    536801929, 536801933, 536801939, 536801999, 536802029, 536802043,
+    536802059, 536802121, 536802127, 536802137, 536802157, 536802163,
+    536802187, 536802223, 536802247, 536802281, 536802317, 536802323,
+    536802337, 536802347, 536802349, 536802377, 536802389, 536802419,
+    536802503, 536802527, 536802533, 536802547, 536802599, 536802601,
+    536802631, 536802647, 536802683, 536802703, 536802713, 536802719,
+    536802733, 536802737, 536802781, 536802787, 536802803, 536802809,
+    536802811, 536802821, 536802823, 536802857, 536802869, 536802883,
+    536802887, 536802899, 536802901, 536802923, 536802941, 536802943,
+    536802967, 536802979, 536803031, 536803039, 536803123, 536803139,
+    536803151, 536803177, 536803213, 536803229, 536803231, 536803259,
+    536803291, 536803303, 536803387, 536803391, 536803429, 536803439,
+    536803457, 536803459, 536803481, 536803483, 536803489, 536803507,
+    536803517, 536803549, 536803559, 536803571, 536803583, 536803621,
+    536803627, 536803649, 536803651, 536803661, 536803667, 536803669,
+    536803691, 536803753, 536803763, 536803783, 536803793, 536803811,
+    536803819, 536803823, 536803829, 536803837, 536803879, 536803907,
+    536803909, 536803937, 536803957, 536803987, 536803999, 536804011,
+    536804101, 536804129, 536804161, 536804197, 536804221, 536804227,
+    536804231, 536804263, 536804269, 536804287, 536804311, 536804327,
+    536804347, 536804351, 536804357, 536804363, 536804369, 536804377,
+    536804407, 536804419, 536804459, 536804503, 536804507, 536804519,
+    536804581, 536804591, 536804623, 536804627, 536804651, 536804683,
+    536804687, 536804707, 536804831, 536804837, 536804861, 536804867,
+    536804881, 536804893, 536804911, 536804953, 536804963, 536805011,
+    536805019, 536805023, 536805029, 536805067, 536805097, 536805173,
+    536805193, 536805223, 536805263, 536805289, 536805317, 536805323,
+    536805343, 536805383, 536805389, 536805397, 536805403, 536805419,
+    536805439, 536805449, 536805559, 536805587, 536805649, 536805697,
+    536805701, 536805713, 536805721, 536805739, 536805749, 536805751,
+    536805757, 536805767, 536805791, 536805799, 536805817, 536805853,
+    536805887, 536805949, 536805961, 536805967, 536806007, 536806009,
+    536806019, 536806021, 536806033, 536806043, 536806087, 536806103,
+    536806117, 536806133, 536806139, 536806159, 536806169, 536806253,
+    536806273, 536806279, 536806321, 536806337, 536806339, 536806349,
+    536806351, 536806409, 536806423, 536806469, 536806477, 536806483,
+    536806489, 536806493, 536806511, 536806519, 536806531, 536806541,
+    536806547, 536806553, 536806607, 536806609, 536806651, 536806663,
+    536806687, 536806703, 536806763, 536806769, 536806783, 536806813,
+    536806861, 536806877, 536806901, 536806903, 536806939, 536806961,
+    536807003, 536807017, 536807027, 536807039, 536807093, 536807099,
+    536807107, 536807153, 536807177, 536807221, 536807261, 536807269,
+    536807273, 536807287, 536807303, 536807309, 536807321, 536807333,
+    536807339, 536807347, 536807353, 536807387, 536807393, 536807407,
+    536807431, 536807443, 536807461, 536807473, 536807543, 536807569,
+    536807573, 536807587, 536807599, 536807611, 536807651, 536807653,
+    536807659, 536807717, 536807767, 536807773, 536807801, 536807807,
+    536807837, 536807839, 536807849, 536807891, 536807899, 536807977,
+    536807987, 536808023, 536808029, 536808037, 536808043, 536808047,
+    536808049, 536808071, 536808119, 536808127, 536808143, 536808149,
+    536808161, 536808169, 536808179, 536808191, 536808229, 536808253,
+    536808281, 536808287, 536808313, 536808319, 536808343, 536808353,
+    536808361, 536808403, 536808413, 536808443, 536808451, 536808457,
+    536808521, 536808527, 536808551, 536808557, 536808563, 536808583,
+    536808697, 536808709, 536808773, 536808781, 536808791, 536808809,
+    536808817, 536808823, 536808829, 536808851, 536808887, 536808893,
+    536808901, 536808971, 536808997, 536809019, 536809027, 536809079,
+    536809087, 536809093, 536809123, 536809151, 536809171, 536809183,
+    536809201, 536809241, 536809253, 536809277, 536809279, 536809297,
+    536809313, 536809319, 536809321, 536809331, 536809363, 536809381,
+    536809409, 536809417, 536809453, 536809457, 536809519, 536809541,
+    536809591, 536809613, 536809649, 536809753, 536809759, 536809781,
+    536809783, 536809817, 536809841, 536809853, 536809859, 536809879,
+    536809883, 536809909, 536809927, 536809939, 536809957, 536809961,
+    536809991, 536809993, 536810011, 536810033, 536810047, 536810063,
+    536810093, 536810101, 536810107, 536810159, 536810189, 536810191,
+    536810221, 536810227, 536810243, 536810273, 536810297, 536810321,
+    536810347, 536810381, 536810383, 536810399, 536810459, 536810471,
+    536810489, 536810507, 536810557, 536810567, 536810627, 536810647,
+    536810693, 536810699, 536810713, 536810719, 536810723, 536810737,
+    536810741, 536810759, 536810773, 536810801, 536810809, 536810821,
+    536810831, 536810863, 536810873, 536810881, 536810891, 536810893,
+    536810899, 536810903, 536810917, 536810947, 536810959, 536810993,
+    536810999, 536811001, 536811019, 536811029, 536811071, 536811089,
+    536811109, 536811127, 536811131, 536811217, 536811229, 536811259,
+    536811277, 536811307, 536811337, 536811343, 536811367, 536811377,
+    536811391, 536811433, 536811479, 536811481, 536811491, 536811511,
+    536811523, 536811553, 536811607, 536811629, 536811659, 536811661,
+    536811679, 536811701, 536811707, 536811733, 536811749, 536811761,
+    536811763, 536811767, 536811787, 536811809, 536811823, 536811833,
+    536811859, 536811929, 536811949, 536811971, 536811991, 536812007,
+    536812033, 536812049, 536812061, 536812093, 536812103, 536812117,
+    536812121, 536812181, 536812201, 536812217, 536812219, 536812223,
+    536812313, 536812319, 536812321, 536812361, 536812421, 536812439,
+    536812457, 536812459, 536812477, 536812487, 536812499, 536812531,
+    536812537, 536812541, 536812561, 536812583, 536812597, 536812603,
+    536812651, 536812721, 536812733, 536812751, 536812769, 536812807,
+    536812813, 536812819, 536812831, 536812853, 536812867, 536812889,
+    536812891, 536812931, 536812937, 536812943, 536812951, 536812967,
+    536813027, 536813083, 536813087, 536813089, 536813129, 536813149,
+    536813209, 536813269, 536813323, 536813339, 536813357, 536813363,
+    536813371, 536813383, 536813401, 536813477, 536813489, 536813507,
+    536813509, 536813531, 536813549, 536813551, 536813561, 536813569,
+    536813597, 536813609, 536813653, 536813657, 536813663, 536813729,
+    536813731, 536813741, 536813759, 536813789, 536813791, 536813803,
+    536813819, 536813857, 536813869, 536813891, 536813899, 536813903,
+    536813911, 536813917, 536813923, 536813933, 536813957, 536813987,
+    536814013, 536814017, 536814053, 536814067, 536814077, 536814079,
+    536814097, 536814101, 536814121, 536814127, 536814133, 536814139,
+    536814149, 536814169, 536814217, 536814221, 536814281, 536814323,
+    536814347, 536814349, 536814359, 536814371, 536814373, 536814403,
+    536814409, 536814419, 536814431, 536814449, 536814461, 536814497,
+    536814527, 536814539, 536814547, 536814571, 536814601, 536814637,
+    536814659, 536814671, 536814673, 536814689, 536814703, 536814713,
+    536814721, 536814731, 536814739, 536814767, 536814769, 536814799,
+    536814829, 536814841, 536814869, 536814913, 536814931, 536814959,
+    536814977, 536814979, 536814983, 536814989, 536815007, 536815031,
+    536815039, 536815057, 536815073, 536815133, 536815141, 536815163,
+    536815177, 536815187, 536815267, 536815319, 536815327, 536815339,
+    536815343, 536815361, 536815369, 536815387, 536815393, 536815399,
+    536815441, 536815459, 536815463, 536815471, 536815523, 536815537,
+    536815547, 536815577, 536815589, 536815603, 536815621, 536815633,
+    536815639, 536815649, 536815661, 536815663, 536815667, 536815673,
+    536815753, 536815757, 536815771, 536815787, 536815831, 536815841,
+    536815843, 536815847, 536815891, 536815901, 536815957, 536815963,
+    536815967, 536815969, 536815973, 536816003, 536816009, 536816047,
+    536816083, 536816099, 536816107, 536816143, 536816149, 536816201,
+    536816207, 536816219, 536816221, 536816233, 536816263, 536816317,
+    536816339, 536816351, 536816353, 536816363, 536816381, 536816393,
+    536816407, 536816411, 536816417, 536816437, 536816503, 536816509,
+    536816549, 536816551, 536816591, 536816611, 536816617, 536816641,
+    536816689, 536816699, 536816713, 536816719, 536816723, 536816759,
+    536816779, 536816809, 536816821, 536816843, 536816857, 536816879,
+    536816887, 536816893, 536816911, 536816933, 536816947, 536816953,
+    536816971, 536816983, 536817037, 536817077, 536817103, 536817119,
+    536817131, 536817157, 536817161, 536817163, 536817187, 536817233,
+    536817251, 536817257, 536817271, 536817287, 536817293, 536817299,
+    536817301, 536817311, 536817329, 536817331, 536817361, 536817371,
+    536817373, 536817389, 536817427, 536817451, 536817487, 536817499,
+    536817509, 536817553, 536817557, 536817559, 536817569, 536817703,
+    536817707, 536817709, 536817737, 536817767, 536817781, 536817791,
+    536817833, 536817859, 536817863, 536817881, 536817937, 536817947,
+    536817949, 536817989, 536817991, 536817997, 536818019, 536818031,
+    536818057, 536818099, 536818109, 536818111, 536818123, 536818141,
+    536818147, 536818151, 536818157, 536818201, 536818241, 536818277,
+    536818279, 536818301, 536818309, 536818313, 536818319, 536818339,
+    536818357, 536818411, 536818423, 536818463, 536818487, 536818501,
+    536818511, 536818517, 536818531, 536818543, 536818547, 536818559,
+    536818561, 536818573, 536818577, 536818589, 536818603, 536818613,
+    536818621, 536818627, 536818637, 536818649, 536818651, 536818663,
+    536818687, 536818691, 536818721, 536818729, 536818753, 536818771,
+    536818783, 536818831, 536818871, 536818879, 536818889, 536818901,
+    536818921, 536818937, 536818943, 536818969, 536819039, 536819069,
+    536819077, 536819083, 536819089, 536819099, 536819113, 536819119,
+    536819159, 536819161, 536819167, 536819177, 536819189, 536819197,
+    536819201, 536819233, 536819263, 536819291, 536819317, 536819323,
+    536819363, 536819399, 536819401, 536819429, 536819501, 536819509,
+    536819513, 536819527, 536819537, 536819579, 536819599, 536819617,
+    536819627, 536819639, 536819687, 536819707, 536819713, 536819719,
+    536819743, 536819771, 536819797, 536819809, 536819821, 536819837,
+    536819849, 536819851, 536819861, 536819873, 536819911, 536819989,
+    536819993, 536820001, 536820061, 536820107, 536820113, 536820157,
+    536820181, 536820187, 536820217, 536820223, 536820259, 536820289,
+    536820311, 536820341, 536820367, 536820379, 536820419, 536820439,
+    536820461, 536820467, 536820497, 536820533, 536820593, 536820607,
+    536820617, 536820631, 536820637, 536820659, 536820673, 536820689,
+    536820709, 536820727, 536820743, 536820773, 536820787, 536820803,
+    536820857, 536820899, 536820953, 536820961, 536820983, 536820997,
+    536821027, 536821031, 536821067, 536821069, 536821093, 536821097,
+    536821099, 536821111, 536821139, 536821147, 536821163, 536821171,
+    536821199, 536821237, 536821261, 536821277, 536821279, 536821283,
+    536821309, 536821319, 536821339, 536821361, 536821379, 536821387,
+    536821399, 536821409, 536821423, 536821447, 536821457, 536821469,
+    536821499, 536821501, 536821531, 536821547, 536821553, 536821583,
+    536821591, 536821603, 536821627, 536821657, 536821693, 536821711,
+    536821717, 536821739, 536821781, 536821783, 536821787, 536821793,
+    536821843, 536821853, 536821861, 536821867, 536821891, 536821913,
+    536821919, 536822017, 536822087, 536822113, 536822123, 536822177,
+    536822183, 536822227, 536822239, 536822261, 536822263, 536822303,
+    536822339, 536822353, 536822357, 536822383, 536822431, 536822437,
+    536822477, 536822479, 536822483, 536822519, 536822521, 536822537,
+    536822563, 536822591, 536822609, 536822623, 536822639, 536822747,
+    536822749, 536822761, 536822779, 536822807, 536822837, 536822863,
+    536822911, 536822927, 536822981, 536823019, 536823037, 536823041,
+    536823043, 536823083, 536823107, 536823113, 536823179, 536823191,
+    536823193, 536823211, 536823251, 536823257, 536823299, 536823307,
+    536823341, 536823361, 536823409, 536823461, 536823479, 536823487,
+    536823493, 536823527, 536823541, 536823571, 536823589, 536823593,
+    536823647, 536823659, 536823667, 536823673, 536823719, 536823757,
+    536823761, 536823779, 536823809, 536823817, 536823821, 536823839,
+    536823883, 536823923, 536824003, 536824031, 536824049, 536824051,
+    536824063, 536824069, 536824073, 536824097, 536824103, 536824151,
+    536824153, 536824199, 536824213, 536824297, 536824331, 536824349,
+    536824381, 536824391, 536824403, 536824429, 536824433, 536824447,
+    536824469, 536824523, 536824529, 536824559, 536824571, 536824579,
+    536824627, 536824637, 536824643, 536824649, 536824667, 536824697,
+    536824711, 536824747, 536824763, 536824789, 536824801, 536824867,
+    536824877, 536824889, 536824901, 536824907, 536824909, 536824913,
+    536824927, 536824933, 536824961, 536824973, 536825027, 536825039,
+    536825041, 536825053, 536825059, 536825087, 536825101, 536825123,
+    536825131, 536825153, 536825203, 536825207, 536825209, 536825251,
+    536825273, 536825279, 536825281, 536825299, 536825323, 536825329,
+    536825339, 536825353, 536825363, 536825369, 536825389, 536825407,
+    536825441, 536825477, 536825501, 536825537, 536825539, 536825557,
+    536825573, 536825581, 536825599, 536825603, 536825623, 536825629,
+    536825647, 536825659, 536825671, 536825683, 536825689, 536825701,
+    536825713, 536825761, 536825767, 536825789, 536825831, 536825843,
+    536825879, 536825903, 536825917, 536825929, 536825951, 536826001,
+    536826067, 536826091, 536826097, 536826107, 536826109, 536826113,
+    536826127, 536826131, 536826137, 536826139, 536826193, 536826217,
+    536826239, 536826253, 536826259, 536826263, 536826293, 536826299,
+    536826313, 536826359, 536826397, 536826443, 536826457, 536826461,
+    536826467, 536826481, 536826517, 536826533, 536826539, 536826541,
+    536826547, 536826553, 536826617, 536826623, 536826637, 536826643,
+    536826649, 536826671, 536826679, 536826683, 536826751, 536826793,
+    536826827, 536826839, 536826863, 536826869, 536826887, 536826911,
+    536826919, 536826943, 536826949, 536826959, 536826989, 536827001,
+    536827009, 536827013, 536827051, 536827087, 536827097, 536827099,
+    536827111, 536827129, 536827133, 536827141, 536827147, 536827157,
+    536827163, 536827169, 536827171, 536827189, 536827211, 536827223,
+    536827229, 536827303, 536827367, 536827393, 536827397, 536827399,
+    536827427, 536827433, 536827471, 536827531, 536827537, 536827541,
+    536827553, 536827579, 536827583, 536827601, 536827639, 536827721,
+    536827723, 536827747, 536827769, 536827777, 536827789, 536827793,
+    536827799, 536827807, 536827813, 536827817, 536827829, 536827849,
+    536827901, 536827979, 536827997, 536828009, 536828011, 536828063,
+    536828087, 536828093, 536828101, 536828113, 536828141, 536828183,
+    536828213, 536828221, 536828239, 536828249, 536828263, 536828269,
+    536828323, 536828351, 536828353, 536828359, 536828371, 536828377,
+    536828381, 536828399, 536828417, 536828419, 536828423, 536828459,
+    536828471, 536828497, 536828587, 536828623, 536828627, 536828639,
+    536828651, 536828693, 536828701, 536828711, 536828713, 536828791,
+    536828797, 536828801, 536828827, 536828833, 536828849, 536828879,
+    536828881, 536828959, 536829101, 536829119, 536829149, 536829151,
+    536829169, 536829193, 536829197, 536829203, 536829283, 536829289,
+    536829299, 536829317, 536829323, 536829343, 536829389, 536829467,
+    536829497, 536829539, 536829541, 536829547, 536829589, 536829703,
+    536829721, 536829737, 536829749, 536829751, 536829827, 536829841,
+    536829901, 536829919, 536829983, 536829989, 536830027, 536830061,
+    536830067, 536830109, 536830121, 536830157, 536830159, 536830171,
+    536830181, 536830183, 536830207, 536830211, 536830241, 536830249,
+    536830297, 536830309, 536830337, 536830363, 536830391, 536830421,
+    536830423, 536830429, 536830451, 536830457, 536830477, 536830523,
+    536830529, 536830531, 536830543, 536830577, 536830583, 536830621,
+    536830639, 536830667, 536830673, 536830681, 536830691, 536830703,
+    536830717, 536830727, 536830729, 536830783, 536830829, 536830837,
+    536830843, 536830859, 536830873, 536830897, 536830901, 536830939,
+    536830949, 536830961, 536830967, 536830979, 536831023, 536831033,
+    536831041, 536831051, 536831089, 536831101, 536831137, 536831143,
+    536831167, 536831177, 536831231, 536831233, 536831249, 536831279,
+    536831297, 536831299, 536831303, 536831333, 536831341, 536831359,
+    536831381, 536831401, 536831411, 536831419, 536831429, 536831437,
+    536831443, 536831447, 536831459, 536831527, 536831539, 536831549,
+    536831551, 536831591, 536831641, 536831663, 536831683, 536831693,
+    536831741, 536831747, 536831773, 536831783, 536831803, 536831807,
+    536831809, 536831837, 536831839, 536831857, 536831863, 536831873,
+    536831879, 536831917, 536831941, 536831957, 536831969, 536831989,
+    536831993, 536832007, 536832011, 536832041, 536832077, 536832089,
+    536832113, 536832119, 536832133, 536832139, 536832157, 536832169,
+    536832203, 536832221, 536832227, 536832281, 536832287, 536832293,
+    536832299, 536832313, 536832337, 536832343, 536832347, 536832353,
+    536832379, 536832383, 536832407, 536832419, 536832433, 536832451,
+    536832493, 536832497, 536832523, 536832551, 536832559, 536832577,
+    536832607, 536832617, 536832643, 536832649, 536832661, 536832671,
+    536832679, 536832697, 536832713, 536832733, 536832767, 536832773,
+    536832841, 536832853, 536832871, 536832883, 536832893, 536832929,
+    536832971, 536832977, 536832979, 536832997, 536833009, 536833019,
+    536833051, 536833067, 536833081, 536833097, 536833177, 536833183,
+    536833189, 536833217, 536833261, 536833273, 536833303, 536833307,
+    536833331, 536833337, 536833373, 536833399, 536833411, 536833439,
+    536833447, 536833469, 536833567, 536833571, 536833573, 536833589,
+    536833601, 536833613, 536833621, 536833643, 536833651, 536833673,
+    536833729, 536833741, 536833753, 536833763, 536833783, 536833811,
+    536833831, 536833867, 536833879, 536833901, 536833903, 536833919,
+    536833963, 536833991, 536834003, 536834009, 536834017, 536834057,
+    536834063, 536834093, 536834131, 536834149, 536834203, 536834209,
+    536834213, 536834251, 536834267, 536834269, 536834273, 536834293,
+    536834299, 536834323, 536834327, 536834377, 536834401, 536834437,
+    536834477, 536834503, 536834527, 536834537, 536834549, 536834593,
+    536834603, 536834647, 536834671, 536834681, 536834737, 536834741,
+    536834761, 536834777, 536834791, 536834807, 536834821, 536834839,
+    536834899, 536834983, 536835001, 536835007, 536835023, 536835031,
+    536835053, 536835071, 536835083, 536835107, 536835133, 536835149,
+    536835193, 536835199, 536835227, 536835241, 536835307, 536835373,
+    536835389, 536835391, 536835413, 536835419, 536835491, 536835517,
+    536835529, 536835547, 536835581, 536835583, 536835623, 536835641,
+    536835643, 536835659, 536835661, 536835697, 536835721, 536835727,
+    536835737, 536835743, 536835751, 536835763, 536835787, 536835811,
+    536835821, 536835839, 536835851, 536835881, 536835917, 536835947,
+    536835953, 536835967, 536835983, 536835989, 536836049, 536836057,
+    536836061, 536836063, 536836129, 536836133, 536836141, 536836187,
+    536836189, 536836243, 536836253, 536836259, 536836271, 536836273,
+    536836283, 536836291, 536836327, 536836343, 536836357, 536836409,
+    536836423, 536836451, 536836453, 536836459, 536836463, 536836483,
+    536836511, 536836543, 536836549, 536836571, 536836649, 536836669,
+    536836673, 536836681, 536836687, 536836691, 536836723, 536836733,
+    536836757, 536836771, 536836801, 536836823, 536836831, 536836847,
+    536836879, 536836891, 536836901, 536836907, 536836913, 536836921,
+    536836933, 536836981, 536836987, 536836991, 536837003, 536837023,
+    536837057, 536837117, 536837141, 536837167, 536837173, 536837219,
+    536837221, 536837233, 536837263, 536837269, 536837291, 536837333,
+    536837341, 536837363, 536837369, 536837417, 536837423, 536837429,
+    536837437, 536837459, 536837467, 536837491, 536837501, 536837507,
+    536837513, 536837527, 536837537, 536837569, 536837573, 536837579,
+    536837593, 536837597, 536837621, 536837629, 536837683, 536837711,
+    536837731, 536837783, 536837803, 536837809, 536837827, 536837831,
+    536837891, 536837893, 536837897, 536837923, 536837981, 536837993,
+    536838011, 536838013, 536838037, 536838073, 536838077, 536838079,
+    536838083, 536838097, 536838139, 536838149, 536838151, 536838167,
+    536838173, 536838229, 536838233, 536838307, 536838311, 536838317,
+    536838353, 536838361, 536838383, 536838389, 536838403, 536838437,
+    536838509, 536838527, 536838539, 536838541, 536838553, 536838557,
+    536838583, 536838611, 536838619, 536838629, 536838667, 536838677,
+    536838697, 536838713, 536838763, 536838769, 536838793, 536838803,
+    536838821, 536838823, 536838829, 536838839, 536838919, 536838943,
+    536838949, 536838959, 536839001, 536839027, 536839057, 536839063,
+    536839081, 536839087, 536839187, 536839211, 536839229, 536839231,
+    536839249, 536839283, 536839339, 536839351, 536839409, 536839421,
+    536839427, 536839439, 536839463, 536839469, 536839483, 536839507,
+    536839517, 536839627, 536839657, 536839663, 536839673, 536839717,
+    536839727, 536839747, 536839763, 536839769, 536839777, 536839783,
+    536839799, 536839801, 536839819, 536839829, 536839837, 536839841,
+    536839859, 536839861, 536839873, 536839921, 536839931, 536839939,
+    536839949, 536839981, 536839999, 536840009, 536840047, 536840053,
+    536840069, 536840081, 536840119, 536840123, 536840137, 536840179,
+    536840197, 536840201, 536840203, 536840207, 536840219, 536840243,
+    536840261, 536840281, 536840327, 536840329, 536840333, 536840377,
+    536840407, 536840411, 536840503, 536840527, 536840531, 536840561,
+    536840567, 536840581, 536840599, 536840651, 536840653, 536840683,
+    536840701, 536840713, 536840729, 536840741, 536840743, 536840797,
+    536840819, 536840831, 536840867, 536840873, 536840893, 536840897,
+    536840903, 536840911, 536840923, 536840959, 536841001, 536841007,
+    536841017, 536841031, 536841037, 536841077, 536841131, 536841139,
+    536841157, 536841161, 536841163, 536841169, 536841199, 536841203,
+    536841209, 536841259, 536841281, 536841289, 536841299, 536841307,
+    536841397, 536841401, 536841421, 536841443, 536841451, 536841457,
+    536841479, 536841511, 536841559, 536841581, 536841631, 536841653,
+    536841667, 536841709, 536841737, 536841743, 536841749, 536841757,
+    536841797, 536841803, 536841817, 536841839, 536841847, 536841853,
+    536841887, 536841889, 536841901, 536841937, 536841959, 536842001,
+    536842021, 536842027, 536842043, 536842049, 536842087, 536842109,
+    536842127, 536842129, 536842153, 536842157, 536842183, 536842211,
+    536842217, 536842231, 536842237, 536842249, 536842259, 536842277,
+    536842349, 536842373, 536842399, 536842421, 536842429, 536842451,
+    536842477, 536842513, 536842529, 536842543, 536842597, 536842613,
+    536842633, 536842651, 536842661, 536842667, 536842681, 536842697,
+    536842723, 536842741, 536842759, 536842763, 536842769, 536842783,
+    536842819, 536842837, 536842849, 536842877, 536842907, 536842919,
+    536842939, 536842961, 536842963, 536842973, 536842979, 536842981,
+    536842993, 536843011, 536843033, 536843039, 536843059, 536843063,
+    536843077, 536843093, 536843113, 536843117, 536843123, 536843129,
+    536843137, 536843143, 536843149, 536843173, 536843191, 536843297,
+    536843327, 536843341, 536843401, 536843441, 536843467, 536843477,
+    536843491, 536843513, 536843521, 536843539, 536843543, 536843579,
+    536843617, 536843641, 536843653, 536843669, 536843743, 536843809,
+    536843819, 536843831, 536843869, 536843887, 536843893, 536843899,
+    536843921, 536843927, 536843929, 536843939, 536843941, 536843977,
+    536844001, 536844023, 536844029, 536844043, 536844059, 536844067,
+    536844151, 536844163, 536844197, 536844229, 536844233, 536844239,
+    536844247, 536844281, 536844307, 536844323, 536844337, 536844389,
+    536844437, 536844457, 536844461, 536844509, 536844521, 536844523,
+    536844533, 536844571, 536844617, 536844619, 536844631, 536844641,
+    536844643, 536844647, 536844653, 536844661, 536844667, 536844673,
+    536844689, 536844691, 536844719, 536844731, 536844739, 536844743,
+    536844757, 536844769, 536844799, 536844823, 536844859, 536844881,
+    536844911, 536844983, 536845027, 536845061, 536845117, 536845147,
+    536845151, 536845157, 536845181, 536845207, 536845213, 536845217,
+    536845223, 536845237, 536845273, 536845289, 536845297, 536845313,
+    536845319, 536845409, 536845423, 536845447, 536845451, 536845459,
+    536845471, 536845481, 536845487, 536845489, 536845537, 536845559,
+    536845613, 536845633, 536845649, 536845663, 536845679, 536845733,
+    536845763, 536845781, 536845787, 536845807, 536845831, 536845847,
+    536845849, 536845853, 536845861, 536845867, 536845877, 536845919,
+    536845949, 536845951, 536845961, 536845973, 536845979, 536846017,
+    536846021, 536846033, 536846041, 536846047, 536846053, 536846113,
+    536846117, 536846171, 536846201, 536846207, 536846237, 536846249,
+    536846257, 536846263, 536846269, 536846293, 536846351, 536846377,
+    536846467, 536846483, 536846491, 536846509, 536846551, 536846567,
+    536846603, 536846617, 536846641, 536846647, 536846669, 536846707,
+    536846711, 536846719, 536846741, 536846759, 536846771, 536846789,
+    536846861, 536846897, 536846923, 536846929, 536846953, 536846977,
+    536846983, 536846987, 536847011, 536847013, 536847049, 536847053,
+    536847061, 536847167, 536847169, 536847187, 536847191, 536847193,
+    536847203, 536847221, 536847239, 536847247, 536847251, 536847253,
+    536847281, 536847287, 536847331, 536847341, 536847343, 536847371,
+    536847419, 536847461, 536847463, 536847473, 536847529, 536847533,
+    536847551, 536847589, 536847593, 536847599, 536847601, 536847613,
+    536847659, 536847691, 536847697, 536847713, 536847721, 536847737,
+    536847791, 536847799, 536847803, 536847823, 536847847, 536847881,
+    536847893, 536847917, 536847931, 536847937, 536847977, 536847979,
+    536848009, 536848031, 536848033, 536848073, 536848079, 536848099,
+    536848121, 536848141, 536848159, 536848181, 536848187, 536848199,
+    536848231, 536848243, 536848283, 536848307, 536848309, 536848339,
+    536848357, 536848381, 536848391, 536848393, 536848409, 536848427,
+    536848471, 536848531, 536848541, 536848549, 536848567, 536848601,
+    536848603, 536848619, 536848621, 536848657, 536848673, 536848691,
+    536848709, 536848717, 536848733, 536848757, 536848769, 536848771,
+    536848787, 536848817, 536848843, 536848877, 536848889, 536848903,
+    536848951, 536848973, 536848981, 536848987, 536849011, 536849029,
+    536849111, 536849113, 536849129, 536849143, 536849147, 536849177,
+    536849179, 536849207, 536849249, 536849251, 536849293, 536849297,
+    536849323, 536849329, 536849333, 536849381, 536849399, 536849407,
+    536849419, 536849429, 536849459, 536849497, 536849501, 536849527,
+    536849581, 536849587, 536849597, 536849603, 536849609, 536849629,
+    536849633, 536849639, 536849641, 536849669, 536849671, 536849683,
+    536849741, 536849759, 536849771, 536849809, 536849843, 536849857,
+    536849891, 536849899, 536849917, 536849939, 536850007, 536850031,
+    536850037, 536850077, 536850113, 536850133, 536850161, 536850173,
+    536850211, 536850217, 536850221, 536850229, 536850247, 536850253,
+    536850257, 536850271, 536850277, 536850289, 536850323, 536850329,
+    536850331, 536850367, 536850373, 536850389, 536850421, 536850439,
+    536850469, 536850487, 536850511, 536850547, 536850553, 536850607,
+    536850637, 536850661, 536850703, 536850709, 536850733, 536850737,
+    536850739, 536850749, 536850763, 536850791, 536850841, 536850859,
+    536850907, 536850911, 536850913, 536850917, 536850959, 536850997,
+    536851009, 536851013, 536851033, 536851037, 536851039, 536851043,
+    536851069, 536851097, 536851111, 536851127, 536851129, 536851157,
+    536851169, 536851187, 536851199, 536851223, 536851243, 536851261,
+    536851307, 536851333, 536851409, 536851411, 536851429, 536851433,
+    536851489, 536851507, 536851573, 536851607, 536851633, 536851657,
+    536851673, 536851699, 536851729, 536851751, 536851781, 536851793,
+    536851829, 536851867, 536851871, 536851873, 536851877, 536851883,
+    536851927, 536851933, 536851943, 536851949, 536851951, 536851969,
+    536851979, 536852009, 536852021, 536852059, 536852083, 536852093,
+    536852111, 536852137, 536852143, 536852149, 536852167, 536852179,
+    536852191, 536852213, 536852227, 536852273, 536852297, 536852347,
+    536852357, 536852369, 536852419, 536852431, 536852489, 536852501,
+    536852507, 536852509, 536852531, 536852557, 536852587, 536852593,
+    536852599, 536852627, 536852629, 536852689, 536852711, 536852713,
+    536852747, 536852759, 536852783, 536852801, 536852819, 536852851,
+    536852857, 536852863, 536852891, 536852903, 536852909, 536852929,
+    536852933, 536852951, 536852971, 536852993, 536853001, 536853011,
+    536853061, 536853127, 536853137, 536853197, 536853241, 536853283,
+    536853293, 536853299, 536853301, 536853311, 536853329, 536853371,
+    536853403, 536853413, 536853433, 536853437, 536853479, 536853491,
+    536853503, 536853517, 536853521, 536853529, 536853533, 536853563,
+    536853571, 536853617, 536853661, 536853671, 536853677, 536853679,
+    536853689, 536853719, 536853739, 536853749, 536853799, 536853827,
+    536853857, 536853859, 536853869, 536853893, 536853913, 536853937,
+    536853943, 536854009, 536854027, 536854037, 536854057, 536854081,
+    536854117, 536854133, 536854147, 536854159, 536854181, 536854193,
+    536854211, 536854223, 536854259, 536854309, 536854313, 536854333,
+    536854361, 536854379, 536854387, 536854391, 536854403, 536854429,
+    536854459, 536854463, 536854469, 536854471, 536854499, 536854517,
+    536854553, 536854589, 536854607, 536854609, 536854657, 536854663,
+    536854711, 536854723, 536854729, 536854789, 536854859, 536854889,
+    536854909, 536854963, 536854973, 536854991, 536855023, 536855119,
+    536855131, 536855149, 536855153, 536855159, 536855171, 536855201,
+    536855339, 536855369, 536855383, 536855413, 536855441, 536855471,
+    536855477, 536855519, 536855567, 536855591, 536855611, 536855647,
+    536855653, 536855677, 536855747, 536855777, 536855783, 536855789,
+    536855807, 536855819, 536855831, 536855833, 536855843, 536855897,
+    536855899, 536855911, 536855939, 536855953, 536855959, 536855981,
+    536855983, 536855987, 536856011, 536856017, 536856029, 536856049,
+    536856097, 536856101, 536856127, 536856143, 536856169, 536856211,
+    536856217, 536856223, 536856227, 536856241, 536856269, 536856293,
+    536856329, 536856361, 536856389, 536856391, 536856407, 536856431,
+    536856433, 536856443, 536856479, 536856487, 536856493, 536856499,
+    536856521, 536856577, 536856581, 536856611, 536856653, 536856659,
+    536856743, 536856757, 536856779, 536856797, 536856851, 536856877,
+    536856883, 536856893, 536856907, 536856917, 536856949, 536856953,
+    536856959, 536856967, 536857001, 536857033, 536857049, 536857091,
+    536857147, 536857151, 536857187, 536857207, 536857231, 536857247,
+    536857259, 536857327, 536857339, 536857351, 536857357, 536857361,
+    536857381, 536857417, 536857423, 536857439, 536857441, 536857487,
+    536857493, 536857499, 536857507, 536857561, 536857571, 536857589,
+    536857609, 536857619, 536857661, 536857681, 536857691, 536857703,
+    536857729, 536857751, 536857757, 536857771, 536857777, 536857817,
+    536857823, 536857847, 536857883, 536857921, 536857963, 536857991,
+    536857999, 536858039, 536858071, 536858089, 536858099, 536858117,
+    536858143, 536858159, 536858173, 536858177, 536858183, 536858191,
+    536858209, 536858213, 536858219, 536858227, 536858233, 536858261,
+    536858263, 536858297, 536858321, 536858369, 536858381, 536858383,
+    536858389, 536858401, 536858423, 536858437, 536858447, 536858459,
+    536858503, 536858507, 536858513, 536858519, 536858563, 536858587,
+    536858599, 536858603, 536858611, 536858639, 536858659, 536858683,
+    536858689, 536858711, 536858723, 536858731, 536858767, 536858809,
+    536858843, 536858849, 536858869, 536858887, 536858891, 536858923,
+    536858941, 536858981, 536858983, 536858989, 536859019, 536859053,
+    536859119, 536859121, 536859139, 536859151, 536859163, 536859179,
+    536859181, 536859199, 536859229, 536859241, 536859251, 536859259,
+    536859263, 536859287, 536859293, 536859299, 536859341, 536859359,
+    536859377, 536859403, 536859413, 536859451, 536859461, 536859469,
+    536859493, 536859523, 536859539, 536859551, 536859559, 536859569,
+    536859577, 536859599, 536859619, 536859623, 536859647, 536859667,
+    536859671, 536859679, 536859683, 536859689, 536859691, 536859731,
+    536859769, 536859787, 536859797, 536859809, 536859857, 536859889,
+    536859901, 536859923, 536859941, 536859959, 536859971, 536859979,
+    536860021, 536860061, 536860073, 536860081, 536860111, 536860123,
+    536860127, 536860157, 536860169, 536860199, 536860217, 536860229,
+    536860231, 536860241, 536860243, 536860249, 536860253, 536860271,
+    536860283, 536860297, 536860301, 536860307, 536860309, 536860327,
+    536860381, 536860399, 536860421, 536860427, 536860477, 536860487,
+    536860507, 536860531, 536860567, 536860579, 536860589, 536860603,
+    536860609, 536860613, 536860631, 536860669, 536860717, 536860721,
+    536860729, 536860741, 536860747, 536860771, 536860781, 536860783,
+    536860811, 536860813, 536860829, 536860843, 536860859, 536860879,
+    536860913, 536860937, 536860943, 536860949, 536860957, 536860967,
+    536860981, 536860997, 536861047, 536861057, 536861077, 536861099,
+    536861107, 536861113, 536861123, 536861153, 536861161, 536861167,
+    536861177, 536861189, 536861191, 536861197, 536861203, 536861209,
+    536861219, 536861233, 536861243, 536861251, 536861279, 536861287,
+    536861291, 536861293, 536861329, 536861333, 536861357, 536861363,
+    536861387, 536861389, 536861431, 536861447, 536861461, 536861467,
+    536861497, 536861519, 536861597, 536861609, 536861621, 536861629,
+    536861681, 536861707, 536861723, 536861753, 536861761, 536861771,
+    536861779, 536861797, 536861803, 536861807, 536861851, 536861863,
+    536861869, 536861873, 536861879, 536861903, 536861911, 536861933,
+    536861939, 536861947, 536861957, 536861981, 536862031, 536862047,
+    536862071, 536862097, 536862101, 536862103, 536862107, 536862127,
+    536862133, 536862191, 536862197, 536862199, 536862203, 536862211,
+    536862269, 536862283, 536862289, 536862301, 536862307, 536862331,
+    536862373, 536862377, 536862419, 536862427, 536862451, 536862457,
+    536862479, 536862511, 536862539, 536862541, 536862551, 536862577,
+    536862581, 536862589, 536862607, 536862617, 536862629, 536862643,
+    536862679, 536862701, 536862719, 536862731, 536862751, 536862793,
+    536862827, 536862829, 536862847, 536862871, 536862901, 536862947,
+    536863001, 536863037, 536863039, 536863057, 536863073, 536863091,
+    536863099, 536863121, 536863139, 536863189, 536863193, 536863199,
+    536863231, 536863237, 536863253, 536863267, 536863289, 536863331,
+    536863333, 536863343, 536863367, 536863403, 536863421, 536863427,
+    536863433, 536863441, 536863489, 536863511, 536863567, 536863571,
+    536863577, 536863583, 536863627, 536863637, 536863651, 536863693,
+    536863703, 536863709, 536863711, 536863721, 536863727, 536863763,
+    536863771, 536863787, 536863793, 536863801, 536863813, 536863823,
+    536863843, 536863879, 536863889, 536863897, 536863903, 536863937,
+    536863997, 536864011, 536864021, 536864023, 536864089, 536864123,
+    536864149, 536864161, 536864197, 536864213, 536864227, 536864239,
+    536864297, 536864333, 536864347, 536864353, 536864357, 536864359,
+    536864381, 536864407, 536864429, 536864453, 536864509, 536864521,
+    536864527, 536864569, 536864609, 536864621, 536864651, 536864681,
+    536864693, 536864707, 536864723, 536864729, 536864747, 536864759,
+    536864767, 536864771, 536864773, 536864837, 536864891, 536864957,
+    536864963, 536864987, 536864989, 536865001, 536865059, 536865061,
+    536865071, 536865073, 536865097, 536865101, 536865107, 536865127,
+    536865167, 536865187, 536865211, 536865233, 536865239, 536865269,
+    536865281, 536865289, 536865317, 536865323, 536865353, 536865359,
+    536865377, 536865383, 536865397, 536865403, 536865419, 536865437,
+    536865451, 536865503, 536865529, 536865541, 536865607, 536865613,
+    536865619, 536865629, 536865649, 536865683, 536865689, 536865709,
+    536865713, 536865727, 536865737, 536865761, 536865773, 536865787,
+    536865799, 536865809, 536865851, 536865859, 536865863, 536865869,
+    536865877, 536865887, 536865911, 536865949, 536865961, 536865983,
+    536866019, 536866087, 536866111, 536866117, 536866129, 536866133,
+    536866151, 536866199, 536866201, 536866247, 536866249, 536866303,
+    536866321, 536866333, 536866349, 536866381, 536866387, 536866397,
+    536866399, 536866439, 536866441, 536866459, 536866513, 536866523,
+    536866543, 536866573, 536866607, 536866609, 536866637, 536866639,
+    536866651, 536866657, 536866663, 536866697, 536866723, 536866727,
+    536866769, 536866807, 536866819, 536866823, 536866849, 536866861,
+    536866931, 536866933, 536867011, 536867027, 536867029, 536867033,
+    536867057, 536867099, 536867119, 536867141, 536867143, 536867147,
+    536867153, 536867167, 536867179, 536867189, 536867197, 536867237,
+    536867291, 536867347, 536867351, 536867377, 536867381, 536867389,
+    536867411, 536867473, 536867503, 536867509, 536867519, 536867533,
+    536867537, 536867557, 536867593, 536867651, 536867657, 536867663,
+    536867677, 536867741, 536867753, 536867761, 536867797, 536867809,
+    536867813, 536867833, 536867839, 536867843, 536867867, 536867869,
+    536867873, 536867879, 536867897, 536867911, 536867917, 536867927,
+    536867941, 536867993, 536868019, 536868053, 536868067, 536868071,
+    536868083, 536868091, 536868103, 536868107, 536868149, 536868181,
+    536868191, 536868193, 536868197, 536868209, 536868221, 536868223,
+    536868289, 536868341, 536868377, 536868379, 536868403, 536868407,
+    536868419, 536868433, 536868443, 536868467, 536868511, 536868539,
+    536868547, 536868569, 536868583, 536868587, 536868589, 536868593,
+    536868623, 536868649, 536868659, 536868697, 536868707, 536868743,
+    536868749, 536868781, 536868797, 536868799, 536868811, 536868821,
+    536868863, 536868901, 536868953, 536868961, 536868973, 536868977,
+    536868979, 536869043, 536869097, 536869117, 536869153, 536869159,
+    536869189, 536869217, 536869247, 536869283, 536869331, 536869387,
+    536869409, 536869423, 536869447, 536869471, 536869483, 536869523,
+    536869549, 536869559, 536869573, 536869583, 536869589, 536869603,
+    536869607, 536869631, 536869633, 536869637, 536869651, 536869679,
+    536869693, 536869747, 536869769, 536869771, 536869777, 536869787,
+    536869793, 536869829, 536869831, 536869891, 536869901, 536869919,
+    536869937, 536869943, 536869951, 536869999, 536870027, 536870041,
+    536870057, 536870063, 536870123, 536870153, 536870167, 536870171,
+    536870219, 536870233, 536870239, 536870267, 536870273, 536870297,
+    536870303, 536870317, 536870363, 536870401, 536870473, 536870497,
+    536870501, 536870513, 536870561, 536870563, 536870569, 536870573,
+    536870599, 536870603, 536870611, 536870627, 536870641, 536870657,
+    536870683, 536870701, 536870717, 536870723, 536870729, 536870743,
+    536870767, 536870779, 536870791, 536870813, 536870819, 536870837,
+    536870839, 536870849, 536870869, 536870879, 536870909, 0
+};
+
+#endif /* ! INCL_CF_PRIMETAB_H */
diff --git a/factory/cf_random.cc b/factory/cf_random.cc
new file mode 100644
index 0000000..be1d872
--- /dev/null
+++ b/factory/cf_random.cc
@@ -0,0 +1,179 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+
+#include "config.h"
+
+
+#include <time.h>
+
+#include "cf_assert.h"
+
+#include "cf_defs.h"
+#include "cf_random.h"
+#include "ffops.h"
+#include "gfops.h"
+#include "imm.h"
+
+class RandomGenerator {
+private:
+    const int ia, im, iq, ir, deflt;
+    int s;
+
+    // s must not equal zero!
+    void seedInit( int ss ) { s = ((ss == 0) ? deflt : ss); }
+public:
+    RandomGenerator();
+    RandomGenerator( int ss );
+    ~RandomGenerator() {}
+    int generate();
+    void seed( int ss ) { seedInit( ss ); }
+};
+
+RandomGenerator::RandomGenerator() : ia(16807), im(2147483647), iq(127773), ir(2836), deflt(123459876)
+{
+  seedInit( (int)time( 0 ) );
+}
+
+RandomGenerator::RandomGenerator( int ss ) : ia(16807), im(2147483647), iq(127773), ir(2836), deflt(123459876)
+{
+  seedInit( ss );
+}
+
+int
+RandomGenerator::generate()
+{
+    int k;
+
+    k = s/iq;
+    s = ia*(s-k*iq)-ir*k;
+    if ( s < 0 ) s += im;
+
+    return s;
+}
+
+RandomGenerator ranGen;
+
+CanonicalForm FFRandom::generate () const
+{
+    return CanonicalForm( int2imm_p( factoryrandom( ff_prime ) ) );
+}
+
+CFRandom * FFRandom::clone () const
+{
+    return new FFRandom();
+}
+
+CanonicalForm GFRandom::generate () const
+{
+    int i= factoryrandom( gf_q );
+    if ( i == gf_q1 ) i++;
+    return CanonicalForm( int2imm_gf( i ) );
+}
+
+CFRandom * GFRandom::clone () const
+{
+    return new GFRandom();
+}
+
+
+IntRandom::IntRandom()
+{
+    max = 50;
+}
+
+IntRandom::IntRandom( int m )
+{
+    max = m;
+}
+
+IntRandom::~IntRandom() {}
+
+CanonicalForm IntRandom::generate() const
+{
+    return factoryrandom( 2*max )-max;
+}
+
+CFRandom * IntRandom::clone() const
+{
+    return new IntRandom( max );
+}
+
+AlgExtRandomF::AlgExtRandomF()
+{
+    ASSERT( 0, "not a valid random generator" );
+}
+
+AlgExtRandomF::AlgExtRandomF( const AlgExtRandomF & )
+{
+    ASSERT( 0, "not a valid random generator" );
+}
+
+AlgExtRandomF& AlgExtRandomF::operator= ( const AlgExtRandomF & )
+{
+    ASSERT( 0, "not a valid random generator" );
+    return *this;
+}
+
+AlgExtRandomF::AlgExtRandomF( const Variable & v )
+{
+    ASSERT( v.level() < 0, "not an algebraic extension" );
+    algext = v;
+    n = degree( getMipo( v ) );
+    gen = CFRandomFactory::generate();
+}
+
+AlgExtRandomF::AlgExtRandomF( const Variable & v1, const Variable & v2 )
+{
+    ASSERT( v1.level() < 0 && v2.level() < 0 && v1 != v2, "not an algebraic extension" );
+    algext = v2;
+    n = degree( getMipo( v2 ) );
+    gen = new AlgExtRandomF( v1 );
+}
+
+AlgExtRandomF::AlgExtRandomF( const Variable & v, CFRandom * g, int nn )
+{
+    algext = v;
+    n = nn;
+    gen = g;
+}
+
+AlgExtRandomF::~AlgExtRandomF()
+{
+    delete gen;
+}
+
+CanonicalForm AlgExtRandomF::generate() const
+{
+    CanonicalForm result;
+    for ( int i = 0; i < n; i++ )
+      result += power( algext, i ) * gen->generate();
+    return result;
+}
+
+CFRandom * AlgExtRandomF::clone () const
+{
+    return new AlgExtRandomF( algext, gen->clone(), n );
+}
+
+CFRandom * CFRandomFactory::generate()
+{
+    if ( getCharacteristic() == 0 )
+        return new IntRandom();
+    if ( getGFDegree() > 1 )
+        return new GFRandom();
+    else
+        return new FFRandom();
+}
+
+int factoryrandom( int n )
+{
+    if ( n == 0 )
+        return (int)ranGen.generate();
+    else
+        return ranGen.generate() % n;
+}
+
+void factoryseed ( int s )
+{
+    ranGen.seed( s );
+}
diff --git a/factory/cf_random.h b/factory/cf_random.h
new file mode 100644
index 0000000..252bc82
--- /dev/null
+++ b/factory/cf_random.h
@@ -0,0 +1,100 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+/**
+ * @file cf_random.h
+ *
+ * generate random integers, random elements of finite fields
+**/
+
+#ifndef INCL_CF_RANDOM_H
+#define INCL_CF_RANDOM_H
+
+// #include "config.h"
+
+#include "canonicalform.h"
+
+/*BEGINPUBLIC*/
+
+/**
+ * virtual class for random element generation
+**/
+class CFRandom {
+public:
+    virtual ~CFRandom() {}
+    virtual CanonicalForm generate() const { return 0; }
+    virtual CFRandom * clone() const { return new CFRandom(); }
+};
+
+/**
+ * generate random elements in GF
+**/
+class GFRandom : public CFRandom
+{
+public:
+    GFRandom() {};
+    ~GFRandom() {}
+    CanonicalForm generate() const;
+    CFRandom * clone() const;
+};
+
+/**
+ * generate random elements in F_p
+**/
+class FFRandom : public CFRandom
+{
+public:
+    FFRandom() {}
+    ~FFRandom() {}
+    CanonicalForm generate() const;
+    CFRandom * clone() const;
+};
+
+/**
+ * generate random integers
+**/
+class IntRandom : public CFRandom
+{
+private:
+    int max;
+public:
+    IntRandom();
+    IntRandom( int m );
+    ~IntRandom();
+    CanonicalForm generate() const;
+    CFRandom * clone() const;
+};
+
+/**
+ * generate random elements in F_p(alpha)
+**/
+class AlgExtRandomF : public CFRandom {
+private:
+    Variable algext;
+    CFRandom * gen;
+    int n;
+    AlgExtRandomF();
+    AlgExtRandomF( const Variable & v, CFRandom * g, int nn );
+    AlgExtRandomF& operator= ( const AlgExtRandomF & );
+public:
+    AlgExtRandomF( const AlgExtRandomF & );
+    AlgExtRandomF( const Variable & v );
+    AlgExtRandomF( const Variable & v1, const Variable & v2 );
+    ~AlgExtRandomF();
+    CanonicalForm generate() const;
+    CFRandom * clone() const;
+};
+
+class CFRandomFactory {
+public:
+    static CFRandom * generate();
+};
+
+/// random integers with abs less than n
+int factoryrandom( int n );
+
+/// random seed initializer
+void factoryseed( int s );
+
+/*ENDPUBLIC*/
+
+#endif /* ! INCL_CF_RANDOM_H */
diff --git a/factory/cf_resultant.cc b/factory/cf_resultant.cc
new file mode 100644
index 0000000..278dc35
--- /dev/null
+++ b/factory/cf_resultant.cc
@@ -0,0 +1,240 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+/**
+ *
+ * @file cf_resultant.cc
+ *
+ * algorithms for calculating resultants.
+ *
+ * Header file: cf_algorithm.h
+ *
+**/
+
+
+#include "config.h"
+
+
+#include "cf_assert.h"
+
+#include "canonicalform.h"
+#include "variable.h"
+#include "cf_algorithm.h"
+
+/** CFArray subResChain ( const CanonicalForm & f, const CanonicalForm & g, const Variable & x )
+ *
+ * subResChain() - caculate extended subresultant chain.
+ *
+ * The chain is calculated from f and g with respect to variable
+ * x which should not be an algebraic variable.  If f or q equals
+ * zero, an array consisting of one zero entry is returned.
+ *
+ * Note: this is not the standard subresultant chain but the
+ * *extended* chain!
+ *
+ * This algorithm is from the article of R. Loos - 'Generalized
+ * Polynomial Remainder Sequences' in B. Buchberger - 'Computer
+ * Algebra - Symbolic and Algebraic Computation' with some
+ * necessary extensions concerning the calculation of the first
+ * step.
+ *
+**/
+CFArray
+subResChain ( const CanonicalForm & f, const CanonicalForm & g, const Variable & x )
+{
+    ASSERT( x.level() > 0, "cannot calculate subresultant sequence with respect to algebraic variables" );
+
+    CFArray trivialResult( 0, 0 );
+    CanonicalForm F, G;
+    Variable X;
+
+    // some checks on triviality
+    if ( f.isZero() || g.isZero() ) {
+        trivialResult[0] = 0;
+        return trivialResult;
+    }
+
+    // make x main variable
+    if ( f.mvar() > x || g.mvar() > x ) {
+        if ( f.mvar() > g.mvar() )
+            X = f.mvar();
+        else
+            X = g.mvar();
+        F = swapvar( f, X, x );
+        G = swapvar( g, X, x );
+    }
+    else {
+        X = x;
+        F = f;
+        G = g;
+    }
+    // at this point, we have to calculate the sequence of F and
+    // G in respect to X where X is equal to or greater than the
+    // main variables of F and G
+
+    // initialization of chain
+    int m = degree( F, X );
+    int n = degree( G, X );
+
+    int j = (m <= n) ? n : m-1;
+    int r;
+
+    CFArray S( 0, j+1 );
+    CanonicalForm R;
+    S[j+1] = F; S[j] = G;
+
+    // make sure that S[j+1] is regular and j < n
+    if ( m == n && j > 0 ) {
+        S[j-1] = LC( S[j], X ) * psr( S[j+1], S[j], X );
+        j--;
+    } else if ( m < n ) {
+        S[j-1] = LC( S[j], X ) * LC( S[j], X ) * S[j+1];
+        j--;
+    } else if ( m > n && j > 0 ) {
+        // calculate first step
+        r = degree( S[j], X );
+        R = LC( S[j+1], X );
+
+        // if there was a gap calculate similar polynomial
+        if ( j > r && r >= 0 )
+            S[r] = power( LC( S[j], X ), j - r ) * S[j] * power( R, j - r );
+
+        if ( r > 0 ) {
+            // calculate remainder
+            S[r-1] = psr( S[j+1], S[j], X ) * power( -R, j - r );
+            j = r-1;
+        }
+    }
+
+    while ( j > 0 ) {
+        // at this point, 0 < j < n and S[j+1] is regular
+        r = degree( S[j], X );
+        R = LC( S[j+1], X );
+
+        // if there was a gap calculate similar polynomial
+        if ( j > r && r >= 0 )
+            S[r] = (power( LC( S[j], X ), j - r ) * S[j]) / power( R, j - r );
+
+        if ( r <= 0 ) break;
+        // calculate remainder
+        S[r-1] = psr( S[j+1], S[j], X ) / power( -R, j - r + 2 );
+
+        j = r-1;
+        // again 0 <= j < r <= jOld and S[j+1] is regular
+    }
+
+    for ( j = 0; j <= S.max(); j++ ) {
+        // reswap variables if necessary
+        if ( X != x ) {
+            S[j] = swapvar( S[j], X, x );
+        }
+    }
+
+    return S;
+}
+
+/** static CanonicalForm trivialResultant ( const CanonicalForm & f, const CanonicalForm & g, const Variable & x )
+ *
+ * trivialResultant - calculate trivial resultants.
+ *
+ * x's level should be larger than f's and g's levels.  Either f
+ * or g should be constant or both linear.
+ *
+ * Used by resultant().
+ *
+**/
+static CanonicalForm
+trivialResultant ( const CanonicalForm & f, const CanonicalForm & g, const Variable & x )
+{
+    // f or g in R
+    if ( degree( f, x ) == 0 )
+        return power( f, degree( g, x ) );
+    if ( degree( g, x ) == 0 )
+        return power( g, degree( f, x ) );
+
+    // f and g are linear polynomials
+    return LC( f, x ) * g - LC( g, x ) * f;
+}
+
+/** CanonicalForm resultant ( const CanonicalForm & f, const CanonicalForm & g, const Variable & x )
+ *
+ * resultant() - return resultant of f and g with respect to x.
+ *
+ * The chain is calculated from f and g with respect to variable
+ * x which should not be an algebraic variable.  If f or q equals
+ * zero, zero is returned.  If f is a coefficient with respect to
+ * x, f^degree(g, x) is returned, analogously for g.
+ *
+ * This algorithm serves as a wrapper around other resultant
+ * algorithms which do the real work.  Here we use standard
+ * properties of resultants only.
+ *
+**/
+CanonicalForm
+resultant ( const CanonicalForm & f, const CanonicalForm & g, const Variable & x )
+{
+    ASSERT( x.level() > 0, "cannot calculate resultant with respect to algebraic variables" );
+
+    // some checks on triviality.  We will not use degree( v )
+    // here because this may involve variable swapping.
+    if ( f.isZero() || g.isZero() )
+        return 0;
+    if ( f.mvar() < x )
+        return power( f, g.degree( x ) );
+    if ( g.mvar() < x )
+        return power( g, f.degree( x ) );
+
+    // make x main variale
+    CanonicalForm F, G;
+    Variable X;
+    if ( f.mvar() > x || g.mvar() > x ) {
+        if ( f.mvar() > g.mvar() )
+            X = f.mvar();
+        else
+            X = g.mvar();
+        F = swapvar( f, X, x );
+        G = swapvar( g, X, x );
+    }
+    else {
+        X = x;
+        F = f;
+        G = g;
+    }
+    // at this point, we have to calculate resultant( F, G, X )
+    // where X is equal to or greater than the main variables
+    // of F and G
+
+    int m = degree( F, X );
+    int n = degree( G, X );
+    // catch trivial cases
+    if ( m+n <= 2 || m == 0 || n == 0 )
+        return swapvar( trivialResultant( F, G, X ), X, x );
+
+    // exchange F and G if necessary
+    int flipFactor;
+    if ( m < n ) {
+        CanonicalForm swap = F;
+        F = G; G = swap;
+        int degswap = m;
+        m = n; n = degswap;
+        if ( m & 1 && n & 1 )
+            flipFactor = -1;
+        else
+            flipFactor = 1;
+    } else
+        flipFactor = 1;
+
+    // this is not an effective way to calculate the resultant!
+    CanonicalForm extFactor;
+    if ( m == n ) {
+        if ( n & 1 )
+            extFactor = -LC( G, X );
+        else
+            extFactor = LC( G, X );
+    } else
+        extFactor = power( LC( F, X ), m-n-1 );
+
+    CanonicalForm result;
+    result = subResChain( F, G, X )[0] / extFactor;
+
+    return swapvar( result, X, x ) * flipFactor;
+}
diff --git a/factory/cf_reval.cc b/factory/cf_reval.cc
new file mode 100644
index 0000000..ca0845a
--- /dev/null
+++ b/factory/cf_reval.cc
@@ -0,0 +1,71 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+#define MORE_ZEROES
+
+
+#include "config.h"
+
+
+#include "cf_assert.h"
+
+#include "cf_defs.h"
+#include "cf_reval.h"
+
+
+REvaluation::REvaluation( const REvaluation & e ):Evaluation()
+{
+    if ( e.gen == 0 )
+        gen = 0;
+    else
+        gen = e.gen->clone();
+    values = e.values;
+}
+
+REvaluation::~REvaluation()
+{
+    if ( gen != 0 )
+        delete gen;
+}
+
+REvaluation&
+REvaluation::operator= ( const REvaluation & e )
+{
+    if ( this != &e ) {
+        if (gen!=0)
+          delete gen;
+        values = e.values;
+        if ( e.gen == 0 )
+            gen = 0;
+        else
+            gen = e.gen->clone();
+    }
+    return *this;
+}
+
+void
+REvaluation::nextpoint()
+{
+    int n = values.max();
+    for ( int i = values.min(); i <= n; i++ )
+        values[i] = gen->generate();
+}
+
+void
+REvaluation::nextpoint (int n)
+{
+  int m= values.max();
+  int t= values.min();
+  for (int i= t; i <= m; i++)
+    values [i]= 0;
+
+  if (m == t)
+  {
+    values [t]= gen->generate();
+    return;
+  }
+  for (int i= 0; i < n; i++)
+  {
+    int l= factoryrandom (m - t + 1) + t;
+    values [l]= gen->generate();
+  }
+}
diff --git a/factory/cf_reval.h b/factory/cf_reval.h
new file mode 100644
index 0000000..f652a65
--- /dev/null
+++ b/factory/cf_reval.h
@@ -0,0 +1,41 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+/**
+ * @file cf_reval.h
+ *
+ * generate random evaluation points
+**/
+
+#ifndef INCL_CF_REVAL_H
+#define INCL_CF_REVAL_H
+
+// #include "config.h"
+
+#include "canonicalform.h"
+#include "cf_eval.h"
+#include "cf_random.h"
+
+/*BEGINPUBLIC*/
+
+/**
+ * class to generate random evaluation points
+ *
+ * @sa cf_eval.h
+**/
+class REvaluation : public Evaluation
+{
+protected: // neeeded in FFREvaluation
+    CFRandom * gen;
+public:
+    REvaluation() : Evaluation(), gen(0) {}
+    REvaluation( int min0, int max0, const CFRandom & sample ) : Evaluation( min0, max0 ), gen( sample.clone() ) {}
+    REvaluation( const REvaluation & e );
+    ~REvaluation();
+    REvaluation& operator= ( const REvaluation & e );
+    void nextpoint();
+    void nextpoint(int n);
+};
+
+/*ENDPUBLIC*/
+
+#endif /* ! INCL_CF_REVAL_H */
diff --git a/factory/cf_switches.cc b/factory/cf_switches.cc
new file mode 100644
index 0000000..699ecd7
--- /dev/null
+++ b/factory/cf_switches.cc
@@ -0,0 +1,39 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+/**
+ *
+ * @file cf_switches.cc
+ *
+ * definition of class CFSwitches.
+ *
+ * Used by: cf_globals.cc
+ *
+**/
+
+
+#include "config.h"
+
+
+#include "cf_switches.h"
+#include "cf_defs.h"
+
+/** CFSwitches::CFSwitches ()
+ *
+ * CFSwitches::CFSwitches() - default constructor.
+ *
+ * Turns all switches off.
+ *
+**/
+CFSwitches::CFSwitches ()
+{
+    for ( int i = 0; i < CFSwitchesMax; i++ )
+        switches[i] = false;
+// and set the default (recommended) On-values:
+#ifdef HAVE_NTL
+  On(SW_USE_CHINREM_GCD);
+  //Off(SW_USE_NTL_SORT);
+#endif
+  On(SW_USE_EZGCD);
+  //On(SW_USE_EZGCD_P); // still testing
+  On(SW_USE_QGCD);
+}
diff --git a/factory/cf_switches.h b/factory/cf_switches.h
new file mode 100644
index 0000000..9782ffd
--- /dev/null
+++ b/factory/cf_switches.h
@@ -0,0 +1,77 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+/**
+ *
+ * @file cf_switches.h
+ *
+ * header to cf_switches.cc.
+ *
+**/
+
+
+#ifndef INCL_CF_SWITCHES_H
+#define INCL_CF_SWITCHES_H
+
+// #include "config.h"
+
+/** const int CFSwitchesMax
+ *
+ * const CFSwitchesMax - maximum number of switches.
+ *
+**/
+const int CFSwitchesMax = 8;
+
+/** class CFSwitches
+ *
+ * class CFSwitches - manages boolean switches.
+ *
+ * An object of class `CFSwitches' is simply an array of booleans
+ * with some comfortable access methods (`On()', `isOn()', etc.).
+ * Each object may contain `CFSwitchesMax' switches.  When a new
+ * object of type `CFSwitches' is created, all its switches are
+ * turned off.
+ *
+ * Note: No range checking is done when accessing switches.
+ *
+ * switches: the switches
+ *
+**/
+class CFSwitches
+{
+private:
+    bool switches [CFSwitchesMax];
+
+    CFSwitches ();
+public:
+    // constructors, destructors
+    ~CFSwitches () {}
+
+    static inline CFSwitches& getInstance()
+    {
+       static CFSwitches singleton;
+       return singleton;
+    }
+    // selectors
+    /// switch 's' on
+    void On ( int s ) { switches[s] = true; }
+    /// switch 's' off
+    void Off ( int s ) { switches[s] = false; }
+    /// check if 's' is on
+    bool isOn ( int s ) const { return switches[s]; }
+    /// check if 's' is off
+    bool isOff ( int s ) const { return ! switches[s]; }
+};
+/** CFSwitches cf_glob_switches;
+ *
+ * cf_glob_switches - factory switches.
+ *
+ * This is the only object of type CFSwitches in factory.  It is
+ * used either directly in the low level algorithms or by the
+ * functions On(), Off(), isOn() defined in canonicalform.cc.
+ *
+**/
+// extern CFSwitches& cf_glob_switches;
+// CFSwitches& cf_glob_switches = CFSwitches::getInstance();
+#define cf_glob_switches (CFSwitches::getInstance())
+
+#endif /* ! INCL_CF_SWITCHES_H */
diff --git a/factory/cf_util.cc b/factory/cf_util.cc
new file mode 100644
index 0000000..50de2d9
--- /dev/null
+++ b/factory/cf_util.cc
@@ -0,0 +1,77 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+/**
+ *
+ * @file cf_util.cc
+ *
+ * miscellaneous functions, not necessarily related
+ *   to canonical forms.
+ *
+ * Used by: fac_cantzass.cc, gfops.cc
+ *
+**/
+
+
+#include "config.h"
+
+
+/** int ipower ( int b, int m )
+ *
+ * ipower() - calculate b^m in standard integer arithmetic.
+ *
+ * Note: Beware of overflows.
+ *
+**/
+int ipower ( int b, int m )
+{
+    int prod = 1;
+
+    while ( m != 0 )
+    {
+        if ( m % 2 != 0 )
+            prod *= b;
+        m /= 2;
+        if ( m != 0 )
+            b *= b;
+    }
+    return prod;
+}
+
+int ilog2 (int a)
+{
+  int n = -1;
+  while ( a > 0 )
+  {
+    n++;
+    a /=2;
+  }
+  return n;
+}
+
+int igcd( int a, int b )
+{
+    if ( a < 0 ) a = -a;
+    if ( b < 0 ) b = -b;
+
+    int c;
+
+    while ( b != 0 )
+    {
+        c = a % b;
+        a = b;
+        b = c;
+    }
+    return a;
+}
+
+#include<stdio.h>
+#include<stdlib.h>
+
+void factoryError_intern(const char *s)
+{
+  fputs(s,stderr);
+  abort();
+}
+void (*factoryError)(const char *s) = factoryError_intern;
+
+
diff --git a/factory/cf_util.h b/factory/cf_util.h
new file mode 100644
index 0000000..05cee4e
--- /dev/null
+++ b/factory/cf_util.h
@@ -0,0 +1,18 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+#ifndef INCL_CF_UTIL_H
+#define INCL_CF_UTIL_H
+
+// #include "config.h"
+
+int ilog2 (int a);
+
+/*BEGINPUBLIC*/
+int igcd (int a, int b);
+int ipower ( int b, int n );
+void factoryError_intern(const char *s);
+extern void (*factoryError)(const char *s);
+/*ENDPUBLIC*/
+
+
+#endif /* ! INCL_CF_UTIL_H */
diff --git a/factory/configure b/factory/configure
new file mode 100755
index 0000000..ecf9025
--- /dev/null
+++ b/factory/configure
@@ -0,0 +1,24421 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.69 for factory 4.0.1.
+#
+#
+# Copyright (C) 1992-1996, 1998-2012 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.
+as_myself=
+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
+
+# Use a proper internal environment variable to ensure we don't fall
+  # into an infinite loop, continuously re-executing ourselves.
+  if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then
+    _as_can_reexec=no; export _as_can_reexec;
+    # 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.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+  *v*x* | *x*v* ) as_opts=-vx ;;
+  *v* ) as_opts=-v ;;
+  *x* ) as_opts=-x ;;
+  * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+as_fn_exit 255
+  fi
+  # We don't want this to propagate to other subprocesses.
+          { _as_can_reexec=; unset _as_can_reexec;}
+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
+test -x / || 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 -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || (
+    ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+    ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO
+    ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO
+    PATH=/empty FPATH=/empty; export PATH FPATH
+    test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\
+      || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || 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 :
+  export CONFIG_SHELL
+             # 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.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+  *v*x* | *x*v* ) as_opts=-vx ;;
+  *v* ) as_opts=-v ;;
+  *x* ) as_opts=-x ;;
+  * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+exit 255
+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_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+  test -f "$1" && test -x "$1"
+} # as_fn_executable_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 STATUS 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=$1; test $as_status -eq 0 && as_status=1
+  if test "$4"; then
+    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+  fi
+  $as_echo "$as_me: error: $2" >&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; }
+
+  # If we had to re-execute with $CONFIG_SHELL, we're ensured to have
+  # already done that, so ensure we don't try to do so again and fall
+  # in an infinite loop.  This has already happened in practice.
+  _as_can_reexec=no; export _as_can_reexec
+  # 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 -pR'.
+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+      as_ln_s='cp -pR'
+  elif ln conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s=ln
+  else
+    as_ln_s='cp -pR'
+  fi
+else
+  as_ln_s='cp -pR'
+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
+
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
+
+# 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'"
+
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+
+test -n "$DJDIR" || exec 7<&0 </dev/null
+exec 6>&1
+
+# Name of the host.
+# hostname on some systems (SVR3.2, old GNU/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='factory'
+PACKAGE_TARNAME='factory'
+PACKAGE_VERSION='4.0.1'
+PACKAGE_STRING='factory 4.0.1'
+PACKAGE_BUGREPORT=''
+PACKAGE_URL=''
+
+ac_unique_file="canonicalform.cc"
+# 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
+factory_version
+MAKEHEADERFLAGS
+SING_HAVE_FLINT_FALSE
+SING_HAVE_FLINT_TRUE
+FLINT_HOME
+FLINT_LIBS
+FLINT_CFLAGS
+SING_HAVE_NTL_FALSE
+SING_HAVE_NTL_TRUE
+NTL_LIBS
+NTL_CFLAGS
+SING_HAVE_GMP_FALSE
+SING_HAVE_GMP_TRUE
+GMP_VERSION
+GMP_HOME
+GMP_LIBS
+GMP_CFLAGS
+DOXYGEN_PAPER_SIZE
+DX_COND_latex_FALSE
+DX_COND_latex_TRUE
+DX_COND_pdf_FALSE
+DX_COND_pdf_TRUE
+DX_PDFLATEX
+DX_FLAG_pdf
+DX_COND_ps_FALSE
+DX_COND_ps_TRUE
+DX_EGREP
+DX_DVIPS
+DX_MAKEINDEX
+DX_LATEX
+DX_FLAG_ps
+DX_COND_html_FALSE
+DX_COND_html_TRUE
+DX_FLAG_html
+DX_COND_chi_FALSE
+DX_COND_chi_TRUE
+DX_FLAG_chi
+DX_COND_chm_FALSE
+DX_COND_chm_TRUE
+DX_HHC
+DX_FLAG_chm
+DX_COND_xml_FALSE
+DX_COND_xml_TRUE
+DX_FLAG_xml
+DX_COND_rtf_FALSE
+DX_COND_rtf_TRUE
+DX_FLAG_rtf
+DX_COND_man_FALSE
+DX_COND_man_TRUE
+DX_FLAG_man
+DX_COND_dot_FALSE
+DX_COND_dot_TRUE
+DX_DOT
+DX_FLAG_dot
+DX_COND_doc_FALSE
+DX_COND_doc_TRUE
+DX_PERL
+DX_FLAG_DX_CURRENT_FEATURE
+DX_DOXYGEN
+DX_FLAG_doc
+DX_ENV
+DX_DOCDIR
+DX_CONFIG
+DX_PROJECT
+ENABLE_RESOURCES_FALSE
+ENABLE_RESOURCES_TRUE
+RESOURCES_LIBS
+RESOURCES_INCLUDES
+WITH_PARSER_FOR_CANONICAL_FORM_FALSE
+WITH_PARSER_FOR_CANONICAL_FORM_TRUE
+ENABLE_OMALLOC_FALSE
+ENABLE_OMALLOC_TRUE
+OMALLOC_LIBS
+OMALLOC_INCLUDES
+PKG_REQUIRE
+BISON
+M4
+OTOOL64
+OTOOL
+LIPO
+NMEDIT
+DSYMUTIL
+MANIFEST_TOOL
+RANLIB
+DLLTOOL
+OBJDUMP
+NM
+ac_ct_DUMPBIN
+DUMPBIN
+LD
+FGREP
+EGREP
+GREP
+SED
+host_os
+host_vendor
+host_cpu
+host
+build_os
+build_vendor
+build_cpu
+build
+LIBTOOL
+YFLAGS
+YACC
+LN_S
+CXXCPP
+CPP
+POLYMAKE_CXXFLAGS
+am__fastdepCXX_FALSE
+am__fastdepCXX_TRUE
+CXXDEPMODE
+ac_ct_CXX
+CXXFLAGS
+CXX
+SINGULAR_CFLAGS
+WANT_OPTIMIZATIONFLAGS_FALSE
+WANT_OPTIMIZATIONFLAGS_TRUE
+WANT_DEBUG_FALSE
+WANT_DEBUG_TRUE
+MAINT
+MAINTAINER_MODE_FALSE
+MAINTAINER_MODE_TRUE
+am__fastdepCC_FALSE
+am__fastdepCC_TRUE
+CCDEPMODE
+am__nodep
+AMDEPBACKSLASH
+AMDEP_FALSE
+AMDEP_TRUE
+am__quote
+am__include
+DEPDIR
+OBJEXT
+EXEEXT
+ac_ct_CC
+CPPFLAGS
+LDFLAGS
+CFLAGS
+CC
+ac_ct_AR
+AR
+AM_BACKSLASH
+AM_DEFAULT_VERBOSITY
+AM_DEFAULT_V
+AM_V
+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
+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_silent_rules
+enable_dependency_tracking
+enable_maintainer_mode
+enable_debug
+enable_optimizationflags
+enable_shared
+enable_static
+with_pic
+enable_fast_install
+with_gnu_ld
+with_sysroot
+enable_libtool_lock
+enable_cf_inline
+enable_assertions
+enable_timing
+enable_debugoutput
+enable_streamio
+with_Singular
+enable_omalloc
+enable_doxygen_doc
+enable_doxygen_dot
+enable_doxygen_man
+enable_doxygen_rtf
+enable_doxygen_xml
+enable_doxygen_chm
+enable_doxygen_chi
+enable_doxygen_html
+enable_doxygen_ps
+enable_doxygen_pdf
+with_gmp
+with_ntl
+with_flint
+'
+      ac_precious_vars='build_alias
+host_alias
+target_alias
+CC
+CFLAGS
+LDFLAGS
+LIBS
+CPPFLAGS
+CXX
+CXXFLAGS
+CCC
+CPP
+CXXCPP
+YACC
+YFLAGS
+OMALLOC_INCLUDES
+OMALLOC_LIBS
+RESOURCES_INCLUDES
+RESOURCES_LIBS
+DOXYGEN_PAPER_SIZE'
+
+
+# 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_TARNAME}'
+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= ;;
+  *)    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
+  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 factory 4.0.1 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/factory]
+  --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
+  case $ac_init_help in
+     short | recursive ) echo "Configuration of factory 4.0.1:";;
+   esac
+  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-silent-rules   less verbose build output (undo: "make V=1")
+  --disable-silent-rules  verbose build output (undo: "make V=0")
+  --enable-dependency-tracking
+                          do not reject slow dependency extractors
+  --disable-dependency-tracking
+                          speeds up one-time build
+  --disable-maintainer-mode
+                          disable make rules and dependencies not useful (and
+                          sometimes confusing) to the casual installer
+  --enable-debug          build the debugging version of the libraries
+  --disable-optimizationflags
+                          build the without default optimization flags
+  --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-cf-inline      build Factory with \"configurable inline methods\"
+                          enabled.
+  --disable-assertions    build Factory with no assertions
+  --enable-timing         build Factory so it will print timing information
+  --enable-debugoutput    build Factory so it will print debugging information
+  --enable-streamio       build Factory with stream IO
+  --enable-omalloc        build for use with omalloc
+  --disable-doxygen-doc   don't generate any doxygen documentation
+  --disable-doxygen-dot   don't generate graphics for doxygen documentation
+  --enable-doxygen-man    generate doxygen manual pages
+  --enable-doxygen-rtf    generate doxygen RTF documentation
+  --enable-doxygen-xml    generate doxygen XML documentation
+  --enable-doxygen-chm    generate doxygen compressed HTML help documentation
+  --enable-doxygen-chi    generate doxygen seperate compressed HTML help index
+                          file
+  --disable-doxygen-html  don't generate doxygen plain HTML documentation
+  --enable-doxygen-ps     generate doxygen PostScript documentation
+  --enable-doxygen-pdf    generate doxygen PDF documentation
+
+Optional Packages:
+  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
+  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
+  --with-pic[=PKGS]       try to use only PIC/non-PIC objects [default=use
+                          both]
+  --with-gnu-ld           assume the C compiler uses GNU ld [default=no]
+  --with-sysroot=DIR Search for dependent libraries within DIR
+                        (or the compiler's sysroot if not specified).
+  --without-Singular      (obsolete) build NOT for the use with CAS Singular.
+  --with-gmp= <path>|yes Use GMP library. This library is mandatory for Singular
+	                 compilation. If argument is yes or <empty> that means
+   	       		 the library is reachable with the standard search path
+			 "/usr" or "/usr/local" (set as default). Otherwise you
+			 give the <path> to the directory which contain the
+			 library.
+
+  --with-ntl=<path>|yes|no  Use NTL library. If argument is no, you do not have
+                            the library installed on your machine (set as
+			    default). If argument is yes or <empty> that means
+			    the library is reachable with the standard search
+			    path (/usr or /usr/local). Otherwise you give the
+			    <path> to the directory which contain the library.
+
+  --with-flint=<path>|yes|no  Use FLINT library. If argument is no, you do not have
+                            the library installed on your machine (set as
+			    default). If argument is yes or <empty> that means
+			    the library is reachable with the standard search
+			    path (/usr or /usr/local). Otherwise you give the
+			    <path> to the directory which contain the library.
+
+
+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    (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
+              you have headers in a nonstandard directory <include dir>
+  CXX         C++ compiler command
+  CXXFLAGS    C++ compiler flags
+  CPP         C preprocessor
+  CXXCPP      C++ preprocessor
+  YACC        The `Yet Another Compiler Compiler' implementation to use.
+              Defaults to the first program found out of: `bison -y', `byacc',
+              `yacc'.
+  YFLAGS      The list of arguments that will be passed by default to $YACC.
+              This script will default YFLAGS to the empty string to avoid a
+              default value of `-d' given by some make applications.
+  OMALLOC_INCLUDES
+              INCLUDES for libomalloc
+  OMALLOC_LIBS
+              LIBS for libomalloc
+  RESOURCES_INCLUDES
+              INCLUDES for libresources
+  RESOURCES_LIBS
+              LIBS for libresources
+  DOXYGEN_PAPER_SIZE
+              a4wide (default), a4, letter, legal or executive
+
+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
+factory configure 4.0.1
+generated by GNU Autoconf 2.69
+
+Copyright (C) 2012 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; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_compile
+
+# ac_fn_cxx_try_compile LINENO
+# ----------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_cxx_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_cxx_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; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_cxx_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 ||
+	 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; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_link
+
+# 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; } > conftest.i && {
+	 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; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_cpp
+
+# ac_fn_cxx_try_cpp LINENO
+# ------------------------
+# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
+ac_fn_cxx_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; } > conftest.i && {
+	 test -z "$ac_cxx_preproc_warn_flag$ac_cxx_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; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_cxx_try_cpp
+
+# 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 eval \${$3+:} false; 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; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_header_compile
+
+# 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; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $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 eval \${$3+:} false; 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; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_func
+
+# ac_fn_cxx_try_link LINENO
+# -------------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded.
+ac_fn_cxx_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_cxx_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext && {
+	 test "$cross_compiling" = yes ||
+	 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; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_cxx_try_link
+
+# ac_fn_c_compute_int LINENO EXPR VAR INCLUDES
+# --------------------------------------------
+# Tries to find the compile-time value of EXPR in a program that includes
+# INCLUDES, setting VAR accordingly. Returns whether the value could be
+# computed
+ac_fn_c_compute_int ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if test "$cross_compiling" = yes; then
+    # Depending upon the size, compute the lo and hi bounds.
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) >= 0)];
+test_array [0] = 0;
+return test_array [0];
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_lo=0 ac_mid=0
+  while :; do
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) <= $ac_mid)];
+test_array [0] = 0;
+return test_array [0];
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_hi=$ac_mid; break
+else
+  as_fn_arith $ac_mid + 1 && ac_lo=$as_val
+			if test $ac_lo -le $ac_mid; then
+			  ac_lo= ac_hi=
+			  break
+			fi
+			as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) < 0)];
+test_array [0] = 0;
+return test_array [0];
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_hi=-1 ac_mid=-1
+  while :; do
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) >= $ac_mid)];
+test_array [0] = 0;
+return test_array [0];
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_lo=$ac_mid; break
+else
+  as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val
+			if test $ac_mid -le $ac_hi; then
+			  ac_lo= ac_hi=
+			  break
+			fi
+			as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
+else
+  ac_lo= ac_hi=
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+# Binary search between lo and hi bounds.
+while test "x$ac_lo" != "x$ac_hi"; do
+  as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) <= $ac_mid)];
+test_array [0] = 0;
+return test_array [0];
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_hi=$ac_mid
+else
+  as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+case $ac_lo in #((
+?*) eval "$3=\$ac_lo"; ac_retval=0 ;;
+'') ac_retval=1 ;;
+esac
+  else
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+static long int longval () { return $2; }
+static unsigned long int ulongval () { return $2; }
+#include <stdio.h>
+#include <stdlib.h>
+int
+main ()
+{
+
+  FILE *f = fopen ("conftest.val", "w");
+  if (! f)
+    return 1;
+  if (($2) < 0)
+    {
+      long int i = longval ();
+      if (i != ($2))
+	return 1;
+      fprintf (f, "%ld", i);
+    }
+  else
+    {
+      unsigned long int i = ulongval ();
+      if (i != ($2))
+	return 1;
+      fprintf (f, "%lu", i);
+    }
+  /* Do not output a trailing newline, as this causes \r\n confusion
+     on some platforms.  */
+  return ferror (f) || fclose (f) != 0;
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  echo >>conftest.val; read $3 <conftest.val; ac_retval=0
+else
+  ac_retval=1
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+rm -f conftest.val
+
+  fi
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_compute_int
+
+# 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 eval \${$3+:} false; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; 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.i 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 eval \${$3+:} false; 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; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_header_mongrel
+
+# ac_fn_cxx_try_run LINENO
+# ------------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes
+# that executables *can* be run.
+ac_fn_cxx_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; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_cxx_try_run
+
+# ac_fn_cxx_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_cxx_check_header_mongrel ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if eval \${$3+:} false; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; 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_cxx_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_cxx_try_cpp "$LINENO"; then :
+  ac_header_preproc=yes
+else
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.i 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_cxx_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 eval \${$3+:} false; 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; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_cxx_check_header_mongrel
+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 factory $as_me 4.0.1, which was
+generated by GNU Autoconf 2.69.  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
+
+    $as_echo "## ---------------- ##
+## Cache variables. ##
+## ---------------- ##"
+    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
+
+    $as_echo "## ----------------- ##
+## Output variables. ##
+## ----------------- ##"
+    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
+      $as_echo "## ------------------- ##
+## File substitutions. ##
+## ------------------- ##"
+      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
+      $as_echo "## ----------- ##
+## confdefs.h. ##
+## ----------- ##"
+      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
+  # We do not want a PATH search for config.site.
+  case $CONFIG_SITE in #((
+    -*)  ac_site_file1=./$CONFIG_SITE;;
+    */*) ac_site_file1=$CONFIG_SITE;;
+    *)   ac_site_file1=./$CONFIG_SITE;;
+  esac
+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 /dev/null != "$ac_site_file" && 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" \
+      || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "failed to load site script $ac_site_file
+See \`config.log' for more details" "$LINENO" 5; }
+  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.  DJGPP emulates it as a regular file.
+  if test /dev/null != "$cache_file" && 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_aux_dir=
+for ac_dir in ../build-aux "$srcdir"/../build-aux; do
+  if test -f "$ac_dir/install-sh"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install-sh -c"
+    break
+  elif test -f "$ac_dir/install.sh"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install.sh -c"
+    break
+  elif test -f "$ac_dir/shtool"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/shtool install -c"
+    break
+  fi
+done
+if test -z "$ac_aux_dir"; then
+  as_fn_error $? "cannot find install-sh, install.sh, or shtool in ../build-aux \"$srcdir\"/../build-aux" "$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.
+
+
+ac_config_headers="$ac_config_headers _config.h"
+
+
+am__api_version='1.13'
+
+# 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 ${ac_cv_path_install+:} false; 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 as_fn_executable_p "$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; }
+# 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 (
+   am_has_slept=no
+   for am_try in 1 2; do
+     echo "timestamp, slept: $am_has_slept" > conftest.file
+     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
+     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
+     if test "$2" = conftest.file || test $am_try -eq 2; then
+       break
+     fi
+     # Just in case.
+     sleep 1
+     am_has_slept=yes
+   done
+   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; }
+# If we didn't sleep, we still need to ensure time stamps of config.status and
+# generated files are strictly newer.
+am_sleep_pid=
+if grep 'slept: no' conftest.file >/dev/null 2>&1; then
+  ( sleep 1 ) &
+  am_sleep_pid=$!
+fi
+
+rm -f conftest.file
+
+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 --is-lightweight"; then
+  am_missing_run="$MISSING "
+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 ${ac_cv_prog_STRIP+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_STRIP+:} false; 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 as_fn_executable_p "$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 ${ac_cv_path_mkdir+:} false; 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
+	   as_fn_executable_p "$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
+
+  test -d ./--version && rmdir ./--version
+  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.
+    MKDIR_P="$ac_install_sh -d"
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5
+$as_echo "$MKDIR_P" >&6; }
+
+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 ${ac_cv_prog_AWK+:} false; 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 as_fn_executable_p "$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 eval \${ac_cv_prog_make_${ac_make}_set+:} false; 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
+
+# Check whether --enable-silent-rules was given.
+if test "${enable_silent_rules+set}" = set; then :
+  enableval=$enable_silent_rules;
+fi
+
+case $enable_silent_rules in # (((
+  yes) AM_DEFAULT_VERBOSITY=0;;
+   no) AM_DEFAULT_VERBOSITY=1;;
+    *) AM_DEFAULT_VERBOSITY=1;;
+esac
+am_make=${MAKE-make}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5
+$as_echo_n "checking whether $am_make supports nested variables... " >&6; }
+if ${am_cv_make_support_nested_variables+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if $as_echo 'TRUE=$(BAR$(V))
+BAR0=false
+BAR1=true
+V=1
+am__doit:
+	@$(TRUE)
+.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then
+  am_cv_make_support_nested_variables=yes
+else
+  am_cv_make_support_nested_variables=no
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5
+$as_echo "$am_cv_make_support_nested_variables" >&6; }
+if test $am_cv_make_support_nested_variables = yes; then
+    AM_V='$(V)'
+  AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
+else
+  AM_V=$AM_DEFAULT_VERBOSITY
+  AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY
+fi
+AM_BACKSLASH='\'
+
+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='factory'
+ VERSION='4.0.1'
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE "$PACKAGE"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define VERSION "$VERSION"
+_ACEOF
+
+# 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"}
+
+# For better backward compatibility.  To be removed once Automake 1.9.x
+# dies out for good.  For more background, see:
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
+mkdir_p='$(MKDIR_P)'
+
+# We need awk for the "check" target.  The system "awk" is bad on
+# some platforms.
+# Always define AMTAR for backward compatibility.  Yes, it's still used
+# in the wild :-(  We should find a proper way to deprecate it ...
+AMTAR='$${TAR-tar}'
+
+
+# We'll loop over all known methods to create a tar archive until one works.
+_am_tools='gnutar  pax cpio none'
+
+am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'
+
+
+
+
+
+ # -Wno-extra-portability -Werror silent-rules
+# Check whether --enable-silent-rules was given.
+if test "${enable_silent_rules+set}" = set; then :
+  enableval=$enable_silent_rules;
+fi
+
+case $enable_silent_rules in # (((
+  yes) AM_DEFAULT_VERBOSITY=0;;
+   no) AM_DEFAULT_VERBOSITY=1;;
+    *) AM_DEFAULT_VERBOSITY=0;;
+esac
+am_make=${MAKE-make}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5
+$as_echo_n "checking whether $am_make supports nested variables... " >&6; }
+if ${am_cv_make_support_nested_variables+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if $as_echo 'TRUE=$(BAR$(V))
+BAR0=false
+BAR1=true
+V=1
+am__doit:
+	@$(TRUE)
+.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then
+  am_cv_make_support_nested_variables=yes
+else
+  am_cv_make_support_nested_variables=no
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5
+$as_echo "$am_cv_make_support_nested_variables" >&6; }
+if test $am_cv_make_support_nested_variables = yes; then
+    AM_V='$(V)'
+  AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
+else
+  AM_V=$AM_DEFAULT_VERBOSITY
+  AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY
+fi
+AM_BACKSLASH='\'
+
+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='\'
+  am__nodep='_no'
+fi
+ if test "x$enable_dependency_tracking" != xno; then
+  AMDEP_TRUE=
+  AMDEP_FALSE='#'
+else
+  AMDEP_TRUE='#'
+  AMDEP_FALSE=
+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 ${ac_cv_prog_CC+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_CC+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_CC+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_CC+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_CC+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_CC+:} false; 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 as_fn_executable_p "$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
+  fi
+  rm -f conftest.er1 conftest.err
+  $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.  */
+
+int
+main ()
+{
+
+  ;
+  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"
+# 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 whether the C compiler works" >&5
+$as_echo_n "checking whether the C compiler works... " >&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
+if test -z "$ac_file"; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+$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 77 "C compiler cannot create executables
+See \`config.log' for more details" "$LINENO" 5; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+fi
+{ $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; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
+$as_echo "$ac_file" >&6; }
+ac_exeext=$ac_cv_exeext
+
+rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+{ $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 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
+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="$ac_clean_files conftest.out"
+# 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; }
+if test "$cross_compiling" != yes; then
+  { { 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; }
+  if { ac_try='./conftest$ac_cv_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
+    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: $cross_compiling" >&5
+$as_echo "$cross_compiling" >&6; }
+
+rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out
+ac_clean_files=$ac_clean_files_save
+{ $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 ${ac_cv_objext+:} false; 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 ${ac_cv_c_compiler_gnu+:} false; 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 ${ac_cv_prog_cc_g+:} false; 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 ${ac_cv_prog_cc_c89+:} false; 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>
+struct stat;
+/* 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
+
+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 ${am_cv_CC_dependencies_compiler_type+:} false; 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".
+  rm -rf conftest.dir
+  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 10 /bin/sh.
+      echo '/* dummy */' > 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
+      ;;
+    msvc7 | msvc7msys | 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 -n "$ac_tool_prefix"; then
+  for ac_prog in ar lib "link -lib"
+  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 ${ac_cv_prog_AR+:} false; 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_AR="$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
+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
+
+
+    test -n "$AR" && break
+  done
+fi
+if test -z "$AR"; then
+  ac_ct_AR=$AR
+  for ac_prog in ar lib "link -lib"
+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 ${ac_cv_prog_ac_ct_AR+:} false; 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_AR="$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_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
+
+
+  test -n "$ac_ct_AR" && break
+done
+
+  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
+fi
+
+: ${AR=ar}
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the archiver ($AR) interface" >&5
+$as_echo_n "checking the archiver ($AR) interface... " >&6; }
+if ${am_cv_ar_interface+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  am_cv_ar_interface=ar
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+int some_variable = 0;
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  am_ar_try='$AR cru libconftest.a conftest.$ac_objext >&5'
+      { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$am_ar_try\""; } >&5
+  (eval $am_ar_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      if test "$ac_status" -eq 0; then
+        am_cv_ar_interface=ar
+      else
+        am_ar_try='$AR -NOLOGO -OUT:conftest.lib conftest.$ac_objext >&5'
+        { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$am_ar_try\""; } >&5
+  (eval $am_ar_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+        if test "$ac_status" -eq 0; then
+          am_cv_ar_interface=lib
+        else
+          am_cv_ar_interface=unknown
+        fi
+      fi
+      rm -f conftest.lib libconftest.a
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_ar_interface" >&5
+$as_echo "$am_cv_ar_interface" >&6; }
+
+case $am_cv_ar_interface in
+ar)
+  ;;
+lib)
+  # Microsoft lib, so override with the ar-lib wrapper script.
+  # FIXME: It is wrong to rewrite AR.
+  # But if we don't then we get into trouble of one sort or another.
+  # A longer-term fix would be to have automake use am__AR in this case,
+  # and then we could set am__AR="$am_aux_dir/ar-lib \$(AR)" or something
+  # similar.
+  AR="$am_aux_dir/ar-lib $AR"
+  ;;
+unknown)
+  as_fn_error $? "could not determine $AR interface" "$LINENO" 5
+  ;;
+esac
+
+
+
+{ $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=yes
+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
+
+
+
+# Add pre'prefixed config
+
+ac_config_commands="$ac_config_commands config.h"
+
+
+#
+# - check for CC and CXX but be careful about CFLAGS.
+#
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Please note that we set empty defaults for \`CFLAGS' and \`CXXFLAGS' (instead of \`-g -O')" >&5
+$as_echo "$as_me: WARNING: Please note that we set empty defaults for \`CFLAGS' and \`CXXFLAGS' (instead of \`-g -O')" >&2;}
+ : ${CFLAGS:=""}
+ : ${CXXFLAGS:=""}
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts " >&5
+$as_echo_n "checking whether C compiler accepts ... " >&6; }
+if ${ax_cv_check_cflags__+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$CFLAGS
+  CFLAGS="$CFLAGS   -Werror"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ax_cv_check_cflags__=yes
+else
+  ax_cv_check_cflags__=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  CFLAGS=$ax_check_save_flags
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags__" >&5
+$as_echo "$ax_cv_check_cflags__" >&6; }
+if test x"$ax_cv_check_cflags__" = xyes; then :
+  :
+else
+  :
+fi
+
+if ${CFLAGS+:} false; then :
+  case " $CFLAGS " in
+    *"  "*)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS already contains "; } >&5
+  (: CFLAGS already contains ) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      ;;
+    *)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS=\"\$CFLAGS \""; } >&5
+  (: CFLAGS="$CFLAGS ") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      CFLAGS="$CFLAGS "
+      ;;
+   esac
+else
+  CFLAGS=""
+fi
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+if test -z "$CXX"; then
+  if test -n "$CCC"; then
+    CXX=$CCC
+  else
+    if test -n "$ac_tool_prefix"; then
+  for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+  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 ${ac_cv_prog_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CXX"; then
+  ac_cv_prog_CXX="$CXX" # 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CXX="$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
+CXX=$ac_cv_prog_CXX
+if test -n "$CXX"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5
+$as_echo "$CXX" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+    test -n "$CXX" && break
+  done
+fi
+if test -z "$CXX"; then
+  ac_ct_CXX=$CXX
+  for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+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 ${ac_cv_prog_ac_ct_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_CXX"; then
+  ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CXX="$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_CXX=$ac_cv_prog_ac_ct_CXX
+if test -n "$ac_ct_CXX"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5
+$as_echo "$ac_ct_CXX" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$ac_ct_CXX" && break
+done
+
+  if test "x$ac_ct_CXX" = x; then
+    CXX="g++"
+  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
+    CXX=$ac_ct_CXX
+  fi
+fi
+
+  fi
+fi
+# 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
+  fi
+  rm -f conftest.er1 conftest.err
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+done
+
+{ $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 ${ac_cv_cxx_compiler_gnu+:} false; 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_cxx_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_cxx_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5
+$as_echo "$ac_cv_cxx_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+  GXX=yes
+else
+  GXX=
+fi
+ac_test_CXXFLAGS=${CXXFLAGS+set}
+ac_save_CXXFLAGS=$CXXFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5
+$as_echo_n "checking whether $CXX accepts -g... " >&6; }
+if ${ac_cv_prog_cxx_g+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_save_cxx_werror_flag=$ac_cxx_werror_flag
+   ac_cxx_werror_flag=yes
+   ac_cv_prog_cxx_g=no
+   CXXFLAGS="-g"
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ac_cv_prog_cxx_g=yes
+else
+  CXXFLAGS=""
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+
+else
+  ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+	 CXXFLAGS="-g"
+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ac_cv_prog_cxx_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_cxx_werror_flag=$ac_save_cxx_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5
+$as_echo "$ac_cv_prog_cxx_g" >&6; }
+if test "$ac_test_CXXFLAGS" = set; then
+  CXXFLAGS=$ac_save_CXXFLAGS
+elif test $ac_cv_prog_cxx_g = yes; then
+  if test "$GXX" = yes; then
+    CXXFLAGS="-g -O2"
+  else
+    CXXFLAGS="-g"
+  fi
+else
+  if test "$GXX" = yes; then
+    CXXFLAGS="-O2"
+  else
+    CXXFLAGS=
+  fi
+fi
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+depcc="$CXX"  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 ${am_cv_CXX_dependencies_compiler_type+:} false; 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".
+  rm -rf conftest.dir
+  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_CXX_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 10 /bin/sh.
+      echo '/* dummy */' > 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
+      ;;
+    msvc7 | msvc7msys | 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_CXX_dependencies_compiler_type=$depmode
+        break
+      fi
+    fi
+  done
+
+  cd ..
+  rm -rf conftest.dir
+else
+  am_cv_CXX_dependencies_compiler_type=none
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5
+$as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; }
+CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type
+
+ if
+  test "x$enable_dependency_tracking" != xno \
+  && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then
+  am__fastdepCXX_TRUE=
+  am__fastdepCXX_FALSE='#'
+else
+  am__fastdepCXX_TRUE='#'
+  am__fastdepCXX_FALSE=
+fi
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the linker accepts " >&5
+$as_echo_n "checking whether the linker accepts ... " >&6; }
+if ${ax_cv_check_ldflags__+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$LDFLAGS
+  LDFLAGS="$LDFLAGS  "
+  _save_cflags="$CFLAGS"
+  CFLAGS="$CFLAGS -Werror"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ax_cv_check_ldflags__=yes
+else
+  ax_cv_check_ldflags__=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+  CFLAGS="$_save_cflags"
+  LDFLAGS=$ax_check_save_flags
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_ldflags__" >&5
+$as_echo "$ax_cv_check_ldflags__" >&6; }
+if test x"$ax_cv_check_ldflags__" = xyes; then :
+  :
+else
+  :
+fi
+
+
+#  SING_SHOW_FLAGS([Initial state?...])dnl
+
+ # Check whether --enable-debug was given.
+if test "${enable_debug+set}" = set; then :
+  enableval=$enable_debug; ENABLE_DEBUG="$enableval"
+else
+  ENABLE_DEBUG=""
+fi
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking debugging checks should be embedded" >&5
+$as_echo_n "checking debugging checks should be embedded... " >&6; }
+ if test "x${ENABLE_DEBUG}" != xyes; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ fi
+
+ # Check whether --enable-optimizationflags was given.
+if test "${enable_optimizationflags+set}" = set; then :
+  enableval=$enable_optimizationflags; ENABLE_OPTIMIZATION="$enableval"
+else
+  ENABLE_OPTIMIZATION="yeah"
+fi
+
+
+ if test "x${ENABLE_DEBUG}" = xyes; then
+  SINGULAR_CFLAGS=""
+  if test "x${ENABLE_OPTIMIZATION}" = xyeah; then
+   ENABLE_OPTIMIZATION="no"
+   { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Please note that we disable implicit (default) optimization flags since you have enabled the debug flags... " >&5
+$as_echo "$as_me: WARNING: Please note that we disable implicit (default) optimization flags since you have enabled the debug flags... " >&2;}
+  fi
+ else
+  SINGULAR_CFLAGS="-DSING_NDEBUG -DOM_NDEBUG"
+  # for now let '-DSING_NDEBUG -DOM_NDEBUG' be here...
+
+$as_echo "#define OM_NDEBUG 1" >>confdefs.h
+
+
+$as_echo "#define SING_NDEBUG 1" >>confdefs.h
+
+ fi
+
+ if test "x${ENABLE_OPTIMIZATION}" = xyeah; then
+   ENABLE_OPTIMIZATION="yes"
+ fi
+
+ if test "x${ENABLE_OPTIMIZATION}" = xyes; then
+  if test "x${ENABLE_DEBUG}" = xyes; then
+   { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Please note that you will be using our optimization flags together with debug flags... " >&5
+$as_echo "$as_me: WARNING: Please note that you will be using our optimization flags together with debug flags... " >&2;}
+  fi
+ fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether optimization flags should be used" >&5
+$as_echo_n "checking whether optimization flags should be used... " >&6; }
+ if test "x${ENABLE_OPTIMIZATION}" = xyes; 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; }
+ fi
+
+
+  if test x"${ENABLE_DEBUG}" = xyes; then
+  WANT_DEBUG_TRUE=
+  WANT_DEBUG_FALSE='#'
+else
+  WANT_DEBUG_TRUE='#'
+  WANT_DEBUG_FALSE=
+fi
+
+  if test x"${ENABLE_OPTIMIZATION}" = xyes; then
+  WANT_OPTIMIZATIONFLAGS_TRUE=
+  WANT_OPTIMIZATIONFLAGS_FALSE='#'
+else
+  WANT_OPTIMIZATIONFLAGS_TRUE='#'
+  WANT_OPTIMIZATIONFLAGS_FALSE=
+fi
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SINGULAR_CFLAGS "$SINGULAR_CFLAGS"
+_ACEOF
+
+
+
+# SING_SHOW_FLAGS([checking flags....])
+
+ FLAGS="-pipe -fno-common"
+ 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
+
+
+
+for flag in ${FLAGS}; do
+  as_CACHEVAR=`$as_echo "ax_cv_check_cflags__$flag" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts $flag" >&5
+$as_echo_n "checking whether C compiler accepts $flag... " >&6; }
+if eval \${$as_CACHEVAR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$CFLAGS
+  CFLAGS="$CFLAGS  $flag -Werror"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  eval "$as_CACHEVAR=yes"
+else
+  eval "$as_CACHEVAR=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  CFLAGS=$ax_check_save_flags
+fi
+eval ac_res=\$$as_CACHEVAR
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if test x"`eval 'as_val=${'$as_CACHEVAR'};$as_echo "$as_val"'`" = xyes; then :
+  if ${CFLAGS+:} false; then :
+  case " $CFLAGS " in
+    *" $flag "*)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS already contains \$flag"; } >&5
+  (: CFLAGS already contains $flag) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      ;;
+    *)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS=\"\$CFLAGS \$flag\""; } >&5
+  (: CFLAGS="$CFLAGS $flag") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      CFLAGS="$CFLAGS $flag"
+      ;;
+   esac
+else
+  CFLAGS="$flag"
+fi
+
+else
+  :
+fi
+
+done
+
+ 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=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+
+for flag in ${FLAGS}; do
+  as_CACHEVAR=`$as_echo "ax_cv_check_cxxflags__$flag" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C++ compiler accepts $flag" >&5
+$as_echo_n "checking whether C++ compiler accepts $flag... " >&6; }
+if eval \${$as_CACHEVAR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$CXXFLAGS
+  CXXFLAGS="$CXXFLAGS  $flag -Werror"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  eval "$as_CACHEVAR=yes"
+else
+  eval "$as_CACHEVAR=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  CXXFLAGS=$ax_check_save_flags
+fi
+eval ac_res=\$$as_CACHEVAR
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if test x"`eval 'as_val=${'$as_CACHEVAR'};$as_echo "$as_val"'`" = xyes; then :
+  if ${CXXFLAGS+:} false; then :
+  case " $CXXFLAGS " in
+    *" $flag "*)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CXXFLAGS already contains \$flag"; } >&5
+  (: CXXFLAGS already contains $flag) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      ;;
+    *)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CXXFLAGS=\"\$CXXFLAGS \$flag\""; } >&5
+  (: CXXFLAGS="$CXXFLAGS $flag") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      CXXFLAGS="$CXXFLAGS $flag"
+      ;;
+   esac
+else
+  CXXFLAGS="$flag"
+fi
+
+else
+  :
+fi
+
+done
+
+
+
+for flag in -fexceptions -frtti; do
+  as_CACHEVAR=`$as_echo "ax_cv_check_cxxflags__$flag" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C++ compiler accepts $flag" >&5
+$as_echo_n "checking whether C++ compiler accepts $flag... " >&6; }
+if eval \${$as_CACHEVAR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$CXXFLAGS
+  CXXFLAGS="$CXXFLAGS  $flag -Werror"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  eval "$as_CACHEVAR=yes"
+else
+  eval "$as_CACHEVAR=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  CXXFLAGS=$ax_check_save_flags
+fi
+eval ac_res=\$$as_CACHEVAR
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if test x"`eval 'as_val=${'$as_CACHEVAR'};$as_echo "$as_val"'`" = xyes; then :
+  if ${POLYMAKE_CXXFLAGS+:} false; then :
+  case " $POLYMAKE_CXXFLAGS " in
+    *" $flag "*)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : POLYMAKE_CXXFLAGS already contains \$flag"; } >&5
+  (: POLYMAKE_CXXFLAGS already contains $flag) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      ;;
+    *)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : POLYMAKE_CXXFLAGS=\"\$POLYMAKE_CXXFLAGS \$flag\""; } >&5
+  (: POLYMAKE_CXXFLAGS="$POLYMAKE_CXXFLAGS $flag") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      POLYMAKE_CXXFLAGS="$POLYMAKE_CXXFLAGS $flag"
+      ;;
+   esac
+else
+  POLYMAKE_CXXFLAGS="$flag"
+fi
+
+else
+  :
+fi
+
+done
+
+ 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
+
+
+
+
+for flag in ${FLAGS}; do
+  as_CACHEVAR=`$as_echo "ax_cv_check_ldflags__$flag" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the linker accepts $flag" >&5
+$as_echo_n "checking whether the linker accepts $flag... " >&6; }
+if eval \${$as_CACHEVAR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$LDFLAGS
+  LDFLAGS="$LDFLAGS  $flag"
+  _save_cflags="$CFLAGS"
+  CFLAGS="$CFLAGS -Werror"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "$as_CACHEVAR=yes"
+else
+  eval "$as_CACHEVAR=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+  CFLAGS="$_save_cflags"
+  LDFLAGS=$ax_check_save_flags
+fi
+eval ac_res=\$$as_CACHEVAR
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if test x"`eval 'as_val=${'$as_CACHEVAR'};$as_echo "$as_val"'`" = xyes; then :
+  if ${LDFLAGS+:} false; then :
+  case " $LDFLAGS " in
+    *" $flag "*)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : LDFLAGS already contains \$flag"; } >&5
+  (: LDFLAGS already contains $flag) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      ;;
+    *)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : LDFLAGS=\"\$LDFLAGS \$flag\""; } >&5
+  (: LDFLAGS="$LDFLAGS $flag") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      LDFLAGS="$LDFLAGS $flag"
+      ;;
+   esac
+else
+  LDFLAGS="$flag"
+fi
+
+else
+  :
+fi
+
+done
+
+
+
+
+ if test "x${ENABLE_DEBUG}" = xyes; then
+  DBGFLAGS="-g -ftrapv -fdiagnostics-show-option -Wall -Wextra"
+  #  -pedantic too strict ??? -Wvla -Wno-long-long ???
+  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
+
+
+
+for flag in ${DBGFLAGS}; do
+  as_CACHEVAR=`$as_echo "ax_cv_check_cflags__$flag" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts $flag" >&5
+$as_echo_n "checking whether C compiler accepts $flag... " >&6; }
+if eval \${$as_CACHEVAR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$CFLAGS
+  CFLAGS="$CFLAGS  $flag -Werror"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  eval "$as_CACHEVAR=yes"
+else
+  eval "$as_CACHEVAR=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  CFLAGS=$ax_check_save_flags
+fi
+eval ac_res=\$$as_CACHEVAR
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if test x"`eval 'as_val=${'$as_CACHEVAR'};$as_echo "$as_val"'`" = xyes; then :
+  if ${CFLAGS+:} false; then :
+  case " $CFLAGS " in
+    *" $flag "*)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS already contains \$flag"; } >&5
+  (: CFLAGS already contains $flag) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      ;;
+    *)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS=\"\$CFLAGS \$flag\""; } >&5
+  (: CFLAGS="$CFLAGS $flag") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      CFLAGS="$CFLAGS $flag"
+      ;;
+   esac
+else
+  CFLAGS="$flag"
+fi
+
+else
+  :
+fi
+
+done
+
+  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=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+
+for flag in ${DBGFLAGS}; do
+  as_CACHEVAR=`$as_echo "ax_cv_check_cxxflags__$flag" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C++ compiler accepts $flag" >&5
+$as_echo_n "checking whether C++ compiler accepts $flag... " >&6; }
+if eval \${$as_CACHEVAR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$CXXFLAGS
+  CXXFLAGS="$CXXFLAGS  $flag -Werror"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  eval "$as_CACHEVAR=yes"
+else
+  eval "$as_CACHEVAR=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  CXXFLAGS=$ax_check_save_flags
+fi
+eval ac_res=\$$as_CACHEVAR
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if test x"`eval 'as_val=${'$as_CACHEVAR'};$as_echo "$as_val"'`" = xyes; then :
+  if ${CXXFLAGS+:} false; then :
+  case " $CXXFLAGS " in
+    *" $flag "*)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CXXFLAGS already contains \$flag"; } >&5
+  (: CXXFLAGS already contains $flag) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      ;;
+    *)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CXXFLAGS=\"\$CXXFLAGS \$flag\""; } >&5
+  (: CXXFLAGS="$CXXFLAGS $flag") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      CXXFLAGS="$CXXFLAGS $flag"
+      ;;
+   esac
+else
+  CXXFLAGS="$flag"
+fi
+
+else
+  :
+fi
+
+done
+
+  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
+
+
+
+for flag in ${DBGFLAGS}; do
+  as_CACHEVAR=`$as_echo "ax_cv_check_ldflags__$flag" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the linker accepts $flag" >&5
+$as_echo_n "checking whether the linker accepts $flag... " >&6; }
+if eval \${$as_CACHEVAR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$LDFLAGS
+  LDFLAGS="$LDFLAGS  $flag"
+  _save_cflags="$CFLAGS"
+  CFLAGS="$CFLAGS -Werror"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "$as_CACHEVAR=yes"
+else
+  eval "$as_CACHEVAR=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+  CFLAGS="$_save_cflags"
+  LDFLAGS=$ax_check_save_flags
+fi
+eval ac_res=\$$as_CACHEVAR
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if test x"`eval 'as_val=${'$as_CACHEVAR'};$as_echo "$as_val"'`" = xyes; then :
+  if ${LDFLAGS+:} false; then :
+  case " $LDFLAGS " in
+    *" $flag "*)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : LDFLAGS already contains \$flag"; } >&5
+  (: LDFLAGS already contains $flag) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      ;;
+    *)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : LDFLAGS=\"\$LDFLAGS \$flag\""; } >&5
+  (: LDFLAGS="$LDFLAGS $flag") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      LDFLAGS="$LDFLAGS $flag"
+      ;;
+   esac
+else
+  LDFLAGS="$flag"
+fi
+
+else
+  :
+fi
+
+done
+
+ fi
+
+ ## for clang: -Wunneeded-internal-declaration
+
+ if test "x${ENABLE_OPTIMIZATION}" != xno; then
+  OPTFLAGS="-O3 -Wno-unused-function -Wno-trigraphs -Wno-unused-parameter -Wunknown-pragmas -Wno-unused-variable -fomit-frame-pointer -fwrapv -fvisibility=default -finline-functions -fno-exceptions -fno-rtti -fno-threadsafe-statics -fno-enforce-eh-specs -fconserve-space -funroll-loops"
+  #  -O3 - crashes gcc???!!!
+  # -fpermissive
+  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
+
+
+
+for flag in ${OPTFLAGS}; do
+  as_CACHEVAR=`$as_echo "ax_cv_check_cflags__$flag" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts $flag" >&5
+$as_echo_n "checking whether C compiler accepts $flag... " >&6; }
+if eval \${$as_CACHEVAR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$CFLAGS
+  CFLAGS="$CFLAGS  $flag -Werror"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  eval "$as_CACHEVAR=yes"
+else
+  eval "$as_CACHEVAR=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  CFLAGS=$ax_check_save_flags
+fi
+eval ac_res=\$$as_CACHEVAR
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if test x"`eval 'as_val=${'$as_CACHEVAR'};$as_echo "$as_val"'`" = xyes; then :
+  if ${CFLAGS+:} false; then :
+  case " $CFLAGS " in
+    *" $flag "*)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS already contains \$flag"; } >&5
+  (: CFLAGS already contains $flag) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      ;;
+    *)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS=\"\$CFLAGS \$flag\""; } >&5
+  (: CFLAGS="$CFLAGS $flag") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      CFLAGS="$CFLAGS $flag"
+      ;;
+   esac
+else
+  CFLAGS="$flag"
+fi
+
+else
+  :
+fi
+
+done
+
+  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=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+
+for flag in ${OPTFLAGS}; do
+  as_CACHEVAR=`$as_echo "ax_cv_check_cxxflags__$flag" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C++ compiler accepts $flag" >&5
+$as_echo_n "checking whether C++ compiler accepts $flag... " >&6; }
+if eval \${$as_CACHEVAR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$CXXFLAGS
+  CXXFLAGS="$CXXFLAGS  $flag -Werror"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  eval "$as_CACHEVAR=yes"
+else
+  eval "$as_CACHEVAR=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  CXXFLAGS=$ax_check_save_flags
+fi
+eval ac_res=\$$as_CACHEVAR
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if test x"`eval 'as_val=${'$as_CACHEVAR'};$as_echo "$as_val"'`" = xyes; then :
+  if ${CXXFLAGS+:} false; then :
+  case " $CXXFLAGS " in
+    *" $flag "*)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CXXFLAGS already contains \$flag"; } >&5
+  (: CXXFLAGS already contains $flag) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      ;;
+    *)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CXXFLAGS=\"\$CXXFLAGS \$flag\""; } >&5
+  (: CXXFLAGS="$CXXFLAGS $flag") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      CXXFLAGS="$CXXFLAGS $flag"
+      ;;
+   esac
+else
+  CXXFLAGS="$flag"
+fi
+
+else
+  :
+fi
+
+done
+
+#   AX_APPEND_COMPILE_FLAGS([-fno-threadsafe-statics -fno-enforce-eh-specs -fconserve-space], [CXXFLAGS])
+###  AX_APPEND_COMPILE_FLAGS([-fno-implicit-templates], [CXXFLAGS]) # problems due to STL
+  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
+
+
+
+for flag in ${OPTFLAGS}; do
+  as_CACHEVAR=`$as_echo "ax_cv_check_ldflags__$flag" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the linker accepts $flag" >&5
+$as_echo_n "checking whether the linker accepts $flag... " >&6; }
+if eval \${$as_CACHEVAR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$LDFLAGS
+  LDFLAGS="$LDFLAGS  $flag"
+  _save_cflags="$CFLAGS"
+  CFLAGS="$CFLAGS -Werror"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "$as_CACHEVAR=yes"
+else
+  eval "$as_CACHEVAR=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+  CFLAGS="$_save_cflags"
+  LDFLAGS=$ax_check_save_flags
+fi
+eval ac_res=\$$as_CACHEVAR
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if test x"`eval 'as_val=${'$as_CACHEVAR'};$as_echo "$as_val"'`" = xyes; then :
+  if ${LDFLAGS+:} false; then :
+  case " $LDFLAGS " in
+    *" $flag "*)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : LDFLAGS already contains \$flag"; } >&5
+  (: LDFLAGS already contains $flag) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      ;;
+    *)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : LDFLAGS=\"\$LDFLAGS \$flag\""; } >&5
+  (: LDFLAGS="$LDFLAGS $flag") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      LDFLAGS="$LDFLAGS $flag"
+      ;;
+   esac
+else
+  LDFLAGS="$flag"
+fi
+
+else
+  :
+fi
+
+done
+
+#  AX_APPEND_LINK_FLAGS([-fno-threadsafe-statics -fno-enforce-eh-specs -fconserve-space])
+###  AX_APPEND_LINK_FLAGS([-fno-implicit-templates]) # see above :(
+#  AX_APPEND_LINK_FLAGS([ ])
+ fi
+
+ FLAGS2="-Qunused-arguments"
+ 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
+
+
+
+for flag in ${FLAGS2}; do
+  as_CACHEVAR=`$as_echo "ax_cv_check_cflags__$flag" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts $flag" >&5
+$as_echo_n "checking whether C compiler accepts $flag... " >&6; }
+if eval \${$as_CACHEVAR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$CFLAGS
+  CFLAGS="$CFLAGS  $flag -Werror"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  eval "$as_CACHEVAR=yes"
+else
+  eval "$as_CACHEVAR=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  CFLAGS=$ax_check_save_flags
+fi
+eval ac_res=\$$as_CACHEVAR
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if test x"`eval 'as_val=${'$as_CACHEVAR'};$as_echo "$as_val"'`" = xyes; then :
+  if ${CFLAGS+:} false; then :
+  case " $CFLAGS " in
+    *" $flag "*)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS already contains \$flag"; } >&5
+  (: CFLAGS already contains $flag) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      ;;
+    *)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS=\"\$CFLAGS \$flag\""; } >&5
+  (: CFLAGS="$CFLAGS $flag") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      CFLAGS="$CFLAGS $flag"
+      ;;
+   esac
+else
+  CFLAGS="$flag"
+fi
+
+else
+  :
+fi
+
+done
+
+ 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=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+
+for flag in ${FLAGS2}; do
+  as_CACHEVAR=`$as_echo "ax_cv_check_cxxflags__$flag" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C++ compiler accepts $flag" >&5
+$as_echo_n "checking whether C++ compiler accepts $flag... " >&6; }
+if eval \${$as_CACHEVAR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$CXXFLAGS
+  CXXFLAGS="$CXXFLAGS  $flag -Werror"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  eval "$as_CACHEVAR=yes"
+else
+  eval "$as_CACHEVAR=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  CXXFLAGS=$ax_check_save_flags
+fi
+eval ac_res=\$$as_CACHEVAR
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if test x"`eval 'as_val=${'$as_CACHEVAR'};$as_echo "$as_val"'`" = xyes; then :
+  if ${CXXFLAGS+:} false; then :
+  case " $CXXFLAGS " in
+    *" $flag "*)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CXXFLAGS already contains \$flag"; } >&5
+  (: CXXFLAGS already contains $flag) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      ;;
+    *)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CXXFLAGS=\"\$CXXFLAGS \$flag\""; } >&5
+  (: CXXFLAGS="$CXXFLAGS $flag") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      CXXFLAGS="$CXXFLAGS $flag"
+      ;;
+   esac
+else
+  CXXFLAGS="$flag"
+fi
+
+else
+  :
+fi
+
+done
+
+ 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
+
+
+
+
+for flag in ${FLAGS2}; do
+  as_CACHEVAR=`$as_echo "ax_cv_check_ldflags__$flag" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the linker accepts $flag" >&5
+$as_echo_n "checking whether the linker accepts $flag... " >&6; }
+if eval \${$as_CACHEVAR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$LDFLAGS
+  LDFLAGS="$LDFLAGS  $flag"
+  _save_cflags="$CFLAGS"
+  CFLAGS="$CFLAGS -Werror"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "$as_CACHEVAR=yes"
+else
+  eval "$as_CACHEVAR=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+  CFLAGS="$_save_cflags"
+  LDFLAGS=$ax_check_save_flags
+fi
+eval ac_res=\$$as_CACHEVAR
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if test x"`eval 'as_val=${'$as_CACHEVAR'};$as_echo "$as_val"'`" = xyes; then :
+  if ${LDFLAGS+:} false; then :
+  case " $LDFLAGS " in
+    *" $flag "*)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : LDFLAGS already contains \$flag"; } >&5
+  (: LDFLAGS already contains $flag) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      ;;
+    *)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : LDFLAGS=\"\$LDFLAGS \$flag\""; } >&5
+  (: LDFLAGS="$LDFLAGS $flag") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      LDFLAGS="$LDFLAGS $flag"
+      ;;
+   esac
+else
+  LDFLAGS="$flag"
+fi
+
+else
+  :
+fi
+
+done
+
+
+# SING_SHOW_FLAGS([before PROG_C_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
+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 ${ac_cv_prog_CC+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_CC+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_CC+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_CC+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_CC+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_CC+:} false; 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 as_fn_executable_p "$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
+  fi
+  rm -f conftest.er1 conftest.err
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+done
+
+{ $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 ${ac_cv_c_compiler_gnu+:} false; 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 ${ac_cv_prog_cc_g+:} false; 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 ${ac_cv_prog_cc_c89+:} false; 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>
+struct stat;
+/* 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
+
+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 ${am_cv_CC_dependencies_compiler_type+:} false; 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".
+  rm -rf conftest.dir
+  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 10 /bin/sh.
+      echo '/* dummy */' > 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
+      ;;
+    msvc7 | msvc7msys | 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
+
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+if test -z "$CXX"; then
+  if test -n "$CCC"; then
+    CXX=$CCC
+  else
+    if test -n "$ac_tool_prefix"; then
+  for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+  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 ${ac_cv_prog_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CXX"; then
+  ac_cv_prog_CXX="$CXX" # 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CXX="$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
+CXX=$ac_cv_prog_CXX
+if test -n "$CXX"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5
+$as_echo "$CXX" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+    test -n "$CXX" && break
+  done
+fi
+if test -z "$CXX"; then
+  ac_ct_CXX=$CXX
+  for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+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 ${ac_cv_prog_ac_ct_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_CXX"; then
+  ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CXX="$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_CXX=$ac_cv_prog_ac_ct_CXX
+if test -n "$ac_ct_CXX"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5
+$as_echo "$ac_ct_CXX" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$ac_ct_CXX" && break
+done
+
+  if test "x$ac_ct_CXX" = x; then
+    CXX="g++"
+  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
+    CXX=$ac_ct_CXX
+  fi
+fi
+
+  fi
+fi
+# 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
+  fi
+  rm -f conftest.er1 conftest.err
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+done
+
+{ $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 ${ac_cv_cxx_compiler_gnu+:} false; 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_cxx_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_cxx_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5
+$as_echo "$ac_cv_cxx_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+  GXX=yes
+else
+  GXX=
+fi
+ac_test_CXXFLAGS=${CXXFLAGS+set}
+ac_save_CXXFLAGS=$CXXFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5
+$as_echo_n "checking whether $CXX accepts -g... " >&6; }
+if ${ac_cv_prog_cxx_g+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_save_cxx_werror_flag=$ac_cxx_werror_flag
+   ac_cxx_werror_flag=yes
+   ac_cv_prog_cxx_g=no
+   CXXFLAGS="-g"
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ac_cv_prog_cxx_g=yes
+else
+  CXXFLAGS=""
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+
+else
+  ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+	 CXXFLAGS="-g"
+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ac_cv_prog_cxx_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_cxx_werror_flag=$ac_save_cxx_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5
+$as_echo "$ac_cv_prog_cxx_g" >&6; }
+if test "$ac_test_CXXFLAGS" = set; then
+  CXXFLAGS=$ac_save_CXXFLAGS
+elif test $ac_cv_prog_cxx_g = yes; then
+  if test "$GXX" = yes; then
+    CXXFLAGS="-g -O2"
+  else
+    CXXFLAGS="-g"
+  fi
+else
+  if test "$GXX" = yes; then
+    CXXFLAGS="-O2"
+  else
+    CXXFLAGS=
+  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
+
+depcc="$CXX"  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 ${am_cv_CXX_dependencies_compiler_type+:} false; 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".
+  rm -rf conftest.dir
+  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_CXX_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 10 /bin/sh.
+      echo '/* dummy */' > 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
+      ;;
+    msvc7 | msvc7msys | 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_CXX_dependencies_compiler_type=$depmode
+        break
+      fi
+    fi
+  done
+
+  cd ..
+  rm -rf conftest.dir
+else
+  am_cv_CXX_dependencies_compiler_type=none
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5
+$as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; }
+CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type
+
+ if
+  test "x$enable_dependency_tracking" != xno \
+  && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then
+  am__fastdepCXX_TRUE=
+  am__fastdepCXX_FALSE='#'
+else
+  am__fastdepCXX_TRUE='#'
+  am__fastdepCXX_FALSE=
+fi
+
+
+
+
+#AC_PROG_CC
+#AC_PROG_CXX
+#
+# - check for some other programs.
+#
+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 ${ac_cv_prog_CPP+:} false; 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.i 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.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i 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.i 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.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i 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
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_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; }
+if test -z "$CXXCPP"; then
+  if ${ac_cv_prog_CXXCPP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+      # Double quotes because CXXCPP needs to be expanded
+    for CXXCPP in "$CXX -E" "/lib/cpp"
+    do
+      ac_preproc_ok=false
+for ac_cxx_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_cxx_try_cpp "$LINENO"; then :
+
+else
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i 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_cxx_try_cpp "$LINENO"; then :
+  # Broken: success on invalid input.
+continue
+else
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+  break
+fi
+
+    done
+    ac_cv_prog_CXXCPP=$CXXCPP
+
+fi
+  CXXCPP=$ac_cv_prog_CXXCPP
+else
+  ac_cv_prog_CXXCPP=$CXXCPP
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5
+$as_echo "$CXXCPP" >&6; }
+ac_preproc_ok=false
+for ac_cxx_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_cxx_try_cpp "$LINENO"; then :
+
+else
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i 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_cxx_try_cpp "$LINENO"; then :
+  # Broken: success on invalid input.
+continue
+else
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i 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 \"$CXXCPP\" 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 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
+
+
+## AC_DISABLE_STATIC
+for ac_prog in 'bison -y' byacc
+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 ${ac_cv_prog_YACC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$YACC"; then
+  ac_cv_prog_YACC="$YACC" # 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_YACC="$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
+YACC=$ac_cv_prog_YACC
+if test -n "$YACC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $YACC" >&5
+$as_echo "$YACC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$YACC" && break
+done
+test -n "$YACC" || YACC="yacc"
+
+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.4.2'
+macro_revision='1.3337'
+
+
+
+
+
+
+
+
+
+
+
+
+
+ltmain="$ac_aux_dir/ltmain.sh"
+
+# 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 ${ac_cv_build+:} false; 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 ${ac_cv_host+:} false; 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
+
+
+# Backslashify 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'
+
+ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5
+$as_echo_n "checking how to print strings... " >&6; }
+# Test print first, because it will be a builtin if present.
+if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \
+   test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then
+  ECHO='print -r --'
+elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then
+  ECHO='printf %s\n'
+else
+  # Use this function as a fallback that always works.
+  func_fallback_echo ()
+  {
+    eval 'cat <<_LTECHO_EOF
+$1
+_LTECHO_EOF'
+  }
+  ECHO='func_fallback_echo'
+fi
+
+# func_echo_all arg...
+# Invoke $ECHO with all args, space-separated.
+func_echo_all ()
+{
+    $ECHO ""
+}
+
+case "$ECHO" in
+  printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5
+$as_echo "printf" >&6; } ;;
+  print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5
+$as_echo "print -r" >&6; } ;;
+  *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5
+$as_echo "cat" >&6; } ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+{ $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 ${ac_cv_path_SED+:} false; 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"
+      as_fn_executable_p "$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 ${ac_cv_path_GREP+:} false; 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"
+      as_fn_executable_p "$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 ${ac_cv_path_EGREP+:} false; 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"
+      as_fn_executable_p "$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 ${ac_cv_path_FGREP+:} false; 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"
+      as_fn_executable_p "$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 ${lt_cv_path_LD+:} false; 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 ${lt_cv_prog_gnu_ld+:} false; 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 ${lt_cv_path_NM+:} false; 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 "$DUMPBIN"; then :
+    # Let the user override the test.
+  else
+    if test -n "$ac_tool_prefix"; then
+  for ac_prog in dumpbin "link -dump"
+  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 ${ac_cv_prog_DUMPBIN+:} false; 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 as_fn_executable_p "$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 "link -dump"
+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 ${ac_cv_prog_ac_ct_DUMPBIN+:} false; 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 as_fn_executable_p "$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
+
+    case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in
+    *COFF*)
+      DUMPBIN="$DUMPBIN -symbols"
+      ;;
+    *)
+      DUMPBIN=:
+      ;;
+    esac
+  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 ${lt_cv_nm_interface+:} false; 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:$LINENO: $ac_compile\"" >&5)
+  (eval "$ac_compile" 2>conftest.err)
+  cat conftest.err >&5
+  (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
+  (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
+  cat conftest.err >&5
+  (eval echo "\"\$as_me:$LINENO: 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; }
+
+# 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 ${lt_cv_sys_max_cmd_len+:} false; 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;
+    ;;
+
+  mint*)
+    # On MiNT this can take a long time and run out of memory.
+    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
+    ;;
+
+  os2*)
+    # The test takes a long time on OS/2.
+    lt_cv_sys_max_cmd_len=8192
+    ;;
+
+  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"`env echo "$teststring$teststring" 2>/dev/null` \
+	         = "X$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%"$_lt_dummy"}, \
+      = c,a/b,b/c, \
+    && 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 how to convert $build file names to $host format" >&5
+$as_echo_n "checking how to convert $build file names to $host format... " >&6; }
+if ${lt_cv_to_host_file_cmd+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $host in
+  *-*-mingw* )
+    case $build in
+      *-*-mingw* ) # actually msys
+        lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32
+        ;;
+      *-*-cygwin* )
+        lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32
+        ;;
+      * ) # otherwise, assume *nix
+        lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32
+        ;;
+    esac
+    ;;
+  *-*-cygwin* )
+    case $build in
+      *-*-mingw* ) # actually msys
+        lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin
+        ;;
+      *-*-cygwin* )
+        lt_cv_to_host_file_cmd=func_convert_file_noop
+        ;;
+      * ) # otherwise, assume *nix
+        lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin
+        ;;
+    esac
+    ;;
+  * ) # unhandled hosts (and "normal" native builds)
+    lt_cv_to_host_file_cmd=func_convert_file_noop
+    ;;
+esac
+
+fi
+
+to_host_file_cmd=$lt_cv_to_host_file_cmd
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5
+$as_echo "$lt_cv_to_host_file_cmd" >&6; }
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5
+$as_echo_n "checking how to convert $build file names to toolchain format... " >&6; }
+if ${lt_cv_to_tool_file_cmd+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  #assume ordinary cross tools, or native build.
+lt_cv_to_tool_file_cmd=func_convert_file_noop
+case $host in
+  *-*-mingw* )
+    case $build in
+      *-*-mingw* ) # actually msys
+        lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32
+        ;;
+    esac
+    ;;
+esac
+
+fi
+
+to_tool_file_cmd=$lt_cv_to_tool_file_cmd
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5
+$as_echo "$lt_cv_to_tool_file_cmd" >&6; }
+
+
+
+
+
+{ $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 ${lt_cv_ld_reload_flag+:} false; 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
+  cygwin* | mingw* | pw32* | cegcc*)
+    if test "$GCC" != yes; then
+      reload_cmds=false
+    fi
+    ;;
+  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 ${ac_cv_prog_OBJDUMP+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_OBJDUMP+:} false; 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 as_fn_executable_p "$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 ${lt_cv_deplibs_check_method+:} false; 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.
+  # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin.
+  if ( test "$lt_cv_nm_interface" = "BSD nm" && 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
+    # Keep this pattern in sync with the one in func_win32_libid.
+    lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)'
+    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
+  ;;
+
+haiku*)
+  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])(-bit)?( [LM]SB)? 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 glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+netbsd*)
+  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_glob=
+want_nocaseglob=no
+if test "$build" = "$host"; then
+  case $host_os in
+  mingw* | pw32*)
+    if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then
+      want_nocaseglob=yes
+    else
+      file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"`
+    fi
+    ;;
+  esac
+fi
+
+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}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 ${ac_cv_prog_DLLTOOL+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_DLLTOOL+:} false; 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 as_fn_executable_p "$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
+
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5
+$as_echo_n "checking how to associate runtime and link libraries... " >&6; }
+if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_sharedlib_from_linklib_cmd='unknown'
+
+case $host_os in
+cygwin* | mingw* | pw32* | cegcc*)
+  # two different shell functions defined in ltmain.sh
+  # decide which to use based on capabilities of $DLLTOOL
+  case `$DLLTOOL --help 2>&1` in
+  *--identify-strict*)
+    lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib
+    ;;
+  *)
+    lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback
+    ;;
+  esac
+  ;;
+*)
+  # fallback: assume linklib IS sharedlib
+  lt_cv_sharedlib_from_linklib_cmd="$ECHO"
+  ;;
+esac
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5
+$as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; }
+sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd
+test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+  for ac_prog in ar
+  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 ${ac_cv_prog_AR+:} false; 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_AR="$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
+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
+
+
+    test -n "$AR" && break
+  done
+fi
+if test -z "$AR"; then
+  ac_ct_AR=$AR
+  for ac_prog in ar
+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 ${ac_cv_prog_ac_ct_AR+:} false; 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_AR="$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_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
+
+
+  test -n "$ac_ct_AR" && break
+done
+
+  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
+fi
+
+: ${AR=ar}
+: ${AR_FLAGS=cru}
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5
+$as_echo_n "checking for archiver @FILE support... " >&6; }
+if ${lt_cv_ar_at_file+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_ar_at_file=no
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  echo conftest.$ac_objext > conftest.lst
+      lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5'
+      { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5
+  (eval $lt_ar_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      if test "$ac_status" -eq 0; then
+	# Ensure the archiver fails upon bogus file names.
+	rm -f conftest.$ac_objext libconftest.a
+	{ { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5
+  (eval $lt_ar_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+	if test "$ac_status" -ne 0; then
+          lt_cv_ar_at_file=@
+        fi
+      fi
+      rm -f conftest.* libconftest.a
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5
+$as_echo "$lt_cv_ar_at_file" >&6; }
+
+if test "x$lt_cv_ar_at_file" = xno; then
+  archiver_list_spec=
+else
+  archiver_list_spec=$lt_cv_ar_at_file
+fi
+
+
+
+
+
+
+
+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 ${ac_cv_prog_STRIP+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_STRIP+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_RANLIB+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_RANLIB+:} false; 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 as_fn_executable_p "$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 \$tool_oldlib"
+    ;;
+  *)
+    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib"
+    ;;
+  esac
+  old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib"
+fi
+
+case $host_os in
+  darwin*)
+    lock_old_archive_extraction=yes ;;
+  *)
+    lock_old_archive_extraction=no ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 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 ${lt_cv_sys_global_symbol_pipe+:} false; 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};"\
+"     /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\
+"     /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
+  lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'"
+
+  # 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
+/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests.  */
+#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE)
+/* DATA imports from DLLs on WIN32 con't be const, because runtime
+   relocations are performed -- see ld's documentation on pseudo-relocs.  */
+# define LT_DLSYM_CONST
+#elif defined(__osf__)
+/* This system does not cope well with relocations in const data.  */
+# define LT_DLSYM_CONST
+#else
+# define LT_DLSYM_CONST const
+#endif
+
+#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.  */
+LT_DLSYM_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_globsym_save_LIBS=$LIBS
+	  lt_globsym_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_globsym_save_LIBS
+	  CFLAGS=$lt_globsym_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
+
+# Response file support.
+if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+  nm_file_list_spec='@'
+elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then
+  nm_file_list_spec='@'
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5
+$as_echo_n "checking for sysroot... " >&6; }
+
+# Check whether --with-sysroot was given.
+if test "${with_sysroot+set}" = set; then :
+  withval=$with_sysroot;
+else
+  with_sysroot=no
+fi
+
+
+lt_sysroot=
+case ${with_sysroot} in #(
+ yes)
+   if test "$GCC" = yes; then
+     lt_sysroot=`$CC --print-sysroot 2>/dev/null`
+   fi
+   ;; #(
+ /*)
+   lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"`
+   ;; #(
+ no|'')
+   ;; #(
+ *)
+   { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${with_sysroot}" >&5
+$as_echo "${with_sysroot}" >&6; }
+   as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5
+   ;;
+esac
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5
+$as_echo "${lt_sysroot:-no}" >&6; }
+
+
+
+
+
+# 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 '$LINENO' "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 ${lt_cv_cc_needs_belf+:} false; 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
+  ;;
+*-*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*)
+        case $host in
+        i?86-*-solaris*)
+          LD="${LD-ld} -m elf_x86_64"
+          ;;
+        sparc*-*-solaris*)
+          LD="${LD-ld} -m elf64_sparc"
+          ;;
+        esac
+        # GNU ld 2.21 introduced _sol2 emulations.  Use them if available.
+        if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then
+          LD="${LD-ld}_sol2"
+        fi
+        ;;
+      *)
+	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"
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args.
+set dummy ${ac_tool_prefix}mt; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_MANIFEST_TOOL+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$MANIFEST_TOOL"; then
+  ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt"
+    $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
+MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL
+if test -n "$MANIFEST_TOOL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5
+$as_echo "$MANIFEST_TOOL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_MANIFEST_TOOL"; then
+  ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL
+  # Extract the first word of "mt", so it can be a program name with args.
+set dummy mt; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_MANIFEST_TOOL"; then
+  ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_MANIFEST_TOOL="mt"
+    $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_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL
+if test -n "$ac_ct_MANIFEST_TOOL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5
+$as_echo "$ac_ct_MANIFEST_TOOL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_MANIFEST_TOOL" = x; then
+    MANIFEST_TOOL=":"
+  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
+    MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL
+  fi
+else
+  MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL"
+fi
+
+test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5
+$as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; }
+if ${lt_cv_path_mainfest_tool+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_path_mainfest_tool=no
+  echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5
+  $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out
+  cat conftest.err >&5
+  if $GREP 'Manifest Tool' conftest.out > /dev/null; then
+    lt_cv_path_mainfest_tool=yes
+  fi
+  rm -f conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5
+$as_echo "$lt_cv_path_mainfest_tool" >&6; }
+if test "x$lt_cv_path_mainfest_tool" != xyes; then
+  MANIFEST_TOOL=:
+fi
+
+
+
+
+
+
+  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 ${ac_cv_prog_DSYMUTIL+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_NMEDIT+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_NMEDIT+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_LIPO+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_LIPO+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_OTOOL+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_OTOOL+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_OTOOL64+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_OTOOL64+:} false; 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 as_fn_executable_p "$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 ${lt_cv_apple_cc_single_mod+:} false; 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 there is a non-empty error log, and "single_module"
+	# appears in it, assume the flag caused a linker warning
+        if test -s conftest.err && $GREP single_module conftest.err; then
+	  cat conftest.err >&5
+	# Otherwise, if the output was created with a 0 exit code from
+	# the compiler, it worked.
+	elif test -f libconftest.dylib && test $_lt_result -eq 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 ${lt_cv_ld_exported_symbols_list+:} false; 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; }
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5
+$as_echo_n "checking for -force_load linker flag... " >&6; }
+if ${lt_cv_ld_force_load+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_ld_force_load=no
+      cat > conftest.c << _LT_EOF
+int forced_loaded() { return 2;}
+_LT_EOF
+      echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5
+      $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5
+      echo "$AR cru libconftest.a conftest.o" >&5
+      $AR cru libconftest.a conftest.o 2>&5
+      echo "$RANLIB libconftest.a" >&5
+      $RANLIB libconftest.a 2>&5
+      cat > conftest.c << _LT_EOF
+int main() { return 0;}
+_LT_EOF
+      echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5
+      $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err
+      _lt_result=$?
+      if test -s conftest.err && $GREP force_load conftest.err; then
+	cat conftest.err >&5
+      elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then
+	lt_cv_ld_force_load=yes
+      else
+	cat conftest.err >&5
+      fi
+        rm -f conftest.err libconftest.a conftest conftest.c
+        rm -rf conftest.dSYM
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5
+$as_echo "$lt_cv_ld_force_load" >&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" != ":" && test "$lt_cv_ld_force_load" = "no"; then
+      _lt_dsymutil='~$DSYMUTIL $lib || :'
+    else
+      _lt_dsymutil=
+    fi
+    ;;
+  esac
+
+
+{ $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 ${ac_cv_header_stdc+:} false; 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
+"
+if eval test \"x\$"$as_ac_Header"\" = 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" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_DLFCN_H 1
+_ACEOF
+
+fi
+
+done
+
+
+
+func_stripname_cnf ()
+{
+  case ${2} in
+  .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;;
+  *)  func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;;
+  esac
+} # func_stripname_cnf
+
+
+
+
+
+# Set options
+
+
+
+        enable_dlopen=no
+
+
+  enable_win32_dll=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; lt_p=${PACKAGE-default}
+    case $withval in
+    yes|no) pic_mode=$withval ;;
+    *)
+      pic_mode=default
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for lt_pkg in $withval; do
+	IFS="$lt_save_ifs"
+	if test "X$lt_pkg" = "X$lt_p"; then
+	  pic_mode=yes
+	fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac
+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 ${lt_cv_objdir+:} false; 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
+
+# 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 "$cc_temp" | $SED "s%.*/%%; 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 ${lt_cv_path_MAGIC_CMD+:} false; 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 ${lt_cv_path_MAGIC_CMD+:} false; 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*
+
+
+## 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...
+if test -n "$compiler"; then
+
+lt_prog_compiler_no_builtin_flag=
+
+if test "$GCC" = yes; then
+  case $cc_basename in
+  nvcc*)
+    lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;;
+  *)
+    lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;;
+  esac
+
+  { $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 ${lt_cv_prog_compiler_rtti_exceptions+:} false; 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:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $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 "$_lt_compiler_boilerplate" | $SED '/^$/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=
+
+
+  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'
+      ;;
+
+    haiku*)
+      # PIC is the default for Haiku.
+      # The "-static" flag exists, but is broken.
+      lt_prog_compiler_static=
+      ;;
+
+    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
+
+    case $cc_basename in
+    nvcc*) # Cuda Compiler Driver 2.2
+      lt_prog_compiler_wl='-Xlinker '
+      if test -n "$lt_prog_compiler_pic"; then
+        lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic"
+      fi
+      ;;
+    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 | kopensolaris*-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'
+	;;
+      nagfor*)
+	# NAG Fortran compiler
+	lt_prog_compiler_wl='-Wl,-Wl,,'
+	lt_prog_compiler_pic='-PIC'
+	lt_prog_compiler_static='-Bstatic'
+	;;
+      pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
+        # 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* | bgxl* | bgf* | mpixl*)
+	# IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene
+	lt_prog_compiler_wl='-Wl,'
+	lt_prog_compiler_pic='-qpic'
+	lt_prog_compiler_static='-qstaticlink'
+	;;
+      *)
+	case `$CC -V 2>&1 | sed 5q` in
+	*Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*)
+	  # 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=''
+	  ;;
+	*Sun\ F* | *Sun*Fortran*)
+	  lt_prog_compiler_pic='-KPIC'
+	  lt_prog_compiler_static='-Bstatic'
+	  lt_prog_compiler_wl='-Qoption ld '
+	  ;;
+	*Sun\ C*)
+	  # Sun C 5.9
+	  lt_prog_compiler_pic='-KPIC'
+	  lt_prog_compiler_static='-Bstatic'
+	  lt_prog_compiler_wl='-Wl,'
+	  ;;
+        *Intel*\ [CF]*Compiler*)
+	  lt_prog_compiler_wl='-Wl,'
+	  lt_prog_compiler_pic='-fPIC'
+	  lt_prog_compiler_static='-static'
+	  ;;
+	*Portland\ Group*)
+	  lt_prog_compiler_wl='-Wl,'
+	  lt_prog_compiler_pic='-fpic'
+	  lt_prog_compiler_static='-Bstatic'
+	  ;;
+	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* | sunf77* | sunf90* | sunf95*)
+	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}: checking for $compiler option to produce PIC" >&5
+$as_echo_n "checking for $compiler option to produce PIC... " >&6; }
+if ${lt_cv_prog_compiler_pic+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_pic=$lt_prog_compiler_pic
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5
+$as_echo "$lt_cv_prog_compiler_pic" >&6; }
+lt_prog_compiler_pic=$lt_cv_prog_compiler_pic
+
+#
+# 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 ${lt_cv_prog_compiler_pic_works+:} false; 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:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $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 "$_lt_compiler_boilerplate" | $SED '/^$/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 ${lt_cv_prog_compiler_static_works+:} false; 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 "$_lt_linker_boilerplate" | $SED '/^$/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 ${lt_cv_prog_compiler_c_o+:} false; 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:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $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 "$_lt_compiler_boilerplate" | $SED '/^$/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 ${lt_cv_prog_compiler_c_o+:} false; 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:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $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 "$_lt_compiler_boilerplate" | $SED '/^$/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_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
+    ;;
+  esac
+
+  ld_shlibs=yes
+
+  # On some targets, GNU ld is compatible enough with the native linker
+  # that we're better off using the native interface for both.
+  lt_use_gnu_ld_interface=no
+  if test "$with_gnu_ld" = yes; then
+    case $host_os in
+      aix*)
+	# The AIX port of GNU ld has always aspired to compatibility
+	# with the native linker.  However, as the warning in the GNU ld
+	# block says, versions before 2.19.5* couldn't really create working
+	# shared libraries, regardless of the interface used.
+	case `$LD -v 2>&1` in
+	  *\ \(GNU\ Binutils\)\ 2.19.5*) ;;
+	  *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;;
+	  *\ \(GNU\ Binutils\)\ [3-9]*) ;;
+	  *)
+	    lt_use_gnu_ld_interface=yes
+	    ;;
+	esac
+	;;
+      *)
+	lt_use_gnu_ld_interface=yes
+	;;
+    esac
+  fi
+
+  if test "$lt_use_gnu_ld_interface" = 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
+      *GNU\ gold*) supports_anon_versioning=yes ;;
+      *\ [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.19, 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 install binutils
+*** 2.20 or above, or modify your PATH so that a non-GNU linker is found.
+*** You will then need to restart the configuration process.
+
+_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'
+      export_dynamic_flag_spec='${wl}--export-all-symbols'
+      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/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols'
+      exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'
+
+      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
+      ;;
+
+    haiku*)
+      archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+      link_all_deplibs=yes
+      ;;
+
+    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 | kopensolaris*-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=' $pic_flag'
+	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; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+	  tmp_addflag=' $pic_flag'
+	  ;;
+	pgf77* | pgf90* | pgf95* | pgfortran*)
+					# 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; func_echo_all \"$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]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below)
+	  tmp_sharedflag='-qmkshrobj'
+	  tmp_addflag= ;;
+	nvcc*)	# Cuda Compiler Driver 2.2
+	  whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+	  compiler_needs_object=yes
+	  ;;
+	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; func_echo_all \"$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* | bgf* | bgxlf* | mpixlf*)
+	  # 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='${wl}-rpath ${wl}$libdir'
+	  archive_cmds='$LD -shared $libobjs $deplibs $linker_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 $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+	  fi
+	  ;;
+	esac
+      else
+        ld_shlibs=no
+      fi
+      ;;
+
+    netbsd*)
+      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 $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	archive_expsym_cmds='$CC -shared $pic_flag $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 $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	archive_expsym_cmds='$CC -shared $pic_flag $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 $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	archive_expsym_cmds='$CC -shared $pic_flag $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
+	# Also, AIX nm treats weak defined symbols like other global
+	# defined symbols, whereas GNU nm marks them as "W".
+	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") || (\$ 2 == "W")) && (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
+      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.
+        if test "${lt_cv_aix_libpath+set}" = set; then
+  aix_libpath=$lt_cv_aix_libpath
+else
+  if ${lt_cv_aix_libpath_+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  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
+	  }
+      }'
+  lt_cv_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 "$lt_cv_aix_libpath_"; then
+    lt_cv_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 "$lt_cv_aix_libpath_"; then
+    lt_cv_aix_libpath_="/usr/lib:/lib"
+  fi
+
+fi
+
+  aix_libpath=$lt_cv_aix_libpath_
+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 func_echo_all "${wl}${allow_undefined_flag}"; 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.
+	 if test "${lt_cv_aix_libpath+set}" = set; then
+  aix_libpath=$lt_cv_aix_libpath
+else
+  if ${lt_cv_aix_libpath_+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  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
+	  }
+      }'
+  lt_cv_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 "$lt_cv_aix_libpath_"; then
+    lt_cv_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 "$lt_cv_aix_libpath_"; then
+    lt_cv_aix_libpath_="/usr/lib:/lib"
+  fi
+
+fi
+
+  aix_libpath=$lt_cv_aix_libpath_
+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'
+	  if test "$with_gnu_ld" = yes; then
+	    # We only use this code for GNU lds that support --whole-archive.
+	    whole_archive_flag_spec='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+	  else
+	    # Exported symbols can be pulled into shared objects from archives
+	    whole_archive_flag_spec='$convenience'
+	  fi
+	  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.
+      case $cc_basename in
+      cl*)
+	# Native MSVC
+	hardcode_libdir_flag_spec=' '
+	allow_undefined_flag=unsupported
+	always_export_symbols=yes
+	file_list_spec='@'
+	# 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 $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
+	archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	    sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
+	  else
+	    sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
+	  fi~
+	  $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+	  linknames='
+	# The linker will not automatically build a static lib if we build a DLL.
+	# _LT_TAGVAR(old_archive_from_new_cmds, )='true'
+	enable_shared_with_static_runtimes=yes
+	exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
+	export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols'
+	# Don't use ranlib
+	old_postinstall_cmds='chmod 644 $oldlib'
+	postlink_cmds='lt_outputfile="@OUTPUT@"~
+	  lt_tool_outputfile="@TOOL_OUTPUT@"~
+	  case $lt_outputfile in
+	    *.exe|*.EXE) ;;
+	    *)
+	      lt_outputfile="$lt_outputfile.exe"
+	      lt_tool_outputfile="$lt_tool_outputfile.exe"
+	      ;;
+	  esac~
+	  if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
+	    $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+	    $RM "$lt_outputfile.manifest";
+	  fi'
+	;;
+      *)
+	# Assume MSVC wrapper
+	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 `func_echo_all "$deplibs" | $SED '\''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'
+	enable_shared_with_static_runtimes=yes
+	;;
+      esac
+      ;;
+
+    darwin* | rhapsody*)
+
+
+  archive_cmds_need_lc=no
+  hardcode_direct=no
+  hardcode_automatic=yes
+  hardcode_shlibpath_var=unsupported
+  if test "$lt_cv_ld_force_load" = "yes"; then
+    whole_archive_flag_spec='`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+
+  else
+    whole_archive_flag_spec=''
+  fi
+  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=func_echo_all
+    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
+      ;;
+
+    # 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 $pic_flag -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 $pic_flag ${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 && test "$with_gnu_ld" = no; then
+	archive_cmds='$CC -shared $pic_flag ${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_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 && test "$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 $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	*)
+	  archive_cmds='$CC -shared $pic_flag ${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'
+	  ;;
+	*)
+
+	  # Older versions of the 11.00 compiler do not understand -b yet
+	  # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does)
+	  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5
+$as_echo_n "checking if $CC understands -b... " >&6; }
+if ${lt_cv_prog_compiler__b+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler__b=no
+   save_LDFLAGS="$LDFLAGS"
+   LDFLAGS="$LDFLAGS -b"
+   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 "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
+       $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+       if diff conftest.exp conftest.er2 >/dev/null; then
+         lt_cv_prog_compiler__b=yes
+       fi
+     else
+       lt_cv_prog_compiler__b=yes
+     fi
+   fi
+   $RM -r conftest*
+   LDFLAGS="$save_LDFLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5
+$as_echo "$lt_cv_prog_compiler__b" >&6; }
+
+if test x"$lt_cv_prog_compiler__b" = xyes; then
+    archive_cmds='$CC -b ${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
+
+	  ;;
+	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 $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${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.
+	# This should be the same for all languages, so no per-tag cache variable.
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5
+$as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; }
+if ${lt_cv_irix_exported_symbol+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  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) { return 0; }
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  lt_cv_irix_exported_symbol=yes
+else
+  lt_cv_irix_exported_symbol=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_irix_exported_symbol" >&5
+$as_echo "$lt_cv_irix_exported_symbol" >&6; }
+	if test "$lt_cv_irix_exported_symbol" = yes; then
+          archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
+	fi
+      else
+	archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+	archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -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*)
+      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" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${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" && func_echo_all "-set_version $verstring"` -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} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${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" && func_echo_all "-set_version $verstring"` -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 "-set_version $verstring"` -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 $pic_flag ${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 $pic_flag ${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; }
+if ${lt_cv_archive_cmds_need_lc+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  $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
+	    lt_cv_archive_cmds_need_lc=no
+	  else
+	    lt_cv_archive_cmds_need_lc=yes
+	  fi
+	  allow_undefined_flag=$lt_save_allow_undefined_flag
+	else
+	  cat conftest.err 1>&5
+	fi
+	$RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5
+$as_echo "$lt_cv_archive_cmds_need_lc" >&6; }
+      archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc
+      ;;
+    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
+  case $host_os in
+    mingw* | cegcc*) lt_sed_strip_eq="s,=\([A-Za-z]:\),\1,g" ;;
+    *) lt_sed_strip_eq="s,=/,/,g" ;;
+  esac
+  lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq`
+  case $lt_search_path_spec in
+  *\;*)
+    # 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 's/;/ /g'`
+    ;;
+  *)
+    lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"`
+    ;;
+  esac
+  # 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; }
+}'`
+  # AWK program above erroneously prepends '/' to C:/dos/paths
+  # for these hosts.
+  case $host_os in
+    mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\
+      $SED 's,/\([A-Za-z]:\),\1,g'` ;;
+  esac
+  sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP`
+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 # correct to gnu/linux during the next big refactor
+  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 # correct to gnu/linux during the next big refactor
+  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=`func_echo_all "$lib" | $SED '\''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 # correct to gnu/linux during the next big refactor
+  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,$cc_basename in
+  yes,*)
+    # gcc
+    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="$sys_lib_search_path_spec /usr/lib/w32api"
+      ;;
+    mingw* | cegcc*)
+      # MinGW DLLs use traditional 'lib' prefix
+      soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      ;;
+    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
+    dynamic_linker='Win32 ld.exe'
+    ;;
+
+  *,cl*)
+    # Native MSVC
+    libname_spec='$name'
+    soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+    library_names_spec='${libname}.dll.lib'
+
+    case $build_os in
+    mingw*)
+      sys_lib_search_path_spec=
+      lt_save_ifs=$IFS
+      IFS=';'
+      for lt_path in $LIB
+      do
+        IFS=$lt_save_ifs
+        # Let DOS variable expansion print the short 8.3 style file name.
+        lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"`
+        sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path"
+      done
+      IFS=$lt_save_ifs
+      # Convert to MSYS style.
+      sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'`
+      ;;
+    cygwin*)
+      # Convert to unix form, then to dos form, then back to unix form
+      # but this time dos style (no spaces!) so that the unix form looks
+      # like /cygdrive/c/PROGRA~1:/cygdr...
+      sys_lib_search_path_spec=`cygpath --path --unix "$LIB"`
+      sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null`
+      sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+      ;;
+    *)
+      sys_lib_search_path_spec="$LIB"
+      if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then
+        # It is most probably a Windows format PATH.
+        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
+      # FIXME: find the short name or the path components, as spaces are
+      # common. (e.g. "Program Files" -> "PROGRA~1")
+      ;;
+    esac
+
+    # 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'
+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+      dlpath=$dir/\$dldll~
+       $RM \$dlpath'
+    shlibpath_overrides_runpath=yes
+    dynamic_linker='Win32 link.exe'
+    ;;
+
+  *)
+    # Assume MSVC wrapper
+    library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
+    dynamic_linker='Win32 ld.exe'
+    ;;
+  esac
+  # 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 # correct to gnu/linux during the next big refactor
+  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
+  ;;
+
+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[23].*) objformat=aout ;;
+    *) objformat=elf ;;
+    esac
+  fi
+  # Handle Gentoo/FreeBSD as it was Linux
+  case $host_vendor in
+    gentoo)
+      version_type=linux ;;
+    *)
+      version_type=freebsd-$objformat ;;
+  esac
+
+  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
+      ;;
+    linux)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+      soname_spec='${libname}${release}${shared_ext}$major'
+      need_lib_prefix=no
+      need_version=no
+      ;;
+  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 # correct to gnu/linux during the next big refactor
+  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
+  ;;
+
+haiku*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  dynamic_linker="$host_os runtime_loader"
+  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=LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
+  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'
+  # or fails outright, so override atomically:
+  install_override_mode=555
+  ;;
+
+interix[3-9]*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  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 # correct to gnu/linux during the next big refactor
+	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 glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  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
+  if ${lt_cv_shlibpath_overrides_runpath+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_shlibpath_overrides_runpath=no
+    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 :
+  lt_cv_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
+
+fi
+
+  shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath
+
+  # 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;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'
+  ;;
+
+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 # correct to gnu/linux during the next big refactor
+  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 # correct to gnu/linux during the next big refactor
+  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 # correct to gnu/linux during the next big refactor
+  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 # correct to gnu/linux during the next big refactor
+    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 # correct to gnu/linux during the next big refactor
+  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 # correct to gnu/linux during the next big refactor
+  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 ${ac_cv_lib_dl_dlopen+:} false; 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" = xyes; 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" = xyes; 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 ${ac_cv_lib_dld_shl_load+:} false; 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" = xyes; 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" = xyes; 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 ${ac_cv_lib_dl_dlopen+:} false; 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" = xyes; 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 ${ac_cv_lib_svld_dlopen+:} false; 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" = xyes; 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 ${ac_cv_lib_dld_dld_link+:} false; 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" = xyes; 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 ${lt_cv_dlopen_self+:} false; 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 $LINENO "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
+
+/* When -fvisbility=hidden is used, assume the code has been annotated
+   correspondingly for the symbols needed.  */
+#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+int fnord () __attribute__((visibility("default")));
+#endif
+
+int fnord () { return 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;
+          else puts (dlerror ());
+	}
+      /* 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 ${lt_cv_dlopen_self_static+:} false; 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 $LINENO "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
+
+/* When -fvisbility=hidden is used, assume the code has been annotated
+   correspondingly for the symbols needed.  */
+#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+int fnord () __attribute__((visibility("default")));
+#endif
+
+int fnord () { return 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;
+          else puts (dlerror ());
+	}
+      /* 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"
+
+      if test -n "$CXX" && ( test "X$CXX" != "Xno" &&
+    ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) ||
+    (test "X$CXX" != "Xg++"))) ; then
+  ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_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; }
+if test -z "$CXXCPP"; then
+  if ${ac_cv_prog_CXXCPP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+      # Double quotes because CXXCPP needs to be expanded
+    for CXXCPP in "$CXX -E" "/lib/cpp"
+    do
+      ac_preproc_ok=false
+for ac_cxx_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_cxx_try_cpp "$LINENO"; then :
+
+else
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i 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_cxx_try_cpp "$LINENO"; then :
+  # Broken: success on invalid input.
+continue
+else
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+  break
+fi
+
+    done
+    ac_cv_prog_CXXCPP=$CXXCPP
+
+fi
+  CXXCPP=$ac_cv_prog_CXXCPP
+else
+  ac_cv_prog_CXXCPP=$CXXCPP
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5
+$as_echo "$CXXCPP" >&6; }
+ac_preproc_ok=false
+for ac_cxx_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_cxx_try_cpp "$LINENO"; then :
+
+else
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i 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_cxx_try_cpp "$LINENO"; then :
+  # Broken: success on invalid input.
+continue
+else
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i 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 \"$CXXCPP\" 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
+
+else
+  _lt_caught_CXX_error=yes
+fi
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+archive_cmds_need_lc_CXX=no
+allow_undefined_flag_CXX=
+always_export_symbols_CXX=no
+archive_expsym_cmds_CXX=
+compiler_needs_object_CXX=no
+export_dynamic_flag_spec_CXX=
+hardcode_direct_CXX=no
+hardcode_direct_absolute_CXX=no
+hardcode_libdir_flag_spec_CXX=
+hardcode_libdir_separator_CXX=
+hardcode_minus_L_CXX=no
+hardcode_shlibpath_var_CXX=unsupported
+hardcode_automatic_CXX=no
+inherit_rpath_CXX=no
+module_cmds_CXX=
+module_expsym_cmds_CXX=
+link_all_deplibs_CXX=unknown
+old_archive_cmds_CXX=$old_archive_cmds
+reload_flag_CXX=$reload_flag
+reload_cmds_CXX=$reload_cmds
+no_undefined_flag_CXX=
+whole_archive_flag_spec_CXX=
+enable_shared_with_static_runtimes_CXX=no
+
+# Source file extension for C++ test sources.
+ac_ext=cpp
+
+# Object file extension for compiled C++ test sources.
+objext=o
+objext_CXX=$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.
+
+
+
+
+
+
+# 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_CFLAGS=$CFLAGS
+  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++"}
+  CFLAGS=$CXXFLAGS
+  compiler=$CC
+  compiler_CXX=$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 "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
+
+
+  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_prog_compiler_no_builtin_flag_CXX=' -fno-builtin'
+    else
+      lt_prog_compiler_no_builtin_flag_CXX=
+    fi
+
+    if test "$GXX" = yes; then
+      # Set up default GNU C++ configuration
+
+
+
+# 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 ${lt_cv_path_LD+:} false; 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 ${lt_cv_prog_gnu_ld+:} false; 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
+
+
+
+
+
+
+
+      # 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
+        archive_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+        archive_expsym_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+
+        hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+        export_dynamic_flag_spec_CXX='${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
+          whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+        else
+          whole_archive_flag_spec_CXX=
+        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.
+        archive_cmds_CXX='$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 -v "^Configured with:" | $GREP "\-L"'
+
+    else
+      GXX=no
+      with_gnu_ld=no
+      wlarc=
+    fi
+
+    # PORTME: fill in a description of your system's C++ link characteristics
+    { $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; }
+    ld_shlibs_CXX=yes
+    case $host_os in
+      aix3*)
+        # FIXME: insert proper C++ library support
+        ld_shlibs_CXX=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.
+
+        archive_cmds_CXX=''
+        hardcode_direct_CXX=yes
+        hardcode_direct_absolute_CXX=yes
+        hardcode_libdir_separator_CXX=':'
+        link_all_deplibs_CXX=yes
+        file_list_spec_CXX='${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
+	    hardcode_direct_CXX=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_CXX=yes
+	    hardcode_libdir_flag_spec_CXX='-L$libdir'
+	    hardcode_libdir_separator_CXX=
+	  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
+
+        export_dynamic_flag_spec_CXX='${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_CXX=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_CXX='-berok'
+          # Determine the default libpath from the value encoded in an empty
+          # executable.
+          if test "${lt_cv_aix_libpath+set}" = set; then
+  aix_libpath=$lt_cv_aix_libpath
+else
+  if ${lt_cv_aix_libpath__CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+
+  lt_aix_libpath_sed='
+      /Import File Strings/,/^$/ {
+	  /^0/ {
+	      s/^0  *\([^ ]*\) *$/\1/
+	      p
+	  }
+      }'
+  lt_cv_aix_libpath__CXX=`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 "$lt_cv_aix_libpath__CXX"; then
+    lt_cv_aix_libpath__CXX=`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 "$lt_cv_aix_libpath__CXX"; then
+    lt_cv_aix_libpath__CXX="/usr/lib:/lib"
+  fi
+
+fi
+
+  aix_libpath=$lt_cv_aix_libpath__CXX
+fi
+
+          hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath"
+
+          archive_expsym_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+        else
+          if test "$host_cpu" = ia64; then
+	    hardcode_libdir_flag_spec_CXX='${wl}-R $libdir:/usr/lib:/lib'
+	    allow_undefined_flag_CXX="-z nodefs"
+	    archive_expsym_cmds_CXX="\$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.
+	    if test "${lt_cv_aix_libpath+set}" = set; then
+  aix_libpath=$lt_cv_aix_libpath
+else
+  if ${lt_cv_aix_libpath__CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+
+  lt_aix_libpath_sed='
+      /Import File Strings/,/^$/ {
+	  /^0/ {
+	      s/^0  *\([^ ]*\) *$/\1/
+	      p
+	  }
+      }'
+  lt_cv_aix_libpath__CXX=`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 "$lt_cv_aix_libpath__CXX"; then
+    lt_cv_aix_libpath__CXX=`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 "$lt_cv_aix_libpath__CXX"; then
+    lt_cv_aix_libpath__CXX="/usr/lib:/lib"
+  fi
+
+fi
+
+  aix_libpath=$lt_cv_aix_libpath__CXX
+fi
+
+	    hardcode_libdir_flag_spec_CXX='${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_CXX=' ${wl}-bernotok'
+	    allow_undefined_flag_CXX=' ${wl}-berok'
+	    if test "$with_gnu_ld" = yes; then
+	      # We only use this code for GNU lds that support --whole-archive.
+	      whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+	    else
+	      # Exported symbols can be pulled into shared objects from archives
+	      whole_archive_flag_spec_CXX='$convenience'
+	    fi
+	    archive_cmds_need_lc_CXX=yes
+	    # This is similar to how AIX traditionally builds its shared
+	    # libraries.
+	    archive_expsym_cmds_CXX="\$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
+	  allow_undefined_flag_CXX=unsupported
+	  # Joseph Beckenbach <jrb3 at best.com> says some releases of gcc
+	  # support --undefined.  This deserves some investigation.  FIXME
+	  archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	else
+	  ld_shlibs_CXX=no
+	fi
+	;;
+
+      chorus*)
+        case $cc_basename in
+          *)
+	  # FIXME: insert proper C++ library support
+	  ld_shlibs_CXX=no
+	  ;;
+        esac
+        ;;
+
+      cygwin* | mingw* | pw32* | cegcc*)
+	case $GXX,$cc_basename in
+	,cl* | no,cl*)
+	  # Native MSVC
+	  # hardcode_libdir_flag_spec is actually meaningless, as there is
+	  # no search path for DLLs.
+	  hardcode_libdir_flag_spec_CXX=' '
+	  allow_undefined_flag_CXX=unsupported
+	  always_export_symbols_CXX=yes
+	  file_list_spec_CXX='@'
+	  # 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_CXX='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
+	  archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	      $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
+	    else
+	      $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
+	    fi~
+	    $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+	    linknames='
+	  # The linker will not automatically build a static lib if we build a DLL.
+	  # _LT_TAGVAR(old_archive_from_new_cmds, CXX)='true'
+	  enable_shared_with_static_runtimes_CXX=yes
+	  # Don't use ranlib
+	  old_postinstall_cmds_CXX='chmod 644 $oldlib'
+	  postlink_cmds_CXX='lt_outputfile="@OUTPUT@"~
+	    lt_tool_outputfile="@TOOL_OUTPUT@"~
+	    case $lt_outputfile in
+	      *.exe|*.EXE) ;;
+	      *)
+		lt_outputfile="$lt_outputfile.exe"
+		lt_tool_outputfile="$lt_tool_outputfile.exe"
+		;;
+	    esac~
+	    func_to_tool_file "$lt_outputfile"~
+	    if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
+	      $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+	      $RM "$lt_outputfile.manifest";
+	    fi'
+	  ;;
+	*)
+	  # g++
+	  # _LT_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless,
+	  # as there is no search path for DLLs.
+	  hardcode_libdir_flag_spec_CXX='-L$libdir'
+	  export_dynamic_flag_spec_CXX='${wl}--export-all-symbols'
+	  allow_undefined_flag_CXX=unsupported
+	  always_export_symbols_CXX=no
+	  enable_shared_with_static_runtimes_CXX=yes
+
+	  if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+	    archive_cmds_CXX='$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...
+	    archive_expsym_cmds_CXX='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
+	    ld_shlibs_CXX=no
+	  fi
+	  ;;
+	esac
+	;;
+      darwin* | rhapsody*)
+
+
+  archive_cmds_need_lc_CXX=no
+  hardcode_direct_CXX=no
+  hardcode_automatic_CXX=yes
+  hardcode_shlibpath_var_CXX=unsupported
+  if test "$lt_cv_ld_force_load" = "yes"; then
+    whole_archive_flag_spec_CXX='`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+
+  else
+    whole_archive_flag_spec_CXX=''
+  fi
+  link_all_deplibs_CXX=yes
+  allow_undefined_flag_CXX="$_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=func_echo_all
+    archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
+    module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
+    archive_expsym_cmds_CXX="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_CXX="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}"
+       if test "$lt_cv_apple_cc_single_mod" != "yes"; then
+      archive_cmds_CXX="\$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}"
+      archive_expsym_cmds_CXX="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
+  ld_shlibs_CXX=no
+  fi
+
+	;;
+
+      dgux*)
+        case $cc_basename in
+          ec++*)
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+          ghcx*)
+	    # Green Hills C++ Compiler
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+          *)
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+        esac
+        ;;
+
+      freebsd2.*)
+        # C++ shared libraries reported to be fairly broken before
+	# switch to ELF
+        ld_shlibs_CXX=no
+        ;;
+
+      freebsd-elf*)
+        archive_cmds_need_lc_CXX=no
+        ;;
+
+      freebsd* | dragonfly*)
+        # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF
+        # conventions
+        ld_shlibs_CXX=yes
+        ;;
+
+      gnu*)
+        ;;
+
+      haiku*)
+        archive_cmds_CXX='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+        link_all_deplibs_CXX=yes
+        ;;
+
+      hpux9*)
+        hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir'
+        hardcode_libdir_separator_CXX=:
+        export_dynamic_flag_spec_CXX='${wl}-E'
+        hardcode_direct_CXX=yes
+        hardcode_minus_L_CXX=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
+            ld_shlibs_CXX=no
+            ;;
+          aCC*)
+            archive_cmds_CXX='$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; func_echo_all "$list"'
+            ;;
+          *)
+            if test "$GXX" = yes; then
+              archive_cmds_CXX='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${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
+              ld_shlibs_CXX=no
+            fi
+            ;;
+        esac
+        ;;
+
+      hpux10*|hpux11*)
+        if test $with_gnu_ld = no; then
+	  hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir'
+	  hardcode_libdir_separator_CXX=:
+
+          case $host_cpu in
+            hppa*64*|ia64*)
+              ;;
+            *)
+	      export_dynamic_flag_spec_CXX='${wl}-E'
+              ;;
+          esac
+        fi
+        case $host_cpu in
+          hppa*64*|ia64*)
+            hardcode_direct_CXX=no
+            hardcode_shlibpath_var_CXX=no
+            ;;
+          *)
+            hardcode_direct_CXX=yes
+            hardcode_direct_absolute_CXX=yes
+            hardcode_minus_L_CXX=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
+	    ld_shlibs_CXX=no
+	    ;;
+          aCC*)
+	    case $host_cpu in
+	      hppa*64*)
+	        archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	        ;;
+	      ia64*)
+	        archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	        ;;
+	      *)
+	        archive_cmds_CXX='$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; func_echo_all "$list"'
+	    ;;
+          *)
+	    if test "$GXX" = yes; then
+	      if test $with_gnu_ld = no; then
+	        case $host_cpu in
+	          hppa*64*)
+	            archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	            ;;
+	          ia64*)
+	            archive_cmds_CXX='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	            ;;
+	          *)
+	            archive_cmds_CXX='$CC -shared -nostdlib $pic_flag ${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
+	      ld_shlibs_CXX=no
+	    fi
+	    ;;
+        esac
+        ;;
+
+      interix[3-9]*)
+	hardcode_direct_CXX=no
+	hardcode_shlibpath_var_CXX=no
+	hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+	export_dynamic_flag_spec_CXX='${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_CXX='$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_CXX='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++
+	    archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -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.
+	    old_archive_cmds_CXX='$CC -ar -WR,-u -o $oldlib $oldobjs'
+	    ;;
+          *)
+	    if test "$GXX" = yes; then
+	      if test "$with_gnu_ld" = no; then
+	        archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+	      else
+	        archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib'
+	      fi
+	    fi
+	    link_all_deplibs_CXX=yes
+	    ;;
+        esac
+        hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+        hardcode_libdir_separator_CXX=:
+        inherit_rpath_CXX=yes
+        ;;
+
+      linux* | k*bsd*-gnu | kopensolaris*-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.
+	    archive_cmds_CXX='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'
+	    archive_expsym_cmds_CXX='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; func_echo_all "$list"'
+
+	    hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+	    export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+
+	    # Archives containing C++ object files must be created using
+	    # "CC -Bstatic", where "CC" is the KAI C++ compiler.
+	    old_archive_cmds_CXX='$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."*)
+	        archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+		archive_expsym_cmds_CXX='$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
+	        archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+		archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+		;;
+	    esac
+	    archive_cmds_need_lc_CXX=no
+	    hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+	    export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+	    whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+	    ;;
+          pgCC* | pgcpp*)
+            # Portland Group C++ compiler
+	    case `$CC -V` in
+	    *pgCC\ [1-5].* | *pgcpp\ [1-5].*)
+	      prelink_cmds_CXX='tpldir=Template.dir~
+		rm -rf $tpldir~
+		$CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~
+		compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"'
+	      old_archive_cmds_CXX='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 | sort | $NL2SP`~
+		$RANLIB $oldlib'
+	      archive_cmds_CXX='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 | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+	      archive_expsym_cmds_CXX='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 | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
+	      ;;
+	    *) # Version 6 and above use weak symbols
+	      archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+	      archive_expsym_cmds_CXX='$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
+
+	    hardcode_libdir_flag_spec_CXX='${wl}--rpath ${wl}$libdir'
+	    export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+	    whole_archive_flag_spec_CXX='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+            ;;
+	  cxx*)
+	    # Compaq C++
+	    archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	    archive_expsym_cmds_CXX='$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
+	    hardcode_libdir_flag_spec_CXX='-rpath $libdir'
+	    hardcode_libdir_separator_CXX=:
+
+	    # 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=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed'
+	    ;;
+	  xl* | mpixl* | bgxl*)
+	    # IBM XL 8.0 on PPC, with GNU ld
+	    hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+	    export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+	    archive_cmds_CXX='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	    if test "x$supports_anon_versioning" = xyes; then
+	      archive_expsym_cmds_CXX='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
+	      no_undefined_flag_CXX=' -zdefs'
+	      archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	      archive_expsym_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols'
+	      hardcode_libdir_flag_spec_CXX='-R$libdir'
+	      whole_archive_flag_spec_CXX='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+	      compiler_needs_object_CXX=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='func_echo_all'
+
+	      # 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.
+	      old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs'
+	      ;;
+	    esac
+	    ;;
+	esac
+	;;
+
+      lynxos*)
+        # FIXME: insert proper C++ library support
+	ld_shlibs_CXX=no
+	;;
+
+      m88k*)
+        # FIXME: insert proper C++ library support
+        ld_shlibs_CXX=no
+	;;
+
+      mvs*)
+        case $cc_basename in
+          cxx*)
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+	  *)
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+	esac
+	;;
+
+      netbsd*)
+        if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+	  archive_cmds_CXX='$LD -Bshareable  -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags'
+	  wlarc=
+	  hardcode_libdir_flag_spec_CXX='-R$libdir'
+	  hardcode_direct_CXX=yes
+	  hardcode_shlibpath_var_CXX=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*)
+        ld_shlibs_CXX=yes
+	;;
+
+      openbsd2*)
+        # C++ shared libraries are fairly broken
+	ld_shlibs_CXX=no
+	;;
+
+      openbsd*)
+	if test -f /usr/libexec/ld.so; then
+	  hardcode_direct_CXX=yes
+	  hardcode_shlibpath_var_CXX=no
+	  hardcode_direct_absolute_CXX=yes
+	  archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+	  hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+	  if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+	    archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib'
+	    export_dynamic_flag_spec_CXX='${wl}-E'
+	    whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+	  fi
+	  output_verbose_link_cmd=func_echo_all
+	else
+	  ld_shlibs_CXX=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.
+	    archive_cmds_CXX='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'
+
+	    hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+	    hardcode_libdir_separator_CXX=:
+
+	    # Archives containing C++ object files must be created using
+	    # the KAI C++ compiler.
+	    case $host in
+	      osf3*) old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ;;
+	      *) old_archive_cmds_CXX='$CC -o $oldlib $oldobjs' ;;
+	    esac
+	    ;;
+          RCC*)
+	    # Rational C++ 2.4.1
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+          cxx*)
+	    case $host in
+	      osf3*)
+	        allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*'
+	        archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+	        hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+		;;
+	      *)
+	        allow_undefined_flag_CXX=' -expect_unresolved \*'
+	        archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+	        archive_expsym_cmds_CXX='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 "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~
+	          $RM $lib.exp'
+	        hardcode_libdir_flag_spec_CXX='-rpath $libdir'
+		;;
+	    esac
+
+	    hardcode_libdir_separator_CXX=:
+
+	    # 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=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+	    ;;
+	  *)
+	    if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+	      allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*'
+	      case $host in
+	        osf3*)
+	          archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+		  ;;
+	        *)
+	          archive_cmds_CXX='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+		  ;;
+	      esac
+
+	      hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+	      hardcode_libdir_separator_CXX=:
+
+	      # 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 -v "^Configured with:" | $GREP "\-L"'
+
+	    else
+	      # FIXME: insert proper C++ library support
+	      ld_shlibs_CXX=no
+	    fi
+	    ;;
+        esac
+        ;;
+
+      psos*)
+        # FIXME: insert proper C++ library support
+        ld_shlibs_CXX=no
+        ;;
+
+      sunos4*)
+        case $cc_basename in
+          CC*)
+	    # Sun C++ 4.x
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+          lcc*)
+	    # Lucid
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+          *)
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+        esac
+        ;;
+
+      solaris*)
+        case $cc_basename in
+          CC* | sunCC*)
+	    # Sun C++ 4.2, 5.x and Centerline C++
+            archive_cmds_need_lc_CXX=yes
+	    no_undefined_flag_CXX=' -zdefs'
+	    archive_cmds_CXX='$CC -G${allow_undefined_flag}  -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	    archive_expsym_cmds_CXX='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'
+
+	    hardcode_libdir_flag_spec_CXX='-R$libdir'
+	    hardcode_shlibpath_var_CXX=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?)
+		whole_archive_flag_spec_CXX='-z allextract$convenience -z defaultextract'
+	        ;;
+	    esac
+	    link_all_deplibs_CXX=yes
+
+	    output_verbose_link_cmd='func_echo_all'
+
+	    # 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.
+	    old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs'
+	    ;;
+          gcx*)
+	    # Green Hills C++ Compiler
+	    archive_cmds_CXX='$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.
+	    old_archive_cmds_CXX='$CC $LDFLAGS -archive -o $oldlib $oldobjs'
+	    ;;
+          *)
+	    # GNU C++ compiler with Solaris linker
+	    if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+	      no_undefined_flag_CXX=' ${wl}-z ${wl}defs'
+	      if $CC --version | $GREP -v '^2\.7' > /dev/null; then
+	        archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+	        archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+		  $CC -shared $pic_flag -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 -v "^Configured with:" | $GREP "\-L"'
+	      else
+	        # g++ 2.7 appears to require `-G' NOT `-shared' on this
+	        # platform.
+	        archive_cmds_CXX='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+	        archive_expsym_cmds_CXX='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 -v "^Configured with:" | $GREP "\-L"'
+	      fi
+
+	      hardcode_libdir_flag_spec_CXX='${wl}-R $wl$libdir'
+	      case $host_os in
+		solaris2.[0-5] | solaris2.[0-5].*) ;;
+		*)
+		  whole_archive_flag_spec_CXX='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+		  ;;
+	      esac
+	    fi
+	    ;;
+        esac
+        ;;
+
+    sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
+      no_undefined_flag_CXX='${wl}-z,text'
+      archive_cmds_need_lc_CXX=no
+      hardcode_shlibpath_var_CXX=no
+      runpath_var='LD_RUN_PATH'
+
+      case $cc_basename in
+        CC*)
+	  archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	*)
+	  archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  archive_expsym_cmds_CXX='$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.
+	no_undefined_flag_CXX='${wl}-z,text'
+	allow_undefined_flag_CXX='${wl}-z,nodefs'
+	archive_cmds_need_lc_CXX=no
+	hardcode_shlibpath_var_CXX=no
+	hardcode_libdir_flag_spec_CXX='${wl}-R,$libdir'
+	hardcode_libdir_separator_CXX=':'
+	link_all_deplibs_CXX=yes
+	export_dynamic_flag_spec_CXX='${wl}-Bexport'
+	runpath_var='LD_RUN_PATH'
+
+	case $cc_basename in
+          CC*)
+	    archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    old_archive_cmds_CXX='$CC -Tprelink_objects $oldobjs~
+	      '"$old_archive_cmds_CXX"
+	    reload_cmds_CXX='$CC -Tprelink_objects $reload_objs~
+	      '"$reload_cmds_CXX"
+	    ;;
+	  *)
+	    archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    archive_expsym_cmds_CXX='$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
+	    ld_shlibs_CXX=no
+	    ;;
+          *)
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+        esac
+        ;;
+
+      vxworks*)
+        # FIXME: insert proper C++ library support
+        ld_shlibs_CXX=no
+        ;;
+
+      *)
+        # FIXME: insert proper C++ library support
+        ld_shlibs_CXX=no
+        ;;
+    esac
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5
+$as_echo "$ld_shlibs_CXX" >&6; }
+    test "$ld_shlibs_CXX" = no && can_build_shared=no
+
+    GCC_CXX="$GXX"
+    LD_CXX="$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...
+    # Dependencies to place before and after the object being linked:
+predep_objects_CXX=
+postdep_objects_CXX=
+predeps_CXX=
+postdeps_CXX=
+compiler_lib_search_path_CXX=
+
+cat > conftest.$ac_ext <<_LT_EOF
+class Foo
+{
+public:
+  Foo (void) { a = 0; }
+private:
+  int a;
+};
+_LT_EOF
+
+
+_lt_libdeps_save_CFLAGS=$CFLAGS
+case "$CC $CFLAGS " in #(
+*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;;
+*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;;
+*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;;
+esac
+
+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
+  # 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 ${prev}${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
+       fi
+
+       # Expand the sysroot to ease extracting the directories later.
+       if test -z "$prev"; then
+         case $p in
+         -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;;
+         -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;;
+         -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;;
+         esac
+       fi
+       case $p in
+       =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;;
+       esac
+       if test "$pre_test_object_deps_done" = no; then
+	 case ${prev} 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 "$compiler_lib_search_path_CXX"; then
+	     compiler_lib_search_path_CXX="${prev}${p}"
+	   else
+	     compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} ${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 "$postdeps_CXX"; then
+	   postdeps_CXX="${prev}${p}"
+	 else
+	   postdeps_CXX="${postdeps_CXX} ${prev}${p}"
+	 fi
+       fi
+       prev=
+       ;;
+
+    *.lto.$objext) ;; # Ignore GCC LTO objects
+    *.$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 "$predep_objects_CXX"; then
+	   predep_objects_CXX="$p"
+	 else
+	   predep_objects_CXX="$predep_objects_CXX $p"
+	 fi
+       else
+	 if test -z "$postdep_objects_CXX"; then
+	   postdep_objects_CXX="$p"
+	 else
+	   postdep_objects_CXX="$postdep_objects_CXX $p"
+	 fi
+       fi
+       ;;
+
+    *) ;; # Ignore the rest.
+
+    esac
+  done
+
+  # Clean up.
+  rm -f a.out a.exe
+else
+  echo "libtool.m4: error: problem compiling CXX test program"
+fi
+
+$RM -f confest.$objext
+CFLAGS=$_lt_libdeps_save_CFLAGS
+
+# PORTME: override above test on systems where it is broken
+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.
+  predep_objects_CXX=
+  postdep_objects_CXX=
+  postdeps_CXX=
+  ;;
+
+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
+      postdeps_CXX='-library=Cstd -library=Crun'
+    fi
+    ;;
+  esac
+  ;;
+
+solaris*)
+  case $cc_basename in
+  CC* | sunCC*)
+    # 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
+      postdeps_CXX='-library=Cstd -library=Crun'
+    fi
+    ;;
+  esac
+  ;;
+esac
+
+
+case " $postdeps_CXX " in
+*" -lc "*) archive_cmds_need_lc_CXX=no ;;
+esac
+ compiler_lib_search_dirs_CXX=
+if test -n "${compiler_lib_search_path_CXX}"; then
+ compiler_lib_search_dirs_CXX=`echo " ${compiler_lib_search_path_CXX}" | ${SED} -e 's! -L! !g' -e 's!^ !!'`
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    lt_prog_compiler_wl_CXX=
+lt_prog_compiler_pic_CXX=
+lt_prog_compiler_static_CXX=
+
+
+  # C++ specific cases for pic, static, wl, etc.
+  if test "$GXX" = yes; then
+    lt_prog_compiler_wl_CXX='-Wl,'
+    lt_prog_compiler_static_CXX='-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_CXX='-Bstatic'
+      fi
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            lt_prog_compiler_pic_CXX='-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_CXX='-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
+      lt_prog_compiler_pic_CXX='-DDLL_EXPORT'
+      ;;
+    darwin* | rhapsody*)
+      # PIC is the default on this platform
+      # Common symbols not allowed in MH_DYLIB files
+      lt_prog_compiler_pic_CXX='-fno-common'
+      ;;
+    *djgpp*)
+      # DJGPP does not support shared libraries at all
+      lt_prog_compiler_pic_CXX=
+      ;;
+    haiku*)
+      # PIC is the default for Haiku.
+      # The "-static" flag exists, but is broken.
+      lt_prog_compiler_static_CXX=
+      ;;
+    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_prog_compiler_pic_CXX=-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_prog_compiler_pic_CXX='-fPIC'
+	;;
+      esac
+      ;;
+    *qnx* | *nto*)
+      # QNX uses GNU C++, but need to define -shared option too, otherwise
+      # it will coredump.
+      lt_prog_compiler_pic_CXX='-fPIC -shared'
+      ;;
+    *)
+      lt_prog_compiler_pic_CXX='-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_prog_compiler_static_CXX='-Bstatic'
+	else
+	  lt_prog_compiler_static_CXX='-bnso -bI:/lib/syscalls.exp'
+	fi
+	;;
+      chorus*)
+	case $cc_basename in
+	cxch68*)
+	  # Green Hills C++ Compiler
+	  # _LT_TAGVAR(lt_prog_compiler_static, CXX)="--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
+	;;
+      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).
+	lt_prog_compiler_pic_CXX='-DDLL_EXPORT'
+	;;
+      dgux*)
+	case $cc_basename in
+	  ec++*)
+	    lt_prog_compiler_pic_CXX='-KPIC'
+	    ;;
+	  ghcx*)
+	    # Green Hills C++ Compiler
+	    lt_prog_compiler_pic_CXX='-pic'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      freebsd* | dragonfly*)
+	# FreeBSD uses GNU C++
+	;;
+      hpux9* | hpux10* | hpux11*)
+	case $cc_basename in
+	  CC*)
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_static_CXX='${wl}-a ${wl}archive'
+	    if test "$host_cpu" != ia64; then
+	      lt_prog_compiler_pic_CXX='+Z'
+	    fi
+	    ;;
+	  aCC*)
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_static_CXX='${wl}-a ${wl}archive'
+	    case $host_cpu in
+	    hppa*64*|ia64*)
+	      # +Z the default
+	      ;;
+	    *)
+	      lt_prog_compiler_pic_CXX='+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_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_static_CXX='-non_shared'
+	    # CC pic flag -KPIC is the default.
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      linux* | k*bsd*-gnu | kopensolaris*-gnu)
+	case $cc_basename in
+	  KCC*)
+	    # KAI C++ Compiler
+	    lt_prog_compiler_wl_CXX='--backend -Wl,'
+	    lt_prog_compiler_pic_CXX='-fPIC'
+	    ;;
+	  ecpc* )
+	    # old Intel C++ for x86_64 which still supported -KPIC.
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_pic_CXX='-KPIC'
+	    lt_prog_compiler_static_CXX='-static'
+	    ;;
+	  icpc* )
+	    # Intel C++, used to be incompatible with GCC.
+	    # ICC 10 doesn't accept -KPIC any more.
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_pic_CXX='-fPIC'
+	    lt_prog_compiler_static_CXX='-static'
+	    ;;
+	  pgCC* | pgcpp*)
+	    # Portland Group C++ compiler
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_pic_CXX='-fpic'
+	    lt_prog_compiler_static_CXX='-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_prog_compiler_pic_CXX=
+	    lt_prog_compiler_static_CXX='-non_shared'
+	    ;;
+	  xlc* | xlC* | bgxl[cC]* | mpixl[cC]*)
+	    # IBM XL 8.0, 9.0 on PPC and BlueGene
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_pic_CXX='-qpic'
+	    lt_prog_compiler_static_CXX='-qstaticlink'
+	    ;;
+	  *)
+	    case `$CC -V 2>&1 | sed 5q` in
+	    *Sun\ C*)
+	      # Sun C++ 5.9
+	      lt_prog_compiler_pic_CXX='-KPIC'
+	      lt_prog_compiler_static_CXX='-Bstatic'
+	      lt_prog_compiler_wl_CXX='-Qoption ld '
+	      ;;
+	    esac
+	    ;;
+	esac
+	;;
+      lynxos*)
+	;;
+      m88k*)
+	;;
+      mvs*)
+	case $cc_basename in
+	  cxx*)
+	    lt_prog_compiler_pic_CXX='-W c,exportall'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      netbsd*)
+	;;
+      *qnx* | *nto*)
+        # QNX uses GNU C++, but need to define -shared option too, otherwise
+        # it will coredump.
+        lt_prog_compiler_pic_CXX='-fPIC -shared'
+        ;;
+      osf3* | osf4* | osf5*)
+	case $cc_basename in
+	  KCC*)
+	    lt_prog_compiler_wl_CXX='--backend -Wl,'
+	    ;;
+	  RCC*)
+	    # Rational C++ 2.4.1
+	    lt_prog_compiler_pic_CXX='-pic'
+	    ;;
+	  cxx*)
+	    # Digital/Compaq C++
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    # Make sure the PIC flag is empty.  It appears that all Alpha
+	    # Linux and Compaq Tru64 Unix objects are PIC.
+	    lt_prog_compiler_pic_CXX=
+	    lt_prog_compiler_static_CXX='-non_shared'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      psos*)
+	;;
+      solaris*)
+	case $cc_basename in
+	  CC* | sunCC*)
+	    # Sun C++ 4.2, 5.x and Centerline C++
+	    lt_prog_compiler_pic_CXX='-KPIC'
+	    lt_prog_compiler_static_CXX='-Bstatic'
+	    lt_prog_compiler_wl_CXX='-Qoption ld '
+	    ;;
+	  gcx*)
+	    # Green Hills C++ Compiler
+	    lt_prog_compiler_pic_CXX='-PIC'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      sunos4*)
+	case $cc_basename in
+	  CC*)
+	    # Sun C++ 4.x
+	    lt_prog_compiler_pic_CXX='-pic'
+	    lt_prog_compiler_static_CXX='-Bstatic'
+	    ;;
+	  lcc*)
+	    # Lucid
+	    lt_prog_compiler_pic_CXX='-pic'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+	case $cc_basename in
+	  CC*)
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_pic_CXX='-KPIC'
+	    lt_prog_compiler_static_CXX='-Bstatic'
+	    ;;
+	esac
+	;;
+      tandem*)
+	case $cc_basename in
+	  NCC*)
+	    # NonStop-UX NCC 3.20
+	    lt_prog_compiler_pic_CXX='-KPIC'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      vxworks*)
+	;;
+      *)
+	lt_prog_compiler_can_build_shared_CXX=no
+	;;
+    esac
+  fi
+
+case $host_os in
+  # For platforms which do not support PIC, -DPIC is meaningless:
+  *djgpp*)
+    lt_prog_compiler_pic_CXX=
+    ;;
+  *)
+    lt_prog_compiler_pic_CXX="$lt_prog_compiler_pic_CXX -DPIC"
+    ;;
+esac
+
+{ $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 ${lt_cv_prog_compiler_pic_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_pic_CXX=$lt_prog_compiler_pic_CXX
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_CXX" >&5
+$as_echo "$lt_cv_prog_compiler_pic_CXX" >&6; }
+lt_prog_compiler_pic_CXX=$lt_cv_prog_compiler_pic_CXX
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$lt_prog_compiler_pic_CXX"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5
+$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... " >&6; }
+if ${lt_cv_prog_compiler_pic_works_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_pic_works_CXX=no
+   ac_outfile=conftest.$ac_objext
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+   lt_compiler_flag="$lt_prog_compiler_pic_CXX -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:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $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 "$_lt_compiler_boilerplate" | $SED '/^$/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_CXX=yes
+     fi
+   fi
+   $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works_CXX" >&5
+$as_echo "$lt_cv_prog_compiler_pic_works_CXX" >&6; }
+
+if test x"$lt_cv_prog_compiler_pic_works_CXX" = xyes; then
+    case $lt_prog_compiler_pic_CXX in
+     "" | " "*) ;;
+     *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;;
+     esac
+else
+    lt_prog_compiler_pic_CXX=
+     lt_prog_compiler_can_build_shared_CXX=no
+fi
+
+fi
+
+
+
+
+
+#
+# Check to make sure the static flag actually works.
+#
+wl=$lt_prog_compiler_wl_CXX eval lt_tmp_static_flag=\"$lt_prog_compiler_static_CXX\"
+{ $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 ${lt_cv_prog_compiler_static_works_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_static_works_CXX=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 "$_lt_linker_boilerplate" | $SED '/^$/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_CXX=yes
+       fi
+     else
+       lt_cv_prog_compiler_static_works_CXX=yes
+     fi
+   fi
+   $RM -r conftest*
+   LDFLAGS="$save_LDFLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works_CXX" >&5
+$as_echo "$lt_cv_prog_compiler_static_works_CXX" >&6; }
+
+if test x"$lt_cv_prog_compiler_static_works_CXX" = xyes; then
+    :
+else
+    lt_prog_compiler_static_CXX=
+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 ${lt_cv_prog_compiler_c_o_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_c_o_CXX=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:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $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 "$_lt_compiler_boilerplate" | $SED '/^$/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_CXX=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_CXX" >&5
+$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&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 ${lt_cv_prog_compiler_c_o_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_c_o_CXX=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:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $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 "$_lt_compiler_boilerplate" | $SED '/^$/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_CXX=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_CXX" >&5
+$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; }
+
+
+
+
+hard_links="nottested"
+if test "$lt_cv_prog_compiler_c_o_CXX" = 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; }
+
+  export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  exclude_expsyms_CXX='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'
+  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
+    # Also, AIX nm treats weak defined symbols like other global defined
+    # symbols, whereas GNU nm marks them as "W".
+    if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+      export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+    else
+      export_symbols_cmds_CXX='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+    fi
+    ;;
+  pw32*)
+    export_symbols_cmds_CXX="$ltdll_cmds"
+    ;;
+  cygwin* | mingw* | cegcc*)
+    case $cc_basename in
+    cl*)
+      exclude_expsyms_CXX='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
+      ;;
+    *)
+      export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols'
+      exclude_expsyms_CXX='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'
+      ;;
+    esac
+    ;;
+  *)
+    export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+    ;;
+  esac
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5
+$as_echo "$ld_shlibs_CXX" >&6; }
+test "$ld_shlibs_CXX" = no && can_build_shared=no
+
+with_gnu_ld_CXX=$with_gnu_ld
+
+
+
+
+
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$archive_cmds_need_lc_CXX" in
+x|xyes)
+  # Assume -lc should be added
+  archive_cmds_need_lc_CXX=yes
+
+  if test "$enable_shared" = yes && test "$GCC" = yes; then
+    case $archive_cmds_CXX 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; }
+if ${lt_cv_archive_cmds_need_lc_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  $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_CXX
+	  pic_flag=$lt_prog_compiler_pic_CXX
+	  compiler_flags=-v
+	  linker_flags=-v
+	  verstring=
+	  output_objdir=.
+	  libname=conftest
+	  lt_save_allow_undefined_flag=$allow_undefined_flag_CXX
+	  allow_undefined_flag_CXX=
+	  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5
+  (eval $archive_cmds_CXX 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
+	    lt_cv_archive_cmds_need_lc_CXX=no
+	  else
+	    lt_cv_archive_cmds_need_lc_CXX=yes
+	  fi
+	  allow_undefined_flag_CXX=$lt_save_allow_undefined_flag
+	else
+	  cat conftest.err 1>&5
+	fi
+	$RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc_CXX" >&5
+$as_echo "$lt_cv_archive_cmds_need_lc_CXX" >&6; }
+      archive_cmds_need_lc_CXX=$lt_cv_archive_cmds_need_lc_CXX
+      ;;
+    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 # correct to gnu/linux during the next big refactor
+  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 # correct to gnu/linux during the next big refactor
+  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=`func_echo_all "$lib" | $SED '\''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 # correct to gnu/linux during the next big refactor
+  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,$cc_basename in
+  yes,*)
+    # gcc
+    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}'
+
+      ;;
+    mingw* | cegcc*)
+      # MinGW DLLs use traditional 'lib' prefix
+      soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      ;;
+    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
+    dynamic_linker='Win32 ld.exe'
+    ;;
+
+  *,cl*)
+    # Native MSVC
+    libname_spec='$name'
+    soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+    library_names_spec='${libname}.dll.lib'
+
+    case $build_os in
+    mingw*)
+      sys_lib_search_path_spec=
+      lt_save_ifs=$IFS
+      IFS=';'
+      for lt_path in $LIB
+      do
+        IFS=$lt_save_ifs
+        # Let DOS variable expansion print the short 8.3 style file name.
+        lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"`
+        sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path"
+      done
+      IFS=$lt_save_ifs
+      # Convert to MSYS style.
+      sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'`
+      ;;
+    cygwin*)
+      # Convert to unix form, then to dos form, then back to unix form
+      # but this time dos style (no spaces!) so that the unix form looks
+      # like /cygdrive/c/PROGRA~1:/cygdr...
+      sys_lib_search_path_spec=`cygpath --path --unix "$LIB"`
+      sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null`
+      sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+      ;;
+    *)
+      sys_lib_search_path_spec="$LIB"
+      if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then
+        # It is most probably a Windows format PATH.
+        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
+      # FIXME: find the short name or the path components, as spaces are
+      # common. (e.g. "Program Files" -> "PROGRA~1")
+      ;;
+    esac
+
+    # 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'
+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+      dlpath=$dir/\$dldll~
+       $RM \$dlpath'
+    shlibpath_overrides_runpath=yes
+    dynamic_linker='Win32 link.exe'
+    ;;
+
+  *)
+    # Assume MSVC wrapper
+    library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
+    dynamic_linker='Win32 ld.exe'
+    ;;
+  esac
+  # 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 # correct to gnu/linux during the next big refactor
+  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
+  ;;
+
+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[23].*) objformat=aout ;;
+    *) objformat=elf ;;
+    esac
+  fi
+  # Handle Gentoo/FreeBSD as it was Linux
+  case $host_vendor in
+    gentoo)
+      version_type=linux ;;
+    *)
+      version_type=freebsd-$objformat ;;
+  esac
+
+  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
+      ;;
+    linux)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+      soname_spec='${libname}${release}${shared_ext}$major'
+      need_lib_prefix=no
+      need_version=no
+      ;;
+  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 # correct to gnu/linux during the next big refactor
+  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
+  ;;
+
+haiku*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  dynamic_linker="$host_os runtime_loader"
+  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=LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
+  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'
+  # or fails outright, so override atomically:
+  install_override_mode=555
+  ;;
+
+interix[3-9]*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  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 # correct to gnu/linux during the next big refactor
+	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 glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  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
+  if ${lt_cv_shlibpath_overrides_runpath+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_shlibpath_overrides_runpath=no
+    save_LDFLAGS=$LDFLAGS
+    save_libdir=$libdir
+    eval "libdir=/foo; wl=\"$lt_prog_compiler_wl_CXX\"; \
+	 LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec_CXX\""
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+  if  ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then :
+  lt_cv_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
+
+fi
+
+  shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath
+
+  # 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;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'
+  ;;
+
+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 # correct to gnu/linux during the next big refactor
+  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 # correct to gnu/linux during the next big refactor
+  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 # correct to gnu/linux during the next big refactor
+  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 # correct to gnu/linux during the next big refactor
+    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 # correct to gnu/linux during the next big refactor
+  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 # correct to gnu/linux during the next big refactor
+  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_CXX=
+if test -n "$hardcode_libdir_flag_spec_CXX" ||
+   test -n "$runpath_var_CXX" ||
+   test "X$hardcode_automatic_CXX" = "Xyes" ; then
+
+  # We can hardcode non-existent directories.
+  if test "$hardcode_direct_CXX" != 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, CXX)" != no &&
+     test "$hardcode_minus_L_CXX" != no; then
+    # Linking always hardcodes the temporary library directory.
+    hardcode_action_CXX=relink
+  else
+    # We can link without hardcoding, and we can hardcode nonexisting dirs.
+    hardcode_action_CXX=immediate
+  fi
+else
+  # We cannot hardcode anything, or else we can only hardcode existing
+  # directories.
+  hardcode_action_CXX=unsupported
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action_CXX" >&5
+$as_echo "$hardcode_action_CXX" >&6; }
+
+if test "$hardcode_action_CXX" = relink ||
+   test "$inherit_rpath_CXX" = 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"
+
+  CC=$lt_save_CC
+  CFLAGS=$lt_save_CFLAGS
+  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_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_config_commands="$ac_config_commands libtool"
+
+
+
+
+# Only expand once:
+
+
+{ $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 eval \${ac_cv_prog_make_${ac_make}_set+:} false; 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
+
+# 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 ${ac_cv_prog_AR+:} false; 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_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
+
+  test -z "$ac_cv_prog_AR" && ac_cv_prog_AR="where-is-your-ar"
+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
+
+
+# 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 ${ac_cv_prog_M4+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$M4"; then
+  ac_cv_prog_M4="$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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_M4="m4"
+    $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_M4" && ac_cv_prog_M4="where-is-your-m4"
+fi
+fi
+M4=$ac_cv_prog_M4
+if test -n "$M4"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $M4" >&5
+$as_echo "$M4" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+# Extract the first word of "bison", so it can be a program name with args.
+set dummy bison; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_BISON+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$BISON"; then
+  ac_cv_prog_BISON="$BISON" # 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_BISON="bison"
+    $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_BISON" && ac_cv_prog_BISON="where-is-your-bison"
+fi
+fi
+BISON=$ac_cv_prog_BISON
+if test -n "$BISON"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $BISON" >&5
+$as_echo "$BISON" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long" >&5
+$as_echo_n "checking size of long... " >&6; }
+if ${ac_cv_sizeof_long+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long))" "ac_cv_sizeof_long"        "$ac_includes_default"; then :
+
+else
+  if test "$ac_cv_type_long" = yes; then
+     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (long)
+See \`config.log' for more details" "$LINENO" 5; }
+   else
+     ac_cv_sizeof_long=0
+   fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long" >&5
+$as_echo "$ac_cv_sizeof_long" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_LONG $ac_cv_sizeof_long
+_ACEOF
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5
+$as_echo_n "checking for an ANSI C-conforming const... " >&6; }
+if ${ac_cv_c_const+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+#ifndef __cplusplus
+  /* Ultrix mips cc rejects this sort of thing.  */
+  typedef int charset[2];
+  const charset cs = { 0, 0 };
+  /* SunOS 4.1.1 cc rejects this.  */
+  char const *const *pcpcc;
+  char **ppc;
+  /* NEC SVR4.0.2 mips cc rejects this.  */
+  struct point {int x, y;};
+  static struct point const zero = {0,0};
+  /* AIX XL C 1.02.0.0 rejects this.
+     It does not let you subtract one const X* pointer from another in
+     an arm of an if-expression whose if-part is not a constant
+     expression */
+  const char *g = "string";
+  pcpcc = &g + (g ? g-g : 0);
+  /* HPUX 7.0 cc rejects these. */
+  ++pcpcc;
+  ppc = (char**) pcpcc;
+  pcpcc = (char const *const *) ppc;
+  { /* SCO 3.2v4 cc rejects this sort of thing.  */
+    char tx;
+    char *t = &tx;
+    char const *s = 0 ? (char *) 0 : (char const *) 0;
+
+    *t++ = 0;
+    if (s) return 0;
+  }
+  { /* Someone thinks the Sun supposedly-ANSI compiler will reject this.  */
+    int x[] = {25, 17};
+    const int *foo = &x[0];
+    ++foo;
+  }
+  { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
+    typedef const int *iptr;
+    iptr p = 0;
+    ++p;
+  }
+  { /* AIX XL C 1.02.0.0 rejects this sort of thing, saying
+       "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
+    struct s { int j; const int *ap[3]; } bx;
+    struct s *b = &bx; b->j = 5;
+  }
+  { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
+    const int foo = 10;
+    if (!foo) return 0;
+  }
+  return !cs[0] && !zero.x;
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_c_const=yes
+else
+  ac_cv_c_const=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5
+$as_echo "$ac_cv_c_const" >&6; }
+if test $ac_cv_c_const = no; then
+
+$as_echo "#define const /**/" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5
+$as_echo_n "checking for inline... " >&6; }
+if ${ac_cv_c_inline+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_cv_c_inline=no
+for ac_kw in inline __inline__ __inline; do
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifndef __cplusplus
+typedef int foo_t;
+static $ac_kw foo_t static_foo () {return 0; }
+$ac_kw foo_t foo () {return 0; }
+#endif
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_c_inline=$ac_kw
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  test "$ac_cv_c_inline" != no && break
+done
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5
+$as_echo "$ac_cv_c_inline" >&6; }
+
+case $ac_cv_c_inline in
+  inline | yes) ;;
+  *)
+    case $ac_cv_c_inline in
+      no) ac_val=;;
+      *) ac_val=$ac_cv_c_inline;;
+    esac
+    cat >>confdefs.h <<_ACEOF
+#ifndef __cplusplus
+#define inline $ac_val
+#endif
+_ACEOF
+    ;;
+esac
+
+
+
+#
+# - check withs and enables.
+#
+# Check whether --enable-cf-inline was given.
+if test "${enable_cf_inline+set}" = set; then :
+  enableval=$enable_cf_inline; enable_cf_inline=$enableval
+else
+  enable_cf_inline=no
+fi
+
+
+# Check whether --enable-assertions was given.
+if test "${enable_assertions+set}" = set; then :
+  enableval=$enable_assertions;
+else
+  enable_assertions=yes
+fi
+
+
+# Check whether --enable-timing was given.
+if test "${enable_timing+set}" = set; then :
+  enableval=$enable_timing;
+else
+  enable_timing=no
+fi
+
+
+# Check whether --enable-debugoutput was given.
+if test "${enable_debugoutput+set}" = set; then :
+  enableval=$enable_debugoutput;
+else
+  enable_debugoutput=no
+fi
+
+
+# Check whether --enable-streamio was given.
+if test "${enable_streamio+set}" = set; then :
+  enableval=$enable_streamio;
+else
+  enable_streamio=no
+fi
+
+
+
+
+
+# Check whether --with-Singular was given.
+if test "${with_Singular+set}" = set; then :
+  withval=$with_Singular;
+else
+  with_Singular=yes
+fi
+
+
+PKG_REQUIRE="$PKG_REQUIRE"
+
+
+
+  # Check whether --enable-omalloc was given.
+if test "${enable_omalloc+set}" = set; then :
+  enableval=$enable_omalloc; if test "x$enableval" = "xyes"; then
+      ENABLE_OMALLOC=yes
+    fi
+else
+  ENABLE_OMALLOC=no
+fi
+
+
+
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use omalloc" >&5
+$as_echo_n "checking whether to use omalloc... " >&6; }
+
+
+
+  if test "x$ENABLE_OMALLOC" = xyes; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking   OMALLOC_INCLUDES?.." >&5
+$as_echo_n "checking   OMALLOC_INCLUDES?..... " >&6; }
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${OMALLOC_INCLUDES:-unset}" >&5
+$as_echo "${OMALLOC_INCLUDES:-unset}" >&6; }
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking   OMALLOC_LIBS?.." >&5
+$as_echo_n "checking   OMALLOC_LIBS?..... " >&6; }
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${OMALLOC_LIBS:-unset}" >&5
+$as_echo "${OMALLOC_LIBS:-unset}" >&6; }
+
+    CPPFLAGS_save="$CPPFLAGS"
+    CFLAGS_save="$CFLAGS"
+    LIBS_save="$LIBS"
+
+    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
+
+#
+    CPPFLAGS="$CPPFLAGS ${OMALLOC_INCLUDES}"
+    CFLAGS="$CFLAGS ${OMALLOC_INCLUDES}"
+    LIBS="$LIBS ${OMALLOC_LIBS}"
+
+    for ac_header in omalloc/omalloc.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "omalloc/omalloc.h" "ac_cv_header_omalloc_omalloc_h" "$ac_includes_default"
+if test "x$ac_cv_header_omalloc_omalloc_h" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_OMALLOC_OMALLOC_H 1
+_ACEOF
+
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: trusting the omalloc locations given: ${OMALLOC_INCLUDES}" >&5
+$as_echo "$as_me: WARNING: trusting the omalloc locations given: ${OMALLOC_INCLUDES}" >&2;}
+fi
+
+done
+
+
+    CFLAGS="$CFLAGS_save"
+    CPPFLAGS="$CPPFLAGS_save"
+    LIBS="$LIBS_save"
+#
+    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 "#define HAVE_OMALLOC 1" >>confdefs.h
+
+
+    PKG_REQUIRE="$PKG_REQUIRE omalloc"
+
+  else
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+  fi
+
+   if test "x$ENABLE_OMALLOC" = xyes; then
+  ENABLE_OMALLOC_TRUE=
+  ENABLE_OMALLOC_FALSE='#'
+else
+  ENABLE_OMALLOC_TRUE='#'
+  ENABLE_OMALLOC_FALSE=
+fi
+
+
+
+
+
+
+# Singular
+if test "x$with_Singular" = xyes; then
+  $as_echo "#define SINGULAR 1" >>confdefs.h
+
+  $as_echo "#define DISABLE_GMP_CPP 1" >>confdefs.h
+
+  $as_echo "#define NOSTREAMIO 1" >>confdefs.h
+
+fi
+
+# Use no streamio (C++) if SINGULAR or explicitely disabled
+if test "x$enable_streamio" = xno || test "x$with_Singular" = xyes;  then
+  $as_echo "#define NOSTREAMIO 1" >>confdefs.h
+
+else
+  for ac_header in iostream.h strstream.h fstream.h iostream string fstream
+do :
+  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+  for ac_header in ctype.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "ctype.h" "ac_cv_header_ctype_h" "$ac_includes_default"
+if test "x$ac_cv_header_ctype_h" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_CTYPE_H 1
+_ACEOF
+
+else
+   as_fn_error $? "standard C header files not found" "$LINENO" 5
+fi
+
+done
+
+
+  # since the FTE will compile only with stream IO enabled we will not
+  # check for the necessary header files if stream IO is disabled
+  for ac_header in stdarg.h signal.h errno.h unistd.h
+do :
+  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+else
+   { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: C/C++ header files not found.
+                    You will not be able to build the Factory Test Environment
+                    (though Factory itself should compile)" >&5
+$as_echo "$as_me: WARNING: C/C++ header files not found.
+                    You will not be able to build the Factory Test Environment
+                    (though Factory itself should compile)" >&2;}
+fi
+
+done
+
+fi
+
+ if test x$with_Singular != xyes && test x$enable_streamio != xno; then
+  WITH_PARSER_FOR_CANONICAL_FORM_TRUE=
+  WITH_PARSER_FOR_CANONICAL_FORM_FALSE='#'
+else
+  WITH_PARSER_FOR_CANONICAL_FORM_TRUE='#'
+  WITH_PARSER_FOR_CANONICAL_FORM_FALSE=
+fi
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether libresources should be used" >&5
+$as_echo_n "checking whether libresources should be used... " >&6; }
+if test "x$with_Singular" = xyes;
+then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking   RESOURCES_INCLUDES?.." >&5
+$as_echo_n "checking   RESOURCES_INCLUDES?..... " >&6; }
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${RESOURCES_INCLUDES:-unset}" >&5
+$as_echo "${RESOURCES_INCLUDES:-unset}" >&6; }
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking   RESOURCES_LIBS?.." >&5
+$as_echo_n "checking   RESOURCES_LIBS?..... " >&6; }
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${RESOURCES_LIBS:-unset}" >&5
+$as_echo "${RESOURCES_LIBS:-unset}" >&6; }
+
+  PKG_REQUIRE="$PKG_REQUIRE resources"
+
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$with_Singular" = xyes; then
+  ENABLE_RESOURCES_TRUE=
+  ENABLE_RESOURCES_FALSE='#'
+else
+  ENABLE_RESOURCES_TRUE='#'
+  ENABLE_RESOURCES_FALSE=
+fi
+
+
+
+
+# Always long long int???!
+$as_echo "#define FACTORY_INT64 long long int" >>confdefs.h
+
+
+
+
+# Files:
+DX_PROJECT=$PACKAGE_NAME
+
+DX_CONFIG=doxygen.cfg
+
+DX_DOCDIR=$srcdir/docu
+
+
+# Environment variables used inside doxygen.cfg:
+DX_ENV="$DX_ENV SRCDIR='$srcdir'"
+
+DX_ENV="$DX_ENV PROJECT='$DX_PROJECT'"
+
+DX_ENV="$DX_ENV DOCDIR='$DX_DOCDIR'"
+
+DX_ENV="$DX_ENV VERSION='$PACKAGE_VERSION'"
+
+
+# Doxygen itself:
+
+
+
+
+    # Check whether --enable-doxygen-doc was given.
+if test "${enable_doxygen_doc+set}" = set; then :
+  enableval=$enable_doxygen_doc;
+case "$enableval" in
+#(
+y|Y|yes|Yes|YES)
+    DX_FLAG_doc=1
+
+
+;; #(
+n|N|no|No|NO)
+    DX_FLAG_doc=0
+
+;; #(
+*)
+    as_fn_error $? "invalid value '$enableval' given to doxygen-doc" "$LINENO" 5
+;;
+esac
+
+else
+
+DX_FLAG_doc=1
+
+
+
+fi
+
+if test "$DX_FLAG_doc" = 1; then
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}doxygen", so it can be a program name with args.
+set dummy ${ac_tool_prefix}doxygen; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_DX_DOXYGEN+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $DX_DOXYGEN in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_DX_DOXYGEN="$DX_DOXYGEN" # 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_DX_DOXYGEN="$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
+
+  ;;
+esac
+fi
+DX_DOXYGEN=$ac_cv_path_DX_DOXYGEN
+if test -n "$DX_DOXYGEN"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DX_DOXYGEN" >&5
+$as_echo "$DX_DOXYGEN" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_path_DX_DOXYGEN"; then
+  ac_pt_DX_DOXYGEN=$DX_DOXYGEN
+  # Extract the first word of "doxygen", so it can be a program name with args.
+set dummy doxygen; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_ac_pt_DX_DOXYGEN+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $ac_pt_DX_DOXYGEN in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_ac_pt_DX_DOXYGEN="$ac_pt_DX_DOXYGEN" # 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_ac_pt_DX_DOXYGEN="$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
+
+  ;;
+esac
+fi
+ac_pt_DX_DOXYGEN=$ac_cv_path_ac_pt_DX_DOXYGEN
+if test -n "$ac_pt_DX_DOXYGEN"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_DX_DOXYGEN" >&5
+$as_echo "$ac_pt_DX_DOXYGEN" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_pt_DX_DOXYGEN" = x; then
+    DX_DOXYGEN=""
+  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
+    DX_DOXYGEN=$ac_pt_DX_DOXYGEN
+  fi
+else
+  DX_DOXYGEN="$ac_cv_path_DX_DOXYGEN"
+fi
+
+if test "$DX_FLAG_doc$DX_DOXYGEN" = 1; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: doxygen not found - will not generate any doxygen documentation" >&5
+$as_echo "$as_me: WARNING: doxygen not found - will not generate any doxygen documentation" >&2;}
+    DX_FLAG_doc=0
+
+fi
+
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}perl", so it can be a program name with args.
+set dummy ${ac_tool_prefix}perl; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_DX_PERL+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $DX_PERL in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_DX_PERL="$DX_PERL" # 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_DX_PERL="$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
+
+  ;;
+esac
+fi
+DX_PERL=$ac_cv_path_DX_PERL
+if test -n "$DX_PERL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DX_PERL" >&5
+$as_echo "$DX_PERL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_path_DX_PERL"; then
+  ac_pt_DX_PERL=$DX_PERL
+  # Extract the first word of "perl", so it can be a program name with args.
+set dummy perl; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_ac_pt_DX_PERL+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $ac_pt_DX_PERL in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_ac_pt_DX_PERL="$ac_pt_DX_PERL" # 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_ac_pt_DX_PERL="$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
+
+  ;;
+esac
+fi
+ac_pt_DX_PERL=$ac_cv_path_ac_pt_DX_PERL
+if test -n "$ac_pt_DX_PERL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_DX_PERL" >&5
+$as_echo "$ac_pt_DX_PERL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_pt_DX_PERL" = x; then
+    DX_PERL=""
+  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
+    DX_PERL=$ac_pt_DX_PERL
+  fi
+else
+  DX_PERL="$ac_cv_path_DX_PERL"
+fi
+
+if test "$DX_FLAG_doc$DX_PERL" = 1; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: perl not found - will not generate any doxygen documentation" >&5
+$as_echo "$as_me: WARNING: perl not found - will not generate any doxygen documentation" >&2;}
+    DX_FLAG_doc=0
+
+fi
+
+    :
+fi
+if test "$DX_FLAG_doc" = 1; then
+     if :; then
+  DX_COND_doc_TRUE=
+  DX_COND_doc_FALSE='#'
+else
+  DX_COND_doc_TRUE='#'
+  DX_COND_doc_FALSE=
+fi
+
+    DX_ENV="$DX_ENV PERL_PATH='$DX_PERL'"
+
+    :
+else
+     if false; then
+  DX_COND_doc_TRUE=
+  DX_COND_doc_FALSE='#'
+else
+  DX_COND_doc_TRUE='#'
+  DX_COND_doc_FALSE=
+fi
+
+
+    :
+fi
+
+
+# Dot for graphics:
+
+
+
+
+    # Check whether --enable-doxygen-dot was given.
+if test "${enable_doxygen_dot+set}" = set; then :
+  enableval=$enable_doxygen_dot;
+case "$enableval" in
+#(
+y|Y|yes|Yes|YES)
+    DX_FLAG_dot=1
+
+
+test "$DX_FLAG_doc" = "1" \
+|| as_fn_error $? "doxygen-dot requires doxygen-dot" "$LINENO" 5
+
+;; #(
+n|N|no|No|NO)
+    DX_FLAG_dot=0
+
+;; #(
+*)
+    as_fn_error $? "invalid value '$enableval' given to doxygen-dot" "$LINENO" 5
+;;
+esac
+
+else
+
+DX_FLAG_dot=1
+
+
+test "$DX_FLAG_doc" = "1" || DX_FLAG_dot=0
+
+
+
+fi
+
+if test "$DX_FLAG_dot" = 1; then
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}dot", so it can be a program name with args.
+set dummy ${ac_tool_prefix}dot; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_DX_DOT+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $DX_DOT in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_DX_DOT="$DX_DOT" # 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_DX_DOT="$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
+
+  ;;
+esac
+fi
+DX_DOT=$ac_cv_path_DX_DOT
+if test -n "$DX_DOT"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DX_DOT" >&5
+$as_echo "$DX_DOT" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_path_DX_DOT"; then
+  ac_pt_DX_DOT=$DX_DOT
+  # Extract the first word of "dot", so it can be a program name with args.
+set dummy dot; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_ac_pt_DX_DOT+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $ac_pt_DX_DOT in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_ac_pt_DX_DOT="$ac_pt_DX_DOT" # 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_ac_pt_DX_DOT="$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
+
+  ;;
+esac
+fi
+ac_pt_DX_DOT=$ac_cv_path_ac_pt_DX_DOT
+if test -n "$ac_pt_DX_DOT"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_DX_DOT" >&5
+$as_echo "$ac_pt_DX_DOT" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_pt_DX_DOT" = x; then
+    DX_DOT=""
+  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
+    DX_DOT=$ac_pt_DX_DOT
+  fi
+else
+  DX_DOT="$ac_cv_path_DX_DOT"
+fi
+
+if test "$DX_FLAG_dot$DX_DOT" = 1; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: dot not found - will not generate graphics for doxygen documentation" >&5
+$as_echo "$as_me: WARNING: dot not found - will not generate graphics for doxygen documentation" >&2;}
+    DX_FLAG_dot=0
+
+fi
+
+    :
+fi
+if test "$DX_FLAG_dot" = 1; then
+     if :; then
+  DX_COND_dot_TRUE=
+  DX_COND_dot_FALSE='#'
+else
+  DX_COND_dot_TRUE='#'
+  DX_COND_dot_FALSE=
+fi
+
+    DX_ENV="$DX_ENV HAVE_DOT='YES'"
+
+             DX_ENV="$DX_ENV DOT_PATH='`expr ".$DX_DOT" : '\(\.\)[^/]*$' \| "x$DX_DOT" : 'x\(.*\)/[^/]*$'`'"
+
+    :
+else
+     if false; then
+  DX_COND_dot_TRUE=
+  DX_COND_dot_FALSE='#'
+else
+  DX_COND_dot_TRUE='#'
+  DX_COND_dot_FALSE=
+fi
+
+    DX_ENV="$DX_ENV HAVE_DOT='NO'"
+
+    :
+fi
+
+
+# Man pages generation:
+
+
+
+
+    # Check whether --enable-doxygen-man was given.
+if test "${enable_doxygen_man+set}" = set; then :
+  enableval=$enable_doxygen_man;
+case "$enableval" in
+#(
+y|Y|yes|Yes|YES)
+    DX_FLAG_man=1
+
+
+test "$DX_FLAG_doc" = "1" \
+|| as_fn_error $? "doxygen-man requires doxygen-man" "$LINENO" 5
+
+;; #(
+n|N|no|No|NO)
+    DX_FLAG_man=0
+
+;; #(
+*)
+    as_fn_error $? "invalid value '$enableval' given to doxygen-man" "$LINENO" 5
+;;
+esac
+
+else
+
+DX_FLAG_man=0
+
+
+test "$DX_FLAG_doc" = "1" || DX_FLAG_man=0
+
+
+
+fi
+
+if test "$DX_FLAG_man" = 1; then
+
+    :
+fi
+if test "$DX_FLAG_man" = 1; then
+     if :; then
+  DX_COND_man_TRUE=
+  DX_COND_man_FALSE='#'
+else
+  DX_COND_man_TRUE='#'
+  DX_COND_man_FALSE=
+fi
+
+    DX_ENV="$DX_ENV GENERATE_MAN='YES'"
+
+    :
+else
+     if false; then
+  DX_COND_man_TRUE=
+  DX_COND_man_FALSE='#'
+else
+  DX_COND_man_TRUE='#'
+  DX_COND_man_FALSE=
+fi
+
+    DX_ENV="$DX_ENV GENERATE_MAN='NO'"
+
+    :
+fi
+
+
+# RTF file generation:
+
+
+
+
+    # Check whether --enable-doxygen-rtf was given.
+if test "${enable_doxygen_rtf+set}" = set; then :
+  enableval=$enable_doxygen_rtf;
+case "$enableval" in
+#(
+y|Y|yes|Yes|YES)
+    DX_FLAG_rtf=1
+
+
+test "$DX_FLAG_doc" = "1" \
+|| as_fn_error $? "doxygen-rtf requires doxygen-rtf" "$LINENO" 5
+
+;; #(
+n|N|no|No|NO)
+    DX_FLAG_rtf=0
+
+;; #(
+*)
+    as_fn_error $? "invalid value '$enableval' given to doxygen-rtf" "$LINENO" 5
+;;
+esac
+
+else
+
+DX_FLAG_rtf=0
+
+
+test "$DX_FLAG_doc" = "1" || DX_FLAG_rtf=0
+
+
+
+fi
+
+if test "$DX_FLAG_rtf" = 1; then
+
+    :
+fi
+if test "$DX_FLAG_rtf" = 1; then
+     if :; then
+  DX_COND_rtf_TRUE=
+  DX_COND_rtf_FALSE='#'
+else
+  DX_COND_rtf_TRUE='#'
+  DX_COND_rtf_FALSE=
+fi
+
+    DX_ENV="$DX_ENV GENERATE_RTF='YES'"
+
+    :
+else
+     if false; then
+  DX_COND_rtf_TRUE=
+  DX_COND_rtf_FALSE='#'
+else
+  DX_COND_rtf_TRUE='#'
+  DX_COND_rtf_FALSE=
+fi
+
+    DX_ENV="$DX_ENV GENERATE_RTF='NO'"
+
+    :
+fi
+
+
+# XML file generation:
+
+
+
+
+    # Check whether --enable-doxygen-xml was given.
+if test "${enable_doxygen_xml+set}" = set; then :
+  enableval=$enable_doxygen_xml;
+case "$enableval" in
+#(
+y|Y|yes|Yes|YES)
+    DX_FLAG_xml=1
+
+
+test "$DX_FLAG_doc" = "1" \
+|| as_fn_error $? "doxygen-xml requires doxygen-xml" "$LINENO" 5
+
+;; #(
+n|N|no|No|NO)
+    DX_FLAG_xml=0
+
+;; #(
+*)
+    as_fn_error $? "invalid value '$enableval' given to doxygen-xml" "$LINENO" 5
+;;
+esac
+
+else
+
+DX_FLAG_xml=0
+
+
+test "$DX_FLAG_doc" = "1" || DX_FLAG_xml=0
+
+
+
+fi
+
+if test "$DX_FLAG_xml" = 1; then
+
+    :
+fi
+if test "$DX_FLAG_xml" = 1; then
+     if :; then
+  DX_COND_xml_TRUE=
+  DX_COND_xml_FALSE='#'
+else
+  DX_COND_xml_TRUE='#'
+  DX_COND_xml_FALSE=
+fi
+
+    DX_ENV="$DX_ENV GENERATE_XML='YES'"
+
+    :
+else
+     if false; then
+  DX_COND_xml_TRUE=
+  DX_COND_xml_FALSE='#'
+else
+  DX_COND_xml_TRUE='#'
+  DX_COND_xml_FALSE=
+fi
+
+    DX_ENV="$DX_ENV GENERATE_XML='NO'"
+
+    :
+fi
+
+
+# (Compressed) HTML help generation:
+
+
+
+
+    # Check whether --enable-doxygen-chm was given.
+if test "${enable_doxygen_chm+set}" = set; then :
+  enableval=$enable_doxygen_chm;
+case "$enableval" in
+#(
+y|Y|yes|Yes|YES)
+    DX_FLAG_chm=1
+
+
+test "$DX_FLAG_doc" = "1" \
+|| as_fn_error $? "doxygen-chm requires doxygen-chm" "$LINENO" 5
+
+;; #(
+n|N|no|No|NO)
+    DX_FLAG_chm=0
+
+;; #(
+*)
+    as_fn_error $? "invalid value '$enableval' given to doxygen-chm" "$LINENO" 5
+;;
+esac
+
+else
+
+DX_FLAG_chm=0
+
+
+test "$DX_FLAG_doc" = "1" || DX_FLAG_chm=0
+
+
+
+fi
+
+if test "$DX_FLAG_chm" = 1; then
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}hhc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}hhc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_DX_HHC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $DX_HHC in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_DX_HHC="$DX_HHC" # 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_DX_HHC="$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
+
+  ;;
+esac
+fi
+DX_HHC=$ac_cv_path_DX_HHC
+if test -n "$DX_HHC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DX_HHC" >&5
+$as_echo "$DX_HHC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_path_DX_HHC"; then
+  ac_pt_DX_HHC=$DX_HHC
+  # Extract the first word of "hhc", so it can be a program name with args.
+set dummy hhc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_ac_pt_DX_HHC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $ac_pt_DX_HHC in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_ac_pt_DX_HHC="$ac_pt_DX_HHC" # 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_ac_pt_DX_HHC="$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
+
+  ;;
+esac
+fi
+ac_pt_DX_HHC=$ac_cv_path_ac_pt_DX_HHC
+if test -n "$ac_pt_DX_HHC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_DX_HHC" >&5
+$as_echo "$ac_pt_DX_HHC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_pt_DX_HHC" = x; then
+    DX_HHC=""
+  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
+    DX_HHC=$ac_pt_DX_HHC
+  fi
+else
+  DX_HHC="$ac_cv_path_DX_HHC"
+fi
+
+if test "$DX_FLAG_chm$DX_HHC" = 1; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: hhc not found - will not generate doxygen compressed HTML help documentation" >&5
+$as_echo "$as_me: WARNING: hhc not found - will not generate doxygen compressed HTML help documentation" >&2;}
+    DX_FLAG_chm=0
+
+fi
+
+    :
+fi
+if test "$DX_FLAG_chm" = 1; then
+     if :; then
+  DX_COND_chm_TRUE=
+  DX_COND_chm_FALSE='#'
+else
+  DX_COND_chm_TRUE='#'
+  DX_COND_chm_FALSE=
+fi
+
+    DX_ENV="$DX_ENV HHC_PATH='$DX_HHC'"
+
+             DX_ENV="$DX_ENV GENERATE_HTML='YES'"
+
+             DX_ENV="$DX_ENV GENERATE_HTMLHELP='YES'"
+
+    :
+else
+     if false; then
+  DX_COND_chm_TRUE=
+  DX_COND_chm_FALSE='#'
+else
+  DX_COND_chm_TRUE='#'
+  DX_COND_chm_FALSE=
+fi
+
+    DX_ENV="$DX_ENV GENERATE_HTMLHELP='NO'"
+
+    :
+fi
+
+
+# Seperate CHI file generation.
+
+
+
+
+    # Check whether --enable-doxygen-chi was given.
+if test "${enable_doxygen_chi+set}" = set; then :
+  enableval=$enable_doxygen_chi;
+case "$enableval" in
+#(
+y|Y|yes|Yes|YES)
+    DX_FLAG_chi=1
+
+
+test "$DX_FLAG_chm" = "1" \
+|| as_fn_error $? "doxygen-chi requires doxygen-chi" "$LINENO" 5
+
+;; #(
+n|N|no|No|NO)
+    DX_FLAG_chi=0
+
+;; #(
+*)
+    as_fn_error $? "invalid value '$enableval' given to doxygen-chi" "$LINENO" 5
+;;
+esac
+
+else
+
+DX_FLAG_chi=0
+
+
+test "$DX_FLAG_chm" = "1" || DX_FLAG_chi=0
+
+
+
+fi
+
+if test "$DX_FLAG_chi" = 1; then
+
+    :
+fi
+if test "$DX_FLAG_chi" = 1; then
+     if :; then
+  DX_COND_chi_TRUE=
+  DX_COND_chi_FALSE='#'
+else
+  DX_COND_chi_TRUE='#'
+  DX_COND_chi_FALSE=
+fi
+
+    DX_ENV="$DX_ENV GENERATE_CHI='YES'"
+
+    :
+else
+     if false; then
+  DX_COND_chi_TRUE=
+  DX_COND_chi_FALSE='#'
+else
+  DX_COND_chi_TRUE='#'
+  DX_COND_chi_FALSE=
+fi
+
+    DX_ENV="$DX_ENV GENERATE_CHI='NO'"
+
+    :
+fi
+
+
+# Plain HTML pages generation:
+
+
+
+
+    # Check whether --enable-doxygen-html was given.
+if test "${enable_doxygen_html+set}" = set; then :
+  enableval=$enable_doxygen_html;
+case "$enableval" in
+#(
+y|Y|yes|Yes|YES)
+    DX_FLAG_html=1
+
+
+test "$DX_FLAG_doc" = "1" \
+|| as_fn_error $? "doxygen-html requires doxygen-html" "$LINENO" 5
+
+test "$DX_FLAG_chm" = "0" \
+|| as_fn_error $? "doxygen-html contradicts doxygen-html" "$LINENO" 5
+
+;; #(
+n|N|no|No|NO)
+    DX_FLAG_html=0
+
+;; #(
+*)
+    as_fn_error $? "invalid value '$enableval' given to doxygen-html" "$LINENO" 5
+;;
+esac
+
+else
+
+DX_FLAG_html=1
+
+
+test "$DX_FLAG_doc" = "1" || DX_FLAG_html=0
+
+
+test "$DX_FLAG_chm" = "0" || DX_FLAG_html=0
+
+
+
+fi
+
+if test "$DX_FLAG_html" = 1; then
+
+    :
+fi
+if test "$DX_FLAG_html" = 1; then
+     if :; then
+  DX_COND_html_TRUE=
+  DX_COND_html_FALSE='#'
+else
+  DX_COND_html_TRUE='#'
+  DX_COND_html_FALSE=
+fi
+
+    DX_ENV="$DX_ENV GENERATE_HTML='YES'"
+
+    :
+else
+     if false; then
+  DX_COND_html_TRUE=
+  DX_COND_html_FALSE='#'
+else
+  DX_COND_html_TRUE='#'
+  DX_COND_html_FALSE=
+fi
+
+    test "$DX_FLAG_chm" = 1 || DX_ENV="$DX_ENV GENERATE_HTML='NO'"
+
+    :
+fi
+
+
+# PostScript file generation:
+
+
+
+
+    # Check whether --enable-doxygen-ps was given.
+if test "${enable_doxygen_ps+set}" = set; then :
+  enableval=$enable_doxygen_ps;
+case "$enableval" in
+#(
+y|Y|yes|Yes|YES)
+    DX_FLAG_ps=1
+
+
+test "$DX_FLAG_doc" = "1" \
+|| as_fn_error $? "doxygen-ps requires doxygen-ps" "$LINENO" 5
+
+;; #(
+n|N|no|No|NO)
+    DX_FLAG_ps=0
+
+;; #(
+*)
+    as_fn_error $? "invalid value '$enableval' given to doxygen-ps" "$LINENO" 5
+;;
+esac
+
+else
+
+DX_FLAG_ps=0
+
+
+test "$DX_FLAG_doc" = "1" || DX_FLAG_ps=0
+
+
+
+fi
+
+if test "$DX_FLAG_ps" = 1; then
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}latex", so it can be a program name with args.
+set dummy ${ac_tool_prefix}latex; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_DX_LATEX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $DX_LATEX in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_DX_LATEX="$DX_LATEX" # 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_DX_LATEX="$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
+
+  ;;
+esac
+fi
+DX_LATEX=$ac_cv_path_DX_LATEX
+if test -n "$DX_LATEX"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DX_LATEX" >&5
+$as_echo "$DX_LATEX" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_path_DX_LATEX"; then
+  ac_pt_DX_LATEX=$DX_LATEX
+  # Extract the first word of "latex", so it can be a program name with args.
+set dummy latex; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_ac_pt_DX_LATEX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $ac_pt_DX_LATEX in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_ac_pt_DX_LATEX="$ac_pt_DX_LATEX" # 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_ac_pt_DX_LATEX="$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
+
+  ;;
+esac
+fi
+ac_pt_DX_LATEX=$ac_cv_path_ac_pt_DX_LATEX
+if test -n "$ac_pt_DX_LATEX"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_DX_LATEX" >&5
+$as_echo "$ac_pt_DX_LATEX" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_pt_DX_LATEX" = x; then
+    DX_LATEX=""
+  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
+    DX_LATEX=$ac_pt_DX_LATEX
+  fi
+else
+  DX_LATEX="$ac_cv_path_DX_LATEX"
+fi
+
+if test "$DX_FLAG_ps$DX_LATEX" = 1; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: latex not found - will not generate doxygen PostScript documentation" >&5
+$as_echo "$as_me: WARNING: latex not found - will not generate doxygen PostScript documentation" >&2;}
+    DX_FLAG_ps=0
+
+fi
+
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}makeindex", so it can be a program name with args.
+set dummy ${ac_tool_prefix}makeindex; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_DX_MAKEINDEX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $DX_MAKEINDEX in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_DX_MAKEINDEX="$DX_MAKEINDEX" # 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_DX_MAKEINDEX="$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
+
+  ;;
+esac
+fi
+DX_MAKEINDEX=$ac_cv_path_DX_MAKEINDEX
+if test -n "$DX_MAKEINDEX"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DX_MAKEINDEX" >&5
+$as_echo "$DX_MAKEINDEX" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_path_DX_MAKEINDEX"; then
+  ac_pt_DX_MAKEINDEX=$DX_MAKEINDEX
+  # Extract the first word of "makeindex", so it can be a program name with args.
+set dummy makeindex; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_ac_pt_DX_MAKEINDEX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $ac_pt_DX_MAKEINDEX in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_ac_pt_DX_MAKEINDEX="$ac_pt_DX_MAKEINDEX" # 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_ac_pt_DX_MAKEINDEX="$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
+
+  ;;
+esac
+fi
+ac_pt_DX_MAKEINDEX=$ac_cv_path_ac_pt_DX_MAKEINDEX
+if test -n "$ac_pt_DX_MAKEINDEX"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_DX_MAKEINDEX" >&5
+$as_echo "$ac_pt_DX_MAKEINDEX" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_pt_DX_MAKEINDEX" = x; then
+    DX_MAKEINDEX=""
+  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
+    DX_MAKEINDEX=$ac_pt_DX_MAKEINDEX
+  fi
+else
+  DX_MAKEINDEX="$ac_cv_path_DX_MAKEINDEX"
+fi
+
+if test "$DX_FLAG_ps$DX_MAKEINDEX" = 1; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: makeindex not found - will not generate doxygen PostScript documentation" >&5
+$as_echo "$as_me: WARNING: makeindex not found - will not generate doxygen PostScript documentation" >&2;}
+    DX_FLAG_ps=0
+
+fi
+
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}dvips", so it can be a program name with args.
+set dummy ${ac_tool_prefix}dvips; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_DX_DVIPS+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $DX_DVIPS in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_DX_DVIPS="$DX_DVIPS" # 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_DX_DVIPS="$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
+
+  ;;
+esac
+fi
+DX_DVIPS=$ac_cv_path_DX_DVIPS
+if test -n "$DX_DVIPS"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DX_DVIPS" >&5
+$as_echo "$DX_DVIPS" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_path_DX_DVIPS"; then
+  ac_pt_DX_DVIPS=$DX_DVIPS
+  # Extract the first word of "dvips", so it can be a program name with args.
+set dummy dvips; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_ac_pt_DX_DVIPS+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $ac_pt_DX_DVIPS in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_ac_pt_DX_DVIPS="$ac_pt_DX_DVIPS" # 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_ac_pt_DX_DVIPS="$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
+
+  ;;
+esac
+fi
+ac_pt_DX_DVIPS=$ac_cv_path_ac_pt_DX_DVIPS
+if test -n "$ac_pt_DX_DVIPS"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_DX_DVIPS" >&5
+$as_echo "$ac_pt_DX_DVIPS" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_pt_DX_DVIPS" = x; then
+    DX_DVIPS=""
+  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
+    DX_DVIPS=$ac_pt_DX_DVIPS
+  fi
+else
+  DX_DVIPS="$ac_cv_path_DX_DVIPS"
+fi
+
+if test "$DX_FLAG_ps$DX_DVIPS" = 1; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: dvips not found - will not generate doxygen PostScript documentation" >&5
+$as_echo "$as_me: WARNING: dvips not found - will not generate doxygen PostScript documentation" >&2;}
+    DX_FLAG_ps=0
+
+fi
+
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}egrep", so it can be a program name with args.
+set dummy ${ac_tool_prefix}egrep; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_DX_EGREP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $DX_EGREP in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_DX_EGREP="$DX_EGREP" # 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_DX_EGREP="$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
+
+  ;;
+esac
+fi
+DX_EGREP=$ac_cv_path_DX_EGREP
+if test -n "$DX_EGREP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DX_EGREP" >&5
+$as_echo "$DX_EGREP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_path_DX_EGREP"; then
+  ac_pt_DX_EGREP=$DX_EGREP
+  # Extract the first word of "egrep", so it can be a program name with args.
+set dummy egrep; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_ac_pt_DX_EGREP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $ac_pt_DX_EGREP in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_ac_pt_DX_EGREP="$ac_pt_DX_EGREP" # 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_ac_pt_DX_EGREP="$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
+
+  ;;
+esac
+fi
+ac_pt_DX_EGREP=$ac_cv_path_ac_pt_DX_EGREP
+if test -n "$ac_pt_DX_EGREP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_DX_EGREP" >&5
+$as_echo "$ac_pt_DX_EGREP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_pt_DX_EGREP" = x; then
+    DX_EGREP=""
+  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
+    DX_EGREP=$ac_pt_DX_EGREP
+  fi
+else
+  DX_EGREP="$ac_cv_path_DX_EGREP"
+fi
+
+if test "$DX_FLAG_ps$DX_EGREP" = 1; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: egrep not found - will not generate doxygen PostScript documentation" >&5
+$as_echo "$as_me: WARNING: egrep not found - will not generate doxygen PostScript documentation" >&2;}
+    DX_FLAG_ps=0
+
+fi
+
+    :
+fi
+if test "$DX_FLAG_ps" = 1; then
+     if :; then
+  DX_COND_ps_TRUE=
+  DX_COND_ps_FALSE='#'
+else
+  DX_COND_ps_TRUE='#'
+  DX_COND_ps_FALSE=
+fi
+
+
+    :
+else
+     if false; then
+  DX_COND_ps_TRUE=
+  DX_COND_ps_FALSE='#'
+else
+  DX_COND_ps_TRUE='#'
+  DX_COND_ps_FALSE=
+fi
+
+
+    :
+fi
+
+
+# PDF file generation:
+
+
+
+
+    # Check whether --enable-doxygen-pdf was given.
+if test "${enable_doxygen_pdf+set}" = set; then :
+  enableval=$enable_doxygen_pdf;
+case "$enableval" in
+#(
+y|Y|yes|Yes|YES)
+    DX_FLAG_pdf=1
+
+
+test "$DX_FLAG_doc" = "1" \
+|| as_fn_error $? "doxygen-pdf requires doxygen-pdf" "$LINENO" 5
+
+;; #(
+n|N|no|No|NO)
+    DX_FLAG_pdf=0
+
+;; #(
+*)
+    as_fn_error $? "invalid value '$enableval' given to doxygen-pdf" "$LINENO" 5
+;;
+esac
+
+else
+
+DX_FLAG_pdf=0
+
+
+test "$DX_FLAG_doc" = "1" || DX_FLAG_pdf=0
+
+
+
+fi
+
+if test "$DX_FLAG_pdf" = 1; then
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}pdflatex", so it can be a program name with args.
+set dummy ${ac_tool_prefix}pdflatex; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_DX_PDFLATEX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $DX_PDFLATEX in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_DX_PDFLATEX="$DX_PDFLATEX" # 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_DX_PDFLATEX="$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
+
+  ;;
+esac
+fi
+DX_PDFLATEX=$ac_cv_path_DX_PDFLATEX
+if test -n "$DX_PDFLATEX"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DX_PDFLATEX" >&5
+$as_echo "$DX_PDFLATEX" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_path_DX_PDFLATEX"; then
+  ac_pt_DX_PDFLATEX=$DX_PDFLATEX
+  # Extract the first word of "pdflatex", so it can be a program name with args.
+set dummy pdflatex; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_ac_pt_DX_PDFLATEX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $ac_pt_DX_PDFLATEX in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_ac_pt_DX_PDFLATEX="$ac_pt_DX_PDFLATEX" # 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_ac_pt_DX_PDFLATEX="$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
+
+  ;;
+esac
+fi
+ac_pt_DX_PDFLATEX=$ac_cv_path_ac_pt_DX_PDFLATEX
+if test -n "$ac_pt_DX_PDFLATEX"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_DX_PDFLATEX" >&5
+$as_echo "$ac_pt_DX_PDFLATEX" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_pt_DX_PDFLATEX" = x; then
+    DX_PDFLATEX=""
+  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
+    DX_PDFLATEX=$ac_pt_DX_PDFLATEX
+  fi
+else
+  DX_PDFLATEX="$ac_cv_path_DX_PDFLATEX"
+fi
+
+if test "$DX_FLAG_pdf$DX_PDFLATEX" = 1; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: pdflatex not found - will not generate doxygen PDF documentation" >&5
+$as_echo "$as_me: WARNING: pdflatex not found - will not generate doxygen PDF documentation" >&2;}
+    DX_FLAG_pdf=0
+
+fi
+
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}makeindex", so it can be a program name with args.
+set dummy ${ac_tool_prefix}makeindex; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_DX_MAKEINDEX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $DX_MAKEINDEX in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_DX_MAKEINDEX="$DX_MAKEINDEX" # 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_DX_MAKEINDEX="$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
+
+  ;;
+esac
+fi
+DX_MAKEINDEX=$ac_cv_path_DX_MAKEINDEX
+if test -n "$DX_MAKEINDEX"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DX_MAKEINDEX" >&5
+$as_echo "$DX_MAKEINDEX" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_path_DX_MAKEINDEX"; then
+  ac_pt_DX_MAKEINDEX=$DX_MAKEINDEX
+  # Extract the first word of "makeindex", so it can be a program name with args.
+set dummy makeindex; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_ac_pt_DX_MAKEINDEX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $ac_pt_DX_MAKEINDEX in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_ac_pt_DX_MAKEINDEX="$ac_pt_DX_MAKEINDEX" # 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_ac_pt_DX_MAKEINDEX="$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
+
+  ;;
+esac
+fi
+ac_pt_DX_MAKEINDEX=$ac_cv_path_ac_pt_DX_MAKEINDEX
+if test -n "$ac_pt_DX_MAKEINDEX"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_DX_MAKEINDEX" >&5
+$as_echo "$ac_pt_DX_MAKEINDEX" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_pt_DX_MAKEINDEX" = x; then
+    DX_MAKEINDEX=""
+  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
+    DX_MAKEINDEX=$ac_pt_DX_MAKEINDEX
+  fi
+else
+  DX_MAKEINDEX="$ac_cv_path_DX_MAKEINDEX"
+fi
+
+if test "$DX_FLAG_pdf$DX_MAKEINDEX" = 1; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: makeindex not found - will not generate doxygen PDF documentation" >&5
+$as_echo "$as_me: WARNING: makeindex not found - will not generate doxygen PDF documentation" >&2;}
+    DX_FLAG_pdf=0
+
+fi
+
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}egrep", so it can be a program name with args.
+set dummy ${ac_tool_prefix}egrep; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_DX_EGREP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $DX_EGREP in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_DX_EGREP="$DX_EGREP" # 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_DX_EGREP="$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
+
+  ;;
+esac
+fi
+DX_EGREP=$ac_cv_path_DX_EGREP
+if test -n "$DX_EGREP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DX_EGREP" >&5
+$as_echo "$DX_EGREP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_path_DX_EGREP"; then
+  ac_pt_DX_EGREP=$DX_EGREP
+  # Extract the first word of "egrep", so it can be a program name with args.
+set dummy egrep; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_ac_pt_DX_EGREP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $ac_pt_DX_EGREP in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_ac_pt_DX_EGREP="$ac_pt_DX_EGREP" # 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_ac_pt_DX_EGREP="$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
+
+  ;;
+esac
+fi
+ac_pt_DX_EGREP=$ac_cv_path_ac_pt_DX_EGREP
+if test -n "$ac_pt_DX_EGREP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_DX_EGREP" >&5
+$as_echo "$ac_pt_DX_EGREP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_pt_DX_EGREP" = x; then
+    DX_EGREP=""
+  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
+    DX_EGREP=$ac_pt_DX_EGREP
+  fi
+else
+  DX_EGREP="$ac_cv_path_DX_EGREP"
+fi
+
+if test "$DX_FLAG_pdf$DX_EGREP" = 1; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: egrep not found - will not generate doxygen PDF documentation" >&5
+$as_echo "$as_me: WARNING: egrep not found - will not generate doxygen PDF documentation" >&2;}
+    DX_FLAG_pdf=0
+
+fi
+
+    :
+fi
+if test "$DX_FLAG_pdf" = 1; then
+     if :; then
+  DX_COND_pdf_TRUE=
+  DX_COND_pdf_FALSE='#'
+else
+  DX_COND_pdf_TRUE='#'
+  DX_COND_pdf_FALSE=
+fi
+
+
+    :
+else
+     if false; then
+  DX_COND_pdf_TRUE=
+  DX_COND_pdf_FALSE='#'
+else
+  DX_COND_pdf_TRUE='#'
+  DX_COND_pdf_FALSE=
+fi
+
+
+    :
+fi
+
+
+# LaTeX generation for PS and/or PDF:
+if test "$DX_FLAG_ps" = 1 || test "$DX_FLAG_pdf" = 1; then
+     if :; then
+  DX_COND_latex_TRUE=
+  DX_COND_latex_FALSE='#'
+else
+  DX_COND_latex_TRUE='#'
+  DX_COND_latex_FALSE=
+fi
+
+    DX_ENV="$DX_ENV GENERATE_LATEX='YES'"
+
+else
+     if false; then
+  DX_COND_latex_TRUE=
+  DX_COND_latex_FALSE='#'
+else
+  DX_COND_latex_TRUE='#'
+  DX_COND_latex_FALSE=
+fi
+
+    DX_ENV="$DX_ENV GENERATE_LATEX='NO'"
+
+fi
+
+# Paper size for PS and/or PDF:
+
+case "$DOXYGEN_PAPER_SIZE" in
+#(
+"")
+    DOXYGEN_PAPER_SIZE=""
+
+;; #(
+a4wide|a4|letter|legal|executive)
+    DX_ENV="$DX_ENV PAPER_SIZE='$DOXYGEN_PAPER_SIZE'"
+
+;; #(
+*)
+    as_fn_error $? "unknown DOXYGEN_PAPER_SIZE='$DOXYGEN_PAPER_SIZE'" "$LINENO" 5
+;;
+esac
+
+#For debugging:
+#echo DX_FLAG_doc=$DX_FLAG_doc
+#echo DX_FLAG_dot=$DX_FLAG_dot
+#echo DX_FLAG_man=$DX_FLAG_man
+#echo DX_FLAG_html=$DX_FLAG_html
+#echo DX_FLAG_chm=$DX_FLAG_chm
+#echo DX_FLAG_chi=$DX_FLAG_chi
+#echo DX_FLAG_rtf=$DX_FLAG_rtf
+#echo DX_FLAG_xml=$DX_FLAG_xml
+#echo DX_FLAG_pdf=$DX_FLAG_pdf
+#echo DX_FLAG_ps=$DX_FLAG_ps
+#echo DX_ENV=$DX_ENV
+
+
+# do not use `MKINSTALLDIRS' and `MAKEHEADER' since there may be
+# name clashes with other peoples configure scripts via
+# `config.cache'.  Furthermore, we do not use cache at all to
+# avoid some nasty problems with our own development environment.
+#unset ac_cv_path_FACTORY_MKINSTALLDIRS
+#unset ac_cv_path_FACTORY_MAKEHEADER
+#save_path="$PATH"
+#PATH="$PATH:$srcdir/bin"
+#AC_PATH_PROG(FACTORY_MKINSTALLDIRS, mkinstalldirs, -mkdir)
+#PATH="$srcdir/bin:$save_path"
+#AC_PATH_PROG(FACTORY_MAKEHEADER, makeheader)
+#PATH="$save_path"
+
+#
+# - expand paths.
+#
+
+#AC_MSG_CHECKING(and generating explicit install paths)
+
+## generate Makefile
+#save_prefix="$prefix"
+#save_exec_prefix="$exec_prefix"
+#test "x$prefix" = xNONE && prefix=$ac_default_prefix
+#test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+#for dir in prefix exec_prefix bindir sbindir libexecdir \
+#	   datadir sysconfdir sharedstatedir localstatedir libdir \
+#	   includedir oldincludedir infodir mandir; do
+#  eval "dir_value=\$$dir"
+#  cat >> ./conftest.mk << EXPLPATHEOT
+#$dir=$dir_value
+#explicit_$dir:
+#	@ echo \$($dir)
+#	@ if echo \$($dir) | grep '^/'; \\
+#	then echo \$($dir) > ./conftest.dir; \\
+#	else echo \`pwd\`/\$($dir) > ./conftest.dir; fi
+#EXPLPATHEOT
+#done
+#prefix="$save_prefix"
+#exec_prefix="$save_exec_prefix"
+
+# generate the explicit paths
+#make >&5 2>&1 -f ./conftest.mk explicit_datadir
+#explicit_datadir=`cat ./conftest.dir`
+#make >&5 2>&1 -f ./conftest.mk explicit_libdir
+#explicit_libdir=`cat ./conftest.dir`
+#make >&5 2>&1 -f ./conftest.mk explicit_includedir
+#explicit_includedir=`cat ./conftest.dir`
+
+# clean up
+#rm -f ./conftest.mk ./conftest.dir
+
+#AC_MSG_RESULT(done)
+
+#
+# - check for libraries.
+#
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for atof in -lm" >&5
+$as_echo_n "checking for atof in -lm... " >&6; }
+if ${ac_cv_lib_m_atof+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-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 atof ();
+int
+main ()
+{
+return atof ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_m_atof=yes
+else
+  ac_cv_lib_m_atof=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_m_atof" >&5
+$as_echo "$ac_cv_lib_m_atof" >&6; }
+if test "x$ac_cv_lib_m_atof" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBM 1
+_ACEOF
+
+  LIBS="-lm $LIBS"
+
+else
+   as_fn_error $? "libm.a not found" "$LINENO" 5
+fi
+
+
+
+DEFAULT_CHECKING_PATH="/usr /usr/local /sw /opt/local"
+
+
+# Check whether --with-gmp was given.
+if test "${with_gmp+set}" = set; then :
+  withval=$with_gmp; if test "$withval" = yes ; then
+			GMP_HOME_PATH="${DEFAULT_CHECKING_PATH}"
+	         elif test "$withval" != no ; then
+			GMP_HOME_PATH="$withval ${DEFAULT_CHECKING_PATH}"
+	        fi
+else
+  GMP_HOME_PATH="${DEFAULT_CHECKING_PATH}"
+fi
+
+
+min_gmp_version=3.1.1
+
+BACKUP_CFLAGS=${CFLAGS}
+BACKUP_LIBS=${LIBS}
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GMP >= $min_gmp_version" >&5
+$as_echo_n "checking for GMP >= $min_gmp_version... " >&6; }
+
+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
+
+
+for GMP_HOME in ${GMP_HOME_PATH}
+  do
+#	if test -r "$GMP_HOME/include/gmp.h"; then
+
+		if test "x$GMP_HOME" != "x/usr"; then
+			GMP_CFLAGS="-I${GMP_HOME}/include"
+			GMP_LIBS="-L${GMP_HOME}/lib -Wl,-rpath -Wl,${GMP_HOME}/lib -lgmp"
+		else
+			GMP_CFLAGS=""
+			GMP_LIBS="-lgmp"
+		fi
+
+		CFLAGS="${BACKUP_CFLAGS} ${GMP_CFLAGS}"
+		LIBS="${BACKUP_LIBS} ${GMP_LIBS}"
+
+    # According to C. Fieker this would link but would not RUN
+    # (AC_TRY_RUN) due to missing SHARED libgmp.so :(
+    # TODO: set LD_LIBRARY_PATH???
+		cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <gmp.h>
+int
+main ()
+{
+mpz_t a; mpz_init (a);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+        		if test "$cross_compiling" = yes; then :
+
+				{ $as_echo "$as_me:${as_lineno-$LINENO}: result: unknown" >&5
+$as_echo "unknown" >&6; }
+				echo "WARNING: You appear to be cross compiling, so there is no way to determine"
+				echo "whether your GMP version is new enough. I am assuming it is."
+
+
+
+				HAVE_GMP=yes
+
+$as_echo "#define HAVE_GMP 1" >>confdefs.h
+
+				:
+				break
+
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <gmp.h>
+			 int main () {  if (__GNU_MP_VERSION < 3) return -1; else return 0; }
+
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+				{ $as_echo "$as_me:${as_lineno-$LINENO}: result: found" >&5
+$as_echo "found" >&6; }
+
+
+
+$as_echo "#define HAVE_GMP 1" >>confdefs.h
+
+				# See if we are running GMP 4.0
+	   			{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether GMP is 4.0 or greater" >&5
+$as_echo_n "checking whether GMP is 4.0 or greater... " >&6; }
+		   		if test "$cross_compiling" = yes; then :
+
+										{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <gmp.h>
+	    			int main () { if (__GNU_MP_VERSION < 4) return -1; else return 0; }
+
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+					gmp_found="yes"
+					{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+					GMP_VERSION=""
+
+
+else
+
+					{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+$as_echo "#define GMP_VERSION_3 1" >>confdefs.h
+
+					GMP_VERSION="-DGMP_VERSION_3"
+
+
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+				:
+				break
+
+else
+
+				gmp_problem="$gmp_problem $GMP_HOME"
+				unset GMP_CFLAGS
+				unset GMP_LIBS
+
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+
+else
+
+		gmp_found="no"
+		unset GMP_CFLAGS
+		unset GMP_LIBS
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+
+#	else
+#		gmp_found="no"
+#	fi
+done
+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
+
+
+CFLAGS=${BACKUP_CFLAGS}
+LIBS=${BACKUP_LIBS}
+#unset LD_LIBRARY_PATH
+
+
+if test "x$gmp_found" != "xyes"; then
+	if test -n "$gmp_problem"; then
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: problem" >&5
+$as_echo "problem" >&6; }
+		echo "Sorry, your GMP version is too old. Disabling."
+	elif test "x$gmp_found" != "xno"; then
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5
+$as_echo "not found" >&6; }
+	fi
+	as_fn_error $? "Unable to find GMP on your machine: please use --with-gmp=PATH_TO_DIR_CONTAINING_LIB_AND_INCLUDE (see also ./configure --help if you do not understand what we are talking about)" "$LINENO" 5
+fi
+
+ if test "x$HAVE_GMP" = "xyes"; then
+  SING_HAVE_GMP_TRUE=
+  SING_HAVE_GMP_FALSE='#'
+else
+  SING_HAVE_GMP_TRUE='#'
+  SING_HAVE_GMP_FALSE=
+fi
+
+
+
+
+DEFAULT_CHECKING_PATH="/usr /usr/local /sw /opt/local"
+
+
+# Check whether --with-ntl was given.
+if test "${with_ntl+set}" = set; then :
+  withval=$with_ntl; if test "$withval" = yes ; then
+			NTL_HOME_PATH="${DEFAULT_CHECKING_PATH}"
+	      elif test "$withval" != no ; then
+			NTL_HOME_PATH="$withval"
+	     fi
+else
+  NTL_HOME_PATH="${DEFAULT_CHECKING_PATH}"
+fi
+
+
+min_ntl_version=5.0
+
+
+BACKUP_CXXFLAGS=${CXXFLAGS}
+BACKUP_CFLAGS=${CFLAGS}
+BACKUP_LIBS=${LIBS}
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+if test -n "$NTL_HOME_PATH"; then
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for NTL >= $min_ntl_version" >&5
+$as_echo_n "checking for NTL >= $min_ntl_version... " >&6; }
+fi
+
+for NTL_HOME in ${NTL_HOME_PATH}
+ do
+if test -r "$NTL_HOME/include/NTL/ZZ.h"; then
+
+	if test "x$NTL_HOME" != "x/usr"; then
+		NTL_CFLAGS="-I${NTL_HOME}/include"
+		NTL_LIBS="-L${NTL_HOME}/lib -lntl"
+	else
+		NTL_CFLAGS=
+		NTL_LIBS="-lntl"
+	fi
+###	CFLAGS="${BACKUP_CFLAGS} ${NTL_CFLAGS} ${GMP_CFLAGS}"
+	CXXFLAGS="${BACKUP_CFLAGS} ${BACKUP_CXXFLAGS} ${NTL_CFLAGS} ${GMP_CFLAGS}"
+	LIBS="${BACKUP_LIBS} ${NTL_LIBS} ${GMP_LIBS}"
+
+	cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <NTL/ZZ.h>
+int
+main ()
+{
+NTL::ZZ a;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+
+	if test "$cross_compiling" = yes; then :
+
+	ntl_found="yes"
+	ntl_cross="yes"
+	break
+
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <NTL/version.h>
+	#include <NTL/config.h>
+	#ifndef NTL_GMP_LIP
+	int main() {return -1;}
+	#else
+	int main () { if (NTL_MAJOR_VERSION < 5) return -1; else return 0;}
+	#endif
+
+_ACEOF
+if ac_fn_cxx_try_run "$LINENO"; then :
+
+	ntl_found="yes"
+	break
+
+else
+
+	ntl_problem="$problem $NTL_HOME"
+	unset NTL_CFLAGS
+	unset NTL_LIBS
+
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+
+else
+
+	ntl_found="no"
+	ntl_checked="$checked $NTL_HOME"
+	unset NTL_CFLAGS
+	unset NTL_LIBS
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+else
+	ntl_found="no"
+fi
+done
+
+if test "x$ntl_found" = "xyes" ; then
+
+
+
+$as_echo "#define HAVE_NTL 1" >>confdefs.h
+
+	HAVE_NTL=yes
+	if test "x$ntl_cross" != "xyes"; then
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: found" >&5
+$as_echo "found" >&6; }
+	else
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: unknown" >&5
+$as_echo "unknown" >&6; }
+		echo "WARNING: You appear to be cross compiling, so there is no way to determine"
+		echo "whether your NTL version is new enough. I am assuming it is."
+	fi
+	:
+elif test -n "$ntl_problem"; then
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: problem" >&5
+$as_echo "problem" >&6; }
+	echo "Sorry, your NTL version is too old or not configured with NTL_GMP_LIP=on. Disabling."
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to find NTL (which is strongly recommended) on your machine: please use --with-ntl=PATH_TO_DIR_CONTAINING_LIB_AND_INCLUDE (see also ./configure --help if you do not understand what we are talking about)" >&5
+$as_echo "$as_me: WARNING: Unable to find NTL (which is strongly recommended) on your machine: please use --with-ntl=PATH_TO_DIR_CONTAINING_LIB_AND_INCLUDE (see also ./configure --help if you do not understand what we are talking about)" >&2;}
+elif test   "x$ntl_found" = "xno";  then
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5
+$as_echo "not found" >&6; }
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to find NTL (which is strongly recommended) on your machine: please use --with-ntl=PATH_TO_DIR_CONTAINING_LIB_AND_INCLUDE (see also ./configure --help if you do not understand what we are talking about)" >&5
+$as_echo "$as_me: WARNING: Unable to find NTL (which is strongly recommended) on your machine: please use --with-ntl=PATH_TO_DIR_CONTAINING_LIB_AND_INCLUDE (see also ./configure --help if you do not understand what we are talking about)" >&2;}
+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 "x$HAVE_NTL" = "xyes"; then
+  SING_HAVE_NTL_TRUE=
+  SING_HAVE_NTL_FALSE='#'
+else
+  SING_HAVE_NTL_TRUE='#'
+  SING_HAVE_NTL_FALSE=
+fi
+
+
+# TODO: The following seems to set CXXFLAGS even if it was not defined previously!!!!
+CXXFLAGS=${BACKUP_CXXFLAGS}
+LIBS=${BACKUP_LIBS}
+#unset LD_LIBRARY_PATH
+
+
+
+
+DEFAULT_CHECKING_PATH="/usr /usr/local /sw /opt/local"
+
+
+# Check whether --with-flint was given.
+if test "${with_flint+set}" = set; then :
+  withval=$with_flint; if test "$withval" = yes ; then
+			FLINT_HOME_PATH="${DEFAULT_CHECKING_PATH}"
+	      elif test "$withval" != no ; then
+			FLINT_HOME_PATH="$withval"
+	     fi
+else
+  FLINT_HOME_PATH="${DEFAULT_CHECKING_PATH}"
+fi
+
+
+min_flint_version=2.3
+
+
+BACKUP_CFLAGS=${CFLAGS}
+BACKUP_LIBS=${LIBS}
+
+if test -n "$FLINT_HOME_PATH"; then
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for FLINT >= $min_flint_version" >&5
+$as_echo_n "checking for FLINT >= $min_flint_version... " >&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
+
+
+for FLINT_HOME in ${FLINT_HOME_PATH}
+ do
+## if test -r "$FLINT_HOME/include/flint/fmpz.h"; then
+
+	if test "x$FLINT_HOME" != "x/usr"; then
+		FLINT_CFLAGS="-I${FLINT_HOME}/include/"
+		FLINT_LIBS="-L${FLINT_HOME}/lib"
+	else
+		FLINT_CFLAGS=""
+		FLINT_LIBS=""
+	fi
+
+	# we suppose that mpfr and mpir to be in the same place or available by default
+	FLINT_LIBS="$FLINT_LIBS -lflint -lmpfr"
+
+	CFLAGS="${BACKUP_CFLAGS} ${FLINT_CFLAGS} ${GMP_CFLAGS}"
+	LIBS="${BACKUP_LIBS} ${FLINT_LIBS} ${GMP_LIBS}"
+
+	cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <flint/fmpz.h>
+int
+main ()
+{
+fmpz_t a; fmpz_init (a);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+	if test "$cross_compiling" = yes; then :
+
+	flint_found="yes"
+	flint_cross="yes"
+	break
+
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <flint/flint.h>
+	int main () { if ((int) version[0] < 2) return -1; else return 0; }
+
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+	flint_found="yes"
+	break
+
+else
+
+	flint_problem="$problem $FLINT_HOME"
+	unset FLINT_CFLAGS
+	unset FLINT_LIBS
+
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+
+else
+
+	flint_found="no"
+	flint_checked="$checked $FLINT_HOME"
+	unset FLINT_CFLAGS
+	unset FLINT_LIBS
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+#else
+#	flint_found="no"
+#fi
+done
+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
+
+
+CFLAGS=${BACKUP_CFLAGS}
+LIBS=${BACKUP_LIBS}
+#unset LD_LIBRARY_PATH
+
+
+if test "x$flint_found" = "xyes" ; then
+
+
+
+
+$as_echo "#define HAVE_FLINT 1" >>confdefs.h
+
+	HAVE_FLINT=yes
+	if test "x$flint_cross" != "xyes"; then
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: found" >&5
+$as_echo "found" >&6; }
+	else
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: unknown" >&5
+$as_echo "unknown" >&6; }
+		echo "WARNING: You appear to be cross compiling, so there is no way to determine"
+		echo "whether your FLINT version is new enough. I am assuming it is."
+	fi
+	:
+elif test -n "$flint_problem"; then
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: problem" >&5
+$as_echo "problem" >&6; }
+	echo "Sorry, your FLINT version is too old. Disabling."
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to find FLINT (which is strongly recommended) on your machine: please use --with-flint=PATH_TO_DIR_CONTAINING_LIB_AND_INCLUDE (see also ./configure --help if you do not understand what we are talking about)" >&5
+$as_echo "$as_me: WARNING: Unable to find FLINT (which is strongly recommended) on your machine: please use --with-flint=PATH_TO_DIR_CONTAINING_LIB_AND_INCLUDE (see also ./configure --help if you do not understand what we are talking about)" >&2;}
+elif test   "x$flint_found" = "xno";  then
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5
+$as_echo "not found" >&6; }
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to find FLINT (which is strongly recommended) on your machine: please use --with-flint=PATH_TO_DIR_CONTAINING_LIB_AND_INCLUDE (see also ./configure --help if you do not understand what we are talking about)" >&5
+$as_echo "$as_me: WARNING: Unable to find FLINT (which is strongly recommended) on your machine: please use --with-flint=PATH_TO_DIR_CONTAINING_LIB_AND_INCLUDE (see also ./configure --help if you do not understand what we are talking about)" >&2;}
+fi
+
+ if test "x$HAVE_FLINT" = "xyes"; then
+  SING_HAVE_FLINT_TRUE=
+  SING_HAVE_FLINT_FALSE='#'
+else
+  SING_HAVE_FLINT_TRUE='#'
+  SING_HAVE_FLINT_FALSE=
+fi
+
+
+
+# arithmetic shift
+#AC_MSG_CHECKING(whether your compiler does arithmetic shifts)
+#AC_CACHE_VAL(ac_cv_shift,
+#  [ LDFLAGS="-L$explicit_libdir $LDFLAGS"
+#	AC_TRY_RUN(
+#      [ int main() { if (-2 >> 1 == -1) return(0); else return(1); } ],
+#      ac_cv_shift=yes, ac_cv_shift=no, ac_cv_shift=yes) ])
+#if test "x$ac_cv_shift" = xyes; then
+#  AC_MSG_RESULT(yes)
+#else
+#  AC_MSG_RESULT(no)
+#fi
+
+#
+# - check for header files.
+#
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+
+for ac_header in stdio.h stdlib.h string.h time.h math.h
+do :
+  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_cxx_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+else
+   as_fn_error $? "C header files not found" "$LINENO" 5
+fi
+
+done
+
+for ac_header in cstdio
+do :
+  ac_fn_cxx_check_header_mongrel "$LINENO" "cstdio" "ac_cv_header_cstdio" "$ac_includes_default"
+if test "x$ac_cv_header_cstdio" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_CSTDIO 1
+_ACEOF
+
+fi
+
+done
+
+
+if test "x$enable_timing" != xno; then
+  for ac_header in sys/param.h sys/times.h
+do :
+  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_cxx_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+else
+   as_fn_error $? "\`sys/times.h' or \`sys/param.h' not found.  Try
+                  \`configure --disable-timing'" "$LINENO" 5
+fi
+
+done
+
+fi
+
+# font-lock-trick: '
+
+#
+# - check for compiler characteristics.
+#
+
+# use C to check compiler characteristics instead of C++.  On
+# nextstep, checking with C++ may fail.
+# AC_LANG_C
+
+# cross-compiling ?!
+#AC_C_CROSS
+#if test "x$cross_compiling" = xyes; then
+#  AC_MSG_WARN([you better specify a cache file to get the values for
+#                    cross-compiling right (e.g., call \`configure
+#                    --cache-file=yourTarget.cache').  In particular, you
+#                    should make sure that your target machine supports
+#                    arithmetic shift.])
+#fi
+
+# font-lock-trick: '
+
+#
+# - paths.
+#
+
+# note that Singular has its own mechanism to search the tables,
+# hence we do not need to mind it here
+#gftabledir='${datadir}/factory/gftables'
+#explicit_gftabledir="$explicit_datadir/gftables"
+
+# for installation of the templates
+#templatedir='${includedir}/templates'
+
+#
+# - set defines and variables according to our tests.
+#
+
+## CFLAGS
+#if test "x$GCC" = xyes && test "x$cflags_expl_set" = xno; then
+#  CFLAGS=""
+#fi
+
+# CXXFLAGS
+#if test "x$GXX" = xyes && test "x$cxxflags_expl_set" = xno; then
+#  CXXFLAGS=""
+#
+#AC_LANG_SAVE
+#AC_LANG_CPLUSPLUS
+# check whether CXX accepts -fno-rtti
+#AC_MSG_CHECKING(whether gcc accepts -fno-rtti)
+#tmp_flags=${CXXFLAGS}
+#CXXFLAGS="${CXXFLAGS}"
+#AC_CACHE_VAL(ac_cv_cxx_have_rtti,
+#AC_TRY_COMPILE(,,ac_cv_cxx_have_rtti=yes,ac_cv_cxx_have_rtti=no)
+#)
+#AC_MSG_RESULT(${ac_cv_cxx_have_rtti})
+#CXXFLAGS=$tmp_flags
+#if test "${ac_cv_cxx_have_rtti}" = yes; then
+#CXXFLAGS="$CXXFLAGS"
+#fi
+#AC_MSG_CHECKING(whether gcc accepts -fno-exceptions)
+#tmp_flags=${CXXFLAGS}
+#CXXFLAGS="${CXXFLAGS} -fno-exceptions"
+#AC_CACHE_VAL(ac_cv_cxx_have_exceptions,
+#AC_TRY_LINK(,,ac_cv_cxx_have_exceptions=yes,ac_cv_cxx_have_exceptions=no)
+#)
+#AC_MSG_RESULT(${ac_cv_cxx_have_exceptions})
+#CXXFLAGS=$tmp_flags
+#if test "${ac_cv_cxx_have_exceptions}" = yes; then
+#CXXFLAGS="$CXXFLAGS -fno-exceptions"
+#fi
+#AC_LANG_RESTORE
+#
+#fi
+
+# ARFLAGS
+#test "${ARFLAGS+set}" = set || ARFLAGS=cr
+
+# M4FLAGS
+#test "${M4FLAGS+set}" = set || M4FLAGS=
+
+# arithmetic shift
+#if test "x$ac_cv_shift" = xyes; then
+#  AC_DEFINE([HAS_ARITHMETIC_SHIFT],[1],[HAS_ARITHMETIC_SHIFT])
+#fi
+
+
+# "configurable inline methods"
+if test "x$enable_cf_inline" != xno; then
+  $as_echo "#define CF_USE_INLINE 1" >>confdefs.h
+
+fi
+
+
+# assertions
+if test "x$enable_assertions" = xno; then
+  $as_echo "#define NOASSERT 1" >>confdefs.h
+
+fi
+
+
+# timing
+if test "x$enable_timing" != xno; then
+  $as_echo "#define TIMING 1" >>confdefs.h
+
+fi
+
+# debugoutput
+
+if test "x$enable_debugoutput" != xno; then
+  $as_echo "#define DEBUGOUTPUT 1" >>confdefs.h
+
+fi
+
+#
+# - complete and substitute variables, defines.
+#
+#AC_SUBST(gftabledir)
+#AC_SUBST(templatedir)
+
+
+
+# AC_SUBST(libfactory)
+
+#AC_SUBST(ARFLAGS)
+#AC_SUBST(M4FLAGS)
+
+
+
+#AC_SUBST(factorysrc)
+#AC_SUBST(factoryincl)
+
+#AC_SUBST(alltargets)
+#AC_SUBST(installtargets)
+#AC_SUBST(uninstalltargets)
+
+factory_version="4.0.1"
+factory_configuration="'$ac_configure_args' in `pwd`"
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define FACTORYVERSION "$factory_version"
+_ACEOF
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define FACTORYCONFIGURATION "$factory_configuration"
+_ACEOF
+
+
+#AH_TEMPLATE([GFTABLEDIR], [where the gftables live])
+#AC_DEFINE_UNQUOTED([GFTABLEDIR], "$explicit_gftabledir")
+
+
+
+ac_config_files="$ac_config_files Makefile include/factory/Makefile factory.pc"
+ #  ftest/GNUmakefile
+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
+    if test "x$cache_file" != "x/dev/null"; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
+$as_echo "$as_me: updating cache $cache_file" >&6;}
+      if test ! -f "$cache_file" || test -h "$cache_file"; then
+	cat confcache >"$cache_file"
+      else
+        case $cache_file in #(
+        */* | ?:*)
+	  mv -f confcache "$cache_file"$$ &&
+	  mv -f "$cache_file"$$ "$cache_file" ;; #(
+        *)
+	  mv -f confcache "$cache_file" ;;
+	esac
+      fi
+    fi
+  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=
+U=
+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
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5
+$as_echo_n "checking that generated files are newer than configure... " >&6; }
+   if test -n "$am_sleep_pid"; then
+     # Hide warnings about reused PIDs.
+     wait $am_sleep_pid 2>/dev/null
+   fi
+   { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5
+$as_echo "done" >&6; }
+ if test -n "$EXEEXT"; then
+  am__EXEEXT_TRUE=
+  am__EXEEXT_FALSE='#'
+else
+  am__EXEEXT_TRUE='#'
+  am__EXEEXT_FALSE=
+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 "${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 "${WANT_DEBUG_TRUE}" && test -z "${WANT_DEBUG_FALSE}"; then
+  as_fn_error $? "conditional \"WANT_DEBUG\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${WANT_OPTIMIZATIONFLAGS_TRUE}" && test -z "${WANT_OPTIMIZATIONFLAGS_FALSE}"; then
+  as_fn_error $? "conditional \"WANT_OPTIMIZATIONFLAGS\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then
+  as_fn_error $? "conditional \"am__fastdepCXX\" 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 "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then
+  as_fn_error $? "conditional \"am__fastdepCXX\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${ENABLE_OMALLOC_TRUE}" && test -z "${ENABLE_OMALLOC_FALSE}"; then
+  as_fn_error $? "conditional \"ENABLE_OMALLOC\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${WITH_PARSER_FOR_CANONICAL_FORM_TRUE}" && test -z "${WITH_PARSER_FOR_CANONICAL_FORM_FALSE}"; then
+  as_fn_error $? "conditional \"WITH_PARSER_FOR_CANONICAL_FORM\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${ENABLE_RESOURCES_TRUE}" && test -z "${ENABLE_RESOURCES_FALSE}"; then
+  as_fn_error $? "conditional \"ENABLE_RESOURCES\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${DX_COND_doc_TRUE}" && test -z "${DX_COND_doc_FALSE}"; then
+  as_fn_error $? "conditional \"DX_COND_doc\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${DX_COND_doc_TRUE}" && test -z "${DX_COND_doc_FALSE}"; then
+  as_fn_error $? "conditional \"DX_COND_doc\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${DX_COND_dot_TRUE}" && test -z "${DX_COND_dot_FALSE}"; then
+  as_fn_error $? "conditional \"DX_COND_dot\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${DX_COND_dot_TRUE}" && test -z "${DX_COND_dot_FALSE}"; then
+  as_fn_error $? "conditional \"DX_COND_dot\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${DX_COND_man_TRUE}" && test -z "${DX_COND_man_FALSE}"; then
+  as_fn_error $? "conditional \"DX_COND_man\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${DX_COND_man_TRUE}" && test -z "${DX_COND_man_FALSE}"; then
+  as_fn_error $? "conditional \"DX_COND_man\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${DX_COND_rtf_TRUE}" && test -z "${DX_COND_rtf_FALSE}"; then
+  as_fn_error $? "conditional \"DX_COND_rtf\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${DX_COND_rtf_TRUE}" && test -z "${DX_COND_rtf_FALSE}"; then
+  as_fn_error $? "conditional \"DX_COND_rtf\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${DX_COND_xml_TRUE}" && test -z "${DX_COND_xml_FALSE}"; then
+  as_fn_error $? "conditional \"DX_COND_xml\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${DX_COND_xml_TRUE}" && test -z "${DX_COND_xml_FALSE}"; then
+  as_fn_error $? "conditional \"DX_COND_xml\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${DX_COND_chm_TRUE}" && test -z "${DX_COND_chm_FALSE}"; then
+  as_fn_error $? "conditional \"DX_COND_chm\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${DX_COND_chm_TRUE}" && test -z "${DX_COND_chm_FALSE}"; then
+  as_fn_error $? "conditional \"DX_COND_chm\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${DX_COND_chi_TRUE}" && test -z "${DX_COND_chi_FALSE}"; then
+  as_fn_error $? "conditional \"DX_COND_chi\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${DX_COND_chi_TRUE}" && test -z "${DX_COND_chi_FALSE}"; then
+  as_fn_error $? "conditional \"DX_COND_chi\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${DX_COND_html_TRUE}" && test -z "${DX_COND_html_FALSE}"; then
+  as_fn_error $? "conditional \"DX_COND_html\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${DX_COND_html_TRUE}" && test -z "${DX_COND_html_FALSE}"; then
+  as_fn_error $? "conditional \"DX_COND_html\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${DX_COND_ps_TRUE}" && test -z "${DX_COND_ps_FALSE}"; then
+  as_fn_error $? "conditional \"DX_COND_ps\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${DX_COND_ps_TRUE}" && test -z "${DX_COND_ps_FALSE}"; then
+  as_fn_error $? "conditional \"DX_COND_ps\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${DX_COND_pdf_TRUE}" && test -z "${DX_COND_pdf_FALSE}"; then
+  as_fn_error $? "conditional \"DX_COND_pdf\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${DX_COND_pdf_TRUE}" && test -z "${DX_COND_pdf_FALSE}"; then
+  as_fn_error $? "conditional \"DX_COND_pdf\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${DX_COND_latex_TRUE}" && test -z "${DX_COND_latex_FALSE}"; then
+  as_fn_error $? "conditional \"DX_COND_latex\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${DX_COND_latex_TRUE}" && test -z "${DX_COND_latex_FALSE}"; then
+  as_fn_error $? "conditional \"DX_COND_latex\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${SING_HAVE_GMP_TRUE}" && test -z "${SING_HAVE_GMP_FALSE}"; then
+  as_fn_error $? "conditional \"SING_HAVE_GMP\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${SING_HAVE_NTL_TRUE}" && test -z "${SING_HAVE_NTL_FALSE}"; then
+  as_fn_error $? "conditional \"SING_HAVE_NTL\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${SING_HAVE_FLINT_TRUE}" && test -z "${SING_HAVE_FLINT_FALSE}"; then
+  as_fn_error $? "conditional \"SING_HAVE_FLINT\" 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.
+as_myself=
+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 STATUS 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=$1; test $as_status -eq 0 && as_status=1
+  if test "$4"; then
+    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+  fi
+  $as_echo "$as_me: error: $2" >&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 -pR'.
+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+      as_ln_s='cp -pR'
+  elif ln conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s=ln
+  else
+    as_ln_s='cp -pR'
+  fi
+else
+  as_ln_s='cp -pR'
+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
+
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+  test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
+
+# 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 factory $as_me 4.0.1, which was
+generated by GNU Autoconf 2.69.  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
+      --config     print configuration, 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_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
+ac_cs_version="\\
+factory config.status 4.0.1
+configured by $0, generated by GNU Autoconf 2.69,
+  with options \\"\$ac_cs_config\\"
+
+Copyright (C) 2012 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=`expr "X$1" : 'X\([^=]*\)='`
+    ac_optarg=
+    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 ;;
+  --config | --confi | --conf | --con | --co | --c )
+    $as_echo "$ac_cs_config"; 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"` ;;
+    '') as_fn_error $? "missing file argument" ;;
+    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"
+PACKAGE="$PACKAGE"
+
+
+# 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'
+macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`'
+macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`'
+enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`'
+enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`'
+pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`'
+enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`'
+SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`'
+ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`'
+PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`'
+host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`'
+host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`'
+host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`'
+build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`'
+build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`'
+build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`'
+SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`'
+Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`'
+GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`'
+EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`'
+FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`'
+LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`'
+NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`'
+LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`'
+max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`'
+ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`'
+exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`'
+lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`'
+lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`'
+lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`'
+lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`'
+lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`'
+reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`'
+reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`'
+OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`'
+deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`'
+file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`'
+file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`'
+want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`'
+DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`'
+sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`'
+AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`'
+AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`'
+archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`'
+STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`'
+RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`'
+old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`'
+old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`'
+old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`'
+lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`'
+CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`'
+CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`'
+compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`'
+GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`'
+nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`'
+lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`'
+objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`'
+MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`'
+lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`'
+need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`'
+MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`'
+DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`'
+NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`'
+LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`'
+OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`'
+OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`'
+libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`'
+shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`'
+extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`'
+archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`'
+enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`'
+export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`'
+whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`'
+compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`'
+old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`'
+old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`'
+archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`'
+archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`'
+module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`'
+module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`'
+with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`'
+allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`'
+no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`'
+hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`'
+hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`'
+hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`'
+hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`'
+hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`'
+inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`'
+link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`'
+always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`'
+export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`'
+exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`'
+include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`'
+prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`'
+postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`'
+file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`'
+variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`'
+need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`'
+need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`'
+version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`'
+runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`'
+shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`'
+shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`'
+libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`'
+library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`'
+soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`'
+install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`'
+postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`'
+postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`'
+finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`'
+finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`'
+hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`'
+sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`'
+sys_lib_dlsearch_path_spec='`$ECHO "$sys_lib_dlsearch_path_spec" | $SED "$delay_single_quote_subst"`'
+hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`'
+enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`'
+enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`'
+enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`'
+old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`'
+striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`'
+compiler_lib_search_dirs='`$ECHO "$compiler_lib_search_dirs" | $SED "$delay_single_quote_subst"`'
+predep_objects='`$ECHO "$predep_objects" | $SED "$delay_single_quote_subst"`'
+postdep_objects='`$ECHO "$postdep_objects" | $SED "$delay_single_quote_subst"`'
+predeps='`$ECHO "$predeps" | $SED "$delay_single_quote_subst"`'
+postdeps='`$ECHO "$postdeps" | $SED "$delay_single_quote_subst"`'
+compiler_lib_search_path='`$ECHO "$compiler_lib_search_path" | $SED "$delay_single_quote_subst"`'
+LD_CXX='`$ECHO "$LD_CXX" | $SED "$delay_single_quote_subst"`'
+reload_flag_CXX='`$ECHO "$reload_flag_CXX" | $SED "$delay_single_quote_subst"`'
+reload_cmds_CXX='`$ECHO "$reload_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+old_archive_cmds_CXX='`$ECHO "$old_archive_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+compiler_CXX='`$ECHO "$compiler_CXX" | $SED "$delay_single_quote_subst"`'
+GCC_CXX='`$ECHO "$GCC_CXX" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_no_builtin_flag_CXX='`$ECHO "$lt_prog_compiler_no_builtin_flag_CXX" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_pic_CXX='`$ECHO "$lt_prog_compiler_pic_CXX" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_wl_CXX='`$ECHO "$lt_prog_compiler_wl_CXX" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_static_CXX='`$ECHO "$lt_prog_compiler_static_CXX" | $SED "$delay_single_quote_subst"`'
+lt_cv_prog_compiler_c_o_CXX='`$ECHO "$lt_cv_prog_compiler_c_o_CXX" | $SED "$delay_single_quote_subst"`'
+archive_cmds_need_lc_CXX='`$ECHO "$archive_cmds_need_lc_CXX" | $SED "$delay_single_quote_subst"`'
+enable_shared_with_static_runtimes_CXX='`$ECHO "$enable_shared_with_static_runtimes_CXX" | $SED "$delay_single_quote_subst"`'
+export_dynamic_flag_spec_CXX='`$ECHO "$export_dynamic_flag_spec_CXX" | $SED "$delay_single_quote_subst"`'
+whole_archive_flag_spec_CXX='`$ECHO "$whole_archive_flag_spec_CXX" | $SED "$delay_single_quote_subst"`'
+compiler_needs_object_CXX='`$ECHO "$compiler_needs_object_CXX" | $SED "$delay_single_quote_subst"`'
+old_archive_from_new_cmds_CXX='`$ECHO "$old_archive_from_new_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+old_archive_from_expsyms_cmds_CXX='`$ECHO "$old_archive_from_expsyms_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+archive_cmds_CXX='`$ECHO "$archive_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+archive_expsym_cmds_CXX='`$ECHO "$archive_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+module_cmds_CXX='`$ECHO "$module_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+module_expsym_cmds_CXX='`$ECHO "$module_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+with_gnu_ld_CXX='`$ECHO "$with_gnu_ld_CXX" | $SED "$delay_single_quote_subst"`'
+allow_undefined_flag_CXX='`$ECHO "$allow_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`'
+no_undefined_flag_CXX='`$ECHO "$no_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_flag_spec_CXX='`$ECHO "$hardcode_libdir_flag_spec_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_separator_CXX='`$ECHO "$hardcode_libdir_separator_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_direct_CXX='`$ECHO "$hardcode_direct_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_direct_absolute_CXX='`$ECHO "$hardcode_direct_absolute_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_minus_L_CXX='`$ECHO "$hardcode_minus_L_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_shlibpath_var_CXX='`$ECHO "$hardcode_shlibpath_var_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_automatic_CXX='`$ECHO "$hardcode_automatic_CXX" | $SED "$delay_single_quote_subst"`'
+inherit_rpath_CXX='`$ECHO "$inherit_rpath_CXX" | $SED "$delay_single_quote_subst"`'
+link_all_deplibs_CXX='`$ECHO "$link_all_deplibs_CXX" | $SED "$delay_single_quote_subst"`'
+always_export_symbols_CXX='`$ECHO "$always_export_symbols_CXX" | $SED "$delay_single_quote_subst"`'
+export_symbols_cmds_CXX='`$ECHO "$export_symbols_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+exclude_expsyms_CXX='`$ECHO "$exclude_expsyms_CXX" | $SED "$delay_single_quote_subst"`'
+include_expsyms_CXX='`$ECHO "$include_expsyms_CXX" | $SED "$delay_single_quote_subst"`'
+prelink_cmds_CXX='`$ECHO "$prelink_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+postlink_cmds_CXX='`$ECHO "$postlink_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+file_list_spec_CXX='`$ECHO "$file_list_spec_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_action_CXX='`$ECHO "$hardcode_action_CXX" | $SED "$delay_single_quote_subst"`'
+compiler_lib_search_dirs_CXX='`$ECHO "$compiler_lib_search_dirs_CXX" | $SED "$delay_single_quote_subst"`'
+predep_objects_CXX='`$ECHO "$predep_objects_CXX" | $SED "$delay_single_quote_subst"`'
+postdep_objects_CXX='`$ECHO "$postdep_objects_CXX" | $SED "$delay_single_quote_subst"`'
+predeps_CXX='`$ECHO "$predeps_CXX" | $SED "$delay_single_quote_subst"`'
+postdeps_CXX='`$ECHO "$postdeps_CXX" | $SED "$delay_single_quote_subst"`'
+compiler_lib_search_path_CXX='`$ECHO "$compiler_lib_search_path_CXX" | $SED "$delay_single_quote_subst"`'
+
+LTCC='$LTCC'
+LTCFLAGS='$LTCFLAGS'
+compiler='$compiler_DEFAULT'
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+  eval 'cat <<_LTECHO_EOF
+\$1
+_LTECHO_EOF'
+}
+
+# Quote evaled strings.
+for var in SHELL \
+ECHO \
+PATH_SEPARATOR \
+SED \
+GREP \
+EGREP \
+FGREP \
+LD \
+NM \
+LN_S \
+lt_SP2NL \
+lt_NL2SP \
+reload_flag \
+OBJDUMP \
+deplibs_check_method \
+file_magic_cmd \
+file_magic_glob \
+want_nocaseglob \
+DLLTOOL \
+sharedlib_from_linklib_cmd \
+AR \
+AR_FLAGS \
+archiver_list_spec \
+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 \
+nm_file_list_spec \
+lt_prog_compiler_no_builtin_flag \
+lt_prog_compiler_pic \
+lt_prog_compiler_wl \
+lt_prog_compiler_static \
+lt_cv_prog_compiler_c_o \
+need_locks \
+MANIFEST_TOOL \
+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_separator \
+exclude_expsyms \
+include_expsyms \
+file_list_spec \
+variables_saved_for_relink \
+libname_spec \
+library_names_spec \
+soname_spec \
+install_override_mode \
+finish_eval \
+old_striplib \
+striplib \
+compiler_lib_search_dirs \
+predep_objects \
+postdep_objects \
+predeps \
+postdeps \
+compiler_lib_search_path \
+LD_CXX \
+reload_flag_CXX \
+compiler_CXX \
+lt_prog_compiler_no_builtin_flag_CXX \
+lt_prog_compiler_pic_CXX \
+lt_prog_compiler_wl_CXX \
+lt_prog_compiler_static_CXX \
+lt_cv_prog_compiler_c_o_CXX \
+export_dynamic_flag_spec_CXX \
+whole_archive_flag_spec_CXX \
+compiler_needs_object_CXX \
+with_gnu_ld_CXX \
+allow_undefined_flag_CXX \
+no_undefined_flag_CXX \
+hardcode_libdir_flag_spec_CXX \
+hardcode_libdir_separator_CXX \
+exclude_expsyms_CXX \
+include_expsyms_CXX \
+file_list_spec_CXX \
+compiler_lib_search_dirs_CXX \
+predep_objects_CXX \
+postdep_objects_CXX \
+predeps_CXX \
+postdeps_CXX \
+compiler_lib_search_path_CXX; do
+    case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+    *[\\\\\\\`\\"\\\$]*)
+      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$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 \
+postlink_cmds \
+postinstall_cmds \
+postuninstall_cmds \
+finish_cmds \
+sys_lib_search_path_spec \
+sys_lib_dlsearch_path_spec \
+reload_cmds_CXX \
+old_archive_cmds_CXX \
+old_archive_from_new_cmds_CXX \
+old_archive_from_expsyms_cmds_CXX \
+archive_cmds_CXX \
+archive_expsym_cmds_CXX \
+module_cmds_CXX \
+module_expsym_cmds_CXX \
+export_symbols_cmds_CXX \
+prelink_cmds_CXX \
+postlink_cmds_CXX; do
+    case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+    *[\\\\\\\`\\"\\\$]*)
+      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\""
+      ;;
+    *)
+      eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+      ;;
+    esac
+done
+
+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'
+
+
+
+
+
+
+_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" ;;
+    "config.h") CONFIG_COMMANDS="$CONFIG_COMMANDS config.h" ;;
+    "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;;
+    "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+    "include/factory/Makefile") CONFIG_FILES="$CONFIG_FILES include/factory/Makefile" ;;
+    "factory.pc") CONFIG_FILES="$CONFIG_FILES factory.pc" ;;
+
+  *) 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= ac_tmp=
+  trap 'exit_status=$?
+  : "${ac_tmp:=$tmp}"
+  { test ! -d "$ac_tmp" || rm -fr "$ac_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 -d "$tmp"
+}  ||
+{
+  tmp=./conf$$-$RANDOM
+  (umask 077 && mkdir "$tmp")
+} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
+ac_tmp=$tmp
+
+# 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 {' >"$ac_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 >>"\$ac_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 >>"\$ac_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 < "$ac_tmp/subs1.awk" > "$ac_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 sole $(srcdir),
+# ${srcdir} and @srcdir@ entries 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[	 ]*=[	 ]*/{
+h
+s///
+s/^/:/
+s/[	 ]*$/:/
+s/:\$(srcdir):/:/g
+s/:\${srcdir}:/:/g
+s/:@srcdir@:/:/g
+s/^:*//
+s/:*$//
+x
+s/\(=[	 ]*\).*/\1/
+G
+s/\n//
+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 >"$ac_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_tt=`sed -n "/$ac_delim/p" confdefs.h`
+  if test -z "$ac_tt"; 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="$ac_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 1 "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 >"$ac_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 "$ac_tmp/subs.awk" \
+  >$ac_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' "$ac_tmp/out"`; test -n "$ac_out"; } &&
+  { ac_out=`sed -n '/^[	 ]*datarootdir[	 ]*:*=/p' \
+      "$ac_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 "$ac_tmp/stdin"
+  case $ac_file in
+  -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";;
+  *) rm -f "$ac_file" && mv "$ac_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 "$ac_tmp/defines.awk"' "$ac_file_inputs"
+    } >"$ac_tmp/config.h" \
+      || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+    if diff "$ac_file" "$ac_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 "$ac_tmp/config.h" "$ac_file" \
+	|| as_fn_error $? "could not create $ac_file" "$LINENO" 5
+    fi
+  else
+    $as_echo "/* $configure_input  */" \
+      && eval '$AWK -f "$ac_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"" || {
+  # Older Autoconf 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"`
+    # 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'`; 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
+}
+ ;;
+    "config.h":C)
+ac_prefix_conf_OUT=`echo config.h`
+ac_prefix_conf_PKG=`echo `
+ac_prefix_conf_LOW=`echo $ac_prefix_conf_PKG | sed -e "y:ABCDEFGHIJKLMNOPQRSTUVWXYZ-:abcdefghijklmnopqrstuvwxyz_:"`
+ac_prefix_conf_UPP=`echo $ac_prefix_conf_PKG | sed -e "y:abcdefghijklmnopqrstuvwxyz-:ABCDEFGHIJKLMNOPQRSTUVWXYZ_:"  -e "/^[0123456789]/s/^/_/"`
+ac_prefix_conf_INP=`echo "_config.h" | sed -e 's/ *//'`
+ac_prefix_conf_DEF=`echo "$ac_prefix_conf_UPP $PACKAGE $ac_prefix_conf_OUT" | sed -e "y:abcdefghijklmnopqrstuvwxyz:ABCDEFGHIJKLMNOPQRSTUVWXYZ:" -e "s/[^abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ]/_/g"`
+
+if test ".$ac_prefix_conf_INP" = "."; then
+   for ac_file in : $CONFIG_HEADERS; do test "_$ac_file" = _: && continue
+     case "$ac_file" in
+        *.h) ac_prefix_conf_INP=$ac_file ;;
+        *)
+     esac
+     test ".$ac_prefix_conf_INP" != "." && break
+   done
+fi
+if test ".$ac_prefix_conf_INP" = "."; then
+   case "$ac_prefix_conf_OUT" in
+      */*) ac_prefix_conf_INP=`basename "$ac_prefix_conf_OUT"`
+      ;;
+      *-*) ac_prefix_conf_INP=`echo "$ac_prefix_conf_OUT" | sed -e "s/[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_]*-//"`
+      ;;
+      *) ac_prefix_conf_INP=config.h
+      ;;
+   esac
+fi
+#if test -z "$_PKG" ; then
+#   AC_MSG_ERROR([no prefix for AX_PREFIX_PKG_CONFIG_H])
+#else
+  if test ! -f "$ac_prefix_conf_INP" ; then if test -f "$srcdir/$ac_prefix_conf_INP" ; then
+     ac_prefix_conf_INP="$srcdir/$ac_prefix_conf_INP"
+  fi fi
+  { $as_echo "$as_me:${as_lineno-$LINENO}: creating '$ac_prefix_conf_OUT' - prefix '$ac_prefix_conf_UPP' for '$ac_prefix_conf_INP' defines" >&5
+$as_echo "$as_me: creating '$ac_prefix_conf_OUT' - prefix '$ac_prefix_conf_UPP' for '$ac_prefix_conf_INP' defines" >&6;}
+  if test -f $ac_prefix_conf_INP ; then
+    $as_echo "s/^#undef  *\\([ABCDEFGHIJKLMNOPQRSTUVWXYZ_]\\)/#undef $ac_prefix_conf_UPP""\\1/" > conftest.prefix
+    $as_echo "s/^#undef  *\\([abcdefghijklmnopqrstuvwxyz]\\)/#undef $ac_prefix_conf_LOW""\\1/" >> conftest.prefix
+    $as_echo "s/^#define  *\\([ABCDEFGHIJKLMNOPQRSTUVWXYZ_][abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_]*\\)\\(.*\\)/#ifndef $ac_prefix_conf_UPP""\\1\\" >> conftest.prefix
+    $as_echo "#define $ac_prefix_conf_UPP""\\1\\2\\" >> conftest.prefix
+    $as_echo "#endif/" >> conftest.prefix
+    $as_echo "s/^#define  *\\([abcdefghijklmnopqrstuvwxyz][abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_]*\\)\\(.*\\)/#ifndef $ac_prefix_conf_LOW""\\1\\" >> conftest.prefix
+    $as_echo "#define $ac_prefix_conf_LOW""\\1\\2\\" >> conftest.prefix
+    $as_echo "#endif/" >> conftest.prefix
+
+    # now executing _script on _DEF input to create _OUT output file
+    echo "#ifndef $ac_prefix_conf_DEF"      >$tmp/pconfig.h
+    echo "#define $ac_prefix_conf_DEF 1" >>$tmp/pconfig.h
+    echo ' ' >>$tmp/pconfig.h
+
+    echo /'*' $ac_prefix_conf_OUT. Generated automatically at end of configure. '*'/ >>$tmp/pconfig.h
+    echo ' ' >>$tmp/pconfig.h
+
+    sed -f conftest.prefix $ac_prefix_conf_INP >>$tmp/pconfig.h
+    echo ' ' >>$tmp/pconfig.h
+    echo '/* once:' $ac_prefix_conf_DEF '*/' >>$tmp/pconfig.h
+    echo "#endif" >>$tmp/pconfig.h
+    if cmp -s $ac_prefix_conf_OUT $tmp/pconfig.h 2>/dev/null; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_prefix_conf_OUT is unchanged" >&5
+$as_echo "$as_me: $ac_prefix_conf_OUT is unchanged" >&6;}
+    else
+      ac_dir=`$as_dirname -- "$ac_prefix_conf_OUT" ||
+$as_expr X"$ac_prefix_conf_OUT" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$ac_prefix_conf_OUT" : 'X\(//\)[^/]' \| \
+	 X"$ac_prefix_conf_OUT" : 'X\(//\)$' \| \
+	 X"$ac_prefix_conf_OUT" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$ac_prefix_conf_OUT" |
+    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
+      rm -f "$ac_prefix_conf_OUT"
+      mv $tmp/pconfig.h "$ac_prefix_conf_OUT"
+    fi
+    cp conftest.prefix _configs.sed
+    rm _configs.sed
+  else
+    as_fn_error $? "input file $ac_prefix_conf_INP does not exist - skip generating $ac_prefix_conf_OUT" "$LINENO" 5
+  fi
+  rm -f conftest.*
+#fi
+ ;;
+    "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, 2009, 2010, 2011 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="CXX "
+
+# ### BEGIN LIBTOOL CONFIG
+
+# 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
+
+# Shell to use when invoking shell scripts.
+SHELL=$lt_SHELL
+
+# An echo program that protects backslashes.
+ECHO=$lt_ECHO
+
+# The PATH separator for the build system.
+PATH_SEPARATOR=$lt_PATH_SEPARATOR
+
+# 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
+
+# convert \$build file names to \$host format.
+to_host_file_cmd=$lt_cv_to_host_file_cmd
+
+# convert \$build files to toolchain format.
+to_tool_file_cmd=$lt_cv_to_tool_file_cmd
+
+# An object symbol dumper.
+OBJDUMP=$lt_OBJDUMP
+
+# 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
+
+# How to find potential files when deplibs_check_method = "file_magic".
+file_magic_glob=$lt_file_magic_glob
+
+# Find potential files using nocaseglob when deplibs_check_method = "file_magic".
+want_nocaseglob=$lt_want_nocaseglob
+
+# DLL creation program.
+DLLTOOL=$lt_DLLTOOL
+
+# Command to associate shared and link libraries.
+sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd
+
+# The archiver.
+AR=$lt_AR
+
+# Flags to create an archive.
+AR_FLAGS=$lt_AR_FLAGS
+
+# How to feed a file listing to the archiver.
+archiver_list_spec=$lt_archiver_list_spec
+
+# 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
+
+# Whether to use a lock for old archive extraction.
+lock_old_archive_extraction=$lock_old_archive_extraction
+
+# 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
+
+# Specify filename containing input files for \$NM.
+nm_file_list_spec=$lt_nm_file_list_spec
+
+# The root where to search for dependent libraries,and in which our libraries should be installed.
+lt_sysroot=$lt_sysroot
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# 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
+
+# Manifest tool.
+MANIFEST_TOOL=$lt_MANIFEST_TOOL
+
+# 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
+
+# Permission mode override for installation of shared libraries.
+install_override_mode=$lt_install_override_mode
+
+# 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
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag
+reload_cmds=$lt_reload_cmds
+
+# 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
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_lt_prog_compiler_pic
+
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl
+
+# 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
+
+# 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
+
+# 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
+
+# Commands necessary for finishing linking programs.
+postlink_cmds=$lt_postlink_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
+
+# The directories searched by this compiler when creating a shared library.
+compiler_lib_search_dirs=$lt_compiler_lib_search_dirs
+
+# Dependencies to place before and after the objects being linked to
+# create a shared library.
+predep_objects=$lt_predep_objects
+postdep_objects=$lt_postdep_objects
+predeps=$lt_predeps
+postdeps=$lt_postdeps
+
+# The library search path used internally by the compiler when linking
+# a shared library.
+compiler_lib_search_path=$lt_compiler_lib_search_path
+
+# ### 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 '$q' "$ltmain" >> "$cfgfile" \
+     || (rm -f "$cfgfile"; exit 1)
+
+  if test x"$xsi_shell" = xyes; then
+  sed -e '/^func_dirname ()$/,/^} # func_dirname /c\
+func_dirname ()\
+{\
+\    case ${1} in\
+\      */*) func_dirname_result="${1%/*}${2}" ;;\
+\      *  ) func_dirname_result="${3}" ;;\
+\    esac\
+} # Extended-shell func_dirname implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_basename ()$/,/^} # func_basename /c\
+func_basename ()\
+{\
+\    func_basename_result="${1##*/}"\
+} # Extended-shell func_basename implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_dirname_and_basename ()$/,/^} # func_dirname_and_basename /c\
+func_dirname_and_basename ()\
+{\
+\    case ${1} in\
+\      */*) func_dirname_result="${1%/*}${2}" ;;\
+\      *  ) func_dirname_result="${3}" ;;\
+\    esac\
+\    func_basename_result="${1##*/}"\
+} # Extended-shell func_dirname_and_basename implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_stripname ()$/,/^} # func_stripname /c\
+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}"}\
+} # Extended-shell func_stripname implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_split_long_opt ()$/,/^} # func_split_long_opt /c\
+func_split_long_opt ()\
+{\
+\    func_split_long_opt_name=${1%%=*}\
+\    func_split_long_opt_arg=${1#*=}\
+} # Extended-shell func_split_long_opt implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_split_short_opt ()$/,/^} # func_split_short_opt /c\
+func_split_short_opt ()\
+{\
+\    func_split_short_opt_arg=${1#??}\
+\    func_split_short_opt_name=${1%"$func_split_short_opt_arg"}\
+} # Extended-shell func_split_short_opt implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_lo2o ()$/,/^} # func_lo2o /c\
+func_lo2o ()\
+{\
+\    case ${1} in\
+\      *.lo) func_lo2o_result=${1%.lo}.${objext} ;;\
+\      *)    func_lo2o_result=${1} ;;\
+\    esac\
+} # Extended-shell func_lo2o implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_xform ()$/,/^} # func_xform /c\
+func_xform ()\
+{\
+    func_xform_result=${1%.*}.lo\
+} # Extended-shell func_xform implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_arith ()$/,/^} # func_arith /c\
+func_arith ()\
+{\
+    func_arith_result=$(( $* ))\
+} # Extended-shell func_arith implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_len ()$/,/^} # func_len /c\
+func_len ()\
+{\
+    func_len_result=${#1}\
+} # Extended-shell func_len implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+fi
+
+if test x"$lt_shell_append" = xyes; then
+  sed -e '/^func_append ()$/,/^} # func_append /c\
+func_append ()\
+{\
+    eval "${1}+=\\${2}"\
+} # Extended-shell func_append implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_append_quoted ()$/,/^} # func_append_quoted /c\
+func_append_quoted ()\
+{\
+\    func_quote_for_eval "${2}"\
+\    eval "${1}+=\\\\ \\$func_quote_for_eval_result"\
+} # Extended-shell func_append_quoted implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  # Save a `func_append' function call where possible by direct use of '+='
+  sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \
+    && mv -f "$cfgfile.tmp" "$cfgfile" \
+      || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+  test 0 -eq $? || _lt_function_replace_fail=:
+else
+  # Save a `func_append' function call even when '+=' is not available
+  sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \
+    && mv -f "$cfgfile.tmp" "$cfgfile" \
+      || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+  test 0 -eq $? || _lt_function_replace_fail=:
+fi
+
+if test x"$_lt_function_replace_fail" = x":"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to substitute extended shell functions in $ofile" >&5
+$as_echo "$as_me: WARNING: Unable to substitute extended shell functions in $ofile" >&2;}
+fi
+
+
+   mv -f "$cfgfile" "$ofile" ||
+    (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
+  chmod +x "$ofile"
+
+
+    cat <<_LT_EOF >> "$ofile"
+
+# ### BEGIN LIBTOOL TAG CONFIG: CXX
+
+# The linker used to build libraries.
+LD=$lt_LD_CXX
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag_CXX
+reload_cmds=$lt_reload_cmds_CXX
+
+# Commands used to build an old-style archive.
+old_archive_cmds=$lt_old_archive_cmds_CXX
+
+# A language specific compiler.
+CC=$lt_compiler_CXX
+
+# Is the compiler the GNU compiler?
+with_gcc=$GCC_CXX
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_CXX
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_lt_prog_compiler_pic_CXX
+
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl_CXX
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_lt_prog_compiler_static_CXX
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_lt_cv_prog_compiler_c_o_CXX
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$archive_cmds_need_lc_CXX
+
+# Whether or not to disallow shared libs when runtime libs are static.
+allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_CXX
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_CXX
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_whole_archive_flag_spec_CXX
+
+# Whether the compiler copes with passing no objects directly.
+compiler_needs_object=$lt_compiler_needs_object_CXX
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_CXX
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_CXX
+
+# Commands used to build a shared archive.
+archive_cmds=$lt_archive_cmds_CXX
+archive_expsym_cmds=$lt_archive_expsym_cmds_CXX
+
+# Commands used to build a loadable module if different from building
+# a shared archive.
+module_cmds=$lt_module_cmds_CXX
+module_expsym_cmds=$lt_module_expsym_cmds_CXX
+
+# Whether we are building with GNU ld or not.
+with_gnu_ld=$lt_with_gnu_ld_CXX
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_allow_undefined_flag_CXX
+
+# Flag that enforces no undefined symbols.
+no_undefined_flag=$lt_no_undefined_flag_CXX
+
+# 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_CXX
+
+# Whether we need a single "-rpath" flag with a separated argument.
+hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX
+
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
+# DIR into the resulting binary.
+hardcode_direct=$hardcode_direct_CXX
+
+# 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_CXX
+
+# Set to "yes" if using the -LDIR flag during linking hardcodes DIR
+# into the resulting binary.
+hardcode_minus_L=$hardcode_minus_L_CXX
+
+# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
+# into the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var_CXX
+
+# 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_CXX
+
+# Set to yes if linker adds runtime paths of dependent libraries
+# to runtime path list.
+inherit_rpath=$inherit_rpath_CXX
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$link_all_deplibs_CXX
+
+# Set to "yes" if exported symbols are required.
+always_export_symbols=$always_export_symbols_CXX
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_export_symbols_cmds_CXX
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_exclude_expsyms_CXX
+
+# Symbols that must always be exported.
+include_expsyms=$lt_include_expsyms_CXX
+
+# Commands necessary for linking programs (against libraries) with templates.
+prelink_cmds=$lt_prelink_cmds_CXX
+
+# Commands necessary for finishing linking programs.
+postlink_cmds=$lt_postlink_cmds_CXX
+
+# Specify filename containing input files.
+file_list_spec=$lt_file_list_spec_CXX
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action_CXX
+
+# The directories searched by this compiler when creating a shared library.
+compiler_lib_search_dirs=$lt_compiler_lib_search_dirs_CXX
+
+# Dependencies to place before and after the objects being linked to
+# create a shared library.
+predep_objects=$lt_predep_objects_CXX
+postdep_objects=$lt_postdep_objects_CXX
+predeps=$lt_predeps_CXX
+postdeps=$lt_postdeps_CXX
+
+# The library search path used internally by the compiler when linking
+# a shared library.
+compiler_lib_search_path=$lt_compiler_lib_search_path_CXX
+
+# ### END LIBTOOL TAG CONFIG: CXX
+_LT_EOF
+
+ ;;
+
+  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 1
+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/factory/configure.ac b/factory/configure.ac
new file mode 100644
index 0000000..c73e465
--- /dev/null
+++ b/factory/configure.ac
@@ -0,0 +1,403 @@
+
+dnl # emacs edit mode for this file is -*- sh -*-
+
+dnl #
+dnl # configure.in - process this file with `autoconf' to generate
+dnl #	a `configure' script.
+dnl #
+dnl # See the `INSTALL' file for information on how the `configure'
+dnl # script works.
+dnl #
+
+#
+# - initialisation.
+#
+AC_INIT([factory], [4.0.1])
+AC_CONFIG_SRCDIR(canonicalform.cc)
+AC_CONFIG_MACRO_DIR([../m4])
+AC_CONFIG_AUX_DIR([../build-aux])
+AC_CONFIG_HEADER([_config.h])
+
+AM_INIT_AUTOMAKE([-Wall foreign subdir-objects]) # -Wno-extra-portability -Werror silent-rules
+m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
+m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
+
+AM_MAINTAINER_MODE([enable])
+
+# Add pre'prefixed config
+AX_PREFIX_CONFIG_H([config.h],[],[_config.h])
+
+#
+# - check for CC and CXX but be careful about CFLAGS.
+#
+SING_RESET_FLAGS()
+SING_CHECK_SET_ARGS()
+
+#AC_PROG_CC
+#AC_PROG_CXX
+#
+# - check for some other programs.
+#
+AC_PROG_CPP
+AC_PROG_CXXCPP
+AC_PROG_LN_S
+AC_PROG_INSTALL
+## AC_DISABLE_STATIC
+AC_PROG_YACC
+LT_INIT
+AC_PROG_MAKE_SET
+AC_CHECK_PROG(AR, ar, ar, where-is-your-ar)
+AC_CHECK_PROG(M4, m4, m4, where-is-your-m4)
+AC_CHECK_PROG(BISON, bison, bison, where-is-your-bison)
+AC_CHECK_SIZEOF(long,4)
+AC_C_CONST
+AC_C_INLINE
+
+
+#
+# - check withs and enables.
+#
+AC_ARG_ENABLE(
+  cf-inline,
+  [AS_HELP_STRING([--enable-cf-inline],[build Factory with \"configurable inline methods\" enabled.])],
+  [enable_cf_inline=$enableval],
+  [enable_cf_inline=no])
+
+AC_ARG_ENABLE(
+  assertions,
+  [AS_HELP_STRING([--disable-assertions],[build Factory with no assertions])],
+  ,
+  enable_assertions=yes)
+
+AC_ARG_ENABLE(
+  timing,
+  [AS_HELP_STRING([--enable-timing],[build Factory so it will print timing information])],
+  ,
+  enable_timing=no)
+
+AC_ARG_ENABLE(
+  debugoutput,
+  [AS_HELP_STRING([--enable-debugoutput],[build Factory so it will print debugging information])],
+  ,
+  enable_debugoutput=no)
+
+AC_ARG_ENABLE(
+  streamio,
+  [AS_HELP_STRING([--enable-streamio],[build Factory with stream IO])],
+  ,
+  [enable_streamio=no])
+
+AH_TEMPLATE([NOSTREAMIO], [define to build factory without stream IO])
+
+AC_ARG_WITH(
+  Singular,
+  [AS_HELP_STRING([--without-Singular],[(obsolete) build NOT for the use with CAS Singular.])],
+  ,
+  [with_Singular=yes])
+
+PKG_REQUIRE="$PKG_REQUIRE"
+AC_SUBST(PKG_REQUIRE)
+
+SING_CHECK_OMALLOC()
+
+AH_TEMPLATE([SINGULAR], [define if linked to Singular])
+AH_TEMPLATE([DISABLE_GMP_CPP],[DISABLE_GMP_CPP])
+
+# Singular
+if test "x$with_Singular" = xyes; then
+  AC_DEFINE([SINGULAR],[1])
+  AC_DEFINE([DISABLE_GMP_CPP],[1])
+  AC_DEFINE([NOSTREAMIO],[1])
+fi
+
+# Use no streamio (C++) if SINGULAR or explicitely disabled
+if test "x$enable_streamio" = xno || test "x$with_Singular" = xyes;  then
+  AC_DEFINE([NOSTREAMIO],[1])
+else
+  AC_CHECK_HEADERS(iostream.h strstream.h fstream.h iostream string fstream)
+  AC_CHECK_HEADERS(ctype.h, , [ AC_MSG_ERROR(standard C header files not found) ])
+
+  # since the FTE will compile only with stream IO enabled we will not
+  # check for the necessary header files if stream IO is disabled
+  AC_CHECK_HEADERS(stdarg.h signal.h errno.h unistd.h, ,
+    [ AC_MSG_WARN(C/C++ header files not found.
+                    You will not be able to build the Factory Test Environment
+                    (though Factory itself should compile)) ])
+fi
+
+AM_CONDITIONAL(
+    [WITH_PARSER_FOR_CANONICAL_FORM],
+    [test x$with_Singular != xyes && test x$enable_streamio != xno])
+
+AC_ARG_VAR( [RESOURCES_INCLUDES], [INCLUDES for libresources] )
+AC_ARG_VAR( [RESOURCES_LIBS], [LIBS for libresources] )
+
+AC_MSG_CHECKING(whether libresources should be used)
+if test "x$with_Singular" = xyes;
+then
+  AC_MSG_RESULT(yes)
+
+  AC_MSG_CHECKING([  RESOURCES_INCLUDES?..])
+  AC_MSG_RESULT(${RESOURCES_INCLUDES:-unset})
+
+  AC_MSG_CHECKING([  RESOURCES_LIBS?..])
+  AC_MSG_RESULT(${RESOURCES_LIBS:-unset})
+
+  PKG_REQUIRE="$PKG_REQUIRE resources"
+  AC_SUBST(PKG_REQUIRE)
+else
+  AC_MSG_RESULT(no)
+fi
+
+AM_CONDITIONAL([ENABLE_RESOURCES],[test "x$with_Singular" = xyes])
+
+
+AH_TEMPLATE([FACTORY_INT64], [Defenition for FACTORY_INT64])
+# Always long long int???!
+AC_DEFINE([FACTORY_INT64], [long long int])
+
+DX_INIT_DOXYGEN($PACKAGE_NAME, doxygen.cfg, $srcdir/docu)
+
+# do not use `MKINSTALLDIRS' and `MAKEHEADER' since there may be
+# name clashes with other peoples configure scripts via
+# `config.cache'.  Furthermore, we do not use cache at all to
+# avoid some nasty problems with our own development environment.
+#unset ac_cv_path_FACTORY_MKINSTALLDIRS
+#unset ac_cv_path_FACTORY_MAKEHEADER
+#save_path="$PATH"
+#PATH="$PATH:$srcdir/bin"
+#AC_PATH_PROG(FACTORY_MKINSTALLDIRS, mkinstalldirs, -mkdir)
+#PATH="$srcdir/bin:$save_path"
+#AC_PATH_PROG(FACTORY_MAKEHEADER, makeheader)
+#PATH="$save_path"
+
+#
+# - expand paths.
+#
+
+#AC_MSG_CHECKING(and generating explicit install paths)
+
+## generate Makefile
+#save_prefix="$prefix"
+#save_exec_prefix="$exec_prefix"
+#test "x$prefix" = xNONE && prefix=$ac_default_prefix
+#test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+#for dir in prefix exec_prefix bindir sbindir libexecdir \
+#	   datadir sysconfdir sharedstatedir localstatedir libdir \
+#	   includedir oldincludedir infodir mandir; do
+#  eval "dir_value=\$$dir"
+#  cat >> ./conftest.mk << EXPLPATHEOT
+#$dir=$dir_value
+#explicit_$dir:
+#	@ echo \$($dir)
+#	@ if echo \$($dir) | grep '^/'; \\
+#	then echo \$($dir) > ./conftest.dir; \\
+#	else echo \`pwd\`/\$($dir) > ./conftest.dir; fi
+#EXPLPATHEOT
+#done
+#prefix="$save_prefix"
+#exec_prefix="$save_exec_prefix"
+
+# generate the explicit paths
+#make >&5 2>&1 -f ./conftest.mk explicit_datadir
+#explicit_datadir=`cat ./conftest.dir`
+#make >&5 2>&1 -f ./conftest.mk explicit_libdir
+#explicit_libdir=`cat ./conftest.dir`
+#make >&5 2>&1 -f ./conftest.mk explicit_includedir
+#explicit_includedir=`cat ./conftest.dir`
+
+# clean up
+#rm -f ./conftest.mk ./conftest.dir
+
+#AC_MSG_RESULT(done)
+
+#
+# - check for libraries.
+#
+AC_CHECK_LIB(m, atof, , [ AC_MSG_ERROR(libm.a not found) ])
+
+LB_CHECK_GMP(3.1.1,,AC_MSG_ERROR([Unable to find GMP on your machine: please use --with-gmp=PATH_TO_DIR_CONTAINING_LIB_AND_INCLUDE (see also ./configure --help if you do not understand what we are talking about)]))
+
+LB_CHECK_NTL(5.0,,AC_MSG_WARN([Unable to find NTL (which is strongly recommended) on your machine: please use --with-ntl=PATH_TO_DIR_CONTAINING_LIB_AND_INCLUDE (see also ./configure --help if you do not understand what we are talking about)]))
+
+LB_CHECK_FLINT(2.3,,AC_MSG_WARN([Unable to find FLINT (which is strongly recommended) on your machine: please use --with-flint=PATH_TO_DIR_CONTAINING_LIB_AND_INCLUDE (see also ./configure --help if you do not understand what we are talking about)]))
+
+# arithmetic shift
+#AC_MSG_CHECKING(whether your compiler does arithmetic shifts)
+#AC_CACHE_VAL(ac_cv_shift,
+#  [ LDFLAGS="-L$explicit_libdir $LDFLAGS"
+#	AC_TRY_RUN(
+#      [ int main() { if (-2 >> 1 == -1) return(0); else return(1); } ],
+#      ac_cv_shift=yes, ac_cv_shift=no, ac_cv_shift=yes) ])
+#if test "x$ac_cv_shift" = xyes; then
+#  AC_MSG_RESULT(yes)
+#else
+#  AC_MSG_RESULT(no)
+#fi
+
+#
+# - check for header files.
+#
+AC_LANG_CPLUSPLUS
+
+AC_CHECK_HEADERS(stdio.h stdlib.h string.h time.h math.h, ,
+  [ AC_MSG_ERROR(C header files not found) ])
+AC_CHECK_HEADERS(cstdio)
+
+if test "x$enable_timing" != xno; then
+  AC_CHECK_HEADERS(sys/param.h sys/times.h, ,
+    [ AC_MSG_ERROR(\`sys/times.h' or \`sys/param.h' not found.  Try
+                  \`configure --disable-timing') ])
+fi
+
+# font-lock-trick: '
+
+#
+# - check for compiler characteristics.
+#
+
+# use C to check compiler characteristics instead of C++.  On
+# nextstep, checking with C++ may fail.
+# AC_LANG_C
+
+# cross-compiling ?!
+#AC_C_CROSS
+#if test "x$cross_compiling" = xyes; then
+#  AC_MSG_WARN([you better specify a cache file to get the values for
+#                    cross-compiling right (e.g., call \`configure
+#                    --cache-file=yourTarget.cache').  In particular, you
+#                    should make sure that your target machine supports
+#                    arithmetic shift.])
+#fi
+
+# font-lock-trick: '
+
+#
+# - paths.
+#
+
+# note that Singular has its own mechanism to search the tables,
+# hence we do not need to mind it here
+#gftabledir='${datadir}/factory/gftables'
+#explicit_gftabledir="$explicit_datadir/gftables"
+
+# for installation of the templates
+#templatedir='${includedir}/templates'
+
+#
+# - set defines and variables according to our tests.
+#
+
+## CFLAGS
+#if test "x$GCC" = xyes && test "x$cflags_expl_set" = xno; then
+#  CFLAGS=""
+#fi
+
+# CXXFLAGS
+#if test "x$GXX" = xyes && test "x$cxxflags_expl_set" = xno; then
+#  CXXFLAGS=""
+#
+#AC_LANG_SAVE
+#AC_LANG_CPLUSPLUS
+# check whether CXX accepts -fno-rtti
+#AC_MSG_CHECKING(whether gcc accepts -fno-rtti)
+#tmp_flags=${CXXFLAGS}
+#CXXFLAGS="${CXXFLAGS}"
+#AC_CACHE_VAL(ac_cv_cxx_have_rtti,
+#AC_TRY_COMPILE(,,ac_cv_cxx_have_rtti=yes,ac_cv_cxx_have_rtti=no)
+#)
+#AC_MSG_RESULT(${ac_cv_cxx_have_rtti})
+#CXXFLAGS=$tmp_flags
+#if test "${ac_cv_cxx_have_rtti}" = yes; then
+#CXXFLAGS="$CXXFLAGS"
+#fi
+#AC_MSG_CHECKING(whether gcc accepts -fno-exceptions)
+#tmp_flags=${CXXFLAGS}
+#CXXFLAGS="${CXXFLAGS} -fno-exceptions"
+#AC_CACHE_VAL(ac_cv_cxx_have_exceptions,
+#AC_TRY_LINK(,,ac_cv_cxx_have_exceptions=yes,ac_cv_cxx_have_exceptions=no)
+#)
+#AC_MSG_RESULT(${ac_cv_cxx_have_exceptions})
+#CXXFLAGS=$tmp_flags
+#if test "${ac_cv_cxx_have_exceptions}" = yes; then
+#CXXFLAGS="$CXXFLAGS -fno-exceptions"
+#fi
+#AC_LANG_RESTORE
+#
+#fi
+
+# ARFLAGS
+#test "${ARFLAGS+set}" = set || ARFLAGS=cr
+
+# M4FLAGS
+#test "${M4FLAGS+set}" = set || M4FLAGS=
+
+# arithmetic shift
+#if test "x$ac_cv_shift" = xyes; then
+#  AC_DEFINE([HAS_ARITHMETIC_SHIFT],[1],[HAS_ARITHMETIC_SHIFT])
+#fi
+
+AH_TEMPLATE([CF_USE_INLINE], [define to use "configurable inline methods" (see cf_inline.cc)])
+# "configurable inline methods"
+if test "x$enable_cf_inline" != xno; then
+  AC_DEFINE([CF_USE_INLINE],[1])
+fi
+
+AH_TEMPLATE([NOASSERT], [define if you do not want to activate assertions])
+# assertions
+if test "x$enable_assertions" = xno; then
+  AC_DEFINE([NOASSERT],[1])
+fi
+
+AH_TEMPLATE([TIMING], [define if you want to activate the timing stuff])
+# timing
+if test "x$enable_timing" != xno; then
+  AC_DEFINE([TIMING],[1])
+fi
+
+# debugoutput
+AH_TEMPLATE([DEBUGOUTPUT], [define if you want to have debugging output])
+if test "x$enable_debugoutput" != xno; then
+  AC_DEFINE([DEBUGOUTPUT],[1])
+fi
+
+#
+# - complete and substitute variables, defines.
+#
+#AC_SUBST(gftabledir)
+#AC_SUBST(templatedir)
+
+
+
+# AC_SUBST(libfactory)
+
+#AC_SUBST(ARFLAGS)
+#AC_SUBST(M4FLAGS)
+
+AC_SUBST(MAKEHEADERFLAGS)
+
+#AC_SUBST(factorysrc)
+#AC_SUBST(factoryincl)
+
+#AC_SUBST(alltargets)
+#AC_SUBST(installtargets)
+#AC_SUBST(uninstalltargets)
+
+factory_version="4.0.1"
+factory_configuration="'$ac_configure_args' in `pwd`"
+AC_SUBST(factory_version)
+
+AH_TEMPLATE([FACTORYVERSION], [factory version])
+AC_DEFINE_UNQUOTED([FACTORYVERSION], "$factory_version")
+
+AH_TEMPLATE([FACTORYCONFIGURATION], [factory configuration])
+AC_DEFINE_UNQUOTED([FACTORYCONFIGURATION], "$factory_configuration")
+
+#AH_TEMPLATE([GFTABLEDIR], [where the gftables live])
+#AC_DEFINE_UNQUOTED([GFTABLEDIR], "$explicit_gftabledir")
+
+
+
+AC_CONFIG_FILES([Makefile include/factory/Makefile factory.pc]) #  ftest/GNUmakefile
+AC_OUTPUT
+
diff --git a/factory/cplusplus.cc b/factory/cplusplus.cc
new file mode 100644
index 0000000..c671de1
--- /dev/null
+++ b/factory/cplusplus.cc
@@ -0,0 +1,37 @@
+#include <stdio.h>
+
+#define QUOTEME_(x) #x
+#define QUOTEME(x) QUOTEME_(x)
+
+int main(void)
+{
+   int ret;
+#  ifdef __cplusplus
+   printf("#ifndef __cplusplus   \n" );
+   printf("/*BEWARE: this fix can lead to problems if cf_gmp.h is publicly installed, while mixing different (versions of) compilers!!!*/\n" );
+   printf("#define __cplusplus %s\n", QUOTEME( __cplusplus )); // System current compiler DEPENDENT!!!
+   printf("#endif /*__cplusplus*/\n" );
+   ret = 0;
+#  else
+   ret = 1;
+#  endif
+
+   return ret;
+/*
+ #define __cplusplus_backup __cplusplus
+
+#ifdef __cplusplus_backup
+  printf("__cplusplus_backup: %s\n", QUOTEME(__cplusplus_backup) );
+#else
+  printf("undefined __cplusplus_backup!\n");
+#endif
+
+#undef __cplusplus
+
+#ifdef __cplusplus_backup
+  printf("__cplusplus_backup: %s\n", QUOTEME(__cplusplus_backup) );
+#else
+  printf("undefined __cplusplus_backup!\n");
+#endif
+*/
+}
diff --git a/factory/debug.cc b/factory/debug.cc
new file mode 100644
index 0000000..45b0ccd
--- /dev/null
+++ b/factory/debug.cc
@@ -0,0 +1,34 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+static int deb_level = -1;
+char * deb_level_msg = (char *)"";
+
+void deb_inc_level()
+{
+    int i;
+
+    // deb_level == -1 iff we enter this function for the first time
+    if ( deb_level == -1 )
+        deb_level = 0;
+    else
+        delete [] deb_level_msg;
+
+    deb_level++;
+    deb_level_msg = new char[3*deb_level+1];
+    for ( i = 0; i < 3*deb_level; i++ )
+        deb_level_msg[i] = ' ';
+    deb_level_msg[3*deb_level] = '\0';
+}
+
+void deb_dec_level()
+{
+    if ( deb_level > 0 ) {
+        int i;
+        deb_level--;
+        delete [] deb_level_msg;
+        deb_level_msg = new char[3*deb_level+1];
+            for ( i = 0; i < 3*deb_level; i++ )
+                deb_level_msg[i] = ' ';
+        deb_level_msg[3*deb_level] = '\0';
+    }
+}
diff --git a/factory/debug.h b/factory/debug.h
new file mode 100644
index 0000000..cabbb68
--- /dev/null
+++ b/factory/debug.h
@@ -0,0 +1,50 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+/**
+ * @file debug.h
+ *
+ * functions to print debug output
+ *
+ * @note needs --enable-debugoutput --enable-streamio at configure
+**/
+
+/* It should be possible to include this file multiple times for different */
+/* settings of DEBUGOUTPUT */
+
+#undef DEBINCLEVEL
+#undef DEBDECLEVEL
+#undef DEBOUTSL
+#undef DEBOUT
+#undef DEBOUTENDL
+#undef DEBOUTLN
+
+#ifdef DEBUGOUTPUT
+#include <iostream>
+#ifdef HAVE_IOSTREAM
+#include <iostream>
+#elif defined(HAVE_IOSTREAM_H)
+#include <iostream.h>
+#endif
+void deb_inc_level();
+void deb_dec_level();
+extern char * deb_level_msg;
+#define DEBINCLEVEL(stream, msg) \
+(std::stream << deb_level_msg << "entering << " << msg << " >>" << std::endl, deb_inc_level())
+#define DEBDECLEVEL(stream, msg) \
+(deb_dec_level(), std::stream << deb_level_msg << "leaving << " << msg << " >>" << std::endl)
+#define DEBOUTSL(stream) \
+(std::stream << deb_level_msg, std::stream.flush())
+#define DEBOUT(stream, objects) \
+(std::stream << objects, std::stream.flush())
+#define DEBOUTENDL(stream) \
+(std::stream << std::endl)
+#define DEBOUTLN(stream, objects) \
+(std::stream << deb_level_msg << objects << std::endl)
+#else /* DEBUGOUTPUT */
+#define DEBINCLEVEL(stream, msg)
+#define DEBDECLEVEL(stream, msg)
+#define DEBOUTSL(stream)
+#define DEBOUT(stream, objects)
+#define DEBOUTENDL(stream)
+#define DEBOUTLN(stream, objects)
+#endif /* DEBUGOUTPUT */
diff --git a/factory/doxygen.cfg b/factory/doxygen.cfg
new file mode 100644
index 0000000..b5aba74
--- /dev/null
+++ b/factory/doxygen.cfg
@@ -0,0 +1,2305 @@
+# Doxyfile 1.8.6
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project.
+#
+# All text after a double hash (##) is considered a comment and is placed in
+# front of the TAG it is preceding.
+#
+# All text after a single hash (#) is considered a comment and will be ignored.
+# The format is:
+# TAG = value [value, ...]
+# For lists, items can also be appended using:
+# TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (\" \").
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file
+# that follow. The default is UTF-8 which is also the encoding used for all text
+# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv
+# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv
+# for the list of possible encodings.
+# The default value is: UTF-8.
+
+DOXYFILE_ENCODING      = UTF-8
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by
+# double-quotes, unless you are using Doxywizard) that should identify the
+# project for which the documentation is generated. This name is used in the
+# title of most generated pages and in a few other places.
+# The default value is: My Project.
+
+PROJECT_NAME           = $(PROJECT)-$(VERSION)
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number. This
+# could be handy for archiving the generated documentation or if some version
+# control system is used.
+
+PROJECT_NUMBER         =
+
+# Using the PROJECT_BRIEF tag one can provide an optional one line description
+# for a project that appears at the top of each page and should give viewer a
+# quick idea about the purpose of the project. Keep the description short.
+
+PROJECT_BRIEF          =
+
+# With the PROJECT_LOGO tag one can specify an logo or icon that is included in
+# the documentation. The maximum height of the logo should not exceed 55 pixels
+# and the maximum width should not exceed 200 pixels. Doxygen will copy the logo
+# to the output directory.
+
+PROJECT_LOGO           =
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
+# into which the generated documentation will be written. If a relative path is
+# entered, it will be relative to the location where doxygen was started. If
+# left blank the current directory will be used.
+
+OUTPUT_DIRECTORY       = $(DOCDIR)
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 4096 sub-
+# directories (in 2 levels) under the output directory of each output format and
+# will distribute the generated files over these directories. Enabling this
+# option can be useful when feeding doxygen a huge amount of source files, where
+# putting all generated files in the same directory would otherwise causes
+# performance problems for the file system.
+# The default value is: NO.
+
+CREATE_SUBDIRS         = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese,
+# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States),
+# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian,
+# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages),
+# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian,
+# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian,
+# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish,
+# Ukrainian and Vietnamese.
+# The default value is: English.
+
+OUTPUT_LANGUAGE        = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES doxygen will include brief member
+# descriptions after the members that are listed in the file and class
+# documentation (similar to Javadoc). Set to NO to disable this.
+# The default value is: YES.
+
+BRIEF_MEMBER_DESC      = YES
+
+# If the REPEAT_BRIEF tag is set to YES doxygen will prepend the brief
+# description of a member or function before the detailed description
+#
+# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+# The default value is: YES.
+
+REPEAT_BRIEF           = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator that is
+# used to form the text in various listings. Each string in this list, if found
+# as the leading text of the brief description, will be stripped from the text
+# and the result, after processing the whole list, is used as the annotated
+# text. Otherwise, the brief description is used as-is. If left blank, the
+# following values are used ($name is automatically replaced with the name of
+# the entity):The $name class, The $name widget, The $name file, is, provides,
+# specifies, contains, represents, a, an and the.
+
+ABBREVIATE_BRIEF       =
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# doxygen will generate a detailed section even if there is only a brief
+# description.
+# The default value is: NO.
+
+ALWAYS_DETAILED_SEC    = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and assignment
+# operators of the base classes will not be shown.
+# The default value is: NO.
+
+INLINE_INHERITED_MEMB  = YES
+
+# If the FULL_PATH_NAMES tag is set to YES doxygen will prepend the full path
+# before files name in the file list and in the header files. If set to NO the
+# shortest path that makes the file name unique will be used
+# The default value is: YES.
+
+FULL_PATH_NAMES        = YES
+
+# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path.
+# Stripping is only done if one of the specified strings matches the left-hand
+# part of the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the path to
+# strip.
+#
+# Note that you can specify absolute paths here, but also relative paths, which
+# will be relative from the directory where doxygen is started.
+# This tag requires that the tag FULL_PATH_NAMES is set to YES.
+
+STRIP_FROM_PATH        = $(SRCDIR)
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the
+# path mentioned in the documentation of a class, which tells the reader which
+# header file to include in order to use a class. If left blank only the name of
+# the header file containing the class definition is used. Otherwise one should
+# specify the list of include paths that are normally passed to the compiler
+# using the -I flag.
+
+STRIP_FROM_INC_PATH    =
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but
+# less readable) file names. This can be useful is your file systems doesn't
+# support long names like on DOS, Mac, or CD-ROM.
+# The default value is: NO.
+
+SHORT_NAMES            = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the
+# first line (until the first dot) of a Javadoc-style comment as the brief
+# description. If set to NO, the Javadoc-style will behave just like regular Qt-
+# style comments (thus requiring an explicit @brief command for a brief
+# description.)
+# The default value is: NO.
+
+JAVADOC_AUTOBRIEF      = YES
+
+# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first
+# line (until the first dot) of a Qt-style comment as the brief description. If
+# set to NO, the Qt-style will behave just like regular Qt-style comments (thus
+# requiring an explicit \brief command for a brief description.)
+# The default value is: NO.
+
+QT_AUTOBRIEF           = YES
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a
+# multi-line C++ special comment block (i.e. a block of //! or /// comments) as
+# a brief description. This used to be the default behavior. The new default is
+# to treat a multi-line C++ comment block as a detailed description. Set this
+# tag to YES if you prefer the old behavior instead.
+#
+# Note that setting this tag to YES also means that rational rose comments are
+# not recognized any more.
+# The default value is: NO.
+
+MULTILINE_CPP_IS_BRIEF = YES
+
+# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the
+# documentation from any documented member that it re-implements.
+# The default value is: YES.
+
+INHERIT_DOCS           = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce a
+# new page for each member. If set to NO, the documentation of a member will be
+# part of the file/class/namespace that contains it.
+# The default value is: NO.
+
+SEPARATE_MEMBER_PAGES  = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen
+# uses this value to replace tabs by spaces in code fragments.
+# Minimum value: 1, maximum value: 16, default value: 4.
+
+TAB_SIZE               = 4
+
+# This tag can be used to specify a number of aliases that act as commands in
+# the documentation. An alias has the form:
+# name=value
+# For example adding
+# "sideeffect=@par Side Effects:\n"
+# will allow you to put the command \sideeffect (or @sideeffect) in the
+# documentation, which will result in a user-defined paragraph with heading
+# "Side Effects:". You can put \n's in the value part of an alias to insert
+# newlines.
+
+ALIASES                =
+
+# This tag can be used to specify a number of word-keyword mappings (TCL only).
+# A mapping has the form "name=value". For example adding "class=itcl::class"
+# will allow you to use the command class in the itcl::class meaning.
+
+TCL_SUBST              =
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
+# only. Doxygen will then generate output that is more tailored for C. For
+# instance, some of the names that are used will be different. The list of all
+# members will be omitted, etc.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_FOR_C  = YES
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or
+# Python sources only. Doxygen will then generate output that is more tailored
+# for that language. For instance, namespaces will be presented as packages,
+# qualified scopes will look different, etc.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_JAVA   = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
+# sources. Doxygen will then generate output that is tailored for Fortran.
+# The default value is: NO.
+
+OPTIMIZE_FOR_FORTRAN   = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
+# sources. Doxygen will then generate output that is tailored for VHDL.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_VHDL   = NO
+
+# Doxygen selects the parser to use depending on the extension of the files it
+# parses. With this tag you can assign which parser to use for a given
+# extension. Doxygen has a built-in mapping, but you can override or extend it
+# using this tag. The format is ext=language, where ext is a file extension, and
+# language is one of the parsers supported by doxygen: IDL, Java, Javascript,
+# C#, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL. For instance to make
+# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C
+# (default is Fortran), use: inc=Fortran f=C.
+#
+# Note For files without extension you can use no_extension as a placeholder.
+#
+# Note that for custom extensions you also need to set FILE_PATTERNS otherwise
+# the files are not read by doxygen.
+
+EXTENSION_MAPPING      =
+
+# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments
+# according to the Markdown format, which allows for more readable
+# documentation. See http://daringfireball.net/projects/markdown/ for details.
+# The output of markdown processing is further processed by doxygen, so you can
+# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in
+# case of backward compatibilities issues.
+# The default value is: YES.
+
+MARKDOWN_SUPPORT       = YES
+
+# When enabled doxygen tries to link words that correspond to documented
+# classes, or namespaces to their corresponding documentation. Such a link can
+# be prevented in individual cases by by putting a % sign in front of the word
+# or globally by setting AUTOLINK_SUPPORT to NO.
+# The default value is: YES.
+
+AUTOLINK_SUPPORT       = YES
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
+# to include (a tag file for) the STL sources as input, then you should set this
+# tag to YES in order to let doxygen match functions declarations and
+# definitions whose arguments contain STL classes (e.g. func(std::string);
+# versus func(std::string) {}). This also make the inheritance and collaboration
+# diagrams that involve STL classes more complete and accurate.
+# The default value is: NO.
+
+BUILTIN_STL_SUPPORT    = NO
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+# The default value is: NO.
+
+CPP_CLI_SUPPORT        = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip (see:
+# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen
+# will parse them like normal C++ but will assume all classes use public instead
+# of private inheritance when no explicit protection keyword is present.
+# The default value is: NO.
+
+SIP_SUPPORT            = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate
+# getter and setter methods for a property. Setting this option to YES will make
+# doxygen to replace the get and set methods by a property in the documentation.
+# This will only work if the methods are indeed getting or setting a simple
+# type. If this is not the case, or you want to show the methods anyway, you
+# should set this option to NO.
+# The default value is: YES.
+
+IDL_PROPERTY_SUPPORT   = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES, then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+# The default value is: NO.
+
+DISTRIBUTE_GROUP_DOC   = NO
+
+# Set the SUBGROUPING tag to YES to allow class member groups of the same type
+# (for instance a group of public functions) to be put as a subgroup of that
+# type (e.g. under the Public Functions section). Set it to NO to prevent
+# subgrouping. Alternatively, this can be done per class using the
+# \nosubgrouping command.
+# The default value is: YES.
+
+SUBGROUPING            = YES
+
+# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions
+# are shown inside the group in which they are included (e.g. using \ingroup)
+# instead of on a separate page (for HTML and Man pages) or section (for LaTeX
+# and RTF).
+#
+# Note that this feature does not work in combination with
+# SEPARATE_MEMBER_PAGES.
+# The default value is: NO.
+
+INLINE_GROUPED_CLASSES = NO
+
+# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions
+# with only public data fields or simple typedef fields will be shown inline in
+# the documentation of the scope in which they are defined (i.e. file,
+# namespace, or group documentation), provided this scope is documented. If set
+# to NO, structs, classes, and unions are shown on a separate page (for HTML and
+# Man pages) or section (for LaTeX and RTF).
+# The default value is: NO.
+
+INLINE_SIMPLE_STRUCTS  = NO
+
+# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or
+# enum is documented as struct, union, or enum with the name of the typedef. So
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
+# with name TypeT. When disabled the typedef will appear as a member of a file,
+# namespace, or class. And the struct will be named TypeS. This can typically be
+# useful for C code in case the coding convention dictates that all compound
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+# The default value is: NO.
+
+TYPEDEF_HIDES_STRUCT   = NO
+
+# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This
+# cache is used to resolve symbols given their name and scope. Since this can be
+# an expensive process and often the same symbol appears multiple times in the
+# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small
+# doxygen will become slower. If the cache is too large, memory is wasted. The
+# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range
+# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536
+# symbols. At the end of a run doxygen will report the cache usage and suggest
+# the optimal cache size from a speed point of view.
+# Minimum value: 0, maximum value: 9, default value: 0.
+
+LOOKUP_CACHE_SIZE      = 0
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
+# documentation are documented, even if no documentation was available. Private
+# class members and static file members will be hidden unless the
+# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES.
+# Note: This will also disable the warnings about undocumented members that are
+# normally produced when WARNINGS is set to YES.
+# The default value is: NO.
+
+EXTRACT_ALL            = YES
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class will
+# be included in the documentation.
+# The default value is: NO.
+
+EXTRACT_PRIVATE        = YES
+
+# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal
+# scope will be included in the documentation.
+# The default value is: NO.
+
+EXTRACT_PACKAGE        = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file will be
+# included in the documentation.
+# The default value is: NO.
+
+EXTRACT_STATIC         = YES
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) defined
+# locally in source files will be included in the documentation. If set to NO
+# only classes defined in header files are included. Does not have any effect
+# for Java sources.
+# The default value is: YES.
+
+EXTRACT_LOCAL_CLASSES  = YES
+
+# This flag is only useful for Objective-C code. When set to YES local methods,
+# which are defined in the implementation section but not in the interface are
+# included in the documentation. If set to NO only methods in the interface are
+# included.
+# The default value is: NO.
+
+EXTRACT_LOCAL_METHODS  = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be
+# extracted and appear in the documentation as a namespace called
+# 'anonymous_namespace{file}', where file will be replaced with the base name of
+# the file that contains the anonymous namespace. By default anonymous namespace
+# are hidden.
+# The default value is: NO.
+
+EXTRACT_ANON_NSPACES   = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all
+# undocumented members inside documented classes or files. If set to NO these
+# members will be included in the various overviews, but no documentation
+# section is generated. This option has no effect if EXTRACT_ALL is enabled.
+# The default value is: NO.
+
+HIDE_UNDOC_MEMBERS     = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy. If set
+# to NO these classes will be included in the various overviews. This option has
+# no effect if EXTRACT_ALL is enabled.
+# The default value is: NO.
+
+HIDE_UNDOC_CLASSES     = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend
+# (class|struct|union) declarations. If set to NO these declarations will be
+# included in the documentation.
+# The default value is: NO.
+
+HIDE_FRIEND_COMPOUNDS  = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any
+# documentation blocks found inside the body of a function. If set to NO these
+# blocks will be appended to the function's detailed documentation block.
+# The default value is: NO.
+
+HIDE_IN_BODY_DOCS      = NO
+
+# The INTERNAL_DOCS tag determines if documentation that is typed after a
+# \internal command is included. If the tag is set to NO then the documentation
+# will be excluded. Set it to YES to include the internal documentation.
+# The default value is: NO.
+
+INTERNAL_DOCS          = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file
+# names in lower-case letters. If set to YES upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# and Mac users are advised to set this option to NO.
+# The default value is: system dependent.
+
+CASE_SENSE_NAMES       = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with
+# their full class and namespace scopes in the documentation. If set to YES the
+# scope will be hidden.
+# The default value is: NO.
+
+HIDE_SCOPE_NAMES       = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of
+# the files that are included by a file in the documentation of that file.
+# The default value is: YES.
+
+SHOW_INCLUDE_FILES     = YES
+
+# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each
+# grouped member an include statement to the documentation, telling the reader
+# which file to include in order to use the member.
+# The default value is: NO.
+
+SHOW_GROUPED_MEMB_INC  = NO
+
+# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include
+# files with double quotes in the documentation rather than with sharp brackets.
+# The default value is: NO.
+
+FORCE_LOCAL_INCLUDES   = NO
+
+# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the
+# documentation for inline members.
+# The default value is: YES.
+
+INLINE_INFO            = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the
+# (detailed) documentation of file and class members alphabetically by member
+# name. If set to NO the members will appear in declaration order.
+# The default value is: YES.
+
+SORT_MEMBER_DOCS       = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief
+# descriptions of file, namespace and class members alphabetically by member
+# name. If set to NO the members will appear in declaration order. Note that
+# this will also influence the order of the classes in the class list.
+# The default value is: NO.
+
+SORT_BRIEF_DOCS        = NO
+
+# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the
+# (brief and detailed) documentation of class members so that constructors and
+# destructors are listed first. If set to NO the constructors will appear in the
+# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS.
+# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief
+# member documentation.
+# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting
+# detailed member documentation.
+# The default value is: NO.
+
+SORT_MEMBERS_CTORS_1ST = NO
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy
+# of group names into alphabetical order. If set to NO the group names will
+# appear in their defined order.
+# The default value is: NO.
+
+SORT_GROUP_NAMES       = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by
+# fully-qualified names, including namespaces. If set to NO, the class list will
+# be sorted only by class name, not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the alphabetical
+# list.
+# The default value is: NO.
+
+SORT_BY_SCOPE_NAME     = NO
+
+# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper
+# type resolution of all parameters of a function it will reject a match between
+# the prototype and the implementation of a member function even if there is
+# only one candidate or it is obvious which candidate to choose by doing a
+# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still
+# accept a match between prototype and implementation in such cases.
+# The default value is: NO.
+
+STRICT_PROTO_MATCHING  = NO
+
+# The GENERATE_TODOLIST tag can be used to enable ( YES) or disable ( NO) the
+# todo list. This list is created by putting \todo commands in the
+# documentation.
+# The default value is: YES.
+
+GENERATE_TODOLIST      = YES
+
+# The GENERATE_TESTLIST tag can be used to enable ( YES) or disable ( NO) the
+# test list. This list is created by putting \test commands in the
+# documentation.
+# The default value is: YES.
+
+GENERATE_TESTLIST      = YES
+
+# The GENERATE_BUGLIST tag can be used to enable ( YES) or disable ( NO) the bug
+# list. This list is created by putting \bug commands in the documentation.
+# The default value is: YES.
+
+GENERATE_BUGLIST       = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable ( YES) or disable ( NO)
+# the deprecated list. This list is created by putting \deprecated commands in
+# the documentation.
+# The default value is: YES.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional documentation
+# sections, marked by \if <section_label> ... \endif and \cond <section_label>
+# ... \endcond blocks.
+
+ENABLED_SECTIONS       =
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the
+# initial value of a variable or macro / define can have for it to appear in the
+# documentation. If the initializer consists of more lines than specified here
+# it will be hidden. Use a value of 0 to hide initializers completely. The
+# appearance of the value of individual variables and macros / defines can be
+# controlled using \showinitializer or \hideinitializer command in the
+# documentation regardless of this setting.
+# Minimum value: 0, maximum value: 10000, default value: 30.
+
+MAX_INITIALIZER_LINES  = 0
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at
+# the bottom of the documentation of classes and structs. If set to YES the list
+# will mention the files that were used to generate the documentation.
+# The default value is: YES.
+
+SHOW_USED_FILES        = YES
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This
+# will remove the Files entry from the Quick Index and from the Folder Tree View
+# (if specified).
+# The default value is: YES.
+
+SHOW_FILES             = YES
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces
+# page. This will remove the Namespaces entry from the Quick Index and from the
+# Folder Tree View (if specified).
+# The default value is: YES.
+
+SHOW_NAMESPACES        = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically from
+# the version control system). Doxygen will invoke the program by executing (via
+# popen()) the command command input-file, where command is the value of the
+# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided
+# by doxygen. Whatever the program writes to standard output is used as the file
+# version. For an example see the documentation.
+
+FILE_VERSION_FILTER    =
+
+# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
+# by doxygen. The layout file controls the global structure of the generated
+# output files in an output format independent way. To create the layout file
+# that represents doxygen's defaults, run doxygen with the -l option. You can
+# optionally specify a file name after the option, if omitted DoxygenLayout.xml
+# will be used as the name of the layout file.
+#
+# Note that if you run doxygen from a directory containing a file called
+# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE
+# tag is left empty.
+
+LAYOUT_FILE            =
+
+# The CITE_BIB_FILES tag can be used to specify one or more bib files containing
+# the reference definitions. This must be a list of .bib files. The .bib
+# extension is automatically appended if omitted. This requires the bibtex tool
+# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info.
+# For LaTeX the style of the bibliography can be controlled using
+# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the
+# search path. Do not use file names with spaces, bibtex cannot handle them. See
+# also \cite for info how to create references.
+
+CITE_BIB_FILES         =
+
+#---------------------------------------------------------------------------
+# Configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated to
+# standard output by doxygen. If QUIET is set to YES this implies that the
+# messages are off.
+# The default value is: NO.
+
+QUIET                  = YES
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated to standard error ( stderr) by doxygen. If WARNINGS is set to YES
+# this implies that the warnings are on.
+#
+# Tip: Turn warnings on while writing the documentation.
+# The default value is: YES.
+
+WARNINGS               = YES
+
+# If the WARN_IF_UNDOCUMENTED tag is set to YES, then doxygen will generate
+# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag
+# will automatically be disabled.
+# The default value is: YES.
+
+WARN_IF_UNDOCUMENTED   = YES
+
+# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some parameters
+# in a documented function, or documenting parameters that don't exist or using
+# markup commands wrongly.
+# The default value is: YES.
+
+WARN_IF_DOC_ERROR      = YES
+
+# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that
+# are documented, but have no documentation for their parameters or return
+# value. If set to NO doxygen will only warn about wrong or incomplete parameter
+# documentation, but not about the absence of documentation.
+# The default value is: NO.
+
+WARN_NO_PARAMDOC       = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that doxygen
+# can produce. The string should contain the $file, $line, and $text tags, which
+# will be replaced by the file and line number from which the warning originated
+# and the warning text. Optionally the format may contain $version, which will
+# be replaced by the version of the file (if it could be obtained via
+# FILE_VERSION_FILTER)
+# The default value is: $file:$line: $text.
+
+WARN_FORMAT            = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning and error
+# messages should be written. If left blank the output is written to standard
+# error (stderr).
+
+WARN_LOGFILE           =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag is used to specify the files and/or directories that contain
+# documented source files. You may enter file names like myfile.cpp or
+# directories like /usr/src/myproject. Separate the files or directories with
+# spaces.
+# Note: If this tag is empty the current directory is searched.
+
+INPUT                  = $(SRCDIR)
+
+# This tag can be used to specify the character encoding of the source files
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
+# libiconv (or the iconv built into libc) for the transcoding. See the libiconv
+# documentation (see: http://www.gnu.org/software/libiconv) for the list of
+# possible encodings.
+# The default value is: UTF-8.
+
+INPUT_ENCODING         = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and
+# *.h) to filter out the source-files in the directories. If left blank the
+# following patterns are tested:*.c, *.cc, *.cxx, *.cpp, *.c++, *.java, *.ii,
+# *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, *.hh, *.hxx, *.hpp,
+# *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, *.m, *.markdown,
+# *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf,
+# *.qsf, *.as and *.js.
+
+FILE_PATTERNS          =
+
+# The RECURSIVE tag can be used to specify whether or not subdirectories should
+# be searched for input files as well.
+# The default value is: NO.
+
+RECURSIVE              = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should be
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+#
+# Note that relative paths are relative to the directory from which doxygen is
+# run.
+
+EXCLUDE                = $(SRCDIR)/include/factory/factory.h $(SRCDIR)/include/factory/factoryconf.h $(SRCDIR)/old
+
+# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
+# directories that are symbolic links (a Unix file system feature) are excluded
+# from the input.
+# The default value is: NO.
+
+EXCLUDE_SYMLINKS       = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories.
+#
+# Note that the wildcards are matched against the file with absolute path, so to
+# exclude all test directories for example use the pattern */test/*
+
+EXCLUDE_PATTERNS       =
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
+# (namespaces, classes, functions, etc.) that should be excluded from the
+# output. The symbol name can be a fully qualified name, a word, or if the
+# wildcard * is used, a substring. Examples: ANamespace, AClass,
+# AClass::ANamespace, ANamespace::*Test
+#
+# Note that the wildcards are matched against the file with absolute path, so to
+# exclude all test directories use the pattern */test/*
+
+EXCLUDE_SYMBOLS        =
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or directories
+# that contain example code fragments that are included (see the \include
+# command).
+
+EXAMPLE_PATH           = ./..
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and
+# *.h) to filter out the source-files in the directories. If left blank all
+# files are included.
+
+EXAMPLE_PATTERNS       =
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude commands
+# irrespective of the value of the RECURSIVE tag.
+# The default value is: NO.
+
+EXAMPLE_RECURSIVE      = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or directories
+# that contain images that are to be included in the documentation (see the
+# \image command).
+
+IMAGE_PATH             =
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command:
+#
+# <filter> <input-file>
+#
+# where <filter> is the value of the INPUT_FILTER tag, and <input-file> is the
+# name of an input file. Doxygen will then use the output that the filter
+# program writes to standard output. If FILTER_PATTERNS is specified, this tag
+# will be ignored.
+#
+# Note that the filter must not add or remove lines; it is applied before the
+# code is scanned, but not when the output code is generated. If lines are added
+# or removed, the anchors will not be placed correctly.
+
+INPUT_FILTER           =
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis. Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match. The filters are a list of the form: pattern=filter
+# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how
+# filters are used. If the FILTER_PATTERNS tag is empty or if none of the
+# patterns match the file name, INPUT_FILTER is applied.
+
+FILTER_PATTERNS        =
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER ) will also be used to filter the input files that are used for
+# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES).
+# The default value is: NO.
+
+FILTER_SOURCE_FILES    = NO
+
+# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file
+# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and
+# it is also possible to disable source filtering for a specific pattern using
+# *.ext= (so without naming a filter).
+# This tag requires that the tag FILTER_SOURCE_FILES is set to YES.
+
+FILTER_SOURCE_PATTERNS =
+
+# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that
+# is part of the input, its contents will be placed on the main page
+# (index.html). This can be useful if you have a project on for instance GitHub
+# and want to reuse the introduction page also for the doxygen output.
+
+USE_MDFILE_AS_MAINPAGE =
+
+#---------------------------------------------------------------------------
+# Configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will be
+# generated. Documented entities will be cross-referenced with these sources.
+#
+# Note: To get rid of all source code in the generated output, make sure that
+# also VERBATIM_HEADERS is set to NO.
+# The default value is: NO.
+
+SOURCE_BROWSER         = YES
+
+# Setting the INLINE_SOURCES tag to YES will include the body of functions,
+# classes and enums directly into the documentation.
+# The default value is: NO.
+
+INLINE_SOURCES         = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any
+# special comment blocks from generated source code fragments. Normal C, C++ and
+# Fortran comments will always remain visible.
+# The default value is: YES.
+
+STRIP_CODE_COMMENTS    = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES then for each documented
+# function all documented functions referencing it will be listed.
+# The default value is: NO.
+
+REFERENCED_BY_RELATION = YES
+
+# If the REFERENCES_RELATION tag is set to YES then for each documented function
+# all documented entities called/used by that function will be listed.
+# The default value is: NO.
+
+REFERENCES_RELATION    = YES
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set
+# to YES, then the hyperlinks from functions in REFERENCES_RELATION and
+# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will
+# link to the documentation.
+# The default value is: YES.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the
+# source code will show a tooltip with additional information such as prototype,
+# brief description and links to the definition and documentation. Since this
+# will make the HTML file larger and loading of large files a bit slower, you
+# can opt to disable this feature.
+# The default value is: YES.
+# This tag requires that the tag SOURCE_BROWSER is set to YES.
+
+SOURCE_TOOLTIPS        = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code will
+# point to the HTML generated by the htags(1) tool instead of doxygen built-in
+# source browser. The htags tool is part of GNU's global source tagging system
+# (see http://www.gnu.org/software/global/global.html). You will need version
+# 4.8.6 or higher.
+#
+# To use it do the following:
+# - Install the latest version of global
+# - Enable SOURCE_BROWSER and USE_HTAGS in the config file
+# - Make sure the INPUT points to the root of the source tree
+# - Run doxygen as normal
+#
+# Doxygen will invoke htags (and that will in turn invoke gtags), so these
+# tools must be available from the command line (i.e. in the search path).
+#
+# The result: instead of the source browser generated by doxygen, the links to
+# source code will now point to the output of htags.
+# The default value is: NO.
+# This tag requires that the tag SOURCE_BROWSER is set to YES.
+
+USE_HTAGS              = NO
+
+# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a
+# verbatim copy of the header file for each class for which an include is
+# specified. Set to NO to disable this.
+# See also: Section \class.
+# The default value is: YES.
+
+VERBATIM_HEADERS       = YES
+
+#---------------------------------------------------------------------------
+# Configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all
+# compounds will be generated. Enable this if the project contains a lot of
+# classes, structs, unions or interfaces.
+# The default value is: YES.
+
+ALPHABETICAL_INDEX     = YES
+
+# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in
+# which the alphabetical index list will be split.
+# Minimum value: 1, maximum value: 20, default value: 5.
+# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
+
+COLS_IN_ALPHA_INDEX    = 5
+
+# In case all classes in a project start with a common prefix, all classes will
+# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag
+# can be used to specify a prefix (or a list of prefixes) that should be ignored
+# while generating the index headers.
+# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
+
+IGNORE_PREFIX          =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES doxygen will generate HTML output
+# The default value is: YES.
+
+GENERATE_HTML          = $(GENERATE_HTML)
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: html.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_OUTPUT            = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each
+# generated HTML page (for example: .htm, .php, .asp).
+# The default value is: .html.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_FILE_EXTENSION    = .html
+
+# The HTML_HEADER tag can be used to specify a user-defined HTML header file for
+# each generated HTML page. If the tag is left blank doxygen will generate a
+# standard header.
+#
+# To get valid HTML the header file that includes any scripts and style sheets
+# that doxygen needs, which is dependent on the configuration options used (e.g.
+# the setting GENERATE_TREEVIEW). It is highly recommended to start with a
+# default header using
+# doxygen -w html new_header.html new_footer.html new_stylesheet.css
+# YourConfigFile
+# and then modify the file new_header.html. See also section "Doxygen usage"
+# for information on how to generate the default header that doxygen normally
+# uses.
+# Note: The header is subject to change so you typically have to regenerate the
+# default header when upgrading to a newer version of doxygen. For a description
+# of the possible markers and block names see the documentation.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_HEADER            =
+
+# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each
+# generated HTML page. If the tag is left blank doxygen will generate a standard
+# footer. See HTML_HEADER for more information on how to generate a default
+# footer and what special commands can be used inside the footer. See also
+# section "Doxygen usage" for information on how to generate the default footer
+# that doxygen normally uses.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_FOOTER            =
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style
+# sheet that is used by each HTML page. It can be used to fine-tune the look of
+# the HTML output. If left blank doxygen will generate a default style sheet.
+# See also section "Doxygen usage" for information on how to generate the style
+# sheet that doxygen normally uses.
+# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as
+# it is more robust and this tag (HTML_STYLESHEET) will in the future become
+# obsolete.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_STYLESHEET        =
+
+# The HTML_EXTRA_STYLESHEET tag can be used to specify an additional user-
+# defined cascading style sheet that is included after the standard style sheets
+# created by doxygen. Using this option one can overrule certain style aspects.
+# This is preferred over using HTML_STYLESHEET since it does not replace the
+# standard style sheet and is therefor more robust against future updates.
+# Doxygen will copy the style sheet file to the output directory. For an example
+# see the documentation.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_EXTRA_STYLESHEET  =
+
+# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the HTML output directory. Note
+# that these files will be copied to the base HTML output directory. Use the
+# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
+# files. In the HTML_STYLESHEET file, use the file name only. Also note that the
+# files will be copied as-is; there are no commands or markers available.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_EXTRA_FILES       =
+
+# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
+# will adjust the colors in the stylesheet and background images according to
+# this color. Hue is specified as an angle on a colorwheel, see
+# http://en.wikipedia.org/wiki/Hue for more information. For instance the value
+# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300
+# purple, and 360 is red again.
+# Minimum value: 0, maximum value: 359, default value: 220.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_HUE    = 220
+
+# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors
+# in the HTML output. For a value of 0 the output will use grayscales only. A
+# value of 255 will produce the most vivid colors.
+# Minimum value: 0, maximum value: 255, default value: 100.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_SAT    = 100
+
+# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the
+# luminance component of the colors in the HTML output. Values below 100
+# gradually make the output lighter, whereas values above 100 make the output
+# darker. The value divided by 100 is the actual gamma applied, so 80 represents
+# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not
+# change the gamma.
+# Minimum value: 40, maximum value: 240, default value: 80.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_GAMMA  = 80
+
+# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
+# page will contain the date and time when the page was generated. Setting this
+# to NO can help when comparing the output of multiple runs.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_TIMESTAMP         = YES
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
+# documentation will contain sections that can be hidden and shown after the
+# page has loaded.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_DYNAMIC_SECTIONS  = NO
+
+# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries
+# shown in the various tree structured indices initially; the user can expand
+# and collapse entries dynamically later on. Doxygen will expand the tree to
+# such a level that at most the specified number of entries are visible (unless
+# a fully collapsed tree already exceeds this amount). So setting the number of
+# entries 1 will produce a full collapsed tree by default. 0 is a special value
+# representing an infinite number of entries and will result in a full expanded
+# tree by default.
+# Minimum value: 0, maximum value: 9999, default value: 100.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_INDEX_NUM_ENTRIES = 100
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files will be
+# generated that can be used as input for Apple's Xcode 3 integrated development
+# environment (see: http://developer.apple.com/tools/xcode/), introduced with
+# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a
+# Makefile in the HTML output directory. Running make will produce the docset in
+# that directory and running make install will install the docset in
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at
+# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
+# for more information.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_DOCSET        = NO
+
+# This tag determines the name of the docset feed. A documentation feed provides
+# an umbrella under which multiple documentation sets from a single provider
+# (such as a company or product suite) can be grouped.
+# The default value is: Doxygen generated docs.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_FEEDNAME        = "Doxygen generated docs"
+
+# This tag specifies a string that should uniquely identify the documentation
+# set bundle. This should be a reverse domain-name style string, e.g.
+# com.mycompany.MyDocSet. Doxygen will append .docset to the name.
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_BUNDLE_ID       = org.doxygen.Project
+
+# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify
+# the documentation publisher. This should be a reverse domain-name style
+# string, e.g. com.mycompany.MyDocSet.documentation.
+# The default value is: org.doxygen.Publisher.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_PUBLISHER_ID    = org.doxygen.Publisher
+
+# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher.
+# The default value is: Publisher.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_PUBLISHER_NAME  = Publisher
+
+# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three
+# additional HTML index files: index.hhp, index.hhc, and index.hhk. The
+# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop
+# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on
+# Windows.
+#
+# The HTML Help Workshop contains a compiler that can convert all HTML output
+# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML
+# files are now used as the Windows 98 help format, and will replace the old
+# Windows help format (.hlp) on all Windows platforms in the future. Compressed
+# HTML files also contain an index, a table of contents, and you can search for
+# words in the documentation. The HTML workshop also contains a viewer for
+# compressed HTML files.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_HTMLHELP      = $(GENERATE_HTMLHELP)
+
+# The CHM_FILE tag can be used to specify the file name of the resulting .chm
+# file. You can add a path in front of the file if the result should not be
+# written to the html output directory.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+CHM_FILE               = ../$(PROJECT).chm
+
+# The HHC_LOCATION tag can be used to specify the location (absolute path
+# including file name) of the HTML help compiler ( hhc.exe). If non-empty
+# doxygen will try to run the HTML help compiler on the generated index.hhp.
+# The file has to be specified with full path.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+HHC_LOCATION           = $(HHC_PATH)
+
+# The GENERATE_CHI flag controls if a separate .chi index file is generated (
+# YES) or that it should be included in the master .chm file ( NO).
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+GENERATE_CHI           = $(GENERATE_CHI)
+
+# The CHM_INDEX_ENCODING is used to encode HtmlHelp index ( hhk), content ( hhc)
+# and project file content.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+CHM_INDEX_ENCODING     =
+
+# The BINARY_TOC flag controls whether a binary table of contents is generated (
+# YES) or a normal table of contents ( NO) in the .chm file.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+BINARY_TOC             = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members to
+# the table of contents of the HTML help documentation and to the tree view.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+TOC_EXPAND             = YES
+
+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
+# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that
+# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help
+# (.qch) of the generated HTML documentation.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_QHP           = NO
+
+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify
+# the file name of the resulting .qch file. The path specified is relative to
+# the HTML output folder.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QCH_FILE               =
+
+# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help
+# Project output. For more information please see Qt Help Project / Namespace
+# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace).
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_NAMESPACE          = org.doxygen.Project
+
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt
+# Help Project output. For more information please see Qt Help Project / Virtual
+# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual-
+# folders).
+# The default value is: doc.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_VIRTUAL_FOLDER     = doc
+
+# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom
+# filter to add. For more information please see Qt Help Project / Custom
+# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
+# filters).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_CUST_FILTER_NAME   =
+
+# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the
+# custom filter to add. For more information please see Qt Help Project / Custom
+# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
+# filters).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_CUST_FILTER_ATTRS  =
+
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
+# project's filter section matches. Qt Help Project / Filter Attributes (see:
+# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_SECT_FILTER_ATTRS  =
+
+# The QHG_LOCATION tag can be used to specify the location of Qt's
+# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the
+# generated .qhp file.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHG_LOCATION           =
+
+# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be
+# generated, together with the HTML files, they form an Eclipse help plugin. To
+# install this plugin and make it available under the help contents menu in
+# Eclipse, the contents of the directory containing the HTML and XML files needs
+# to be copied into the plugins directory of eclipse. The name of the directory
+# within the plugins directory should be the same as the ECLIPSE_DOC_ID value.
+# After copying Eclipse needs to be restarted before the help appears.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_ECLIPSEHELP   = NO
+
+# A unique identifier for the Eclipse help plugin. When installing the plugin
+# the directory name containing the HTML and XML files should also have this
+# name. Each documentation set should have its own identifier.
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES.
+
+ECLIPSE_DOC_ID         = org.doxygen.Project
+
+# If you want full control over the layout of the generated HTML pages it might
+# be necessary to disable the index and replace it with your own. The
+# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top
+# of each HTML page. A value of NO enables the index and the value YES disables
+# it. Since the tabs in the index contain the same information as the navigation
+# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+DISABLE_INDEX          = NO
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
+# structure should be generated to display hierarchical information. If the tag
+# value is set to YES, a side panel will be generated containing a tree-like
+# index structure (just like the one that is generated for HTML Help). For this
+# to work a browser that supports JavaScript, DHTML, CSS and frames is required
+# (i.e. any modern browser). Windows users are probably better off using the
+# HTML help feature. Via custom stylesheets (see HTML_EXTRA_STYLESHEET) one can
+# further fine-tune the look of the index. As an example, the default style
+# sheet generated by doxygen has an example that shows how to put an image at
+# the root of the tree instead of the PROJECT_NAME. Since the tree basically has
+# the same information as the tab index, you could consider setting
+# DISABLE_INDEX to YES when enabling this option.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_TREEVIEW      = YES
+
+# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that
+# doxygen will group on one line in the generated HTML documentation.
+#
+# Note that a value of 0 will completely suppress the enum values from appearing
+# in the overview section.
+# Minimum value: 0, maximum value: 20, default value: 4.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+ENUM_VALUES_PER_LINE   = 4
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used
+# to set the initial width (in pixels) of the frame in which the tree is shown.
+# Minimum value: 0, maximum value: 1500, default value: 250.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+TREEVIEW_WIDTH         = 250
+
+# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open links to
+# external symbols imported via tag files in a separate window.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+EXT_LINKS_IN_WINDOW    = NO
+
+# Use this tag to change the font size of LaTeX formulas included as images in
+# the HTML documentation. When you change the font size after a successful
+# doxygen run you need to manually remove any form_*.png images from the HTML
+# output directory to force them to be regenerated.
+# Minimum value: 8, maximum value: 50, default value: 10.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+FORMULA_FONTSIZE       = 10
+
+# Use the FORMULA_TRANPARENT tag to determine whether or not the images
+# generated for formulas are transparent PNGs. Transparent PNGs are not
+# supported properly for IE 6.0, but are supported on all modern browsers.
+#
+# Note that when changing this option you need to delete any form_*.png files in
+# the HTML output directory before the changes have effect.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+FORMULA_TRANSPARENT    = YES
+
+# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see
+# http://www.mathjax.org) which uses client side Javascript for the rendering
+# instead of using prerendered bitmaps. Use this if you do not have LaTeX
+# installed or if you want to formulas look prettier in the HTML output. When
+# enabled you may also need to install MathJax separately and configure the path
+# to it using the MATHJAX_RELPATH option.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+USE_MATHJAX            = NO
+
+# When MathJax is enabled you can set the default output format to be used for
+# the MathJax output. See the MathJax site (see:
+# http://docs.mathjax.org/en/latest/output.html) for more details.
+# Possible values are: HTML-CSS (which is slower, but has the best
+# compatibility), NativeMML (i.e. MathML) and SVG.
+# The default value is: HTML-CSS.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_FORMAT         = HTML-CSS
+
+# When MathJax is enabled you need to specify the location relative to the HTML
+# output directory using the MATHJAX_RELPATH option. The destination directory
+# should contain the MathJax.js script. For instance, if the mathjax directory
+# is located at the same level as the HTML output directory, then
+# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax
+# Content Delivery Network so you can quickly see the result without installing
+# MathJax. However, it is strongly recommended to install a local copy of
+# MathJax from http://www.mathjax.org before deployment.
+# The default value is: http://cdn.mathjax.org/mathjax/latest.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_RELPATH        = http://cdn.mathjax.org/mathjax/latest
+
+# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax
+# extension names that should be enabled during MathJax rendering. For example
+# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_EXTENSIONS     =
+
+# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces
+# of code that will be used on startup of the MathJax code. See the MathJax site
+# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an
+# example see the documentation.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_CODEFILE       =
+
+# When the SEARCHENGINE tag is enabled doxygen will generate a search box for
+# the HTML output. The underlying search engine uses javascript and DHTML and
+# should work on any modern browser. Note that when using HTML help
+# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET)
+# there is already a search function so this one should typically be disabled.
+# For large projects the javascript based search engine can be slow, then
+# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to
+# search using the keyboard; to jump to the search box use <access key> + S
+# (what the <access key> is depends on the OS and browser, but it is typically
+# <CTRL>, <ALT>/<option>, or both). Inside the search box use the <cursor down
+# key> to jump into the search results window, the results can be navigated
+# using the <cursor keys>. Press <Enter> to select an item or <escape> to cancel
+# the search. The filter options can be selected when the cursor is inside the
+# search box by pressing <Shift>+<cursor down>. Also here use the <cursor keys>
+# to select a filter and <Enter> or <escape> to activate or cancel the filter
+# option.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+SEARCHENGINE           = NO
+
+# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
+# implemented using a web server instead of a web client using Javascript. There
+# are two flavours of web server based searching depending on the
+# EXTERNAL_SEARCH setting. When disabled, doxygen will generate a PHP script for
+# searching and an index file used by the script. When EXTERNAL_SEARCH is
+# enabled the indexing and searching needs to be provided by external tools. See
+# the section "External Indexing and Searching" for details.
+# The default value is: NO.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SERVER_BASED_SEARCH    = NO
+
+# When EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP
+# script for searching. Instead the search results are written to an XML file
+# which needs to be processed by an external indexer. Doxygen will invoke an
+# external search engine pointed to by the SEARCHENGINE_URL option to obtain the
+# search results.
+#
+# Doxygen ships with an example indexer ( doxyindexer) and search engine
+# (doxysearch.cgi) which are based on the open source search engine library
+# Xapian (see: http://xapian.org/).
+#
+# See the section "External Indexing and Searching" for details.
+# The default value is: NO.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTERNAL_SEARCH        = NO
+
+# The SEARCHENGINE_URL should point to a search engine hosted by a web server
+# which will return the search results when EXTERNAL_SEARCH is enabled.
+#
+# Doxygen ships with an example indexer ( doxyindexer) and search engine
+# (doxysearch.cgi) which are based on the open source search engine library
+# Xapian (see: http://xapian.org/). See the section "External Indexing and
+# Searching" for details.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SEARCHENGINE_URL       =
+
+# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed
+# search data is written to a file for indexing by an external tool. With the
+# SEARCHDATA_FILE tag the name of this file can be specified.
+# The default file is: searchdata.xml.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SEARCHDATA_FILE        = searchdata.xml
+
+# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the
+# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is
+# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple
+# projects and redirect the results back to the right project.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTERNAL_SEARCH_ID     =
+
+# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen
+# projects other than the one defined by this configuration file, but that are
+# all added to the same external search index. Each project needs to have a
+# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id of
+# to a relative location where the documentation can be found. The format is:
+# EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ...
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTRA_SEARCH_MAPPINGS  =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES doxygen will generate LaTeX output.
+# The default value is: YES.
+
+GENERATE_LATEX         = $(GENERATE_LATEX)
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: latex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_OUTPUT           = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked.
+#
+# Note that when enabling USE_PDFLATEX this option is only used for generating
+# bitmaps for formulas in the HTML output, but not in the Makefile that is
+# written to the output directory.
+# The default file is: latex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_CMD_NAME         =
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate
+# index for LaTeX.
+# The default file is: makeindex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+MAKEINDEX_CMD_NAME     =
+
+# If the COMPACT_LATEX tag is set to YES doxygen generates more compact LaTeX
+# documents. This may be useful for small projects and may help to save some
+# trees in general.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+COMPACT_LATEX          = YES
+
+# The PAPER_TYPE tag can be used to set the paper type that is used by the
+# printer.
+# Possible values are: a4 (210 x 297 mm), letter (8.5 x 11 inches), legal (8.5 x
+# 14 inches) and executive (7.25 x 10.5 inches).
+# The default value is: a4.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+PAPER_TYPE             = $(PAPER_SIZE)
+
+# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names
+# that should be included in the LaTeX output. To get the times font for
+# instance you can specify
+# EXTRA_PACKAGES=times
+# If left blank no extra packages will be included.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+EXTRA_PACKAGES         =
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the
+# generated LaTeX document. The header should contain everything until the first
+# chapter. If it is left blank doxygen will generate a standard header. See
+# section "Doxygen usage" for information on how to let doxygen write the
+# default header to a separate file.
+#
+# Note: Only use a user-defined header if you know what you are doing! The
+# following commands have a special meaning inside the header: $title,
+# $datetime, $date, $doxygenversion, $projectname, $projectnumber. Doxygen will
+# replace them by respectively the title of the page, the current date and time,
+# only the current date, the version number of doxygen, the project name (see
+# PROJECT_NAME), or the project number (see PROJECT_NUMBER).
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_HEADER           =
+
+# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the
+# generated LaTeX document. The footer should contain everything after the last
+# chapter. If it is left blank doxygen will generate a standard footer.
+#
+# Note: Only use a user-defined footer if you know what you are doing!
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_FOOTER           =
+
+# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the LATEX_OUTPUT output
+# directory. Note that the files will be copied as-is; there are no commands or
+# markers available.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_EXTRA_FILES      =
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is
+# prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will
+# contain links (just like the HTML output) instead of page references. This
+# makes the output suitable for online browsing using a PDF viewer.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+PDF_HYPERLINKS         = NO
+
+# If the LATEX_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate
+# the PDF file directly from the LaTeX files. Set this option to YES to get a
+# higher quality PDF documentation.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+USE_PDFLATEX           = $(GENERATE_PDF)
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode
+# command to the generated LaTeX files. This will instruct LaTeX to keep running
+# if errors occur, instead of asking the user for help. This option is also used
+# when generating formulas in HTML.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_BATCHMODE        = YES
+
+# If the LATEX_HIDE_INDICES tag is set to YES then doxygen will not include the
+# index chapters (such as File Index, Compound Index, etc.) in the output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_HIDE_INDICES     = NO
+
+# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source
+# code with syntax highlighting in the LaTeX output.
+#
+# Note that which sources are shown also depends on other settings such as
+# SOURCE_BROWSER.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_SOURCE_CODE      = NO
+
+# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
+# bibliography, e.g. plainnat, or ieeetr. See
+# http://en.wikipedia.org/wiki/BibTeX and \cite for more info.
+# The default value is: plain.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_BIB_STYLE        = plain
+
+#---------------------------------------------------------------------------
+# Configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES doxygen will generate RTF output. The
+# RTF output is optimized for Word 97 and may not look too pretty with other RTF
+# readers/editors.
+# The default value is: NO.
+
+GENERATE_RTF           = $(GENERATE_RTF)
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: rtf.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_OUTPUT             = rtf
+
+# If the COMPACT_RTF tag is set to YES doxygen generates more compact RTF
+# documents. This may be useful for small projects and may help to save some
+# trees in general.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+COMPACT_RTF            = YES
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated will
+# contain hyperlink fields. The RTF file will contain links (just like the HTML
+# output) instead of page references. This makes the output suitable for online
+# browsing using Word or some other Word compatible readers that support those
+# fields.
+#
+# Note: WordPad (write) and others do not support links.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_HYPERLINKS         = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's config
+# file, i.e. a series of assignments. You only have to provide replacements,
+# missing definitions are set to their default value.
+#
+# See also section "Doxygen usage" for information on how to generate the
+# default style sheet that doxygen normally uses.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_STYLESHEET_FILE    =
+
+# Set optional variables used in the generation of an RTF document. Syntax is
+# similar to doxygen's config file. A template extensions file can be generated
+# using doxygen -e rtf extensionFile.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_EXTENSIONS_FILE    =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES doxygen will generate man pages for
+# classes and files.
+# The default value is: NO.
+
+GENERATE_MAN           = $(GENERATE_MAN)
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it. A directory man3 will be created inside the directory specified by
+# MAN_OUTPUT.
+# The default directory is: man.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_OUTPUT             = man
+
+# The MAN_EXTENSION tag determines the extension that is added to the generated
+# man pages. In case the manual section does not start with a number, the number
+# 3 is prepended. The dot (.) at the beginning of the MAN_EXTENSION tag is
+# optional.
+# The default value is: .3.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_EXTENSION          = .3
+
+# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it
+# will generate one additional man file for each entity documented in the real
+# man page(s). These additional files only source the real man page, but without
+# them the man command would be unable to find the correct page.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_LINKS              = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES doxygen will generate an XML file that
+# captures the structure of the code including all documentation.
+# The default value is: NO.
+
+GENERATE_XML           = $(GENERATE_XML)
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: xml.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_OUTPUT             = xml
+
+# The XML_SCHEMA tag can be used to specify a XML schema, which can be used by a
+# validating XML parser to check the syntax of the XML files.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_SCHEMA             =
+
+# The XML_DTD tag can be used to specify a XML DTD, which can be used by a
+# validating XML parser to check the syntax of the XML files.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_DTD                =
+
+# If the XML_PROGRAMLISTING tag is set to YES doxygen will dump the program
+# listings (including syntax highlighting and cross-referencing information) to
+# the XML output. Note that enabling this will significantly increase the size
+# of the XML output.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_PROGRAMLISTING     = YES
+
+#---------------------------------------------------------------------------
+# Configuration options related to the DOCBOOK output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_DOCBOOK tag is set to YES doxygen will generate Docbook files
+# that can be used to generate PDF.
+# The default value is: NO.
+
+GENERATE_DOCBOOK       = NO
+
+# The DOCBOOK_OUTPUT tag is used to specify where the Docbook pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in
+# front of it.
+# The default directory is: docbook.
+# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
+
+DOCBOOK_OUTPUT         = docbook
+
+#---------------------------------------------------------------------------
+# Configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES doxygen will generate an AutoGen
+# Definitions (see http://autogen.sf.net) file that captures the structure of
+# the code including all documentation. Note that this feature is still
+# experimental and incomplete at the moment.
+# The default value is: NO.
+
+GENERATE_AUTOGEN_DEF   = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES doxygen will generate a Perl module
+# file that captures the structure of the code including all documentation.
+#
+# Note that this feature is still experimental and incomplete at the moment.
+# The default value is: NO.
+
+GENERATE_PERLMOD       = NO
+
+# If the PERLMOD_LATEX tag is set to YES doxygen will generate the necessary
+# Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI
+# output from the Perl module output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_LATEX          = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be nicely
+# formatted so it can be parsed by a human reader. This is useful if you want to
+# understand what is going on. On the other hand, if this tag is set to NO the
+# size of the Perl module output will be much smaller and Perl will parse it
+# just the same.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_PRETTY         = YES
+
+# The names of the make variables in the generated doxyrules.make file are
+# prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. This is useful
+# so different doxyrules.make files included by the same Makefile don't
+# overwrite each other's variables.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_MAKEVAR_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES doxygen will evaluate all
+# C-preprocessor directives found in the sources and include files.
+# The default value is: YES.
+
+ENABLE_PREPROCESSING   = NO
+
+# If the MACRO_EXPANSION tag is set to YES doxygen will expand all macro names
+# in the source code. If set to NO only conditional compilation will be
+# performed. Macro expansion can be done in a controlled way by setting
+# EXPAND_ONLY_PREDEF to YES.
+# The default value is: NO.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+MACRO_EXPANSION        = YES
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then
+# the macro expansion is limited to the macros specified with the PREDEFINED and
+# EXPAND_AS_DEFINED tags.
+# The default value is: NO.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+EXPAND_ONLY_PREDEF     = YES
+
+# If the SEARCH_INCLUDES tag is set to YES the includes files in the
+# INCLUDE_PATH will be searched if a #include is found.
+# The default value is: YES.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+SEARCH_INCLUDES        = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by the
+# preprocessor.
+# This tag requires that the tag SEARCH_INCLUDES is set to YES.
+
+INCLUDE_PATH           = .
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will be
+# used.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+INCLUDE_FILE_PATTERNS  =
+
+# The PREDEFINED tag can be used to specify one or more macro names that are
+# defined before the preprocessor is started (similar to the -D option of e.g.
+# gcc). The argument of the tag is a list of macros of the form: name or
+# name=definition (no spaces). If the definition and the "=" are omitted, "=1"
+# is assumed. To prevent a macro definition from being undefined via #undef or
+# recursively expanded use the := operator instead of the = operator.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+PREDEFINED             = _DOXYGEN
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
+# tag can be used to specify a list of macro names that should be expanded. The
+# macro definition that is found in the sources will be used. Use the PREDEFINED
+# tag if you want to use a different macro definition that overrules the
+# definition found in the source code.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+EXPAND_AS_DEFINED      = EASY_TYPE \
+                         EASY_DESTRUCTOR \
+                         EASY_METHOD
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will
+# remove all refrences to function-like macros that are alone on a line, have an
+# all uppercase name, and do not end with a semicolon. Such function macros are
+# typically used for boiler-plate code, and will confuse the parser if not
+# removed.
+# The default value is: YES.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+SKIP_FUNCTION_MACROS   = YES
+
+#---------------------------------------------------------------------------
+# Configuration options related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES tag can be used to specify one or more tag files. For each tag
+# file the location of the external documentation should be added. The format of
+# a tag file without this location is as follows:
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where loc1 and loc2 can be relative or absolute paths or URLs. See the
+# section "Linking to external documentation" for more information about the use
+# of tag files.
+# Note: Each tag file must have an unique name (where the name does NOT include
+# the path). If a tag file is not located in the directory in which doxygen is
+# run, you must also specify the path to the tagfile here.
+
+TAGFILES               =
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create a
+# tag file that is based on the input files it reads. See section "Linking to
+# external documentation" for more information about the usage of tag files.
+
+GENERATE_TAGFILE       = $(DOCDIR)/$(PROJECT).tag
+
+# If the ALLEXTERNALS tag is set to YES all external class will be listed in the
+# class index. If set to NO only the inherited external classes will be listed.
+# The default value is: NO.
+
+ALLEXTERNALS           = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed in
+# the modules index. If set to NO, only the current project's groups will be
+# listed.
+# The default value is: YES.
+
+EXTERNAL_GROUPS        = YES
+
+# If the EXTERNAL_PAGES tag is set to YES all external pages will be listed in
+# the related pages index. If set to NO, only the current project's pages will
+# be listed.
+# The default value is: YES.
+
+EXTERNAL_PAGES         = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of 'which perl').
+# The default file (with absolute path) is: /usr/bin/perl.
+
+PERL_PATH              = /usr/bin/false
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES doxygen will generate a class diagram
+# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to
+# NO turns the diagrams off. Note that this option also works with HAVE_DOT
+# disabled, but it is recommended to install and use dot, since it yields more
+# powerful graphs.
+# The default value is: YES.
+
+CLASS_DIAGRAMS         = YES
+
+# You can define message sequence charts within doxygen comments using the \msc
+# command. Doxygen will then run the mscgen tool (see:
+# http://www.mcternan.me.uk/mscgen/)) to produce the chart and insert it in the
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where
+# the mscgen tool resides. If left empty the tool is assumed to be found in the
+# default search path.
+
+MSCGEN_PATH            =
+
+# You can include diagrams made with dia in doxygen documentation. Doxygen will
+# then run dia to produce the diagram and insert it in the documentation. The
+# DIA_PATH tag allows you to specify the directory where the dia binary resides.
+# If left empty dia is assumed to be found in the default search path.
+
+DIA_PATH               =
+
+# If set to YES, the inheritance and collaboration graphs will hide inheritance
+# and usage relations if the target is undocumented or is not a class.
+# The default value is: YES.
+
+HIDE_UNDOC_RELATIONS   = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz (see:
+# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent
+# Bell Labs. The other options in this section have no effect if this option is
+# set to NO
+# The default value is: NO.
+
+HAVE_DOT               = $(HAVE_DOT)
+
+# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed
+# to run in parallel. When set to 0 doxygen will base this on the number of
+# processors available in the system. You can set it explicitly to a value
+# larger than 0 to get control over the balance between CPU load and processing
+# speed.
+# Minimum value: 0, maximum value: 32, default value: 0.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_NUM_THREADS        = 0
+
+# When you want a differently looking font n the dot files that doxygen
+# generates you can specify the font name using DOT_FONTNAME. You need to make
+# sure dot is able to find the font, which can be done by putting it in a
+# standard location or by setting the DOTFONTPATH environment variable or by
+# setting DOT_FONTPATH to the directory containing the font.
+# The default value is: Helvetica.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTNAME           = Helvetica
+
+# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of
+# dot graphs.
+# Minimum value: 4, maximum value: 24, default value: 10.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTSIZE           = 10
+
+# By default doxygen will tell dot to use the default font as specified with
+# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set
+# the path where dot can find it using this tag.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTPATH           =
+
+# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for
+# each documented class showing the direct and indirect inheritance relations.
+# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CLASS_GRAPH            = YES
+
+# If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a
+# graph for each documented class showing the direct and indirect implementation
+# dependencies (inheritance, containment, and class references variables) of the
+# class with other documented classes.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+COLLABORATION_GRAPH    = YES
+
+# If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for
+# groups, showing the direct groups dependencies.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GROUP_GRAPHS           = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+UML_LOOK               = NO
+
+# If the UML_LOOK tag is enabled, the fields and methods are shown inside the
+# class node. If there are many fields or methods and many nodes the graph may
+# become too big to be useful. The UML_LIMIT_NUM_FIELDS threshold limits the
+# number of items for each type to make the size more manageable. Set this to 0
+# for no limit. Note that the threshold may be exceeded by 50% before the limit
+# is enforced. So when you set the threshold to 10, up to 15 fields may appear,
+# but if the number exceeds 15, the total amount of fields shown is limited to
+# 10.
+# Minimum value: 0, maximum value: 100, default value: 10.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+UML_LIMIT_NUM_FIELDS   = 10
+
+# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and
+# collaboration graphs will show the relations between templates and their
+# instances.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+TEMPLATE_RELATIONS     = YES
+
+# If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to
+# YES then doxygen will generate a graph for each documented file showing the
+# direct and indirect include dependencies of the file with other documented
+# files.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INCLUDE_GRAPH          = YES
+
+# If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are
+# set to YES then doxygen will generate a graph for each documented file showing
+# the direct and indirect include dependencies of the file with other documented
+# files.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INCLUDED_BY_GRAPH      = YES
+
+# If the CALL_GRAPH tag is set to YES then doxygen will generate a call
+# dependency graph for every global function or class method.
+#
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable call graphs for selected
+# functions only using the \callgraph command.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CALL_GRAPH             = NO
+
+# If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller
+# dependency graph for every global function or class method.
+#
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable caller graphs for selected
+# functions only using the \callergraph command.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CALLER_GRAPH           = NO
+
+# If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical
+# hierarchy of all classes instead of a textual one.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GRAPHICAL_HIERARCHY    = YES
+
+# If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the
+# dependencies a directory has on other directories in a graphical way. The
+# dependency relations are determined by the #include relations between the
+# files in the directories.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DIRECTORY_GRAPH        = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot.
+# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order
+# to make the SVG files visible in IE 9+ (other browsers do not have this
+# requirement).
+# Possible values are: png, jpg, gif and svg.
+# The default value is: png.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_IMAGE_FORMAT       = png
+
+# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to
+# enable generation of interactive SVG images that allow zooming and panning.
+#
+# Note that this requires a modern browser other than Internet Explorer. Tested
+# and working are Firefox, Chrome, Safari, and Opera.
+# Note: For IE 9+ you need to set HTML_FILE_EXTENSION to xhtml in order to make
+# the SVG files visible. Older versions of IE do not have SVG support.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INTERACTIVE_SVG        = NO
+
+# The DOT_PATH tag can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found in the path.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_PATH               = $(DOT_PATH)
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the \dotfile
+# command).
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOTFILE_DIRS           =
+
+# The MSCFILE_DIRS tag can be used to specify one or more directories that
+# contain msc files that are included in the documentation (see the \mscfile
+# command).
+
+MSCFILE_DIRS           =
+
+# The DIAFILE_DIRS tag can be used to specify one or more directories that
+# contain dia files that are included in the documentation (see the \diafile
+# command).
+
+DIAFILE_DIRS           =
+
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes
+# that will be shown in the graph. If the number of nodes in a graph becomes
+# larger than this value, doxygen will truncate the graph, which is visualized
+# by representing a node as a red box. Note that doxygen if the number of direct
+# children of the root node in a graph is already larger than
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note that
+# the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+# Minimum value: 0, maximum value: 10000, default value: 50.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_GRAPH_MAX_NODES    = 50
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the graphs
+# generated by dot. A depth value of 3 means that only nodes reachable from the
+# root by following a path via at most 3 edges will be shown. Nodes that lay
+# further from the root node will be omitted. Note that setting this option to 1
+# or 2 may greatly reduce the computation time needed for large code bases. Also
+# note that the size of a graph can be further restricted by
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+# Minimum value: 0, maximum value: 1000, default value: 0.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+MAX_DOT_GRAPH_DEPTH    = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
+# background. This is disabled by default, because dot on Windows does not seem
+# to support this out of the box.
+#
+# Warning: Depending on the platform used, enabling this option may lead to
+# badly anti-aliased labels on the edges of a graph (i.e. they become hard to
+# read).
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_TRANSPARENT        = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
+# files in one run (i.e. multiple -o and -T options on the command line). This
+# makes dot run faster, but since only newer versions of dot (>1.8.10) support
+# this, this feature is disabled by default.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_MULTI_TARGETS      = YES
+
+# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page
+# explaining the meaning of the various boxes and arrows in the dot generated
+# graphs.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GENERATE_LEGEND        = YES
+
+# If the DOT_CLEANUP tag is set to YES doxygen will remove the intermediate dot
+# files that are used to generate the various graphs.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_CLEANUP            = YES
diff --git a/factory/examples/application.cc b/factory/examples/application.cc
new file mode 100644
index 0000000..f6cee57
--- /dev/null
+++ b/factory/examples/application.cc
@@ -0,0 +1,55 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+//{{{ docu
+//
+// application.cc - sample Factory application.
+//
+//}}}
+
+#include <factory.h>
+#include <iostream.h>
+
+int
+main()
+{
+    Variable x( 'x' );
+    Variable y( 'y' );
+    Variable z( 'z' );
+    CanonicalForm f;
+    CanonicalForm g;
+
+    cout << "Do not forget to terminate canonical forms with `;' in input!" << endl;
+
+    // set our ring
+    setCharacteristic( 0 );
+    On( SW_RATIONAL );
+
+    cout << "Simple polynomial operations in characteristic 0." << endl;
+    cout << "Please enter two multivariate polynomials over Q." << endl;
+    cout << "f(x, y, z) = ";
+    cin >> f;
+    cout << "g(x, y, z) = ";
+    cin >> g;
+    cout << "f                = " << f << endl;
+    cout << "g                = " << g << endl;
+
+    // call some of Factory's functions and methods and print
+    // their results
+    cout << "Polynomial information on f:" << endl;
+    cout << "mvar(f)          = " << mvar( f ) << endl;
+    cout << "degree(f)        = " << degree( f ) << endl;
+    cout << "degree(f, x)     = " << degree( f, x ) << endl;
+    cout << "degree(f, y)     = " << degree( f, y ) << endl;
+    cout << "degree(f, z)     = " << degree( f, z ) << endl;
+    cout << "LC(f, x)         = " << LC( f, x ) << endl;
+    cout << "LC(f, y)         = " << LC( f, y ) << endl;
+    cout << "LC(f, z)         = " << LC( f, z ) << endl;
+
+    cout << "Arithmetic operators:" << endl;
+    cout << "f+g              = " << f + g << endl;
+    cout << "f-g              = " << f - g << endl;
+    cout << "f*g              = " << f * g << endl;
+    cout << "f/g              = " << f / g << endl;
+    cout << "f%g              = " << f % g << endl;
+    cout << "f(g, x)          = " << f(g, x) << endl;
+}
diff --git a/factory/examples/factorize.cc b/factory/examples/factorize.cc
new file mode 100644
index 0000000..c0a4891
--- /dev/null
+++ b/factory/examples/factorize.cc
@@ -0,0 +1,36 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+//{{{ docu
+//
+// factorize.cc - sample Factory application.
+//
+//}}}
+
+#include <factory.h>
+
+int
+main()
+{
+    Variable x( 'x' );
+    Variable y( 'y' );
+    Variable z( 'z' );
+    CanonicalForm f;
+
+    cout << "Do not forget to terminate canonical forms with `;' in input!" << endl;
+
+    setCharacteristic( 0 );
+    cout << "Multivariate factorization in characteristic 0." << endl;
+    cout << "Please enter a multivariate polynomial over Z." << endl;
+    cout << "f(x, y, z) = ";
+    cin >> f;
+    cout << "f                  = " << f << endl;
+    cout << "factorize(f)       = " << factorize( f ) << endl << endl;
+
+    setCharacteristic( 29 );
+    cout << "Univariate factorization in GF(29)." << endl;
+    cout << "Please enter an univariate polynomial over GF(29)." << endl;
+    cout << "f(x) = ";
+    cin >> f;
+    cout << "f (mod 29)         = " << f << endl;
+    cout << "factorize(f)       = " << factorize( f ) << endl;
+}
diff --git a/factory/examples/gcd.cc b/factory/examples/gcd.cc
new file mode 100644
index 0000000..5784df3
--- /dev/null
+++ b/factory/examples/gcd.cc
@@ -0,0 +1,45 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+//{{{ docu
+//
+// gcd.cc - sample Factory application.
+//
+//}}}
+
+#include <factory.h>
+
+int
+main()
+{
+    Variable x( 'x' );
+    Variable y( 'y' );
+    Variable z( 'z' );
+    CanonicalForm f;
+    CanonicalForm g;
+
+    cout << "Do not forget to terminate canonical forms with `;' in input!" << endl;
+
+    setCharacteristic( 0 );
+    On( SW_USE_EZGCD );
+    On( SW_RATIONAL );
+    cout << "Multivariate gcd calculation in characteristic 0." << endl;
+    cout << "Please enter two multivariate polynomials over Q." << endl;
+    cout << "f(x, y, z) = ";
+    cin >> f;
+    cout << "g(x, y, z) = ";
+    cin >> g;
+    cout << "f                  = " << f << endl;
+    cout << "g                  = " << g << endl;
+    cout << "gcd(f, g)          = " << gcd( f, g ) << endl << endl;
+
+    setCharacteristic( 29 );
+    cout << "Multivariate gcd calculation in GF(29)." << endl;
+    cout << "Please enter two multivariate polynomials over GF(29)." << endl;
+    cout << "f(x, y, z) = ";
+    cin >> f;
+    cout << "g(x, y, z) = ";
+    cin >> g;
+    cout << "f (mod 29)         = " << f << endl;
+    cout << "g (mod 29)         = " << g << endl;
+    cout << "gcd(f, g) (mod 29) = " << gcd( f, g ) << endl;
+}
diff --git a/factory/facAbsBiFact.cc b/factory/facAbsBiFact.cc
new file mode 100644
index 0000000..98ad6af
--- /dev/null
+++ b/factory/facAbsBiFact.cc
@@ -0,0 +1,785 @@
+/*****************************************************************************\
+ * Computer Algebra System SINGULAR
+\*****************************************************************************/
+/** @file facAbsBiFact.cc
+ *
+ * @author Martin Lee
+ *
+ **/
+/*****************************************************************************/
+
+
+#include "config.h"
+
+
+#include "timing.h"
+#include "debug.h"
+
+#include "facAbsBiFact.h"
+#include "facBivar.h"
+#include "facFqBivar.h"
+#include "cf_reval.h"
+#include "cf_primes.h"
+#include "cf_algorithm.h"
+#ifdef HAVE_FLINT
+#include "FLINTconvert.h"
+#include <flint/fmpz_poly_factor.h>
+#endif
+#ifdef HAVE_NTL
+#include "NTLconvert.h"
+#include <NTL/LLL.h>
+#endif
+
+#ifdef HAVE_NTL
+
+TIMING_DEFINE_PRINT(fac_Qa_factorize)
+TIMING_DEFINE_PRINT(fac_evalpoint)
+
+CFAFList uniAbsFactorize (const CanonicalForm& F, bool full)
+{
+  CFAFList result;
+  if (degree (F) == 1)
+  {
+    bool isRat= isOn (SW_RATIONAL);
+    On (SW_RATIONAL);
+    result= CFAFList (CFAFactor (F/Lc(F), 1, 1));
+    result.insert (CFAFactor (Lc (F), 1, 1));
+    if (!isRat)
+      Off (SW_RATIONAL);
+    return result;
+  }
+  CanonicalForm LcF= 1;
+  Variable alpha;
+  CFFList QaFactors;
+  CFFListIterator iter;
+  alpha= rootOf (F);
+  QaFactors= factorize (F, alpha);
+  iter= QaFactors;
+  if (iter.getItem().factor().inCoeffDomain())
+  {
+    LcF = iter.getItem().factor();
+    iter++;
+  }
+  for (;iter.hasItem(); iter++)
+  {
+    if (full)
+      result.append (CFAFactor (iter.getItem().factor(), getMipo (alpha),
+                                iter.getItem().exp()));
+    if (!full && degree (iter.getItem().factor()) == 1)
+    {
+      result.append (CFAFactor (iter.getItem().factor(), getMipo (alpha),
+                                iter.getItem().exp()));
+      break;
+    }
+  }
+  result.insert (CFAFactor (LcF, 1, 1));
+  return result;
+}
+
+//TODO optimize choice of p -> choose p as large as possible (better than small p since factorization mod p does not require field extension, also less lifting)
+int
+choosePoint (const CanonicalForm& F, int tdegF, CFArray& eval, bool rec,
+             int absValue)
+{
+  REvaluation E1 (1, 1, IntRandom (absValue));
+  REvaluation E2 (2, 2, IntRandom (absValue));
+  if (rec)
+  {
+    E1.nextpoint();
+    E2.nextpoint();
+  }
+
+  CanonicalForm f, f1, f2, Fp;
+  int i, p;
+  CFFList f1Factors, f2Factors;
+  CFFListIterator iter;
+  int count= 0;
+  while (1)
+  {
+    count++;
+    f1= E1 (F);
+    if (!f1.isZero() && degree (f1) == degree (F,2))
+    {
+      f1Factors= factorize (f1);
+      if (f1Factors.getFirst().factor().inCoeffDomain())
+        f1Factors.removeFirst();
+      if (f1Factors.length() == 1 && f1Factors.getFirst().exp() == 1)
+      {
+        f= E2(f1);
+        f2= E2 (F);
+        f2Factors= factorize (f2);
+        Off (SW_RATIONAL);
+        if (f2Factors.getFirst().factor().inCoeffDomain())
+          f2Factors.removeFirst();
+        if (f2Factors.length() == 1 && f2Factors.getFirst().exp() == 1)
+        {
+          ZZX NTLf1= convertFacCF2NTLZZX (f1);
+          ZZX NTLf2= convertFacCF2NTLZZX (f2);
+          ZZ NTLD1= discriminant (NTLf1);
+          ZZ NTLD2= discriminant (NTLf2);
+          CanonicalForm D1= convertZZ2CF (NTLD1);
+          CanonicalForm D2= convertZZ2CF (NTLD2);
+          if ((!f.isZero()) &&
+              (abs(f)>cf_getSmallPrime (cf_getNumSmallPrimes()-1)))
+          {
+            for (i= cf_getNumPrimes()-1; i >= 0; i--)
+            {
+              if (f % CanonicalForm (cf_getPrime (i)) == 0)
+              {
+                p= cf_getPrime(i);
+                Fp= mod (F,p);
+                if (totaldegree (Fp) == tdegF &&
+                    degree (mod (f2,p), 1) == degree (F,1) &&
+                    degree (mod (f1, p),2) == degree (F,2))
+                {
+                  if (mod (D1, p) != 0 && mod (D2, p) != 0)
+                  {
+                    eval[0]= E1[1];
+                    eval[1]= E2[2];
+                    return p;
+                  }
+                }
+              }
+            }
+          }
+          else if (!f.isZero())
+          {
+            for (i= cf_getNumSmallPrimes()-1; i >= 0; i--)
+            {
+              if (f % CanonicalForm (cf_getSmallPrime (i)) == 0)
+              {
+                p= cf_getSmallPrime (i);
+                Fp= mod (F,p);
+                if (totaldegree (Fp) == tdegF &&
+                    degree (mod (f2, p),1) == degree (F,1) &&
+                    degree (mod (f1,p),2) == degree (F,2))
+                {
+                  if (mod (D1, p) != 0 && mod (D2, p) != 0)
+                  {
+                    eval[0]= E1[1];
+                    eval[1]= E2[2];
+                    return p;
+                  }
+                }
+              }
+            }
+          }
+        }
+        E2.nextpoint();
+        On (SW_RATIONAL);
+      }
+    }
+    E1.nextpoint();
+    if (count == 2)
+    {
+      count= 0;
+      absValue++;
+      E1=REvaluation (1, 1, IntRandom (absValue));
+      E2=REvaluation (2, 2, IntRandom (absValue));
+      E1.nextpoint();
+      E2.nextpoint();
+    }
+  }
+  return 0;
+}
+
+//G is assumed to be bivariate, irreducible over Q, primitive wrt x and y, compressed
+CFAFList absBiFactorizeMain (const CanonicalForm& G, bool full)
+{
+  CanonicalForm F= bCommonDen (G)*G;
+  bool isRat= isOn (SW_RATIONAL);
+  Off (SW_RATIONAL);
+  F /= icontent (F);
+  On (SW_RATIONAL);
+
+  mpz_t * M=new mpz_t [4];
+  mpz_init (M[0]);
+  mpz_init (M[1]);
+  mpz_init (M[2]);
+  mpz_init (M[3]);
+
+  mpz_t * S=new mpz_t [2];
+  mpz_init (S[0]);
+  mpz_init (S[1]);
+
+  F= compress (F, M, S);
+
+  if (F.isUnivariate())
+  {
+    if (degree (F) == 1)
+    {
+      mpz_clear (M[0]);
+      mpz_clear (M[1]);
+      mpz_clear (M[2]);
+      mpz_clear (M[3]);
+      delete [] M;
+
+      mpz_clear (S[0]);
+      mpz_clear (S[1]);
+      delete [] S;
+      if (!isRat)
+        Off (SW_RATIONAL);
+      return CFAFList (CFAFactor (G, 1, 1));
+    }
+    CFAFList result= uniAbsFactorize (F, full);
+    if (result.getFirst().factor().inCoeffDomain())
+      result.removeFirst();
+    for (CFAFListIterator iter=result; iter.hasItem(); iter++)
+      iter.getItem()= CFAFactor (decompress (iter.getItem().factor(), M, S),
+                                 iter.getItem().minpoly(),iter.getItem().exp());
+    mpz_clear (M[0]);
+    mpz_clear (M[1]);
+    mpz_clear (M[2]);
+    mpz_clear (M[3]);
+    delete [] M;
+
+    mpz_clear (S[0]);
+    mpz_clear (S[1]);
+    delete [] S;
+    if (!isRat)
+      Off (SW_RATIONAL);
+    return result;
+  }
+
+  if (degree (F, 1) == 1 || degree (F, 2) == 1)
+  {
+    mpz_clear (M[0]);
+    mpz_clear (M[1]);
+    mpz_clear (M[2]);
+    mpz_clear (M[3]);
+    delete [] M;
+
+    mpz_clear (S[0]);
+    mpz_clear (S[1]);
+    delete [] S;
+    if (!isRat)
+      Off (SW_RATIONAL);
+    return CFAFList (CFAFactor (G, 1, 1));
+  }
+  int minTdeg, tdegF= totaldegree (F);
+  CanonicalForm Fp, smallestFactor;
+  int p;
+  CFFList factors;
+  Variable alpha;
+  bool rec= false;
+  Variable x= Variable (1);
+  Variable y= Variable (2);
+  CanonicalForm bufF= F;
+  CFFListIterator iter;
+  CFArray eval= CFArray (2);
+  int absValue= 1;
+differentevalpoint:
+  while (1)
+  {
+    TIMING_START (fac_evalpoint);
+    p= choosePoint (F, tdegF, eval, rec, absValue);
+    TIMING_END_AND_PRINT (fac_evalpoint, "time to find eval point: ");
+
+    //after here isOn (SW_RATIONAL)==false
+    setCharacteristic (p);
+    Fp=F.mapinto();
+    factors= factorize (Fp);
+
+    if (factors.getFirst().factor().inCoeffDomain())
+      factors.removeFirst();
+
+    if (factors.length() == 1 && factors.getFirst().exp() == 1)
+    {
+      if (absIrredTest (Fp))
+      {
+        if (isRat)
+          On (SW_RATIONAL);
+        setCharacteristic(0);
+        mpz_clear (M[0]);
+        mpz_clear (M[1]);
+        mpz_clear (M[2]);
+        mpz_clear (M[3]);
+        delete [] M;
+
+        mpz_clear (S[0]);
+        mpz_clear (S[1]);
+        delete [] S;
+        return CFAFList (CFAFactor (G, 1, 1));
+      }
+      else
+      {
+        setCharacteristic (0);
+        if (modularIrredTestWithShift (F))
+        {
+          if (isRat)
+            On (SW_RATIONAL);
+          mpz_clear (M[0]);
+          mpz_clear (M[1]);
+          mpz_clear (M[2]);
+          mpz_clear (M[3]);
+          delete [] M;
+
+          mpz_clear (S[0]);
+          mpz_clear (S[1]);
+          delete [] S;
+          return CFAFList (CFAFactor (G, 1, 1));
+        }
+        rec= true;
+        continue;
+      }
+    }
+    iter= factors;
+    smallestFactor= iter.getItem().factor();
+    while (smallestFactor.isUnivariate() && iter.hasItem())
+    {
+      iter++;
+      if (!iter.hasItem())
+        break;
+      smallestFactor= iter.getItem().factor();
+    }
+
+    minTdeg= totaldegree (smallestFactor);
+    if (iter.hasItem())
+      iter++;
+    for (; iter.hasItem(); iter++)
+    {
+      if (!iter.getItem().factor().isUnivariate() &&
+          (totaldegree (iter.getItem().factor()) < minTdeg))
+      {
+        smallestFactor= iter.getItem().factor();
+        minTdeg= totaldegree (smallestFactor);
+      }
+    }
+    if (tdegF % minTdeg == 0)
+      break;
+    setCharacteristic(0);
+    rec=true;
+  }
+  CanonicalForm Gp= Fp/smallestFactor;
+  Gp= Gp /Lc (Gp);
+
+  CanonicalForm Gpy= Gp (eval[0].mapinto(), 1);
+  CanonicalForm smallestFactorEvaly= smallestFactor (eval[0].mapinto(),1);
+  CanonicalForm Gpx= Gp (eval[1].mapinto(), 2);
+  CanonicalForm smallestFactorEvalx= smallestFactor (eval[1].mapinto(),2);
+
+  bool xValid= !(Gpx.inCoeffDomain() || smallestFactorEvalx.inCoeffDomain() ||
+               !gcd (Gpx, smallestFactorEvalx).inCoeffDomain());
+  bool yValid= !(Gpy.inCoeffDomain() || smallestFactorEvaly.inCoeffDomain() ||
+               !gcd (Gpy, smallestFactorEvaly).inCoeffDomain());
+  if (!xValid || !yValid)
+  {
+    rec= true;
+    setCharacteristic (0);
+    goto differentevalpoint;
+  }
+
+  setCharacteristic (0);
+
+  CanonicalForm mipo;
+
+  CFArray mipos= CFArray (2);
+  CFFList mipoFactors;
+  for (int i= 1; i < 3; i++)
+  {
+    CanonicalForm Fi= F(eval[i-1],i);
+
+    int s= tdegF/minTdeg + 1;
+    CanonicalForm bound= power (maxNorm (Fi), 2*(s-1));
+    bound *= power (CanonicalForm (s),s-1);
+    bound *= power (CanonicalForm (2), ((s-1)*(s-1))/2); //possible int overflow
+
+    CanonicalForm B = p;
+    long k = 1L;
+    while ( B < bound ) {
+      B *= p;
+      k++;
+    }
+
+    //TODO take floor (log2(k))
+    k= k+1;
+#ifdef HAVE_FLINT
+    fmpz_poly_t FLINTFi;
+    convertFacCF2Fmpz_poly_t (FLINTFi, Fi);
+    setCharacteristic (p);
+    nmod_poly_t FLINTFpi, FLINTGpi;
+    if (i == 2)
+    {
+      convertFacCF2nmod_poly_t (FLINTFpi,
+                                smallestFactorEvalx/lc (smallestFactorEvalx));
+      convertFacCF2nmod_poly_t (FLINTGpi, Gpx/lc (Gpx));
+    }
+    else
+    {
+      convertFacCF2nmod_poly_t (FLINTFpi,
+                                smallestFactorEvaly/lc (smallestFactorEvaly));
+      convertFacCF2nmod_poly_t (FLINTGpi, Gpy/lc (Gpy));
+    }
+    nmod_poly_factor_t nmodFactors;
+    nmod_poly_factor_init (nmodFactors);
+    nmod_poly_factor_insert (nmodFactors, FLINTFpi, 1L);
+    nmod_poly_factor_insert (nmodFactors, FLINTGpi, 1L);
+
+    // the following fix is due to interface changes from  FLINT 2.3 -> FLINT 2.4
+#   ifndef slong
+#          define slong long
+#   endif
+
+    slong * link= new slong [2];
+    fmpz_poly_t *v= new fmpz_poly_t[2];
+    fmpz_poly_t *w= new fmpz_poly_t[2];
+    fmpz_poly_init(v[0]);
+    fmpz_poly_init(v[1]);
+    fmpz_poly_init(w[0]);
+    fmpz_poly_init(w[1]);
+
+    fmpz_poly_factor_t liftedFactors;
+    fmpz_poly_factor_init (liftedFactors);
+    _fmpz_poly_hensel_start_lift (liftedFactors, link, v, w, FLINTFi,
+                                  nmodFactors, k);
+
+    nmod_poly_factor_clear (nmodFactors);
+    nmod_poly_clear (FLINTFpi);
+    nmod_poly_clear (FLINTGpi);
+
+    setCharacteristic(0);
+    CanonicalForm liftedSmallestFactor=
+    convertFmpz_poly_t2FacCF ((fmpz_poly_t &)liftedFactors->p[0],x);
+
+    CanonicalForm otherFactor=
+    convertFmpz_poly_t2FacCF ((fmpz_poly_t &)liftedFactors->p[1],x);
+    modpk pk= modpk (p, k);
+#else
+    modpk pk= modpk (p, k);
+    ZZX NTLFi=convertFacCF2NTLZZX (pk (Fi*pk.inverse (lc(Fi))));
+    setCharacteristic (p);
+
+    if (fac_NTL_char != p)
+    {
+      fac_NTL_char= p;
+      zz_p::init (p);
+    }
+    zz_pX NTLFpi, NTLGpi;
+    if (i == 2)
+    {
+      NTLFpi=convertFacCF2NTLzzpX (smallestFactorEvalx/lc(smallestFactorEvalx));
+      NTLGpi=convertFacCF2NTLzzpX (Gpx/lc (Gpx));
+    }
+    else
+    {
+      NTLFpi=convertFacCF2NTLzzpX (smallestFactorEvaly/lc(smallestFactorEvaly));
+      NTLGpi=convertFacCF2NTLzzpX (Gpy/lc (Gpy));
+    }
+    vec_zz_pX modFactors;
+    modFactors.SetLength(2);
+    modFactors[0]= NTLFpi;
+    modFactors[1]= NTLGpi;
+    vec_ZZX liftedFactors;
+    MultiLift (liftedFactors, modFactors, NTLFi, (long) k);
+    setCharacteristic(0);
+    CanonicalForm liftedSmallestFactor=
+                  convertNTLZZX2CF (liftedFactors[0], x);
+
+    CanonicalForm otherFactor=
+                  convertNTLZZX2CF (liftedFactors[1], x);
+#endif
+
+    Off (SW_SYMMETRIC_FF);
+    liftedSmallestFactor= pk (liftedSmallestFactor);
+    if (i == 2)
+      liftedSmallestFactor= liftedSmallestFactor (eval[0],1);
+    else
+      liftedSmallestFactor= liftedSmallestFactor (eval[1],1);
+
+    On (SW_SYMMETRIC_FF);
+    CFMatrix *M= new CFMatrix (s, s);
+    (*M)(s,s)= power (CanonicalForm (p), k);
+    for (int j= 1; j < s; j++)
+    {
+      (*M) (j,j)= 1;
+      (*M) (j+1,j)= -liftedSmallestFactor;
+    }
+
+    mat_ZZ * NTLM= convertFacCFMatrix2NTLmat_ZZ (*M);
+
+    ZZ det;
+
+    transpose (*NTLM, *NTLM);
+    (void) LLL (det, *NTLM, 1L, 1L); //use floating point LLL ?
+    transpose (*NTLM, *NTLM);
+    delete M;
+    M= convertNTLmat_ZZ2FacCFMatrix (*NTLM);
+    delete NTLM;
+
+    mipo= 0;
+    for (int j= 1; j <= s; j++)
+      mipo += (*M) (j,1)*power (x,s-j);
+
+    delete M;
+    mipoFactors= factorize (mipo);
+    if (mipoFactors.getFirst().factor().inCoeffDomain())
+      mipoFactors.removeFirst();
+
+#ifdef HAVE_FLINT
+    fmpz_poly_clear (v[0]);
+    fmpz_poly_clear (v[1]);
+    fmpz_poly_clear (w[0]);
+    fmpz_poly_clear (w[1]);
+    delete [] v;
+    delete [] w;
+    delete [] link;
+    fmpz_poly_factor_clear (liftedFactors);
+#endif
+
+    if (mipoFactors.length() > 1 ||
+        (mipoFactors.length() == 1 && mipoFactors.getFirst().exp() > 1) ||
+         mipo.inCoeffDomain())
+    {
+        rec=true;
+        goto differentevalpoint;
+    }
+    else
+      mipos[i-1]= mipo;
+  }
+
+  if (degree (mipos[0]) != degree (mipos[1]))
+  {
+    rec=true;
+    goto differentevalpoint;
+  }
+
+  On (SW_RATIONAL);
+  if (maxNorm (mipos[0]) < maxNorm (mipos[1]))
+    alpha= rootOf (mipos[0]);
+  else
+    alpha= rootOf (mipos[1]);
+
+  int wrongMipo= 0;
+
+  Variable beta;
+  if (maxNorm (mipos[0]) < maxNorm (mipos[1]))
+  {
+    mipoFactors= factorize (mipos[1], alpha);
+    if (mipoFactors.getFirst().factor().inCoeffDomain())
+      mipoFactors.removeFirst();
+    for (iter= mipoFactors; iter.hasItem(); iter++)
+    {
+      if (degree (iter.getItem().factor()) > 1)
+        wrongMipo++;
+    }
+    if (wrongMipo == mipoFactors.length())
+    {
+      rec=true;
+      goto differentevalpoint;
+    }
+    wrongMipo= 0;
+    beta= rootOf (mipos[1]);
+    mipoFactors= factorize (mipos[0], beta);
+    if (mipoFactors.getFirst().factor().inCoeffDomain())
+      mipoFactors.removeFirst();
+    for (iter= mipoFactors; iter.hasItem(); iter++)
+    {
+      if (degree (iter.getItem().factor()) > 1)
+        wrongMipo++;
+    }
+    if (wrongMipo == mipoFactors.length())
+    {
+      rec=true;
+      goto differentevalpoint;
+    }
+  }
+  else
+  {
+    mipoFactors= factorize (mipos[0], alpha);
+    if (mipoFactors.getFirst().factor().inCoeffDomain())
+      mipoFactors.removeFirst();
+    for (iter= mipoFactors; iter.hasItem(); iter++)
+    {
+      if (degree (iter.getItem().factor()) > 1)
+        wrongMipo++;
+    }
+    if (wrongMipo == mipoFactors.length())
+    {
+      rec=true;
+      goto differentevalpoint;
+    }
+    wrongMipo= 0;
+    beta= rootOf (mipos[0]);
+    mipoFactors= factorize (mipos[1], beta);
+    if (mipoFactors.getFirst().factor().inCoeffDomain())
+      mipoFactors.removeFirst();
+    for (iter= mipoFactors; iter.hasItem(); iter++)
+    {
+      if (degree (iter.getItem().factor()) > 1)
+        wrongMipo++;
+    }
+    if (wrongMipo == mipoFactors.length())
+    {
+      rec=true;
+      goto differentevalpoint;
+    }
+  }
+
+
+  CanonicalForm F1;
+  if (degree (F,1) > minTdeg)
+    F1= F (eval[1], 2);
+  else
+    F1= F (eval[0], 1);
+
+  CFFList QaF1Factors;
+  bool swap= false;
+  if (F1.level() == 2)
+  {
+    swap= true;
+    F1=swapvar (F1, x, y);
+    F= swapvar (F, x, y);
+  }
+
+  wrongMipo= 0;
+  QaF1Factors= factorize (F1, alpha);
+  if (QaF1Factors.getFirst().factor().inCoeffDomain())
+    QaF1Factors.removeFirst();
+  for (iter= QaF1Factors; iter.hasItem(); iter++)
+  {
+    if (degree (iter.getItem().factor()) > minTdeg)
+      wrongMipo++;
+  }
+
+  if (wrongMipo == QaF1Factors.length())
+  {
+    rec= true;
+    F= bufF;
+    goto differentevalpoint;
+  }
+
+  CanonicalForm evaluation;
+  if (swap)
+    evaluation= eval[0];
+  else
+    evaluation= eval[1];
+
+  F *= bCommonDen (F);
+  F= F (y + evaluation, y);
+
+  int liftBound= degree (F,y) + 1;
+
+  modpk b= modpk();
+
+  CanonicalForm den= 1;
+
+  mipo= getMipo (alpha);
+
+  CFList uniFactors;
+  for (iter=QaF1Factors; iter.hasItem(); iter++)
+    uniFactors.append (iter.getItem().factor());
+
+  F /= Lc (F1);
+  ZZX NTLmipo= convertFacCF2NTLZZX (mipo);
+  ZZX NTLLcf= convertFacCF2NTLZZX (Lc (F*bCommonDen (F)));
+  ZZ NTLf= resultant (NTLmipo, NTLLcf);
+  ZZ NTLD= discriminant (NTLmipo);
+  den= abs (convertZZ2CF (NTLD*NTLf));
+
+  // make factors elements of Z(a)[x] disable for modularDiophant
+  CanonicalForm multiplier= 1;
+  for (CFListIterator i= uniFactors; i.hasItem(); i++)
+  {
+    multiplier *= bCommonDen (i.getItem());
+    i.getItem()= i.getItem()*bCommonDen(i.getItem());
+  }
+  F *= multiplier;
+  F *= bCommonDen (F);
+
+  Off (SW_RATIONAL);
+  int ii= 0;
+  CanonicalForm discMipo= convertZZ2CF (NTLD);
+  findGoodPrime (bufF*discMipo,ii);
+  findGoodPrime (F1*discMipo,ii);
+  findGoodPrime (F*discMipo,ii);
+
+  int pp=cf_getBigPrime(ii);
+  b = coeffBound( F, pp, mipo );
+  modpk bb= coeffBound (F1, pp, mipo);
+  if (bb.getk() > b.getk() ) b=bb;
+    bb= coeffBound (F, pp, mipo);
+  if (bb.getk() > b.getk() ) b=bb;
+
+  ExtensionInfo dummy= ExtensionInfo (alpha, false);
+  DegreePattern degs= DegreePattern (uniFactors);
+
+  bool earlySuccess= false;
+  CFList earlyFactors;
+  uniFactors= henselLiftAndEarly
+              (F, earlySuccess, earlyFactors, degs, liftBound,
+               uniFactors, dummy, evaluation, b, den);
+
+  DEBOUTLN (cerr, "lifted factors= " << uniFactors);
+
+  CanonicalForm MODl= power (y, liftBound);
+
+  On (SW_RATIONAL);
+  F *= bCommonDen (F);
+  Off (SW_RATIONAL);
+
+  CFList biFactors;
+
+  biFactors= factorRecombination (uniFactors, F, MODl, degs, evaluation, 1,
+                                  uniFactors.length()/2, b, den);
+
+  On (SW_RATIONAL);
+
+  if (earlySuccess)
+    biFactors= Union (earlyFactors, biFactors);
+  else if (!earlySuccess && degs.getLength() == 1)
+    biFactors= earlyFactors;
+
+  bool swap2= false;
+  appendSwapDecompress (biFactors, CFList(), CFList(), swap, swap2, CFMap());
+  if (isOn (SW_RATIONAL))
+    normalize (biFactors);
+
+  CFAFList result;
+  bool found= false;
+
+  for (CFListIterator i= biFactors; i.hasItem(); i++)
+  {
+    if (full)
+      result.append (CFAFactor (decompress (i.getItem(), M, S),
+                                getMipo (alpha), 1));
+
+    if (totaldegree (i.getItem()) == minTdeg)
+    {
+      if (!full)
+        result= CFAFList (CFAFactor (decompress (i.getItem(), M, S),
+                                     getMipo (alpha), 1));
+      found= true;
+
+      if (!full)
+        break;
+    }
+  }
+
+  if (!found)
+  {
+    rec= true;
+    F= bufF;
+    goto differentevalpoint;
+  }
+
+  if (isRat)
+    On (SW_RATIONAL);
+  else
+    Off (SW_RATIONAL);
+
+  mpz_clear (M[0]);
+  mpz_clear (M[1]);
+  mpz_clear (M[2]);
+  mpz_clear (M[3]);
+  delete [] M;
+
+  mpz_clear (S[0]);
+  mpz_clear (S[1]);
+  delete [] S;
+
+  return result;
+}
+
+#endif
+
+
diff --git a/factory/facAbsBiFact.h b/factory/facAbsBiFact.h
new file mode 100644
index 0000000..09df13e
--- /dev/null
+++ b/factory/facAbsBiFact.h
@@ -0,0 +1,60 @@
+/*****************************************************************************\
+ * Computer Algebra System SINGULAR
+\*****************************************************************************/
+/** @file facAbsBiFact.h
+ *
+ * bivariate absolute factorization over Q described in "Modular Las Vegas
+ * Algorithms for Polynomial Absolute Factorization" by Bertone, Chèze, Galligo
+ *
+ * @author Martin Lee
+ *
+ **/
+/*****************************************************************************/
+
+#ifndef FAC_ABS_BI_FACT_H
+#define FAC_ABS_BI_FACT_H
+
+#include "canonicalform.h"
+
+#ifdef HAVE_NTL
+/// main absolute factorization routine, expects bivariate poly which is
+/// irreducible over Q
+///
+/// @return absBiFactorizeMain returns a list whose entries contain three
+///         entities:
+///         an absolute irreducible factor, an irreducible univariate polynomial
+///         that defines the minimal field extension over which the irreducible
+///         factor is defined (note: in case the factor is already defined over
+///         Q[t]/(t), 1 is returned as defining poly), and the
+///         multiplicity of the absolute irreducible factor
+CFAFList absBiFactorizeMain (const CanonicalForm& F, ///<[in] s.a.
+                             bool full= false        ///<[in] true if all
+                                                     ///< factors should be
+                                                     ///< returned
+                            );
+#endif
+
+/// normalize factors, i.e. make factors monic
+static inline
+void normalize (CFAFList & L)
+{
+  for (CFAFListIterator i= L; i.hasItem(); i++)
+    i.getItem()= CFAFactor (i.getItem().factor()/Lc (i.getItem().factor()),
+                            i.getItem().minpoly(), i.getItem().exp());
+}
+
+/// univariate absolute factorization over Q
+///
+/// @return uniAbsFactorize returns a list whose entries contain three entities:
+///         an absolute irreducible factor, an irreducible univariate polynomial
+///         that defines the minimal field extension over which the irreducible
+///         factor is defined (note: in case the factor is already defined over
+///         Q[t]/(t), 1 is returned as defining poly), and the multiplicity of
+///         the absolute irreducible factor
+CFAFList uniAbsFactorize (const CanonicalForm& F, ///<[in] univariate poly
+                                                  ///< irreducible over Q
+                          bool full= false        ///<[in] true if all factors
+                                                  ///< should be returned
+                         );
+
+#endif
diff --git a/factory/facAbsFact.cc b/factory/facAbsFact.cc
new file mode 100644
index 0000000..987c97d
--- /dev/null
+++ b/factory/facAbsFact.cc
@@ -0,0 +1,946 @@
+/*****************************************************************************\
+ * Computer Algebra System SINGULAR
+\*****************************************************************************/
+/** @file facAbsFact.cc
+ *
+ * @author Martin Lee
+ *
+ **/
+/*****************************************************************************/
+
+
+#include "config.h"
+
+
+#include "timing.h"
+#include "debug.h"
+
+#include "facAbsBiFact.h"
+#include "facAbsFact.h"
+#include "facFqFactorize.h"
+#include "facFqFactorizeUtil.h"
+#include "facHensel.h"
+#include "facSparseHensel.h"
+#include "facFactorize.h"
+#include "cf_reval.h"
+#include "cf_primes.h"
+#include "cf_algorithm.h"
+#include "cfModResultant.h"
+#include "cfUnivarGcd.h"
+#ifdef HAVE_FLINT
+#include "FLINTconvert.h"
+#endif
+#ifdef HAVE_NTL
+#include "NTLconvert.h"
+#include <NTL/LLL.h>
+#endif
+
+#ifdef HAVE_NTL
+TIMING_DEFINE_PRINT(abs_fac_bi_factorizer)
+TIMING_DEFINE_PRINT(abs_fac_hensel_lift)
+TIMING_DEFINE_PRINT(abs_fac_factor_recombination)
+TIMING_DEFINE_PRINT(abs_fac_shift_to_zero)
+TIMING_DEFINE_PRINT(abs_fac_precompute_leadcoeff)
+TIMING_DEFINE_PRINT(abs_fac_evaluation)
+TIMING_DEFINE_PRINT(abs_fac_recover_factors)
+TIMING_DEFINE_PRINT(abs_fac_bifactor_total)
+TIMING_DEFINE_PRINT(abs_fac_luckswang)
+TIMING_DEFINE_PRINT(abs_fac_lcheuristic)
+TIMING_DEFINE_PRINT(abs_fac_cleardenom)
+TIMING_DEFINE_PRINT(abs_fac_compress)
+
+/// steps 4)-8) of Algorithm B.7.8. from Greuel, Pfister "A Singular
+/// Introduction to Commutative Algebra"
+CFAFList
+RothsteinTragerResultant (const CanonicalForm& F, const CanonicalForm& w, int s,
+                          const CFList& evaluation, const Variable& y)
+{
+  CFList terms;
+  for (CFIterator i= w; i.hasTerms(); i++)
+    terms.append (i.coeff());
+
+  Variable x= Variable (1);
+  CanonicalForm derivF= deriv (F, x);
+  CanonicalForm g, geval, derivFeval, Feval, H, res, sqrfPartRes;
+  CFListIterator iter;
+
+  REvaluation E (1, terms.length(), IntRandom (25));
+
+  do
+  {
+    E.nextpoint();
+    g= 0;
+    iter= terms;
+    for (int i= terms.length(); i >= 1; i--, iter++)
+      g += E[i]*iter.getItem();
+
+    geval= g;
+    Feval= F;
+    derivFeval= derivF;
+    iter= evaluation;
+    for (int i= F.level(); i >= 2; iter++, i--)
+    {
+      Feval= Feval (iter.getItem(), i);
+      geval= geval (iter.getItem(), i);
+      derivFeval= derivFeval (iter.getItem(), i);
+    }
+
+    H= y*derivFeval-geval;
+
+    if (degree (Feval, x) >= 8 || degree (H, x) >= 8)
+      res= resultantZ (Feval, H, x);
+    else
+      res= resultant (Feval, H, x);
+
+    sqrfPartRes= sqrfPart (res); //univariate poly in y
+  }
+  while (degree (sqrfPartRes) != s);
+
+  Variable beta= rootOf (sqrfPartRes);
+
+  CanonicalForm factor= gcd (F, beta*derivF-g);
+
+  return CFAFList (CFAFactor (factor, getMipo (beta), 1));
+}
+
+
+/// Algorithm B.7.8 from Greuel, Pfister "A Singular Introduction to Commutative
+/// Algebra"
+CFAFList
+RothsteinTrager (const CanonicalForm& F, const CFList& factors,
+                 const Variable& alpha, const CFList& evaluation)
+{
+  Variable x= Variable (1);
+  ASSERT (factors.length() == 2, "expected two factors");
+  CanonicalForm G, H;
+  if (totaldegree (factors.getFirst()) > totaldegree (factors.getLast()))
+  {
+    H= factors.getLast();
+    G= factors.getFirst();
+  }
+  else
+  {
+    H= factors.getFirst();
+    G= factors.getLast();
+  }
+  CanonicalForm derivH= deriv (H, x);
+  CanonicalForm w= G*derivH;
+  Variable y= Variable (F.level()+1);
+  w= replacevar (w, alpha, y);
+
+  int s= totaldegree (F)/totaldegree (H);
+
+  return RothsteinTragerResultant (F, w, s, evaluation, y);
+}
+
+CFList
+evalPoints4AbsFact (const CanonicalForm& F, CFList& eval, Evaluation& E,
+                    int& intervalSize)
+{
+  CFList result;
+  Variable x= Variable (1);
+
+  CanonicalForm LCF= LC (F, x);
+  CFList LCFeval= CFList();
+
+  bool found= false;
+  bool allZero= true;
+  bool foundZero= false;
+  CanonicalForm deriv_x, gcd_deriv;
+  CFFList uniFactors;
+  CFListIterator iter;
+  int count= 0;
+  do
+  {
+    count++;
+    if (count==E.max() - E.min() + 1)
+    {
+      count= 1;
+      intervalSize++;
+      E= REvaluation (E.min(), E.max(), IntRandom (intervalSize));
+      E.nextpoint();
+    }
+    eval.insert (F);
+    LCFeval.insert (LCF);
+    bool bad= false;
+    for (int i= E.max(); i >= E.min(); i--)
+    {
+      eval.insert (eval.getFirst()( E [i], i));
+      LCFeval.insert (LCFeval.getFirst()( E [i], i));
+      result.append (E[i]);
+      if (!E[i].isZero())
+        allZero= false;
+      else
+        foundZero= true;
+      if (!allZero && foundZero)
+      {
+        result= CFList();
+        eval= CFList();
+        LCFeval= CFList();
+        bad= true;
+        foundZero= false;
+        break;
+      }
+      if (degree (eval.getFirst(), i - 1) != degree (F, i - 1))
+      {
+        result= CFList();
+        LCFeval= CFList();
+        eval= CFList();
+        bad= true;
+        break;
+      }
+      if ((i != 2) && (degree (LCFeval.getFirst(), i-1) != degree (LCF, i-1)))
+      {
+        result= CFList();
+        LCFeval= CFList();
+        eval= CFList();
+        bad= true;
+        break;
+      }
+    }
+
+    if (bad)
+    {
+      E.nextpoint();
+      continue;
+    }
+
+    if (degree (eval.getFirst()) != degree (F, 1))
+    {
+      result= CFList();
+      eval= CFList();
+      LCFeval= CFList();
+      E.nextpoint();
+      continue;
+    }
+
+    deriv_x= deriv (eval.getFirst(), x);
+    gcd_deriv= gcd (eval.getFirst(), deriv_x);
+    if (degree (gcd_deriv) > 0)
+    {
+      result= CFList();
+      eval= CFList();
+      LCFeval= CFList();
+      E.nextpoint();
+      continue;
+    }
+    uniFactors= factorize (eval.getFirst());
+    if (uniFactors.getFirst().factor().inCoeffDomain())
+      uniFactors.removeFirst();
+    if (uniFactors.length() > 1 || uniFactors.getFirst().exp() > 1)
+    {
+      result= CFList();
+      eval= CFList();
+      LCFeval= CFList();
+      E.nextpoint();
+      continue;
+    }
+    iter= eval;
+    iter++;
+    CanonicalForm contentx= content (iter.getItem(), x);
+    if (degree (contentx) > 0)
+    {
+      result= CFList();
+      eval= CFList();
+      LCFeval= CFList();
+      E.nextpoint();
+      continue;
+    }
+    contentx= content (iter.getItem());
+    if (degree (contentx) > 0)
+    {
+      result= CFList();
+      eval= CFList();
+      LCFeval= CFList();
+      E.nextpoint();
+      continue;
+    }
+    found= true;
+  }
+  while (!found);
+
+  if (!eval.isEmpty())
+    eval.removeFirst();
+  return result;
+}
+
+CFAFList absFactorize (const CanonicalForm& G
+                           )
+{
+  //TODO handle homogeneous input, is already done in LIB interface but still...
+  ASSERT (getCharacteristic() == 0, "expected poly over Q");
+
+  CanonicalForm F= G;
+
+  CanonicalForm LcF= Lc (F);
+  bool isRat= isOn (SW_RATIONAL);
+  if (isRat)
+    F *= bCommonDen (F);
+
+  Off (SW_RATIONAL);
+  F /= icontent (F);
+  if (isRat)
+    On (SW_RATIONAL);
+
+  CFFList rationalFactors= factorize (F);
+
+  CFAFList result, resultBuf;
+
+  CFAFListIterator iter;
+  CFFListIterator i= rationalFactors;
+  i++;
+  for (; i.hasItem(); i++)
+  {
+    resultBuf= absFactorizeMain (i.getItem().factor());
+    for (iter= resultBuf; iter.hasItem(); iter++)
+      iter.getItem()= CFAFactor (iter.getItem().factor(),
+                                 iter.getItem().minpoly(), i.getItem().exp());
+    result= Union (result, resultBuf);
+  }
+
+  if (isRat)
+    normalize (result);
+  result.insert (CFAFactor (LcF, 1, 1));
+
+  return result;
+}
+
+CFAFList absFactorizeMain (const CanonicalForm& G)
+{
+  CanonicalForm F= bCommonDen (G)*G;
+
+  Off (SW_RATIONAL);
+  F /= icontent (F);
+  On (SW_RATIONAL);
+
+  if (F.inCoeffDomain())
+    return CFAFList (CFAFactor (F, 1, 1));
+
+  // compress and find main Variable
+  CFMap N;
+  TIMING_START (abs_fac_compress)
+  CanonicalForm A= myCompress (F, N);
+  TIMING_END_AND_PRINT (abs_fac_compress,
+                        "time to compress poly in abs fact: ")
+
+  //univariate case
+  if (F.isUnivariate())
+  {
+    CFAFList result;
+    result= uniAbsFactorize (F);
+    if (result.getFirst().factor().inCoeffDomain())
+      result.removeFirst();
+    return result;
+  }
+
+  //bivariate case
+  if (A.level() == 2)
+  {
+    CFAFList result= absBiFactorizeMain (A);
+    decompress (result, N);
+    return result; //needs compressed input
+  }
+
+  Variable x= Variable (1);
+  Variable y= Variable (2);
+
+  CFAFList factors;
+  A *= bCommonDen (A);
+  CFList Aeval, list, evaluation, bufEvaluation, bufAeval;
+  int factorNums= 1;
+  CFAFList absBiFactors, absBufBiFactors;
+  CanonicalForm evalPoly;
+  int lift, bufLift, lengthAeval2= A.level()-2;
+  CFList* bufAeval2= new CFList [lengthAeval2];
+  CFList* Aeval2= new CFList [lengthAeval2];
+  int counter;
+  int differentSecondVar= 0;
+  CanonicalForm bufA;
+
+  // several bivariate factorizations
+  TIMING_START (abs_fac_bifactor_total);
+  int absValue= 2;
+  REvaluation E (2, A.level(), IntRandom (absValue));
+  for (int i= 0; i < factorNums; i++)
+  {
+    counter= 0;
+    bufA= A;
+    bufAeval= CFList();
+    TIMING_START (abs_fac_evaluation);
+    bufEvaluation= evalPoints4AbsFact (bufA, bufAeval, E, absValue);
+    TIMING_END_AND_PRINT (abs_fac_evaluation,
+                          "time to find evaluation point in abs fact: ");
+    E.nextpoint();
+    evalPoly= 0;
+
+    TIMING_START (abs_fac_evaluation);
+    evaluationWRTDifferentSecondVars (bufAeval2, bufEvaluation, A);
+    TIMING_END_AND_PRINT (abs_fac_evaluation,
+                          "time to eval wrt diff second vars in abs fact: ");
+
+    for (int j= 0; j < lengthAeval2; j++)
+    {
+      if (!bufAeval2[j].isEmpty())
+        counter++;
+    }
+
+    bufLift= degree (A, y) + 1 + degree (LC(A, x), y);
+
+    TIMING_START (abs_fac_bi_factorizer);
+    absBufBiFactors= absBiFactorizeMain (bufAeval.getFirst(), true);
+    TIMING_END_AND_PRINT (abs_fac_bi_factorizer,
+                          "time for bivariate factorization in abs fact: ");
+
+    if (absBufBiFactors.length() == 1)
+    {
+      factors.append (CFAFactor (A, 1, 1));
+      decompress (factors, N);
+      if (isOn (SW_RATIONAL))
+        normalize (factors);
+      delete [] bufAeval2;
+      delete [] Aeval2;
+      return factors;
+    }
+
+    if (i == 0)
+    {
+      Aeval= bufAeval;
+      evaluation= bufEvaluation;
+      absBiFactors= absBufBiFactors;
+      lift= bufLift;
+      for (int j= 0; j < lengthAeval2; j++)
+        Aeval2 [j]= bufAeval2 [j];
+      differentSecondVar= counter;
+    }
+    else
+    {
+      if (absBufBiFactors.length() < absBiFactors.length() ||
+          ((bufLift < lift) &&
+          (absBufBiFactors.length() == absBiFactors.length())) ||
+          counter > differentSecondVar)
+      {
+        Aeval= bufAeval;
+        evaluation= bufEvaluation;
+        absBiFactors= absBufBiFactors;
+        lift= bufLift;
+        for (int j= 0; j < lengthAeval2; j++)
+          Aeval2 [j]= bufAeval2 [j];
+        differentSecondVar= counter;
+      }
+    }
+    int k= 0;
+    for (CFListIterator j= bufEvaluation; j.hasItem(); j++, k++)
+      evalPoly += j.getItem()*power (x, k);
+    list.append (evalPoly);
+  }
+
+  delete [] bufAeval2;
+
+  CFList rationalFactors;
+  Variable v= mvar (absBiFactors.getFirst().minpoly());
+
+  CFList biFactors;
+  for (CFAFListIterator iter= absBiFactors; iter.hasItem(); iter++)
+    biFactors.append (iter.getItem().factor());
+
+  sortList (biFactors, x);
+
+  int minFactorsLength;
+  bool irred= false;
+
+  TIMING_START (abs_fac_bi_factorizer);
+  factorizationWRTDifferentSecondVars (A, Aeval2, minFactorsLength, irred, v);
+  TIMING_END_AND_PRINT (abs_fac_bi_factorizer,
+         "time for bivariate factorization wrt diff second vars in abs fact: ");
+
+  TIMING_END_AND_PRINT (abs_fac_bifactor_total,
+                        "total time for eval and bivar factors in abs fact: ");
+  if (irred)
+  {
+    factors.append (CFAFactor (A, 1, 1));
+    decompress (factors, N);
+    if (isOn (SW_RATIONAL))
+      normalize (factors);
+    delete [] Aeval2;
+    return factors;
+  }
+
+  if (minFactorsLength == 0)
+    minFactorsLength= biFactors.length();
+  else if (biFactors.length() > minFactorsLength)
+    refineBiFactors (A, biFactors, Aeval2, evaluation, minFactorsLength);
+  minFactorsLength= tmin (minFactorsLength, biFactors.length());
+
+  CFList uniFactors= buildUniFactors (biFactors, evaluation.getLast(), y);
+
+  sortByUniFactors (Aeval2, lengthAeval2, uniFactors, biFactors, evaluation);
+
+  minFactorsLength= tmin (minFactorsLength, biFactors.length());
+
+  if (minFactorsLength == 1)
+  {
+    factors.append (CFAFactor (A, 1, 1));
+    decompress (factors, N);
+    if (isOn (SW_RATIONAL))
+      normalize (factors);
+    delete [] Aeval2;
+    return factors;
+  }
+
+  bool found= false;
+  if (differentSecondVar == lengthAeval2)
+  {
+    bool zeroOccured= false;
+    for (CFListIterator iter= evaluation; iter.hasItem(); iter++)
+    {
+      if (iter.getItem().isZero())
+      {
+        zeroOccured= true;
+        break;
+      }
+    }
+    if (!zeroOccured)
+    {
+      rationalFactors= sparseHeuristic (A, biFactors, Aeval2, evaluation,
+                                       minFactorsLength);
+      if (rationalFactors.length() == biFactors.length())
+      {
+        for (CFListIterator iter= rationalFactors; iter.hasItem(); iter++)
+        {
+          if (totaldegree(iter.getItem())*degree(getMipo(v)) == totaldegree (G))
+          {
+            factors= CFAFList (CFAFactor (iter.getItem(), getMipo (v), 1));
+            found= true;
+            break;
+          }
+        }
+        // necessary since extension may be too large
+        if (!found)
+          factors= RothsteinTrager (A, rationalFactors, v, evaluation);
+
+        decompress (factors, N);
+        normalize (factors);
+        delete [] Aeval2;
+        return factors;
+      }
+      else
+        rationalFactors= CFList();
+      //TODO case where factors.length() > 0
+    }
+  }
+
+  CFList * oldAeval= new CFList [lengthAeval2];
+  for (int i= 0; i < lengthAeval2; i++)
+    oldAeval[i]= Aeval2[i];
+
+  getLeadingCoeffs (A, Aeval2);
+
+  CFList biFactorsLCs;
+  for (CFListIterator i= biFactors; i.hasItem(); i++)
+    biFactorsLCs.append (LC (i.getItem(), 1));
+
+  Variable w;
+  TIMING_START (abs_fac_precompute_leadcoeff);
+  CFList leadingCoeffs= precomputeLeadingCoeff (LC (A, 1), biFactorsLCs, x,
+                                          evaluation, Aeval2, lengthAeval2, w);
+
+  if (w.level() != 1)
+    changeSecondVariable (A, biFactors, evaluation, oldAeval, lengthAeval2,
+                          uniFactors, w);
+
+  CanonicalForm oldA= A;
+  CFList oldBiFactors= biFactors;
+
+  CanonicalForm LCmultiplier= leadingCoeffs.getFirst();
+  bool LCmultiplierIsConst= LCmultiplier.inCoeffDomain();
+  leadingCoeffs.removeFirst();
+
+  if (!LCmultiplierIsConst)
+    distributeLCmultiplier (A, leadingCoeffs, biFactors, evaluation,
+                            LCmultiplier);
+
+  //prepare leading coefficients
+  CFList* leadingCoeffs2= new CFList [lengthAeval2];
+  prepareLeadingCoeffs (leadingCoeffs2, A, Aeval, A.level(), leadingCoeffs,
+                        biFactors, evaluation);
+
+  CFListIterator iter;
+  CFList bufLeadingCoeffs2= leadingCoeffs2[lengthAeval2-1];
+  CFList bufBiFactors= biFactors;
+  bufA= A;
+  CanonicalForm testVars, bufLCmultiplier= LCmultiplier;
+  if (!LCmultiplierIsConst)
+  {
+    testVars= Variable (2);
+    for (int i= 0; i < lengthAeval2; i++)
+    {
+      if (!oldAeval[i].isEmpty())
+        testVars *= oldAeval[i].getFirst().mvar();
+    }
+  }
+  TIMING_END_AND_PRINT(abs_fac_precompute_leadcoeff,
+                       "time to precompute LC in abs fact: ");
+
+  TIMING_START (abs_fac_luckswang);
+  CFList bufFactors= CFList();
+  bool LCheuristic= false;
+  if (LucksWangSparseHeuristic (A, biFactors, 2, leadingCoeffs2[lengthAeval2-1],
+                                rationalFactors))
+  {
+    int check= biFactors.length();
+    int * index= new int [factors.length()];
+    CFList oldFactors= rationalFactors;
+    rationalFactors= recoverFactors (A, rationalFactors, index);
+
+    if (check == rationalFactors.length())
+    {
+      if (w.level() != 1)
+      {
+        for (iter= rationalFactors; iter.hasItem(); iter++)
+          iter.getItem()= swapvar (iter.getItem(), w, y);
+      }
+
+      for (CFListIterator iter= rationalFactors; iter.hasItem(); iter++)
+      {
+        if (totaldegree(iter.getItem())*degree (getMipo (v)) == totaldegree (G))
+        {
+          factors= CFAFList (CFAFactor (iter.getItem(), getMipo (v), 1));
+          found=true;
+          break;
+        }
+      }
+      // necessary since extension may be too large
+      if (!found)
+        factors= RothsteinTrager (A, rationalFactors, v, evaluation);
+
+      decompress (factors, N);
+      normalize (factors);
+      delete [] index;
+      delete [] Aeval2;
+      TIMING_END_AND_PRINT (abs_fac_luckswang,
+                            "time for successful LucksWang in abs fact: ");
+      return factors;
+    }
+    else if (rationalFactors.length() > 0)
+    {
+      int oneCount= 0;
+      CFList l;
+      for (int i= 0; i < check; i++)
+      {
+        if (index[i] == 1)
+        {
+          iter=biFactors;
+          for (int j=1; j <= i-oneCount; j++)
+            iter++;
+          iter.remove (1);
+          for (int j= 0; j < lengthAeval2; j++)
+          {
+            l= leadingCoeffs2[j];
+            iter= l;
+            for (int k=1; k <= i-oneCount; k++)
+              iter++;
+            iter.remove (1);
+            leadingCoeffs2[j]=l;
+          }
+          oneCount++;
+        }
+      }
+      bufFactors= rationalFactors;
+      rationalFactors= CFList();
+    }
+    else if (!LCmultiplierIsConst && rationalFactors.length() == 0)
+    {
+      LCheuristic= true;
+      rationalFactors= oldFactors;
+      CFList contents, LCs;
+      bool foundTrueMultiplier= false;
+      LCHeuristic2 (LCmultiplier,rationalFactors,leadingCoeffs2[lengthAeval2-1],
+                    contents, LCs, foundTrueMultiplier);
+      if (foundTrueMultiplier)
+      {
+          A= oldA;
+          leadingCoeffs= leadingCoeffs2[lengthAeval2-1];
+          for (int i= lengthAeval2-1; i > -1; i--)
+            leadingCoeffs2[i]= CFList();
+          prepareLeadingCoeffs (leadingCoeffs2, A, Aeval, A.level(),
+                                leadingCoeffs, biFactors, evaluation);
+      }
+      else
+      {
+        bool foundMultiplier= false;
+        LCHeuristic3 (LCmultiplier, rationalFactors, oldBiFactors, contents,
+                      oldAeval,A,leadingCoeffs2, lengthAeval2, foundMultiplier);
+        // coming from above: divide out more LCmultiplier if possible
+        if (foundMultiplier)
+        {
+          foundMultiplier= false;
+          LCHeuristic4 (oldBiFactors, oldAeval, contents, rationalFactors,
+                        testVars, lengthAeval2, leadingCoeffs2, A, LCmultiplier,
+                        foundMultiplier);
+        }
+        else
+        {
+          LCHeuristicCheck (LCs, contents, A, oldA,
+                            leadingCoeffs2[lengthAeval2-1], foundMultiplier);
+          if (!foundMultiplier && fdivides (getVars (LCmultiplier), testVars))
+          {
+            LCHeuristic (A, LCmultiplier, biFactors, leadingCoeffs2, oldAeval,
+                         lengthAeval2, evaluation, oldBiFactors);
+          }
+        }
+
+        // patch everything together again
+        leadingCoeffs= leadingCoeffs2[lengthAeval2-1];
+        for (int i= lengthAeval2-1; i > -1; i--)
+          leadingCoeffs2[i]= CFList();
+        prepareLeadingCoeffs (leadingCoeffs2, A, Aeval, A.level(),leadingCoeffs,
+                              biFactors, evaluation);
+      }
+      rationalFactors= CFList();
+      if (!fdivides (LC (oldA,1),prod (leadingCoeffs2[lengthAeval2-1])))
+      {
+        LCheuristic= false;
+        A= bufA;
+        biFactors= bufBiFactors;
+        leadingCoeffs2[lengthAeval2-1]= bufLeadingCoeffs2;
+        LCmultiplier= bufLCmultiplier;
+      }
+    }
+    else
+      rationalFactors= CFList();
+    delete [] index;
+  }
+  TIMING_END_AND_PRINT (abs_fac_luckswang, "time for LucksWang in abs fact: ");
+
+  TIMING_START (abs_fac_lcheuristic);
+  if (!LCheuristic && !LCmultiplierIsConst && bufFactors.isEmpty()
+      && fdivides (getVars (LCmultiplier), testVars))
+  {
+    LCheuristic= true;
+    LCHeuristic (A, LCmultiplier, biFactors, leadingCoeffs2, oldAeval,
+                 lengthAeval2, evaluation, oldBiFactors);
+
+    leadingCoeffs= leadingCoeffs2[lengthAeval2-1];
+    for (int i= lengthAeval2-1; i > -1; i--)
+      leadingCoeffs2[i]= CFList();
+    prepareLeadingCoeffs (leadingCoeffs2, A, Aeval, A.level(),leadingCoeffs,
+                          biFactors, evaluation);
+
+    if (!fdivides (LC (oldA,1),prod (leadingCoeffs2[lengthAeval2-1])))
+    {
+      LCheuristic= false;
+      A= bufA;
+      biFactors= bufBiFactors;
+      leadingCoeffs2[lengthAeval2-1]= bufLeadingCoeffs2;
+      LCmultiplier= bufLCmultiplier;
+    }
+  }
+  TIMING_END_AND_PRINT (abs_fac_lcheuristic,
+                        "time for Lc heuristic in abs fact: ");
+
+tryAgainWithoutHeu:
+  //shifting to zero
+  TIMING_START (abs_fac_shift_to_zero);
+  CanonicalForm denA= bCommonDen (A);
+  A *= denA;
+  A= shift2Zero (A, Aeval, evaluation);
+  A /= denA;
+
+  for (iter= biFactors; iter.hasItem(); iter++)
+    iter.getItem()= iter.getItem () (y + evaluation.getLast(), y);
+
+  for (int i= 0; i < lengthAeval2-1; i++)
+    leadingCoeffs2[i]= CFList();
+  for (iter= leadingCoeffs2[lengthAeval2-1]; iter.hasItem(); iter++)
+  {
+    iter.getItem()= shift2Zero (iter.getItem(), list, evaluation);
+    for (int i= A.level() - 4; i > -1; i--)
+    {
+      if (i + 1 == lengthAeval2-1)
+        leadingCoeffs2[i].append (iter.getItem() (0, i + 4));
+      else
+        leadingCoeffs2[i].append (leadingCoeffs2[i+1].getLast() (0, i + 4));
+    }
+  }
+  TIMING_END_AND_PRINT (abs_fac_shift_to_zero,
+                        "time to shift evaluation point to zero in abs fact: ");
+
+  CFArray Pi;
+  CFList diophant;
+  int* liftBounds= new int [A.level() - 1];
+  int liftBoundsLength= A.level() - 1;
+  for (int i= 0; i < liftBoundsLength; i++)
+    liftBounds [i]= degree (A, i + 2) + 1;
+
+  Aeval.removeFirst();
+  bool noOneToOne= false;
+
+  TIMING_START (abs_fac_cleardenom);
+  CFList commonDenominators;
+  for (iter=biFactors; iter.hasItem(); iter++)
+    commonDenominators.append (bCommonDen (iter.getItem()));
+  CanonicalForm tmp1, tmp2, tmp3=1;
+  CFListIterator iter2;
+  for (int i= 0; i < lengthAeval2; i++)
+  {
+    iter2= commonDenominators;
+    for (iter= leadingCoeffs2[i]; iter.hasItem(); iter++, iter2++)
+    {
+      tmp1= bCommonDen (iter.getItem());
+      Off (SW_RATIONAL);
+      iter2.getItem()= lcm (iter2.getItem(), tmp1);
+      On (SW_RATIONAL);
+    }
+  }
+  tmp1= prod (commonDenominators);
+  for (iter= Aeval; iter.hasItem(); iter++)
+  {
+    tmp2= bCommonDen (iter.getItem()/denA);
+    Off (SW_RATIONAL);
+    tmp3= lcm (tmp2,tmp3);
+    On (SW_RATIONAL);
+  }
+  CanonicalForm multiplier;
+  multiplier= tmp3/tmp1;
+  iter2= commonDenominators;
+  for (iter=biFactors; iter.hasItem(); iter++, iter2++)
+    iter.getItem() *= iter2.getItem()*multiplier;
+
+  for (iter= Aeval; iter.hasItem(); iter++)
+    iter.getItem() *= tmp3*power (multiplier, biFactors.length() - 1)/denA;
+
+  for (int i= 0; i < lengthAeval2; i++)
+  {
+    iter2= commonDenominators;
+    for (iter= leadingCoeffs2[i]; iter.hasItem(); iter++, iter2++)
+      iter.getItem() *= iter2.getItem()*multiplier;
+  }
+
+  TIMING_END_AND_PRINT (abs_fac_cleardenom,
+                        "time to clear denominators in abs fact: ");
+
+  TIMING_START (abs_fac_hensel_lift);
+  rationalFactors= nonMonicHenselLift (Aeval, biFactors,leadingCoeffs2,diophant,
+                               Pi, liftBounds, liftBoundsLength, noOneToOne);
+  TIMING_END_AND_PRINT (abs_fac_hensel_lift,
+                        "time for non monic hensel lifting in abs fact: ");
+
+  if (!noOneToOne)
+  {
+    int check= rationalFactors.length();
+    A= oldA;
+    TIMING_START (abs_fac_recover_factors);
+    rationalFactors= recoverFactors (A, rationalFactors, evaluation);
+    TIMING_END_AND_PRINT (abs_fac_recover_factors,
+                          "time to recover factors in abs fact: ");
+    if (check != rationalFactors.length())
+      noOneToOne= true;
+    else
+      rationalFactors= Union (rationalFactors, bufFactors);
+  }
+  if (noOneToOne)
+  {
+    if (!LCmultiplierIsConst && LCheuristic)
+    {
+      A= bufA;
+      biFactors= bufBiFactors;
+      leadingCoeffs2[lengthAeval2-1]= bufLeadingCoeffs2;
+      delete [] liftBounds;
+      LCheuristic= false;
+      goto tryAgainWithoutHeu;
+      //something probably went wrong in the heuristic
+    }
+
+    A= shift2Zero (oldA, Aeval, evaluation);
+    biFactors= oldBiFactors;
+    for (iter= biFactors; iter.hasItem(); iter++)
+      iter.getItem()= iter.getItem () (y + evaluation.getLast(), y);
+    CanonicalForm LCA= LC (Aeval.getFirst(), 1);
+    CanonicalForm yToLift= power (y, lift);
+    CFListIterator i= biFactors;
+    lift= degree (i.getItem(), 2) + degree (LC (i.getItem(), 1)) + 1;
+    i++;
+
+    for (; i.hasItem(); i++)
+      lift= tmax (lift, degree (i.getItem(), 2)+degree (LC (i.getItem(), 1))+1);
+
+    lift= tmax (degree (Aeval.getFirst() , 2) + 1, lift);
+
+    i= biFactors;
+    yToLift= power (y, lift);
+    CanonicalForm dummy;
+    for (; i.hasItem(); i++)
+    {
+      LCA= LC (i.getItem(), 1);
+      extgcd (LCA, yToLift, LCA, dummy);
+      i.getItem()= mod (i.getItem()*LCA, yToLift);
+    }
+
+    liftBoundsLength= F.level() - 1;
+    liftBounds= liftingBounds (A, lift);
+
+    CFList MOD;
+    bool earlySuccess;
+    CFList earlyFactors;
+    ExtensionInfo info= ExtensionInfo (false);
+    CFList liftedFactors;
+    TIMING_START (abs_fac_hensel_lift);
+    liftedFactors= henselLiftAndEarly
+                   (A, MOD, liftBounds, earlySuccess, earlyFactors,
+                    Aeval, biFactors, evaluation, info);
+    TIMING_END_AND_PRINT (abs_fac_hensel_lift,
+                          "time for hensel lifting in abs fact: ");
+
+    TIMING_START (abs_fac_factor_recombination);
+    rationalFactors= factorRecombination (A, liftedFactors, MOD);
+    TIMING_END_AND_PRINT (abs_fac_factor_recombination,
+                          "time for factor recombination in abs fact: ");
+
+    if (earlySuccess)
+      rationalFactors= Union (rationalFactors, earlyFactors);
+
+    for (CFListIterator i= rationalFactors; i.hasItem(); i++)
+    {
+      int kk= Aeval.getLast().level();
+      for (CFListIterator j= evaluation; j.hasItem(); j++, kk--)
+      {
+        if (i.getItem().level() < kk)
+          continue;
+       i.getItem()= i.getItem() (Variable (kk) - j.getItem(), kk);
+      }
+    }
+  }
+
+  if (w.level() != 1)
+  {
+    for (CFListIterator iter= rationalFactors; iter.hasItem(); iter++)
+      iter.getItem()= swapvar (iter.getItem(), w, y);
+  }
+
+  for (CFListIterator iter= rationalFactors; iter.hasItem(); iter++)
+  {
+    if (totaldegree (iter.getItem())*degree (getMipo (v)) == totaldegree (G))
+    {
+      factors= CFAFList (CFAFactor (iter.getItem(), getMipo (v), 1));
+      found= true;
+      break;
+    }
+  }
+
+  // necessary since extension may be too large
+  if (!found)
+    factors= RothsteinTrager (A, rationalFactors, v, evaluation);
+
+  decompress (factors, N);
+  if (isOn (SW_RATIONAL))
+    normalize (factors);
+
+  delete [] leadingCoeffs2;
+  delete [] oldAeval;
+  delete [] Aeval2;
+  delete[] liftBounds;
+
+  return factors;
+}
+
+#endif
diff --git a/factory/facAbsFact.h b/factory/facAbsFact.h
new file mode 100644
index 0000000..c5d61f1
--- /dev/null
+++ b/factory/facAbsFact.h
@@ -0,0 +1,50 @@
+/*****************************************************************************\
+ * Computer Algebra System SINGULAR
+\*****************************************************************************/
+/** @file facAbsFact.h
+ *
+ * absolute multivariate factorization over Q
+ *
+ * @author Martin Lee
+ *
+ **/
+/*****************************************************************************/
+
+#ifndef FAC_ABS_FACT_H
+#define FAC_ABS_FACT_H
+
+#include "facAbsBiFact.h"
+
+#ifdef HAVE_NTL
+/// main absolute factorization routine, expects poly which is
+/// irreducible over Q
+///
+/// @return absFactorizeMain returns a list whose entries contain three
+///         entities:
+///         an absolute irreducible factor, an irreducible univariate polynomial
+///         that defines the minimal field extension over which the irreducible
+///         factor is defined (note: in case the factor is already defined over
+///         Q[t]/(t), 1 is returned as defining poly), and the
+///         multiplicity of the absolute irreducible factor
+CFAFList absFactorizeMain (const CanonicalForm& F ///<[in] irred poly over Q
+                          );
+#endif
+
+/*BEGINPUBLIC*/
+#ifdef HAVE_NTL
+/// absolute factorization of a multivariate poly over Q
+///
+/// @return absFactorize returns a list whose entries contain three
+///         entities:
+///         an absolute irreducible factor, an irreducible univariate polynomial
+///         that defines the minimal field extension over which the irreducible
+///         factor is defined (note: in case the factor is already defined over
+///         Q[t]/(t), 1 is returned), and the multiplicity of the
+///         absolute irreducible factor
+CFAFList absFactorize (const CanonicalForm& G ///<[in] poly over Q
+                      );
+#endif
+/*ENDPUBLIC*/
+
+
+#endif
diff --git a/factory/facAlgExt.cc b/factory/facAlgExt.cc
new file mode 100644
index 0000000..14c0a65
--- /dev/null
+++ b/factory/facAlgExt.cc
@@ -0,0 +1,404 @@
+// -*- c++ -*-
+//*****************************************************************************
+/** @file facAlgExt.cc
+ *
+ * Univariate factorization over algebraic extension of Q using Trager's
+ * algorithm
+ *
+ * @par Copyright:
+ *   (c) by The SINGULAR Team, see LICENSE file
+ *
+ * @author Martin Lee
+**/
+//*****************************************************************************
+
+
+#include "config.h"
+
+
+#include "cf_assert.h"
+#include "debug.h"
+#include "timing.h"
+
+#include "canonicalform.h"
+#include "cf_random.h"
+#include "cf_algorithm.h"
+#include "facFqBivarUtil.h"
+#include "facAlgExt.h"
+#include "cfModResultant.h"
+#include "fac_sqrfree.h"
+
+TIMING_DEFINE_PRINT(fac_alg_resultant)
+TIMING_DEFINE_PRINT(fac_alg_norm)
+TIMING_DEFINE_PRINT(fac_alg_factor_norm)
+TIMING_DEFINE_PRINT(fac_alg_gcd)
+TIMING_DEFINE_PRINT(fac_alg_sqrf)
+TIMING_DEFINE_PRINT(fac_alg_factor_sqrf)
+TIMING_DEFINE_PRINT(fac_alg_time_shift)
+
+// squarefree part of F
+CanonicalForm
+uniSqrfPart (const CanonicalForm& F)
+{
+  ASSERT (F.isUnivariate(), "univariate input expected");
+  ASSERT (getCharacteristic() == 0, "characteristic 0 expected");
+  CanonicalForm G= deriv (F, F.mvar());
+  G= gcd (F, G);
+  return F/G;
+}
+
+CanonicalForm Norm (const CanonicalForm& F, const Variable& alpha)
+{
+  Variable x= Variable (F.level() + 1);
+  Variable y= F.mvar();
+  CanonicalForm g= F (x, alpha);
+  CanonicalForm mipo= getMipo (alpha);
+  mipo= mipo (x, alpha);
+  mipo *= bCommonDen (mipo);
+
+  int degg= degree (g);
+  int degmipo= degree (mipo);
+  CanonicalForm norm;
+  TIMING_START (fac_alg_resultant);
+#ifdef HAVE_NTL
+  if (degg >= 8 || degmipo >= 8)
+    norm= resultantZ (g, mipo, x);
+  else
+#endif
+    norm= resultant (g, mipo, x);
+  TIMING_END_AND_PRINT (fac_alg_resultant, "time to compute resultant0: ");
+  return norm;
+}
+
+// i is an integer such that Norm (F (x-i*alpha)) is squarefree
+CanonicalForm sqrfNorm (const CanonicalForm& F, const Variable& alpha, int& i)
+{
+  Variable x= Variable (F.level() + 1);
+  Variable y= F.mvar();
+  CanonicalForm g= F (x, alpha);
+  CanonicalForm mipo= getMipo (alpha);
+  mipo= mipo (x, alpha);
+  mipo *= bCommonDen (mipo);
+
+  int degg= degree (g);
+  int degmipo= degree (mipo);
+  CanonicalForm norm;
+  TIMING_START (fac_alg_resultant);
+#ifdef HAVE_NTL
+  if (degg >= 8 || degmipo >= 8)
+    norm= resultantZ (g, mipo, x);
+  else
+#endif
+    norm= resultant (g, mipo, x);
+  TIMING_END_AND_PRINT (fac_alg_resultant, "time to compute resultant0: ");
+
+  i= 0;
+  int k;
+  if (degree (gcd (deriv (norm, y), norm)) <= 0)
+    return norm;
+  i= 1;
+  do
+  {
+    k= 1;
+    while (k < 3)
+    {
+      if (k == 1)
+      {
+        g= F (y - i*alpha, y);
+        g *= bCommonDen (g);
+        TIMING_START (fac_alg_resultant);
+#ifdef HAVE_NTL
+        if (degg >= 8 || degmipo >= 8)
+          norm= resultantZ (g (x, alpha), mipo, x);
+        else
+#endif
+          norm= resultant (g (x, alpha), mipo, x);
+        TIMING_END_AND_PRINT (fac_alg_resultant,"time to compute resultant1: ");
+      }
+      else
+      {
+        g= F (y + i*alpha, y);
+        g *= bCommonDen (g);
+        TIMING_START (fac_alg_resultant);
+#ifdef HAVE_NTL
+        if (degg >= 8 || degmipo >= 8)
+          norm= resultantZ (g (x, alpha), mipo, x);
+        else
+#endif
+          norm= resultant (g (x, alpha), mipo, x);
+        TIMING_END_AND_PRINT (fac_alg_resultant,"time to compute resultant2: ");
+      }
+      if (degree (gcd (deriv (norm, y), norm)) <= 0)
+      {
+        if (k == 2)
+          i= -i;
+        return norm;
+      }
+      k++;
+    }
+    i++;
+  } while (1);
+}
+
+CFList
+AlgExtSqrfFactorize (const CanonicalForm& F, const Variable& alpha)
+{
+  ASSERT (F.isUnivariate(), "univariate input expected");
+  ASSERT (getCharacteristic() == 0, "characteristic 0 expected");
+
+  bool save_rat=!isOn (SW_RATIONAL);
+  On (SW_RATIONAL);
+  CanonicalForm f= F*bCommonDen (F);
+  Variable y= f.mvar();
+  int shift= 0, k= 0, count= 0;
+  CanonicalForm norm, buf, factor, oldF;
+  CFFList normFactors;
+  bool save_sort= !isOn (SW_USE_NTL_SORT);
+  CFList factors, tmp, tmp2;
+  CFFListIterator i;
+  CFListIterator iter;
+  bool shiftBuf= false;
+
+  tmp.append (f);
+  do
+  {
+    tmp2= CFList();
+    for (iter= tmp; iter.hasItem(); iter++)
+    {
+      oldF= iter.getItem()*bCommonDen (iter.getItem());
+      if (shift == 0)
+        f= oldF;
+      else
+      {
+        f= oldF (y - shift*alpha, y);
+        f *= bCommonDen (f);
+      }
+      TIMING_START (fac_alg_norm);
+      norm= Norm (f, alpha);
+      TIMING_END_AND_PRINT (fac_alg_norm, "time to compute sqrf norm: ");
+      ASSERT (degree (norm, alpha) <= 0, "wrong norm computed");
+
+      TIMING_START (fac_alg_factor_norm);
+      On (SW_USE_NTL_SORT);
+      normFactors= factorize (norm);
+      if (save_sort)
+        Off (SW_USE_NTL_SORT);
+      TIMING_END_AND_PRINT (fac_alg_factor_norm, "time to factor norm: ");
+
+      if (normFactors.getFirst().factor().inCoeffDomain())
+        normFactors.removeFirst();
+      if (normFactors.length() < 2 && normFactors.getLast().exp() == 1)
+      {
+        factors.append (oldF);
+        continue;
+      }
+
+      i= normFactors;
+      shiftBuf= false;
+      if (!(normFactors.length() == 2 &&
+            degree (i.getItem().factor()) <= degree (f)))
+      {
+        TIMING_START (fac_alg_time_shift);
+        if (shift != 0)
+          buf= f;
+        else
+          buf= oldF;
+        shiftBuf= true;
+        TIMING_END_AND_PRINT (fac_alg_time_shift, "time to shift: ");
+      }
+      else
+        buf= oldF;
+
+      count= 0;
+      for (; i.hasItem(); i++)
+      {
+        TIMING_START (fac_alg_gcd);
+        if (shiftBuf)
+          factor= gcd (buf, i.getItem().factor());
+        else
+        {
+          if (shift == 0)
+            factor= gcd (buf, i.getItem().factor());
+          else
+            factor= gcd (buf, i.getItem().factor() (y + shift*alpha, y));
+        }
+        buf /= factor;
+        if (shiftBuf)
+        {
+          if (shift != 0)
+            factor= factor (y + shift*alpha, y);
+        }
+        TIMING_END_AND_PRINT (fac_alg_gcd, "time to recover factors: ");
+        if (i.getItem().exp() == 1 || degree (factor) == 1)
+          factors.append (factor);
+        else
+          tmp2.append (factor);
+        if (buf.inCoeffDomain())
+          break;
+        count++;
+        if (normFactors.length() - 1 == count)
+        {
+          if (shiftBuf)
+          {
+            if (normFactors.getLast().exp() == 1)
+              factors.append (buf (y + shift*alpha, y));
+            else
+              tmp2.append (buf (y + shift*alpha, y));
+          }
+          else
+          {
+            if (normFactors.getLast().exp() == 1)
+              factors.append (buf);
+            else
+              tmp2.append (buf);
+          }
+          buf= 1;
+          break;
+        }
+      }
+    }
+    k++;
+    if (shift == 0)
+    {
+      shift++;
+      k= 1;
+    }
+    if (k == 2)
+      shift= -shift;
+    if (k == 3)
+    {
+      shift= -shift;
+      shift++;
+      k= 1;
+    }
+    tmp= tmp2;
+  }
+  while (!tmp.isEmpty());
+
+  if (save_rat) Off(SW_RATIONAL);
+  return factors;
+}
+
+
+/*CFList
+AlgExtSqrfFactorize (const CanonicalForm& F, const Variable& alpha)
+{
+  ASSERT (F.isUnivariate(), "univariate input expected");
+  ASSERT (getCharacteristic() == 0, "characteristic 0 expected");
+
+  bool save_rat=!isOn (SW_RATIONAL);
+  On (SW_RATIONAL);
+  CanonicalForm f= F*bCommonDen (F);
+  int shift;
+  TIMING_START (fac_alg_norm);
+  CanonicalForm norm= sqrfNorm (f, alpha, shift);
+  TIMING_END_AND_PRINT (fac_alg_norm, "time to compute sqrf norm: ");
+  ASSERT (degree (norm, alpha) <= 0, "wrong norm computed");
+  TIMING_START (fac_alg_factor_norm);
+  bool save_sort= !isOn (SW_USE_NTL_SORT);
+  On (SW_USE_NTL_SORT);
+  CFFList normFactors= factorize (norm);
+  if (save_sort)
+    Off (SW_USE_NTL_SORT);
+  TIMING_END_AND_PRINT (fac_alg_factor_norm, "time to factor norm: ");
+  CFList factors;
+  if (normFactors.length() <= 2)
+  {
+    if (save_rat) Off(SW_RATIONAL);
+    return CFList (F);
+  }
+
+  normFactors.removeFirst();
+  CFFListIterator i= normFactors;
+  CanonicalForm buf;
+  bool shiftBuf= false;
+  if (!(normFactors.length() == 2 && degree (i.getItem().factor()) <= degree (f)))
+  {
+    TIMING_START (fac_alg_time_shift);
+    if (shift != 0)
+      buf= f (f.mvar() - shift*alpha, f.mvar());
+    else
+      buf= f;
+    shiftBuf= true;
+    TIMING_END_AND_PRINT (fac_alg_time_shift, "time to shift: ");
+  }
+  else
+    buf= f;
+  CanonicalForm factor;
+  int count= 0;
+  for (; i.hasItem(); i++)
+  {
+    ASSERT (i.getItem().exp() == 1, "norm not squarefree");
+    TIMING_START (fac_alg_gcd);
+    if (shiftBuf)
+      factor= gcd (buf, i.getItem().factor());
+    else
+    {
+      if (shift == 0)
+        factor= gcd (buf, i.getItem().factor());
+      else
+        factor= gcd (buf, i.getItem().factor() (f.mvar() + shift*alpha, f.mvar()));
+    }
+    buf /= factor;
+    if (shiftBuf)
+    {
+      if (shift != 0)
+        factor= factor (f.mvar() + shift*alpha, f.mvar());
+    }
+    TIMING_END_AND_PRINT (fac_alg_gcd, "time to recover factors: ");
+    factors.append (factor);
+    count++;
+    if (normFactors.length() - 1 == count)
+    {
+      if (shiftBuf)
+        factors.append (buf (f.mvar() + shift*alpha, f.mvar()));
+      else
+        factors.append (buf);
+      buf= 1;
+      break;
+    }
+  }
+  ASSERT (degree (buf) <= 0, "incomplete factorization");
+  if (save_rat) Off(SW_RATIONAL);
+  return factors;
+}*/
+
+CFFList
+AlgExtFactorize (const CanonicalForm& F, const Variable& alpha)
+{
+  ASSERT (F.isUnivariate(), "univariate input expected");
+  ASSERT (getCharacteristic() == 0, "characteristic 0 expected");
+
+
+  if (F.inCoeffDomain())
+    return CFFList (CFFactor (F, 1));
+
+  bool save_rat=!isOn (SW_RATIONAL);
+  On (SW_RATIONAL);
+  TIMING_START (fac_alg_sqrf);
+  CFFList sqrf= sqrFreeZ (F);
+  TIMING_END_AND_PRINT (fac_alg_sqrf, "time for sqrf factors in Q(a)[x]: ");
+  CFList factorsSqrf;
+  CFFList factors;
+  CFListIterator j;
+
+  CanonicalForm lcinv;
+  for (CFFListIterator i= sqrf; i.hasItem(); i++)
+  {
+    if (i.getItem().factor().inCoeffDomain()) continue;
+    TIMING_START (fac_alg_factor_sqrf);
+    factorsSqrf= AlgExtSqrfFactorize (i.getItem().factor(), alpha);
+    TIMING_END_AND_PRINT (fac_alg_factor_sqrf,
+                          "time to factor sqrf factors in Q(a)[x]: ");
+    for (j= factorsSqrf; j.hasItem(); j++)
+    {
+      lcinv= 1/Lc (j.getItem());
+      factors.append (CFFactor (j.getItem()*lcinv, i.getItem().exp()));
+    }
+  }
+
+  factors.insert (CFFactor (Lc(F), 1));
+  if (save_rat) Off(SW_RATIONAL);
+  return factors;
+}
+
diff --git a/factory/facAlgExt.h b/factory/facAlgExt.h
new file mode 100644
index 0000000..81e6df2
--- /dev/null
+++ b/factory/facAlgExt.h
@@ -0,0 +1,41 @@
+/*****************************************************************************\
+ * Computer Algebra System SINGULAR
+\*****************************************************************************/
+/** @file facAlgExt.h
+ *
+ * Univariate factorization over algebraic extension of Q using Trager's
+ * algorithm
+ *
+ * @par Copyright:
+ *   (c) by The SINGULAR Team, see LICENSE file
+ *
+ * @author Martin Lee
+**/
+//*****************************************************************************
+
+#ifndef FAC_ALG_EXT_H
+#define FAC_ALG_EXT_H
+
+#include "cf_assert.h"
+
+#include "canonicalform.h"
+
+///factorize a univariate squarefree polynomial over algebraic extension of Q
+///
+/// @return @a AlgExtSqrfFactorize returns a list of factors of F
+CFList
+AlgExtSqrfFactorize (const CanonicalForm& F, ///<[in] a univariate squarefree
+                                             ///< polynomial
+                     const Variable& alpha   ///<[in] an algebraic variable
+                    );
+
+/// factorize a univariate polynomial over algebraic extension of Q
+///
+/// @return @a AlgExtFactorize returns a list of factors of F with multiplicity
+CFFList
+AlgExtFactorize (const CanonicalForm& F, ///<[in] a univariate polynomial
+                 const Variable& alpha   ///<[in] an algebraic variable
+                );
+
+#endif
+
diff --git a/factory/facAlgFunc.cc b/factory/facAlgFunc.cc
new file mode 100644
index 0000000..35dabd7
--- /dev/null
+++ b/factory/facAlgFunc.cc
@@ -0,0 +1,1076 @@
+/*****************************************************************************\
+ * Computer Algebra System SINGULAR
+\*****************************************************************************/
+/** @file facAlgFunc.cc
+ *
+ * This file provides functions to factorize polynomials over alg. function
+ * fields
+ *
+ * @note some of the code is code from libfac or derived from code from libfac.
+ * Libfac is written by M. Messollen. See also COPYING for license information
+ * and README for general information on characteristic sets.
+ *
+ * ABSTRACT: Descriptions can be found in B. Trager "Algebraic Factoring and
+ * Rational Function Integration" and A. Steel "Conquering Inseparability:
+ * Primary decomposition and multivariate factorization over algebraic function
+ * fields of positive characteristic"
+ *
+ * @author Martin Lee
+ *
+ **/
+/*****************************************************************************/
+
+#include "config.h"
+
+#include "cf_assert.h"
+#include "debug.h"
+
+#include "cf_generator.h"
+#include "cf_iter.h"
+#include "cf_util.h"
+#include "cf_algorithm.h"
+#include "templates/ftmpl_functions.h"
+#include "cf_map.h"
+#include "cfModResultant.h"
+#include "cfCharSets.h"
+#include "facAlgFunc.h"
+#include "facAlgFuncUtil.h"
+
+void out_cf(const char *s1,const CanonicalForm &f,const char *s2);
+
+CanonicalForm
+alg_content (const CanonicalForm& f, const CFList& as)
+{
+  if (!f.inCoeffDomain())
+  {
+    CFIterator i= f;
+    CanonicalForm result= abs (i.coeff());
+    i++;
+    while (i.hasTerms() && !result.isOne())
+    {
+      result= alg_gcd (i.coeff(), result, as);
+      i++;
+    }
+    return result;
+  }
+
+  return abs (f);
+}
+
+CanonicalForm
+alg_gcd (const CanonicalForm & fff, const CanonicalForm &ggg, const CFList &as)
+{
+  if (fff.inCoeffDomain() || ggg.inCoeffDomain())
+    return 1;
+  CanonicalForm f=fff;
+  CanonicalForm g=ggg;
+  f=Prem(f,as);
+  g=Prem(g,as);
+  if ( f.isZero() )
+  {
+    if ( g.lc().sign() < 0 ) return -g;
+    else                     return g;
+  }
+  else  if ( g.isZero() )
+  {
+    if ( f.lc().sign() < 0 ) return -f;
+    else                     return f;
+  }
+
+  int v= as.getLast().level();
+  if (f.level() <= v || g.level() <= v)
+    return 1;
+
+  CanonicalForm res;
+
+  // does as appear in f and g ?
+  bool has_alg_var=false;
+  for ( CFListIterator j=as;j.hasItem(); j++ )
+  {
+    Variable v=j.getItem().mvar();
+    if (hasVar (f, v))
+      has_alg_var=true;
+    if (hasVar (g, v))
+      has_alg_var=true;
+  }
+  if (!has_alg_var)
+  {
+    /*if ((hasAlgVar(f))
+    || (hasAlgVar(g)))
+    {
+      Varlist ord;
+      for ( CFListIterator j=as;j.hasItem(); j++ )
+        ord.append(j.getItem().mvar());
+      res=algcd(f,g,as,ord);
+    }
+    else*/
+    if (!hasAlgVar (f) && !hasAlgVar (g))
+      return res=gcd(f,g);
+  }
+
+  int mvf=f.level();
+  int mvg=g.level();
+  if (mvg > mvf)
+  {
+    CanonicalForm tmp=f; f=g; g=tmp;
+    int tmp2=mvf; mvf=mvg; mvg=tmp2;
+  }
+  if (g.inBaseDomain() || f.inBaseDomain())
+    return CanonicalForm(1);
+
+  CanonicalForm c_f= alg_content (f, as);
+
+  if (mvf != mvg)
+  {
+    res= alg_gcd (g, c_f, as);
+    return res;
+  }
+  Variable x= f.mvar();
+
+  // now: mvf==mvg, f.level()==g.level()
+  CanonicalForm c_g= alg_content (g, as);
+
+  int delta= degree (f) - degree (g);
+
+  f= divide (f, c_f, as);
+  g= divide (g, c_g, as);
+
+  // gcd of contents
+  CanonicalForm c_gcd= alg_gcd (c_f, c_g, as);
+  CanonicalForm tmp;
+
+  if (delta < 0)
+  {
+    tmp= f;
+    f= g;
+    g= tmp;
+    delta= -delta;
+  }
+
+  CanonicalForm r= 1;
+
+  while (degree (g, x) > 0)
+  {
+    r= Prem (f, g);
+    r= Prem (r, as);
+    if (!r.isZero())
+    {
+      r= divide (r, alg_content (r,as), as);
+      r /= vcontent (r,Variable (v+1));
+    }
+    f= g;
+    g= r;
+  }
+
+  if (degree (g, x) == 0)
+    return c_gcd;
+
+  c_f= alg_content (f, as);
+
+  f= divide (f, c_f, as);
+
+  f *= c_gcd;
+  f /= vcontent (f, Variable (v+1));
+
+  return f;
+}
+
+static CanonicalForm
+resultante (const CanonicalForm & f, const CanonicalForm& g, const Variable & v)
+{
+  bool on_rational = isOn(SW_RATIONAL);
+  if (!on_rational && getCharacteristic() == 0)
+    On(SW_RATIONAL);
+  CanonicalForm cd = bCommonDen( f );
+  CanonicalForm fz = f * cd;
+  cd = bCommonDen( g );
+  CanonicalForm gz = g * cd;
+  if (!on_rational && getCharacteristic() == 0)
+    Off(SW_RATIONAL);
+  CanonicalForm result;
+#ifdef HAVE_NTL
+  if (getCharacteristic() == 0)
+    result= resultantZ (fz, gz,v);
+  else
+#endif
+    result= resultant (fz,gz,v);
+
+  return result;
+}
+
+/// compute the norm R of f over PPalpha, g= f (x-s*alpha)
+/// if proof==true, R is squarefree and if in addition getCharacteristic() > 0
+/// the squarefree factors of R are returned.
+/// Based on Trager's sqrf_norm algorithm.
+static CFFList
+norm (const CanonicalForm & f, const CanonicalForm & PPalpha,
+      CFGenerator & myrandom, CanonicalForm & s, CanonicalForm & g,
+      CanonicalForm & R, bool proof)
+{
+  Variable y= PPalpha.mvar(), vf= f.mvar();
+  CanonicalForm temp, Palpha= PPalpha, t;
+  int sqfreetest= 0;
+  CFFList testlist;
+  CFFListIterator i;
+
+  if (proof)
+  {
+    myrandom.reset();
+    s= myrandom.item();
+    g= f;
+    R= CanonicalForm(0);
+  }
+  else
+  {
+    if (getCharacteristic() == 0)
+      t= CanonicalForm (mapinto (myrandom.item()));
+    else
+      t= CanonicalForm (myrandom.item());
+    s= t;
+    g= f (vf - t*Palpha.mvar(), vf);
+  }
+
+  // Norm, resultante taken with respect to y
+  while (!sqfreetest)
+  {
+    R= resultante (Palpha, g, y);
+    R= R* bCommonDen(R);
+    R /= content (R);
+    if (proof)
+    {
+      // sqfree check ; R is a polynomial in K[x]
+      if (getCharacteristic() == 0)
+      {
+        temp= gcd (R, R.deriv (vf));
+        if (degree(temp,vf) != 0 || temp == temp.genZero())
+          sqfreetest= 0;
+        else
+          sqfreetest= 1;
+      }
+      else
+      {
+        Variable X;
+        testlist= sqrFree (R);
+
+        if (testlist.getFirst().factor().inCoeffDomain())
+          testlist.removeFirst();
+        sqfreetest= 1;
+        for (i= testlist; i.hasItem(); i++)
+        {
+          if (i.getItem().exp() > 1 && degree (i.getItem().factor(),R.mvar()) > 0)
+          {
+            sqfreetest= 0;
+            break;
+          }
+        }
+      }
+      if (!sqfreetest)
+      {
+        myrandom.next();
+        if (getCharacteristic() == 0)
+          t= CanonicalForm (mapinto (myrandom.item()));
+        else
+          t= CanonicalForm (myrandom.item());
+        s= t;
+        g= f (vf - t*Palpha.mvar(), vf);
+      }
+    }
+    else
+      break;
+  }
+  return testlist;
+}
+
+/// see @a norm, R is guaranteed to be squarefree
+/// Based on Trager's sqrf_norm algorithm.
+static CFFList
+sqrfNorm (const CanonicalForm & f, const CanonicalForm & PPalpha,
+          const Variable & Extension, CanonicalForm & s,  CanonicalForm & g,
+          CanonicalForm & R)
+{
+  CFFList result;
+  if (getCharacteristic() == 0)
+  {
+    IntGenerator myrandom;
+    result= norm (f, PPalpha, myrandom, s, g, R, true);
+  }
+  else if (degree (Extension) > 0)
+  {
+    AlgExtGenerator myrandom (Extension);
+    result= norm (f, PPalpha, myrandom, s, g, R, true);
+  }
+  else
+  {
+    FFGenerator myrandom;
+    result= norm (f, PPalpha, myrandom, s, g, R, true);
+  }
+  return result;
+}
+
+// calculate a "primitive element"
+// K must have more than S elements (-> getDegOfExt)
+static CFList
+simpleExtension (CFList& backSubst, const CFList & Astar,
+                 const Variable & Extension, bool& isFunctionField,
+                 CanonicalForm & R)
+{
+  CFList Returnlist, Bstar= Astar;
+  CanonicalForm s, g, ra, rb, oldR, h, denra, denrb= 1;
+  Variable alpha;
+  CFList tmp;
+
+  bool isRat= isOn (SW_RATIONAL);
+
+  CFListIterator j;
+  if (Astar.length() == 1)
+  {
+    R= Astar.getFirst();
+    rb= R.mvar();
+  }
+  else
+  {
+    R=Bstar.getFirst();
+    Bstar.removeFirst();
+    for (CFListIterator i= Bstar; i.hasItem(); i++)
+    {
+      j= i;
+      j++;
+      if (getCharacteristic() == 0)
+        Off (SW_RATIONAL);
+      R /= icontent (R);
+      if (getCharacteristic() == 0)
+        On (SW_RATIONAL);
+      oldR= R;
+      //TODO normalize i.getItem over K(R)?
+      (void) sqrfNorm (i.getItem(), R, Extension, s, g, R);
+
+      backSubst.insert (s);
+
+      if (getCharacteristic() == 0)
+        Off (SW_RATIONAL);
+      R /= icontent (R);
+
+      if (getCharacteristic() == 0)
+        On (SW_RATIONAL);
+
+      if (!isFunctionField)
+      {
+        alpha= rootOf (R);
+        h= replacevar (g, g.mvar(), alpha);
+        if (getCharacteristic() == 0)
+          On (SW_RATIONAL); //needed for GCD
+        h= gcd (h, oldR);
+        h /= Lc (h);
+        ra= -h[0];
+        ra= replacevar(ra, alpha, g.mvar());
+        rb= R.mvar()-s*ra;
+        for (; j.hasItem(); j++)
+        {
+          j.getItem()= j.getItem() (rb, i.getItem().mvar());
+          j.getItem()= j.getItem() (ra, oldR.mvar());
+        }
+        prune (alpha);
+      }
+      else
+      {
+        if (getCharacteristic() == 0)
+          On (SW_RATIONAL);
+        Variable v= Variable (tmax (g.level(), oldR.level()) + 1);
+        h= swapvar (g, oldR.mvar(), v);
+        tmp= CFList (R);
+        h= alg_gcd (h, swapvar (oldR, oldR.mvar(), v), tmp);
+
+        CanonicalForm numinv, deninv;
+        numinv= QuasiInverse (tmp.getFirst(), LC (h), tmp.getFirst().mvar());
+        h *= numinv;
+        h= Prem (h, tmp);
+        deninv= LC(h);
+
+        ra= -h[0];
+        denra= gcd (ra, deninv);
+        ra /= denra;
+        denra= deninv/denra;
+        rb= R.mvar()*denra-s*ra;
+        denrb= denra;
+        for (; j.hasItem(); j++)
+        {
+          CanonicalForm powdenra= power (denra, degree (j.getItem(),
+                                         i.getItem().mvar()));
+          j.getItem()= evaluate (j.getItem(), rb, denrb, powdenra,
+                                 i.getItem().mvar());
+          powdenra= power (denra, degree (j.getItem(), oldR.mvar()));
+          j.getItem()= evaluate (j.getItem(),ra, denra, powdenra, oldR.mvar());
+
+        }
+      }
+
+      Returnlist.append (ra);
+      if (isFunctionField)
+        Returnlist.append (denra);
+    }
+  }
+  Returnlist.append (rb);
+  if (isFunctionField)
+    Returnlist.append (denrb);
+
+  if (isRat && getCharacteristic() == 0)
+    On (SW_RATIONAL);
+  else if (!isRat && getCharacteristic() == 0)
+    Off (SW_RATIONAL);
+
+  return Returnlist;
+}
+
+/// Trager's algorithm, i.e. convert to one field extension and
+/// factorize over this field extension
+static CFFList
+Trager (const CanonicalForm & F, const CFList & Astar,
+        const Variable & vminpoly, const CFList & as, bool isFunctionField)
+{
+  bool isRat= isOn (SW_RATIONAL);
+  CFFList L, normFactors, tmp;
+  CFFListIterator iter, iter2;
+  CanonicalForm R, Rstar, s, g, h, f= F;
+  CFList substlist, backSubsts;
+
+  substlist= simpleExtension (backSubsts, Astar, vminpoly, isFunctionField,
+                              Rstar);
+
+  f= subst (f, Astar, substlist, Rstar, isFunctionField);
+
+  Variable alpha;
+  if (!isFunctionField)
+  {
+    alpha= rootOf (Rstar);
+    g= replacevar (f, Rstar.mvar(), alpha);
+
+    if (!isRat && getCharacteristic() == 0)
+      On (SW_RATIONAL);
+    tmp= factorize (g, alpha); // factorization over number field
+
+    for (iter= tmp; iter.hasItem(); iter++)
+    {
+      h= iter.getItem().factor();
+      if (!h.inCoeffDomain())
+      {
+        h= replacevar (h, alpha, Rstar.mvar());
+        h *= bCommonDen(h);
+        h= backSubst (h, backSubsts, Astar);
+        h= Prem (h, as);
+        L.append (CFFactor (h, iter.getItem().exp()));
+      }
+    }
+    if (!isRat && getCharacteristic() == 0)
+      Off (SW_RATIONAL);
+    prune (alpha);
+    return L;
+  }
+  // after here we are over an extension of a function field
+
+  // make quasi monic
+  CFList Rstarlist= CFList (Rstar);
+  int algExtLevel= Astar.getLast().level(); //highest level of algebraic variables
+  CanonicalForm numinv;
+  if (!isRat && getCharacteristic() == 0)
+    On (SW_RATIONAL);
+  numinv= QuasiInverse (Rstar, alg_LC (f, algExtLevel), Rstar.mvar());
+
+  f *= numinv;
+  f= Prem (f, Rstarlist);
+  f /= vcontent (f, Rstar.mvar());
+  // end quasi monic
+
+  if (degree (f) == 1)
+  {
+    f= backSubst (f, backSubsts, Astar);
+    f *= bCommonDen (f);
+    f= Prem (f, as);
+    f /= vcontent (f, as.getFirst().mvar());
+
+    return CFFList (CFFactor (f, 1));
+  }
+
+  CFGenerator * Gen;
+  if (getCharacteristic() == 0)
+    Gen= CFGenFactory::generate();
+  else if (degree (vminpoly) > 0)
+    Gen= AlgExtGenerator (vminpoly).clone();
+  else
+    Gen= CFGenFactory::generate();
+
+  CFFList LL= CFFList (CFFactor (f, 1));
+
+  Variable X;
+  do
+  {
+    tmp= CFFList();
+    for (iter= LL; iter.hasItem(); iter++)
+    {
+      f= iter.getItem().factor();
+      (void) norm (f, Rstar, *Gen, s, g, R, false);
+
+      if (hasFirstAlgVar (R, X))
+        normFactors= factorize (R, X);
+      else
+        normFactors= factorize (R);
+
+      if (normFactors.getFirst().factor().inCoeffDomain())
+        normFactors.removeFirst();
+      if (normFactors.length() < 1 || (normFactors.length() == 1 && normFactors.getLast().exp() == 1))
+      {
+        f= backSubst (f, backSubsts, Astar);
+        f *= bCommonDen (f);
+        f= Prem (f, as);
+        f /= vcontent (f, as.getFirst().mvar());
+
+        L.append (CFFactor (f, 1));
+      }
+      else
+      {
+        g= f;
+        int count= 0;
+        for (iter2= normFactors; iter2.hasItem(); iter2++)
+        {
+          CanonicalForm fnew= iter2.getItem().factor();
+          if (fnew.level() <= Rstar.level()) //factor is a constant from the function field
+            continue;
+          else
+          {
+            fnew= fnew (g.mvar() + s*Rstar.mvar(), g.mvar());
+            fnew= Prem (fnew, CFList (Rstar));
+          }
+
+          h= alg_gcd (g, fnew, Rstarlist);
+          numinv= QuasiInverse (Rstar, alg_LC (h, algExtLevel), Rstar.mvar());
+          h *= numinv;
+          h= Prem (h, Rstarlist);
+          h /= vcontent (h, Rstar.mvar());
+
+          if (h.level() > Rstar.level())
+          {
+            g= divide (g, h, Rstarlist);
+            if (degree (h) == 1 || iter2.getItem().exp() == 1)
+            {
+              h= backSubst (h, backSubsts, Astar);
+              h= Prem (h, as);
+              h *= bCommonDen (h);
+              h /= vcontent (h, as.getFirst().mvar());
+              L.append (CFFactor (h, 1));
+            }
+            else
+              tmp.append (CFFactor (h, iter2.getItem().exp()));
+          }
+          count++;
+          if (g.level() <= Rstar.level())
+            break;
+          if (count == normFactors.length() - 1)
+          {
+            if (normFactors.getLast().exp() == 1 && g.level() > Rstar.level())
+            {
+              g= backSubst (g, backSubsts, Astar);
+              g= Prem (g, as);
+              g *= bCommonDen (g);
+              g /= vcontent (g, as.getFirst().mvar());
+              L.append (CFFactor (g, 1));
+            }
+            else if (normFactors.getLast().exp() > 1 &&
+                     g.level() > Rstar.level())
+            {
+              g /= vcontent (g, Rstar.mvar());
+              tmp.append (CFFactor (g, normFactors.getLast().exp()));
+            }
+            break;
+          }
+        }
+      }
+    }
+    LL= tmp;
+    (*Gen).next();
+  }
+  while (!LL.isEmpty());
+
+  if (!isRat && getCharacteristic() == 0)
+    Off (SW_RATIONAL);
+
+  delete Gen;
+
+  return L;
+}
+
+
+/// map elements in @a AS into a PIE \f$ L \f$ and record where the variables
+/// are mapped to in @a varsMapLevel, i.e @a varsMapLevel contains a list of
+/// pairs of variables \f$ v_i \f$ and integers \f$ e_i \f$ such that
+/// \f$ L=K(\sqrt[p^{e_1}]{v_1}, \ldots, \sqrt[p^{e_n}]{v_n}) \f$
+CFList
+mapIntoPIE (CFFList& varsMapLevel, CanonicalForm& lcmVars, const CFList & AS)
+{
+  CanonicalForm varsG;
+  int j, exp= 0, tmpExp;
+  bool recurse= false;
+  CFList asnew, as= AS;
+  CFListIterator i= as, ii;
+  CFFList varsGMapLevel, tmp;
+  CFFListIterator iter;
+  CFFList * varsGMap= new CFFList [as.length()];
+  for (j= 0; j < as.length(); j++)
+    varsGMap[j]= CFFList();
+  j= 0;
+  while (i.hasItem())
+  {
+    if (i.getItem().deriv() == 0)
+    {
+      deflateDegree (i.getItem(), exp, i.getItem().level());
+      i.getItem()= deflatePoly (i.getItem(), exp, i.getItem().level());
+
+      varsG= getVars (i.getItem());
+      varsG /= i.getItem().mvar();
+
+      lcmVars= lcm (varsG, lcmVars);
+
+      while (!varsG.isOne())
+      {
+        if (i.getItem().deriv (varsG.level()).isZero())
+        {
+          deflateDegree (i.getItem(), tmpExp, varsG.level());
+          if (exp >= tmpExp)
+          {
+            if (exp == tmpExp)
+              i.getItem()= deflatePoly (i.getItem(), exp, varsG.level());
+            else
+            {
+              if (j != 0)
+                recurse= true;
+              i.getItem()= deflatePoly (i.getItem(), tmpExp, varsG.level());
+            }
+            varsGMapLevel.insert (CFFactor (varsG.mvar(), exp - tmpExp));
+          }
+          else
+          {
+            i.getItem()= deflatePoly (i.getItem(), exp, varsG.level());
+            varsGMapLevel.insert (CFFactor (varsG.mvar(), 0));
+          }
+        }
+        else
+        {
+          if (j != 0)
+            recurse= true;
+          varsGMapLevel.insert (CFFactor (varsG.mvar(),exp));
+        }
+        varsG /= varsG.mvar();
+      }
+
+      if (recurse)
+      {
+        ii= as;
+        for (; ii.hasItem(); ii++)
+        {
+          if (ii.getItem() == i.getItem())
+            continue;
+          for (iter= varsGMapLevel; iter.hasItem(); iter++)
+            ii.getItem()= inflatePoly (ii.getItem(), iter.getItem().exp(),
+                                       iter.getItem().factor().level());
+        }
+      }
+      else
+      {
+        ii= i;
+        ii++;
+        for (; ii.hasItem(); ii++)
+        {
+          for (iter= varsGMapLevel; iter.hasItem(); iter++)
+          {
+            ii.getItem()= inflatePoly (ii.getItem(), iter.getItem().exp(),
+                                       iter.getItem().factor().level());
+          }
+        }
+      }
+      if (varsGMap[j].isEmpty())
+        varsGMap[j]= varsGMapLevel;
+      else
+      {
+        if (!varsGMapLevel.isEmpty())
+        {
+          tmp= varsGMap[j];
+          CFFListIterator iter2= varsGMapLevel;
+          ASSERT (tmp.length() == varsGMapLevel.length(),
+                  "wrong length of lists");
+          for (iter=tmp; iter.hasItem(); iter++, iter2++)
+            iter.getItem()= CFFactor (iter.getItem().factor(),
+                                  iter.getItem().exp() + iter2.getItem().exp());
+          varsGMap[j]= tmp;
+        }
+      }
+      varsGMapLevel= CFFList();
+    }
+    asnew.append (i.getItem());
+    if (!recurse)
+    {
+      i++;
+      j++;
+    }
+    else
+    {
+      i= as;
+      j= 0;
+      recurse= false;
+      asnew= CFList();
+    }
+  }
+
+  while (!lcmVars.isOne())
+  {
+    varsMapLevel.insert (CFFactor (lcmVars.mvar(), 0));
+    lcmVars /= lcmVars.mvar();
+  }
+
+  for (j= 0; j < as.length(); j++)
+  {
+    if (varsGMap[j].isEmpty())
+      continue;
+
+    for (CFFListIterator iter2= varsGMap[j]; iter2.hasItem(); iter2++)
+    {
+      for (iter= varsMapLevel; iter.hasItem(); iter++)
+      {
+        if (iter.getItem().factor() == iter2.getItem().factor())
+        {
+          iter.getItem()= CFFactor (iter.getItem().factor(),
+                                  iter.getItem().exp() + iter2.getItem().exp());
+        }
+      }
+    }
+  }
+
+  delete [] varsGMap;
+
+  return asnew;
+}
+
+/// algorithm of A. Steel described in "Conquering Inseparability: Primary
+/// decomposition and multivariate factorization over algebraic function fields
+/// of positive characteristic" with the following modifications: we use
+/// characteristic sets in IdealOverSubfield and Trager's primitive element
+/// algorithm instead of FGLM
+CFFList
+SteelTrager (const CanonicalForm & f, const CFList & AS)
+{
+  CanonicalForm F= f, lcmVars= 1;
+  CFList asnew, as= AS;
+  CFListIterator i, ii;
+
+  bool derivZeroF= false;
+  int j, expF= 0, tmpExp;
+  CFFList varsMapLevel, tmp;
+  CFFListIterator iter;
+
+  // check if F is separable
+  if (F.deriv().isZero())
+  {
+    derivZeroF= true;
+    deflateDegree (F, expF, F.level());
+  }
+
+  CanonicalForm varsF= getVars (F);
+  varsF /= F.mvar();
+
+  lcmVars= lcm (varsF, lcmVars);
+
+  if (derivZeroF)
+    as.append (F);
+
+  asnew= mapIntoPIE (varsMapLevel, lcmVars, as);
+
+  if (derivZeroF)
+  {
+    asnew.removeLast();
+    F= deflatePoly (F, expF, F.level());
+  }
+
+  // map variables in F
+  for (iter= varsMapLevel; iter.hasItem(); iter++)
+  {
+    if (expF > 0)
+      tmpExp= iter.getItem().exp() - expF;
+    else
+      tmpExp= iter.getItem().exp();
+
+    if (tmpExp > 0)
+      F= inflatePoly (F, tmpExp, iter.getItem().factor().level());
+    else if (tmpExp < 0)
+      F= deflatePoly (F, -tmpExp, iter.getItem().factor().level());
+  }
+
+  // factor F with minimal polys given in asnew
+  asnew.append (F);
+  asnew= charSetViaModCharSet (asnew, false);
+
+  F= asnew.getLast();
+  F /= content (F);
+
+  asnew.removeLast();
+  for (i= asnew; i.hasItem(); i++)
+    i.getItem() /= content (i.getItem());
+
+  tmp= facAlgFunc (F, asnew);
+
+  // transform back
+  j= 0;
+  int p= getCharacteristic();
+  CFList transBack;
+  CFMap M;
+  CanonicalForm g;
+
+  for (iter= varsMapLevel; iter.hasItem(); iter++)
+  {
+    if (iter.getItem().exp() > 0)
+    {
+      j++;
+      g= power (Variable (f.level() + j), ipower (p, iter.getItem().exp())) -
+         iter.getItem().factor().mvar();
+      transBack.append (g);
+      M.newpair (iter.getItem().factor().mvar(), Variable (f.level() + j));
+    }
+  }
+
+  for (i= asnew; i.hasItem(); i++)
+    transBack.insert (M (i.getItem()));
+
+  if (expF > 0)
+    tmpExp= ipower (p, expF);
+
+  CFFList result;
+  CFList transform;
+
+  bool found;
+  for (iter= tmp; iter.hasItem(); iter++)
+  {
+    found= false;
+    transform= transBack;
+    CanonicalForm factor= iter.getItem().factor();
+    factor= M (factor);
+    transform.append (factor);
+    transform= modCharSet (transform, false);
+
+retry:
+    if (transform.isEmpty())
+    {
+      transform= transBack;
+      transform.append (factor);
+      transform= charSetViaCharSetN (transform);
+    }
+    for (i= transform; i.hasItem(); i++)
+    {
+      if (degree (i.getItem(), f.mvar()) > 0)
+      {
+        if (i.getItem().level() > f.level())
+          break;
+        found= true;
+        factor= i.getItem();
+        break;
+      }
+    }
+
+    if (!found)
+    {
+      found= false;
+      transform= CFList();
+      goto retry;
+    }
+
+    factor /= content (factor);
+
+    if (expF > 0)
+    {
+      int mult= tmpExp/(degree (factor)/degree (iter.getItem().factor()));
+      result.append (CFFactor (factor, iter.getItem().exp()*mult));
+    }
+    else
+      result.append (CFFactor (factor, iter.getItem().exp()));
+  }
+
+  return result;
+}
+
+/// factorize a polynomial that is irreducible over the ground field modulo an
+/// extension given by an irreducible characteristic set
+
+// 1) prepares data
+// 2) for char=p we distinguish 3 cases:
+//           no transcendentals, separable and inseparable extensions
+CFFList
+facAlgFunc2 (const CanonicalForm & f, const CFList & as)
+{
+  bool isRat= isOn (SW_RATIONAL);
+  if (!isRat && getCharacteristic() == 0)
+    On (SW_RATIONAL);
+  Variable vf=f.mvar();
+  CFListIterator i;
+  CFFListIterator jj;
+  CFList reduceresult;
+  CFFList result;
+
+// F1: [Test trivial cases]
+// 1) first trivial cases:
+  if (vf.level() <= as.getLast().level())
+  {
+    if (!isRat && getCharacteristic() == 0)
+      Off (SW_RATIONAL);
+    return CFFList(CFFactor(f,1));
+  }
+
+// 2) Setup list of those polys in AS having degree > 1
+  CFList Astar;
+  Variable x;
+  CanonicalForm elem;
+  Varlist ord, uord;
+  for (int ii= 1; ii < level (vf); ii++)
+    uord.append (Variable (ii));
+
+  for (i= as; i.hasItem(); i++)
+  {
+    elem= i.getItem();
+    x= elem.mvar();
+    if (degree (elem, x) > 1)  // otherwise it's not an extension
+    {
+      Astar.append (elem);
+      ord.append (x);
+    }
+  }
+  uord= Difference (uord, ord);
+
+// 3) second trivial cases: we already proved irr. of f over no extensions
+  if (Astar.length() == 0)
+  {
+    if (!isRat && getCharacteristic() == 0)
+      Off (SW_RATIONAL);
+    return CFFList (CFFactor (f, 1));
+  }
+
+// 4) Look if elements in uord actually occur in any of the minimal
+//    polynomials. If no element of uord occures in any of the minimal
+//    polynomials the field is an alg. number field not an alg. function field
+  Varlist newuord= varsInAs (uord, Astar);
+
+  CFFList Factorlist;
+  Varlist gcdord= Union (ord, newuord);
+  gcdord.append (f.mvar());
+  bool isFunctionField= (newuord.length() > 0);
+
+  // TODO alg_sqrfree?
+  CanonicalForm Fgcd= 0;
+  if (isFunctionField)
+    Fgcd= alg_gcd (f, f.deriv(), Astar);
+
+  bool derivZero= f.deriv().isZero();
+  if (isFunctionField && (degree (Fgcd, f.mvar()) > 0) && !derivZero)
+  {
+    CanonicalForm Ggcd= divide(f, Fgcd,Astar);
+    if (getCharacteristic() == 0)
+    {
+      CFFList result= facAlgFunc2 (Ggcd, as); //Ggcd is the squarefree part of f
+      multiplicity (result, f, Astar);
+      if (!isRat && getCharacteristic() == 0)
+        Off (SW_RATIONAL);
+      return result;
+    }
+
+    Fgcd= pp (Fgcd);
+    Ggcd= pp (Ggcd);
+    if (!isRat && getCharacteristic() == 0)
+      Off (SW_RATIONAL);
+    return merge (facAlgFunc2 (Fgcd, as), facAlgFunc2 (Ggcd, as));
+  }
+
+  if (getCharacteristic() > 0)
+  {
+    IntList degreelist;
+    Variable vminpoly;
+    for (i= Astar; i.hasItem(); i++)
+      degreelist.append (degree (i.getItem()));
+
+    int extdeg= getDegOfExt (degreelist, degree (f));
+
+    if (newuord.length() == 0) // no parameters
+    {
+      if (extdeg > 1)
+      {
+        CanonicalForm MIPO= generateMipo (extdeg);
+        vminpoly= rootOf(MIPO);
+      }
+      Factorlist= Trager(f, Astar, vminpoly, as, isFunctionField);
+      if (extdeg > 1)
+        prune (vminpoly);
+      return Factorlist;
+    }
+    else if (isInseparable(Astar) || derivZero) // inseparable case
+    {
+      Factorlist= SteelTrager (f, Astar);
+      return Factorlist;
+    }
+    else // separable case
+    {
+      if (extdeg > 1)
+      {
+        CanonicalForm MIPO=generateMipo (extdeg);
+        vminpoly= rootOf (MIPO);
+      }
+      Factorlist= Trager (f, Astar, vminpoly, as, isFunctionField);
+      if (extdeg > 1)
+        prune (vminpoly);
+      return Factorlist;
+    }
+  }
+  else // char 0
+  {
+    Variable vminpoly;
+    Factorlist= Trager (f, Astar, vminpoly, as, isFunctionField);
+    if (!isRat && getCharacteristic() == 0)
+      Off (SW_RATIONAL);
+    return Factorlist;
+  }
+
+  return CFFList (CFFactor(f,1));
+}
+
+
+/// factorize a polynomial modulo an extension given by an irreducible
+/// characteristic set
+CFFList
+facAlgFunc (const CanonicalForm & f, const CFList & as)
+{
+  bool isRat= isOn (SW_RATIONAL);
+  if (!isRat && getCharacteristic() == 0)
+    On (SW_RATIONAL);
+  CFFList Output, output, Factors= factorize(f);
+  if (Factors.getFirst().factor().inCoeffDomain())
+    Factors.removeFirst();
+
+  if (as.length() == 0)
+  {
+    if (!isRat && getCharacteristic() == 0)
+      Off (SW_RATIONAL);
+    return Factors;
+  }
+  if (f.level() <= as.getLast().level())
+  {
+    if (!isRat && getCharacteristic() == 0)
+      Off (SW_RATIONAL);
+    return Factors;
+  }
+
+  for (CFFListIterator i=Factors; i.hasItem(); i++)
+  {
+    if (i.getItem().factor().level() > as.getLast().level())
+    {
+      output= facAlgFunc2 (i.getItem().factor(), as);
+      for (CFFListIterator j= output; j.hasItem(); j++)
+        Output= append (Output, CFFactor (j.getItem().factor(),
+                                          j.getItem().exp()*i.getItem().exp()));
+    }
+  }
+
+  if (!isRat && getCharacteristic() == 0)
+    Off (SW_RATIONAL);
+  return Output;
+}
diff --git a/factory/facAlgFunc.h b/factory/facAlgFunc.h
new file mode 100644
index 0000000..da1320e
--- /dev/null
+++ b/factory/facAlgFunc.h
@@ -0,0 +1,51 @@
+/*****************************************************************************\
+ * Computer Algebra System SINGULAR
+\*****************************************************************************/
+/** @file facAlgFunc.h
+ *
+ * Factorization over algebraic function fields
+ *
+ * @note some of the code is code from libfac or derived from code from libfac.
+ * Libfac is written by M. Messollen. See also COPYING for license information
+ * and README for general information on characteristic sets.
+ *
+ * @author Martin Lee
+ *
+ **/
+/*****************************************************************************/
+
+#ifndef FAC_ALG_FUNC_H
+#define FAC_ALG_FUNC_H
+
+#include "canonicalform.h"
+
+CanonicalForm alg_gcd(const CanonicalForm &, const CanonicalForm &, const CFList &);
+/*BEGINPUBLIC*/
+
+/// factorize a polynomial @a f that is irreducible over the ground field modulo
+/// an extension given by an irreducible characteristic set @a as, @a f is
+/// assumed to be integral, i.e. \f$ f\in K[x_1,\ldots,x_n]/(as) \f$, and each
+/// element of @a as is assumed to be integral as well. \f$ K \f$ must be either
+/// \f$ F_p \f$ or \f$ Q \f$.
+///
+/// @return the returned factors are not necessarily monic but only primitive
+/// and the product of the factors equals @a f up to a unit.
+CFFList facAlgFunc2 (const CanonicalForm & f,///<[in] univariate poly
+                     const CFList & as       ///<[in] irreducible characteristic
+                                             ///< set
+                    );
+
+/// factorize a polynomial @a f modulo an extension given by an irreducible
+/// characteristic set as, @a f is assumed to be integral, i.e.
+/// \f$ f\in K[x_1,\ldots,x_n]/(as) \f$, and each element of @a as is assumed to
+/// be integral as well. \f$ K \f$ must be either \f$ F_p \f$ or \f$ Q \f$.
+///
+/// @return the returned factors are not necessarily monic but only primitive
+/// and the product of the factors equals @a f up to a unit.
+CFFList facAlgFunc (const CanonicalForm & f, ///<[in] univariate poly
+                    const CFList & as        ///<[in] irreducible characteristic
+                                             ///< set
+                   );
+/*ENDPUBLIC*/
+
+#endif /* INCL_ALGFACTOR_H */
diff --git a/factory/facAlgFuncUtil.cc b/factory/facAlgFuncUtil.cc
new file mode 100644
index 0000000..05f2976
--- /dev/null
+++ b/factory/facAlgFuncUtil.cc
@@ -0,0 +1,722 @@
+/*****************************************************************************\
+ * Computer Algebra System SINGULAR
+\*****************************************************************************/
+/** @file facAlgFuncUtil.cc
+ *
+ * This file provides utility functions to factorize polynomials over alg.
+ * function fields
+ *
+ * @note some of the code is code from libfac or derived from code from libfac.
+ * Libfac is written by M. Messollen. See also COPYING for license information
+ * and README for general information on characteristic sets.
+ *
+ * @author Martin Lee
+ *
+ **/
+/*****************************************************************************/
+
+#include "config.h"
+
+#include "cf_assert.h"
+
+#include "canonicalform.h"
+#include "facAlgFuncUtil.h"
+#include "cfCharSetsUtil.h"
+#include "cf_random.h"
+#include "cf_irred.h"
+#include "cf_algorithm.h"
+#include "cf_util.h"
+#include "cf_iter.h"
+
+CFFList
+append (const CFFList & Inputlist, const CFFactor & TheFactor)
+{
+  CFFList Outputlist;
+  CFFactor copy;
+  CFFListIterator i;
+  int exp=0;
+
+  for (i= Inputlist; i.hasItem() ; i++)
+  {
+    copy= i.getItem();
+    if (copy.factor() == TheFactor.factor())
+      exp += copy.exp();
+    else
+      Outputlist.append(copy);
+  }
+  Outputlist.append (CFFactor (TheFactor.factor(), exp + TheFactor.exp()));
+  return Outputlist;
+}
+
+CFFList
+merge (const CFFList & Inputlist1, const CFFList & Inputlist2)
+{
+  CFFList Outputlist;
+  CFFListIterator i;
+
+  for (i= Inputlist1; i.hasItem(); i++)
+    Outputlist= append (Outputlist, i.getItem());
+  for (i= Inputlist2; i.hasItem() ; i++)
+    Outputlist= append (Outputlist, i.getItem());
+
+  return Outputlist;
+}
+
+Varlist
+varsInAs (const Varlist & uord, const CFList & Astar)
+{
+  Varlist output;
+  CanonicalForm elem;
+  Variable x;
+
+  for (VarlistIterator i= uord; i.hasItem(); i++)
+  {
+    x= i.getItem();
+    for (CFListIterator j= Astar; j.hasItem(); j++ )
+    {
+      elem= j.getItem();
+      if (degree (elem, x) > 0) // x actually occures in Astar
+      {
+        output.append (x);
+        break;
+      }
+    }
+  }
+  return output;
+}
+
+// generate an irreducible poly of degree degOfExt over F_p
+CanonicalForm
+generateMipo (int degOfExt)
+{
+#ifndef HAVE_NTL
+  FFRandom gen;
+  return find_irreducible (degOfExt, gen, Variable (1));
+#else
+  return randomIrredpoly (degOfExt, Variable (1));
+#endif
+}
+
+CanonicalForm alg_lc (const CanonicalForm & f)
+{
+  if (f.level()>0)
+  {
+    return alg_lc(f.LC());
+  }
+
+  return f;
+}
+
+CanonicalForm alg_LC (const CanonicalForm& f, int lev)
+{
+  CanonicalForm result= f;
+  while (result.level() > lev)
+    result= LC (result);
+  return result;
+}
+
+
+CanonicalForm
+subst (const CanonicalForm& f, const CFList& a, const CFList& b,
+       const CanonicalForm& Rstar, bool isFunctionField)
+{
+  if (isFunctionField)
+    ASSERT (2*a.length() == b.length(), "wrong length of lists");
+  else
+    ASSERT (a.length() == b.length(), "lists of equal length expected");
+  CFListIterator j= b;
+  CanonicalForm result= f, tmp, powj;
+  CFListIterator i= a;
+  int length= a.length();
+  int count= 0;
+  for (; i.hasItem() && j.hasItem(); i++, j++, count++)
+  {
+    if (length - count == 2)
+    {
+      if (!isFunctionField)
+      {
+        result= result (b.getLast(), a.getLast().mvar());
+        result= result (j.getItem(), i.getItem().mvar());
+        break;
+      }
+      else
+      {
+        tmp= b.getLast();
+        j++;
+        j++;
+        powj= power (tmp, degree (result, a.getLast().mvar()));
+        result= evaluate (result, j.getItem(), tmp, powj, a.getLast().mvar());
+
+        if (fdivides (powj, result, tmp))
+          result= tmp;
+
+        result /= vcontent (result, Variable (a.getLast().level() + 1));
+        j--;
+        j--;
+        tmp= j.getItem();
+        j++;
+        powj= power (j.getItem(), degree (result, i.getItem().mvar()));
+        result= evaluate (result, tmp, j.getItem(), powj, i.getItem().mvar());
+
+        if (fdivides (powj, result, tmp))
+          result= tmp;
+
+        result /= vcontent (result, Variable (i.getItem().level() + 1));
+        break;
+      }
+    }
+    else
+    {
+      if (!isFunctionField)
+        result= result (j.getItem(), i.getItem().mvar());
+      else
+      {
+        tmp= j.getItem();
+        j++;
+        powj= power (j.getItem(), degree (result, i.getItem().mvar()));
+        result= evaluate (result, tmp, j.getItem(), powj, i.getItem().mvar());
+
+        if (fdivides (powj, result, tmp))
+          result= tmp;
+
+        result /= vcontent (result, Variable (i.getItem().level() + 1));
+      }
+    }
+  }
+  result= Prem (result, CFList (Rstar));
+  result /= vcontent (result, Variable (Rstar.level() + 1));
+  return result;
+}
+
+CanonicalForm
+backSubst (const CanonicalForm& F, const CFList& a, const CFList& b)
+{
+  ASSERT (a.length() == b.length() - 1, "wrong length of lists in backSubst");
+  CanonicalForm result= F;
+  Variable tmp;
+  CFList tmp2= b;
+  tmp= tmp2.getLast().mvar();
+  tmp2.removeLast();
+  for (CFListIterator iter= a; iter.hasItem(); iter++)
+  {
+    result= result (tmp+iter.getItem()*tmp2.getLast().mvar(), tmp);
+    tmp= tmp2.getLast().mvar();
+    tmp2.removeLast();
+  }
+  return result;
+}
+
+void deflateDegree (const CanonicalForm & F, int & pExp, int n)
+{
+  if (n == 0 || n > F.level())
+  {
+    pExp= -1;
+    return;
+  }
+  if (F.level() == n)
+  {
+    ASSERT (F.deriv().isZero(), "derivative of F is not zero");
+    int termCount=0;
+    CFIterator i= F;
+    for (; i.hasTerms(); i++)
+    {
+      if (i.exp() != 0)
+        termCount++;
+    }
+
+    int j= 1;
+    i= F;
+    for (;j < termCount; j++, i++)
+      ;
+
+    int exp= i.exp();
+    int count= 0;
+    int p= getCharacteristic();
+    while ((exp >= p) && (exp != 0) && (exp % p == 0))
+    {
+      exp /= p;
+      count++;
+    }
+    pExp= count;
+  }
+  else
+  {
+    CFIterator i= F;
+    deflateDegree (i.coeff(), pExp, n);
+    i++;
+    int tmp= pExp;
+    for (; i.hasTerms(); i++)
+    {
+      deflateDegree (i.coeff(), pExp, n);
+      if (tmp == -1)
+        tmp= pExp;
+      else if (tmp != -1 && pExp != -1)
+        pExp= (pExp < tmp) ? pExp : tmp;
+      else
+        pExp= tmp;
+    }
+  }
+}
+
+CanonicalForm deflatePoly (const CanonicalForm & F, int exp)
+{
+  if (exp == 0)
+    return F;
+  int p= getCharacteristic();
+  int pToExp= ipower (p, exp);
+  Variable x=F.mvar();
+  CanonicalForm result= 0;
+  for (CFIterator i= F; i.hasTerms(); i++)
+    result += i.coeff()*power (x, i.exp()/pToExp);
+  return result;
+}
+
+CanonicalForm deflatePoly (const CanonicalForm & F, int exps, int n)
+{
+  if (n == 0 || exps <= 0 || F.level() < n)
+    return F;
+  if (F.level() == n)
+    return deflatePoly (F, exps);
+  else
+  {
+    CanonicalForm result= 0;
+    for (CFIterator i= F; i.hasTerms(); i++)
+      result += deflatePoly (i.coeff(), exps, n)*power(F.mvar(), i.exp());
+    return result;
+  }
+}
+
+CanonicalForm inflatePoly (const CanonicalForm & F, int exp)
+{
+  if (exp == 0)
+    return F;
+  int p= getCharacteristic();
+  int pToExp= ipower (p, exp);
+  Variable x=F.mvar();
+  CanonicalForm result= 0;
+  for (CFIterator i= F; i.hasTerms(); i++)
+    result += i.coeff()*power (x, i.exp()*pToExp);
+  return result;
+}
+
+CanonicalForm inflatePoly (const CanonicalForm & F, int exps, int n)
+{
+  if (n == 0 || exps <= 0 || F.level() < n)
+    return F;
+  if (F.level() == n)
+    return inflatePoly (F, exps);
+  else
+  {
+    CanonicalForm result= 0;
+    for (CFIterator i= F; i.hasTerms(); i++)
+      result += inflatePoly (i.coeff(), exps, n)*power(F.mvar(), i.exp());
+    return result;
+  }
+}
+
+void
+multiplicity (CFFList& factors, const CanonicalForm& F, const CFList& as)
+{
+  CanonicalForm G= F;
+  Variable x= F.mvar();
+  CanonicalForm q, r;
+  int count= -1;
+  for (CFFListIterator iter=factors; iter.hasItem(); iter++)
+  {
+    count= -1;
+    if (iter.getItem().factor().inCoeffDomain())
+      continue;
+    while (1)
+    {
+      psqr (G, iter.getItem().factor(), q, r, x);
+
+      q= Prem (q, as);
+      r= Prem (r, as);
+      if (!r.isZero())
+        break;
+      count++;
+      G= q;
+    }
+    iter.getItem()= CFFactor (iter.getItem().factor(),
+                              iter.getItem().exp() + count);
+  }
+}
+
+int hasAlgVar (const CanonicalForm &f, const Variable &v)
+{
+  if (f.inBaseDomain())
+    return 0;
+  if (f.inCoeffDomain())
+  {
+    if (f.mvar() == v)
+      return 1;
+    return hasAlgVar (f.LC(), v);
+  }
+  if (f.inPolyDomain())
+  {
+    if (hasAlgVar(f.LC(), v))
+      return 1;
+    for (CFIterator i= f; i.hasTerms(); i++)
+    {
+      if (hasAlgVar (i.coeff(), v))
+        return 1;
+    }
+  }
+  return 0;
+}
+
+int hasVar (const CanonicalForm &f, const Variable &v)
+{
+  if (f.inBaseDomain())
+    return 0;
+  if (f.inCoeffDomain())
+  {
+    if (f.mvar() == v)
+      return 1;
+    return hasAlgVar (f.LC(), v);
+  }
+  if (f.inPolyDomain())
+  {
+    if (f.mvar() == v)
+      return 1;
+    if (hasVar (f.LC(), v))
+      return 1;
+    for (CFIterator i= f; i.hasTerms(); i++)
+    {
+      if (hasVar (i.coeff(), v))
+        return 1;
+    }
+  }
+  return 0;
+}
+
+int hasAlgVar (const CanonicalForm &f)
+{
+  if (f.inBaseDomain())
+    return 0;
+  if (f.inCoeffDomain())
+  {
+    if (f.level() != 0)
+      return 1;
+    return hasAlgVar(f.LC());
+  }
+  if (f.inPolyDomain())
+  {
+    if (hasAlgVar(f.LC()))
+      return 1;
+    for (CFIterator i= f; i.hasTerms(); i++)
+    {
+      if (hasAlgVar (i.coeff()))
+        return 1;
+    }
+  }
+  return 0;
+}
+
+/// pseudo division of f and g wrt. x s.t. multiplier*f=q*g+r
+void
+psqr (const CanonicalForm & f, const CanonicalForm & g, CanonicalForm & q,
+      CanonicalForm & r, CanonicalForm& multiplier, const Variable& x)
+{
+    ASSERT( x.level() > 0, "type error: polynomial variable expected" );
+    ASSERT( ! g.isZero(), "math error: division by zero" );
+
+    // swap variables such that x's level is larger or equal
+    // than both f's and g's levels.
+    Variable X;
+    if (f.level() > g.level())
+      X= f.mvar();
+    else
+      X= g.mvar();
+    if (X.level() < x.level())
+      X= x;
+    CanonicalForm F= swapvar (f, x, X);
+    CanonicalForm G= swapvar (g, x, X);
+
+    // now, we have to calculate the pseudo remainder of F and G
+    // w.r.t. X
+    int fDegree= degree (F, X);
+    int gDegree= degree (G, X);
+    if (fDegree < 0 || fDegree < gDegree)
+    {
+      q= 0;
+      r= f;
+    }
+    else
+    {
+      CanonicalForm LCG= LC (G, X);
+      multiplier= power (LCG, fDegree - gDegree + 1);
+      divrem (multiplier*F, G, q, r);
+      q= swapvar (q, x, X);
+      r= swapvar (r, x, X);
+    }
+}
+
+CanonicalForm
+Sprem (const CanonicalForm &f, const CanonicalForm &g, CanonicalForm & m,
+       CanonicalForm & q )
+{
+  CanonicalForm ff, gg, l, test, retvalue;
+  int df, dg,n;
+  bool reord;
+  Variable vf, vg, v;
+
+  if ((vf = f.mvar()) < (vg = g.mvar()))
+  {
+    m= 0;
+    q= 0;
+    return f;
+  }
+  else
+  {
+    if ( vf == vg )
+    {
+      ff= f;
+      gg= g;
+      reord= false;
+      v= vg; // == x
+    }
+    else
+    {
+      v= Variable (f.level() + 1);
+      ff= swapvar (f, vg, v); // == r
+      gg= swapvar (g, vg, v); // == v
+      reord=true;
+    }
+    dg= degree (gg, v); // == dv
+    df= degree (ff, v); // == dr
+    if (dg <= df)
+    {
+      l= LC (gg);
+      gg= gg - LC(gg)*power(v,dg);
+    }
+    else
+      l = 1;
+    n= 0;
+    while ((dg <= df) && (!ff.isZero()))
+    {
+      test= gg*LC (ff)*power (v, df - dg);
+      if (df == 0)
+        ff= 0;
+      else
+        ff= ff - LC(ff)*power(v,df);
+      ff= l*ff - test;
+      df= degree (ff, v);
+      n++;
+    }
+
+    if (reord)
+      retvalue= swapvar (ff, vg, v);
+    else
+      retvalue= ff;
+
+    m= power (l, n);
+    if (fdivides (g, m*f - retvalue))
+      q= (m*f - retvalue)/g;
+    else
+      q= 0;
+    return retvalue;
+  }
+}
+
+CanonicalForm
+divide (const CanonicalForm & ff, const CanonicalForm & f, const CFList & as)
+{
+  CanonicalForm r, m, q;
+
+  if (f.inCoeffDomain())
+  {
+    bool isRat= isOn(SW_RATIONAL);
+    if (getCharacteristic() == 0)
+      On(SW_RATIONAL);
+    q= ff/f;
+    if (!isRat && getCharacteristic() == 0)
+      Off(SW_RATIONAL);
+  }
+  else
+    r= Sprem (ff, f, m, q);
+
+  r= Prem (q, as);
+  return r;
+}
+
+// check if polynomials in Astar define a separable extension
+bool
+isInseparable (const CFList & Astar)
+{
+  CanonicalForm elem;
+
+  if (Astar.length() == 0)
+    return false;
+  for (CFListIterator i= Astar; i.hasItem(); i++)
+  {
+    elem= i.getItem();
+    if (elem.deriv().isZero())
+      return true;
+  }
+  return false;
+}
+
+// calculate big enough extension for finite fields
+// Idea: first calculate k, such that q^k > S (->thesis)
+// Second, search k with gcd(k,m_i)=1, where m_i is the degree of the i'th
+// minimal polynomial. Then the minpoly f_i remains irrd. over q^k and we
+// have enough elements to plug in.
+int
+getDegOfExt (IntList & degreelist, int n)
+{
+  int charac= getCharacteristic();
+  setCharacteristic(0); // need it for k !
+  int k= 1, m= 1, length= degreelist.length();
+  IntListIterator i;
+
+  for (i= degreelist; i.hasItem(); i++)
+     m= m*i.getItem();
+  int q= charac;
+  while (q <= ((n*m)*(n*m)/2))
+  {
+    k= k+1;
+    q= q*charac;
+  }
+  int l= 0;
+  do
+  {
+    for (i= degreelist; i.hasItem(); i++)
+    {
+      l= l + 1;
+      if (igcd (k, i.getItem()) == 1)
+      {
+        if (l == length)
+        {
+          setCharacteristic (charac);
+          return k;
+        }
+      }
+      else
+        break;
+    }
+    k= k + 1;
+    l= 0;
+  }
+  while (1);
+}
+
+CanonicalForm
+QuasiInverse (const CanonicalForm& f, const CanonicalForm& g,
+              const Variable& x)
+{
+  CanonicalForm pi, pi1, q, t0, t1, Hi, bi, pi2;
+  bool isRat= isOn (SW_RATIONAL);
+  pi= f;
+  pi1= g;
+  if (isRat)
+  {
+    pi *= bCommonDen (pi);
+    pi1 *= bCommonDen (pi1);
+  }
+  CanonicalForm m,tmp;
+  if (isRat && getCharacteristic() == 0)
+    Off (SW_RATIONAL);
+
+  pi= pi/content (pi,x);
+  pi1= pi1/content (pi1,x);
+
+  t0= 0;
+  t1= 1;
+  bi= 1;
+
+  int delta= degree (f, x) - degree (g, x);
+  Hi= power (LC (pi1, x), delta);
+  if ( (delta+1) % 2 )
+      bi = 1;
+  else
+      bi = -1;
+
+  while (degree (pi1,x) > 0)
+  {
+    psqr (pi, pi1, q, pi2, m, x);
+    pi2 /= bi;
+
+    tmp= t1;
+    t1= t0*m - t1*q;
+    t0= tmp;
+    t1 /= bi;
+    pi= pi1;
+    pi1= pi2;
+    if (degree (pi1, x) > 0)
+    {
+      delta= degree (pi, x) - degree (pi1, x);
+      if ((delta + 1) % 2)
+        bi= LC (pi, x)*power (Hi, delta);
+      else
+        bi= -LC (pi, x)*power (Hi, delta);
+      Hi= power (LC (pi1, x), delta)/power (Hi, delta - 1);
+    }
+  }
+  t1 /= gcd (pi1, t1);
+  if (isRat && getCharacteristic() == 0)
+    On (SW_RATIONAL);
+  return t1;
+}
+
+CanonicalForm
+evaluate (const CanonicalForm& f, const CanonicalForm& g,
+          const CanonicalForm& h, const CanonicalForm& powH)
+{
+  if (f.inCoeffDomain())
+    return f;
+  CFIterator i= f;
+  int lastExp = i.exp();
+  CanonicalForm result = i.coeff()*powH;
+  i++;
+  while (i.hasTerms())
+  {
+    int i_exp= i.exp();
+    if ((lastExp - i_exp) == 1)
+    {
+      result *= g;
+      result /= h;
+    }
+    else
+    {
+      result *= power (g, lastExp - i_exp);
+      result /= power (h, lastExp - i_exp);
+    }
+    result += i.coeff()*powH;
+    lastExp = i_exp;
+    i++;
+  }
+  if (lastExp != 0)
+  {
+    result *= power (g, lastExp);
+    result /= power (h, lastExp);
+  }
+  return result;
+}
+
+
+/// evaluate f at g/h at v such that powH*f is integral i.e. powH is assumed to be h^degree(f,v)
+CanonicalForm
+evaluate (const CanonicalForm& f, const CanonicalForm& g,
+          const CanonicalForm& h, const CanonicalForm& powH,
+          const Variable& v)
+{
+  if (f.inCoeffDomain())
+  {
+    return f*powH;
+  }
+
+  Variable x = f.mvar();
+  if ( v > x )
+    return f*powH;
+  else  if ( v == x )
+    return evaluate (f, g, h, powH);
+
+  // v is less than main variable of f
+  CanonicalForm result= 0;
+  for (CFIterator i= f; i.hasTerms(); i++)
+    result += evaluate (i.coeff(), g, h, powH, v)*power (x, i.exp());
+  return result;
+}
+
+
diff --git a/factory/facAlgFuncUtil.h b/factory/facAlgFuncUtil.h
new file mode 100644
index 0000000..5528806
--- /dev/null
+++ b/factory/facAlgFuncUtil.h
@@ -0,0 +1,76 @@
+/*****************************************************************************\
+ * Computer Algebra System SINGULAR
+\*****************************************************************************/
+/** @file facAlgFuncUtil.h
+ *
+ * Utility functions for factorization over algebraic function fields
+ *
+ * @note some of the code is code from libfac or derived from code from libfac.
+ * Libfac is written by M. Messollen. See also COPYING for license information
+ * and README for general information on characteristic sets.
+ *
+ * @author Martin Lee
+ *
+ **/
+/*****************************************************************************/
+
+
+#ifndef FAC_ALG_FUNC_UTIL_H
+#define FAC_ALG_FUNC_UTIL_H
+
+CFFList
+append (const CFFList & Inputlist, const CFFactor & TheFactor);
+
+CFFList
+merge (const CFFList & Inputlist1, const CFFList & Inputlist2);
+
+Varlist
+varsInAs (const Varlist & uord, const CFList & As);
+
+int hasVar (const CanonicalForm &f, const Variable &v);
+
+int hasAlgVar(const CanonicalForm &f);
+
+CanonicalForm
+generateMipo (int degOfExt);
+
+CanonicalForm alg_lc (const CanonicalForm & f);
+
+CanonicalForm alg_LC (const CanonicalForm& f, int lev);
+
+void deflateDegree (const CanonicalForm & F, int & pExp, int n);
+
+CanonicalForm deflatePoly (const CanonicalForm & F, int exps, int n);
+
+CanonicalForm inflatePoly (const CanonicalForm & F, int exps, int n);
+
+void
+multiplicity (CFFList& factors, const CanonicalForm& F, const CFList& as);
+
+CanonicalForm
+backSubst (const CanonicalForm& F, const CFList& a, const CFList& b);
+
+CanonicalForm
+subst (const CanonicalForm& f, const CFList& a, const CFList& b,
+       const CanonicalForm& Rstar, bool isFunctionField);
+
+CanonicalForm
+divide (const CanonicalForm & ff, const CanonicalForm & f, const CFList & as);
+
+CanonicalForm
+QuasiInverse (const CanonicalForm& f, const CanonicalForm& g,
+              const Variable& x);
+
+CanonicalForm
+evaluate (const CanonicalForm& f, const CanonicalForm& g,
+          const CanonicalForm& h, const CanonicalForm& powH,
+          const Variable& v);
+
+int
+getDegOfExt (IntList & degreelist, int n);
+
+bool
+isInseparable (const CFList & Astar);
+
+#endif
+
diff --git a/factory/facBivar.cc b/factory/facBivar.cc
new file mode 100644
index 0000000..8ccd365
--- /dev/null
+++ b/factory/facBivar.cc
@@ -0,0 +1,608 @@
+/*****************************************************************************\
+ * Computer Algebra System SINGULAR
+\*****************************************************************************/
+/** @file facBivar.cc
+ *
+ * bivariate factorization over Q(a)
+ *
+ * @author Martin Lee
+ *
+ **/
+/*****************************************************************************/
+
+
+#include "config.h"
+
+
+#include "cf_assert.h"
+#include "debug.h"
+#include "timing.h"
+
+#include "cf_algorithm.h"
+#include "facFqBivar.h"
+#include "facBivar.h"
+#include "facHensel.h"
+#include "facMul.h"
+#include "cf_primes.h"
+
+#ifdef HAVE_NTL
+TIMING_DEFINE_PRINT(fac_uni_factorizer)
+TIMING_DEFINE_PRINT(fac_bi_hensel_lift)
+TIMING_DEFINE_PRINT(fac_bi_factor_recombination)
+TIMING_DEFINE_PRINT(fac_bi_evaluation)
+TIMING_DEFINE_PRINT(fac_bi_shift_to_zero)
+
+// bound on coeffs of f (cf. Musser: Multivariate Polynomial Factorization,
+//                          Gelfond: Transcendental and Algebraic Numbers)
+modpk
+coeffBound ( const CanonicalForm & f, int p )
+{
+    int * degs = degrees( f );
+    int M = 0, i, k = f.level();
+    CanonicalForm b= 1;
+    for ( i = 1; i <= k; i++ )
+    {
+      M += degs[i];
+      b *= degs[i] + 1;
+    }
+    b /= power (CanonicalForm (2), k);
+    b= b.sqrt() + 1;
+    b *= 2 * maxNorm( f ) * power( CanonicalForm( 2 ), M );
+    CanonicalForm B = p;
+    k = 1;
+    while ( B < b ) {
+        B *= p;
+        k++;
+    }
+    return modpk( p, k );
+}
+
+void findGoodPrime(const CanonicalForm &f, int &start)
+{
+  if (! f.inBaseDomain() )
+  {
+    CFIterator i = f;
+    for(;;)
+    {
+      if  ( i.hasTerms() )
+      {
+        findGoodPrime(i.coeff(),start);
+        if (0==cf_getBigPrime(start)) return;
+        if((i.exp()!=0) && ((i.exp() % cf_getBigPrime(start))==0))
+        {
+          start++;
+          i=f;
+        }
+        else  i++;
+      }
+      else break;
+    }
+  }
+  else
+  {
+    if (f.inZ())
+    {
+      if (0==cf_getBigPrime(start)) return;
+      while((!f.isZero()) && (mod(f,cf_getBigPrime(start))==0))
+      {
+        start++;
+        if (0==cf_getBigPrime(start)) return;
+      }
+    }
+  }
+}
+
+modpk
+coeffBound ( const CanonicalForm & f, int p, const CanonicalForm& mipo )
+{
+    int * degs = degrees( f );
+    int M = 0, i, k = f.level();
+    CanonicalForm K= 1;
+    for ( i = 1; i <= k; i++ )
+    {
+        M += degs[i];
+        K *= degs[i] + 1;
+    }
+    K /= power (CanonicalForm (2), k/2);
+    K *= power (CanonicalForm (2), M);
+    int N= degree (mipo);
+    CanonicalForm b;
+    b= 2*power (maxNorm (f), N)*power (maxNorm (mipo), 4*N)*K*
+       power (CanonicalForm (2), N)*
+       power (CanonicalForm (N+1), 4*N);
+    b /= power (abs (lc (mipo)), N);
+
+    CanonicalForm B = p;
+    k = 1;
+    while ( B < b ) {
+        B *= p;
+        k++;
+    }
+    return modpk( p, k );
+}
+
+CFList conv (const CFFList& L)
+{
+  CFList result;
+  for (CFFListIterator i= L; i.hasItem(); i++)
+    result.append (i.getItem().factor());
+  return result;
+}
+
+bool testPoint (const CanonicalForm& F, CanonicalForm& G, int i)
+{
+  G= F (i, 2);
+  if (G.inCoeffDomain() || degree (F, 1) > degree (G, 1))
+    return false;
+
+  if (degree (gcd (deriv (G, G.mvar()), G)) > 0)
+    return false;
+  return true;
+}
+
+CanonicalForm evalPoint (const CanonicalForm& F, int& i)
+{
+  Variable x= Variable (1);
+  Variable y= Variable (2);
+  CanonicalForm result;
+
+  int k;
+
+  if (i == 0)
+  {
+    if (testPoint (F, result, i))
+      return result;
+  }
+  do
+  {
+    if (i > 0)
+      k= 1;
+    else
+      k= 2;
+    while (k < 3)
+    {
+      if (k == 1)
+      {
+        if (testPoint (F, result, i))
+          return result;
+      }
+      else
+      {
+        if (testPoint (F, result, -i))
+        {
+          i= -i;
+          return result;
+        }
+        else if (i < 0)
+          i= -i;
+      }
+      k++;
+    }
+    i++;
+  } while (1);
+}
+
+CFList biFactorize (const CanonicalForm& F, const Variable& v)
+{
+  if (F.inCoeffDomain())
+    return CFList(F);
+
+  bool extension= (v.level() != 1);
+  CanonicalForm A;
+  if (isOn (SW_RATIONAL))
+    A= F*bCommonDen (F);
+  else
+    A= F;
+
+  CanonicalForm mipo;
+  if (extension)
+    mipo= getMipo (v);
+
+  if (A.isUnivariate())
+  {
+    CFFList buf;
+    if (extension)
+      buf= factorize (A, v);
+    else
+      buf= factorize (A, true);
+    CFList result= conv (buf);
+    if (result.getFirst().inCoeffDomain())
+      result.removeFirst();
+    return result;
+  }
+
+  CFMap N;
+  A= compress (A, N);
+  Variable y= A.mvar();
+
+  if (y.level() > 2) return CFList (F);
+  Variable x= Variable (1);
+
+  CanonicalForm contentAx= content (A, x);
+  CanonicalForm contentAy= content (A);
+
+  A= A/(contentAx*contentAy);
+  CFFList contentAxFactors, contentAyFactors;
+
+  if (extension)
+  {
+    if (!contentAx.inCoeffDomain())
+    {
+      contentAxFactors= factorize (contentAx, v);
+      if (contentAxFactors.getFirst().factor().inCoeffDomain())
+        contentAxFactors.removeFirst();
+    }
+    if (!contentAy.inCoeffDomain())
+    {
+      contentAyFactors= factorize (contentAy, v);
+      if (contentAyFactors.getFirst().factor().inCoeffDomain())
+        contentAyFactors.removeFirst();
+    }
+  }
+  else
+  {
+    if (!contentAx.inCoeffDomain())
+    {
+      contentAxFactors= factorize (contentAx, true);
+      if (contentAxFactors.getFirst().factor().inCoeffDomain())
+        contentAxFactors.removeFirst();
+    }
+    if (!contentAy.inCoeffDomain())
+    {
+      contentAyFactors= factorize (contentAy, true);
+      if (contentAyFactors.getFirst().factor().inCoeffDomain())
+        contentAyFactors.removeFirst();
+    }
+  }
+
+  //check trivial case
+  if (degree (A) == 1 || degree (A, 1) == 1 ||
+      (size (A) == 2 && igcd (degree (A), degree (A,1)) == 1))
+  {
+    CFList factors;
+    factors.append (A);
+
+    appendSwapDecompress (factors, conv (contentAxFactors),
+                          conv (contentAyFactors), false, false, N);
+
+    normalize (factors);
+    return factors;
+  }
+
+  //trivial case
+  CFList factors;
+  if (A.inCoeffDomain())
+  {
+    append (factors, conv (contentAxFactors));
+    append (factors, conv (contentAyFactors));
+    decompress (factors, N);
+    return factors;
+  }
+  else if (A.isUnivariate())
+  {
+    if (extension)
+      factors= conv (factorize (A, v));
+    else
+      factors= conv (factorize (A, true));
+    append (factors, conv (contentAxFactors));
+    append (factors, conv (contentAyFactors));
+    decompress (factors, N);
+    return factors;
+  }
+
+  if (irreducibilityTest (A))
+  {
+    CFList factors;
+    factors.append (A);
+
+    appendSwapDecompress (factors, conv (contentAxFactors),
+                          conv (contentAyFactors), false, false, N);
+
+    normalize (factors);
+    return factors;
+  }
+  bool swap= false;
+  if (degree (A) > degree (A, x))
+  {
+    A= swapvar (A, y, x);
+    swap= true;
+  }
+
+  CanonicalForm Aeval, bufAeval, buf;
+  CFList uniFactors, list, bufUniFactors;
+  DegreePattern degs;
+  DegreePattern bufDegs;
+
+  CanonicalForm Aeval2, bufAeval2;
+  CFList bufUniFactors2, list2, uniFactors2;
+  DegreePattern degs2;
+  DegreePattern bufDegs2;
+  bool swap2= false;
+
+  // several univariate factorizations to obtain more information about the
+  // degree pattern therefore usually less combinations have to be tried during
+  // the recombination process
+  int factorNums= 2;
+  int subCheck1= substituteCheck (A, x);
+  int subCheck2= substituteCheck (A, y);
+  buf= swapvar (A,x,y);
+  int evaluation, evaluation2, bufEvaluation= 0, bufEvaluation2= 0;
+  for (int i= 0; i < factorNums; i++)
+  {
+    bufAeval= A;
+    TIMING_START (fac_bi_evaluation);
+    bufAeval= evalPoint (A, bufEvaluation);
+    TIMING_END_AND_PRINT (fac_bi_evaluation, "time for eval point over Q: ");
+
+    bufAeval2= buf;
+    TIMING_START (fac_bi_evaluation);
+    bufAeval2= evalPoint (buf, bufEvaluation2);
+    TIMING_END_AND_PRINT (fac_bi_evaluation,
+                          "time for eval point over Q in y: ");
+
+    // univariate factorization
+    TIMING_START (fac_uni_factorizer);
+    if (extension)
+      bufUniFactors= conv (factorize (bufAeval, v));
+    else
+      bufUniFactors= conv (factorize (bufAeval, true));
+    TIMING_END_AND_PRINT (fac_uni_factorizer,
+                          "time for univariate factorization over Q: ");
+    DEBOUTLN (cerr, "prod (bufUniFactors)== bufAeval " <<
+              (prod (bufUniFactors) == bufAeval));
+
+    if (bufUniFactors.getFirst().inCoeffDomain())
+      bufUniFactors.removeFirst();
+
+    if (bufUniFactors.length() == 1)
+    {
+      factors.append (A);
+
+      appendSwapDecompress (factors, conv (contentAxFactors),
+                            conv (contentAyFactors), swap, swap2, N);
+
+      if (isOn (SW_RATIONAL))
+        normalize (factors);
+      return factors;
+    }
+
+    TIMING_START (fac_uni_factorizer);
+    if (extension)
+      bufUniFactors2= conv (factorize (bufAeval2, v));
+    else
+      bufUniFactors2= conv (factorize (bufAeval2, true));
+    TIMING_END_AND_PRINT (fac_uni_factorizer,
+                          "time for univariate factorization in y over Q: ");
+    DEBOUTLN (cerr, "prod (bufuniFactors2)== bufAeval2 " <<
+              (prod (bufUniFactors2) == bufAeval2));
+
+    if (bufUniFactors2.getFirst().inCoeffDomain())
+      bufUniFactors2.removeFirst();
+    if (bufUniFactors2.length() == 1)
+    {
+      factors.append (A);
+
+      appendSwapDecompress (factors, conv (contentAxFactors),
+                            conv (contentAyFactors), swap, swap2, N);
+
+      if (isOn (SW_RATIONAL))
+        normalize (factors);
+      return factors;
+    }
+
+    if (i == 0)
+    {
+      if (subCheck1 > 0)
+      {
+        int subCheck= substituteCheck (bufUniFactors);
+
+        if (subCheck > 1 && (subCheck1%subCheck == 0))
+        {
+          CanonicalForm bufA= A;
+          subst (bufA, bufA, subCheck, x);
+          factors= biFactorize (bufA, v);
+          reverseSubst (factors, subCheck, x);
+          appendSwapDecompress (factors, conv (contentAxFactors),
+                                conv (contentAyFactors), swap, swap2, N);
+          if (isOn (SW_RATIONAL))
+            normalize (factors);
+          return factors;
+        }
+      }
+
+      if (subCheck2 > 0)
+      {
+        int subCheck= substituteCheck (bufUniFactors2);
+
+        if (subCheck > 1 && (subCheck2%subCheck == 0))
+        {
+          CanonicalForm bufA= A;
+          subst (bufA, bufA, subCheck, y);
+          factors= biFactorize (bufA, v);
+          reverseSubst (factors, subCheck, y);
+          appendSwapDecompress (factors, conv (contentAxFactors),
+                                conv (contentAyFactors), swap, swap2, N);
+          if (isOn (SW_RATIONAL))
+            normalize (factors);
+          return factors;
+        }
+      }
+    }
+
+    // degree analysis
+    bufDegs = DegreePattern (bufUniFactors);
+    bufDegs2= DegreePattern (bufUniFactors2);
+
+    if (i == 0)
+    {
+      Aeval= bufAeval;
+      evaluation= bufEvaluation;
+      uniFactors= bufUniFactors;
+      degs= bufDegs;
+      Aeval2= bufAeval2;
+      evaluation2= bufEvaluation2;
+      uniFactors2= bufUniFactors2;
+      degs2= bufDegs2;
+    }
+    else
+    {
+      degs.intersect (bufDegs);
+      degs2.intersect (bufDegs2);
+      if (bufUniFactors2.length() < uniFactors2.length())
+      {
+        uniFactors2= bufUniFactors2;
+        Aeval2= bufAeval2;
+        evaluation2= bufEvaluation2;
+      }
+      if (bufUniFactors.length() < uniFactors.length())
+      {
+        uniFactors= bufUniFactors;
+        Aeval= bufAeval;
+        evaluation= bufEvaluation;
+      }
+    }
+    if (bufEvaluation > 0)
+      bufEvaluation++;
+    else
+      bufEvaluation= -bufEvaluation + 1;
+    if (bufEvaluation > 0)
+      bufEvaluation2++;
+    else
+      bufEvaluation2= -bufEvaluation2 + 1;
+  }
+
+  if (uniFactors.length() > uniFactors2.length() ||
+      (uniFactors.length() == uniFactors2.length()
+       && degs.getLength() > degs2.getLength()))
+  {
+    degs= degs2;
+    uniFactors= uniFactors2;
+    evaluation= evaluation2;
+    Aeval= Aeval2;
+    A= buf;
+    swap2= true;
+  }
+
+  if (degs.getLength() == 1) // A is irreducible
+  {
+    factors.append (A);
+    appendSwapDecompress (factors, conv (contentAxFactors),
+                          conv (contentAyFactors), swap, swap2, N);
+    if (isOn (SW_RATIONAL))
+      normalize (factors);
+    return factors;
+  }
+
+  A *= bCommonDen (A);
+  A= A (y + evaluation, y);
+
+  int liftBound= degree (A, y) + 1;
+
+  modpk b= modpk();
+  bool mipoHasDen= false;
+  CanonicalForm den= 1;
+  if (!extension)
+  {
+    Off (SW_RATIONAL);
+    int i= 0;
+    findGoodPrime(F,i);
+    findGoodPrime(Aeval,i);
+    findGoodPrime(A,i);
+    if (i >= cf_getNumBigPrimes())
+      printf ("out of primes\n"); //TODO exit
+
+    int p=cf_getBigPrime(i);
+    b = coeffBound( A, p );
+    modpk bb= coeffBound (Aeval, p);
+    if (bb.getk() > b.getk() ) b=bb;
+      bb= coeffBound (F, p);
+    if (bb.getk() > b.getk() ) b=bb;
+  }
+  else
+  {
+    A /= Lc (Aeval);
+    mipoHasDen= !bCommonDen(mipo).isOne();
+    mipo *= bCommonDen (mipo);
+    ZZX NTLmipo= convertFacCF2NTLZZX (mipo);
+    ZZX NTLLcf= convertFacCF2NTLZZX (Lc (A*bCommonDen (A)));
+    ZZ NTLf= resultant (NTLmipo, NTLLcf);
+    ZZ NTLD= discriminant (NTLmipo);
+    den= abs (convertZZ2CF (NTLD*NTLf));
+
+    // make factors elements of Z(a)[x] disable for modularDiophant
+    CanonicalForm multiplier= 1;
+    for (CFListIterator i= uniFactors; i.hasItem(); i++)
+    {
+      multiplier *= bCommonDen (i.getItem());
+      i.getItem()= i.getItem()*bCommonDen(i.getItem());
+    }
+    A *= multiplier;
+    A *= bCommonDen (A);
+
+    Off (SW_RATIONAL);
+    int i= 0;
+    CanonicalForm discMipo= convertZZ2CF (NTLD);
+    findGoodPrime (F*discMipo,i);
+    findGoodPrime (Aeval*discMipo,i);
+    findGoodPrime (A*discMipo,i);
+
+    int p=cf_getBigPrime(i);
+    b = coeffBound( A, p, mipo );
+    modpk bb= coeffBound (Aeval, p, mipo);
+    if (bb.getk() > b.getk() ) b=bb;
+      bb= coeffBound (F, p, mipo);
+    if (bb.getk() > b.getk() ) b=bb;
+  }
+
+  ExtensionInfo dummy= ExtensionInfo (false);
+  if (extension)
+    dummy= ExtensionInfo (v, false);
+  bool earlySuccess= false;
+  CFList earlyFactors;
+  TIMING_START (fac_bi_hensel_lift);
+  uniFactors= henselLiftAndEarly
+              (A, earlySuccess, earlyFactors, degs, liftBound,
+               uniFactors, dummy, evaluation, b, den);
+  TIMING_END_AND_PRINT (fac_bi_hensel_lift,
+                        "time for bivariate hensel lifting over Q: ");
+  DEBOUTLN (cerr, "lifted factors= " << uniFactors);
+
+  CanonicalForm MODl= power (y, liftBound);
+
+  if (mipoHasDen)
+  {
+    Variable vv;
+    for (CFListIterator iter= uniFactors; iter.hasItem(); iter++)
+      if (hasFirstAlgVar (iter.getItem(), vv))
+        break;
+    for (CFListIterator iter= uniFactors; iter.hasItem(); iter++)
+      iter.getItem()= replacevar (iter.getItem(), vv, v);
+    prune (vv);
+  }
+
+  On (SW_RATIONAL);
+  A *= bCommonDen (A);
+  Off (SW_RATIONAL);
+
+  TIMING_START (fac_bi_factor_recombination);
+  factors= factorRecombination (uniFactors, A, MODl, degs, evaluation, 1,
+                                uniFactors.length()/2, b, den);
+  TIMING_END_AND_PRINT (fac_bi_factor_recombination,
+                        "time for bivariate factor recombination over Q: ");
+
+  On (SW_RATIONAL);
+
+  if (earlySuccess)
+    factors= Union (earlyFactors, factors);
+  else if (!earlySuccess && degs.getLength() == 1)
+    factors= earlyFactors;
+
+  appendSwapDecompress (factors, conv (contentAxFactors),
+                        conv (contentAyFactors), swap, swap2, N);
+  if (isOn (SW_RATIONAL))
+    normalize (factors);
+
+  return factors;
+}
+
+#endif
diff --git a/factory/facBivar.h b/factory/facBivar.h
new file mode 100644
index 0000000..454b469
--- /dev/null
+++ b/factory/facBivar.h
@@ -0,0 +1,306 @@
+/*****************************************************************************\
+ * Computer Algebra System SINGULAR
+\*****************************************************************************/
+/** @file facBivar.h
+ *
+ * bivariate factorization over Q(a)
+ *
+ * @author Martin Lee
+ *
+ **/
+/*****************************************************************************/
+
+#ifndef FAC_BIVAR_H
+#define FAC_BIVAR_H
+
+// #include "config.h"
+
+#include "cf_assert.h"
+#include "timing.h"
+
+#include "facFqBivarUtil.h"
+#include "DegreePattern.h"
+#include "cf_util.h"
+#include "facFqSquarefree.h"
+#include "cf_map.h"
+#include "cfNewtonPolygon.h"
+#include "fac_util.h"
+
+TIMING_DEFINE_PRINT(fac_bi_sqrf)
+TIMING_DEFINE_PRINT(fac_bi_factor_sqrf)
+
+/// @return @a biFactorize returns a list of factors of F. If F is not monic
+///         its leading coefficient is not outputted.
+CFList
+biFactorize (const CanonicalForm& F,       ///< [in] a sqrfree bivariate poly
+             const Variable& v             ///< [in] some algebraic variable
+            );
+
+/// factorize a squarefree bivariate polynomial over \f$ Q(\alpha) \f$.
+///
+/// @ return @a ratBiSqrfFactorize returns a list of monic factors, the first
+///         element is the leading coefficient.
+#ifdef HAVE_NTL
+inline
+CFList
+ratBiSqrfFactorize (const CanonicalForm & G,        ///< [in] a bivariate poly
+                    const Variable& v= Variable (1) ///< [in] algebraic variable
+                   )
+{
+  CFMap N;
+  CanonicalForm F= compress (G, N);
+  CanonicalForm contentX= content (F, 1); //erwarte hier primitiven input: primitiv über Z bzw. Z[a]
+  CanonicalForm contentY= content (F, 2);
+  F /= (contentX*contentY);
+  CFFList contentXFactors, contentYFactors;
+  if (v.level() != 1)
+  {
+    contentXFactors= factorize (contentX, v);
+    contentYFactors= factorize (contentY, v);
+  }
+  else
+  {
+    contentXFactors= factorize (contentX);
+    contentYFactors= factorize (contentY);
+  }
+  if (contentXFactors.getFirst().factor().inCoeffDomain())
+    contentXFactors.removeFirst();
+  if (contentYFactors.getFirst().factor().inCoeffDomain())
+    contentYFactors.removeFirst();
+  if (F.inCoeffDomain())
+  {
+    CFList result;
+    for (CFFListIterator i= contentXFactors; i.hasItem(); i++)
+      result.append (N (i.getItem().factor()));
+    for (CFFListIterator i= contentYFactors; i.hasItem(); i++)
+      result.append (N (i.getItem().factor()));
+    if (isOn (SW_RATIONAL))
+    {
+      normalize (result);
+      result.insert (Lc (G));
+    }
+    return result;
+  }
+
+  mpz_t * M=new mpz_t [4];
+  mpz_init (M[0]);
+  mpz_init (M[1]);
+  mpz_init (M[2]);
+  mpz_init (M[3]);
+
+  mpz_t * S=new mpz_t [2];
+  mpz_init (S[0]);
+  mpz_init (S[1]);
+
+  F= compress (F, M, S);
+  CFList result= biFactorize (F, v);
+  for (CFListIterator i= result; i.hasItem(); i++)
+    i.getItem()= N (decompress (i.getItem(), M, S));
+  for (CFFListIterator i= contentXFactors; i.hasItem(); i++)
+    result.append (N(i.getItem().factor()));
+  for (CFFListIterator i= contentYFactors; i.hasItem(); i++)
+    result.append (N (i.getItem().factor()));
+  if (isOn (SW_RATIONAL))
+  {
+    normalize (result);
+    result.insert (Lc (G));
+  }
+
+  mpz_clear (M[0]);
+  mpz_clear (M[1]);
+  mpz_clear (M[2]);
+  mpz_clear (M[3]);
+  delete [] M;
+
+  mpz_clear (S[0]);
+  mpz_clear (S[1]);
+  delete [] S;
+
+  return result;
+}
+
+/// factorize a bivariate polynomial over \f$ Q(\alpha) \f$
+///
+/// @return @a ratBiFactorize returns a list of monic factors with
+///         multiplicity, the first element is the leading coefficient.
+inline
+CFFList
+ratBiFactorize (const CanonicalForm & G,         ///< [in] a bivariate poly
+                const Variable& v= Variable (1), ///< [in] algebraic variable
+                bool substCheck= true        ///< [in] enables substitute check
+               )
+{
+  CFMap N;
+  CanonicalForm F= compress (G, N);
+
+  if (substCheck)
+  {
+    bool foundOne= false;
+    int * substDegree= new int [F.level()];
+    for (int i= 1; i <= F.level(); i++)
+    {
+      substDegree[i-1]= substituteCheck (F, Variable (i));
+      if (substDegree [i-1] > 1)
+      {
+        foundOne= true;
+        subst (F, F, substDegree[i-1], Variable (i));
+      }
+    }
+    if (foundOne)
+    {
+      CFFList result= ratBiFactorize (F, v, false);
+      CFFList newResult, tmp;
+      CanonicalForm tmp2;
+      newResult.insert (result.getFirst());
+      result.removeFirst();
+      for (CFFListIterator i= result; i.hasItem(); i++)
+      {
+        tmp2= i.getItem().factor();
+        for (int j= 1; j <= F.level(); j++)
+        {
+          if (substDegree[j-1] > 1)
+            tmp2= reverseSubst (tmp2, substDegree[j-1], Variable (j));
+        }
+        tmp= ratBiFactorize (tmp2, v, false);
+        tmp.removeFirst();
+        for (CFFListIterator j= tmp; j.hasItem(); j++)
+          newResult.append (CFFactor (j.getItem().factor(),
+                                      j.getItem().exp()*i.getItem().exp()));
+      }
+      decompress (newResult, N);
+      delete [] substDegree;
+      return newResult;
+    }
+    delete [] substDegree;
+  }
+
+  CanonicalForm LcF= Lc (F);
+  CanonicalForm contentX= content (F, 1);
+  CanonicalForm contentY= content (F, 2);
+  F /= (contentX*contentY);
+  CFFList contentXFactors, contentYFactors;
+  if (v.level() != 1)
+  {
+    contentXFactors= factorize (contentX, v);
+    contentYFactors= factorize (contentY, v);
+  }
+  else
+  {
+    contentXFactors= factorize (contentX);
+    contentYFactors= factorize (contentY);
+  }
+  if (contentXFactors.getFirst().factor().inCoeffDomain())
+    contentXFactors.removeFirst();
+  if (contentYFactors.getFirst().factor().inCoeffDomain())
+    contentYFactors.removeFirst();
+  decompress (contentXFactors, N);
+  decompress (contentYFactors, N);
+  CFFList result, resultRoot;
+  if (F.inCoeffDomain())
+  {
+    result= Union (contentXFactors, contentYFactors);
+    if (isOn (SW_RATIONAL))
+    {
+      normalize (result);
+      if (v.level() == 1)
+      {
+        for (CFFListIterator i= result; i.hasItem(); i++)
+        {
+          LcF /= power (bCommonDen (i.getItem().factor()), i.getItem().exp());
+          i.getItem()= CFFactor (i.getItem().factor()*
+                       bCommonDen(i.getItem().factor()), i.getItem().exp());
+        }
+      }
+      result.insert (CFFactor (LcF, 1));
+    }
+    return result;
+  }
+
+  mpz_t * M=new mpz_t [4];
+  mpz_init (M[0]);
+  mpz_init (M[1]);
+  mpz_init (M[2]);
+  mpz_init (M[3]);
+
+  mpz_t * S=new mpz_t [2];
+  mpz_init (S[0]);
+  mpz_init (S[1]);
+
+  F= compress (F, M, S);
+  TIMING_START (fac_bi_sqrf);
+  CFFList sqrfFactors= sqrFree (F);
+  TIMING_END_AND_PRINT (fac_bi_sqrf,
+                       "time for bivariate sqrf factors over Q: ");
+  for (CFFListIterator i= sqrfFactors; i.hasItem(); i++)
+  {
+    TIMING_START (fac_bi_factor_sqrf);
+    CFList tmp= ratBiSqrfFactorize (i.getItem().factor(), v);
+    TIMING_END_AND_PRINT (fac_bi_factor_sqrf,
+                          "time to factor bivariate sqrf factors over Q: ");
+    for (CFListIterator j= tmp; j.hasItem(); j++)
+    {
+      if (j.getItem().inCoeffDomain()) continue;
+      result.append (CFFactor (N (decompress (j.getItem(), M, S)),
+                               i.getItem().exp()));
+    }
+  }
+  result= Union (result, contentXFactors);
+  result= Union (result, contentYFactors);
+  if (isOn (SW_RATIONAL))
+  {
+    normalize (result);
+    if (v.level() == 1)
+    {
+      for (CFFListIterator i= result; i.hasItem(); i++)
+      {
+        LcF /= power (bCommonDen (i.getItem().factor()), i.getItem().exp());
+        i.getItem()= CFFactor (i.getItem().factor()*
+                     bCommonDen(i.getItem().factor()), i.getItem().exp());
+      }
+    }
+    result.insert (CFFactor (LcF, 1));
+  }
+
+  mpz_clear (M[0]);
+  mpz_clear (M[1]);
+  mpz_clear (M[2]);
+  mpz_clear (M[3]);
+  delete [] M;
+
+  mpz_clear (S[0]);
+  mpz_clear (S[1]);
+  delete [] S;
+
+  return result;
+}
+
+#endif
+
+/// convert a CFFList to a CFList by dropping the multiplicity
+CFList conv (const CFFList& L ///< [in] a CFFList
+            );
+
+/// compute p^k larger than the bound on the coefficients of a factor of @a f
+/// over Q (mipo)
+modpk
+coeffBound (const CanonicalForm & f,  ///< [in] poly over Z[a]
+            int p,                    ///< [in] some positive integer
+            const CanonicalForm& mipo ///< [in] minimal polynomial with
+                                      ///< denominator 1
+           );
+
+/// find a big prime p from our tables such that no term of f vanishes mod p
+void findGoodPrime(const CanonicalForm &f, ///< [in] poly over Z or Z[a]
+                   int &start              ///< [in,out] index of big prime in
+                                           /// cf_primetab.h
+                  );
+
+/// compute p^k larger than the bound on the coefficients of a factor of @a f
+/// over Z
+modpk
+coeffBound (const CanonicalForm & f, ///< [in] poly over Z
+            int p                    ///< [in] some positive integer
+           );
+
+#endif
+
diff --git a/factory/facFactorize.cc b/factory/facFactorize.cc
new file mode 100644
index 0000000..a27d626
--- /dev/null
+++ b/factory/facFactorize.cc
@@ -0,0 +1,832 @@
+/*****************************************************************************\
+ * Computer Algebra System SINGULAR
+\*****************************************************************************/
+/** @file facFactorize.cc
+ *
+ * multivariate factorization over Q(a)
+ *
+ * @author Martin Lee
+ *
+ **/
+/*****************************************************************************/
+
+
+#include "config.h"
+
+
+#include "cf_assert.h"
+#include "debug.h"
+#include "timing.h"
+
+#include "cf_algorithm.h"
+#include "facFqFactorizeUtil.h"
+#include "facFactorize.h"
+#include "facFqFactorize.h"
+#include "cf_random.h"
+#include "facHensel.h"
+#include "cf_map_ext.h"
+#include "cf_reval.h"
+#include "facSparseHensel.h"
+#include "cfUnivarGcd.h"
+
+TIMING_DEFINE_PRINT(fac_bi_factorizer)
+TIMING_DEFINE_PRINT(fac_hensel_lift)
+TIMING_DEFINE_PRINT(fac_factor_recombination)
+TIMING_DEFINE_PRINT(fac_shift_to_zero)
+TIMING_DEFINE_PRINT(fac_precompute_leadcoeff)
+TIMING_DEFINE_PRINT(fac_evaluation)
+TIMING_DEFINE_PRINT(fac_recover_factors)
+TIMING_DEFINE_PRINT(fac_preprocess_and_content)
+TIMING_DEFINE_PRINT(fac_bifactor_total)
+TIMING_DEFINE_PRINT(fac_luckswang)
+TIMING_DEFINE_PRINT(fac_lcheuristic)
+TIMING_DEFINE_PRINT(fac_cleardenom)
+TIMING_DEFINE_PRINT(fac_content)
+TIMING_DEFINE_PRINT(fac_compress)
+
+#ifdef HAVE_NTL
+CFList evalPoints (const CanonicalForm& F, CFList& eval, Evaluation& E)
+{
+  CFList result;
+  Variable x= Variable (1);
+
+  CanonicalForm LCF=LC (F,x);
+  CFList LCFeval;
+
+  bool found= false;
+  bool allZero= true;
+  bool foundZero= false;
+  CanonicalForm deriv_x, gcd_deriv;
+  CFListIterator iter;
+  do
+  {
+    eval.insert (F);
+    LCFeval.insert (LCF);
+    bool bad= false;
+    for (int i= E.max(); i >= E.min(); i--)
+    {
+      eval.insert (eval.getFirst()( E [i], i));
+      LCFeval.insert (LCFeval.getFirst() (E [i], i));
+      result.append (E[i]);
+      if (!E[i].isZero())
+        allZero= false;
+      else
+        foundZero= true;
+      if (!allZero && foundZero)
+      {
+        result= CFList();
+        eval= CFList();
+        LCFeval= CFList();
+        bad= true;
+        foundZero= false;
+        break;
+      }
+      if (degree (eval.getFirst(), i - 1) != degree (F, i - 1))
+      {
+        result= CFList();
+        eval= CFList();
+        LCFeval= CFList();
+        bad= true;
+        break;
+      }
+      if ((i != 2) && (degree (LCFeval.getFirst(), i-1) != degree (LCF, i-1)))
+      {
+        result= CFList();
+        eval= CFList();
+        LCFeval= CFList();
+        bad= true;
+        break;
+      }
+    }
+
+    if (bad)
+    {
+      E.nextpoint();
+      continue;
+    }
+
+    if (degree (eval.getFirst()) != degree (F, 1))
+    {
+      result= CFList();
+      eval= CFList();
+      LCFeval= CFList();
+      E.nextpoint();
+      continue;
+    }
+
+    deriv_x= deriv (eval.getFirst(), x);
+    gcd_deriv= gcd (eval.getFirst(), deriv_x);
+    if (degree (gcd_deriv) > 0)
+    {
+      result= CFList();
+      eval= CFList();
+      LCFeval= CFList();
+      E.nextpoint();
+      continue;
+    }
+    iter= eval;
+    iter++;
+    CanonicalForm contentx= content (iter.getItem(), x);
+    if (degree (contentx) > 0)
+    {
+      result= CFList();
+      eval= CFList();
+      LCFeval= CFList();
+      E.nextpoint();
+      continue;
+    }
+    contentx= content (iter.getItem());
+    if (degree (contentx) > 0)
+    {
+      result= CFList();
+      eval= CFList();
+      LCFeval= CFList();
+      E.nextpoint();
+      continue;
+    }
+    found= true;
+  }
+  while (!found);
+
+  if (!eval.isEmpty())
+    eval.removeFirst();
+  return result;
+}
+
+void
+factorizationWRTDifferentSecondVars (const CanonicalForm& A, CFList*& Aeval,
+                                     int& minFactorsLength, bool& irred,
+                                     const Variable& w)
+{
+  Variable x= Variable (1);
+  minFactorsLength= 0;
+  irred= false;
+  Variable v;
+  CFList factors;
+  CanonicalForm LCA= LC (A,1);
+  for (int j= 0; j < A.level() - 2; j++)
+  {
+    if (!Aeval[j].isEmpty())
+    {
+      v= Variable (Aeval[j].getFirst().level());
+
+      factors= ratBiSqrfFactorize (Aeval[j].getFirst(), w);
+      if (factors.getFirst().inCoeffDomain())
+        factors.removeFirst();
+
+      if (minFactorsLength == 0)
+        minFactorsLength= factors.length();
+      else
+        minFactorsLength= tmin (minFactorsLength, factors.length());
+
+      if (factors.length() == 1)
+      {
+        irred= true;
+        return;
+      }
+      sortList (factors, x);
+      Aeval [j]= factors;
+    }
+  }
+}
+
+CFList
+multiFactorize (const CanonicalForm& F, const Variable& v)
+{
+  if (F.inCoeffDomain())
+    return CFList (F);
+
+  TIMING_START (fac_preprocess_and_content);
+  // compress and find main Variable
+  CFMap N;
+  TIMING_START (fac_compress)
+  CanonicalForm A= myCompress (F, N);
+  TIMING_END_AND_PRINT (fac_compress, "time to compress poly over Q: ")
+
+  //univariate case
+  if (F.isUnivariate())
+  {
+    CFList result;
+    if (v.level() != 1)
+      result= conv (factorize (F, v));
+    else
+      result= conv (factorize (F,true));
+    if (result.getFirst().inCoeffDomain())
+      result.removeFirst();
+    return result;
+  }
+
+  //bivariate case
+  if (A.level() == 2)
+  {
+    CFList buf= ratBiSqrfFactorize (F, v);
+    if (buf.getFirst().inCoeffDomain())
+      buf.removeFirst();
+    return buf;
+  }
+
+  Variable x= Variable (1);
+  Variable y= Variable (2);
+
+  // remove content
+  TIMING_START (fac_content);
+  CFList contentAi;
+  CanonicalForm lcmCont= lcmContent (A, contentAi);
+  A /= lcmCont;
+  TIMING_END_AND_PRINT (fac_content, "time to extract content over Q: ");
+
+  // trivial after content removal
+  CFList contentAFactors;
+  if (A.inCoeffDomain())
+  {
+    for (CFListIterator i= contentAi; i.hasItem(); i++)
+    {
+      if (i.getItem().inCoeffDomain())
+        continue;
+      else
+      {
+        lcmCont /= i.getItem();
+        contentAFactors=
+        Union (multiFactorize (lcmCont, v),
+               multiFactorize (i.getItem(), v));
+        break;
+      }
+    }
+    decompress (contentAFactors, N);
+    if (isOn (SW_RATIONAL))
+      normalize (contentAFactors);
+    return contentAFactors;
+  }
+
+  // factorize content
+  TIMING_START (fac_content);
+  contentAFactors= multiFactorize (lcmCont, v);
+  TIMING_END_AND_PRINT (fac_content, "time to factor content over Q: ");
+
+  // univariate after content removal
+  CFList factors;
+  if (A.isUnivariate ())
+  {
+    if (v.level() != 1)
+      factors= conv (factorize (A, v));
+    else
+      factors= conv (factorize (A,true));
+    append (factors, contentAFactors);
+    decompress (factors, N);
+    return factors;
+  }
+
+  A *= bCommonDen (A);
+  CFList Aeval, list, evaluation, bufEvaluation, bufAeval;
+  int factorNums= 2;
+  //p is irreducible. But factorize does not recognizes this. However, if you
+  //change factorNums to 2 at line 281 in facFactorize.cc it will. That change
+  //might impair performance in some cases since you do twice as many
+  //bivariate factorizations as before. Otherwise you need to change
+  //precomputeLeadingCoeff to detect these cases and trigger more bivariate
+  // factorizations.
+  // (http://www.singular.uni-kl.de:8002/trac/ticket/666)
+  CFList biFactors, bufBiFactors;
+  CanonicalForm evalPoly;
+  int lift, bufLift, lengthAeval2= A.level()-2;
+  CFList* bufAeval2= new CFList [lengthAeval2];
+  CFList* Aeval2= new CFList [lengthAeval2];
+  int counter;
+  int differentSecondVar= 0;
+  CanonicalForm bufA;
+  TIMING_END_AND_PRINT (fac_preprocess_and_content,
+                       "time to preprocess poly and extract content over Q: ");
+
+  // several bivariate factorizations
+  TIMING_START (fac_bifactor_total);
+  REvaluation E (2, A.level(), IntRandom (25));
+  for (int i= 0; i < factorNums; i++)
+  {
+    counter= 0;
+    bufA= A;
+    bufAeval= CFList();
+    TIMING_START (fac_evaluation);
+    bufEvaluation= evalPoints (bufA, bufAeval, E);
+    TIMING_END_AND_PRINT (fac_evaluation,
+                          "time to find evaluation point over Q: ");
+    E.nextpoint();
+    evalPoly= 0;
+
+    TIMING_START (fac_evaluation);
+    evaluationWRTDifferentSecondVars (bufAeval2, bufEvaluation, A);
+    TIMING_END_AND_PRINT (fac_evaluation,
+                          "time to eval wrt diff second vars over Q: ");
+
+    for (int j= 0; j < lengthAeval2; j++)
+    {
+      if (!bufAeval2[j].isEmpty())
+        counter++;
+    }
+
+    bufLift= degree (A, y) + 1 + degree (LC(A, x), y);
+
+    TIMING_START (fac_bi_factorizer);
+    bufBiFactors= ratBiSqrfFactorize (bufAeval.getFirst(), v);
+    TIMING_END_AND_PRINT (fac_bi_factorizer,
+                          "time for bivariate factorization: ");
+    bufBiFactors.removeFirst();
+
+    if (bufBiFactors.length() == 1)
+    {
+      factors.append (A);
+      appendSwapDecompress (factors, contentAFactors, N, 0, 0, x);
+      if (isOn (SW_RATIONAL))
+        normalize (factors);
+      delete [] bufAeval2;
+      delete [] Aeval2;
+      return factors;
+    }
+
+    if (i == 0)
+    {
+      Aeval= bufAeval;
+      evaluation= bufEvaluation;
+      biFactors= bufBiFactors;
+      lift= bufLift;
+      for (int j= 0; j < lengthAeval2; j++)
+        Aeval2 [j]= bufAeval2 [j];
+      differentSecondVar= counter;
+    }
+    else
+    {
+      if (bufBiFactors.length() < biFactors.length() ||
+          ((bufLift < lift) && (bufBiFactors.length() == biFactors.length())) ||
+          counter > differentSecondVar)
+      {
+        Aeval= bufAeval;
+        evaluation= bufEvaluation;
+        biFactors= bufBiFactors;
+        lift= bufLift;
+        for (int j= 0; j < lengthAeval2; j++)
+          Aeval2 [j]= bufAeval2 [j];
+        differentSecondVar= counter;
+      }
+    }
+    int k= 0;
+    for (CFListIterator j= bufEvaluation; j.hasItem(); j++, k++)
+      evalPoly += j.getItem()*power (x, k);
+    list.append (evalPoly);
+  }
+
+  delete [] bufAeval2;
+
+  sortList (biFactors, x);
+
+  int minFactorsLength;
+  bool irred= false;
+  TIMING_START (fac_bi_factorizer);
+  factorizationWRTDifferentSecondVars (A, Aeval2, minFactorsLength, irred, v);
+  TIMING_END_AND_PRINT (fac_bi_factorizer,
+             "time for bivariate factorization wrt diff second vars over Q: ");
+
+  TIMING_END_AND_PRINT (fac_bifactor_total,
+                        "total time for eval and bivar factors over Q: ");
+  if (irred)
+  {
+    factors.append (A);
+    appendSwapDecompress (factors, contentAFactors, N, 0, 0, x);
+    if (isOn (SW_RATIONAL))
+      normalize (factors);
+    delete [] Aeval2;
+    return factors;
+  }
+
+  if (minFactorsLength == 0)
+    minFactorsLength= biFactors.length();
+  else if (biFactors.length() > minFactorsLength)
+    refineBiFactors (A, biFactors, Aeval2, evaluation, minFactorsLength);
+  minFactorsLength= tmin (minFactorsLength, biFactors.length());
+
+  CFList uniFactors= buildUniFactors (biFactors, evaluation.getLast(), y);
+
+  sortByUniFactors (Aeval2, lengthAeval2, uniFactors, biFactors, evaluation);
+
+  minFactorsLength= tmin (minFactorsLength, biFactors.length());
+
+  if (minFactorsLength == 1)
+  {
+    factors.append (A);
+    appendSwapDecompress (factors, contentAFactors, N, 0, 0, x);
+    if (isOn (SW_RATIONAL))
+      normalize (factors);
+    delete [] Aeval2;
+    return factors;
+  }
+
+  if (differentSecondVar == lengthAeval2)
+  {
+    bool zeroOccured= false;
+    for (CFListIterator iter= evaluation; iter.hasItem(); iter++)
+    {
+      if (iter.getItem().isZero())
+      {
+        zeroOccured= true;
+        break;
+      }
+    }
+    if (!zeroOccured)
+    {
+      factors= sparseHeuristic (A, biFactors, Aeval2, evaluation,
+                                minFactorsLength);
+      if (factors.length() == biFactors.length())
+      {
+        appendSwapDecompress (factors, contentAFactors, N, 0, 0, x);
+        normalize (factors);
+        delete [] Aeval2;
+        return factors;
+      }
+      else
+        factors= CFList();
+      //TODO case where factors.length() > 0
+    }
+  }
+
+  CFList * oldAeval= new CFList [lengthAeval2];
+  for (int i= 0; i < lengthAeval2; i++)
+    oldAeval[i]= Aeval2[i];
+
+  getLeadingCoeffs (A, Aeval2);
+
+  CFList biFactorsLCs;
+  for (CFListIterator i= biFactors; i.hasItem(); i++)
+    biFactorsLCs.append (LC (i.getItem(), 1));
+
+  Variable w;
+  TIMING_START (fac_precompute_leadcoeff);
+  CFList leadingCoeffs= precomputeLeadingCoeff (LC (A, 1), biFactorsLCs, x,
+                                          evaluation, Aeval2, lengthAeval2, w);
+
+  if (w.level() != 1)
+    changeSecondVariable (A, biFactors, evaluation, oldAeval, lengthAeval2,
+                          uniFactors, w);
+
+  CanonicalForm oldA= A;
+  CFList oldBiFactors= biFactors;
+
+  CanonicalForm LCmultiplier= leadingCoeffs.getFirst();
+  bool LCmultiplierIsConst= LCmultiplier.inCoeffDomain();
+  leadingCoeffs.removeFirst();
+
+  if (!LCmultiplierIsConst)
+    distributeLCmultiplier (A, leadingCoeffs, biFactors, evaluation, LCmultiplier);
+
+  //prepare leading coefficients
+  CFList* leadingCoeffs2= new CFList [lengthAeval2];
+  prepareLeadingCoeffs (leadingCoeffs2, A, Aeval, A.level(), leadingCoeffs,
+                        biFactors, evaluation);
+
+  CFListIterator iter;
+  CFList bufLeadingCoeffs2= leadingCoeffs2[lengthAeval2-1];
+  bufBiFactors= biFactors;
+  bufA= A;
+  CanonicalForm testVars, bufLCmultiplier= LCmultiplier;
+  if (!LCmultiplierIsConst)
+  {
+    testVars= Variable (2);
+    for (int i= 0; i < lengthAeval2; i++)
+    {
+      if (!oldAeval[i].isEmpty())
+        testVars *= oldAeval[i].getFirst().mvar();
+    }
+  }
+  TIMING_END_AND_PRINT(fac_precompute_leadcoeff,
+                       "time to precompute LC over Q: ");
+
+  TIMING_START (fac_luckswang);
+  CFList bufFactors= CFList();
+  bool LCheuristic= false;
+  if (LucksWangSparseHeuristic (A, biFactors, 2, leadingCoeffs2[lengthAeval2-1],
+                                factors))
+  {
+    int check= biFactors.length();
+    int * index= new int [factors.length()];
+    CFList oldFactors= factors;
+    factors= recoverFactors (A, factors, index);
+
+    if (check == factors.length())
+    {
+      if (w.level() != 1)
+      {
+        for (iter= factors; iter.hasItem(); iter++)
+          iter.getItem()= swapvar (iter.getItem(), w, y);
+      }
+
+      appendSwapDecompress (factors, contentAFactors, N, 0, 0, x);
+      normalize (factors);
+      delete [] index;
+      delete [] Aeval2;
+      TIMING_END_AND_PRINT (fac_luckswang,
+                            "time for successful LucksWang over Q: ");
+      return factors;
+    }
+    else if (factors.length() > 0)
+    {
+      int oneCount= 0;
+      CFList l;
+      for (int i= 0; i < check; i++)
+      {
+        if (index[i] == 1)
+        {
+          iter=biFactors;
+          for (int j=1; j <= i-oneCount; j++)
+            iter++;
+          iter.remove (1);
+          for (int j= 0; j < lengthAeval2; j++)
+          {
+            l= leadingCoeffs2[j];
+            iter= l;
+            for (int k=1; k <= i-oneCount; k++)
+              iter++;
+            iter.remove (1);
+            leadingCoeffs2[j]=l;
+          }
+          oneCount++;
+        }
+      }
+      bufFactors= factors;
+      factors= CFList();
+    }
+    else if (!LCmultiplierIsConst && factors.length() == 0)
+    {
+      LCheuristic= true;
+      factors= oldFactors;
+      CFList contents, LCs;
+      bool foundTrueMultiplier= false;
+      LCHeuristic2 (LCmultiplier, factors, leadingCoeffs2[lengthAeval2-1],
+                    contents, LCs, foundTrueMultiplier);
+      if (foundTrueMultiplier)
+      {
+          A= oldA;
+          leadingCoeffs= leadingCoeffs2[lengthAeval2-1];
+          for (int i= lengthAeval2-1; i > -1; i--)
+            leadingCoeffs2[i]= CFList();
+          prepareLeadingCoeffs (leadingCoeffs2, A, Aeval, A.level(),
+                                leadingCoeffs, biFactors, evaluation);
+      }
+      else
+      {
+        bool foundMultiplier= false;
+        LCHeuristic3 (LCmultiplier, factors, oldBiFactors, contents, oldAeval,
+                      A, leadingCoeffs2, lengthAeval2, foundMultiplier);
+        // coming from above: divide out more LCmultiplier if possible
+        if (foundMultiplier)
+        {
+          foundMultiplier= false;
+          LCHeuristic4 (oldBiFactors, oldAeval, contents, factors, testVars,
+                        lengthAeval2, leadingCoeffs2, A, LCmultiplier,
+                        foundMultiplier);
+        }
+        else
+        {
+          LCHeuristicCheck (LCs, contents, A, oldA,
+                            leadingCoeffs2[lengthAeval2-1], foundMultiplier);
+          if (!foundMultiplier && fdivides (getVars (LCmultiplier), testVars))
+          {
+            LCHeuristic (A, LCmultiplier, biFactors, leadingCoeffs2, oldAeval,
+                         lengthAeval2, evaluation, oldBiFactors);
+          }
+        }
+
+        // patch everything together again
+        leadingCoeffs= leadingCoeffs2[lengthAeval2-1];
+        for (int i= lengthAeval2-1; i > -1; i--)
+          leadingCoeffs2[i]= CFList();
+        prepareLeadingCoeffs (leadingCoeffs2, A, Aeval, A.level(),leadingCoeffs,
+                              biFactors, evaluation);
+      }
+      factors= CFList();
+      if (!fdivides (LC (oldA,1),prod (leadingCoeffs2[lengthAeval2-1])))
+      {
+        LCheuristic= false;
+        A= bufA;
+        biFactors= bufBiFactors;
+        leadingCoeffs2[lengthAeval2-1]= bufLeadingCoeffs2;
+        LCmultiplier= bufLCmultiplier;
+      }
+    }
+    else
+      factors= CFList();
+    delete [] index;
+  }
+  TIMING_END_AND_PRINT (fac_luckswang, "time for LucksWang over Q: ");
+
+  TIMING_START (fac_lcheuristic);
+  if (!LCheuristic && !LCmultiplierIsConst && bufFactors.isEmpty()
+      && fdivides (getVars (LCmultiplier), testVars))
+  {
+    LCheuristic= true;
+    LCHeuristic (A, LCmultiplier, biFactors, leadingCoeffs2, oldAeval,
+                 lengthAeval2, evaluation, oldBiFactors);
+
+    leadingCoeffs= leadingCoeffs2[lengthAeval2-1];
+    for (int i= lengthAeval2-1; i > -1; i--)
+      leadingCoeffs2[i]= CFList();
+    prepareLeadingCoeffs (leadingCoeffs2, A, Aeval, A.level(),leadingCoeffs,
+                          biFactors, evaluation);
+
+    if (!fdivides (LC (oldA,1),prod (leadingCoeffs2[lengthAeval2-1])))
+    {
+      LCheuristic= false;
+      A= bufA;
+      biFactors= bufBiFactors;
+      leadingCoeffs2[lengthAeval2-1]= bufLeadingCoeffs2;
+      LCmultiplier= bufLCmultiplier;
+    }
+  }
+  TIMING_END_AND_PRINT (fac_lcheuristic, "time for Lc heuristic over Q: ");
+
+tryAgainWithoutHeu:
+  //shifting to zero
+  TIMING_START (fac_shift_to_zero);
+  CanonicalForm denA= bCommonDen (A);
+  A *= denA;
+  A= shift2Zero (A, Aeval, evaluation);
+  A /= denA;
+
+  for (iter= biFactors; iter.hasItem(); iter++)
+    iter.getItem()= iter.getItem () (y + evaluation.getLast(), y);
+
+  for (int i= 0; i < lengthAeval2-1; i++)
+    leadingCoeffs2[i]= CFList();
+  for (iter= leadingCoeffs2[lengthAeval2-1]; iter.hasItem(); iter++)
+  {
+    iter.getItem()= shift2Zero (iter.getItem(), list, evaluation);
+    for (int i= A.level() - 4; i > -1; i--)
+    {
+      if (i + 1 == lengthAeval2-1)
+        leadingCoeffs2[i].append (iter.getItem() (0, i + 4));
+      else
+        leadingCoeffs2[i].append (leadingCoeffs2[i+1].getLast() (0, i + 4));
+    }
+  }
+  TIMING_END_AND_PRINT (fac_shift_to_zero,
+                        "time to shift evaluation point to zero: ");
+
+  CFArray Pi;
+  CFList diophant;
+  int* liftBounds= new int [A.level() - 1];
+  int liftBoundsLength= A.level() - 1;
+  for (int i= 0; i < liftBoundsLength; i++)
+    liftBounds [i]= degree (A, i + 2) + 1;
+
+  Aeval.removeFirst();
+  bool noOneToOne= false;
+
+  TIMING_START (fac_cleardenom);
+  CFList commonDenominators;
+  for (iter=biFactors; iter.hasItem(); iter++)
+    commonDenominators.append (bCommonDen (iter.getItem()));
+  CanonicalForm tmp1, tmp2, tmp3=1;
+  CFListIterator iter2;
+  for (int i= 0; i < lengthAeval2; i++)
+  {
+    iter2= commonDenominators;
+    for (iter= leadingCoeffs2[i]; iter.hasItem(); iter++, iter2++)
+    {
+      tmp1= bCommonDen (iter.getItem());
+      Off (SW_RATIONAL);
+      iter2.getItem()= lcm (iter2.getItem(), tmp1);
+      On (SW_RATIONAL);
+    }
+  }
+  tmp1= prod (commonDenominators);
+  for (iter= Aeval; iter.hasItem(); iter++)
+  {
+    tmp2= bCommonDen (iter.getItem()/denA);
+    Off (SW_RATIONAL);
+    tmp3= lcm (tmp2,tmp3);
+    On (SW_RATIONAL);
+  }
+  CanonicalForm multiplier;
+  multiplier= tmp3/tmp1;
+  iter2= commonDenominators;
+  for (iter=biFactors; iter.hasItem(); iter++, iter2++)
+    iter.getItem() *= iter2.getItem()*multiplier;
+
+  for (iter= Aeval; iter.hasItem(); iter++)
+    iter.getItem() *= tmp3*power (multiplier, biFactors.length() - 1)/denA;
+
+  for (int i= 0; i < lengthAeval2; i++)
+  {
+    iter2= commonDenominators;
+    for (iter= leadingCoeffs2[i]; iter.hasItem(); iter++, iter2++)
+      iter.getItem() *= iter2.getItem()*multiplier;
+  }
+  TIMING_END_AND_PRINT (fac_cleardenom, "time to clear denominators: ");
+
+  TIMING_START (fac_hensel_lift);
+  factors= nonMonicHenselLift (Aeval, biFactors, leadingCoeffs2, diophant,
+                               Pi, liftBounds, liftBoundsLength, noOneToOne);
+  TIMING_END_AND_PRINT (fac_hensel_lift,
+                        "time for non monic hensel lifting over Q: ");
+
+  if (!noOneToOne)
+  {
+    int check= factors.length();
+    A= oldA;
+    TIMING_START (fac_recover_factors);
+    factors= recoverFactors (A, factors, evaluation);
+    TIMING_END_AND_PRINT (fac_recover_factors,
+                          "time to recover factors over Q: ");
+    if (check != factors.length())
+      noOneToOne= true;
+    else
+      factors= Union (factors, bufFactors);
+  }
+  if (noOneToOne)
+  {
+    if (!LCmultiplierIsConst && LCheuristic)
+    {
+      A= bufA;
+      biFactors= bufBiFactors;
+      leadingCoeffs2[lengthAeval2-1]= bufLeadingCoeffs2;
+      delete [] liftBounds;
+      LCheuristic= false;
+      goto tryAgainWithoutHeu;
+      //something probably went wrong in the heuristic
+    }
+
+    A= shift2Zero (oldA, Aeval, evaluation);
+    biFactors= oldBiFactors;
+    for (iter= biFactors; iter.hasItem(); iter++)
+      iter.getItem()= iter.getItem () (y + evaluation.getLast(), y);
+    CanonicalForm LCA= LC (Aeval.getFirst(), 1);
+    CanonicalForm yToLift= power (y, lift);
+    CFListIterator i= biFactors;
+    lift= degree (i.getItem(), 2) + degree (LC (i.getItem(), 1)) + 1;
+    i++;
+
+    for (; i.hasItem(); i++)
+      lift= tmax (lift, degree (i.getItem(), 2)+degree (LC (i.getItem(), 1))+1);
+
+    lift= tmax (degree (Aeval.getFirst() , 2) + 1, lift);
+
+    i= biFactors;
+    yToLift= power (y, lift);
+    CanonicalForm dummy;
+    for (; i.hasItem(); i++)
+    {
+      LCA= LC (i.getItem(), 1);
+      extgcd (LCA, yToLift, LCA, dummy);
+      i.getItem()= mod (i.getItem()*LCA, yToLift);
+    }
+
+    liftBoundsLength= F.level() - 1;
+    liftBounds= liftingBounds (A, lift);
+
+    CFList MOD;
+    bool earlySuccess;
+    CFList earlyFactors;
+    ExtensionInfo info= ExtensionInfo (false);
+    CFList liftedFactors;
+    TIMING_START (fac_hensel_lift);
+    liftedFactors= henselLiftAndEarly
+                   (A, MOD, liftBounds, earlySuccess, earlyFactors,
+                    Aeval, biFactors, evaluation, info);
+    TIMING_END_AND_PRINT (fac_hensel_lift, "time for hensel lifting: ");
+
+    TIMING_START (fac_factor_recombination);
+    factors= factorRecombination (A, liftedFactors, MOD);
+    TIMING_END_AND_PRINT (fac_factor_recombination,
+                          "time for factor recombination: ");
+
+    if (earlySuccess)
+      factors= Union (factors, earlyFactors);
+
+    for (CFListIterator i= factors; i.hasItem(); i++)
+    {
+      int kk= Aeval.getLast().level();
+      for (CFListIterator j= evaluation; j.hasItem(); j++, kk--)
+      {
+        if (i.getItem().level() < kk)
+          continue;
+       i.getItem()= i.getItem() (Variable (kk) - j.getItem(), kk);
+      }
+    }
+  }
+
+  if (w.level() != 1)
+  {
+    for (CFListIterator iter= factors; iter.hasItem(); iter++)
+      iter.getItem()= swapvar (iter.getItem(), w, y);
+  }
+
+  append (factors, contentAFactors);
+  decompress (factors, N);
+  if (isOn (SW_RATIONAL))
+    normalize (factors);
+
+  delete [] leadingCoeffs2;
+  delete [] oldAeval;
+  delete [] Aeval2;
+  delete[] liftBounds;
+
+  return factors;
+}
+
+#endif
diff --git a/factory/facFactorize.h b/factory/facFactorize.h
new file mode 100644
index 0000000..1c2a42d
--- /dev/null
+++ b/factory/facFactorize.h
@@ -0,0 +1,176 @@
+/*****************************************************************************\
+ * Computer Algebra System SINGULAR
+\*****************************************************************************/
+/** @file facFactorize.h
+ *
+ * multivariate factorization over Q(a)
+ *
+ * @author Martin Lee
+ *
+ **/
+/*****************************************************************************/
+
+#ifndef FAC_FACTORIZE_H
+#define FAC_FACTORIZE_H
+
+// #include "config.h"
+#include "timing.h"
+
+#include "facBivar.h"
+#include "facFqBivarUtil.h"
+
+TIMING_DEFINE_PRINT (fac_squarefree)
+TIMING_DEFINE_PRINT (fac_factor_squarefree)
+
+/// Factorization of A wrt. to different second vars
+void
+factorizationWRTDifferentSecondVars (
+                          const CanonicalForm& A, ///<[in] poly
+                          CFList*& Aeval,         ///<[in,out] A evaluated wrt.
+                                                  ///< different second vars
+                                                  ///< returns bivariate factors
+                          int& minFactorsLength,  ///<[in,out] minimal length of
+                                                  ///< bivariate factors
+                          bool& irred,            ///<[in,out] Is A irreducible?
+                          const Variable& w       ///<[in] alg. variable
+                                    );
+
+/// Factorization over Q (a)
+///
+/// @return @a multiFactorize returns a factorization of F
+CFList
+multiFactorize (const CanonicalForm& F,     ///< [in] sqrfree poly
+                const Variable& v           ///< [in] some algebraic variable
+               );
+
+/// factorize a squarefree multivariate polynomial over \f$ Q(\alpha) \f$
+///
+/// @return @a ratSqrfFactorize returns a list of monic factors, the first
+///         element is the leading coefficient.
+#ifdef HAVE_NTL
+inline
+CFList
+ratSqrfFactorize (const CanonicalForm & G,        ///<[in] a multivariate poly
+                  const Variable& v= Variable (1) ///<[in] algebraic variable
+                 )
+{
+  if (getNumVars (G) == 2)
+    return ratBiSqrfFactorize (G, v);
+  CanonicalForm F= G;
+  if (isOn (SW_RATIONAL))
+    F *= bCommonDen (F);
+  CFList result= multiFactorize (F, v);
+  if (isOn (SW_RATIONAL))
+  {
+    normalize (result);
+    result.insert (Lc(F));
+  }
+  return result;
+}
+
+/// factorize a multivariate polynomial over \f$ Q(\alpha) \f$
+///
+/// @return @a ratFactorize returns a list of monic factors with
+///         multiplicity, the first element is the leading coefficient.
+inline
+CFFList
+ratFactorize (const CanonicalForm& G,          ///<[in] a multivariate poly
+              const Variable& v= Variable (1), ///<[in] algebraic variable
+              bool substCheck= true            ///<[in] enables substitute check
+             )
+{
+  if (getNumVars (G) == 2)
+  {
+    CFFList result= ratBiFactorize (G,v);
+    return result;
+  }
+  CanonicalForm F= G;
+
+  if (substCheck)
+  {
+    bool foundOne= false;
+    int * substDegree= new int [F.level()];
+    for (int i= 1; i <= F.level(); i++)
+    {
+      if (degree (F, i) > 0)
+      {
+        substDegree[i-1]= substituteCheck (F, Variable (i));
+        if (substDegree [i-1] > 1)
+        {
+          foundOne= true;
+          subst (F, F, substDegree[i-1], Variable (i));
+        }
+      }
+      else
+        substDegree[i-1]= -1;
+    }
+    if (foundOne)
+    {
+      CFFList result= ratFactorize (F, v, false);
+      CFFList newResult, tmp;
+      CanonicalForm tmp2;
+      newResult.insert (result.getFirst());
+      result.removeFirst();
+      for (CFFListIterator i= result; i.hasItem(); i++)
+      {
+        tmp2= i.getItem().factor();
+        for (int j= 1; j <= G.level(); j++)
+        {
+          if (substDegree[j-1] > 1)
+            tmp2= reverseSubst (tmp2, substDegree[j-1], Variable (j));
+        }
+        tmp= ratFactorize (tmp2, v, false);
+        tmp.removeFirst();
+        for (CFFListIterator j= tmp; j.hasItem(); j++)
+          newResult.append (CFFactor (j.getItem().factor(),
+                                      j.getItem().exp()*i.getItem().exp()));
+      }
+      delete [] substDegree;
+      return newResult;
+    }
+    delete [] substDegree;
+  }
+
+  CanonicalForm LcF= Lc (F);
+  if (isOn (SW_RATIONAL))
+    F *= bCommonDen (F);
+
+  CFFList result;
+  TIMING_START (fac_squarefree);
+  CFFList sqrfFactors= sqrFree (F);
+  TIMING_END_AND_PRINT (fac_squarefree,
+                        "time for squarefree factorization over Q: ");
+
+  CFList tmp;
+  for (CFFListIterator i= sqrfFactors; i.hasItem(); i++)
+  {
+    TIMING_START (fac_factor_squarefree);
+    tmp= ratSqrfFactorize (i.getItem().factor(), v);
+    TIMING_END_AND_PRINT (fac_factor_squarefree,
+                          "time to factorize sqrfree factor over Q: ");
+    for (CFListIterator j= tmp; j.hasItem(); j++)
+    {
+      if (j.getItem().inCoeffDomain()) continue;
+      result.append (CFFactor (j.getItem(), i.getItem().exp()));
+    }
+  }
+  if (isOn (SW_RATIONAL))
+  {
+    normalize (result);
+    if (v.level() == 1)
+    {
+      for (CFFListIterator i= result; i.hasItem(); i++)
+      {
+        LcF /= power (bCommonDen (i.getItem().factor()), i.getItem().exp());
+        i.getItem()= CFFactor (i.getItem().factor()*
+                     bCommonDen(i.getItem().factor()), i.getItem().exp());
+      }
+    }
+    result.insert (CFFactor (LcF, 1));
+  }
+  return result;
+}
+#endif
+
+#endif
+
diff --git a/factory/facFqBivar.cc b/factory/facFqBivar.cc
new file mode 100644
index 0000000..b816bde
--- /dev/null
+++ b/factory/facFqBivar.cc
@@ -0,0 +1,9000 @@
+/*****************************************************************************\
+ * Computer Algebra System SINGULAR
+\*****************************************************************************/
+/** @file facFqBivar.cc
+ *
+ * This file provides functions for factorizing a bivariate polynomial over
+ * \f$ F_{p} \f$ , \f$ F_{p}(\alpha ) \f$ or GF, based on "Modern Computer
+ * Algebra, Chapter 15" by J. von zur Gathen & J. Gerhard and "Factoring
+ * multivariate polynomials over a finite field" by L. Bernardin.
+ * Factor Recombination is described in "Factoring polynomials over global
+ * fields" by K. Belabas, M. van Hoeij, J. Klueners, A. Steel
+ *
+ *
+ * @author Martin Lee
+ *
+ **/
+/*****************************************************************************/
+
+
+#include "config.h"
+
+
+#include "cf_assert.h"
+#include "debug.h"
+#include "timing.h"
+
+#include "canonicalform.h"
+#include "cf_defs.h"
+#include "cf_map_ext.h"
+#include "cf_random.h"
+#include "facHensel.h"
+#include "facMul.h"
+#include "cf_map.h"
+#include "cf_irred.h"
+#include "facFqBivarUtil.h"
+#include "facFqBivar.h"
+#include "cfNewtonPolygon.h"
+
+#ifdef HAVE_NTL
+#include "NTLconvert.h"
+
+#ifdef HAVE_FLINT
+#include "FLINTconvert.h"
+#endif
+
+TIMING_DEFINE_PRINT(fac_fq_uni_factorizer)
+TIMING_DEFINE_PRINT(fac_fq_bi_hensel_lift)
+TIMING_DEFINE_PRINT(fac_fq_bi_factor_recombination)
+TIMING_DEFINE_PRINT(fac_fq_bi_evaluation)
+TIMING_DEFINE_PRINT(fac_fq_bi_shift_to_zero)
+TIMING_DEFINE_PRINT(fac_fq_logarithmic)
+TIMING_DEFINE_PRINT(fac_fq_compute_lattice_lift)
+TIMING_DEFINE_PRINT(fac_fq_till_reduced)
+TIMING_DEFINE_PRINT(fac_fq_reconstruction)
+TIMING_DEFINE_PRINT(fac_fq_lift)
+TIMING_DEFINE_PRINT(fac_fq_uni_total)
+
+CanonicalForm prodMod0 (const CFList& L, const CanonicalForm& M, const modpk& b)
+{
+  if (L.isEmpty())
+    return 1;
+  else if (L.length() == 1)
+    return mod (L.getFirst()(0, 1) , M);
+  else if (L.length() == 2)
+    return mod (mulNTL (L.getFirst()(0, 1),L.getLast()(0, 1), b), M);
+  else
+  {
+    int l= L.length()/2;
+    CFListIterator i= L;
+    CFList tmp1, tmp2;
+    CanonicalForm buf1, buf2;
+    for (int j= 1; j <= l; j++, i++)
+      tmp1.append (i.getItem());
+    tmp2= Difference (L, tmp1);
+    buf1= prodMod0 (tmp1, M, b);
+    buf2= prodMod0 (tmp2, M, b);
+    return mod (mulNTL (buf1,buf2, b), M);
+  }
+}
+
+CanonicalForm evalPoint (const CanonicalForm& F, CanonicalForm & eval,
+                         const Variable& alpha, CFList& list, const bool& GF,
+                         bool& fail)
+{
+  fail= false;
+  Variable x= Variable(2);
+  Variable y= Variable(1);
+  FFRandom genFF;
+  GFRandom genGF;
+  CanonicalForm random, mipo;
+  double bound;
+  int p= getCharacteristic ();
+  if (alpha.level() != 1)
+  {
+    mipo= getMipo (alpha);
+    int d= degree (mipo);
+    bound= pow ((double) p, (double) d);
+  }
+  else if (GF)
+  {
+    int d= getGFDegree();
+    bound= ipower (p, d);
+  }
+  else
+    bound= p;
+
+  random= 0;
+  do
+  {
+    if (list.length() >= bound)
+    {
+      fail= true;
+      break;
+    }
+    if (list.isEmpty())
+      random= 0;
+    else if (GF)
+    {
+      if (list.length() == 1)
+        random= getGFGenerator();
+      else
+        random= genGF.generate();
+    }
+    else if (list.length() < p || alpha.level() == 1)
+      random= genFF.generate();
+    else if (alpha != x && list.length() >= p)
+    {
+      if (list.length() == p)
+        random= alpha;
+      else
+      {
+        AlgExtRandomF genAlgExt (alpha);
+        random= genAlgExt.generate();
+      }
+    }
+    if (find (list, random)) continue;
+    eval= F (random, x);
+    if (degree (eval) != degree (F, y))
+    { //leading coeff vanishes
+      if (!find (list, random))
+        list.append (random);
+      continue;
+    }
+    if (degree (gcd (deriv (eval, eval.mvar()), eval), eval.mvar()) > 0)
+    { //evaluated polynomial is not squarefree
+      if (!find (list, random))
+        list.append (random);
+      continue;
+    }
+  } while (find (list, random));
+
+  return random;
+}
+
+CFList
+uniFactorizer (const CanonicalForm& A, const Variable& alpha, const bool& GF)
+{
+  Variable x= A.mvar();
+  if (A.inCoeffDomain())
+    return CFList();
+  ASSERT (A.isUnivariate(),
+          "univariate polynomial expected or constant expected");
+  CFFList factorsA;
+  if (GF)
+  {
+    int k= getGFDegree();
+    char cGFName= gf_name;
+    CanonicalForm mipo= gf_mipo;
+    setCharacteristic (getCharacteristic());
+    Variable beta= rootOf (mipo.mapinto());
+    CanonicalForm buf= GF2FalphaRep (A, beta);
+    if (getCharacteristic() > 2)
+    {
+#if (HAVE_FLINT && __FLINT_RELEASE >= 20400)
+      nmod_poly_t FLINTmipo, leadingCoeff;
+      fq_nmod_ctx_t fq_con;
+      fq_nmod_poly_t FLINTA;
+      fq_nmod_poly_factor_t FLINTFactorsA;
+
+      nmod_poly_init (FLINTmipo, getCharacteristic());
+      convertFacCF2nmod_poly_t (FLINTmipo, mipo.mapinto());
+
+      fq_nmod_ctx_init_modulus (fq_con, FLINTmipo, "Z");
+
+      convertFacCF2Fq_nmod_poly_t (FLINTA, buf, fq_con);
+      fq_nmod_poly_make_monic (FLINTA, FLINTA, fq_con);
+
+      fq_nmod_poly_factor_init (FLINTFactorsA, fq_con);
+      nmod_poly_init (leadingCoeff, getCharacteristic());
+
+      fq_nmod_poly_factor (FLINTFactorsA, leadingCoeff, FLINTA, fq_con);
+
+      factorsA= convertFLINTFq_nmod_poly_factor2FacCFFList (FLINTFactorsA, x,
+                                                            beta, fq_con);
+
+      fq_nmod_poly_factor_clear (FLINTFactorsA, fq_con);
+      fq_nmod_poly_clear (FLINTA, fq_con);
+      nmod_poly_clear (FLINTmipo);
+      nmod_poly_clear (leadingCoeff);
+      fq_nmod_ctx_clear (fq_con);
+#else
+      if (fac_NTL_char != getCharacteristic())
+      {
+        fac_NTL_char= getCharacteristic();
+        zz_p::init (getCharacteristic());
+      }
+      zz_pX NTLMipo= convertFacCF2NTLzzpX (mipo.mapinto());
+      zz_pE::init (NTLMipo);
+      zz_pEX NTLA= convertFacCF2NTLzz_pEX (buf, NTLMipo);
+      MakeMonic (NTLA);
+      vec_pair_zz_pEX_long NTLFactorsA= CanZass (NTLA);
+      zz_pE multi= to_zz_pE (1);
+      factorsA= convertNTLvec_pair_zzpEX_long2FacCFFList (NTLFactorsA, multi,
+                                                         x, beta);
+#endif
+    }
+    else
+    {
+      GF2X NTLMipo= convertFacCF2NTLGF2X (mipo.mapinto());
+      GF2E::init (NTLMipo);
+      GF2EX NTLA= convertFacCF2NTLGF2EX (buf, NTLMipo);
+      MakeMonic (NTLA);
+      vec_pair_GF2EX_long NTLFactorsA= CanZass (NTLA);
+      GF2E multi= to_GF2E (1);
+      factorsA= convertNTLvec_pair_GF2EX_long2FacCFFList (NTLFactorsA, multi,
+                                                           x, beta);
+    }
+    setCharacteristic (getCharacteristic(), k, cGFName);
+    for (CFFListIterator i= factorsA; i.hasItem(); i++)
+    {
+      buf= i.getItem().factor();
+      buf= Falpha2GFRep (buf);
+      i.getItem()= CFFactor (buf, i.getItem().exp());
+    }
+    prune (beta);
+  }
+  else if (alpha.level() != 1)
+  {
+    if (getCharacteristic() > 2)
+    {
+#if (HAVE_FLINT && __FLINT_RELEASE >= 20400)
+      nmod_poly_t FLINTmipo, leadingCoeff;
+      fq_nmod_ctx_t fq_con;
+      fq_nmod_poly_t FLINTA;
+      fq_nmod_poly_factor_t FLINTFactorsA;
+
+      nmod_poly_init (FLINTmipo, getCharacteristic());
+      convertFacCF2nmod_poly_t (FLINTmipo, getMipo (alpha));
+
+      fq_nmod_ctx_init_modulus (fq_con, FLINTmipo, "Z");
+
+      convertFacCF2Fq_nmod_poly_t (FLINTA, A, fq_con);
+      fq_nmod_poly_make_monic (FLINTA, FLINTA, fq_con);
+
+      fq_nmod_poly_factor_init (FLINTFactorsA, fq_con);
+      nmod_poly_init (leadingCoeff, getCharacteristic());
+
+      fq_nmod_poly_factor (FLINTFactorsA, leadingCoeff, FLINTA, fq_con);
+
+      factorsA= convertFLINTFq_nmod_poly_factor2FacCFFList (FLINTFactorsA, x,
+                                                            alpha, fq_con);
+
+      fq_nmod_poly_factor_clear (FLINTFactorsA, fq_con);
+      fq_nmod_poly_clear (FLINTA, fq_con);
+      nmod_poly_clear (FLINTmipo);
+      nmod_poly_clear (leadingCoeff);
+      fq_nmod_ctx_clear (fq_con);
+#else
+      if (fac_NTL_char != getCharacteristic())
+      {
+        fac_NTL_char= getCharacteristic();
+        zz_p::init (getCharacteristic());
+      }
+      zz_pX NTLMipo= convertFacCF2NTLzzpX (getMipo (alpha));
+      zz_pE::init (NTLMipo);
+      zz_pEX NTLA= convertFacCF2NTLzz_pEX (A, NTLMipo);
+      MakeMonic (NTLA);
+      vec_pair_zz_pEX_long NTLFactorsA= CanZass (NTLA);
+      zz_pE multi= to_zz_pE (1);
+      factorsA= convertNTLvec_pair_zzpEX_long2FacCFFList (NTLFactorsA, multi,
+                                                           x, alpha);
+#endif
+    }
+    else
+    {
+      GF2X NTLMipo= convertFacCF2NTLGF2X (getMipo (alpha));
+      GF2E::init (NTLMipo);
+      GF2EX NTLA= convertFacCF2NTLGF2EX (A, NTLMipo);
+      MakeMonic (NTLA);
+      vec_pair_GF2EX_long NTLFactorsA= CanZass (NTLA);
+      GF2E multi= to_GF2E (1);
+      factorsA= convertNTLvec_pair_GF2EX_long2FacCFFList (NTLFactorsA, multi,
+                                                           x, alpha);
+    }
+  }
+  else
+  {
+#ifdef HAVE_FLINT
+    if (degree (A) < 300)
+    {
+      nmod_poly_t FLINTA;
+      convertFacCF2nmod_poly_t (FLINTA, A);
+      nmod_poly_factor_t result;
+      nmod_poly_factor_init (result);
+      mp_limb_t leadingCoeff= nmod_poly_factor (result, FLINTA);
+      factorsA= convertFLINTnmod_poly_factor2FacCFFList (result, leadingCoeff, x);
+      if (factorsA.getFirst().factor().inCoeffDomain())
+        factorsA.removeFirst();
+      nmod_poly_factor_clear (result);
+      nmod_poly_clear (FLINTA);
+    }
+    else
+#endif
+    if (getCharacteristic() > 2)
+    {
+      if (fac_NTL_char != getCharacteristic())
+      {
+        fac_NTL_char= getCharacteristic();
+        zz_p::init (getCharacteristic());
+      }
+      zz_pX NTLA= convertFacCF2NTLzzpX (A);
+      MakeMonic (NTLA);
+      vec_pair_zz_pX_long NTLFactorsA= CanZass (NTLA);
+      zz_p multi= to_zz_p (1);
+      factorsA= convertNTLvec_pair_zzpX_long2FacCFFList (NTLFactorsA, multi,
+                                                          x);
+    }
+    else
+    {
+      GF2X NTLA= convertFacCF2NTLGF2X (A);
+      vec_pair_GF2X_long NTLFactorsA= CanZass (NTLA);
+      GF2 multi= to_GF2 (1);
+      factorsA= convertNTLvec_pair_GF2X_long2FacCFFList (NTLFactorsA, multi,
+                                                          x);
+    }
+  }
+  CFList uniFactors;
+  for (CFFListIterator i= factorsA; i.hasItem(); i++)
+    uniFactors.append (i.getItem().factor());
+  return uniFactors;
+}
+
+/// naive factor recombination as decribed in "Factoring
+/// multivariate polynomials over a finite field" by L Bernardin.
+CFList
+extFactorRecombination (CFList& factors, CanonicalForm& F,
+                        const CanonicalForm& N, const ExtensionInfo& info,
+                        DegreePattern& degs, const CanonicalForm& eval, int s,
+                        int thres)
+{
+  if (factors.length() == 0)
+  {
+    F= 1;
+    return CFList();
+  }
+  if (F.inCoeffDomain())
+    return CFList();
+
+  Variable alpha= info.getAlpha();
+  Variable beta= info.getBeta();
+  CanonicalForm gamma= info.getGamma();
+  CanonicalForm delta= info.getDelta();
+  int k= info.getGFDegree();
+
+  CanonicalForm M= N;
+  int l= degree (N);
+  Variable y= F.mvar();
+  Variable x= Variable (1);
+  CFList source, dest;
+  if (degs.getLength() <= 1 || factors.length() == 1)
+  {
+    CFList result= CFList(mapDown (F(y-eval, y), info, source, dest));
+    F= 1;
+    return result;
+  }
+
+  DEBOUTLN (cerr, "LC (F, 1)*prodMod (factors, M) == F " <<
+            (mod (LC (F, 1)*prodMod (factors, M), M)/Lc (mod (LC (F, 1)*prodMod (factors, M), M)) == F/Lc (F)));
+  int degMipoBeta= 1;
+  if (!k && beta.level() != 1)
+    degMipoBeta= degree (getMipo (beta));
+
+  CFList T, S, Diff;
+  T= factors;
+
+  CFList result;
+  CanonicalForm buf, buf2, quot;
+
+  buf= F;
+
+  CanonicalForm g, LCBuf= LC (buf, x);
+  int * v= new int [T.length()];
+  for (int i= 0; i < T.length(); i++)
+    v[i]= 0;
+
+  CFArray TT;
+  DegreePattern bufDegs1, bufDegs2;
+  bufDegs1= degs;
+  int subsetDeg;
+  TT= copy (factors);
+  bool nosubset= false;
+  bool recombination= false;
+  bool trueFactor= false;
+  CanonicalForm test;
+  CanonicalForm buf0= buf (0, x)*LCBuf;
+  while (T.length() >= 2*s && s <= thres)
+  {
+    while (nosubset == false)
+    {
+      if (T.length() == s)
+      {
+        delete [] v;
+        if (recombination)
+        {
+          T.insert (LCBuf);
+          g= prodMod (T, M);
+          T.removeFirst();
+          g /= content(g);
+          g= g (y - eval, y);
+          g /= Lc (g);
+          appendTestMapDown (result, g, info, source, dest);
+          F= 1;
+          return result;
+        }
+        else
+        {
+          appendMapDown (result, F (y - eval, y), info, source, dest);
+          F= 1;
+          return result;
+        }
+      }
+      S= subset (v, s, TT, nosubset);
+      if (nosubset) break;
+      subsetDeg= subsetDegree (S);
+      // skip those combinations that are not possible
+      if (!degs.find (subsetDeg))
+        continue;
+      else
+      {
+        test= prodMod0 (S, M);
+        test *= LCBuf;
+        test = mod (test, M);
+        if (fdivides (test, buf0))
+        {
+          S.insert (LCBuf);
+          g= prodMod (S, M);
+          S.removeFirst();
+          g /= content (g, x);
+          if (fdivides (g, buf, quot))
+          {
+            buf2= g (y - eval, y);
+            buf2 /= Lc (buf2);
+
+            if (!k && beta.level() == 1)
+            {
+              if (degree (buf2, alpha) < degMipoBeta)
+              {
+                buf= quot;
+                LCBuf= LC (buf, x);
+                recombination= true;
+                appendTestMapDown (result, buf2, info, source, dest);
+                trueFactor= true;
+              }
+            }
+            else
+            {
+              if (!isInExtension (buf2, gamma, k, delta, source, dest))
+              {
+                buf= quot;
+                LCBuf= LC (buf, x);
+                recombination= true;
+                appendTestMapDown (result, buf2, info, source, dest);
+                trueFactor= true;
+              }
+            }
+            if (trueFactor)
+            {
+              T= Difference (T, S);
+              l -= degree (g);
+              M= power (y, l);
+              buf0= buf (0, x)*LCBuf;
+
+              // compute new possible degree pattern
+              bufDegs2= DegreePattern (T);
+              bufDegs1.intersect (bufDegs2);
+              bufDegs1.refine ();
+              if (T.length() < 2*s || T.length() == s ||
+                  bufDegs1.getLength() == 1)
+              {
+                delete [] v;
+                if (recombination)
+                {
+                  buf= buf (y-eval,y);
+                  buf /= Lc (buf);
+                  appendTestMapDown (result, buf, info, source,
+                                      dest);
+                  F= 1;
+                  return result;
+                }
+                else
+                {
+                  appendMapDown (result, F (y - eval, y), info, source, dest);
+                  F= 1;
+                  return result;
+                }
+              }
+              trueFactor= false;
+              TT= copy (T);
+              indexUpdate (v, s, T.length(), nosubset);
+              if (nosubset) break;
+            }
+          }
+        }
+      }
+    }
+    s++;
+    if (T.length() < 2*s || T.length() == s)
+    {
+      delete [] v;
+      if (recombination)
+      {
+        buf= buf (y-eval,y);
+        buf /= Lc (buf);
+        appendTestMapDown (result, buf, info, source, dest);
+        F= 1;
+        return result;
+      }
+      else
+      {
+        appendMapDown (result, F (y - eval, y), info, source, dest);
+        F= 1;
+        return result;
+      }
+    }
+    for (int i= 0; i < T.length(); i++)
+      v[i]= 0;
+    nosubset= false;
+  }
+  if (T.length() < 2*s)
+  {
+    appendMapDown (result, F (y - eval, y), info, source, dest);
+    F= 1;
+    delete [] v;
+    return result;
+  }
+
+  if (s > thres)
+  {
+    factors= T;
+    F= buf;
+    degs= bufDegs1;
+  }
+
+  delete [] v;
+  return result;
+}
+
+/// naive factor recombination as decribed in "Factoring
+/// multivariate polynomials over a finite field" by L Bernardin.
+CFList
+factorRecombination (CFList& factors, CanonicalForm& F,
+                     const CanonicalForm& N, DegreePattern& degs, const
+                     CanonicalForm& eval, int s, int thres, const modpk& b,
+                     const CanonicalForm& den
+                    )
+{
+  if (factors.length() == 0)
+  {
+    F= 1;
+    return CFList ();
+  }
+  if (F.inCoeffDomain())
+    return CFList();
+  Variable y= Variable (2);
+  if (degs.getLength() <= 1 || factors.length() == 1)
+  {
+    CFList result= CFList (F(y-eval,y));
+    F= 1;
+    return result;
+  }
+#ifdef DEBUGOUTPUT
+  if (b.getp() == 0)
+    DEBOUTLN (cerr, "LC (F, 1)*prodMod (factors, N) == F " <<
+              (mod (LC (F, 1)*prodMod (factors, N),N)/Lc (mod (LC (F, 1)*prodMod (factors, N),N)) == F/Lc(F)));
+  else
+    DEBOUTLN (cerr, "LC (F, 1)*prodMod (factors, N) == F " <<
+              (mod (b(LC (F, 1)*prodMod (factors, N)),N)/Lc (mod (b(LC (F, 1)*prodMod (factors, N)),N)) == F/Lc(F)));
+#endif
+
+  CFList T, S;
+
+  CanonicalForm M= N;
+  int l= degree (N);
+  T= factors;
+  CFList result;
+  Variable x= Variable (1);
+  CanonicalForm denom= den, denQuot;
+  CanonicalForm LCBuf= LC (F, x)*denom;
+  CanonicalForm g, quot, buf= F;
+  int * v= new int [T.length()];
+  for (int i= 0; i < T.length(); i++)
+    v[i]= 0;
+  bool nosubset= false;
+  CFArray TT;
+  DegreePattern bufDegs1, bufDegs2;
+  bufDegs1= degs;
+  int subsetDeg;
+  TT= copy (factors);
+  bool recombination= false;
+  CanonicalForm test;
+  bool isRat= (isOn (SW_RATIONAL) && getCharacteristic() == 0) ||
+               getCharacteristic() > 0;
+  if (!isRat)
+    On (SW_RATIONAL);
+  CanonicalForm buf0= mulNTL (buf (0, x), LCBuf);
+  if (!isRat)
+    Off (SW_RATIONAL);
+  while (T.length() >= 2*s && s <= thres)
+  {
+    while (nosubset == false)
+    {
+      if (T.length() == s)
+      {
+        delete [] v;
+        if (recombination)
+        {
+          T.insert (LCBuf);
+          g= prodMod (T, M);
+          if (b.getp() != 0)
+            g= b(g);
+          T.removeFirst();
+          g /= content (g,x);
+          result.append (g(y-eval,y));
+          F= 1;
+          return result;
+        }
+        else
+        {
+          result= CFList (F(y-eval,y));
+          F= 1;
+          return result;
+        }
+      }
+      S= subset (v, s, TT, nosubset);
+      if (nosubset) break;
+      subsetDeg= subsetDegree (S);
+      // skip those combinations that are not possible
+      if (!degs.find (subsetDeg))
+        continue;
+      else
+      {
+        if (!isRat)
+          On (SW_RATIONAL);
+        test= prodMod0 (S, M);
+        if (!isRat)
+        {
+          test *= bCommonDen (test);
+          Off (SW_RATIONAL);
+        }
+        test= mulNTL (test, LCBuf, b);
+        test= mod (test, M);
+        if (uniFdivides (test, buf0))
+        {
+          if (!isRat)
+            On (SW_RATIONAL);
+          S.insert (LCBuf);
+          g= prodMod (S, M);
+          S.removeFirst();
+          if (!isRat)
+          {
+            g *= bCommonDen(g);
+            Off (SW_RATIONAL);
+          }
+          if (b.getp() != 0)
+            g= b(g);
+          if (!isRat)
+            On (SW_RATIONAL);
+          g /= content (g, x);
+          if (!isRat)
+          {
+            On (SW_RATIONAL);
+            if (!Lc (g).inBaseDomain())
+              g /= Lc (g);
+            g *= bCommonDen (g);
+            Off (SW_RATIONAL);
+            g /= icontent (g);
+            On (SW_RATIONAL);
+          }
+          if (fdivides (g, buf, quot))
+          {
+            denom *= abs (lc (g));
+            recombination= true;
+            result.append (g (y-eval,y));
+            if (b.getp() != 0)
+            {
+              denQuot= bCommonDen (quot);
+              buf= quot*denQuot;
+              Off (SW_RATIONAL);
+              denom /= gcd (denom, denQuot);
+              On (SW_RATIONAL);
+            }
+            else
+              buf= quot;
+            LCBuf= LC (buf, x)*denom;
+            T= Difference (T, S);
+            l -= degree (g);
+            M= power (y, l);
+            buf0= mulNTL (buf (0, x), LCBuf);
+            if (!isRat)
+              Off (SW_RATIONAL);
+            // compute new possible degree pattern
+            bufDegs2= DegreePattern (T);
+            bufDegs1.intersect (bufDegs2);
+            bufDegs1.refine ();
+            if (T.length() < 2*s || T.length() == s ||
+                bufDegs1.getLength() == 1)
+            {
+              delete [] v;
+              if (recombination)
+              {
+                result.append (buf (y-eval,y));
+                F= 1;
+                return result;
+              }
+              else
+              {
+                result= CFList (F (y-eval,y));
+                F= 1;
+                return result;
+              }
+            }
+            TT= copy (T);
+            indexUpdate (v, s, T.length(), nosubset);
+            if (nosubset) break;
+          }
+          if (!isRat)
+            Off (SW_RATIONAL);
+        }
+      }
+    }
+    s++;
+    if (T.length() < 2*s || T.length() == s)
+    {
+      delete [] v;
+      if (recombination)
+      {
+        result.append (buf(y-eval,y));
+        F= 1;
+        return result;
+      }
+      else
+      {
+        result= CFList (F(y-eval,y));
+        F= 1;
+        return result;
+      }
+    }
+    for (int i= 0; i < T.length(); i++)
+      v[i]= 0;
+    nosubset= false;
+  }
+  delete [] v;
+  if (T.length() < 2*s)
+  {
+    result.append (F(y-eval,y));
+    F= 1;
+    return result;
+  }
+
+  if (s > thres)
+  {
+    factors= T;
+    F= buf;
+    degs= bufDegs1;
+  }
+
+  return result;
+}
+
+Variable chooseExtension (const Variable & alpha, const Variable& beta, int k)
+{
+  if (fac_NTL_char != getCharacteristic())
+  {
+    fac_NTL_char= getCharacteristic();
+    zz_p::init (getCharacteristic());
+  }
+  zz_pX NTLIrredpoly;
+  int i=1, m= 2;
+  // extension of F_p needed
+  if (alpha.level() == 1 && beta.level() == 1 && k == 1)
+  {
+    i= 1;
+    m= 2;
+  } //extension of F_p(alpha) needed but want to factorize over F_p
+  else if (alpha.level() != 1 && beta.level() == 1 && k == 1)
+  {
+    i= 1;
+    m= degree (getMipo (alpha)) + 1;
+  } //extension of F_p(alpha) needed for first time
+  else if (alpha.level() != 1 && beta.level() == 1 && k != 1)
+  {
+    i= 2;
+    m= degree (getMipo (alpha));
+  }
+  else if (alpha.level() != 1 && beta.level() != 1 && k != 1)
+  {
+    m= degree (getMipo (beta));
+    i= degree (getMipo (alpha))/m + 1;
+  }
+  BuildIrred (NTLIrredpoly, i*m);
+  CanonicalForm newMipo= convertNTLzzpX2CF (NTLIrredpoly, Variable (1));
+  return rootOf (newMipo);
+}
+
+void
+earlyFactorDetection (CFList& reconstructedFactors, CanonicalForm& F, CFList&
+                      factors, int& adaptedLiftBound, int*& factorsFoundIndex,
+                      DegreePattern& degs, bool& success, int deg, const
+                      CanonicalForm& eval, const modpk& b, CanonicalForm& den)
+{
+  DegreePattern bufDegs1= degs;
+  DegreePattern bufDegs2;
+  CFList T= factors;
+  CanonicalForm buf= F;
+  Variable x= Variable (1);
+  Variable y= Variable (2);
+  CanonicalForm g, quot;
+  CanonicalForm M= power (F.mvar(), deg);
+  adaptedLiftBound= 0;
+  int d= degree (F), l= 0;
+  bool isRat= (isOn (SW_RATIONAL) && getCharacteristic() == 0) ||
+               getCharacteristic() > 0;
+  if (!isRat)
+    On (SW_RATIONAL);
+  if (b.getp() != 0)
+    buf *= bCommonDen (buf);
+  CanonicalForm LCBuf= LC (buf, x)*den;
+  CanonicalForm buf0= mulNTL (buf (0,x), LCBuf);
+  CanonicalForm buf1= mulNTL (buf (1,x), LCBuf);
+  if (!isRat)
+    Off (SW_RATIONAL);
+  CanonicalForm test0, test1;
+  CanonicalForm denQuot;
+
+  for (CFListIterator i= factors; i.hasItem(); i++, l++)
+  {
+    if (!bufDegs1.find (degree (i.getItem(), 1)) || factorsFoundIndex[l] == 1)
+      continue;
+    else
+    {
+      test1= mod (mulNTL (i.getItem() (1,x), LCBuf, b), M);
+      if (uniFdivides (test1, buf1))
+      {
+        test0= mod (mulNTL (i.getItem() (0,x), LCBuf, b), M);
+        if (uniFdivides (test0, buf0))
+        {
+          if (!isRat)
+            On (SW_RATIONAL);
+          g= mulMod2 (i.getItem(), LCBuf, M);
+          if (!isRat)
+          {
+            g *= bCommonDen(g);
+            Off (SW_RATIONAL);
+          }
+          if (b.getp() != 0)
+            g= b(g);
+          if (!isRat)
+            On (SW_RATIONAL);
+          g /= content (g, x);
+          if (!isRat)
+          {
+            On (SW_RATIONAL);
+            if (!Lc (g).inBaseDomain())
+              g /= Lc (g);
+            g *= bCommonDen (g);
+            Off (SW_RATIONAL);
+            g /= icontent (g);
+            On (SW_RATIONAL);
+          }
+          if (fdivides (g, buf, quot))
+          {
+            den *= abs (lc (g));
+            reconstructedFactors.append (g (y-eval,y));
+            factorsFoundIndex[l]= 1;
+            if (b.getp() != 0)
+            {
+              denQuot= bCommonDen (quot);
+              buf= quot*denQuot;
+              Off (SW_RATIONAL);
+              den /= gcd (den, denQuot);
+              On (SW_RATIONAL);
+            }
+            else
+              buf= quot;
+            d -= degree (g);
+            LCBuf= LC (buf, x)*den;
+            buf0= mulNTL (buf (0,x), LCBuf);
+            buf1= mulNTL (buf (1,x), LCBuf);
+            if (!isRat)
+              Off (SW_RATIONAL);
+            T= Difference (T, CFList (i.getItem()));
+            F= buf;
+
+            // compute new possible degree pattern
+            bufDegs2= DegreePattern (T);
+            bufDegs1.intersect (bufDegs2);
+            bufDegs1.refine ();
+            if (bufDegs1.getLength() <= 1)
+            {
+              if (!buf.inCoeffDomain())
+              {
+                reconstructedFactors.append (buf (y-eval,y));
+                F= 1;
+              }
+              break;
+            }
+          }
+          if (!isRat)
+            Off (SW_RATIONAL);
+        }
+      }
+    }
+  }
+  adaptedLiftBound= d + 1;
+  if (adaptedLiftBound < deg)
+  {
+    degs= bufDegs1;
+    success= true;
+  }
+  if (bufDegs1.getLength() <= 1)
+    degs= bufDegs1;
+}
+
+void
+earlyFactorDetection (CFList& reconstructedFactors, CanonicalForm& F, CFList&
+                      factors, int& adaptedLiftBound, int*& factorsFoundIndex,
+                      DegreePattern& degs, bool& success, int deg, const
+                      CanonicalForm& eval, const modpk& b)
+{
+  CanonicalForm den= 1;
+  earlyFactorDetection (reconstructedFactors, F, factors, adaptedLiftBound,
+                        factorsFoundIndex, degs, success, deg, eval, b, den);
+}
+
+void
+extEarlyFactorDetection (CFList& reconstructedFactors, CanonicalForm& F, CFList&
+                         factors,int& adaptedLiftBound, int*& factorsFoundIndex,
+                         DegreePattern& degs, bool& success, const
+                         ExtensionInfo& info, const CanonicalForm& eval, int deg
+                        )
+{
+  Variable alpha= info.getAlpha();
+  Variable beta= info.getBeta();
+  CanonicalForm gamma= info.getGamma();
+  CanonicalForm delta= info.getDelta();
+  int k= info.getGFDegree();
+  DegreePattern bufDegs1= degs, bufDegs2;
+  CFList result;
+  CFList T= factors;
+  Variable y= F.mvar();
+  Variable x= Variable (1);
+  CanonicalForm buf= F, LCBuf= LC (buf, x), g, buf2;
+  CanonicalForm M= power (y, deg);
+  adaptedLiftBound= 0;
+  bool trueFactor= false;
+  int d= degree (F), l= 0;
+  CFList source, dest;
+  int degMipoBeta= 1;
+  if (!k && beta.level() != 1)
+    degMipoBeta= degree (getMipo (beta));
+  CanonicalForm quot;
+  for (CFListIterator i= factors; i.hasItem(); i++, l++)
+  {
+    if (!bufDegs1.find (degree (i.getItem(), 1)) || factorsFoundIndex[l] == 1)
+      continue;
+    else
+    {
+      g= mulMod2 (i.getItem(), LCBuf, M);
+      g /= content (g, x);
+      if (fdivides (g, buf, quot))
+      {
+        buf2= g (y - eval, y);
+        buf2 /= Lc (buf2);
+
+        if (!k && beta == x)
+        {
+          if (degree (buf2, alpha) < degMipoBeta)
+          {
+            appendTestMapDown (reconstructedFactors, buf2, info, source, dest);
+            factorsFoundIndex[l]= 1;
+            buf= quot;
+            d -= degree (g);
+            LCBuf= LC (buf, x);
+            trueFactor= true;
+          }
+        }
+        else
+        {
+          if (!isInExtension (buf2, gamma, k, delta, source, dest))
+          {
+            appendTestMapDown (reconstructedFactors, buf2, info, source, dest);
+            factorsFoundIndex[l]= 1;
+            buf= quot;
+            d -= degree (g);
+            LCBuf= LC (buf, x);
+            trueFactor= true;
+          }
+        }
+        if (trueFactor)
+        {
+          T= Difference (T, CFList (i.getItem()));
+          F= buf;
+
+          // compute new possible degree pattern
+          bufDegs2= DegreePattern (T);
+          bufDegs1.intersect (bufDegs2);
+          bufDegs1.refine ();
+          trueFactor= false;
+          if (bufDegs1.getLength() <= 1)
+          {
+            if (!buf.inCoeffDomain())
+            {
+              buf= buf (y - eval, y);
+              buf /= Lc (buf);
+              appendMapDown (reconstructedFactors, buf, info, source, dest);
+              F= 1;
+            }
+            break;
+          }
+        }
+      }
+    }
+  }
+  adaptedLiftBound= d + 1;
+  if (adaptedLiftBound < deg)
+  {
+    degs= bufDegs1;
+    success= true;
+  }
+  if (bufDegs1.getLength() <= 1)
+    degs= bufDegs1;
+}
+
+int*
+getCombinations (int * rightSide, int sizeOfRightSide, int& sizeOfOutput,
+                 int degreeLC)
+{
+  Variable x= Variable (1);
+  int p= getCharacteristic();
+  int d= getGFDegree();
+  char cGFName= gf_name;
+  setCharacteristic(0);
+  CanonicalForm buf= 1;
+  for (int i= 0; i < sizeOfRightSide; i++)
+    buf *= (power (x, rightSide [i]) + 1);
+
+  int j= 0;
+  for (CFIterator i= buf; i.hasTerms(); i++, j++)
+  {
+    if (i.exp() < degreeLC)
+    {
+      j++;
+      break;
+    }
+  }
+
+  ASSERT ( j > 1, "j > 1 expected" );
+
+  int* result = new int  [j - 1];
+  sizeOfOutput= j - 1;
+
+  int i= 0;
+  for (CFIterator m = buf; i < j - 1; i++, m++)
+    result [i]= m.exp();
+
+  if (d > 1)
+    setCharacteristic (p, d, cGFName);
+  else
+    setCharacteristic (p);
+  return result;
+}
+
+int *
+getLiftPrecisions (const CanonicalForm& F, int& sizeOfOutput, int degreeLC)
+{
+  int sizeOfNewtonPoly;
+  int ** newtonPolyg= newtonPolygon (F, sizeOfNewtonPoly);
+  int sizeOfRightSide;
+  int * rightSide= getRightSide(newtonPolyg, sizeOfNewtonPoly, sizeOfRightSide);
+  int * result= getCombinations(rightSide, sizeOfRightSide, sizeOfOutput,
+                                degreeLC);
+  delete [] rightSide;
+  for (int i= 0; i < sizeOfNewtonPoly; i++)
+    delete [] newtonPolyg[i];
+  delete [] newtonPolyg;
+  return result;
+}
+
+void
+deleteFactors (CFList& factors, int* factorsFoundIndex)
+{
+  CFList result;
+  int i= 0;
+  for (CFListIterator iter= factors; iter.hasItem(); iter++, i++)
+  {
+    if (factorsFoundIndex[i] == 1)
+      continue;
+    else
+      result.append (iter.getItem());
+  }
+  factors= result;
+}
+
+CFList
+henselLiftAndEarly (CanonicalForm& A, bool& earlySuccess, CFList&
+                    earlyFactors, DegreePattern& degs, int& liftBound,
+                    const CFList& uniFactors, const ExtensionInfo& info,
+                    const CanonicalForm& eval,modpk& b, CanonicalForm& den)
+{
+  Variable alpha= info.getAlpha();
+  Variable beta= info.getBeta();
+  CanonicalForm gamma= info.getGamma();
+  CanonicalForm delta= info.getDelta();
+  bool extension= info.isInExtension();
+
+  int sizeOfLiftPre;
+  int * liftPre= getLiftPrecisions (A, sizeOfLiftPre, degree (LC (A, 1), 2));
+
+  Variable x= Variable (1);
+  Variable y= Variable (2);
+  CFArray Pi;
+  CFList diophant;
+  CFList bufUniFactors= uniFactors;
+  On (SW_RATIONAL);
+  CanonicalForm bufA= A;
+  if (!Lc (A).inBaseDomain())
+  {
+    bufA /= Lc (A);
+    CanonicalForm denBufA= bCommonDen (bufA);
+    bufA *= denBufA;
+    Off (SW_RATIONAL);
+    den /= gcd (den, denBufA);
+  }
+  else
+  {
+    bufA= A;
+    Off (SW_RATIONAL);
+    den /= gcd (den, Lc (A));
+  }
+  CanonicalForm lcA0= 0;
+  bool mipoHasDen= false;
+  if (getCharacteristic() == 0 && b.getp() != 0)
+  {
+    if (alpha.level() == 1)
+    {
+      lcA0= lc (A (0, 2));
+      A *= b.inverse (lcA0);
+      A= b (A);
+      for (CFListIterator i= bufUniFactors; i.hasItem(); i++)
+        i.getItem()= b (i.getItem()*b.inverse (lc (i.getItem())));
+    }
+    else
+    {
+      lcA0= Lc (A (0,2));
+      On (SW_RATIONAL);
+      mipoHasDen= !bCommonDen(getMipo(alpha)).isOne();
+      Off (SW_RATIONAL);
+      CanonicalForm lcA0inverse= b.inverse (lcA0);
+      A *= lcA0inverse;
+      A= b (A);
+      // Lc of bufUniFactors is in Z
+      for (CFListIterator i= bufUniFactors; i.hasItem(); i++)
+        i.getItem()= b (i.getItem()*b.inverse (lc (i.getItem())));
+    }
+  }
+  bufUniFactors.insert (LC (A, x));
+  CFMatrix M= CFMatrix (liftBound, bufUniFactors.length() - 1);
+  earlySuccess= false;
+  int newLiftBound= 0;
+
+  int smallFactorDeg= tmin (11, liftPre [sizeOfLiftPre- 1] + 1);//this is a tunable parameter
+  int dummy;
+  int * factorsFoundIndex= new int [uniFactors.length()];
+  for (int i= 0; i < uniFactors.length(); i++)
+    factorsFoundIndex [i]= 0;
+
+  CFList bufBufUniFactors;
+  Variable v= alpha;
+  if (smallFactorDeg >= liftBound || degree (A,y) <= 4)
+    henselLift12 (A, bufUniFactors, liftBound, Pi, diophant, M, b, true);
+  else if (sizeOfLiftPre > 1 && sizeOfLiftPre < 30)
+  {
+    henselLift12 (A, bufUniFactors, smallFactorDeg, Pi, diophant, M, b, true);
+    if (mipoHasDen)
+    {
+      for (CFListIterator iter= bufUniFactors; iter.hasItem(); iter++)
+        if (hasFirstAlgVar (iter.getItem(), v))
+          break;
+      if (v != alpha)
+      {
+        bufBufUniFactors= bufUniFactors;
+        for (CFListIterator iter= bufBufUniFactors; iter.hasItem(); iter++)
+          iter.getItem()= replacevar (iter.getItem(), v, alpha);
+        A= replacevar (A, alpha, v);
+      }
+    }
+
+    if (!extension)
+    {
+      if (v==alpha)
+        earlyFactorDetection (earlyFactors, bufA, bufUniFactors, newLiftBound,
+                              factorsFoundIndex, degs, earlySuccess,
+                              smallFactorDeg, eval, b, den);
+      else
+        earlyFactorDetection(earlyFactors, bufA, bufBufUniFactors, newLiftBound,
+                             factorsFoundIndex, degs, earlySuccess,
+                             smallFactorDeg, eval, b, den);
+    }
+    else
+      extEarlyFactorDetection (earlyFactors, bufA, bufUniFactors, newLiftBound,
+                               factorsFoundIndex, degs, earlySuccess, info,
+                               eval, smallFactorDeg);
+    if (degs.getLength() > 1 && !earlySuccess &&
+        smallFactorDeg != liftPre [sizeOfLiftPre-1] + 1)
+    {
+      if (newLiftBound >= liftPre[sizeOfLiftPre-1]+1)
+      {
+        bufUniFactors.insert (LC (A, x));
+        henselLiftResume12 (A, bufUniFactors, smallFactorDeg,
+                            liftPre[sizeOfLiftPre-1] + 1, Pi, diophant, M, b);
+        if (v!=alpha)
+        {
+          bufBufUniFactors= bufUniFactors;
+          for (CFListIterator iter= bufBufUniFactors; iter.hasItem(); iter++)
+            iter.getItem()= replacevar (iter.getItem(), v, alpha);
+        }
+        if (!extension)
+        {
+          if (v==alpha)
+          earlyFactorDetection (earlyFactors, bufA, bufUniFactors, newLiftBound,
+                                factorsFoundIndex, degs, earlySuccess,
+                                liftPre[sizeOfLiftPre-1] + 1, eval, b, den);
+          else
+          earlyFactorDetection (earlyFactors,bufA,bufBufUniFactors,newLiftBound,
+                                factorsFoundIndex, degs, earlySuccess,
+                                liftPre[sizeOfLiftPre-1] + 1, eval, b, den);
+        }
+        else
+          extEarlyFactorDetection (earlyFactors,bufA,bufUniFactors,newLiftBound,
+                                   factorsFoundIndex, degs, earlySuccess, info,
+                                   eval, liftPre[sizeOfLiftPre-1] + 1);
+      }
+    }
+    else if (earlySuccess)
+      liftBound= newLiftBound;
+
+    int i= sizeOfLiftPre - 1;
+    while (degs.getLength() > 1 && !earlySuccess && i - 1 >= 0)
+    {
+      if (newLiftBound >= liftPre[i] + 1)
+      {
+        bufUniFactors.insert (LC (A, x));
+        henselLiftResume12 (A, bufUniFactors, liftPre[i] + 1,
+                            liftPre[i-1] + 1, Pi, diophant, M, b);
+        if (v!=alpha)
+        {
+          bufBufUniFactors= bufUniFactors;
+          for (CFListIterator iter= bufBufUniFactors; iter.hasItem(); iter++)
+            iter.getItem()= replacevar (iter.getItem(), v, alpha);
+        }
+        if (!extension)
+        {
+          if (v==alpha)
+          earlyFactorDetection (earlyFactors, bufA, bufUniFactors, newLiftBound,
+                                factorsFoundIndex, degs, earlySuccess,
+                                liftPre[i-1] + 1, eval, b, den);
+          else
+          earlyFactorDetection (earlyFactors,bufA,bufBufUniFactors,newLiftBound,
+                                factorsFoundIndex, degs, earlySuccess,
+                                liftPre[i-1] + 1, eval, b, den);
+        }
+        else
+          extEarlyFactorDetection (earlyFactors,bufA,bufUniFactors,newLiftBound,
+                                   factorsFoundIndex, degs, earlySuccess, info,
+                                   eval, liftPre[i-1] + 1);
+      }
+      else
+      {
+        liftBound= newLiftBound;
+        break;
+      }
+      i--;
+    }
+    if (earlySuccess)
+      liftBound= newLiftBound;
+    //after here all factors are lifted to liftPre[sizeOfLiftPre-1]
+  }
+  else
+  {
+    henselLift12 (A, bufUniFactors, smallFactorDeg, Pi, diophant, M, b, true);
+    if (mipoHasDen)
+    {
+      for (CFListIterator iter= bufUniFactors; iter.hasItem(); iter++)
+        if (hasFirstAlgVar (iter.getItem(), v))
+          break;
+      if (v != alpha)
+      {
+        bufBufUniFactors= bufUniFactors;
+        for (CFListIterator iter= bufBufUniFactors; iter.hasItem(); iter++)
+          iter.getItem()= replacevar (iter.getItem(), v, alpha);
+        A= replacevar (A, alpha, v);
+      }
+    }
+    if (!extension)
+    {
+      if (v==alpha)
+      earlyFactorDetection (earlyFactors, bufA, bufUniFactors, newLiftBound,
+                            factorsFoundIndex, degs, earlySuccess,
+                            smallFactorDeg, eval, b, den);
+      else
+      earlyFactorDetection (earlyFactors, bufA, bufBufUniFactors, newLiftBound,
+                            factorsFoundIndex, degs, earlySuccess,
+                            smallFactorDeg, eval, b, den);
+    }
+    else
+      extEarlyFactorDetection (earlyFactors, bufA, bufUniFactors, newLiftBound,
+                               factorsFoundIndex, degs, earlySuccess, info,
+                               eval, smallFactorDeg);
+    int i= 1;
+    while ((degree (A,y)/4)*i + 4 <= smallFactorDeg)
+      i++;
+    dummy= tmin (degree (A,y)+1, (degree (A,y)/4)*i+4);
+    if (degs.getLength() > 1 && !earlySuccess && dummy > smallFactorDeg)
+    {
+      bufUniFactors.insert (LC (A, x));
+      henselLiftResume12 (A, bufUniFactors, smallFactorDeg,
+                          dummy, Pi, diophant, M, b);
+      if (v!=alpha)
+      {
+        bufBufUniFactors= bufUniFactors;
+        for (CFListIterator iter= bufBufUniFactors; iter.hasItem(); iter++)
+          iter.getItem()= replacevar (iter.getItem(), v, alpha);
+      }
+      if (!extension)
+      {
+        if (v==alpha)
+        earlyFactorDetection (earlyFactors, bufA, bufUniFactors, newLiftBound,
+                              factorsFoundIndex, degs, earlySuccess, dummy,eval,
+                              b, den);
+        else
+        earlyFactorDetection (earlyFactors, bufA,bufBufUniFactors, newLiftBound,
+                              factorsFoundIndex, degs, earlySuccess, dummy,eval,
+                              b, den);
+      }
+      else
+        extEarlyFactorDetection (earlyFactors, bufA,bufUniFactors, newLiftBound,
+                                 factorsFoundIndex, degs, earlySuccess, info,
+                                 eval, dummy);
+    }
+    while (degs.getLength() > 1 && !earlySuccess && i < 4)
+    {
+      if (newLiftBound >= dummy)
+      {
+        bufUniFactors.insert (LC (A, x));
+        dummy= tmin (degree (A,y)+1, (degree (A,y)/4)*(i+1)+4);
+        henselLiftResume12 (A, bufUniFactors, (degree (A,y)/4)*i + 4,
+                            dummy, Pi, diophant, M, b);
+        if (v!=alpha)
+        {
+          bufBufUniFactors= bufUniFactors;
+          for (CFListIterator iter= bufBufUniFactors; iter.hasItem(); iter++)
+            iter.getItem()= replacevar (iter.getItem(), v, alpha);
+        }
+        if (!extension)
+        {
+          if (v==alpha)
+          earlyFactorDetection (earlyFactors, bufA, bufUniFactors, newLiftBound,
+                                factorsFoundIndex, degs, earlySuccess, dummy,
+                                eval, b, den);
+          else
+          earlyFactorDetection (earlyFactors,bufA,bufBufUniFactors,newLiftBound,
+                                factorsFoundIndex, degs, earlySuccess, dummy,
+                                eval, b, den);
+        }
+        else
+          extEarlyFactorDetection (earlyFactors,bufA,bufUniFactors,newLiftBound,
+                                   factorsFoundIndex, degs, earlySuccess, info,
+                                   eval, dummy);
+      }
+      else
+      {
+        liftBound= newLiftBound;
+        break;
+      }
+      i++;
+    }
+    if (earlySuccess)
+      liftBound= newLiftBound;
+  }
+
+  A= bufA;
+  if (earlyFactors.length() > 0 && degs.getLength() > 1)
+  {
+    liftBound= degree (A,y) + 1;
+    earlySuccess= true;
+    deleteFactors (bufUniFactors, factorsFoundIndex);
+  }
+
+  delete [] factorsFoundIndex;
+  delete [] liftPre;
+
+  return bufUniFactors;
+}
+
+CFList
+henselLiftAndEarly (CanonicalForm& A, bool& earlySuccess, CFList&
+                    earlyFactors, DegreePattern& degs, int& liftBound,
+                    const CFList& uniFactors, const ExtensionInfo& info,
+                    const CanonicalForm& eval)
+{
+  modpk dummy= modpk();
+  CanonicalForm den= 1;
+  return henselLiftAndEarly (A, earlySuccess, earlyFactors, degs, liftBound,
+                             uniFactors, info, eval, dummy, den);
+}
+
+#ifndef HAVE_FLINT
+long isReduced (const mat_zz_p& M)
+{
+  long i, j, nonZero;
+  for (i = 1; i <= M.NumRows(); i++)
+  {
+    nonZero= 0;
+    for (j = 1; j <= M.NumCols(); j++)
+    {
+      if (!IsZero (M (i,j)))
+        nonZero++;
+    }
+    if (nonZero != 1)
+      return 0;
+  }
+  return 1;
+}
+#endif
+
+#ifdef HAVE_FLINT
+long isReduced (const nmod_mat_t M)
+{
+  long i, j, nonZero;
+  for (i = 1; i <= nmod_mat_nrows(M); i++)
+  {
+    nonZero= 0;
+    for (j = 1; j <= nmod_mat_ncols (M); j++)
+    {
+      if (!(nmod_mat_entry (M, i-1, j-1)==0))
+        nonZero++;
+    }
+    if (nonZero != 1)
+      return 0;
+  }
+  return 1;
+}
+#endif
+
+long isReduced (const mat_zz_pE& M)
+{
+  long i, j, nonZero;
+  for (i = 1; i <= M.NumRows(); i++)
+  {
+    nonZero= 0;
+    for (j = 1; j <= M.NumCols(); j++)
+    {
+      if (!IsZero (M (i,j)))
+        nonZero++;
+    }
+    if (nonZero != 1)
+      return 0;
+  }
+  return 1;
+}
+
+#ifndef HAVE_FLINT
+int * extractZeroOneVecs (const mat_zz_p& M)
+{
+  long i, j;
+  bool nonZeroOne= false;
+  int * result= new int [M.NumCols()];
+  for (i = 1; i <= M.NumCols(); i++)
+  {
+    for (j = 1; j <= M.NumRows(); j++)
+    {
+      if (!(IsOne (M (j,i)) || IsZero (M (j,i))))
+      {
+        nonZeroOne= true;
+        break;
+      }
+    }
+    if (!nonZeroOne)
+      result [i - 1]= 1;
+    else
+      result [i - 1]= 0;
+    nonZeroOne= false;
+  }
+  return result;
+}
+#endif
+
+#ifdef HAVE_FLINT
+int * extractZeroOneVecs (const nmod_mat_t M)
+{
+  long i, j;
+  bool nonZeroOne= false;
+  int * result= new int [nmod_mat_ncols (M)];
+  for (i = 0; i < nmod_mat_ncols (M); i++)
+  {
+    for (j = 0; j < nmod_mat_nrows (M); j++)
+    {
+      if (!((nmod_mat_entry (M, j, i) == 1) || (nmod_mat_entry (M, j,i) == 0)))
+      {
+        nonZeroOne= true;
+        break;
+      }
+    }
+    if (!nonZeroOne)
+      result [i]= 1;
+    else
+      result [i]= 0;
+    nonZeroOne= false;
+  }
+  return result;
+}
+#endif
+
+int * extractZeroOneVecs (const mat_zz_pE& M)
+{
+  long i, j;
+  bool nonZeroOne= false;
+  int * result= new int [M.NumCols()];
+  for (i = 1; i <= M.NumCols(); i++)
+  {
+    for (j = 1; j <= M.NumRows(); j++)
+    {
+      if (!(IsOne (M (j,i)) || IsZero (M (j,i))))
+      {
+        nonZeroOne= true;
+        break;
+      }
+    }
+    if (!nonZeroOne)
+      result [i - 1]= 1;
+    else
+      result [i - 1]= 0;
+    nonZeroOne= false;
+  }
+  return result;
+}
+
+void
+reconstructionTry (CFList& reconstructedFactors, CanonicalForm& F, const CFList&
+                   factors, const int liftBound, int& factorsFound, int*&
+                   factorsFoundIndex, mat_zz_pE& N, const CanonicalForm& eval,
+                   bool beenInThres
+                  )
+{
+  Variable y= Variable (2);
+  Variable x= Variable (1);
+  CanonicalForm yToL= power (y, liftBound);
+  CanonicalForm bufF= F (y-eval, y);
+  if (factors.length() == 2)
+  {
+    CanonicalForm tmp1, tmp2, tmp3;
+    tmp1= factors.getFirst();
+    tmp2= factors.getLast();
+    tmp1= mulMod2 (tmp1, LC (F,x), yToL);
+    tmp1 /= content (tmp1, x);
+    tmp1= tmp1 (y-eval, y);
+    tmp2= mulMod2 (tmp2, LC (F,x), yToL);
+    tmp2 /= content (tmp2, x);
+    tmp2= tmp2 (y-eval, y);
+    tmp3 = tmp1*tmp2;
+    if (tmp3/Lc (tmp3) == bufF/Lc (bufF))
+    {
+      factorsFound++;
+      F= 1;
+      reconstructedFactors.append (tmp1);
+      reconstructedFactors.append (tmp2);
+      return;
+    }
+  }
+  CanonicalForm quot, buf;
+  CFListIterator iter;
+  for (long i= 1; i <= N.NumCols(); i++)
+  {
+    if (factorsFoundIndex [i - 1] == 1)
+      continue;
+    iter= factors;
+    if (beenInThres)
+    {
+      int count= 1;
+      while (count < i)
+      {
+        count++;
+        iter++;
+      }
+      buf= iter.getItem();
+    }
+    else
+    {
+      buf= 1;
+      for (long j= 1; j <= N.NumRows(); j++, iter++)
+      {
+        if (!IsZero (N (j,i)))
+          buf= mulMod2 (buf, iter.getItem(), yToL);
+      }
+    }
+    buf= mulMod2 (buf, LC (F,x), yToL);
+    buf /= content (buf, x);
+    buf= buf (y-eval,y);
+    if (fdivides (buf, bufF, quot))
+    {
+      factorsFoundIndex[i - 1]= 1;
+      factorsFound++;
+      bufF= quot;
+      bufF /= Lc (bufF);
+      reconstructedFactors.append (buf);
+    }
+    if (degree (bufF) <= 0)
+      return;
+    if (factorsFound + 1 == N.NumCols())
+    {
+      reconstructedFactors.append (bufF);
+      F= 1;
+      return;
+    }
+  }
+  if (reconstructedFactors.length() != 0)
+    F= bufF (y+eval,y);
+}
+
+#ifndef HAVE_FLINT
+void
+reconstructionTry (CFList& reconstructedFactors, CanonicalForm& F, const CFList&
+                   factors, const int liftBound, int& factorsFound, int*&
+                   factorsFoundIndex, mat_zz_p& N, const CanonicalForm& eval,
+                   bool beenInThres
+                  )
+{
+  Variable y= Variable (2);
+  Variable x= Variable (1);
+  CanonicalForm yToL= power (y, liftBound);
+  CanonicalForm bufF= F (y-eval, y);
+  if (factors.length() == 2)
+  {
+    CanonicalForm tmp1, tmp2, tmp3;
+    tmp1= factors.getFirst();
+    tmp2= factors.getLast();
+    tmp1= mulMod2 (tmp1, LC (F,x), yToL);
+    tmp1 /= content (tmp1, x);
+    tmp1= tmp1 (y-eval, y);
+    tmp2= mulMod2 (tmp2, LC (F,x), yToL);
+    tmp2 /= content (tmp2, x);
+    tmp2= tmp2 (y-eval,y);
+    tmp3 = tmp1*tmp2;
+    if (tmp3/Lc (tmp3) == bufF/Lc (bufF))
+    {
+      factorsFound++;
+      F= 1;
+      reconstructedFactors.append (tmp1);
+      reconstructedFactors.append (tmp2);
+      return;
+    }
+  }
+  CanonicalForm quot, buf;
+  CFListIterator iter;
+  for (long i= 1; i <= N.NumCols(); i++)
+  {
+    if (factorsFoundIndex [i - 1] == 1)
+      continue;
+    iter= factors;
+    if (beenInThres)
+    {
+      int count= 1;
+      while (count < i)
+      {
+        count++;
+        iter++;
+      }
+      buf= iter.getItem();
+    }
+    else
+    {
+      buf= 1;
+      for (long j= 1; j <= N.NumRows(); j++, iter++)
+      {
+        if (!IsZero (N (j,i)))
+          buf= mulMod2 (buf, iter.getItem(), yToL);
+      }
+    }
+    buf= mulMod2 (buf, LC (F,x), yToL);
+    buf /= content (buf, x);
+    buf= buf (y-eval,y);
+    if (fdivides (buf, bufF, quot))
+    {
+      factorsFoundIndex[i - 1]= 1;
+      factorsFound++;
+      bufF= quot;
+      bufF /= Lc (bufF);
+      reconstructedFactors.append (buf);
+    }
+    if (degree (bufF) <= 0)
+      return;
+    if (factorsFound + 1 == N.NumCols())
+    {
+      reconstructedFactors.append (bufF);
+      F=1;
+      return;
+    }
+  }
+  if (reconstructedFactors.length() != 0)
+    F= bufF (y+eval,y);
+}
+#endif
+
+#ifdef HAVE_FLINT
+void
+reconstructionTry (CFList& reconstructedFactors, CanonicalForm& F, const CFList&
+                   factors, const int liftBound, int& factorsFound, int*&
+                   factorsFoundIndex, nmod_mat_t N, const CanonicalForm& eval,
+                   bool beenInThres
+                  )
+{
+  Variable y= Variable (2);
+  Variable x= Variable (1);
+  CanonicalForm yToL= power (y, liftBound);
+  CanonicalForm bufF= F (y-eval, y);
+  if (factors.length() == 2)
+  {
+    CanonicalForm tmp1, tmp2, tmp3;
+    tmp1= factors.getFirst();
+    tmp2= factors.getLast();
+    tmp1= mulMod2 (tmp1, LC (F,x), yToL);
+    tmp1 /= content (tmp1, x);
+    tmp1= tmp1 (y-eval, y);
+    tmp2= mulMod2 (tmp2, LC (F,x), yToL);
+    tmp2 /= content (tmp2, x);
+    tmp2= tmp2 (y-eval, y);
+    tmp3 = tmp1*tmp2;
+    if (tmp3/Lc (tmp3) == bufF/Lc (bufF))
+    {
+      factorsFound++;
+      F= 1;
+      reconstructedFactors.append (tmp1);
+      reconstructedFactors.append (tmp2);
+      return;
+    }
+  }
+  CanonicalForm quot, buf;
+  CFListIterator iter;
+  for (long i= 0; i < nmod_mat_ncols (N); i++)
+  {
+    if (factorsFoundIndex [i] == 1)
+      continue;
+    iter= factors;
+    if (beenInThres)
+    {
+      int count= 0;
+      while (count < i)
+      {
+        count++;
+        iter++;
+      }
+      buf= iter.getItem();
+    }
+    else
+    {
+      buf= 1;
+      for (long j= 0; j < nmod_mat_nrows (N); j++, iter++)
+      {
+        if (!(nmod_mat_entry (N, j, i) == 0))
+          buf= mulMod2 (buf, iter.getItem(), yToL);
+      }
+    }
+    buf= mulMod2 (buf, LC (F,x), yToL);
+    buf /= content (buf, x);
+    buf= buf (y-eval,y);
+    if (fdivides (buf, bufF, quot))
+    {
+      factorsFoundIndex[i]= 1;
+      factorsFound++;
+      bufF= quot;
+      bufF /= Lc (bufF);
+      reconstructedFactors.append (buf);
+    }
+    if (degree (F) <= 0)
+      return;
+    if (factorsFound + 1 == nmod_mat_ncols (N))
+    {
+      F= 1;
+      reconstructedFactors.append (bufF);
+      return;
+    }
+  }
+  if (reconstructedFactors.length() != 0)
+    F= bufF (y+eval,y);
+}
+#endif
+
+CFList
+reconstruction (CanonicalForm& G, CFList& factors, int* zeroOneVecs, int
+                precision, const mat_zz_pE& N, const CanonicalForm& eval
+               )
+{
+  Variable y= Variable (2);
+  Variable x= Variable (1);
+  CanonicalForm F= G;
+  CanonicalForm yToL= power (y, precision);
+  CanonicalForm quot, buf;
+  CFList result, factorsConsidered;
+  CFList bufFactors= factors;
+  CFListIterator iter;
+  for (long i= 1; i <= N.NumCols(); i++)
+  {
+    if (zeroOneVecs [i - 1] == 0)
+      continue;
+    iter= factors;
+    buf= 1;
+    factorsConsidered= CFList();
+    for (long j= 1; j <= N.NumRows(); j++, iter++)
+    {
+      if (!IsZero (N (j,i)))
+      {
+        factorsConsidered.append (iter.getItem());
+        buf= mulMod2 (buf, iter.getItem(), yToL);
+      }
+    }
+    buf= mulMod2 (buf, LC (F,x), yToL);
+    buf /= content (buf, x);
+    if (fdivides (buf, F, quot))
+    {
+      F= quot;
+      F /= Lc (F);
+      result.append (buf (y-eval,y));
+      bufFactors= Difference (bufFactors, factorsConsidered);
+    }
+    if (degree (F) <= 0)
+    {
+      G= F;
+      factors= bufFactors;
+      return result;
+    }
+  }
+  G= F;
+  factors= bufFactors;
+  return result;
+}
+
+CFList
+monicReconstruction (CanonicalForm& G, CFList& factors, int* zeroOneVecs,
+                     int precision, const mat_zz_pE& N
+                    )
+{
+  Variable y= Variable (2);
+  Variable x= Variable (1);
+  CanonicalForm F= G;
+  CanonicalForm yToL= power (y, precision);
+  CanonicalForm quot, buf, buf2;
+  CFList result;
+  CFList bufFactors= factors;
+  CFList factorsConsidered;
+  CFListIterator iter;
+  for (long i= 1; i <= N.NumCols(); i++)
+  {
+    if (zeroOneVecs [i - 1] == 0)
+      continue;
+    iter= factors;
+    buf= 1;
+    factorsConsidered= CFList();
+    for (long j= 1; j <= N.NumRows(); j++, iter++)
+    {
+      if (!IsZero (N (j,i)))
+      {
+        factorsConsidered.append (iter.getItem());
+        buf= mulMod2 (buf, iter.getItem(), yToL);
+      }
+    }
+    buf2= buf;
+    buf= mulMod2 (buf, LC (F,x), yToL);
+    buf /= content (buf, x);
+    if (fdivides (buf, F, quot))
+    {
+      F= quot;
+      F /= Lc (F);
+      result.append (buf2);
+      bufFactors= Difference (bufFactors, factorsConsidered);
+    }
+    if (degree (F) <= 0)
+    {
+      G= F;
+      factors= bufFactors;
+      return result;
+    }
+  }
+  G= F;
+  factors= bufFactors;
+  return result;
+}
+
+#ifndef HAVE_FLINT
+CFList
+extReconstruction (CanonicalForm& G, CFList& factors, int* zeroOneVecs, int
+                   precision, const mat_zz_p& N, const ExtensionInfo& info,
+                   const CanonicalForm& evaluation
+                  )
+{
+  Variable y= Variable (2);
+  Variable x= Variable (1);
+  Variable alpha= info.getAlpha();
+  Variable beta= info.getBeta();
+  int k= info.getGFDegree();
+  CanonicalForm gamma= info.getGamma();
+  CanonicalForm delta= info.getDelta();
+  CanonicalForm F= G;
+  CanonicalForm yToL= power (y, precision);
+  CFList result;
+  CFList bufFactors= factors;
+  CFList factorsConsidered;
+  CanonicalForm buf2, quot, buf;
+  CFListIterator iter;
+  for (long i= 1; i <= N.NumCols(); i++)
+  {
+    if (zeroOneVecs [i - 1] == 0)
+      continue;
+    iter= factors;
+    buf= 1;
+    factorsConsidered= CFList();
+    for (long j= 1; j <= N.NumRows(); j++, iter++)
+    {
+      if (!IsZero (N (j,i)))
+      {
+        factorsConsidered.append (iter.getItem());
+        buf= mulMod2 (buf, iter.getItem(), yToL);
+      }
+    }
+    buf= mulMod2 (buf, LC (F,x), yToL);
+    buf /= content (buf, x);
+    buf2= buf (y-evaluation, y);
+    buf2 /= Lc (buf2);
+    if (!k && beta == x)
+    {
+      if (degree (buf2, alpha) < 1)
+      {
+        if (fdivides (buf, F, quot))
+        {
+          F= quot;
+          F /= Lc (F);
+          result.append (buf2);
+          bufFactors= Difference (bufFactors, factorsConsidered);
+        }
+      }
+    }
+    else
+    {
+      CFList source, dest;
+
+      if (!isInExtension (buf2, gamma, k, delta, source, dest))
+      {
+        if (fdivides (buf, F, quot))
+        {
+          F= quot;
+          F /= Lc (F);
+          result.append (buf2);
+          bufFactors= Difference (bufFactors, factorsConsidered);
+        }
+      }
+    }
+    if (degree (F) <= 0)
+    {
+      G= F;
+      factors= bufFactors;
+      return result;
+    }
+  }
+  G= F;
+  factors= bufFactors;
+  return result;
+}
+#endif
+
+#ifdef HAVE_FLINT
+CFList
+extReconstruction (CanonicalForm& G, CFList& factors, int* zeroOneVecs, int
+                   precision, const nmod_mat_t N, const ExtensionInfo& info,
+                   const CanonicalForm& evaluation
+                  )
+{
+  Variable y= Variable (2);
+  Variable x= Variable (1);
+  Variable alpha= info.getAlpha();
+  Variable beta= info.getBeta();
+  int k= info.getGFDegree();
+  CanonicalForm gamma= info.getGamma();
+  CanonicalForm delta= info.getDelta();
+  CanonicalForm F= G;
+  CanonicalForm yToL= power (y, precision);
+  CFList result;
+  CFList bufFactors= factors;
+  CFList factorsConsidered;
+  CanonicalForm buf2, quot, buf;
+  CFListIterator iter;
+  for (long i= 0; i < nmod_mat_ncols(N); i++)
+  {
+    if (zeroOneVecs [i] == 0)
+      continue;
+    iter= factors;
+    buf= 1;
+    factorsConsidered= CFList();
+    for (long j= 0; j < nmod_mat_nrows(N); j++, iter++)
+    {
+      if (!(nmod_mat_entry (N, j, i) == 0))
+      {
+        factorsConsidered.append (iter.getItem());
+        buf= mulMod2 (buf, iter.getItem(), yToL);
+      }
+    }
+    buf= mulMod2 (buf, LC (F,x), yToL);
+    buf /= content (buf, x);
+    buf2= buf (y-evaluation, y);
+    buf2 /= Lc (buf2);
+    if (!k && beta == x)
+    {
+      if (degree (buf2, alpha) < 1)
+      {
+        if (fdivides (buf, F, quot))
+        {
+          F= quot;
+          F /= Lc (F);
+          result.append (buf2);
+          bufFactors= Difference (bufFactors, factorsConsidered);
+        }
+      }
+    }
+    else
+    {
+      CFList source, dest;
+
+      if (!isInExtension (buf2, gamma, k, delta, source, dest))
+      {
+        if (fdivides (buf, F, quot))
+        {
+          F= quot;
+          F /= Lc (F);
+          result.append (buf2);
+          bufFactors= Difference (bufFactors, factorsConsidered);
+        }
+      }
+    }
+    if (degree (F) <= 0)
+    {
+      G= F;
+      factors= bufFactors;
+      return result;
+    }
+  }
+  G= F;
+  factors= bufFactors;
+  return result;
+}
+#endif
+
+#ifndef HAVE_FLINT
+CFList
+reconstruction (CanonicalForm& G, CFList& factors, int* zeroOneVecs,
+                int precision, const mat_zz_p& N, const CanonicalForm& eval)
+{
+  Variable y= Variable (2);
+  Variable x= Variable (1);
+  CanonicalForm F= G;
+  CanonicalForm yToL= power (y, precision);
+  CanonicalForm quot, buf;
+  CFList result;
+  CFList bufFactors= factors;
+  CFList factorsConsidered;
+  CFListIterator iter;
+  for (long i= 1; i <= N.NumCols(); i++)
+  {
+    if (zeroOneVecs [i - 1] == 0)
+      continue;
+    iter= factors;
+    buf= 1;
+    factorsConsidered= CFList();
+    for (long j= 1; j <= N.NumRows(); j++, iter++)
+    {
+      if (!IsZero (N (j,i)))
+      {
+        factorsConsidered.append (iter.getItem());
+        buf= mulMod2 (buf, iter.getItem(), yToL);
+      }
+    }
+    buf= mulMod2 (buf, LC (F,x), yToL);
+    buf /= content (buf, x);
+    if (fdivides (buf, F, quot))
+    {
+      F= quot;
+      F /= Lc (F);
+      result.append (buf (y-eval,y));
+      bufFactors= Difference (bufFactors, factorsConsidered);
+    }
+    if (degree (F) <= 0)
+    {
+      G= F;
+      factors= bufFactors;
+      return result;
+    }
+  }
+  G= F;
+  factors= bufFactors;
+  return result;
+}
+#endif
+
+#ifdef HAVE_FLINT
+CFList
+reconstruction (CanonicalForm& G, CFList& factors, int* zeroOneVecs,
+                int precision, const nmod_mat_t N, const CanonicalForm& eval)
+{
+  Variable y= Variable (2);
+  Variable x= Variable (1);
+  CanonicalForm F= G;
+  CanonicalForm yToL= power (y, precision);
+  CanonicalForm quot, buf;
+  CFList result;
+  CFList bufFactors= factors;
+  CFList factorsConsidered;
+  CFListIterator iter;
+  for (long i= 0; i < nmod_mat_ncols (N); i++)
+  {
+    if (zeroOneVecs [i] == 0)
+      continue;
+    iter= factors;
+    buf= 1;
+    factorsConsidered= CFList();
+    for (long j= 0; j < nmod_mat_nrows (N); j++, iter++)
+    {
+      if (!(nmod_mat_entry (N, j, i) == 0))
+      {
+        factorsConsidered.append (iter.getItem());
+        buf= mulMod2 (buf, iter.getItem(), yToL);
+      }
+    }
+    buf= mulMod2 (buf, LC (F,x), yToL);
+    buf /= content (buf, x);
+    if (fdivides (buf, F, quot))
+    {
+      F= quot;
+      F /= Lc (F);
+      result.append (buf (y-eval,y));
+      bufFactors= Difference (bufFactors, factorsConsidered);
+    }
+    if (degree (F) <= 0)
+    {
+      G= F;
+      factors= bufFactors;
+      return result;
+    }
+  }
+  G= F;
+  factors= bufFactors;
+  return result;
+}
+#endif
+
+#ifndef HAVE_FLINT
+void
+extReconstructionTry (CFList& reconstructedFactors, CanonicalForm& F, const
+                      CFList& factors, const int liftBound, int& factorsFound,
+                      int*& factorsFoundIndex, mat_zz_p& N, bool beenInThres,
+                      const ExtensionInfo& info, const CanonicalForm& evaluation
+                     )
+{
+  Variable y= Variable (2);
+  Variable x= Variable (1);
+  Variable alpha= info.getAlpha();
+  Variable beta= info.getBeta();
+  int k= info.getGFDegree();
+  CanonicalForm gamma= info.getGamma();
+  CanonicalForm delta= info.getDelta();
+  CanonicalForm yToL= power (y, liftBound);
+  CFList source, dest;
+  if (factors.length() == 2)
+  {
+    CanonicalForm tmp1, tmp2, tmp3;
+    tmp1= factors.getFirst();
+    tmp2= factors.getLast();
+    tmp1= mulMod2 (tmp1, LC (F,x), yToL);
+    tmp1 /= content (tmp1, x);
+    tmp2= mulMod2 (tmp2, LC (F,x), yToL);
+    tmp2 /= content (tmp2, x);
+    tmp3 = tmp1*tmp2;
+    if (tmp3/Lc (tmp3) == F/Lc (F))
+    {
+      tmp1= tmp1 (y - evaluation, y);
+      tmp2= tmp2 (y - evaluation, y);
+      tmp1 /= Lc (tmp1);
+      tmp2 /= Lc (tmp2);
+      if (!k && beta == x && degree (tmp2, alpha) < 1 &&
+          degree (tmp1, alpha) < 1)
+      {
+        factorsFound++;
+        F= 1;
+        tmp1= mapDown (tmp1, info, source, dest);
+        tmp2= mapDown (tmp2, info, source, dest);
+        reconstructedFactors.append (tmp1);
+        reconstructedFactors.append (tmp2);
+        return;
+      }
+      else if (!isInExtension (tmp2, gamma, k, delta, source, dest) &&
+               !isInExtension (tmp1, gamma, k, delta, source, dest))
+      {
+        factorsFound++;
+        F= 1;
+        tmp1= mapDown (tmp1, info, source, dest);
+        tmp2= mapDown (tmp2, info, source, dest);
+        reconstructedFactors.append (tmp1);
+        reconstructedFactors.append (tmp2);
+        return;
+      }
+    }
+  }
+  CanonicalForm quot, buf, buf2;
+  CFListIterator iter;
+  for (long i= 1; i <= N.NumCols(); i++)
+  {
+    if (factorsFoundIndex [i - 1] == 1)
+      continue;
+    iter= factors;
+    if (beenInThres)
+    {
+      int count= 1;
+      while (count < i)
+      {
+        count++;
+        iter++;
+      }
+      buf= iter.getItem();
+    }
+    else
+    {
+      buf= 1;
+      for (long j= 1; j <= N.NumRows(); j++, iter++)
+      {
+        if (!IsZero (N (j,i)))
+          buf= mulMod2 (buf, iter.getItem(), yToL);
+      }
+    }
+    buf= mulMod2 (buf, LC (F,x), yToL);
+    buf /= content (buf, x);
+    buf2= buf (y - evaluation, y);
+    buf2 /= Lc (buf2);
+    if (!k && beta == x)
+    {
+      if (degree (buf2, alpha) < 1)
+      {
+        if (fdivides (buf, F, quot))
+        {
+          factorsFoundIndex[i - 1]= 1;
+          factorsFound++;
+          F= quot;
+          F /= Lc (F);
+          buf2= mapDown (buf2, info, source, dest);
+          reconstructedFactors.append (buf2);
+        }
+      }
+    }
+    else
+    {
+      if (!isInExtension (buf2, gamma, k, delta, source, dest))
+      {
+        if (fdivides (buf, F, quot))
+        {
+          factorsFoundIndex[i - 1]= 1;
+          factorsFound++;
+          F= quot;
+          F /= Lc (F);
+          buf2= mapDown (buf2, info, source, dest);
+          reconstructedFactors.append (buf2);
+        }
+      }
+    }
+    if (degree (F) <= 0)
+      return;
+    if (factorsFound + 1 == N.NumCols())
+    {
+      CanonicalForm tmp= F (y - evaluation, y);
+      tmp= mapDown (tmp, info, source, dest);
+      reconstructedFactors.append (tmp);
+      return;
+    }
+  }
+}
+#endif
+
+#ifdef HAVE_FLINT
+void
+extReconstructionTry (CFList& reconstructedFactors, CanonicalForm& F, const
+                      CFList& factors, const int liftBound, int& factorsFound,
+                      int*& factorsFoundIndex, nmod_mat_t N, bool beenInThres,
+                      const ExtensionInfo& info, const CanonicalForm& evaluation
+                     )
+{
+  Variable y= Variable (2);
+  Variable x= Variable (1);
+  Variable alpha= info.getAlpha();
+  Variable beta= info.getBeta();
+  int k= info.getGFDegree();
+  CanonicalForm gamma= info.getGamma();
+  CanonicalForm delta= info.getDelta();
+  CanonicalForm yToL= power (y, liftBound);
+  CFList source, dest;
+  if (factors.length() == 2)
+  {
+    CanonicalForm tmp1, tmp2, tmp3;
+    tmp1= factors.getFirst();
+    tmp2= factors.getLast();
+    tmp1= mulMod2 (tmp1, LC (F,x), yToL);
+    tmp1 /= content (tmp1, x);
+    tmp2= mulMod2 (tmp2, LC (F,x), yToL);
+    tmp2 /= content (tmp2, x);
+    tmp3 = tmp1*tmp2;
+    if (tmp3/Lc (tmp3) == F/Lc (F))
+    {
+      tmp1= tmp1 (y - evaluation, y);
+      tmp2= tmp2 (y - evaluation, y);
+      tmp1 /= Lc (tmp1);
+      tmp2 /= Lc (tmp2);
+      if (!k && beta == x && degree (tmp2, alpha) < 1 &&
+          degree (tmp1, alpha) < 1)
+      {
+        factorsFound++;
+        F= 1;
+        tmp1= mapDown (tmp1, info, source, dest);
+        tmp2= mapDown (tmp2, info, source, dest);
+        reconstructedFactors.append (tmp1);
+        reconstructedFactors.append (tmp2);
+        return;
+      }
+      else if (!isInExtension (tmp2, gamma, k, delta, source, dest) &&
+               !isInExtension (tmp1, gamma, k, delta, source, dest))
+      {
+        factorsFound++;
+        F= 1;
+        tmp1= mapDown (tmp1, info, source, dest);
+        tmp2= mapDown (tmp2, info, source, dest);
+        reconstructedFactors.append (tmp1);
+        reconstructedFactors.append (tmp2);
+        return;
+      }
+    }
+  }
+  CanonicalForm quot, buf, buf2;
+  CFListIterator iter;
+  for (long i= 0; i < nmod_mat_ncols (N); i++)
+  {
+    if (factorsFoundIndex [i] == 1)
+      continue;
+    iter= factors;
+    if (beenInThres)
+    {
+      int count= 0;
+      while (count < i)
+      {
+        count++;
+        iter++;
+      }
+      buf= iter.getItem();
+    }
+    else
+    {
+      buf= 1;
+      for (long j= 0; j < nmod_mat_nrows (N); j++, iter++)
+      {
+        if (!(nmod_mat_entry (N, j, i) == 0))
+          buf= mulMod2 (buf, iter.getItem(), yToL);
+      }
+    }
+    buf= mulMod2 (buf, LC (F,x), yToL);
+    buf /= content (buf, x);
+    buf2= buf (y - evaluation, y);
+    buf2 /= Lc (buf2);
+    if (!k && beta == x)
+    {
+      if (degree (buf2, alpha) < 1)
+      {
+        if (fdivides (buf, F, quot))
+        {
+          factorsFoundIndex[i]= 1;
+          factorsFound++;
+          F= quot;
+          F /= Lc (F);
+          buf2= mapDown (buf2, info, source, dest);
+          reconstructedFactors.append (buf2);
+        }
+      }
+    }
+    else
+    {
+      if (!isInExtension (buf2, gamma, k, delta, source, dest))
+      {
+        if (fdivides (buf, F, quot))
+        {
+          factorsFoundIndex[i]= 1;
+          factorsFound++;
+          F= quot;
+          F /= Lc (F);
+          buf2= mapDown (buf2, info, source, dest);
+          reconstructedFactors.append (buf2);
+        }
+      }
+    }
+    if (degree (F) <= 0)
+      return;
+    if (factorsFound + 1 == nmod_mat_nrows (N))
+    {
+      CanonicalForm tmp= F (y - evaluation, y);
+      tmp= mapDown (tmp, info, source, dest);
+      reconstructedFactors.append (tmp);
+      return;
+    }
+  }
+}
+#endif
+
+#ifndef HAVE_FLINT
+//over Fp
+int
+liftAndComputeLattice (const CanonicalForm& F, int* bounds, int sizeBounds, int
+                       start, int liftBound, int minBound, CFList& factors,
+                       mat_zz_p& NTLN, CFList& diophant, CFMatrix& M, CFArray&
+                       Pi, CFArray& bufQ, bool& irreducible
+                      )
+{
+  CanonicalForm LCF= LC (F, 1);
+  CFArray *A= new CFArray [factors.length() - 1];
+  bool wasInBounds= false;
+  bool hitBound= false;
+  int l= (minBound+1)*2;
+  int stepSize= 2;
+  int oldL= l/2;
+  bool reduced= false;
+  mat_zz_p NTLK, *NTLC;
+  CFMatrix C;
+  CFArray buf;
+  CFListIterator j;
+  CanonicalForm truncF;
+  Variable y= F.mvar();
+  while (l <= liftBound)
+  {
+    TIMING_START (fac_fq_compute_lattice_lift);
+    if (start)
+    {
+      henselLiftResume12 (F, factors, start, l, Pi, diophant, M);
+      start= 0;
+    }
+    else
+    {
+      if (wasInBounds)
+        henselLiftResume12 (F, factors, oldL, l, Pi, diophant, M);
+      else
+        henselLift12 (F, factors, l, Pi, diophant, M);
+    }
+    TIMING_END_AND_PRINT (fac_fq_compute_lattice_lift,
+                          "time to lift in compute lattice: ");
+
+    factors.insert (LCF);
+    j= factors;
+    j++;
+
+    truncF= mod (F, power (y, l));
+    TIMING_START (fac_fq_logarithmic);
+    for (int i= 0; i < factors.length() - 1; i++, j++)
+    {
+      if (!wasInBounds)
+        A[i]= logarithmicDerivative (truncF, j.getItem(), l, bufQ[i]);
+      else
+        A[i]= logarithmicDerivative (truncF, j.getItem(), l, oldL, bufQ[i],
+                                     bufQ[i]);
+    }
+    TIMING_END_AND_PRINT (fac_fq_logarithmic,
+                          "time to compute logarithmic derivative: ");
+
+    for (int i= 0; i < sizeBounds; i++)
+    {
+      if (bounds [i] + 1 <= l/2)
+      {
+        wasInBounds= true;
+        int k= tmin (bounds [i] + 1, l/2);
+        C= CFMatrix (l - k, factors.length() - 1);
+        for (int ii= 0; ii < factors.length() - 1; ii++)
+        {
+          if (A[ii].size() - 1 >= i)
+          {
+            buf= getCoeffs (A[ii] [i], k);
+            writeInMatrix (C, buf, ii + 1, 0);
+          }
+        }
+        NTLC= convertFacCFMatrix2NTLmat_zz_p(C);
+        NTLK= (*NTLC)*NTLN;
+        transpose (NTLK, NTLK);
+        kernel (NTLK, NTLK);
+        transpose (NTLK, NTLK);
+        NTLN *= NTLK;
+        delete NTLC;
+
+        if (NTLN.NumCols() == 1)
+        {
+          irreducible= true;
+          break;
+        }
+        if (isReduced (NTLN) && l > (minBound+1)*2)
+        {
+          reduced= true;
+          break;
+        }
+      }
+    }
+
+    if (irreducible)
+      break;
+    if (reduced)
+      break;
+    oldL= l;
+    l += stepSize;
+    stepSize *= 2;
+    if (l > liftBound)
+    {
+      if (!hitBound)
+      {
+        l= liftBound;
+        hitBound= true;
+      }
+      else
+        break;
+    }
+  }
+  delete [] A;
+  if (!wasInBounds)
+  {
+    if (start)
+      henselLiftResume12 (F, factors, start, degree (F) + 1, Pi, diophant, M);
+    else
+      henselLift12 (F, factors, degree (F) + 1, Pi, diophant, M);
+    factors.insert (LCF);
+  }
+  return l;
+}
+#endif
+
+#ifdef HAVE_FLINT
+int
+liftAndComputeLattice (const CanonicalForm& F, int* bounds, int sizeBounds, int
+                       start, int liftBound, int minBound, CFList& factors,
+                       nmod_mat_t FLINTN, CFList& diophant, CFMatrix& M,CFArray&
+                       Pi, CFArray& bufQ, bool& irreducible
+                      )
+{
+  CanonicalForm LCF= LC (F, 1);
+  CFArray *A= new CFArray [factors.length() - 1];
+  bool wasInBounds= false;
+  bool hitBound= false;
+  int l= (minBound+1)*2;
+  int stepSize= 2;
+  int oldL= l/2;
+  bool reduced= false;
+  long rank;
+  nmod_mat_t FLINTK, FLINTC, null;
+  CFMatrix C;
+  CFArray buf;
+  CFListIterator j;
+  CanonicalForm truncF;
+  Variable y= F.mvar();
+  while (l <= liftBound)
+  {
+    TIMING_START (fac_fq_compute_lattice_lift);
+    if (start)
+    {
+      henselLiftResume12 (F, factors, start, l, Pi, diophant, M);
+      start= 0;
+    }
+    else
+    {
+      if (wasInBounds)
+        henselLiftResume12 (F, factors, oldL, l, Pi, diophant, M);
+      else
+        henselLift12 (F, factors, l, Pi, diophant, M);
+    }
+    TIMING_END_AND_PRINT (fac_fq_compute_lattice_lift,
+                          "time to lift in compute lattice: ");
+
+    factors.insert (LCF);
+    j= factors;
+    j++;
+
+    truncF= mod (F, power (y, l));
+    TIMING_START (fac_fq_logarithmic);
+    for (int i= 0; i < factors.length() - 1; i++, j++)
+    {
+      if (!wasInBounds)
+        A[i]= logarithmicDerivative (truncF, j.getItem(), l, bufQ[i]);
+      else
+        A[i]= logarithmicDerivative (truncF, j.getItem(), l, oldL, bufQ[i],
+                                     bufQ[i]);
+    }
+    TIMING_END_AND_PRINT (fac_fq_logarithmic,
+                          "time to compute logarithmic derivative: ");
+
+    for (int i= 0; i < sizeBounds; i++)
+    {
+      if (bounds [i] + 1 <= l/2)
+      {
+        wasInBounds= true;
+        int k= tmin (bounds [i] + 1, l/2);
+        C= CFMatrix (l - k, factors.length() - 1);
+        for (int ii= 0; ii < factors.length() - 1; ii++)
+        {
+          if (A[ii].size() - 1 >= i)
+          {
+            buf= getCoeffs (A[ii] [i], k);
+            writeInMatrix (C, buf, ii + 1, 0);
+          }
+        }
+
+        convertFacCFMatrix2nmod_mat_t (FLINTC, C);
+        nmod_mat_init (FLINTK, nmod_mat_nrows (FLINTC), nmod_mat_ncols (FLINTN),
+                       getCharacteristic());
+        nmod_mat_mul (FLINTK, FLINTC, FLINTN);
+        nmod_mat_init (null, nmod_mat_ncols (FLINTK), nmod_mat_ncols (FLINTK),
+                       getCharacteristic());
+        rank= nmod_mat_nullspace (null, FLINTK);
+        nmod_mat_clear (FLINTK);
+        nmod_mat_window_init (FLINTK, null, 0, 0, nmod_mat_nrows(null), rank);
+        nmod_mat_clear (FLINTC);
+        nmod_mat_init_set (FLINTC, FLINTN);
+        nmod_mat_clear (FLINTN);
+        nmod_mat_init (FLINTN, nmod_mat_nrows (FLINTC), nmod_mat_ncols (FLINTK),
+                       getCharacteristic());
+        nmod_mat_mul (FLINTN, FLINTC, FLINTK); //no aliasing allowed!!
+
+        nmod_mat_clear (FLINTC);
+        nmod_mat_window_clear (FLINTK);
+        nmod_mat_clear (null);
+        if (nmod_mat_ncols (FLINTN) == 1)
+        {
+          irreducible= true;
+          break;
+        }
+        if (isReduced (FLINTN) && l > (minBound+1)*2)
+        {
+          reduced= true;
+          break;
+        }
+      }
+    }
+
+    if (irreducible)
+      break;
+    if (reduced)
+      break;
+    oldL= l;
+    l += stepSize;
+    stepSize *= 2;
+    if (l > liftBound)
+    {
+      if (!hitBound)
+      {
+        l= liftBound;
+        hitBound= true;
+      }
+      else
+        break;
+    }
+  }
+  delete [] A;
+  if (!wasInBounds)
+  {
+    if (start)
+      henselLiftResume12 (F, factors, start, degree (F) + 1, Pi, diophant, M);
+    else
+      henselLift12 (F, factors, degree (F) + 1, Pi, diophant, M);
+    factors.insert (LCF);
+  }
+  return l;
+}
+#endif
+
+#ifndef HAVE_FLINT
+//over field extension
+int
+extLiftAndComputeLattice (const CanonicalForm& F, int* bounds, int sizeBounds,
+                          int liftBound, int minBound, int start, CFList&
+                          factors, mat_zz_p& NTLN, CFList& diophant,
+                          CFMatrix& M, CFArray& Pi, CFArray& bufQ, bool&
+                          irreducible, const CanonicalForm& evaluation, const
+                          ExtensionInfo& info, CFList& source, CFList& dest
+                         )
+{
+  bool GF= (CFFactory::gettype()==GaloisFieldDomain);
+  CanonicalForm LCF= LC (F, 1);
+  CFArray *A= new CFArray [factors.length() - 1];
+  bool wasInBounds= false;
+  bool hitBound= false;
+  int degMipo;
+  Variable alpha;
+  alpha= info.getAlpha();
+  degMipo= degree (getMipo (alpha));
+
+  Variable gamma= info.getBeta();
+  CanonicalForm primElemAlpha= info.getGamma();
+  CanonicalForm imPrimElemAlpha= info.getDelta();
+
+  int stepSize= 2;
+  int l= ((minBound+1)/degMipo+1)*2;
+  l= tmax (l, 2);
+  if (start > l)
+    l= start;
+  int oldL= l/2;
+  bool reduced= false;
+  Variable y= F.mvar();
+  Variable x= Variable (1);
+  CanonicalForm powX, imBasis, truncF;
+  CFMatrix Mat, C;
+  CFArray buf;
+  CFIterator iter;
+  mat_zz_p* NTLMat, *NTLC, NTLK;
+  CFListIterator j;
+  while (l <= liftBound)
+  {
+    TIMING_START (fac_fq_compute_lattice_lift);
+    if (start)
+    {
+      henselLiftResume12 (F, factors, start, l, Pi, diophant, M);
+      start= 0;
+    }
+    else
+    {
+      if (wasInBounds)
+        henselLiftResume12 (F, factors, oldL, l, Pi, diophant, M);
+      else
+        henselLift12 (F, factors, l, Pi, diophant, M);
+    }
+    TIMING_END_AND_PRINT (fac_fq_compute_lattice_lift,
+                          "time to lift in compute lattice: ");
+
+    factors.insert (LCF);
+
+    if (GF)
+      setCharacteristic (getCharacteristic());
+
+    powX= power (y-gamma, l);
+    Mat= CFMatrix (l*degMipo, l*degMipo);
+    for (int i= 0; i < l*degMipo; i++)
+    {
+      imBasis= mod (power (y, i), powX);
+      imBasis= imBasis (power (y, degMipo), y);
+      imBasis= imBasis (y, gamma);
+      iter= imBasis;
+      for (; iter.hasTerms(); iter++)
+        Mat (iter.exp()+ 1, i+1)= iter.coeff();
+    }
+
+    NTLMat= convertFacCFMatrix2NTLmat_zz_p (Mat);
+    *NTLMat= inv (*NTLMat);
+
+    if (GF)
+      setCharacteristic (getCharacteristic(), degMipo, info.getGFName());
+
+    j= factors;
+    j++;
+
+    truncF= mod (F, power (y, l));
+    TIMING_START (fac_fq_logarithmic);
+    for (int i= 0; i < factors.length() - 1; i++, j++)
+    {
+      if (!wasInBounds)
+        A[i]= logarithmicDerivative (truncF, j.getItem(), l, bufQ[i]);
+      else
+        A[i]= logarithmicDerivative (truncF, j.getItem(), l, oldL, bufQ[i],
+                                     bufQ[i]);
+    }
+    TIMING_END_AND_PRINT (fac_fq_logarithmic,
+                          "time to compute logarithmic derivative: ");
+
+    for (int i= 0; i < sizeBounds; i++)
+    {
+      if (bounds [i] + 1 <= (l/2)*degMipo)
+      {
+        wasInBounds= true;
+        int k= tmin (bounds [i] + 1, (l/2)*degMipo);
+        C= CFMatrix (l*degMipo - k, factors.length() - 1);
+
+        for (int ii= 0; ii < factors.length() - 1; ii++)
+        {
+          if (A[ii].size() - 1 >= i)
+          {
+            if (GF)
+            {
+              A [ii] [i]= A [ii] [i] (y-evaluation, y);
+              setCharacteristic (getCharacteristic());
+              A[ii] [i]= GF2FalphaRep (A[ii] [i], alpha);
+              if (alpha != gamma)
+                A [ii] [i]= mapDown (A[ii] [i], imPrimElemAlpha, primElemAlpha,
+                                     gamma, source, dest
+                                    );
+              buf= getCoeffs (A[ii] [i], k, l, degMipo, gamma, 0, *NTLMat);
+            }
+            else
+            {
+              A [ii] [i]= A [ii] [i] (y-evaluation, y);
+              if (alpha != gamma)
+                A[ii] [i]= mapDown (A[ii] [i], imPrimElemAlpha, primElemAlpha,
+                                    gamma, source, dest
+                                   );
+              buf= getCoeffs (A[ii] [i], k, l, degMipo, gamma, 0, *NTLMat);
+            }
+            writeInMatrix (C, buf, ii + 1, 0);
+          }
+          if (GF)
+            setCharacteristic (getCharacteristic(), degMipo, info.getGFName());
+        }
+
+        if (GF)
+          setCharacteristic(getCharacteristic());
+
+        NTLC= convertFacCFMatrix2NTLmat_zz_p(C);
+        NTLK= (*NTLC)*NTLN;
+        transpose (NTLK, NTLK);
+        kernel (NTLK, NTLK);
+        transpose (NTLK, NTLK);
+        NTLN *= NTLK;
+        delete NTLC;
+
+        if (GF)
+          setCharacteristic (getCharacteristic(), degMipo, info.getGFName());
+
+        if (NTLN.NumCols() == 1)
+        {
+          irreducible= true;
+          break;
+        }
+        if (isReduced (NTLN))
+        {
+          reduced= true;
+          break;
+        }
+      }
+    }
+
+    delete NTLMat;
+
+    if (NTLN.NumCols() == 1)
+    {
+      irreducible= true;
+      break;
+    }
+    if (reduced)
+      break;
+    oldL= l;
+    l += stepSize;
+    stepSize *= 2;
+    if (l > liftBound)
+    {
+      if (!hitBound)
+      {
+        l= liftBound;
+        hitBound= true;
+      }
+      else
+        break;
+    }
+  }
+  delete [] A;
+  if (!wasInBounds)
+  {
+    if (start)
+      henselLiftResume12 (F, factors, start, degree (F) + 1, Pi, diophant, M);
+    else
+      henselLift12 (F, factors, degree (F) + 1, Pi, diophant, M);
+    factors.insert (LCF);
+  }
+  return l;
+}
+#endif
+
+#ifdef HAVE_FLINT
+//over field extension
+int
+extLiftAndComputeLattice (const CanonicalForm& F, int* bounds, int sizeBounds,
+                          int liftBound, int minBound, int start, CFList&
+                          factors, nmod_mat_t FLINTN, CFList& diophant,
+                          CFMatrix& M, CFArray& Pi, CFArray& bufQ, bool&
+                          irreducible, const CanonicalForm& evaluation, const
+                          ExtensionInfo& info, CFList& source, CFList& dest
+                         )
+{
+  bool GF= (CFFactory::gettype()==GaloisFieldDomain);
+  CanonicalForm LCF= LC (F, 1);
+  CFArray *A= new CFArray [factors.length() - 1];
+  bool wasInBounds= false;
+  bool hitBound= false;
+  int degMipo;
+  Variable alpha;
+  alpha= info.getAlpha();
+  degMipo= degree (getMipo (alpha));
+
+  Variable gamma= info.getBeta();
+  CanonicalForm primElemAlpha= info.getGamma();
+  CanonicalForm imPrimElemAlpha= info.getDelta();
+
+  int stepSize= 2;
+  int l= ((minBound+1)/degMipo+1)*2;
+  l= tmax (l, 2);
+  if (start > l)
+    l= start;
+  int oldL= l/2;
+  bool reduced= false;
+  Variable y= F.mvar();
+  Variable x= Variable (1);
+  CanonicalForm powX, imBasis, truncF;
+  CFMatrix Mat, C;
+  CFArray buf;
+  CFIterator iter;
+  long rank;
+  nmod_mat_t FLINTMat, FLINTMatInv, FLINTC, FLINTK, null;
+  CFListIterator j;
+  while (l <= liftBound)
+  {
+    if (start)
+    {
+      henselLiftResume12 (F, factors, start, l, Pi, diophant, M);
+      start= 0;
+    }
+    else
+    {
+      if (wasInBounds)
+        henselLiftResume12 (F, factors, oldL, l, Pi, diophant, M);
+      else
+        henselLift12 (F, factors, l, Pi, diophant, M);
+    }
+
+    factors.insert (LCF);
+
+    if (GF)
+      setCharacteristic (getCharacteristic());
+
+    powX= power (y-gamma, l);
+    Mat= CFMatrix (l*degMipo, l*degMipo);
+    for (int i= 0; i < l*degMipo; i++)
+    {
+      imBasis= mod (power (y, i), powX);
+      imBasis= imBasis (power (y, degMipo), y);
+      imBasis= imBasis (y, gamma);
+      iter= imBasis;
+      for (; iter.hasTerms(); iter++)
+        Mat (iter.exp()+ 1, i+1)= iter.coeff();
+    }
+
+    convertFacCFMatrix2nmod_mat_t (FLINTMat, Mat);
+    nmod_mat_init (FLINTMatInv, nmod_mat_nrows (FLINTMat),
+                   nmod_mat_nrows (FLINTMat), getCharacteristic());
+    nmod_mat_inv (FLINTMatInv, FLINTMat);
+
+    if (GF)
+      setCharacteristic (getCharacteristic(), degMipo, info.getGFName());
+
+    j= factors;
+    j++;
+
+    truncF= mod (F, power (y, l));
+    for (int i= 0; i < factors.length() - 1; i++, j++)
+    {
+      if (!wasInBounds)
+        A[i]= logarithmicDerivative (truncF, j.getItem(), l, bufQ[i]);
+      else
+        A[i]= logarithmicDerivative (truncF, j.getItem(), l, oldL, bufQ[i],
+                                     bufQ[i]);
+    }
+
+    for (int i= 0; i < sizeBounds; i++)
+    {
+      if (bounds [i] + 1 <= (l/2)*degMipo)
+      {
+        wasInBounds= true;
+        int k= tmin (bounds [i] + 1, (l/2)*degMipo);
+        C= CFMatrix (l*degMipo - k, factors.length() - 1);
+
+        for (int ii= 0; ii < factors.length() - 1; ii++)
+        {
+          if (A[ii].size() - 1 >= i)
+          {
+            if (GF)
+            {
+              A [ii] [i]= A [ii] [i] (y-evaluation, y);
+              setCharacteristic (getCharacteristic());
+              A[ii] [i]= GF2FalphaRep (A[ii] [i], alpha);
+              if (alpha != gamma)
+                A [ii] [i]= mapDown (A[ii] [i], imPrimElemAlpha, primElemAlpha,
+                                     gamma, source, dest
+                                    );
+              buf= getCoeffs (A[ii] [i], k, l, degMipo, gamma, 0, FLINTMatInv);
+            }
+            else
+            {
+              A [ii] [i]= A [ii] [i] (y-evaluation, y);
+              if (alpha != gamma)
+                A[ii] [i]= mapDown (A[ii] [i], imPrimElemAlpha, primElemAlpha,
+                                    gamma, source, dest
+                                   );
+              buf= getCoeffs (A[ii] [i], k, l, degMipo, gamma, 0, FLINTMatInv);
+            }
+            writeInMatrix (C, buf, ii + 1, 0);
+          }
+          if (GF)
+            setCharacteristic (getCharacteristic(), degMipo, info.getGFName());
+        }
+
+        if (GF)
+          setCharacteristic(getCharacteristic());
+
+        convertFacCFMatrix2nmod_mat_t (FLINTC, C);
+        nmod_mat_init (FLINTK, nmod_mat_nrows (FLINTC), nmod_mat_ncols (FLINTN),
+                       getCharacteristic());
+        nmod_mat_mul (FLINTK, FLINTC, FLINTN);
+        nmod_mat_init (null, nmod_mat_ncols (FLINTK), nmod_mat_ncols (FLINTK),
+                       getCharacteristic());
+        rank= nmod_mat_nullspace (null, FLINTK);
+        nmod_mat_clear (FLINTK);
+        nmod_mat_window_init (FLINTK, null, 0, 0, nmod_mat_nrows(null), rank);
+        nmod_mat_clear (FLINTC);
+        nmod_mat_init_set (FLINTC, FLINTN);
+        nmod_mat_clear (FLINTN);
+        nmod_mat_init (FLINTN, nmod_mat_nrows (FLINTC), nmod_mat_ncols (FLINTK),
+                       getCharacteristic());
+        nmod_mat_mul (FLINTN, FLINTC, FLINTK); //no aliasing allowed!!
+
+        nmod_mat_clear (FLINTC);
+        nmod_mat_window_clear (FLINTK);
+        nmod_mat_clear (null);
+
+        if (GF)
+          setCharacteristic (getCharacteristic(), degMipo, info.getGFName());
+
+        if (nmod_mat_ncols (FLINTN) == 1)
+        {
+          irreducible= true;
+          break;
+        }
+        if (isReduced (FLINTN))
+        {
+          reduced= true;
+          break;
+        }
+      }
+    }
+
+    nmod_mat_clear (FLINTMat);
+    nmod_mat_clear (FLINTMatInv);
+
+    if (nmod_mat_ncols (FLINTN) == 1)
+    {
+      irreducible= true;
+      break;
+    }
+    if (reduced)
+      break;
+    oldL= l;
+    l += stepSize;
+    stepSize *= 2;
+    if (l > liftBound)
+    {
+      if (!hitBound)
+      {
+        l= liftBound;
+        hitBound= true;
+      }
+      else
+        break;
+    }
+  }
+  delete [] A;
+  if (!wasInBounds)
+  {
+    if (start)
+      henselLiftResume12 (F, factors, start, degree (F) + 1, Pi, diophant, M);
+    else
+      henselLift12 (F, factors, degree (F) + 1, Pi, diophant, M);
+    factors.insert (LCF);
+  }
+  return l;
+}
+#endif
+
+// over Fq
+int
+liftAndComputeLattice (const CanonicalForm& F, int* bounds, int sizeBounds,
+                       int start, int liftBound, int minBound, CFList& factors,
+                       mat_zz_pE& NTLN, CFList& diophant, CFMatrix& M, CFArray&
+                       Pi, CFArray& bufQ, bool& irreducible
+                      )
+{
+  CanonicalForm LCF= LC (F, 1);
+  CFArray *A= new CFArray [factors.length() - 1];
+  bool wasInBounds= false;
+  bool hitBound= false;
+  int l= (minBound+1)*2;
+  int stepSize= 2;
+  int oldL= l/2;
+  bool reduced= false;
+  CFListIterator j;
+  mat_zz_pE* NTLC, NTLK;
+  CFArray buf;
+  CFMatrix C;
+  Variable y= F.mvar();
+  CanonicalForm truncF;
+  while (l <= liftBound)
+  {
+    TIMING_START (fac_fq_compute_lattice_lift);
+    if (start)
+    {
+      henselLiftResume12 (F, factors, start, l, Pi, diophant, M);
+      start= 0;
+    }
+    else
+    {
+      if (wasInBounds)
+        henselLiftResume12 (F, factors, oldL, l, Pi, diophant, M);
+      else
+        henselLift12 (F, factors, l, Pi, diophant, M);
+    }
+    TIMING_END_AND_PRINT (fac_fq_compute_lattice_lift,
+                          "time to lift in compute lattice: ");
+
+    factors.insert (LCF);
+    j= factors;
+    j++;
+
+    truncF= mod (F, power (y,l));
+    TIMING_START (fac_fq_logarithmic);
+    for (int i= 0; i < factors.length() - 1; i++, j++)
+    {
+      if (l == (minBound+1)*2)
+      {
+        A[i]= logarithmicDerivative (truncF, j.getItem(), l, bufQ[i]);
+      }
+      else
+      {
+        A[i]= logarithmicDerivative (truncF, j.getItem(), l, oldL, bufQ[i],
+                                     bufQ[i]
+                                    );
+      }
+    }
+    TIMING_END_AND_PRINT (fac_fq_logarithmic,
+                          "time to compute logarithmic derivative: ");
+
+    for (int i= 0; i < sizeBounds; i++)
+    {
+      if (bounds [i] + 1 <= l/2)
+      {
+        wasInBounds= true;
+        int k= tmin (bounds [i] + 1, l/2);
+        C= CFMatrix (l - k, factors.length() - 1);
+        for (int ii= 0; ii < factors.length() - 1; ii++)
+        {
+
+          if (A[ii].size() - 1 >= i)
+          {
+            buf= getCoeffs (A[ii] [i], k);
+            writeInMatrix (C, buf, ii + 1, 0);
+          }
+        }
+
+        NTLC= convertFacCFMatrix2NTLmat_zz_pE(C);
+        NTLK= (*NTLC)*NTLN;
+        transpose (NTLK, NTLK);
+        kernel (NTLK, NTLK);
+        transpose (NTLK, NTLK);
+        NTLN *= NTLK;
+        delete NTLC;
+
+        if (NTLN.NumCols() == 1)
+        {
+          irreducible= true;
+          break;
+        }
+        if (isReduced (NTLN) && l > (minBound+1)*2)
+        {
+          reduced= true;
+          break;
+        }
+      }
+    }
+
+    if (NTLN.NumCols() == 1)
+    {
+      irreducible= true;
+      break;
+    }
+    if (reduced)
+      break;
+    oldL= l;
+    l += stepSize;
+    stepSize *= 2;
+    if (l > liftBound)
+    {
+      if (!hitBound)
+      {
+        l= liftBound;
+        hitBound= true;
+      }
+      else
+        break;
+    }
+  }
+  delete [] A;
+  if (!wasInBounds)
+  {
+    if (start)
+      henselLiftResume12 (F, factors, start, degree (F) + 1, Pi, diophant, M);
+    else
+      henselLift12 (F, factors, degree (F) + 1, Pi, diophant, M);
+    factors.insert (LCF);
+  }
+  return l;
+}
+
+#ifdef HAVE_FLINT
+int
+liftAndComputeLatticeFq2Fp (const CanonicalForm& F, int* bounds, int sizeBounds,
+                            int start, int liftBound, int minBound, CFList&
+                            factors, nmod_mat_t FLINTN, CFList& diophant,
+                            CFMatrix& M, CFArray& Pi, CFArray& bufQ, bool&
+                            irreducible, const Variable& alpha
+                           )
+#else
+int
+liftAndComputeLatticeFq2Fp (const CanonicalForm& F, int* bounds, int sizeBounds,
+                            int start, int liftBound, int minBound, CFList&
+                            factors, mat_zz_p& NTLN, CFList& diophant, CFMatrix&
+                            M, CFArray& Pi, CFArray& bufQ, bool& irreducible,
+                            const Variable& alpha
+                           )
+#endif
+{
+  CanonicalForm LCF= LC (F, 1);
+  CFArray *A= new CFArray [factors.length() - 1];
+  bool wasInBounds= false;
+  int l= (minBound+1)*2;
+  int oldL= l/2;
+  int stepSize= 2;
+  bool hitBound= false;
+  int extensionDeg= degree (getMipo (alpha));
+  bool reduced= false;
+  CFListIterator j;
+  CFMatrix C;
+  CFArray buf;
+#ifdef HAVE_FLINT
+  long rank;
+  nmod_mat_t FLINTC, FLINTK, null;
+#else
+  mat_zz_p* NTLC, NTLK;
+#endif
+  Variable y= F.mvar();
+  CanonicalForm truncF;
+  while (l <= liftBound)
+  {
+    TIMING_START (fac_fq_compute_lattice_lift);
+    if (start)
+    {
+      henselLiftResume12 (F, factors, start, l, Pi, diophant, M);
+      start= 0;
+    }
+    else
+    {
+      if (wasInBounds)
+        henselLiftResume12 (F, factors, oldL, l, Pi, diophant, M);
+      else
+        henselLift12 (F, factors, l, Pi, diophant, M);
+    }
+    TIMING_END_AND_PRINT (fac_fq_compute_lattice_lift,
+                          "time to lift in compute lattice: ");
+
+    factors.insert (LCF);
+    j= factors;
+    j++;
+
+    truncF= mod (F, power (y,l));
+    TIMING_START (fac_fq_logarithmic);
+    for (int i= 0; i < factors.length() - 1; i++, j++)
+    {
+      if (l == (minBound+1)*2)
+      {
+        A[i]= logarithmicDerivative (truncF, j.getItem(), l, bufQ[i]);
+      }
+      else
+      {
+        A[i]= logarithmicDerivative (truncF, j.getItem(), l, oldL, bufQ[i],
+                                     bufQ[i]
+                                    );
+      }
+    }
+    TIMING_END_AND_PRINT (fac_fq_logarithmic,
+                          "time to compute logarithmic derivative: ");
+
+    for (int i= 0; i < sizeBounds; i++)
+    {
+      if (bounds [i] + 1 <= l/2)
+      {
+        wasInBounds= true;
+        int k= tmin (bounds [i] + 1, l/2);
+        C= CFMatrix ((l - k)*extensionDeg, factors.length() - 1);
+        for (int ii= 0; ii < factors.length() - 1; ii++)
+        {
+          if (A[ii].size() - 1 >= i)
+          {
+            buf= getCoeffs (A[ii] [i], k, alpha);
+            writeInMatrix (C, buf, ii + 1, 0);
+          }
+        }
+
+#ifdef HAVE_FLINT
+        convertFacCFMatrix2nmod_mat_t (FLINTC, C);
+        nmod_mat_init (FLINTK, nmod_mat_nrows (FLINTC), nmod_mat_ncols (FLINTN),
+                       getCharacteristic());
+        nmod_mat_mul (FLINTK, FLINTC, FLINTN);
+        nmod_mat_init (null, nmod_mat_ncols (FLINTK), nmod_mat_ncols (FLINTK),
+                       getCharacteristic());
+        rank= nmod_mat_nullspace (null, FLINTK);
+        nmod_mat_clear (FLINTK);
+        nmod_mat_window_init (FLINTK, null, 0, 0, nmod_mat_nrows(null), rank);
+        nmod_mat_clear (FLINTC);
+        nmod_mat_init_set (FLINTC, FLINTN);
+        nmod_mat_clear (FLINTN);
+        nmod_mat_init (FLINTN, nmod_mat_nrows (FLINTC), nmod_mat_ncols (FLINTK),
+                       getCharacteristic());
+        nmod_mat_mul (FLINTN, FLINTC, FLINTK); //no aliasing allowed!!
+
+        nmod_mat_clear (FLINTC);
+        nmod_mat_window_clear (FLINTK);
+        nmod_mat_clear (null);
+#else
+        NTLC= convertFacCFMatrix2NTLmat_zz_p(C);
+        NTLK= (*NTLC)*NTLN;
+        transpose (NTLK, NTLK);
+        kernel (NTLK, NTLK);
+        transpose (NTLK, NTLK);
+        NTLN *= NTLK;
+        delete NTLC;
+#endif
+
+#ifdef HAVE_FLINT
+        if (nmod_mat_nrows (FLINTN) == 1)
+#else
+        if (NTLN.NumCols() == 1)
+#endif
+        {
+          irreducible= true;
+          break;
+        }
+#ifdef HAVE_FLINT
+        if (isReduced (FLINTN) && l > (minBound+1)*2)
+#else
+        if (isReduced (NTLN) && l > (minBound+1)*2)
+#endif
+        {
+          reduced= true;
+          break;
+        }
+      }
+    }
+
+#ifdef HAVE_FLINT
+    if (nmod_mat_ncols (FLINTN) == 1)
+#else
+    if (NTLN.NumCols() == 1)
+#endif
+    {
+      irreducible= true;
+      break;
+    }
+    if (reduced)
+      break;
+    oldL= l;
+    l += stepSize;
+    stepSize *= 2;
+    if (l > liftBound)
+    {
+      if (!hitBound)
+      {
+        l= liftBound;
+        hitBound= true;
+      }
+      else
+        break;
+    }
+  }
+  delete [] A;
+  if (!wasInBounds)
+  {
+    if (start)
+      henselLiftResume12 (F, factors, start, degree (F) + 1, Pi, diophant, M);
+    else
+      henselLift12 (F, factors, degree (F) + 1, Pi, diophant, M);
+    factors.insert (LCF);
+  }
+  return l;
+}
+
+CFList
+increasePrecision (CanonicalForm& F, CFList& factors, int factorsFound,
+                   int oldNumCols, int oldL, int precision,
+                   const CanonicalForm& eval
+                  )
+{
+  int d;
+  bool isIrreducible= false;
+  int* bounds= computeBounds (F, d, isIrreducible);
+  Variable y= F.mvar();
+  if (isIrreducible)
+  {
+    delete [] bounds;
+    CanonicalForm G= F;
+    F= 1;
+    return CFList (G (y-eval, y));
+  }
+  CFArray * A= new CFArray [factors.length()];
+  CFArray bufQ= CFArray (factors.length());
+#ifdef HAVE_FLINT
+  nmod_mat_t FLINTN;
+  nmod_mat_init (FLINTN,factors.length(),factors.length(), getCharacteristic());
+  for (long i=factors.length()-1; i >= 0; i--)
+    nmod_mat_entry (FLINTN, i, i)= 1;
+#else
+  mat_zz_p NTLN;
+  ident (NTLN, factors.length());
+#endif
+  int minBound= bounds[0];
+  for (int i= 1; i < d; i++)
+  {
+    if (bounds[i] != 0)
+      minBound= tmin (minBound, bounds[i]);
+  }
+  int l= tmax (2*(minBound + 1), oldL);
+  int oldL2= l/2;
+  int stepSize= 2;
+  bool useOldQs= false;
+  bool hitBound= false;
+  CFListIterator j;
+  CFMatrix C;
+  CFArray buf;
+#ifdef HAVE_FLINT
+  long rank;
+  nmod_mat_t FLINTC, FLINTK, null;
+#else
+  mat_zz_p* NTLC, NTLK;
+#endif
+  CanonicalForm truncF;
+  while (l <= precision)
+  {
+    j= factors;
+    truncF= mod (F, power (y,l));
+    if (useOldQs)
+    {
+      for (int i= 0; i < factors.length(); i++, j++)
+        A[i]= logarithmicDerivative (truncF, j.getItem(), l, oldL2, bufQ[i],
+                                     bufQ[i]
+                                    );
+    }
+    else
+    {
+      for (int i= 0; i < factors.length(); i++, j++)
+        A[i]= logarithmicDerivative (truncF, j.getItem(), l, bufQ [i]);
+    }
+    useOldQs= true;
+    for (int i= 0; i < d; i++)
+    {
+      if (bounds [i] + 1 <= l/2)
+      {
+        int k= tmin (bounds [i] + 1, l/2);
+        C= CFMatrix (l - k, factors.length());
+        for (int ii= 0; ii < factors.length(); ii++)
+        {
+          if (A[ii].size() - 1 >= i)
+          {
+            buf= getCoeffs (A[ii] [i], k);
+            writeInMatrix (C, buf, ii + 1, 0);
+          }
+        }
+#ifdef HAVE_FLINT
+        convertFacCFMatrix2nmod_mat_t (FLINTC, C);
+        nmod_mat_init (FLINTK, nmod_mat_nrows (FLINTC), nmod_mat_ncols (FLINTN),
+                       getCharacteristic());
+        nmod_mat_mul (FLINTK, FLINTC, FLINTN);
+        nmod_mat_init (null, nmod_mat_ncols (FLINTK), nmod_mat_ncols (FLINTK),
+                       getCharacteristic());
+        rank= nmod_mat_nullspace (null, FLINTK);
+        nmod_mat_clear (FLINTK);
+        nmod_mat_window_init (FLINTK, null, 0, 0, nmod_mat_nrows(null), rank);
+        nmod_mat_clear (FLINTC);
+        nmod_mat_init_set (FLINTC, FLINTN);
+        nmod_mat_clear (FLINTN);
+        nmod_mat_init (FLINTN, nmod_mat_nrows (FLINTC), nmod_mat_ncols (FLINTK),
+                       getCharacteristic());
+        nmod_mat_mul (FLINTN, FLINTC, FLINTK); //no aliasing allowed!!
+
+        nmod_mat_clear (FLINTC);
+        nmod_mat_window_clear (FLINTK);
+        nmod_mat_clear (null);
+#else
+        NTLC= convertFacCFMatrix2NTLmat_zz_p(C);
+        NTLK= (*NTLC)*NTLN;
+        transpose (NTLK, NTLK);
+        kernel (NTLK, NTLK);
+        transpose (NTLK, NTLK);
+        NTLN *= NTLK;
+        delete NTLC;
+#endif
+#ifdef HAVE_FLINT
+        if (nmod_mat_ncols (FLINTN) == 1)
+        {
+          nmod_mat_clear (FLINTN);
+#else
+        if (NTLN.NumCols() == 1)
+        {
+#endif
+          delete [] A;
+          delete [] bounds;
+          CanonicalForm G= F;
+          F= 1;
+          return CFList (G (y-eval,y));
+        }
+      }
+    }
+
+#ifdef HAVE_FLINT
+    if (nmod_mat_ncols (FLINTN) < oldNumCols - factorsFound)
+    {
+      if (isReduced (FLINTN))
+      {
+        int * factorsFoundIndex= new int [nmod_mat_ncols (FLINTN)];
+        for (long i= 0; i < nmod_mat_ncols (FLINTN); i++)
+#else
+    if (NTLN.NumCols() < oldNumCols - factorsFound)
+    {
+      if (isReduced (NTLN))
+      {
+        int * factorsFoundIndex= new int [NTLN.NumCols()];
+        for (long i= 0; i < NTLN.NumCols(); i++)
+#endif
+          factorsFoundIndex[i]= 0;
+        int factorsFound2= 0;
+        CFList result;
+        CanonicalForm bufF= F;
+#ifdef HAVE_FLINT
+        reconstructionTry (result, bufF, factors, degree (F) + 1, factorsFound2,
+                           factorsFoundIndex, FLINTN, eval, false
+                          );
+        if (result.length() == nmod_mat_ncols (FLINTN))
+        {
+          nmod_mat_clear (FLINTN);
+#else
+        reconstructionTry (result, bufF, factors, degree (F) + 1, factorsFound2,
+                           factorsFoundIndex, NTLN, eval, false
+                          );
+        if (result.length() == NTLN.NumCols())
+        {
+#endif
+          delete [] factorsFoundIndex;
+          delete [] A;
+          delete [] bounds;
+          F= 1;
+          return result;
+        }
+        delete [] factorsFoundIndex;
+      }
+      else if (l == precision)
+      {
+        CanonicalForm bufF= F;
+#ifdef HAVE_FLINT
+        int * zeroOne= extractZeroOneVecs (FLINTN);
+        CFList result= reconstruction (bufF,factors,zeroOne,precision,FLINTN, eval);
+        nmod_mat_clear (FLINTN);
+#else
+        int * zeroOne= extractZeroOneVecs (NTLN);
+        CFList result= reconstruction (bufF, factors, zeroOne, precision, NTLN, eval);
+#endif
+        F= bufF;
+        delete [] zeroOne;
+        delete [] A;
+        delete [] bounds;
+        return result;
+      }
+    }
+    oldL2= l;
+    l += stepSize;
+    stepSize *= 2;
+    if (l > precision)
+    {
+      if (!hitBound)
+      {
+        l= precision;
+        hitBound= true;
+      }
+      else
+        break;
+    }
+  }
+#ifdef HAVE_FLINT
+  nmod_mat_clear (FLINTN);
+#endif
+  delete [] bounds;
+  delete [] A;
+  return CFList();
+}
+
+CFList
+increasePrecision (CanonicalForm& F, CFList& factors, int factorsFound,
+                   int oldNumCols, int oldL, const Variable&,
+                   int precision, const CanonicalForm& eval
+                  )
+{
+  int d;
+  bool isIrreducible= false;
+  Variable y= F.mvar();
+  int* bounds= computeBounds (F, d, isIrreducible);
+  if (isIrreducible)
+  {
+    delete [] bounds;
+    CanonicalForm G= F;
+    F= 1;
+    return CFList (G (y-eval,y));
+  }
+  CFArray * A= new CFArray [factors.length()];
+  CFArray bufQ= CFArray (factors.length());
+  mat_zz_pE NTLN;
+  ident (NTLN, factors.length());
+  int minBound= bounds[0];
+  for (int i= 1; i < d; i++)
+  {
+    if (bounds[i] != 0)
+      minBound= tmin (minBound, bounds[i]);
+  }
+  int l= tmax (2*(minBound + 1), oldL);
+  int oldL2= l/2;
+  int stepSize= 2;
+  bool useOldQs= false;
+  bool hitBound= false;
+  CFListIterator j;
+  CFMatrix C;
+  mat_zz_pE* NTLC, NTLK;
+  CFArray buf;
+  CanonicalForm truncF;
+  while (l <= precision)
+  {
+    j= factors;
+    truncF= mod (F, power (y,l));
+    if (useOldQs)
+    {
+      for (int i= 0; i < factors.length(); i++, j++)
+        A[i]= logarithmicDerivative (truncF, j.getItem(), l, oldL2, bufQ[i],
+                                     bufQ[i]
+                                    );
+    }
+    else
+    {
+      for (int i= 0; i < factors.length(); i++, j++)
+        A[i]= logarithmicDerivative (truncF, j.getItem(), l, bufQ [i]);
+    }
+    useOldQs= true;
+    for (int i= 0; i < d; i++)
+    {
+      if (bounds [i] + 1 <= l/2)
+      {
+        int k= tmin (bounds [i] + 1, l/2);
+        C= CFMatrix (l - k, factors.length());
+        for (int ii= 0; ii < factors.length(); ii++)
+        {
+          if (A[ii].size() - 1 >= i)
+          {
+            buf= getCoeffs (A[ii] [i], k);
+            writeInMatrix (C, buf, ii + 1, 0);
+          }
+        }
+        NTLC= convertFacCFMatrix2NTLmat_zz_pE(C);
+        NTLK= (*NTLC)*NTLN;
+        transpose (NTLK, NTLK);
+        kernel (NTLK, NTLK);
+        transpose (NTLK, NTLK);
+        NTLN *= NTLK;
+        delete NTLC;
+        if (NTLN.NumCols() == 1)
+        {
+          delete [] A;
+          delete [] bounds;
+          CanonicalForm G= F;
+          F= 1;
+          return CFList (G (y-eval,y));
+        }
+      }
+    }
+
+    if (NTLN.NumCols() < oldNumCols - factorsFound)
+    {
+      if (isReduced (NTLN))
+      {
+        int * factorsFoundIndex= new int [NTLN.NumCols()];
+        for (long i= 0; i < NTLN.NumCols(); i++)
+          factorsFoundIndex[i]= 0;
+        int factorsFound2= 0;
+        CFList result;
+        CanonicalForm bufF= F;
+        reconstructionTry (result, bufF, factors, degree (F) + 1, factorsFound2,
+                           factorsFoundIndex, NTLN, eval, false);
+        if (result.length() == NTLN.NumCols())
+        {
+          delete [] factorsFoundIndex;
+          delete [] A;
+          delete [] bounds;
+          F= 1;
+          return result;
+        }
+        delete [] factorsFoundIndex;
+      }
+      else if (l == precision)
+      {
+        CanonicalForm bufF= F;
+        int * zeroOne= extractZeroOneVecs (NTLN);
+        CFList result= reconstruction (bufF, factors, zeroOne, precision, NTLN, eval);
+        F= bufF;
+        delete [] zeroOne;
+        delete [] A;
+        delete [] bounds;
+        return result;
+      }
+    }
+    oldL2= l;
+    l += stepSize;
+    stepSize *= 2;
+    if (l > precision)
+    {
+      if (!hitBound)
+      {
+        l= precision;
+        hitBound= true;
+      }
+      else
+        break;
+    }
+  }
+  delete [] bounds;
+  delete [] A;
+  return CFList();
+}
+
+//over field extension
+CFList
+extIncreasePrecision (CanonicalForm& F, CFList& factors, int factorsFound,
+                      int oldNumCols, int oldL, const CanonicalForm& evaluation,
+                      const ExtensionInfo& info, CFList& source, CFList& dest,
+                      int precision
+                     )
+{
+  bool GF= (CFFactory::gettype()==GaloisFieldDomain);
+  int degMipo= degree (getMipo (info.getAlpha()));
+  Variable alpha= info.getAlpha();
+  int d;
+  bool isIrreducible= false;
+  int* bounds= computeBounds (F, d, isIrreducible);
+  if (isIrreducible)
+  {
+    delete [] bounds;
+    Variable y= Variable (2);
+    CanonicalForm tmp= F (y - evaluation, y);
+    CFList source, dest;
+    tmp= mapDown (tmp, info, source, dest);
+    F= 1;
+    return CFList (tmp);
+  }
+
+  CFArray * A= new CFArray [factors.length()];
+  CFArray bufQ= CFArray (factors.length());
+#ifdef HAVE_FLINT
+  nmod_mat_t FLINTN;
+  nmod_mat_init (FLINTN,factors.length(),factors.length(), getCharacteristic());
+  for (long i=factors.length()-1; i >= 0; i--)
+    nmod_mat_entry (FLINTN, i, i)= 1;
+#else
+  if (fac_NTL_char != getCharacteristic())
+  {
+    fac_NTL_char= getCharacteristic();
+    zz_p::init (getCharacteristic());
+  }
+  mat_zz_p NTLN;
+  ident (NTLN, factors.length());
+#endif
+  int minBound= bounds[0];
+  for (int i= 1; i < d; i++)
+  {
+    if (bounds[i] != 0)
+      minBound= tmin (minBound, bounds[i]);
+  }
+  int l= tmax (oldL, 2*((minBound+1)/degMipo+1));
+  int oldL2= l/2;
+  int stepSize= 2;
+  bool useOldQs= false;
+  bool hitBound= false;
+  Variable gamma= info.getBeta();
+  CanonicalForm primElemAlpha= info.getGamma();
+  CanonicalForm imPrimElemAlpha= info.getDelta();
+  CFListIterator j;
+  Variable y= F.mvar();
+  CanonicalForm powX, imBasis, truncF;
+  CFMatrix Mat, C;
+  CFIterator iter;
+#ifdef HAVE_FLINT
+  long rank;
+  nmod_mat_t FLINTMat, FLINTMatInv, FLINTC, FLINTK, null;
+#else
+  mat_zz_p* NTLMat,*NTLC, NTLK;
+#endif
+  CFArray buf;
+  while (l <= precision)
+  {
+    j= factors;
+    if (GF)
+      setCharacteristic (getCharacteristic());
+    powX= power (y-gamma, l);
+    Mat= CFMatrix (l*degMipo, l*degMipo);
+    for (int i= 0; i < l*degMipo; i++)
+    {
+      imBasis= mod (power (y, i), powX);
+      imBasis= imBasis (power (y, degMipo), y);
+      imBasis= imBasis (y, gamma);
+      iter= imBasis;
+      for (; iter.hasTerms(); iter++)
+          Mat (iter.exp()+ 1, i+1)= iter.coeff();
+    }
+
+#ifdef HAVE_FLINT
+    convertFacCFMatrix2nmod_mat_t (FLINTMat, Mat);
+    nmod_mat_init (FLINTMatInv, nmod_mat_nrows (FLINTMat),
+                   nmod_mat_nrows (FLINTMat), getCharacteristic());
+    nmod_mat_inv (FLINTMatInv, FLINTMat);
+#else
+    NTLMat= convertFacCFMatrix2NTLmat_zz_p (Mat);
+    *NTLMat= inv (*NTLMat);
+#endif
+
+    if (GF)
+      setCharacteristic (getCharacteristic(), degMipo, info.getGFName());
+
+    truncF= mod (F, power (y, l));
+    if (useOldQs)
+    {
+      for (int i= 0; i < factors.length(); i++, j++)
+        A[i]= logarithmicDerivative (truncF, j.getItem(), l, oldL2, bufQ[i],
+                                     bufQ[i]
+                                    );
+    }
+    else
+    {
+      for (int i= 0; i < factors.length(); i++, j++)
+        A[i]= logarithmicDerivative (truncF, j.getItem(), l, bufQ [i]);
+    }
+    useOldQs= true;
+    for (int i= 0; i < d; i++)
+    {
+      if (bounds [i] + 1 <= (l/2)*degMipo)
+      {
+        int k= tmin (bounds [i] + 1, (l/2)*degMipo);
+        C= CFMatrix (l*degMipo - k, factors.length());
+        for (int ii= 0; ii < factors.length(); ii++)
+        {
+          if (A[ii].size() - 1 >= i)
+          {
+            if (GF)
+            {
+              A[ii] [i]= A [ii] [i] (y-evaluation, y);
+              setCharacteristic (getCharacteristic());
+              A[ii] [i]= GF2FalphaRep (A[ii] [i], alpha);
+              if (alpha != gamma)
+                A [ii] [i]= mapDown (A[ii] [i], imPrimElemAlpha, primElemAlpha,
+                                     gamma, source, dest
+                                    );
+#ifdef HAVE_FLINT
+              buf= getCoeffs (A[ii] [i], k, l, degMipo, gamma, 0, FLINTMatInv);
+#else
+              buf= getCoeffs (A[ii] [i], k, l, degMipo, gamma, 0, *NTLMat);
+#endif
+            }
+            else
+            {
+              A [ii] [i]= A [ii] [i] (y-evaluation, y);
+              if (alpha != gamma)
+                A[ii] [i]= mapDown (A[ii] [i], imPrimElemAlpha, primElemAlpha,
+                                    gamma, source, dest
+                                   );
+#ifdef HAVE_FLINT
+              buf= getCoeffs (A[ii] [i], k, l, degMipo, gamma, 0, FLINTMatInv);
+#else
+              buf= getCoeffs (A[ii] [i], k, l, degMipo, gamma, 0, *NTLMat);
+#endif
+            }
+            writeInMatrix (C, buf, ii + 1, 0);
+          }
+          if (GF)
+            setCharacteristic (getCharacteristic(), degMipo, info.getGFName());
+        }
+
+        if (GF)
+          setCharacteristic(getCharacteristic());
+
+#ifdef HAVE_FLINT
+        convertFacCFMatrix2nmod_mat_t (FLINTC, C);
+        nmod_mat_init (FLINTK, nmod_mat_nrows (FLINTC), nmod_mat_ncols (FLINTN),
+                       getCharacteristic());
+        nmod_mat_mul (FLINTK, FLINTC, FLINTN);
+        nmod_mat_init (null, nmod_mat_ncols (FLINTK), nmod_mat_ncols (FLINTK),
+                       getCharacteristic());
+        rank= nmod_mat_nullspace (null, FLINTK);
+        nmod_mat_clear (FLINTK);
+        nmod_mat_window_init (FLINTK, null, 0, 0, nmod_mat_nrows(null), rank);
+        nmod_mat_clear (FLINTC);
+        nmod_mat_init_set (FLINTC, FLINTN);
+        nmod_mat_clear (FLINTN);
+        nmod_mat_init (FLINTN, nmod_mat_nrows (FLINTC), nmod_mat_ncols (FLINTK),
+                       getCharacteristic());
+        nmod_mat_mul (FLINTN, FLINTC, FLINTK); //no aliasing allowed!!
+
+        nmod_mat_clear (FLINTC);
+        nmod_mat_window_clear (FLINTK);
+        nmod_mat_clear (null);
+#else
+        NTLC= convertFacCFMatrix2NTLmat_zz_p(C);
+        NTLK= (*NTLC)*NTLN;
+        transpose (NTLK, NTLK);
+        kernel (NTLK, NTLK);
+        transpose (NTLK, NTLK);
+        NTLN *= NTLK;
+        delete NTLC;
+#endif
+
+        if (GF)
+          setCharacteristic (getCharacteristic(), degMipo, info.getGFName());
+
+#ifdef HAVE_FLINT
+        if (nmod_mat_ncols (FLINTN) == 1)
+        {
+          nmod_mat_clear (FLINTMat);
+          nmod_mat_clear (FLINTMatInv);
+          nmod_mat_clear (FLINTN);
+#else
+        if (NTLN.NumCols() == 1)
+        {
+          delete NTLMat;
+#endif
+          Variable y= Variable (2);
+          CanonicalForm tmp= F (y - evaluation, y);
+          CFList source, dest;
+          tmp= mapDown (tmp, info, source, dest);
+          delete [] A;
+          delete [] bounds;
+          F= 1;
+          return CFList (tmp);
+        }
+      }
+    }
+
+#ifdef HAVE_FLINT
+    nmod_mat_clear (FLINTMat);
+    nmod_mat_clear (FLINTMatInv);
+#else
+    delete NTLMat;
+#endif
+
+#ifdef HAVE_FLINT
+    if (nmod_mat_ncols (FLINTN) < oldNumCols - factorsFound)
+    {
+      if (isReduced (FLINTN))
+      {
+        int * factorsFoundIndex= new int [nmod_mat_ncols (FLINTN)];
+        for (long i= 0; i < nmod_mat_ncols (FLINTN); i++)
+#else
+    if (NTLN.NumCols() < oldNumCols - factorsFound)
+    {
+      if (isReduced (NTLN))
+      {
+        int * factorsFoundIndex= new int [NTLN.NumCols()];
+        for (long i= 0; i < NTLN.NumCols(); i++)
+#endif
+          factorsFoundIndex[i]= 0;
+        int factorsFound2= 0;
+        CFList result;
+        CanonicalForm bufF= F;
+#ifdef HAVE_FLINT
+        extReconstructionTry (result, bufF, factors,degree (F)+1, factorsFound2,
+                              factorsFoundIndex, FLINTN, false, info, evaluation
+                             );
+        if (result.length() == nmod_mat_ncols (FLINTN))
+        {
+          nmod_mat_clear (FLINTN);
+#else
+        extReconstructionTry (result, bufF, factors,degree (F)+1, factorsFound2,
+                              factorsFoundIndex, NTLN, false, info, evaluation
+                             );
+        if (result.length() == NTLN.NumCols())
+        {
+#endif
+          delete [] factorsFoundIndex;
+          delete [] A;
+          delete [] bounds;
+          F= 1;
+          return result;
+        }
+        delete [] factorsFoundIndex;
+      }
+      else if (l == precision)
+      {
+        CanonicalForm bufF= F;
+#ifdef HAVE_FLINT
+        int * zeroOne= extractZeroOneVecs (FLINTN);
+        CFList result= extReconstruction (bufF, factors, zeroOne, precision,
+                                          FLINTN, info, evaluation
+                                         );
+        nmod_mat_clear (FLINTN);
+#else
+        int * zeroOne= extractZeroOneVecs (NTLN);
+        CFList result= extReconstruction (bufF, factors, zeroOne, precision,
+                                          NTLN, info, evaluation
+                                         );
+#endif
+        F= bufF;
+        delete [] zeroOne;
+        delete [] A;
+        delete [] bounds;
+        return result;
+      }
+    }
+    oldL2= l;
+    l += stepSize;
+    stepSize *= 2;
+    if (l > precision)
+    {
+      if (!hitBound)
+      {
+        hitBound= true;
+        l= precision;
+      }
+      else
+        break;
+    }
+  }
+
+#ifdef HAVE_FLINT
+  nmod_mat_clear (FLINTN);
+#endif
+  delete [] bounds;
+  delete [] A;
+  return CFList();
+}
+
+CFList
+increasePrecision2 (const CanonicalForm& F, CFList& factors,
+                    const Variable& alpha, int precision)
+{
+  int d;
+  bool isIrreducible= false;
+  int* bounds= computeBounds (F, d, isIrreducible);
+  if (isIrreducible)
+  {
+    delete [] bounds;
+    return CFList (F);
+  }
+  CFArray * A= new CFArray [factors.length()];
+  CFArray bufQ= CFArray (factors.length());
+  if (fac_NTL_char != getCharacteristic())
+  {
+    fac_NTL_char= getCharacteristic();
+    zz_p::init (getCharacteristic());
+  }
+  zz_pX NTLMipo= convertFacCF2NTLzzpX (getMipo (alpha));
+  zz_pE::init (NTLMipo);
+  mat_zz_pE NTLN;
+  ident (NTLN, factors.length());
+  int minBound= bounds[0];
+  for (int i= 1; i < d; i++)
+  {
+    if (bounds[i] != 0)
+      minBound= tmin (minBound, bounds[i]);
+  }
+  int l= tmin (2*(minBound + 1), precision);
+  int oldL= l/2;
+  int stepSize= 2;
+  bool useOldQs= false;
+  bool hitBound= false;
+  CFListIterator j;
+  CFMatrix C;
+  CFArray buf;
+  mat_zz_pE* NTLC, NTLK;
+  Variable y= F.mvar();
+  CanonicalForm truncF;
+  while (l <= precision)
+  {
+    j= factors;
+    truncF= mod (F, power (y, l));
+    if (useOldQs)
+    {
+      for (int i= 0; i < factors.length(); i++, j++)
+        A[i]= logarithmicDerivative (truncF, j.getItem(), l, oldL, bufQ[i], bufQ[i]);
+    }
+    else
+    {
+      for (int i= 0; i < factors.length(); i++, j++)
+        A[i]= logarithmicDerivative (truncF, j.getItem(), l, bufQ [i]);
+    }
+    useOldQs= true;
+    for (int i= 0; i < d; i++)
+    {
+      if (bounds [i] + 1 <= l/2)
+      {
+        int k= tmin (bounds [i] + 1, l/2);
+        C= CFMatrix (l - k, factors.length());
+        for (int ii= 0; ii < factors.length(); ii++)
+        {
+          if (A[ii].size() - 1 >= i)
+          {
+            buf= getCoeffs (A[ii] [i], k);
+            writeInMatrix (C, buf, ii + 1, 0);
+          }
+        }
+        NTLC= convertFacCFMatrix2NTLmat_zz_pE(C);
+        NTLK= (*NTLC)*NTLN;
+        transpose (NTLK, NTLK);
+        kernel (NTLK, NTLK);
+        transpose (NTLK, NTLK);
+        NTLN *= NTLK;
+        delete NTLC;
+
+        if (NTLN.NumCols() == 1)
+        {
+          delete [] A;
+          delete [] bounds;
+          return CFList (F);
+        }
+      }
+    }
+
+    if (isReduced (NTLN) || l == precision)
+    {
+      CanonicalForm bufF= F;
+      int * zeroOne= extractZeroOneVecs (NTLN);
+      CFList bufFactors= factors;
+      CFList result= monicReconstruction (bufF, factors, zeroOne, precision,
+                                          NTLN
+                                         );
+      if (result.length() != NTLN.NumCols() && l != precision)
+        factors= bufFactors;
+      if (result.length() == NTLN.NumCols())
+      {
+        delete [] zeroOne;
+        delete [] A;
+        delete [] bounds;
+        return result;
+      }
+      if (l == precision)
+      {
+        delete [] zeroOne;
+        delete [] A;
+        delete [] bounds;
+        return Union (result, factors);
+      }
+      delete [] zeroOne;
+    }
+    oldL= l;
+    l += stepSize;
+    stepSize *= 2;
+    if (l > precision)
+    {
+      if (!hitBound)
+      {
+        l= precision;
+        hitBound= true;
+      }
+      else
+        break;
+    }
+  }
+  delete [] bounds;
+  delete [] A;
+  return CFList();
+}
+
+CFList
+increasePrecisionFq2Fp (CanonicalForm& F, CFList& factors, int factorsFound,
+                        int oldNumCols, int oldL, const Variable& alpha,
+                        int precision, const CanonicalForm& eval
+                       )
+{
+  int d;
+  bool isIrreducible= false;
+  Variable y= F.mvar();
+  int* bounds= computeBounds (F, d, isIrreducible);
+  if (isIrreducible)
+  {
+    delete [] bounds;
+    CanonicalForm G= F;
+    F= 1;
+    return CFList (G (y-eval,y));
+  }
+  int extensionDeg= degree (getMipo (alpha));
+  CFArray * A= new CFArray [factors.length()];
+  CFArray bufQ= CFArray (factors.length());
+#ifdef HAVE_FLINT
+  nmod_mat_t FLINTN;
+  nmod_mat_init (FLINTN,factors.length(),factors.length(), getCharacteristic());
+  for (long i=factors.length()-1; i >= 0; i--)
+    nmod_mat_entry (FLINTN, i, i)= 1;
+#else
+  mat_zz_p NTLN;
+  ident (NTLN, factors.length());
+#endif
+  int minBound= bounds[0];
+  for (int i= 1; i < d; i++)
+  {
+    if (bounds[i] != 0)
+      minBound= tmin (minBound, bounds[i]);
+  }
+  int l= tmax (2*(minBound + 1), oldL);
+  int oldL2= l/2;
+  int stepSize= 2;
+  bool useOldQs= false;
+  bool hitBound= false;
+  CFListIterator j;
+  CFMatrix C;
+#ifdef HAVE_FLINT
+  long rank;
+  nmod_mat_t FLINTC, FLINTK, null;
+#else
+  mat_zz_p* NTLC, NTLK;
+#endif
+  CFArray buf;
+  CanonicalForm truncF;
+  while (l <= precision)
+  {
+    j= factors;
+    truncF= mod (F, power (y, l));
+    if (useOldQs)
+    {
+      for (int i= 0; i < factors.length(); i++, j++)
+        A[i]= logarithmicDerivative (truncF, j.getItem(), l, oldL2, bufQ[i],
+                                     bufQ[i]
+                                    );
+    }
+    else
+    {
+      for (int i= 0; i < factors.length(); i++, j++)
+        A[i]= logarithmicDerivative (truncF, j.getItem(), l, bufQ [i]);
+    }
+    useOldQs= true;
+    for (int i= 0; i < d; i++)
+    {
+      if (bounds [i] + 1 <= l/2)
+      {
+        int k= tmin (bounds [i] + 1, l/2);
+        C= CFMatrix ((l - k)*extensionDeg, factors.length());
+        for (int ii= 0; ii < factors.length(); ii++)
+        {
+          if (A[ii].size() - 1 >= i)
+          {
+            buf= getCoeffs (A[ii] [i], k, alpha);
+            writeInMatrix (C, buf, ii + 1, 0);
+          }
+        }
+#ifdef HAVE_FLINT
+        convertFacCFMatrix2nmod_mat_t (FLINTC, C);
+        nmod_mat_init (FLINTK, nmod_mat_nrows (FLINTC), nmod_mat_ncols (FLINTN),
+                       getCharacteristic());
+        nmod_mat_mul (FLINTK, FLINTC, FLINTN);
+        nmod_mat_init (null, nmod_mat_ncols (FLINTK), nmod_mat_ncols (FLINTK),
+                       getCharacteristic());
+        rank= nmod_mat_nullspace (null, FLINTK);
+        nmod_mat_clear (FLINTK);
+        nmod_mat_window_init (FLINTK, null, 0, 0, nmod_mat_nrows(null), rank);
+        nmod_mat_clear (FLINTC);
+        nmod_mat_init_set (FLINTC, FLINTN);
+        nmod_mat_clear (FLINTN);
+        nmod_mat_init (FLINTN, nmod_mat_nrows (FLINTC), nmod_mat_ncols (FLINTK),
+                       getCharacteristic());
+        nmod_mat_mul (FLINTN, FLINTC, FLINTK); //no aliasing allowed!!
+
+        nmod_mat_clear (FLINTC);
+        nmod_mat_window_clear (FLINTK);
+        nmod_mat_clear (null);
+#else
+        NTLC= convertFacCFMatrix2NTLmat_zz_p(C);
+        NTLK= (*NTLC)*NTLN;
+        transpose (NTLK, NTLK);
+        kernel (NTLK, NTLK);
+        transpose (NTLK, NTLK);
+        NTLN *= NTLK;
+        delete NTLC;
+#endif
+#ifdef HAVE_FLINT
+        if (nmod_mat_ncols (FLINTN) == 1)
+        {
+          nmod_mat_clear (FLINTN);
+#else
+        if (NTLN.NumCols() == 1)
+        {
+#endif
+          delete [] A;
+          delete [] bounds;
+          CanonicalForm G= F;
+          F= 1;
+          return CFList (G (y-eval,y));
+        }
+      }
+    }
+
+#ifdef HAVE_FLINT
+    if (nmod_mat_ncols (FLINTN) < oldNumCols - factorsFound)
+    {
+      if (isReduced (FLINTN))
+      {
+        int * factorsFoundIndex= new int [nmod_mat_ncols (FLINTN)];
+        for (long i= 0; i < nmod_mat_ncols (FLINTN); i++)
+#else
+    if (NTLN.NumCols() < oldNumCols - factorsFound)
+    {
+      if (isReduced (NTLN))
+      {
+        int * factorsFoundIndex= new int [NTLN.NumCols()];
+        for (long i= 0; i < NTLN.NumCols(); i++)
+#endif
+          factorsFoundIndex[i]= 0;
+        int factorsFound2= 0;
+        CFList result;
+        CanonicalForm bufF= F;
+#ifdef HAVE_FLINT
+        reconstructionTry (result, bufF, factors, degree (F) + 1, factorsFound2,
+                           factorsFoundIndex, FLINTN, eval, false
+                          );
+        if (result.length() == nmod_mat_ncols (FLINTN))
+        {
+          nmod_mat_clear (FLINTN);
+#else
+        reconstructionTry (result, bufF, factors, degree (F) + 1, factorsFound2,
+                           factorsFoundIndex, NTLN, eval, false
+                          );
+        if (result.length() == NTLN.NumCols())
+        {
+#endif
+          delete [] factorsFoundIndex;
+          delete [] A;
+          delete [] bounds;
+          F= 1;
+          return result;
+        }
+        delete [] factorsFoundIndex;
+      }
+      else if (l == precision)
+      {
+        CanonicalForm bufF= F;
+#ifdef HAVE_FLINT
+        int * zeroOne= extractZeroOneVecs (FLINTN);
+        CFList result= reconstruction (bufF,factors,zeroOne,precision,FLINTN, eval);
+        nmod_mat_clear (FLINTN);
+#else
+        int * zeroOne= extractZeroOneVecs (NTLN);
+        CFList result= reconstruction (bufF, factors, zeroOne, precision, NTLN, eval);
+#endif
+        F= bufF;
+        delete [] zeroOne;
+        delete [] A;
+        delete [] bounds;
+        return result;
+      }
+    }
+    oldL2= l;
+    l += stepSize;
+    stepSize *= 2;
+    if (l > precision)
+    {
+      if (!hitBound)
+      {
+        hitBound= true;
+        l= precision;
+      }
+      else
+        break;
+    }
+  }
+#ifdef HAVE_FLINT
+  nmod_mat_clear (FLINTN);
+#endif
+  delete [] bounds;
+  delete [] A;
+  return CFList();
+}
+
+#ifdef HAVE_FLINT
+CFList
+increasePrecision (CanonicalForm& F, CFList& factors, int oldL, int
+                   l, int d, int* bounds, CFArray& bufQ, nmod_mat_t FLINTN,
+                   const CanonicalForm& eval
+                  )
+#else
+CFList
+increasePrecision (CanonicalForm& F, CFList& factors, int oldL, int
+                   l, int d, int* bounds, CFArray& bufQ, mat_zz_p& NTLN,
+                   const CanonicalForm& eval
+                  )
+#endif
+{
+  CFList result= CFList();
+  CFArray * A= new CFArray [factors.length()];
+  int oldL2= oldL/2;
+  bool hitBound= false;
+#ifdef HAVE_FLINT
+  if (nmod_mat_nrows (FLINTN) != factors.length()) //refined factors
+  {
+    nmod_mat_clear (FLINTN);
+    nmod_mat_init(FLINTN,factors.length(),factors.length(),getCharacteristic());
+    for (long i=factors.length()-1; i >= 0; i--)
+      nmod_mat_entry (FLINTN, i, i)= 1;
+    bufQ= CFArray (factors.length());
+  }
+#else
+  if (NTLN.NumRows() != factors.length()) //refined factors
+  {
+    ident (NTLN, factors.length());
+    bufQ= CFArray (factors.length());
+  }
+#endif
+  bool useOldQs= false;
+  CFListIterator j;
+  CFMatrix C;
+  CFArray buf;
+#ifdef HAVE_FLINT
+  long rank;
+  nmod_mat_t FLINTC, FLINTK, null;
+#else
+  mat_zz_p* NTLC, NTLK;
+#endif
+  CanonicalForm bufF, truncF;
+  CFList bufUniFactors;
+  Variable y= F.mvar();
+  while (oldL <= l)
+  {
+    j= factors;
+    truncF= mod (F, power (y, oldL));
+    if (useOldQs)
+    {
+      for (int i= 0; i < factors.length(); i++, j++)
+        A[i]= logarithmicDerivative (truncF, j.getItem(), oldL, oldL2, bufQ[i],
+                                     bufQ[i]
+                                    );
+    }
+    else
+    {
+      for (int i= 0; i < factors.length(); i++, j++)
+        A[i]= logarithmicDerivative (truncF, j.getItem(), oldL, bufQ [i]);
+    }
+    useOldQs= true;
+
+    for (int i= 0; i < d; i++)
+    {
+      if (bounds [i] + 1 <= oldL/2)
+      {
+        int k= tmin (bounds [i] + 1, oldL/2);
+        C= CFMatrix (oldL - k, factors.length());
+        for (int ii= 0; ii < factors.length(); ii++)
+        {
+          if (A[ii].size() - 1 >= i)
+          {
+            buf= getCoeffs (A[ii] [i], k);
+            writeInMatrix (C, buf, ii + 1, 0);
+          }
+        }
+#ifdef HAVE_FLINT
+        convertFacCFMatrix2nmod_mat_t (FLINTC, C);
+        nmod_mat_init (FLINTK, nmod_mat_nrows (FLINTC), nmod_mat_ncols (FLINTN),
+                       getCharacteristic());
+        nmod_mat_mul (FLINTK, FLINTC, FLINTN);
+        nmod_mat_init (null, nmod_mat_ncols (FLINTK), nmod_mat_ncols (FLINTK),
+                       getCharacteristic());
+        rank= nmod_mat_nullspace (null, FLINTK);
+        nmod_mat_clear (FLINTK);
+        nmod_mat_window_init (FLINTK, null, 0, 0, nmod_mat_nrows(null), rank);
+        nmod_mat_clear (FLINTC);
+        nmod_mat_init_set (FLINTC, FLINTN);
+        nmod_mat_clear (FLINTN);
+        nmod_mat_init (FLINTN, nmod_mat_nrows (FLINTC), nmod_mat_ncols (FLINTK),
+                       getCharacteristic());
+        nmod_mat_mul (FLINTN, FLINTC, FLINTK); //no aliasing allowed!!
+
+        nmod_mat_clear (FLINTC);
+        nmod_mat_window_clear (FLINTK);
+        nmod_mat_clear (null);
+#else
+        NTLC= convertFacCFMatrix2NTLmat_zz_p(C);
+        NTLK= (*NTLC)*NTLN;
+        transpose (NTLK, NTLK);
+        kernel (NTLK, NTLK);
+        transpose (NTLK, NTLK);
+        NTLN *= NTLK;
+        delete NTLC;
+#endif
+#ifdef HAVE_FLINT
+        if (nmod_mat_ncols (FLINTN) == 1)
+#else
+        if (NTLN.NumCols() == 1)
+#endif
+        {
+          delete [] A;
+          return CFList (F (y-eval,y));
+        }
+      }
+    }
+#ifdef HAVE_FLINT
+    if (nmod_mat_ncols (FLINTN) == 1)
+#else
+    if (NTLN.NumCols() == 1)
+#endif
+    {
+      delete [] A;
+      return CFList (F (y-eval,y));
+    }
+    int * zeroOneVecs;
+#ifdef HAVE_FLINT
+    zeroOneVecs= extractZeroOneVecs (FLINTN);
+#else
+    zeroOneVecs= extractZeroOneVecs (NTLN);
+#endif
+    bufF= F;
+    bufUniFactors= factors;
+#ifdef HAVE_FLINT
+    result= reconstruction (bufF, bufUniFactors, zeroOneVecs, oldL, FLINTN, eval);
+#else
+    result= reconstruction (bufF, bufUniFactors, zeroOneVecs, oldL, NTLN, eval);
+#endif
+    delete [] zeroOneVecs;
+    if (degree (bufF) + 1 + degree (LC (bufF, 1)) < oldL && result.length() > 0)
+    {
+      F= bufF;
+      factors= bufUniFactors;
+      delete [] A;
+      return result;
+    }
+
+    result= CFList();
+    oldL2= oldL;
+    oldL *= 2;
+    if (oldL > l)
+    {
+      if (!hitBound)
+      {
+        oldL= l;
+        hitBound= true;
+      }
+      else
+        break;
+    }
+  }
+  delete [] A;
+  return result;
+}
+
+CFList
+increasePrecision (CanonicalForm& F, CFList& factors, int oldL, int
+                   l, int d, int* bounds, CFArray& bufQ, mat_zz_pE& NTLN,
+                   const CanonicalForm& eval
+                  )
+{
+  CFList result= CFList();
+  CFArray * A= new CFArray [factors.length()];
+  int oldL2= oldL/2;
+  bool hitBound= false;
+  bool useOldQs= false;
+  if (NTLN.NumRows() != factors.length()) //refined factors
+    ident (NTLN, factors.length());
+  CFListIterator j;
+  CFMatrix C;
+  CFArray buf;
+  mat_zz_pE* NTLC, NTLK;
+  CanonicalForm bufF, truncF;
+  CFList bufUniFactors;
+  Variable y= F.mvar();
+  while (oldL <= l)
+  {
+    j= factors;
+    truncF= mod (F, power (y, oldL));
+    if (useOldQs)
+    {
+      for (int i= 0; i < factors.length(); i++, j++)
+        A[i]= logarithmicDerivative (truncF, j.getItem(), oldL, oldL2, bufQ[i],
+                                     bufQ[i]
+                                    );
+    }
+    else
+    {
+      for (int i= 0; i < factors.length(); i++, j++)
+        A[i]= logarithmicDerivative (truncF, j.getItem(), oldL, bufQ [i]);
+    }
+    useOldQs= true;
+
+    for (int i= 0; i < d; i++)
+    {
+      if (bounds [i] + 1 <= oldL/2)
+      {
+        int k= tmin (bounds [i] + 1, oldL/2);
+        C= CFMatrix (oldL - k, factors.length());
+        for (int ii= 0; ii < factors.length(); ii++)
+        {
+          if (A[ii].size() - 1 >= i)
+          {
+            buf= getCoeffs (A[ii] [i], k);
+            writeInMatrix (C, buf, ii + 1, 0);
+          }
+        }
+        NTLC= convertFacCFMatrix2NTLmat_zz_pE(C);
+        NTLK= (*NTLC)*NTLN;
+        transpose (NTLK, NTLK);
+        kernel (NTLK, NTLK);
+        transpose (NTLK, NTLK);
+        NTLN *= NTLK;
+        delete NTLC;
+
+        if (NTLN.NumCols() == 1)
+        {
+          delete [] A;
+          return CFList (F (y-eval,y));
+        }
+      }
+    }
+    if (NTLN.NumCols() == 1)
+    {
+      delete [] A;
+      return CFList (F (y-eval,y));
+    }
+
+    int * zeroOneVecs;
+    zeroOneVecs= extractZeroOneVecs (NTLN);
+    bufF= F;
+    bufUniFactors= factors;
+    result= reconstruction (bufF, bufUniFactors, zeroOneVecs, oldL, NTLN, eval);
+    delete [] zeroOneVecs;
+    if (degree (bufF) + 1 + degree (LC (bufF, 1)) < l && result.length() > 0)
+    {
+      F= bufF;
+      factors= bufUniFactors;
+      delete [] A;
+      return result;
+    }
+
+    result= CFList();
+    oldL2= oldL;
+    oldL *= 2;
+    if (oldL > l)
+    {
+      if (!hitBound)
+      {
+        oldL= l;
+        hitBound= true;
+      }
+      else
+        break;
+    }
+  }
+  delete [] A;
+  return result;
+}
+
+//over field extension
+#ifdef HAVE_FLINT
+CFList
+extIncreasePrecision (CanonicalForm& F, CFList& factors, int oldL, int l, int d,
+                      int* bounds, CFArray& bufQ, nmod_mat_t FLINTN, const
+                      CanonicalForm& evaluation, const ExtensionInfo& info,
+                      CFList& source, CFList& dest
+                     )
+#else
+CFList
+extIncreasePrecision (CanonicalForm& F, CFList& factors, int oldL, int l, int d,
+                      int* bounds, CFArray& bufQ, mat_zz_p& NTLN, const
+                      CanonicalForm& evaluation, const ExtensionInfo& info,
+                      CFList& source, CFList& dest
+                     )
+#endif
+{
+  CFList result= CFList();
+  CFArray * A= new CFArray [factors.length()];
+  int oldL2= oldL/2; //be careful
+  bool hitBound= false;
+  bool useOldQs= false;
+  bool GF= (CFFactory::gettype()==GaloisFieldDomain);
+  int degMipo= degree (getMipo (info.getAlpha()));
+  Variable alpha= info.getAlpha();
+
+  Variable gamma= info.getBeta();
+  CanonicalForm primElemAlpha= info.getGamma();
+  CanonicalForm imPrimElemAlpha= info.getDelta();
+#ifdef HAVE_FLINT
+  nmod_mat_clear (FLINTN);
+  nmod_mat_init (FLINTN,factors.length(),factors.length(), getCharacteristic());
+  for (long i=factors.length()-1; i >= 0; i--)
+    nmod_mat_entry (FLINTN, i, i)= 1;
+#else
+  if (NTLN.NumRows() != factors.length()) //refined factors
+    ident (NTLN, factors.length());
+#endif
+  Variable y= F.mvar();
+  CFListIterator j;
+  CanonicalForm powX, imBasis, bufF, truncF;
+  CFMatrix Mat, C;
+  CFIterator iter;
+  CFArray buf;
+#ifdef HAVE_FLINT
+  long rank;
+  nmod_mat_t FLINTMat, FLINTMatInv, FLINTC, FLINTK, null;
+#else
+  mat_zz_p* NTLC, NTLK, *NTLMat;
+#endif
+  CFList bufUniFactors;
+  while (oldL <= l)
+  {
+    j= factors;
+    if (GF)
+      setCharacteristic (getCharacteristic());
+
+    powX= power (y-gamma, oldL);
+    Mat= CFMatrix (oldL*degMipo, oldL*degMipo);
+    for (int i= 0; i < oldL*degMipo; i++)
+    {
+      imBasis= mod (power (y, i), powX);
+      imBasis= imBasis (power (y, degMipo), y);
+      imBasis= imBasis (y, gamma);
+      iter= imBasis;
+      for (; iter.hasTerms(); iter++)
+        Mat (iter.exp()+ 1, i+1)= iter.coeff();
+    }
+
+#ifdef HAVE_FLINT
+    convertFacCFMatrix2nmod_mat_t (FLINTMat, Mat);
+    nmod_mat_init (FLINTMatInv, nmod_mat_nrows (FLINTMat),
+                   nmod_mat_nrows (FLINTMat), getCharacteristic());
+    nmod_mat_inv (FLINTMatInv, FLINTMat);
+#else
+    NTLMat= convertFacCFMatrix2NTLmat_zz_p (Mat);
+    *NTLMat= inv (*NTLMat);
+#endif
+
+    if (GF)
+      setCharacteristic (getCharacteristic(), degMipo, info.getGFName());
+
+    truncF= mod (F, power (y, oldL));
+    if (useOldQs)
+    {
+      for (int i= 0; i < factors.length(); i++, j++)
+        A[i]= logarithmicDerivative (truncF, j.getItem(), oldL, oldL2, bufQ[i],
+                                     bufQ[i]);
+    }
+    else
+    {
+      for (int i= 0; i < factors.length(); i++, j++)
+        A[i]= logarithmicDerivative (truncF, j.getItem(), oldL, bufQ [i]);
+    }
+    useOldQs= true;
+
+    for (int i= 0; i < d; i++)
+    {
+      if (bounds [i] + 1 <= oldL/2)
+      {
+        int k= tmin (bounds [i] + 1, oldL/2);
+        C= CFMatrix (oldL*degMipo - k, factors.length());
+        for (int ii= 0; ii < factors.length(); ii++)
+        {
+          if (A[ii].size() - 1 >= i)
+          {
+            if (GF)
+            {
+              A [ii] [i]= A [ii] [i] (y-evaluation, y);
+              setCharacteristic (getCharacteristic());
+              A[ii] [i]= GF2FalphaRep (A[ii] [i], alpha);
+              if (alpha != gamma)
+                A [ii] [i]= mapDown (A[ii] [i], imPrimElemAlpha, primElemAlpha,
+                                     gamma, source, dest
+                                    );
+#ifdef HAVE_FLINT
+              buf= getCoeffs (A[ii] [i], k, oldL, degMipo, gamma, 0, FLINTMatInv);
+#else
+              buf= getCoeffs (A[ii] [i], k, oldL, degMipo, gamma, 0, *NTLMat);
+#endif
+            }
+            else
+            {
+              A [ii] [i]= A [ii] [i] (y-evaluation, y);
+              if (alpha != gamma)
+                A[ii] [i]= mapDown (A[ii] [i], imPrimElemAlpha, primElemAlpha,
+                                    gamma, source, dest
+                                   );
+#ifdef HAVE_FLINT
+              buf= getCoeffs (A[ii] [i], k, oldL, degMipo, gamma, 0, FLINTMatInv);
+#else
+              buf= getCoeffs (A[ii] [i], k, oldL, degMipo, gamma, 0, *NTLMat);
+#endif
+            }
+            writeInMatrix (C, buf, ii + 1, 0);
+          }
+          if (GF)
+            setCharacteristic (getCharacteristic(), degMipo, info.getGFName());
+        }
+
+        if (GF)
+          setCharacteristic(getCharacteristic());
+
+#ifdef HAVE_FLINT
+        convertFacCFMatrix2nmod_mat_t (FLINTC, C);
+        nmod_mat_init (FLINTK, nmod_mat_nrows (FLINTC), nmod_mat_ncols (FLINTN),
+                       getCharacteristic());
+        nmod_mat_mul (FLINTK, FLINTC, FLINTN);
+        nmod_mat_init (null, nmod_mat_ncols (FLINTK), nmod_mat_ncols (FLINTK),
+                       getCharacteristic());
+        rank= nmod_mat_nullspace (null, FLINTK);
+        nmod_mat_clear (FLINTK);
+        nmod_mat_window_init (FLINTK, null, 0, 0, nmod_mat_nrows(null), rank);
+        nmod_mat_clear (FLINTC);
+        nmod_mat_init_set (FLINTC, FLINTN);
+        nmod_mat_clear (FLINTN);
+        nmod_mat_init (FLINTN, nmod_mat_nrows (FLINTC), nmod_mat_ncols (FLINTK),
+                       getCharacteristic());
+        nmod_mat_mul (FLINTN, FLINTC, FLINTK); //no aliasing allowed!!
+
+        nmod_mat_clear (FLINTC);
+        nmod_mat_window_clear (FLINTK);
+        nmod_mat_clear (null);
+#else
+        NTLC= convertFacCFMatrix2NTLmat_zz_p(C);
+        NTLK= (*NTLC)*NTLN;
+        transpose (NTLK, NTLK);
+        kernel (NTLK, NTLK);
+        transpose (NTLK, NTLK);
+        NTLN *= NTLK;
+        delete NTLC;
+#endif
+
+        if (GF)
+          setCharacteristic (getCharacteristic(), degMipo, info.getGFName());
+
+#ifdef HAVE_FLINT
+        if (nmod_mat_ncols (FLINTN) == 1)
+        {
+          nmod_mat_clear (FLINTMat);
+          nmod_mat_clear (FLINTMatInv);
+#else
+        if (NTLN.NumCols() == 1)
+        {
+          delete NTLMat;
+#endif
+          Variable y= Variable (2);
+          CanonicalForm tmp= F (y - evaluation, y);
+          CFList source, dest;
+          tmp= mapDown (tmp, info, source, dest);
+          delete [] A;
+          return CFList (tmp);
+        }
+      }
+    }
+
+#ifdef HAVE_FLINT
+    nmod_mat_clear (FLINTMat);
+    nmod_mat_clear (FLINTMatInv);
+#else
+    delete NTLMat;
+#endif
+
+#ifdef HAVE_FLINT
+    if (nmod_mat_ncols (FLINTN) == 1)
+#else
+    if (NTLN.NumCols() == 1)
+#endif
+    {
+      Variable y= Variable (2);
+      CanonicalForm tmp= F (y - evaluation, y);
+      CFList source, dest;
+      tmp= mapDown (tmp, info, source, dest);
+      delete [] A;
+      return CFList (tmp);
+    }
+
+    int * zeroOneVecs;
+    bufF= F;
+    bufUniFactors= factors;
+#ifdef HAVE_FLINT
+    zeroOneVecs= extractZeroOneVecs (FLINTN);
+    result= extReconstruction (bufF, bufUniFactors, zeroOneVecs, oldL, FLINTN,
+                               info, evaluation
+                              );
+#else
+    zeroOneVecs= extractZeroOneVecs (NTLN);
+    result= extReconstruction (bufF, bufUniFactors, zeroOneVecs, oldL, NTLN,
+                               info, evaluation
+                              );
+#endif
+    delete [] zeroOneVecs;
+    if (degree (bufF) + 1 + degree (LC (bufF, 1)) < l && result.length() > 0)
+    {
+      F= bufF;
+      factors= bufUniFactors;
+      return result;
+    }
+
+    result= CFList();
+    oldL2= oldL;
+    oldL *= 2;
+    if (oldL > l)
+    {
+      if (!hitBound)
+      {
+        oldL= l;
+        hitBound= true;
+      }
+      else
+        break;
+    }
+  }
+  delete [] A;
+  return result;
+}
+
+#ifdef HAVE_FLINT
+CFList
+increasePrecisionFq2Fp (CanonicalForm& F, CFList& factors, int oldL, int l,
+                        int d, int* bounds, CFArray& bufQ, nmod_mat_t FLINTN,
+                        const Variable& alpha, const CanonicalForm& eval
+                       )
+#else
+CFList
+increasePrecisionFq2Fp (CanonicalForm& F, CFList& factors, int oldL, int l,
+                        int d, int* bounds, CFArray& bufQ, mat_zz_p& NTLN,
+                        const Variable& alpha, const CanonicalForm& eval
+                       )
+#endif
+{
+  CFList result= CFList();
+  CFArray * A= new CFArray [factors.length()];
+  int extensionDeg= degree (getMipo (alpha));
+  int oldL2= oldL/2;
+  bool hitBound= false;
+  bool useOldQs= false;
+#ifdef HAVE_FLINT
+  if (nmod_mat_nrows (FLINTN) != factors.length()) //refined factors
+  {
+    nmod_mat_clear (FLINTN);
+    nmod_mat_init(FLINTN,factors.length(),factors.length(),getCharacteristic());
+    for (long i=factors.length()-1; i >= 0; i--)
+      nmod_mat_entry (FLINTN, i, i)= 1;
+  }
+#else
+  if (NTLN.NumRows() != factors.length()) //refined factors
+    ident (NTLN, factors.length());
+#endif
+  CFListIterator j;
+  CFMatrix C;
+  CFArray buf;
+#ifdef HAVE_FLINT
+  long rank;
+  nmod_mat_t FLINTC, FLINTK, null;
+#else
+  mat_zz_p* NTLC, NTLK;
+#endif
+  CanonicalForm bufF, truncF;
+  CFList bufUniFactors;
+  Variable y= F.mvar();
+  while (oldL <= l)
+  {
+    j= factors;
+    truncF= mod (F, power (y, oldL));
+    if (useOldQs)
+    {
+      for (int i= 0; i < factors.length(); i++, j++)
+        A[i]= logarithmicDerivative (truncF, j.getItem(), oldL, oldL2, bufQ[i],
+                                     bufQ[i]
+                                    );
+    }
+    else
+    {
+      for (int i= 0; i < factors.length(); i++, j++)
+        A[i]= logarithmicDerivative (truncF, j.getItem(), oldL, bufQ [i]);
+    }
+    useOldQs= true;
+
+    for (int i= 0; i < d; i++)
+    {
+      if (bounds [i] + 1 <= oldL/2)
+      {
+        int k= tmin (bounds [i] + 1, oldL/2);
+        C= CFMatrix ((oldL - k)*extensionDeg, factors.length());
+        for (int ii= 0; ii < factors.length(); ii++)
+        {
+          if (A[ii].size() - 1 >= i)
+          {
+            buf= getCoeffs (A[ii] [i], k, alpha);
+            writeInMatrix (C, buf, ii + 1, 0);
+          }
+        }
+#ifdef HAVE_FLINT
+        convertFacCFMatrix2nmod_mat_t (FLINTC, C);
+        nmod_mat_init (FLINTK, nmod_mat_nrows (FLINTC), nmod_mat_ncols (FLINTN),
+                       getCharacteristic());
+        nmod_mat_mul (FLINTK, FLINTC, FLINTN);
+        nmod_mat_init (null, nmod_mat_ncols (FLINTK), nmod_mat_ncols (FLINTK),
+                       getCharacteristic());
+        rank= nmod_mat_nullspace (null, FLINTK);
+        nmod_mat_clear (FLINTK);
+        nmod_mat_window_init (FLINTK, null, 0, 0, nmod_mat_nrows(null), rank);
+        nmod_mat_clear (FLINTC);
+        nmod_mat_init_set (FLINTC, FLINTN);
+        nmod_mat_clear (FLINTN);
+        nmod_mat_init (FLINTN, nmod_mat_nrows (FLINTC), nmod_mat_ncols (FLINTK),
+                       getCharacteristic());
+        nmod_mat_mul (FLINTN, FLINTC, FLINTK); //no aliasing allowed!!
+
+        nmod_mat_clear (FLINTC);
+        nmod_mat_window_clear (FLINTK);
+        nmod_mat_clear (null);
+#else
+        NTLC= convertFacCFMatrix2NTLmat_zz_p(C);
+        NTLK= (*NTLC)*NTLN;
+        transpose (NTLK, NTLK);
+        kernel (NTLK, NTLK);
+        transpose (NTLK, NTLK);
+        NTLN *= NTLK;
+        delete NTLC;
+#endif
+#ifdef HAVE_FLINT
+        if (nmod_mat_ncols (FLINTN) == 1)
+#else
+        if (NTLN.NumCols() == 1)
+#endif
+        {
+          delete [] A;
+          return CFList (F(y-eval,y));
+        }
+      }
+    }
+
+    int * zeroOneVecs;
+#ifdef HAVE_FLINT
+    zeroOneVecs= extractZeroOneVecs (FLINTN);
+#else
+    zeroOneVecs= extractZeroOneVecs (NTLN);
+#endif
+
+    bufF= F;
+    bufUniFactors= factors;
+#ifdef HAVE_FLINT
+    result= reconstruction (bufF, bufUniFactors, zeroOneVecs, oldL, FLINTN, eval);
+#else
+    result= reconstruction (bufF, bufUniFactors, zeroOneVecs, oldL, NTLN, eval);
+#endif
+    delete [] zeroOneVecs;
+    if (degree (bufF) + 1 + degree (LC (bufF, 1)) < l && result.length() > 0)
+    {
+      F= bufF;
+      factors= bufUniFactors;
+      delete [] A;
+      return result;
+    }
+
+    result= CFList();
+    oldL2= oldL;
+    oldL *= 2;
+    if (oldL > l)
+    {
+      if (!hitBound)
+      {
+        oldL= l;
+        hitBound= true;
+      }
+      else
+        break;
+    }
+  }
+  delete [] A;
+  return result;
+}
+
+#ifdef HAVE_FLINT
+CFList
+furtherLiftingAndIncreasePrecision (CanonicalForm& F, CFList&
+                                    factors, int l, int liftBound, int d, int*
+                                    bounds, nmod_mat_t FLINTN, CFList& diophant,
+                                    CFMatrix& M, CFArray& Pi, CFArray& bufQ,
+                                    const CanonicalForm& eval
+                                   )
+#else
+CFList
+furtherLiftingAndIncreasePrecision (CanonicalForm& F, CFList&
+                                    factors, int l, int liftBound, int d, int*
+                                    bounds, mat_zz_p& NTLN, CFList& diophant,
+                                    CFMatrix& M, CFArray& Pi, CFArray& bufQ,
+                                    const CanonicalForm& eval
+                                   )
+#endif
+{
+  CanonicalForm LCF= LC (F, 1);
+  CFList result;
+  bool irreducible= false;
+  CFList bufFactors= factors;
+  CFList bufBufFactors;
+  CFArray *A = new CFArray [bufFactors.length()];
+  bool useOldQs= false;
+  bool hitBound= false;
+  int oldL= l;
+  int stepSize= 8; //TODO choose better step size?
+  l += tmax (tmin (8, degree (F) + 1 + degree (LC (F, 1))-l), 2);
+#ifdef HAVE_FLINT
+  if (nmod_mat_nrows (FLINTN) != factors.length()) //refined factors
+  {
+    nmod_mat_clear (FLINTN);
+    nmod_mat_init(FLINTN,factors.length(),factors.length(),getCharacteristic());
+    for (long i=factors.length()-1; i >= 0; i--)
+      nmod_mat_entry (FLINTN, i, i)= 1;
+  }
+#else
+  if (NTLN.NumRows() != factors.length()) //refined factors
+    ident (NTLN, factors.length());
+#endif
+  CFListIterator j;
+  CFMatrix C;
+  CFArray buf;
+#ifdef HAVE_FLINT
+  long rank;
+  nmod_mat_t FLINTC, FLINTK, null;
+#else
+  mat_zz_p* NTLC, NTLK;
+#endif
+  CanonicalForm bufF, truncF;
+  Variable y= F.mvar();
+  while (l <= liftBound)
+  {
+    bufFactors.insert (LCF);
+    henselLiftResume12 (F, bufFactors, oldL, l, Pi, diophant, M);
+    j= bufFactors;
+    truncF= mod (F, power (y, l));
+    if (useOldQs)
+    {
+      for (int i= 0; i < bufFactors.length(); i++, j++)
+        A[i]= logarithmicDerivative (truncF, j.getItem(), l, oldL, bufQ[i],
+                                     bufQ[i]);
+    }
+    else
+    {
+      for (int i= 0; i < bufFactors.length(); i++, j++)
+        A[i]= logarithmicDerivative (truncF, j.getItem(), l, bufQ [i]);
+    }
+    for (int i= 0; i < d; i++)
+    {
+      if (bounds [i] + 1 <= l/2)
+      {
+        int k= tmin (bounds [i] + 1, l/2);
+        C= CFMatrix (l - k, bufFactors.length());
+        for (int ii= 0; ii < bufFactors.length(); ii++)
+        {
+          if (A[ii].size() - 1 >= i)
+          {
+            buf= getCoeffs (A[ii] [i], k);
+            writeInMatrix (C, buf, ii + 1, 0);
+          }
+        }
+#ifdef HAVE_FLINT
+        convertFacCFMatrix2nmod_mat_t (FLINTC, C);
+        nmod_mat_init (FLINTK, nmod_mat_nrows (FLINTC), nmod_mat_ncols (FLINTN),
+                       getCharacteristic());
+        nmod_mat_mul (FLINTK, FLINTC, FLINTN);
+        nmod_mat_init (null, nmod_mat_ncols (FLINTK), nmod_mat_ncols (FLINTK),
+                       getCharacteristic());
+        rank= nmod_mat_nullspace (null, FLINTK);
+        nmod_mat_clear (FLINTK);
+        nmod_mat_window_init (FLINTK, null, 0, 0, nmod_mat_nrows(null), rank);
+        nmod_mat_clear (FLINTC);
+        nmod_mat_init_set (FLINTC, FLINTN);
+        nmod_mat_clear (FLINTN);
+        nmod_mat_init (FLINTN, nmod_mat_nrows (FLINTC), nmod_mat_ncols (FLINTK),
+                       getCharacteristic());
+        nmod_mat_mul (FLINTN, FLINTC, FLINTK); //no aliasing allowed!!
+
+        nmod_mat_clear (FLINTC);
+        nmod_mat_window_clear (FLINTK);
+        nmod_mat_clear (null);
+#else
+        NTLC= convertFacCFMatrix2NTLmat_zz_p(C);
+        NTLK= (*NTLC)*NTLN;
+        transpose (NTLK, NTLK);
+        kernel (NTLK, NTLK);
+        transpose (NTLK, NTLK);
+        NTLN *= NTLK;
+        delete NTLC;
+#endif
+#ifdef HAVE_FLINT
+        if (nmod_mat_ncols (FLINTN) == 1)
+#else
+        if (NTLN.NumCols() == 1)
+#endif
+        {
+          irreducible= true;
+          break;
+        }
+      }
+    }
+
+#ifdef HAVE_FLINT
+    if (nmod_mat_ncols (FLINTN) == 1)
+#else
+    if (NTLN.NumCols() == 1)
+#endif
+    {
+      irreducible= true;
+      break;
+    }
+
+#ifdef HAVE_FLINT
+    int * zeroOneVecs= extractZeroOneVecs (FLINTN);
+#else
+    int * zeroOneVecs= extractZeroOneVecs (NTLN);
+#endif
+    bufF= F;
+    bufBufFactors= bufFactors;
+#ifdef HAVE_FLINT
+    result= reconstruction (bufF, bufFactors, zeroOneVecs, l, FLINTN, eval);
+#else
+    result= reconstruction (bufF, bufFactors, zeroOneVecs, l, NTLN, eval);
+#endif
+    delete [] zeroOneVecs;
+    if (result.length() > 0 && degree (bufF) + 1 + degree (LC (bufF, 1)) <= l)
+    {
+      F= bufF;
+      factors= bufFactors;
+      delete [] A;
+      return result;
+    }
+    else
+    {
+      bufF= F;
+      bufFactors= bufBufFactors;
+    }
+
+#ifdef HAVE_FLINT
+    if (isReduced (FLINTN))
+#else
+    if (isReduced (NTLN))
+#endif
+    {
+      int factorsFound= 0;
+      bufF= F;
+#ifdef HAVE_FLINT
+      int* factorsFoundIndex= new int [nmod_mat_ncols (FLINTN)];
+      for (long i= 0; i < nmod_mat_ncols (FLINTN); i++)
+#else
+      int* factorsFoundIndex= new int [NTLN.NumCols()];
+      for (long i= 0; i < NTLN.NumCols(); i++)
+#endif
+        factorsFoundIndex[i]= 0;
+#ifdef HAVE_FLINT
+      if (l < liftBound)
+        reconstructionTry (result, bufF, bufFactors, l, factorsFound,
+                           factorsFoundIndex, FLINTN, eval, false
+                          );
+      else
+        reconstructionTry (result, bufF, bufFactors, degree (bufF) + 1 +
+                           degree (LCF), factorsFound, factorsFoundIndex,
+                           FLINTN, eval, false
+                          );
+
+      if (nmod_mat_ncols (FLINTN) == result.length())
+#else
+      if (l < liftBound)
+        reconstructionTry (result, bufF, bufFactors, l, factorsFound,
+                           factorsFoundIndex, NTLN, eval, false
+                          );
+      else
+        reconstructionTry (result, bufF, bufFactors, degree (bufF) + 1 +
+                           degree (LCF), factorsFound, factorsFoundIndex,
+                           NTLN, eval, false
+                          );
+
+      if (NTLN.NumCols() == result.length())
+#endif
+      {
+        delete [] A;
+        delete [] factorsFoundIndex;
+        return result;
+      }
+      delete [] factorsFoundIndex;
+    }
+    result= CFList();
+    oldL= l;
+    stepSize *= 2;
+    l += stepSize;
+    if (l > liftBound)
+    {
+      if (!hitBound)
+      {
+        l= liftBound;
+        hitBound= true;
+      }
+      else
+        break;
+    }
+  }
+  if (irreducible)
+  {
+    delete [] A;
+    return CFList (F (y-eval,y));
+  }
+  delete [] A;
+  factors= bufFactors;
+  return CFList();
+}
+
+//Fq
+CFList
+furtherLiftingAndIncreasePrecision (CanonicalForm& F, CFList&
+                                    factors, int l, int liftBound, int d, int*
+                                    bounds, mat_zz_pE& NTLN, CFList& diophant,
+                                    CFMatrix& M, CFArray& Pi, CFArray& bufQ,
+                                    const CanonicalForm& eval
+                                   )
+{
+  CanonicalForm LCF= LC (F, 1);
+  CFList result;
+  bool irreducible= false;
+  CFList bufFactors= factors;
+  CFList bufBufFactors;
+  CFArray *A = new CFArray [bufFactors.length()];
+  bool useOldQs= false;
+  bool hitBound= false;
+  int oldL= l;
+  int stepSize= 8; //TODO choose better step size?
+  l += tmax (tmin (8, degree (F) + 1 + degree (LC (F, 1))-l), 2);
+  if (NTLN.NumRows() != factors.length()) //refined factors
+    ident (NTLN, factors.length());
+  CFListIterator j;
+  CFArray buf;
+  mat_zz_pE* NTLC, NTLK;
+  CanonicalForm bufF, truncF;
+  Variable y= F.mvar();
+  while (l <= liftBound)
+  {
+    bufFactors.insert (LCF);
+    henselLiftResume12 (F, bufFactors, oldL, l, Pi, diophant, M);
+    j= bufFactors;
+    truncF= mod (F, power (y, l));
+    if (useOldQs)
+    {
+      for (int i= 0; i < bufFactors.length(); i++, j++)
+        A[i]= logarithmicDerivative (truncF, j.getItem(), l, oldL, bufQ[i],
+                                     bufQ[i]);
+    }
+    else
+    {
+      for (int i= 0; i < bufFactors.length(); i++, j++)
+        A[i]= logarithmicDerivative (truncF, j.getItem(), l, bufQ [i]);
+    }
+    for (int i= 0; i < d; i++)
+    {
+      if (bounds [i] + 1 <= l/2)
+      {
+        int k= tmin (bounds [i] + 1, l/2);
+        CFMatrix C= CFMatrix (l - k, bufFactors.length());
+        for (int ii= 0; ii < bufFactors.length(); ii++)
+        {
+          if (A[ii].size() - 1 >= i)
+          {
+            buf= getCoeffs (A[ii] [i], k);
+            writeInMatrix (C, buf, ii + 1, 0);
+          }
+        }
+        NTLC= convertFacCFMatrix2NTLmat_zz_pE(C);
+        NTLK= (*NTLC)*NTLN;
+        transpose (NTLK, NTLK);
+        kernel (NTLK, NTLK);
+        transpose (NTLK, NTLK);
+        NTLN *= NTLK;
+        delete NTLC;
+        if (NTLN.NumCols() == 1)
+        {
+          irreducible= true;
+          break;
+        }
+      }
+    }
+    if (NTLN.NumCols() == 1)
+    {
+      irreducible= true;
+      break;
+    }
+
+    int * zeroOneVecs= extractZeroOneVecs (NTLN);
+    bufF= F;
+    bufBufFactors= bufFactors;
+    result= reconstruction (bufF, bufFactors, zeroOneVecs, l, NTLN, eval);
+    delete [] zeroOneVecs;
+    if (result.length() > 0 && degree (bufF) + 1 + degree (LC (bufF, 1)) <= l)
+    {
+      F= bufF;
+      factors= bufFactors;
+      delete [] A;
+      return result;
+    }
+    else
+    {
+      bufF= F;
+      bufFactors= bufBufFactors;
+    }
+
+    if (isReduced (NTLN))
+    {
+      int factorsFound= 0;
+      bufF= F;
+      int* factorsFoundIndex= new int [NTLN.NumCols()];
+      for (long i= 0; i < NTLN.NumCols(); i++)
+        factorsFoundIndex[i]= 0;
+      if (l < liftBound)
+        reconstructionTry (result, bufF, bufFactors, l, factorsFound,
+                           factorsFoundIndex, NTLN, eval, false
+                          );
+      else
+        reconstructionTry (result, bufF, bufFactors, degree (bufF) + 1 +
+                           degree (LCF), factorsFound, factorsFoundIndex,
+                           NTLN, eval, false
+                          );
+      if (NTLN.NumCols() == result.length())
+      {
+        delete [] A;
+        delete [] factorsFoundIndex;
+        return result;
+      }
+      delete [] factorsFoundIndex;
+    }
+    result= CFList();
+    oldL= l;
+    stepSize *= 2;
+    l += stepSize;
+    if (l > liftBound)
+    {
+      if (!hitBound)
+      {
+        l= liftBound;
+        hitBound= true;
+      }
+      else
+        break;
+    }
+  }
+  if (irreducible)
+  {
+    delete [] A;
+    return CFList (F (y-eval,y));
+  }
+  delete [] A;
+  factors= bufFactors;
+  return CFList();
+}
+
+//over field extension
+#ifdef HAVE_FLINT
+CFList
+extFurtherLiftingAndIncreasePrecision (CanonicalForm& F, CFList& factors, int l,
+                                       int liftBound, int d, int* bounds,
+                                       nmod_mat_t FLINTN, CFList& diophant,
+                                       CFMatrix& M, CFArray& Pi, CFArray& bufQ,
+                                       const CanonicalForm& evaluation, const
+                                       ExtensionInfo& info, CFList& source,
+                                       CFList& dest
+                                      )
+#else
+CFList
+extFurtherLiftingAndIncreasePrecision (CanonicalForm& F, CFList& factors, int l,
+                                       int liftBound, int d, int* bounds,
+                                       mat_zz_p& NTLN, CFList& diophant,
+                                       CFMatrix& M, CFArray& Pi, CFArray& bufQ,
+                                       const CanonicalForm& evaluation, const
+                                       ExtensionInfo& info, CFList& source,
+                                       CFList& dest
+                                      )
+#endif
+{
+  CanonicalForm LCF= LC (F, 1);
+  CFList result;
+  bool irreducible= false;
+  CFList bufFactors= factors;
+  CFList bufBufFactors;
+  CFArray *A = new CFArray [bufFactors.length()];
+  bool useOldQs= false;
+  bool hitBound= false;
+  bool GF= (CFFactory::gettype()==GaloisFieldDomain);
+  int degMipo= degree (getMipo (info.getAlpha()));
+  Variable alpha= info.getAlpha();
+  int oldL= l; //be careful
+  int stepSize= 8;
+  l += tmax (tmin (8, degree (F) + 1 + degree (LC (F, 1))-l),2);
+  Variable gamma= info.getBeta();
+  CanonicalForm primElemAlpha= info.getGamma();
+  CanonicalForm imPrimElemAlpha= info.getDelta();
+#ifdef HAVE_FLINT
+  nmod_mat_clear (FLINTN);
+  nmod_mat_init (FLINTN,factors.length(),factors.length(), getCharacteristic());
+  for (long i=factors.length()-1; i >= 0; i--)
+    nmod_mat_entry (FLINTN, i, i)= 1;
+#else
+  if (NTLN.NumRows() != factors.length()) //refined factors
+    ident (NTLN, factors.length());
+#endif
+  Variable y= F.mvar();
+  CanonicalForm powX, imBasis, bufF, truncF;
+  CFMatrix Mat, C;
+  CFIterator iter;
+#ifdef HAVE_FLINT
+  long rank;
+  nmod_mat_t FLINTMat, FLINTMatInv, FLINTC, FLINTK, null;
+#else
+  mat_zz_p* NTLMat,*NTLC, NTLK;
+#endif
+  CFListIterator j;
+  CFArray buf;
+  while (l <= liftBound)
+  {
+    bufFactors.insert (LCF);
+    henselLiftResume12 (F, bufFactors, oldL, l, Pi, diophant, M);
+
+    if (GF)
+      setCharacteristic (getCharacteristic());
+
+    powX= power (y-gamma, l);
+    Mat= CFMatrix (l*degMipo, l*degMipo);
+    for (int i= 0; i < l*degMipo; i++)
+    {
+
+      imBasis= mod (power (y, i), powX);
+      imBasis= imBasis (power (y, degMipo), y);
+      imBasis= imBasis (y, gamma);
+      iter= imBasis;
+      for (; iter.hasTerms(); iter++)
+        Mat (iter.exp()+ 1, i+1)= iter.coeff();
+    }
+
+#ifdef HAVE_FLINT
+    convertFacCFMatrix2nmod_mat_t (FLINTMat, Mat);
+    nmod_mat_init (FLINTMatInv, nmod_mat_nrows (FLINTMat),
+                   nmod_mat_nrows (FLINTMat), getCharacteristic());
+    nmod_mat_inv (FLINTMatInv, FLINTMat);
+#else
+    NTLMat= convertFacCFMatrix2NTLmat_zz_p (Mat);
+    *NTLMat= inv (*NTLMat);
+#endif
+
+    if (GF)
+      setCharacteristic (getCharacteristic(), degMipo, info.getGFName());
+
+    j= bufFactors;
+    truncF= mod (F, power (y, l));
+    if (useOldQs)
+    {
+      for (int i= 0; i < bufFactors.length(); i++, j++)
+        A[i]= logarithmicDerivative (truncF, j.getItem(), l, oldL, bufQ[i],
+                                     bufQ[i]);
+    }
+    else
+    {
+      for (int i= 0; i < bufFactors.length(); i++, j++)
+        A[i]= logarithmicDerivative (truncF, j.getItem(), l, bufQ [i]);
+    }
+    for (int i= 0; i < d; i++)
+    {
+      if (bounds [i] + 1 <= l/2)
+      {
+        int k= tmin (bounds [i] + 1, l/2);
+        C= CFMatrix (l*degMipo - k, bufFactors.length());
+        for (int ii= 0; ii < bufFactors.length(); ii++)
+        {
+          if (A[ii].size() - 1 >= i)
+          {
+            if (GF)
+            {
+              A [ii] [i]= A [ii] [i] (y-evaluation, y);
+              setCharacteristic (getCharacteristic());
+              A[ii] [i]= GF2FalphaRep (A[ii] [i], alpha);
+              if (alpha != gamma)
+                A [ii] [i]= mapDown (A[ii] [i], imPrimElemAlpha, primElemAlpha,
+                                     gamma, source, dest
+                                    );
+#ifdef HAVE_FLINT
+              buf= getCoeffs (A[ii] [i], k, l, degMipo, gamma, 0, FLINTMatInv);
+#else
+              buf= getCoeffs (A[ii] [i], k, l, degMipo, gamma, 0, *NTLMat);
+#endif
+            }
+            else
+            {
+              A [ii] [i]= A [ii] [i] (y-evaluation, y);
+              if (alpha != gamma)
+                A[ii] [i]= mapDown (A[ii] [i], imPrimElemAlpha, primElemAlpha,
+                                    gamma, source, dest
+                                   );
+#ifdef HAVE_FLINT
+              buf= getCoeffs (A[ii] [i], k, l, degMipo, gamma, 0, FLINTMatInv);
+#else
+              buf= getCoeffs (A[ii] [i], k, l, degMipo, gamma, 0, *NTLMat);
+#endif
+            }
+            writeInMatrix (C, buf, ii + 1, 0);
+          }
+          if (GF)
+            setCharacteristic (getCharacteristic(), degMipo, info.getGFName());
+        }
+
+        if (GF)
+          setCharacteristic(getCharacteristic());
+
+#ifdef HAVE_FLINT
+        convertFacCFMatrix2nmod_mat_t (FLINTC, C);
+        nmod_mat_init (FLINTK, nmod_mat_nrows (FLINTC), nmod_mat_ncols (FLINTN),
+                       getCharacteristic());
+        nmod_mat_mul (FLINTK, FLINTC, FLINTN);
+        nmod_mat_init (null, nmod_mat_ncols (FLINTK), nmod_mat_ncols (FLINTK),
+                       getCharacteristic());
+        rank= nmod_mat_nullspace (null, FLINTK);
+        nmod_mat_clear (FLINTK);
+        nmod_mat_window_init (FLINTK, null, 0, 0, nmod_mat_nrows(null), rank);
+        nmod_mat_clear (FLINTC);
+        nmod_mat_init_set (FLINTC, FLINTN);
+        nmod_mat_clear (FLINTN);
+        nmod_mat_init (FLINTN, nmod_mat_nrows (FLINTC), nmod_mat_ncols (FLINTK),
+                       getCharacteristic());
+        nmod_mat_mul (FLINTN, FLINTC, FLINTK); //no aliasing allowed!!
+
+        nmod_mat_clear (FLINTC);
+        nmod_mat_window_clear (FLINTK);
+        nmod_mat_clear (null);
+#else
+        NTLC= convertFacCFMatrix2NTLmat_zz_p(C);
+        NTLK= (*NTLC)*NTLN;
+        transpose (NTLK, NTLK);
+        kernel (NTLK, NTLK);
+        transpose (NTLK, NTLK);
+        NTLN *= NTLK;
+        delete NTLC;
+#endif
+
+        if (GF)
+          setCharacteristic (getCharacteristic(), degMipo, info.getGFName());
+
+#ifdef HAVE_FLINT
+        if (nmod_mat_ncols (FLINTN) == 1)
+#else
+        if (NTLN.NumCols() == 1)
+#endif
+        {
+          irreducible= true;
+          break;
+        }
+      }
+    }
+
+#ifdef HAVE_FLINT
+    nmod_mat_clear (FLINTMat);
+    nmod_mat_clear (FLINTMatInv);
+    if (nmod_mat_ncols (FLINTN) == 1)
+#else
+    delete NTLMat;
+    if (NTLN.NumCols() == 1)
+#endif
+    {
+      irreducible= true;
+      break;
+    }
+
+    bufF= F;
+    bufBufFactors= bufFactors;
+#ifdef HAVE_FLINT
+    int * zeroOneVecs= extractZeroOneVecs (FLINTN);
+    result= extReconstruction (bufF, bufFactors, zeroOneVecs, l, FLINTN, info,
+                               evaluation
+                              );
+#else
+    int * zeroOneVecs= extractZeroOneVecs (NTLN);
+    result= extReconstruction (bufF, bufFactors, zeroOneVecs, l, NTLN, info,
+                               evaluation
+                              );
+#endif
+    delete [] zeroOneVecs;
+    if (result.length() > 0 && degree (bufF) + 1 + degree (LC (bufF, 1)) <= l)
+    {
+      F= bufF;
+      factors= bufFactors;
+      delete [] A;
+      return result;
+    }
+    else
+    {
+      bufF= F;
+      bufFactors= bufBufFactors;
+    }
+
+#ifdef HAVE_FLINT
+    if (isReduced (FLINTN))
+#else
+    if (isReduced (NTLN))
+#endif
+    {
+      int factorsFound= 0;
+      bufF= F;
+#ifdef HAVE_FLINT
+      int* factorsFoundIndex= new int [nmod_mat_ncols (FLINTN)];
+      for (long i= 0; i < nmod_mat_ncols (FLINTN); i++)
+#else
+      int* factorsFoundIndex= new int [NTLN.NumCols()];
+      for (long i= 0; i < NTLN.NumCols(); i++)
+#endif
+        factorsFoundIndex[i]= 0;
+#ifdef HAVE_FLINT
+      if (l < degree (bufF) + 1 + degree (LCF))
+        extReconstructionTry (result, bufF, bufFactors, l, factorsFound,
+                              factorsFoundIndex, FLINTN, false, info, evaluation
+                             );
+      else
+        extReconstructionTry (result, bufF, bufFactors, degree (bufF) + 1 +
+                              degree (LCF), factorsFound, factorsFoundIndex,
+                              FLINTN, false, info, evaluation
+                             );
+      if (nmod_mat_ncols (FLINTN) == result.length())
+#else
+      if (l < degree (bufF) + 1 + degree (LCF))
+        extReconstructionTry (result, bufF, bufFactors, l, factorsFound,
+                              factorsFoundIndex, NTLN, false, info, evaluation
+                             );
+      else
+        extReconstructionTry (result, bufF, bufFactors, degree (bufF) + 1 +
+                              degree (LCF), factorsFound, factorsFoundIndex,
+                              NTLN, false, info, evaluation
+                             );
+      if (NTLN.NumCols() == result.length())
+#endif
+      {
+        delete [] A;
+        delete [] factorsFoundIndex;
+        return result;
+      }
+      delete [] factorsFoundIndex;
+    }
+    result= CFList();
+    oldL= l;
+    stepSize *= 2;
+    l += stepSize;
+    if (l > liftBound)
+    {
+      if (!hitBound)
+      {
+        l= liftBound;
+        hitBound= true;
+      }
+      else
+        break;
+    }
+  }
+  if (irreducible)
+  {
+    delete [] A;
+    Variable y= Variable (2);
+    CanonicalForm tmp= F (y - evaluation, y);
+    CFList source, dest;
+    tmp= mapDown (tmp, info, source, dest);
+    return CFList (tmp);
+  }
+  delete [] A;
+  factors= bufFactors;
+  return CFList();
+}
+
+#ifdef HAVE_FLINT
+CFList
+furtherLiftingAndIncreasePrecisionFq2Fp (CanonicalForm& F, CFList& factors, int
+                                         l, int liftBound, int d, int* bounds,
+                                         nmod_mat_t FLINTN, CFList& diophant,
+                                         CFMatrix& M, CFArray& Pi, CFArray& bufQ,
+                                         const Variable& alpha,
+                                         const CanonicalForm& eval
+                                        )
+#else
+CFList
+furtherLiftingAndIncreasePrecisionFq2Fp (CanonicalForm& F, CFList& factors, int
+                                         l, int liftBound, int d, int* bounds,
+                                         mat_zz_p& NTLN, CFList& diophant,
+                                         CFMatrix& M, CFArray& Pi, CFArray& bufQ,
+                                         const Variable& alpha,
+                                         const CanonicalForm& eval
+                                        )
+#endif
+{
+  CanonicalForm LCF= LC (F, 1);
+  CFList result;
+  bool irreducible= false;
+  CFList bufFactors= factors;
+  CFList bufBufFactors;
+  CFArray *A = new CFArray [bufFactors.length()];
+  bool useOldQs= false;
+  int extensionDeg= degree (getMipo (alpha));
+  bool hitBound= false;
+  int oldL= l;
+  int stepSize= 8; //TODO choose better step size?
+  l += tmax (tmin (8, degree (F) + 1 + degree (LC (F, 1))-l), 2);
+#ifdef HAVE_FLINT
+  if (nmod_mat_nrows (FLINTN) != factors.length()) //refined factors
+  {
+    nmod_mat_clear (FLINTN);
+    nmod_mat_init(FLINTN,factors.length(),factors.length(),getCharacteristic());
+    for (long i=factors.length()-1; i >= 0; i--)
+      nmod_mat_entry (FLINTN, i, i)= 1;
+  }
+#else
+  if (NTLN.NumRows() != factors.length()) //refined factors
+    ident (NTLN, factors.length());
+#endif
+  CFListIterator j;
+  CFMatrix C;
+#ifdef HAVE_FLINT
+  long rank;
+  nmod_mat_t FLINTC, FLINTK, null;
+#else
+  mat_zz_p* NTLC, NTLK;
+#endif
+  CanonicalForm bufF, truncF;
+  Variable y= F.mvar();
+  while (l <= liftBound)
+  {
+    bufFactors.insert (LCF);
+    henselLiftResume12 (F, bufFactors, oldL, l, Pi, diophant, M);
+    j= bufFactors;
+    truncF= mod (F, power (y, l));
+    if (useOldQs)
+    {
+      for (int i= 0; i < bufFactors.length(); i++, j++)
+        A[i]= logarithmicDerivative (truncF, j.getItem(), l, oldL, bufQ[i],
+                                     bufQ[i]);
+    }
+    else
+    {
+      for (int i= 0; i < bufFactors.length(); i++, j++)
+        A[i]= logarithmicDerivative (truncF, j.getItem(), l, bufQ [i]);
+    }
+    for (int i= 0; i < d; i++)
+    {
+      if (bounds [i] + 1 <= l/2)
+      {
+        int k= tmin (bounds [i] + 1, l/2);
+        C= CFMatrix ((l - k)*extensionDeg, bufFactors.length());
+        for (int ii= 0; ii < bufFactors.length(); ii++)
+        {
+          CFArray buf;
+          if (A[ii].size() - 1 >= i)
+          {
+            buf= getCoeffs (A[ii] [i], k, alpha);
+            writeInMatrix (C, buf, ii + 1, 0);
+          }
+        }
+#ifdef HAVE_FLINT
+        convertFacCFMatrix2nmod_mat_t (FLINTC, C);
+        nmod_mat_init (FLINTK, nmod_mat_nrows (FLINTC), nmod_mat_ncols (FLINTN),
+                       getCharacteristic());
+        nmod_mat_mul (FLINTK, FLINTC, FLINTN);
+        nmod_mat_init (null, nmod_mat_ncols (FLINTK), nmod_mat_ncols (FLINTK),
+                       getCharacteristic());
+        rank= nmod_mat_nullspace (null, FLINTK);
+        nmod_mat_clear (FLINTK);
+        nmod_mat_window_init (FLINTK, null, 0, 0, nmod_mat_nrows(null), rank);
+        nmod_mat_clear (FLINTC);
+        nmod_mat_init_set (FLINTC, FLINTN);
+        nmod_mat_clear (FLINTN);
+        nmod_mat_init (FLINTN, nmod_mat_nrows (FLINTC), nmod_mat_ncols (FLINTK),
+                       getCharacteristic());
+        nmod_mat_mul (FLINTN, FLINTC, FLINTK); //no aliasing allowed!!
+
+        nmod_mat_clear (FLINTC);
+        nmod_mat_window_clear (FLINTK);
+        nmod_mat_clear (null);
+#else
+        NTLC= convertFacCFMatrix2NTLmat_zz_p(C);
+        NTLK= (*NTLC)*NTLN;
+        transpose (NTLK, NTLK);
+        kernel (NTLK, NTLK);
+        transpose (NTLK, NTLK);
+        NTLN *= NTLK;
+        delete NTLC;
+#endif
+#ifdef HAVE_FLINT
+        if (nmod_mat_ncols (FLINTN) == 1)
+#else
+        if (NTLN.NumCols() == 1)
+#endif
+        {
+          irreducible= true;
+          break;
+        }
+      }
+    }
+#ifdef HAVE_FLINT
+    if (nmod_mat_ncols (FLINTN) == 1)
+#else
+    if (NTLN.NumCols() == 1)
+#endif
+    {
+      irreducible= true;
+      break;
+    }
+
+#ifdef HAVE_FLINT
+    int * zeroOneVecs= extractZeroOneVecs (FLINTN);
+#else
+    int * zeroOneVecs= extractZeroOneVecs (NTLN);
+#endif
+    CanonicalForm bufF= F;
+    bufBufFactors= bufFactors;
+#ifdef HAVE_FLINT
+    result= reconstruction (bufF, bufFactors, zeroOneVecs, l, FLINTN, eval);
+#else
+    result= reconstruction (bufF, bufFactors, zeroOneVecs, l, NTLN,  eval);
+#endif
+    delete [] zeroOneVecs;
+    if (result.length() > 0 && degree (bufF) + 1 + degree (LC (bufF, 1)) <= l)
+    {
+      F= bufF;
+      factors= bufFactors;
+      delete [] A;
+      return result;
+    }
+    else
+    {
+      bufF= F;
+      bufFactors= bufBufFactors;
+    }
+
+#ifdef HAVE_FLINT
+    if (isReduced (FLINTN))
+#else
+    if (isReduced (NTLN))
+#endif
+    {
+      int factorsFound= 0;
+      bufF= F;
+#ifdef HAVE_FLINT
+      int* factorsFoundIndex= new int [nmod_mat_ncols (FLINTN)];
+      for (long i= 0; i < nmod_mat_ncols (FLINTN); i++)
+#else
+      int* factorsFoundIndex= new int [NTLN.NumCols()];
+      for (long i= 0; i < NTLN.NumCols(); i++)
+#endif
+        factorsFoundIndex[i]= 0;
+#ifdef HAVE_FLINT
+      if (l < degree (bufF) + 1 + degree (LCF))
+        reconstructionTry (result, bufF, bufFactors, l, factorsFound,
+                           factorsFoundIndex, FLINTN, eval, false
+                          );
+      else
+        reconstructionTry (result, bufF, bufFactors, degree (bufF) + 1 +
+                           degree (LCF), factorsFound, factorsFoundIndex,
+                           FLINTN, eval, false
+                          );
+      if (nmod_mat_ncols (FLINTN) == result.length())
+#else
+      if (l < degree (bufF) + 1 + degree (LCF))
+        reconstructionTry (result, bufF, bufFactors, l, factorsFound,
+                           factorsFoundIndex, NTLN, eval, false
+                          );
+      else
+        reconstructionTry (result, bufF, bufFactors, degree (bufF) + 1 +
+                           degree (LCF), factorsFound, factorsFoundIndex,
+                           NTLN, eval, false
+                          );
+      if (NTLN.NumCols() == result.length())
+#endif
+      {
+        delete [] A;
+        delete [] factorsFoundIndex;
+        return result;
+      }
+      delete [] factorsFoundIndex;
+    }
+    result= CFList();
+    oldL= l;
+    stepSize *= 2;
+    l += stepSize;
+    if (l > liftBound)
+    {
+      if (!hitBound)
+      {
+        l= liftBound;
+        hitBound= true;
+      }
+      else
+        break;
+    }
+  }
+  if (irreducible)
+  {
+    delete [] A;
+    return CFList (F (y-eval,y));
+  }
+  delete [] A;
+  factors= bufFactors;
+  return CFList();
+}
+
+#ifndef HAVE_FLINT
+void
+refineAndRestartLift (const CanonicalForm& F, const mat_zz_p& NTLN, int
+                      liftBound, int l, CFList& factors, CFMatrix& M, CFArray&
+                      Pi, CFList& diophant
+                     )
+{
+  CFList bufFactors;
+  Variable y= Variable (2);
+  CanonicalForm LCF= LC (F, 1);
+  CFListIterator iter;
+  CanonicalForm buf;
+  for (long i= 1; i <= NTLN.NumCols(); i++)
+  {
+    iter= factors;
+    buf= 1;
+    for (long j= 1; j <= NTLN.NumRows(); j++, iter++)
+    {
+      if (!IsZero (NTLN (j,i)))
+        buf= mulNTL (buf, mod (iter.getItem(), y));
+    }
+    bufFactors.append (buf);
+  }
+  factors= bufFactors;
+  M= CFMatrix (liftBound, factors.length());
+  Pi= CFArray();
+  diophant= CFList();
+  factors.insert (LCF);
+  henselLift12 (F, factors, l, Pi, diophant, M);
+}
+#endif
+
+#ifdef HAVE_FLINT
+void
+refineAndRestartLift (const CanonicalForm& F, const nmod_mat_t FLINTN, int
+                      liftBound, int l, CFList& factors, CFMatrix& M, CFArray&
+                      Pi, CFList& diophant
+                     )
+{
+  CFList bufFactors;
+  Variable y= Variable (2);
+  CanonicalForm LCF= LC (F, 1);
+  CFListIterator iter;
+  CanonicalForm buf;
+  for (long i= 0; i < nmod_mat_ncols (FLINTN); i++)
+  {
+    iter= factors;
+    buf= 1;
+    for (long j= 0; j < nmod_mat_nrows (FLINTN); j++, iter++)
+    {
+      if (!(nmod_mat_entry (FLINTN,j,i) == 0))
+        buf= mulNTL (buf, mod (iter.getItem(), y));
+    }
+    bufFactors.append (buf);
+  }
+  factors= bufFactors;
+  M= CFMatrix (liftBound, factors.length());
+  Pi= CFArray();
+  diophant= CFList();
+  factors.insert (LCF);
+  henselLift12 (F, factors, l, Pi, diophant, M);
+}
+#endif
+
+void
+refineAndRestartLift (const CanonicalForm& F, const mat_zz_pE& NTLN, int
+                      liftBound, int l, CFList& factors, CFMatrix& M, CFArray&
+                      Pi, CFList& diophant
+                     )
+{
+  CFList bufFactors;
+  Variable y= Variable (2);
+  CanonicalForm LCF= LC (F, 1);
+  CFListIterator iter;
+  CanonicalForm buf;
+  for (long i= 1; i <= NTLN.NumCols(); i++)
+  {
+    iter= factors;
+    buf= 1;
+    for (long j= 1; j <= NTLN.NumRows(); j++, iter++)
+    {
+      if (!IsZero (NTLN (j,i)))
+        buf= mulNTL (buf, mod (iter.getItem(), y));
+    }
+    bufFactors.append (buf);
+  }
+  factors= bufFactors;
+  M= CFMatrix (liftBound, factors.length());
+  Pi= CFArray();
+  diophant= CFList();
+  factors.insert (LCF);
+  henselLift12 (F, factors, l, Pi, diophant, M);
+}
+
+#ifdef HAVE_FLINT
+CFList
+earlyReconstructionAndLifting (const CanonicalForm& F, const nmod_mat_t N,
+                               CanonicalForm& bufF, CFList& factors, int& l,
+                               int& factorsFound, bool beenInThres, CFMatrix& M,
+                               CFArray& Pi, CFList& diophant, bool symmetric,
+                               const CanonicalForm& evaluation
+                              )
+#else
+CFList
+earlyReconstructionAndLifting (const CanonicalForm& F, const mat_zz_p& N,
+                               CanonicalForm& bufF, CFList& factors, int& l,
+                               int& factorsFound, bool beenInThres, CFMatrix& M,
+                               CFArray& Pi, CFList& diophant, bool symmetric,
+                               const CanonicalForm& evaluation
+                              )
+#endif
+{
+  int sizeOfLiftPre;
+  int * liftPre= getLiftPrecisions (F, sizeOfLiftPre, degree (LC (F, 1), 2));
+
+  Variable y= F.mvar();
+  factorsFound= 0;
+  CanonicalForm LCF= LC (F, 1);
+  CFList result;
+  int smallFactorDeg= tmin (11, liftPre [sizeOfLiftPre- 1] + 1);
+#ifdef HAVE_FLINT
+  nmod_mat_t FLINTN;
+  nmod_mat_init_set (FLINTN, N);
+  int * factorsFoundIndex= new int [nmod_mat_ncols (FLINTN)];
+  for (long i= 0; i < nmod_mat_ncols (FLINTN); i++)
+#else
+  mat_zz_p NTLN= N;
+  int * factorsFoundIndex= new int [NTLN.NumCols()];
+  for (long i= 0; i < NTLN.NumCols(); i++)
+#endif
+    factorsFoundIndex [i]= 0;
+
+  if (degree (F) + 1 > smallFactorDeg)
+  {
+    if (l < smallFactorDeg)
+    {
+      TIMING_START (fac_fq_lift);
+      factors.insert (LCF);
+      henselLiftResume12 (F, factors, l, smallFactorDeg, Pi, diophant, M);
+      TIMING_END_AND_PRINT (fac_fq_lift, "time to lift in reconstruction0: ");
+      l= smallFactorDeg;
+    }
+#ifdef HAVE_FLINT
+    TIMING_START (fac_fq_reconstruction);
+    reconstructionTry (result, bufF, factors, smallFactorDeg, factorsFound,
+                       factorsFoundIndex, FLINTN, evaluation, beenInThres
+                      );
+    TIMING_END_AND_PRINT (fac_fq_reconstruction, "time to reconstruct0: ");
+    if (result.length() == nmod_mat_ncols (FLINTN))
+    {
+      nmod_mat_clear (FLINTN);
+#else
+    TIMING_START (fac_fq_reconstruction);
+    reconstructionTry (result, bufF, factors, smallFactorDeg, factorsFound,
+                       factorsFoundIndex, NTLN, evaluation, beenInThres
+                      );
+    TIMING_END_AND_PRINT (fac_fq_reconstruction, "time to reconstruct0: ");
+    if (result.length() == NTLN.NumCols())
+    {
+#endif
+      delete [] liftPre;
+      delete [] factorsFoundIndex;
+      return result;
+    }
+  }
+
+  int i= sizeOfLiftPre - 1;
+  int dummy= 1;
+  if (sizeOfLiftPre > 1 && sizeOfLiftPre < 30)
+  {
+    while (i > 0)
+    {
+      if (l < liftPre[i-1] + 1)
+      {
+        factors.insert (LCF);
+        TIMING_START (fac_fq_lift);
+        henselLiftResume12 (F, factors, l, liftPre[i-1] + 1, Pi, diophant, M);
+        TIMING_END_AND_PRINT (fac_fq_lift, "time to lift in reconstruction1: ");
+        l= liftPre[i-1] + 1;
+      }
+      else
+      {
+        i--;
+        if (i != 0)
+          continue;
+      }
+#ifdef HAVE_FLINT
+      TIMING_START (fac_fq_reconstruction);
+      reconstructionTry (result, bufF, factors, l, factorsFound,
+                         factorsFoundIndex, FLINTN, evaluation, beenInThres
+                        );
+      TIMING_END_AND_PRINT (fac_fq_reconstruction, "time to reconstruct1: ");
+      if (result.length() == nmod_mat_ncols (FLINTN))
+      {
+        nmod_mat_clear (FLINTN);
+#else
+      TIMING_START (fac_fq_reconstruction);
+      reconstructionTry (result, bufF, factors, l, factorsFound,
+                         factorsFoundIndex, NTLN, evaluation, beenInThres
+                        );
+      TIMING_END_AND_PRINT (fac_fq_reconstruction, "time to reconstruct1: ");
+      if (result.length() == NTLN.NumCols())
+      {
+#endif
+        delete [] liftPre;
+        delete [] factorsFoundIndex;
+        return result;
+      }
+      i--;
+    }
+  }
+  else
+  {
+    i= 1;
+    while (((degree (F,y)/4)*i+1) + 4 <= smallFactorDeg)
+      i++;
+    while (i < 5)
+    {
+      dummy= tmin (degree (F,y)+1, ((degree (F,y)/4)+1)*i+4);
+      if (l < dummy)
+      {
+        factors.insert (LCF);
+        TIMING_START (fac_fq_lift);
+        henselLiftResume12 (F, factors, l, dummy, Pi, diophant, M);
+        TIMING_END_AND_PRINT (fac_fq_lift, "time to lift in reconstruction2: ");
+        l= dummy;
+        if (i == 1 && degree (F)%4==0 && symmetric && factors.length() == 2 &&
+            LC (F,1).inCoeffDomain() &&
+           (degree (factors.getFirst(), 1) == degree (factors.getLast(),1)))
+        {
+          Variable x= Variable (1);
+          CanonicalForm g, h, gg, hh, multiplier1, multiplier2, check1, check2;
+          int m= degree (F)/4+1;
+          g= factors.getFirst();
+          h= factors.getLast();
+          g= mod (g, power (y,m));
+          h= mod (h, power (y,m));
+          g= g (y-evaluation, y);
+          h= h (y-evaluation, y);
+          gg= mod (swapvar (g,x,y),power (x,m));
+          gg= gg (y + evaluation, y);
+          multiplier1= factors.getLast()[m-1][0]/gg[m-1][0];
+          gg= div (gg, power (y,m));
+          gg= gg*power (y,m);
+          hh= mod (swapvar (h,x,y),power (x,m));
+          hh= hh (y + evaluation, y);
+          multiplier2= factors.getFirst()[m-1][0]/hh[m-1][0];
+          hh= div (hh, power (y,m));
+          hh= hh*power (y,m);
+          gg= multiplier1*gg+mod (factors.getLast(), power (y,m));
+          hh= multiplier2*hh+mod (factors.getFirst(), power (y,m));
+          check1= gg (y-evaluation,y);
+          check2= hh (y-evaluation,y);
+          CanonicalForm oldcheck1= check1;
+          check1= swapvar (check1, x, y);
+          if (check1/Lc (check1) == check2/Lc (check2))
+          {
+#ifdef HAVE_FLINT
+            nmod_mat_clear (FLINTN);
+#endif
+            result.append (oldcheck1);
+            result.append (check2);
+            delete [] liftPre;
+            delete [] factorsFoundIndex;
+            return result;
+          }
+        }
+      }
+      else
+      {
+        i++;
+        if (i < 5)
+          continue;
+      }
+#ifdef HAVE_FLINT
+      TIMING_START (fac_fq_reconstruction);
+      reconstructionTry (result, bufF, factors, l, factorsFound,
+                         factorsFoundIndex, FLINTN, evaluation, beenInThres
+                        );
+      TIMING_END_AND_PRINT (fac_fq_reconstruction, "time to reconstruct2: ");
+      if (result.length() == nmod_mat_ncols (FLINTN))
+      {
+        nmod_mat_clear (FLINTN);
+#else
+      TIMING_START (fac_fq_reconstruction);
+      reconstructionTry (result, bufF, factors, l, factorsFound,
+                         factorsFoundIndex, NTLN, evaluation, beenInThres
+                        );
+      TIMING_END_AND_PRINT (fac_fq_reconstruction, "time to reconstruct2: ");
+      if (result.length() == NTLN.NumCols())
+      {
+#endif
+        delete [] liftPre;
+        delete [] factorsFoundIndex;
+        return result;
+      }
+      i++;
+    }
+  }
+
+#ifdef HAVE_FLINT
+  nmod_mat_clear (FLINTN);
+#endif
+  delete [] liftPre;
+  delete [] factorsFoundIndex;
+  return result;
+}
+
+CFList
+earlyReconstructionAndLifting (const CanonicalForm& F, const mat_zz_pE& N,
+                               CanonicalForm& bufF, CFList& factors, int& l,
+                               int& factorsFound, bool beenInThres, CFMatrix& M,
+                               CFArray& Pi, CFList& diophant, bool symmetric,
+                               const CanonicalForm& evaluation
+                              )
+{
+  int sizeOfLiftPre;
+  int * liftPre= getLiftPrecisions (F, sizeOfLiftPre, degree (LC (F, 1), 2));
+  Variable y= F.mvar();
+  factorsFound= 0;
+  CanonicalForm LCF= LC (F, 1);
+  CFList result;
+  int smallFactorDeg= 11;
+  mat_zz_pE NTLN= N;
+  int * factorsFoundIndex= new int [NTLN.NumCols()];
+  for (long i= 0; i < NTLN.NumCols(); i++)
+    factorsFoundIndex [i]= 0;
+
+  if (degree (F) + 1 > smallFactorDeg)
+  {
+    if (l < smallFactorDeg)
+    {
+      TIMING_START (fac_fq_lift);
+      factors.insert (LCF);
+      henselLiftResume12 (F, factors, l, smallFactorDeg, Pi, diophant, M);
+      TIMING_END_AND_PRINT (fac_fq_lift, "time to lift in reconstruction0: ");
+      l= smallFactorDeg;
+    }
+    TIMING_START (fac_fq_reconstruction);
+    reconstructionTry (result, bufF, factors, smallFactorDeg, factorsFound,
+                       factorsFoundIndex, NTLN, evaluation, beenInThres
+                      );
+    TIMING_END_AND_PRINT (fac_fq_reconstruction, "time to reconstruct0: ");
+    if (result.length() == NTLN.NumCols())
+    {
+      delete [] liftPre;
+      delete [] factorsFoundIndex;
+      return result;
+    }
+  }
+
+  int i= sizeOfLiftPre - 1;
+  int dummy= 1;
+  if (sizeOfLiftPre > 1 && sizeOfLiftPre < 30)
+  {
+    while (i > 0)
+    {
+      if (l < liftPre[i-1] + 1)
+      {
+        factors.insert (LCF);
+        TIMING_START (fac_fq_lift);
+        henselLiftResume12 (F, factors, l, liftPre[i-1] + 1, Pi, diophant, M);
+        TIMING_END_AND_PRINT (fac_fq_lift, "time to lift in reconstruction1: ");
+        l= liftPre[i-1] + 1;
+      }
+      else
+      {
+        i--;
+        if (i != 0)
+          continue;
+      }
+      TIMING_START (fac_fq_reconstruction);
+      reconstructionTry (result, bufF, factors, l, factorsFound,
+                         factorsFoundIndex, NTLN, evaluation, beenInThres
+                        );
+      TIMING_END_AND_PRINT (fac_fq_reconstruction, "time to reconstruct1: ");
+      if (result.length() == NTLN.NumCols())
+      {
+        delete [] liftPre;
+        delete [] factorsFoundIndex;
+        return result;
+      }
+      i--;
+    }
+  }
+  else
+  {
+    i= 1;
+    while ((degree (F,y)/4+1)*i + 4 <= smallFactorDeg)
+      i++;
+    while (i < 5)
+    {
+      dummy= tmin (degree (F,y)+1, (degree (F,y)/4+1)*i+4);
+      if (l < dummy)
+      {
+        factors.insert (LCF);
+        TIMING_START (fac_fq_lift);
+        henselLiftResume12 (F, factors, l, dummy, Pi, diophant, M);
+        TIMING_END_AND_PRINT (fac_fq_lift, "time to lift in reconstruction2: ");
+        l= dummy;
+        if (i == 1 && degree (F)%4==0 && symmetric && factors.length() == 2 &&
+            LC (F,1).inCoeffDomain() &&
+           (degree (factors.getFirst(), 1) == degree (factors.getLast(),1)))
+        {
+          Variable x= Variable (1);
+          CanonicalForm g, h, gg, hh, multiplier1, multiplier2, check1, check2;
+          int m= degree (F)/4+1;
+          g= factors.getFirst();
+          h= factors.getLast();
+          g= mod (g, power (y,m));
+          h= mod (h, power (y,m));
+          g= g (y-evaluation, y);
+          h= h (y-evaluation, y);
+          gg= mod (swapvar (g,x,y),power (x,m));
+          gg= gg (y + evaluation, y);
+          multiplier1= factors.getLast()[m-1][0]/gg[m-1][0];
+          gg= div (gg, power (y,m));
+          gg= gg*power (y,m);
+          hh= mod (swapvar (h,x,y),power (x,m));
+          hh= hh (y + evaluation, y);
+          multiplier2= factors.getFirst()[m-1][0]/hh[m-1][0];
+          hh= div (hh, power (y,m));
+          hh= hh*power (y,m);
+          gg= multiplier1*gg+mod (factors.getLast(), power (y,m));
+          hh= multiplier2*hh+mod (factors.getFirst(), power (y,m));
+          check1= gg (y-evaluation,y);
+          check2= hh (y-evaluation,y);
+          CanonicalForm oldcheck1= check1;
+          check1= swapvar (check1, x, y);
+          if (check1/Lc (check1) == check2/Lc (check2))
+          {
+            result.append (oldcheck1);
+            result.append (check2);
+            delete [] liftPre;
+            delete [] factorsFoundIndex;
+            return result;
+          }
+        }
+      }
+      else
+      {
+        i++;
+        if (i < 5)
+          continue;
+      }
+      TIMING_START (fac_fq_reconstruction);
+      reconstructionTry (result, bufF, factors, l, factorsFound,
+                         factorsFoundIndex, NTLN, evaluation, beenInThres
+                        );
+      TIMING_END_AND_PRINT (fac_fq_reconstruction, "time to reconstruct2: ");
+      if (result.length() == NTLN.NumCols())
+      {
+        delete [] liftPre;
+        delete [] factorsFoundIndex;
+        return result;
+      }
+      i++;
+    }
+  }
+
+  delete [] liftPre;
+  delete [] factorsFoundIndex;
+  return result;
+}
+
+//over field extension
+#ifdef HAVE_FLINT
+CFList
+extEarlyReconstructionAndLifting (const CanonicalForm& F, const nmod_mat_t N,
+                                  CanonicalForm& bufF, CFList& factors, int& l,
+                                  int& factorsFound, bool beenInThres, CFMatrix&
+                                  M, CFArray& Pi, CFList& diophant, const
+                                  ExtensionInfo& info, const CanonicalForm&
+                                  evaluation
+                                 )
+#else
+CFList
+extEarlyReconstructionAndLifting (const CanonicalForm& F, const mat_zz_p& N,
+                                  CanonicalForm& bufF, CFList& factors, int& l,
+                                  int& factorsFound, bool beenInThres, CFMatrix&
+                                  M, CFArray& Pi, CFList& diophant, const
+                                  ExtensionInfo& info, const CanonicalForm&
+                                  evaluation
+                                 )
+#endif
+{
+  int sizeOfLiftPre;
+  int * liftPre= getLiftPrecisions (F, sizeOfLiftPre, degree (LC (F, 1), 2));
+  Variable y= F.mvar();
+  factorsFound= 0;
+  CanonicalForm LCF= LC (F, 1);
+  CFList result;
+  int smallFactorDeg= 11;
+#ifdef HAVE_FLINT
+  nmod_mat_t FLINTN;
+  nmod_mat_init_set (FLINTN, N);
+  int * factorsFoundIndex= new int [nmod_mat_ncols (FLINTN)];
+  for (long i= 0; i < nmod_mat_ncols (FLINTN); i++)
+#else
+  mat_zz_p NTLN= N;
+  int * factorsFoundIndex= new int [NTLN.NumCols()];
+  for (long i= 0; i < NTLN.NumCols(); i++)
+#endif
+    factorsFoundIndex [i]= 0;
+
+  if (degree (F) + 1 > smallFactorDeg)
+  {
+    if (l < smallFactorDeg)
+    {
+      TIMING_START (fac_fq_lift);
+      factors.insert (LCF);
+      henselLiftResume12 (F, factors, l, smallFactorDeg, Pi, diophant, M);
+      TIMING_END_AND_PRINT (fac_fq_lift, "time to lift in reconstruction0: ");
+      l= smallFactorDeg;
+    }
+    TIMING_START (fac_fq_reconstruction);
+#ifdef HAVE_FLINT
+    extReconstructionTry (result, bufF, factors, smallFactorDeg, factorsFound,
+                          factorsFoundIndex, FLINTN, beenInThres, info,
+                          evaluation
+                      );
+#else
+    extReconstructionTry (result, bufF, factors, smallFactorDeg, factorsFound,
+                          factorsFoundIndex, NTLN, beenInThres, info,
+                          evaluation
+                      );
+#endif
+    TIMING_END_AND_PRINT (fac_fq_reconstruction, "time to reconstruct0: ");
+#ifdef HAVE_FLINT
+    if (result.length() == nmod_mat_ncols (FLINTN))
+    {
+      nmod_mat_clear (FLINTN);
+#else
+    if (result.length() == NTLN.NumCols())
+    {
+#endif
+      delete [] liftPre;
+      delete [] factorsFoundIndex;
+      return result;
+    }
+  }
+
+  int i= sizeOfLiftPre - 1;
+  int dummy= 1;
+  if (sizeOfLiftPre > 1 && sizeOfLiftPre < 30)
+  {
+    while (i > 0)
+    {
+      if (l < liftPre[i-1] + 1)
+      {
+        factors.insert (LCF);
+        TIMING_START (fac_fq_lift);
+        henselLiftResume12 (F, factors, l, liftPre[i-1] + 1, Pi, diophant, M);
+        TIMING_END_AND_PRINT (fac_fq_lift, "time to lift in reconstruction1: ");
+        l= liftPre[i-1] + 1;
+      }
+      else
+      {
+        i--;
+        if (i != 0)
+          continue;
+      }
+      TIMING_START (fac_fq_reconstruction);
+#ifdef HAVE_FLINT
+      extReconstructionTry (result, bufF, factors, l, factorsFound,
+                            factorsFoundIndex, FLINTN, beenInThres, info,
+                            evaluation
+                           );
+#else
+      extReconstructionTry (result, bufF, factors, l, factorsFound,
+                            factorsFoundIndex, NTLN, beenInThres, info,
+                            evaluation
+                           );
+#endif
+      TIMING_END_AND_PRINT (fac_fq_reconstruction, "time to reconstruct1: ");
+#ifdef HAVE_FLINT
+      if (result.length() == nmod_mat_ncols (FLINTN))
+      {
+        nmod_mat_clear (FLINTN);
+#else
+      if (result.length() == NTLN.NumCols())
+      {
+#endif
+        delete [] liftPre;
+        delete [] factorsFoundIndex;
+        return result;
+      }
+      i--;
+    }
+  }
+  else
+  {
+    i= 1;
+    while ((degree (F,y)/4+1)*i + 4 <= smallFactorDeg)
+      i++;
+    while (i < 5)
+    {
+      dummy= tmin (degree (F,y)+1, (degree (F,y)/4+1)*i+4);
+      if (l < dummy)
+      {
+        factors.insert (LCF);
+        TIMING_START (fac_fq_lift);
+        henselLiftResume12 (F, factors, l, dummy, Pi, diophant, M);
+        TIMING_END_AND_PRINT (fac_fq_lift, "time to lift in reconstruction2: ");
+        l= dummy;
+      }
+      else
+      {
+        i++;
+        if (i < 5)
+          continue;
+      }
+      TIMING_START (fac_fq_reconstruction);
+#ifdef HAVE_FLINT
+      extReconstructionTry (result, bufF, factors, l, factorsFound,
+                            factorsFoundIndex, FLINTN, beenInThres, info,
+                            evaluation
+                           );
+#else
+      extReconstructionTry (result, bufF, factors, l, factorsFound,
+                            factorsFoundIndex, NTLN, beenInThres, info,
+                            evaluation
+                           );
+#endif
+      TIMING_END_AND_PRINT (fac_fq_reconstruction, "time to reconstruct2: ");
+#ifdef HAVE_FLINT
+      if (result.length() == nmod_mat_ncols (FLINTN))
+      {
+        nmod_mat_clear (FLINTN);
+#else
+      if (result.length() == NTLN.NumCols())
+      {
+#endif
+        delete [] liftPre;
+        delete [] factorsFoundIndex;
+        return result;
+      }
+      i++;
+    }
+  }
+
+#ifdef HAVE_FLINT
+  nmod_mat_clear (FLINTN);
+#endif
+  delete [] liftPre;
+  delete [] factorsFoundIndex;
+  return result;
+}
+
+CFList
+sieveSmallFactors (const CanonicalForm& G, CFList& uniFactors, DegreePattern&
+                   degPat, CanonicalForm& H, CFList& diophant, CFArray& Pi,
+                   CFMatrix& M, bool& success, int d, const CanonicalForm& eval
+                  )
+{
+  CanonicalForm F= G;
+  CFList bufUniFactors= uniFactors;
+  bufUniFactors.insert (LC (F, 1));
+  int smallFactorDeg= d;
+  DegreePattern degs= degPat;
+  henselLift12 (F, bufUniFactors, smallFactorDeg, Pi, diophant, M);
+  int adaptedLiftBound;
+  success= false;
+  int * factorsFoundIndex= new int [uniFactors.length()];
+  for (int i= 0; i < uniFactors.length(); i++)
+    factorsFoundIndex [i]= 0;
+  CFList earlyFactors;
+  earlyFactorDetection (earlyFactors, F, bufUniFactors, adaptedLiftBound,
+                        factorsFoundIndex, degs, success, smallFactorDeg, eval);
+  delete [] factorsFoundIndex;
+  if (degs.getLength() == 1)
+  {
+    degPat= degs;
+    return earlyFactors;
+  }
+  if (success)
+  {
+    H= F;
+    return earlyFactors;
+  }
+  int sizeOldF= size (G);
+  if (size (F) < sizeOldF)
+  {
+    H= F;
+    success= true;
+    return earlyFactors;
+  }
+  else
+  {
+    uniFactors= bufUniFactors;
+    return CFList();
+  }
+}
+
+CFList
+extSieveSmallFactors (const CanonicalForm& G, CFList& uniFactors, DegreePattern&
+                      degPat, CanonicalForm& H, CFList& diophant, CFArray& Pi,
+                      CFMatrix& M, bool& success, int d, const CanonicalForm&
+                      evaluation, const ExtensionInfo& info
+                     )
+{
+  CanonicalForm F= G;
+  CFList bufUniFactors= uniFactors;
+  bufUniFactors.insert (LC (F, 1));
+  int smallFactorDeg= d;
+  DegreePattern degs= degPat;
+  henselLift12 (F, bufUniFactors, smallFactorDeg, Pi, diophant, M);
+  int adaptedLiftBound;
+  success= false;
+  int * factorsFoundIndex= new int [uniFactors.length()];
+  for (int i= 0; i < uniFactors.length(); i++)
+    factorsFoundIndex [i]= 0;
+  CFList earlyFactors;
+  extEarlyFactorDetection (earlyFactors, F, bufUniFactors, adaptedLiftBound,
+                           factorsFoundIndex, degs, success, info, evaluation,
+                           smallFactorDeg);
+  delete [] factorsFoundIndex;
+  if (degs.getLength() == 1)
+  {
+    degPat= degs;
+    return earlyFactors;
+  }
+  if (success)
+  {
+    H= F;
+    return earlyFactors;
+  }
+  Variable y= F.mvar();
+  int sizeOldF= size (G);
+  if (size (F) < sizeOldF)
+  {
+    H= F;
+    success= true;
+    return earlyFactors;
+  }
+  else
+  {
+    uniFactors= bufUniFactors;
+    return CFList();
+  }
+}
+
+CFList
+henselLiftAndLatticeRecombi (const CanonicalForm& G, const CFList& uniFactors,
+                             const Variable& alpha, const DegreePattern& degPat,
+                             bool symmetric, const CanonicalForm& eval
+                            )
+{
+  DegreePattern degs= degPat;
+  CanonicalForm F= G;
+  CanonicalForm LCF= LC (F, 1);
+  Variable y= F.mvar();
+  Variable x= Variable (1);
+  int d;
+  bool isIrreducible= false;
+  int* bounds= computeBounds (F, d, isIrreducible);
+  if (isIrreducible)
+  {
+    delete [] bounds;
+    return CFList (G);
+  }
+  int minBound= bounds[0];
+  for (int i= 1; i < d; i++)
+  {
+    if (bounds[i] != 0)
+      minBound= tmin (minBound, bounds[i]);
+  }
+
+  CFList bufUniFactors= uniFactors;
+  CFArray Pi;
+  CFList diophant;
+  int liftBound= 2*totaldegree (F) - 1;
+  CFMatrix M= CFMatrix (liftBound, bufUniFactors.length());
+
+  CFList smallFactors;
+  CanonicalForm H;
+  bool success= false;
+  smallFactors= sieveSmallFactors (F, bufUniFactors, degs, H, diophant, Pi, M,
+                                   success, minBound + 1, eval
+                                  );
+
+  if (smallFactors.length() > 0)
+  {
+    if (smallFactors.length() == 1)
+    {
+      if (smallFactors.getFirst() == F)
+      {
+        delete [] bounds;
+        return CFList (G (y-eval,y));
+      }
+    }
+    if (degs.getLength() <= 1)
+    {
+      delete [] bounds;
+      return smallFactors;
+    }
+  }
+
+  int index;
+  CanonicalForm tmp1, tmp2;
+  for (CFListIterator i= smallFactors; i.hasItem(); i++)
+  {
+    index= 1;
+    tmp1= mod (i.getItem(),y-eval);
+    tmp1 /= Lc (tmp1);
+    for (CFListIterator j= bufUniFactors; j.hasItem(); j++, index++)
+    {
+      tmp2= mod (j.getItem(), y);
+      tmp2 /= Lc (tmp2);
+      if (tmp1 == tmp2)
+      {
+        index++;
+        j.remove(index);
+        break;
+      }
+    }
+  }
+
+  if (bufUniFactors.isEmpty())
+  {
+    delete [] bounds;
+    return smallFactors;
+  }
+
+  if (success)
+  {
+    F= H;
+    delete [] bounds;
+    bounds= computeBounds (F, d, isIrreducible);
+    if (isIrreducible)
+    {
+      smallFactors.append (F (y-eval,y));
+      delete [] bounds;
+      return smallFactors;
+    }
+    LCF= LC (F, 1);
+
+    minBound= bounds[0];
+    for (int i= 1; i < d; i++)
+    {
+      if (bounds[i] != 0)
+        minBound= tmin (minBound, bounds[i]);
+    }
+    Pi= CFArray();
+    diophant= CFList();
+    liftBound= 2*totaldegree (F) - 1;
+    M= CFMatrix (liftBound, bufUniFactors.length());
+    DegreePattern bufDegs= DegreePattern (bufUniFactors);
+    degs.intersect (bufDegs);
+    degs.refine();
+    if (degs.getLength() <= 1)
+    {
+      smallFactors.append (F (y-eval,y));
+      delete [] bounds;
+      return smallFactors;
+    }
+  }
+
+  bool reduceFq2Fp= (degree (F) > getCharacteristic());
+  bufUniFactors.insert (LCF);
+  int l= 1;
+
+#ifdef HAVE_FLINT
+  nmod_mat_t FLINTN;
+#else
+  if (fac_NTL_char != getCharacteristic())
+  {
+    fac_NTL_char= getCharacteristic();
+    zz_p::init (getCharacteristic());
+  }
+  mat_zz_p NTLN;
+#endif
+
+  if (alpha.level() != 1)
+  {
+    zz_pX NTLMipo= convertFacCF2NTLzzpX (getMipo (alpha));
+    zz_pE::init (NTLMipo);
+  }
+  mat_zz_pE NTLNe;
+  if (alpha.level() == 1)
+  {
+#ifdef HAVE_FLINT
+    nmod_mat_init (FLINTN, bufUniFactors.length()-1, bufUniFactors.length()-1, getCharacteristic());
+    for (long i= bufUniFactors.length()-2; i >= 0; i--)
+      nmod_mat_entry (FLINTN, i, i)= 1;
+#else
+    ident (NTLN, bufUniFactors.length() - 1);
+#endif
+  }
+  else
+  {
+    if (reduceFq2Fp)
+#ifdef HAVE_FLINT
+    {
+      nmod_mat_init (FLINTN, bufUniFactors.length()-1, bufUniFactors.length()-1, getCharacteristic());
+      for (long i= bufUniFactors.length()-2; i >= 0; i--)
+        nmod_mat_entry (FLINTN, i, i)= 1;
+    }
+#else
+      ident (NTLN, bufUniFactors.length() - 1);
+#endif
+    else
+      ident (NTLNe, bufUniFactors.length() - 1);
+  }
+  bool irreducible= false;
+  CFArray bufQ= CFArray (bufUniFactors.length() - 1);
+
+  int oldL;
+  TIMING_START (fac_fq_till_reduced);
+  if (success)
+  {
+    int start= 0;
+    if (alpha.level() == 1)
+      oldL= liftAndComputeLattice (F, bounds, d, start, liftBound, minBound,
+#ifdef HAVE_FLINT
+                                   bufUniFactors, FLINTN, diophant, M, Pi, bufQ,
+#else
+                                   bufUniFactors, NTLN, diophant, M, Pi, bufQ,
+#endif
+                                   irreducible
+                                  );
+    else
+    {
+      if (reduceFq2Fp)
+        oldL= liftAndComputeLatticeFq2Fp (F, bounds, d, start, liftBound,
+#ifdef HAVE_FLINT
+                                          minBound, bufUniFactors, FLINTN,
+#else
+                                          minBound, bufUniFactors, NTLN,
+#endif
+                                          diophant, M, Pi, bufQ, irreducible,
+                                          alpha
+                                         );
+      else
+        oldL= liftAndComputeLattice (F, bounds, d, start, liftBound, minBound,
+                                    bufUniFactors, NTLNe, diophant, M, Pi, bufQ,
+                                    irreducible
+                                    );
+    }
+  }
+  else
+  {
+    if (alpha.level() == 1)
+    {
+      oldL= liftAndComputeLattice (F, bounds, d, minBound + 1, liftBound,
+#ifdef HAVE_FLINT
+                                   minBound, bufUniFactors, FLINTN, diophant, M,
+#else
+                                   minBound, bufUniFactors, NTLN, diophant, M,
+#endif
+                                   Pi, bufQ, irreducible
+                                  );
+    }
+    else
+    {
+      if (reduceFq2Fp)
+        oldL= liftAndComputeLatticeFq2Fp (F, bounds, d, minBound + 1,
+                                          liftBound, minBound, bufUniFactors,
+#ifdef HAVE_FLINT
+                                          FLINTN, diophant, M, Pi, bufQ,
+#else
+                                          NTLN, diophant, M, Pi, bufQ,
+#endif
+                                          irreducible, alpha
+                                         );
+      else
+        oldL= liftAndComputeLattice (F, bounds, d, minBound + 1, liftBound,
+                                     minBound, bufUniFactors, NTLNe, diophant,
+                                     M, Pi, bufQ, irreducible
+                                    );
+    }
+  }
+
+  TIMING_END_AND_PRINT (fac_fq_till_reduced,
+                        "time to compute a reduced lattice: ");
+  bufUniFactors.removeFirst();
+  if (oldL > liftBound)
+  {
+#ifdef HAVE_FLINT
+    if (alpha.level() == 1 || (alpha.level() != 1 && reduceFq2Fp))
+      nmod_mat_clear (FLINTN);
+#endif
+    delete [] bounds;
+    return Union (smallFactors,
+                  factorRecombination (bufUniFactors, F,
+                                       power (y, degree (F) + 1),
+                                       degs, eval, 1, bufUniFactors.length()/2
+                                      )
+                 );
+  }
+
+  l= oldL;
+  if (irreducible)
+  {
+#ifdef HAVE_FLINT
+    if (alpha.level() == 1 || (alpha.level() != 1 && reduceFq2Fp))
+      nmod_mat_clear (FLINTN);
+#endif
+    delete [] bounds;
+    return Union (CFList (F(y-eval,y)), smallFactors);
+  }
+
+  CanonicalForm yToL= power (y,l);
+
+  CFList result;
+  if (l >= degree (F) + 1)
+  {
+    int * factorsFoundIndex;
+    if (alpha.level() == 1 || (alpha.level() != 1 && reduceFq2Fp))
+    {
+#ifdef HAVE_FLINT
+      factorsFoundIndex= new int [nmod_mat_ncols (FLINTN)];
+      for (long i= 0; i < nmod_mat_ncols (FLINTN); i++)
+#else
+      factorsFoundIndex= new int [NTLN.NumCols()];
+      for (long i= 0; i < NTLN.NumCols(); i++)
+#endif
+        factorsFoundIndex[i]= 0;
+    }
+    else
+    {
+      factorsFoundIndex= new int [NTLNe.NumCols()];
+      for (long i= 0; i < NTLNe.NumCols(); i++)
+        factorsFoundIndex[i]= 0;
+    }
+    int factorsFound= 0;
+    CanonicalForm bufF= F;
+    if (alpha.level() == 1 || (alpha.level() != 1 && reduceFq2Fp))
+      reconstructionTry (result, bufF, bufUniFactors, degree (F) + 1,
+#ifdef HAVE_FLINT
+                         factorsFound, factorsFoundIndex, FLINTN, eval, false
+#else
+                         factorsFound, factorsFoundIndex, NTLN, eval, false
+#endif
+                        );
+    else
+        reconstructionTry (result, bufF, bufUniFactors, degree (F) + 1,
+                           factorsFound, factorsFoundIndex, NTLNe, eval, false
+                          );
+    if (alpha.level() == 1 || (alpha.level() != 1 && reduceFq2Fp))
+    {
+#ifdef HAVE_FLINT
+      if (result.length() == nmod_mat_ncols (FLINTN))
+      {
+        if (alpha.level() == 1 || (alpha.level() != 1 && reduceFq2Fp))
+          nmod_mat_clear (FLINTN);
+#else
+      if (result.length() == NTLN.NumCols())
+      {
+#endif
+        delete [] factorsFoundIndex;
+        delete [] bounds;
+        return Union (result, smallFactors);
+      }
+    }
+    else
+    {
+      if (result.length() == NTLNe.NumCols())
+      {
+        delete [] factorsFoundIndex;
+        delete [] bounds;
+        return Union (result, smallFactors);
+      }
+    }
+    delete [] factorsFoundIndex;
+  }
+  if (l >= liftBound)
+  {
+    int * factorsFoundIndex;
+    if (alpha.level() == 1 || (alpha.level() != 1 && reduceFq2Fp))
+    {
+#ifdef HAVE_FLINT
+      factorsFoundIndex= new int [nmod_mat_ncols (FLINTN)];
+      for (long i= 0; i < nmod_mat_ncols (FLINTN); i++)
+#else
+      factorsFoundIndex= new int [NTLN.NumCols()];
+      for (long i= 0; i < NTLN.NumCols(); i++)
+#endif
+        factorsFoundIndex[i]= 0;
+    }
+    else
+    {
+      factorsFoundIndex= new int [NTLNe.NumCols()];
+      for (long i= 0; i < NTLNe.NumCols(); i++)
+        factorsFoundIndex[i]= 0;
+    }
+    CanonicalForm bufF= F;
+    int factorsFound= 0;
+    if (alpha.level() == 1 || (alpha.level() != 1 && reduceFq2Fp))
+      reconstructionTry (result, bufF, bufUniFactors, degree (F) + 1,
+#ifdef HAVE_FLINT
+                         factorsFound, factorsFoundIndex, FLINTN, eval, false
+#else
+                         factorsFound, factorsFoundIndex, NTLN, eval, false
+#endif
+                        );
+    else
+      reconstructionTry (result, bufF, bufUniFactors, degree (F) + 1,
+                         factorsFound, factorsFoundIndex, NTLNe, eval, false
+                        );
+    if (alpha.level() == 1 || (alpha.level() != 1 && reduceFq2Fp))
+    {
+#ifdef HAVE_FLINT
+      if (result.length() == nmod_mat_ncols(FLINTN))
+      {
+        nmod_mat_clear (FLINTN);
+#else
+      if (result.length() == NTLN.NumCols())
+      {
+#endif
+        delete [] factorsFoundIndex;
+        delete [] bounds;
+        return Union (result, smallFactors);
+      }
+    }
+    else
+    {
+      if (result.length() == NTLNe.NumCols())
+      {
+        delete [] factorsFoundIndex;
+        delete [] bounds;
+        return Union (result, smallFactors);
+      }
+    }
+    delete [] factorsFoundIndex;
+  }
+
+  result= CFList();
+  bool beenInThres= false;
+  int thres= 100;
+  if (l <= thres)
+  {
+    if (alpha.level() == 1 || (alpha.level() != 1 && reduceFq2Fp))
+    {
+#ifdef HAVE_FLINT
+      if (nmod_mat_ncols (FLINTN) < bufUniFactors.length())
+      {
+        refineAndRestartLift (F, FLINTN, liftBound, l, bufUniFactors, M, Pi,
+#else
+      if (NTLN.NumCols() < bufUniFactors.length())
+      {
+        refineAndRestartLift (F, NTLN, liftBound, l, bufUniFactors, M, Pi,
+#endif
+                              diophant
+                             );
+        beenInThres= true;
+      }
+    }
+    else
+    {
+      if (NTLNe.NumCols() < bufUniFactors.length())
+      {
+        refineAndRestartLift (F, NTLNe, liftBound, l, bufUniFactors, M, Pi,
+                              diophant
+                             );
+        beenInThres= true;
+      }
+    }
+  }
+
+  CanonicalForm bufF= F;
+  int factorsFound= 0;
+  if (alpha.level() == 1 || (alpha.level() != 1 && reduceFq2Fp))
+  {
+#ifdef HAVE_FLINT
+    result= earlyReconstructionAndLifting (F, FLINTN, bufF, bufUniFactors, l,
+#else
+    result= earlyReconstructionAndLifting (F, NTLN, bufF, bufUniFactors, l,
+#endif
+                                           factorsFound, beenInThres, M, Pi,
+                                           diophant, symmetric, eval
+                                          );
+
+#ifdef HAVE_FLINT
+    if (result.length() == nmod_mat_ncols (FLINTN))
+    {
+      nmod_mat_clear (FLINTN);
+#else
+    if (result.length() == NTLN.NumCols())
+    {
+#endif
+      delete [] bounds;
+      return Union (result, smallFactors);
+    }
+  }
+  else
+  {
+    result= earlyReconstructionAndLifting (F, NTLNe, bufF, bufUniFactors, l,
+                                           factorsFound, beenInThres, M, Pi,
+                                           diophant, symmetric, eval
+                                          );
+
+    if (result.length() == NTLNe.NumCols())
+    {
+      delete [] bounds;
+      return Union (result, smallFactors);
+    }
+  }
+
+  if (result.length() > 0)
+  {
+    if (beenInThres)
+    {
+      int index;
+      for (CFListIterator i= result; i.hasItem(); i++)
+      {
+        index= 1;
+        tmp1= mod (i.getItem(), y-eval);
+        tmp1 /= Lc (tmp1);
+        for (CFListIterator j= bufUniFactors; j.hasItem(); j++, index++)
+        {
+          tmp2= mod (j.getItem(), y);
+          tmp2 /= Lc (tmp2);
+          if (tmp1 == tmp2)
+          {
+            index++;
+            j.remove(index);
+            break;
+          }
+        }
+      }
+    }
+    else
+    {
+      int * zeroOne;
+      long numCols, numRows;
+      if (alpha.level() == 1 || (alpha.level() != 1 && reduceFq2Fp))
+      {
+#ifdef HAVE_FLINT
+        numCols= nmod_mat_ncols (FLINTN);
+        numRows= nmod_mat_nrows (FLINTN);
+        zeroOne= extractZeroOneVecs (FLINTN);
+#else
+        numCols= NTLN.NumCols();
+        numRows= NTLN.NumRows();
+        zeroOne= extractZeroOneVecs (NTLN);
+#endif
+      }
+      else
+      {
+        numCols= NTLNe.NumCols();
+        numRows= NTLNe.NumRows();
+        zeroOne= extractZeroOneVecs (NTLNe);
+      }
+      CFList bufBufUniFactors= bufUniFactors;
+      CFListIterator iter, iter2;
+      CanonicalForm buf;
+      CFList factorsConsidered;
+      CanonicalForm tmp;
+      for (int i= 0; i < numCols; i++)
+      {
+        if (zeroOne [i] == 0)
+          continue;
+        iter= bufUniFactors;
+        buf= 1;
+        factorsConsidered= CFList();
+        for (int j= 0; j < numRows; j++, iter++)
+        {
+          if (alpha.level() == 1 || (alpha.level() != 1 && reduceFq2Fp))
+          {
+#ifdef HAVE_FLINT
+            if (!(nmod_mat_entry (FLINTN, j,i) == 0))
+#else
+            if (!IsZero (NTLN (j + 1,i + 1)))
+#endif
+            {
+              factorsConsidered.append (iter.getItem());
+              buf *= mod (iter.getItem(), y);
+            }
+          }
+          else
+          {
+            if (!IsZero (NTLNe (j + 1,i + 1)))
+            {
+              factorsConsidered.append (iter.getItem());
+              buf *= mod (iter.getItem(), y);
+            }
+          }
+        }
+        buf /= Lc (buf);
+        for (iter2= result; iter2.hasItem(); iter2++)
+        {
+          tmp= mod (iter2.getItem(), y-eval);
+          tmp /= Lc (tmp);
+          if (tmp == buf)
+          {
+            bufBufUniFactors= Difference (bufBufUniFactors, factorsConsidered);
+            break;
+          }
+        }
+      }
+      bufUniFactors= bufBufUniFactors;
+      delete [] zeroOne;
+    }
+
+    int oldNumCols;
+    CFList resultBufF;
+    irreducible= false;
+
+    if (alpha.level() == 1)
+    {
+#ifdef HAVE_FLINT
+      oldNumCols= nmod_mat_ncols (FLINTN);
+#else
+      oldNumCols= NTLN.NumCols();
+#endif
+      resultBufF= increasePrecision (bufF, bufUniFactors, factorsFound,
+                                     oldNumCols, oldL, l, eval
+                                    );
+    }
+    else
+    {
+      if (reduceFq2Fp)
+      {
+#ifdef HAVE_FLINT
+        oldNumCols= nmod_mat_ncols (FLINTN);
+#else
+        oldNumCols= NTLN.NumCols();
+#endif
+
+        resultBufF= increasePrecisionFq2Fp (bufF, bufUniFactors, factorsFound,
+                                            oldNumCols, oldL, alpha, l, eval
+                                           );
+      }
+      else
+      {
+        oldNumCols= NTLNe.NumCols();
+
+        resultBufF= increasePrecision (bufF, bufUniFactors, factorsFound,
+                                       oldNumCols, oldL, alpha, l, eval
+                                      );
+      }
+    }
+
+    if (bufUniFactors.isEmpty() || degree (bufF) <= 0)
+    {
+#ifdef HAVE_FLINT
+      if (alpha.level() == 1 || (alpha.level() != 1 && reduceFq2Fp))
+        nmod_mat_clear (FLINTN);
+#endif
+      delete [] bounds;
+      result= Union (resultBufF, result);
+      return Union (result, smallFactors);
+    }
+
+    for (CFListIterator i= bufUniFactors; i.hasItem(); i++)
+      i.getItem()= mod (i.getItem(), y);
+
+    result= Union (result, resultBufF);
+    result= Union (result, smallFactors);
+    delete [] bounds;
+    DegreePattern bufDegs= DegreePattern (bufUniFactors);
+    degs.intersect (bufDegs);
+    degs.refine();
+    if (degs.getLength() == 1 || bufUniFactors.length() == 1)
+    {
+#ifdef HAVE_FLINT
+      if (alpha.level() == 1 || (alpha.level() != 1 && reduceFq2Fp))
+        nmod_mat_clear (FLINTN);
+#endif
+      result.append (bufF (y-eval,y));
+      return result;
+    }
+#ifdef HAVE_FLINT
+    if (alpha.level() == 1 || (alpha.level() != 1 && reduceFq2Fp))
+      nmod_mat_clear (FLINTN);
+#endif
+    return Union (result, henselLiftAndLatticeRecombi (bufF, bufUniFactors,
+                                                       alpha, degs, symmetric,
+                                                       eval
+                                                      )
+                 );
+  }
+
+  if (l < liftBound)
+  {
+    if (alpha.level() == 1)
+    {
+        result=increasePrecision (F, bufUniFactors, oldL, l, d, bounds, bufQ,
+#ifdef HAVE_FLINT
+                                  FLINTN, eval
+#else
+                                  NTLN, eval
+#endif
+                                 );
+    }
+    else
+    {
+      if (reduceFq2Fp)
+      {
+          result=increasePrecisionFq2Fp (F, bufUniFactors, oldL, l, d, bounds,
+#ifdef HAVE_FLINT
+                                         bufQ, FLINTN, alpha, eval
+#else
+                                         bufQ, NTLN, alpha, eval
+#endif
+                                        );
+      }
+      else
+      {
+          result=increasePrecision (F, bufUniFactors, oldL, l, d, bounds, bufQ,
+                                    NTLNe, eval
+                                   );
+      }
+    }
+    if (alpha.level() == 1 || (alpha.level() != 1 && reduceFq2Fp))
+    {
+#ifdef HAVE_FLINT
+      if (result.length()== nmod_mat_ncols (FLINTN))
+      {
+        nmod_mat_clear (FLINTN);
+#else
+      if (result.length()== NTLN.NumCols())
+      {
+#endif
+        delete [] bounds;
+        result= Union (result, smallFactors);
+        return result;
+      }
+    }
+    else
+    {
+      if (result.length()== NTLNe.NumCols())
+      {
+        delete [] bounds;
+        result= Union (result, smallFactors);
+        return result;
+      }
+    }
+
+    if (result.isEmpty())
+    {
+      if (alpha.level() == 1)
+        result= furtherLiftingAndIncreasePrecision (F,bufUniFactors, l,
+#ifdef HAVE_FLINT
+                                                    liftBound,d,bounds,FLINTN,
+#else
+                                                    liftBound, d, bounds, NTLN,
+#endif
+                                                    diophant, M, Pi, bufQ, eval
+                                                   );
+      else
+      {
+        if (reduceFq2Fp)
+          result= furtherLiftingAndIncreasePrecisionFq2Fp (F,bufUniFactors, l,
+                                                           liftBound, d, bounds,
+#ifdef HAVE_FLINT
+                                                           FLINTN, diophant, M,
+#else
+                                                           NTLN, diophant, M,
+#endif
+                                                           Pi, bufQ, alpha, eval
+                                                          );
+        else
+          result= furtherLiftingAndIncreasePrecision (F,bufUniFactors, l,
+                                                      liftBound, d, bounds,
+                                                      NTLNe, diophant, M,
+                                                      Pi, bufQ, eval
+                                                     );
+      }
+
+      if (alpha.level() == 1 || (alpha.level() != 1 && reduceFq2Fp))
+      {
+#ifdef HAVE_FLINT
+        if (result.length() == nmod_mat_ncols (FLINTN))
+        {
+          nmod_mat_clear (FLINTN);
+#else
+        if (result.length() == NTLN.NumCols())
+        {
+#endif
+          delete [] bounds;
+          result= Union (result, smallFactors);
+          return result;
+        }
+      }
+      else
+      {
+        if (result.length() == NTLNe.NumCols())
+        {
+          delete [] bounds;
+          result= Union (result, smallFactors);
+          return result;
+        }
+      }
+    }
+  }
+
+  DEBOUTLN (cerr, "lattice recombination failed");
+
+  DegreePattern bufDegs= DegreePattern (bufUniFactors);
+  degs.intersect (bufDegs);
+  degs.refine();
+
+  delete [] bounds;
+  bounds= computeBounds (F, d, isIrreducible);
+#ifdef HAVE_FLINT
+  if (alpha.level() == 1 || (alpha.level() != 1 && reduceFq2Fp))
+    nmod_mat_clear (FLINTN);
+#endif
+  if (isIrreducible)
+  {
+    delete [] bounds;
+    result= Union (result, smallFactors);
+    result.append (F (y-eval,y));
+    return result;
+  }
+  minBound= bounds[0];
+  for (int i= 1; i < d; i++)
+  {
+    if (bounds[i] != 0)
+      minBound= tmin (minBound, bounds[i]);
+  }
+
+  if (minBound > 16 || result.length() == 0)
+  {
+    result= Union (result, smallFactors);
+    CanonicalForm MODl= power (y, degree (F) + 1);
+    delete [] bounds;
+    return Union (result, factorRecombination (bufUniFactors, F, MODl, degs,
+                                               eval, 1, bufUniFactors.length()/2
+                                              )
+                 );
+  }
+  else
+  {
+    result= Union (result, smallFactors);
+    for (CFListIterator i= bufUniFactors; i.hasItem(); i++)
+      i.getItem()= mod (i.getItem(), y);
+    delete [] bounds;
+    return Union (result, henselLiftAndLatticeRecombi (F, bufUniFactors, alpha,
+                                                       degs,symmetric, eval
+                                                      )
+                 );
+  }
+}
+
+ExtensionInfo
+init4ext (const ExtensionInfo& info, const CanonicalForm& evaluation,
+          int& degMipo
+         )
+{
+  bool GF= (CFFactory::gettype() == GaloisFieldDomain);
+  Variable alpha= info.getAlpha();
+  if (GF)
+  {
+    degMipo= getGFDegree();
+    CanonicalForm GFMipo= gf_mipo;
+    setCharacteristic (getCharacteristic());
+    GFMipo.mapinto();
+    alpha= rootOf (GFMipo);
+    setCharacteristic (getCharacteristic(), degMipo, info.getGFName());
+  }
+  else
+  {
+    alpha= info.getAlpha();
+    degMipo= degree (getMipo (alpha));
+  }
+
+  Variable gamma;
+  CanonicalForm primElemAlpha, imPrimElemAlpha;
+  if ((!GF && evaluation != alpha) || (GF && evaluation != getGFGenerator()))
+  {
+    CanonicalForm bufEvaluation;
+    if (GF)
+    {
+      setCharacteristic (getCharacteristic());
+      bufEvaluation= GF2FalphaRep (evaluation, alpha);
+    }
+    else
+      bufEvaluation= evaluation;
+    CanonicalForm mipo= findMinPoly (bufEvaluation, alpha);
+    gamma= rootOf (mipo);
+    Variable V_buf;
+    bool fail= false;
+    primElemAlpha= primitiveElement (alpha, V_buf, fail);
+    imPrimElemAlpha= map (primElemAlpha, alpha, bufEvaluation, gamma);
+
+    if (GF)
+      setCharacteristic (getCharacteristic(), degMipo, info.getGFName());
+  }
+  else
+    gamma= alpha;
+  ExtensionInfo info2= ExtensionInfo (alpha, gamma, primElemAlpha,
+                                      imPrimElemAlpha, 1, info.getGFName(), true
+                                     );
+
+  return info2;
+}
+
+CFList
+extHenselLiftAndLatticeRecombi(const CanonicalForm& G, const CFList& uniFactors,
+                               const ExtensionInfo& extInfo, const
+                               DegreePattern& degPat, const CanonicalForm& eval
+                              )
+{
+  CanonicalForm evaluation= eval;
+  ExtensionInfo info= extInfo;
+  Variable alpha;
+  DegreePattern degs= degPat;
+  CanonicalForm F= G;
+  Variable x= Variable (1);
+  Variable y= F.mvar();
+  CFList bufUniFactors= uniFactors;
+
+
+  int degMipo;
+  ExtensionInfo info2= init4ext (info, evaluation, degMipo);
+
+  CFList source, dest;
+  CanonicalForm LCF= LC (F, 1);
+
+  int d;
+  bool isIrreducible= false;
+  int* bounds= computeBounds (F, d, isIrreducible);
+  if (isIrreducible)
+  {
+    delete [] bounds;
+    CFList source, dest;
+    CanonicalForm tmp= G (y - evaluation, y);
+    tmp= mapDown (tmp, info, source, dest);
+    return CFList (tmp);
+  }
+  int minBound= bounds[0];
+  for (int i= 1; i < d; i++)
+  {
+    if (bounds[i] != 0)
+      minBound= tmin (minBound, bounds[i]);
+  }
+
+
+  CFArray Pi;
+  CFList diophant;
+  int liftBound= tmax ((2*totaldegree (F) - 1)/degMipo + 1, degree (F) + 1 +
+                       degree (LC (F, 1)));
+  CFMatrix M= CFMatrix (liftBound, bufUniFactors.length());
+
+  CFList smallFactors;
+  CanonicalForm H;
+  bool success= false;
+  smallFactors= extSieveSmallFactors (F, bufUniFactors, degs, H, diophant, Pi,
+                                      M, success, minBound + 1, evaluation, info
+                                     );
+
+  if (smallFactors.length() > 0)
+  {
+    if (smallFactors.length() == 1)
+    {
+      if (smallFactors.getFirst() == F)
+      {
+        delete [] bounds;
+        CFList source, dest;
+        CanonicalForm tmp= G (y - evaluation, y);
+        tmp= mapDown (tmp, info, source, dest);
+        return CFList (tmp);
+      }
+    }
+    if (degs.getLength() <= 1)
+    {
+      delete [] bounds;
+      return smallFactors;
+    }
+  }
+
+  int index;
+  CanonicalForm tmp1, tmp2;
+  for (CFListIterator i= smallFactors; i.hasItem(); i++)
+  {
+    index= 1;
+    tmp1= mod (i.getItem(), y - evaluation);
+    tmp1 /= Lc (tmp1);
+    for (CFListIterator j= bufUniFactors; j.hasItem(); j++, index++)
+    {
+      tmp2= mod (j.getItem(), y);
+      tmp2 /= Lc (tmp2);
+      if (tmp1 == tmp2)
+      {
+        index++;
+        j.remove(index);
+        break;
+      }
+    }
+  }
+
+  if (bufUniFactors.isEmpty())
+  {
+    delete [] bounds;
+    return smallFactors;
+  }
+
+  if (success)
+  {
+    F= H/Lc(H);
+    delete [] bounds;
+    bounds= computeBounds (F, d, isIrreducible);
+    if (isIrreducible)
+    {
+      delete [] bounds;
+      CFList source, dest;
+      CanonicalForm tmp= F (y - evaluation, y);
+      tmp= mapDown (tmp, info, source, dest);
+      smallFactors.append (tmp);
+      return smallFactors;
+    }
+    LCF= LC (F, 1);
+
+    minBound= bounds[0];
+    for (int i= 1; i < d; i++)
+    {
+      if (bounds[i] != 0)
+        minBound= tmin (minBound, bounds[i]);
+    }
+    Pi= CFArray();
+    diophant= CFList();
+    liftBound=tmax ((2*totaldegree (F) - 1)/degMipo + 1, degree (F) + 1 +
+                    degree (LC (F, 1)));
+    M= CFMatrix (liftBound, bufUniFactors.length());
+    DegreePattern bufDegs= DegreePattern (bufUniFactors);
+    degs.intersect (bufDegs);
+    degs.refine();
+    if (degs.getLength() <= 1)
+    {
+      delete [] bounds;
+      CFList source, dest;
+      CanonicalForm tmp= F (y - evaluation, y);
+      tmp= mapDown (tmp, info, source, dest);
+      smallFactors.append (tmp);
+      return smallFactors;
+    }
+  }
+
+  bufUniFactors.insert (LCF);
+  int l= 1;
+
+#ifdef HAVE_FLINT
+  nmod_mat_t FLINTN;
+  nmod_mat_init (FLINTN, bufUniFactors.length()-1, bufUniFactors.length()-1,
+                 getCharacteristic());
+  for (long i= bufUniFactors.length()-2; i >= 0; i--)
+    nmod_mat_entry (FLINTN, i, i)= 1;
+#else
+  if (fac_NTL_char != getCharacteristic())
+  {
+    fac_NTL_char= getCharacteristic();
+    zz_p::init (getCharacteristic());
+  }
+  zz_pX NTLMipo;
+  mat_zz_p NTLN;
+
+  ident (NTLN, bufUniFactors.length() - 1);
+#endif
+  bool irreducible= false;
+  CFArray bufQ= CFArray (bufUniFactors.length() - 1);
+
+  int oldL;
+  TIMING_START (fac_fq_till_reduced);
+  if (success)
+  {
+    int start= 0;
+#ifdef HAVE_FLINT
+    oldL= extLiftAndComputeLattice (F, bounds, d, liftBound, minBound, start,
+                                    bufUniFactors, FLINTN, diophant,M, Pi, bufQ,
+                                    irreducible, evaluation, info2, source, dest
+                                   );
+#else
+    oldL= extLiftAndComputeLattice (F, bounds, d, liftBound, minBound, start,
+                                    bufUniFactors, NTLN, diophant, M, Pi, bufQ,
+                                    irreducible, evaluation, info2, source, dest
+                                   );
+#endif
+  }
+  else
+  {
+#ifdef HAVE_FLINT
+    oldL= extLiftAndComputeLattice (F, bounds, d, liftBound, minBound,
+                                    minBound+1, bufUniFactors, FLINTN, diophant,
+                                    M, Pi, bufQ, irreducible, evaluation, info2,
+                                    source, dest
+                                   );
+#else
+    oldL= extLiftAndComputeLattice (F, bounds, d, liftBound, minBound,
+                                    minBound + 1, bufUniFactors, NTLN, diophant,
+                                    M, Pi, bufQ, irreducible, evaluation, info2,
+                                    source, dest
+                                   );
+#endif
+  }
+  TIMING_END_AND_PRINT (fac_fq_till_reduced,
+                        "time to compute a reduced lattice: ");
+
+  bufUniFactors.removeFirst();
+  if (oldL > liftBound)
+  {
+#ifdef HAVE_FLINT
+    nmod_mat_clear (FLINTN);
+#endif
+    delete [] bounds;
+    return Union (smallFactors, extFactorRecombination
+                                (bufUniFactors, F,
+                                 power (y, degree (F) + 1),info,
+                                 degs, evaluation, 1, bufUniFactors.length()/2
+                                )
+                 );
+  }
+
+  l= oldL;
+  if (irreducible)
+  {
+#ifdef HAVE_FLINT
+    nmod_mat_clear (FLINTN);
+#endif
+    delete [] bounds;
+    CFList source, dest;
+    CanonicalForm tmp= F (y - evaluation, y);
+    tmp= mapDown (tmp, info, source, dest);
+    return Union (CFList (tmp), smallFactors);
+  }
+
+  CanonicalForm yToL= power (y,l);
+
+  CFList result;
+  if (l >= degree (F) + 1)
+  {
+    int * factorsFoundIndex;
+
+#ifdef HAVE_FLINT
+    factorsFoundIndex= new int [nmod_mat_ncols (FLINTN)];
+    for (long i= 0; i < nmod_mat_ncols (FLINTN); i++)
+#else
+    factorsFoundIndex= new int [NTLN.NumCols()];
+    for (long i= 0; i < NTLN.NumCols(); i++)
+#endif
+      factorsFoundIndex[i]= 0;
+
+    int factorsFound= 0;
+    CanonicalForm bufF= F;
+
+#ifdef HAVE_FLINT
+    extReconstructionTry (result, bufF, bufUniFactors, degree (F) + 1,
+                          factorsFound, factorsFoundIndex, FLINTN, false, info,
+                          evaluation
+                         );
+
+    if (result.length() == nmod_mat_ncols (FLINTN))
+    {
+      nmod_mat_clear (FLINTN);
+#else
+    extReconstructionTry (result, bufF, bufUniFactors, degree (F) + 1,
+                          factorsFound, factorsFoundIndex, NTLN, false, info,
+                          evaluation
+                         );
+
+    if (result.length() == NTLN.NumCols())
+    {
+#endif
+      delete [] factorsFoundIndex;
+      delete [] bounds;
+      return Union (result, smallFactors);
+    }
+
+    delete [] factorsFoundIndex;
+  }
+  if (l >= liftBound)
+  {
+    int * factorsFoundIndex;
+#ifdef HAVE_FLINT
+    factorsFoundIndex= new int [nmod_mat_ncols (FLINTN)];
+    for (long i= 0; i < nmod_mat_ncols (FLINTN); i++)
+#else
+    factorsFoundIndex= new int [NTLN.NumCols()];
+    for (long i= 0; i < NTLN.NumCols(); i++)
+#endif
+      factorsFoundIndex[i]= 0;
+    CanonicalForm bufF= F;
+    int factorsFound= 0;
+
+#ifdef HAVE_FLINT
+    extReconstructionTry (result, bufF, bufUniFactors, degree (F) + 1,
+                          factorsFound, factorsFoundIndex, FLINTN, false,
+                          info, evaluation
+                         );
+
+    if (result.length() == nmod_mat_ncols (FLINTN))
+    {
+      nmod_mat_clear (FLINTN);
+#else
+    extReconstructionTry (result, bufF, bufUniFactors, degree (F) + 1,
+                          factorsFound, factorsFoundIndex, NTLN, false,
+                          info, evaluation
+                         );
+
+    if (result.length() == NTLN.NumCols())
+    {
+#endif
+      delete [] factorsFoundIndex;
+      delete [] bounds;
+      return Union (result, smallFactors);
+    }
+    delete [] factorsFoundIndex;
+  }
+
+  result= CFList();
+  bool beenInThres= false;
+  int thres= 100;
+#ifdef HAVE_FLINT
+  if (l <= thres && bufUniFactors.length() > nmod_mat_ncols (FLINTN))
+  {
+    refineAndRestartLift (F, FLINTN, 2*totaldegree (F)-1, l, bufUniFactors, M, Pi,
+                         diophant
+                        );
+#else
+  if (l <= thres && bufUniFactors.length() > NTLN.NumCols())
+  {
+    refineAndRestartLift (F, NTLN, 2*totaldegree (F)-1, l, bufUniFactors, M, Pi,
+                         diophant
+                        );
+#endif
+    beenInThres= true;
+  }
+
+
+  CanonicalForm bufF= F;
+  int factorsFound= 0;
+
+#ifdef HAVE_FLINT
+  result= extEarlyReconstructionAndLifting (F, FLINTN, bufF, bufUniFactors, l,
+                                            factorsFound, beenInThres, M, Pi,
+                                            diophant, info, evaluation
+                                           );
+
+  if (result.length() == nmod_mat_ncols (FLINTN))
+  {
+    nmod_mat_clear (FLINTN);
+#else
+  result= extEarlyReconstructionAndLifting (F, NTLN, bufF, bufUniFactors, l,
+                                            factorsFound, beenInThres, M, Pi,
+                                            diophant, info, evaluation
+                                           );
+
+  if (result.length() == NTLN.NumCols())
+  {
+#endif
+    delete [] bounds;
+    return Union (result, smallFactors);
+  }
+
+  if (result.length() > 0)
+  {
+   if (beenInThres)
+   {
+      int index;
+      for (CFListIterator i= result; i.hasItem(); i++)
+      {
+        index= 1;
+        tmp1= mod (i.getItem(), y-evaluation);
+        tmp1 /= Lc (tmp1);
+        for (CFListIterator j= bufUniFactors; j.hasItem(); j++, index++)
+        {
+          tmp2= mod (j.getItem(), y);
+          tmp2 /= Lc (tmp2);
+          if (tmp1 == tmp2)
+          {
+            index++;
+            j.remove(index);
+            break;
+          }
+        }
+      }
+    }
+    else
+    {
+#ifdef HAVE_FLINT
+      int * zeroOne= extractZeroOneVecs (FLINTN);
+#else
+      int * zeroOne= extractZeroOneVecs (NTLN);
+#endif
+      CFList bufBufUniFactors= bufUniFactors;
+      CFListIterator iter, iter2;
+      CanonicalForm buf;
+      CFList factorsConsidered;
+#ifdef HAVE_FLINT
+      for (int i= 0; i < nmod_mat_ncols (FLINTN); i++)
+#else
+      for (int i= 0; i < NTLN.NumCols(); i++)
+#endif
+      {
+        if (zeroOne [i] == 0)
+          continue;
+        iter= bufUniFactors;
+        buf= 1;
+        factorsConsidered= CFList();
+#ifdef HAVE_FLINT
+        for (int j= 0; j < nmod_mat_nrows (FLINTN); j++, iter++)
+        {
+          if (!(nmod_mat_entry (FLINTN, j, i) == 0))
+#else
+        for (int j= 0; j < NTLN.NumRows(); j++, iter++)
+        {
+          if (!IsZero (NTLN (j + 1,i + 1)))
+#endif
+          {
+            factorsConsidered.append (iter.getItem());
+            buf *= mod (iter.getItem(), y);
+          }
+        }
+        buf /= Lc (buf);
+        for (iter2= result; iter2.hasItem(); iter2++)
+        {
+          CanonicalForm tmp= mod (iter2.getItem(), y - evaluation);
+          tmp /= Lc (tmp);
+          if (tmp == buf)
+          {
+            bufBufUniFactors= Difference (bufBufUniFactors, factorsConsidered);
+            break;
+          }
+        }
+      }
+      bufUniFactors= bufBufUniFactors;
+      delete [] zeroOne;
+    }
+
+    int oldNumCols;
+    CFList resultBufF;
+    irreducible= false;
+
+#ifdef HAVE_FLINT //TODO
+    oldNumCols= nmod_mat_ncols (FLINTN);
+    resultBufF= extIncreasePrecision (bufF, bufUniFactors, factorsFound,
+                                      oldNumCols, oldL, evaluation, info2,
+                                      source, dest, l
+                                     );
+    nmod_mat_clear (FLINTN);
+#else
+    oldNumCols= NTLN.NumCols();
+    resultBufF= extIncreasePrecision (bufF, bufUniFactors, factorsFound,
+                                      oldNumCols, oldL, evaluation, info2,
+                                      source, dest, l
+                                     );
+#endif
+    if (bufUniFactors.isEmpty() || degree (bufF) <= 0)
+    {
+      delete [] bounds;
+      result= Union (resultBufF, result);
+      return Union (result, smallFactors);
+    }
+
+    for (CFListIterator i= bufUniFactors; i.hasItem(); i++)
+      i.getItem()= mod (i.getItem(), y);
+
+    delete [] bounds;
+    CFList bufResult;
+    DegreePattern bufDegs= DegreePattern (bufUniFactors);
+    degs.intersect (bufDegs);
+    degs.refine();
+    result= Union (result, smallFactors);
+    if (degs.getLength() == 1 || bufUniFactors.length() == 1)
+    {
+      CFList source, dest;
+      CanonicalForm tmp= bufF (y - evaluation, y);
+      tmp= mapDown (tmp, info, source, dest);
+      result.append (tmp);
+      return result;
+    }
+    return Union (result, extHenselLiftAndLatticeRecombi (bufF, bufUniFactors,
+                                                          info, degs, evaluation
+                                                         )
+                 );
+  }
+
+  if (l/degMipo < liftBound)
+  {
+#ifdef HAVE_FLINT
+    result=extIncreasePrecision (F, bufUniFactors, oldL, l, d, bounds, bufQ,
+                                 FLINTN, evaluation, info2, source, dest
+                                );
+
+    if (result.length()== nmod_mat_ncols (FLINTN))
+    {
+      nmod_mat_clear (FLINTN);
+#else
+    result=extIncreasePrecision (F, bufUniFactors, oldL, l, d, bounds, bufQ,
+                                 NTLN, evaluation, info2, source, dest
+                                );
+
+    if (result.length()== NTLN.NumCols())
+    {
+#endif
+      delete [] bounds;
+      result= Union (result, smallFactors);
+      return result;
+    }
+
+    if (result.isEmpty())
+    {
+#ifdef HAVE_FLINT
+      result= extFurtherLiftingAndIncreasePrecision (F,bufUniFactors, l,
+                                                     liftBound, d,bounds,FLINTN,
+                                                     diophant, M, Pi, bufQ,
+                                                     evaluation, info2, source,
+                                                     dest
+                                                    );
+      if (result.length()== nmod_mat_ncols (FLINTN))
+      {
+        nmod_mat_clear (FLINTN);
+#else
+      result= extFurtherLiftingAndIncreasePrecision (F,bufUniFactors, l,
+                                                     liftBound, d, bounds, NTLN,
+                                                     diophant, M, Pi, bufQ,
+                                                     evaluation, info2, source,
+                                                     dest
+                                                    );
+      if (result.length()== NTLN.NumCols())
+      {
+#endif
+        delete [] bounds;
+        result= Union (result, smallFactors);
+        return result;
+      }
+    }
+  }
+
+#ifdef HAVE_FLINT
+  nmod_mat_clear (FLINTN);
+#endif
+
+  DEBOUTLN (cerr, "lattice recombination failed");
+
+  DegreePattern bufDegs= DegreePattern (bufUniFactors);
+  degs.intersect (bufDegs);
+  degs.refine();
+
+  delete [] bounds;
+  bounds= computeBounds (F, d, isIrreducible);
+  if (isIrreducible)
+  {
+    delete [] bounds;
+    CFList source, dest;
+    CanonicalForm tmp= F (y - evaluation, y);
+    tmp= mapDown (tmp, info, source, dest);
+    smallFactors.append (tmp);
+    result= Union (result, smallFactors);
+    return result;
+  }
+  minBound= bounds[0];
+  for (int i= 1; i < d; i++)
+  {
+    if (bounds[i] != 0)
+      minBound= tmin (minBound, bounds[i]);
+  }
+
+  if (minBound > 16 || result.length() == 0)
+  {
+    result= Union (result, smallFactors);
+    CanonicalForm MODl= power (y, degree (F) + 1);
+    delete [] bounds;
+    return Union (result, extFactorRecombination (bufUniFactors, F, MODl, info,
+                                                  degs, evaluation, 1,
+                                                  bufUniFactors.length()/2
+                                                 )
+                 );
+  }
+  else
+  {
+    result= Union (result, smallFactors);
+    for (CFListIterator i= bufUniFactors; i.hasItem(); i++)
+      i.getItem()= mod (i.getItem(), y);
+    delete [] bounds;
+    return Union (result, extHenselLiftAndLatticeRecombi (F, bufUniFactors,
+                                                          info, degs, evaluation
+                                                         )
+                 );
+  }
+}
+
+CFList
+extBiFactorize (const CanonicalForm& F, const ExtensionInfo& info);
+
+/// bivariate factorization over finite fields as decribed in "Factoring
+/// multivariate polynomials over a finite field" by L Bernardin.
+CFList
+biFactorize (const CanonicalForm& F, const ExtensionInfo& info)
+{
+  if (F.inCoeffDomain())
+    return CFList(F);
+
+  CanonicalForm A= F;
+  bool GF= (CFFactory::gettype() == GaloisFieldDomain);
+
+  Variable alpha= info.getAlpha();
+  Variable beta= info.getBeta();
+  CanonicalForm gamma= info.getGamma();
+  CanonicalForm delta= info.getDelta();
+  int k= info.getGFDegree();
+  bool extension= info.isInExtension();
+  if (A.isUnivariate())
+  {
+    if (extension == false)
+      return uniFactorizer (F, alpha, GF);
+    else
+    {
+      CFList source, dest;
+      A= mapDown (A, info, source, dest);
+      return uniFactorizer (A, beta, GF);
+    }
+  }
+
+  CFMap N;
+  A= compress (A, N);
+  Variable y= A.mvar();
+
+  if (y.level() > 2) return CFList (F);
+  Variable x= Variable (1);
+
+  //remove and factorize content
+  CanonicalForm contentAx= content (A, x);
+  CanonicalForm contentAy= content (A);
+
+  A= A/(contentAx*contentAy);
+  CFList contentAxFactors, contentAyFactors;
+
+  if (!extension)
+  {
+    contentAxFactors= uniFactorizer (contentAx, alpha, GF);
+    contentAyFactors= uniFactorizer (contentAy, alpha, GF);
+  }
+
+  //trivial case
+  CFList factors;
+  if (A.inCoeffDomain())
+  {
+    append (factors, contentAxFactors);
+    append (factors, contentAyFactors);
+    decompress (factors, N);
+    return factors;
+  }
+  else if (A.isUnivariate())
+  {
+    factors= uniFactorizer (A, alpha, GF);
+    append (factors, contentAxFactors);
+    append (factors, contentAyFactors);
+    decompress (factors, N);
+    return factors;
+  }
+
+
+  //check trivial case
+  if (degree (A) == 1 || degree (A, 1) == 1 ||
+      (size (A) == 2 && igcd (degree (A), degree (A,1))==1))
+  {
+    factors.append (A);
+
+    appendSwapDecompress (factors, contentAxFactors, contentAyFactors,
+                          false, false, N);
+
+    if (!extension)
+      normalize (factors);
+    return factors;
+  }
+
+  // check derivatives
+  bool derivXZero= false;
+  CanonicalForm derivX= deriv (A, x);
+  CanonicalForm gcdDerivX;
+  if (derivX.isZero())
+    derivXZero= true;
+  else
+  {
+    gcdDerivX= gcd (A, derivX);
+    if (degree (gcdDerivX) > 0)
+    {
+      CanonicalForm g= A/gcdDerivX;
+      CFList factorsG=
+      Union (biFactorize (g, info), biFactorize (gcdDerivX, info));
+      append (factorsG, contentAxFactors);
+      append (factorsG, contentAyFactors);
+      decompress (factorsG, N);
+      if (!extension)
+        normalize (factorsG);
+      return factorsG;
+    }
+  }
+  bool derivYZero= false;
+  CanonicalForm derivY= deriv (A, y);
+  CanonicalForm gcdDerivY;
+  if (derivY.isZero())
+    derivYZero= true;
+  else
+  {
+    gcdDerivY= gcd (A, derivY);
+    if (degree (gcdDerivY) > 0)
+    {
+      CanonicalForm g= A/gcdDerivY;
+      CFList factorsG=
+      Union (biFactorize (g, info), biFactorize (gcdDerivY, info));
+      append (factorsG, contentAxFactors);
+      append (factorsG, contentAyFactors);
+      decompress (factorsG, N);
+      if (!extension)
+        normalize (factorsG);
+      return factorsG;
+    }
+  }
+  //main variable is chosen s.t. the degree in x is minimal
+  bool swap= false;
+  if ((degree (A) > degree (A, x)) || derivXZero)
+  {
+    if (!derivYZero)
+    {
+      A= swapvar (A, y, x);
+      swap= derivXZero;
+      derivXZero= derivYZero;
+      derivYZero= swap;
+      swap= true;
+    }
+  }
+
+  int boundsLength;
+  bool isIrreducible= false;
+  int * bounds= computeBounds (A, boundsLength, isIrreducible);
+  if (isIrreducible)
+  {
+    delete [] bounds;
+    factors.append (A);
+
+    appendSwapDecompress (factors, contentAxFactors, contentAyFactors,
+                          swap, false, N);
+
+    if (!extension)
+      normalize (factors);
+    return factors;
+  }
+
+  int minBound= bounds[0];
+  for (int i= 1; i < boundsLength; i++)
+  {
+    if (bounds[i] != 0)
+      minBound= tmin (minBound, bounds[i]);
+  }
+
+  int boundsLength2;
+  int * bounds2= computeBoundsWrtDiffMainvar (A, boundsLength2, isIrreducible);
+  int minBound2= bounds2[0];
+  for (int i= 1; i < boundsLength2; i++)
+  {
+    if (bounds2[i] != 0)
+      minBound2= tmin (minBound2, bounds2[i]);
+  }
+
+
+  bool fail= false;
+  CanonicalForm Aeval, evaluation, bufAeval, bufEvaluation, buf, tmp;
+  CFList uniFactors, list, bufUniFactors;
+  DegreePattern degs;
+  DegreePattern bufDegs;
+
+  bool fail2= false;
+  CanonicalForm Aeval2, evaluation2, bufAeval2, bufEvaluation2;
+  CFList bufUniFactors2, list2, uniFactors2;
+  DegreePattern degs2;
+  DegreePattern bufDegs2;
+  bool swap2= false;
+
+  // several univariate factorizations to obtain more information about the
+  // degree pattern therefore usually less combinations have to be tried during
+  // the recombination process
+  int factorNums= 3;
+  int subCheck1= substituteCheck (A, x);
+  int subCheck2= substituteCheck (A, y);
+  bool symmetric= false;
+
+  TIMING_START (fac_fq_uni_total);
+  for (int i= 0; i < factorNums; i++)
+  {
+    bufAeval= A;
+    TIMING_START (fac_fq_bi_evaluation);
+    bufEvaluation= evalPoint (A, bufAeval, alpha, list, GF, fail);
+    TIMING_END_AND_PRINT (fac_fq_bi_evaluation, "time to find eval point: ");
+    if (!derivXZero && !fail2 && !symmetric)
+    {
+      if (i == 0)
+      {
+        buf= swapvar (A, x, y);
+        symmetric= (A/Lc (A) == buf/Lc (buf));
+      }
+      bufAeval2= buf;
+      TIMING_START (fac_fq_bi_evaluation);
+      bufEvaluation2= evalPoint (buf, bufAeval2, alpha, list2, GF, fail2);
+      TIMING_END_AND_PRINT (fac_fq_bi_evaluation,
+                            "time to find eval point wrt y: ");
+    }
+    // first try to change main variable if there is no valid evaluation point
+    if (fail && (i == 0))
+    {
+      if (!derivXZero && !fail2 && !symmetric)
+      {
+        bufEvaluation= bufEvaluation2;
+        int dummy= subCheck2;
+        subCheck2= subCheck1;
+        subCheck1= dummy;
+        tmp= A;
+        A= buf;
+        buf= tmp;
+        bufAeval= bufAeval2;
+        swap2= true;
+        fail= false;
+      }
+      else
+        fail= true;
+    }
+
+    // if there is no valid evaluation point pass to a field extension
+    if (fail && (i == 0))
+    {
+      factors= extBiFactorize (A, info);
+      appendSwapDecompress (factors, contentAxFactors, contentAyFactors,
+                            swap, swap2, N);
+      normalize (factors);
+      delete [] bounds;
+      delete [] bounds2;
+      return factors;
+    }
+
+    // there is at least one valid evaluation point
+    // but we do not compute more univariate factorization over an extension
+    if (fail && (i != 0))
+      break;
+
+    // univariate factorization
+    TIMING_START (fac_fq_uni_factorizer);
+    bufUniFactors= uniFactorizer (bufAeval, alpha, GF);
+    TIMING_END_AND_PRINT (fac_fq_uni_factorizer,
+                          "time for univariate factorization over Fq: ");
+    DEBOUTLN (cerr, "Lc (bufAeval)*prod (bufUniFactors)== bufAeval " <<
+              (prod (bufUniFactors)*Lc (bufAeval) == bufAeval));
+
+    if (!derivXZero && !fail2 && !symmetric)
+    {
+      TIMING_START (fac_fq_uni_factorizer);
+      bufUniFactors2= uniFactorizer (bufAeval2, alpha, GF);
+      TIMING_END_AND_PRINT (fac_fq_uni_factorizer,
+                            "time for univariate factorization in y over Fq: ");
+      DEBOUTLN (cerr, "Lc (bufAeval2)*prod (bufUniFactors2)== bufAeval2 " <<
+                (prod (bufUniFactors2)*Lc (bufAeval2) == bufAeval2));
+    }
+
+    if (bufUniFactors.length() == 1 ||
+        (!fail2 && !derivXZero && !symmetric && (bufUniFactors2.length() == 1)))
+    {
+      if (extension)
+      {
+        CFList source, dest;
+        appendMapDown (factors, A, info, source, dest);
+      }
+      else
+        factors.append (A);
+
+      appendSwapDecompress (factors, contentAxFactors, contentAyFactors,
+                            swap, swap2, N);
+
+      if (!extension)
+        normalize (factors);
+      delete [] bounds;
+      delete [] bounds2;
+      return factors;
+    }
+
+    if (i == 0 && !extension)
+    {
+      if (subCheck1 > 0)
+      {
+        int subCheck= substituteCheck (bufUniFactors);
+
+        if (subCheck > 1 && (subCheck1%subCheck == 0))
+        {
+          CanonicalForm bufA= A;
+          subst (bufA, bufA, subCheck, x);
+          factors= biFactorize (bufA, info);
+          reverseSubst (factors, subCheck, x);
+          appendSwapDecompress (factors, contentAxFactors, contentAyFactors,
+                                swap, swap2, N);
+          if (!extension)
+            normalize (factors);
+          delete [] bounds;
+          delete [] bounds2;
+          return factors;
+        }
+      }
+
+      if (!derivXZero && !fail2 && !symmetric && subCheck2 > 0)
+      {
+        int subCheck= substituteCheck (bufUniFactors2);
+
+        if (subCheck > 1 && (subCheck2%subCheck == 0))
+        {
+          CanonicalForm bufA= A;
+          subst (bufA, bufA, subCheck, y);
+          factors= biFactorize (bufA, info);
+          reverseSubst (factors, subCheck, y);
+          appendSwapDecompress (factors, contentAxFactors, contentAyFactors,
+                                swap, swap2, N);
+          if (!extension)
+            normalize (factors);
+          delete [] bounds;
+          delete [] bounds2;
+          return factors;
+        }
+      }
+    }
+
+    // degree analysis
+    bufDegs = DegreePattern (bufUniFactors);
+    if (!derivXZero && !fail2 && !symmetric)
+      bufDegs2= DegreePattern (bufUniFactors2);
+
+    if (i == 0)
+    {
+      Aeval= bufAeval;
+      evaluation= bufEvaluation;
+      uniFactors= bufUniFactors;
+      degs= bufDegs;
+      if (!derivXZero && !fail2 && !symmetric)
+      {
+        Aeval2= bufAeval2;
+        evaluation2= bufEvaluation2;
+        uniFactors2= bufUniFactors2;
+        degs2= bufDegs2;
+      }
+    }
+    else
+    {
+      degs.intersect (bufDegs);
+      if (!derivXZero && !fail2 && !symmetric)
+      {
+        degs2.intersect (bufDegs2);
+        if (bufUniFactors2.length() < uniFactors2.length())
+        {
+          uniFactors2= bufUniFactors2;
+          Aeval2= bufAeval2;
+          evaluation2= bufEvaluation2;
+        }
+      }
+      if (bufUniFactors.length() < uniFactors.length())
+      {
+        uniFactors= bufUniFactors;
+        Aeval= bufAeval;
+        evaluation= bufEvaluation;
+      }
+    }
+    list.append (bufEvaluation);
+    if (!derivXZero && !fail2 && !symmetric)
+      list2.append (bufEvaluation2);
+  }
+  TIMING_END_AND_PRINT (fac_fq_uni_total,
+                        "total time for univariate factorizations: ");
+
+  if (!derivXZero && !fail2 && !symmetric)
+  {
+    if ((uniFactors.length() > uniFactors2.length() && minBound2 <= minBound)||
+        (uniFactors.length() == uniFactors2.length()
+         && degs.getLength() > degs2.getLength() && minBound2 <= minBound))
+    {
+      degs= degs2;
+      uniFactors= uniFactors2;
+      evaluation= evaluation2;
+      Aeval= Aeval2;
+      A= buf;
+      swap2= true;
+    }
+  }
+
+  if (degs.getLength() == 1) // A is irreducible
+  {
+    if (extension)
+    {
+      CFList source, dest;
+      appendMapDown (factors, A, info, source, dest);
+    }
+    else
+      factors.append (A);
+    appendSwapDecompress (factors, contentAxFactors, contentAyFactors,
+                            swap, swap2, N);
+    if (!extension)
+      normalize (factors);
+    delete [] bounds;
+    delete [] bounds2;
+    return factors;
+  }
+
+  int liftBound= degree (A, y) + 1;
+
+  if (swap2)
+  {
+    delete [] bounds;
+    bounds= bounds2;
+    minBound= minBound2;
+  }
+
+  TIMING_START (fac_fq_bi_shift_to_zero);
+  A= A (y + evaluation, y);
+  TIMING_END_AND_PRINT (fac_fq_bi_shift_to_zero,
+                        "time to shift eval to zero: ");
+
+  int degMipo= 1;
+  if (extension && alpha.level() != 1 && k==1)
+    degMipo= degree (getMipo (alpha));
+
+  DEBOUTLN (cerr, "uniFactors= " << uniFactors);
+
+  if ((GF && !extension) || (GF && extension && k != 1))
+  {
+    bool earlySuccess= false;
+    CFList earlyFactors;
+    TIMING_START (fac_fq_bi_hensel_lift);
+    uniFactors= henselLiftAndEarly
+               (A, earlySuccess, earlyFactors, degs, liftBound,
+                uniFactors, info, evaluation);
+    TIMING_END_AND_PRINT (fac_fq_bi_hensel_lift,
+                          "time for bivariate hensel lifting over Fq: ");
+    DEBOUTLN (cerr, "lifted factors= " << uniFactors);
+
+    CanonicalForm MODl= power (y, liftBound);
+
+    TIMING_START (fac_fq_bi_factor_recombination);
+    if (extension)
+      factors= extFactorRecombination (uniFactors, A, MODl, info, degs,
+                                       evaluation, 1, uniFactors.length()/2);
+    else
+      factors= factorRecombination (uniFactors, A, MODl, degs, evaluation, 1,
+                                    uniFactors.length()/2);
+    TIMING_END_AND_PRINT (fac_fq_bi_factor_recombination,
+                          "time for naive bivariate factor recombi over Fq: ");
+
+    if (earlySuccess)
+      factors= Union (earlyFactors, factors);
+    else if (!earlySuccess && degs.getLength() == 1)
+      factors= earlyFactors;
+  }
+  else if (degree (A) > 4 && beta.level() == 1 && (2*minBound)/degMipo < 32)
+  {
+    TIMING_START (fac_fq_bi_hensel_lift);
+    if (extension)
+    {
+      CFList lll= extHenselLiftAndLatticeRecombi (A, uniFactors, info, degs,
+                                                  evaluation
+                                                 );
+      factors= Union (lll, factors);
+    }
+    else if (alpha.level() == 1 && !GF)
+    {
+      CFList lll= henselLiftAndLatticeRecombi (A, uniFactors, alpha, degs,
+                                               symmetric, evaluation);
+      factors= Union (lll, factors);
+    }
+    else if (!extension && (alpha != x || GF))
+    {
+      CFList lll= henselLiftAndLatticeRecombi (A, uniFactors, alpha, degs,
+                                               symmetric, evaluation);
+      factors= Union (lll, factors);
+    }
+    TIMING_END_AND_PRINT (fac_fq_bi_hensel_lift,
+                          "time to bivar lift and LLL recombi over Fq: ");
+    DEBOUTLN (cerr, "lifted factors= " << uniFactors);
+  }
+  else
+  {
+    bool earlySuccess= false;
+    CFList earlyFactors;
+    TIMING_START (fac_fq_bi_hensel_lift);
+    uniFactors= henselLiftAndEarly
+               (A, earlySuccess, earlyFactors, degs, liftBound,
+                uniFactors, info, evaluation);
+    TIMING_END_AND_PRINT (fac_fq_bi_hensel_lift,
+                          "time for bivar hensel lifting over Fq: ");
+    DEBOUTLN (cerr, "lifted factors= " << uniFactors);
+
+    CanonicalForm MODl= power (y, liftBound);
+    if (!extension)
+    {
+      TIMING_START (fac_fq_bi_factor_recombination);
+      factors= factorRecombination (uniFactors, A, MODl, degs, evaluation, 1, 3);
+      TIMING_END_AND_PRINT (fac_fq_bi_factor_recombination,
+                            "time for small subset naive recombi over Fq: ");
+
+      int oldUniFactorsLength= uniFactors.length();
+      if (degree (A) > 0)
+      {
+        CFList tmp;
+        TIMING_START (fac_fq_bi_hensel_lift);
+        if (alpha.level() == 1)
+          tmp= increasePrecision (A, uniFactors, 0, uniFactors.length(), 1,
+                                  liftBound, evaluation
+                                 );
+        else
+        {
+          if (degree (A) > getCharacteristic())
+            tmp= increasePrecisionFq2Fp (A, uniFactors, 0, uniFactors.length(),
+                                         1, alpha, liftBound, evaluation
+                                        );
+          else
+            tmp= increasePrecision (A, uniFactors, 0, uniFactors.length(), 1,
+                                    alpha, liftBound, evaluation
+                                   );
+        }
+        TIMING_END_AND_PRINT (fac_fq_bi_hensel_lift,
+                              "time to increase precision: ");
+        factors= Union (factors, tmp);
+        if (tmp.length() == 0 || (tmp.length() > 0 && uniFactors.length() != 0
+                                  && uniFactors.length() != oldUniFactorsLength)
+           )
+        {
+          DegreePattern bufDegs= DegreePattern (uniFactors);
+          degs.intersect (bufDegs);
+          degs.refine ();
+          factors= Union (factors, factorRecombination (uniFactors, A, MODl,
+                                                        degs, evaluation, 4,
+                                                        uniFactors.length()/2
+                                                       )
+                         );
+        }
+      }
+    }
+    else
+    {
+      if (beta.level() != 1 || k > 1)
+      {
+        if (k > 1)
+        {
+          factors= extFactorRecombination (uniFactors, A, MODl, info, degs,
+                                           evaluation, 1, uniFactors.length()/2
+                                          );
+        }
+        else
+        {
+          factors= extFactorRecombination (uniFactors, A, MODl, info, degs,
+                                           evaluation, 1, 3
+                                          );
+          if (degree (A) > 0)
+          {
+            CFList tmp= increasePrecision2 (A, uniFactors, alpha, liftBound);
+            DegreePattern bufDegs= DegreePattern (tmp);
+            degs.intersect (bufDegs);
+            degs.refine ();
+            factors= Union (factors, extFactorRecombination (tmp, A, MODl, info,
+                                                             degs, evaluation,
+                                                             1, tmp.length()/2
+                                                            )
+                           );
+          }
+        }
+      }
+      else
+      {
+        factors= extFactorRecombination (uniFactors, A, MODl, info, degs,
+                                         evaluation, 1, 3
+                                        );
+        int oldUniFactorsLength= uniFactors.length();
+        if (degree (A) > 0)
+        {
+          int degMipo;
+          ExtensionInfo info2= init4ext (info, evaluation, degMipo);
+
+          CFList source, dest;
+          CFList tmp= extIncreasePrecision (A, uniFactors, 0,
+                                            uniFactors.length(), 1, evaluation,
+                                            info2, source, dest, liftBound
+                                           );
+          factors= Union (factors, tmp);
+          if (tmp.length() == 0 || (tmp.length() > 0 && uniFactors.length() != 0
+                                  && uniFactors.length() != oldUniFactorsLength)
+             )
+          {
+            DegreePattern bufDegs= DegreePattern (uniFactors);
+            degs.intersect (bufDegs);
+            degs.refine ();
+            factors= Union (factors,extFactorRecombination (uniFactors, A, MODl,
+                                                        info, degs, evaluation,
+                                                        4, uniFactors.length()/2
+                                                            )
+                           );
+          }
+        }
+      }
+    }
+
+    if (earlySuccess)
+      factors= Union (earlyFactors, factors);
+    else if (!earlySuccess && degs.getLength() == 1)
+      factors= earlyFactors;
+  }
+
+  if (!swap2)
+    delete [] bounds2;
+  delete [] bounds;
+
+  appendSwapDecompress (factors, contentAxFactors, contentAyFactors,
+                        swap, swap2, N);
+  if (!extension)
+    normalize (factors);
+
+  return factors;
+}
+
+CFList
+extBiFactorize (const CanonicalForm& F, const ExtensionInfo& info)
+{
+
+  CanonicalForm A= F;
+  Variable alpha= info.getAlpha();
+  Variable beta= info.getBeta();
+  int k= info.getGFDegree();
+  char cGFName= info.getGFName();
+  CanonicalForm delta= info.getDelta();
+
+  bool GF= (CFFactory::gettype() == GaloisFieldDomain);
+  Variable x= Variable (1);
+  CFList factors;
+  if (!GF && alpha == x)  // we are in F_p
+  {
+    bool extension= true;
+    int p= getCharacteristic();
+    if (p*p < (1<<16)) // pass to GF if possible
+    {
+      setCharacteristic (getCharacteristic(), 2, 'Z');
+      A= A.mapinto();
+      ExtensionInfo info2= ExtensionInfo (extension);
+      factors= biFactorize (A, info2);
+
+      CanonicalForm mipo= gf_mipo;
+      setCharacteristic (getCharacteristic());
+      Variable vBuf= rootOf (mipo.mapinto());
+      for (CFListIterator j= factors; j.hasItem(); j++)
+        j.getItem()= GF2FalphaRep (j.getItem(), vBuf);
+      prune (vBuf);
+    }
+    else // not able to pass to GF, pass to F_p(\alpha)
+    {
+      CanonicalForm mipo= randomIrredpoly (2, x);
+      Variable v= rootOf (mipo);
+      ExtensionInfo info2= ExtensionInfo (v);
+      factors= biFactorize (A, info2);
+      prune (v);
+    }
+    return factors;
+  }
+  else if (!GF && (alpha != x)) // we are in F_p(\alpha)
+  {
+    if (k == 1) // need factorization over F_p
+    {
+      int extDeg= degree (getMipo (alpha));
+      extDeg++;
+      CanonicalForm mipo= randomIrredpoly (extDeg, x);
+      Variable v= rootOf (mipo);
+      ExtensionInfo info2= ExtensionInfo (v);
+      factors= biFactorize (A, info2);
+      prune (v);
+    }
+    else
+    {
+      if (beta == x)
+      {
+        Variable v= chooseExtension (alpha, beta, k);
+        CanonicalForm primElem, imPrimElem;
+        bool primFail= false;
+        Variable vBuf;
+        primElem= primitiveElement (alpha, vBuf, primFail);
+        ASSERT (!primFail, "failure in integer factorizer");
+        if (primFail)
+          ; //ERROR
+        else
+          imPrimElem= mapPrimElem (primElem, alpha, v);
+
+        CFList source, dest;
+        CanonicalForm bufA= mapUp (A, alpha, v, primElem, imPrimElem,
+                                   source, dest);
+        ExtensionInfo info2= ExtensionInfo (v, alpha, imPrimElem, primElem);
+        factors= biFactorize (bufA, info2);
+        prune (v);
+      }
+      else
+      {
+        Variable v= chooseExtension (alpha, beta, k);
+        CanonicalForm primElem, imPrimElem;
+        bool primFail= false;
+        Variable vBuf;
+        ASSERT (!primFail, "failure in integer factorizer");
+        if (primFail)
+          ; //ERROR
+        else
+          imPrimElem= mapPrimElem (delta, beta, v);
+
+        CFList source, dest;
+        CanonicalForm bufA= mapDown (A, info, source, dest);
+        source= CFList();
+        dest= CFList();
+        bufA= mapUp (bufA, beta, v, delta, imPrimElem, source, dest);
+        ExtensionInfo info2= ExtensionInfo (v, beta, imPrimElem, delta);
+        factors= biFactorize (bufA, info2);
+        prune (v);
+      }
+    }
+    return factors;
+  }
+  else // we are in GF (p^k)
+  {
+    int p= getCharacteristic();
+    int extensionDeg= getGFDegree();
+    bool extension= true;
+    if (k == 1) // need factorization over F_p
+    {
+      extensionDeg++;
+      if (ipower (p, extensionDeg) < (1<<16))
+      // pass to GF(p^k+1)
+      {
+        CanonicalForm mipo= gf_mipo;
+        setCharacteristic (p);
+        Variable vBuf= rootOf (mipo.mapinto());
+        A= GF2FalphaRep (A, vBuf);
+        setCharacteristic (p, extensionDeg, 'Z');
+        ExtensionInfo info2= ExtensionInfo (extension);
+        factors= biFactorize (A.mapinto(), info2);
+        prune (vBuf);
+      }
+      else // not able to pass to another GF, pass to F_p(\alpha)
+      {
+        CanonicalForm mipo= gf_mipo;
+        setCharacteristic (p);
+        Variable vBuf= rootOf (mipo.mapinto());
+        A= GF2FalphaRep (A, vBuf);
+        Variable v= chooseExtension (vBuf, beta, k);
+        ExtensionInfo info2= ExtensionInfo (v, extension);
+        factors= biFactorize (A, info2);
+        prune (vBuf);
+      }
+    }
+    else // need factorization over GF (p^k)
+    {
+      if (ipower (p, 2*extensionDeg) < (1<<16))
+      // pass to GF (p^2k)
+      {
+        setCharacteristic (p, 2*extensionDeg, 'Z');
+        ExtensionInfo info2= ExtensionInfo (k, cGFName, extension);
+        factors= biFactorize (GFMapUp (A, extensionDeg), info2);
+        setCharacteristic (p, extensionDeg, cGFName);
+      }
+      else // not able to pass to GF (p^2k), pass to F_p (\alpha)
+      {
+        CanonicalForm mipo= gf_mipo;
+        setCharacteristic (p);
+        Variable v1= rootOf (mipo.mapinto());
+        A= GF2FalphaRep (A, v1);
+        Variable v2= chooseExtension (v1, v1, k);
+        CanonicalForm primElem, imPrimElem;
+        bool primFail= false;
+        Variable vBuf;
+        primElem= primitiveElement (v1, vBuf, primFail);
+        ASSERT (!primFail, "failure in integer factorizer");
+        if (primFail)
+          ; //ERROR
+        else
+          imPrimElem= mapPrimElem (primElem, v1, v2);
+
+        CFList source, dest;
+        CanonicalForm bufA= mapUp (A, v1, v2, primElem, imPrimElem,
+                                     source, dest);
+        ExtensionInfo info2= ExtensionInfo (v2, v1, imPrimElem, primElem);
+        factors= biFactorize (bufA, info2);
+        setCharacteristic (p, k, cGFName);
+        for (CFListIterator i= factors; i.hasItem(); i++)
+          i.getItem()= Falpha2GFRep (i.getItem());
+        prune (v1);
+      }
+    }
+    return factors;
+  }
+}
+
+#endif
+/* HAVE_NTL */
+
+
diff --git a/factory/facFqBivar.h b/factory/facFqBivar.h
new file mode 100644
index 0000000..5800b84
--- /dev/null
+++ b/factory/facFqBivar.h
@@ -0,0 +1,767 @@
+/*****************************************************************************\
+ * Computer Algebra System SINGULAR
+\*****************************************************************************/
+/** @file facFqBivar.h
+ *
+ * This file provides functions for factorizing a bivariate polynomial over
+ * \f$ F_{p} \f$ , \f$ F_{p}(\alpha ) \f$ or GF.
+ *
+ * @author Martin Lee
+ *
+ **/
+/*****************************************************************************/
+
+#ifndef FAC_FQ_BIVAR_H
+#define FAC_FQ_BIVAR_H
+
+// #include "config.h"
+
+#include "timing.h"
+#include "cf_assert.h"
+
+#include "facFqBivarUtil.h"
+#include "DegreePattern.h"
+#include "ExtensionInfo.h"
+#include "cf_util.h"
+#include "facFqSquarefree.h"
+#include "cf_map.h"
+#include "cfNewtonPolygon.h"
+#include "fac_util.h"
+
+TIMING_DEFINE_PRINT(fac_fq_bi_sqrf)
+TIMING_DEFINE_PRINT(fac_fq_bi_factor_sqrf)
+
+static const double log2exp= 1.442695041;
+
+#ifdef HAVE_NTL
+/// Factorization of a squarefree bivariate polynomials over an arbitrary finite
+/// field, information on the current field we work over is in @a info. @a info
+/// may also contain information about the initial field if initial and current
+/// field do not coincide. In this case the current field is an extension of the
+/// initial field and the factors returned are factors of F over the initial
+/// field.
+///
+/// @return @a biFactorize returns a list of factors of F. If F is not monic
+///         its leading coefficient is not outputted.
+/// @sa extBifactorize()
+CFList
+biFactorize (const CanonicalForm& F,       ///< [in] a sqrfree bivariate poly
+             const ExtensionInfo& info     ///< [in] information about extension
+            );
+
+inline CFList
+biSqrfFactorizeHelper (const CanonicalForm& G, const ExtensionInfo& info)
+{
+  CFMap N;
+  CanonicalForm F= compress (G, N);
+  CanonicalForm contentX= content (F, 1);
+  CanonicalForm contentY= content (F, 2);
+  F /= (contentX*contentY);
+  CFFList contentXFactors, contentYFactors;
+  if (info.getAlpha().level() != 1)
+  {
+    contentXFactors= factorize (contentX, info.getAlpha());
+    contentYFactors= factorize (contentY, info.getAlpha());
+  }
+  else if (info.getAlpha().level() == 1 && info.getGFDegree() == 1)
+  {
+    contentXFactors= factorize (contentX);
+    contentYFactors= factorize (contentY);
+  }
+  else if (info.getAlpha().level() == 1 && info.getGFDegree() != 1)
+  {
+    CFList bufContentX, bufContentY;
+    bufContentX= biFactorize (contentX, info);
+    bufContentY= biFactorize (contentY, info);
+    for (CFListIterator iter= bufContentX; iter.hasItem(); iter++)
+      contentXFactors.append (CFFactor (iter.getItem(), 1));
+    for (CFListIterator iter= bufContentY; iter.hasItem(); iter++)
+      contentYFactors.append (CFFactor (iter.getItem(), 1));
+  }
+
+  if (contentXFactors.getFirst().factor().inCoeffDomain())
+    contentXFactors.removeFirst();
+  if (contentYFactors.getFirst().factor().inCoeffDomain())
+    contentYFactors.removeFirst();
+  if (F.inCoeffDomain())
+  {
+    CFList result;
+    for (CFFListIterator i= contentXFactors; i.hasItem(); i++)
+      result.append (N (i.getItem().factor()));
+    for (CFFListIterator i= contentYFactors; i.hasItem(); i++)
+      result.append (N (i.getItem().factor()));
+    normalize (result);
+    result.insert (Lc (G));
+    return result;
+  }
+  mpz_t * M=new mpz_t [4];
+  mpz_init (M[0]);
+  mpz_init (M[1]);
+  mpz_init (M[2]);
+  mpz_init (M[3]);
+
+  mpz_t * S=new mpz_t [2];
+  mpz_init (S[0]);
+  mpz_init (S[1]);
+
+  F= compress (F, M, S);
+  CFList result= biFactorize (F, info);
+  for (CFListIterator i= result; i.hasItem(); i++)
+    i.getItem()= N (decompress (i.getItem(), M, S));
+  for (CFFListIterator i= contentXFactors; i.hasItem(); i++)
+    result.append (N(i.getItem().factor()));
+  for (CFFListIterator i= contentYFactors; i.hasItem(); i++)
+    result.append (N (i.getItem().factor()));
+  normalize (result);
+  result.insert (Lc(G));
+
+  mpz_clear (M[0]);
+  mpz_clear (M[1]);
+  mpz_clear (M[2]);
+  mpz_clear (M[3]);
+  delete [] M;
+
+  mpz_clear (S[0]);
+  mpz_clear (S[1]);
+  delete [] S;
+
+  return result;
+}
+
+/// factorize a squarefree bivariate polynomial over \f$ F_{p} \f$.
+///
+/// @return @a FpBiSqrfFactorize returns a list of monic factors, the first
+///         element is the leading coefficient.
+/// @sa FqBiSqrfFactorize(), GFBiSqrfFactorize()
+inline
+CFList FpBiSqrfFactorize (const CanonicalForm & G ///< [in] a bivariate poly
+                         )
+{
+  ExtensionInfo info= ExtensionInfo (false);
+  return biSqrfFactorizeHelper (G, info);
+}
+
+/// factorize a squarefree bivariate polynomial over \f$ F_{p}(\alpha ) \f$.
+///
+/// @return @a FqBiSqrfFactorize returns a list of monic factors, the first
+///         element is the leading coefficient.
+/// @sa FpBiSqrfFactorize(), GFBiSqrfFactorize()
+inline
+CFList FqBiSqrfFactorize (const CanonicalForm & G, ///< [in] a bivariate poly
+                          const Variable& alpha    ///< [in] algebraic variable
+                         )
+{
+  ExtensionInfo info= ExtensionInfo (alpha, false);
+  return biSqrfFactorizeHelper (G, info);
+}
+
+/// factorize a squarefree bivariate polynomial over GF
+///
+/// @return @a GFBiSqrfFactorize returns a list of monic factors, the first
+///         element is the leading coefficient.
+/// @sa FpBiSqrfFactorize(), FqBiSqrfFactorize()
+inline
+CFList GFBiSqrfFactorize (const CanonicalForm & G ///< [in] a bivariate poly
+                         )
+{
+  ASSERT (CFFactory::gettype() == GaloisFieldDomain,
+          "GF as base field expected");
+  ExtensionInfo info= ExtensionInfo (getGFDegree(), gf_name, false);
+  return biSqrfFactorizeHelper (G, info);
+}
+
+/// factorize a bivariate polynomial over \f$ F_{p} \f$
+///
+/// @return @a FpBiFactorize returns a list of monic factors with
+///         multiplicity, the first element is the leading coefficient.
+/// @sa FqBiFactorize(), GFBiFactorize()
+inline
+CFFList
+FpBiFactorize (const CanonicalForm & G, ///< [in] a bivariate poly
+               bool substCheck= true    ///< [in] enables substitute check
+              )
+{
+  ExtensionInfo info= ExtensionInfo (false);
+  CFMap N;
+  CanonicalForm F= compress (G, N);
+
+  if (substCheck)
+  {
+    bool foundOne= false;
+    int * substDegree= new int [F.level()];
+    for (int i= 1; i <= F.level(); i++)
+    {
+      substDegree[i-1]= substituteCheck (F, Variable (i));
+      if (substDegree [i-1] > 1)
+      {
+        foundOne= true;
+        subst (F, F, substDegree[i-1], Variable (i));
+      }
+    }
+    if (foundOne)
+    {
+      CFFList result= FpBiFactorize (F, false);
+      CFFList newResult, tmp;
+      CanonicalForm tmp2;
+      newResult.insert (result.getFirst());
+      result.removeFirst();
+      for (CFFListIterator i= result; i.hasItem(); i++)
+      {
+        tmp2= i.getItem().factor();
+        for (int j= 1; j <= F.level(); j++)
+        {
+          if (substDegree[j-1] > 1)
+            tmp2= reverseSubst (tmp2, substDegree[j-1], Variable (j));
+        }
+        tmp= FpBiFactorize (tmp2, false);
+        tmp.removeFirst();
+        for (CFFListIterator j= tmp; j.hasItem(); j++)
+          newResult.append (CFFactor (j.getItem().factor(),
+                                      j.getItem().exp()*i.getItem().exp()));
+      }
+      decompress (newResult, N);
+      delete [] substDegree;
+      return newResult;
+    }
+    delete [] substDegree;
+  }
+
+  CanonicalForm LcF= Lc (F);
+  CanonicalForm contentX= content (F, 1);
+  CanonicalForm contentY= content (F, 2);
+  F /= (contentX*contentY);
+  CFFList contentXFactors, contentYFactors;
+  contentXFactors= factorize (contentX);
+  contentYFactors= factorize (contentY);
+  if (contentXFactors.getFirst().factor().inCoeffDomain())
+    contentXFactors.removeFirst();
+  if (contentYFactors.getFirst().factor().inCoeffDomain())
+    contentYFactors.removeFirst();
+  decompress (contentXFactors, N);
+  decompress (contentYFactors, N);
+  CFFList result;
+  if (F.inCoeffDomain())
+  {
+    result= Union (contentXFactors, contentYFactors);
+    normalize (result);
+    result.insert (CFFactor (LcF, 1));
+    return result;
+  }
+  mpz_t * M=new mpz_t [4];
+  mpz_init (M[0]);
+  mpz_init (M[1]);
+  mpz_init (M[2]);
+  mpz_init (M[3]);
+
+  mpz_t * S=new mpz_t [2];
+  mpz_init (S[0]);
+  mpz_init (S[1]);
+
+  F= compress (F, M, S);
+
+  TIMING_START (fac_fq_bi_sqrf);
+  CFFList sqrf= FpSqrf (F, false);
+  TIMING_END_AND_PRINT (fac_fq_bi_sqrf,
+                       "time for bivariate sqrf factors over Fp: ");
+  CFList bufResult;
+  sqrf.removeFirst();
+  CFListIterator i;
+  for (CFFListIterator iter= sqrf; iter.hasItem(); iter++)
+  {
+    TIMING_START (fac_fq_bi_factor_sqrf);
+    bufResult= biFactorize (iter.getItem().factor(), info);
+    TIMING_END_AND_PRINT (fac_fq_bi_factor_sqrf,
+                          "time to factor bivariate sqrf factors over Fp: ");
+    for (i= bufResult; i.hasItem(); i++)
+      result.append (CFFactor (N (decompress (i.getItem(), M, S)),
+                               iter.getItem().exp()));
+  }
+
+  result= Union (result, contentXFactors);
+  result= Union (result, contentYFactors);
+  normalize (result);
+  result.insert (CFFactor (LcF, 1));
+
+  mpz_clear (M[0]);
+  mpz_clear (M[1]);
+  mpz_clear (M[2]);
+  mpz_clear (M[3]);
+  delete [] M;
+
+  mpz_clear (S[0]);
+  mpz_clear (S[1]);
+  delete [] S;
+
+  return result;
+}
+
+/// factorize a bivariate polynomial over \f$ F_{p}(\alpha ) \f$
+///
+/// @return @a FqBiFactorize returns a list of monic factors with
+///         multiplicity, the first element is the leading coefficient.
+/// @sa FpBiFactorize(), FqBiFactorize()
+inline
+CFFList
+FqBiFactorize (const CanonicalForm & G, ///< [in] a bivariate poly
+               const Variable & alpha,  ///< [in] algebraic variable
+               bool substCheck= true    ///< [in] enables substitute check
+              )
+{
+  ExtensionInfo info= ExtensionInfo (alpha, false);
+  CFMap N;
+  CanonicalForm F= compress (G, N);
+
+  if (substCheck)
+  {
+    bool foundOne= false;
+    int * substDegree= new int [F.level()];
+    for (int i= 1; i <= F.level(); i++)
+    {
+      substDegree[i-1]= substituteCheck (F, Variable (i));
+      if (substDegree [i-1] > 1)
+      {
+        foundOne= true;
+        subst (F, F, substDegree[i-1], Variable (i));
+      }
+    }
+    if (foundOne)
+    {
+      CFFList result= FqBiFactorize (F, alpha, false);
+      CFFList newResult, tmp;
+      CanonicalForm tmp2;
+      newResult.insert (result.getFirst());
+      result.removeFirst();
+      for (CFFListIterator i= result; i.hasItem(); i++)
+      {
+        tmp2= i.getItem().factor();
+        for (int j= 1; j <= F.level(); j++)
+        {
+          if (substDegree[j-1] > 1)
+            tmp2= reverseSubst (tmp2, substDegree[j-1], Variable (j));
+        }
+        tmp= FqBiFactorize (tmp2, alpha, false);
+        tmp.removeFirst();
+        for (CFFListIterator j= tmp; j.hasItem(); j++)
+          newResult.append (CFFactor (j.getItem().factor(),
+                                      j.getItem().exp()*i.getItem().exp()));
+      }
+      decompress (newResult, N);
+      delete [] substDegree;
+      return newResult;
+    }
+    delete [] substDegree;
+  }
+
+  CanonicalForm LcF= Lc (F);
+  CanonicalForm contentX= content (F, 1);
+  CanonicalForm contentY= content (F, 2);
+  F /= (contentX*contentY);
+  CFFList contentXFactors, contentYFactors;
+  contentXFactors= factorize (contentX, alpha);
+  contentYFactors= factorize (contentY, alpha);
+  if (contentXFactors.getFirst().factor().inCoeffDomain())
+    contentXFactors.removeFirst();
+  if (contentYFactors.getFirst().factor().inCoeffDomain())
+    contentYFactors.removeFirst();
+  decompress (contentXFactors, N);
+  decompress (contentYFactors, N);
+  CFFList result;
+  if (F.inCoeffDomain())
+  {
+    result= Union (contentXFactors, contentYFactors);
+    normalize (result);
+    result.insert (CFFactor (LcF, 1));
+    return result;
+  }
+
+  mpz_t * M=new mpz_t [4];
+  mpz_init (M[0]);
+  mpz_init (M[1]);
+  mpz_init (M[2]);
+  mpz_init (M[3]);
+
+  mpz_t * S=new mpz_t [2];
+  mpz_init (S[0]);
+  mpz_init (S[1]);
+
+  F= compress (F, M, S);
+
+  TIMING_START (fac_fq_bi_sqrf);
+  CFFList sqrf= FqSqrf (F, alpha, false);
+  TIMING_END_AND_PRINT (fac_fq_bi_sqrf,
+                       "time for bivariate sqrf factors over Fq: ");
+  CFList bufResult;
+  sqrf.removeFirst();
+  CFListIterator i;
+  for (CFFListIterator iter= sqrf; iter.hasItem(); iter++)
+  {
+    TIMING_START (fac_fq_bi_factor_sqrf);
+    bufResult= biFactorize (iter.getItem().factor(), info);
+    TIMING_END_AND_PRINT (fac_fq_bi_factor_sqrf,
+                          "time to factor bivariate sqrf factors over Fq: ");
+    for (i= bufResult; i.hasItem(); i++)
+      result.append (CFFactor (N (decompress (i.getItem(), M, S)),
+                               iter.getItem().exp()));
+  }
+
+  result= Union (result, contentXFactors);
+  result= Union (result, contentYFactors);
+  normalize (result);
+  result.insert (CFFactor (LcF, 1));
+
+  mpz_clear (M[0]);
+  mpz_clear (M[1]);
+  mpz_clear (M[2]);
+  mpz_clear (M[3]);
+  delete [] M;
+
+  mpz_clear (S[0]);
+  mpz_clear (S[1]);
+  delete [] S;
+
+  return result;
+}
+
+/// factorize a bivariate polynomial over GF
+///
+/// @return @a GFBiFactorize returns a list of monic factors with
+///         multiplicity, the first element is the leading coefficient.
+/// @sa FpBiFactorize(), FqBiFactorize()
+inline
+CFFList
+GFBiFactorize (const CanonicalForm & G, ///< [in] a bivariate poly
+               bool substCheck= true    ///< [in] enables substitute check
+              )
+{
+  ASSERT (CFFactory::gettype() == GaloisFieldDomain,
+          "GF as base field expected");
+  ExtensionInfo info= ExtensionInfo (getGFDegree(), gf_name, false);
+  CFMap N;
+  CanonicalForm F= compress (G, N);
+
+  if (substCheck)
+  {
+    bool foundOne= false;
+    int * substDegree= new int [F.level()];
+    for (int i= 1; i <= F.level(); i++)
+    {
+      substDegree[i-1]= substituteCheck (F, Variable (i));
+      if (substDegree [i-1] > 1)
+      {
+        foundOne= true;
+        subst (F, F, substDegree[i-1], Variable (i));
+      }
+    }
+    if (foundOne)
+    {
+      CFFList result= GFBiFactorize (F, false);
+      CFFList newResult, tmp;
+      CanonicalForm tmp2;
+      newResult.insert (result.getFirst());
+      result.removeFirst();
+      for (CFFListIterator i= result; i.hasItem(); i++)
+      {
+        tmp2= i.getItem().factor();
+        for (int j= 1; j <= F.level(); j++)
+        {
+          if (substDegree[j-1] > 1)
+            tmp2= reverseSubst (tmp2, substDegree[j-1], Variable (j));
+        }
+        tmp= GFBiFactorize (tmp2, false);
+        tmp.removeFirst();
+        for (CFFListIterator j= tmp; j.hasItem(); j++)
+          newResult.append (CFFactor (j.getItem().factor(),
+                                      j.getItem().exp()*i.getItem().exp()));
+      }
+      decompress (newResult, N);
+      delete [] substDegree;
+      return newResult;
+    }
+    delete [] substDegree;
+  }
+
+  CanonicalForm LcF= Lc (F);
+  CanonicalForm contentX= content (F, 1);
+  CanonicalForm contentY= content (F, 2);
+  F /= (contentX*contentY);
+  CFFList contentXFactors, contentYFactors;
+  contentXFactors= factorize (contentX);
+  contentYFactors= factorize (contentY);
+  if (contentXFactors.getFirst().factor().inCoeffDomain())
+    contentXFactors.removeFirst();
+  if (contentYFactors.getFirst().factor().inCoeffDomain())
+    contentYFactors.removeFirst();
+  decompress (contentXFactors, N);
+  decompress (contentYFactors, N);
+  CFFList result;
+  if (F.inCoeffDomain())
+  {
+    result= Union (contentXFactors, contentYFactors);
+    normalize (result);
+    result.insert (CFFactor (LcF, 1));
+    return result;
+  }
+
+  mpz_t * M=new mpz_t [4];
+  mpz_init (M[0]);
+  mpz_init (M[1]);
+  mpz_init (M[2]);
+  mpz_init (M[3]);
+
+  mpz_t * S=new mpz_t [2];
+  mpz_init (S[0]);
+  mpz_init (S[1]);
+
+  F= compress (F, M, S);
+
+  TIMING_START (fac_fq_bi_sqrf);
+  CFFList sqrf= GFSqrf (F, false);
+  TIMING_END_AND_PRINT (fac_fq_bi_sqrf,
+                       "time for bivariate sqrf factors over GF: ");
+  CFList bufResult;
+  sqrf.removeFirst();
+  CFListIterator i;
+  for (CFFListIterator iter= sqrf; iter.hasItem(); iter++)
+  {
+    TIMING_START (fac_fq_bi_factor_sqrf);
+    bufResult= biFactorize (iter.getItem().factor(), info);
+    TIMING_END_AND_PRINT (fac_fq_bi_factor_sqrf,
+                          "time to factor bivariate sqrf factors over GF: ");
+    for (i= bufResult; i.hasItem(); i++)
+      result.append (CFFactor (N (decompress (i.getItem(), M, S)),
+                               iter.getItem().exp()));
+  }
+
+  result= Union (result, contentXFactors);
+  result= Union (result, contentYFactors);
+  normalize (result);
+  result.insert (CFFactor (LcF, 1));
+
+  mpz_clear (M[0]);
+  mpz_clear (M[1]);
+  mpz_clear (M[2]);
+  mpz_clear (M[3]);
+  delete [] M;
+
+  mpz_clear (S[0]);
+  mpz_clear (S[1]);
+  delete [] S;
+
+  return result;
+}
+
+/// \f$ \prod_{f\in L} {f (0, x)} \ mod\ M \f$ via divide-and-conquer
+///
+/// @return @a prodMod0 computes the above defined product
+/// @sa prodMod()
+CanonicalForm prodMod0 (const CFList& L,       ///< [in] a list of compressed,
+                                               ///< bivariate polynomials
+                        const CanonicalForm& M,///< [in] a power of Variable (2)
+                        const modpk& b= modpk()///< [in] coeff bound
+                       );
+
+/// find an evaluation point p, s.t. F(p,y) is squarefree and
+/// \f$ deg_{y} (F(p,y))= deg_{y} (F(x,y)) \f$.
+///
+/// @return @a evalPoint returns an evaluation point, which is valid if and only
+///         if fail == false.
+CanonicalForm
+evalPoint (const CanonicalForm& F, ///< [in] compressed, bivariate poly
+           CanonicalForm & eval,   ///< [in,out] F (p, y)
+           const Variable& alpha,  ///< [in] algebraic variable
+           CFList& list,           ///< [in] list of points already considered
+           const bool& GF,         ///< [in] GaloisFieldDomain?
+           bool& fail              ///< [in,out] equals true, if there is no
+                                   ///< valid evaluation point
+          );
+
+/// Univariate factorization of squarefree monic polys over finite fields via
+/// NTL. If the characteristic is even special GF2 routines of NTL are used.
+///
+/// @return @a uniFactorizer returns a list of monic factors
+CFList
+uniFactorizer (const CanonicalForm& A, ///< [in] squarefree univariate poly
+               const Variable& alpha,  ///< [in] algebraic variable
+               const bool& GF          ///< [in] GaloisFieldDomain?
+              );
+
+/// naive factor recombination over an extension of the initial field.
+/// Uses precomputed data to exclude combinations that are not possible.
+///
+/// @return @a extFactorRecombination returns a list of factors over the initial
+///         field, whose shift to zero is reversed.
+/// @sa factorRecombination(), extEarlyFactorDetection()
+CFList
+extFactorRecombination (
+         CFList& factors,          ///< [in,out] list of lifted factors that are
+                                   ///< monic wrt Variable (1),
+                                   ///< original factors-factors found
+         CanonicalForm& F,         ///< [in,out] poly to be factored,
+                                   ///< F/factors found
+         const CanonicalForm& M,   ///< [in] Variable (2)^liftBound
+         const ExtensionInfo& info,///< [in] contains information about
+                                   ///< extension
+         DegreePattern& degs,
+         const CanonicalForm& eval,///< [in] evaluation point
+         int s,                    ///< [in] algorithm starts checking subsets
+                                   ///< of size s
+         int thres                 ///< [in] threshold for the size of subsets
+                                   ///< which are checked, for a full factor
+                                   ///< recombination choose
+                                   ///< thres= factors.length()/2
+                       );
+
+/// naive factor recombination.
+/// Uses precomputed data to exclude combinations that are not possible.
+///
+/// @return @a factorRecombination returns a list of factors of F.
+/// @sa extFactorRecombination(), earlyFactorDetectection()
+CFList
+factorRecombination (
+            CFList& factors,            ///< [in,out] list of lifted factors
+                                        ///< that are monic wrt Variable (1)
+            CanonicalForm& F,           ///< [in,out] poly to be factored
+            const CanonicalForm& M,     ///< [in] Variable (2)^liftBound
+            DegreePattern& degs,        ///< [in] degree pattern
+            const CanonicalForm& eval,  ///< [in] evaluation point
+            int s,                      ///< [in] algorithm starts checking
+                                        ///< subsets of size s
+            int thres,                  ///< [in] threshold for the size of
+                                        ///< subsets which are checked, for a
+                                        ///< full factor recombination choose
+                                        ///< thres= factors.length()/2
+            const modpk& b=modpk(),     ///< [in] coeff bound
+            const CanonicalForm& den= 1 ///< [in] bound on the den if over Q (a)
+                    );
+
+/// chooses a field extension.
+///
+/// @return @a chooseExtension returns an extension specified by @a beta of
+///         appropiate size
+Variable chooseExtension (
+                      const Variable & alpha, ///< [in] some algebraic variable
+                      const Variable & beta,  ///< [in] some algebraic variable
+                      int k                   ///< [in] some int
+                         );
+
+/// compute lifting precisions from the shape of the Newton polygon of F
+///
+/// @return @a getLiftPrecisions returns lifting precisions computed from the
+/// shape of the Newton polygon of F
+int *
+getLiftPrecisions (const CanonicalForm& F, ///< [in] a bivariate poly
+                   int& sizeOfOutput,      ///< [in,out] size of the output
+                   int degreeLC            ///< [in] degree of the leading coeff
+                                           ///< [in] of F wrt. Variable (1)
+                  );
+
+
+/// detects factors of @a F at stage @a deg of Hensel lifting.
+/// No combinations of more than one factor are tested. Lift bound and possible
+/// degree pattern are updated.
+///
+/// @sa factorRecombination(), extEarlyFactorDetection()
+void
+earlyFactorDetection (
+           CFList& reconstructedFactors, ///< [in,out] list of reconstructed
+                                         ///< factors
+           CanonicalForm& F,       ///< [in,out] poly to be factored, returns
+                                   ///< poly divided by detected factors in case
+                                   ///< of success
+           CFList& factors,        ///< [in,out] list of factors lifted up to
+                                   ///< @a deg, returns a list of factors
+                                   ///< without detected factors
+           int& adaptedLiftBound,  ///< [in,out] adapted lift bound
+           int*& factorsFoundIndex,///< [in,out] factors already considered
+           DegreePattern& degs,    ///< [in,out] degree pattern, is updated
+                                   ///< whenever we find a factor
+           bool& success,          ///< [in,out] indicating success
+           int deg,                ///< [in] stage of Hensel lifting
+           const CanonicalForm& eval, ///<[in] evaluation point
+           const modpk& b= modpk()///< [in] coeff bound
+                     );
+
+/// detects factors of @a F at stage @a deg of Hensel lifting.
+/// No combinations of more than one factor are tested. Lift bound and possible
+/// degree pattern are updated.
+///
+/// @sa factorRecombination(), earlyFactorDetection()
+void
+extEarlyFactorDetection (
+        CFList& reconstructedFactors, ///< [in,out] list of reconstructed
+                                      ///< factors
+        CanonicalForm& F,          ///< [in,out] poly to be factored, returns
+                                   ///< poly divided by detected factors in case
+                                   ///< of success
+        CFList& factors,           ///< [in,out] list of factors lifted up to
+                                   ///< @a deg, returns a list of factors
+                                   ///< without detected factors
+        int& adaptedLiftBound,     ///< [in,out] adapted lift bound
+        int*& factorsFoundIndex,   ///< [in,out] factors already considered
+        DegreePattern& degs,       ///< [in,out] degree pattern, is updated
+                                   ///< whenever we find a factor
+        bool& success,             ///< [in,out] indicating success
+        const ExtensionInfo& info,  ///< [in] information about extension
+        const CanonicalForm& eval, ///< [in] evaluation point
+        int deg                    ///< [in] stage of Hensel lifting
+                      );
+
+/// hensel Lifting and early factor detection
+///
+/// @return @a henselLiftAndEarly returns monic (wrt Variable (1)) lifted
+///         factors without factors which have been detected at an early stage
+///         of Hensel lifting
+/// @sa earlyFactorDetection(), extEarlyFactorDetection()
+
+CFList
+henselLiftAndEarly (
+        CanonicalForm& A,          ///< [in,out] poly to be factored,
+                                   ///< returns poly divided by detected factors
+                                   ///< in case of success
+        bool& earlySuccess,        ///< [in,out] indicating success
+        CFList& earlyFactors,      ///< [in,out] list of factors detected
+                                   ///< at early stage of Hensel lifting
+        DegreePattern& degs,       ///< [in,out] degree pattern
+        int& liftBound,            ///< [in,out] (adapted) lift bound
+        const CFList& uniFactors,  ///< [in] univariate factors
+        const ExtensionInfo& info, ///< [in] information about extension
+        const CanonicalForm& eval, ///< [in] evaluation point
+        modpk& b,                  ///< [in] coeff bound
+        CanonicalForm& den         ///< [in] bound on the den if over Q(a)
+                  );
+
+/// hensel Lifting and early factor detection
+///
+/// @return @a henselLiftAndEarly returns monic (wrt Variable (1)) lifted
+///         factors without factors which have been detected at an early stage
+///         of Hensel lifting
+/// @sa earlyFactorDetection(), extEarlyFactorDetection()
+
+CFList
+henselLiftAndEarly (
+        CanonicalForm& A,          ///< [in,out] poly to be factored,
+                                   ///< returns poly divided by detected factors
+                                   ///< in case of success
+        bool& earlySuccess,        ///< [in,out] indicating success
+        CFList& earlyFactors,      ///< [in,out] list of factors detected
+                                   ///< at early stage of Hensel lifting
+        DegreePattern& degs,       ///< [in,out] degree pattern
+        int& liftBound,            ///< [in,out] (adapted) lift bound
+        const CFList& uniFactors,  ///< [in] univariate factors
+        const ExtensionInfo& info, ///< [in] information about extension
+        const CanonicalForm& eval  ///< [in] evaluation point
+                  );
+
+/// Factorization over an extension of initial field
+///
+/// @return @a extBiFactorize returns factorization of F over initial field
+/// @sa biFactorize()
+CFList
+extBiFactorize (const CanonicalForm& F,    ///< [in] poly to be factored
+                const ExtensionInfo& info  ///< [in] info about extension
+               );
+
+#endif
+#endif
+/* FAC_FQ_BIVAR_H */
+
diff --git a/factory/facFqBivarUtil.cc b/factory/facFqBivarUtil.cc
new file mode 100644
index 0000000..d6d8581
--- /dev/null
+++ b/factory/facFqBivarUtil.cc
@@ -0,0 +1,1313 @@
+/*****************************************************************************\
+ * Computer Algebra System SINGULAR
+\*****************************************************************************/
+/** @file facFqBivarUtil.cc
+ *
+ * This file provides utility functions for bivariate factorization
+ *
+ * @author Martin Lee
+ *
+ **/
+/*****************************************************************************/
+
+
+#include "config.h"
+
+
+#include "timing.h"
+
+#include "cf_map.h"
+#include "cf_map_ext.h"
+#include "templates/ftmpl_functions.h"
+#include "ExtensionInfo.h"
+#include "cf_algorithm.h"
+#include "cf_factory.h"
+#include "cf_util.h"
+#include "imm.h"
+#include "cf_iter.h"
+#include "facFqBivarUtil.h"
+#include "cfNewtonPolygon.h"
+#include "facHensel.h"
+#include "facMul.h"
+
+#ifdef HAVE_FLINT
+#include "FLINTconvert.h"
+#endif
+
+TIMING_DEFINE_PRINT(fac_log_deriv_div)
+TIMING_DEFINE_PRINT(fac_log_deriv_mul)
+TIMING_DEFINE_PRINT(fac_log_deriv_pre)
+
+void append (CFList& factors1, const CFList& factors2)
+{
+  for (CFListIterator i= factors2; i.hasItem(); i++)
+  {
+    if (!i.getItem().inCoeffDomain())
+      factors1.append (i.getItem());
+  }
+  return;
+}
+
+void decompress (CFList& factors, const CFMap& N)
+{
+  for (CFListIterator i= factors; i.hasItem(); i++)
+    i.getItem()= N (i.getItem());
+}
+
+void decompress (CFFList& factors, const CFMap& N)
+{
+  for (CFFListIterator i= factors; i.hasItem(); i++)
+    i.getItem()= CFFactor (N (i.getItem().factor()), i.getItem().exp());
+}
+
+void decompress (CFAFList& factors, const CFMap& N)
+{
+  for (CFAFListIterator i= factors; i.hasItem(); i++)
+    i.getItem()= CFAFactor (N (i.getItem().factor()), i.getItem().minpoly(),
+                            i.getItem().exp());
+}
+
+void appendSwapDecompress (CFList& factors1, const CFList& factors2,
+                           const CFList& factors3, const bool swap1,
+                           const bool swap2, const CFMap& N)
+{
+  Variable x= Variable (1);
+  Variable y= Variable (2);
+  for (CFListIterator i= factors1; i.hasItem(); i++)
+  {
+    if (swap1)
+    {
+      if (!swap2)
+        i.getItem()= swapvar (i.getItem(), x, y);
+    }
+    else
+    {
+      if (swap2)
+        i.getItem()= swapvar (i.getItem(), y, x);
+    }
+    i.getItem()= N (i.getItem());
+  }
+  for (CFListIterator i= factors2; i.hasItem(); i++)
+    factors1.append (N (i.getItem()));
+  for (CFListIterator i= factors3; i.hasItem(); i++)
+    factors1.append (N (i.getItem()));
+  return;
+}
+
+void swapDecompress (CFList& factors, const bool swap, const CFMap& N)
+{
+  Variable x= Variable (1);
+  Variable y= Variable (2);
+  for (CFListIterator i= factors; i.hasItem(); i++)
+  {
+    if (swap)
+      i.getItem()= swapvar (i.getItem(), x, y);
+    i.getItem()= N (i.getItem());
+  }
+  return;
+}
+
+static inline
+bool GFInExtensionHelper (const CanonicalForm& F, const int number)
+{
+  if (F.isOne()) return false;
+  InternalCF* buf;
+  int exp;
+  bool result= false;
+  if (F.inBaseDomain())
+  {
+    buf= F.getval();
+    exp= imm2int (buf);
+    if (exp%number != 0)
+      return true;
+    else
+      return result;
+  }
+  else
+  {
+    for (CFIterator i= F; i.hasTerms(); i++)
+    {
+      result= GFInExtensionHelper (i.coeff(), number);
+      if (result == true)
+        return result;
+    }
+  }
+  return result;
+}
+
+static inline
+bool FqInExtensionHelper (const CanonicalForm& F, const CanonicalForm& gamma,
+                          const CanonicalForm& delta, CFList& source,
+                          CFList& dest)
+{
+  bool result= false;
+  if (F.inBaseDomain())
+    return result;
+  else if (F.inCoeffDomain())
+  {
+    if (!fdivides (gamma, F))
+      return true;
+    else
+    {
+      int pos= findItem (source, F);
+      if (pos > 0)
+        return false;
+      Variable a;
+      hasFirstAlgVar (F, a);
+      int bound= ipower (getCharacteristic(), degree (getMipo (a)));
+      CanonicalForm buf= 1;
+      for (int i= 1; i < bound; i++)
+      {
+        buf *= gamma;
+        if (buf == F)
+        {
+          source.append (buf);
+          dest.append (power (delta, i));
+          return false;
+        }
+      }
+      return true;
+    }
+  }
+  else
+  {
+    for (CFIterator i= F; i.hasTerms(); i++)
+    {
+      result= FqInExtensionHelper (i.coeff(), gamma, delta, source, dest);
+      if (result == true)
+        return result;
+    }
+  }
+  return result;
+}
+
+bool isInExtension (const CanonicalForm& F, const CanonicalForm& gamma,
+                    const int k, const CanonicalForm& delta,
+                    CFList& source, CFList& dest)
+{
+  bool result;
+  if (CFFactory::gettype() == GaloisFieldDomain)
+  {
+    int p= getCharacteristic();
+    int orderFieldExtension= ipower (p, getGFDegree()) - 1;
+    int order= ipower (p, k) - 1;
+    int number= orderFieldExtension/order;
+    result= GFInExtensionHelper (F, number);
+    return result;
+  }
+  else
+  {
+    result= FqInExtensionHelper (F, gamma, delta, source, dest);
+    return result;
+  }
+}
+
+CanonicalForm
+mapDown (const CanonicalForm& F, const ExtensionInfo& info, CFList& source,
+         CFList& dest)
+{
+  int k= info.getGFDegree();
+  Variable beta= info.getAlpha();
+  CanonicalForm primElem= info.getGamma();
+  CanonicalForm imPrimElem= info.getDelta();
+  if (k > 1)
+    return GFMapDown (F, k);
+  else if (k == 1)
+    return F;
+  if (/*k==0 &&*/ beta == Variable (1))
+    return F;
+  else /*if (k==0 && beta != Variable (1))*/
+    return mapDown (F, imPrimElem, primElem, beta, source, dest);
+}
+
+void appendTestMapDown (CFList& factors, const CanonicalForm& f,
+                        const ExtensionInfo& info, CFList& source, CFList& dest)
+{
+  int k= info.getGFDegree();
+  Variable beta= info.getBeta();
+  Variable alpha= info.getAlpha();
+  CanonicalForm delta= info.getDelta();
+  CanonicalForm gamma= info.getGamma();
+  CanonicalForm g= f;
+  int degMipoBeta;
+  if (!k && beta.level() == 1)
+    degMipoBeta= 1;
+  else if (!k && beta.level() != 1)
+    degMipoBeta= degree (getMipo (beta));
+  if (k > 1)
+  {
+    if (!isInExtension (g, gamma, k, delta, source, dest))
+    {
+      g= GFMapDown (g, k);
+      factors.append (g);
+    }
+  }
+  else if (k == 1)
+  {
+    if (!isInExtension (g, gamma, k, delta, source, dest))
+      factors.append (g);
+  }
+  else if (!k && beta == Variable (1))
+  {
+    if (degree (g, alpha) < degMipoBeta)
+      factors.append (g);
+  }
+  else if (!k && beta != Variable (1))
+  {
+    if (!isInExtension (g, gamma, k, delta, source, dest))
+    {
+      g= mapDown (g, delta, gamma, alpha, source, dest);
+      factors.append (g);
+    }
+  }
+  return;
+}
+
+void
+appendMapDown (CFList& factors, const CanonicalForm& g,
+               const ExtensionInfo& info, CFList& source, CFList& dest)
+{
+  int k= info.getGFDegree();
+  Variable beta= info.getBeta();
+  Variable alpha= info.getAlpha();
+  CanonicalForm gamma= info.getGamma();
+  CanonicalForm delta= info.getDelta();
+  if (k > 1)
+    factors.append (GFMapDown (g, k));
+  else if (k == 1)
+    factors.append (g);
+  else if (!k && beta == Variable (1))
+    factors.append (g);
+  else if (!k && beta != Variable (1))
+    factors.append (mapDown (g, delta, gamma, alpha, source, dest));
+  return;
+}
+
+void normalize (CFList& factors)
+{
+  CanonicalForm lcinv;
+  for (CFListIterator i= factors; i.hasItem(); i++)
+  {
+    lcinv= 1/Lc (i.getItem());
+    i.getItem() *= lcinv;
+  }
+  return;
+}
+
+void normalize (CFFList& factors)
+{
+  CanonicalForm lcinv;
+  for (CFFListIterator i= factors; i.hasItem(); i++)
+  {
+    lcinv= 1/ Lc (i.getItem().factor());
+    i.getItem()= CFFactor (i.getItem().factor()*lcinv,
+                           i.getItem().exp());
+  }
+  return;
+}
+
+CFList subset (int index [], const int& s, const CFArray& elements,
+               bool& noSubset)
+{
+  int r= elements.size();
+  int i= 0;
+  CFList result;
+  noSubset= false;
+  if (index[s - 1] == 0)
+  {
+    while (i < s)
+    {
+      index[i]= i + 1;
+      result.append (elements[i]);
+      i++;
+    }
+    return result;
+  }
+  int buf;
+  int k;
+  bool found= false;
+  if (index[s - 1] == r)
+  {
+    if (index[0] == r - s + 1)
+    {
+      noSubset= true;
+      return result;
+    }
+    else {
+      while (found == false)
+      {
+        if (index[s - 2 - i] < r - i - 1)
+          found= true;
+        i++;
+      }
+      buf= index[s - i - 1];
+      k= 0;
+      while (s - i - 1 + k < s)
+      {
+        index[s - i - 1 + k]= buf + k + 1;
+        k++;
+      }
+    }
+    for (int j= 0; j < s; j++)
+      result.append (elements[index[j] - 1]);
+    return result;
+  }
+  else
+  {
+    index[s - 1] += 1;
+    for (int j= 0; j < s; j++)
+      result.append (elements[index[j] - 1]);
+    return result;
+  }
+}
+
+CFArray copy (const CFList& list)
+{
+  CFArray array= CFArray (list.length());
+  int j= 0;
+  for (CFListIterator i= list; i.hasItem(); i++, j++)
+    array[j]= i.getItem();
+  return array;
+}
+
+void indexUpdate (int index [], const int& subsetSize, const int& setSize,
+                   bool& noSubset)
+{
+  noSubset= false;
+  if (subsetSize > setSize)
+  {
+    noSubset= true;
+    return;
+  }
+  int * v= new int [setSize];
+  for (int i= 0; i < setSize; i++)
+    v[i]= index[i];
+  if (subsetSize == 1)
+  {
+    v[0]= v[0] - 1;
+    if (v[0] >= setSize)
+    {
+      noSubset= true;
+      delete [] v;
+      return;
+    }
+  }
+  else
+  {
+    if (v[subsetSize - 1] - v[0] + 1 == subsetSize && v[0] > 1)
+    {
+      if (v[0] + subsetSize - 1 > setSize)
+      {
+        noSubset= true;
+        delete [] v;
+        return;
+      }
+      v[0]= v[0] - 1;
+      for (int i= 1; i < subsetSize - 1; i++)
+        v[i]= v[i - 1] + 1;
+      v[subsetSize - 1]= v[subsetSize - 2];
+    }
+    else
+    {
+      if (v[0] + subsetSize - 1 > setSize)
+      {
+        noSubset= true;
+        delete [] v;
+        return;
+      }
+      for (int i= 1; i < subsetSize - 1; i++)
+        v[i]= v[i - 1] + 1;
+      v[subsetSize - 1]= v[subsetSize - 2];
+    }
+  }
+  for (int i= 0; i < setSize; i++)
+    index[i]= v[i];
+  delete [] v;
+}
+
+int subsetDegree (const CFList& S)
+{
+  int result= 0;
+  for (CFListIterator i= S; i.hasItem(); i++)
+    result += degree (i.getItem(), Variable (1));
+  return result;
+}
+
+CFFList multiplicity (CanonicalForm& F, const CFList& factors)
+{
+  if (F.inCoeffDomain())
+    return CFFList (CFFactor (F, 1));
+  CFFList result;
+  int multi= 0;
+  CanonicalForm quot;
+  for (CFListIterator i= factors; i.hasItem(); i++)
+  {
+    while (fdivides (i.getItem(), F, quot))
+    {
+      multi++;
+      F= quot;
+    }
+    if (multi > 0)
+      result.append (CFFactor (i.getItem(), multi));
+    multi= 0;
+  }
+  return result;
+}
+
+#ifdef HAVE_NTL
+CFArray
+logarithmicDerivative (const CanonicalForm& F, const CanonicalForm& G, int l,
+                       CanonicalForm& Q
+                      )
+{
+  Variable x= Variable (2);
+  Variable y= Variable (1);
+  CanonicalForm xToL= power (x, l);
+  CanonicalForm q,r;
+  CanonicalForm logDeriv;
+
+  TIMING_START (fac_log_deriv_div);
+  q= newtonDiv (F, G, xToL);
+  TIMING_END_AND_PRINT (fac_log_deriv_div, "time for division in logderiv1: ");
+
+  TIMING_START (fac_log_deriv_mul);
+  logDeriv= mulMod2 (q, deriv (G, y), xToL);
+  TIMING_END_AND_PRINT (fac_log_deriv_mul, "time to multiply in logderiv1: ");
+
+  if (degree (logDeriv, x) == 0)
+  {
+    Q= q;
+    return CFArray();
+  }
+
+  int j= degree (logDeriv, y) + 1;
+  CFArray result= CFArray (j);
+  CFIterator ii;
+  for (CFIterator i= logDeriv; i.hasTerms() && !logDeriv.isZero(); i++)
+  {
+    if (i.coeff().inCoeffDomain())
+      result[0] += i.coeff()*power (x,i.exp());
+    else
+    {
+      for (ii= i.coeff(); ii.hasTerms(); ii++)
+        result[ii.exp()] += ii.coeff()*power (x,i.exp());
+    }
+  }
+  Q= q;
+  return result;
+}
+
+CFArray
+logarithmicDerivative (const CanonicalForm& F, const CanonicalForm& G, int l,
+                       int oldL, const CanonicalForm& oldQ, CanonicalForm& Q
+                      )
+{
+  Variable x= Variable (2);
+  Variable y= Variable (1);
+  CanonicalForm xToL= power (x, l);
+  CanonicalForm xToOldL= power (x, oldL);
+  CanonicalForm xToLOldL= power (x, l-oldL);
+  CanonicalForm q,r;
+  CanonicalForm logDeriv;
+
+  CanonicalForm bufF;
+  TIMING_START (fac_log_deriv_pre);
+  if ((oldL > 100 && l - oldL < 50) || (oldL < 100 && l - oldL < 30))
+  {
+    bufF= F;
+    CanonicalForm oldF= mulMod2 (G, oldQ, xToL);
+    bufF -= oldF;
+    bufF= div (bufF, xToOldL);
+  }
+  else
+  {
+    //middle product style computation of [G*oldQ]^{l}_{oldL}
+    CanonicalForm G3= div (G, xToOldL);
+    CanonicalForm Up= mulMod2 (G3, oldQ, xToLOldL);
+    CanonicalForm xToOldL2= power (x, (oldL+1)/2);
+    CanonicalForm G2= mod (G, xToOldL);
+    CanonicalForm G1= div (G2, xToOldL2);
+    CanonicalForm G0= mod (G2, xToOldL2);
+    CanonicalForm oldQ1= div (oldQ, xToOldL2);
+    CanonicalForm oldQ0= mod (oldQ, xToOldL2);
+    CanonicalForm Mid;
+    if (oldL % 2 == 1)
+      Mid= mulMod2 (G1, oldQ1*x, xToLOldL);
+    else
+      Mid= mulMod2 (G1, oldQ1, xToLOldL);
+    //computation of Low might be faster using a real middle product?
+    CanonicalForm Low= mulMod2 (G0, oldQ1, xToOldL)+mulMod2 (G1, oldQ0, xToOldL);
+    Low= div (Low, power (x, oldL/2));
+    Low= mod (Low, xToLOldL);
+    Up += Mid + Low;
+    bufF= div (F, xToOldL);
+    bufF -= Up;
+  }
+  TIMING_END_AND_PRINT (fac_log_deriv_pre, "time to preprocess: ");
+
+  TIMING_START (fac_log_deriv_div);
+  if (l-oldL > 0)
+    q= newtonDiv (bufF, G, xToLOldL);
+  else
+    q= 0;
+  q *= xToOldL;
+  q += oldQ;
+  TIMING_END_AND_PRINT (fac_log_deriv_div, "time for div in logderiv2: ");
+
+  TIMING_START (fac_log_deriv_mul);
+  logDeriv= mulMod2 (q, deriv (G, y), xToL);
+  TIMING_END_AND_PRINT (fac_log_deriv_mul, "time for mul in logderiv2: ");
+
+  if (degree (logDeriv, x) == 0)
+  {
+    Q= q;
+    return CFArray();
+  }
+
+  int j= degree (logDeriv,y) + 1;
+  CFArray result= CFArray (j);
+  CFIterator ii;
+  for (CFIterator i= logDeriv; i.hasTerms() && !logDeriv.isZero(); i++)
+  {
+    if (i.coeff().inCoeffDomain())
+      result[0] += i.coeff()*power (x,i.exp());
+    else
+    {
+      for (ii= i.coeff(); ii.hasTerms(); ii++)
+        result[ii.exp()] += ii.coeff()*power (x,i.exp());
+    }
+  }
+  Q= q;
+  return result;
+}
+#endif
+
+void
+writeInMatrix (CFMatrix& M, const CFArray& A, const int column,
+               const int startIndex
+              )
+{
+  ASSERT (A.size () - startIndex >= 0, "wrong starting index");
+  ASSERT (A.size () - startIndex <= M.rows(), "wrong starting index");
+  ASSERT (column > 0 && column <= M.columns(), "wrong column");
+  if (A.size() - startIndex <= 0) return;
+  int j= 1;
+  for (int i= startIndex; i < A.size(); i++, j++)
+    M (j, column)= A [i];
+}
+
+CFArray getCoeffs (const CanonicalForm& F, const int k)
+{
+  ASSERT (F.isUnivariate() || F.inCoeffDomain(), "univariate input expected");
+  if (degree (F, 2) < k)
+    return CFArray();
+
+  CFArray result= CFArray (degree (F) - k + 1);
+  CFIterator j= F;
+  for (int i= degree (F); i >= k; i--)
+  {
+    if (j.exp() == i)
+    {
+      result [i - k]= j.coeff();
+      j++;
+      if (!j.hasTerms())
+        return result;
+    }
+    else
+      result[i - k]= 0;
+  }
+  return result;
+}
+
+CFArray getCoeffs (const CanonicalForm& F, const int k, const Variable& alpha)
+{
+  ASSERT (F.isUnivariate() || F.inCoeffDomain(), "univariate input expected");
+  if (degree (F, 2) < k)
+    return CFArray ();
+
+  int d= degree (getMipo (alpha));
+  CFArray result= CFArray ((degree (F) - k + 1)*d);
+  CFIterator j= F;
+  CanonicalForm buf;
+  CFIterator iter;
+  for (int i= degree (F); i >= k; i--)
+  {
+    if (j.exp() == i)
+    {
+      iter= j.coeff();
+      for (int l= degree (j.coeff(), alpha); l >= 0; l--)
+      {
+        if (iter.exp() == l)
+        {
+          result [(i - k)*d + l]= iter.coeff();
+          iter++;
+          if (!iter.hasTerms())
+            break;
+        }
+      }
+      j++;
+      if (!j.hasTerms())
+        return result;
+    }
+    else
+    {
+      for (int l= 0; l < d; l++)
+        result[(i - k)*d + l]= 0;
+    }
+  }
+  return result;
+}
+
+#ifdef HAVE_NTL
+CFArray
+getCoeffs (const CanonicalForm& G, const int k, const int l, const int degMipo,
+           const Variable& alpha, const CanonicalForm& evaluation,
+           const mat_zz_p& M)
+{
+  ASSERT (G.isUnivariate() || G.inCoeffDomain(), "univariate input expected");
+  CanonicalForm F= G (G.mvar() - evaluation, G.mvar());
+  if (F.isZero())
+    return CFArray ();
+
+  Variable y= Variable (2);
+  F= F (power (y, degMipo), y);
+  F= F (y, alpha);
+  zz_pX NTLF= convertFacCF2NTLzzpX (F);
+  NTLF.rep.SetLength (l*degMipo);
+  NTLF.rep= M*NTLF.rep;
+  NTLF.normalize();
+  F= convertNTLzzpX2CF (NTLF, y);
+
+  if (degree (F, 2) < k)
+    return CFArray();
+
+  CFArray result= CFArray (degree (F) - k + 1);
+
+  CFIterator j= F;
+  for (int i= degree (F); i >= k; i--)
+  {
+    if (j.exp() == i)
+    {
+      result [i - k]= j.coeff();
+      j++;
+      if (!j.hasTerms())
+        return result;
+    }
+    else
+      result[i - k]= 0;
+  }
+  return result;
+}
+#endif
+
+#ifdef HAVE_FLINT
+CFArray
+getCoeffs (const CanonicalForm& G, const int k, const int l, const int degMipo,
+           const Variable& alpha, const CanonicalForm& evaluation,
+           const nmod_mat_t M)
+{
+  ASSERT (G.isUnivariate() || G.inCoeffDomain(), "univariate input expected");
+  CanonicalForm F= G (G.mvar() - evaluation, G.mvar());
+  if (F.isZero())
+    return CFArray ();
+
+  Variable y= Variable (2);
+  F= F (power (y, degMipo), y);
+  F= F (y, alpha);
+
+  nmod_poly_t FLINTF;
+  nmod_mat_t MFLINTF, mulResult;
+  nmod_mat_init (MFLINTF, l*degMipo, 1, getCharacteristic());
+  nmod_mat_init (mulResult, l*degMipo, 1, getCharacteristic());
+
+  convertFacCF2nmod_poly_t (FLINTF, F);
+
+#ifndef slong
+#define slong long
+#endif
+  slong i;
+
+  for (i= 0; i < FLINTF->length; i++)
+    nmod_mat_entry (MFLINTF, i, 0)= FLINTF->coeffs[i];
+
+  for (; i < MFLINTF->r; i++)
+    nmod_mat_entry (MFLINTF, i, 0)= 0;
+
+  nmod_mat_mul (mulResult, M, MFLINTF);
+
+  F= 0;
+  for (i= 0; i < mulResult->r; i++)
+    F += CanonicalForm ((long) nmod_mat_entry (mulResult, i, 0))*power (y, i);
+
+  nmod_mat_clear (MFLINTF);
+  nmod_mat_clear (mulResult);
+
+  if (degree (F, 2) < k)
+    return CFArray();
+
+  CFArray result= CFArray (degree (F) - k + 1);
+
+  CFIterator j= F;
+  for (int i= degree (F); i >= k; i--)
+  {
+    if (j.exp() == i)
+    {
+      result [i - k]= j.coeff();
+      j++;
+      if (!j.hasTerms())
+        return result;
+    }
+    else
+      result[i - k]= 0;
+  }
+  return result;
+}
+#endif
+
+int * computeBounds (const CanonicalForm& F, int& n, bool& isIrreducible)
+{
+  n= degree (F, 1);
+  int* result= new int [n];
+  int sizeOfNewtonPolygon;
+  int** newtonPolyg= newtonPolygon (F, sizeOfNewtonPolygon);
+
+  isIrreducible= false;
+  if (sizeOfNewtonPolygon == 3)
+  {
+    bool check1=
+        (newtonPolyg[0][0]==0 || newtonPolyg[1][0]==0 || newtonPolyg[2][0]==0);
+    if (check1)
+    {
+      bool check2=
+        (newtonPolyg[0][1]==0 || newtonPolyg[1][1]==0 || newtonPolyg[2][0]==0);
+      if (check2)
+      {
+        int p=getCharacteristic();
+        int d=1;
+        char bufGFName='Z';
+        bool GF= (CFFactory::gettype()==GaloisFieldDomain);
+        if (GF)
+        {
+          d= getGFDegree();
+          bufGFName=gf_name;
+        }
+        setCharacteristic(0);
+        CanonicalForm tmp= gcd (newtonPolyg[0][0],newtonPolyg[0][1]);  // maybe it's better to use plain intgcd
+        tmp= gcd (tmp, newtonPolyg[1][0]);
+        tmp= gcd (tmp, newtonPolyg[1][1]);
+        tmp= gcd (tmp, newtonPolyg[2][0]);
+        tmp= gcd (tmp, newtonPolyg[2][1]);
+        isIrreducible= (tmp==1);
+        if (GF)
+          setCharacteristic (p, d, bufGFName);
+        else
+          setCharacteristic(p);
+      }
+    }
+  }
+
+  int minX, minY, maxX, maxY;
+  minX= newtonPolyg [0] [0];
+  minY= newtonPolyg [0] [1];
+  maxX= minX;
+  maxY= minY;
+  int indZero= 0;
+  for (int i= 1; i < sizeOfNewtonPolygon; i++)
+  {
+    if (newtonPolyg[i][1] == 0)
+    {
+      if (newtonPolyg[indZero][1] == 0)
+      {
+        if (newtonPolyg[indZero][0] < newtonPolyg[i][0])
+          indZero= i;
+      }
+      else
+        indZero= i;
+    }
+    if (minX > newtonPolyg [i] [0])
+      minX= newtonPolyg [i] [0];
+    if (maxX < newtonPolyg [i] [0])
+      maxX= newtonPolyg [i] [0];
+    if (minY > newtonPolyg [i] [1])
+      minY= newtonPolyg [i] [1];
+    if (maxY < newtonPolyg [i] [1])
+      maxY= newtonPolyg [i] [1];
+  }
+
+  int slopeNum, slopeDen, constTerm;
+  bool negativeSlope=false;
+  if (indZero != sizeOfNewtonPolygon - 1)
+  {
+    slopeNum= newtonPolyg[indZero+1][0]-newtonPolyg[indZero][0];
+    slopeDen= newtonPolyg[indZero+1][1];
+    constTerm= newtonPolyg[indZero][0];
+  }
+  else
+  {
+    slopeNum= newtonPolyg[0][0]-newtonPolyg[indZero][0];
+    slopeDen= newtonPolyg[0][1];
+    constTerm= newtonPolyg[indZero][0];
+  }
+  if (slopeNum < 0)
+  {
+    slopeNum= -slopeNum;
+    negativeSlope= true;
+  }
+  int k= 0;
+  int* point= new int [2];
+  for (int i= 0; i < n; i++)
+  {
+    if (((indZero+1) < sizeOfNewtonPolygon && (i+1) > newtonPolyg[indZero+1][1])
+        || ((indZero+1) >= sizeOfNewtonPolygon && (i+1) > newtonPolyg[0][1]))
+    {
+      if (indZero + 1 != sizeOfNewtonPolygon)
+        indZero++;
+      else
+        indZero= 0;
+      if (indZero != sizeOfNewtonPolygon - 1)
+      {
+        slopeNum= newtonPolyg[indZero+1][0]-newtonPolyg[indZero][0];
+        slopeDen= newtonPolyg[indZero+1][1]-newtonPolyg[indZero][1];
+        constTerm= newtonPolyg[indZero][0];
+      }
+      else
+      {
+        slopeNum= newtonPolyg[0][0]-newtonPolyg[indZero][0];
+        slopeDen= newtonPolyg[0][1]-newtonPolyg[indZero][1];
+        constTerm= newtonPolyg[indZero][0];
+      }
+      if (slopeNum < 0)
+      {
+        negativeSlope= true;
+        slopeNum= - slopeNum;
+        k= (int) -(((long) slopeNum*((i+1)-newtonPolyg[indZero][1])+slopeDen-1)/
+                   slopeDen) + constTerm;
+      }
+      else
+        k= (int) (((long) slopeNum*((i+1)-newtonPolyg[indZero][1])) / slopeDen)
+                  + constTerm;
+    }
+    else
+    {
+      if (negativeSlope)
+        k= (int) -(((long) slopeNum*((i+1)-newtonPolyg[indZero][1])+slopeDen-1)/
+                   slopeDen) + constTerm;
+      else
+        k= (int) ((long) slopeNum*((i+1)-newtonPolyg[indZero][1])) / slopeDen
+                  + constTerm;
+    }
+    if (i + 1 > maxY || i + 1 < minY)
+    {
+      result [i]= 0;
+      continue;
+    }
+    point [0]= k;
+    point [1]= i + 1;
+    if (!isInPolygon (newtonPolyg, sizeOfNewtonPolygon, point) && k > 0)
+      k= 0;
+    result [i]= k;
+  }
+
+  delete [] point;
+
+  for (int i= 0; i < sizeOfNewtonPolygon; i++)
+    delete [] newtonPolyg[i];
+  delete [] newtonPolyg;
+
+  return result;
+}
+
+int *
+computeBoundsWrtDiffMainvar (const CanonicalForm& F, int& n,
+                             bool& isIrreducible)
+{
+  n= degree (F, 2);
+  int* result= new int [n];
+  int sizeOfNewtonPolygon;
+  int** newtonPolyg= newtonPolygon (F, sizeOfNewtonPolygon);
+
+  isIrreducible= false;
+  if (sizeOfNewtonPolygon == 3)
+  {
+    bool check1=
+        (newtonPolyg[0][0]==0 || newtonPolyg[1][0]==0 || newtonPolyg[2][0]==0);
+    if (check1)
+    {
+      bool check2=
+        (newtonPolyg[0][1]==0 || newtonPolyg[1][1]==0 || newtonPolyg[2][0]==0);
+      if (check2)
+      {
+        int p=getCharacteristic();
+        int d=1;
+        char bufGFName='Z';
+        bool GF= (CFFactory::gettype()==GaloisFieldDomain);
+        if (GF)
+        {
+          d= getGFDegree();
+          bufGFName=gf_name;
+        }
+        setCharacteristic(0);
+        CanonicalForm tmp= gcd (newtonPolyg[0][0],newtonPolyg[0][1]);
+        tmp= gcd (tmp, newtonPolyg[1][0]);
+        tmp= gcd (tmp, newtonPolyg[1][1]);
+        tmp= gcd (tmp, newtonPolyg[2][0]);
+        tmp= gcd (tmp, newtonPolyg[2][1]);
+        isIrreducible= (tmp==1);
+        if (GF)
+          setCharacteristic (p, d, bufGFName);
+        else
+          setCharacteristic(p);
+      }
+    }
+  }
+
+  int swap;
+  for (int i= 0; i < sizeOfNewtonPolygon; i++)
+  {
+    swap= newtonPolyg[i][1];
+    newtonPolyg[i][1]=newtonPolyg[i][0];
+    newtonPolyg[i][0]= swap;
+  }
+
+  sizeOfNewtonPolygon= polygon(newtonPolyg, sizeOfNewtonPolygon);
+
+  int minX, minY, maxX, maxY;
+  minX= newtonPolyg [0] [0];
+  minY= newtonPolyg [0] [1];
+  maxX= minX;
+  maxY= minY;
+  int indZero= 0;
+  for (int i= 1; i < sizeOfNewtonPolygon; i++)
+  {
+    if (newtonPolyg[i][1] == 0)
+    {
+      if (newtonPolyg[indZero][1] == 0)
+      {
+        if (newtonPolyg[indZero][0] < newtonPolyg[i][0])
+          indZero= i;
+      }
+      else
+        indZero= i;
+    }
+    if (minX > newtonPolyg [i] [0])
+      minX= newtonPolyg [i] [0];
+    if (maxX < newtonPolyg [i] [0])
+      maxX= newtonPolyg [i] [0];
+    if (minY > newtonPolyg [i] [1])
+      minY= newtonPolyg [i] [1];
+    if (maxY < newtonPolyg [i] [1])
+      maxY= newtonPolyg [i] [1];
+  }
+
+  int slopeNum, slopeDen, constTerm;
+  bool negativeSlope=false;
+  if (indZero != sizeOfNewtonPolygon - 1)
+  {
+    slopeNum= newtonPolyg[indZero+1][0]-newtonPolyg[indZero][0];
+    slopeDen= newtonPolyg[indZero+1][1];
+    constTerm= newtonPolyg[indZero][0];
+  }
+  else
+  {
+    slopeNum= newtonPolyg[0][0]-newtonPolyg[indZero][0];
+    slopeDen= newtonPolyg[0][1];
+    constTerm= newtonPolyg[indZero][0];
+  }
+  if (slopeNum < 0)
+  {
+    slopeNum= -slopeNum;
+    negativeSlope= true;
+  }
+  int k= 0;
+
+  int* point= new int [2];
+  for (int i= 0; i < n; i++)
+  {
+    if (((indZero+1) < sizeOfNewtonPolygon && (i+1) > newtonPolyg[indZero+1][1])
+        || ((indZero+1) >= sizeOfNewtonPolygon && (i+1) > newtonPolyg[0][1]))
+    {
+      if (indZero + 1 != sizeOfNewtonPolygon)
+        indZero++;
+      else
+        indZero= 0;
+      if (indZero != sizeOfNewtonPolygon - 1)
+      {
+        slopeNum= newtonPolyg[indZero+1][0]-newtonPolyg[indZero][0];
+        slopeDen= newtonPolyg[indZero+1][1]-newtonPolyg[indZero][1];
+        constTerm= newtonPolyg[indZero][0];
+      }
+      else
+      {
+        slopeNum= newtonPolyg[0][0]-newtonPolyg[indZero][0];
+        slopeDen= newtonPolyg[0][1]-newtonPolyg[indZero][1];
+        constTerm= newtonPolyg[indZero][0];
+      }
+      if (slopeNum < 0)
+      {
+        negativeSlope= true;
+        slopeNum= - slopeNum;
+        k= (int) -(((long) slopeNum*((i+1)-newtonPolyg[indZero][1])+slopeDen-1)/
+                   slopeDen) + constTerm;
+      }
+      else
+        k= (int) (((long) slopeNum*((i+1)-newtonPolyg[indZero][1])) / slopeDen)
+                  + constTerm;
+    }
+    else
+    {
+      if (negativeSlope)
+        k= (int) -(((long) slopeNum*((i+1)-newtonPolyg[indZero][1])+slopeDen-1)/
+                   slopeDen) + constTerm;
+      else
+        k= (int) ((long) slopeNum*((i+1)-newtonPolyg[indZero][1])) / slopeDen
+                  + constTerm;
+    }
+    if (i + 1 > maxY || i + 1 < minY)
+    {
+      result [i]= 0;
+      continue;
+    }
+
+    point [0]= k;
+    point [1]= i + 1;
+    if (!isInPolygon (newtonPolyg, sizeOfNewtonPolygon, point) && k > 0)
+      k= 0;
+    result [i]= k;
+  }
+
+  delete [] point;
+
+  for (int i= 0; i < sizeOfNewtonPolygon; i++)
+    delete [] newtonPolyg[i];
+  delete [] newtonPolyg;
+
+  return result;
+}
+
+int
+substituteCheck (const CanonicalForm& F, const Variable& x)
+{
+  if (F.inCoeffDomain())
+    return 0;
+  if (degree (F, x) < 0)
+    return 0;
+  CanonicalForm f= swapvar (F, F.mvar(), x);
+  int sizef= 0;
+  for (CFIterator i= f; i.hasTerms(); i++, sizef++)
+  {
+    if (i.exp() == 1)
+      return 0;
+  }
+  int * expf= new int [sizef];
+  int j= 0;
+  for (CFIterator i= f; i.hasTerms(); i++, j++)
+    expf [j]= i.exp();
+
+  int indf= sizef - 1;
+  if (expf[indf] == 0)
+    indf--;
+
+  int result= expf[indf];
+  for (int i= indf - 1; i >= 0; i--)
+  {
+    if (expf [i]%result != 0)
+    {
+      delete [] expf;
+      return 0;
+    }
+  }
+
+  delete [] expf;
+  return result;
+}
+
+static int
+substituteCheck (const CanonicalForm& F, const CanonicalForm& G)
+{
+  if (F.inCoeffDomain() || G.inCoeffDomain())
+    return 0;
+  Variable x= Variable (1);
+  if (degree (F, x) <= 1 || degree (G, x) <= 1)
+    return 0;
+  CanonicalForm f= swapvar (F, F.mvar(), x);
+  CanonicalForm g= swapvar (G, G.mvar(), x);
+  int sizef= 0;
+  int sizeg= 0;
+  for (CFIterator i= f; i.hasTerms(); i++, sizef++)
+  {
+    if (i.exp() == 1)
+      return 0;
+  }
+  for (CFIterator i= g; i.hasTerms(); i++, sizeg++)
+  {
+    if (i.exp() == 1)
+      return 0;
+  }
+  int * expf= new int [sizef];
+  int * expg= new int [sizeg];
+  int j= 0;
+  for (CFIterator i= f; i.hasTerms(); i++, j++)
+  {
+    expf [j]= i.exp();
+  }
+  j= 0;
+  for (CFIterator i= g; i.hasTerms(); i++, j++)
+  {
+    expg [j]= i.exp();
+  }
+
+  int indf= sizef - 1;
+  int indg= sizeg - 1;
+  if (expf[indf] == 0)
+    indf--;
+  if (expg[indg] == 0)
+    indg--;
+
+  if ((expg[indg]%expf [indf] != 0 && expf[indf]%expg[indg] != 0) ||
+      (expg[indg] == 1 && expf[indf] == 1))
+  {
+    delete [] expg;
+    delete [] expf;
+    return 0;
+  }
+
+  int result;
+  if (expg [indg]%expf [indf] == 0)
+    result= expf[indf];
+  else
+    result= expg[indg];
+  for (int i= indf - 1; i >= 0; i--)
+  {
+    if (expf [i]%result != 0)
+    {
+      delete [] expf;
+      delete [] expg;
+      return 0;
+    }
+  }
+
+  for (int i= indg - 1; i >= 0; i--)
+  {
+    if (expg [i]%result != 0)
+    {
+      delete [] expf;
+      delete [] expg;
+      return 0;
+    }
+  }
+
+  delete [] expg;
+  delete [] expf;
+  return result;
+}
+
+int recSubstituteCheck (const CanonicalForm& F, const int d)
+{
+  if (F.inCoeffDomain())
+    return 0;
+  Variable x= Variable (1);
+  if (degree (F, x) <= 1)
+    return 0;
+  CanonicalForm f= swapvar (F, F.mvar(), x);
+  int sizef= 0;
+  for (CFIterator i= f; i.hasTerms(); i++, sizef++)
+  {
+    if (i.exp() == 1)
+      return 0;
+  }
+  int * expf= new int [sizef];
+  int j= 0;
+  for (CFIterator i= f; i.hasTerms(); i++, j++)
+  {
+    expf [j]= i.exp();
+  }
+
+  int indf= sizef - 1;
+  if (expf[indf] == 0)
+    indf--;
+
+  if ((d%expf [indf] != 0 && expf[indf]%d != 0) || (expf[indf] == 1))
+  {
+    delete [] expf;
+    return 0;
+  }
+
+  int result;
+  if (d%expf [indf] == 0)
+    result= expf[indf];
+  else
+    result= d;
+  for (int i= indf - 1; i >= 0; i--)
+  {
+    if (expf [i]%result != 0)
+    {
+      delete [] expf;
+      return 0;
+    }
+  }
+
+  delete [] expf;
+  return result;
+}
+
+int substituteCheck (const CFList& L)
+{
+  ASSERT (L.length() > 1, "expected a list of at least two elements");
+  if (L.length() < 2)
+    return 0;
+  CFListIterator i= L;
+  i++;
+  int result= substituteCheck (L.getFirst(), i.getItem());
+  if (result <= 1)
+    return result;
+  i++;
+  for (;i.hasItem(); i++)
+  {
+    result= recSubstituteCheck (i.getItem(), result);
+    if (result <= 1)
+      return result;
+  }
+  return result;
+}
+
+void
+subst (const CanonicalForm& F, CanonicalForm& A, const int d, const Variable& x)
+{
+  if (d <= 1)
+  {
+    A= F;
+    return;
+  }
+  if (degree (F, x) <= 0)
+  {
+    A= F;
+    return;
+  }
+  CanonicalForm C= 0;
+  CanonicalForm f= swapvar (F, x, F.mvar());
+  for (CFIterator i= f; i.hasTerms(); i++)
+    C += i.coeff()*power (f.mvar(), i.exp()/ d);
+  A= swapvar (C, x, F.mvar());
+}
+
+CanonicalForm
+reverseSubst (const CanonicalForm& F, const int d, const Variable& x)
+{
+  if (d <= 1)
+    return F;
+  if (degree (F, x) <= 0)
+    return F;
+  CanonicalForm f= swapvar (F, x, F.mvar());
+  CanonicalForm result= 0;
+  for (CFIterator i= f; i.hasTerms(); i++)
+    result += i.coeff()*power (f.mvar(), d*i.exp());
+  return swapvar (result, x, F.mvar());
+}
+
+void
+reverseSubst (CFList& L, const int d, const Variable& x)
+{
+  for (CFListIterator i= L; i.hasItem(); i++)
+    i.getItem()= reverseSubst (i.getItem(), d, x);
+}
+
diff --git a/factory/facFqBivarUtil.h b/factory/facFqBivarUtil.h
new file mode 100644
index 0000000..04eacb2
--- /dev/null
+++ b/factory/facFqBivarUtil.h
@@ -0,0 +1,345 @@
+/*****************************************************************************\
+ * Computer Algebra System SINGULAR
+\*****************************************************************************/
+/** @file facFqBivarUtil.h
+ *
+ * This file provides utility functions for bivariate factorization
+ *
+ * @author Martin Lee
+ *
+ **/
+/*****************************************************************************/
+
+#ifndef FAC_FQ_BIVAR_UTIL_H
+#define FAC_FQ_BIVAR_UTIL_H
+
+// #include "config.h"
+
+#include "cf_map.h"
+#include "ExtensionInfo.h"
+
+#ifdef HAVE_NTL
+#include "NTLconvert.h"
+#endif
+
+#ifdef HAVE_FLINT
+#include "FLINTconvert.h"
+#endif
+
+/// append @a factors2 on @a factors1
+void append (CFList& factors1,       ///< [in,out] a list of polys
+             const CFList& factors2  ///< [in] a list of polys
+            );
+
+/// decompress a list of polys @a factors using the map @a N
+void decompress (CFList& factors, ///< [in,out] a list of polys
+                 const CFMap& N   ///< [in] a map
+                );
+
+/// as above
+void decompress (CFFList& factors, ///< [in,out] a list of factors
+                 const CFMap& N    ///< [in] a map
+                );
+
+/// as above
+void decompress (CFAFList& factors, ///< [in,out] a list of factors
+                 const CFMap& N    ///< [in] a map
+                );
+
+/// first swap Variables in @a factors1 if necessary, then append @a factors2
+/// and @a factors3 on @a factors1 and finally decompress @a factors1
+void appendSwapDecompress (CFList& factors1,       ///< [in,out] a list of polys
+                           const CFList& factors2, ///< [in] a list of polys
+                           const CFList& factors3, ///< [in] a list of polys
+                           const bool swap1,       ///< [in] indicates the need
+                                                   ///< to swap
+                           const bool swap2,       ///< [in] indicates the need
+                                                   ///< to swap
+                           const CFMap& N          ///< [in] a map
+                          );
+
+/// swap Variables in @a factors, then decompress @a factors
+void swapDecompress (CFList& factors, ///< [in,out] a list of polys
+                     const bool swap, ///< [in] indicates the need to swap
+                     const CFMap& N   ///< [in] a map
+                    );
+
+/// tests if F is not contained in a subfield defined by @a gamma (Fq case) or
+/// @a k (GF case)
+///
+/// @return @a isInExtension returns true if @a F is not contained in a subfield
+///         defined by @a gamma (Fq case) or @a k (GF case), false else
+/// @sa appendTestMapDown()
+bool isInExtension (const CanonicalForm& F,      ///< [in] a poly over
+                                                 ///< F_p (alpha)=Fq or GF(p^l)
+                    const CanonicalForm& gamma,  ///< [in] a primitive element
+                                                 ///< defining a subfield of
+                                                 ///< Fq if we are not over some
+                                                 ///< GF
+                    const int k,                 ///< some int k such that k
+                                                 ///< divides l if we are not
+                                                 ///< over some Fq
+                    const CanonicalForm& delta,  ///< [in] image of gamma
+                    CFList& source,              ///< [in,out] list of preimages
+                    CFList& dest                 ///< [in,out] list of images
+                   );
+
+/// map a poly into a subfield of the current field, no testing is performed!
+///
+/// @return @a mapDown returns @a F mapped into a subfield of the current field
+/// @sa appendTestMapDown(), appendMapDown()
+CanonicalForm
+mapDown (const CanonicalForm& F,    ///< [in] a poly
+         const ExtensionInfo& info, ///< [in] information about the sub- and
+                                    ///< current field
+         CFList& source,            ///< [in,out] in case we are over some
+                                    ///< F_p (alpha) and want to map down into
+                                    ///< F_p (beta) source contains powers of
+                                    ///< the primitive element of F_p (alpha)
+         CFList& dest               ///< [in,out] as source but contains
+                                    ///< the corresponding powers of the
+                                    ///< primitive element of F_p (beta)
+        );
+
+/// test if @a g is in a subfield of the current field, if so map it down and
+/// append it to @a factors
+///
+/// @sa mapDown(), isInExtension()
+void appendTestMapDown (CFList& factors,          ///< [in,out] a list of polys
+                        const CanonicalForm& f,   ///< [in] a poly
+                        const ExtensionInfo& info,///< [in] information about
+                                                  ///< extension
+                        CFList& source,           ///< [in,out] @sa mapDown()
+                        CFList& dest              ///< [in,out] @sa mapDown()
+                       );
+
+/// map @a g down into a subfield of the current field and append it to @a
+/// factors
+///
+/// @sa mapDown(), appendTestMapDown()
+void
+appendMapDown (CFList& factors,          ///< [in,out] a list of polys
+               const CanonicalForm& g,   ///< [in] a poly
+               const ExtensionInfo& info,///< [in] information about extension
+               CFList& source,           ///< [in,out] @sa mapDown()
+               CFList& dest              ///< [in,out] @sa mapDown()
+              );
+
+/// normalize factors, i.e. make factors monic
+void normalize (CFList& factors ///< [in,out] a list of polys
+               );
+
+/// as above
+void normalize (CFFList& factors ///< [in,out] a list of factors
+               );
+
+/// extract a subset given by @a index of size @a s from @a elements, if there
+/// is no subset we have not yet considered noSubset is set to true. @a index
+/// encodes the next subset, e.g. if s= 3, elements= {a,b,c,d},
+/// index= {1, 2, 4, 0}, then subset= {a,c,d}. @a index is of size
+/// @a elements.size().
+///
+/// @return @a subset returns a list of polys of length @a s if there is a
+///         subset we have not yet considered.
+CFList subset (int index [],            ///< [in,out] an array encoding the next
+                                        ///< subset
+               const int& s,            ///< [in] size of the subset
+               const CFArray& elements, ///< [in] an array of polys
+               bool& noSubset           ///< [in,out] if there is no subset we
+                                        ///< have not yet considered @a noSubset
+                                        ///< is true
+              );
+
+/// write elements of @a list into an array
+///
+/// @return an array of polys
+CFArray copy (const CFList& list ///< [in] a list of polys
+             );
+
+/// update @a index
+void indexUpdate (int index [],          ///< [in,out] an array encoding a
+                                         ///< subset of size subsetSize
+                  const int& subsetSize, ///< [in] size of the subset
+                  const int& setSize,    ///< [in] size of the given set
+                  bool& noSubset         ///< [in,out] if there is no subset we
+                                         ///< have not yet considered @a
+                                         ///< noSubset is true
+                 );
+
+/// compute the sum of degrees in Variable(1) of elements in S
+///
+/// @return @a subsetDegree returns the sum of degrees in Variable(1) of
+///         elements in S
+int subsetDegree (const CFList& S ///< [in] a list of polys
+                 );
+
+/// determine multiplicity of the factors
+///
+/// @return a list of factors of F with their multiplicity
+CFFList multiplicity (CanonicalForm& F,     ///< [in] a poly
+                      const CFList& factors ///< [in] a list of factors of F
+                     );
+
+/// compute the coefficients of the logarithmic derivative of G mod
+/// Variable (2)^l over Fq
+///
+/// @return an array of coefficients of the logarithmic derivative of G mod
+///         Variable (2)^l
+CFArray logarithmicDerivative (const CanonicalForm& F,///<[in] a bivariate poly
+                              const CanonicalForm& G, ///<[in] a factor of F
+                              int l,                  ///<[in] lifting precision
+                              CanonicalForm& Q        ///<[in,out] F/G
+                              );
+
+/// compute the coefficients of the logarithmic derivative of G mod
+/// Variable (2)^l over Fq with oldQ= F/G mod Variable (2)^oldL
+///
+/// @return an array of coefficients of the logarithmic derivative of G mod
+///         Variable (2)^l
+CFArray
+logarithmicDerivative (const CanonicalForm& F,   ///< [in] bivariate poly
+                                                 ///< truncated at Variable(2)^l
+                       const CanonicalForm& G,   ///< [in] a factor of F
+                       int l,                    ///< [in] lifting precision
+                       int oldL,                 ///< [in] old precision
+                       const CanonicalForm& oldQ,///< [in] F/G mod
+                                                 ///< Variable(2)^oldL
+                       CanonicalForm& Q          ///< [in, out] F/G
+                      );
+
+/// compute bounds for logarithmic derivative as described in K. Belabas,
+/// M. van Hoeij, J. Klüners, and A. Steel, Factoring polynomials over global
+/// fields
+///
+/// @return @a computeBounds returns bounds as described above
+int *
+computeBounds (const CanonicalForm& F,///< [in] compressed bivariate polynomial
+               int& n,                ///< [in,out] length of output
+               bool& isIrreducible    ///< [in,out] check if poly is irreducible
+              );
+
+/// as above just wrt to the other variable
+///
+/// @return @a computeBounds returns bounds as described above
+int *
+computeBoundsWrtDiffMainvar
+              (const CanonicalForm& F,///< [in] compressed bivariate polynomial
+               int& n,                ///< [in,out] length of output
+               bool& isIrreducible    ///< [in,out] check if poly is irreducible
+              );
+
+/// extract coefficients of \f$ x^i \f$ for \f$i\geq k\f$ where \f$ x \f$ is
+/// a variable of level 1
+///
+/// @return coefficients of \f$ x^i \f$ for \f$i\geq k\f$
+/// @sa {getCoeffs (const CanonicalForm&, const int, const Variable&),
+/// getCoeffs (const CanonicalForm&, const int, const int, const int,
+/// const Variable&, const CanonicalForm&, const mat_zz_p&)}
+CFArray
+getCoeffs (const CanonicalForm& F,///< [in] compressed bivariate poly over F_p
+           const int k            ///< [in] some int
+          );
+
+/// extract coefficients of \f$ x^i \f$ for \f$i\geq k\f$ where \f$ x \f$ is
+/// a variable of level 1
+///
+/// @return coefficients of \f$ x^i \f$ for \f$i\geq k\f$
+/// @sa {getCoeffs (const CanonicalForm&, const int),
+/// getCoeffs (const CanonicalForm&, const int, const int, const int,
+/// const Variable&, const CanonicalForm&, const mat_zz_p&)}
+CFArray
+getCoeffs (const CanonicalForm& F,///< [in] compressed bivariate poly over
+                                  ///< F_p(alpha)
+           const int k,           ///< [in] some int
+           const Variable& alpha  ///< [in] algebraic variable
+          );
+
+#ifdef HAVE_NTL
+/// extract coefficients of \f$ x^i \f$ for \f$i\geq k\f$ where \f$ x \f$ is
+/// a variable of level 1
+///
+/// @return coefficients of \f$ x^i \f$ for \f$i\geq k\f$
+/// @sa {getCoeffs (const CanonicalForm&, const int, const Variable& alpha),
+/// getCoeffs (const CanonicalForm&, const int)}
+CFArray
+getCoeffs (const CanonicalForm& F,         ///< [in] compressed bivariate poly
+           const int k,                    ///< [in] some int
+           const int l,                    ///< [in] precision
+           const int degMipo,              ///< [in] degree of minimal poly
+           const Variable& alpha,          ///< [in] algebraic variable
+           const CanonicalForm& evaluation,///< [in] evaluation point
+           const mat_zz_p& M               ///< [in] bases change matrix
+          );
+#endif
+
+#ifdef HAVE_FLINT
+/// extract coefficients of \f$ x^i \f$ for \f$i\geq k\f$ where \f$ x \f$ is
+/// a variable of level 1
+///
+/// @return coefficients of \f$ x^i \f$ for \f$i\geq k\f$
+/// @sa {getCoeffs (const CanonicalForm&, const int, const Variable& alpha),
+/// getCoeffs (const CanonicalForm&, const int)}
+CFArray
+getCoeffs (const CanonicalForm& F,         ///< [in] compressed bivariate poly
+           const int k,                    ///< [in] some int
+           const int l,                    ///< [in] precision
+           const int degMipo,              ///< [in] degree of minimal poly
+           const Variable& alpha,          ///< [in] algebraic variable
+           const CanonicalForm& evaluation,///< [in] evaluation point
+           const nmod_mat_t M              ///< [in] bases change matrix
+          );
+#endif
+
+/// write A into M starting at row startIndex
+void
+writeInMatrix (CFMatrix& M,        ///< [in,out] some matrix
+               const CFArray& A,   ///< [in] array of polys
+               const int column,   ///< [in] column in which A is written
+               const int startIndex///< [in] row in which to start
+              );
+
+/// checks if a substitution x^n->x is possible
+///
+/// @return an integer n > 1, if a substitution described as above is possible
+///         else n <= 1
+int substituteCheck (const CFList& L ///< [in] a list of univariate polys
+                    );
+
+/// substitute x^d by x in F
+void
+subst (const CanonicalForm& F, ///< [in] a polynomial
+       CanonicalForm& A,       ///< [in,out] returns F with x^d replaced by x
+       const int d,            ///< d > 1 such that a substitution x^d -> x
+                               ///< [in] is possible
+       const Variable& x       ///< [in] a Variable
+      );
+
+/// reverse a substitution x^d->x
+///
+/// @return a poly with x replaced by x^d
+CanonicalForm
+reverseSubst (const CanonicalForm& F, ///< [in] a poly
+              const int d,            ///< [in] an integer > 0
+              const Variable& x       ///< [in] a Variable
+             );
+
+/// reverse a substitution x^d->x
+void
+reverseSubst (CFList& L,        ///< [in,out] a list of polys, returns the
+                                ///< given list with x replaced by x^d
+              const int d,      ///< [in] an integer > 0
+              const Variable& x ///< [in] a Variable
+             );
+
+/// check if a substitution x^n->x is possible
+///
+/// @return an integer n > 1, if a substitution described as above is possible
+///         else n <= 1
+int
+substituteCheck (const CanonicalForm& F, ///<[in] a polynomial
+                 const Variable& x       ///<[in] some variable
+                );
+
+#endif
+/* FAC_FQ_BIVAR_UTIL_H */
+
diff --git a/factory/facFqFactorize.cc b/factory/facFqFactorize.cc
new file mode 100644
index 0000000..eb6f10d
--- /dev/null
+++ b/factory/facFqFactorize.cc
@@ -0,0 +1,3832 @@
+/*****************************************************************************\
+ * Computer Algebra System SINGULAR
+\*****************************************************************************/
+/** @file facFqFactorize.cc
+ *
+ * This file implements functions for factoring a multivariate polynomial over
+ * a finite field.
+ *
+ * ABSTRACT: "Efficient Multivariate Factorization over Finite Fields" by
+ * L. Bernardin & M. Monagon. Precomputation of leading coefficients is
+ * described in "Sparse Hensel lifting" by E. Kaltofen
+ *
+ * @author Martin Lee
+ *
+ **/
+/*****************************************************************************/
+
+
+#include "config.h"
+
+
+#include "cf_assert.h"
+#include "debug.h"
+#include "timing.h"
+
+#include "facFqFactorizeUtil.h"
+#include "facFqFactorize.h"
+#include "cf_random.h"
+#include "facHensel.h"
+#include "cf_irred.h"
+#include "cf_map_ext.h"
+#include "facSparseHensel.h"
+#include "facMul.h"
+#include "cfUnivarGcd.h"
+
+#ifdef HAVE_NTL
+#include "NTLconvert.h"
+
+TIMING_DEFINE_PRINT(fac_fq_bi_factorizer)
+TIMING_DEFINE_PRINT(fac_fq_hensel_lift)
+TIMING_DEFINE_PRINT(fac_fq_factor_recombination)
+TIMING_DEFINE_PRINT(fac_fq_shift_to_zero)
+TIMING_DEFINE_PRINT(fac_fq_precompute_leadcoeff)
+TIMING_DEFINE_PRINT(fac_fq_evaluation)
+TIMING_DEFINE_PRINT(fac_fq_recover_factors)
+TIMING_DEFINE_PRINT(fac_fq_preprocess_and_content)
+TIMING_DEFINE_PRINT(fac_fq_bifactor_total)
+TIMING_DEFINE_PRINT(fac_fq_luckswang)
+TIMING_DEFINE_PRINT(fac_fq_lcheuristic)
+TIMING_DEFINE_PRINT(fac_fq_content)
+TIMING_DEFINE_PRINT(fac_fq_check_mainvar)
+TIMING_DEFINE_PRINT(fac_fq_compress)
+
+
+static inline
+CanonicalForm
+listGCD (const CFList& L);
+
+static inline
+CanonicalForm
+myContent (const CanonicalForm& F)
+{
+  Variable x= Variable (1);
+  CanonicalForm G= swapvar (F, F.mvar(), x);
+  CFList L;
+  for (CFIterator i= G; i.hasTerms(); i++)
+    L.append (i.coeff());
+  if (L.length() == 2)
+    return swapvar (gcd (L.getFirst(), L.getLast()), F.mvar(), x);
+  if (L.length() == 1)
+    return LC (F, x);
+  return swapvar (listGCD (L), F.mvar(), x);
+}
+
+static inline
+CanonicalForm
+listGCD (const CFList& L)
+{
+  if (L.length() == 0)
+    return 0;
+  if (L.length() == 1)
+    return L.getFirst();
+  if (L.length() == 2)
+    return gcd (L.getFirst(), L.getLast());
+  else
+  {
+    CFList lHi, lLo;
+    CanonicalForm resultHi, resultLo;
+    int length= L.length()/2;
+    int j= 0;
+    for (CFListIterator i= L; j < length; i++, j++)
+      lHi.append (i.getItem());
+    lLo= Difference (L, lHi);
+    resultHi= listGCD (lHi);
+    resultLo= listGCD (lLo);
+    if (resultHi.isOne() || resultLo.isOne())
+      return 1;
+    return gcd (resultHi, resultLo);
+  }
+}
+
+static inline
+CanonicalForm
+myContent (const CanonicalForm& F, const Variable& x)
+{
+  if (degree (F, x) <= 0)
+    return 1;
+  CanonicalForm G= F;
+  bool swap= false;
+  if (x != F.mvar())
+  {
+    swap= true;
+    G= swapvar (F, x, F.mvar());
+  }
+  CFList L;
+  Variable alpha;
+  for (CFIterator i= G; i.hasTerms(); i++)
+    L.append (i.coeff());
+  if (L.length() == 2)
+  {
+    if (swap)
+      return swapvar (gcd (L.getFirst(), L.getLast()), F.mvar(), x);
+    else
+      return gcd (L.getFirst(), L.getLast());
+  }
+  if (L.length() == 1)
+  {
+    return LC (F, x);
+  }
+  if (swap)
+    return swapvar (listGCD (L), F.mvar(), x);
+  else
+    return listGCD (L);
+}
+
+CanonicalForm myCompress (const CanonicalForm& F, CFMap& N)
+{
+  int n= F.level();
+  int * degsf= new int [n + 1];
+  int ** swap= new int* [n + 1];
+  for (int i= 0; i <= n; i++)
+  {
+    degsf[i]= 0;
+    swap [i]= new int [3];
+    swap [i] [0]= 0;
+    swap [i] [1]= 0;
+    swap [i] [2]= 0;
+  }
+  int i= 1;
+  n= 1;
+  degsf= degrees (F, degsf);
+
+  CanonicalForm result= F;
+  while ( i <= F.level() )
+  {
+    while( degsf[i] == 0 ) i++;
+    swap[n][0]= i;
+    swap[n][1]= size (LC (F,i));
+    swap[n][2]= degsf [i];
+    if (i != n)
+      result= swapvar (result, Variable (n), Variable(i));
+    n++; i++;
+  }
+
+  int buf1, buf2, buf3;
+  n--;
+
+  for (i= 1; i < n; i++)
+  {
+    for (int j= 1; j < n - i + 1; j++)
+    {
+      if (swap[j][1] > swap[j + 1][1])
+      {
+        buf1= swap [j + 1] [0];
+        buf2= swap [j + 1] [1];
+        buf3= swap [j + 1] [2];
+        swap[j + 1] [0]= swap[j] [0];
+        swap[j + 1] [1]= swap[j] [1];
+        swap[j + 1] [2]= swap[j] [2];
+        swap[j][0]= buf1;
+        swap[j][1]= buf2;
+        swap[j][2]= buf3;
+        result= swapvar (result, Variable (j + 1), Variable (j));
+      }
+      else if (swap[j][1] == swap[j + 1][1] && swap[j][2] < swap[j + 1][2])
+      {
+        buf1= swap [j + 1] [0];
+        buf2= swap [j + 1] [1];
+        buf3= swap [j + 1] [2];
+        swap[j + 1] [0]= swap[j] [0];
+        swap[j + 1] [1]= swap[j] [1];
+        swap[j + 1] [2]= swap[j] [2];
+        swap[j][0]= buf1;
+        swap[j][1]= buf2;
+        swap[j][2]= buf3;
+        result= swapvar (result, Variable (j + 1), Variable (j));
+      }
+    }
+  }
+
+  for (i= n; i > 0; i--)
+  {
+    if (i != swap[i] [0])
+      N.newpair (Variable (i), Variable (swap[i] [0]));
+  }
+
+  for (i= 0; i <= F.level(); i++)
+    delete [] swap[i];
+  delete [] swap;
+
+  delete [] degsf;
+
+  return result;
+}
+
+CFList
+extFactorRecombination (const CFList& factors, const CanonicalForm& F,
+                        const CFList& M, const ExtensionInfo& info,
+                        const CFList& evaluation)
+{
+  Variable alpha= info.getAlpha();
+  Variable beta= info.getBeta();
+  CanonicalForm gamma= info.getGamma();
+  CanonicalForm delta= info.getDelta();
+  int k= info.getGFDegree();
+  CFList source, dest;
+  if (factors.length() == 1)
+  {
+    CanonicalForm buf= reverseShift (F, evaluation);
+    return CFList (mapDown (buf, info, source, dest));
+  }
+  if (factors.length() < 1)
+    return CFList();
+
+  int degMipoBeta= 1;
+  if (!k && beta.level() != 1)
+    degMipoBeta= degree (getMipo (beta));
+
+  CFList T, S;
+  T= factors;
+
+  int s= 1;
+  CFList result;
+  CanonicalForm buf;
+
+  buf= F;
+
+  Variable x= Variable (1);
+  CanonicalForm g, LCBuf= LC (buf, x);
+  CanonicalForm buf2, quot;
+  int * v= new int [T.length()];
+  for (int i= 0; i < T.length(); i++)
+    v[i]= 0;
+  bool noSubset= false;
+  CFArray TT;
+  TT= copy (factors);
+  bool recombination= false;
+  bool trueFactor= false;
+  while (T.length() >= 2*s)
+  {
+    while (noSubset == false)
+    {
+      if (T.length() == s)
+      {
+        delete [] v;
+        if (recombination)
+        {
+          T.insert (LCBuf);
+          g= prodMod (T, M);
+          T.removeFirst();
+          result.append (g/myContent (g));
+          g= reverseShift (g, evaluation);
+          g /= Lc (g);
+          appendTestMapDown (result, g, info, source, dest);
+          return result;
+        }
+        else
+        {
+          buf= reverseShift (buf, evaluation);
+          return CFList (buf);
+        }
+      }
+
+      S= subset (v, s, TT, noSubset);
+      if (noSubset) break;
+
+      S.insert (LCBuf);
+      g= prodMod (S, M);
+      S.removeFirst();
+      g /= myContent (g);
+      if (fdivides (g, buf, quot))
+      {
+        buf2= reverseShift (g, evaluation);
+        buf2 /= Lc (buf2);
+        if (!k && beta == x)
+        {
+          if (degree (buf2, alpha) < degMipoBeta)
+          {
+            appendTestMapDown (result, buf2, info, source, dest);
+            buf= quot;
+            LCBuf= LC (buf, x);
+            recombination= true;
+            trueFactor= true;
+          }
+        }
+        else
+        {
+          if (!isInExtension (buf2, gamma, k, delta, source, dest))
+          {
+            appendTestMapDown (result, buf2, info, source, dest);
+            buf /= g;
+            LCBuf= LC (buf, x);
+            recombination= true;
+            trueFactor= true;
+          }
+        }
+
+        if (trueFactor)
+        {
+          T= Difference (T, S);
+
+          if (T.length() < 2*s || T.length() == s)
+          {
+            buf= reverseShift (buf, evaluation);
+            buf /= Lc (buf);
+            appendTestMapDown (result, buf, info, source, dest);
+            delete [] v;
+            return result;
+          }
+          trueFactor= false;
+          TT= copy (T);
+          indexUpdate (v, s, T.length(), noSubset);
+          if (noSubset) break;
+        }
+      }
+    }
+    s++;
+    if (T.length() < 2*s || T.length() == s)
+    {
+      buf= reverseShift (buf, evaluation);
+      appendTestMapDown (result, buf, info, source, dest);
+      delete [] v;
+      return result;
+    }
+    for (int i= 0; i < T.length(); i++)
+      v[i]= 0;
+    noSubset= false;
+  }
+  if (T.length() < 2*s)
+  {
+    buf= reverseShift (F, evaluation);
+    appendMapDown (result, buf, info, source, dest);
+  }
+
+  delete [] v;
+  return result;
+}
+
+CFList
+factorRecombination (const CanonicalForm& F, const CFList& factors,
+                     const CFList& M)
+{
+  if (factors.length() == 1)
+    return CFList(F);
+  if (factors.length() < 1)
+    return CFList();
+
+  CFList T, S;
+
+  T= factors;
+
+  int s= 1;
+  CFList result;
+  CanonicalForm LCBuf= LC (F, Variable (1));
+  CanonicalForm g, buf= F;
+  int * v= new int [T.length()];
+  for (int i= 0; i < T.length(); i++)
+    v[i]= 0;
+  bool noSubset= false;
+  CFArray TT;
+  TT= copy (factors);
+  Variable y= F.level() - 1;
+  bool recombination= false;
+  CanonicalForm h, quot;
+  while (T.length() >= 2*s)
+  {
+    while (noSubset == false)
+    {
+      if (T.length() == s)
+      {
+        delete [] v;
+        if (recombination)
+        {
+          T.insert (LC (buf));
+          g= prodMod (T, M);
+          result.append (g/myContent (g));
+          return result;
+        }
+        else
+          return CFList (F);
+      }
+      S= subset (v, s, TT, noSubset);
+      if (noSubset) break;
+      S.insert (LCBuf);
+      g= prodMod (S, M);
+      S.removeFirst();
+      g /= myContent (g);
+      if (fdivides (g, buf, quot))
+      {
+        recombination= true;
+        result.append (g);
+        buf= quot;
+        LCBuf= LC (buf, Variable(1));
+        T= Difference (T, S);
+        if (T.length() < 2*s || T.length() == s)
+        {
+          result.append (buf);
+          delete [] v;
+          return result;
+        }
+        TT= copy (T);
+        indexUpdate (v, s, T.length(), noSubset);
+        if (noSubset) break;
+      }
+    }
+    s++;
+    if (T.length() < 2*s || T.length() == s)
+    {
+      result.append (buf);
+      delete [] v;
+      return result;
+    }
+    for (int i= 0; i < T.length(); i++)
+      v[i]= 0;
+    noSubset= false;
+  }
+  if (T.length() < 2*s)
+    result.append (F);
+
+  delete [] v;
+  return result;
+}
+
+int
+liftBoundAdaption (const CanonicalForm& F, const CFList& factors, bool&
+                   success, const int deg, const CFList& MOD, const int bound)
+{
+  int adaptedLiftBound= 0;
+  CanonicalForm buf= F;
+  Variable y= F.mvar();
+  Variable x= Variable (1);
+  CanonicalForm LCBuf= LC (buf, x);
+  CanonicalForm g, quot;
+  CFList M= MOD;
+  M.append (power (y, deg));
+  int d= bound;
+  int e= 0;
+  int nBuf;
+  for (CFListIterator i= factors; i.hasItem(); i++)
+  {
+    g= mulMod (i.getItem(), LCBuf, M);
+    g /= myContent (g);
+    if (fdivides (g, buf, quot))
+    {
+      nBuf= degree (g, y) + degree (LC (g, 1), y);
+      d -= nBuf;
+      e= tmax (e, nBuf);
+      buf= quot;
+      LCBuf= LC (buf, x);
+    }
+  }
+  adaptedLiftBound= d;
+
+  if (adaptedLiftBound < deg)
+  {
+    if (adaptedLiftBound < degree (F) + 1)
+    {
+      if (d == 1)
+      {
+        if (e + 1 > deg)
+        {
+          adaptedLiftBound= deg;
+          success= false;
+        }
+        else
+        {
+          success= true;
+          if (e + 1 < degree (F) + 1)
+            adaptedLiftBound= deg;
+          else
+            adaptedLiftBound= e + 1;
+        }
+      }
+      else
+      {
+        success= true;
+        adaptedLiftBound= deg;
+      }
+    }
+    else
+    {
+      success= true;
+    }
+  }
+  return adaptedLiftBound;
+}
+
+int
+extLiftBoundAdaption (const CanonicalForm& F, const CFList& factors, bool&
+                      success, const ExtensionInfo& info, const CFList& eval,
+                      const int deg, const CFList& MOD, const int bound)
+{
+  Variable alpha= info.getAlpha();
+  Variable beta= info.getBeta();
+  CanonicalForm gamma= info.getGamma();
+  CanonicalForm delta= info.getDelta();
+  int k= info.getGFDegree();
+  int adaptedLiftBound= 0;
+  CanonicalForm buf= F;
+  Variable y= F.mvar();
+  Variable x= Variable (1);
+  CanonicalForm LCBuf= LC (buf, x);
+  CanonicalForm g, gg, quot;
+  CFList M= MOD;
+  M.append (power (y, deg));
+  adaptedLiftBound= 0;
+  int d= bound;
+  int e= 0;
+  int nBuf;
+  int degMipoBeta= 1;
+  if (!k && beta.level() != 1)
+    degMipoBeta= degree (getMipo (beta));
+
+  CFList source, dest;
+  for (CFListIterator i= factors; i.hasItem(); i++)
+  {
+    g= mulMod (i.getItem(), LCBuf, M);
+    g /= myContent (g);
+    if (fdivides (g, buf, quot))
+    {
+      gg= reverseShift (g, eval);
+      gg /= Lc (gg);
+      if (!k && beta == x)
+      {
+        if (degree (gg, alpha) < degMipoBeta)
+        {
+          buf= quot;
+          nBuf= degree (g, y) + degree (LC (g, x), y);
+          d -= nBuf;
+          e= tmax (e, nBuf);
+          LCBuf= LC (buf, x);
+        }
+      }
+      else
+      {
+        if (!isInExtension (gg, gamma, k, delta, source, dest))
+        {
+          buf= quot;
+          nBuf= degree (g, y) + degree (LC (g, x), y);
+          d -= nBuf;
+          e= tmax (e, nBuf);
+          LCBuf= LC (buf, x);
+        }
+      }
+    }
+  }
+  adaptedLiftBound= d;
+
+  if (adaptedLiftBound < deg)
+  {
+    if (adaptedLiftBound < degree (F) + 1)
+    {
+      if (d == 1)
+      {
+        if (e + 1 > deg)
+        {
+          adaptedLiftBound= deg;
+          success= false;
+        }
+        else
+        {
+          success= true;
+          if (e + 1 < degree (F) + 1)
+            adaptedLiftBound= deg;
+          else
+            adaptedLiftBound= e + 1;
+        }
+      }
+      else
+      {
+        success= true;
+        adaptedLiftBound= deg;
+      }
+    }
+    else
+    {
+      success= true;
+    }
+  }
+
+  return adaptedLiftBound;
+}
+
+CFList
+earlyFactorDetect (CanonicalForm& F, CFList& factors, int& adaptedLiftBound,
+                   bool& success, const int deg, const CFList& MOD,
+                   const int bound)
+{
+  CFList result;
+  CFList T= factors;
+  CanonicalForm buf= F;
+  Variable y= F.mvar();
+  Variable x= Variable (1);
+  CanonicalForm LCBuf= LC (buf, x);
+  CanonicalForm g, quot;
+  CFList M= MOD;
+  M.append (power (y, deg));
+  adaptedLiftBound= 0;
+  int d= bound;
+  int e= 0;
+  int nBuf;
+  for (CFListIterator i= factors; i.hasItem(); i++)
+  {
+    g= mulMod (i.getItem(), LCBuf, M);
+    g /= myContent (g);
+    if (fdivides (g, buf, quot))
+    {
+      result.append (g);
+      nBuf= degree (g, y) + degree (LC (g, x), y);
+      d -= nBuf;
+      e= tmax (e, nBuf);
+      buf= quot;
+      LCBuf= LC (buf, x);
+      T= Difference (T, CFList (i.getItem()));
+    }
+  }
+  adaptedLiftBound= d;
+
+  if (adaptedLiftBound < deg)
+  {
+    if (adaptedLiftBound < degree (F) + 1)
+    {
+      if (d == 1)
+        adaptedLiftBound= tmin (e + 1, deg);
+      else
+        adaptedLiftBound= deg;
+    }
+    factors= T;
+    F= buf;
+    success= true;
+  }
+  return result;
+}
+
+CFList
+extEarlyFactorDetect (CanonicalForm& F, CFList& factors, int& adaptedLiftBound,
+                      bool& success, const ExtensionInfo& info, const CFList&
+                      eval, const int deg, const CFList& MOD, const int bound)
+{
+  Variable alpha= info.getAlpha();
+  Variable beta= info.getBeta();
+  CanonicalForm gamma= info.getGamma();
+  CanonicalForm delta= info.getDelta();
+  int k= info.getGFDegree();
+  CFList result;
+  CFList T= factors;
+  CanonicalForm buf= F;
+  Variable y= F.mvar();
+  Variable x= Variable (1);
+  CanonicalForm LCBuf= LC (buf, x);
+  CanonicalForm g, gg, quot;
+  CFList M= MOD;
+  M.append (power (y, deg));
+  adaptedLiftBound= 0;
+  int d= bound;
+  int e= 0;
+  int nBuf;
+  CFList source, dest;
+
+  int degMipoBeta= 1;
+  if (!k && beta.level() != 1)
+    degMipoBeta= degree (getMipo (beta));
+
+  for (CFListIterator i= factors; i.hasItem(); i++)
+  {
+    g= mulMod (i.getItem(), LCBuf, M);
+    g /= myContent (g);
+    if (fdivides (g, buf, quot))
+    {
+      gg= reverseShift (g, eval);
+      gg /= Lc (gg);
+      if (!k && beta == x)
+      {
+        if (degree (gg, alpha) < degMipoBeta)
+        {
+          appendTestMapDown (result, gg, info, source, dest);
+          buf= quot;
+          nBuf= degree (g, y) + degree (LC (g, x), y);
+          d -= nBuf;
+          e= tmax (e, nBuf);
+          LCBuf= LC (buf, x);
+          T= Difference (T, CFList (i.getItem()));
+        }
+      }
+      else
+      {
+        if (!isInExtension (gg, gamma, k, delta, source, dest))
+        {
+          appendTestMapDown (result, gg, info, source, dest);
+          buf= quot;
+          nBuf= degree (g, y) + degree (LC (g, x), y);
+          d -= nBuf;
+          e= tmax (e, nBuf);
+          LCBuf= LC (buf, x);
+          T= Difference (T, CFList (i.getItem()));
+         }
+      }
+    }
+  }
+  adaptedLiftBound= d;
+
+  if (adaptedLiftBound < deg)
+  {
+    if (adaptedLiftBound < degree (F) + 1)
+    {
+      if (d == 1)
+        adaptedLiftBound= tmin (e + 1, deg);
+      else
+        adaptedLiftBound= deg;
+    }
+    success= true;
+    factors= T;
+    F= buf;
+  }
+  return result;
+}
+
+#define CHAR_THRESHOLD 8
+CFList
+evalPoints (const CanonicalForm& F, CFList & eval, const Variable& alpha,
+            CFList& list, const bool& GF, bool& fail)
+{
+  int k= F.level() - 1;
+  Variable x= Variable (1);
+  CanonicalForm LCF=LC (F, x);
+  CFList LCFeval;
+
+  CFList result;
+  FFRandom genFF;
+  GFRandom genGF;
+  int p= getCharacteristic ();
+  if (p < CHAR_THRESHOLD)
+  {
+    if (!GF && alpha.level() == 1)
+    {
+      fail= true;
+      return CFList();
+    }
+    else if (!GF && alpha.level() != 1)
+    {
+      if ((p == 2 && degree (getMipo (alpha)) < 6) ||
+          (p == 3 && degree (getMipo (alpha)) < 4) ||
+          (p == 5 && degree (getMipo (alpha)) < 3))
+      {
+        fail= true;
+        return CFList();
+      }
+    }
+  }
+  double bound;
+  if (alpha != x)
+  {
+    bound= pow ((double) p, (double) degree (getMipo(alpha)));
+    bound *= (double) k;
+  }
+  else if (GF)
+  {
+    bound= pow ((double) p, (double) getGFDegree());
+    bound *= (double) k;
+  }
+  else
+    bound= pow ((double) p, (double) k);
+
+  CanonicalForm random;
+  CanonicalForm deriv_x, gcd_deriv;
+  do
+  {
+    random= 0;
+    // possible overflow if list.length() does not fit into a int
+    if (list.length() >= bound)
+    {
+      fail= true;
+      break;
+    }
+    for (int i= 0; i < k; i++)
+    {
+      if (list.isEmpty())
+        result.append (0);
+      else if (GF)
+      {
+        result.append (genGF.generate());
+        random += result.getLast()*power (x, i);
+      }
+      else if (alpha.level() != 1)
+      {
+        AlgExtRandomF genAlgExt (alpha);
+        result.append (genAlgExt.generate());
+        random += result.getLast()*power (x, i);
+      }
+      else
+      {
+        result.append (genFF.generate());
+        random += result.getLast()*power (x, i);
+      }
+    }
+    if (find (list, random))
+    {
+      result= CFList();
+      continue;
+    }
+    int l= F.level();
+    eval.insert (F);
+    LCFeval.insert (LCF);
+    bool bad= false;
+    for (CFListIterator i= result; i.hasItem(); i++, l--)
+    {
+      eval.insert (eval.getFirst()(i.getItem(), l));
+      LCFeval.insert (LCFeval.getFirst()(i.getItem(), l));
+      if (degree (eval.getFirst(), l - 1) != degree (F, l - 1))
+      {
+        if (!find (list, random))
+          list.append (random);
+        result= CFList();
+        eval= CFList();
+        LCFeval= CFList();
+        bad= true;
+        break;
+      }
+      if ((l != 2) && (degree (LCFeval.getFirst(), l-1) != degree (LCF, l-1)))
+      {
+        if (!find (list, random))
+          list.append (random);
+        result= CFList();
+        eval= CFList();
+        LCFeval= CFList();
+        bad= true;
+        break;
+      }
+    }
+
+    if (bad)
+      continue;
+
+    if (degree (eval.getFirst()) != degree (F, 1))
+    {
+      if (!find (list, random))
+        list.append (random);
+      result= CFList();
+      LCFeval= CFList();
+      eval= CFList();
+      continue;
+    }
+
+    deriv_x= deriv (eval.getFirst(), x);
+    gcd_deriv= gcd (eval.getFirst(), deriv_x);
+    if (degree (gcd_deriv) > 0)
+    {
+      if (!find (list, random))
+        list.append (random);
+      result= CFList();
+      LCFeval= CFList();
+      eval= CFList();
+      continue;
+    }
+    CFListIterator i= eval;
+    i++;
+    CanonicalForm contentx= content (i.getItem(), x);
+    if (degree (contentx) > 0)
+    {
+      if (!find (list, random))
+        list.append (random);
+      result= CFList();
+      LCFeval= CFList();
+      eval= CFList();
+      continue;
+    }
+
+    contentx= content (i.getItem());
+    if (degree (contentx) > 0)
+    {
+      if (!find (list, random))
+        list.append (random);
+      result= CFList();
+      LCFeval= CFList();
+      eval= CFList();
+      continue;
+    }
+
+    if (list.length() >= bound)
+    {
+      fail= true;
+      break;
+    }
+  } while (find (list, random));
+
+  if (!eval.isEmpty())
+    eval.removeFirst();
+
+  return result;
+}
+
+static inline
+int newMainVariableSearch (CanonicalForm& A, CFList& Aeval, CFList&
+                           evaluation, const Variable& alpha, const int lev,
+                           CanonicalForm& g
+                          )
+{
+  Variable x= Variable (1);
+  CanonicalForm derivI, buf;
+  bool GF= (CFFactory::gettype() == GaloisFieldDomain);
+  int swapLevel= 0;
+  CFList list;
+  bool fail= false;
+  buf= A;
+  Aeval= CFList();
+  evaluation= CFList();
+  for (int i= lev; i <= A.level(); i++)
+  {
+    derivI= deriv (buf, Variable (i));
+    if (!derivI.isZero())
+    {
+      g= gcd (buf, derivI);
+      if (degree (g) > 0)
+        return -1;
+
+      buf= swapvar (buf, x, Variable (i));
+      Aeval= CFList();
+      evaluation= CFList();
+      fail= false;
+      evaluation= evalPoints (buf, Aeval, alpha, list, GF, fail);
+      if (!fail)
+      {
+        A= buf;
+        swapLevel= i;
+        break;
+      }
+      else
+        buf= A;
+    }
+  }
+  return swapLevel;
+}
+
+CanonicalForm lcmContent (const CanonicalForm& A, CFList& contentAi)
+{
+  int i= A.level();
+  CanonicalForm buf= A;
+  contentAi.append (content (buf, i));
+  buf /= contentAi.getLast();
+  contentAi.append (content (buf, i - 1));
+  CanonicalForm result= lcm (contentAi.getFirst(), contentAi.getLast());
+  for (i= i - 2; i > 0; i--)
+  {
+    contentAi.append (content (buf, i));
+    buf /= contentAi.getLast();
+    result= lcm (result, contentAi.getLast());
+  }
+  return result;
+}
+
+CFList
+henselLiftAndEarly (CanonicalForm& A, CFList& MOD, int*& liftBounds, bool&
+                    earlySuccess, CFList& earlyFactors, const CFList& Aeval,
+                    const CFList& biFactors, const CFList& evaluation,
+                    const ExtensionInfo& info)
+{
+  bool extension= info.isInExtension();
+  CFList bufFactors= biFactors;
+  bufFactors.insert (LC (Aeval.getFirst(), 1));
+
+  sortList (bufFactors, Variable (1));
+
+  CFList diophant;
+  CFArray Pi;
+  int smallFactorDeg= 11; //tunable parameter
+  CFList result;
+  int adaptedLiftBound= 0;
+  int liftBound= liftBounds[1];
+
+  earlySuccess= false;
+  CFList earlyReconstFactors;
+  CFListIterator j= Aeval;
+  j++;
+  CanonicalForm buf= j.getItem();
+  CFMatrix Mat= CFMatrix (liftBound, bufFactors.length() - 1);
+  MOD= CFList (power (Variable (2), liftBounds[0]));
+  if (smallFactorDeg >= liftBound)
+  {
+    result= henselLift23 (Aeval, bufFactors, liftBounds, diophant, Pi, Mat);
+  }
+  else if (smallFactorDeg >= degree (buf) + 1)
+  {
+    liftBounds[1]= degree (buf) + 1;
+    result= henselLift23 (Aeval, bufFactors, liftBounds, diophant, Pi, Mat);
+    if (Aeval.length() == 2)
+    {
+      if (!extension)
+        earlyFactors= earlyFactorDetect
+                       (buf, result, adaptedLiftBound, earlySuccess,
+                        degree (buf) + 1, MOD, liftBound);
+      else
+        earlyFactors= extEarlyFactorDetect
+                       (buf, result, adaptedLiftBound, earlySuccess,
+                        info, evaluation, degree
+                        (buf) + 1, MOD, liftBound);
+    }
+    else
+    {
+      if (!extension)
+        adaptedLiftBound= liftBoundAdaption (buf, result, earlySuccess,
+                                             degree (buf) + 1, MOD, liftBound);
+      else
+        adaptedLiftBound= extLiftBoundAdaption (buf, result, earlySuccess, info,
+                                                evaluation, degree (buf) + 1,
+                                                MOD, liftBound);
+    }
+    if (!earlySuccess)
+    {
+      result.insert (LC (buf, 1));
+      liftBounds[1]= adaptedLiftBound;
+      liftBound= adaptedLiftBound;
+      henselLiftResume (buf, result, degree (buf) + 1, liftBound,
+                        Pi, diophant, Mat, MOD);
+    }
+    else
+      liftBounds[1]= adaptedLiftBound;
+  }
+  else if (smallFactorDeg < degree (buf) + 1)
+  {
+    liftBounds[1]= smallFactorDeg;
+    result= henselLift23 (Aeval, bufFactors, liftBounds, diophant, Pi, Mat);
+    if (Aeval.length() == 2)
+    {
+      if (!extension)
+        earlyFactors= earlyFactorDetect (buf, result, adaptedLiftBound,
+                                         earlySuccess, smallFactorDeg, MOD,
+                                         liftBound);
+      else
+        earlyFactors= extEarlyFactorDetect (buf, result, adaptedLiftBound,
+                                            earlySuccess, info, evaluation,
+                                            smallFactorDeg, MOD, liftBound);
+    }
+    else
+    {
+      if (!extension)
+        adaptedLiftBound= liftBoundAdaption (buf, result, earlySuccess,
+                                             smallFactorDeg, MOD, liftBound);
+      else
+        adaptedLiftBound= extLiftBoundAdaption (buf, result, earlySuccess, info,
+                                                evaluation, smallFactorDeg, MOD,
+                                                liftBound);
+    }
+
+    if (!earlySuccess)
+    {
+      result.insert (LC (buf, 1));
+      henselLiftResume (buf, result, smallFactorDeg, degree (buf) + 1,
+                        Pi, diophant, Mat, MOD);
+      if (Aeval.length() == 2)
+      {
+         if (!extension)
+           earlyFactors= earlyFactorDetect (buf, result, adaptedLiftBound,
+                                            earlySuccess, degree (buf) + 1,
+                                            MOD, liftBound);
+         else
+           earlyFactors= extEarlyFactorDetect (buf, result, adaptedLiftBound,
+                                               earlySuccess, info, evaluation,
+                                               degree (buf) + 1, MOD,
+                                               liftBound);
+      }
+      else
+      {
+        if (!extension)
+          adaptedLiftBound= liftBoundAdaption (buf, result, earlySuccess,
+                                               degree (buf) + 1, MOD,liftBound);
+        else
+          adaptedLiftBound= extLiftBoundAdaption (buf, result, earlySuccess,
+                                                  info, evaluation,
+                                                  degree (buf) + 1, MOD,
+                                                  liftBound);
+      }
+      if (!earlySuccess)
+      {
+        result.insert (LC (buf, 1));
+        liftBounds[1]= adaptedLiftBound;
+        liftBound= adaptedLiftBound;
+        henselLiftResume (buf, result, degree (buf) + 1, liftBound,
+                          Pi, diophant, Mat, MOD);
+      }
+      else
+        liftBounds[1]= adaptedLiftBound;
+    }
+    else
+      liftBounds[1]= adaptedLiftBound;
+  }
+
+  MOD.append (power (Variable (3), liftBounds[1]));
+
+  if (Aeval.length() > 2)
+  {
+    CFListIterator j= Aeval;
+    j++;
+    CFList bufEval;
+    bufEval.append (j.getItem());
+    j++;
+    int liftBoundsLength= Aeval.getLast().level() - 1;
+    for (int i= 2; i <= liftBoundsLength && j.hasItem(); i++, j++)
+    {
+      earlySuccess= false;
+      result.insert (LC (bufEval.getFirst(), 1));
+      bufEval.append (j.getItem());
+      liftBound= liftBounds[i];
+      Mat= CFMatrix (liftBounds[i], result.length() - 1);
+
+      buf= j.getItem();
+      if (smallFactorDeg >= liftBound)
+        result= henselLift (bufEval, result, MOD, diophant, Pi, Mat,
+                            liftBounds[i -  1], liftBounds[i]);
+      else if (smallFactorDeg >= degree (buf) + 1)
+      {
+        result= henselLift (bufEval, result, MOD, diophant, Pi, Mat,
+                            liftBounds[i -  1], degree (buf) + 1);
+
+        if (Aeval.length() == i + 1)
+        {
+          if (!extension)
+            earlyFactors= earlyFactorDetect
+                           (buf, result, adaptedLiftBound, earlySuccess,
+                            degree (buf) + 1, MOD, liftBound);
+          else
+            earlyFactors= extEarlyFactorDetect
+                           (buf, result, adaptedLiftBound, earlySuccess,
+                            info, evaluation, degree (buf) + 1, MOD, liftBound);
+        }
+        else
+        {
+          if (!extension)
+            adaptedLiftBound= liftBoundAdaption
+                                (buf, result, earlySuccess, degree (buf)
+                                 + 1,  MOD, liftBound);
+          else
+            adaptedLiftBound= extLiftBoundAdaption
+                                (buf, result, earlySuccess, info, evaluation,
+                                 degree (buf) + 1, MOD, liftBound);
+        }
+
+        if (!earlySuccess)
+        {
+          result.insert (LC (buf, 1));
+          liftBounds[i]= adaptedLiftBound;
+          liftBound= adaptedLiftBound;
+          henselLiftResume (buf, result, degree (buf) + 1, liftBound,
+                            Pi, diophant, Mat, MOD);
+        }
+        else
+        {
+          liftBounds[i]= adaptedLiftBound;
+        }
+      }
+      else if (smallFactorDeg < degree (buf) + 1)
+      {
+        result= henselLift (bufEval, result, MOD, diophant, Pi, Mat,
+                            liftBounds[i -  1], smallFactorDeg);
+
+        if (Aeval.length() == i + 1)
+        {
+          if (!extension)
+            earlyFactors= earlyFactorDetect
+                           (buf, result, adaptedLiftBound, earlySuccess,
+                            smallFactorDeg, MOD, liftBound);
+          else
+            earlyFactors= extEarlyFactorDetect
+                           (buf, result, adaptedLiftBound, earlySuccess,
+                            info, evaluation, smallFactorDeg, MOD, liftBound);
+        }
+        else
+        {
+          if (!extension)
+            adaptedLiftBound= liftBoundAdaption
+                                (buf, result, earlySuccess,
+                                 smallFactorDeg, MOD, liftBound);
+          else
+            adaptedLiftBound= extLiftBoundAdaption
+                                (buf, result, earlySuccess, info, evaluation,
+                                 smallFactorDeg, MOD, liftBound);
+        }
+
+        if (!earlySuccess)
+        {
+          result.insert (LC (buf, 1));
+          henselLiftResume (buf, result, smallFactorDeg,
+                            degree (buf) + 1, Pi, diophant, Mat, MOD);
+          if (Aeval.length() == i + 1)
+          {
+            if (!extension)
+              earlyFactors= earlyFactorDetect
+                             (buf, result, adaptedLiftBound, earlySuccess,
+                              degree (buf) +  1,  MOD, liftBound);
+            else
+              earlyFactors= extEarlyFactorDetect
+                             (buf, result, adaptedLiftBound, earlySuccess,
+                              info, evaluation, degree (buf) + 1, MOD,
+                              liftBound);
+          }
+          else
+          {
+            if (!extension)
+              adaptedLiftBound= liftBoundAdaption
+                                  (buf, result, earlySuccess, degree
+                                   (buf) +  1,  MOD, liftBound);
+            else
+              adaptedLiftBound= extLiftBoundAdaption
+                                  (buf, result, earlySuccess, info, evaluation,
+                                   degree (buf) + 1,  MOD, liftBound);
+          }
+
+          if (!earlySuccess)
+          {
+            result.insert (LC (buf, 1));
+            liftBounds[i]= adaptedLiftBound;
+            liftBound= adaptedLiftBound;
+            henselLiftResume (buf, result, degree (buf) + 1, liftBound,
+                              Pi, diophant, Mat, MOD);
+          }
+          else
+            liftBounds[i]= adaptedLiftBound;
+        }
+        else
+          liftBounds[i]= adaptedLiftBound;
+      }
+      MOD.append (power (Variable (i + 2), liftBounds[i]));
+      bufEval.removeFirst();
+    }
+    bufFactors= result;
+  }
+  else
+    bufFactors= result;
+
+  if (earlySuccess)
+    A= buf;
+  return result;
+}
+
+void
+gcdFreeBasis (CFFList& factors1, CFFList& factors2)
+{
+  CanonicalForm g;
+  int k= factors1.length();
+  int l= factors2.length();
+  int n= 0;
+  int m;
+  CFFListIterator j;
+  for (CFFListIterator i= factors1; (n < k && i.hasItem()); i++, n++)
+  {
+    m= 0;
+    for (j= factors2; (m < l && j.hasItem()); j++, m++)
+    {
+      g= gcd (i.getItem().factor(), j.getItem().factor());
+      if (degree (g,1) > 0)
+      {
+        j.getItem()= CFFactor (j.getItem().factor()/g, j.getItem().exp());
+        i.getItem()= CFFactor (i.getItem().factor()/g, i.getItem().exp());
+        factors1.append (CFFactor (g, i.getItem().exp()));
+        factors2.append (CFFactor (g, j.getItem().exp()));
+      }
+    }
+  }
+}
+
+CFList
+distributeContent (const CFList& L, const CFList* differentSecondVarFactors,
+                   int length
+                  )
+{
+  CFList l= L;
+  CanonicalForm content= l.getFirst();
+
+  if (content.inCoeffDomain())
+    return l;
+
+  if (l.length() == 1)
+  {
+    CFList result;
+    for (int i= 0; i < length; i++)
+    {
+      if (differentSecondVarFactors[i].isEmpty())
+        continue;
+      if (result.isEmpty())
+      {
+        result= differentSecondVarFactors[i];
+        for (CFListIterator iter= result; iter.hasItem(); iter++)
+          content /= iter.getItem();
+      }
+      else
+      {
+        CFListIterator iter1= result;
+        for (CFListIterator iter2= differentSecondVarFactors[i];iter2.hasItem();
+             iter2++, iter1++)
+        {
+          iter1.getItem() *= iter2.getItem();
+          content /= iter2.getItem();
+        }
+      }
+    }
+    result.insert (content);
+    return result;
+  }
+
+  Variable v;
+  CFListIterator iter1, iter2;
+  CanonicalForm tmp, g;
+  CFList multiplier;
+  for (int i= 0; i < length; i++)
+  {
+    if (differentSecondVarFactors[i].isEmpty())
+      continue;
+    iter1= l;
+    iter1++;
+
+    tmp= 1;
+    for (iter2= differentSecondVarFactors[i]; iter2.hasItem();
+         iter2++, iter1++)
+    {
+      if (iter2.getItem().inCoeffDomain())
+      {
+        multiplier.append (1);
+        continue;
+      }
+      v= iter2.getItem().mvar();
+      if (degree (iter2.getItem()) == degree (iter1.getItem(),v))
+      {
+        multiplier.append (1);
+        continue;
+      }
+      g= gcd (iter2.getItem(), content);
+      if (!g.inCoeffDomain())
+      {
+        tmp *= g;
+        multiplier.append (g);
+      }
+      else
+        multiplier.append (1);
+    }
+    if (!tmp.isOne() && fdivides (tmp, content))
+    {
+      iter1= l;
+      iter1++;
+      content /= tmp;
+      for (iter2= multiplier; iter2.hasItem(); iter1++, iter2++)
+        iter1.getItem() *= iter2.getItem();
+    }
+    multiplier= CFList();
+  }
+
+  l.removeFirst();
+  l.insert (content);
+  return l;
+}
+
+int
+testFactors (const CanonicalForm& G, const CFList& uniFactors,
+             const Variable& alpha, CanonicalForm& sqrfPartF, CFList& factors,
+             CFFList*& bufSqrfFactors, CFList& evalSqrfPartF,
+             const CFArray& evalPoint)
+{
+  CanonicalForm F= G;
+  CFFList sqrfFactorization;
+  if (getCharacteristic() > 0)
+    sqrfFactorization= squarefreeFactorization (F, alpha);
+  else
+    sqrfFactorization= sqrFree (F);
+
+  sqrfPartF= 1;
+  for (CFFListIterator i= sqrfFactorization; i.hasItem(); i++)
+    sqrfPartF *= i.getItem().factor();
+
+  evalSqrfPartF= evaluateAtEval (sqrfPartF, evalPoint);
+
+  CanonicalForm test= evalSqrfPartF.getFirst() (evalPoint[0], 2);
+
+  if (degree (test) != degree (sqrfPartF, 1) || test.inCoeffDomain())
+    return 0;
+
+  CFFList sqrfFactors;
+  CanonicalForm tmp;
+  CFList tmp2;
+  int k= 0;
+  factors= uniFactors;
+  CFFListIterator iter;
+  for (CFListIterator i= factors; i.hasItem(); i++, k++)
+  {
+    tmp= 1;
+    if (getCharacteristic() > 0)
+      sqrfFactors= squarefreeFactorization (i.getItem(), alpha);
+    else
+      sqrfFactors= sqrFree (i.getItem());
+
+    for (iter= sqrfFactors; iter.hasItem(); iter++)
+    {
+      tmp2.append (iter.getItem().factor());
+      tmp *= iter.getItem().factor();
+    }
+    i.getItem()= tmp/Lc(tmp);
+    bufSqrfFactors [k]= sqrfFactors;
+  }
+
+  for (int i= 0; i < factors.length() - 1; i++)
+  {
+    for (k= i + 1; k < factors.length(); k++)
+    {
+      gcdFreeBasis (bufSqrfFactors [i], bufSqrfFactors[k]);
+    }
+  }
+
+  factors= CFList();
+  for (int i= 0; i < uniFactors.length(); i++)
+  {
+    if (i == 0)
+    {
+      for (iter= bufSqrfFactors [i]; iter.hasItem(); iter++)
+      {
+        if (iter.getItem().factor().inCoeffDomain())
+          continue;
+        iter.getItem()= CFFactor (iter.getItem().factor()/
+                                  Lc (iter.getItem().factor()),
+                                  iter.getItem().exp());
+        factors.append (iter.getItem().factor());
+      }
+    }
+    else
+    {
+      for (iter= bufSqrfFactors [i]; iter.hasItem(); iter++)
+      {
+        if (iter.getItem().factor().inCoeffDomain())
+          continue;
+        iter.getItem()= CFFactor (iter.getItem().factor()/
+                                  Lc (iter.getItem().factor()),
+                                  iter.getItem().exp());
+        if (!find (factors, iter.getItem().factor()))
+          factors.append (iter.getItem().factor());
+      }
+    }
+  }
+
+  test= prod (factors);
+  tmp= evalSqrfPartF.getFirst() (evalPoint[0],2);
+  if (test/Lc (test) != tmp/Lc (tmp))
+    return 0;
+  else
+    return 1;
+}
+
+CFList
+precomputeLeadingCoeff (const CanonicalForm& LCF, const CFList& LCFFactors,
+                        const Variable& alpha, const CFList& evaluation,
+                        CFList* & differentSecondVarLCs, int lSecondVarLCs,
+                        Variable& y
+                       )
+{
+  y= Variable (1);
+  if (LCF.inCoeffDomain())
+  {
+    CFList result;
+    for (int i= 1; i <= LCFFactors.length() + 1; i++)
+      result.append (1);
+    return result;
+  }
+
+  CFMap N, M;
+  CFArray dummy= CFArray (2);
+  dummy [0]= LCF;
+  dummy [1]= Variable (2);
+  compress (dummy, M, N);
+  CanonicalForm F= M (LCF);
+  if (LCF.isUnivariate())
+  {
+    CFList result;
+    int LCFLevel= LCF.level();
+    bool found= false;
+    if (LCFLevel == 2)
+    {
+    //bivariate leading coefficients are already the true leading coefficients
+      result= LCFFactors;
+      found= true;
+    }
+    else
+    {
+      CFListIterator j;
+      for (int i= 0; i < lSecondVarLCs; i++)
+      {
+        for (j= differentSecondVarLCs[i]; j.hasItem(); j++)
+        {
+          if (j.getItem().level() == LCFLevel)
+          {
+            found= true;
+            break;
+          }
+        }
+        if (found)
+        {
+          result= differentSecondVarLCs [i];
+          break;
+        }
+      }
+      if (!found)
+        result= LCFFactors;
+    }
+    if (found)
+      result.insert (Lc (LCF));
+    else
+      result.insert (LCF);
+
+    return result;
+  }
+
+  CFList factors= LCFFactors;
+
+  for (CFListIterator i= factors; i.hasItem(); i++)
+    i.getItem()= M (i.getItem());
+
+  CanonicalForm sqrfPartF;
+  CFFList * bufSqrfFactors= new CFFList [factors.length()];
+  CFList evalSqrfPartF, bufFactors;
+  CFArray evalPoint= CFArray (evaluation.length() - 1);
+  CFArray buf= CFArray (evaluation.length());
+  CFArray swap= CFArray (evaluation.length());
+  CFListIterator iter= evaluation;
+  CanonicalForm vars=getVars (LCF)*Variable (2);
+  for (int i= evaluation.length() +1; i > 1; i--, iter++)
+  {
+    buf[i-2]=iter.getItem();
+    if (degree (vars, i) > 0)
+      swap[M(Variable (i)).level()-1]=buf[i-2];
+  }
+  buf= swap;
+  for (int i= 0; i < evaluation.length() - 1; i++)
+    evalPoint[i]= buf[i+1];
+
+  int pass= testFactors (F, factors, alpha, sqrfPartF,
+                         bufFactors, bufSqrfFactors, evalSqrfPartF, evalPoint);
+
+  bool foundDifferent= false;
+  Variable z, x= y;
+  int j= 0;
+  if (!pass)
+  {
+    int lev= 0;
+    // LCF is non-constant here
+    CFList bufBufFactors;
+    CanonicalForm bufF;
+    for (int i= 0; i < lSecondVarLCs; i++)
+    {
+      if (!differentSecondVarLCs [i].isEmpty())
+      {
+        bool allConstant= true;
+        for (iter= differentSecondVarLCs[i]; iter.hasItem(); iter++)
+        {
+          if (!iter.getItem().inCoeffDomain())
+          {
+            allConstant= false;
+            y= Variable (iter.getItem().level());
+            lev= M(y).level();
+          }
+        }
+        if (allConstant)
+          continue;
+
+        bufFactors= differentSecondVarLCs [i];
+        for (iter= bufFactors; iter.hasItem(); iter++)
+          iter.getItem()= swapvar (iter.getItem(), x, y);
+        bufF= F;
+        z= Variable (lev);
+        bufF= swapvar (bufF, x, z);
+        bufBufFactors= bufFactors;
+        evalPoint= CFArray (evaluation.length() - 1);
+        for (int k= 1; k < evaluation.length(); k++)
+        {
+          if (N (Variable (k+1)).level() != y.level())
+            evalPoint[k-1]= buf[k];
+          else
+            evalPoint[k-1]= buf[0];
+        }
+        pass= testFactors (bufF, bufBufFactors, alpha, sqrfPartF, bufFactors,
+                           bufSqrfFactors, evalSqrfPartF, evalPoint);
+        if (pass)
+        {
+          foundDifferent= true;
+          F= bufF;
+          CFList l= factors;
+          for (iter= l; iter.hasItem(); iter++)
+            iter.getItem()= swapvar (iter.getItem(), x, y);
+          differentSecondVarLCs [i]= l;
+          j= i;
+          break;
+        }
+        if (!pass && i == lSecondVarLCs - 1)
+        {
+          CFList result;
+          result.append (LCF);
+          for (int j= 1; j <= factors.length(); j++)
+            result.append (1);
+          result= distributeContent (result, differentSecondVarLCs, lSecondVarLCs);
+          y= Variable (1);
+          delete [] bufSqrfFactors;
+          return result;
+        }
+      }
+    }
+  }
+  if (!pass)
+  {
+    CFList result;
+    result.append (LCF);
+    for (int j= 1; j <= factors.length(); j++)
+      result.append (1);
+    result= distributeContent (result, differentSecondVarLCs, lSecondVarLCs);
+    y= Variable (1);
+    delete [] bufSqrfFactors;
+    return result;
+  }
+  else
+    factors= bufFactors;
+
+  bufFactors= factors;
+
+  CFMap MM, NN;
+  dummy [0]= sqrfPartF;
+  dummy [1]= 1;
+  compress (dummy, MM, NN);
+  sqrfPartF= MM (sqrfPartF);
+  CanonicalForm varsSqrfPartF= getVars (sqrfPartF);
+  for (CFListIterator iter= factors; iter.hasItem(); iter++)
+    iter.getItem()= MM (iter.getItem());
+
+  CFList evaluation2;
+  for (int i= 2; i <= varsSqrfPartF.level(); i++)
+    evaluation2.insert (evalPoint[NN (Variable (i)).level()-2]);
+
+  CFList interMedResult;
+  CanonicalForm oldSqrfPartF= sqrfPartF;
+  sqrfPartF= shift2Zero (sqrfPartF, evalSqrfPartF, evaluation2);
+  if (factors.length() > 1)
+  {
+    CanonicalForm LC1= LC (oldSqrfPartF, 1);
+    CFList leadingCoeffs;
+    for (int i= 0; i < factors.length(); i++)
+      leadingCoeffs.append (LC1);
+
+    CFList LC1eval= evaluateAtEval (LC1, evaluation2, 2);
+    CFList oldFactors= factors;
+    for (CFListIterator i= oldFactors; i.hasItem(); i++)
+      i.getItem() *= LC1eval.getFirst()/Lc (i.getItem());
+
+    bool success= false;
+    CanonicalForm oldSqrfPartFPowLC= oldSqrfPartF*power(LC1,factors.length()-1);
+    CFList heuResult;
+    if (size (oldSqrfPartFPowLC)/getNumVars (oldSqrfPartFPowLC) < 500 &&
+        LucksWangSparseHeuristic (oldSqrfPartFPowLC,
+                                  oldFactors, 2, leadingCoeffs, heuResult))
+    {
+      interMedResult= recoverFactors (oldSqrfPartF, heuResult);
+      if (oldFactors.length() == interMedResult.length())
+        success= true;
+    }
+    if (!success)
+    {
+      LC1= LC (evalSqrfPartF.getFirst(), 1);
+
+      CFArray leadingCoeffs= CFArray (factors.length());
+      for (int i= 0; i < factors.length(); i++)
+        leadingCoeffs[i]= LC1;
+
+      for (CFListIterator i= factors; i.hasItem(); i++)
+        i.getItem() *= LC1 (0,2)/Lc (i.getItem());
+      factors.insert (1);
+
+      CanonicalForm
+      newSqrfPartF= evalSqrfPartF.getFirst()*power (LC1, factors.length() - 2);
+
+      int liftBound= degree (newSqrfPartF,2) + 1;
+
+      CFMatrix M= CFMatrix (liftBound, factors.length() - 1);
+      CFArray Pi;
+      CFList diophant;
+      nonMonicHenselLift12 (newSqrfPartF, factors, liftBound, Pi, diophant, M,
+                            leadingCoeffs, false);
+
+      if (sqrfPartF.level() > 2)
+      {
+        int* liftBounds= new int [sqrfPartF.level() - 1];
+        bool noOneToOne= false;
+        CFList *leadingCoeffs2= new CFList [sqrfPartF.level()-2];
+        LC1= LC (evalSqrfPartF.getLast(), 1);
+        CFList LCs;
+        for (int i= 0; i < factors.length(); i++)
+          LCs.append (LC1);
+        leadingCoeffs2 [sqrfPartF.level() - 3]= LCs;
+        for (int i= sqrfPartF.level() - 1; i > 2; i--)
+        {
+          for (CFListIterator j= LCs; j.hasItem(); j++)
+            j.getItem()= j.getItem() (0, i + 1);
+          leadingCoeffs2 [i - 3]= LCs;
+        }
+        sqrfPartF *= power (LC1, factors.length()-1);
+
+        int liftBoundsLength= sqrfPartF.level() - 1;
+        for (int i= 0; i < liftBoundsLength; i++)
+          liftBounds [i]= degree (sqrfPartF, i + 2) + 1;
+        evalSqrfPartF= evaluateAtZero (sqrfPartF);
+        evalSqrfPartF.removeFirst();
+        factors= nonMonicHenselLift (evalSqrfPartF, factors, leadingCoeffs2,
+                 diophant, Pi, liftBounds, sqrfPartF.level() - 1, noOneToOne);
+        delete [] leadingCoeffs2;
+        delete [] liftBounds;
+      }
+      for (CFListIterator iter= factors; iter.hasItem(); iter++)
+        iter.getItem()= reverseShift (iter.getItem(), evaluation2);
+
+      interMedResult=
+      recoverFactors (reverseShift(evalSqrfPartF.getLast(),evaluation2),
+                      factors);
+    }
+  }
+  else
+  {
+    CanonicalForm contF=content (oldSqrfPartF,1);
+    factors= CFList (oldSqrfPartF/contF);
+    interMedResult= recoverFactors (oldSqrfPartF, factors);
+  }
+
+  for (CFListIterator iter= interMedResult; iter.hasItem(); iter++)
+    iter.getItem()= NN (iter.getItem());
+
+  CFList result;
+  CFFListIterator k;
+  for (int i= 0; i < LCFFactors.length(); i++)
+  {
+    CanonicalForm tmp= 1;
+    for (k= bufSqrfFactors[i]; k.hasItem(); k++)
+    {
+      int pos= findItem (bufFactors, k.getItem().factor());
+      if (pos)
+        tmp *= power (getItem (interMedResult, pos), k.getItem().exp());
+    }
+    result.append (tmp);
+  }
+
+  for (CFListIterator i= result; i.hasItem(); i++)
+  {
+    F /= i.getItem();
+    if (foundDifferent)
+      i.getItem()= swapvar (i.getItem(), x, z);
+    i.getItem()= N (i.getItem());
+  }
+
+  if (foundDifferent)
+  {
+    CFList l= differentSecondVarLCs [j];
+    for (CFListIterator i= l; i.hasItem(); i++)
+      i.getItem()= swapvar (i.getItem(), y, z);
+    differentSecondVarLCs [j]= l;
+    F= swapvar (F, x, z);
+  }
+
+  result.insert (N (F));
+
+  result= distributeContent (result, differentSecondVarLCs, lSecondVarLCs);
+
+  if (!result.getFirst().inCoeffDomain())
+  {
+    // prepare input for recursion
+    if (foundDifferent)
+    {
+      for (CFListIterator i= result; i.hasItem(); i++)
+        i.getItem()= swapvar (i.getItem(), Variable (2), y);
+      CFList l= differentSecondVarLCs [j];
+      for (CFListIterator i= l; i.hasItem(); i++)
+        i.getItem()= swapvar (i.getItem(), y, z);
+      differentSecondVarLCs [j]= l;
+    }
+
+    F= result.getFirst();
+    int level= 0;
+    if (foundDifferent)
+    {
+      level= y.level() - 2;
+      for (int i= y.level(); i > 1; i--)
+      {
+        if (degree (F,i) > 0)
+        {
+          if (y.level() == 3)
+            level= 0;
+          else
+            level= i-3;
+        }
+      }
+    }
+lcretry:
+    if (lSecondVarLCs - level > 0)
+    {
+      CFList evaluation2= evaluation;
+      int j= lSecondVarLCs+2;
+      CanonicalForm swap;
+      CFListIterator i;
+      for (i= evaluation2; i.hasItem(); i++, j--)
+      {
+        if (j==y.level())
+        {
+          swap= i.getItem();
+          i.getItem()= evaluation2.getLast();
+          evaluation2.removeLast();
+          evaluation2.append (swap);
+        }
+      }
+
+      CFList newLCs= differentSecondVarLCs[level];
+      if (newLCs.isEmpty())
+      {
+        if (degree (F, level+3) > 0)
+        {
+          delete [] bufSqrfFactors;
+          return result; //TODO handle this case
+        }
+        level=level+1;
+        goto lcretry;
+      }
+      i= newLCs;
+      CFListIterator iter= result;
+      iter++;
+      CanonicalForm quot;
+      for (;iter.hasItem(); iter++, i++)
+      {
+        swap= iter.getItem();
+        if (degree (swap, level+3) > 0)
+        {
+          int count= evaluation.length()+1;
+          for (CFListIterator iter2= evaluation2; iter2.hasItem(); iter2++,
+                                                                    count--)
+          {
+            if (count != level+3)
+              swap= swap (iter2.getItem(), count);
+          }
+          if (fdivides (swap, i.getItem(), quot))
+            i.getItem()= quot;
+        }
+      }
+      CFList * differentSecondVarLCs2= new CFList [lSecondVarLCs - level - 1];
+      for (int j= level+1; j < lSecondVarLCs; j++)
+      {
+        if (degree (F, j+3) > 0)
+        {
+          if (!differentSecondVarLCs[j].isEmpty())
+          {
+            differentSecondVarLCs2[j - level - 1]= differentSecondVarLCs[j];
+            i= differentSecondVarLCs2[j-level - 1];
+            iter=result;
+            iter++;
+            for (;iter.hasItem(); iter++, i++)
+            {
+              swap= iter.getItem();
+              if (degree (swap, j+3) > 0)
+              {
+                int count= evaluation.length()+1;
+                for (CFListIterator iter2= evaluation2; iter2.hasItem();iter2++,
+                                                                        count--)
+                {
+                  if (count != j+3)
+                    swap= swap (iter2.getItem(), count);
+                }
+                if (fdivides (swap, i.getItem(), quot))
+                  i.getItem()= quot;
+              }
+            }
+          }
+        }
+      }
+
+      for (int j= 0; j < level+1; j++)
+        evaluation2.removeLast();
+      Variable dummyvar= Variable (1);
+
+      CanonicalForm newLCF= result.getFirst();
+      newLCF=swapvar (newLCF, Variable (2), Variable (level+3));
+      for (i=newLCs; i.hasItem(); i++)
+        i.getItem()= swapvar (i.getItem(), Variable (2), Variable (level+3));
+      for (int j= 1; j < lSecondVarLCs-level;j++)
+      {
+        for (i= differentSecondVarLCs2[j-1]; i.hasItem(); i++)
+          i.getItem()= swapvar (i.getItem(), Variable (2+j),
+                                             Variable (level+3+j));
+        newLCF= swapvar (newLCF, Variable (2+j), Variable (level+3+j));
+      }
+
+      CFList recursiveResult=
+      precomputeLeadingCoeff (newLCF, newLCs, alpha, evaluation2,
+                              differentSecondVarLCs2, lSecondVarLCs - level - 1,
+                              dummyvar);
+
+      if (dummyvar.level() != 1)
+      {
+        for (i= recursiveResult; i.hasItem(); i++)
+          i.getItem()= swapvar (i.getItem(), Variable (2), dummyvar);
+      }
+      for (i= recursiveResult; i.hasItem(); i++)
+      {
+        for (int j= lSecondVarLCs-level-1; j > 0; j--)
+          i.getItem()=swapvar (i.getItem(), Variable (2+j),
+                                      Variable (level+3+j));
+        i.getItem()= swapvar (i.getItem(), Variable (2), Variable (level+3));
+      }
+
+      if (recursiveResult.getFirst() == result.getFirst())
+      {
+        delete [] bufSqrfFactors;
+        delete [] differentSecondVarLCs2;
+        return result;
+      }
+      else
+      {
+        iter=recursiveResult;
+        i= result;
+        i.getItem()= iter.getItem();
+        i++;
+        iter++;
+        for (; i.hasItem(); i++, iter++)
+          i.getItem() *= iter.getItem();
+        delete [] differentSecondVarLCs2;
+      }
+    }
+  }
+  else
+    y= Variable (1);
+
+  delete [] bufSqrfFactors;
+
+  return result;
+}
+
+void
+evaluationWRTDifferentSecondVars (CFList*& Aeval, const CFList& evaluation,
+                                  const CanonicalForm& A)
+{
+  CanonicalForm tmp;
+  CFList tmp2;
+  CFListIterator iter;
+  bool preserveDegree= true;
+  Variable x= Variable (1);
+  int j, degAi, degA1= degree (A,1);
+  for (int i= A.level(); i > 2; i--)
+  {
+    tmp= A;
+    tmp2= CFList();
+    iter= evaluation;
+    preserveDegree= true;
+    degAi= degree (A,i);
+    for (j= A.level(); j > 1; j--, iter++)
+    {
+      if (j == i)
+        continue;
+      else
+      {
+        tmp= tmp (iter.getItem(), j);
+        tmp2.insert (tmp);
+        if ((degree (tmp, i) != degAi) ||
+            (degree (tmp, 1) != degA1))
+        {
+          preserveDegree= false;
+          break;
+        }
+      }
+    }
+    if (!content(tmp,1).inCoeffDomain())
+      preserveDegree= false;
+    if (!content(tmp).inCoeffDomain())
+      preserveDegree= false;
+    if (!(gcd (deriv (tmp,x), tmp)).inCoeffDomain())
+      preserveDegree= false;
+    if (preserveDegree)
+      Aeval [i - 3]= tmp2;
+    else
+      Aeval [i - 3]= CFList();
+  }
+}
+
+#endif
+
+static inline
+CanonicalForm prodEval (const CFList& l, const CanonicalForm& evalPoint,
+                        const Variable& v)
+{
+  CanonicalForm result= 1;
+  for (CFListIterator i= l; i.hasItem(); i++)
+    result *= i.getItem() (evalPoint, v);
+  return result;
+}
+
+void
+checkHelper (const CanonicalForm& f1, CFList& factors1, CFList& factors2,
+             CFList& l1, CFList& l2)
+{
+  CanonicalForm g1= f1, g2;
+  CFListIterator iter1= factors1, iter2= factors2;
+  for (; iter1.hasItem(); iter1++, iter2++)
+  {
+    g2= gcd (g1, iter1.getItem());
+    if (!g2.inCoeffDomain())
+    {
+      l1.append (iter1.getItem());
+      l2.append (iter2.getItem());
+      g1 /= g2;
+    }
+  }
+  factors1= Difference (factors1, l1);
+  factors2= Difference (factors2, l2);
+}
+
+/// check if univariate factors @a factors2 of @a factors3 coincide with
+/// univariate factors of @a factors1 and recombine if necessary.
+/// The recombined factors of @a factors1 are returned and @a factors3 is
+/// recombined accordingly.
+CFList
+checkOneToOne (const CFList& factors1, const CFList& factors2, CFList& factors3,
+               const CanonicalForm& evalPoint, const Variable& x)
+{
+  CFList uniFactorsOfFactors1;
+  CFList result, result2;
+  CFList bad1= factors2;
+  CFListIterator iter, iter2, iter3;
+  CanonicalForm tmp;
+  int pos;
+
+  for (iter= factors1; iter.hasItem(); iter++)
+  {
+    tmp= iter.getItem() (evalPoint, x);
+    tmp /= Lc (tmp);
+    if ((pos= findItem (factors2, tmp)))
+    {
+      result2.append (getItem (factors3, pos));
+      result.append (iter.getItem());
+      bad1= Difference (bad1, CFList (tmp));
+    }
+    else
+      uniFactorsOfFactors1.append (tmp);
+  }
+
+  CFList bad2, bad3;
+  bad2= Difference (factors1, result);
+  bad3= Difference (factors3, result2);
+  CFList tmp2, tmp3;
+  CanonicalForm g1, g2, g3, g4;
+
+  while (!uniFactorsOfFactors1.isEmpty())
+  {
+    tmp= uniFactorsOfFactors1.getFirst();
+    checkHelper (tmp, bad1, bad3, tmp2, tmp3);
+    g1= prod (tmp2);
+    g2= prod (tmp3);
+    tmp2= CFList();
+    tmp3= CFList();
+    checkHelper (g1, uniFactorsOfFactors1, bad2, tmp2, tmp3);
+    g3= prod (tmp2);
+    g4= prod (tmp3);
+    tmp2= CFList();
+    tmp3= CFList();
+    do
+    {
+      checkHelper (g3, bad1, bad3, tmp2, tmp3);
+      g1 *= prod (tmp2);
+      g2 *= prod (tmp3);
+      tmp2= CFList();
+      tmp3= CFList();
+      checkHelper (g1, uniFactorsOfFactors1, bad2, tmp2, tmp3);
+      g3 *= prod (tmp2);
+      g4 *= prod (tmp3);
+      tmp2= CFList();
+      tmp3= CFList();
+    } while (!bad2.isEmpty() && !bad3.isEmpty());
+    result.append (g4);
+    result2.append (g2);
+  }
+
+  if (factors3.length() != result2.length())
+    factors3= result2;
+  return result;
+}
+
+//recombine bivariate factors in case one bivariate factorization yields less
+// factors than the other
+CFList
+recombination (const CFList& factors1, const CFList& factors2, int s, int thres,
+               const CanonicalForm& evalPoint, const Variable& x)
+{
+  CFList T, S;
+
+  T= factors1;
+  CFList result;
+  CanonicalForm buf;
+  int * v= new int [T.length()];
+  for (int i= 0; i < T.length(); i++)
+    v[i]= 0;
+  bool nosubset= false;
+  CFArray TT;
+  TT= copy (factors1);
+  int recombinations= 0;
+  while (T.length() >= 2*s && s <= thres)
+  {
+    while (nosubset == false)
+    {
+      if (T.length() == s)
+      {
+        delete [] v;
+        if (recombinations == factors2.length() - 1)
+          result.append (prod (T));
+        else
+          result= Union (result, T);
+        return result;
+      }
+      S= subset (v, s, TT, nosubset);
+      if (nosubset) break;
+      buf= prodEval (S, evalPoint, x);
+      buf /= Lc (buf);
+      if (find (factors2, buf))
+      {
+        recombinations++;
+        T= Difference (T, S);
+        result.append (prod (S));
+        TT= copy (T);
+        indexUpdate (v, s, T.length(), nosubset);
+        if (nosubset) break;
+      }
+    }
+    s++;
+    if (T.length() < 2*s || T.length() == s)
+    {
+      if (recombinations == factors2.length() - 1)
+        result.append (prod (T));
+      else
+        result= Union (result, T);
+      delete [] v;
+      return result;
+    }
+    for (int i= 0; i < T.length(); i++)
+      v[i]= 0;
+    nosubset= false;
+  }
+
+  delete [] v;
+  if (T.length() < 2*s)
+  {
+    result= Union (result, T);
+    return result;
+  }
+
+  return result;
+}
+
+#ifdef HAVE_NTL
+void
+factorizationWRTDifferentSecondVars (const CanonicalForm& A, CFList*& Aeval,
+                                     const ExtensionInfo& info,
+                                     int& minFactorsLength, bool& irred)
+{
+  Variable x= Variable (1);
+  minFactorsLength= 0;
+  irred= false;
+  CFList factors;
+  Variable v;
+  for (int j= 0; j < A.level() - 2; j++)
+  {
+    if (!Aeval[j].isEmpty())
+    {
+      v= Variable (Aeval[j].getFirst().level());
+      if (CFFactory::gettype() == GaloisFieldDomain)
+        factors= GFBiSqrfFactorize (Aeval[j].getFirst());
+      else if (info.getAlpha().level() == 1)
+        factors= FpBiSqrfFactorize (Aeval[j].getFirst());
+      else
+        factors= FqBiSqrfFactorize (Aeval[j].getFirst(), info.getAlpha());
+
+      factors.removeFirst();
+      if (minFactorsLength == 0)
+        minFactorsLength= factors.length();
+      else
+        minFactorsLength= tmin (minFactorsLength, factors.length());
+
+      if (factors.length() == 1)
+      {
+        irred= true;
+        return;
+      }
+      sortList (factors, x);
+      Aeval [j]= factors;
+    }
+  }
+}
+
+CFList conv (const CFArray & A)
+{
+  CFList result;
+  for (int i= A.max(); i >= A.min(); i--)
+    result.insert (A[i]);
+  return result;
+}
+
+
+void getLeadingCoeffs (const CanonicalForm& A, CFList*& Aeval
+                      )
+{
+  CFListIterator iter;
+  CFList LCs;
+  for (int j= 0; j < A.level() - 2; j++)
+  {
+    if (!Aeval[j].isEmpty())
+    {
+      LCs= CFList();
+      for (iter= Aeval[j]; iter.hasItem(); iter++)
+        LCs.append (LC (iter.getItem(), 1));
+      //normalize (LCs);
+      Aeval[j]= LCs;
+    }
+  }
+}
+
+void sortByUniFactors (CFList*& Aeval, int AevalLength,
+                       CFList& uniFactors, CFList& biFactors,
+                       const CFList& evaluation
+                      )
+{
+  CanonicalForm evalPoint;
+  int i;
+  CFListIterator iter, iter2;
+  Variable v;
+  CFList LCs, buf;
+  CFArray l;
+  int pos, index, checklength;
+  bool leaveLoop=false;
+recurse:
+  for (int j= 0; j < AevalLength; j++)
+  {
+    if (!Aeval[j].isEmpty())
+    {
+      i= evaluation.length() + 1;
+      for (iter= evaluation; iter.hasItem(); iter++, i--)
+      {
+        for (iter2= Aeval[j]; iter2.hasItem(); iter2++)
+        {
+          if (i == iter2.getItem().level())
+          {
+            evalPoint= iter.getItem();
+            leaveLoop= true;
+            break;
+          }
+        }
+        if (leaveLoop)
+        {
+          leaveLoop= false;
+          break;
+        }
+      }
+
+      v= Variable (i);
+      if (Aeval[j].length() > uniFactors.length())
+        Aeval[j]= recombination (Aeval[j], uniFactors, 1,
+                                 Aeval[j].length() - uniFactors.length() + 1,
+                                 evalPoint, v);
+
+      checklength= biFactors.length();
+      Aeval[j]= checkOneToOne (Aeval[j], uniFactors, biFactors, evalPoint, v);
+      if (checklength > biFactors.length())
+      {
+        uniFactors= buildUniFactors (biFactors, evaluation.getLast(),
+                                     Variable (2));
+        goto recurse;
+      }
+
+      buf= buildUniFactors (Aeval[j], evalPoint, v);
+      l= CFArray (uniFactors.length());
+      index= 1;
+      for (iter= buf; iter.hasItem(); iter++, index++)
+      {
+        pos= findItem (uniFactors, iter.getItem());
+        if (pos)
+          l[pos-1]= getItem (Aeval[j], index);
+      }
+      buf= conv (l);
+      Aeval [j]= buf;
+
+      buf= buildUniFactors (Aeval[j], evalPoint, v);
+    }
+  }
+}
+
+CFList
+buildUniFactors (const CFList& biFactors, const CanonicalForm& evalPoint,
+                 const Variable& y)
+{
+  CFList result;
+  CanonicalForm tmp;
+  for (CFListIterator i= biFactors; i.hasItem(); i++)
+  {
+    tmp= mod (i.getItem(), y - evalPoint);
+    tmp /= Lc (tmp);
+    result.append (tmp);
+  }
+  return result;
+}
+
+void refineBiFactors (const CanonicalForm& A, CFList& biFactors,
+                      CFList* const& Aeval, const CFList& evaluation,
+                      int minFactorsLength)
+{
+  CFListIterator iter, iter2;
+  CanonicalForm evalPoint;
+  int i;
+  Variable v;
+  Variable y= Variable (2);
+  CFList list;
+  bool leaveLoop= false;
+  for (int j= 0; j < A.level() - 2; j++)
+  {
+    if (Aeval[j].length() == minFactorsLength)
+    {
+      i= A.level();
+
+      for (iter= evaluation; iter.hasItem(); iter++, i--)
+      {
+        for (iter2= Aeval[j]; iter2.hasItem(); iter2++)
+        {
+          if (i == iter2.getItem().level())
+          {
+            evalPoint= iter.getItem();
+            leaveLoop= true;
+            break;
+          }
+        }
+        if (leaveLoop)
+        {
+          leaveLoop= false;
+          break;
+        }
+      }
+
+      v= Variable (i);
+      list= buildUniFactors (Aeval[j], evalPoint, v);
+
+      biFactors= recombination (biFactors, list, 1,
+                                biFactors.length() - list.length() + 1,
+                                evaluation.getLast(), y);
+      return;
+    }
+  }
+}
+
+void
+prepareLeadingCoeffs (CFList*& LCs, CanonicalForm& A, CFList& Aeval, int n,
+                      const CFList& leadingCoeffs, const CFList& biFactors,
+                      const CFList& evaluation)
+{
+  CFList l= leadingCoeffs;
+  LCs [n-3]= l;
+  CFListIterator j;
+  CFListIterator iter= evaluation;
+  for (int i= n - 1; i > 2; i--, iter++)
+  {
+    for (j= l; j.hasItem(); j++)
+      j.getItem()= j.getItem() (iter.getItem(), i + 1);
+    LCs [i - 3]= l;
+  }
+  l= LCs [0];
+  for (CFListIterator i= l; i.hasItem(); i++)
+    i.getItem()= i.getItem() (iter.getItem(), 3);
+  CFListIterator ii= biFactors;
+  CFList normalizeFactor;
+  for (CFListIterator i= l; i.hasItem(); i++, ii++)
+    normalizeFactor.append (Lc (LC (ii.getItem(), 1))/Lc (i.getItem()));
+  for (int i= 0; i < n-2; i++)
+  {
+    ii= normalizeFactor;
+    for (j= LCs [i]; j.hasItem(); j++, ii++)
+      j.getItem() *= ii.getItem();
+  }
+
+  Aeval= evaluateAtEval (A, evaluation, 2);
+
+  CanonicalForm hh= 1/Lc (Aeval.getFirst());
+
+  for (iter= Aeval; iter.hasItem(); iter++)
+    iter.getItem() *= hh;
+
+  A *= hh;
+}
+
+CFList
+extNonMonicFactorRecombination (const CFList& factors, const CanonicalForm& F,
+                                const ExtensionInfo& info)
+{
+  Variable alpha= info.getAlpha();
+  Variable beta= info.getBeta();
+  CanonicalForm gamma= info.getGamma();
+  CanonicalForm delta= info.getDelta();
+  int k= info.getGFDegree();
+  CFList source, dest;
+
+  int degMipoBeta= 1;
+  if (!k && beta != Variable(1))
+    degMipoBeta= degree (getMipo (beta));
+
+  CFList T, S;
+  T= factors;
+  int s= 1;
+  CFList result;
+  CanonicalForm quot, buf= F;
+
+  CanonicalForm g;
+  CanonicalForm buf2;
+  int * v= new int [T.length()];
+  for (int i= 0; i < T.length(); i++)
+    v[i]= 0;
+  bool noSubset= false;
+  CFArray TT;
+  TT= copy (factors);
+  bool recombination= false;
+  bool trueFactor= false;
+  while (T.length() >= 2*s)
+  {
+    while (noSubset == false)
+    {
+      if (T.length() == s)
+      {
+        delete [] v;
+        if (recombination)
+        {
+          g= prod (T);
+          T.removeFirst();
+          g /= myContent (g);
+          g /= Lc (g);
+          appendTestMapDown (result, g, info, source, dest);
+          return result;
+        }
+        else
+          return CFList (buf/myContent(buf));
+      }
+
+      S= subset (v, s, TT, noSubset);
+      if (noSubset) break;
+
+      g= prod (S);
+      g /= myContent (g);
+      if (fdivides (g, buf, quot))
+      {
+        buf2= g;
+        buf2 /= Lc (buf2);
+        if (!k && beta.level() == 1)
+        {
+          if (degree (buf2, alpha) < degMipoBeta)
+          {
+            appendTestMapDown (result, buf2, info, source, dest);
+            buf= quot;
+            recombination= true;
+            trueFactor= true;
+          }
+        }
+        else
+        {
+          if (!isInExtension (buf2, gamma, k, delta, source, dest))
+          {
+            appendTestMapDown (result, buf2, info, source, dest);
+            buf= quot;
+            recombination= true;
+            trueFactor= true;
+          }
+        }
+        if (trueFactor)
+        {
+          T= Difference (T, S);
+
+          if (T.length() < 2*s || T.length() == s)
+          {
+            delete [] v;
+            buf /= myContent (buf);
+            buf /= Lc (buf);
+            appendTestMapDown (result, buf, info, source, dest);
+            return result;
+          }
+          trueFactor= false;
+          TT= copy (T);
+          indexUpdate (v, s, T.length(), noSubset);
+          if (noSubset) break;
+        }
+      }
+    }
+    s++;
+    if (T.length() < 2*s || T.length() == s)
+    {
+      delete [] v;
+      buf /= myContent (buf);
+      buf /= Lc (buf);
+      appendTestMapDown (result, buf, info, source, dest);
+      return result;
+    }
+    for (int i= 0; i < T.length(); i++)
+      v[i]= 0;
+    noSubset= false;
+  }
+  if (T.length() < 2*s)
+  {
+    buf= F/myContent (F);
+    buf /= Lc (buf);
+    appendMapDown (result, buf, info, source, dest);
+  }
+
+  delete [] v;
+  return result;
+}
+
+void
+changeSecondVariable (CanonicalForm& A, CFList& biFactors, CFList& evaluation,
+                      CFList*& oldAeval, int lengthAeval2,
+                      const CFList& uniFactors, const Variable& w)
+{
+  Variable y= Variable (2);
+  A= swapvar (A, y, w);
+  int i= A.level();
+  CanonicalForm evalPoint;
+  for (CFListIterator iter= evaluation; iter.hasItem(); iter++, i--)
+  {
+    if (i == w.level())
+    {
+      evalPoint= iter.getItem();
+      iter.getItem()= evaluation.getLast();
+      evaluation.removeLast();
+      evaluation.append (evalPoint);
+      break;
+    }
+  }
+  for (i= 0; i < lengthAeval2; i++)
+  {
+    if (oldAeval[i].isEmpty())
+      continue;
+    if (oldAeval[i].getFirst().level() == w.level())
+    {
+      CFArray tmp= copy (oldAeval[i]);
+      oldAeval[i]= biFactors;
+      for (CFListIterator iter= oldAeval[i]; iter.hasItem(); iter++)
+        iter.getItem()= swapvar (iter.getItem(), w, y);
+      for (int ii= 0; ii < tmp.size(); ii++)
+        tmp[ii]= swapvar (tmp[ii], w, y);
+      CFArray tmp2= CFArray (tmp.size());
+      CanonicalForm buf;
+      for (int ii= 0; ii < tmp.size(); ii++)
+      {
+        buf= tmp[ii] (evaluation.getLast(),y);
+        buf /= Lc (buf);
+        tmp2[findItem (uniFactors, buf)-1]=tmp[ii];
+      }
+      biFactors= CFList();
+      for (int j= 0; j < tmp2.size(); j++)
+        biFactors.append (tmp2[j]);
+    }
+  }
+}
+
+void
+distributeLCmultiplier (CanonicalForm& A, CFList& leadingCoeffs,
+                        CFList& biFactors, const CFList& evaluation,
+                        const CanonicalForm& LCmultipler)
+{
+  CanonicalForm tmp= power (LCmultipler, biFactors.length() - 1);
+  A *= tmp;
+  tmp= LCmultipler;
+  CFListIterator iter= leadingCoeffs;
+  for (;iter.hasItem(); iter++)
+    iter.getItem() *= LCmultipler;
+  iter= evaluation;
+  for (int i= A.level(); i > 2; i--, iter++)
+    tmp= tmp (iter.getItem(), i);
+  if (!tmp.inCoeffDomain())
+  {
+    for (CFListIterator i= biFactors; i.hasItem(); i++)
+    {
+      i.getItem() *= tmp/LC (i.getItem(), 1);
+      i.getItem() /= Lc (i.getItem());
+    }
+  }
+}
+
+void
+LCHeuristic (CanonicalForm& A, const CanonicalForm& LCmultiplier,
+             CFList& biFactors, CFList*& leadingCoeffs, const CFList* oldAeval,
+             int lengthAeval, const CFList& evaluation,
+             const CFList& oldBiFactors)
+{
+  CFListIterator iter, iter2;
+  int index;
+  Variable xx;
+  CFList vars1;
+  CFFList sqrfMultiplier= sqrFree (LCmultiplier);
+  if (sqrfMultiplier.getFirst().factor().inCoeffDomain())
+    sqrfMultiplier.removeFirst();
+  sqrfMultiplier= sortCFFListByNumOfVars (sqrfMultiplier);
+  xx= Variable (2);
+  for (iter= oldBiFactors; iter.hasItem(); iter++)
+    vars1.append (power (xx, degree (LC (iter.getItem(),1), xx)));
+  for (int i= 0; i < lengthAeval; i++)
+  {
+    if (oldAeval[i].isEmpty())
+      continue;
+    xx= oldAeval[i].getFirst().mvar();
+    iter2= vars1;
+    for (iter= oldAeval[i]; iter.hasItem(); iter++, iter2++)
+      iter2.getItem() *= power (xx, degree (LC (iter.getItem(),1), xx));
+  }
+  CanonicalForm tmp, quot1, quot2, quot3;
+  iter2= vars1;
+  for (iter= leadingCoeffs[lengthAeval-1]; iter.hasItem(); iter++, iter2++)
+  {
+    tmp= iter.getItem()/LCmultiplier;
+    for (int i=1; i <= tmp.level(); i++)
+    {
+      if (degree (tmp,i) > 0 && (degree (iter2.getItem(),i) > degree (tmp,i)))
+        iter2.getItem() /= power (Variable (i), degree (tmp,i));
+    }
+  }
+  int multi;
+  for (CFFListIterator ii= sqrfMultiplier; ii.hasItem(); ii++)
+  {
+    multi= 0;
+    for (iter= vars1; iter.hasItem(); iter++)
+    {
+      tmp= iter.getItem();
+      while (fdivides (myGetVars (ii.getItem().factor()), tmp))
+      {
+        multi++;
+        tmp /= myGetVars (ii.getItem().factor());
+      }
+    }
+    if (multi == ii.getItem().exp())
+    {
+      index= 1;
+      for (iter= vars1; iter.hasItem(); iter++, index++)
+      {
+        while (fdivides (myGetVars (ii.getItem().factor()), iter.getItem()))
+        {
+          int index2= 1;
+          for (iter2= leadingCoeffs[lengthAeval-1]; iter2.hasItem();iter2++,
+                                                                    index2++)
+          {
+            if (index2 == index)
+              continue;
+            else
+            {
+              tmp= ii.getItem().factor();
+              if (fdivides (tmp, iter2.getItem(), quot1))
+              {
+                CFListIterator iter3= evaluation;
+                for (int jj= A.level(); jj > 2; jj--, iter3++)
+                  tmp= tmp (iter3.getItem(), jj);
+                if (!tmp.inCoeffDomain())
+                {
+                  int index3= 1;
+                  for (iter3= biFactors; iter3.hasItem(); iter3++, index3++)
+                  {
+                    if (index3 == index2)
+                    {
+                      if (fdivides (tmp, iter3.getItem(), quot2))
+                      {
+                        if (fdivides (ii.getItem().factor(), A, quot3))
+                        {
+                          A               = quot3;
+                          iter2.getItem() = quot2;
+                          iter3.getItem() = quot3;
+                          iter3.getItem() /= Lc (iter3.getItem());
+                          break;
+                        }
+                      }
+                    }
+                  }
+                }
+              }
+            }
+          }
+          iter.getItem() /= getVars (ii.getItem().factor());
+        }
+      }
+    }
+    else
+    {
+      index= 1;
+      for (iter= vars1; iter.hasItem(); iter++, index++)
+      {
+        if (!fdivides (myGetVars (ii.getItem().factor()), iter.getItem()))
+        {
+          int index2= 1;
+          for (iter2= leadingCoeffs[lengthAeval-1];iter2.hasItem();iter2++,
+                                                                    index2++)
+          {
+            if (index2 == index)
+            {
+              tmp= power (ii.getItem().factor(), ii.getItem().exp());
+              if (fdivides (tmp, A, quot1))
+              {
+                if (fdivides (tmp, iter2.getItem()))
+                {
+                  CFListIterator iter3= evaluation;
+                  for (int jj= A.level(); jj > 2; jj--, iter3++)
+                    tmp= tmp (iter3.getItem(), jj);
+                  if (!tmp.inCoeffDomain())
+                  {
+                    int index3= 1;
+                    for (iter3= biFactors; iter3.hasItem(); iter3++, index3++)
+                    {
+                      if (index3 == index2)
+                      {
+                        if (fdivides (tmp, iter3.getItem(), quot3))
+                        {
+                          A               =  quot1;
+                          iter2.getItem() =  quot2;
+                          iter3.getItem() =  quot3;
+                          iter3.getItem() /= Lc (iter3.getItem());
+                          break;
+                        }
+                      }
+                    }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+}
+
+void
+LCHeuristicCheck (const CFList& LCs, const CFList& contents, CanonicalForm& A,
+                  const CanonicalForm& oldA, CFList& leadingCoeffs,
+                  bool& foundTrueMultiplier)
+{
+  CanonicalForm pLCs= prod (LCs);
+  if (fdivides (pLCs, LC (oldA,1)) && (LC(oldA,1)/pLCs).inCoeffDomain()) // check if the product of the lead coeffs of the primitive factors equals the lead coeff of the old A
+  {
+    A= oldA;
+    CFListIterator iter2= leadingCoeffs;
+    for (CFListIterator iter= contents; iter.hasItem(); iter++, iter2++)
+      iter2.getItem() /= iter.getItem();
+    foundTrueMultiplier= true;
+  }
+}
+
+void
+LCHeuristic2 (const CanonicalForm& LCmultiplier, const CFList& factors,
+              CFList& leadingCoeffs, CFList& contents, CFList& LCs,
+              bool& foundTrueMultiplier)
+{
+  CanonicalForm cont;
+  int index= 1;
+  CFListIterator iter2;
+  for (CFListIterator iter= factors; iter.hasItem(); iter++, index++)
+  {
+    cont= content (iter.getItem(), 1);
+    cont= gcd (cont, LCmultiplier);
+    contents.append (cont);
+    if (cont.inCoeffDomain()) // trivial content->LCmultiplier needs to go there
+    {
+      foundTrueMultiplier= true;
+      int index2= 1;
+      for (iter2= leadingCoeffs; iter2.hasItem(); iter2++, index2++)
+      {
+        if (index2 == index)
+          continue;
+        iter2.getItem() /= LCmultiplier;
+      }
+      break;
+    }
+    else
+      LCs.append (LC (iter.getItem()/cont, 1));
+  }
+}
+
+void
+LCHeuristic3 (const CanonicalForm& LCmultiplier, const CFList& factors,
+              const CFList& oldBiFactors, const CFList& contents,
+              const CFList* oldAeval, CanonicalForm& A, CFList*& leadingCoeffs,
+              int lengthAeval, bool& foundMultiplier)
+{
+  int index= 1;
+  CFListIterator iter, iter2= factors;
+  for (iter= contents; iter.hasItem(); iter++, iter2++, index++)
+  {
+    if (fdivides (iter.getItem(), LCmultiplier))
+    {
+      if ((LCmultiplier/iter.getItem()).inCoeffDomain() &&
+          !isOnlyLeadingCoeff(iter2.getItem())) //content divides LCmultiplier completely and factor consists of more terms than just the leading coeff
+      {
+        Variable xx= Variable (2);
+        CanonicalForm vars;
+        vars= power (xx, degree (LC (getItem(oldBiFactors, index),1),
+                                  xx));
+        for (int i= 0; i < lengthAeval; i++)
+        {
+          if (oldAeval[i].isEmpty())
+            continue;
+          xx= oldAeval[i].getFirst().mvar();
+          vars *= power (xx, degree (LC (getItem(oldAeval[i], index),1),
+                                      xx));
+        }
+        if (vars.level() <= 2)
+        {
+          int index2= 1;
+          for (CFListIterator iter3= leadingCoeffs[lengthAeval-1];
+                iter3.hasItem(); iter3++, index2++)
+          {
+            if (index2 == index)
+            {
+              iter3.getItem() /= LCmultiplier;
+              break;
+            }
+          }
+          A /= LCmultiplier;
+          foundMultiplier= true;
+          iter.getItem()= 1;
+        }
+      }
+    }
+  }
+}
+
+void
+LCHeuristic4 (const CFList& oldBiFactors, const CFList* oldAeval,
+              const CFList& contents, const CFList& factors,
+              const CanonicalForm& testVars, int lengthAeval,
+              CFList*& leadingCoeffs, CanonicalForm& A,
+              CanonicalForm& LCmultiplier, bool& foundMultiplier)
+{
+  int index=1;
+  CFListIterator iter, iter2= factors;
+  for (iter= contents; iter.hasItem(); iter++, iter2++, index++)
+  {
+    if (!iter.getItem().isOne() &&
+        fdivides (iter.getItem(), LCmultiplier))
+    {
+      if (!isOnlyLeadingCoeff (iter2.getItem())) // factor is more than just leading coeff
+      {
+        int index2= 1;
+        for (iter2= leadingCoeffs[lengthAeval-1]; iter2.hasItem();
+              iter2++, index2++)
+        {
+          if (index2 == index)
+          {
+            iter2.getItem() /= iter.getItem();
+            foundMultiplier= true;
+            break;
+          }
+        }
+        A /= iter.getItem();
+        LCmultiplier /= iter.getItem();
+        iter.getItem()= 1;
+      }
+      else if (fdivides (getVars (LCmultiplier), testVars))//factor consists of just leading coeff
+      {
+        Variable xx= Variable (2);
+        CanonicalForm vars;
+        vars= power (xx, degree (LC (getItem(oldBiFactors, index),1),
+                                  xx));
+        for (int i= 0; i < lengthAeval; i++)
+        {
+          if (oldAeval[i].isEmpty())
+            continue;
+          xx= oldAeval[i].getFirst().mvar();
+          vars *= power (xx, degree (LC (getItem(oldAeval[i], index),1),
+                                      xx));
+        }
+        if (myGetVars(content(getItem(leadingCoeffs[lengthAeval-1],index),1))
+            /myGetVars (LCmultiplier) == vars)
+        {
+          int index2= 1;
+          for (iter2= leadingCoeffs[lengthAeval-1]; iter2.hasItem();
+                iter2++, index2++)
+          {
+            if (index2 == index)
+            {
+              iter2.getItem() /= LCmultiplier;
+              foundMultiplier= true;
+              break;
+            }
+          }
+          A /= LCmultiplier;
+          iter.getItem()= 1;
+        }
+      }
+    }
+  }
+}
+
+CFList
+extFactorize (const CanonicalForm& F, const ExtensionInfo& info);
+
+CFList
+multiFactorize (const CanonicalForm& F, const ExtensionInfo& info)
+{
+  if (F.inCoeffDomain())
+    return CFList (F);
+
+  TIMING_START (fac_fq_preprocess_and_content);
+  // compress and find main Variable
+  CFMap N;
+  TIMING_START (fac_fq_compress)
+  CanonicalForm A= myCompress (F, N);
+  TIMING_END_AND_PRINT (fac_fq_compress, "time to compress poly over Fq: ")
+
+  A /= Lc (A); // make monic
+
+  Variable alpha= info.getAlpha();
+  Variable beta= info.getBeta();
+  CanonicalForm gamma= info.getGamma();
+  CanonicalForm delta= info.getDelta();
+  bool extension= info.isInExtension();
+  bool GF= (CFFactory::gettype() == GaloisFieldDomain);
+  //univariate case
+  if (F.isUnivariate())
+  {
+    if (extension == false)
+      return uniFactorizer (F, alpha, GF);
+    else
+    {
+      CFList source, dest;
+      A= mapDown (F, info, source, dest);
+      return uniFactorizer (A, beta, GF);
+    }
+  }
+
+  //bivariate case
+  if (A.level() == 2)
+  {
+    CFList buf= biSqrfFactorizeHelper (F, info);
+    if (buf.getFirst().inCoeffDomain())
+      buf.removeFirst();
+    return buf;
+  }
+
+  Variable x= Variable (1);
+  Variable y= Variable (2);
+
+  // remove content
+  TIMING_START (fac_fq_content);
+  CFList contentAi;
+  CanonicalForm lcmCont= lcmContent (A, contentAi);
+  A /= lcmCont;
+  TIMING_END_AND_PRINT (fac_fq_content, "time to extract content over Fq: ");
+
+  // trivial after content removal
+  CFList contentAFactors;
+  if (A.inCoeffDomain())
+  {
+    for (CFListIterator i= contentAi; i.hasItem(); i++)
+    {
+      if (i.getItem().inCoeffDomain())
+        continue;
+      else
+      {
+        lcmCont /= i.getItem();
+        contentAFactors=
+        Union (multiFactorize (lcmCont, info),
+               multiFactorize (i.getItem(), info));
+        break;
+      }
+    }
+    decompress (contentAFactors, N);
+    if (!extension)
+      normalize (contentAFactors);
+    return contentAFactors;
+  }
+
+  // factorize content
+  TIMING_START (fac_fq_content);
+  contentAFactors= multiFactorize (lcmCont, info);
+  TIMING_END_AND_PRINT (fac_fq_content, "time to factor content over Fq: ");
+
+  // univariate after content removal
+  CFList factors;
+  if (A.isUnivariate ())
+  {
+    factors= uniFactorizer (A, alpha, GF);
+    append (factors, contentAFactors);
+    decompress (factors, N);
+    return factors;
+  }
+
+  // check main variable
+  TIMING_START (fac_fq_check_mainvar);
+  int swapLevel= 0;
+  CanonicalForm derivZ;
+  CanonicalForm gcdDerivZ;
+  CanonicalForm bufA= A;
+  Variable z;
+  for (int i= 1; i <= A.level(); i++)
+  {
+    z= Variable (i);
+    derivZ= deriv (bufA, z);
+    if (derivZ.isZero())
+    {
+      if (i == 1)
+        swapLevel= 1;
+      else
+        continue;
+    }
+    else
+    {
+      gcdDerivZ= gcd (bufA, derivZ);
+      if (degree (gcdDerivZ) > 0 && !derivZ.isZero())
+      {
+        CanonicalForm g= bufA/gcdDerivZ;
+        CFList factorsG=
+        Union (multiFactorize (g, info),
+               multiFactorize (gcdDerivZ, info));
+        appendSwapDecompress (factorsG, contentAFactors, N, swapLevel, x);
+        if (!extension)
+          normalize (factorsG);
+        return factorsG;
+      }
+      else
+      {
+        if (swapLevel == 1)
+        {
+          swapLevel= i;
+          bufA= swapvar (A, x, z);
+        }
+        A= bufA;
+        break;
+      }
+    }
+  }
+  TIMING_END_AND_PRINT (fac_fq_check_mainvar,
+                        "time to check main var over Fq: ");
+  TIMING_END_AND_PRINT (fac_fq_preprocess_and_content,
+                       "time to preprocess poly and extract content over Fq: ");
+
+  CFList Aeval, list, evaluation, bufEvaluation, bufAeval;
+  bool fail= false;
+  int swapLevel2= 0;
+  //int level;
+  int factorNums= 3;
+  CFList biFactors, bufBiFactors;
+  CanonicalForm evalPoly;
+  int lift, bufLift, lengthAeval2= A.level()-2;
+  double logarithm= (double) ilog2 (totaldegree (A));
+  logarithm /= log2exp;
+  logarithm= ceil (logarithm);
+  if (factorNums < (int) logarithm)
+    factorNums= (int) logarithm;
+  CFList* bufAeval2= new CFList [lengthAeval2];
+  CFList* Aeval2= new CFList [lengthAeval2];
+  int counter;
+  int differentSecondVar= 0;
+  // several bivariate factorizations
+  TIMING_START (fac_fq_bifactor_total);
+  for (int i= 0; i < factorNums; i++)
+  {
+    counter= 0;
+    bufA= A;
+    bufAeval= CFList();
+    TIMING_START (fac_fq_evaluation);
+    bufEvaluation= evalPoints (bufA, bufAeval, alpha, list, GF, fail);
+    TIMING_END_AND_PRINT (fac_fq_evaluation,
+                          "time to find evaluation point over Fq: ");
+    evalPoly= 0;
+
+    if (fail && (i == 0))
+    {
+      /*if (!swapLevel) //uncomment to reenable search for new main variable
+        level= 2;
+      else
+        level= swapLevel + 1;*/
+
+      //CanonicalForm g;
+      //swapLevel2= newMainVariableSearch (A, Aeval, evaluation, alpha, level, g);
+
+      /*if (!swapLevel2) // need to pass to an extension
+      {*/
+        factors= extFactorize (A, info);
+        appendSwapDecompress (factors, contentAFactors, N, swapLevel, x);
+        normalize (factors);
+        delete [] bufAeval2;
+        delete [] Aeval2;
+        return factors;
+      /*}
+      else
+      {
+        if (swapLevel2 == -1)
+        {
+          CFList factorsG=
+          Union (multiFactorize (g, info),
+                 multiFactorize (A/g, info));
+          appendSwapDecompress (factorsG, contentAFactors, N, swapLevel, x);
+          if (!extension)
+            normalize (factorsG);
+          delete [] bufAeval2;
+          delete [] Aeval2;
+          return factorsG;
+        }
+        fail= false;
+        bufAeval= Aeval;
+        bufA= A;
+        bufEvaluation= evaluation;
+      }*/ //end uncomment
+    }
+    else if (fail && (i > 0))
+      break;
+
+    TIMING_START (fac_fq_evaluation);
+    evaluationWRTDifferentSecondVars (bufAeval2, bufEvaluation, A);
+    TIMING_END_AND_PRINT (fac_fq_evaluation,
+                          "time for evaluation wrt diff second vars over Fq: ");
+
+    for (int j= 0; j < lengthAeval2; j++)
+    {
+      if (!bufAeval2[j].isEmpty())
+        counter++;
+    }
+
+    bufLift= degree (A, y) + 1 + degree (LC(A, x), y);
+
+    TIMING_START (fac_fq_bi_factorizer);
+    if (!GF && alpha.level() == 1)
+      bufBiFactors= FpBiSqrfFactorize (bufAeval.getFirst());
+    else if (GF)
+      bufBiFactors= GFBiSqrfFactorize (bufAeval.getFirst());
+    else
+      bufBiFactors= FqBiSqrfFactorize (bufAeval.getFirst(), alpha);
+    TIMING_END_AND_PRINT (fac_fq_bi_factorizer,
+                          "time for bivariate factorization: ");
+    bufBiFactors.removeFirst();
+
+    if (bufBiFactors.length() == 1)
+    {
+      if (extension)
+      {
+        CFList source, dest;
+        A= mapDown (A, info, source, dest);
+      }
+      factors.append (A);
+      appendSwapDecompress (factors, contentAFactors, N, swapLevel,
+                            swapLevel2, x);
+      if (!extension)
+        normalize (factors);
+      delete [] bufAeval2;
+      delete [] Aeval2;
+      return factors;
+    }
+
+    if (i == 0)
+    {
+      Aeval= bufAeval;
+      evaluation= bufEvaluation;
+      biFactors= bufBiFactors;
+      lift= bufLift;
+      for (int j= 0; j < lengthAeval2; j++)
+        Aeval2 [j]= bufAeval2 [j];
+      differentSecondVar= counter;
+    }
+    else
+    {
+      if (bufBiFactors.length() < biFactors.length() ||
+          ((bufLift < lift) && (bufBiFactors.length() == biFactors.length())) ||
+          counter > differentSecondVar)
+      {
+        Aeval= bufAeval;
+        evaluation= bufEvaluation;
+        biFactors= bufBiFactors;
+        lift= bufLift;
+        for (int j= 0; j < lengthAeval2; j++)
+          Aeval2 [j]= bufAeval2 [j];
+        differentSecondVar= counter;
+      }
+    }
+    int k= 0;
+    for (CFListIterator j= bufEvaluation; j.hasItem(); j++, k++)
+      evalPoly += j.getItem()*power (x, k);
+    list.append (evalPoly);
+  }
+
+  delete [] bufAeval2;
+
+  sortList (biFactors, x);
+
+  int minFactorsLength;
+  bool irred= false;
+  TIMING_START (fac_fq_bi_factorizer);
+  factorizationWRTDifferentSecondVars (A, Aeval2, info, minFactorsLength,irred);
+  TIMING_END_AND_PRINT (fac_fq_bi_factorizer,
+             "time for bivariate factorization wrt diff second vars over Fq: ");
+
+  TIMING_END_AND_PRINT (fac_fq_bifactor_total,
+                        "total time for eval and bivar factors over Fq: ");
+  if (irred)
+  {
+    if (extension)
+    {
+      CFList source, dest;
+      A= mapDown (A, info, source, dest);
+    }
+    factors.append (A);
+    appendSwapDecompress (factors, contentAFactors, N, swapLevel,
+                          swapLevel2, x);
+    if (!extension)
+      normalize (factors);
+    delete [] Aeval2;
+    return factors;
+  }
+
+  if (minFactorsLength == 0)
+    minFactorsLength= biFactors.length();
+  else if (biFactors.length() > minFactorsLength)
+    refineBiFactors (A, biFactors, Aeval2, evaluation, minFactorsLength);
+  minFactorsLength= tmin (minFactorsLength, biFactors.length());
+
+  CFList uniFactors= buildUniFactors (biFactors, evaluation.getLast(), y);
+
+  sortByUniFactors (Aeval2, lengthAeval2, uniFactors, biFactors, evaluation);
+
+  minFactorsLength= tmin (minFactorsLength, biFactors.length());
+
+  if (minFactorsLength == 1)
+  {
+    if (extension)
+    {
+      CFList source, dest;
+      A= mapDown (A, info, source, dest);
+    }
+    factors.append (A);
+    appendSwapDecompress (factors, contentAFactors, N, swapLevel,
+                          swapLevel2, x);
+    if (!extension)
+      normalize (factors);
+    delete [] Aeval2;
+    return factors;
+  }
+
+  if (differentSecondVar == lengthAeval2)
+  {
+    bool zeroOccured= false;
+    for (CFListIterator iter= evaluation; iter.hasItem(); iter++)
+    {
+      if (iter.getItem().isZero())
+      {
+        zeroOccured= true;
+        break;
+      }
+    }
+    if (!zeroOccured)
+    {
+      factors= sparseHeuristic (A, biFactors, Aeval2, evaluation,
+                                minFactorsLength);
+      if (factors.length() == biFactors.length())
+      {
+        if (extension)
+          factors= extNonMonicFactorRecombination (factors, A, info);
+
+        appendSwapDecompress (factors, contentAFactors, N, swapLevel,
+                              swapLevel2, x);
+        if (!extension)
+          normalize (factors);
+        delete [] Aeval2;
+        return factors;
+      }
+      else
+        factors= CFList();
+      //TODO case where factors.length() > 0
+    }
+  }
+
+  CFList * oldAeval= new CFList [lengthAeval2]; //TODO use bufAeval2 for this
+  for (int i= 0; i < lengthAeval2; i++)
+    oldAeval[i]= Aeval2[i];
+
+  getLeadingCoeffs (A, Aeval2);
+
+  CFList biFactorsLCs;
+  for (CFListIterator i= biFactors; i.hasItem(); i++)
+    biFactorsLCs.append (LC (i.getItem(), 1));
+
+  Variable v;
+  TIMING_START (fac_fq_precompute_leadcoeff);
+  CFList leadingCoeffs= precomputeLeadingCoeff (LC (A, 1), biFactorsLCs, alpha,
+                                          evaluation, Aeval2, lengthAeval2, v);
+
+  if (v.level() != 1)
+    changeSecondVariable (A, biFactors, evaluation, oldAeval, lengthAeval2,
+                          uniFactors, v);
+
+  CanonicalForm oldA= A;
+  CFList oldBiFactors= biFactors;
+
+  CanonicalForm LCmultiplier= leadingCoeffs.getFirst();
+  bool LCmultiplierIsConst= LCmultiplier.inCoeffDomain();
+  leadingCoeffs.removeFirst();
+
+  if (!LCmultiplierIsConst)
+    distributeLCmultiplier (A, leadingCoeffs, biFactors, evaluation, LCmultiplier);
+
+  //prepare leading coefficients
+  CFList* leadingCoeffs2= new CFList [lengthAeval2];
+  prepareLeadingCoeffs (leadingCoeffs2, A, Aeval, A.level(), leadingCoeffs,
+                        biFactors, evaluation);
+
+  CFListIterator iter;
+  CFList bufLeadingCoeffs2= leadingCoeffs2[lengthAeval2-1];
+  bufBiFactors= biFactors;
+  bufA= A;
+  CanonicalForm testVars, bufLCmultiplier= LCmultiplier;
+  if (!LCmultiplierIsConst)
+  {
+    testVars= Variable (2);
+    for (int i= 0; i < lengthAeval2; i++)
+    {
+      if (!oldAeval[i].isEmpty())
+        testVars *= oldAeval[i].getFirst().mvar();
+    }
+  }
+  TIMING_END_AND_PRINT(fac_fq_precompute_leadcoeff,
+                       "time to precompute LC over Fq: ");
+
+  TIMING_START (fac_fq_luckswang);
+  CFList bufFactors= CFList();
+  bool LCheuristic= false;
+  if (LucksWangSparseHeuristic (A, biFactors, 2, leadingCoeffs2[lengthAeval2-1],
+                                 factors))
+  {
+    int check= biFactors.length();
+    int * index= new int [factors.length()];
+    CFList oldFactors= factors;
+    factors= recoverFactors (A, factors, index);
+
+    if (check == factors.length())
+    {
+      if (extension)
+        factors= extNonMonicFactorRecombination (factors, bufA, info);
+
+      if (v.level() != 1)
+      {
+        for (iter= factors; iter.hasItem(); iter++)
+          iter.getItem()= swapvar (iter.getItem(), v, y);
+      }
+
+      appendSwapDecompress (factors, contentAFactors, N, swapLevel,
+                            swapLevel2, x);
+      if (!extension)
+        normalize (factors);
+      delete [] index;
+      delete [] Aeval2;
+      TIMING_END_AND_PRINT (fac_fq_luckswang,
+                            "time for successful LucksWang over Fq: ");
+      return factors;
+    }
+    else if (factors.length() > 0)
+    {
+      int oneCount= 0;
+      CFList l;
+      for (int i= 0; i < check; i++)
+      {
+        if (index[i] == 1)
+        {
+          iter=biFactors;
+          for (int j=1; j <= i-oneCount; j++)
+            iter++;
+          iter.remove (1);
+          for (int j= 0; j < lengthAeval2; j++)
+          {
+            l= leadingCoeffs2[j];
+            iter= l;
+            for (int k=1; k <= i-oneCount; k++)
+              iter++;
+            iter.remove (1);
+            leadingCoeffs2[j]=l;
+          }
+          oneCount++;
+        }
+      }
+      bufFactors= factors;
+      factors= CFList();
+    }
+    else if (!LCmultiplierIsConst && factors.length() == 0)
+    {
+      LCheuristic= true;
+      factors= oldFactors;
+      CFList contents, LCs;
+      bool foundTrueMultiplier= false;
+      LCHeuristic2 (LCmultiplier, factors, leadingCoeffs2[lengthAeval2-1],
+                    contents, LCs, foundTrueMultiplier);
+      if (foundTrueMultiplier)
+      {
+          A= oldA;
+          leadingCoeffs= leadingCoeffs2[lengthAeval2-1];
+          for (int i= lengthAeval2-1; i > -1; i--)
+            leadingCoeffs2[i]= CFList();
+          prepareLeadingCoeffs (leadingCoeffs2, A, Aeval, A.level(),
+                                leadingCoeffs, biFactors, evaluation);
+      }
+      else
+      {
+        bool foundMultiplier= false;
+        LCHeuristic3 (LCmultiplier, factors, oldBiFactors, contents, oldAeval,
+                      A, leadingCoeffs2, lengthAeval2, foundMultiplier);
+
+        // coming from above: divide out more LCmultiplier if possible
+        if (foundMultiplier)
+        {
+          foundMultiplier= false;
+          LCHeuristic4 (oldBiFactors, oldAeval, contents, factors, testVars,
+                        lengthAeval2, leadingCoeffs2, A, LCmultiplier,
+                        foundMultiplier);
+        }
+        else
+        {
+          LCHeuristicCheck (LCs, contents, A, oldA,
+                            leadingCoeffs2[lengthAeval2-1], foundMultiplier);
+          if (!foundMultiplier && fdivides (getVars (LCmultiplier), testVars))
+          {
+            LCHeuristic (A, LCmultiplier, biFactors, leadingCoeffs2, oldAeval,
+                         lengthAeval2, evaluation, oldBiFactors);
+          }
+        }
+
+        // patch everything together again
+        leadingCoeffs= leadingCoeffs2[lengthAeval2-1];
+        for (int i= lengthAeval2-1; i > -1; i--)
+          leadingCoeffs2[i]= CFList();
+        prepareLeadingCoeffs (leadingCoeffs2, A, Aeval, A.level(),leadingCoeffs,
+                              biFactors, evaluation);
+      }
+      factors= CFList();
+      if (!fdivides (LC (oldA,1),prod (leadingCoeffs2[lengthAeval2-1])))
+      {
+        LCheuristic= false;
+        A= bufA;
+        biFactors= bufBiFactors;
+        leadingCoeffs2[lengthAeval2-1]= bufLeadingCoeffs2;
+        LCmultiplier= bufLCmultiplier;
+      }
+    }
+    else
+      factors= CFList();
+    delete [] index;
+  }
+  TIMING_END_AND_PRINT (fac_fq_luckswang, "time for LucksWang over Fq: ");
+
+  TIMING_START (fac_fq_lcheuristic);
+  if (!LCheuristic && !LCmultiplierIsConst && bufFactors.isEmpty()
+      && fdivides (getVars (LCmultiplier), testVars))
+  {
+    LCheuristic= true;
+    LCHeuristic (A, LCmultiplier, biFactors, leadingCoeffs2, oldAeval,
+                 lengthAeval2, evaluation, oldBiFactors);
+
+    leadingCoeffs= leadingCoeffs2[lengthAeval2-1];
+    for (int i= lengthAeval2-1; i > -1; i--)
+      leadingCoeffs2[i]= CFList();
+    prepareLeadingCoeffs (leadingCoeffs2, A, Aeval, A.level(),leadingCoeffs,
+                          biFactors, evaluation);
+
+    if (!fdivides (LC (oldA,1),prod (leadingCoeffs2[lengthAeval2-1])))
+    {
+      LCheuristic= false;
+      A= bufA;
+      biFactors= bufBiFactors;
+      leadingCoeffs2[lengthAeval2-1]= bufLeadingCoeffs2;
+      LCmultiplier= bufLCmultiplier;
+    }
+  }
+  TIMING_END_AND_PRINT (fac_fq_lcheuristic, "time for Lc heuristic over Fq: ");
+
+tryAgainWithoutHeu:
+  TIMING_START (fac_fq_shift_to_zero);
+  A= shift2Zero (A, Aeval, evaluation);
+
+  for (iter= biFactors; iter.hasItem(); iter++)
+    iter.getItem()= iter.getItem () (y + evaluation.getLast(), y);
+
+  for (int i= 0; i < lengthAeval2-1; i++)
+    leadingCoeffs2[i]= CFList();
+  for (iter= leadingCoeffs2[lengthAeval2-1]; iter.hasItem(); iter++)
+  {
+    iter.getItem()= shift2Zero (iter.getItem(), list, evaluation);
+    for (int i= A.level() - 4; i > -1; i--)
+    {
+      if (i + 1 == lengthAeval2-1)
+        leadingCoeffs2[i].append (iter.getItem() (0, i + 4));
+      else
+        leadingCoeffs2[i].append (leadingCoeffs2[i+1].getLast() (0, i + 4));
+    }
+  }
+  TIMING_END_AND_PRINT (fac_fq_shift_to_zero,
+                        "time to shift evaluation point to zero: ");
+
+  CFArray Pi;
+  CFList diophant;
+  int* liftBounds= new int [A.level() - 1];
+  int liftBoundsLength= A.level() - 1;
+  for (int i= 0; i < liftBoundsLength; i++)
+    liftBounds [i]= degree (A, i + 2) + 1;
+
+  Aeval.removeFirst();
+  bool noOneToOne= false;
+  TIMING_START (fac_fq_hensel_lift);
+  factors= nonMonicHenselLift (Aeval, biFactors, leadingCoeffs2, diophant,
+                               Pi, liftBounds, liftBoundsLength, noOneToOne);
+  TIMING_END_AND_PRINT (fac_fq_hensel_lift,
+                        "time for non monic hensel lifting over Fq: ");
+
+  if (!noOneToOne)
+  {
+    int check= factors.length();
+    A= oldA;
+    TIMING_START (fac_fq_recover_factors);
+    factors= recoverFactors (A, factors, evaluation);
+    TIMING_END_AND_PRINT (fac_fq_recover_factors,
+                          "time to recover factors over Fq: ");
+    if (check != factors.length())
+      noOneToOne= true;
+    else
+      factors= Union (factors, bufFactors);
+
+    if (extension && !noOneToOne)
+      factors= extNonMonicFactorRecombination (factors, A, info);
+  }
+  if (noOneToOne)
+  {
+    if (!LCmultiplierIsConst && LCheuristic)
+    {
+      A= bufA;
+      biFactors= bufBiFactors;
+      leadingCoeffs2[lengthAeval2-1]= bufLeadingCoeffs2;
+      delete [] liftBounds;
+      LCheuristic= false;
+      goto tryAgainWithoutHeu;
+      //something probably went wrong in the heuristic
+    }
+
+    A= shift2Zero (oldA, Aeval, evaluation);
+    biFactors= oldBiFactors;
+    for (iter= biFactors; iter.hasItem(); iter++)
+      iter.getItem()= iter.getItem () (y + evaluation.getLast(), y);
+    CanonicalForm LCA= LC (Aeval.getFirst(), 1);
+    CanonicalForm yToLift= power (y, lift);
+    CFListIterator i= biFactors;
+    lift= degree (i.getItem(), 2) + degree (LC (i.getItem(), 1)) + 1;
+    i++;
+
+    for (; i.hasItem(); i++)
+      lift= tmax (lift,
+                  degree (i.getItem(), 2) + degree (LC (i.getItem(), 1)) + 1);
+
+    lift= tmax (degree (Aeval.getFirst() , 2) + 1, lift);
+
+    i= biFactors;
+    yToLift= power (y, lift);
+    CanonicalForm dummy;
+    for (; i.hasItem(); i++)
+    {
+      LCA= LC (i.getItem(), 1);
+      extgcd (LCA, yToLift, LCA, dummy);
+      i.getItem()= mod (i.getItem()*LCA, yToLift);
+    }
+
+    liftBoundsLength= F.level() - 1;
+    liftBounds= liftingBounds (A, lift);
+
+    CFList MOD;
+    bool earlySuccess;
+    CFList earlyFactors, liftedFactors;
+    TIMING_START (fac_fq_hensel_lift);
+    liftedFactors= henselLiftAndEarly
+                   (A, MOD, liftBounds, earlySuccess, earlyFactors,
+                    Aeval, biFactors, evaluation, info);
+    TIMING_END_AND_PRINT (fac_fq_hensel_lift,
+                          "time for hensel lifting over Fq: ");
+
+    if (!extension)
+    {
+      TIMING_START (fac_fq_factor_recombination);
+      factors= factorRecombination (A, liftedFactors, MOD);
+      TIMING_END_AND_PRINT (fac_fq_factor_recombination,
+                            "time for factor recombination: ");
+    }
+    else
+    {
+      TIMING_START (fac_fq_factor_recombination);
+      factors= extFactorRecombination (liftedFactors, A, MOD, info, evaluation);
+      TIMING_END_AND_PRINT (fac_fq_factor_recombination,
+                            "time for factor recombination: ");
+    }
+
+    if (earlySuccess)
+      factors= Union (factors, earlyFactors);
+    if (!extension)
+    {
+      for (CFListIterator i= factors; i.hasItem(); i++)
+      {
+        int kk= Aeval.getLast().level();
+        for (CFListIterator j= evaluation; j.hasItem(); j++, kk--)
+        {
+          if (i.getItem().level() < kk)
+            continue;
+          i.getItem()= i.getItem() (Variable (kk) - j.getItem(), kk);
+        }
+      }
+    }
+  }
+
+  if (v.level() != 1)
+  {
+    for (CFListIterator iter= factors; iter.hasItem(); iter++)
+      iter.getItem()= swapvar (iter.getItem(), v, y);
+  }
+
+  swap (factors, swapLevel, swapLevel2, x);
+  append (factors, contentAFactors);
+  decompress (factors, N);
+  if (!extension)
+    normalize (factors);
+
+  delete[] liftBounds;
+
+  return factors;
+}
+
+/// multivariate factorization over an extension of the initial field
+CFList
+extFactorize (const CanonicalForm& F, const ExtensionInfo& info)
+{
+  CanonicalForm A= F;
+
+  Variable alpha= info.getAlpha();
+  Variable beta= info.getBeta();
+  int k= info.getGFDegree();
+  char cGFName= info.getGFName();
+  CanonicalForm delta= info.getDelta();
+  bool GF= (CFFactory::gettype() == GaloisFieldDomain);
+  Variable w= Variable (1);
+
+  CFList factors;
+  if (!GF && alpha == w)  // we are in F_p
+  {
+    CFList factors;
+    bool extension= true;
+    int p= getCharacteristic();
+    if (p < 7)
+    {
+      if (p == 2)
+        setCharacteristic (getCharacteristic(), 6, 'Z');
+      else if (p == 3)
+        setCharacteristic (getCharacteristic(), 4, 'Z');
+      else if (p == 5)
+        setCharacteristic (getCharacteristic(), 3, 'Z');
+      ExtensionInfo info= ExtensionInfo (extension);
+      A= A.mapinto();
+      factors= multiFactorize (A, info);
+
+      CanonicalForm mipo= gf_mipo;
+      setCharacteristic (getCharacteristic());
+      Variable vBuf= rootOf (mipo.mapinto());
+      for (CFListIterator j= factors; j.hasItem(); j++)
+        j.getItem()= GF2FalphaRep (j.getItem(), vBuf);
+      prune (vBuf);
+    }
+    else if (p >= 7 && p*p < (1<<16)) // pass to GF if possible
+    {
+      setCharacteristic (getCharacteristic(), 2, 'Z');
+      ExtensionInfo info= ExtensionInfo (extension);
+      A= A.mapinto();
+      factors= multiFactorize (A, info);
+
+      CanonicalForm mipo= gf_mipo;
+      setCharacteristic (getCharacteristic());
+      Variable vBuf= rootOf (mipo.mapinto());
+      for (CFListIterator j= factors; j.hasItem(); j++)
+        j.getItem()= GF2FalphaRep (j.getItem(), vBuf);
+      prune (vBuf);
+    }
+    else  // not able to pass to GF, pass to F_p(\alpha)
+    {
+      CanonicalForm mipo= randomIrredpoly (2, w);
+      Variable v= rootOf (mipo);
+      ExtensionInfo info= ExtensionInfo (v);
+      factors= multiFactorize (A, info);
+      prune (v);
+    }
+    return factors;
+  }
+  else if (!GF && (alpha != w)) // we are in F_p(\alpha)
+  {
+    if (k == 1) // need factorization over F_p
+    {
+      int extDeg= degree (getMipo (alpha));
+      extDeg++;
+      CanonicalForm mipo= randomIrredpoly (extDeg, w);
+      Variable v= rootOf (mipo);
+      ExtensionInfo info= ExtensionInfo (v);
+      factors= multiFactorize (A, info);
+      prune (v);
+    }
+    else
+    {
+      if (beta == w)
+      {
+        Variable v= chooseExtension (alpha, beta, k);
+        CanonicalForm primElem, imPrimElem;
+        bool primFail= false;
+        Variable vBuf;
+        primElem= primitiveElement (alpha, vBuf, primFail);
+        ASSERT (!primFail, "failure in integer factorizer");
+        if (primFail)
+          ; //ERROR
+        else
+          imPrimElem= mapPrimElem (primElem, alpha, v);
+
+        CFList source, dest;
+        CanonicalForm bufA= mapUp (A, alpha, v, primElem, imPrimElem,
+                                   source, dest);
+        ExtensionInfo info= ExtensionInfo (v, alpha, imPrimElem, primElem);
+        factors= multiFactorize (bufA, info);
+        prune (v);
+      }
+      else
+      {
+        Variable v= chooseExtension (alpha, beta, k);
+        CanonicalForm primElem, imPrimElem;
+        bool primFail= false;
+        Variable vBuf;
+        ASSERT (!primFail, "failure in integer factorizer");
+        if (primFail)
+          ; //ERROR
+        else
+          imPrimElem= mapPrimElem (delta, beta, v);
+
+        CFList source, dest;
+        CanonicalForm bufA= mapDown (A, info, source, dest);
+        source= CFList();
+        dest= CFList();
+        bufA= mapUp (bufA, beta, v, delta, imPrimElem, source, dest);
+        ExtensionInfo info= ExtensionInfo (v, beta, imPrimElem, delta);
+        factors= multiFactorize (bufA, info);
+        prune (v);
+      }
+    }
+    return factors;
+  }
+  else // we are in GF (p^k)
+  {
+    int p= getCharacteristic();
+    int extensionDeg= getGFDegree();
+    bool extension= true;
+    if (k == 1) // need factorization over F_p
+    {
+      extensionDeg++;
+      if (pow ((double) p, (double) extensionDeg) < (1<<16))
+      // pass to GF(p^k+1)
+      {
+        CanonicalForm mipo= gf_mipo;
+        setCharacteristic (p);
+        Variable vBuf= rootOf (mipo.mapinto());
+        A= GF2FalphaRep (A, vBuf);
+        setCharacteristic (p, extensionDeg, 'Z');
+        ExtensionInfo info= ExtensionInfo (extension);
+        factors= multiFactorize (A.mapinto(), info);
+        prune (vBuf);
+      }
+      else // not able to pass to another GF, pass to F_p(\alpha)
+      {
+        CanonicalForm mipo= gf_mipo;
+        setCharacteristic (p);
+        Variable vBuf= rootOf (mipo.mapinto());
+        A= GF2FalphaRep (A, vBuf);
+        Variable v= chooseExtension (vBuf, beta, k);
+        ExtensionInfo info= ExtensionInfo (v, extension);
+        factors= multiFactorize (A, info);
+        prune (vBuf);
+      }
+    }
+    else // need factorization over GF (p^k)
+    {
+      if (pow ((double) p, (double) 2*extensionDeg) < (1<<16))
+      // pass to GF(p^2k)
+      {
+        setCharacteristic (p, 2*extensionDeg, 'Z');
+        ExtensionInfo info= ExtensionInfo (k, cGFName, extension);
+        factors= multiFactorize (GFMapUp (A, extensionDeg), info);
+        setCharacteristic (p, extensionDeg, cGFName);
+      }
+      else // not able to pass to GF (p^2k), pass to F_p (\alpha)
+      {
+        CanonicalForm mipo= gf_mipo;
+        setCharacteristic (p);
+        Variable v1= rootOf (mipo.mapinto());
+        A= GF2FalphaRep (A, v1);
+        Variable v2= chooseExtension (v1, v1, k);
+        CanonicalForm primElem, imPrimElem;
+        bool primFail= false;
+        Variable vBuf;
+        primElem= primitiveElement (v1, v1, primFail);
+        if (primFail)
+          ; //ERROR
+        else
+          imPrimElem= mapPrimElem (primElem, v1, v2);
+        CFList source, dest;
+        CanonicalForm bufA= mapUp (A, v1, v2, primElem, imPrimElem,
+                                     source, dest);
+        ExtensionInfo info= ExtensionInfo (v2, v1, imPrimElem, primElem);
+        factors= multiFactorize (bufA, info);
+        setCharacteristic (p, k, cGFName);
+        for (CFListIterator i= factors; i.hasItem(); i++)
+          i.getItem()= Falpha2GFRep (i.getItem());
+        prune (v1);
+      }
+    }
+    return factors;
+  }
+}
+
+#endif
+/* HAVE_NTL */
diff --git a/factory/facFqFactorize.h b/factory/facFqFactorize.h
new file mode 100644
index 0000000..87c37f4
--- /dev/null
+++ b/factory/facFqFactorize.h
@@ -0,0 +1,798 @@
+/*****************************************************************************\
+ * Computer Algebra System SINGULAR
+\*****************************************************************************/
+/** @file facFqFactorize.h
+ *
+ * This file provides functions for factorizing a multivariate polynomial over
+ * \f$ F_{p} \f$ , \f$ F_{p}(\alpha ) \f$ or GF.
+ *
+ * @author Martin Lee
+ *
+ **/
+/*****************************************************************************/
+
+#ifndef FAC_FQ_FACTORIZE_H
+#define FAC_FQ_FACTORIZE_H
+
+// #include "config.h"
+#include "timing.h"
+
+#include "facFqBivar.h"
+#include "DegreePattern.h"
+#include "ExtensionInfo.h"
+#include "cf_util.h"
+#include "facFqSquarefree.h"
+#include "facFqBivarUtil.h"
+
+
+TIMING_DEFINE_PRINT (fac_fq_squarefree)
+TIMING_DEFINE_PRINT (fac_fq_factor_squarefree)
+
+/// Factorization over a finite field
+///
+/// @return @a multiFactorize returns a factorization of F
+/// @sa biFactorize(), extFactorize()
+CFList
+multiFactorize (const CanonicalForm& F,    ///< [in] sqrfree poly
+                const ExtensionInfo& info  ///< [in] info about extension
+               );
+
+/// factorize a squarefree multivariate polynomial over \f$ F_{p} \f$
+///
+/// @return @a FpSqrfFactorize returns a list of monic factors, the first
+///         element is the leading coefficient.
+/// @sa FqSqrfFactorize(), GFSqrfFactorize()
+#ifdef HAVE_NTL
+inline
+CFList FpSqrfFactorize (const CanonicalForm & F ///< [in] a multivariate poly
+                       )
+{
+  if (getNumVars (F) == 2)
+    return FpBiSqrfFactorize (F);
+  ExtensionInfo info= ExtensionInfo (false);
+  CFList result= multiFactorize (F, info);
+  result.insert (Lc(F));
+  return result;
+}
+
+/// factorize a squarefree multivariate polynomial over \f$ F_{p} (\alpha ) \f$
+///
+/// @return @a FqSqrfFactorize returns a list of monic factors, the first
+///         element is the leading coefficient.
+/// @sa FpSqrfFactorize(), GFSqrfFactorize()
+inline
+CFList FqSqrfFactorize (const CanonicalForm & F, ///< [in] a multivariate poly
+                        const Variable& alpha    ///< [in] algebraic variable
+                       )
+{
+  if (getNumVars (F) == 2)
+    return FqBiSqrfFactorize (F, alpha);
+  ExtensionInfo info= ExtensionInfo (alpha, false);
+  CFList result= multiFactorize (F, info);
+  result.insert (Lc(F));
+  return result;
+}
+
+/// factorize a squarefree multivariate polynomial over GF
+///
+/// @return @a GFSqrfFactorize returns a list of monic factors, the first
+///         element is the leading coefficient.
+/// @sa FpSqrfFactorize(), FqSqrfFactorize()
+inline
+CFList GFSqrfFactorize (const CanonicalForm & F ///< [in] a multivariate poly
+                       )
+{
+  ASSERT (CFFactory::gettype() == GaloisFieldDomain,
+          "GF as base field expected");
+  if (getNumVars (F) == 2)
+    return GFBiSqrfFactorize (F);
+  ExtensionInfo info= ExtensionInfo (getGFDegree(), gf_name, false);
+  CFList result= multiFactorize (F, info);
+  result.insert (Lc(F));
+  return result;
+}
+
+/// factorize a multivariate polynomial over \f$ F_{p} \f$
+///
+/// @return @a FpFactorize returns a list of monic factors with
+///         multiplicity, the first element is the leading coefficient.
+/// @sa FqFactorize(), GFFactorize()
+inline
+CFFList FpFactorize (const CanonicalForm& G,///< [in] a multivariate poly
+                     bool substCheck= true  ///< [in] enables substitute check
+                    )
+{
+  if (getNumVars (G) == 2)
+    return FpBiFactorize (G, substCheck);
+
+  CanonicalForm F= G;
+  if (substCheck)
+  {
+    bool foundOne= false;
+    int * substDegree= new int [F.level()];
+    for (int i= 1; i <= F.level(); i++)
+    {
+      if (degree (F, i) > 0)
+      {
+        substDegree[i-1]= substituteCheck (F, Variable (i));
+        if (substDegree [i-1] > 1)
+        {
+          foundOne= true;
+          subst (F, F, substDegree[i-1], Variable (i));
+        }
+      }
+      else
+        substDegree[i-1]= -1;
+    }
+    if (foundOne)
+    {
+      CFFList result= FpFactorize (F, false);
+      CFFList newResult, tmp;
+      CanonicalForm tmp2;
+      newResult.insert (result.getFirst());
+      result.removeFirst();
+      for (CFFListIterator i= result; i.hasItem(); i++)
+      {
+        tmp2= i.getItem().factor();
+        for (int j= 1; j <= G.level(); j++)
+        {
+          if (substDegree[j-1] > 1)
+            tmp2= reverseSubst (tmp2, substDegree[j-1], Variable (j));
+        }
+        tmp= FpFactorize (tmp2, false);
+        tmp.removeFirst();
+        for (CFFListIterator j= tmp; j.hasItem(); j++)
+          newResult.append (CFFactor (j.getItem().factor(),
+                                      j.getItem().exp()*i.getItem().exp()));
+      }
+      delete [] substDegree;
+      return newResult;
+    }
+    delete [] substDegree;
+  }
+
+  ExtensionInfo info= ExtensionInfo (false);
+  Variable a= Variable (1);
+  CanonicalForm LcF= Lc (F);
+  TIMING_START (fac_fq_squarefree);
+  CFFList sqrf= FpSqrf (F, false);
+  TIMING_END_AND_PRINT (fac_fq_squarefree,
+                        "time for squarefree factorization over Fq: ");
+  CFFList result;
+  CFList bufResult;
+  sqrf.removeFirst();
+  CFListIterator i;
+  for (CFFListIterator iter= sqrf; iter.hasItem(); iter++)
+  {
+    TIMING_START (fac_fq_factor_squarefree);
+    bufResult= multiFactorize (iter.getItem().factor(), info);
+    TIMING_END_AND_PRINT (fac_fq_factor_squarefree,
+                          "time to factorize sqrfree factor over Fq: ");
+    for (i= bufResult; i.hasItem(); i++)
+      result.append (CFFactor (i.getItem(), iter.getItem().exp()));
+  }
+  result.insert (CFFactor (LcF, 1));
+  return result;
+}
+
+/// factorize a multivariate polynomial over \f$ F_{p} (\alpha ) \f$
+///
+/// @return @a FqFactorize returns a list of monic factors with
+///         multiplicity, the first element is the leading coefficient.
+/// @sa FpFactorize(), GFFactorize()
+inline
+CFFList FqFactorize (const CanonicalForm& G, ///< [in] a multivariate poly
+                     const Variable& alpha,  ///< [in] algebraic variable
+                     bool substCheck= true   ///< [in] enables substitute check
+                    )
+{
+  if (getNumVars (G) == 2)
+    return FqBiFactorize (G, alpha, substCheck);
+
+  CanonicalForm F= G;
+  if (substCheck)
+  {
+    bool foundOne= false;
+    int * substDegree= new int [F.level()];
+    for (int i= 1; i <= F.level(); i++)
+    {
+      if (degree (F, i) > 0)
+      {
+        substDegree[i-1]= substituteCheck (F, Variable (i));
+        if (substDegree [i-1] > 1)
+        {
+          foundOne= true;
+          subst (F, F, substDegree[i-1], Variable (i));
+        }
+      }
+      else
+        substDegree[i-1]= -1;
+    }
+    if (foundOne)
+    {
+      CFFList result= FqFactorize (F, alpha, false);
+      CFFList newResult, tmp;
+      CanonicalForm tmp2;
+      newResult.insert (result.getFirst());
+      result.removeFirst();
+      for (CFFListIterator i= result; i.hasItem(); i++)
+      {
+        tmp2= i.getItem().factor();
+        for (int j= 1; j <= G.level(); j++)
+        {
+          if (substDegree[j-1] > 1)
+            tmp2= reverseSubst (tmp2, substDegree[j-1], Variable (j));
+        }
+        tmp= FqFactorize (tmp2, alpha, false);
+        tmp.removeFirst();
+        for (CFFListIterator j= tmp; j.hasItem(); j++)
+          newResult.append (CFFactor (j.getItem().factor(),
+                                      j.getItem().exp()*i.getItem().exp()));
+      }
+      delete [] substDegree;
+      return newResult;
+    }
+    delete [] substDegree;
+  }
+
+  ExtensionInfo info= ExtensionInfo (alpha, false);
+  CanonicalForm LcF= Lc (F);
+  TIMING_START (fac_fq_squarefree);
+  CFFList sqrf= FqSqrf (F, alpha, false);
+  TIMING_END_AND_PRINT (fac_fq_squarefree,
+                        "time for squarefree factorization over Fq: ");
+  CFFList result;
+  CFList bufResult;
+  sqrf.removeFirst();
+  CFListIterator i;
+  for (CFFListIterator iter= sqrf; iter.hasItem(); iter++)
+  {
+    TIMING_START (fac_fq_factor_squarefree);
+    bufResult= multiFactorize (iter.getItem().factor(), info);
+    TIMING_END_AND_PRINT (fac_fq_factor_squarefree,
+                          "time to factorize sqrfree factor over Fq: ");
+    for (i= bufResult; i.hasItem(); i++)
+      result.append (CFFactor (i.getItem(), iter.getItem().exp()));
+  }
+  result.insert (CFFactor (LcF, 1));
+  return result;
+}
+
+/// factorize a multivariate polynomial over GF
+///
+/// @return @a GFFactorize returns a list of monic factors with
+///         multiplicity, the first element is the leading coefficient.
+/// @sa FpFactorize(), FqFactorize()
+inline
+CFFList GFFactorize (const CanonicalForm& G, ///< [in] a multivariate poly
+                     bool substCheck= true   ///< [in] enables substitute check
+                    )
+{
+  ASSERT (CFFactory::gettype() == GaloisFieldDomain,
+          "GF as base field expected");
+  if (getNumVars (G) == 2)
+    return GFBiFactorize (G, substCheck);
+
+  CanonicalForm F= G;
+  if (substCheck)
+  {
+    bool foundOne= false;
+    int * substDegree= new int [F.level()];
+    for (int i= 1; i <= F.level(); i++)
+    {
+      if (degree (F, i) > 0)
+      {
+        substDegree[i-1]= substituteCheck (F, Variable (i));
+        if (substDegree [i-1] > 1)
+        {
+          foundOne= true;
+          subst (F, F, substDegree[i-1], Variable (i));
+        }
+      }
+      else
+        substDegree[i-1]= -1;
+    }
+    if (foundOne)
+    {
+      CFFList result= GFFactorize (F, false);
+      CFFList newResult, tmp;
+      CanonicalForm tmp2;
+      newResult.insert (result.getFirst());
+      result.removeFirst();
+      for (CFFListIterator i= result; i.hasItem(); i++)
+      {
+        tmp2= i.getItem().factor();
+        for (int j= 1; j <= G.level(); j++)
+        {
+          if (substDegree[j-1] > 1)
+            tmp2= reverseSubst (tmp2, substDegree[j-1], Variable (j));
+        }
+        tmp= GFFactorize (tmp2, false);
+        tmp.removeFirst();
+        for (CFFListIterator j= tmp; j.hasItem(); j++)
+          newResult.append (CFFactor (j.getItem().factor(),
+                                      j.getItem().exp()*i.getItem().exp()));
+      }
+      delete [] substDegree;
+      return newResult;
+    }
+    delete [] substDegree;
+  }
+
+  Variable a= Variable (1);
+  ExtensionInfo info= ExtensionInfo (getGFDegree(), gf_name, false);
+  CanonicalForm LcF= Lc (F);
+  CFFList sqrf= GFSqrf (F, false);
+  CFFList result;
+  CFList bufResult;
+  sqrf.removeFirst();
+  CFListIterator i;
+  for (CFFListIterator iter= sqrf; iter.hasItem(); iter++)
+  {
+    bufResult= multiFactorize (iter.getItem().factor(), info);
+    for (i= bufResult; i.hasItem(); i++)
+      result.append (CFFactor (i.getItem(), iter.getItem().exp()));
+  }
+  result.insert (CFFactor (LcF, 1));
+  return result;
+}
+
+#endif
+
+/// Naive factor recombination for multivariate factorization over an extension
+/// of the initial field. No precomputed is used to exclude combinations.
+///
+/// @return @a extFactorRecombination returns a list of factors of @a F, whose
+///         shift to zero is reversed.
+/// @sa factorRecombination()
+CFList
+extFactorRecombination (
+                 const CFList& factors,     ///< [in] list of lifted factors
+                                            ///< that are monic wrt Variable (1)
+                 const CanonicalForm& F,    ///< [in] poly to be factored
+                 const CFList& M,           ///< [in] a list of powers of
+                                            ///< Variables
+                 const ExtensionInfo& info, ///< [in] info about extension
+                 const CFList& evaluation   ///< [in] evaluation point
+                       );
+
+/// Naive factor recombination for multivariate factorization.
+/// No precomputed is used to exclude combinations.
+///
+/// @return @a factorRecombination returns a list of factors of @a F
+/// @sa extFactorRecombination()
+CFList
+factorRecombination (const CanonicalForm& F,///< [in] poly to be factored
+                     const CFList& factors, ///< [in] list of lifted factors
+                                            ///< that are monic wrt Variable (1)
+                     const CFList& M        ///< [in] a list of powers of
+                                            ///< Variables
+                    );
+
+/// recombination of bivariate factors @a factors1 s. t. the result evaluated
+/// at @a evalPoint coincides with @a factors2
+CFList
+recombination (const CFList& factors1,        ///<[in] list of bivariate factors
+               const CFList& factors2,        ///<[in] list univariate factors
+               int s,                         ///<[in] algorithm starts checking
+                                              ///<  subsets of size s
+               int thres,                     ///<[in] threshold for the size of
+                                              ///<  subsets which are checked
+               const CanonicalForm& evalPoint,///<[in] evaluation point
+               const Variable& x              ///<[in] second variable of
+                                              ///< bivariate factors
+              );
+
+/// Lift bound adaption. Essentially an early factor detection but only the lift
+/// bound is adapted.
+///
+/// @return @a liftBoundAdaption returns an adapted lift bound.
+/// @sa earlyFactorDetect(), earlyFactorDetection()
+int
+liftBoundAdaption (const CanonicalForm& F, ///< [in] a poly
+                   const CFList& factors,  ///< [in] list of list of lifted
+                                           ///< factors that are monic wrt
+                                           ///< Variable (1)
+                   bool& success,          ///< [in,out] indicates that no
+                                           ///< further lifting is necessary
+                   const int deg,          ///< [in] stage of Hensel lifting
+                   const CFList& MOD,      ///< [in] a list of powers of
+                                           ///< Variables
+                   const int bound         ///< [in] initial lift bound
+                  );
+
+/// Lift bound adaption over an extension of the initial field. Essentially an
+///early factor detection but only the lift bound is adapted.
+///
+/// @return @a liftBoundAdaption returns an adapted lift bound.
+/// @sa earlyFactorDetect(), earlyFactorDetection()
+int
+extLiftBoundAdaption (
+            const CanonicalForm& F,    ///< [in] a poly
+            const CFList& factors,     ///< [in] list of list of lifted
+                                       ///< factors that are monic wrt
+            bool& success,             ///< [in,out] indicates that no further
+                                       ///< lifting is necessary
+            const ExtensionInfo& info, ///< [in] info about extension
+            const CFList& eval,        ///< [in] evaluation point
+            const int deg,             ///< [in] stage of Hensel lifting
+            const CFList& MOD,         ///< [in] a list of powers of
+                                       ///< Variables
+            const int bound            ///< [in] initial lift bound
+                     );
+
+/// detects factors of @a F at stage @a deg of Hensel lifting.
+/// No combinations of more than one factor are tested. Lift bound is adapted.
+///
+/// @return @a earlyFactorDetect returns a list of factors of F (possibly
+///         incomplete), in case of success. Otherwise an empty list.
+/// @sa factorRecombination(), extEarlyFactorDetect()
+CFList
+earlyFactorDetect (
+                CanonicalForm& F,      ///< [in,out] poly to be factored,
+                                       ///< returns poly divided by detected
+                                       ///< factors in case of success
+                CFList& factors,       ///< [in,out] list of factors lifted up
+                                       ///< to @a deg, returns a list of factors
+                                       ///< without detected factors
+                int& adaptedLiftBound, ///< [in,out] adapted lift bound
+                bool& success,         ///< [in,out] indicating success
+                const int deg,         ///< [in] stage of Hensel lifting
+                const CFList& MOD,     ///< [in] a list of powers of
+                                       ///< Variables
+                const int bound        ///< [in] initial lift bound
+                  );
+
+/// detects factors of @a F at stage @a deg of Hensel lifting.
+/// No combinations of more than one factor are tested. Lift bound is adapted.
+///
+/// @return @a extEarlyFactorDetect returns a list of factors of F (possibly
+///         incomplete), whose shift to zero is reversed, in case of success.
+///         Otherwise an empty list.
+/// @sa factorRecombination(), earlyFactorDetection()
+CFList
+extEarlyFactorDetect (
+            CanonicalForm& F,          ///< [in,out] poly to be factored,
+                                       ///< returns poly divided by detected
+                                       ///< factors in case of success
+            CFList& factors,           ///< [in,out] list of factors lifted up
+                                       ///< to @a deg, returns a list of factors
+                                       ///< without detected factors
+            int& adaptedLiftBound,     ///< [in,out] adapted lift bound
+            bool& success,             ///< [in,out] indicating succes
+            const ExtensionInfo& info, ///< [in] info about extension
+            const CFList& eval,        ///< [in] evaluation point
+            const int deg,             ///< [in] stage of Hensel lifting
+            const CFList& MOD,         ///< [in] a list of powers of Variables
+            const int bound            ///< [in] initial lift bound
+                     );
+
+/// evaluation point search for multivariate factorization,
+/// looks for a (F.level() - 1)-tuple such that the resulting univariate
+/// polynomial has main variable Variable (1), is squarefree and its degree
+/// coincides with degree(F) and the bivariate one is primitive wrt.
+/// Variable(1), and successively evaluated polynomials have the same degree in
+/// their main variable as F has, fails if there are no valid evaluation points,
+/// eval contains the intermediate evaluated polynomials.
+///
+/// @return @a evalPoints returns an evaluation point, which is valid if and
+///         only if fail == false.
+CFList
+evalPoints (const CanonicalForm& F,  ///< [in] a compressed poly
+            CFList & eval,           ///< [in,out] an empty list, returns @a F
+                                     ///< successive evaluated
+            const Variable& alpha,   ///< [in] algebraic variable
+            CFList& list,            ///< [in,out] a list of points already
+                                     ///< considered, a point is encoded as a
+                                     ///< poly of degree F.level()-1 in
+                                     ///< Variable(1)
+            const bool& GF,          ///< [in] GF?
+            bool& fail               ///< [in,out] indicates failure
+           );
+
+/// hensel Lifting and early factor detection
+///
+/// @return @a henselLiftAndEarly returns monic (wrt Variable (1)) lifted
+///         factors without factors which have been detected at an early stage
+///         of Hensel lifting
+/// @sa earlyFactorDetectn(), extEarlyFactorDetect()
+CFList
+henselLiftAndEarly (
+            CanonicalForm& A,         ///< [in,out] poly to be factored,
+                                      ///< returns poly divided by detected
+                                      ///< factors, in case of success
+            CFList& MOD,              ///< [in,out] a list of powers of
+                                      ///< Variables
+            int*& liftBounds,         ///< [in,out] initial lift bounds, returns
+                                      ///< adapted lift bounds
+            bool& earlySuccess,       ///< [in,out] indicating success
+            CFList& earlyFactors,     ///< [in,out] early factors
+            const CFList& Aeval,      ///< [in] @a A successively evaluated at
+                                      ///< elements of @a evaluation
+            const CFList& biFactors,  ///< [in] bivariate factors
+            const CFList& evaluation, ///< [in] evaluation point
+            const ExtensionInfo& info ///< [in] info about extension
+                   );
+
+/// Factorization over an extension of initial field
+///
+/// @return @a extFactorize returns factorization of F over initial field
+/// @sa extBiFactorize(), multiFactorize()
+CFList
+extFactorize (const CanonicalForm& F,   ///< [in] poly to be factored
+              const ExtensionInfo& info ///< [in] info about extension
+             );
+
+/// compute the LCM of the contents of @a A wrt to each variable occuring in @a
+/// A.
+///
+/// @return @a lcmContent returns the LCM of the contents of @a A wrt to each
+///         variable occuring in @a A.
+CanonicalForm
+lcmContent (const CanonicalForm& A, ///< [in] a compressed multivariate poly
+            CFList& contentAi       ///< [in,out] an empty list, returns a list
+                                    ///< of the contents of @a A wrt to each
+                                    ///< variable occuring in @a A starting from
+                                    ///< @a A.mvar().
+           );
+
+/// compress a polynomial s.t. \f$ deg_{x_{i}} (F) >= deg_{x_{i+1}} (F) \f$ and
+/// no gaps between the variables occur
+///
+/// @return a compressed poly with the above properties
+CanonicalForm myCompress (const CanonicalForm& F, ///< [in] a poly
+                          CFMap& N                ///< [in,out] a map to
+                                                  ///< decompress
+                         );
+
+/// evaluate a poly A with main variable at level 1 at an evaluation point in
+/// K^(n-1) wrt different second variables. If this evaluation is valid (see
+/// evalPoints) then Aeval contains A successively evaluated at this point,
+/// otherwise this entry is empty
+void
+evaluationWRTDifferentSecondVars (
+                    CFList*& Aeval,          ///<[in,out] an array of length n-2
+                                             ///< if variable at level i > 2
+                                             ///< admits a valid evaluation
+                                             ///< this entry contains A
+                                             ///< successively evaluated at this
+                                             ///< point otherwise an empty list
+                    const CFList& evaluation,///<[in] a valid evaluation point
+                                             ///< for main variable at level 1
+                                             ///< and second variable at level 2
+                    const CanonicalForm& A   ///<[in] some poly
+                                 );
+
+/// refine a bivariate factorization of A with l factors to one with
+/// minFactorsLength if possible
+void
+refineBiFactors (const CanonicalForm& A,  ///< [in] some poly
+                 CFList& biFactors,       ///< [in,out] list of bivariate to be
+                                          ///< refined, returns refined factors
+                 CFList* const& factors,  ///< [in] list of bivariate
+                                          ///< factorizations of A wrt different
+                                          ///< second variables
+                 const CFList& evaluation,///< [in] the evaluation point
+                 int minFactorsLength     ///< [in] the minimal number of factors
+                );
+
+/// plug in evalPoint for y in a list of polys
+///
+/// @return returns a list of the evaluated polys, these evaluated polys are
+/// made monic
+CFList
+buildUniFactors (const CFList& biFactors,       ///< [in] a list of polys
+                 const CanonicalForm& evalPoint,///< [in] some evaluation point
+                 const Variable& y              ///< [in] some variable
+                );
+
+
+/// sort bivariate factors in Aeval such that their corresponding univariate
+/// factors coincide with uniFactors, uniFactors and biFactors may get
+/// recombined if necessary
+void sortByUniFactors (CFList*& Aeval,          ///< [in,out] array of bivariate
+                                                ///< factors
+                       int AevalLength,         ///< [in] length of Aeval
+                       CFList& uniFactors,      ///< [in,out] univariate factors
+                       CFList& biFactors,       ///< [in,out] bivariate factors
+                       const CFList& evaluation ///< [in] evaluation point
+                      );
+
+/// extract leading coefficients wrt Variable(1) from bivariate factors obtained
+/// from factorizations of A wrt different second variables
+void
+getLeadingCoeffs (const CanonicalForm& A,  ///< [in] some poly
+                  CFList*& Aeval           ///< [in,out] array of bivariate
+                                           ///< factors, returns the leading
+                                           ///< coefficients of these factors
+                 );
+
+/// normalize precomputed leading coefficients such that leading coefficients
+/// evaluated at @a evaluation in K^(n-2) equal the leading coeffs wrt
+/// Variable(1) of bivariate factors and change @a A and @a Aeval accordingly
+void
+prepareLeadingCoeffs (CFList*& LCs,               ///<[in,out]
+                      CanonicalForm& A,           ///<[in,out]
+                      CFList& Aeval,              ///<[in,out]
+                      int n,                      ///<[in] level of poly to be
+                                                  ///< factored
+                      const CFList& leadingCoeffs,///<[in] precomputed leading
+                                                  ///< coeffs
+                      const CFList& biFactors,    ///<[in] bivariate factors
+                      const CFList& evaluation    ///<[in] evaluation point
+                     );
+
+/// obtain factors of F by reconstructing their leading coeffs
+///
+/// @return returns the reconstructed factors
+/// @sa factorRecombination()
+CFList
+leadingCoeffReconstruction (const CanonicalForm& F,///<[in] poly to be factored
+                            const CFList& factors, ///<[in] factors of f monic
+                                                   ///< wrt Variable (1)
+                            const CFList& M        ///<[in] a list of powers of
+                                                   ///< Variables
+                           );
+
+/// distribute content
+///
+/// @return returns a list result of polys such that prod (result)= prod (L)
+/// but the first entry of L may be (partially) factorized and these factors
+/// are distributed onto other entries in L
+CFList
+distributeContent (
+          const CFList& L,                        ///<[in] list of polys, first
+                                                  ///< entry the content to be
+                                                  ///< distributed
+          const CFList* differentSecondVarFactors,///<[in] factorization wrt
+                                                  ///< different second vars
+          int length                              ///<[in] length of
+                                                  ///<differentSecondVarFactors
+                  );
+
+/// gcd free basis of two lists of factors
+void
+gcdFreeBasis (CFFList& factors1, ///< [in,out] list of factors, returns gcd free
+                                 ///< factors
+              CFFList& factors2  ///< [in,out] list of factors, returns gcd free
+                                 ///< factors
+             );
+
+/// computes a list l of length length(LCFFactors)+1 of polynomials such that
+/// prod (l)=LCF, note that the first entry of l may be non constant. Intended
+/// to be used to precompute coefficients of a polynomial f from its bivariate
+/// factorizations.
+///
+/// @return see above
+CFList
+precomputeLeadingCoeff (const CanonicalForm& LCF,       ///<[in] a multivariate
+                                                        ///< poly
+                        const CFList& LCFFactors,       ///<[in] a list of
+                                                        ///< univariate factors
+                                                        ///< of LCF of level 2
+                        const Variable& alpha,          ///<[in] algebraic var.
+                        const CFList& evaluation,       ///<[in] an evaluation
+                                                        ///< point having
+                                                        ///< lSecondVarLCs+1
+                                                        ///< components
+                        CFList* & differentSecondVarLCs,///<[in] LCs of factors
+                                                        ///< of f wrt different
+                                                        ///< second variables
+                        int lSecondVarLCs,              ///<[in] length of the
+                                                        ///< above
+                        Variable& y                     ///<[in,out] if y.level()
+                                                        ///< is not 1 on output
+                                                        ///< the second variable
+                                                        ///< has been changed to
+                                                        ///< y
+                       );
+
+/// changes the second variable to be @a w and updates all relevant data
+void
+changeSecondVariable (CanonicalForm& A,        ///<[in,out] a multivariate poly
+                      CFList& biFactors,       ///<[in,out] bivariate factors
+                      CFList& evaluation,      ///<[in,out] evaluation point
+                      CFList*& oldAeval,       ///<[in,out] old bivariate factors
+                                               ///< wrt. different second vars
+                      int lengthAeval2,        ///<[in] length of oldAeval
+                      const CFList& uniFactors,///<[in] univariate factors
+                      const Variable& w        ///<[in] some variable
+                     );
+
+/// distributes a divisor LCmultiplier of LC(A,1) on the bivariate factors and
+/// the precomputed leading coefficients
+void
+distributeLCmultiplier (CanonicalForm& A,               ///<[in,out] some poly
+                        CFList& leadingCoeffs,          ///<[in,out] leading
+                                                        ///< coefficients
+                        CFList& biFactors,              ///<[in,out] bivariate
+                                                        ///< factors
+                        const CFList& evaluation,       ///<[in] eval. point
+                        const CanonicalForm& LCmultipler///<[in] multiplier
+                       );
+
+/// heuristic to distribute @a LCmultiplier onto factors based on the variables
+/// that occur in @a LCmultiplier and in the leading coeffs of bivariate factors
+void
+LCHeuristic (CanonicalForm& A,                 ///<[in,out] a poly
+             const CanonicalForm& LCmultiplier,///<[in,out] divisor of LC (A,1)
+             CFList& biFactors,                ///<[in,out] bivariate factors
+             CFList*& leadingCoeffs,           ///<[in,out] leading coeffs
+             const CFList* oldAeval,           ///<[in] bivariate factors wrt.
+                                               ///< different second vars
+             int lengthAeval,                  ///<[in] length of oldAeval
+             const CFList& evaluation,         ///<[in] evaluation point
+             const CFList& oldBiFactors        ///<[in] bivariate factors
+                                               ///< without LCmultiplier
+                                               ///< distributed on them
+            );
+
+/// checks if prod(LCs)==LC (oldA,1) and if so divides elements of leadingCoeffs
+/// by elements in contents, sets A to oldA and sets foundTrueMultiplier to true
+void
+LCHeuristicCheck (const CFList& LCs,        ///<[in] leading coeffs computed
+                  const CFList& contents,   ///<[in] content of factors
+                  CanonicalForm& A,         ///<[in,out] oldA*LCmultiplier^m
+                  const CanonicalForm& oldA,///<[in] some poly
+                  CFList& leadingCoeffs,    ///<[in,out] leading coefficients
+                  bool& foundTrueMultiplier ///<[in,out] success?
+                 );
+
+/// heuristic to distribute @a LCmultiplier onto factors based on the contents
+/// of @a factors. @a factors are assumed to come from LucksWangSparseHeuristic.
+/// If not successful @a contents will contain the content of each element of @a
+/// factors and @a LCs will contain the LC of each element of @a factors divided
+/// by its content
+void
+LCHeuristic2 (const CanonicalForm& LCmultiplier,///<[in] divisor of LC (A,1)
+              const CFList& factors,            ///<[in] result of
+                                                ///< LucksWangSparseHeuristic
+              CFList& leadingCoeffs,            ///<[in,out] leading coeffs
+              CFList& contents,                 ///<[in,out] content of factors
+              CFList& LCs,                      ///<[in,out] LC of factors
+                                                ///< divided by content of
+                                                ///< factors
+              bool& foundTrueMultiplier         ///<[in,out] success?
+             );
+
+/// heuristic to remove @a LCmultiplier from a factor based on the contents
+/// of @a factors. @a factors are assumed to come from LucksWangSparseHeuristic.
+void
+LCHeuristic3 (const CanonicalForm& LCmultiplier,///<[in] divisor of LC (A,1)
+              const CFList& factors,            ///<[in] result of
+                                                ///< LucksWangSparseHeuristic
+              const CFList& oldBiFactors,       ///<[in] bivariate factors
+                                                ///< without LCmultiplier
+                                                ///< distributed on them
+              const CFList& contents,           ///<[in] content of factors
+              const CFList* oldAeval,           ///<[in] bivariate factors wrt.
+                                                ///< different second vars
+              CanonicalForm& A,                 ///<[in,out] poly
+              CFList*& leadingCoeffs,           ///<[in,out] leading coeffs
+              int lengthAeval,                  ///<[in] length of oldAeval
+              bool& foundMultiplier             ///<[in,out] success?
+             );
+
+/// heuristic to remove factors of @a LCmultiplier from @a factors.
+/// More precisely checks if elements of @a contents divide @a LCmultiplier.
+/// Assumes LCHeuristic3 is run before it and was successful.
+void
+LCHeuristic4 (const CFList& oldBiFactors,   ///<[in] bivariate factors
+                                            ///< without LCmultiplier
+                                            ///< distributed on them
+              const CFList* oldAeval,       ///<[in] bivariate factors wrt.
+                                            ///< different second vars
+              const CFList& contents,       ///<[in] content of factors
+              const CFList& factors,        ///<[in] result of
+                                            ///< LucksWangSparseHeuristic
+              const CanonicalForm& testVars,///<[in] product of second vars that
+                                            ///< occur among oldAeval
+              int lengthAeval,              ///<[in] length of oldAeval
+              CFList*& leadingCoeffs,       ///<[in,out] leading coeffs
+              CanonicalForm& A,             ///<[in,out] poly
+              CanonicalForm& LCmultiplier,  ///<[in,out] divisor of LC (A,1)
+              bool& foundMultiplier         ///<[in] success?
+             );
+
+#endif
+/* FAC_FQ_FACTORIZE_H */
diff --git a/factory/facFqFactorizeUtil.cc b/factory/facFqFactorizeUtil.cc
new file mode 100644
index 0000000..d0dc592
--- /dev/null
+++ b/factory/facFqFactorizeUtil.cc
@@ -0,0 +1,310 @@
+/*****************************************************************************\
+ * Computer Algebra System SINGULAR
+\*****************************************************************************/
+/** @file facFqFactorizeUtil.cc
+ *
+ * This file provides utility functions for multivariate factorization
+ *
+ * @author Martin Lee
+ *
+ **/
+/*****************************************************************************/
+
+
+#include "config.h"
+
+
+#include "canonicalform.h"
+#include "cf_map.h"
+#include "cf_algorithm.h"
+
+static inline
+void appendSwap (CFList& factors1, const CFList& factors2, const int
+                  swapLevel1, const int swapLevel2, const Variable& x)
+{
+  for (CFListIterator i= factors2; i.hasItem(); i++)
+  {
+    if (swapLevel1)
+    {
+      if (swapLevel2)
+        factors1.append (swapvar (swapvar (i.getItem(), x,
+                         Variable (swapLevel2)), Variable (swapLevel1), x));
+      else
+        factors1.append (swapvar (i.getItem(), Variable (swapLevel1), x));
+    }
+    else
+    {
+      if (swapLevel2)
+        factors1.append (swapvar (i.getItem(), x, Variable (swapLevel2)));
+      else
+        factors1.append (i.getItem());
+    }
+  }
+  return;
+}
+
+
+void swap (CFList& factors, const int swapLevel1, const int swapLevel2, const
+           Variable& x)
+{
+  for (CFListIterator i= factors; i.hasItem(); i++)
+  {
+    if (swapLevel1)
+    {
+      if (swapLevel2)
+        i.getItem()= swapvar (swapvar (i.getItem(), x, Variable (swapLevel2)),
+                              Variable (swapLevel1), x);
+      else
+        i.getItem()= swapvar (i.getItem(), Variable (swapLevel1), x);
+    }
+    else
+    {
+      if (swapLevel2)
+        i.getItem()= swapvar (i.getItem(), x, Variable (swapLevel2));
+    }
+  }
+  return;
+}
+
+void appendSwapDecompress (CFList& factors1, const CFList& factors2,
+                             const CFMap& N, const int swapLevel, const
+                             Variable& x)
+{
+  for (CFListIterator i= factors1; i.hasItem(); i++)
+  {
+    if (swapLevel)
+      i.getItem()= swapvar (i.getItem(), Variable (swapLevel), x);
+    i.getItem()= N(i.getItem());
+  }
+  for (CFListIterator i= factors2; i.hasItem(); i++)
+  {
+    if (!i.getItem().inCoeffDomain())
+      factors1.append (N (i.getItem()));
+  }
+  return;
+}
+
+void appendSwapDecompress (CFList& factors1, const CFList& factors2,
+                             const CFMap& N, const int swapLevel1,
+                             const int swapLevel2, const Variable& x)
+{
+  for (CFListIterator i= factors1; i.hasItem(); i++)
+  {
+    if (swapLevel1)
+    {
+      if (swapLevel2)
+        i.getItem()=
+        N (swapvar (swapvar (i.getItem(), Variable (swapLevel2), x), x,
+                    Variable (swapLevel1)));
+      else
+        i.getItem()= N (swapvar (i.getItem(), x, Variable (swapLevel1)));
+    }
+    else
+    {
+      if (swapLevel2)
+        i.getItem()= N (swapvar (i.getItem(), Variable (swapLevel2), x));
+      else
+        i.getItem()= N (i.getItem());
+    }
+  }
+  for (CFListIterator i= factors2; i.hasItem(); i++)
+  {
+    if (!i.getItem().inCoeffDomain())
+      factors1.append (N (i.getItem()));
+  }
+  return;
+}
+
+int* liftingBounds (const CanonicalForm& A, const int& bivarLiftBound)
+{
+  int j= A.level() - 1;
+  int* liftBounds= new int [j];
+  liftBounds[0]= bivarLiftBound;
+  for (int i= 1; i < j; i++)
+  {
+    liftBounds[i]= degree (A, Variable (i + 2)) + 1 +
+                            degree (LC (A, 1), Variable (i + 2));
+  }
+  return liftBounds;
+}
+
+CanonicalForm shift2Zero (const CanonicalForm& F, CFList& Feval, const CFList& evaluation, int l)
+{
+  CanonicalForm A= F;
+  int k= evaluation.length() + l - 1;
+  for (CFListIterator i= evaluation; i.hasItem(); i++, k--)
+    A= A (Variable (k) + i.getItem(), k);
+  CanonicalForm buf= A;
+  Feval= CFList();
+  Feval.append (buf);
+  for (k= A.level(); k > 2; k--)
+  {
+    buf= mod (buf, Variable (k));
+    Feval.insert (buf);
+  }
+  return A;
+}
+
+CanonicalForm reverseShift (const CanonicalForm& F, const CFList& evaluation, int l)
+{
+  int k= evaluation.length() + l - 1;
+  CanonicalForm result= F;
+  CFListIterator j= evaluation;
+  for (int i= k; j.hasItem() && (i > l - 1); i--, j++)
+  {
+    if (F.level() < i)
+      continue;
+    result= result (Variable (i) - j.getItem(), i);
+  }
+  return result;
+}
+
+bool isOnlyLeadingCoeff (const CanonicalForm& F)
+{
+  return (F-LC (F,1)*power (Variable(1),degree (F,1))).isZero();
+}
+
+/// like getVars but including multiplicities
+CanonicalForm myGetVars (const CanonicalForm& F)
+{
+  CanonicalForm result= 1;
+  int deg;
+  for (int i= 1; i <= F.level(); i++)
+  {
+    if ((deg= degree (F, i)) > 0)
+      result *= power (Variable (i), deg);
+  }
+  return result;
+}
+
+int compareByNumberOfVars (const CFFactor& F, const CFFactor& G)
+{
+  return getNumVars (F.factor()) < getNumVars (G.factor());
+}
+
+CFFList
+sortCFFListByNumOfVars (CFFList& F)
+{
+    F.sort (compareByNumberOfVars);
+    CFFList result= F;
+    return result;
+}
+
+CFList evaluateAtZero (const CanonicalForm& F)
+{
+  CFList result;
+  CanonicalForm buf= F;
+  result.insert (buf);
+  for (int i= F.level(); i > 2; i--)
+  {
+    buf= buf (0, i);
+    result.insert (buf);
+  }
+  return result;
+}
+
+CFList evaluateAtEval (const CanonicalForm& F, const CFArray& eval)
+{
+  CFList result;
+  CanonicalForm buf= F;
+  result.insert (buf);
+  int k= eval.size();
+  for (int i= 1; i < k; i++)
+  {
+    buf= buf (eval[i], i + 2);
+    result.insert (buf);
+  }
+  return result;
+}
+
+CFList evaluateAtEval (const CanonicalForm& F, const CFList& evaluation, int l)
+{
+  CFList result;
+  CanonicalForm buf= F;
+  result.insert (buf);
+  int k= evaluation.length() + l - 1;
+  CFListIterator j= evaluation;
+  for (int i= k; j.hasItem() && i > l; i--, j++)
+  {
+    if (F.level() < i)
+      continue;
+    buf= buf (j.getItem(), i);
+    result.insert (buf);
+  }
+  return result;
+}
+
+
+CFList recoverFactors (const CanonicalForm& F, const CFList& factors)
+{
+  CFList result;
+  CanonicalForm tmp, tmp2;
+  CanonicalForm G= F;
+  for (CFListIterator i= factors; i.hasItem(); i++)
+  {
+    tmp= i.getItem()/content (i.getItem(), 1);
+    if (fdivides (tmp, G, tmp2))
+    {
+      G= tmp2;
+      result.append (tmp);
+    }
+  }
+  if (result.length() + 1 == factors.length())
+    result.append (G/content (G,1));
+  return result;
+}
+
+CFList recoverFactors (const CanonicalForm& F, const CFList& factors,
+                       const CFList& evaluation)
+{
+  CFList result;
+  CanonicalForm tmp, tmp2;
+  CanonicalForm G= F;
+  for (CFListIterator i= factors; i.hasItem(); i++)
+  {
+    tmp= reverseShift (i.getItem(), evaluation, 2);
+    tmp /= content (tmp, 1);
+    if (fdivides (tmp, G, tmp2))
+    {
+      G= tmp2;
+      result.append (tmp);
+    }
+  }
+  if (result.length() + 1 == factors.length())
+    result.append (G/content (G,1));
+  return result;
+}
+
+CFList recoverFactors (CanonicalForm& F, const CFList& factors, int* index)
+{
+  CFList result;
+  CanonicalForm tmp, tmp2;
+  CanonicalForm G= F;
+  int j= 0;
+  for (CFListIterator i= factors; i.hasItem(); i++, j++)
+  {
+    if (i.getItem().isZero())
+    {
+      index[j]= 0;
+      continue;
+    }
+    tmp= i.getItem();
+    if (fdivides (tmp, G, tmp2))
+    {
+      G= tmp2;
+      tmp /=content (tmp, 1);
+      result.append (tmp);
+      index[j]= 1;
+    }
+    else
+      index[j]= 0;
+  }
+  if (result.length() + 1 == factors.length())
+  {
+    result.append (G/content (G,1));
+    F= G/content (G,1);
+  }
+  else
+    F= G;
+  return result;
+}
diff --git a/factory/facFqFactorizeUtil.h b/factory/facFqFactorizeUtil.h
new file mode 100644
index 0000000..a510d00
--- /dev/null
+++ b/factory/facFqFactorizeUtil.h
@@ -0,0 +1,194 @@
+/*****************************************************************************\
+ * Computer Algebra System SINGULAR
+\*****************************************************************************/
+/** @file facFqFactorizeUtil.h
+ *
+ * This file provides utility functions for multivariate factorization
+ *
+ * @author Martin Lee
+ *
+ **/
+/*****************************************************************************/
+
+#ifndef FAC_FQ_FACTORIZE_UTIL_H
+#define FAC_FQ_FACTORIZE_UTIL_H
+
+// #include "config.h"
+#include "canonicalform.h"
+#include "cf_map.h"
+
+/// append @a factors2 to @a factors1 and decompress
+///
+static inline
+void decompressAppend (CFList& factors1,       ///< [in,out] a list of polys,
+                                               ///< returns @a factors2 appended
+                                               ///< to it and everything is
+                                               ///< decompressed
+                       const CFList& factors2, ///< [in] a list of polys
+                       const CFMap& N          ///< [in] a map
+                      )
+{
+  for (CFListIterator i= factors1; i.hasItem(); i++)
+    i.getItem()= N (i.getItem());
+  for (CFListIterator i= factors2; i.hasItem(); i++)
+    factors1.append (N (i.getItem()));
+}
+
+
+/// swap elements in @a factors2 and append them to @a factors1
+///
+void appendSwap (CFList& factors1,       ///< [in,out] a list of polys,
+                                         ///< returns swapped elements of @a
+                                         ///< factors2 appended to it
+                 const CFList& factors2, ///< [in] a list of polys
+                 const int swapLevel1,   ///< [in] level of variable to be
+                                         ///< swapped with x, 0 if no swapping
+                 const int swapLevel2,   ///< [in] level of variable to be
+                                         ///< swapped with x, 0 if no swapping
+                 const Variable& x       ///< [in] a variable
+                );
+
+/// swap elements in @a factors
+void swap (CFList& factors,       ///< [in] a list of polys, returns swapped
+                                  ///< elements of factors
+           const int swapLevel1, ///< [in] level of variable to be
+                                  ///< swapped with x, 0 if no swapping
+           const int swapLevel2, ///< [in] level of variable to be
+                                  ///< swapped with x, 0 if no swapping
+           const Variable& x      ///< [in] a variable
+          );
+
+/// swap elements of @a factors2, append them to @a factors1 and decompress
+void appendSwapDecompress (
+                  CFList& factors1,       ///< [in,out] a list of polys,
+                                          ///< returns swapped elements of @a
+                                          ///< factors2 appended to it and
+                                          ///< everything is decompressed
+                  const CFList& factors2, ///< [in] a list of polys
+                  const CFMap& N,         ///< [in] a map
+                  const int swapLevel,    ///< [in] level of variable to be
+                                          ///< swapped with x, 0 if no swapping
+                  const Variable& x       ///< [in] a variable
+                          );
+
+/// swap elements of @a factors2, append them to @a factors1 and decompress
+void appendSwapDecompress (
+                  CFList& factors1,       ///< [in,out] a list of polys,
+                                          ///< returns swapped elements of @a
+                                          ///< factors2 appended to it and
+                                          ///< everything is decompressed
+                  const CFList& factors2, ///< [in] a list of polys
+                  const CFMap& N,         ///< [in] a map
+                  const int swapLevel1,   ///< [in] level of variable to be
+                                          ///< swapped with x, 0 if no swapping
+                  const int swapLevel2,   ///< [in] level of variable to be
+                                          ///< swapped with x, 0 if no swapping
+                  const Variable& x       ///< [in] a variable
+                          );
+
+
+/// compute lifting bounds
+///
+/// @return @a liftingBounds returns an array containing the lift bounds for A
+int* liftingBounds (const CanonicalForm& A,    ///< [in] a compressed poly
+                    const int& bivarLiftBound  ///< [in] lift bound for
+                                               ///< @a biFactorizer()
+                   );
+
+/// shift evaluation point to zero
+/// @return @a shift2Zero returns @a F shifted by @a evaluation s.t. 0 is a
+///         valid evaluation point
+/// @sa evalPoints(), reverseShift()
+CanonicalForm
+shift2Zero (const CanonicalForm& F,  ///< [in] a compressed poly
+            CFList& Feval,           ///< [in,out] an empty list, returns
+                                     ///< @a F successively evaluated
+                                     ///< at 0
+            const CFList& evaluation,///< [in] a valid evaluation point
+            int l= 2                 ///< [in] level at which the evaluation
+                                     ///< starts
+           );
+
+/// reverse shifting the evaluation point to zero
+///
+/// @return @a reverseShift returns a poly whose shift to zero is reversed
+/// @sa shift2Zero(), evalPoints()
+CanonicalForm reverseShift (const CanonicalForm& F,  ///< [in] a compressed poly
+                            const CFList& evaluation,///< [in] a valid
+                                                     ///< evaluation point
+                            int l= 2                 ///< [in] level at which
+                                                     ///< the evaluation starts
+                           );
+
+/// check if @a F consists of more than just the leading coeff wrt. Variable (1)
+///
+/// @return as described above
+bool isOnlyLeadingCoeff (const CanonicalForm& F ///< [in] some poly
+                        );
+
+/// sort CFFList by the number variables in a factor
+CFFList sortCFFListByNumOfVars (CFFList & F ///< [in,out] a list of factors
+                               );
+
+/// like getVars but each variable x occuring in @a F is raised to x^degree (F,x)
+CanonicalForm myGetVars (const CanonicalForm& F ///< [in] a polynomial
+                        );
+
+/// evaluate @a F at @a evaluation
+///
+/// @return @a evaluateAtEval returns a list containing the successive
+/// evaluations of @a F, last entry is @a F again
+CFList
+evaluateAtEval (const CanonicalForm& F,   ///<[in] some poly
+                const CFArray& evaluation ///<[in] some evaluation point
+               );
+
+/// evaluate @a F at @a evaluation
+///
+/// @return @a evaluateAtEval returns a list containing the successive
+/// evaluations of @a F starting at level @a l, last entry is @a F again
+CFList
+evaluateAtEval (const CanonicalForm& F,  ///<[in] some poly
+                const CFList& evaluation,///<[in] some evaluation point
+                int l                    ///<[in] level to start at
+               );
+
+/// evaluate F successively n-2 at 0
+///
+/// @return returns a list of successive evaluations of F, ending with F
+CFList evaluateAtZero (const CanonicalForm& F ///< [in] some poly
+                      );
+
+/// divides factors by their content wrt. Variable(1) and checks if these polys
+/// divide F
+///
+/// @return returns factors of F
+CFList recoverFactors (const CanonicalForm& F, ///< [in] some poly F
+                       const CFList& factors   ///< [in] some list of
+                                               ///< factor candidates
+                      );
+
+/// divides factors shifted by evaluation by their content wrt. Variable(1) and
+/// checks if these polys divide F
+///
+/// @return returns factors of F
+CFList recoverFactors (const CanonicalForm& F,  ///< [in] some poly F
+                       const CFList& factors,   ///< [in] some list of
+                                                ///< factor candidates
+                       const CFList& evaluation ///< [in] evaluation point
+                      );
+
+/// checks if factors divide F, if so F is divided by this factor and the factor
+/// is divided by its content wrt. Variable(1) and the entry in index at the
+/// position of the factor is set to 1, otherwise the entry in index is set to 0
+///
+/// @return returns factors of F
+CFList recoverFactors (CanonicalForm& F,     ///< [in,out] some poly F
+                       const CFList& factors,///< [in] some list of
+                                             ///< factor candidates
+                       int* index            ///< [in] position of real factors
+                      );
+
+#endif
+/* FAC_FQ_FACTORIZE_UTIL_H */
+
diff --git a/factory/facFqSquarefree.cc b/factory/facFqSquarefree.cc
new file mode 100644
index 0000000..42e08e7
--- /dev/null
+++ b/factory/facFqSquarefree.cc
@@ -0,0 +1,357 @@
+/*****************************************************************************\
+ * Computer Algebra System SINGULAR
+\*****************************************************************************/
+/** @file facFqSquarefree.cc
+ *
+ * This file provides functions for squarefrees factorizing over
+ * \f$ F_{p} \f$ , \f$ F_{p}(\alpha ) \f$ or GF, as decribed in "Factoring
+ * multivariate polynomials over a finite field" by L. Bernardin
+ *
+ * @author Martin Lee
+ *
+ **/
+/*****************************************************************************/
+
+
+#include "config.h"
+
+
+#include "canonicalform.h"
+
+#include "cf_iter.h"
+#include "cf_map.h"
+#include "cf_util.h"
+#include "cf_factory.h"
+#include "facFqSquarefree.h"
+
+#ifdef HAVE_NTL
+#include "NTLconvert.h"
+#endif
+
+#ifdef HAVE_FLINT
+#include "FLINTconvert.h"
+#endif
+
+static inline
+CanonicalForm
+pthRoot (const CanonicalForm & F, int q)
+{
+  CanonicalForm A= F;
+  int p= getCharacteristic ();
+  if (A.inCoeffDomain())
+  {
+    A= power (A, q/p);
+    return A;
+  }
+  else
+  {
+    CanonicalForm buf= 0;
+    for (CFIterator i= A; i.hasTerms(); i++)
+      buf= buf + power(A.mvar(), i.exp()/p)*pthRoot (i.coeff(), q);
+    return buf;
+  }
+}
+
+#ifdef HAVE_NTL
+CanonicalForm
+pthRoot (const CanonicalForm & F, const ZZ& q, const Variable& alpha)
+{
+  CanonicalForm A= F;
+  int p= getCharacteristic ();
+  if (A.inCoeffDomain())
+  {
+    zz_p::init (p);
+    zz_pX NTLMipo= convertFacCF2NTLzzpX (getMipo (alpha));
+    zz_pE::init (NTLMipo);
+    zz_pX NTLA= convertFacCF2NTLzzpX (A);
+    zz_pE NTLA2= to_zz_pE (NTLA);
+    power (NTLA2, NTLA2, q/p);
+    A= convertNTLzzpE2CF (NTLA2, alpha);
+    return A;
+  }
+  else
+  {
+    CanonicalForm buf= 0;
+    for (CFIterator i= A; i.hasTerms(); i++)
+      buf= buf + power(A.mvar(), i.exp()/p)*pthRoot (i.coeff(), q, alpha);
+    return buf;
+  }
+}
+#endif
+
+#if (HAVE_FLINT && __FLINT_RELEASE >= 20400)
+CanonicalForm
+pthRoot (const CanonicalForm & F, const fmpz_t& q, const Variable& alpha)
+{
+  CanonicalForm A= F;
+  int p= getCharacteristic ();
+  if (A.inCoeffDomain())
+  {
+    nmod_poly_t FLINTmipo;
+    fq_nmod_ctx_t fq_con;
+    fmpz_t qp;
+    fq_nmod_t FLINTA;
+
+    nmod_poly_init (FLINTmipo, p);
+    convertFacCF2nmod_poly_t (FLINTmipo, getMipo (alpha));
+
+    fq_nmod_ctx_init_modulus (fq_con, FLINTmipo, "Z");
+
+    fq_nmod_init2 (FLINTA, fq_con);
+
+    convertFacCF2Fq_nmod_t (FLINTA, A, fq_con);
+
+    fmpz_init_set (qp, q);
+    fmpz_divexact_si (qp, qp, p);
+
+    fq_nmod_pow (FLINTA, FLINTA, qp, fq_con);
+    A= convertFq_nmod_t2FacCF (FLINTA, alpha);
+
+    fmpz_clear (qp);
+    nmod_poly_clear (FLINTmipo);
+    fq_nmod_clear (FLINTA, fq_con);
+    fq_nmod_ctx_clear (fq_con);
+    return A;
+  }
+  else
+  {
+    CanonicalForm buf= 0;
+    for (CFIterator i= A; i.hasTerms(); i++)
+      buf= buf + power(A.mvar(), i.exp()/p)*pthRoot (i.coeff(), q, alpha);
+    return buf;
+  }
+}
+#endif
+
+CanonicalForm
+maxpthRoot (const CanonicalForm & F, int q, int& l)
+{
+  CanonicalForm result= F;
+  bool derivZero= true;
+  l= 0;
+  while (derivZero)
+  {
+    for (int i= 1; i <= result.level(); i++)
+    {
+      if (!deriv (result, Variable (i)).isZero())
+      {
+        derivZero= false;
+        break;
+      }
+    }
+    if (!derivZero)
+      break;
+    result= pthRoot (result, q);
+    l++;
+  }
+  return result;
+}
+
+static inline
+CFFList
+sqrfPosDer (const CanonicalForm & F, const Variable & x,
+            CanonicalForm & c)
+{
+  CanonicalForm b= deriv (F, x);
+  c= gcd (F, b);
+  CanonicalForm w= F/c;
+  CanonicalForm v= b/c;
+  CanonicalForm u= v - deriv (w, x);
+  int j= 1;
+  int p= getCharacteristic();
+  CanonicalForm g;
+  CFFList result;
+  while (j < p - 1 && degree(u) >= 0)
+  {
+    g= gcd (w, u);
+    if (!g.inCoeffDomain())
+      result.append (CFFactor (g, j));
+    w= w/g;
+    c= c/w;
+    v= u/g;
+    u= v - deriv (w, x);
+    j++;
+  }
+  if (!w.inCoeffDomain())
+    result.append (CFFactor (w, j));
+  return result;
+}
+
+CFFList
+squarefreeFactorization (const CanonicalForm & F, const Variable & alpha)
+{
+  int p= getCharacteristic();
+  CanonicalForm A= F;
+  CFMap M;
+  A= compress (A, M);
+  Variable x= A.mvar();
+  int l= x.level();
+  int k;
+  if (CFFactory::gettype() == GaloisFieldDomain)
+    k= getGFDegree();
+  else if (alpha.level() != 1)
+    k= degree (getMipo (alpha));
+  else
+    k= 1;
+  Variable buf, buf2;
+  CanonicalForm tmp;
+
+  CFFList tmp1, tmp2;
+  bool found;
+  for (int i= l; i > 0; i--)
+  {
+    buf= Variable (i);
+    if (degree (deriv (A, buf)) >= 0)
+    {
+      tmp1= sqrfPosDer (A, buf, tmp);
+      A= tmp;
+      for (CFFListIterator j= tmp1; j.hasItem(); j++)
+      {
+        found= false;
+        CFFListIterator k= tmp2;
+        if (!k.hasItem() && !j.getItem().factor().inCoeffDomain()) tmp2.append (j.getItem());
+        else
+        {
+          for (; k.hasItem(); k++)
+          {
+            if (k.getItem().exp() == j.getItem().exp())
+            {
+              k.getItem()= CFFactor (k.getItem().factor()*j.getItem().factor(),
+                                     j.getItem().exp());
+              found= true;
+            }
+          }
+          if (found == false && !j.getItem().factor().inCoeffDomain())
+            tmp2.append(j.getItem());
+        }
+      }
+    }
+  }
+
+  bool degcheck= false;;
+  for (int i= l; i > 0; i--)
+  if (degree (A, Variable(i)) >= p)
+    degcheck= true;
+
+  if (degcheck == false && tmp1.isEmpty() && tmp2.isEmpty())
+    return CFFList (CFFactor (F/Lc(F), 1));
+
+  CanonicalForm buffer;
+#if defined(HAVE_NTL) || (HAVE_FLINT && __FLINT_RELEASE >= 20400)
+  if (alpha.level() == 1)
+#endif
+    buffer= pthRoot (A, ipower (p, k));
+#if (HAVE_FLINT && __FLINT_RELEASE >= 20400)
+  else
+  {
+    fmpz_t qq;
+    fmpz_init_set_ui (qq, p);
+    fmpz_pow_ui (qq, qq, k);
+    buffer= pthRoot (A, qq, alpha);
+    fmpz_clear (qq);
+  }
+#elif defined(HAVE_NTL)
+  else
+  {
+    ZZ q;
+    power (q, p, k);
+    buffer= pthRoot (A, q, alpha);
+  }
+#endif
+
+  tmp1= squarefreeFactorization (buffer, alpha);
+
+  CFFList result;
+  buf= alpha;
+  for (CFFListIterator i= tmp2; i.hasItem(); i++)
+  {
+    for (CFFListIterator j= tmp1; j.hasItem(); j++)
+    {
+      tmp= gcd (i.getItem().factor(), j.getItem().factor());
+      i.getItem()= CFFactor (i.getItem().factor()/tmp, i.getItem().exp());
+      j.getItem()= CFFactor (j.getItem().factor()/tmp, j.getItem().exp());
+      if (!tmp.inCoeffDomain())
+      {
+        tmp= M (tmp);
+        result.append (CFFactor (tmp/Lc(tmp),
+                       j.getItem().exp()*p + i.getItem().exp()));
+      }
+    }
+  }
+  for (CFFListIterator i= tmp2; i.hasItem(); i++)
+  {
+    if (!i.getItem().factor().inCoeffDomain())
+    {
+      tmp= M (i.getItem().factor());
+      result.append (CFFactor (tmp/Lc(tmp), i.getItem().exp()));
+    }
+  }
+  for (CFFListIterator j= tmp1; j.hasItem(); j++)
+  {
+    if (!j.getItem().factor().inCoeffDomain())
+    {
+      tmp= M (j.getItem().factor());
+      result.append (CFFactor (tmp/Lc(tmp), j.getItem().exp()*p));
+    }
+  }
+  return result;
+}
+
+CanonicalForm
+sqrfPart (const CanonicalForm& F, CanonicalForm& pthPower,
+          const Variable& alpha)
+{
+  if (F.inCoeffDomain())
+  {
+    pthPower= 1;
+    return F;
+  }
+  CFMap M;
+  CanonicalForm A= compress (F, M);
+  Variable vBuf= alpha;
+  CanonicalForm w, v, b;
+  pthPower= 1;
+  CanonicalForm result;
+  int i= 1;
+  bool allZero= true;
+  for (; i <= A.level(); i++)
+  {
+    if (!deriv (A, Variable (i)).isZero())
+    {
+      allZero= false;
+      break;
+    }
+  }
+  if (allZero)
+  {
+    pthPower= F;
+    return 1;
+  }
+  w= gcd (A, deriv (A, Variable (i)));
+
+  b= A/w;
+  result= b;
+  if (degree (w) < 1)
+    return M (result);
+  i++;
+  for (; i <= A.level(); i++)
+  {
+    if (!deriv (w, Variable (i)).isZero())
+    {
+      b= w;
+      w= gcd (w, deriv (w, Variable (i)));
+      b /= w;
+      if (degree (b) < 1)
+        break;
+      CanonicalForm g;
+      g= gcd (b, result);
+      if (degree (g) > 0)
+        result *= b/g;
+      if (degree (g) <= 0)
+        result *= b;
+    }
+  }
+  result= M (result);
+  return result;
+}
+
diff --git a/factory/facFqSquarefree.h b/factory/facFqSquarefree.h
new file mode 100644
index 0000000..0345d6e
--- /dev/null
+++ b/factory/facFqSquarefree.h
@@ -0,0 +1,150 @@
+/*****************************************************************************\
+ * Computer Algebra System SINGULAR
+\*****************************************************************************/
+/** @file facFqSquarefree.h
+ *
+ * This file provides functions for squarefrees factorizing over
+ * \f$ F_{p} \f$ , \f$ F_{p}(\alpha ) \f$ or GF.
+ *
+ * @author Martin Lee
+ *
+ **/
+/*****************************************************************************/
+
+#ifndef FAC_FQ_SQUAREFREE_H
+#define FAC_FQ_SQUAREFREE_H
+
+#include "cf_assert.h"
+#include "cf_factory.h"
+#include "fac_sqrfree.h"
+#include "cf_factory.h"
+
+/// squarefree factorization over a finite field
+/// @a return a list of squarefree factors with multiplicity
+CFFList
+squarefreeFactorization
+                (const CanonicalForm & F, ///<[in] a poly
+                 const Variable & alpha   ///<[in] either an algebraic variable,
+                                          ///< i.e. we are over some F_p (alpha)
+                                          ///< or a variable of level 1, i.e.
+                                          ///< we are F_p or GF
+                );
+
+/// squarefree factorization over \f$ F_{p} \f$.
+/// If input is not monic, the leading coefficient is dropped
+///
+/// @return a list of squarefree factors with multiplicity
+inline
+CFFList FpSqrf (const CanonicalForm& F, ///< [in] a poly
+                bool sort= true         ///< [in] sort factors by exponent?
+               )
+{
+  Variable a= 1;
+  int n= F.level();
+  CanonicalForm cont, bufF= F;
+  CFFList bufResult;
+
+  CFFList result;
+  for (int i= n; i >= 1; i++)
+  {
+    cont= content (bufF, i);
+    bufResult= squarefreeFactorization (cont, a);
+    if (bufResult.getFirst().factor().inCoeffDomain())
+      bufResult.removeFirst();
+    result= Union (result, bufResult);
+    bufF /= cont;
+    if (bufF.inCoeffDomain())
+      break;
+  }
+  if (!bufF.inCoeffDomain())
+  {
+    bufResult= squarefreeFactorization (bufF, a);
+    if (bufResult.getFirst().factor().inCoeffDomain())
+      bufResult.removeFirst();
+    result= Union (result, bufResult);
+  }
+  if (sort)
+    result= sortCFFList (result);
+  result.insert (CFFactor (Lc(F), 1));
+  return result;
+}
+
+/// squarefree factorization over \f$ F_{p}(\alpha ) \f$.
+/// If input is not monic, the leading coefficient is dropped
+///
+/// @return a list of squarefree factors with multiplicity
+inline
+CFFList FqSqrf (const CanonicalForm& F, ///< [in] a poly
+                const Variable& alpha,  ///< [in] algebraic variable
+                bool sort= true         ///< [in] sort factors by exponent?
+               )
+{
+  int n= F.level();
+  CanonicalForm cont, bufF= F;
+  CFFList bufResult;
+
+  CFFList result;
+  for (int i= n; i >= 1; i++)
+  {
+    cont= content (bufF, i);
+    bufResult= squarefreeFactorization (cont, alpha);
+    if (bufResult.getFirst().factor().inCoeffDomain())
+      bufResult.removeFirst();
+    result= Union (result, bufResult);
+    bufF /= cont;
+    if (bufF.inCoeffDomain())
+      break;
+  }
+  if (!bufF.inCoeffDomain())
+  {
+    bufResult= squarefreeFactorization (bufF, alpha);
+    if (bufResult.getFirst().factor().inCoeffDomain())
+      bufResult.removeFirst();
+    result= Union (result, bufResult);
+  }
+  if (sort)
+    result= sortCFFList (result);
+  result.insert (CFFactor (Lc(F), 1));
+  return result;
+}
+
+/// squarefree factorization over GF.
+/// If input is not monic, the leading coefficient is dropped
+///
+/// @return a list of squarefree factors with multiplicity
+inline
+CFFList GFSqrf (const CanonicalForm& F, ///< [in] a poly
+                bool sort= true         ///< [in] sort factors by exponent?
+               )
+{
+  ASSERT (CFFactory::gettype() == GaloisFieldDomain,
+          "GF as base field expected");
+  return FpSqrf (F, sort);
+}
+
+/// squarefree part of @a F/g, where g is the product of those squarefree
+/// factors whose multiplicity is 0 mod p, if @a F a pth power pthPower= F.
+///
+/// @return @a sqrfPart returns 1, if F is a pthPower, else it returns the
+///         squarefree part of @a F/g, where g is the product of those
+///         squarefree factors whose multiplicity is 0 mod p
+CanonicalForm
+sqrfPart (const CanonicalForm& F,  ///< [in] a poly
+          CanonicalForm& pthPower, ///< [in,out] returns F is F is a pthPower
+          const Variable& alpha    ///< [in] algebraic variable
+         );
+
+/// p^l-th root extraction, where l is maximal
+///
+/// @return @a maxpthRoot returns a p^l-th root of @a F, where @a l is maximal
+/// @sa pthRoot()
+CanonicalForm
+maxpthRoot (const CanonicalForm & F, ///< [in] a poly which is a pth power
+            int q,                   ///< [in] size of the field
+            int& l                   ///< [in,out] @a l maximal, s.t. @a F is
+                                     ///< a p^l-th power
+           );
+
+#endif
+/* FAC_FQ_SQUAREFREE_H */
+
diff --git a/factory/facHensel.cc b/factory/facHensel.cc
new file mode 100644
index 0000000..42dd7de
--- /dev/null
+++ b/factory/facHensel.cc
@@ -0,0 +1,2844 @@
+/*****************************************************************************\
+ * Computer Algebra System SINGULAR
+\*****************************************************************************/
+/** @file facHensel.cc
+ *
+ * This file implements functions to lift factors via Hensel lifting.
+ *
+ * ABSTRACT: Hensel lifting is described in "Efficient Multivariate
+ * Factorization over Finite Fields" by L. Bernardin & M. Monagon and
+ * "Algorithms for Computer Algebra" by Geddes, Czapor, Labahn
+ *
+ * @author Martin Lee
+ *
+ **/
+/*****************************************************************************/
+
+
+#include "config.h"
+
+
+#include "cf_assert.h"
+#include "debug.h"
+#include "timing.h"
+
+#include "cfGcdAlgExt.h"
+#include "facHensel.h"
+#include "facMul.h"
+#include "fac_util.h"
+#include "cf_algorithm.h"
+#include "cf_primes.h"
+#include "facBivar.h"
+#include "cfNTLzzpEXGCD.h"
+#include "cfUnivarGcd.h"
+
+#ifdef HAVE_NTL
+#include <NTL/lzz_pEX.h>
+#include "NTLconvert.h"
+
+#ifdef HAVE_FLINT
+#include "FLINTconvert.h"
+#endif
+
+TIMING_DEFINE_PRINT (diotime)
+TIMING_DEFINE_PRINT (product1)
+TIMING_DEFINE_PRINT (product2)
+TIMING_DEFINE_PRINT (hensel23)
+TIMING_DEFINE_PRINT (hensel)
+
+#if (!(HAVE_FLINT && __FLINT_RELEASE >= 20400))
+static
+CFList productsNTL (const CFList& factors, const CanonicalForm& M)
+{
+  if (fac_NTL_char != getCharacteristic())
+  {
+    fac_NTL_char= getCharacteristic();
+    zz_p::init (getCharacteristic());
+  }
+  zz_pX NTLMipo= convertFacCF2NTLzzpX (M);
+  zz_pE::init (NTLMipo);
+  zz_pEX prod;
+  vec_zz_pEX v;
+  v.SetLength (factors.length());
+  int j= 0;
+  for (CFListIterator i= factors; i.hasItem(); i++, j++)
+  {
+    if (i.getItem().inCoeffDomain())
+      v[j]= to_zz_pEX (to_zz_pE (convertFacCF2NTLzzpX (i.getItem())));
+    else
+      v[j]= convertFacCF2NTLzz_pEX (i.getItem(), NTLMipo);
+  }
+  CFList result;
+  Variable x= Variable (1);
+  for (int j= 0; j < factors.length(); j++)
+  {
+    int k= 0;
+    set(prod);
+    for (int i= 0; i < factors.length(); i++, k++)
+    {
+      if (k == j)
+        continue;
+      prod *= v[i];
+    }
+    result.append (convertNTLzz_pEX2CF (prod, x, M.mvar()));
+  }
+  return result;
+}
+#endif
+
+#if (HAVE_FLINT && __FLINT_RELEASE >= 20400)
+static
+CFList productsFLINT (const CFList& factors, const CanonicalForm& M)
+{
+  nmod_poly_t FLINTmipo;
+  fq_nmod_ctx_t fq_con;
+  fq_nmod_poly_t prod;
+  fq_nmod_t buf;
+
+  nmod_poly_init (FLINTmipo, getCharacteristic());
+  convertFacCF2nmod_poly_t (FLINTmipo, M);
+
+  fq_nmod_ctx_init_modulus (fq_con, FLINTmipo, "Z");
+
+  fq_nmod_poly_t * vec=new fq_nmod_poly_t [factors.length()];
+
+  int j= 0;
+
+  for (CFListIterator i= factors; i.hasItem(); i++, j++)
+  {
+    if (i.getItem().inCoeffDomain())
+    {
+      fq_nmod_poly_init (vec[j], fq_con);
+      fq_nmod_init2 (buf, fq_con);
+      convertFacCF2Fq_nmod_t (buf, i.getItem(), fq_con);
+      fq_nmod_poly_set_coeff (vec[j], 0, buf, fq_con);
+      fq_nmod_clear (buf, fq_con);
+    }
+    else
+      convertFacCF2Fq_nmod_poly_t (vec[j], i.getItem(), fq_con);
+  }
+
+  CFList result;
+  Variable x= Variable (1);
+  fq_nmod_poly_init (prod, fq_con);
+  for (j= 0; j < factors.length(); j++)
+  {
+    int k= 0;
+    fq_nmod_poly_one (prod, fq_con);
+    for (int i= 0; i < factors.length(); i++, k++)
+    {
+      if (k == j)
+        continue;
+      fq_nmod_poly_mul (prod, prod, vec[i], fq_con);
+    }
+    result.append (convertFq_nmod_poly_t2FacCF (prod, x, M.mvar(), fq_con));
+  }
+  for (j= 0; j < factors.length(); j++)
+    fq_nmod_poly_clear (vec[j], fq_con);
+
+  nmod_poly_clear (FLINTmipo);
+  fq_nmod_poly_clear (prod, fq_con);
+  fq_nmod_ctx_clear (fq_con);
+  delete [] vec;
+  return result;
+}
+#endif
+
+static
+void tryDiophantine (CFList& result, const CanonicalForm& F,
+                     const CFList& factors, const CanonicalForm& M, bool& fail)
+{
+  ASSERT (M.isUnivariate(), "expected univariate poly");
+
+  CFList bufFactors= factors;
+  bufFactors.removeFirst();
+  bufFactors.insert (factors.getFirst () (0,2));
+  CanonicalForm inv, leadingCoeff= Lc (F);
+  CFListIterator i= bufFactors;
+  if (bufFactors.getFirst().inCoeffDomain())
+  {
+    if (i.hasItem())
+      i++;
+  }
+  for (; i.hasItem(); i++)
+  {
+    tryInvert (Lc (i.getItem()), M, inv ,fail);
+    if (fail)
+      return;
+    i.getItem()= reduce (i.getItem()*inv, M);
+  }
+#if (HAVE_FLINT && __FLINT_RELEASE >= 20400)
+  bufFactors= productsFLINT (bufFactors, M);
+#else
+  bufFactors= productsNTL (bufFactors, M);
+#endif
+
+  CanonicalForm buf1, buf2, buf3, S, T;
+  i= bufFactors;
+  if (i.hasItem())
+    i++;
+  buf1= bufFactors.getFirst();
+  buf2= i.getItem();
+#ifdef HAVE_NTL
+  Variable x= Variable (1);
+  if (fac_NTL_char != getCharacteristic())
+  {
+    fac_NTL_char= getCharacteristic();
+    zz_p::init (getCharacteristic());
+  }
+  zz_pX NTLMipo= convertFacCF2NTLzzpX (M);
+  zz_pE::init (NTLMipo);
+  zz_pEX NTLbuf1, NTLbuf2, NTLbuf3, NTLS, NTLT;
+  NTLbuf1= convertFacCF2NTLzz_pEX (buf1, NTLMipo);
+  NTLbuf2= convertFacCF2NTLzz_pEX (buf2, NTLMipo);
+  tryNTLXGCD (NTLbuf3, NTLS, NTLT, NTLbuf1, NTLbuf2, fail);
+  if (fail)
+    return;
+  S= convertNTLzz_pEX2CF (NTLS, x, M.mvar());
+  T= convertNTLzz_pEX2CF (NTLT, x, M.mvar());
+#else
+  tryExtgcd (buf1, buf2, M, buf3, S, T, fail);
+  if (fail)
+    return;
+#endif
+  result.append (S);
+  result.append (T);
+  if (i.hasItem())
+    i++;
+  for (; i.hasItem(); i++)
+  {
+#ifdef HAVE_NTL
+    NTLbuf1= convertFacCF2NTLzz_pEX (i.getItem(), NTLMipo);
+    tryNTLXGCD (NTLbuf3, NTLS, NTLT, NTLbuf3, NTLbuf1, fail);
+    if (fail)
+      return;
+    S= convertNTLzz_pEX2CF (NTLS, x, M.mvar());
+    T= convertNTLzz_pEX2CF (NTLT, x, M.mvar());
+#else
+    buf1= i.getItem();
+    tryExtgcd (buf3, buf1, M, buf3, S, T, fail);
+    if (fail)
+      return;
+#endif
+    CFListIterator k= factors;
+    for (CFListIterator j= result; j.hasItem(); j++, k++)
+    {
+      j.getItem() *= S;
+      j.getItem()= mod (j.getItem(), k.getItem());
+      j.getItem()= reduce (j.getItem(), M);
+    }
+    result.append (T);
+  }
+}
+
+static
+CFList mapinto (const CFList& L)
+{
+  CFList result;
+  for (CFListIterator i= L; i.hasItem(); i++)
+    result.append (mapinto (i.getItem()));
+  return result;
+}
+
+static
+int mod (const CFList& L, const CanonicalForm& p)
+{
+  for (CFListIterator i= L; i.hasItem(); i++)
+  {
+    if (mod (i.getItem(), p) == 0)
+      return 0;
+  }
+  return 1;
+}
+
+
+static void
+chineseRemainder (const CFList & x1, const CanonicalForm & q1,
+                  const CFList & x2, const CanonicalForm & q2,
+                  CFList & xnew, CanonicalForm & qnew)
+{
+  ASSERT (x1.length() == x2.length(), "expected lists of equal length");
+  CanonicalForm tmp1, tmp2;
+  CFListIterator j= x2;
+  for (CFListIterator i= x1; i.hasItem() && j.hasItem(); i++, j++)
+  {
+    chineseRemainder (i.getItem(), q1, j.getItem(), q2, tmp1, tmp2);
+    xnew.append (tmp1);
+  }
+  qnew= tmp2;
+}
+
+static
+CFList Farey (const CFList& L, const CanonicalForm& q)
+{
+  CFList result;
+  for (CFListIterator i= L; i.hasItem(); i++)
+    result.append (Farey (i.getItem(), q));
+  return result;
+}
+
+static
+CFList replacevar (const CFList& L, const Variable& a, const Variable& b)
+{
+  CFList result;
+  for (CFListIterator i= L; i.hasItem(); i++)
+    result.append (replacevar (i.getItem(), a, b));
+  return result;
+}
+
+CFList
+modularDiophant (const CanonicalForm& f, const CFList& factors,
+                 const CanonicalForm& M)
+{
+  bool save_rat=!isOn (SW_RATIONAL);
+  On (SW_RATIONAL);
+  CanonicalForm F= f*bCommonDen (f);
+  CFList products= factors;
+  for (CFListIterator i= products; i.hasItem(); i++)
+  {
+    if (products.getFirst().level() == 1)
+      i.getItem() /= Lc (i.getItem());
+    i.getItem() *= bCommonDen (i.getItem());
+  }
+  if (products.getFirst().level() == 1)
+    products.insert (Lc (F));
+  CanonicalForm bound= maxNorm (F);
+  CFList leadingCoeffs;
+  leadingCoeffs.append (lc (F));
+  CanonicalForm dummy;
+  for (CFListIterator i= products; i.hasItem(); i++)
+  {
+    leadingCoeffs.append (lc (i.getItem()));
+    dummy= maxNorm (i.getItem());
+    bound= (dummy > bound) ? dummy : bound;
+  }
+  bound *= maxNorm (Lc (F))*maxNorm (Lc(F))*bound;
+  bound *= bound*bound;
+  bound= power (bound, degree (M));
+  bound *= power (CanonicalForm (2),degree (f));
+  CanonicalForm bufBound= bound;
+  int i = cf_getNumBigPrimes() - 1;
+  int p;
+  CFList resultModP, result, newResult;
+  CanonicalForm q (0), newQ;
+  bool fail= false;
+  Variable a= M.mvar();
+  Variable b= Variable (2);
+  setReduce (M.mvar(), false);
+  CanonicalForm mipo= bCommonDen (M)*M;
+  Off (SW_RATIONAL);
+  CanonicalForm modMipo;
+  leadingCoeffs.append (lc (mipo));
+  CFList tmp1, tmp2;
+  bool equal= false;
+  int count= 0;
+  do
+  {
+    p = cf_getBigPrime( i );
+    i--;
+    while ( i >= 0 && mod( leadingCoeffs, p ) == 0)
+    {
+      p = cf_getBigPrime( i );
+      i--;
+    }
+
+    ASSERT (i >= 0, "ran out of primes"); //sic
+
+    setCharacteristic (p);
+    modMipo= mapinto (mipo);
+    modMipo /= lc (modMipo);
+    resultModP= CFList();
+    tryDiophantine (resultModP, mapinto (F), mapinto (products), modMipo, fail);
+    setCharacteristic (0);
+    if (fail)
+    {
+      fail= false;
+      continue;
+    }
+
+    if ( q.isZero() )
+    {
+      result= replacevar (mapinto(resultModP), a, b);
+      q= p;
+    }
+    else
+    {
+      result= replacevar (result, a, b);
+      newResult= CFList();
+      chineseRemainder( result, q, replacevar (mapinto (resultModP), a, b),
+                        p, newResult, newQ );
+      q= newQ;
+      result= newResult;
+      if (newQ > bound)
+      {
+        count++;
+        tmp1= replacevar (Farey (result, q), b, a);
+        if (tmp2.isEmpty())
+          tmp2= tmp1;
+        else
+        {
+          equal= true;
+          CFListIterator k= tmp1;
+          for (CFListIterator j= tmp2; j.hasItem(); j++, k++)
+          {
+            if (j.getItem() != k.getItem())
+              equal= false;
+          }
+          if (!equal)
+            tmp2= tmp1;
+        }
+        if (count > 2)
+        {
+          bound *= bufBound;
+          equal= false;
+          count= 0;
+        }
+      }
+      if (newQ > bound && equal)
+      {
+        On( SW_RATIONAL );
+        CFList bufResult= result;
+        result= tmp2;
+        setReduce (M.mvar(), true);
+        if (factors.getFirst().level() == 1)
+        {
+          result.removeFirst();
+          CFListIterator j= factors;
+          CanonicalForm denf= bCommonDen (f);
+          for (CFListIterator i= result; i.hasItem(); i++, j++)
+            i.getItem() *= Lc (j.getItem())*denf;
+        }
+        if (factors.getFirst().level() != 1 &&
+            !bCommonDen (factors.getFirst()).isOne())
+        {
+          CanonicalForm denFirst= bCommonDen (factors.getFirst());
+          for (CFListIterator i= result; i.hasItem(); i++)
+            i.getItem() *= denFirst;
+        }
+
+        CanonicalForm test= 0;
+        CFListIterator jj= factors;
+        for (CFListIterator ii= result; ii.hasItem(); ii++, jj++)
+          test += ii.getItem()*(f/jj.getItem());
+        if (!test.isOne())
+        {
+          bound *= bufBound;
+          equal= false;
+          count= 0;
+          setReduce (M.mvar(), false);
+          result= bufResult;
+          Off (SW_RATIONAL);
+        }
+        else
+          break;
+      }
+    }
+  } while (1);
+  if (save_rat) Off(SW_RATIONAL);
+  return result;
+}
+
+void sortList (CFList& list, const Variable& x)
+{
+  int l= 1;
+  int k= 1;
+  CanonicalForm buf;
+  CFListIterator m;
+  for (CFListIterator i= list; l <= list.length(); i++, l++)
+  {
+    for (CFListIterator j= list; k <= list.length() - l; k++)
+    {
+      m= j;
+      m++;
+      if (degree (j.getItem(), x) > degree (m.getItem(), x))
+      {
+        buf= m.getItem();
+        m.getItem()= j.getItem();
+        j.getItem()= buf;
+        j++;
+        j.getItem()= m.getItem();
+      }
+      else
+        j++;
+    }
+    k= 1;
+  }
+}
+
+CFList
+diophantine (const CanonicalForm& F, const CFList& factors);
+
+CFList
+diophantineHensel (const CanonicalForm & F, const CFList& factors,
+                   const modpk& b)
+{
+  int p= b.getp();
+  setCharacteristic (p);
+  CFList recResult= diophantine (mapinto (F), mapinto (factors));
+  setCharacteristic (0);
+  recResult= mapinto (recResult);
+  CanonicalForm e= 1;
+  CFList L;
+  CFArray bufFactors= CFArray (factors.length());
+  int k= 0;
+  for (CFListIterator i= factors; i.hasItem(); i++, k++)
+  {
+    if (k == 0)
+      bufFactors[k]= i.getItem() (0);
+    else
+      bufFactors [k]= i.getItem();
+  }
+  CanonicalForm tmp, quot;
+  for (k= 0; k < factors.length(); k++) //TODO compute b's faster
+  {
+    tmp= 1;
+    for (int l= 0; l < factors.length(); l++)
+    {
+      if (l == k)
+        continue;
+      else
+      {
+        tmp= mulNTL (tmp, bufFactors[l]);
+      }
+    }
+    L.append (tmp);
+  }
+
+  setCharacteristic (p);
+  for (k= 0; k < factors.length(); k++)
+    bufFactors [k]= bufFactors[k].mapinto();
+  setCharacteristic(0);
+
+  CFListIterator j= L;
+  for (CFListIterator i= recResult; i.hasItem(); i++, j++)
+    e= b (e - mulNTL (i.getItem(),j.getItem(), b));
+
+  if (e.isZero())
+    return recResult;
+  CanonicalForm coeffE;
+  CFList s;
+  CFList result= recResult;
+  setCharacteristic (p);
+  recResult= mapinto (recResult);
+  setCharacteristic (0);
+  CanonicalForm g;
+  CanonicalForm modulus= p;
+  int d= b.getk();
+  modpk b2;
+  for (int i= 1; i < d; i++)
+  {
+    coeffE= div (e, modulus);
+    setCharacteristic (p);
+    coeffE= coeffE.mapinto();
+    setCharacteristic (0);
+    b2= modpk (p, d - i);
+    if (!coeffE.isZero())
+    {
+      CFListIterator k= result;
+      CFListIterator l= L;
+      int ii= 0;
+      j= recResult;
+      for (; j.hasItem(); j++, k++, l++, ii++)
+      {
+        setCharacteristic (p);
+        g= modNTL (coeffE, bufFactors[ii]);
+        g= mulNTL (g, j.getItem());
+        g= modNTL (g, bufFactors[ii]);
+        setCharacteristic (0);
+        k.getItem() += g.mapinto()*modulus;
+        e -= mulNTL (g.mapinto(), b2 (l.getItem()), b2)*modulus;
+        e= b(e);
+      }
+    }
+    modulus *= p;
+    if (e.isZero())
+      break;
+  }
+
+  return result;
+}
+
+/// solve \f$ 1=\sum_{i=1}^n{\delta_{i} \prod_{j\neq i}{f_j}} \f$ mod \f$p^k\f$
+/// over \f$ Q(\alpha) \f$ by p-adic lifting
+CFList
+diophantineHenselQa (const CanonicalForm & F, const CanonicalForm& G,
+                     const CFList& factors, modpk& b, const Variable& alpha)
+{
+  bool fail= false;
+  CFList recResult;
+  CanonicalForm modMipo, mipo;
+  //here SW_RATIONAL is off
+  On (SW_RATIONAL);
+  mipo= getMipo (alpha);
+  bool mipoHasDen= false;
+  if (!bCommonDen (mipo).isOne())
+  {
+    mipo *= bCommonDen (mipo);
+    mipoHasDen= true;
+  }
+  Off (SW_RATIONAL);
+  int p= b.getp();
+  setCharacteristic (p);
+  setReduce (alpha, false);
+  while (1)
+  {
+    setCharacteristic (p);
+    modMipo= mapinto (mipo);
+    modMipo /= lc (modMipo);
+    tryDiophantine (recResult, mapinto (F), mapinto (factors), modMipo, fail);
+    if (fail)
+    {
+      int i= 0;
+      while (cf_getBigPrime (i) < p)
+        i++;
+      findGoodPrime (F, i);
+      findGoodPrime (G, i);
+      p=cf_getBigPrime(i);
+      b = coeffBound( G, p, mipo );
+      modpk bb= coeffBound (F, p, mipo );
+      if (bb.getk() > b.getk() ) b=bb;
+      fail= false;
+    }
+    else
+      break;
+  }
+  setCharacteristic (0);
+  recResult= mapinto (recResult);
+  setReduce (alpha, true);
+  CanonicalForm e= 1;
+  CFList L;
+  CFArray bufFactors= CFArray (factors.length());
+  int k= 0;
+  for (CFListIterator i= factors; i.hasItem(); i++, k++)
+  {
+    if (k == 0)
+      bufFactors[k]= i.getItem() (0);
+    else
+      bufFactors [k]= i.getItem();
+  }
+  CanonicalForm tmp;
+  On (SW_RATIONAL);
+  for (k= 0; k < factors.length(); k++) //TODO compute b's faster
+  {
+    tmp= 1;
+    for (int l= 0; l < factors.length(); l++)
+    {
+      if (l == k)
+        continue;
+      else
+        tmp= mulNTL (tmp, bufFactors[l]);
+    }
+    L.append (tmp*bCommonDen(tmp));
+  }
+
+  Variable gamma;
+  CanonicalForm den;
+  if (mipoHasDen)
+  {
+    modMipo= getMipo (alpha);
+    den= bCommonDen (modMipo);
+    modMipo *= den;
+    Off (SW_RATIONAL);
+    setReduce (alpha, false);
+    gamma= rootOf (b (modMipo*b.inverse (den)));
+    setReduce (alpha, true);
+  }
+
+  setCharacteristic (p);
+  Variable beta;
+  Off (SW_RATIONAL);
+  setReduce (alpha, false);
+  modMipo= modMipo.mapinto();
+  modMipo /= lc (modMipo);
+  beta= rootOf (modMipo);
+  setReduce (alpha, true);
+
+  setReduce (alpha, false);
+  for (k= 0; k < factors.length(); k++)
+  {
+    bufFactors [k]= bufFactors[k].mapinto();
+    bufFactors [k]= replacevar (bufFactors[k], alpha, beta);
+  }
+  setReduce (alpha, true);
+  setCharacteristic(0);
+
+  CFListIterator j= L;
+  for (;j.hasItem(); j++)
+  {
+    if (mipoHasDen)
+      j.getItem()= replacevar (b(j.getItem()*b.inverse(lc(j.getItem()))),
+                               alpha, gamma);
+    else
+      j.getItem()= b(j.getItem()*b.inverse(lc(j.getItem())));
+  }
+  j= L;
+  for (CFListIterator i= recResult; i.hasItem(); i++, j++)
+  {
+    if (mipoHasDen)
+      e= b (e - mulNTL (replacevar (i.getItem(), alpha, gamma),j.getItem(), b));
+    else
+      e= b (e - mulNTL (i.getItem(), j.getItem(), b));
+  }
+
+  if (e.isZero())
+  {
+    if (mipoHasDen)
+    {
+      for (CFListIterator i= recResult; i.hasItem(); i++)
+        i.getItem()= replacevar (i.getItem(), alpha, gamma);
+    }
+    return recResult;
+  }
+  CanonicalForm coeffE;
+  CFList result= recResult;
+  if (mipoHasDen)
+  {
+    for (CFListIterator i= result; i.hasItem(); i++)
+      i.getItem()= replacevar (i.getItem(), alpha, gamma);
+  }
+  setCharacteristic (p);
+  setReduce (alpha, false);
+  recResult= mapinto (recResult);
+  setReduce (alpha, true);
+
+  for (CFListIterator i= recResult; i.hasItem(); i++)
+    i.getItem()= replacevar (i.getItem(), alpha, beta);
+
+  setCharacteristic (0);
+  CanonicalForm g;
+  CanonicalForm modulus= p;
+  int d= b.getk();
+  modpk b2;
+  for (int i= 1; i < d; i++)
+  {
+    coeffE= div (e, modulus);
+    setCharacteristic (p);
+    if (mipoHasDen)
+      setReduce (gamma, false);
+    else
+      setReduce (alpha, false);
+    coeffE= coeffE.mapinto();
+    if (mipoHasDen)
+      setReduce (gamma, true);
+    else
+      setReduce (alpha, true);
+    if (mipoHasDen)
+      coeffE= replacevar (coeffE, gamma, beta);
+    else
+      coeffE= replacevar (coeffE, alpha, beta);
+    setCharacteristic (0);
+    b2= modpk (p, d - i);
+    if (!coeffE.isZero())
+    {
+      CFListIterator k= result;
+      CFListIterator l= L;
+      int ii= 0;
+      j= recResult;
+      for (; j.hasItem(); j++, k++, l++, ii++)
+      {
+        setCharacteristic (p);
+        g= modNTL (coeffE, bufFactors[ii]);
+        g= mulNTL (g, j.getItem());
+        g= modNTL (g, bufFactors[ii]);
+        setCharacteristic (0);
+        if (mipoHasDen)
+        {
+          setReduce (beta, false);
+          k.getItem() += replacevar (g.mapinto()*modulus, beta, gamma);
+          e -= mulNTL (replacevar (g.mapinto(), beta, gamma),
+                       b2 (l.getItem()), b2)*modulus;
+          setReduce (beta, true);
+        }
+        else
+        {
+          setReduce (beta, false);
+          k.getItem() += replacevar (g.mapinto()*modulus, beta, alpha);
+          e -= mulNTL (replacevar (g.mapinto(), beta, alpha),
+                       b2 (l.getItem()), b2)*modulus;
+          setReduce (beta, true);
+        }
+        e= b(e);
+      }
+    }
+    modulus *= p;
+    if (e.isZero())
+      break;
+  }
+
+  return result;
+}
+
+
+/// solve \f$ 1=\sum_{i=1}^n{\delta_{i} \prod_{j\neq i}{f_j}} \f$ mod \f$p^k\f$
+/// over \f$ Q(\alpha) \f$ by first computing mod \f$p\f$ and if no zero divisor
+/// occured compute it mod \f$p^k\f$
+CFList
+diophantineQa (const CanonicalForm& F, const CanonicalForm& G,
+               const CFList& factors, modpk& b, const Variable& alpha)
+{
+  bool fail= false;
+  CFList recResult;
+  CanonicalForm modMipo, mipo;
+  //here SW_RATIONAL is off
+  On (SW_RATIONAL);
+  mipo= getMipo (alpha);
+  bool mipoHasDen= false;
+  if (!bCommonDen (mipo).isOne())
+  {
+    mipo *= bCommonDen (mipo);
+    mipoHasDen= true;
+  }
+  Off (SW_RATIONAL);
+  int p= b.getp();
+  setCharacteristic (p);
+  setReduce (alpha, false);
+  while (1)
+  {
+    setCharacteristic (p);
+    modMipo= mapinto (mipo);
+    modMipo /= lc (modMipo);
+    tryDiophantine (recResult, mapinto (F), mapinto (factors), modMipo, fail);
+    if (fail)
+    {
+      int i= 0;
+      while (cf_getBigPrime (i) < p)
+        i++;
+      findGoodPrime (F, i);
+      findGoodPrime (G, i);
+      p=cf_getBigPrime(i);
+      b = coeffBound( G, p, mipo );
+      modpk bb= coeffBound (F, p, mipo );
+      if (bb.getk() > b.getk() ) b=bb;
+      fail= false;
+    }
+    else
+      break;
+  }
+  setReduce (alpha, true);
+  setCharacteristic (0);
+
+  Variable gamma= alpha;
+  CanonicalForm den;
+  if (mipoHasDen)
+  {
+    On (SW_RATIONAL);
+    modMipo= getMipo (alpha);
+    den= bCommonDen (modMipo);
+    modMipo *= den;
+    Off (SW_RATIONAL);
+    setReduce (alpha, false);
+    gamma= rootOf (b (modMipo*b.inverse (den)));
+    setReduce (alpha, true);
+  }
+
+  Variable x= Variable (1);
+  CanonicalForm buf1, buf2, buf3, S;
+  CFList bufFactors= factors;
+  CFListIterator i= bufFactors;
+  if (mipoHasDen)
+  {
+    for (; i.hasItem(); i++)
+      i.getItem()= replacevar (i.getItem(), alpha, gamma);
+  }
+  i= bufFactors;
+  CFList result;
+  if (i.hasItem())
+    i++;
+  buf1= 0;
+  CanonicalForm Freplaced;
+  if (mipoHasDen)
+  {
+    Freplaced= replacevar (F, alpha, gamma);
+    buf2= divNTL (Freplaced, replacevar (i.getItem(), alpha, gamma), b);
+  }
+  else
+    buf2= divNTL (F, i.getItem(), b);
+  ZZ_p::init (convertFacCF2NTLZZ (b.getpk()));
+  ZZ_pX NTLmipo= to_ZZ_pX (convertFacCF2NTLZZX (getMipo (gamma)));
+  ZZ_pE::init (NTLmipo);
+  ZZ_pEX NTLS, NTLT, NTLbuf3;
+  ZZ_pEX NTLbuf1= convertFacCF2NTLZZ_pEX (buf1, NTLmipo);
+  ZZ_pEX NTLbuf2= convertFacCF2NTLZZ_pEX (buf2, NTLmipo);
+  XGCD (NTLbuf3, NTLS, NTLT, NTLbuf1, NTLbuf2);
+  result.append (b (convertNTLZZ_pEX2CF (NTLS, x, gamma)));
+  result.append (b (convertNTLZZ_pEX2CF (NTLT, x, gamma)));
+  if (i.hasItem())
+    i++;
+  for (; i.hasItem(); i++)
+  {
+    if (mipoHasDen)
+      buf1= divNTL (Freplaced, i.getItem(), b);
+    else
+      buf1= divNTL (F, i.getItem(), b);
+    XGCD (NTLbuf3, NTLS, NTLT, NTLbuf3, convertFacCF2NTLZZ_pEX (buf1, NTLmipo));
+    CFListIterator k= bufFactors;
+    S= convertNTLZZ_pEX2CF (NTLS, x, gamma);
+    for (CFListIterator j= result; j.hasItem(); j++, k++)
+    {
+      j.getItem()= mulNTL (j.getItem(), S, b);
+      j.getItem()= modNTL (j.getItem(), k.getItem(), b);
+    }
+    result.append (b (convertNTLZZ_pEX2CF (NTLT, x, gamma)));
+  }
+  return result;
+}
+
+CFList
+diophantine (const CanonicalForm& F, const CanonicalForm& G,
+             const CFList& factors, modpk& b)
+{
+  if (getCharacteristic() == 0)
+  {
+    Variable v;
+    bool hasAlgVar= hasFirstAlgVar (F, v);
+    for (CFListIterator i= factors; i.hasItem() && !hasAlgVar; i++)
+      hasAlgVar= hasFirstAlgVar (i.getItem(), v);
+    if (hasAlgVar)
+    {
+      if (b.getp() != 0)
+      {
+        CFList result= diophantineQa (F, G, factors, b, v);
+        return result;
+      }
+      CFList result= modularDiophant (F, factors, getMipo (v));
+      return result;
+    }
+    if (b.getp() != 0)
+      return diophantineHensel (F, factors, b);
+  }
+
+  CanonicalForm buf1, buf2, buf3, S, T;
+  CFListIterator i= factors;
+  CFList result;
+  if (i.hasItem())
+    i++;
+  buf1= F/factors.getFirst();
+  buf2= divNTL (F, i.getItem());
+  buf3= extgcd (buf1, buf2, S, T);
+  result.append (S);
+  result.append (T);
+  if (i.hasItem())
+    i++;
+  for (; i.hasItem(); i++)
+  {
+    buf1= divNTL (F, i.getItem());
+    buf3= extgcd (buf3, buf1, S, T);
+    CFListIterator k= factors;
+    for (CFListIterator j= result; j.hasItem(); j++, k++)
+    {
+      j.getItem()= mulNTL (j.getItem(), S);
+      j.getItem()= modNTL (j.getItem(), k.getItem());
+    }
+    result.append (T);
+  }
+  return result;
+}
+
+CFList
+diophantine (const CanonicalForm& F, const CFList& factors)
+{
+  modpk b= modpk();
+  return diophantine (F, 1, factors, b);
+}
+
+void
+henselStep12 (const CanonicalForm& F, const CFList& factors,
+              CFArray& bufFactors, const CFList& diophant, CFMatrix& M,
+              CFArray& Pi, int j, const modpk& b)
+{
+  CanonicalForm E;
+  CanonicalForm xToJ= power (F.mvar(), j);
+  Variable x= F.mvar();
+  // compute the error
+  if (j == 1)
+    E= F[j];
+  else
+  {
+    if (degree (Pi [factors.length() - 2], x) > 0)
+      E= F[j] - Pi [factors.length() - 2] [j];
+    else
+      E= F[j];
+  }
+
+  if (b.getp() != 0)
+    E= b(E);
+  CFArray buf= CFArray (diophant.length());
+  bufFactors[0]= mod (factors.getFirst(), power (F.mvar(), j + 1));
+  int k= 0;
+  CanonicalForm remainder;
+  // actual lifting
+  for (CFListIterator i= diophant; i.hasItem(); i++, k++)
+  {
+    if (degree (bufFactors[k], x) > 0)
+    {
+      if (k > 0)
+        remainder= modNTL (E, bufFactors[k] [0], b); //TODO precompute inverses of bufFactors[k][0]
+      else
+        remainder= E;
+    }
+    else
+      remainder= modNTL (E, bufFactors[k], b);
+
+    buf[k]= mulNTL (i.getItem(), remainder, b);
+    if (degree (bufFactors[k], x) > 0)
+      buf[k]= modNTL (buf[k], bufFactors[k] [0], b);
+    else
+      buf[k]= modNTL (buf[k], bufFactors[k], b);
+  }
+  for (k= 1; k < factors.length(); k++)
+  {
+    bufFactors[k] += xToJ*buf[k];
+    if (b.getp() != 0)
+      bufFactors[k]= b(bufFactors[k]);
+  }
+
+  // update Pi [0]
+  int degBuf0= degree (bufFactors[0], x);
+  int degBuf1= degree (bufFactors[1], x);
+  if (degBuf0 > 0 && degBuf1 > 0)
+    M (j + 1, 1)= mulNTL (bufFactors[0] [j], bufFactors[1] [j], b);
+  CanonicalForm uIZeroJ;
+
+  if (degBuf0 > 0 && degBuf1 > 0)
+    uIZeroJ= mulNTL ((bufFactors[0] [0] + bufFactors[0] [j]),
+                    (bufFactors[1] [0] + buf[1]), b) - M(1, 1) - M(j + 1, 1);
+  else if (degBuf0 > 0)
+    uIZeroJ= mulNTL (bufFactors[0] [j], bufFactors[1], b);
+  else if (degBuf1 > 0)
+    uIZeroJ= mulNTL (bufFactors[0], buf[1], b);
+  else
+    uIZeroJ= 0;
+  if (b.getp() != 0)
+    uIZeroJ= b (uIZeroJ);
+  Pi [0] += xToJ*uIZeroJ;
+  if (b.getp() != 0)
+    Pi [0]= b (Pi[0]);
+
+  CFArray tmp= CFArray (factors.length() - 1);
+  for (k= 0; k < factors.length() - 1; k++)
+    tmp[k]= 0;
+  CFIterator one, two;
+  one= bufFactors [0];
+  two= bufFactors [1];
+  if (degBuf0 > 0 && degBuf1 > 0)
+  {
+    for (k= 1; k <= (int) ceil (j/2.0); k++)
+    {
+      if (k != j - k + 1)
+      {
+        if ((one.hasTerms() && one.exp() == j - k + 1)
+             && (two.hasTerms() && two.exp() == j - k + 1))
+        {
+          tmp[0] += mulNTL ((bufFactors[0][k]+one.coeff()), (bufFactors[1][k]+
+                     two.coeff()), b) - M (k + 1, 1) - M (j - k + 2, 1);
+          one++;
+          two++;
+        }
+        else if (one.hasTerms() && one.exp() == j - k + 1)
+        {
+          tmp[0] += mulNTL ((bufFactors[0][k]+one.coeff()), bufFactors[1][k], b)
+                    - M (k + 1, 1);
+          one++;
+        }
+        else if (two.hasTerms() && two.exp() == j - k + 1)
+        {
+          tmp[0] += mulNTL (bufFactors[0][k], (bufFactors[1][k]+two.coeff()), b)
+                    - M (k + 1, 1);
+          two++;
+        }
+      }
+      else
+      {
+        tmp[0] += M (k + 1, 1);
+      }
+    }
+  }
+  if (b.getp() != 0)
+    tmp[0]= b (tmp[0]);
+  Pi [0] += tmp[0]*xToJ*F.mvar();
+
+  // update Pi [l]
+  int degPi, degBuf;
+  for (int l= 1; l < factors.length() - 1; l++)
+  {
+    degPi= degree (Pi [l - 1], x);
+    degBuf= degree (bufFactors[l + 1], x);
+    if (degPi > 0 && degBuf > 0)
+      M (j + 1, l + 1)= mulNTL (Pi [l - 1] [j], bufFactors[l + 1] [j], b);
+    if (j == 1)
+    {
+      if (degPi > 0 && degBuf > 0)
+        Pi [l] += xToJ*(mulNTL (Pi [l - 1] [0] + Pi [l - 1] [j],
+                  bufFactors[l + 1] [0] + buf[l + 1], b) - M (j + 1, l +1) -
+                  M (1, l + 1));
+      else if (degPi > 0)
+        Pi [l] += xToJ*(mulNTL (Pi [l - 1] [j], bufFactors[l + 1], b));
+      else if (degBuf > 0)
+        Pi [l] += xToJ*(mulNTL (Pi [l - 1], buf[l + 1], b));
+    }
+    else
+    {
+      if (degPi > 0 && degBuf > 0)
+      {
+        uIZeroJ= mulNTL (uIZeroJ, bufFactors [l + 1] [0], b);
+        uIZeroJ += mulNTL (Pi [l - 1] [0], buf [l + 1], b);
+      }
+      else if (degPi > 0)
+        uIZeroJ= mulNTL (uIZeroJ, bufFactors [l + 1], b);
+      else if (degBuf > 0)
+      {
+        uIZeroJ= mulNTL (uIZeroJ, bufFactors [l + 1] [0], b);
+        uIZeroJ += mulNTL (Pi [l - 1], buf[l + 1], b);
+      }
+      Pi[l] += xToJ*uIZeroJ;
+    }
+    one= bufFactors [l + 1];
+    two= Pi [l - 1];
+    if (two.hasTerms() && two.exp() == j + 1)
+    {
+      if (degBuf > 0 && degPi > 0)
+      {
+          tmp[l] += mulNTL (two.coeff(), bufFactors[l + 1][0], b);
+          two++;
+      }
+      else if (degPi > 0)
+      {
+          tmp[l] += mulNTL (two.coeff(), bufFactors[l + 1], b);
+          two++;
+      }
+    }
+    if (degBuf > 0 && degPi > 0)
+    {
+      for (k= 1; k <= (int) ceil (j/2.0); k++)
+      {
+        if (k != j - k + 1)
+        {
+          if ((one.hasTerms() && one.exp() == j - k + 1) &&
+              (two.hasTerms() && two.exp() == j - k + 1))
+          {
+            tmp[l] += mulNTL ((bufFactors[l+1][k] + one.coeff()), (Pi[l-1][k] +
+                      two.coeff()),b) - M (k + 1, l + 1) - M (j - k + 2, l + 1);
+            one++;
+            two++;
+          }
+          else if (one.hasTerms() && one.exp() == j - k + 1)
+          {
+            tmp[l] += mulNTL ((bufFactors[l+1][k]+one.coeff()), Pi[l-1][k], b) -
+                       M (k + 1, l + 1);
+            one++;
+          }
+          else if (two.hasTerms() && two.exp() == j - k + 1)
+          {
+            tmp[l] += mulNTL (bufFactors[l+1][k], (Pi[l-1][k] + two.coeff()), b)
+                      - M (k + 1, l + 1);
+            two++;
+          }
+        }
+        else
+          tmp[l] += M (k + 1, l + 1);
+      }
+    }
+    if (b.getp() != 0)
+      tmp[l]= b (tmp[l]);
+    Pi[l] += tmp[l]*xToJ*F.mvar();
+  }
+}
+
+void
+henselLift12 (const CanonicalForm& F, CFList& factors, int l, CFArray& Pi,
+              CFList& diophant, CFMatrix& M, modpk& b, bool sort)
+{
+  if (sort)
+    sortList (factors, Variable (1));
+  Pi= CFArray (factors.length() - 1);
+  CFListIterator j= factors;
+  diophant= diophantine (F[0], F, factors, b);
+  CanonicalForm bufF= F;
+  if (getCharacteristic() == 0 && b.getp() != 0)
+  {
+    Variable v;
+    bool hasAlgVar= hasFirstAlgVar (F, v);
+    for (CFListIterator i= factors; i.hasItem() && !hasAlgVar; i++)
+      hasAlgVar= hasFirstAlgVar (i.getItem(), v);
+    Variable w;
+    bool hasAlgVar2= false;
+    for (CFListIterator i= diophant; i.hasItem() && !hasAlgVar2; i++)
+      hasAlgVar2= hasFirstAlgVar (i.getItem(), w);
+    if (hasAlgVar && hasAlgVar2 && v!=w)
+    {
+      bufF= replacevar (bufF, v, w);
+      for (CFListIterator i= factors; i.hasItem(); i++)
+        i.getItem()= replacevar (i.getItem(), v, w);
+    }
+  }
+
+  DEBOUTLN (cerr, "diophant= " << diophant);
+  j++;
+  Pi [0]= mulNTL (j.getItem(), mod (factors.getFirst(), F.mvar()), b);
+  M (1, 1)= Pi [0];
+  int i= 1;
+  if (j.hasItem())
+    j++;
+  for (; j.hasItem(); j++, i++)
+  {
+    Pi [i]= mulNTL (Pi [i - 1], j.getItem(), b);
+    M (1, i + 1)= Pi [i];
+  }
+  CFArray bufFactors= CFArray (factors.length());
+  i= 0;
+  for (CFListIterator k= factors; k.hasItem(); i++, k++)
+  {
+    if (i == 0)
+      bufFactors[i]= mod (k.getItem(), F.mvar());
+    else
+      bufFactors[i]= k.getItem();
+  }
+  for (i= 1; i < l; i++)
+    henselStep12 (bufF, factors, bufFactors, diophant, M, Pi, i, b);
+
+  CFListIterator k= factors;
+  for (i= 0; i < factors.length (); i++, k++)
+    k.getItem()= bufFactors[i];
+  factors.removeFirst();
+}
+
+void
+henselLift12 (const CanonicalForm& F, CFList& factors, int l, CFArray& Pi,
+              CFList& diophant, CFMatrix& M, bool sort)
+{
+  modpk dummy= modpk();
+  henselLift12 (F, factors, l, Pi, diophant, M, dummy, sort);
+}
+
+void
+henselLiftResume12 (const CanonicalForm& F, CFList& factors, int start, int
+                    end, CFArray& Pi, const CFList& diophant, CFMatrix& M,
+                    const modpk& b)
+{
+  CFArray bufFactors= CFArray (factors.length());
+  int i= 0;
+  CanonicalForm xToStart= power (F.mvar(), start);
+  for (CFListIterator k= factors; k.hasItem(); k++, i++)
+  {
+    if (i == 0)
+      bufFactors[i]= mod (k.getItem(), xToStart);
+    else
+      bufFactors[i]= k.getItem();
+  }
+  for (i= start; i < end; i++)
+    henselStep12 (F, factors, bufFactors, diophant, M, Pi, i, b);
+
+  CFListIterator k= factors;
+  for (i= 0; i < factors.length(); k++, i++)
+    k.getItem()= bufFactors [i];
+  factors.removeFirst();
+  return;
+}
+
+CFList
+biDiophantine (const CanonicalForm& F, const CFList& factors, int d)
+{
+  Variable y= F.mvar();
+  CFList result;
+  if (y.level() == 1)
+  {
+    result= diophantine (F, factors);
+    return result;
+  }
+  else
+  {
+    CFList buf= factors;
+    for (CFListIterator i= buf; i.hasItem(); i++)
+      i.getItem()= mod (i.getItem(), y);
+    CanonicalForm A= mod (F, y);
+    int bufD= 1;
+    CFList recResult= biDiophantine (A, buf, bufD);
+    CanonicalForm e= 1;
+    CFList p;
+    CFArray bufFactors= CFArray (factors.length());
+    CanonicalForm yToD= power (y, d);
+    int k= 0;
+    for (CFListIterator i= factors; i.hasItem(); i++, k++)
+    {
+      bufFactors [k]= i.getItem();
+    }
+    CanonicalForm b, quot;
+    for (k= 0; k < factors.length(); k++) //TODO compute b's faster
+    {
+      b= 1;
+      if (fdivides (bufFactors[k], F, quot))
+        b= quot;
+      else
+      {
+        for (int l= 0; l < factors.length(); l++)
+        {
+          if (l == k)
+            continue;
+          else
+          {
+            b= mulMod2 (b, bufFactors[l], yToD);
+          }
+        }
+      }
+      p.append (b);
+    }
+
+    CFListIterator j= p;
+    for (CFListIterator i= recResult; i.hasItem(); i++, j++)
+      e -= i.getItem()*j.getItem();
+
+    if (e.isZero())
+      return recResult;
+    CanonicalForm coeffE;
+    CFList s;
+    result= recResult;
+    CanonicalForm g;
+    for (int i= 1; i < d; i++)
+    {
+      if (degree (e, y) > 0)
+        coeffE= e[i];
+      else
+        coeffE= 0;
+      if (!coeffE.isZero())
+      {
+        CFListIterator k= result;
+        CFListIterator l= p;
+        int ii= 0;
+        j= recResult;
+        for (; j.hasItem(); j++, k++, l++, ii++)
+        {
+          g= coeffE*j.getItem();
+          if (degree (bufFactors[ii], y) <= 0)
+            g= mod (g, bufFactors[ii]);
+          else
+            g= mod (g, bufFactors[ii][0]);
+          k.getItem() += g*power (y, i);
+          e -= mulMod2 (g*power(y, i), l.getItem(), yToD);
+          DEBOUTLN (cerr, "mod (e, power (y, i + 1))= " <<
+                    mod (e, power (y, i + 1)));
+        }
+      }
+      if (e.isZero())
+        break;
+    }
+
+    DEBOUTLN (cerr, "mod (e, y)= " << mod (e, y));
+
+#ifdef DEBUGOUTPUT
+    CanonicalForm test= 0;
+    j= p;
+    for (CFListIterator i= result; i.hasItem(); i++, j++)
+      test += mod (i.getItem()*j.getItem(), power (y, d));
+    DEBOUTLN (cerr, "test= " << test);
+#endif
+    return result;
+  }
+}
+
+CFList
+multiRecDiophantine (const CanonicalForm& F, const CFList& factors,
+                     const CFList& recResult, const CFList& M, int d)
+{
+  Variable y= F.mvar();
+  CFList result;
+  CFListIterator i;
+  CanonicalForm e= 1;
+  CFListIterator j= factors;
+  CFList p;
+  CFArray bufFactors= CFArray (factors.length());
+  CanonicalForm yToD= power (y, d);
+  int k= 0;
+  for (CFListIterator i= factors; i.hasItem(); i++, k++)
+    bufFactors [k]= i.getItem();
+  CanonicalForm b, quot;
+  CFList buf= M;
+  buf.removeLast();
+  buf.append (yToD);
+  for (k= 0; k < factors.length(); k++) //TODO compute b's faster
+  {
+    b= 1;
+    if (fdivides (bufFactors[k], F, quot))
+      b= quot;
+    else
+    {
+      for (int l= 0; l < factors.length(); l++)
+      {
+        if (l == k)
+          continue;
+        else
+        {
+          b= mulMod (b, bufFactors[l], buf);
+        }
+      }
+    }
+    p.append (b);
+  }
+  j= p;
+  for (CFListIterator i= recResult; i.hasItem(); i++, j++)
+    e -= mulMod (i.getItem(), j.getItem(), M);
+
+  if (e.isZero())
+    return recResult;
+  CanonicalForm coeffE;
+  CFList s;
+  result= recResult;
+  CanonicalForm g;
+  for (int i= 1; i < d; i++)
+  {
+    if (degree (e, y) > 0)
+      coeffE= e[i];
+    else
+      coeffE= 0;
+    if (!coeffE.isZero())
+    {
+      CFListIterator k= result;
+      CFListIterator l= p;
+      j= recResult;
+      int ii= 0;
+      CanonicalForm dummy;
+      for (; j.hasItem(); j++, k++, l++, ii++)
+      {
+        g= mulMod (coeffE, j.getItem(), M);
+        if (degree (bufFactors[ii], y) <= 0)
+          divrem (g, mod (bufFactors[ii], Variable (y.level() - 1)), dummy,
+                  g, M);
+        else
+          divrem (g, bufFactors[ii][0], dummy, g, M);
+        k.getItem() += g*power (y, i);
+        e -= mulMod (g*power (y, i), l.getItem(), M);
+      }
+    }
+
+    if (e.isZero())
+      break;
+  }
+
+#ifdef DEBUGOUTPUT
+    CanonicalForm test= 0;
+    j= p;
+    for (CFListIterator i= result; i.hasItem(); i++, j++)
+      test += mod (i.getItem()*j.getItem(), power (y, d));
+    DEBOUTLN (cerr, "test in multiRecDiophantine= " << test);
+#endif
+  return result;
+}
+
+static
+void
+henselStep (const CanonicalForm& F, const CFList& factors, CFArray& bufFactors,
+            const CFList& diophant, CFMatrix& M, CFArray& Pi, int j,
+            const CFList& MOD)
+{
+  CanonicalForm E;
+  CanonicalForm xToJ= power (F.mvar(), j);
+  Variable x= F.mvar();
+  // compute the error
+  if (j == 1)
+  {
+    E= F[j];
+#ifdef DEBUGOUTPUT
+    CanonicalForm test= 1;
+    for (int i= 0; i < factors.length(); i++)
+    {
+      if (i == 0)
+        test= mulMod (test, mod (bufFactors [i], xToJ), MOD);
+      else
+        test= mulMod (test, bufFactors[i], MOD);
+    }
+    CanonicalForm test2= mod (F-test, xToJ);
+
+    test2= mod (test2, MOD);
+    DEBOUTLN (cerr, "test in henselStep= " << test2);
+#endif
+  }
+  else
+  {
+#ifdef DEBUGOUTPUT
+    CanonicalForm test= 1;
+    for (int i= 0; i < factors.length(); i++)
+    {
+      if (i == 0)
+        test *= mod (bufFactors [i], power (x, j));
+      else
+        test *= bufFactors[i];
+    }
+    test= mod (test, power (x, j));
+    test= mod (test, MOD);
+    CanonicalForm test2= mod (F, power (x, j - 1)) - mod (test, power (x, j-1));
+    DEBOUTLN (cerr, "test in henselStep= " << test2);
+#endif
+
+    if (degree (Pi [factors.length() - 2], x) > 0)
+      E= F[j] - Pi [factors.length() - 2] [j];
+    else
+      E= F[j];
+  }
+
+  CFArray buf= CFArray (diophant.length());
+  bufFactors[0]= mod (factors.getFirst(), power (F.mvar(), j + 1));
+  int k= 0;
+  // actual lifting
+  CanonicalForm dummy, rest1;
+  for (CFListIterator i= diophant; i.hasItem(); i++, k++)
+  {
+    if (degree (bufFactors[k], x) > 0)
+    {
+      if (k > 0)
+        divrem (E, bufFactors[k] [0], dummy, rest1, MOD);
+      else
+        rest1= E;
+    }
+    else
+      divrem (E, bufFactors[k], dummy, rest1, MOD);
+
+    buf[k]= mulMod (i.getItem(), rest1, MOD);
+
+    if (degree (bufFactors[k], x) > 0)
+      divrem (buf[k], bufFactors[k] [0], dummy, buf[k], MOD);
+    else
+      divrem (buf[k], bufFactors[k], dummy, buf[k], MOD);
+  }
+  for (k= 1; k < factors.length(); k++)
+    bufFactors[k] += xToJ*buf[k];
+
+  // update Pi [0]
+  int degBuf0= degree (bufFactors[0], x);
+  int degBuf1= degree (bufFactors[1], x);
+  if (degBuf0 > 0 && degBuf1 > 0)
+    M (j + 1, 1)= mulMod (bufFactors[0] [j], bufFactors[1] [j], MOD);
+  CanonicalForm uIZeroJ;
+
+  if (degBuf0 > 0 && degBuf1 > 0)
+    uIZeroJ= mulMod ((bufFactors[0] [0] + bufFactors[0] [j]),
+                  (bufFactors[1] [0] + buf[1]), MOD) - M(1, 1) - M(j + 1, 1);
+  else if (degBuf0 > 0)
+    uIZeroJ= mulMod (bufFactors[0] [j], bufFactors[1], MOD);
+  else if (degBuf1 > 0)
+    uIZeroJ= mulMod (bufFactors[0], buf[1], MOD);
+  else
+    uIZeroJ= 0;
+  Pi [0] += xToJ*uIZeroJ;
+
+  CFArray tmp= CFArray (factors.length() - 1);
+  for (k= 0; k < factors.length() - 1; k++)
+    tmp[k]= 0;
+  CFIterator one, two;
+  one= bufFactors [0];
+  two= bufFactors [1];
+  if (degBuf0 > 0 && degBuf1 > 0)
+  {
+    for (k= 1; k <= (int) ceil (j/2.0); k++)
+    {
+      if (k != j - k + 1)
+      {
+        if ((one.hasTerms() && one.exp() == j - k + 1) &&
+            (two.hasTerms() && two.exp() == j - k + 1))
+        {
+          tmp[0] += mulMod ((bufFactors[0] [k] + one.coeff()),
+                    (bufFactors[1] [k] + two.coeff()), MOD) - M (k + 1, 1) -
+                    M (j - k + 2, 1);
+          one++;
+          two++;
+        }
+        else if (one.hasTerms() && one.exp() == j - k + 1)
+        {
+          tmp[0] += mulMod ((bufFactors[0] [k] + one.coeff()),
+                    bufFactors[1] [k], MOD) - M (k + 1, 1);
+          one++;
+        }
+        else if (two.hasTerms() && two.exp() == j - k + 1)
+        {
+          tmp[0] += mulMod (bufFactors[0] [k], (bufFactors[1] [k] +
+                    two.coeff()), MOD) - M (k + 1, 1);
+          two++;
+        }
+      }
+      else
+      {
+        tmp[0] += M (k + 1, 1);
+      }
+    }
+  }
+  Pi [0] += tmp[0]*xToJ*F.mvar();
+
+  // update Pi [l]
+  int degPi, degBuf;
+  for (int l= 1; l < factors.length() - 1; l++)
+  {
+    degPi= degree (Pi [l - 1], x);
+    degBuf= degree (bufFactors[l + 1], x);
+    if (degPi > 0 && degBuf > 0)
+      M (j + 1, l + 1)= mulMod (Pi [l - 1] [j], bufFactors[l + 1] [j], MOD);
+    if (j == 1)
+    {
+      if (degPi > 0 && degBuf > 0)
+        Pi [l] += xToJ*(mulMod ((Pi [l - 1] [0] + Pi [l - 1] [j]),
+                  (bufFactors[l + 1] [0] + buf[l + 1]), MOD) - M (j + 1, l +1)-
+                  M (1, l + 1));
+      else if (degPi > 0)
+        Pi [l] += xToJ*(mulMod (Pi [l - 1] [j], bufFactors[l + 1], MOD));
+      else if (degBuf > 0)
+        Pi [l] += xToJ*(mulMod (Pi [l - 1], buf[l + 1], MOD));
+    }
+    else
+    {
+      if (degPi > 0 && degBuf > 0)
+      {
+        uIZeroJ= mulMod (uIZeroJ, bufFactors [l + 1] [0], MOD);
+        uIZeroJ += mulMod (Pi [l - 1] [0], buf [l + 1], MOD);
+      }
+      else if (degPi > 0)
+        uIZeroJ= mulMod (uIZeroJ, bufFactors [l + 1], MOD);
+      else if (degBuf > 0)
+      {
+        uIZeroJ= mulMod (uIZeroJ, bufFactors [l + 1] [0], MOD);
+        uIZeroJ += mulMod (Pi [l - 1], buf[l + 1], MOD);
+      }
+      Pi[l] += xToJ*uIZeroJ;
+    }
+    one= bufFactors [l + 1];
+    two= Pi [l - 1];
+    if (two.hasTerms() && two.exp() == j + 1)
+    {
+      if (degBuf > 0 && degPi > 0)
+      {
+          tmp[l] += mulMod (two.coeff(), bufFactors[l + 1][0], MOD);
+          two++;
+      }
+      else if (degPi > 0)
+      {
+          tmp[l] += mulMod (two.coeff(), bufFactors[l + 1], MOD);
+          two++;
+      }
+    }
+    if (degBuf > 0 && degPi > 0)
+    {
+      for (k= 1; k <= (int) ceil (j/2.0); k++)
+      {
+        if (k != j - k + 1)
+        {
+          if ((one.hasTerms() && one.exp() == j - k + 1) &&
+              (two.hasTerms() && two.exp() == j - k + 1))
+          {
+            tmp[l] += mulMod ((bufFactors[l + 1] [k] + one.coeff()),
+                      (Pi[l - 1] [k] + two.coeff()), MOD) - M (k + 1, l + 1) -
+                      M (j - k + 2, l + 1);
+            one++;
+            two++;
+          }
+          else if (one.hasTerms() && one.exp() == j - k + 1)
+          {
+            tmp[l] += mulMod ((bufFactors[l + 1] [k] + one.coeff()),
+                      Pi[l - 1] [k], MOD) - M (k + 1, l + 1);
+            one++;
+          }
+          else if (two.hasTerms() && two.exp() == j - k + 1)
+          {
+            tmp[l] += mulMod (bufFactors[l + 1] [k],
+                      (Pi[l - 1] [k] + two.coeff()), MOD) - M (k + 1, l + 1);
+            two++;
+          }
+        }
+        else
+          tmp[l] += M (k + 1, l + 1);
+      }
+    }
+    Pi[l] += tmp[l]*xToJ*F.mvar();
+  }
+
+  return;
+}
+
+CFList
+henselLift23 (const CFList& eval, const CFList& factors, int* l, CFList&
+              diophant, CFArray& Pi, CFMatrix& M)
+{
+  CFList buf= factors;
+  int k= 0;
+  int liftBoundBivar= l[k];
+  diophant= biDiophantine (eval.getFirst(), buf, liftBoundBivar);
+  CFList MOD;
+  MOD.append (power (Variable (2), liftBoundBivar));
+  CFArray bufFactors= CFArray (factors.length());
+  k= 0;
+  CFListIterator j= eval;
+  j++;
+  buf.removeFirst();
+  buf.insert (LC (j.getItem(), 1));
+  for (CFListIterator i= buf; i.hasItem(); i++, k++)
+    bufFactors[k]= i.getItem();
+  Pi= CFArray (factors.length() - 1);
+  CFListIterator i= buf;
+  i++;
+  Variable y= j.getItem().mvar();
+  Pi [0]= mulMod (i.getItem(), mod (buf.getFirst(), y), MOD);
+  M (1, 1)= Pi [0];
+  k= 1;
+  if (i.hasItem())
+    i++;
+  for (; i.hasItem(); i++, k++)
+  {
+    Pi [k]= mulMod (Pi [k - 1], i.getItem(), MOD);
+    M (1, k + 1)= Pi [k];
+  }
+
+  for (int d= 1; d < l[1]; d++)
+    henselStep (j.getItem(), buf, bufFactors, diophant, M, Pi, d, MOD);
+  CFList result;
+  for (k= 1; k < factors.length(); k++)
+    result.append (bufFactors[k]);
+  return result;
+}
+
+void
+henselLiftResume (const CanonicalForm& F, CFList& factors, int start, int end,
+                  CFArray& Pi, const CFList& diophant, CFMatrix& M,
+                  const CFList& MOD)
+{
+  CFArray bufFactors= CFArray (factors.length());
+  int i= 0;
+  CanonicalForm xToStart= power (F.mvar(), start);
+  for (CFListIterator k= factors; k.hasItem(); k++, i++)
+  {
+    if (i == 0)
+      bufFactors[i]= mod (k.getItem(), xToStart);
+    else
+      bufFactors[i]= k.getItem();
+  }
+  for (i= start; i < end; i++)
+    henselStep (F, factors, bufFactors, diophant, M, Pi, i, MOD);
+
+  CFListIterator k= factors;
+  for (i= 0; i < factors.length(); k++, i++)
+    k.getItem()= bufFactors [i];
+  factors.removeFirst();
+  return;
+}
+
+CFList
+henselLift (const CFList& F, const CFList& factors, const CFList& MOD, CFList&
+            diophant, CFArray& Pi, CFMatrix& M, int lOld, int lNew)
+{
+  diophant= multiRecDiophantine (F.getFirst(), factors, diophant, MOD, lOld);
+  int k= 0;
+  CFArray bufFactors= CFArray (factors.length());
+  for (CFListIterator i= factors; i.hasItem(); i++, k++)
+  {
+    if (k == 0)
+      bufFactors[k]= LC (F.getLast(), 1);
+    else
+      bufFactors[k]= i.getItem();
+  }
+  CFList buf= factors;
+  buf.removeFirst();
+  buf.insert (LC (F.getLast(), 1));
+  CFListIterator i= buf;
+  i++;
+  Variable y= F.getLast().mvar();
+  Variable x= F.getFirst().mvar();
+  CanonicalForm xToLOld= power (x, lOld);
+  Pi [0]= mod (Pi[0], xToLOld);
+  M (1, 1)= Pi [0];
+  k= 1;
+  if (i.hasItem())
+    i++;
+  for (; i.hasItem(); i++, k++)
+  {
+    Pi [k]= mod (Pi [k], xToLOld);
+    M (1, k + 1)= Pi [k];
+  }
+
+  for (int d= 1; d < lNew; d++)
+    henselStep (F.getLast(), buf, bufFactors, diophant, M, Pi, d, MOD);
+  CFList result;
+  for (k= 1; k < factors.length(); k++)
+    result.append (bufFactors[k]);
+  return result;
+}
+
+CFList
+henselLift (const CFList& eval, const CFList& factors, int* l, int lLength,
+            bool sort)
+{
+  CFList diophant;
+  CFList buf= factors;
+  buf.insert (LC (eval.getFirst(), 1));
+  if (sort)
+    sortList (buf, Variable (1));
+  CFArray Pi;
+  CFMatrix M= CFMatrix (l[1], factors.length());
+  CFList result= henselLift23 (eval, buf, l, diophant, Pi, M);
+  if (eval.length() == 2)
+    return result;
+  CFList MOD;
+  for (int i= 0; i < 2; i++)
+    MOD.append (power (Variable (i + 2), l[i]));
+  CFListIterator j= eval;
+  j++;
+  CFList bufEval;
+  bufEval.append (j.getItem());
+  j++;
+
+  for (int i= 2; i < lLength && j.hasItem(); i++, j++)
+  {
+    result.insert (LC (bufEval.getFirst(), 1));
+    bufEval.append (j.getItem());
+    M= CFMatrix (l[i], factors.length());
+    result= henselLift (bufEval, result, MOD, diophant, Pi, M, l[i - 1], l[i]);
+    MOD.append (power (Variable (i + 2), l[i]));
+    bufEval.removeFirst();
+  }
+  return result;
+}
+
+// nonmonic
+
+void
+nonMonicHenselStep12 (const CanonicalForm& F, const CFList& factors,
+                      CFArray& bufFactors, const CFList& diophant, CFMatrix& M,
+                      CFArray& Pi, int j, const CFArray& /*LCs*/)
+{
+  Variable x= F.mvar();
+  CanonicalForm xToJ= power (x, j);
+
+  CanonicalForm E;
+  // compute the error
+  if (degree (Pi [factors.length() - 2], x) > 0)
+    E= F[j] - Pi [factors.length() - 2] [j];
+  else
+    E= F[j];
+
+  CFArray buf= CFArray (diophant.length());
+
+  int k= 0;
+  CanonicalForm remainder;
+  // actual lifting
+  for (CFListIterator i= diophant; i.hasItem(); i++, k++)
+  {
+    if (degree (bufFactors[k], x) > 0)
+      remainder= modNTL (E, bufFactors[k] [0]);
+    else
+      remainder= modNTL (E, bufFactors[k]);
+    buf[k]= mulNTL (i.getItem(), remainder);
+    if (degree (bufFactors[k], x) > 0)
+      buf[k]= modNTL (buf[k], bufFactors[k] [0]);
+    else
+      buf[k]= modNTL (buf[k], bufFactors[k]);
+  }
+
+  for (k= 0; k < factors.length(); k++)
+    bufFactors[k] += xToJ*buf[k];
+
+  // update Pi [0]
+  int degBuf0= degree (bufFactors[0], x);
+  int degBuf1= degree (bufFactors[1], x);
+  if (degBuf0 > 0 && degBuf1 > 0)
+  {
+    M (j + 1, 1)= mulNTL (bufFactors[0] [j], bufFactors[1] [j]);
+    if (j + 2 <= M.rows())
+      M (j + 2, 1)= mulNTL (bufFactors[0] [j + 1], bufFactors[1] [j + 1]);
+  }
+  else
+    M (j + 1, 1)= 0;
+
+  CanonicalForm uIZeroJ;
+  if (degBuf0 > 0 && degBuf1 > 0)
+    uIZeroJ= mulNTL(bufFactors[0][0], buf[1]) +
+             mulNTL (bufFactors[1][0], buf[0]);
+  else if (degBuf0 > 0)
+    uIZeroJ= mulNTL (buf[0], bufFactors[1]) +
+             mulNTL (buf[1], bufFactors[0][0]);
+  else if (degBuf1 > 0)
+    uIZeroJ= mulNTL (bufFactors[0], buf[1]) +
+             mulNTL (buf[0], bufFactors[1][0]);
+  else
+    uIZeroJ= mulNTL (bufFactors[0], buf[1]) +
+             mulNTL (buf[0], bufFactors[1]);
+
+  Pi [0] += xToJ*uIZeroJ;
+
+  CFArray tmp= CFArray (factors.length() - 1);
+  for (k= 0; k < factors.length() - 1; k++)
+    tmp[k]= 0;
+  CFIterator one, two;
+  one= bufFactors [0];
+  two= bufFactors [1];
+  if (degBuf0 > 0 && degBuf1 > 0)
+  {
+    while (one.hasTerms() && one.exp() > j) one++;
+    while (two.hasTerms() && two.exp() > j) two++;
+    for (k= 1; k <= (int) ceil (j/2.0); k++)
+    {
+      if (k != j - k + 1)
+      {
+        if ((one.hasTerms() && one.exp() == j - k + 1) && +
+            (two.hasTerms() && two.exp() == j - k + 1))
+        {
+          tmp[0] += mulNTL ((bufFactors[0][k]+one.coeff()),(bufFactors[1][k] +
+                    two.coeff())) - M (k + 1, 1) - M (j - k + 2, 1);
+          one++;
+          two++;
+        }
+        else if (one.hasTerms() && one.exp() == j - k + 1)
+        {
+          tmp[0] += mulNTL ((bufFactors[0][k]+one.coeff()), bufFactors[1] [k]) -
+                    M (k + 1, 1);
+          one++;
+        }
+        else if (two.hasTerms() && two.exp() == j - k + 1)
+        {
+          tmp[0] += mulNTL (bufFactors[0][k],(bufFactors[1][k] + two.coeff())) -
+                    M (k + 1, 1);
+          two++;
+        }
+      }
+      else
+        tmp[0] += M (k + 1, 1);
+    }
+  }
+
+  if (degBuf0 >= j + 1 && degBuf1 >= j + 1)
+  {
+    if (j + 2 <= M.rows())
+      tmp [0] += mulNTL ((bufFactors [0] [j + 1]+ bufFactors [0] [0]),
+                         (bufFactors [1] [j + 1] + bufFactors [1] [0]))
+                         - M(1,1) - M (j + 2,1);
+  }
+  else if (degBuf0 >= j + 1)
+  {
+    if (degBuf1 > 0)
+      tmp[0] += mulNTL (bufFactors [0] [j+1], bufFactors [1] [0]);
+    else
+      tmp[0] += mulNTL (bufFactors [0] [j+1], bufFactors [1]);
+  }
+  else if (degBuf1 >= j + 1)
+  {
+    if (degBuf0 > 0)
+      tmp[0] += mulNTL (bufFactors [0] [0], bufFactors [1] [j + 1]);
+    else
+      tmp[0] += mulNTL (bufFactors [0], bufFactors [1] [j + 1]);
+  }
+
+  Pi [0] += tmp[0]*xToJ*F.mvar();
+
+  int degPi, degBuf;
+  for (int l= 1; l < factors.length() - 1; l++)
+  {
+    degPi= degree (Pi [l - 1], x);
+    degBuf= degree (bufFactors[l + 1], x);
+    if (degPi > 0 && degBuf > 0)
+    {
+      M (j + 1, l + 1)= mulNTL (Pi [l - 1] [j], bufFactors[l + 1] [j]);
+      if (j + 2 <= M.rows())
+        M (j + 2, l + 1)= mulNTL (Pi [l - 1][j + 1], bufFactors[l + 1] [j + 1]);
+    }
+    else
+      M (j + 1, l + 1)= 0;
+
+    if (degPi > 0 && degBuf > 0)
+      uIZeroJ= mulNTL (Pi[l - 1] [0], buf[l + 1]) +
+               mulNTL (uIZeroJ, bufFactors[l+1] [0]);
+    else if (degPi > 0)
+      uIZeroJ= mulNTL (uIZeroJ, bufFactors[l + 1]) +
+               mulNTL (Pi[l - 1][0], buf[l + 1]);
+    else if (degBuf > 0)
+      uIZeroJ= mulNTL (uIZeroJ, bufFactors[l + 1][0]) +
+               mulNTL (Pi[l - 1], buf[l + 1]);
+    else
+      uIZeroJ= mulNTL (uIZeroJ, bufFactors[l + 1]) +
+               mulNTL (Pi[l - 1], buf[l + 1]);
+
+    Pi [l] += xToJ*uIZeroJ;
+
+    one= bufFactors [l + 1];
+    two= Pi [l - 1];
+    if (degBuf > 0 && degPi > 0)
+    {
+      while (one.hasTerms() && one.exp() > j) one++;
+      while (two.hasTerms() && two.exp() > j) two++;
+      for (k= 1; k <= (int) ceil (j/2.0); k++)
+      {
+        if (k != j - k + 1)
+        {
+          if ((one.hasTerms() && one.exp() == j - k + 1) &&
+              (two.hasTerms() && two.exp() == j - k + 1))
+          {
+            tmp[l] += mulNTL ((bufFactors[l + 1] [k] + one.coeff()),
+                      (Pi[l - 1] [k] + two.coeff())) - M (k + 1, l + 1) -
+                      M (j - k + 2, l + 1);
+            one++;
+            two++;
+          }
+          else if (one.hasTerms() && one.exp() == j - k + 1)
+          {
+            tmp[l] += mulNTL ((bufFactors[l + 1] [k] + one.coeff()),
+                               Pi[l - 1] [k]) - M (k + 1, l + 1);
+            one++;
+          }
+          else if (two.hasTerms() && two.exp() == j - k + 1)
+          {
+            tmp[l] += mulNTL (bufFactors[l + 1] [k],
+                      (Pi[l - 1] [k] + two.coeff())) - M (k + 1, l + 1);
+            two++;
+           }
+        }
+        else
+          tmp[l] += M (k + 1, l + 1);
+      }
+    }
+
+    if (degPi >= j + 1 && degBuf >= j + 1)
+    {
+      if (j + 2 <= M.rows())
+        tmp [l] += mulNTL ((Pi [l - 1] [j + 1]+ Pi [l - 1] [0]),
+                           (bufFactors [l + 1] [j + 1] + bufFactors [l + 1] [0])
+                          ) - M(1,l+1) - M (j + 2,l+1);
+    }
+    else if (degPi >= j + 1)
+    {
+      if (degBuf > 0)
+        tmp[l] += mulNTL (Pi [l - 1] [j+1], bufFactors [l + 1] [0]);
+      else
+        tmp[l] += mulNTL (Pi [l - 1] [j+1], bufFactors [l + 1]);
+    }
+    else if (degBuf >= j + 1)
+    {
+      if (degPi > 0)
+        tmp[l] += mulNTL (Pi [l - 1] [0], bufFactors [l + 1] [j + 1]);
+      else
+        tmp[l] += mulNTL (Pi [l - 1], bufFactors [l + 1] [j + 1]);
+    }
+
+    Pi[l] += tmp[l]*xToJ*F.mvar();
+  }
+  return;
+}
+
+void
+nonMonicHenselLift12 (const CanonicalForm& F, CFList& factors, int l,
+                      CFArray& Pi, CFList& diophant, CFMatrix& M,
+                      const CFArray& LCs, bool sort)
+{
+  if (sort)
+    sortList (factors, Variable (1));
+  Pi= CFArray (factors.length() - 2);
+  CFList bufFactors2= factors;
+  bufFactors2.removeFirst();
+  diophant= diophantine (F[0], bufFactors2);
+  DEBOUTLN (cerr, "diophant= " << diophant);
+
+  CFArray bufFactors= CFArray (bufFactors2.length());
+  int i= 0;
+  for (CFListIterator k= bufFactors2; k.hasItem(); i++, k++)
+    bufFactors[i]= replaceLc (k.getItem(), LCs [i]);
+
+  Variable x= F.mvar();
+  if (degree (bufFactors[0], x) > 0 && degree (bufFactors [1], x) > 0)
+  {
+    M (1, 1)= mulNTL (bufFactors [0] [0], bufFactors[1] [0]);
+    Pi [0]= M (1, 1) + (mulNTL (bufFactors [0] [1], bufFactors[1] [0]) +
+                        mulNTL (bufFactors [0] [0], bufFactors [1] [1]))*x;
+  }
+  else if (degree (bufFactors[0], x) > 0)
+  {
+    M (1, 1)= mulNTL (bufFactors [0] [0], bufFactors[1]);
+    Pi [0]= M (1, 1) +
+            mulNTL (bufFactors [0] [1], bufFactors[1])*x;
+  }
+  else if (degree (bufFactors[1], x) > 0)
+  {
+    M (1, 1)= mulNTL (bufFactors [0], bufFactors[1] [0]);
+    Pi [0]= M (1, 1) +
+            mulNTL (bufFactors [0], bufFactors[1] [1])*x;
+  }
+  else
+  {
+    M (1, 1)= mulNTL (bufFactors [0], bufFactors[1]);
+    Pi [0]= M (1, 1);
+  }
+
+  for (i= 1; i < Pi.size(); i++)
+  {
+    if (degree (Pi[i-1], x) > 0 && degree (bufFactors [i+1], x) > 0)
+    {
+      M (1,i+1)= mulNTL (Pi[i-1] [0], bufFactors[i+1] [0]);
+      Pi [i]= M (1,i+1) + (mulNTL (Pi[i-1] [1], bufFactors[i+1] [0]) +
+                       mulNTL (Pi[i-1] [0], bufFactors [i+1] [1]))*x;
+    }
+    else if (degree (Pi[i-1], x) > 0)
+    {
+      M (1,i+1)= mulNTL (Pi[i-1] [0], bufFactors [i+1]);
+      Pi [i]=  M(1,i+1) + mulNTL (Pi[i-1] [1], bufFactors[i+1])*x;
+    }
+    else if (degree (bufFactors[i+1], x) > 0)
+    {
+      M (1,i+1)= mulNTL (Pi[i-1], bufFactors [i+1] [0]);
+      Pi [i]= M (1,i+1) + mulNTL (Pi[i-1], bufFactors[i+1] [1])*x;
+    }
+    else
+    {
+      M (1,i+1)= mulNTL (Pi [i-1], bufFactors [i+1]);
+      Pi [i]= M (1,i+1);
+    }
+  }
+
+  for (i= 1; i < l; i++)
+    nonMonicHenselStep12 (F, bufFactors2, bufFactors, diophant, M, Pi, i, LCs);
+
+  factors= CFList();
+  for (i= 0; i < bufFactors.size(); i++)
+    factors.append (bufFactors[i]);
+  return;
+}
+
+
+/// solve \f$ E=\sum_{i= 1}^r{\sigma_{i}\prod_{j=1, j\neq i}^{r}{f_{j}}} \f$
+/// mod M, @a products contains \f$ \prod_{j=1, j\neq i}^{r}{f_{j}} \f$
+CFList
+diophantine (const CFList& recResult, const CFList& factors,
+             const CFList& products, const CFList& M, const CanonicalForm& E,
+             bool& bad)
+{
+  if (M.isEmpty())
+  {
+    CFList result;
+    CFListIterator j= factors;
+    CanonicalForm buf;
+    for (CFListIterator i= recResult; i.hasItem(); i++, j++)
+    {
+      ASSERT (E.isUnivariate() || E.inCoeffDomain(),
+              "constant or univariate poly expected");
+      ASSERT (i.getItem().isUnivariate() || i.getItem().inCoeffDomain(),
+              "constant or univariate poly expected");
+      ASSERT (j.getItem().isUnivariate() || j.getItem().inCoeffDomain(),
+              "constant or univariate poly expected");
+      buf= mulNTL (E, i.getItem());
+      result.append (modNTL (buf, j.getItem()));
+    }
+    return result;
+  }
+  Variable y= M.getLast().mvar();
+  CFList bufFactors= factors;
+  for (CFListIterator i= bufFactors; i.hasItem(); i++)
+    i.getItem()= mod (i.getItem(), y);
+  CFList bufProducts= products;
+  for (CFListIterator i= bufProducts; i.hasItem(); i++)
+    i.getItem()= mod (i.getItem(), y);
+  CFList buf= M;
+  buf.removeLast();
+  CanonicalForm bufE= mod (E, y);
+  CFList recDiophantine= diophantine (recResult, bufFactors, bufProducts, buf,
+                                      bufE, bad);
+
+  if (bad)
+    return CFList();
+
+  CanonicalForm e= E;
+  CFListIterator j= products;
+  for (CFListIterator i= recDiophantine; i.hasItem(); i++, j++)
+    e -= j.getItem()*i.getItem();
+
+  CFList result= recDiophantine;
+  int d= degree (M.getLast());
+  CanonicalForm coeffE;
+  for (int i= 1; i < d; i++)
+  {
+    if (degree (e, y) > 0)
+      coeffE= e[i];
+    else
+      coeffE= 0;
+    if (!coeffE.isZero())
+    {
+      CFListIterator k= result;
+      recDiophantine= diophantine (recResult, bufFactors, bufProducts, buf,
+                                   coeffE, bad);
+      if (bad)
+        return CFList();
+      CFListIterator l= products;
+      for (j= recDiophantine; j.hasItem(); j++, k++, l++)
+      {
+        k.getItem() += j.getItem()*power (y, i);
+        e -= l.getItem()*(j.getItem()*power (y, i));
+      }
+    }
+    if (e.isZero())
+      break;
+  }
+  if (!e.isZero())
+  {
+    bad= true;
+    return CFList();
+  }
+  return result;
+}
+
+void
+nonMonicHenselStep (const CanonicalForm& F, const CFList& factors,
+                    CFArray& bufFactors, const CFList& diophant, CFMatrix& M,
+                    CFArray& Pi, const CFList& products, int j,
+                    const CFList& MOD, bool& noOneToOne)
+{
+  CanonicalForm E;
+  CanonicalForm xToJ= power (F.mvar(), j);
+  Variable x= F.mvar();
+
+  // compute the error
+#ifdef DEBUGOUTPUT
+    CanonicalForm test= 1;
+    for (int i= 0; i < factors.length(); i++)
+    {
+      if (i == 0)
+        test *= mod (bufFactors [i], power (x, j));
+      else
+        test *= bufFactors[i];
+    }
+    test= mod (test, power (x, j));
+    test= mod (test, MOD);
+    CanonicalForm test2= mod (F, power (x, j - 1)) - mod (test, power (x, j-1));
+    DEBOUTLN (cerr, "test in nonMonicHenselStep= " << test2);
+#endif
+
+  if (degree (Pi [factors.length() - 2], x) > 0)
+    E= F[j] - Pi [factors.length() - 2] [j];
+  else
+    E= F[j];
+
+  CFArray buf= CFArray (diophant.length());
+
+  // actual lifting
+  TIMING_START (diotime);
+  CFList diophantine2= diophantine (diophant, factors, products, MOD, E,
+                                    noOneToOne);
+
+  if (noOneToOne)
+    return;
+
+  int k= 0;
+  for (CFListIterator i= diophantine2; k < factors.length(); k++, i++)
+  {
+    buf[k]= i.getItem();
+    bufFactors[k] += xToJ*i.getItem();
+  }
+  TIMING_END_AND_PRINT (diotime, "time for dio: ");
+
+  // update Pi [0]
+  TIMING_START (product2);
+  int degBuf0= degree (bufFactors[0], x);
+  int degBuf1= degree (bufFactors[1], x);
+  if (degBuf0 > 0 && degBuf1 > 0)
+  {
+    M (j + 1, 1)= mulMod (bufFactors[0] [j], bufFactors[1] [j], MOD);
+    if (j + 2 <= M.rows())
+      M (j + 2, 1)= mulMod (bufFactors[0] [j + 1], bufFactors[1] [j + 1], MOD);
+  }
+  else
+    M (j + 1, 1)= 0;
+
+  CanonicalForm uIZeroJ;
+  if (degBuf0 > 0 && degBuf1 > 0)
+    uIZeroJ= mulMod (bufFactors[0] [0], buf[1], MOD) +
+             mulMod (bufFactors[1] [0], buf[0], MOD);
+  else if (degBuf0 > 0)
+    uIZeroJ= mulMod (buf[0], bufFactors[1], MOD) +
+             mulMod (buf[1], bufFactors[0][0], MOD);
+  else if (degBuf1 > 0)
+    uIZeroJ= mulMod (bufFactors[0], buf[1], MOD) +
+             mulMod (buf[0], bufFactors[1][0], MOD);
+  else
+    uIZeroJ= mulMod (bufFactors[0], buf[1], MOD) +
+             mulMod (buf[0], bufFactors[1], MOD);
+  Pi [0] += xToJ*uIZeroJ;
+
+  CFArray tmp= CFArray (factors.length() - 1);
+  for (k= 0; k < factors.length() - 1; k++)
+    tmp[k]= 0;
+  CFIterator one, two;
+  one= bufFactors [0];
+  two= bufFactors [1];
+  if (degBuf0 > 0 && degBuf1 > 0)
+  {
+    while (one.hasTerms() && one.exp() > j) one++;
+    while (two.hasTerms() && two.exp() > j) two++;
+    for (k= 1; k <= (int) ceil (j/2.0); k++)
+    {
+      if (k != j - k + 1)
+      {
+        if ((one.hasTerms() && one.exp() == j - k + 1) &&
+            (two.hasTerms() && two.exp() == j - k + 1))
+        {
+          tmp[0] += mulMod ((bufFactors[0] [k] + one.coeff()),
+                    (bufFactors[1] [k] + two.coeff()), MOD) - M (k + 1, 1) -
+                    M (j - k + 2, 1);
+          one++;
+          two++;
+        }
+        else if (one.hasTerms() && one.exp() == j - k + 1)
+        {
+          tmp[0] += mulMod ((bufFactors[0] [k] + one.coeff()),
+                    bufFactors[1] [k], MOD) - M (k + 1, 1);
+          one++;
+        }
+        else if (two.hasTerms() && two.exp() == j - k + 1)
+        {
+          tmp[0] += mulMod (bufFactors[0] [k], (bufFactors[1] [k] +
+                    two.coeff()), MOD) - M (k + 1, 1);
+          two++;
+        }
+      }
+      else
+      {
+        tmp[0] += M (k + 1, 1);
+      }
+    }
+  }
+
+  if (degBuf0 >= j + 1 && degBuf1 >= j + 1)
+  {
+    if (j + 2 <= M.rows())
+      tmp [0] += mulMod ((bufFactors [0] [j + 1]+ bufFactors [0] [0]),
+                         (bufFactors [1] [j + 1] + bufFactors [1] [0]), MOD)
+                         - M(1,1) - M (j + 2,1);
+  }
+  else if (degBuf0 >= j + 1)
+  {
+    if (degBuf1 > 0)
+      tmp[0] += mulMod (bufFactors [0] [j+1], bufFactors [1] [0], MOD);
+    else
+      tmp[0] += mulMod (bufFactors [0] [j+1], bufFactors [1], MOD);
+  }
+  else if (degBuf1 >= j + 1)
+  {
+    if (degBuf0 > 0)
+      tmp[0] += mulMod (bufFactors [0] [0], bufFactors [1] [j + 1], MOD);
+    else
+      tmp[0] += mulMod (bufFactors [0], bufFactors [1] [j + 1], MOD);
+  }
+  Pi [0] += tmp[0]*xToJ*F.mvar();
+
+  // update Pi [l]
+  int degPi, degBuf;
+  for (int l= 1; l < factors.length() - 1; l++)
+  {
+    degPi= degree (Pi [l - 1], x);
+    degBuf= degree (bufFactors[l + 1], x);
+    if (degPi > 0 && degBuf > 0)
+    {
+      M (j + 1, l + 1)= mulMod (Pi [l - 1] [j], bufFactors[l + 1] [j], MOD);
+      if (j + 2 <= M.rows())
+        M (j + 2, l + 1)= mulMod (Pi [l - 1] [j + 1], bufFactors[l + 1] [j + 1],
+                                  MOD);
+    }
+    else
+      M (j + 1, l + 1)= 0;
+
+    if (degPi > 0 && degBuf > 0)
+      uIZeroJ= mulMod (Pi[l - 1] [0], buf[l + 1], MOD) +
+               mulMod (uIZeroJ, bufFactors[l + 1] [0], MOD);
+    else if (degPi > 0)
+      uIZeroJ= mulMod (uIZeroJ, bufFactors[l + 1], MOD) +
+               mulMod (Pi[l - 1][0], buf[l + 1], MOD);
+    else if (degBuf > 0)
+      uIZeroJ= mulMod (Pi[l - 1], buf[l + 1], MOD) +
+               mulMod (uIZeroJ, bufFactors[l + 1][0], MOD);
+    else
+      uIZeroJ= mulMod (Pi[l - 1], buf[l + 1], MOD) +
+               mulMod (uIZeroJ, bufFactors[l + 1], MOD);
+
+    Pi [l] += xToJ*uIZeroJ;
+
+    one= bufFactors [l + 1];
+    two= Pi [l - 1];
+    if (degBuf > 0 && degPi > 0)
+    {
+      while (one.hasTerms() && one.exp() > j) one++;
+      while (two.hasTerms() && two.exp() > j) two++;
+      for (k= 1; k <= (int) ceil (j/2.0); k++)
+      {
+        if (k != j - k + 1)
+        {
+          if ((one.hasTerms() && one.exp() == j - k + 1) &&
+              (two.hasTerms() && two.exp() == j - k + 1))
+          {
+            tmp[l] += mulMod ((bufFactors[l + 1] [k] + one.coeff()),
+                      (Pi[l - 1] [k] + two.coeff()), MOD) - M (k + 1, l + 1) -
+                      M (j - k + 2, l + 1);
+            one++;
+            two++;
+          }
+          else if (one.hasTerms() && one.exp() == j - k + 1)
+          {
+            tmp[l] += mulMod ((bufFactors[l + 1] [k] + one.coeff()),
+                      Pi[l - 1] [k], MOD) - M (k + 1, l + 1);
+            one++;
+          }
+          else if (two.hasTerms() && two.exp() == j - k + 1)
+          {
+            tmp[l] += mulMod (bufFactors[l + 1] [k],
+                      (Pi[l - 1] [k] + two.coeff()), MOD) - M (k + 1, l + 1);
+            two++;
+           }
+        }
+        else
+          tmp[l] += M (k + 1, l + 1);
+      }
+    }
+
+    if (degPi >= j + 1 && degBuf >= j + 1)
+    {
+      if (j + 2 <= M.rows())
+        tmp [l] += mulMod ((Pi [l - 1] [j + 1]+ Pi [l - 1] [0]),
+                           (bufFactors [l + 1] [j + 1] + bufFactors [l + 1] [0])
+                            , MOD) - M(1,l+1) - M (j + 2,l+1);
+    }
+    else if (degPi >= j + 1)
+    {
+      if (degBuf > 0)
+        tmp[l] += mulMod (Pi [l - 1] [j+1], bufFactors [l + 1] [0], MOD);
+      else
+        tmp[l] += mulMod (Pi [l - 1] [j+1], bufFactors [l + 1], MOD);
+    }
+    else if (degBuf >= j + 1)
+    {
+      if (degPi > 0)
+        tmp[l] += mulMod (Pi [l - 1] [0], bufFactors [l + 1] [j + 1], MOD);
+      else
+        tmp[l] += mulMod (Pi [l - 1], bufFactors [l + 1] [j + 1], MOD);
+    }
+
+    Pi[l] += tmp[l]*xToJ*F.mvar();
+  }
+  TIMING_END_AND_PRINT (product2, "time for product in hensel step: ");
+  return;
+}
+
+// wrt. Variable (1)
+CanonicalForm replaceLC (const CanonicalForm& F, const CanonicalForm& c)
+{
+  if (degree (F, 1) <= 0)
+   return c;
+  else
+  {
+    CanonicalForm result= swapvar (F, Variable (F.level() + 1), Variable (1));
+    result += (swapvar (c, Variable (F.level() + 1), Variable (1))
+              - LC (result))*power (result.mvar(), degree (result));
+    return swapvar (result, Variable (F.level() + 1), Variable (1));
+  }
+}
+
+CFList
+nonMonicHenselLift232(const CFList& eval, const CFList& factors, int* l, CFList&
+                      diophant, CFArray& Pi, CFMatrix& M, const CFList& LCs1,
+                      const CFList& LCs2, bool& bad)
+{
+  CFList buf= factors;
+  int k= 0;
+  int liftBoundBivar= l[k];
+  CFList bufbuf= factors;
+  Variable v= Variable (2);
+
+  CFList MOD;
+  MOD.append (power (Variable (2), liftBoundBivar));
+  CFArray bufFactors= CFArray (factors.length());
+  k= 0;
+  CFListIterator j= eval;
+  j++;
+  CFListIterator iter1= LCs1;
+  CFListIterator iter2= LCs2;
+  iter1++;
+  iter2++;
+  bufFactors[0]= replaceLC (buf.getFirst(), iter1.getItem());
+  bufFactors[1]= replaceLC (buf.getLast(), iter2.getItem());
+
+  CFListIterator i= buf;
+  i++;
+  Variable y= j.getItem().mvar();
+  if (y.level() != 3)
+    y= Variable (3);
+
+  Pi[0]= mod (Pi[0], power (v, liftBoundBivar));
+  M (1, 1)= Pi[0];
+  if (degree (bufFactors[0], y) > 0 && degree (bufFactors [1], y) > 0)
+    Pi [0] += (mulMod (bufFactors [0] [1], bufFactors[1] [0], MOD) +
+                        mulMod (bufFactors [0] [0], bufFactors [1] [1], MOD))*y;
+  else if (degree (bufFactors[0], y) > 0)
+    Pi [0] += mulMod (bufFactors [0] [1], bufFactors[1], MOD)*y;
+  else if (degree (bufFactors[1], y) > 0)
+    Pi [0] += mulMod (bufFactors [0], bufFactors[1] [1], MOD)*y;
+
+  CFList products;
+  for (int i= 0; i < bufFactors.size(); i++)
+  {
+    if (degree (bufFactors[i], y) > 0)
+      products.append (eval.getFirst()/bufFactors[i] [0]);
+    else
+      products.append (eval.getFirst()/bufFactors[i]);
+  }
+
+  for (int d= 1; d < l[1]; d++)
+  {
+    nonMonicHenselStep (j.getItem(), buf, bufFactors, diophant, M, Pi, products,
+                        d, MOD, bad);
+    if (bad)
+      return CFList();
+  }
+  CFList result;
+  for (k= 0; k < factors.length(); k++)
+    result.append (bufFactors[k]);
+  return result;
+}
+
+
+CFList
+nonMonicHenselLift2 (const CFList& F, const CFList& factors, const CFList& MOD,
+                    CFList& diophant, CFArray& Pi, CFMatrix& M, int lOld,
+                    int& lNew, const CFList& LCs1, const CFList& LCs2, bool& bad
+                   )
+{
+  int k= 0;
+  CFArray bufFactors= CFArray (factors.length());
+  bufFactors[0]= replaceLC (factors.getFirst(), LCs1.getLast());
+  bufFactors[1]= replaceLC (factors.getLast(), LCs2.getLast());
+  CFList buf= factors;
+  Variable y= F.getLast().mvar();
+  Variable x= F.getFirst().mvar();
+  CanonicalForm xToLOld= power (x, lOld);
+  Pi [0]= mod (Pi[0], xToLOld);
+  M (1, 1)= Pi [0];
+
+  if (degree (bufFactors[0], y) > 0 && degree (bufFactors [1], y) > 0)
+    Pi [0] += (mulMod (bufFactors [0] [1], bufFactors[1] [0], MOD) +
+                        mulMod (bufFactors [0] [0], bufFactors [1] [1], MOD))*y;
+  else if (degree (bufFactors[0], y) > 0)
+    Pi [0] += mulMod (bufFactors [0] [1], bufFactors[1], MOD)*y;
+  else if (degree (bufFactors[1], y) > 0)
+    Pi [0] += mulMod (bufFactors [0], bufFactors[1] [1], MOD)*y;
+
+  CFList products;
+  CanonicalForm quot;
+  for (int i= 0; i < bufFactors.size(); i++)
+  {
+    if (degree (bufFactors[i], y) > 0)
+    {
+      if (!fdivides (bufFactors[i] [0], F.getFirst(), quot))
+      {
+        bad= true;
+        return CFList();
+      }
+      products.append (quot);
+    }
+    else
+    {
+      if (!fdivides (bufFactors[i], F.getFirst(), quot))
+      {
+        bad= true;
+        return CFList();
+      }
+      products.append (quot);
+    }
+  }
+
+  for (int d= 1; d < lNew; d++)
+  {
+    nonMonicHenselStep (F.getLast(), buf, bufFactors, diophant, M, Pi, products,
+                        d, MOD, bad);
+    if (bad)
+      return CFList();
+  }
+
+  CFList result;
+  for (k= 0; k < factors.length(); k++)
+    result.append (bufFactors[k]);
+  return result;
+}
+
+CFList
+nonMonicHenselLift2 (const CFList& eval, const CFList& factors, int* l, int
+                    lLength, bool sort, const CFList& LCs1, const CFList& LCs2,
+                    const CFArray& Pi, const CFList& diophant, bool& bad)
+{
+  CFList bufDiophant= diophant;
+  CFList buf= factors;
+  if (sort)
+    sortList (buf, Variable (1));
+  CFArray bufPi= Pi;
+  CFMatrix M= CFMatrix (l[1], factors.length());
+  CFList result=
+    nonMonicHenselLift232(eval, buf, l, bufDiophant, bufPi, M, LCs1, LCs2, bad);
+  if (bad)
+    return CFList();
+
+  if (eval.length() == 2)
+    return result;
+  CFList MOD;
+  for (int i= 0; i < 2; i++)
+    MOD.append (power (Variable (i + 2), l[i]));
+  CFListIterator j= eval;
+  j++;
+  CFList bufEval;
+  bufEval.append (j.getItem());
+  j++;
+  CFListIterator jj= LCs1;
+  CFListIterator jjj= LCs2;
+  CFList bufLCs1, bufLCs2;
+  jj++, jjj++;
+  bufLCs1.append (jj.getItem());
+  bufLCs2.append (jjj.getItem());
+  jj++, jjj++;
+
+  for (int i= 2; i < lLength && j.hasItem(); i++, j++, jj++, jjj++)
+  {
+    bufEval.append (j.getItem());
+    bufLCs1.append (jj.getItem());
+    bufLCs2.append (jjj.getItem());
+    M= CFMatrix (l[i], factors.length());
+    result= nonMonicHenselLift2 (bufEval, result, MOD, bufDiophant, bufPi, M,
+                                 l[i - 1], l[i], bufLCs1, bufLCs2, bad);
+    if (bad)
+      return CFList();
+    MOD.append (power (Variable (i + 2), l[i]));
+    bufEval.removeFirst();
+    bufLCs1.removeFirst();
+    bufLCs2.removeFirst();
+  }
+  return result;
+}
+
+CFList
+nonMonicHenselLift23 (const CanonicalForm& F, const CFList& factors, const
+                      CFList& LCs, CFList& diophant, CFArray& Pi, int liftBound,
+                      int bivarLiftBound, bool& bad)
+{
+  CFList bufFactors2= factors;
+
+  Variable y= Variable (2);
+  for (CFListIterator i= bufFactors2; i.hasItem(); i++)
+    i.getItem()= mod (i.getItem(), y);
+
+  CanonicalForm bufF= F;
+  bufF= mod (bufF, y);
+  bufF= mod (bufF, Variable (3));
+
+  TIMING_START (diotime);
+  diophant= diophantine (bufF, bufFactors2);
+  TIMING_END_AND_PRINT (diotime, "time for dio in 23: ");
+
+  CFMatrix M= CFMatrix (liftBound, bufFactors2.length() - 1);
+
+  Pi= CFArray (bufFactors2.length() - 1);
+
+  CFArray bufFactors= CFArray (bufFactors2.length());
+  CFListIterator j= LCs;
+  int i= 0;
+  for (CFListIterator k= factors; k.hasItem(); j++, k++, i++)
+    bufFactors[i]= replaceLC (k.getItem(), j.getItem());
+
+  //initialise Pi
+  Variable v= Variable (3);
+  CanonicalForm yToL= power (y, bivarLiftBound);
+  if (degree (bufFactors[0], v) > 0 && degree (bufFactors [1], v) > 0)
+  {
+    M (1, 1)= mulMod2 (bufFactors [0] [0], bufFactors[1] [0], yToL);
+    Pi [0]= M (1,1) + (mulMod2 (bufFactors [0] [1], bufFactors[1] [0], yToL) +
+                       mulMod2 (bufFactors [0] [0], bufFactors [1] [1], yToL))*v;
+  }
+  else if (degree (bufFactors[0], v) > 0)
+  {
+    M (1,1)= mulMod2 (bufFactors [0] [0], bufFactors [1], yToL);
+    Pi [0]=  M(1,1) + mulMod2 (bufFactors [0] [1], bufFactors[1], yToL)*v;
+  }
+  else if (degree (bufFactors[1], v) > 0)
+  {
+    M (1,1)= mulMod2 (bufFactors [0], bufFactors [1] [0], yToL);
+    Pi [0]= M (1,1) + mulMod2 (bufFactors [0], bufFactors[1] [1], yToL)*v;
+  }
+  else
+  {
+    M (1,1)= mulMod2 (bufFactors [0], bufFactors [1], yToL);
+    Pi [0]= M (1,1);
+  }
+
+  for (i= 1; i < Pi.size(); i++)
+  {
+    if (degree (Pi[i-1], v) > 0 && degree (bufFactors [i+1], v) > 0)
+    {
+      M (1,i+1)= mulMod2 (Pi[i-1] [0], bufFactors[i+1] [0], yToL);
+      Pi [i]= M (1,i+1) + (mulMod2 (Pi[i-1] [1], bufFactors[i+1] [0], yToL) +
+                       mulMod2 (Pi[i-1] [0], bufFactors [i+1] [1], yToL))*v;
+    }
+    else if (degree (Pi[i-1], v) > 0)
+    {
+      M (1,i+1)= mulMod2 (Pi[i-1] [0], bufFactors [i+1], yToL);
+      Pi [i]=  M(1,i+1) + mulMod2 (Pi[i-1] [1], bufFactors[i+1], yToL)*v;
+    }
+    else if (degree (bufFactors[i+1], v) > 0)
+    {
+      M (1,i+1)= mulMod2 (Pi[i-1], bufFactors [i+1] [0], yToL);
+      Pi [i]= M (1,i+1) + mulMod2 (Pi[i-1], bufFactors[i+1] [1], yToL)*v;
+    }
+    else
+    {
+      M (1,i+1)= mulMod2 (Pi [i-1], bufFactors [i+1], yToL);
+      Pi [i]= M (1,i+1);
+    }
+  }
+
+  CFList products;
+  bufF= mod (F, Variable (3));
+  TIMING_START (product1);
+  for (CFListIterator k= factors; k.hasItem(); k++)
+    products.append (bufF/k.getItem());
+  TIMING_END_AND_PRINT (product1, "time for product1 in 23: ");
+
+  CFList MOD= CFList (power (v, liftBound));
+  MOD.insert (yToL);
+  for (int d= 1; d < liftBound; d++)
+  {
+    nonMonicHenselStep (F, factors, bufFactors, diophant, M, Pi, products, d,
+                        MOD, bad);
+    if (bad)
+      return CFList();
+  }
+
+  CFList result;
+  for (i= 0; i < factors.length(); i++)
+    result.append (bufFactors[i]);
+  return result;
+}
+
+CFList
+nonMonicHenselLift (const CFList& F, const CFList& factors, const CFList& LCs,
+                    CFList& diophant, CFArray& Pi, CFMatrix& M, int lOld,
+                    int& lNew, const CFList& MOD, bool& noOneToOne
+                   )
+{
+
+  int k= 0;
+  CFArray bufFactors= CFArray (factors.length());
+  CFListIterator j= LCs;
+  for (CFListIterator i= factors; i.hasItem(); i++, j++, k++)
+    bufFactors [k]= replaceLC (i.getItem(), j.getItem());
+
+  Variable y= F.getLast().mvar();
+  Variable x= F.getFirst().mvar();
+  CanonicalForm xToLOld= power (x, lOld);
+
+  Pi [0]= mod (Pi[0], xToLOld);
+  M (1, 1)= Pi [0];
+
+  if (degree (bufFactors[0], y) > 0 && degree (bufFactors [1], y) > 0)
+    Pi [0] += (mulMod (bufFactors [0] [1], bufFactors[1] [0], MOD) +
+                        mulMod (bufFactors [0] [0], bufFactors [1] [1], MOD))*y;
+  else if (degree (bufFactors[0], y) > 0)
+    Pi [0] += mulMod (bufFactors [0] [1], bufFactors[1], MOD)*y;
+  else if (degree (bufFactors[1], y) > 0)
+    Pi [0] += mulMod (bufFactors [0], bufFactors[1] [1], MOD)*y;
+
+  for (int i= 1; i < Pi.size(); i++)
+  {
+    Pi [i]= mod (Pi [i], xToLOld);
+    M (1, i + 1)= Pi [i];
+
+    if (degree (Pi[i-1], y) > 0 && degree (bufFactors [i+1], y) > 0)
+      Pi [i] += (mulMod (Pi[i-1] [1], bufFactors[i+1] [0], MOD) +
+                 mulMod (Pi[i-1] [0], bufFactors [i+1] [1], MOD))*y;
+    else if (degree (Pi[i-1], y) > 0)
+      Pi [i] += mulMod (Pi[i-1] [1], bufFactors[i+1], MOD)*y;
+    else if (degree (bufFactors[i+1], y) > 0)
+      Pi [i] += mulMod (Pi[i-1], bufFactors[i+1] [1], MOD)*y;
+  }
+
+  CFList products;
+  CanonicalForm quot, bufF= F.getFirst();
+
+  TIMING_START (product1);
+  for (int i= 0; i < bufFactors.size(); i++)
+  {
+    if (degree (bufFactors[i], y) > 0)
+    {
+      if (!fdivides (bufFactors[i] [0], bufF, quot))
+      {
+        noOneToOne= true;
+        return factors;
+      }
+      products.append (quot);
+    }
+    else
+    {
+      if (!fdivides (bufFactors[i], bufF, quot))
+      {
+        noOneToOne= true;
+        return factors;
+      }
+      products.append (quot);
+    }
+  }
+  TIMING_END_AND_PRINT (product1, "time for product1 in further hensel:" );
+
+  for (int d= 1; d < lNew; d++)
+  {
+    nonMonicHenselStep (F.getLast(), factors, bufFactors, diophant, M, Pi,
+                        products, d, MOD, noOneToOne);
+    if (noOneToOne)
+      return CFList();
+  }
+
+  CFList result;
+  for (k= 0; k < factors.length(); k++)
+    result.append (bufFactors[k]);
+  return result;
+}
+
+CFList
+nonMonicHenselLift (const CFList& eval, const CFList& factors,
+                    CFList* const& LCs, CFList& diophant, CFArray& Pi,
+                    int* liftBound, int length, bool& noOneToOne
+                   )
+{
+  CFList bufDiophant= diophant;
+  CFList buf= factors;
+  CFArray bufPi= Pi;
+  CFMatrix M= CFMatrix (liftBound[1], factors.length() - 1);
+  int k= 0;
+
+  TIMING_START (hensel23);
+  CFList result=
+  nonMonicHenselLift23 (eval.getFirst(), factors, LCs [0], diophant, bufPi,
+                        liftBound[1], liftBound[0], noOneToOne);
+  TIMING_END_AND_PRINT (hensel23, "time for 23: ");
+
+  if (noOneToOne)
+    return CFList();
+
+  if (eval.length() == 1)
+    return result;
+
+  k++;
+  CFList MOD;
+  for (int i= 0; i < 2; i++)
+    MOD.append (power (Variable (i + 2), liftBound[i]));
+
+  CFListIterator j= eval;
+  CFList bufEval;
+  bufEval.append (j.getItem());
+  j++;
+
+  for (int i= 2; i <= length && j.hasItem(); i++, j++, k++)
+  {
+    bufEval.append (j.getItem());
+    M= CFMatrix (liftBound[i], factors.length() - 1);
+    TIMING_START (hensel);
+    result= nonMonicHenselLift (bufEval, result, LCs [i-1], diophant, bufPi, M,
+                                liftBound[i-1], liftBound[i], MOD, noOneToOne);
+    TIMING_END_AND_PRINT (hensel, "time for further hensel: ");
+    if (noOneToOne)
+      return result;
+    MOD.append (power (Variable (i + 2), liftBound[i]));
+    bufEval.removeFirst();
+  }
+
+  return result;
+}
+
+#endif
+/* HAVE_NTL */
+
diff --git a/factory/facHensel.h b/factory/facHensel.h
new file mode 100644
index 0000000..6b0c0aa
--- /dev/null
+++ b/factory/facHensel.h
@@ -0,0 +1,245 @@
+/*****************************************************************************\
+ * Computer Algebra System SINGULAR
+\*****************************************************************************/
+/** @file facHensel.h
+ *
+ * This file defines functions for Hensel lifting.
+ *
+ * ABSTRACT: function are used for bi- and multivariate factorization over
+ * finite fields. Described in "Efficient Multivariate Factorization over Finite
+ * Fields" by L. Bernardin & M. Monagon and "Algorithms for Computer Algebra" by
+ * Geddes, Czapor, Labahn
+ *
+ * @author Martin Lee
+ *
+ **/
+/*****************************************************************************/
+
+#ifndef FAC_HENSEL_H
+#define FAC_HENSEL_H
+
+// #include "config.h"
+#include "cf_assert.h"
+#include "debug.h"
+#include "timing.h"
+
+#include "canonicalform.h"
+#include "fac_util.h"
+
+#ifdef HAVE_NTL
+/// sort a list of polynomials by their degree in @a x.
+///
+void sortList (CFList& list,     ///< [in, out] list of polys, sorted list
+               const Variable& x ///< [in] some Variable
+              );
+
+/// Hensel lift from univariate to bivariate.
+///
+/// @sa henselLiftResume12(), henselLift23(), henselLiftResume(), henselLift()
+void
+henselLift12 (const CanonicalForm& F, ///< [in] compressed, bivariate poly
+              CFList& factors,        ///< [in, out] monic univariate factors of
+                                      ///< F, including leading coefficient as
+                                      ///< first element. Returns monic lifted
+                                      ///< factors without the leading
+                                      ///< coefficient
+              int l,                  ///< [in] lifting precision
+              CFArray& Pi,            ///< [in,out] stores intermediate results
+              CFList& diophant,       ///< [in,out] result of diophantine()
+              CFMatrix& M,            ///< [in,out] stores intermediate results
+              modpk& b,               ///< [in] coeff bound
+              bool sort= true         ///< [in] sort factors by degree in
+                                      ///< Variable(1)
+             );
+
+/// Hensel lift from univariate to bivariate.
+///
+/// @sa henselLiftResume12(), henselLift23(), henselLiftResume(), henselLift()
+void
+henselLift12 (const CanonicalForm& F, ///< [in] compressed, bivariate poly
+              CFList& factors,        ///< [in, out] monic univariate factors of
+                                      ///< F, including leading coefficient as
+                                      ///< first element. Returns monic lifted
+                                      ///< factors without the leading
+                                      ///< coefficient
+              int l,                  ///< [in] lifting precision
+              CFArray& Pi,            ///< [in,out] stores intermediate results
+              CFList& diophant,       ///< [in,out] result of diophantine()
+              CFMatrix& M,            ///< [in,out] stores intermediate results
+              bool sort= true        ///< [in] sort factors by degree in
+                                      ///< Variable(1)
+             );
+
+/// resume Hensel lift from univariate to bivariate. Assumes factors are lifted
+/// to precision Variable (2)^start and lifts them to precision Variable (2)^end
+///
+/// @sa henselLift12(), henselLift23(), henselLiftResume(), henselLift()
+void
+henselLiftResume12 (const CanonicalForm& F, ///< [in] compressed, bivariate poly
+                    CFList& factors,        ///< [in,out] monic factors of F,
+                                            ///< lifted to precision start,
+                                            ///< including leading coefficient
+                                            ///< as first element. Returns monic
+                                            ///< lifted factors without the
+                                            ///< leading coefficient
+                    int start,              ///< [in] starting precision
+                    int end,                ///< [in] end precision
+                    CFArray& Pi,            ///< [in,out] stores intermediate
+                                            ///< results
+                    const CFList& diophant, ///< [in] result of diophantine
+                    CFMatrix& M,            ///< [in,out] stores intermediate
+                                            ///< results
+                    const modpk& b= modpk() ///< [in] coeff bound
+                   );
+
+/// Hensel lifting from bivariate to trivariate.
+///
+/// @return @a henselLift23 returns a list of polynomials lifted to precision
+///          Variable (3)^l[1]
+/// @sa henselLift12(), henselLiftResume12(), henselLiftResume(), henselLift()
+CFList
+henselLift23 (const CFList& eval,    ///< [in] contains compressed, bivariate
+                                     ///< as first element and trivariate one as
+                                     ///< second element
+              const CFList& factors, ///< [in] monic bivariate factors,
+                                     ///< including leading coefficient
+                                     ///< as first element.
+              int* l,          ///< [in] l[0]: precision of bivariate
+                                     ///< lifting, l[1] as above
+              CFList& diophant,      ///< [in,out] returns the result of
+                                     ///< biDiophantine()
+              CFArray& Pi,           ///< [in,out] stores intermediate results
+              CFMatrix& M            ///< [in,out] stores intermediate results
+             );
+
+/// resume Hensel lifting.
+///
+/// @sa henselLift12(), henselLiftResume12(), henselLift23(), henselLift()
+void
+henselLiftResume (
+              const CanonicalForm& F, ///< [in] compressed, multivariate poly
+              CFList& factors,        ///< [in,out] monic multivariate factors
+                                      ///< lifted to precision F.mvar()^start,
+                                      ///< including leading coefficient
+                                      ///< as first element. Returns factors
+                                      ///< lifted to precision F.mvar()^end
+              int start,              ///< [in] starting precision
+              int end,                ///< [in] end precision
+              CFArray& Pi,            ///< [in,out] stores intermediate results
+              const CFList& diophant, ///< [in] result of multiRecDiophantine()
+              CFMatrix& M,            ///< [in, out] stores intermediate results
+              const CFList& MOD       ///< [in] a list of powers of Variables
+                                      ///< of level higher than 1
+                 );
+
+/// Hensel lifting
+///
+/// @return @a henselLift returns a list of polynomials lifted to
+///          precision F.getLast().mvar()^l_new
+/// @sa henselLift12(), henselLiftResume12(), henselLift23(), henselLiftResume()
+CFList
+henselLift (const CFList& F,       ///< [in] two compressed, multivariate
+                                   ///< polys F and G
+            const CFList& factors, ///< [in] monic multivariate factors
+                                   ///< including leading coefficient
+                                   ///< as first element.
+            const CFList& MOD,     ///< [in] a list of powers of Variables
+                                   ///< of level higher than 1
+            CFList& diophant,      ///< [in,out] result of multiRecDiophantine()
+            CFArray& Pi,           ///< [in,out] stores intermediate results
+            CFMatrix& M,           ///< [in,out] stores intermediate results
+            int lOld,       ///< [in] lifting precision of F.mvar()
+            int lNew        ///< [in] lifting precision of G.mvar()
+           );
+
+/// Hensel lifting from bivariate to multivariate
+///
+/// @return @a henselLift returns a list of lifted factors
+/// @sa henselLift12(), henselLiftResume12(), henselLift23(), henselLiftResume()
+CFList
+henselLift (const CFList& eval,    ///< [in] a list of polynomials the last
+                                   ///< element is a compressed multivariate
+                                   ///< poly, last but one element equals the
+                                   ///< last elements modulo its main variable
+                                   ///< and so on. The first element is a
+                                   ///< compressed bivariate poly.
+            const CFList& factors, ///< [in] bivariate factors, including
+                                   ///< leading coefficient
+            int* l,          ///< [in] lifting bounds
+            int lLength,     ///< [in] length of l
+            bool sort= true        ///< [in] sort factors by degree in
+                                   ///< Variable(1)
+           );
+
+/// Hensel lifting from univariate to bivariate, factors need not to be monic
+void
+nonMonicHenselLift12 (const CanonicalForm& F,///< [in] a bivariate poly
+               CFList& factors,       ///< [in, out] a list of univariate polys
+                                      ///< lifted factors
+               int l,                 ///< [in] lift bound
+               CFArray& Pi,           ///< [in, out] stores intermediate results
+               CFList& diophant,      ///< [in, out] result of diophantine
+               CFMatrix& M,           ///< [in, out] stores intermediate results
+               const CFArray& LCs,    ///< [in] leading coefficients
+               bool sort              ///< [in] if true factors are sorted by
+                                      ///< their degree
+              );
+
+/// two factor Hensel lifting from bivariate to multivariate, factors need not
+/// to be monic
+///
+/// @return @a henselLift122 returns a list of lifted factors
+CFList
+nonMonicHenselLift2 (const CFList& eval,///< [in] a list of polynomials the last
+                                   ///< element is a compressed multivariate
+                                   ///< poly, last but one element equals the
+                                   ///< last elements modulo its main variable
+                                   ///< and so on. The first element is a
+                                   ///< compressed bivariate poly.
+             const CFList& factors,///< [in] bivariate factors
+             int* l,               ///< [in] lift bounds
+             int lLength,          ///< [in] length of l
+             bool sort,            ///< [in] if true factors are sorted by
+                                   ///< their degree in Variable(1)
+             const CFList& LCs1,   ///< [in] a list of evaluated LC of first
+                                   ///< factor
+             const CFList& LCs2,   ///< [in] a list of evaluated LC of second
+                                   ///< factor
+             const CFArray& Pi,    ///< [in] intermediate result
+             const CFList& diophant,///< [in] result of diophantine
+             bool& noOneToOne      ///< [in,out] check for one to one
+                                   ///< correspondence
+            );
+
+/// Hensel lifting of non monic factors, needs correct leading coefficients of
+/// factors and a one to one corresponds between bivariate and multivariate
+/// factors to succeed
+///
+/// @return @a nonMonicHenselLift returns a list of lifted factors
+/// such that prod (factors) == eval.getLast() if there is a one to one
+/// correspondence
+CFList
+nonMonicHenselLift (const CFList& eval,    ///< [in] a list of polys the last
+                                           ///< element is a compressed
+                                           ///< multivariate poly, last but one
+                                           ///< element equals the last elements
+                                           ///< modulo its main variable and so
+                                           ///< on. The first element is a
+                                           ///< compressed poly in 3 variables
+                    const CFList& factors, ///< [in] a list of bivariate factors
+                    CFList* const& LCs,    ///< [in] leading coefficients,
+                                           ///< evaluated in the same way as
+                                           ///< eval
+                    CFList& diophant,      ///< [in, out] solution of univariate
+                                           ///< diophantine equation
+                    CFArray& Pi,           ///< [in, out] buffer intermediate
+                                           ///< results
+                    int* liftBound,        ///< [in] lifting bounds
+                    int length,            ///< [in] length of lifting bounds
+                    bool& noOneToOne       ///< [in, out] check for one to one
+                                           ///< correspondence
+                   );
+#endif /* HAVE_NTL */
+#endif
+/* FAC_HENSEL_H */
+
diff --git a/factory/facIrredTest.cc b/factory/facIrredTest.cc
new file mode 100644
index 0000000..1888079
--- /dev/null
+++ b/factory/facIrredTest.cc
@@ -0,0 +1,113 @@
+/*****************************************************************************\
+ * Computer Algebra System SINGULAR
+\*****************************************************************************/
+/** @file facIrredTest.cc
+ *
+ * This file implements a probabilistic irreducibility test for polynomials over
+ * Z/p.
+ *
+ * @author Martin Lee
+ *
+ **/
+/*****************************************************************************/
+
+
+#include "config.h"
+
+#include <math.h>
+
+#include "facIrredTest.h"
+#include "cf_map.h"
+#include "cf_random.h"
+
+//returns 0 if number of zeros/k >= l
+double numZeros (const CanonicalForm& F, int k)
+{
+  int result= 0;
+
+  FFRandom FFgen;
+  CanonicalForm buf;
+  for (int i= 0; i < k; i++)
+  {
+    buf= F;
+    for (int j= F.level(); j > 0; j++)
+      buf= buf (FFgen.generate(), j);
+    if (buf.isZero())
+      result++;
+  }
+
+  return (double) result/k;
+}
+
+double inverseERF (double d)
+{
+  double pi= 3.141592653589793;
+  double a= 0.140012288;
+
+  double buf1;
+  double buf= 2.0/(pi*a)+log (1.0-d*d)/2.0;
+  buf1= buf;
+  buf *= buf;
+  buf -= log (1.0-d*d)/a;
+  buf= sqrt (buf);
+  buf -= buf1;
+  buf= sqrt (buf);
+
+  if (d < 0)
+    buf= -buf;
+
+  return buf;
+}
+
+//doesn't make much sense to use this if getCharacteristic() > 17 ?
+int probIrredTest (const CanonicalForm& F, double error)
+{
+  CFMap N;
+  CanonicalForm G= compress (F, N);
+  int n= G.level();
+  int p= getCharacteristic();
+
+  double sqrtTrials= inverseERF (1-2.0*error)*sqrt (2.0);
+
+  double s= sqrtTrials;
+
+  double pn= pow ((double) p, (double) n);
+  double p1= (double) 1/p;
+  p1= p1*(1.0-p1);
+  p1= p1/(double) pn;
+  p1= sqrt (p1);
+  p1 *= s;
+  p1 += (double) 1/p;
+
+  double p2= (double) (2*p-1)/(p*p);
+  p2= p2*(1-p2);
+  p2= p2/(double) pn;
+  p2= sqrt (p2);
+  p2 *= s;
+  p2= (double) (2*p - 1)/(p*p)-p2;
+
+  //no testing possible
+  if (p2 < p1)
+    return 0;
+
+  double den= sqrt (p1*(1-p1))+sqrt (p2*(1-p2));
+  double num= p2-p1;
+
+  sqrtTrials *= den/num;
+
+  int trials= (int) floor (pow (sqrtTrials, 2.0));
+
+  double experimentalNumZeros= numZeros (G, trials);
+
+  double pmiddle= sqrt (p1*p2);
+
+  num= den;
+  den= sqrt (p1*(1.0-p2))+sqrt (p2*(1.0-p1));
+  pmiddle *= (den/num);
+
+  if (experimentalNumZeros < pmiddle)
+    return 1;
+  else
+    return -1;
+}
+
diff --git a/factory/facIrredTest.h b/factory/facIrredTest.h
new file mode 100644
index 0000000..6a195dc
--- /dev/null
+++ b/factory/facIrredTest.h
@@ -0,0 +1,47 @@
+/*****************************************************************************\
+ * Computer Algebra System SINGULAR
+\*****************************************************************************/
+/** @file facIrredTest.h
+ *
+ * This file provides a probabilistic irreducibility test for polynomials over
+ * Z/p.
+ *
+ * ABSTRACT: irreducibility test based on "Quick and Dirty Irreducibility Test"
+ * by v. Bothmer and Schreyer
+ *
+ * @author Martin Lee
+ *
+ **/
+/*****************************************************************************/
+
+#ifndef FAC_IRRED_TEST_H
+#define FAC_IRRED_TEST_H
+
+// #include "config.h"
+
+#include "canonicalform.h"
+
+/// evaluate F at k random points in Z/p^n and count the number of zeros that
+/// occur
+///
+/// @return numZeros returns #zeros/trials
+double numZeros (const CanonicalForm& F, ///< [in] some poly over Z/p with n
+                                         ///< variables
+                 int k                   ///< [in] number of trials
+                );
+
+/*BEGINPUBLIC*/
+
+/// given some error probIrredTest detects irreducibility or reducibility of F
+/// with confidence level 1-error
+///
+/// @return probIrredTest returns 1 for irreducibility, -1 for reducibility
+///         or 0 if the test is not applicable
+int probIrredTest (const CanonicalForm& F, ///< [in] some poly over Z/p
+                   double error            ///< [in] 0 < error < 1
+                  );
+
+/*ENDPUBLIC*/
+
+#endif
+
diff --git a/factory/facMul.cc b/factory/facMul.cc
new file mode 100644
index 0000000..dbf12eb
--- /dev/null
+++ b/factory/facMul.cc
@@ -0,0 +1,3729 @@
+/*****************************************************************************\
+ * Computer Algebra System SINGULAR
+\*****************************************************************************/
+/** @file facMul.cc
+ *
+ * This file implements functions for fast multiplication and division with
+ * remainder.
+ *
+ * Nomenclature rules: kronSub* -> plain Kronecker substitution
+ *                     reverseSubst* -> reverse Kronecker substitution
+ *                     kronSubRecipro* -> reciprocal Kronecker substitution as
+ *                                        described in D. Harvey "Faster
+ *                                        polynomial multiplication via
+ *                                        multipoint Kronecker substitution"
+ *
+ * @author Martin Lee
+ *
+ **/
+/*****************************************************************************/
+
+#include "debug.h"
+
+#include "config.h"
+
+
+#include "canonicalform.h"
+#include "facMul.h"
+#include "cf_util.h"
+#include "templates/ftmpl_functions.h"
+
+#ifdef HAVE_NTL
+#include <NTL/lzz_pEX.h>
+#include "NTLconvert.h"
+
+#ifdef HAVE_FLINT
+#include "FLINTconvert.h"
+#endif
+
+// univariate polys
+
+#ifdef HAVE_FLINT
+void kronSubQa (fmpz_poly_t result, const CanonicalForm& A, int d)
+{
+  int degAy= degree (A);
+  fmpz_poly_init2 (result, d*(degAy + 1));
+  _fmpz_poly_set_length (result, d*(degAy + 1));
+  CFIterator j;
+  for (CFIterator i= A; i.hasTerms(); i++)
+  {
+    if (i.coeff().inBaseDomain())
+      convertCF2Fmpz (fmpz_poly_get_coeff_ptr (result, i.exp()*d), i.coeff());
+    else
+      for (j= i.coeff(); j.hasTerms(); j++)
+        convertCF2Fmpz (fmpz_poly_get_coeff_ptr (result, i.exp()*d+j.exp()),
+                        j.coeff());
+  }
+  _fmpz_poly_normalise(result);
+}
+
+
+CanonicalForm
+reverseSubstQa (const fmpz_poly_t F, int d, const Variable& x,
+                const Variable& alpha, const CanonicalForm& den)
+{
+  CanonicalForm result= 0;
+  int i= 0;
+  int degf= fmpz_poly_degree (F);
+  int k= 0;
+  int degfSubK;
+  int repLength;
+  fmpq_poly_t buf;
+  fmpq_poly_t mipo;
+  convertFacCF2Fmpq_poly_t (mipo, getMipo(alpha));
+  while (degf >= k)
+  {
+    degfSubK= degf - k;
+    if (degfSubK >= d)
+      repLength= d;
+    else
+      repLength= degfSubK + 1;
+
+    fmpq_poly_init2 (buf, repLength);
+    _fmpq_poly_set_length (buf, repLength);
+    _fmpz_vec_set (buf->coeffs, F->coeffs + k, repLength);
+    _fmpq_poly_normalise (buf);
+    fmpq_poly_rem (buf, buf, mipo);
+
+    result += convertFmpq_poly_t2FacCF (buf, alpha)*power (x, i);
+    fmpq_poly_clear (buf);
+    i++;
+    k= d*i;
+  }
+  fmpq_poly_clear (mipo);
+  result /= den;
+  return result;
+}
+
+CanonicalForm
+mulFLINTQa (const CanonicalForm& F, const CanonicalForm& G,
+            const Variable& alpha)
+{
+  CanonicalForm A= F;
+  CanonicalForm B= G;
+
+  CanonicalForm denA= bCommonDen (A);
+  CanonicalForm denB= bCommonDen (B);
+
+  A *= denA;
+  B *= denB;
+  int degAa= degree (A, alpha);
+  int degBa= degree (B, alpha);
+  int d= degAa + 1 + degBa;
+
+  fmpz_poly_t FLINTA,FLINTB;
+  kronSubQa (FLINTA, A, d);
+  kronSubQa (FLINTB, B, d);
+
+  fmpz_poly_mul (FLINTA, FLINTA, FLINTB);
+
+  denA *= denB;
+  A= reverseSubstQa (FLINTA, d, F.mvar(), alpha, denA);
+
+  fmpz_poly_clear (FLINTA);
+  fmpz_poly_clear (FLINTB);
+  return A;
+}
+
+CanonicalForm
+mulFLINTQ (const CanonicalForm& F, const CanonicalForm& G)
+{
+  CanonicalForm A= F;
+  CanonicalForm B= G;
+
+  CanonicalForm denA= bCommonDen (A);
+  CanonicalForm denB= bCommonDen (B);
+
+  A *= denA;
+  B *= denB;
+  fmpz_poly_t FLINTA,FLINTB;
+  convertFacCF2Fmpz_poly_t (FLINTA, A);
+  convertFacCF2Fmpz_poly_t (FLINTB, B);
+  fmpz_poly_mul (FLINTA, FLINTA, FLINTB);
+  denA *= denB;
+  A= convertFmpz_poly_t2FacCF (FLINTA, F.mvar());
+  A /= denA;
+  fmpz_poly_clear (FLINTA);
+  fmpz_poly_clear (FLINTB);
+
+  return A;
+}
+
+/*CanonicalForm
+mulFLINTQ2 (const CanonicalForm& F, const CanonicalForm& G)
+{
+  CanonicalForm A= F;
+  CanonicalForm B= G;
+
+  fmpq_poly_t FLINTA,FLINTB;
+  convertFacCF2Fmpq_poly_t (FLINTA, A);
+  convertFacCF2Fmpq_poly_t (FLINTB, B);
+
+  fmpq_poly_mul (FLINTA, FLINTA, FLINTB);
+  A= convertFmpq_poly_t2FacCF (FLINTA, F.mvar());
+  fmpq_poly_clear (FLINTA);
+  fmpq_poly_clear (FLINTB);
+  return A;
+}*/
+
+CanonicalForm
+divFLINTQ (const CanonicalForm& F, const CanonicalForm& G)
+{
+  CanonicalForm A= F;
+  CanonicalForm B= G;
+
+  fmpq_poly_t FLINTA,FLINTB;
+  convertFacCF2Fmpq_poly_t (FLINTA, A);
+  convertFacCF2Fmpq_poly_t (FLINTB, B);
+
+  fmpq_poly_div (FLINTA, FLINTA, FLINTB);
+  A= convertFmpq_poly_t2FacCF (FLINTA, F.mvar());
+
+  fmpq_poly_clear (FLINTA);
+  fmpq_poly_clear (FLINTB);
+  return A;
+}
+
+CanonicalForm
+modFLINTQ (const CanonicalForm& F, const CanonicalForm& G)
+{
+  CanonicalForm A= F;
+  CanonicalForm B= G;
+
+  fmpq_poly_t FLINTA,FLINTB;
+  convertFacCF2Fmpq_poly_t (FLINTA, A);
+  convertFacCF2Fmpq_poly_t (FLINTB, B);
+
+  fmpq_poly_rem (FLINTA, FLINTA, FLINTB);
+  A= convertFmpq_poly_t2FacCF (FLINTA, F.mvar());
+
+  fmpq_poly_clear (FLINTA);
+  fmpq_poly_clear (FLINTB);
+  return A;
+}
+
+CanonicalForm
+mulFLINTQaTrunc (const CanonicalForm& F, const CanonicalForm& G,
+                 const Variable& alpha, int m)
+{
+  CanonicalForm A= F;
+  CanonicalForm B= G;
+
+  CanonicalForm denA= bCommonDen (A);
+  CanonicalForm denB= bCommonDen (B);
+
+  A *= denA;
+  B *= denB;
+
+  int degAa= degree (A, alpha);
+  int degBa= degree (B, alpha);
+  int d= degAa + 1 + degBa;
+
+  fmpz_poly_t FLINTA,FLINTB;
+  kronSubQa (FLINTA, A, d);
+  kronSubQa (FLINTB, B, d);
+
+  int k= d*m;
+  fmpz_poly_mullow (FLINTA, FLINTA, FLINTB, k);
+
+  denA *= denB;
+  A= reverseSubstQa (FLINTA, d, F.mvar(), alpha, denA);
+  fmpz_poly_clear (FLINTA);
+  fmpz_poly_clear (FLINTB);
+  return A;
+}
+
+CanonicalForm
+mulFLINTQTrunc (const CanonicalForm& F, const CanonicalForm& G, int m)
+{
+  if (F.inCoeffDomain() && G.inCoeffDomain())
+    return F*G;
+  if (F.inCoeffDomain())
+    return mod (F*G, power (G.mvar(), m));
+  if (G.inCoeffDomain())
+    return mod (F*G, power (F.mvar(), m));
+  Variable alpha;
+  if (hasFirstAlgVar (F, alpha) || hasFirstAlgVar (G, alpha))
+    return mulFLINTQaTrunc (F, G, alpha, m);
+
+  CanonicalForm A= F;
+  CanonicalForm B= G;
+
+  CanonicalForm denA= bCommonDen (A);
+  CanonicalForm denB= bCommonDen (B);
+
+  A *= denA;
+  B *= denB;
+  fmpz_poly_t FLINTA,FLINTB;
+  convertFacCF2Fmpz_poly_t (FLINTA, A);
+  convertFacCF2Fmpz_poly_t (FLINTB, B);
+  fmpz_poly_mullow (FLINTA, FLINTA, FLINTB, m);
+  denA *= denB;
+  A= convertFmpz_poly_t2FacCF (FLINTA, F.mvar());
+  A /= denA;
+  fmpz_poly_clear (FLINTA);
+  fmpz_poly_clear (FLINTB);
+
+  return A;
+}
+
+CanonicalForm uniReverse (const CanonicalForm& F, int d, const Variable& x)
+{
+  if (d == 0)
+    return F;
+  if (F.inCoeffDomain())
+    return F*power (x,d);
+  CanonicalForm result= 0;
+  CFIterator i= F;
+  while (d - i.exp() < 0)
+    i++;
+
+  for (; i.hasTerms() && (d - i.exp() >= 0); i++)
+    result += i.coeff()*power (x, d - i.exp());
+  return result;
+}
+
+CanonicalForm
+newtonInverse (const CanonicalForm& F, const int n, const Variable& x)
+{
+  int l= ilog2(n);
+
+  CanonicalForm g;
+  if (F.inCoeffDomain())
+    g= F;
+  else
+    g= F [0];
+
+  if (!F.inCoeffDomain())
+    ASSERT (F.mvar() == x, "main variable of F and x differ");
+  ASSERT (!g.isZero(), "expected a unit");
+
+  if (!g.isOne())
+    g = 1/g;
+  CanonicalForm result;
+  int exp= 0;
+  if (n & 1)
+  {
+    result= g;
+    exp= 1;
+  }
+  CanonicalForm h;
+
+  for (int i= 1; i <= l; i++)
+  {
+    h= mulNTL (g, mod (F, power (x, (1 << i))));
+    h= mod (h, power (x, (1 << i)) - 1);
+    h= div (h, power (x, (1 << (i - 1))));
+    g -= power (x, (1 << (i - 1)))*
+         mulFLINTQTrunc (g, h, 1 << (i-1));
+
+    if (n & (1 << i))
+    {
+      if (exp)
+      {
+        h= mulNTL (result, mod (F, power (x, exp + (1 << i))));
+        h= mod (h, power (x, exp + (1 << i)) - 1);
+        h= div (h, power (x, exp));
+        result -= power(x, exp)*mulFLINTQTrunc (g, h, 1 << i);
+        exp += (1 << i);
+      }
+      else
+      {
+        exp= (1 << i);
+        result= g;
+      }
+    }
+  }
+
+  return result;
+}
+
+void
+newtonDivrem (const CanonicalForm& F, const CanonicalForm& G, CanonicalForm& Q,
+              CanonicalForm& R)
+{
+  ASSERT (F.level() == G.level(), "F and G have different level");
+  CanonicalForm A= F;
+  CanonicalForm B= G;
+  Variable x= A.mvar();
+  int degA= degree (A);
+  int degB= degree (B);
+  int m= degA - degB;
+
+  if (m < 0)
+  {
+    R= A;
+    Q= 0;
+    return;
+  }
+
+  if (degB <= 1)
+    divrem (A, B, Q, R);
+  else
+  {
+    R= uniReverse (A, degA, x);
+
+    CanonicalForm revB= uniReverse (B, degB, x);
+    revB= newtonInverse (revB, m + 1, x);
+    Q= mulFLINTQTrunc (R, revB, m + 1);
+    Q= uniReverse (Q, m, x);
+
+    R= A - mulNTL (Q, B);
+  }
+}
+
+void
+newtonDiv (const CanonicalForm& F, const CanonicalForm& G, CanonicalForm& Q)
+{
+  ASSERT (F.level() == G.level(), "F and G have different level");
+  CanonicalForm A= F;
+  CanonicalForm B= G;
+  Variable x= A.mvar();
+  int degA= degree (A);
+  int degB= degree (B);
+  int m= degA - degB;
+
+  if (m < 0)
+  {
+    Q= 0;
+    return;
+  }
+
+  if (degB <= 1)
+    Q= div (A, B);
+  else
+  {
+    CanonicalForm R= uniReverse (A, degA, x);
+    CanonicalForm revB= uniReverse (B, degB, x);
+    revB= newtonInverse (revB, m + 1, x);
+    Q= mulFLINTQTrunc (R, revB, m + 1);
+    Q= uniReverse (Q, m, x);
+  }
+}
+
+#endif
+
+CanonicalForm
+mulNTL (const CanonicalForm& F, const CanonicalForm& G, const modpk& b)
+{
+  if (CFFactory::gettype() == GaloisFieldDomain)
+    return F*G;
+  if (getCharacteristic() == 0)
+  {
+    Variable alpha;
+    if ((!F.inCoeffDomain() && !G.inCoeffDomain()) &&
+        (hasFirstAlgVar (F, alpha) || hasFirstAlgVar (G, alpha)))
+    {
+      if (b.getp() != 0)
+      {
+        CanonicalForm mipo= getMipo (alpha);
+        bool is_rat= isOn (SW_RATIONAL);
+        if (!is_rat)
+          On (SW_RATIONAL);
+        mipo *=bCommonDen (mipo);
+        if (!is_rat)
+          Off (SW_RATIONAL);
+#if (HAVE_FLINT && __FLINT_RELEASE >= 20400)
+        fmpz_t FLINTp;
+        fmpz_mod_poly_t FLINTmipo;
+        fq_ctx_t fq_con;
+        fq_poly_t FLINTF, FLINTG;
+
+        fmpz_init (FLINTp);
+
+        convertCF2Fmpz (FLINTp, b.getpk());
+
+        convertFacCF2Fmpz_mod_poly_t (FLINTmipo, mipo, FLINTp);
+
+        fq_ctx_init_modulus (fq_con, FLINTmipo, "Z");
+
+        convertFacCF2Fq_poly_t (FLINTF, F, fq_con);
+        convertFacCF2Fq_poly_t (FLINTG, G, fq_con);
+
+        fq_poly_mul (FLINTF, FLINTF, FLINTG, fq_con);
+
+        CanonicalForm result= convertFq_poly_t2FacCF (FLINTF, F.mvar(),
+                                                      alpha, fq_con);
+
+        fmpz_clear (FLINTp);
+        fmpz_mod_poly_clear (FLINTmipo);
+        fq_poly_clear (FLINTF, fq_con);
+        fq_poly_clear (FLINTG, fq_con);
+        fq_ctx_clear (fq_con);
+        return b (result);
+#else
+        ZZ_p::init (convertFacCF2NTLZZ (b.getpk()));
+        ZZ_pX NTLmipo= to_ZZ_pX (convertFacCF2NTLZZX (mipo));
+        ZZ_pE::init (NTLmipo);
+        ZZ_pEX NTLg= convertFacCF2NTLZZ_pEX (G, NTLmipo);
+        ZZ_pEX NTLf= convertFacCF2NTLZZ_pEX (F, NTLmipo);
+        mul (NTLf, NTLf, NTLg);
+
+        return b (convertNTLZZ_pEX2CF (NTLf, F.mvar(), alpha));
+#endif
+      }
+#ifdef HAVE_FLINT
+      CanonicalForm result= mulFLINTQa (F, G, alpha);
+      return result;
+#else
+      return F*G;
+#endif
+    }
+    else if (!F.inCoeffDomain() && !G.inCoeffDomain())
+    {
+#ifdef HAVE_FLINT
+      if (b.getp() != 0)
+      {
+        fmpz_t FLINTpk;
+        fmpz_init (FLINTpk);
+        convertCF2Fmpz (FLINTpk, b.getpk());
+        fmpz_mod_poly_t FLINTF, FLINTG;
+        convertFacCF2Fmpz_mod_poly_t (FLINTF, F, FLINTpk);
+        convertFacCF2Fmpz_mod_poly_t (FLINTG, G, FLINTpk);
+        fmpz_mod_poly_mul (FLINTF, FLINTF, FLINTG);
+        CanonicalForm result= convertFmpz_mod_poly_t2FacCF (FLINTF, F.mvar(),b);
+        fmpz_mod_poly_clear (FLINTG);
+        fmpz_mod_poly_clear (FLINTF);
+        fmpz_clear (FLINTpk);
+        return result;
+      }
+      return mulFLINTQ (F, G);
+#else
+      if (b.getp() != 0)
+      {
+        ZZ_p::init (convertFacCF2NTLZZ (b.getpk()));
+        ZZX ZZf= convertFacCF2NTLZZX (F);
+        ZZX ZZg= convertFacCF2NTLZZX (G);
+        ZZ_pX NTLf= to_ZZ_pX (ZZf);
+        ZZ_pX NTLg= to_ZZ_pX (ZZg);
+        mul (NTLf, NTLf, NTLg);
+        return b (convertNTLZZX2CF (to_ZZX (NTLf), F.mvar()));
+      }
+      return F*G;
+#endif
+    }
+    if (b.getp() != 0)
+    {
+      if (!F.inBaseDomain() && !G.inBaseDomain())
+      {
+        if (hasFirstAlgVar (G, alpha) || hasFirstAlgVar (F, alpha))
+        {
+#if (HAVE_FLINT && __FLINT_RELEASE >= 20400)
+          fmpz_t FLINTp;
+          fmpz_mod_poly_t FLINTmipo;
+          fq_ctx_t fq_con;
+
+          fmpz_init (FLINTp);
+          convertCF2Fmpz (FLINTp, b.getpk());
+
+          convertFacCF2Fmpz_mod_poly_t (FLINTmipo, getMipo (alpha), FLINTp);
+
+          fq_ctx_init_modulus (fq_con, FLINTmipo, "Z");
+
+          CanonicalForm result;
+
+          if (F.inCoeffDomain() && !G.inCoeffDomain())
+          {
+            fq_poly_t FLINTG;
+            fmpz_poly_t FLINTF;
+            convertFacCF2Fmpz_poly_t (FLINTF, F);
+            convertFacCF2Fq_poly_t (FLINTG, G, fq_con);
+
+            fq_poly_scalar_mul_fq (FLINTG, FLINTG, FLINTF, fq_con);
+
+            result= convertFq_poly_t2FacCF (FLINTG, G.mvar(), alpha, fq_con);
+            fmpz_poly_clear (FLINTF);
+            fq_poly_clear (FLINTG, fq_con);
+          }
+          else if (!F.inCoeffDomain() && G.inCoeffDomain())
+          {
+            fq_poly_t FLINTF;
+            fmpz_poly_t FLINTG;
+
+            convertFacCF2Fmpz_poly_t (FLINTG, G);
+            convertFacCF2Fq_poly_t (FLINTF, F, fq_con);
+
+            fq_poly_scalar_mul_fq (FLINTF, FLINTF, FLINTG, fq_con);
+
+            result= convertFq_poly_t2FacCF (FLINTF, F.mvar(), alpha, fq_con);
+            fmpz_poly_clear (FLINTG);
+            fq_poly_clear (FLINTF, fq_con);
+          }
+          else
+          {
+            fq_t FLINTF, FLINTG;
+
+            convertFacCF2Fq_t (FLINTF, F, fq_con);
+            convertFacCF2Fq_t (FLINTG, G, fq_con);
+
+            fq_mul (FLINTF, FLINTF, FLINTG, fq_con);
+
+            result= convertFq_t2FacCF (FLINTF, alpha);
+            fq_clear (FLINTF, fq_con);
+            fq_clear (FLINTG, fq_con);
+          }
+
+          fmpz_clear (FLINTp);
+          fmpz_mod_poly_clear (FLINTmipo);
+          fq_ctx_clear (fq_con);
+
+          return b (result);
+#else
+          ZZ_p::init (convertFacCF2NTLZZ (b.getpk()));
+          ZZ_pX NTLmipo= to_ZZ_pX (convertFacCF2NTLZZX (getMipo (alpha)));
+          ZZ_pE::init (NTLmipo);
+
+          if (F.inCoeffDomain() && !G.inCoeffDomain())
+          {
+            ZZ_pEX NTLg= convertFacCF2NTLZZ_pEX (G, NTLmipo);
+            ZZ_pX NTLf= convertFacCF2NTLZZpX (F);
+            mul (NTLg, to_ZZ_pE (NTLf), NTLg);
+            return b (convertNTLZZ_pEX2CF (NTLg, G.mvar(), alpha));
+          }
+          else if (!F.inCoeffDomain() && G.inCoeffDomain())
+          {
+            ZZ_pX NTLg= convertFacCF2NTLZZpX (G);
+            ZZ_pEX NTLf= convertFacCF2NTLZZ_pEX (F, NTLmipo);
+            mul (NTLf, NTLf, to_ZZ_pE (NTLg));
+            return b (convertNTLZZ_pEX2CF (NTLf, F.mvar(), alpha));
+          }
+          else
+          {
+            ZZ_pX NTLg= convertFacCF2NTLZZpX (G);
+            ZZ_pX NTLf= convertFacCF2NTLZZpX (F);
+            ZZ_pE result;
+            mul (result, to_ZZ_pE (NTLg), to_ZZ_pE (NTLf));
+            return b (convertNTLZZpX2CF (rep (result), alpha));
+          }
+#endif
+        }
+      }
+      return b (F*G);
+    }
+    return F*G;
+  }
+  else if (F.inCoeffDomain() || G.inCoeffDomain())
+    return F*G;
+  ASSERT (F.isUnivariate() && G.isUnivariate(), "expected univariate polys");
+  ASSERT (F.level() == G.level(), "expected polys of same level");
+  if (fac_NTL_char != getCharacteristic())
+  {
+    fac_NTL_char= getCharacteristic();
+    zz_p::init (getCharacteristic());
+  }
+  Variable alpha;
+  CanonicalForm result;
+  if (hasFirstAlgVar (F, alpha) || hasFirstAlgVar (G, alpha))
+  {
+    if (!getReduce (alpha))
+    {
+      result= 0;
+      for (CFIterator i= F; i.hasTerms(); i++)
+        result += i.coeff()*G*power (F.mvar(),i.exp());
+      return result;
+    }
+#if (HAVE_FLINT &&  __FLINT_RELEASE >= 20400)
+    nmod_poly_t FLINTmipo;
+    fq_nmod_ctx_t fq_con;
+
+    nmod_poly_init (FLINTmipo, getCharacteristic());
+    convertFacCF2nmod_poly_t (FLINTmipo, getMipo (alpha));
+
+    fq_nmod_ctx_init_modulus (fq_con, FLINTmipo, "Z");
+
+    fq_nmod_poly_t FLINTF, FLINTG;
+    convertFacCF2Fq_nmod_poly_t (FLINTF, F, fq_con);
+    convertFacCF2Fq_nmod_poly_t (FLINTG, G, fq_con);
+
+    fq_nmod_poly_mul (FLINTF, FLINTF, FLINTG, fq_con);
+
+    result= convertFq_nmod_poly_t2FacCF (FLINTF, F.mvar(), alpha, fq_con);
+
+    fq_nmod_poly_clear (FLINTF, fq_con);
+    fq_nmod_poly_clear (FLINTG, fq_con);
+    nmod_poly_clear (FLINTmipo);
+    fq_nmod_ctx_clear (fq_con);
+#else
+    zz_pX NTLMipo= convertFacCF2NTLzzpX (getMipo (alpha));
+    zz_pE::init (NTLMipo);
+    zz_pEX NTLF= convertFacCF2NTLzz_pEX (F, NTLMipo);
+    zz_pEX NTLG= convertFacCF2NTLzz_pEX (G, NTLMipo);
+    mul (NTLF, NTLF, NTLG);
+    result= convertNTLzz_pEX2CF(NTLF, F.mvar(), alpha);
+#endif
+  }
+  else
+  {
+#ifdef HAVE_FLINT
+    nmod_poly_t FLINTF, FLINTG;
+    convertFacCF2nmod_poly_t (FLINTF, F);
+    convertFacCF2nmod_poly_t (FLINTG, G);
+    nmod_poly_mul (FLINTF, FLINTF, FLINTG);
+    result= convertnmod_poly_t2FacCF (FLINTF, F.mvar());
+    nmod_poly_clear (FLINTF);
+    nmod_poly_clear (FLINTG);
+#else
+    zz_pX NTLF= convertFacCF2NTLzzpX (F);
+    zz_pX NTLG= convertFacCF2NTLzzpX (G);
+    mul (NTLF, NTLF, NTLG);
+    result= convertNTLzzpX2CF(NTLF, F.mvar());
+#endif
+  }
+  return result;
+}
+
+CanonicalForm
+modNTL (const CanonicalForm& F, const CanonicalForm& G, const modpk& b)
+{
+  if (CFFactory::gettype() == GaloisFieldDomain)
+    return mod (F, G);
+  if (F.inCoeffDomain() && G.isUnivariate() && !G.inCoeffDomain())
+  {
+    if (b.getp() != 0)
+      return b(F);
+    return F;
+  }
+  else if (F.inCoeffDomain() && G.inCoeffDomain())
+  {
+    if (b.getp() != 0)
+      return b(F%G);
+    return mod (F, G);
+  }
+  else if (F.isUnivariate() && G.inCoeffDomain())
+  {
+    if (b.getp() != 0)
+      return b(F%G);
+    return mod (F,G);
+  }
+
+  if (getCharacteristic() == 0)
+  {
+    Variable alpha;
+    if (!hasFirstAlgVar (F, alpha) && !hasFirstAlgVar (G, alpha))
+    {
+#ifdef HAVE_FLINT
+      if (b.getp() != 0)
+      {
+        fmpz_t FLINTpk;
+        fmpz_init (FLINTpk);
+        convertCF2Fmpz (FLINTpk, b.getpk());
+        fmpz_mod_poly_t FLINTF, FLINTG;
+        convertFacCF2Fmpz_mod_poly_t (FLINTF, F, FLINTpk);
+        convertFacCF2Fmpz_mod_poly_t (FLINTG, G, FLINTpk);
+        fmpz_mod_poly_divrem (FLINTG, FLINTF, FLINTF, FLINTG);
+        CanonicalForm result= convertFmpz_mod_poly_t2FacCF (FLINTF,F.mvar(),b);
+        fmpz_mod_poly_clear (FLINTG);
+        fmpz_mod_poly_clear (FLINTF);
+        fmpz_clear (FLINTpk);
+        return result;
+      }
+      return modFLINTQ (F, G);
+#else
+      if (b.getp() != 0)
+      {
+        ZZ_p::init (convertFacCF2NTLZZ (b.getpk()));
+        ZZX ZZf= convertFacCF2NTLZZX (F);
+        ZZX ZZg= convertFacCF2NTLZZX (G);
+        ZZ_pX NTLf= to_ZZ_pX (ZZf);
+        ZZ_pX NTLg= to_ZZ_pX (ZZg);
+        rem (NTLf, NTLf, NTLg);
+        return b (convertNTLZZX2CF (to_ZZX (NTLf), F.mvar()));
+      }
+      return mod (F, G);
+#endif
+    }
+    else
+    {
+      if (b.getp() != 0)
+      {
+#if (HAVE_FLINT &&  __FLINT_RELEASE >= 20400)
+        fmpz_t FLINTp;
+        fmpz_mod_poly_t FLINTmipo;
+        fq_ctx_t fq_con;
+        fq_poly_t FLINTF, FLINTG;
+
+        fmpz_init (FLINTp);
+
+        convertCF2Fmpz (FLINTp, b.getpk());
+
+        convertFacCF2Fmpz_mod_poly_t (FLINTmipo, getMipo (alpha), FLINTp);
+
+        fq_ctx_init_modulus (fq_con, FLINTmipo, "Z");
+
+        convertFacCF2Fq_poly_t (FLINTF, F, fq_con);
+        convertFacCF2Fq_poly_t (FLINTG, G, fq_con);
+
+        fq_poly_rem (FLINTF, FLINTF, FLINTG, fq_con);
+
+        CanonicalForm result= convertFq_poly_t2FacCF (FLINTF, F.mvar(),
+                                                      alpha, fq_con);
+
+        fmpz_clear (FLINTp);
+        fmpz_mod_poly_clear (FLINTmipo);
+        fq_poly_clear (FLINTF, fq_con);
+        fq_poly_clear (FLINTG, fq_con);
+        fq_ctx_clear (fq_con);
+
+        return b(result);
+#else
+        ZZ_p::init (convertFacCF2NTLZZ (b.getpk()));
+        ZZ_pX NTLmipo= to_ZZ_pX (convertFacCF2NTLZZX (getMipo (alpha)));
+        ZZ_pE::init (NTLmipo);
+        ZZ_pEX NTLg= convertFacCF2NTLZZ_pEX (G, NTLmipo);
+        ZZ_pEX NTLf= convertFacCF2NTLZZ_pEX (F, NTLmipo);
+        rem (NTLf, NTLf, NTLg);
+        return b (convertNTLZZ_pEX2CF (NTLf, F.mvar(), alpha));
+#endif
+      }
+#ifdef HAVE_FLINT
+      CanonicalForm Q, R;
+      newtonDivrem (F, G, Q, R);
+      return R;
+#else
+      return mod (F,G);
+#endif
+    }
+  }
+
+  ASSERT (F.isUnivariate() && G.isUnivariate(), "expected univariate polys");
+  ASSERT (F.level() == G.level(), "expected polys of same level");
+  if (fac_NTL_char != getCharacteristic())
+  {
+    fac_NTL_char= getCharacteristic();
+    zz_p::init (getCharacteristic());
+  }
+  Variable alpha;
+  CanonicalForm result;
+  if (hasFirstAlgVar (F, alpha) || hasFirstAlgVar (G, alpha))
+  {
+#if (HAVE_FLINT &&  __FLINT_RELEASE >= 20400)
+    nmod_poly_t FLINTmipo;
+    fq_nmod_ctx_t fq_con;
+
+    nmod_poly_init (FLINTmipo, getCharacteristic());
+    convertFacCF2nmod_poly_t (FLINTmipo, getMipo (alpha));
+
+    fq_nmod_ctx_init_modulus (fq_con, FLINTmipo, "Z");
+
+    fq_nmod_poly_t FLINTF, FLINTG;
+    convertFacCF2Fq_nmod_poly_t (FLINTF, F, fq_con);
+    convertFacCF2Fq_nmod_poly_t (FLINTG, G, fq_con);
+
+    fq_nmod_poly_rem (FLINTF, FLINTF, FLINTG, fq_con);
+
+    result= convertFq_nmod_poly_t2FacCF (FLINTF, F.mvar(), alpha, fq_con);
+
+    fq_nmod_poly_clear (FLINTF, fq_con);
+    fq_nmod_poly_clear (FLINTG, fq_con);
+    nmod_poly_clear (FLINTmipo);
+    fq_nmod_ctx_clear (fq_con);
+#else
+    zz_pX NTLMipo= convertFacCF2NTLzzpX(getMipo (alpha));
+    zz_pE::init (NTLMipo);
+    zz_pEX NTLF= convertFacCF2NTLzz_pEX (F, NTLMipo);
+    zz_pEX NTLG= convertFacCF2NTLzz_pEX (G, NTLMipo);
+    rem (NTLF, NTLF, NTLG);
+    result= convertNTLzz_pEX2CF(NTLF, F.mvar(), alpha);
+#endif
+  }
+  else
+  {
+#ifdef HAVE_FLINT
+    nmod_poly_t FLINTF, FLINTG;
+    convertFacCF2nmod_poly_t (FLINTF, F);
+    convertFacCF2nmod_poly_t (FLINTG, G);
+    nmod_poly_divrem (FLINTG, FLINTF, FLINTF, FLINTG);
+    result= convertnmod_poly_t2FacCF (FLINTF, F.mvar());
+    nmod_poly_clear (FLINTF);
+    nmod_poly_clear (FLINTG);
+#else
+    zz_pX NTLF= convertFacCF2NTLzzpX (F);
+    zz_pX NTLG= convertFacCF2NTLzzpX (G);
+    rem (NTLF, NTLF, NTLG);
+    result= convertNTLzzpX2CF(NTLF, F.mvar());
+#endif
+  }
+  return result;
+}
+
+CanonicalForm
+divNTL (const CanonicalForm& F, const CanonicalForm& G, const modpk& b)
+{
+  if (CFFactory::gettype() == GaloisFieldDomain)
+    return div (F, G);
+  if (F.inCoeffDomain() && G.isUnivariate() && !G.inCoeffDomain())
+  {
+    return 0;
+  }
+  else if (F.inCoeffDomain() && G.inCoeffDomain())
+  {
+    if (b.getp() != 0)
+    {
+      if (!F.inBaseDomain() || !G.inBaseDomain())
+      {
+        Variable alpha;
+        hasFirstAlgVar (F, alpha);
+        hasFirstAlgVar (G, alpha);
+#if (HAVE_FLINT &&  __FLINT_RELEASE >= 20400)
+        fmpz_t FLINTp;
+        fmpz_mod_poly_t FLINTmipo;
+        fq_ctx_t fq_con;
+        fq_t FLINTF, FLINTG;
+
+        fmpz_init (FLINTp);
+        convertCF2Fmpz (FLINTp, b.getpk());
+
+        convertFacCF2Fmpz_mod_poly_t (FLINTmipo, getMipo (alpha), FLINTp);
+
+        fq_ctx_init_modulus (fq_con, FLINTmipo, "Z");
+
+        convertFacCF2Fq_t (FLINTF, F, fq_con);
+        convertFacCF2Fq_t (FLINTG, G, fq_con);
+
+        fq_inv (FLINTG, FLINTG, fq_con);
+        fq_mul (FLINTF, FLINTF, FLINTG, fq_con);
+
+        CanonicalForm result= convertFq_t2FacCF (FLINTF, alpha);
+
+        fmpz_clear (FLINTp);
+        fmpz_mod_poly_clear (FLINTmipo);
+        fq_clear (FLINTF, fq_con);
+        fq_clear (FLINTG, fq_con);
+        fq_ctx_clear (fq_con);
+        return b (result);
+#else
+        ZZ_p::init (convertFacCF2NTLZZ (b.getpk()));
+        ZZ_pX NTLmipo= to_ZZ_pX (convertFacCF2NTLZZX (getMipo (alpha)));
+        ZZ_pE::init (NTLmipo);
+        ZZ_pX NTLg= convertFacCF2NTLZZpX (G);
+        ZZ_pX NTLf= convertFacCF2NTLZZpX (F);
+        ZZ_pE result;
+        div (result, to_ZZ_pE (NTLf), to_ZZ_pE (NTLg));
+        return b (convertNTLZZpX2CF (rep (result), alpha));
+#endif
+      }
+      return b(div (F,G));
+    }
+    return div (F, G);
+  }
+  else if (F.isUnivariate() && G.inCoeffDomain())
+  {
+    if (b.getp() != 0)
+    {
+      if (!G.inBaseDomain())
+      {
+        Variable alpha;
+        hasFirstAlgVar (G, alpha);
+#if (HAVE_FLINT &&  __FLINT_RELEASE >= 20400)
+        fmpz_t FLINTp;
+        fmpz_mod_poly_t FLINTmipo;
+        fq_ctx_t fq_con;
+        fq_poly_t FLINTF;
+        fq_t FLINTG;
+
+        fmpz_init (FLINTp);
+        convertCF2Fmpz (FLINTp, b.getpk());
+
+        convertFacCF2Fmpz_mod_poly_t (FLINTmipo, getMipo (alpha), FLINTp);
+
+        fq_ctx_init_modulus (fq_con, FLINTmipo, "Z");
+
+        convertFacCF2Fq_poly_t (FLINTF, F, fq_con);
+        convertFacCF2Fq_t (FLINTG, G, fq_con);
+
+        fq_inv (FLINTG, FLINTG, fq_con);
+        fq_poly_scalar_mul_fq (FLINTF, FLINTF, FLINTG, fq_con);
+
+        CanonicalForm result= convertFq_poly_t2FacCF (FLINTF, F.mvar(),
+                                                      alpha, fq_con);
+
+        fmpz_clear (FLINTp);
+        fmpz_mod_poly_clear (FLINTmipo);
+        fq_poly_clear (FLINTF, fq_con);
+        fq_clear (FLINTG, fq_con);
+        fq_ctx_clear (fq_con);
+        return b (result);
+#else
+        ZZ_p::init (convertFacCF2NTLZZ (b.getpk()));
+        ZZ_pX NTLmipo= to_ZZ_pX (convertFacCF2NTLZZX (getMipo (alpha)));
+        ZZ_pE::init (NTLmipo);
+        ZZ_pX NTLg= convertFacCF2NTLZZpX (G);
+        ZZ_pEX NTLf= convertFacCF2NTLZZ_pEX (F, NTLmipo);
+        div (NTLf, NTLf, to_ZZ_pE (NTLg));
+        return b (convertNTLZZ_pEX2CF (NTLf, F.mvar(), alpha));
+#endif
+      }
+      return b(div (F,G));
+    }
+    return div (F, G);
+  }
+
+  if (getCharacteristic() == 0)
+  {
+
+    Variable alpha;
+    if (!hasFirstAlgVar (F, alpha) && !hasFirstAlgVar (G, alpha))
+    {
+#ifdef HAVE_FLINT
+      if (b.getp() != 0)
+      {
+        fmpz_t FLINTpk;
+        fmpz_init (FLINTpk);
+        convertCF2Fmpz (FLINTpk, b.getpk());
+        fmpz_mod_poly_t FLINTF, FLINTG;
+        convertFacCF2Fmpz_mod_poly_t (FLINTF, F, FLINTpk);
+        convertFacCF2Fmpz_mod_poly_t (FLINTG, G, FLINTpk);
+        fmpz_mod_poly_divrem (FLINTF, FLINTG, FLINTF, FLINTG);
+        CanonicalForm result= convertFmpz_mod_poly_t2FacCF (FLINTF,F.mvar(),b);
+        fmpz_mod_poly_clear (FLINTG);
+        fmpz_mod_poly_clear (FLINTF);
+        fmpz_clear (FLINTpk);
+        return result;
+      }
+      return divFLINTQ (F,G);
+#else
+      if (b.getp() != 0)
+      {
+        ZZ_p::init (convertFacCF2NTLZZ (b.getpk()));
+        ZZX ZZf= convertFacCF2NTLZZX (F);
+        ZZX ZZg= convertFacCF2NTLZZX (G);
+        ZZ_pX NTLf= to_ZZ_pX (ZZf);
+        ZZ_pX NTLg= to_ZZ_pX (ZZg);
+        div (NTLf, NTLf, NTLg);
+        return b (convertNTLZZX2CF (to_ZZX (NTLf), F.mvar()));
+      }
+      return div (F, G);
+#endif
+    }
+    else
+    {
+      if (b.getp() != 0)
+      {
+#if (HAVE_FLINT &&  __FLINT_RELEASE >= 20400)
+        fmpz_t FLINTp;
+        fmpz_mod_poly_t FLINTmipo;
+        fq_ctx_t fq_con;
+        fq_poly_t FLINTF, FLINTG;
+
+        fmpz_init (FLINTp);
+        convertCF2Fmpz (FLINTp, b.getpk());
+
+        convertFacCF2Fmpz_mod_poly_t (FLINTmipo, getMipo (alpha), FLINTp);
+
+        fq_ctx_init_modulus (fq_con, FLINTmipo, "Z");
+
+        convertFacCF2Fq_poly_t (FLINTF, F, fq_con);
+        convertFacCF2Fq_poly_t (FLINTG, G, fq_con);
+
+        fq_poly_divrem (FLINTF, FLINTG, FLINTF, FLINTG, fq_con);
+
+        CanonicalForm result= convertFq_poly_t2FacCF (FLINTF, F.mvar(),
+                                                      alpha, fq_con);
+
+        fmpz_clear (FLINTp);
+        fmpz_mod_poly_clear (FLINTmipo);
+        fq_ctx_clear (fq_con);
+        fq_poly_clear (FLINTF, fq_con);
+        fq_poly_clear (FLINTG, fq_con);
+        return b (result);
+#else
+        ZZ_p::init (convertFacCF2NTLZZ (b.getpk()));
+        ZZ_pX NTLmipo= to_ZZ_pX (convertFacCF2NTLZZX (getMipo (alpha)));
+        ZZ_pE::init (NTLmipo);
+        ZZ_pEX NTLg= convertFacCF2NTLZZ_pEX (G, NTLmipo);
+        ZZ_pEX NTLf= convertFacCF2NTLZZ_pEX (F, NTLmipo);
+        div (NTLf, NTLf, NTLg);
+        return b (convertNTLZZ_pEX2CF (NTLf, F.mvar(), alpha));
+#endif
+      }
+#ifdef HAVE_FLINT
+      CanonicalForm Q;
+      newtonDiv (F, G, Q);
+      return Q;
+#else
+      return div (F,G);
+#endif
+    }
+  }
+
+  ASSERT (F.isUnivariate() && G.isUnivariate(), "expected univariate polys");
+  ASSERT (F.level() == G.level(), "expected polys of same level");
+  if (fac_NTL_char != getCharacteristic())
+  {
+    fac_NTL_char= getCharacteristic();
+    zz_p::init (getCharacteristic());
+  }
+  Variable alpha;
+  CanonicalForm result;
+  if (hasFirstAlgVar (F, alpha) || hasFirstAlgVar (G, alpha))
+  {
+#if (HAVE_FLINT &&  __FLINT_RELEASE >= 20400)
+    nmod_poly_t FLINTmipo;
+    fq_nmod_ctx_t fq_con;
+
+    nmod_poly_init (FLINTmipo, getCharacteristic());
+    convertFacCF2nmod_poly_t (FLINTmipo, getMipo (alpha));
+
+    fq_nmod_ctx_init_modulus (fq_con, FLINTmipo, "Z");
+
+    fq_nmod_poly_t FLINTF, FLINTG;
+    convertFacCF2Fq_nmod_poly_t (FLINTF, F, fq_con);
+    convertFacCF2Fq_nmod_poly_t (FLINTG, G, fq_con);
+
+    fq_nmod_poly_divrem (FLINTF, FLINTG, FLINTF, FLINTG, fq_con);
+
+    result= convertFq_nmod_poly_t2FacCF (FLINTF, F.mvar(), alpha, fq_con);
+
+    fq_nmod_poly_clear (FLINTF, fq_con);
+    fq_nmod_poly_clear (FLINTG, fq_con);
+    nmod_poly_clear (FLINTmipo);
+    fq_nmod_ctx_clear (fq_con);
+#else
+    zz_pX NTLMipo= convertFacCF2NTLzzpX(getMipo (alpha));
+    zz_pE::init (NTLMipo);
+    zz_pEX NTLF= convertFacCF2NTLzz_pEX (F, NTLMipo);
+    zz_pEX NTLG= convertFacCF2NTLzz_pEX (G, NTLMipo);
+    div (NTLF, NTLF, NTLG);
+    result= convertNTLzz_pEX2CF(NTLF, F.mvar(), alpha);
+#endif
+  }
+  else
+  {
+#ifdef HAVE_FLINT
+    nmod_poly_t FLINTF, FLINTG;
+    convertFacCF2nmod_poly_t (FLINTF, F);
+    convertFacCF2nmod_poly_t (FLINTG, G);
+    nmod_poly_div (FLINTF, FLINTF, FLINTG);
+    result= convertnmod_poly_t2FacCF (FLINTF, F.mvar());
+    nmod_poly_clear (FLINTF);
+    nmod_poly_clear (FLINTG);
+#else
+    zz_pX NTLF= convertFacCF2NTLzzpX (F);
+    zz_pX NTLG= convertFacCF2NTLzzpX (G);
+    div (NTLF, NTLF, NTLG);
+    result= convertNTLzzpX2CF(NTLF, F.mvar());
+#endif
+  }
+  return result;
+}
+
+// end univariate polys
+//*************************
+// bivariate polys
+
+#ifdef HAVE_FLINT
+void kronSubFp (nmod_poly_t result, const CanonicalForm& A, int d)
+{
+  int degAy= degree (A);
+  nmod_poly_init2 (result, getCharacteristic(), d*(degAy + 1));
+  result->length= d*(degAy + 1);
+  flint_mpn_zero (result->coeffs, d*(degAy+1));
+
+  nmod_poly_t buf;
+
+  int k;
+  for (CFIterator i= A; i.hasTerms(); i++)
+  {
+    convertFacCF2nmod_poly_t (buf, i.coeff());
+    k= i.exp()*d;
+    flint_mpn_copyi (result->coeffs+k, buf->coeffs, nmod_poly_length(buf));
+
+    nmod_poly_clear (buf);
+  }
+  _nmod_poly_normalise (result);
+}
+
+#if ( __FLINT_RELEASE >= 20400)
+void
+kronSubFq (fq_nmod_poly_t result, const CanonicalForm& A, int d,
+           const fq_nmod_ctx_t fq_con)
+{
+  int degAy= degree (A);
+  fq_nmod_poly_init2 (result, d*(degAy + 1), fq_con);
+  _fq_nmod_poly_set_length (result, d*(degAy + 1), fq_con);
+  _fq_nmod_vec_zero (result->coeffs, d*(degAy + 1), fq_con);
+
+  fq_nmod_poly_t buf1;
+
+  nmod_poly_t buf2;
+
+  int k;
+
+  for (CFIterator i= A; i.hasTerms(); i++)
+  {
+    if (i.coeff().inCoeffDomain())
+    {
+      convertFacCF2nmod_poly_t (buf2, i.coeff());
+      fq_nmod_poly_init2 (buf1, 1, fq_con);
+      fq_nmod_poly_set_coeff (buf1, 0, buf2, fq_con);
+      nmod_poly_clear (buf2);
+    }
+    else
+      convertFacCF2Fq_nmod_poly_t (buf1, i.coeff(), fq_con);
+
+    k= i.exp()*d;
+    _fq_nmod_vec_set (result->coeffs+k, buf1->coeffs,
+                      fq_nmod_poly_length (buf1, fq_con), fq_con);
+
+    fq_nmod_poly_clear (buf1, fq_con);
+  }
+
+  _fq_nmod_poly_normalise (result, fq_con);
+}
+#endif
+
+/*void kronSubQa (fmpq_poly_t result, const CanonicalForm& A, int d1, int d2)
+{
+  int degAy= degree (A);
+  fmpq_poly_init2 (result, d1*(degAy + 1));
+
+  fmpq_poly_t buf;
+  fmpq_t coeff;
+
+  int k, l, bufRepLength;
+  CFIterator j;
+  for (CFIterator i= A; i.hasTerms(); i++)
+  {
+    if (i.coeff().inCoeffDomain())
+    {
+      k= d1*i.exp();
+      convertFacCF2Fmpq_poly_t (buf, i.coeff());
+      bufRepLength= (int) fmpq_poly_length(buf);
+      for (l= 0; l < bufRepLength; l++)
+      {
+        fmpq_poly_get_coeff_fmpq (coeff, buf, l);
+        fmpq_poly_set_coeff_fmpq (result, l + k, coeff);
+      }
+      fmpq_poly_clear (buf);
+    }
+    else
+    {
+      for (j= i.coeff(); j.hasTerms(); j++)
+      {
+        k= d1*i.exp();
+        k += d2*j.exp();
+        convertFacCF2Fmpq_poly_t (buf, j.coeff());
+        bufRepLength= (int) fmpq_poly_length(buf);
+        for (l= 0; l < bufRepLength; l++)
+        {
+          fmpq_poly_get_coeff_fmpq (coeff, buf, l);
+          fmpq_poly_set_coeff_fmpq (result, k + l, coeff);
+        }
+        fmpq_poly_clear (buf);
+      }
+    }
+  }
+  fmpq_clear (coeff);
+  _fmpq_poly_normalise (result);
+}*/
+
+void kronSubQa (fmpz_poly_t result, const CanonicalForm& A, int d1, int d2)
+{
+  int degAy= degree (A);
+  fmpz_poly_init2 (result, d1*(degAy + 1));
+  _fmpz_poly_set_length (result, d1*(degAy + 1));
+
+  fmpz_poly_t buf;
+
+  int k;
+  CFIterator j;
+  for (CFIterator i= A; i.hasTerms(); i++)
+  {
+    if (i.coeff().inCoeffDomain())
+    {
+      k= d1*i.exp();
+      convertFacCF2Fmpz_poly_t (buf, i.coeff());
+      _fmpz_vec_set (result->coeffs + k, buf->coeffs, buf->length);
+      fmpz_poly_clear (buf);
+    }
+    else
+    {
+      for (j= i.coeff(); j.hasTerms(); j++)
+      {
+        k= d1*i.exp();
+        k += d2*j.exp();
+        convertFacCF2Fmpz_poly_t (buf, j.coeff());
+        _fmpz_vec_set (result->coeffs + k, buf->coeffs, buf->length);
+        fmpz_poly_clear (buf);
+      }
+    }
+  }
+  _fmpz_poly_normalise (result);
+}
+
+void
+kronSubReciproFp (nmod_poly_t subA1, nmod_poly_t subA2, const CanonicalForm& A,
+                  int d)
+{
+  int degAy= degree (A);
+  mp_limb_t ninv= n_preinvert_limb (getCharacteristic());
+  nmod_poly_init2_preinv (subA1, getCharacteristic(), ninv, d*(degAy + 2));
+  nmod_poly_init2_preinv (subA2, getCharacteristic(), ninv, d*(degAy + 2));
+
+  nmod_poly_t buf;
+
+  int k, kk, j, bufRepLength;
+  for (CFIterator i= A; i.hasTerms(); i++)
+  {
+    convertFacCF2nmod_poly_t (buf, i.coeff());
+
+    k= i.exp()*d;
+    kk= (degAy - i.exp())*d;
+    bufRepLength= (int) nmod_poly_length (buf);
+    for (j= 0; j < bufRepLength; j++)
+    {
+      nmod_poly_set_coeff_ui (subA1, j + k,
+                              n_addmod (nmod_poly_get_coeff_ui (subA1, j+k),
+                                        nmod_poly_get_coeff_ui (buf, j),
+                                        getCharacteristic()
+                                       )
+                             );
+      nmod_poly_set_coeff_ui (subA2, j + kk,
+                              n_addmod (nmod_poly_get_coeff_ui (subA2, j + kk),
+                                        nmod_poly_get_coeff_ui (buf, j),
+                                        getCharacteristic()
+                                       )
+                             );
+    }
+    nmod_poly_clear (buf);
+  }
+  _nmod_poly_normalise (subA1);
+  _nmod_poly_normalise (subA2);
+}
+
+#if ( __FLINT_RELEASE >= 20400)
+void
+kronSubReciproFq (fq_nmod_poly_t subA1, fq_nmod_poly_t subA2,
+                  const CanonicalForm& A, int d, const fq_nmod_ctx_t fq_con)
+{
+  int degAy= degree (A);
+  fq_nmod_poly_init2 (subA1, d*(degAy + 2), fq_con);
+  fq_nmod_poly_init2 (subA2, d*(degAy + 2), fq_con);
+
+  _fq_nmod_poly_set_length (subA1, d*(degAy + 2), fq_con);
+  _fq_nmod_vec_zero (subA1->coeffs, d*(degAy + 2), fq_con);
+
+  _fq_nmod_poly_set_length (subA2, d*(degAy + 2), fq_con);
+  _fq_nmod_vec_zero (subA2->coeffs, d*(degAy + 2), fq_con);
+
+  fq_nmod_poly_t buf1;
+
+  nmod_poly_t buf2;
+
+  int k, kk;
+  for (CFIterator i= A; i.hasTerms(); i++)
+  {
+    if (i.coeff().inCoeffDomain())
+    {
+      convertFacCF2nmod_poly_t (buf2, i.coeff());
+      fq_nmod_poly_init2 (buf1, 1, fq_con);
+      fq_nmod_poly_set_coeff (buf1, 0, buf2, fq_con);
+      nmod_poly_clear (buf2);
+    }
+    else
+      convertFacCF2Fq_nmod_poly_t (buf1, i.coeff(), fq_con);
+
+    k= i.exp()*d;
+    kk= (degAy - i.exp())*d;
+    _fq_nmod_vec_add (subA1->coeffs+k, subA1->coeffs+k, buf1->coeffs,
+                      fq_nmod_poly_length(buf1, fq_con), fq_con);
+    _fq_nmod_vec_add (subA2->coeffs+kk, subA2->coeffs+kk, buf1->coeffs,
+                      fq_nmod_poly_length(buf1, fq_con), fq_con);
+
+    fq_nmod_poly_clear (buf1, fq_con);
+  }
+  _fq_nmod_poly_normalise (subA1, fq_con);
+  _fq_nmod_poly_normalise (subA2, fq_con);
+}
+#endif
+
+void
+kronSubReciproQ (fmpz_poly_t subA1, fmpz_poly_t subA2, const CanonicalForm& A,
+                 int d)
+{
+  int degAy= degree (A);
+  fmpz_poly_init2 (subA1, d*(degAy + 2));
+  fmpz_poly_init2 (subA2, d*(degAy + 2));
+
+  fmpz_poly_t buf;
+
+  int k, kk;
+  for (CFIterator i= A; i.hasTerms(); i++)
+  {
+    convertFacCF2Fmpz_poly_t (buf, i.coeff());
+
+    k= i.exp()*d;
+    kk= (degAy - i.exp())*d;
+    _fmpz_vec_add (subA1->coeffs+k, subA1->coeffs + k, buf->coeffs, buf->length);
+    _fmpz_vec_add (subA2->coeffs+kk, subA2->coeffs + kk, buf->coeffs, buf->length);
+    fmpz_poly_clear (buf);
+  }
+
+  _fmpz_poly_normalise (subA1);
+  _fmpz_poly_normalise (subA2);
+}
+
+CanonicalForm reverseSubstQ (const fmpz_poly_t F, int d)
+{
+  Variable y= Variable (2);
+  Variable x= Variable (1);
+
+  fmpz_poly_t buf;
+  CanonicalForm result= 0;
+  int i= 0;
+  int degf= fmpz_poly_degree(F);
+  int k= 0;
+  int degfSubK, repLength;
+  while (degf >= k)
+  {
+    degfSubK= degf - k;
+    if (degfSubK >= d)
+      repLength= d;
+    else
+      repLength= degfSubK + 1;
+
+    fmpz_poly_init2 (buf, repLength);
+    _fmpz_poly_set_length (buf, repLength);
+    _fmpz_vec_set (buf->coeffs, F->coeffs+k, repLength);
+    _fmpz_poly_normalise (buf);
+
+    result += convertFmpz_poly_t2FacCF (buf, x)*power (y, i);
+    i++;
+    k= d*i;
+    fmpz_poly_clear (buf);
+  }
+
+  return result;
+}
+
+/*CanonicalForm
+reverseSubstQa (const fmpq_poly_t F, int d1, int d2, const Variable& alpha,
+                const fmpq_poly_t mipo)
+{
+  Variable y= Variable (2);
+  Variable x= Variable (1);
+
+  fmpq_poly_t f;
+  fmpq_poly_init (f);
+  fmpq_poly_set (f, F);
+
+  fmpq_poly_t buf;
+  CanonicalForm result= 0, result2;
+  int i= 0;
+  int degf= fmpq_poly_degree(f);
+  int k= 0;
+  int degfSubK;
+  int repLength;
+  fmpq_t coeff;
+  while (degf >= k)
+  {
+    degfSubK= degf - k;
+    if (degfSubK >= d1)
+      repLength= d1;
+    else
+      repLength= degfSubK + 1;
+
+    fmpq_init (coeff);
+    int j= 0;
+    int l;
+    result2= 0;
+    while (j*d2 < repLength)
+    {
+      fmpq_poly_init2 (buf, d2);
+      for (l= 0; l < d2; l++)
+      {
+        fmpq_poly_get_coeff_fmpq (coeff, f, k + j*d2 + l);
+        fmpq_poly_set_coeff_fmpq (buf, l, coeff);
+      }
+      _fmpq_poly_normalise (buf);
+      fmpq_poly_rem (buf, buf, mipo);
+      result2 += convertFmpq_poly_t2FacCF (buf, alpha)*power (x, j);
+      j++;
+      fmpq_poly_clear (buf);
+    }
+    if (repLength - j*d2 != 0 && j*d2 - repLength < d2)
+    {
+      j--;
+      repLength -= j*d2;
+      fmpq_poly_init2 (buf, repLength);
+      j++;
+      for (l= 0; l < repLength; l++)
+      {
+        fmpq_poly_get_coeff_fmpq (coeff, f, k + j*d2 + l);
+        fmpq_poly_set_coeff_fmpq (buf, l, coeff);
+      }
+      _fmpq_poly_normalise (buf);
+      fmpq_poly_rem (buf, buf, mipo);
+      result2 += convertFmpq_poly_t2FacCF (buf, alpha)*power (x, j);
+      fmpq_poly_clear (buf);
+    }
+    fmpq_clear (coeff);
+
+    result += result2*power (y, i);
+    i++;
+    k= d1*i;
+  }
+
+  fmpq_poly_clear (f);
+  return result;
+}*/
+
+CanonicalForm
+reverseSubstQa (const fmpz_poly_t F, int d1, int d2, const Variable& alpha,
+                const fmpq_poly_t mipo)
+{
+  Variable y= Variable (2);
+  Variable x= Variable (1);
+
+  fmpq_poly_t buf;
+  CanonicalForm result= 0, result2;
+  int i= 0;
+  int degf= fmpz_poly_degree(F);
+  int k= 0;
+  int degfSubK;
+  int repLength;
+  while (degf >= k)
+  {
+    degfSubK= degf - k;
+    if (degfSubK >= d1)
+      repLength= d1;
+    else
+      repLength= degfSubK + 1;
+
+    int j= 0;
+    result2= 0;
+    while (j*d2 < repLength)
+    {
+      fmpq_poly_init2 (buf, d2);
+      _fmpq_poly_set_length (buf, d2);
+      _fmpz_vec_set (buf->coeffs, F->coeffs + k + j*d2, d2);
+      _fmpq_poly_normalise (buf);
+      fmpq_poly_rem (buf, buf, mipo);
+      result2 += convertFmpq_poly_t2FacCF (buf, alpha)*power (x, j);
+      j++;
+      fmpq_poly_clear (buf);
+    }
+    if (repLength - j*d2 != 0 && j*d2 - repLength < d2)
+    {
+      j--;
+      repLength -= j*d2;
+      fmpq_poly_init2 (buf, repLength);
+      _fmpq_poly_set_length (buf, repLength);
+      j++;
+      _fmpz_vec_set (buf->coeffs, F->coeffs + k + j*d2, repLength);
+      _fmpq_poly_normalise (buf);
+      fmpq_poly_rem (buf, buf, mipo);
+      result2 += convertFmpq_poly_t2FacCF (buf, alpha)*power (x, j);
+      fmpq_poly_clear (buf);
+    }
+
+    result += result2*power (y, i);
+    i++;
+    k= d1*i;
+  }
+
+  return result;
+}
+
+CanonicalForm
+reverseSubstReciproFp (const nmod_poly_t F, const nmod_poly_t G, int d, int k)
+{
+  Variable y= Variable (2);
+  Variable x= Variable (1);
+
+  nmod_poly_t f, g;
+  mp_limb_t ninv= n_preinvert_limb (getCharacteristic());
+  nmod_poly_init_preinv (f, getCharacteristic(), ninv);
+  nmod_poly_init_preinv (g, getCharacteristic(), ninv);
+  nmod_poly_set (f, F);
+  nmod_poly_set (g, G);
+  int degf= nmod_poly_degree(f);
+  int degg= nmod_poly_degree(g);
+
+
+  nmod_poly_t buf1,buf2, buf3;
+
+  if (nmod_poly_length (f) < (long) d*(k+1)) //zero padding
+    nmod_poly_fit_length (f,(long)d*(k+1));
+
+  CanonicalForm result= 0;
+  int i= 0;
+  int lf= 0;
+  int lg= d*k;
+  int degfSubLf= degf;
+  int deggSubLg= degg-lg;
+  int repLengthBuf2, repLengthBuf1, ind, tmp;
+  while (degf >= lf || lg >= 0)
+  {
+    if (degfSubLf >= d)
+      repLengthBuf1= d;
+    else if (degfSubLf < 0)
+      repLengthBuf1= 0;
+    else
+      repLengthBuf1= degfSubLf + 1;
+    nmod_poly_init2_preinv (buf1, getCharacteristic(), ninv, repLengthBuf1);
+
+    for (ind= 0; ind < repLengthBuf1; ind++)
+      nmod_poly_set_coeff_ui (buf1, ind, nmod_poly_get_coeff_ui (f, ind+lf));
+    _nmod_poly_normalise (buf1);
+
+    repLengthBuf1= nmod_poly_length (buf1);
+
+    if (deggSubLg >= d - 1)
+      repLengthBuf2= d - 1;
+    else if (deggSubLg < 0)
+      repLengthBuf2= 0;
+    else
+      repLengthBuf2= deggSubLg + 1;
+
+    nmod_poly_init2_preinv (buf2, getCharacteristic(), ninv, repLengthBuf2);
+    for (ind= 0; ind < repLengthBuf2; ind++)
+      nmod_poly_set_coeff_ui (buf2, ind, nmod_poly_get_coeff_ui (g, ind + lg));
+
+    _nmod_poly_normalise (buf2);
+    repLengthBuf2= nmod_poly_length (buf2);
+
+    nmod_poly_init2_preinv (buf3, getCharacteristic(), ninv, repLengthBuf2 + d);
+    for (ind= 0; ind < repLengthBuf1; ind++)
+      nmod_poly_set_coeff_ui (buf3, ind, nmod_poly_get_coeff_ui (buf1, ind));
+    for (ind= repLengthBuf1; ind < d; ind++)
+      nmod_poly_set_coeff_ui (buf3, ind, 0);
+    for (ind= 0; ind < repLengthBuf2; ind++)
+      nmod_poly_set_coeff_ui (buf3, ind+d, nmod_poly_get_coeff_ui (buf2, ind));
+    _nmod_poly_normalise (buf3);
+
+    result += convertnmod_poly_t2FacCF (buf3, x)*power (y, i);
+    i++;
+
+
+    lf= i*d;
+    degfSubLf= degf - lf;
+
+    lg= d*(k-i);
+    deggSubLg= degg - lg;
+
+    if (lg >= 0 && deggSubLg > 0)
+    {
+      if (repLengthBuf2 > degfSubLf + 1)
+        degfSubLf= repLengthBuf2 - 1;
+      tmp= tmin (repLengthBuf1, deggSubLg + 1);
+      for (ind= 0; ind < tmp; ind++)
+        nmod_poly_set_coeff_ui (g, ind + lg,
+                                n_submod (nmod_poly_get_coeff_ui (g, ind + lg),
+                                          nmod_poly_get_coeff_ui (buf1, ind),
+                                          getCharacteristic()
+                                         )
+                               );
+    }
+    if (lg < 0)
+    {
+      nmod_poly_clear (buf1);
+      nmod_poly_clear (buf2);
+      nmod_poly_clear (buf3);
+      break;
+    }
+    if (degfSubLf >= 0)
+    {
+      for (ind= 0; ind < repLengthBuf2; ind++)
+        nmod_poly_set_coeff_ui (f, ind + lf,
+                                n_submod (nmod_poly_get_coeff_ui (f, ind + lf),
+                                          nmod_poly_get_coeff_ui (buf2, ind),
+                                          getCharacteristic()
+                                         )
+                               );
+    }
+    nmod_poly_clear (buf1);
+    nmod_poly_clear (buf2);
+    nmod_poly_clear (buf3);
+  }
+
+  nmod_poly_clear (f);
+  nmod_poly_clear (g);
+
+  return result;
+}
+
+#if ( __FLINT_RELEASE >= 20400)
+CanonicalForm
+reverseSubstReciproFq (const fq_nmod_poly_t F, const fq_nmod_poly_t G, int d,
+                       int k, const Variable& alpha, const fq_nmod_ctx_t fq_con)
+{
+  Variable y= Variable (2);
+  Variable x= Variable (1);
+
+  fq_nmod_poly_t f, g;
+  int degf= fq_nmod_poly_degree(F, fq_con);
+  int degg= fq_nmod_poly_degree(G, fq_con);
+
+  fq_nmod_poly_t buf1,buf2, buf3;
+
+  fq_nmod_poly_init (f, fq_con);
+  fq_nmod_poly_init (g, fq_con);
+  fq_nmod_poly_set (f, F, fq_con);
+  fq_nmod_poly_set (g, G, fq_con);
+  if (fq_nmod_poly_length (f, fq_con) < (long) d*(k + 1)) //zero padding
+    fq_nmod_poly_fit_length (f, (long) d*(k + 1), fq_con);
+
+  CanonicalForm result= 0;
+  int i= 0;
+  int lf= 0;
+  int lg= d*k;
+  int degfSubLf= degf;
+  int deggSubLg= degg-lg;
+  int repLengthBuf2, repLengthBuf1, tmp;
+  while (degf >= lf || lg >= 0)
+  {
+    if (degfSubLf >= d)
+      repLengthBuf1= d;
+    else if (degfSubLf < 0)
+      repLengthBuf1= 0;
+    else
+      repLengthBuf1= degfSubLf + 1;
+    fq_nmod_poly_init2 (buf1, repLengthBuf1, fq_con);
+    _fq_nmod_poly_set_length (buf1, repLengthBuf1, fq_con);
+
+    _fq_nmod_vec_set (buf1->coeffs, f->coeffs + lf, repLengthBuf1, fq_con);
+    _fq_nmod_poly_normalise (buf1, fq_con);
+
+    repLengthBuf1= fq_nmod_poly_length (buf1, fq_con);
+
+    if (deggSubLg >= d - 1)
+      repLengthBuf2= d - 1;
+    else if (deggSubLg < 0)
+      repLengthBuf2= 0;
+    else
+      repLengthBuf2= deggSubLg + 1;
+
+    fq_nmod_poly_init2 (buf2, repLengthBuf2, fq_con);
+    _fq_nmod_poly_set_length (buf2, repLengthBuf2, fq_con);
+    _fq_nmod_vec_set (buf2->coeffs, g->coeffs + lg, repLengthBuf2, fq_con);
+
+    _fq_nmod_poly_normalise (buf2, fq_con);
+    repLengthBuf2= fq_nmod_poly_length (buf2, fq_con);
+
+    fq_nmod_poly_init2 (buf3, repLengthBuf2 + d, fq_con);
+    _fq_nmod_poly_set_length (buf3, repLengthBuf2 + d, fq_con);
+    _fq_nmod_vec_set (buf3->coeffs, buf1->coeffs, repLengthBuf1, fq_con);
+    _fq_nmod_vec_set (buf3->coeffs + d, buf2->coeffs, repLengthBuf2, fq_con);
+
+    _fq_nmod_poly_normalise (buf3, fq_con);
+
+    result += convertFq_nmod_poly_t2FacCF (buf3, x, alpha, fq_con)*power (y, i);
+    i++;
+
+
+    lf= i*d;
+    degfSubLf= degf - lf;
+
+    lg= d*(k - i);
+    deggSubLg= degg - lg;
+
+    if (lg >= 0 && deggSubLg > 0)
+    {
+      if (repLengthBuf2 > degfSubLf + 1)
+        degfSubLf= repLengthBuf2 - 1;
+      tmp= tmin (repLengthBuf1, deggSubLg + 1);
+      _fq_nmod_vec_sub (g->coeffs + lg, g->coeffs + lg, buf1-> coeffs,
+                        tmp, fq_con);
+    }
+    if (lg < 0)
+    {
+      fq_nmod_poly_clear (buf1, fq_con);
+      fq_nmod_poly_clear (buf2, fq_con);
+      fq_nmod_poly_clear (buf3, fq_con);
+      break;
+    }
+    if (degfSubLf >= 0)
+      _fq_nmod_vec_sub (f->coeffs + lf, f->coeffs + lf, buf2->coeffs,
+                        repLengthBuf2, fq_con);
+    fq_nmod_poly_clear (buf1, fq_con);
+    fq_nmod_poly_clear (buf2, fq_con);
+    fq_nmod_poly_clear (buf3, fq_con);
+  }
+
+  fq_nmod_poly_clear (f, fq_con);
+  fq_nmod_poly_clear (g, fq_con);
+
+  return result;
+}
+#endif
+
+CanonicalForm
+reverseSubstReciproQ (const fmpz_poly_t F, const fmpz_poly_t G, int d, int k)
+{
+  Variable y= Variable (2);
+  Variable x= Variable (1);
+
+  fmpz_poly_t f, g;
+  fmpz_poly_init (f);
+  fmpz_poly_init (g);
+  fmpz_poly_set (f, F);
+  fmpz_poly_set (g, G);
+  int degf= fmpz_poly_degree(f);
+  int degg= fmpz_poly_degree(g);
+
+  fmpz_poly_t buf1,buf2, buf3;
+
+  if (fmpz_poly_length (f) < (long) d*(k+1)) //zero padding
+    fmpz_poly_fit_length (f,(long)d*(k+1));
+
+  CanonicalForm result= 0;
+  int i= 0;
+  int lf= 0;
+  int lg= d*k;
+  int degfSubLf= degf;
+  int deggSubLg= degg-lg;
+  int repLengthBuf2, repLengthBuf1, ind, tmp;
+  fmpz_t tmp1, tmp2;
+  while (degf >= lf || lg >= 0)
+  {
+    if (degfSubLf >= d)
+      repLengthBuf1= d;
+    else if (degfSubLf < 0)
+      repLengthBuf1= 0;
+    else
+      repLengthBuf1= degfSubLf + 1;
+
+    fmpz_poly_init2 (buf1, repLengthBuf1);
+
+    for (ind= 0; ind < repLengthBuf1; ind++)
+    {
+      fmpz_poly_get_coeff_fmpz (tmp1, f, ind + lf);
+      fmpz_poly_set_coeff_fmpz (buf1, ind, tmp1);
+    }
+    _fmpz_poly_normalise (buf1);
+
+    repLengthBuf1= fmpz_poly_length (buf1);
+
+    if (deggSubLg >= d - 1)
+      repLengthBuf2= d - 1;
+    else if (deggSubLg < 0)
+      repLengthBuf2= 0;
+    else
+      repLengthBuf2= deggSubLg + 1;
+
+    fmpz_poly_init2 (buf2, repLengthBuf2);
+
+    for (ind= 0; ind < repLengthBuf2; ind++)
+    {
+      fmpz_poly_get_coeff_fmpz (tmp1, g, ind + lg);
+      fmpz_poly_set_coeff_fmpz (buf2, ind, tmp1);
+    }
+
+    _fmpz_poly_normalise (buf2);
+    repLengthBuf2= fmpz_poly_length (buf2);
+
+    fmpz_poly_init2 (buf3, repLengthBuf2 + d);
+    for (ind= 0; ind < repLengthBuf1; ind++)
+    {
+      fmpz_poly_get_coeff_fmpz (tmp1, buf1, ind);
+      fmpz_poly_set_coeff_fmpz (buf3, ind, tmp1);
+    }
+    for (ind= repLengthBuf1; ind < d; ind++)
+      fmpz_poly_set_coeff_ui (buf3, ind, 0);
+    for (ind= 0; ind < repLengthBuf2; ind++)
+    {
+      fmpz_poly_get_coeff_fmpz (tmp1, buf2, ind);
+      fmpz_poly_set_coeff_fmpz (buf3, ind + d, tmp1);
+    }
+    _fmpz_poly_normalise (buf3);
+
+    result += convertFmpz_poly_t2FacCF (buf3, x)*power (y, i);
+    i++;
+
+
+    lf= i*d;
+    degfSubLf= degf - lf;
+
+    lg= d*(k-i);
+    deggSubLg= degg - lg;
+
+    if (lg >= 0 && deggSubLg > 0)
+    {
+      if (repLengthBuf2 > degfSubLf + 1)
+        degfSubLf= repLengthBuf2 - 1;
+      tmp= tmin (repLengthBuf1, deggSubLg + 1);
+      for (ind= 0; ind < tmp; ind++)
+      {
+        fmpz_poly_get_coeff_fmpz (tmp1, g, ind + lg);
+        fmpz_poly_get_coeff_fmpz (tmp2, buf1, ind);
+        fmpz_sub (tmp1, tmp1, tmp2);
+        fmpz_poly_set_coeff_fmpz (g, ind + lg, tmp1);
+      }
+    }
+    if (lg < 0)
+    {
+      fmpz_poly_clear (buf1);
+      fmpz_poly_clear (buf2);
+      fmpz_poly_clear (buf3);
+      break;
+    }
+    if (degfSubLf >= 0)
+    {
+      for (ind= 0; ind < repLengthBuf2; ind++)
+      {
+        fmpz_poly_get_coeff_fmpz (tmp1, f, ind + lf);
+        fmpz_poly_get_coeff_fmpz (tmp2, buf2, ind);
+        fmpz_sub (tmp1, tmp1, tmp2);
+        fmpz_poly_set_coeff_fmpz (f, ind + lf, tmp1);
+      }
+    }
+    fmpz_poly_clear (buf1);
+    fmpz_poly_clear (buf2);
+    fmpz_poly_clear (buf3);
+  }
+
+  fmpz_poly_clear (f);
+  fmpz_poly_clear (g);
+  fmpz_clear (tmp1);
+  fmpz_clear (tmp2);
+
+  return result;
+}
+
+#if ( __FLINT_RELEASE >= 20400)
+CanonicalForm
+reverseSubstFq (const fq_nmod_poly_t F, int d, const Variable& alpha,
+                const fq_nmod_ctx_t fq_con)
+{
+  Variable y= Variable (2);
+  Variable x= Variable (1);
+
+  fq_nmod_poly_t buf;
+  CanonicalForm result= 0;
+  int i= 0;
+  int degf= fq_nmod_poly_degree(F, fq_con);
+  int k= 0;
+  int degfSubK, repLength;
+  while (degf >= k)
+  {
+    degfSubK= degf - k;
+    if (degfSubK >= d)
+      repLength= d;
+    else
+      repLength= degfSubK + 1;
+
+    fq_nmod_poly_init2 (buf, repLength, fq_con);
+    _fq_nmod_poly_set_length (buf, repLength, fq_con);
+    _fq_nmod_vec_set (buf->coeffs, F->coeffs+k, repLength, fq_con);
+    _fq_nmod_poly_normalise (buf, fq_con);
+
+    result += convertFq_nmod_poly_t2FacCF (buf, x, alpha, fq_con)*power (y, i);
+    i++;
+    k= d*i;
+    fq_nmod_poly_clear (buf, fq_con);
+  }
+
+  return result;
+}
+#endif
+
+CanonicalForm reverseSubstFp (const nmod_poly_t F, int d)
+{
+  Variable y= Variable (2);
+  Variable x= Variable (1);
+
+  mp_limb_t ninv= n_preinvert_limb (getCharacteristic());
+
+  nmod_poly_t buf;
+  CanonicalForm result= 0;
+  int i= 0;
+  int degf= nmod_poly_degree(F);
+  int k= 0;
+  int degfSubK, repLength, j;
+  while (degf >= k)
+  {
+    degfSubK= degf - k;
+    if (degfSubK >= d)
+      repLength= d;
+    else
+      repLength= degfSubK + 1;
+
+    nmod_poly_init2_preinv (buf, getCharacteristic(), ninv, repLength);
+    for (j= 0; j < repLength; j++)
+      nmod_poly_set_coeff_ui (buf, j, nmod_poly_get_coeff_ui (F, j + k));
+    _nmod_poly_normalise (buf);
+
+    result += convertnmod_poly_t2FacCF (buf, x)*power (y, i);
+    i++;
+    k= d*i;
+    nmod_poly_clear (buf);
+  }
+
+  return result;
+}
+
+CanonicalForm
+mulMod2FLINTFpReci (const CanonicalForm& F, const CanonicalForm& G, const
+                    CanonicalForm& M)
+{
+  int d1= degree (F, 1) + degree (G, 1) + 1;
+  d1 /= 2;
+  d1 += 1;
+
+  nmod_poly_t F1, F2;
+  kronSubReciproFp (F1, F2, F, d1);
+
+  nmod_poly_t G1, G2;
+  kronSubReciproFp (G1, G2, G, d1);
+
+  int k= d1*degree (M);
+  nmod_poly_mullow (F1, F1, G1, (long) k);
+
+  int degtailF= degree (tailcoeff (F), 1);;
+  int degtailG= degree (tailcoeff (G), 1);
+  int taildegF= taildegree (F);
+  int taildegG= taildegree (G);
+
+  int b= nmod_poly_degree (F2) + nmod_poly_degree (G2) - k - degtailF - degtailG
+         + d1*(2+taildegF + taildegG);
+  nmod_poly_mulhigh (F2, F2, G2, b);
+  nmod_poly_shift_right (F2, F2, b);
+  int d2= tmax (nmod_poly_degree (F2)/d1, nmod_poly_degree (F1)/d1);
+
+
+  CanonicalForm result= reverseSubstReciproFp (F1, F2, d1, d2);
+
+  nmod_poly_clear (F1);
+  nmod_poly_clear (F2);
+  nmod_poly_clear (G1);
+  nmod_poly_clear (G2);
+  return result;
+}
+
+CanonicalForm
+mulMod2FLINTFp (const CanonicalForm& F, const CanonicalForm& G, const
+                CanonicalForm& M)
+{
+  CanonicalForm A= F;
+  CanonicalForm B= G;
+
+  int degAx= degree (A, 1);
+  int degAy= degree (A, 2);
+  int degBx= degree (B, 1);
+  int degBy= degree (B, 2);
+  int d1= degAx + 1 + degBx;
+  int d2= tmax (degAy, degBy);
+
+  if (d1 > 128 && d2 > 160 && (degAy == degBy) && (2*degAy > degree (M)))
+    return mulMod2FLINTFpReci (A, B, M);
+
+  nmod_poly_t FLINTA, FLINTB;
+  kronSubFp (FLINTA, A, d1);
+  kronSubFp (FLINTB, B, d1);
+
+  int k= d1*degree (M);
+  nmod_poly_mullow (FLINTA, FLINTA, FLINTB, (long) k);
+
+  A= reverseSubstFp (FLINTA, d1);
+
+  nmod_poly_clear (FLINTA);
+  nmod_poly_clear (FLINTB);
+  return A;
+}
+
+#if ( __FLINT_RELEASE >= 20400)
+CanonicalForm
+mulMod2FLINTFqReci (const CanonicalForm& F, const CanonicalForm& G, const
+                    CanonicalForm& M, const Variable& alpha,
+                    const fq_nmod_ctx_t fq_con)
+{
+  int d1= degree (F, 1) + degree (G, 1) + 1;
+  d1 /= 2;
+  d1 += 1;
+
+  fq_nmod_poly_t F1, F2;
+  kronSubReciproFq (F1, F2, F, d1, fq_con);
+
+  fq_nmod_poly_t G1, G2;
+  kronSubReciproFq (G1, G2, G, d1, fq_con);
+
+  int k= d1*degree (M);
+  fq_nmod_poly_mullow (F1, F1, G1, (long) k, fq_con);
+
+  int degtailF= degree (tailcoeff (F), 1);
+  int degtailG= degree (tailcoeff (G), 1);
+  int taildegF= taildegree (F);
+  int taildegG= taildegree (G);
+
+  int b= k + degtailF + degtailG - d1*(2+taildegF + taildegG);
+
+  fq_nmod_poly_reverse (F2, F2, fq_nmod_poly_length (F2, fq_con), fq_con);
+  fq_nmod_poly_reverse (G2, G2, fq_nmod_poly_length (G2, fq_con), fq_con);
+  fq_nmod_poly_mullow (F2, F2, G2, b+1, fq_con);
+  fq_nmod_poly_reverse (F2, F2, b+1, fq_con);
+
+  int d2= tmax (fq_nmod_poly_degree (F2, fq_con)/d1,
+                fq_nmod_poly_degree (F1, fq_con)/d1);
+
+  CanonicalForm result= reverseSubstReciproFq (F1, F2, d1, d2, alpha, fq_con);
+
+  fq_nmod_poly_clear (F1, fq_con);
+  fq_nmod_poly_clear (F2, fq_con);
+  fq_nmod_poly_clear (G1, fq_con);
+  fq_nmod_poly_clear (G2, fq_con);
+  return result;
+}
+
+CanonicalForm
+mulMod2FLINTFq (const CanonicalForm& F, const CanonicalForm& G, const
+                CanonicalForm& M, const Variable& alpha,
+                const fq_nmod_ctx_t fq_con)
+{
+  CanonicalForm A= F;
+  CanonicalForm B= G;
+
+  int degAx= degree (A, 1);
+  int degAy= degree (A, 2);
+  int degBx= degree (B, 1);
+  int degBy= degree (B, 2);
+  int d1= degAx + 1 + degBx;
+  int d2= tmax (degAy, degBy);
+
+  if (d1 > 128 && d2 > 160 && (degAy == degBy) && (2*degAy > degree (M)))
+    return mulMod2FLINTFqReci (A, B, M, alpha, fq_con);
+
+  fq_nmod_poly_t FLINTA, FLINTB;
+  kronSubFq (FLINTA, A, d1, fq_con);
+  kronSubFq (FLINTB, B, d1, fq_con);
+
+  int k= d1*degree (M);
+  fq_nmod_poly_mullow (FLINTA, FLINTA, FLINTB, (long) k, fq_con);
+
+  A= reverseSubstFq (FLINTA, d1, alpha, fq_con);
+
+  fq_nmod_poly_clear (FLINTA, fq_con);
+  fq_nmod_poly_clear (FLINTB, fq_con);
+  return A;
+}
+#endif
+
+CanonicalForm
+mulMod2FLINTQReci (const CanonicalForm& F, const CanonicalForm& G, const
+                    CanonicalForm& M)
+{
+  int d1= degree (F, 1) + degree (G, 1) + 1;
+  d1 /= 2;
+  d1 += 1;
+
+  fmpz_poly_t F1, F2;
+  kronSubReciproQ (F1, F2, F, d1);
+
+  fmpz_poly_t G1, G2;
+  kronSubReciproQ (G1, G2, G, d1);
+
+  int k= d1*degree (M);
+  fmpz_poly_mullow (F1, F1, G1, (long) k);
+
+  int degtailF= degree (tailcoeff (F), 1);;
+  int degtailG= degree (tailcoeff (G), 1);
+  int taildegF= taildegree (F);
+  int taildegG= taildegree (G);
+
+  int b= fmpz_poly_degree (F2) + fmpz_poly_degree (G2) - k - degtailF - degtailG
+         + d1*(2+taildegF + taildegG);
+  fmpz_poly_mulhigh_n (F2, F2, G2, b);
+  fmpz_poly_shift_right (F2, F2, b);
+  int d2= tmax (fmpz_poly_degree (F2)/d1, fmpz_poly_degree (F1)/d1);
+
+  CanonicalForm result= reverseSubstReciproQ (F1, F2, d1, d2);
+
+  fmpz_poly_clear (F1);
+  fmpz_poly_clear (F2);
+  fmpz_poly_clear (G1);
+  fmpz_poly_clear (G2);
+  return result;
+}
+
+CanonicalForm
+mulMod2FLINTQ (const CanonicalForm& F, const CanonicalForm& G, const
+                CanonicalForm& M)
+{
+  CanonicalForm A= F;
+  CanonicalForm B= G;
+
+  int degAx= degree (A, 1);
+  int degBx= degree (B, 1);
+  int d1= degAx + 1 + degBx;
+
+  CanonicalForm f= bCommonDen (F);
+  CanonicalForm g= bCommonDen (G);
+  A *= f;
+  B *= g;
+
+  fmpz_poly_t FLINTA, FLINTB;
+  kronSubQa (FLINTA, A, d1);
+  kronSubQa (FLINTB, B, d1);
+  int k= d1*degree (M);
+
+  fmpz_poly_mullow (FLINTA, FLINTA, FLINTB, (long) k);
+  A= reverseSubstQ (FLINTA, d1);
+  fmpz_poly_clear (FLINTA);
+  fmpz_poly_clear (FLINTB);
+  return A/(f*g);
+}
+
+/*CanonicalForm
+mulMod2FLINTQa (const CanonicalForm& F, const CanonicalForm& G,
+                const CanonicalForm& M)
+{
+  Variable a;
+  if (!hasFirstAlgVar (F,a) && !hasFirstAlgVar (G, a))
+    return mulMod2FLINTQ (F, G, M);
+  CanonicalForm A= F;
+
+  int degFx= degree (F, 1);
+  int degFa= degree (F, a);
+  int degGx= degree (G, 1);
+  int degGa= degree (G, a);
+
+  int d2= degFa+degGa+1;
+  int d1= degFx + 1 + degGx;
+  d1 *= d2;
+
+  fmpq_poly_t FLINTF, FLINTG;
+  kronSubQa (FLINTF, F, d1, d2);
+  kronSubQa (FLINTG, G, d1, d2);
+
+  fmpq_poly_mullow (FLINTF, FLINTF, FLINTG, d1*degree (M));
+
+  fmpq_poly_t mipo;
+  convertFacCF2Fmpq_poly_t (mipo, getMipo (a));
+  CanonicalForm result= reverseSubstQa (FLINTF, d1, d2, a, mipo);
+  fmpq_poly_clear (FLINTF);
+  fmpq_poly_clear (FLINTG);
+  return result;
+}*/
+
+CanonicalForm
+mulMod2FLINTQa (const CanonicalForm& F, const CanonicalForm& G,
+                const CanonicalForm& M)
+{
+  Variable a;
+  if (!hasFirstAlgVar (F,a) && !hasFirstAlgVar (G, a))
+    return mulMod2FLINTQ (F, G, M);
+  CanonicalForm A= F, B= G;
+
+  int degFx= degree (F, 1);
+  int degFa= degree (F, a);
+  int degGx= degree (G, 1);
+  int degGa= degree (G, a);
+
+  int d2= degFa+degGa+1;
+  int d1= degFx + 1 + degGx;
+  d1 *= d2;
+
+  CanonicalForm f= bCommonDen (F);
+  CanonicalForm g= bCommonDen (G);
+  A *= f;
+  B *= g;
+
+  fmpz_poly_t FLINTF, FLINTG;
+  kronSubQa (FLINTF, A, d1, d2);
+  kronSubQa (FLINTG, B, d1, d2);
+
+  fmpz_poly_mullow (FLINTF, FLINTF, FLINTG, d1*degree (M));
+
+  fmpq_poly_t mipo;
+  convertFacCF2Fmpq_poly_t (mipo, getMipo (a));
+  A= reverseSubstQa (FLINTF, d1, d2, a, mipo);
+  fmpz_poly_clear (FLINTF);
+  fmpz_poly_clear (FLINTG);
+  return A/(f*g);
+}
+
+#endif
+
+#ifndef HAVE_FLINT
+zz_pX kronSubFp (const CanonicalForm& A, int d)
+{
+  int degAy= degree (A);
+  zz_pX result;
+  result.rep.SetLength (d*(degAy + 1));
+
+  zz_p *resultp;
+  resultp= result.rep.elts();
+  zz_pX buf;
+  zz_p *bufp;
+  int j, k, bufRepLength;
+
+  for (CFIterator i= A; i.hasTerms(); i++)
+  {
+    if (i.coeff().inCoeffDomain())
+      buf= convertFacCF2NTLzzpX (i.coeff());
+    else
+      buf= convertFacCF2NTLzzpX (i.coeff());
+
+    k= i.exp()*d;
+    bufp= buf.rep.elts();
+    bufRepLength= (int) buf.rep.length();
+    for (j= 0; j < bufRepLength; j++)
+      resultp [j + k]= bufp [j];
+  }
+  result.normalize();
+
+  return result;
+}
+#endif
+
+#if (!(HAVE_FLINT &&  __FLINT_RELEASE >= 20400))
+zz_pEX kronSubFq (const CanonicalForm& A, int d, const Variable& alpha)
+{
+  int degAy= degree (A);
+  zz_pEX result;
+  result.rep.SetLength (d*(degAy + 1));
+
+  Variable v;
+  zz_pE *resultp;
+  resultp= result.rep.elts();
+  zz_pEX buf1;
+  zz_pE *buf1p;
+  zz_pX buf2;
+  zz_pX NTLMipo= convertFacCF2NTLzzpX (getMipo (alpha));
+  int j, k, buf1RepLength;
+
+  for (CFIterator i= A; i.hasTerms(); i++)
+  {
+    if (i.coeff().inCoeffDomain())
+    {
+      buf2= convertFacCF2NTLzzpX (i.coeff());
+      buf1= to_zz_pEX (to_zz_pE (buf2));
+    }
+    else
+      buf1= convertFacCF2NTLzz_pEX (i.coeff(), NTLMipo);
+
+    k= i.exp()*d;
+    buf1p= buf1.rep.elts();
+    buf1RepLength= (int) buf1.rep.length();
+    for (j= 0; j < buf1RepLength; j++)
+      resultp [j + k]= buf1p [j];
+  }
+  result.normalize();
+
+  return result;
+}
+
+void
+kronSubReciproFq (zz_pEX& subA1, zz_pEX& subA2,const CanonicalForm& A, int d,
+                  const Variable& alpha)
+{
+  int degAy= degree (A);
+  subA1.rep.SetLength ((long) d*(degAy + 2));
+  subA2.rep.SetLength ((long) d*(degAy + 2));
+
+  Variable v;
+  zz_pE *subA1p;
+  zz_pE *subA2p;
+  subA1p= subA1.rep.elts();
+  subA2p= subA2.rep.elts();
+  zz_pEX buf;
+  zz_pE *bufp;
+  zz_pX buf2;
+  zz_pX NTLMipo= convertFacCF2NTLzzpX (getMipo (alpha));
+  int j, k, kk, bufRepLength;
+
+  for (CFIterator i= A; i.hasTerms(); i++)
+  {
+    if (i.coeff().inCoeffDomain())
+    {
+      buf2= convertFacCF2NTLzzpX (i.coeff());
+      buf= to_zz_pEX (to_zz_pE (buf2));
+    }
+    else
+      buf= convertFacCF2NTLzz_pEX (i.coeff(), NTLMipo);
+
+    k= i.exp()*d;
+    kk= (degAy - i.exp())*d;
+    bufp= buf.rep.elts();
+    bufRepLength= (int) buf.rep.length();
+    for (j= 0; j < bufRepLength; j++)
+    {
+      subA1p [j + k] += bufp [j];
+      subA2p [j + kk] += bufp [j];
+    }
+  }
+  subA1.normalize();
+  subA2.normalize();
+}
+#endif
+
+#ifndef HAVE_FLINT
+void
+kronSubReciproFp (zz_pX& subA1, zz_pX& subA2, const CanonicalForm& A, int d)
+{
+  int degAy= degree (A);
+  subA1.rep.SetLength ((long) d*(degAy + 2));
+  subA2.rep.SetLength ((long) d*(degAy + 2));
+
+  zz_p *subA1p;
+  zz_p *subA2p;
+  subA1p= subA1.rep.elts();
+  subA2p= subA2.rep.elts();
+  zz_pX buf;
+  zz_p *bufp;
+  int j, k, kk, bufRepLength;
+
+  for (CFIterator i= A; i.hasTerms(); i++)
+  {
+    buf= convertFacCF2NTLzzpX (i.coeff());
+
+    k= i.exp()*d;
+    kk= (degAy - i.exp())*d;
+    bufp= buf.rep.elts();
+    bufRepLength= (int) buf.rep.length();
+    for (j= 0; j < bufRepLength; j++)
+    {
+      subA1p [j + k] += bufp [j];
+      subA2p [j + kk] += bufp [j];
+    }
+  }
+  subA1.normalize();
+  subA2.normalize();
+}
+#endif
+
+#if (!(HAVE_FLINT &&  __FLINT_RELEASE >= 20400))
+CanonicalForm
+reverseSubstReciproFq (const zz_pEX& F, const zz_pEX& G, int d, int k,
+                       const Variable& alpha)
+{
+  Variable y= Variable (2);
+  Variable x= Variable (1);
+
+  zz_pEX f= F;
+  zz_pEX g= G;
+  int degf= deg(f);
+  int degg= deg(g);
+
+  zz_pEX buf1;
+  zz_pEX buf2;
+  zz_pEX buf3;
+
+  zz_pE *buf1p;
+  zz_pE *buf2p;
+  zz_pE *buf3p;
+  if (f.rep.length() < (long) d*(k+1)) //zero padding
+    f.rep.SetLength ((long)d*(k+1));
+
+  zz_pE *gp= g.rep.elts();
+  zz_pE *fp= f.rep.elts();
+  CanonicalForm result= 0;
+  int i= 0;
+  int lf= 0;
+  int lg= d*k;
+  int degfSubLf= degf;
+  int deggSubLg= degg-lg;
+  int repLengthBuf2, repLengthBuf1, ind, tmp;
+  zz_pE zzpEZero= zz_pE();
+
+  while (degf >= lf || lg >= 0)
+  {
+    if (degfSubLf >= d)
+      repLengthBuf1= d;
+    else if (degfSubLf < 0)
+      repLengthBuf1= 0;
+    else
+      repLengthBuf1= degfSubLf + 1;
+    buf1.rep.SetLength((long) repLengthBuf1);
+
+    buf1p= buf1.rep.elts();
+    for (ind= 0; ind < repLengthBuf1; ind++)
+      buf1p [ind]= fp [ind + lf];
+    buf1.normalize();
+
+    repLengthBuf1= buf1.rep.length();
+
+    if (deggSubLg >= d - 1)
+      repLengthBuf2= d - 1;
+    else if (deggSubLg < 0)
+      repLengthBuf2= 0;
+    else
+      repLengthBuf2= deggSubLg + 1;
+
+    buf2.rep.SetLength ((long) repLengthBuf2);
+    buf2p= buf2.rep.elts();
+    for (ind= 0; ind < repLengthBuf2; ind++)
+      buf2p [ind]= gp [ind + lg];
+    buf2.normalize();
+
+    repLengthBuf2= buf2.rep.length();
+
+    buf3.rep.SetLength((long) repLengthBuf2 + d);
+    buf3p= buf3.rep.elts();
+    buf2p= buf2.rep.elts();
+    buf1p= buf1.rep.elts();
+    for (ind= 0; ind < repLengthBuf1; ind++)
+      buf3p [ind]= buf1p [ind];
+    for (ind= repLengthBuf1; ind < d; ind++)
+      buf3p [ind]= zzpEZero;
+    for (ind= 0; ind < repLengthBuf2; ind++)
+      buf3p [ind + d]= buf2p [ind];
+    buf3.normalize();
+
+    result += convertNTLzz_pEX2CF (buf3, x, alpha)*power (y, i);
+    i++;
+
+
+    lf= i*d;
+    degfSubLf= degf - lf;
+
+    lg= d*(k-i);
+    deggSubLg= degg - lg;
+
+    buf1p= buf1.rep.elts();
+
+    if (lg >= 0 && deggSubLg > 0)
+    {
+      if (repLengthBuf2 > degfSubLf + 1)
+        degfSubLf= repLengthBuf2 - 1;
+      tmp= tmin (repLengthBuf1, deggSubLg + 1);
+      for (ind= 0; ind < tmp; ind++)
+        gp [ind + lg] -= buf1p [ind];
+    }
+
+    if (lg < 0)
+      break;
+
+    buf2p= buf2.rep.elts();
+    if (degfSubLf >= 0)
+    {
+      for (ind= 0; ind < repLengthBuf2; ind++)
+        fp [ind + lf] -= buf2p [ind];
+    }
+  }
+
+  return result;
+}
+#endif
+
+#ifndef HAVE_FLINT
+CanonicalForm
+reverseSubstReciproFp (const zz_pX& F, const zz_pX& G, int d, int k)
+{
+  Variable y= Variable (2);
+  Variable x= Variable (1);
+
+  zz_pX f= F;
+  zz_pX g= G;
+  int degf= deg(f);
+  int degg= deg(g);
+
+  zz_pX buf1;
+  zz_pX buf2;
+  zz_pX buf3;
+
+  zz_p *buf1p;
+  zz_p *buf2p;
+  zz_p *buf3p;
+
+  if (f.rep.length() < (long) d*(k+1)) //zero padding
+    f.rep.SetLength ((long)d*(k+1));
+
+  zz_p *gp= g.rep.elts();
+  zz_p *fp= f.rep.elts();
+  CanonicalForm result= 0;
+  int i= 0;
+  int lf= 0;
+  int lg= d*k;
+  int degfSubLf= degf;
+  int deggSubLg= degg-lg;
+  int repLengthBuf2, repLengthBuf1, ind, tmp;
+  zz_p zzpZero= zz_p();
+  while (degf >= lf || lg >= 0)
+  {
+    if (degfSubLf >= d)
+      repLengthBuf1= d;
+    else if (degfSubLf < 0)
+      repLengthBuf1= 0;
+    else
+      repLengthBuf1= degfSubLf + 1;
+    buf1.rep.SetLength((long) repLengthBuf1);
+
+    buf1p= buf1.rep.elts();
+    for (ind= 0; ind < repLengthBuf1; ind++)
+      buf1p [ind]= fp [ind + lf];
+    buf1.normalize();
+
+    repLengthBuf1= buf1.rep.length();
+
+    if (deggSubLg >= d - 1)
+      repLengthBuf2= d - 1;
+    else if (deggSubLg < 0)
+      repLengthBuf2= 0;
+    else
+      repLengthBuf2= deggSubLg + 1;
+
+    buf2.rep.SetLength ((long) repLengthBuf2);
+    buf2p= buf2.rep.elts();
+    for (ind= 0; ind < repLengthBuf2; ind++)
+      buf2p [ind]= gp [ind + lg];
+
+    buf2.normalize();
+
+    repLengthBuf2= buf2.rep.length();
+
+
+    buf3.rep.SetLength((long) repLengthBuf2 + d);
+    buf3p= buf3.rep.elts();
+    buf2p= buf2.rep.elts();
+    buf1p= buf1.rep.elts();
+    for (ind= 0; ind < repLengthBuf1; ind++)
+      buf3p [ind]= buf1p [ind];
+    for (ind= repLengthBuf1; ind < d; ind++)
+      buf3p [ind]= zzpZero;
+    for (ind= 0; ind < repLengthBuf2; ind++)
+      buf3p [ind + d]= buf2p [ind];
+    buf3.normalize();
+
+    result += convertNTLzzpX2CF (buf3, x)*power (y, i);
+    i++;
+
+
+    lf= i*d;
+    degfSubLf= degf - lf;
+
+    lg= d*(k-i);
+    deggSubLg= degg - lg;
+
+    buf1p= buf1.rep.elts();
+
+    if (lg >= 0 && deggSubLg > 0)
+    {
+      if (repLengthBuf2 > degfSubLf + 1)
+        degfSubLf= repLengthBuf2 - 1;
+      tmp= tmin (repLengthBuf1, deggSubLg + 1);
+      for (ind= 0; ind < tmp; ind++)
+        gp [ind + lg] -= buf1p [ind];
+    }
+    if (lg < 0)
+      break;
+
+    buf2p= buf2.rep.elts();
+    if (degfSubLf >= 0)
+    {
+      for (ind= 0; ind < repLengthBuf2; ind++)
+        fp [ind + lf] -= buf2p [ind];
+    }
+  }
+
+  return result;
+}
+#endif
+
+#if (!(HAVE_FLINT &&  __FLINT_RELEASE >= 20400))
+CanonicalForm reverseSubstFq (const zz_pEX& F, int d, const Variable& alpha)
+{
+  Variable y= Variable (2);
+  Variable x= Variable (1);
+
+  zz_pEX f= F;
+  zz_pE *fp= f.rep.elts();
+
+  zz_pEX buf;
+  zz_pE *bufp;
+  CanonicalForm result= 0;
+  int i= 0;
+  int degf= deg(f);
+  int k= 0;
+  int degfSubK, repLength, j;
+  while (degf >= k)
+  {
+    degfSubK= degf - k;
+    if (degfSubK >= d)
+      repLength= d;
+    else
+      repLength= degfSubK + 1;
+
+    buf.rep.SetLength ((long) repLength);
+    bufp= buf.rep.elts();
+    for (j= 0; j < repLength; j++)
+      bufp [j]= fp [j + k];
+    buf.normalize();
+
+    result += convertNTLzz_pEX2CF (buf, x, alpha)*power (y, i);
+    i++;
+    k= d*i;
+  }
+
+  return result;
+}
+#endif
+
+#ifndef HAVE_FLINT
+CanonicalForm reverseSubstFp (const zz_pX& F, int d)
+{
+  Variable y= Variable (2);
+  Variable x= Variable (1);
+
+  zz_pX f= F;
+  zz_p *fp= f.rep.elts();
+
+  zz_pX buf;
+  zz_p *bufp;
+  CanonicalForm result= 0;
+  int i= 0;
+  int degf= deg(f);
+  int k= 0;
+  int degfSubK, repLength, j;
+  while (degf >= k)
+  {
+    degfSubK= degf - k;
+    if (degfSubK >= d)
+      repLength= d;
+    else
+      repLength= degfSubK + 1;
+
+    buf.rep.SetLength ((long) repLength);
+    bufp= buf.rep.elts();
+    for (j= 0; j < repLength; j++)
+      bufp [j]= fp [j + k];
+    buf.normalize();
+
+    result += convertNTLzzpX2CF (buf, x)*power (y, i);
+    i++;
+    k= d*i;
+  }
+
+  return result;
+}
+
+// assumes input to be reduced mod M and to be an element of Fp
+CanonicalForm
+mulMod2NTLFpReci (const CanonicalForm& F, const CanonicalForm& G, const
+                  CanonicalForm& M)
+{
+  int d1= degree (F, 1) + degree (G, 1) + 1;
+  d1 /= 2;
+  d1 += 1;
+
+  zz_pX F1, F2;
+  kronSubReciproFp (F1, F2, F, d1);
+  zz_pX G1, G2;
+  kronSubReciproFp (G1, G2, G, d1);
+
+  int k= d1*degree (M);
+  MulTrunc (F1, F1, G1, (long) k);
+
+  int degtailF= degree (tailcoeff (F), 1);
+  int degtailG= degree (tailcoeff (G), 1);
+  int taildegF= taildegree (F);
+  int taildegG= taildegree (G);
+  int b= k + degtailF + degtailG - d1*(2+taildegF+taildegG);
+
+  reverse (F2, F2);
+  reverse (G2, G2);
+  MulTrunc (F2, F2, G2, b + 1);
+  reverse (F2, F2, b);
+
+  int d2= tmax (deg (F2)/d1, deg (F1)/d1);
+  return reverseSubstReciproFp (F1, F2, d1, d2);
+}
+
+//Kronecker substitution
+CanonicalForm
+mulMod2NTLFp (const CanonicalForm& F, const CanonicalForm& G, const
+              CanonicalForm& M)
+{
+  CanonicalForm A= F;
+  CanonicalForm B= G;
+
+  int degAx= degree (A, 1);
+  int degAy= degree (A, 2);
+  int degBx= degree (B, 1);
+  int degBy= degree (B, 2);
+  int d1= degAx + 1 + degBx;
+  int d2= tmax (degAy, degBy);
+
+  if (d1 > 128 && d2 > 160 && (degAy == degBy) && (2*degAy > degree (M)))
+    return mulMod2NTLFpReci (A, B, M);
+
+  zz_pX NTLA= kronSubFp (A, d1);
+  zz_pX NTLB= kronSubFp (B, d1);
+
+  int k= d1*degree (M);
+  MulTrunc (NTLA, NTLA, NTLB, (long) k);
+
+  A= reverseSubstFp (NTLA, d1);
+
+  return A;
+}
+#endif
+
+#if (!(HAVE_FLINT &&  __FLINT_RELEASE >= 20400))
+// assumes input to be reduced mod M and to be an element of Fq not Fp
+CanonicalForm
+mulMod2NTLFqReci (const CanonicalForm& F, const CanonicalForm& G, const
+                  CanonicalForm& M, const Variable& alpha)
+{
+  int d1= degree (F, 1) + degree (G, 1) + 1;
+  d1 /= 2;
+  d1 += 1;
+
+  zz_pEX F1, F2;
+  kronSubReciproFq (F1, F2, F, d1, alpha);
+  zz_pEX G1, G2;
+  kronSubReciproFq (G1, G2, G, d1, alpha);
+
+  int k= d1*degree (M);
+  MulTrunc (F1, F1, G1, (long) k);
+
+  int degtailF= degree (tailcoeff (F), 1);
+  int degtailG= degree (tailcoeff (G), 1);
+  int taildegF= taildegree (F);
+  int taildegG= taildegree (G);
+  int b= k + degtailF + degtailG - d1*(2+taildegF+taildegG);
+
+  reverse (F2, F2);
+  reverse (G2, G2);
+  MulTrunc (F2, F2, G2, b + 1);
+  reverse (F2, F2, b);
+
+  int d2= tmax (deg (F2)/d1, deg (F1)/d1);
+  return reverseSubstReciproFq (F1, F2, d1, d2, alpha);
+}
+#endif
+
+#ifdef HAVE_FLINT
+CanonicalForm
+mulMod2FLINTFp (const CanonicalForm& F, const CanonicalForm& G, const
+                CanonicalForm& M);
+#endif
+
+CanonicalForm
+mulMod2NTLFq (const CanonicalForm& F, const CanonicalForm& G, const
+              CanonicalForm& M)
+{
+  Variable alpha;
+  CanonicalForm A= F;
+  CanonicalForm B= G;
+
+  if (hasFirstAlgVar (A, alpha) || hasFirstAlgVar (B, alpha))
+  {
+#if (HAVE_FLINT &&  __FLINT_RELEASE >= 20400)
+    nmod_poly_t FLINTmipo;
+    convertFacCF2nmod_poly_t (FLINTmipo, getMipo (alpha));
+
+    fq_nmod_ctx_t fq_con;
+    fq_nmod_ctx_init_modulus (fq_con, FLINTmipo, "Z");
+
+    A= mulMod2FLINTFq (A, B, M, alpha, fq_con);
+    nmod_poly_clear (FLINTmipo);
+    fq_nmod_ctx_clear (fq_con);
+#else
+    int degAx= degree (A, 1);
+    int degAy= degree (A, 2);
+    int degBx= degree (B, 1);
+    int degBy= degree (B, 2);
+    int d1= degAx + degBx + 1;
+    int d2= tmax (degAy, degBy);
+    if (fac_NTL_char != getCharacteristic())
+    {
+      fac_NTL_char= getCharacteristic();
+      zz_p::init (getCharacteristic());
+    }
+    zz_pX NTLMipo= convertFacCF2NTLzzpX (getMipo (alpha));
+    zz_pE::init (NTLMipo);
+
+    int degMipo= degree (getMipo (alpha));
+    if ((d1 > 128/degMipo) && (d2 > 160/degMipo) && (degAy == degBy) &&
+        (2*degAy > degree (M)))
+      return mulMod2NTLFqReci (A, B, M, alpha);
+
+    zz_pEX NTLA= kronSubFq (A, d1, alpha);
+    zz_pEX NTLB= kronSubFq (B, d1, alpha);
+
+    int k= d1*degree (M);
+
+    MulTrunc (NTLA, NTLA, NTLB, (long) k);
+
+    A= reverseSubstFq (NTLA, d1, alpha);
+#endif
+  }
+  else
+  {
+#ifdef HAVE_FLINT
+    A= mulMod2FLINTFp (A, B, M);
+#else
+    A= mulMod2NTLFp (A, B, M);
+#endif
+  }
+  return A;
+}
+
+CanonicalForm mulMod2 (const CanonicalForm& A, const CanonicalForm& B,
+                       const CanonicalForm& M)
+{
+  if (A.isZero() || B.isZero())
+    return 0;
+
+  ASSERT (M.isUnivariate(), "M must be univariate");
+
+  CanonicalForm F= mod (A, M);
+  CanonicalForm G= mod (B, M);
+  if (F.inCoeffDomain())
+    return G*F;
+  if (G.inCoeffDomain())
+    return F*G;
+
+  Variable y= M.mvar();
+  int degF= degree (F, y);
+  int degG= degree (G, y);
+
+  if ((degF < 1 && degG < 1) && (F.isUnivariate() && G.isUnivariate()) &&
+      (F.level() == G.level()))
+  {
+    CanonicalForm result= mulNTL (F, G);
+    return mod (result, M);
+  }
+  else if (degF <= 1 && degG <= 1)
+  {
+    CanonicalForm result= F*G;
+    return mod (result, M);
+  }
+
+  int sizeF= size (F);
+  int sizeG= size (G);
+
+  int fallBackToNaive= 50;
+  if (sizeF < fallBackToNaive || sizeG < fallBackToNaive)
+  {
+    if (sizeF < sizeG)
+      return mod (G*F, M);
+    else
+      return mod (F*G, M);
+  }
+
+#ifdef HAVE_FLINT
+  if (getCharacteristic() == 0)
+    return mulMod2FLINTQa (F, G, M);
+#endif
+
+  if (getCharacteristic() > 0 && CFFactory::gettype() != GaloisFieldDomain &&
+      (((degF-degG) < 50 && degF > degG) || ((degG-degF) < 50 && degF <= degG)))
+    return mulMod2NTLFq (F, G, M);
+
+  int m= (int) ceil (degree (M)/2.0);
+  if (degF >= m || degG >= m)
+  {
+    CanonicalForm MLo= power (y, m);
+    CanonicalForm MHi= power (y, degree (M) - m);
+    CanonicalForm F0= mod (F, MLo);
+    CanonicalForm F1= div (F, MLo);
+    CanonicalForm G0= mod (G, MLo);
+    CanonicalForm G1= div (G, MLo);
+    CanonicalForm F0G1= mulMod2 (F0, G1, MHi);
+    CanonicalForm F1G0= mulMod2 (F1, G0, MHi);
+    CanonicalForm F0G0= mulMod2 (F0, G0, M);
+    return F0G0 + MLo*(F0G1 + F1G0);
+  }
+  else
+  {
+    m= (int) ceil (tmax (degF, degG)/2.0);
+    CanonicalForm yToM= power (y, m);
+    CanonicalForm F0= mod (F, yToM);
+    CanonicalForm F1= div (F, yToM);
+    CanonicalForm G0= mod (G, yToM);
+    CanonicalForm G1= div (G, yToM);
+    CanonicalForm H00= mulMod2 (F0, G0, M);
+    CanonicalForm H11= mulMod2 (F1, G1, M);
+    CanonicalForm H01= mulMod2 (F0 + F1, G0 + G1, M);
+    return H11*yToM*yToM + (H01 - H11 - H00)*yToM + H00;
+  }
+  DEBOUTLN (cerr, "fatal end in mulMod2");
+}
+
+// end bivariate polys
+//**********************
+// multivariate polys
+
+CanonicalForm mod (const CanonicalForm& F, const CFList& M)
+{
+  CanonicalForm A= F;
+  for (CFListIterator i= M; i.hasItem(); i++)
+    A= mod (A, i.getItem());
+  return A;
+}
+
+CanonicalForm mulMod (const CanonicalForm& A, const CanonicalForm& B,
+                      const CFList& MOD)
+{
+  if (A.isZero() || B.isZero())
+    return 0;
+
+  if (MOD.length() == 1)
+    return mulMod2 (A, B, MOD.getLast());
+
+  CanonicalForm M= MOD.getLast();
+  CanonicalForm F= mod (A, M);
+  CanonicalForm G= mod (B, M);
+  if (F.inCoeffDomain())
+    return G*F;
+  if (G.inCoeffDomain())
+    return F*G;
+
+  int sizeF= size (F);
+  int sizeG= size (G);
+
+  if (sizeF / MOD.length() < 100 || sizeG / MOD.length() < 100)
+  {
+    if (sizeF < sizeG)
+      return mod (G*F, MOD);
+    else
+      return mod (F*G, MOD);
+  }
+
+  Variable y= M.mvar();
+  int degF= degree (F, y);
+  int degG= degree (G, y);
+
+  if ((degF <= 1 && F.level() <= M.level()) &&
+      (degG <= 1 && G.level() <= M.level()))
+  {
+    CFList buf= MOD;
+    buf.removeLast();
+    if (degF == 1 && degG == 1)
+    {
+      CanonicalForm F0= mod (F, y);
+      CanonicalForm F1= div (F, y);
+      CanonicalForm G0= mod (G, y);
+      CanonicalForm G1= div (G, y);
+      if (degree (M) > 2)
+      {
+        CanonicalForm H00= mulMod (F0, G0, buf);
+        CanonicalForm H11= mulMod (F1, G1, buf);
+        CanonicalForm H01= mulMod (F0 + F1, G0 + G1, buf);
+        return H11*y*y + (H01 - H00 - H11)*y + H00;
+      }
+      else //here degree (M) == 2
+      {
+        buf.append (y);
+        CanonicalForm F0G1= mulMod (F0, G1, buf);
+        CanonicalForm F1G0= mulMod (F1, G0, buf);
+        CanonicalForm F0G0= mulMod (F0, G0, MOD);
+        CanonicalForm result= F0G0 + y*(F0G1 + F1G0);
+        return result;
+      }
+    }
+    else if (degF == 1 && degG == 0)
+      return mulMod (div (F, y), G, buf)*y + mulMod (mod (F, y), G, buf);
+    else if (degF == 0 && degG == 1)
+      return mulMod (div (G, y), F, buf)*y + mulMod (mod (G, y), F, buf);
+    else
+      return mulMod (F, G, buf);
+  }
+  int m= (int) ceil (degree (M)/2.0);
+  if (degF >= m || degG >= m)
+  {
+    CanonicalForm MLo= power (y, m);
+    CanonicalForm MHi= power (y, degree (M) - m);
+    CanonicalForm F0= mod (F, MLo);
+    CanonicalForm F1= div (F, MLo);
+    CanonicalForm G0= mod (G, MLo);
+    CanonicalForm G1= div (G, MLo);
+    CFList buf= MOD;
+    buf.removeLast();
+    buf.append (MHi);
+    CanonicalForm F0G1= mulMod (F0, G1, buf);
+    CanonicalForm F1G0= mulMod (F1, G0, buf);
+    CanonicalForm F0G0= mulMod (F0, G0, MOD);
+    return F0G0 + MLo*(F0G1 + F1G0);
+  }
+  else
+  {
+    m= (int) ceil (tmin (degF, degG)/2.0);
+    CanonicalForm yToM= power (y, m);
+    CanonicalForm F0= mod (F, yToM);
+    CanonicalForm F1= div (F, yToM);
+    CanonicalForm G0= mod (G, yToM);
+    CanonicalForm G1= div (G, yToM);
+    CanonicalForm H00= mulMod (F0, G0, MOD);
+    CanonicalForm H11= mulMod (F1, G1, MOD);
+    CanonicalForm H01= mulMod (F0 + F1, G0 + G1, MOD);
+    return H11*yToM*yToM + (H01 - H11 - H00)*yToM + H00;
+  }
+  DEBOUTLN (cerr, "fatal end in mulMod");
+}
+
+CanonicalForm prodMod (const CFList& L, const CanonicalForm& M)
+{
+  if (L.isEmpty())
+    return 1;
+  int l= L.length();
+  if (l == 1)
+    return mod (L.getFirst(), M);
+  else if (l == 2) {
+    CanonicalForm result= mulMod2 (L.getFirst(), L.getLast(), M);
+    return result;
+  }
+  else
+  {
+    l /= 2;
+    CFList tmp1, tmp2;
+    CFListIterator i= L;
+    CanonicalForm buf1, buf2;
+    for (int j= 1; j <= l; j++, i++)
+      tmp1.append (i.getItem());
+    tmp2= Difference (L, tmp1);
+    buf1= prodMod (tmp1, M);
+    buf2= prodMod (tmp2, M);
+    CanonicalForm result= mulMod2 (buf1, buf2, M);
+    return result;
+  }
+}
+
+CanonicalForm prodMod (const CFList& L, const CFList& M)
+{
+  if (L.isEmpty())
+    return 1;
+  else if (L.length() == 1)
+    return L.getFirst();
+  else if (L.length() == 2)
+    return mulMod (L.getFirst(), L.getLast(), M);
+  else
+  {
+    int l= L.length()/2;
+    CFListIterator i= L;
+    CFList tmp1, tmp2;
+    CanonicalForm buf1, buf2;
+    for (int j= 1; j <= l; j++, i++)
+      tmp1.append (i.getItem());
+    tmp2= Difference (L, tmp1);
+    buf1= prodMod (tmp1, M);
+    buf2= prodMod (tmp2, M);
+    return mulMod (buf1, buf2, M);
+  }
+}
+
+// end multivariate polys
+//***************************
+// division
+
+CanonicalForm reverse (const CanonicalForm& F, int d)
+{
+  if (d == 0)
+    return F;
+  CanonicalForm A= F;
+  Variable y= Variable (2);
+  Variable x= Variable (1);
+  if (degree (A, x) > 0)
+  {
+    A= swapvar (A, x, y);
+    CanonicalForm result= 0;
+    CFIterator i= A;
+    while (d - i.exp() < 0)
+      i++;
+
+    for (; i.hasTerms() && (d - i.exp() >= 0); i++)
+      result += swapvar (i.coeff(),x,y)*power (x, d - i.exp());
+    return result;
+  }
+  else
+    return A*power (x, d);
+}
+
+CanonicalForm
+newtonInverse (const CanonicalForm& F, const int n, const CanonicalForm& M)
+{
+  int l= ilog2(n);
+
+  CanonicalForm g= mod (F, M)[0] [0];
+
+  ASSERT (!g.isZero(), "expected a unit");
+
+  Variable alpha;
+
+  if (!g.isOne())
+    g = 1/g;
+  Variable x= Variable (1);
+  CanonicalForm result;
+  int exp= 0;
+  if (n & 1)
+  {
+    result= g;
+    exp= 1;
+  }
+  CanonicalForm h;
+
+  for (int i= 1; i <= l; i++)
+  {
+    h= mulMod2 (g, mod (F, power (x, (1 << i))), M);
+    h= mod (h, power (x, (1 << i)) - 1);
+    h= div (h, power (x, (1 << (i - 1))));
+    h= mod (h, M);
+    g -= power (x, (1 << (i - 1)))*
+         mod (mulMod2 (g, h, M), power (x, (1 << (i - 1))));
+
+    if (n & (1 << i))
+    {
+      if (exp)
+      {
+        h= mulMod2 (result, mod (F, power (x, exp + (1 << i))), M);
+        h= mod (h, power (x, exp + (1 << i)) - 1);
+        h= div (h, power (x, exp));
+        h= mod (h, M);
+        result -= power(x, exp)*mod (mulMod2 (g, h, M),
+                                       power (x, (1 << i)));
+        exp += (1 << i);
+      }
+      else
+      {
+        exp= (1 << i);
+        result= g;
+      }
+    }
+  }
+
+  return result;
+}
+
+CanonicalForm
+newtonDiv (const CanonicalForm& F, const CanonicalForm& G, const CanonicalForm&
+           M)
+{
+  ASSERT (getCharacteristic() > 0, "positive characteristic expected");
+
+  CanonicalForm A= mod (F, M);
+  CanonicalForm B= mod (G, M);
+
+  Variable x= Variable (1);
+  int degA= degree (A, x);
+  int degB= degree (B, x);
+  int m= degA - degB;
+  if (m < 0)
+    return 0;
+
+  Variable v;
+  CanonicalForm Q;
+  if (degB < 1 || CFFactory::gettype() == GaloisFieldDomain)
+  {
+    CanonicalForm R;
+    divrem2 (A, B, Q, R, M);
+  }
+  else
+  {
+    if (hasFirstAlgVar (A, v) || hasFirstAlgVar (B, v))
+    {
+      CanonicalForm R= reverse (A, degA);
+      CanonicalForm revB= reverse (B, degB);
+      revB= newtonInverse (revB, m + 1, M);
+      Q= mulMod2 (R, revB, M);
+      Q= mod (Q, power (x, m + 1));
+      Q= reverse (Q, m);
+    }
+    else
+    {
+      Variable y= Variable (2);
+#if (HAVE_FLINT &&  __FLINT_RELEASE >= 20400)
+      nmod_poly_t FLINTmipo;
+      fq_nmod_ctx_t fq_con;
+
+      nmod_poly_init (FLINTmipo, getCharacteristic());
+      convertFacCF2nmod_poly_t (FLINTmipo, M);
+
+      fq_nmod_ctx_init_modulus (fq_con, FLINTmipo, "Z");
+
+
+      fq_nmod_poly_t FLINTA, FLINTB;
+      convertFacCF2Fq_nmod_poly_t (FLINTA, swapvar (A, x, y), fq_con);
+      convertFacCF2Fq_nmod_poly_t (FLINTB, swapvar (B, x, y), fq_con);
+
+      fq_nmod_poly_divrem (FLINTA, FLINTB, FLINTA, FLINTB, fq_con);
+
+      Q= convertFq_nmod_poly_t2FacCF (FLINTA, x, y, fq_con);
+
+      fq_nmod_poly_clear (FLINTA, fq_con);
+      fq_nmod_poly_clear (FLINTB, fq_con);
+      nmod_poly_clear (FLINTmipo);
+      fq_nmod_ctx_clear (fq_con);
+#else
+      bool zz_pEbak= zz_pE::initialized();
+      zz_pEBak bak;
+      if (zz_pEbak)
+        bak.save();
+      zz_pX mipo= convertFacCF2NTLzzpX (M);
+      zz_pEX NTLA, NTLB;
+      NTLA= convertFacCF2NTLzz_pEX (swapvar (A, x, y), mipo);
+      NTLB= convertFacCF2NTLzz_pEX (swapvar (B, x, y), mipo);
+      div (NTLA, NTLA, NTLB);
+      Q= convertNTLzz_pEX2CF (NTLA, x, y);
+      if (zz_pEbak)
+        bak.restore();
+#endif
+    }
+  }
+
+  return Q;
+}
+
+void
+newtonDivrem (const CanonicalForm& F, const CanonicalForm& G, CanonicalForm& Q,
+              CanonicalForm& R, const CanonicalForm& M)
+{
+  CanonicalForm A= mod (F, M);
+  CanonicalForm B= mod (G, M);
+  Variable x= Variable (1);
+  int degA= degree (A, x);
+  int degB= degree (B, x);
+  int m= degA - degB;
+
+  if (m < 0)
+  {
+    R= A;
+    Q= 0;
+    return;
+  }
+
+  Variable v;
+  if (degB <= 1 || CFFactory::gettype() == GaloisFieldDomain)
+  {
+     divrem2 (A, B, Q, R, M);
+  }
+  else
+  {
+    if (hasFirstAlgVar (A, v) || hasFirstAlgVar (B, v))
+    {
+      R= reverse (A, degA);
+
+      CanonicalForm revB= reverse (B, degB);
+      revB= newtonInverse (revB, m + 1, M);
+      Q= mulMod2 (R, revB, M);
+
+      Q= mod (Q, power (x, m + 1));
+      Q= reverse (Q, m);
+
+      R= A - mulMod2 (Q, B, M);
+    }
+    else
+    {
+      Variable y= Variable (2);
+#if (HAVE_FLINT &&  __FLINT_RELEASE >= 20400)
+      nmod_poly_t FLINTmipo;
+      fq_nmod_ctx_t fq_con;
+
+      nmod_poly_init (FLINTmipo, getCharacteristic());
+      convertFacCF2nmod_poly_t (FLINTmipo, M);
+
+      fq_nmod_ctx_init_modulus (fq_con, FLINTmipo, "Z");
+
+      fq_nmod_poly_t FLINTA, FLINTB;
+      convertFacCF2Fq_nmod_poly_t (FLINTA, swapvar (A, x, y), fq_con);
+      convertFacCF2Fq_nmod_poly_t (FLINTB, swapvar (B, x, y), fq_con);
+
+      fq_nmod_poly_divrem (FLINTA, FLINTB, FLINTA, FLINTB, fq_con);
+
+      Q= convertFq_nmod_poly_t2FacCF (FLINTA, x, y, fq_con);
+      R= convertFq_nmod_poly_t2FacCF (FLINTB, x, y, fq_con);
+
+      fq_nmod_poly_clear (FLINTA, fq_con);
+      fq_nmod_poly_clear (FLINTB, fq_con);
+      nmod_poly_clear (FLINTmipo);
+      fq_nmod_ctx_clear (fq_con);
+#else
+      zz_pX mipo= convertFacCF2NTLzzpX (M);
+      zz_pEX NTLA, NTLB;
+      NTLA= convertFacCF2NTLzz_pEX (swapvar (A, x, y), mipo);
+      NTLB= convertFacCF2NTLzz_pEX (swapvar (B, x, y), mipo);
+      zz_pEX NTLQ, NTLR;
+      DivRem (NTLQ, NTLR, NTLA, NTLB);
+      Q= convertNTLzz_pEX2CF (NTLQ, x, y);
+      R= convertNTLzz_pEX2CF (NTLR, x, y);
+#endif
+    }
+  }
+}
+
+static inline
+CFList split (const CanonicalForm& F, const int m, const Variable& x)
+{
+  CanonicalForm A= F;
+  CanonicalForm buf= 0;
+  bool swap= false;
+  if (degree (A, x) <= 0)
+    return CFList(A);
+  else if (x.level() != A.level())
+  {
+    swap= true;
+    A= swapvar (A, x, A.mvar());
+  }
+
+  int j= (int) floor ((double) degree (A)/ m);
+  CFList result;
+  CFIterator i= A;
+  for (; j >= 0; j--)
+  {
+    while (i.hasTerms() && i.exp() - j*m >= 0)
+    {
+      if (swap)
+        buf += i.coeff()*power (A.mvar(), i.exp() - j*m);
+      else
+        buf += i.coeff()*power (x, i.exp() - j*m);
+      i++;
+    }
+    if (swap)
+      result.append (swapvar (buf, x, F.mvar()));
+    else
+      result.append (buf);
+    buf= 0;
+  }
+  return result;
+}
+
+static inline
+void divrem32 (const CanonicalForm& F, const CanonicalForm& G, CanonicalForm& Q,
+               CanonicalForm& R, const CFList& M);
+
+static inline
+void divrem21 (const CanonicalForm& F, const CanonicalForm& G, CanonicalForm& Q,
+               CanonicalForm& R, const CFList& M)
+{
+  CanonicalForm A= mod (F, M);
+  CanonicalForm B= mod (G, M);
+  Variable x= Variable (1);
+  int degB= degree (B, x);
+  int degA= degree (A, x);
+  if (degA < degB)
+  {
+    Q= 0;
+    R= A;
+    return;
+  }
+  if (degB < 1)
+  {
+    divrem (A, B, Q, R);
+    Q= mod (Q, M);
+    R= mod (R, M);
+    return;
+  }
+  int m= (int) ceil ((double) (degB + 1)/2.0) + 1;
+  ASSERT (4*m >= degA, "expected degree (F, 1) < 2*degree (G, 1)");
+  CFList splitA= split (A, m, x);
+  if (splitA.length() == 3)
+    splitA.insert (0);
+  if (splitA.length() == 2)
+  {
+    splitA.insert (0);
+    splitA.insert (0);
+  }
+  if (splitA.length() == 1)
+  {
+    splitA.insert (0);
+    splitA.insert (0);
+    splitA.insert (0);
+  }
+
+  CanonicalForm xToM= power (x, m);
+
+  CFListIterator i= splitA;
+  CanonicalForm H= i.getItem();
+  i++;
+  H *= xToM;
+  H += i.getItem();
+  i++;
+  H *= xToM;
+  H += i.getItem();
+  i++;
+
+  divrem32 (H, B, Q, R, M);
+
+  CFList splitR= split (R, m, x);
+  if (splitR.length() == 1)
+    splitR.insert (0);
+
+  H= splitR.getFirst();
+  H *= xToM;
+  H += splitR.getLast();
+  H *= xToM;
+  H += i.getItem();
+
+  CanonicalForm bufQ;
+  divrem32 (H, B, bufQ, R, M);
+
+  Q *= xToM;
+  Q += bufQ;
+  return;
+}
+
+static inline
+void divrem32 (const CanonicalForm& F, const CanonicalForm& G, CanonicalForm& Q,
+               CanonicalForm& R, const CFList& M)
+{
+  CanonicalForm A= mod (F, M);
+  CanonicalForm B= mod (G, M);
+  Variable x= Variable (1);
+  int degB= degree (B, x);
+  int degA= degree (A, x);
+  if (degA < degB)
+  {
+    Q= 0;
+    R= A;
+    return;
+  }
+  if (degB < 1)
+  {
+    divrem (A, B, Q, R);
+    Q= mod (Q, M);
+    R= mod (R, M);
+    return;
+  }
+  int m= (int) ceil ((double) (degB + 1)/ 2.0);
+  ASSERT (3*m > degA, "expected degree (F, 1) < 3*degree (G, 1)");
+  CFList splitA= split (A, m, x);
+  CFList splitB= split (B, m, x);
+
+  if (splitA.length() == 2)
+  {
+    splitA.insert (0);
+  }
+  if (splitA.length() == 1)
+  {
+    splitA.insert (0);
+    splitA.insert (0);
+  }
+  CanonicalForm xToM= power (x, m);
+
+  CanonicalForm H;
+  CFListIterator i= splitA;
+  i++;
+
+  if (degree (splitA.getFirst(), x) < degree (splitB.getFirst(), x))
+  {
+    H= splitA.getFirst()*xToM + i.getItem();
+    divrem21 (H, splitB.getFirst(), Q, R, M);
+  }
+  else
+  {
+    R= splitA.getFirst()*xToM + i.getItem() + splitB.getFirst() -
+       splitB.getFirst()*xToM;
+    Q= xToM - 1;
+  }
+
+  H= mulMod (Q, splitB.getLast(), M);
+
+  R= R*xToM + splitA.getLast() - H;
+
+  while (degree (R, x) >= degB)
+  {
+    xToM= power (x, degree (R, x) - degB);
+    Q += LC (R, x)*xToM;
+    R -= mulMod (LC (R, x), B, M)*xToM;
+    Q= mod (Q, M);
+    R= mod (R, M);
+  }
+
+  return;
+}
+
+void divrem2 (const CanonicalForm& F, const CanonicalForm& G, CanonicalForm& Q,
+              CanonicalForm& R, const CanonicalForm& M)
+{
+  CanonicalForm A= mod (F, M);
+  CanonicalForm B= mod (G, M);
+
+  if (B.inCoeffDomain())
+  {
+    divrem (A, B, Q, R);
+    return;
+  }
+  if (A.inCoeffDomain() && !B.inCoeffDomain())
+  {
+    Q= 0;
+    R= A;
+    return;
+  }
+
+  if (B.level() < A.level())
+  {
+    divrem (A, B, Q, R);
+    return;
+  }
+  if (A.level() > B.level())
+  {
+    R= A;
+    Q= 0;
+    return;
+  }
+  if (B.level() == 1 && B.isUnivariate())
+  {
+    divrem (A, B, Q, R);
+    return;
+  }
+
+  Variable x= Variable (1);
+  int degB= degree (B, x);
+  if (degB > degree (A, x))
+  {
+    Q= 0;
+    R= A;
+    return;
+  }
+
+  CFList splitA= split (A, degB, x);
+
+  CanonicalForm xToDegB= power (x, degB);
+  CanonicalForm H, bufQ;
+  Q= 0;
+  CFListIterator i= splitA;
+  H= i.getItem()*xToDegB;
+  i++;
+  H += i.getItem();
+  CFList buf;
+  while (i.hasItem())
+  {
+    buf= CFList (M);
+    divrem21 (H, B, bufQ, R, buf);
+    i++;
+    if (i.hasItem())
+      H= R*xToDegB + i.getItem();
+    Q *= xToDegB;
+    Q += bufQ;
+  }
+  return;
+}
+
+void divrem (const CanonicalForm& F, const CanonicalForm& G, CanonicalForm& Q,
+             CanonicalForm& R, const CFList& MOD)
+{
+  CanonicalForm A= mod (F, MOD);
+  CanonicalForm B= mod (G, MOD);
+  Variable x= Variable (1);
+  int degB= degree (B, x);
+  if (degB > degree (A, x))
+  {
+    Q= 0;
+    R= A;
+    return;
+  }
+
+  if (degB <= 0)
+  {
+    divrem (A, B, Q, R);
+    Q= mod (Q, MOD);
+    R= mod (R, MOD);
+    return;
+  }
+  CFList splitA= split (A, degB, x);
+
+  CanonicalForm xToDegB= power (x, degB);
+  CanonicalForm H, bufQ;
+  Q= 0;
+  CFListIterator i= splitA;
+  H= i.getItem()*xToDegB;
+  i++;
+  H += i.getItem();
+  while (i.hasItem())
+  {
+    divrem21 (H, B, bufQ, R, MOD);
+    i++;
+    if (i.hasItem())
+      H= R*xToDegB + i.getItem();
+    Q *= xToDegB;
+    Q += bufQ;
+  }
+  return;
+}
+
+bool
+uniFdivides (const CanonicalForm& A, const CanonicalForm& B)
+{
+  if (B.isZero())
+    return true;
+  if (A.isZero())
+    return false;
+  if (CFFactory::gettype() == GaloisFieldDomain)
+    return fdivides (A, B);
+  int p= getCharacteristic();
+  if (A.inCoeffDomain() || B.inCoeffDomain())
+  {
+    if (A.inCoeffDomain())
+      return true;
+    else
+      return false;
+  }
+  if (p > 0)
+  {
+    if (fac_NTL_char != p)
+    {
+      fac_NTL_char= p;
+      zz_p::init (p);
+    }
+    Variable alpha;
+    if (hasFirstAlgVar (A, alpha) || hasFirstAlgVar (B, alpha))
+    {
+#if (HAVE_FLINT && __FLINT_RELEASE >= 20400)
+      nmod_poly_t FLINTmipo;
+      fq_nmod_ctx_t fq_con;
+
+      nmod_poly_init (FLINTmipo, getCharacteristic());
+      convertFacCF2nmod_poly_t (FLINTmipo, getMipo (alpha));
+
+      fq_nmod_ctx_init_modulus (fq_con, FLINTmipo, "Z");
+
+      fq_nmod_poly_t FLINTA, FLINTB;
+      convertFacCF2Fq_nmod_poly_t (FLINTA, A, fq_con);
+      convertFacCF2Fq_nmod_poly_t (FLINTB, B, fq_con);
+      int result= fq_nmod_poly_divides (FLINTA, FLINTB, FLINTA, fq_con);
+      fq_nmod_poly_clear (FLINTA, fq_con);
+      fq_nmod_poly_clear (FLINTB, fq_con);
+      nmod_poly_clear (FLINTmipo);
+      fq_nmod_ctx_clear (fq_con);
+      return result;
+#else
+      zz_pX NTLMipo= convertFacCF2NTLzzpX (getMipo (alpha));
+      zz_pE::init (NTLMipo);
+      zz_pEX NTLA= convertFacCF2NTLzz_pEX (A, NTLMipo);
+      zz_pEX NTLB= convertFacCF2NTLzz_pEX (B, NTLMipo);
+      return divide (NTLB, NTLA);
+#endif
+    }
+#ifdef HAVE_FLINT
+    nmod_poly_t FLINTA, FLINTB;
+    convertFacCF2nmod_poly_t (FLINTA, A);
+    convertFacCF2nmod_poly_t (FLINTB, B);
+    nmod_poly_divrem (FLINTB, FLINTA, FLINTB, FLINTA);
+    bool result= nmod_poly_is_zero (FLINTA);
+    nmod_poly_clear (FLINTA);
+    nmod_poly_clear (FLINTB);
+    return result;
+#else
+    zz_pX NTLA= convertFacCF2NTLzzpX (A);
+    zz_pX NTLB= convertFacCF2NTLzzpX (B);
+    return divide (NTLB, NTLA);
+#endif
+  }
+#ifdef HAVE_FLINT
+  Variable alpha;
+  bool isRat= isOn (SW_RATIONAL);
+  if (!isRat)
+    On (SW_RATIONAL);
+  if (!hasFirstAlgVar (A, alpha) && !hasFirstAlgVar (B, alpha))
+  {
+    fmpq_poly_t FLINTA,FLINTB;
+    convertFacCF2Fmpq_poly_t (FLINTA, A);
+    convertFacCF2Fmpq_poly_t (FLINTB, B);
+    fmpq_poly_rem (FLINTA, FLINTB, FLINTA);
+    bool result= fmpq_poly_is_zero (FLINTA);
+    fmpq_poly_clear (FLINTA);
+    fmpq_poly_clear (FLINTB);
+    if (!isRat)
+      Off (SW_RATIONAL);
+    return result;
+  }
+  CanonicalForm Q, R;
+  newtonDivrem (B, A, Q, R);
+  if (!isRat)
+    Off (SW_RATIONAL);
+  return R.isZero();
+#else
+  bool isRat= isOn (SW_RATIONAL);
+  if (!isRat)
+    On (SW_RATIONAL);
+  bool result= fdivides (A, B);
+  if (!isRat)
+    Off (SW_RATIONAL);
+  return result; //maybe NTL?
+#endif
+}
+
+// end division
+
+#endif
diff --git a/factory/facMul.h b/factory/facMul.h
new file mode 100644
index 0000000..cfc11f4
--- /dev/null
+++ b/factory/facMul.h
@@ -0,0 +1,181 @@
+/*****************************************************************************\
+ * Computer Algebra System SINGULAR
+\*****************************************************************************/
+/** @file facMul.h
+ *
+ * This file defines functions for fast multiplication and division with
+ * remainder
+ *
+ * @author Martin Lee
+ *
+ **/
+/*****************************************************************************/
+
+#ifndef FAC_MUL_H
+#define FAC_MUL_H
+
+#include "canonicalform.h"
+#include "fac_util.h"
+
+#ifdef HAVE_NTL
+/// multiplication of univariate polys using FLINT/NTL over F_p, F_q, Z/p^k,
+/// Z/p^k[t]/(f), Z, Q, Q(a), if we are in GF factory's default multiplication
+/// is used. If @a b!= 0 and getCharacteristic() == 0 the input will be
+/// considered as elements over Z/p^k or Z/p^k[t]/(f).
+///
+/// @return @a mulNTL returns F*G
+CanonicalForm
+mulNTL (const CanonicalForm& F, ///< [in] a univariate poly
+        const CanonicalForm& G, ///< [in] a univariate poly
+        const modpk& b= modpk() ///< [in] coeff bound
+       );
+
+/// mod of univariate polys using FLINT/NTL over F_p, F_q, Z/p^k,
+/// Z/p^k[t]/(f), Z, Q, Q(a), if we are in GF factory's default multiplication
+/// is used. If @a b!= 0 and getCharacteristic() == 0 the input will be
+/// considered as elements over Z/p^k or Z/p^k[t]/(f); in this case invertiblity
+/// of Lc(G) is not checked
+///
+/// @return @a modNTL returns F mod G
+CanonicalForm
+modNTL (const CanonicalForm& F, ///< [in] a univariate poly
+        const CanonicalForm& G, ///< [in] a univariate poly
+        const modpk& b= modpk() ///< [in] coeff bound
+       );
+
+/// division of univariate polys using FLINT/NTL over F_p, F_q, Z/p^k,
+/// Z/p^k[t]/(f), Z, Q, Q(a), if we are in GF factory's default multiplication
+/// is used. If @a b!= 0 and getCharacteristic() == 0 the input will be
+/// considered as elements over Z/p^k or Z/p^k[t]/(f); in this case invertiblity
+/// of Lc(G) is not checked
+///
+/// @return @a divNTL returns F/G
+CanonicalForm
+divNTL (const CanonicalForm& F, ///< [in] a univariate poly
+        const CanonicalForm& G, ///< [in] a univariate poly
+        const modpk& b= modpk() ///< [in] coeff bound
+       );
+
+/// division with remainder of @a F by @a G wrt Variable (1) modulo @a M.
+/// Uses an algorithm based on Burnikel, Ziegler "Fast recursive division".
+///
+/// @return @a Q returns the dividend, @a R returns the remainder.
+/// @sa divrem()
+void divrem2 (const CanonicalForm& F, ///< [in] bivariate, compressed polynomial
+              const CanonicalForm& G, ///< [in] bivariate, compressed polynomial
+              CanonicalForm& Q,       ///< [in,out] dividend
+              CanonicalForm& R,       ///< [in,out] remainder, degree (R, 1) <
+                                      ///< degree (G, 1)
+              const CanonicalForm& M  ///< [in] power of Variable (2)
+             );
+
+/// division with remainder of @a F by @a G wrt Variable (1) modulo @a MOD.
+/// Uses an algorithm based on Burnikel, Ziegler "Fast recursive division".
+///
+/// @sa divrem2()
+void divrem (
+           const CanonicalForm& F, ///< [in] multivariate, compressed polynomial
+           const CanonicalForm& G, ///< [in] multivariate, compressed polynomial
+           CanonicalForm& Q,       ///< [in,out] dividend
+           CanonicalForm& R,       ///< [in,out] remainder, degree (R, 1) <
+                                   ///< degree (G, 1)
+           const CFList& MOD       ///< [in] only contains powers of
+                                   ///< Variables of level higher than 1
+            );
+
+
+/// division with remainder of @a F by
+/// @a G wrt Variable (1) modulo @a M using Newton inversion
+///
+/// @return @a Q returns the dividend, @a R returns the remainder.
+/// @sa divrem2(), newtonDiv()
+void
+newtonDivrem (const CanonicalForm& F, ///< [in] bivariate, compressed polynomial
+              const CanonicalForm& G, ///< [in] bivariate, compressed polynomial
+                                      ///< which is monic in Variable (1)
+              CanonicalForm& Q,       ///< [in,out] dividend
+              CanonicalForm& R,       ///< [in,out] remainder, degree (R, 1) <
+                                      ///< degree (G, 1)
+              const CanonicalForm& M  ///< [in] power of Variable (2)
+             );
+
+/// division of @a F by
+/// @a G wrt Variable (1) modulo @a M using Newton inversion
+///
+/// @return @a newtonDiv returns the dividend
+/// @sa divrem2(), newtonDivrem()
+CanonicalForm
+newtonDiv (const CanonicalForm& F, ///< [in] bivariate, compressed polynomial
+           const CanonicalForm& G, ///< [in] bivariate, compressed polynomial
+                                   ///< which is monic in Variable (1)
+           const CanonicalForm& M  ///< [in] power of Variable (2)
+          );
+
+/// divisibility test for univariate polys
+///
+/// @return @a uniFdivides returns true if A divides B
+bool
+uniFdivides (const CanonicalForm& A, ///< [in] univariate poly
+             const CanonicalForm& B  ///< [in] univariate poly
+            );
+
+/// Karatsuba style modular multiplication for bivariate polynomials.
+///
+/// @return @a mulMod2 returns @a A * @a B mod @a M.
+CanonicalForm
+mulMod2 (const CanonicalForm& A, ///< [in] bivariate, compressed polynomial
+         const CanonicalForm& B, ///< [in] bivariate, compressed polynomial
+         const CanonicalForm& M  ///< [in] power of Variable (2)
+        );
+
+/// Karatsuba style modular multiplication for multivariate polynomials.
+///
+/// @return @a mulMod2 returns @a A * @a B mod @a MOD.
+CanonicalForm
+mulMod (const CanonicalForm& A, ///< [in] multivariate, compressed polynomial
+        const CanonicalForm& B, ///< [in] multivariate, compressed polynomial
+        const CFList& MOD       ///< [in] only contains powers of
+                                ///< Variables of level higher than 1
+       );
+
+/// reduce @a F modulo elements in @a M.
+///
+/// @return @a mod returns @a F modulo @a M
+CanonicalForm mod (const CanonicalForm& F, ///< [in] compressed polynomial
+                   const CFList& M         ///< [in] list containing only
+                                           ///< univariate polynomials
+                  );
+
+/// product of all elements in @a L modulo @a M via divide-and-conquer.
+///
+/// @return @a prodMod returns product of all elements in @a L modulo @a M.
+CanonicalForm
+prodMod (const CFList& L,       ///< [in] contains only bivariate, compressed
+                                ///< polynomials
+         const CanonicalForm& M ///< [in] power of Variable (2)
+        );
+
+/// product of all elements in @a L modulo @a M via divide-and-conquer.
+///
+/// @return @a prodMod returns product of all elements in @a L modulo @a M.
+CanonicalForm
+prodMod (const CFList& L, ///< [in] contains multivariate, compressed
+                          ///< polynomials
+         const CFList& M  ///< [in] contains only powers of Variables
+        );
+
+#ifdef HAVE_FLINT
+/// division with remainder of univariate polynomials over Q and Q(a) using
+/// Newton inversion, satisfying F=G*Q+R, deg(R) < deg(G)
+void
+newtonDivrem (const CanonicalForm& F, ///<[in] univariate poly
+              const CanonicalForm& G, ///<[in] univariate poly
+              CanonicalForm& Q,       ///<[in, out] quotient
+              CanonicalForm& R        ///<[in, out] remainder
+             );
+#endif
+#endif
+
+#endif
+/* FAC_MUL_H */
+
diff --git a/factory/facSparseHensel.cc b/factory/facSparseHensel.cc
new file mode 100644
index 0000000..b863de7
--- /dev/null
+++ b/factory/facSparseHensel.cc
@@ -0,0 +1,405 @@
+/*****************************************************************************\
+ * Computer Algebra System SINGULAR
+\*****************************************************************************/
+/** @file facSparseHensel.cc
+ *
+ * This file implements functions for sparse heuristic Hensel lifting
+ *
+ * ABSTRACT: "A fast implementation of polynomial factorization" by M. Lucks and
+ * "Effective polynomial computation" by R. Zippel
+ *
+ * @author Martin Lee
+ *
+ **/
+/*****************************************************************************/
+
+
+#include "config.h"
+
+#include "cf_assert.h"
+#include "facSparseHensel.h"
+#include "cf_algorithm.h"
+#include "cfModGcd.h"
+#include "facFqFactorize.h"
+
+int
+LucksWangSparseHeuristic (const CanonicalForm& F, const CFList& factors,
+                          int level, const CFList& leadingCoeffs, CFList& result)
+{
+  int threshold= 450;
+  CFArray termsF= getBiTerms (F, threshold);
+  if (termsF.size() > threshold)
+    return 0;
+  sort (termsF, level);
+
+  CFArray* monoms= new CFArray [factors.length()];
+  int i= 0;
+  int num= 0;
+  for (CFListIterator iter= factors; iter.hasItem(); iter++, i++)
+  {
+    monoms[i]= getTerms (iter.getItem());
+    num += monoms [i].size();
+    sort (monoms [i]);
+  }
+
+  i= 0;
+  CFArray* monomsLead= new CFArray [leadingCoeffs.length()];
+  for (CFListIterator iter= leadingCoeffs; iter.hasItem(); iter++, i++)
+  {
+    monomsLead[i]= getTerms (iter.getItem());
+    sort (monomsLead [i]);
+    groupTogether (monomsLead [i], level);
+    strip (monomsLead [i], level);
+  }
+
+  CFArray solution= CFArray (num);
+  int k, d, count, j= F.level() + 1;
+  num= 0;
+  i= 0;
+  for (CFListIterator iter= factors; iter.hasItem(); i++, iter++)
+  {
+    d= degree (iter.getItem(), 1);
+    count= 0;
+    for (k= 0; k < monoms[i].size(); k++, j++, num++)
+    {
+      monoms [i][k] *= Variable (j);
+      if (degree (monoms[i][k], 1) == d)
+      {
+        solution[num]= monomsLead [i] [count];
+        count++;
+      }
+    }
+  }
+
+  delete [] monomsLead;
+
+  CFList tmp;
+  CFArray* stripped2= new CFArray [factors.length()];
+  for (i= factors.length() - 1; i > -1; i--)
+  {
+    tmp.insert (buildPolyFromArray (monoms [i]));
+    strip (monoms[i], stripped2 [i], level);
+  }
+  delete [] monoms;
+
+  CanonicalForm H= prod (tmp);
+  CFArray monomsH= getMonoms (H);
+  sort (monomsH,F.level());
+
+  groupTogether (monomsH, F.level());
+
+  if (monomsH.size() != termsF.size())
+  {
+    delete [] stripped2;
+    return 0;
+  }
+
+  CFArray strippedH;
+  strip (monomsH, strippedH, level);
+  CFArray strippedF;
+  strip (termsF, strippedF, level);
+
+  if (!isEqual (strippedH, strippedF))
+  {
+    delete [] stripped2;
+    return 0;
+  }
+
+  CFArray A= getEquations (monomsH, termsF);
+  CFArray startingSolution= solution;
+  CFArray newSolution= CFArray (solution.size());
+  result= CFList();
+  do
+  {
+    evaluate (A, solution, F.level() + 1);
+    if (isZero (A))
+      break;
+    if (!simplify (A, newSolution, F.level() + 1))
+    {
+      delete [] stripped2;
+      return 0;
+    }
+    if (isZero (newSolution))
+      break;
+    if (!merge (solution, newSolution))
+      break;
+  } while (1);
+
+  if (isEqual (startingSolution, solution))
+  {
+    delete [] stripped2;
+    return 0;
+  }
+  CanonicalForm factor;
+  num= 0;
+  for (i= 0; i < factors.length(); i++)
+  {
+    k= stripped2[i].size();
+    factor= 0;
+    for (j= 0; j < k; j++, num++)
+    {
+      if (solution [num].isZero())
+        continue;
+      factor += solution [num]*stripped2[i][j];
+    }
+    result.append (factor);
+  }
+
+  delete [] stripped2;
+  if (result.length() > 0)
+    return 1;
+  return 0;
+}
+
+CFList
+sparseHeuristic (const CanonicalForm& A, const CFList& biFactors,
+                 CFList*& moreBiFactors, const CFList& evaluation,
+                 int minFactorsLength)
+{
+  int j= A.level() - 1;
+  int i;
+
+  //initialize storage
+  CFArray *** storeFactors= new CFArray** [j];
+  for (i= 0; i < j; i++)
+    storeFactors [i]= new CFArray* [2];
+
+  CFArray eval= CFArray (j);
+  i= j - 1;
+  for (CFListIterator iter= evaluation; iter.hasItem(); iter++,i--)
+    eval[i]= iter.getItem();
+  storeFactors [0] [0]= new CFArray [minFactorsLength];
+  storeFactors [0] [1]= new CFArray [minFactorsLength];
+  for (i= 1; i < j; i++)
+  {
+    storeFactors[i] [0]= new CFArray [minFactorsLength];
+    storeFactors[i] [1]= new CFArray [minFactorsLength];
+  }
+  //
+
+  CFList * normalizingFactors= new CFList [j];
+  CFList uniFactors;
+  normalizingFactors [0]= findNormalizingFactor1 (biFactors,
+                                              evaluation.getLast(), uniFactors);
+  for (i= j - 1; i > 0; i--)
+  {
+    if (moreBiFactors[i-1].length() != minFactorsLength)
+    {
+      moreBiFactors[i-1]=
+        recombination (moreBiFactors [i-1], uniFactors, 1,
+                       moreBiFactors[i-1].length()-uniFactors.length()+1,
+                       eval[i], Variable (i + 2)
+                      );
+    }
+    normalizingFactors [i]= findNormalizingFactor2 (moreBiFactors [i - 1],
+                                                    eval[i], uniFactors);
+  }
+
+  CFList tmp;
+  tmp= normalize (biFactors, normalizingFactors[0]);
+  getTerms2 (tmp, storeFactors [0] [0]);
+  storeFactors [0] [1]= evaluate (storeFactors [0] [0], minFactorsLength,
+                                  evaluation.getLast(), Variable (2));
+  for (i= j - 1; i > 0; i--)
+  {
+    tmp= normalize (moreBiFactors [i-1], normalizingFactors [i]);
+    getTerms2 (tmp, storeFactors [i] [0]);
+    storeFactors [i] [1]= evaluate (storeFactors [i] [0], minFactorsLength,
+                                    eval[i], Variable (i + 2));
+  }
+
+
+  int k, l, m, mm, count, sizeOfUniFactors= 0;
+  int*** seperator= new int** [j];
+  Variable x= Variable (1);
+
+  for (i= 0; i < j; i++)
+    seperator [i]= new int* [minFactorsLength];
+  for (k= 0; k < minFactorsLength; k++)
+  {
+    for (i= 0; i < j; i++)
+    {
+      count= 0;
+      for (l= 0; l < storeFactors [i][0][k].size() - 1; l++)
+      {
+        if (degree (storeFactors[i][0][k][l], x) <
+            degree (storeFactors[i][0][k][l+1], x))
+          count++;
+      }
+      if (i == 0)
+        sizeOfUniFactors= count;
+      else if (sizeOfUniFactors != count)
+      {
+        for (m= 0; m < j; m++)
+        {
+          delete [] storeFactors [m] [0];
+          delete [] storeFactors [m] [1];
+          delete [] storeFactors [m];
+          for (mm= 0; mm < k; mm++)
+            delete [] seperator [m][mm];
+          delete [] seperator [m];
+        }
+        delete [] storeFactors;
+        delete [] seperator;
+        return CFList();
+      }
+      seperator [i][k]= new int [count + 3];
+      seperator [i][k][0]= count + 1;
+      seperator [i][k][1]= 0;
+      count= 2;
+      for (l= 0; l < storeFactors [i][0][k].size() - 1; l++)
+      {
+        if (degree (storeFactors[i][0][k][l], x) <
+            degree (storeFactors[i][0][k][l+1], x))
+        {
+          seperator[i][k][count]=l + 1;
+          count++;
+        }
+      }
+      seperator [i][k][count]= storeFactors[i][0][k].size();
+    }
+  }
+
+  CanonicalForm tmp1, factor, quot;
+  CanonicalForm B= A;
+  CFList result;
+  int maxTerms, n, index1, index2, mmm, found, columns, oneCount;
+  int ** mat;
+
+  for (k= 0; k < minFactorsLength; k++)
+  {
+    factor= 0;
+    sizeOfUniFactors= seperator [0][k][0];
+    for (n= 1; n <= sizeOfUniFactors; n++)
+    {
+      columns= 0;
+      maxTerms= 1;
+      index1= j - 1;
+      for (i= j - 1; i >= 0; i--)
+      {
+        if (maxTerms < seperator[i][k][n+1]-seperator[i][k][n])
+        {
+          maxTerms= seperator[i][k][n + 1]-seperator[i][k][n];
+          index1= i;
+        }
+      }
+      for (i= j - 1; i >= 0; i--)
+      {
+        if (i == index1)
+          continue;
+        columns += seperator [i][k][n+1]-seperator[i][k][n];
+      }
+      mat= new int *[maxTerms];
+      mm= 0;
+      for (m= seperator[index1][k][n]; m < seperator[index1][k][n+1]; m++, mm++)
+      {
+        tmp1= storeFactors [index1][1][k][m];
+        mat[mm]= new int [columns];
+        for (i= 0; i < columns; i++)
+          mat[mm][i]= 0;
+        index2= 0;
+        for (i= j - 1; i >= 0; i--)
+        {
+          if (i == index1)
+            continue;
+          found= -1;
+          if ((found= search (storeFactors[i][1][k], tmp1,
+                              seperator[i][k][n], seperator[i][k][n+1])) >= 0)
+            mat[mm][index2 + found - seperator [i][k][n]]= 1;
+          index2 += seperator [i][k][n+1]-seperator[i][k][n];
+        }
+      }
+
+      index2= 0;
+      for (i= j - 1; i >= 0; i--)
+      {
+        if (i == index1)
+          continue;
+        oneCount= 0;
+        for (mm= 0; mm < seperator [i][k][n + 1] - seperator [i][k][n]; mm++)
+        {
+          for (m= 0; m < maxTerms; m++)
+          {
+            if (mat[m][mm+index2] == 1)
+              oneCount++;
+          }
+        }
+        if (oneCount == seperator [i][k][n+1]-seperator[i][k][n] - 1)
+        {
+          for (mm= 0; mm < seperator [i][k][n+1]-seperator[i][k][n]; mm++)
+          {
+            oneCount= 0;
+            for (m= 0; m < maxTerms; m++)
+              if (mat[m][mm+index2] == 1)
+                oneCount++;
+            if (oneCount > 0)
+              continue;
+            for (m= 0; m < maxTerms; m++)
+            {
+              oneCount= 0;
+              for (mmm= 0; mmm < seperator[i][k][n+1]-seperator[i][k][n]; mmm++)
+              {
+                if (mat[m][mmm+index2] == 1)
+                  oneCount++;
+              }
+              if (oneCount > 0)
+                continue;
+              mat[m][mm+index2]= 1;
+            }
+          }
+        }
+        index2 += seperator [i][k][n+1] - seperator [i][k][n];
+      }
+
+      //read off solution
+      mm= 0;
+      for (m= seperator[index1][k][n]; m < seperator[index1][k][n+1]; m++, mm++)
+      {
+        tmp1= storeFactors [index1][0][k][m];
+        index2= 0;
+        for (i= j - 1; i > -1; i--)
+        {
+          if (i == index1)
+            continue;
+          for (mmm= 0; mmm < seperator [i][k][n+1]-seperator[i][k][n]; mmm++)
+            if (mat[mm][mmm+index2] == 1)
+              tmp1= patch (tmp1, storeFactors[i][0][k][seperator[i][k][n]+mmm],
+                           eval[i]);
+          index2 += seperator [i][k][n+1]-seperator[i][k][n];
+        }
+        factor += tmp1;
+      }
+
+      for (m= 0; m < maxTerms; m++)
+        delete [] mat [m];
+      delete [] mat;
+    }
+
+    if (fdivides (factor, B, quot))
+    {
+      result.append (factor);
+      B= quot;
+      if (result.length() == biFactors.length() - 1)
+      {
+        result.append (quot);
+        break;
+      }
+    }
+  }
+
+  //delete
+  for (i= 0; i < j; i++)
+  {
+    delete [] storeFactors [i] [0];
+    delete [] storeFactors [i] [1];
+    delete [] storeFactors [i];
+    for (k= 0; k < minFactorsLength; k++)
+      delete [] seperator [i][k];
+    delete [] seperator [i];
+  }
+  delete [] seperator;
+  delete [] storeFactors;
+  //
+
+  return result;
+}
diff --git a/factory/facSparseHensel.h b/factory/facSparseHensel.h
new file mode 100644
index 0000000..25c836c
--- /dev/null
+++ b/factory/facSparseHensel.h
@@ -0,0 +1,621 @@
+/*****************************************************************************\
+ * Computer Algebra System SINGULAR
+\*****************************************************************************/
+/** @file facSparseHensel.h
+ *
+ * This file provides functions for sparse heuristic Hensel lifting
+ *
+ * @author Martin Lee
+ *
+ **/
+/*****************************************************************************/
+
+#ifndef FAC_SPARSE_HENSEL_H
+#define FAC_SPARSE_HENSEL_H
+
+#include "canonicalform.h"
+#include "cf_map_ext.h"
+#include "cf_iter.h"
+#include "templates/ftmpl_functions.h"
+#include "cf_algorithm.h"
+#include "cf_map.h"
+
+/// compare polynomials
+inline
+int comp (const CanonicalForm& A, const CanonicalForm& B)
+{
+  if (A.inCoeffDomain() && !B.inCoeffDomain())
+    return -1;
+  else if (!A.inCoeffDomain() && B.inCoeffDomain())
+    return 1;
+  else if (A.inCoeffDomain() && B.inCoeffDomain())
+    return 0;
+  else if (degree (A, 1) > degree (B, 1))
+    return 1;
+  else if (degree (A, 1) < degree (B, 1))
+    return -1;
+  // here A and B are not in CoeffDomain
+  int n= tmax (A.level(), B.level());
+  for (int i= 2; i <= n; i++)
+  {
+    if (degree (A,i) > degree (B,i))
+      return 1;
+    else if (degree (A,i) < degree (B,i))
+      return -1;
+  }
+  return 0;
+}
+
+/// compare two polynomials up to level @a level
+inline
+int comp (const CanonicalForm& A, const CanonicalForm& B, int level)
+{
+  if (A.inCoeffDomain() && !B.inCoeffDomain() && B.level() <= level)
+    return -1;
+  else if (!A.inCoeffDomain() && A.level() <= level && B.inCoeffDomain())
+    return 1;
+  else if (A.inCoeffDomain() && B.inCoeffDomain())
+    return 0;
+  else if (degree (A, 1) > degree (B, 1))
+    return 1;
+  else if (degree (A, 1) < degree (B, 1))
+    return -1;
+  // here A and B are not in coeffdomain
+  for (int i= 2; i <= level; i++)
+  {
+    if (degree (A,i) > degree (B,i))
+      return 1;
+    else if (degree (A,i) < degree (B,i))
+      return -1;
+  }
+  return 0;
+}
+
+/// swap entry @a i and @a j in @a A
+inline
+void swap (CFArray& A, int i, int j)
+{
+  CanonicalForm tmp= A[i];
+  A[i]= A[j];
+  A[j]= tmp;
+}
+
+/// quick sort helper function
+inline
+void quickSort (int lo, int hi, CFArray& A, int l)
+{
+  int i= lo, j= hi;
+  CanonicalForm tmp= A[(lo+hi)/2];
+  while (i <= j)
+  {
+    if (l > 0)
+    {
+      while (comp (A [i], tmp, l) < 0 && i < hi) i++;
+      while (comp (tmp, A[j], l) < 0 && j > lo) j--;
+    }
+    else
+    {
+      while (comp (A [i], tmp) < 0 && i < hi) i++;
+      while (comp (tmp, A[j]) < 0 && j > lo) j--;
+    }
+    if (i <= j)
+    {
+      swap (A, i, j);
+      i++;
+      j--;
+    }
+  }
+  if (lo < j) quickSort (lo, j, A, l);
+  if (i < hi) quickSort (i, hi, A, l);
+}
+
+/// quick sort @a A
+inline
+void sort (CFArray& A, int l= 0)
+{
+  quickSort (0, A.size() - 1, A, l);
+}
+
+
+/// find normalizing factors for @a biFactors and build monic univariate factors
+/// from @a biFactors
+inline CFList
+findNormalizingFactor1 (const CFList& biFactors, const CanonicalForm& evalPoint,
+                        CFList& uniFactors)
+{
+  CFList result;
+  CanonicalForm tmp;
+  for (CFListIterator i= biFactors; i.hasItem(); i++)
+  {
+    tmp= i.getItem() (evalPoint);
+    uniFactors.append (tmp /Lc (tmp));
+    result.append (Lc (tmp));
+  }
+  return result;
+}
+
+/// find normalizing factors for @a biFactors and sort @a biFactors s.t.
+/// the returned @a biFactors evaluated at evalPoint coincide with @a uniFactors
+inline CFList
+findNormalizingFactor2 (CFList& biFactors, const CanonicalForm& evalPoint,
+                        const CFList& uniFactors)
+{
+  CFList result;
+  CFList uniBiFactors= biFactors;
+  CFList newBiFactors;
+  CFList l;
+  int pos;
+  CFListIterator iter;
+  for (iter= uniBiFactors; iter.hasItem(); iter++)
+  {
+    iter.getItem()= iter.getItem() (evalPoint);
+    l.append (Lc (iter.getItem()));
+    iter.getItem() /= Lc (iter.getItem());
+  }
+  for (CFListIterator i= uniFactors; i.hasItem(); i++)
+  {
+    pos= findItem (uniBiFactors, i.getItem());
+    newBiFactors.append (getItem (biFactors, pos));
+    result.append (getItem (l, pos));
+  }
+  biFactors= newBiFactors;
+  return result;
+}
+
+/// get terms of @a F
+inline CFArray
+getTerms (const CanonicalForm& F)
+{
+  if (F.inCoeffDomain())
+  {
+    CFArray result= CFArray (1);
+    result [0]= F;
+    return result;
+  }
+  if (F.isUnivariate())
+  {
+    CFArray result= CFArray (size(F));
+    int j= 0;
+    for (CFIterator i= F; i.hasTerms(); i++, j++)
+      result[j]= i.coeff()*power (F.mvar(), i.exp());
+    return result;
+  }
+  int numMon= size (F);
+  CFArray result= CFArray (numMon);
+  int j= 0;
+  CFArray recResult;
+  Variable x= F.mvar();
+  CanonicalForm powX;
+  for (CFIterator i= F; i.hasTerms(); i++)
+  {
+    powX= power (x, i.exp());
+    recResult= getTerms (i.coeff());
+    for (int k= 0; k < recResult.size(); k++)
+      result[j+k]= powX*recResult[k];
+    j += recResult.size();
+  }
+  return result;
+}
+
+/// helper function for getBiTerms
+inline CFArray
+getBiTerms_helper (const CanonicalForm& F, const CFMap& M, int threshold)
+{
+  CFArray buf= CFArray (size (F));
+  int k= 0, level= F.level() - 1;
+  Variable x= F.mvar();
+  Variable y= Variable (F.level() - 1);
+  Variable one= Variable (1);
+  Variable two= Variable (2);
+  CFIterator j;
+  for (CFIterator i= F; i.hasTerms(); i++)
+  {
+    if (i.coeff().level() < level)
+    {
+      buf[k]= M (i.coeff())*power (one,i.exp());
+      k++;
+      if (k > threshold)
+        break;
+      continue;
+    }
+    j= i.coeff();
+    for (;j.hasTerms() && k <= threshold; j++, k++)
+      buf[k]= power (one,i.exp())*power (two,j.exp())*M (j.coeff());
+    if (k > threshold)
+      break;
+  }
+  CFArray result= CFArray (k);
+  for (int i= 0; i < k && k <= threshold; i++)
+    result[i]= buf[i];
+  return result;
+}
+
+/// get terms of @a F where F is considered a bivariate poly in Variable(1),
+/// Variable (2)
+inline CFArray
+getBiTerms (const CanonicalForm& F, int threshold)
+{
+  if (F.inCoeffDomain())
+  {
+    CFArray result= CFArray (1);
+    result [0]= F;
+    return result;
+  }
+  if (F.isUnivariate())
+  {
+    CFArray result= CFArray (size(F));
+    int j= 0;
+    for (CFIterator i= F; i.hasTerms(); i++, j++)
+      result[j]= i.coeff()*power (F.mvar(), i.exp());
+    return result;
+  }
+
+  CanonicalForm G= F;
+
+  CFMap M;
+  M.newpair (Variable (1), F.mvar());
+  M.newpair (Variable (2), Variable (F.level() - 1));
+  G= swapvar (F, Variable (1), F.mvar());
+  G= swapvar (G, Variable (2), Variable (F.level() - 1));
+
+  CFArray result= getBiTerms_helper (G, M, threshold);
+  return result;
+}
+
+/// build a poly from entries in @a A
+inline CanonicalForm
+buildPolyFromArray (const CFArray& A)
+{
+  CanonicalForm result= 0;
+  for (int i= A.size() - 1; i > -1; i--)
+    result += A[i];
+  return result;
+}
+
+/// group together elements in @a A, where entries in @a A are put together
+/// if they coincide up to level @a level
+inline void
+groupTogether (CFArray& A, int level)
+{
+  int n= A.size() - 1;
+  int k= A.size();
+  for (int i= 0; i < n; i++)
+  {
+    if (comp (A[i],A[i+1], level) == 0)
+    {
+      A[i+1] += A[i];
+      A[i]= 0;
+      k--;
+    }
+  }
+  if (A[n].isZero())
+    k--;
+  CFArray B= CFArray (k);
+  n++;
+  k= 0;
+  for (int i= 0; i < n; i++)
+  {
+    if (!A[i].isZero())
+    {
+      B[k]= A[i];
+      k++;
+    }
+  }
+  A= B;
+}
+
+/// strip off those parts of entries in @a F whose level is less than or equal
+/// than @a level and store the stripped off parts in @a G
+inline void
+strip (CFArray& F, CFArray& G, int level)
+{
+  int n, m, i, j;
+  CanonicalForm g;
+  m= F.size();
+  G= CFArray (m);
+  for (j= 0; j < m; j++)
+  {
+    g= 1;
+    for (i= 1; i <= level; i++)
+    {
+      if ((n= degree (F[j],i)) > 0)
+        g *= power (Variable (i), n);
+    }
+    F[j] /= g;
+    G[j]= g;
+  }
+}
+
+/// s.a. stripped off parts are not returned
+inline void
+strip (CFArray& F, int level)
+{
+  int n, m, i;
+  CanonicalForm g;
+  m= F.size();
+  for (int j= 0; j < m; j++)
+  {
+    g= 1;
+    for (i= 1; i <= level; i++)
+    {
+      if ((n= degree (F[j],i)) > 0)
+        g *= power (Variable (i), n);
+    }
+    F[j] /= g;
+  }
+}
+
+/// get equations for LucksWangSparseHeuristic
+inline
+CFArray getEquations (const CFArray& A, const CFArray& B)
+{
+  ASSERT (A.size() == B.size(), "size of A and B has to coincide");
+  CFArray result= CFArray (A.size());
+  int n= A.size();
+  for (int i= 0; i < n; i++)
+    result[i]= A[i]-B[i];
+  return result;
+}
+
+/// evaluate every entry of @a A at @a B and level @a level
+inline void
+evaluate (CFArray& A, const CanonicalForm& B, int level)
+{
+  int n= A.size();
+  for (int i= 0; i < n; i++)
+  {
+    if (A[i].level() < level)
+      continue;
+    else
+      A[i]= A[i] (B, level);
+  }
+}
+
+/// evaluate every entry of @a A at every entry of @a B starting at level @a
+/// level
+inline void
+evaluate (CFArray& A, const CFArray& B, int level)
+{
+  int n= B.size();
+  for (int i= 0; i < n; i++)
+  {
+    if (!B[i].isZero())
+      evaluate (A, B[i], level + i);
+  }
+}
+
+/// simplify @a A if possible, i.e. @a A consists of 2 terms and contains only
+/// one variable of level greater or equal than @a level
+inline CanonicalForm
+simplify (const CanonicalForm& A, int level)
+{
+  CanonicalForm F= 0;
+  if (size (A, A.level()) == 2)
+  {
+    CanonicalForm C= getVars (A);
+    if ((C/C.mvar()).level() < level)
+    {
+      CanonicalForm B= LC (A);
+      if (B.level() < level)
+      {
+        CanonicalForm quot;
+        if (fdivides (B, A, quot))
+          F= -tailcoeff (quot);
+      }
+    }
+  }
+  return F;
+}
+
+///  if possible simplify @a A as described above and store result in @a B
+inline bool
+simplify (CFArray& A, CFArray& B, int level)
+{
+  int n= A.size();
+  CanonicalForm f;
+  int index;
+  for (int i= 0; i < n; i++)
+  {
+    if (!A[i].isZero())
+    {
+      f= simplify (A[i], level);
+      if (!f.isZero())
+      {
+        index= A[i].level() - level;
+        if (index < 0 || index >= B.size())
+          return false;
+        if (!B[index].isZero() && B[index] != f)
+          return false;
+        else if (B[index].isZero())
+        {
+          B[index]= f;
+          A[i]= 0;
+        }
+      }
+    }
+  }
+  return true;
+}
+
+/// merge @a B into @a A if possible, i.e. every non-zero entry in @a A should
+/// be zero in @a B
+inline bool
+merge (CFArray& A, CFArray& B)
+{
+  if (A.size() != B.size())
+    return false;
+  int n= A.size();
+  for (int i= 0; i < n; i++)
+  {
+    if (!B[i].isZero())
+    {
+      if (A[i].isZero())
+      {
+        A[i]= B[i];
+        B[i]= 0;
+      }
+      else if (A[i] == B[i])
+        B[i]= 0;
+      else
+        return false;
+    }
+  }
+  return true;
+}
+
+/// checks if entries of @a A are zero
+inline bool
+isZero (const CFArray& A)
+{
+  int n= A.size();
+  for (int i= 0; i < n; i++)
+    if (!A[i].isZero())
+      return false;
+  return true;
+}
+
+/// checks if @a A equals @a B
+inline bool
+isEqual (const CFArray& A, const CFArray& B)
+{
+  if (A.size() != B.size())
+    return false;
+  int i, n= B.size();
+  for (i= 0; i < n; i++)
+    if (A[i] != B[i])
+      return false;
+  return true;
+}
+
+/// get terms of @a F wrt. Variable (1)
+inline CFArray
+getTerms2 (const CanonicalForm& F)
+{
+  if (F.inCoeffDomain())
+  {
+    CFArray result= CFArray (1);
+    result[0]= F;
+    return result;
+  }
+  CFArray result= CFArray (size (F));
+  int j= 0;
+  Variable x= F.mvar();
+  Variable y= Variable (1);
+  CFIterator k;
+  for (CFIterator i= F; i.hasTerms(); i++)
+  {
+    if (i.coeff().inCoeffDomain())
+    {
+      result[j]= i.coeff()*power (x,i.exp());
+      j++;
+    }
+    else
+    {
+      for (k= i.coeff(); k.hasTerms(); k++, j++)
+        result[j]= k.coeff()*power (x,i.exp())*power (y,k.exp());
+    }
+  }
+  sort (result);
+  return result;
+}
+
+/// get terms of entries in @a F and put them in @a result
+inline
+void getTerms2 (const CFList& F, CFArray* result)
+{
+  int j= 0;
+  for (CFListIterator i= F; i.hasItem(); i++, j++)
+    result[j]= getTerms2 (i.getItem());
+}
+
+/// evaluate entries in @a A at @a eval and @a y
+inline CFArray
+evaluate (const CFArray& A, const CanonicalForm& eval, const Variable& y)
+{
+  int j= A.size();
+  CFArray result= CFArray (j);
+  for (int i= 0; i < j; i++)
+    result [i]= A[i] (eval, y);
+  return result;
+}
+
+/// s.a.
+inline CFArray*
+evaluate (CFArray* const& A, int sizeA, const CanonicalForm& eval,
+          const Variable& y)
+{
+  CFArray* result= new CFArray [sizeA];
+  for (int i= 0; i < sizeA; i++)
+    result[i]= evaluate (A[i], eval, y);
+  return result;
+}
+
+/// normalize entries in @a L with @a normalizingFactor
+inline
+CFList normalize (const CFList& L, const CFList& normalizingFactor)
+{
+  CFList result;
+  CFListIterator j= normalizingFactor;
+  for (CFListIterator i= L; i.hasItem(); i++, j++)
+    result.append (i.getItem() / j.getItem());
+  return result;
+}
+
+/// search for @a F in @a A between index @a i and @a j
+inline
+int search (const CFArray& A, const CanonicalForm& F, int i, int j)
+{
+  for (; i < j; i++)
+    if (A[i] == F)
+      return i;
+  return -1;
+}
+
+/// patch together @a F1 and @a F2 and normalize by a power of @a eval
+/// @a F1 and @a F2 are assumed to be bivariate with one variable having level 1
+inline
+CanonicalForm patch (const CanonicalForm& F1, const CanonicalForm& F2,
+                     const CanonicalForm& eval)
+{
+  CanonicalForm result= F1;
+  if (F2.level() != 1 && !F2.inCoeffDomain())
+  {
+    int d= degree (F2);
+    result *= power (F2.mvar(), d);
+    result /= power (eval, d);
+  }
+  return result;
+}
+
+/// sparse heuristic lifting by Wang and Lucks
+///
+/// @return @a LucksWangSparseHeuristic returns true if it was successful
+int
+LucksWangSparseHeuristic (const CanonicalForm& F,     ///<[in] polynomial to be
+                                                      ///< factored
+                          const CFList& factors,      ///<[in] factors of F
+                                                      ///< lifted to level
+                          int level,                  ///<[in] level of lifted
+                                                      ///< factors
+                          const CFList& leadingCoeffs,///<[in] leading
+                                                      ///< coefficients of
+                                                      ///< factors
+                          CFList& result              ///<[in,out] result
+                         );
+
+/// sparse heuristic which patches together bivariate factors of @a A wrt.
+/// different second variables by their univariate images
+///
+/// @return @a sparseHeuristic returns a list of found factors of A
+CFList
+sparseHeuristic (const CanonicalForm& A,  ///<[in] polynomial to be factored
+                 const CFList& biFactors, ///<[in] bivariate factors of A where
+                                          ///< the second variable has level 2
+                 CFList*& moreBiFactors,  ///<[in] more bivariate factorizations
+                                          ///< wrt. different second variables
+                 const CFList& evaluation,///<[in] evaluation point
+                 int minFactorsLength     ///<[in] minimal length of bivariate
+                                          ///< factorizations
+                );
+
+#endif
diff --git a/factory/fac_sqrfree.cc b/factory/fac_sqrfree.cc
new file mode 100644
index 0000000..9d475a3
--- /dev/null
+++ b/factory/fac_sqrfree.cc
@@ -0,0 +1,151 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+
+#include "config.h"
+
+
+#include "cf_assert.h"
+
+#include "cf_defs.h"
+#include "canonicalform.h"
+#include "cf_map.h"
+#include "cf_algorithm.h"
+
+static int
+compareFactors( const CFFactor & f, const CFFactor & g )
+{
+    return f.exp() > g.exp();
+}
+
+CFFList
+sortCFFList( CFFList & F )
+{
+    F.sort( compareFactors );
+
+    int exp;
+    CanonicalForm f;
+    CFFListIterator I = F;
+    CFFList result;
+
+    // join elements with the same degree
+    while ( I.hasItem() ) {
+        f = I.getItem().factor();
+        exp = I.getItem().exp();
+        I++;
+        while ( I.hasItem() && I.getItem().exp() == exp ) {
+            f *= I.getItem().factor();
+            I++;
+        }
+        result.append( CFFactor( f, exp ) );
+    }
+
+    return result;
+}
+
+CFFList sqrFreeZ ( const CanonicalForm & a )
+{
+    if ( a.inCoeffDomain() )
+        return CFFactor( a, 1 );
+    CanonicalForm aa, LcA;
+    if (isOn (SW_RATIONAL))
+    {
+      LcA= bCommonDen (a);
+      aa= a*LcA;
+    }
+    else
+    {
+      LcA= icontent (a);
+      if (lc (a).sign() < 0)
+        LcA= -LcA;
+      aa= a/LcA;
+    }
+    CanonicalForm cont = content( aa );
+    aa /= cont;
+    CanonicalForm b = aa.deriv(), c = gcd( aa, b );
+    CanonicalForm y, z, w = aa / c;
+    int i = 1;
+    CFFList F;
+    Variable v = aa.mvar();
+    CanonicalForm lcinv;
+    while ( c.degree(v) != 0 )
+    {
+        y = gcd( w, c ); z = w / y;
+        if ( degree( z, v ) > 0 )
+        {
+          if (isOn (SW_RATIONAL))
+          {
+            lcinv= 1/Lc (z);
+            z *= lcinv;
+            z *= bCommonDen (z);
+          }
+          if (lc (z).sign() < 0)
+            z= -z;
+          F.append( CFFactor( z, i ) );
+        }
+        i++;
+        w = y; c = c / y;
+    }
+    if ( degree( w,v ) > 0 )
+    {
+      if (isOn (SW_RATIONAL))
+      {
+        lcinv= 1/Lc (w);
+        w *= lcinv;
+        w *= bCommonDen (w);
+      }
+      if (lc (w).sign() < 0)
+        w= -w;
+      F.append( CFFactor( w, i ) );
+    }
+    if ( ! cont.isOne() )
+    {
+        CFFList buf= sqrFreeZ (cont);
+        buf.removeFirst();
+        F = Union( F, buf );
+    }
+    F.insert (CFFactor (LcA, 1));
+    return F;
+}
+
+CanonicalForm
+sqrfPart (const CanonicalForm& F)
+{
+  if (F.inCoeffDomain())
+    return F;
+  CFMap M;
+  CanonicalForm A= compress (F, M);
+  CanonicalForm w, v, b;
+  CanonicalForm result;
+  int i= 1;
+  for (; i <= A.level(); i++)
+  {
+    if (!deriv (A, Variable (i)).isZero())
+      break;
+  }
+
+  w= gcd (A, deriv (A, Variable (i)));
+  b= A/w;
+  result= b;
+  if (degree (w) < 1)
+    return M (result);
+  i++;
+  for (; i <= A.level(); i++)
+  {
+    if (!deriv (w, Variable (i)).isZero())
+    {
+      b= w;
+      w= gcd (w, deriv (w, Variable (i)));
+      b /= w;
+      if (degree (b) < 1)
+        break;
+      CanonicalForm g= gcd (b, result);
+      if (degree (g) > 0)
+        result *= b/g;
+      if (degree (g) <= 0)
+        result *= b;
+    }
+  }
+  result= M (result);
+  return result;
+}
+
diff --git a/factory/fac_sqrfree.h b/factory/fac_sqrfree.h
new file mode 100644
index 0000000..69c0b11
--- /dev/null
+++ b/factory/fac_sqrfree.h
@@ -0,0 +1,24 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+/**
+ * @file fac_sqrfree.h
+ *
+ * squarefree part and factorization over Q, Q(a)
+**/
+
+#ifndef INCL_FAC_SQRFREE_H
+#define INCL_FAC_SQRFREE_H
+
+// #include "config.h"
+
+#include "canonicalform.h"
+
+CFFList sortCFFList ( CFFList & F );
+
+CFFList sqrFreeZ ( const CanonicalForm & f );
+
+/// squarefree part of a poly
+CanonicalForm sqrfPart (const CanonicalForm& F ///<[in] some poly
+                       );
+
+#endif /* ! INCL_FAC_SQRFREE_H */
diff --git a/factory/fac_util.cc b/factory/fac_util.cc
new file mode 100644
index 0000000..a767d34
--- /dev/null
+++ b/factory/fac_util.cc
@@ -0,0 +1,112 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+
+#include "config.h"
+
+
+#include "cf_assert.h"
+
+#include "cf_defs.h"
+#include "canonicalform.h"
+#include "cf_iter.h"
+#include "fac_util.h"
+
+static CanonicalForm PK, PKHALF;
+
+static CanonicalForm mappk ( const CanonicalForm& );
+
+static CanonicalForm mappksymmetric ( const CanonicalForm& );
+
+
+modpk::modpk()
+{
+    p = 0;
+    k = 0;
+    pk = 1;
+    pkhalf = 0;
+}
+
+modpk::modpk( int q, int l )
+{
+    p = q;
+    k = l;
+    pk = power( CanonicalForm( p ), k );
+    pkhalf = pk / 2;
+}
+
+modpk::modpk( const modpk & m )
+{
+    p = m.p;
+    k = m.k;
+    pk = m.pk;
+    pkhalf = m.pkhalf;
+}
+
+modpk&
+modpk::operator= ( const modpk & m )
+{
+    if ( this != &m ) {
+        p = m.p;
+        k = m.k;
+        pk = m.pk;
+        pkhalf = m.pkhalf;
+    }
+    return *this;
+}
+
+CanonicalForm
+modpk::inverse( const CanonicalForm & f, bool symmetric ) const
+{
+    CanonicalForm u, r0 = this->operator()( f, false ), r1 = pk, q0 = 1, q1 = 0;
+    while ( ( r0 > 0 ) && ( r1 > 0 ) ) {
+        u = r0 / r1;
+        r0 = r0 % r1;
+        q0 = u*q1 + q0;
+        if ( r0 > 0 ) {
+            u = r1 / r0;
+            r1 = r1 % r0;
+            q1 = u*q0 + q1;
+        }
+    }
+    if ( r0 == 0 )
+        return this->operator()( pk-q1, symmetric );
+    else
+        return this->operator()( q0, symmetric );
+}
+
+CanonicalForm
+modpk::operator() ( const CanonicalForm & f, bool symmetric ) const
+{
+    PKHALF = pkhalf;
+    PK = pk;
+    if ( symmetric )
+        return mapdomain( f, mappksymmetric );
+    else
+        return mapdomain( f, mappk );
+}
+
+CanonicalForm
+replaceLc( const CanonicalForm & f, const CanonicalForm & c )
+{
+    if ( f.inCoeffDomain() )
+        return c;
+    else
+        return f + ( c - LC( f ) ) * power( f.mvar(), degree( f ) );
+}
+
+CanonicalForm
+mappksymmetric ( const CanonicalForm & f )
+{
+    CanonicalForm result = mod( f, PK );
+    if ( result > PKHALF )
+        return result - PK;
+    else
+        return result;
+}
+
+CanonicalForm
+mappk ( const CanonicalForm & f )
+{
+    return mod( f, PK );
+}
+
diff --git a/factory/fac_util.h b/factory/fac_util.h
new file mode 100644
index 0000000..dd89f13
--- /dev/null
+++ b/factory/fac_util.h
@@ -0,0 +1,51 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+/**
+ * @file fac_util.h
+ *
+ * operations mod p^k and some other useful functions for factorization
+**/
+
+#ifndef INCL_FAC_UTIL_H
+#define INCL_FAC_UTIL_H
+
+// #include "config.h"
+
+#include "canonicalform.h"
+#include "cf_eval.h"
+
+/*BEGINPUBLIC*/
+
+/**
+ * class to do operations mod p^k for int's p and k
+**/
+class modpk
+{
+private:
+    CanonicalForm pk;
+    CanonicalForm pkhalf;
+    int p;
+    int k;
+public:
+    modpk();
+    modpk( int q, int l );
+    modpk( const modpk & m );
+    modpk& operator= ( const modpk& m );
+    ~modpk() {}
+    int getp() const { return p; }
+    int getk() const { return k; }
+    CanonicalForm inverse( const CanonicalForm & f, bool symmetric = true ) const;
+    CanonicalForm getpk() const { return pk; }
+    CanonicalForm operator() ( const CanonicalForm & f, bool symmetric = true ) const;
+};
+
+
+CanonicalForm replaceLc( const CanonicalForm & f, const CanonicalForm & c );
+
+/*ENDPUBLIC*/
+
+bool gcd_test_one ( const CanonicalForm & f, const CanonicalForm & g, bool swap, int & d );
+
+void extgcd ( const CanonicalForm & a, const CanonicalForm & b, CanonicalForm & S, CanonicalForm & T, const modpk & pk );
+
+#endif /* ! INCL_FAC_UTIL_H */
diff --git a/factory/factory.pc.in b/factory/factory.pc.in
new file mode 100644
index 0000000..2f27285
--- /dev/null
+++ b/factory/factory.pc.in
@@ -0,0 +1,17 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: @PACKAGE@
+Description: The Singular factorization library
+Version: @PACKAGE_VERSION@
+URL: https://github.com/Singular/Sources/tree/spielwiese/@PACKAGE@
+
+Requires: @PKG_REQUIRE@
+Conflicts:
+
+Cflags: -I${includedir} @SINGULAR_CFLAGS@ @FLINT_CFLAGS@ @NTL_CFLAGS@ @GMP_CFLAGS@
+Libs: -L${libdir} -l at PACKAGE@ @FLINT_LIBS@ @NTL_LIBS@ @GMP_LIBS@
+Libs.private:
+
diff --git a/factory/factory.template b/factory/factory.template
new file mode 100644
index 0000000..ab68834
--- /dev/null
+++ b/factory/factory.template
@@ -0,0 +1,124 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+#ifndef INCL_FACTORY_H
+#define INCL_FACTORY_H
+
+/* factory.template is a template to generate `factory.h' */
+
+/**
+ *
+ * @file factory.h
+ *
+ * `factory.h' is the user interface to Factory.  Created
+ * automatically by `makeheader', it collects all important
+ * declarations from all important Factory header files into one
+ * overall header file leaving out all boring Factory internal
+ * stuff.  See `./bin/makeheader' for an explanation of the syntax
+ * of this file.
+ *
+ * Note: In this file the order of "includes" matters (since this
+ * are not real includes)!  In general, files at the end depend
+ * on files at the beginning.
+ *
+**/
+
+#include <factory/factoryconf.h>
+#include <stdint.h>
+
+#ifndef NOSTREAMIO
+#  ifdef HAVE_IOSTREAM
+#    include <iostream>
+#    define OSTREAM std::ostream
+#    define ISTREAM std::istream
+#  elif defined(HAVE_IOSTREAM_H)
+#    include <iostream.h>
+#    define OSTREAM ostream
+#    define ISTREAM istream
+#  endif
+#endif /* ! NOSTREAMIO */
+
+#include <factory/cf_gmp.h>
+
+#include <factory/templates/ftmpl_array.h>
+#include <factory/templates/ftmpl_afactor.h>
+#include <factory/templates/ftmpl_factor.h>
+#include <factory/templates/ftmpl_list.h>
+#include <factory/templates/ftmpl_matrix.h>
+
+/*MAKEHEADER PUBLIC ONLY*/
+#include "cf_globals.h"
+
+/*MAKEHEADER PUBLIC ONLY*/
+#include "cf_primes.h"
+
+/*MAKEHEADER PUBLIC ONLY*/
+#include "cf_defs.h"
+
+/*MAKEHEADER PUBLIC ONLY*/
+#include "variable.h"
+
+/*MAKEHEADER PUBLIC ONLY*/
+#include "canonicalform.h"
+
+/*MAKEHEADER PUBLIC ONLY*/
+#include "cf_algorithm.h"
+
+/*MAKEHEADER PUBLIC ONLY*/
+#include "cf_eval.h"
+
+/*MAKEHEADER PUBLIC ONLY*/
+#include "cf_generator.h"
+
+/*MAKEHEADER PUBLIC ONLY*/
+#include "cf_iter.h"
+
+/*MAKEHEADER PUBLIC ONLY*/
+#include "cf_random.h"
+
+/*MAKEHEADER PUBLIC ONLY*/
+#include "fac_util.h"
+
+/*MAKEHEADER PUBLIC ONLY*/
+#include "cf_map.h"
+
+/*MAKEHEADER PUBLIC ONLY*/
+#include "cf_reval.h"
+
+/*MAKEHEADER PUBLIC ONLY*/
+#include "fac_sqrfree.h"
+
+/*MAKEHEADER PUBLIC ONLY*/
+#include "gfops.h"
+
+/*MAKEHEADER PUBLIC ONLY*/
+#include "cf_hnf.h"
+
+/*MAKEHEADER PUBLIC ONLY*/
+#include "singext.h"
+
+/*MAKEHEADER PUBLIC ONLY*/
+#include "cf_util.h"
+
+/*MAKEHEADER PUBLIC ONLY*/
+#include "facIrredTest.h"
+
+/*MAKEHEADER PUBLIC ONLY*/
+#include "facAbsFact.h"
+
+/*MAKEHEADER PUBLIC ONLY*/
+#include "cfModResultant.h"
+
+/*MAKEHEADER PUBLIC ONLY*/
+#include "facAlgFunc.h"
+
+/*MAKEHEADER PUBLIC ONLY*/
+#include "cfCharSetsUtil.h"
+
+/*MAKEHEADER PUBLIC ONLY*/
+#include "cfCharSets.h"
+
+/*MAKEHEADER PUBLIC ONLY*/
+#include "cfUnivarGcd.h"
+
+
+#endif /* ! INCL_FACTORY_H */
diff --git a/factory/factoryconf.template b/factory/factoryconf.template
new file mode 100644
index 0000000..54243c0
--- /dev/null
+++ b/factory/factoryconf.template
@@ -0,0 +1,27 @@
+/* emacs edit mode for this file is -*- C -*- */
+
+#ifndef INCL_FACTORYCONF_H
+#define INCL_FACTORYCONF_H
+
+/* template to generate `factoryconf.h'. */
+
+/**
+ *
+ * @file factoryconf.h
+ *
+ * `factoryconf.h' serves as a configuration file for the
+ * installed source files (templates and `factory.h') the same
+ * way as `config.h' serves as a configuration file for the
+ * source files from which the library is build.  Additionally,
+ * we paste a copy of our `cf_assert.h' into this file which is
+ * necessary for the templates to translate.
+ *
+**/
+
+/*MAKEHEADER*/
+#include "config.h"
+
+/*MAKEHEADER*/
+#include "cf_assert.h"
+
+#endif /* ! INCL_FACTORYCONF_H */
diff --git a/factory/ffops.cc b/factory/ffops.cc
new file mode 100644
index 0000000..5d00e8d
--- /dev/null
+++ b/factory/ffops.cc
@@ -0,0 +1,107 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+
+#include "config.h"
+
+
+#include <string.h>
+
+#include "cf_assert.h"
+
+#include "cf_defs.h"
+#include "ffops.h"
+
+int ff_prime = 0;
+int ff_halfprime = 0;
+bool ff_big = false;
+short * ff_invtab = new short [32767];
+
+void ff_setprime ( const int p )
+{
+    if ( p != ff_prime ) {
+        ff_prime = p;
+        ff_halfprime = ff_prime / 2;
+        if ( ! ff_big )
+            memset( ff_invtab, 0, ff_prime*sizeof(short) );
+    }
+}
+
+int ff_newinv ( const int a )
+{
+    int p, q, r1, r2, y1, y2;
+    if (a < 2)
+          return (ff_invtab[a] = a);
+    r1 = p = ff_prime;
+    q = r1 / a;
+    y1 = -q;
+    r1 -= a * q;
+    if (r1 == 1)
+    {
+      y1 += p;
+      ff_invtab[y1] = a;
+      return (ff_invtab[a] = y1);
+    }
+    r2 = a;
+    y2 = 1;
+    for (;;)
+    {
+      q = r2 / r1;
+      y2 -= y1 * q;
+      r2 -= r1 * q;
+      if (r2 == 1)
+      {
+        if (y2 < 0)
+          y2 += p;
+        ff_invtab[y2] = a;
+        return (ff_invtab[a] = y2);
+      }
+      q = r1 / r2;
+      y1 -= y2 * q;
+      r1 -= r2 * q;
+      if (r1 == 1)
+      {
+        if (y1 < 0)
+          y1 += p;
+        ff_invtab[y1] = a;
+        return (ff_invtab[a] = y1);
+      }
+    }
+}
+
+int ff_biginv ( const int a )
+{
+    int p, q, r1, r2, y1, y2;
+    if (a < 2)
+      return a;
+    r1 = p = ff_prime;
+    q = r1 / a;
+    y1 = -q;
+    r1 -= a * q;
+    if (r1 == 1)
+      return p + y1;
+    r2 = a;
+    y2 = 1;
+    for (;;)
+    {
+      q = r2 / r1;
+      y2 -= y1 * q;
+      r2 -= r1 * q;
+      if (r2 == 1)
+      {
+        if (y2 > 0)
+          return y2;
+        else
+          return p + y2;
+      }
+      q = r1 / r2;
+      y1 -= y2 * q;
+      r1 -= r2 * q;
+      if (r1 == 1)
+      {
+        if (y1 > 0)
+          return y1;
+        else
+          return p + y1;
+      }
+    }
+}
diff --git a/factory/ffops.h b/factory/ffops.h
new file mode 100644
index 0000000..17d7d46
--- /dev/null
+++ b/factory/ffops.h
@@ -0,0 +1,168 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+/**
+ * @file ffops.h
+ *
+ * operations in a finite prime field F_p.
+ * The largest supported p is 536870909, i.e. the largest prime less than 2^29.
+ *
+**/
+
+#ifndef INCL_FFOPS_H
+#define INCL_FFOPS_H
+
+// #include "config.h"
+
+#include "cf_globals.h"
+#ifdef HAVE_NTL
+#include <NTL/config.h>
+#endif
+
+/* define type of your compilers 64 bit integer type */
+#ifndef FACTORY_INT64
+#define FACTORY_INT64 long long int
+#endif
+
+extern int ff_prime;
+extern int ff_halfprime;
+extern short * ff_invtab;
+extern bool ff_big;
+
+int ff_newinv ( const int );
+int ff_biginv ( const int );
+void ff_setprime ( const int );
+
+inline int ff_norm ( const int a )
+{
+    int n = a % ff_prime;
+#if defined(i386) || defined(NTL_AVOID_BRANCHING)
+    n += (n >> 31) & ff_prime;
+    return n;
+#else
+    if (n < 0) n += ff_prime;
+    return n;
+#endif
+}
+
+inline long ff_norm ( const long a )
+{
+    long n = a % ff_prime;
+#if defined(i386) || defined(NTL_AVOID_BRANCHING)
+    n += (n >> 31) & ff_prime;
+    return n;
+#else
+    if (n < 0) n += ff_prime;
+    return n;
+#endif
+}
+
+inline int ff_symmetric( const int a )
+{
+    if ( cf_glob_switches.isOn( SW_SYMMETRIC_FF ) )
+        return ( a > ff_halfprime ) ? a - ff_prime : a;
+    else
+        return a;
+}
+
+inline long ff_symmetric( const long a )
+{
+    if ( cf_glob_switches.isOn( SW_SYMMETRIC_FF ) )
+        return ( a > ff_halfprime ) ? a - ff_prime : a;
+    else
+        return a;
+}
+
+inline int ff_longnorm ( const long a )
+{
+    int n = (int)(a % (long)ff_prime);
+#if defined(i386) || defined(NTL_AVOID_BRANCHING)
+    n += (n >> 31) & ff_prime;
+    return n;
+#else
+    if (n < 0) n += ff_prime;
+    return n;
+#endif
+}
+
+inline int ff_bignorm ( const FACTORY_INT64 a )
+{
+    int n = (int)(a % (FACTORY_INT64)ff_prime);
+#if defined(i386) || defined(NTL_AVOID_BRANCHING)
+    n += (n >> 31) & ff_prime;
+    return n;
+#else
+    if (n < 0) n += ff_prime;
+    return n;
+#endif
+}
+
+inline int ff_add ( const int a, const int b )
+{
+    //return ff_norm( a + b );
+#if defined(i386) || defined(NTL_AVOID_BRANCHING)
+    int r=( a + b );
+    r -= ff_prime;
+    r += (r >> 31) & ff_prime;
+    return r;
+#else
+    int r=( a + b );
+    if (r >= ff_prime) r -= ff_prime;
+    return r;
+#endif
+}
+
+inline int ff_sub ( const int a, const int b )
+{
+    //return ff_norm( a - b );
+#if defined(i386) || defined(NTL_AVOID_BRANCHING)
+    int r=( a - b );
+    r += (r >> 31) & ff_prime;
+    return r;
+#else
+    int r=( a - b );
+    if (r < 0) r += ff_prime;
+    return r;
+#endif
+}
+
+inline int ff_neg ( const int a )
+{
+    //return ff_norm( -a );
+// EXPERIMENT
+#if defined(i386) || defined(NTL_AVOID_BRANCHING)
+    int r= -a;
+    r += (r >> 31) & ff_prime;
+    return r;
+#else
+    return ( a == 0 ? 0 : ff_prime-a );
+#endif
+}
+
+inline int ff_mul ( const int a, const int b )
+{
+    if ( ff_big )
+        return ff_bignorm( (FACTORY_INT64)a * (FACTORY_INT64)b );
+    else
+        return ff_longnorm ( (long)a * (long)b );
+}
+
+inline int ff_inv ( const int a )
+{
+    if ( ff_big )
+        return ff_biginv( a );
+    else {
+        register int b;
+        if ( (b = (int)(ff_invtab[a])) )
+            return b;
+        else
+            return ff_newinv( a );
+    }
+
+}
+
+inline int ff_div ( const int a, const int b )
+{
+    return ff_mul( a, ff_inv( b ) );
+}
+
+#endif /* ! INCL_FFOPS_H */
diff --git a/factory/ftmpl_inst.cc b/factory/ftmpl_inst.cc
new file mode 100644
index 0000000..dab7c9d
--- /dev/null
+++ b/factory/ftmpl_inst.cc
@@ -0,0 +1,164 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+/**
+ *
+ * @file ftmpl_inst.cc
+ *
+ * Factory's template instantiations.
+ *
+ * For a detailed description how to instantiate Factory's
+ * template classes and functions and how to add new
+ * instantiations see the `README' file.
+ *
+**/
+
+
+#include "config.h"
+
+
+// #include <factory/factoryconf.h>
+// #include "factory.h"
+#include "cf_iter.h"
+#include "canonicalform.h"
+#include "cf_assert.h"
+#include "cf_reval.h"
+#include "cf_map.h"
+
+
+#include "templates/ftmpl_array.cc"
+#include "templates/ftmpl_afactor.cc"
+#include "templates/ftmpl_factor.cc"
+#include "templates/ftmpl_list.cc"
+#include "templates/ftmpl_functions.h"
+#include "templates/ftmpl_matrix.cc"
+
+
+/** explicit template class instantiations **/
+template class Factor<CanonicalForm>;
+template class List<CFFactor>;
+template class ListItem<CFFactor>;
+template class ListIterator<CFFactor>;
+template class AFactor<CanonicalForm>;
+template class List<CFAFactor>;
+template class ListItem<CFAFactor>;
+template class ListIterator<CFAFactor>;
+template class List<CanonicalForm>;
+template class ListItem<CanonicalForm>;
+template class ListIterator<CanonicalForm>;
+template class Array<CanonicalForm>;
+template class List<MapPair>;
+template class ListItem<MapPair>;
+template class ListIterator<MapPair>;
+template class Matrix<CanonicalForm>;
+template class SubMatrix<CanonicalForm>;
+template class Array<REvaluation>;
+// libfac:
+template class Array<int>;
+template class Array<Variable>;
+template class List<Variable>;
+template class ListItem<Variable>;
+template class ListIterator<Variable> ;
+template class List<int>;
+template class ListItem<int>;
+template class ListIterator<int>;
+template class List< List<int> >;
+template class ListItem< List<int> >;
+template class ListIterator< List<int> >;
+template class List< List<CanonicalForm> >;
+template class ListItem< List<CanonicalForm> >;
+template class ListIterator< List<CanonicalForm> >;
+
+template List<Variable> Union ( const List<Variable>&, const List<Variable>& );
+template List<Variable> Difference ( const List<Variable>&, const List<Variable>& );
+
+// NTL 6
+#ifdef HAVE_NTL
+#include<NTL/version.h>
+#if NTL_MAJOR_VERSION == 6
+
+#include<NTL/tools.h>
+#include<NTL/lzz_pE.h>
+#include<NTL/lzz_pEX.h>
+#include<NTL/lzz_p.h>
+#include<NTL/vector.h>
+#include<NTL/pair.h>
+#include<NTL/GF2X.h>
+#include<NTL/GF2EX.h>
+#include<NTL/ZZ.h>
+#include<NTL/ZZX.h>
+#include<NTL/ZZ_pX.h>
+#include<NTL/vector.h>
+#ifdef NTL_CLIENT               // in <NTL/tools.h>: using of name space NTL
+NTL_CLIENT
+#endif
+template void BlockDestroy<zz_pE> (zz_pE*, long);
+template void BlockConstruct<zz_pE> (zz_pE*, long);
+template void BlockDestroy<Pair<zz_pEX, long> > (Pair<zz_pEX, long>*, long);
+template void BlockDestroy<Pair<GF2EX, long> > (Pair<GF2EX, long>*, long);
+template void BlockDestroy<Pair<ZZX, long> > (Pair<ZZX, long>*, long);
+template void BlockDestroy<Pair<ZZ_pX, long> > (Pair<ZZ_pX, long>*, long);
+template void BlockDestroy<Pair<GF2X, long> > (Pair<GF2X, long>*, long);
+template void BlockDestroy<Vec<zz_pE> > (Vec<zz_pE>*, long);
+template class Vec<zz_p>;
+template class Vec<Vec<zz_p> >;
+template class Vec<zz_pE>;
+template class Vec<ZZ>;
+template class Vec<Vec<ZZ> >;
+template class Mat<zz_p>;
+template class Mat<zz_pE>;
+template class Mat<ZZ>;
+template class Vec<Pair<zz_pEX, long> >;
+template class Vec<Pair<GF2EX, long> >;
+template class Vec<Pair<ZZX, long> >;
+template class Vec<Pair<ZZ_pX, long> >;
+template class Vec<Pair<GF2X, long> >;
+template class Vec<Vec<zz_pE> >;
+template void swap<zz_pE>(Vec<zz_pE>&, Vec<zz_pE>&);
+template long operator==<zz_p>(Vec<zz_p> const&, Vec<zz_p> const&);
+#endif
+#endif
+
+
+/** explicit template function instantiations **/
+#ifndef NOSTREAMIO
+template OSTREAM & operator << ( OSTREAM &, const List<CanonicalForm> & );
+template OSTREAM & operator << ( OSTREAM &, const List<CFFactor> & );
+template OSTREAM & operator << ( OSTREAM &, const List<MapPair> & );
+template OSTREAM & operator << ( OSTREAM &, const Array<CanonicalForm> & );
+template OSTREAM & operator << ( OSTREAM &, const Factor<CanonicalForm> & );
+template OSTREAM & operator << ( OSTREAM &, const Matrix<CanonicalForm> & );
+template OSTREAM & operator << ( OSTREAM &, const Array<REvaluation> & );
+//template OSTREAM & operator << ( OSTREAM &, const AFactor<CanonicalForm> & );
+#endif /* NOSTREAMIO */
+
+template int operator == ( const Factor<CanonicalForm> &, const Factor<CanonicalForm> & );
+template int operator == ( const AFactor<CanonicalForm> &, const AFactor<CanonicalForm> & );
+
+template List<CFFactor> Union ( const List<CFFactor> &, const List<CFFactor> & );
+template List<CFAFactor> Union ( const List<CFAFactor> &, const List<CFAFactor> & );
+
+#if ! defined(WINNT) || defined(__GNUC__)
+template CanonicalForm tmax ( const CanonicalForm &, const CanonicalForm & );
+template CanonicalForm tmin ( const CanonicalForm &, const CanonicalForm & );
+
+template Variable tmax ( const Variable &, const Variable & );
+template Variable tmin ( const Variable &, const Variable & );
+
+template int tmax ( const int &, const int & );
+template int tmin ( const int &, const int & );
+template int tabs ( const int & );
+#endif
+
+//
+template int operator== (const List<CanonicalForm> &, const List<CanonicalForm> &);
+template List<CanonicalForm> Union ( const List<CanonicalForm> &, const List<CanonicalForm> & );
+template List<CFList> Union ( const List<CFList>&, const List<CFList>&);
+template List<CanonicalForm> Difference ( const List<CanonicalForm> &, const List<CanonicalForm> & );
+template List<List<CanonicalForm> > Difference ( const List<List<CanonicalForm> >&, const List<List<CanonicalForm> >&);
+template List<List<CanonicalForm> > Difference ( const List<List<CanonicalForm> >&, const List<CanonicalForm>&);
+
+template CanonicalForm prod ( const List<CanonicalForm> & );
+template bool find ( const List<CanonicalForm> &, const CanonicalForm&);
+template bool find ( const List<List<CanonicalForm> >&, const List<CanonicalForm>&);
+// place here your own template stuff, not yet instantiated by factory
+//
diff --git a/factory/gengftables-conway.cc b/factory/gengftables-conway.cc
new file mode 100644
index 0000000..4408ab8
--- /dev/null
+++ b/factory/gengftables-conway.cc
@@ -0,0 +1,373 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+/**
+ *
+ * @file gengftables-conway.cc
+ *
+ * generate addition tables used by Factory
+ *   to calculate in GF(q).
+ *
+ * @note This may take quite a while ...
+ *
+**/
+
+
+#include "config.h"
+
+
+#ifdef HAVE_IOSTREAM
+#include <iostream>
+#include <fstream>
+#include <strstream>
+#include <string>
+#else
+#include <iostream.h>
+#include <fstream.h>
+#include <strstream.h>
+#include <string.h>
+#endif
+
+
+#include <stdlib.h>
+
+#include "cf_assert.h"
+#include "gf_tabutil.h"
+#include "cf_algorithm.h"
+#include "cf_iter.h"
+
+using namespace std;
+
+/**
+ *
+ * constants.
+ *
+ * maxtable: maximal size of a gf_table
+ *
+**/
+const int maxtable = 65536;
+
+/**
+ * primes, primes_len:
+ *   used to step through possible extensions
+**/
+const int primes_len = 54;
+
+/**
+ * primes, primes_len:
+ *   used to step through possible extensions
+**/
+static unsigned short primes [] =
+{
+      2,   3,   5,   7,  11,  13,  17,  19,
+     23,  29,  31,  37,  41,  43,  47,  53,
+     59,  61,  67,  71,  73,  79,  83,  89,
+     97, 101, 103, 107, 109, 113, 127, 131,
+    137, 139, 149, 151, 157, 163, 167, 173,
+    179, 181, 191, 193, 197, 199, 211, 223,
+        227, 229, 233, 239, 241, 251
+};
+
+/** bool isIrreducible ( const CanonicalForm & f )
+ *
+ * isIrreducible() - return true iff f is irreducible.
+ *
+**/
+bool
+isIrreducible ( const CanonicalForm & f )
+{
+    CFFList F = factorize( f );
+    if (F.getFirst().factor().inCoeffDomain())
+      F.removeFirst();
+    return F.length() == 1 && F.getFirst().exp() == 1;
+}
+
+/** int exponent ( const CanonicalForm & f, int q )
+ *
+ * exponent() - return e > 0 such that x^e == 1 mod f.
+ *
+ * q: upper limit for e (?)
+ *
+**/
+int
+exponent ( const CanonicalForm & f, int q )
+{
+    Variable x = f.mvar();
+    int e = 1;
+    CanonicalForm prod = x;
+    while ( e <= q && ! prod.isOne() ) {
+        e++;
+        prod = ( prod * x ) % f;
+    }
+    return e;
+}
+
+/** bool findGenRec ( int d, int n, int q, const CanonicalForm & m, const Variable & x, CanonicalForm & result )
+ *
+ * findGenRec() - find a generator of GF(q).
+ *
+ * Returns true iff result is a valid generator.
+ *
+ * d: degree of extension
+ * q: the q in GF(q) (q == p^d)
+ * x: generator should be a poly in x
+ * n, m: used to step recursively through all polys in FF(p)
+ *   Initially, n == d and m == 0.  If 0 <= n <= d we are
+ *   in the process of building m, if n < 0 we built m and
+ *   may test whether it generates GF(q).
+ * result: generator found
+ *
+ * i: used to step through GF(p)
+ * p: current characteristic
+ *
+**/
+bool
+findGenRec ( int d, int n, int q,
+             const CanonicalForm & m, const Variable & x,
+             CanonicalForm & result )
+{
+    int i, p = getCharacteristic();
+    if ( n < 0 ) {
+        cerr << "."; cerr.flush();
+        // check whether m is irreducible
+        if ( isIrreducible( m ) ) {
+            cerr << "*"; cerr.flush();
+            // check whether m generates multiplicative group
+            if ( exponent( m, q ) == q - 1 ) {
+                result = m;
+                return true;
+            }
+            else
+                return false;
+        }
+        else
+            return false;
+    }
+    // for each monomial x^0, ..., x^n, ..., x^d, try all possible coefficients
+    else  if ( n == d || n == 0 ) {
+        // we want to have a leading coefficient and a constant term,
+        // so start with coefficient >= 1
+        for ( i = 1; i < p; i++ )
+            if ( findGenRec( d, n-1, q, m + i * power( x, n ), x, result ) )
+                return true;
+    }
+    else {
+        for ( i = 0; i < p; i++ )
+            if ( findGenRec( d, n-1, q, m + i * power( x, n ), x, result ) )
+                return true;
+    }
+    return false;
+}
+
+/** CanonicalForm findGen ( int d, int q )
+ *
+ * findGen() - find and return a generator of GF(q).
+ *
+ * d: degree of extension
+ * q: the q in GF(q)
+ *
+**/
+CanonicalForm
+findGen ( int d, int q )
+{
+    Variable x( 1 );
+    CanonicalForm result;
+    cerr << "testing p = " << getCharacteristic() << ", d = " << d << " ... ";
+    cerr.flush();
+    bool ok = findGenRec( d, d, q, 0, x, result );
+    cerr << endl;
+    if ( ! ok )
+        return 0;
+    else
+        return result;
+}
+
+/** void printTable ( int d, int q, CanonicalForm mipo )
+ *
+ * printTable - print +1 table of field GF(q).
+ *
+ * d: degree of extension
+ * q: the q in GF(q)
+ * mipo: the minimal polynomial of the extension
+ *
+ * p: current characteristic
+ *
+**/
+void
+printTable ( int d, int q, CanonicalForm mipo )
+{
+    int i, p = getCharacteristic();
+
+    // open file to write to
+        ostrstream fname;
+    fname << "gftables/" << q << '\0';
+    char * fn = fname.str();
+    ofstream outfile;
+    outfile.open( fn, ios::out );
+    STICKYASSERT1( outfile, "can not open GF(q) table %s for writing", fn );
+    delete fn;
+
+    cerr << "mipo = " << mipo << ": ";
+    cerr << "generating multiplicative group ... ";
+    cerr.flush();
+
+    CanonicalForm * T = new CanonicalForm[maxtable];
+    Variable x( 1 );
+
+    // fill T with powers of x
+    T[0] = 1;
+    for ( i = 1; i < q; i++ )
+        T[i] = ( T[i-1] * x ) % mipo;
+
+    cerr << "generating addition table ... ";
+    cerr.flush();
+
+    // brute force method
+    int * table = new int[maxtable];
+    CanonicalForm f;
+
+    for ( i = 0; i < q; i++ ) {
+        f = T[i] + 1;
+        int j = 0;
+        while ( j < q && T[j] != f ) j++;
+        table[i] = j;
+    }
+
+    cerr << "writing table ... ";
+    cerr.flush();
+
+    outfile << "@@ factory GF(q) table @@" << endl;
+    outfile << p << " " << d << " " << mipo << "; ";
+
+    // print simple reprenstation of mipo
+    outfile << d;
+    CFIterator MiPo = mipo;
+    for ( i = d; MiPo.hasTerms(); i--, MiPo++ ) {
+        int exp;
+        for ( exp = MiPo.exp(); exp < i; i-- )
+            outfile << " 0";
+        outfile << " " << MiPo.coeff();
+    }
+    // since mipo is irreducible, it has a constant term,
+    // so i == 0 at this point
+    outfile << endl;
+
+    int m = gf_tab_numdigits62( q );
+    char * outstr = new char[30*m+1];
+    outstr[30*m] = '\0';
+    i = 1;
+    while ( i < q ) {
+        int k = 0;
+        char * sptr = outstr;
+        while ( i < q && k < 30 ) {
+            convert62( table[i], m, sptr );
+            sptr += m;
+            k++; i++;
+        }
+        while ( k < 30 ) {
+            convert62( 0, m, sptr );
+            sptr += m;
+            k++;
+        }
+        outfile << outstr << endl;
+    }
+    outfile.close();
+
+    delete [] outstr;
+    delete [] T;
+    delete [] table;
+
+    cerr << endl;
+}
+
+/**
+ * The new function for getting the minimal polynomials.
+ * It uses the Conway polynomials.
+ * It reads the polynomials from a file.
+ * The file contains all poynomials with p^k <= 2^16
+ * but currently only polynomials with p^k <= 2^14 are used.
+**/
+static CanonicalForm findGenNew(int n, ///< n is the exponent
+                                int q  ///< parameter q is not used. It is added to respect the old version
+                               )
+{
+        CanonicalForm conway = 0;
+        Variable x( 1 );
+        int p = getCharacteristic();
+        int ntmp,ptmp,pos1,pos2,ii;
+        string ns, ps;
+        string LineSe,coef,PC;
+        int flag=1;
+        ifstream in("./ConwayList.txt");
+        getline(in,LineSe); // For the first line
+
+        string err="END"; //to check if we are at the end of the file
+        while((flag) && (err != LineSe))
+        {
+                getline(in,LineSe); //for the line: allConwayPolynomials := [
+                if(LineSe == err){
+                        break;
+                }
+                pos1 = LineSe.find( ",", 0 );
+                pos2 = LineSe.find( ",", pos1 + 1);        // we check where are the "," to now p and n of this line
+                ps = LineSe.substr(0, pos1);
+                ns = LineSe.substr(pos1 + 1,pos2 - pos1);
+                ptmp = atoi(ps.c_str());                //we have the value of p and n of these line
+                ntmp = atoi(ns.c_str());
+
+        if((ntmp==n)&&(ptmp==p)){flag=0;}        // we check if they are our p and n to stop the search
+
+        }
+
+        if (err==LineSe) // If the Conway Polynomial is not in the list, there is an error.
+        {
+                //cout << "Error: This Conway polinomial is not in the list" << endl;
+                return(0);
+        }
+
+        // Read the polynomial from the file
+        pos1 = pos2 + 1;
+        pos2 = LineSe.find(",", pos1 + 1);
+        conway = atoi(LineSe.substr(pos1, pos2 - pos1).c_str()); // value of the constant term in PC=Conway Polynomial
+    pos1 = pos2;
+        pos2 = LineSe.find(",", pos1 + 1);
+
+        for(ii = 2; ii <= n; ii++)
+        {
+                coef = LineSe.substr(pos1 + 1,pos2 - pos1 - 1); //Coefficient of the monomial of degree ii-1
+        if(coef != "0")
+                {
+                        conway = conway + atoi(coef.c_str()) * power(x, ii - 1) ; //We add this monomial to the Conway Polynomial
+                }
+                pos1 = pos2;
+                pos2 = LineSe.find( ",", pos1+1);
+        }
+
+        pos2 = LineSe.find( ",END", pos1 + 1); // To obtain the last coefficient we search "END" instead of ","
+        coef = LineSe.substr(pos1 + 1,pos2 - pos1 - 1);
+        conway = conway + atoi(coef.c_str()) * power(x, ii - 1) ; //We add the last monomial to the Conway Polynomial
+
+        in.close();
+
+        return(conway);
+
+}
+
+
+int
+main()
+{
+    int i, p, q, n;
+    for ( i = 0; i < primes_len; i++ ) {
+                p = primes[i];
+                q = p*p;
+                n = 2;
+                setCharacteristic( p );
+                while ( q < maxtable ) {
+                        CanonicalForm f = findGenNew( n, q );
+                        ASSERT( f != 0, "no generator found" );
+                        printTable( n, q, f );
+                        n++; q *= p;
+                }
+    }
+}
+
diff --git a/factory/gf_tabutil.cc b/factory/gf_tabutil.cc
new file mode 100644
index 0000000..1b0ee14
--- /dev/null
+++ b/factory/gf_tabutil.cc
@@ -0,0 +1,56 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+
+#include "config.h"
+
+
+#include "cf_assert.h"
+
+#include "cf_defs.h"
+#include "gf_tabutil.h"
+
+int gf_tab_numdigits62 ( int q )
+{
+    if ( q < 62 )
+        return 1;
+    else  if ( q < 62*62 )
+        return 2;
+    else
+        return 3;
+}
+
+char conv62 ( int i )
+{
+    if ( i < 10 )
+        return '0' + char(i);
+    else  if ( i < 36 )
+        return 'A' + char(i-10);
+    else
+        return 'a' + char(i-36);
+}
+
+void convert62 ( int i, int n, char * p )
+{
+    for ( int j = n-1; j >= 0; j-- ) {
+        p[j] = conv62( i % 62 );
+        i /= 62;
+    }
+}
+
+int convback62 ( char c )
+{
+    if ( c >= '0' && c <= '9' )
+        return int(c) - int('0');
+    else  if ( c >= 'A' && c <= 'Z' )
+        return int(c) - int('A') + 10;
+    else
+        return int(c) - int('a') + 36;
+}
+
+int convertback62 ( char * p, int n )
+{
+    int r = 0;
+    for ( int j = 0; j < n; j++ )
+        r = r * 62 + convback62( p[j] );
+    return r;
+}
diff --git a/factory/gf_tabutil.h b/factory/gf_tabutil.h
new file mode 100644
index 0000000..c96e993
--- /dev/null
+++ b/factory/gf_tabutil.h
@@ -0,0 +1,24 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+#ifndef INCL_GF_TABUTIL_H
+#define INCL_GF_TABUTIL_H
+
+/**
+ * @file gf_tabutil.h
+ *
+ * utility functions to access GF Tables
+**/
+
+// #include "config.h"
+
+int gf_tab_numdigits62 ( int q );
+
+char conv62 ( int i );
+
+void convert62 ( int i, int n, char * p );
+
+int convback62 ( char c );
+
+int convertback62 ( char * p, int n );
+
+#endif /* ! INCL_GF_TABUTIL_H */
diff --git a/factory/gfops.cc b/factory/gfops.cc
new file mode 100644
index 0000000..7dbd2df
--- /dev/null
+++ b/factory/gfops.cc
@@ -0,0 +1,290 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+
+#include "config.h"
+
+
+#ifdef HAVE_CSTDIO
+#include <cstdio>
+#include <cstdlib>
+#else
+#include <stdio.h>
+#include <stdlib.h>
+#endif
+#include <string.h>
+
+#include "cf_assert.h"
+
+#include "cf_defs.h"
+#include "gf_tabutil.h"
+#include "cf_util.h"
+#include "canonicalform.h"
+#include "variable.h"
+#include "gfops.h"
+
+#ifdef SINGULAR
+#include "singext.h"
+#endif
+
+
+const int gf_maxtable = 63001;
+const int gf_maxbuffer = 200;
+
+const int gf_primes_len = 42;
+#ifndef NOASSERT
+static unsigned short gf_primes [] =
+{
+      2,   3,   5,   7,  11,  13,  17,  19,
+     23,  29,  31,  37,  41,  43,  47,  53,
+     59,  61,  67,  71,  73,  79,  83,  89,
+     97, 101, 103, 107, 109, 113, 127, 131,
+    137, 139, 149, 151, 157, 163, 167, 173,
+    179, 181, 191, 193, 197, 199, 223, 211,
+    227, 229, 233, 239, 241, 251
+};
+#endif
+
+int gf_q = 0;
+int gf_p = 0;
+int gf_n = 0;
+int gf_q1 = 0;
+int gf_m1 = 0;
+char gf_name = 'Z';
+
+unsigned short * gf_table = 0;
+
+CanonicalForm gf_mipo(0);
+
+static CanonicalForm intVec2CF ( int degree, int * coeffs, int level )
+{
+    int i;
+    CanonicalForm result;
+    for ( i = 0; i <= degree; i++ )
+    {
+        result += CanonicalForm( coeffs[ i ] ) * power( Variable( level ), degree - i );
+    }
+    return result;
+}
+
+static char *gftable_dir;
+extern "C" {
+  void set_gftable_dir(char *d){
+    gftable_dir = d;
+  }
+}
+
+static void gf_get_table ( int p, int n )
+{
+    char buffer[gf_maxbuffer];
+    int q = ipower( p, n );
+
+    // do not read the table a second time
+    if ( gf_q == q )
+    {
+        return;
+    }
+
+    if ( gf_table == 0 )
+        gf_table = new unsigned short[gf_maxtable];
+
+/*#ifdef SINGULAR
+    // just copy the table if Singular already read it
+    //printf("init_gf(gf_get_table) q=%d, nfCharQ=%d\n",q,nfCharQ);
+    if ( q == nfCharQ )
+    {
+        gf_p = p; gf_n = n;
+        gf_q = q; gf_q1 = q - 1;
+        gf_m1 = nfM1;
+        gf_mipo = intVec2CF( nfMinPoly[0], nfMinPoly + 1, 1 );
+        (void)memcpy( gf_table, nfPlus1Table, gf_q * sizeof( unsigned short ) );
+        gf_table[gf_q] = 0;
+        return;
+    }
+#endif*/
+
+    // try to open file
+    char *gffilename;
+    FILE * inputfile;
+    if (gftable_dir)
+    {
+      sprintf( buffer, "gftables/%d", q);
+      gffilename = (char *)malloc(strlen(gftable_dir) + strlen(buffer) + 1);
+      STICKYASSERT(gffilename,"out of memory");
+      strcpy(gffilename,gftable_dir);
+      strcat(gffilename,buffer);
+      inputfile = fopen( gffilename, "r" );
+    }
+    else
+    {
+#ifndef SINGULAR
+      sprintf( buffer, "gftables/%d", q );
+      gffilename = buffer;
+      inputfile = fopen( buffer, "r" );
+#else
+      sprintf( buffer, "gftables/%d", q );
+      gffilename = buffer;
+      inputfile = feFopen( buffer, "r" );
+#endif
+    }
+    if (!inputfile)
+    {
+      fprintf(stderr,"can not open GF(q) addition table: %s\n",gffilename);
+      STICKYASSERT(inputfile, "can not open GF(q) table");
+    }
+
+    // read ID
+    char * bufptr;
+    char * success;
+    success = fgets( buffer, gf_maxbuffer, inputfile );
+    STICKYASSERT( success, "illegal table (reading ID)" );
+    STICKYASSERT( strcmp( buffer, "@@ factory GF(q) table @@\n" ) == 0, "illegal table" );
+    // read p and n from file
+    int pFile, nFile;
+    success = fgets( buffer, gf_maxbuffer, inputfile );
+    STICKYASSERT( success, "illegal table (reading p and n)" );
+    sscanf( buffer, "%d %d", &pFile, &nFile );
+    STICKYASSERT( p == pFile && n == nFile, "illegal table" );
+    // skip (sic!) factory-representation of mipo
+    // and terminating "; "
+    bufptr = (char *)strchr( buffer, ';' ) + 2;
+    // read simple representation of mipo
+    int i, degree;
+    sscanf( bufptr, "%d", &degree );
+    bufptr = (char *)strchr( bufptr, ' ' ) + 1;
+    int * mipo = new int[degree + 1];
+    for ( i = 0; i <= degree; i++ )
+    {
+        sscanf( bufptr, "%d", mipo + i );
+        bufptr = (char *)strchr( bufptr, ' ' ) + 1;
+    }
+
+    gf_p = p; gf_n = n;
+    gf_q = q; gf_q1 = q-1;
+    gf_mipo = intVec2CF( degree, mipo, 1 );
+    delete [] mipo;
+
+    // now for the table
+    int k, digs = gf_tab_numdigits62( gf_q );
+    i = 1;
+    while ( i < gf_q )
+    {
+        success = fgets( buffer, gf_maxbuffer, inputfile );
+        STICKYASSERT( strlen( buffer ) - 1 == (size_t)digs * 30, "illegal table" );
+        bufptr = buffer;
+        k = 0;
+        while ( i < gf_q && k < 30 )
+        {
+            gf_table[i] = convertback62( bufptr, digs );
+            bufptr += digs;
+            if ( gf_table[i] == gf_q )
+            {
+                if ( i == gf_q1 )
+                    gf_m1 = 0;
+                else
+                    gf_m1 = i;
+            }
+            i++; k++;
+        }
+    }
+    gf_table[0] = gf_table[gf_q1];
+    gf_table[gf_q] = 0;
+
+    (void)fclose( inputfile );
+}
+
+#ifndef NOASSERT
+static bool gf_valid_combination ( int p, int n )
+{
+    int i = 0;
+    while ( i < gf_primes_len && gf_primes[i] != p ) i++;
+    if ( i == gf_primes_len )
+        return false;
+    else
+    {
+        i = n;
+        int a = 1;
+        while ( a < gf_maxtable && i > 0 )
+        {
+            a *= p;
+            i--;
+        }
+        if ( i > 0 || a > gf_maxtable )
+            return false;
+        else
+            return true;
+    }
+}
+#endif
+
+void gf_setcharacteristic ( int p, int n, char name )
+{
+    ASSERT( gf_valid_combination( p, n ), "illegal immediate GF(q)" );
+    gf_name = name;
+    gf_get_table( p, n );
+}
+
+long gf_gf2ff ( long a )
+{
+    if ( gf_iszero( a ) )
+        return 0;
+    else
+    {
+        // starting from z^0=1, step through the table
+        // counting the steps until we hit z^a or z^0
+        // again.  since we are working in char(p), the
+        // latter is guaranteed to be fulfilled.
+        long i = 0, ff = 1;
+        do
+        {
+            if ( i == a )
+                return ff;
+            ff++;
+            i = gf_table[i];
+        } while ( i != 0 );
+        return -1;
+    }
+}
+
+int gf_gf2ff ( int a )
+{
+    if ( gf_iszero( a ) )
+        return 0;
+    else
+    {
+        // starting from z^0=1, step through the table
+        // counting the steps until we hit z^a or z^0
+        // again.  since we are working in char(p), the
+        // latter is guaranteed to be fulfilled.
+        int i = 0, ff = 1;
+        do
+        {
+            if ( i == a )
+                return ff;
+            ff++;
+            i = gf_table[i];
+        } while ( i != 0 );
+        return -1;
+    }
+}
+
+bool gf_isff ( long a )
+{
+    if ( gf_iszero( a ) )
+        return true;
+    else
+    {
+        // z^a in GF(p) iff (z^a)^p-1=1
+        return gf_isone( gf_power( a, gf_p - 1 ) );
+    }
+}
+
+bool gf_isff ( int a )
+{
+    if ( gf_iszero( a ) )
+        return true;
+    else
+    {
+        // z^a in GF(p) iff (z^a)^p-1=1
+        return gf_isone( gf_power( a, gf_p - 1 ) );
+    }
+}
diff --git a/factory/gfops.h b/factory/gfops.h
new file mode 100644
index 0000000..17d81c8
--- /dev/null
+++ b/factory/gfops.h
@@ -0,0 +1,256 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+/**
+ * @file gfops.h
+ *
+ * Operations in GF, where GF is a finite field of size less than 2^16
+ * represented by a root of Conway polynomial. Uses look up tables for addition.
+ *
+ * @sa gf_tabutil.h
+**/
+#ifndef INCL_GFOPS_H
+#define INCL_GFOPS_H
+
+// #include "config.h"
+
+#ifndef NOSTREAMIO
+#ifdef HAVE_IOSTREAM
+#include <iostream>
+#define OSTREAM std::ostream
+#elif defined(HAVE_IOSTREAM_H)
+#include <iostream.h>
+#define OSTREAM ostream
+#endif
+#endif /* NOSTREAMIO */
+
+#include "cf_assert.h"
+
+#include "cf_defs.h"
+#include "canonicalform.h"
+
+extern int gf_q;
+extern int gf_p;
+extern int gf_n;
+extern int gf_q1;
+extern int gf_m1;
+extern char gf_name;
+
+extern unsigned short * gf_table;
+
+extern CanonicalForm gf_mipo;
+
+//{{{ predicates
+inline bool gf_iszero ( int a )
+{
+    return gf_q == a;
+}
+
+inline bool gf_iszero ( long a )
+{
+    return gf_q == a;
+}
+
+inline bool gf_isone ( int a )
+{
+    return 0 == a;
+}
+
+inline bool gf_isone ( long a )
+{
+    return 0 == a;
+}
+//}}}
+
+//{{{ conversion functions
+inline int gf_int2gf ( int i )
+{
+    while ( i < 0 )
+	i += gf_p;
+    while ( i >= gf_p )
+	i -= gf_p;
+    if ( i == 0 )
+	return gf_q;
+    int c = 0;
+    while ( i > 1 ) {
+	c = gf_table[c];
+	i--;
+    }
+    return c;
+}
+
+inline long gf_int2gf ( long i )
+{
+    while ( i < 0 )
+	i += gf_p;
+    while ( i >= gf_p )
+	i -= gf_p;
+    if ( i == 0 )
+	return gf_q;
+    long c = 0;
+    while ( i > 1 ) {
+	c = gf_table[c];
+	i--;
+    }
+    return c;
+}
+//}}}
+
+//{{{ zero and one
+inline int gf_zero()
+{
+    return gf_q;
+}
+
+inline int gf_one()
+{
+    return 0;
+}
+//}}}
+
+//{{{ inline int gf_sign ( int a )
+// docu: see imm_sign()
+inline
+int gf_sign ( int a )
+{
+    if ( gf_iszero( a ) )
+	return 0;
+    else
+	return 1;
+}
+//}}}
+
+//{{{ arithmetic operators
+inline int gf_neg ( int a )
+{
+    // -z^a=z^a*(-1)=z^a*gf_m1;
+    if ( a == gf_q ) return a;
+    int i = a + gf_m1;
+    if ( i >= gf_q1 )
+	i -= gf_q1;
+    return i;
+}
+
+inline int gf_add ( int a, int b )
+{
+    // z^a+z^b=z^b*(z^(a-b)+1), if a>=b;
+    //        =z^a*(z^(b-a)+1), if a<b;
+    if ( a == gf_q ) return b;
+    if ( b == gf_q ) return a;
+    int zb, zab, r;
+    if ( a >= b ) {
+	zb = b;
+	zab = a - b;
+    }
+    else {
+	zb = a;
+	zab = b - a;
+    }
+    if ( gf_table[zab] == gf_q )
+	r = gf_q; /*if z^(a-b)+1 =0*/
+    else {
+	r= zb + gf_table[zab];
+	if ( r >= gf_q1 )
+	    r -= gf_q1;
+    }
+    return r;
+}
+
+inline int gf_sub ( int a, int b )
+{
+    return gf_add( a, gf_neg( b ) );
+}
+
+inline int gf_mul ( int a, int b )
+{
+    if ( a == gf_q || b == gf_q )
+	return gf_q;
+    else {
+	int i = a + b;
+	if ( i >= gf_q1 ) i -= gf_q1;
+	return i;
+    }
+}
+
+inline long gf_mul ( long a, int b )
+{
+    if ( a == gf_q || b == gf_q )
+	return gf_q;
+    else {
+	long i = a + b;
+	if ( i >= gf_q1 ) i -= gf_q1;
+	return i;
+    }
+}
+
+inline int gf_div ( int a, int b )
+{
+    ASSERT( b != gf_q, "divide by zero" );
+    if ( a == gf_q )
+	return gf_q;
+    else {
+	int s = a - b;
+	if (s < 0)
+	    s += gf_q1;
+	return s;
+    }
+}
+
+inline int gf_inv ( int a )
+{
+    ASSERT( a != gf_q, "divide by zero" );
+    return gf_q1 - a;
+}
+//}}}
+
+//{{{ input/output
+#ifndef NOSTREAMIO
+inline void gf_print ( OSTREAM & os, int a )
+{
+    if ( a == gf_q )
+	os << "0";
+    else  if ( a == 0 )
+	os << "1";
+    else  if ( a == 1 )
+	os << gf_name;
+    else
+	os << gf_name << "^" << a;
+}
+#endif /* NOSTREAMIO */
+//}}}
+
+//{{{ exponentation
+inline int gf_power ( int a, int n )
+{
+    if ( n == 0 )
+	return 0;
+    else if ( n == 1 )
+	return a;
+    else
+	return gf_mul( a, gf_power( a, n-1 ) );
+}
+
+inline long gf_power ( long a, int n )
+{
+    if ( n == 0 )
+	return 0;
+    else if ( n == 1 )
+	return a;
+    else
+	return gf_mul( a, gf_power( a, n-1 ) );
+}
+//}}}
+
+void gf_setcharacteristic ( int p, int n, char name );
+
+// Singular needs this
+/*BEGINPUBLIC*/
+
+long gf_gf2ff ( long a );
+int gf_gf2ff ( int a );
+
+bool gf_isff ( long a );
+bool gf_isff ( int a );
+
+/*ENDPUBLIC*/
+
+#endif /* ! INCL_GFOPS_H */
diff --git a/factory/gftables/10201 b/factory/gftables/10201
new file mode 100644
index 0000000..e07bf00
--- /dev/null
+++ b/factory/gftables/10201
@@ -0,0 +1,342 @@
+@@ factory GF(q) table @@
+101 2 v_1^2+97*v_1+2; 2 1 97 2
+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
diff --git a/factory/gftables/1024 b/factory/gftables/1024
new file mode 100644
index 0000000..368791d
--- /dev/null
+++ b/factory/gftables/1024
@@ -0,0 +1,37 @@
+@@ factory GF(q) table @@
+2 10 v_1^10+v_1^6+v_1^5+v_1^3+v_1^2+v_1+1; 10 1 0 0 0 1 1 0 1 1 1 1
+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
+219GGW000000000000000000000000000000000000000000000000000000
diff --git a/factory/gftables/10609 b/factory/gftables/10609
new file mode 100644
index 0000000..adbdda9
--- /dev/null
+++ b/factory/gftables/10609
@@ -0,0 +1,356 @@
+@@ factory GF(q) table @@
+103 2 v_1^2+102*v_1+5; 2 1 102 5
+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
diff --git a/factory/gftables/11449 b/factory/gftables/11449
new file mode 100644
index 0000000..a86f8a6
--- /dev/null
+++ b/factory/gftables/11449
@@ -0,0 +1,384 @@
+@@ factory GF(q) table @@
+107 2 v_1^2+103*v_1+2; 2 1 103 2
+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
+1BX1rZ09A2fA2bj2Y61DM28G0xb2dB0Cg2UA11b2Ph1B90JF2M001k000000000000000000000000000000000000
diff --git a/factory/gftables/11881 b/factory/gftables/11881
new file mode 100644
index 0000000..0908187
--- /dev/null
+++ b/factory/gftables/11881
@@ -0,0 +1,398 @@
+@@ factory GF(q) table @@
+109 2 v_1^2+108*v_1+6; 2 1 108 6
+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
diff --git a/factory/gftables/121 b/factory/gftables/121
new file mode 100644
index 0000000..287332c
--- /dev/null
+++ b/factory/gftables/121
@@ -0,0 +1,6 @@
+@@ factory GF(q) table @@
+11 2 v_1^2+7*v_1+2; 2 1 7 2
+0R1R1C1X0B050q1D0d0N0v1Y0911160b0A0W0Z1u1S0J1b0m1g080w1i101J
+0u0H1W1V121A1j0e1L0K030Y0F1N0S1Q1Z1k1q07040I0h1l010l0c1I0s1x
+1r0M1d1n140t1m1O1B1F130y0o0g1f0f1U1o1K1c0i02180a0T0x0z1h0P0p
+0X1G0V1e1H0O1E1t171a0G0E1p0L0r0n1s1M0k0D0U150j1v061T191P0Q0C
diff --git a/factory/gftables/12167 b/factory/gftables/12167
new file mode 100644
index 0000000..df9e677
--- /dev/null
+++ b/factory/gftables/12167
@@ -0,0 +1,408 @@
+@@ factory GF(q) table @@
+23 3 v_1^3+2*v_1+18; 3 1 0 2 18
+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
+0tK2LT1MK0W90ES1Il0eI0RL2vu0lr0p60Fj2xW1Re15r0Hq000000000000000000000000000000000000000000
diff --git a/factory/gftables/125 b/factory/gftables/125
new file mode 100644
index 0000000..2871707
--- /dev/null
+++ b/factory/gftables/125
@@ -0,0 +1,7 @@
+@@ factory GF(q) table @@
+5 3 v_1^3+3*v_1+3; 3 1 0 3 3
+1Y190A1O1k0F0y1b121j1y1R1U0Y0o0O0n1h050w0M040B140i031C1g0s1D
+1V0Q0z110q06181s0a1z0v1S1I0e1A151r0h0p0d0C1t1l1c1q0U0E0I0N1B
+1e210f0D1Q1M1J1a0x0k0u131N1p021v160L0R1w0b0m0G1L1x1G0X1W0H0T
+0S1u100j0P1E0l1d0J0g1o1i010c1m1P0W080Z0K1H1F1n1Z0t1T0r091f1K
+07171X0V0000000000000000000000000000000000000000000000000000
diff --git a/factory/gftables/12769 b/factory/gftables/12769
new file mode 100644
index 0000000..f717ac3
--- /dev/null
+++ b/factory/gftables/12769
@@ -0,0 +1,428 @@
+@@ factory GF(q) table @@
+113 2 v_1^2+101*v_1+3; 2 1 101 3
+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
+0NN1PF2PI0It10x21U2Ng2ys18z37u0nq0db1xf2JK1Vq04N3Dg3Aw39A0ml0Xd0W21T409w1822oQ1F33AC04c0Nb
+2dt0dG1Cd3Hc3DX2nS0Da0zw2Us1Ey1iW1yW2QX1CW2300Qc08c3II33D0Bt2WN2Vb1KM2yh31D01K1WP0mB2XJ0eB
+0YC0Ex0LU1Jt0ij3Er0gk1qN1at0iJ0kV21n0d80uc0nF27S1hr0U83Ae0n42SL0EH2IE0bZ30S3CT30G0b12g52l9
+1LT2GY0ez0Df0xF05W0vs2SD1uE1id2mg2280Vd2LF15y2X60d70Z30nD0xJ1kW1xT0Ll3AQ3Fi2Zj1ij0362Pd0xc
+2gF3DY3Bw2JI1X424W2W40ji0kl1370cZ0ju2fN36G1II2N53FJ2LI0jU0lF1wQ2Ue2ft2bv0kM0J91s32RL0LZ08z
+2hs0sm2OG0oy0gr1Fa00j3Ef0T938M14503B1Jf03y0rI2GL1qv3Df2iy0ME1Z72rb1qC2ud1Qi1Na2Fi0N10Na1Nq
+1I11PS2Rj01U1WL2R52K63Fn0hw1Jn1tF2Nl2i42Pk0We0wn22S0nx1Bk3CD3492DT0BK3891pJ1RS1ZA20X2VQ2AE
+0np26l0OW2oc27g2r91KZ2WX1Wk17u1L62ZW0612HA1xI2NL15f2sQ1ew15S1f01vw2SP12d1lB2a838N12j1Eq3CZ
+0xr2PJ0wy2gN2DY05F2EO0lv2QO14V1RZ2DK0uL04e0RM2h30fW1IT2Rf1Fr21Z0KH1jP1Jh0bt0qf3812B11QS3A3
+1mi0fz3HD1W90Ol2d21ux0YA16b3021rm3Bk15u0Ae1xD1ws2YA1xN1et1Xn03P2me0461f32OO2TZ0Xc2HR2xK2IN
+1zp3Af1mj3C81aI36e2Gn1RL0PN1N90Mf2gf2cZ0kg3Dy1O717S1IB2Hu1av1u51j317h03g0Ne2vs0wi0ts0Ia1kf
+2DM01a1Lk04P1Hp0Md2dq2MM2It1pX1752Py37A3Hx2le0JP02E2JL2Cz1qc0ht0Dy1ME1Jk2rk15G3CH35Z37w1r2
+3Dc1yw3H61pP1Yo09q2Uz2WA3GO33U1Cw2MN0wQ28D1JU1Gh07x26v2ao1uY2cF2yK2E33JS0XR1Mr2vJ1990xo0q9
+25W01d36C1Gp0Jc02g1GA1wK0FC0Ky0xG0Fb2cH1zz2v50650j12vq2z41xQ0k91Pd2sW2kl0zS2rE0Av0FF0nG2BU
+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
+1Lq1rE2cg1gq01w33b39n30s0ZB22q0US0H72ib0v82aK2hd39r0M4000000000000000000000000000000000000
diff --git a/factory/gftables/128 b/factory/gftables/128
new file mode 100644
index 0000000..b3b5556
--- /dev/null
+++ b/factory/gftables/128
@@ -0,0 +1,7 @@
+@@ factory GF(q) table @@
+2 7 v_1^7+v_1+1; 7 1 0 0 0 0 0 1 1
+070E110S0s22010u1S1k1P210t020V1o0h0r0T1R0v0l1K1z1h1m14040J10
+0F1Z1F1O1l1i0k0w1c0p1D1q0H1W160b0M1v1y1L0e1V0I050D080L0c1g20
+1Q0U03151X0R120j1j1T1H1N1G1U0f1s0X1B191e1u0N0o1d1A0Y0B0z0K09
+181C0q0i131n0W1t1f0d1M1I1b0x0P0a170A0Z0Q1Y0G1r0g1p1E1a1J0m1x
+1w0n0O0y0C06240000000000000000000000000000000000000000000000
diff --git a/factory/gftables/1331 b/factory/gftables/1331
new file mode 100644
index 0000000..8f0d342
--- /dev/null
+++ b/factory/gftables/1331
@@ -0,0 +1,47 @@
+@@ factory GF(q) table @@
+11 3 v_1^3+2*v_1+9; 3 1 0 2 9
+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
+EU9152EHDfIRLGCIJZ290000000000000000000000000000000000000000
diff --git a/factory/gftables/1369 b/factory/gftables/1369
new file mode 100644
index 0000000..69525e0
--- /dev/null
+++ b/factory/gftables/1369
@@ -0,0 +1,48 @@
+@@ factory GF(q) table @@
+37 2 v_1^2+33*v_1+2; 2 1 33 2
+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
+Fe5f9vB84OCVDY2V1UJu7uAiARLnIzJF830c000000000000000000000000
diff --git a/factory/gftables/14641 b/factory/gftables/14641
new file mode 100644
index 0000000..5671273
--- /dev/null
+++ b/factory/gftables/14641
@@ -0,0 +1,490 @@
+@@ factory GF(q) table @@
+11 4 v_1^4+8*v_1^2+10*v_1+2; 4 1 0 8 10 2
+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
diff --git a/factory/gftables/15625 b/factory/gftables/15625
new file mode 100644
index 0000000..08ced07
--- /dev/null
+++ b/factory/gftables/15625
@@ -0,0 +1,523 @@
+@@ factory GF(q) table @@
+5 6 v_1^6+v_1^4+4*v_1^3+v_1^2+2; 6 1 0 1 4 1 0 2
+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
diff --git a/factory/gftables/16 b/factory/gftables/16
new file mode 100644
index 0000000..9c96ae7
--- /dev/null
+++ b/factory/gftables/16
@@ -0,0 +1,3 @@
+@@ factory GF(q) table @@
+2 4 v_1^4+v_1+1; 4 1 0 0 1 1
+48E1AD9275CB63G000000000000000
diff --git a/factory/gftables/16129 b/factory/gftables/16129
new file mode 100644
index 0000000..d2e11c1
--- /dev/null
+++ b/factory/gftables/16129
@@ -0,0 +1,540 @@
+@@ factory GF(q) table @@
+127 2 v_1^2+126*v_1+3; 2 1 126 3
+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
+3E30vi16W0QL0XG3L43pV3ev1Wn1KI1pt3SX3XF47T34e2DX2m62Oe000000000000000000000000000000000000
diff --git a/factory/gftables/16384 b/factory/gftables/16384
new file mode 100644
index 0000000..5aa15a7
--- /dev/null
+++ b/factory/gftables/16384
@@ -0,0 +1,549 @@
+@@ factory GF(q) table @@
+2 14 v_1^14+v_1^7+v_1^5+v_1^3+1; 14 1 0 0 0 0 0 0 1 0 1 0 1 0 0 1
+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
+2Rl3M04GG000000000000000000000000000000000000000000000000000000000000000000000000000000000
diff --git a/factory/gftables/16807 b/factory/gftables/16807
new file mode 100644
index 0000000..c398841
--- /dev/null
+++ b/factory/gftables/16807
@@ -0,0 +1,563 @@
+@@ factory GF(q) table @@
+7 5 v_1^5+v_1+4; 5 1 0 0 0 1 4
+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
+0DU0j64As2fh38g1SM000000000000000000000000000000000000000000000000000000000000000000000000
diff --git a/factory/gftables/1681 b/factory/gftables/1681
new file mode 100644
index 0000000..59bb1f2
--- /dev/null
+++ b/factory/gftables/1681
@@ -0,0 +1,58 @@
+@@ factory GF(q) table @@
+41 2 v_1^2+38*v_1+6; 2 1 38 6
+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
diff --git a/factory/gftables/169 b/factory/gftables/169
new file mode 100644
index 0000000..abb3f80
--- /dev/null
+++ b/factory/gftables/169
@@ -0,0 +1,8 @@
+@@ factory GF(q) table @@
+13 2 v_1^2+12*v_1+2; 2 1 12 2
+1m1Z0Q171h240I2H2K0G1K2h1O0u1f1H260P1b0z1R2W232E1L1N2d22150y
+090a2R0p0F0d081G020J0V1o1j1S2f1d0j2e1E101D0v0A1k0l0S1U2L2b1V
+2I0r0i0n0L2X1t2c0K2U1A1i2Q0h0M0T2J2S1n28250b1Y2j0D1z0m0q0W1C
+141x1r2D1F0Y011M1v1W0o1T202T2P2Z1J0X1e1P0Z2G2a0s21050O0C0R1s
+2g0t1w0k12182Y2N270e2F032O0H1u042M0U0c1a2C0x0w1q1g2A160f1I07
+1p111Q0g1B2V19062B290B1y1c130N1X1l0E000000000000000000000000
diff --git a/factory/gftables/17161 b/factory/gftables/17161
new file mode 100644
index 0000000..f8bcc90
--- /dev/null
+++ b/factory/gftables/17161
@@ -0,0 +1,574 @@
+@@ factory GF(q) table @@
+131 2 v_1^2+127*v_1+2; 2 1 127 2
+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
diff --git a/factory/gftables/1849 b/factory/gftables/1849
new file mode 100644
index 0000000..8d930a2
--- /dev/null
+++ b/factory/gftables/1849
@@ -0,0 +1,64 @@
+@@ factory GF(q) table @@
+43 2 v_1^2+42*v_1+3; 2 1 42 3
+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
+7wKUNA9gLE0kL2HI6JObSREAQxKHG8KhBuJA000000000000000000000000
diff --git a/factory/gftables/18769 b/factory/gftables/18769
new file mode 100644
index 0000000..b1983e3
--- /dev/null
+++ b/factory/gftables/18769
@@ -0,0 +1,628 @@
+@@ factory GF(q) table @@
+137 2 v_1^2+131*v_1+3; 2 1 131 3
+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
diff --git a/factory/gftables/19321 b/factory/gftables/19321
new file mode 100644
index 0000000..f222caa
--- /dev/null
+++ b/factory/gftables/19321
@@ -0,0 +1,646 @@
+@@ factory GF(q) table @@
+139 2 v_1^2+138*v_1+2; 2 1 138 2
+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
diff --git a/factory/gftables/19683 b/factory/gftables/19683
new file mode 100644
index 0000000..f2b9992
--- /dev/null
+++ b/factory/gftables/19683
@@ -0,0 +1,659 @@
+@@ factory GF(q) table @@
+3 9 v_1^9+2*v_1^3+2*v_1^2+v_1+1; 9 1 0 0 0 0 0 2 2 1 1
+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
+21H2Yj000000000000000000000000000000000000000000000000000000000000000000000000000000000000
diff --git a/factory/gftables/2048 b/factory/gftables/2048
new file mode 100644
index 0000000..a60d7c0
--- /dev/null
+++ b/factory/gftables/2048
@@ -0,0 +1,71 @@
+@@ factory GF(q) table @@
+2 11 v_1^11+v_1^2+1; 11 1 0 0 0 0 0 0 0 0 1 0 1
+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
+FKSU0I7f09GaX20000000000000000000000000000000000000000000000
diff --git a/factory/gftables/2187 b/factory/gftables/2187
new file mode 100644
index 0000000..247d75d
--- /dev/null
+++ b/factory/gftables/2187
@@ -0,0 +1,75 @@
+@@ factory GF(q) table @@
+3 7 v_1^7+2*v_1^2+1; 7 1 0 0 0 0 2 0 1
+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
diff --git a/factory/gftables/2197 b/factory/gftables/2197
new file mode 100644
index 0000000..42ed0ef
--- /dev/null
+++ b/factory/gftables/2197
@@ -0,0 +1,76 @@
+@@ factory GF(q) table @@
+13 3 v_1^3+2*v_1+11; 3 1 0 2 11
+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
+94FHEP6hRc2x000000000000000000000000000000000000000000000000
diff --git a/factory/gftables/2209 b/factory/gftables/2209
new file mode 100644
index 0000000..d0d913f
--- /dev/null
+++ b/factory/gftables/2209
@@ -0,0 +1,76 @@
+@@ factory GF(q) table @@
+47 2 v_1^2+45*v_1+5; 2 1 45 5
+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
diff --git a/factory/gftables/22201 b/factory/gftables/22201
new file mode 100644
index 0000000..86475b4
--- /dev/null
+++ b/factory/gftables/22201
@@ -0,0 +1,742 @@
+@@ factory GF(q) table @@
+149 2 v_1^2+145*v_1+2; 2 1 145 2
+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
diff --git a/factory/gftables/22801 b/factory/gftables/22801
new file mode 100644
index 0000000..46bfe7e
--- /dev/null
+++ b/factory/gftables/22801
@@ -0,0 +1,762 @@
+@@ factory GF(q) table @@
+151 2 v_1^2+149*v_1+6; 2 1 149 6
+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
diff --git a/factory/gftables/2401 b/factory/gftables/2401
new file mode 100644
index 0000000..b338117
--- /dev/null
+++ b/factory/gftables/2401
@@ -0,0 +1,82 @@
+@@ factory GF(q) table @@
+7 4 v_1^4+5*v_1^2+4*v_1+3; 4 1 0 5 4 3
+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
diff --git a/factory/gftables/243 b/factory/gftables/243
new file mode 100644
index 0000000..bef0669
--- /dev/null
+++ b/factory/gftables/243
@@ -0,0 +1,11 @@
+@@ factory GF(q) table @@
+3 5 v_1^5+2*v_1+1; 5 1 0 0 0 2 1
+170k3L33012E1o1b2D3N1r1L3g0m0326232m1a0Q1W2R2d0t140b2j1F3e2J
+0u101f0D0o070K2l3E1K132K3c37091C3S2O0l2Z2F2o2n0W3F3W0q0J3Q1G
+0p0s0e1t3V3P0821050A3f2f3M023C1U3A1n2a2q0N111u3j1E2038270M31
+2u1N2i1k3o302r0w151P0H0d2e1M2Q362A0L1i3J0y0a0x0T3U121s0C1A04
+3v22392C3t341d2X322g351X3r2V0R1O0j3a0z2t2Y3h3O3G1I1S2H0E1D3n
+1R1Z2p0h1j0c3l2N0Z3b2y1Y1J0X1v0G1z2k2B1V2W2w2s0v2x2L2S0r3X3m
+3k0I2T3H3p2c2M3Y1w1y1Q1l3s1c2h0S3K2P2v1e0O0g2b293d3R0F3Z180U
+0P1p3B0n2I0B0f0V2G251B061H2U1m1q3i0Y3T191g3D241T1h283q2z3I0i
+161x00000000000000000000000000000000000000000000000000000000
diff --git a/factory/gftables/24389 b/factory/gftables/24389
new file mode 100644
index 0000000..31499e4
--- /dev/null
+++ b/factory/gftables/24389
@@ -0,0 +1,815 @@
+@@ factory GF(q) table @@
+29 3 v_1^3+2*v_1+27; 3 1 0 2 27
+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
diff --git a/factory/gftables/24649 b/factory/gftables/24649
new file mode 100644
index 0000000..6c5590b
--- /dev/null
+++ b/factory/gftables/24649
@@ -0,0 +1,824 @@
+@@ factory GF(q) table @@
+157 2 v_1^2+152*v_1+5; 2 1 152 5
+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
diff --git a/factory/gftables/25 b/factory/gftables/25
new file mode 100644
index 0000000..9dd05c8
--- /dev/null
+++ b/factory/gftables/25
@@ -0,0 +1,3 @@
+@@ factory GF(q) table @@
+5 2 v_1^2+4*v_1+2; 2 1 4 2
+MHANEI84BDGP532K1C9J7FL6000000
diff --git a/factory/gftables/256 b/factory/gftables/256
new file mode 100644
index 0000000..da4c35b
--- /dev/null
+++ b/factory/gftables/256
@@ -0,0 +1,11 @@
+@@ factory GF(q) table @@
+2 8 v_1^8+v_1^4+v_1^3+v_1^2+1; 8 1 0 0 0 1 1 1 0 1
+0P0o3b1c2E351o3E1w0L3x231b3c0X2L163s1U0g0A3n3A46013C1g372v14
+0j0Z0F2C0W3d2t2y1i1M2X0K1x3T0V2D1d453B023q2H2N3M11271L1j1K28
+301S0t182c0U3U0H26121l393o1f3D1p3g3Q2o2i2a0x0v0e2k3u2h2p3H10
+3N0J2Y3G2q43342F0D040l3Z1C0R400d0w2b19223y071E2g3v3S1y2e2T09
+0h1t2x2u381m0C2G3r170u0y422r2K0Y0k051a240q3W2Q2B0G3V0r3K322J
+2s3e1v3F2Z2j0f1V2V1J1k132w1u3f1q1P1I2W1N3P3h3k1H1Q1X2A2R0b20
+0T2d1z0c410z3I2P3X1Z063z0S211A0N0n0Q1D082U1W1R313L2O3J0s1T3t
+2l1G3l1s0i152M2I33441e3p030E0a2S2f1F2m3j3i2n3R3w0M1B3a0p250I
+3O1O1r3m0B1n361h2z291Y3Y0m0O48000000000000000000000000000000
diff --git a/factory/gftables/26569 b/factory/gftables/26569
new file mode 100644
index 0000000..3c701e7
--- /dev/null
+++ b/factory/gftables/26569
@@ -0,0 +1,888 @@
+@@ factory GF(q) table @@
+163 2 v_1^2+159*v_1+2; 2 1 159 2
+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
+6gk0VK08C4U82YM4wr1zW6Fe2oV6Za5sR69L3Ut2fn0oI2bs5g258F2Y06eC0S23Oq2nd2yI2ab4jr5k63EJ0cM03z
+1qa4Dw3jG3kt3nM0ni4gs4x02c736Z1yJ4MJ0oa2513G70Mt4lC1nM6mj4pz1oI0Xp6J26PA5X343E4hk06p4pv0oA
+1zz4Jp1hp0Cq3nN26d1R32nM3WT1Ud1Oa2sA30U4CZ62m0Nd5Ix4oL00v3C11H95j11kF3Yd3PK2lW4dF5Ov1KS6Ip
+19u20I35q05G0sD6Wo2C628d05x4CG46v25R1gq5iY2GT1Rr4pW08w2Hf3750Yu3Wh0a741r3Xh68y0TS3mC3Uo64J
+6FZ66Q3fO0LA3ZV2LF4495IK3ik1yU6Aq3P26Nl45f2sR6VY6F12rg6fW23S3am19G6CL37C3iv4jv4tp5xV5dX4zP
+0yg3xi1yu4rX5070nL0so3D105K1791hl13e4Hf6nc1wx3bJ2HB2TT0zm4qQ5iU3S13nf5JR4N603v5Ml4Ni6jf1hc
+5Ev4SI6oP24l09J2qo3SV5gj6Rv3452Xf4N70rJ5Gq4jK6in3970FT4Te3py2Fb49a4zz4dX2806285dW6en3pP6om
+6dZ28q5zG5sL4Y84h23zZ1UM4tm2gK1pA31y2FY61J5iI57J6AI3iA1FI3c92uz53t5LG3Vg5cF1wL5po1qY3pd6rv
+6iZ68R3Pl5Sw2Lp2Ne6Fl6bt3CS2lo3BS1MW1HY1Xo4Gg6Fw0VV2ji6jD3DN5Zu2TH0fB0D20HA3dO3VC2t73Zp3vo
+0274s238U2LC0CG02I6LK1WW1lm3jT2cQ0wb3MV0NA1Ty6Q11l922y0Uo4EY2g059M23b4kg5gn35h1fG5Sz4nW1sv
+28t6NQ1Zj2yE0Fz01V3QX4VT1N22mf24I1bD0Ph2DK3ez2ig41n09b5LY6lA6Ah1Fb6YK2Vl1Aw2p13JP06Q05549i
+1Qx3VU2ci5oO6L85bO1gi2aI6tM48Y1d96R36i41ve6D93MU59m3CZ49C4k36YS5ST1rH6HG4dD19L1B44aQ20X5NH
+6Ll1Hu2Je0Fg3t65Xa1aP2A85kX6082xx3RQ4Ka2E92wC1901sR2QJ0l849U1CV4Nu4UM1JZ3wr1Jx58K4mB69n4lr
+35F0QR0lR5w30wt06M5CW3Ul3is3Ig34X4KU0cN31w3n225g63s2E113A5yr0xI3iI2Hl3Tz2SZ2T10gh6rB3824eW
+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
+0DQ0603w84yl2t561855W1AU2bT0YD5SV0791TQ4ml34R1rr68202e000000000000000000000000000000000000
diff --git a/factory/gftables/27 b/factory/gftables/27
new file mode 100644
index 0000000..61ef0b3
--- /dev/null
+++ b/factory/gftables/27
@@ -0,0 +1,3 @@
+@@ factory GF(q) table @@
+3 3 v_1^3+2*v_1+1; 3 1 0 2 1
+9L1IHB4F36A2RGPMK7N5CEOJ8D0000
diff --git a/factory/gftables/27889 b/factory/gftables/27889
new file mode 100644
index 0000000..6ffa426
--- /dev/null
+++ b/factory/gftables/27889
@@ -0,0 +1,932 @@
+@@ factory GF(q) table @@
+167 2 v_1^2+166*v_1+5; 2 1 166 5
+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
+3Du2xB25R6r34pi5ic1I02C455D0p85aK32t3nN0Pp57h2Ij5Fr1kO000000000000000000000000000000000000
diff --git a/factory/gftables/2809 b/factory/gftables/2809
new file mode 100644
index 0000000..ae658d5
--- /dev/null
+++ b/factory/gftables/2809
@@ -0,0 +1,96 @@
+@@ factory GF(q) table @@
+53 2 v_1^2+49*v_1+2; 2 1 49 2
+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
diff --git a/factory/gftables/28561 b/factory/gftables/28561
new file mode 100644
index 0000000..d59a715
--- /dev/null
+++ b/factory/gftables/28561
@@ -0,0 +1,954 @@
+@@ factory GF(q) table @@
+13 4 v_1^4+3*v_1^2+12*v_1+2; 4 1 0 3 12 2
+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
diff --git a/factory/gftables/289 b/factory/gftables/289
new file mode 100644
index 0000000..e861070
--- /dev/null
+++ b/factory/gftables/289
@@ -0,0 +1,12 @@
+@@ factory GF(q) table @@
+17 2 v_1^2+16*v_1+3; 2 1 16 3
+3h050n202b0Y3l0l4U0Q0h2F3c1W1i4d2P3U1h2i1g373N2e4K0Z1y3q154Q
+4D3k1j1N0v0s3S3B3G3J0b1x4A0g0q19060X2g3M494G2w224T1o132x3p1J
+2y1V4J382h1s271U0e2v1d2c4F0D110N421R4W2X0C2D182J2L1p4I2q2R4M
+164X3H2m3u0m413r1v1q48021Z0T3t3Z042K4V4C0F3x39311D462p4O3V3A
+0r3j3L2j2B3m244E1Y2o0z173D2T453b3o0f4b1f4Z1c2a4f0H3y2I432M35
+1b1P1u0J143d3W0i472A011k0A0j1M1l3Y1E1a2U0w2E401B1K29362Q2k0a
+2z1r2C3R4Y322V0E0K2H2S3s2N1G1m334H2u101Q2t0R0y0x4R0t3X1F3F0B
+2n3n4S3f341S0U1n4B0O120o1e263I0V1z0L2s21080u3a1A253Q3K2Y1t4P
+3z0P074c3T1H4a2f2d2Z2r0I0M0p1C3E3i3w0c3O1X093v2G302l1L2O1O3C
+284N1T1I3P230W0G4L0d3e0S2W1w0k033g44000000000000000000000000
diff --git a/factory/gftables/29791 b/factory/gftables/29791
new file mode 100644
index 0000000..1bb0031
--- /dev/null
+++ b/factory/gftables/29791
@@ -0,0 +1,995 @@
+@@ factory GF(q) table @@
+31 3 v_1^3+v_1+28; 3 1 0 1 28
+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
diff --git a/factory/gftables/29929 b/factory/gftables/29929
new file mode 100644
index 0000000..de320f6
--- /dev/null
+++ b/factory/gftables/29929
@@ -0,0 +1,1000 @@
+@@ factory GF(q) table @@
+173 2 v_1^2+169*v_1+2; 2 1 169 2
+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
diff --git a/factory/gftables/3125 b/factory/gftables/3125
new file mode 100644
index 0000000..9a4df60
--- /dev/null
+++ b/factory/gftables/3125
@@ -0,0 +1,107 @@
+@@ factory GF(q) table @@
+5 5 v_1^5+4*v_1+3; 5 1 0 0 0 4 3
+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
+GNA820Cb0000000000000000000000000000000000000000000000000000
diff --git a/factory/gftables/32 b/factory/gftables/32
new file mode 100644
index 0000000..8c8d16d
--- /dev/null
+++ b/factory/gftables/32
@@ -0,0 +1,4 @@
+@@ factory GF(q) table @@
+2 5 v_1^5+v_1^2+1; 5 1 0 0 1 0 1
+I5TA2RMKG4JNEDO9U1B8P7CFLS6Q3H
+W00000000000000000000000000000
diff --git a/factory/gftables/32041 b/factory/gftables/32041
new file mode 100644
index 0000000..c17974d
--- /dev/null
+++ b/factory/gftables/32041
@@ -0,0 +1,1070 @@
+@@ factory GF(q) table @@
+179 2 v_1^2+172*v_1+2; 2 1 172 2
+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
diff --git a/factory/gftables/32761 b/factory/gftables/32761
new file mode 100644
index 0000000..c152da5
--- /dev/null
+++ b/factory/gftables/32761
@@ -0,0 +1,1094 @@
+@@ factory GF(q) table @@
+181 2 v_1^2+177*v_1+2; 2 1 177 2
+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
diff --git a/factory/gftables/32768 b/factory/gftables/32768
new file mode 100644
index 0000000..8e93faa
--- /dev/null
+++ b/factory/gftables/32768
@@ -0,0 +1,1095 @@
+@@ factory GF(q) table @@
+2 15 v_1^15+v_1^5+v_1^4+v_1^2+1; 15 1 0 0 0 0 0 0 0 0 0 1 1 0 1 0 1
+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
+8N409r7Zr4BX83B8Hq8WW000000000000000000000000000000000000000000000000000000000000000000000
diff --git a/factory/gftables/343 b/factory/gftables/343
new file mode 100644
index 0000000..fabacce
--- /dev/null
+++ b/factory/gftables/343
@@ -0,0 +1,14 @@
+@@ factory GF(q) table @@
+7 3 v_1^3+6*v_1^2+4; 3 1 6 0 4
+1L0H1g3I41253r031F0Y551T521v3U4k084I560G0i4h1j3x3u3m4t0y2h2W
+4X3z2p5D0X4D2L154r1P1S3X072F302M4d3R4v2N5E3p572B010L3g5K0S1C
+2e5J3B4A0x3b3t2s203q3A0M2g390A3H2T2q2G4F4j101A4l1y0k3n4C4B3L
+28431u4Q331l5I2P0B0g1p1w4H532K1Y2V0q0K3G5006190v113W1s2D0u37
+1b4431470e2S592Y0w3O1N3C2a3Y241r58024Y1o2y4R0V2w343c4y4o0o0Z
+1R3J3a5H045F4K3l3h1Q132U090a1i2d2R052C0s5X3e4z2t5G5T4Z3S325O
+3y4M181D1n2j352n170r4W3f3v2Q2b1G0j0c3i290h542J3K2v5B5P1O0R14
+4m1I4N0U360Q492712265A1B4V0J5V1e4g4b4q3o3D1U454c0m5M0d3N2c0I
+0C4a460p3j0D1W2u0P2Z0f1t2k2m2O4s0b3P5L5C3Q2x0z1a1E234T1x1V4i
+212i0t1m2o2X5Q382A4J1f0E514O2l4x4e1J4G2z4P1Z482f3s1c2H1X4w2r
+0n0l4E0T1k3d5U4f2I3T42222E0W4S3M3V3Z1M4L0N5S4n405N4U3F1h4p1H
+4u0O165R3k1z3w3E1d0F1K1q000000000000000000000000000000000000
diff --git a/factory/gftables/3481 b/factory/gftables/3481
new file mode 100644
index 0000000..439a13a
--- /dev/null
+++ b/factory/gftables/3481
@@ -0,0 +1,118 @@
+@@ factory GF(q) table @@
+59 2 v_1^2+58*v_1+2; 2 1 58 2
+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
diff --git a/factory/gftables/361 b/factory/gftables/361
new file mode 100644
index 0000000..1d039fa
--- /dev/null
+++ b/factory/gftables/361
@@ -0,0 +1,14 @@
+@@ factory GF(q) table @@
+19 2 v_1^2+18*v_1+2; 2 1 18 2
+3W3D0c4V1g3w1T1K3J3v4A59050B1f2l2s5n2w4C5i14241933542H4j1O0p
+1i251P0n211G2t2v3y5A2B0T4T074I505X1l0V0O4F472k2D4M13022o0j2a
+5Y0Y34301a3X2j0W0U5S4p5k114b3k4D4O350u3E485H3j2A2S3d0P1m4S3n
+0C494w4t2q4L3b4c2y2G1R581v1k464U0x2U530q160h3M565f290A1V430y
+0m184Q0N1z4P2i0w5T3e5Z1B4f3K0E4k174Y363Y1n5F2C1o5C0S4E0a0I0d
+0D1u2Z26100Q1d424z5U2c273f3t511x2E1H031j4l2h0b3F08442g0t3C5p
+0J3p5d1E370R3c5j204n384N5L552M1F125J012u2Q1U4u3i4J5Q065G3a41
+3h401r3u2r5I5h2x5K1I0r2K4i2Y3r1A2W4r3S1Y3O4g0f2N5m4B2R4y4d4q
+285P450H3o3G1X4h574s3I0k522m2P040G3U5c0e1N32222n1J3N3R2f4X2L
+310M4o2F150o2O3x2p1w5R1p392z2X3P5e4a3g4K5B5E1e2T0X1y235M4Z1c
+5a1s4v093T1L1t3H3Q5O5W0z4m4G3Z5D3m5b1W4W3L2J2I0g1S0F0s1Z1D0L
+0v4H1q4e2e0l1h0i5N3s2d5V2b2V1Q5l5g4x3z3l3A1C1M3q1b4R0Z3B3V0K
diff --git a/factory/gftables/36481 b/factory/gftables/36481
new file mode 100644
index 0000000..a5d443e
--- /dev/null
+++ b/factory/gftables/36481
@@ -0,0 +1,1218 @@
+@@ factory GF(q) table @@
+191 2 v_1^2+190*v_1+19; 2 1 190 19
+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
diff --git a/factory/gftables/3721 b/factory/gftables/3721
new file mode 100644
index 0000000..91fc38f
--- /dev/null
+++ b/factory/gftables/3721
@@ -0,0 +1,126 @@
+@@ factory GF(q) table @@
+61 2 v_1^2+60*v_1+2; 2 1 60 2
+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
diff --git a/factory/gftables/37249 b/factory/gftables/37249
new file mode 100644
index 0000000..7dbb807
--- /dev/null
+++ b/factory/gftables/37249
@@ -0,0 +1,1244 @@
+@@ factory GF(q) table @@
+193 2 v_1^2+192*v_1+5; 2 1 192 5
+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
diff --git a/factory/gftables/38809 b/factory/gftables/38809
new file mode 100644
index 0000000..b3868ea
--- /dev/null
+++ b/factory/gftables/38809
@@ -0,0 +1,1296 @@
+@@ factory GF(q) table @@
+197 2 v_1^2+192*v_1+2; 2 1 192 2
+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
+71m3wj8wA8KT91D15h9Dq4XC8Yt5sH7dF2Hx1ik5e578z80i1wA03C000000000000000000000000000000000000
diff --git a/factory/gftables/39601 b/factory/gftables/39601
new file mode 100644
index 0000000..cd3c255
--- /dev/null
+++ b/factory/gftables/39601
@@ -0,0 +1,1322 @@
+@@ factory GF(q) table @@
+199 2 v_1^2+193*v_1+3; 2 1 193 3
+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
diff --git a/factory/gftables/4 b/factory/gftables/4
new file mode 100644
index 0000000..779ceee
--- /dev/null
+++ b/factory/gftables/4
@@ -0,0 +1,3 @@
+@@ factory GF(q) table @@
+2 2 v_1^2+v_1+1; 2 1 1 1
+214000000000000000000000000000
diff --git a/factory/gftables/4096 b/factory/gftables/4096
new file mode 100644
index 0000000..2882b59
--- /dev/null
+++ b/factory/gftables/4096
@@ -0,0 +1,139 @@
+@@ factory GF(q) table @@
+2 12 v_1^12+v_1^7+v_1^6+v_1^5+v_1^3+v_1+1; 12 1 0 0 0 0 1 1 1 0 1 0 1 1
+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
+05X0wn0RL0d709I0ta1230Zn0kh04e1330uN13Y0Wm144000000000000000000000000000000000000000000000
diff --git a/factory/gftables/44521 b/factory/gftables/44521
new file mode 100644
index 0000000..8445dae
--- /dev/null
+++ b/factory/gftables/44521
@@ -0,0 +1,1486 @@
+@@ factory GF(q) table @@
+211 2 v_1^2+207*v_1+2; 2 1 207 2
+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
diff --git a/factory/gftables/4489 b/factory/gftables/4489
new file mode 100644
index 0000000..2e348f4
--- /dev/null
+++ b/factory/gftables/4489
@@ -0,0 +1,152 @@
+@@ factory GF(q) table @@
+67 2 v_1^2+63*v_1+2; 2 1 63 2
+0Qz0LG0OA0HC0gz0c718P0UD0ti0oj11Z0ck0oF03F0Nk0uE0sO1420Zp0Qq0J60hy0as0dc0EE0wS0UR0XQ0ow0uo
+0Ft18500Y19r19K0fi1830M712f06c0y40aZ0O60Jg0c60RI0IL13J0MG07W02013e07x0Q40Ey0Tn0yp0ex0xz0VN
+0ng0wj04V05w0Pz02B18d0gm0ls0wL0CB04H0ZT0Qf0nc03x00U03j00d1920JC1150X70fC07y0D301u06o0RZ0e7
+0sP10t0im0ie0j70WO0WC0Po0Sb0hJ0RW1860QS18G0qu13M0th06S0Tp0ID19W0i40a61750gc15h0TC0av0aI0gH
+0NA0DB0pm0tD0op15D17o0Bu0K70pb0KY0iw05m0mw0MK0GS15o0HV0gW0n400g02r0iX06T0Ip0a007F0wf0OS0Hc
+0Db1210Yk12Y0HI0WX0840aO10x11f09M0GF1030y10z117P0HG0QX05F0GC0Ol0dQ0E40VI0jc0O50Rl0R30y90Rj
+0MX0tF0Ue16D0Tt1AI10r0Zo0E015v0ec0Ea0lu13i0nQ04q18R0Jh04b0cy0QI1AB0t20DA0Vh1111A204U0TH01E
+0Sk0aa04E13z0EW0JX0qo0mT0730O307Q00q16e0OC0O90Yq0gN0ns0yA0Fs0pp0M80Bh0on0If0fY0ZG02V0A10Ty
+0JZ01Y0be0IU0VJ0ox0yC0fl05S0Gf0L30z20Xx0EU1570ts0YG0lK00a16V06I0Jv0Ve0120II0x50GG14A0Jd0EJ
+0OF18C0zX0dH0xo0zh0Ik0oA0i00Qh0Ph0iz0YL0rY0Le0jv0q00u10Da0H21960ML0uS0Jm0b80QA0vt0Cj0fz0D0
+0BE0C90j20hu0EX0Zc0ut0pJ0q80bY00C0xH0p40wx0kf0Sy0Va0KF0wY0Bw0lE0qG02y16K0Sc0ws17E08e0OK0qZ
+0QL0e00ny0V70up17D0PU0Nd16z0Z60Ya0am0Lc0ih0eC08G09e0wc0v90S10rm0zy0MV16c15b0Ih0gO0R50f10DF
+0yl0pR0V10Ae0Tf19z0Qg0IE0nB05o0gJ0SR0Qx0Xt11j0YO0c80Rp0gB0Bt0sb0r20dr0fx08l0kI10v0M50Q50n0
+0jU0cR0nj0EA0iK09m0hV0c30y707i0530K10xx0Tu0mc0PR00W0bI0XN0Y40xt0JP13A02b0Qe0a70ED11o0vZ0Gv
+0aH0Rw1730870oN0DP10s07p0kU0Yg1440W20uF0j50SD0UF0Eh0uX0Yh0MJ0bo0CD13D0tA1A00Tr18t0mW01j0rr
+00w0EB0gb0TL02S0Gl0Cw0Yf0By0Zq0210l309D07c15114q0pn0AB0Br0n10jO0As0Pk02i12F0qe0Hm0f60xI16q
+0nx0aY13S0eh0EL0Lz02O0c019f0Bo15B07T0Ob0tU0pC15j0vc0Lq0Mo0Sf0CX0xg0Jn0gZ09l0DO0o119h10j0rn
+0yf0pG0BT0xZ05u01D0cV11Q0of18A0Up00R0lU0bi0lZ14C0fk11U19E0GK0Dv0bh0X50Nf0kG17b14e0kV06v07P
+00K0cK0Wg0SW0ek12d17p0f50z903v0hC0jq0bj0tm19N11v0Mw09S0w90wP04X12j11X0Ao0p508z0mD0HU17m0hn
+0jQ0jP0pS0460u60gV0De0Kv1940js0Ry08F0UM0d112w0Cu1770Vi0oD0pd0kv0qR0Mu0zH0tb0M20BS0j60mZ0jY
+0Cc02l0eo0lb0Fn09k0P80Qb0V902m0pO14u12D0nL0Ir0670JH0yo0NU0WW0Pr0p00xn0ip0X30gQ0qa0lC0VE18W
+08o0240lS12h16t0AN0GL0h70is08g0uY0G20Ia0mA0Sw1340Nj0sH0fH0KQ0pE01S00I0330Z50Y204y0Xw0Qv0RG
+0P30U20GH0qL0jj16i0rV0I50WE16p0WQ19P0he0V00Ee17R11Y0xJ0VD0Ie00m0kK13h0fN0Us0v30IN0Ot0610eM
+0w004c0VZ13X13x0Cn10I0kP0Gm0id0wb0SE12508H0if0LQ0jw06O0oO1AK00i13P0Ag04K17U15x03f0Gb0tk14B
+17B18411A0bJ1070dJ05e0oL0DY0Hh0Ix0T21170230690rN0yN0WT0UX1080qW0ka0Ma0po0jL0mH0ps11c0mE0mz
+0p910H0pt0910PG0130Yz0Mg0CT0U30di0OJ0G10hQ1AD0MP0jr0Aj1740gj18M0mt0x610O0ZD13f0vL04G0sD0DK
+0Cg0YB0GD06p0FT0Bm0me0wt0Gy0cM10C0Vc0mI0gU0hm05q0At0cS14x12W09t0RB02N10A0g90NE13y0pB1580TD
+0Gx01h0Wh11M0k60HY0RA0Kz0Ds0dL0NR0wR0T80x30Y614V0FU09p09j0vd0SB0bP13U1A90HJ0bB08O0zw0gX0Q9
+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
+07X0dY0bD15r0jF0Is0Sn06n0dP0lM02a0KR0Cf0Ll06Z0YS0z80uO0pf0UK0AW0IY1AC0dM0pX0Xp17w0ZA0Jb17g
+16T0kn0LH0vK0Oc1400gf11s0T414N12001x03J16I07D0qE0D80S20cv0IJ09O0zN0oI0zt0LM0Rd0Cs0Ym0yr18N
+0IK0eD1800FM0Ov18f0Xf0D40Sp0PV0uk0sp15Q0lv02z0Pq0qS14F0oc0EP0U40cL0qv0gA13Z0n20Ku0va0JD0iV
+0OQ0bE0zT0ZY01I0rO0lJ0QR19s0Pv14k0yk0k80u50m30WL1230Eg0Hp0AY0L20oU0tq0eP00P0DH19S06e0VL0lc
+09r0JR0He0bw0cW10i0rT0SN0TK15m04h02C0Yp0aq10K06M0u009o0Hi0ZO0JF07a0Xb0V204a0bc0mq0ue0I310U
+0Su0KL0it0Ej17d0si0IT14Y0tY08k0dj17c07r0ZL19B0Ln04B0OP0EK16405B0Dt0cZ0wC0VK0P70PQ0Hk03k12I
+0qC0yW0iu0dl0UO0Gt0i80TT17L0b004T0yH00O06k0ym0hg0vV0T90Gj0PE0Hv0ge08M0r50GZ0Re0N00Tq0h60AK
+0750Km10216j0VO0WR0b30bZ19x0zb0zK1480y00cj03t0pe0h218K0Fo0VM0I40xw0Pp0uz0ja0fm0lY1680Je0R2
+0oi07j0Ap0nh1A40xc03A0xY0HR0t710n0nm0rp0te0MD0FK03B00j1310fU0Ei0kW14f01V0BJ0720gP0Kq1550kN
+0900Jl0Hw03P00h0HQ0VX0QH0sG0HK0jK08p0mM0MA0xM18w0xB11r11R11812e0yL0vT0z30hf0Kt0z40sa0L6044
+0Ad0QF0uc0cn0Ch05H0Sq0un0C00jC0Fi03m0Az0GP0CY0uU0zz16P0sI0VH0tX0fn0Hs0qM01A10l0nZ0jy0iL0ga
+18L06g0nY0Y806P0Wu0n70qy0vX0Pi0Vq0110yd0MU0e30Oo0Nq0qt0SV0LL0MF0oR0TQ03L0hk0Mx19c0NC1A60MC
+0Ly0zr0o707q0Cy0sR0kS0W60uA0G611u0Ny0zI15X0q104n0v106E14h1810OD02E09J0g401K0lh0F915d0ma10q
+19g13t0sz0jI08N15C0FG0ho0n311q0r414b0X90oS09V0xV0qV0Z30Wj0tH1130vl0Kh17119L0Xl10y14O0YE0f3
+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
+0lN0fJ0H30my0Tm0eR0LA0MB0dV0jg0EH0vF0tN0Yr0v813o0Js09x0FI0zq0Bx0sn0E117A0RP0Fh02512J16n0hA
+0U70pk1100AO0Ts0uy0H00Cd01R0bl0uD0kz0RM0EY0Xj1820Fg0Q606A1930VR0bk0Es0l107w0IO0m60CA0uT0kC
+0ci0VC0KW0Ka13317e03r0KV03W0ix0nJ0G30B310X00n0XA0PL18E0Pu01816h0xh0SO09s0pl16v0N30Zk01O0GV
+15G01g0kH10a0in0BU0bX12r0Ax0Wm0xq17I0Qu13F0Rh0qJ0Jc0Op0vG0OB0Ou0LF0gn0SU0BH0ae0M00DS02W0Np
+0EZ14j0wM0vN0xQ0Dd06l0z50yO0Xq05X0U10En1040WH0zZ0BA0FC0M30uH04s0Xe0GU0490gE00Z18n0ko0eH0FH
+13b0EG0K90km03d0go0IR0nV0I209q15l13B0mo0rD0nn0BD0LD0eL0YN0Z10RJ13p0el15F0YH0gG17j0GR0S404i
+0ry11e0pD16a0On16S0Pt0fh0R00OE0Ud0Uq0ha0h80hH0zP0qw0cf0Q805O00V0Bf06b0dq0Vm0zl0Ht17k19k02T
+19d02j0mP0PT0YI0370B20vD0kl0fg17Y0170Ow04u03U0vj0mh0UP0x20e10xu0St0E50PC07612o01B06i0LT12X
+0Ha0QY0bN0Iy0NP0Zt0xP05y1220LV17S0f818l19J00117Z0FO0uK0oT0Wy0U00w20Dp0dE0aV0hc0Il0QW0ZW13k
+0s70ty0NV0310o20cY11O0oZ0tZ0U518I0c10gu0H80O70LE0Qy016000000000000000000000000000000000000
diff --git a/factory/gftables/49 b/factory/gftables/49
new file mode 100644
index 0000000..c6810e5
--- /dev/null
+++ b/factory/gftables/49
@@ -0,0 +1,4 @@
+@@ factory GF(q) table @@
+7 2 v_1^2+6*v_1+3; 2 1 6 3
+5BjHclZWJkVEdTb8ILihRYUn7C6NP3
+1eMFQ2KaAOSfXDg94G000000000000
diff --git a/factory/gftables/4913 b/factory/gftables/4913
new file mode 100644
index 0000000..8a08175
--- /dev/null
+++ b/factory/gftables/4913
@@ -0,0 +1,166 @@
+@@ factory GF(q) table @@
+17 3 v_1^3+v_1+14; 3 1 0 1 14
+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
+10j0rD0Xr0Cd08l0bY0jz0le0Fc08t0QK0Eu0uR11X0KE0mn10v08u16O1920cB0Ux0O91Aq04t0Zm08L0tS0bJ0IU
+0ux0Wh0fU0pb05M1030kZ1GO00K0FO15S02H0rf0r90xn0kF0IB0sZ0Fm0sC15t13A0XI0Bg0Y90QJ0DO0Ni0ps03O
+0Mz0Gh0GS0Zs15x0j70jb0yz00U0mV0NK0R30y90GT0HG15K01i1DK0Gf1DT0u518d0M70fI13i0uu11v0pS1Bd12L
+0A40dT06B0aQ0FB15m0vv0EG0tz0vL0dl16409V11P0LT0Jc0P00Sx17r0f30q60G10jd07h0Cp0ln10t0wQ0gD0LQ
+0my0FI0zt0Z80jn0NT0hH0TE0lV1EB0wj1EN0fp0fg0ki0l20cq0Ri13C1BM0n41H40nh0Hm0D30201F80ZA0qH0ad
+05119p0Ia0WJ0LL0B405X1Cs0zF0gT0VK0vN0A60Re0wV0Lp0O114j0jh0DV1A70fv09k13d0OP1F71E10jo1BW0K9
+0Mv0E50Vc14f0eO0sP10D1GD1BO0B207e0d40mU0tF09D1E00Qk1H713T04b0Je0K40t90tm00k0lY19G0qK0ct11K
+07L1Ag0TH0QM16g0JC0oB0CE0Ww0r204G0KT1C410G0Iy0eA0GI0iQ1D519j0E01E70VV0t30FS0BO1FS09401R0da
+15X0de0Ti13B0tL19P03T06g0Yt0yW0560550bS0eL0GB0nP0A90ys0qd1G50A70Nf1EK0hS0Vh1Fb0OV01b0PX0SI
+00407T0uM0Uf0vh0SF17H0tQ03Z0010Rw0CM0lg0Bj09S19e0Qs0jv0YE0nF0Ga0go0Jg0PT0VF0hM0zY0nX0vs0mm
+0as0wR1Gj0F90EZ0tP0VA14q0WO1Ch0wx17Y09P13c0AA15N1Dv12P02X0s60VM0x60qV0OQ09F1861650YI0Xc0s0
+1EF0lQ07G15k0gb1H20at1730Y41H513G0oc11F0cd0cV0WH19E1Az0cN0520rn0cY1F41Dt00p0js0aC1010yd0jN
+0bN1G40QF0ZC0B30XS0AT19z0RF15T17u0PM0l30HE15w17C0oW0V507Q12z0XL0yV19v0tC0rp06P0fm0sq0s80DB
+04R0Is15H0j50oV07917l0wG05Q1AX0pr0i60Rc10g0eb0qq08Q0IC08z0470QX18v02s0ej0Oq0vx0mB0eg17y1C1
+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
diff --git a/factory/gftables/49729 b/factory/gftables/49729
new file mode 100644
index 0000000..aab125a
--- /dev/null
+++ b/factory/gftables/49729
@@ -0,0 +1,1660 @@
+@@ factory GF(q) table @@
+223 2 v_1^2+221*v_1+3; 2 1 221 3
+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
+4CF74B0tW5i7A4gBOFC2Z10Z7Em01n3hQ6uV8vy61I8apCUw24EAUK000000000000000000000000000000000000
diff --git a/factory/gftables/5041 b/factory/gftables/5041
new file mode 100644
index 0000000..210e65b
--- /dev/null
+++ b/factory/gftables/5041
@@ -0,0 +1,170 @@
+@@ factory GF(q) table @@
+71 2 v_1^2+69*v_1+7; 2 1 69 7
+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
+0cu0140Tb0ii0Vr13K0Ej1Av11h0Ql0a51El15R16K0HB0Sx0ad0ZS0q018z0LQ01e0ME02t0l21Bb0GR17n0Cv0mZ
+0Za0Pg12i1840wm0TJ0zk0X70yk0cX0sM03J0vC0HS1Ay0yZ06p0KG1Bv0Kd0ZP0Um0cU0C60CK0l51Hs0yK0D716w
+07r0MD0zH0Lc0X10020vQ0n514q05D1HY1Fo03j03S0e20Yw0eQ1Ba0Wk11G0OK0380SN0o70c20FI0rN0gz0vG0PO
+0es0R00zX0ah0Ps04f14u0GI1FT0Hm0lI00M0T30lC0xk0Fj07C0hX0gO0Yf0IW1880fG0vL0Xb0nY12V0QW0il05u
+08C0R90H119E0AI1F60pD0La1Cl1H719R05m0nb1810iv1HN0Or0C51G90CA1Bd1Da0Kf0HQ0cA19t0Qm0a80830WG
+0tO0Hf11P0Dm0qE0Yt1Bc06M0bY10u0UJ0ZJ1E80xT0bs0ri0ot0uh06U15q0gl19x0wU16c19z17J03f0m700O07D
+0P912C17G12n19y0mL0go12G06H0yY07818d0b301K0k21ED07w0t60K51Bm0Nn0LU03X0W700g0D00GW0Av0Dk1E1
+12c0XJ17701C0Qs0jI14X17s03H17R0xc0tE1EJ16o0yC0FJ02r0Lb0uP0Oq01B0Lo0s70CN1BE0Cz0k40CZ17b0qU
+1920o616a0yN0QM0570hG1JE0HM0UG0Ih04a0t812t0vu1C107P0Db1Df0ks0S21CC07k0te0TX0if14W1B204m06s
+0Hc16X12y0BX0GL0N10wM0tP0zn0Ay0jN08j0vT0441GQ11z08x08801Y0da1GI0bR0JH0jD0xM04L1601AR0h8148
+0QS1Hc18l0WA0Ey0750Xa0Ib0nE0pq1Hf0UX0FL0II0mt05B03y0OT19w0mR0561B80180dI0CV1DS0nJ1CV0Nl0so
+0Ep0FN0PK08Z0xG09D0hQ0Kt0ib0jq0QD0Ef1IO1FO0ji0Hp0VK0Rz0oS12N0hk08h0Me0me14r0fi0VI0280Se0VM
+0dW0pk0SH0rm17u01w0E10O70eR0Na1It07j19m0b812d0jt0MR0T61500I406R0er1A81EI0Io0ZV0wh0QN0330U3
+0L216g0GE02Y0O80Sd09H0S006918j0Cj02j0D10HL0nG0ZX16s0g00bM1A30T80v611C15e0D40iF1C30cc1A40Hu
+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
diff --git a/factory/gftables/50653 b/factory/gftables/50653
new file mode 100644
index 0000000..65d8176
--- /dev/null
+++ b/factory/gftables/50653
@@ -0,0 +1,1691 @@
+@@ factory GF(q) table @@
+37 3 v_1^3+6*v_1+35; 3 1 0 6 35
+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
+CNv3vr8sL88124IBkxBfj9MaClj8bLC9v0Mh000000000000000000000000000000000000000000000000000000
diff --git a/factory/gftables/512 b/factory/gftables/512
new file mode 100644
index 0000000..f66cc3c
--- /dev/null
+++ b/factory/gftables/512
@@ -0,0 +1,20 @@
+@@ factory GF(q) table @@
+2 9 v_1^9+v_1^4+1; 9 1 0 0 0 0 1 0 0 0 1
+264C6m098B5J150I04877a2N2E2A220a5V086n7z4w6v5R4k0u4S2I4K7T44
+7q1A2v2l3j0G635L3S7j0q1d5y5b502d4r1F1v1o7K0f3d4a6a0P1k6h7Z88
+2h7R4F2K485q075W4E7S4L0W3X3r712R0m6u4x7D671g2b3G5d3h5i2x6g1l
+1W5G4u1T6p2U303q3Y3c0g6P2Y1K6C7G4R0v1S4v800o5m3U7o597V6t0n81
+6e5O5k6d820F3k4e8E014g3R5M0E832n7h0D5N6f2y0R6r125B740C7i3T5n
+1E4s4I1Y4U5Z3w1f686B1L3z0k3M735C0z6W3p310Y7O2C3B7c5u4p57523W
+0X321Q2H4T1Z2k2w5j5P7C4y78606T7g2o76667E3y1M6N4Z3e564q2e5p49
+6k6H280d2P1q3t2u1B1b5g7l5f1c0r3J4X6y1O7N0Z236G6l4D5X2j1a1C7n
+3V534N2X6Q3F2c51587p450U437U5A133O8D4f023n17116s7W2T6q0S197r
+3v5a5z791j0Q2z2V6Y553f5w3I0s7u5T6F244B276I5t7d0O6b7B5Q6w2r3L
+0l2S7X1V1m0L1H366L0j402t3u7s4W3K2s411s472L2g897y6o1U7Y6i065r
+0c292F1y344n0N7e4c620H163o6X2W4O0i6M1N6z3b3Z7M1P331z7J1p2Q72
+3N145K644i2q6x4Y6O0h4P386E5U0b5s6J3D1J2Z6A692a1h6S614d3l3Q4h
+65774z5c3H5x1e3x7F6D397w7Q2i5Y4V7t0t4l7I201x2G1R0w5I8C3P3m03
+0J5F1X4J2J4G1u1G0M4o5v3g5e7m1D5o2f2M7b3C6K374Q7H4m351I3E6R1i
+7A6c5l0p7k5h3i2m846V10180T461t4H4t5H0x0B752p4j5S7v3A2D2O0e7L
+3a703s1r420V4M546Z4b7f6U855E0K1n1w212B7P7x8A0A0y5D86056j4A25
+8G0000000000000000000000000000000000000000000000000000000000
diff --git a/factory/gftables/51529 b/factory/gftables/51529
new file mode 100644
index 0000000..5b64940
--- /dev/null
+++ b/factory/gftables/51529
@@ -0,0 +1,1720 @@
+@@ factory GF(q) table @@
+227 2 v_1^2+220*v_1+2; 2 1 220 2
+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
diff --git a/factory/gftables/52441 b/factory/gftables/52441
new file mode 100644
index 0000000..285b071
--- /dev/null
+++ b/factory/gftables/52441
@@ -0,0 +1,1750 @@
+@@ factory GF(q) table @@
+229 2 v_1^2+228*v_1+6; 2 1 228 6
+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
diff --git a/factory/gftables/529 b/factory/gftables/529
new file mode 100644
index 0000000..05f7b0d
--- /dev/null
+++ b/factory/gftables/529
@@ -0,0 +1,20 @@
+@@ factory GF(q) table @@
+23 2 v_1^2+21*v_1+5; 2 1 21 5
+2E5P3W4b6B5Y4Z3P380i6i491W0W7x7F4C2h4N6h4K0l066y5B815w685f0h
+1g3r0q3d1e1P0x2W5R5Z3c753B2g6T538N6C5005198U5F7I1m1q4f3n7J7s
+572v820Q6w8T621l4E5X4I3U4t4A0B7Y3p205O4M4u7O6b1j1M2e4j3o7f2V
+8K3X0G1r1h0O676Y7W7G3D252f4h0d072B6c7T5L8I2w8H4B5p4i0n224L52
+0T2p0b1T046J6I32843J3w1S3a3O852R4z8O2T7m455q2F3s5b601n118B7a
+4a4R0a7d7r1K891Z8M7L2n7R1L3I2Y5J0z4e407D3F2J0X0g4w1Q7h2H1s01
+1I1C701d4W5s2l585D1k6q2i8C5a3C2N6s2Z61331N5r1i5U8A6g3q3V6k3Q
+5h8D7741167k876W3S7y8J286l5E143E1O1t4V7o2G8E4g5H1U6L6R0c7l1A
+6n7Z6f7N7g803t1F65637p5j126p516U1b0H0j1x5K562t8X7A0s176H544d
+5y2M0u2j5T1f3m21245l8Q423j3R2k3f2u5o3u5I2c2X6D1V0v4U73460o6j
+6F865x1c3A744k4Q8R304c4G690Z3g4n2I023N090V3M4r2C6x2b6e8L2o7t
+3h7j032S55883l7C2A268G2s1X7B436m6t5d7V7v4q76276O6G830U4T1H1w
+6o2d8P0e7E4p0C4l5n7X5c7K5M596d1z295A5m797w3e3G1Y8S3Y1o5W0E6A
+2m0F5u1E1R7q1p1D5z0y4F4H6Z7z780r72362Q087Q2q3y2L6S186V3Z5i4s
+0S6v7S31100R1a5e5v4y4Y7M0A0L7H236r136E2O3K1G8V0N5G643b34470k
+2a6K7U2y3i2K394P370f4x7P5t7u711v486u6M2r3k0w0t6Q4O7e0K7n4D5Q
+7c4J5k1y2U6P2x4v4o1u0M0p15350J3L1B0D5C5g5V7b4m6a8F0P3z6N442P
+3v6z7i0I1J3x6X0Y2z3H4S5S664X3T5N2D0m000000000000000000000000
diff --git a/factory/gftables/5329 b/factory/gftables/5329
new file mode 100644
index 0000000..0b386e2
--- /dev/null
+++ b/factory/gftables/5329
@@ -0,0 +1,180 @@
+@@ factory GF(q) table @@
+73 2 v_1^2+70*v_1+5; 2 1 70 5
+0v60jK0Uk11p0pC0010xa1Ej0iz05T0xZ0i90IP15J0Oo1Hg0E70qX13L00v0IM0Ah0PD0aW0di18c0HL0Ii0zv0BN
+0Hw0SZ0B20A203w0L30JQ0bk1121JL0VC0fa0Oa0Qv1L70sm08h0le1Fr1BN13G0A01An0eW1B30GK0Mo0YE0lr0NT
+0gm0uu0dj1NA1KE0nv09S0zH0et07J09c0790hA0Gi0uL0PQ0El14d0IA0SG0361Fh1LC00p11r0j20Yj0520Mn1B7
+16v1351C70rT0Ro1Il0KE0dp0YQ1LG12J0Si0wM0BX1EI0md13j0Aq1Fj1LX0XX0em0ST0cb1G20gp0OD1L00Vi0mL
+0JE13h1Fb10L0h70Kx0r30iM0kA0ZD1K10K01DY0qL0P20ky1A818Y0E10BF1Bc0Fq1IM0gw0Gb0h01Bl1Hy0xX0w7
+0bQ0kI04M0a61I90BC0WW0dP0B51Gt03G06d0Vm07h0b41Ae1NE0P51E704F0bZ0b710000Z0HA1IS18k0pU0VB1JO
+0Tl0C804Z0uW0Yx0SB0tE0RA12C1CH0FZ0rv1G50YN0lh1Go0zl0j30JT1IW0lE0kd0KO0Er07L0jQ0Ut1Af1AM0N1
+0WH0Rq0f21MA0Au14n0Pn0LH09q0oy0n511G0vz0Aw0wY0vb0kE0It06u1Js0Be1Kk0p51Lz18p02x0oo09x1EA0VX
+12B0gC0T40g10fG1Co17N0jA0d91JM1Jo0ty1Gh0W80U01FJ1E20Az03Z0UU0Aa1NV0LY0kD0Zw0DD0I00u10HB0dD
+0nB14z0Dz0Qm0WQ0dQ0C30YV01h1L50200Xm1ET0XW0Yn0ZC1D50Zk0RB0hk15e0IX0k70VP0Lz0u604Q14L0Gk1HB
+0rd1L40hv1La0JM0Ye0YK1Az08y17G0vo11N19n19q17P0bn06g1C808X0K60rF13l0xJ0mo0RI0so0X01060PH0Cg
+0Zn14B0iu0ZA0p80a40t51Ak03S1NT1780Ou05f0ox0Op0Mf0LD18908r0e60ig0LR1Mb0T00VH00l18A0DV0Hp0c7
+1Am0mC0pb0AF0fu0pX15c0Os12o0RS0ZZ13W1AE0KC17b1Hk08O1GJ0kX0Nv1AC0OX0C61H30lL0uH0xv1CQ1JC1Do
+1Et0RQ0Rw0V514O0K31Ij13p0Su0no1BC01Y12v0Fe03B01P0Sh0bi1BW0KN1C60QK0Q20bX10S1F91NF0180U813m
+0240Io0PP0nQ0NW0qK1Nk0tI1Cd19U0i21Nq0J01M01IZ0sH09X01B0ak0Ri11C0UL0I90J60tU0Bs0eo0sq0Em0UN
+0ZH04i1FM0R111E0Li14K0G30uM06K0N20M404r0Tw13o01p0Je0YJ0121D80Vh0AS0Bx07I0Q010c0vw1Br0G207z
+0qp0tM1E80uA1Gv0kn0ds0Fi0Fx15h06116M0zn0xi0mW0kW0ry0ev0yw0Kh1Gw1H90kj0zx0gt0mN0tk11u00A0h3
+0qc00O0y61Hf0J40uE0BM0cC05u0Gz1Nb1EE1C313V0tv0OY1F70jq0J80r70ms0Tu0sh0Xd0mp0uZ0xB0DJ0Am00S
+0ce0qe1840Z00A10GC0Dc1EZ0Yh1Au19G0TY0XO0cu0T11JS0fS1Dt06O1KV10a19r0Ms01X0RX0641Ms16312I0ui
+0OW0MU0dx07x0gg15u16o19W0yv0nq0j803I1KL0FB0sC0v00N00MH0UQ07E01G07A0hG0zT0R000o0UM0pD05V0pi
+0GJ0PR0AJ0LC1CW0CI15z09O0bx1Dl0oj0Jk0MG13B0Yv0Ax0Wq0wD0Gn01I0HU1ER0T505o0j10Mp1Av1130pW0D3
+1AG0Mh0PM05P0Ol0FS0m91Ir1770Pj12p0Vc03y16t09P18g0Dr0tx0WF0UP0iU13r06s0vx0Xv0e00IH1Np06z03n
+0lp0DE0v40aj12A13e0TJ1JU0HM1M50760vu0Yq0Z11Dx0Br1Ln0SU0k40CM0dK0oz0PU06v0HV0gE0LZ1I41IY0bl
+0Dw0AX07i0un09I0qP06y0u90zq03H0o001A0Gc12g1AL0AH14c0dN0wH1EF03x0EP0Sk0Wd0HO1Jn0xH0U61JY19S
+1Fk1EV0GH08u0yO1920pZ02y1Ds0tP0ve0hi1CG0mE0AN0oC0zD0IV1Ev0WE0dL0ZI02C0OS0Qg0Tg1Bs0Fp0wO1GX
+0mP0NJ0Xn0fl1821CR0Ed0tF0VZ0jz0tC1Er0X40ns16T0Ea0WS0ok0F40Na0sk0HW1NX0xe00H0o918m1311410PC
+10p13D10j0E404V04t0Kq1Bj0eY0Ym08x0p90aH0G807U10Z1Mf15Q1Ax1D70Zd0fy0pR0y30rQ0l20QV11U0lI12c
+1IQ0Im0Zr0lk0Om0Ud0sE0om0x60Gr0NA0pI09k16I0nC0TK18e1Dk0iB0oN18513I0Ci1Fy1Fp0Bj03p0G707p0jw
+1CF0T30pc0601Hr17w15O00K1GI0TZ0fJ0qA18b0Qk1JI1HF0sA0bg1Kb0TD14u0yn18T0hy13s10e0Cw0MY1Hb0qQ
+02G11T0YW0rf0gx0gz0Kt0eZ1Eg1Nu0Ai16h1FX0ws11o1M403s0Ak0Td0901Jk1Cn0vt05701W0S106R16O0xI1LF
+1CM03A0HZ0A700e02u0kc06D0PL0sl0SA0wy1Es0F00KJ01f0yl1AT0RE0lz1Fi0R20Un1En0vN0ro1AN0of0rW1DJ
+0kZ12L1J21II1KG0RF0380zW0jO0xf00D1IV0DB0XB0qw13K0UR09j0sP0Lo0ZT0Og0bw0id1Kt0t315W0aT1CC01b
+0EX12S0Wa12q1EH0kb0860dn00V0Xg1Gp11t0EN0JP1Bn1BX0RV06Q11Q0zo0Kk0Wf0Fd0GY0b10vE0Xo1Bm14F16X
+0Zb0vg03k0aC0xj0Ca1Dq09w1MM0uB04s1FD1EQ11a0pd1Ay0eB05k05d19H0sX0vT0mB0VG02z0Ei0CJ0gn0aY0FY
+1AS0F30gr0150Xf0ay0jN0040h90h502S14G05S0tS0w80dO1Nd0ow0x10Pf0Qt0IB0Z41Lb0SR0VM05p0GM0Bl14Z
+0nD15b0FX0AM0BU0KL0ab00U0tw0U504D0pF0L202811e0Hz0fs1N318X1JP0Qn0WY1F30d50Ry0OJ0ey01D06q0sf
+0Sa0Z203519T1Lf05018D0zk15M0Mq0bm18n1DG0O006E0Nc13y0TP0DQ0RP0z61BK0vl0G60us0BI0bc06m11Z0D8
+0AG1150qJ0p10Gq0Vb0Lv0L40UG14Y0Qo1501HR0yj14g0zN0dv1CJ19Q1Ll0sr00q05q1Ec0i41Kn0YD0Or0DF103
+0z817s15Z18d02K0gV0qY1BU1Lt0w60cA1K602D0HG04R02Z1Gz1IL0OI01z0b30Ge11c0yW0k90B30ov0wm0Uv0sF
+0Dv1Nl0S41Jb0hR1Ha0p60I40HI0jl1690N40zM01C0Wn0mG0GR0H00SF0En0GU0Xe0U41LV0Um0030EI0Ky0EF1I0
+0iy1Cm0Y50Tc0gL17H0V90nf11R0fb0Sn01k0Es0JI0to0q10ca0oe1Cl0uw0O20fL0430AT0tb0M907Y1E10Xu0Wr
+0tZ07H0S71Jw1Mh18L14J1AP0cH08S1Mx09F1NC0hb0r61A90yu1Ig1BD12312a0RJ0Ev0o50BP0oJ1BR0kY16r0Sj
+0dU02e0Ik1MT0m01FO04E0wl10T1Ag0v20u008Z0OO0HS0av0yr0xA0fU0zj0bT0y91B91BZ0Ic04o0f00880gu01y
+1LZ0vF0h20ED0iL19K0we0pA03r0Lq16i0LW05m0fF1K20Y61180AE0Ma1N40VD1HS0Pi0rh0kr0k10De19a0Ni0by
+0LS0q90ib0bt0w00TV1DS16d0bD1NQ0g90wU0Oe1Nn18B0TW0bM0a20Ug1190TH0u20AY0Jq16B0sK0Iy03m18K1CU
+0XD0N30VW0mv0rJ0wW0VK1Ku13T1K30nT0Mx09B1MI1510V30tW0gf1HC0W50iS1Fn0Ex0Jf0Mv0Hg0qs1J10ta0Ru
+1BJ0hn0Bu0uO0Rm0wE0hH0OR0fi0cz0920Cr0TA0A912t0630pQ0my0Ok16p1AB0Sx1Kd0YX1IO0ri04x0GF0iw15H
+0ih19m0mA0nk0Ja0oT0nO1900rU0uv1AH06F0X816409t0yf0Rv03W0tX0Gm0ap07B0Av01q0VL0GS0ZG0PT0mK1E4
+0ax0TL0wv0xc02V1Bp10v0oL0lm03F0Ee0nL0Ww0Jw0Us0Ez17g06909E1571KF0z20xu19V0IJ0sN0iE00I0FH0z7
+0Ng16f0aV0bv0Q80bu0kS1DL0Hj1C00O41DB0Xy0ur0aN1Bv0b902l0lM0z412z0dB18j0DR0gk0MA14W1Bw07o1IG
+0Rt01d06a15g0H408U13i0bW0hC0270Tt0yX0Sb0ud1A70tq1HL0fV0aL0RZ0TB0wP15k0ZO0zP15v0xw0mt05K0lf
+1GG15E0os0a30Y815X1MZ1731Cw0YY0Pk0Gs0A500w0e70qG15a1AF1N90LE0ql16V0c00Ns0q813w0Ac0BG1Bu0NQ
+1010ai12f0KH0680Mc0Qr04W0Ij0uG0GE0ek0ZB0ou1Kw0vS0F11Is1HU1GT0tJ0371600Oi0ww1I50JS1HN1720YT
+12O01j14i01M0vC11x0SS0T71B619b09Q0qH13Y0M111H07D0rM0QF0iR02A1FL0Vs0db0bq0BE16b15m0801KJ019
+0rH0mT1H806I0Ek1C10OG18Q0K20ly10Q0260dc1If19g0Pu0kx1NG0m30QO0Vr02j0KS06i02i0ag0H90ON0In00Y
+0n118W1HK0Du1JK14T06T0970MX1GY0Pa0Sg0OV1Kc1LL01i0OK0zO1FH1Fd0el0uc0VN0eI1Fs0ME0Js0t90Zf0pj
+0uN1AO1KB0Ig0ma0mj12V0gY0yV1G60VQ0NF0DL1Eo00E12j10u0Ch1BS00u01S17E0aG0cL0ut1Ik0QS17c0yD0jC
+0Wg0af0uj0hO0zQ0uJ08Q0rO0Lx0WC1530jp1IB0tV0ya0RL0kl0d00Yt1LH01R0Po0AQ1Ng08V0Rn07C13q05I0sg
+0Ys04h1CN0Z90Gv0I504P1GP1AQ0BT0du01g0Fa0pr0xG08l1LW11s0eh1Li0Yg0eb00y0zB0Hr0sa0yS0nu14a0qI
+1L10PV01K12E16m0EK0JR0510fW17L0560Sm06f0OL0QL13k0m10U71A60m20q21MW0cp0cP1CA0g71EM0Ff0SN1L9
+04y0Cm0RU0Hq1KW19p15P0jB1140g513Z0n70as0mz15w0r913t07b0d71J90sL0kL0vv18610w19B1GD0xR0vm0Y0
+0Af04J0KX0Qb0gA0TI0Dy0fT1JJ0je0kK11S0581LO1F10mQ0220mn0hp04m0SC0Jz0am0W31L30pq0r50XZ0tr0xC
+0lw0130SX0Pr0hr0UV09b16l0iQ0Kz11f0GI0cq0nR11700j0Eh1Ga0WA0MC13F0yk0N603U0hm0eF0ep0PS11F18N
+0Xw0zU0Oh0nZ0wi0Zx11g1MY0KU0jF0461LQ0Qx0au0NB0UT0tg0Jr0jL0wu0wh1Ek14I1I10og0t11GM16714w158
+0Rr0MR1Jc14q17C0AP0pP1JG1Mz0nb0iT0m60Sv19v05A0wR01l0SM0uX0sn0k21G10zA0aZ0c80vV1950My1E50nE
+0tA05X0Gl12k0PJ0qj08q0SQ1D31Kv0fH0ct0nt06Y0Qp0Ds1Ex0Ep0QJ1FG10d10M0vM0kw0LJ0P61FQ0Q507l1DR
+0ah15n1H70dr1Mv1Gc0CC1GV1CZ0Ls0lb1Eq0ts0oY0Mw1Lr14s03a0WM03V1Db0yb0Is0Qh0vy0EV14o1HZ0PZ0B7
+00d0Qi1Cu12N09H1L60Sf0HX0Kf0j701U06e1DF0ez1NM0do01707f1JZ0As0Xp0uK0qo0Ve0CL0nG04T0x30Eo0sj
+0py1ES1Mi1Em0rr0fD1Hp06A10m0l70D614C1CP1Hd0jh0ol0Uz0kp0f703X05Z0pO0sQ0TT0wX0if0eO1FT0KW19x
+0fe1EO1LS0x90r01Du0lX1FZ0sc0GP01000Q0po0RC0gq0zG0SY01v0NE0v90An0EJ0h61Bo0Co1Dw0vs18I0Hd1D6
+0tG0vh0nH0DP0st05M1Ch1Jx03o0Zy1Aj02m0yH0gB1Ki0Mj0pT0XM0ng0VE0JZ0YZ0x80Wy1G01Ck17t0dk0l60cw
+16x0oH0By11O1KY1Cr0JU0Fo1EK0BY0SK0JH0vD1Ld1EU0ea0ix0e817u0eT0XR0YG0iI0vp0ij0sb0cv0UJ1360Ce
+0uR07V0hl17z0Yl0SV0Vg0I61Nh0uQ01J1FF1CI0ip0ef0Yi0k518E05i0GN0UI0dG0OA0c61AR03T1It15f0P30uf
+0n40TM0Lj1Bt0Xs0CF19A0VV0RN05L16S0e41D20aF0t417k0cS1BG1Ju1D01Hl00M0Cb0c40l302I0Ih0Kp0Fv02O
+1Hx0k80wd03j0a50a00jY0bH0on0p303e04H0zd0dE0471Kj0nA03f0WK0AZ1Cx1790p40B60lo1330fQ0Jo0um1MN
+0M60Py1Jv17d15R0Hf16a0P80ZP0gi0z51280KG16R08209M0Wb02d1DM0zw0uz0161E60Ju0pG0hE0Gh0BR08R0n2
+1Gd0Qs0HN0J71Dz0Xa0ub0340GT0er01u07c1Gn0jM0bU10K1Bq02T0Zu0s416Y0CR0B404G0jT0FF18l0AW0dC0TR
+0ZS15A1No0w20Ae0aE0ze0jH0Rg13d0Px0u304A0jo1Id0BD0wA0kC04p0s50nz0Sc0U90JL1IT0Ml17K1160gK0dW
+0nN18U0iW0Q30aQ0Ob09J0Nd0rG16Q1GF1KK0Nf0CW0bE0O50Hk0aU13C0w107n0BH02c0f40Wk0Fw1AK0P40fv0nF
+0aB02a0NP1C40ck0ul1Ad17f0hc0l01MK0js0yE0Km08A0pw0SO0rk0EC00N0Nm0sZ1Dh1M30zu1Bz0PF0fM0Vj0Wu
+1MR0GD0Cu0vL0fC0XJ0sW0l10Vw0QZ0fd0kg0Fg1Gb1HJ10s1Ey06P07W1KZ0j512112u0AR0H60zY09g0UD06r0Hy
+1870CH0W90i114X0w30WR0WL1751Iu0qN0Se00c0gF0Th0JW0Sl0Qu0Vn0210q01A50eH1FP1K00aR0up17o13b066
+0811NH0K91F51H20ki03M0BO0zI0Bz0MP1M90EO0Xq0wN12s1Ca16N0DO08m00r0is19X0Bi1At0lq0lU1DU0hh0cT
+1A00VI0LF0iJ0Nl0Np0vU0ia18s0Hi0Xx0ZV17p0Zg0G51Ai0cR1Be0Ko1EP0Yb0EB10E19J0ik0XQ11n0ls0xo0G9
+1FY0XS0yT0Bn0eA19M0GO09n0zC0No0rt0F20MF0OE1DA04j0zV0Rl0bV02X0Gj0Iq0kk0ny0Vl0Z31Ja0vG0rm0LI
+05h0fw1Kq0kQ0TU0Ho0Nx0PA02o0Qa0D712y0Mb1JN0Dt0x51HG04w07Z0Cv1Jh0V711M0Pz0QU19s0591Ba15l0OM
+0mf0RH0Xi08i0tp08H10t1Dv0GB0Hu05t0AA0Oz05c0Va0ZY0FR0q70Sz06X1Cz0WZ10z0RT1C50Ny1NL0QW0yC126
+0dA0HQ00X08o15x0i004z1110TX0jf0nh17O1Kg0Dx0Vo0cn1N11Dd02F0Q40fc12Q0F80Ga0mS08G0lC0XA0tR07s
+0cB0ZK0pN0DM0xh0NO0CE18w1Fx0R70Ey0nr0zs08312U1IH0ra0nw0gs0GW0JF0vA0051Nx0h40EE10G0xY1Nv074
+0Aj0bR0Lf0pB0J50750w918J0ZE0SE0tT14e0H20ue08k1Ge1JW0pE0Cs1EY04f0pg05x0y20wb0Ly1N717a0jm0XF
+0ge1KN1DP0vZ0eN0R607Q03P1BE0Kn0mi01o0Pm0qa0iK0zE1Kz0M00I718O0hI15s0W419P0L01EX0X20oX1B00AD
+0xU1Hc1Df0ni1760sI0o21040yM0YB0LA0qV0E80qy1Fz19Z07216g0QA0W00nW0UK18t18P0Lr1DZ0eE0vP0q40nS
+0br0Hh0wS0e115C0Ne0vk19E0lT17q16e10W1CD05E0ff00m0oU1460Cf0GA0eV1Hv1Ee08w05j11m0zg0lV1KU1Al
+0Ka0nl0YH17I15K0y80D416w0KP0sx0zZ0Uc1NN0v10Jm1Gi0at0zR0JB07G0NC1Gm04B0Ul0Lh0xb1I20Zv14H0XC
+1Lw0WI0zc1JE0TS1J51HY11K0UZ04I0HD17V17S04514y1F20Vp1MF03Y0ZM07N07k0Wo0va0VU04q0km0si0xL0SP
+0Yd0Ow0IS1Hs0yR0iH16U0w50LT0vW0nV06w0dH0bL14M0jZ0sG0qM0Pw0UA0HC1Kl0gP0bp00i0WX0CT0mR1GE1BM
+1DE1401EC02p0l91DC0D00fY0Tk1Gx1H40Il0RG04l1Gq0wz0Uu12i0rc1Ez0uT0MQ11v0vH0Pp0Ox0620hX0sR0rL
+0bz0Nu0eM0df10h07m02k1Bd1H108B0Fh1IR02P0IZ0y511P0ji1I81Gy02g1AW0ZL0NH0jR0b60Fz1990ll0zb0FE
+1Dp0DS0td16G0Ln07S0jv08c05F0VJ0YI0IR00R0Zm1940oG1Ls0B103i1Ao0Y911i1IX02w0oR0x70te0Jx0R91MO
+13f1A11NB0yU19e0iO0eK0UW0FN19h0vO1Ah1MX1CB06j0Wi0Bc01m04b0PO0Vd1910go15d1GS1Ew0CO0GV0rC08e
+0Kd0xd0h808K0qd0Ib1CS0SD1ED07t0OH1Mo0xF0Ki0mV0Ts1M71G701x0xE0XY11z08I0r20xr0zF0VR0Gy1Ml0pL
+0an0PI00T08M0fo0ua0ot03v13U0q60Ji1Ke0d816D14U1E00fq0CG0vc0yd13u06W0EZ17A0dR0oO0KM0PK0cl0pz
+1Jy0wk0vR0Vv17h0Re0Oc06G1Mu1Ce0WB15D0V40XH0ja1Da19j0m50KV17U05B0Sp0Bb0yq0Et0Wz0co0yN1K90rV
+0D50kf0s003C0Pc0sD0rb0F50Eq01L09d00600C0rn0Mm0AI0i80qW14418z16s0qU0BK02M10q0oc0i60dM0kH0be
+02r0YA0JV00h0dV04Y0Wx0tn1Fq1Jz0Zj10l1MP0cV1AI1Hw0Dj0LL1Dg0WN0jc0s90bC02s1Ct0441J31590uV0Z6
+0Ay1NY05a09l0dF0gD0qE0LQ0oi1741Kf1HV1Nm0Z508s0wZ0La11k0UH1JR0480Jp09y0N509Z1NU1Mg05n0ZF05U
+0AK05y0ft0n30Me18f1Hj10y0fp15G18x0eP0m70Sy11V0Ft0Ya04a0Cl05Q0Za0eS0hj1Me0Ot00L19I1Ky0FV1N8
+0HK1CX0mb0850QC0se0cg01w0tj0lx0ei0vK0Kw13P0FM0Nn0LN0fE17i0aS0O30g812x0e209L14V1100NR1DT0sB
+1Ip0Rc09D1HW0ID0qm0rN16n0L50i30E20gQ0JX0Ph0o10gy08F0cZ1B50i70730BL0PE1K70L90I80wG0uF07u0Dd
+1Lk0Hb0CY0kV0fI0X613x0E30Tj0x40ko08D0Ks0ho0pl0hW0J30Lp15r0QB0vY0GQ13S1Mm0K10NY0141240mq0yt
+0sM0780qh08L0gc0xy0sp0CX1C218v1K40oa10i0Vt0gR1IC0s812d1H60lB0YR1650Pd1IJ1AV0SJ0hK0vB0070vI
+0Yf0pf1Eh0IO0Nj0ii0FU1Di0gU0kR1450ka0qu07r0l80Zp04k0hV0zm1I70jX1HA1DO0F60PX0UY0Uq0jU1IU171
+0jE1661J40yo0IE07F09e0pJ0hS1Km11D0LB1Hi0XE19C0xz0Nh0Hm0ie1FU0dg0Q706l05D0Tp0kh0Ej0NV0PG1L2
+0uS0RD0xt0ej1Lg0Gw0DK0IT0rs0oA0KK13H0c90Zo0ob1FN1Ko0aA0Zz0bB0lR0O70Jn0n90ZR0ju0Rs0S60EY1D1
+0Ov1Nf1GO06C1KC0qk0xN0Eb1Dn0rw0X505N0S90J11I60Uy03R0dt0Wm1Iw0AO09p0DN0x21Gf0UO0Yu1Fo01r0mI
+18M0uP0Ws0JD08d1A20XU1El0EH0cd13Q00P0Dm1Jj1MQ0ux0Hv0TC0Ps03b0N80Lu0r802906t1E31MH0ys0E00Iz
+0wB0Ie0lG0re0zL0Xk0Gd0Fy0pe0Bp18H1Nc0CZ1Kx1Eu0yh15404U0SH0Tx0mk0fj0XV0eg0SW0Gx0Oy0pn09m12D
+0aa0Nr0cf0Jj07d0Jt0aM0Ct0Xt0G10cG0gh0rP1Cg1ML17e0zr0s71NI1Ab0lN0D90jD09T09u0tc0N90JA0hF01H
+0JC0aw1LU1JV11q00210J0ed0Cp10H1Ei19c0e90Zc0wf1Kr0sS0Nk0c30LO0Vx0Q61DK0Wj0wT0CB06H0tK0CK0ZW
+0tB14N0Ux0NZ1BF0xM0Bf17B0iD0oD10A1Dr1Ci0710kG10X06n0Qc11B0bo1371Nj14S0vi16P1Lo0xS0tN0700B8
+0Iu1NR0Wl0Rh0qO0I30dI04S1IA0Pg14f0Sd0Xl0Fk0T60930550Hc0We0g41Mr0rE0TO0Ar08n0fm0xx0xQ0k319F
+0ZX0bN0wp0nU19y1Jt0490oq0XG0FK0bI0LX0LP1FS0t20jG0TG0Od08a0S51Gl1J80or0DI04O0Te0Do0oh0oM0YU
+1LN0ym0uU0tm1Lc01s1Mj0pm1Ji16J13g0dl0sd1BA0qf0hs0MO0xs1G81Lj1EW0A81071481Ht10B05O1Ns0Lc0wq
+0KY1NS0jJ0sJ0DH0zi0a70Lg1Hh0iA1Lx0ln1CT1420qx0MJ0R80yx0uC15q0fh0gX1970Bo0Da05s0pM1080IU00J
+0RR15F0bO1K50dh0QR17X0jn0lJ03L02h0cD0VT0za0f10zz0cj08p0hP0rl1Hn0sV0XN1N60gT11X0To0qz0s10tQ
+1DW0W20vX0PW09o0FO1Ep0Uw1HM13A01a1LI14p1Iz0dS0BW0aq1MC0ml1A419R0eq0R31Mk0Cx0hT0Rk1KA0yA0lH
+0gd0RK0FC0zy1981Fw00t09i0o70iF0xm0gl09N0BJ0Q90gW0rZ0Mz14b0OF0ZJ0hJ0ao0Ao0hB0Xr04e0330Bq0H1
+0ss0VO0lg0WD04C0a905W11h0Ir0DC0fP1881Gj0hQ16H11L03g0u417Z0nm0gN1Ly0Id1DH0ke0F70ew0b20NL12h
+0DA0nx0CQ0Wv0A30pH00B0o81Ho0pV0Md0E602L0E90Ck0iv1Nt0bP1FW10Y0KZ0Uj1Ic0lt0aJ0bS0wg0hZ19d16Z
+0kB1FR07P1KQ09V0Pv1FB13n0OP0Qz0da0oV1380aK0Ze0650Di0qq0P702H0C51HE08C12e1Bk1810Dk1He0WU14Q
+04u0bf1Aq0j60AB17F0nM0Y10Ub0m80QX0Rd1Kh0Qw0PN0n00Lw0iX0MD1HT16C0V20vj0Bt0y006L0na0kF02B0QQ
+0St17T0gO1Bb06h1EL1AX0GZ0JJ0230Ku0Zs05R0Y41DX0LV0p205e0XL0wn0Uf1JQ00k1LR1Gk0tf0ML09z0v70Kb
+0XT0910j010I1B800z0RW0y70hY0z009R0ae0VS0R509h01F0BQ0qi0mZ15y1LB0Wc0kU1M61Cp0YO07e0fX0950ES
+0Fn07y0me12H0390b00Kg11y0Fm0lD0s30870ad0GX0NG0Up0090Gg02R0oK1GL0On0Pe0WV04X0wI0A411w01T1D4
+0g30D20yz0KD18h00W0lj00s16q0UE0bj0oQ0NS1HH0MB0aP10k1560M71BI0KF1801Lp0qr0qS0dT0Go0f50Kr0cY
+0eG0GL1Kp03q1By0ZU0aX0qC0g00cJ17j0uy0Rb1251MJ16E0J908P0mY0QG0rA0U31F60Tr1Ie0770iP0ht0r40yY
+0en0q30X10NX1391D912w1CO0II0qR0kM0oP12m10208E1BL0Zi0D10E50uD1Bh02N0Zq1Ef18G0Ld04L0bG0t60V0
+0Ix0WP0aD1Ne1JF16809G0M50hw0UB0Bg0np0Mu0AC0Eg0tO0Pb0ye1Iq01e1Iv14h0BV12F0Ap0EQ1LD1JX0941Lm
+1LE0T80Dg1620gH0400n60Qj1MD1N00W70yc0OU10f09914r1Iy0ZN0C40dw0W61GB0RM0fk0ir1Lq0IK17D05b0zf
+0yK17r19k1Ma17Y11W0Jb0dY13M0sy0Y30O117n0qB0n80pS0gj0hf1Io06V0Fs12T0Pl0wK1BV16W0ac13X0rD0u7
+0Lk0hD0mX0gb0zK0mu08j0mU0CD03203u0Db1Mn0X30YM0j91GH1JA0jg1Cq0Jl1HO0d31ME0dy0tY0hL09f1Jd0Bh
+0mH05w1CV06M0vd0rB0KB05G0nn0iC0qg1BQ14A0rz19Y0Ha0B90bF1DN17l0Nb06x0Ad0Ll0xk0FG09W1290rI15p
+0Of00n0kT18u03t0Y71B20Cz0cr17M0JY03J1IP1HI1MU0od0WG0nd1Im1NO1Cs0EU0Ba14l0IF01N0A608t0gG0YC
+16u0Mg0fR0cm1Cj0nc19l0QT0QY17Q0So0KQ0H818V0QM1MV0tz1N20K70QN1Jq1MG1AY0Eu0Vq0f90cE0sz1DI1DQ
+0Nw0uk0ZQ0lO0yF0z31Cf0e316F1Hm0xl1KS0hg0KA1Bf0fg0Jc0qZ0oI0vq0Ht0fK0L800g1Ni0Gp04v0k00ld1Ea
+0Bk0vn0w403h1Mc0mD11A0I218o0OB1GR0V10yi0nI0H30mw1My1A30wj0L10q50dd15U0TF0MZ09K0K806U0d61IN
+0FA0o40bh0Hx1Lu13J18y0iV0UF0kO1Bx0C915B13E13z0nJ0VY0yJ0cX0Zh0vQ0cs0gS0zt0Fu0CA10r0X90CP0vf
+0jy1Ap05Y00G1090iG0DT0e50Ag1FV0Vz1CE19z1JT0301CY0xp16j0in0ru1Fu0DZ1B11Ed0hU0yP15N1Ia0FI1KM
+1DV17m0nX0ic11I0sT1KR19i10V0QP06k0Sr0Sq0dZ0KR0nP1C90cO13a08Y1Mt0mg0pv0U20uY0kt0r10FL16k0Nq
+0eL13R15V0Cy0uq0cQ0Ra0Fr12b1Aa0rj0uI14E1GK0c10FT0yg0WO1IE02b1EG1MB12M12W1ND0ps0ug0az0Uo10O
+0vJ0G00Zt0t01KP0c209v03d0jt0ba0f30HT0Bd0Yc0Mk05g15L0pY0YF0oS0DU0Y20eR0l50cU0T20Mi10D0y40sY
+19o0nj1Ib03K0NU0cN1K80M20Rp0z10891G91Fm01Q0o60qb0oE0Cc0rS0qT0wF0bd1Bi0lA1B40540gJ0BA02f0cM
+0K502E0u80bY0Kl12Z0gv0Xj0JK0h102Q10F0vr0Tb0Le0BB0aI14R0kJ03l0zp0He0Ef0CS1E90NK0RO0KI13006b
+0nK0cK1MS0aO10R0Vu0jr0hd1271FA0dq0xK0mh1LA04c12r1470xq17x0IW0li18F05r0L70HF02v1GQ12n0kq0Rx
+0tD1Mp0yy0rK05H1Dm0ch1Fv0oZ0it1Jf0fB1M10jb1KT1NJ02n0Qd17R16y0AU0VA06S1Jp0ET0dz0SL01O0Z70HY
+1As00x1340O90Nz0l41KD1BH06Z18i0IY0su0rR0Q10kN02Y0bA1H51KI1DD07g0TQ0NM0lP1KH0tL0Xz0Jv0Lm0jV
+03Q0yG1Mw0wV1HX0LG0sU0FP0wo18Z0bs05C0EW1J70F90CV10502t0fN0qv10o0Cj0Yw1Jg0J214P07T1FE06o0mF
+0Mt0110P00tH0CN09s0es13v0S81NW0wC02W12l0BS00a0Fj06c0g21Jm0fZ0Kj1F80HP0pt0Xh1LY1Ff1Le0Kv0Cn
+0DX0lY0il05l1Aw1Hq0Zl0eU0pa10C0xV0wc0XP1Md0Ui0DG0FJ0lW0t70wt1Dj1Ks0IQ1GN0Dn10n0rX1BT1LJ14t
+0WT1AU0K40Ty0OT0Ke10N1220Pq15j04n07O01E0QE0zJ0hu0Tv1Fg02504d0oW0lv0eC0P10k60LK0eJ0iZ0Ab0bK
+16c0G40lS0v313c15o1FC08b1LT0Tq0310lu0Al19N0pp1G40iN0Yp1Ft0ti0lZ0eD0Yk0rp0cc19318r0Cd0qt0Wt
+0jx0cW0eX0pk0rq0yQ1M20xn08407q0W10cx1960mM16L0la0j400F08J1490oF0sw0IL1Na04K02q0O615Y1HP0Ql
+0C71IF0wJ0MS1LK0Ec0Fb1Mq0mx08f0wx0EM0tt0Jh1831LM0S00N707X0lc0Xb04g0mJ0Bw0B00ND0u50Kc0Tf1I3
+02U0lF1BY1F00C11Gs0b512Y15i0mO1Gr0jS0Gf0ga0Ia0C01JD0x00NN1IK1GW18R0tl0Ur0JN0Jg15T0Dl14v0V8
+0M81In1Ka0980wQ1J014j0hM0MT0xP1CK0Df0y10Oj0Lb0L618a17W1Cv16A0rg0o30f81Ar05v0IN1430Hn0eQ1AD
+02J1Bg11Y0EA14D0xW0Ta0LU0wr0Iw0zh0jd0a104N0jk0gM14x0WJ0C207j12P1Ix0PY0NI1Gu0Fl0d10YS03E12X
+0Fc0H50JG0jP0080JO11d1Hz1Lv15I0ne0Ue0jj0Tm0dX0yp0US07M0Jy0uo0Rj0nY0M30ha0s60yZ0m40Ew03O170
+01Z0Wh12K14m14k0wL0qn12G03z1610TN0Ti0ER1Gg0d21GC0mm1CL0Bv0zX1NZ0pK0HE0Qf0fO0Dp10x0d40MW0V6
+18S0Ua0UC0Sw19u0TE1LP1GZ1L80U107a0Yy0Rz0MM09a10b0io0Yr0Cq0ph0Dh08v0Vf0fx0HJ1JH06N0QI1NK06p
+19t1BB0Pt0S21Cc0pu1Fl1FK0Z80fA13O18q0bJ0c50P90cI0yI0Rf1AJ0670kz1N51521ID0lK1H007v1GA03D0FD
+0gZ0rx0sv07K0sO0xg0jW0lQ06J0Hl0MI11J07R1Ii0bb0OQ0Ss0Jd16z17J0RY0g60420BZ0H70hN0hz1FI0GG0fr
+0wa1De0iY0VF1Cy0op0CU19D0z90O80qD0PB0Vy0rY01c09C0Qq1GU0SI0mc15t1Fc0EL1Lh0xD0YL0Yo01V1BO0MN
+1KX17y0YP0530T904100f1EJ08W0ar0Tz08g1Fe0Xc01t0hq0Yz0th0v81Fa19O0ee0EG0ec1G30DY19L08z0Bm16K
+17v0im0Mr0oB1BP0Hs1Hu0X70i50gI0p00Iv0f60yL1Dc11j0HH0kP0Tn1J60MK0ex1EB0al0Qe0cy0Vk1Jl1Dy096
+1200kv1Cb09r0uh0R410g1Je0Wp0cF0If1HD0QH0px1Ac11b15S19f0LM03c0XK0he10U1NP1Jr1EN01n0Qy0Gt13N
+0DW0OC0t80FW0fz05z08T06B0dm0yB08N0mr1JB1M80ci0tu0fn0MV0ku0XI0Lt0FQ1AA0de19w09A12R1AZ1F40ks
+07w0s21KO0QD0Nt0eu0UX1Ih10P0b80Ip0KT03N09U0AV0S30HR0At0zS0IG0Gu18C0dJ0a80Oq0AL0I100b1320qF
+0Dq1HQ0OZ1550IC0hx0xO05J0iq1Eb0xT1Nr0p711l0Uh0jI0v509Y000000000000000000000000000000000000
diff --git a/factory/gftables/54289 b/factory/gftables/54289
new file mode 100644
index 0000000..eae33fd
--- /dev/null
+++ b/factory/gftables/54289
@@ -0,0 +1,1812 @@
+@@ factory GF(q) table @@
+233 2 v_1^2+232*v_1+3; 2 1 232 3
+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
+2O57n24DJBIU2tL4HW3xl9pI8yL3FfB2P7vT86M1Bq08g0A72om4Nk000000000000000000000000000000000000
diff --git a/factory/gftables/57121 b/factory/gftables/57121
new file mode 100644
index 0000000..6831e86
--- /dev/null
+++ b/factory/gftables/57121
@@ -0,0 +1,1906 @@
+@@ factory GF(q) table @@
+239 2 v_1^2+237*v_1+7; 2 1 237 7
+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
diff --git a/factory/gftables/58081 b/factory/gftables/58081
new file mode 100644
index 0000000..66eb309
--- /dev/null
+++ b/factory/gftables/58081
@@ -0,0 +1,1938 @@
+@@ factory GF(q) table @@
+241 2 v_1^2+238*v_1+7; 2 1 238 7
+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
diff --git a/factory/gftables/59049 b/factory/gftables/59049
new file mode 100644
index 0000000..8df9b68
--- /dev/null
+++ b/factory/gftables/59049
@@ -0,0 +1,1971 @@
+@@ factory GF(q) table @@
+3 10 v_1^10+2*v_1^6+2*v_1^5+2*v_1^4+v_1+2; 10 1 0 0 0 2 2 2 0 0 1 2
+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
+4Xy8CkC4OEzj6Jn2ja26b7gC000000000000000000000000000000000000000000000000000000000000000000
diff --git a/factory/gftables/6241 b/factory/gftables/6241
new file mode 100644
index 0000000..d6e05df
--- /dev/null
+++ b/factory/gftables/6241
@@ -0,0 +1,210 @@
+@@ factory GF(q) table @@
+79 2 v_1^2+78*v_1+3; 2 1 78 3
+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
diff --git a/factory/gftables/625 b/factory/gftables/625
new file mode 100644
index 0000000..5d1fdd0
--- /dev/null
+++ b/factory/gftables/625
@@ -0,0 +1,23 @@
+@@ factory GF(q) table @@
+5 4 v_1^4+4*v_1^2+4*v_1+2; 4 1 0 4 4 2
+0N0T3R8A1r490A6f1T2L7F0h8z3N771N8K4j5d0Y6F6a6S6H9H9E2O6G8G0b
+9L1l3k1w0o0W5L723u378U7Q9K2Y7L7l1f4a131d9M784e4h61841v3x2N3T
+5v8r0z9a4f2l733d2f6n967v2S4g5N5U5Q4C1t6r1b8V9D0P1M4Q7X5P0f3V
+8f994u3A815O7Z4J6g2k5A6d6v9e114M3s1p6A2i2K1i6K4n248Q6h2I7b1B
+140d4I5e674r9V0H5H5s9v483i3Z1s1c5D2Z9s168N8w5l98120s8W5i2E2z
+1z0K9j8E6R7Y6b2Q6x8n2n083Y878e227t9X5m9g4Z2v4N0B423h7j196C2a
+3t3M1V9r6Z0e4l5w0S4y7g8g94569S0J8I7W9z5V2y8D8p5J2A067J1g9A6u
+9F0a9m5h6M7P4D401S2g8k254L7h6V888x01348b2h4p7c4c8J4X624d0l2m
+1j7K8h1A5F0t9o1J0g89026B3g7M6W8P351U6N5S8R9p5R3b365j5X5r9Z3L
+0m2M1L8B9x2q759q7k049N649d2b9b6i0x7m9i9h7V282r8T1n919G9W807H
+2dA1792U9T3E8F4S9u413fA58i954v9Y3I8M4Y7e2G597q2R3B4i4T4F763j
+8C7U2o5153386O265085541W4q5c3F5M2c8S5W3l70826T935E1X1E1R8t9P
+1C5b4E1G2C7O904H2P3G9f2763476j7N5p6z1I7I4m3Q7u8y6y0n2D0j4W0q
+3r15924t9R6P5I4U2s450k8Z5B9C7z0U0i3v2t2F6L7E5q3W5n8O3y6q8v21
+5Y4x9n2H6m4K577D6J1y5x5a4b1u7T2u1k7i3a6t8c0Q0y9k3J8L4s0r1D7R
+1a091o6w336p5C9Q5z5T0v7a0C6D4O9w44523w5k7G7w9c0Z9t3K698a8l6o
+3S6e668u7d0L309U9l1P1Z207o3m3C8H7S2p463e2J8j9B9J5g0O4o6Y0D2x
+4V9y0X0w4P05292e9O7y5G4z3X18552j603q6U1e3P7f7C239I3z6832A397
+7s7B0I5Z0c2w4B4G4A3U1H6l7x5f1Y2X5y1h3c8YA27r4w2V1Q31107A583p
+3n6I8X0p0G3o0u716c1q8d6k7p2T3H6Q4kA00F1O3D1F8q077n5o1x8o8s5t
+656E5u0E5K4R83176s398m0V742B1K6X03431m863O0R0M2W000000000000
diff --git a/factory/gftables/63001 b/factory/gftables/63001
new file mode 100644
index 0000000..6b67c7e
--- /dev/null
+++ b/factory/gftables/63001
@@ -0,0 +1,2102 @@
+@@ factory GF(q) table @@
+251 2 v_1^2+242*v_1+6; 2 1 242 6
+6YI43Q2ySCkhDm3Fxv4xM0CuCQP3gD4FU9aXAGgBxZEAAG6FBxg2mZEpZG836Cu66n2aH48H22i3hwE8H0Mn1oC9vp
+7LFAMn50u3H92UO4D28od9MN4qWCeMAwYCLhEr21WH4tVBNnFNADUhB4y6iu9VP4QVB4R8Vf5Mb7aM9XXDut61mCyp
+4KLCIrFYNE5g1cBBUE2IiF0DEFb4qK63i7Zg4p744p2LeAMyDaFDoy2614mwCMWEwv71L3Iq7Kh6iLEQFEKR3tUCY7
+9O02Ef2IzDC4Fwj0xrBBX2C9FhG8QFEeQF9d6iiEivCUD5PdCoj4AJ7WJ77qGFG4Pn6d5BYEDRuBdtFlt2EU7nmBth
+C6s0DA82Y2M37F158dDQN2go1yfAQLBbU0GHF1v8OE5eD9NU0kZCEMD9j8rD0Q22xD4IM9PmCCx6r20X9C3uDzDAms
+14TAAREQD6oX1p77eJ8mXB5D0KuFp36w84jUEGQ5PhEHTDyp7vd4TPEIX83UD3u3BbGN8DQG0vU4oS6H707V6Ui1AR
+3ksATa6tw7fq0daCBz7Z8Ab3CFoFNp56oC5X68O9et4XN4nlCrMDOI0kD2Y00i4DUZ0t7CAq7cPD2M5326oB5o93BS
+8kDB5oAbzECQBKlFcY0XZBPPBD6AF00ZH9OP9Jj5BmG2V5gnA0XFsrEu3CHa1izBPK8l70xPBca1Kf7gW3Vq92r9Jy
+AYhCID67QFtOGJZ0rgDFKDid5I92635tyGG09880YQ1voDAVA5kDe09St759Be68UW2Y3Cnk5Hk0oD5GU81e5cq5ha
+9MrDXtCGx5jYACO1zrD890tJAz7FLe9Hf6gXC154pQ36PDAE1TdCIo5NFASZBzf9GB1TSDJlFEb04ICqO6YlCBm0aR
+EWIA1DG252Sg94D7on8tb03T8daCJN9wtA1wCsFAB57g8FTN5YGCsv61kDAC7yu3jR0sSAf30id2ga6UF2TD12cEk9
+Ax2DHbDX9BF8AfY9HsDCH1zF13bCg0EWQ24b1OU4QH4h84mN6eR15GAHy8RxEz66p52vRBJH3kmFlr2fH2Mm7kH8vY
+825EVg4xE5zeCVODOg7LK80LFHYCPUFHj4z7G3pCMl1um6Dc4rS0iOB2ABso1lo1phEGA6scCtsD5L9bE3yBGGkCcI
+EPX5QC6KPD978RkDoVAos3rR1s9FXX8jb9V138j014F1K6dOAgjGGG3iAFMCCd87Uu1OaDBs76MAdYAbPDlm4ca9WB
+7hj8xmGF16xeG8IAKfD3TCGTFQR4Ak9JT7lG5YzERO1hbAse0PRBy92M5Dq0BM91dV9cnCXuE9S15D6Nf0T26nc3MO
+AO711r5UD5J34vW8xAAQpEXsBN89WXANWBEm0cTBeTFuwCqnA3LGCOFXP1u44ueDO2DFe1t56J08yU9m17sUCnl774
+EmyAgz40J9Ed75HDyGAsh2Sv5kV46iDzk4yC11UCx51LY5eeCJI7a0Be22cY1441iGDoSDZMA5eAGY2Ms2FzEqtCaL
+23X2DY2Tb9CuCQs9y85UV6haFix9MyCu47jO8n43KC7JYFSS45UG7L7gp3Ue2N58NOFyYECb5eQ2LW05O9nr0Bg5SS
+5gFDj83zBCq93Jx49SA3s21MB6E41F7rf5NEB1mDgvBr9AogFXU72K1v22QQ9Lw2ks35f04lAUZ9Oa4Ht8un6XLEag
+EsoBRi57OGKDCnF90o85h0Jo6LQDH83kX74jC5o7ToDQ60zxA2y7o00ft8NZA3r20d2XP9zZ7Mn41S05REIE6zv0qG
+7vSDEs6FiB09BOm6056AK6eV7iX06aAzaAaqD3sDCeD2EEKg2vl80E8Rs89uFe8AO54fZ32o4mv0Gx4mXDwtBwG4MB
+AUV0vx4qp24w86QAad3ly1Na93r4h73Bx4Pe7c317W3jh8Qo2KyEvFD4IAcpBzdCnM60V0Vj0BMADM6CF5Ks5TU4e9
+20w56wC2BBwkEEO9lz1Yi7Qs6E32604yLBgN4HQ6vv8jJ66fAID37nFd5EtGDYTAoBAHM2weCiE5As6aLFF96rf3gE
+Fq76TW6fADaH4fcCNO1FtGLC00RAwP6yV8KeBjC4lPBViESl0fPDRB541EOC01K0vG8La6NS2xGBmf2Qs4nU67yAyL
+3w89Hq06s7GhEcmEcN8TjBTw0oA95wDLq9GxFtQ8Xs5QUDat5II7DOCJK6uo0e61t0Cbd7Mi7Id3GQFzZBy75hz43x
+5zF28v9DY8EE8v4C3sAOR5wY0pO3iq6sT95z09Q6xqDf6Db7CVx1ZL8rZ3NW6VQ2Ns9QK4FrAiM7EkDEN7Lv8AS9TH
+1eOB03Dym39N9BvFnE8nDCLJ75NFKm55AAc52It5TgDDQ6Jj9ZZ3Z5GDOC9l7mhD2yBjQCYp02oAYlB7n39d4qCEXJ
+B7a90EBfC0RtAkA8UPDqt3Yh5Wt4200iuCwH1Hx286Cgv533Du92dWCFEAZKDWPCbL5ZiBDq1pm9b6GC73hv99g7ps
+G0x0Of7u9BXN3lX1zm6rQEMZ57q1OY9Sl4TrE9K4Ah0GB2A42TZEta5eT5zX8zw10uAu7CzW2jy3ad6c50MQ9zC9eF
+70C3j470lCF97CK7ga3b7FBM8Dg2NB51i87qETUF2M4UwDdt2wo26W38u3c72x12DXEOwEtb6dXCZR4ErAdWEwSC9t
+3fOGNV5rdBmeDhh3Hh2i6CLBAhH7fm65B6v46Mw8MUBNO0eGAd7F7TEO84vjDQg5Cy5Id4Ww9Gl3NADpu4CCFVx0Ev
+9f0A1SCRG2Z00d26843LqBVe6YpAySC4rA8E5RlCPuBka1woGJy8zA61dCcED9bBRS5Ay53R63q2vu50K70v2xN4gk
+FvpGDa3SYB6B9zXCEh1kw9z62pSFHLFXe8IR66Q7i17Ff5mo9I5B27AhG8M3D56BUP8rQ3CQ8HiCxW3Pw7Xx2eH2HT
+C6q2CiEgpEMJ5ZN3x5AtDAPR52tCmW7Ss1rCEg558v9jg3tO32nGK49GJ7ueFlHC1a2ss3rB7B82d94gP96o8VC6bd
+5AoDOD8wrDkb4I5EEsFhp1AE6SQ8cN3it0zQDD30uX6xO9NL9IP1Rz5VS6fRF97CNVDaEBpz2Gx1C71XpFeGDxC6hi
+1Uz6piAdZ9HA4dK6BSBKiCl3E93F0TAYGC3a9XIABT6Pz4GS2u1F3E4uFG5EDsiBJUFD578dBzODef6201Pl0zw8jm
+77H5z0EVO5Kb6H16v19UO6B5DEXBA7DSI5X17MdDEO8Nn9QfBw5FdcDXR7OA7Wt47z7jYEmE7Uc3dCE6IEhtFLK6hv
+8haAEj7tn7qVEIu0nJ3RW7oU6a82A1CK5Djw0VUBOE79I9wEDzg3cB2ug01S2oy9hp8mI5zZ6Mi2zm8PE6549rB1nI
+7Mt2rV0Ik8GID7A9fu5rS14B6iVAtjDFg1XgBwo1bGB7XExGEdV5991E3D138BC6wtCi71OzFec2FdDlp9oN92JFC0
+7EnBv7FCH6CqEPrB97AZgBq3CvK6DO92I7KK66CDEP4tM8SV1u76Ps08nCb6ECp73n3s4A677LMElDEgDEIK2pm1ye
+0SeEWaGB44nR2i4Bho0yABemDCc2GC3113DMF1m8dM8Cw7k20B81o1Fwf9Xb4l29RB3ny8yw6mGFcwDcS2oh1B6Dor
+CRu1EH90KFdf0N1ELs9p04O66YoCUKEyyGDb25kFo4EqT8wjCtE1ZO3S9Dxf52u5Sv9Fp4ZaFn3BHZ4Zy0buE8j6E8
+1yO2jtBUxDy38fM2psDTn4bh9Mu4t0Frp2VE7qn7Yj0OzEgr9xB0f25YI4JYD3QE5r9q870m6pyBJo75l3EO0XI3Ul
+CJn0FV18514U5uw1Wh4dNBew4ZE20xBSp099F4r4tW4nm428F7LA9kDzuALy92d6itDQJ2a915WAt2G5y7CW8rsAC0
+GIp4VgEp3FfxBsf7gX7fV7C44clCYX6GxApp4h90kg4Y61in8pbDH96Pw2HZApK2u07bF1S29zjA9NAHe9yHDCVBpB
+4w58Nu0o1CP6Fj2Bir0oQ5fz6BRCNE9Wj3XV2urDCu2Z34mH6ZVA0K6p85U4Ebw6HG9K0Cd0CkE8lo2cw4Z64I4EUI
+A37FCz1dx0EG9JR81B26v2ZBGLR6UuB0x5tc41gGId78r1kF875AZs0QyFPIBeC9lT7fwBaF2OCC7A3t81LtDQt3I2
+3421Zn1v86967265ep12M5ix1uNDX46yQ1rR31S4oUGKvAldBYK4sBBevD6v0En20u20s4Tc9phAeS2ez3chDIP3RF
+0pKGE98eHEjlBWd0579hy4OC2m4C0uCeJAv71tf4ySB7F98P9gxFGZCYfBr4ExU8rgAT77UJC2S3FHBNGCw1D87EPL
+50T0ix3Yd2mFAL2Cza70KEMV3Fv0cYCP70MZ1T5BnZDVq4Up4wu9U32uX3g8BxB8jc7QV2dd1yC4hxFMG23aEthEHy
+F5w7U1FfSAT6Egq8cH9JM9TZBMc3EK3nIDdQ7131oG5U77zNDjN7Sq9jE0R0CYTCgX9B56inAXYF7l60ZAHHFEo5M8
+Bf33tJDYJARU9oP51o6vo6ZR4jSCqR6Vm2Hg4ALFgj5AQAkw3kxBFG5tPCH0AMb4wb0CbBZMDDK7cn4DD5222d3C67
+ASn1JY7iY5qFF1VCQBBSz3s2549ArY2kDFOL8oM4diBvB5St7SrA14Efi5D47wDF9j5xi9E63rx2X36t2CKcFgdBXp
+9WDCK611f5of1pT5WG4iNDfW3NtEOL9dzFyUBRAGJT96f5Vd4Ea0de2x26DoFvB1HRBRI2vM6iI2H6GDXD2FBLi9g6
+9GMC223zIFyv8aM0bvCWY1tr4Rh2Xz8Sg0fK5tz4t41fg2eNBLo5T2AyyFWaEREFqnE8nCJgEqDDB47ryDjK45J6Xz
+CH43D34JRD549582T5EwDAk72Ka3iW2k68jq9Ey7Ch31FBB79CN9R20WdAkM3xh7WmBHG1bfEjx4WP0z185bAPj6NE
+47iBgq9grFnV3m0Aho3VVFUkAEmDl81ip8Ve1feCQdDhi5DlEm6FzIAElCKM7Cb610G5x4VS6uz8H3ByeCZGDzBA8s
+5Gx01u0j0Bot4wxFdFFPL9Wf5iL6tnCAL3DK8je59tCu61eY7fSFPi7iCAVbAQ1FXJDEiEjr7FXB616Jh8xiEc31LI
+1klD7a6YZ41r0hbDfIExcBOj8ZLBfN3Bu1NKDMU0T6AuN778F6OFzA7lN0LA6ajFoN7bLFXI1jm13x6W58wNGHlGEF
+83dA6J41v5PV5JLEsl2hX8nA4pZBGEDXO5WQ1jf3v4B3h3OD6Cc54RCKR0ZM0qw6wB0EYBisE1m5GD2y4FPQFbN5Or
+3ft74wBnR7zfAHC7sKDdF4Xd5Kr42EEFa02M4Tf0CEFnC8WTDPkBGFFFpBmN4P49uyEE2F8v3nM4p1Dsw3TW3jw94n
+8pQFeLEb4DjA3tC2U20gV9ZrBd1ACAB6b1ZDAuk9Cs4s4BcsAtN1vO3M3AMEC6r97p9cdEhA0rx4cmA3n0va69UCLE
+FndELN8vpGMA5kT46j9fiEiQ2ui5itDtZ9CwA7dEBdGD2DTtCsQ7vZFwQC3I8nC5kM7sBBtg3Y72CjECV189GL071j
+4sIFvR4i1DLy1XI6iJ4fE2a26HEGHTEKWDwCDjG7mB5Fa88f4CzAvK1QDD8CFCS2zF6EzBNM05y6WaDtXA7OF5L1m2
+7VS10s119AkE4f6FDdDy69OAAT2Ffi0diFZn6ES9azEQa3rO8pq4p30zU88J4RaDQq4Y315E9hh6yLC0f7qvAdS1oN
+7JC8vgBSM8Tz92z8lRC8W57771SB9wFPa0uI3Gf3i55qk6tO5SJBjDE76CLIBEB2rpAGM2pRCP2GKkCv973d2An8n5
+AjQBUl4Xg0BY4ZH63e3hcFzrCw9ATzAXr94pCP35SWDWqDD1E228lG5gjGBo4bO8x27QZ9LpDju6e3CMd34KFu5COF
+5dr2n01o9BxIABy9tk5pYCop9421Km7dd9AXCOA23dBbf7hs2rnC0ODP8G0Y3o13P3DFQE1y7zt2gO2lZEDmAzQDkM
+GIHDYj32XEY05iF42y62kF9u9g07iK5CD4fJEoG2CECMk5xH7t15f128f1sX8Mx3AW3mC17K7OO2ML70y6Nv28g7tD
+2DLCWCC9BFdb18u6KlDh80we8IX8a8EJR8dr4Qv17x5IqERt1VBBLnCqs8TUAWy1J68mL8csFoB7wm2c7FcB9WP3zM
+FNaCkm2Gf89X6NG1HhCPL5ji9sKCJZCIFAwqFlU4mV5hv03Y8FT2ci7QoFqCAeo4wR1FB6DZ5ez4DQ56jFW7Fmg9ib
+4141a81Yk5IF9H60pVA10GNUBwZ37uEXW9s53NC2FI7Sp9tq7Nv1Dt33I40B4Vf6vp1hFFbkAsMABa6wkCKj76u7aP
+7oa2tW36V5DnF2W30l1XcD6D0zi9W9CGO2NW8Fp1LK1fV5CSA8DFQx6Or4kWBCZ8iI5Im2UF0Pn7Zx9AR6x05nY6IW
+9e6F2U8hc6T4EwV7lBCCV7NX5eRAcLFKU6fT9rUFoI82uAke4811KAG3s9yI8p27Fl4jm2MP1T08YG2Dt5WI39uFO7
+FraBNLAVL1V40c75ec3AO1ohEiVCMz7yB49X8wSEeH9vK9Vn6hnCPC4My51nDc51yhD8kDKsBEW8ULApQC168jp61n
+2hG9y34En10r5hWDw4Bkv58n4wh7nV8Eb58130wFCf0DV4ln53AC7w2Q16HABLfFVD2Mj2iDG32FLl9FE49WFpt0NN
+DBX9kZ98Y3JuAgZEoP6MJ4HmCLG2Qa1QK5KEEa98KV8i0Cl9Ap17yyAKH8ek0ry8gP8Ol1qJBgy1O25jV24UDLB0dJ
+6lE57sBfd9dp2op5a7GLaASkAJ37Fg5w128xAyK6dD3Oq7E4C0X5Yl5Bp5R7FrqAVW5yI3bR9MZAnHC518og2jjEU6
+CDuEke5Fp3MB7AR0kOCA49wUA3aCku6LP3aY9fs8BT09ZEyYCjFD3hBQk8wA7lF2f39NR2VdBafBjp3taCSvF6CFmx
+2DmFGSF2v8bRC98DlSDJcDl7AvU8pcDFvF62C1iDqS34c7mWFxI0k7CMqFhg8Cf8771AD8nm5Kd3TSDWcFS32ApFJO
+C2j7Vh9aDEFr0MT0kr3FR0oj4bCAjP89o5qz5Kt8s10Eq8lj9ZyGJW2QgA7J3AKBPy0sbBvqGBA2rECNh4VG3R64ti
+1j25dQ3Ir73vAAU1aeAOB0mL99x8fb2SF6huD6nEEv7fkD55DNv3bv0Gf3MP8Xd8oS0i731k23V4PJ6LtBrs76L86G
+EwT6DRDSM84i9dY8hJ9bOCXc5DQA4561I0HvAEcEGVA845yaG3M6Db4YTBJW6W42255yG3l6BsD9gW967Bqf7lv4WF
+BhKEqF0eZ9hUAEYBFMAzU7982AS7veEOe3oq2rf2Yx6iWFj51sQ2lECRm65P63KG0O5M01JvC325yNDLT5TB0vHAwm
+Ekg6Vz7PVFmd4OB84O5J5Ff96XRDZS5NOBgT5QaBZRG8Y85GCgi21hEdi3xX4wYAlrF4g75xD4VEN34F32991jO78s
+8EKEBA990Co7EoRCj9G4UGKC2UG9IKA5DBzF4vx8Rv1qu3HR6Ns3zZ2H982mDp2D9n8OTETT7WEEvq2Ge0E1DmD8Ze
+Fh9FowFMSA2AEi26Yd4to4MD8taDc71w68XLFB09XR3JeFXB9cbF2k64F3Ak8p0BpAExuAmT12kFqU7JzFaK37QD3V
+EPh1e1BX0ANhCVfG5D5FY9bZAiJAYT5oaBa8G8FEYk6Tg0aG9VB56nB2GC2HAtkFFUE093rm2zl02CFoX1Dm1DvCRB
+41X9Nf2TrFzVE313Ig2XN5k4G517NdE2DAmA6cG1cm0qc71fDEC4zY5loALK5yqDxF1Oe5QYAOY7gyEdL4Q3DEg13w
+AWD1ahERHC3lDdw8zsGHa9rS2qH5hk15m35H336Bio4uG3Ic0oY1ChATqDGT4jABaJAs99BLBxM81l70J8rp8H15pM
+2N2GKo0kw3G97zmBwj71mDon2SY2NV5NsE1v9HR0gQ0IZA3p7034dcCfgE4W1gSCEL0gh7325sk4Oi4WD1DhCUR5j8
+9ILCTpEYO80I9ei4elFZXFE86FsA7EEfC3JV2x093k9dg70G4FH7Oe3dtBP34BT1XwFet5XK3j92DQ0VuFTs6O7DI6
+1O40wmFQ1AzqFdK7G44x1FNZDcI276FP06sm8LEAEaA8i6PgB5uCemBt939LC1m6ZiBj1EsPEKI24o2dvENh7nl8OF
+EFk21663ZBHJF6ADtqGLbDda6Ca6gS3Yg9BP9Ki9Jm9Tu2rx7VqCVC5P25T37Tn0ISCOV0bzEn2ED3FOg2q0AKz8Hs
+FRmAWj6c67rr1i90GQD5R8hYEEuDRo7c05wd3NbCm40chE798g739q4C2AE25l83Mx0s2DxvEUoAHk1w7Cnb9rbEkw
+CXOEfP28q16hCgt2Vr7yX8o8Eic7Oj3BK6zP5Ma6C2Bt42R55jAAxi1oqCxZ8eaDWA2akFbRCDE8m5F3ACoeC4GBW6
+FO43r63mUBmG7TxEPNF2s3pKFOl1106Ds7WB8WABDw0DhFnz5iP1Ps5Ub4ae8SZDw22S0GIcAreDdX1LB1Bh7Z56oS
+0y38iM38G65K1c37pj6U9FPM7d48JQAiU9rN2B914zD2s9829mF6yJ66c9VV9k0CsN5XbBIl0ldEVm51N7ZJ4Xk2PQ
+CEz9psFjBBEe9TsB0S7YH2IA9LiFgx4R51DS1qa8e6EGWBRy6AS8Is4FdBxe3a6EK67pvAl650rCMM4cgAt84eQFXH
+2I1A0ICUH5ROBJI5qf0jbFVH0GaCZECdn0CJ58W4sCAPMAX41QjEa25foDYb43Z4WfFaq1JPEKyFAP3D83QD5NdBnQ
+Dqy8JkEjP5rRDNy7eD1ZbDOOFbfFog9dKE4l0f70MW42K4uH7Qn5No6z97JkDMfCxBCVIBbQB0MAh60F41nHD7w8Vo
+62YG7F6fW88DDXW7KjFV5EQO1gZDNE0Jy55IEQW8RM0Q9CrIG6yGKYFg97zPEEt879DCG2GAEnr6VUDkZ1Z29jX4y7
+EDp5iq3p49hoArxAby53948oCl5DAnANC1fKDKC181DpF3rl1If40X11X9X3CUV37x7YJ6N95vI6crBLH8tE6wG1O9
+BOw8PxBEY9HiF4y5YLCS57vn3yaGEy9te6FL6Tm7lAEGl7v44Rz3pi9Yq8PA3tfFkK2oPAQc1L28Vx5viFkG4F1GA8
+FWsEGh1dtDhxC3wEPH9hF67DAj4DPD5rZE9p9a3AhTDEG0Ck0qQAPZEGoBoD6es1kC1L941n9rL8LM0cf4Z40VxBEC
+6nR6N32U00j8GNoBnj0No0hWG0s7QrEyL0Vw0ct1qN0TD6qj6ZX2Yf6j7EQHC3FDpk9Je3Oj4dAABfAnrB8f9AwDQ9
+5MSEw77zv9DQ1vZ2DNA211F79J8DHC43IFHT6xU5DHCL30BG5VO2zY1MS7vL1ewBbnCq5AwS6y6Ecg5Bk1R81Yr7x9
+4bQBoQ2Dv0TeFuI6XT694DxJF8e4Ry6M25WE5geDh2CSzEI15Wp32zFa94v504F2hY9El0BoCMj3d9Cfx8V78Uv7wJ
+1cYCHn1oo5DxB607Xy7rbCFL5593rb7ak5do6NF14j4EJCcDD9S7NL8XDFxS1qkE7I4Pm15w6q64IVC239M306S98j
+GHv7738FvCJc93O352BvK1k74NxBjs8hb2jeB5BC9vAZu134BZc1l03pv5Fn6K439hCbu6FrD5B1ypDOC7XqCJ6DpL
+3nlCF77FMGCj5Qr92t9qN1pL94o70B7JwFQtC7F0L203B2Pj1zq2SrEPMDklDpzDTGAmJEpLEP07HR6by8uKASxDnJ
+A4K9Ms6x7CSD8MN4DY4q6FIi7a701s2na3FJ2mGEK30xC8id87zBEs1T1BDN1pW5Nn9kCBZW4VP9vb8Gz5P7ELJ1il
+CHLDNiG44DVXDG52Cm33k9r6Cfs7Qc3TYDJx2Gr113Eo42sl4C4FdMFpj9D37Ci83mBabFck4SRASWALnBgD2J1ERD
+7cj46J8fa93R8iC21U1iFA3A0Hd0CY6Qk9aP7kMC9FCKL0tg1DyA2B08aE5S33DCQI1om8cl80G3VLC3kCzk3STDWU
+7nk2BDDIxClO0jIDfbE2XEsRGH974L71CBEX6uBC4N1002nQ9HW5Lz2ZECaQ0qd3CoAaeG3G7O339HDivCYh5er0Yy
+6i9BcKES75XZ7gs5pVEBEBVv0e4Aab4zWBSZ3478Nq2f8Ate8OM4RkDih3zE7o43GSFvvA538qBE5HBIO54l5cj80Q
+7iQ79f7QwAuJ3Xc2Fj33YF84353AUx5u6Baj6rY4XKC2E6EH1ABFOu5LVDpOEly7mP1Rw58O1jtB3O7vMDoG8bx00V
+9yLDadCV72v5FguBGmB1D8SU84GAyE6p179X3zXC4n4w8D2GAEUCqeAnmDimB0NCy1FGE46v0Zf4QTCe9B1QE4z6Px
+BLsEVn5v7BeiD9i6dpCvw6id71KCQUAk01xdG4r4KXCzt4pc9J74yY7sMCub76XCxp0x070d1o80OcBEp1sN1Xe7S7
+4AO2yi4BIEF55OF2eq1Sc4TM6MM1j48fw518Edf6ni4dT4qdBKc5lWAxvBx9EAL2JT6eU8xG3Oz9qgEHZDcR2aj8G9
+FzN2Sb10840y3HzB06CXlEajEoVEYG2kv4or3pEAfK9i3DYq8ZY5fHEvj9js9OC6XI2562493bP8mtCtA0ro9aa4MW
+6AXEdXBuI2qsDAb17492o7iB4XbA033cPFw8CO1BWiFHg2f2A6q4a5D1pFcn7f1CYC7uO8rFCyeEot7ATEZFDfhCen
+9B8DHHCBV71xC6nFbu7J6ErS2pFAc816O2zj40WAUC9SE2oQ5jB9LuC300T40mPEV5G74Ah1CEuFnkERT2Pp5KG0gg
+76E1c961qDFC2Pv8PbEz4BWj5tY1HP7bGDLN4mp0zDBk2FgB2ji54TGMLFXtDJu35N8pP5HyCV1Aa27FF2jFCP49la
+BTFAtVGIy5WK07lALh4T9GFn4H22p77di7Us19fGDQ4Rg2jdFLC7JG0ZIEtQEcj4VU8lLFVLCBqADd6702ri8ig1Ez
+FUYAIP43b5NWDA554s0RE0RQ2KY5OyASK9MeBnM7q7F4c6b51mf0iv3goDrS4odBb3CG691L3nt3oOBooBYz7I2220
+AL63Mh8adFon0xK99707GD8j1P83Yt4hqEFNEHU6UfCPlG2P3oGCQD8tWBc6AFlCnt8vGA3x9cH6aK87M2u6Bed1Ry
+9cyBW5E390yR7hx9Ws3C871u5Xu64M5hJAFZAfq6erDPZ19kFce9Pv1f41hoCPDBBtELk2pq8Oj3CX64yCwU3aZE3i
+EZY5xy1i49XU2R31xI1ng1gXDBwD9Y30r2glEjz3WAEIFFWP4z406H1hU7ghBB5F0Q8cx42j6t01CR4W186eGNIFDE
+19x857CUbEwRAmKEIs7KL7Mf5He5t5Flv5kP2eLAw20FECgHCwgCdw5BEDwi4rLCVd7uX8fo8318KM2aV8gGFp62fG
+EgF9TNGD9Fee94a0EM0iG53E6IK87XBXSAFHFXqFp5CQ23PjG1q4Hf1WmFgL3uK0fe31sCasALz0SBDLi91QCvL2CP
+G2f5o0CjNF3d29L8ODDIw0Zc2Vf25ODX05nMAAeCJr9pW1oO6ZDAYCBf41jN1CQCkMDGp6im7zb2yFAca0Vm7sO0Wj
+6cPD724Lj2Lw40iEsMCnQ2UfDsp8bcDNsDkqCBF7mF7Ay0CL4HJ5PSCs2ATHDSn38XD2i4ez1KK7Q8CZ04hVEtt3KY
+6XiFodA8d2CC6aGFuLFIP4zpEEr83gA9PFOw8Js5rrBSfATy5Cv1TBFDa6nq92DAjj2Z90hu0xX9WzAb8AjaCJH31r
+0K74gZC1t8ctCvU9tIF7u7yL2tD2XE5uuEQCEh76HD3Aj0rB1OG24Q7De8mnBFl9uO9bm5JWCUi3nN1SOGG2FhLEkY
+463ERNC1Y82w0lj3mQ9Wp0rzASr4wJ3HmEhJ4TsBpEDhO6aC15s72hF9c7kv6vk6ztBv5G885Zo1nB8WHCukC2w5vf
+CRTEnV7CQF5P4A17lwBSmCJj4HA3n7GHi3l42ls88C1I288T7uvDlk8Gm5KN0nm19v3rjC7s5vz9I48SLEBOBSw8cD
+Fyl0K2D6bD9rESS7Cl28bCs524q3SWF3h5ijEmRFAt49d3lt56DCcf3EW1vA7zU6ZL3dv5BU8QzFPcEOy28n1rg2jQ
+9YI6V93HqDa16QLFfz8NsByaFgY9jKCvBCu7EnO9OoA7r8kV3k92WuBQL8T41n217L3C39q33HV4rT2i908xFPSBdh
+365FfFDGv4y24th1ka8tpCde03l1z756F95V2SKCTC3q53GkAD23K13sD2Iy8GbAaF3OC8zy6gT2HpFp29OT9vSCEp
+1xQ8NiBKQ8HUCDXAFR6o167J7cX09mBWe5V853Z5Bz4mt9GI8Rp6IR5Jz0Up3PBBGe9xD3pg5WD3h7BUg6NpF6F1tU
+1Bf8rM8u7Ak59d83S48Sn0bg2kSGJDD2c87h43a13Q4Y00TxDtDCHA0Eh43j2P0FoAEgwArgAlHDY41R468t9VUAW0
+Aqe4aO6rr4Ub9QgC9D3NQFBCDZtCLy40E5cm9NBEJvCa91cx4inDxQ0tsD2W97R91V0yJAgW6J19mGDUuCfaDrnEAp
+DaU4txAzED4LFDo8aNGBs3Hn9Sn3AI8YP7oZ8J11ziB6K2i87dWFrI5Kg3437HB6XW36R91F4kBFcpCE6CEQ8FfC8g
+6fL8vIAD73um2ABFzsBSh0Kn7DY2U1Fw20ne2uz8FwBPU8YD1EG0owEz3DXT6NrFtCC4oGDZ0SPF3i7364Rq9xT4UF
+0emEOD1Gy72T7e3BH09dZ3nfCG0Du4G1d0wlFLq1Hj0NEFYW9qP5THAbZFY25RdBXa2Zy7aC7oj1OvEBF7AlF5H8vH
+7nZ3I843H5te5KV29V88U0bl6fi0r6DBQ2RNG30AvRB1jFTU6CxBXlBuLAT9EuNFFyBUwA320Kw2TxCOP13y5js1Zm
+F2R7dS0DM6eO7c189s3pAFkFEOS5hE4euEe63WX431AP35dJDXa1SFFwr2AOAqB6vGCED6RH5kN2KM6VN25DATtAts
+2VM8xdBJwE3g8BS1Y01UI9Uo8iODA0CRt4IoAZy99O18x8L7EAoBLG6i41aW7UG9ir92m2tj0YA0mg7D5EkM1ERG5d
+AJH6BxCSmALo0F92p2AtpBPcF7F2fnG1YA418Cg5Lb9qt1XZ7Mq2mmA3J7WOFvtDPS8Ab1PM8nj0GkDpN5SAAds9Ak
+BUI9sHBJd7zD0Ij2wJ4Vt6K99O8AI3EQ85OD8GR93o35Z8WX3kuAGH2lQ8KSAfU1EB40tFdD5lZ0gO9lUEYb1Px6Ae
+4jd9uV9Iz2JF9cf7fYDeu6yW3CL0cL2KX4hF8Sm9i49bS4mC27C7ta8oB89kCaa8EGAIzAmZBqY10hE8M2nl7Dy7ya
+5wUFHA8sgEaM1tj4fq7bkCpl0cJEMz3AR9ldA5K5Bw2m8A6A0GSFgCAaD9bzAFL1ZSB118DXEPE2O214S27IA5u4KV
+CjG9Mn1Zg8hAAeX98T9XsD4eARvBSIFrNFs50lKDoWCyG70DAok3no8Fe1KkByV0M09Hm3K53W72Tf85a5LlESJ8LC
+3GmGDm1Kv7cQ2g8ECUC3t87tA8tDEF6jG1DG4qn9H4Ff3BcT7pSFUz6vD51TEtL3eE6srFEeABg0DwDlG7Ts6d055n
+BTx4cV84e5ra1PC0lbAmtBOfFRe3SHFX02zdFIX75M1Rr1ea1770lECuV78b85IGEHGFUEGc3WTCwl5mpCuCFzH1Om
+7to5orF1SAao9aw7nJ0qfAm5CrJ9md2ZZ6RY6xu8EO9vBCEKAB3DckBpn1RK44I7Wl9BoD9g7TJBpm7x3FtuES6AFj
+6rp3UgBvlBVTB6HDJf72FCiZBenCqv7y2Adv7YE2Wm0D89ccEYo8OX0Np3mw3214oX0WD30W4wNDMcE2u9XKBre0lg
+BR21K95zwFahCRM1OI5w5AG98Tk9Ir1DD1Xs5fg9hR6dd1aFEkXDin3xd1WD3Zg5eGEVrEYCFtjFli6jwD2Q2PP5ZW
+AIm8cy0wtCpL79sFKzF1pA0Q2RP47p8VmEpeC0c4R99jzCNY3Fk0mm3gMAhV4xJ79S6TrA0BFCiDpx2oYDQMCKQ5Lx
+BxSBmo6Uv2A9BY87ig02mCOaCAE1PB4jY3t47aB2irEF85GA6BPDgT3fx1IO6tpB0E1ieAFhCN8BdV5BcED19ur6r0
+22k9Ub12TGD558Y0ScG864SzG4e4Z931EDpjF0R0Zu9d599L6wo2ffBYoCbBA119r71DsDszFXxAW3FQq6zxF2gAqs
+413633AuwG6B7db7ovG5e2ll6c4Auq2ZkFK96ic6Rh3yF6SuDuRC0i8PnFaR9JP4nLFv8EtZ3i3AcM8GFGHdAfkCiV
+DixD343qZDZQ6ieEjX16Y9hmDWn73b9kdBMG9ue7JR2r1Es3Bs54sN1OJDX58OeD8g71V9fG4nQ6dC9D0CiiCFe26M
+6DN5Mz7vrBFvFc9B2r4hu4qh8aO4wL1ObBru4Eu3Rc7DPBU3BVyCXeC5F5X7FHe0I26mADIQAmB1JKEuz8xZ2n38vJ
+3Bc6UyANKDHx24m1aJGAUD2h8a43Qw1No33v2bX6Yz7Y9F1iGLy9X94Iv7SG0dN64o7Z20GbAk43Ed9w5FHG6mX8Tb
+Frj6uJFJD4ad2yb0Tc3o5E3oFYA2kI7198BF9S04UL76SBBi4fCGDW0FKFzQFVFA0SDIyBoNCqF9LoFTh6frAtT4yd
+0D51MnDfYFcZCXI1Vq85pDsr8IY0SH7s76ow5WO9uh2oBAVT6HJELY8sRDxe3ZaDZzCBjFslAiA2DrBw8Djs6fqAE4
+E204i88Ct5rB7rNE0ZFKd9Il8xK9bi7tE4o92Fv2fJ6sN12C5gl84v9hwDMnDIA6XH1mx3aQApIDZl8m8Beh26I7TK
+C1f0Wf1RN6hh3JpDW8E1b1hh2Bp3fv1lX5Gr6LX6du6081Yf3QEDvR8l44wS8Iq0YR8bjEDa4Fi28LAd2AsNAkI3AM
+1wH5rjC0A6Wf8jv3z33HT0sN9ha6fE0kf7AO8JUCCu0RnAQv08R8B9FNK6NL8dm1ekCEs9kN8Y1ErNArw03d2zyCk3
+9FV3XXAsc9Bc2T16qaFOF7EoFW131b9Eq0LN03qFJ88zkBmq5Sb9ZSCc7An29UCFF06ml0y57YnBBE6rNCpm1AH8TD
+CP89QU6YJG1K5up2e6AMT6JG8ru33LEtJ9C4E8JFPt8CzAsOCKn0Za8VkBbB064C1DGLx0FpD3K3nD6OkCyVExX4UI
+0rJ47Z6rH7SA6FD9OD4JW6bX5oxDNLBzX4rW5Dw1bT1fyAOh1GM3kYEXaDSwBc53rK6rq9st05421Q58hFZL2tPFZ9
+Fv59Gr2LCEty79H6XE0X22Nb2x49pOEKxFGM6yS0WU5qW45z0tn2xqAzjDJD17a6Qn0wu3SL02I3DQEde1KX5huB4Z
+EEH3ctEDc7thFEd90D3Ht4Dv3fW0IW23G1PwD8V0Z10hj9v5D5n1jV9ej3NU1GS7cxATu2tBBtrGJf0TpAsC4wwCfT
+5laBeE2NO3llDFx1PH5240piGGpEfTEoO74yFAh9X61VJBAO4WH4te16r2ad8Ov0uA9c55a25gWElH7OXAKcETkDMD
+4xq1zo1LM6yxCrU0B15ri7i78fiEv5BCN7JS6ac50j9dJ8p325UFcM1pR1jC90bBUh2dMGAJAfy0TGCO23Iv4aCCsj
+8op21ABfiEK0EFzAcy7Xp31d8Bs6jJ0AeCOO94wAWEBOkBIu4V06vg2LV9hl8CGDnT3sR98b5aTCFH3Ha2PE7Hm6tH
+APW65r7YBE7n7AFB8x24aCe8CRaE6T2rcC79Cqw6HY6CQ9Pd7NSCqq8hGCTUEXn0CzCJS5sa3VQ8PY70cEV1Efx11p
+5C10vR1kL8IJ81K7KNFgyDRyC3N3Q2GGFCyDAwU8pr0GlB7E4QM9NN1cGDsB0sV7SbDn2DYH8sI55lAtu7mc4syEce
+BP94um1659VW0KdESA88w9FHF32Fox60z3aaB9L9vd4To3mp22LFXhDN8Ath9NwFLg55f0zkDoq1Ub9Zb7E8DTsGIX
+FY6Fsa3gcBk0BqtBvCDjPC9x9BR2zQDBJEeX50356d5zk7Nq3eQDQZ6zl7h84Oa0FREgTF6b7qK4DiDxa7rT8rx9QI
+8fx3DS9NDEKGGJp1ZG3gzEO73NBBnG8JD7dI09G3eUCDtBx84vYAEBF9PBvxEiF9BXD18EO027ED2R02911V9SD0cA
+5bm9INFqjFI81ju1MU7Pv6pZGLH2s2FSfFeR9Zx8yd0IoD4lCzeBpG6G17hrEuF2d66093DA1Os5G8FM98pp9KLDsx
+2B4ETB4mQEapDFH8uLDmhGAV7jU03rB74BxV75m4LQ8nO0Py4Of0xi2mcG1S3icGIS0yLD2v8bt4E704t7qNChV7tu
+3lM8lP48O5amCoT5ai14aAt50Mp5a88Q67q01pA6vW2oc84NEkc4vXC6f6Lj1Fh7VA1Jy2zVDgM09p6vd6PN1iRBIg
+4UX4RDC0IDPJ4Dj75R3yj5NV5Cf8uB9Z3BY1EnJ3KL3fzEXCB372im0ULArZ8FCEK2CZq7Es1wADdPGEQ8R5AU8CfD
+3PP2EIBnm1AA1duFPHC9X1X583O3EMGHO9g2A0P9TKG311yd0HqG87A3vAh86kN2RTFIR9h51S6Fds7fZAwRAajAw7
+44s5Lq2Y65VE2YwAK19yABit5wr2Gt06u8gB3DtBMP2YF5R49hB10MAAPA5tCd38o1Db28UYDOSCQ11Hu5cCAZe8j7
+4dR9fEDP0ApzD7p8cC0FJ0qXFih5ns7CPFhV9y7AJcFl20Kr02S133CV320cAGQ5k52Mc17vETL9xMB0HFyq0SoDBY
+5SP8qA0yN9ouC4jEgYEmBG0Z1hm3ze5NwBTv1zb72bEtVFcL0Ok79G7IG65dCTi7pn8dD6eyEei47266k26Q8ZZBSD
+GHF51G79MCld13mDZX9fQFHX7IX6Qw2f460J9fnDXQ0YCDs290V2Do6GM7kU4uZ5WT2J2Dtv67q1B8BPX46F9Qk1MT
+BV58qIBWX0AS7Vu5NI7V59WT9m94WV1kf7afAnKAQq8hR57H6SpFq59aW9T46KO8zU8UK23C3LP6mi6pODZC1uB9Vf
+5qL8ZP0kNCLcEsi42a98N9NMBef4XiBakGE80jV3rE1GZ2lIC4SFFd06K1VkB13B1ZG6L4Gl5ft6XK07hG5Q2hZArD
+EJk3eDByx7iO04K6MnG6i262FWfE3P8kQAVX5rQ2DEAIBBcN9zT4RnFAr2mrCXAFKWAqUE80F7WGHA9M2ChIDmGB3K
+7L5DSk1LP9u900TGGc2sR7Fm68A2iSBPY5ZI3pm29t5nrBDyDgX7az4Eq8aZBGtAXvAixBwEEQ49H0G4X1Zy2WT4PR
+6PH2mtDf7Cc30eL7wSG0WDcg8zP6mHEHbDp47Ee71r9tRAfbFEl8SH9pI6et3MsAswDS6C001AOCx8E51BIoFu198S
+4CeDkw75L2roGHJ7wV9RF8xL28i27x3GH0jdAGR3d45WMBMq25d2r26L99490rFB4E6nM72S4Mr0wkAfV3Qj2GaBKg
+9Wi3QX2uc55oDK26wI5cYD8oAzCEac7gFBze8msBmT9z2Bhu9T7FCYBwH4tvEDH017DS29rI3DG0VK4nyCg9Fmm2Q0
+DHF7Yl4sr7PuAMPB2E3vd5LZ1ACEb948w6eI9ms75S1TNFXQDV7Ay7CaH10j7y3CR66B04yh3R2CKuAZ3DmU0ju0fo
+5bS2ARFVi3ZT6uc5Jj4I0DMa8Yg9N51kcFQZ4KnBe30mx9A4ESXEUG9No3ln4Q8CQO0n8El2Anc6UJF4mGLY1fu3l2
+7BZBqa38bASfCgy1596HS1KPE0J5sB8Mo0lA8JlAVZA02B2b3HF00vCOp05B9hbAdp3B11nv4nz0l98xH9JC5yKBN9
+EV42UTCuJ0wWC4W6dmC1d7x22YqCrZ7Uh4NgA2x0Fs25vCAn73C2r9B8R2rT9PiGMMFlZE4r2eXF4M3n5EL03qLDVZ
+1Pj0ff4XBCWa7so9l3CGC3OL6bqBXq2A36oe4dt4FG3WNEC2Aln2in54BBfo497C7hFC61rm0BWBW37SYBSq1HLC4l
+C0RBzy0o22Se27O7kf4HzEBHAFoDu54MtEiaBQsCr62e5BBN7kpFhaGMVFY0CRvBjMBsnC0J7qMBkN6IfG2G00m231
+GCE2239ysAnC50eBqc8KkAqJCauBc2BnBArWBfJFWV5uhA630C2E4a4T5Dg87ix4HU5RP4jODKp3pr5k2Ef54Lz63n
+1S5DaAEuT0LH6APG3K4nY4C68UuFLJ8apAXI5XvCGn5tW2f1CJD7OcEC16oF5ivBVDAdg2pdAAg7qy66IDKkADVEtw
+7Gn0TZ5uH6e0AtRE1zFB62tK1qlFGdEI39gYAqa5soEiJEYH3sa8W15BB3Fo4m44zZ0GM709FeK7UzB7D0qJ1LwCOT
+FJtFiOD2040L4u89jhA4SA9JEuc1S89uB9YQEoCE7G2TmDOQ6afF9eAVD9Dh5r51KBAHg3An6Md0V63C7E0hBiy484
+8ZD4eyBfE3mJEY65i5CT583kBB69pr9pq8xWCIa2VyCy5E7s0F80K082U1865ZLETV9HE6quG4k1QmGKR8WlAGlDEa
+3dN6jaBzH0jKEU33hC2TL0QIEeVF22F3J0KY93P0G39KVAsnFZN4xW4QB3ZwGEh1PDDzF5Qm2yn4SD2EQAyAGIR1tI
+AgX984AVU7qmG7G2lu3qXF9L9zyBN6EkJAnGBAVCFV9MPBDCBj72gvDit2xo5EIDKi2YA0ZR1gsEtDCRq94O9SK4o6
+0Xu0fa8UR3f23nZFsKDZLFhzBcH9kkBrm62M90n7ag8xCD04E4HEz5Cx08tGBBn8lb5o70aH00yAMS4XOEbi8w122Y
+FNlFX96A76au1qr415FgnFfv5ZD2Dp4laEP8DXS3sIF6G873F1O0Xi3eG3Om0IK2Y774pD0DFhZ27QAKYAW58kcDIh
+3AV4pJAWp0QG0yG2Sq7Vo6y1G5H1Pf9MgCwh0am8k5FsLAHDBgR7iEFoQEdP1wc5IY09C6R94Zk6OY6f3E333cF1Ca
+2AADy07nQAfwELuFAH6ZYA596iO5O7B2K1fPErYD1FEEe73B7H91v79YADxK7NW4oH3WL25aAxnE3BG117wsDp9224
+DRrDRQ41s6tUGIFBB210n2ihB8gAFe2c91TjFpk9F0CT8D4a1kVDyH1fEGMDFOa9wJ9jdEgIAsfDPu82bFCmCcH4vD
+1SECVg4U0Bn6EAC9053nv5G3BvDCI13Yj8ia1w8DOX2mQ4IkBTV8kg0Xt6Cp9zA7aSBoE5ndElUF7tAf2EdI59WBje
+2eAFd2BoRCHUCjh1mt9iy0b49pN6gj6Od4gQ2o4ERnB9a7PG7uu82XDSKAiPCN09FGDvL18X1FeAan1RU34x9NA6ng
+5htDo80wICEf7NbA5m6OJ9T93o21tx9V67KT2YI2dE39nEc21zQ003Fnx67o9RxCZACCLCqD6awG424CT8fSD333M7
+F9M1Ff83FAUS9Z00T7Eea6NQDvA5im9PnEH6DYiBBsFNvEabClpC7UBQy8m78Ba4Xj1JJ7BQ2swCIcEx89Hn7E27cD
+1fR0gN3L91Yu0uQFJI94C4169bs1DKFn10Sa31wACJ66oE0uG5t08X1me84X8CY0PuCJk2y32Dh1lm7qL1bH3gt6JK
+0to26r3183i16QN0cB9UL0j7CZFExQD9H6Jd4EEFmMCwM8UE1Y1Ccd0y6CFb9tQDru87C0Wg2pYCxoGCz36DBD3250
+50a8nwExj35XCBP1KMESnBAGFi10BF54oDtADgO3RgCHdFTB1mT62c4cHFpe7u85uo4co24fB6N88P8H5872CtkC3R
+6EX6bCBdP4x70iA0r9E4P6Wr29CEcX5HI18OFDnBpR8WfBSG9IBBpd7oH11DG8e4Fl6hAGJbBJt9gQ7QxAqFCpN157
+0XJE1p9KD0fS83vE635P64IhDaT7n3EDI3Nz2iM2jD1POFCdDRh05GE4h4ibBhk6DkB2eE5s3j6Cpn3Xy0o47fyE6W
+7gx2Fu62I2Mn3q9CjP1uhEKU8mOCxI5N47k99gD8KOAFK9fdAtHAJn4nC3p5ErPAHQ8Xo8liCJ05FW96h08GEfG0Tm
+EHn4lIFzEAhE6AlDaP6ueCnp0wf61DFz8Dz24pS7MpGAo7kz0652cR3UdEU0EwmEsQBRDCZN1kzGHbE4o35LBWC9nn
+74dCYt1AyEzSDFnCU7ClB0kpCf59kb4B4CgoE6p8Rg3HoCoO4D89ttFSp8Q521TCsm7eLFD1AYQ7QG6hS0d1GDE17O
+CMpBL31E60JVF1REyn9ih1IABhe5Ij8Rd6mT8LeBg2EVVGJk4qZEEECEd6gf55xDbb8Xl7IA1CbBvIEVa0EHBiOD0M
+3yXF0lFYHEcY0iZDyTDyY9qn0Rj5mvAiW9m398mFq6FEY43z7Hs6Vl5fRCel9RO6aEAXZDqV695AffB8I8y0B6V8Y8
+4xw3IJ6nh0A19fF9R8CCa9UkA7g2sL4Xx1JN8FjG2o5M30w2D57E6454x57JEJgACCDXMBjm0dxDJZ4Mb2LSBLN0z3
+4Sk7qw1HHAYpArMAS0Dfu5Qy1td61UAoj8kX9SJDu23m48bWApv6gd49Z5BO3X11uJ1ANAFv8GwCQC0FZ4BR2y0CNB
+3ob1INBXnCAM1cj0WpDQCAJj41f8R64lw2oKBf2FNw6BH1ds6YP0n587vDdMDro4IjBwK6U62DM2hA1u67fx08NAxV
+Dmd4seAci2X91NwFnYFSU5DC3JM8H6CgeF3w3YFBut91T7GB3XM7Vp0AtAs31Wd4OmCjE8rk952DCmEmhEGpAfsCOX
+CV24FA2iP1Sy3G32Hj0oxEPABUj5qyEr842F1j85sUDqK1u1EmVFFtFTMD1MBMaD26FzGChQFVmF9FDZuAC3Aee7nK
+4qA81U3slCsqEkv1wY7ca1sf5CMCcr5P05QK9mV8LXBb6C065jw9L6Cmk1rc1m34Ep8YLDhL0G994s2AHDjxFDz0On
+55FDqg04q4l39MTDnC8JbDZwAar3OMFgf6aB1cb7HIFsD12O3sY4oq1zJDRM5848nxCm37mt4Z5CLK53l4JE7kAEWm
+AA4BZT3xAFwR8g10dC8ts60j8Lb8Kt1TqDKL9fL7Fu9BQCbIBEh0H89MMDaj0LeAv98puEsm1dKFGI2hJ4rz5Ug5u7
+FSvDGh5706XDDUA4KQFaL93n6QyCBQ4pd692AHFDrCAWS9pJ6Qu5bhBob7Od5Ok2ul6ca1ia0Wm59rG4EDwRD4PE5B
+6g128r4obELeE996b2DSRBoi4k47no1dgBQE5fZFHK12aE6j6M83TH36p3Ch2o66649660FD5UTFl1BCEACn9siEci
+1LA6v08rN0Gd5x30WED0h4I3FAf9Np6jO37y6YT7VI3607H71E7G29Bh61Ac5Qb7oT5D56UW4frFA36DHAew3aE8KD
+FHO5YtBBj7bD5zU8GD6fS9uc2qIB6r5ww4H12DqENZ9fq9O5CT02YW0hsDM4GKGErb870FNs9o03RJGGHEQd8VK34l
+Dm69NsFN05UX3zDExNDmw3r92PnEvD8ee5s48137H06UD1XaFob6U34pz4gp7W47HLFYD60r7ZCG6j4zRBVQ7dr2oG
+Dht4JG4edBgX6o4GED6MTFlV1KZ7MO7RD4FfBPu98t7X4AT03dwAbXB9z6Dq4IqAha1Li23wA9sDhr5oyDGe4XIE05
+AOcEEP3fj5dXASe5sJ5HZ8uG0CT7QC3IV8198p6Fr2Da5FVcCmC8h0DCv5Co2Ty1jo49QEwk3HO4dd0ys5CWFIp6OM
+EyuCul8gH0jaElGA0T12YCCO4px3Nw1N7Bcz0O16aW0vw5V79H52Bl2mA0zG2g653187d1mW89c09d7gd13i6FW8pz
+5le5LKBZSECP1EeDlL3DV2F98lB8RG0u3AqRAzPFoHCZe0610XAFDL0YJ83uEpwAI9DSxDVe5XaEKe3meFTkG3A4He
+DzP5Kx2N8C4b9ET6g3E4v4QW1ir8up4kL73o6aSDOjAwp69l3WG7HW0oJ8de9Oj3fCBUiFSQ7nT1qRFUj71R4oREk2
+CHO5pCE401mdFlw1vSAe06L851f30aDgjD44CIuCl03XT2ub9pK2bn7vy6dW8Xm3cH9Eb1oQFEr3EDDNt2T4DeE1vr
+3Ef4re1kiFnvBuU0LU05aDJK0VOAer4t6ERw2Ko8XA2Kl2IdFvkFJGDV02SAB4FA715Sg0RwDdeEZq5UwDfODiKAUK
+0ME1tF1ZaA3jAKs1pZ4LM4sO1uPFjp2ZqFUo0353Ti4PvAut72PC5ACbZAaI345Dz412uBw69fpDVU8EWD3245x8pL
+1XNAGaAoV75yAipFkJ50I1Hq02n9Df45i9odAoP7Ud5JMATmBS83tR5n47BnGJ5052C4O1DnCDo2gqFygEqz0FQ36x
+4HhEVs2lr1xo9Pp7cU8H8398FT70SG4N10xOBK607o2qMABZ0750ra5uBAUEBt76aDFZF72A34e4V5DgtGBR5Od88W
+8TE4uh43RAeL6ywAuhABE8kq7aOF5cFSx5LA91I9OzDOsBaZ5MC5az1djDYF3OWGFrDuDDDWF7I0kBAMUDnX2nSFd9
+E2Z8iZEMS8XM3mm4b5A2iCqp7CGAwI4ASEjVCQT8fkBMJA0gFpf7zr0s00Zk2JM0Pm9viDiV86RFwaFQE8GVFya4V3
+6uSDuaGDN06GFelFBu6Wp2J86xb78t1na4dJ1p43Ah3H5ATiAYc4ePBSQFw64J3DHgA5853b2hg18jC2KDKG2pKEO6
+CcZ5ssF7S2sMCca1WO2gx9HbAUb3OrDmu4u19JnBmH2StEe42KdG2J05qFmb4gx36KFtH00a7Vd7pWG5V8MeBzmDrU
+EhqFjx0JG7Ro7g7BOY9oh5ye69jG2M7PH6URBAA4Fv9AU5r62lkAzN5Ga3CyBpyElQFjADDJ85CANb5MK5YvEzFGLP
+DsCEIo3bqCm06dY7b1CJv60eBtc8vs8229VMCjo56O52SENA40bFq29cuEmwCJb7L7CgO1FxDy20m93yT2Z86uRDM5
+CB72YTCFs4nN5EbD7o55Q96xDqc5hQ1c68qJ3BL8uoCIs8px76HAidFL967g1wd22X8U02vg8dT8dJ4MoFGi3I56aI
+F4622sGHqCWU4g67QYEJF5DX6DF8Fc4jzAbqC3EB4x42tC7QCjqFpL07A5pD7bp7h2D3kCO5BLv3W49DA0MF6iU9y9
+9Nx0oRD6G71q2RECSZ9Hu1RL5VMDt90PC09qFZV1Da9BiEbKCbWFFK6qW9tE7Lj1BY9RsGJe9Q2AIr9BNEffCYR9nP
+1RBDEf2MUCUG30NFqMA1C1CH0E4Bmx0rI3DP03t6q1CNqAVA84d6zs5Hb4tK9QeARlG3y2iHDxm5AS5wnCq79MwBlb
+EoQBz669X8ht5sqEs8CMA9gL9k5CJ48BrEr40160TEEdG8KE520AAW34a7ks2ol25S4jl8CH7t5AKd5cK6GQ9q9Ec8
+3S26cIBMh84n0wXE8vFL14WOB5N6z304E3Ox5vM5fQF406os4Qs0uE5p9GBQDgCBFZ7ux3AS2iI8fB9sM6aVA4P7TU
+8ai7ou4ADC0zAHh8N5Da6BmF2rw9yG6y269vASN4lOCWJB2l6nt3IP7494lyDYlClz0lV8XnClh9pZAHLAXPDZ38vy
+DOGFuPCcp4XQ67jBuR5tIGO6FVnFBE2SkAb13xH8Hh4596A9Fmj0ok9MoCB20iWFk71YG7XQA8Q0Rl9if0O68MzDmf
+DnI3HiBgv3fI5AFDjt4VYDFTCSL3FQ9AaCziDDiEXD5JH4vhBnF38W43rCpZ6RCGAO6vrFEc6wZ5lGDa30V43yx1Al
+AxDDow2Gw9R15m4B3o2Fo1WGAFk0wSDeS4zVG4g2wlAXeDB19NV1gUEFqCY48nTAbQ4xb0zl7Zh6JmDqLBJ33iiGMc
+0FzDLVFiVEUA9MB7GXDzmBbWF3gFc37lKDMz7Mo7l84QD84h0XDGFJCTW53x5U65QtE1F45L7dJ9gE4TIE6bDLfDQH
+71T0sjA1Q2Hx31DBJO9yCDCs3wC48f6856lwAzo5wJ3zcDex05H5ld1stEbt9fc4L3D5TGEUCduEsg2ds4m5D2gCpY
+Eao5Fy3cUG804sh1dI8n9AZh4aH81tBwVGMB5kX3uH6F5ALZ4bH3na2GWAqWE2a4v32Cc9s3B3cCt9ELV9ZgAGiCot
+8Iw33PE8x4VlFVU1ib6j3F12EbuAzJ0GT0rCDghAA5CtJ74H68uENf6sK3q78vX4vO3Oi8Zr3bg6MmBbV9B3Cqc6Xv
+5Z257Z7Ii3JR7XnEx9CaX76zDR24yIG1g8sy7K2DIo0UUAsPEfnFlG53P82x3idDaBGNtC6C1Y32QxAKQB8T2jl32t
+1l4EHLD4uFkq9AAEUa6Et8Aq7z4C1294h9MEEQMC7j7Vf5Yb1UG4A77337ygDMy8XC9DN7n8EDl65lEoe7HM64d0Jg
+58uAdV1he2V63lG5xs2g78fu4n6EIa8BYBJrEg34ZIAwdANJFT8ARX9kvEkaDJr9rY9XPABtAboDve5aG6lM1l57v5
+8b51UxDW7CBY3pG2V82mDCxOD86FRn3af1mG8Ca4zeGGQB0h7ab7K4FPw0mwC9P01PE838DI2711Pz4RU0Ct3F43Jk
+1Rx1bc7THAoaBmuFm6EuK8zb3FGCu84GE4AXCHj5XsAMM9Tx4DyFBl1piDj1CFBEBsFyFENDFy9CPQ0Pc8JV1pJD8Z
+AmC5EGADo5dvAYA2Yy6wE6dT8sE3le38M2dY16e3OwFM3G3UBsv3YIG2RDOW87O3F7DaV6kk0g1DyUBpOBi1Dho0Kk
+AXp1TA8M64we8JL5Q34RV4mM8pNBch6Nh54w89y6Sq4ha2sG7Hz7xHDbz3FmCoyBoh3Bq2wn8OHCfk3W5AUM75tF5R
+E2p8t3AgrGL8AcTA777p4CIJ77n4pF9Y23UD6aU6aq7GD7e0Eeu1a1738CoE789Fi2Ab02kuDRI4Ez5hDEgN4OG6eq
+Cwo7xa9LR73Y3sPFe02BvAgaD803nCEvf0O068i6ar1QrEWtG4bB6D7zI3PL4JF8yDF107NGDKm0jZ8SA34n2RRCQw
+CvA9ah5lCB3U90g7iHFFJ3uz0DF2LPGHV3qm6zI2wz8d9FU2B4L3j73eqC011F8B1T5XfB3v42gFSa1A8Eyj3p0Esc
+0IJ0gW8dzDel1GK79T09h5wO3NE0wDDLlBQ845019J2xQE2V0X3CaOGJrDKJ1dP01f8EADzT81o6BzCy8Apx3qJ68G
+0AVCo5Cwj3f5FAi7hI4AZ46BDSX90IEz28987OB6xx5CkEgc7696lv7Gx5Zb2jm1nr8JR9hgAy166d4RBDiB9Wa6Rb
+GFg82CGHNDW97iL6OTF5F1ocCKG6565832rD0wd6da1A1CKxFni1eoDXg3GVBus6bjE8e4szCVW62t2q603jF3P44M
+Fkt3Ng7wH8aoBBBF2IAMOFxrDbSAdoDpRGChFyNBdD3VOEiG0KM192EQRCfmAGAEnZFvO1CBCZf6r4Eti41CG6M3pe
+9OF3rc18R2tu1usA0u52h4HMBgc7jl2Xq1DdB3YFYyBWM0CO4xk1N219c7mkFkN1lK42Z6eM5c69Aj81a5KvAHTDyg
+FyZBGhFEFFVbBWHGA03jl94g7fB6ff8Gk2uJFHd7xPFpUA7B9ls0tQDIK1FS0MR8nSFJbCXh8bF5h6FnDBGb9FX2Qc
+08D5ab0dd53F93lD3U2l6A6sBOA8hBFu31CF06P8aK8Zf0929L27Qa5AHAo53RDBWF0b17RO9EG2L0BocCE42uR5zg
+GMe5DPFabENJC5M3T0CxJDk45fE6TF4aYDSV6as8F04bj25m5ON69EDbC4TZ7qRACg1ro6KU2EGAAk5Q20hX5dW8tR
+C6Y4Gr9Lf9Z73NhEYACTA9Eg8iAELSCM9BOLDkh2EB5FZ1Qf20r9f1AuUAYDFRs99K6blABI50E296ECtEGgFTRAA0
+7qaAOU5HGDnQ4RQFZr3DF9v4DCABdC8MFAqy2tq3kd8LBBSFAD3C710IxFuN1Tx85LDe368LAtiEuR1t60oiEER88B
+5A1CadFtDFZ533REdz0gm2v696MFVzFCG4mD3ov6luBVdER06lC54W4wB5Q84jgAG40240JN9pV7E3EVYCW83m9CZb
+1W8C8C8lv10H6RqBDL2Ds4SW4iODMA9V89qh0HS8ng9icBuY9m22Y58dyFSK1uzCM46tMFHy0h3EZjD8f0dL0sk2Lo
+6kM4IYCQx3fr7zZEUf643FPo4cG3gnC5rCrd4Uo9ImEfd4kG9SOCQK9s40pgDpv1Pc6TY16j4wZ1E18t99aQ0cO4ov
+BYr1JqFME6lG2wD2Tc7AzF5QBqhBuBE8rA4REpV4SPAl45rF2gXBjcBL4Dl67CaFuY6b0E44ECCApBBJ9C3H8va4pa
+6Pp6ozEaU1oJ9s985MFLzEbgCrLEaWFuQF4uBqJ8jn36O6RR7yvCYcCAW8yE3Xl66L2Aj3jJBA3CNW3D00g8GGfF8K
+4BoDHuEGs9oQ7Q5EY4G8s6wc3U5B35AHiFr47QkCwGBJT7OH1d24fd5Y88afA0DEdrDXABu33wBAIx0Yq17P7oeDJH
+5sA19E6jXFmnC3g7qqAO32SD8iB239Ax7GKe9jGDFM6Mq1gl68X1tO8925Gw0h12nb3Yf2OPEfgE2e4L1ANdE0i9Dk
+AUA3QO7T08TB32e0r56fvFbe6Ls1ob3AG4ie5YM9zH76oE908sK3PQEYrFSd7ld88d20qB5724LAChBSN3aj3lP1yx
+8Fx1j97IE47N8P4BGKGCI1bVA0s19pDvG4YqFERGEGCc1CVw4HNEXICe0FZZ5lHFxH9lH3Ei7EQ1BC4zi1Bj6IDCU9
+Bv20NR84I1d72TJ6SiBmnFo35Fl8PS5d70rrEXLFJz2BC2TADKy6U2AzB3NxDS16Ol1f1BFp4P9G8n4JiG1M0aK9fz
+5xe8V3AKIEhC1MFFsW34Q3rz2XG0Z786qD6J3Wl8Yc4D4933DhM7FI6SH9LtAdM11mCFS9A07D8GKdEee0R124rBbY
+86f85V0np4NL9Nv6hZ9HgC4MC7MAAK6ba0eT3WD6uW6UQDGm2KJ13t0eA5Pe0QZ3zRCINDHZ0P421jDQLB9t95s3WB
+8MK95b4O92xR6XG06i9fV148EssBcM9uS9PcDij8LwA3N5qgDEq7jH20W6uv4TlFqrELIAOtAHw6Mu8F6CZn7OD7Xo
+EQx9ErDJ8D2X7tW0qyCP9FPC2iw0Ff4x4F2OBokAr4E5b3Kg3Ej1TQ8InAJ401F5zI2q21624Wv2nsA6uEZf9KX2kE
+4UD1Qn2WP07N6B91emErL6BD1s0DPV426DOH0v3AMVFLDAF20QT6yAEUmE28FzXDa7DKt8zW8FV6yHG0tEHu2DTCin
+8Oq1gN2eu99G7II3wo2F33xS7DE0EU10V3csEHS4Fj3EbBJD8lY9Ss3ERGNc0mz3Ew1063fcAObCYVCkP3suFP9Bzj
+BnY9Dt0LYBYUEDU4tD5zl4Ws2G0A1p31n3U75Up2GUDZK7Cm8MYEKLCzoCjS6sp7iNFbhCqP4029aI0cvBMp2Z79WH
+FVa2XL0b2E4U8Qr7vzDbdE368141HK6xdEgZDPAETmFqV2Na2WF6DpD4oAZz7AN7ct6FpGCA5my8hV2OGF0hAM88QY
+5kn8Im8T348RClu42TAlW6qBB7k9obG8O09gBeL2OrBnIB8857DARa9mA3iT1WZ9Md1wO0tj9QE2TRE48E8I55aA99
+7k4EyRC8LBKm1IyCGD36H6mpEaR1t2Ee0CV969t1PeEdlBnN4cAFPm7br7gSABW6jlFiJFQG6ZgBCQ4ID8ZE5bv1cz
+0gt7pd9OB0Gy06jAj04Tm5jQBFqA2jDFR30s6TlD7G4QEE6R6YF2BP5fx8kH6LrE0NA9g2XxFLB2nREGvA5cBcGBPD
+ECEBN22Mq9tz8HIG2k70bE8Q2agFLZDTC2mCB237CdCHi273B9PFg5DCQBSgEQl98M2xvCOS6bFFgUBjt4Ri4NB3mb
+EBC9Mz9kJ7Y41bm8HTFxBFYt9je1hd6qU0DEA0GE9h1Tw836BQS9Sv1p537CB7W4IFEkt9Bj6rlA2FBCs5uf5B99se
+DvY9a75634ZDDtiGH2CJlEZJGLc66T3rn0j1AsE40w0R27y9BEKC2tCOiFbZFAm7QO63UDfXDWx3ID0yhBNc7Hk1sl
+66W6izDjSFuD3hH9JA9qfAku8mvAP82lRBGz1Or2Ol2nX07Z7TiCjA8IdFuc0C36Zd6914V2BgS0k6AOZ5EQEluBqC
+CtoGCiDCC29c8Jq3QV99UCxm2iW2VP1168ys02c9fM3YiDaoFjF5I66PA9ySDVw8Rr8Qj3pB5hB0eqAkzDhJC0w21n
+BDe7JyFdm63y90cBXT9RK0Kx0AgDEj631A6yETaC5B3v75Kj3iZ0850soG3r5yd6y3GO005s6A38dGFbF4y30pZ6sH
+AqcEamFsH4rI2nADiF3IX1lB6wd7JV1KE34f0d5ELw4J6DXZB439VHDAuFc2EiO3DeCEW4Zr3tI5xd8sJBUX6nG8OZ
+5NG7gH9uM5W1FNcBx785f8xBEiBA015oIEXwCbO0RM7L31qbAEe7IO0LL2X0CWmCne3fX3zs3lk5AbF63EsLAAZ5bt
+BfD1sj2CLD0L0j22Ya9jH60uG00Aea4B7FDsFfw90X65a2PgBGJ3K7BHQ57r4mjFci5ir25V5ga0WyBcu7wuB69GJR
+5CT1gQ55z6KA8ow8i1Ehp4eO1b0ArUEjEBJQDXD7Gu14r9Es0tuF4Y2TO34uAxWFEZBJAAsL9EmEPo6ls7ob5xjDhl
+5DB0wv5z7Byg36gDjgAm60tM3o03N309V97L0hq6vO2R49UJ9IM4LA8co6AC1QX8PD3up23zCvl8h67lCDxMBGi9WJ
+3RGBam17b8d02HIGJB316GBV43T89e4Qe63F0IE4x2EWU4wjDod1dcCfhD2N63Y8leDqG0CBEVZBNw5Wn0NJ3X51Jd
+2Oe2kOBuD84DDyM4B14iEAgY2oD8b01Mb23xAhLFVtD8I7bR3a0AWV2Qh8xs80mG820Eo1Qh26S3A7EkC1gT5KI4Qi
+9IhApd0jx1qm6YwBsG4EM737BfW2kHEpxEXc6wv4BO547AddDhZEIT06OCJz5178528Z47Rc5Ta78W3LF6csE3I2Z1
+G20GLQ9n3CqT2h51HS8r4FYB6Up4O467sCFq0aSFqO4gj3ZE6LED2H6PE0DR9PgAjv47R6zh7MQ8sq9TpANZDEc3q6
+DJ12cW7EJE6E93f9CZ7wICDP2vi2MiG391LyCer4ix8s4EwpDx71WCFbl2qO9NW5vA0mI1MO3RdFZT6PMCLxETf51r
+80S61Q4pIEUi3YK0KL6X35jT1gb8EU9PB7Z07ikEWL1YyG4t4FOE7kGNB9X82Et4hw5BV6lH2DaDgdCmpDuVEcW9no
+DnR1YH2jC9qq8nk48vFyJ9hf0T1CFQ2Jo4Yb2SGCFW7zS3w63Op4NZ7cE7jMD4N1RC7JQ6uPFVZ9lj1AkFvVCCCGDl
+0iKFa23Iz3OJ1Ei96z4OR6EsFjt5C991JCyL2LOENLEKX2ST0A74U21XGCGABPN3yI4q950bATCCBe7eO2nm2aR6UY
+8N44fRGLs5R54jrEpuFpaF5r50gBs30fi2et0AC3lLAAhB1r5EL14d4DC0iNAAX5EgD3F4Yn0XUAN83y3C3Y1I37PI
+7DN8L27a13arA0z9ONB4o6c1CSk0jl3moCLs47u8IT1Xk7tRCUcDTI5MqG2g12A5sP8n71WvFCA4dSFpKCyB3bEDd0
+Aw82FyAWg6S1CqzGGDCir3Wx2HH9Vl27A8Xh5Og6YLBQv3BT0ms8mJEfl0ZZEFd0Ho33qG7wCzL2XRDn32oq3oi46w
+AlI1k1FYO6g81uD4Pw82D3JrEbODC7Bdj5UL8XYBAT3uOAuz7D94bzA15EKMAQQFL09g4DBT5nFFlI2mfDmzFK22rq
+Djk1Cz7t61Ue9LX3KzCSaBpp9xOD1U7l57n69nsFvy1QR6TG3HN6aX82K5ZCA8G3SqD4G9inDxnAKUBbqCmxBkH9ov
+4UcAht7wW9In6Ny4A016BEvx6nW51e6MB6cSE4uBZE6C46LU7Vv9SS6GlFFF3yk4tn5IXAUW1WK0q9C8hF5J49jAbK
+2x84W9B8j2sp3ib3mP3wb03c9iQ1JbB4S6zR1ML1i8BhMEeBDQ0A0t2lf78N5PUF2SFZe42c1nUAjU4nI9nw3O18bO
+9es2WI04g1YVG718wvCMv9Ig86jBKS0fqCAl1fcCPp1GRBps3C2BRc3zKBHc0rlBhsBy49Wl8zV6cw2cj51u1zzFM8
+A26DcL0vfEqKDOT6P78tV03o3Qu9ZC0wiAg920i30B15zE84FRlEYeAji8kp9WI9XYALO6ra6Rs5nk4g47hCBIP1yD
+7uU6st15fG0yFpg9WrFNY8J69tTB9R8JvEgS3E7BiJELqCwB9qQE0eGMYFTJ83944G7UeCMQEGG9jk5B17LA3d1Byw
+Con8XIFrb1Qc9eCEEl5nc8xw6LzFcA2ghCr58S9DsZDm7Dph9yBEpqDK04cUE7E65i8fr3Yw3hp5KC9onClZ9Ur5qC
+9A6F0XBeI1IB4kM2asCnj0vLB1y95yCmg77A9byAUj8Uc8sV5tf3xQDXX6P49MH7VmDe99LgFkv9bbB1EGMkG1WESo
+1GPFE6BISD1V5mzBGA3GW2wZ8Pz1zd2z1GFpFOn3wj4xpDgw6rR1bUDm4Deo96G37zF0yExs8eN59E0ZT37A3H4B7G
+6n5AU97yz6KXGNsDU97XC1UK63z87Z1FpB5H6wVENmABYEPn3Vh8fnFSy7z30ug6Ub3Dx9ScC3JDolAAG36M5yz9SV
+BZZ0fWAps5mBFHM4sY4tT0wRBePBLW8ZU3izA44F7qFc81cNBFP5PlBKf3H31Ng4QN62T8gq3jV0Ee0Fo0dT7lf1tC
+9KwCtH3x98oR1ON4y1CGY1SUEiY2Er7lxBRm4gI1Xx4wEB4O1vdE4yCQA0Pq6L52XI2rN6bIBRY4j9EcZ2si8BP1ox
+3xr45w3jAC6WGD6E495Pb9Ci85x0cl26y2Gh9fWAp96iC521G953paFfP2Vk5QE2jUFZoAC63Pr09I5W45UHBBa2m0
+8NM1mv9fU91k3nd9bNC501sy7js8CjFzC5Tq4682MeAMLDvp3XP3fYFL75qsCYmBii7418qi4FC3emA8n8k87gZ3Av
+3fg3ss3QFEuE2qV1TU2JXFEyBYb8HPDZDCQm60aEwPAXt1rt3p7Cm23P93DcAIj2QdD4jEPdBoaEAg7ro3CWFK8Cbq
+83D1RTGGnFq961P3MR6Q8645A1mAjfCqyBcP5KPBeY5oh4g35qQB9V5IS4ZN7FT8wKERF0sHF3NFtl9szCogEyt0ck
+4ggG230E3Di597xB4G2053Qy5ktDH4AQr0hiF4J40fDA9DFp9l81y6G8W9qc78hFHS3YH96q3oH6P97nj3Pe6uj8nX
+8NgErUDhXEBaDqYGEWB158REEX9DMsB0D7ZvDiU2cB5mMESTDoP7MGBRFDdz4moC0q3WS2cb3f6FLG4GH5Tu7g6FEj
+7NAEmIG3P1wb00r0RJF4t3Q86hJ8cVFtK79BBrBCkV1ub7rK6aFBiP8GZCpz78HBxoAZT9kV6GW9JJ3x30POBSJ6qZ
+AKo0YX2K20EyADgCrrA8H8ix0gfDcj2R28qLCys59K5KLEbP7NQ8Lv7oPGCPFls4Q21NP3Pg0eCFby9YZ5ebDHK1wI
+5BCAJt5mO8ueEwqERMBvY0UnCAh5Z06nz3Xa3x72VoCgh3NH8Og6nk2w098E5iz7TB8LoFz5EJPCUnAyV9Rq4GbBhz
+9gRGIB0wwBn0BsP8yr9717yc4XvFUD0Li8xa6fNFVBBmsF6q3HyFPUFAU6yK68vBzACTF4BP1iXErXAMqFFi0JnBfZ
+5gt4je1f56hp0DCCWKEIPDXBB5YB9oFmV1n78YV31C1OB74O9Nz7Pg9iHCn5AyRDyB4SM0WZCIX1GV21c6cz96nAtv
+7GA0eV7m3DeB7mD6P00bi0xo6PcEVJ2AQ978FG43WfAPq0r75g07UmB2QBlj9iI1mL2rm2kX7XE6U1ESvBqz5vR24v
+9Kx7RY3gh8Kz4FtD3Z3nU5nZAoQ5PX3CD0EpF8SD1b12gAtd378BQg2Y15ICAfB25zCqa6LK8RqBgfBvb8IBCHb7um
+G9C9kw1ZP8sT15OCVmGIe9slF6J0dSCEr88e75GB1X2dq0PTEPPGDv43c2NfCCrGC8CbT44t9m46SrBx49xn89W5hn
+47jEqjEPlFwcAHW5sg1RHCyq6nJ3FD9TWFdQFFN3KDEJUG8k68lD2YFvu0cb3sy0HWEyc3ZrAXO2L99epFFR7Xt0oh
+Czh3fkDJV2r0BgABDsBWS2qt2P79iu0Nv2QWF9R96cDYz55y2HNCAx4WiAPYBg8F8hBL1AS74O18BDGIjAKZCCM2Uw
+7v177s8er7mnDpEFVuC7t1U6DrGAIo4lHDd15TrC1N6qpBesAPsDlIE923zi0ZvFRu6QI6QjAi908t4lbFde65AGH8
+CACFb48BH4hr5Pj9kEA9rAxwFkmG2s4mR7alAPl2b33d0AvgCdl3Xq8CvArF7LDFnQ2JZFQIGFA6n89Yk5od2BaC7q
+4Sc6Dg6eg4eIF8c72ZF4wG6Z1cQD3RBXQAol03Q0nTDBG0H6Ff52caF3U5UtAF48Cr2G17fP6wfFZIBjo0mBBCPE4N
+AYa64KFmvF8E931G5b8Ec21o1PRFkTAueBcv2BhFzmEbEBeZAGv5FuCsr69gEg93kHFHhG55BKO1hV0gCB0t5b0Cly
+DkU6Ou53813p7EjDrH5Y15gyGMI2TK0qv0yH7at8FU4uJBHj0sC30bBeJ8ur3CdDvu5TG4CNBA092P8e4DbA04w0fm
+5xq7tw48VE6xAjJC448Rc4E9API8Kv1OKEcp9Q757B3tu9JVEkb2bw9wrBAf0rs3x10Ng2Ag74RC73A0JFD8DAaEL5
+D1i0rX8fl1FO5Eu571GNu471Fjv1az1Sn0PL3tV74Q3IR0IyE9jCrtA5oDPB12m6EuFT0Ey02Qj14P6jD0iy0tC11W
+F5i9dl2UKE9I2Wq2U56cF0OYBYmDTA9p99bQ8ZXAuSCRF0ef6wF84c65hEnz6TE4hs6dK4tc5yj0944TY6Ir2exAfn
+8UhD9B1MP8P9G9T2jv2RuBBx7Zu5xz73l76F1YOAdfE4cFKO8P5Ejs5Dz7r57HhFGq1lr4WcBatEpI15ZCNe2n5CZS
+58wF8PGGz4TbCph5cb3vaAdm4czDGI7mQGBDFe6E1YFsx0yk1jkA0HBk6EAzBzP6wsDVc3rJEE9FgJ9mbGKXALa3f4
+5Us2le0QUBdHDQaBon5lLCus7xJ5A691K9tDFae1ulAr7Ed10rkFa5EBR2OcFtf4LT7Rr0896RD2Sz5GN4kp9am52y
+5Y4G9d4kl6wWEEXEqm76K7iI8V22V75N279z65m7W6FuAE3n0nW6iHG4o3iJ0Xg7ol9br7iP3bi58tAfF0KBAsgDlu
+Ee561hAxe62mDBu5YZ88X9uH0xy0WA3S1FHE1cn7Ex0q4DeW28U86gG4f2HzDmAB0u2h3ColFR1DLOAaa3gf3us8hg
+7HE8AVA6vB5z5eK1kuAX93Hd0dc2MI8TeFU3E5uADbC0VCW73L3ESE5mC9waEJc7n009l7TFBjFF6mBbj9ZU0eN1TY
+23H0LuApq6fG9qr7bf42r5kz1Te7rhDDV4Sr7Ix75YB6O3tDEreBoXDS3FZtEBp3KI3b63PzFzl6LYC0N4nj68I3MF
+2ZaD0mDiiFDU7Ig3wU5ua9tAD4WBaY9CL9pp8cwEji1GXBQ2ARV4N0CDq9XE5RUEeU5ho6Q47p3D6g5J27LN9nWDQ1
+5Uu0D32Mv4x9Ce6FepEN81IL8Dd6LWFDCAwN6AMD765qX18cDiwBkm45y9UeA5h0xl4SHD2b9rT6JTFQ85eEFUH9vE
+9Bs7QKBj04WoB7e4dBDnl0PX5gmGHu2Wf4qS5757wiCbEECKCI71RAFUeCNy6RvA576j65C0EKS5avBnsFoC5gABFy
+9ZtC27B55AeQ1HoFGP18gFs80MUCSN7Xw1kt8lF6OI2PGFCZDneCHK38nFh34z360G4HXD1o13l3J7ERfF0L6xXFEm
+0EDAft5I0CDd3O3E0fCpuEzEDgq3LpGDM1po9wR42Y62B8FbDu05DN7jqBSX2wk9qu4pU21R2VgBOK21B4953UqBTn
+AVOFVS9464sL1YcFuF7DfFY97gK6Rk4op4EyDkF0er86M2m77pQ1px2pCAhP2hpDHqEp5Bcd1Ru6CIFiR1rG4ek1qf
+1Db8PWDUyB3GDK83joFMR8wkGFR9jA41u5xXFrBEAc3Ft64T3KH7MvDWs7Xz4iWG4R8hr90s2iZ7YQBg35H2D6p3D6
+FEvAgD64u05K3MY2OU6tB7Ez5zD1CV2IW15YER98mH95Q8zx7wE0hGG9XCwZEaw8xY4Zw1nnA3z5FL5Fo4yOEpB8JW
+0w7E2G97b0Cf2Gm9440ayDxE4i24j80nZ5HJBXf4db82J84x5hfFQz7UQ75C1IF8HSEcTFzw1nYEB9BVPDPHECZ8b2
+Fko55C0z572zBpl8qK4Hv6nKAvD2cDCba1bnFzB11KBHX6k57Nf2WtAH8CVZ1CAC1j1lA4Pj64k6aeG3v7kw84fCAG
+9FF0YK7887KdAZYAed1K70477UbFnJ9TU7j84eRBCM0DH6uQ0k53Eh1bQD7ZDV8GGTBqb5dZFwqAu44gb4f53mR8em
+8fOBrYDnNBTzAj7AYm7JA7nN02k37HFs74FB1pP79F6Vq47O2Pi7ww1LN44jDPf6NXASq2Jv1JR9IA6h61f7ASQAkH
+2VuBPzF8596m1HA1EZD5P52MCmVF0i9jF3pUDieG6kEBB6BMAgc9KKBmbEXUEH46r14PhEoaEBhD9J5KB3cb6bgBRs
+5x83y07DD8d31XB88b8v8BKPBxjEcU32C48WBpiAj92gE3gY7Ed2lVChn0PkBFV5F58WK6Gj7pTArs6WhGCb5dTFP6
+FqD2qUB5qDJm07kEeR50A5Fj62r337F3G7p1CNK0UVCMU4mWFOMF21FCrFr93gK3ax4wz2e2Dm072H4QI4RXDpSE9W
+D5o80KG0UESs7AS3V5G2d1xx6ouCqgCVL2nJCht969AsV3HB37dAu1CiQ82q5wt35F2tSDkT66N3pO2Rb3JA71v1vz
+64S9eYEoqDL73097Yy8xO4IWGHC9jq1T7C5u3dy2NdDA49aS7TDEMA7L6BVjC9O50J7iiF7YAJAG26FJK0Xj4Wr2dO
+AWhAjhD7kDVMAcK2R61uICHq8Hm8y3GD1D3t2a15XdCDTAJm5ayAjW3tH6BGAXT8TM5oD8q4ETYFjg0syFt05uTDce
+9Mh0a1CHT3vSBmX4n00NyFvX7yS3y569m8Wo7Rd2ULAMIEeJ9xL5VK7Wk9LjCuy5nJBjI7r8DtS6bn0uv4OQ3gNABB
+BVY6T92dU1PUDRdFyG5S86YD5Br1nw6W807j0qn22A80h7izDByB5VBHK9Hr3ojAriF8t3FE6VK3Y5DLH0SKCQW1mX
+27M97v33h1wKAvF9kMBa58T7DU66Wk8FXAe41TM1cCFJq46G2za0tcDblCLwGNN2Sx6vqBvXC8SEEZB3X4b19zOAWZ
+BYPBORDGzEZm4t5EI44Ps2If3VSBfPBbM9Ly8zr7saGIl5SQ4AtFR3A0nGEe5Dr5tRDbO0J81pgFBaEcEAv6GCl61V
+0Pg88K2sYFnaF316H48mhDNj18K8cB3YB6EU3PoEQY8jk8cTGJ92797Ve97B88YFPDAFF0IH5wZEno0xH0oE3XH4Fs
+13rCjL54bBlEE6DDQd8JB43q0hJ3vP4ZmE2A1yk9T8Dwv3N4ACBBl6BwT2GS51P6jz9fkBad0622wfDJaE1A2bh4eb
+F0zG4C1yAA2b3rH8aP7Uw6LwCZV5bdAGp55uEX23X0C884xs43U1yqAd09k83ZpCroFDf0lS21i4kX2aAGAk7qCCIm
+DwYAf08BKGE0Fdy9qo4Y48JT9mIEpiG4B0hlF1IBNl7kQ8ZjC9617G1l66Uo8lu8gwEf38QpClH3St0lrDzh2XQCzF
+27k2LaDzXD7x2Xl1MaFKYAgOFdi78FBlOFXN5Cd76aFFuEcCBNE4GD8CoBdFEUlDMN7Ko2SS0V7Dg54LUAkiElcETh
+GGq3Ae3fwFfr3tl7dZCoM3AHF500lP1EwAT12z541KG8N8UC3gS1ID0m4F7UCQnBDGAU27sc0Xp2h73o8DlTBL6009
+7XVDZEF7nFx06JuADUD1ZC5S1hsCIRDVT60D9PCFDVDJC59d8eG9aR30k8LpFoc4LJ6YtFhI15v1vn7Av1Bp0xn8zv
+7Lg11A4gd7aXBV1Ei58uQCPHEPiFnT3vo7Jr9bf5ds70f6RzAey2ge6CR5Pk7Zd7hg6rK8Fo4Rb1kmAo16eK8Fa7CH
+Cyb5Qq4IL9JzCiJ0Rp9hP9j55dHCKy0bh9MI7o81eE2zDBn835q5zn438ESQ5i71hXBac00HG7uDZ428D0J0G53A6p
+4AiBXs5Un8p8BGk7ZLCDNBBAExf1c1DvrCVQE9ZAQA1X81r35XLDET0WBA4s1JLEayEhLCnxE8S2fh9H92hx2eDDgV
+3ea0u44VqAfj3mD6Ef2F250ODXY7Cr1xM5rY5HaD50FSD2hs3irB201M25304Vu8o762eBQt5y67faCg67bo4pB9nT
+BQmBWlApN5BL7Co9vJEQN27BDBx9QXEieDqH7E5DzYC9k2YJEX88bvBsqCoL9ylBpDAyd7FJFvf8c50fAG6T2ES1NO
+4RM6ukDzt7J9C1s8RQ78pDdW7Lm41oBqZAvpDlgC6Z1eDArq6vC3mO5iBClmBzv8LI44407BCg8AvcCjJFwDCVJ5Vq
+FprBHC7KrEBVFlK6nADl08xk2gYCMr6FM1kIBnq2V07yx3PO6nFAAl0Nq6IAC7W0y29gy0ZoAUa9xC4Na9OGAzH4L2
+3C98hZAYd1nTBhFACjDYrFw11NBG5Y6KE576BDA1DA95uCtPCutBZx5LD5ue9EfAfI9Jr5u510dDbg4IA9Fz52d7LG
+8X39nE7RhFW33SU6PBDAP9GL00b1ry8bL0NS1PN1W1CJ94fxDbXFKS1uH4xr4rZ8B00gb757GNb66X9A53vTFlB3zw
+2b27aN5xECsy1Gj66P7qIF0sDSr65T0wABb59tp7oW1Eu7QdCyo2lCFOp5NH5cP3Kk4x57fM2Tl23WFbg50l6oL2z2
+BDKErEENa0d8CGVCBBBl81NW9gg8No9P50JMBGID7D3W822Q9Tg5Du0l43VKDV97Bb3fm1RcCbPGHtD2p8D8EvMGNx
+3kG9Mf3V3CA3E9DFqfFxh4rF8RuC7cCZm4df6xyCrwFkuEPsAiK2PV0PM6qs6nwBpeBVM3ZvEDe9IF9a4A8vA2P327
+8i2Bnt66lDYs0Rg4Ia7BIEu46NO33lDvV9L58WRFlc0Cl4WkBP1DSfEe8BvQ9hT5tk4z6BpcDkPCuj4gf2LB9oa7Go
+0It7gfD465Nx2iiF8f7wpBUdG13234BFDA6aDdc0h49Q6DLE0QW7MX81EBK70UlEEY4du04WAV38RC29lFwb21H8NR
+BIyDToCmv7mfEX73Gu4E8C0L6075s124T1tb95qCI4Bsz9Th8415bq1BD4Ym9nCBzp9BY8wW4mF28BDOF2cz1Ty9yr
+2EOGEpATE10kAST3Xg2gW20A13TAS9FxO8AE1PtFJF7UAB3H7z7DTy54G3nQ9hV7LtEne6FhFwwCsW8ZN9HzCbrBcl
+79l98q99i3CSBQuFduCXY5b87ZlE2i37F09uEpD1wS2aMFDcFRo0cz84a8sDFcJ2MN7t41PX64C7E97kX6Di1zV2gJ
+00w56m7013ve6EJ7J2FCe7qhBhWFIeCk47bU8PgGKQGNSB4nCov9D9AhU1rbCTL6tLFN42IKDL89Ka5jIBYF65F3kp
+BEzEXg60k4P35V23by9L00xLA1LBYw8bi9mw80jBPw0U863H2XBBkz0ToDOfE9y3ZM9ekCPr4kU7xU77U49PFtV9RZ
+DSW2sdDTq2Ku7aD8DuBXc76gFbT4NGFSX8Z56kl0ib59V361BL574u2B00uW5pHAccDQoCTs6CMDtEC1G2BzAx1GM0
+0P5EZnFGfDLD3KABdI56M34g0uHB7B88H9SHDEtE9XAWH3VXDlV0kk6mmBXoEnk7hk9B05LfBaC1T20oOFivC4L5LP
+C2Z7o17vE0Ic2TkFVfDtPAqo0t26FgCVXDQkEakFeH1RP8b889x58z5VDGIP8qwA87A3k4uKCYK94ADSC4HyAux7Am
+Cnv935FGmBwc1ZKBcWDWe6JL50BGJE2TW1hO0733Vg0221FPDGj6Ka87r5wX0Dt4DtBScF8WCtT0c1GJgDF64Us0ZU
+BKh0Go4kz8sMDAID8t2cuBZ16l908U8Yi3knFp83mi8tU4BQ6x4BvPBdX6deEZDG2c7KI7HP2pg6XyG3l7QE0gABB4
+ABiDCr94dBPnBMQBmE8oD1GABu7Crz96O9i7Dd7AkKCrX1J4FQCEGH6Mj1QZB7v16xFIwDN5F8q1jz1R32Y26kADlD
+9Au2vaBTUA2z80WEim6710H59XcBcUBlI2zEChE4tG4hp7FACZ2ENv3E0BLF05v369E8W8yqFQ44OS6l68EBAL5AJK
+2W2Aa82hl7FtBliEhUC9jFek8ijGJHETwD3HBAN7edBhLDns91i1Hf4EIAqXBxt7luEvw1DiDurCnG6Jr1XW35Q5ky
+8AC9nuDk7DF39Y79BM3yp4kH7aJDhg0ucDRb7tA5Yf5kBAex9rH5mEG6q95kCCtAam9ig2g0AxYFQi1dR47o9OqBbC
+4ZzBZgEUYDIHF968Fr0hSGNvBDi0iL6W21pEAOC2zUBo5DiABWg11y6xwFpV6qODPCEUc8fqG0iAjHB5I2Ym7gV7M3
+A7m7iD8fj4eT1RF7cdDUJBwn0Ns0LrF1C3N14ttAUUARe7BMBNo4W6B8YBYiEaB5MTFU936TEaK2L49wz42eF895l2
+6km2tC9Ru7ogBaN5OG1Z107aEoTCCm65oEzdFAN6yR9HK0vXApn0Yz5jOELHDaS6i33jf1goF3vDxq8Dw52A1wq1O1
+ClY1gc0p630C01R8K79lYDWp70O8GHFB87O7Dh63bT3ng8Yf7tT9ZG23TGGAEGSAtXB5t2evAdjCE3Diy7uNAv50Q3
+5QsDxX8JYETCCpa3vu4ViAxaB5MCuB5px50y9BVBhG9i5C3V9Vo97E4VzDGo36L8VY9QB6Gn7oRG8X24HB3u1cuF8A
+8Z78X01FHCMNEOlEhs3LHA1V8al9Dl7ISFEi0We7Sh5VN5TSEFZ8PBAir9pjFzt1Rk3Ta5Cs9nx4jECmK2Ne8eI5j2
+BLEGHw3Lw1N02fkE1o3uXAlPDRD043B0k5QP7BOEhh8nN08F0EP0DrG6e9aF0aPDz7C5W6X86ED9n63fh1YhG69GMz
+3EoEEj0xg0Lg5PYG845MkCzK2TI9zaBEF6QR5iSEixCAeB3V04VB3FC4JEHC94iCxh49AEbaEYPCfRF5W5mn5FOFyD
+8Mu5kAFq3FSI9sNAgp8qu5YC65uG3NA6gDsl1sg5q02KbAS3Cix232B285Ef4JU2551Bk6ycFH34kh6Ed7ON6UM8dC
+2xPFtFCs94KRAIH7Ia7mu8nFC2UBmZBrL3Us1rZ0CjGL5A5T65t6he5TQ0PBDiM6yl2hT1nRBSPBeeGHz0BZDbh8qF
+BblArJ7d3BwsEHK1Pi39aETFF0a6EAEuQBXJEle6CjCkR06c4Ke0yEFo19zV22e0VX6qRDPsBy89xl7F22oa5if8VW
+00ZERP4AoAru3049kc0pm7Ad5In2JOB0G2UVAO0Dkt7ujEOTETd2Sw3yQ6ZSGB12cyEzB83755RFWy6Bo65ODbmCtw
+Ask7Q7FMI5vk3lC9zpAz60lW3hl6dH2Hs6UeE3xBtj7PJ2JfBsc7kJ4lZ7AK5Hs6Km2rF5aDEKpAwk6NR6Zz6K64kT
+4Ec8tMCFv6p78Xw8f09feCDVFYsD1X1er9pf5caBBv8uxCE5EnB3il4k17H19qv056ClPDMo2xT8NP8hoCsXBAL64z
+6LRBJz5j91L16ye9ncCRVEl732K8P12xe4HS10Q5rUDe64uiEtz572FkX6Ev3JaAWYFia9u2FAd4y5EnaCVbDkNEH8
+15gA0i3mTB538oEEcS3ah92yAfP48P11G12r4nBGAnBud9cC2wh99p6TnFN1FyKB8JG6R4M947U1gH0T87e10wjF3l
+DLA4PqAqZ2vW7ZX0KO7b90zs9ng6V26E9C9oFWn2AEF2r7pODfxCSMEnT7Yv4UC8RJ7VU4oA2zL5D0CgUENgDEe3Pf
+6u65PfC5gBBg7KxC1pDlN6V3GEaG6z3uq5UA8mT1kKEkrCaBBXw0AI4GA6Yg0SI6lp3d7BMK4cJBTtEhE1Ny5xm61c
+4VXBM630t7vkGApBbDGCvDW5GJMCFIC6oBNf0jG1q17A5CXJFX72Ui5aE1OR7e2BsJ2INGFKAGI6pBCyfESu6dh4j2
+7LYBbbB1Y0GA7U02xM1hQFqbFKs0FNDWYE5j6B37Sm7dG4Xn3D2EEB6znFyj0qW81M8001xj3KN31p81vGNPEPz6vA
+3DZ3FY4G1BaeAHO8waAD81Cc0CD3NrFTd4hN8fQ3GaE3w7U3C6t7uw9ka59N1tL3r0BJh373Bh060ABH15pgFea8Qe
+8Nc85wFd6CcV2ZDCJ1GJs5IhAZH9RW4Hj9X4DvEB0V6H6AN95lVCPnAFyFpC2VYB0K7c60QpDn127j3OX9tcEw5BPg
+FxN7Q09nv6cg2iN0NUAIV9cm2L1Adl7Xb6HV1uv9AlAeG2C07S58yS8f95AR2IQCYGD5t6xA7JjAcZ8a0E533aV1RQ
+2Ua40P77e6kT6CE1J290yCuU0MB9f53O96MW1ZRBS3Dw6BCJBUm4J25OaDC36OQ2Bn6Pe0zR2B23jvCkt5jDBcj1RS
+2fz5GKFEaC8R69dEqn90i9tv3tP1SoEKT1OE2P31Kw5xuEyV9UmDUp0WF91s9u5FlC0O95rh3wuFiCBAiC8m7CkAxH
+A4VATJ1aM4Wp3Ol2gsAOOA4oFTpAbJEaN2A0B8a9Az4VaDz6CKs3G68diC9rEIr20G0AG6QZD531Ar4e4CBGDgcCdq
+1nQ7by3ak81Z7768s28Xq0HaBRE9Fc6Fy9dO15rEC6FfR4MiERpF9KFyoANz4soG789xA4HsFjk7Vt2587gIEQr3zP
+6Sv0z67evBV89xEBUcCTe7wtGCGBHP68e7LrBFL9Py9PrGI9AqEFwU79tAro1g75g22ho3IS0gGADj8SuGHM4fnCBZ
+8V4F17CLQ0Fv30UCwb50v6AkDecAguEeY7773w27fh6L02G9AWx5HnFQD5zb6AFCbnDZhDMS7lRCMRFeC2FlCJf51b
+CnE9NXBRX9lqBG79nq4PXGE48qC3haAWPDwS7ZsDWFBtu32649FClA2V2Dlr7w52M49cD21m30v47rDRi78IB1g2Rd
+4Sh2tr6ND8Zc8500VgG8S2Jd8L14ZPAz1C66EGe7i45lrEHsEyK0nMFTtErCBh17e535dFAK03SEip4qr6uqCdj81N
+4KWEnM7fRBGG1G17jD5rT0MHDNB9QV30q7zs6WJ7PzCIlDwa8A89rJ39X43g7fe0HYDFI8piCW39TcCZu5m62mO3F6
+EX17n46HzFJEAoK3t09TD0ujCsU5eOFKo7Iq1FN2OW8q9F6tD2wAlM2ZvF6fBlY09y2VD19GE115VoB0LFKt2miCDm
+CRA6zu0Hs1cL64pFVJ799DyrFRkBiZ4KgCr08XRCKA5Gm6opCkq4rC6Ht5SH9nd8IC6KwBRB24nCW21F47fvANp7ke
+5010bcBVx0wV5DR5bRDsN8wHDtRENqABJDHX8ut7lY7gDC7T4oV0IQ1AgFHFFgV1ttCHHEDF1gm4bn6dP3Q45wp5GC
+GGt52V24i2xa0gpEY3D0J26t5lI4OYDM6AE167v3Tf3cn8gS8E03YPBiW64Z3u35F4DCL7YG3JhDFY9Z94G9D23Bql
+EJSFSR2Mf7Ah4Mn5bM1bl344AXc4pT4nDEW0BahDbf63d6WtAWQ6BgAkp2tF2ymCxnC8198f0bsDK99L1EMtEJG1VC
+6eN7mOAHq6CJCNiA9b25sCHeEqXAVYECBEpz6iD37gBjz2cZ21W5tr2pl0ZKBxR2fO3GLCqUFvD2eJ1vlE2P6bMARH
+A20G1V3QQ0KI3ka87NCt67mS6i5AZBDX2GIZ9FlFsi8Uy3dXDBB3GE8bT9cE9th2RSGKm4zqEtp9zm1jI92v3TZ4zd
+7xYDk9BaMBV4FaOG4v5bC7520AxEo5BKyAztG122i7B29EEy1zO1LF5qr001CoI5tLEG97HA9Q5Ekp6RT6yC69r8pA
+EvY6fC0hg57GDaR6Ko9cw7TG7BN0jTFwM3gZ2dA6d18TlAAO56A9VJCkGCm638I3Ey75f9jI1jS8MD9kfD4Q3g2A1f
+DSzGL75n9CqK82fEPmCMiCuhBML1GkAKL87VF9oCRr8kZ7CAF2fBZeE8iE7b7FZ3Cc6pYEF38ti8Mm6jWFC5Bd68Uf
+G7J7S17zABhOGCL6MLDPR5dREBm0VIDC93MT16WG0HCieB2d74o0KfAiS9cs97y61B8a73kFCUo1wP6mBE2F1Io8iY
+FjE3u78Bq8tX1WI4qo8BnEWcBuj9RV56HEVt9dm5ip1dh3tG8CI7OZ1hADuEByT8xoCsh8CL5YN4cfBHL2osEgzDN9
+4NNAzA7UDF3tC3P2ecBbrEQZE5I4hiDcM6Zs4QpDXb5db2qC5gXArvCf7Elg8O8Bhj8J81zW3HHEbqDwO5cg3rGF7N
+GBtFWU1oe5BAC09Coz2btG4jF1z4dhF3S5tqBxdC8q9OR0xE6sR2MB6oQ9GyFdA1Iq2UH8dbFpDAjsDW13Ua0FnGCJ
+0Qi7ee16K1BICcR6Ji39p2PB4ri2YU5WoAt09iT7rFEMU2QN64U2Up5SZCSRFKjAGK7wU0mW2MHB0c7Ge1lj0Kh0E6
+8rOGAZ9qD4Ur7kk08f3eZDpQ1UU8TPB8LChOGBJ1JzDRG6Ks31O5PI9XxDPx1HdFh65BKG8R8MZ9kY8GlFP4EbQF7i
+AcY36s1WsADN4Xf5VQBW420z0bWECn6Ld03fBRhCNICeg9nIEOa9jmAPoCK06uAEZu5LQA30Erc0gUByL9WNCr43Pu
+6li72IFxy3ec6tN9eb9ne63RBVq4liBAr8imG4T7MP9nHDas79p53fBAB60i8nbFGlEbz5562pO9RD2MG2Sm8hT6uK
+4mh9Sk7GrG0dFmU6DmEOv4fu3i4Ayg1l2FN64zS8ZS7moAhNEUK14LAHK3Di0saALm7xyGMx8Gd8mKE0CF0G2EeCbH
+47C2XX9Xe7oBDccBYZDZU7q82UCE43FjG3oJB3s3285axFeg4nJ5fa6qC2LD0Om89gDqE9FR6zO8SO4qbCyA9mP2HG
+9Vr05u7F78oVBFc2BU1Hm8uv7X90WVBkoG2F7yhBRR9Ex5n1Chf1ODCC729BFa37tz4fD8cE92l0rV1g93tYBCO2K7
+DeI52e8Ml4Yp1rX96R6MV77j8sU6gw2S3ACr6Nu7SM7Gc5YhD4K3L788y8Zh4bRBgz2ye1Yg2IO3kwBZ75ks73F4PT
+09TFEVEzR6CB0U1DUS8on6mq10gE0p2831d0FFZ51F3NJ4knAgE6FZ5NS9Fr49MEb00x299P1Yp8qd7H645aEB3FJM
+EPC5HC0ncG5X6sS08012qAF391D7qEAWi8gOAur3CYDco6gE9bJ57NBxr4v29wwFk12txFZ1Beg5u83ZBAoc3Xw8TC
+CyvFj3DFf2BS7S8AXnFYXDvw3dz95B8tC1aVC4m6276m1FzR6JU8OG9Oh8ES7Wq90T3Wo1m737L6XB4bV2Ph25iB6A
+1fX22f67G6a42Vn7Ow1ct0wF1rT7Re50P8wV25c3owBgBGMwBZ5AaG95SAAr1v9ERx3w79iD2un2RC0g39mN6h47Gj
+2lGCPEA8cDQR3NLFZH3UR0dyCVM0HK9gZGKA9nGC3n96u9K72hj47l8RFDzSEIADwW8A75gE5mF7FD2NiAwV8nlEb5
+6H26N6E5mFgw3jO7AAG6XAAIAhc5PmDNM6ec9Tj3ElGLdE0B5i4DF83QmATR10qDn8Duz02dDqvBOa0Cg0UM77iBfl
+8FAFOK03XEPK6y0FCKCwJ6Ta0zKBkl1TJ3jB12V4Zc0LkC85FJC8LT0tw3ubAVx3N7EZdBIqEYI37Z5uiFMf3AB1Ya
+0AA3R9CMaCSJDzJBrC8bEDfVDhSFTe21LALWF9WG6OCFOFje2Ri4pp7lp4Co4YfChGGMl1KOFhA3jqE5M3WcD7fE2y
+3IsAvy7xQATrBRa0nwF7G7Iw1nqDig9eNFe47vGCHZ1DX1iPETeEMk99BBlND8y8S38fv8E1BmR6q24rB56987FDAv
+6F33PCAUcG6PB6U4217QmD5FE0t3MS9as8Yk1Ld2D76iF7a393V2PcEP54uXG673kv3v5AaHDdd7HC809AF61eP3Ib
+BtC9vI0RdBSBEvi88m1T82Ew0X5BUQ5L56Ro4KICOs9n87kWALq6eh62U3wP0RN1DU0HyB4cEuY9GGB3lEJ5FJd8me
+3wwFgvFpn5t4BuH2EV7sD2HWC5m0K5FiGBMl0CR6V51QaAVKE9l6xgExyFIECKl3AL3Dk6FTAe35jzDtb61sEYdDSb
+BoABKzE3D5DmCuE8hd4ow1kJ3iD6RU7zM5Uq2pjC8p41x9JkAr112F1dfEjf2LIBoY6ma4ZgC8eByUCrADjo6573sG
+7WsEtfFDJDzC8947aA50X3Sj5OH2nZCoABNHCxQ8oNEM1FAc8jV0pa9IsDQn94y2yNCNkDgRE0L1nyCjg5RC3qdBIz
+AMv6ex49e7By1Y43sE2rCFgF9f9CZT85A3GA0983dP7Cy0wT1YW4T22fs1VlBbdBR78OyEj54NtBkQD0KFZbBou03N
+8QaDu19327nX9cG2jHF47FTlDbx5olBUK8nv0wc2uU7b23q21NqELR5maB49DX19RdFY7BFk0vs5W22WQ7s48dpA1M
+07S5pADcyDau7PK5eh2Mp0SZ6jAAX312D26T287D2O6OC89j5JDBg76OB7wqAzvCj05H53MjArk5wP9mY0h939E8FM
+5sG4Gp3343XnCa2EnLB3S6wg2uuDy54eVAI45cvEYt53JCBgAEN7oXCfu1GiBTs3pP1MG1Uj9E9Bp28432Dj1XjG5a
+0v70lN5R21W49wXA4M4H60eW0tTDjJ9997DV2xtAMeBq25jt1Es76l3yYAo6DuYCB60Xs0if9VF5fdF5f8Gt5ed3sd
+60g9AT7Bz3K35jx0GW0MGCQu4NO1T68F40OO5BWDoK0M9D4X6SzCvtC1x89q3Na80q3PAAnf7x14Hu5fv6sC5JP1Tm
+553EXV9utB3d5stA7i4S75pd5G62nW4MI4TL8lV6PY0SL87f6JSA0R1dT0Zd0Ll0fzCv259pE1tFayF1JEmA891Bdc
+1pd5qo07cD8TB2X7eABcL9WY11x2Wl8EP63X3UY6TjEjy4eZ22RE037qc6eEElv5QJ3B20VM2En0lG1FC8wRFMW6cq
+7Rm05w1V3Fj70wq30hBQ1CKKAmMFRHCRD4IzBJN3WhBiu0Px9Ht44FES43dDEOn2kBBCu4xV1qhEDj5CZ5Zs3YxD9L
+1z6BsSCcgAAtCFZBBD6JC88M9cr8npEJAGKp6jf7FR3nS5BIENr7KvBeMATKBj29JhDI0Esk0ua87Q1Wx0Zh9LZ1qI
+17z1fm16E4bA88A9Po8ty8EI8740QQEtO9Ji4Ky1R93keGBrDJ2AiF7Gt0TkE3c5DACobCpM9zf2RX9uaCNU8ReEA7
+Fal06x0c6G5f63C3Dm9Ho2umB2N9WhFtc99V1sE0g52GvFj98xV71cDq433cFGH7AJ2vJ2s993K5Iy8QA4mUANPDo9
+EqR8PR4vG4pr9acBlM4R6D2o92S3Yz52EC6F5kuAnM6fFAa1ENF2Nj9qsAnQ23M41UCDp5Tm9wIFKwF9g9TP0lk5rE
+EhD0DbFnZDhn5rL6v33n08F73ZZAlwCGFAEP6us27LBip1eR1D602R5JR9KN5Bg5Ln6sMDtg5sQ9AvCpi4NjCXvAo0
+2fY9mtAe6Et1CFr10TFv95uCDVPFgi6G069BG998l5F72ChX6Qg6JN8Iy6VEBTr0Fd1srAvXDcJ5ch62J3kh5o3Foj
+2hi0myEqk29n862FLAEdR33K9oS2mW6su7pu4cK5rG2XC7of1h0G638GT6AE6Um8b44oo3qo32H8ch5hFDlwFBj5iJ
+2Xt9Ia3qbEukDCD6SO5Kc1LCBtJ2ME5XQBCe94H4r73u0A93ClVCPK7AZ6VWBJf9u62gT6NW4SZ6eYC6i8FmB2B7EU
+9whBuW1a75QN7QtAfDANH0vS52m2T392M2vADAXBJG8B4FQeDnF7ss2X80nPEWT3m27nWF2X9ti5PD6PJBVwDLQ1YX
+BC95KlDebFHnEGaF248Fy01z8k732O7fW0LFAOe5Q55qY39JAaV5Nc4PkEH1BOc4gV56B6v83Ne35kB19G9Y83l9pt
+5MD9vQ3T1CR94TE5Hc5Tn4YI6ai2MoBrjBN0EQJ8GiCjQ1Sq8D4AEb0jyA9F7LX14n4AC1n5EOu9yJBmk6QP3lgAGS
+5Uc93H3WPEXFBT30UR7eN4rM9oV6ltF9lDmj9Et8K5CKV8Nz6H03tB8H40j9FNt6R53Q59b342756S2e98661UO5oQ
+8k67zhAED92s5q15EUBqV8ca5ys07C9G09vrAg3EZ88Wt6P327aDXf9DgF0gGLN3LoADz2YS45u0aTAlaC024uP2a4
+3oNFZj8U98bk0He6QKE8BBsgCWH1oi7F00R53f0AR5EQkFUO2sVCDO94z8dU7Aj0e3DQx9RT8evG0C1Zr3uLCJJFAx
+DJ4DQzD6o5AD6Qc8bg20lFVNEt26QEEK8CKk8ksCKiC8H6Xb9XZ1Ex10KDAJDTYBor4OW9lG2uY62QARCBPa7xcFYf
+8BO5GG91b6kR7PD6A0DUT36J5tECsA8Qi3tw8Al8g4EOG8mzFJk8hq8OmA3e2VR1941OL0h6DLjBq50ELEZH2DgFmq
+4YlF0u4SgDrWEbmFMa5fK9i01x210cEnD5s78Ck4hj3e93d650S3fo3gpD8R7A17ST7z6AoqECHCp64p4BKuAmg9Iw
+5NZCh405IElj7EDAVe3h80MzGH7CZMAU1AGPGIm16dCooFO96V8E3JCoP4az28MFbmDB38xuBey2EF5beAsuBqSCiv
+EBqBHv2yW8DN6C94RJ6VaC63D3C2oj8iR02048ACWI6tDBwR92F8jD8I61rD0JiFYw9zN8obBS06guCVl7wkArfEck
+1tX64s8m29uN1suE6aE2hCvRDdU5Wi6YU9Rt2FVDJIA1IErI2bJ8Y0DYC6BE7OYBzw0pIBHt3b53ff4Os8NI7VyDPN
+0yc1BGF9TCEg8SsAXAEPc9RG6mb1w3DBFDKr2rvB7y7EM44Q8pDBuTFzJC9H74v2w8E0z7JnCVcAG30Sq1FQ3igDUn
+7ye4OhCwdBCC5942TQ98p9a97pt2l2AFEEoz0nS2ta7hn8ih72fFfQ1hP6Fe8iUEuw0qa5If1dO33d13f2435L09aO
+9L9FGK4hGAfM9pCDt48vREWNA2G5LFD3z9RcDJQ1PG6gm2d41TT5GMEn7AgFG2D5Sy4lKCwe4c8F4b9m7Cp16m5C7g
+2qBDIsEJ46WjCXi6yI6na2Jn7Op8hv8iD9A3DjR8Xu8Zx9XJAbD1NUEVo8mA9BrC4a6ZK7gBBP42eaFpMCHQ8k37tJ
+0ouF4FDs0ANU0mj7X17448I286B0xV2nODDX22W011EDO0xa4PO805ERu4Pr7NVFvl3YO7Ir9BH1ouBmw154ArmF1o
+BY27CNDgW8RI1vY10tCWD0JL1TF1G29fw9DDFXl7fzF2c3GG0zaFVI2t6Avj8bKA1E9BK1AZ2GH8BvFA89564e3AW4
+5X628m5CJ9lg8CD6cBCrO1tuAC997KDfGBKZ3bC2HF3SJ79rD5Z6so8dO6OU6LuEqo5MhF8Q26R84u6wMAx4BOJ1O7
+65g3qhEWk8KN171CBw4nrAPUAVpEIfFAO1VeFEw3UNCh75NQFEG9lCFLT3JSCIeBsT8seGN5CDRG3fB7H8R72V31rs
+0jDErQ0lX9Qb2hq0ukF9X75Q6kY2E49Ft4JOBjN4RFF6e3is7Jg9ap7nE3iQ7YcFQa7a21eh3dJ5mRGNR7Mc6QX8qX
+3uI2ht1kW9r5BwY0u99Lr8Vv9nbEZhEnW5xQ5PKCddGKOF3Q2zB6vB901G6H83q14Q50V3Gr5zL3Vn93qFug0ar1NM
+7kF3aoC64FfNAINBkWBCW10z49O4IrBz44Hl4tdFneE1O8AN0fnFObAFQAqD3Xb6a66UV5wSFjrFaI63x4tAFcrAon
+6me9MD3bj3qC2qD4Aq0ks1t816H1IG8oG2xc5136JO925A5vEya75D00CCvq9pn42h1GW9tJEghATx63L9HY2Ey5EH
+B0dFR774rG27F1Q1aPBXVDb61Lf7Yf4X118D1YD3YA5zA9b028TAJVGNJ3iy3yA1Q6Fx27yl5ZqBpf0Qf3cw4EG9gp
+70tF7X6IG4Yi0E5DV38u80LREcBBYW5066Yi4hm16Z6484ur7v06YCGFH5R86xK228GBm1Wt9yy0BJAZA5Am5nN0FC
+8DlFOT6bSAFs8y16EQ7Wa8W40qg0QBFgM2H43iI22u8u53DNDIe5CH8zl4zI5BxD6j1iCGKc9CXAovFPKCW50gL4Jo
+ETP9FJG6uCky0u02qwB0CBxDCtXF13FcEGGM0iE2DfFTXCyX0E72ko4BJCrh99zA2H9gJDkg6NT5rf96jGB8AeCFM7
+77E8vM278Evg0edFG60bo8ypBRp5PwBILC4hEM68Hx1JoBQ67AV6Pj4wD7Jq077ARLBZHE8TBFaEN1BjiCNp9Cq2yz
+8sF9taDuC0XqEik2fpCMtB2I1YM61p0nrEBc0aF04a2Kw05CDbUAYw8OR3KJ5E085m3tmBssBrtCpJCUeCvOBACAVG
+Etr5U8Cvk8jUCPx3T70oB1yXCKBCMgAHVB0qF0ODCqDJz7vwDaa0lq3lf62j5k6AEu85REmODMx8cJ2Km9mq6I20nB
+7OV12X8Ac2UxCd74it19gD1y5AgAih1oSDssFT90eaFhOGJ36fYE302uM6D8CnJ2ozERB5eW7KtDHW1MV3Ce6lZ0su
+41LG7a0gc9il8113uT0hO2jn7d66eJ4Dl9UxBlS0EA7VDEky1xA8w34Ii67M0O54q13AX1HW06g0dg0EWBWnDoU1D7
+ECI8ps7V19Ti0pf1TRASmCOx4413P098F1aTE8U68YEmC5Jc5wM2Oq6VJ8JECG90QY4N46SwEJu298EgvF8CDdYAJ2
+48Q0828DW2aE5HD4IZ4dG98yDPG1UP0aoBnUEAN1796z7BZV7oOE5P4tm4e15T7DMYAFnDea8abEoKAcU6Q68XWFIg
+7bt5PO31uAX24YRFdU8Zb1d395g3Mk09jFfG1OPAwj67bDJO8P26Lk5QnEjT9yuDVB4hc3cQF4BDiD2uN9ENFK6BbJ
+ELDDMT7Ug0mQ7rxEn10dW9us5Z503IEsA8y89w78dc5keDDe47c5fL237CM89ym1O8FhmFCx8QWB80C9Y4XUBMf4Uh
+EOm6Zb4T47TYAVI16w6vyA8JARp2YG1MY1F04EXDYe0JcBURAb42qj00z9evFM2DZ74lFBrv6t87PL6ak5K82YjFmL
+2KOCAvDsU4wH1JQEIhD6sF819J1CttBky7P2EHo61iDZ81Od9l91I72azDme8KI0bKDRcAQG5XE95Y4z2G2ZDil5RR
+FKu86aALFEiwEFi9NT6wi0rZAUqFQP2vv0ET2A5FvA7Na7bHDe1D4D37k2Zb4RmCzD7Mm9DM1Tc9ntDwZEo23kT1f2
+1oy5NaDez2iyEBi6b64228VG1Vz0Gj0zT3nm9SIDpU5DOBC72fr6fKC1AA3yE19FE58PUEbJ6s0AiZBUBFze2Pu2tl
+B2ZEXv7PbAFbF4v0zyAAJBFR4St4cr8O3DM9G9O7KUFfqDf8FGpFrK5tO7oGBqO1wWEFVAxMBWf7PY4zL93BFqKD9D
+68M6ECEvC1huAYv24V9jSER31bW0Js9X7D3J7lyCmR2eb54a92a8RODgn6zo9tX8IM7t33sQEBv4iHDzbF954rX1LL
+Byp0LJ0YiEo8Bmi7Fk2SL2t2ACvACzCqE3Su9wG21N9GeCDn6vm1ygEzK3cD3ptE4nFF72u5AHn81YA2uEmz4eA3cK
+1tDG9F3Xd6Ay4sS8YE4iRDH69frDh44rlECqCWh8Ih45q5mqD2805Y0ALDo519FCgB7Jo2VIFyt7IuG1XCj55FM7hG
+1VI4Y80Jr17y2Ea0HlEvz7Zf1UaGMR3Z6DzaCmy0yPCS09HS0eQ4cp3HY8BQBrT2YVB4P6vP8y92UJ78VBp4FXFFw5
+00tAK55wH9Cm4OE82nDj2AYz5FR52W3EA1Hn32bBBT0zO9ao9774iA31jD7hGGB5KO17D4ni1YT0AW8ZTFgA4I78Ci
+Euo7lO4YK4MSCoq3LIG6E4Fz3a76sw4SS0sc3oz3sH15d32VFNu6dR625BzxCjt5yA10A09fA0A8us9964CEEzt71X
+AmR2YC2GN2R02HC4fz0ATFOrDNQ4KwEsjEQn0peCt89z12VjBy56KQFOD0YW40H28W9f26ZFCvs0WcFtsCrY6VT4nd
+0yX1SdGCN4tl5CeEmXBgI0T99ZE7jyEouE7NFKc2HiFBA9JE35eD6O4vg1WMF7R8tvAkb0X80qCAOS4jIARk4dH4cY
+Fd30a35Ni94P2PCCB90EI2CN92HCmZ7HQ8HY5Y384LDBj06hDwsBQpEQ5BRl9ko5W6CdGCgcCtj13s2ed3Pq9Ck3eV
+FNe5J61mr3qcGCkAEF7G23Mv5BS4wr4wKBkf6AjDCZ8acGLA5hr0oG4lpCgC31VA1x3YS5TxB018qz3sr5AN5Ne3PH
+3TM9z47fs3EJFBI7XT8w75f68PNEL85eS9lt5VV0StDnB4LV43uCM01RX5YACR32VtE7o1vF6sg26d2baBbFER8C6M
+7Zj9is0SuDg7F1D6PQ83IBzQ4IfA2eFX82rHFfJ1Qt9e3E7dCGQ2dJ03PFmy58r7wA3O577yC1vFtr6nI6sB2Nu4sl
+FpmDx1BHVFnl2wU1QN6OL3hYBINCt2Ci53rI5Fv6OX2n9D622uO2uj2Ia2TeChv04D8Up2pzEAs7SQDxuFu9E298N7
+DBI37jF236RZBPV0Tu7tMG0R3NSFZWEdUBITGCCFTH0Vd3Mi9SwF8u2Os5yx9QAFTCFFGE5R7fHBx32Ft7F36sl9TO
+3GnCxH7rP7A0Ac43vt0uiEp4ApF2Yp1ec1J5CMSEfmBgd5Jy1qiCAi7yoFVhExVFfUCdMEOE6nO0TB8rIAgi4bN2w4
+60xA298o59O784YEx1BRn4BVBM4FU69DV6WK9y0CIp6C0Acs58E87o3BO09a4OoFxt08i3st6Ts6Iy0pjEAQ3qzC9L
+9u7EA31fo6AO2xH1WR291AE52q3AF77p0EPjCehDwmEGJ7ap5Fi2MY0VW3Xp1S45rC9WoBXL4cn6eZ1Ne2iA0DgFqx
+67pEf1Dos8YFDSaBw95TN4C50yU6bO4GJ9Do3qv19rAcV7oNBhZ7Yb5xV3KTAz27lW4CD4zc7P756R05X74t8C0642
+3iP7bs8C82qA0K91J9EOs8jy3j569w0cKBsj5yC18vBo38ny0OJD2m1qZCUkDbBA9GGK20Wa8T8EJ68zZ5rkFS2FdR
+8n6Bqo9yz0eg56821CE7xFBSBNP1Cr1WP2Qr04o6tc3Th95IBj92ZmD8d31Q44y54YCHP5VpFqdBdxAtS7y887H5K2
+9h2Etn83f2liAHf0kSDiS73k34CBRg1D30oW9vH7RkEjB3tTESOAdb0oT3QnD49B5aAHcADwD0NAxAA3b8vm3fJBwA
+2sn3P71CnG7q4G2A7NDPh49k4Wj5JF2ilEo92KgBfL7Io2S87Pq2K60f0FjjCcAEvR1Bm31XBGr8SC5VI3PZCfy4C8
+3Nj5LG4Ac67eGElAtfDOL75ZDjCA337k74gr2ja4JQAn95wc2en6qd35YFPxBVl0dHAqYCdb2aa8ALD1AFll0aC6F6
+B143Eu29m39o2xW5quFt98711BeBqX8LLBbwFPv1KLCWx0fQ4c08Ma6fh02JF9z9E3GLE3vbEyA3TmD1T3p23tFEDK
+DnUDPW8w02da012Aii85r39B5ylE7OAtb8GK8Jn57j86w67k9yW7H854O2Hn9BOEhTBZb5BoBQI4js62u3Ip0sKDZn
+2H85wjAQU32s8rGFN73MEC9588tEScG6nAOq7mz3jaFfHBvhFz65OQBRCBO53dp9z8CMH25X2tXE3F9e91V26xf1sR
+1cTE7h0UC4iiCEb1kO7YL8wUENzAxo7tb6OE8Dn7I7B9qGAiAt1CMD8icCeR1xE1sPAKeFOqBXR2dL0IIAONByM3TB
+COq0sPD1v4Ou2jrCLu8464ve0UJ2Kf0SiFWW1J35A7DoN28a7wF5HRCW47IT9R4CEc9xP49aEX4FKVD2dDYdFBU2sP
+DDG2kx6Y6AKAAIYBeV5Rr3ri1bD4Sd6GT0w9B85CG709F0fH9Nk9XG9xqFQX2q8F1cFc06XtEfoBCx1hc1QBFzc0jE
+Az84BbDKQ7z8FyV4h391j1g1AGG53w8KqEbx4IN0JZ9uuCcb9Un5x538HFie107BwO0R31CUFBO8GrAcw7548auGAg
+AloBum0tGDkj0iwFeS28uB25EBNAL7DCb96yEnsBIK44A2ZtFbK7qJ3rWEgl8Ja7A3AC49ayG0o8jl6pL7q49QC9at
+1I8AxXApDBse33f7M4FPkC0BAtC9nUEgCG1o3nWC8rFUN6jE4wo4yF5fh4PP5Is8zC9Ph0L5AWt8FFFFACQR6Ss7hW
+0Uj2qLFgr9Zn6R20NmBanCfI9mS6pNE0w5pFAVy2GnE54FeJCV05Be0ae2aLESi6nrEYgBMs1vV4VoAzOEodB6q1WA
+FGCBUUFGVDs8BaiG9xE4S9EFF4SEvG9GU3wp6DC3rtBgtCLA3Tl3qT3vH3sJ8H71gq4DeCw882963M0kL5jF8xM4Ay
+7fL8gLFb6GGC1paBs75j0BWcBjE1qX5Jr1mPGFP1ZNDJq7DG7RCG1pBxfEHj9aCF8L57z9zEDltGAq6epA2oB5P2db
+5Ai1Vt8HC4gJ6PlBTM5zc6cX5SxChuFzF50xGBKBuz7sZCf4AKa98Z4iG3Af7KW8WB2iC006AvSFuXAKt6TM5t93Cm
+DEB3inBSa6ru1RtE7SBZzD22Eg83HQCUp0I47Ng0WN6Fj2H17TP6lS4mS7HU0OA51aCgD9wv0kb4GL1uuAgv81b5Iz
+43k8IHCaA1asF6ZBiI7ZP2kn82B72OFKh5aXFFM8KT1Z88dt9H2ANE4yJ6LJBea9PW7jnC8V1rH7wj5Wh2bj9mL4Gd
+55v17e1CM3wn6YNEsa15c7Sw0DvBnk9PN1Pp2cmGNl0FiDmx97UDO62TB7XG4ruDXKBwS6cWBVA9FqA7c11N5YT36F
+6bp3FnEnlB8cBSb29Q2iU7Hc19lBJx3kW5Je0r3CCf4oi5Uy2lM5540dYFCW8hxAPV9H17or1fL0xeG6b5Rv1thFZg
+7sy8V59DR6U86ZACW60UF1Q4CN45mJ3k19Ez4ZB7gk6T14oO7qUDB77KME043jPGCTDoo4Ov49w27u4o7CWBAkD58f
+EIN6ns0mCCT4E91CfFCC642k1jP97H1gk7BKDG83r28Zk6Lb32wE2O1JcF0pFtgCsI8i94f0Asm6WY2tQ4zv5xbAXS
+8PK30JC5d3Xm7WI9wD4CR7vP64n55r7ilEh41xg9ByFX4EE63tn6LvBEc85BBq8DEdCNxCOm5ok9Cl9sI2m5AQV7uQ
+9PU5Ft7UvAP1Eqp58y70ZFV7DK75FJFE42VW5d87uV0Sp9rR5EvDaD6Vi6l88K2EWH7tV9jo6wCFj48yoEFC4BWFdL
+1c77OlCik9y4ATT1vM1950SV4lWAMiEVfC976lO6AH4Md3yh2E38Ry49N5jq8wM2LlEVv4k7FSZ5ND6I8320BgE0IR
+3S3FJu4R2Ah2BuG9wO97W3hu8B65vhFikEHxDkH5jk2AI1z42z9Fks97235l0hI0HG9pvENM7KqAQPFwtC1cAp6DE7
+9bM0OE3dG9OLFiW14M5OVG81Ans5sS5cG5aQDzZ7KV2mvFm408zFki9Xk3mzCUw4hz1Av6phBPR3ma3av991Bld5lb
+4iaFL8ERiGEm2em1VUFC3BTZ8D2B2o15RAzV5bU6UgC3b0VkE520axFk66hj1Ax88k6774IeDVr4qk85q0wgDv82WU
+F45FAuCaq4gYBNU2QBF0HDanFaiBg0ApXEfE0Dq4UuDobF8N3tN4pW6wP4d83bf8Q04014TC4Vd8Zs0CUEzL7ho9dN
+3dk4GXB3BAIQ3yl95C4twEr6EadAcrFbV51A1Wy6zS97P4WIDSjE5Z44k2gV0Da1kk4Y25mu17U9rOG0w4bpFfa2iv
+Elh1ssFNbEvs9s02tvDQ26Xp0CP58RBtXC9pAiu9zqCm135W1Co3FaFIIFFq60m0in1o71zHDkE0cV2Un7Mu7zFDD2
+1kvENe7ft18rA5HE7X2II6K26LhBAw0VE1RV0TU3bzFop2CA3NKFEx72BDZVEReDFu6Hq5DJ0Wh2yo8UmGBIFYz5vX
+0459cz89JCn1Dl15rH17R3jX9soEYv45F5bb69H6Ge49CA2a3XB0zu0bx19iE0R3cLCnVAqGAu24LRBiw2QCBOZG3t
+B1w2Kh6kW7OT0OT0YcFn5B6ZDfFD903cq5yX7f8BCk98v7zX26k57CG0j1FrCp37bvDdlCWk5rp9pFEkxCtUBtt2dc
+DVuA2c4qjCdB4PN6dc40p07R6d88Lz8cA96wAm2DHPG3F0m259y8FOAkcCAa4oJ9Qy9d26sy3wG6mO3zr9J6AbAB2y
+2Ha4YwBBm9ITCpR73T1VpAK99U29EJEYW82A85iCkw4iUCFKBUD17607g8xFFcW5vN9dyBsF6Zw8P0EmS5140VFAAS
+9uz9SyG1E5UF1oX1lTFhH3jt2yHCMb6Hu6ygAoX4CgBbi52bCc89Xh2Ja3LT6GXGKy2PY8WjB4mFSk8IxASy8sA2lB
+4BU3wkB1oE5w6UB2e774s7CZ1Dx87b8o61mg4cIAFD0Fe7C8EWV36Y0zbG2YG5s8LxBJK8EpFulDCO4qx02TCOZ2Tj
+Fb53YvEGTA9E0flBVHE9f2h1Clx7pLDCy4kYCamDf42laAqTFhx8MXEOAC2P9JK35uAnXFFOA4fBwI0O46jK4gqDkL
+8r7BB3CC40Dx7Pf9tK5l54cODmr9OE7jL0vcFDp3kgAxF4ml9dMEud5QiAdL2ip3Si4WW2er4MKALf50926q2xiGBW
+5L9BQcG5j86uBoz8ck8pW8RtA0b7qtFgo82M93D85OETJ6PtC760bZDiWD6e1J752k8II1rL5iY66EBGp6ZB8vfDm8
+AK35gJ3TcDmq0cn6XJCQb5ewFbW87SF0q2kl46C0LQG0Q2QSFBD6PO4ts54p9Z1BIBEu739D4h42rZBnV5fwFaD5LO
+6n05sE25wEEg2IkCi0F8o6CW3rUDSq6oR2nUE2IFud5pc3kt8l22dkET2AFN48TEB7AZqEtNEDfE9r87wCfc5P9FCc
+DL34uv1hy47SG4V5Io4DKEV76BB1A59GP7WTEBoD5IER2BBKDm51Q2CUYF2BFl42Nk8pTCKZBEH86d0UqCa7Egu3PM
+8Z8382GDJ5END7X59X56U9DyF7eFpRFqHBBc7UO77o4CQ8UX2au6agBU002q3aqAei0zF1pB3OH5Y61FsEJt5hsECu
+7MA1rV1kR4oLDd889p6CH3oWD6z0JkBG48eA5ErFpdFMp2iuC6TE1gCeCDJk7vaBJB2ha82i0SMAES9g54vBEfq0xm
+7o70Ss2ti8yvBNY0hMDpbAP984R0Mi5QM65WEyMAMj8Zl5aJ8GX3yW3yc8gsDW432FGAE4Aw27wAl12M7ElI1SzFKe
+4iSENb5gh2PFCLo4nuCCq1xX9Yx4RA2Lh1YmANY0Ka3dO4aNClR3UhAVj9TIDlWFF29BA8mF7Zi5sW3vk9kUE0j6n7
+DWVFK1BaAGHKFzh4iT5f5C6p214D1kFKr0Qo3pqFK32ox4sW8IQ7Zk5VX0VAB7YFZYCbw1M86kU7In9w92IsBH80F1
+CDk7rd0eR52JFYiFWQGDP92bF6w4JSERl52pFZm9CA7Wb7nL8RPEED7eZ1kP3y19PwFa097F8EJDUW5txEcu8rYDYA
+1GT25F9GQ4Zf6hF7GzF7J2e823N1Dp37s9LqFqg2yK80HBIt9Ad7iv6PP0BHAy57pAFsw8HE4Cm8GgEdu4do29MBa9
+CKq60L2Pw0oy3fE0iVBSv0bE3YC4au55LFge8GCFveCHp8AY0MYB6X98h5V5F6k5Jq4yKEbG7uTEXKFEf7Sy151DUK
+8zaDca6VL5lD6YjEjZFTGAiBC6y2W33EUEcO5NyDxLAIyGDGCML8ccDbj0MrCvaFWF3yCFCoBv95tp7I07RGCNbB4r
+70MCiF9cJE4q8851UW40h6cQ6Og9KtF4N6BcAq018MG5M0Y08mr9gU6q30eiEBTFws2zK2st5Ie08E3HfDRaCg34Jd
+3CK68WEN01nN7xD2694OH8Ik4zgB9XG1k9C9BR1BKN048EBZEpa6hYBnw8DaEHEFrrApm24CBwzAUTDMWAgxCHDDeT
+86i8zJ8HVFOd5Z322jBtn79Z2n4D3w5B7AfH5827J45Iw3w08XpEUNDFJ24pCgW6PCCqd8VZ5p88LyFpzDG45F82ZM
+1wM1M32wLA2CFFIDwx3uCCWMBaaAJo5is8Y4A7P2HQ6OGD4B7581sn8iGD0c8Sj6mU5tA0q3EnE7ju3rP5ik3VE3Gh
+Fy14rG2sSCpV7076RdADm8b9Eqr6S05ZrDtKEGU8OtFE17fA1WT01IBAbABqCPY5AB7fj3vF1AsDksEtgCZI1tRFIm
+EPQAIR3e1Dnf6ShEY20ltDqr2xkELC01lFaB5JO46O3k45GX0jk69K4b67ZcFn96MA7SC6Oh2eZ2JxCyC5gx6y74oD
+CtN8sv6X4Do19Ok90d6loDy40cy1RGEx22lD8Ob8Ti8VA7G9E5X3WEBQC2LHDRX53D8Td0Ln7hN9qA0WCAmDCwcBkh
+AFq8t75RZ8e1AhY5yEDRP4X2Dxd4TQ0wzAatE8R8LmBYp0pX1kZ23R1SR2ac3uiFE287K7ngBc43Qt5FwBa261FC5K
+2XT42U72n99e5vgDTZ3U32DV9dfBrrDCX8G3GFwAXw71J5poDLu8irAef3yKAIM3oQ21Y3znEpKBtq28o7iUEHpFM4
+4wO8JhC3d8Ud43J7uL3qY7mI80eFRR9yx6zZAy60bp1VwE0r312D0y8oT4iC9ZJ3AT3B85jl73s6ld2H7DCg94L1mq
+4myCvzFyPF9SE3t67F7CuDok5QG1q35tGB8A7V83xFDRH5yO7kj1Gz1OT84S2D30as8tS5cAGMs2rM6IY4O00mJ4Ew
+32G5PH49zA7482d7LSA4EDwnBZr3Ze2qNAaO0kaBek9Dp2RJGLB6mz0DY4o29HNFke3VWFzKBL7G6v6pR6xF6FmAy0
+0TRCd261O8LQ8Xe3UEFG591W32h2BT9kr0go9986ZQFAEAzl6Yn6lB2vU2aZD2I6Ip4d5FpH7IJ6Eh5tiCX2Bt84HY
+AaW1lC8HQ2QGDqW6hX0KpACmEPG5XoDMKFcf4TpG0c0MMFJ012lBDgFju5LC1cVAXGF2H5C69Ty4t90JBCE73nq4Zj
+ENK7Bt3Gq8ua0GJFBT6ok9Vh7PU4Cf4gy1mO3e76ZrBcY07n7CtASh6jn7BY1gD10i8ZH9To2Vv33aDRY1Nt0Zg24c
+3L069TETO1VHF331io6LSCUT7sH24B9s60KV3gI7lUEGd86AF5ZALM61l4VAE07COu01D5w04l09DZ95H9Ul2gw7yf
+AmFCEV5LvCKXEDME9w3liAb94dx3KQF1bBOh9YaFqo2Fn5ujAXiCNA2SXA9eFWj6xEFDRCYo7vFCOb7GQ0I0FpTFIn
+B3DDvz3o3FO5A0kBMT3ge8oP5UB4oy9Q87Vb4AnFhP6WiD7i8GoBHk51hDqC3BPCsdAMR7ko2EM99v5aU1VV94S4Cn
+CWNAtJEDs9kRFIK0duERbDgrCwtBDtBuK2XY7UK8zdEcF3qe77LACs3GiFxjAQI3SvA3u2Zf0F5ECh47sCq104s5VY
+1bI3NV18d0zM3xu22o6xpEEp2lb6jN41w3h34Kz2tsFdW9r0FTL9og2E2APPEgB11O9o9DtVCNc8mGAbx7nbEDw3O8
+4l1AZR3SB5G502fE2JD6R0vl2ZY88sBIiBXZEBDBkF8nJ1h3BYgBVUFUn1ZABKX3cp7NYDVODba2cN99mB9s2bgCI5
+22S7VJ8qfFhhAJE6EK1PQ7G36WF2e3DsY3L11Q35LaAJf7bg35S9DPCLP13oAQ93YV4Dr0V14ji8Nr12i22H1tvDFP
+7CF0372fW8gc4SF0nC0GZ0cc45CA5yAEMBtbEaQ1jcCbeAVS3ImF5p9Zi1Kd38dENXEP735c0YDDHjFn07VPBNqDzy
+1QO5gD5PzBqQCZ48eLEklDCBEhRCYQ57l9lS1Yt9QS1T47UC8ynDjd5Jb1Xy4E30m36g72sN9VgBjA63P6Kv3eMAyU
+DnkEczFUcGBqCWXALxAJOF6x4EUFvN3oR5apBaw22nDge9bxBxm792BrdDxh0dw8z60YIFpsENO0el7ui6GZ9XwC5D
+DwJ0Bx7SKCez10b89G3im8155Le4UdGHLFKg7124P03v1Eby53q0dZ4S83SD6oU94IBLg2vkFRa6Xo6IT3Nd1jv4st
+2YN9E7A9T42m8pX0RkG498yX06W40g78i8Jg4gS0Vl77hCuc2pa3Zb5FgEit2O793F8SY6K0BW9AHlAbm8FG4IJ8A1
+CmhDggE4s8yaELd9pS58G9fvAs76JEEbhANs9tm09D3nsEEA3sj7h9Er10RABXy8Hy39CEowA8m70S7zi3Vs0ZE20F
+2mU6hP5OWABhDtj0Pw0EO3ok1Go5Rx1mm9g380C6Xn0D25K080s0IgG7C8in1KbAdFB6sBcq90Y4BD3FeCYDBFE5kr
+9ec1qAF3q0jPCNQ7ht6LaEL2Bwv9MW7ib0rnAbkCnaEhw3vE9Bl4uA7xm1Bv4M43r5BGZDPjCmD2utDPg8fN0yp5ZA
+5he1ze6Os3pN1sqBhiERh9tU6Bl5hOBzY66F6UAArLBBOD0F8ADDt3F9t8LV3Y2FFL91M2a656NA1PFtU3y811a8Es
+AJgEmm8XFF5EAaZ9RS8E72416T71vBC4c7Oh6WH0Zj4YB1JG6O30jq9cQB8Z3Bo1dZBM84pV0Ze8QvFpJFer0XOBZI
+DgE0cMC9EBYV5oq8hO1aQDcP8Yn3iUDTD2ZPCKP5z2CKYG616QSALH6ojEnP5qMDr3DfUE9NFen59m8NU5KXBfX83w
+3kbBzTDGLAOv88oDfdFdhA3YFYF04NDEl9t60bG5WV0DjDcW2v47hODEVDITG9bDBiBcCCaNBKB1ZH2pM7Or9xhBqx
+4j140G4N786h24M8viEcV7ty9t54Db3YD8DvFmC2an5nA9bI7M21FaAZV9kjBAj1b43kj9jl7K8GG949r5Pi7NRBZX
+1SgDhe4Jw3C03F98Tf5cN9uL7Ni8pnDcK2Fw5LpG2jA4nFV83Ba3ulATYBY9AQb0TQ6v6CkFC8Q0ci5IP29pBV27Nz
+DYO6QzCzv9iw7zjDso9EH5bj17iD66BTR6kh6Hx3Ny3nF9Y6A8R1AaBwL7tF7gzFluENj2KN5f97xT2p67JtEb2B7C
+5S9Af9DQv1412Il93eDpGAow5HT4yG0xc180FLr6CV1bFDxZ38ZDlf33N2TU87gF1rFQlCKrDFE1EJDrc3EB7Se13Y
+6VS5iZFky6bQ4FQ1bZ1SY1QV8WVBVkFkLBYB4IT9c78gK6I68BI49t5NqBWU5bA7Eb3VYETS1Wf6D17vYBKjDlKDpm
+AuYA4H0xS5vt1uFFk84L92Ek0l7FmlBd5DAm43K2lw1Vd3jrEeP22936uC2iCL75Yc3CID9k2Zn1IU8FK2rY1iqE3U
+6XM4v834F0D18Cq1qjEqu2Tn64m72kCNuF7aBoO5oO7QP4iP0ov9JDEXu0YEEs1BDr4tZA9p7sE1KzCTo3n16cN1XS
+9l7BG5BU77fGCYuFEX4sd5zG26hDlb7SR3vsGAN6Uc1hGBJCENpDLKCGJGFE4kO5QjBOdAAQ0TT5wh94K6FC9mm0Gz
+3EIB8N1FkA8S4Il28jF2e5qi1l12b82ILFWgFKD6xL7fr8a1Cz5Fi64vzD253fFAhF3qS3ZW1At7WuByh68b4qBD8D
+BlKExIAMd9VwAR08wOEFRFbX1Je6YeBqk4Wq3ePGAKE27F4CE32GLt3pu2bf8PTEUs4qF5vJEAq95ED8rEvJ52CBlr
+22F2Qy2bY8ojDp3BZhF7D6Dw6rO3uY7T334tGGU2D69T537hBe48iF1e7BE70fMEA2Flz16FAgL4IPF7V9DdCADBv3
+4tJ8Yy9TGF5CEoE00A8HRAXbB0s1RmAjX3Tt00LETs6oG6Fc3VfCug48BA0h7KR8en1X19hC8Tn9rp9K45893xK8z1
+AtnBQXAi89LTBy07kVGIW0FACJqARF7Eg6po5TyG8E2EKFWv1p36F97KXFRZEF452g8GS6qf1QY0vm1Me1iU8381nd
+59IFnL4cj9Ii1hiFxV4LNEHa1g5D9o3VaCNF5gQ3QoABmDsg9bYEY88an7QI6ZJDrh0ssDSh16q7IN38s0Yj8N36Mc
+FB33yy7JO2MT5wvFIt8yI3SrCpSCZk7PlDoJE4X9vD8j00z9AHb2QF5JJFZd7j798OBSRBUoEW44Pc5vV0CN3Nc5d0
+B3P8ApEXB2RxAHjBPq5I5EjICZsCaF1VvDrP2849huAx3BOU2tO0wo3DrGCoEAeAcn9rF8KCFdw4sZ1Lp9T0DtF8qs
+5FGC1HD0wF1l9h40h85rDEox7C74o43m35Dp2gc5mDBqPEX0ENw5j49Vm6SYCo2FPE4Kv87u3FrFUQ9IvA2hG8mA3M
+Et06Cn9VE5rW9GuFSzAIfFIFA7LAHNAbw2zx3I99oGALU2ueCx28St8DJFzi8NG7205p66Gm75TGCQElt83K9yU5tH
+BvvBdn9xZ9JHANv6wwFwXESR19RCWPG5C1Cs96i26a7GwFaXG3XEU8A421Q56fJ6JvCzIAhA0Iz3zW7NeC0S8NwCAQ
+6uw5m77x7G6r1im60y6az9ft08q2DFEsuCTM8OQE7a7MwB62CkzATf1zS62SF8b385F7x3QA3UL64t7gJElk7T9BLR
+3Rf0tf7unARZGFSCVv7YeF3LBT55BHDbrDLL9zi1IEAd92QHBu8BSkBhJFJRDB50tVBKtBiH5tU5Gg5Ci6qNDbZETn
+Dzf62iFmYG52CA1FXnAOLEnn0FP7Fq1yZDzR8mD3JC8rqGMS5aS5PF4Av2WM4o8FGu7F4EgHFbE8ujCGZDSNAs4Bxx
+EstFdzDQs1nu9868VrGHm0Ao4ycDRU2Mw26bE9QDAo7YAC1F0JvBJc6MF9jWG7EEnbAzS9Pq3sL1xf6vIC3L4W2F8y
+6LZ17F3qMEHM2H50WK26HCAP3u2Ap8B3qFtx5Yu5v57ZI1QyBalD7T5di42l1sV6uHEZSFq48fDDmK6CC4fi6mL1Y6
+1x7A1c28p7P49ey8aS7Oz3y94CXCN57ruBRU8wwCY34NA8vC051BVRC7NA9v7rgEk34V87yt3ZGGCUD1x6Hd78Y5oW
+6ZGEwKGDD3WJ8QMG3QE3G8tD1HN6dUAye8GECalE4pAUh791662BjV3Zc46sAtrDs7B1I6fP0BdA9VDyb3nA1tAC29
+52Z6Bd1bNFt5Fnu7DjEG8EcD54PAItDCEEVQEclB9i7Fs1r93pSCYSCI9BqB88400i8TQ3BC4c7EjU7T66StAQ22jM
+7qxAuI7RW3x81Ed5UCEcr9NFFQVGG7AJw3uhCb13zT5K485K4lXD4E3MH8OP9jRCbi2rX1g06LTG4N2592CgD1jCQV
+Euv8eE29w7B9FGLF881rSA9y5Tb0aXFMZ2tb2rkDR7C688bqAgK9Uv0Ja2sO95KGAbDRK20N5wLFCg9956OxFVy4Cy
+0smFRL5VJ3dB4nbFkxFjz4GK4lUA0vEGb1yzBkV1puElCEnS11PDuf3A2DzVBNu3m8ChK9o46lc4xv0WLAH74rADQl
+1Xr0Wi7v91XT0Jm0w383x9eT0hk9wf1B21MtC9IFhD9Rm6zDBQOCPt9jB2E7FCuEWiE9GBp3An8DN70ngDOMAKr3hn
+A9D6Yv5kR667CcF7yjFYuBCzDK6EHBABP7fC8L0AuE7FUFWc39e4HP0VD924GGoCd40GiBe92B38jZ2oT6eTFi82Pz
+FM578k6Uj0vk3uoFg8AhMDjOA38AZvEhV9Fd7hq50F00QC696AN0WW7tt2gzAyNDmoAlX0ZNG240dj27PDSE1OyBcA
+8Qf8dP4PLEEaAjo4vuCFkAO10en5hCA727GHA6d0P93f977Z90S53a7X0EubFsAFdt4gD7hdAxu6Jp85g0kK0w4Bck
+AQu6WVCYy5vjAhy1Hl1jK7lZ1drA9zEsbBhB5wa0nf77556c0YZCljEyfAyXACKD5H6RQ6lD3ZH1OZ6Ai2UN8G4BGv
+2xCC6e961BAxAap13ICaT9709Qo5wVF2L36WDocEjm9qx84y95fBBf9SxBeN6ZkEctANOCdz2wCFE9ELBEfuFLX8Ko
+E6K8fe0GUCmj0nLG9HGLX8gl2DxEeyCBU8ce1w027v8aXDhK9cF34pCP5AgT6fu4uI1pY17C1lW1Ye2NS7VxFKE6ty
+DMg4zl78EAju4R74YY5ZvAq7EA93EqEkQC8s14R7BvDzo9VKAIK8iP0a68UAA3CFRx1TI2Jk2DRF5MFLUATU2VT0Ry
+Bc32xyBvO7Ux5Bd45IETAD0XBDXFsJCxv0CX7Xj6vxD4U8iyBjj2GQBV97Qi4pm6OFBIYB5bE8b2CO23D1xy8zNFwG
+8SaDxy7if0Ub37ICV4AU330HCqW0Tg93cF8n1zX5ki1sB9E85dkDDcBi2FTa7SB9ju5Ei16pE1NBRxD1BFCQ44b1ZW
+EAEAWa8oQ8dK0h70t87rOE7PBb20lD4Cv9P15oYB3w4k9DU7A8A25hBkp73503CEJa6Au8oOBOQ3NGBYtD8h0A30GG
+161DteDVGGLo4a85DgDTSBRZFYJ5cM6Dy9GA2Wv8Io6DY4sg8Ut5VyBqq7eVCsnB9S0R9CH60AJ8BzFTABI5EJq4pE
+8C9AuHD6hA69AtFD5S7zRB9n5eo0IM8rf5b71AQ9it6904yX6vhDdGFjb5HK7ir3SQ26V5JG0Yk2Xf2if9lI6h268E
+3QB1tZ5NJ2izF4e5WwA1nCaKAIE4PK9dh4dvCJG60f81w6x156EDhY1ZqD5WD4d60h49gAD53I7A6FCua7MMAq42iY
+Bn39bXApZ5i60HF0gD5MEC5O1nG5RoCh1A3K3wS2KDCHt06e5WXAIF93m6oh2f53FbBGHEXjEjSAUOAnDGGV9aYCnZ
+FAz2SIABu20L2Ul33y5qn4uxEoUBCdDDk35h01e8Ao5C8DMtBBz0kV25L6fM3tZ7PsDoEBbm4Dz1lq6yX69y7WY0aj
+E9B3FpDEE2e04wp1XuCdEEIi0XG9uYCFCEwh3n94Hk16IDnr24l96e3gyFmPDYgCC22ig1zaCpFF4xAyb7rl7uD8KB
+2YdCXZ8IS9OK1p90PHF2E2ZTCzPDirAkZ4Gx3335L666M3TE2fTDGEAus2RI8tkCvf5529c38VuCkD6F1EiN11SAIk
+EBL8DKEriFrGGFy8rXDWd9jaEB66ij00fE4C9t3G0kETZFIj3LZB3j8zfDTH3zpFPf1xz6Kj93I0s69Mb96W1pCBzM
+ARbBI9EeZCbC33m6Bv4p5GMQ5pL43fD7zFjU1tB1EMFrz1ZQAtG4dm9SA91E2dQDU83Dn5Om0glFYV7hP1pMFJa8R1
+AW71uc9RQFUv93d8JAFVvFJXG9ZCF1DuK0qu0HwDtMEGR3cuGIzDJo4MNC1X1XCAkfBR4G6J7TzA2VAJ95QF0dk7A6
+6EY84E3Kn8oW32j3lDA0EDHd5wFAyP54U2aY1HbAEV46260H2VcA3G0630dzE0I3QdEXS4YrGHn4gW6HO0CQDDoGEb
+8PFEtuC5R1Xd0og8yTFgl1Yj3Fi6kyDR6745EGf4Vm6ccGNk4ef3HM4u3A4Q32mEwI0WbB3nB5g0OD3Zi4CA7i2F5Y
+1U75yrDZA5pE5Hh9As0TKADO7HbCLY4eD79j6WU5Gy5i3DTb4Ut2GcFOy4BqDYM1RpGHI60K3NP2tm9JFA1d84909E
+3rL6pJGJ89wK7F64Ap4iD7uz6J2CPP4kQ9hE6Fq6Ar2Sp0tRDeACry5FbFW09bUADt2aS0Yl1zB4OZEcL7Fr5gN0I8
+1MI7aKBt30EQ1xJ7Vk62p0VVEu0Ca3EUd38z3XZDLbAtE15N4Fx2FM4lx46T32YDYG1dq8TLGNj58MBgYF2P5HODSm
+9E51vw9V0CWo3wJEDQ1B48fX9da49x9SMG3c0RxG38DQ4COU1kA19j4eC0l0AFU9we1pf0Me9IZBYYDZR5NP3MW72v
+1I9DDO2JiDq836k3zvBZD14iBt5BK1EvT5SmDKq3Ys8gz16z8gF5veC8N7sr11RDlaFTvCG44CuAg1DOtDuJ32B7ns
+0dR0Qh1xR8vA1IIEZ9ET76qy9hM1L38B86pg4otBD7C9uA120Qz9KO9nQENiF1xEiz8PPFpXF3FCVhABpBxc7eQ6Hj
+Eau7EuDtkDq52otFXj0ns0tN2OD4PW9Sj4ReF6v22MAnAGEoE2oCBfE8OACS6aA0uB5Sl2nwDg26kbGMZ1iW4Og04B
+50w5KnFZ00QMGI010fBbv4Ck8D03mKE0D3IQ2FOGIKC5P6Xh5cZ6U4ELlFsU1cf7DkFFwCz90Tr9v90fv136E35Bmr
+FwKAYrEmnFbQ3DC51x9uP1Lo7grG1F7S46BO9W8E0M5NhFWkBUv5qvErdAfx7yJEdH2ei73y7JdAMW09P0jM5h14pN
+4Qr6m84GZ6Go1y8F1HAwe39ABQ5095EZGB5wGHhC3i7BaFtkDJW28A5Zl8ws4Z88mS1OCBnr4eNEgx89O3lQ2v18gk
+6j00Tf4EQ4pg59F6BmDNN7V33Kj5aB4VFByD6cl1SVA4eBqi4MC6aY1DJC4u0ewBN1CavBrk1b34Cp5o473RFPz1Hi
+GA69CoFBo5EWF5bCjuDGi89f2dT3BQ3b1Cg58MCG0FBMH1REDCo7Pd7Tr71pChm0g4EhH06vEx60MNAmV21q5wW2tY
+G6f8Sz5LgBEu8t0E8p28P5lk91y9suDB0AkG6wj4Vx0UA9J408KEaT5006RX0KXGEKBeSEYUDTQ9cZ3UW0QmDEn9VC
+8WE2TCDNCE6k7KS6MG1MZAGDAqV4IR65DBds2zJ2fI2wTCiB8vw2PI2N1Dkc4zr9sc6ELAEH8WSDEICB08h9EYiFWu
+3596r6B162YLEvo1zT6Bj8Ju9tM5gMEvn7vWFsYAkr3QY6d2Ept0ej1SH07M9zwANy7Rx1Va7mG9zx5Ep2RnDeF50h
+0sz4WZ7oEASO48CEk8FDe51E7X78Oh4Ef5qE8Ek3MaBsa0bH2X7FNU3lU24d1Nd6tm7dX7sk0S89ya4ETAAM1DCBoq
+BfkF5h7Im7b58ddC8y8ET77b9qX27b02p1wyC653yM3WU7Fh05p4lMA8Z3eLDc4C4sAQM0A5Dg40Y8BNXBR6CyPCda
+CcN1Hc3gw0dqDbt8UFBNS5e9GLl8Jz4qMAJJ4SUDjr6DD63u67x039BRP8XB3K8EMb6uNDMO3ql5mh2o075rCD4Cvc
+A76FC4DIr7Bm8sX6fZC5IC17Duv27l6WOECi47DDqj9lx5OsC9JDvSAeq2Wy1fh1VDD1R3vG0Sn15e0jB4bqFMr03e
+9VS7On5gSEZeEiLAsoBCw3A39peAYBD8pFNx7lb3wq5xB6KfC2m6thDFs6AaC779vk7u5CrbEF97S6CNnFxXBsN7f6
+E9c4BX5hSEif3Os6WPCbJBMU6Aw33X0cS6sfAJZE9R6Z10671ba1jsFnFE78DkzCSVEc40Dc7ER6kr1LE0Nu5AaFVp
+78CB8E5c42BM9Vx6W77oMG5R301D7g5dS49sEbR6zA0yb8f1EZ7BfU9xS0bk1Qo1SJCCh1j08to7s81QJ8is9oo9VN
+2a88iHE981IkE456O4DWJAbuCiDBME7AcF488sp6RwBxGBEo84tD69DL2GM27WN5jZ2PlCw4Buq5282am5x93rsE3h
+AQE5Ye95L0psABxAKV5PEEBGFR4AY83m6FrOCN3BWqGGJ0GR6rV4I86WsDuXAOX1bP2h959Y4uf9QT1UDFPB0xxC6U
+0VtCWu8sjDWL9sY16GDvDAdA1GCGKM9BZEDb9t01ytC8T11ECoSDdv3a5AljCMGG0z5gb1zjG146rD9ia6ST2Ur2FZ
+2IRDUcG4c3iw19wEUJ6vUF2DFEqCEZ7Sf3xg81L9LkE2U9C05E323Z2wdFDKB9E9UW0424xi5cz65YDGB5yT3GxBmP
+BiV3on83SA951Vx2GEC1KAWeE250TF3aGAdxAw05Dj2i5Dp80kd6An7c25879rP5SO45A0HV1t975EB563EC9x33NZ
+6qcCs11CpAd61LR8twDYh2Xh0Ys9o20ROB7l41M8B2F0b4rs9xj43w6KM1CW8yeG4zCcm9ypDe2DBK9mgDONFG1Aqn
+A8f6RM797Avi979G5U9jpCyxBnaCrf5OEFaNExm4FPE6eFAkA4g6TJ4hP6YuEI22eM968Bxv4Ol6yr5ulC6R2yQ2bD
+CYME6VCic9540qT5hNG3D4aQDER2DPCzw70UAbL0jt5N05xr61J8D63Yy1IzBls1Y51H8C5531M13A3yD2WN8Wk9xo
+7DLBA95mUD3a6x2ErW78R4L77XP4vw9xWA0c4176aaEs25K90fj5kQGDr5nQBM7AmI4nE1EX7w28TvFBzDj92K14Lc
+77Y672Fwh2BmAekEVK9aq644E5Q9xu74n2YvESBCN2AJe1eU3iCE59EMd53p6Fb2jSA4wDxi0a041B7Mk4Zo9z50H1
+0Lw1YK1xF7t74KM2BfB68734EmQ2Kr2msEX639m21G5sx8hp2QXE1M8vo4GhEO2GDt1lyAtLFar9pQEzg92g4ON4rn
+2On0m1CfWCniDlC3fT0TLCtSEfOEn37iV3OyD0iFfp5GqDb8BweGG1ChW0AE6hO0tqCoY3Hu5bKAn02CS5iU9akCh9
+6mC8Bd1xu9pw64e3bk5ddERSClFEvE1O59io6lz7poAMxAsI6Vj4vP0cu0AdEGL0N8CK930OFRiFu62Gi3u48CVAdy
+9XVGF52rO9NZ1OfDuZF2dAf6DErBQJCVYCXnERJBbP6Ur7c73bp82QDkV5zY1vaARJ40Y3ti6LVBwd8WN3TV6Ig3RC
+8cZ59BDxGEhQAWR7aI7yO4JxAGs53GAKh88cG57AYSCvrB3x8T94zD0B40zP4QlE23A4l22BDnz1gaBUL7Wr0M6Dgb
+0UfB767xF8Pp1mK7N5DR833S5OoDcZE1G8JFEAx1aR7TABIABYq2CpBQ73nR54ZE131hTEBYD4710pAfgFoFB6p15l
+C8D2tT5L837N90aFcqD6M03R1w55I48BpDJ603pBXz85t7k13GNDWuCji21K2XO2ufCEi4ZqDjl8CJ3JG9tdF02Dl5
+Ek005TFTVG45Fq1FfW97zEmbCYH4LK1lVCjeFuG1vj25B6ig6vj4jB7xf0NT5MnEIqEOzBE22phDZJ0CWAxI3KWEtA
+3g5828F09G0PEiC9Lx9JGDWT5IbCi93BlFhU79P6tJE9T6bTB8K4Tk1i137cC355452rKDp5D6I6rBBFC8rEBGxAfT
+DL995p9KfE2c9nO5Lm3kf3q8DoxF3eCqb9GKEfpERQB8n3GUDBb529BRuGJz5xoE9eDC0AyO42VCVq8gI4K36JV3jF
+BH7Cb3FD73M42HVBwx0KUD6dBAlCMT4HOANQ4eoEj2CcLFEM4Fa2ceEDZ4mE9oX9n27Xs6Vn6CiBpI3sv1PK1AX5H8
+BuZAWf018Aez6Ha49uCLtCXbFWEBC81Q73iaG8B4zAA888FW0hY5lu3jD9Og8gV47b5wk0gxBFF6tP8Kg5ja6PZ1eC
+2th1g8DKOE0G0HJ80c5dO3eABzs7Be8VHCd66Ph5fTAUHD7OF670C96ps6BfEy84cy9Rw4BL8vUFeb3K01Qv4cc1BN
+3yZ6Wu6pu7sg6kq4ATBtK7iA9kh9xbEq0CnYEjGDJ56hwCPb0AKDsu5Ms0ji73hAcd49D5v37bC4a2EBz9WEE3A9Yn
+5gcBUfD6LErzFmz0evCDgFNCAM18iw89R7Ho8zR2bbG4yDK163m1OA7ubDKvFLiFuVFTT4aW6dJ8fT2EYERsFoyCwW
+EWB1SiB8PDOaBly3JJD9c9zeFlJ4M39Yl7hw36l6Na1ur2RH19q8MnA786o8AUn62d5Et8Ax6yv0LIB93BVaBL0Dhk
+5ms6hzFNN9sp61CD605OR2ZQBfu4ZsAt62orFGG89PDKa4Eo9EZ8Sc8zH8vh8pUFzx1gjBvcEu52Co69F096BwiDXr
+97i5QI2Oi9RjE0x3udEqdCxCERL2Vb7xp5TjG7vEzJ3IU2uhFK525W9BE4s73AtFnNDWBEmpEmg64wCbp5vFFJw2Uc
+BfB8fH8DB2KcApT0pB28y4nS6tbCaZ3co8v54oI21tFZz89L7pxAJ18oq5an3zm3xP15a79b1Bt3bm9aH68Q1qOETK
+4mK3F31ig5v06CKDePBvj8IFFo92oH3PN2bk7mbAsvBaq7WWCjv43VE894Qb3gP13h1TH8EhDq9BeHD43DDP8py8xj
+3fb20B5ERCIBDfv9PSDIlBrDDr5AUI90QFwg3OAFs190911B1wV90hA2EFSq6htAXH5S4FhrAevFSH17l0W512d2C1
+CIQEzi7O9BH30M79vC03uBjk7ex0d3DgsBgCEdaDC51ab4zHG1D2m25J4BhPALeDcu80g2j34HV5Oh3CUAcH8Ej9BF
+2OV59L3Jt3I0985DY89jZEVw3Tq6vl1s10Sf28EFmaCsi4ig6mrFZ89yPCaDDFbFbb3KcBrG7k6Ac27W54U7Cxu8aG
+2td525926E5F9otBLAEM7FoaEJOESw0k1C4t6zG2nzFsg8Li9CF1cZ5Sk66G7RV8VO4KA0BmCvnEcRB0r1mH3Tb4nK
+AlY4giFqa1mb8EnFzS7nnAMG2Wp3xm0RfFgZCQyGNGCa6Do67M9FKI7Rf7YN3WOADu5JIEAaBov9Ca2sX8U3FSV7l3
+3tE5fY3O01YJ8AeFFT1PZCOvC7uCl45ZZG3W5lXCDv5FNETQ0kj85lAExBuN0JCFNj2vfF2G1c0FbH3XQEI7B0B1ch
+8jdBtvG4FB2v3iF31qEP3FiH6HQDlQ6AGBAH2LTEus1FMA0f6tCFMq6vM9iR4QX3BN0IC5y36ytDm11OW5Q6D7MCXz
+9J02vs32R58pFGR9aG4Vc9eu9406V728F8xq3AJCKh0U950q0UxGF876p5xf7z09cg4kC8uz5Yg6DJAcqApw4NH854
+6gO5vy8DUBCHBoH9y2Er98gjAnvEii3o773AESq1E8EyEA8U1Oi8M02zR6ud7kh5TA2uW20767d4vaBih7tP0v6Fhj
+7FH77M3VGFqi9YR8yN0If9mk2KADPQ5hx1GGB6Y1RYFwnCgw5HY6TCDj5DDqCZ32FS7H5GO4BdmAaz94F35g38F5IN
+8g6FbJ2xXELpCAAAU01pN1SxAKb64B4AN9VA4ubG180072AzDOPA4k5Hj36v1yY1FY5Ky9BtDv33g4Fle4aJELQAsl
+37X8W03IG9sf4ZVAi63uv1663GD2FsC9958eF05G34FxnCVNEI5FL65sdBIw6xY6SN5CO6eH41p6I37rU3jE8S60rM
+0TX1d45H779W0Ml199F1NABz7omByz8Zu0nV5IH7a48Pk31tDzw1h5E6fFFQG9o4is0zjFiq4OwC6m2PDEVc1sm3wg
+52R7WA1IM3tkBuM7sl7Dn2Xy102Fl89NmDBnCVaF648r82vr7Sz7cf4zEBBV1mnAE8Ei9EXrANSEkKCFTEkN0HC0Lf
+ATQDI3AnuCy627oDNH4Rt0fT6Qr4Jv67B6AqEX3FrmDMG4ulA5sBTpD8O0OL4UnD0eAKwBkg8v2Du6DT389b3TDAug
+3b95yVDVNBt6CE11cc3CV5esBbKDZj44J1K6Cof9d048bE7B0lo6877PkACu9ck8Qt0fyD4J4Sp8NW9KGCj66PVCLF
+ESjFFn5WPFm08bsEc05sw4l53rZFVq5ow9LLBi43E60iR5tVFtA3ci5EXBzz3ZC1ma1La8qP3mh3Ph5cBG7R5nb1kB
+BezCZXCDb5mHGGI8Af2pBCklEULCIzC0n8QT3h09GnEAb93hFUR22bEJX2mqC7H6VtDMH9ro3UtA2O0NfC376mK9O1
+3sFDHh90U1BuFGTC5a8Zm93b8wc1BRB2TDDhEzb2RyERYEiqFsj4Lv8IN73a3RQ4B52LfCNXAxG6kz7X37lX8sBBP5
+CjsEk5B2jBwQAuiAjk5Me86E8V1BUW4nG7vt0iFEo36On1CLBm93lb7uC0ny6169jJCg773e7jQ9Mp3fG3aW18H9F6
+8EX3xt8DT4n991C5nfCIn01A6I9ALpBQz8z41cH4YFARj2mj3T384gFLn8z94PpBLmBxu8hH2yt6aQA667Zn80M5Fs
+3kKFWT6Y3CKHAfJ1H9Cf27w33j2FQsBpX7KE3xa2fZ86Z4JjAb72O94zzAV43UAD6fCc46Zo80N2CX5o2ChFBEV3qG
+CWz5BN94k8cXAxj59e8tB1V1E8VEgaEFDAzs9FQ8J4BhqEBQ87DE7w99X82s060G7t0qDEPT5ZnGIMDK52TE48ED0x
+BCn1OODPtCyj1ol0VRD9V34J9uG1CGBpL0rQFm8EE48jiCPf7smA9iC4QFur7MaG9hFBwF7p41kCDZ2FT9Q195l3bH
+1Ab9bkE6Z3kq68zBAE7164on01b6zJ9OZEWR1H16DV1n0Clt42fBPkDaY9GRAya6ly0o05y99lb40zFHw2IJ6XPCoC
+2kG6Rj4r401c5IMCrlEOHEwY8NS2pu9wZAty6AvEKb5wRBIE2ZrBleB1fEI83JBFXa1xCEpnG9pD6F4iI6Dv6edEc7
+Dtt7ci0OaDkD9dcBeU1gM2mpBhS0L347Q4xtD5DEG29gPEZP11tDIZCUhEJCGFODU28ra8QJ9q23jG0sOBJXDpBAhb
+7d97ZeBi5C6lAmh4rjBNy7qj03g9ZhEqeAdGDbs4uEGIv1Ct1MmDXG3Nu5vP0jQBbhFzo6Be7Zr9yiEnAGJh9qFEbe
+5Ze8noGKZDai4zsAJGGCn4p63Fu2KU1nL9lcEuX8YKE3YC0xEOt70EDCW6DIFg27uG2pW6hgEru7HeGJO68c1QFBcX
+3gvALi2HMBcrDsVFasAVs5H638AAmm5QO0SYBNpAbt1h68vx5aRG9Q6PKDWQ04j4vf2Xe0qA3kO3Z33z82Ng9b80Pb
+Ech9mJ99S0Z4D6YEh65ZK0rU7WF5g374S2I30F22vE2Bc3KxB1OE6S3894Hx0bb8TX0e5DeU7jt1bpGMH7lL9zb7nt
+4xRAVFAkh9znF2pEMm3Yc4kZCxP8Hu2k1FA92kP4mAFRJ8xQ97CCPB4cL63J9QtAB0BxU2AdCxbEHc3ga7TuEcQBu6
+6hW6Ct7DZDYt5HF4fB4Da0Xf6EV1OwEE76OW7Bs4wm0tB2NMCx68Gv4dy0PrAmwG7SCOW7rz5Bf8HZESKFbDCHxAkX
+D3nGNW1Tp4v71dQ8VS1ycBxQ33r5Mm20g3brEtdDga7AxCQr58XA3i31x6Cw5Np6xC2qu1ASAPG6062JVEn67Dg64v
+3bLDZiBrzBMjENVCpP1N3E72BVnBR9AyT5CUDZ19eoAISFCbCJ86enGCuAYy8P8DAiAZN0iUGAAFNz3Rv2gD2AuDql
+1B5BH2CCK8kb0fxFJB2iK9Y52pxAlS5HA4ty5YjBXg06T5goDnO4DZFMn6229b15GBF8z2BsENC8JS6FoDUvCbUAiY
+57K3N64rx8j25e7DDmBtWAXK3E99pl1jLDYI5l3ATw1Bb9Qu4jF3e059g98I9oyC5v68B1BA6QoElp5IU8u9BgH0Lb
+Eeb1Jj3rSDxY2B6D2j4Z32qp08T3ht9N6FQfC8PAsKEyOCrnFweDy71Ey8sO4K23oSFQ99QJ0MA5cpAYV6prCB41bO
+D1G3o9363G1B3nK5ywEbW7Vc0ec0BV3Wg6fkE1nCJmDts2Zx0ut50YBaP2Oo994DvtCLSFJZAg4FPd5X8FSP4Qu6tj
+ETM2JQF9NDdD7Ke1xb5oK0QO0Xh9C16ss4dC32W6kEC5tE0cAbY2WHCRw08wAViFbOF5DBL8BYe6ir0WRA9w4oTEyI
+5bXC047oVEaP76m5AJF6SFVV30K8yG7EE5WF5TL6fpEtl5l98n329IBdJ1KGGAL3cS6fb6Xd0Qt26j5fDBdN1Ep9Ng
+Bol7h7EZwDM7Ae9FaVDxSAWn3YJAWu6aN0Cx57L1FZ9vG9kWCzn0rv1Sr8LG1hj1pb98GBZJ3CNAhu4UqAKB9deEtE
+FNh3np5oVDuH5MBBEdFehBQG72oC2y11lDT92Jp8fdC52FgD77C4TJ9l06UzFuq4lh0xRB5LGJJDAg2hQ3HCCbMAFa
+4OI3Q95qTAplAzYBzhE1j34yFaEGLD0APEZ14Jr4Py5T4BgG1Lz09O779EU4GMKAWsDOV9ra2u73Jm6KrCLZ13B4Ax
+6G8ByC4K50OSAK0AKn5UW8YBCqADNcC0ZEOM25n9um8e7E1P04yF74ET6AGm7bY49BCTrBNkDeQBLVDKD7mp19y3q0
+60dEiTDsHGMC8NmDAy21PEVzEIOBjqBF9BHMDRpAnB9x69zuAvr5jdFwY3lx4Cq9be35b91mEV3A5A9APCMwDeV8Nl
+8AR0UsB6G4kADet7f2Dj0D9m7CL3KK0kl1IPDMu57VB8k1Q90PQ0OV5i023l3YeFUA01k4kI4v6Esn33e1D41FbAGX
+Dva9u05Lr5918t51SWF5S33C9sQ0CnCGl5hIG92CiP8UjGCx98eFiu3IIEHD7Rb2VFGKu9Yh97r7B63Aw8r13DB2sA
+AeF5W3G2w1oY2CB1VgAXa6XVF0PDAF5nhFSc4SV3wrAUuAeBFUt78l7jjADAB9T9LO0tZBV31ev7RTArK7Zo3RqG5L
+FYm45O8m67R0BJs0Ba5noF6p6vJ1CTDUP8DhBHm58HF7EBBG9qJ3QS9cKBqDDpT9v7EYR7tQG1bAa56DB20j5Vv9gt
+30SFJrFgT7Ew4ci3mt86k1zx6io6xD6UkAOn7TQG2u7s3DjI0dV07HCkC57bBNNFao9oCFIJ7Aq46qEis6zr7xe8uH
+84JCzM7Sd9yN0Dm3ZhF6a3NkF0t3g9FXZE7T8w46Gt6TK4LL9ZOFvH7ie53y0Q509w5Bh5Cz164408AW13dQAFmAY7
+G8A8bX2CH7yEApRCiwALPCptEBPD7r6zqEnyFYgDj67FC2aJ9b96y8FPY0x66Ah6qmAMJFg38SF65w4GwCtVB5R3CR
+DKnCr78VN2i29Cz1UfDcG9tS7TNFg65rtGAvAOy6Y14gu3eJG0LAsi9cV0SR0lv2wFEnY9gaAdEERK1WBAQi1BxFgt
+4G67ZMCT91sJ2Uk1gKCqm6tQ7WP6MN8S58aL8We3c1FFcD6tCY19IfDw824NBxl5xt5Cc4bd4TTCwS3S5EV89F72Nr
+68q8fy4xzAZiCFhBl98AOGMFDx32zM9Fa1kyBQH20V0f93394MAE8qDMX7TVCnuBbcDhN1lI0uC4GYFUa75UFhf6PT
+7hF0QS0shFPZBfc0qs7nr6QQ0jf4an5sO4oMAjRADP1rpBf08Tw5gH3Q6DPX7xZ5ut29s4KU1xi8rl3g06g0BP27P5
+2y13n6ENBG47AiVEAn7sVGHx9cxARg7SZ8169ox2rrE0d2MQDouAiD7EI8gC48eF8pEcKF9n8m11057NjAvZ7h09nS
+2CU8wBFHiBR3E1683r040EKY01JCVj53LBb833oFWMBrQEPU6kQEf9DOA0258DkCaYBg65HWDu86M31PVEBu19eFip
+C9m2js0iS5qw7nS5q5ClrFYp4nAAjV7Q2EDL1s2DZ662l0aM76N0kq7uyG408yV6eB2avDnPCYsDeiAC82sD9T2Fwo
+DAsFBQ82r5eC6Wb4G4C8k6f82PRBB82GyEwL8ZMDis65y74a6Nk7r38e2B7o68d1ZM1bK4MO8d5CD19CDEAF3ggA92
+Ddg7LzEPk6PmFQFDyi8HO7JUF6UAlD7mYGDHFYc0Bc3sO42n9qpENE6J49M8ENG6fI0LyDjn27m0F72J055J5eX0uu
+9Qn9FO3azAMQB6L9eLErl8nq2N48qj1mw4h50aq2YrDMV5lj81c0EjBvm0UuBkx7JaAfp5vDA2p8w2D21CXM7cZ6aZ
+0k39li7bM4XE2jZ0iPBjO2Dk0pR742Fs9Dfz8VM1pv2FEA7f9ZeD8K5gR7BT1KoFSA7QA7Ta0CaADk4Uf71d46M9tx
+6j94ZC0Em5sR4TdFbr6IuBNx3TKBhX300By6D091GHCM2DbM16l6bU2476ybEYM6cM4c4GBHDaNAgtCD71WYEn096X
+FjX7uq3940QN5tD6EWFX68dR1bz4VH4y4CCk9gbCXp7HN8Ts79g7qz6o2Ayq4hZ6h91Rb0rh26CCWW6E7E6z9GZD2z
+FDT7ijA2X0ZQCfQ4Df3g765SEAM2oV0lF16iG8bEFTA2D1SZ4FN4lS3quDQIDvH4wXEFS3X708bF5U3g667c32MAEC
+6SM8JpCcsElxCZ88vTE7U3ew49UEWwCOh0wP1JfEU1Bj36KzCLfDD76aP36y5eI5VZ9el6K8CAwBrW5Z99H3DR472d
+FUXDg0BkXFQm9FuCRx4UaEgXARmBjhDciFxY2HDBWZ2lF6Bq4Mz3eN2grBYxCur22DDc0BLyG5l5nx8zLCqfG2b5Vr
+5uK64f7AwEfsB7MFMO2VUCawEPw94VBvW7xo0cjCcUCmIGLS74D9pP7BBDX76iv8jB2YY40v7cGCYUFB7FxU5AP9ZP
+8mwAGJ8rHG0XBdbDnd98H6MtFb20OP7PnBH66w13zUCrsAM36OKG0a22K44C1GmF8s37B4yUF1B1oH6RWBIh3gJGFW
+992CfVFIdDOiDZa3a2CO638t6c25GZ8XPCiqBDhFcQ1sU7PX6vZ11vBEl5ByBWt0Aa3be8BlFf2B7w2I8DFX93g3Ni
+7ZOFNn46DF0B1v52HmG9V3yqAWT1Sj5My2LM8CNDC12XV2P51739RC2tk5XR7eBBNA6vc1NH7D22lNET04MU4YdAtI
+12t0XnDyPAoG2jAA8PAlR5mwBuaEDJ5kE3tA4Lb2PL0bQ56r0CAFzq7nP3cg1BdFYa8cb4468qGG4u3wK7EcF7CAs6
+8BN88N5Zg1552RW6GLCFDF928W9Fm347FFPTBuX0MkG0v6kC6dQ1sOEFBETl3wl3la7pm5y8B2iCGh0R4B94BoCCQg
+CwpFLPDDL14f8KHDUj6Vf46z1Y26mnAAw1gxDOd8ClGK9AGU7RiCzm3oKA2REKV3Gp2VABrK163BTo2l92Gp71nCNC
+7WC6D0AbhFsZ9Wk7Tv9yFCRKFCL99E3lKAyM0JQE5yB0g9sn0vE53KA60C07DvXBAh3Uw6f931HDoz32q0UYEkd2xE
+6K518b7cw2F1EsZ0aW79cEUTG6h14G4yM39gEDg0n7DUxE679TC2TG6w374I1kxAGO2t4CZD4M03Xr3rA6EE3Ax60B
+5HtGBC3Km7vHAio9E22Rt00S8uy9yk95M4w66m02jI3mg5hl6u74GsErrCuQDiLAPy3cN3HE7xGAK65om9i1Cf1CE8
+8eiA46EdC8LHGGE2w33bFAalDcNDb54J92D8FQc7Ot5pqDZxCGECKf7oYFSw2WC37O4kD7tCFA6EAi0fb6lR9r4Eaq
+6c08N25DZ73j9XT5Di9Ov7t9D6KCEP2UR9AO86P5mL4zX19S9gj6olGJX2wt9Sq8Pu8QU3UmEWh2IpC8wDDd8aFARr
+2rl2d5Ea75s2Cle1ECBvHG3ZCW90fZ9EPDqu4Me9oi7gR9YKBjXDsT4BC1Nc8FlBUsEEz6ktD5p5tM73D1q90oe0zh
+5h3Aww9dR7W06Oi0Nz4qeANB5yi2WS9L35It0DTBhVAUk77l9oH1UrEz82vDEUHC7r7bQ1UoDi09pLD4m1HQ2j8EzP
+2sB0vu7TTCHC05e1fN85XCeN2QK44d4b4EJe2kg6tSDfHCOGFxb0iq9Tr2SN1de2WoFIy3hV9Zs1twFn8FUr3TI0NI
+4gTCbzA6IE7y8MWCs44vk2dwDWW29O1RsBUF7QU5TV5Aj4ZMCmS3nTDtT5eZ30fFrD71yBvr5853p98Ak4ym4Hr1H0
+APBCVE3aSC7X98RFz16Ku7ulDyJDyD4NV8rc4K6D0CG5J0FH6ETBbtAqi7NmCdV0BA6fd01H0A635tBn7FHm91O7Ns
+FCtFvc0j4Fqh8cn1Zl3FU5HPG9WDrE4DpDdqEjk3tM6hr21SAx67j49CY8QZ8pl7Tf8lT1qU58gESk6oy4hU33U5U9
+3NF0Gv1Jr2AaDoA2A81vsA7UGGa9yj0c3GAcAmUAzr1PS3b01zk4Je8DO1AI0ca1Yw2bFFmkCjIDEL5Y0G3j1xsDx5
+6w69vRALE4045sN7xu4a77JZ34X8Ui0mKDW65aV4Oz0yl0DGA6E5N9Fja9w818P5dn0rN8ZdCj31GO9Xl2VX1yF3vJ
+17Y8eF3rD7kNBQ36Bs1Dq7Qb9wV3jx35PE577dkFYl4Pa7kC5lhAuM4sE8s3FSi5OT3DhC8F50pB6w4aA2rQ3yb3JI
+3jW3Uc7nvECz0kxCnTG9EGL46a7EKd1uSFj06ftEZs3IdBrH913D85FFlEYf0B025eAe25lt0GX12WBoM0uS6ax8o4
+4hQCT11vTB3357S1icDiT5LL1Tk3k3APw0MD1raG9G9zS4ak5Ua5WLGM72nIAxpA7b0FFGC1GEX8W57miFy76FnAQd
+9K399h9rQ8Hj8AyEuVFHv46dBiB4vAG7nBCyADr02Z15i6l5EFICcjCzcGCq6YB7FKEug4jtC2f9yw4XeFgR2zZ6fl
+GH4F6D47xFDIEPR4jHBdeF5B3fsE7H2B1EH22yI4rE1L489v2ky1VrGH0GEO6XkG2zCep2E02Rf4Lp1Qk4dgFnp2zC
+2qdEAD4XqFibEM3FbI23r6FlEAl2B8EpQ0Rr8DA61E3iXC18CzH2aF6kOGILBCo6qT7XICWLEdt9CM9SB1LX8TA3AP
+4PG5KMAtWFAq6WBBhTE4f1uK6632pc7AtCJsAdUBGs1QC1ru9zs2sq6vEFT4Cw6D5d5GPBTQEfLCLW6yi5vS1tEAuL
+BMXAPN0YaAKmCUq6k74xy0t6Bq426O5aN6IsEonBd9ChL6zW47T7AfDvoBNDCCj8IbGKB4v1EMR9rt6iRCTJ9zR9Pb
+6Z33zF8bJ7WR1CI1ow4P8315DJBCpq2yU04e08vFrH7wQ9UA1Z61EADZW8Vd1IsCPq9R74JzDTW2ct11Q7I38ED6O9
+Du75o8ByP3b2BHy9qKCiHCIC3ed1sb6yh7PW53Y1EOD6k0HBE3aDoZFOxEJKDHvARW41W4NUDip8QK6JXAbIDsm0ZD
+9LDArQ2ve8lQ2ZU8kzCI04qz5WuFAZ5SrCQ5E8PDVhBwb9SR4X07pU0BU8ry1j602L351FbsEVbFUuBkT8wd2OL4UB
+8oL2k0Fnq0XxFrg7dKBLd9bnDIb5Sd4MpFrL2CF6gc3xz8wT7Cq2HKGFm8TIDuBBHr7RM7Fz9qL5ETDbWFZwAxlGFk
+ARPCS27uBByRF7HB4v3pX7kq3sU6bc0a85nO0275ZV9DWEBM5niAJL9GX9KA0FT2ZwBkE0Q83GtG656pTDPL6tx53s
+Bxq1BlBdrA1y0JJFdaGITAH11jg4ro80y66VCzBAErC9zE2C2TP08PCYxDWKFil6YACPO6SI5Qk10OAy32zX7eE9mi
+DBR6Xm52f78M7MDCs35HQ40V1F53QP1LZAjc74lFTmCOo9An7guDmb7Xe8r51l834bFr15me0V59ll1uqGMa0Q07jc
+8X53vCAyvAWwCbXB4jDoO8zz3FXBO73a8Fcm3Dl25g3K62Ic5sm7ZW4af193EzeDX6EZlDQKAR35Wr9Kh2TiAr22SP
+8h1Dk27k84XG9FwAWOAOWEdNFt6Ems740BgJ6jeDrMDIn6PkDwlABc6Mk400CBl5wzDz8B7358VGLU0Wt4sR1h75cI
+DMC4PVAoI2ya1ko47K1tz8aH1PJ0VG4P63Ml3678oUAinEN21KWGA9ECv7lc7ec8v9FJS8oHEzY0Bz9IH9rr5y00gi
+B2L1iZ3AD2Xv4ER8ePGEn4SuFePEZz285EkB2Vs4Vw4Mw63ICtvEfJ9cW33u6lJCRXBsI1IKFWh5RAG4PDAd4AWBAM
+0Jq19oEeMB0W0XW7LUBsE666DuTD9TDN01nZ4xZ4cZ6r7CGP6rMEc66px6SS4zG5Sa3nLGFN6ZqEqJDWfEeT9MJC6b
+F3TABrD9v3w58X95LtByG2Tg20a2iOCffACx8QsBOIDWz9ipCTkBJ20FYDUo1iY30X1YbD733hI06Z1PIBzi1RW5V4
+8ag05dBOV0xfES2AvA5JN4sk9ty9F17XM4arDbH28S8AQ7VXCa87zK69q96KBGl2xu2PUDfMBdRBeu0mFCY26T2B5A
+FJU3fP3Zz6Vy1SkAXECsk7j3CzQ43pB82CQi0CeB1v0TJ0Sj6CGBZy5Ba40M58x4u6DbFB4h6qV91zBVK11CB3W2wO
+28N1fA2Qk4sFDkmD63EiSBax2DcEokBKTCiW8fU2lxFhCDcqEXp0ydFyREqS5dM2RlCcOBcZ8Sr38eG7d57h2tn1x9
+64Q22ZA2g2kf68m7WQ59SBpM9qm9v1EZR6i19cv1MzB3NDGACNT0hR4EAC6DCRP7Gl1qB6KK4ff9Fh8Di9pU7EfCFd
+GJm7IW8ba5biCJF4PEEiUBwX43D87JFTjGHpDQ58j65qS5TYGKt5bWCnP4uQ0fG0ZFA5a6QhFSmEt9167CQHEViG37
+3de6XqFqmDHJFit02P9sg5Xn3k5BrO0l1FquBdfCQz8yO2C8FsR7W26nlB0Z12P6Rm1oA0puF2a7gw2h8C9ABjf2iG
+A5JFwI9ZRAQX7ZqE5A5ryAgH7iW0WG4X8F0Y9ijGNa9GaCzC01Q4ZpCKW23KDnV8rt38P2qnDYV5E63Mg9opEoLBe7
+1R5CfZ5pI9IuD5jAHu54t4Bg3MNCgr4fa3bX3NI8QE6wXCqN6oKEjaFsnClGDI8CpT6892Nc0b60Tw7kOBLU8674gA
+1pt3Ro5Fr5qOGC3GDRCH7865ANM3Vx51ZDwj7Jp5dB0rb53U14lACW7N7ES113Z1rNE6J8UwFSt6rXCynE06Bwm9n9
+6IB6GU6n6Ap35Ic7B741d51K4s0AUz8Uz5p2211C5cErR3Od5g52Iv1BLDl2FxL8gtGIi3PV5SUCv85AW9keBCc0s4
+EXED6Q9xgBXH8maDfg51t9RP6ip78m4ph9tW5p0DBA75g2bSBHz308Ew9DgZ28k1BqCZQ5B68YM0KC9zGFWr5AK4Vn
+8TN4JJEBjB6W6le0bt3c0BBZ3ba9CU4923qf2S5EzaC8xE3mA8M6740vt1Qp7dz6NPDJN2WVEmTBAyBOg0io55U46K
+33b9Ej4pYBWw8h8DyjBMt5AMFGb4Pl7850NL0ek65G9x99JLD4h5aa0AwAj26OoFUUFqW0OjG8M0IsA3D13jDDRDF0
+3kRCwvCbKAu01568uEDj45GFGEc4hXGIN6UHASRCR53OT4sT1Cx5kw7djEBw3Z8GE64XJ3feAYt3AzGCg5NLC2e16X
+DVCA05AjgBo98GpAIc9Yp9OyDAj5Xy4F4Bf6Ayo7cW9jfBCq6hs8aj14pE3bA9R2X23Hw1CSBEJCR1D0uAx051D9XA
+6ZOD8i3cC30E5k316cCcn7bJ8NACrN00u7Dq3PtFmhAquCib3flDCnAPbAFcDQ8Cu3B2tD4O0s3EMeB381rjEJ28sW
+3zo1qy5X96mjC2p85S0ZpEgt9iE6FH6kn6YW17SB0i5cy0cgEyN3r4EOI21J8fPD0S55q67HA2YBNj399Dv76Bt9L4
+FkR6WEE4t0VqFauB1RDHBCVGG3h49I2uC3JQFnnCrv0MP9737aTEEnCF3A486S4COQDfL9YS4x87eHBCS493EJz8oK
+EPJ3aeCrx6Cs1Qg0Ex8Za5dzFDhFR09os3gVBYf5wB3hiAEo1ED0fuC0YBZdGLvFo6CbjB7s65223y4JZDcE3Ky4QG
+6Wz7x53F57mR06A3jgBglGDi5WW6Ty37o87Y4aV9Ne2Ht3Gc7npB9eBtG9UM0Gc4FV4S5A4u8RiAv15SwA5f1DN5Ts
+G1TAyC91Y15333V5wQ9h68I13BJ0AR5vv2eRASb9Tl7Dw98rB5TEid8I3GEx7cFEw6CIA2gP7nA4Vr3AY4kk4Ed2vz
+Ez9ESZ1YSAVg7wP7ds5rw53o0JY5NT5Z61JO4TU9dA1aE6Qe6hNG8q26sC8GDa4GLr2XMD0REf6DK36qSFzb4rv6tF
+9EX5hV9fP2S11aq4im3Mu3cl9PH4yH1qK1ws6X6FdpEovBXK6VpCYY3hM93uDpC1kp4b9DDgDJU6jvA7Z6OD7VQFOU
+DYaFoGFQ7Bav6WcEv30UhDHo0gF5wx5ZF38g60N6mP3tg9X2G4J7sIEXYC5n9URBs2BWQA9o1Se9va5xwBJ5325C36
+5v48omG9t4ceDbiF6B5a9F8F1Xl859Dq20NXEZIDptASl7i3C7vFeWFM607X4TK3Be1qVCLH7sA3hs2kZ6pE7OvBKp
+Eek5bc9pDCxk7inEFXFcT83aAZO1KYD8sAq5D94FS9EFLCZ14D9AxL9Se058FmfG1GDVnDjb1KT3QI268EIk1pl45s
+7PA0RD1wwB7m5yD0sG50dBT638c8lZCpQ9imFQ0BNb5wK4E27qiCfX9VTD8M2GoDNYCu1032Bz56dM8908Oo7ZZBs9
+6tR4TOD91BlpBsQCaV7E1CFc5MY4qa9R6ApyAGt4g26ScGC40RBEM8AwhCyiAEfCGkAet9ALAbp0vP5auAyk2V12oJ
+9oO8Tx6R71s3430G1PEqq4757Km1nDCR7Dk352IFQpDj70qHAf80t53I35ju2rA8Ga0DU9c06MYEDx5w20p28mmFid
+EQV7Nk7tH9KRDTN7XY2uP7uM2wG0HM7je1alAWr6Ft6P8CZrANnDFcDhDFJfCVAAs29dX2Ok2yu8Ig5bBAWJ5FQ8aD
+FTZBiL0NH6kI7ku1MA5NCEo08BJ6CyBDv8rjFmA76f6tqCDF6hf4CbDfRCLaGAG1tS0PVFUbC5y4bP4g85oP4SY47M
+3hL6LlEXl226D7dEJiE0X2Wb7Bf4pw0jz5vQ53X2BkFs0A6BBk41Tv6xrBXXGFVC0sCo8G7k3FL8Cp7qDEDk6S2Fb8
+3CzFsGFxd2sT4wn9Wd0gK7vAEEd2JS0YN45c0An2q14i7Dyu2G238y4AmAsd8ui8jxD0BAiR1PgCgJ33j7ffEar2Wz
+EJI5rq9rd0TOEpO38R8F87Il1J1A62CJPCed9vFA1WE0k3SVEXOGK73e81QH5WN8wXDJY5Ar8lsGHXCME3PWFXdFfb
+Cf93pQ9Wv2YQ86y7VL6GJC5Y8bQBHx17H0QE5AuFxP5iR6uMCUEFIs8357EF3sA3ET6r89tPCSY6WyDCIFtv3Pc8vV
+2cVFfM4xd3Sf8wf496AuB2uHBTbCouCey0wa3vy96UGMf9EcF2FDrf4NX8ul7Vs2eQ24ABzg0phBHgFqA6z8AcX8C4
+E2wAbEBLuDZo7Wp0wb9f88Ye4EsCUd8dl8x85mW1xS7Y78f41Vc9HJEqWB0Y5yJ3Cl4r6EfzEhg8hh3Uk9GmEZK3Zl
+DpI6jH0158dw3T9Cr30W6AeI0TYAVu08m84V1vR0hr9XW2XKCnHAMtCmuFjRDwfFKX8ud0m70N3BbRGB22I6FIvBBp
+EYn1zZ4swBapBqLACNEk7AeOFRpB4W7la1rU2F43y221v6QGCae0U68Iz2WB5y53lWDev4JfCpo3Fy9lWCRe05EEsx
+3FxCHsEYc4Kf5RiBcQFUV11iDTXEnU2ON01jFLW9SP2CeEQq93U2pE7hYGIt8lC7O4BF4FGcB9r5WqBLME2d85c2tt
+CTGGMb45m7LJ6gv1rJ1ar0Pf0I67vVCDQ34REVl4QODfmG9u0Bb0bU2bQ1jRDFm3qO0poFz01IS31P6Gb6GEDXqDNl
+18G0dm2kR9PD3171AM1mZE8D5efBsbAsJ8vZAMkBWxFQH0mD76qAUB2vtB401Hr7VlDjy2LF3hT76A26cCl78ok4a1
+4YD0sU7hl817FK4ElMFcN0zpBQd5mk65Q32LEGwBgQ72tAVc7bN4Q64DF4ZSEZMA8wBtw8KY1kMA1tEIv3x0BYJFwW
+CxdAPu2W7EdwAYWFVT9dH3AE0ThExv6DlD3S70FFA51mD7rp9zBEGqG7UFeMFC15kHA4DEt4ABdAulDa2B6v34A5Dh
+6bKF0o1Ug71tAB7AMNCWpDlz9wiCia2D45dY5SEDAtCiS6XuAsq6o0DKjA2Z8HA3Ka2lJ3c3AUJ1o3EDz9KyEAH2VV
+CUv37VFMHDkuFkH2RsBmLC6A7XB5s09Up0p5F9rA8WCA0F4a7g07fKBojFzU2SQ8uYBrJ1AmDtf5bH4oN0TM3Lf7s0
+7HSAPkBA82KI128CjM8233OhBdLEd87Bq2zpB0Q1dd7cR0D9BBr51m6R60q70Sg71YCrBCKI1Y7DZsEP1GNO4VhFDu
+FQj2FCEnR9AZ5YUEhZFMeDMv4WBBCB35w6co4mb1NCA8z8dI4ox1eWDLFAACFZJ6oxEv83lBEe1F2qDpy21l5R07vl
+9Os4fyFYI5vw6GR6ef8z32U9CwsDSS4ta2EXB0U7m58mi3S89Uj4TR8y6CQ8BsY1cp9AS4avCKe1Qx1Ev6rZ5cuBDM
+FSeAKjEa03ZsG8c2wNAnbAd3ASSA7M0Ww6NYBZCFatCj29lN3kZ5P50S1A2fAHt3jdE1WEOQ1tP6G6Al0B3kDq121b
+8R3DfjAUyDsA9Wx4lCBSs68S6BIGFx8kO18B0BTG7HG0671P5WfECJDB822T1VR75X7Cz04i4LdEio1o424x9CGD9Q
+5ibFaQEQiByI9nyCpC68C17c3Wz8cW22zDgy2yV5Rc9iZDVmF6h5OMDJLDvU5u25IuBkR7ji0UQ1CdFD290P0guDy8
+DXm1Ha0BvBiE0tp9PF1yJ0Hi1V9CwV3ruEm5BlTChR9re1YA8rwG0522m4n8Cdr5em8xy8eW8e07rZ2HS8B3BNg7Ou
+8Jd9l66t63Rb0Mw8L302sGEL8IW3LdEfNESy0dX2jRFOB8Rj52w6xn9bwGMJDuM6zgCQ37REDby7Dz0mn9DB6JDFhY
+99u7kg5PG3dT9SN5Si1on9na6S99KY7Yx27Z4Az9c9CAF7KCBDS9UXAls6peA6V68aDRN50c9ztFV1Dlh6Pb79w2g5
+8D5Apf3hq0Xa6NK1UM3Vw3dLDpq9KUC3h37Y1gEEqC4DJEkFG757mECL0Eft5jeD9P7lsFkzExoEeF6cpFw3EjC3Lx
+6plBivAfaDgp7NBCMo5EPAS8D15DunC3U2cp6SZ88aAUs6Ke6buEHm9YG49K11M0J24Tu3OPABL6l2C4eB52FUp6te
+9YE6c89qR1HEGCF1U022P4qDAme5tTAFXCiO8uDD9CAZ0GGvC9q3lEDYoArR3lOCvI1ErFvbCK42Yb6e4D9X8hEAwH
+18U7KbAUQ3gGBAk2LiFeDF3M3W0FljEFnD9h731AniC1z0xkB8m0nDFvw5SR9295Q0DDs36aD5vEbT6pA4uR3VuCSg
+1aI8s8A4J0GNE56BvR7UtFWS9Sm4gv4if0KEEaS33TDag7zO2FK83hATP29f5MxB8h25J3Ob9QaCzJ3IT6w4CEj2rs
+4joEf4Fsp8yLE7FEUeFVgFG36ap4Mk3XNCCi6sG0mV5spEoX12RB4AD41CsR74GFNE1dM3He0mY1NuEWSDcHAhp1qT
+EJMF06ELOCqj6Yy0SS8f5EZk3QeDvI8wQ0NMBYH7B4CzpD5bDWC6fzAgG6cZEHq30Y6cRAYK8ybBTjAcv3ac0Ay8ko
+AmXCMKGF75yt4IC1oFElaF2o69s99C6TZ3xZ26pAzi1G5Cpr6RrAiCAJM2Q94Od44E59HAvB9TVAtA8ju6qY5iWCUr
+4Fq7Lx2PW3YWBX15QB9gk9a0FSB3Hr0HgEp66rw0SmFJx7SxGNqD2t0RV8FY9Uw6g93Tk2kq1K49BnDHk2PO7BPAjC
+2Qf94e3DvF5298w0Qv9JgE9qCSj3Fs5pK0S44nx8Vq73f0om0p17sP4X69u4Cfp2Wx8N1Bmh6DG4w4ABwByb618GKn
+9N27UU8dk3VvGG55mS1278ufCxE94Y5g82c65MQB2sCl8Fyy0ZmCYe57WDKh3x64K9FfmF3y8jW8Tm4rDB468Vy3pC
+DRLBNd7J5GFa0lYAhR3vw4lkFIc77k7LL9fSDi2BWmFh8DZN1FdBN5DcOAP6GGX1kg2JsC6g5ouB8D5M48M56Qs3Mr
+1pIBqTFZv0pL59f8SyBZK4UeCrg9p78fcFSs1sz4I9F6R5Hg9dICqY5m27kb0oNFJe02Q1C01TnBmdED48Ur0ma9D2
+30TC1QEax5YR4TtBbeACV50GDR90uqBBU09xDQi2q58uT3ug3W27Wo55G80v3OB05k10vEpH9Op613B4t1np1l3G6l
+8qq2ByG2v3vX0FrFsT9HMCYkCoH604ChT6Ie45dFOiCSK79DAwDCOCBpJ8aJ3GzCj4FkkEAK2dh7fo15ID07FOC1NV
+4Fp5co8AT5ob5U08hC5qdFlq1u3FdZ2iF1tJE7YCbhBO20Il5Vc3ab9rkAj38XQ12n9Gw6xjGJaEUPEg4FjJAfGEgK
+86KDhI8zFCeK99q9NuEb60KqC9W1C16Vx1q7B8Q7wZ9DICUN2TN4mZ0fC24GEzU329EelAfOBtH7Z4G8g9GzEIe5Ip
+1aD07Q8bhDAUA3P2j56FzCGK8ay3dlDqz4EY9rjD592So44hCrT2LGEge96lC7yC568xe9bH3Hb4gM4ry3SEBCg2cK
+1caBza1eyFdv8rhC6P5JXF8xDgS6dv1lY8DfD39BOq30c4OO9FN1c54x0CWrDJi6DW01E0Gq26iEAu9gC3eT2aWFXs
+9s19nY80F1XQGBG37aEhb8ocDLU01MEKs0Uc135CZP3cG6Ux8Sd7JEEGu2xd6Qi6vw4up2DHD4H2iJ9rG1f09wbAOs
+3Mn54u3CODVs1VsDhB3Kb5W75fWBoW53C6OmFrkC87EJY1zpAeN0tS3ag2EE4CG9pE5EM1wZBDl73z0v50LcAJFCyH
+61W0zW62FBjdF0423OFLmCqI5Vt15y9g93vqFu8CxtF4D4fT7hpG98Ej4EMi3yP6IhFAFEdYBZ46p98KR2a55qAEyG
+07U8XvC3cCxA8qUG3iCDK3vLCEyADl8xX55X5MjBxJAhBC1L2Md1qQFg46tt4qy0TP4WT6Mx57d4KoFPy3uS2GZDpc
+3eY5iNElz3gCGNmExPDmL3Ks2AhC6G1jnBJY4Is3nBCmQBpT2Jy7Lu0t47VYAAA7MWCSfFyeAnpDHrB6h29RADQ1kD
+Dfr8ABC3SFvz5fG0Fj3UHCyzAI6DUE50f3Ee1Ai4XD7ah4U69LK90MFTb59kAAa90GDTp6bmASF50Z4rpGFZFFz3hm
+B5GGAQ1dE2KPBjZFnX4Y145V6i03jZ5pQDGw25r2Cq54ICyU7qpFfV0eoB4H1gLBFHGM5ALg3xbCy0ARRBUVAtt1EY
+DfqDThFYk2eeA569gF1swD6l5S3G0B1AFEMy2hv4PHBTHBoS1o05J90C8ALQ8SNAq2EEFBRv4Gg7f927F2925zK4dq
+0726R00C68k9A6k4XM2EL68J9mfG9S75aBUy4BzELnFt85Ch7jW9QwFZy1hnCn24cM0Yt3wR0ZOFfk8HoAzd8DxDT2
+9CfA9717p0osDWvEOKGLu3QbEqUCyS68gANA2lvERr07PFMT4DODRvGCRG6W6PD36N7237NU4Rx3hPCa09wC0X15E2
+DoI2DZ2bq0Ug89UC0lB0v35I5hiDbv4HdEHiADE3CH8qm6dqFKB8kPFFE62bAI1Ex0DUI9kpAXm3my7hQCLU5BX4e7
+7604N8B597JF8oIChaEDhDML9vf6ON8WJ172D1h1pz1gAEv7DE12Rr4Bx8fLASp8OkE1L4TW3fK5xpBFu3lNDY215T
+EFQ7yV51BB4U84Z7lzBP64518dE801FkYA1sCFjBLc4sp65I8g5CSU3XR1zRFsXARD2tG99WCho5wuFGB1nFEzzF2x
+15B0663jYDeNA9a40n9up7uo8wm6HNBhd4xlAZI8W83tjFGo2XZ5KhEGB9Ie8jrBCK2I00gEE9iFIuA8I8lc6Ti2gM
+7Py6rd8eU1QS4eh9sP3SR4Wl0LM4ex3Qv0Ru8sb0lw23pEI6A6PBOn9ES2oW28s8yc15X612CGe70N4w9GHe9B639K
+D0r0P1FsQ7gC6Oj4dV6H98ri9boEE57Ak7da1od9Hl8Ee5jy9DC9Cx0ntBaH2sh0Kg88OBmyByf7jX70q5JdDHS1ml
+DQhAp5AF8CPJ57P51d4nf3rhD74888DJTASdBco4H0DuA6GN4xoAoH2Ej3uaD7c9wmACDAsb0lhFto94Z9tH6cyChl
+C7z2VO1O04ctBRrDNG8mp4ke4c20wx83T0brDCf5FKEAJAEABgPDdE9hkA048ND4RSAxQFP76Ix8kGBHh17B19u3Rl
+D753lo2eUCbv661AFu7PFAly2ZJ1885pm2PZ5mP8s6AdHFDv7hb6omFu4EIVBlo6NHClX251BUMDA1EwCEKw9d94hH
+7DTFAD8cYDJE1E4GBdAay54n7ooFAM1aC7DSCkA1P7FtM3wWF4jA7K3OSAXQ1h80pH73I7RNBI020EBE16mdEvW7GY
+6MoDp0F1g9JY1IVCbkF361Ll9OHE2g0V94xU4IG1Dc0n92wPGIQ3wa58a42O2IV8ltAt34yu3JF0pw7sfF2z5rK7Kc
+9UPFiF4B9ENW4xm4uY8WZ8nfDC66SU3661My0i84WL2hy2RODpfFMzEGk6hb5Yp7AE9OI7i0BGPBCUElBDi10Iq0J4
+A3T0CZ5L2FNGAhv6Y8DkG9rE9sL0W44gF4H8G2xForFAR39MFfEDv440mAZkFnhDyLErM9cA30542P5AtGAl7Q1EID
+5kFBv6EPV1SD9VG3VkFBR13OFap3Fc8Fk6Oe4Li4JV4zkDABB8F4Rw7ACBJa2gi18S6Nc1bYDeMF5T4ejFlfCnBEOX
+5dA9K6AUr63sBgs5vsADH4Px0bFAyz2J3Fqz2ok8G04Ae8Nt6cE75i5SYDQDBY771453z7dw7s26B87mCCEt2bL1ep
+B8pCw73cf6qL9QvDvyAxm3P40ySFpi48m7EiChgCfH4F69Q0FOe48JDd25HB5dw2rh9jr6kGAT3FqZ8iTE8E3McFij
+CiCB9D0cX6VYAgU42MBDQEAR5FE91v0tI2s59EW1IYAUe3YkAHmAWv6mw5505GV0MCEDy0ooCtIAWc1976kB5gkAgk
+D6A4LH4pyCSE4ba4n473t6iKD3v6oY5S25C56T6EbBERy0uo5On1bE0Lq8JZ43t7SU40F34z1FvGNK7P10UI9YHG2K
+28G9SpCGHCai8c38AXBun42L4234SyEfU3ix4I611b5Lc6xcDN2ARn6Th4AP8ga6pb5cxGErAne0nOBJk1H23Vr5q8
+FZiEwA4InDAWBRH6wq61z7a50fgA9nCPi4TN3Y82gA8RZ36h0qh1Wo9MVB2z965Fa70Z9AqKFk25KpBSS9JvFYo6ym
+CdsACk6rg98o7pa5645F01VuBRo7AYG9NDka6MHFAg2ldDvF0siBw11eL4k81MC8gNA3m2r55euBpq3ToFSYDaXEcb
+7WUACMBVgB2k6yyEYh8VjEGiE6P0XC8Db5R93UM25AEL7EjY2LXBG99LVDBcCy90XN6h5BWb6hq4lQ58iBOW7N9CTb
+3h56Dd4DE2351x1GLe5H0GJjAfZ87B6zp7Si5xK7iqAZ28oZ3A94WAFCR5KmBn9BWNFOQ3Lz5H392e3qwEoMDY67ql
+E10Enc1xq3vKEux2svFNH2Vz1zK658BUN3buDKI5x469b5IOEM58638By1DwARY1FqCjY6m68CA7p53s7C0F0My6Ra
+DDD7PS63O7wY32JG0NEz06SlANT11o3bV4muBgM1JsANRBKC5uP2JqAnJBk509S1aSARd2fiDG97kSF912jp6pV8bu
+Cq31lp5tN8KfASPACP2aP7yZ6l4Fjs2QvAAvG5k61ZBm02No9GN2t92VLBpN83Y9gS5DD88RCdJ7UH8cG1eF35vFdS
+56hFRUEvk7pf2xU1zPB0ACoJ7Dl9yZGJi8eQBFTAwZ7hB9yRCt3A2d9PX8dSCNjDGy1SN3Qf98915x6d99UiC3qEIY
+GD3FTq8si0WuAbv5sV8O72WYFIMCpx62VCbQ4R861MD8vDaG6E53bYBApB5K5nDETx4AYEq88i89JqBfF4Nw5H1BFA
+EEw4JT3EGAiz7Z71i23xI4UJFXCFWB1Xi1p86KF2jhFl6CKS2TM5RWDwu33BBx22sF0qS0R7EgR4HgFy68qaEAmD5h
+CiM2Wh5pSBID7zB9jVEoS8io9gcEog6jxDHmC0k3Dg5b12tU1zhBctD1tDpA0DP7226eLCqr2BN6Lo6my911Ac10lB
+EqZD058PdAsaE3K5Yy9t1BvZBVNE3N6qw7bXGL2ELa3n37OxEYy6yTEHHD35DvOFKC4cB7YZ15K9XMG1nAZc5na6Hk
+FLO4ZG85D9duFHR5KUBuuAtxCdL9ML01L4bxEed0Q69KP2dx0GKALJ1uEGFi6hkDBv5Of4jNG1LCr8Csg9DF3JH3db
+1gz1bj6QT7ME3FW60b3dqAll5iu5b5AxsDhb8GxBJ4CTI0qOA5S6CN7YC5YrCOj2cUC1q9ni35D7N1ADCFv64ghADY
+3eo3Xx9BI2SfANr38C5pZ1WL8Fh7Ao60lD3qCaS24zEntBaQBIH1c49DTAoy3wL4YCDSQAf40zZ7H32BGA0Y4555hA
+1GxB4I3kzEewFfBEdnFsP07EEzs9Kv9fH8ml4KBEM45w90WQFAADt2AmPA8X2AV0o7E5VG5nD2J95c19L79K4km9oK
+0n18q1BgW1rEAyrDdu3SS7IQ3QNANo152EJ8Dah4bwEtq1Jk5QuDt04m95fFCRE7g4FG7Fj6Ex43DsBaV1vH2GP7vo
+8I53OaAhi8lhD1a74CBFh6gk2dBAGB4EWEjO0ik9uw3bx94JEAI0kIEiA1JuDNx0T5BNBBMY56eA4dEJT46A47W6at
+FJ9GDe2Us5ATDfC4bkF6j3r1BEA1qMC0P8rJD6V4459jL59v4KZ6mRAPHE3V1Tr9S7B9lAIv7wn6M1ByO9q51zl2yY
+3uZB9H6Ya84W97N1i7AmyEqGBvS5o14mkEDrE4m2qG8snDbwBPt7N4B5U746E8z2uo55m2bm1zcDab8sG8TK30I6j2
+9sF7NHEvt18TEeEDBV7B3GNp0rw9iOE1e4uM5qGE50ADL34UC3ABSU0PECBKB5C14K9MA9SZCEm0Qu4TD3OkD51Fyh
+Enp5HmG3E1NZ1vc4Kb2rbD3r9vl2GD7ok5pX8dX8XJ8Bo5O8DR06x5CGw4PQF3o0zgC7J4pOBfr3dn9SW5M70LxCeT
+8CK3OZCS61BPDqI2Lc9iJARt49fC6EC7273GBk778fBRK3qP0bCFmEC593LYB4k3OECvF2ZS5alBfhDxB21zErv9iX
+A6YBGwFf86sWCoD3bK5jMBcJDay4Uk5JmCUjDH05u16Yx8zDBks1aoArd2bi38199TFYd7io5dlBpQ52X2BWGHHDP7
+6TfDch8yy9qjFWA7EYBwp37E8Ka7tq18a0tm48L5EJEOiEWM0MqFSr1cX6ob11d0VT4tOCX86Vs3jKF995Gd1sI0vN
+5aF0TA8BkFN877v1MfEzD7ZH4pkCmAG9z5JEERWBPpEFHApWGLk3JW1awAKECyKAl88COBfy1OH9S59fK9Fm1rAEfh
+ECN85F3O7DXk8sN1Ka7DI8Iv15n2TV3WsFDxBODAdh7IH4SnBzcBr729X4c33opAy9Beq8qx1Zc6fxEmfFVX05L9xH
+6cCFgX1Az1jT5AYB2w3KPDZvAZa13J1EkFIC6UZAXL6Xc0lR1dn42w7xW56Q0v21Ol6JHEdT4tE0XlAwB6494iFFio
+CGN2YK6pXB2D005EyBCcwEymDjE0O72b12KH08I6KhFwFCbf6K1EUq0rqFlaB7b2UeEpTEwHBEbCIYDq30ENDRZ46x
+B902Bg4A985UES05Ru3FC4yT7j90me3v2EMfET14FZ1ZT084FJPFRM2ma80oCs0476G7rASU44m3Z443e1pp2XmDwh
+0RZ90OF66EXN4eX0z04UUD8F39yFMb3Fl4ZT9a6DWIEaD6FRDVJAIa51gFkU0X04KP85n9U19di5bk3q34aLBzG4rH
+DfcEwo0N26w76UsCqS2MZCom7bIBMyFse0vpBjy9ydBlHCso2qe6Y220K2GMEgM2bZ82oGCw753115Bi9FQ515k8VT
+2mJ4zx55bCV81Bz8pB6BXEsIB8CGBM1y5FhdElsD14BzRCt56EZGBE36A0bq3IHAH6ABQ3gj2q76jjAkQD4y0CS6Ml
+7Tb0gI5Lh5m5Fqq4b31ii7n13je5SM4bo23i5AVCU50pn8iK0ZnDMwCEU9JNByH0H23O28802MR6Rt5oj7N3Eyw7NJ
+FBhFL42Ie1Pv8PZB2Y6iBAdQ4zNCiR78y9nlFZPBph7r4AYnByk0eMBwt5uWCfN8JcAzcDaMFmDGL9CveDdk5GW6Ma
+73i6Gg3Jf0KSBHe1Pb6BV6fB78cFETARcAgw93MCgNBLXGNLEUBDZI46lEzM4mn0eI1ZJEXHBlJGAyEdW6Ym9wP08V
+BJJ8gJFzT5lx9S2Avz1Cj6bL9D17Eh3YU6qrDdr9zL1f8DB2EkE80nD6x5Fc70aBD1ACT8OxD9R9AIFBi2Kn8AH1Df
+5lR9Ug8c96Sa9K88Ra8W64Hi23uG4K4IQ1L06v5FH46F27stAng9Oc4Go5r15Pa3OeE6B3SdE7C5lMB2U2S77z53jn
+80bBN42Rm6Zt5dLBqe5PQFEO1eJ9i88ZK3WI7Ip6JYA6i3Au8ecAYu9PQ1tc1IbDxWFXW0w82oUEzq4Cw9ez24K2Hy
+4J1AK41mJAyQEyx4Ns0SQBkrDqsFEB2OQBLO3h67cp9qV02t5aC6GACmfCykF6PDuWBWE2ayFvU1HV4UQ5WY53H1XD
+FHk9040Br3oP8It5ts5aj2mKE8K282FbnEKC4dQB4X0wH6Ei6ggDVQ2j78DrCU15G9AJUBla0AO74zF7AETRCsb4On
+BDxDbT3eb9PRFN5Eos6SC0kPFkQFdk1bB8877sR3Fg6E2AQx1C6G1i6jhF3O1hKF3D9AC5d3AuA7ozABo1e23LL4rO
+28cDFLFW6Dp12of8G8E7c9FM2NX7pkFdH4E0Dew3j8DS8BeGCeDCsSApEEsp9bL8IeA65EOpE2j1rK4yRCUs0qK2xx
+30VAMp1Oc4j7BG6DWlDnS3t9Fe13Jw2N3Ewl7059j0GJV7PTAXD3qr4ih7N87Sg8IL2ID5f2AxPDh39ZNBNz6Lf0rp
+BtR7jgFZa40S38V1vvB83Ezp4CKAg21s6EzX3Gg7SLCM7B4895N9iq3vjBIn5e51Mj9gz04nG7BDrj9jxD8uDNXBq0
+AQz9fD2Lm2Hw4NJ4El8gi5UYAPf3OuFO803G6p38tF9yo55P9SuFom6FA0kHDvv9G32Ac2T78ebDcTDqn1PrF9sAEt
+0tx1uABUCBC292pBfQEiE6ynBhHDup5j77Vi1gW1FV5Ya34L1qF69RBpo0OvB0I3vI3JO3ji9t92Pq8iz1vJ5hUDuy
+F0KERaFED7NCBZQFrV9qd9dwF3z6d36q5DXd9c81rzBv44La4T08wu8YYB2J5sj85Y04CFCTB3b03HBLJCMB7rE2wy
+8XN44f22c1gOFQw79JETp4Ee1Ut9A7DqB72y0ID3RyCWs1H3AAp1tk5MWDrtBLp6L3AkO2p39ISBZk1N453VBbg1mN
+EbF4UT80PBlL04LEUV6E67FYAjK2ar8bw6kwGGd8p4EtX4FE8G1Fg19xK3F23PaAFi9ZABa1EU2Fz9FxA9zc5AxF9h
+82y1S79ch00UAQHBml0ls20f4Rp82R5eV8RLEBW4vn2zhCl14ky8SK3PR5njFO06SdEr3C4kF1L8rK8LK619204A5z
+1Np1H75u42cI89HE3811eCS12BbBXO9q76Dz3kB5kq1H52bWB8S8zEEU70Ua3pyCUaAa4AXu01V3bt5uN2pL4S68hw
+3uRBvFFdC8teCDw4Jq83P82EF9xEdd8Z35W90oID3O5kf8gX56lG171v4EyCBh575cBwMAOaGCSCgYDGr8NKEbUCnR
+7zl7IZ9dF4sK5kO0AB1vm1ClCJt31ZADsAlm8YTEoA56IF5k3qj2SRDjF9lm6kd8nR8vBAg5C5HFx84pR1Rl41T7Q3
+6vnG7xDzj0Qs6oNDlc4Z11KJFIGAoDDWMFm1FGn0eK9Xf9UB1OqBYc6pQE2K6Ul2H3Fkp3LjEyr48a44B8g8AKMEcM
+9tO0PiEhG0q0EVTB5jFXiEbf99t9me5026PL7D1DpYCdYDc82Cb5Zz9nZ6F06EcAspDuhF4oFR8AJC876ATNFOv0Gm
+3QW6xR29TAtwC6N7UI7oA0A96VM5086ihDGV2O87U955cC4KC146D6Bfs5z11XX23L7CY05SCRC4aX4CV8Er4Mm1eV
+An13KB1Z772D4QwEIg2ly9CTCTXFv2GCm1atBKvFUSBm85RsCRjBXP5cO8kY8QcEWW3GI20e3VCFAsBTDAcO0u787I
+1WS6fs0Aq5UxDsjDr8CuYFjZ5Kq90xG5OFcV3DTAuXALVB6fBcc4GnBUG5Ku3CFAhl69Q4h67x4ELG1ihAHs3jbGO9
+Bvg25q9uo69GG9DCtGELb2VpBOSDX83INCT33Ql2up29g2ijBPo7Qj7td0pDDXF7Xr4ir5fS5h4DhR8NLEsO9izGJq
+96g2Qq3Hg6zMBhpADIBSx6L40FB0Z8Dp73M14GMDee3an7J839c9nj81V7jm4II11FAyt67UCdtFFB9m6BXB2bu9rX
+CZp03nCPaCnd4GB8IaFPhAGV9kiECD3UxEQK3qB3tSDItFhRAbR55hEw2DDUEij8NXG1ZFhi3vg2jGAMwFAvBe18UI
+7EK2InGKf28e7Gb6uI5kC2iLESHESg1d8DnhAQK5Rk4TB5fCFQoEd9DDr1cM0zc6RP7NT2vV6LG93w6X58dg1jF6SE
+2AF0W2CIECMe6ooBZp7aoAVBEiu5sMF3b3Og9d31KH1Nm8sa76w7cB5MX2eP78T9YfCnO5bsF2m8fI5q27yHFAGFeX
+CFy9gHD3y7nY3vi2WX0le0dvEzG1cI5ZmAh7C5Q6wKDL16em0P62cQ24XBGN4Aa9RbAAd8P3DzHD7E1U2FXVGEi4eH
+6SL0EC57k4XS83N2FW3nJFKi3Y46pCAAD7s9DLw0XbDzs4uU93XDlP0QC6Un718GHYGIkCZC45B0ku7UT3mXC9s0ZG
+ChZB4pE9sBrP8H22PK2RV4M2C5Z8kC6Lc0qk2zzArC9WmE0YBzuETj1hk3P2ARO4Jh9HT5uq010AsAE9x9X19dk1xn
+AG1EH70DB0jC6tE3we6iyEih7FxE3pBfY0KKD174d3BFsDBz63b0JRDukGIhCi6AGx92B3ex2IU8Gq1Uw9iVGJN71z
+DRO1rw7pV7rV6MP3SP1RZ288Bg9BVc1pn7YV08WCVs6m40hc89CF1e0UXArb2bxFWKEUt6NB8LA3e3GHGClL6U0A3H
+3UTDKR9e13Sa1BJB632dHEc53Ek5kpDdbAAq23o9YB4PtBj88ZOFKA5jG13D9m8CVu6MyFQb7K79xiAJxCM10QcBEM
+G8d4FT3Ec8Kj2ww75p8LhGN4EAG2vj0Rz0qMCkbCdC3oZA9d1Vf5RBF7mEul6xa1XY1kG7l93T5Ff077u6LI6u35oi
+DzNADD0cmAhm1myC1gBbNCDI2uB8gx3jjERVA8KBMRDqh9Xd9yfFnsE1I5ot3bMFH16cL3ZY0wy36C3ONACU9CI297
+7479iF5l45Wl0YuAlZAT51AP5qI92nEXh7jC1NLDNz1tH0njF7g8Lu7IfBha2KEDnG0bJCXVCg4AaiAeZ1Zt2Lg3ki
+5IG53e1ei5mV81y8Nj1bo9fhDx43DfCEk1dk10I2z44H4FlRBZn6uXABF2b4CVV6ut338AF9BRkCJi7UjG2y3oc9B9
+Ef03JD1Uc5cJ2sgDySAbe0DfFm9FgcD2CCAN2ScFj18Ew1eSFJg6sFAggBda7ZYCCp5j15SL3BhD2r9iN2ITBKIBHl
+9A94QaDIIABC5yU6Kb21s0ES1XA6of2l54oK4a63aA5O3C3C5atCY67ZGG9sAhg1BO63f0CCB8s5l77SD5BTAStDBg
+Bfe9yM281G9L2qPDxR16T6zVA1l6ziF4A7y49Wb2NLEYZBaEGD004Z9vm7aE7gv953Emr6lQ7Je1M1BzK5Y53AaCjZ
+4pG6Q773rFPp8VF3iK2GFDb34Qo0AfB445SGF1fEZi9HI31RCyT6H87YkAT865JB7SDvsEF20FwC9b8X40xA7Er9sT
+DOYDrqCpj9cp7shAwK3TT5rm73g4w24jyEbcDvf8ON1nsFyLC2d3IoAjz7Bd5oL3iL8o3CjW6wU2vyA802HeCekAdi
+AQ51cdCYj6xWBAJ9Hy7VF5vG9eUAFW1ND2Wi0cRBWs24ZEfYFeqBsK0XF1g4A0O7CMDlX3oeDzUEw3Anx3L8GMoC61
+GLKAoN30dE7e65NBox64OBl0DlxEDPCdD1Mu2lzGFLEbV7FQFHa9hWCex82kAQTCeI0UZ0Q41IdEpE0ag1TEE889aN
+08sAhX7AL18w5860Nd2BA3BjFNRDcU55iGNh6j159qA251yB5ciFDrBvVFbj1BwEyP9Zo2ux1R1E957yU0fL3IM8Vh
+1vUEw06cd8A63kS6WR9wc91cDA86yaCU85YY6TS8Md3Kq4fh12h2gI2Qz7DrFW9F2jEZ49nB3H78i4BhIEeKFRNEkG
+DeD5dK4vF8Kl7lq5a02zH0JI4f4EIM3wc92E3yV2YZGEz3pV7ZE1nbFWx4iJDNO2dKF6E32U0PW9o1Agl7L47BiFlT
+6yzFlFECwEq7Akg088BmJ8fK3yS1JZ4Eh5NA8yA0ia9EC4UNDYwASAD0HDqqC89GBXA7FCzb7rHEAfDkI94uFsEElP
+8b755W2kzF8RBEqC5T2C32HkBh490eBUz8BwEdQ4tp40C51q6mf7iRAN28CC3936tAEaY0q59b24W4DUgDP3BBQ0WT
+9Ut7R73jC9QHFUG8E203vB0p6hVAfeAPdExMBFz4u23mW1zt3lF9LF7tx3OIG0l4q8Am44rqEuPFLf8mb6yG5h5DGt
+40lCzzCFiE1Q1fH1Vb07OCk98wl7m8DRT2KG5X0EfH6bw5Y21brCzNBfg7OPBZv5A5CuT9P0D4Y6ZH78112K8re5yf
+AxtAFxCTnBzECUx2UY89wCXK4u702wBCr7TW7La8YO9zoCfv6VG6OvCLR9D4G9aDOvBffDsO6UN07sCagAcE3BRCXX
+5U28ez5sY4L43H86yp6s2AvM3AC7oC9Ib6XUEko4eL7ywElX8Z9Al9B1u8p15m171a4fl7118R4355FGYAzM4JI7lk
+D9KEVF2zA8ytDKN6gVEkS9px9MFDXe00dCUCA549CjEyv2aXEvu7LQ9g79Uh2cr5dDBlq36GDc1AAx9cU7jvF3j20h
+8Wu7Yz6q8F7ZA1F0uT3iN31hCGWD3lAbG3uj43FCuZFk42hN3Ru7HfByjAvN9Xg0MhFfD9mW0wC5baBq60976GG6jb
+AJD1Ji1jH1W39qO3jy0GP2pA52N2OIA39Blk8Pr2te6JQ3Tz6VhDlY8EC4qODI7G1f73U9p5FaM7RS0G58veE2k9Nt
+AKpDjB7DaCBuEyT4bcDM18y79UIFHHA5E7XR8pZ6ay6TLDh5Cb89Ma9bPGMg0PJBa641aFhS7ax1vX13n5hXEwe5Tz
+8MAAeYDVa3uME6qGBu7dc1ETBbAB4s2wgA403px14JF2CENH5M94ZtDn5Cy45gB3hXECjC4i4tUFLw7kR3MG2Bt1nt
+6xIAVV62a3l7E4KB3250iBrq3AFBpC4Ag7rm94tCK73WvFcP3pkFX24Ch4BuCdU2Xb1o2ApU5w39fJ4XtBsV0I94kJ
+8pwDq71YPC7p3lmDJS4DG9Tm79nCtY4MxFRF5X3DsK0Ht0dP0jeEJnGJ1AkV21w5A3BLwCoxAPz9rx89VDmC6u8851
+5BMBtECxi8vQ4LB1Yz1Sb9Yu3Bf4Ho8tr3Z049hBZA2Ju6BaEKzDP668H1p29Mj8UVFfs5ID6kx9dL72eFsB1z2FDy
+BVF0aA0z75hTAUdB6oDapBPs6FwFZC3CTFsC3Wu5iy0zqBLS6Br6KxDHzEJH42b6xQ2u9ADR1Ea0BkF3x3GXCPyBTy
+AVC1xP45jErV04A2QJ3HA1ZX9zQ6Ax2WkFI3CqCDfZ1qsCZl5E40yt480AM63LnCMn7EOD7Y5mtDgJB0j8LO7QuF6n
+CdRCc66RI2CTDcd3UQ3V48z75Vs9py6q79GO6IH1CJC8622y9Ev6rSCkj2OHB9QFD03NqFaU59l0tt2pvBuw0QK044
+AmoARh3ioBkK75P7rS7OUGCa4ZdEBnDIi61SDxV9qM72LD8a5jE6Rg9bj2WOBx6FpABzD5mY37WAO23pD0yj9Js1x4
+DHfFgE9gG1EQ5B88Ed6EM9L7AhW2HR2vK61y7J793WETG6V4CrK0vn1oK1Tz78x8eS81W6mv7oK6o6CII3DU9oIEEW
+CcS29oAifFoT9X02oO5blD5gCTq2yM1MsA9c3Ri3js6xMAcb4jx5DMEYQFiU0PGA43ENIBfw2XUB0R1KxC5lCCd2NG
+DEY84q2MxFuvBd81xW4BfBAS4YaE6rG6DEkP2FN9OS4dF3T20Qw5rb37tE9FEH52vpCC3EYpBnlFuUEykAA1AFICBv
+Brc1NT52v51O8BcDHnDx65MFFGD8Q4ASj2Vh8orBCV1Uq8yg6p6DAZ8Zy1Wr4ns34V45TDtC7S21oW0FqD827W3EqY
+EMP2kK8CW1i69eDG7TDB67V066D5Dv6S8FXT6jrFxzCM66WW8VzGAdFQ36EN3gO46b244E8A6EP33g0ak5BD71i9KT
+2nC1CDFMJEvAAkk527FDkFbS8mq60U5DE3oFAZCBT0EAYBnE4CB5TEFJY70A1s70uK6zz1v30Ak3TnEPBB6R4tz5HL
+6MR12G89nCrW6sA90z9QLBS948pBd768jE1UB3L4WK7wzBJjEuIAPCA7n7i97jBD4RCXRAICG9I2v3BoTCth6R33RI
+DrICyE3rQ1W20uL72MCkv6gDENc3Hc3N8CC0EoY5mc5LIEbsD1f4nqEd452P7UpB7A0acET92oS97a15H7gQ8Pe6VA
+4GT1hMFDw9gl1KqC1VA3E5Ti4aU0qE1cK2FR55s2BHGIA39R3SM0rK8Wd2BVFoq51H3D9AaXBYd02h78n7eYDhu7qY
+BhAAFV0pPG5Z4qU0LdDoY1tg0Gn42dB6kBUZ1TgAzG3zLEd38J72OJB2S7xIFMd0C1BC02Pt2fu0YBEV2ANV53c0pU
+FREBLZ7MeGME5ToBHW2fKACI8lJ3xp314AvkEWK3Y02bG9vq3uDDOuCDW9dq2bOF4p7Cx8ELBeQ0AYEfXG1c5RGF3m
+8zB4ELCUM03D0QJFOO4xj9sA2fl9qI0QD0KJ6aMDuoEm2EZW5YdCEO3ikEheAbrB8X7biBVV79QCXwAaT7286FX05J
+5mf72wCTf1HGDtoByl7d53l341qDxc7RAD92Bn213L2npGLmEaHG5gFco0M32uS8YdDu38aaAa6AgBCqLEqlCKE4id
+G0K3daDlvDOeFL53ljFKM9Af5DK5Qo1ai3VNAyu6yo6aOAiaC7nE4b0Sw9Ag6Lm6W60l86o7FcX3IC3l92RqGA76s7
+5q47i6C7V45QEIdBUp2JP0w19zzDNwAIA4Bj9WZ6AzBPW7QSF0C60O8PCFoW3hfA9uDt1Dk605V1OkFVl2Si4trFcu
+7op1Zx3iVDz180736Q9DO7qF1ME3J91cgAB89V2Bl30hoBKYCCXD7n4g12Q79K9GEZEgUFbM3hg5QwCxM7Cc7qBEUk
+CAU9vg3aH9S434D8VREHgFUL0xDCpBF8U2iT5djFcSE0T9gTCwzCNr6wHD7uCh0ChJ4Be0RP0sw4rc4XC1jlAnL8JI
+1pG99QG4A8eM9v6BkBCfSG7iCj80ah917AGWE469a86jB6sPF8TDrTE7RFTy5LEFNmFjMDSYDH54jcDVVD0p5Nb2yC
+EMLFPn9ok2o85Ap9UU6VX91uDwEDkkFSh2oZ2ZRCEY2mL9yO1WFBXx9ZB1JhDv96SF3VFCiK2yLFBY9IY3R750780f
+C2h6QC10S88Z2l4FQQ21uBXtEK9DxP5v9CoZ7gn1iACvP4xT4ztFv4Cp987y9erC5U3G56EI1jGFWpCJA5EV3REALN
+BHu4XL04fErk0AXGKaDkeFhk3qg5inE9HFmSFIz0gXCrR0YgBVZ89hAzu3Hj9I8D6r2W4Eco3zhEkq2ni1cyEKB6hR
+56684bDLo7OR5xLAIgF4l9pcBNt3ceFrPD9A3RM5TJDh1D0nD31F5y0YxBwy7u49km7UiCDA1oZA9f6iq4ESERk6bb
+G7Y8UBDsSCjzBhg1ve7Ar6Hr87E2tICiT6Ee7ypBr67U488V8McCywDO49Du2C42Ay641FG231i7h4E2z8uX2NK914
+90r61v7563WQ3aM01y1iHFsMEGyFPl6an7h369kB9cBQDDEb9QPA5GBoPFAo5WJ17t0qoDcwDgB6hoCta82Z1okG36
+EZp7NN0D49YUC1oDhU3DW16NB18Cl2DrFCfG8czBf79Vs9wMD11DgG9Dw6NM1iyA4b7Np4wUA1O1eK7MT69oF5lFzW
+7GNFVd3YuAjG3cvGARFmN9YNAQF2sQC7b2SM7PmCfi8ERA8L55HFwiAJT7VW09zDo72wB8Wr9xR5eU0xp7VVFwuDQj
+1yU6gI7HZ5VP3plAoZ56yF6r47H6dz8FZFYQ0387ZT2yq1DgEW8B9JEZX9ruBJ637eG942bcEps4xfBONCVi5SsCBh
+9tr9r93dY168F2y7l13JLDBW0jA2M223j5zE42Q2aC6WMDzW5Yk9M50Pa9hDDMJDUw1905jS3o4DNFA8NBFm4UG543
+FNP2Fb1Qu8GA9WC3Ez2Yc2JC5U3CfAAzK3AlDiRF116GhD1g3zN2pD5g40Uk5ThCcTDYSDmRDsE4m12br3Bp5nSAXf
+5eFE4ZFln06N4LW49q0VH95iBdk3xD9Yy1Zv1aBEV60bf1enAZo00eFvx6bB1yv1EqF2QDOnFA203O8Fd9AN5O6Bui
+1YN8ewDhaFlp4dzEmW9r21M0AuPBa41bt3mF2Ts6faApS9Xa1G89DaCCcDQf975DIVCEC2G3DQUACG12BFdTGBpBSE
+FFb19O2W57gi6XX9SCB3z3aC17k1gY6e6E6lBJe7emCfq0u82xJDjv45gF3Z1Kr0Iu2IwCn32Xj62XCVr8sQ9rW7RB
+7OEAZd7eSEjK5671XqBfj2pZ8GuAlxCJy4qu14WErsDfQ3k64eE2QO8950OZ11nCrj3nh0Ab0TC3T8Dny0NB6e79sJ
+5wlCYF3efEkjCSFDGS6QA0na2rg14DCyyBEt5cw7K3ATFAd55Qg9uA0vKFBX2Ki5lP6cm56g1DPG6V3UIDAQFtJDRR
+Dys4ki06fCaM2x32A75tb7MK2hMEq57eb19n7jaFRO1GDBzr2ch6hCD5G61REVNBsy3QU4QL0Z59IQBPbB1L6DxE1q
+9Kq2Lu4zjCVHDFqGBOFpyBuJFDA8WM8cI5rnD1P7mN8vS6rnBa02n8Ewn5OS7GVCEl8lx6oO5x09d69w42ZF1co5tC
+0e83Pp0i185y9NlCkp9NIDQm5DLAWF80J1rI09tE1D8JX6mDD0Y3vQFuB8Zw2DAEwxB30DM22XJ1Aj90pFFk8vnDSc
+Eo7AxqAw405rD5X3sf6f03Go0tA2mE915E87Acz4FK3uADEJBWy6nu9zK8R9EHA5XlAi527H2W9BTq7zp5un66xA3o
+3L23vf2sc5PCCmw2mu8nK3gXAVk3VZ9UF86p0IA5PqDtnB2MAvO5iMEezCZ9FXbCv7DNe8F34B6BA5ASv8c03WrCXW
+7hc8hDDhcDqN2twFRc5vY1S02cLDze7vO1SA1n9DK402YDNDA0jC4gDqi5wA2k35QxCKO95rEVP8O14VV0cF67wAaR
+2fXAzh3Yq5k13G08Qq4usGCs2cPGLw9jTGCKBAP4Hn5ElCdfD9N3lwAaK4YgB1GCBS6Eo7Pt8qHCWq7EWEZ3CVF6IC
+B7IClC7sbDBaDyQFDlDNI9KFDhpFkl88pAhKBDY4U93A04Q9EDiDwX1QQ2gf4htCmP4gH8Wg1JT5QA4Wd10x8yf7RK
+EhNBRJ0nYFgP42D76i7dQFA1Cpk6pw7CJ8cO0B6DWt7XW5RD8NTCnK29W9xUENQ5Ji7pDAuy7TX4D7Ets9rAEtB5Rp
+2mo9DK9moFvj3hOAoLE692IuD45B64CSX9lK388Arj6nL4bv8LZFGkDvB4IOEXXEO9CCe6B7ANx5zqC4VDx2CEw2su
+2QeAXC2LLBaX5YOB5XDn6FoEFJ1Bpx6l7GBa0wsFNLCUf53h9vW9N46pD8tq5pr1J07C0C088fhAQ00Ui2I22MW82O
+BTBCX92Al6fUAzR99a8tzF6I5oN51XDppAUv1k6DHGBtV3tc5Xw0iTAeVFWt6BJ7dpECY4bJ1Mc88rAY34UYAVhBVS
+3hhCLODl9DZYCAo26N1Sl4aE4d71bv7BpBEa5MgCy3BMB5aP2N0D7y6MICXD16J4lgF9UBcb2Yo5fu178910AToECR
+6o91mV8eD04c4Oq3Ay7AMBvt7V7Ay29YzDgNBNC5051j10SJ3eBAk1FPsA5x4fL9Eo76x1tm1fj5AE1VA6DE0cH7CI
+3BF8FJ7C570R8pdFrv1n19x113X3FB2NtCUtEPv9D53uF57v6dnAnhBce89rAoU8IAEl61DYEOVEj70gsEXMDAOAI5
+7uf5Wb9zv0CKBYM6gs8HJ5FeCBi16v4Lw4uq3SsG414z17vQD0UFDW5EEEuy5L455Y1oB8PJ9AqCqX8ZoB701Nl8dh
+Ag8Aiv3bsEwB1vq7MJ9w690wCJO0Y1E0V03wCRJCpy1ReBlP5xv95J3ij9qE5yQDvg2jo48yDPMETv78K4YoBw01kS
+9i912J6kX4K7APQA7e8y57rC9k40IBEhl5OA2AvEDS7e6DDxAoo80a1DL2Mr5PRDQY47710mE5c9lJ87m4OLAlJCIt
+FMv0u1EI93gBEl14egBG1Agq8oa2xA6AT3vBABs67V8FH44w6GD2DeGHgG467qrDi8CsL3Fj9hz8nuGFY3vz5ziCli
+14N3cWDnm12E1Hz7cS8EHDGnCtl5tFE4D57E9WV8Xa5Jl3bWEJDBYuEcx1dG5Vx1TP9z0EjM8osCSr1CZ03K1vt8tf
+Ey94XV2krDt8FAL4Lf0w0BU55Eq2T6DUH0RT9mE9m0G0u14yDlE9PMEmdCDC51w6j41sv9OJ1iD7eKCBM1dyBO83IY
+G8uBMu5r91lDAHdBiQCRLFdl24R0p49PA5cR8xP02X7tY9QWFph7Ok9FTCFf81s29i2GTEO346mCWQBNRGJtDDn54h
+EgVFoY1Jn3T423Q3V7E7MD2KDMkBOH2tN3IEFQ25PvAEI3ZoB54CvpFRq1jMF8B7d07LnAmbDGZExH8pO4wc3Mq1L8
+99RCZ63DI4471Z038kFb0Bz86sJFbB3GlFed66j5g95aOG9m48s9M61X36VwCPR7AQ1Fm9RIFXp5RT6w97as6u9ApP
+3Ie6D777JAMu9lZCGgAcP7yAG3L5TP5f03fAA1a7PZEs09lhFrT4noCWcDM0Fa67rD86r75q6iS1ZZ8U47GKDjDBrI
+4q2FvWCHw5af21xCO7B4q3k7EMWB9F34s0fBBEx0au6CDC397C19JwDiODgf24P88606Y4X76gn9GD2g21TsAaB54S
+CVpDuNFp77DJ5hmC6a5plEQ21e4ESV8Xt9nJ3kl9xs4e03PkG3C5ll6rs8NpCWF7fU8GMBM03mvCga36dGKxA8r3YX
+1JV5lpFeVBZ34wP8XxAFM5XgClv3Tr6BFClo4mJ8tP3BV5li1Wk5Kw2s6EuB3PFDqxB3AAUm8ouAI22T8Fcy2AxFuW
+87a3ho4hRFly2oACPNDUt9K2A2NDAM2BB6uiFczFLk37r0laFTiBdz4gX6Xr5eA35EEFe4zw00K6Jz3Il4M7Fr6CNJ
+7MR8ZJFeE7HX7b78OJ0PD5mlEl97JH4yP0Pe8kW7NhDEu7TgAhrC9C4hE1y26TPCf3CXfAW6FP59ZMCjd3TL0qmBhv
+GBnFRT6PS88n2dgE2Y65CFAY2kMFre3Pl28R3rNGMG4oC2G7DD6B9h0Cy1yaFUK2ReAr0EUw26UCfjERX0Oq1o58Lk
+FLY1rP9pAGGN6GF05W54MG286Yh90f2GJG0JE5T16982cBm19g877S7JsCOH0x38st95Z0zd9PfCULFvr2Pk0yI03a
+42N0plBKJ0WJ1Il1JI1clEhi5IgDq6B5l8ex1WpAbC2WZ5MN4QQ7R3Cv15bVAYI9KsB1U24J9x24NK9FAAKq6Cv6dI
+9kD1fb7sFAFz9Xn0Oy4PiEMKExT6ao5ygERq7m46BA2NyEVAC246MQB6a1I0CacABGFBr5Uk2TX4ds76J8G2EmM5p4
+1rvB8lArt7OWDPU98aGGsG9RAZMB6P5qx6s9EaeG5P8fz8nB9FWACF1QL8vvFFPFCa48tDpM2D06YE3B36Lp17AB5r
+6WA3ju3RBFKQAxk74e6hlCo12yA2ix9WSETXCp22Rj5PP8HH4FbFS69bV2no38v3JX3U6C118p9CeY7GZ31J89F3ty
+EhfFwLAJiAVl51LDfl1rBAhh4ZJ56u1etDYN2BYCX61TZ0Sx3hNBJZDyd69O5dpBZF1g2FjnFLaF168FLDlA25x0cr
+EWFB716X77k07LCCqV7cLFuJ8GY2rS62WAjwDuO1Kc2qKASgDs6FiKCBT3tbDbk64N8477P3Ee71s57UyBKs88I7vU
+DbQ95076e6HWAdu51y5YsG7O9YX9vzFWzE7g3te9J50KGAjb3iHC5pGHr7L24LGCUl0k05RKA8FBQQ3s937mGNd0a4
+CRs9ZaDucEhX6boAH44ZU1ckBYl8hi4Wy0Na0OH7ms4sJ2qq7sC9vZ2DCEyW0Fa4oa4UmBYS8Sk6TO84mCE95DSBcB
+6sq23Y6waAun3CwCipBs6CRO0zr2lH63SFus3bbFeo5RF5thEZBEkWBK35RS2fb6Ut5Fk35J2u4G8zAbn7joFiTEKr
+CBL3pz6J73dr2uk7cC2nMErZ7vC8NY8qh7042iQ0b5Atc7tNG7g5mmFLE7hH9bCCHk2Mg8Et3Hx7NOBdi39O5h88g2
+4HqD4g72U2lTAs514A4dZ2sa7J1DhGDL4DXw0L63FMGAm4QC70jCAHFDNEui4AUA7p8MG7VG83z0l30RiA0aDgKDi9
+1Yl5V9BEnGEMCpgBTT6U50FtAQ83oAC4C3ENGFB9uZ8AW4HD3711fr3cc4cvEn86sZAv4AIsC9e29dBt09mMAGr68F
+6ILFOsFPGCA5AR98ja9yXCz860PAsDBkD9kI9KQ8uc6QVDZG7GWCDL4yD0gJ9R39YdAjqB0JFpw06DDEp97X5EDC2z
+0qb6nd46NEg03uu81g40909A1WJ9410ShByW1of7C2BLz2Dd86l9B7BXm7Ym6EqABA8Fq4NmEbDDUB7K153ICPW7eP
+9Ep5D82X1CPc5bLDTL6QUCvEF7oBfv14c9ds5MJFa4BBkD7sBOvB1M0XL3qI8Dc3QC7Vw2yD4cC4MhE2xB9b7Ki3xl
+84sBSC8x14NR9XC9wH1gg86b6ik8VX5Z13915ZQBhc2Jh9sBB5m0qj9J93IA9dx3Qa9gX5dNCdc1QI9BaFtn6bhCkJ
+7Ll23ECfL1UB7UB7SVE1lCNRF903n87d723vAgN1Ri0KmB8GExL1jq1QU5HNDPl1LQ2RvA7X0Je6Me48l3O66pp0yy
+3PSGAC8d744eA0o4mgBFJBpa0Iv1hpDYk6el7pM21k99o1teD7HA7u5SB5c84GqC5f3hSDKW1jyCe7E968SiBo01it
+Cb98hL5zjFiY5G12gtG2lCQ7D3p01n0qe86S5HpG66EuC8l3EMh9c2AJ645f1P94tIFSC0J70ulBkM2KkD1O5T08TT
+8LWCbY5A995T1ZpEMx67X1kXEiWAcRCqJ98B7LTCej6or2pe2jO5Sn57a2uEAVM06z13NCKp7df9fo2fwF4I77dBjT
+7PE0U3CGG5UjAcF3Wt5oe1YR1jD3h9DNRCLeBSj6nUDuqC2l9NYDIO9lABWG73K0js9tB2LNE9gC5N8mQ8h4CPw8Py
+Ff172c0f611jCSO8wg5d54pq94U4MXGB0Ah54Z72vF8h5BOyEGmF8g9xGE3E00qBjv6pk78w5wsBFU7N2FZBCumDKo
+Dg1F1tDtdDov4vN8K19d4B728zj5B46UwDQFFvK52nG7XGKN8bl1hL43YFQk10y7dgEb1Aa00adFyA9bA4Y78JM1Q1
+ETN3M9EpA18YCCvBcm2TS3hy5L789d6XC65c3Do5PtFdJFU53MwAoz0Zl9VcCAX0kWC8i0Nk6Ja2Af0jW0E07Gm8Yv
+1d5A3UFAV74JFb32SO9S1170C5jEyUCWeA7h3VdA4v6Ze8HNEGz6ad5HiB1x0BPDLr7hV8s5DHpB6tFfy1Kh2f9C3D
+Bjw3pYEprAAN3Sg21D3Vm57e35a5pe3ne7D69gI934FhlDvC37w3h22IBE5oEbn56k05A5Rf4jb4d160EDikG8o4jP
+0Qq1G610JFso4qQ9IW5lO6EwBWL5zm2Mu5Wz0iBDTeFBx4F78HX2aK5gz1d9COL4KiEGOA82FE03zSBCl9h30GtDLk
+B5e7AWBM3CgEAaQ6bR6Ne8t88eY9LA2KZ3pHDTE5Qz77K8K96153i760vAak3RT0vg8Ua77f0aw5pu2hOErw7Wx4D3
+0HAG5cC0yCyI0kT5DbB6yCS8Djp9O38EV8Ww50M0aV3LE6iN7Rn9eB6iZ0xhAoS80pEqs7yn6ULDtQ92Y1hSFBt4vo
+CIw4BpFEp2oMAjZ32c4PF4ks2NI4yf7QR0lC8xE2PyDAlG3VFHUCPoEqOFE79xQ6As9lu7o9Fnr4U38JG8hQ6Rl8Hg
+0OdFfZ30oG1J6Cl66yDsaB2H6iX1xGCyr5RwFnM4Qk7iM8XHFohBEUB7xEFv2IoCuRCebE0UAsZBjl2Z2EzH28CGB3
+E9k8tJG8J6Dn7Yr5uDBpH9Ff6Tt526BOr92iFzOFigAsH2X6DlZAbUErDEfb9bhELyFA70Xw0qU3PmAqh7Mh7tICEH
+DWwE34CStDoD0hPByn5CR7qO0WY99H1CO7cz3zq23F08L2OB3N2Bx1FEW9T3CTw1CX2bdFF6CMCANl1w93so8w6Eme
+AWA30LEll3pj1MR2zeDkyDYP9ZX2PA4o544U0igCZcBau2IYDtY12UCQtFn4Epd98i4bmD2q9PL0hVCYI0sBFqEDjW
+CeF6XODcsBNIFON4365Wy8jM9HC4Uv4vr9zMAXg3AAD1DFFh4U4D032kJ8MS89AExb1V59YbAkLFWY5nWCuM7Ku1jw
+7FcDSp4870ZxEGx2UA6b45KAFlx2zu5Aq7Ab0WI22t9gO5nn8jgCdSCEFDTM8ze5RE6DA3xR8Wv9q070wFqQ8gW2HA
+FW86rFCTQ4Jt2yjFRbEQB5wg1beBLh7KZDBU7ug9x8ExR3x4ARxFt2G5KFZp2ef7dL9uQ11w4zKG7NEroBBeDKV1p6
+7FdBCT3zl7JIACq6143za5ql6Mr3CM3MM69ZD0g5fP3nj8jXCks0Ai9Lv5oH1K50YF5ZkARiF5ACLMCxL65kFuZ2UE
+EMQ3u65y15O94BSAXkCdFBsM36e70pAQC1XzG3H4A82gy0Zq3w94cSDaZEtU6882MO2WG3G41EI4ld3hB2xb6SjASD
+50DEj39AHCWj3WWD1QDt69BmCux79e0bSF6oAYqEENCkO5Ot3QGFqF9GEE3X9CVEcH6gz1sAARB3ry5ZJ5uvD6a6D2
+6BUAPv31I9f696T9kz8of8SeFl73hE9XHEww62w2Hb2vQFRgA1B9jn06QDmF8EyEWs4LI6x91fZ4VOEC92DDCQEDSy
+ES9A5U4NF49Y7l4BtF6I0FkB0ceAndAIiFTu37572W57i7yMBp0DDbDVz2BKCyZ4ARCz19yvG8h45S7AgDgP1SMDsv
+EXT8Vt2yJ9hO1XREYK5YXAZ6BW16fj7vKCNS4HCByo04v6AQFCP2soED8086G6I2QlEPO6f41lz4Wh2x765s7WhAFg
+4C72kAEYB5ugEqBCnD9IJ1gV8wy6kgAZ8BgjF3uCmT7rA55MBOuFCw1Um3UnEFxEPIDPc0AzEgd3oxGB9FeYFgG2n7
+4wl7065yoGFh8Sw1V076OBFbARo7S90NG3CgAT4ERoAFwF1X0K46wzEPyCuN3Nf16P5HS9Dn9CQFEuEeOCqMBESE4k
+16a4Ly0kt9sa9zlBmIFWq5q36Ij5ls8tQ7kEGD75r3GLM1QwCm9D0PE4T5hdClIDacETq3Ik66a2JmFEJ5gTAq84f3
+7pI2pnClnEdE6ZWCFxCXa1sx6oaBSY5LdDz59Qh60M2Hl9Om2jw81mDwV9ve0jn3hZFHP76U0bB3Rt2ao8xg36iC7o
+4l65AcC6j0iQ845AFYBDpFrSAS6429GDU0Xe8u4Bbu2035Sf4fM8scAAs4t8D9yExh2uT9SL8ki6J98sdFxqD3f951
+7Xd5SDAWC7v78UlFqp37b9zPA5REKc5pUF1k9N0EtoFGj1lG6SG9K18Vw19XDTa4yn7klDpe5LYF2A1dv0Ks9M95I1
+0H42ru1G92I9E6GFkwBGo0JH5Tw58lDerA895Q46Im460Anl2faG8p7c82xj2tV4s6EaL0ZCFZhCBb35VBTXFVPBO9
+CKoEYj9AYCZi1Vo4fX5fNBstF4V7tU91UAPp7au6fw8kJCDD1id5lg4Ne7rwBex4eB7lh69J6o3EJfBsBB6cBZqCNs
+46tASi4Yj25PGI44896eiELiEaaDS0EdF4dWFdx9uR9v245X9eP5UM4BhDVd6370ml5wT3ayAudFxsD1uD7L8NJ490
+Fv15buAEG4io4hM6jIBrZCQ04Kk2AKFbz13M5eB0Zb1EVBag6fOE370bV2JB2y9EL4Eli3zO7WHAQ34Sm9Y31ezExW
+Atz544Arn9Z5D9p6BTB1ACT7BB96ZI9iB4NY5YH2nN6bY4Ss1VT3HZ5kICBABTNBwU52xEoj1bsDOx6Eg3Gd88G5BP
+2R87jJ6bW7vBG2r9KHDGOEveESLFvYGJ47h6GKV5LRGKIE5lEQmBGn6S76Eb6zcFZO4xP0QgA0r45k7jbAdC9nF4Fe
+Ddx6Fx99kEue8c4Alq4xh5WxGEsCXU2hz7kn5zQFWwDqbDzcBzZ7plBbo7fb8k2Dwg9KS1k5DiGC1lCe4BCR486AAc
+FRv2xf2O69fx85P1u98PL2130kX0rY7Is9G7Aod7T23oo1uWCaICqxDtJ9zUAtY1gPBOGDbcBF7CSu3uVDtr6SRF6g
+BBWEMrA1K9RoEcy4DP75VFRV5IADUYFrJ3I473EFuM6PI6xsGEJ4mr0AZ7tS8zh7jz3V93d22MbE240qp6qk1nkBxH
+3xnByc2RUF1n3Xs6XA7gc6dy86XAe5E5i0gSFNrBniCpDBaoCiu8joD5J4VBCkk2756vV4Br5ig3e6466DQW1eI0qq
+9vN9TqBQF2t3A0WFI68yMCa5BGd1yT0f36u10oL2IF5WH8bG0CG3r8ArECw5AkmDWDEn95zf0Tq0G0EYSG3a6J82uQ
+0lxCVP45oAWIEwfFyE5XDG488qc6eC5gq9eRBzS7A85Hw3Mp67AFcd18zENyBFr3P59QY8lg9pY3A64m0Ai3561EaC
+02A6XZGLq9ELCnI9wY4sXC6O9lw2SW2Ou3RjFKF7Jm2LxF659YiFK0A6lG8GDP90tODME4DV8Fs57312o5ag3a49OQ
+46S8ie6kFElL2z60Ol0a94Qf7301c89OdBoK0Lj25NDV2GDgBjK90JDtwEzl6Rc2kp4Ug0mO90lA5B8wxCHG1xUE1T
+Bve25p4tg8e87eq8l8CcQ9ZlBGX21I9ix0yqE4V2bp5606f77Hq5ZXF0S8K3F4XEOd5RX1uXC7B1v0CTN4122UqA6z
+72R3kyFrM1a26sYDvMDZP3bI6Ri7T88Ym6yP7DR9pB6GdAmQEbb0ZS08eBQhDCk5SC5sI30M4S1D9E58UFMM74EFwP
+1OM0SDAZjCBD6djDsL2bM5a6ArH1fv6jpAmcB7Z2eW16n91f9hS9dCCX360I6TeCZhDxlBNaAkx0gz1lsDXxG7m2aD
+3A45dxGHE32Z7X8ETr9Uu1TL5NU4Xz76b0LTDgQ0AM5sC4o17zgFruF9QBfS511ASCEX5GJF5fr3VoA7l3aR4Xc45R
+BSTFUi09r5Wg7qW4ecEpk6Gr67L8eK06VCSG3BBBRMAzf4SE3or5VG0MICPAFfcBTu7G84sxG5o8MM453Eu2DyxCk7
+1elAvH2do2O07pY5i10iz02B4OX9U5GKHCA96B45CwDIUFbC1P1A1r81JBlA7MgFppBdw8nG7Y28ubE7z7MFCQoCZO
+8zuEDuB0zDw5C1wBoI5r09FBG859Qc9TFB6FCLN1MDAvVERgCYl7TOBlW7JfDGP8Hb4q5EJr7bu8PmDia8Ij9TbGGR
+CaG8t1E8N3BY5FIEKf87L0S0G909PY6CL5pT7S3GLzAgd9dV3Qg4Po9KeEWA4v4Dhf8Uq87R1Nv1Uh34P2Mh2X43df
+Fqy9BB0zn1jB9Re9P99qW3Kl4B0COc9ZKF7hF5xEC83Cj9MYBT19xf3dHDLXB5FEwr6vsBKAEj14GVBX45gVEJ321a
+GCcAW851vAeE9sGFNd3rfBhQ9mn7mL8TS6Ln2Em551CuW7neGHo8woBWP7YTGC69Yw9N761NAN07Qv11sD6iDLdCvQ
+DakCTaECL4L0Ed25MLCpwF0j8gr26DEUX48YFO20yQE1x8n10s17JPChqDMP3Aq0exAqLFoO4eS0ynDTm1shAk9DXv
+BasC8B2mIAt45xc1oDAU6FGXAlA3Am8yFEzx3Kv9q6AbcE1rFDO6ksAPF1jWChU0YPED61CmFVODd63a93AN0B37C3
+Baz9IjFB96TN5yL91oCESBCAAFpAnY1SXDwwBd3DEKB2n4F541j9PsAFS3E19Vt3MoBZLBnc73XBo6AxO9uTD0oF7j
+Ch5EL604T7iGEmLBUA2120jF25M1gB2SB0yi4ClBfGGLgDXC7zT6taDri7709PJEvLCtRBDj1se96ZAN59BW8So0do
+2HL8Xk536Ck19oF9fRGJo9pM5ta0ds46p4s1Fsk9tZ9LU6GODyR27qE1s7ET7Ea1B3FzL9FL2Om5NtDEx5lc3faAvY
+DwQEdM1RDDTlEmi5CN0IV97lCfMFJH7A4DSD635EE8EpWF8J0hB4kxB6jBoG6nHCIqEaf68s1dL7Oo3N95srELUA2K
+D8L8ln945BZ22qrDMd8ZzCByBIpC7Z2kwAO49Ei5fO6wQ0AcCPz7aqEGPDjzC5h5vd1MoBKn9l55YW0koAbOCXg8Gn
+COfAwy6MD36n6zTBAQ0sv5PN7loCat8GhBAZ35s0PN3mN4z99tGEyh2ckCCIFeZ3evEWXA3tG4d0no2vG4EmFN2Afh
+AUfBWB0L8FZQ6Nm02r7Wy4ms1XmB3mDrN7AX51c2qQ0yY36qE2v7942WaALt5oM9Ln5DWAua63vFYS7sQCJXCYE3kD
+1sc6W15RLBzN7p8DBM1ix1iO2lLCdX9c407J2zIAqAEgGFT51P22T2CBE5X56P11Br2heEua2qE0MVEuU1fqGIx7tg
+39v04JAMc7Tc8T11C8ERICoUCDJ8lw17Z5dh5ZH6t1FX30hz8jjBuOE0Q6uF6vY3txDIaCdP9ZT1eX7wT3NO1y15XS
+5yM31NFWH3dU1GfCymDJw3jQ71o6Du8BMDyW0DeFPRDUNCR005bEdq2Oz3IO2Ed9iGC9i2Xk42X1F1D2f9UyEzoFi7
+CsuFwCDZ9DFrE415t7Cb73aKBT20OG0G2CBO2nD7Q96p0AVJ7XlCruEgbAmW9Qq7od0TnAIq8CmBxN0xBAqzG2UCfe
+84wAD0ClJ79LCjmGNfDDT4V77Fy5KZ3QTElwAdr3DJ4LD7QWA274IwDU32Tq8Wy5ly3Iu0ob2rR9DH3wQFvs0qx5hy
+0MaBzlCU64oeAp25CCCEBCzr7fQ3NNDXP6Kk0mh3bU9fA1Xn6jgBQ93W107tBHHDqFGEw6pt1fSAnz6YY8gd6I45lw
+59T4UMAAV5c14O3Fhc1B9DV6DgI7pB7acBbyGN105g9MQA6O5G48l1Dqw97d1rk8Ue5aqG07CBJAotFJV1U51X64Dq
+8Sx0aODgF9Qi2C5Do41yS8uSAveDMi19K9Lm9wFEqxALXC9TE5kDdKFUP7ZN5GfFXA47Y3UXCTR4AQ7KaAI7AnE4FW
+EJ0E6s7pHCVn0ZLB7j0Hx4jW10YFHxCeH2ncArcC9fCI66YV1YsC60F7dBDP3t2DjY9W6C2WBfq8MpDr08kT0w5D8Y
+2QP6cHC314Ui91p1YZDMb9vY4tkEwy4beAmx0IU0mTBdZ8zO4ag65q1uQF1jGNDCu55lBDLG6wh6lq8fm62f2WD9ci
+DRe4fvGCtBZf8OSEjuCsc8WCB2FDpgBnp9NyG9r3jT6FJDl40JU4ea0nIAA38yZG8Z2Vq7BD51C9O92Eu3dx2Ab2x5
+EwE9LC8Yq5wE101DmpCKT26z06k6ux0Z23DH0S69jM6AD60QAOo1Lm5JV2SV7nx5yyCHf8kS4VR83y0Z3FqvFgbFI9
+9Qm6Er2NYFaJ9U04kE70HBod6JA4xHCTKDQrE9UFyMCXm4uzC3m9M071B58B3qH853EHF5qV2eT8pM59874c8tA0RH
+6pj2fjFLy5GE5ZfG7033WFITFRDCtuGNM6bx5kWG7z57w7svB6iAjT5ne7vuDwbDS47WV2KV5yB8B161x1ivGFb3dK
+CpdFuuDTP8Ug9vwDKT7ehEjv7KY6paDeLEYuE2qBG33Ra7er9Y0AuGAYoCc57ZpFt4DTkE1J64xAN63S618J8d46Sb
+2gC7WdG1u5wCBu1AfXBFS06tEVS4Oc0Dp1Gn0ZV1ti0hE5xh36U5ceEm7EJLBQ423P8x5G2eFhMAEXCxF1Ku99c2Wd
+8D7BKo5dG47370Y9bTEQP02a7yb0OrBsW01mAvC71g5mNB4l6QW5OUCoX57xDHt4oPG7V92LEIGFh5A3RENs09i3KX
+Dv50SFEJQ3eOA1N0uG0qr8ssB9f0cDFVK6Z630R3YTC4BBet1wD76r9J20UwAeUC2o5ALAXVCYgEMM12N3CkAZE01d
+13e5yS6T82NA3TyFkV4700km5CAAKG5N1A471StFb96noCOJAQJEWZBcR2I7CCb2FG8JC35n4Xo3nuDQc2gu2sKAka
+FUEEv1C8jA4rBxX7BRABl06y7ox2nqG8v7oy3IaDshDiJA1Y90R9f71EP4D58YN0lO1jJ7Qe8sCGFs7rj0nz75h3b4
+DWr7cJ2eI5f725CECeBRbBPeFyw4a026F1JHGE70WqFwN7BA21f8OfC7R4dUCFw07W5b9E6cGNAFUm1VK8du6dN9PK
+2vZCit3eh77I61T7G1CRg06p2RA9Wg1NfAbg0Z6AREFte71sBix7g90sr4CLEe991h6EkFh71GNFi0AZXCay5cl9Bp
+B0n7ewBGgGDF7NDF8k59D63g1gt9tN6rL88L0Dd7si5Kf8zcCvD54QEum5z39sm7nu9vV1XF7UV4uT8l92PdC453Gw
+1AV4P50rGArl2Fa8dN85v8cRE0P29q0hx4Bt7IbCEG7UMCjj3Ii1Us0wM3vU36m9ln1MM7ef4CO9Y17r6DfACq60t3
+4t10A0DY92LnBptECgC25Fn71Rg6tfDINFYZ1y759CBkA3hd4DgEgkFknETDAc6GIs1ICAjM59z8txAlEAJ01BgGI3
+9C80Zy8z5E9CAmrBdy7Bw56C6IV0y76rA7dUEExCvxAXyBtL4v0Bdq2kLCsG7Rq9r31fD5Fz5kY44aEr02AsG1tCGv
+2k4806DLC6RSEMcEUnF5nFr55SqBxb7RF2nn63A6c38knDVL21r25Z1xKGFl11g0Oi6M5BZmCODBln5yW14kE9d9CJ
+B5W3wABPm7wo48j3C68J5CpvAfcAM93864OK9VyDY5Eah03h3uf9gdFlk9Bq0z83PE783BOb2ioCc021E6Mz6qgD6T
+4bM6PREB1G021yE9C33sK0MoG4sArI8vd0UE37GCUZ0lL7FG94r8KA0W36e57he6M93rg6FE4Lk1UYC6k27t9eX44V
+3mBDXy42SDuiB0fF7bF6KA4aAKkEye1FD9Rr35zEG5GO5GBf2Sj7e994GDaz8XcDIc8dLDUbA8h3VB0zS6WC1bA2R9
+1UX0Wl8FnE1u0hn8pH3LB97o4uOF2l6HFA2TAYi7GO1PA9a210Z3vx01v0UP0G1BvJ1dzDiHEY70mE9Dm8rBCvv3EF
+FRQBwFG8i47V9Z21Qs85u3Sb7My5Nj39rDM83Ns4iq8epF414pP1lL724B8H0T08eXFjfA7S4rd0ym2JtE1K96b9dB
+DNp17g4PD0zNBay52zApe2tM4hS3lA1Hk0gn92w4CF42zDt5EOk90kFjy6iP8Ya05h45nBS2C8YBkw9bDFST4CYCoc
+D9e2PND7R0jU2gG3779tLCRp1047phDEv9HQ2hB9lV23I6Gz9hdFe25pOA9Z3R5D008e9BPM2RoF5tFIk3Sm7UN3pL
+BCYBA2D0d8RfEs7EhK9yn936DVjC0rFf7ALdAMZBNJ4hnF4h6vzBFdAi0DHa0lU6iw7IB1EE7E6EhW4fVASG1ji1x3
+7Do5wG2jk3eW84Q2bAD383B4EAPDjX9W1FhF4VM3ZQ3Wd4Mj71O4qw4ok5JS7s185dBzC6ke1xT9vu7S08IDFyWDnu
+B7t1Md6u24vL7EH4xc63kE7D1BT3qi8338h2A357bP2E83UoC3y7yQ5ae6xi6QH28JFSn3ux3uBAMmEIQ5YQGEVE9L
+B1a5vrGJIDIECsa3Rw6ys47G9wj84U0haA7yBKa5GkFRhEOcEIW89ZA969vn9ApD3i7cM5aL4aD4QRFpIDOzEN93qK
+6C7DG6CgL6lU9u84gBAwQEkh9Vj05t3LvESN0i99HB5g12GdCIy74BB0w5e20dt51M9Fo4plFLS7VRFnoDn98yu8US
+3Et3vREUF4JCDBo5Ad2jbBp5BhE1weBSOArT6bE3Ly3WjBFBF6yACb0Bu48SDY048N7Z39C74Fm6xl8Bb1In5QS2zO
+BEg5F7Ff6C6dAQo09R0HQDcQ9mCBKG5FCC9K2OyFlD8Vi0HnFTSFWN0qF2aID0V97Z8iXFAX0it8CX1Qe5cEFbq8aU
+Eoo3mAAWo0L75Av4xQ8hW9Di483A9Q64JCWn4Dx7d25iK0MgD37Edo0VN2oXAYMAR4Fp1ByJ0xF7Fp8m0CKC8610WP
+ERj957FXz92N4Ip8wL5yF7Yh2ltCPm5DGF1YAvuCaz7Wn5wi7ek0IiDXnACdAfl18e8EZG08DoX9eHD7IDpP6ePBcg
+5oF0T34BiFeBANX33Z93QDpsELT2ViBGR7bT9a16VB8bn4Vk5lq94730ZDjVAA6CsTEai6gHCCn7b8DtBBLT8IEANN
+5Jw2XpFKJ8PX04XBD2GA45jh3Sl2m6FBdDfyElE34mBDc47qFn67CEBlQ3TjDGG4BK5XX6roFgI2N6EuADPKF9Z4Mg
+6Fd795GI71xe81PCEE8nEFIZ3FIG4S916EG17RjFjIA8y5C4FbGEwWFJj4PuCsY3CZCkx8xhAic2P95qt4vcBDo7VN
+CDfCizDUi92f9orAlK4E66pS23t4Dk9rh0Jb5xx8rR3xJ3Jg7DuFFW4dO5655Ak7m0BQA6UP82W51l5X27EmDeYG89
+0sn8SECMmG3O44RBDmCuF0cQFRCGGKD5M3j0FBy66B0qI7Lw8Z0DfNC4DFQKD7Q5csC2D2AwBh3EylBXUA346jM4Q7
+5xY9Gp87x1xDFFS1Xf64D9nA4SfATjEhr1wh6ctCRIAx8F0k0rj04O7u0BSyGIYAbjEHfEjHFLM7Et0taGH30NZ5aA
+8IV1A0Dkp7xk6dkCEv5df3rC376G7fEgi65R2nT2di97cEqcCos8qVCoW1yI6doEp7DdB83E8jI3gH4RC4BlF261UR
+3gA1RvA2sBgZ1QW7L8Ais2ADAgQEMnDD07nC4i9DPrCGXD0AAJzCN10lJFl31D8AwWFeN8O26nVAeA2qR3TJ8JiAUl
+3IBCSsE4LDeHDpdAvQCcvF0xAA27Dc06X9qeFfo2dDBmV4JB558AY0FVr4U8DDfFMc4DH9II7Zw5KJCMx43CDmY5K3
+BVuGEIA0x0zE8ZV0PICvH1bu9NhGJ66uD0hw86c5ih7lJ2G68cK3TQBtICQSDLtEv69ug41AF5v7IeA2W2VmFfl8Je
+3YGA1j8VD3gm1HwGHs9hv5JpAphG1hDUD7FSBT7BJFA1AF0c7K94LY8Yx3I1AA91Z556LEyF4V65pB5QW1I61Lc4Q5
+7Xg523Az3Dpw3Yb28t2aB7Ce9y181q6DM71FB8i8I73P87ym6nyF4nEELARz5QHCtnBnL5NM3MV7T7AVd1Le7cq8L5
+0NcGL3EpR6pH9ss8YrC4P9GgDQQ81G4ko5UoChA51QG3m83pGII4dE3fqCxK26l8fs87c6b7FPrA98Eyb0B9Crp6Xe
+0GsCPv91RE8d3V8G5pAvh0VY4iB3037KB59OEAS6VZBupGLLBOs8GB38K0j5A9WEwj0kv4u4GGyDsq7qS3LeBIeDjL
+2pi39zCNa5xZE9t8rr8vz9tl16f9ex5oX3tq1cv69p2Tt7yG9WLAzm5ZaBKe3eXDCj6toAdtBxE6j57AGBWu4xC6lN
+EGnCbo74YA2qFiQ89zAys9sRAEh1nS2u87sY1rq7w45SV23k3074ka7zw8RK7tGBdv2dyFIa4iY2NN2pbFKN6HsDzI
+4zQ6SBFx7CLd1lM0Ko6N56rhDdL4G8F9CCXN4MEESz1riCorE6t15Q5ak9C6DsP1hJ6QJBQZ4Qc65b0JO9HpDtpFPO
+1ll1LD3rX0LsD8U2Sl5jP57IEZU2kh97M1qGDcmCwT4DMEi1Bm42kk5Cg47X03sAB264YFxZ2mzEx51zIE7r20O30y
+BIIDkYDpJ38l1VN0pc6S63VJGBFAy81gFDvn5YEBMZ0Au8aBAsW1i3ExZ5Gi2HE1sSFX14W04gz5ii4p28WP6WD5BR
+2eY1Xv1JS0XP4jh69zCWGELhDc30q624uEWb9fI8VQ8E9Cci8mE70L4p8BMF2jJ2qJ2MV5sK93EBMo2nH74VE3C3Ar
+0ZB5pzAYg3pIDfw3ek79E0Ir5uGCxy86YCDl9HU2ql7xg33tDsF2Db5nw6698HW6XxD0W1xtA3XFxf60s6Mp5SIBvd
+Fz49unFngDbDDyE2dpBX9ByADkn5nTFQADoM9ghG5BAu8DPo5Vf38xG0h9JUE3MEwtG4l8Pi2Pb9ZkFiI93Z8GW693
+0DK6Ww3872BOEeq6sDAs12Ep3Qh40s1DjGKFAxx7vDEKm3R46ckBWKEGY7Nr5PTFrADOoBow62E5hK7JcGAtDnY4iy
+Dfe1xv7HO7iS2jP5Z449L6p4EhMAav6wr5IJ3uNF7P7An9gK8LcGNYGJuEWf0FUAsFEeg7BxCKd6mo4cd76n4IBAYZ
+AU78ZB64I8ZA4CJ8Mj8X2432Bzq50RFCJ1Rd1HyD8z2g98v66Kd70r3Cr9aEBDHClE12w1hv5jXE74BVh1LOFFoEA4
+C6B8KuCce5w6EcP9YCBDEEwO9zD94q7w6Buf7pPDFV2FF1PaFVwB1B2PT5oZ1eN41b8r0BMvAaY0zCFUwBquAhOB5E
+2HrDx81hH07rEFm0U7FQN0IF0nR58qG6g9B28826LL9nm9t48q6FMo5zCCU4DUQBKKE9A4YEEnm3ipDWZ2MCDLs4iz
+8BfEoh9bvDuU7lM32DFZRBU2CD3DLRFWG3vA7EqCPZAEi9rcF9E3LgEP2GIr4BABhfC464Kc60n8CTDCK9Rz2WnFXD
+DN6DKY2v04Rl5UZAEs17uCUQ6Pu74i7Zy0K6FWb6Xs9nkBge4xXBVOFx67GSCZL3doAXs2pT3PY9hqDkX0yW16S9Yv
+BAR1kd5ZwFAyGN2CFXD9xFic1c20lzDEw2DOBeF3zu8pfBTi8KJ0ueE3k8aE4fS2YH8ii3pc5fs53t257GBk0Y31wk
+Ed64he4UZ053FoZ2mlF073UU1qpGDd0ygA70AkyFGsAkC6CdDQO2poCOM0N72w13WwEln3SK98WFP3DIgDC83B96Q9
+6zXFgQBer7eF0r8GERAYbDRnEgy3al0nh9FC0lZ3t3BVt8nICc252j02j7du09v9an8HaDIWDyw4vV9wq5mX2cGBtT
+4sq8AnDoF9TzBsr8v0DCY9GVAa75nB47m1ybB1i8MIFWO66pG2a9wSFqe6e260t6HvBgi98V23hBpVDfDFwmEAT1eB
+9Le2NDD9q35m5i883oFaf47ADnn1Rf1Ky9Dc1FU7hS6TTAGe6KN9ZzAjEEFMCoQ4Fk1hI9sy28KC4H9k9EyQ4f9F54
+DlMC434uW8W76pUATcEc12P81LG002FkfBuV3642FY9mXD5z0t95ynB248Ms8DL9iY8G65FA3iu7zH2w9FKHDBq2UM
+6s1EmN1QE4WC1eH5lSDcx9Vp79q6UT3sg9TQ0hAF186n39gwCQjAlBCAY0qBDmP8QO3e27Sc32aDaeDcYFS1ChC35p
+29K4WtDVFFhTEaID1r1vN7Xc4GN5c9FbxD4w9w0FIDBtY76v8YR5b47blAw51Zs5egAMz3qAAfE5C31JA8uk6DTCVD
+BLqApJBR09NP4a49d1FlN4ST0d69O43xT2vxCFuBKb2vS9nLDhd9s22vn4Pg7mU5md7EC3Ku7bO6DfFY4CJpDzG2tH
+2lX78z6ze5Zt7lm2ALBn4BNVE0EEkR83sENN6fg1SI5Wd4oj1iQCviDjMD8H9k22E95re7aL08HGF6C2nDZBF6T8PM
+CAZ04U3WMDw0BW815jBPrEHhEK5Fv72l34FF1mC25b9WGCMJF8j2rPDxH6Wv0pyF7yCTVB9j4luCfC29e2bl5bgCpG
+9GTGFv6YO01W8jH8jR7So9k1DVgFCv37vCQM9GoDFZDdN8w5A4iFof1ueCqZ8OC6u48nWEFf7xs3OfCjnFlO34h7Ur
+5tjAUG06ICY08rA5siC1y9x52md2sr2wS2Po3BmEaA7Hp26f9DXDAH4qPEvK5dFCuuFjw73OGMj3qF9Ko0fRG8T7fE
+5IV5T656aAgy0wU28XFac00F4SQ0lm44n2KTBVfCn7CGi0LKDSe1fi3WYEhz9j83xU77TDfJ5jr7MU56KBom8U86uU
+9mx8PsCah2dV0bMEwi9RY9sb9Jp7J31skBkS01x7IDA3BCxx2xg1G427i2hE4KK9LW6C1B1P9lM8qN74k5T5G3B3XF
+81d3Ui8AUEwg1ZjGHjEVu4bD12IB6SFjd7rYAX76OH0gd7Hn8hz6mI8ol3wN3jU1gy5s9EXR0jh1rY0on0VoELcBYR
+EzhBo1Dh79db2uVEYV3QzF0A8xD0Al0ozAZP95G76Y4TSG2n0Ou6cK2UW1Au5z9E1aG0p1zwAem7zc7JlC3eDHEC1k
+0P0G7A2K90st5EkB4bGKPEVH2g43OGE6wG9eB5J2FA47nFMyA7sE6QBny5Bs9Vz6XN6LgEXq0HP4epAP74WX5uSFfA
+BYaBnOEH05pG0Ch0Vn1Xt3n43oaFAQ8DeD0sEdp9EU6cU8jCF374NcEfj6Mh5B076tAit5xFCfwDkW9DS6bP5HUE7l
+0JuEib2gj6WIER64ys7CV8AAGMTAKX5STFQr7CCDfE59Q8S48gU3H06rI94M7pgEF0E9YFkg3oB83Q3LU36f7M04gL
+5Hq2s85G70s777F7q3DGRFTD646DWmC7CEsw59P0cZ8Aa0uR1AY9ieDb46jLFhw7Xh3KV3ND8jTA1h91S23SE5Y8uW
+Dk14ygAc37ajDFG5FU8QS8KKFmQAn71zCF8r0xI0kGCUuCLT9vt6lICBIEl86Zy8oJ39i9hG9rmA5r9VIAVP8lp7mv
+91t3vVDjH2ED7lgEzu6GfDKlCxVCRS6lj7YwDgY1m527y5a5AU47LE2DyFiMCMOATl78Z9f432pDXlFlXDJt6AWBWD
+59A9qb4i3BRL76W8DyC8283VFVAEE35ScCdT5bN5Ki1VjC198DY2Lr83t7fDFpbDUG7Tp1PnCDB2SZ20059sAva7jP
+An31Zh5XCC7a7qsCTD47g84zErqBQVAcBFQL2WA56z6yu4bWA8C2Bi4NoFUW4K1ElF21Z1dU4Ze8ke80VFaZ2fqDsc
+0LzDux2Zi5zz0OsELEES54UjCN90307ny25uE3S1fd0YO5ex8Us6bN6Z95Tv7IU4ik96I7yFBqU3RHDJFAIp3bG4hk
+2GIEM0Cif9xw9VZDSO6O2ApA8KGAchB4zFNV0Zi4wI4Qy1tq0q23msBqI8zK6pM8VaG5uE4208p3u8CQF2Fr0qR6lP
+3f1GAuCet4rKG3nDkO6svBMM0lnAcm6lxAKT6177fcFjT9kL75FDre1n48rd8jz6y4Aw6E8F7pr6sO6kDBErCreFKf
+ErG37S94T3uE9fg4yBCExAIl8SvEjj30j86ICtc2mnGM4CUODcv8c8DG3Co38rV18A5BFCevEnd1yHCQYC1eApHAkN
+44KF3C1S1EUbB3R8324AHDCw0KyFXL8S28AZEBlC844P76SW8XgD2Z1AK43S8Az09e3gR8aw4kNCfYA2M0Ci1DFEpS
+Cns7ot9Hk2Zh21pBiTFHB4s85RyGHQAJkGESB9mFoD8xz0gYEVE46c43XFQ61dSEpJ1EW8xc13979iGGl5GJ1JW440
+2cxD0jESaBXYDVl6BNBlZC2X5sDBnTE3T2JU07i04HFrZBET4ho16y76RCi37KyF56A9mGC5BLC3Bg6pF8D96f1D61
+DTF6D901U15bEte64h3CvD9I8Or0fkFCO0aB4BZ9He8DZEkT94j9hLFtL6yf5ub75z3qsACY3EE52o1GE0YU4Fo4xx
+9NC7VZ3tt7IY7lH4656k3ACH35xBhy0RhEZQ456FNO9802ISEWv5FDAwz3vWB4VD3L7gE31UBr84kgBiY6zd0yFDtL
+44iDk05Cn1CwCP0AnNEb3FyI3zCFe31jr0IdBGc7x0DE6Fjl53v4ltE6LAzL8A44ee69LCmOC284H92BXEL15qc5uX
+DnE06d7OM0DkG9KFU4AaP3cm5HV9LcDT4Ca1FkW3KM8Ar3U829kEUE1b66N19NJ9Ah13z8cpBgbEFcADB7dCCpACmJ
+D1c0b73rF0ztA9lCWZGDSA9j6V14uVE707mj6xHBYC6HKCVt41t8MV3KUATIBnH4m884CBdO41Z7fN31m6fyB366Fa
+BVC9YJC1U3ZdFRyFgsDEUC8l4Xm83n0g9EpY10oAntAPe5gC6WQA0mEJd4hY9aV8KiFwp4Tz4LSBNW3EsG6K4Zn8DH
+EPb06lD8XFZu64V75kCxaGHP1g6AVm7Un7Fv2Eg5Oc6750bm32g9E01KV5W86s84lq7gG0Y28E4Bqs8J92sJD8J3fR
+3yt2syByY22G33xCHI6MsC0dBz9BA647h5pk8jO2pJBX219U8lmEiMGBx7I4DYYAFr1yn0gZ3gQCjyGAh5Ik1Ij9gN
+FjHAwcBtx0vT1P4AmO8mj6dB7vg8Hq9xyCIkCATAf10jo8KF4UO13VBBRDcX0Lp5XO6mE0hLDxx8tdGGZEkf8Kd1q8
+63QA8b6Ys1dC8QG72j25E46u6II0Lm7R514v6E10Vv08SEWG1wu9ZH7KA4jX411DjZ5OL54E8tm8l6GG31aH3gxAdI
+9YOFBWBIsBfMB2WEV07D4C4zCFUD6m4qX87A6L2Fyk3xi82VEh88OW0iDChj86m6Cz6HB0rT34S1Ni7Uo9O24J577c
+6P51HtDOBGMtEQy7YU16U8YjDuP2jL5daAdT0KA0G80PS7w7F2t4VbFQn2WJAY6GEd5Zp2gd7oIBEOEHVBsC6oq6q4
+7Au5dc5a4B8o7sdAkn4cx6HU7ohEF74LEFMAAge1SPE7LEZE6IqCXsAdkCiX43M1KR2RK6Lq2qW1nz1Vh9Id5sh61o
+BoJ4NMEpc4BcB3J25o1qc16sBysCftEMl9aeD8QBCb65nDxw2Rz03UEq42bz1kQFcg9Qz8xUEjh4fm21dF87BUYFcH
+7riD3PFqS4DT1znC7G1fW4bY4DXAj6C42BGV93Y0qiE2N4yZA6H29G99YGIG4792Xi0PYCbR99fDAL5Ez150DhC9kq
+8mf2v76Oz7SI2kT4SJ0SO46gFc47yiCzGD1Y3A56wLDYmDHcDbe5s60JSEup54m4UVBz00aa1Yn8L67bZD5i2kd3jc
+7TEB3ME773r37hv8n05szASsAxE0g7Fcj8p5Al53XiB6xF8l1BQ4yy7Pj47e3Gj00WClK8Nd37p5TkFyf2hrALYDWa
+0BRCeu51SAzT9C5Ak38wIBJE6wp1Gt1iw1ej7RvC4U5bQAFP2bN6vHEEMDomDGq2Ov7Vz6zC9KuFry9R93SAAPTBvE
+9fO1Ir03VEqPCEe67E6qQ5cXBIb6KSBr00q8Ezv66K4KHC6H0sQ6DtF94GE1Dya1kn7d80RYFnAFTcEsNB7d0yr2wc
+DZ2EPS2PJ8wtFIS63pC2J32SFDH3CuGDwCmM7ZbA9q1Rh6JqAXq5M68pRAnP5gIDnW5Ct9HXCcX0X6Ev012SF5KFTr
+GLWBNsAnw4cw1a41KQDJJ8tl2Eo4wT98A07T5lU9nKG2Q8Gy3ml0S21ijAHv1xYC0e4B8FgpDs59sC93a4pfAD963h
+8JwBi6BKw4C3B8u7G59Wt1UiCHmA9U8cm0l6GHk0ol6MUAZQCudDxg8HMERc2UBEs45t8Bg1AZFB5k9qHG0DFgNAjd
+F49CO0Adw11z7xRDTUG8KBZl0rd4Tw8Pt6TB8KLAWM54jCi49OWF7O3kMF5ID40BZBBTh9pRDUk87p8BV1Wg8sh0ZX
+1wF6FS4Tg6nZ9L8A7R2hK90v9Ju8fg45P3cOB784J46Rx5VBFV617m2TFC1J3zV1988lI8rLByd3DOCdoB75BJq26A
+Dic8Cd7hE4yNEtP6YS9mK840Bi02BJ6Qq0E82ykBnd2zWEFY7dPG9U9E45cd6BiBlU5rsEgjDnZ88qD0Z7W8Bz21Lh
+E3RG4L7sG5rO3bQB3eCWg4FY4YPBS4FLHBqpCRH6hU7j5AMAB98AMg3lRErB3wh2yfBsL8WaEdc6q03oDCdI3XK7m2
+Fyn9Lh5zrFpoAh42mhCLL7reDk5Eo1FTWCwwExYBmz5Cj7f7EFEDqf8oC6td9DbBDF0MS1pOCf6AwE6Ck1u2C49B00
+0081Zd8w8F6VCh8BGjDIR4Xl3vN9puFxe7Bu7y7BbXDAw0Ur0Zr41GFSb6jT0d72F5FQSEt51ZF4GUAdJ19VEZgAra
+2OO4Lt3dWDcCE5q0KeAbdCAJ7sjEuM9jNCzAFDS7o302WFza0qz1UFFMs6g61cA4XyBC33VUG0S09s7tp0JXCCw9QG
+22lEv2EIbB775QT5ObBFY9H8Dll4PIFd4E0OFNiAig0xZFEs8be1P57m7160DytCHvA1q3JZBXvCGt6Qa9F42kQAZn
+7Z1Avm0cdFPuAd4FIH8slEA58LdBNTApY4OeDF90LhEpb4ZxC1CDKAFo75Jv0Hm7dB4LnEUvDmS3A8E4Y2Ps0aD1Vm
+BNZGA54es4OF1pkAS55mr56TCH96NNF6M7fgAesEMw8cM8FIB21Bb08GJ6b1AVa9fZ9ry2fE3Pi9r13nXCes4sG2nB
+9flCZg23c9ujBR8G9ADyC7qQDNr3NY3oVFOG5FdCJwAEOByuCdkA5w7USEoH0BqAiwFZk0YTDoT6xm91A5el4oE6M0
+CZz3TC3jIBcw3Q10hTCis9mREkk7q53MU5QZE6Y9fb8qSANe4Fy8R8Alk15h8Y546a7te3EZAd1AEK9En2aQ8YS4fs
+Bmj95X0cC77P2t73zHFqP7Iv3H1DCi5IB7dYDQwEEi0TjG6cDoaF2V58086J7MsDL59PjBAvCao3ls2g16v9DKM2hn
+2Hq2FP5MG9Sd7CwClQDUX6Zm7wRAABESt3USCqi8BhBsHF3kEZA9Kb6d74IUBJL8gg71DCK2FiyDQA7cHE218XGBMx
+1uf0Y61MgCY8F0I5zy8CR1o6Efw13cCrkBWv5aI7lDFyb2ZAAo9DsD7c95b39CvFhX0FGDqaDHOCmz4aRDEy9ZY7C9
+3z9Af75Bq4t29878wP5eyE2RDRw1DR3SX4h1GJSAta6giD7BEjR4SC75uGEqCaJ6UKG9JBTJB4M0765Ea40Z6C6DVk
+5F91lS7Jh4VNE5O4cFEwz0Pt7Tq7UkCND86oFtd1MJ2RF0Pz6ibFRP434FCq4hd6zk4REGKW9U7DWbGAwChDEDq0Xm
+16b4AsDWODLPBMVG72CuIEGE28YG5AA9K8301LSFmR0Yn48hByN00x3HWB6M04h5Zh2PM7VO5JC4W77Wg5KH2cAFdO
+8jt5i99tF2c5AyY6hEBFQ5Zc7Iy24h6H3GKK2v8Fh40dp2j6DLM3gU0eJ02i9yg5rx7trG2EFOhAmG7vj8K8BueB4u
+Ayi7ZF5zSEBy5p13F00bX8kEArz1Tl6BWCuX4Yt7urFZ25Ui0FL3ppF1sBaB61t8YH2IHBiABWA34G3FN4xY8bDCOe
+Etk9dS7SE5t18SSBw3G3x4B21tK9uk69D7eo04x3fMChY0ByCow9a53UvBJ87HrDpl4vQ6wSDwpBK92A68PQ2u3ANk
+3QsCncCssD248aA5XB5k90prFfX1sM5woD6E6BQ3Ag7WD1Nh1zUB2R7PiAK75fM7SN8v1EvIG1e1wr6NJDo2640BI4
+DLa4vU9nV9XOD3cD9wCJV9u34VJ2wIBQN3AZ4kV3xW8S11e9Buo6b89ChE5G8cS5IR02GFP2FHc5CI1adFqJ7p71MQ
+9mh1yRDE5CPICcBBxsCgFFl018V5956riDvb44u8A033ECylCmr35O6eF97kD4s39ZAoMAc7BeK7FbB7V38Y8ZF2nk
+9oU98s8oA9h9DnL7714qR95x12p67T3w45en3Yo2Y84K89Cy8HpDxs9Va0Pl3u53aI73mBuk54A5eJ3ZO6a2Doj5kL
+2jVDLx0eBCGBEQu1Ej0ux7Yp4ft5S79SG7FLBQKFyO1akBfT0QH6At9MK4djCVk2FLCbFC9h5Bn0PZ72p10N4un66e
+Bo7BcO2Zd0nn5Rt2BdFYMA7vAMD9Of215Fvo3UZ1bhEXQBHR4ao1kT4bF0BQBXA4sH6k1FoK5E78iuFHo37l2v266Y
+CHV7weCzyBWJAWXBRz5G28HK5SuDZf2OSBPE0ey6alAtBFt12CV3kJ9CC54d4Xr8E85C7AAuEnjBog0zY1da9qwDIz
+AD119NDhW3EVD48697B9p784Alp3X6BOOFAbE2rA1i1kb5PM2q92AM4ga8mN7pJ5iDA492Tz77W0bP0Fk14F4eYEbH
+4qE7tkBhD7sX5IZ6KV8ej92C9iPD7l4Ei6vR5vx1Un3xNACp6evCGfC4p4SLBbZ4AB2ZgBpvBDfCRN2QwBQeCRo7wb
+Fl94mzBQMFrx1HX4K07DHEgE5tt8VVE4B8QhBva9JW9HHCk86GcCtF8mk4X5FfnFAeAGCAHBFhyEXZ01a9xdBnDF7Q
+A2J0vJ3fS9j40SkCuv7xlAh33bnDn0BED41R5Cr38O6ch7xhDmTDoL9tCBVJ00G4geCmH9eq9n41htD4p3B09Ri6xJ
+7YYD7eD08AbF0sMCb2Dma78e4GO2vNEHO7bEFgg2cMGFFEuf786Epv4r3AnF9xe3uP9A201OC9yEsU1yl5RY2OEDem
+4xL10D20R9GqFXcE6i30pAwG2fV6Nd6pc75wEl5Cmn1nP5hG9AK9307jp4qVG0A99r8nn1lPALbAQnCXE0jNFyS6Zv
+Cp5Ej68WQ4hLB7c1DH5ZB8Q15RmF2wEVh6HT0e11h152i8cr78o2oI5Wj1BaCDc3RL8bPAba2yXESdAlQ9UY17V0Mm
+1gp0pv7aGAkoEVj2XFFRd9IR2Q54iL6fo63tB1c3TgFJn76Z3VT6022QT6vfF9GEut1xc3964Dd1xkD5e4aKCtyCUy
+1L6Fcc0kz8L83E2AOu98J1T9CpWEzn0Cd7gP69iCO428H0U507vASz5ct5OCErF6jVD3WBTaDEM8qWEnfC4Z0um9iC
+FTP6cb1UZCv5Epm3zA5Yn9MxAgb4Iu0ve5t2BHU6ah27d7kI8ivD4FDKb812FwJB8WArN35T3hjClg80XADf9Sa6Xf
+5Rn8276qK3UVAB19G51ot9qkFm7DUMF8wGNH0ANAwO3RnEHI3MC8ZRCwi1psBDa9Nr4yQA7t6k8AfAAMh0cs8Zq93z
+8Bm1QbGB5GF40Tl6IZ5vCBrx7lQ9tn6Hg6386UXDOp5DaCGo4aB7vp8CMG9v63c9dt29D76VAq352B2VQBsREQS5w7
+23q9MS2H20fdETEEP49ikE719jQ0dICyR54X7Ls5gw1xr8iW2zN74K9TtDCNB7z4Gv1C20c2ChzAhx2YE0NF1W56la
+2z76be1yrEysBIM5IQ7aZ0vD1GcCPX4fN95UAeuABv1sLD683i9CCSAgf77tC9493xAY41YU4zU3ur4ZA6FP6XY0Uv
+4a92f09NaAo81hC0sW0Qr1dm2z3AbW2p834j7YtDue4xN4QAEICE015Dt4tL4jK9uF4ugA513sx0Ta47J0ot9V74fU
+Akv4er3v6A6cEGC2k8FLIA1U7QJ14q4850LO90H99M6Sm0ObDh9GENEmcFoe1oa9RR0TiBhm4Jb9eJ7dV6drGFz3TU
+8Vs45eCMcFtNAGd2wu4Ty5FX8nPApaEEmBxkDuL61K5Zu4KmD958UJCWy7DB7Cp9MGGJC62q4ukDT79AE2nt5gU0G6
+EOrBDd0YeFQu99F68065e3lc2MMACtGKiDRf4uuC0b3ML4YZ8hu8Rh23A7DA7StEUR3bl9wN0aQDO71wvF0e9oc10C
+30eBaTEAd1w1C8d86NBuh8VP1D22423EY9Bu4FL8WU4pbESm0KH717EXb7niCi88vWFNSAbTCjp3wiFesARNGBTCpp
+2hDCkiCOtBy2CSp1Up2udG508tHA5n1ym0tPCrSABDDGlAmY08J1UA1t355d6yFBHiAwx2Ox6cT3zx5Md6535YK3dZ
+F01GAr3yf4WR38Q4LqCZo3JT1z84fPFB27ZQEYY0uO1T398gB3IEWr5OOCUm5fl5CV2wMB3E9TB9kA48F3DyFwS6a5
+6pG3sh9maFLd5LSC9VAR88pCBif5tJChS3NT6JJEB548MDGWAvnE8L28OEy21Wl0tK9mc6F78UU3UBDf9DUaD5s6RN
+G5r9ar7oQ3ko8qR0avFu09AW358DfTEtjB1b8il9jw8hsAq6EiKFam6WZ1EUCNdAHP8vK3cI56v4Bs52a9dG6RJ7oD
+FuK0od6ek2CyCF6EdkEuh5NNEjW7iFG0IAOI7fI3GF2M61dbA0UACyDMmDfaCpU0X49j1DDFFNI4osCKJ5opEItBLb
+4TH0vi3kr0dFBYA4r065E07LFp9Avs6wy82094W5zuCm71BMAr8F0m29E8SPDBe0g6Fxc9vP7Fn2MA6B25x14S4CcY
+1JMEs97ApCQ92ZH4qtFym5ux9Z8BdU9F340NBuEFnj27c0Vc6Vd9oq75B1k20m5DZF9YFCwD2uDBIXE9mG0g1En8kw
+CoRDxA2wpCO8DfS7rIEHz0GC72i6kKECfD7v9M4EpfCbSDrmF9B7sW6KqAUXBr2DKgFR6ARyD0E0dlC3T4mB5cT8Xi
+8TH62h2dX0v1Cco9BUEbj1wf0JF6Ea05xFG92tR10G3OV4KJFOo6GPASa6E03EmCWvCYzCi1FLt1JmATL0Qx1DrCA6
+2B5EKl8a5CKv7xj73NA9I9kP2qFDaCEA68UHEFK8gDCi20vBA4YCEqC4TG5800E5Xi8Y33mSDPiCAz89m5O10B25q6
+9Jx22pDwB2gR0O8DRV96kAUw2Q22cJ6fQCHo4rY4HEEuWEVG1181Tt6Ce7pKCF50Kz3xY8c62j24SG7jG1AL8Hl27N
+6ERDHN01qBkI6rt7Tj1ebBb45A86Hh5D7F2TEJJAEk4oQAmN05UDNk8M13ZV27R4e50M83DREN4EJwFRt8RUCaf6JP
+27K09cFHuB052454TjEsqCjC5uk4Ul5JYCNm2674LO0XHDj3AWL2y5EgWFLv4dI2eC9Mk3fyDCl2qzFVYF8iFrU6bJ
+4i429FDxtChp64c7Kp6Mf7wCAu682z7z22RwE3l8N6BMS0H7Bk14dk7zQBDBAIw4oGAOQ8QN2tZ59h8186kHEtY2om
+6QO05P38NGIoAPi8uJ8QR8c10bL9YP1Zk56J1BVAr575d0k875WDif8EMErm3Jy8NbCjl3Sc0a56Jl6uVBlm8RX6Kc
+BgrAQDAag3CJBjBFz367ZCn9ELP5u34NvBtU19aCSwFhsBjR1Hs2AJ6qFD4x1EmDDp2zo4DA5MI9qy3J09YY55T30g
+CBXF86AfL4nHGGODk83nHA1HEi737T9vs8f32wE7mH5xR5dP1GF0sL6lf0TW0xu4fe9Ds6TuD3BEzj1B7DA20Tv0LS
+C9G3Rh8C1E5N7Ya8C762yF1dFWdCMV2kFG4m3yGF5s9UT7a85OJC2V2VC4986jY97g18F2UZ7A7BuF9qZD124RN0Xd
+6217L1EQbFMB3nP6Pi5tl5Q9CVe3VjAu9BTm2nr070BOB1Kp2nF4T7Cxz0F3CS3F00BPfBbE8gu4yt0Bj1UdDxrDBd
+BkdEhI2n11nm4w79cIEKh35M6LNBci9eS2UbF4K91eEzVBKr4hJ5BQ9PG16o5fi4TXGK14d699I3mG8sZ8UO7aQ2xl
+FUC3325PZ55Z6Jy17q3GP3r7Da89Wn03bElfE1f7ia1vgBhtFsb37i1wlFCsBIj3mdAsGBe03dgFF44xe42JDkiG5F
+CwIEa116k1M6AFtE8C6A13se1crEejFefBq7GGP9QQF7cFbc1pXA9CB5sFhJ0AD2pfEvV2xsCDM7Td2GzBOl8l06tv
+4Mf15J2jTBrf9CBAegBlF3nwBqv8mZ6gW1xw6mh4Qt8VbDFt6Pv0PpF1aAkPFRf9w158T5B37LeB0yAJl9S98cv5ng
+Erh1A90se6YQ4KxE5n1VQBzVFRWClS08y8Z13oC2JcCgd4FuCmU4awGLO7Nw9Wy81j9aK3Tv7Of6g20Fc0VrCeB8pe
+6DX2L7Acj87TBm6EJW9Eu9DLEMaCYb4PZ9vhEWn5LM7RZCxg9QN6jZ54L4vyFJLBqmBUkC1OFgS3WiDtlBHN22O85Z
+D8EDGbCH33E5Fy5BjPFSGEmv5GSCIG7Bk43lEJx2S45A40C0CecEZb8j1Dsf1Mk26ZCe514s59nAYH3hG2LvDHD78j
+DqT60Y40TDrD8SJ8M82EJErj6BKCo6ALc6MK6PXCw33eC6b99286OV69f2zqDofCAt7xS8tLBHq079EhO5QXG0GEdO
+9552el5T83dS7Ep8kj4fOCGm9XS5GhDTT4g0AKg4iMAUtE9OFaWEwbFHV1apE1C96J1pKDISFDZCF2COKEdDCr10NA
+BKd7hfFNf94NBUuDpV4vdEin5I3ApVEWd54g1zAF6c9U63rV2MDDna6mF65p7oq8Yp9JaBu2AAL4cT95v5lN7OSFT1
+3wZCll0Sd425DUf2d05Ee7krERm8iSGI66A23978021P3AZlFRI2Nz4IXG5W0Mc3grExF6Ex4tFAGbF4i8oX5vmABN
+Ai4BYk2937HF2nu7RUA681pwAPS52ODjQ7Fw5QV0nXDWkAje4RR6HZ9uUEbSFv05U5F2n92u96L7DX0Ew77X5fI2rj
+Dy94Nr3yO46hG2H0pABIW7I68tKFmW0v05Ec9yq2zS99w2eoExlBbz4lTDLh2lg7Nt1EtD0O9wWCmt9Mt12zEcfDMI
+BrNCfb8L9ELKDng4NS3SwCIWCy225G1dW5MR26eBPh6WL1TfEw4D4MFyxFUf2JN4Pb1ifA5PBYO3oYEYx25t9HLFrt
+F6178BBbOGBN4O506E9wQ5RQCuo0FOAe767uCL8ADGBelAuuFmGAWz8Gf0SA9Jd57ABdM1bx8kxDiq3BtD3o5V1FaC
+6nf7Ra0oH19H2CuAjtFvq1DT7wxDtNEEJ1ft1TW5uVA4z1UC43vBzk4fgDURELg3wOAAyEnG3SZ3GM0wL7Y0BmY5t0
+1An1sH1kUB1z6GCAuQEolAfm4CWG7KBWr1iBBGODkf4946a0C3z5VgE9oEt66VC8s94zb2Gq2y252UFTY0KjELrFYY
+C5wFhe1E5EB2BIR0Xk3p3BucDWo306CiGCan2gQ0u68N0FH72Qt63w0p3D9z0M58ka28l1378zmA5MAuK7rvG73D6w
+40K88gDbG1hf1zv0fpEVLEUh4VQG2S3kc7x8ELL8x3CqHBwB5uL1vp4vEANj2wx2icFB12qhFNo3R17023G7GGxAIW
+9EI2eyDTR6qM9lrFKTDMFF985ExFJ45bI3fV8IZ0mU1y05UeBCf3Cn89I6od4aSDYREp08QP0sX46W1zgFNWDsW72G
+0yC6X00CvEm16Z52ki34NAB6FFvDvqCngDOhD5qCAp6W03Iy95e5Y7CIMFoo8uuFsS8Oi0vY5et3bN0Ow3qV5DF6i7
+7u35jfBrn4ne2esBhR3RA00l8P6Dgz6NnEry93A2Dn3Sp3RO3MIE739ulCn8Byr8vq1jb3yR4MZ8lr1Uv3qn7rGGAF
+1w20et7w9Dg3E0g1Mh2QD1KCAlC2XgFxJ17QC5z0EfF6LFSg0HZAYNBO69JQEK78p7C8I9WK1R08lzF0U5Gn9NnAHA
+DFy7Xi9s78jKCXTFHr2eE08h7O55AO69ABO0CtC2dmACe3NX9F98s00YY1Qi9pa3Zt5CX1QP1yu7oJEFPGEEAwsEdh
+EsF0heFES2iq9mBCD90s91lU3Rk7ze3hJDFz24D83H1NNDeg56Y3XE0i35J06Zn7VaFHZ8wDAEZ51UEJmCjVDJpDwq
+0EV8FSApO3LO0oZ3V17q61Og7g1DST8Eq9Tv3XOFJi0IX2Ig07f5ev0Am83cEAt29H6tWDQb0YoAOP3HI3z736X8eJ
+7H45gp8MP5UN6wuDSG5pjArp9HD3Da6nx1ha9pd9BdBSL6KT6R84CHB1t69hGNz3IwFmcDUV2xSDBl9NH18oEalFi5
+7gO8RwEgABWk0J3EHRENtAxK9BwC3K1qY4h03nOBwgB5vCX45qb1CEA504LX1PL1d6FPWCtM38o95a4d47j121965f
+7OQ2S62Ir0uh6w2ADiFNFAXB7wXBlx8ci3dc7NMBEI5K18yP0P39dUEdjDvJ7875jLAUR9kl1Zw0mR1Wa8dq40r8Vc
+CUS2UIAG09Yg2vq9ceGNr0LGA8B0WX4AA681BmB3C47JMAxC3HlAiE06wG0eExxC106UaC8JF53CEoDpn1257Mb6bv
+DZHG3k9fj3IWFcl3J6Aup2r4600BbL1RM2kt4Cc6Kt32IEOUAsj4NuEY5Ce3DTcE4OA9S2J91jQFzz4IdDVbCgq8aQ
+3tp9fC0wG8Wq3Ge49bAcN4SKFOYDAx2h09Gf3Ts2pp2Z64EgAcJ05N9UKFkAA9X45DBG2AZ4AbN04zC5G2uL7GTBft
+6JtDjm4yw2Lb1nJCn67enAcQ6ARBwC0YS2cg3LNGJcEG4AN3FGzBryANu84oDSH79v0iCG9jB2qBKU6dLAND8Zi1qL
+93y4nkFN90vo2d13pZ4EVAIO8ot4Wg5Z8EwF7osG1xF4zBmC5R3D0QDnMFsq4cWDPF7GRGFe7PRDr10kM9RHGAHAOM
+Cuq9p2Do05onDZrFcsBE3EUD8Zv3kkFQdFQY3KS0eF3di5QhA2L19W0UNBos38U5TD8tgC9a6Rf433ELzBvA2sICQ6
+9k3GNX4kK5IiBul370EA16NV2zv8O67iZ9647AsEBSARGAu50JK3ie6KZBmO8BWFHC1Gq3EP8hjGH5DDCDKH2Qp9Ha
+0mZ9ObCij0cqErADI5CSA5jWF3nBVo6Yr1fYE3v3ZRFfT2Ck2ZL6GaAvGAuRACf4J00BX0Eb8Cc0JTBIQEbI3eHEse
+9m57fJByB3Br6JW7Pp3ukDrAAqNA7V7ZtCtW8rS6Gi9WR8Ai9HF2bv4LsCdh1Gg9adFgz0OMBA4FbADBh00X8QgAIG
+0Uo7lI3Dd9FZ9JO9z75fb9GtFcO5LB9YrE7i3qtFEt0vVB0X98DEHY1uO8YoFLb1IWAEp7o2Dmv9KkDa90yK1t70RW
+AgM0m66tgELtGBPEdZA0M6OR4fI0B700B1ViAHYDuwB6nBpwFajEFJA7H3DuAhz0lQ7X61dpC7S8tOEyJ0mt5Qe8sk
+42I1fp6NU1Cu0pFDMB3P109UCo08DQ8pJC6V7Dv1Wj9aA3CG4A639GAnj2xp57Y3Yr3wV3jk6w03DwBCm6Xg0SEBIc
+ESxDc607I5SpFrdEABG1rEy4EEC5kb0XzA1v4kfGID64aFGAALCCR82qk4Ve8uIG7y0sY50o2XABjb7Jb6Ib3yg8rv
+GCZ1qwBtp73w5CKAN45vEEbk4R37A99Vv3UJApk5yHEHX8mu7idGGY8Kr2xF7tsED59Hc6dFCBs5HE9OUF55Aj8Dzv
+7WeBYhGNC8KWB2u3Mz6RV3U9BE5BAmCVyEcw9em2KQBm55NXG8lDJA3wT3FzCkU2Kz2DJEAh1ce9EQ6AJFTOFi9EHr
+40j5bY3RYAbM6DP3fNDwLBTe1PEEsJDqR4gR7kt0BN6kVFjc5xM27W1Ql7VTEVIFGvAqCDIXDLc0dDBAD4by5405JU
+C2Q0A89vX3Y61j371N4n714XAlh46RBf1CeS6dS7OaGFt7uE3F13BU9hr4Nf4dP5TXD3M2Ct7ys4Rv6LFG6YDpD6CU
+5kh4SeFXY1vyFTz22a4mf4acGM67KG5uJ3P60JhCJuBD08RB5vp4Gk3lz3Vp1mzBfRFYq1nWFxQ7n700g5Ca8ftEBk
+73u83W9v04zJ11u7gq8ns2m37zCCo9BAu0HODf539l4JA6N02pP18pFBH8JK8pa6GvAxSC78Bx02Yt1uxDtH6CPBEN
+6Z4Dyq6tTFu764b60q7y6FB59B4CiUCAkCYiF605DIFi31RO1K20mNFeA9jj53dFIVCgQ1298vu7xv3KE4nvBdA16V
+AjyBMI3fnEXyC5s0ON1Sv8R09cl8kd2DKAQ7EwdDlUB02FBLC2rD0tC4d6ME1X01VMDrl9It5GeCiN2rI9Z4DKU8OU
+3Ai2YOE4QCC98vlDYxDNoCIV1CNARSATvEpMCmbEfK7xi5BY5ud7LZ75I0KDBmK1jd8brETt53rA7kAZUDSu9xcEIz
+ArXGBvBCv53OChd0ywG8DDKwBnnEGjFez9Hh8esG6a4Ja2BeD7J0DOAnk5p79muA3O06F4HWFZE5Um6FYFr3FEH4pn
+2uFABnBn53mMG6GG3qFag3cYFCMGDq290028FU8AL191GG5iBof9rw62G6skAnT8nZAD4E176aJGHW7nhANmAGyE7W
+983CXk3In03i8iqFtm1K83LmCm81unAxBCCB9I9C707Gk1hq0of6ChCgm6G23QH6gpAPKD6uEGDBS69f3AYUGK50yz
+6z24MRFCUFOA6cu23BCmYGJd7iTFOf4lJAyIBkiAzgEOg2Y99DE0o60px16A61bBLl0cGCgGAwJ4c9FFDC0C4pD8Rz
+62z7FWBAo5eL2Yn9bK53uBtOCJREhv4L5AywEbMDbIDmX0xs8yQ9W7Awv19t3PJFKG4Ll5Ae78X5vKG3TAYEF4WBuv
+6ubEeW1WX0bdAh0GMh9kODyN4Ar0yMFm23gWDqkFbPFzM1Ot2017Nl9kK5bO00DC5LClwDYE5iE5Cq7xX2dZDF4AsB
+FoV9U44DhAxy2B74yk38S9lF3Z12081kj8pF0Ty56VC6239b0sFE8mATD0UT8ZIAkJ2Fm0OCA645eH2kC0VB4en39k
+5fqEPZ57f4S91497eC7dO8U575b3Kf6U71bRFXS9TeAmd4RYDbP9wg2yO0LV1KS3B5FqG5Bv2m1FBe7LOEeD3f75nG
+1DQ0FlEXP1mQ68fGJ23y488EB9dAGnCxj9IOEh51bd3pnFVE8WD2RQDKz4NPDNgFh27SH7vR9PE7jICQZ2489Ye0Ox
+60W7mV04SDmOFoRG3R95DBStFNy9GW2ap8Rb36z04u1jY2xIGDs4VZFOk12v7dhD4qC927mm1pr1kq4UA3lp39jAqS
+DYc0ijBNQCccDKK35j4Xu5gP3ysATSCId0M2EQT0ly05j7ThCWE0aiFPj6b3Cp02YkENlDoi6jm6PoA4yEv91t4Eld
+0pkCgn5Ov4XA6mV1ts7Dp8oi09J2ogE8k8fY4Ox94RBvLBfHEIRD5V4gw75KBte2kYClNAAE1q2FcbCsBCnU0NeFwV
+546EHd0oU3EXDXE7QL31e4hO6wT1dD0GE5fA4Yz3vrDFF3cTAXN0sZAck2KS3KGER12rW70QAOiDHA7sL3aTFk50bD
+3Jq5zBDbJFwlCR25FF7yY0JwC4f2Zs04r23s2lqDxb1YCCCz2gBByi7nMEy69yh8Kc6sa9Q4D8e2AY6lFFPb8WsEtc
+1Bs1m65deBDJ6EFBh2EP93p12dNErf0194RT5dV7y03BW7DxBUJ0JxBIG80w0m01vb1Ih6mS1isGNZ3aLDDB0TtEKv
+6Oc5M21y4BU695A5IW0RIARf4tX9b57H2BLD2kb2Wg8dHDGxBYsDU10dMDYB72l6qA12Z7BhDXJBZoAuj3zz2z0Fsm
+4H312xCSC1N63Lu8FuFvZDOm3awFaHFdGFYTFBm7f470oFZx1X9Fev4aTAFGAOT4YH9OVBU16un9CEAac6ocAaLDES
+6R1A8p6JbGEADds6h89sx2899n1EInCJ70W07pNAyh9PTDzL5qP19h9LP29r56x7zo6vKC6S1lb4uNB1SEZ5CDU32A
+1nX7l7AZr3Zx5rcC3x4kS4Jy0dfG8L10W0J50Hf246ApG7TlFWZBMkA1958S6EB7LBAkl2h6Emq7Di6AI6IdD1N4w1
+4lL3BE2AW44xBM14wC5XJ2VJ3erA23Fax3BdAwfEJNFnf6diA9H4SO8Y25gZ9Wq6NZDsXAzyCSb96HCcx7GM67PBWI
+3wX2Qi5yb3cXAX5CwKCAu7I8Ck0B4QEsC1It4qc7yR5GlC3ZG2O9xr3gl0Ps5cDDQ74Ni033BKW3LA8gTFvn6LDCTS
+BLjDARDRt6Z7A1z1u5AyDANqEaVAmn5K74tY4k3CPjBti7cT6USCgf1csGDBDLmFcI0oK70z5f35gg1udEVd8ZpEd7
+AY58vF8PGAh99tjFuO5K67bK4nn2fD7sp0eD3J2DtW9BC0WxD42AtOCDjE5hCFM0Ia3R37isEUyGA28OwCdZ7ltFEN
+7LR5lTC3XEOb6uaAm05hpDdjDiZ81f45r7jT6GIBY06X92fR3b81la3Gy6LC9lO4Ju2vmDVy7c406CCFp9VDDO8De7
+2LEDGk51k9QrEfIDrJ7jw5MoFPe6ln6ov0mABMr7JTB34FVW3Ao5mgBUe9qU3Wm7WzF8HAl34FDEoy5oT1KjE3H8xp
+CeVF511Qz07y6oP0Zw6xkA5d4ZZE470Sb2fM5Ml1W03VD0W13i63ee6Hw9Vk1N8Evh3UG678BnbEQA4KT8o09Bz9bq
+FfuFbi8Q2FGUAMlFiLBjr4chAYeBp724O3lI00jCSI7viD7FAoi70k3kA7FNCyd3VtBI21FoEkZEwsDwrF206Q31e6
+CNLBAn8QD3ZPENn82h6FfCQX6uuAp7Esr2FpES81Lq6COG6oEWz06939Q5SN98X2Uv8ni6J3BeA1X4FyB0kiFBKFzk
+85TFDD0up3rk6gQEpFCzVAL381nB9NCSnE7u2pXEFy2iX755E8ZADvEWg0j3GKgFxi8pY5XFG43BXkD0qFDBEgs7M8
+FTQ4Lm5Tc6NC8QQ5e05hh6Vg8UGFF3Cck63l9sZFhnA9O2ry5LWCcuD1S6ryEsd2U498nCYw5i2EaE3U4AKD57T0kU
+3Xk3Oc6Jx74TBHA0wN7hy0V8FthEqA8ZGEOY79o4VyFIW2KKBtfEFjDLID1l6oCAcG9YmDqA0WzCTg5Ps7Hi4E1B4N
+Asz1Ii4QY9k63u9CLkBl55aK92G7vqDfo8TuCDa4F87FECyF1PP7JxCRh1bCFYU4BG9qBD8bC9cEfe3dV33GFXw1VS
+3dR2WLBv80Xv2qc0R8G1s3D46QbFAB1P630D79C3G164ACzfFgk4fWG6A238CoNG1z0vA7Nx8uP4059GjA6t1ZiBIr
+C3jEYEDDj26X04m6zL4yp1JEDIFFO1CLjECm0hp32x9iS9Ow86s9rv3HD5hLEgQ5gLDzQDMrEni1ciDWH9cP5MU7bj
+FhW9cqCgI1lQ1wLFjVBzLBQPGFTC0GF253aO0ap65U1ed7lT5Qf1z04gCAwo6onG2N6uYAPn3XL4qv4Gu5Uz1ToEn4
+04G69c4KDCKF2GL9rC86LB8UAQWAyj3Rr7dmDhv0n479kA8u7pbDANDVvEQ96ISAIICm5FnH65L2dI3Ki8QbF8G4wk
+2M82iRE7Q7QT38i9YtAijAwg4tf1STEGXAcS4wVFEQCNMAwtBfp6m7A79B3CFFHBU93N5CLm6tG1vLAVqEzf8f73qx
+9W0BO19Rn2wK9enEi33ymBwJ8BuELmEAjEmtEmZ8a6EfM1sd0k2FjY8CE8NC6mYFZs1sYDIjEorBI16lm9RJBK50N5
+EGN2MX2HfBOF7WK2cOFGe3Qc0dKBHSBw2EVx7kx9cB58cDJbB9uEk1B1l5XIGBS7U63Xz1u8AVw9ArCLn5De34W7bA
+9vx765EUZDzd2NZDoH9cjEOx7w0138DKe7r0Fx3GEf9IECM510a5Gz19Z9qG3uW1AG4RI32fAgVF7f3B75UKFMlFIh
+0sx0fhFmK4ML6VO0zLFRz5XNEv48Be0HIChs1DMBqg4698i71gI7GF0Rv0ST0h5FGh2lh5jvBiRFkSDgi0oqAtPFYP
+4iXFJmEYaCxq8Pa8CU8991205Gj6xh9w26wn9SrC0p8hk3aN1463nc2nV8If4YOE6dC8Z7hJEJV4ab0tvCUPB9I08o
+09Y5y20Fb5umCkfCRc6Gy4QJAdqDQu0S78cqF0F4piAhfECMAr99dvALT3GY55pCNt7CvAJB0jJ0QRBj4DNTCtO0KN
+22E8OKBQfCRY8Sh2655BtE3WFvICTYAv81rM7V2EQp5W08Q8Ckn9xpAPmGG88uVAvxC5i0D7ECTEMIEBgETW6Je2Yl
+AX8G7c4gN4SA5XTC57Cvd1VW8HG7XL1ZU2ArAvLEy5D1EFntFkcCoGGO72QUFVoGBhBdpFH28MTGIE05z3J4ASV3kQ
+GDyBDu47EC6QDUO0LWD3A0sEBo28fZExk0G44f258kCvT6jREyiDDvFAJ0aY0nU6739H73atGKT4ku1UQ5sFBxCBUH
+B5S7NI2gkEQh4WQ2Th6ciEUx7Po3jmFE30BDCax4ps80RCuz8LR9Y4FVjBuxDRF38DAUYCETEBJD4iCGc06mDS53Fw
+0o38HnBaG2reBXeESC2sb8EzD6C9MvC7KC2Y8b11LkG2t3rd85e9lo0Qk9G45Es8q80HU47I0RX1k4FUsBiNDqUFZc
+0DLAMB5c73am5r2ErTAoO9e5FnKFZfAYfDwA2V97nB4q3Dyv5VhFQU8Ph5mT5mQEqgEQ02pI7MHANiCWRCJ37YSDJ7
+0RCAil9ZI0Hz9leFqI3So3s85TK2Zc9Gc41E4cR0eSEcc8ML3Lt8dF574CHyDZdA135JTE2f68yDg6AVH1oI1iT8jL
+BQT4dL0ZW2zk76s6Xa9pkDuu7Qf3OY1ThBReArA9FUBGD2usBjn8wZ3yU0DJ03M6pv5koCycAfS5q930AA8V6dAEsV
+EOfBaI74q6JF2ShAC140DAop9bu5ek7bx2G8Eeo6mx0oF9QM53BFmoCyWCFnDV446EG192C69mjEi89G20yeDoBDeG
+FjiAPA9Xi5P3DSv4oY2xz8aR031EYzF798fV9FK3Cb2yvBWWE9aCDzEvSB1p66HCr92YB4yx9rDAKS5wm3i8AwT131
+9KMBeB0af4hC18t61w93JCbA3w19OOEasDI15MwDOZ9Ax1dY9tf30u7Mr8Vn4uwAjx8ip9ufDJX0YH9UV7mxEKZBOP
+EYw0wE2Cr31T2VH7U50NQ9BJAyF5H9C1MEr76DL76jCK39AyGF0DFUDN3EYm64E5kj2YPD7W67l36205Z2C7A1J07F
+6zE0A47m96kc439ApbBKRDOw5bT7yqE3y1I5G8V8qQ1NR4GQ5Yw4ayAV1C4I1By5XmCeZAPx3UuCnW37f8zT9yE7EL
+Ax94rREva9LJAhIFdg0Kl98L5c5AMf1401yy42H8we1ks6a1DPqBIaCBCFOE4j3DeZ4D0BGu0Bs6AUF3V12s3FOAwC
+4B323e6G3ARu4EC9IC5tQ90C16m0Hh0XT9j73S77DF2csD939oA7RICclDWN9374mq0H9GKb0v8EcI3rTCA8GAX5x2
+9HZAmEAKyEBK9xz27201BCSo7uI3xO29UERA1aZ0xqAQR1mo9mlDct4mYFRSG6U83J679DVxCsC58839S4UK9qlDFj
+9Sz7BJCHBCgMC9NDKEFDG0UdCQq1m0GLV4ajDzzAPg39wCH27QD59jGGg2J73HvEmlCkNFxT3fu5NfCjfBmWG4QCw0
+2QYFFmDPe8wY2zw1JaA6GEsD8SQ1sGExd9iA2KjByFBMbChwB8O9Y8Drr6Nz0pz8hIDD90OF8IUEYT3q1D6533wCql
+1xV5SKEOP4Hp92UARw3l05uU1Ph1iLFpQCpc9GF3bc8zg8sYAg76ga5xG82S7zyE2TCs8FX585o4PM8bd1A2AZm6BC
+6q98bM8Ad8VJ7Xu7YuFxx3lq0u5FOX44Y6F49HdC9UEPFC8uCea9rqCsE1i5Dcl6ia83CEkHAP5CcK9aZ5Zy4YeF3X
+4tH84H7QBA3V6w59oz7Fo67tCBo30Q0co26L2r876kDOb3ydA2n7lP6z416g78a4fbCgjAwuCjaAcWEC74cE2o7B31
+6L7Bs44ng1Yd24S9Rg5NK5jJ4r28YlGGWEq2CJM8ffBAgEIxCnXBxYBJRAiH8am7eT6hTEwMCzR8SIBoF4wfAAm01C
+Cls8DVB6l6WN4u0C26Dnp8oF0tU0gq4hK0tr90FFJ74biE8gFo5EMsBO3CW1CwX4Do3EL1wC4fo5xg2JHB6J3vcCLC
+1VG0sg6H5CHN5gvDczBtlE8G2fL19ABxK2GG3d50cx1mFDCp0Pv2Gs0iH7GiAKOCRn4cN9DJCKU0H020ZApr2jE5PB
+GKlFjSCXC7Y51IH3hDBfVDWiG4nFpcC5q623EFA5Ja1hlFeuDeyDEz0Fg3HLDSU9Jo7GEDhHAkBBkt2neB9v6jS0x7
+ELx50Q1mE6CrAPc5cFDNbG9n5Ym8eqC7L2oFAhd5oz4lA22U0kAF4s4XPDPYDDaE0SCsDGICExaFxaFj855V2Vx6Y7
+BMC0cW1nKBJgBTG1fs2Dw2JYFfC6Zh5yvB87CnS3tv9kxBXE0dE01N7ih02VGHBD8n6wD7UE626BP77ppFii3U2DVI
+CioBeW4nhFdn1jEFOt0kQDCU3nnBqF4k02fBF7KAnSC4R8Nh19P1hWAXdAJp5Xk4G5562D2T7gl5bJDstEqHG2h4ap
+2Aq36wC7m1WnFloDnD3KRBB03J3Fr03Xh5LJ34BFrWArB0Bn7Tw03y50UEMo2VB2q4AuCD3YEqf5BJCuOAcACs6E0m
+Edy4Bv6s6BoV7yIC7x4dX7dN83ZFSWB6Q5WAAzF18Q8S8FdXAzzDeqAvTA3l6Gw6Ac0Z07x6DGK45ZAHxG031qvDXV
+79a6iM2hf3qEEFuAtm184AcC27J29u4Op2eG8r22vLFbwEQtFkr7679Qp4su5xkE3e8d12Np3xs5XM0y0EIc1Ip6Ho
+0Po4qsAvv3xjEQEDKX4xB5n64ND6hdF39BHED9fFQMAob3RzBJm4zF5RzDQEDdSCTZ8IKDB9E5p4DS9Sh2yZ7KFAo2
+6e1DFS7ZDDzK4xa35BFirBi739s0CFAEJ3mV0BpD8A9zrCBdED9903Ey3D8B3sk44c2qf3JdCxU6A89efAqvCzj3g1
+4Wm84ABc7EpU7Br3Sz2M97rQ4yi4Z2AIhDYW6O85KF4Mu4Ks9WQ4x34VE4Ux3BsEUz2af2lO8Kp2JrA6D962F1U7us
+2ZI8cF5ZMArr0PP8jw0Yd1GIBpY6TbAaU13kDf0Eoc2UDDaq96t5F68rU18l5pnAJv4j09ge5cn6Sy0UtB3y58o5O4
+18hEFtDFWFFVDpH16RD2VAik4WJ23UDtOBTI2qY4Wb3ViF5eCzXAcx63DExA3du5OB4wsEfc0x970I8kk0Cp3mn9Ix
+FuzDRkCfB64H8Jr3839pGF8Y2tE7xbBne7ip4daGGw32l6wOF4U99J8ziE8f2b65FmAE96Li4HR83GAy4DO0DBN9E1
+3Kd4By0DZFsVFnw76dD2B7oi3DL2029N14MqEoIAgA5qB98CESY5Gp2NR1Lg9ST8kR9ri9vcE655jR4b71tyE6mARs
+6go3lu8Kw2W67HD4dp5ocBOCCX7E4d47P4YX4ra7ln2ia8LgGLhCFY4XsF2J8sf7vX2L50Gp21g42vFCD77VA1R8YX
+7g56iY1RJES37Uf4nc90mBRWEMF0Ql8eC9t72KxBDz8efDKdC8f66J6Jw8PIC74Cb5FvF6Le34EAblCJT8X81De592
+6cn7B20fD8fGA2S6f23pJ3Ih30G8yhFvEFuE0qlFrYFsc0Y54371iVAdcDFAEBb5YS1VnBD4ASH9i20JDArS0PKBdQ
+ESPAPtCT67gj9COCvuDdADNuEkI5uO4FX4YcBAX4dnAF54Wu41cG8w4Hb8j41k9FLN9LQ20y3GC2bR4sc17I42RBPj
+3oh7Gg6IJ1tYF9p5cQ0Fh7g39Kl91XDFhDUL5Oq2Ot7za8C24cD8C6ABV2HcAkRBMnEGK4T82I511h8yJ9IV9AbB2V
+8AsGA3DpaBro4WY5J79IcCtr32Q4VC4wi858F8OBMAAIX6ItFuxCh336rE4i8OA7kaA062IGCXj4Ti4M8BRjG4WEqE
+0mS7s66dfCqhGM9Eoi668Fc6CDYAss55t9PtENx2HJ4PAARQ6YM5oB58LCNg1rF4Uy7iu16u1iS4vK66g3sB4cb1gw
+Dl33yeEuq0z2GIq5TfFgq2JjBGYCzx49lGA129j4Gj8DG4Cr57g9fXB2a2ej5hM0kE3XGClT7LyAQBFnU4wF1Nb69S
+G2p2JR7fn5rNAHzE4J03JDM33Eg62PD1H67n46HDkC8cf49yAJa7GI7l2EeG2U30Re1NA1B00Md8KZFka5os1Fg5jN
+3xGC346ugFNQFfL2oi0zm0a77IFAAf0JP1HI6UCFR91kH1Jp6IPCd93ZJFKK4dwCJx49pAvwAATBBh9YW1Eh766Dqd
+9FP7Pw2JK1JF5nlAwb3hbG4GAQaD5fEpP3n29hQBKq45H7DU94mFDY4wdElT0x5DDu6Hc6ZZ3LG1KlDse7ow5r838w
+6we4AG81D2Z40N62I4EzA5og7EG2Q835C8Jy8gA63jGCp0lp4z077O1SBEf87o6De81FR2NE974ApcG9c5DUEqw1dF
+B6g9gu1cE4XhFLQG9y0jr4W82Pr25K4BaC1BE0H3jpEqV1mS0XX3l82o9F5u5jjFMkAYkBGU41NETHAm7D6UF1FBk9
+1jUG4H1xm1YB9Xo6r3ECWCZJ7PQ2Qo4EZ2Ez2MJ8dBB2h4glC4q24t2BjBcS9RA1pyBqwDKP8BgAor6Zx5ilEzZ6ju
+8Tq0Jf8lf56t1oP9pg2oN1Hp17j5GR1FWCMfDXLDyh7eyERd2r36Ab8CS6iAFtw4BNG7P2rL1ne9e7BjuCY5Ada1nc
+D6H5PpB67BHO5sl1QG8AKGM8EO16jy5nREiRAJq6Wd2bs6k01hZ82v0yvFtp4zB8zY0Nr7i85XP0mf0s54MHAnI9l1
+6KI0jO4N51Fu50HFDFFGQ37JBDIFOm9n72yg4uaBgFEcAD1LEDV56fBqn5Tt6zaFG85F3FZA20TC2xCxXCSPBY6A7T
+4P18Ks5rzEn55x68mo8m41AeA17CpO3EQ6fn9GbC9RG6NDmt0Ib5HMAr3CmE44l4C04rh5NY45v0YwDS9E1iDTwECG
+5JQCvhDsy45KDGdAqg9Fx5Hf7h16RK7cN3IxALu19MG9f3DX2hmCIxAHJ4lz5b246Y2HP79R8Do6998ax7qkELX97f
+FvQ1YE1AwAC7EDE0vv7BLF6lANGFzpAQZ02l5GQCmd7hTFtP7Hy0Hb8PqBPv6l18J07OiFNXDJhBhrDrwCSq3QZ2be
+BLL4vHDcBD8GEboCsOFY51PFAks2dC3pb9z3EPa0dbAj12SnFrl22d4DWEu1DPE5Vi7bW3dM71k97hCUz1q4ED27cu
+48KAlUB0eBaKA1G19D8uRD3XCjKCxDE145zv2Ix47BCq02P64l40Sv0LtFBG1Fj1pH0Rm67O1sa73L5ucAXF14oDrg
+1JC2s01fk0Hk3ws6nXFnB40kFld49m81u8vr2Sy94XCkI9oM1BZCma4F9DrK0NV8R2CkXCeo1k8FiN3CC5Ah20vGH1
+1eu4HBB5y1fx5VaD79CwN8BU9ux6oWGN737DDdT1kN7qX6NAFMY3E359i9jtDICD3G0Hj6505xCDus1RjDADDJyC6K
+DwcEcd44q7pq5EyDthDlFGEP7UlDfk8gp3pT6FK8Ce14IAZt1dw6J60fY9z9FK72xm74ZAoT8bBFx5FSN0I11tT4Ga
+FYbD6X5np1xh6t3FmB1IQ8kM71I3yE2Pa7hX1Ke4BB2Pf93sEXkEW7DRs6Yb2kjCsHEmY1gJ3Qx9cY9ed1qqCXH634
+4fY3toEwJ1XoDLn7HYBZw5TT9Ys7611oTANLDntGG63czFKaDMj4pv7WL1qn9e0BVpB6CF9V5eN3pf55B9wB4SlCTh
+7r7Bbp92Z7mg0QAAlN4RH7TR7dyDwFF6N0VQDz3DN13FPG3zCZjFgm47f8bz5hgBinFHtGIwDyn3Ea0CH2hb6Pa7Lf
+GHS1Tu8mPEEqA369jD8QXFPJ57n9Td5LjDGa4mOBDWAOw4rJ90N7QF8r9FEh1RIFtt13a3dE4C9A2IBGQAwn3a1GJY
+28I9n08uN81i8Bt0cw2pr7rqEmjAmzE58DTj6uO5N805M8CFFHI1YI42p2UyG9qEBx0sT4lB8xn1HMA6o7Ob7rn9WF
+AcI25Y9xI1nh6hm2JDFfdFcF8OYBM2B1n31WADc6ZCDsb2YzCeU7QhBmDCmB89lEje3wEEgf7yK1x8BtsBl10134qm
+BNmANF77w5KSAyl78qCkLDfsCtm00h26n2j16QB3os5rV8TG0Oh2WE1PW7YsCzgEhYDvl4DIB0F7WjCuK5zs7xnFlL
+E7A6Jk44o3Ls9iK6ezGNwGDnCAs0zJATsEsY58K3et2n6Eg7Doe4de5fnFpWA5q9AD3Vl0717BVCBR6ZfFsO2K89G1
+4CM1BH0wK2vC7rc4JD4l84XH9ED7qd5ESAS2AYxEBrDh08Mv40dBjS5jm9o6EHP3OOBCjDHY7X56ZN42x71WFmZA8Y
+9DGG0MAAzGDcBmpDoCCSS8my0eO0IY3ra0vbEvdBpS8LDCCEBFN6ROEVMBZY9nN9lR4hB7xAA5I8YJ8SbFvJCeLE2m
+FeOBSl20pFbpAeR7P0AfoFrR6cA00pDOJ4RjBPT8ENCqB0fwDWyGDfDxo7r9DTr2a092kBIm34TAVoCYABUq4Lh7mJ
+3EHCz4ChP7VC9xYCXPA1e9toDVf6a9Fvd9Ls1opA6xCSQFjh5aY2lS9UD1We6oV6HCCDS3H6GETBnuACl2U62O3Ai7
+4uo73ZEsv3MJ1tM1nM4HGA3gAPLA6e4YS0EzFD65RN5EB8B55uZCRU5nuCmo8cjD9UFzyBghFsu9Xt6G58WiFGt3OF
+2ob5tvDBkEwuFQW5pp03kAZbEQw6IX5D96hy7goCUg7nwGKqEbX54J18E3ZUENSDSFE8u3WqF1q2i02FDEYlEBe7EA
+EbrEvr0jY2fFFdYEILG3358b3ez4Mc5Ws4WS2RhC7f2uG2AN8D3E6v51V5DVGASA4IBgu6gB3aXEi09O6BrV97O4bg
+G4Z6x8G5q22g7nFBhbFQgBsd65Z13g86W1G35k02ow9lXFjQ73c4pA6fV3z25A26NtDZpCf031LCERDKf1Q8AY9BSK
+AK20Ea3Q74zfE605ITDUFAk60IT5Oz1Wb2Oj6pP0tzFue1ATBOoEAOEfSAA7DY72wA4y89doD1W2LZB8qBNvCh20Yv
+3Ci1uM7icGIaEq3E6MFWL7qZ0l24jJ4IbFst9Dz1iN3QJ3c42Xd6MbEzw2qi52H3HX2WK5GHEPW0ih4We1CY9oDEsB
+7ML03WEEGDPd5Cm4mG0pG443Bk8EhP8MEDwT8ro1xB5P87bd48uCCT7v3D4t3hQ55DDqDEjw7Px4yr3PUCeQ5gGEpo
+5wq98c1144cs39t5PxA0l4KECxTEtv30n1qC0xwBpK1lcFaw7EZGN9BtzAEnF3540u9kH7jN9nR3z15iVF6X0I58mB
+EnhBBCAB94xI4RcCXx48z6WoDRlFmu6SPDdZAfR6sV3xx4kc1AdBYIEKN79uGHR0rAAaC2P4BxnCBx3SC5e60y435i
+4ssF2KEvp5cfFOz1GaAnUBSH4z82CG7Lk1FF3LQ9mU5yu3Y3CG84uS7MY0xQ7hZ2FB5zP5qN35AGEYC9n3E82xZFzu
+92x5iH8AGDGYB3Z6Ey1XPAlu36B8W26br5vqAaf5zO8qn8ZQ7dqCdx2XoAOzDBrEbL7iJ1hg0jw6PfE7JFhK6otBK4
+AnnBbS4TA5wy4Z0CKt1NnBtaDsG9cT5kU1bqFc52XS9drDujCNw8u27L04g5E5JA28GFQCjX3xV0hd630CNN54DCp4
+CvgEMj3TX7DWExKDNa49R6TIBXi8fR1faF5z2HXF1ZAZZ44L5va7681jxF9m14tF0VFlA2Ww8pgDmgDhj3rwD29CPd
+CrGG649jO6xGC2c4r1F5qDuQBqd5US31vExp35yDYu5c08MQ8BE27SBH50rLBFeCIPFDi92h8Ds1OuEQXBkGCPgBLB
+0551qWAAFApiFtIEbY4X37vf4c5Aze8t675v1uYFSM1re9lf0eu2ny9qT0vqAJRAej7q2FGw8HcBI73iS7DQ0be9bR
+AvIFRK7Vg0r11mk4Qj9765CE8CuA8gEJl3d34Qn07mEGM1xN5sLAkT1Ks5g789MAlG4QS15UE9758F4QZ08rBxz4xK
+DvjAH3310EZN8jfGNF4p02G55Mt5ro6xPCxl3Jn7Hd8xfCFJDjhFzf9RED8WAQt1sZ9ea2bVCRW7wa4EN3hFCMY4jv
+7sNBRN2yp4c6593AUP34vFq83UyAN1AO97p6BI83Re5048hNBPL4N36ZuDuS7bw9AJ8cLAfQ4IK96022qCap9ii6HP
+GJv9KC60S4c1ENP5z83LWFsyFmJ92090B5lF1M76QM4jk2t1FHJGKjCCPDNf3RS3jM5t32aw9qa1NQDLz2vOBBl55O
+2Q63ES2hkB175gO3XUAWU29h94fCeX27GDznEdxAVQ7IcFMjCHX7GP7bVB4dCpe3Lc1rnCLXBr17li7r1A0p4EF1GL
+G8Q5JfEOB6GYBAc1GeCbbF6Q6AY5t64sMFvG9S6GIb4lvC9g5WkCZZ9o36qD2z843W9AB4OT01hCzYG5hCIf6JB6iT
+2sZAJdEb8FJhCCU97mFvmFKq8EmDEoFVG2BFEh3FI781QFnG2zgB7TATg6n4B848ZCElZ6RB8fJ2Tv6ZT4422w2EB0
+AaxAeb5ck9btDHl5QR8Po9FbFejFZD72g2TY6oJ2on2LY9tb7seAny15C17T6pdFkEEHw1tQ0es3SnF2uBkZAbb88v
+9KE0YL5rM9XmG043qW9Uc1XM0CM2Mt80rGEt4WN4yqGJKGAD2QM6WT9eZ0h223nEnX9IqAqbDNWFeIElR1L7CZW1Yq
+2FUG6s2w60uVENdAVz8a2EanBzIBa3DrdCzO17M8QL3z644S5Do9aT6UGAgoACQ5FHABO1uT1WUDdh7p2DIq1J843m
+6gy3z5DwN8pEEm87kP2eB4bS66u1lZ2bC1AW94B38B1a98dY4qq9AQ0e7821BlDAIL3SeBop2OMEK1CzZ3JU8kl8XO
+FUTBeX7K01pUAKiDr6FD4Crq85JBQRFHq75A9MlBQj5A0F6WDxO3ckBej1yK9CRDcp5nC0D078LBdG2c2478Ar6FxK
+FUd26E8u35nm8qE59u9ZVCzu3zt0NwFrw6Bb4URAGu8d63kL2qg4KGFjN5kv9hcD4r2Bw43hDye7am3zyB7u0f54Lx
+8yK3FS1BUB3TCmFBV0FoS3yn81kBBwBoeDWGBJ7Acg26g42uAbV8Qy7Ju0uJ4fwF2hCTPDEm4Pz4uc2iEFd10nkFAp
+7Ml3TO9mp0SzFkCEl45xOF5O4HIA75FEP96Q0UWFlW8FD9rZ3vDAHo6rm02y5BbCZU0ky69I7ba67K7n25j398l1N9
+8fEEzTBzn8i34749i69vM8xT2Vw2LJBlw1dX6siF032gn41V0Hr3SxB0P72mA0V2We1Mq9IXFkZD018hPBN74r58Xb
+11qCdQ4oz6ZpDQVG2iFS522CEQQ7E03W6CIi7CTCeP5m85mG7be3iB2Uz7dlCYd4JH8q37r26Jf7ra41ODji2pQ0Lv
+AnO42qEpp3sTC6L0eU6JnCTm1FT6kfCLVBW2AoY0jSC2CAYsDqm60C2cn5cS7o5D2a4uj5Ew3U14OVGLp3ywEYX90q
+A3d8YI117Dw39S82nfCvVElWAg08X150tG1Q8i5AMK0sp5YF7VrEvQAxg6ydBrA6SA6llFSOGAI0uFELv6ql6Ry7Kl
+3aF8WI7YFC5k0KT2FHD9sC8o6Hi5PWDI29sV5sTBMD2LdE6oFAwEA8AiGEEk0HE6Hl5OZBEf2XW8WLBcV1eGFS4EDY
+80i27D98u07xExDDld2njEy12mX9aB1mj0hC7sx7aVAKJ7qHELo2kmGAY63ND8c9Io5PJE5W2ab38r3W30OpFH9EE0
+GN6ATX4yV7153iG3Li9US8wqF591Z353m5N63qkEyo72x5ZTEhm2gF3wM72XF7w61a6hKDASFVM31Y6Co3ouCMI7oc
+BL26IaGBeEurAC2DDz4197POFIlCEI6f58ov2Ae6mJ2gH7PhAKR5wI0gy5qm6yY1hzCjB8iLFMg91rC2T4VK4n14q4
+C412F87gU2Pe86VFuh7jE0GYEh21Yx6AB4KY8WW3thATbG4O557175BtMGBjD06E0W6cv5MO6hD80U0fsG3YG1a3L4
+ApuCnL4RsFpvG8UElr4Q14RODehCOn3PsAeHG1H0xv43P3sw2bEAVv9wlD3jBl7CGrEVpFlm3uJD4c7Rt81x3lv19Q
+346AtK9P63Fd6glCfoF708Ip44ZED720nFJQBxi8xv3aiEenDY37oL8XV8g0Ck59wpCdg81zCbc4MYFpq7mw0wO2SU
+2OfED0B897up13G7nI0463CpDHR2zi0hDCzU7z191HBByEZa5Dc1vK0M1CYBCfn2wHACc8T53mE7cy8Wz1qz3LRGF9
+9g1Ap497t1eQFou1Fc3wx4sn0vh40RBF08tuA7W4GyBUSEzyByQ8bS2fo2wi6FNDpi42sDAG41IFlQ7IM0re9mzBVb
+Dmi45tDJ9EWJ0ZP0o5CYO7aHCQJBp12vo5brFms64G8MiCct1FIDt7DrX0aZ77a5VA02uB4g5GT7XJ0Ek6T0Dw7AjS
+ACi8xxBFx1QTBd26MSCB16z0GAB2hPCD21ZYBMW1NGA6f2K4Dr90k4FoP4rfFt7BDn8uC6GK3RNEBt2Bu7ml2oE2Xn
+7dA9LN5Af4qHFoU9pi9EKCwA6Js3jz1D00BlBGC8h75O07ez25f6IlEW69UfC218gf68p58C5193IL8jA5Mc0ht1Dl
+2nP33J2qm7Q6AoC23bFim2oC1lJ3dm1F24Dn8M7FBJ3sq8NHAXW2yEF9b36t0BODdI7Sl6TV0Et2PSBq13tr7MV9Ni
+A5Z2ZC2fdC0o1ZI4WzBT4FV0Cew33O0SNFL2AxcAsT4OkAEv6s3FMh7ULFBc1mu3elDi36EmFsN7M60f1AvdCsw4zm
+2CwFh03jL6S58ST9uE3KoDO3EvB6TvCISDqo0p7CzE9Ew2hFBGB81rBOz2ikBVBAxrG2LEIUAlz8RY47k7M186U5Kz
+A6SD4TCmm89S7xEEgPFaS3TdADFDID1yL3Ca2aq6aRCq4D5rEkiGO28MO8Hd8XZ5IL4I13ni6nQ0pb9NKCORFqk58Q
+2zb3td2ju1FzBmM3TwE5DEyZ0or1k37XXEwa9EO6xVFEC2LUEmJAOH6cDCYv2bT23m5MV7CR6O0BxwCLi2Fq4sbCTv
+1l72IXBbH9BDB4CB7O0ez9TX5aZAn48aC7Z9CyY7ZR8gbBEv2ER2wR7kG6VcFNT9VO1spCeA1vfDFwDrxAktG97CtB
+CcMET30Bw6JM2kU33Q8bpAVRDUs66bCd1D8ND8wD2n5JoBE93hr1wt7XFCyh9xk7Hx0R6AYOFaTEHkGGhCoa7rt2Fi
+5AzFIU9J31Fy6Ki1je00NEMgCWi6MZ7Fi4w3AmS20M22I3zdDRjBlg3pR5kl57m6YXGGSBEwAvq8tTEAW54856GBfK
+EYD7b6EzcCfl4Lg2o35xS52qG1m9o813K5ea63B8at6FU8Eg5iw1YQ2NQ9Rf7cr7V613F0TS9N9B0m4r9AV91yVDLp
+7Sk4S3AGf8ll7BSFan7de7RJAoFCnyEzQ6764RK56X0LZ09NAF13w3Bj54oF3YNA4p6JZ4s9CxcFwODlJEcq9JfEKH
+Et71aK4m7AW2Bc8EdA0Hu3GJA8jAtZ2HhDVR7O8Ds15ph3WpBimBY32eF8lEBMwD4CEVe1wm88u4NE60TFpu3JN2Je
+Bgm0bI6VeFHsB91G3JC2s1vDB8w87U7hL14u7wd3kC70V73M1SmGK3Ba7DIvDKx8VlA3I4BdEOO1DV5Em4HH6gr3v9
+4FcFW27eR7IRCZt5F2B3p9yQ3PdCOl3XDDzO85zAHU8NQFwy6xZEmk35RDft7n9CxNDf34pLBib9rnB4589E19Y8Am
+5yR0hQEbCC0M7XDFdo6IN7AU8mc5fUCgb2M06R47El2K028V4T1A1TDsdAHa4AE1KD0Ym5lK6869p3AK86Nw4kF2L2
+G3dEVk2ty9NOAV0EC0BW74M68Y67Ql0oXEG35bzAOA8He4Ex7ki9ddB4JCtf5J8CFA8kABHw8MB3qNFgO7AeFUh6ts
+6ve4ol3Lh0z4C0h5ZUAjBG4xD4k7vxGCrAyf99n3pw1Ic1U49I3FyC8M98DM68VDG72hwBJi4bT6dx84TFui5lvAMF
+3LDFXEEQGEjDBjx9yDBu5E6F7j6EPt2xwArVC1REIS9So7LcAEQ6JR5hj9TL8VUEFg5Pc8Ne7xr81F5g69oL6nD7ma
+Dfp41mCfK39YFpP3t13vvCeGBAs3FK8FE8X73Yn0nA5VF0OUCQv0Mb5AXD8S3N08AtFcv9kn9mD5UI1MwDGu7wgDZc
+16t9r8CvjDcD9VYBkc84j0q1DEA2Yh4k22wm9swEFlD2P07wD7SEhoFTxCvY1cW2vhA918EuEZr8Z2BtD5fX9QO3nG
+7XS0uUA4j5gi9At1Wu6gL6kj5TZCv327s1lf4me5DqESGCH1BDVA3W98K2sUDtz7TeAWGC8XFUlDJe4Y94Qx8fW1yN
+8hKCLvDpXEUC8DF1yj5o54KqBQr8Aw3PvDm2AOg08j79UAml9s865X4lY7kTDviG681jh8GeGLf9ybBu4BDDDQeCzS
+7aUFDb8elAWk2pt97QA4N7GC2SsDwGFCl3iY7ykG7p1nCDkR3OU5CpC6I112CFG3kU8BR4rk4E4FMuA7jFufA6R65V
+CXS0nN3lT4bU1OV93t6In0DQAo3A2lDW38P7FZS2hRDWR8484ew6RA5Fx8DC6fcDzl5zJ0GI29N13P2f7BC47tO0PF
+2jg8Ch2Nl5z49zdFKyC1b3Xt97uEuJ7M55rl9TY7jRD27Cz654N4GC9OnBxO8MH4VTBrR3xq2t80aU3es1leD3xFjL
+F2Y2se4PU3t72jBESf4Y5FPXCHM5XH4jfDgDC6vBskFddEzkBUODDEGAaAhw4F02GO9CpCJC86DGFu5p35oC3p88I9
+9HG5xP5Eo9XyCcP2vBBT941P6N20Sy1jpA9Y4ei7it49nBytETg4puCd577rE7KF42FkP0DS78GE4g793CufFIN6ej
+EXzFh1A4AFCF1SC5cU5rX8fp6TD1EoEFO2Hu4k669n8Z68yC5lzExtF8m2YD2gK8gZ0uNGLIBDO4Sx9TEAA87zJ53n
+F5mCczFEI57c7BUD961KNAv2DZO80d4hl435DVDA1o66hDloAKF6nE7vsF7sChk8BL4dYBpPFnb24j9kt4NTDNq3xe
+6VRFQB1NY9bdARK8WY1g32ai6OS8cQBL9A9h8641DoDHyCSi5DY62DAceG9334ZBbG3sV0zoDX3AG82o28VB5PLG7Z
+6jk6qH6HR5zdAv30HL8Cn8X63VP3YMDUzFV97PrB7QCST9ZW3fZ1LH9HP8pG59Z1YvCfOCYNAqw8rn0Co64R0S3D5l
+BdB4uy9kgCzl9JIEXe0Nh3tXAD60DIDrB1vu6BhF8a0EB9pH7yNDPa67C55w6OpETo8TJ8tN8yiDjUB5pBZU7vbG5S
+3We1j5CK1FA0FaG4Nk1fU03A2Kq25jC7IFro9hJ499ELZ4X46cO8JfE2t2o5ABUBjW4Yx2p5ENY9bg2fx4J7Fhv0ii
+CTy0eH5su2pND6S3nzDnc4tu1aU1gnF1MC3QAKW1Ox92AEdBEWYDUe5KQEzCD7q5zT9tY38L0BfCFF4Au6WS5GI44W
+1lu5zH11TAL0E862dR63E7Og5y42e424e8JP9eM9ct5pPEKo7wh1qe33nCp8EUuCfdAIU6wN8QuEvH7IK5RHGK014m
+7j268217N6h07EPDhm6QpE628rP324DVt6uh3XC09M4iwFd88XrEsS2zP96vFol5hqAV73XICVTAvf45281OCa42G4
+9FYCgT9Ta7fu9QRDFd0oP55e8kI9WA2Sa0Wo3fd7cIEmo8r3AWB7gL8b60mM46LAO63tQ5C28mV43nAkY3fQ1C3EWE
+FNJCrDDo35MrCgS4077jS8a36jc9ZD8dj5MpBI3FhN8uhAkW3z4AbHBTf6BZ9x0FGNBBS6gP3xv1wT7aW8Hv8Bx6Yf
+1aO4N29RL4Qq2jN8CB2nx5ZR1HF1oMEVX7nO0UGFrQCDe9qS2332d2F6z3yNAJ51lwFOj30F0Xo7RL1HTE3q0QFASB
+Fo2Frn62sFpZAuD9ZjBT8BMmETI6qiDgAA0L2JEF15EhB7C6AvW9HOAhqEm9Bjg7xC8zQ4LP82p5bE2Gu8K00wr6sz
+CrEDTKFIYALICu9DAf8MtErx2UQBEk0pT2m9GGL8ZWG9kEom4aZ68kDmI97S2Pm6Vb6TwDcV9Us66Z14w2DS9lE3yv
+52F3R07aiEvc1EK52Y3e54US4MQ2CY2zGFrc7Rp3Er3nY2Qm6Oa46n0ilCaRBCh9CH5hRBV78I44Nb1TiECO48n5n3
+E94EN73y6F77EHGCUW3M818ZCbt597GCB6Nl5Rb1wzA6ZC0t6Cb2ndAIu95tEtT8sw9p471037RCkYBvMAMo4L6DBt
+88jAZ70bnFsvDje4gK7Hl8109EYBvGDxzEU90UH5I2CwE0pCGB67GvEQzDxTBsxGMN9cL4RZ0hmCTt0TzGMqD4vBHn
+BZj7Yq19dAUFDhQFem491AAbBJ08RV51514V8BXBQWC4F3uw210CLl8Zn3wfCS97UqC91EZCFkO9wTAo4FYGFKR9np
+Fk9AoJDyc0HX9Zw5FVBTk5Ve5ad3JYExzEKA8xt5OX4ZF8CbBq9DulCt4Bec6bD58P1N16fmCSxD3050L7U2Alb97q
+4fHCzqFnP1ZfFEzDykC2q9h00P26ZM7SFFCE0sl1nA8xR0MKBMN1vG76C2R19Ou3BM4KN5Pr0gk6s5FBnCtiBqW1U9
+FpOAqkA9BGAPDJn8QH6VP3Zf1r6FUI8mC8aq71w0CqAmi6IwFChAs01Pd0lHDvK0tk596AGZAwA8bC1ua9ZLEI015u
+0NKE2QEBUBdu2mgDWX75OCFN4yj5xN4LrFLVD9O5Sj5a1BGq0G734o0OW5SXEMpAE75d637UBtSCe2G794yoDeJ2s1
+D3I7leBSnC2AF4PDXsAS12k524WD5K6rUCHl11c2JAD9W4jM5qe6Cm8SB8WF0MJFXf1GlB8y1k0BQiA7w8FP8PO7NZ
+6qP1S37uaB5d8zX8md3mxFiDDEW9D6ASwE8wGEv0xUCB5EraEil7VM56q3O4ALR5KT8RS6bk7meFBsGJG5zNFMxF29
+9I1DhyACo0Pd3Mt06oC0U7jK0gM69V88z7xBA3f4ah4sQFI2E6gDNd3NvF3s23g3Q32JzCq8AJWEfWFtX3L58NV739
+0YM1GQEB43TpAlV4jC8bN2fP9n56Dr4Ot2NU6pWBWV7EVFkh4Js5P43230qN4qlCnrDeR1fM8eu0nq99sDqZ6F8AV6
+2mwClUE9bCcCBM55ic2gm5Lw7Q433s0lu7cA2Td7CS96A2QLFqs9wdD5m5qp5AZ9AeFBFFi47VBAOEA0d7cb7PcFuS
+1PoDopCCJCv67CBC0a4bl1tN92T8Op4EDBFI4MM6TcA3FFex0XB8z8EkU6d6DAT1Bo5qh4SIGHcAETBiD6Xw2xrFDX
+3vM0CcFjC0is2zsAdzGB7GMv2qS4wQ9c17nd01G0Ap7mA5zp9baG599P49kQ3ifFFrCwQ0Ot44HBMiCuL4uC9zhB3Q
+AjN1LT1KF3wFAfzFwA1r00Uz0aNClDC6wBw7CIT1ge9GdDmn9HV4jDBxTGLT2x629z1uRBYjDQBAE680BG8yCkaCJU
+2XsD713R87mK4jw3BD5Qp29b8A2DiQ9cMG4D49E0bAFyz7dn8kN13CGL1BXC8sS8F95pt53NEq65Xr4820sq2rz8Mk
+3WZ0XV2F6A4FB6eBjY1Kg3m1BC5BSW8he6FO7bh36SB6ID1sAdn0ke6eQBvu9hi1xaA0eEXxEaZ624C3O8LJFpN7fd
+7NnEyd3cV6DaEd0FdV7OJ3J1ALA10FEf24sUFjP12y3RR44rF9A1ApCnm02xDMZ4j54Et7UW7es8PlAjA8nM5bD5ac
+0iI1ax1cU7pyCsl2ZV8mYDCRAR7A3ZEvZ0AjE4G3qUDXU88S1aY4fG6PdCjT4QmDOREeS7ar7Vn4Gt44PDsk6BY96a
+5104hID0I3X23191M9F5j8yBEWl9S37DdFrX4KC3gd8E6EM2CvmEwX9YDFwz7rs3k01Ec5n28mU3zjEJy21yChb5Xq
+B9OAM78SGB81F8ZCwqBZO5EOEdK42A4RPCNz2eg51z4zM1af8Uk2EPE8o1gG1fBAuODwH61GFc7DY164qAzWEHW5Go
+BmU1vi2D92Ch71MF9J1XL5uyBYN9u1D70E2s4tj5xT62x5jpBOiERGFeFEYF2wq4Cd3qqFkI0KFDRA32d7dxCCg0As
+A4c2Eq8ds4WGG4Y5yk5fkD2L1gR4VvAUp4Kt0IG32T0DuB8eCpE2vb0zz6hGDDY5usCKa0hyAIJ81SATB5NkEZyFD3
+1d1FDgCgk3AcEoN8azBnSAGEG4M7fpGBlFCX4ntG8j54rE1VAim1DW1nO3QK4evCWl4CICstEvP1r162nCUA7U78SX
+0Tb17rFO68N8FsdFOP1oL6pmGJl8RR4il2CJAsx5EZ31A11Y6vSFCyDCP0KtAfvByK9p1Azn0NC9Cn2HB7f5DbYCE0
+3wmBzbBQw0IPERCA181Gs2zc1yQCgR08C9GkAn5CC1Fmr3Nm5kkF8X4XT9RvDkBCriEWPCG1EfZ7e484k91n6Za8Fg
+2ftCnw8nd2ahBKF2Bo3iv74x3Rm9NqCUXEpC9I2BCG9bB4wg2741qSFuoDHw2gpDnjAnq1dH87l1Ww8j94QU6C36vQ
+CUU2eSCQN3Jj6rkA2t1SaEMD7626V016L8lAAjLEXA2qyA7Y3Ap7wrCDh3M25EAEh1BNhCfP9eh1xlFlgDbp2VZAQh
+6oD4M52JlA7Q4po3Qq2ibBfI2SJ6Y49Eh1Ns7SO8QwEfaBke5dt6qn6DK8bYA5X6uC2vd0xY4JlCEaAjpA1uFyr0NP
+39T1ov91a3MmD100RF0cN0LaBD8CbDATO8ptBt10ub87n46y4KO1UJAEy4tBEtH2mV14O4dD6sQ3gq7rRDleFT2EtK
+E4A6bA8dQC8U8ky4UzDZe4omBLP6yO2o1BU40Mu9Xz92O7FVB7pCVz5VbFmOE3j0Jd7ZAFB42gN8837905Cb4JL5jo
+0x10ip7clANaCTE9qzG7Q83AAoRFiPD6y590FYxAgsEGZ4HLF3KCJe0USDwkEOZ6wl5B22b5AER35K80D34HBggAoW
+7vJDkx7hu2BZ0eP4l76ea4rVDyZ0l5D7b3l5EETB6dCx14Yy38f4Ct2PxFwB5Xz4lG49JBtmBHY3zY1noDCh2b9264
+6dt1nx2JWFuH3UODZT4V41OhCwuFq0BEiCdNEJBBgL7uSFMFCe16wb64j2DW50k9yK2oo8sHAU58gnDs9GDK2YR0ie
+7PBDO96qECjxBHo0uzAZJ40a938BEj8nr743FBfEQgCwmB5OChxDF54qJAKC1gu7hi0zX2gZ9tg1XbDL0CCR2Cz9dW
+GFI9RkEXoBtQ8f21amFEACL24Lu4vJ2IEBo85TMCOgB8v7hzF0r4Ab48832N4eJ8GNFuTGCVDDw5TdEp2ADh5ZE7kL
+G7e3NR1Y9Dbo33M1yG3hz1mY3XvBsh3AQ59M410E7Z9W27zG5eM6gG6u0AY28dfDra3hAFx9FzvBEGFxR6ilCAjEUg
+EMNECA3oIEXdFtyC38CY93K4EW5AUN7B19x7BEyDmM0Ni49i0yoDsnEwGF4TCpI1CPDTJ2CR2KLEiy5lEEL9A7DBQb
+AG7CIg75s9Cd4A2FeQDrR12fELf8GL72YG5mBqK6PF0zf2Cx6VuBidEsH5Ql7V91K15XV99y7pEBCt1ES4zu33pE9u
+DZ5AhC5k768T8G51IT2ZNB220Im6118kU06nEMX8Nx20Y5Lk4hAEShELMFxmDSd2nK2eOAxf4L8EYN29Z3VMAqx9sS
+2hV87PEArFCB8QxDBfCOI0qtBmm3GK9zW2Ma7Nc8lHBhxD6WFga8jh81RCrHEuOFWm5LTDCT69uCF8Ctq3BG7fXBBL
+8JOEHJ8qpCgK43i4mTFlE5Jx7MB2c1CAdG7sCmGDmQAITEIpDYn7w18ehAAjF7rDDtCCH49vCFz1lg3m53L61a39FI
+FhB2w76gF3ueDMhCXqFpGCv04So7yr5KY0fU9lQ83M0khG6t7XU4iV1uCDAeCsZ85k7Hg6s42Xa1pj5JACiy9I7DP4
+3D7Clc1taDf17qA3Yl3YLCZyE6817oBH9AtQ7Y18n23z099Z2c4AlF1tW7R4AzXF0W9GCCeEAxZ4v95nE4GG53QG1U
+9Kn7T1DRC5Jh1WW7ad8TYCHF8oh7Y81fJ9JZFo82EcAhe6FICI8FxMDum6reFw0GNn8fF8Mg8ozGNyASM0ocA8aELj
+4goCON6nmFsF7gN0irC7dDog121E9nD4zABe3HsDHsBSd0TNCOYCmc6cj0OR3wYA86Eyg31y7QpD5wBZ6C051H62rB
+5Iv77D96V3cJ6vX1EN9kyDLe9MOFvL1DBDNVBZ0DxDGBb8BB4Ev5IK9OYEBICG272VDSP9fYEdJ62HF7M6umDJ354e
+9RU5S595W8qb5bn3VIA0ZFe77pC2SEG6C8ak0HD83jEavABjCIbDn70MO2Zj7yd2xn0xjADp1QA5VH0r04bs6VIFdP
+35o91NBdK3eR4hfGJ702FFKx6sn8wF8Cx4fK2qZEPp7aR0hHCQh6HmFjDBfz3aJEWeEAZ3Zk4wyAox4wqEDR4Qz84l
+6He3nrFadEpX9TSE5d1dJB9989Q9y56tI4ai6Z24FSExO0CI5jcFMNCxe8Ky8GjAiNBTc9hYDmZ3t5FEU1uw2sC8qt
+DtGCR47YDC2vFI41Mp9eg9Ac3KO49oCLzCb00TVCIO8yRCgl3qy69CDvTCfr1ja5AI6Ii6AZ9488ykEWpDTx6sE8tn
+1SQ6dg8AM9gfBVIDAz5Xj4f72uw6KC07z3zk5ah0ZJ9skG6019C0jg4062l89MqE5597jBdYC9366s2yd7W92NTFWi
+ATd2qv6kuCoKEEh0c4Exw1cSCyJDOr50s5YP4ZvBnv2Ws2LsABR62vG1lApLEHQ5vb7KwA4X7QNDpoFutE9P7XZ43L
+8f6E0K19s6W93TN6xN7mM9Ai4LCA2v5TW8vN3nE54KFVk9xX94E4MFD6P5pb3uQ0dGCI2E2bDcAFXvDGcBzW4aPCRz
+4tN2hC1TaCYa0sRGE50jp9EE20DArP8eg4ZiB1sBfx2zrGDpAw14nT8DmAaSBkk5eq8EiDSAB4DBPGAvEC5C5bP61H
+48U0dQ51W3cx1266Kg0m8CVK4Ma74WDMRFaA6z5ATnAO81EfCIKEJs7euAV82yy0f4FcK8IO6M6AwFDqMDGF1utEF6
+CD8A2w77GD83CHgEUjBfa6Ag4Tq1nl2Wr8Nv34r1uV33A8t22Yu8qvA5V7yD7GL3If3ej0b33G2D4nDVSF4H5Hu9qY
+CYr0RG56ZBPS93NBeRAJYG3b7Xa0SU0e2A0w142FUx7mqCBN3FZ9fmAoE5WR8neCU2FwkF6i05cC9M0fO1820ur0Q7
+4vm5zM7O20u21UT6604JK8y29o736ECaU0uw0moBBF7bmG0E1Lb2jKDEh5SF4zPFWe9KZ6qx13E6HM6v7FQh5d101g
+8RH2jz2lnDnA0fc7RsCpbGNQ2g3G9iCvG15SDOy2Hv3y78556vTFunFl5EGt5Ly6Sk2feBKDDTB9Mc0zH1M41E0FTF
+5Ra08uBsm1zN8hn3rY07eGBi3bOE4I9gVBLKFa88Km2CdFCV1wj8iE52QFtTBz3F789X52EZF346511DkA9t6bZFXy
+52KEIHDudDtU10E5xa3JE1h9F2b0Xr8bU2gb8WGFHNCt1COk7Kz0zv5qR8cU8vOEbZ2AU29aCYP33F86xEKk8qg6jd
+3G80NW7RRB5x9KW6jq0VC3lrEa55GLCkH5x70n2Bh97SvBfA4Du8MhEvO5P13LSF9w4ohAlfDfP3c55GY7lj44g8Os
+0Yh0OoEFG2Qu5w4CFaCIh0Pj6O1AwaB3rFHQ49GAym2Fg1EbCggDXj0GwFfh5hw0EX0YV8YA350AJX8aVCWAEwcBku
+DJdDes8JN6tlD366dsAwM4o06eW3hKApo1Fi3By6Ap5mx7n56uL4PYA556OO8KPEbvA6CGHU22rEyp8wpCJ56Sf38m
+6nSA4B77Q2cq10U0rc5yY3OQBPx1vEAclC8c7GyB8VB4wBBP5l0A9xGNiCv43eu6Gs36ZBXj6xBF7kDAc5qKA7q9I0
+0w64eG2U872sBZP9fa4np1NS5MMCmXDfnBJu79hAFTBf991d0XSBzo5dI8Sp7Cs5cWCgz6qJD99DKSEnI4CP5E1Fft
+8by50m1zf37M3lV4BE7f36rE6pz64X83RBsOClWBRqEnu0JzFif7zzEeh6t40knDlq6DQ3j3AiQCAIEdmAwL7M7CgA
+FiA2LyGKw3x26Jc6qt9ID922Ea48bo1JX8lq0WH9A8Eyq9k7FO39V5EOJ8eo5R66d49hK6HLDRSFH5DnHGEu6zN5vu
+0iY78U27r844FWD1NECuHCN62k94T306M7LbAkjByv927FR2F5G4KF8PHF2Z73HDmc1HU17J13W0Dl8Tg1r70I77wK
+1UkCQL9TkEZLFFX7pc2de2Ev1JtCaP3bw6ne4r83gi3XJ8uUBQB3xk3hU2My48rCHJEpg1VO3jN6eD5Hx83L1q57AP
+95mA8T8xN7g2BJM74NAPr0oS7Tt2uq5Nz3wD0d43oyFAIDHi79d58s56sANI7JD9Bf9oR0gr6hQFEg5F1Ex3B5h0Do
+Cg1B8z08gD7K39IAXX729Ch67mXBgU7NE1y94ZK8HB1Gb8Wh5tn2qb900AYPBxh0gB5OY1mIFei42WCunFUZ87j1TO
+1BB0BKB9YGI5ALsDUU0QPE2WBcEEKJC2O68xEXf0Y98nc3v32lP5uRFs36sXG2C0tlA5gDd3ADq3ot7tZG108J3Azw
+0yBAL9DCJ20SCZBFI56AA3FTEnNDPm2jxAqQ9rl5GbFJ35ff1V79j61A3EV99q13zJ8S76lh7OK0yD4xO5iQ4am4mi
+F3c9R01LW7kcEJ71wJAQm2cE7Y6EU51anEqN2by8PV7YM191Dw102bERZ9Fn2ORCTdDDNCDi27g2ovDjj23J5kx3sS
+GMU0Bi52L9Zc7rB2Ob2EA1MK8nQ9eEFJT1s8DwMGEjBigBlVG7hAMX6PW2aND883d81mi6VHF190md0hKCyOEUpDc9
+9abDJvExJ7ABCu24It4hvFDqASu57u50n1m90nQ1Ki5O59eAGF31xHG6d9e8EFs76PDN41Xh6CX7Fe081FLFBCI7Cg
+C1PBJPABkB5ZG0f4AF2aU26wG226wADmEBWo1eTDTzFMDBvT57t4yA6oM5dgFTw38h3wIE7j0xbBu02Eb3Qk5Pn2RD
+Bt29lL3olCyt0r4F9yEZt3Ke6n10FuD1IFJsBMgCMP6Hf28ZA4UF9kDSoGAW0LP9d75M16cJ6TQBW04e602KAiq1Fw
+AeT7nR6ti6Ik4mL4Pd1XO89t6pfE1Z3pFASJ3lH0zI26oDGUEOh9fy3Y11oE3v0CyN6HHF5o07KAGj7DKDliDSJGNT
+BTd43E0lc4Yu2tz4s25zV5VU2Ra9kTDv1BizB8684B2Ug1by4NWByECGa0Av96B4Tn1f39Iy3zfFfeEYq8GP6jU1rW
+2l7FVRCB30azFvTFFjE3rDYy5Rj6OqGFo7xV11152TAZLCwx88QFtBFBq6280FM87i29P1cDBPZ5VR9LS0BeGE3F93
+0yOECl2y88pIBwwE1hBHf6D43UzATpA7AFTEBG82OFBy12OaE7v3Up1sF5bG1V6Dd90SlDkrG7764iExS92W0t16y5
+8iVBPA5D168wANcFtz1Mi5r7FGa3c864l1n86kL6wJGHD4NQEY16ZPDzi0p91G7Ejc8EFBBq0Yr9Qs3RKEnH2fQBA1
+3Q05Gt4EBBs86h78Kh8lXCgx8Pv0XKGJxCX0EkV6hMEvU4jQAzk8lyCBn8K4FRj270CAS6Af6Hb3mq2YgFXG2fCDmB
+8Yu5Pg95hENu39PFwT3BiD5a2Fc2al8kL0n38jGGGm3YZ6TXD8xCgu1eA87eDT53U07CO01iEaJATVG3eFk398Q357
+7doCLbCZK2dt1F31TC18sAH0A0900OECs4lo7i5FiB4oWEIyA4tC1S3Hp7TZCBk6Ql5ZG9QjCrF2zf7O159x2qx5sH
+4Gz8yH6M43RP1N523f9iL0hUCCFD5uAen6zB8XyB1V1n3BpuEVC0YfFCN4nX4QgFdN0mcBCL0HH2LQDMQC4w8Kn4MT
+Ehu2SHD5U67W3eKDyIDsJ4SN3SyDYDElJE0b1Cy2p91PY9ZdBy37bS3XWAjFE3LEDd6vt9236VD3YaD8P4oc8iJFub
+9VdBC18FiEXi3Bw1Jx5vW5wfB0l7TI3u12myDE8B5i13d7AIDvh6TqEuD00P0DXASo6eX0vZ5ovG2qAhJDhqAOx9LM
+CH52jc7tmEdS9Bh20I3eI44vE5UDPw5nyAEW4z5E150IwGIJFIQ8mR0Gu7uc6IQ8GQ7MC6oi1CqDPnBF34Eb3c9FmX
+4nP8tIEsW0nvB2gBBH3ZF4wACgZD7N9uX9Yj8kB5U1EL31Wq8O9Ed51Nk3cRDrbC5J9pmDn4BPl25H2c876DBRf7Om
+2hI3Qp8j37YR4Ny6hxCH81oV8dn0dUFjW6zF8wn5ZSFORBg57WfE7m4MvFcD7G7D5NDTg5nzFWR54c7Gs6tZBhn1JD
+1to1yM9GYDDA47w9vA0Ue6f6BxW8zSAjDDCt8gEG219oZ4jV8Yw0J6B07CsV07dBfO4XaDZk5oJ7R1GI18u6BjJ8wJ
+99N7ckBo40KbCsM0597gtBXb3t66HX3DEG6p45YBdl1xZAec4180YGAmq7a98nH3Gs21F8GUE2MECc6vi5NBEcaFYh
+39W66q1pq8k447LCxwDG04HT7jF5EC59cCxY29x9LBCBaFLc3hkA31CBtFp4C8M4Kl0eE9oBFF58sm9gMCWT5I77hD
+2dfBgOBcF01Z6yNEq1Fsh6upFSu1Gh7KP7zq2fU8gQ9LbGLJ9CgE6ADgl7Mz8g94Ob8Jx1avAKN1gv61Y5rI3JK5z6
+7uhCZHGKz6G73LbDko3oU5BZ4j488hAdX3mZ050GKUDPIC2aAxzCFP4WUFEK5ZxBc0BAY5Uv5zoBdSEY906LD4b75J
+08A8vtEa879O1Z9APXDAq5HX4S0AIeAZ1BtZ5vn4m2B8bGDu34813R0b87bBGDV26G3ZA2SdBmv97wEJ96nN9N39ZF
+Cyg1SSAJyA857yC1FEExr0oaEkmDxI0o872a6LH8sx0oM1pVBrF1CgEySECS4n51XKGD41Wi4sD6jC0ErFeT5ypAIn
+GBcBrwDaw4YL5pa6ZcAv0BAFDZgBcIC4x4YMEOo7pGCvS7wlEtSAyZ1cPAzpFqT3lZCRiFdI3lYE5v06qFPN24g0Ki
+6v2CAB7hR0OQ27UF4k0Qd3ZuE007ti5tSFSE0pQ0vOBgK8Ro9PVCdA2XrEEb0JlD02A00Epy5UPAdRAu36pnC1u58m
+4zCAAn5q73xw7sz7zxBwNDRx24s4W3Fzn5KRAq13Rs7ea5xABJy70s7Vj9DeCUBF3a7GqE6C48d0Yp1zY6h15xl17d
+6hL8lNB1qG1NEOjAt79tw1b1EQI31GEdvF3fGK6AsS4674WE17wEeL4DL7m69j99gA6tV4JP6zm1zDEnq5hP5ia9DU
+G4wER7CGdDwd4p96m29rVF1y8FR6xz44O4rQBJV6fD1pF6Ao18yAiX5j5EZV09X1UH0gjDUqFMiCJY7wf67R3a37IP
+EatDdo1wBDlH21e8sLFfg41JB4a10X8bm46eAxb05oGBzCwfCA2Esh3Fq62C2sWDQp9Pa45W068Fe55h9EOR9XvA73
+3v8FCn2cfFCI4rP0ri7OIDaJ3OKDCdAH5CAO1uUA94AFADrQCrc2C2BYTFBB7e7FctDpZ8tc62N1kh4vZFkd5tKG0T
+1Oo1E995o7q9G5w8ibG2T5m95PAD6BCCQ1306VvBmc4kR7cv3C12MK0nxFqR3zbDFO4JgEsz0gR66z56p14E8816rc
+Beb81X1ywBgaCJd02N1Ce0RbEjA2uy5n5Fva3mcFiz40xAtU7NPDyo8bIG5T6MO06R82I5V69hxDR54NqFBg3WVAxd
+5T1F9vEbN7xN1ac9YVBBdCIL7ei6FB3Cf2KBFfj52r8y4Aas55NDVi7wN8hl18m4bKDnbCCo54q7TCBvfAwi1qdCnA
+DvWEj80rtA2Q8oy1OFGDo3lJ1Ck6dE9pXADe5dy46V0lT6Ot9VQCk2DZZCFgAWWCGsD1C5ka7XOFrhCFl4UH4582Uu
+6av9id8yW8UZBrbBjU4GRDa04s3BQa90Z9P80M43Wn8Qd27zCV67k3BoU9Zp9WMCl64qg09K0bw4R0D1zFNk9Ee2Uj
+EgL7GG6Z0FI12cSFAl49TFTgBVsEtm7Y3A6K78P2QICLg6yq2AtAXj9ly1Mv2IPD5y3kECAr5fm1M5A7C1yo4Qd026
+ExBEhnAp0CG5ElYCyM4ZlA2UFzYD8m6KR0EZ7SX9b47P96UEEM97XH7BjB2m2P129AGIf8u148XF576Se9owFb1AGN
+1SwACwCCN4ut7WMEONE757wy2Qb3742d82lU4SBC809Ce4Sw1Vy2THCtLDD56nT0cEEm3CL90kcDGHDaQAHr2rG5pR
+BviEu8FyXCbl8b33phBLQ5mjFZUDbnEOW9oT7uW99j62g1S90bN8YW63o9KmAtl7cg0usDHV295BV62yx86C5YJ7rk
+DBCBySBugGF22i37t84Jc6rCD9l8G78cP7MxG6wFWl2xYGKJBSi96NA4CC3W6QF6wmABHCGI15q7HH73q1z39ol6bf
+3LlEnv38J7t2GKh42oFyH7v25Yo2BxBJb3re36oGCM2KC5xU4JNBB12J54Bn3NnBSeAfu1Bc9nzC5xDJG2w5E5L3iO
+0dA9wo9XN03m6x35ACEhy9F51A48Wx2tA59U73xEG66Ic6JIEDWFJNDd46QD97D7pw0UBAma6ms2mNEku3JlEFW09o
+6yk8zpDWS3QM6KWAGzD2u6WmETuFMwB1hF0w7VH7qbDYv5grD160dn60F4PB5Oi6oE1TKDta9FsDFDCxs90LDiEBiM
+81A34d5lJ6uT3Lr4O81mMFtGDUC5WaFHbFV22hdEKQ9GHDIu8nVFLj0Hp5Tl9Qd21O2mk7kyG350e0FGg1bk78O1Zo
+DqX1lOCdv4bIAJuFKZDffCXr80TAQ6CAmFHWESrCSe1Fn9NdDioDx9BZu8OIBLxDiN86vCmq8vk6LO5gs18IDVW1p0
+Co4ECX0an3nbAGF2djBtP4MV9ff11JBIVFnmDYZA5pFJ24OUF5g0c92t03q4A5FFxkCqG49V5TOBHDE2S5nIE0n4Cj
+7HjBTL2CM3rp8jE7Su64gFxF0V33Kt52G4XF4rUCRy2y74jL59a5uYCkT6lkBE01rf1w45SoCwF1QdAiIAZfEKE3ts
+1bw8bbAjn3xf5nVBlB5ztEBXFnIB65E5eAMCEh0BoL0jHFJJ1qt9C2B7gF6H19B3iMEJo4vTFQTBQn6Q2EqiESWCei
+1b7CkrFKPDEk1or8q73Js8nhFPV9mH1R71VP8qeDGM6PU0jL4lf1dAE3u07pENo1hRD1m5Ul6nB8q03Xj7NFAhjADW
+0E20rP6EnEuLB7R59wCnh6kv25y1C55m38szDrOCJhFbo4Nh3vZEZ0CiY1a6Auv8TWGN0DQy1fO4qY78S5kcAjr4Ru
+2BLCTT3UK227BER0Y48OBDVE4vMAbS4qNFlPCSB5RI53W4OA4Np1HZ7LP2cd4vCA5j5cV7uZ8PwE8c8UM6gZBqMCsz
+4tS8Hw1JgATM6Bu0kR0zV9cNAcf13UBPi5l155k0g22VN4Ge5xn2sm4BY9QZ6dG2aG2FQ3Dz67I2kc6A5FfI8LqEWu
+BVr9W59dTBmaEsG4YsBOe13H5vZBCiDqe1MW9hADrkDAK1DEFJ50Rs0wh1a06gb4Rr4kd0NO8Mb3SN82H32k8ahAx5
+G1y683EcJAE0DmkCBpDmsC0WA3qBXhG2XD0T22h7Ih8B73MeA6W1zL253Aiy1476oTCjDDb09bp8dW5IEFoiFf418k
+145EQ32GXFdBGKE62OBxAEEf9yYF0EDF759G5Po8pvE5f2ou61rFzg1PyDH7AxRAmk0ba0KW1efA0yBLYFiX6QY5kZ
+Fyi4as3PnBlC8RN81T7N07hAB9UCaE7aa8HDDIp8D18mM2P2CVo99d61LC8O2cv6Vk0Vy3nk1b90L0Fvh8TR2yrEXm
+3uc57MCef3vnC3o5dC73S6NIBD55oo4tC20HFiZ3On5Ls9xxCGb7CU6uy9rK5pN61A45ECKw70XDbEAvJC7lFzd0tL
+0aE8yx8Av0HTFmi9wkEESBQl1ZE5tZ2u2DbuCWS8j5EjJB9W5Al6jiDsR2p4BHp4xnARMCnz5Oe1AJ59b2yT3Px4Or
+AhZ7219SU4Dm1Sh6Qt1Fl2mS6mc1hD4jRCEn4034vRAkU81HBXuF6YEVq8qZCTBCsK4aMFy3DMp2N7C0K0un6ALAgJ
+8897R8CCyAkd8v77jZ0492mbBu98i60871fC2Su8DD46k1lx3cEEDt9oE5td2S28RT6ewFtE2kWDzq1UL37qCShAhS
+Aub2e10VpCkeAVtE6UAxU2D57XfCTxG963djELWBX51rl3oT8rz4e840I20t1oRB587qT9Bg0tW0AH7tlF9D4tqBIf
+BE4Bz12Lj7Yg5Vm1xpBtk3JP3Md2wVAM5E7tEnw5xJ2Iq5dm5FTBFf5e1DUlCwP9UGBsX59J7EyCMyDbKBELEWyEFU
+1bb9BxBjG4Ci5SeFGr2qa8UQ6gUAR6C8tFxg7GaB478Ql0ptDxp2sfBXdFDm88xFnc0938x43fL7KJ0AFBiG8qYFSF
+1sKEmaBTS3eg4q0D844pKE3s4KhAj51xO1249go2pH3CsCQpB7LAtM74F196AM2B9B2PHBdd3401Z49ai1BWBh7BgV
+6GqEg67cYEjn82L5RMFqLDe5F0dA527GpF6uDgm44D1zE6Bn1rO8V90MtD5ODPyEII3nV9of41y2RgAX6DohBIZ6qI
+BTO8Rl8Bi7jxAg66SDF44AgRBTE2gS4ye1Cv4iQ8xJAQs2fy8My44X4sf7su0mb9gvBUn6Hn8CQ9vj24y5jg6VV5OI
+7zE4VL7nD6a30dB15M5ps9AVBb9E6O3k8FDM2Lt4juCz33aU3qR1K3ENT4uB90W2RYDGCC47FFs6019Hw4XY1NJCXQ
+7lS4Bk3Xf8Fz5oS67f2fA00s0kC5gK1038602xV6FkCYnEmuEKnCme67SAEg7fi7bzAHpCno3oX6db45G9uqCkB9hN
+7IjAlv3sc36IBtd0e9Dzr8Nf7MZ2pG3DY4vq60c8RAAJr4m3EO419TFBV9j3EYJFWX7xLDmW0wYAQS0IhBAtFlY7jf
+AUiCbx77g8FB7MNEG07OFFW45I87pe4mxDBmAXzCXo78DFYEDW2EUWEjtBpj3RxFm57EXAPD0Nt4yWB2xF9H7Kg7ut
+4fFEh979x1Ss9IkAKvB0b5du5Yi3m7ESDDmHAgnA4O1zs91xA0F8Ys2h26Cg4AK3AdCGM5Ng2dFATeEF1004D1J4XW
+1FKDDy2K56ab6am0t06RLGO1GI8454DIY8g353i6nPAGL6sI18q6npFxl3eyBoB74X331B5Q3CE2l1ADX0W9A8oBJn
+4sA0Ws1wEF83BvpFbtAeD5IxAHSCko7anDnw1yWCL630P34MAhn7TM6036tu9rf3yiAI05Z74bfAk81ZzCGyBqNEJb
+CxS3X93KZ8Lr63TBBbDhTCjk9oJ1BK3Ex8xl0k93pW78v2EN98d4Sv5NmE0s48G3xC7nG9N85ei5QQEg1DibCgVBqA
+9yT6LME4E5oG5UOENUDs41582fmDlRESpE1B0JWCcy0Ro9lD7Ik2szBlt1Nr8Tc7Gd0g0FtaAbf0rSD6Z3s0AbiCNG
+0oVBJSA1XFW50gv32r84PBGy2IMDvQ9Rl2dl8Xz8T61GU1A7GCd2clGBB58N4x60Ie4WMDBSDeKETyECyBuC4u52Uh
+DyF6GBDPvDwI66ABiF7vTEng0J9ExgFFx5zhDpW80Y9MC6feAQOCjR2AP8wG5CFAqp82j2b71mp6XQCMX6ifC2gDdH
+0nbBnh8MfF8VD7VBDkBuSEG71OnBYXG2A3bJ3MX9avBPF7PN71h3LaDTOD645ar6lK8Bj8vD4zT8et2402vH6Tp698
+3PGEC5BhY2Vl15L52sDZy4ax9ts8V03uyFGWEW28CP0rDEWo9KzFMQ2NwErKDU41A66I75dU7QqGMy0muCWw2Im183
+EefCs7Dzp0i0AEzFd7A5bEUOEKK5D33oL1uj9TR8V63Kh5Vz8pm7q12777F5ESMFhQ31lDln8kK57U8q28I8Fx46qv
+27YB4e6G9BX87hU9xmFSjC0m15o8c2AdKA6w54C8wh2Rk1VYET4DWg0bjDljGKS2uK2NJGFf8Mr85jFzjGJPEmP8WO
+BkPBhU3X3CbyBfnEsE3Ur89D96S0UOBXFDLWDy10Kv0N46ZU0N9CUI2vT8hFEvvBLkEW9Em49wxDqPGBL2uA1HCGMX
+Bgn0VeBQU1GpDHUGFC7HG1ex6aT4gE5yh0eX7s50xN1aGAnoALjB6uBja13S34Y4O28gvGMWDotGDjC6z3sCAKPCn4
+2rU54VDXoGHf5qaDVY9Xr1iM7Ru6gqFFe5Kk1ZV4D1906BS14dl5782ng6yBGAM2TuC8K4jT7HuA830Qb3ORC2u2LA
+E6hDXI1qDCOE3bBBZGBWa8LnCtb67aF08DH3Ez1EXtAdPDs393C8uFFM06V66p20J11HOBpFFghCGL9dP3PI3pd6tz
+4JXFVs5kgEbp6DhGEk6Bk3790kFFRY0qL0Fx7LI3ZLFOJ4emEqQ9hHFpY1SG2uIAGkFV384rCpfFC86kiAzDD3N4Sq
+DNK3H2FRX2iB1LxD1K2E1GCY0Yb3HSBHa6lgAqtDaKBeoDvm6tr65v1NI5V0EfQ6z63MQ3xB8XX3iR1keCJL8TZC53
+2cHBLe3tzBmt8Ev090Fov8mg2Nx4Iy9F88gh1j78YC5cH7E79V92Kv5WU5RgFo0Dqp4RoEJZ4tR9lv2k22OgBnK0ti
+5jK9au34wECF5ej46PDdm5Mv5bf2mR2vc4ZhDuGG1O4Zu5Mi66m3xo6kPD0z0Va1wxBslD3D2543aPDSt7TmBs11Ah
+6bHCWbEMG1XJ7u1DTu6D3CxfEQLBSAFC70eeAZ97UF7m1CTl0K32NF43B9D70wZ80u4ll6MX45p5hZ9I63fHDNn6Qd
+1gf8lO4JkDGX2mM4b23Jc5v13XAFfK9nhE8lFis5Nl1Cf5by4fA1Eg4q77UZDHQ2OpB7UF1A43sElb6yE51sFqBCjc
+7zd8Jj9JBDrz3bSEkL7D74D60v91Jl1Du1aN4TFCDrFXrDOU3mk9XQG915v22rJ9vyBZi4iKCGSCSy2vw0GD4nOCCZ
+BBoC3rEBf3HJF2NGEC4k512H3WH5WB9wA3jH4YV7wv8e5Byq8Ou4Gi2xKAJ84Yh7BXDi62SCBbx4f13EpBOXDam41z
+3cZ2zt0pEDOEG9PD0k6xt939ErnBil7UPEnK9MmAjO7JX5O27nUBSVG096T56To48x727F9a6oIE4j25T9hn8IPCf8
+5sX2Rc3CAATk2hW5vLAuW6wR3GZBZs07q2xO217FZ6E0o5PuG9M4ipDpK1X28jYBie6SKBvw7VE2tpEblBzU3E4Evl
+DMqBsp0JA7DmEnCBqH6hI2NnGJA00cAvl7U83szA9A9kB6Ud7vc3ZS3Y9Am13LX01r5ln05mCuAB262226Am2zT5we
+8nz8LPBjHDIdDfBAqqE8hBBY9W3BAqDcrDPPCw203ZBzt424GGr2BrD0l40c9eOCYqFMm0RR1PmG0q0sA2OwAepAYL
+8phCQfCwYBMe7Ev71eAt92YiG4i921Ej05fp1hN5QD7BWA4x1iKDE2Aql6RE1TV3NMDcfDxkFwH0hN8mx32uBwu97n
+Ego5qH04R0rW0Nj4eUA6j2T9C2FBno6IOFLh4iuGCW4LoDYU9pb0yu2wX6bi2CI8UNBarF5dGBYAL49iWFrF1zMAXx
+18n2MFEoWAb26Rn8QnFjO05D1hw3MK2KW4rb90u6mW1x5C547dM6vb8zo4Ca04k3c6Br38dA92X8k1Fqc62A2dzFYR
+9We0Wk2XuBUtFDQ9v8Bij8NaCV53Ij3GOCHWBGaFVe3XYEEK6RGFt32jW13v8JH7gMAOD7cm7quEjp4zO1U139f6js
+9IG79m9K58rT4KuC2L8jQ4m67dHAqf3rM4hh5Tp2FxDQXE267Kn7y58uZ3yzF1w82tCAfCAbFIqCoiDkSDCx2AkBCa
+9udEofChrA7aFn25UU6k6Bnx3IK4t3AR2CQe330EWCChy9sW6Y94yz6eA3VH9uDFss7vIDBPDE4EuHFot9XjAZWFiE
+EPxFDt4uD5d28lDDPp5rAB5c0EK6cxDfi86n2Q3B1K1Ul6eeCJoAto2O57xdAs8FM1AyGAhDBSuDCaFmFAm35Ho80z
+9jP1IZCI3EUrGMOAmf9eWD5kDA7ChM1i00ppEhc5yPEOF5aH32vCCWECd4EjFYKB1N58DBnz4OM8uqECr2ywCVSF5a
+CsxEk67KQ3TGAWl6zU6lb8VED5E22v3138Xf97A7tX8TF6YK7uA5y73b3BBI70PCYW08kAxT24E0at4GP0U25v6CKg
+5u9FQO1mBB411xLCK89Gv4S29w32wvCJ2EhkBg4DR1G1v0xd0wn1cRCRl61XBoy2XD3ddCKb6IUFIA7YoCGRFA4Fht
+B4294v5fe7v89YcEYL4vv2UXENRFe9636A4T7X29h86lYA4LDSiFlS3WFCrV0OB4lrCJQFUJFLL3CB9sU4qI4TeAIZ
+B8t6MC6WG6Nb9La0Jt2s34A469PE4w2ra4Hw01oDiXAX01h4BvnC8a3KFEopDxU9PkCiIFy0AQw1L5DDI73W3GB0Kc
+9Sg1LrESeBDU15FFAW6MvC7e89BAVNFc1AsRGBy6k4BCDE2E2U74ZXBPCDDMApCFND7kKFGJ4gO1y31HB0MvFY14ZQ
+1x0GFX66U01w0Ts1EFAZxF4G6Sn6Kn02vEmxEMCCHE4N98Sf1IJF76E3QFrs7sJ2HY7KfDZmFZ3GDY1bgFL3GK85sn
+5Ud7YPDDlAZG19b5S6Fy82oR6SJ72r9hjAOGB2cCrPDek9SiBpZCXy7gg3zgCC54eMCvXF8D7pz8lS6KGFupDQP1dB
+BK86wY2TaELA4s5B7NATWAqM7jA4P2E5CEfR0GhCtK1R60uY0pd5bp7mT0BL25R7kZ4fk8NE5f4AW9FbvC5e3zQ55E
+7ej1MXG7D8sPFvPFoJCD07WwAeh907Bk36KH6Cf5h29RNCjb15t2yG4gU4yb87GFH680t04pB1eAZSA6QDv20wBA1g
+3RZCvM8x7DPzD3b45lA6N5sc8HL4V1FEE72u9lk2b014hBgp0ER70u1r4AaNADa3YR26K7IVCSdA5Y2mTAoAG8r3Dj
+AuoDVK6LABiU9BGCyu82G8ExDhFEetGM3CGz03EBNKAlt7XmE8XGAf0uy8YU9RX11ZFho9TwEbA5CQ2KpBkOBkq0L4
+C8A6FuEK4CMF9Gs0Og1pS37P5gfCGU7rL0EJ5aM5MPCXtBKVDApGMp9Ld3hR51j8OV4svDTfCfJ8zM66rCHS0TdFuC
+1vkCMZ4ya4i62tJ4kjEqv3cA0GFCx3E8561uA088avEC473pFIfBGT7gTG7bEP65Hr5pf0miFgHF8I8qk39F1USBcf
+74b8q58eZ0RSE1cBKH5Ou0sDF0Z1iu1yPFG0DLZ6RFDQT2CWBrhCjO35r0Y73tWE0FE182LR0BE4vI4UWDrZDiC0N0
+7GUCwC2rt8gyEjdFIx48g76B9WO7DsBHdDJjCOwBKk7Ht5vO7LW4N6ACX85W9x4E2nBuAEDA28Q1zu6pKFOcFGx392
+7nH7PMAmpDED01tFIb0tDBfm3ZN1IuC40123A4G9YM7haAah9Vi98UD5Y9iM8LFDUd2Bq17EESb6C88qr7TS91w0Ei
+Eds9Jc0Zt2nh1KI3mICKmG8tEaG1vW2lm3J8Dv09ER7gAEzr7P6F4ODP2DNmD0GFAC0p8230CpsFTIAL855S1zGBaU
+8cg6shEgOGAsEQj5Cu7dFCpX3vOFsI6OZF4EEzNCU0BKE0s8Ael7Ji8C38C59XL6Q0ApM44NCuP28dA1Z31K6va2US
+A5NCN71YYFFg4j61XH8eBG4p4Dc7aF8rmDWE4xGBl20qPCTuDAr7v68GsGCyDHL8W38RD86T3Gv2N9BOpE5EDgkAlL
+G6xFbL9U85rvE1H5N7F1T3MZ3951cq3YE6t52FfCvND5Q4Fw9Dj83iCfEDdp0Dy1GYDYLCPF9Gi51I4HaFF15e8DHI
+8asBi84Th6EO8Y71D59199sh46Q5BlCZY5mAAgm12b4H7AeP3vY8uw6yUDiz6sb2Zo3BHER44YAF7BDIGBxyGE24Rd
+2jqD2x47v2DlBik37K3pM2fS66wC482r6CScEyD8U74ImDubA3Q9FeABKA0CAz59EV6ixAEq3Ot9BS8N90QLEaX0RL
+EnFEQc4h2A8l6ElAOjAHEA7oAqODwUEl0E6669M9Zv12eBFg9pTD7C2lWCIj8eTCZx2gg69N0W70rOFavAOkAPEATZ
+G4I9rg5rP9uvEyX0GgDb1AWd2Y4A4m3TA17n9AoCb41vQ2eK32y5Dk0ZA9wy50z1nVAfN8AF6I1Avo2wQFT3GD8Bur
+2FeCkK2CQDTi13uCUFEAyElm7p91Gv9Xu1Gd5ShAaJ0VSF3Y8SW2nG5uIBHB0yT6MgARI53SAUDFkMBK20uDCup9mv
+4O77j07N6FZ73Dq0Dn1au93j87WEtFAomEp11hE9Sb8Q38vb6joFZM6mt4IHCQQG8f4hbFtRB798sr1YoAGo5bo2BI
+06BElqDV54ud9DxDBOFbdAqm2qX2CD7oFCuiCt07aYFbaA4Z2lKDr70BB7nf6zHBnC2id3kN5LH209DwP0b942BFUg
+FYnCDG8zqAli1rr3PX4brAry6OwFplB1C9P3Bw4DyOGIU5WS8Dt55K2ZzD2DFzP3mf2Mk9TM8nY5r43K25zxBiS0rE
+EE1B7P3FFFKk1eZ8IcBtNEqbCee3LJANgDdy7uYA9M8QVADx7ENARA67mD2A9QlBaO4495NuBlf3XS1MH1sD7yP9mO
+0iJ1sT97GFme2oe5UG5FB9W4FhE7W14n21Iw0XY9om3yJ2528iQFZl1iI0Zz0al7PP7tK6ObEjQ1Jw5XUCD62ep7ae
+EME9l2CXGBPOG0nASIBuP9LG1pD57F8Hf6ufDhA9818Ls5UJ5h7CHYCk65En7RwC5EET56P2FV4B4fC7k1FX4rw2s7
+0zA02gEXG7jkCspAP09Bk90j9ji73P2hh63rC9Q9gs4Gm0cp2Ij42G9sX1BS4bB5io1LUEjgErg8NFGCeBvs5oE9WU
+CFRBAU7pFEkODalCbG9JlDnoB0T1GBDeC2v98SqA5l8la0ge4Kr8yz7DtCWtE0A0ZYEaF4qLEw16ByASY27pCnN9Kr
+1BEEZ6EzW51249c2kVEa69VL9UqGNgEyHDjTAYJ1FAG8a2L8FbYEi4A4h31gA8e7rM7cO2WcDMlApgFca73V4KS7zn
+0OKC3M5JZ5Gu1pc0XQ6yZ7Tk4of7xM84pEKP4xA3bd7Bo8vE9Hj6550F630x8Gc80x5za3ro60RF38A167Ks9zgGFD
+7vN2at9uCG3w4cXCOd0nl41D3PK6FG4l90ic7VKCMsFRBC2I8Ag4VD19z4vs5nUDmV8APC4XFwvBGf5eP3WKEmK9xJ
+74g0bY4bt2cCD9t5AA78Q6L1Ayx4at5nX5eYFIBE7fDOq5Xx0Uy9zJ3tL2V40DDEW1DHeDC2AaE8KQFs27Li3xyBh8
+FMXEUS9Vu8T0Cz0G1j0sJ4Fn8m90WMB0oFwxEwNFEnEGr8pS8TyEDN5iI4JmEEcFkbF9O78ABdo9LzBv18BG39U7FB
+95j48IGC9Aw9Bub70iC7D7KDB9G8c78geFuk8DS3xM14Y9sj1kE7CXF1P0nH4TGAFJ8Ub8qT15P41i14b3sM2bP9Sf
+97I9T16CAEAUGMr8DjDp60y95H49Dq8aeEerFCj0VPEZo8088XE8CsEoF1lE6aH03zAgSDwD0ArG5GAKl0lI1wQBCF
+91B6y9ElVCAV0TH5m0B6zCrC6mN9OlFPg1G09aMD4S2DG1rdDKcA5L86O7RX3k23ut2W85cr2lABwlAXl2yh3229qC
+0Fy4wv5TCF5XCDx1X7GFj62oGBU4tPAeM3TFDIL6c71MN5TI0Mx6No6xv47yFIo9QxG0b48cBMO48i2gL7JN2JL6Ru
+BFW6OPF142mB79yBb1FuaEqa2GlEZc1KnFu22wsFMK7Ld2tg5e3AVn9fNF0J6HpEirCL47SjBngD9F3KrD1d0jXCRR
+7sq7OLDug3ogGLZ1lk4Yk1BiDSs6GV4ogANwBYLBdTFFf7XN88iEDDE1S1QqEu65OP5ymGJU0InDr2EPe7rJ4AjFZG
+81CFydEzIBbT0gHCx4BaD7kdDHMAV5DiY8nL3UjAWKAn62DiF6d6CY6sUAMY1wUCxR2GK08cEtCCte7wc1ms7FO7zk
+7RQ6QxCX52nE6PrDg9DG2FD92yB6Gk5ZOC0D2E55xW4ZR3gL3ZmDEHBl41ZC7lEAjlCJEAV2AQkAJs2GVESUE81EsT
+C3p5o689a04bCOrFxu3fiDvk7y19TnBxFE7p0cU2Mz33z8Vp9jY2Ao4bEEPDDdJ7pZ6jFD2UFJ685sG4a3VA9zYDD4
+3TP6N49UN3gF7SnC8nCNZ639FrCCSl0Cr7xz30z9hsFFY7QX9XBBYvEqy20mAe8C2kEHl5vB6c96t90LCFuR3muG0r
+DGsD5x5bZ70W26P4TaAuTFC9D8qB4Y7ILBRw5yZ80l4nZ4siBS7AiL1SpChhB2pBFO0fr9kF5lYCj769W4hD90t5Uf
+5tB10e1t1Aqj4Bw7k52TwCOz6nn8JJ0x45XG36b9uWA0N97s7gbB04FAT5L16nb1dN69a9EkCrmCvoAHX0d07QgBUb
+3C51upAzxFTK9HvEmH1FLA6h7cc0LE0RUEEQ0hZ7R98FQ3cr5Cl5vc9oYDXH7Hv6KL4TxFBPBTl5bFGLn0c83aBByZ
+D678x060wDNh4Ix4CU8EYFum71Q1D9G7W3WC38q9my07u89iDnK5hcDR3DI9EtWFqY3en021Bsi2OX10BAH24OPBIJ
+3Zn9V4FUqEwZAWm1W796r6FvGHZ20U8Hk0MXBiq8Y9FiwFaFBlc0340gPFJo2Ih2r71v67dRDrs6WxCqt2GBCra9ht
+4LFGM1DH11qoF3p25lFyT54FG9BBwh9dE1bMFvS2jX4U5FYC5c3DtyCya8T21aj11HFYr5Aw5n0DXi0yx7udEYsECx
+1XEEDB3mY0fIF758Wn5Vl2VGAG2C6uDBZ2OYGIV92j0K10FX3s13VcAdeC1T4T65Fh2xh82P4tQ66O5VW2lpFti38a
+DbqBcp5352RZBhhFILF0MAfdF8dAFd7ADFcCAzI9Wu6rWE4RCms7qeDXu1hx7WX4xu9181Im4ZWEg25D285EB3t77z
+GDCBUa5WC9q46DeG155ReDtu8979RyBH48EQ47aARq7elDyAF71FOZ7tv1ghEB85twE3O5Vk18C7qo9Xp2Cl7ukBPJ
+1fFF739XFDWh7DM8PjAuF0K87JB52lE2l6qbFC296PFVQAsQ6z15pwFoM5Ko8NBFw71x62eh7Pa5CLAfr4XR0c01q6
+9Q39Y99Ip0o92vXCtQ7HaFcR6yj3cM7QzCbN26B0Ed4g75Ju51Y3wt0Ra2Lz0ru0NnChiCCG1zy5Nr07YFazAhs69Y
+0mXAKx7SPCG39Vb2Gk0TI5DdByXC3B8OL6lL4NCG6m5Yq1Ln0wQ3Uf6Zl8IG7dt7zLE1EChB6Y04Xp6tY3OoCih8um
+5MZCQcAct0ud9OxEZZAsYCGp2GRCeW7ZKD2S4yE9CP1V88bf4DN5Vw6Z8FXR6zbCZv6mu0CwBEPEJhCMh03xFIO3fp
+9ag5N5EAw834BXWAVfC0H8hmECaEgmFKpEuu3Mb9t85nt3Bn89T6sj5ie1RoEFhClM2VeFZK1gC3IFE0q5bxEZO7BH
+5UEDyy8do1wN9RpFMV6Gp4mcFjK6A630m8F1F3rDjc6G45Gv1JU1lt05n28w7I5BkjEsX0IN0mrC0395R5D61tl7dT
+1VE7flDdC01Y9UQC0g5URFOSDzx4FRAnaBG0AELACR5vo2A22xLAaM0743ep7It3ZD3QR9lPEKi9yV6eS45b4w00p0
+AyJBRO7vh5Lu3W98O05kGBrS77RCFt0783bDAawDav1Zu62L8dZA5C8Ta5mZCFm8QmGDhDSZ5RhCIU2ZeBmACS4BRd
+9OtF0n6zQ9LY2RGDcnEeN3Wb82gEJj796Ak2Cdm5CG2hc5B55S1E3Z1JB9eI5LX1VFEp96YR6N8Epj9eV4md2ke9aU
+DmJ5jbEAV9FjEHeCchGLj8ar8kmBKxAIb1PT5gd7tB8MwFhuDkKCZd1l93J5Eob3CxEs5Fak3sZEx7GAe8Ef0mp5b6
+8eyCx93vlANfB7J8zt0Sr9kS5e402e2QECQl4vi40UCzT1TD6KY2dS3Tx09bAufB92FBN6TAAId0uf5FSAXMAi146X
+B51CAy1ZBCabDxN8kr5EY5uA3i29SF2R7Fvg20XB8M8Uo3BzAlTDaW7Gf2sj1CK8lMDmmE5x5urBaLG627O093p4Ka
+1AUBnW5V3EWqEesDJMDH24PS2Kt0HR2isCU3DVo0LX5Ow8Sl4R10JEGMi84F7F991Z4hW09kBCpEMB4lR05fACZFvM
+AdD8IuCoVC8E3i01mAFg03aD1ni2YeFXg7AHDKZ8OOFN31Ia6K39Pl6jtBcnAQgBUT5oAC5b9sEAHRAhk2Gg5dq91l
+DE9Efy6j8Abs6FQBvo7xx6Iv2qT0DWAc0COy8xIB0a8hS70g5kD5Ds1Lu8YzBdg9YTG1C6Zj8NN9NGDnv4bL6gJ0BI
+EloBgk4ZOBjL2J4D3EF27F0v6rx5vHBhCFw4GHy0RK0Ec5s8E5K1mREJp2F7EEVABX9ZmFwd0C74eW6rb3PTAGw3sn
+5Q16GuCYJFP88ylE1k5fy2RMDgU3od5iOEIB6cfAPhESI84K3e400Y5WZC1Z8wE6vFArGCzs1TX6Pq08MF1E24F78g
+DFo49H6t71HD2Jg27f85NFXkAm808O73J2bU9cR5nvBlzCcGFxDEfrEfAAG69FkBsU8Lj7wL9SQ7V40Nb8AjBXD38T
+8tt0vIGGb1C4DDH71b9p60NY93S8Q79OMEUMFSl8uM1aL40A8tZ8Zt1yiDBHFokBe56Q53UC0i6DOk7h5E5a4kv6n2
+62R1cFCwrGDLAf59b797Y72qBPB6yM7co6iE0vr3as8Q98Wm7HV3Vz19IFpF2185nKCTj6UO8RW18787s8jP3YY4za
+0EuDNZ8aTFtW4aaESF2pw03F9UZ79Y1aX95P2a37Lh1uk7t075e4DRDFN97J8DP59R3LC1ldFWC6oZA908hfAJh80A
+9TJ4HcCeqFUM7dE0Es708CF0ElS6Ly8su1cO6CT0ND8gY4BH72N8tjErH1VXDx0AFO9jc1eqFT69BeBId51p99AEvX
+04MDaI632G0mFmH1jj7sn8Yt6KJ0Qa5Y9ABMD0v7BFGNE7zY9Q9390BI6C0E7Yd8L40KZ0OI71lCu0AAH7nz1Lj9kG
+9KI0vd5Lo1Ao4aq5HlB4i5lm9gi10wEnQ0IpCOB4Tv9Fg2tf2NCDUm3Vb4XwDFBEaz2fv70e6So5VCFSJ6UIDtI0Qe
+4alGJ0BFK1KtFa18u0ALvE6yDlO9KBAlOAOp542EKa9sq9mZEu91IXC2bG6Q5WvFr76zj10l4Bm4kw2ua29S6eu7md
+Dwe629D2e0GL6gA6Re1RRAP44J8EPY9T64Kp8hyEQ6Fcx09LEDTGCXEtIClkB7h2fN8VIA8k6Vo5uF08lDG1Fuj3M5
+8pK3Ji5uzDvcFiSF5VAwlElA5FqCPTDr4G5606J7QHAHZ7821n6G3uEoB1MB65jFb7AKuEs612Q2n295O7na5XeB10
+780B6mB6TEVD3ca7tf1ys5Py69e1wX4DBEjo6W31ag9yt0sI7Bc6hB7R222w8LS2ATF4Z7T5E6XBx59rz3mjCTHD3d
+CkcBYQCNl8f85Bu9ZQGFM7uR80OBvUGAzCqQ3bo0VzBTCDCz8GG4Vs2tLBF6CT2E4M2GbB2P8Jt3Np5l63Te9jv9PI
+8On52D0KPCRQ9ee9l4DaLEha1IR2xBFWIBAeCmiFlb3RXGL62x971HBwDFCp1e5FtS7MS2Lk8Wp9dn7nq7l605Q0nG
+E025HdAOV2ax4Q42jY8r6AAY2J6Fmt4Dw5CP7Lo8AI3gu4613xc4PCAQjFS06We51R5iA99bB7i7BgAEd7Hw0rfB95
+8pj8IlEjL1C95ao7uK2IZ9Ud7B01DO2me2ET97V2BE2kaBNi1Mr80340o0thFMUBYG7oS0fE3oM3siCBcEZx20oAYR
+EKDFRr1cw3mH2CK8kt26u02D0hv7NyALG1Rq2f67fT92q8JoDiPBp9BqE8eOEbdAtg7IzEb75LUCVB2D15QL8TV1ee
+0mv143DKFEKu7MI46o2ZG5Uh6ur0qY29vBY541e2hL356E6NDhw4eFDzE2O410PBnf14C68NDO5C5VC2GFdqEuS7Xv
+AOfD787O68Dq4rmB3g2nY05lG7l4GF7CfChe6qq74P0Dz74A1hr2h4FDj2j93DDBFnAOr6i2368E1X68ZDjfBNe4rr
+Az9Bqy7SW0jR4W5F4QArO5wD5s56hHE5z5z502H5WcCdpAlg3QLDdn2EH3sp9POGCf8TO2j0G6S6zYAyBDO132iDhE
+Ee2FCk0P72k7BRT4GI8YZ8rCACa7jd6AV11I0L9GCD27e5E9De4DNA4rt1UE1qE6vNE4x8qMBsZ7ZzAz03dhFfO1z1
+BGS9gm9YL8UDGIuG3I1WQ9h17zW5lAEAv0QX4AI9RMAQ44pH7HJEMO96s71ADCM3xLEFwErt5Xp19m96EEmF5VL2IC
+DrY3fBBWh6Nq0I33cjC0T26JCQa9R5Bpr4NI3FAFYL68r6k9B9ACimCLp7ZaCqo1SfBlRDqO2yl1K03JoC585aWFsz
+6qXFs49al1wR6xo5h0CF4Bic0Ah0hfAdN9WW5XY0mk8ntBIF9934lmCVR13q1U8FwECHR7Mj17sE2BBhw4maF1G1B1
+Bty804CKNFoz9KgBZa20bG2W2t5Ef70VZ3GTF0f2OZBOtEnxEWj9EBAWN76T5HH42CG5NFbU83bEdgFCC8SRDfK1eM
+EoD7fO1Ze7JW72C7f06tkBUr3qaCvy4AVBdEBvzBfbFch9vO1di4jnElK4sV4H56M76JoDIM9lpDvxBU874f09WECo
+FMt76G3Ve0C55sf32P7ceE08AAo6gR0hFFUB3yrEWDDI42W0Djq1gd20kC9SCBr0gT0nd0xG1R28XU0i54y0DZbD3m
+2aeBwa5552Cf7Os1q0DLvAC5BPQ0i20fJ8QBEcv0A2CPs5fB9gB9Fv4hg54k4YJ62K2CZ8XK6iQGN3D3eAWb8dV0SW
+AfC1ug77x5aw8cu94b7vvBoZ9GSAco7uFBQx2p1F3BBQY5VTDIJDGD3ih2Zl0Q1C9dFWJ8A3GMPEpl7bc2Nh9M7132
+6J5Aa3Apt2pU2p082TBHFAcD3poCse2i1G8H0nu5cLE5t6rPAof8Ny9Tf4QK1LvFqwFql46ICBW4Oy3549JtEW30GV
+7kD1tG58Z9FDBDREWx7my3X8DeODv6Fz76KyEMv1lN3TRFFC0BS6Wg6fX1qx3ItFHf3V29NbFXo4YGFKv9vTAVE8na
+BR51lH6HI9c6BX64K47rW27VCM3Ea3FOW46f1lvEiPAmH01T3p6CNf6dZ0Jj4vtAZ5E1R7Rz1SKCHc54H0eb68hG7I
+4Ml1SLDU0EqIBHT9jbF9fDXhGDAFtqB5f8Oa4ls1r88Ux9Ww33H22V09B9ew1s4DuI6LxEemB9g64rBEQCKD8E5Bhl
+CigDcF6DUDrvC1h7uJ6xTBbI6i8EfvC4y3dF9A11iEEKtAZwBRGEzO2fg93L3au6lV8690AQCDy1uGAxhDgx5Dy3Py
+8e3GJQBwf7qP2ew17h18f5as8Rn8nUDzM4iv7dDCcW8lk9j22sx3sb1ogDc2DsIDeXBbaA3w2Lq34q0411WVF3I7K5
+1egCgPDLY8ug2T081I5iX1NXDEQB1FA224peAOl3un3he5ruDhs45M7kB0nK5Qd3Xe0Wv1jA4SaDJR3Ff2363En6WX
+0c50wpAJIFrE0sd65901XC2N6B6BzB6wx43A8Nk3uGC4Y3PDF9Y12L9ojBVE6655nPC0j5idCEXAjY4zyDafAQl5Ur
+D9uA6MBj63VRG2m3BvELFC33A5QCnq9srBvk9JbC7O41HB9x34i6Ej5uEA3S79V7XkA6UAM4EmD20PBaSCfz93iFU1
+7hMCtg70nA8q0pM4Ds0XR6rvDrVCuw4R4EUU0Fm5JtB7r3cy5xDAgP4zn9af2AmEDo29J1LV2dPA076Wl6FV6oH76I
+4ic4AfAOJDBD7w89B1F1u2MS6u535GCok3Xo7UR9zk1lF7Ty2AGAYj45h9gnG8PAc9DHT4vl6n94drDYQAie5oUG3S
+4lEBf5CpK2Fh6UUF9i9h72JIGLGBgw1fl4SX8O51u006bBAz60oALB67r6B1FNqDz9D9GCmLGEBBsACPk1I16uZCdK
+2ZKC6cBAd2cF77B7jh0vjBXG2ACDCSFdj99D0L100kBRQBGL6rT8hX5XtFhqFmw9AM0pS18i7pR8Ah7mr3Db6k2DYX
+1QMAnZ9TA9Zu3ZqEkAAi27BE6KB8KXExEEks3Jb20JDvd08d1OSCRZ2bB6YGBnX8ym2BR1KUCNoCdHFBpCVUBP80qZ
+DT84Wx7Oq93T3dIAhQ8s74Vj0xTALL0b0AMs7G07qf05FDS71uL2NP1vhFY86iGEQs3yH3Lk7UaBaR65M8V89CbCvb
+9bG82e5kJ6PnDXNDxj9uiCbgCyQCtDDXp1bL18L1YFFZqFriBFoEZT6SX68n8DR0xz8z28BZ4ZYFLR6O5BNr2wWCy7
+BRt6geCX117fCE25OjBkn2Ib5Sz4Oj2ys0tyAib0C49ivBIxAEE1si7qgAsy3X40tFB4T2EC8CZBSo7P86GHFRA8Hz
+Fdr8VLBBM3Rp5zR0FI3Z9DGg109F6s7ge6WnCIvBlh3No0EF5Wm4nM6kJ31B4EkBOx71E6hcAFf4Nd0yVBRV0mH763
+7eg7etBpk2mxBWYFjm8Oc1rQFcG44zEk42Cv4gmDRzBcyCr24qf4gG5W53c2EIjD7P5JB5hbF4RG1w1O6Ayc3ld77N
+0j60bO4M1Dmy68PA6mC0QAm90pJ75j0Wr29y4fpFjqBVW4Nl67zERz3DpCRk8Th0Ph9Cc1Nz16C8O47AaE6n4X9Car
+8LfAJP9yc9MR3nx2ZX8UTD0aBE6Db95u01jZ5kS61fG2I11LGC0G54E9M6btFBvGGiFx1AypFYvGIO1f95YD5ycAPO
+G5I3kIGC27Wc92c3D50WS0vW5qDAzZDSB9ax01pFmICPh9sv8lWDLJ534Caj9ub5Il8soDarBFXCtZ0pWDSLEiXFLo
+3QiEvy57R7hh0Wn9cO20CEw835U7b08kh31a3ds76yDSg6x65fj5RJ95dFQy3Ab77pBe84kPEH38ToAQf7c5Ab50aJ
+68R85QAXU5p557X5ZP6ka2KFBgo8jN0Ds3Ct0V2349D1e0KRCWd0rm9ZfCNHBxa3LK4Fg9oWA4W8uO31f4vSDQS4Al
+8wC0liCxG5iCE0a1SuCP17JvDRg7CDEsyFXOFJpC4AG1A7eGDdR4IEFv3CaC0tYDdOEi66XlCkZ7LH5sbFKL5Ff7iw
+CL510RFqN9uIADZAoeBiXCARCZw6X26CS4b86e847d3FhFy2GGeDIB8qlF28Ep8Cbs0n66rjCbV54zDwy7XKD4ZB12
+4bG2dr2QnEO5DYf0X7EoZ3kP3HKCmN4tbDnq0eY9ku9dD4644MPFoLBriBnAFsfEjFGLi54fAXJ4fQBiK9EM1W6ElN
+3sXA7G3qpBaW4F29zI748DYK2oLBBu3Tu7XA5OlAgIDUr7sS14x0Rq3fUEvN8a91Wc6mkAEw8iNATAExi94QBTY1e0
+3mL6nv4G0DkQ00IAXR4mIC758yj8kF5LN6D59128MqCHh0Jp1Q096F9xN7YK6rzEeI5j674h0r25KK2NH7xO0D663W
+6oA0Qn0aICsfA6nFXm1hBDBE7hm3ps4jq0f84xgF3HFr8ATG7lV6lX5TF0GOEeA34kEIJDep6jQB1k31z36cEdbAle
+BJpC4EEIl81hBSrEr51qPClq7uHCDH14ZADS4yv1grB8r5Rq4cP6FF2RB6ebDyV8427ES1lnBwq0Mf1OpDvPBnPE0y
+97eC3f1CC9XqDkvDE308B2d751J9UE3SF2Q47wMDNPGH6C2M2du5Cx6sLCiADVH7xwCLqFuy0ya78J5sZ9nDEiH7YO
+9bW26YEfFDTdE3dGGjBf8FxE6kS4jj4fjBlu6mZ28h8kf8aY8bV8SD2pV5xI5TRCuSFcUDAkEN5AYF5KW1I4DWj7fF
+74mDej1uy1LsDbNE9VB085qqBIv2QVBAKBvyAN75gu9Px9Vq7cV6A4EgJ1OQCtdEev4EO6XSEujAHGEhS0EE0fXCZa
+5fcElOGBZ1Uy30i4ouEwU0pY3T6Agh2vY6gK3Wy6Hy8vP8LU2El2bHDwz9P25XhEVyErO3wd8wb7ICDqJBll8aI516
+BmQ0Vh3oE3gk5An6L6GMuBWR0yZDMeBxp3vm6IE9M1FyuGMm8ZgDKB4g91fn1krD776K7BF57I92YX03LFdE1fT57o
+7ZU8AJ6Io7KHBFt8TtAAiAst41lCZ59mT0VL07D2bI4CxB1W2Lp2O10OX50W2949AGFaP8IiCwnBMdDkA0tb9p80Ms
+CXd3j1DwK6zy9hZ4ja0hhDGJ5Hv9eQ54v4IgCXL6Kp09n0vy5vTA5ODLS6gtFOI53M1qg2c0DMMFIr1nE8h33KwBkb
+0XM0XEF80Fjo2JG3BIDJgEZ2ADJBLrALr4QP8ooGI25nLDsQFRwAtq58J9sDA248vL4ZLFP1BpU9hXAqr0xtDjaCNP
+2RLEuG6dwFAS0MjA6TEHvB9C8932Uo5OKEMq8wiErJ2dn8rbEVB7rX1GJCwL8Dp3gT4E55svE2L9MUEgnF9IF1W7u2
+D6cFwZ1b5EGI6qhDnx7iyCUJD9Z7NK1bi3K95iT2c31BX7mZ4GcBJv9Pu8d21ozFewFPFC3vE9EC8v8TpDW07ZB6Tk
+14H1U33ZyDhzCPS6QvEPfA6r4HZ3IZDyl1MlC1n7QMFTfAuZ4ljB1d4iZCue5seF0N4eK7Pe3jSF7v6ko5rJE61AI8
+0Ge4oZCgs5JnBOT0fN4hTFLs5Op5QvBnJ26m1DzF4f6471uZ2DI3AUDkJ7HK1W96UqALDAb69aJ93G00MEC3B393s5
+77mBCX8S092QBE83725KD1O35s3AfW3uU5ZdFPP5Ke9U9Dcb9ajG2B5NR9QF4ZbBto8xb83X8zn7QyCod5ZjEIm7Sa
+6SgBEE5iG3lh1Pu2OA04Y8Au7u62itG1I2yRCkSCRd72JDbVCTO64W1os82F8Wc0919ks0xM9XD6Qf2fc50C15p4GW
+2nv3s6BkY2E6FY3BIk0FWAmu2XH9UH1nfFgW8wz88lG018F54hy5E57WvA6X3yL0Bt2cc083G7oDd58xS6sxBQ0Egg
+1Y8EpNCtx2qo4i08BA0Xc7UX7a6F58BkJ07bFKn7A22S9DE0BPHETcCdW8DEAJ7D8lChHD98BWp7z9EQeEeC1bXFAj
+ETzBqj3HPB7fAyW1tV8lK22x79A8K6AohCRfC7EEMYFvi7ZV93v2yc5jUC909Rh9KcBYD08Y6Yc2kN4e2E8sBc9DsM
+2808CyBTKABb8ku2zn5Mf9tuFGF4pX4aG4xDBP06cY2nL61jAMr1XV5Ka6eG9he9rMFkD4yl2DU92VB4K4Wa69x023
+Cjw1TG58I0mqB5n1F97nc85H0Gr83e9jC7NuADyCA786z7jVDzA4jG0pN1peBkL3gs5lQEDXA5i2j48Xj99lCakGAj
+FF83Ym8eVEl3FSL27X1m4EuZAl25gY1pQBXM4Sb4BFG16Ec92QR4XX7e87D34MG4YNBAWDLg5790QV3eS9Nj26x5RV
+89YBQqAFB7u7AeJCkgCYZ1OXD1w4Rf3mrBp667i8vj9LHE4F8MR3ZX7OCBn1E8Y1El2aT54i02E0vC9vUAnVFHlEoJ
+2a74wW1e87yW0tH1mh4A56g58FN9OeFUF0kY3YQAB47TLFEk9Hx65xEkzA2r54y6o5Bd47BlEN65tg88FET894l5jC
+5EF6Ni8bA70hGEg1v14jZ896AdO4BM5piErp9Z64dM16Q0mG7gm1oUBhN8x90QjCXF0yf2RpETb4et2Xc2Ke7Fj71Z
+6Y5Blv6Nx9coAJbF3018W6N73wy3RV2Ud0fF6pI9LE6uE1gi2od9JXDyz2ZOBO4Fp09SX0H38if4jp10L11k3Sh9AF
+FELExn4YQ3f856i5fJ0gw4ODA6bFI06sd24Y7hKFtY59o4EPFDPAOmBkCBlX9KJ5BiBrM0jj5pJ7bb1ikCCsEph3RU
+8yYF4L24I7OyFGO8568Ea0lM9zF7vmCJBAo70xWDuF4lD0aL3tK86HDls82a7l00P8D9d5nH0bRF69BbkBym1fw7Lp
+1bJ5qZ6Td1p16r50a23Ev2dG7pi1LJ1bS57p7Lq5Q7Bpb1f6EH948D4f87BG98xEcs5Vj3Vy5BGE122VaD1nFlMDDS
+ASXDgu2Ei29Y7T4DVACid2sH3HGFToCsPBTg2L67BCB501WzBrX8dv7720oC8XTCIH5J19NE9fTBQo1Hg2GY57QBrp
+FNg2XwBqG67hDDZ8pV6uG8Qk457FfY5AU8F2DVpCgpD0f4wMBsu8YhA1k9xtCQ4FTn3BZ5Xc43GG3g41hAynADT8H9
+1es6XjCPGFosBtB2Jb9kX2M1AiOBpWDbLBDT4wa6Ng5L33CP2l00OeEtxAeK6Vr4bXBcx8Ft8XS7yTAwr8QC6nj1Iv
+A817LVBVG6Sx9CK0Zs42iCvW3wH7d10UD4Jn8Kb3MADvN95n5jHF4d08ZFAa9xv8t4DT1EiZ4A3AFC0W80Vs70T1H4
+EaO9cSDOc61gFzDAsU5k82UPEhdCdO0vQAQY3iE7dv4kr7HTDEZDRWDprFmp5mb25Q4Ad6Dj12jCrQ4DUFQv4Nn6XF
+FqX0dhDi41iJ33iBPI7No5G08IrBYyFS77RHCO9CzdFinDhP9dQ8ikDPO5Ej2QZEEI9Bb3cd5GOFs68RmDrLFJcBrE
+5fV0Rc9Zq48q0O2EDG98k8dxBd09sO2sE1RaAPaB964OJ8j8AR115VAcu9iUB9M96D0Cs20Q3PbDFaE7VFAn8Lt8bH
+3GR302DPT4LZ3JvEfVDkd9Ra3vhBJ1EmUAmvCwR83BFJvG7640QFxGDmN3Z24rg44TDA67PC9o57WZBKM6bs3Cq4vp
+F8MEwQ2V54nFDYpBFwG9l6TH0O306UBra4bb5jn2vPAau3SI1Gu53gD4fAnW4Ms8KU2EsEQ74qi4wt3ZK9dj7b4Flh
+FpE8Tr63a0bT1HJF4q78uFLx68KGGu7J0FWoEe36eoAS400oCuD0v42jfBD9878AwXEVRDD80FS3Zj66SCfU1Ig0tE
+EA08Vg5rgAe16nYEHtCmlF5N9y6A3h7GJExq7Db1CiCSH4i58Hr2lYBia6S35Gc94xExeFBZ4VIBNF0HNFyQ4pM9hI
+DXcC7iBX77pX6TU43yFeU5ZY6lABsw9nMFXuEKj4mPDGNBzJ1EL84M1HYDJs9nXF3W34IAGc3KpFML9FiBFi3gb5w8
+9ye7eX0Xy45NEIw1AfAqH75o3WkAJQ05i9088lUAkF2aO6lr8o98J22JJ3Hk1tpAJNEVU22N8eRCeO3sm2mPBqR67N
+3eiDIk7RPCkWEPgBtADiIFQJE0lF68AYX52cAvP2Dz1FJ4Si5Te0F082N27h41Q1TbC6J0Bh8A9FYj3Z7Bbs8qD9Fy
+AvbCc9FnS1r26IF2VKB1H0rRFVC5nq2X50Di3of55j8gmFtbB1JFYe9EADyX2y6DFk4Ic56W1Pk5Ox0byBuQ96YB8B
+FH0Bv06TR27T3SO8oY5YBEkD7Wi4naEGF9bc73Q53TBVm4EK8OzEyz2KsASE4eq3SkB3iC0vEcG5R17JL0uMA3cBgx
+2Du4cu3o67DhCoFBAIGBg4XZ9xaBs05UQAqI3M0AM04lVFHp3lS1so66vCRb4Kd6Ad6X14d29PeA2kD9a3UbBGM4xS
+Eq99sd5bwEj9A8x6KD8mWCHzC9w02U9Kj74MDKu7av55g1Pq6ceDF23Ov2pyAyH95F8v38DzEIZA4qFHD75nEhjDtm
+EVW1fQEy74Jp1a52FX72Q8LYBZ83I62WW9634Yv46rD7tBPd15AGMnC1E0Eg2s4Dyf6cVCbm9xF2OT3As0LD4ckE1d
+CkQCYLAzb2rdBep76hA5W8U6EZvBTWCB8Et39JS8kvAjm4b01WEAXhCGuBdW2Oh40q9KdG5vB9KEMT8H0Fqt0S5341
+CvC3FV2HoAHI9SY46U1dl1doGFqCjrBHs4V9BBJAOdFxw4RW2eV1UV6bVDAA1XU5M50fV5Hz6fH5mI1YL1D12hH2vI
+D4A0zB3WRBkU21XBDb7JJ9OrBHbF2i04PADK7kY1Nj6mMFw93fD5XAAeW68UFz22Cn1kY7ep8x6GG41HeEqh9gqE82
+3vp4Cs2Gj8PcCO3CGq8xr5v8EFp57y6T39eG6DS4QF2D2Cqu2Ys3BX9AmC1I5pW5K50SXBMzFNBC3G0SC8264aIBTP
+Cqk9cX9vv9nf9e216M7Fa2YMATh1vx64LCvZ8U21NF4CZ0PA4LeAUL5vUCD54HK6qe7K67L9BXIFKbETi4AMFxW9qi
+8Wb6rGFkjAXo0kJ2ExD586Nj8hUA0qDen9oeEmG3h44Sj4YUEjqGCHB7q1fz4EHBK04IS1Bn5a30jc0nEGInByy39x
+0CV2tc6l0Az46VF6g49VRDlBCil3yu5Df0KQ9caEMH04Q7EB7WG2AiFXK4YW92R4HFD9M2VS8KxDdfBAa2PX1e35to
+DoQ0Hc4FhAxJFSo4FM8vc58j4ijDdV3801FGCZ78cdEWOFU01lhFtZEexCAK6Ep4489V3E1w036FJl8gR0uPC83DV1
+0rH2UtDIfFJA6SV8fC3UF97T4RL9DvFd01UNGFd7QQ7tL8JmEiD2to2hU1wgCt7BLI0ehBOM2Od4U1FrfEDC09H1fI
+2WRDz0EMuERv7259mr3Yp6kZDtcCHuGDk66i1ay89N4aFCvJ5n771G8jF5uMCcJBX3AGhAq9E6u5tuEtMBcD6vuEt8
+8jS9VXDT01wpFLp16DCPM6e97sTCiL0vM4qTEKqEecAou1IeBeD1F6Cx7AbB6Py0lf5Yx9NQCoh7xq00J2Z574U1Uu
+9Yo5mi86t2hS64P5hH8U19PZ2WjG7M2cT3JzDhV9e46r9B660DNDRqC201rx6I57WS39V0VJE0v7YX7bq9wn8Pf6Q1
+F3REQ1DoR3LM7CnEUQ7Rl3qD7F876QDFiFLuBeO98z868Cwk7505FPDAhAsXCwy5tX9Cr6dV5zW537EDv5hY6pq8SM
+0iX18N5kdDNJBi36rJEvmB2CDbRFny4d0Em02co3zG68o9uJ9G9BmSAH9EjNDryCTzB3f5uQ4MJ90AAMa6Yk1E26Qm
+DgHFNM1Gw0vF206BZ9DJPC6hEsK6Of5Eh1BF91g96d6gh0drCwO0im3SG8Ll6Bp0teFRGDyK41YDU58gMD7j4uL6LB
+8El8qO4Q02Ml6ul3ap2cXBlGFUy7eM902G3o2mY3dA9TT4sjEPu1b27CjCWO4mmA9LAd83h15JKE6HEQo1wiBqr21V
+2OK7I13A1Chc81p2wY8bZBEZCpH86FARTAmL92K5X46zw7SJ5qj82lFHzF1h2Zp9jU1VLBz79jyAqd3D1Fy4FgK4RG
+2hu6lT4kt2gU5oR4o34vbBC6CuGCMu5mK8jsG4h1hYBVLCAg5CY9t2BpgAjI6JgBGW36j5sy0Nx2JwCCD9mQ9PzGO3
+FGy3xEDax38E91q4I253k4y6DBp4gtE9JEsfAOK0PUB8d87k68D6gM5qU7R6AScC6X2TT335DT6BY45d4G8x3QrBvN
+EhxAP240OCKz6P6EfBEAX1z92ie3Nl2uZ1sC2iVDPb4GfEo6EFF7tc4nV28z7zVExC3My7SS6yDC136mg3V06m99QD
+9lB08Q6O63Mf2W1ClaAgC0n08m35lf5QcEfk2Fk1wG02O3wvDvZ4G79F21Aq4u9E8t6dl1m83XuBJl7gY0B5FnO7cK
+8w93UPFyc9Nc1cJB0O5MHCNvDJ0ALwC1r2QADgo4pjCTc1uo14gCj10Vf3om5Jg3LVDdi8HFAX10ElBS58n8AuVEKF
+4d92wbAumALlGDxCLrBWTCq27ZmBwrG0V3MD9Mi66tD0b5Gs266APJ4sPF826seC8b8aWFaY8zG2wjDm9AnR1Rn9Gh
+7xt79ND1q72EAVr43N9Dr2BQ6Iz3B68fA1MxCJaDOlDSl6lWGLF8th6gC3Wa0d95kKACEBrg8it82491P1wn5n83rr
+5VuBm3FnW34O76c7AiCPe1h20S96isC7P71U56PDP15Ed8M2Fhb959DA38uA0cPBIC8I0EQfER5751GJL96C3kVAmj
+5wN4bu2FJBb72lj6Bw8A50jmGDzECk4saDFl0U0EHNBKL4a3BXr89K6nCAl7GDIG9w14eCCA4UPDP56Tz6IMFey3V6
+6gYF436PG4zoCXB2lcA6LAdBDNUEiIFS82wrA7I5vl8YQ6l346ZBVX4nW1vC63G7G61Nx9bFE3fBm2BrU4wG1qH4TV
+5Ir5AG61eA2m00n0LB5pyCcqBp8ASLCtpEkn2AX8GO3ZI0x87Rg4FI31c4Wn8tY1DI3bhAQN7wB1ui4gc0llAKK4C1
+Bm7Dml4cQ06r4cq2sk4VWAE3FU77zu8Ht7qG2loEAkCsJD2kCtzAQyApjGKs7Yi6Uh60X5qJBF1AqP65zD5A7ll0ga
+6qGE8aGJw3rq7DC9pz2Nq1r59uK8E30WO7eW9tV0qVDGf7KOBwP6vL3bAD7m6C50AU7wO8rWCdyGAx4y9BIUEjbERU
+6OA8ld48k9FSALSGJn2wa2bo9Ct2HO1m16tKFOVAfiBiCDXzAsr5EK7im3sNAxN1sW9v340e3BAChN3qQDaO5XW5Jk
+02z9fBGKr2Cs5VnE3zFpx8Eo2EW3M67YIFyp3wzFJy7B53Bk8ed7ayClf9EaFaa6ZE5MA9poCIZ94c2LK25I1vICS7
+Eig27n2EhA8O9xVDREDgL1aA0vz2UUBVz7RyCBH5We1DZCp70tX4qGDrp3yo5cc2L3AkqDqQ6xS96p3sWAZDEfD6zK
+Cg27km9eK8qo6BL1lRD81DGQ4n31mUFPqG4q9voCjHFnRBWz0V0B7KAG59P7BFjEQUAJS8po4oB5Bj5Mu0uZAGq3F8
+6gN0Lo6GS0y1E2HCQk9Ve1WNBF2Diu2F0Br50IOAlc1aaEKO5S07eI9CW43oFJWC9ZCwaADnG1R6qoG8C8qy7aw9PP
+4VpDf2AUgAWq6zfD5C1Hv7OGCWVFFa3bZG9gAaA6WqEunGIg32E9OX8d8FR51li3l1AiTDi78LND2l6E45JsEJECW0
+GAT3rv9UzCz7Cnf6mQE9z1jX1ffBmgAw30cI4lN67Y1ojCGjFxo4t7FBkCJWFBb7uP7FPDImCPV5tm4rNEPq7wG8pk
+7eU2H02ZWFg73f3BDZ2pk6jPEtR8MJACL0ze6Yq4gn4bZ4Kj1Ix1z5EQvCaW0y81tnD6q9CSAa9B9kDRmDCFArhEep
+0xJ2Nv6Oy2bK0dOAZp0nF3eF7tjD525wbCnn5T9FOH7b3A61CnC9wu9rsCEN8YbGMd8oe7jr8zI2NmFxC9wLERR0Vb
+C6x6TxClbGNeF9qDF11Oj9BTBuyANt5IaCEA1P0D5c31o4kqBwW6bz9D8FH8Auc0opD3g1vPA7x5f8CCYDTV9IU5dE
+5YV7xK5CB0jv5DTCjU2To8QIBZt70x9OiDZqA1bD6N1rh0UK943GBw5pv2215E8DedDBL0niGFcFpS63VCEJAUo9G6
+8z03S07ch1GrBYn0td8hMBLa1fGCDsEqMFpB9ws5d9Fys58A9G89Kp0ViABSB9ZBLt0U4FZ4BHIE8yAYYB2O8go384
+5km6kp4zhCz27Z6C7Y0pqDRJ0ep2Um0h0DL6CoB4kb4UE9bl65HC2R53jFKlCClAY17W7C8z0ab7cs6qzAQe3hx17X
+6Rp04d6EG4lc0sfDNSGKL38pD1980kEFo4Qh7swDw9EEo5N3EDn4gs6tXFmT0ILB2f8k07bn1mc6m3ENkA7z122AkS
+DwoC1W0Um6ogCAc9NS4G32uv0Nl8oxD7UCC80iM9LI5c28M4Ezm0E9BZNAOF1wa2ekDOK56b7D02K380Z0BCC4vBrl
+7lr2CaFk0Bc1DQ3BWO6bG4NzGDT7647UY48ZCn05NvCSWEhF6h3F7zEcn8OdFff2AZB9y0wJFvCDAY2HU2DB9MXCWf
+3s3EJ1EOq6gx7JK3HU700EvbCLD4le24kDniDZ0ALk2KR43d4nw7YW62Z4pCEEUEz72HdBTA1b8E4eFXMCHr4JMCxr
+60pDtx9Wc7ZS5Li8UnB3a4Pf9Ua6i6B4BDTvFMPBN34sm1VZEqLCL1AvtCdi4pt9Ll8o24CS2Tp3Gb50NAMH7Kk9vL
+1nj0MLE7q3hW22J47t2Zu66R6CZG7jEpG2mHBxPG5zE9vBxLAGT9aL4FJ3g3CQG0Cm4xFFxpDlyCkd2yP43O6YHFPA
diff --git a/factory/gftables/64 b/factory/gftables/64
new file mode 100644
index 0000000..95410a2
--- /dev/null
+++ b/factory/gftables/64
@@ -0,0 +1,5 @@
+@@ factory GF(q) table @@
+2 6 v_1^6+v_1^4+v_1^3+v_1+1; 6 1 0 1 1 0 1 1
+0u0n0D0Z0U0Q08070R0y0N0q030G0Y0E0d0s0m0v0g0k0B0f0w06090W0i05
+0x0S0c0F040j0h0X0H0p0O0L0b0T0a0M0z0J020r0e0C0o0I10010K0P0V0A
+0l0t12000000000000000000000000000000000000000000000000000000
diff --git a/factory/gftables/6561 b/factory/gftables/6561
new file mode 100644
index 0000000..30159df
--- /dev/null
+++ b/factory/gftables/6561
@@ -0,0 +1,221 @@
+@@ factory GF(q) table @@
+3 8 v_1^8+2*v_1^5+v_1^4+2*v_1^2+2*v_1+2; 8 1 0 0 2 1 0 2 2 2
+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
diff --git a/factory/gftables/6859 b/factory/gftables/6859
new file mode 100644
index 0000000..c635bec
--- /dev/null
+++ b/factory/gftables/6859
@@ -0,0 +1,231 @@
+@@ factory GF(q) table @@
+19 3 v_1^3+4*v_1+17; 3 1 0 4 17
+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
diff --git a/factory/gftables/6889 b/factory/gftables/6889
new file mode 100644
index 0000000..395a464
--- /dev/null
+++ b/factory/gftables/6889
@@ -0,0 +1,232 @@
+@@ factory GF(q) table @@
+83 2 v_1^2+82*v_1+2; 2 1 82 2
+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
+1cv0Y80wP1Ue0cZ14B0SF0jy1KJ1W501R02t0pv1ap02d0ur0wD01M000000000000000000000000000000000000
diff --git a/factory/gftables/729 b/factory/gftables/729
new file mode 100644
index 0000000..89e6980
--- /dev/null
+++ b/factory/gftables/729
@@ -0,0 +1,27 @@
+@@ factory GF(q) table @@
+3 6 v_1^6+2*v_1^4+v_1^2+2*v_1+2; 6 1 0 2 0 1 2 2
+9sAn684C5b8tAvBd6e5B1b0q5p7o535v6E3B1R2h9H699zBP1W1L8C448q3n
+8c5H4n8T9T2W6z8G5j2233Bg6j1C3PA49F610t0a6w866Z9X3o9U4J148W85
+2e0P4L4S1J6h7U136T9L1ZAjAUAN4Y3y4u410f3t168PAb0S2552328K3mBN
+2wBD2M108Q458M3R2d6x9m1vBi7c4v5e1E7Y9S5G9D88471I8zBJ5R902066
+Ay0Z991eAfBY5K8p8R9P1F3a2c3hAD1V6q6i5N7g4FAI2K6J4k2C2f6U261k
+9t7I947R5P0o7C7P7x0d6Q570B6pBQBM8r4y096N1B3r503C9MA7241Y3D0l
+5mAH7w6L8Z1D5y5J1H5X0y1c7j7m3v1o9N8LBSA5AiBH7r394g1A7f9o6d4X
+6D3F4h58708h93At7yBj407d6R6m1u3q6k0A4i2Y2y5V2n0JB20n1zAM4OBf
+1q7V3I9EBT1j5r5t8J234Q1M2s2p6F0g2F3M4D6c960M8i1UAK37BK1K83Ad
+0h2m8o8AAcA93u9i742iAp30BU0Y1m730s0V1nBG1a2A7DAJAE0D7tBc0397
+720W5q275u5lAP4WBe3l9OB65z1i317p295C5U9f3g3S0cAu1x4b4s0E1P42
+7M4M49AY980u7kAB0b8Y7K3s6G8X3T959pAR5k544Z7u2S3W2aAg60Ar9k6Y
+4m7X9QBl3Z1hAh0k3x550F4w8b9Y8V2EAeBA074p4E3V9e2z0jA61p346s4j
+2J7E3j5AAWAk21AS7q6gBLB58S5g79A0AF4V0L048m2j9g8O0w644NAV6fBI
+5S0p0z8x0x7O2B4H6y6o367B5T5Z2U9C8d6a8s7b7z2R8v7i6vAC6I9w2Z5E
+BB5h6B3k4PA8846H3i8k71AZ638y4T7s4t2Q02Aw9q8I28ATAX920N9l4I1t
+1s9V7W5IB73b9h7n0X6W9u8j7F8HAm1lAzAa118E350CA13A2q430R8B4R7N
+5Y5D3X1g1GBZ2o193G6S4K9a1NBb4a817T6r8F596CAO0m4e4cAG9d2T9y2H
+2x9x5a3N4z7L2r9b0KAQAx7H6X0O2D15AA3d9A2G6A8g8l4B9I2V3p9n5O4r
+4fA22u4x6b4q7SB4BR460IBa2P3z01801y5Q384U4dB3821X0T1SAs7J6M6l
+3H9W8eBO7AAL914A05763Y9R78BC2I6K7Q3U7h5oBF3w3E5wA30H895L121r
+6n2X6tBE0r9j1T9v2L6u1d3e0iAq9G75BX2bB82l3f2k3L9B9J9Z0Q8D5MBh
+6P5d0G3Q3KB91f777Z083O8a2v8f5i7G67BW065F8U9K2g0U62B02O1O567e
+6O1w8u7v4G4l873J8N3c7l0v17B19c5n8w2N182t5x5f4o7a5c0e1Q516VBV
+Ao8n5W4865Al9r5s00000000000000000000000000000000000000000000
diff --git a/factory/gftables/7921 b/factory/gftables/7921
new file mode 100644
index 0000000..19cd5a5
--- /dev/null
+++ b/factory/gftables/7921
@@ -0,0 +1,266 @@
+@@ factory GF(q) table @@
+89 2 v_1^2+82*v_1+3; 2 1 82 3
+1ci11i1aH13k1M90sO1y81lp1Oq1240zb1220fq0uP0Ek1En0gR0uM0x50ir0Dz0B00fG0To0Cv1jE0oJ0zE1mh1bt
+0FO08T0TK0pk0aa0zh15K1Nr0ES23F1bF0dP19U0IX1p60Wm0qT1x30db0Cu1Gd1bc1dM0Xj0jo0Mq0vb1Ae1Fp0rZ
+1yz1Ps1NZ0ay1Pf0xS0A41U30ZB0Aq1Sq20K07S1Hg1nS1ds0tL0Q41kL0S30l10nZ1VM1gf1BV1Ll0CA1tZ0LE0kS
+0ZG0uj1fE1nJ0z51GN1oV1rj0d20gM0PW0u002C1is0WY0QR0Sb1rr0IP1nX1PL11o1ud0sW1vD11w1Mb1s519e1lB
+1DM0tE01O1Iv07W1e718Y01C0q607603Y0Qn0C81HW14d0Na0531in0MW1dU14K0dp1tc1RL1R00ot0pu09H0Zx0In
+1WB1490hQ0Xv1Wc0xm0W920x0qt0LP0e021z0nu14y1df1fD1z60CT1vb0M31431vt16C0gZ1FZ0g411H0nW1AA20q
+0Zy1VS1ri1qE1Mh09u0ro0pq0me1G220614W0Yh1ec0Ai00Q1f30ah0t105S1ve1We1lf1Zc0I00Mx0jy1G90Mn1dF
+21K1nB0ow12T0rv0vt0tI1xK21H23j0Hd0ka1hY1Lz0NY1G60vK22t0AU1TV0b11h10YZ1Za0bV0JL1wW0iz0D21F1
+0X01E71A61g81ox1aY02f0mU1Xv0Wj1bj0571s418U0UP1a10rq1iY1es1W90mf07P0Gb0XL09S0nj0xx14f07a0aI
+0ZP0Uk0BK17M0aE0Fz0MU08f0LV0GJ1Uf1mG0Nd1ii0Es0Jx0zp1k608h1tJ0Ex1Hb1lq0bZ1Te00l16y0Zs0g81R5
+1ke1Xt1rb1VD0Pl1Gh1G00UX0kR1bx05J0Ly03T1Pd0fY16f0Hw0IV1pk0LJ1fu1Ie1tv1ef1Dz1Sg1zH0eq0pe0Lk
+0oy0Bk0Kf1bp0yz0fT0sp1Fl0f216I02N09q0Dr1Gi1hN1PX1r71Nt0ba1EN0gx0A61Fe1RR0WO1ee1tQ0Dy1N50ri
+1az02U0zx0U30Nr0kA0Cf05G0U01pa1BL0Tk02R0bd1FC0bF1op0Yu0qU0310WM0UV1PM0Uu1sq08V1JZ1Sy1940AI
+0ME05d0tf0oF0Z21ge0br1tC0L60cr23G0WG0Ze1QU1xj1C500d0ac1Yk15y0r30sJ0nT13v1L11l41aZ0If1kh23T
+1wG1hj0la0XG0wE0wd0KJ1YV11B1Pw0OV0Ar1f70eM1pz0hx03b1dq0kf0A521I0RJ1AV20b1Ht1891Go0rS1z70Is
+0vp1PH1bY1iv1qX1Hk0P31zE1jo0o81xu0bh19Z1tX1M119g0rb1sr1St1Sw1q412Z1pX1O90Yr0Fn19L1kq0uf1v9
+1xm13n0qd19O1MQ10w1ZQ1BO0HI1Qb0fl0Qv0gO01Q0SE1x90jI07n0KA1oJ0wB1Qq0n81WG06d23f0NU0H61GQ15n
+0DR10V1i914l1Uc03m0xy2121QH22v0Yb1Vk0wQ05N1yC1Yx1t10uW1Be0ZF1zw1Dx0Dx1q01911CU1pW1VK0aX0Q8
+0Ho1oc1qh12o0D623M1fl0uh1Dw1Ow0Yw0Gv1s21Zu1mz0Pr1yw1wF0ZL00C1GM0Cg20U1eU01h1wv0OY1rQ0wv01I
+1en21P0LX0s90y00wK0b51wi0rD1D41ff0hW0be1qa1ov1OD17r1BS23N19k0zv1zn1I51BM02w1Qo13F1v705a1hg
+00e21V1Kr0R41Zx1AP1kH0df09G1V00I70mC0ww1cI20m1NX1FI03w0XN1Nh0CC1G30BQ1Ex00x0ey0Kn1et0ps1Hq
+1c70ON18Q1zs0kH1RV1Jg0mW1D91r91lg1cD0VM05E1mR1JW07R0aZ1al0my0dL1wc1Mx0rL0BH0yE1ky1AW1ON0gw
+1Ls1U40FC1iI0Cw0l50F30qC0Kk0901JK0SY0bw0z31jr1zg0yW1xP0qc1cn1FQ0bY0xA1pC0gp1PW1pq0yo1jD1Qa
+1Sl1Um0Ol1BE06T0dX1Ku1O51CB0d622B0GO1Xq0nE02j1JN1E21ub1ZH0vd1kA13p0md1qw0UY1vT0jc0wg1Xr07G
+1X41ej0QH1OK0UB1c80rw02p1rw1Fj06i03z0rs04u1kE0rF1iw1hq1bd0FZ1vc1GD0U91O11s31Gw1kG1Aj1AS0kY
+1771EY02c1DH0EC0kV0K91JP15m0js0Lh0cO0l71tt0YU21n00R0Z91oC1lR0Iv0vB0p71vW17W0NI0Xu0Op1l10qo
+1h21qP0G80uN11c1E01iP09f0u30DU1R61Z71nT20S0Tz1UH0cY0gm0sQ1K71281IF10K0HP1HD10v1s72190Tm1f4
+1Bw1mY0CX22V15k0WH1kY0he0aU1ww1VQ1WA0l21X91dL17v1aT0N91oT20T0iK1Bp1tm00c1W50zi0kD0AZ1tY1Cr
+1Fs0qk0iC1k51Lr0LW08Q1bS14h0ei0VO1N21WD17Z0iY09h0Zv0I61De0OH17K0Rb1Vm11312p1IT0PN1FR21v0Ir
+0cc1YP0h10Vd0NR16p1KJ14w1Bu0t00Np15W0M51l315E0CP1HV1e11Dq1J60Oq0Ew1Mw0Kc1dl0JO07y1Av13Q0g6
+0lm1A50id1nt0QZ10g0uE1Rs06y1qk0P90Fs1xS1Oj12h0CD1t50DB16o17Q1jy01P0DY1RG0Hm1951mB1k41lX1Z3
+0HN0dU0zs1Du0iu1n21h81Yn0ML06m0910ib1LI1K91Sc1lb0kl1s10Z30sG1Er1RW0rc1LG05O0w50UH0TZ1br21M
+02t1e922k1lH0p222F01z1qV1GB14204A1RQ1hL0UW16a0qj1pJ0aA1sx1341pw04P1gv19E0Fw0ci0d302g0aQ1C2
+0nx0Nf1930tV1oe00P0B81WV0ua1xb1yG1yT1aV1ZA1BR0G71oa0Uy0aV1Oz0od0650Zi0hL1Eo1tA0wG0ef1fG0ZO
+1aX0CO0yG1gQ07J0c80Fe0o71Fq1kk1qc21m07t0B91td2241d00oP1Uw1741TP0aN0ty1Vz1K20tm0TS0VG1mv0gE
+0gS0Jc03y1mn1iZ0oc13s1aC0NS0lg1YG0uw20W20G0eU05R1QA1GE1bK0ko2171Mk0vh1VI0Uf0IC1VR0S51eT1Kk
+1OI1Ch1b40O61DG0rC1E60ZI0Av0Sc1Ti0ND21e1CI1X20gt1871PU0kP0qi1cL1jX0mk1C907D0yt0aR21D1mJ1N7
+0Dm23R0Ck04r0oa1W81xy1qx0Mw1Kp0wI0vM1yK0KS0Yp1Ij0ms0lP0kd1wd1Em1Vh1H60JK0dj01m1pK1uC1d10fM
+1iV23e1G10lh0no0Cj10U1nv1hU1w40Vs1ST1e00WK20Y0FU0J80240wo0k71rA1l20b30jV03D0HD0Bz0zz0FK1JI
+1Ob0110XB0561Jw1Zv1Bb1fa1LD1D720L0L70EU20y02s0gI18Z0Ds1ui0hn1oF1kr1Zg20E1aL0s20Gn1Yz1Kt1rt
+1xI1HG0gP1H50H80uJ0JI0uI08W0Y60jH1Yp0qF0JF1ku1jw1oy1ql1y51Z90bQ1jG0Qt0UL1fX1yu1y61zP0Cy1u9
+0wA04813G0i71Sp0DX0aw0Gd1FV1CX0Su01U02h1g41f90bx15U0ho19N0H40E811n1rk1ZI0PA1xp11x0590gb1v2
+0bB1Vc0x20qH0l91kn0tZ1On0p60Xm1zV0mP1cl19h0Uw1k21sv0E20qX1rv0fo10r0cI0is13l0Ti1yx0tC0Me00n
+14r0vc1ao1JA0Pv22X1SS1XS07I1ka1eX1nr01G0f61Xy1GH1CP1Zq21c07z0dn1Fc0RI0kT17f0FW1Jm0oX1hS0BN
+1Pz0Ci1uz0cN11G0F41uV1eF1Na0tS1gk1VJ1vf1P00Yc0wc0Lv1ga0CJ1uG1rg1eS1Bo10512t1NJ02Y1SR1rF1cA
+0E51QW1Bs0TO0bD0Ku0Ll0oC0Nl1vJ0Lj0qR12U0AE17U1O70aW1ib09R0RQ1Vu21q1Ds1sa04j0B11D81tE1Nu0tk
+19W1uv1vN1TH1BK1ki1yy22l1Th1JJ1sY1DY0Ne0fW1CV1gm0V105r1xB0EF0Il1Or1zY1qy1x41tD0WV1xg1Kl10p
+0mM1jg0zX0RT11j1UB1Gc0bC0P21Ys1MK1xx0lR1211OU10s0x71UC1v41Ak0jL1zT1IA1NO0zY1ck0Ej0SK1fV01S
+08Z08s0PJ1uo1mb0LA0Qm0510cp1gR19A0eZ0Fo0nR13f1830NT1WO0E91oX0Lr0hI0Lz1Ja0Nh1Cw17S0iA0a907F
+0E30gu16w20g12v0W60nY0px0aY1SL0GA1ty0yA07v0cy01e1tk12s0Mk0lM1SD18o1l61w81NB1wD1iK0oZ0Sd00G
+1Zt0jT0KQ0xL1Qw1J52010s71bR22d07b1fI1AF0rP0wy0iG1R10XR0hS0SZ1au0qA0MA0Zt0tO18O0GS1Ng1zX1ta
+0UZ1D019m2031vR1bw0L80WB1gc1SJ0Hn0Pe0Uz1oj0Gs1BU0WL19y23X0YN1XL0as1oI1Q920R0sw0eK14D1QL1gw
+2350m116i1Ed04O1fB0Dv0Yv1xV1e30NL21f0ZW1Gm1tO0HG0iH1xW14C1de1mj0Dw08n1HY17a1m90MD0Mh1C81HE
+0R80kr0u10Ry0uy1iA0ie0mB03u0EZ10j0Xe1u10bK0k60Rh1lt1cf0qu0JX0rW1GW1YI07m0Ay0rh0xg0N40bf0oo
+0ml1vO1ZV22c1sC1bV1Y909M0vH1Xn1Wv1dC1Pv0M81W20MT0ak0j81Qi1m11Pk1uF0KI0ry0SS1sI1Nc1Mn1KS0DO
+1YZ0yw1oO1pQ1mu0ZS0Q01H70RH0Hc1by1781lS0B71WS0Uc1D11To1zx1ml1Ln1310gs1ru19R02o0Zb19S10m188
+0Ed1tP0x008o1WF07l0qE22o07k1Zi0Kl1Tj1dd1r31bu1pH1jW1gT1OC0Ww1lA1jH02I0SN1kB0yc1If0WQ1zz1Xo
+06s0QW15a1Xx0140Z022R1jM1rI0BE0JM16d0Pg01f1OH1JT1TA0zR0bO1Wh1WC1Sm1he0v91sR1Yg0N20xr1wb084
+0Js09e0cT0Rz10X1kN12y1CY0LD1ab0zN0lG1vC0c11Oi1Ou0Z61tb0uZ23Q1Ei1v00Tf0fE1Yi1ko0Mb00A1dQ0jz
+0pH1m01xO1Vx1d30El0A20Zp1Vg0W51gz1AB09J1wz16P0Qw1k01b50B61wQ0rk1D20ZH1dh1u71aw00o0Ms1cY0dC
+1n41Id0O70YV0Ak1Bi0Oa0if1YA0Te0Qd0mu0n11qf1dY0w31Yw0X216m0bi1yL1hb0Xt1JC1NM1AY0iF13D1uN0sm
+0jM1F71JF14o0GP0g701X0940DP0Lg0O10sf0V51ME0Io1pA05t1UZ1K80pB0mK1AI0dt1Fn0ks0y61YJ1iN1zG03K
+0xk1Nz0O40py1UU1qS1Ii0kx1Wt1SF0gF0dy1FL1vw0fR1Js1641F814J1Tn1Fd0LG1T31A006z0sV1un0ya0mc0EW
+1gM1PO1af0fi0wU1Sj0oG1dK1Hy09a0fC0mt1pU0xu21o14N22C1582200d71Tm2020FB1ad0FQ0uo0nc1yE07B0R7
+0PQ0OT1W102V1SB0t30ws1Xi0jX0fe1b31JX0pz1DV0X90Jy0iE0MX1FA0820CE1Yt0X50mv1tw0DM0hE0P70PU1ys
+1Qt1d50oh1dX1wM1q20X71Mo1kd1dy07H0ea0hf01j1wN0rA1a807M0Mu1vS20N0xp0KL1Wy0RB0RG0Ao0MR1SA1TS
+05T1DD1DT1qR16k00u15t0mm1TW1Mv0Jr0sC0ep0dm0BD0cQ0dk0ql1mD0ut1S71V30VE0cZ0pp0Tb0EX1Iz0FE1Rt
+1Vp0hH0ld1m50q11il1Fw0aJ0j90pJ03g1pO18m0150iW0CQ1SV0S00lp0Vq0fa0gG22O1Ts0qP1UL1vG18T1xe1p2
+1H01tN1LQ1f20MZ1Om1XC0w80jq1VB1AM0qz1LC1dO0pS0ax1Gs0fZ1qQ0gT1Ee2001LY1I41xs1kj1eB1ow1fP0D4
+1DJ1M60nI0Rl1dS0Ou0fw09W1t919j0we0om1ou0QX1S30LT0HL0m71lG15e1la15A0RV0gX0T61L71fZ1T80FG1fh
+1ma0Rj0WC0IK0Fm1My0yU0tb1Q51Ao1Kq1aK1Bd1n10lF1g01601um0EL0OJ22W23I0m31Xb02l0gN1pd1Iw0K311p
+0710vU11v1rB0i21Zw1L91wC0rH0Cx0fD1ax0N30C51FD0s51I30Ln1IL15q18b11D1U60fJ1Wk04h1WP0p50xh0hY
+0wh0aB1CL1120OQ1Mj0VH1ur0A30dD0mG1QP0v41Uq1aQ0fA17h0zD0ew0ZU1X11JL1Ui0oV1zI1si1cs0Re1zh1m2
+0Wq0zc12X0GB0Jh21p0d81J70rX0cn22r0ZM11O1yc1QD1FY0G00yk1S61jV0ih19B0Yt0ae0uY12i1Dn0YF1t30BP
+1cz0dZ15v04i00921U0pT0wJ17G0jW1HL0yh12M1TD09L1Qe16s1Sf05h0Fh06B0rT21x0nC0zq07e1C31Da1q31Ne
+0GC0xw1CE0Nb06G0G21z51Bm0cW1yQ1Jd0PP0em0TV0uT0bg1jZ1xd23E04c1110F00zC1Ut04g0EP0fV22H03r10e
+1Ro1mQ11r11t0ma1P21MP0lU1Cq01s1kl0C31wa1b90CF0e60fF0lB1f520J1bh1Ib1KF0Rp1UV0Xs1XM0Pw02a0uA
+0aD0m51rm1SC07501615G0Vv0y80HE1f11WU1FB12j0Kv1Z00Be1UP0HT1ZL1p81480BT0jK1XO1V90hc0QF0a41mK
+1TB1RM14X1ew1Uo0MF10N00j1GJ0M00pG0BI1yi18w0QL1361mr0ch0iV0v70yH1XU1iu1KT1GC0sv1RC0270NM22y
+13u0xI1HO0qq1ZD0h70DS1fr1NI05x0dW0n50i505Z0B50vA1sM0xi0je0iD21i1NW1JH1Ay0Ha0MQ1Mr0ct0aP1yp
+1tI15006J17c1760Lx1m421b1DW0Eu0qn0G31B50St0Qu08a0PX1631C01tH1rT1dg0G40Qr1qA0hN1dJ1Yq1531Ew
+1cx0or18r0i61Lx04Z1R81oL14Y13N1mC1IJ06X1QG10W0AV0S40W81pZ0WF1ZF0qM09t0xE1tL0sR1P50aq1Ld0LY
+1Zh1Ks0i40IQ04y1x81BF05z1Zk0fk05g0UM1Ah0P00x10dg0JG0Y51eE0t81lm1731u80Mg0jr0Wv21u1a00oL0pr
+23g1Lw1w522Z1kg15o0Cl1iM0q71jp0jl0N70to1oR0021xN1uQ0XT0oR1WN0fU0Er0201IO1PG1sy1TG0Wa0gl1gW
+1y90Iy0ze1NS1tx1Qh0HF18G13E0320BW04z0On1NL0Lc1OO1k71yr0rY08r0tD0680Oy1ho1Hj1R21kK0ic1Ub01H
+15c1ET02v0HO0Lf21t0x91Gz05u0sS0AQ10C08j1jT0TI1lj03v0ip09T0GE1HZ0Kb17R0tG1wY0du0RA1N90lk1KP
+0Fb1np03O15T0pY02P1VG04E0gy1Tp1vu1BY1kR0xK18g0Fu01c1mo0Gr1gu23O1Dm0c50im01i0uF0jF0t70Cr0ee
+0081nK00E0NC1uK0800JY0RE0lj0JH1A91Rc0TM0I81rS1vs1mk0si0CB1Ca0li1Q11kv1gA1Vq0yb1EZ0O81nb0LI
+0uH0961KH1jx0701621It02A1Nw03f21h1p50Vz0XE0PF16S0n90vn1YO0Vh14611S0Ga00y0MO13Y0cd1dz19C1Dl
+1t40ur06W1tn0aH0pO0Nv10b1oS0ki0sx1xY0Kt0YE0qS0uX1Cz12I0zw1La1TK21Q0Rk03p0k01Ta0kj0RU0BU0UU
+1qK06D1hE0VC1bW1TF1Je0QS1cR1rd1vo0vu0RZ0QJ0pv1Oe0EI0oe0h40Zo0yS0BG1oP19H1gC0kb1Cl08D0CG0Th
+0qK1LU1iW1Gj0gr1Uh0kF1MS0Fi1Gq1FU16W1gn2160SH1DL1TN0Mf06R1Dj0ad1Dv1Bf0Z70ag1gx1391yo1U208P
+1oD22i1hh00B0Mz0Kh00L0tN0SU1F30g91Mq0wj23H1XT16j0WZ1g718d1OE1ZC1IU1cp0Li1MI1UM1xG19a1L61s8
+1yv1LT1iL0Ax1nN1CT03q0xv1ER1Kc1G818a1rp1Px0ZD0lE0U11TJ13o0hq1lv0jS1qN1ZZ1HQ0Zm0uK0LK1n60lA
+0Yl0ai0eW0Fc1EI1Sh0sE0bq0jw0wH1Gr22u0Tv1Zb1H80OC1vU1zU1591CD11k0WU1hG1p31061ft10M1qv12016b
+0iy0mO1Rn0VV1lD1uf07420t0Z11US1SK1bC0uO1eh1YM0rM1pg09A1RS0L31Gp1fF1Y711P10f16Q0K60fh1Jl1dc
+1zJ0No21O0hp0GK1cg1CH1uL0qw08A0NW0KC01b1Ey0VT1Zl1PB02J0vf1uq0mI03612L0wz1RN1iF1So0vS1Is1hm
+1vj0bc1dt0830P41SZ1In10J02W0dV1Ap0cL1Zy1Gy0fK1Uv0oU1lL03L0jC1rO0QN15I0jY0mL0a80ss0yu0eA08B
+13O1i00DC1yg1kx0sY0u80UD1rx1351Ef0YD0il0PE13e0K70JD07j1iR20F0070p40w70N10Mr0KM0dw0Jb1sD0XO
+0sk23h1hW0Py1Ms22a1GS0nr1KO07d1vd0IB0xn0i00b20ST0KR0X10lo00v0oq0Tw0Q20j52071EH1kP05i1L503A
+0Wz1Qv19w0FT1fC1or1191SX1jn03X1gG1j51FF0Ib13R0HB1PQ1zF0Fg1I70ha1Ac0xC1Hv0bp06K1zS0wf1Qm0Le
+0yv0qy1tU23C17x0Ny1oM1tT0Pf1ZT1BJ1ZE15p1LV0Dt1pF08S1Ym1lk0ed1ie12b0CU1dT0ts1Ve0BF1Cu0Hq0Fy
+1p004b1TE1pv1Hd1KD0MJ0ec0ok1YU0Jq1SY0pW0TX0v51WZ08L1AX19V21j1fN17q09O0631aB0re07i1m709g06a
+0tP1711q61vY1yO0Ba0BM1Cx0ZE05I1vQ0iw1pI1Hh0st04918t1AU0u71XQ1c919T0gv1pl1080mH10I1ez0zy01L
+06P14q0sK2300n00Ot1yY1jR0GG0DE1lF0I21EU1Z51Xs1Vy0uR0lw1HU0bG19D0YH01d1BI0gk1IV0ju1zR1V80KK
+1Ad1uZ0kt1GY1LW06r0LZ21X1rE1re0rx0qZ0TE0oQ1lo1DO1Ju1OW0RW05D05l08c1TC2081x00fn17T0mN1CC1Kb
+1aI0vL00a1qp1Nd0al1tz1Tb0zZ0KG01t0460tJ1n90sn1B209I1iD1ev0Vl0Om0J502Z21Z0UE1sz16l1tl1ja1qq
+0MV1NV0Ov14p13S1M506q1dB0sA0pV1l50uU13c0ud1LE1Ss1MW1Dd1nR0fs0kg1xM1HA1An1Dt15x13m0Pt1Et1ks
+10S0cM0se1S51nl0TJ0mD0W30QA1SQ0m222N0OP1eN09v0cb0yd1wp1Tr0Qe2320We0c40GW0Ky1OJ0fg1O205X04x
+0Fj0Hl0RO0tW0y31b80BB1t60iN0F50Y710306e18519Q0z91zr1u21MT0L51Hf1gS1ra0IN1AN1wB1bf1ix1Gf1sk
+0z60k31ZP1IG02x18I1OY1O60Sx1wx1eu1eb16Y0Ut1fT1011Yo1RH1T017d0ui1zk1os1on0lY0Bm19M1FP13I1QY
+1UE14B1IZ1zK20l1ul0Ow0Id0mT1Pr1rc1FJ1j00yM0ga1wq0Tg0sN1EC1zQ1751XF1gb1Pm1rH0wb1Rj1su0470e9
+0330IS1Up1fv1Li0L40ul1KE0pj0O01SM1NU0Vy1yZ0Ce1i31mS0eL1VN0Gu0Qi1gJ0JS0gH1wr00Z1NH0lL0tU0t4
+1qi0b61DI0rn13h0XW1lw0Ka0sB1L306A01o1tg1a21WJ1PA0q81me1aq0EO0W70sq1OA0IM0Gk0lD1ND1UI0Wc1MC
+1zi1Ov1zZ0qV1BW0gY19c0UO0Eg1U913j0Az21T1Yj1vn0eh1No05F0a70mi1OB1S20fI1pt1Qd1Xe1DQ1ld0ti1EM
+0Zn1pm0dF0cS14b1Dp1nx1571NN0K00cx0NG1mp0YC0D906V1vH1jb0G10sg08m1iE14e1hf0q41W600F0IG0JR0JV
+0dz0g50nD1KQ1g50Sa0eR1Py0Gm20V1t21aM1Q01yF1As18f1161xT0300sl20Z1XP1XZ0OO0zB1Uk09E0Df0OM04M
+0GT15h0Ac1hP0Nm1cr1Tv1CO1K61yk0UG0d10v61BC0RM0Zf0NQ07h0vP0q21sQ1tq1uT0Kj0i30j31B01F61tG08O
+1Ue1r50yn05512e1OX0sH0kJ01W1fe19s0hG1OR0tu0Ws0ab0nP1kp04k1LF0bu15O0hw1s01gI1UT1Co0gU0WS1Gb
+1wI0U71RB1RK0bN1j80Ty0mh1I00Ys1cS1Yl0AF1Oa0hh0ru18P0yL0Xp19d0WR0vJ1M80ZN0Nu1ZB0Gh19J0yT0yy
+1Oo1Jt0jO10t11l0ge0UQ0YB1LX1Lf00h11z1gX0450Wt1AL0lC1Wo1wE1I10QU21W0Bl1Jz1VF0A10351pn0zK1cK
+23S0ii1I200g0oD05A0jv1qJ1uI0rU0F91bQ22h0Dq0q51nM20u1dp0IL1we0Zr0Yn0ln1kM1ea06w1go1XK0D71Le
+1kt1Ar1Md1OF12r0qf0HS0VA0U50W11cH14Z1970W00in10i0Yj0tY0yC19G1oY1Vr1791b71mL1te0BR0Kr0zG0qG
+1Lg1tu1qe1oh1Oy1le1MN0bW1QX1OV1v50BV0jx0Fk0o40lO0sD1Cm1bB1v30x61tS07p0D11BQ0620bU0Lt1st1C6
+0Wu0fH0dd1AR1Sn04Y1TR1Z81QB1Wi1Qc0Sv0d514x1oB1r403S0vr0yK22J0j11L81nc1J201a0up1cy1321Kv0cH
+1Xf0w20hu0Qg1Qx1Eg1FG1Ax1wA1J10Fa1KV1wL0jE1920wN0vk0hi0tQ1Pe0pA0bm0370rR1tf1Bn0oM06f0cG14m
+0Cc0GF1ly1yh08v0OE14Q1Ky0VW0yi08e1AE0HM0DG01K1k81J909X1Eu0Yf0n60JB1Jk0iZ0SX03M15P18z03a15H
+0dJ1HM0381mN1B61jI0iR0PB1vF1bm1Ba1yI1qo23D1rY0eY1ei1Mz0a51JV1RE0Gc1id1eR1pY0cX0Dc1IW1EE1Wb
+1bI1O00na0Z41h61fz1Ft0r41c30GY14U1Wf0Tx0eJ07Q1Ia0Q90MK0n40eH0j40wp1DB1Wd0S60tj1HS0IY1cc0Lm
+20C06Y0DT00b1sK1Yf0mz0xt1TZ07u0dr0Jl1F01a51Mm00s1g61ns11E1S41QE0aG0VZ0Qb1yd1kQ0Ht1HP1OG0g0
+0981T60lJ0V81bN0zo15Y1lY1AG0SB0K11e60411qG0b91sT0vY0vw1R309305w0Cq0zt0ol0s31oo21Y1cT12W18L
+1kc1a60Bw02k0Ff1Ag1BN1hp0iI1UG1Jo1yR18e0Nw0tq0fv1Qr08q0iP0SM0Zk0fz0le1KI1A21g31no0eN15Q23l
+03Z1gH0lz0eF08F0IW1nd1hz1bl1UO1kS1Au0PC1i11vx1Q40730wr0IF0Si1kV0gJ09s09C1Hw1521EF0Yg0jD06x
+0190b710D0nU1uU1rD22M1FK18R1BZ0Pq1yU1y70rJ1dk0p816e0d01Mg1Ur09D0kW04X22Y0aO1Xu1o60SA1Bx1iq
+0NN0GX1Km0ja0xo1TX1YW1dE0PT0RK00V0nA0fP13w0M70ZR0EN1Mt1h01B40T02151qC0Y90rp13r1Gk19q0zl1P6
+0cD1Lu0H51x71VV0WJ0Cs20H1mX1hl1qZ1Pq1Tg0IO1Az1ht1XY0WX04N1KC0by1uk0Fq0fx0h51co1rL0O20bL0Wf
+0EJ0Ic1HT1gP0ph0eb0io1KY0RR0Jj1e40NF0ez1ia0rr13X0r90ye0Bx0cA0ve1TL1mc0jk0BZ0mr17N0Hs1ha05p
+17t09Z06017i1Wu1mx0KP1Nb1rX1d70Fd1E10Ju0ku15r1Ho1Lv0B41DF23K1a90Ls05L1Su1Dc0zf0mx1Kz1HN05o
+1h31BT1tB0Ct0um1wJ1801gg1u50Qq1yN1mg20j21N0AJ1oG0xe0Lp1Kf0KN0xX0CL0Gf0G60SO1Vs1n721G0ZA1hX
+0MS04a0eX20916v0Ke0pF0Mm1oQ13z00121J18v0so0pw06j1ic1YT0SR0YY0S20b00VK1AC0Ui0CN1jK1kz1cd0E6
+0uu1Rf1hH1Bq0DV1Ir1Dg0va22z0xD0dM0Ey1yA1rM1u31Lk1py1HX0xO0Qp0Ss1hc0Ok0o20RN0r70t50wM0O91wU
+01l1R71Hi0wC0ou0dh09k0YT0rB0Bu00r1zy1fA03Q1pG1cU0Bs07L0f41cZ1ae1bk1O31xH05k0R90PY0Dn0nq0Oc
+1Jq0aK0jp1Di0hd0nQ1sc1fd1gi0zm1PE0gz1450qY1x21Ko15w0eg1MA1yW0xb0td1r01CG1vK17o0LR1ps16t0fm
+02n0tH1AK1HH0Ym0NX1J41561Xp0Ld0zr0aS1sb0E11eK1BX0kG05j18C0PR0PK1fj1bz1oE05c04l1r10Nn0Sj02u
+02Q0DH1OQ0dB1Vf1h90QB2371eG0Dj1fg02T0CY1zo1pc0Sm1IC0cz0gh1gs0MH1uj1c10nS1jS0Vg0VY1cF10h0L1
+1ed1og0HH0Yx0kn0wW1qD09w1kD0Pp1D50pR1vm1iz1fH22K0T81pi0Eb0kO1A11sp20o0TL07T1Df03e0vx0ZX1H2
+0yB0K20Fx1rl1qm1TT0zU0ys0xT1yq00U1GX1WH1iX1aF0GM00H1lx1dD13y0PL0He0ZC0i91Wp0mj1Jh0B31Pa1DU
+1XV1Mp1IP0aC04e1Xc0d40cv1662231CJ13306h0EH0GV13t0Vf0g20yj16D1QF0Vi1nw1c60ls0QE1wm1pf1na1T7
+1T41Ru19u0c21zl0nd0Ad0oE1IX22S1Po0pf11M1GL1N01i40sy1XA1ms1Tw0Ta0BL0uC0K50As1mU1nI0w61js0Ki
+0050s10Jp0e40X40wL1pV0YW0Ug1wy1kO1FX0UN1p112O0fL1861LN0AO0ap1P71eq0GL1r20IH21116M0Vj16X0T2
+1hD0bA0U61vr1RP1T20V723Y1gq1P80hr0tg20v0WE0dO0h810n1Cg1H30SD2361VW0t91iU0Aw22n0KZ1m80y100O
+00p1wR0Ue1Bh14G1rR1Ud0nl1bv1S80cs1pb0tz0pb1Nx1691hJ0V60Zz1ZO2180Ru02S1WW0TR0nf0ca1Ty1Ea1ph
+1Fg10k0Za04T0zA0Xg0oW0fB0F217O0MB00N1fR14s1sN06Q0r50NP0zj0Xz1yM1UX1ar12x18y17Y0Qo0CR0cV0Yq
+0Bb0Nj0Hh1Ns1xf0xB0xH18A0390G50bT0Zl0hJ08X0o01hB0F70nB0nV15Z1fK0Wk0XD0Gy1FO0Qy0i81wX07r11W
+0PS0rl0kU1510JE1Uz10T0pM0Qa1Xl0VQ13018q0890IR0H71JR0971kw1Rv1vE12E1O40kI07E02i1eL1Uj1Si1Hx
+1IY0XK1sj0Xd1Y31Tc1pB1jm1CR1do0dI16H0861pp1NA0nt1bg1Bv1zL0c01dV1jP1za1gh0xQ0bl02L1po0AB0uc
+0Oe1dP0DZ0Fl0Ni0Kd0R117E1yJ1tW0xM0NZ0WT0cq0VD04d0Dd04W0v823J02F0nH1Kh0WD0Db0Ez1cq0Xh1aS114
+0tp1410H213H1iH1Bt1Ge1XB1ct1jt0pK0sd1NT0LU03G0xd03o1IM1GA1YY0A80eB14a1p70YG11T1Ez0610kz0VJ
+0Mv20r0IE1uJ17n1Aw0e11NC1KM1Jp1g90ZQ0Up0OK0wl2381hx01Z02y12g12H1Cb1aO1Lh0Wd0Rg1zm15j0Lo1ZG
+0gL1Af1yt0Tl1vl0Ma1Gg1nL0KY1qM0Sr21405q0hO0jJ0kX0Px1XG0wk1SU1VX0uz1A71eD22L1Ec03x0GU1Lo1Gl
+0Bf0qh0C121l0Bt11X1wS0LH0ny0jG05y0MM0Km1Jn04o0Td11F1ye17P1L21oz0Oz1R91RO1AT17e12D0J905Y1MU
+1Pb0yJ1Nf03s0mQ1M31PP0K80rg1E30Lq0Mt1OS0ix07U1jh01x0f01a30ky01F1us1ca0Wl0UC12V0fp1Kx11d1WM
+1YF0Pa1Rg0iM06b0qD1Sz0FN0vR1vB0yZ0lc1P31271UW0YP0Ik0mA0OG0mR1gO16T11N1ek0L01GG16Z0440C21cW
+0dv09p1Cd1NG1sm0V90AR0Ns1yb0VP1Wj1CZ0cl1YH0Go1Zj0Se0wV0th1Kj0xG0g10Ee12N0sj1Wl0NV0eV1oK1KW
+0Yi1N60y40Rx1Do20X1hV1lQ02b1IR23L1oZ1c01k31sd1zc0Bg1Zp19Y1PJ0YL01p0UR1Ga0at1hk0vZ1Hl06p1pE
+16K1bT1vp1cG1em1ex0AK03I1I61EV0wi1Pl1bG1cB0Hz1hK20s1qL0T40HV16O1mP08b0720zS1DC1VT0wY0Hx1QV
+1wV0DW07V1sW01021y0Jz1ip16721g1Lq10703H0jj1xt0Vo0op1ux0Pi1w91LB0FF0Xk0hX1hn1Qn0su1uO1Am0wq
+0Xx0AY0hv0xN0gW0C90HW1M201V1A40Au1LJ0eS0p31oW0UI1Kg1dI1gd1RI06L19l0Ri0s81ZX2131Gt1h41Eq0tA
+0ZK1z11dR0M20GI0H30nm0uv0WW1eV0hB1Se15R0780o90uV0AD0r20iB0kK1se1Gn1Qj1Ab11A1pD0hm02O22j0Md
+0I316z0GR0vz0GD15B0xP1qO0Hv0SP0LM1Fi1Bj1iC0XP0pt1ny1JE0XC0Cd00J1vy08d0j70Uj1Zo1yj1uw1t001g
+13d1fc0At1u60Y10qB17000612a22G0KV0k11oU01y1ti0gj18c0PO0Wx0bS0VI0En1OT0TN14I1Vd0zI0cR1Fu198
+0c70Qc1EJ0lQ0dN1gY0tw0Zc0qL0fO0Po0xJ1rW0Nx0oi1KX0E00e821C0WN1nZ0Aj1LS1fp1i81LL0z81KA15g1Td
+0lX1GK0Kg0yV1vz1uR0TG0VX1w00VN1Rq1i50l40V31nk1Iq0yY0OI0XH0Ye1bH0eI0260mZ22U0Yd10R0dQ08H1pP
+1Xz1Tx0Um02d0yF0RL16U1X60GZ1vg22x06o1aD0gq0881mH1nY0EA1E519v0uk1mW0bz0lb0tt1rK0zd1SN18l1qg
+1Xh1ni03E0m602X1Q71o31K00lv0eC0IZ0Kw0Ve0DD0991ug1hM1GI0Bi03U17F0JP1kU08E1ws1Cf1T90Dl1Bz0Wh
+0S90wx1zM0MY1j91Nk1dN0KW0NB1sX0rV0Ev06I0Pc1mA1uA1sw18J1Kw1Qf0hD1PC0cC0PM1U513J0de1WE0Dg1iS
+1721lK0Y20I50pL0zg14S0jZ05H0WA1ZW0CK16N1FW1B71fY1qn0lK0Ts1gl05U1ok1h51VY1E91km1Np17C1Nl22I
+1aW0D303C0ED1PR02m1zq0Xo1NR10y1eg16u1PT1dm0Sp0HU14c0Vk1G70o301D1SE0pX1QR09r0Pn1RT18B1di0en
+0690hZ1pL2261H10Dk0Rw1ir0c61eW1Xm03P1SG16L1rf1471X80Ks1Yr0DA1UN0bj0Hu1Mf1kC1fw1RU0ZJ0QT1Pt
+0pU03W15F0ly0cg12m1nh1Us0EE1Xd0Cb1Jv15C0jU1kT0iT1ng1Tt1aR1Ry0OR0TU1gE0lx1FE0ik0Kx1i21JU11s
+0281vi0of1EO0kh0dq1RD1e500z0rt09y1wl1Fz1Ix1PN1A30FR1mV05Q15V0Bo1441cE0RY16R1OL1Hs0hk1PV0Bh
+0AC0vs1Nn1wZ05m1mM1G50T117l0F810F1xr1j323U0J61oq0Wo1uE1VZ01u0vv1Vv0XS1JM1Ux1iQ04L0hA0w01lc
+0hy20w0lS0Ep1Fk0Je1a40Co0vi1wT1C41wO1sL1an0N50mq1Ws0ev18p0Q10RD1B10np1V10ig04q0Vc0Bd0zk0bk
+0Rs0vg10A04F1D31rV1gj10c1EQ1GF0Yz0T31qI1ZM1rh1th0YA1gt0Du1fm0af1Ol19F1mt0UJ0Uq1XI0SG1GZ1M7
+21S00D0kC1nW1ih0YM0gg0kw1P905f0770LC1Fr0Ig1cM1Wr05e0Af0171XJ0kv13V1er04n0wu0EY0f70L20Rf1Qk
+1ot1Tf0p10Gl0e30iL16n0vO0MC0J306S00f1Aq0R61s60Wy1Ml1d60DL1nq0eQ1Sb0OW1o90sz1380Sk0pa0rQ1Aa
+2251sH05v0tT0vj07g1da0SW1DX0xl1je0sr1dr0xU1nA0RF0di0v213a1jY0Mj1yH0Tt1TU1ZU0qs1GT0An22g0Iu
+1V51sS0w920Q0tK1uP0j60hT10a1PD1400A704C0341ey1091Lb1ep19o1Ug0bv0Aa0lW0oA0Bj0R30R21Bc0r10Ps
+1Wq1RX04m1hR1Xj0uD0OX1i60QO1Xk1Sd1N31900180Jw1wj04H1sf0jA1Ny0250bM1Og1jO1Zd1qz0bt0Nc1jd0nM
+1Fm0dK0bo1bA0Pd0D01Rm0HJ1Zm1jJ1ZK0sZ0Wn0qa1d20tB0SL0Oh0hM09Y0XJ0MN0FY1Ra1U01Ya0W403j13A1fL
+1JG22D0e20Sy0Kp00w22w0ZV09219r0sT0P81k90fy0qe1P40Rr23a1TM03J0I40jf03h1SP1o21kX0TA0QG21F1Ci
+1QO1w613b1JS1Q30FH0vV0k90xq00K05n0Q50Ya06411L0vm0M10rN0DF04D1eo1Lt2040nn1tF0S80dS01J0Nq08i
+0Os0GH0xc1Zf0xz06Z0vN0SV0Zu0XA0jg1qt0jQ0JT0gc1hF1sE12P06g1iB0Im1Ni0mg11U09b1Il0TW0N61cO0TT
+1pS0kc1HK0851YE0zL0Do1V41UJ1tr1ju1Mc0Xr17s0D81Ev0dY12G0mn0cm0s40Lb0QV0p01lZ1o82211xZ1Eh17p
+1l90vI17k0nJ1z308l1xU0XQ1Dr0Xw1DZ0ER1nQ1rZ0uQ1wf1HJ0HC0P50cB1Lc1fk08R1vA15z1y30Fr0og0fu1jQ
+1821Ha16q1DP1QZ0km0oH1Sk0hP09F1JD08N0jh03n0IJ16G0o50Jt0dH0y70Cn0P610B0rm1tK1840oT1MR0k51I8
+1Ql0bb1OP0xV0Ja0x41Vb09U08p22q0F61z20vo1jU0Br1YB0c91Im1ap0Ij0Ca03l0jP1CF0JW1Fb0FA0Ap0zO0vT
+1mZ0mb1lu20z0JU06F22f0yl0vq0Od1Fy0KX07X06E1im07c08g0M41rU0qp0xR0Gi0Zq1Yc0aj1KR0hU0hF1dG0xW
+0wF1uH1if1z81z41181sG0S11Ua1Pg1ut1fM14P0LS1Qg1Zn0C008w1fO18M1F20rE01Y1KU1Qp1810JC17b0vQ1TQ
+1xn1xR0Bp1li1OZ0HZ01k13Z1kf1gU0jt1v10Cz1sU01w0iJ0Ko0oN15u0AW0EQ12c0Rn0Nz0x81bD1101xD1yB1zt
+1fy1TI0Ih0Pu1oH15l1o41VC0yx08J1XD0aM1XR0Zd1X50TC1Kn0ID0AX1ig0nL18i0Jf0y90Rv0BA1680us1Br1nm
+0I90U81QM0O51gK0fc0yg1ue0lI0zT0a00kq0bn0pc0BC1Ri0l809m0C40y512k0Gp0ob1MM10P0Lu1xl0tx0Tj1d4
+1VH1EP14M0UA0Gx0lt0A00gQ0IT0LL0qJ10l1fq1LO1sn0sU01M0Ox1y41vk1nU1jA1be0CV1qY0bE0pg0lZ0Fp0PG
+1Qs0Zj0Em0h60tv0pm04U1ED1Uy08M0dR03i15d0Sl1AH1NP0Jm0Jg21A00S14z0FV1zB0ia1lN05P1ym0pZ1K10AA
+19X1xc1bZ17y1RA1Al06M0k80Or1TY1lz18F1HB21s0dc1UD1kI0hR1EG03N12z0791l71pr1AQ13L1Un1JQ0Mi0HR
+1At1bO1xq1IK16F0Cm01E1Sa0mJ1b20SC1RF06l0wa0wP09j1Sv0J00X818N1wk0kM0an1ID0YO23b0AM1lI1vX1jk
+1UY0Vp1yl16g1QS0TB1Fh10q14H14n09V0XZ11J0rd0wS1db21d0er1vL1nE1PZ1He1ak07K1d916J0dx22e1j116E
+1YQ04s0r80X61Ig00t1eZ1Hp1Jj05W0wn1F51I91Nv1AZ1Pj1CK12R1xE18S1kF1ba0P11kJ1541lO0Vr1SH1rG0h2
+0Zh0iO08Y1fW0iQ1Qu0Ft0c30uq1Lp1Z212u0m803k15b1o11Kd0gK1BB1ua00W0qN23108k1MD1Ok1Nj0YI17w1qW
+0tr0wD0x31Rk01v0RS1xX1Tl0zH1LZ10H0Ii0AL1zp15f1zW0za1Cs16c17V0V01mq17u1BH1Rz1cQ19K1VE0Mc0Og
+0BY20i0Xb0Rd1of1lU18H0qW0RX1xJ0Qx1Cj1Ly01n0KD0BS1UA07o0au1sV1hr0MP0It1IQ0VF02G0UK0LB01T0ra
+0mV20p20M1MZ0i10s01n01sA1NE1EA0ej1Y40Iq1va1Tz0rO0A91cJ21k1Ej1YC09d1sO1Fv1it0pP0hV0Mp1du1Hm
+11C0f50FD0Tq1bM1151PF0Bq18K09N1eY0l007O0mY1vh1Pp06600m1wg13T1Hn07N2051DA1Wg1bJ0l30oI05s1Uu
+1as0z21vZ0jm0Un0BJ21L0Rc1CN0430Ix08x12Y0Jo0YX0Sz0lq1Gu1my1eH1D60Tn1bi0un12f0Z51zv0LF1Bg1fo
+04S0QP1KB1Y50z41Y21N10kk14A0NK22T0es1Vl1hQ0F11nj0aF1W41w114T0Ch0S70Pj08I0f81cu0jB0JA1u41nH
+0CS0KU0jn0pI0040vy2280Ji2221Qz1uM18s23i0kZ0gC0Pz1w70H90ll1J30FS1lP03R21a1PI1XW0221pM1p41hy
+1II0581vI1Fa0cP10G0v31cN0MG0ng1Y117A0a60ds11V0f30OU1b10zP1By0290EK0tl17L0eu04f0ck1Mu0Pb0e5
+0y21ay09o1WX1aP1UK1cv12F1zu1vP1ac1n308U1KG0q00J201B0r61W70wt17I1gN1cb1OM0oz16x1Z41Yd0nF0XU
+11f1X00qv1sZ1mI1WQ0rj1fi19n05K1r61MX0ET1250lT1ry0gV0UT23W1ZN01q0SI23c22m0FM07Y0q314i1w21GO
+1VU16h1kZ11b0hC0eP0q91Io1W31Ye1uS1L000M0b40D513U1aA19p1LH0Y01291Ip1Z61xQ0ft0H11Ze1v814g1tp
+1MB0TH0yX1y20mS0PH0670uS0Ie1qb1gV1Ek0rK0vD1Cv0K41jz1Sr1JY1Pc1q51CW17X1hd0520yI1Fx0am0k21jj
+01r0YQ1eC08y0j20OA0Hb0gB0L91XH0Vu1xA1YK1PS0AN0p91IE0Rt1f00DI0Ud14L0Z81QN0Qk0Vt0cf1BG0Gq1ai
+0MI1ob0hg1dZ04v1F41XX0hb1xh20e0pE0Ng0lN0Hr1L41M01mO1lC08t0sX0vW20P0Gz1xL18u0OD0jN1o00cJ1aJ
+1wt1fb1eJ1f81Lm0Ab07A1PY0Hj1FT1eQ1X71VL1QK1RJ23P0Wg1FH0Pk0Ea1sl0ao23Z0ar21R0xf0N00xs1dv1YX
+11Y1Ff21E0Yk1H41gy1GR1Rd1V20Ob1bX1yS0pQ0NA1nV1hs1z90231hI0u512C1Ma0sc1Gx10z1pu0EG1lr15i10Q
+20D0h91wu2291oA0Qj0II1SI1YR0RP0e71n800T20a1hv0Di1LP19t0DJ1dW1Ox1VP0hz1xz0VL0TF0xa1lE1Q60My
+1Ke1bq1Wz1nC0LQ0120yp1DR0wX1eP0SQ0TD0Uh10Z0Gg02K1gD0dG0eD12l04t1Yv1fx1E80Wb1qd1yX1lV1zb15D
+1UQ1jL0Ia0h31t80uL0Ux1Rl1Ka0Yy0Sg17m0qQ0PD1FN0ue1k105b1C70B21x60Hk0wZ0Zg0vl06c1Jb0vF16r13K
+1N40Ah1E400q0DK1Dy0eO15S1jq0TY1K50z018x1rz0NJ1j61jN0do1H90Ua06N1J80mp0Xa1RY1Vn1qj02e0PV0PI
+1W00EM0CZ0cu13B1F90d90JZ1Cc0qI1EB0Xf1MH1lM1cw1yD1uy1l81Zz1U80zF0XX22p0La1uW1Pu0hl1ze1K40Iw
+1Op0OF0fr1cm0yR0Qz0JN1tV0YK18h0KE0Ei1YL23d0vE1Iy1KK1iJ1i71hT0eT1GP1yn1o51Yb0dT0t207f0Xy0w4
+0KT1qU0N80Mo0030tM1R41sJ1a70nG1dA0KO1ZY0az0qr0Eo1Re1Bk1sF0oO10Y1at1q81mf0ZT1Vj1nD1Od1r81ls
+1MO0E70Eq0gf1tj15s0cF1CA0zW0cw0Jk1cj0VU1WL1DN14v1650TP1xa1vM07C1Jf1S11Xw0Tp0yq0kp0OS02M1K3
+1WY1V61XE0u902r1CM22P1qH1V70sa0rz2271eI21B0nw19z1ij01A0AS1c41w31DE0fb0m40By1ZJ0U40vX0XF0Ra
+0ov0wR1xF04w1PK06C18X00Y0AT14k0zV1Ph13C21r0qx1Wn07q0rI09c0eo0xj0qm16A0sh09K0HX0Sw1KL0OZ04p
+1nu11R0BO14V0os0n71Hr0Dh0tR0AP0zn04G0M61zd0Ul0tn1IS19I0Hf0R00r01Nm1yV07s18E1WT0Ub0dA12J0zJ
+1g120n0Wi0mE1Ic1qu1gL0yP0Uv1n51b609n1N80ub1Q21Jr0Xl1Iu1IB1ji0NH0US1XN0J70sb1pN23A1ZS0yr1S0
+0Gj1o71f60nv14E04R0nN15J0pD17D0fX0Tu0Ph1HR0HA1ne1ag1ML1EL00k0hK20h1Vi11K0ox0hj03V1dn1UR0eE
+1YS0CH0LN0Am0v11j20ce0ij06U1Z11bn0Ml1ro1pR0M91hZ0Yo0Q609Q0Xc0tX17B07w0YJ0211171uD12Q0v00YS
+0yN0yf1YD14u1g21C10IA14F1jf03d1Pi1Vw1X30fN1YN1wo0g31vv1yf13x1gB1up0gD1QQ0IU1Ce0Ec1T51LR1zO
+1MG0l60Y31jv0J11fQ0b80sL1Yh0kB1Nq1jB12d17z1v60bs1MV0541qs0Ro10u1Cp19f0SJ1z01020Da1Jc1Hc1FS
+1Y60ni1el1ES0Vm1eA0m90QY14R1Rp0ff1mT0nb1om1Yy0oB0R50Hi18V21w09x0fQ04I0aL02D1Xa04V1JO1BD0WI
+1Dk0zu1aN0ne00i0gn1CQ1m60Sq0cU1QI0Q720k1961c21ya0Kz1Rr1bL1gp12q0cE19P1HF0a21pe0yD0EB1Rw17g
+0fj1Ul0Ag0Us1uc14t01N16102B1Dh0NO1xi15L1Db1qr1SO0n30cK08G1LA23B0Tr1aU10d1QC0HK1B81rn1uh1Y0
+1zf1lT0tc1HC1x511m18W1qF0qO10E1ts11y0yO1El1fU1hA0SF0Y81WI13i0hs1nO0Rm0n20oj0it0CI1sB1Va1vq
+0nk1iG0FP1nn1wK1VO1rP03c17J1uu0QK1nF1px0Gt1e21Qy1j70810Q31G41550lr1Ww1uY04J0u21hw1fs0950HQ
+0Rq1Me1gr13q10O1hO05M15N1rN0Qh1370m01kW1QT1pj20f0nz1NK0QC1uX1Hu1sg0pd1zC1MJ0wT1Zs0sF05C0xZ
+18D08u0FJ1vV22E1O80f11Ik0o61gF0C723V0bH1p90KF1xC0YR0Iz0Xq1Ih09P13W1RZ0t61Eb11a0iq0w11q11nP
+0mw1d811e0870RC1GV1hu0ux1iT1LM1LK1lJ0k412A1EW1m31260UF1qT0gi1cP1rq0Hg1AO1jC1bb1UF1Hz0oY0Bc
+1rs0kE19b10x1Ai1tR13M0KB1uB02z0da1Wm20I0av1iy0XM1Y803t0HY1J00uG1Rb0DQ0pl0pN0QQ0el1av1pT1wh
+1dw0Bv1Tq1eM1EK0xF0go0lf0kQ0zM1S90U21xo15X1rC1Jy0T90Pm1wn0WP0Ef1mm0VS1aG0Sf0ht0nK2330Fv040
+12n1Mi1DK02H1md0Oi1JB0OL0QD20d0kN0So1ik0VB1990Vb20A0Nk15M1jc0O323406k0eG0Hy0OB0u620O1VA0lu
+1HI08C1nf1Yu0Qf1Lj19x04Q0bI18j0Vx1IH1lW1Jx1bo1BA08K04K20c10o0ZZ1AJ0nO0a30ta1WR0FI06O0jd0GQ
+0kL0ZY1u01NQ18k1ZR1oi1DS1aj0G91kb0DN0Cp11Z0aT1KZ22A0Gw00I1Wx0fS0PZ1B31Bl0Kq1QJ1mi1T11fn1MF
+0bJ0V412B1zj1Ot0Wp1h71Ct0AG1od0421fS0vC0FL0AH1e80J41hi1Q80Bn0H004B0I10BX0Vn12w06v0QM0V20Vw
+03F10L0te0jR05B0T50CM03B0iS1Rx1ah1eO0nh1Vt0QI14O1nz0131Xg0Sh1Tu0iU22Q1Wa1l01cC16B1AD0T71B9
+09B0f91sh0FX0Xi1Vo0Uo1dH0XI1Pn06n1zD0rf1CS0Jv1IN1dx0h00E420B1xk1to0pn0sP0oS0z10lV1jl1xv1Zr
+0JQ1Cn0gd0Jd0Eh1WK1iO1TO1sP02E0po0XV1bs21007Z1bU0Va11Q1x11Cy0jb0mo0on06u1Ji1nG1ol1SW0X31xw
+17H0ke0yQ0dE1Ck0dl13P1t711I0JJ1ss09l1wP1cX1b012K0lH1zN0bP0Ip0oK1yP0Tc0vG1U70VR0ex11h1Tk0GN
+0XY06t0nX0mX1Of1P11rJ0bX1231bE0KH1gZ02q0LO12S1FM09z0Of01R0500o122s16V1c505V1Gv2390rG1BP1jF
+17j1qB1Ki1041tM0qg1so1001NY1ll0Ge1q70Qs0Oj0Ur1hC00X0sM0Nt0ek0bR1q91mw1Ep0xY1ln1dj0tF0Xn0j0
+0Jn1s90Al1KN1A81fJ1U10mF0ji0Ql1j40Oo0s61ce1mF1GU06H1zA1Rh09i0Y41Sx08z0wO1Oc0Zw1MY1Os1y00qb
+1Es19i0ug0Lw0iv0Wr1cV1am1Fo0C60co1wH0pi0W21oN0Hp18n0cj1aa22b0Dp1NF14j0z70a10pC0Sn07x0Et1bP
+1mE0ym0ns1io0CW0TQ0et0Ae0De0iX0wm0u40gA1EX0EV0uB0fd11q0zQ11u1Oh1lh1y10sI1M413g1aE11g1ch0NE
diff --git a/factory/gftables/8 b/factory/gftables/8
new file mode 100644
index 0000000..f2bf9bb
--- /dev/null
+++ b/factory/gftables/8
@@ -0,0 +1,3 @@
+@@ factory GF(q) table @@
+2 3 v_1^3+v_1+1; 3 1 0 1 1
+361542800000000000000000000000
diff --git a/factory/gftables/81 b/factory/gftables/81
new file mode 100644
index 0000000..3e70004
--- /dev/null
+++ b/factory/gftables/81
@@ -0,0 +1,5 @@
+@@ factory GF(q) table @@
+3 4 v_1^4+2*v_1^3+2; 4 1 2 0 0 2
+0S0w04190B0E100T0C0K0x0r0q1D0X0c0F0g0p180Q0l0G07021A0a1F1C0y
+0i140H170s1H160N1E1J0b130V0h0J0Z120Y0D0U0j0n090k0v111B0P050o
+0W0O1G0M0I0z0d0f0m0A030L0t080615010u0R0e00000000000000000000
diff --git a/factory/gftables/8192 b/factory/gftables/8192
new file mode 100644
index 0000000..e0f0c84
--- /dev/null
+++ b/factory/gftables/8192
@@ -0,0 +1,276 @@
+@@ factory GF(q) table @@
+2 13 v_1^13+v_1^4+v_1^3+v_1+1; 13 1 0 0 0 0 0 0 0 0 1 1 0 1 1
+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
+1IT1Cc0Ku1MF1VT1oX0nt0Ng23j0MQ1jH24G0QB23g1UL1Ni1oa1Iv1f60XZ1X90On25V0Gj0RC1yA1PO0z01bP1Uv
+0vG0sr0gw0cT0RY11j0460qU1R31f21GE0rq07G1UP1Be0pO0QX14B2550un0Cq1KL1i51CY06M1Od16f0lS03h21G
+1Ru1P10mD0if1S419I1z61ng1xl0VD06W0q70fk15H26U0lu0St1te1D50qs0y50Dt1Ec24f1Mc14d0pv1cv09K0gj
+1Q70OX1951Is1Ui1nb1UO07H21S0TH0mI1Dd0Xm1321OT1iI0AS1on1T025v1vh1H91oE0uI0pY1pd26o0Db0hh1rl
+0Sd0LT0Dm0231ma0d703d0ap1HK26b06Q1v603B1cO15u0ix1SA0j20zY22w03G0Ks13F1IV1fb1Y60cJ0gJ1U104f
+1m71db0kM0kC10j0O90Gt1lI05E0jV21u0u70Pm13P1Pu1IN06t0tI15s0df03D15e0Xx0j50Um01d1ag1tr1ND1o4
+1x70NB1ZQ1CV02c10x0Ct0hx17V0Xw15f1L20FO0nL1kf22c0mi01J1AV1co1bt07h1wO0OM1eJ1s00yC1tD0U60F3
+288000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
diff --git a/factory/gftables/841 b/factory/gftables/841
new file mode 100644
index 0000000..768fccf
--- /dev/null
+++ b/factory/gftables/841
@@ -0,0 +1,30 @@
+@@ factory GF(q) table @@
+29 2 v_1^2+24*v_1+2; 2 1 24 2
+4Z0l2b392SB9CB6d735GBp0A3wAY0g8d6v547e91ClAi8P9X178a5bAdAR2Q
+135sDUCH6T9q9A5z3t65BP0v872h5qA8Af2J8BC59i3TCj75368C0e8R3JAe
+Cm1O960L53DKB50Z2rAV9S1M8O3R3PAJ066P4u3p5l1q7T1P9t6M7Z7g4e4q
+AyAX4p8S5d3b450V6W7x791K7i8I0d8m9Y5PBk2s6B7C1c3x729vBgD86SAA
+AE2x2j8U3y1Z01Ba3m0w5xAL0u1i0PCy908z762L5I1Q5Y7n3M3h6O7NC20y
+0M1CC76CCFC01aDR2i2I5e6210CL3H7vB24G5J4i7A8V2cBbBR9p4N4JAI5o
+487bB14H0rBr4t3A9c7MCD1b89618e0NBV6J515h0J2E0t0oAv1EBJ7WBM8i
+6KCX3B8jBC2eCw9f806Y8u6Q0GDQAT2z7FBLAP1n7u2Z8G700f2ACZ3X7E7k
+7XCSBo781t673c4a201rCoDPBZ2R4E0qA50BB08F1BAx9j9T6g3U7rBB1fBc
+6s3VB6AFDT4sC10I5y2GA712ASA92k1e7R3n9b3S4L2p9x4j2l21Ar8q9aB8
+346b248f2BD26E8X1v4b5nAh6x0S9m5v2g2y490D1V0x0T9IBF9B3g6f7a4M
+9F0sDVDA6tDM9r0K9H5i7K4K4d269Q1G324g5X6RCqAg5C55D03WAC1dAb1S
+4F1ADJ1F2O4U283I7d2U777lCpApCnCR5kD7380H14AH6F8y0XCV5gBi15D4
+4k4cCs8g1mCA2n250h582w4C5r3LCd7q4xCC3z02AqAO9K19BD7JC96a22DZ
+8pDO5Q0b4W812f3k4D6yAw5cBw1I66ANCuBGA1CE7o9D9w5m8x2K6XBqBz6m
+8M5SCz6H7s2m04478T7hAZ71DD6N6k4n6o1l18A41gAu9lC8A38v7S8sBy9C
+4o9P4RBK7HCvD3507B0nDSCcAz9E3rA6CeCM1p0E3o8Q4Q7w1U7m88943uCa
+2H1NBx3v60448o9J9s8bCYBOB70p4h8w1u5f0mD9AU3Z1H86Ao3lAj1jBl6I
+4l4264AnBYDX5EBfDCCK4wCh2oAaBh5Z5tA25aBI1T9M7Y0Q925p6hCf2V7G
+As6r3YCk2P5D5U6jAW436p9Z5wAG07Bt7U9L8lBNBX0aDB29BU3C7t8Y3e3s
+3NDF8kBuAQ3E4VCN4BBd6i7f3aCt6q9oAD2q5L304T699RCi7j5HDI972v5K
+7z4A7yBS7cB4BACWAc2T1o378KAl5V2t52C3984I6Z081s8rBQ1J844f1D2u
+7P1R1W6z8c8nDN5j4P1y2a1Y8L5F0c9hBv3Q33DG09AtCb9U9k3i9eCIBTC6
+9d4z411L115T3FCg31054r6l6nAmBmD6CJ8D3qCO1h9WBWD51x6U0k0z8H8E
+4XBE9n835B27DL5O4O169z3f7p74CU6c63DE5W6L4vCT2W23466w3K939V3O
+3D6G6A4y8W03680W4S2X3d59CP952C2F7D0C8J9N1kD1A0CG40Cr850OBn9g
+2M7VDH7I2D6DBs2d8tBH7O1X9u9O571z7Q0FAk5R3G5N8Z9G5uBjCx5M0Y1w
+9yAB5A8A0i9982AMCQ8h7L4m6e8N0RAK3jDWBe566u6VC4B32N352Y0j4Y0U
diff --git a/factory/gftables/9 b/factory/gftables/9
new file mode 100644
index 0000000..288c3b7
--- /dev/null
+++ b/factory/gftables/9
@@ -0,0 +1,3 @@
+@@ factory GF(q) table @@
+3 2 v_1^2+2*v_1+2; 2 1 2 2
+276935140000000000000000000000
diff --git a/factory/gftables/9409 b/factory/gftables/9409
new file mode 100644
index 0000000..253d522
--- /dev/null
+++ b/factory/gftables/9409
@@ -0,0 +1,316 @@
+@@ factory GF(q) table @@
+97 2 v_1^2+96*v_1+5; 2 1 96 5
+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
+2Jy0Rp03116J0ZE05r0sE1nN0100l21QL2Gl0DG07I0W41h900U0rk000000000000000000000000000000000000
diff --git a/factory/gftables/961 b/factory/gftables/961
new file mode 100644
index 0000000..128f6ae
--- /dev/null
+++ b/factory/gftables/961
@@ -0,0 +1,34 @@
+@@ factory GF(q) table @@
+31 2 v_1^2+29*v_1+3; 2 1 29 3
+AZ6y3K7f7t4q5h8v7pF28fCg755t5mEfB28O2r56637S2M5e45BE2Z1VA2CN
+2L9IAf2mCMB3Ej6a1y828c6uDX1w4J7Z1d8Y1H8W2H9G6F8PBmDE7vFF0P4c
+2JEi5L7E7cDnBbCeCh4HCH9W7sBJEa47DJ14EO1N19AgCcAV2w4I6O5P5wEv
+Dy1XA68a3k8GCo410g6Q5jCTDL2f9mDq0QFC2v8u2UAz7H069p4ZEl4C1b3Y
+099x445FBO9R9u489bAEDmCr5K9nFH1f9iD117CR2X8DFT0VBV9F6Y7DBACJ
+5UF70E9qCF1r3N0d3J1Y3CE62bAi0T0a112P7ADh966f3j7j7lDcEqEW1TAk
+8H94F9AO5cAe7T4u5W7K663c3TBq6r1jCnEI503L9Y492Q818K3l1l4Y3R6b
+2SA9BuCaCL8A6B2i6PDC8w3SEbDQCb9lBoDP3y0BD358A5FD1I6e326d8p0O
+204s5d65231FF3DHEY8d7BBP35As3PEy7GBB1DDs422k4t3sF808FQ6V0i1P
+Ee62FNCDEk4nCA3EAF1G8tEtAA6qBD8J8E7k102AA00n9O7Y6H3Z3ODvEKBC
+BN95Cw8q5I7w8rDG6g1U3m0oAv9JEV739s5r022aDMCdFE343xEn9y0xBT0r
+0J5Z6TDVDe5REABIE28e5HCiBk558z2W9PCv6X54BQBM1u606I1tD8E98REG
+5C3n3rAa0fD95Q5nAU6k1a5u1R9r8o530X9SEcBw0K4PCY12FR9DER3W1QDD
+4a4r2xAMFP79DWDB612VF03G2jDY2yAw6oCZ0A5V18917U0CDz5A1g3fCpAc
+4LBl698xBLDr4TC7804E3v8k8LCB9d3dD00v5EAb1v7aCI269C6n5YBs1pED
+2C7uBj1J0Y3UACC1Ah5p529UBWCx8g2F9v6U3X6R1o4AC91kE7C3Dx57A3FV
+2KCt6G4N6S9a4WC29hELBSEQ2OAD1B5T4322D5Dt3I4d2pBc8h9T4Q0cAP6x
+A44eDpF521AQ590SAI3VDd9L5xC52c5B1M1mCSCm155DD46z4U27Eo4xD23q
+64CPARDw7I900p2N9zEN935z0F4OBv72BiCG8XBXF46l770l9240C6E1Dl6v
+AdCk8C2z9EAK6NDj9f5o8V3M9wET2l3pAuFOB50m4XFLEz7FAG4iDUDREr8S
+2e8N7NBd0Z0IBh5g5lEu0u7J3oCQ3QF16D7CFG3A8Z5q8j018F87160DASB1
+6AB94h9XECDKA17R8BCuAN0j4l1x9Q4F5sBGEFBy1h8I3u300N3w834D6W6M
+9V97E5EH1W2o4fBZ5JCyBp363b3h6c2G5bAL4MCE5kEE7h0LAJ7nAy1eAHCX
+Br2BB7BKArF60eE0FJ9gCW7137AqEm6mEU7L384bAX9HB4ClDa291i0yDbC0
+4y2nEh2qCzBR6K1O9KBx0H9j89678y9oB0FM5N9e2sEg2g4g8s988T6jEX3D
+041CDu0R514jEd0t6J071nB69cE33i8i0M0W314G2T1s4S7e2d7QCC685M7q
+E4BeBzAm4w4v0w3t6LAx4RFBDoDODI84FSBU0bES0kDZ0qEp9k7MDFCf339t
+8l4p4B6t9ADfDA5v0GABEMAn7VExD67d3BAjBf887W247r7P9N3F257zDg1c
+FA2ICs2h7yDk5S9B0h781ADSEBC8850zBgAp464oEZ2RBF6i2D748b03CVDT
+4V3z4z2u1Z99BH9MFK05D7FIC42tDNA76h8MB839BaBYAWCj6Z6C4KDi1K3e
+EwEJ70CKAt7X5O8Q1S7i0U7m0s6p3a1ECq6E7x7O1L5yE8ATBn2EA88m1qBt
+9Z1328Ao3g5G1z765i4m2Y86AlEP5X5f6sCU8UEs7g8n5a4k7o7b3H6wAYCO
diff --git a/factory/gmpext.h b/factory/gmpext.h
new file mode 100644
index 0000000..6c5cf56
--- /dev/null
+++ b/factory/gmpext.h
@@ -0,0 +1,26 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+#ifndef INCL_GMPEXT_H
+#define INCL_GMPEXT_H
+
+/**
+ * @file gmpext.h
+ *
+ * utility functions for gmp
+**/
+
+// #include "config.h"
+// #include <factory/cf_gmp.h>
+
+#include "cf_defs.h"
+#include "imm.h"
+
+
+inline bool
+mpz_is_imm( const mpz_t mpi )
+{
+    return ( mpz_cmp_si( mpi, MINIMMEDIATE ) >= 0 ) &&
+	( mpz_cmp_si( mpi, MAXIMMEDIATE ) <= 0 );
+}
+
+#endif /* ! INCL_GMPEXT_H */
diff --git a/factory/imm.cc b/factory/imm.cc
new file mode 100644
index 0000000..64a585e
--- /dev/null
+++ b/factory/imm.cc
@@ -0,0 +1,17 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+//{{{ docu
+//
+// imm.cc - some special implementations of immediate functions
+//   for some special platforms.
+//
+// Hierarchy: basic, arithmetic
+//
+//}}}
+
+
+#include "config.h"
+
+
+#include "imm.h"
+
diff --git a/factory/imm.h b/factory/imm.h
new file mode 100644
index 0000000..c896607
--- /dev/null
+++ b/factory/imm.h
@@ -0,0 +1,489 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+/**
+ * @file imm.h
+ *
+ * operations on immediates, that is elements of F_p, GF, Z, Q
+ * that fit into intrinsic int, long
+**/
+
+#ifndef INCL_IMM_H
+#define INCL_IMM_H
+
+#include <stdint.h>
+
+// #include "config.h"
+
+#ifndef NOSTREAMIO
+#ifdef HAVE_IOSTREAM
+#include <iostream>
+#define OSTREAM std::ostream
+#elif defined(HAVE_IOSTREAM_H)
+#include <iostream.h>
+#define OSTREAM ostream
+#endif
+#endif /* NOSTREAMIO */
+
+#include "cf_assert.h"
+
+#include "cf_defs.h"
+#include "cf_globals.h"
+#include "ffops.h"
+#include "gfops.h"
+#include "cf_factory.h"
+#include "canonicalform.h"
+#include "int_cf.h"
+
+const long INTMARK = 1;
+const long FFMARK = 2;
+const long GFMARK = 3;
+
+/* define type of your compilers 64 bit integer type */
+#ifndef FACTORY_INT64
+#define FACTORY_INT64 long long int
+#endif
+
+#if SIZEOF_LONG == 4
+const long MINIMMEDIATE = -268435454; // -2^28+2
+const long MAXIMMEDIATE = 268435454;  // 2^28-2
+#else
+const long MINIMMEDIATE = -(1L<<60)+2L; // -2^60+2
+const long MAXIMMEDIATE = (1L<<60)-2L;  // 2^60-2
+#endif
+
+#if defined(WINNT) && ! defined(__GNUC__)
+const FACTORY_INT64 MINIMMEDIATELL = -268435454i64;
+const FACTORY_INT64 MAXIMMEDIATELL = 268435454i64;
+#else
+const FACTORY_INT64 MINIMMEDIATELL = -268435454LL;
+const FACTORY_INT64 MAXIMMEDIATELL = 268435454LL;
+#endif
+
+//{{{ conversion functions
+//#ifdef HAS_ARITHMETIC_SHIFT
+#if 1
+
+inline long imm2int ( const InternalCF * const imm )
+{
+    return ((intptr_t)imm) >> 2;
+}
+
+inline InternalCF * int2imm ( long i )
+{
+    return (InternalCF*)((i << 2) | INTMARK );
+}
+
+#else
+
+inline int imm2int ( const InternalCF * const imm )
+{
+    // this could be better done by masking the sign bit
+    if ( ((int)((intptr_t)imm)) < 0 )
+        return -((-(intptr_t)imm) >> 2);
+    else
+        return (intptr_t)imm >> 2;
+}
+
+inline InternalCF * int2imm ( long i )
+{
+    if ( i < 0 )
+        return (InternalCF*)(-(((-i) << 2) | INTMARK));
+    else
+        return (InternalCF*)((i << 2) | INTMARK );
+}
+
+#endif
+
+inline InternalCF * int2imm_p ( long i )
+{
+    return (InternalCF*)((i << 2) | FFMARK );
+}
+
+inline InternalCF * int2imm_gf ( long i )
+{
+    return (InternalCF*)((i << 2) | GFMARK );
+}
+//}}}
+
+// predicates
+#if 0
+inline int is_imm ( const InternalCF * const ptr )
+{
+    // returns 0 if ptr is not immediate
+    return ( (intptr_t)ptr & 3 );
+}
+#endif
+
+//{{{ inline int imm_isone, imm_isone_p, imm_isone_gf ( const InternalCF * const ptr )
+// docu: see CanonicalForm::isOne()
+inline int
+imm_isone ( const InternalCF * const ptr )
+{
+    return imm2int( ptr ) == 1;
+}
+
+inline int
+imm_isone_p ( const InternalCF * const ptr )
+{
+    return imm2int( ptr ) == 1;
+}
+
+inline int
+imm_isone_gf ( const InternalCF * const ptr )
+{
+    return gf_isone( imm2int( ptr ) );
+}
+//}}}
+
+//{{{ inline int imm_iszero, imm_iszero_p, imm_iszero_gf ( const InternalCF * const ptr )
+// docu: see CanonicalForm::isZero()
+inline int
+imm_iszero ( const InternalCF * const ptr )
+{
+    return imm2int( ptr ) == 0;
+}
+
+inline int
+imm_iszero_p ( const InternalCF * const ptr )
+{
+    return imm2int( ptr ) == 0;
+}
+
+inline int
+imm_iszero_gf ( const InternalCF * const ptr )
+{
+    return gf_iszero( imm2int( ptr ) );
+}
+//}}}
+
+//{{{ conversion functions
+inline long imm_intval ( const InternalCF* const op )
+{
+    if ( is_imm( op ) == FFMARK )
+        if ( cf_glob_switches.isOn( SW_SYMMETRIC_FF ) )
+            return ff_symmetric( imm2int( op ) );
+        else
+            return imm2int( op );
+    else  if ( is_imm( op ) == GFMARK ) {
+        ASSERT( gf_isff( imm2int( op ) ), "invalid conversion" );
+        if ( cf_glob_switches.isOn( SW_SYMMETRIC_FF ) )
+            return ff_symmetric( gf_gf2ff( imm2int( op ) ) );
+        else
+            return gf_gf2ff( imm2int( op ) );
+    }
+    else
+        return imm2int( op );
+}
+//}}}
+
+/**
+ *
+ * imm_sign() - return sign of immediate object.
+ *
+ * If CO is an immediate integer, the sign is defined as usual.
+ * If CO is an element of FF(p) and SW_SYMMETRIC_FF is on the
+ * sign of CO is the sign of the symmetric representation of CO.
+ * If CO is in GF(q) or in FF(p) and SW_SYMMETRIC_FF is off, the
+ * sign of CO is zero iff CO is zero, otherwise the sign is one.
+ *
+ * @sa CanonicalForm::sign(), gf_sign()
+ *
+**/
+inline int
+imm_sign ( const InternalCF * const op )
+{
+    if ( is_imm( op ) == FFMARK )
+        if ( imm2int( op ) == 0 )
+            return 0;
+        else  if ( cf_glob_switches.isOn( SW_SYMMETRIC_FF ) )
+            if ( ff_symmetric( imm2int( op ) ) > 0 )
+                return 1;
+            else
+                return -1;
+        else
+            return 1;
+    else  if ( is_imm( op ) == GFMARK )
+        return gf_sign( imm2int( op ) );
+    else  if ( imm2int( op ) == 0 )
+        return 0;
+    else  if ( imm2int( op ) > 0 )
+        return 1;
+    else
+        return -1;
+}
+
+/**
+ *
+ * imm_cmp(), imm_cmp_p(), imm_cmp_gf() - compare immediate objects.
+ *
+ * For immediate integers, it is clear how this should be done.
+ * For objects from finite fields, it is not clear since they
+ * are not ordered fields.  However, since we want to have a
+ * total well order on polynomials we have to define a total well
+ * order on all coefficients, too. We decided to use simply the
+ * order on the representation as `int's of such objects.
+ *
+ * @sa CanonicalForm::operator <(), CanonicalForm::operator ==()
+ *
+**/
+inline int
+imm_cmp ( const InternalCF * const lhs, const InternalCF * const rhs )
+{
+    if ( imm2int( lhs ) == imm2int( rhs ) )
+        return 0;
+    else  if ( imm2int( lhs ) > imm2int( rhs ) )
+        return 1;
+    else
+        return -1;
+}
+
+inline int
+imm_cmp_p ( const InternalCF * const lhs, const InternalCF * const rhs )
+{
+    if ( imm2int( lhs ) == imm2int( rhs ) )
+        return 0;
+    else if ( imm2int( lhs ) > imm2int( rhs ) )
+        return 1;
+    else
+        return -1;
+}
+
+inline int
+imm_cmp_gf ( const InternalCF * const lhs, const InternalCF * const rhs )
+{
+    if ( imm2int( lhs ) == imm2int( rhs ) )
+        return 0;
+    // check is done in this way because zero should be minimal
+    else if ( imm2int( lhs ) > imm2int( rhs ) )
+        return -1;
+    else
+        return 1;
+}
+//}}}
+
+//{{{ arithmetic operators
+inline InternalCF * imm_add ( const InternalCF * const lhs, const InternalCF * const rhs )
+{
+    long result = imm2int( lhs ) + imm2int( rhs );
+    if ( ( result > MAXIMMEDIATE ) || ( result < MINIMMEDIATE ) )
+        return CFFactory::basic( result );
+    else
+        return int2imm( result );
+}
+
+inline InternalCF * imm_add_p ( const InternalCF * const lhs, const InternalCF * const rhs )
+{
+    return int2imm_p( ff_add( imm2int( lhs ), imm2int( rhs ) ) );
+}
+
+inline InternalCF * imm_add_gf ( const InternalCF * const lhs, const InternalCF * const rhs )
+{
+    return int2imm_gf( gf_add( imm2int( lhs ), imm2int( rhs ) ) );
+}
+
+inline InternalCF * imm_sub ( const InternalCF * const lhs, const InternalCF * const rhs )
+{
+    long result = imm2int( lhs ) - imm2int( rhs );
+    if ( ( result > MAXIMMEDIATE ) || ( result < MINIMMEDIATE ) )
+        return CFFactory::basic( result );
+    else
+        return int2imm( result );
+}
+
+inline InternalCF * imm_sub_p ( const InternalCF * const lhs, const InternalCF * const rhs )
+{
+    return int2imm_p( ff_sub( imm2int( lhs ), imm2int( rhs ) ) );
+}
+
+inline InternalCF * imm_sub_gf ( const InternalCF * const lhs, const InternalCF * const rhs )
+{
+    return int2imm_gf( gf_sub( imm2int( lhs ), imm2int( rhs ) ) );
+}
+
+inline InternalCF *
+imm_mul ( InternalCF * lhs, InternalCF * rhs )
+{
+    long a = imm2int( lhs );
+    long b = imm2int( rhs );
+    int sa= 1;
+    unsigned FACTORY_INT64 aa, bb;
+    if (a < 0)
+    {
+      sa= -1;
+      aa= (unsigned FACTORY_INT64) (-a);
+    }
+    else
+      aa= (unsigned FACTORY_INT64) a;
+    if (b < 0)
+    {
+      sa= -sa;
+      bb= (unsigned FACTORY_INT64) (-b);
+    }
+    else
+      bb= (unsigned FACTORY_INT64) b;
+    unsigned FACTORY_INT64 result = aa*bb;
+    #if SIZEOF_LONG == 4
+    if (result>(unsigned FACTORY_INT64)MAXIMMEDIATE)
+    {
+        InternalCF * res = CFFactory::basic( IntegerDomain, a, true );
+        return res->mulcoeff( rhs );
+    }
+    #else
+    if ( ( a!=0L ) && ((result/aa!=bb) || (result>(unsigned FACTORY_INT64) MAXIMMEDIATE) ))
+    {
+        InternalCF * res = CFFactory::basic( IntegerDomain, a, true );
+        return res->mulcoeff( rhs );
+    }
+    #endif
+    else
+      return int2imm( sa*result );
+}
+
+inline InternalCF * imm_mul_p ( const InternalCF * const lhs, const InternalCF * const rhs )
+{
+    return int2imm_p( ff_mul( imm2int( lhs ), imm2int( rhs ) ) );
+}
+
+inline InternalCF * imm_mul_gf ( const InternalCF * const lhs, const InternalCF * const rhs )
+{
+    return int2imm_gf( gf_mul( imm2int( lhs ), imm2int( rhs ) ) );
+}
+
+inline InternalCF * imm_div ( const InternalCF * const lhs, const InternalCF * const rhs )
+{
+    long a = imm2int( lhs );
+    long b = imm2int( rhs );
+    if ( a > 0 )
+        return int2imm( a / b );
+    else  if ( b > 0 )
+        return int2imm( -((b-a-1)/b) );
+    else
+        return int2imm( (-a-b-1)/(-b) );
+}
+
+inline InternalCF * imm_divrat ( const InternalCF * const lhs, const InternalCF * const rhs )
+{
+    if ( cf_glob_switches.isOn( SW_RATIONAL ) )
+        return CFFactory::rational( imm2int( lhs ), imm2int( rhs ) );
+    else {
+        long a = imm2int( lhs );
+        long b = imm2int( rhs );
+        if ( a > 0 )
+            return int2imm( a / b );
+        else  if ( b > 0 )
+            return int2imm( -((b-a-1)/b) );
+        else
+            return int2imm( (-a-b-1)/(-b) );
+    }
+}
+
+inline InternalCF * imm_div_p ( const InternalCF * const lhs, const InternalCF * const rhs )
+{
+    return int2imm_p( ff_div( imm2int( lhs ), imm2int( rhs ) ) );
+}
+
+inline InternalCF * imm_div_gf ( const InternalCF * const lhs, const InternalCF * const rhs )
+{
+    return int2imm_gf( gf_div( imm2int( lhs ), imm2int( rhs ) ) );
+}
+
+inline InternalCF * imm_mod ( const InternalCF * const lhs, const InternalCF * const rhs )
+{
+    if ( cf_glob_switches.isOn( SW_RATIONAL ) )
+        return int2imm( 0 );
+    else {
+        long a = imm2int( lhs );
+        long b = imm2int( rhs );
+        if ( a > 0 )
+            if ( b > 0 )
+                return int2imm( a % b );
+            else
+                return int2imm( a % (-b) );
+        else
+            if ( b > 0 ) {
+                long r = (-a) % b;
+                return int2imm( (r==0) ? r : b-r );
+            }
+            else {
+                long r = (-a) % (-b);
+                return int2imm( (r==0) ? r : -b-r );
+            }
+    }
+}
+
+inline InternalCF * imm_mod_p ( const InternalCF * const, const InternalCF * const )
+{
+    return int2imm_p( 0 );
+}
+
+inline InternalCF * imm_mod_gf ( const InternalCF * const, const InternalCF * const )
+{
+    return int2imm_gf( gf_q );
+}
+
+inline void imm_divrem ( const InternalCF * const lhs, const InternalCF * const rhs, InternalCF * & q, InternalCF * & r )
+{
+    if ( cf_glob_switches.isOn( SW_RATIONAL ) ) {
+        q = imm_divrat( lhs, rhs );
+        r = CFFactory::basic( 0L );
+    }
+    else {
+        q = imm_div( lhs, rhs );
+        r = imm_mod( lhs, rhs );
+    }
+}
+
+inline void imm_divrem_p ( const InternalCF * const lhs, const InternalCF * const rhs, InternalCF * & q, InternalCF * & r )
+{
+    q = int2imm_p( ff_div( imm2int( lhs ), imm2int( rhs ) ) );
+    r = int2imm_p( 0 );
+}
+
+inline void imm_divrem_gf ( const InternalCF * const lhs, const InternalCF * const rhs, InternalCF * & q, InternalCF * & r )
+{
+    q = int2imm_gf( gf_div( imm2int( lhs ), imm2int( rhs ) ) );
+    r = int2imm_gf( gf_q );
+}
+
+//{{{ inline InternalCF * imm_neg, imm_neg_p, imm_neg_gf ( const InternalCF * const op )
+// docu: see CanonicalForm::operator -()
+inline InternalCF *
+imm_neg ( const InternalCF * const op )
+{
+    return int2imm( -imm2int( op ) );
+}
+
+inline InternalCF *
+imm_neg_p ( const InternalCF * const op )
+{
+    return int2imm_p( ff_neg( imm2int( op ) ) );
+}
+
+inline InternalCF *
+imm_neg_gf ( const InternalCF * const op )
+{
+    return int2imm_gf( gf_neg( imm2int( op ) ) );
+}
+//}}}
+//}}}
+
+//{{{ input/output
+#ifndef NOSTREAMIO
+inline void imm_print ( OSTREAM & os, const InternalCF * const op, const char * const str )
+{
+    if ( is_imm( op ) == FFMARK )
+        if ( cf_glob_switches.isOn( SW_SYMMETRIC_FF ) )
+            os << ff_symmetric( imm2int( op ) ) << str;
+        else
+            os << imm2int( op ) << str;
+    else  if ( is_imm( op ) == GFMARK ) {
+        gf_print( os, imm2int( op ) );
+        os << str;
+    }
+    else
+        os << imm2int( op ) << str;
+}
+#endif /* NOSTREAMIO */
+//}}}
+
+#endif /* ! INCL_IMM_H */
diff --git a/factory/include/factory/Makefile.am b/factory/include/factory/Makefile.am
new file mode 100644
index 0000000..4f13cc1
--- /dev/null
+++ b/factory/include/factory/Makefile.am
@@ -0,0 +1,12 @@
+# -*- Makefile -*-
+
+templateincl =	templates/ftmpl_array.h \
+		templates/ftmpl_afactor.h \
+		templates/ftmpl_factor.h \
+		templates/ftmpl_list.h \
+		templates/ftmpl_matrix.h
+
+libfactory_includedir = ${includedir}/factory
+
+nobase_libfactory_include_HEADERS = \
+              cf_gmp.h ${templateincl}
diff --git a/factory/include/factory/Makefile.in b/factory/include/factory/Makefile.in
new file mode 100644
index 0000000..141958a
--- /dev/null
+++ b/factory/include/factory/Makefile.in
@@ -0,0 +1,623 @@
+# Makefile.in generated by automake 1.13.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 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@
+
+# -*- Makefile -*-
+
+VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+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 = include/factory
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(nobase_libfactory_include_HEADERS)
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/../m4/ax_append_compile_flags.m4 \
+	$(top_srcdir)/../m4/ax_append_flag.m4 \
+	$(top_srcdir)/../m4/ax_append_link_flags.m4 \
+	$(top_srcdir)/../m4/ax_check_compile_flag.m4 \
+	$(top_srcdir)/../m4/ax_check_link_flag.m4 \
+	$(top_srcdir)/../m4/ax_prefix_config_h.m4 \
+	$(top_srcdir)/../m4/flags.m4 \
+	$(top_srcdir)/../m4/flint-check.m4 \
+	$(top_srcdir)/../m4/gmp-check.m4 \
+	$(top_srcdir)/../m4/libtool.m4 \
+	$(top_srcdir)/../m4/ltoptions.m4 \
+	$(top_srcdir)/../m4/ltsugar.m4 \
+	$(top_srcdir)/../m4/ltversion.m4 \
+	$(top_srcdir)/../m4/lt~obsolete.m4 \
+	$(top_srcdir)/../m4/ntl-check.m4 \
+	$(top_srcdir)/../m4/options.m4 $(top_srcdir)/acinclude.m4 \
+	$(top_srcdir)/configure.ac
+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_V_P = $(am__v_P_ at AM_V@)
+am__v_P_ = $(am__v_P_ at AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_ at AM_V@)
+am__v_GEN_ = $(am__v_GEN_ at AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_ at AM_V@)
+am__v_at_ = $(am__v_at_ at AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+SOURCES =
+DIST_SOURCES =
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+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__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
+am__installdirs = "$(DESTDIR)$(libfactory_includedir)"
+HEADERS = $(nobase_libfactory_include_HEADERS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BISON = @BISON@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DOXYGEN_PAPER_SIZE = @DOXYGEN_PAPER_SIZE@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+DX_CONFIG = @DX_CONFIG@
+DX_DOCDIR = @DX_DOCDIR@
+DX_DOT = @DX_DOT@
+DX_DOXYGEN = @DX_DOXYGEN@
+DX_DVIPS = @DX_DVIPS@
+DX_EGREP = @DX_EGREP@
+DX_ENV = @DX_ENV@
+DX_FLAG_DX_CURRENT_FEATURE = @DX_FLAG_DX_CURRENT_FEATURE@
+DX_FLAG_chi = @DX_FLAG_chi@
+DX_FLAG_chm = @DX_FLAG_chm@
+DX_FLAG_doc = @DX_FLAG_doc@
+DX_FLAG_dot = @DX_FLAG_dot@
+DX_FLAG_html = @DX_FLAG_html@
+DX_FLAG_man = @DX_FLAG_man@
+DX_FLAG_pdf = @DX_FLAG_pdf@
+DX_FLAG_ps = @DX_FLAG_ps@
+DX_FLAG_rtf = @DX_FLAG_rtf@
+DX_FLAG_xml = @DX_FLAG_xml@
+DX_HHC = @DX_HHC@
+DX_LATEX = @DX_LATEX@
+DX_MAKEINDEX = @DX_MAKEINDEX@
+DX_PDFLATEX = @DX_PDFLATEX@
+DX_PERL = @DX_PERL@
+DX_PROJECT = @DX_PROJECT@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+FLINT_CFLAGS = @FLINT_CFLAGS@
+FLINT_HOME = @FLINT_HOME@
+FLINT_LIBS = @FLINT_LIBS@
+GMP_CFLAGS = @GMP_CFLAGS@
+GMP_HOME = @GMP_HOME@
+GMP_LIBS = @GMP_LIBS@
+GMP_VERSION = @GMP_VERSION@
+GREP = @GREP@
+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@
+M4 = @M4@
+MAINT = @MAINT@
+MAKEHEADERFLAGS = @MAKEHEADERFLAGS@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NTL_CFLAGS = @NTL_CFLAGS@
+NTL_LIBS = @NTL_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OMALLOC_INCLUDES = @OMALLOC_INCLUDES@
+OMALLOC_LIBS = @OMALLOC_LIBS@
+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@
+PKG_REQUIRE = @PKG_REQUIRE@
+POLYMAKE_CXXFLAGS = @POLYMAKE_CXXFLAGS@
+RANLIB = @RANLIB@
+RESOURCES_INCLUDES = @RESOURCES_INCLUDES@
+RESOURCES_LIBS = @RESOURCES_LIBS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SINGULAR_CFLAGS = @SINGULAR_CFLAGS@
+STRIP = @STRIP@
+VERSION = @VERSION@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+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@
+factory_version = @factory_version@
+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@
+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@
+templateincl = templates/ftmpl_array.h \
+		templates/ftmpl_afactor.h \
+		templates/ftmpl_factor.h \
+		templates/ftmpl_list.h \
+		templates/ftmpl_matrix.h
+
+libfactory_includedir = ${includedir}/factory
+nobase_libfactory_include_HEADERS = \
+              cf_gmp.h ${templateincl}
+
+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) --foreign include/factory/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign include/factory/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-nobase_libfactory_includeHEADERS: $(nobase_libfactory_include_HEADERS)
+	@$(NORMAL_INSTALL)
+	@list='$(nobase_libfactory_include_HEADERS)'; test -n "$(libfactory_includedir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(libfactory_includedir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(libfactory_includedir)" || exit 1; \
+	fi; \
+	$(am__nobase_list) | while read dir files; do \
+	  xfiles=; for file in $$files; do \
+	    if test -f "$$file"; then xfiles="$$xfiles $$file"; \
+	    else xfiles="$$xfiles $(srcdir)/$$file"; fi; done; \
+	  test -z "$$xfiles" || { \
+	    test "x$$dir" = x. || { \
+	      echo " $(MKDIR_P) '$(DESTDIR)$(libfactory_includedir)/$$dir'"; \
+	      $(MKDIR_P) "$(DESTDIR)$(libfactory_includedir)/$$dir"; }; \
+	    echo " $(INSTALL_HEADER) $$xfiles '$(DESTDIR)$(libfactory_includedir)/$$dir'"; \
+	    $(INSTALL_HEADER) $$xfiles "$(DESTDIR)$(libfactory_includedir)/$$dir" || exit $$?; }; \
+	done
+
+uninstall-nobase_libfactory_includeHEADERS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(nobase_libfactory_include_HEADERS)'; test -n "$(libfactory_includedir)" || list=; \
+	$(am__nobase_strip_setup); files=`$(am__nobase_strip)`; \
+	dir='$(DESTDIR)$(libfactory_includedir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	$(am__define_uniq_tagged_files); \
+	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-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	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"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+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 $(HEADERS)
+installdirs:
+	for dir in "$(DESTDIR)$(libfactory_includedir)"; 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:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+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 distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-nobase_libfactory_includeHEADERS
+
+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-nobase_libfactory_includeHEADERS
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
+	clean-libtool cscopelist-am ctags ctags-am 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-nobase_libfactory_includeHEADERS 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 tags tags-am uninstall \
+	uninstall-am uninstall-nobase_libfactory_includeHEADERS
+
+
+# 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/factory/include/factory/cf_gmp.h b/factory/include/factory/cf_gmp.h
new file mode 100644
index 0000000..58f81c2
--- /dev/null
+++ b/factory/include/factory/cf_gmp.h
@@ -0,0 +1,28 @@
+#ifndef SI_GMP_H
+#define SI_GMP_H
+
+/*
+#ifdef __cplusplus
+//  #define __cplusplus_backup __cplusplus
+
+# ifdef DISABLE_GMP_CPP
+#  undef __cplusplus
+extern "C"
+{
+*/
+
+# include <gmp.h>
+/*
+}
+  #include <factory/cplusplus.h>
+#else
+  #include <gmp.h>
+#endif
+//  #define __cplusplus __cplusplus_backup
+#else
+  #include <gmp.h>
+#endif
+*/
+
+
+#endif /* SI_GMP_H */
diff --git a/factory/include/factory/templates/ftmpl_afactor.h b/factory/include/factory/templates/ftmpl_afactor.h
new file mode 100644
index 0000000..b961577
--- /dev/null
+++ b/factory/include/factory/templates/ftmpl_afactor.h
@@ -0,0 +1,48 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+#ifndef INCL_AFACTOR_H
+#define INCL_AFACTOR_H
+
+// #include <factory/factoryconf.h>
+
+#ifndef NOSTREAMIO
+#ifdef HAVE_IOSTREAM
+#include <iostream>
+#define OSTREAM std::ostream
+#elif defined(HAVE_IOSTREAM_H)
+#include <iostream.h>
+#define OSTREAM ostream
+#endif
+#endif /* NOSTREAMIO */
+
+template <class T>
+class AFactor {
+private:
+    T _factor;
+    T _minpoly;
+    int _exp;
+public:
+    AFactor() : _factor(1), _minpoly (1), _exp(0) {}
+    AFactor( const AFactor<T> & f ) : _factor(f._factor), _minpoly (f._minpoly), _exp(f._exp) {}
+    AFactor( const T & f, const T & m, int e ) : _factor(f), _minpoly (m), _exp(e) {}
+    AFactor( const T & f, const T & m ) : _factor(f), _minpoly (m), _exp(1) {}
+    ~AFactor() {}
+    AFactor<T>& operator= ( const AFactor<T>& );
+    T factor() const { return _factor; }
+    T minpoly() const { return _minpoly; }
+    int exp() const { return _exp; }
+    T value() const { return power( _factor, _exp ); }
+#ifndef NOSTREAMIO
+    void print ( OSTREAM& ) const;
+#endif /* NOSTREAMIO */
+};
+
+template <class T> int
+operator== ( const AFactor<T>&, const AFactor<T>& );
+
+#ifndef NOSTREAMIO
+template <class T>
+OSTREAM& operator<< ( OSTREAM & os, const AFactor<T> & f );
+#endif /* NOSTREAMIO */
+
+#endif /* ! INCL_AFACTOR_H */
diff --git a/factory/include/factory/templates/ftmpl_array.h b/factory/include/factory/templates/ftmpl_array.h
new file mode 100644
index 0000000..2759e03
--- /dev/null
+++ b/factory/include/factory/templates/ftmpl_array.h
@@ -0,0 +1,46 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+#ifndef INCL_ARRAY_H
+#define INCL_ARRAY_H
+
+// #include <factory/factoryconf.h>
+
+#ifndef NOSTREAMIO
+#ifdef HAVE_IOSTREAM
+#include <iostream>
+#define OSTREAM std::ostream
+#elif defined(HAVE_IOSTREAM_H)
+#include <iostream.h>
+#define OSTREAM ostream
+#endif
+#endif /* NOSTREAMIO */
+
+template <class T>
+class Array {
+private:
+    T * data;
+    int _min;
+    int _max;
+    int _size;
+public:
+    Array();
+    Array( const Array<T>& );
+    Array( int size );
+    Array( int min, int max );
+    ~Array();
+    Array<T>& operator= ( const Array<T>& );
+    T& operator[] ( int i ) const;
+    int size() const;
+    int min() const;
+    int max() const;
+#ifndef NOSTREAMIO
+    void print ( OSTREAM& ) const;
+#endif /* NOSTREAMIO */
+};
+
+#ifndef NOSTREAMIO
+template <class T>
+OSTREAM& operator<< ( OSTREAM & os, const Array<T> & a );
+#endif /* NOSTREAMIO */
+
+#endif /* ! INCL_ARRAY_H */
diff --git a/factory/include/factory/templates/ftmpl_factor.h b/factory/include/factory/templates/ftmpl_factor.h
new file mode 100644
index 0000000..98eb7c8
--- /dev/null
+++ b/factory/include/factory/templates/ftmpl_factor.h
@@ -0,0 +1,51 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+#ifndef INCL_FACTOR_H
+#define INCL_FACTOR_H
+
+// #include <factory/factoryconf.h>
+
+#ifndef NOSTREAMIO
+#ifdef HAVE_IOSTREAM
+#include <iostream>
+#define OSTREAM std::ostream
+#elif defined(HAVE_IOSTREAM_H)
+#include <iostream.h>
+#define OSTREAM ostream
+#endif
+#endif /* NOSTREAMIO */
+
+
+template <class T>
+class Factor {
+private:
+    T _factor;
+    int _exp;
+public:
+    Factor() : _factor(1), _exp(0) {}
+    Factor( const Factor<T> & f ) : _factor(f._factor), _exp(f._exp) {}
+    Factor( const T & f, int e ) : _factor(f), _exp(e) {}
+    Factor( const T & f ) : _factor(f), _exp(1) {}
+    ~Factor() {}
+    Factor<T>& operator= ( const Factor<T>& );
+    Factor<T>& operator= ( const T& );
+    T factor() const { return _factor; }
+    int exp() const { return _exp; }
+    T value() const { return power( _factor, _exp ); }
+    Factor<T>& operator+= ( int i ) { _exp += i; return *this; }
+    Factor<T>& operator*= ( int i ) { _exp *= i; return *this; }
+    Factor<T>& operator*= ( const T & f ) { _factor *= f; return *this; }
+#ifndef NOSTREAMIO
+    void print ( OSTREAM& ) const;
+#endif /* NOSTREAMIO */
+};
+
+template <class T> int
+operator== ( const Factor<T>&, const Factor<T>& );
+
+#ifndef NOSTREAMIO
+template <class T>
+OSTREAM& operator<< ( OSTREAM & os, const Factor<T> & f );
+#endif /* NOSTREAMIO */
+
+#endif /* ! INCL_FACTOR_H */
diff --git a/factory/include/factory/templates/ftmpl_list.h b/factory/include/factory/templates/ftmpl_list.h
new file mode 100644
index 0000000..aa10cf8
--- /dev/null
+++ b/factory/include/factory/templates/ftmpl_list.h
@@ -0,0 +1,145 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+#ifndef INCL_LIST_H
+#define INCL_LIST_H
+
+// #include <factory/factoryconf.h>
+
+#ifndef NOSTREAMIO
+#ifdef HAVE_IOSTREAM
+#include <iostream>
+#define OSTREAM std::ostream
+#elif defined(HAVE_IOSTREAM_H)
+#include <iostream.h>
+#define OSTREAM ostream
+#endif
+#endif /* NOSTREAMIO */
+
+template <class T>
+class ListIterator;
+
+template <class T>
+class List;
+
+#ifndef NOSTREAMIO
+template <class T>
+OSTREAM& operator<< ( OSTREAM &, const List<T> &);
+#endif
+
+template <class T>
+class ListItem
+{
+private:
+    ListItem * next;
+    ListItem * prev;
+    T * item;
+public:
+    ListItem( const ListItem<T>& );
+    ListItem( const T&, ListItem<T>*, ListItem<T>* );
+    ListItem( T* , ListItem<T>* , ListItem<T>* );
+    ~ListItem();
+    ListItem<T>& operator= ( const ListItem<T>& );
+    ListItem<T>* getNext();
+    ListItem<T>* getPrev();
+    T& getItem();
+#ifndef NOSTREAMIO
+    void print ( OSTREAM& );
+#endif /* NOSTREAMIO */
+    friend class ListIterator<T>;
+    friend class List<T>;
+};
+
+template <class T>
+class List
+{
+private:
+    ListItem<T> *first;
+    ListItem<T> *last;
+    int _length;
+public:
+    List();
+    List( const List<T>& );
+    List( const T& );
+    ~List();
+    List<T>& operator= ( const List<T>& );
+    void insert ( const T& );
+    void insert ( const T&, int (*cmpf)( const T&, const T& ) );
+    void insert ( const T&, int (*cmpf)( const T&, const T& ), void (*insf)( T&, const T& ) );
+    void append ( const T& );
+    int isEmpty() const;
+    int length() const;
+    T getFirst() const;
+    void removeFirst();
+    T getLast() const;
+    void removeLast();
+    void sort ( int (*) ( const T&, const T& ) );
+#ifndef NOSTREAMIO
+    void print ( OSTREAM & ) const;
+    friend OSTREAM& operator<< <T>( OSTREAM & os, const List<T> & l );
+#endif /* NOSTREAMIO */
+    friend class ListIterator<T>;
+};
+
+#ifndef NOSTREAMIO
+template <class T>
+OSTREAM& operator<< ( OSTREAM & os, const List<T> & l );
+#endif /* NOSTREAMIO */
+
+template <class T>
+class ListIterator {
+private:
+    List<T> *theList;
+    ListItem<T> *current;
+public:
+    ListIterator();
+    ListIterator( const ListIterator<T>& );
+    ListIterator( const List<T>& );
+    ~ListIterator();
+    ListIterator<T>& operator = ( const ListIterator<T>& );
+    ListIterator<T>& operator = ( const List<T>& );
+    T& getItem() const;
+    int hasItem();
+    void operator++();
+    void operator--();
+    void operator++( int );
+    void operator--( int );
+    void firstItem();
+    void lastItem();
+    void insert( const T& );
+    void append( const T& );
+    void remove( int moveright );
+};
+
+template <class T>
+int operator== (const List<T>&, const List<T>& );
+
+template <class T>
+List<T> Union ( const List<T>&, const List<T>& );
+
+template <class T>
+List<T> Difference ( const List<T>&, const List<T>& );
+
+template <class T>
+List<T> Union ( const List<T> &, const List<T> & , int (*ecmpf)( const T&, const T& ));
+
+template <class T>
+List<T> Difference ( const List<T> &, const List<T> & , int (*ecmpf)( const T&, const T& ));
+
+template <class T>
+List<T> Difference ( const List<T> & F, const T & G);
+
+template <class T>
+List<T> Difference ( const List<T> & F, const T & G, int (*ecmpf)( const T&, const T& ));
+
+template <class T>
+List<T> Union ( const List<T>&, const List<T>&, int (*cmpf)( const T&, const T& ), void (*insf)( T&, const T& ) );
+
+template <class T>
+T prod ( const List<T>& );
+
+template <class T>
+bool find (const List<T>&, const T& t);
+
+template <class T>
+bool find (const List<T> & F, const T& t, int (*ecmpf)( const T&, const T& ));
+#endif /* ! INCL_LIST_H */
diff --git a/factory/include/factory/templates/ftmpl_matrix.h b/factory/include/factory/templates/ftmpl_matrix.h
new file mode 100644
index 0000000..b451b87
--- /dev/null
+++ b/factory/include/factory/templates/ftmpl_matrix.h
@@ -0,0 +1,95 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+#ifndef INCL_MATRIX_H
+#define INCL_MATRIX_H
+
+// #include <factory/factoryconf.h>
+
+#ifndef NOSTREAMIO
+#ifdef HAVE_IOSTREAM
+#include <iostream>
+#define OSTREAM std::ostream
+#elif defined(HAVE_IOSTREAM_H)
+#include <iostream.h>
+#define OSTREAM ostream
+#endif
+#endif /* NOSTREAMIO */
+
+template <class T>
+class SubMatrix;
+
+template <class T>
+class Matrix;
+
+#ifndef NOSTREAMIO
+template <class T>
+OSTREAM& operator<< (OSTREAM &, const Matrix<T> &);
+#endif
+
+template <class T>
+class Matrix
+{
+private:
+    int NR, NC;
+    T ** elems;
+#ifndef NOSTREAMIO
+    void printrow ( OSTREAM & s, int i ) const;
+#endif /* NOSTREAMIO */
+    typedef T* T_ptr;
+public:
+    Matrix() : NR(0), NC(0), elems(0) {}
+    Matrix( int nr, int nc );
+    Matrix( const Matrix<T>& M );
+    ~Matrix();
+    Matrix<T>& operator= ( const Matrix<T>& M );
+    int rows() const { return NR; }
+    int columns() const { return NC; }
+    SubMatrix<T> operator[] ( int i );
+    const SubMatrix<T> operator[] ( int i ) const;
+    T& operator() ( int row, int col );
+    T operator() ( int row, int col ) const;
+    SubMatrix<T> operator() ( int rmin, int rmax, int cmin, int cmax );
+    const SubMatrix<T> operator() ( int rmin, int rmax, int cmin, int cmax ) const;
+    void swapRow( int i, int j );
+    void swapColumn( int i, int j );
+#ifndef NOSTREAMIO
+    void print( OSTREAM& s ) const;
+    friend OSTREAM & operator<< <T>( OSTREAM & s, const Matrix<T>& M );
+#endif /* NOSTREAMIO */
+    friend class SubMatrix<T>;
+};
+    /*template <class T>
+    Matrix<T> operator+ ( const Matrix<T>& lhs, const Matrix<T>& rhs );
+    template <class T>
+    Matrix<T> operator- ( const Matrix<T>& lhs, const Matrix<T>& rhs );
+    template <class T>
+    Matrix<T> operator* ( const Matrix<T>& lhs, const Matrix<T>& rhs );
+    template <class T>
+    Matrix<T> operator* ( const Matrix<T>& lhs, const T& rhs );
+    template <class T>
+    Matrix<T> operator* ( const T& lhs, const Matrix<T>& rhs );*/
+
+template <class T>
+class SubMatrix
+{
+private:
+    int r_min, r_max, c_min, c_max;
+    Matrix<T>& M;
+    // we do not provide a default ctor, so nobody can declare an empty SubMatrix
+    SubMatrix( int rmin, int rmax, int cmin, int cmax, const Matrix<T> & m );
+public:
+    SubMatrix( const SubMatrix<T> & S );
+    SubMatrix<T>& operator= ( const SubMatrix<T>& S );
+    SubMatrix<T>& operator= ( const Matrix<T>& S );
+    operator Matrix<T>() const;
+    T operator[] ( int i ) const;
+    T& operator[] ( int i );
+    friend class Matrix<T>;
+};
+
+#ifndef NOSTREAMIO
+template <class T>
+OSTREAM & operator<< ( OSTREAM & s, const Matrix<T>& M );
+#endif /* NOSTREAMIO */
+
+#endif /* ! INCL_MATRIX_H */
diff --git a/factory/int_cf.cc b/factory/int_cf.cc
new file mode 100644
index 0000000..00cd754
--- /dev/null
+++ b/factory/int_cf.cc
@@ -0,0 +1,225 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+
+#include "config.h"
+
+
+#include "cf_assert.h"
+
+#include "cf_defs.h"
+#include "int_cf.h"
+#include "canonicalform.h"
+#include "cf_factory.h"
+
+/** bool InternalCF::isOne, isZero () const
+ * @sa CanonicalForm::isOne(), CanonicalForm::isZero()
+**/
+bool
+InternalCF::isOne () const
+{
+    return false;
+}
+
+bool
+InternalCF::isZero () const
+{
+    return false;
+}
+
+
+/** CanonicalForm InternalCF::lc (), Lc (), LC ()
+ *  @sa CanonicalForm::lc(), Lc(), LC()
+**/
+CanonicalForm
+InternalCF::lc ()
+{
+    return CanonicalForm( copyObject() );
+}
+
+CanonicalForm
+InternalCF::Lc ()
+{
+    return CanonicalForm( copyObject() );
+}
+
+CanonicalForm
+InternalCF::LC ()
+{
+    return CanonicalForm( copyObject() );
+}
+
+/** int InternalCF::degree ()
+ * @sa CanonicalForm::degree()
+**/
+int
+InternalCF::degree ()
+{
+    if ( isZero() )
+        return -1;
+    else
+        return 0;
+}
+
+/** CanonicalForm InternalCF::tailcoeff (), int InternalCF::taildegree ()
+ * @sa CanonicalForm::tailcoeff(), taildegree()
+**/
+CanonicalForm
+InternalCF::tailcoeff ()
+{
+    return CanonicalForm( copyObject() );
+}
+
+int
+InternalCF::taildegree ()
+{
+    if ( isZero() )
+        return -1;
+    else
+        return 0;
+}
+
+/** InternalCF * InternalCF::num (), den ()
+ * @sa CanonicalForm::num(), den()
+**/
+InternalCF *
+InternalCF::num ()
+{
+    return copyObject();
+}
+
+InternalCF *
+InternalCF::den ()
+{
+    return CFFactory::basic( 1L );
+}
+
+/** InternalCF * InternalCF::sqrt ()
+ * @sa CanonicalForm::sqrt()
+**/
+InternalCF *
+InternalCF::sqrt ()
+{
+    ASSERT1( 0, "sqrt() not implemented for class %s", this->classname() );
+    return 0;
+}
+
+/** int InternalCF::ilog2 ()
+ * @sa CanonicalForm::ilog2()
+**/
+int
+InternalCF::ilog2 ()
+{
+    ASSERT1( 0, "ilog2() not implemented for class %s", this->classname() );
+    return 0;
+}
+
+/** CanonicalForm InternalCF::coeff ( int i )
+ * @sa CanonicalForm::operator []()
+**/
+CanonicalForm
+InternalCF::coeff ( int i )
+{
+    if ( i == 0 )
+        return CanonicalForm( copyObject() );
+    else
+        return CanonicalForm( 0 );
+}
+
+/** InternalCF * InternalCF::bgcdsame, bgcdcoeff ( const InternalCF * const )
+ * @sa CanonicalForm::bgcd()
+**/
+InternalCF *
+InternalCF::bgcdsame ( const InternalCF * const ) const
+{
+    ASSERT1( 0, "bgcd() not implemented for class %s", this->classname() );
+    return CFFactory::basic( 0L );
+}
+
+InternalCF *
+InternalCF::bgcdcoeff ( const InternalCF * const )
+{
+    ASSERT1( 0, "bgcd() not implemented for class %s", this->classname() );
+    return CFFactory::basic( 0L );
+}
+
+/** InternalCF * InternalCF::bextgcdsame ( InternalCF *, CanonicalForm & a, CanonicalForm & b )
+ * @sa CanonicalForm::bextgcd()
+**/
+InternalCF *
+InternalCF::bextgcdsame ( InternalCF *, CanonicalForm & a, CanonicalForm & b )
+{
+    ASSERT1( 0, "bextgcd() not implemented for class %s", this->classname() );
+    a = 0; b = 0;
+    return CFFactory::basic( 0L );
+}
+
+InternalCF *
+InternalCF::bextgcdcoeff ( InternalCF *, CanonicalForm & a, CanonicalForm & b )
+{
+    ASSERT1( 0, "bextgcd() not implemented for class %s", this->classname() );
+    a = 0; b = 0;
+    return CFFactory::basic( 0L );
+}
+
+long
+InternalCF::intval() const
+{
+    ASSERT1( 0, "intval() not implemented for class %s", this->classname() );
+    return 0;
+}
+
+InternalCF*
+InternalCF::invert()
+{
+    ASSERT1( 0, "invert() not implemented for class %s", this->classname() );
+    return 0;
+}
+
+InternalCF*
+InternalCF::tryMulsame( InternalCF*, const CanonicalForm&)
+{
+    ASSERT1( 0, "tryMulsame() not implemented for class %s", this->classname() );
+    return 0;
+}
+
+InternalCF*
+InternalCF::tryInvert ( const CanonicalForm&, bool&)
+{
+    ASSERT1( 0, "tryInvert() not implemented for class %s", this->classname() );
+    return 0;
+}
+
+bool
+InternalCF::tryDivremsamet ( InternalCF*, InternalCF*&, InternalCF*&, const CanonicalForm&, bool&)
+{
+    ASSERT1( 0, "tryDivremsamet() not implemented for class %s", this->classname() );
+    return 0;
+}
+
+bool
+InternalCF::tryDivremcoefft ( InternalCF*, InternalCF*&, InternalCF*&, bool, const CanonicalForm&, bool&)
+{
+    ASSERT1( 0, "tryDivremcoefft() not implemented for class %s", this->classname() );
+    return 0;
+}
+
+InternalCF*
+InternalCF::tryDivsame ( InternalCF*, const CanonicalForm&, bool&)
+{
+    ASSERT1( 0, "tryDivsame() not implemented for class %s", this->classname() );
+    return 0;
+}
+
+InternalCF*
+InternalCF::tryDivcoeff ( InternalCF*, bool, const CanonicalForm&, bool&)
+{
+    ASSERT1( 0, "tryDivcoeff() not implemented for class %s", this->classname() );
+    return 0;
+}
+
+InternalCF*
+InternalCF::tryDividecoeff ( InternalCF*, bool, const CanonicalForm&, bool&)
+{
+    ASSERT1( 0, "tryDividecoeff() not implemented for class %s", this->classname() );
+    return 0;
+}
diff --git a/factory/int_cf.h b/factory/int_cf.h
new file mode 100644
index 0000000..8795103
--- /dev/null
+++ b/factory/int_cf.h
@@ -0,0 +1,126 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+/**
+ * @file int_cf.h
+ *
+ * Factory's internal CanonicalForm's
+**/
+#ifndef INCL_INT_CF_H
+#define INCL_INT_CF_H
+
+// #include "config.h"
+
+#ifndef NOSTREAMIO
+#ifdef HAVE_IOSTREAM
+#include <iostream>
+#define OSTREAM std::ostream
+#elif defined(HAVE_IOSTREAM_H)
+#include <iostream.h>
+#define OSTREAM ostream
+#endif
+#endif /* NOSTREAMIO */
+
+#include "cf_assert.h"
+
+#include "cf_defs.h"
+#include "variable.h"
+
+class CanonicalForm;
+
+/**
+ * virtual class for internal CanonicalForm's
+ *
+ * InternalCF will become an InternalPoly, InternalInteger, InternalRational
+**/
+class InternalCF {
+private:
+    int refCount;
+protected:
+    int getRefCount() { return refCount; };
+    void incRefCount() { refCount++; };
+    int decRefCount() { return --refCount; };
+public:
+    InternalCF() { refCount = 1; };
+    InternalCF( const InternalCF& )
+    {
+	ASSERT( 0, "ups there is something wrong in your code");
+    };
+    virtual ~InternalCF() {};
+    int deleteObject() { return decRefCount() == 0; }
+    InternalCF* copyObject() { incRefCount(); return this; }
+    virtual InternalCF* deepCopyObject() const PVIRT_INTCF("deepCopyObject");
+    virtual const char * classname() const PVIRT_CHARCC("classname");
+    virtual InternalCF* genZero() PVIRT_INTCF("genZero");
+    virtual InternalCF* genOne() PVIRT_INTCF("genOne");
+    virtual int level() const { return LEVELBASE; }
+    virtual int levelcoeff() const { return UndefinedDomain; }
+    virtual int type() const { return UndefinedDomain; }
+    virtual Variable variable() const { return Variable(); }
+#ifndef NOSTREAMIO
+    virtual void print( OSTREAM&, char* ) PVIRT_VOID("print");
+#endif /* NOSTREAMIO */
+    virtual bool inBaseDomain() const { return true; }
+    virtual bool inExtension() const { return false; }
+    virtual bool inCoeffDomain() const { return true; }
+    virtual bool inPolyDomain() const { return false; }
+    virtual bool inQuotDomain() const { return false; }
+    virtual bool isZero() const;
+    virtual bool isOne() const;
+    virtual bool isUnivariate() const { return false; }
+    virtual long intval() const;
+    virtual int intmod( int ) const { return 0; }
+    virtual int sign() const PVIRT_INT("sign");
+
+    virtual InternalCF* num();
+    virtual InternalCF* den();
+
+    virtual InternalCF* neg() PVIRT_INTCF("neg");
+    virtual InternalCF* invert(); // semantically const, changes refCount
+    virtual InternalCF* tryInvert( const CanonicalForm&, bool& );
+    virtual int comparesame ( InternalCF * ) PVIRT_INT("comparesame");
+    virtual int comparecoeff ( InternalCF * ) PVIRT_INT("comparecoeff");
+
+    virtual InternalCF* addsame( InternalCF* ) PVIRT_INTCF("addsame");
+    virtual InternalCF* subsame( InternalCF* ) PVIRT_INTCF("subsame");
+    virtual InternalCF* mulsame( InternalCF* ) PVIRT_INTCF("mulsame");
+    virtual InternalCF* tryMulsame( InternalCF*, const CanonicalForm& );
+    virtual InternalCF* dividesame( InternalCF* ) PVIRT_INTCF("dividesame");
+    virtual InternalCF* modulosame( InternalCF* ) PVIRT_INTCF("modulosame");
+    virtual InternalCF* divsame( InternalCF* ) PVIRT_INTCF("divsame");
+    virtual InternalCF* tryDivsame ( InternalCF* , const CanonicalForm&, bool& );
+    virtual InternalCF* modsame( InternalCF* ) PVIRT_INTCF("modsame");
+    virtual void divremsame( InternalCF*, InternalCF*&, InternalCF*& ) PVIRT_VOID("divremsame");
+    virtual bool divremsamet( InternalCF*, InternalCF*&, InternalCF*& ) PVIRT_BOOL("divremsamet");
+    virtual bool tryDivremsamet ( InternalCF*, InternalCF*&, InternalCF*&, const CanonicalForm&, bool& );
+
+    virtual InternalCF* addcoeff( InternalCF* ) PVIRT_INTCF("addcoeff");
+    virtual InternalCF* subcoeff( InternalCF*, bool ) PVIRT_INTCF("subcoeff");
+    virtual InternalCF* mulcoeff( InternalCF* ) PVIRT_INTCF("mulcoeff");
+    virtual InternalCF* dividecoeff( InternalCF*, bool ) PVIRT_INTCF("dividecoeff");
+    virtual InternalCF* tryDividecoeff ( InternalCF*, bool, const CanonicalForm&, bool& );
+    virtual InternalCF* modulocoeff( InternalCF*, bool ) PVIRT_INTCF("dividecoeff");
+    virtual InternalCF* divcoeff( InternalCF*, bool ) PVIRT_INTCF("divcoeff");
+    virtual InternalCF* tryDivcoeff ( InternalCF*, bool, const CanonicalForm&, bool& );
+    virtual InternalCF* modcoeff( InternalCF*, bool ) PVIRT_INTCF("modcoeff");
+    virtual void divremcoeff( InternalCF*, InternalCF*&, InternalCF*&, bool ) PVIRT_VOID("divremcoeff");
+    virtual bool divremcoefft( InternalCF*, InternalCF*&, InternalCF*&, bool ) PVIRT_BOOL("divremcoefft");
+    virtual bool tryDivremcoefft( InternalCF*, InternalCF*&, InternalCF*&, bool, const CanonicalForm&, bool& );
+
+    virtual InternalCF * bgcdsame ( const InternalCF * const ) const;
+    virtual InternalCF * bgcdcoeff ( const InternalCF * const ); // semantically const, changes refcount
+
+    virtual InternalCF * bextgcdsame ( InternalCF *, CanonicalForm &, CanonicalForm & ); // semantically const, changes refcount
+    virtual InternalCF * bextgcdcoeff ( InternalCF *, CanonicalForm &, CanonicalForm & ); // semantically const, changes refcount
+
+    virtual InternalCF* sqrt();
+    virtual int ilog2();
+    virtual CanonicalForm lc();
+    virtual CanonicalForm Lc();
+    virtual CanonicalForm LC();
+    virtual CanonicalForm coeff( int i );
+    virtual int degree();
+    virtual int taildegree();
+    virtual CanonicalForm tailcoeff();
+};
+
+#endif /* ! INCL_INT_CF_H */
diff --git a/factory/int_int.cc b/factory/int_int.cc
new file mode 100644
index 0000000..7e06d3d
--- /dev/null
+++ b/factory/int_int.cc
@@ -0,0 +1,580 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+
+#include "config.h"
+
+
+#include "canonicalform.h"
+#include "imm.h"
+#include "int_int.h"
+#include "int_rat.h"
+#include <factory/cf_gmp.h>
+#include "gmpext.h"
+
+#ifdef HAVE_OMALLOC
+const omBin InternalInteger::InternalInteger_bin = omGetSpecBin(sizeof(InternalInteger));
+#endif
+
+InternalInteger::InternalInteger()
+{
+    mpz_init( thempi );
+}
+
+InternalInteger::InternalInteger( const int i )
+{
+    mpz_init_set_si( thempi, i );
+}
+
+InternalInteger::InternalInteger( const long i )
+{
+    mpz_init_set_si( thempi, i );
+}
+
+InternalInteger::InternalInteger( const mpz_ptr mpi) { thempi[0]=*mpi;}
+
+InternalInteger::InternalInteger( const char * str, const int base )
+{
+    mpz_init_set_str( thempi, str, base );
+}
+
+InternalInteger::~InternalInteger()
+{
+    mpz_clear( thempi );
+}
+
+InternalCF* InternalInteger::deepCopyObject() const
+{
+    mpz_t dummy;
+    mpz_init_set( dummy, thempi );
+    return new InternalInteger( dummy );
+}
+
+#ifndef NOSTREAMIO
+void InternalInteger::print( OSTREAM & os, char * c )
+{
+    if ( *c == '*' && mpz_cmp_si( thempi, 1 ) == 0 )
+        os << c+1;
+    else if ( *c == '*' && mpz_cmp_si( thempi, -1 ) == 0 )
+        os << '-' << c+1;
+    else {
+        char * str = new char[mpz_sizeinbase( thempi, 10 ) + 2];
+        str = mpz_get_str( str, 10, thempi );
+        os << str << c;
+        delete [] str;
+    }
+}
+#endif /* NOSTREAMIO */
+
+bool InternalInteger::is_imm() const
+{
+    return mpz_is_imm( thempi );
+}
+
+InternalCF* InternalInteger::genZero()
+{
+    if ( isZero() )
+        return copyObject();
+    else
+        return new InternalInteger();
+}
+
+InternalCF* InternalInteger::genOne()
+{
+    if ( isOne() )
+        return copyObject();
+    else
+        return new InternalInteger( 1 );
+}
+
+/** InternalCF * InternalInteger::neg ()
+ * @sa CanonicalForm::operator -()
+**/
+InternalCF *
+InternalInteger::neg ()
+{
+    if ( getRefCount() > 1 )
+    {
+        decRefCount();
+        mpz_t dummy;
+        mpz_init_set( dummy, thempi );
+        mpz_neg( dummy, dummy );
+        return new InternalInteger( dummy );
+    }
+    else
+    {
+        mpz_neg( thempi, thempi );
+        return this;
+    }
+}
+
+
+
+InternalCF* InternalInteger::addsame( InternalCF * c )
+{
+    if ( getRefCount() > 1 )
+    {
+        decRefCount();
+        mpz_t dummy;
+        mpz_init( dummy );
+        mpz_add( dummy, thempi, MPI( c ) );
+        if ( mpz_is_imm( dummy ) )
+        {
+            InternalCF * res = int2imm( mpz_get_si( dummy ) );
+            mpz_clear( dummy );
+            return res;
+        }
+        else
+            return new InternalInteger( dummy );
+    }
+    else
+    {
+        mpz_add( thempi, thempi, MPI( c ) );
+        if ( mpz_is_imm( thempi ) )
+        {
+            InternalCF * res = int2imm( mpz_get_si( thempi ) );
+            delete this;
+            return res;
+        }
+        else
+            return this;
+    }
+}
+
+InternalCF* InternalInteger::subsame( InternalCF * c )
+{
+    if ( getRefCount() > 1 )
+    {
+        decRefCount();
+        mpz_t dummy;
+        mpz_init( dummy );
+        mpz_sub( dummy, thempi, MPI( c ) );
+        if ( mpz_is_imm( dummy ) )
+        {
+            InternalCF * res = int2imm( mpz_get_si( dummy ) );
+            mpz_clear( dummy );
+            return res;
+        }
+        else
+            return new InternalInteger( dummy );
+    }
+    else
+    {
+        mpz_sub( thempi, thempi, MPI( c ) );
+        if ( mpz_is_imm( thempi ) )
+        {
+            InternalCF * res = int2imm( mpz_get_si( thempi ) );
+            delete this;
+            return res;
+        }
+        else
+            return this;
+    }
+}
+
+InternalCF* InternalInteger::mulsame( InternalCF * c )
+{
+    if ( getRefCount() > 1 )
+    {
+        decRefCount();
+        mpz_t dummy;
+        mpz_init( dummy );
+        mpz_mul( dummy, thempi, MPI( c ) );
+        #if 0
+        if ( mpz_is_imm( dummy ) )
+        {
+        // can this happen ???
+            InternalCF * res = int2imm( mpz_get_si( dummy ) );
+            mpz_clear( dummy );
+            return res;
+        }
+        else
+        #endif
+            return new InternalInteger( dummy );
+    }
+    else
+    {
+        mpz_mul( thempi, thempi, MPI( c ) );
+        #if 0
+        if ( mpz_is_imm( &thempi ) )
+        {
+        // can this happen ???
+            InternalCF * res = int2imm( mpz_get_si( &thempi ) );
+            delete this;
+            return res;
+        }
+        else
+        #endif
+            return this;
+    }
+}
+
+/**
+ * @sa CanonicalForm::operator <(), CanonicalForm::operator ==(), InternalInteger::comparecoeff()
+**/
+int
+InternalInteger::comparesame ( InternalCF * c )
+{
+    ASSERT( ! ::is_imm( c ) && c->levelcoeff() == IntegerDomain, "incompatible base coefficients" );
+    return mpz_cmp( thempi, MPI( c ) );
+}
+
+/**
+ * @sa CanonicalForm::operator <(), CanonicalForm::operator ==(), InternalInteger::comparesame()
+**/
+int
+InternalInteger::comparecoeff ( InternalCF * c )
+{
+    ASSERT( ::is_imm( c ) == INTMARK, "incompatible base coefficients" );
+    return mpz_cmp_si( thempi, imm2int( c ) );
+}
+
+
+InternalCF* InternalInteger::addcoeff( InternalCF* c )
+{
+    ASSERT( ::is_imm( c ) == INTMARK, "incompatible base coefficients" );
+    long cc = imm2int( c );
+    if ( getRefCount() > 1 )
+    {
+        decRefCount();
+        mpz_t dummy;
+        mpz_init( dummy );
+        if ( cc < 0 )
+            mpz_sub_ui( dummy, thempi, -cc );
+        else
+            mpz_add_ui( dummy, thempi, cc );
+        if ( mpz_is_imm( dummy ) )
+        {
+            InternalCF * res = int2imm( mpz_get_si( dummy ) );
+            mpz_clear( dummy );
+            return res;
+        }
+        else
+            return new InternalInteger( dummy );
+    }
+    else
+    {
+        if ( cc < 0 )
+            mpz_sub_ui( thempi, thempi, -cc );
+        else
+            mpz_add_ui( thempi, thempi, cc );
+        if ( mpz_is_imm( thempi ) )
+        {
+            InternalCF * res = int2imm( mpz_get_si( thempi ) );
+            delete this;
+            return res;
+        }
+        else
+            return this;
+    }
+}
+
+InternalCF* InternalInteger::subcoeff( InternalCF* c, bool negate )
+{
+    ASSERT( ::is_imm( c ) == INTMARK, "incompatible base coefficients" );
+    long cc = imm2int( c );
+    if ( getRefCount() > 1 )
+    {
+        decRefCount();
+        mpz_t dummy;
+        if ( negate )
+        {
+            mpz_init_set_si( dummy, cc );
+            mpz_sub( dummy, dummy, thempi );
+        }
+        else
+        {
+            mpz_init( dummy );
+            if ( cc < 0 )
+                mpz_add_ui( dummy, thempi, -cc );
+            else
+                mpz_sub_ui( dummy, thempi, cc );
+        }
+        if ( mpz_is_imm( dummy ) )
+        {
+            InternalCF * res = int2imm( mpz_get_si( dummy ) );
+            mpz_clear( dummy );
+            return res;
+        }
+        else
+            return new InternalInteger( dummy );
+    }
+    else
+    {
+        if ( negate )
+        {
+            mpz_t dummy;
+            mpz_init_set_si( dummy, cc );
+            mpz_sub( thempi, dummy, thempi );
+            mpz_clear( dummy );
+        }
+        else
+            if ( cc < 0 )
+                mpz_add_ui( thempi, thempi, -cc );
+            else
+                mpz_sub_ui( thempi, thempi, cc );
+        if ( mpz_is_imm( thempi ) )
+        {
+            InternalCF * res = int2imm( mpz_get_si( thempi ) );
+            delete this;
+            return res;
+        }
+        else
+            return this;
+    }
+}
+
+InternalCF* InternalInteger::mulcoeff( InternalCF* c )
+{
+    ASSERT( ::is_imm( c ) == INTMARK, "incompatible base coefficients" );
+    long cc = imm2int( c );
+    if ( getRefCount() > 1 )
+    {
+        decRefCount();
+        mpz_t dummy;
+        mpz_init( dummy );
+        if ( cc < 0 )
+        {
+            mpz_mul_ui( dummy, thempi, -cc );
+            mpz_neg( dummy, dummy );
+        }
+        else
+            mpz_mul_ui( dummy, thempi, cc );
+        if ( mpz_is_imm( dummy ) )
+        {
+            InternalCF * res = int2imm( mpz_get_si( dummy ) );
+            mpz_clear( dummy );
+            return res;
+        }
+        else
+            return new InternalInteger( dummy );
+    }
+    else
+    {
+        if ( cc < 0 )
+        {
+            mpz_mul_ui( thempi, thempi, -cc );
+            mpz_neg( thempi, thempi );
+        }
+        else
+            mpz_mul_ui( thempi, thempi, cc );
+        if ( mpz_is_imm( thempi ) )
+        {
+            InternalCF * res = int2imm( mpz_get_si( thempi ) );
+            delete this;
+            return res;
+        }
+        else
+            return this;
+    }
+}
+
+/**
+ * @sa CanonicalForm::bgcd(), InternalInteger::bgcdcoeff()
+**/
+InternalCF *
+InternalInteger::bgcdsame ( const InternalCF * const c ) const
+{
+    ASSERT( ! ::is_imm( c ) && c->levelcoeff() == IntegerDomain, "incompatible base coefficients" );
+
+    // simply return 1 if we are calculating over the rationals
+    if ( cf_glob_switches.isOn( SW_RATIONAL ) )
+         return int2imm( 1 );
+
+    // calculate gcd
+    mpz_t result;
+    mpz_init( result );
+    mpz_gcd( result, thempi, MPI( c ) );
+    mpz_abs( result, result );
+
+    // check for immediate result
+    if ( mpz_is_imm( result ) )
+    {
+        InternalCF * res = int2imm( mpz_get_si( result ) );
+        mpz_clear( result );
+        return res;
+    }
+    else
+        return new InternalInteger( result );
+}
+
+/**
+ * @sa CanonicalForm::bgcd(), InternalInteger::bgcdsame()
+**/
+InternalCF *
+InternalInteger::bgcdcoeff ( const InternalCF * const c )
+{
+    ASSERT( ::is_imm( c ) == INTMARK, "incompatible base coefficients" );
+
+    // simply return 1 if we are calculating over the rationals
+    if ( cf_glob_switches.isOn( SW_RATIONAL ) )
+         return int2imm( 1 );
+
+    long cInt = imm2int( c );
+
+    // trivial cases
+    if ( cInt == 1 || cInt == -1 )
+        return int2imm( 1 );
+    else if ( cInt == 0 )
+        return copyObject();
+
+    // calculate gcd.  We need a positive operand since
+    // `mpz_gcd_ui()' operates an unsigned int's only.
+    if ( cInt < 0 ) cInt = -cInt;
+    mpz_t dummy;
+    mpz_init( dummy );
+    // we do not need dummy since we know that cInt != 0
+    cInt = mpz_gcd_ui( dummy, thempi, cInt );
+    mpz_clear( dummy );
+    if ( cInt < 0 ) cInt = -cInt;
+    return int2imm( cInt );
+}
+
+/**
+ * @sa CanonicalForm::bextgcd(), InternalInteger::bextgcdcoeff()
+**/
+InternalCF *
+InternalInteger::bextgcdsame( InternalCF * c, CanonicalForm & a, CanonicalForm & b )
+{
+    ASSERT( ! ::is_imm( c ) && c->levelcoeff() == IntegerDomain, "incompatible base coefficients" );
+
+    // simply return 1 if we are calculating over the rationals
+    if ( cf_glob_switches.isOn( SW_RATIONAL ) )
+    {
+        a = 1/CanonicalForm( copyObject() ); b = 0;
+        return int2imm( 1 );
+    }
+
+    // calculate extended gcd
+    mpz_t result, aMPI, bMPI;
+    mpz_init( result );
+    mpz_init( aMPI );
+    mpz_init( bMPI );
+    mpz_gcdext( result, aMPI, bMPI, thempi, MPI( c ) );
+
+    // check and modify signs
+    if ( mpz_sgn( result ) < 0 )
+    {
+        mpz_neg( result, result );
+        mpz_neg( aMPI, aMPI );
+        mpz_neg( bMPI, bMPI );
+    }
+
+    // postconditioning of result
+    if ( mpz_is_imm( aMPI ) )
+    {
+        a = CanonicalForm( int2imm( mpz_get_si( aMPI ) ) );
+        mpz_clear( aMPI );
+    }
+    else
+        a = CanonicalForm( new InternalInteger( aMPI ) );
+    if ( mpz_is_imm( bMPI ) )
+    {
+        b = CanonicalForm( int2imm( mpz_get_si( bMPI ) ) );
+        mpz_clear( bMPI );
+    }
+    else
+        b = CanonicalForm( new InternalInteger( bMPI ) );
+    if ( mpz_is_imm( result ) )
+    {
+        InternalCF * res = int2imm( mpz_get_si( result ) );
+        mpz_clear( result );
+        return res;
+    }
+    else
+        return new InternalInteger( result );
+}
+
+/**
+ * @sa CanonicalForm::bextgcd(), InternalInteger::bextgcdsame()
+**/
+InternalCF *
+InternalInteger::bextgcdcoeff( InternalCF * c, CanonicalForm & a, CanonicalForm & b )
+{
+    ASSERT( ::is_imm( c ) == INTMARK, "incompatible base coefficients" );
+
+    // simply return 1 if we are calculating over the rationals
+    if ( cf_glob_switches.isOn( SW_RATIONAL ) )
+    {
+        a = 1/CanonicalForm( copyObject() ); b = 0;
+        return int2imm( 1 );
+    }
+
+    long cInt = imm2int( c );
+
+    // trivial cases
+    if ( cInt == 1 || cInt == -1 )
+    {
+        a = 0; b = cInt;
+        return int2imm( 1 );
+    }
+    else if ( cInt == 0 )
+    {
+        a = 1; b = 0;
+        return copyObject();
+    }
+
+    // calculate q and r such that CO = q*cInt + r
+    InternalCF * q = 0, * r = 0;
+    divremcoeff( c, q, r, false );
+
+    // we do not repeat all the code to calculate the gcd of two
+    // immediates.  Note that r is an immediate since c != 0, so
+    // we do not have to destroy it.  q is destroyed by the
+    // CanonicalForm destructor, hence we do not need to worry
+    // about it, either.
+    CanonicalForm aPrime, bPrime;
+    CanonicalForm result = bextgcd( c, r, aPrime, bPrime );
+    a = bPrime;
+    b = aPrime - CanonicalForm( q ) * bPrime;
+
+    return result.getval();
+}
+
+long InternalInteger::intval() const
+{
+  return mpz_get_si( thempi );
+}
+
+int InternalInteger::intmod( int p ) const
+{
+  return (int)mpz_fdiv_ui( thempi, (unsigned long)p );
+}
+
+/** int InternalInteger::sign () const
+ * @sa CanonicalForm::sign()
+**/
+int
+InternalInteger::sign () const
+{
+    return mpz_sgn( thempi );
+}
+
+/** InternalCF * InternalInteger::sqrt ()
+ * @sa CanonicalForm::sqrt()
+**/
+InternalCF *
+InternalInteger::sqrt ()
+{
+    ASSERT( mpz_cmp_si( thempi, 0 ) >= 0, "sqrt() argument < 0" );
+    mpz_t result;
+    mpz_init( result );
+    mpz_sqrt( result, thempi );
+    if ( mpz_is_imm( result ) )
+    {
+        InternalCF * res = int2imm( mpz_get_si( result ) );
+        mpz_clear( result );
+        return res;
+    }
+    else
+        return new InternalInteger( result );
+}
+
+/** int InternalInteger::ilog2 ()
+ * @sa CanonicalForm::ilog2()
+**/
+int
+InternalInteger::ilog2 ()
+{
+    ASSERT( mpz_cmp_si( thempi, 0 ) > 0, "log() argument <= 0" );
+    return mpz_sizeinbase( thempi, 2 ) - 1;
+}
diff --git a/factory/int_int.h b/factory/int_int.h
new file mode 100644
index 0000000..a5d9f29
--- /dev/null
+++ b/factory/int_int.h
@@ -0,0 +1,240 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+#ifndef INCL_INT_INT_H
+#define INCL_INT_INT_H
+
+/**
+ * @file int_int.h
+ *
+ * Factory's internal integers
+**/
+
+// #include "config.h"
+
+#ifndef NOSTREAMIO
+#ifdef HAVE_IOSTREAM
+#include <iostream>
+#define OSTREAM std::ostream
+#elif defined(HAVE_IOSTREAM_H)
+#include <iostream.h>
+#define OSTREAM ostream
+#endif
+#endif /* NOSTREAMIO */
+
+#include "cf_assert.h"
+
+#include "int_cf.h"
+// #include <factory/cf_gmp.h>
+#include "gmpext.h"
+
+#ifdef HAVE_OMALLOC
+#ifndef OM_NDEBUG
+#define OM_NDEBUG
+#endif
+#  include <omalloc/omalloc.h>
+#endif
+
+/**
+ * factory's class for integers
+ *
+ * an integer is represented as an mpz_t thempi
+ *
+ * @sa InternalRational
+**/
+class InternalInteger : public InternalCF
+{
+private:
+    mpz_t thempi;
+
+    // auxilliary methods
+    inline InternalCF * normalizeMyself ();
+    inline InternalCF * uiNormalizeMyself ();
+
+    static inline InternalCF * normalizeMPI ( mpz_ptr );
+    static inline InternalCF * uiNormalizeMPI ( mpz_ptr );
+
+    static inline mpz_ptr MPI ( const InternalCF * const c );
+#ifdef HAVE_OMALLOC
+  static const omBin InternalInteger_bin;
+#endif
+public:
+#ifdef HAVE_OMALLOC
+  void* operator new(size_t)
+    {
+      void* addr;
+      omTypeAllocBin(void*, addr, InternalInteger_bin);
+      return addr;
+    }
+  void operator delete(void* addr, size_t)
+    {
+      omFreeBin(addr, InternalInteger_bin);
+    }
+#endif
+
+    InternalInteger();
+    InternalInteger( const InternalCF& )
+    {
+        ASSERT( 0, "ups there is something wrong in your code" );
+    }
+    InternalInteger( const int i );
+    InternalInteger( const long i );
+    InternalInteger( const char * str, const int base=10 );
+    InternalInteger( const mpz_ptr );
+    ~InternalInteger();
+    InternalCF* deepCopyObject() const;
+    const char * classname() const { return "InternalInteger"; }
+#ifndef NOSTREAMIO
+    void print( OSTREAM&, char* );
+#endif /* NOSTREAMIO */
+    InternalCF* genZero();
+    InternalCF* genOne();
+
+    bool is_imm() const;
+
+    int levelcoeff() const { return IntegerDomain; }
+    InternalCF* neg();
+
+    int comparesame( InternalCF* );
+
+    InternalCF* addsame( InternalCF* );
+    InternalCF* subsame( InternalCF* );
+    InternalCF* mulsame( InternalCF* );
+    InternalCF* dividesame( InternalCF* );
+    InternalCF* modulosame( InternalCF* );
+    InternalCF* divsame( InternalCF* );
+    InternalCF* modsame( InternalCF* );
+    void divremsame( InternalCF*, InternalCF*&, InternalCF*& );
+    bool divremsamet( InternalCF*, InternalCF*&, InternalCF*& );
+
+    int comparecoeff( InternalCF* );
+
+    InternalCF* addcoeff( InternalCF* );
+    InternalCF* subcoeff( InternalCF*, bool );
+    InternalCF* mulcoeff( InternalCF* );
+    InternalCF* dividecoeff( InternalCF*, bool );
+    InternalCF* modulocoeff( InternalCF*, bool );
+    InternalCF* divcoeff( InternalCF*, bool );
+    InternalCF* modcoeff( InternalCF*, bool );
+    void divremcoeff( InternalCF*, InternalCF*&, InternalCF*&, bool );
+    bool divremcoefft( InternalCF*, InternalCF*&, InternalCF*&, bool );
+
+    InternalCF * bgcdsame ( const InternalCF * const ) const;
+    InternalCF * bgcdcoeff ( const InternalCF * const );
+
+    InternalCF * bextgcdsame ( InternalCF *, CanonicalForm &, CanonicalForm & );
+    InternalCF * bextgcdcoeff ( InternalCF *, CanonicalForm &, CanonicalForm & );
+
+    long intval() const;
+
+    int intmod( int p ) const;
+
+    int sign() const;
+
+    InternalCF* sqrt();
+
+    int ilog2();
+
+    friend class InternalRational;
+    friend void gmp_numerator ( const CanonicalForm & f, mpz_ptr result);
+    friend void gmp_denominator ( const CanonicalForm & f, mpz_ptr result );
+    friend void getmpi ( InternalCF * value, mpz_t mpi);
+};
+
+/**
+ *
+ * normalizeMyself(), uiNormalizeMyself() - normalize CO.
+ *
+ * If CO fits into an immediate integer, delete CO and return the
+ * immediate.  Otherwise, return a pointer to CO.
+ *
+ * Note: We do not mind reference counting at this point!  CO is
+ * deleted unconditionally!
+ *
+**/
+inline InternalCF *
+InternalInteger::normalizeMyself ()
+{
+    ASSERT( getRefCount() == 1, "internal error: must not delete CO" );
+
+    if ( mpz_is_imm( thempi ) ) {
+        InternalCF * result = int2imm( mpz_get_si( thempi ) );
+        delete this;
+        return result;
+    } else
+        return this;
+}
+
+/**
+ * `uiNormalizeMyself()' is the same as `normalizeMyself()'
+ * except that CO is expected to be non-negative.  In this case,
+ * we may use `mpz_get_ui()' to convert the underlying mpi into
+ * an immediate which is slightly faster than the signed variant.
+ *
+ * Note: We do not mind reference counting at this point!  CO is
+ * deleted unconditionally!
+**/
+inline InternalCF *
+InternalInteger::uiNormalizeMyself ()
+{
+    ASSERT( getRefCount() == 1, "internal error: must not delete CO" );
+
+    if ( mpz_is_imm( thempi ) ) {
+        InternalCF * result = int2imm( mpz_get_ui( thempi ) );
+        delete this;
+        return result;
+    } else
+        return this;
+}
+
+/**
+ *
+ * normalizeMPI(), uiNormalizeMPI() - normalize a mpi.
+ *
+ * If `aMpi' fits into an immediate integer, clear `aMpi' and
+ * return the immediate.  Otherwise, return a new
+ * `InternalInteger' with `aMpi' as underlying mpi.
+ *
+**/
+inline InternalCF *
+InternalInteger::normalizeMPI ( mpz_ptr aMpi )
+{
+    if ( mpz_is_imm( aMpi ) ) {
+        InternalCF * result = int2imm( mpz_get_si( aMpi ) );
+        mpz_clear( aMpi );
+        return result;
+    } else
+        return new InternalInteger( aMpi );
+}
+
+/**
+ * `uiNormalizeMPI()' is the same as `normalizeMPI()' except that
+ * `aMpi' is expected to be non-begative.  In this case, we may
+ * use `mpz_get_ui()' to convert `aMpi' into an immediate which
+ * is slightly faster than the signed variant.
+**/
+inline InternalCF *
+InternalInteger::uiNormalizeMPI ( mpz_ptr aMpi )
+{
+    if ( mpz_is_imm( aMpi ) ) {
+        InternalCF * result = int2imm( mpz_get_ui( aMpi ) );
+        mpz_clear( aMpi );
+        return result;
+    } else
+        return new InternalInteger( aMpi );
+}
+
+/**
+ *
+ * MPI() - return underlying mpz_t of `c'.
+ *
+ * `c' is expected to be an `InternalInteger *'.  `c's underlying
+ * mpz_t is returned.
+ *
+**/
+inline mpz_ptr
+InternalInteger::MPI ( const InternalCF * const c )
+{
+    return (((InternalInteger*)c)->thempi);
+}
+
+#endif /* ! INCL_INT_INT_H */
diff --git a/factory/int_intdiv.cc b/factory/int_intdiv.cc
new file mode 100644
index 0000000..65df990
--- /dev/null
+++ b/factory/int_intdiv.cc
@@ -0,0 +1,378 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+/**
+ *
+ * @file int_intdiv.cc
+ *
+ * 'InternalInteger' division algorithms.
+ *
+**/
+
+
+#include "config.h"
+
+
+#include "canonicalform.h"
+#include "imm.h"
+#include "int_cf.h"
+#include "int_int.h"
+#include "int_rat.h"
+#include <factory/cf_gmp.h>
+#include "gmpext.h"
+#include "templates/ftmpl_functions.h"
+
+/**
+ * @sa CanonicalForm::operator /(), InternalInteger::dividecoeff()
+**/
+InternalCF *
+InternalInteger::dividesame ( InternalCF * c )
+{
+    ASSERT( ! ::is_imm( c ) && c->levelcoeff() == IntegerDomain,
+            "type error: InternalInteger expected" );
+
+    if ( c == this ) {
+        if ( deleteObject() ) delete this;
+        return int2imm( 1 );
+    }
+
+    if ( cf_glob_switches.isOn( SW_RATIONAL ) ) {
+        mpz_t n, d;
+        mpz_init_set( n, thempi );
+        mpz_init_set( d, MPI( c ) );
+        if ( deleteObject() ) delete this;
+        InternalRational * result = new InternalRational( n, d );
+        return result->normalize_myself();
+    }
+
+    if ( getRefCount() > 1 ) {
+        decRefCount();
+        mpz_t mpiResult;
+        mpz_init( mpiResult );
+        if ( mpz_sgn( MPI( c ) ) > 0 )
+            mpz_fdiv_q( mpiResult, thempi, MPI( c ) );
+        else
+            mpz_cdiv_q( mpiResult, thempi, MPI( c ) );
+        return normalizeMPI( mpiResult );
+    } else {
+        if ( mpz_sgn( MPI( c ) ) > 0 )
+            mpz_fdiv_q( thempi, thempi, MPI( c ) );
+        else
+            mpz_cdiv_q( thempi, thempi, MPI( c ) );
+        return normalizeMyself();
+    }
+}
+
+/**
+ * @sa CanonicalForm::operator /(), InternalInteger::dividesame()
+**/
+InternalCF *
+InternalInteger::dividecoeff ( InternalCF * c, bool invert )
+{
+    ASSERT( ::is_imm( c ) == INTMARK,
+            "type error: immediate integer expected" );
+    ASSERT( invert || imm2int( c ) != 0,
+            "math error: divide by zero" );
+
+    long intC = imm2int( c );
+
+    if ( cf_glob_switches.isOn( SW_RATIONAL ) ) {
+        mpz_t n, d;
+        if ( invert ) {
+            mpz_init_set_si( n, intC );
+            mpz_init_set( d, thempi );
+        } else {
+            mpz_init_set( n, thempi );
+            mpz_init_set_si( d, intC );
+        }
+        if ( deleteObject() ) delete this;
+        InternalRational * result = new InternalRational( n, d );
+        return result->normalize_myself();
+    }
+
+    if ( invert ) {
+        int mpiSign = mpz_sgn( thempi );
+        if ( deleteObject() ) delete this;
+        if ( intC >= 0 )
+            return int2imm( 0 );
+        else
+            return int2imm( -mpiSign );
+    } else if ( getRefCount() > 1 ) {
+        decRefCount();
+        mpz_t mpiResult;
+        mpz_init( mpiResult );
+        if ( intC > 0 )
+            mpz_fdiv_q_ui( mpiResult, thempi, intC );
+        else {
+            mpz_fdiv_q_ui( mpiResult, thempi, -intC );
+            mpz_neg( mpiResult, mpiResult );
+        }
+        return normalizeMPI( mpiResult );
+    } else {
+        if ( intC > 0 )
+            mpz_fdiv_q_ui( thempi, thempi, intC );
+        else {
+            mpz_fdiv_q_ui( thempi, thempi, -intC );
+            mpz_neg( thempi, thempi );
+        }
+        return normalizeMyself();
+    }
+}
+
+/**
+ * @sa CanonicalForm::div(), InternalInteger::divcoeff()
+**/
+InternalCF *
+InternalInteger::divsame ( InternalCF * c )
+{
+    ASSERT( ! ::is_imm( c ) && c->levelcoeff() == IntegerDomain,
+            "type error: InternalInteger expected" );
+
+    if ( c == this ) {
+        if ( deleteObject() ) delete this;
+        return int2imm( 1 );
+    }
+
+    if ( getRefCount() > 1 ) {
+        deleteObject();
+        mpz_t mpiResult;
+        mpz_init( mpiResult );
+        mpz_divexact( mpiResult, thempi, MPI( c ) );
+        return normalizeMPI( mpiResult );
+    } else {
+        mpz_divexact( thempi, thempi, MPI( c ) );
+        return normalizeMyself();
+    }
+}
+
+/**
+ * @sa CanonicalForm::div(), InternalInteger::divsame()
+**/
+InternalCF *
+InternalInteger::divcoeff ( InternalCF * c, bool invert )
+{
+    ASSERT( ::is_imm( c ) == INTMARK,
+            "type error: immediate integer expected" );
+    ASSERT( invert || imm2int( c ) != 0,
+            "math error: divide by zero" );
+    ASSERT( ! invert || imm2int( c ) == 0,
+            "math error: c does not divide CO" );
+
+    if ( invert ) {
+        if ( deleteObject() ) delete this;
+        // this may happen iff `c' == 0
+        return int2imm( 0 );
+    } else if ( getRefCount() > 1 ) {
+        deleteObject();
+        mpz_t mpiC;
+        mpz_t mpiResult;
+        mpz_init_set_si( mpiC, imm2int( c ) );
+        mpz_init( mpiResult );
+        mpz_divexact( mpiResult, thempi, mpiC );
+        mpz_clear( mpiC );
+        return normalizeMPI( mpiResult );
+    } else {
+        mpz_t mpiC;
+        mpz_init_set_si( mpiC, imm2int( c ) );
+        mpz_divexact( thempi, thempi, mpiC );
+        mpz_clear( mpiC );
+        return normalizeMyself();
+    }
+}
+
+/**
+ * @sa CanonicalForm::operator %(), InternalInteger::modulocoeff()
+**/
+InternalCF *
+InternalInteger::modulosame ( InternalCF * c )
+{
+    ASSERT( ! ::is_imm( c ) && c->levelcoeff() == IntegerDomain,
+            "type error: InternalInteger expected" );
+
+    if ( (c == this) || cf_glob_switches.isOn( SW_RATIONAL ) ) {
+        if ( deleteObject() ) delete this;
+        return int2imm( 0 );
+    }
+
+    if ( getRefCount() > 1 ) {
+        decRefCount();
+        mpz_t mpiResult;
+        mpz_init( mpiResult );
+        mpz_mod( mpiResult, thempi, MPI( c ) );
+        return uiNormalizeMPI( mpiResult );
+    } else {
+        mpz_mod( thempi, thempi, MPI( c ) );
+        return uiNormalizeMyself();
+    }
+}
+
+/**
+ * @sa CanonicalForm::operator %(), InternalInteger::modulosame()
+**/
+InternalCF *
+InternalInteger::modulocoeff ( InternalCF * c, bool invert )
+{
+    ASSERT( ::is_imm( c ) == INTMARK,
+            "type error: immediate integer expected" );
+    ASSERT( invert || imm2int( c ) != 0,
+            "math error: divide by zero" );
+
+    if ( cf_glob_switches.isOn( SW_RATIONAL ) ) {
+        if ( deleteObject() ) delete this;
+        return int2imm( 0 );
+    }
+
+    long intC = imm2int( c );
+
+    if ( invert ) {
+        if ( intC >= 0 ) {
+            if ( deleteObject() ) delete this;
+            return c;
+        } else {
+            // no checks for refCount == 1 are done.  It is not worth ...
+            mpz_t mpiResult;
+            mpz_init_set( mpiResult, thempi );
+            mpz_abs( mpiResult, mpiResult );
+            mpz_sub_ui( mpiResult, mpiResult, -intC );
+            if ( deleteObject() ) delete this;
+            return uiNormalizeMPI( mpiResult );
+        }
+    } else {
+        mpz_t dummy;
+        mpz_init( dummy );
+        InternalCF * result = int2imm( mpz_mod_ui( dummy, thempi, tabs( intC ) ) );
+        mpz_clear( dummy );
+        if ( deleteObject() ) delete this;
+        return result;
+    }
+}
+
+/**
+ * @sa see CanonicalForm::mod(), InternalInteger::modcoeff()
+**/
+InternalCF *
+InternalInteger::modsame ( InternalCF * c )
+{
+    return modulosame( c );
+}
+
+/**
+ * @sa see CanonicalForm::mod(), InternalInteger::modsame()
+**/
+InternalCF *
+InternalInteger::modcoeff ( InternalCF * c, bool invert )
+{
+    return modulocoeff( c, invert );
+}
+
+/**
+ * @sa CanonicalForm::divrem(), InternalInteger::divremcoeff()
+**/
+void
+InternalInteger::divremsame ( InternalCF * c, InternalCF * & quot, InternalCF * & rem )
+{
+    ASSERT( ! ::is_imm( c ) && c->levelcoeff() == IntegerDomain,
+            "type error: InternalInteger expected" );
+
+    if ( c == this ) {
+        quot = int2imm( 1 );
+        rem = int2imm( 0 );
+        return;
+    }
+
+    if ( cf_glob_switches.isOn( SW_RATIONAL ) ) {
+        mpz_t n, d;
+        mpz_init_set( n, thempi );
+        mpz_init_set( d, MPI( c ) );
+        InternalRational * result = new InternalRational( n, d );
+        quot = result->normalize_myself();
+        rem = int2imm( 0 );
+        return;
+    }
+
+    mpz_t q;
+    mpz_t r;
+    mpz_init( q ); mpz_init( r );
+    if ( mpz_sgn( MPI( c ) ) > 0 )
+        mpz_fdiv_qr( q, r, thempi, MPI( c ) );
+    else
+        mpz_cdiv_qr( q, r, thempi, MPI( c ) );
+
+    quot = normalizeMPI( q );
+    rem = uiNormalizeMPI( r );
+}
+
+/**
+ * @sa CanonicalForm::divrem(), InternalInteger::divremsame()
+**/
+void
+InternalInteger::divremcoeff ( InternalCF * c, InternalCF * & quot, InternalCF * & rem, bool invert )
+{
+    ASSERT( ::is_imm( c ) == INTMARK,
+            "type error: immediate integer expected" );
+    ASSERT( invert || imm2int( c ) != 0,
+            "math error: divide by zero" );
+
+    long intC = imm2int( c );
+
+    if ( cf_glob_switches.isOn( SW_RATIONAL ) ) {
+        mpz_t n, d;
+        if ( invert ) {
+            mpz_init_set_si( n, intC );
+            mpz_init_set( d, thempi );
+        } else {
+            mpz_init_set( n, thempi );
+            mpz_init_set_si( d, intC );
+        }
+        InternalRational * result = new InternalRational( n, d );
+        quot = result->normalize_myself();
+        rem = int2imm( 0 );
+        return;
+    }
+
+    if ( invert ) {
+        if ( intC >= 0 ) {
+            rem = c;
+            quot = int2imm( 0 );
+        } else {
+            mpz_t mpiResult;
+            mpz_init_set( mpiResult, thempi );
+            mpz_abs( mpiResult, mpiResult );
+            mpz_sub_ui( mpiResult, mpiResult, -intC );
+            rem = uiNormalizeMPI( mpiResult );
+            quot = int2imm( -mpz_sgn( thempi ) );
+        }
+    } else {
+        mpz_t q;
+        mpz_t dummy;
+        mpz_init( q ); mpz_init( dummy );
+        if ( intC > 0 ) {
+            rem = int2imm( mpz_fdiv_qr_ui( q, dummy, thempi, intC ) );
+            quot = normalizeMPI( q );
+        } else {
+            rem = int2imm( mpz_fdiv_qr_ui( q, dummy, thempi, -intC ) );
+            mpz_neg( q, q );
+            quot = normalizeMPI( q );
+        }
+        mpz_clear( dummy );
+    }
+}
+
+/**
+ * @sa CanonicalForm::divremt(), InternalInteger::divremcoefft()
+**/
+bool
+InternalInteger::divremsamet ( InternalCF * c, InternalCF * & quot, InternalCF * & rem )
+{
+    divremsame( c, quot, rem );
+    return true;
+}
+
+/**
+ * @sa CanonicalForm::divremt(), InternalInteger::divremsamet()
+**/
+bool
+InternalInteger::divremcoefft ( InternalCF * c, InternalCF * & quot, InternalCF * & rem, bool invert )
+{
+    divremcoeff( c, quot, rem, invert );
+    return true;
+}
diff --git a/factory/int_poly.cc b/factory/int_poly.cc
new file mode 100644
index 0000000..ef89395
--- /dev/null
+++ b/factory/int_poly.cc
@@ -0,0 +1,2253 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+
+#include "config.h"
+
+
+#ifndef NOSTREAMIO
+#include <string.h>
+#if defined(WINNT) && ! defined(__GNUC__)
+#include <strstrea.h>
+#else
+#if __GNUC__ < 3
+#include <strstream.h>
+#else
+#include <strstream>
+using namespace std;
+#endif
+#endif
+#endif /* NOSTREAMIO */
+
+#include "cf_assert.h"
+
+#include "cf_defs.h"
+#include "cf_factory.h"
+#include "cfUnivarGcd.h"
+#include "int_cf.h"
+#include "int_int.h"
+#include "int_poly.h"
+#include "canonicalform.h"
+#include "variable.h"
+#include "imm.h"
+
+#ifdef HAVE_OMALLOC
+const omBin term::term_bin = omGetSpecBin(sizeof(term));
+const omBin InternalPoly::InternalPoly_bin = omGetSpecBin(sizeof(InternalPoly));
+#endif
+
+InternalPoly::InternalPoly( termList first, termList last, const Variable & v )
+{
+    firstTerm = first;
+    lastTerm = last;
+    var = v;
+}
+
+InternalPoly::InternalPoly()
+{
+    ASSERT( 0, "ups, why do you initialize an empty poly" );
+}
+
+InternalPoly::InternalPoly( const Variable & v, const int e, const CanonicalForm& c )
+{
+    var = v;
+    firstTerm = new term( 0, c, e );
+    lastTerm = firstTerm;
+}
+
+InternalPoly::InternalPoly( const InternalPoly& ):InternalCF()
+{
+    ASSERT( 0, "ups there is something wrong in your code" );
+}
+
+InternalPoly::~InternalPoly()
+{
+    freeTermList( firstTerm );
+}
+
+InternalCF*
+InternalPoly::deepCopyObject() const
+{
+    termList first, last;
+    first = deepCopyTermList( firstTerm, last );
+    return new InternalPoly( first, last, var );
+}
+
+InternalCF*
+InternalPoly::genZero()
+{
+    return firstTerm->coeff.genZero().getval();
+}
+
+InternalCF*
+InternalPoly::genOne()
+{
+    return firstTerm->coeff.genOne().getval();
+}
+
+bool
+InternalPoly::isUnivariate() const
+{
+    termList cursor = firstTerm;
+    while ( cursor )
+    {
+        if ( ! cursor->coeff.inCoeffDomain() )
+            return false;
+        cursor = cursor->next;
+    }
+    return true;
+}
+
+/** int InternalPoly::degree ()
+ * @sa CanonicalForm::sign ()
+**/
+int
+InternalPoly::degree ()
+{
+    return firstTerm->exp;
+}
+
+
+/** int InternalPoly::sign () const
+ * @sa CanonicalForm::sign()
+**/
+int
+InternalPoly::sign () const
+{
+    return firstTerm->coeff.sign();
+}
+
+
+/**
+  * @sa CanonicalForm::lc(), CanonicalForm::Lc(), CanonicalForm::LC(), InternalPoly::Lc (), InternalPoly::LC ()
+**/
+CanonicalForm
+InternalPoly::lc ()
+{
+    return firstTerm->coeff.lc();
+}
+
+/**
+  * @sa CanonicalForm::lc(), CanonicalForm::Lc(), CanonicalForm::LC(), InternalPoly::lc (), InternalPoly::LC ()
+**/
+CanonicalForm
+InternalPoly::Lc ()
+{
+    return firstTerm->coeff.Lc();
+}
+
+/**
+  * @sa CanonicalForm::lc(), CanonicalForm::Lc(), CanonicalForm::LC(), InternalPoly::lc (), InternalPoly::Lc ()
+**/
+CanonicalForm
+InternalPoly::LC ()
+{
+    return firstTerm->coeff;
+}
+
+/** CanonicalForm InternalPoly::tailcoeff (), int InternalPoly::taildegree ()
+ * @sa CanonicalForm::tailcoeff(), taildegree()
+**/
+CanonicalForm
+InternalPoly::tailcoeff ()
+{
+    return lastTerm->coeff;
+}
+
+int
+InternalPoly::taildegree ()
+{
+    return lastTerm->exp;
+}
+
+/** CanonicalForm InternalPoly::coeff ( int i )
+ * @sa CanonicalForm::operator []()
+**/
+CanonicalForm
+InternalPoly::coeff ( int i )
+{
+    termList theCursor = firstTerm;
+    while ( theCursor )
+    {
+        if ( theCursor->exp == i )
+            return theCursor->coeff;
+        else if ( theCursor->exp < i )
+            return CanonicalForm( 0 );
+        else
+            theCursor = theCursor->next;
+    }
+    return CanonicalForm( 0 );
+}
+
+#ifndef NOSTREAMIO
+void
+InternalPoly::print(OSTREAM &aStream, char * aString )
+{
+    if ( ! firstTerm )
+        aStream << 0 << aString;
+    else
+    {
+        char * theString;
+        termList theCursor = firstTerm;
+        while ( theCursor )
+        {
+            ostrstream theStream;
+            if ( theCursor->exp == 0 )
+                theCursor->coeff.print( aStream, aString );
+            else  if ( theCursor->coeff.isOne() )
+            {
+                aStream << var;
+                if ( theCursor->exp != 1 )
+                    aStream << '^' << theCursor->exp << aString;
+                else
+                    aStream << aString;
+            }
+            else  if ( theCursor->coeff.sign() < 0 && (-theCursor->coeff).isOne() )
+            {
+                aStream << '-' << var;
+                if ( theCursor->exp != 1 )
+                    aStream << '^' << theCursor->exp << aString;
+                else
+                    aStream << aString;
+            }
+            else
+            {
+                theStream << '*' << var;
+                if ( theCursor->exp != 1 )
+                    theStream << '^' << theCursor->exp << aString << ends;
+                else
+                    theStream << aString << ends; // results from error in GNU strstream
+                theString = theStream.str();
+                theCursor->coeff.print( aStream, theString );
+                theStream.freeze(0);//delete [] theString;
+            }
+            theCursor = theCursor->next;
+            if ( theCursor && ( theCursor->coeff.sign() >= 0 ) )
+                aStream << '+';
+        }
+    }
+}
+#endif /* NOSTREAMIO */
+
+/** InternalCF * InternalPoly::neg ()
+ * @sa CanonicalForm::operator -()
+**/
+InternalCF *
+InternalPoly::neg ()
+{
+    if ( getRefCount() <= 1 )
+    {
+        negateTermList( firstTerm );
+        return this;
+    }
+    else
+    {
+        decRefCount();
+        termList last, first = copyTermList( firstTerm, last, true );
+        return new InternalPoly( first, last, var );
+    }
+}
+
+InternalCF*
+InternalPoly::invert()
+{
+    if ( inExtension() && getReduce( var ) )
+    {
+        setReduce( var, false );
+        CanonicalForm a( this->copyObject() );
+        CanonicalForm b = getMipo( var );
+        CanonicalForm u, v;
+        CanonicalForm g = extgcd( a, b, u, v );
+        setReduce( var, true );
+        return u.getval();
+    }
+    else
+        return CFFactory::basic( 0L );
+}
+
+InternalCF*
+InternalPoly::tryInvert ( const CanonicalForm& M, bool& fail)
+{
+  if ( inExtension() && !getReduce ( var ) )
+  {
+    CanonicalForm b, inverse;
+    CanonicalForm F ( this ->copyObject() );
+    Variable a = M.mvar();
+    Variable x = Variable(1);
+    F= mod (F, M); //reduce mod M
+    CanonicalForm g= extgcd (replacevar( F, a, x ), replacevar( M, a, x ), inverse, b );
+    if(!g.isOne())
+      fail = true;
+    else
+      inverse = replacevar( inverse, x, a ); // change back to alg var
+    CanonicalForm test= mod (inverse*F, M);
+    return inverse.getval();
+  }
+  else
+    return CFFactory::basic( 0L );
+}
+
+InternalCF*
+InternalPoly::addsame( InternalCF* aCoeff )
+{
+    InternalPoly * aPoly = (InternalPoly*)aCoeff;
+    if ( getRefCount() <= 1 )
+    {
+        firstTerm = addTermList( firstTerm, aPoly->firstTerm, lastTerm, false );
+        if ( firstTerm && firstTerm->exp != 0 )
+            return this;
+        else  if ( firstTerm )
+        {
+            InternalCF * res = firstTerm->coeff.getval();
+            delete this;
+            return res;
+        }
+        else
+        {
+            delete this;
+            return CFFactory::basic( 0L );
+        }
+    }
+    else
+    {
+        decRefCount();
+        termList last, first = copyTermList( firstTerm, last );
+        first = addTermList( first, aPoly->firstTerm, last, false );
+        if ( first && first->exp != 0 )
+            return new InternalPoly( first, last, var );
+        else  if ( first )
+        {
+            InternalCF * res = first->coeff.getval();
+            delete first;
+            return res;
+        }
+        else
+            return CFFactory::basic( 0L );
+
+    }
+}
+
+InternalCF*
+InternalPoly::subsame( InternalCF* aCoeff )
+{
+    InternalPoly * aPoly = (InternalPoly*)aCoeff;
+    if ( getRefCount() <= 1 )
+    {
+        firstTerm = addTermList( firstTerm, aPoly->firstTerm, lastTerm, true );
+        if ( firstTerm && firstTerm->exp != 0 )
+            return this;
+        else  if ( firstTerm )
+        {
+            InternalCF * res = firstTerm->coeff.getval();
+            delete this;
+            return res;
+        }
+        else
+        {
+            delete this;
+            return CFFactory::basic( 0L );
+        }
+    }
+    else
+    {
+        decRefCount();
+        termList last, first = copyTermList( firstTerm, last );
+        first = addTermList( first, aPoly->firstTerm, last, true );
+        if ( first && first->exp != 0 )
+            return new InternalPoly( first, last, var );
+        else  if ( first )
+        {
+            InternalCF * res = first->coeff.getval();
+            delete first;
+            return res;
+        }
+        else
+            return CFFactory::basic( 0L );
+
+    }
+}
+
+InternalCF*
+InternalPoly::mulsame( InternalCF* aCoeff )
+{
+    if (is_imm(aCoeff)) return mulcoeff(aCoeff);
+    InternalPoly *aPoly = (InternalPoly*)aCoeff;
+    termList resultFirst = 0, resultLast = 0;
+    termList theCursor = firstTerm;
+
+    while ( theCursor )
+    {
+        resultFirst = mulAddTermList( resultFirst, aPoly->firstTerm,
+                          theCursor->coeff, theCursor->exp, resultLast, false );
+        theCursor = theCursor->next;
+    }
+    if ( inExtension() && getReduce( var ) )
+    {
+        resultFirst = reduceTermList( resultFirst, (getInternalMipo( var ))->firstTerm, resultLast );
+        if ( resultFirst == 0 )
+        {
+            if ( getRefCount() <= 1 )
+            {
+                delete this;
+                return CFFactory::basic(0L);
+            }
+            else
+            {
+                decRefCount();
+                return CFFactory::basic(0L);
+            }
+        }
+        else  if ( resultFirst->exp == 0 )
+        {
+            if ( getRefCount() <= 1 )
+            {
+                InternalCF * res = resultFirst->coeff.getval();
+                delete resultFirst;
+                delete this;
+                return res;
+            }
+            else
+            {
+                decRefCount();
+                InternalCF * res = resultFirst->coeff.getval();
+                delete resultFirst;
+                return res;
+            }
+        }
+    }
+    if ( getRefCount() <= 1 )
+    {
+        freeTermList( firstTerm );
+        firstTerm = resultFirst;
+        lastTerm = resultLast;
+        return this;
+    }
+    else
+    {
+        decRefCount();
+        return new InternalPoly( resultFirst, resultLast, var );
+    }
+}
+
+InternalCF*
+InternalPoly::tryMulsame( InternalCF* aCoeff, const CanonicalForm& M)
+{
+    if (is_imm(aCoeff))
+       return mulcoeff(aCoeff);
+    InternalPoly *aPoly = (InternalPoly*)aCoeff;
+    termList resultFirst = 0, resultLast = 0;
+    termList theCursor = firstTerm;
+
+    while ( theCursor )
+    {
+        resultFirst = mulAddTermList( resultFirst, aPoly->firstTerm,
+                          theCursor->coeff, theCursor->exp, resultLast, false );
+        theCursor = theCursor->next;
+    }
+    if ( inExtension() && !getReduce( var ) )
+    {
+        resultFirst= reduceTermList (resultFirst, ((InternalPoly*) M.getval())->firstTerm, resultLast);
+        if ( resultFirst == 0 )
+        {
+            if ( getRefCount() <= 1 )
+            {
+                delete this;
+                return CFFactory::basic(0L);
+            }
+            else
+            {
+                decRefCount();
+                return CFFactory::basic(0L);
+            }
+        }
+        else  if ( resultFirst->exp == 0 )
+        {
+            if ( getRefCount() <= 1 )
+            {
+                InternalCF * res = resultFirst->coeff.getval();
+                delete resultFirst;
+                delete this;
+                return res;
+            }
+            else
+            {
+                decRefCount();
+                InternalCF * res = resultFirst->coeff.getval();
+                delete resultFirst;
+                return res;
+            }
+        }
+    }
+    if ( getRefCount() <= 1 )
+    {
+        freeTermList( firstTerm );
+        firstTerm = resultFirst;
+        lastTerm = resultLast;
+        return this;
+    }
+    else
+    {
+        decRefCount();
+        return new InternalPoly( resultFirst, resultLast, var );
+    }
+}
+
+InternalCF*
+InternalPoly::dividesame( InternalCF* aCoeff )
+{
+    return divsame( aCoeff );
+}
+
+
+InternalCF*
+InternalPoly::divsame( InternalCF* aCoeff )
+{
+    if ( inExtension() && getReduce( var ) )
+    {
+        InternalCF * dummy = aCoeff->invert();
+        if (is_imm(dummy)) dummy=this->mulsame(dummy);
+        else dummy = dummy->mulsame( this );
+        if ( getRefCount() <= 1 )
+        {
+             delete this;
+             return dummy;
+        }
+        else
+        {
+            decRefCount();
+            return dummy;
+        }
+    }
+    InternalPoly *aPoly = (InternalPoly*)aCoeff;
+    termList dummy, first, last, resultfirst = 0, resultlast = 0;
+    CanonicalForm coeff, newcoeff;
+    int exp, newexp;
+    bool singleObject;
+
+    if ( getRefCount() <= 1 )
+    {
+        first = firstTerm; last = lastTerm; singleObject = true;
+    }
+    else
+    {
+        first = copyTermList( firstTerm, last ); singleObject = false;
+        decRefCount();
+    }
+    coeff = aPoly->firstTerm->coeff;
+    exp = aPoly->firstTerm->exp;
+    while (first && ( first->exp >= exp ) )
+    {
+        newcoeff = first->coeff / coeff;
+        newexp = first->exp - exp;
+        dummy = first;
+        first = mulAddTermList( first->next, aPoly->firstTerm->next, newcoeff, newexp, last, true );
+        delete dummy;
+        appendTermList( resultfirst, resultlast, newcoeff, newexp );
+    }
+    freeTermList( first );
+    if ( singleObject )
+    {
+        if ( resultfirst && resultfirst->exp != 0 )
+        {
+            firstTerm = resultfirst;
+            lastTerm = resultlast;
+            return this;
+        }
+        else  if ( resultfirst )
+        {
+            InternalCF * res = resultfirst->coeff.getval();
+            delete resultfirst;
+            firstTerm = 0;
+            delete this;
+            return res;
+        }
+        else
+        {
+            // this should not happen (evtl use assertion)
+            ASSERT( 0, "FATAL ERROR, PLEASE INFORM THE AUTHOR" );
+            firstTerm = 0;
+            delete this;
+            return CFFactory::basic( 0L );
+        }
+    }
+    else
+    {
+        if ( resultfirst && resultfirst->exp != 0 )
+            return new InternalPoly( resultfirst, resultlast, var );
+        else  if ( resultfirst )
+        {
+            InternalCF * res = resultfirst->coeff.getval();
+            delete resultfirst;
+            return res;
+        }
+        else
+            return CFFactory::basic( 0L );
+    }
+}
+
+InternalCF*
+InternalPoly::tryDivsame( InternalCF* aCoeff, const CanonicalForm& M, bool& fail )
+{
+    if ( inExtension() && !getReduce( var ) )
+    {
+        InternalCF * dummy = aCoeff->tryInvert(M, fail);
+        if (fail)
+          return CFFactory::basic( 0L );
+        if (is_imm(dummy)) dummy=this->tryMulsame(dummy, M);
+        else dummy = dummy->tryMulsame( this, M);
+        if (fail)
+        {
+          if (getRefCount() <= 1)
+            delete this;
+          else
+            decRefCount();
+          return dummy;
+        }
+        if ( getRefCount() <= 1 )
+        {
+             delete this;
+             return dummy;
+        }
+        else
+        {
+            decRefCount();
+            return dummy;
+        }
+    }
+    InternalPoly *aPoly = (InternalPoly*)aCoeff;
+    termList dummy, first, last, resultfirst = 0, resultlast = 0;
+    CanonicalForm coeff, newcoeff;
+    int exp, newexp;
+    bool singleObject;
+
+    if ( getRefCount() <= 1 )
+    {
+        first = firstTerm; last = lastTerm; singleObject = true;
+    }
+    else
+    {
+        first = copyTermList( firstTerm, last ); singleObject = false;
+        decRefCount();
+    }
+    coeff = aPoly->firstTerm->coeff;
+    exp = aPoly->firstTerm->exp;
+    while (first && ( first->exp >= exp ) )
+    {
+        newcoeff= first->coeff.tryDiv (coeff, M, fail);
+        if (fail)
+        {
+          freeTermList (first);
+          return CFFactory::basic (0L);
+        }
+        newcoeff= reduce (newcoeff, M);
+        newexp = first->exp - exp;
+        dummy = first;
+        first = mulAddTermList( first->next, aPoly->firstTerm->next, newcoeff, newexp, last, true );
+        delete dummy;
+        if (!newcoeff.isZero())
+          appendTermList( resultfirst, resultlast, newcoeff, newexp );
+    }
+    freeTermList( first );
+    if ( singleObject )
+    {
+        if ( resultfirst && resultfirst->exp != 0 )
+        {
+            firstTerm = resultfirst;
+            lastTerm = resultlast;
+            return this;
+        }
+        else  if ( resultfirst )
+        {
+            InternalCF * res = resultfirst->coeff.getval();
+            delete resultfirst;
+            firstTerm = 0;
+            delete this;
+            return res;
+        }
+        else
+        {
+            // this should not happen (evtl use assertion)
+            ASSERT( 0, "FATAL ERROR, PLEASE INFORM THE AUTHOR" );
+            firstTerm = 0;
+            delete this;
+            return CFFactory::basic( 0L );
+        }
+    }
+    else
+    {
+        if ( resultfirst && resultfirst->exp != 0 )
+            return new InternalPoly( resultfirst, resultlast, var );
+        else  if ( resultfirst )
+        {
+            InternalCF * res = resultfirst->coeff.getval();
+            delete resultfirst;
+            return res;
+        }
+        else
+            return CFFactory::basic( 0L );
+    }
+}
+
+InternalCF*
+InternalPoly::modulosame( InternalCF* aCoeff )
+{
+    return modsame( aCoeff );
+}
+
+InternalCF*
+InternalPoly::modsame( InternalCF* aCoeff )
+{
+    if ( inExtension() && getReduce( var ) )
+    {
+        if ( deleteObject() ) delete this;
+        return CFFactory::basic( 0L );
+    }
+    InternalPoly *aPoly = (InternalPoly*)aCoeff;
+    termList dummy, first, last;
+    CanonicalForm coeff, newcoeff;
+    int exp, newexp;
+    bool singleObject;
+
+    if ( getRefCount() <= 1 )
+    {
+        first = firstTerm; last = lastTerm; singleObject = true;
+    }
+    else
+    {
+        first = copyTermList( firstTerm, last ); singleObject = false;
+        decRefCount();
+    }
+    coeff = aPoly->firstTerm->coeff;
+    exp = aPoly->firstTerm->exp;
+    while (first && ( first->exp >= exp ) )
+    {
+        newcoeff = first->coeff / coeff;
+        newexp = first->exp - exp;
+        dummy = first;
+        first = mulAddTermList( first->next, aPoly->firstTerm->next, newcoeff, newexp, last, true );
+        delete dummy;
+    }
+    if ( singleObject )
+    {
+        if ( first && first->exp != 0 )
+        {
+            firstTerm = first;
+            lastTerm = last;
+            return this;
+        }
+        else  if ( first )
+        {
+            InternalCF * res = first->coeff.getval();
+            delete first;
+            firstTerm = 0;
+            delete this;
+            return res;
+        }
+        else
+        {
+            firstTerm = 0;
+            delete this;
+            return CFFactory::basic( 0L );
+        }
+    }
+    else
+    {
+        if ( first && first->exp != 0 )
+            return new InternalPoly( first, last, var );
+        else  if ( first )
+        {
+            InternalCF * res = first->coeff.getval();
+            delete first;
+            return res;
+        }
+        else
+            return CFFactory::basic( 0L );
+    }
+}
+
+
+void
+InternalPoly::divremsame( InternalCF* acoeff, InternalCF*& quot, InternalCF*& rem )
+{
+    if ( inExtension() && getReduce( var ) )
+    {
+        InternalCF * dummy = acoeff->invert();
+        quot = dummy->mulsame( this );
+        rem = CFFactory::basic( 0L );
+    }
+    else
+    {
+        InternalPoly *aPoly = (InternalPoly*)acoeff;
+        termList dummy, first, last, resultfirst = 0, resultlast = 0;
+        CanonicalForm coeff, newcoeff;
+        int exp, newexp;
+
+        first = copyTermList( firstTerm, last );
+
+        coeff = aPoly->firstTerm->coeff;
+        exp = aPoly->firstTerm->exp;
+        while (first && ( first->exp >= exp ) )
+        {
+            newcoeff = first->coeff / coeff;
+            newexp = first->exp - exp;
+            dummy = first;
+            first = mulAddTermList( first->next, aPoly->firstTerm->next, newcoeff, newexp, last, true );
+            delete dummy;
+            appendTermList( resultfirst, resultlast, newcoeff, newexp );
+        }
+        if ( resultfirst )
+            if ( resultfirst->exp == 0 )
+            {
+                quot = resultfirst->coeff.getval();
+                delete resultfirst;
+            }
+            else
+                quot = new InternalPoly( resultfirst, resultlast, var );
+        else
+            quot = CFFactory::basic( 0L );
+        if ( first )
+            if ( first->exp == 0 )
+            {
+                rem = first->coeff.getval();
+                delete first;
+            }
+            else
+                rem = new InternalPoly( first, last, var );
+        else
+            rem = CFFactory::basic( 0L );
+    }
+}
+
+bool
+InternalPoly::divremsamet( InternalCF* acoeff, InternalCF*& quot, InternalCF*& rem )
+{
+    if ( inExtension() && getReduce( var ) )
+    {
+        divremsame( acoeff, quot, rem );
+        return true;
+    }
+    InternalPoly *aPoly = (InternalPoly*)acoeff;
+    termList dummy, first, last, resultfirst = 0, resultlast = 0;
+    CanonicalForm coeff, newcoeff, dummycoeff;
+    int exp, newexp;
+    bool divideok = true;
+
+//    if ( ! ::divremt( lastTerm->coeff, aPoly->lastTerm->coeff, newcoeff, dummycoeff ) )
+//        return false;
+
+    first = copyTermList( firstTerm, last );
+
+    coeff = aPoly->firstTerm->coeff;
+    exp = aPoly->firstTerm->exp;
+    while (first && ( first->exp >= exp ) && divideok )
+    {
+        divideok = divremt( first->coeff, coeff, newcoeff, dummycoeff );
+        if ( divideok && dummycoeff.isZero() )
+        {
+            newexp = first->exp - exp;
+            dummy = first;
+            first = mulAddTermList( first->next, aPoly->firstTerm->next, newcoeff, newexp, last, true );
+            delete dummy;
+            appendTermList( resultfirst, resultlast, newcoeff, newexp );
+        }
+        else
+            divideok = false;
+    }
+    if ( divideok )
+    {
+        if ( resultfirst )
+            if ( resultfirst->exp == 0 )
+            {
+                quot = resultfirst->coeff.getval();
+                delete resultfirst;
+            }
+            else
+                quot = new InternalPoly( resultfirst, resultlast, var );
+        else
+            quot = CFFactory::basic( 0L );
+        if ( first )
+            if ( first->exp == 0 )
+            {
+                rem = first->coeff.getval();
+                delete first;
+            }
+            else
+                rem = new InternalPoly( first, last, var );
+        else
+            rem = CFFactory::basic( 0L );
+    }
+    else
+    {
+        freeTermList( resultfirst );
+        freeTermList( first );
+    }
+    return divideok;
+}
+
+bool
+InternalPoly::tryDivremsamet( InternalCF* acoeff, InternalCF*& quot, InternalCF*& rem, const CanonicalForm& M, bool& fail)
+{
+    if (inExtension() && !getReduce (var))
+    {
+       InternalCF * dummy = acoeff->tryInvert(M, fail);
+       if (fail)
+         return false;
+       quot = dummy->tryMulsame( this, M);
+       rem = CFFactory::basic( 0L );
+       if (fail)
+         return false;
+       return true;
+    }
+    InternalPoly *aPoly = (InternalPoly*)acoeff;
+    termList dummy, first, last, resultfirst = 0, resultlast = 0;
+    CanonicalForm coeff, newcoeff, dummycoeff;
+    int exp, newexp;
+    bool divideok = true;
+
+    first = copyTermList( firstTerm, last );
+
+    coeff = aPoly->firstTerm->coeff;
+    exp = aPoly->firstTerm->exp;
+    while (first && ( first->exp >= exp ) && divideok )
+    {
+        divideok = tryDivremt( first->coeff, coeff, newcoeff, dummycoeff, M, fail );
+        if (fail)
+        {
+          freeTermList (first);
+          return false;
+        }
+        if ( divideok && dummycoeff.isZero() )
+        {
+            newexp = first->exp - exp;
+            dummy = first;
+            first = mulAddTermList( first->next, aPoly->firstTerm->next, newcoeff, newexp, last, true );
+            delete dummy;
+            if (!newcoeff.isZero())
+              appendTermList( resultfirst, resultlast, newcoeff, newexp );
+        }
+        else
+            divideok = false;
+    }
+    if ( divideok )
+    {
+        if ( resultfirst )
+            if ( resultfirst->exp == 0 )
+            {
+                quot = resultfirst->coeff.getval();
+                delete resultfirst;
+            }
+            else
+                quot = new InternalPoly( resultfirst, resultlast, var );
+        else
+            quot = CFFactory::basic( 0L );
+        if ( first )
+            if ( first->exp == 0 )
+            {
+                rem = first->coeff.getval();
+                delete first;
+            }
+            else
+            {
+                if (first->coeff.isZero())
+                {
+                  rem= CFFactory::basic (0L);
+                  delete first;
+                }
+                else
+                  rem = new InternalPoly( first, last, var );
+            }
+        else
+            rem = CFFactory::basic( 0L );
+    }
+    else
+    {
+        freeTermList( resultfirst );
+        freeTermList( first );
+    }
+    return divideok;
+}
+
+/**
+ * comparesame(), comparecoeff() - compare with an
+ *   InternalPoly.
+ *
+ * comparesame() compares the coefficient vectors of f=CO and
+ * g=acoeff w.r.t to a lexicographic order in the following way:
+ * f < g iff there exists an 0 <= i <= max(deg(f),deg(g)) s.t.
+ * i) f[j] = g[j] for all i < j <= max(deg(f),deg(g)) and
+ * ii) g[i] occurs in g (i.e. is not equal to zero) and
+ *     f[i] does not occur in f or f[i] < g[i] if f[i] occurs
+ * where f[i] denotes the coefficient to the power x^i of f.
+ *
+ * As usual, comparesame() returns 1 if CO is larger than c, 0 if
+ * CO equals c, and -1 if CO is less than c.  However, this
+ * function is optimized to test on equality since this is its
+ * most important and frequent usage.
+ *
+ * See the respective `CanonicalForm'-methods for an explanation
+ * why we define such a strange (but total) ordering on
+ * polynomials.
+ *
+ * @sa CanonicalForm::operator <(), CanonicalForm::operator ==()
+ *
+**/
+int
+InternalPoly::comparesame ( InternalCF * acoeff )
+{
+    ASSERT( ! ::is_imm( acoeff ) && acoeff->level() > LEVELBASE, "incompatible base coefficients" );
+    InternalPoly* apoly = (InternalPoly*)acoeff;
+    // check on triviality
+    if ( this == apoly )
+        return 0;
+    else
+    {
+        termList cursor1 = firstTerm;
+        termList cursor2 = apoly->firstTerm;
+        for ( ; cursor1 && cursor2; cursor1 = cursor1->next, cursor2 = cursor2->next )
+            // we test on inequality of coefficients at this
+            // point instead of testing on "less than" at the
+            // last `else' in the enclosed `if' statement since a
+            // test on inequaltiy in general is cheaper
+            if ( (cursor1->exp != cursor2->exp) || (cursor1->coeff != cursor2->coeff) )
+            {
+                if ( cursor1->exp > cursor2->exp )
+                    return 1;
+                else  if ( cursor1->exp < cursor2->exp )
+                    return -1;
+                else  if ( cursor1->coeff > cursor2->coeff )
+                    return 1;
+                else
+                    return -1;
+             }
+        // check trailing terms
+        if ( cursor1 == cursor2 )
+            return 0;
+        else if ( cursor1 != 0 )
+            return 1;
+        else
+            return -1;
+    }
+}
+
+/**
+ * comparecoeff() always returns 1 since CO is defined to be
+ * larger than anything which is a coefficient w.r.t. CO.
+**/
+int
+InternalPoly::comparecoeff ( InternalCF * )
+{
+    return 1;
+}
+
+InternalCF*
+InternalPoly::addcoeff( InternalCF* cc )
+{
+    CanonicalForm c( is_imm(cc) ? cc : cc->copyObject() );
+    if ( c.isZero() )
+        return this;
+    else
+    {
+        if ( getRefCount() <= 1 )
+        {
+            if ( lastTerm->exp == 0 )
+            {
+                lastTerm->coeff += c;
+                if ( lastTerm->coeff.isZero() )
+                {
+                    termList cursor = firstTerm;
+                    while ( cursor->next != lastTerm )
+                        cursor = cursor->next;
+                    delete lastTerm;
+                    cursor->next = 0;
+                    lastTerm = cursor;
+                }
+            }
+            else
+            {
+                lastTerm->next = new term( 0, c, 0 );
+                lastTerm = lastTerm->next;
+            }
+            return this;
+        }
+        else
+        {
+            decRefCount();
+            termList last, first = copyTermList( firstTerm, last, false );
+            if ( last->exp == 0 )
+            {
+                last->coeff += c;
+                if ( last->coeff.isZero() )
+                {
+                    termList cursor = first;
+                    while ( cursor->next != last )
+                        cursor = cursor->next;
+                    delete last;
+                    cursor->next = 0;
+                    last = cursor;
+                }
+            }
+            else
+            {
+                last->next = new term( 0, c, 0L );
+                last = last->next;
+            }
+            return new InternalPoly( first, last, var );
+        }
+    }
+}
+
+InternalCF*
+InternalPoly::subcoeff( InternalCF* cc, bool negate )
+{
+    CanonicalForm c( is_imm(cc) ? cc : cc->copyObject() );
+    if ( c.isZero() )
+        if ( getRefCount() > 1 )
+        {
+            decRefCount();
+            termList last, first = copyTermList( firstTerm, last, negate );
+            return new InternalPoly( first, last, var );
+        }
+        else
+        {
+            if ( negate )
+                negateTermList( firstTerm );
+            return this;
+        }
+    else
+    {
+        if ( getRefCount() <= 1 )
+        {
+            if ( lastTerm->exp == 0 )
+            {
+                if ( negate )
+                {
+                    negateTermList( firstTerm );
+                    lastTerm->coeff += c;
+                }
+                else
+                    lastTerm->coeff -= c;
+                if ( lastTerm->coeff.isZero() )
+                {
+                    termList cursor = firstTerm;
+                    while ( cursor->next != lastTerm )
+                        cursor = cursor->next;
+                    delete lastTerm;
+                    cursor->next = 0;
+                    lastTerm = cursor;
+                }
+            }
+            else
+            {
+                if ( negate )
+                {
+                    negateTermList( firstTerm );
+                    lastTerm->next = new term( 0, c, 0 );
+                }
+                else
+                    lastTerm->next = new term( 0, -c, 0 );
+                lastTerm = lastTerm->next;
+            }
+            return this;
+        }
+        else
+        {
+            decRefCount();
+            termList last, first = copyTermList( firstTerm, last, negate );
+            if ( last->exp == 0 )
+            {
+                if ( negate )
+                    last->coeff += c;
+                else
+                    last->coeff -= c;
+                if ( last->coeff.isZero() )
+                {
+                    termList cursor = first;
+                    while ( cursor->next != last )
+                        cursor = cursor->next;
+                    delete last;
+                    cursor->next = 0;
+                    last = cursor;
+                }
+            }
+            else
+            {
+                if ( negate )
+                    last->next = new term( 0, c, 0 );
+                else
+                    last->next = new term( 0, -c, 0 );
+                last = last->next;
+            }
+            return new InternalPoly( first, last, var );
+        }
+    }
+}
+
+InternalCF*
+InternalPoly::mulcoeff( InternalCF* cc )
+{
+    CanonicalForm c( is_imm(cc) ? cc : cc->copyObject() );
+    if ( c.isZero() )
+    {
+        if ( getRefCount() <= 1 )
+        {
+            delete this;
+            return CFFactory::basic( 0L );
+        }
+        else
+        {
+            decRefCount();
+            return CFFactory::basic( 0L );
+        }
+    }
+    else  if ( c.isOne() )
+        return this;
+    else
+    {
+        if ( getRefCount() <= 1 )
+        {
+            mulTermList( firstTerm, c, 0L );
+            return this;
+        }
+        else
+        {
+            decRefCount();
+            termList last, first = copyTermList( firstTerm, last );
+            mulTermList( first, c, 0 );
+            return new InternalPoly( first, last, var );
+        }
+    }
+}
+
+InternalCF*
+InternalPoly::dividecoeff( InternalCF* cc, bool invert )
+{
+    CanonicalForm c( is_imm(cc) ? cc : cc->copyObject() );
+    if ( inExtension() && getReduce( var ) && invert )
+    {
+        InternalCF * dummy;
+        dummy = this->invert();
+        if (is_imm(dummy))
+        {
+          if (is_imm(cc))
+          {
+            InternalInteger *d=new InternalInteger(imm2int(dummy)*imm2int(cc));
+            dummy=d;
+          }
+          else
+            dummy=cc->mulcoeff(dummy);
+        }
+        else dummy = dummy->mulcoeff( cc );
+        if ( getRefCount() <= 1 )
+        {
+            delete this;
+            return dummy;
+        }
+        else
+        {
+            decRefCount();
+            return dummy;
+        }
+    }
+    if ( invert )
+    {
+        if ( getRefCount() <= 1 )
+        {
+            delete this;
+            return CFFactory::basic( 0L );
+        }
+        else
+        {
+            decRefCount();
+            return CFFactory::basic( 0L );
+        }
+    }
+    if ( c.isOne() )
+        return this;
+    else
+    {
+        if ( getRefCount() <= 1 )
+        {
+            firstTerm = divideTermList( firstTerm, c, lastTerm );
+            if ( firstTerm && firstTerm->exp != 0 )
+                return this;
+            else  if ( firstTerm )
+            {
+                InternalCF * res = firstTerm->coeff.getval();
+                delete this;
+                return res;
+            }
+            else
+            {
+                delete this;
+                return CFFactory::basic( 0L );
+            }
+        }
+        else
+        {
+            decRefCount();
+            termList last, first = copyTermList( firstTerm, last );
+            first = divideTermList( first, c, last );
+            if ( first && first->exp != 0 )
+                return new InternalPoly( first, last, var );
+            else  if ( first )
+            {
+                InternalCF * res = first->coeff.getval();
+                delete first;
+                return res;
+            }
+            else
+            {
+                delete first;
+                return CFFactory::basic( 0L );
+            }
+        }
+    }
+}
+
+InternalCF*
+InternalPoly::tryDividecoeff( InternalCF* cc, bool invert, const CanonicalForm& M, bool& fail )
+{
+    CanonicalForm c( is_imm(cc) ? cc : cc->copyObject() );
+    if ( inExtension() && !getReduce( var ) && invert )
+    {
+        InternalCF * dummy;
+        dummy = this->tryInvert(M, fail);
+        if (fail)
+        {
+          if (getRefCount() <= 1)
+            delete this;
+          else
+            decRefCount();
+          return dummy; //is equal to CFFactory::basic ( 0L ) in this case
+        }
+        if (is_imm(dummy))
+        {
+          if (is_imm(cc))
+          {
+            InternalInteger *d=new InternalInteger(imm2int(dummy)*imm2int(cc));
+            dummy=d;
+          }
+          else
+            dummy=cc->mulcoeff(dummy);
+        }
+        else dummy = dummy->mulcoeff( cc );
+        if ( getRefCount() <= 1 )
+        {
+            delete this;
+            return dummy;
+        }
+        else
+        {
+            decRefCount();
+            return dummy;
+        }
+    }
+    if ( invert )
+    {
+        if ( getRefCount() <= 1 )
+        {
+            delete this;
+            return CFFactory::basic( 0L );
+        }
+        else
+        {
+            decRefCount();
+            return CFFactory::basic( 0L );
+        }
+    }
+    if ( c.isOne() )
+        return this;
+    //one should never get here
+    else
+    {
+        if ( getRefCount() <= 1 )
+        {
+            firstTerm = divideTermList( firstTerm, c, lastTerm );
+            if ( firstTerm && firstTerm->exp != 0 )
+                return this;
+            else  if ( firstTerm )
+            {
+                InternalCF * res = firstTerm->coeff.getval();
+                delete this;
+                return res;
+            }
+            else
+            {
+                delete this;
+                return CFFactory::basic( 0L );
+            }
+        }
+        else
+        {
+            decRefCount();
+            termList last, first = copyTermList( firstTerm, last );
+            first = divideTermList( first, c, last );
+            if ( first && first->exp != 0 )
+                return new InternalPoly( first, last, var );
+            else  if ( first )
+            {
+                InternalCF * res = first->coeff.getval();
+                delete first;
+                return res;
+            }
+            else
+            {
+                delete first;
+                return CFFactory::basic( 0L );
+            }
+        }
+    }
+}
+
+
+InternalCF*
+InternalPoly::divcoeff( InternalCF* cc, bool invert )
+{
+    CanonicalForm c( is_imm(cc) ? cc : cc->copyObject() );
+    if ( inExtension() && getReduce( var ) && invert )
+    {
+        InternalCF * dummy;
+        dummy = this->invert();
+        dummy = dummy->mulcoeff( cc );
+        if ( getRefCount() <= 1 )
+        {
+            delete this;
+            return dummy;
+        }
+        else
+        {
+            decRefCount();
+            return dummy;
+        }
+    }
+    if ( invert )
+    {
+        if ( getRefCount() <= 1 )
+        {
+            delete this;
+            return CFFactory::basic( 0L );
+        }
+        else
+        {
+            decRefCount();
+            return CFFactory::basic( 0L );
+        }
+    }
+    if ( c.isOne() )
+        return this;
+    else
+    {
+        if ( getRefCount() <= 1 )
+        {
+            firstTerm = divTermList( firstTerm, c, lastTerm );
+            if ( firstTerm && firstTerm->exp != 0 )
+                return this;
+            else  if ( firstTerm )
+            {
+                InternalCF * res = firstTerm->coeff.getval();
+                delete this;
+                return res;
+            }
+            else
+            {
+                delete this;
+                return CFFactory::basic( 0L );
+            }
+        }
+        else
+        {
+            decRefCount();
+            termList last, first = copyTermList( firstTerm, last );
+            first = divTermList( first, c, last );
+            if ( first && first->exp != 0 )
+                return new InternalPoly( first, last, var );
+            else  if ( first )
+            {
+                InternalCF * res = first->coeff.getval();
+                delete first;
+                return res;
+            }
+            else
+            {
+                delete first;
+                return CFFactory::basic( 0L );
+            }
+        }
+    }
+}
+
+InternalCF*
+InternalPoly::tryDivcoeff( InternalCF* cc, bool invert, const CanonicalForm& M, bool& fail )
+{
+    CanonicalForm c( is_imm(cc) ? cc : cc->copyObject() );
+    if ( inExtension() && !getReduce( var ) && invert )
+    {
+        InternalCF * dummy;
+        dummy = this->tryInvert(M, fail);
+        if (fail)
+        {
+          if (getRefCount() <= 1)
+            delete this;
+          else
+            decRefCount();
+          return dummy;
+        }
+        dummy = dummy->mulcoeff( cc );
+        if ( getRefCount() <= 1 )
+        {
+            delete this;
+            return dummy;
+        }
+        else
+        {
+            decRefCount();
+            return dummy;
+        }
+    }
+    if ( invert )
+    {
+        if ( getRefCount() <= 1 )
+        {
+            delete this;
+            return CFFactory::basic( 0L );
+        }
+        else
+        {
+            decRefCount();
+            return CFFactory::basic( 0L );
+        }
+    }
+    if ( c.isOne() )
+        return this;
+    else
+    {
+        if ( getRefCount() <= 1 )
+        {
+            firstTerm = tryDivTermList( firstTerm, c, lastTerm, M, fail );
+            if (fail)
+            {
+              delete this;
+              return CFFactory::basic (0L);
+            }
+            if ( firstTerm && firstTerm->exp != 0 )
+                return this;
+            else  if ( firstTerm )
+            {
+                InternalCF * res = firstTerm->coeff.getval();
+                delete this;
+                return res;
+            }
+            else
+            {
+                delete this;
+                return CFFactory::basic( 0L );
+            }
+        }
+        else
+        {
+            decRefCount();
+            termList last, first = copyTermList( firstTerm, last );
+            first = tryDivTermList( first, c, last, M, fail );
+            if (fail)
+            {
+              delete this;
+              return CFFactory::basic (0L);
+            }
+            if (fail)
+            {
+              delete first;
+              return CFFactory::basic (0L);
+            }
+            if ( first && first->exp != 0 )
+                return new InternalPoly( first, last, var );
+            else  if ( first )
+            {
+                InternalCF * res = first->coeff.getval();
+                delete first;
+                return res;
+            }
+            else
+            {
+                delete first;
+                return CFFactory::basic( 0L );
+            }
+        }
+    }
+}
+
+InternalCF*
+InternalPoly::modulocoeff( InternalCF* cc, bool invert )
+{
+    CanonicalForm c( is_imm(cc) ? cc : cc->copyObject() );
+    if ( invert )
+    {
+        if ( deleteObject() ) delete this;
+        return c.getval();
+    }
+    ASSERT( ! c.isZero(), "divide by zero!" );
+    if ( deleteObject() ) delete this;
+    return CFFactory::basic( 0L );
+}
+
+InternalCF*
+InternalPoly::modcoeff( InternalCF* cc, bool invert )
+{
+    CanonicalForm c( is_imm(cc) ? cc : cc->copyObject() );
+    if ( invert )
+    {
+        if ( deleteObject() ) delete this;
+        return c.getval();
+    }
+    ASSERT( ! c.isZero(), "divide by zero!" );
+    if ( c.isOne() )
+    {
+        if ( getRefCount() <= 1 )
+        {
+            delete this;
+            return CFFactory::basic( 0L );
+        }
+        else
+        {
+            decRefCount();
+            return CFFactory::basic( 0L );
+        }
+    }
+    else
+    {
+        if ( getRefCount() <= 1 )
+        {
+            firstTerm = modTermList( firstTerm, c, lastTerm );
+            if ( firstTerm && firstTerm->exp != 0 )
+                return this;
+            else  if ( firstTerm )
+            {
+                InternalCF * res = firstTerm->coeff.getval();
+                delete this;
+                return res;
+            }
+            else
+            {
+                delete this;
+                return CFFactory::basic( 0L );
+            }
+        }
+        else
+        {
+            decRefCount();
+            termList last, first = copyTermList( firstTerm, last );
+            first = modTermList( first, c, last );
+            if ( first && first->exp != 0 )
+                return new InternalPoly( first, last, var );
+            else  if ( first )
+            {
+                InternalCF * res = first->coeff.getval();
+                delete first;
+                return res;
+            }
+            else
+            {
+                delete first;
+                return CFFactory::basic( 0L );
+            }
+        }
+    }
+}
+
+void
+InternalPoly::divremcoeff( InternalCF* cc, InternalCF*& quot, InternalCF*& rem, bool invert )
+{
+    if ( inExtension() && getReduce( var ) )
+    {
+        quot = copyObject();
+        quot = quot->dividecoeff( cc, invert );
+        rem = CFFactory::basic( 0L );
+    }
+    else  if ( invert )
+    {
+        if ( is_imm( cc ) )
+            rem = cc;
+        else
+            rem = cc->copyObject();
+        quot = CFFactory::basic( 0L );
+    }
+    else
+    {
+        CanonicalForm c( is_imm(cc) ? cc : cc->copyObject() );
+        ASSERT( ! c.isZero(), "divide by zero!" );
+        termList quotlast, quotfirst = copyTermList( firstTerm, quotlast );
+        quotfirst = divideTermList( quotfirst, c, quotlast );
+        if ( quotfirst )
+            if ( quotfirst->exp == 0 )
+            {
+                quot = quotfirst->coeff.getval();
+                delete quotfirst;
+            }
+            else
+                quot = new InternalPoly( quotfirst, quotlast, var );
+        else
+            quot = CFFactory::basic( 0L );
+        rem = CFFactory::basic( 0L );
+    }
+}
+
+bool
+InternalPoly::divremcoefft( InternalCF* cc, InternalCF*& quot, InternalCF*& rem, bool invert )
+{
+    if ( inExtension() && getReduce( var ) )
+    {
+        quot = copyObject();
+        quot = quot->dividecoeff( cc, invert );
+        rem = CFFactory::basic( 0L );
+        return true;
+    }
+    else  if ( invert )
+    {
+        if ( is_imm( cc ) )
+            rem = cc;
+        else
+            rem = cc->copyObject();
+        quot = CFFactory::basic( 0L );
+        return true;
+    }
+    CanonicalForm c( is_imm(cc) ? cc : cc->copyObject() );
+    ASSERT( ! c.isZero(), "divide by zero!" );
+    termList quotfirst, quotcursor;
+    termList cursor;
+    CanonicalForm cquot, crem;
+    bool divideok = true;
+
+    cursor = firstTerm;
+    quotcursor = quotfirst = new term;
+
+    while ( cursor && divideok )
+    {
+        divideok = divremt( cursor->coeff, c, cquot, crem );
+        divideok = divideok && crem.isZero();
+        if ( divideok )
+        {
+            if ( ! cquot.isZero() )
+            {
+                quotcursor->next = new term( 0, cquot, cursor->exp );
+                quotcursor = quotcursor->next;
+            }
+            cursor = cursor->next;
+        }
+    }
+    quotcursor->next = 0;
+    if ( divideok )
+    {
+        cursor = quotfirst; quotfirst = quotfirst->next; delete cursor;
+        if ( quotfirst )
+            if ( quotfirst->exp == 0 )
+            {
+                quot = quotfirst->coeff.getval();
+                delete quotfirst;
+            }
+            else
+                quot = new InternalPoly( quotfirst, quotcursor, var );
+        else
+            quot = CFFactory::basic( 0L );
+        rem = CFFactory::basic( 0L );
+    }
+    else
+    {
+        freeTermList( quotfirst );
+    }
+    return divideok;
+}
+
+bool
+InternalPoly::tryDivremcoefft( InternalCF* cc, InternalCF*& quot, InternalCF*& rem, bool invert, const CanonicalForm& M, bool& fail )
+{
+    if ( inExtension() && !getReduce( var ) )
+    {
+        quot = copyObject();
+        quot = quot->tryDividecoeff( cc, invert, M, fail );
+        if (fail)
+          return false;
+        rem = CFFactory::basic( 0L );
+        return true;
+    }
+    else  if ( invert )
+    {
+        if ( is_imm( cc ) )
+            rem = cc;
+        else
+            rem = cc->copyObject();
+        quot = CFFactory::basic( 0L );
+        return true;
+    }
+    CanonicalForm c( is_imm(cc) ? cc : cc->copyObject() );
+    ASSERT( ! c.isZero(), "divide by zero!" );
+    termList quotfirst, quotcursor;
+    termList cursor;
+    CanonicalForm cquot, crem;
+    bool divideok = true;
+
+    cursor = firstTerm;
+    quotcursor = quotfirst = new term;
+
+    while ( cursor && divideok )
+    {
+        divideok = tryDivremt( cursor->coeff, c, cquot, crem, M, fail );
+        if (fail)
+        {
+          freeTermList (quotfirst);
+          return false;
+        }
+        divideok = divideok && crem.isZero();
+        if ( divideok )
+        {
+            if ( ! cquot.isZero() )
+            {
+                quotcursor->next = new term( 0, cquot, cursor->exp );
+                quotcursor = quotcursor->next;
+            }
+            cursor = cursor->next;
+        }
+    }
+    quotcursor->next = 0;
+    if ( divideok )
+    {
+        cursor = quotfirst; quotfirst = quotfirst->next; delete cursor;
+        if ( quotfirst )
+            if ( quotfirst->exp == 0 )
+            {
+                quot = quotfirst->coeff.getval();
+                delete quotfirst;
+            }
+            else
+                quot = new InternalPoly( quotfirst, quotcursor, var );
+        else
+            quot = CFFactory::basic( 0L );
+        rem = CFFactory::basic( 0L );
+    }
+    else
+    {
+        freeTermList( quotfirst );
+    }
+    return divideok;
+}
+
+// static functions
+
+termList
+InternalPoly::copyTermList ( termList aTermList, termList& theLastTerm, bool negate )
+{
+    if ( aTermList == 0 )
+        return 0;
+    else  if ( negate )
+    {
+        termList sourceCursor = aTermList;
+        termList dummy = new term;
+        termList targetCursor = dummy;
+
+        while ( sourceCursor )
+        {
+            targetCursor->next = new term( 0, -sourceCursor->coeff, sourceCursor->exp );
+            targetCursor = targetCursor->next;
+            sourceCursor = sourceCursor->next;
+        }
+        targetCursor->next = 0;
+        theLastTerm = targetCursor;
+        targetCursor = dummy->next;
+        delete dummy;
+        return targetCursor;
+    }
+    else
+    {
+        termList sourceCursor = aTermList;
+        termList dummy = new term;
+        termList targetCursor = dummy;
+
+        while ( sourceCursor )
+        {
+            targetCursor->next = new term( 0, sourceCursor->coeff, sourceCursor->exp );
+            targetCursor = targetCursor->next;
+            sourceCursor = sourceCursor->next;
+        }
+        targetCursor->next = 0;
+        theLastTerm = targetCursor;
+        targetCursor = dummy->next;
+        delete dummy;
+        return targetCursor;
+    }
+}
+
+termList
+InternalPoly::deepCopyTermList ( termList aTermList, termList& theLastTerm )
+{
+    if ( aTermList == 0 )
+        return 0;
+    else
+    {
+        termList sourceCursor = aTermList;
+        termList dummy = new term;
+        termList targetCursor = dummy;
+
+        while ( sourceCursor )
+        {
+            targetCursor->next = new term( 0, sourceCursor->coeff.deepCopy(), sourceCursor->exp );
+            targetCursor = targetCursor->next;
+            sourceCursor = sourceCursor->next;
+        }
+        targetCursor->next = 0;
+        theLastTerm = targetCursor;
+        targetCursor = dummy->next;
+        delete dummy;
+        return targetCursor;
+    }
+}
+
+void
+InternalPoly::freeTermList ( termList aTermList )
+{
+    termList cursor = aTermList;
+
+    while ( cursor )
+    {
+        cursor = cursor->next;
+        delete aTermList;
+        aTermList = cursor;
+    }
+}
+
+void
+InternalPoly::negateTermList ( termList terms )
+{
+    termList cursor = terms;
+    while ( cursor )
+    {
+        cursor->coeff = -cursor->coeff;
+        cursor = cursor->next;
+    }
+}
+
+termList
+InternalPoly::addTermList ( termList theList, termList aList, termList& lastTerm, bool negate )
+{
+    termList theCursor = theList;
+    termList aCursor = aList;
+    termList predCursor = 0;
+
+    while ( theCursor && aCursor )
+    {
+        if ( theCursor->exp == aCursor->exp )
+        {
+            if ( negate )
+                theCursor->coeff -= aCursor->coeff;
+            else
+                theCursor->coeff += aCursor->coeff;
+            if ( theCursor->coeff.isZero() )
+            {
+                if ( predCursor )
+                {
+                    predCursor->next = theCursor->next;
+                    delete theCursor;
+                    theCursor = predCursor->next;
+                }
+                else
+                {
+                    theList = theList->next;
+                    delete theCursor;
+                    theCursor = theList;
+                }
+            }
+            else
+            {
+                predCursor = theCursor;
+                theCursor = theCursor->next;
+            }
+            aCursor = aCursor->next;
+        }
+        else if ( theCursor->exp < aCursor->exp )
+        {
+            if ( negate )
+                if ( predCursor )
+                {
+                    predCursor->next = new term( theCursor, -aCursor->coeff, aCursor->exp );
+                    predCursor = predCursor->next;
+                }
+                else
+                {
+                    theList = new term( theCursor, -aCursor->coeff, aCursor->exp );
+                    predCursor = theList;
+                }
+            else
+                if ( predCursor )
+                {
+                    predCursor->next = new term( theCursor, aCursor->coeff, aCursor->exp );
+                    predCursor = predCursor->next;
+                }
+                else
+                {
+                    theList = new term( theCursor, aCursor->coeff, aCursor->exp );
+                    predCursor = theList;
+                }
+            aCursor = aCursor->next;
+        }
+        else
+        {
+            predCursor = theCursor;
+            theCursor = theCursor->next;
+        }
+    }
+    if ( aCursor )
+    {
+        if ( predCursor )
+            predCursor->next = copyTermList( aCursor, lastTerm, negate );
+        else
+            theList = copyTermList( aCursor, lastTerm, negate );
+    }
+    else if ( ! theCursor )
+        lastTerm = predCursor;
+
+    return theList;
+}
+
+void
+InternalPoly::mulTermList ( termList theCursor, const CanonicalForm& coeff, const int exp )
+{
+    while ( theCursor )
+    {
+        theCursor->coeff *= coeff;
+        theCursor->exp += exp;
+        theCursor = theCursor->next;
+    }
+}
+
+termList
+InternalPoly::divideTermList ( termList firstTerm, const CanonicalForm& coeff, termList& lastTerm )
+{
+    termList theCursor = firstTerm;
+    lastTerm = 0;
+    termList dummy;
+
+    while ( theCursor )
+    {
+        theCursor->coeff /= coeff;
+        if ( theCursor->coeff.isZero() )
+        {
+            if ( theCursor == firstTerm )
+                firstTerm = theCursor->next;
+            else
+                lastTerm->next = theCursor->next;
+            dummy = theCursor;
+            theCursor = theCursor->next;
+            delete dummy;
+        }
+        else
+        {
+            lastTerm = theCursor;
+            theCursor = theCursor->next;
+        }
+    }
+    return firstTerm;
+}
+
+termList
+InternalPoly::divTermList ( termList firstTerm, const CanonicalForm& coeff, termList& lastTerm )
+{
+    termList theCursor = firstTerm;
+    lastTerm = 0;
+    termList dummy;
+
+    while ( theCursor )
+    {
+        theCursor->coeff.div( coeff );
+        if ( theCursor->coeff.isZero() )
+        {
+            if ( theCursor == firstTerm )
+                firstTerm = theCursor->next;
+            else
+                lastTerm->next = theCursor->next;
+            dummy = theCursor;
+            theCursor = theCursor->next;
+            delete dummy;
+        }
+        else
+        {
+            lastTerm = theCursor;
+            theCursor = theCursor->next;
+        }
+    }
+    return firstTerm;
+}
+
+termList
+InternalPoly::tryDivTermList ( termList firstTerm, const CanonicalForm& coeff, termList& lastTerm, const CanonicalForm& M, bool& fail )
+{
+    termList theCursor = firstTerm;
+    lastTerm = 0;
+    termList dummy;
+
+    while ( theCursor )
+    {
+        theCursor->coeff.tryDiv( coeff, M, fail );
+        if (fail)
+          return 0;
+        if ( theCursor->coeff.isZero() )
+        {
+            if ( theCursor == firstTerm )
+                firstTerm = theCursor->next;
+            else
+                lastTerm->next = theCursor->next;
+            dummy = theCursor;
+            theCursor = theCursor->next;
+            delete dummy;
+        }
+        else
+        {
+            lastTerm = theCursor;
+            theCursor = theCursor->next;
+        }
+    }
+    return firstTerm;
+}
+
+termList
+InternalPoly::modTermList ( termList firstTerm, const CanonicalForm& coeff, termList& lastTerm )
+{
+    termList theCursor = firstTerm;
+    lastTerm = 0;
+    termList dummy;
+
+    while ( theCursor )
+    {
+        theCursor->coeff.mod( coeff );
+        if ( theCursor->coeff.isZero() )
+        {
+            if ( theCursor == firstTerm )
+                firstTerm = theCursor->next;
+            else
+                lastTerm->next = theCursor->next;
+            dummy = theCursor;
+            theCursor = theCursor-> next;
+            delete dummy;
+        }
+        else
+        {
+            lastTerm = theCursor;
+            theCursor = theCursor->next;
+        }
+    }
+    return firstTerm;
+}
+
+void
+InternalPoly::appendTermList ( termList& first, termList& last, const CanonicalForm& coeff, const int exp )
+{
+    if ( last )
+    {
+        last->next = new term( 0, coeff, exp );
+        last = last->next;
+    }
+    else
+    {
+        first = new term( 0, coeff, exp );
+        last = first;
+    }
+}
+
+termList
+InternalPoly::mulAddTermList ( termList theList, termList aList, const CanonicalForm & c, const int exp, termList & lastTerm, bool negate )
+{
+    termList theCursor = theList;
+    termList aCursor = aList;
+    termList predCursor = 0;
+    CanonicalForm coeff;
+
+    if ( negate )
+        coeff = -c;
+    else
+        coeff = c;
+
+    while ( theCursor && aCursor )
+    {
+        if ( theCursor->exp == aCursor->exp + exp )
+        {
+            theCursor->coeff += aCursor->coeff * coeff;
+            if ( theCursor->coeff.isZero() )
+            {
+                if ( predCursor )
+                {
+                    predCursor->next = theCursor->next;
+                    delete theCursor;
+                    theCursor = predCursor->next;
+                }
+                else
+                {
+                    theList = theList->next;
+                    delete theCursor;
+                    theCursor = theList;
+                }
+            }
+            else
+            {
+                predCursor = theCursor;
+                theCursor = theCursor->next;
+            }
+            aCursor = aCursor->next;
+        }
+        else if ( theCursor->exp < aCursor->exp + exp )
+        {
+            if ( predCursor )
+            {
+                predCursor->next = new term( theCursor, aCursor->coeff * coeff, aCursor->exp + exp );
+                predCursor = predCursor->next;
+            }
+            else
+            {
+                theList = new term( theCursor, aCursor->coeff * coeff, aCursor->exp + exp );
+                predCursor = theList;
+            }
+            aCursor = aCursor->next;
+        }
+        else
+        {
+            predCursor = theCursor;
+            theCursor = theCursor->next;
+        }
+    }
+    if ( aCursor )
+    {
+        if ( predCursor )
+        {
+            predCursor->next = copyTermList( aCursor, lastTerm );
+            predCursor = predCursor->next;
+        }
+        else
+        {
+            theList = copyTermList( aCursor, lastTerm );
+            predCursor = theList;
+        }
+        while ( predCursor )
+        {
+            predCursor->exp += exp;
+            predCursor->coeff *= coeff;
+            predCursor = predCursor->next;
+        }
+    }
+    else if ( ! theCursor )
+        lastTerm = predCursor;
+    return theList;
+}
+
+termList
+InternalPoly::reduceTermList ( termList first, termList redterms, termList & last )
+{
+    CanonicalForm coeff = CanonicalForm (1)/redterms->coeff;
+    CanonicalForm newcoeff;
+    int newexp;
+    int exp = redterms->exp;
+    termList dummy;
+    while ( first && ( first->exp >= exp ) )
+    {
+        newcoeff = first->coeff * coeff;
+        newexp = first->exp - exp;
+        dummy = first;
+        first = mulAddTermList( first->next, redterms->next, newcoeff, newexp, last, true );
+        delete dummy;
+    }
+    return first;
+}
+
diff --git a/factory/int_poly.h b/factory/int_poly.h
new file mode 100644
index 0000000..d5d0955
--- /dev/null
+++ b/factory/int_poly.h
@@ -0,0 +1,173 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+#ifndef INCL_INT_POLY_H
+#define INCL_INT_POLY_H
+
+/**
+ * @file int_poly.h
+ *
+ * Factory's internal polynomials
+**/
+
+// #include "config.h"
+
+#ifndef NOSTREAMIO
+#ifdef HAVE_IOSTREAM
+#include <iostream>
+#define OSTREAM std::ostream
+#elif defined(HAVE_IOSTREAM_H)
+#include <iostream.h>
+#define OSTREAM ostream
+#endif
+#endif /* NOSTREAMIO */
+
+#include "cf_defs.h"
+#include "int_cf.h"
+#include "variable.h"
+#include "canonicalform.h"
+
+#ifdef HAVE_OMALLOC
+#ifndef OM_NDEBUG
+#define OM_NDEBUG
+#endif
+#  include <omalloc/omalloc.h>
+#endif
+
+class term {
+private:
+    term * next;
+    CanonicalForm coeff;
+    int exp;
+#ifdef HAVE_OMALLOC
+  static const omBin term_bin;
+#endif
+public:
+    term() : next(0), coeff(0), exp(0) {}
+    term( term * n, const CanonicalForm & c, int e ) : next(n), coeff(c), exp(e) {}
+    friend class InternalPoly;
+    friend class CFIterator;
+#ifdef HAVE_OMALLOC
+  void* operator new(size_t)
+    {
+      void* addr;
+      omTypeAllocBin(void*, addr, term_bin);
+      return addr;
+    }
+  void operator delete(void* addr, size_t)
+    {
+      omFreeBin(addr, term_bin);
+    }
+#endif
+};
+
+typedef term * termList;
+
+
+/**
+ * factory's class for polynomials
+ *
+ * polynomials are represented as a linked list termList, factory
+ * uses a sparse distributive representation of polynomials, i.e. each poly
+ * is viewed as a univariate poly in its main variable CanonicalForm::mvar()
+ * over a (polynomial) ring
+**/
+class InternalPoly : public InternalCF {
+private:
+    termList firstTerm, lastTerm;
+    Variable var;
+    InternalPoly( termList, termList, const Variable & );
+
+    static termList copyTermList ( termList, termList&, bool negate = false );
+    static termList deepCopyTermList ( termList, termList& );
+    static void freeTermList ( termList );
+    static void negateTermList ( termList );
+    static termList addTermList ( termList, termList, termList&, bool negate );
+    static void mulTermList ( termList, const CanonicalForm& , const int );
+    static termList divideTermList ( termList, const CanonicalForm&, termList& );
+    static termList divTermList ( termList, const CanonicalForm&, termList& );
+    static termList tryDivTermList ( termList, const CanonicalForm&, termList&, const CanonicalForm&, bool& );
+    static termList modTermList ( termList, const CanonicalForm&, termList& );
+    static void appendTermList ( termList&, termList&, const CanonicalForm&, const int );
+    static termList mulAddTermList ( termList theList, termList aList, const CanonicalForm & c, const int exp, termList & lastTerm, bool negate );
+    static termList reduceTermList ( termList first, termList redterms, termList & last );
+public:
+    InternalPoly();
+    InternalPoly( const Variable & v, const int e, const CanonicalForm& c );
+    InternalPoly( const InternalPoly& );
+    ~InternalPoly();
+    InternalCF* deepCopyObject() const;
+    const char * classname() const { return "InternalPoly"; }
+    int level() const { return var.level(); }
+    Variable variable() const { return var; }
+    int degree();
+    CanonicalForm lc();
+    CanonicalForm Lc();
+    CanonicalForm LC();
+    int taildegree();
+    CanonicalForm tailcoeff();
+    CanonicalForm coeff( int i );
+#ifndef NOSTREAMIO
+    void print( OSTREAM&, char* );
+#endif /* NOSTREAMIO */
+    bool inBaseDomain() const { return false; }
+    bool inExtension() const { return var.level() < 0; }
+    bool inCoeffDomain() const { return var.level() < 0; }
+    bool inPolyDomain() const { return var.level() > 0; }
+    bool inQuotDomain() const { return false; }
+    InternalCF* genZero();
+    InternalCF* genOne();
+
+    bool isUnivariate() const;
+
+    InternalCF* neg();
+    InternalCF* invert();
+    InternalCF* tryInvert( const CanonicalForm&, bool& );
+    int comparesame ( InternalCF* );
+
+    InternalCF* addsame( InternalCF* );
+    InternalCF* subsame( InternalCF* );
+    InternalCF* mulsame( InternalCF* );
+    InternalCF* tryMulsame ( InternalCF*, const CanonicalForm&);
+    InternalCF* dividesame( InternalCF* );
+    InternalCF* modulosame( InternalCF* );
+    InternalCF* divsame( InternalCF* );
+    InternalCF* tryDivsame ( InternalCF*, const CanonicalForm&, bool& );
+    InternalCF* modsame( InternalCF* );
+    void divremsame( InternalCF*, InternalCF*&, InternalCF*& );
+    bool divremsamet( InternalCF*, InternalCF*&, InternalCF*& );
+    bool tryDivremsamet( InternalCF*, InternalCF*&, InternalCF*&, const CanonicalForm&, bool& );
+
+    int comparecoeff ( InternalCF* );
+
+    InternalCF* addcoeff( InternalCF* );
+    InternalCF* subcoeff( InternalCF*, bool );
+    InternalCF* mulcoeff( InternalCF* );
+    InternalCF* dividecoeff( InternalCF*, bool );
+    InternalCF* tryDividecoeff ( InternalCF*, bool, const CanonicalForm&, bool& );
+    InternalCF* modulocoeff( InternalCF*, bool );
+    InternalCF* divcoeff( InternalCF*, bool );
+    InternalCF* tryDivcoeff ( InternalCF*, bool, const CanonicalForm&, bool& );
+    InternalCF* modcoeff( InternalCF*, bool );
+    void divremcoeff( InternalCF*, InternalCF*&, InternalCF*&, bool );
+    bool divremcoefft( InternalCF*, InternalCF*&, InternalCF*&, bool );
+    bool tryDivremcoefft ( InternalCF*, InternalCF*&, InternalCF*&, bool, const CanonicalForm&, bool& );
+
+    int sign() const;
+
+#ifdef HAVE_OMALLOC
+  static const omBin InternalPoly_bin;
+  void* operator new(size_t)
+    {
+      void* addr;
+      omTypeAllocBin(void*, addr, InternalPoly_bin);
+      return addr;
+    }
+  void operator delete(void* addr, size_t)
+    {
+      omFreeBin(addr, InternalPoly_bin);
+    }
+#endif
+    friend class CFIterator;
+};
+
+#endif /* ! INCL_INT_POLY_H */
diff --git a/factory/int_rat.cc b/factory/int_rat.cc
new file mode 100644
index 0000000..9a103bc
--- /dev/null
+++ b/factory/int_rat.cc
@@ -0,0 +1,912 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+
+#include "config.h"
+
+
+#include "cf_assert.h"
+
+#include "cf_defs.h"
+#include "int_rat.h"
+#include "int_int.h"
+#include "imm.h"
+#include "canonicalform.h"
+#include "cf_factory.h"
+#include "gmpext.h"
+
+static long intgcd( long a, long b )
+{
+    if ( a < 0 ) a = -a;
+    if ( b < 0 ) b = -b;
+
+    long c;
+
+    while ( b != 0 )
+    {
+        c = a % b;
+        a = b;
+        b = c;
+    }
+    return a;
+}
+
+
+InternalRational::InternalRational()
+{
+    mpz_init( _num );
+    mpz_init_set_si( _den, 1 );
+}
+
+InternalRational::InternalRational( const int i )
+{
+    mpz_init_set_si( _num, i );
+    mpz_init_set_si( _den, 1 );
+}
+
+InternalRational::InternalRational( const int n, const int d )
+{
+    ASSERT( d != 0, "divide by zero" );
+    if ( n == 0 )
+    {
+        mpz_init_set_si( _num, 0 );
+        mpz_init_set_si( _den, 1 );
+    }
+    else
+    {
+        long g = intgcd( (long) n, (long) d );
+        if ( d < 0 )
+        {
+          mpz_init_set_si( _num, -((long)n) / g );
+          mpz_init_set_si( _den, -((long)d) / g );
+        }
+        else
+        {
+          mpz_init_set_si( _num, n / g );
+          mpz_init_set_si( _den, d / g );
+        }
+    }
+}
+
+InternalRational::InternalRational( const long i )
+{
+    mpz_init_set_si( _num, i );
+    mpz_init_set_si( _den, 1 );
+}
+
+InternalRational::InternalRational( const long n, const long d )
+{
+    ASSERT( d != 0, "divide by zero" );
+    if ( n == 0 )
+    {
+        mpz_init_set_si( _num, 0 );
+        mpz_init_set_si( _den, 1 );
+    }
+    else
+    {
+        long g = intgcd( n, d );
+        if ( d < 0 )
+        {
+          mpz_init_set_si( _num, -n / g );
+          mpz_init_set_si( _den, -d / g );
+        }
+        else
+        {
+          mpz_init_set_si( _num, n / g );
+          mpz_init_set_si( _den, d / g );
+        }
+    }
+}
+
+InternalRational::InternalRational( const char * )
+{
+    // sollte nicht gebraucht werden !!!
+    ASSERT( 0, "fatal error" );
+    mpz_init( _num );
+    mpz_init( _den );
+}
+
+//InternalRational::InternalRational( const mpz_ptr n ) : _num(n)
+//{
+//    mpz_init_set_si( _den, 1 );
+//}
+
+InternalRational::InternalRational( const mpz_ptr n )
+{
+    _num[0]=*n;
+    mpz_init_set_si( _den, 1 );
+}
+
+InternalRational::InternalRational( const mpz_ptr n, const mpz_ptr d )
+{
+  _num[0]=*n;
+  _den[0]=*d;
+}
+
+InternalRational::~InternalRational()
+{
+    mpz_clear( _num );
+    mpz_clear( _den );
+}
+
+InternalCF* InternalRational::deepCopyObject() const
+{
+    mpz_t dummy_num;
+    mpz_t dummy_den;
+    mpz_init_set( dummy_num, _num );
+    mpz_init_set( dummy_den, _den );
+    return new InternalRational( dummy_num, dummy_den );
+}
+
+#ifndef NOSTREAMIO
+void InternalRational::print( OSTREAM & os, char * c )
+{
+    char * str = new char[mpz_sizeinbase( _num, 10 ) + 2];
+    str = mpz_get_str( str, 10, _num );
+    os << str << '/';
+    delete [] str;
+    str = new char[mpz_sizeinbase( _den, 10 ) + 2];
+    str = mpz_get_str( str, 10, _den );
+    os << str << c;
+    delete [] str;
+}
+#endif /* NOSTREAMIO */
+
+bool InternalRational::is_imm() const
+{
+    return mpz_cmp_si( _den, 1 ) == 0 && mpz_is_imm( _num );
+}
+
+InternalCF* InternalRational::genZero()
+{
+    if ( isZero() )
+        return copyObject();
+    else
+        return new InternalRational();
+}
+
+InternalCF* InternalRational::genOne()
+{
+    if ( isOne() )
+        return copyObject();
+    else
+        return new InternalRational( 1 );
+}
+
+/**
+ * @sa CanonicalForm::num(), CanonicalForm::den(), InternalRational::den()
+**/
+InternalCF * InternalRational::num ()
+{
+    if ( mpz_is_imm( _num ) )
+    {
+        InternalCF * res = int2imm( mpz_get_si( _num ) );
+        return res;
+    }
+    else
+    {
+        mpz_t dummy;
+        mpz_init_set( dummy, _num );
+        return new InternalInteger( dummy );
+    }
+}
+
+/**
+ * @sa CanonicalForm::num(), CanonicalForm::den(), InternalRational::num()
+**/
+InternalCF * InternalRational::den ()
+{
+    if ( mpz_is_imm( _den ) )
+    {
+        InternalCF * res = int2imm( mpz_get_si( _den ) );
+        return res;
+    }
+    else
+    {
+        mpz_t dummy;
+        mpz_init_set( dummy, _den );
+        return new InternalInteger( dummy );
+    }
+}
+
+/** InternalCF * InternalRational::neg ()
+ * @sa CanonicalForm::operator -()
+**/
+InternalCF *
+InternalRational::neg ()
+{
+    if ( getRefCount() > 1 )
+    {
+        decRefCount();
+        mpz_t dummy_num;
+        mpz_t dummy_den;
+        mpz_init_set( dummy_num, _num );
+        mpz_init_set( dummy_den, _den );
+        mpz_neg( dummy_num, dummy_num );
+        return new InternalRational( dummy_num, dummy_den );
+    }
+    else
+    {
+        mpz_neg( _num, _num );
+        return this;
+    }
+}
+
+InternalCF* InternalRational::addsame( InternalCF * c )
+{
+    ASSERT( ! ::is_imm( c ) && c->levelcoeff() == RationalDomain, "illegal domain" );
+    mpz_t n, d, g;
+
+    mpz_init( g ); mpz_init( n ); mpz_init( d );
+    mpz_gcd( g, _den, MPQDEN( c ) );
+
+    if ( mpz_cmp_si( g, 1 ) == 0 )
+    {
+      mpz_mul( n, _den, MPQNUM( c ) );
+      mpz_mul( g, _num, MPQDEN( c ) );
+      mpz_add( n, n, g );
+      mpz_mul( d, _den, MPQDEN( c ) );
+    }
+    else
+    {
+      mpz_t tmp1;
+      mpz_t tmp2;
+      mpz_init( tmp1 );
+      mpz_divexact( tmp1, _den, g );
+      mpz_init( tmp2 );
+      mpz_divexact( tmp2, MPQDEN( c ), g );
+      mpz_mul( d, tmp2, _den );
+      mpz_mul( tmp2, tmp2, _num );
+      mpz_mul( tmp1, tmp1, MPQNUM( c ) );
+      mpz_add( n, tmp1, tmp2 );
+      mpz_gcd( g, n, d );
+      if ( mpz_cmp_si( g, 1 ) != 0 )
+      {
+          mpz_divexact( n, n, g );
+          mpz_divexact( d, d, g );
+      }
+      mpz_clear( tmp1 );
+      mpz_clear( tmp2 );
+    }
+    mpz_clear( g );
+    if ( deleteObject() ) delete this;
+    if ( mpz_cmp_si( d, 1 ) == 0 )
+    {
+      mpz_clear( d );
+      if ( mpz_is_imm( n ) )
+      {
+          InternalCF * res = int2imm( mpz_get_si( n ) );
+          mpz_clear( n );
+          return res;
+      }
+      else
+      {
+          return new InternalInteger( n );
+      }
+    }
+    else
+    {
+      return new InternalRational( n, d );
+    }
+}
+
+InternalCF* InternalRational::subsame( InternalCF * c )
+{
+    ASSERT( ! ::is_imm( c ) && c->levelcoeff() == RationalDomain, "illegal domain" );
+    mpz_t n, d, g;
+
+    mpz_init( g ); mpz_init( n ); mpz_init( d );
+    mpz_gcd( g, _den, MPQDEN( c ) );
+
+    if ( mpz_cmp_si( g, 1 ) == 0 )
+    {
+        mpz_mul( n, _den, MPQNUM( c ) );
+        mpz_mul( g, _num, MPQDEN( c ) );
+        mpz_sub( n, g, n );
+        mpz_mul( d, _den, MPQDEN( c ) );
+    }
+    else
+    {
+        mpz_t tmp1;
+        mpz_t tmp2;
+        mpz_init( tmp1 );
+        mpz_divexact( tmp1, _den, g );
+        mpz_init( tmp2 );
+        mpz_divexact( tmp2, MPQDEN( c ), g );
+        mpz_mul( d, tmp2, _den );
+        mpz_mul( tmp2, tmp2, _num );
+        mpz_mul( tmp1, tmp1, MPQNUM( c ) );
+        mpz_sub( n, tmp2, tmp1 );
+        mpz_gcd( g, n, d );
+        if ( mpz_cmp_si( g, 1 ) != 0 )
+        {
+            mpz_divexact( n, n, g );
+            mpz_divexact( d, d, g );
+        }
+        mpz_clear( tmp1 );
+        mpz_clear( tmp2 );
+    }
+    mpz_clear( g );
+    if ( deleteObject() ) delete this;
+    if ( mpz_cmp_si( d, 1 ) == 0 )
+    {
+        mpz_clear( d );
+        if ( mpz_is_imm( n ) )
+        {
+            InternalCF * res = int2imm( mpz_get_si( n ) );
+            mpz_clear( n );
+            return res;
+        }
+        else
+        {
+            return new InternalInteger( n );
+        }
+    }
+    else
+        return new InternalRational( n, d );
+}
+
+InternalCF* InternalRational::mulsame( InternalCF * c )
+{
+    ASSERT( ! ::is_imm( c ) && c->levelcoeff() == RationalDomain, "illegal domain" );
+    mpz_t n, d;
+    mpz_init( n ); mpz_init( d );
+
+    if ( this == c )
+    {
+        mpz_mul( n, _num, _num );
+        mpz_mul( d, _den, _den );
+    }
+    else
+    {
+        mpz_t g1, g2, tmp1, tmp2;
+        mpz_init( g1 ); mpz_init( g2 );
+        mpz_gcd( g1, _num, MPQDEN( c ) );
+        mpz_gcd( g2, _den, MPQNUM( c ) );
+        bool g1is1 = mpz_cmp_si( g1, 1 ) == 0;
+        bool g2is1 = mpz_cmp_si( g2, 1 ) == 0;
+        mpz_init( tmp1 ); mpz_init( tmp2 );
+        if ( ! g1is1 )
+            mpz_divexact( tmp1, _num, g1 );
+        else
+            mpz_set( tmp1, _num );
+        if ( ! g2is1 )
+            mpz_divexact( tmp2, MPQNUM( c ), g2 );
+        else
+            mpz_set( tmp2, MPQNUM( c ) );
+        mpz_mul( n, tmp1, tmp2 );
+        if ( ! g1is1 )
+            mpz_divexact( tmp1, MPQDEN( c ), g1 );
+        else
+            mpz_set( tmp1, MPQDEN( c ) );
+        if ( ! g2is1 )
+            mpz_divexact( tmp2, _den, g2 );
+        else
+            mpz_set( tmp2, _den );
+        mpz_mul( d, tmp1, tmp2 );
+        mpz_clear( tmp1 ); mpz_clear( tmp2 );
+        mpz_clear( g1 ); mpz_clear( g2 );
+    }
+    if ( deleteObject() ) delete this;
+    if ( mpz_cmp_si( d, 1 ) == 0 )
+    {
+        mpz_clear( d );
+        if ( mpz_is_imm( n ) )
+        {
+            InternalCF * res = int2imm( mpz_get_si( n ) );
+            mpz_clear( n );
+            return res;
+        }
+        else
+        {
+            return new InternalInteger( n );
+        }
+    }
+    else
+        return new InternalRational( n, d );
+}
+
+InternalCF* InternalRational::dividesame( InternalCF * c )
+{
+    ASSERT( ! ::is_imm( c ) && c->levelcoeff() == RationalDomain, "illegal domain" );
+
+    if ( this == c )
+    {
+        if ( deleteObject() ) delete this;
+        return CFFactory::basic( 1L );
+    }
+    else
+    {
+        mpz_t n, d;
+        mpz_t g1, g2, tmp1, tmp2;
+        mpz_init( n ); mpz_init( d );
+        mpz_init( g1 ); mpz_init( g2 );
+        mpz_gcd( g1, _num, MPQNUM( c ) );
+        mpz_gcd( g2, _den, MPQDEN( c ) );
+        bool g1is1 = mpz_cmp_si( g1, 1 ) == 0;
+        bool g2is1 = mpz_cmp_si( g2, 1 ) == 0;
+        mpz_init( tmp1 ); mpz_init( tmp2 );
+        if ( ! g1is1 )
+            mpz_divexact( tmp1, _num, g1 );
+        else
+            mpz_set( tmp1, _num );
+        if ( ! g2is1 )
+            mpz_divexact( tmp2, MPQDEN( c ), g2 );
+        else
+            mpz_set( tmp2, MPQDEN( c ) );
+        mpz_mul( n, tmp1, tmp2 );
+        if ( ! g1is1 )
+            mpz_divexact( tmp1, MPQNUM( c ), g1 );
+        else
+            mpz_set( tmp1, MPQNUM( c ) );
+        if ( ! g2is1 )
+            mpz_divexact( tmp2, _den, g2 );
+        else
+            mpz_set( tmp2, _den );
+        mpz_mul( d, tmp1, tmp2 );
+        mpz_clear( tmp1 ); mpz_clear( tmp2 );
+        mpz_clear( g1 ); mpz_clear( g2 );
+        if ( deleteObject() ) delete this;
+        if ( mpz_cmp_si( d, 0 ) < 0 )
+        {
+            mpz_neg( d, d );
+            mpz_neg( n, n );
+        }
+        if ( mpz_cmp_si( d, 1 ) == 0 )
+        {
+            mpz_clear( d );
+            if ( mpz_is_imm( n ) )
+            {
+                InternalCF * res = int2imm( mpz_get_si( n ) );
+                mpz_clear( n );
+                return res;
+            }
+            else
+            {
+                return new InternalInteger( n );
+            }
+        }
+        else
+            return new InternalRational( n, d );
+    }
+}
+
+InternalCF* InternalRational::divsame( InternalCF * c )
+{
+    return dividesame( c );
+}
+
+InternalCF* InternalRational::modulosame( InternalCF * c )
+{
+    return modsame( c );
+}
+
+InternalCF* InternalRational::modsame( InternalCF * )
+{
+    if ( deleteObject() ) delete this;
+    return CFFactory::basic( 0L );
+}
+
+void InternalRational::divremsame( InternalCF * c, InternalCF*& quot, InternalCF*& rem )
+{
+    quot = copyObject();
+    quot = quot->dividesame( c );
+    rem = CFFactory::basic( 0L );
+}
+
+bool InternalRational::divremsamet( InternalCF* c, InternalCF*& quot, InternalCF*& rem )
+{
+    divremsame( c, quot, rem );
+    return true;
+}
+
+/**
+ * comparesame(), comparecoeff() - compare with an
+ *   InternalRational.
+ *
+ * comparesame() compares the CO=a/b and c=p/q using the
+ * equivalence a/b < p/q iff a*q < p*b.
+ *
+ * Note: May be relatively expensive due to the
+ * multiplications.
+ *
+ * See also: CanonicalForm::operator <(), CanonicalForm::operator ==()
+ *
+**/
+int
+InternalRational::comparesame ( InternalCF * c )
+{
+    ASSERT( ! ::is_imm( c ) && c->levelcoeff() == RationalDomain, "incompatible base coefficients" );
+    mpz_t dummy1, dummy2;
+    mpz_init( dummy1 ); mpz_init( dummy2 );
+    mpz_mul( dummy1, _num, MPQDEN( c ) );
+    mpz_mul( dummy2, _den, MPQNUM( c ) );
+    int result = mpz_cmp( dummy1, dummy2 );
+    mpz_clear( dummy1 ); mpz_clear( dummy2 );
+    return result;
+}
+
+/**
+ * comparecoeff() compares the CO=a/b and the integer c using the
+ * equivalence a/b < c iff a < c*b.
+ *
+ * Note: May be relatively expensive due to the
+ * multiplications.
+**/
+int
+InternalRational::comparecoeff ( InternalCF* c )
+{
+    if ( ::is_imm( c ) )
+    {
+        ASSERT( ::is_imm( c ) == INTMARK, "incompatible base coefficients" );
+        mpz_t dummy;
+        mpz_init_set_si( dummy, imm2int( c ) );
+        mpz_mul( dummy, dummy, _den );
+        int result = mpz_cmp( _num, dummy );
+        mpz_clear( dummy );
+        return result;
+    }
+    else
+    {
+        ASSERT( c->levelcoeff() == IntegerDomain, "incompatible base coefficients" );
+        mpz_t dummy;
+        mpz_init( dummy );
+        mpz_mul( dummy, _den, InternalInteger::MPI( c ) );
+        int result = mpz_cmp( _num, dummy );
+        mpz_clear( dummy );
+        return result;
+    }
+}
+
+InternalCF* InternalRational::addcoeff( InternalCF* c )
+{
+    ASSERT( ::is_imm( c ) == INTMARK || ! ::is_imm( c ), "expected integer" );
+    mpz_t n, d;
+    if ( ::is_imm( c ) )
+    {
+        long cc = imm2int( c );
+        if ( cc == 0 )
+            return this;
+        else
+	{
+          mpz_init( n );
+	  if ( cc < 0 )
+          {
+            mpz_mul_ui( n, _den, -cc );
+            mpz_sub( n, _num, n );
+          }
+          else
+          {
+            mpz_mul_ui( n, _den, cc );
+            mpz_add( n, _num, n );
+          }
+	}
+    }
+    else
+    {
+        ASSERT( c->levelcoeff() == IntegerDomain, "expected integer" );
+        mpz_init( n );
+        mpz_mul( n, _den, InternalInteger::MPI( c ) );
+        mpz_add( n, _num, n );
+    }
+    mpz_init_set( d, _den );
+    // at this point there is no way that the result is not a true rational
+    if ( deleteObject() ) delete this;
+    return new InternalRational( n, d );
+}
+
+InternalCF* InternalRational::subcoeff( InternalCF* c, bool negate )
+{
+    ASSERT( ::is_imm( c ) == INTMARK || ! ::is_imm( c ), "expected integer" );
+    mpz_t n, d;
+    if ( ::is_imm( c ) )
+    {
+        long cc = imm2int( c );
+        if ( cc == 0 )
+        {
+            if ( negate )
+            {
+                if ( getRefCount() == 1 )
+                {
+                    mpz_neg( _num, _num );
+                    return this;
+                }
+                else
+                {
+                    decRefCount();
+                    mpz_init_set( d, _den );
+                    mpz_init_set( n, _num );
+                    mpz_neg( n, n );
+                    return new InternalRational( n, d );
+                }
+            }
+            else
+                return this;
+        }
+        mpz_init( n );
+        if ( cc < 0 )
+        {
+            mpz_mul_ui( n, _den, -cc );
+            mpz_neg( n, n );
+        }
+        else
+            mpz_mul_ui( n, _den, cc );
+        if ( negate )
+            mpz_sub( n, n, _num );
+        else
+            mpz_sub( n, _num, n );
+    }
+    else
+    {
+        ASSERT( c->levelcoeff() == IntegerDomain, "expected integer" );
+        mpz_init( n );
+        mpz_mul( n, _den, InternalInteger::MPI( c ) );
+        if ( negate )
+            mpz_sub( n, n, _num );
+        else
+            mpz_sub( n, _num, n );
+    }
+    mpz_init_set( d, _den );
+    // at this point there is no way that the result is not a true rational
+    if ( deleteObject() ) delete this;
+    return new InternalRational( n, d );
+}
+
+InternalCF* InternalRational::mulcoeff( InternalCF* c )
+{
+    ASSERT( ::is_imm( c ) == INTMARK || ! ::is_imm( c ), "expected integer" );
+    mpz_t n, d, g;
+    if ( ::is_imm( c ) )
+    {
+        long cc = imm2int( c );
+        if ( cc == 0 )
+        {
+            if ( deleteObject() ) delete this;
+            return CFFactory::basic( 0L );
+        }
+        mpz_init_set_si( n, cc );
+    }
+    else
+    {
+        ASSERT( c->levelcoeff() == IntegerDomain, "expected integer" );
+        mpz_init_set( n, InternalInteger::MPI( c ) );
+    }
+    mpz_init( g );
+    mpz_gcd( g, n, _den );
+    if ( mpz_cmp_si( g, 1 ) == 0 )
+    {
+        mpz_mul( n, n, _num );
+        mpz_init_set( d, _den );
+    }
+    else
+    {
+        mpz_divexact( n, n, g );
+        mpz_mul( n, n, _num );
+        mpz_init( d );
+        mpz_divexact( d, _den, g );
+    }
+    mpz_clear( g );
+    if ( deleteObject() ) delete this;
+    if ( mpz_cmp_si( d, 1 ) == 0 )
+    {
+        mpz_clear( d );
+        if ( mpz_is_imm( n ) )
+        {
+            InternalCF * res = int2imm( mpz_get_si( n ) );
+            mpz_clear( n );
+            return res;
+        }
+        else
+        {
+            return new InternalInteger( n );
+        }
+    }
+    else
+        return new InternalRational( n, d );
+}
+
+InternalCF* InternalRational::dividecoeff( InternalCF* c, bool invert )
+{
+    ASSERT( ::is_imm( c ) == INTMARK || ! ::is_imm( c ), "expected integer" );
+    mpz_t n, d, g;
+    if ( ::is_imm( c ) )
+    {
+        long cc = imm2int( c );
+        ASSERT( c != 0 || invert, "divide by zero" );
+        if ( cc == 0 )
+        {
+            // => invert
+            if ( deleteObject() ) delete this;
+            return CFFactory::basic( 0L );
+        }
+        if ( invert )
+        {
+            mpz_init_set_si( n, cc );
+            mpz_mul( n, n, _den );
+            mpz_init_set( d, _num );
+        }
+        else
+        {
+            mpz_init_set_si( d, cc );
+            mpz_mul( d, d, _den );
+            mpz_init_set( n, _num );
+        }
+    }
+    else
+    {
+        ASSERT( c->levelcoeff() == IntegerDomain, "expected integer" );
+        if ( invert )
+        {
+            mpz_init_set( n, InternalInteger::MPI( c ) );
+            mpz_mul( n, n, _den );
+            mpz_init_set( d, _num );
+        }
+        else
+        {
+            mpz_init_set( d, InternalInteger::MPI( c ) );
+            mpz_mul( d, d, _den );
+            mpz_init_set( n, _num );
+        }
+    }
+    if ( mpz_cmp_si( d, 0 ) < 0 )
+    {
+        mpz_neg( d, d );
+        mpz_neg( n, n );
+    }
+    mpz_init( g );
+    mpz_gcd( g, n, d );
+    if ( mpz_cmp_si( g, 1 ) != 0 )
+    {
+        mpz_divexact( d, d, g );
+        mpz_divexact( n, n, g );
+    }
+    mpz_clear( g );
+    if ( deleteObject() ) delete this;
+    if ( ! invert )
+    {
+        // then there was no way for the result to become an integer
+        return new InternalRational( n, d );
+    }
+    if ( mpz_cmp_si( d, 1 ) == 0 )
+    {
+        mpz_clear( d );
+        if ( mpz_is_imm( n ) )
+        {
+            InternalCF * res = int2imm( mpz_get_si( n ) );
+            mpz_clear( n );
+            return res;
+        }
+        else
+        {
+            return new InternalInteger( n );
+        }
+    }
+    else
+        return new InternalRational( n, d );
+}
+
+InternalCF* InternalRational::divcoeff( InternalCF* c, bool invert )
+{
+    return dividecoeff( c, invert );
+}
+
+InternalCF* InternalRational::modulocoeff( InternalCF* c, bool invert )
+{
+    return modcoeff( c, invert );
+}
+
+InternalCF* InternalRational::modcoeff( InternalCF* c, bool invert )
+{
+    ASSERT( ::is_imm( c ) == INTMARK || ! ::is_imm( c ), "integer expected" );
+    ASSERT( invert || ! ::is_imm( c ) || imm2int( c ) != 0, "divide by zero" );
+    if ( deleteObject() ) delete this;
+    return CFFactory::basic( 0L );
+}
+
+void InternalRational::divremcoeff( InternalCF* c, InternalCF*& quot, InternalCF*& rem, bool invert )
+{
+    quot = copyObject();
+    quot = quot->dividecoeff( c, invert );
+    rem = CFFactory::basic( 0L );
+}
+
+bool InternalRational::divremcoefft( InternalCF* c, InternalCF*& quot, InternalCF*& rem, bool invert )
+{
+    divremcoeff( c, quot, rem, invert );
+    return true;
+}
+
+/**
+ * @sa CanonicalForm::bgcd(), InternalRational::bgcdcoeff()
+**/
+InternalCF *
+InternalRational::bgcdsame ( const InternalCF * const ) const
+{
+    return int2imm( 1 );
+}
+
+/**
+ * @sa CanonicalForm::bgcd(), InternalRational::bgcdsame()
+**/
+InternalCF *
+InternalRational::bgcdcoeff ( const InternalCF * const )
+{
+    return int2imm( 1 );
+}
+
+/**
+ * @sa CanonicalForm::bextgcd(), InternalRational::bextgcdcoeff()
+**/
+InternalCF *
+InternalRational::bextgcdsame ( InternalCF *, CanonicalForm & a, CanonicalForm & b )
+{
+    a = 1/CanonicalForm( copyObject() ); b = 0;
+    return int2imm( 1 );
+}
+
+/**
+ * @sa CanonicalForm::bextgcd(), InternalRational::bextgcdsame()
+**/
+InternalCF *
+InternalRational::bextgcdcoeff ( InternalCF *, CanonicalForm & a, CanonicalForm & b )
+{
+    a = 1/CanonicalForm( copyObject() ); b = 0;
+    return int2imm( 1 );
+}
+
+/**
+ * reduce InternalRational to lowest terms
+**/
+InternalCF * InternalRational::normalize_myself()
+{
+    ASSERT( getRefCount() == 1, "illegal operation" );
+    mpz_t g;
+    mpz_init( g );
+    mpz_gcd( g, _num, _den );
+    if ( mpz_cmp_si( g, 1 ) != 0 )
+    {
+        mpz_divexact( _num, _num, g );
+        mpz_divexact( _den, _den, g );
+    }
+    mpz_clear( g );
+    if ( mpz_cmp_si( _den, 0 ) < 0 )
+    {
+        mpz_neg( _num, _num );
+        mpz_neg( _den, _den );
+    }
+    if ( mpz_cmp_si( _den, 1 ) == 0 )
+    {
+        if ( mpz_is_imm( _num ) )
+        {
+            InternalCF * res = int2imm( mpz_get_si( _num ) );
+            delete this;
+            return res;
+        }
+        else
+        {
+            mpz_t res;
+            mpz_init_set( res, _num );
+            delete this;
+            return new InternalInteger( res );
+        }
+    }
+    else
+        return this;
+}
+
+
+long InternalRational::intval() const
+{
+
+    ASSERT( mpz_cmp_si( _den, 1 ) == 0, "illegal operation" );
+    return mpz_get_si( _num );
+
+}
+
+/**
+ * @sa CanonicalForm::sign()
+**/
+int
+InternalRational::sign () const
+{
+    return mpz_sgn( _num );
+}
diff --git a/factory/int_rat.h b/factory/int_rat.h
new file mode 100644
index 0000000..97fe5ed
--- /dev/null
+++ b/factory/int_rat.h
@@ -0,0 +1,130 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+#ifndef INCL_INT_RAT_H
+#define INCL_INT_RAT_H
+
+/**
+ * @file int_rat.h
+ *
+ * Factory's internal rationals
+**/
+// #include "config.h"
+
+#ifndef NOSTREAMIO
+#ifdef HAVE_IOSTREAM
+#include <iostream>
+#define OSTREAM std::ostream
+#elif defined(HAVE_IOSTREAM_H)
+#include <iostream.h>
+#define OSTREAM ostream
+#endif
+#endif /* NOSTREAMIO */
+
+#include "cf_assert.h"
+
+#include "canonicalform.h"
+#include "int_cf.h"
+#include "imm.h"
+// #include <factory/cf_gmp.h>
+
+/**
+ * factory's class for rationals
+ *
+ * a rational is represented as two mpz_t's _num, _den
+ *
+ * Note: If you want to compute over Q make sure that SW_RATIONAL is set to 1!
+ *
+ * @sa InternalInteger
+**/
+class InternalRational : public InternalCF
+{
+private:
+    mpz_t _num;
+    mpz_t _den;
+    static int initialized;
+    static mpz_ptr MPQNUM( const InternalCF * const c );
+    static mpz_ptr MPQDEN( const InternalCF * const c );
+    static void normalize( const mpz_ptr, const mpz_ptr, mpz_ptr, mpz_ptr );
+public:
+    InternalRational();
+    InternalRational( const InternalCF& )
+    {
+	ASSERT( 0, "ups there is something wrong in your code" );
+    }
+    InternalRational( const int i );
+    InternalRational( const int n, const int d );
+    InternalRational( const long i );
+    InternalRational( const long n, const long d );
+    InternalRational( const char * str );
+    InternalRational( const mpz_ptr );
+    InternalRational( const mpz_ptr , const mpz_ptr );
+    ~InternalRational();
+    InternalCF* deepCopyObject() const;
+    const char * classname() const { return "InternalRational"; }
+#ifndef NOSTREAMIO
+    void print( OSTREAM&, char* );
+#endif /* NOSTREAMIO */
+    InternalCF* genZero();
+    InternalCF* genOne();
+
+    bool is_imm() const;
+    int levelcoeff() const { return RationalDomain; }
+
+    InternalCF* num();
+    InternalCF* den();
+
+    InternalCF* neg();
+
+    int comparesame( InternalCF* );
+
+    InternalCF* addsame( InternalCF* );
+    InternalCF* subsame( InternalCF* );
+    InternalCF* mulsame( InternalCF* );
+    InternalCF* dividesame( InternalCF* );
+    InternalCF* modulosame( InternalCF* );
+    InternalCF* divsame( InternalCF* );
+    InternalCF* modsame( InternalCF* );
+    void divremsame( InternalCF*, InternalCF*&, InternalCF*& );
+    bool divremsamet( InternalCF*, InternalCF*&, InternalCF*& );
+
+    int comparecoeff( InternalCF* );
+
+    InternalCF* addcoeff( InternalCF* );
+    InternalCF* subcoeff( InternalCF*, bool );
+    InternalCF* mulcoeff( InternalCF* );
+    InternalCF* dividecoeff( InternalCF*, bool );
+    InternalCF* modulocoeff( InternalCF*, bool );
+    InternalCF* divcoeff( InternalCF*, bool );
+    InternalCF* modcoeff( InternalCF*, bool );
+    void divremcoeff( InternalCF*, InternalCF*&, InternalCF*&, bool );
+    bool divremcoefft( InternalCF*, InternalCF*&, InternalCF*&, bool );
+
+    InternalCF * bgcdsame ( const InternalCF * const ) const;
+    InternalCF * bgcdcoeff ( const InternalCF * const );
+
+    InternalCF * bextgcdsame ( InternalCF *, CanonicalForm &, CanonicalForm & );
+    InternalCF * bextgcdcoeff ( InternalCF *, CanonicalForm &, CanonicalForm & );
+
+    long intval() const;
+
+    int sign() const;
+
+    InternalCF * normalize_myself();
+
+    friend class InternalInteger;
+    friend void gmp_numerator ( const CanonicalForm & f, mpz_ptr result );
+    friend void gmp_denominator ( const CanonicalForm & f, mpz_ptr result );
+    friend CanonicalForm make_cf ( const mpz_ptr n, const mpz_ptr d );
+};
+
+inline mpz_ptr InternalRational::MPQNUM( const InternalCF * const c )
+{
+    return (((InternalRational*)c)->_num);
+}
+
+inline mpz_ptr InternalRational::MPQDEN( const InternalCF * const c )
+{
+    return (((InternalRational*)c)->_den);
+}
+
+#endif /* ! INCL_INT_RAT_H */
diff --git a/factory/make_factory_dist b/factory/make_factory_dist
new file mode 100644
index 0000000..b090378
--- /dev/null
+++ b/factory/make_factory_dist
@@ -0,0 +1,9 @@
+#!/bin/sh
+cp -r ../m4 m4
+sed -e 's:AC_CONFIG_AUX_DIR.*:AC_CONFIG_AUX_DIR([.]):' <configure.ac >c.ac
+sed -e 's:AC_CONFIG_MACRO_DIR.*:AC_CONFIG_MACRO_DIR([m4]):' <c.ac >configure.ac
+sed -e 's:ACLOCAL_AMFLAGS.*:ACLOCAL_AMFLAGS = -I m4:' <Makefile.am >m.am
+mv m.am Makefile.am
+autoreconf  -v -f -i
+make dist
+
diff --git a/factory/parseutil.cc b/factory/parseutil.cc
new file mode 100644
index 0000000..64ebc27
--- /dev/null
+++ b/factory/parseutil.cc
@@ -0,0 +1,160 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+
+#include "config.h"
+
+
+#include <string.h>
+#include <stdlib.h>
+
+#include "cf_assert.h"
+
+#include "cf_defs.h"
+#include "parseutil.h"
+
+class PUtilBase
+{
+public:
+    PUtilBase() {};
+    virtual ~PUtilBase() {}
+    virtual PUtilBase * copy() const = 0;
+    virtual CanonicalForm getval() const = 0;
+    virtual int getintval() const = 0;
+    virtual bool isInt() const = 0;
+    virtual bool isCF() const = 0;
+    virtual bool isVar() const = 0;
+};
+
+class PUtilInt : public PUtilBase
+{
+private:
+    int val;
+public:
+    PUtilInt() { val = 0; }
+    PUtilInt( int i ) { val = i; }
+    ~PUtilInt() {}
+    PUtilBase * copy() const { return new PUtilInt( val ); }
+    CanonicalForm getval() const { return CanonicalForm( val ); }
+    int getintval() const { return val; }
+    bool isInt() const { return true; }
+    bool isCF() const { return false; }
+    bool isVar() const { return false; }
+};
+
+class PUtilCF : public PUtilBase
+{
+private:
+    CanonicalForm val;
+public:
+    PUtilCF() { val = 0; }
+    PUtilCF( const CanonicalForm & cf ) { val = cf; }
+    ~PUtilCF() {}
+    PUtilBase * copy() const { return new PUtilCF( val ); }
+    CanonicalForm getval() const { return val; }
+    int getintval() const { return val.intval(); }
+    bool isInt() const { return false; }
+    bool isCF() const { return true; }
+    bool isVar() const { return false; }
+};
+
+class PUtilVar : public PUtilBase
+{
+private:
+    Variable val;
+public:
+    PUtilVar() { val = Variable(); }
+    PUtilVar( const Variable & v ) { val = v; }
+    ~PUtilVar() {}
+    PUtilBase * copy() const { return new PUtilVar( val ); }
+    CanonicalForm getval() const { return CanonicalForm( val ); }
+    int getintval() const { return 0; }
+    bool isInt() const { return false; }
+    bool isCF() const { return false; }
+    bool isVar() const { return true; }
+};
+
+class PUtilFactory
+{
+public:
+    static PUtilBase * create( ) { return new PUtilInt( 0 ); }
+    static PUtilBase * create( int val ) { return new PUtilInt( val ); }
+    static PUtilBase * create( const CanonicalForm & cf ) { return new PUtilCF( cf ); }
+    static PUtilBase * create( const Variable & v ) { return new PUtilVar( v ); }
+    static PUtilBase * create( const char * str )
+    {
+	if ( strlen( str ) < 9 )
+	    return new PUtilInt( atoi( str ) );
+	else
+	    return new PUtilCF( CanonicalForm( str ) );
+    }
+};
+
+ParseUtil::ParseUtil()
+{
+    value = PUtilFactory::create();
+}
+
+ParseUtil::ParseUtil( const ParseUtil &pu )
+{
+    value = pu.value->copy();
+}
+
+ParseUtil::ParseUtil( const CanonicalForm &f )
+{
+    value = PUtilFactory::create( f );
+}
+
+ParseUtil::ParseUtil( int i )
+{
+    value = PUtilFactory::create( i );
+}
+
+ParseUtil::ParseUtil( char * str )
+{
+    value = PUtilFactory::create( str );
+}
+
+ParseUtil::~ParseUtil()
+{
+    delete value;
+}
+
+ParseUtil& ParseUtil::operator= ( const ParseUtil &pu )
+{
+    if ( this != &pu ) {
+	delete value;
+	value = pu.value->copy();
+    }
+    return *this;
+}
+
+ParseUtil& ParseUtil::operator= ( const CanonicalForm &f )
+{
+    delete value;
+    value = PUtilFactory::create( f );
+    return *this;
+}
+
+ParseUtil& ParseUtil::operator= ( int i )
+{
+    delete value;
+    value = PUtilFactory::create( i );
+    return *this;
+}
+
+ParseUtil& ParseUtil::operator= ( const Variable & v )
+{
+    delete value;
+    value = PUtilFactory::create( v );
+    return *this;
+}
+
+CanonicalForm ParseUtil::getval()
+{
+    return value->getval();
+}
+
+int ParseUtil::getintval()
+{
+    return value->getintval();
+}
diff --git a/factory/parseutil.h b/factory/parseutil.h
new file mode 100644
index 0000000..4c03ce6
--- /dev/null
+++ b/factory/parseutil.h
@@ -0,0 +1,34 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+#ifndef INCL_PARSEUTIL_H
+#define INCL_PARSEUTIL_H
+
+// #include "config.h"
+
+#include "cf_defs.h"
+#include "canonicalform.h"
+#include "variable.h"
+
+class PUtilBase;
+
+class ParseUtil
+{
+private:
+    PUtilBase * value;
+public:
+    ParseUtil();
+    ParseUtil( const ParseUtil & );
+    ParseUtil( const CanonicalForm & );
+    ParseUtil( const Variable & );
+    ParseUtil( int );
+    ParseUtil( char * );
+    ~ParseUtil();
+    ParseUtil & operator= ( const ParseUtil & );
+    ParseUtil & operator= ( const CanonicalForm & );
+    ParseUtil & operator= ( const Variable & );
+    ParseUtil & operator= ( int );
+    CanonicalForm getval();
+    int getintval();
+};
+
+#endif /* ! INCL_PARSEUTIL_H */
diff --git a/factory/readcf.cc b/factory/readcf.cc
new file mode 100644
index 0000000..f2cfdc1
--- /dev/null
+++ b/factory/readcf.cc
@@ -0,0 +1,1801 @@
+/* A Bison parser, made by GNU Bison 2.4.3.  */
+
+/* Skeleton implementation for Bison's Yacc-like parsers in C
+   
+      Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
+   2009, 2010 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 3 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+/* As a special exception, you may create a larger work that contains
+   part or all of the Bison parser skeleton and distribute that work
+   under terms of your choice, so long as that work isn't itself a
+   parser generator using the skeleton or a modified version thereof
+   as a parser skeleton.  Alternatively, if you modify or redistribute
+   the parser skeleton itself, you may (at your option) remove this
+   special exception, which will cause the skeleton and the resulting
+   Bison output files to be licensed under the GNU General Public
+   License without this special exception.
+   
+   This special exception was added by the Free Software Foundation in
+   version 2.2 of Bison.  */
+
+/* C LALR(1) parser skeleton written by Richard Stallman, by
+   simplifying the original so-called "semantic" parser.  */
+
+/* All symbols defined below should begin with yy or YY, to avoid
+   infringing on user name space.  This should be done even for local
+   variables, as they might otherwise be expanded by user macros.
+   There are some unavoidable exceptions within include files to
+   define necessary library symbols; they are noted "INFRINGES ON
+   USER NAME SPACE" below.  */
+
+/* Identify Bison output.  */
+#define YYBISON 1
+
+/* Bison version.  */
+#define YYBISON_VERSION "2.4.3"
+
+/* Skeleton name.  */
+#define YYSKELETON_NAME "yacc.c"
+
+/* Pure parsers.  */
+#define YYPURE 0
+
+/* Push parsers.  */
+#define YYPUSH 0
+
+/* Pull parsers.  */
+#define YYPULL 1
+
+/* Using locations.  */
+#define YYLSP_NEEDED 0
+
+
+
+/* Copy the first part of user declarations.  */
+
+/* Line 189 of yacc.c  */
+#line 3 "/home/hannes/git/singular/factory/readcf.yy"
+
+
+
+#include "config.h"
+
+#include <factory/factoryconf.h>
+
+#if defined(WINNT) && ! defined(__GNUC__)
+# include <malloc.h>
+# include <memory.h>
+# define alloca _alloca
+#endif
+
+#include <cstring> // we need this for gcc 4.3
+
+#include <config.h>
+
+
+#include <ctype.h>
+
+#ifdef HAVE_IOSTREAM
+# include <iostream>
+# define ISTREAM std::istream
+# define CERR std::cerr
+#elif defined(HAVE_IOSTREAM_H)
+# include <iostream.h>
+# define ISTREAM istream
+# define CERR cerr
+#endif
+
+
+#include "cf_assert.h"
+
+#include "canonicalform.h"
+#include "cf_defs.h"
+#include "gfops.h"
+#include "parseutil.h"
+#include "variable.h"
+
+#ifndef BISONPP
+# define YYSTYPE ParseUtil
+#else
+# define YY_parse_USE_GOTO 1
+# define YY_parse_STYPE ParseUtil
+#endif
+
+static char* readString( ISTREAM& );
+
+#ifndef BISONPP
+void yyerror( char * s );
+int yylex();
+#endif
+
+static ISTREAM * defaultin = 0;
+
+static CanonicalForm * retvalue = 0;
+
+
+
+/* Line 189 of yacc.c  */
+#line 132 "readcf.cc"
+
+/* Enabling traces.  */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+
+/* Enabling verbose error messages.  */
+#ifdef YYERROR_VERBOSE
+# undef YYERROR_VERBOSE
+# define YYERROR_VERBOSE 1
+#else
+# define YYERROR_VERBOSE 0
+#endif
+
+/* Enabling the token table.  */
+#ifndef YYTOKEN_TABLE
+# define YYTOKEN_TABLE 0
+#endif
+
+
+/* Tokens.  */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+   /* Put the tokens into the symbol table, so that GDB and other debuggers
+      know about them.  */
+   enum yytokentype {
+     NUM = 258,
+     NEG = 259
+   };
+#endif
+/* Tokens.  */
+#define NUM 258
+#define NEG 259
+
+
+
+
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+typedef int YYSTYPE;
+# define YYSTYPE_IS_TRIVIAL 1
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+#endif
+
+
+/* Copy the second part of user declarations.  */
+
+
+/* Line 264 of yacc.c  */
+#line 182 "readcf.cc"
+
+#ifdef short
+# undef short
+#endif
+
+#ifdef YYTYPE_UINT8
+typedef YYTYPE_UINT8 yytype_uint8;
+#else
+typedef unsigned char yytype_uint8;
+#endif
+
+#ifdef YYTYPE_INT8
+typedef YYTYPE_INT8 yytype_int8;
+#elif (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+typedef signed char yytype_int8;
+#else
+typedef short int yytype_int8;
+#endif
+
+#ifdef YYTYPE_UINT16
+typedef YYTYPE_UINT16 yytype_uint16;
+#else
+typedef unsigned short int yytype_uint16;
+#endif
+
+#ifdef YYTYPE_INT16
+typedef YYTYPE_INT16 yytype_int16;
+#else
+typedef short int yytype_int16;
+#endif
+
+#ifndef YYSIZE_T
+# ifdef __SIZE_TYPE__
+#  define YYSIZE_T __SIZE_TYPE__
+# elif defined size_t
+#  define YYSIZE_T size_t
+# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+#  include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+#  define YYSIZE_T size_t
+# else
+#  define YYSIZE_T unsigned int
+# endif
+#endif
+
+#define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
+
+#ifndef YY_
+# if defined YYENABLE_NLS && YYENABLE_NLS
+#  if ENABLE_NLS
+#   include <libintl.h> /* INFRINGES ON USER NAME SPACE */
+#   define YY_(msgid) dgettext ("bison-runtime", msgid)
+#  endif
+# endif
+# ifndef YY_
+#  define YY_(msgid) msgid
+# endif
+#endif
+
+/* Suppress unused-variable warnings by "using" E.  */
+#if ! defined lint || defined __GNUC__
+# define YYUSE(e) ((void) (e))
+#else
+# define YYUSE(e) /* empty */
+#endif
+
+/* Identity function, used to suppress warnings about constant conditions.  */
+#ifndef lint
+# define YYID(n) (n)
+#else
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static int
+YYID (int yyi)
+#else
+static int
+YYID (yyi)
+    int yyi;
+#endif
+{
+  return yyi;
+}
+#endif
+
+#if ! defined yyoverflow || YYERROR_VERBOSE
+
+/* The parser invokes alloca or malloc; define the necessary symbols.  */
+
+# ifdef YYSTACK_USE_ALLOCA
+#  if YYSTACK_USE_ALLOCA
+#   ifdef __GNUC__
+#    define YYSTACK_ALLOC __builtin_alloca
+#   elif defined __BUILTIN_VA_ARG_INCR
+#    include <alloca.h> /* INFRINGES ON USER NAME SPACE */
+#   elif defined _AIX
+#    define YYSTACK_ALLOC __alloca
+#   elif defined _MSC_VER
+#    include <malloc.h> /* INFRINGES ON USER NAME SPACE */
+#    define alloca _alloca
+#   else
+#    define YYSTACK_ALLOC alloca
+#    if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+#     include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+#     ifndef _STDLIB_H
+#      define _STDLIB_H 1
+#     endif
+#    endif
+#   endif
+#  endif
+# endif
+
+# ifdef YYSTACK_ALLOC
+   /* Pacify GCC's `empty if-body' warning.  */
+#  define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0))
+#  ifndef YYSTACK_ALLOC_MAXIMUM
+    /* The OS might guarantee only one guard page at the bottom of the stack,
+       and a page size can be as small as 4096 bytes.  So we cannot safely
+       invoke alloca (N) if N exceeds 4096.  Use a slightly smaller number
+       to allow for a few compiler-allocated temporary stack slots.  */
+#   define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
+#  endif
+# else
+#  define YYSTACK_ALLOC YYMALLOC
+#  define YYSTACK_FREE YYFREE
+#  ifndef YYSTACK_ALLOC_MAXIMUM
+#   define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
+#  endif
+#  if (defined __cplusplus && ! defined _STDLIB_H \
+       && ! ((defined YYMALLOC || defined malloc) \
+	     && (defined YYFREE || defined free)))
+#   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+#   ifndef _STDLIB_H
+#    define _STDLIB_H 1
+#   endif
+#  endif
+#  ifndef YYMALLOC
+#   define YYMALLOC malloc
+#   if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
+#   endif
+#  endif
+#  ifndef YYFREE
+#   define YYFREE free
+#   if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+void free (void *); /* INFRINGES ON USER NAME SPACE */
+#   endif
+#  endif
+# endif
+#endif /* ! defined yyoverflow || YYERROR_VERBOSE */
+
+
+#if (! defined yyoverflow \
+     && (! defined __cplusplus \
+	 || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
+
+/* A type that is properly aligned for any stack member.  */
+union yyalloc
+{
+  yytype_int16 yyss_alloc;
+  YYSTYPE yyvs_alloc;
+};
+
+/* The size of the maximum gap between one aligned stack and the next.  */
+# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
+
+/* The size of an array large to enough to hold all stacks, each with
+   N elements.  */
+# define YYSTACK_BYTES(N) \
+     ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \
+      + YYSTACK_GAP_MAXIMUM)
+
+/* Copy COUNT objects from FROM to TO.  The source and destination do
+   not overlap.  */
+# ifndef YYCOPY
+#  if defined __GNUC__ && 1 < __GNUC__
+#   define YYCOPY(To, From, Count) \
+      __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
+#  else
+#   define YYCOPY(To, From, Count)		\
+      do					\
+	{					\
+	  YYSIZE_T yyi;				\
+	  for (yyi = 0; yyi < (Count); yyi++)	\
+	    (To)[yyi] = (From)[yyi];		\
+	}					\
+      while (YYID (0))
+#  endif
+# endif
+
+/* Relocate STACK from its old location to the new one.  The
+   local variables YYSIZE and YYSTACKSIZE give the old and new number of
+   elements in the stack, and YYPTR gives the new location of the
+   stack.  Advance YYPTR to a properly aligned location for the next
+   stack.  */
+# define YYSTACK_RELOCATE(Stack_alloc, Stack)				\
+    do									\
+      {									\
+	YYSIZE_T yynewbytes;						\
+	YYCOPY (&yyptr->Stack_alloc, Stack, yysize);			\
+	Stack = &yyptr->Stack_alloc;					\
+	yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
+	yyptr += yynewbytes / sizeof (*yyptr);				\
+      }									\
+    while (YYID (0))
+
+#endif
+
+/* YYFINAL -- State number of the termination state.  */
+#define YYFINAL  2
+/* YYLAST -- Last index in YYTABLE.  */
+#define YYLAST   44
+
+/* YYNTOKENS -- Number of terminals.  */
+#define YYNTOKENS  13
+/* YYNNTS -- Number of nonterminals.  */
+#define YYNNTS  4
+/* YYNRULES -- Number of rules.  */
+#define YYNRULES  14
+/* YYNRULES -- Number of states.  */
+#define YYNSTATES  25
+
+/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
+#define YYUNDEFTOK  2
+#define YYMAXUTOK   259
+
+#define YYTRANSLATE(YYX)						\
+  ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
+
+/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX.  */
+static const yytype_uint8 yytranslate[] =
+{
+       0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+      11,    12,     6,     5,     2,     4,     2,     7,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,    10,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     9,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     1,     2,     3,     8
+};
+
+#if YYDEBUG
+/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
+   YYRHS.  */
+static const yytype_uint8 yyprhs[] =
+{
+       0,     0,     3,     4,     7,     9,    12,    14,    18,    22,
+      26,    30,    33,    36,    40
+};
+
+/* YYRHS -- A `-1'-separated list of the rules' RHS.  */
+static const yytype_int8 yyrhs[] =
+{
+      14,     0,    -1,    -1,    14,    15,    -1,    10,    -1,    16,
+      10,    -1,     3,    -1,    16,     5,    16,    -1,    16,     4,
+      16,    -1,    16,     6,    16,    -1,    16,     7,    16,    -1,
+       4,    16,    -1,     5,    16,    -1,    16,     9,     3,    -1,
+      11,    16,    12,    -1
+};
+
+/* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
+static const yytype_uint8 yyrline[] =
+{
+       0,    73,    73,    74,    77,    78,    81,    82,    83,    84,
+      85,    86,    87,    88,    89
+};
+#endif
+
+#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
+/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+   First, the terminals, then, starting at YYNTOKENS, nonterminals.  */
+static const char *const yytname[] =
+{
+  "$end", "error", "$undefined", "NUM", "'-'", "'+'", "'*'", "'/'", "NEG",
+  "'^'", "';'", "'('", "')'", "$accept", "input", "line", "exp", 0
+};
+#endif
+
+# ifdef YYPRINT
+/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
+   token YYLEX-NUM.  */
+static const yytype_uint16 yytoknum[] =
+{
+       0,   256,   257,   258,    45,    43,    42,    47,   259,    94,
+      59,    40,    41
+};
+# endif
+
+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
+static const yytype_uint8 yyr1[] =
+{
+       0,    13,    14,    14,    15,    15,    16,    16,    16,    16,
+      16,    16,    16,    16,    16
+};
+
+/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
+static const yytype_uint8 yyr2[] =
+{
+       0,     2,     0,     2,     1,     2,     1,     3,     3,     3,
+       3,     2,     2,     3,     3
+};
+
+/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
+   STATE-NUM when YYTABLE doesn't specify something else to do.  Zero
+   means the default is an error.  */
+static const yytype_uint8 yydefact[] =
+{
+       2,     0,     1,     6,     0,     0,     4,     0,     3,     0,
+      11,    12,     0,     0,     0,     0,     0,     0,     5,    14,
+       8,     7,     9,    10,    13
+};
+
+/* YYDEFGOTO[NTERM-NUM].  */
+static const yytype_int8 yydefgoto[] =
+{
+      -1,     1,     8,     9
+};
+
+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+   STATE-NUM.  */
+#define YYPACT_NINF -8
+static const yytype_int8 yypact[] =
+{
+      -8,    13,    -8,    -8,     3,     3,    -8,     3,    -8,    30,
+      -7,    -7,    21,     3,     3,     3,     3,     1,    -8,    -8,
+      35,    35,    -7,    -7,    -8
+};
+
+/* YYPGOTO[NTERM-NUM].  */
+static const yytype_int8 yypgoto[] =
+{
+      -8,    -8,    -8,    -4
+};
+
+/* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
+   positive, shift that token.  If negative, reduce the rule which
+   number is the opposite.  If zero, do what YYDEFACT says.
+   If YYTABLE_NINF, syntax error.  */
+#define YYTABLE_NINF -1
+static const yytype_uint8 yytable[] =
+{
+      10,    11,    17,    12,    24,     0,     3,     4,     5,    20,
+      21,    22,    23,     2,     7,     0,     3,     4,     5,     0,
+       0,     0,     0,     6,     7,    13,    14,    15,    16,     0,
+      17,     0,     0,    19,    13,    14,    15,    16,     0,    17,
+      18,    15,    16,     0,    17
+};
+
+static const yytype_int8 yycheck[] =
+{
+       4,     5,     9,     7,     3,    -1,     3,     4,     5,    13,
+      14,    15,    16,     0,    11,    -1,     3,     4,     5,    -1,
+      -1,    -1,    -1,    10,    11,     4,     5,     6,     7,    -1,
+       9,    -1,    -1,    12,     4,     5,     6,     7,    -1,     9,
+      10,     6,     7,    -1,     9
+};
+
+/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+   symbol of state STATE-NUM.  */
+static const yytype_uint8 yystos[] =
+{
+       0,    14,     0,     3,     4,     5,    10,    11,    15,    16,
+      16,    16,    16,     4,     5,     6,     7,     9,    10,    12,
+      16,    16,    16,    16,     3
+};
+
+#define yyerrok		(yyerrstatus = 0)
+#define yyclearin	(yychar = YYEMPTY)
+#define YYEMPTY		(-2)
+#define YYEOF		0
+
+#define YYACCEPT	goto yyacceptlab
+#define YYABORT		goto yyabortlab
+#define YYERROR		goto yyerrorlab
+
+
+/* Like YYERROR except do call yyerror.  This remains here temporarily
+   to ease the transition to the new meaning of YYERROR, for GCC.
+   Once GCC version 2 has supplanted version 1, this can go.  However,
+   YYFAIL appears to be in use.  Nevertheless, it is formally deprecated
+   in Bison 2.4.2's NEWS entry, where a plan to phase it out is
+   discussed.  */
+
+#define YYFAIL		goto yyerrlab
+#if defined YYFAIL
+  /* This is here to suppress warnings from the GCC cpp's
+     -Wunused-macros.  Normally we don't worry about that warning, but
+     some users do, and we want to make it easy for users to remove
+     YYFAIL uses, which will produce warnings from Bison 2.5.  */
+#endif
+
+#define YYRECOVERING()  (!!yyerrstatus)
+
+#define YYBACKUP(Token, Value)					\
+do								\
+  if (yychar == YYEMPTY && yylen == 1)				\
+    {								\
+      yychar = (Token);						\
+      yylval = (Value);						\
+      yytoken = YYTRANSLATE (yychar);				\
+      YYPOPSTACK (1);						\
+      goto yybackup;						\
+    }								\
+  else								\
+    {								\
+      yyerror (YY_("syntax error: cannot back up")); \
+      YYERROR;							\
+    }								\
+while (YYID (0))
+
+
+#define YYTERROR	1
+#define YYERRCODE	256
+
+
+/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
+   If N is 0, then set CURRENT to the empty location which ends
+   the previous symbol: RHS[0] (always defined).  */
+
+#define YYRHSLOC(Rhs, K) ((Rhs)[K])
+#ifndef YYLLOC_DEFAULT
+# define YYLLOC_DEFAULT(Current, Rhs, N)				\
+    do									\
+      if (YYID (N))                                                    \
+	{								\
+	  (Current).first_line   = YYRHSLOC (Rhs, 1).first_line;	\
+	  (Current).first_column = YYRHSLOC (Rhs, 1).first_column;	\
+	  (Current).last_line    = YYRHSLOC (Rhs, N).last_line;		\
+	  (Current).last_column  = YYRHSLOC (Rhs, N).last_column;	\
+	}								\
+      else								\
+	{								\
+	  (Current).first_line   = (Current).last_line   =		\
+	    YYRHSLOC (Rhs, 0).last_line;				\
+	  (Current).first_column = (Current).last_column =		\
+	    YYRHSLOC (Rhs, 0).last_column;				\
+	}								\
+    while (YYID (0))
+#endif
+
+
+/* YY_LOCATION_PRINT -- Print the location on the stream.
+   This macro was not mandated originally: define only if we know
+   we won't break user code: when these are the locations we know.  */
+
+#ifndef YY_LOCATION_PRINT
+# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL
+#  define YY_LOCATION_PRINT(File, Loc)			\
+     fprintf (File, "%d.%d-%d.%d",			\
+	      (Loc).first_line, (Loc).first_column,	\
+	      (Loc).last_line,  (Loc).last_column)
+# else
+#  define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+# endif
+#endif
+
+
+/* YYLEX -- calling `yylex' with the right arguments.  */
+
+#ifdef YYLEX_PARAM
+# define YYLEX yylex (YYLEX_PARAM)
+#else
+# define YYLEX yylex ()
+#endif
+
+/* Enable debugging if requested.  */
+#if YYDEBUG
+
+# ifndef YYFPRINTF
+#  include <stdio.h> /* INFRINGES ON USER NAME SPACE */
+#  define YYFPRINTF fprintf
+# endif
+
+# define YYDPRINTF(Args)			\
+do {						\
+  if (yydebug)					\
+    YYFPRINTF Args;				\
+} while (YYID (0))
+
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)			  \
+do {									  \
+  if (yydebug)								  \
+    {									  \
+      YYFPRINTF (stderr, "%s ", Title);					  \
+      yy_symbol_print (stderr,						  \
+		  Type, Value); \
+      YYFPRINTF (stderr, "\n");						  \
+    }									  \
+} while (YYID (0))
+
+
+/*--------------------------------.
+| Print this symbol on YYOUTPUT.  |
+`--------------------------------*/
+
+/*ARGSUSED*/
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static void
+yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
+#else
+static void
+yy_symbol_value_print (yyoutput, yytype, yyvaluep)
+    FILE *yyoutput;
+    int yytype;
+    YYSTYPE const * const yyvaluep;
+#endif
+{
+  if (!yyvaluep)
+    return;
+# ifdef YYPRINT
+  if (yytype < YYNTOKENS)
+    YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+# else
+  YYUSE (yyoutput);
+# endif
+  switch (yytype)
+    {
+      default:
+	break;
+    }
+}
+
+
+/*--------------------------------.
+| Print this symbol on YYOUTPUT.  |
+`--------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static void
+yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
+#else
+static void
+yy_symbol_print (yyoutput, yytype, yyvaluep)
+    FILE *yyoutput;
+    int yytype;
+    YYSTYPE const * const yyvaluep;
+#endif
+{
+  if (yytype < YYNTOKENS)
+    YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
+  else
+    YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
+
+  yy_symbol_value_print (yyoutput, yytype, yyvaluep);
+  YYFPRINTF (yyoutput, ")");
+}
+
+/*------------------------------------------------------------------.
+| yy_stack_print -- Print the state stack from its BOTTOM up to its |
+| TOP (included).                                                   |
+`------------------------------------------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static void
+yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)
+#else
+static void
+yy_stack_print (yybottom, yytop)
+    yytype_int16 *yybottom;
+    yytype_int16 *yytop;
+#endif
+{
+  YYFPRINTF (stderr, "Stack now");
+  for (; yybottom <= yytop; yybottom++)
+    {
+      int yybot = *yybottom;
+      YYFPRINTF (stderr, " %d", yybot);
+    }
+  YYFPRINTF (stderr, "\n");
+}
+
+# define YY_STACK_PRINT(Bottom, Top)				\
+do {								\
+  if (yydebug)							\
+    yy_stack_print ((Bottom), (Top));				\
+} while (YYID (0))
+
+
+/*------------------------------------------------.
+| Report that the YYRULE is going to be reduced.  |
+`------------------------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static void
+yy_reduce_print (YYSTYPE *yyvsp, int yyrule)
+#else
+static void
+yy_reduce_print (yyvsp, yyrule)
+    YYSTYPE *yyvsp;
+    int yyrule;
+#endif
+{
+  int yynrhs = yyr2[yyrule];
+  int yyi;
+  unsigned long int yylno = yyrline[yyrule];
+  YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
+	     yyrule - 1, yylno);
+  /* The symbols being reduced.  */
+  for (yyi = 0; yyi < yynrhs; yyi++)
+    {
+      YYFPRINTF (stderr, "   $%d = ", yyi + 1);
+      yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
+		       &(yyvsp[(yyi + 1) - (yynrhs)])
+		       		       );
+      YYFPRINTF (stderr, "\n");
+    }
+}
+
+# define YY_REDUCE_PRINT(Rule)		\
+do {					\
+  if (yydebug)				\
+    yy_reduce_print (yyvsp, Rule); \
+} while (YYID (0))
+
+/* Nonzero means print parse trace.  It is left uninitialized so that
+   multiple parsers can coexist.  */
+int yydebug;
+#else /* !YYDEBUG */
+# define YYDPRINTF(Args)
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
+# define YY_STACK_PRINT(Bottom, Top)
+# define YY_REDUCE_PRINT(Rule)
+#endif /* !YYDEBUG */
+
+
+/* YYINITDEPTH -- initial size of the parser's stacks.  */
+#ifndef	YYINITDEPTH
+# define YYINITDEPTH 200
+#endif
+
+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
+   if the built-in stack extension method is used).
+
+   Do not make this value too large; the results are undefined if
+   YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
+   evaluated with infinite-precision integer arithmetic.  */
+
+#ifndef YYMAXDEPTH
+# define YYMAXDEPTH 10000
+#endif
+
+

+
+#if YYERROR_VERBOSE
+
+# ifndef yystrlen
+#  if defined __GLIBC__ && defined _STRING_H
+#   define yystrlen strlen
+#  else
+/* Return the length of YYSTR.  */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static YYSIZE_T
+yystrlen (const char *yystr)
+#else
+static YYSIZE_T
+yystrlen (yystr)
+    const char *yystr;
+#endif
+{
+  YYSIZE_T yylen;
+  for (yylen = 0; yystr[yylen]; yylen++)
+    continue;
+  return yylen;
+}
+#  endif
+# endif
+
+# ifndef yystpcpy
+#  if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
+#   define yystpcpy stpcpy
+#  else
+/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
+   YYDEST.  */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static char *
+yystpcpy (char *yydest, const char *yysrc)
+#else
+static char *
+yystpcpy (yydest, yysrc)
+    char *yydest;
+    const char *yysrc;
+#endif
+{
+  char *yyd = yydest;
+  const char *yys = yysrc;
+
+  while ((*yyd++ = *yys++) != '\0')
+    continue;
+
+  return yyd - 1;
+}
+#  endif
+# endif
+
+# ifndef yytnamerr
+/* Copy to YYRES the contents of YYSTR after stripping away unnecessary
+   quotes and backslashes, so that it's suitable for yyerror.  The
+   heuristic is that double-quoting is unnecessary unless the string
+   contains an apostrophe, a comma, or backslash (other than
+   backslash-backslash).  YYSTR is taken from yytname.  If YYRES is
+   null, do not copy; instead, return the length of what the result
+   would have been.  */
+static YYSIZE_T
+yytnamerr (char *yyres, const char *yystr)
+{
+  if (*yystr == '"')
+    {
+      YYSIZE_T yyn = 0;
+      char const *yyp = yystr;
+
+      for (;;)
+	switch (*++yyp)
+	  {
+	  case '\'':
+	  case ',':
+	    goto do_not_strip_quotes;
+
+	  case '\\':
+	    if (*++yyp != '\\')
+	      goto do_not_strip_quotes;
+	    /* Fall through.  */
+	  default:
+	    if (yyres)
+	      yyres[yyn] = *yyp;
+	    yyn++;
+	    break;
+
+	  case '"':
+	    if (yyres)
+	      yyres[yyn] = '\0';
+	    return yyn;
+	  }
+    do_not_strip_quotes: ;
+    }
+
+  if (! yyres)
+    return yystrlen (yystr);
+
+  return yystpcpy (yyres, yystr) - yyres;
+}
+# endif
+
+/* Copy into YYRESULT an error message about the unexpected token
+   YYCHAR while in state YYSTATE.  Return the number of bytes copied,
+   including the terminating null byte.  If YYRESULT is null, do not
+   copy anything; just return the number of bytes that would be
+   copied.  As a special case, return 0 if an ordinary "syntax error"
+   message will do.  Return YYSIZE_MAXIMUM if overflow occurs during
+   size calculation.  */
+static YYSIZE_T
+yysyntax_error (char *yyresult, int yystate, int yychar)
+{
+  int yyn = yypact[yystate];
+
+  if (! (YYPACT_NINF < yyn && yyn <= YYLAST))
+    return 0;
+  else
+    {
+      int yytype = YYTRANSLATE (yychar);
+      YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
+      YYSIZE_T yysize = yysize0;
+      YYSIZE_T yysize1;
+      int yysize_overflow = 0;
+      enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
+      char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
+      int yyx;
+
+# if 0
+      /* This is so xgettext sees the translatable formats that are
+	 constructed on the fly.  */
+      YY_("syntax error, unexpected %s");
+      YY_("syntax error, unexpected %s, expecting %s");
+      YY_("syntax error, unexpected %s, expecting %s or %s");
+      YY_("syntax error, unexpected %s, expecting %s or %s or %s");
+      YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
+# endif
+      char *yyfmt;
+      char const *yyf;
+      static char const yyunexpected[] = "syntax error, unexpected %s";
+      static char const yyexpecting[] = ", expecting %s";
+      static char const yyor[] = " or %s";
+      char yyformat[sizeof yyunexpected
+		    + sizeof yyexpecting - 1
+		    + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
+		       * (sizeof yyor - 1))];
+      char const *yyprefix = yyexpecting;
+
+      /* Start YYX at -YYN if negative to avoid negative indexes in
+	 YYCHECK.  */
+      int yyxbegin = yyn < 0 ? -yyn : 0;
+
+      /* Stay within bounds of both yycheck and yytname.  */
+      int yychecklim = YYLAST - yyn + 1;
+      int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+      int yycount = 1;
+
+      yyarg[0] = yytname[yytype];
+      yyfmt = yystpcpy (yyformat, yyunexpected);
+
+      for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+	if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+	  {
+	    if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+	      {
+		yycount = 1;
+		yysize = yysize0;
+		yyformat[sizeof yyunexpected - 1] = '\0';
+		break;
+	      }
+	    yyarg[yycount++] = yytname[yyx];
+	    yysize1 = yysize + yytnamerr (0, yytname[yyx]);
+	    yysize_overflow |= (yysize1 < yysize);
+	    yysize = yysize1;
+	    yyfmt = yystpcpy (yyfmt, yyprefix);
+	    yyprefix = yyor;
+	  }
+
+      yyf = YY_(yyformat);
+      yysize1 = yysize + yystrlen (yyf);
+      yysize_overflow |= (yysize1 < yysize);
+      yysize = yysize1;
+
+      if (yysize_overflow)
+	return YYSIZE_MAXIMUM;
+
+      if (yyresult)
+	{
+	  /* Avoid sprintf, as that infringes on the user's name space.
+	     Don't have undefined behavior even if the translation
+	     produced a string with the wrong number of "%s"s.  */
+	  char *yyp = yyresult;
+	  int yyi = 0;
+	  while ((*yyp = *yyf) != '\0')
+	    {
+	      if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
+		{
+		  yyp += yytnamerr (yyp, yyarg[yyi++]);
+		  yyf += 2;
+		}
+	      else
+		{
+		  yyp++;
+		  yyf++;
+		}
+	    }
+	}
+      return yysize;
+    }
+}
+#endif /* YYERROR_VERBOSE */
+

+
+/*-----------------------------------------------.
+| Release the memory associated to this symbol.  |
+`-----------------------------------------------*/
+
+/*ARGSUSED*/
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static void
+yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep)
+#else
+static void
+yydestruct (yymsg, yytype, yyvaluep)
+    const char *yymsg;
+    int yytype;
+    YYSTYPE *yyvaluep;
+#endif
+{
+  YYUSE (yyvaluep);
+
+  if (!yymsg)
+    yymsg = "Deleting";
+  YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
+
+  switch (yytype)
+    {
+
+      default:
+	break;
+    }
+}
+
+/* Prevent warnings from -Wmissing-prototypes.  */
+#ifdef YYPARSE_PARAM
+#if defined __STDC__ || defined __cplusplus
+int yyparse (void *YYPARSE_PARAM);
+#else
+int yyparse ();
+#endif
+#else /* ! YYPARSE_PARAM */
+#if defined __STDC__ || defined __cplusplus
+int yyparse (void);
+#else
+int yyparse ();
+#endif
+#endif /* ! YYPARSE_PARAM */
+
+
+/* The lookahead symbol.  */
+int yychar;
+
+/* The semantic value of the lookahead symbol.  */
+YYSTYPE yylval;
+
+/* Number of syntax errors so far.  */
+int yynerrs;
+
+
+
+/*-------------------------.
+| yyparse or yypush_parse.  |
+`-------------------------*/
+
+#ifdef YYPARSE_PARAM
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+int
+yyparse (void *YYPARSE_PARAM)
+#else
+int
+yyparse (YYPARSE_PARAM)
+    void *YYPARSE_PARAM;
+#endif
+#else /* ! YYPARSE_PARAM */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+int
+yyparse (void)
+#else
+int
+yyparse ()
+
+#endif
+#endif
+{
+
+
+    int yystate;
+    /* Number of tokens to shift before error messages enabled.  */
+    int yyerrstatus;
+
+    /* The stacks and their tools:
+       `yyss': related to states.
+       `yyvs': related to semantic values.
+
+       Refer to the stacks thru separate pointers, to allow yyoverflow
+       to reallocate them elsewhere.  */
+
+    /* The state stack.  */
+    yytype_int16 yyssa[YYINITDEPTH];
+    yytype_int16 *yyss;
+    yytype_int16 *yyssp;
+
+    /* The semantic value stack.  */
+    YYSTYPE yyvsa[YYINITDEPTH];
+    YYSTYPE *yyvs;
+    YYSTYPE *yyvsp;
+
+    YYSIZE_T yystacksize;
+
+  int yyn;
+  int yyresult;
+  /* Lookahead token as an internal (translated) token number.  */
+  int yytoken;
+  /* The variables used to return semantic value and location from the
+     action routines.  */
+  YYSTYPE yyval;
+
+#if YYERROR_VERBOSE
+  /* Buffer for error messages, and its allocated size.  */
+  char yymsgbuf[128];
+  char *yymsg = yymsgbuf;
+  YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
+#endif
+
+#define YYPOPSTACK(N)   (yyvsp -= (N), yyssp -= (N))
+
+  /* The number of symbols on the RHS of the reduced rule.
+     Keep to zero when no symbol should be popped.  */
+  int yylen = 0;
+
+  yytoken = 0;
+  yyss = yyssa;
+  yyvs = yyvsa;
+  yystacksize = YYINITDEPTH;
+
+  YYDPRINTF ((stderr, "Starting parse\n"));
+
+  yystate = 0;
+  yyerrstatus = 0;
+  yynerrs = 0;
+  yychar = YYEMPTY; /* Cause a token to be read.  */
+
+  /* Initialize stack pointers.
+     Waste one element of value and location stack
+     so that they stay on the same level as the state stack.
+     The wasted elements are never initialized.  */
+  yyssp = yyss;
+  yyvsp = yyvs;
+
+  goto yysetstate;
+
+/*------------------------------------------------------------.
+| yynewstate -- Push a new state, which is found in yystate.  |
+`------------------------------------------------------------*/
+ yynewstate:
+  /* In all cases, when you get here, the value and location stacks
+     have just been pushed.  So pushing a state here evens the stacks.  */
+  yyssp++;
+
+ yysetstate:
+  *yyssp = yystate;
+
+  if (yyss + yystacksize - 1 <= yyssp)
+    {
+      /* Get the current used size of the three stacks, in elements.  */
+      YYSIZE_T yysize = yyssp - yyss + 1;
+
+#ifdef yyoverflow
+      {
+	/* Give user a chance to reallocate the stack.  Use copies of
+	   these so that the &'s don't force the real ones into
+	   memory.  */
+	YYSTYPE *yyvs1 = yyvs;
+	yytype_int16 *yyss1 = yyss;
+
+	/* Each stack pointer address is followed by the size of the
+	   data in use in that stack, in bytes.  This used to be a
+	   conditional around just the two extra args, but that might
+	   be undefined if yyoverflow is a macro.  */
+	yyoverflow (YY_("memory exhausted"),
+		    &yyss1, yysize * sizeof (*yyssp),
+		    &yyvs1, yysize * sizeof (*yyvsp),
+		    &yystacksize);
+
+	yyss = yyss1;
+	yyvs = yyvs1;
+      }
+#else /* no yyoverflow */
+# ifndef YYSTACK_RELOCATE
+      goto yyexhaustedlab;
+# else
+      /* Extend the stack our own way.  */
+      if (YYMAXDEPTH <= yystacksize)
+	goto yyexhaustedlab;
+      yystacksize *= 2;
+      if (YYMAXDEPTH < yystacksize)
+	yystacksize = YYMAXDEPTH;
+
+      {
+	yytype_int16 *yyss1 = yyss;
+	union yyalloc *yyptr =
+	  (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
+	if (! yyptr)
+	  goto yyexhaustedlab;
+	YYSTACK_RELOCATE (yyss_alloc, yyss);
+	YYSTACK_RELOCATE (yyvs_alloc, yyvs);
+#  undef YYSTACK_RELOCATE
+	if (yyss1 != yyssa)
+	  YYSTACK_FREE (yyss1);
+      }
+# endif
+#endif /* no yyoverflow */
+
+      yyssp = yyss + yysize - 1;
+      yyvsp = yyvs + yysize - 1;
+
+      YYDPRINTF ((stderr, "Stack size increased to %lu\n",
+		  (unsigned long int) yystacksize));
+
+      if (yyss + yystacksize - 1 <= yyssp)
+	YYABORT;
+    }
+
+  YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+
+  if (yystate == YYFINAL)
+    YYACCEPT;
+
+  goto yybackup;
+
+/*-----------.
+| yybackup.  |
+`-----------*/
+yybackup:
+
+  /* Do appropriate processing given the current state.  Read a
+     lookahead token if we need one and don't already have one.  */
+
+  /* First try to decide what to do without reference to lookahead token.  */
+  yyn = yypact[yystate];
+  if (yyn == YYPACT_NINF)
+    goto yydefault;
+
+  /* Not known => get a lookahead token if don't already have one.  */
+
+  /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol.  */
+  if (yychar == YYEMPTY)
+    {
+      YYDPRINTF ((stderr, "Reading a token: "));
+      yychar = YYLEX;
+    }
+
+  if (yychar <= YYEOF)
+    {
+      yychar = yytoken = YYEOF;
+      YYDPRINTF ((stderr, "Now at end of input.\n"));
+    }
+  else
+    {
+      yytoken = YYTRANSLATE (yychar);
+      YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
+    }
+
+  /* If the proper action on seeing token YYTOKEN is to reduce or to
+     detect an error, take that action.  */
+  yyn += yytoken;
+  if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
+    goto yydefault;
+  yyn = yytable[yyn];
+  if (yyn <= 0)
+    {
+      if (yyn == 0 || yyn == YYTABLE_NINF)
+	goto yyerrlab;
+      yyn = -yyn;
+      goto yyreduce;
+    }
+
+  /* Count tokens shifted since error; after three, turn off error
+     status.  */
+  if (yyerrstatus)
+    yyerrstatus--;
+
+  /* Shift the lookahead token.  */
+  YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
+
+  /* Discard the shifted token.  */
+  yychar = YYEMPTY;
+
+  yystate = yyn;
+  *++yyvsp = yylval;
+
+  goto yynewstate;
+
+
+/*-----------------------------------------------------------.
+| yydefault -- do the default action for the current state.  |
+`-----------------------------------------------------------*/
+yydefault:
+  yyn = yydefact[yystate];
+  if (yyn == 0)
+    goto yyerrlab;
+  goto yyreduce;
+
+
+/*-----------------------------.
+| yyreduce -- Do a reduction.  |
+`-----------------------------*/
+yyreduce:
+  /* yyn is the number of a rule to reduce with.  */
+  yylen = yyr2[yyn];
+
+  /* If YYLEN is nonzero, implement the default value of the action:
+     `$$ = $1'.
+
+     Otherwise, the following line sets YYVAL to garbage.
+     This behavior is undocumented and Bison
+     users should not rely upon it.  Assigning to YYVAL
+     unconditionally makes the parser a bit smaller, and it avoids a
+     GCC warning that YYVAL may be used uninitialized.  */
+  yyval = yyvsp[1-yylen];
+
+
+  YY_REDUCE_PRINT (yyn);
+  switch (yyn)
+    {
+        case 5:
+
+/* Line 1464 of yacc.c  */
+#line 78 "/home/hannes/git/singular/factory/readcf.yy"
+    { *retvalue = (yyvsp[(1) - (2)]).getval(); return 0; }
+    break;
+
+  case 6:
+
+/* Line 1464 of yacc.c  */
+#line 81 "/home/hannes/git/singular/factory/readcf.yy"
+    { (yyval) = (yyvsp[(1) - (1)]); }
+    break;
+
+  case 7:
+
+/* Line 1464 of yacc.c  */
+#line 82 "/home/hannes/git/singular/factory/readcf.yy"
+    { (yyval) = (yyvsp[(1) - (3)]).getval() + (yyvsp[(3) - (3)]).getval(); }
+    break;
+
+  case 8:
+
+/* Line 1464 of yacc.c  */
+#line 83 "/home/hannes/git/singular/factory/readcf.yy"
+    { (yyval) = (yyvsp[(1) - (3)]).getval() - (yyvsp[(3) - (3)]).getval(); }
+    break;
+
+  case 9:
+
+/* Line 1464 of yacc.c  */
+#line 84 "/home/hannes/git/singular/factory/readcf.yy"
+    { (yyval) = (yyvsp[(1) - (3)]).getval() * (yyvsp[(3) - (3)]).getval(); }
+    break;
+
+  case 10:
+
+/* Line 1464 of yacc.c  */
+#line 85 "/home/hannes/git/singular/factory/readcf.yy"
+    { (yyval) = (yyvsp[(1) - (3)]).getval() / (yyvsp[(3) - (3)]).getval(); }
+    break;
+
+  case 11:
+
+/* Line 1464 of yacc.c  */
+#line 86 "/home/hannes/git/singular/factory/readcf.yy"
+    { (yyval) = -(yyvsp[(2) - (2)]).getval(); }
+    break;
+
+  case 12:
+
+/* Line 1464 of yacc.c  */
+#line 87 "/home/hannes/git/singular/factory/readcf.yy"
+    { (yyval) = (yyvsp[(2) - (2)]).getval(); }
+    break;
+
+  case 13:
+
+/* Line 1464 of yacc.c  */
+#line 88 "/home/hannes/git/singular/factory/readcf.yy"
+    { (yyval) = power( (yyvsp[(1) - (3)]).getval(), (yyvsp[(3) - (3)]).getintval() ); }
+    break;
+
+  case 14:
+
+/* Line 1464 of yacc.c  */
+#line 89 "/home/hannes/git/singular/factory/readcf.yy"
+    { (yyval) = (yyvsp[(2) - (3)]).getval(); }
+    break;
+
+
+
+/* Line 1464 of yacc.c  */
+#line 1461 "readcf.cc"
+      default: break;
+    }
+  YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
+
+  YYPOPSTACK (yylen);
+  yylen = 0;
+  YY_STACK_PRINT (yyss, yyssp);
+
+  *++yyvsp = yyval;
+
+  /* Now `shift' the result of the reduction.  Determine what state
+     that goes to, based on the state we popped back to and the rule
+     number reduced by.  */
+
+  yyn = yyr1[yyn];
+
+  yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
+  if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+    yystate = yytable[yystate];
+  else
+    yystate = yydefgoto[yyn - YYNTOKENS];
+
+  goto yynewstate;
+
+
+/*------------------------------------.
+| yyerrlab -- here on detecting error |
+`------------------------------------*/
+yyerrlab:
+  /* If not already recovering from an error, report this error.  */
+  if (!yyerrstatus)
+    {
+      ++yynerrs;
+#if ! YYERROR_VERBOSE
+      yyerror (YY_("syntax error"));
+#else
+      {
+	YYSIZE_T yysize = yysyntax_error (0, yystate, yychar);
+	if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM)
+	  {
+	    YYSIZE_T yyalloc = 2 * yysize;
+	    if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))
+	      yyalloc = YYSTACK_ALLOC_MAXIMUM;
+	    if (yymsg != yymsgbuf)
+	      YYSTACK_FREE (yymsg);
+	    yymsg = (char *) YYSTACK_ALLOC (yyalloc);
+	    if (yymsg)
+	      yymsg_alloc = yyalloc;
+	    else
+	      {
+		yymsg = yymsgbuf;
+		yymsg_alloc = sizeof yymsgbuf;
+	      }
+	  }
+
+	if (0 < yysize && yysize <= yymsg_alloc)
+	  {
+	    (void) yysyntax_error (yymsg, yystate, yychar);
+	    yyerror (yymsg);
+	  }
+	else
+	  {
+	    yyerror (YY_("syntax error"));
+	    if (yysize != 0)
+	      goto yyexhaustedlab;
+	  }
+      }
+#endif
+    }
+
+
+
+  if (yyerrstatus == 3)
+    {
+      /* If just tried and failed to reuse lookahead token after an
+	 error, discard it.  */
+
+      if (yychar <= YYEOF)
+	{
+	  /* Return failure if at end of input.  */
+	  if (yychar == YYEOF)
+	    YYABORT;
+	}
+      else
+	{
+	  yydestruct ("Error: discarding",
+		      yytoken, &yylval);
+	  yychar = YYEMPTY;
+	}
+    }
+
+  /* Else will try to reuse lookahead token after shifting the error
+     token.  */
+  goto yyerrlab1;
+
+
+/*---------------------------------------------------.
+| yyerrorlab -- error raised explicitly by YYERROR.  |
+`---------------------------------------------------*/
+yyerrorlab:
+
+  /* Pacify compilers like GCC when the user code never invokes
+     YYERROR and the label yyerrorlab therefore never appears in user
+     code.  */
+  if (/*CONSTCOND*/ 0)
+     goto yyerrorlab;
+
+  /* Do not reclaim the symbols of the rule which action triggered
+     this YYERROR.  */
+  YYPOPSTACK (yylen);
+  yylen = 0;
+  YY_STACK_PRINT (yyss, yyssp);
+  yystate = *yyssp;
+  goto yyerrlab1;
+
+
+/*-------------------------------------------------------------.
+| yyerrlab1 -- common code for both syntax error and YYERROR.  |
+`-------------------------------------------------------------*/
+yyerrlab1:
+  yyerrstatus = 3;	/* Each real token shifted decrements this.  */
+
+  for (;;)
+    {
+      yyn = yypact[yystate];
+      if (yyn != YYPACT_NINF)
+	{
+	  yyn += YYTERROR;
+	  if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
+	    {
+	      yyn = yytable[yyn];
+	      if (0 < yyn)
+		break;
+	    }
+	}
+
+      /* Pop the current state because it cannot handle the error token.  */
+      if (yyssp == yyss)
+	YYABORT;
+
+
+      yydestruct ("Error: popping",
+		  yystos[yystate], yyvsp);
+      YYPOPSTACK (1);
+      yystate = *yyssp;
+      YY_STACK_PRINT (yyss, yyssp);
+    }
+
+  *++yyvsp = yylval;
+
+
+  /* Shift the error token.  */
+  YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
+
+  yystate = yyn;
+  goto yynewstate;
+
+
+/*-------------------------------------.
+| yyacceptlab -- YYACCEPT comes here.  |
+`-------------------------------------*/
+yyacceptlab:
+  yyresult = 0;
+  goto yyreturn;
+
+/*-----------------------------------.
+| yyabortlab -- YYABORT comes here.  |
+`-----------------------------------*/
+yyabortlab:
+  yyresult = 1;
+  goto yyreturn;
+
+#if !defined(yyoverflow) || YYERROR_VERBOSE
+/*-------------------------------------------------.
+| yyexhaustedlab -- memory exhaustion comes here.  |
+`-------------------------------------------------*/
+yyexhaustedlab:
+  yyerror (YY_("memory exhausted"));
+  yyresult = 2;
+  /* Fall through.  */
+#endif
+
+yyreturn:
+  if (yychar != YYEMPTY)
+     yydestruct ("Cleanup: discarding lookahead",
+		 yytoken, &yylval);
+  /* Do not reclaim the symbols of the rule which action triggered
+     this YYABORT or YYACCEPT.  */
+  YYPOPSTACK (yylen);
+  YY_STACK_PRINT (yyss, yyssp);
+  while (yyssp != yyss)
+    {
+      yydestruct ("Cleanup: popping",
+		  yystos[*yyssp], yyvsp);
+      YYPOPSTACK (1);
+    }
+#ifndef yyoverflow
+  if (yyss != yyssa)
+    YYSTACK_FREE (yyss);
+#endif
+#if YYERROR_VERBOSE
+  if (yymsg != yymsgbuf)
+    YYSTACK_FREE (yymsg);
+#endif
+  /* Make sure YYID is used.  */
+  return YYID (yyresult);
+}
+
+
+
+/* Line 1684 of yacc.c  */
+#line 92 "/home/hannes/git/singular/factory/readcf.yy"
+
+
+#ifdef BISONPP
+void YY_parse_CLASS::yyerror( char * s )
+#else
+void yyerror( char * s )
+#endif
+{
+    CERR << s << "\n";
+}
+
+#ifdef BISONPP
+int YY_parse_CLASS::yylex()
+#else
+int yylex()
+#endif
+{
+    int c;
+
+    while ((c = defaultin->get()) == ' ' || c == '\t' || c == '\n' ) ;
+    if ( isdigit( c ) ) {
+        defaultin->putback( c );
+        yylval = ParseUtil( readString( *defaultin ) );
+        return NUM;
+    }
+    else if ( isalpha( c ) ) {
+        // look for generators of GF(q)
+        if ( getCharacteristic() > 0 && getGFDegree() > 1 && c == gf_name ) {
+#ifdef BISONPP
+            this->yylval = getGFGenerator();
+#else
+            yylval = getGFGenerator();
+#endif
+        }
+        else if ( c == getDefaultVarName() ) {
+            int cc;
+            cc = defaultin->get();
+            if ( cc == '_' ) {
+                ParseUtil index( readString( *defaultin ) );
+#ifdef BISONPP
+                this->yylval = Variable( index.getintval() );
+#else
+                yylval = Variable( index.getintval() );
+#endif
+            }
+            else {
+                defaultin->putback( cc );
+#ifdef BISONPP
+                this->yylval = Variable( (char)c );
+#else
+                yylval = Variable( (char)c );
+#endif
+            }
+        }
+        else {
+#ifdef BISONPP
+            this->yylval = Variable( (char)c );
+#else
+            yylval = Variable( (char)c );
+#endif
+        }
+        return NUM;
+    }
+    return c;
+}
+
+CanonicalForm readCF( ISTREAM& str )
+{
+    CanonicalForm theRetvalue;
+    retvalue = new CanonicalForm();
+#ifdef BISONPP
+    YY_parse_CLASS my_parser;
+    defaultin = &str;
+    if ( my_parser.yyparse() == 0 ) {
+        theRetvalue = *retvalue;
+        delete retvalue;
+        return theRetvalue;
+    }
+    else {
+        delete retvalue;
+        return 0;
+    }
+#else
+    defaultin = &str;
+    if ( yyparse() == 0 ) {
+        theRetvalue = *retvalue;
+        delete retvalue;
+        return theRetvalue;
+    }
+    else {
+        delete retvalue;
+        return 0;
+    }
+#endif
+}
+
+char* readString( ISTREAM& s )
+{
+    static char * buffer = 0;
+    static int bufsize = 0;
+
+    if ( buffer == 0 ) {
+        bufsize = 10000;
+        buffer = new char[bufsize];
+    }
+    int i = 0, c, goon = 1;
+    while ( goon ) {
+        while ( isdigit( c = s.get() ) && i < bufsize - 2 ) {
+            buffer[i] = c;
+            i++;
+        }
+        if ( isdigit( c ) ) {
+            bufsize += 1000;
+            char * newbuffer = (char*)memcpy( new char[bufsize], buffer, bufsize - 1000 );
+            delete [] buffer;
+            buffer = newbuffer;
+            buffer[i] = c;
+            i++;
+        }
+        else {
+            goon = 0;
+            buffer[i] = '\0';
+            s.putback( c );
+        }
+    }
+    return buffer;
+}
+
+
diff --git a/factory/readcf.yy b/factory/readcf.yy
new file mode 100644
index 0000000..8dd8df4
--- /dev/null
+++ b/factory/readcf.yy
@@ -0,0 +1,219 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+%{
+
+
+#include "config.h"
+
+#include <factory/factoryconf.h>
+
+#if defined(WINNT) && ! defined(__GNUC__)
+# include <malloc.h>
+# include <memory.h>
+# define alloca _alloca
+#endif
+
+#include <cstring> // we need this for gcc 4.3
+
+#include <config.h>
+
+
+#include <ctype.h>
+
+#ifdef HAVE_IOSTREAM
+# include <iostream>
+# define ISTREAM std::istream
+# define CERR std::cerr
+#elif defined(HAVE_IOSTREAM_H)
+# include <iostream.h>
+# define ISTREAM istream
+# define CERR cerr
+#endif
+
+
+#include "cf_assert.h"
+
+#include "canonicalform.h"
+#include "cf_defs.h"
+#include "gfops.h"
+#include "parseutil.h"
+#include "variable.h"
+
+#ifndef BISONPP
+# define YYSTYPE ParseUtil
+#else
+# define YY_parse_USE_GOTO 1
+# define YY_parse_STYPE ParseUtil
+#endif
+
+static char* readString( ISTREAM& );
+
+#ifndef BISONPP
+void yyerror( char * s );
+int yylex();
+#endif
+
+static ISTREAM * defaultin = 0;
+
+static CanonicalForm * retvalue = 0;
+
+%}
+
+/* BISON Declarations */
+
+%token NUM
+%left '-' '+'
+%left '*' '/'
+%left NEG
+%right '^'
+
+/* Grammar follows */
+
+%%
+input:        /* empty string */
+        | input line
+;
+
+line:        ';'
+        | exp ';' { *retvalue = $1.getval(); return 0; }
+;
+
+exp:        NUM                        { $$ = $1; }
+        | exp '+' exp                { $$ = $1.getval() + $3.getval(); }
+        | exp '-' exp                { $$ = $1.getval() - $3.getval(); }
+        | exp '*' exp                { $$ = $1.getval() * $3.getval(); }
+        | exp '/' exp                { $$ = $1.getval() / $3.getval(); }
+        | '-' exp %prec NEG        { $$ = -$2.getval(); }
+        | '+' exp %prec NEG        { $$ = $2.getval(); }
+        | exp '^' NUM                { $$ = power( $1.getval(), $3.getintval() ); }
+        | '(' exp ')'                { $$ = $2.getval(); }
+;
+
+%%
+
+#ifdef BISONPP
+void YY_parse_CLASS::yyerror( char * s )
+#else
+void yyerror( char * s )
+#endif
+{
+    CERR << s << "\n";
+}
+
+#ifdef BISONPP
+int YY_parse_CLASS::yylex()
+#else
+int yylex()
+#endif
+{
+    int c;
+
+    while ((c = defaultin->get()) == ' ' || c == '\t' || c == '\n' ) ;
+    if ( isdigit( c ) ) {
+        defaultin->putback( c );
+        yylval = ParseUtil( readString( *defaultin ) );
+        return NUM;
+    }
+    else if ( isalpha( c ) ) {
+        // look for generators of GF(q)
+        if ( getCharacteristic() > 0 && getGFDegree() > 1 && c == gf_name ) {
+#ifdef BISONPP
+            this->yylval = getGFGenerator();
+#else
+            yylval = getGFGenerator();
+#endif
+        }
+        else if ( c == getDefaultVarName() ) {
+            int cc;
+            cc = defaultin->get();
+            if ( cc == '_' ) {
+                ParseUtil index( readString( *defaultin ) );
+#ifdef BISONPP
+                this->yylval = Variable( index.getintval() );
+#else
+                yylval = Variable( index.getintval() );
+#endif
+            }
+            else {
+                defaultin->putback( cc );
+#ifdef BISONPP
+                this->yylval = Variable( (char)c );
+#else
+                yylval = Variable( (char)c );
+#endif
+            }
+        }
+        else {
+#ifdef BISONPP
+            this->yylval = Variable( (char)c );
+#else
+            yylval = Variable( (char)c );
+#endif
+        }
+        return NUM;
+    }
+    return c;
+}
+
+CanonicalForm readCF( ISTREAM& str )
+{
+    CanonicalForm theRetvalue;
+    retvalue = new CanonicalForm();
+#ifdef BISONPP
+    YY_parse_CLASS my_parser;
+    defaultin = &str;
+    if ( my_parser.yyparse() == 0 ) {
+        theRetvalue = *retvalue;
+        delete retvalue;
+        return theRetvalue;
+    }
+    else {
+        delete retvalue;
+        return 0;
+    }
+#else
+    defaultin = &str;
+    if ( yyparse() == 0 ) {
+        theRetvalue = *retvalue;
+        delete retvalue;
+        return theRetvalue;
+    }
+    else {
+        delete retvalue;
+        return 0;
+    }
+#endif
+}
+
+char* readString( ISTREAM& s )
+{
+    static char * buffer = 0;
+    static int bufsize = 0;
+
+    if ( buffer == 0 ) {
+        bufsize = 10000;
+        buffer = new char[bufsize];
+    }
+    int i = 0, c, goon = 1;
+    while ( goon ) {
+        while ( isdigit( c = s.get() ) && i < bufsize - 2 ) {
+            buffer[i] = c;
+            i++;
+        }
+        if ( isdigit( c ) ) {
+            bufsize += 1000;
+            char * newbuffer = (char*)memcpy( new char[bufsize], buffer, bufsize - 1000 );
+            delete [] buffer;
+            buffer = newbuffer;
+            buffer[i] = c;
+            i++;
+        }
+        else {
+            goon = 0;
+            buffer[i] = '\0';
+            s.putback( c );
+        }
+    }
+    return buffer;
+}
+
diff --git a/factory/singext.cc b/factory/singext.cc
new file mode 100644
index 0000000..dc2db77
--- /dev/null
+++ b/factory/singext.cc
@@ -0,0 +1,81 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+
+#include "config.h"
+
+
+#include "cf_assert.h"
+
+#include "cf_defs.h"
+#include "singext.h"
+#include "int_cf.h"
+#include "int_int.h"
+#include "int_rat.h"
+#include "imm.h"
+#include "cf_factory.h"
+
+#include <factory/cf_gmp.h>
+
+
+void gmp_numerator ( const CanonicalForm & f, mpz_ptr result )
+{
+    InternalCF * ff = f.getval();
+    ASSERT( ! is_imm( ff ), "illegal type" );
+    if ( ff->levelcoeff() == IntegerDomain )
+    {
+        mpz_init_set( result, (InternalInteger::MPI( ff )) );
+        ff->deleteObject();
+    }
+    else  if ( ff->levelcoeff() == RationalDomain )
+    {
+        mpz_init_set( result, (InternalRational::MPQNUM( ff )) );
+        ff->deleteObject();
+    }
+    else
+    {
+        ASSERT( 0, "illegal type" );
+    }
+}
+
+void gmp_denominator ( const CanonicalForm & f, mpz_ptr result )
+{
+    InternalCF * ff = f.getval();
+    ASSERT( ! is_imm( ff ), "illegal type" );
+    if ( ff->levelcoeff() == IntegerDomain )
+    {
+        mpz_init_set_si( result, 1 );
+        ff->deleteObject();
+    }
+    else  if ( ff->levelcoeff() == RationalDomain )
+    {
+        mpz_init_set( result, (InternalRational::MPQDEN( ff )) );
+        ff->deleteObject();
+    }
+    else
+    {
+        ASSERT( 0, "illegal type" );
+    }
+}
+
+int gf_value (const CanonicalForm & f )
+{
+    InternalCF * ff = f.getval();
+    return ((intptr_t)ff) >>2;
+}
+
+CanonicalForm
+make_cf ( const mpz_ptr n )
+{
+    return CanonicalForm( CFFactory::basic( n ) );
+}
+
+CanonicalForm
+make_cf ( const mpz_ptr n, const mpz_ptr d, bool normalize )
+{
+    return CanonicalForm( CFFactory::rational( n, d, normalize ) );
+}
+
+CanonicalForm make_cf_from_gf ( const int z )
+{
+    return CanonicalForm(int2imm_gf(z));
+}
diff --git a/factory/singext.h b/factory/singext.h
new file mode 100644
index 0000000..717703b
--- /dev/null
+++ b/factory/singext.h
@@ -0,0 +1,37 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+/**
+ * @file singext.h
+ *
+ * helper functions for conversion to and from Singular
+**/
+#ifndef INCL_SINGEXT_H
+#define INCL_SINGEXT_H
+
+// #include "config.h"
+
+#include "canonicalform.h"
+#include <factory/cf_gmp.h>
+
+#ifdef SINGULAR
+#include <resources/feFopen.h>
+#endif
+
+//TODO make these functions members of CanonicalForm?
+/*BEGINPUBLIC*/
+
+void gmp_numerator ( const CanonicalForm & f, mpz_ptr result );
+
+void gmp_denominator ( const CanonicalForm & f, mpz_ptr result );
+
+int gf_value (const CanonicalForm & f );
+
+CanonicalForm make_cf ( const mpz_ptr n );
+
+CanonicalForm make_cf ( const mpz_ptr n, const mpz_ptr d, bool normalize );
+
+CanonicalForm make_cf_from_gf ( const int z );
+
+/*ENDPUBLIC*/
+
+#endif /* ! INCL_SINGEXT_H */
diff --git a/factory/templates/ftmpl_afactor.cc b/factory/templates/ftmpl_afactor.cc
new file mode 100644
index 0000000..67216db
--- /dev/null
+++ b/factory/templates/ftmpl_afactor.cc
@@ -0,0 +1,39 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+#include <factory/templates/ftmpl_afactor.h>
+
+template <class T>
+AFactor<T>& AFactor<T>::operator= ( const AFactor<T>& f )
+{
+    if ( this != &f )
+    {
+      _minpoly = f._minpoly;
+      _factor = f._factor;
+      _exp = f._exp;
+    }
+    return *this;
+}
+
+template <class T>
+int operator== ( const AFactor<T> &f1, const AFactor<T> &f2 )
+{
+    return (f1.exp() == f2.exp()) && (f1.factor() == f2.factor()) && (f1.minpoly() == f2.minpoly()); //minpoly comparision may not be enough but checking the fields they define are equal
+}
+
+#ifndef NOSTREAMIO
+template <class T>
+void AFactor<T>::print ( OSTREAM& s ) const
+{
+    if ( exp() == 1 )
+	s << "(" << factor() << ", " << minpoly() << ")";
+    else
+	s << "((" << factor() << ")^" << exp() << ", " << minpoly() << ")";
+}
+
+template <class T>
+OSTREAM& operator<< ( OSTREAM & os, const AFactor<T> & f )
+{
+    f.print( os );
+    return os;
+}
+#endif /* NOSTREAMIO */
diff --git a/factory/templates/ftmpl_array.cc b/factory/templates/ftmpl_array.cc
new file mode 100644
index 0000000..59a00b1
--- /dev/null
+++ b/factory/templates/ftmpl_array.cc
@@ -0,0 +1,156 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+#include <factory/templates/ftmpl_array.h>
+
+template <class T>
+Array<T>::Array() : data(0), _min(0), _max(-1), _size(0)
+{
+}
+
+template <class T>
+Array<T>::Array( const Array<T> & a )
+{
+    if ( a._size > 0 ) {
+	_min = a._min;
+	_max = a._max;
+	_size = a._size;
+	data = new T[_size];
+	for ( int i = 0; i < _size; i++ )
+	    data[i] = a.data[i];
+    }
+    else {
+	data = 0;
+	_min = _size = 0;
+	_max = -1;
+    }
+}
+
+template <class T>
+Array<T>::Array( int i )
+{
+    _min = 0;
+    _max = i-1;
+    _size = i;
+    if ( i == 0 )
+	data = 0;
+    else
+	data = new T[_size];
+}
+
+template <class T>
+Array<T>::Array( int min, int max )
+{
+    if ( max < min ) {
+	_min = _size = 0;
+	_max = -1;
+	data = 0;
+    }
+    else {
+	_min = min;
+	_max = max;
+	_size = _max - _min + 1;
+	data = new T[_size];
+    }
+}
+
+template <class T>
+Array<T>::~Array()
+{
+    delete [] data;
+}
+
+template <class T>
+Array<T>& Array<T>::operator= ( const Array<T> & a )
+{
+    if ( this != &a ) {
+	delete [] data;
+	_min = a._min;
+	_max = a._max;
+	_size = a._size;
+	if ( a._size > 0 ) {
+	    _size = a._size;
+	    data = new T[_size];
+	    for ( int i = 0; i < _size; i++ )
+		data[i] = a.data[i];
+	}
+	else {
+	    data = 0;
+	    _size = 0;
+	}
+    }
+    return *this;
+}
+
+template <class T>
+T& Array<T>::operator[] ( int i ) const
+{
+    ASSERT( i >= _min && i <= _max, "warning: array size mismatch." );
+    return data[i-_min];
+}
+
+template <class T>
+int Array<T>::size() const
+{
+    return _size;
+}
+
+template <class T>
+int Array<T>::min() const
+{
+    return _min;
+}
+
+template <class T>
+int Array<T>::max() const
+{
+    return _max;
+}
+
+/*
+template <class T>
+Array<T>& Array<T>::operator*= ( const T & t )
+{
+    for ( int i = 0; i < _size; i++ )
+	data[i] *= t;
+    return *this;
+}
+
+template <class T>
+Array<T>& Array<T>::operator+= ( const T & t )
+{
+    for ( int i = 0; i < _size; i++ )
+	data[i] += t;
+    return *this;
+}
+
+template <class T>
+Array<T>& Array<T>::operator+= ( const Array<T> & a )
+{
+    ASSERT ( _size == a._size, "warning: array size mismatch." );
+    for ( int i = 0; i < _size; i++ )
+	data[i] += a.data[i];
+    return *this;
+}
+*/
+
+#ifndef NOSTREAMIO
+template <class T>
+void Array<T>::print ( OSTREAM & os ) const
+{
+    if ( _size == 0 )
+	os << "( )";
+    else {
+	os << "( " << data[0];
+	for ( int i = 1; i < _size; i++ )
+	    os << ", " << data[i];
+	os << " )";
+    }
+}
+
+template <class T>
+OSTREAM& operator<< ( OSTREAM & os, const Array<T> & a )
+{
+    a.print( os );
+    return os;
+}
+#endif /* NOSTREAMIO */
diff --git a/factory/templates/ftmpl_factor.cc b/factory/templates/ftmpl_factor.cc
new file mode 100644
index 0000000..027ed0c
--- /dev/null
+++ b/factory/templates/ftmpl_factor.cc
@@ -0,0 +1,45 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+#include <factory/templates/ftmpl_factor.h>
+
+template <class T>
+Factor<T>& Factor<T>::operator= ( const Factor<T>& f )
+{
+    if ( this != &f ) {
+	_factor = f._factor;
+	_exp = f._exp;
+    }
+    return *this;
+}
+
+template <class T>
+Factor<T>& Factor<T>::operator= ( const T & f )
+{
+    _factor = f;
+    _exp = 1;
+    return *this;
+}
+
+template <class T>
+int operator== ( const Factor<T> &f1, const Factor<T> &f2 )
+{
+    return (f1.exp() == f2.exp()) && (f1.factor() == f2.factor());
+}
+
+#ifndef NOSTREAMIO
+template <class T>
+void Factor<T>::print ( OSTREAM& s ) const
+{
+    if ( exp() == 1 )
+	s << factor();
+    else
+	s << "(" << factor() << ")^" << exp();
+}
+
+template <class T>
+OSTREAM& operator<< ( OSTREAM & os, const Factor<T> & f )
+{
+    f.print( os );
+    return os;
+}
+#endif /* NOSTREAMIO */
diff --git a/factory/templates/ftmpl_functions.h b/factory/templates/ftmpl_functions.h
new file mode 100644
index 0000000..9a6aabe
--- /dev/null
+++ b/factory/templates/ftmpl_functions.h
@@ -0,0 +1,79 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+#ifndef INCL_FUNCTIONS_H
+#define INCL_FUNCTIONS_H
+
+/**
+ *
+ * @file ftmpl_functions.h
+ * some useful template functions.
+ *
+ * Header file corresponds to: nothing
+ *
+ * Hierarchy: bottom, templates
+ *
+ * Developer note:
+ * ---------------
+ * Sooner or later you need them: functions to calculate the
+ * minimum or maximum of two values or the absolute value.  Here
+ * they are.  All of them are inlined, hence there is no source
+ * file corresponding to `ftmpl_functions.h'.
+ *
+ * The functions are for internal use only (i.e., to build the
+ * library), hence they should not be included from `factory.h'.
+ * However, we have to install `ftmpl_functions.h' with the other
+ * templates since the functions have to be instantiated.
+ *
+**/
+
+// #include <factory/factoryconf.h>
+
+/** template <class T> inline T tmax ( const T & a, const T & b )
+ *
+ * tmax() - return the maximum of `a' and `b'.
+ *
+ * Developers note:
+ * ----------------
+ * `T' should have an `operator >()'.
+ *
+**/
+template <class T>
+inline T tmax ( const T & a, const T & b )
+{
+    return (a > b) ? a : b;
+}
+
+/** template <class T> inline T tmin ( const T & a, const T & b )
+ *
+ * tmin() - return the minimum of `a' and `b'.
+ *
+ * Developers note:
+ * ----------------
+ * `T' should have an `operator <()'.
+ *
+**/
+template <class T>
+inline T tmin ( const T & a, const T & b )
+{
+    return (a < b) ? a : b;
+}
+
+/** template <class T> inline T tabs ( const T & a )
+ *
+ * tabs() - return the absolute value of `a'.
+ *
+ * `a' is negated iff it is less or equal `T( 0 )'.
+ *
+ * Developers note:
+ * ----------------
+ * `T' should have an `operator >()', an `operator -()', and a
+ * `T::T( int )' constructor.
+ *
+**/
+template <class T>
+inline T tabs ( const T & a )
+{
+    return (a > T( 0 )) ? a : -a;
+}
+
+#endif /* ! INCL_FUNCTIONS_H */
diff --git a/factory/templates/ftmpl_list.cc b/factory/templates/ftmpl_list.cc
new file mode 100644
index 0000000..8b00c5e
--- /dev/null
+++ b/factory/templates/ftmpl_list.cc
@@ -0,0 +1,726 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+#include <factory/templates/ftmpl_list.h>
+
+template <class T>
+ListItem<T>::ListItem( const ListItem<T>& i )
+{
+    next = i.next;
+    prev = i.prev;
+    item = i.item;
+}
+
+
+template <class T>
+ListItem<T>::ListItem( const T& t, ListItem<T>* n, ListItem<T>* p )
+{
+    next = n;
+    prev = p;
+    item = new T( t );
+}
+
+
+template <class T>
+ListItem<T>::ListItem( T* t, ListItem<T>* n, ListItem<T>* p )
+{
+    next = n;
+    prev = p;
+    item = t;
+}
+
+
+template <class T>
+ListItem<T>::~ListItem()
+{
+    delete item;
+}
+
+
+template <class T>
+ListItem<T>& ListItem<T>::operator=( const ListItem<T>& i )
+{
+    if ( this != &i )
+    {
+        next = i.next;
+        prev = i.prev;
+        item = i.item;
+    }
+    return *this;
+}
+
+
+template <class T>
+ListItem<T>* ListItem<T>::getNext()
+{
+    return next;
+}
+
+
+template <class T>
+ListItem<T>* ListItem<T>::getPrev()
+{
+    return prev;
+}
+
+
+template <class T>
+T& ListItem<T>::getItem()
+{
+    return *item;
+}
+
+#ifndef NOSTREAMIO
+template <class T>
+void ListItem<T>::print( OSTREAM & os )
+{
+    if ( item )
+        os << *item;
+    else
+        os << "(no item)";
+}
+#endif /* NOSTREAMIO */
+
+
+
+template <class T>
+List<T>::List()
+{
+    first = last = 0;
+    _length = 0;
+}
+
+
+template <class T>
+List<T>::List( const List<T>& l )
+{
+    ListItem<T>* cur = l.last;
+    if ( cur )
+    {
+        first = new ListItem<T>( *(cur->item), 0, 0 );
+        last = first;
+        cur = cur->prev;
+        while ( cur )
+        {
+            first = new ListItem<T>( *(cur->item), first, 0 );
+            first->next->prev = first;
+            cur = cur->prev;
+        }
+        _length = l._length;
+    }
+    else
+    {
+        first = last = 0;
+        _length = 0;
+    }
+}
+
+
+template <class T>
+List<T>::List( const T& t )
+{
+    first = last = new ListItem<T>( t, 0, 0 );
+    _length = 1;
+}
+
+
+template <class T>
+List<T>::~List()
+{
+    ListItem<T> *dummy;
+    while ( first )
+    {
+        dummy = first;
+        first = first->next;
+        delete dummy;
+    }
+}
+
+
+template <class T>
+List<T>& List<T>::operator=( const List<T>& l )
+{
+    if ( this != &l )
+    {
+        ListItem<T> *dummy;
+        while ( first )
+        {
+            dummy = first;
+            first = first->next;
+            delete dummy;
+        }
+        ListItem<T>* cur = l.last;
+        if ( cur )
+        {
+            first = new ListItem<T>( *(cur->item), 0, 0 );
+            last = first;
+            cur = cur->prev;
+            while ( cur )
+            {
+                first = new ListItem<T>( *(cur->item), first, 0 );
+                first->next->prev = first;
+                cur = cur->prev;
+            }
+            _length = l._length;
+        }
+        else
+        {
+            first = last = 0;
+            _length = 0;
+        }
+        _length = l._length;
+    }
+    return *this;
+}
+
+template <class T>
+int operator== ( const List<T>& l1, const List<T>& l2 )
+{
+    if (l1.length() != l2.length())
+      return 0;
+    ListIterator<T> iter2= l2;
+    for (ListIterator<T> iter1= l1; iter1.hasItem(); iter1++)
+    {
+      if (!(iter1.getItem() == iter2.getItem()))
+        return 0;
+      iter2++;
+    }
+
+    return 1;
+}
+
+
+template <class T>
+void List<T>::insert ( const T& t )
+{
+    first = new ListItem<T>( t, first, 0 );
+    if ( last )
+        first->next->prev = first;
+    last = ( last ) ? last : first;
+    _length++;
+}
+
+
+template <class T>
+void List<T>::insert ( const T& t, int (*cmpf)( const T&, const T& ) )
+{
+    if ( ! first || cmpf( *first->item, t ) > 0 )
+        insert( t );
+    else if ( cmpf( *last->item, t ) < 0 )
+        append( t );
+    else
+    {
+        ListItem<T> * cursor = first;
+        int c;
+        while ( (c = cmpf( *cursor->item, t )) < 0 )
+            cursor = cursor->next;
+        if ( c == 0 )
+            *cursor->item = t;
+        else
+        {
+            cursor = cursor->prev;
+            cursor->next = new ListItem<T>( t, cursor->next, cursor );
+            cursor->next->next->prev = cursor->next;
+            _length++;
+        }
+    }
+}
+
+
+template <class T>
+void List<T>::insert ( const T& t, int (*cmpf)( const T&, const T& ), void (*insf)( T&, const T& ) )
+{
+    if ( ! first || cmpf( *first->item, t ) > 0 )
+        insert( t );
+    else if ( cmpf( *last->item, t ) < 0 )
+        append( t );
+    else
+    {
+        ListItem<T> * cursor = first;
+        int c;
+        while ( (c = cmpf( *cursor->item, t )) < 0 )
+            cursor = cursor->next;
+        if ( c == 0 )
+            insf( *cursor->item, t );
+        else
+        {
+            cursor = cursor->prev;
+            cursor->next = new ListItem<T>( t, cursor->next, cursor );
+            cursor->next->next->prev = cursor->next;
+            _length++;
+        }
+    }
+}
+
+
+template <class T>
+void List<T>::append ( const T& t )
+{
+    last = new ListItem<T>( t, 0, last );
+    if ( first )
+        last->prev->next = last;
+    first = ( first ) ? first : last;
+    _length++;
+}
+
+
+template <class T>
+int List<T>::isEmpty() const
+{
+    return ( first == 0 );
+}
+
+template <class T>
+int List<T>::length() const
+{
+    return _length;
+}
+
+template <class T>
+T List<T>::getFirst() const
+{
+    ASSERT( first, "List: no item available" );
+    return first->getItem();
+}
+
+
+template <class T>
+void List<T>::removeFirst()
+{
+    if ( first )
+    {
+        _length--;
+        if ( first == last )
+        {
+            delete first;
+            first = last = 0;
+        }
+        else
+        {
+            ListItem<T> *dummy = first;
+            first->next->prev = 0;
+            first = first->next;
+            delete dummy;
+        }
+    }
+}
+
+
+template <class T>
+T List<T>::getLast() const
+{
+    ASSERT( first, "List: no item available" );
+    return last->getItem();
+}
+
+
+template <class T>
+void List<T>::removeLast()
+{
+    if ( last )
+    {
+        _length--;
+        if ( first == last )
+        {
+            delete last;
+            first = last = 0;
+        }
+        else
+        {
+            ListItem<T> *dummy = last;
+            last->prev->next = 0;
+            last = last->prev;
+            delete dummy;
+        }
+    }
+}
+
+
+template <class T>
+void List<T>::sort( int (*swapit) ( const T&, const T& ) )
+{
+    if ( first != last )
+    {
+        int swap;
+        do
+        {
+            swap = 0;
+            ListItem<T> *cur = first;
+            while ( cur->next )
+            {
+                if ( swapit( *(cur->item), *(cur->next->item) ) )
+                {
+                    T* dummy = cur->item;
+                    cur->item = cur->next->item;
+                    cur->next->item = dummy;
+                    swap = 1;
+                }
+                cur = cur->next;
+            }
+        } while (swap);
+    }
+}
+
+
+#ifndef NOSTREAMIO
+template <class T>
+void List<T>::print ( OSTREAM & os ) const
+{
+    ListItem<T> *cur = first;
+    os << "( ";
+    while ( cur )
+    {
+        cur->print( os );
+        if ( (cur = cur->getNext()) )
+            os << ", ";
+    }
+    os << " )";
+}
+#endif /* NOSTREAMIO */
+
+
+template <class T>
+ListIterator<T>::ListIterator()
+{
+    theList = 0;
+    current = 0;
+}
+
+
+template <class T>
+ListIterator<T>::ListIterator ( const ListIterator<T> & i )
+{
+    theList = i.theList;
+    current = i.current;
+}
+
+
+template <class T>
+ListIterator<T>::ListIterator ( const List<T> & l )
+{
+    theList = (List<T>*)&l;
+    current = l.first;
+}
+
+
+template <class T>
+ListIterator<T>::~ListIterator() { }
+
+
+template <class T>
+ListIterator<T>& ListIterator<T>::operator= ( const ListIterator<T> & I )
+{
+    if ( this != &I )
+    {
+        theList = I.theList;
+        current = I.current;
+    }
+    return *this;
+}
+
+
+template <class T>
+ListIterator<T>& ListIterator<T>::operator= ( const List<T> & l )
+{
+    theList = (List<T>*)&l;
+    current = l.first;
+    return *this;
+}
+
+
+template <class T>
+T& ListIterator<T>::getItem () const
+{
+    ASSERT( current, "ListIterator: no item available" );
+    return current->getItem();
+}
+
+
+template <class T>
+int ListIterator<T>::hasItem ()
+{
+    return current != 0;
+}
+
+
+template <class T>
+void ListIterator<T>::operator++ ()
+{
+    if ( current )
+        current = current->next;
+}
+
+
+template <class T>
+void ListIterator<T>::operator-- ()
+{
+    if ( current )
+        current = current->prev;
+}
+
+
+template <class T>
+void ListIterator<T>::operator++ ( int )
+{
+    if ( current )
+        current = current->next;
+}
+
+
+template <class T>
+void ListIterator<T>::operator-- ( int )
+{
+    if ( current )
+        current = current->prev;
+}
+
+
+template <class T>
+void ListIterator<T>::firstItem ()
+{
+    current = theList->first;
+}
+
+
+template <class T>
+void ListIterator<T>::lastItem ()
+{
+    current = theList->last;
+}
+
+
+template <class T>
+void ListIterator<T>::insert ( const T & t )
+{
+    if ( current )
+    {
+        if ( ! current->prev )
+            theList->insert( t );
+        else
+        {
+            current->prev = new ListItem<T>( t, current, current->prev );
+            current->prev->prev->next = current->prev;
+            theList->_length++;
+        }
+    }
+}
+
+
+template <class T>
+void ListIterator<T>::append ( const T & t )
+{
+    if ( current )
+    {
+        if ( ! current->next )
+            theList->append( t );
+        else
+        {
+            current->next = new ListItem<T>( t, current->next, current );
+            current->next->next->prev = current->next;
+            theList->_length++;
+        }
+    }
+}
+
+
+template <class T>
+void ListIterator<T>::remove ( int moveright )
+{
+    if ( current )
+    {
+        ListItem <T>*dummynext = current->next, *dummyprev = current->prev;
+        if ( current->prev )
+        {
+            current->prev->next = current->next;
+            if ( current->next )
+                current->next->prev = current->prev;
+            else
+                theList->last = current->prev;
+            delete current;
+            current = ( moveright ) ? dummynext : dummyprev;
+        }
+        else
+        {
+            if ( current->next )
+                current->next->prev = 0;
+            theList->first = current->next;
+            delete current;
+            current = ( moveright ) ? dummynext : dummyprev;
+        }
+        theList->_length--;
+    }
+}
+
+#ifndef NOSTREAMIO
+template <class T>
+OSTREAM& operator<<( OSTREAM & os, const List<T> & l )
+{
+    l.print( os );
+    return os;
+}
+#endif /* NOSTREAMIO */
+
+template <class T>
+List<T> Union ( const List<T> & F, const List<T> & G )
+{
+    List<T> L = G;
+    ListIterator<T> i, j;
+    T f;
+    bool iselt;
+
+    for ( i = F; i.hasItem(); i++ )
+    {
+        f = i.getItem();
+        iselt = false;
+        j = G;
+        while ( ( ! iselt ) && j.hasItem() )
+        {
+            iselt =  f == j.getItem();
+            j++;
+        }
+        if ( ! iselt )
+            L.append( f );
+    }
+    return L;
+}
+
+template <class T>
+List<T> Union ( const List<T> & F, const List<T> & G, int (*cmpf)( const T&, const T& ), void (*insf)( T&, const T& ) )
+{
+    List<T> L = G;
+    ListIterator<T> i;
+
+    for ( i = F; i.hasItem(); ++i )
+        L.insert( i.getItem(), cmpf, insf );
+    return L;
+}
+
+template <class T>
+List<T> Union ( const List<T> & F, const List<T> & G, int (*ecmpf)( const T&, const T& ))
+{
+    List<T> L = G;
+    ListIterator<T> i, j;
+    T f;
+    bool iselt;
+
+    for ( i = F; i.hasItem(); i++ )
+    {
+        f = i.getItem();
+        iselt = false;
+        j = G;
+        while ( ( ! iselt ) && j.hasItem() )
+        {
+            iselt =  ecmpf (f, j.getItem());
+            j++;
+        }
+        if ( ! iselt )
+            L.append( f );
+    }
+    return L;
+}
+
+template <class T>
+List<T> Difference ( const List<T> & F, const List<T> & G )
+{
+    List<T> L;
+    ListIterator<T> i, j;
+    T f;
+    int found;
+    for ( i = F; i.hasItem(); ++i )
+    {
+        f = i.getItem();
+        found = 0;
+        for ( j = G; j.hasItem() && (!found); ++j )
+            found = f == j.getItem();
+        if ( ! found )
+            L.append( f );
+    }
+    return L;
+}
+
+template <class T>
+List<T> Difference ( const List<T> & F, const List<T> & G, int (*ecmpf)( const T&, const T& ))
+{
+    List<T> L;
+    ListIterator<T> i, j;
+    T f;
+    int found;
+    for ( i = F; i.hasItem(); ++i )
+    {
+        f = i.getItem();
+        found = 0;
+        for ( j = G; j.hasItem() && (!found); ++j )
+            found = ecmpf (f, j.getItem());
+        if ( ! found )
+            L.append( f );
+    }
+    return L;
+}
+
+template <class T>
+List<T> Difference ( const List<T> & F, const T & G, int (*ecmpf)( const T&, const T& ))
+{
+    List<T> L;
+    ListIterator<T> i;
+    int found;
+    for ( i = F; i.hasItem(); ++i )
+    {
+        found = ecmpf (G, i.getItem());
+        if ( ! found )
+            L.append( i.getItem() );
+    }
+    return L;
+}
+
+template <class T>
+List<T> Difference ( const List<T> & F, const T & G)
+{
+    List<T> L;
+    ListIterator<T> i;
+    int found;
+    for ( i = F; i.hasItem(); ++i )
+    {
+        found = G == i.getItem();
+        if ( ! found )
+            L.append( i.getItem() );
+    }
+    return L;
+}
+
+template <class T>
+T prod ( const List<T> & F )
+{
+    ListIterator<T> i;
+    T p = 1;
+    for ( i = F; i.hasItem(); i++ )
+        p = p * i.getItem();
+    return p;
+}
+
+template <class T>
+bool find (const List<T> & F, const T& t)
+{
+  if (F.length() == 0) return false;
+  ListIterator<T> J= F;
+  while (J.hasItem())
+  {
+    if (J.getItem() == t)
+      return true;
+    J++;
+  }
+  return false;
+}
+
+template <class T>
+bool find (const List<T> & F, const T& t, int (*ecmpf)( const T&, const T& ))
+{
+  if (F.length() == 0) return false;
+  ListIterator<T> J= F;
+  while (J.hasItem())
+  {
+    if (ecmpf (J.getItem(), t))
+      return true;
+    J++;
+  }
+  return false;
+}
+
diff --git a/factory/templates/ftmpl_matrix.cc b/factory/templates/ftmpl_matrix.cc
new file mode 100644
index 0000000..40b0860
--- /dev/null
+++ b/factory/templates/ftmpl_matrix.cc
@@ -0,0 +1,319 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+#include <factory/templates/ftmpl_matrix.h>
+
+template <class T>
+Matrix<T>::Matrix( int nr, int nc ) : NR(nr), NC(nc)
+{
+    ASSERT( (nr > 0 && nc > 0) || (nr == 0 && nc == 0), "illegal index" );
+    if ( nr == 0 )
+	elems = 0;
+    else {
+	int i;
+	elems = new T_ptr[nr];
+	for ( i = 0; i < nr; i++ )
+	    elems[i] = new T[nc];
+    }
+}
+
+template <class T>
+Matrix<T>::Matrix( const Matrix<T>& M ) : NR(M.NR), NC(M.NC)
+{
+    if ( NR == 0 )
+	elems = 0;
+    else {
+	int i, j;
+	elems = new T_ptr[NR];
+	for ( i = 0; i < NR; i++ ) {
+	    elems[i] = new T[NC];
+	    for ( j = 0; j < NC; j++ )
+		elems[i][j] = M.elems[i][j];
+	}
+    }
+}
+
+template <class T>
+Matrix<T>::~Matrix()
+{
+    if ( elems != 0 ) {
+	int i;
+	for ( i = 0; i < NR; i++ )
+	    delete [] elems[i];
+	delete [] elems;
+    }
+}
+
+template <class T>
+Matrix<T>& Matrix<T>::operator= ( const Matrix<T>& M )
+{
+    if ( this != &M ) {
+	int i, j;
+	if ( NR != M.NR || NC != M.NC ) {
+	    for ( i = 0; i < NR; i++ )
+		delete [] elems[i];
+	    delete elems;
+	    NR = M.NR; NC = M.NC;
+	    elems = new T_ptr[NR];
+	    for ( i = 0; i < NR; i++ )
+		elems[i] = new T[NC];
+	}
+	for ( i = 0; i < NR; i++ )
+	    for ( j = 0; j < NC; j++ )
+		elems[i][j] = M.elems[i][j];
+    }
+    return *this;
+}
+
+template <class T>
+SubMatrix<T> Matrix<T>::operator[] ( int i )
+{
+    ASSERT( i > 0 && i <= NR, "illegal index" );
+    return SubMatrix<T>( i, i, 1, NC, *this );
+}
+
+template <class T>
+const SubMatrix<T> Matrix<T>::operator[] ( int i ) const
+{
+    ASSERT( i > 0 && i <= NR, "illegal index" );
+    return SubMatrix<T>( i, i, 1, NC, *this );
+}
+
+template <class T>
+T& Matrix<T>::operator() ( int row, int col )
+{
+    ASSERT( row > 0 && col > 0 && row <= NR && col <= NC, "illegal index" );
+    return elems[row-1][col-1];
+}
+
+template <class T>
+T Matrix<T>::operator() ( int row, int col ) const
+{
+    ASSERT( row > 0 && col > 0 && row <= NR && col <= NC, "illegal index" );
+    return elems[row-1][col-1];
+}
+
+template <class T>
+SubMatrix<T> Matrix<T>::operator() ( int rmin, int rmax, int cmin, int cmax )
+{
+    ASSERT( rmin > 0 && rmax <= NR && rmin <= rmax && cmin > 0 && cmax <= NC && cmin <= cmax , "illegal index" );
+    return SubMatrix<T>( rmin, rmax, cmin, cmax, *this );
+}
+
+template <class T>
+const SubMatrix<T> Matrix<T>::operator() ( int rmin, int rmax, int cmin, int cmax ) const
+{
+    ASSERT( rmin > 0 && rmax <= NR && rmin <= rmax && cmin > 0 && cmax <= NC && cmin <= cmax , "illegal index" );
+    return SubMatrix<T>( rmin, rmax, cmin, cmax, *this );
+}
+
+template <class T>
+void Matrix<T>::swapRow ( int i, int j )
+{
+    ASSERT( i > 0 && i <= NR && j > 0 && j <= NR, "illegal index" );
+    if ( i != j ) {
+	i--; j--;
+	T * h = elems[i];
+	elems[i] = elems[j];
+	elems[j] = h;
+    }
+}
+
+template <class T>
+void Matrix<T>::swapColumn ( int i, int j )
+{
+    ASSERT( i > 0 && i <= NC && j > 0 && j <= NC, "illegal index" );
+    if ( i != j ) {
+	int k;
+	i--; j--;
+	for ( k = 0; k < NR; k++ ) {
+	    T h = elems[k][i];
+	    elems[k][i] = elems[k][j];
+	    elems[k][j] = h;
+	}
+    }
+}
+
+#ifndef NOSTREAMIO
+template <class T>
+void Matrix<T>::printrow ( OSTREAM & s, int i ) const
+{
+    s << "( " << elems[i][0];
+    for ( int j = 1; j < NC; j++ )
+	s << ", " << elems[i][j];
+    s << " )";
+}
+
+template <class T>
+void Matrix<T>::print( OSTREAM& s ) const
+{
+    if ( NR == 0 )
+	s << "( )";
+    else if ( NR == 1 ) {
+	s << "( ";
+	printrow( s, 0 );
+	s << " )";
+    }
+    else {
+	int i;
+	s << "(\n";
+	printrow( s, 0 );
+	for ( i = 1; i < NR; i++ ) {
+	    s << ",\n";
+	    printrow( s, i );
+	}
+	s << "\n)";
+    }
+}
+#endif /* NOSTREAMIO */
+
+/*template <class T>
+Matrix<T> operator+ ( const Matrix<T>& lhs, const Matrix<T>& rhs )
+{
+    ASSERT( lhs.NR == rhs.NR && lhs.NC == rhs.NC, "incompatible matrices" );
+    Matrix<T> res( lhs.NR, rhs.NR );
+    int i, j;
+    for ( i = 0; i < lhs.NR; i++ )
+	for ( j = 0; j < lhs.NC; j++ )
+	    res.elems[i][j] = lhs.elems[i][j] + rhs.elems[i][j];
+    return res;
+}
+
+template <class T>
+Matrix<T> operator- ( const Matrix<T>& lhs, const Matrix<T>& rhs )
+{
+    ASSERT( lhs.NR == rhs.NR && lhs.NC == rhs.NC, "incompatible matrices" );
+    Matrix<T> res( lhs.NR, rhs.NR );
+    int i, j;
+    for ( i = 0; i < lhs.NR; i++ )
+	for ( j = 0; j < lhs.NC; j++ )
+	    res.elems[i][j] = lhs.elems[i][j] - rhs.elems[i][j];
+    return res;
+}
+
+template <class T>
+Matrix<T> operator* ( const Matrix<T>& lhs, const T& rhs )
+{
+    Matrix<T> res( lhs.NR, lhs.NC );
+    int i, j;
+    for ( i = 0; i < lhs.NR; i++ )
+	for ( j = 0; j < lhs.NC; j++ )
+	    res.elems[i][j] = lhs.elems[i][j] * rhs;
+    return res;
+}
+
+template <class T>
+Matrix<T> operator* ( const T& lhs, const Matrix<T>& rhs )
+{
+    Matrix<T> res( rhs.NR, rhs.NC );
+    int i, j;
+    for ( i = 0; i < rhs.NR; i++ )
+	for ( j = 0; j < rhs.NC; j++ )
+	    res.elems[i][j] = rhs.elems[i][j] * lhs;
+    return res;
+}
+
+template <class T>
+Matrix<T> operator* ( const Matrix<T>& lhs, const Matrix<T>& rhs )
+{
+    ASSERT( lhs.NC == rhs.NR, "incompatible matrices" );
+    Matrix<T> res( lhs.NR, rhs.NC );
+    int i, j, k;
+    for ( i = 0; i < lhs.NR; i++ )
+	for ( j = 0; j < rhs.NC; j++ ) {
+	    res[i][j] = 0;
+	    for ( k = 0; k < lhs.NC; k++ )
+		res[i][j]+= lhs.elems[i][k] * rhs.elems[k][j];
+	}
+    return res;
+}*/
+
+template <class T>
+SubMatrix<T>::SubMatrix( int rmin, int rmax, int cmin, int cmax, const Matrix<T> & m ) : r_min(rmin), r_max(rmax), c_min(cmin), c_max(cmax), M((Matrix<T>&)m) {}
+
+template <class T>
+SubMatrix<T>::SubMatrix( const SubMatrix<T> & S ) : r_min(S.r_min), r_max(S.r_max), c_min(S.c_min), c_max(S.c_max), M(S.M) {}
+
+template <class T>
+SubMatrix<T>& SubMatrix<T>::operator= ( const Matrix<T>& S )
+{
+    ASSERT( r_max - r_min + 1 == S.NR && c_max - c_min + 1 == S.NC, "incompatible matrices" );
+    if ( M.elems != S.elems ) {
+	int i, j;
+	for ( i = 0; i < S.NR; i++ )
+	    for ( j = 0; j < S.NC; j++ )
+		M.elems[r_min+i-1][c_min+j-1] = S.elems[i][j];
+    }
+    return *this;
+}
+
+template <class T>
+SubMatrix<T>& SubMatrix<T>::operator= ( const SubMatrix<T>& S )
+{
+    ASSERT( r_max - r_min == S.r_max - S.r_min && c_max - c_min == S.c_max - S.c_min, "incompatible matrices" );
+    int i, j, n, m;
+    n = r_max - r_min + 1;
+    m = c_max - c_min + 1;
+    if ( M.elems == S.M.elems ) {
+	if ( r_min < S.r_min ) {
+	    for ( i = 0; i < n; i++ )
+		for ( j = 0; j < m; j++ )
+		    M.elems[r_min+i-1][c_min+j-1] = S.M.elems[S.r_min+i-1][S.c_min+j-1];
+	}
+	else if ( r_min > S.r_min ) {
+	    for ( i = n-1; i >= 0; i-- )
+		for ( j = 0; j < m; j++ )
+		    M.elems[r_min+i-1][c_min+j-1] = S.M.elems[S.r_min+i-1][S.c_min+j-1];
+	}
+	else if ( c_min < S.c_min ) {
+	    for ( j = 0; j < m; j++ )
+		for ( i = 0; i < n; i++ )
+		    M.elems[r_min+i-1][c_min+j-1] = S.M.elems[S.r_min+i-1][S.c_min+j-1];
+	}
+	else if ( c_min > S.c_min ) {
+	    for ( j = m-1; j >= 0; j-- )
+		for ( i = 0; i < n; i++ )
+		    M.elems[r_min+i-1][c_min+j-1] = S.M.elems[S.r_min+i-1][S.c_min+j-1];
+	}
+    }
+    else {
+	for ( i = 0; i < n; i++ )
+	    for ( j = 0; j < m; j++ )
+		M.elems[r_min+i-1][c_min+j-1] = S.M.elems[S.r_min+i-1][S.c_min+j-1];
+    }
+    return *this;
+}
+
+template <class T>
+SubMatrix<T>::operator Matrix<T>() const
+{
+    Matrix<T> res( r_max - r_min + 1, c_max - c_min + 1 );
+    int i, j;
+    int n = r_max - r_min + 1, m = c_max - c_min + 1;
+    for ( i = 0; i < n; i++ )
+	for ( j = 0; j < m; j++ )
+	    res.elems[i][j] = M.elems[r_min+i-1][c_min+j-1];
+    return res;
+}
+
+template <class T>
+T SubMatrix<T>::operator[] ( int i ) const
+{
+    ASSERT( r_min == r_max && i >= c_min && i <= c_max, "illegal index" );
+    return M.elems[r_min-1][i-1];
+}
+
+template <class T>
+T& SubMatrix<T>::operator[] ( int i )
+{
+    ASSERT( r_min == r_max && i >= c_min && i <= c_max, "illegal index" );
+    return M.elems[r_min-1][i-1];
+}
+
+#ifndef NOSTREAMIO
+template <class T>
+OSTREAM & operator<< ( OSTREAM & s, const Matrix<T>& M )
+{
+   M.print( s );
+   return s;
+}
+#endif /* NOSTREAMIO */
diff --git a/factory/test.cc b/factory/test.cc
new file mode 100644
index 0000000..39be452
--- /dev/null
+++ b/factory/test.cc
@@ -0,0 +1,132 @@
+#include <factory/factory.h>
+#ifdef SINGULAR
+#include <resources/feFopen.h>
+#include <resources/feResource.h>
+#endif
+#include "cf_assert.h"
+
+int test2 (int p)
+{
+  int ret = 1;
+  setCharacteristic (p);
+  printf ("p: %d, i: %d", p, 0);
+  CanonicalForm d1= Variable (1) + Variable (2) + 1;
+  CanonicalForm f1= Variable (1) - Variable (2) - 2;
+  CanonicalForm g1= Variable (1) + Variable (2) + 2;
+  CanonicalForm d= power (d1, 2);
+  CanonicalForm f= d* power (f1, 2);
+  CanonicalForm g= d* power (g1, 2);
+  CanonicalForm h= gcd (f,g);
+  h /= Lc (h);
+  printf (", h==d? %d\n", (h == d));
+  if (h != d)
+    ret = -1;
+  for (int i= 3; i <= 11; i++)
+  {
+    printf ("p: %d, i: %d", p, i);
+    d1 += power (Variable (i), i);
+    f1 -= power (Variable (i), i);
+    g1 += power (Variable (i), i);
+    d= power (d1, 2);
+    f= d*power (f1, 2);
+    g= d*power (g1, 2);
+    h= gcd (f,g);
+    h /= Lc (h);
+    printf (", h==d? %d\n", (h == d));
+    if (h != d)
+      ret = -1;
+  }
+  return ret;
+}
+
+/*int test5 (int p)
+{
+  setCharacteristic (p);
+  Variable x= Variable (1);
+  CanonicalForm d1= x + 1;
+  CanonicalForm d2= Variable (2) + 1;
+  CanonicalForm f1= x - 2;
+  CanonicalForm f2= Variable (2) - 2;
+  CanonicalForm g1= x + 2;
+  CanonicalForm g2= Variable (2) + 2;
+  CanonicalForm d= d1*d2 - 2;
+  CanonicalForm f= f1*f2 + 2;
+  CanonicalForm g= g1*g2 - 2;
+  f *= d;
+  g *= d;
+  CanonicalForm h= gcd (f, g);
+  h /= Lc (h);
+  if (h != d)
+    return - 1;
+  printf ("h==d? %d\n", (h == d));
+  for (int i= 3; i <= 11; i++)
+  {
+    d2 *= power (Variable (i), i) + 1;
+    f2 *= power (Variable (i), i) - 2;
+    g2 *= power (Variable (i), i) + 2;
+
+    d= d1*d2 - 2;
+    f= f1*f2 + 2;
+    g= g1*g2 - 2;
+    f *= d;
+    g *= d;
+    h= gcd (f, g);
+    h /= Lc (h);
+    if (h != d)
+      return -1;
+    printf ("h==d? %d\n", (h == d));
+  }
+  return 1;
+}*/
+
+int main( int, char *argv[] )
+{
+  int ret = 0;
+
+  ASSERT( sizeof(long) == SIZEOF_LONG, "Bad config.h: wrong size of long!"  );
+
+  if( sizeof(long) != SIZEOF_LONG )
+  {
+    printf("Bad config.h: wrong size of long!");
+
+    return(1);
+  }
+
+#ifdef SINGULAR
+  feInitResources(argv[0]);
+#endif
+
+//  On (SW_USE_EZGCD); On (SW_USE_EZGCD_P); // TODO&NOTE: these switches lead to failed tests (with nonzero p)!
+
+  Off (SW_USE_EZGCD);
+  Off (SW_USE_CHINREM_GCD);
+
+  int t= test2 (0);
+  if (t < 0)
+    ret = t;
+  /*t= test5 (0);
+  if (t < 0)
+    return t;
+  t= test5 (3);
+  if (t < 0)
+    return t;
+  t= test5 (101);
+  if (t < 0)
+    return t;
+  t= test5 (43051);
+  if (t < 0)
+    return t;*/
+  t= test2 (3);
+  if (t < 0)
+    ret += t;
+
+  t= test2 (101);
+  if (t < 0)
+    ret += t;
+
+  t= test2 (43051);
+  if (t < 0)
+    ret += t;
+
+  return ret;
+}
diff --git a/factory/test_install.cc b/factory/test_install.cc
new file mode 100644
index 0000000..dd4cfff
--- /dev/null
+++ b/factory/test_install.cc
@@ -0,0 +1,20 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+//{{{ docu
+//
+// test_install.cc - test factory installation.
+//
+//}}}
+
+#include <factory.h>
+
+int
+main ()
+{
+    // this will try to locate the GF(q) tables
+    setCharacteristic( 2, 3, 'Z' );
+    printf( "%s\n", factoryVersion );
+    printf( "%s\n", factoryConfiguration );
+    printf( "Factory lives!!" );
+    return 0;
+}
diff --git a/factory/timing.h b/factory/timing.h
new file mode 100644
index 0000000..8be75b0
--- /dev/null
+++ b/factory/timing.h
@@ -0,0 +1,94 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+/* It should be possible to include this file multiple times for different */
+/* settings of TIMING */
+
+#undef TIMING_START
+#undef TIMING_END
+#undef TIMING_END_AND_PRINT
+#undef TIMING_DEFINE_PRINT
+#undef TIMING_DEFINE_PRINTPROTO
+#undef TIMING_PRINT
+
+#ifdef TIMING
+#include <time.h>
+#if ! defined(WINNT) || defined(__GNUC__)
+#include <sys/times.h>
+#include <sys/param.h>
+#endif
+#ifndef NOSTREAMIO
+#ifdef HAVE_CSTDIO
+#include <cstdio>
+#else
+#include <stdio.h>
+#endif
+#endif
+
+// need to be adjusted on your machine:
+// the number of ticks per second: HZ
+#if ! defined (HZ) && defined (CLOCKS_PER_SEC)
+#define HZ CLOCKS_PER_SEC
+#endif
+#if ! defined (HZ)  && defined (CLK_TCK)
+#define HZ CLK_TCK
+#endif
+#ifndef HZ
+#ifdef sun
+#define HZ 60.0
+#else
+#define HZ 100.0
+#endif
+#endif
+
+#if defined(WINNT) && ! defined(__GNUC__)
+
+#define TIMING_START(t) timing_ ## t ## _start = clock();
+#define TIMING_END(t) timing_ ## t ## _end = clock(); \
+timing_ ## t ## _time += timing_ ## t ## _end - timing_ ## t ## _start;
+#define TIMING_END_AND_PRINT(t, msg) times( &timing_ ## t ## _end ); \
+  fprintf( stderr, "%s%.2f sec\n", msg, \
+	   float( timing_ ## t ## _end - timing_ ## t ## _start ) / HZ ); \
+  timing_ ## t ## _time += timing_ ## t ## _end - timing_ ## t ## _start;
+#define TIMING_DEFINE_PRINT(t) static clock_t timing_ ## t ## _start, timing_ ## t ## _end; \
+static clock_t timing_ ## t ## _time; \
+static void timing_print_ ## t ( char * msg ) { \
+  fprintf( stderr, "%s%.2f sec\n", msg, float(timing_ ## t ## _time) / HZ ); \
+} \
+static void timing_reset_ ## t () { \
+  timing_ ## t ## _time = 0; \
+}
+
+#else /* ! WINNT */
+
+#define TIMING_START(t) times( &timing_ ## t ## _start );
+#define TIMING_END(t) times( &timing_ ## t ## _end ); \
+  timing_ ## t ## _time += timing_ ## t ## _end.tms_utime - timing_ ## t ## _start.tms_utime;
+#define TIMING_END_AND_PRINT(t, msg) times( &timing_ ## t ## _end ); \
+  fprintf( stderr, "%s%.2f sec\n", msg, \
+	   float( timing_ ## t ## _end.tms_utime - timing_ ## t ## _start.tms_utime ) / HZ ); \
+  timing_ ## t ## _time += timing_ ## t ## _end.tms_utime - timing_ ## t ## _start.tms_utime;
+#define TIMING_DEFINE_PRINT(t) static struct tms timing_ ## t ## _start, timing_ ## t ## _end; \
+static long timing_ ## t ## _time; \
+static void timing_print_ ## t ( char * msg ) { \
+  fprintf( stderr, "%s%.2f sec\n", msg, float(timing_ ## t ## _time) / HZ ); \
+} \
+static void timing_reset_ ## t () { \
+  timing_ ## t ## _time = 0; \
+}
+#endif /* ! WINNT */
+
+/* macros common to all platforms */
+#define TIMING_DEFINE_PRINTPROTO(t) void timing_print_ ## t ( char * ); \
+  void timing_reset_ ## t ();
+#define TIMING_PRINT(t, msg) timing_print_ ## t ( msg );
+#define TIMING_RESET(t) timing_reset_ ## t ();
+
+#else /* TIMING */
+#define TIMING_START(t)
+#define TIMING_END(t)
+#define TIMING_END_AND_PRINT(t, msg)
+#define TIMING_DEFINE_PRINT(t)
+#define TIMING_DEFINE_PRINTPROTO(t)
+#define TIMING_PRINT(t, msg)
+#define TIMING_RESET(t)
+#endif /* TIMING */
diff --git a/factory/variable.cc b/factory/variable.cc
new file mode 100644
index 0000000..f0e606b
--- /dev/null
+++ b/factory/variable.cc
@@ -0,0 +1,314 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+
+#include "config.h"
+
+
+#include <string.h>
+
+#include "cf_assert.h"
+
+#include "cf_defs.h"
+#include "variable.h"
+#include "canonicalform.h"
+#include "cf_factory.h"
+#include "int_poly.h"
+#include "cf_iter.h"
+
+class ext_entry
+{
+private:
+    InternalPoly * _mipo;
+    bool _reduce;
+public:
+    ext_entry () : _mipo(0), _reduce(false) {}
+    ext_entry ( InternalPoly * mipoly, bool reduce ) : _mipo(mipoly), _reduce(reduce) {};
+    ext_entry ( const ext_entry & e ) : _mipo(e._mipo), _reduce(e._reduce) {}
+    ~ext_entry () {};
+    ext_entry & operator= ( const ext_entry & e )
+    {
+        if ( this != &e ) {
+            _mipo = e._mipo;
+            _reduce = e._reduce;
+        }
+        return *this;
+    }
+    InternalPoly * mipo () { return _mipo; }
+    void setmipo( InternalPoly * p ) { _mipo = p; }
+    bool & reduce () { return _reduce; }
+};
+
+static ext_entry * algextensions = 0;
+static char * var_names = 0;
+static char * var_names_ext = 0;
+static char default_name = 'v';
+static char default_name_ext = 'a';
+
+Variable::Variable( int l, bool flag ) : _level(l)
+{
+    ASSERT( flag, "illegal level" );
+}
+
+Variable::Variable( int l ) : _level(l)
+{
+    //ASSERT( l > 0 && l != LEVELQUOT, "illegal level" );
+}
+
+Variable::Variable( char name )
+{
+    bool isext = false;
+    int n, i;
+    if ( var_names_ext != 0 ) {
+        n = strlen( var_names_ext );
+        i = 1;
+        while ( i < n && var_names_ext[i] != name ) i++;
+        if ( i < n ) {
+            _level = -i;
+            isext = true;
+        }
+    }
+    if ( ! isext ) {
+        if ( var_names == 0 ) {
+            var_names = new char [3];
+            var_names[0] = '@';
+            var_names[1] = name;
+            var_names[2] = '\0';
+            _level = 1;
+        }
+        else {
+            n = strlen( var_names );
+            i = 1;
+            while ( i < n && var_names[i] != name ) i++;
+            if ( i < n )
+                _level = i;
+            else {
+                ASSERT( name != '@', "illegal variable name" );
+                char * newvarnames = new char [n+2];
+                for ( i = 0; i < n; i++ )
+                    newvarnames[i] = var_names[i];
+                newvarnames[n] = name;
+                newvarnames[n+1] = 0;
+                delete [] var_names;
+                var_names = newvarnames;
+                _level = n;
+            }
+        }
+    }
+}
+
+Variable::Variable( int l, char name ) : _level(l)
+{
+    ASSERT( l > 0 && l != LEVELQUOT, "illegal level" );
+    int n;
+    if ( (n = (var_names == 0 ? 0 : strlen( var_names ))) <= l ) {
+        char * newvarnames = new char [l+2];
+        int i;
+        for ( i = 0; i < n; i++ )
+            newvarnames[i] = var_names[i];
+        for ( i = n; i < l; i++ )
+            newvarnames[i] = '@';
+        newvarnames[l] = name;
+        newvarnames[l+1] = 0;
+        delete [] var_names;
+        var_names = newvarnames;
+    }
+    else {
+        ASSERT( var_names[l] == '@', "illegal name" );
+        var_names[l] = name;
+    }
+}
+
+char
+Variable::name() const
+{
+    if ( _level > 0 && _level < (int)strlen( var_names ) )
+        return( var_names[_level] );
+    else if ( _level < 0 && -_level < (int)strlen( var_names_ext ) )
+        return( var_names_ext[-_level] );
+    else
+        return '@';
+}
+
+#ifndef NOSTREAMIO
+OSTREAM & operator << ( OSTREAM & os, const Variable & v )
+{
+    if ( v._level == LEVELBASE )
+        os << "1";
+    else {
+        char * vn = ( v._level > 0 ) ? var_names : var_names_ext;
+        char dn = ( v._level > 0 ) ? default_name : default_name_ext;
+        int l = v._level;
+
+        if ( l < 0 ) l = -l;
+        if ( (vn == 0) || ((int)strlen( vn ) <= l) )
+            os << dn << "_" << l;
+        else  if ( vn[l] == '@' )
+            os << dn << "_" << l;
+        else
+            os << vn[l];
+    }
+    return os;
+}
+#endif /* NOSTREAMIO */
+
+static CanonicalForm conv2mipo ( const CanonicalForm & mipo, const Variable & alpha )
+{
+    CanonicalForm result;
+    for ( CFIterator i = mipo; i.hasTerms(); i++ )
+        result += i.coeff() * power( alpha, i.exp() );
+    return result;
+}
+
+Variable rootOf( const CanonicalForm & mipo, char name )
+{
+    ASSERT (mipo.isUnivariate(), "not a legal extension");
+
+    int l;
+    if ( var_names_ext == 0 ) {
+        var_names_ext = new char [3];
+        var_names_ext[0] = '@';
+        var_names_ext[1] = name;
+        var_names_ext[2] = '\0';
+        l = 1;
+        Variable result( -l, true );
+        algextensions = new ext_entry [2];
+        algextensions[1] = ext_entry( 0, false );
+        algextensions[1] = ext_entry( (InternalPoly*)(conv2mipo( mipo, result ).getval()), true );
+        return result;
+    }
+    else {
+        int i, n = strlen( var_names_ext );
+        char * newvarnames = new char [n+2];
+        for ( i = 0; i < n; i++ )
+            newvarnames[i] = var_names_ext[i];
+        newvarnames[n] = name;
+        newvarnames[n+1] = 0;
+        delete [] var_names_ext;
+        var_names_ext = newvarnames;
+        l = n;
+        Variable result( -l, true );
+        ext_entry * newalgext = new ext_entry [n+1];
+        for ( i = 0; i < n; i++ )
+            newalgext[i] = algextensions[i];
+        newalgext[n] = ext_entry( 0, false );
+        delete [] algextensions;
+        algextensions = newalgext;
+        algextensions[n] = ext_entry( (InternalPoly*)(conv2mipo( mipo, result ).getval()), true );
+        return result;
+    }
+}
+
+InternalPoly * getInternalMipo ( const Variable & alpha )
+{
+    ASSERT( alpha.level() < 0 && alpha.level() != LEVELBASE, "illegal extension" );
+    return algextensions[-alpha.level()].mipo();
+}
+
+CanonicalForm getMipo( const Variable & alpha, const Variable & x )
+{
+    ASSERT( alpha.level() < 0 && alpha.level() != LEVELBASE, "illegal extension" );
+    return CanonicalForm( algextensions[-alpha.level()].mipo()->copyObject() )(x,alpha);
+}
+
+CanonicalForm getMipo( const Variable & alpha )
+{
+    ASSERT( alpha.level() < 0 && alpha.level() != LEVELBASE, "illegal extension" );
+    return CanonicalForm( algextensions[-alpha.level()].mipo()->copyObject() );
+}
+
+void setMipo ( const Variable & alpha, const CanonicalForm & mipo)
+{
+    ASSERT( alpha.level() < 0 && alpha.level() != LEVELBASE, "illegal extension" );
+    algextensions[-alpha.level()]= ext_entry( 0, false );
+    algextensions[-alpha.level()]= ext_entry((InternalPoly*)(conv2mipo( mipo, alpha ).getval()), true );
+}
+
+bool hasMipo( const Variable & alpha )
+{
+    ASSERT( alpha.level() < 0, "illegal extension" );
+    return (alpha.level() != LEVELBASE && (algextensions!=NULL) && getReduce(alpha) );
+}
+
+bool getReduce( const Variable & alpha )
+{
+    ASSERT( alpha.level() < 0 && alpha.level() != LEVELBASE, "illegal extension" );
+    return algextensions[-alpha.level()].reduce();
+}
+
+void setReduce( const Variable & alpha, bool reduce )
+{
+    ASSERT( alpha.level() < 0 && alpha.level() != LEVELBASE, "illegal extension" );
+    algextensions[-alpha.level()].reduce() = reduce;
+}
+
+char getDefaultVarName()
+{
+    return default_name;
+}
+
+char getDefaultExtName()
+{
+    return default_name_ext;
+}
+
+int ExtensionLevel()
+{
+  if( var_names_ext == 0)
+    return 0;
+  return strlen( var_names_ext )-1;
+}
+
+void prune (Variable& alpha)
+{
+  int i, n = strlen( var_names_ext );
+  ASSERT (n+1 >= -alpha.level(), "wrong variable");
+  if (-alpha.level() == 1)
+  {
+    delete [] var_names_ext;
+    delete [] algextensions;
+    var_names_ext= 0;
+    algextensions= 0;
+    alpha= Variable();
+    return;
+  }
+  char * newvarnames = new char [-alpha.level() + 1];
+  for ( i = 0; i < -alpha.level(); i++ )
+    newvarnames[i] = var_names_ext[i];
+  newvarnames[-alpha.level()] = 0;
+  delete [] var_names_ext;
+  var_names_ext = newvarnames;
+  ext_entry * newalgext = new ext_entry [-alpha.level()];
+  for ( i = 0; i < -alpha.level(); i++ )
+    newalgext[i] = algextensions[i];
+  delete [] algextensions;
+  algextensions = newalgext;
+  alpha= Variable();
+}
+
+void prune1 (const Variable& alpha)
+{
+  int i, n = strlen( var_names_ext );
+  ASSERT (n+1 >= -alpha.level(), "wrong variable");
+
+  char * newvarnames = new char [-alpha.level() + 2];
+  for ( i = 0; i <= -alpha.level(); i++ )
+    newvarnames[i] = var_names_ext[i];
+  newvarnames[-alpha.level()+1] = 0;
+  delete [] var_names_ext;
+  var_names_ext = newvarnames;
+  ext_entry * newalgext = new ext_entry [-alpha.level()+1];
+  for ( i = 0; i <= -alpha.level(); i++ )
+    newalgext[i] = algextensions[i];
+  delete [] algextensions;
+  algextensions = newalgext;
+}
+
+void Reduce( bool on)
+{
+  int i;
+  for (i=ExtensionLevel(); i>0;i--)
+  {
+    Variable l(-i);
+    setReduce(l,on);
+  }
+}
diff --git a/factory/variable.h b/factory/variable.h
new file mode 100644
index 0000000..d0ade14
--- /dev/null
+++ b/factory/variable.h
@@ -0,0 +1,117 @@
+/* emacs edit mode for this file is -*- C++ -*- */
+
+/**
+ * @file variable.h
+ *
+ * operations on variables
+**/
+#ifndef INCL_VARIABLE_H
+#define INCL_VARIABLE_H
+
+// #include "config.h"
+
+#ifndef NOSTREAMIO
+# ifdef HAVE_IOSTREAM
+#  include <iostream>
+#  define OSTREAM std::ostream
+# elif defined(HAVE_IOSTREAM_H)
+#  include <iostream.h>
+#  define OSTREAM ostream
+# endif
+#endif /* NOSTREAMIO */
+
+#include "cf_defs.h"
+
+/*BEGINPUBLIC*/
+
+class CanonicalForm;
+
+/**
+ * factory's class for variables
+**/
+class Variable
+{
+private:
+    int _level;
+    Variable( int l, bool flag );
+public:
+    Variable() : _level(LEVELBASE) {}
+    Variable( int l );
+    Variable( char name );
+    Variable( int l, char name );
+    Variable( const Variable & v ) : _level(v._level) {}
+    ~Variable() {};
+    Variable& operator= ( const Variable & v )
+    {
+	_level = v._level;
+	return *this;
+    }
+    int level() const { return _level; }
+    char name() const;
+    static Variable highest() { return Variable( LEVELQUOT-1 ); }
+    Variable next() const { return Variable( _level+1 ); }
+    friend bool operator == ( const Variable & lhs, const Variable & rhs )
+    {
+	return lhs._level == rhs._level;
+    }
+    friend bool operator != ( const Variable & lhs, const Variable & rhs )
+    {
+	return lhs._level != rhs._level;
+    }
+    friend bool operator > ( const Variable & lhs, const Variable & rhs )
+    {
+	return lhs._level > rhs._level;
+    }
+    friend bool operator < ( const Variable & lhs, const Variable & rhs )
+    {
+	return lhs._level < rhs._level;
+    }
+    friend bool operator >= ( const Variable & lhs, const Variable & rhs )
+    {
+	return lhs._level >= rhs._level;
+    }
+    friend bool operator <= ( const Variable & lhs, const Variable & rhs )
+    {
+	return lhs._level <= rhs._level;
+    }
+#ifndef NOSTREAMIO
+   friend OSTREAM & operator << ( OSTREAM & os, const Variable & v );
+#endif /* NOSTREAMIO */
+    friend void swap_levels();
+    /** returns a symbolic root of polynomial with name @a name.
+     *  Use it to define algebraic variables
+     *  @note: algebraic variables have a level < 0
+    **/
+    friend Variable rootOf( const CanonicalForm &, char name );
+};
+
+/** returns a symbolic root of polynomial with name @a name
+ *  Use it to define algebraic variables
+ *  @note: algebraic variables have a level < 0
+**/
+Variable rootOf( const CanonicalForm &, char name = '@' );
+
+inline int level( const Variable & v ) { return v.level(); }
+inline char name( const Variable & v ) { return v.name(); }
+
+void setReduce( const Variable & alpha, bool reduce );
+void setMipo ( const Variable & alpha, const CanonicalForm & mipo);
+CanonicalForm getMipo( const Variable & alpha, const Variable & x );
+bool hasMipo( const Variable & alpha );
+
+char getDefaultVarName();
+char getDefaultExtName();
+
+void prune (Variable& alpha);
+void prune1 (const Variable& alpha);
+int ExtensionLevel();
+
+/*ENDPUBLIC*/
+
+// the following functions do not need to be public available
+CanonicalForm getMipo( const Variable & alpha );
+class InternalPoly;
+InternalPoly * getInternalMipo ( const Variable & alpha );
+bool getReduce( const Variable & alpha );
+
+#endif /* ! INCL_VARIABLE_H */
diff --git a/gfanlib/Makefile.am b/gfanlib/Makefile.am
new file mode 100644
index 0000000..cb0bd4b
--- /dev/null
+++ b/gfanlib/Makefile.am
@@ -0,0 +1,19 @@
+ACLOCAL_AMFLAGS = -I ../m4
+
+if HAVE_GFANLIB
+  libgfan_LTLIBRARIES=libgfan.la
+endif
+
+libgfandir = $(libdir)
+
+AM_CPPFLAGS = -I${top_srcdir} -I${top_builddir} -DGMPRATIONAL
+
+SOURCES  = gfanlib_zcone.cpp gfanlib_symmetry.cpp gfanlib_symmetriccomplex.cpp gfanlib_polyhedralfan.cpp gfanlib_zfan.cpp gfanlib_polymakefile.cpp
+libgfan_la_SOURCES   = $(SOURCES)
+
+libgfan_includedir  =$(includedir)/gfanlib
+
+libgfan_include_HEADERS = gfanlib_z.h gfanlib_q.h gfanlib_vector.h gfanlib_matrix.h gfanlib_zcone.h gfanlib.h gfanlib_polyhedralfan.h gfanlib_polymakefile.h gfanlib_symmetriccomplex.h gfanlib_symmetry.h gfanlib_zfan.h
+
+DISTCLEANFILES =  config.h
+
diff --git a/gfanlib/Makefile.in b/gfanlib/Makefile.in
new file mode 100644
index 0000000..c403335
--- /dev/null
+++ b/gfanlib/Makefile.in
@@ -0,0 +1,891 @@
+# Makefile.in generated by automake 1.13.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 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@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+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 = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/configure $(am__configure_deps) \
+	$(srcdir)/_config.h.in $(top_srcdir)/../build-aux/depcomp \
+	$(libgfan_include_HEADERS) ../build-aux/ar-lib \
+	../build-aux/compile ../build-aux/config.guess \
+	../build-aux/config.sub ../build-aux/depcomp \
+	../build-aux/install-sh ../build-aux/missing \
+	../build-aux/ylwrap ../build-aux/ltmain.sh \
+	$(top_srcdir)/../build-aux/ar-lib \
+	$(top_srcdir)/../build-aux/config.guess \
+	$(top_srcdir)/../build-aux/config.sub \
+	$(top_srcdir)/../build-aux/install-sh \
+	$(top_srcdir)/../build-aux/ltmain.sh \
+	$(top_srcdir)/../build-aux/missing
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/../m4/ax_append_compile_flags.m4 \
+	$(top_srcdir)/../m4/ax_append_flag.m4 \
+	$(top_srcdir)/../m4/ax_append_link_flags.m4 \
+	$(top_srcdir)/../m4/ax_check_compile_flag.m4 \
+	$(top_srcdir)/../m4/ax_check_link_flag.m4 \
+	$(top_srcdir)/../m4/ax_prefix_config_h.m4 \
+	$(top_srcdir)/../m4/flags.m4 \
+	$(top_srcdir)/../m4/gfanlib-check.m4 \
+	$(top_srcdir)/../m4/gmp-check.m4 \
+	$(top_srcdir)/../m4/libtool.m4 \
+	$(top_srcdir)/../m4/ltoptions.m4 \
+	$(top_srcdir)/../m4/ltsugar.m4 \
+	$(top_srcdir)/../m4/ltversion.m4 \
+	$(top_srcdir)/../m4/lt~obsolete.m4 $(top_srcdir)/configure.ac
+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 =
+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__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
+am__installdirs = "$(DESTDIR)$(libgfandir)" \
+	"$(DESTDIR)$(libgfan_includedir)"
+LTLIBRARIES = $(libgfan_LTLIBRARIES)
+libgfan_la_LIBADD =
+am__objects_1 = gfanlib_zcone.lo gfanlib_symmetry.lo \
+	gfanlib_symmetriccomplex.lo gfanlib_polyhedralfan.lo \
+	gfanlib_zfan.lo gfanlib_polymakefile.lo
+am_libgfan_la_OBJECTS = $(am__objects_1)
+libgfan_la_OBJECTS = $(am_libgfan_la_OBJECTS)
+AM_V_lt = $(am__v_lt_ at AM_V@)
+am__v_lt_ = $(am__v_lt_ at AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 = 
+ at HAVE_GFANLIB_TRUE@am_libgfan_la_rpath = -rpath $(libgfandir)
+AM_V_P = $(am__v_P_ at AM_V@)
+am__v_P_ = $(am__v_P_ at AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_ at AM_V@)
+am__v_GEN_ = $(am__v_GEN_ at AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_ at AM_V@)
+am__v_at_ = $(am__v_at_ at AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+DEFAULT_INCLUDES = -I. at am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/../build-aux/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \
+	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+	$(AM_CXXFLAGS) $(CXXFLAGS)
+AM_V_CXX = $(am__v_CXX_ at AM_V@)
+am__v_CXX_ = $(am__v_CXX_ at AM_DEFAULT_V@)
+am__v_CXX_0 = @echo "  CXX     " $@;
+am__v_CXX_1 = 
+CXXLD = $(CXX)
+CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+	$(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CXXLD = $(am__v_CXXLD_ at AM_V@)
+am__v_CXXLD_ = $(am__v_CXXLD_ at AM_DEFAULT_V@)
+am__v_CXXLD_0 = @echo "  CXXLD   " $@;
+am__v_CXXLD_1 = 
+DIST_SOURCES = $(libgfan_la_SOURCES)
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+HEADERS = $(libgfan_include_HEADERS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \
+	$(LISP)_config.h.in
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+CSCOPE = cscope
+AM_RECURSIVE_TARGETS = cscope
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+distdir = $(PACKAGE)-$(VERSION)
+top_distdir = $(distdir)
+am__remove_distdir = \
+  if test -d "$(distdir)"; then \
+    find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \
+      && rm -rf "$(distdir)" \
+      || { sleep 5 && rm -rf "$(distdir)"; }; \
+  else :; fi
+am__post_remove_distdir = $(am__remove_distdir)
+DIST_ARCHIVES = $(distdir).tar.gz
+GZIP_ENV = --best
+DIST_TARGETS = dist-gzip
+distuninstallcheck_listfiles = find . -type f -print
+am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \
+  | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$'
+distcleancheck_listfiles = find . -type f -print
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CDDGMPCPPFLAGS = @CDDGMPCPPFLAGS@
+CDDGMPLDFLAGS = @CDDGMPLDFLAGS@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+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@
+FGREP = @FGREP@
+GMP_CFLAGS = @GMP_CFLAGS@
+GMP_HOME = @GMP_HOME@
+GMP_LIBS = @GMP_LIBS@
+GMP_VERSION = @GMP_VERSION@
+GREP = @GREP@
+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@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+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@
+POLYMAKE_CXXFLAGS = @POLYMAKE_CXXFLAGS@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SINGULAR_CFLAGS = @SINGULAR_CFLAGS@
+STRIP = @STRIP@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+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@
+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@
+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@
+ACLOCAL_AMFLAGS = -I ../m4
+ at HAVE_GFANLIB_TRUE@libgfan_LTLIBRARIES = libgfan.la
+libgfandir = $(libdir)
+AM_CPPFLAGS = -I${top_srcdir} -I${top_builddir} -DGMPRATIONAL
+SOURCES = gfanlib_zcone.cpp gfanlib_symmetry.cpp gfanlib_symmetriccomplex.cpp gfanlib_polyhedralfan.cpp gfanlib_zfan.cpp gfanlib_polymakefile.cpp
+libgfan_la_SOURCES = $(SOURCES)
+libgfan_includedir = $(includedir)/gfanlib
+libgfan_include_HEADERS = gfanlib_z.h gfanlib_q.h gfanlib_vector.h gfanlib_matrix.h gfanlib_zcone.h gfanlib.h gfanlib_polyhedralfan.h gfanlib_polymakefile.h gfanlib_symmetriccomplex.h gfanlib_symmetry.h gfanlib_zfan.h
+DISTCLEANFILES = config.h
+all: _config.h
+	$(MAKE) $(AM_MAKEFLAGS) all-am
+
+.SUFFIXES:
+.SUFFIXES: .cpp .lo .o .obj
+am--refresh: Makefile
+	@:
+$(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) --foreign'; \
+	      $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \
+		&& exit 0; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign 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; else :; fi
+	@if test ! -f $@; then $(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
+
+install-libgfanLTLIBRARIES: $(libgfan_LTLIBRARIES)
+	@$(NORMAL_INSTALL)
+	@list='$(libgfan_LTLIBRARIES)'; test -n "$(libgfandir)" || list=; \
+	list2=; for p in $$list; do \
+	  if test -f $$p; then \
+	    list2="$$list2 $$p"; \
+	  else :; fi; \
+	done; \
+	test -z "$$list2" || { \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(libgfandir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(libgfandir)" || exit 1; \
+	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libgfandir)'"; \
+	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libgfandir)"; \
+	}
+
+uninstall-libgfanLTLIBRARIES:
+	@$(NORMAL_UNINSTALL)
+	@list='$(libgfan_LTLIBRARIES)'; test -n "$(libgfandir)" || list=; \
+	for p in $$list; do \
+	  $(am__strip_dir) \
+	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libgfandir)/$$f'"; \
+	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libgfandir)/$$f"; \
+	done
+
+clean-libgfanLTLIBRARIES:
+	-test -z "$(libgfan_LTLIBRARIES)" || rm -f $(libgfan_LTLIBRARIES)
+	@list='$(libgfan_LTLIBRARIES)'; \
+	locs=`for p in $$list; do echo $$p; done | \
+	      sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+	      sort -u`; \
+	test -z "$$locs" || { \
+	  echo rm -f $${locs}; \
+	  rm -f $${locs}; \
+	}
+
+libgfan.la: $(libgfan_la_OBJECTS) $(libgfan_la_DEPENDENCIES) $(EXTRA_libgfan_la_DEPENDENCIES) 
+	$(AM_V_CXXLD)$(CXXLINK) $(am_libgfan_la_rpath) $(libgfan_la_OBJECTS) $(libgfan_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/gfanlib_polyhedralfan.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/gfanlib_polymakefile.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/gfanlib_symmetriccomplex.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/gfanlib_symmetry.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/gfanlib_zcone.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/gfanlib_zfan.Plo at am__quote@
+
+.cpp.o:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+ at am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXXCOMPILE) -c -o $@ $<
+
+.cpp.obj:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+ at am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.cpp.lo:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+ at am__fastdepCXX_TRUE@	$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LTCXXCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+
+distclean-libtool:
+	-rm -f libtool config.lt
+install-libgfan_includeHEADERS: $(libgfan_include_HEADERS)
+	@$(NORMAL_INSTALL)
+	@list='$(libgfan_include_HEADERS)'; test -n "$(libgfan_includedir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(libgfan_includedir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(libgfan_includedir)" || exit 1; \
+	fi; \
+	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)$(libgfan_includedir)'"; \
+	  $(INSTALL_HEADER) $$files "$(DESTDIR)$(libgfan_includedir)" || exit $$?; \
+	done
+
+uninstall-libgfan_includeHEADERS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(libgfan_include_HEADERS)'; test -n "$(libgfan_includedir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	dir='$(DESTDIR)$(libgfan_includedir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	$(am__define_uniq_tagged_files); \
+	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-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	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"
+cscope: cscope.files
+	test ! -s cscope.files \
+	  || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS)
+clean-cscope:
+	-rm -f cscope.files
+cscope.files: clean-cscope cscopelist
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+	-rm -f cscope.out cscope.in.out cscope.po.out cscope.files
+
+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
+	-test -n "$(am__skip_mode_fix)" \
+	|| find "$(distdir)" -type d ! -perm -755 \
+		-exec chmod u+rwx,go+rx {} \; -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__post_remove_distdir)
+
+dist-bzip2: distdir
+	tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2
+	$(am__post_remove_distdir)
+
+dist-lzip: distdir
+	tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz
+	$(am__post_remove_distdir)
+
+dist-xz: distdir
+	tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz
+	$(am__post_remove_distdir)
+
+dist-tarZ: distdir
+	tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
+	$(am__post_remove_distdir)
+
+dist-shar: distdir
+	shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
+	$(am__post_remove_distdir)
+
+dist-zip: distdir
+	-rm -f $(distdir).zip
+	zip -rq $(distdir).zip $(distdir)
+	$(am__post_remove_distdir)
+
+dist dist-all:
+	$(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:'
+	$(am__post_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) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\
+	*.tar.bz2*) \
+	  bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
+	*.tar.lz*) \
+	  lzip -dc $(distdir).tar.lz | $(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) gzip -dc $(distdir).shar.gz | unshar ;;\
+	*.zip*) \
+	  unzip $(distdir).zip ;;\
+	esac
+	chmod -R a-w $(distdir)
+	chmod u+w $(distdir)
+	mkdir $(distdir)/_build $(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" \
+	    $(AM_DISTCHECK_CONFIGURE_FLAGS) \
+	    $(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__post_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:
+	@test -n '$(distuninstallcheck_dir)' || { \
+	  echo 'ERROR: trying to run $@ with an empty' \
+	       '$$(distuninstallcheck_dir)' >&2; \
+	  exit 1; \
+	}; \
+	$(am__cd) '$(distuninstallcheck_dir)' || { \
+	  echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \
+	  exit 1; \
+	}; \
+	test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \
+	   || { 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-am
+all-am: Makefile $(LTLIBRARIES) $(HEADERS) _config.h
+installdirs:
+	for dir in "$(DESTDIR)$(libgfandir)" "$(DESTDIR)$(libgfan_includedir)"; 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:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+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)
+	-test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
+
+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-libgfanLTLIBRARIES clean-libtool \
+	mostlyclean-am
+
+distclean: distclean-am
+	-rm -f $(am__CONFIG_DISTCLEAN_FILES)
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+	distclean-hdr distclean-libtool distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-libgfanLTLIBRARIES \
+	install-libgfan_includeHEADERS
+
+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 $(am__CONFIG_DISTCLEAN_FILES)
+	-rm -rf $(top_srcdir)/autom4te.cache
+	-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-libgfanLTLIBRARIES \
+	uninstall-libgfan_includeHEADERS
+
+.MAKE: all install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am am--refresh check check-am clean \
+	clean-cscope clean-generic clean-libgfanLTLIBRARIES \
+	clean-libtool cscope cscopelist-am ctags ctags-am dist \
+	dist-all dist-bzip2 dist-gzip dist-lzip dist-shar dist-tarZ \
+	dist-xz dist-zip distcheck distclean distclean-compile \
+	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-libgfanLTLIBRARIES \
+	install-libgfan_includeHEADERS 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 tags-am uninstall uninstall-am \
+	uninstall-libgfanLTLIBRARIES uninstall-libgfan_includeHEADERS
+
+
+# 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/gfanlib/_config.h.in b/gfanlib/_config.h.in
new file mode 100644
index 0000000..c2fa586
--- /dev/null
+++ b/gfanlib/_config.h.in
@@ -0,0 +1,95 @@
+/* _config.h.in.  Generated from configure.ac by autoheader.  */
+
+/* Define if GMP is version 3.xxx */
+#undef GMP_VERSION_3
+
+/* Define to 1 if you have the <cddlib/setoper.h> header file. */
+#undef HAVE_CDDLIB_SETOPER_H
+
+/* Define to 1 if you have the <cdd/setoper.h> header file. */
+#undef HAVE_CDD_SETOPER_H
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
+
+/* whether gfanlib support is enabled */
+#undef HAVE_GFANLIB
+
+/* Define if GMP is installed */
+#undef HAVE_GMP
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the <setoper.h> header file. */
+#undef HAVE_SETOPER_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
+
+/* "Disable OM Debug" */
+#undef OM_NDEBUG
+
+/* Name of package */
+#undef PACKAGE
+
+/* 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
+
+/* SINGULAR_CFLAGS */
+#undef SINGULAR_CFLAGS
+
+/* "Disable Singular Debug" */
+#undef SING_NDEBUG
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Version number of package */
+#undef VERSION
+
+/* Define to `__inline__' or `__inline' if that's what the C compiler
+   calls it, or to nothing if 'inline' is not supported under any name.  */
+#ifndef __cplusplus
+#undef inline
+#endif
diff --git a/gfanlib/aclocal.m4 b/gfanlib/aclocal.m4
new file mode 100644
index 0000000..13f355f
--- /dev/null
+++ b/gfanlib/aclocal.m4
@@ -0,0 +1,1148 @@
+# generated automatically by aclocal 1.13.4 -*- Autoconf -*-
+
+# Copyright (C) 1996-2013 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_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])
+m4_ifndef([AC_AUTOCONF_VERSION],
+  [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],,
+[m4_warning([this file was generated for autoconf 2.69.
+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'.])])
+
+# Copyright (C) 2002-2013 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.13'
+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.13.4], [],
+      [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.13.4])dnl
+m4_ifndef([AC_AUTOCONF_VERSION],
+  [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
+
+# Copyright (C) 2011-2013 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_AR([ACT-IF-FAIL])
+# -------------------------
+# Try to determine the archiver interface, and trigger the ar-lib wrapper
+# if it is needed.  If the detection of archiver interface fails, run
+# ACT-IF-FAIL (default is to abort configure with a proper error message).
+AC_DEFUN([AM_PROG_AR],
+[AC_BEFORE([$0], [LT_INIT])dnl
+AC_BEFORE([$0], [AC_PROG_LIBTOOL])dnl
+AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([ar-lib])dnl
+AC_CHECK_TOOLS([AR], [ar lib "link -lib"], [false])
+: ${AR=ar}
+
+AC_CACHE_CHECK([the archiver ($AR) interface], [am_cv_ar_interface],
+  [am_cv_ar_interface=ar
+   AC_COMPILE_IFELSE([AC_LANG_SOURCE([[int some_variable = 0;]])],
+     [am_ar_try='$AR cru libconftest.a conftest.$ac_objext >&AS_MESSAGE_LOG_FD'
+      AC_TRY_EVAL([am_ar_try])
+      if test "$ac_status" -eq 0; then
+        am_cv_ar_interface=ar
+      else
+        am_ar_try='$AR -NOLOGO -OUT:conftest.lib conftest.$ac_objext >&AS_MESSAGE_LOG_FD'
+        AC_TRY_EVAL([am_ar_try])
+        if test "$ac_status" -eq 0; then
+          am_cv_ar_interface=lib
+        else
+          am_cv_ar_interface=unknown
+        fi
+      fi
+      rm -f conftest.lib libconftest.a
+     ])
+   ])
+
+case $am_cv_ar_interface in
+ar)
+  ;;
+lib)
+  # Microsoft lib, so override with the ar-lib wrapper script.
+  # FIXME: It is wrong to rewrite AR.
+  # But if we don't then we get into trouble of one sort or another.
+  # A longer-term fix would be to have automake use am__AR in this case,
+  # and then we could set am__AR="$am_aux_dir/ar-lib \$(AR)" or something
+  # similar.
+  AR="$am_aux_dir/ar-lib $AR"
+  ;;
+unknown)
+  m4_default([$1],
+             [AC_MSG_ERROR([could not determine $AR interface])])
+  ;;
+esac
+AC_SUBST([AR])dnl
+])
+
+# AM_AUX_DIR_EXPAND                                         -*- Autoconf -*-
+
+# Copyright (C) 2001-2013 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-2013 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_CONDITIONAL(NAME, SHELL-CONDITION)
+# -------------------------------------
+# Define a conditional.
+AC_DEFUN([AM_CONDITIONAL],
+[AC_PREREQ([2.52])dnl
+ m4_if([$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-2013 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.
+
+
+# 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", "OBJC", "OBJCXX", "UPC", or "GJC".
+# 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
+
+m4_if([$1], [CC],   [depcc="$CC"   am_compiler_list=],
+      [$1], [CXX],  [depcc="$CXX"  am_compiler_list=],
+      [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
+      [$1], [OBJCXX], [depcc="$OBJCXX" 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".
+  rm -rf conftest.dir
+  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 10 /bin/sh.
+      echo '/* dummy */' > 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
+      ;;
+    msvc7 | msvc7msys | 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], [dnl
+AS_HELP_STRING(
+  [--enable-dependency-tracking],
+  [do not reject slow dependency extractors])
+AS_HELP_STRING(
+  [--disable-dependency-tracking],
+  [speeds up one-time build])])
+if test "x$enable_dependency_tracking" != xno; then
+  am_depcomp="$ac_aux_dir/depcomp"
+  AMDEPBACKSLASH='\'
+  am__nodep='_no'
+fi
+AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
+AC_SUBST([AMDEPBACKSLASH])dnl
+_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl
+AC_SUBST([am__nodep])dnl
+_AM_SUBST_NOTMAKE([am__nodep])dnl
+])
+
+# Generate code to set up dependency tracking.              -*- Autoconf -*-
+
+# Copyright (C) 1999-2013 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_OUTPUT_DEPENDENCY_COMMANDS
+# ------------------------------
+AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
+[{
+  # Older Autoconf 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"`
+    # 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'`; 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"])
+])
+
+# Do all the work for Automake.                             -*- Autoconf -*-
+
+# Copyright (C) 1996-2013 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 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.65])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],
+[AC_DIAGNOSE([obsolete],
+             [$0: two- and three-arguments forms are deprecated.])
+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], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]),
+  [ok:ok],,
+  [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([AC_PROG_MKDIR_P])dnl
+# For better backward compatibility.  To be removed once Automake 1.9.x
+# dies out for good.  For more background, see:
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
+AC_SUBST([mkdir_p], ['$(MKDIR_P)'])
+# 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])],
+		  [m4_define([AC_PROG_CC],
+			     m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_CXX],
+		  [_AM_DEPENDENCIES([CXX])],
+		  [m4_define([AC_PROG_CXX],
+			     m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_OBJC],
+		  [_AM_DEPENDENCIES([OBJC])],
+		  [m4_define([AC_PROG_OBJC],
+			     m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_OBJCXX],
+		  [_AM_DEPENDENCIES([OBJCXX])],
+		  [m4_define([AC_PROG_OBJCXX],
+			     m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl
+])
+AC_REQUIRE([AM_SILENT_RULES])dnl
+dnl The testsuite driver may need to know about EXEEXT, so add the
+dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen.  This
+dnl macro 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-2013 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-2013 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.
+
+# 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-2013 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_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 enable maintainer-specific portions of Makefiles])
+  dnl maintainer-mode's default is 'disable' unless 'enable' is passed
+  AC_ARG_ENABLE([maintainer-mode],
+    [AS_HELP_STRING([--]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
+]
+)
+
+# Check to see how 'make' treats includes.	            -*- Autoconf -*-
+
+# Copyright (C) 2001-2013 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_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-2013 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_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 is modern enough.
+# If it is, 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 --is-lightweight"; then
+  am_missing_run="$MISSING "
+else
+  am_missing_run=
+  AC_MSG_WARN(['missing' script is too old or missing])
+fi
+])
+
+# Helper functions for option handling.                     -*- Autoconf -*-
+
+# Copyright (C) 2001-2013 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_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-2013 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_SANITY_CHECK
+# ---------------
+AC_DEFUN([AM_SANITY_CHECK],
+[AC_MSG_CHECKING([whether build environment is sane])
+# 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 (
+   am_has_slept=no
+   for am_try in 1 2; do
+     echo "timestamp, slept: $am_has_slept" > conftest.file
+     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
+     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
+     if test "$[2]" = conftest.file || test $am_try -eq 2; then
+       break
+     fi
+     # Just in case.
+     sleep 1
+     am_has_slept=yes
+   done
+   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])
+# If we didn't sleep, we still need to ensure time stamps of config.status and
+# generated files are strictly newer.
+am_sleep_pid=
+if grep 'slept: no' conftest.file >/dev/null 2>&1; then
+  ( sleep 1 ) &
+  am_sleep_pid=$!
+fi
+AC_CONFIG_COMMANDS_PRE(
+  [AC_MSG_CHECKING([that generated files are newer than configure])
+   if test -n "$am_sleep_pid"; then
+     # Hide warnings about reused PIDs.
+     wait $am_sleep_pid 2>/dev/null
+   fi
+   AC_MSG_RESULT([done])])
+rm -f conftest.file
+])
+
+# Copyright (C) 2009-2013 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_SILENT_RULES([DEFAULT])
+# --------------------------
+# Enable less verbose build rules; with the default set to DEFAULT
+# ("yes" being less verbose, "no" or empty being verbose).
+AC_DEFUN([AM_SILENT_RULES],
+[AC_ARG_ENABLE([silent-rules], [dnl
+AS_HELP_STRING(
+  [--enable-silent-rules],
+  [less verbose build output (undo: "make V=1")])
+AS_HELP_STRING(
+  [--disable-silent-rules],
+  [verbose build output (undo: "make V=0")])dnl
+])
+case $enable_silent_rules in @%:@ (((
+  yes) AM_DEFAULT_VERBOSITY=0;;
+   no) AM_DEFAULT_VERBOSITY=1;;
+    *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);;
+esac
+dnl
+dnl A few 'make' implementations (e.g., NonStop OS and NextStep)
+dnl do not support nested variable expansions.
+dnl See automake bug#9928 and bug#10237.
+am_make=${MAKE-make}
+AC_CACHE_CHECK([whether $am_make supports nested variables],
+   [am_cv_make_support_nested_variables],
+   [if AS_ECHO([['TRUE=$(BAR$(V))
+BAR0=false
+BAR1=true
+V=1
+am__doit:
+	@$(TRUE)
+.PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then
+  am_cv_make_support_nested_variables=yes
+else
+  am_cv_make_support_nested_variables=no
+fi])
+if test $am_cv_make_support_nested_variables = yes; then
+  dnl Using '$V' instead of '$(V)' breaks IRIX make.
+  AM_V='$(V)'
+  AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
+else
+  AM_V=$AM_DEFAULT_VERBOSITY
+  AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY
+fi
+AC_SUBST([AM_V])dnl
+AM_SUBST_NOTMAKE([AM_V])dnl
+AC_SUBST([AM_DEFAULT_V])dnl
+AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl
+AC_SUBST([AM_DEFAULT_VERBOSITY])dnl
+AM_BACKSLASH='\'
+AC_SUBST([AM_BACKSLASH])dnl
+_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl
+])
+
+# Copyright (C) 2001-2013 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-2013 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_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-2013 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_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.  Yes, it's still used
+# in the wild :-(  We should find a proper way to deprecate it ...
+AC_SUBST([AMTAR], ['$${TAR-tar}'])
+
+# We'll loop over all known methods to create a tar archive until one works.
+_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
+
+m4_if([$1], [v7],
+  [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'],
+
+  [m4_case([$1],
+    [ustar],
+     [# The POSIX 1988 'ustar' format is defined with fixed-size fields.
+      # There is notably a 21 bits limit for the UID and the GID.  In fact,
+      # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343
+      # and bug#13588).
+      am_max_uid=2097151 # 2^21 - 1
+      am_max_gid=$am_max_uid
+      # The $UID and $GID variables are not portable, so we need to resort
+      # to the POSIX-mandated id(1) utility.  Errors in the 'id' calls
+      # below are definitely unexpected, so allow the users to see them
+      # (that is, avoid stderr redirection).
+      am_uid=`id -u || echo unknown`
+      am_gid=`id -g || echo unknown`
+      AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format])
+      if test $am_uid -le $am_max_uid; then
+         AC_MSG_RESULT([yes])
+      else
+         AC_MSG_RESULT([no])
+         _am_tools=none
+      fi
+      AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format])
+      if test $am_gid -le $am_max_gid; then
+         AC_MSG_RESULT([yes])
+      else
+        AC_MSG_RESULT([no])
+        _am_tools=none
+      fi],
+
+  [pax],
+    [],
+
+  [m4_fatal([Unknown tar format])])
+
+  AC_MSG_CHECKING([how to create a $1 tar archive])
+
+  # Go ahead even if we have the value already cached.  We do so because we
+  # need to set the values for the 'am__tar' and 'am__untar' variables.
+  _am_tools=${am_cv_prog_tar_$1-$_am_tools}
+
+  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])
+      AM_RUN_LOG([cat conftest.dir/file])
+      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([../m4/ax_append_compile_flags.m4])
+m4_include([../m4/ax_append_flag.m4])
+m4_include([../m4/ax_append_link_flags.m4])
+m4_include([../m4/ax_check_compile_flag.m4])
+m4_include([../m4/ax_check_link_flag.m4])
+m4_include([../m4/ax_prefix_config_h.m4])
+m4_include([../m4/flags.m4])
+m4_include([../m4/gfanlib-check.m4])
+m4_include([../m4/gmp-check.m4])
+m4_include([../m4/libtool.m4])
+m4_include([../m4/ltoptions.m4])
+m4_include([../m4/ltsugar.m4])
+m4_include([../m4/ltversion.m4])
+m4_include([../m4/lt~obsolete.m4])
diff --git a/gfanlib/configure b/gfanlib/configure
new file mode 100755
index 0000000..47096a2
--- /dev/null
+++ b/gfanlib/configure
@@ -0,0 +1,20821 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.69 for libgfan 0.1.
+#
+# Report bugs to <ren at mathematik.uni-kl.de>.
+#
+#
+# Copyright (C) 1992-1996, 1998-2012 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.
+as_myself=
+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
+
+# Use a proper internal environment variable to ensure we don't fall
+  # into an infinite loop, continuously re-executing ourselves.
+  if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then
+    _as_can_reexec=no; export _as_can_reexec;
+    # 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.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+  *v*x* | *x*v* ) as_opts=-vx ;;
+  *v* ) as_opts=-v ;;
+  *x* ) as_opts=-x ;;
+  * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+as_fn_exit 255
+  fi
+  # We don't want this to propagate to other subprocesses.
+          { _as_can_reexec=; unset _as_can_reexec;}
+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
+test -x / || 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 -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || (
+    ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+    ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO
+    ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO
+    PATH=/empty FPATH=/empty; export PATH FPATH
+    test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\
+      || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || 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 :
+  export CONFIG_SHELL
+             # 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.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+  *v*x* | *x*v* ) as_opts=-vx ;;
+  *v* ) as_opts=-v ;;
+  *x* ) as_opts=-x ;;
+  * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+exit 255
+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 and
+$0: ren at mathematik.uni-kl.de about your system, including
+$0: any error possibly output before this message. Then
+$0: install a modern shell, or manually run the script
+$0: 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_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+  test -f "$1" && test -x "$1"
+} # as_fn_executable_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 STATUS 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=$1; test $as_status -eq 0 && as_status=1
+  if test "$4"; then
+    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+  fi
+  $as_echo "$as_me: error: $2" >&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; }
+
+  # If we had to re-execute with $CONFIG_SHELL, we're ensured to have
+  # already done that, so ensure we don't try to do so again and fall
+  # in an infinite loop.  This has already happened in practice.
+  _as_can_reexec=no; export _as_can_reexec
+  # 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 -pR'.
+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+      as_ln_s='cp -pR'
+  elif ln conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s=ln
+  else
+    as_ln_s='cp -pR'
+  fi
+else
+  as_ln_s='cp -pR'
+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
+
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
+
+# 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'"
+
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+
+test -n "$DJDIR" || exec 7<&0 </dev/null
+exec 6>&1
+
+# Name of the host.
+# hostname on some systems (SVR3.2, old GNU/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='libgfan'
+PACKAGE_TARNAME='libgfan'
+PACKAGE_VERSION='0.1'
+PACKAGE_STRING='libgfan 0.1'
+PACKAGE_BUGREPORT='ren at mathematik.uni-kl.de'
+PACKAGE_URL=''
+
+ac_unique_file="gfanlib.h"
+# 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
+HAVE_GFANLIB_FALSE
+HAVE_GFANLIB_TRUE
+CDDGMPCPPFLAGS
+CDDGMPLDFLAGS
+SING_HAVE_GMP_FALSE
+SING_HAVE_GMP_TRUE
+GMP_VERSION
+GMP_HOME
+GMP_LIBS
+GMP_CFLAGS
+CXXCPP
+CPP
+OTOOL64
+OTOOL
+LIPO
+NMEDIT
+DSYMUTIL
+MANIFEST_TOOL
+RANLIB
+DLLTOOL
+OBJDUMP
+NM
+ac_ct_DUMPBIN
+DUMPBIN
+LD
+FGREP
+EGREP
+GREP
+SED
+host_os
+host_vendor
+host_cpu
+host
+build_os
+build_vendor
+build_cpu
+build
+LIBTOOL
+LN_S
+POLYMAKE_CXXFLAGS
+am__fastdepCXX_FALSE
+am__fastdepCXX_TRUE
+CXXDEPMODE
+ac_ct_CXX
+CXXFLAGS
+CXX
+SINGULAR_CFLAGS
+WANT_OPTIMIZATIONFLAGS_FALSE
+WANT_OPTIMIZATIONFLAGS_TRUE
+WANT_DEBUG_FALSE
+WANT_DEBUG_TRUE
+MAINT
+MAINTAINER_MODE_FALSE
+MAINTAINER_MODE_TRUE
+am__fastdepCC_FALSE
+am__fastdepCC_TRUE
+CCDEPMODE
+am__nodep
+AMDEPBACKSLASH
+AMDEP_FALSE
+AMDEP_TRUE
+am__quote
+am__include
+DEPDIR
+OBJEXT
+EXEEXT
+ac_ct_CC
+CPPFLAGS
+LDFLAGS
+CFLAGS
+CC
+ac_ct_AR
+AR
+AM_BACKSLASH
+AM_DEFAULT_VERBOSITY
+AM_DEFAULT_V
+AM_V
+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
+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_silent_rules
+enable_dependency_tracking
+enable_maintainer_mode
+enable_debug
+enable_optimizationflags
+enable_shared
+enable_static
+with_pic
+enable_fast_install
+with_gnu_ld
+with_sysroot
+enable_libtool_lock
+with_gmp
+enable_gfanlib
+'
+      ac_precious_vars='build_alias
+host_alias
+target_alias
+CC
+CFLAGS
+LDFLAGS
+LIBS
+CPPFLAGS
+CXX
+CXXFLAGS
+CCC
+CPP
+CXXCPP'
+
+
+# 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_TARNAME}'
+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= ;;
+  *)    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
+  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 libgfan 0.1 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/libgfan]
+  --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
+  case $ac_init_help in
+     short | recursive ) echo "Configuration of libgfan 0.1:";;
+   esac
+  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-silent-rules   less verbose build output (undo: "make V=1")
+  --disable-silent-rules  verbose build output (undo: "make V=0")
+  --enable-dependency-tracking
+                          do not reject slow dependency extractors
+  --disable-dependency-tracking
+                          speeds up one-time build
+  --disable-maintainer-mode
+                          disable make rules and dependencies not useful (and
+                          sometimes confusing) to the casual installer
+  --enable-debug          build the debugging version of the libraries
+  --disable-optimizationflags
+                          build the without default optimization flags
+  --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-gfanlib        Enables gfanlib, a package for basic convex geometry
+
+Optional Packages:
+  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
+  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
+  --with-pic[=PKGS]       try to use only PIC/non-PIC objects [default=use
+                          both]
+  --with-gnu-ld           assume the C compiler uses GNU ld [default=no]
+  --with-sysroot=DIR Search for dependent libraries within DIR
+                        (or the compiler's sysroot if not specified).
+  --with-gmp= <path>|yes Use GMP library. This library is mandatory for Singular
+	                 compilation. If argument is yes or <empty> that means
+   	       		 the library is reachable with the standard search path
+			 "/usr" or "/usr/local" (set as default). Otherwise you
+			 give the <path> to the directory which contain the
+			 library.
+
+
+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    (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
+              you have headers in a nonstandard directory <include dir>
+  CXX         C++ compiler command
+  CXXFLAGS    C++ compiler flags
+  CPP         C preprocessor
+  CXXCPP      C++ preprocessor
+
+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 <ren at mathematik.uni-kl.de>.
+_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
+libgfan configure 0.1
+generated by GNU Autoconf 2.69
+
+Copyright (C) 2012 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; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_compile
+
+# ac_fn_cxx_try_compile LINENO
+# ----------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_cxx_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_cxx_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; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_cxx_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 ||
+	 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; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $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 eval \${$3+:} false; 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; ${as_lineno_stack:+:} 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; } > conftest.i && {
+	 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; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $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; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $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 eval \${$3+:} false; 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; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_func
+
+# ac_fn_cxx_try_cpp LINENO
+# ------------------------
+# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
+ac_fn_cxx_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; } > conftest.i && {
+	 test -z "$ac_cxx_preproc_warn_flag$ac_cxx_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; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_cxx_try_cpp
+
+# ac_fn_cxx_try_link LINENO
+# -------------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded.
+ac_fn_cxx_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_cxx_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext && {
+	 test "$cross_compiling" = yes ||
+	 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; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_cxx_try_link
+
+# 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 eval \${$3+:} false; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; 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.i 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;}
+( $as_echo "## --------------------------------------- ##
+## Report this to ren at mathematik.uni-kl.de ##
+## --------------------------------------- ##"
+     ) | sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; 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; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_header_mongrel
+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 libgfan $as_me 0.1, which was
+generated by GNU Autoconf 2.69.  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
+
+    $as_echo "## ---------------- ##
+## Cache variables. ##
+## ---------------- ##"
+    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
+
+    $as_echo "## ----------------- ##
+## Output variables. ##
+## ----------------- ##"
+    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
+      $as_echo "## ------------------- ##
+## File substitutions. ##
+## ------------------- ##"
+      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
+      $as_echo "## ----------- ##
+## confdefs.h. ##
+## ----------- ##"
+      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
+  # We do not want a PATH search for config.site.
+  case $CONFIG_SITE in #((
+    -*)  ac_site_file1=./$CONFIG_SITE;;
+    */*) ac_site_file1=$CONFIG_SITE;;
+    *)   ac_site_file1=./$CONFIG_SITE;;
+  esac
+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 /dev/null != "$ac_site_file" && 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" \
+      || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "failed to load site script $ac_site_file
+See \`config.log' for more details" "$LINENO" 5; }
+  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.  DJGPP emulates it as a regular file.
+  if test /dev/null != "$cache_file" && 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_aux_dir=
+for ac_dir in ../build-aux "$srcdir"/../build-aux; do
+  if test -f "$ac_dir/install-sh"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install-sh -c"
+    break
+  elif test -f "$ac_dir/install.sh"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install.sh -c"
+    break
+  elif test -f "$ac_dir/shtool"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/shtool install -c"
+    break
+  fi
+done
+if test -z "$ac_aux_dir"; then
+  as_fn_error $? "cannot find install-sh, install.sh, or shtool in ../build-aux \"$srcdir\"/../build-aux" "$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.
+
+
+
+ac_config_headers="$ac_config_headers _config.h"
+
+
+am__api_version='1.13'
+
+# 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 ${ac_cv_path_install+:} false; 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 as_fn_executable_p "$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; }
+# 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 (
+   am_has_slept=no
+   for am_try in 1 2; do
+     echo "timestamp, slept: $am_has_slept" > conftest.file
+     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
+     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
+     if test "$2" = conftest.file || test $am_try -eq 2; then
+       break
+     fi
+     # Just in case.
+     sleep 1
+     am_has_slept=yes
+   done
+   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; }
+# If we didn't sleep, we still need to ensure time stamps of config.status and
+# generated files are strictly newer.
+am_sleep_pid=
+if grep 'slept: no' conftest.file >/dev/null 2>&1; then
+  ( sleep 1 ) &
+  am_sleep_pid=$!
+fi
+
+rm -f conftest.file
+
+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 --is-lightweight"; then
+  am_missing_run="$MISSING "
+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 ${ac_cv_prog_STRIP+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_STRIP+:} false; 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 as_fn_executable_p "$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 ${ac_cv_path_mkdir+:} false; 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
+	   as_fn_executable_p "$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
+
+  test -d ./--version && rmdir ./--version
+  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.
+    MKDIR_P="$ac_install_sh -d"
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5
+$as_echo "$MKDIR_P" >&6; }
+
+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 ${ac_cv_prog_AWK+:} false; 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 as_fn_executable_p "$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 eval \${ac_cv_prog_make_${ac_make}_set+:} false; 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
+
+# Check whether --enable-silent-rules was given.
+if test "${enable_silent_rules+set}" = set; then :
+  enableval=$enable_silent_rules;
+fi
+
+case $enable_silent_rules in # (((
+  yes) AM_DEFAULT_VERBOSITY=0;;
+   no) AM_DEFAULT_VERBOSITY=1;;
+    *) AM_DEFAULT_VERBOSITY=1;;
+esac
+am_make=${MAKE-make}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5
+$as_echo_n "checking whether $am_make supports nested variables... " >&6; }
+if ${am_cv_make_support_nested_variables+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if $as_echo 'TRUE=$(BAR$(V))
+BAR0=false
+BAR1=true
+V=1
+am__doit:
+	@$(TRUE)
+.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then
+  am_cv_make_support_nested_variables=yes
+else
+  am_cv_make_support_nested_variables=no
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5
+$as_echo "$am_cv_make_support_nested_variables" >&6; }
+if test $am_cv_make_support_nested_variables = yes; then
+    AM_V='$(V)'
+  AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
+else
+  AM_V=$AM_DEFAULT_VERBOSITY
+  AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY
+fi
+AM_BACKSLASH='\'
+
+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='libgfan'
+ VERSION='0.1'
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE "$PACKAGE"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define VERSION "$VERSION"
+_ACEOF
+
+# 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"}
+
+# For better backward compatibility.  To be removed once Automake 1.9.x
+# dies out for good.  For more background, see:
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
+mkdir_p='$(MKDIR_P)'
+
+# We need awk for the "check" target.  The system "awk" is bad on
+# some platforms.
+# Always define AMTAR for backward compatibility.  Yes, it's still used
+# in the wild :-(  We should find a proper way to deprecate it ...
+AMTAR='$${TAR-tar}'
+
+
+# We'll loop over all known methods to create a tar archive until one works.
+_am_tools='gnutar  pax cpio none'
+
+am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'
+
+
+
+
+
+ # -Wno-extra-portability -Werror silent-rules
+# Check whether --enable-silent-rules was given.
+if test "${enable_silent_rules+set}" = set; then :
+  enableval=$enable_silent_rules;
+fi
+
+case $enable_silent_rules in # (((
+  yes) AM_DEFAULT_VERBOSITY=0;;
+   no) AM_DEFAULT_VERBOSITY=1;;
+    *) AM_DEFAULT_VERBOSITY=0;;
+esac
+am_make=${MAKE-make}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5
+$as_echo_n "checking whether $am_make supports nested variables... " >&6; }
+if ${am_cv_make_support_nested_variables+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if $as_echo 'TRUE=$(BAR$(V))
+BAR0=false
+BAR1=true
+V=1
+am__doit:
+	@$(TRUE)
+.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then
+  am_cv_make_support_nested_variables=yes
+else
+  am_cv_make_support_nested_variables=no
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5
+$as_echo "$am_cv_make_support_nested_variables" >&6; }
+if test $am_cv_make_support_nested_variables = yes; then
+    AM_V='$(V)'
+  AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
+else
+  AM_V=$AM_DEFAULT_VERBOSITY
+  AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY
+fi
+AM_BACKSLASH='\'
+
+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='\'
+  am__nodep='_no'
+fi
+ if test "x$enable_dependency_tracking" != xno; then
+  AMDEP_TRUE=
+  AMDEP_FALSE='#'
+else
+  AMDEP_TRUE='#'
+  AMDEP_FALSE=
+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 ${ac_cv_prog_CC+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_CC+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_CC+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_CC+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_CC+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_CC+:} false; 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 as_fn_executable_p "$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
+  fi
+  rm -f conftest.er1 conftest.err
+  $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.  */
+
+int
+main ()
+{
+
+  ;
+  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"
+# 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 whether the C compiler works" >&5
+$as_echo_n "checking whether the C compiler works... " >&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
+if test -z "$ac_file"; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+$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 77 "C compiler cannot create executables
+See \`config.log' for more details" "$LINENO" 5; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+fi
+{ $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; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
+$as_echo "$ac_file" >&6; }
+ac_exeext=$ac_cv_exeext
+
+rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+{ $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 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
+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="$ac_clean_files conftest.out"
+# 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; }
+if test "$cross_compiling" != yes; then
+  { { 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; }
+  if { ac_try='./conftest$ac_cv_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
+    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: $cross_compiling" >&5
+$as_echo "$cross_compiling" >&6; }
+
+rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out
+ac_clean_files=$ac_clean_files_save
+{ $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 ${ac_cv_objext+:} false; 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 ${ac_cv_c_compiler_gnu+:} false; 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 ${ac_cv_prog_cc_g+:} false; 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 ${ac_cv_prog_cc_c89+:} false; 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>
+struct stat;
+/* 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
+
+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 ${am_cv_CC_dependencies_compiler_type+:} false; 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".
+  rm -rf conftest.dir
+  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 10 /bin/sh.
+      echo '/* dummy */' > 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
+      ;;
+    msvc7 | msvc7msys | 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 -n "$ac_tool_prefix"; then
+  for ac_prog in ar lib "link -lib"
+  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 ${ac_cv_prog_AR+:} false; 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_AR="$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
+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
+
+
+    test -n "$AR" && break
+  done
+fi
+if test -z "$AR"; then
+  ac_ct_AR=$AR
+  for ac_prog in ar lib "link -lib"
+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 ${ac_cv_prog_ac_ct_AR+:} false; 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_AR="$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_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
+
+
+  test -n "$ac_ct_AR" && break
+done
+
+  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
+fi
+
+: ${AR=ar}
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the archiver ($AR) interface" >&5
+$as_echo_n "checking the archiver ($AR) interface... " >&6; }
+if ${am_cv_ar_interface+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  am_cv_ar_interface=ar
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+int some_variable = 0;
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  am_ar_try='$AR cru libconftest.a conftest.$ac_objext >&5'
+      { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$am_ar_try\""; } >&5
+  (eval $am_ar_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      if test "$ac_status" -eq 0; then
+        am_cv_ar_interface=ar
+      else
+        am_ar_try='$AR -NOLOGO -OUT:conftest.lib conftest.$ac_objext >&5'
+        { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$am_ar_try\""; } >&5
+  (eval $am_ar_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+        if test "$ac_status" -eq 0; then
+          am_cv_ar_interface=lib
+        else
+          am_cv_ar_interface=unknown
+        fi
+      fi
+      rm -f conftest.lib libconftest.a
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_ar_interface" >&5
+$as_echo "$am_cv_ar_interface" >&6; }
+
+case $am_cv_ar_interface in
+ar)
+  ;;
+lib)
+  # Microsoft lib, so override with the ar-lib wrapper script.
+  # FIXME: It is wrong to rewrite AR.
+  # But if we don't then we get into trouble of one sort or another.
+  # A longer-term fix would be to have automake use am__AR in this case,
+  # and then we could set am__AR="$am_aux_dir/ar-lib \$(AR)" or something
+  # similar.
+  AR="$am_aux_dir/ar-lib $AR"
+  ;;
+unknown)
+  as_fn_error $? "could not determine $AR interface" "$LINENO" 5
+  ;;
+esac
+
+
+# Add pre'prefixed config
+
+ac_config_commands="$ac_config_commands config.h"
+
+
+
+{ $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=yes
+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
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Please note that we set empty defaults for \`CFLAGS' and \`CXXFLAGS' (instead of \`-g -O')" >&5
+$as_echo "$as_me: WARNING: Please note that we set empty defaults for \`CFLAGS' and \`CXXFLAGS' (instead of \`-g -O')" >&2;}
+ : ${CFLAGS:=""}
+ : ${CXXFLAGS:=""}
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts " >&5
+$as_echo_n "checking whether C compiler accepts ... " >&6; }
+if ${ax_cv_check_cflags__+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$CFLAGS
+  CFLAGS="$CFLAGS   -Werror"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ax_cv_check_cflags__=yes
+else
+  ax_cv_check_cflags__=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  CFLAGS=$ax_check_save_flags
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags__" >&5
+$as_echo "$ax_cv_check_cflags__" >&6; }
+if test x"$ax_cv_check_cflags__" = xyes; then :
+  :
+else
+  :
+fi
+
+if ${CFLAGS+:} false; then :
+  case " $CFLAGS " in
+    *"  "*)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS already contains "; } >&5
+  (: CFLAGS already contains ) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      ;;
+    *)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS=\"\$CFLAGS \""; } >&5
+  (: CFLAGS="$CFLAGS ") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      CFLAGS="$CFLAGS "
+      ;;
+   esac
+else
+  CFLAGS=""
+fi
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+if test -z "$CXX"; then
+  if test -n "$CCC"; then
+    CXX=$CCC
+  else
+    if test -n "$ac_tool_prefix"; then
+  for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+  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 ${ac_cv_prog_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CXX"; then
+  ac_cv_prog_CXX="$CXX" # 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CXX="$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
+CXX=$ac_cv_prog_CXX
+if test -n "$CXX"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5
+$as_echo "$CXX" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+    test -n "$CXX" && break
+  done
+fi
+if test -z "$CXX"; then
+  ac_ct_CXX=$CXX
+  for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+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 ${ac_cv_prog_ac_ct_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_CXX"; then
+  ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CXX="$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_CXX=$ac_cv_prog_ac_ct_CXX
+if test -n "$ac_ct_CXX"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5
+$as_echo "$ac_ct_CXX" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$ac_ct_CXX" && break
+done
+
+  if test "x$ac_ct_CXX" = x; then
+    CXX="g++"
+  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
+    CXX=$ac_ct_CXX
+  fi
+fi
+
+  fi
+fi
+# 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
+  fi
+  rm -f conftest.er1 conftest.err
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+done
+
+{ $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 ${ac_cv_cxx_compiler_gnu+:} false; 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_cxx_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_cxx_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5
+$as_echo "$ac_cv_cxx_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+  GXX=yes
+else
+  GXX=
+fi
+ac_test_CXXFLAGS=${CXXFLAGS+set}
+ac_save_CXXFLAGS=$CXXFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5
+$as_echo_n "checking whether $CXX accepts -g... " >&6; }
+if ${ac_cv_prog_cxx_g+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_save_cxx_werror_flag=$ac_cxx_werror_flag
+   ac_cxx_werror_flag=yes
+   ac_cv_prog_cxx_g=no
+   CXXFLAGS="-g"
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ac_cv_prog_cxx_g=yes
+else
+  CXXFLAGS=""
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+
+else
+  ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+	 CXXFLAGS="-g"
+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ac_cv_prog_cxx_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_cxx_werror_flag=$ac_save_cxx_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5
+$as_echo "$ac_cv_prog_cxx_g" >&6; }
+if test "$ac_test_CXXFLAGS" = set; then
+  CXXFLAGS=$ac_save_CXXFLAGS
+elif test $ac_cv_prog_cxx_g = yes; then
+  if test "$GXX" = yes; then
+    CXXFLAGS="-g -O2"
+  else
+    CXXFLAGS="-g"
+  fi
+else
+  if test "$GXX" = yes; then
+    CXXFLAGS="-O2"
+  else
+    CXXFLAGS=
+  fi
+fi
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+depcc="$CXX"  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 ${am_cv_CXX_dependencies_compiler_type+:} false; 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".
+  rm -rf conftest.dir
+  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_CXX_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 10 /bin/sh.
+      echo '/* dummy */' > 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
+      ;;
+    msvc7 | msvc7msys | 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_CXX_dependencies_compiler_type=$depmode
+        break
+      fi
+    fi
+  done
+
+  cd ..
+  rm -rf conftest.dir
+else
+  am_cv_CXX_dependencies_compiler_type=none
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5
+$as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; }
+CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type
+
+ if
+  test "x$enable_dependency_tracking" != xno \
+  && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then
+  am__fastdepCXX_TRUE=
+  am__fastdepCXX_FALSE='#'
+else
+  am__fastdepCXX_TRUE='#'
+  am__fastdepCXX_FALSE=
+fi
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the linker accepts " >&5
+$as_echo_n "checking whether the linker accepts ... " >&6; }
+if ${ax_cv_check_ldflags__+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$LDFLAGS
+  LDFLAGS="$LDFLAGS  "
+  _save_cflags="$CFLAGS"
+  CFLAGS="$CFLAGS -Werror"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ax_cv_check_ldflags__=yes
+else
+  ax_cv_check_ldflags__=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+  CFLAGS="$_save_cflags"
+  LDFLAGS=$ax_check_save_flags
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_ldflags__" >&5
+$as_echo "$ax_cv_check_ldflags__" >&6; }
+if test x"$ax_cv_check_ldflags__" = xyes; then :
+  :
+else
+  :
+fi
+
+
+#  SING_SHOW_FLAGS([Initial state?...])dnl
+
+ # Check whether --enable-debug was given.
+if test "${enable_debug+set}" = set; then :
+  enableval=$enable_debug; ENABLE_DEBUG="$enableval"
+else
+  ENABLE_DEBUG=""
+fi
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking debugging checks should be embedded" >&5
+$as_echo_n "checking debugging checks should be embedded... " >&6; }
+ if test "x${ENABLE_DEBUG}" != xyes; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ fi
+
+ # Check whether --enable-optimizationflags was given.
+if test "${enable_optimizationflags+set}" = set; then :
+  enableval=$enable_optimizationflags; ENABLE_OPTIMIZATION="$enableval"
+else
+  ENABLE_OPTIMIZATION="yeah"
+fi
+
+
+ if test "x${ENABLE_DEBUG}" = xyes; then
+  SINGULAR_CFLAGS=""
+  if test "x${ENABLE_OPTIMIZATION}" = xyeah; then
+   ENABLE_OPTIMIZATION="no"
+   { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Please note that we disable implicit (default) optimization flags since you have enabled the debug flags... " >&5
+$as_echo "$as_me: WARNING: Please note that we disable implicit (default) optimization flags since you have enabled the debug flags... " >&2;}
+  fi
+ else
+  SINGULAR_CFLAGS="-DSING_NDEBUG -DOM_NDEBUG"
+  # for now let '-DSING_NDEBUG -DOM_NDEBUG' be here...
+
+$as_echo "#define OM_NDEBUG 1" >>confdefs.h
+
+
+$as_echo "#define SING_NDEBUG 1" >>confdefs.h
+
+ fi
+
+ if test "x${ENABLE_OPTIMIZATION}" = xyeah; then
+   ENABLE_OPTIMIZATION="yes"
+ fi
+
+ if test "x${ENABLE_OPTIMIZATION}" = xyes; then
+  if test "x${ENABLE_DEBUG}" = xyes; then
+   { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Please note that you will be using our optimization flags together with debug flags... " >&5
+$as_echo "$as_me: WARNING: Please note that you will be using our optimization flags together with debug flags... " >&2;}
+  fi
+ fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether optimization flags should be used" >&5
+$as_echo_n "checking whether optimization flags should be used... " >&6; }
+ if test "x${ENABLE_OPTIMIZATION}" = xyes; 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; }
+ fi
+
+
+  if test x"${ENABLE_DEBUG}" = xyes; then
+  WANT_DEBUG_TRUE=
+  WANT_DEBUG_FALSE='#'
+else
+  WANT_DEBUG_TRUE='#'
+  WANT_DEBUG_FALSE=
+fi
+
+  if test x"${ENABLE_OPTIMIZATION}" = xyes; then
+  WANT_OPTIMIZATIONFLAGS_TRUE=
+  WANT_OPTIMIZATIONFLAGS_FALSE='#'
+else
+  WANT_OPTIMIZATIONFLAGS_TRUE='#'
+  WANT_OPTIMIZATIONFLAGS_FALSE=
+fi
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SINGULAR_CFLAGS "$SINGULAR_CFLAGS"
+_ACEOF
+
+
+
+# SING_SHOW_FLAGS([checking flags....])
+
+ FLAGS="-pipe -fno-common"
+ 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
+
+
+
+for flag in ${FLAGS}; do
+  as_CACHEVAR=`$as_echo "ax_cv_check_cflags__$flag" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts $flag" >&5
+$as_echo_n "checking whether C compiler accepts $flag... " >&6; }
+if eval \${$as_CACHEVAR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$CFLAGS
+  CFLAGS="$CFLAGS  $flag -Werror"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  eval "$as_CACHEVAR=yes"
+else
+  eval "$as_CACHEVAR=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  CFLAGS=$ax_check_save_flags
+fi
+eval ac_res=\$$as_CACHEVAR
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if test x"`eval 'as_val=${'$as_CACHEVAR'};$as_echo "$as_val"'`" = xyes; then :
+  if ${CFLAGS+:} false; then :
+  case " $CFLAGS " in
+    *" $flag "*)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS already contains \$flag"; } >&5
+  (: CFLAGS already contains $flag) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      ;;
+    *)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS=\"\$CFLAGS \$flag\""; } >&5
+  (: CFLAGS="$CFLAGS $flag") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      CFLAGS="$CFLAGS $flag"
+      ;;
+   esac
+else
+  CFLAGS="$flag"
+fi
+
+else
+  :
+fi
+
+done
+
+ 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=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+
+for flag in ${FLAGS}; do
+  as_CACHEVAR=`$as_echo "ax_cv_check_cxxflags__$flag" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C++ compiler accepts $flag" >&5
+$as_echo_n "checking whether C++ compiler accepts $flag... " >&6; }
+if eval \${$as_CACHEVAR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$CXXFLAGS
+  CXXFLAGS="$CXXFLAGS  $flag -Werror"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  eval "$as_CACHEVAR=yes"
+else
+  eval "$as_CACHEVAR=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  CXXFLAGS=$ax_check_save_flags
+fi
+eval ac_res=\$$as_CACHEVAR
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if test x"`eval 'as_val=${'$as_CACHEVAR'};$as_echo "$as_val"'`" = xyes; then :
+  if ${CXXFLAGS+:} false; then :
+  case " $CXXFLAGS " in
+    *" $flag "*)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CXXFLAGS already contains \$flag"; } >&5
+  (: CXXFLAGS already contains $flag) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      ;;
+    *)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CXXFLAGS=\"\$CXXFLAGS \$flag\""; } >&5
+  (: CXXFLAGS="$CXXFLAGS $flag") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      CXXFLAGS="$CXXFLAGS $flag"
+      ;;
+   esac
+else
+  CXXFLAGS="$flag"
+fi
+
+else
+  :
+fi
+
+done
+
+
+
+for flag in -fexceptions -frtti; do
+  as_CACHEVAR=`$as_echo "ax_cv_check_cxxflags__$flag" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C++ compiler accepts $flag" >&5
+$as_echo_n "checking whether C++ compiler accepts $flag... " >&6; }
+if eval \${$as_CACHEVAR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$CXXFLAGS
+  CXXFLAGS="$CXXFLAGS  $flag -Werror"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  eval "$as_CACHEVAR=yes"
+else
+  eval "$as_CACHEVAR=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  CXXFLAGS=$ax_check_save_flags
+fi
+eval ac_res=\$$as_CACHEVAR
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if test x"`eval 'as_val=${'$as_CACHEVAR'};$as_echo "$as_val"'`" = xyes; then :
+  if ${POLYMAKE_CXXFLAGS+:} false; then :
+  case " $POLYMAKE_CXXFLAGS " in
+    *" $flag "*)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : POLYMAKE_CXXFLAGS already contains \$flag"; } >&5
+  (: POLYMAKE_CXXFLAGS already contains $flag) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      ;;
+    *)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : POLYMAKE_CXXFLAGS=\"\$POLYMAKE_CXXFLAGS \$flag\""; } >&5
+  (: POLYMAKE_CXXFLAGS="$POLYMAKE_CXXFLAGS $flag") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      POLYMAKE_CXXFLAGS="$POLYMAKE_CXXFLAGS $flag"
+      ;;
+   esac
+else
+  POLYMAKE_CXXFLAGS="$flag"
+fi
+
+else
+  :
+fi
+
+done
+
+ 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
+
+
+
+
+for flag in ${FLAGS}; do
+  as_CACHEVAR=`$as_echo "ax_cv_check_ldflags__$flag" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the linker accepts $flag" >&5
+$as_echo_n "checking whether the linker accepts $flag... " >&6; }
+if eval \${$as_CACHEVAR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$LDFLAGS
+  LDFLAGS="$LDFLAGS  $flag"
+  _save_cflags="$CFLAGS"
+  CFLAGS="$CFLAGS -Werror"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "$as_CACHEVAR=yes"
+else
+  eval "$as_CACHEVAR=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+  CFLAGS="$_save_cflags"
+  LDFLAGS=$ax_check_save_flags
+fi
+eval ac_res=\$$as_CACHEVAR
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if test x"`eval 'as_val=${'$as_CACHEVAR'};$as_echo "$as_val"'`" = xyes; then :
+  if ${LDFLAGS+:} false; then :
+  case " $LDFLAGS " in
+    *" $flag "*)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : LDFLAGS already contains \$flag"; } >&5
+  (: LDFLAGS already contains $flag) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      ;;
+    *)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : LDFLAGS=\"\$LDFLAGS \$flag\""; } >&5
+  (: LDFLAGS="$LDFLAGS $flag") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      LDFLAGS="$LDFLAGS $flag"
+      ;;
+   esac
+else
+  LDFLAGS="$flag"
+fi
+
+else
+  :
+fi
+
+done
+
+
+
+
+ if test "x${ENABLE_DEBUG}" = xyes; then
+  DBGFLAGS="-g -ftrapv -fdiagnostics-show-option -Wall -Wextra"
+  #  -pedantic too strict ??? -Wvla -Wno-long-long ???
+  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
+
+
+
+for flag in ${DBGFLAGS}; do
+  as_CACHEVAR=`$as_echo "ax_cv_check_cflags__$flag" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts $flag" >&5
+$as_echo_n "checking whether C compiler accepts $flag... " >&6; }
+if eval \${$as_CACHEVAR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$CFLAGS
+  CFLAGS="$CFLAGS  $flag -Werror"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  eval "$as_CACHEVAR=yes"
+else
+  eval "$as_CACHEVAR=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  CFLAGS=$ax_check_save_flags
+fi
+eval ac_res=\$$as_CACHEVAR
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if test x"`eval 'as_val=${'$as_CACHEVAR'};$as_echo "$as_val"'`" = xyes; then :
+  if ${CFLAGS+:} false; then :
+  case " $CFLAGS " in
+    *" $flag "*)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS already contains \$flag"; } >&5
+  (: CFLAGS already contains $flag) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      ;;
+    *)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS=\"\$CFLAGS \$flag\""; } >&5
+  (: CFLAGS="$CFLAGS $flag") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      CFLAGS="$CFLAGS $flag"
+      ;;
+   esac
+else
+  CFLAGS="$flag"
+fi
+
+else
+  :
+fi
+
+done
+
+  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=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+
+for flag in ${DBGFLAGS}; do
+  as_CACHEVAR=`$as_echo "ax_cv_check_cxxflags__$flag" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C++ compiler accepts $flag" >&5
+$as_echo_n "checking whether C++ compiler accepts $flag... " >&6; }
+if eval \${$as_CACHEVAR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$CXXFLAGS
+  CXXFLAGS="$CXXFLAGS  $flag -Werror"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  eval "$as_CACHEVAR=yes"
+else
+  eval "$as_CACHEVAR=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  CXXFLAGS=$ax_check_save_flags
+fi
+eval ac_res=\$$as_CACHEVAR
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if test x"`eval 'as_val=${'$as_CACHEVAR'};$as_echo "$as_val"'`" = xyes; then :
+  if ${CXXFLAGS+:} false; then :
+  case " $CXXFLAGS " in
+    *" $flag "*)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CXXFLAGS already contains \$flag"; } >&5
+  (: CXXFLAGS already contains $flag) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      ;;
+    *)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CXXFLAGS=\"\$CXXFLAGS \$flag\""; } >&5
+  (: CXXFLAGS="$CXXFLAGS $flag") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      CXXFLAGS="$CXXFLAGS $flag"
+      ;;
+   esac
+else
+  CXXFLAGS="$flag"
+fi
+
+else
+  :
+fi
+
+done
+
+  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
+
+
+
+for flag in ${DBGFLAGS}; do
+  as_CACHEVAR=`$as_echo "ax_cv_check_ldflags__$flag" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the linker accepts $flag" >&5
+$as_echo_n "checking whether the linker accepts $flag... " >&6; }
+if eval \${$as_CACHEVAR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$LDFLAGS
+  LDFLAGS="$LDFLAGS  $flag"
+  _save_cflags="$CFLAGS"
+  CFLAGS="$CFLAGS -Werror"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "$as_CACHEVAR=yes"
+else
+  eval "$as_CACHEVAR=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+  CFLAGS="$_save_cflags"
+  LDFLAGS=$ax_check_save_flags
+fi
+eval ac_res=\$$as_CACHEVAR
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if test x"`eval 'as_val=${'$as_CACHEVAR'};$as_echo "$as_val"'`" = xyes; then :
+  if ${LDFLAGS+:} false; then :
+  case " $LDFLAGS " in
+    *" $flag "*)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : LDFLAGS already contains \$flag"; } >&5
+  (: LDFLAGS already contains $flag) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      ;;
+    *)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : LDFLAGS=\"\$LDFLAGS \$flag\""; } >&5
+  (: LDFLAGS="$LDFLAGS $flag") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      LDFLAGS="$LDFLAGS $flag"
+      ;;
+   esac
+else
+  LDFLAGS="$flag"
+fi
+
+else
+  :
+fi
+
+done
+
+ fi
+
+ ## for clang: -Wunneeded-internal-declaration
+
+ if test "x${ENABLE_OPTIMIZATION}" != xno; then
+  OPTFLAGS="-O3 -Wno-unused-function -Wno-trigraphs -Wno-unused-parameter -Wunknown-pragmas -Wno-unused-variable -fomit-frame-pointer -fwrapv -fvisibility=default -finline-functions -fno-exceptions -fno-rtti -fno-threadsafe-statics -fno-enforce-eh-specs -fconserve-space -funroll-loops"
+  #  -O3 - crashes gcc???!!!
+  # -fpermissive
+  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
+
+
+
+for flag in ${OPTFLAGS}; do
+  as_CACHEVAR=`$as_echo "ax_cv_check_cflags__$flag" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts $flag" >&5
+$as_echo_n "checking whether C compiler accepts $flag... " >&6; }
+if eval \${$as_CACHEVAR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$CFLAGS
+  CFLAGS="$CFLAGS  $flag -Werror"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  eval "$as_CACHEVAR=yes"
+else
+  eval "$as_CACHEVAR=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  CFLAGS=$ax_check_save_flags
+fi
+eval ac_res=\$$as_CACHEVAR
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if test x"`eval 'as_val=${'$as_CACHEVAR'};$as_echo "$as_val"'`" = xyes; then :
+  if ${CFLAGS+:} false; then :
+  case " $CFLAGS " in
+    *" $flag "*)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS already contains \$flag"; } >&5
+  (: CFLAGS already contains $flag) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      ;;
+    *)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS=\"\$CFLAGS \$flag\""; } >&5
+  (: CFLAGS="$CFLAGS $flag") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      CFLAGS="$CFLAGS $flag"
+      ;;
+   esac
+else
+  CFLAGS="$flag"
+fi
+
+else
+  :
+fi
+
+done
+
+  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=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+
+for flag in ${OPTFLAGS}; do
+  as_CACHEVAR=`$as_echo "ax_cv_check_cxxflags__$flag" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C++ compiler accepts $flag" >&5
+$as_echo_n "checking whether C++ compiler accepts $flag... " >&6; }
+if eval \${$as_CACHEVAR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$CXXFLAGS
+  CXXFLAGS="$CXXFLAGS  $flag -Werror"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  eval "$as_CACHEVAR=yes"
+else
+  eval "$as_CACHEVAR=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  CXXFLAGS=$ax_check_save_flags
+fi
+eval ac_res=\$$as_CACHEVAR
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if test x"`eval 'as_val=${'$as_CACHEVAR'};$as_echo "$as_val"'`" = xyes; then :
+  if ${CXXFLAGS+:} false; then :
+  case " $CXXFLAGS " in
+    *" $flag "*)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CXXFLAGS already contains \$flag"; } >&5
+  (: CXXFLAGS already contains $flag) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      ;;
+    *)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CXXFLAGS=\"\$CXXFLAGS \$flag\""; } >&5
+  (: CXXFLAGS="$CXXFLAGS $flag") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      CXXFLAGS="$CXXFLAGS $flag"
+      ;;
+   esac
+else
+  CXXFLAGS="$flag"
+fi
+
+else
+  :
+fi
+
+done
+
+#   AX_APPEND_COMPILE_FLAGS([-fno-threadsafe-statics -fno-enforce-eh-specs -fconserve-space], [CXXFLAGS])
+###  AX_APPEND_COMPILE_FLAGS([-fno-implicit-templates], [CXXFLAGS]) # problems due to STL
+  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
+
+
+
+for flag in ${OPTFLAGS}; do
+  as_CACHEVAR=`$as_echo "ax_cv_check_ldflags__$flag" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the linker accepts $flag" >&5
+$as_echo_n "checking whether the linker accepts $flag... " >&6; }
+if eval \${$as_CACHEVAR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$LDFLAGS
+  LDFLAGS="$LDFLAGS  $flag"
+  _save_cflags="$CFLAGS"
+  CFLAGS="$CFLAGS -Werror"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "$as_CACHEVAR=yes"
+else
+  eval "$as_CACHEVAR=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+  CFLAGS="$_save_cflags"
+  LDFLAGS=$ax_check_save_flags
+fi
+eval ac_res=\$$as_CACHEVAR
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if test x"`eval 'as_val=${'$as_CACHEVAR'};$as_echo "$as_val"'`" = xyes; then :
+  if ${LDFLAGS+:} false; then :
+  case " $LDFLAGS " in
+    *" $flag "*)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : LDFLAGS already contains \$flag"; } >&5
+  (: LDFLAGS already contains $flag) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      ;;
+    *)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : LDFLAGS=\"\$LDFLAGS \$flag\""; } >&5
+  (: LDFLAGS="$LDFLAGS $flag") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      LDFLAGS="$LDFLAGS $flag"
+      ;;
+   esac
+else
+  LDFLAGS="$flag"
+fi
+
+else
+  :
+fi
+
+done
+
+#  AX_APPEND_LINK_FLAGS([-fno-threadsafe-statics -fno-enforce-eh-specs -fconserve-space])
+###  AX_APPEND_LINK_FLAGS([-fno-implicit-templates]) # see above :(
+#  AX_APPEND_LINK_FLAGS([ ])
+ fi
+
+ FLAGS2="-Qunused-arguments"
+ 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
+
+
+
+for flag in ${FLAGS2}; do
+  as_CACHEVAR=`$as_echo "ax_cv_check_cflags__$flag" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts $flag" >&5
+$as_echo_n "checking whether C compiler accepts $flag... " >&6; }
+if eval \${$as_CACHEVAR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$CFLAGS
+  CFLAGS="$CFLAGS  $flag -Werror"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  eval "$as_CACHEVAR=yes"
+else
+  eval "$as_CACHEVAR=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  CFLAGS=$ax_check_save_flags
+fi
+eval ac_res=\$$as_CACHEVAR
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if test x"`eval 'as_val=${'$as_CACHEVAR'};$as_echo "$as_val"'`" = xyes; then :
+  if ${CFLAGS+:} false; then :
+  case " $CFLAGS " in
+    *" $flag "*)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS already contains \$flag"; } >&5
+  (: CFLAGS already contains $flag) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      ;;
+    *)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS=\"\$CFLAGS \$flag\""; } >&5
+  (: CFLAGS="$CFLAGS $flag") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      CFLAGS="$CFLAGS $flag"
+      ;;
+   esac
+else
+  CFLAGS="$flag"
+fi
+
+else
+  :
+fi
+
+done
+
+ 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=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+
+for flag in ${FLAGS2}; do
+  as_CACHEVAR=`$as_echo "ax_cv_check_cxxflags__$flag" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C++ compiler accepts $flag" >&5
+$as_echo_n "checking whether C++ compiler accepts $flag... " >&6; }
+if eval \${$as_CACHEVAR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$CXXFLAGS
+  CXXFLAGS="$CXXFLAGS  $flag -Werror"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  eval "$as_CACHEVAR=yes"
+else
+  eval "$as_CACHEVAR=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  CXXFLAGS=$ax_check_save_flags
+fi
+eval ac_res=\$$as_CACHEVAR
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if test x"`eval 'as_val=${'$as_CACHEVAR'};$as_echo "$as_val"'`" = xyes; then :
+  if ${CXXFLAGS+:} false; then :
+  case " $CXXFLAGS " in
+    *" $flag "*)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CXXFLAGS already contains \$flag"; } >&5
+  (: CXXFLAGS already contains $flag) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      ;;
+    *)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CXXFLAGS=\"\$CXXFLAGS \$flag\""; } >&5
+  (: CXXFLAGS="$CXXFLAGS $flag") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      CXXFLAGS="$CXXFLAGS $flag"
+      ;;
+   esac
+else
+  CXXFLAGS="$flag"
+fi
+
+else
+  :
+fi
+
+done
+
+ 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
+
+
+
+
+for flag in ${FLAGS2}; do
+  as_CACHEVAR=`$as_echo "ax_cv_check_ldflags__$flag" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the linker accepts $flag" >&5
+$as_echo_n "checking whether the linker accepts $flag... " >&6; }
+if eval \${$as_CACHEVAR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$LDFLAGS
+  LDFLAGS="$LDFLAGS  $flag"
+  _save_cflags="$CFLAGS"
+  CFLAGS="$CFLAGS -Werror"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "$as_CACHEVAR=yes"
+else
+  eval "$as_CACHEVAR=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+  CFLAGS="$_save_cflags"
+  LDFLAGS=$ax_check_save_flags
+fi
+eval ac_res=\$$as_CACHEVAR
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if test x"`eval 'as_val=${'$as_CACHEVAR'};$as_echo "$as_val"'`" = xyes; then :
+  if ${LDFLAGS+:} false; then :
+  case " $LDFLAGS " in
+    *" $flag "*)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : LDFLAGS already contains \$flag"; } >&5
+  (: LDFLAGS already contains $flag) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      ;;
+    *)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : LDFLAGS=\"\$LDFLAGS \$flag\""; } >&5
+  (: LDFLAGS="$LDFLAGS $flag") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      LDFLAGS="$LDFLAGS $flag"
+      ;;
+   esac
+else
+  LDFLAGS="$flag"
+fi
+
+else
+  :
+fi
+
+done
+
+
+# SING_SHOW_FLAGS([before PROG_C_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
+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 ${ac_cv_prog_CC+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_CC+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_CC+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_CC+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_CC+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_CC+:} false; 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 as_fn_executable_p "$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
+  fi
+  rm -f conftest.er1 conftest.err
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+done
+
+{ $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 ${ac_cv_c_compiler_gnu+:} false; 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 ${ac_cv_prog_cc_g+:} false; 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 ${ac_cv_prog_cc_c89+:} false; 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>
+struct stat;
+/* 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
+
+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 ${am_cv_CC_dependencies_compiler_type+:} false; 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".
+  rm -rf conftest.dir
+  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 10 /bin/sh.
+      echo '/* dummy */' > 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
+      ;;
+    msvc7 | msvc7msys | 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
+
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+if test -z "$CXX"; then
+  if test -n "$CCC"; then
+    CXX=$CCC
+  else
+    if test -n "$ac_tool_prefix"; then
+  for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+  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 ${ac_cv_prog_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CXX"; then
+  ac_cv_prog_CXX="$CXX" # 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CXX="$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
+CXX=$ac_cv_prog_CXX
+if test -n "$CXX"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5
+$as_echo "$CXX" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+    test -n "$CXX" && break
+  done
+fi
+if test -z "$CXX"; then
+  ac_ct_CXX=$CXX
+  for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+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 ${ac_cv_prog_ac_ct_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_CXX"; then
+  ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CXX="$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_CXX=$ac_cv_prog_ac_ct_CXX
+if test -n "$ac_ct_CXX"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5
+$as_echo "$ac_ct_CXX" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$ac_ct_CXX" && break
+done
+
+  if test "x$ac_ct_CXX" = x; then
+    CXX="g++"
+  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
+    CXX=$ac_ct_CXX
+  fi
+fi
+
+  fi
+fi
+# 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
+  fi
+  rm -f conftest.er1 conftest.err
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+done
+
+{ $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 ${ac_cv_cxx_compiler_gnu+:} false; 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_cxx_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_cxx_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5
+$as_echo "$ac_cv_cxx_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+  GXX=yes
+else
+  GXX=
+fi
+ac_test_CXXFLAGS=${CXXFLAGS+set}
+ac_save_CXXFLAGS=$CXXFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5
+$as_echo_n "checking whether $CXX accepts -g... " >&6; }
+if ${ac_cv_prog_cxx_g+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_save_cxx_werror_flag=$ac_cxx_werror_flag
+   ac_cxx_werror_flag=yes
+   ac_cv_prog_cxx_g=no
+   CXXFLAGS="-g"
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ac_cv_prog_cxx_g=yes
+else
+  CXXFLAGS=""
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+
+else
+  ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+	 CXXFLAGS="-g"
+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ac_cv_prog_cxx_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_cxx_werror_flag=$ac_save_cxx_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5
+$as_echo "$ac_cv_prog_cxx_g" >&6; }
+if test "$ac_test_CXXFLAGS" = set; then
+  CXXFLAGS=$ac_save_CXXFLAGS
+elif test $ac_cv_prog_cxx_g = yes; then
+  if test "$GXX" = yes; then
+    CXXFLAGS="-g -O2"
+  else
+    CXXFLAGS="-g"
+  fi
+else
+  if test "$GXX" = yes; then
+    CXXFLAGS="-O2"
+  else
+    CXXFLAGS=
+  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
+
+depcc="$CXX"  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 ${am_cv_CXX_dependencies_compiler_type+:} false; 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".
+  rm -rf conftest.dir
+  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_CXX_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 10 /bin/sh.
+      echo '/* dummy */' > 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
+      ;;
+    msvc7 | msvc7msys | 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_CXX_dependencies_compiler_type=$depmode
+        break
+      fi
+    fi
+  done
+
+  cd ..
+  rm -rf conftest.dir
+else
+  am_cv_CXX_dependencies_compiler_type=none
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5
+$as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; }
+CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type
+
+ if
+  test "x$enable_dependency_tracking" != xno \
+  && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then
+  am__fastdepCXX_TRUE=
+  am__fastdepCXX_FALSE='#'
+else
+  am__fastdepCXX_TRUE='#'
+  am__fastdepCXX_FALSE=
+fi
+
+
+
+
+# Checks for programs.
+# AC_PROG_CC
+# AC_PROG_CXX
+{ $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
+
+#AC_PROG_INSTALL
+
+# Checks for libraries.
+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.4.2'
+macro_revision='1.3337'
+
+
+
+
+
+
+
+
+
+
+
+
+
+ltmain="$ac_aux_dir/ltmain.sh"
+
+# 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 ${ac_cv_build+:} false; 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 ${ac_cv_host+:} false; 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
+
+
+# Backslashify 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'
+
+ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5
+$as_echo_n "checking how to print strings... " >&6; }
+# Test print first, because it will be a builtin if present.
+if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \
+   test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then
+  ECHO='print -r --'
+elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then
+  ECHO='printf %s\n'
+else
+  # Use this function as a fallback that always works.
+  func_fallback_echo ()
+  {
+    eval 'cat <<_LTECHO_EOF
+$1
+_LTECHO_EOF'
+  }
+  ECHO='func_fallback_echo'
+fi
+
+# func_echo_all arg...
+# Invoke $ECHO with all args, space-separated.
+func_echo_all ()
+{
+    $ECHO ""
+}
+
+case "$ECHO" in
+  printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5
+$as_echo "printf" >&6; } ;;
+  print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5
+$as_echo "print -r" >&6; } ;;
+  *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5
+$as_echo "cat" >&6; } ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+{ $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 ${ac_cv_path_SED+:} false; 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"
+      as_fn_executable_p "$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 ${ac_cv_path_GREP+:} false; 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"
+      as_fn_executable_p "$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 ${ac_cv_path_EGREP+:} false; 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"
+      as_fn_executable_p "$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 ${ac_cv_path_FGREP+:} false; 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"
+      as_fn_executable_p "$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 ${lt_cv_path_LD+:} false; 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 ${lt_cv_prog_gnu_ld+:} false; 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 ${lt_cv_path_NM+:} false; 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 "$DUMPBIN"; then :
+    # Let the user override the test.
+  else
+    if test -n "$ac_tool_prefix"; then
+  for ac_prog in dumpbin "link -dump"
+  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 ${ac_cv_prog_DUMPBIN+:} false; 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 as_fn_executable_p "$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 "link -dump"
+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 ${ac_cv_prog_ac_ct_DUMPBIN+:} false; 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 as_fn_executable_p "$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
+
+    case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in
+    *COFF*)
+      DUMPBIN="$DUMPBIN -symbols"
+      ;;
+    *)
+      DUMPBIN=:
+      ;;
+    esac
+  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 ${lt_cv_nm_interface+:} false; 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:$LINENO: $ac_compile\"" >&5)
+  (eval "$ac_compile" 2>conftest.err)
+  cat conftest.err >&5
+  (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
+  (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
+  cat conftest.err >&5
+  (eval echo "\"\$as_me:$LINENO: 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; }
+
+# 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 ${lt_cv_sys_max_cmd_len+:} false; 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;
+    ;;
+
+  mint*)
+    # On MiNT this can take a long time and run out of memory.
+    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
+    ;;
+
+  os2*)
+    # The test takes a long time on OS/2.
+    lt_cv_sys_max_cmd_len=8192
+    ;;
+
+  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"`env echo "$teststring$teststring" 2>/dev/null` \
+	         = "X$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%"$_lt_dummy"}, \
+      = c,a/b,b/c, \
+    && 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 how to convert $build file names to $host format" >&5
+$as_echo_n "checking how to convert $build file names to $host format... " >&6; }
+if ${lt_cv_to_host_file_cmd+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $host in
+  *-*-mingw* )
+    case $build in
+      *-*-mingw* ) # actually msys
+        lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32
+        ;;
+      *-*-cygwin* )
+        lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32
+        ;;
+      * ) # otherwise, assume *nix
+        lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32
+        ;;
+    esac
+    ;;
+  *-*-cygwin* )
+    case $build in
+      *-*-mingw* ) # actually msys
+        lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin
+        ;;
+      *-*-cygwin* )
+        lt_cv_to_host_file_cmd=func_convert_file_noop
+        ;;
+      * ) # otherwise, assume *nix
+        lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin
+        ;;
+    esac
+    ;;
+  * ) # unhandled hosts (and "normal" native builds)
+    lt_cv_to_host_file_cmd=func_convert_file_noop
+    ;;
+esac
+
+fi
+
+to_host_file_cmd=$lt_cv_to_host_file_cmd
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5
+$as_echo "$lt_cv_to_host_file_cmd" >&6; }
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5
+$as_echo_n "checking how to convert $build file names to toolchain format... " >&6; }
+if ${lt_cv_to_tool_file_cmd+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  #assume ordinary cross tools, or native build.
+lt_cv_to_tool_file_cmd=func_convert_file_noop
+case $host in
+  *-*-mingw* )
+    case $build in
+      *-*-mingw* ) # actually msys
+        lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32
+        ;;
+    esac
+    ;;
+esac
+
+fi
+
+to_tool_file_cmd=$lt_cv_to_tool_file_cmd
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5
+$as_echo "$lt_cv_to_tool_file_cmd" >&6; }
+
+
+
+
+
+{ $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 ${lt_cv_ld_reload_flag+:} false; 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
+  cygwin* | mingw* | pw32* | cegcc*)
+    if test "$GCC" != yes; then
+      reload_cmds=false
+    fi
+    ;;
+  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 ${ac_cv_prog_OBJDUMP+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_OBJDUMP+:} false; 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 as_fn_executable_p "$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 ${lt_cv_deplibs_check_method+:} false; 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.
+  # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin.
+  if ( test "$lt_cv_nm_interface" = "BSD nm" && 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
+    # Keep this pattern in sync with the one in func_win32_libid.
+    lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)'
+    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
+  ;;
+
+haiku*)
+  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])(-bit)?( [LM]SB)? 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 glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+netbsd*)
+  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_glob=
+want_nocaseglob=no
+if test "$build" = "$host"; then
+  case $host_os in
+  mingw* | pw32*)
+    if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then
+      want_nocaseglob=yes
+    else
+      file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"`
+    fi
+    ;;
+  esac
+fi
+
+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}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 ${ac_cv_prog_DLLTOOL+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_DLLTOOL+:} false; 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 as_fn_executable_p "$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
+
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5
+$as_echo_n "checking how to associate runtime and link libraries... " >&6; }
+if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_sharedlib_from_linklib_cmd='unknown'
+
+case $host_os in
+cygwin* | mingw* | pw32* | cegcc*)
+  # two different shell functions defined in ltmain.sh
+  # decide which to use based on capabilities of $DLLTOOL
+  case `$DLLTOOL --help 2>&1` in
+  *--identify-strict*)
+    lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib
+    ;;
+  *)
+    lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback
+    ;;
+  esac
+  ;;
+*)
+  # fallback: assume linklib IS sharedlib
+  lt_cv_sharedlib_from_linklib_cmd="$ECHO"
+  ;;
+esac
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5
+$as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; }
+sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd
+test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+  for ac_prog in ar
+  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 ${ac_cv_prog_AR+:} false; 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_AR="$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
+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
+
+
+    test -n "$AR" && break
+  done
+fi
+if test -z "$AR"; then
+  ac_ct_AR=$AR
+  for ac_prog in ar
+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 ${ac_cv_prog_ac_ct_AR+:} false; 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_AR="$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_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
+
+
+  test -n "$ac_ct_AR" && break
+done
+
+  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
+fi
+
+: ${AR=ar}
+: ${AR_FLAGS=cru}
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5
+$as_echo_n "checking for archiver @FILE support... " >&6; }
+if ${lt_cv_ar_at_file+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_ar_at_file=no
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  echo conftest.$ac_objext > conftest.lst
+      lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5'
+      { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5
+  (eval $lt_ar_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      if test "$ac_status" -eq 0; then
+	# Ensure the archiver fails upon bogus file names.
+	rm -f conftest.$ac_objext libconftest.a
+	{ { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5
+  (eval $lt_ar_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+	if test "$ac_status" -ne 0; then
+          lt_cv_ar_at_file=@
+        fi
+      fi
+      rm -f conftest.* libconftest.a
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5
+$as_echo "$lt_cv_ar_at_file" >&6; }
+
+if test "x$lt_cv_ar_at_file" = xno; then
+  archiver_list_spec=
+else
+  archiver_list_spec=$lt_cv_ar_at_file
+fi
+
+
+
+
+
+
+
+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 ${ac_cv_prog_STRIP+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_STRIP+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_RANLIB+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_RANLIB+:} false; 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 as_fn_executable_p "$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 \$tool_oldlib"
+    ;;
+  *)
+    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib"
+    ;;
+  esac
+  old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib"
+fi
+
+case $host_os in
+  darwin*)
+    lock_old_archive_extraction=yes ;;
+  *)
+    lock_old_archive_extraction=no ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 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 ${lt_cv_sys_global_symbol_pipe+:} false; 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};"\
+"     /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\
+"     /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
+  lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'"
+
+  # 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
+/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests.  */
+#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE)
+/* DATA imports from DLLs on WIN32 con't be const, because runtime
+   relocations are performed -- see ld's documentation on pseudo-relocs.  */
+# define LT_DLSYM_CONST
+#elif defined(__osf__)
+/* This system does not cope well with relocations in const data.  */
+# define LT_DLSYM_CONST
+#else
+# define LT_DLSYM_CONST const
+#endif
+
+#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.  */
+LT_DLSYM_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_globsym_save_LIBS=$LIBS
+	  lt_globsym_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_globsym_save_LIBS
+	  CFLAGS=$lt_globsym_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
+
+# Response file support.
+if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+  nm_file_list_spec='@'
+elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then
+  nm_file_list_spec='@'
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5
+$as_echo_n "checking for sysroot... " >&6; }
+
+# Check whether --with-sysroot was given.
+if test "${with_sysroot+set}" = set; then :
+  withval=$with_sysroot;
+else
+  with_sysroot=no
+fi
+
+
+lt_sysroot=
+case ${with_sysroot} in #(
+ yes)
+   if test "$GCC" = yes; then
+     lt_sysroot=`$CC --print-sysroot 2>/dev/null`
+   fi
+   ;; #(
+ /*)
+   lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"`
+   ;; #(
+ no|'')
+   ;; #(
+ *)
+   { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${with_sysroot}" >&5
+$as_echo "${with_sysroot}" >&6; }
+   as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5
+   ;;
+esac
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5
+$as_echo "${lt_sysroot:-no}" >&6; }
+
+
+
+
+
+# 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 '$LINENO' "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 ${lt_cv_cc_needs_belf+:} false; 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
+  ;;
+*-*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*)
+        case $host in
+        i?86-*-solaris*)
+          LD="${LD-ld} -m elf_x86_64"
+          ;;
+        sparc*-*-solaris*)
+          LD="${LD-ld} -m elf64_sparc"
+          ;;
+        esac
+        # GNU ld 2.21 introduced _sol2 emulations.  Use them if available.
+        if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then
+          LD="${LD-ld}_sol2"
+        fi
+        ;;
+      *)
+	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"
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args.
+set dummy ${ac_tool_prefix}mt; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_MANIFEST_TOOL+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$MANIFEST_TOOL"; then
+  ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt"
+    $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
+MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL
+if test -n "$MANIFEST_TOOL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5
+$as_echo "$MANIFEST_TOOL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_MANIFEST_TOOL"; then
+  ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL
+  # Extract the first word of "mt", so it can be a program name with args.
+set dummy mt; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_MANIFEST_TOOL"; then
+  ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_MANIFEST_TOOL="mt"
+    $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_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL
+if test -n "$ac_ct_MANIFEST_TOOL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5
+$as_echo "$ac_ct_MANIFEST_TOOL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_MANIFEST_TOOL" = x; then
+    MANIFEST_TOOL=":"
+  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
+    MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL
+  fi
+else
+  MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL"
+fi
+
+test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5
+$as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; }
+if ${lt_cv_path_mainfest_tool+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_path_mainfest_tool=no
+  echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5
+  $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out
+  cat conftest.err >&5
+  if $GREP 'Manifest Tool' conftest.out > /dev/null; then
+    lt_cv_path_mainfest_tool=yes
+  fi
+  rm -f conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5
+$as_echo "$lt_cv_path_mainfest_tool" >&6; }
+if test "x$lt_cv_path_mainfest_tool" != xyes; then
+  MANIFEST_TOOL=:
+fi
+
+
+
+
+
+
+  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 ${ac_cv_prog_DSYMUTIL+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_NMEDIT+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_NMEDIT+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_LIPO+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_LIPO+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_OTOOL+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_OTOOL+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_OTOOL64+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_OTOOL64+:} false; 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 as_fn_executable_p "$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 ${lt_cv_apple_cc_single_mod+:} false; 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 there is a non-empty error log, and "single_module"
+	# appears in it, assume the flag caused a linker warning
+        if test -s conftest.err && $GREP single_module conftest.err; then
+	  cat conftest.err >&5
+	# Otherwise, if the output was created with a 0 exit code from
+	# the compiler, it worked.
+	elif test -f libconftest.dylib && test $_lt_result -eq 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 ${lt_cv_ld_exported_symbols_list+:} false; 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; }
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5
+$as_echo_n "checking for -force_load linker flag... " >&6; }
+if ${lt_cv_ld_force_load+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_ld_force_load=no
+      cat > conftest.c << _LT_EOF
+int forced_loaded() { return 2;}
+_LT_EOF
+      echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5
+      $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5
+      echo "$AR cru libconftest.a conftest.o" >&5
+      $AR cru libconftest.a conftest.o 2>&5
+      echo "$RANLIB libconftest.a" >&5
+      $RANLIB libconftest.a 2>&5
+      cat > conftest.c << _LT_EOF
+int main() { return 0;}
+_LT_EOF
+      echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5
+      $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err
+      _lt_result=$?
+      if test -s conftest.err && $GREP force_load conftest.err; then
+	cat conftest.err >&5
+      elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then
+	lt_cv_ld_force_load=yes
+      else
+	cat conftest.err >&5
+      fi
+        rm -f conftest.err libconftest.a conftest conftest.c
+        rm -rf conftest.dSYM
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5
+$as_echo "$lt_cv_ld_force_load" >&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" != ":" && test "$lt_cv_ld_force_load" = "no"; 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 ${ac_cv_prog_CPP+:} false; 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.i 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.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i 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.i 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.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i 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 ${ac_cv_header_stdc+:} false; 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
+"
+if eval test \"x\$"$as_ac_Header"\" = 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" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_DLFCN_H 1
+_ACEOF
+
+fi
+
+done
+
+
+
+func_stripname_cnf ()
+{
+  case ${2} in
+  .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;;
+  *)  func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;;
+  esac
+} # func_stripname_cnf
+
+
+
+
+
+# Set options
+
+
+
+        enable_dlopen=no
+
+
+  enable_win32_dll=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; lt_p=${PACKAGE-default}
+    case $withval in
+    yes|no) pic_mode=$withval ;;
+    *)
+      pic_mode=default
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for lt_pkg in $withval; do
+	IFS="$lt_save_ifs"
+	if test "X$lt_pkg" = "X$lt_p"; then
+	  pic_mode=yes
+	fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac
+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 ${lt_cv_objdir+:} false; 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
+
+# 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 "$cc_temp" | $SED "s%.*/%%; 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 ${lt_cv_path_MAGIC_CMD+:} false; 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 ${lt_cv_path_MAGIC_CMD+:} false; 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*
+
+
+## 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...
+if test -n "$compiler"; then
+
+lt_prog_compiler_no_builtin_flag=
+
+if test "$GCC" = yes; then
+  case $cc_basename in
+  nvcc*)
+    lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;;
+  *)
+    lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;;
+  esac
+
+  { $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 ${lt_cv_prog_compiler_rtti_exceptions+:} false; 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:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $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 "$_lt_compiler_boilerplate" | $SED '/^$/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=
+
+
+  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'
+      ;;
+
+    haiku*)
+      # PIC is the default for Haiku.
+      # The "-static" flag exists, but is broken.
+      lt_prog_compiler_static=
+      ;;
+
+    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
+
+    case $cc_basename in
+    nvcc*) # Cuda Compiler Driver 2.2
+      lt_prog_compiler_wl='-Xlinker '
+      if test -n "$lt_prog_compiler_pic"; then
+        lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic"
+      fi
+      ;;
+    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 | kopensolaris*-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'
+	;;
+      nagfor*)
+	# NAG Fortran compiler
+	lt_prog_compiler_wl='-Wl,-Wl,,'
+	lt_prog_compiler_pic='-PIC'
+	lt_prog_compiler_static='-Bstatic'
+	;;
+      pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
+        # 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* | bgxl* | bgf* | mpixl*)
+	# IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene
+	lt_prog_compiler_wl='-Wl,'
+	lt_prog_compiler_pic='-qpic'
+	lt_prog_compiler_static='-qstaticlink'
+	;;
+      *)
+	case `$CC -V 2>&1 | sed 5q` in
+	*Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*)
+	  # 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=''
+	  ;;
+	*Sun\ F* | *Sun*Fortran*)
+	  lt_prog_compiler_pic='-KPIC'
+	  lt_prog_compiler_static='-Bstatic'
+	  lt_prog_compiler_wl='-Qoption ld '
+	  ;;
+	*Sun\ C*)
+	  # Sun C 5.9
+	  lt_prog_compiler_pic='-KPIC'
+	  lt_prog_compiler_static='-Bstatic'
+	  lt_prog_compiler_wl='-Wl,'
+	  ;;
+        *Intel*\ [CF]*Compiler*)
+	  lt_prog_compiler_wl='-Wl,'
+	  lt_prog_compiler_pic='-fPIC'
+	  lt_prog_compiler_static='-static'
+	  ;;
+	*Portland\ Group*)
+	  lt_prog_compiler_wl='-Wl,'
+	  lt_prog_compiler_pic='-fpic'
+	  lt_prog_compiler_static='-Bstatic'
+	  ;;
+	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* | sunf77* | sunf90* | sunf95*)
+	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}: checking for $compiler option to produce PIC" >&5
+$as_echo_n "checking for $compiler option to produce PIC... " >&6; }
+if ${lt_cv_prog_compiler_pic+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_pic=$lt_prog_compiler_pic
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5
+$as_echo "$lt_cv_prog_compiler_pic" >&6; }
+lt_prog_compiler_pic=$lt_cv_prog_compiler_pic
+
+#
+# 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 ${lt_cv_prog_compiler_pic_works+:} false; 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:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $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 "$_lt_compiler_boilerplate" | $SED '/^$/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 ${lt_cv_prog_compiler_static_works+:} false; 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 "$_lt_linker_boilerplate" | $SED '/^$/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 ${lt_cv_prog_compiler_c_o+:} false; 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:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $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 "$_lt_compiler_boilerplate" | $SED '/^$/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 ${lt_cv_prog_compiler_c_o+:} false; 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:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $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 "$_lt_compiler_boilerplate" | $SED '/^$/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_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
+    ;;
+  esac
+
+  ld_shlibs=yes
+
+  # On some targets, GNU ld is compatible enough with the native linker
+  # that we're better off using the native interface for both.
+  lt_use_gnu_ld_interface=no
+  if test "$with_gnu_ld" = yes; then
+    case $host_os in
+      aix*)
+	# The AIX port of GNU ld has always aspired to compatibility
+	# with the native linker.  However, as the warning in the GNU ld
+	# block says, versions before 2.19.5* couldn't really create working
+	# shared libraries, regardless of the interface used.
+	case `$LD -v 2>&1` in
+	  *\ \(GNU\ Binutils\)\ 2.19.5*) ;;
+	  *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;;
+	  *\ \(GNU\ Binutils\)\ [3-9]*) ;;
+	  *)
+	    lt_use_gnu_ld_interface=yes
+	    ;;
+	esac
+	;;
+      *)
+	lt_use_gnu_ld_interface=yes
+	;;
+    esac
+  fi
+
+  if test "$lt_use_gnu_ld_interface" = 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
+      *GNU\ gold*) supports_anon_versioning=yes ;;
+      *\ [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.19, 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 install binutils
+*** 2.20 or above, or modify your PATH so that a non-GNU linker is found.
+*** You will then need to restart the configuration process.
+
+_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'
+      export_dynamic_flag_spec='${wl}--export-all-symbols'
+      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/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols'
+      exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'
+
+      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
+      ;;
+
+    haiku*)
+      archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+      link_all_deplibs=yes
+      ;;
+
+    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 | kopensolaris*-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=' $pic_flag'
+	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; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+	  tmp_addflag=' $pic_flag'
+	  ;;
+	pgf77* | pgf90* | pgf95* | pgfortran*)
+					# 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; func_echo_all \"$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]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below)
+	  tmp_sharedflag='-qmkshrobj'
+	  tmp_addflag= ;;
+	nvcc*)	# Cuda Compiler Driver 2.2
+	  whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+	  compiler_needs_object=yes
+	  ;;
+	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; func_echo_all \"$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* | bgf* | bgxlf* | mpixlf*)
+	  # 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='${wl}-rpath ${wl}$libdir'
+	  archive_cmds='$LD -shared $libobjs $deplibs $linker_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 $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+	  fi
+	  ;;
+	esac
+      else
+        ld_shlibs=no
+      fi
+      ;;
+
+    netbsd*)
+      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 $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	archive_expsym_cmds='$CC -shared $pic_flag $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 $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	archive_expsym_cmds='$CC -shared $pic_flag $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 $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	archive_expsym_cmds='$CC -shared $pic_flag $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
+	# Also, AIX nm treats weak defined symbols like other global
+	# defined symbols, whereas GNU nm marks them as "W".
+	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") || (\$ 2 == "W")) && (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
+      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.
+        if test "${lt_cv_aix_libpath+set}" = set; then
+  aix_libpath=$lt_cv_aix_libpath
+else
+  if ${lt_cv_aix_libpath_+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  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
+	  }
+      }'
+  lt_cv_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 "$lt_cv_aix_libpath_"; then
+    lt_cv_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 "$lt_cv_aix_libpath_"; then
+    lt_cv_aix_libpath_="/usr/lib:/lib"
+  fi
+
+fi
+
+  aix_libpath=$lt_cv_aix_libpath_
+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 func_echo_all "${wl}${allow_undefined_flag}"; 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.
+	 if test "${lt_cv_aix_libpath+set}" = set; then
+  aix_libpath=$lt_cv_aix_libpath
+else
+  if ${lt_cv_aix_libpath_+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  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
+	  }
+      }'
+  lt_cv_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 "$lt_cv_aix_libpath_"; then
+    lt_cv_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 "$lt_cv_aix_libpath_"; then
+    lt_cv_aix_libpath_="/usr/lib:/lib"
+  fi
+
+fi
+
+  aix_libpath=$lt_cv_aix_libpath_
+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'
+	  if test "$with_gnu_ld" = yes; then
+	    # We only use this code for GNU lds that support --whole-archive.
+	    whole_archive_flag_spec='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+	  else
+	    # Exported symbols can be pulled into shared objects from archives
+	    whole_archive_flag_spec='$convenience'
+	  fi
+	  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.
+      case $cc_basename in
+      cl*)
+	# Native MSVC
+	hardcode_libdir_flag_spec=' '
+	allow_undefined_flag=unsupported
+	always_export_symbols=yes
+	file_list_spec='@'
+	# 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 $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
+	archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	    sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
+	  else
+	    sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
+	  fi~
+	  $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+	  linknames='
+	# The linker will not automatically build a static lib if we build a DLL.
+	# _LT_TAGVAR(old_archive_from_new_cmds, )='true'
+	enable_shared_with_static_runtimes=yes
+	exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
+	export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols'
+	# Don't use ranlib
+	old_postinstall_cmds='chmod 644 $oldlib'
+	postlink_cmds='lt_outputfile="@OUTPUT@"~
+	  lt_tool_outputfile="@TOOL_OUTPUT@"~
+	  case $lt_outputfile in
+	    *.exe|*.EXE) ;;
+	    *)
+	      lt_outputfile="$lt_outputfile.exe"
+	      lt_tool_outputfile="$lt_tool_outputfile.exe"
+	      ;;
+	  esac~
+	  if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
+	    $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+	    $RM "$lt_outputfile.manifest";
+	  fi'
+	;;
+      *)
+	# Assume MSVC wrapper
+	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 `func_echo_all "$deplibs" | $SED '\''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'
+	enable_shared_with_static_runtimes=yes
+	;;
+      esac
+      ;;
+
+    darwin* | rhapsody*)
+
+
+  archive_cmds_need_lc=no
+  hardcode_direct=no
+  hardcode_automatic=yes
+  hardcode_shlibpath_var=unsupported
+  if test "$lt_cv_ld_force_load" = "yes"; then
+    whole_archive_flag_spec='`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+
+  else
+    whole_archive_flag_spec=''
+  fi
+  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=func_echo_all
+    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
+      ;;
+
+    # 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 $pic_flag -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 $pic_flag ${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 && test "$with_gnu_ld" = no; then
+	archive_cmds='$CC -shared $pic_flag ${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_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 && test "$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 $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	*)
+	  archive_cmds='$CC -shared $pic_flag ${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'
+	  ;;
+	*)
+
+	  # Older versions of the 11.00 compiler do not understand -b yet
+	  # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does)
+	  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5
+$as_echo_n "checking if $CC understands -b... " >&6; }
+if ${lt_cv_prog_compiler__b+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler__b=no
+   save_LDFLAGS="$LDFLAGS"
+   LDFLAGS="$LDFLAGS -b"
+   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 "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
+       $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+       if diff conftest.exp conftest.er2 >/dev/null; then
+         lt_cv_prog_compiler__b=yes
+       fi
+     else
+       lt_cv_prog_compiler__b=yes
+     fi
+   fi
+   $RM -r conftest*
+   LDFLAGS="$save_LDFLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5
+$as_echo "$lt_cv_prog_compiler__b" >&6; }
+
+if test x"$lt_cv_prog_compiler__b" = xyes; then
+    archive_cmds='$CC -b ${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
+
+	  ;;
+	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 $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${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.
+	# This should be the same for all languages, so no per-tag cache variable.
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5
+$as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; }
+if ${lt_cv_irix_exported_symbol+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  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) { return 0; }
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  lt_cv_irix_exported_symbol=yes
+else
+  lt_cv_irix_exported_symbol=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_irix_exported_symbol" >&5
+$as_echo "$lt_cv_irix_exported_symbol" >&6; }
+	if test "$lt_cv_irix_exported_symbol" = yes; then
+          archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
+	fi
+      else
+	archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+	archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -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*)
+      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" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${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" && func_echo_all "-set_version $verstring"` -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} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${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" && func_echo_all "-set_version $verstring"` -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 "-set_version $verstring"` -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 $pic_flag ${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 $pic_flag ${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; }
+if ${lt_cv_archive_cmds_need_lc+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  $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
+	    lt_cv_archive_cmds_need_lc=no
+	  else
+	    lt_cv_archive_cmds_need_lc=yes
+	  fi
+	  allow_undefined_flag=$lt_save_allow_undefined_flag
+	else
+	  cat conftest.err 1>&5
+	fi
+	$RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5
+$as_echo "$lt_cv_archive_cmds_need_lc" >&6; }
+      archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc
+      ;;
+    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
+  case $host_os in
+    mingw* | cegcc*) lt_sed_strip_eq="s,=\([A-Za-z]:\),\1,g" ;;
+    *) lt_sed_strip_eq="s,=/,/,g" ;;
+  esac
+  lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq`
+  case $lt_search_path_spec in
+  *\;*)
+    # 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 's/;/ /g'`
+    ;;
+  *)
+    lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"`
+    ;;
+  esac
+  # 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; }
+}'`
+  # AWK program above erroneously prepends '/' to C:/dos/paths
+  # for these hosts.
+  case $host_os in
+    mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\
+      $SED 's,/\([A-Za-z]:\),\1,g'` ;;
+  esac
+  sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP`
+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 # correct to gnu/linux during the next big refactor
+  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 # correct to gnu/linux during the next big refactor
+  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=`func_echo_all "$lib" | $SED '\''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 # correct to gnu/linux during the next big refactor
+  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,$cc_basename in
+  yes,*)
+    # gcc
+    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="$sys_lib_search_path_spec /usr/lib/w32api"
+      ;;
+    mingw* | cegcc*)
+      # MinGW DLLs use traditional 'lib' prefix
+      soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      ;;
+    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
+    dynamic_linker='Win32 ld.exe'
+    ;;
+
+  *,cl*)
+    # Native MSVC
+    libname_spec='$name'
+    soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+    library_names_spec='${libname}.dll.lib'
+
+    case $build_os in
+    mingw*)
+      sys_lib_search_path_spec=
+      lt_save_ifs=$IFS
+      IFS=';'
+      for lt_path in $LIB
+      do
+        IFS=$lt_save_ifs
+        # Let DOS variable expansion print the short 8.3 style file name.
+        lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"`
+        sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path"
+      done
+      IFS=$lt_save_ifs
+      # Convert to MSYS style.
+      sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'`
+      ;;
+    cygwin*)
+      # Convert to unix form, then to dos form, then back to unix form
+      # but this time dos style (no spaces!) so that the unix form looks
+      # like /cygdrive/c/PROGRA~1:/cygdr...
+      sys_lib_search_path_spec=`cygpath --path --unix "$LIB"`
+      sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null`
+      sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+      ;;
+    *)
+      sys_lib_search_path_spec="$LIB"
+      if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then
+        # It is most probably a Windows format PATH.
+        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
+      # FIXME: find the short name or the path components, as spaces are
+      # common. (e.g. "Program Files" -> "PROGRA~1")
+      ;;
+    esac
+
+    # 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'
+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+      dlpath=$dir/\$dldll~
+       $RM \$dlpath'
+    shlibpath_overrides_runpath=yes
+    dynamic_linker='Win32 link.exe'
+    ;;
+
+  *)
+    # Assume MSVC wrapper
+    library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
+    dynamic_linker='Win32 ld.exe'
+    ;;
+  esac
+  # 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 # correct to gnu/linux during the next big refactor
+  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
+  ;;
+
+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[23].*) objformat=aout ;;
+    *) objformat=elf ;;
+    esac
+  fi
+  # Handle Gentoo/FreeBSD as it was Linux
+  case $host_vendor in
+    gentoo)
+      version_type=linux ;;
+    *)
+      version_type=freebsd-$objformat ;;
+  esac
+
+  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
+      ;;
+    linux)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+      soname_spec='${libname}${release}${shared_ext}$major'
+      need_lib_prefix=no
+      need_version=no
+      ;;
+  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 # correct to gnu/linux during the next big refactor
+  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
+  ;;
+
+haiku*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  dynamic_linker="$host_os runtime_loader"
+  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=LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
+  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'
+  # or fails outright, so override atomically:
+  install_override_mode=555
+  ;;
+
+interix[3-9]*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  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 # correct to gnu/linux during the next big refactor
+	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 glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  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
+  if ${lt_cv_shlibpath_overrides_runpath+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_shlibpath_overrides_runpath=no
+    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 :
+  lt_cv_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
+
+fi
+
+  shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath
+
+  # 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;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'
+  ;;
+
+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 # correct to gnu/linux during the next big refactor
+  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 # correct to gnu/linux during the next big refactor
+  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 # correct to gnu/linux during the next big refactor
+  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 # correct to gnu/linux during the next big refactor
+    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 # correct to gnu/linux during the next big refactor
+  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 # correct to gnu/linux during the next big refactor
+  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 ${ac_cv_lib_dl_dlopen+:} false; 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" = xyes; 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" = xyes; 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 ${ac_cv_lib_dld_shl_load+:} false; 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" = xyes; 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" = xyes; 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 ${ac_cv_lib_dl_dlopen+:} false; 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" = xyes; 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 ${ac_cv_lib_svld_dlopen+:} false; 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" = xyes; 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 ${ac_cv_lib_dld_dld_link+:} false; 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" = xyes; 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 ${lt_cv_dlopen_self+:} false; 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 $LINENO "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
+
+/* When -fvisbility=hidden is used, assume the code has been annotated
+   correspondingly for the symbols needed.  */
+#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+int fnord () __attribute__((visibility("default")));
+#endif
+
+int fnord () { return 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;
+          else puts (dlerror ());
+	}
+      /* 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 ${lt_cv_dlopen_self_static+:} false; 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 $LINENO "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
+
+/* When -fvisbility=hidden is used, assume the code has been annotated
+   correspondingly for the symbols needed.  */
+#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+int fnord () __attribute__((visibility("default")));
+#endif
+
+int fnord () { return 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;
+          else puts (dlerror ());
+	}
+      /* 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"
+
+      if test -n "$CXX" && ( test "X$CXX" != "Xno" &&
+    ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) ||
+    (test "X$CXX" != "Xg++"))) ; then
+  ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_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; }
+if test -z "$CXXCPP"; then
+  if ${ac_cv_prog_CXXCPP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+      # Double quotes because CXXCPP needs to be expanded
+    for CXXCPP in "$CXX -E" "/lib/cpp"
+    do
+      ac_preproc_ok=false
+for ac_cxx_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_cxx_try_cpp "$LINENO"; then :
+
+else
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i 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_cxx_try_cpp "$LINENO"; then :
+  # Broken: success on invalid input.
+continue
+else
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+  break
+fi
+
+    done
+    ac_cv_prog_CXXCPP=$CXXCPP
+
+fi
+  CXXCPP=$ac_cv_prog_CXXCPP
+else
+  ac_cv_prog_CXXCPP=$CXXCPP
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5
+$as_echo "$CXXCPP" >&6; }
+ac_preproc_ok=false
+for ac_cxx_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_cxx_try_cpp "$LINENO"; then :
+
+else
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i 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_cxx_try_cpp "$LINENO"; then :
+  # Broken: success on invalid input.
+continue
+else
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i 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 \"$CXXCPP\" 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
+
+else
+  _lt_caught_CXX_error=yes
+fi
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+archive_cmds_need_lc_CXX=no
+allow_undefined_flag_CXX=
+always_export_symbols_CXX=no
+archive_expsym_cmds_CXX=
+compiler_needs_object_CXX=no
+export_dynamic_flag_spec_CXX=
+hardcode_direct_CXX=no
+hardcode_direct_absolute_CXX=no
+hardcode_libdir_flag_spec_CXX=
+hardcode_libdir_separator_CXX=
+hardcode_minus_L_CXX=no
+hardcode_shlibpath_var_CXX=unsupported
+hardcode_automatic_CXX=no
+inherit_rpath_CXX=no
+module_cmds_CXX=
+module_expsym_cmds_CXX=
+link_all_deplibs_CXX=unknown
+old_archive_cmds_CXX=$old_archive_cmds
+reload_flag_CXX=$reload_flag
+reload_cmds_CXX=$reload_cmds
+no_undefined_flag_CXX=
+whole_archive_flag_spec_CXX=
+enable_shared_with_static_runtimes_CXX=no
+
+# Source file extension for C++ test sources.
+ac_ext=cpp
+
+# Object file extension for compiled C++ test sources.
+objext=o
+objext_CXX=$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.
+
+
+
+
+
+
+# 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_CFLAGS=$CFLAGS
+  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++"}
+  CFLAGS=$CXXFLAGS
+  compiler=$CC
+  compiler_CXX=$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 "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
+
+
+  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_prog_compiler_no_builtin_flag_CXX=' -fno-builtin'
+    else
+      lt_prog_compiler_no_builtin_flag_CXX=
+    fi
+
+    if test "$GXX" = yes; then
+      # Set up default GNU C++ configuration
+
+
+
+# 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 ${lt_cv_path_LD+:} false; 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 ${lt_cv_prog_gnu_ld+:} false; 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
+
+
+
+
+
+
+
+      # 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
+        archive_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+        archive_expsym_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+
+        hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+        export_dynamic_flag_spec_CXX='${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
+          whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+        else
+          whole_archive_flag_spec_CXX=
+        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.
+        archive_cmds_CXX='$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 -v "^Configured with:" | $GREP "\-L"'
+
+    else
+      GXX=no
+      with_gnu_ld=no
+      wlarc=
+    fi
+
+    # PORTME: fill in a description of your system's C++ link characteristics
+    { $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; }
+    ld_shlibs_CXX=yes
+    case $host_os in
+      aix3*)
+        # FIXME: insert proper C++ library support
+        ld_shlibs_CXX=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.
+
+        archive_cmds_CXX=''
+        hardcode_direct_CXX=yes
+        hardcode_direct_absolute_CXX=yes
+        hardcode_libdir_separator_CXX=':'
+        link_all_deplibs_CXX=yes
+        file_list_spec_CXX='${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
+	    hardcode_direct_CXX=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_CXX=yes
+	    hardcode_libdir_flag_spec_CXX='-L$libdir'
+	    hardcode_libdir_separator_CXX=
+	  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
+
+        export_dynamic_flag_spec_CXX='${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_CXX=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_CXX='-berok'
+          # Determine the default libpath from the value encoded in an empty
+          # executable.
+          if test "${lt_cv_aix_libpath+set}" = set; then
+  aix_libpath=$lt_cv_aix_libpath
+else
+  if ${lt_cv_aix_libpath__CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+
+  lt_aix_libpath_sed='
+      /Import File Strings/,/^$/ {
+	  /^0/ {
+	      s/^0  *\([^ ]*\) *$/\1/
+	      p
+	  }
+      }'
+  lt_cv_aix_libpath__CXX=`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 "$lt_cv_aix_libpath__CXX"; then
+    lt_cv_aix_libpath__CXX=`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 "$lt_cv_aix_libpath__CXX"; then
+    lt_cv_aix_libpath__CXX="/usr/lib:/lib"
+  fi
+
+fi
+
+  aix_libpath=$lt_cv_aix_libpath__CXX
+fi
+
+          hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath"
+
+          archive_expsym_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+        else
+          if test "$host_cpu" = ia64; then
+	    hardcode_libdir_flag_spec_CXX='${wl}-R $libdir:/usr/lib:/lib'
+	    allow_undefined_flag_CXX="-z nodefs"
+	    archive_expsym_cmds_CXX="\$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.
+	    if test "${lt_cv_aix_libpath+set}" = set; then
+  aix_libpath=$lt_cv_aix_libpath
+else
+  if ${lt_cv_aix_libpath__CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+
+  lt_aix_libpath_sed='
+      /Import File Strings/,/^$/ {
+	  /^0/ {
+	      s/^0  *\([^ ]*\) *$/\1/
+	      p
+	  }
+      }'
+  lt_cv_aix_libpath__CXX=`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 "$lt_cv_aix_libpath__CXX"; then
+    lt_cv_aix_libpath__CXX=`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 "$lt_cv_aix_libpath__CXX"; then
+    lt_cv_aix_libpath__CXX="/usr/lib:/lib"
+  fi
+
+fi
+
+  aix_libpath=$lt_cv_aix_libpath__CXX
+fi
+
+	    hardcode_libdir_flag_spec_CXX='${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_CXX=' ${wl}-bernotok'
+	    allow_undefined_flag_CXX=' ${wl}-berok'
+	    if test "$with_gnu_ld" = yes; then
+	      # We only use this code for GNU lds that support --whole-archive.
+	      whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+	    else
+	      # Exported symbols can be pulled into shared objects from archives
+	      whole_archive_flag_spec_CXX='$convenience'
+	    fi
+	    archive_cmds_need_lc_CXX=yes
+	    # This is similar to how AIX traditionally builds its shared
+	    # libraries.
+	    archive_expsym_cmds_CXX="\$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
+	  allow_undefined_flag_CXX=unsupported
+	  # Joseph Beckenbach <jrb3 at best.com> says some releases of gcc
+	  # support --undefined.  This deserves some investigation.  FIXME
+	  archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	else
+	  ld_shlibs_CXX=no
+	fi
+	;;
+
+      chorus*)
+        case $cc_basename in
+          *)
+	  # FIXME: insert proper C++ library support
+	  ld_shlibs_CXX=no
+	  ;;
+        esac
+        ;;
+
+      cygwin* | mingw* | pw32* | cegcc*)
+	case $GXX,$cc_basename in
+	,cl* | no,cl*)
+	  # Native MSVC
+	  # hardcode_libdir_flag_spec is actually meaningless, as there is
+	  # no search path for DLLs.
+	  hardcode_libdir_flag_spec_CXX=' '
+	  allow_undefined_flag_CXX=unsupported
+	  always_export_symbols_CXX=yes
+	  file_list_spec_CXX='@'
+	  # 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_CXX='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
+	  archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	      $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
+	    else
+	      $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
+	    fi~
+	    $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+	    linknames='
+	  # The linker will not automatically build a static lib if we build a DLL.
+	  # _LT_TAGVAR(old_archive_from_new_cmds, CXX)='true'
+	  enable_shared_with_static_runtimes_CXX=yes
+	  # Don't use ranlib
+	  old_postinstall_cmds_CXX='chmod 644 $oldlib'
+	  postlink_cmds_CXX='lt_outputfile="@OUTPUT@"~
+	    lt_tool_outputfile="@TOOL_OUTPUT@"~
+	    case $lt_outputfile in
+	      *.exe|*.EXE) ;;
+	      *)
+		lt_outputfile="$lt_outputfile.exe"
+		lt_tool_outputfile="$lt_tool_outputfile.exe"
+		;;
+	    esac~
+	    func_to_tool_file "$lt_outputfile"~
+	    if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
+	      $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+	      $RM "$lt_outputfile.manifest";
+	    fi'
+	  ;;
+	*)
+	  # g++
+	  # _LT_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless,
+	  # as there is no search path for DLLs.
+	  hardcode_libdir_flag_spec_CXX='-L$libdir'
+	  export_dynamic_flag_spec_CXX='${wl}--export-all-symbols'
+	  allow_undefined_flag_CXX=unsupported
+	  always_export_symbols_CXX=no
+	  enable_shared_with_static_runtimes_CXX=yes
+
+	  if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+	    archive_cmds_CXX='$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...
+	    archive_expsym_cmds_CXX='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
+	    ld_shlibs_CXX=no
+	  fi
+	  ;;
+	esac
+	;;
+      darwin* | rhapsody*)
+
+
+  archive_cmds_need_lc_CXX=no
+  hardcode_direct_CXX=no
+  hardcode_automatic_CXX=yes
+  hardcode_shlibpath_var_CXX=unsupported
+  if test "$lt_cv_ld_force_load" = "yes"; then
+    whole_archive_flag_spec_CXX='`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+
+  else
+    whole_archive_flag_spec_CXX=''
+  fi
+  link_all_deplibs_CXX=yes
+  allow_undefined_flag_CXX="$_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=func_echo_all
+    archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
+    module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
+    archive_expsym_cmds_CXX="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_CXX="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}"
+       if test "$lt_cv_apple_cc_single_mod" != "yes"; then
+      archive_cmds_CXX="\$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}"
+      archive_expsym_cmds_CXX="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
+  ld_shlibs_CXX=no
+  fi
+
+	;;
+
+      dgux*)
+        case $cc_basename in
+          ec++*)
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+          ghcx*)
+	    # Green Hills C++ Compiler
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+          *)
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+        esac
+        ;;
+
+      freebsd2.*)
+        # C++ shared libraries reported to be fairly broken before
+	# switch to ELF
+        ld_shlibs_CXX=no
+        ;;
+
+      freebsd-elf*)
+        archive_cmds_need_lc_CXX=no
+        ;;
+
+      freebsd* | dragonfly*)
+        # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF
+        # conventions
+        ld_shlibs_CXX=yes
+        ;;
+
+      gnu*)
+        ;;
+
+      haiku*)
+        archive_cmds_CXX='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+        link_all_deplibs_CXX=yes
+        ;;
+
+      hpux9*)
+        hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir'
+        hardcode_libdir_separator_CXX=:
+        export_dynamic_flag_spec_CXX='${wl}-E'
+        hardcode_direct_CXX=yes
+        hardcode_minus_L_CXX=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
+            ld_shlibs_CXX=no
+            ;;
+          aCC*)
+            archive_cmds_CXX='$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; func_echo_all "$list"'
+            ;;
+          *)
+            if test "$GXX" = yes; then
+              archive_cmds_CXX='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${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
+              ld_shlibs_CXX=no
+            fi
+            ;;
+        esac
+        ;;
+
+      hpux10*|hpux11*)
+        if test $with_gnu_ld = no; then
+	  hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir'
+	  hardcode_libdir_separator_CXX=:
+
+          case $host_cpu in
+            hppa*64*|ia64*)
+              ;;
+            *)
+	      export_dynamic_flag_spec_CXX='${wl}-E'
+              ;;
+          esac
+        fi
+        case $host_cpu in
+          hppa*64*|ia64*)
+            hardcode_direct_CXX=no
+            hardcode_shlibpath_var_CXX=no
+            ;;
+          *)
+            hardcode_direct_CXX=yes
+            hardcode_direct_absolute_CXX=yes
+            hardcode_minus_L_CXX=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
+	    ld_shlibs_CXX=no
+	    ;;
+          aCC*)
+	    case $host_cpu in
+	      hppa*64*)
+	        archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	        ;;
+	      ia64*)
+	        archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	        ;;
+	      *)
+	        archive_cmds_CXX='$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; func_echo_all "$list"'
+	    ;;
+          *)
+	    if test "$GXX" = yes; then
+	      if test $with_gnu_ld = no; then
+	        case $host_cpu in
+	          hppa*64*)
+	            archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	            ;;
+	          ia64*)
+	            archive_cmds_CXX='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	            ;;
+	          *)
+	            archive_cmds_CXX='$CC -shared -nostdlib $pic_flag ${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
+	      ld_shlibs_CXX=no
+	    fi
+	    ;;
+        esac
+        ;;
+
+      interix[3-9]*)
+	hardcode_direct_CXX=no
+	hardcode_shlibpath_var_CXX=no
+	hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+	export_dynamic_flag_spec_CXX='${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_CXX='$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_CXX='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++
+	    archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -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.
+	    old_archive_cmds_CXX='$CC -ar -WR,-u -o $oldlib $oldobjs'
+	    ;;
+          *)
+	    if test "$GXX" = yes; then
+	      if test "$with_gnu_ld" = no; then
+	        archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+	      else
+	        archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib'
+	      fi
+	    fi
+	    link_all_deplibs_CXX=yes
+	    ;;
+        esac
+        hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+        hardcode_libdir_separator_CXX=:
+        inherit_rpath_CXX=yes
+        ;;
+
+      linux* | k*bsd*-gnu | kopensolaris*-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.
+	    archive_cmds_CXX='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'
+	    archive_expsym_cmds_CXX='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; func_echo_all "$list"'
+
+	    hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+	    export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+
+	    # Archives containing C++ object files must be created using
+	    # "CC -Bstatic", where "CC" is the KAI C++ compiler.
+	    old_archive_cmds_CXX='$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."*)
+	        archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+		archive_expsym_cmds_CXX='$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
+	        archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+		archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+		;;
+	    esac
+	    archive_cmds_need_lc_CXX=no
+	    hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+	    export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+	    whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+	    ;;
+          pgCC* | pgcpp*)
+            # Portland Group C++ compiler
+	    case `$CC -V` in
+	    *pgCC\ [1-5].* | *pgcpp\ [1-5].*)
+	      prelink_cmds_CXX='tpldir=Template.dir~
+		rm -rf $tpldir~
+		$CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~
+		compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"'
+	      old_archive_cmds_CXX='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 | sort | $NL2SP`~
+		$RANLIB $oldlib'
+	      archive_cmds_CXX='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 | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+	      archive_expsym_cmds_CXX='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 | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
+	      ;;
+	    *) # Version 6 and above use weak symbols
+	      archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+	      archive_expsym_cmds_CXX='$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
+
+	    hardcode_libdir_flag_spec_CXX='${wl}--rpath ${wl}$libdir'
+	    export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+	    whole_archive_flag_spec_CXX='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+            ;;
+	  cxx*)
+	    # Compaq C++
+	    archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	    archive_expsym_cmds_CXX='$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
+	    hardcode_libdir_flag_spec_CXX='-rpath $libdir'
+	    hardcode_libdir_separator_CXX=:
+
+	    # 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=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed'
+	    ;;
+	  xl* | mpixl* | bgxl*)
+	    # IBM XL 8.0 on PPC, with GNU ld
+	    hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+	    export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+	    archive_cmds_CXX='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	    if test "x$supports_anon_versioning" = xyes; then
+	      archive_expsym_cmds_CXX='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
+	      no_undefined_flag_CXX=' -zdefs'
+	      archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	      archive_expsym_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols'
+	      hardcode_libdir_flag_spec_CXX='-R$libdir'
+	      whole_archive_flag_spec_CXX='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+	      compiler_needs_object_CXX=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='func_echo_all'
+
+	      # 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.
+	      old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs'
+	      ;;
+	    esac
+	    ;;
+	esac
+	;;
+
+      lynxos*)
+        # FIXME: insert proper C++ library support
+	ld_shlibs_CXX=no
+	;;
+
+      m88k*)
+        # FIXME: insert proper C++ library support
+        ld_shlibs_CXX=no
+	;;
+
+      mvs*)
+        case $cc_basename in
+          cxx*)
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+	  *)
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+	esac
+	;;
+
+      netbsd*)
+        if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+	  archive_cmds_CXX='$LD -Bshareable  -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags'
+	  wlarc=
+	  hardcode_libdir_flag_spec_CXX='-R$libdir'
+	  hardcode_direct_CXX=yes
+	  hardcode_shlibpath_var_CXX=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*)
+        ld_shlibs_CXX=yes
+	;;
+
+      openbsd2*)
+        # C++ shared libraries are fairly broken
+	ld_shlibs_CXX=no
+	;;
+
+      openbsd*)
+	if test -f /usr/libexec/ld.so; then
+	  hardcode_direct_CXX=yes
+	  hardcode_shlibpath_var_CXX=no
+	  hardcode_direct_absolute_CXX=yes
+	  archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+	  hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+	  if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+	    archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib'
+	    export_dynamic_flag_spec_CXX='${wl}-E'
+	    whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+	  fi
+	  output_verbose_link_cmd=func_echo_all
+	else
+	  ld_shlibs_CXX=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.
+	    archive_cmds_CXX='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'
+
+	    hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+	    hardcode_libdir_separator_CXX=:
+
+	    # Archives containing C++ object files must be created using
+	    # the KAI C++ compiler.
+	    case $host in
+	      osf3*) old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ;;
+	      *) old_archive_cmds_CXX='$CC -o $oldlib $oldobjs' ;;
+	    esac
+	    ;;
+          RCC*)
+	    # Rational C++ 2.4.1
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+          cxx*)
+	    case $host in
+	      osf3*)
+	        allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*'
+	        archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+	        hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+		;;
+	      *)
+	        allow_undefined_flag_CXX=' -expect_unresolved \*'
+	        archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+	        archive_expsym_cmds_CXX='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 "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~
+	          $RM $lib.exp'
+	        hardcode_libdir_flag_spec_CXX='-rpath $libdir'
+		;;
+	    esac
+
+	    hardcode_libdir_separator_CXX=:
+
+	    # 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=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+	    ;;
+	  *)
+	    if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+	      allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*'
+	      case $host in
+	        osf3*)
+	          archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+		  ;;
+	        *)
+	          archive_cmds_CXX='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+		  ;;
+	      esac
+
+	      hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+	      hardcode_libdir_separator_CXX=:
+
+	      # 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 -v "^Configured with:" | $GREP "\-L"'
+
+	    else
+	      # FIXME: insert proper C++ library support
+	      ld_shlibs_CXX=no
+	    fi
+	    ;;
+        esac
+        ;;
+
+      psos*)
+        # FIXME: insert proper C++ library support
+        ld_shlibs_CXX=no
+        ;;
+
+      sunos4*)
+        case $cc_basename in
+          CC*)
+	    # Sun C++ 4.x
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+          lcc*)
+	    # Lucid
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+          *)
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+        esac
+        ;;
+
+      solaris*)
+        case $cc_basename in
+          CC* | sunCC*)
+	    # Sun C++ 4.2, 5.x and Centerline C++
+            archive_cmds_need_lc_CXX=yes
+	    no_undefined_flag_CXX=' -zdefs'
+	    archive_cmds_CXX='$CC -G${allow_undefined_flag}  -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	    archive_expsym_cmds_CXX='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'
+
+	    hardcode_libdir_flag_spec_CXX='-R$libdir'
+	    hardcode_shlibpath_var_CXX=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?)
+		whole_archive_flag_spec_CXX='-z allextract$convenience -z defaultextract'
+	        ;;
+	    esac
+	    link_all_deplibs_CXX=yes
+
+	    output_verbose_link_cmd='func_echo_all'
+
+	    # 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.
+	    old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs'
+	    ;;
+          gcx*)
+	    # Green Hills C++ Compiler
+	    archive_cmds_CXX='$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.
+	    old_archive_cmds_CXX='$CC $LDFLAGS -archive -o $oldlib $oldobjs'
+	    ;;
+          *)
+	    # GNU C++ compiler with Solaris linker
+	    if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+	      no_undefined_flag_CXX=' ${wl}-z ${wl}defs'
+	      if $CC --version | $GREP -v '^2\.7' > /dev/null; then
+	        archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+	        archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+		  $CC -shared $pic_flag -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 -v "^Configured with:" | $GREP "\-L"'
+	      else
+	        # g++ 2.7 appears to require `-G' NOT `-shared' on this
+	        # platform.
+	        archive_cmds_CXX='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+	        archive_expsym_cmds_CXX='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 -v "^Configured with:" | $GREP "\-L"'
+	      fi
+
+	      hardcode_libdir_flag_spec_CXX='${wl}-R $wl$libdir'
+	      case $host_os in
+		solaris2.[0-5] | solaris2.[0-5].*) ;;
+		*)
+		  whole_archive_flag_spec_CXX='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+		  ;;
+	      esac
+	    fi
+	    ;;
+        esac
+        ;;
+
+    sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
+      no_undefined_flag_CXX='${wl}-z,text'
+      archive_cmds_need_lc_CXX=no
+      hardcode_shlibpath_var_CXX=no
+      runpath_var='LD_RUN_PATH'
+
+      case $cc_basename in
+        CC*)
+	  archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	*)
+	  archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  archive_expsym_cmds_CXX='$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.
+	no_undefined_flag_CXX='${wl}-z,text'
+	allow_undefined_flag_CXX='${wl}-z,nodefs'
+	archive_cmds_need_lc_CXX=no
+	hardcode_shlibpath_var_CXX=no
+	hardcode_libdir_flag_spec_CXX='${wl}-R,$libdir'
+	hardcode_libdir_separator_CXX=':'
+	link_all_deplibs_CXX=yes
+	export_dynamic_flag_spec_CXX='${wl}-Bexport'
+	runpath_var='LD_RUN_PATH'
+
+	case $cc_basename in
+          CC*)
+	    archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    old_archive_cmds_CXX='$CC -Tprelink_objects $oldobjs~
+	      '"$old_archive_cmds_CXX"
+	    reload_cmds_CXX='$CC -Tprelink_objects $reload_objs~
+	      '"$reload_cmds_CXX"
+	    ;;
+	  *)
+	    archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    archive_expsym_cmds_CXX='$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
+	    ld_shlibs_CXX=no
+	    ;;
+          *)
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+        esac
+        ;;
+
+      vxworks*)
+        # FIXME: insert proper C++ library support
+        ld_shlibs_CXX=no
+        ;;
+
+      *)
+        # FIXME: insert proper C++ library support
+        ld_shlibs_CXX=no
+        ;;
+    esac
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5
+$as_echo "$ld_shlibs_CXX" >&6; }
+    test "$ld_shlibs_CXX" = no && can_build_shared=no
+
+    GCC_CXX="$GXX"
+    LD_CXX="$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...
+    # Dependencies to place before and after the object being linked:
+predep_objects_CXX=
+postdep_objects_CXX=
+predeps_CXX=
+postdeps_CXX=
+compiler_lib_search_path_CXX=
+
+cat > conftest.$ac_ext <<_LT_EOF
+class Foo
+{
+public:
+  Foo (void) { a = 0; }
+private:
+  int a;
+};
+_LT_EOF
+
+
+_lt_libdeps_save_CFLAGS=$CFLAGS
+case "$CC $CFLAGS " in #(
+*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;;
+*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;;
+*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;;
+esac
+
+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
+  # 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 ${prev}${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
+       fi
+
+       # Expand the sysroot to ease extracting the directories later.
+       if test -z "$prev"; then
+         case $p in
+         -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;;
+         -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;;
+         -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;;
+         esac
+       fi
+       case $p in
+       =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;;
+       esac
+       if test "$pre_test_object_deps_done" = no; then
+	 case ${prev} 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 "$compiler_lib_search_path_CXX"; then
+	     compiler_lib_search_path_CXX="${prev}${p}"
+	   else
+	     compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} ${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 "$postdeps_CXX"; then
+	   postdeps_CXX="${prev}${p}"
+	 else
+	   postdeps_CXX="${postdeps_CXX} ${prev}${p}"
+	 fi
+       fi
+       prev=
+       ;;
+
+    *.lto.$objext) ;; # Ignore GCC LTO objects
+    *.$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 "$predep_objects_CXX"; then
+	   predep_objects_CXX="$p"
+	 else
+	   predep_objects_CXX="$predep_objects_CXX $p"
+	 fi
+       else
+	 if test -z "$postdep_objects_CXX"; then
+	   postdep_objects_CXX="$p"
+	 else
+	   postdep_objects_CXX="$postdep_objects_CXX $p"
+	 fi
+       fi
+       ;;
+
+    *) ;; # Ignore the rest.
+
+    esac
+  done
+
+  # Clean up.
+  rm -f a.out a.exe
+else
+  echo "libtool.m4: error: problem compiling CXX test program"
+fi
+
+$RM -f confest.$objext
+CFLAGS=$_lt_libdeps_save_CFLAGS
+
+# PORTME: override above test on systems where it is broken
+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.
+  predep_objects_CXX=
+  postdep_objects_CXX=
+  postdeps_CXX=
+  ;;
+
+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
+      postdeps_CXX='-library=Cstd -library=Crun'
+    fi
+    ;;
+  esac
+  ;;
+
+solaris*)
+  case $cc_basename in
+  CC* | sunCC*)
+    # 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
+      postdeps_CXX='-library=Cstd -library=Crun'
+    fi
+    ;;
+  esac
+  ;;
+esac
+
+
+case " $postdeps_CXX " in
+*" -lc "*) archive_cmds_need_lc_CXX=no ;;
+esac
+ compiler_lib_search_dirs_CXX=
+if test -n "${compiler_lib_search_path_CXX}"; then
+ compiler_lib_search_dirs_CXX=`echo " ${compiler_lib_search_path_CXX}" | ${SED} -e 's! -L! !g' -e 's!^ !!'`
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    lt_prog_compiler_wl_CXX=
+lt_prog_compiler_pic_CXX=
+lt_prog_compiler_static_CXX=
+
+
+  # C++ specific cases for pic, static, wl, etc.
+  if test "$GXX" = yes; then
+    lt_prog_compiler_wl_CXX='-Wl,'
+    lt_prog_compiler_static_CXX='-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_CXX='-Bstatic'
+      fi
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            lt_prog_compiler_pic_CXX='-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_CXX='-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
+      lt_prog_compiler_pic_CXX='-DDLL_EXPORT'
+      ;;
+    darwin* | rhapsody*)
+      # PIC is the default on this platform
+      # Common symbols not allowed in MH_DYLIB files
+      lt_prog_compiler_pic_CXX='-fno-common'
+      ;;
+    *djgpp*)
+      # DJGPP does not support shared libraries at all
+      lt_prog_compiler_pic_CXX=
+      ;;
+    haiku*)
+      # PIC is the default for Haiku.
+      # The "-static" flag exists, but is broken.
+      lt_prog_compiler_static_CXX=
+      ;;
+    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_prog_compiler_pic_CXX=-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_prog_compiler_pic_CXX='-fPIC'
+	;;
+      esac
+      ;;
+    *qnx* | *nto*)
+      # QNX uses GNU C++, but need to define -shared option too, otherwise
+      # it will coredump.
+      lt_prog_compiler_pic_CXX='-fPIC -shared'
+      ;;
+    *)
+      lt_prog_compiler_pic_CXX='-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_prog_compiler_static_CXX='-Bstatic'
+	else
+	  lt_prog_compiler_static_CXX='-bnso -bI:/lib/syscalls.exp'
+	fi
+	;;
+      chorus*)
+	case $cc_basename in
+	cxch68*)
+	  # Green Hills C++ Compiler
+	  # _LT_TAGVAR(lt_prog_compiler_static, CXX)="--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
+	;;
+      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).
+	lt_prog_compiler_pic_CXX='-DDLL_EXPORT'
+	;;
+      dgux*)
+	case $cc_basename in
+	  ec++*)
+	    lt_prog_compiler_pic_CXX='-KPIC'
+	    ;;
+	  ghcx*)
+	    # Green Hills C++ Compiler
+	    lt_prog_compiler_pic_CXX='-pic'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      freebsd* | dragonfly*)
+	# FreeBSD uses GNU C++
+	;;
+      hpux9* | hpux10* | hpux11*)
+	case $cc_basename in
+	  CC*)
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_static_CXX='${wl}-a ${wl}archive'
+	    if test "$host_cpu" != ia64; then
+	      lt_prog_compiler_pic_CXX='+Z'
+	    fi
+	    ;;
+	  aCC*)
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_static_CXX='${wl}-a ${wl}archive'
+	    case $host_cpu in
+	    hppa*64*|ia64*)
+	      # +Z the default
+	      ;;
+	    *)
+	      lt_prog_compiler_pic_CXX='+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_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_static_CXX='-non_shared'
+	    # CC pic flag -KPIC is the default.
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      linux* | k*bsd*-gnu | kopensolaris*-gnu)
+	case $cc_basename in
+	  KCC*)
+	    # KAI C++ Compiler
+	    lt_prog_compiler_wl_CXX='--backend -Wl,'
+	    lt_prog_compiler_pic_CXX='-fPIC'
+	    ;;
+	  ecpc* )
+	    # old Intel C++ for x86_64 which still supported -KPIC.
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_pic_CXX='-KPIC'
+	    lt_prog_compiler_static_CXX='-static'
+	    ;;
+	  icpc* )
+	    # Intel C++, used to be incompatible with GCC.
+	    # ICC 10 doesn't accept -KPIC any more.
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_pic_CXX='-fPIC'
+	    lt_prog_compiler_static_CXX='-static'
+	    ;;
+	  pgCC* | pgcpp*)
+	    # Portland Group C++ compiler
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_pic_CXX='-fpic'
+	    lt_prog_compiler_static_CXX='-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_prog_compiler_pic_CXX=
+	    lt_prog_compiler_static_CXX='-non_shared'
+	    ;;
+	  xlc* | xlC* | bgxl[cC]* | mpixl[cC]*)
+	    # IBM XL 8.0, 9.0 on PPC and BlueGene
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_pic_CXX='-qpic'
+	    lt_prog_compiler_static_CXX='-qstaticlink'
+	    ;;
+	  *)
+	    case `$CC -V 2>&1 | sed 5q` in
+	    *Sun\ C*)
+	      # Sun C++ 5.9
+	      lt_prog_compiler_pic_CXX='-KPIC'
+	      lt_prog_compiler_static_CXX='-Bstatic'
+	      lt_prog_compiler_wl_CXX='-Qoption ld '
+	      ;;
+	    esac
+	    ;;
+	esac
+	;;
+      lynxos*)
+	;;
+      m88k*)
+	;;
+      mvs*)
+	case $cc_basename in
+	  cxx*)
+	    lt_prog_compiler_pic_CXX='-W c,exportall'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      netbsd*)
+	;;
+      *qnx* | *nto*)
+        # QNX uses GNU C++, but need to define -shared option too, otherwise
+        # it will coredump.
+        lt_prog_compiler_pic_CXX='-fPIC -shared'
+        ;;
+      osf3* | osf4* | osf5*)
+	case $cc_basename in
+	  KCC*)
+	    lt_prog_compiler_wl_CXX='--backend -Wl,'
+	    ;;
+	  RCC*)
+	    # Rational C++ 2.4.1
+	    lt_prog_compiler_pic_CXX='-pic'
+	    ;;
+	  cxx*)
+	    # Digital/Compaq C++
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    # Make sure the PIC flag is empty.  It appears that all Alpha
+	    # Linux and Compaq Tru64 Unix objects are PIC.
+	    lt_prog_compiler_pic_CXX=
+	    lt_prog_compiler_static_CXX='-non_shared'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      psos*)
+	;;
+      solaris*)
+	case $cc_basename in
+	  CC* | sunCC*)
+	    # Sun C++ 4.2, 5.x and Centerline C++
+	    lt_prog_compiler_pic_CXX='-KPIC'
+	    lt_prog_compiler_static_CXX='-Bstatic'
+	    lt_prog_compiler_wl_CXX='-Qoption ld '
+	    ;;
+	  gcx*)
+	    # Green Hills C++ Compiler
+	    lt_prog_compiler_pic_CXX='-PIC'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      sunos4*)
+	case $cc_basename in
+	  CC*)
+	    # Sun C++ 4.x
+	    lt_prog_compiler_pic_CXX='-pic'
+	    lt_prog_compiler_static_CXX='-Bstatic'
+	    ;;
+	  lcc*)
+	    # Lucid
+	    lt_prog_compiler_pic_CXX='-pic'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+	case $cc_basename in
+	  CC*)
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_pic_CXX='-KPIC'
+	    lt_prog_compiler_static_CXX='-Bstatic'
+	    ;;
+	esac
+	;;
+      tandem*)
+	case $cc_basename in
+	  NCC*)
+	    # NonStop-UX NCC 3.20
+	    lt_prog_compiler_pic_CXX='-KPIC'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      vxworks*)
+	;;
+      *)
+	lt_prog_compiler_can_build_shared_CXX=no
+	;;
+    esac
+  fi
+
+case $host_os in
+  # For platforms which do not support PIC, -DPIC is meaningless:
+  *djgpp*)
+    lt_prog_compiler_pic_CXX=
+    ;;
+  *)
+    lt_prog_compiler_pic_CXX="$lt_prog_compiler_pic_CXX -DPIC"
+    ;;
+esac
+
+{ $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 ${lt_cv_prog_compiler_pic_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_pic_CXX=$lt_prog_compiler_pic_CXX
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_CXX" >&5
+$as_echo "$lt_cv_prog_compiler_pic_CXX" >&6; }
+lt_prog_compiler_pic_CXX=$lt_cv_prog_compiler_pic_CXX
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$lt_prog_compiler_pic_CXX"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5
+$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... " >&6; }
+if ${lt_cv_prog_compiler_pic_works_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_pic_works_CXX=no
+   ac_outfile=conftest.$ac_objext
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+   lt_compiler_flag="$lt_prog_compiler_pic_CXX -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:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $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 "$_lt_compiler_boilerplate" | $SED '/^$/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_CXX=yes
+     fi
+   fi
+   $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works_CXX" >&5
+$as_echo "$lt_cv_prog_compiler_pic_works_CXX" >&6; }
+
+if test x"$lt_cv_prog_compiler_pic_works_CXX" = xyes; then
+    case $lt_prog_compiler_pic_CXX in
+     "" | " "*) ;;
+     *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;;
+     esac
+else
+    lt_prog_compiler_pic_CXX=
+     lt_prog_compiler_can_build_shared_CXX=no
+fi
+
+fi
+
+
+
+
+
+#
+# Check to make sure the static flag actually works.
+#
+wl=$lt_prog_compiler_wl_CXX eval lt_tmp_static_flag=\"$lt_prog_compiler_static_CXX\"
+{ $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 ${lt_cv_prog_compiler_static_works_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_static_works_CXX=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 "$_lt_linker_boilerplate" | $SED '/^$/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_CXX=yes
+       fi
+     else
+       lt_cv_prog_compiler_static_works_CXX=yes
+     fi
+   fi
+   $RM -r conftest*
+   LDFLAGS="$save_LDFLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works_CXX" >&5
+$as_echo "$lt_cv_prog_compiler_static_works_CXX" >&6; }
+
+if test x"$lt_cv_prog_compiler_static_works_CXX" = xyes; then
+    :
+else
+    lt_prog_compiler_static_CXX=
+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 ${lt_cv_prog_compiler_c_o_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_c_o_CXX=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:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $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 "$_lt_compiler_boilerplate" | $SED '/^$/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_CXX=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_CXX" >&5
+$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&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 ${lt_cv_prog_compiler_c_o_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_c_o_CXX=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:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $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 "$_lt_compiler_boilerplate" | $SED '/^$/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_CXX=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_CXX" >&5
+$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; }
+
+
+
+
+hard_links="nottested"
+if test "$lt_cv_prog_compiler_c_o_CXX" = 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; }
+
+  export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  exclude_expsyms_CXX='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'
+  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
+    # Also, AIX nm treats weak defined symbols like other global defined
+    # symbols, whereas GNU nm marks them as "W".
+    if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+      export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+    else
+      export_symbols_cmds_CXX='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+    fi
+    ;;
+  pw32*)
+    export_symbols_cmds_CXX="$ltdll_cmds"
+    ;;
+  cygwin* | mingw* | cegcc*)
+    case $cc_basename in
+    cl*)
+      exclude_expsyms_CXX='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
+      ;;
+    *)
+      export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols'
+      exclude_expsyms_CXX='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'
+      ;;
+    esac
+    ;;
+  *)
+    export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+    ;;
+  esac
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5
+$as_echo "$ld_shlibs_CXX" >&6; }
+test "$ld_shlibs_CXX" = no && can_build_shared=no
+
+with_gnu_ld_CXX=$with_gnu_ld
+
+
+
+
+
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$archive_cmds_need_lc_CXX" in
+x|xyes)
+  # Assume -lc should be added
+  archive_cmds_need_lc_CXX=yes
+
+  if test "$enable_shared" = yes && test "$GCC" = yes; then
+    case $archive_cmds_CXX 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; }
+if ${lt_cv_archive_cmds_need_lc_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  $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_CXX
+	  pic_flag=$lt_prog_compiler_pic_CXX
+	  compiler_flags=-v
+	  linker_flags=-v
+	  verstring=
+	  output_objdir=.
+	  libname=conftest
+	  lt_save_allow_undefined_flag=$allow_undefined_flag_CXX
+	  allow_undefined_flag_CXX=
+	  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5
+  (eval $archive_cmds_CXX 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
+	    lt_cv_archive_cmds_need_lc_CXX=no
+	  else
+	    lt_cv_archive_cmds_need_lc_CXX=yes
+	  fi
+	  allow_undefined_flag_CXX=$lt_save_allow_undefined_flag
+	else
+	  cat conftest.err 1>&5
+	fi
+	$RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc_CXX" >&5
+$as_echo "$lt_cv_archive_cmds_need_lc_CXX" >&6; }
+      archive_cmds_need_lc_CXX=$lt_cv_archive_cmds_need_lc_CXX
+      ;;
+    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 # correct to gnu/linux during the next big refactor
+  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 # correct to gnu/linux during the next big refactor
+  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=`func_echo_all "$lib" | $SED '\''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 # correct to gnu/linux during the next big refactor
+  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,$cc_basename in
+  yes,*)
+    # gcc
+    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}'
+
+      ;;
+    mingw* | cegcc*)
+      # MinGW DLLs use traditional 'lib' prefix
+      soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      ;;
+    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
+    dynamic_linker='Win32 ld.exe'
+    ;;
+
+  *,cl*)
+    # Native MSVC
+    libname_spec='$name'
+    soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+    library_names_spec='${libname}.dll.lib'
+
+    case $build_os in
+    mingw*)
+      sys_lib_search_path_spec=
+      lt_save_ifs=$IFS
+      IFS=';'
+      for lt_path in $LIB
+      do
+        IFS=$lt_save_ifs
+        # Let DOS variable expansion print the short 8.3 style file name.
+        lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"`
+        sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path"
+      done
+      IFS=$lt_save_ifs
+      # Convert to MSYS style.
+      sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'`
+      ;;
+    cygwin*)
+      # Convert to unix form, then to dos form, then back to unix form
+      # but this time dos style (no spaces!) so that the unix form looks
+      # like /cygdrive/c/PROGRA~1:/cygdr...
+      sys_lib_search_path_spec=`cygpath --path --unix "$LIB"`
+      sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null`
+      sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+      ;;
+    *)
+      sys_lib_search_path_spec="$LIB"
+      if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then
+        # It is most probably a Windows format PATH.
+        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
+      # FIXME: find the short name or the path components, as spaces are
+      # common. (e.g. "Program Files" -> "PROGRA~1")
+      ;;
+    esac
+
+    # 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'
+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+      dlpath=$dir/\$dldll~
+       $RM \$dlpath'
+    shlibpath_overrides_runpath=yes
+    dynamic_linker='Win32 link.exe'
+    ;;
+
+  *)
+    # Assume MSVC wrapper
+    library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
+    dynamic_linker='Win32 ld.exe'
+    ;;
+  esac
+  # 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 # correct to gnu/linux during the next big refactor
+  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
+  ;;
+
+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[23].*) objformat=aout ;;
+    *) objformat=elf ;;
+    esac
+  fi
+  # Handle Gentoo/FreeBSD as it was Linux
+  case $host_vendor in
+    gentoo)
+      version_type=linux ;;
+    *)
+      version_type=freebsd-$objformat ;;
+  esac
+
+  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
+      ;;
+    linux)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+      soname_spec='${libname}${release}${shared_ext}$major'
+      need_lib_prefix=no
+      need_version=no
+      ;;
+  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 # correct to gnu/linux during the next big refactor
+  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
+  ;;
+
+haiku*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  dynamic_linker="$host_os runtime_loader"
+  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=LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
+  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'
+  # or fails outright, so override atomically:
+  install_override_mode=555
+  ;;
+
+interix[3-9]*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  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 # correct to gnu/linux during the next big refactor
+	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 glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  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
+  if ${lt_cv_shlibpath_overrides_runpath+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_shlibpath_overrides_runpath=no
+    save_LDFLAGS=$LDFLAGS
+    save_libdir=$libdir
+    eval "libdir=/foo; wl=\"$lt_prog_compiler_wl_CXX\"; \
+	 LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec_CXX\""
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+  if  ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then :
+  lt_cv_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
+
+fi
+
+  shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath
+
+  # 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;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'
+  ;;
+
+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 # correct to gnu/linux during the next big refactor
+  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 # correct to gnu/linux during the next big refactor
+  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 # correct to gnu/linux during the next big refactor
+  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 # correct to gnu/linux during the next big refactor
+    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 # correct to gnu/linux during the next big refactor
+  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 # correct to gnu/linux during the next big refactor
+  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_CXX=
+if test -n "$hardcode_libdir_flag_spec_CXX" ||
+   test -n "$runpath_var_CXX" ||
+   test "X$hardcode_automatic_CXX" = "Xyes" ; then
+
+  # We can hardcode non-existent directories.
+  if test "$hardcode_direct_CXX" != 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, CXX)" != no &&
+     test "$hardcode_minus_L_CXX" != no; then
+    # Linking always hardcodes the temporary library directory.
+    hardcode_action_CXX=relink
+  else
+    # We can link without hardcoding, and we can hardcode nonexisting dirs.
+    hardcode_action_CXX=immediate
+  fi
+else
+  # We cannot hardcode anything, or else we can only hardcode existing
+  # directories.
+  hardcode_action_CXX=unsupported
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action_CXX" >&5
+$as_echo "$hardcode_action_CXX" >&6; }
+
+if test "$hardcode_action_CXX" = relink ||
+   test "$inherit_rpath_CXX" = 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"
+
+  CC=$lt_save_CC
+  CFLAGS=$lt_save_CFLAGS
+  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_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_config_commands="$ac_config_commands libtool"
+
+
+
+
+# Only expand once:
+
+
+
+# Checks for header files.
+{ $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 ${ac_cv_header_stdc+:} false; 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
+
+
+# Checks for typedefs, structures, and compiler characteristics.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5
+$as_echo_n "checking for inline... " >&6; }
+if ${ac_cv_c_inline+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_cv_c_inline=no
+for ac_kw in inline __inline__ __inline; do
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifndef __cplusplus
+typedef int foo_t;
+static $ac_kw foo_t static_foo () {return 0; }
+$ac_kw foo_t foo () {return 0; }
+#endif
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_c_inline=$ac_kw
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  test "$ac_cv_c_inline" != no && break
+done
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5
+$as_echo "$ac_cv_c_inline" >&6; }
+
+case $ac_cv_c_inline in
+  inline | yes) ;;
+  *)
+    case $ac_cv_c_inline in
+      no) ac_val=;;
+      *) ac_val=$ac_cv_c_inline;;
+    esac
+    cat >>confdefs.h <<_ACEOF
+#ifndef __cplusplus
+#define inline $ac_val
+#endif
+_ACEOF
+    ;;
+esac
+
+
+
+DEFAULT_CHECKING_PATH="/usr /usr/local /sw /opt/local"
+
+
+# Check whether --with-gmp was given.
+if test "${with_gmp+set}" = set; then :
+  withval=$with_gmp; if test "$withval" = yes ; then
+			GMP_HOME_PATH="${DEFAULT_CHECKING_PATH}"
+	         elif test "$withval" != no ; then
+			GMP_HOME_PATH="$withval ${DEFAULT_CHECKING_PATH}"
+	        fi
+else
+  GMP_HOME_PATH="${DEFAULT_CHECKING_PATH}"
+fi
+
+
+min_gmp_version=4.0
+
+BACKUP_CFLAGS=${CFLAGS}
+BACKUP_LIBS=${LIBS}
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GMP >= $min_gmp_version" >&5
+$as_echo_n "checking for GMP >= $min_gmp_version... " >&6; }
+
+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
+
+
+for GMP_HOME in ${GMP_HOME_PATH}
+  do
+#	if test -r "$GMP_HOME/include/gmp.h"; then
+
+		if test "x$GMP_HOME" != "x/usr"; then
+			GMP_CFLAGS="-I${GMP_HOME}/include"
+			GMP_LIBS="-L${GMP_HOME}/lib -Wl,-rpath -Wl,${GMP_HOME}/lib -lgmp"
+		else
+			GMP_CFLAGS=""
+			GMP_LIBS="-lgmp"
+		fi
+
+		CFLAGS="${BACKUP_CFLAGS} ${GMP_CFLAGS}"
+		LIBS="${BACKUP_LIBS} ${GMP_LIBS}"
+
+    # According to C. Fieker this would link but would not RUN
+    # (AC_TRY_RUN) due to missing SHARED libgmp.so :(
+    # TODO: set LD_LIBRARY_PATH???
+		cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <gmp.h>
+int
+main ()
+{
+mpz_t a; mpz_init (a);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+        		if test "$cross_compiling" = yes; then :
+
+				{ $as_echo "$as_me:${as_lineno-$LINENO}: result: unknown" >&5
+$as_echo "unknown" >&6; }
+				echo "WARNING: You appear to be cross compiling, so there is no way to determine"
+				echo "whether your GMP version is new enough. I am assuming it is."
+
+
+
+				HAVE_GMP=yes
+
+$as_echo "#define HAVE_GMP 1" >>confdefs.h
+
+				:
+				break
+
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <gmp.h>
+			 int main () {  if (__GNU_MP_VERSION < 3) return -1; else return 0; }
+
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+				{ $as_echo "$as_me:${as_lineno-$LINENO}: result: found" >&5
+$as_echo "found" >&6; }
+
+
+
+$as_echo "#define HAVE_GMP 1" >>confdefs.h
+
+				# See if we are running GMP 4.0
+	   			{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether GMP is 4.0 or greater" >&5
+$as_echo_n "checking whether GMP is 4.0 or greater... " >&6; }
+		   		if test "$cross_compiling" = yes; then :
+
+										{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <gmp.h>
+	    			int main () { if (__GNU_MP_VERSION < 4) return -1; else return 0; }
+
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+					gmp_found="yes"
+					{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+					GMP_VERSION=""
+
+
+else
+
+					{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+$as_echo "#define GMP_VERSION_3 1" >>confdefs.h
+
+					GMP_VERSION="-DGMP_VERSION_3"
+
+
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+				:
+				break
+
+else
+
+				gmp_problem="$gmp_problem $GMP_HOME"
+				unset GMP_CFLAGS
+				unset GMP_LIBS
+
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+
+else
+
+		gmp_found="no"
+		unset GMP_CFLAGS
+		unset GMP_LIBS
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+
+#	else
+#		gmp_found="no"
+#	fi
+done
+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
+
+
+CFLAGS=${BACKUP_CFLAGS}
+LIBS=${BACKUP_LIBS}
+#unset LD_LIBRARY_PATH
+
+
+if test "x$gmp_found" != "xyes"; then
+	if test -n "$gmp_problem"; then
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: problem" >&5
+$as_echo "problem" >&6; }
+		echo "Sorry, your GMP version is too old. Disabling."
+	elif test "x$gmp_found" != "xno"; then
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5
+$as_echo "not found" >&6; }
+	fi
+	as_fn_error $? "Unable to find GMP on your machine: please use --with-gmp=PATH_TO_DIR_CONTAINING_LIB_AND_INCLUDE (see also ./configure --help if you do not understand what we are talking about)" "$LINENO" 5
+fi
+
+ if test "x$HAVE_GMP" = "xyes"; then
+  SING_HAVE_GMP_TRUE=
+  SING_HAVE_GMP_FALSE='#'
+else
+  SING_HAVE_GMP_TRUE='#'
+  SING_HAVE_GMP_FALSE=
+fi
+
+
+
+
+
+# Check whether --enable-gfanlib was given.
+if test "${enable_gfanlib+set}" = set; then :
+  enableval=$enable_gfanlib; ENABLE_GFANLIB="$enableval"
+else
+  ENABLE_GFANLIB=""
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to check for gfanlib" >&5
+$as_echo_n "checking whether to check for gfanlib... " >&6; }
+
+if test "x$ENABLE_GFANLIB" != "xno"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+ for ac_header in setoper.h cdd/setoper.h cddlib/setoper.h
+do :
+  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+ if test "x$ac_cv_header_setoper_h" = xno -a "x$ac_cv_header_cdd_setoper_h" = xno -a "x$ac_cv_header_cddlib_setoper_h" = xno; then
+   { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Note that setoper.h is missing!" >&5
+$as_echo "$as_me: WARNING: Note that setoper.h is missing!" >&2;}
+ fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether libcddgmp is usable" >&5
+$as_echo_n "checking whether libcddgmp is usable... " >&6; }
+
+ BACKUP_LIBS=$LIBS
+
+ LIBS="$LIBS -lcddgmp $GMP_LIBS "
+
+ 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.  */
+
+
+    #define GMPRATIONAL
+     #ifdef HAVE_SETOPER_H
+     # include <setoper.h>
+     # include <cdd.h>
+     #endif
+     #ifdef HAVE_CDD_SETOPER_H
+     # include <cdd/setoper.h>
+     # include <cdd/cdd.h>
+     #endif
+     #ifdef HAVE_CDDLIB_SETOPER_H
+     # include <cddlib/setoper.h>
+     # include <cddlib/cdd.h>
+     #endif
+
+int
+main ()
+{
+dd_set_global_constants(); dd_log=dd_FALSE;
+
+  ;
+  return 0;
+}
+
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  PASSED_ALL_TESTS_FOR_GFANLIB="1" CDDGMPLDFLAGS="-lcddgmp $GMP_LIBS"  CDDGMPCPPFLAGS="-DGMPRATIONAL"
+else
+  PASSED_ALL_TESTS_FOR_GFANLIB="0"
+
+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
+
+
+ LIBS=$BACKUP_LIBS
+
+ if test "x$PASSED_ALL_TESTS_FOR_GFANLIB" = x1; 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 "x$ENABLE_GFANLIB" = "xyes"; then
+   as_fn_error $? "Error, could not use libcddgmp" "$LINENO" 5
+  fi
+ fi
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ PASSED_ALL_TESTS_FOR_GFANLIB="0"
+fi
+
+
+
+ if test "x$PASSED_ALL_TESTS_FOR_GFANLIB" = x1; then
+  HAVE_GFANLIB_TRUE=
+  HAVE_GFANLIB_FALSE='#'
+else
+  HAVE_GFANLIB_TRUE='#'
+  HAVE_GFANLIB_FALSE=
+fi
+
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_GFANLIB ${PASSED_ALL_TESTS_FOR_GFANLIB}
+_ACEOF
+
+
+
+
+#AC_MSG_RESULT($ac_cv_singuname)
+#if test "$ac_cv_singuname" = unknown; then
+#  AC_MSG_WARN(Unknown architecture: Check singuname.sh)
+#  ac_cv_singuname="unknown"
+#fi
+#AC_DEFINE_UNQUOTED(S_UNAME, "$ac_cv_singuname")
+#SINGUNAME=$ac_cv_singuname
+#AC_SUBST(SINGUNAME)
+
+ac_config_files="$ac_config_files Makefile"
+
+## AC_CONFIG_HEADERS([config.h])
+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
+    if test "x$cache_file" != "x/dev/null"; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
+$as_echo "$as_me: updating cache $cache_file" >&6;}
+      if test ! -f "$cache_file" || test -h "$cache_file"; then
+	cat confcache >"$cache_file"
+      else
+        case $cache_file in #(
+        */* | ?:*)
+	  mv -f confcache "$cache_file"$$ &&
+	  mv -f "$cache_file"$$ "$cache_file" ;; #(
+        *)
+	  mv -f confcache "$cache_file" ;;
+	esac
+      fi
+    fi
+  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=
+U=
+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
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5
+$as_echo_n "checking that generated files are newer than configure... " >&6; }
+   if test -n "$am_sleep_pid"; then
+     # Hide warnings about reused PIDs.
+     wait $am_sleep_pid 2>/dev/null
+   fi
+   { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5
+$as_echo "done" >&6; }
+ if test -n "$EXEEXT"; then
+  am__EXEEXT_TRUE=
+  am__EXEEXT_FALSE='#'
+else
+  am__EXEEXT_TRUE='#'
+  am__EXEEXT_FALSE=
+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 "${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 "${WANT_DEBUG_TRUE}" && test -z "${WANT_DEBUG_FALSE}"; then
+  as_fn_error $? "conditional \"WANT_DEBUG\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${WANT_OPTIMIZATIONFLAGS_TRUE}" && test -z "${WANT_OPTIMIZATIONFLAGS_FALSE}"; then
+  as_fn_error $? "conditional \"WANT_OPTIMIZATIONFLAGS\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then
+  as_fn_error $? "conditional \"am__fastdepCXX\" 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 "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then
+  as_fn_error $? "conditional \"am__fastdepCXX\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${SING_HAVE_GMP_TRUE}" && test -z "${SING_HAVE_GMP_FALSE}"; then
+  as_fn_error $? "conditional \"SING_HAVE_GMP\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${HAVE_GFANLIB_TRUE}" && test -z "${HAVE_GFANLIB_FALSE}"; then
+  as_fn_error $? "conditional \"HAVE_GFANLIB\" 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.
+as_myself=
+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 STATUS 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=$1; test $as_status -eq 0 && as_status=1
+  if test "$4"; then
+    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+  fi
+  $as_echo "$as_me: error: $2" >&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 -pR'.
+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+      as_ln_s='cp -pR'
+  elif ln conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s=ln
+  else
+    as_ln_s='cp -pR'
+  fi
+else
+  as_ln_s='cp -pR'
+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
+
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+  test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
+
+# 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 libgfan $as_me 0.1, which was
+generated by GNU Autoconf 2.69.  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
+      --config     print configuration, 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 <ren at mathematik.uni-kl.de>."
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
+ac_cs_version="\\
+libgfan config.status 0.1
+configured by $0, generated by GNU Autoconf 2.69,
+  with options \\"\$ac_cs_config\\"
+
+Copyright (C) 2012 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=`expr "X$1" : 'X\([^=]*\)='`
+    ac_optarg=
+    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 ;;
+  --config | --confi | --conf | --con | --co | --c )
+    $as_echo "$ac_cs_config"; 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"` ;;
+    '') as_fn_error $? "missing file argument" ;;
+    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"
+PACKAGE="$PACKAGE"
+
+
+# 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'
+macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`'
+macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`'
+enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`'
+enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`'
+pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`'
+enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`'
+SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`'
+ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`'
+PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`'
+host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`'
+host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`'
+host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`'
+build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`'
+build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`'
+build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`'
+SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`'
+Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`'
+GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`'
+EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`'
+FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`'
+LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`'
+NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`'
+LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`'
+max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`'
+ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`'
+exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`'
+lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`'
+lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`'
+lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`'
+lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`'
+lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`'
+reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`'
+reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`'
+OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`'
+deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`'
+file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`'
+file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`'
+want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`'
+DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`'
+sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`'
+AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`'
+AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`'
+archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`'
+STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`'
+RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`'
+old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`'
+old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`'
+old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`'
+lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`'
+CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`'
+CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`'
+compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`'
+GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`'
+nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`'
+lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`'
+objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`'
+MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`'
+lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`'
+need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`'
+MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`'
+DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`'
+NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`'
+LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`'
+OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`'
+OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`'
+libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`'
+shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`'
+extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`'
+archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`'
+enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`'
+export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`'
+whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`'
+compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`'
+old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`'
+old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`'
+archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`'
+archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`'
+module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`'
+module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`'
+with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`'
+allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`'
+no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`'
+hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`'
+hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`'
+hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`'
+hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`'
+hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`'
+inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`'
+link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`'
+always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`'
+export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`'
+exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`'
+include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`'
+prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`'
+postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`'
+file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`'
+variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`'
+need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`'
+need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`'
+version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`'
+runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`'
+shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`'
+shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`'
+libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`'
+library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`'
+soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`'
+install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`'
+postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`'
+postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`'
+finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`'
+finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`'
+hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`'
+sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`'
+sys_lib_dlsearch_path_spec='`$ECHO "$sys_lib_dlsearch_path_spec" | $SED "$delay_single_quote_subst"`'
+hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`'
+enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`'
+enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`'
+enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`'
+old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`'
+striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`'
+compiler_lib_search_dirs='`$ECHO "$compiler_lib_search_dirs" | $SED "$delay_single_quote_subst"`'
+predep_objects='`$ECHO "$predep_objects" | $SED "$delay_single_quote_subst"`'
+postdep_objects='`$ECHO "$postdep_objects" | $SED "$delay_single_quote_subst"`'
+predeps='`$ECHO "$predeps" | $SED "$delay_single_quote_subst"`'
+postdeps='`$ECHO "$postdeps" | $SED "$delay_single_quote_subst"`'
+compiler_lib_search_path='`$ECHO "$compiler_lib_search_path" | $SED "$delay_single_quote_subst"`'
+LD_CXX='`$ECHO "$LD_CXX" | $SED "$delay_single_quote_subst"`'
+reload_flag_CXX='`$ECHO "$reload_flag_CXX" | $SED "$delay_single_quote_subst"`'
+reload_cmds_CXX='`$ECHO "$reload_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+old_archive_cmds_CXX='`$ECHO "$old_archive_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+compiler_CXX='`$ECHO "$compiler_CXX" | $SED "$delay_single_quote_subst"`'
+GCC_CXX='`$ECHO "$GCC_CXX" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_no_builtin_flag_CXX='`$ECHO "$lt_prog_compiler_no_builtin_flag_CXX" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_pic_CXX='`$ECHO "$lt_prog_compiler_pic_CXX" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_wl_CXX='`$ECHO "$lt_prog_compiler_wl_CXX" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_static_CXX='`$ECHO "$lt_prog_compiler_static_CXX" | $SED "$delay_single_quote_subst"`'
+lt_cv_prog_compiler_c_o_CXX='`$ECHO "$lt_cv_prog_compiler_c_o_CXX" | $SED "$delay_single_quote_subst"`'
+archive_cmds_need_lc_CXX='`$ECHO "$archive_cmds_need_lc_CXX" | $SED "$delay_single_quote_subst"`'
+enable_shared_with_static_runtimes_CXX='`$ECHO "$enable_shared_with_static_runtimes_CXX" | $SED "$delay_single_quote_subst"`'
+export_dynamic_flag_spec_CXX='`$ECHO "$export_dynamic_flag_spec_CXX" | $SED "$delay_single_quote_subst"`'
+whole_archive_flag_spec_CXX='`$ECHO "$whole_archive_flag_spec_CXX" | $SED "$delay_single_quote_subst"`'
+compiler_needs_object_CXX='`$ECHO "$compiler_needs_object_CXX" | $SED "$delay_single_quote_subst"`'
+old_archive_from_new_cmds_CXX='`$ECHO "$old_archive_from_new_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+old_archive_from_expsyms_cmds_CXX='`$ECHO "$old_archive_from_expsyms_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+archive_cmds_CXX='`$ECHO "$archive_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+archive_expsym_cmds_CXX='`$ECHO "$archive_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+module_cmds_CXX='`$ECHO "$module_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+module_expsym_cmds_CXX='`$ECHO "$module_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+with_gnu_ld_CXX='`$ECHO "$with_gnu_ld_CXX" | $SED "$delay_single_quote_subst"`'
+allow_undefined_flag_CXX='`$ECHO "$allow_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`'
+no_undefined_flag_CXX='`$ECHO "$no_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_flag_spec_CXX='`$ECHO "$hardcode_libdir_flag_spec_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_separator_CXX='`$ECHO "$hardcode_libdir_separator_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_direct_CXX='`$ECHO "$hardcode_direct_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_direct_absolute_CXX='`$ECHO "$hardcode_direct_absolute_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_minus_L_CXX='`$ECHO "$hardcode_minus_L_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_shlibpath_var_CXX='`$ECHO "$hardcode_shlibpath_var_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_automatic_CXX='`$ECHO "$hardcode_automatic_CXX" | $SED "$delay_single_quote_subst"`'
+inherit_rpath_CXX='`$ECHO "$inherit_rpath_CXX" | $SED "$delay_single_quote_subst"`'
+link_all_deplibs_CXX='`$ECHO "$link_all_deplibs_CXX" | $SED "$delay_single_quote_subst"`'
+always_export_symbols_CXX='`$ECHO "$always_export_symbols_CXX" | $SED "$delay_single_quote_subst"`'
+export_symbols_cmds_CXX='`$ECHO "$export_symbols_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+exclude_expsyms_CXX='`$ECHO "$exclude_expsyms_CXX" | $SED "$delay_single_quote_subst"`'
+include_expsyms_CXX='`$ECHO "$include_expsyms_CXX" | $SED "$delay_single_quote_subst"`'
+prelink_cmds_CXX='`$ECHO "$prelink_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+postlink_cmds_CXX='`$ECHO "$postlink_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+file_list_spec_CXX='`$ECHO "$file_list_spec_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_action_CXX='`$ECHO "$hardcode_action_CXX" | $SED "$delay_single_quote_subst"`'
+compiler_lib_search_dirs_CXX='`$ECHO "$compiler_lib_search_dirs_CXX" | $SED "$delay_single_quote_subst"`'
+predep_objects_CXX='`$ECHO "$predep_objects_CXX" | $SED "$delay_single_quote_subst"`'
+postdep_objects_CXX='`$ECHO "$postdep_objects_CXX" | $SED "$delay_single_quote_subst"`'
+predeps_CXX='`$ECHO "$predeps_CXX" | $SED "$delay_single_quote_subst"`'
+postdeps_CXX='`$ECHO "$postdeps_CXX" | $SED "$delay_single_quote_subst"`'
+compiler_lib_search_path_CXX='`$ECHO "$compiler_lib_search_path_CXX" | $SED "$delay_single_quote_subst"`'
+
+LTCC='$LTCC'
+LTCFLAGS='$LTCFLAGS'
+compiler='$compiler_DEFAULT'
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+  eval 'cat <<_LTECHO_EOF
+\$1
+_LTECHO_EOF'
+}
+
+# Quote evaled strings.
+for var in SHELL \
+ECHO \
+PATH_SEPARATOR \
+SED \
+GREP \
+EGREP \
+FGREP \
+LD \
+NM \
+LN_S \
+lt_SP2NL \
+lt_NL2SP \
+reload_flag \
+OBJDUMP \
+deplibs_check_method \
+file_magic_cmd \
+file_magic_glob \
+want_nocaseglob \
+DLLTOOL \
+sharedlib_from_linklib_cmd \
+AR \
+AR_FLAGS \
+archiver_list_spec \
+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 \
+nm_file_list_spec \
+lt_prog_compiler_no_builtin_flag \
+lt_prog_compiler_pic \
+lt_prog_compiler_wl \
+lt_prog_compiler_static \
+lt_cv_prog_compiler_c_o \
+need_locks \
+MANIFEST_TOOL \
+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_separator \
+exclude_expsyms \
+include_expsyms \
+file_list_spec \
+variables_saved_for_relink \
+libname_spec \
+library_names_spec \
+soname_spec \
+install_override_mode \
+finish_eval \
+old_striplib \
+striplib \
+compiler_lib_search_dirs \
+predep_objects \
+postdep_objects \
+predeps \
+postdeps \
+compiler_lib_search_path \
+LD_CXX \
+reload_flag_CXX \
+compiler_CXX \
+lt_prog_compiler_no_builtin_flag_CXX \
+lt_prog_compiler_pic_CXX \
+lt_prog_compiler_wl_CXX \
+lt_prog_compiler_static_CXX \
+lt_cv_prog_compiler_c_o_CXX \
+export_dynamic_flag_spec_CXX \
+whole_archive_flag_spec_CXX \
+compiler_needs_object_CXX \
+with_gnu_ld_CXX \
+allow_undefined_flag_CXX \
+no_undefined_flag_CXX \
+hardcode_libdir_flag_spec_CXX \
+hardcode_libdir_separator_CXX \
+exclude_expsyms_CXX \
+include_expsyms_CXX \
+file_list_spec_CXX \
+compiler_lib_search_dirs_CXX \
+predep_objects_CXX \
+postdep_objects_CXX \
+predeps_CXX \
+postdeps_CXX \
+compiler_lib_search_path_CXX; do
+    case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+    *[\\\\\\\`\\"\\\$]*)
+      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$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 \
+postlink_cmds \
+postinstall_cmds \
+postuninstall_cmds \
+finish_cmds \
+sys_lib_search_path_spec \
+sys_lib_dlsearch_path_spec \
+reload_cmds_CXX \
+old_archive_cmds_CXX \
+old_archive_from_new_cmds_CXX \
+old_archive_from_expsyms_cmds_CXX \
+archive_cmds_CXX \
+archive_expsym_cmds_CXX \
+module_cmds_CXX \
+module_expsym_cmds_CXX \
+export_symbols_cmds_CXX \
+prelink_cmds_CXX \
+postlink_cmds_CXX; do
+    case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+    *[\\\\\\\`\\"\\\$]*)
+      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\""
+      ;;
+    *)
+      eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+      ;;
+    esac
+done
+
+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'
+
+
+
+
+
+
+_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" ;;
+    "config.h") CONFIG_COMMANDS="$CONFIG_COMMANDS config.h" ;;
+    "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;;
+    "Makefile") CONFIG_FILES="$CONFIG_FILES 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= ac_tmp=
+  trap 'exit_status=$?
+  : "${ac_tmp:=$tmp}"
+  { test ! -d "$ac_tmp" || rm -fr "$ac_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 -d "$tmp"
+}  ||
+{
+  tmp=./conf$$-$RANDOM
+  (umask 077 && mkdir "$tmp")
+} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
+ac_tmp=$tmp
+
+# 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 {' >"$ac_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 >>"\$ac_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 >>"\$ac_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 < "$ac_tmp/subs1.awk" > "$ac_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 sole $(srcdir),
+# ${srcdir} and @srcdir@ entries 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[	 ]*=[	 ]*/{
+h
+s///
+s/^/:/
+s/[	 ]*$/:/
+s/:\$(srcdir):/:/g
+s/:\${srcdir}:/:/g
+s/:@srcdir@:/:/g
+s/^:*//
+s/:*$//
+x
+s/\(=[	 ]*\).*/\1/
+G
+s/\n//
+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 >"$ac_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_tt=`sed -n "/$ac_delim/p" confdefs.h`
+  if test -z "$ac_tt"; 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="$ac_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 1 "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 >"$ac_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 "$ac_tmp/subs.awk" \
+  >$ac_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' "$ac_tmp/out"`; test -n "$ac_out"; } &&
+  { ac_out=`sed -n '/^[	 ]*datarootdir[	 ]*:*=/p' \
+      "$ac_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 "$ac_tmp/stdin"
+  case $ac_file in
+  -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";;
+  *) rm -f "$ac_file" && mv "$ac_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 "$ac_tmp/defines.awk"' "$ac_file_inputs"
+    } >"$ac_tmp/config.h" \
+      || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+    if diff "$ac_file" "$ac_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 "$ac_tmp/config.h" "$ac_file" \
+	|| as_fn_error $? "could not create $ac_file" "$LINENO" 5
+    fi
+  else
+    $as_echo "/* $configure_input  */" \
+      && eval '$AWK -f "$ac_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"" || {
+  # Older Autoconf 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"`
+    # 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'`; 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
+}
+ ;;
+    "config.h":C)
+ac_prefix_conf_OUT=`echo config.h`
+ac_prefix_conf_PKG=`echo `
+ac_prefix_conf_LOW=`echo $ac_prefix_conf_PKG | sed -e "y:ABCDEFGHIJKLMNOPQRSTUVWXYZ-:abcdefghijklmnopqrstuvwxyz_:"`
+ac_prefix_conf_UPP=`echo $ac_prefix_conf_PKG | sed -e "y:abcdefghijklmnopqrstuvwxyz-:ABCDEFGHIJKLMNOPQRSTUVWXYZ_:"  -e "/^[0123456789]/s/^/_/"`
+ac_prefix_conf_INP=`echo "_config.h" | sed -e 's/ *//'`
+ac_prefix_conf_DEF=`echo "$ac_prefix_conf_UPP $PACKAGE $ac_prefix_conf_OUT" | sed -e "y:abcdefghijklmnopqrstuvwxyz:ABCDEFGHIJKLMNOPQRSTUVWXYZ:" -e "s/[^abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ]/_/g"`
+
+if test ".$ac_prefix_conf_INP" = "."; then
+   for ac_file in : $CONFIG_HEADERS; do test "_$ac_file" = _: && continue
+     case "$ac_file" in
+        *.h) ac_prefix_conf_INP=$ac_file ;;
+        *)
+     esac
+     test ".$ac_prefix_conf_INP" != "." && break
+   done
+fi
+if test ".$ac_prefix_conf_INP" = "."; then
+   case "$ac_prefix_conf_OUT" in
+      */*) ac_prefix_conf_INP=`basename "$ac_prefix_conf_OUT"`
+      ;;
+      *-*) ac_prefix_conf_INP=`echo "$ac_prefix_conf_OUT" | sed -e "s/[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_]*-//"`
+      ;;
+      *) ac_prefix_conf_INP=config.h
+      ;;
+   esac
+fi
+#if test -z "$_PKG" ; then
+#   AC_MSG_ERROR([no prefix for AX_PREFIX_PKG_CONFIG_H])
+#else
+  if test ! -f "$ac_prefix_conf_INP" ; then if test -f "$srcdir/$ac_prefix_conf_INP" ; then
+     ac_prefix_conf_INP="$srcdir/$ac_prefix_conf_INP"
+  fi fi
+  { $as_echo "$as_me:${as_lineno-$LINENO}: creating '$ac_prefix_conf_OUT' - prefix '$ac_prefix_conf_UPP' for '$ac_prefix_conf_INP' defines" >&5
+$as_echo "$as_me: creating '$ac_prefix_conf_OUT' - prefix '$ac_prefix_conf_UPP' for '$ac_prefix_conf_INP' defines" >&6;}
+  if test -f $ac_prefix_conf_INP ; then
+    $as_echo "s/^#undef  *\\([ABCDEFGHIJKLMNOPQRSTUVWXYZ_]\\)/#undef $ac_prefix_conf_UPP""\\1/" > conftest.prefix
+    $as_echo "s/^#undef  *\\([abcdefghijklmnopqrstuvwxyz]\\)/#undef $ac_prefix_conf_LOW""\\1/" >> conftest.prefix
+    $as_echo "s/^#define  *\\([ABCDEFGHIJKLMNOPQRSTUVWXYZ_][abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_]*\\)\\(.*\\)/#ifndef $ac_prefix_conf_UPP""\\1\\" >> conftest.prefix
+    $as_echo "#define $ac_prefix_conf_UPP""\\1\\2\\" >> conftest.prefix
+    $as_echo "#endif/" >> conftest.prefix
+    $as_echo "s/^#define  *\\([abcdefghijklmnopqrstuvwxyz][abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_]*\\)\\(.*\\)/#ifndef $ac_prefix_conf_LOW""\\1\\" >> conftest.prefix
+    $as_echo "#define $ac_prefix_conf_LOW""\\1\\2\\" >> conftest.prefix
+    $as_echo "#endif/" >> conftest.prefix
+
+    # now executing _script on _DEF input to create _OUT output file
+    echo "#ifndef $ac_prefix_conf_DEF"      >$tmp/pconfig.h
+    echo "#define $ac_prefix_conf_DEF 1" >>$tmp/pconfig.h
+    echo ' ' >>$tmp/pconfig.h
+
+    echo /'*' $ac_prefix_conf_OUT. Generated automatically at end of configure. '*'/ >>$tmp/pconfig.h
+    echo ' ' >>$tmp/pconfig.h
+
+    sed -f conftest.prefix $ac_prefix_conf_INP >>$tmp/pconfig.h
+    echo ' ' >>$tmp/pconfig.h
+    echo '/* once:' $ac_prefix_conf_DEF '*/' >>$tmp/pconfig.h
+    echo "#endif" >>$tmp/pconfig.h
+    if cmp -s $ac_prefix_conf_OUT $tmp/pconfig.h 2>/dev/null; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_prefix_conf_OUT is unchanged" >&5
+$as_echo "$as_me: $ac_prefix_conf_OUT is unchanged" >&6;}
+    else
+      ac_dir=`$as_dirname -- "$ac_prefix_conf_OUT" ||
+$as_expr X"$ac_prefix_conf_OUT" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$ac_prefix_conf_OUT" : 'X\(//\)[^/]' \| \
+	 X"$ac_prefix_conf_OUT" : 'X\(//\)$' \| \
+	 X"$ac_prefix_conf_OUT" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$ac_prefix_conf_OUT" |
+    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
+      rm -f "$ac_prefix_conf_OUT"
+      mv $tmp/pconfig.h "$ac_prefix_conf_OUT"
+    fi
+    cp conftest.prefix _configs.sed
+    rm _configs.sed
+  else
+    as_fn_error $? "input file $ac_prefix_conf_INP does not exist - skip generating $ac_prefix_conf_OUT" "$LINENO" 5
+  fi
+  rm -f conftest.*
+#fi
+ ;;
+    "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, 2009, 2010, 2011 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="CXX "
+
+# ### BEGIN LIBTOOL CONFIG
+
+# 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
+
+# Shell to use when invoking shell scripts.
+SHELL=$lt_SHELL
+
+# An echo program that protects backslashes.
+ECHO=$lt_ECHO
+
+# The PATH separator for the build system.
+PATH_SEPARATOR=$lt_PATH_SEPARATOR
+
+# 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
+
+# convert \$build file names to \$host format.
+to_host_file_cmd=$lt_cv_to_host_file_cmd
+
+# convert \$build files to toolchain format.
+to_tool_file_cmd=$lt_cv_to_tool_file_cmd
+
+# An object symbol dumper.
+OBJDUMP=$lt_OBJDUMP
+
+# 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
+
+# How to find potential files when deplibs_check_method = "file_magic".
+file_magic_glob=$lt_file_magic_glob
+
+# Find potential files using nocaseglob when deplibs_check_method = "file_magic".
+want_nocaseglob=$lt_want_nocaseglob
+
+# DLL creation program.
+DLLTOOL=$lt_DLLTOOL
+
+# Command to associate shared and link libraries.
+sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd
+
+# The archiver.
+AR=$lt_AR
+
+# Flags to create an archive.
+AR_FLAGS=$lt_AR_FLAGS
+
+# How to feed a file listing to the archiver.
+archiver_list_spec=$lt_archiver_list_spec
+
+# 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
+
+# Whether to use a lock for old archive extraction.
+lock_old_archive_extraction=$lock_old_archive_extraction
+
+# 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
+
+# Specify filename containing input files for \$NM.
+nm_file_list_spec=$lt_nm_file_list_spec
+
+# The root where to search for dependent libraries,and in which our libraries should be installed.
+lt_sysroot=$lt_sysroot
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# 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
+
+# Manifest tool.
+MANIFEST_TOOL=$lt_MANIFEST_TOOL
+
+# 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
+
+# Permission mode override for installation of shared libraries.
+install_override_mode=$lt_install_override_mode
+
+# 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
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag
+reload_cmds=$lt_reload_cmds
+
+# 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
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_lt_prog_compiler_pic
+
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl
+
+# 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
+
+# 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
+
+# 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
+
+# Commands necessary for finishing linking programs.
+postlink_cmds=$lt_postlink_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
+
+# The directories searched by this compiler when creating a shared library.
+compiler_lib_search_dirs=$lt_compiler_lib_search_dirs
+
+# Dependencies to place before and after the objects being linked to
+# create a shared library.
+predep_objects=$lt_predep_objects
+postdep_objects=$lt_postdep_objects
+predeps=$lt_predeps
+postdeps=$lt_postdeps
+
+# The library search path used internally by the compiler when linking
+# a shared library.
+compiler_lib_search_path=$lt_compiler_lib_search_path
+
+# ### 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 '$q' "$ltmain" >> "$cfgfile" \
+     || (rm -f "$cfgfile"; exit 1)
+
+  if test x"$xsi_shell" = xyes; then
+  sed -e '/^func_dirname ()$/,/^} # func_dirname /c\
+func_dirname ()\
+{\
+\    case ${1} in\
+\      */*) func_dirname_result="${1%/*}${2}" ;;\
+\      *  ) func_dirname_result="${3}" ;;\
+\    esac\
+} # Extended-shell func_dirname implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_basename ()$/,/^} # func_basename /c\
+func_basename ()\
+{\
+\    func_basename_result="${1##*/}"\
+} # Extended-shell func_basename implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_dirname_and_basename ()$/,/^} # func_dirname_and_basename /c\
+func_dirname_and_basename ()\
+{\
+\    case ${1} in\
+\      */*) func_dirname_result="${1%/*}${2}" ;;\
+\      *  ) func_dirname_result="${3}" ;;\
+\    esac\
+\    func_basename_result="${1##*/}"\
+} # Extended-shell func_dirname_and_basename implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_stripname ()$/,/^} # func_stripname /c\
+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}"}\
+} # Extended-shell func_stripname implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_split_long_opt ()$/,/^} # func_split_long_opt /c\
+func_split_long_opt ()\
+{\
+\    func_split_long_opt_name=${1%%=*}\
+\    func_split_long_opt_arg=${1#*=}\
+} # Extended-shell func_split_long_opt implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_split_short_opt ()$/,/^} # func_split_short_opt /c\
+func_split_short_opt ()\
+{\
+\    func_split_short_opt_arg=${1#??}\
+\    func_split_short_opt_name=${1%"$func_split_short_opt_arg"}\
+} # Extended-shell func_split_short_opt implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_lo2o ()$/,/^} # func_lo2o /c\
+func_lo2o ()\
+{\
+\    case ${1} in\
+\      *.lo) func_lo2o_result=${1%.lo}.${objext} ;;\
+\      *)    func_lo2o_result=${1} ;;\
+\    esac\
+} # Extended-shell func_lo2o implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_xform ()$/,/^} # func_xform /c\
+func_xform ()\
+{\
+    func_xform_result=${1%.*}.lo\
+} # Extended-shell func_xform implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_arith ()$/,/^} # func_arith /c\
+func_arith ()\
+{\
+    func_arith_result=$(( $* ))\
+} # Extended-shell func_arith implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_len ()$/,/^} # func_len /c\
+func_len ()\
+{\
+    func_len_result=${#1}\
+} # Extended-shell func_len implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+fi
+
+if test x"$lt_shell_append" = xyes; then
+  sed -e '/^func_append ()$/,/^} # func_append /c\
+func_append ()\
+{\
+    eval "${1}+=\\${2}"\
+} # Extended-shell func_append implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_append_quoted ()$/,/^} # func_append_quoted /c\
+func_append_quoted ()\
+{\
+\    func_quote_for_eval "${2}"\
+\    eval "${1}+=\\\\ \\$func_quote_for_eval_result"\
+} # Extended-shell func_append_quoted implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  # Save a `func_append' function call where possible by direct use of '+='
+  sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \
+    && mv -f "$cfgfile.tmp" "$cfgfile" \
+      || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+  test 0 -eq $? || _lt_function_replace_fail=:
+else
+  # Save a `func_append' function call even when '+=' is not available
+  sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \
+    && mv -f "$cfgfile.tmp" "$cfgfile" \
+      || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+  test 0 -eq $? || _lt_function_replace_fail=:
+fi
+
+if test x"$_lt_function_replace_fail" = x":"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to substitute extended shell functions in $ofile" >&5
+$as_echo "$as_me: WARNING: Unable to substitute extended shell functions in $ofile" >&2;}
+fi
+
+
+   mv -f "$cfgfile" "$ofile" ||
+    (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
+  chmod +x "$ofile"
+
+
+    cat <<_LT_EOF >> "$ofile"
+
+# ### BEGIN LIBTOOL TAG CONFIG: CXX
+
+# The linker used to build libraries.
+LD=$lt_LD_CXX
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag_CXX
+reload_cmds=$lt_reload_cmds_CXX
+
+# Commands used to build an old-style archive.
+old_archive_cmds=$lt_old_archive_cmds_CXX
+
+# A language specific compiler.
+CC=$lt_compiler_CXX
+
+# Is the compiler the GNU compiler?
+with_gcc=$GCC_CXX
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_CXX
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_lt_prog_compiler_pic_CXX
+
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl_CXX
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_lt_prog_compiler_static_CXX
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_lt_cv_prog_compiler_c_o_CXX
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$archive_cmds_need_lc_CXX
+
+# Whether or not to disallow shared libs when runtime libs are static.
+allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_CXX
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_CXX
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_whole_archive_flag_spec_CXX
+
+# Whether the compiler copes with passing no objects directly.
+compiler_needs_object=$lt_compiler_needs_object_CXX
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_CXX
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_CXX
+
+# Commands used to build a shared archive.
+archive_cmds=$lt_archive_cmds_CXX
+archive_expsym_cmds=$lt_archive_expsym_cmds_CXX
+
+# Commands used to build a loadable module if different from building
+# a shared archive.
+module_cmds=$lt_module_cmds_CXX
+module_expsym_cmds=$lt_module_expsym_cmds_CXX
+
+# Whether we are building with GNU ld or not.
+with_gnu_ld=$lt_with_gnu_ld_CXX
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_allow_undefined_flag_CXX
+
+# Flag that enforces no undefined symbols.
+no_undefined_flag=$lt_no_undefined_flag_CXX
+
+# 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_CXX
+
+# Whether we need a single "-rpath" flag with a separated argument.
+hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX
+
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
+# DIR into the resulting binary.
+hardcode_direct=$hardcode_direct_CXX
+
+# 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_CXX
+
+# Set to "yes" if using the -LDIR flag during linking hardcodes DIR
+# into the resulting binary.
+hardcode_minus_L=$hardcode_minus_L_CXX
+
+# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
+# into the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var_CXX
+
+# 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_CXX
+
+# Set to yes if linker adds runtime paths of dependent libraries
+# to runtime path list.
+inherit_rpath=$inherit_rpath_CXX
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$link_all_deplibs_CXX
+
+# Set to "yes" if exported symbols are required.
+always_export_symbols=$always_export_symbols_CXX
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_export_symbols_cmds_CXX
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_exclude_expsyms_CXX
+
+# Symbols that must always be exported.
+include_expsyms=$lt_include_expsyms_CXX
+
+# Commands necessary for linking programs (against libraries) with templates.
+prelink_cmds=$lt_prelink_cmds_CXX
+
+# Commands necessary for finishing linking programs.
+postlink_cmds=$lt_postlink_cmds_CXX
+
+# Specify filename containing input files.
+file_list_spec=$lt_file_list_spec_CXX
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action_CXX
+
+# The directories searched by this compiler when creating a shared library.
+compiler_lib_search_dirs=$lt_compiler_lib_search_dirs_CXX
+
+# Dependencies to place before and after the objects being linked to
+# create a shared library.
+predep_objects=$lt_predep_objects_CXX
+postdep_objects=$lt_postdep_objects_CXX
+predeps=$lt_predeps_CXX
+postdeps=$lt_postdeps_CXX
+
+# The library search path used internally by the compiler when linking
+# a shared library.
+compiler_lib_search_path=$lt_compiler_lib_search_path_CXX
+
+# ### END LIBTOOL TAG CONFIG: CXX
+_LT_EOF
+
+ ;;
+
+  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 1
+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/gfanlib/configure.ac b/gfanlib/configure.ac
new file mode 100755
index 0000000..11e8648
--- /dev/null
+++ b/gfanlib/configure.ac
@@ -0,0 +1,53 @@
+#                                               -*- Autoconf -*-
+# Process this file with autoconf to produce a configure script.
+
+AC_PREREQ([2.63])
+AC_INIT([libgfan], [0.1], [ren at mathematik.uni-kl.de])
+AC_CONFIG_MACRO_DIR([../m4])
+AC_CONFIG_AUX_DIR([../build-aux])
+AC_CONFIG_SRCDIR([gfanlib.h])
+AC_CONFIG_HEADER([_config.h])
+
+AM_INIT_AUTOMAKE([-Wall foreign subdir-objects]) # -Wno-extra-portability -Werror silent-rules
+m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
+m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
+
+# Add pre'prefixed config
+AX_PREFIX_CONFIG_H([config.h],[],[_config.h])
+
+AM_MAINTAINER_MODE([enable])
+
+SING_RESET_FLAGS()
+SING_CHECK_SET_ARGS()
+
+# Checks for programs.
+# AC_PROG_CC
+# AC_PROG_CXX
+AC_PROG_LN_S
+#AC_PROG_INSTALL
+
+# Checks for libraries.
+LT_INIT
+
+# Checks for header files.
+AC_HEADER_STDC
+
+# Checks for typedefs, structures, and compiler characteristics.
+AC_C_INLINE
+
+LB_CHECK_GMP(4.0,,AC_MSG_ERROR([Unable to find GMP on your machine: please use --with-gmp=PATH_TO_DIR_CONTAINING_LIB_AND_INCLUDE (see also ./configure --help if you do not understand what we are talking about)]))
+
+SING_CHECK_GFANLIB
+
+#AC_MSG_RESULT($ac_cv_singuname)
+#if test "$ac_cv_singuname" = unknown; then
+#  AC_MSG_WARN(Unknown architecture: Check singuname.sh)
+#  ac_cv_singuname="unknown"
+#fi
+#AC_DEFINE_UNQUOTED(S_UNAME, "$ac_cv_singuname")
+#SINGUNAME=$ac_cv_singuname
+#AC_SUBST(SINGUNAME)
+
+AC_CONFIG_FILES([Makefile])
+## AC_CONFIG_HEADERS([config.h])
+AC_OUTPUT
diff --git a/gfanlib/gfanlib.h b/gfanlib/gfanlib.h
new file mode 100644
index 0000000..c225bed
--- /dev/null
+++ b/gfanlib/gfanlib.h
@@ -0,0 +1,19 @@
+/*
+ * gfanlib.h
+ *
+ *  Created on: Sep 28, 2010
+ *      Author: anders
+ */
+
+#ifndef GFANLIB_H_
+#define GFANLIB_H_
+
+#include "gfanlib_z.h"
+#include "gfanlib_vector.h"
+#include "gfanlib_matrix.h"
+#include "gfanlib_zcone.h"
+#include "gfanlib_symmetry.h"
+#include "gfanlib_polyhedralfan.h"
+#include "gfanlib_zfan.h"
+
+#endif /* GFANLIB_H_ */
diff --git a/gfanlib/gfanlib_matrix.h b/gfanlib/gfanlib_matrix.h
new file mode 100644
index 0000000..7a315f2
--- /dev/null
+++ b/gfanlib/gfanlib_matrix.h
@@ -0,0 +1,646 @@
+/*
+ * lib_zmatrix.h
+ *
+ *  Created on: Sep 28, 2010
+ *      Author: anders
+ */
+
+#ifndef LIB_ZMATRIX_H_
+#define LIB_ZMATRIX_H_
+
+#include <vector>
+#include <algorithm>
+#include "gfanlib_vector.h"
+
+namespace gfan{
+
+template <class typ> class Matrix{
+  int width,height;
+  std::vector<Vector<typ> > rows;
+public:
+  inline int getHeight()const{return height;};
+  inline int getWidth()const{return width;};
+  Matrix(const Matrix &a):width(a.getWidth()),height(a.getHeight()),rows(a.rows){
+  }
+  Matrix(int height_, int width_):width(width_),height(height_),rows(height_){
+    assert(height>=0);
+    assert(width>=0);
+    for(int i=0;i<getHeight();i++)rows[i]=Vector<typ>(width);
+  };
+  ~Matrix(){
+  };
+  Matrix():width(0),height(0){
+  };
+  static Matrix rowVectorMatrix(Vector<typ> const &v)
+  {
+    Matrix ret(1,v.size());
+    for(int i=0;i<v.size();i++)ret[0][i]=v[i];
+    return ret;
+  }
+  Vector<typ> column(int i)const
+    {
+      assert(i>=0);
+      assert(i<getWidth());
+      Vector<typ> ret(getHeight());
+      for(int j=0;j<getHeight();j++)ret[j]=rows[j][i];
+      return ret;
+    }
+  Matrix transposed()const
+    {
+      Matrix ret(getWidth(),getHeight());
+      for(int i=0;i<getWidth();i++)
+        ret.rows[i]=column(i);
+      return ret;
+    }
+  static Matrix identity(int n)
+    {
+      Matrix m(n,n);
+      for(int i=0;i<n;i++)m.rows[i]=Vector<typ>::standardVector(n,i);
+      return m;
+    }
+  void append(Matrix const &m)
+    {
+      for(int i=0;i<m.height;i++)
+        {
+          rows.push_back(m[i]);
+        }
+      height+=m.height;
+    }
+  void appendRow(Vector<typ> const &v)
+    {
+      assert((int)v.size()==width);
+      rows.push_back(v);
+      height++;
+    }
+  void eraseLastRow()
+  {
+    assert(rows.size()>0);
+    rows.resize(rows.size()-1);
+    height--;
+  }
+  /*IntegerVector vectormultiply(IntegerVector const &v)const
+    {
+      assert(v.size()==width);
+      IntegerVector ret(height);
+      for(int i=0;i<height;i++)
+        ret[i]=dot(rows[i],v);
+      return ret;
+    }*/
+  /**
+   * Decides if v is in the kernel of the matrix.
+   */
+/*  bool inKernel(IntegerVector const &v)const
+    {
+      assert(v.size()==width);
+      for(int i=0;i<height;i++)
+          if(dotLong(rows[i],v)!=0)return false;
+      return true;
+    }
+*/
+  friend Matrix operator*(const typ &s, const Matrix& q)
+    {
+      Matrix p=q;
+      for(int i=0;i<q.height;i++)p[i]=s*(q[i]);
+      return p;
+    }
+  friend Matrix operator*(const Matrix& a, const Matrix& b)
+    {
+      assert(a.width==b.height);
+      Matrix ret(b.width,a.height);
+      for(int i=0;i<b.width;i++)
+        ret[i]=a.vectormultiply(b.column(i));
+      return ret.transposed();
+    }
+  /*  template<class T>
+    Matrix<T>(const Matrix<T>& c):v(c.size()){
+    for(int i=0;i<size();i++)v[i]=typ(c[i]);}
+  */
+  friend Matrix operator-(const Matrix &b)
+  {
+    Matrix ret(b.height,b.width);
+    for(int i=0;i<b.height;i++)ret[i]=-b[i];
+    return ret;
+  }
+
+  /**
+     Returns the specified submatrix. The endRow and endColumn are not included.
+   */
+  Matrix submatrix(int startRow, int startColumn, int endRow, int endColumn)const
+  {
+    assert(startRow>=0);
+    assert(startColumn>=0);
+    assert(endRow>=startRow);
+    assert(endColumn>=startColumn);
+    assert(endRow<=height);
+    assert(endColumn<=width);
+    Matrix ret(endRow-startRow,endColumn-startColumn);
+    for(int i=startRow;i<endRow;i++)
+      for(int j=startColumn;j<endColumn;j++)
+        ret[i-startRow][j-startColumn]=rows[i][j];
+    return ret;
+  }
+  const Vector<typ>& operator[](int n)const{assert(n>=0 && n<getHeight());return (rows[n]);}
+// Bugfix for gcc4.5 (passing assertion to the above operator):
+  Vector<typ>& operator[](int n){if(!(n>=0 && n<getHeight())){(*(const Matrix<typ>*)(this))[n];}return (rows[n]);}
+
+
+  bool operator<(const Matrix & b)const
+  {
+    if(getWidth()<b.getWidth())return true;
+    if(b.getWidth()<getWidth())return false;
+    if(getHeight()<b.getHeight())return true;
+    if(b.getHeight()<getHeight())return false;
+
+    for(int i=0;i<getHeight();i++)
+      {
+        if((*this)[i]<b[i])return true;
+        if(b[i]<(*this)[i])return false;
+      }
+    return false;
+  }
+  /**
+     Adds a times the i th row to the j th row.
+  */
+  void madd(int i, typ a, int j)
+  {
+    assert(i!=j);
+    assert(i>=0 && i<height);
+    assert(j>=0 && j<height);
+
+    if(!a.isZero())
+    for(int k=0;k<width;k++)
+      if(!rows[i][k].isZero())
+        rows[j][k].madd(rows[i][k],a);
+  }
+
+  friend std::ostream &operator<<(std::ostream &f, Matrix const &a){
+    f<<"{";
+    for(int i=0;i<a.getHeight();i++)
+      {
+        if(i)f<<","<<std::endl;
+        f<<a.rows[i];
+      }
+    f<<"}"<<std::endl;
+    return f;
+  }
+  /**
+     Swaps the i th and the j th row.
+   */
+  void swapRows(int i, int j)
+  {
+    std::swap(rows[i],rows[j]);
+  }
+  /**
+     This method is used for iterating through the pivots in a matrix
+     in row echelon form. To find the first pivot put i=-1 and
+     j=-1 and call this routine. The (i,j) th entry of the matrix is a
+     pivot. Call the routine again to get the next pivot. When no more
+     pivots are found the routine returns false.
+  */
+  bool nextPivot(int &i, int &j)const
+  {
+    i++;
+    if(i>=height)return false;
+    while(++j<width)
+      {
+        if(!rows[i][j].isZero()) return true;
+      }
+    return false;
+  }
+  /**
+     Returns the indices of the columns containing a pivot.
+     The returned list is sorted.
+     The matrix must be in row echelon form.
+   */
+  std::vector<int> pivotColumns()const
+  {
+    std::vector<int> ret;
+    int pivotI=-1;
+    int pivotJ=-1;
+    while(nextPivot(pivotI,pivotJ))ret.push_back(pivotJ);
+    return ret;
+  }
+  /**
+     Returns the indices of the columns not containing a pivot.
+     The returned list is sorted.
+     The matrix must be in row echelon form.
+   */
+  std::vector<int> nonPivotColumns()const
+  {
+    std::vector<int> ret;
+    int pivotI=-1;
+    int pivotJ=-1;
+    int firstPossiblePivot=0;
+    while(nextPivot(pivotI,pivotJ))
+      {
+        for(int j=firstPossiblePivot;j<pivotJ;j++)
+          ret.push_back(j);
+        firstPossiblePivot=pivotJ+1;
+      }
+    for(int j=firstPossiblePivot;j<getWidth();j++)
+      ret.push_back(j);
+
+    return ret;
+  }
+  /**
+     This routine removes the zero rows of the matrix.
+   */
+  void removeZeroRows()
+  {
+    int nonZeros=0;
+    for(int i=0;i<height;i++)if(!(*this)[i].isZero())nonZeros++;
+    if(nonZeros==height)return;
+
+    Matrix b(nonZeros,width);
+
+    int j=0;
+    for(int i=0;i<height;i++)
+      {
+        if(!(*this)[i].isZero())
+          {
+            b[j]=(*this)[i];
+            j++;
+          }
+      }
+    *this=b;
+  }
+  /**
+     Returns the index of a row whose index is at least currentRow and
+     which has a non-zero element on the column th entry. If no such
+     row exists then -1 is returned. This routine is used in the Gauss
+     reduction. To make the reduction more efficient the routine
+     chooses its row with as few non-zero entries as possible.
+   */
+  int findRowIndex(int column, int currentRow)const
+  {
+    int best=-1;
+    int bestNumberOfNonZero=0;
+    for(int i=currentRow;i<height;i++)
+      if(!rows[i][column].isZero())
+        {
+          int nz=0;
+          for(int k=column+1;k<width;k++)
+            if(!rows[i][k].isZero())nz++;
+          if(best==-1)
+            {
+              best=i;
+              bestNumberOfNonZero=nz;
+            }
+          else if(nz<bestNumberOfNonZero)
+            {
+              best=i;
+              bestNumberOfNonZero=nz;
+            }
+        }
+    return best;
+  }
+  /**
+     Performs a Gauss reduction and returns the number of row swaps
+     done.  The result is a matrix in row echelon form. The pivots may
+     not be all 1.  In terms of Groebner bases, what is computed is a
+     minimal (not necessarily reduced) Groebner basis of the linear
+     ideal generated by the rows.  The number of swaps is need if one
+     wants to compute the determinant afterwards. In this case it is
+     also a good idea to set the flag returnIfZeroDeterminant which
+     make the routine terminate before completion if it discovers that
+     the determinant is zero.
+  */
+  int reduce(bool returnIfZeroDeterminant=false, bool integral=false, bool makePivotsOne=false)
+  {
+    assert(integral || typ::isField());
+    int retSwaps=0;
+    int currentRow=0;
+
+    for(int i=0;i<width;i++)
+      {
+        int s=findRowIndex(i,currentRow);
+
+        if(s!=-1)
+          {
+            if(s!=currentRow)
+              {
+                swapRows(currentRow,s);
+                retSwaps++;
+              }
+            if(makePivotsOne)
+              {//THE PIVOT SHOULD BE SET TO ONE IF INTEGRAL IS FALSE
+                if(rows[currentRow][i].sign()>=0)
+                  retSwaps++;
+                typ inverse=typ(1)/rows[currentRow][i];
+                //                if(!rows[currentRow][i].isOne())
+                  {
+                    for(int k=0;k<width;k++)
+                      if(!rows[currentRow][k].isZero())
+                        rows[currentRow][k]*=inverse;
+                  }
+              }
+            for(int j=currentRow+1;j<height;j++)
+              if(integral)
+                {
+                  if(!rows[j][i].isZero())
+                    {
+                      typ s;
+                      typ t;
+
+                      typ g=typ::gcd(rows[currentRow][i],rows[j][i],s,t);
+                      typ u=-rows[j][i]/g;
+                      typ v=rows[currentRow][i]/g;
+                        /* We want the (s,t) vector to be as small as possible.
+                         * We are allowed to adjust by multiples of (u,v).
+                         * The following computes the correct multiplier (in most cases).
+                         */
+/*                        {
+                          FieldElement multiplier=(s*u+t*v)*((u*u+v*v).inverse());
+                          double d=mpq_get_d(*(multiplier.getGmpRationalTemporaryPointer()));
+                          multiplier=multiplier.getField()->zHomomorphism(-(((int)(d+10000.5))-10000));
+                          s.madd(multiplier,u);
+                          t.madd(multiplier,v);
+                        }*/
+                        for(int k=0;k<width;k++)
+                          {
+                            typ A=rows[currentRow][k];
+                            typ B=rows[j][k];
+
+                            rows[currentRow][k]=s*A+t*B;
+                            rows[j][k]=u*A+v*B;
+                          }
+                      }
+                  }
+                else
+                  {
+                    if(!rows[j][i].isZero())
+                      madd(currentRow,-rows[j][i]/rows[currentRow][i],j);
+                  }
+              currentRow++;
+            }
+          else
+            if(returnIfZeroDeterminant)return -1;
+        }
+
+      return retSwaps;
+    }
+  /**
+     Computes a reduced row echelon form from a row echelon form. In
+     Groebner basis terms this is the same as tranforming a minimal
+     Groebner basis to a reduced one except that we do not force
+     pivots to be 1 unless the scalePivotsToOne parameter is set.
+   */
+  int REformToRREform(bool scalePivotsToOne=false)
+  {
+    int ret=0;
+    int pivotI=-1;
+    int pivotJ=-1;
+    while(nextPivot(pivotI,pivotJ))
+      {
+        if(scalePivotsToOne)
+          rows[pivotI]=rows[pivotI]/rows[pivotI][pivotJ];
+        for(int i=0;i<pivotI;i++)
+          if(!rows[i][pivotJ].isZero())
+            madd(pivotI,-rows[i][pivotJ]/rows[pivotI][pivotJ],i);
+      }
+    return ret;
+  }
+  /**
+     This function may be called if the FieldMatrix is in Row Echelon
+     Form. The input is a FieldVector which is rewritten modulo the
+     rows of the matrix. The result is unique and is the same as the
+     normal form of the input vector modulo the Groebner basis of the
+     linear ideal generated by the rows of the matrix.
+  */
+  Vector<typ> canonicalize(Vector<typ> v)const
+  {
+    assert(typ::isField());
+    assert((int)v.size()==getWidth());
+
+    int pivotI=-1;
+    int pivotJ=-1;
+
+    while(nextPivot(pivotI,pivotJ))
+      if(!v[pivotJ].isZero())
+      {
+        typ s=-v[pivotJ]/rows[pivotI][pivotJ];
+
+        for(int k=0;k<width;k++)
+          if(!rows[pivotI][k].isZero())
+            v[k].madd(rows[pivotI][k],s);
+      }
+    return v;
+  }
+  /**
+     Calls reduce() and constructs matrix whose rows forms a basis of
+     the kernel of the linear map defined by the original matrix. The
+     return value is the new matrix.
+   */
+  Matrix reduceAndComputeKernel()
+  {
+    Matrix ret(width-reduceAndComputeRank(),width);
+
+    REformToRREform();
+
+    int k=0;
+    int pivotI=-1;
+    int pivotJ=-1;
+    bool pivotExists=nextPivot(pivotI,pivotJ);
+    for(int j=0;j<width;j++)
+      {
+        if(pivotExists && (pivotJ==j))
+          {
+            pivotExists=nextPivot(pivotI,pivotJ);
+            continue;
+          }
+        int pivot2I=-1;
+        int pivot2J=-1;
+        while(nextPivot(pivot2I,pivot2J))
+          {
+            ret[k][pivot2J]=rows[pivot2I][j]/rows[pivot2I][pivot2J];
+          }
+        ret[k][j]=typ(-1);
+        k++;
+      }
+    return ret;
+  }
+  /**
+     Assumes that the matrix has a kernel of dimension 1.
+     Calls reduce() and returns a non-zero vector in the kernel.
+     If the matrix is an (n-1)x(n) matrix then the returned vector has
+     the property that if it was appended as a row to the original matrix
+     then the determinant of that matrix would be positive. Of course
+     this property, as described here, only makes sense for ordered fields.
+     Only allowed for fields at the moment.
+   */
+  Vector<typ> reduceAndComputeVectorInKernel()
+  {
+    assert(typ::isField());
+    // TODO: (optimization) if the field is ordered, then it is better to just keep track of signs rather than
+    // multiplying by sign*diagonalProduct*lastEntry at the end.
+    int nswaps=this->reduce();
+    typ sign=typ(1-2*(nswaps&1));
+    int rank=reduceAndComputeRank();
+    assert(rank+1==width);
+
+    REformToRREform();
+
+    Vector<typ> ret(width);
+
+    typ diagonalProduct(1);
+    {
+      int pivot2I=-1;
+      int pivot2J=-1;
+      while(nextPivot(pivot2I,pivot2J))
+        {
+          diagonalProduct*=rows[pivot2I][pivot2J];
+        }
+    }
+    {
+      int j=nonPivotColumns().front();
+      int pivot2I=-1;
+      int pivot2J=-1;
+      ret[j]=typ(-1);
+      // Pretend that we are appending ret to the matrix, and reducing this
+      // new row by the previous ones. The last entry of the resulting matrix
+      // is lastEntry.
+      typ lastEntry=ret[j];
+      while(nextPivot(pivot2I,pivot2J))
+        {
+          ret[pivot2J]=rows[pivot2I][j]/rows[pivot2I][pivot2J];
+          lastEntry-=ret[pivot2J]*ret[pivot2J];
+        }
+      ret=(sign*(diagonalProduct*lastEntry))*ret;
+    }
+
+    return ret;
+  }
+
+  /**
+     Calls reduce() and returns the rank of the matrix.
+   */
+  int reduceAndComputeRank()
+  {
+    if (typ::isField())
+      reduce();
+    else
+      reduce(false,true,false);
+    int ret=0;
+    int pivotI=-1;
+    int pivotJ=-1;
+    while(nextPivot(pivotI,pivotJ))ret++;
+    return ret;
+  }
+  /**
+   * Sort the rows of the matrix.
+   */
+  void sortRows()
+  {
+    std::sort(rows.begin(),rows.end());
+  }
+  /**
+   * Sort the rows of the matrix and remove duplicate rows.
+   */
+  void sortAndRemoveDuplicateRows()
+  {
+    sortRows();
+    if(getHeight()==0)return;
+    Matrix B(0,getWidth());
+    B.appendRow((*this)[0]);
+    for(int i=1;i<getHeight();i++)
+      if(rows[i]!=rows[i-1])B.appendRow((*this)[i]);
+    *this=B;
+  }
+  /**
+     Takes two matrices with the same number of columns and construct
+     a new matrix which has the rows of the matrix top on the top and
+     the rows of the matrix bottom at the bottom. The return value is
+     the constructed matrix.
+   */
+  friend Matrix combineOnTop(Matrix const &top, Matrix const &bottom)
+  {
+    assert(bottom.getWidth()==top.getWidth());
+    Matrix ret(top.getHeight()+bottom.getHeight(),top.getWidth());
+    for(int i=0;i<top.getHeight();i++)ret.rows[i]=top.rows[i];
+    for(int i=0;i<bottom.getHeight();i++)ret.rows[i+top.getHeight()]=bottom.rows[i];
+
+    return ret;
+  }
+  /**
+     Takes two matrices with the same number of rows and construct
+     a new matrix which has the columns of the matrix left on the left and
+     the columns of the matrix right on the right. The return value is
+     the constructed matrix.
+   */
+  friend Matrix combineLeftRight(Matrix const &left, Matrix const &right)
+  {
+    assert(left.getHeight()==right.getHeight());
+    Matrix ret(left.getHeight(),left.getWidth()+right.getWidth());
+    for(int i=0;i<left.getHeight();i++)
+      {
+        for(int j=0;j<left.getWidth();j++)ret.rows[i][j]=left.rows[i][j];
+        for(int j=0;j<right.getWidth();j++)ret.rows[i][j+left.getWidth()]=right.rows[i][j];
+      }
+    return ret;
+  }
+};
+
+typedef Matrix<Integer> ZMatrix;
+typedef Matrix<Rational> QMatrix;
+typedef Matrix<int> IntMatrix;
+
+inline QMatrix ZToQMatrix(ZMatrix const &m)
+{
+  QMatrix ret(m.getHeight(),m.getWidth());
+  for(int i=0;i<m.getHeight();i++)ret[i]=ZToQVector(m[i]);
+  return ret;
+}
+
+inline ZMatrix QToZMatrixPrimitive(QMatrix const &m)
+{
+  ZMatrix ret(m.getHeight(),m.getWidth());
+  for(int i=0;i<m.getHeight();i++)ret[i]=QToZVectorPrimitive(m[i]);
+  return ret;
+}
+
+
+inline IntMatrix ZToIntMatrix(ZMatrix const &m)
+{
+  IntMatrix ret(m.getHeight(),m.getWidth());
+  for(int i=0;i<m.getHeight();i++)ret[i]=ZToIntVector(m[i]);
+  return ret;
+}
+
+
+inline ZMatrix IntToZMatrix(IntMatrix const &m)
+{
+  ZMatrix ret(m.getHeight(),m.getWidth());
+  for(int i=0;i<m.getHeight();i++)ret[i]=IntToZVector(m[i]);
+  return ret;
+}
+
+inline QMatrix canonicalizeSubspace(QMatrix const &m)
+{
+  QMatrix temp=m;
+  temp.reduce();
+  temp.REformToRREform();
+  temp.removeZeroRows();
+  return temp;
+}
+
+inline ZMatrix canonicalizeSubspace(ZMatrix const &m)
+{
+  return QToZMatrixPrimitive(canonicalizeSubspace(ZToQMatrix(m)));
+}
+
+
+inline QMatrix kernel(QMatrix const &m)
+{
+  QMatrix temp=m;
+  return temp.reduceAndComputeKernel();
+}
+
+inline ZMatrix kernel(ZMatrix const &m)
+{
+  return QToZMatrixPrimitive(kernel(ZToQMatrix(m)));
+}
+
+}
+
+
+#endif /* LIB_ZMATRIX_H_ */
diff --git a/gfanlib/gfanlib_polyhedralfan.cpp b/gfanlib/gfanlib_polyhedralfan.cpp
new file mode 100644
index 0000000..3c28bf4
--- /dev/null
+++ b/gfanlib/gfanlib_polyhedralfan.cpp
@@ -0,0 +1,895 @@
+/*
+ * gfanlib_polyhedralfan.cpp
+ *
+ *  Created on: Nov 16, 2010
+ *      Author: anders
+ */
+
+#include <sstream>
+#include "gfanlib_polyhedralfan.h"
+#include "gfanlib_polymakefile.h"
+
+using namespace std;
+namespace gfan{
+
+PolyhedralFan::PolyhedralFan(int ambientDimension):
+  n(ambientDimension),
+  symmetries(n)
+{
+}
+
+PolyhedralFan::PolyhedralFan(SymmetryGroup const &sym):
+  n(sym.sizeOfBaseSet()),
+  symmetries(sym)
+{
+
+}
+
+PolyhedralFan PolyhedralFan::fullSpace(int n)
+{
+  PolyhedralFan ret(n);
+
+  ZCone temp(n);
+  temp.canonicalize();
+  ret.cones.insert(temp);
+
+  return ret;
+}
+
+
+PolyhedralFan PolyhedralFan::facetsOfCone(ZCone const &c)
+{
+  ZCone C(c);
+  C.canonicalize();
+  PolyhedralFan ret(C.ambientDimension());
+
+  ZMatrix halfSpaces=C.getFacets();
+
+  for(int i=0;i<halfSpaces.getHeight();i++)
+    {
+      ZMatrix a(0,C.ambientDimension());
+      ZMatrix b(0,C.ambientDimension());
+      b.appendRow(halfSpaces[i]);
+      ZCone N=intersection(ZCone(a,b),c);
+      N.canonicalize();
+      ret.cones.insert(N);
+    }
+  return ret;
+}
+
+
+int PolyhedralFan::getAmbientDimension()const
+{
+  return n;
+}
+
+bool PolyhedralFan::isEmpty()const
+{
+  return cones.empty();
+}
+
+int PolyhedralFan::getMaxDimension()const
+{
+  assert(!cones.empty());
+
+  return cones.begin()->dimension();
+}
+
+int PolyhedralFan::getMinDimension()const
+{
+  assert(!cones.empty());
+
+  return cones.rbegin()->dimension();
+}
+
+/*
+PolyhedralFan refinement(const PolyhedralFan &a, const PolyhedralFan &b, int cutOffDimension, bool allowASingleConeOfCutOffDimension)
+{
+  //  fprintf(Stderr,"PolyhedralFan refinement: #A=%i #B=%i\n",a.cones.size(),b.cones.size());
+  int conesSkipped=0;
+  int numberOfComputedCones=0;
+  bool linealityConeFound=!allowASingleConeOfCutOffDimension;
+  assert(a.getAmbientDimension()==b.getAmbientDimension());
+
+  PolyhedralFan ret(a.getAmbientDimension());
+
+  for(PolyhedralConeList::const_iterator A=a.cones.begin();A!=a.cones.end();A++)
+    for(PolyhedralConeList::const_iterator B=b.cones.begin();B!=b.cones.end();B++)
+      {
+        PolyhedralCone c=intersection(*A,*B);
+        int cdim=c.dimension();
+        //      assert(cdim>=linealitySpaceDimension);
+        bool thisIsLinealityCone=(cutOffDimension>=cdim);
+        if((!thisIsLinealityCone)||(!linealityConeFound))
+          {
+            numberOfComputedCones++;
+            c.canonicalize();
+            ret.cones.insert(c);
+            linealityConeFound=linealityConeFound || thisIsLinealityCone;
+          }
+        else
+          {
+            conesSkipped++;
+          }
+      }
+  //  fprintf(Stderr,"Number of skipped cones: %i, lineality cone found: %i\n",conesSkipped,linealityConeFound);
+  //  fprintf(Stderr,"Number of computed cones: %i, number of unique cones: %i\n",numberOfComputedCones,ret.cones.size());
+
+  return ret;
+}
+*/
+
+/*
+PolyhedralFan product(const PolyhedralFan &a, const PolyhedralFan &b)
+{
+  PolyhedralFan ret(a.getAmbientDimension()+b.getAmbientDimension());
+
+  for(PolyhedralConeList::const_iterator A=a.cones.begin();A!=a.cones.end();A++)
+    for(PolyhedralConeList::const_iterator B=b.cones.begin();B!=b.cones.end();B++)
+      ret.insert(product(*A,*B));
+
+  return ret;
+}
+*/
+
+/*IntegerVectorList PolyhedralFan::getRays(int dim)
+{
+  IntegerVectorList ret;
+  for(PolyhedralConeList::iterator i=cones.begin();i!=cones.end();i++)
+    {
+      if(i->dimension()==dim)
+        ret.push_back(i->getRelativeInteriorPoint());
+    }
+  return ret;
+}
+*/
+
+/*IntegerVectorList PolyhedralFan::getRelativeInteriorPoints()
+{
+  IntegerVectorList ret;
+  for(PolyhedralConeList::iterator i=cones.begin();i!=cones.end();i++)
+    {
+      ret.push_back(i->getRelativeInteriorPoint());
+    }
+  return ret;
+}
+*/
+
+/*PolyhedralCone const& PolyhedralFan::highestDimensionalCone()const
+{
+  return *cones.rbegin();
+}
+*/
+void PolyhedralFan::insert(ZCone const &c)
+{
+  ZCone temp=c;
+  temp.canonicalize();
+  cones.insert(temp);
+}
+
+void PolyhedralFan::remove(ZCone const &c)
+{
+  cones.erase(c);
+}
+
+/*
+void PolyhedralFan::removeAllExcept(int a)
+{
+  PolyhedralConeList::iterator i=cones.begin();
+  while(a>0)
+    {
+      if(i==cones.end())return;
+      i++;
+      a--;
+    }
+  cones.erase(i,cones.end());
+}
+*/
+
+void PolyhedralFan::removeAllLowerDimensional()
+{
+  if(!cones.empty())
+    {
+      int d=getMaxDimension();
+      PolyhedralConeList::iterator i=cones.begin();
+      while(i!=cones.end() && i->dimension()==d)i++;
+      cones.erase(i,cones.end());
+    }
+}
+
+
+PolyhedralFan PolyhedralFan::facetComplex()const
+{
+  //  fprintf(Stderr,"Computing facet complex...\n");
+  PolyhedralFan ret(n);
+
+  for(PolyhedralConeList::iterator i=cones.begin();i!=cones.end();i++)
+    {
+      PolyhedralFan a=facetsOfCone(*i);
+      for(PolyhedralConeList::const_iterator j=a.cones.begin();j!=a.cones.end();j++)
+        ret.insert(*j);
+    }
+  //  fprintf(Stderr,"Done computing facet complex.\n");
+  return ret;
+}
+
+
+/*
+PolyhedralFan PolyhedralFan::fullComplex()const
+{
+  PolyhedralFan ret=*this;
+
+  while(1)
+    {
+      log2 debug<<"looping";
+      bool doLoop=false;
+      PolyhedralFan facets=ret.facetComplex();
+      log2 debug<<"number of facets"<<facets.size()<<"\n";
+      for(PolyhedralConeList::const_iterator i=facets.cones.begin();i!=facets.cones.end();i++)
+        if(!ret.contains(*i))
+          {
+            ret.insert(*i);
+            doLoop=true;
+          }
+      if(!doLoop)break;
+    }
+  return ret;
+}
+*/
+
+
+#if 0
+PolyhedralFan PolyhedralFan::facetComplexSymmetry(SymmetryGroup const &sym, bool keepRays, bool dropLinealitySpace)const
+{
+  log1 fprintf(Stderr,"Computing facet complex...\n");
+  PolyhedralFan ret(n);
+
+  vector<IntegerVector> relIntTable;
+  vector<int> dimensionTable;
+
+  if(keepRays)
+    for(PolyhedralConeList::iterator i=cones.begin();i!=cones.end();i++)
+      if(i->dimension()==i->dimensionOfLinealitySpace()+1)
+        {
+          relIntTable.push_back(i->getRelativeInteriorPoint());
+          dimensionTable.push_back(i->dimension());
+          ret.insert(*i);
+        }
+
+  for(PolyhedralConeList::iterator i=cones.begin();i!=cones.end();i++)
+    {
+      int iDim=i->dimension();
+      if(dropLinealitySpace && (i->dimension()==i->dimensionOfLinealitySpace()+1))continue;
+
+      //      i->findFacets();
+      IntegerVectorList normals=i->getHalfSpaces();
+      for(IntegerVectorList::const_iterator j=normals.begin();j!=normals.end();j++)
+        {
+          bool alreadyInRet=false;
+          for(int l=0;l<relIntTable.size();l++)
+            {
+              if(dimensionTable[l]==iDim-1)
+                for(SymmetryGroup::ElementContainer::const_iterator k=sym.elements.begin();k!=sym.elements.end();k++)
+                  {
+                    IntegerVector u=SymmetryGroup::compose(*k,relIntTable[l]);
+                    if((dotLong(*j,u)==0) && (i->contains(u)))
+                      {
+                        alreadyInRet=true;
+                        goto exitLoop;
+                      }
+                  }
+            }
+        exitLoop:
+          if(!alreadyInRet)
+            {
+              IntegerVectorList equations=i->getEquations();
+              IntegerVectorList inequalities=i->getHalfSpaces();
+              equations.push_back(*j);
+              PolyhedralCone c(inequalities,equations,n);
+              c.canonicalize();
+              ret.insert(c);
+              relIntTable.push_back(c.getRelativeInteriorPoint());
+              dimensionTable.push_back(c.dimension());
+            }
+        }
+    }
+  log1 fprintf(Stderr,"Done computing facet complex.\n");
+  return ret;
+}
+#endif
+
+
+
+ZMatrix PolyhedralFan::getRaysInPrintingOrder(bool upToSymmetry)const
+{
+  /*
+   * The ordering changed in this version. Previously the orbit representatives stored in "rays" were
+   * just the first extreme ray from the orbit that appeared. Now it is gotten using "orbitRepresentative"
+   * which causes the ordering in which the different orbits appear to change.
+   */
+  if(cones.empty())return ZMatrix(0,n);
+ZMatrix generatorsOfLinealitySpace=cones.begin()->generatorsOfLinealitySpace();//all cones have the same lineality space
+
+
+  std::set<ZVector> rays;//(this->getAmbientDimension());
+//  log1 fprintf(Stderr,"Computing rays of %i cones\n",cones.size());
+  for(PolyhedralConeList::const_iterator i=cones.begin();i!=cones.end();i++)
+    {
+      ZMatrix temp=i->extremeRays(&generatorsOfLinealitySpace);
+ //     std::cerr<<temp;
+      for(int j=0;j<temp.getHeight();j++)
+        rays.insert(symmetries.orbitRepresentative(temp[j]));
+    }
+  ZMatrix ret(0,getAmbientDimension());
+  if(upToSymmetry)
+    for(set<ZVector>::const_iterator i=rays.begin();i!=rays.end();i++)ret.appendRow(*i);
+  else
+    for(set<ZVector>::const_iterator i=rays.begin();i!=rays.end();i++)
+      {
+        set<ZVector> thisOrbitsRays;
+        for(SymmetryGroup::ElementContainer::const_iterator k=symmetries.elements.begin();k!=symmetries.elements.end();k++)
+          {
+            ZVector temp=k->apply(*i);
+            thisOrbitsRays.insert(temp);
+          }
+
+        for(set<ZVector>::const_iterator i=thisOrbitsRays.begin();i!=thisOrbitsRays.end();i++)ret.appendRow(*i);
+      }
+  return ret;
+}
+
+
+
+/*MARKS CONES AS NONMAXIMAL IN THE SYMMETRIC COMPLEX IN WHICH THEY WILL BE INSERTED -not to be confused with the facet testing in the code
+   */
+ static list<SymmetricComplex::Cone> computeFacets(SymmetricComplex::Cone const &theCone, ZMatrix const &rays, ZMatrix const &facetCandidates, SymmetricComplex const &theComplex/*, int linealityDim*/)
+{
+  set<SymmetricComplex::Cone> ret;
+
+  for(int i=0;i<facetCandidates.getHeight();i++)
+    {
+      set<int> indices;
+
+      bool notAll=false;
+      for(unsigned j=0;j<theCone.indices.size();j++)
+        if(dot(rays[theCone.indices[j]],facetCandidates[i]).sign()==0)
+          indices.insert(theCone.indices[j]);
+        else
+          notAll=true;
+
+      SymmetricComplex::Cone temp(indices,theCone.dimension-1,Integer(),false,theComplex);
+      /*      temp.multiplicity=0;
+      temp.dimension=theCone.dimension-1;
+      temp.setIgnoreSymmetry(true);
+      */
+      if(notAll)ret.insert(temp);
+
+    }
+  //  fprintf(Stderr,"HEJ!!!!\n");
+
+  list<SymmetricComplex::Cone> ret2;
+  for(set<SymmetricComplex::Cone>::const_iterator i=ret.begin();i!=ret.end();i++)
+    {
+      bool isMaximal=true;
+
+      /*      if(i->indices.size()+linealityDim<i->dimension)//#3
+        isMaximal=false;
+        else*/
+        for(set<SymmetricComplex::Cone>::const_iterator j=ret.begin();j!=ret.end();j++)
+          if(i!=j && i->isSubsetOf(*j))
+            {
+              isMaximal=false;
+              break;
+            }
+      if(isMaximal)
+        {
+          SymmetricComplex::Cone temp(i->indexSet(),i->dimension,i->multiplicity,true,theComplex);
+          temp.setKnownToBeNonMaximal(); // THIS IS WHERE WE SET THE CONES NON-MAXIMAL FLAG
+          //      temp.setIgnoreSymmetry(false);
+          ret2.push_back(temp);
+        }
+    }
+  return ret2;
+}
+
+void addFacesToSymmetricComplex(SymmetricComplex &c, ZCone const &cone, ZMatrix const &facetCandidates, ZMatrix const &generatorsOfLinealitySpace)
+{
+  // ZMatrix const &rays=c.getVertices();
+  std::set<int> indices;
+
+//  for(int j=0;j<rays.getHeight();j++)if(cone.contains(rays[j]))indices.insert(j);
+
+  ZMatrix l=cone.extremeRays(&generatorsOfLinealitySpace);
+  for(int i=0;i<l.getHeight();i++)indices.insert(c.indexOfVertex(l[i]));
+
+  addFacesToSymmetricComplex(c,indices,facetCandidates,cone.dimension(),cone.getMultiplicity());
+}
+
+void addFacesToSymmetricComplex(SymmetricComplex &c, std::set<int> const &indices, ZMatrix const &facetCandidates, int dimension, Integer multiplicity)
+{
+  ZMatrix const &rays=c.getVertices();
+  list<SymmetricComplex::Cone> clist;
+  {
+    SymmetricComplex::Cone temp(indices,dimension,multiplicity,true,c);
+    //    temp.dimension=cone.dimension();
+    //   temp.multiplicity=cone.getMultiplicity();
+    clist.push_back(temp);
+  }
+
+  //  int linealityDim=cone.dimensionOfLinealitySpace();
+
+  while(!clist.empty())
+    {
+      SymmetricComplex::Cone &theCone=clist.front();
+
+      if(!c.contains(theCone))
+        {
+          c.insert(theCone);
+          list<SymmetricComplex::Cone> facets=computeFacets(theCone,rays,facetCandidates,c/*,linealityDim*/);
+          clist.splice(clist.end(),facets);
+        }
+      clist.pop_front();
+    }
+
+}
+
+#if 0
+/**
+   Produce strings that express the vectors in terms of rays of the fan modulo the lineality space. Symmetry is ignored??
+ */
+vector<string> PolyhedralFan::renamingStrings(IntegerVectorList const &theVectors, IntegerVectorList const &originalRays, IntegerVectorList const &linealitySpace, SymmetryGroup *sym)const
+{
+  vector<string> ret;
+  for(IntegerVectorList::const_iterator i=theVectors.begin();i!=theVectors.end();i++)
+    {
+      for(PolyhedralConeList::const_iterator j=cones.begin();j!=cones.end();j++)
+        {
+          if(j->contains(*i))
+            {
+              vector<int> relevantIndices;
+              IntegerVectorList relevantRays=linealitySpace;
+              int K=0;
+              for(IntegerVectorList::const_iterator k=originalRays.begin();k!=originalRays.end();k++,K++)
+                if(j->contains(*k))
+                  {
+                    relevantIndices.push_back(K);
+                    relevantRays.push_back(*k);
+                  }
+
+              FieldMatrix LFA(Q,relevantRays.size(),n);
+              int J=0;
+              for(IntegerVectorList::const_iterator j=relevantRays.begin();j!=relevantRays.end();j++,J++)
+                LFA[J]=integerVectorToFieldVector(*j,Q);
+              FieldVector LFB=concatenation(integerVectorToFieldVector(*i,Q),FieldVector(Q,relevantRays.size()));
+              LFA=LFA.transposed();
+              FieldVector LFX=LFA.solver().canonicalize(LFB);
+              stringstream s;
+              if(LFX.subvector(0,n).isZero())
+                {
+                  s<<"Was:";
+                  FieldVector S=LFX.subvector(n+linealitySpace.size(),LFX.size());
+                  for(int k=0;k<S.size();k++)
+                    if(!S[k].isZero())
+                      s<<"+"<<S[k].toString()<<"*["<<relevantIndices[k]<<"] ";
+                }
+              ret.push_back(s.str());
+              break;
+            }
+        }
+    }
+  return ret;
+}
+#endif
+
+SymmetricComplex PolyhedralFan::toSymmetricComplex()const
+{
+
+          ZMatrix rays=getRaysInPrintingOrder();
+
+          ZMatrix generatorsOfLinealitySpace=cones.empty()?ZMatrix::identity(getAmbientDimension()):cones.begin()->generatorsOfLinealitySpace();
+          SymmetricComplex symCom(rays,generatorsOfLinealitySpace,symmetries);
+
+          for(PolyhedralConeList::const_iterator i=cones.begin();i!=cones.end();i++)
+            {
+              addFacesToSymmetricComplex(symCom,*i,i->getFacets(),generatorsOfLinealitySpace);
+            }
+
+//          log1 cerr<<"Remapping";
+          symCom.remap();
+//          log1 cerr<<"Done remapping";
+
+          return symCom;
+}
+
+std::string PolyhedralFan::toString(int /*flags*/)const
+//void PolyhedralFan::printWithIndices(class Printer *p, bool printMultiplicities, SymmetryGroup *sym, bool group, bool ignoreCones, bool xml, bool tPlaneSort, vector<string> const *comments)const
+{
+  stringstream ret;
+
+  for(PolyhedralConeList::const_iterator i=cones.begin();i!=cones.end();i++)
+    {
+      ret<<"Cone\n"<<endl;
+    ret<<*i;
+    }  return ret.str();
+#if 0
+  PolymakeFile polymakeFile;
+  polymakeFile.create("NONAME","PolyhedralFan","PolyhedralFan",flags&FPF_xml);
+
+//  if(!sym)sym=&symm;
+
+  if(cones.empty())
+    {
+//      p->printString("Polyhedral fan is empty. Printing not supported.\n");
+      ret<<"Polyhedral fan is empty. Printing not supported.\n";
+      return ret.str();
+    }
+
+  int h=cones.begin()->dimensionOfLinealitySpace();
+
+//  log1 fprintf(Stderr,"Computing rays.\n");
+  ZMatrix rays=getRaysInPrintingOrder();
+
+  SymmetricComplex symCom(rays,cones.begin()->generatorsOfLinealitySpace(),symmetries);
+
+  polymakeFile.writeCardinalProperty("AMBIENT_DIM",n);
+  polymakeFile.writeCardinalProperty("DIM",getMaxDimension());
+  polymakeFile.writeCardinalProperty("LINEALITY_DIM",h);
+  polymakeFile.writeMatrixProperty("RAYS",rays,true,comments);
+  polymakeFile.writeCardinalProperty("N_RAYS",rays.size());
+  IntegerVectorList linealitySpaceGenerators=highestDimensionalCone().linealitySpace().dualCone().getEquations();
+  polymakeFile.writeMatrixProperty("LINEALITY_SPACE",rowsToIntegerMatrix(linealitySpaceGenerators,n));
+  polymakeFile.writeMatrixProperty("ORTH_LINEALITY_SPACE",rowsToIntegerMatrix(highestDimensionalCone().linealitySpace().getEquations(),n));
+
+  if(flags & FPF_primitiveRays)
+  {
+         ZMatrix primitiveRays;
+         for(IntegerVectorList::const_iterator i=rays.begin();i!=rays.end();i++)
+                 for(PolyhedralConeList::const_iterator j=cones.begin();j!=cones.end();j++)
+                         if(j->contains(*i)&&(j->dimensionOfLinealitySpace()+1==j->dimension()))
+                                         primitiveRays.push_back(j->semiGroupGeneratorOfRay());
+
+          polymakeFile.writeMatrixProperty("PRIMITIVE_RAYS",rowsToIntegerMatrix(primitiveRays,n));
+  }
+
+
+  ZMatrix generatorsOfLinealitySpace=cones.begin()->generatorsOfLinealitySpace();
+
+  log1 fprintf(Stderr,"Building symmetric complex.\n");
+  for(PolyhedralConeList::const_iterator i=cones.begin();i!=cones.end();i++)
+    {
+      {
+        static int t;
+//        log1 fprintf(Stderr,"Adding faces of cone %i\n",t++);
+      }
+//      log2 fprintf(Stderr,"Dim: %i\n",i->dimension());
+
+      addFacesToSymmetricComplex(symCom,*i,i->getHalfSpaces(),generatorsOfLinealitySpace);
+    }
+
+//  log1 cerr<<"Remapping";
+  symCom.remap();
+//  log1 cerr<<"Done remapping";
+
+
+  PolyhedralFan f=*this;
+
+//  log1 fprintf(Stderr,"Computing f-vector.\n");
+  ZVector fvector=symCom.fvector();
+  polymakeFile.writeCardinalVectorProperty("F_VECTOR",fvector);
+//  log1 fprintf(Stderr,"Done computing f-vector.\n");
+
+  if(flags&FPF_boundedInfo)
+    {
+//      log1 fprintf(Stderr,"Computing bounded f-vector.\n");
+      ZVector fvectorBounded=symCom.fvector(true);
+      polymakeFile.writeCardinalVectorProperty("F_VECTOR_BOUNDED",fvectorBounded);
+//      log1 fprintf(Stderr,"Done computing bounded f-vector.\n");
+    }
+  {
+    Integer euler;
+    int mul=-1;
+    for(int i=0;i<fvector.size();i++,mul*=-1)euler+=Integer(mul)*fvector[i];
+    polymakeFile.writeCardinalProperty("MY_EULER",euler);
+  }
+
+//  log1 fprintf(Stderr,"Checking if complex is simplicial and pure.\n");
+  polymakeFile.writeCardinalProperty("SIMPLICIAL",symCom.isSimplicial());
+  polymakeFile.writeCardinalProperty("PURE",symCom.isPure());
+//  log1 fprintf(Stderr,"Done checking.\n");
+
+
+  if(flags&FPF_conesCompressed)
+  {
+//    log1 fprintf(Stderr,"Producing list of cones up to symmetry.\n");
+    polymakeFile.writeStringProperty("CONES_ORBITS",symCom.toString(symCom.getMinDim(),symCom.getMaxDim(),false,flags&FPF_group,0,true,flags&FPF_tPlaneSort));
+//    log1 fprintf(Stderr,"Done producing list of cones up to symmetry.\n");
+//    log1 fprintf(Stderr,"Producing list of maximal cones up to symmetry.\n");
+    stringstream multiplicities;
+    polymakeFile.writeStringProperty("MAXIMAL_CONES_ORBITS",symCom.toString(symCom.getMinDim(),symCom.getMaxDim(),true,flags&FPF_group, &multiplicities,true,flags&FPF_tPlaneSort));
+    if(flags&FPF_multiplicities)polymakeFile.writeStringProperty("MULTIPLICITIES_ORBITS",multiplicities.str());
+//    log1 fprintf(Stderr,"Done producing list of maximal cones up to symmetry.\n");
+  }
+
+  if(flags&FPF_conesExpanded)
+    {
+      if(flags&FPF_cones)
+        {
+//          log1 fprintf(Stderr,"Producing list of cones.\n");
+          polymakeFile.writeStringProperty("CONES",symCom.toString(symCom.getMinDim(),symCom.getMaxDim(),false,flags&FPF_group,0,false,flags&FPF_tPlaneSort));
+//          log1 fprintf(Stderr,"Done producing list of cones.\n");
+        }
+      if(flags&FPF_maximalCones)
+        {
+//          log1 fprintf(Stderr,"Producing list of maximal cones.\n");
+          stringstream multiplicities;
+          polymakeFile.writeStringProperty("MAXIMAL_CONES",symCom.toString(symCom.getMinDim(),symCom.getMaxDim(),true,flags&FPF_group, &multiplicities,false,flags&FPF_tPlaneSort));
+          if(flags&FPF_multiplicities)polymakeFile.writeStringProperty("MULTIPLICITIES",multiplicities.str());
+//          log1 fprintf(Stderr,"Done producing list of maximal cones.\n");
+        }
+    }
+#endif
+  #if 0
+  if(flags&FPF_values)
+    {
+      {
+        ZMatrix values;
+        for(int i=0;i<linealitySpaceGenerators.getHeight();i++)
+          {
+            ZVector v(1);
+            v[0]=evaluatePiecewiseLinearFunction(linealitySpaceGenerators[i]);
+            values.appendRow(v);
+          }
+        polymakeFile.writeMatrixProperty("LINEALITY_VALUES",rowsToIntegerMatrix(values,1));
+      }
+      {
+        ZMatrix values;
+        for(IntegerVectorList::const_iterator i=rays.begin();i!=rays.end();i++)
+          {
+            ZVector v(1);
+            v[0]=evaluatePiecewiseLinearFunction(*i);
+            values.push_back(v);
+          }
+        polymakeFile.writeMatrixProperty("RAY_VALUES",rowsToIntegerMatrix(values,1));
+      }
+    }
+#endif
+
+
+//  log1 fprintf(Stderr,"Producing final string for output.\n");
+/*  stringstream s;
+  polymakeFile.writeStream(s);
+  string S=s.str();
+//  log1 fprintf(Stderr,"Printing string.\n");
+  p->printString(S.c_str());
+*///  log1 fprintf(Stderr,"Done printing string.\n");
+}
+
+#if 0
+PolyhedralFan PolyhedralFan::readFan(string const &filename, bool onlyMaximal, IntegerVector *w, set<int> const *coneIndices, SymmetryGroup const *sym, bool readCompressedIfNotSym)
+{
+    PolymakeFile inFile;
+    inFile.open(filename.c_str());
+
+    int n=inFile.readCardinalProperty("AMBIENT_DIM");
+    int nRays=inFile.readCardinalProperty("N_RAYS");
+    IntegerMatrix rays=inFile.readMatrixProperty("RAYS",nRays,n);
+    int linealityDim=inFile.readCardinalProperty("LINEALITY_DIM");
+    IntegerMatrix linealitySpace=inFile.readMatrixProperty("LINEALITY_SPACE",linealityDim,n);
+
+
+    const char *sectionName=0;
+    const char *sectionNameMultiplicities=0;
+    if(sym || readCompressedIfNotSym)
+    {
+      sectionName=(onlyMaximal)?"MAXIMAL_CONES_ORBITS":"CONES_ORBITS";
+      sectionNameMultiplicities=(onlyMaximal)?"MULTIPLICITIES_ORBITS":"DUMMY123";
+    }
+      else
+      {  sectionName=(onlyMaximal)?"MAXIMAL_CONES":"CONES";
+      sectionNameMultiplicities=(onlyMaximal)?"MULTIPLICITIES":"DUMMY123";
+      }
+
+
+    IntegerVector w2(n);
+    if(w==0)w=&w2;
+
+    SymmetryGroup sym2(n);
+    if(sym==0)sym=&sym2;
+
+    vector<list<int> > cones=inFile.readMatrixIncidenceProperty(sectionName);
+    IntegerVectorList r;
+
+    bool hasMultiplicities=inFile.hasProperty(sectionNameMultiplicities);
+    IntegerMatrix multiplicities(0,0);
+    if(hasMultiplicities)multiplicities=inFile.readMatrixProperty(sectionNameMultiplicities,cones.size(),1);
+
+
+    PolyhedralFan ret(n);
+
+    log2 cerr<< "Number of orbits to expand "<<cones.size()<<endl;
+    for(int i=0;i<cones.size();i++)
+      if(coneIndices==0 || coneIndices->count(i))
+        {
+          log2 cerr<<"Expanding symmetries of cone"<<endl;
+          {
+            IntegerVectorList coneRays;
+            for(list<int>::const_iterator j=cones[i].begin();j!=cones[i].end();j++)
+              coneRays.push_back((rays[*j]));
+            PolyhedralCone C=PolyhedralCone::givenByRays(coneRays,linealitySpace.getRows(),n);
+            if(hasMultiplicities)C.setMultiplicity(multiplicities[i][0]);
+            for(SymmetryGroup::ElementContainer::const_iterator perm=sym->elements.begin();perm!=sym->elements.end();perm++)
+              {
+                if(C.contains(SymmetryGroup::composeInverse(*perm,*w)))
+                  {
+                    PolyhedralCone C2=C.permuted(*perm);
+                    C2.canonicalize();
+                    ret.insert(C2);
+                  }
+              }
+          }
+        }
+    return ret;
+}
+#endif
+
+#if 0
+IncidenceList PolyhedralFan::getIncidenceList(SymmetryGroup *sym)const //fan must be pure
+{
+  IncidenceList ret;
+  SymmetryGroup symm(n);
+  if(!sym)sym=&symm;
+  assert(!cones.empty());
+  int h=cones.begin()->dimensionOfLinealitySpace();
+  IntegerVectorList rays=getRaysInPrintingOrder(sym);
+  PolyhedralFan f=*this;
+
+  while(f.getMaxDimension()!=h)
+    {
+      IntegerVectorList l;
+      PolyhedralFan done(n);
+      IntegerVector rayIncidenceCounter(rays.size());
+      int faceIndex =0;
+      for(PolyhedralConeList::const_iterator i=f.cones.begin();i!=f.cones.end();i++)
+        {
+          if(!done.contains(*i))
+            {
+              for(SymmetryGroup::ElementContainer::const_iterator k=sym->elements.begin();k!=sym->elements.end();k++)
+                {
+                  PolyhedralCone cone=i->permuted(*k);
+                  if(!done.contains(cone))
+                    {
+                      int rayIndex=0;
+                      IntegerVector indices(0);
+                      for(IntegerVectorList::const_iterator j=rays.begin();j!=rays.end();j++)
+                        {
+                          if(cone.contains(*j))
+                            {
+                              indices.grow(indices.size()+1);
+                              indices[indices.size()-1]=rayIndex;
+                              rayIncidenceCounter[rayIndex]++;
+                            }
+                          rayIndex++;
+                        }
+                      l.push_back(indices);
+                      faceIndex++;
+                      done.insert(cone);
+                    }
+                }
+            }
+        }
+      ret[f.getMaxDimension()]=l;
+      f=f.facetComplex();
+    }
+  return ret;
+}
+#endif
+
+void PolyhedralFan::makePure()
+{
+  if(getMaxDimension()!=getMinDimension())removeAllLowerDimensional();
+}
+
+bool PolyhedralFan::contains(ZCone const &c)const
+{
+  return cones.count(c);
+}
+
+
+#if 0
+PolyhedralCone PolyhedralFan::coneContaining(ZVector const &v)const
+{
+  for(PolyhedralConeList::const_iterator i=cones.begin();i!=cones.end();i++)
+    if(i->contains(v))return i->faceContaining(v);
+  debug<<"Vector "<<v<<" not contained in support of fan\n";
+  assert(0);
+}
+#endif
+
+PolyhedralFan::coneIterator PolyhedralFan::conesBegin()const
+{
+  return cones.begin();
+}
+
+
+PolyhedralFan::coneIterator PolyhedralFan::conesEnd()const
+{
+  return cones.end();
+}
+
+
+
+PolyhedralFan PolyhedralFan::link(ZVector const &w, SymmetryGroup *sym)const
+{
+  SymmetryGroup symL(n);
+  if(!sym)sym=&symL;
+
+  PolyhedralFan ret(n);
+
+  for(PolyhedralConeList::const_iterator i=cones.begin();i!=cones.end();i++)
+    {
+      for(SymmetryGroup::ElementContainer::const_iterator perm=sym->elements.begin();perm!=sym->elements.end();perm++)
+        {
+          ZVector w2=perm->applyInverse(w);
+          if(i->contains(w2))
+            {
+              ret.insert(i->link(w2));
+            }
+        }
+    }
+  return ret;
+}
+
+PolyhedralFan PolyhedralFan::link(ZVector const &w)const
+{
+  PolyhedralFan ret(n);
+
+  for(PolyhedralConeList::const_iterator i=cones.begin();i!=cones.end();i++)
+    {
+      if(i->contains(w))
+        {
+          ret.insert(i->link(w));
+        }
+    }
+  return ret;
+}
+
+
+int PolyhedralFan::size()const
+{
+  return cones.size();
+}
+
+int PolyhedralFan::dimensionOfLinealitySpace()const
+{
+  if(cones.size()) //slow!
+    return 0;
+  else
+    return cones.begin()->dimensionOfLinealitySpace();
+}
+
+
+
+
+void PolyhedralFan::removeNonMaximal()
+{
+  for(PolyhedralConeList::iterator i=cones.begin();i!=cones.end();)
+    {
+      ZVector w=i->getRelativeInteriorPoint();
+      bool containedInOther=false;
+      for(PolyhedralConeList::iterator j=cones.begin();j!=cones.end();j++)
+        if(j!=i)
+          {
+            if(j->contains(w)){containedInOther=true;break;}
+          }
+      if(containedInOther)
+        {
+          PolyhedralConeList::iterator k=i;
+          i++;
+          cones.erase(k);
+        }
+      else i++;
+    }
+}
+
+
+}
diff --git a/gfanlib/gfanlib_polyhedralfan.h b/gfanlib/gfanlib_polyhedralfan.h
new file mode 100644
index 0000000..89a58f3
--- /dev/null
+++ b/gfanlib/gfanlib_polyhedralfan.h
@@ -0,0 +1,117 @@
+/*
+ * gfanlib_polyhedralfan.h
+ *
+ *  Created on: Nov 16, 2010
+ *      Author: anders
+ */
+
+#ifndef GFANLIB_POLYHEDRALFAN_H_INCLUDED
+#define GFANLIB_POLYHEDRALFAN_H_INCLUDED
+
+#include <set>
+#include <list>
+#include <map>
+#include "gfanlib_symmetry.h"
+#include "gfanlib_matrix.h"
+#include "gfanlib_zcone.h"
+#include "gfanlib_symmetriccomplex.h"
+
+namespace gfan{
+
+
+typedef std::set<ZCone> PolyhedralConeList;
+typedef std::list<IntVector> IntVectorList;
+typedef std::map<int,IntVectorList> IncidenceList;
+
+class PolyhedralFan ;
+
+PolyhedralFan refinement(const PolyhedralFan &a, const PolyhedralFan &b, int cutOffDimension=-1, bool allowASingleConeOfCutOffDimension=false);
+
+/** A PolyhedralFan is simply a collection of canonicalized PolyhedralCones.
+ * It contains no combinatorial information in the sense of a polyhedral complex.
+ * A cone being present in the PolyhedralFan corresponds to the cone and all its facets being present
+ * in the mathematical object.
+ * The intersection of cones in the fan must be a face of both.
+ * In particular all cones in a PolyhedralFan have the same lineality space.*/
+class PolyhedralFan
+{
+  int n;
+  SymmetryGroup symmetries;
+  PolyhedralConeList cones;
+ public:
+  static class PolyhedralFan fullSpace(int n);
+  static class PolyhedralFan facetsOfCone(ZCone const &c);
+  PolyhedralFan(int ambientDimension);
+  PolyhedralFan(SymmetryGroup const &sym);
+  std::string toString(int flags=FPF_default)const;
+  /* Read in a polyhedral fan, but with the cones containing w.  If
+     present, only read in cones among coneIndices.  If sym is
+     present, read COMPRESSED section and make w containment up to
+     symmetry, taking all elements in the orbit that contains w into
+     the fan.  If onlyMaximal is set then only maximal cones are read
+     in.
+   */
+  int getAmbientDimension()const;
+  int getMaxDimension()const;
+  int getMinDimension()const;
+
+//   friend PolyhedralFan refinement(const PolyhedralFan &a, const PolyhedralFan &b, int cutOffDimension=-1, bool allowASingleConeOfCutOffDimension=false);
+
+  ZMatrix getRays(int dim=1);//This can be called for other dimensions than 1. The term "Rays" still makes sense modulo the common linearity space
+  ZMatrix getRelativeInteriorPoints();
+  void insert(ZCone const &c);
+  void remove(ZCone const &c);
+  void removeAllLowerDimensional();
+  /**
+     Since the cones stored in a PolyhedralFan are cones of a
+     polyhedral fan, it is possible to identify non maximal cones by
+     just checking containment of relative interior points in other
+     cones. This routine removes all non-maximal cones.
+   */
+  void removeNonMaximal();
+  /**
+     Returns the number of cones stored in the fan. This is not the number of cones in the fan in a mathematical sense.
+   */
+  int size()const;
+  int dimensionOfLinealitySpace()const;
+  void makePure();
+  bool contains(ZCone const &c)const;
+  /**
+   * For a vector contained in the support of the fan represented by the fan object, this function
+   * computes the cone that contains the vector in its relative interior.
+   */
+  ZCone coneContaining(ZVector const &v)const;
+  PolyhedralFan facetComplex()const;
+
+  ZMatrix getRaysInPrintingOrder(bool upToSymmetry=false)const;
+  IncidenceList getIncidenceList(SymmetryGroup *sym=0)const;
+  bool isEmpty()const;
+
+
+  /**
+     Computes the link of the face containing w in its relative interior.
+   */
+  PolyhedralFan link(ZVector const &w)const;
+  PolyhedralFan link(ZVector const &w, SymmetryGroup *sym)const;
+
+
+
+  typedef PolyhedralConeList::const_iterator coneIterator;
+  PolyhedralFan::coneIterator conesBegin()const;
+  PolyhedralFan::coneIterator conesEnd()const;
+
+
+  /**
+   * Converts a PolyhedralFan into a SymmetricComplex. This is used for homology computations, but not for printing yet.
+   */
+  SymmetricComplex toSymmetricComplex()const;
+//  static PolyhedralFan readFan(string const &filename, bool onlyMaximal=true, IntegerVector *w=0, set<int> const *conesIndice=0, SymmetryGroup const *sym=0, bool readCompressedIfNotSym=false);
+};
+
+
+void addFacesToSymmetricComplex(SymmetricComplex &c, ZCone const &cone, ZMatrix const &facetCandidates, ZMatrix const &generatorsOfLinealitySpace);
+void addFacesToSymmetricComplex(SymmetricComplex &c, std::set<int> const &indices, ZMatrix const &facetCandidates, int dimension, Integer multiplicity);
+
+}
+
+#endif
diff --git a/gfanlib/gfanlib_polymakefile.cpp b/gfanlib/gfanlib_polymakefile.cpp
new file mode 100644
index 0000000..4eeafa4
--- /dev/null
+++ b/gfanlib/gfanlib_polymakefile.cpp
@@ -0,0 +1,474 @@
+/*
+ * gfanlib_polymakefile.cpp
+ *
+ *  Created on: Nov 17, 2010
+ *      Author: anders
+ */
+
+#include "gfanlib_polymakefile.h"
+
+#include <assert.h>
+#include <sstream>
+#include <istream>
+#include <stdio.h>
+
+using namespace std;
+
+static void eatComment2(int &c, stringstream &s)
+{
+  if(c=='#')
+    {
+      do
+        c=s.get();
+      while(c!='\n' && !s.eof());
+    }
+}
+
+static void eatComment(stringstream &s)
+{
+  int c=s.get();
+  while(c==' '||c=='\t')c=s.get();
+  eatComment2(c,s);
+  s.unget();
+}
+
+static string readUntil(istream &f, int c)
+{
+  stringstream ret;
+  int c2;
+  c2=f.get();
+//  c2=fgetc(f);
+//  while(c2!=c && c2!=EOF)
+  while(c2!=c && !f.eof())
+  {
+      ret<<char(c2);
+      //c2=fgetc(f);
+      c2=f.get();
+  }
+  return ret.str();
+}
+
+static list<int> readIntList(istream &s)
+{
+  list<int> ret;
+  int c=s.peek();
+  while(((c>='0') && (c<='9')) || (c==' '))
+    {
+      //      fprintf(Stderr,"?\n");
+      int r;
+      s >> r;
+      ret.push_back(r);
+      c=s.peek();
+    }
+  return ret;
+}
+
+namespace gfan{
+PolymakeProperty::PolymakeProperty(const std::string &name_, const std::string &value_):
+  value(value_),
+  name(name_)
+{
+}
+
+
+void PolymakeFile::open(std::istream &f)
+{
+  isXml=false;
+//  fileName=string(fileName_);
+
+//  FILE *f=fopen(fileName.c_str(),"r");
+//  if(!f)//fprintf(Stderr,"Could not open file:\"%s\"\n",fileName_);
+//  assert(f);
+
+  int c=f.get();//fgetc(f);
+  while(!f.eof())
+    {
+      if(c=='_')
+        {
+          readUntil(f,'\n');
+        }
+      else if(c!='\n')
+        {
+          f.unget();
+          //          ungetc(c,f);
+          string name=readUntil(f,'\n');
+
+//          fprintf(Stderr,"Reading:\"%s\"\n",name.c_str());
+          stringstream value;
+          while(1)
+            {
+              string l=readUntil(f,'\n');
+              if(l.size()==0)break;
+              value << l <<endl;
+            }
+          properties.push_back(PolymakeProperty(name.c_str(),value.str().c_str()));
+        }
+      c=f.get();//fgetc(f);
+    }
+}
+
+/*void PolymakeFile::open(const char *fileName_)
+{
+  isXml=false;
+  fileName=string(fileName_);
+
+  FILE *f=fopen(fileName.c_str(),"r");
+//  if(!f)//fprintf(Stderr,"Could not open file:\"%s\"\n",fileName_);
+  assert(f);
+
+  int c=fgetc(f);
+  while(c!=EOF)
+    {
+      if(c=='_')
+        {
+          readUntil(f,'\n');
+        }
+      else if(c!='\n')
+        {
+          ungetc(c,f);
+          string name=readUntil(f,'\n');
+
+//          fprintf(Stderr,"Reading:\"%s\"\n",name.c_str());
+          stringstream value;
+          while(1)
+            {
+              string l=readUntil(f,'\n');
+              if(l.size()==0)break;
+              value << l <<endl;
+            }
+          properties.push_back(PolymakeProperty(name.c_str(),value.str().c_str()));
+        }
+      c=fgetc(f);
+    }
+}
+*/
+void PolymakeFile::create(const char *fileName_, const char *application_, const char *type_, bool isXml_)
+{
+  fileName=string(fileName_);
+  application=string(application_);
+  type=string(type_);
+  isXml=isXml_;
+}
+
+
+void PolymakeFile::close()
+{
+  FILE *f=fopen(fileName.c_str(),"w");
+  assert(f);
+
+  if(isXml)
+    {
+      fprintf(f,"<properties>\n");
+
+      for(list<PolymakeProperty>::const_iterator i=properties.begin();i!=properties.end();i++)
+        {
+          fprintf(f,"<property name=\"%s\">\n",i->name.c_str());
+          fprintf(f,"%s",i->value.c_str());
+          fprintf(f,"</property>\n");
+        }
+      fprintf(f,"</properties>\n");
+    }
+  else
+    {
+      // fprintf(f,"_application %s\n",application.c_str());
+      // fprintf(f,"_version 2.2\n");
+      // fprintf(f,"_type %s\n",type.c_str());
+
+      for(list<PolymakeProperty>::const_iterator i=properties.begin();i!=properties.end();i++)
+        {
+          fprintf(f,"\n%s\n",i->name.c_str());
+          fprintf(f,"%s",i->value.c_str());
+        }
+    }
+  fclose(f);
+}
+
+
+void PolymakeFile::writeStream(ostream &file)
+{
+  if(isXml)
+    {
+      file << "<properties>\n";
+
+      for(list<PolymakeProperty>::const_iterator i=properties.begin();i!=properties.end();i++)
+        {
+          file << "<property name=\"" << i->name.c_str() << "\">\n";
+          file << i->value.c_str();
+          file << "</property>\n";
+        }
+      file << "</properties>\n";
+    }
+  else
+    {
+      // file << "_application " << application << endl;
+      // file << "_version 2.2\n";
+      // file << "_type " << type << endl;
+
+      for(list<PolymakeProperty>::const_iterator i=properties.begin();i!=properties.end();i++)
+        {
+          file << endl << i->name.c_str() << endl;
+          file << i->value;
+        }
+    }
+}
+
+
+list<PolymakeProperty>::iterator PolymakeFile::findProperty(const char *p)
+{
+  string s(p);
+  for(list<PolymakeProperty>::iterator i=properties.begin();i!=properties.end();i++)
+    {
+      if(s==i->name)return i;
+    }
+
+  return properties.end();
+}
+
+
+void PolymakeFile::writeProperty(const char *p, const string &data)
+{
+  if(hasProperty(p))
+    {
+      assert(0);
+    }
+  properties.push_back(PolymakeProperty(string(p),data));
+}
+
+
+bool PolymakeFile::hasProperty(const char *p, bool doAssert)
+{
+  if(doAssert)
+    if(findProperty(p)==properties.end())
+      {
+        fprintf(stderr,"Property: \"%s\" not found in file.\n",p);
+        assert(0);
+      }
+
+  return findProperty(p)!=properties.end();
+}
+
+
+Integer PolymakeFile::readCardinalProperty(const char *p)
+{
+  assert(hasProperty(p,true));
+
+  list<PolymakeProperty>::iterator prop=findProperty(p);
+  stringstream s(prop->value);
+
+  int ret;
+  s>>ret;
+
+  return ret;
+}
+
+
+void PolymakeFile::writeCardinalProperty(const char *p, Integer n)
+{
+  stringstream t;
+  t<<n<<endl;
+  writeProperty(p,t.str());
+}
+
+
+bool PolymakeFile::readBooleanProperty(const char */*p*/)
+{
+  return false;
+}
+
+
+void PolymakeFile::writeBooleanProperty(const char */*p*/, bool /*n*/)
+{
+}
+
+
+ZMatrix PolymakeFile::readMatrixProperty(const char *p, int height, int width)
+{
+  ZMatrix ret(0,width);
+
+  assert(hasProperty(p,true));
+  list<PolymakeProperty>::iterator prop=findProperty(p);
+  stringstream s(prop->value);
+//  for(int i=0;i<height;i++)
+  for(int i=0;;i++)
+  {
+    if(i==height)break;
+    ZVector w(width);
+    for(int j=0;j<width;j++)
+        {
+          int v;
+          eatComment(s);
+          s>>v;
+          if(s.eof())goto done;
+          w[j]=v;
+        }
+    ret.appendRow(w);
+  }
+  done:
+
+  if(height>=0)assert(ret.getHeight()==height);
+//  cerr<<p;
+ //   eatComment(s);
+   // int v;
+   // s>>v;
+//  while(!s.eof())std::cerr<<char(s.get());
+ // assert(s.eof());
+
+  return ret;
+}
+
+
+void PolymakeFile::writeMatrixProperty(const char *p, const ZMatrix &m, bool indexed, const vector<string> *comments)
+{
+  stringstream t;
+
+  if(comments)assert((int)comments->size()>=m.getHeight());
+  if(isXml)
+    {
+      t << "<matrix>\n";
+      for(int i=0;i<m.getHeight();i++)
+        {
+          t << "<vector>";
+          for(int j=0;j<m.getWidth();j++)
+            {
+              if(j!=0)t<<" ";
+              t<<m[i][j];
+            }
+          t<<endl;
+          t << "</vector>\n";
+        }
+      t << "</matrix>\n";
+    }
+  else
+    {
+      for(int i=0;i<m.getHeight();i++)
+        {
+          for(int j=0;j<m.getWidth();j++)
+            {
+              if(j!=0)t<<" ";
+              t<<m[i][j];
+            }
+          if(indexed)t<<"\t# "<<i;
+          if(comments)t<<"\t# "<<(*comments)[i];
+          t<<endl;
+        }
+    }
+  writeProperty(p,t.str());
+}
+
+
+vector<list<int> > PolymakeFile::readMatrixIncidenceProperty(const char *p)
+{
+  vector<list<int> > ret;
+  assert(hasProperty(p,true));
+  list<PolymakeProperty>::iterator prop=findProperty(p);
+  stringstream s(prop->value);
+
+  while((s.peek()!=-1)&&(s.peek()!='\n')&&(s.peek()!=0))
+    {
+      //      fprintf(Stderr,"!\n");
+      int c=s.get();
+      //fprintf(Stderr,"%i",c);
+      assert(c=='{');
+      ret.push_back(readIntList(s));
+      c=s.get();
+      assert(c=='}');
+      c=s.get();
+      while(c==' ' || c=='\t')c=s.get();
+      eatComment2(c,s);
+      assert(c=='\n');
+    }
+  return ret;
+}
+
+
+void PolymakeFile::writeIncidenceMatrixProperty(const char *p, const vector<list<int> > &m)
+{
+  stringstream t;
+
+  if(isXml)
+    {
+      t<<"<incidence_matrix>";
+      for(unsigned i=0;i<m.size();i++)
+        {
+          t<<"<set>";
+          list<int> temp=m[i];
+          temp.sort();
+          for(list<int>::const_iterator j=temp.begin();j!=temp.end();j++)
+            {
+              if(j!=temp.begin())t<<' ';
+              t<< *j;
+            }
+          t<<"</set>\n"<<endl;
+        }
+      t<<"</incidence_matrix>\n";
+    }
+  else
+    {
+      for(unsigned i=0;i<m.size();i++)
+        {
+          t<<'{';
+          list<int> temp=m[i];
+          temp.sort();
+          for(list<int>::const_iterator j=temp.begin();j!=temp.end();j++)
+            {
+              if(j!=temp.begin())t<<' ';
+              t<< *j;
+            }
+          t<<'}'<<endl;
+        }
+    }
+  writeProperty(p,t.str());
+}
+
+
+ZVector PolymakeFile::readCardinalVectorProperty(const char *p)
+{
+  assert(hasProperty(p,true));
+  list<PolymakeProperty>::iterator prop=findProperty(p);
+  stringstream s(prop->value);
+
+  list<int> temp=readIntList(s);
+
+  ZVector ret(temp.size());
+  int I=0;
+  for(list<int>::const_iterator i=temp.begin();i!=temp.end();i++,I++)ret[I]=*i;
+
+  return ret;
+}
+
+
+void PolymakeFile::writeCardinalVectorProperty(const char *p, ZVector const &v)
+{
+  stringstream t;
+
+  if(isXml)
+    {
+      t<<"<vector>";
+      for(unsigned i=0;i<v.size();i++)
+        {
+          if(i!=0)t<<" ";
+          t<<v[i];
+        }
+      t<<"</vector>\n";
+    }
+  else
+    {
+      for(unsigned i=0;i<v.size();i++)
+        {
+          if(i!=0)t<<" ";
+          t<<v[i];
+        }
+      t<<endl;
+    }
+  writeProperty(p,t.str());
+}
+
+
+void PolymakeFile::writeStringProperty(const char *p, const string &s)
+{
+  if(isXml)
+    writeProperty(p,s);
+  else
+    writeProperty(p,s);
+}
+}
diff --git a/gfanlib/gfanlib_polymakefile.h b/gfanlib/gfanlib_polymakefile.h
new file mode 100644
index 0000000..df6d7ce
--- /dev/null
+++ b/gfanlib/gfanlib_polymakefile.h
@@ -0,0 +1,66 @@
+/*
+ * gfanlib_polymakefile.h
+ *
+ *  Created on: Nov 17, 2010
+ *      Author: anders
+ */
+
+#ifndef GFANLIB_POLYMAKEFILE_H_INCLUDED
+#define GFANLIB_POLYMAKEFILE_H_INCLUDED
+
+
+#include <list>
+#include <vector>
+#include <string>
+#include <iostream>
+
+#include "gfanlib_matrix.h"
+
+namespace gfan
+{
+class PolymakeProperty
+{
+ public:
+  std::string value;
+  std::string name;
+  PolymakeProperty(const std::string &name_, const std::string &value_);
+};
+
+class PolymakeFile
+{
+  std::string application,type;
+  std::string fileName;
+  std::list<PolymakeProperty> properties;
+  std::list<PolymakeProperty>::iterator findProperty(const char *p);
+  void writeProperty(const char *p, const std::string &data);
+  bool isXml;
+ public:
+//   void open(const char *fileName_);
+   void open(std::istream &f);
+  void create(const char *fileName_, const char *application_, const char *type_, bool isXml_=false);
+  void writeStream(std::ostream &file);
+  void close();
+  bool hasProperty(const char *p, bool doAssert=false);
+
+  // The following could be part of a subclass to avoid dependencies on gfan
+  Integer readCardinalProperty(const char *p);
+  void writeCardinalProperty(const char *p, Integer n);
+
+  bool readBooleanProperty(const char *p);
+  void writeBooleanProperty(const char *p, bool n);
+
+  ZMatrix readMatrixProperty(const char *p, int height, int width);
+  void writeMatrixProperty(const char *p, const ZMatrix &m, bool indexed=false, const std::vector<std::string> *comments=0);
+
+  std::vector<std::list<int> > readMatrixIncidenceProperty(const char *p);
+  void writeIncidenceMatrixProperty(const char *p, const std::vector<std::list<int> > &m);
+
+  ZVector readCardinalVectorProperty(const char *p);
+  void writeCardinalVectorProperty(const char *p, ZVector const &v);
+
+  void writeStringProperty(const char *p, const std::string &s);
+};
+}
+
+#endif
+
diff --git a/gfanlib/gfanlib_q.h b/gfanlib/gfanlib_q.h
new file mode 100644
index 0000000..7ca737b
--- /dev/null
+++ b/gfanlib/gfanlib_q.h
@@ -0,0 +1,180 @@
+/*
+ * lib_q.h
+ *
+ *  Created on: Sep 29, 2010
+ *      Author: anders
+ */
+
+#ifndef LIB_Q_H_
+#define LIB_Q_H_
+
+#include <string.h>
+#include <ostream>
+#include "gmp.h"
+
+#include "gfanlib_z.h"
+
+namespace gfan{
+class Rational
+{
+  mpq_t value;
+public:
+  static bool isField()
+  {
+    return true;
+  }
+  Rational()
+  {
+    mpq_init(value);
+  }
+  Rational(signed long int value_)
+  {
+    mpq_init(value);
+    mpz_set_si(mpq_numref(value), value_);
+    mpz_set_ui(mpq_denref(value), 1);
+    mpq_canonicalize(value);
+  }
+  Rational(Rational const & value_)
+  {
+    mpq_init(value);
+    mpq_set(value,value_.value);
+  }
+  Rational(mpq_t value_)
+  {
+    mpq_init(value);
+    mpq_set(value,value_);
+  }
+  explicit Rational(Integer const & value_)
+  {
+    mpq_init(value);
+    mpz_set(mpq_numref(value), value_.value);
+    mpz_set_ui(mpq_denref(value), 1);
+    mpq_canonicalize(value);
+  }
+  ~Rational()
+  {
+    mpq_clear(value);
+  }
+  Rational& operator=(const Rational& a)
+    {
+      const Rational *A=(const Rational*)&a;
+      if (this != A) {
+        mpq_clear(value);
+        mpq_init(value);
+        mpq_set(value,a.value);
+      }
+      return *this;
+    }
+  bool isZero()const{
+    return mpz_sgn(mpq_numref(value))==0;
+  }
+  friend std::ostream &operator<<(std::ostream &f, Rational const &a)
+  {
+    void (*freefunc)(void *, size_t);
+    mp_get_memory_functions(0,0,&freefunc);
+    char *str=mpq_get_str(0,10,a.value);
+    f<<str;
+    freefunc(str,strlen(str)+1);
+    return f;
+  }
+  Rational& operator+=(const Rational& a)
+    {
+      mpq_add(value,value,a.value);
+      return *this;
+    }
+  Rational& operator-=(const Rational& a)
+    {
+      mpq_sub(value,value,a.value);
+      return *this;
+    }
+  Rational& operator*=(const Rational& a)
+    {
+      mpq_mul(value,value,a.value);
+      return *this;
+    }
+  Rational& operator/=(const Rational& a)
+    {
+      assert(!a.isZero());
+      mpq_div(value,value,a.value);
+      return *this;
+    }
+  friend Rational operator-(const Rational &b)
+  {
+    Rational ret;
+    ret-=b;
+    return ret;
+  }
+  Rational operator+(const Rational &a)const
+  {
+    Rational ret(*this);
+    ret+=a;
+    return ret;
+  }
+  Rational operator-(const Rational &a)const
+  {
+    Rational ret(*this);
+    ret-=a;
+    return ret;
+  }
+  Rational operator*(const Rational &a)const
+  {
+    Rational ret(*this);
+    ret*=a;
+    return ret;
+  }
+  Rational operator/(const Rational &a)const
+  {
+    Rational ret(*this);
+    ret/=a;
+    return ret;
+  }
+  void madd(const Rational &a,const Rational &b)
+    {
+      mpq_t temp;
+      mpq_init(temp);
+      mpq_mul(temp,a.value,b.value);
+      mpq_add(value,value,temp);
+      mpq_clear(temp);
+    }
+  bool operator<(const Rational &a)const
+  {
+    return mpq_cmp(value,a.value)<0;
+  }
+  bool operator==(const Rational &a)const
+  {
+    return mpq_cmp(value,a.value)==0;
+  }
+  bool operator!=(const Rational &a)const
+  {
+    return mpq_cmp(value,a.value)!=0;
+  }
+  /**
+   * Returns +1,-1, or 0.
+   */
+  int sign()const
+  {
+    return mpq_sgn(value);
+  }
+  static Rational gcd(Rational const &a, Rational const /*&b*/, Rational /*&s*/, Rational /*t*/)
+  {
+/*    mpz_t r;
+    mpz_init(r);
+    mpz_gcdext(r,s.value,t.value,a.value,b.value);
+    Integer ret(r);
+    mpz_clear(r);*/
+    assert(0);
+    return a;
+  }
+  /**
+   * Assigns the value to q. q must have been initialized as a gmp variable.
+   */
+  void setGmp(mpq_t q)const
+  {
+    mpq_set(q,value);
+  }
+};
+
+
+}
+
+#endif /* LIB_Q_H_ */
diff --git a/gfanlib/gfanlib_symmetriccomplex.cpp b/gfanlib/gfanlib_symmetriccomplex.cpp
new file mode 100644
index 0000000..05e4cbe
--- /dev/null
+++ b/gfanlib/gfanlib_symmetriccomplex.cpp
@@ -0,0 +1,697 @@
+/*
+ * gfanlib_symmetriccomplex.cpp
+ *
+ *  Created on: Nov 16, 2010
+ *      Author: anders
+ */
+
+#include "gfanlib_symmetriccomplex.h"
+#include "gfanlib_polymakefile.h"
+
+#include <sstream>
+#include <iostream>
+
+namespace gfan{
+
+SymmetricComplex::Cone::Cone(std::set<int> const &indices_, int dimension_, Integer multiplicity_, bool sortWithSymmetry, SymmetricComplex const &complex):
+  isKnownToBeNonMaximalFlag(false),
+  dimension(dimension_),
+  multiplicity(multiplicity_),
+  sortKeyPermutation(complex.n)
+{
+  indices=IntVector(indices_.size());
+  int j=0;
+  for(std::set<int>::const_iterator i=indices_.begin();i!=indices_.end();i++,j++)
+    indices[j]=*i;
+
+  ZMatrix const &vertices=complex.getVertices();
+  ZVector sum(vertices.getWidth());
+  for(unsigned i=0;i<indices.size();i++)
+    sum+=vertices[indices[i]];
+
+  if(sortWithSymmetry)
+    {
+      sortKey=complex.sym.orbitRepresentative(sum,&sortKeyPermutation);
+    }
+  else
+    {
+      sortKey=sum;
+    }
+}
+
+
+int SymmetricComplex::indexOfVertex(ZVector const &v)const
+{
+//  std::cerr<<v<<std::endl<<"In";
+//  for(std::map<ZVector,int>::const_iterator i =indexMap.begin();i!=indexMap.end();i++)std::cerr<<i->first;
+
+  std::map<ZVector,int>::const_iterator it=indexMap.find(v);
+  assert(it!=indexMap.end());
+  return it->second;
+}
+
+
+void SymmetricComplex::Cone::remap(SymmetricComplex &complex)
+{
+  ZMatrix const &vertices=complex.getVertices();
+  ZVector sum(vertices.getWidth());
+  for(unsigned i=0;i<indices.size();i++)
+    sum+=vertices[indices[i]];
+
+  int n=sum.size();
+  Permutation const &bestPermutation=sortKeyPermutation;
+
+  assert((int)bestPermutation.size()==n);
+
+  IntVector indicesNew(indices.size());
+  int I=0;
+  for(unsigned i=0;i<indices.size();i++,I++)
+    {
+      ZVector ny=bestPermutation.apply(complex.vertices[indices[i]]);
+      std::map<ZVector,int>::const_iterator it=complex.indexMap.find(ny);
+      assert(it!=complex.indexMap.end());
+      indicesNew[I]=it->second;
+    }
+  indices=indicesNew;
+}
+
+
+std::set<int> SymmetricComplex::Cone::indexSet()const
+{
+  std::set<int> ret;
+  for(unsigned i=0;i<indices.size();i++)
+    ret.insert(indices[i]);
+
+  return ret;
+}
+
+bool SymmetricComplex::Cone::isSubsetOf(Cone const &c)const
+{
+  int next=0;
+  for(unsigned i=0;i<indices.size();i++)
+    {
+      while(1)
+        {
+          if(next>=(int)c.indices.size())return false;
+          if(indices[i]==c.indices[next])break;
+          next++;
+        }
+    }
+  return true;
+}
+
+
+SymmetricComplex::Cone SymmetricComplex::Cone::permuted(Permutation const &permutation, SymmetricComplex const &complex, bool withSymmetry)const
+{
+  std::set<int> r;
+  for(unsigned i=0;i<indices.size();i++)
+    {
+      ZVector ny=permutation.apply(complex.vertices[indices[i]]);
+      std::map<ZVector,int>::const_iterator it=complex.indexMap.find(ny);
+      if(it==complex.indexMap.end())
+        {
+//          AsciiPrinter(Stderr).printVector(complex.vertices[indices[i]]);
+//          AsciiPrinter(Stderr).printVector(ny);
+
+          assert(0);
+        }
+      r.insert(it->second);
+    }
+
+
+  return Cone(r,dimension,multiplicity,withSymmetry,complex);
+}
+
+
+bool SymmetricComplex::Cone::operator<(Cone const & b)const
+{
+  return sortKey<b.sortKey;
+}
+
+
+bool SymmetricComplex::Cone::isSimplicial(int linealityDim)const
+{
+  return (indices.size()+linealityDim)==dimension;
+}
+
+
+ZMatrix SymmetricComplex::Cone::orthogonalComplement(SymmetricComplex &complex)const
+{
+  ZMatrix l;
+  for(unsigned i=0;i<indices.size();i++)
+    l.appendRow(complex.vertices[indices[i]]);
+
+  return l.reduceAndComputeKernel();
+//  FieldMatrix m=integerMatrixToFieldMatrix(rowsToIntegerMatrix(l,complex.n),Q);
+//  return fieldMatrixToIntegerMatrixPrimitive(m.reduceAndComputeKernel()).getRows();
+}
+
+
+SymmetricComplex::SymmetricComplex(ZMatrix const &rays, ZMatrix const &linealitySpace_, SymmetryGroup const &sym_):
+  n(rays.getWidth()),
+  linealitySpace(canonicalizeSubspace(linealitySpace_)),
+  sym(sym_),
+  dimension(-1)
+{
+  assert(rays.getWidth()==linealitySpace.getWidth());
+//  vertices=rowsToIntegerMatrix(v,n);
+  vertices=rays;
+
+  for(int i=0;i<vertices.getHeight();i++)indexMap[vertices[i]]=i;
+}
+
+
+bool SymmetricComplex::contains(Cone const &c)const
+{
+  Cone temp=c;
+  return cones.find(temp)!=cones.end();///////////////////!!!!!!!!!!!!!!!!!!!!!!!
+}
+
+
+void SymmetricComplex::insert(Cone const &c)
+{
+        if(c.dimension>dimension)dimension=c.dimension;
+  if(!contains(c))//#2
+    {
+      cones.insert(c);
+    }
+  else
+    {
+      if(c.isKnownToBeNonMaximal()){cones.erase(c);cones.insert(c);}// mark as non-maximal
+    }
+}
+
+
+int SymmetricComplex::getMaxDim()const
+{
+  return dimension;
+}
+
+
+int SymmetricComplex::getMinDim()const
+{
+  int ret=100000;
+  for(ConeContainer::const_iterator i=cones.begin();i!=cones.end();i++)
+    {
+      if(i->dimension<ret)ret=i->dimension;
+    }
+  return ret;
+}
+
+
+int SymmetricComplex::getLinDim()const
+{
+  ZMatrix zm=linealitySpace;
+  return zm.reduceAndComputeRank();
+}
+
+bool SymmetricComplex::isMaximal(Cone const &c)const
+{
+  if(c.isKnownToBeNonMaximal())return false;
+  if(c.dimension==dimension)return true;
+  for(SymmetryGroup::ElementContainer::const_iterator k=sym.elements.begin();k!=sym.elements.end();k++)
+    {
+      Cone c2=c.permuted(*k,*this,false);
+      for(ConeContainer::const_iterator i=cones.begin();i!=cones.end();i++)
+        {
+          if(i->dimension>c.dimension)
+            if(c2.isSubsetOf(*i) && !i->isSubsetOf(c2))return false;
+        }
+    }
+  return true;
+}
+
+#if 0
+IntVector SymmetricComplex::dimensionsAtInfinity()const
+{
+  /* Using a double description like method this routine computes the
+     dimension of the intersection of each cone in the complex with
+     the plane x_0=0 */
+  IntVector ret(cones.size());
+
+  int I=0;
+  for(ConeContainer::const_iterator i=cones.begin();i!=cones.end();i++,I++)
+    {
+      ZMatrix raysAtInfinity;
+      for(int j=0;j<i->indices.size();j++)
+        {
+          if(vertices[i->indices[j]][0]==0)raysAtInfinity.push_back(vertices[i->indices[j]]);
+          for(vector<int>::const_iterator k=j;k!=i->indices.end();k++)
+            if(vertices[*j][0]*vertices[*k][0]<0)
+              raysAtInfinity.push_back(((vertices[*j][0]>0)?1:-1)*(vertices[*j][0])*vertices[*k]+
+                                       ((vertices[*k][0]>0)?1:-1)*(vertices[*k][0])*vertices[*j]);
+        }
+      ret[I]=rankOfMatrix(raysAtInfinity);
+    }
+  return ret;
+}
+#endif
+
+void SymmetricComplex::buildConeLists(bool onlyMaximal, bool compressed, std::vector<std::vector<IntVector > >*conelist/*, ZMatrix *multiplicities*/)const
+{
+  int dimLow=this->linealitySpace.getHeight();
+  int dimHigh=this->getMaxDim();
+  if(dimHigh<dimLow)dimHigh=dimLow-1;
+  if(conelist)*conelist=std::vector<std::vector<IntVector> >(dimHigh-dimLow+1);
+  for(int d=dimLow;d<=dimHigh;d++)
+    {
+      int numberOfOrbitsOutput=0;
+      int numberOfOrbitsOfThisDimension=0;
+      // bool newDimension=true;
+        {
+          int I=0;
+          for(ConeContainer::const_iterator i=cones.begin();i!=cones.end();i++,I++)
+            if(i->dimension==d)
+            {
+              numberOfOrbitsOfThisDimension++;
+              if(!onlyMaximal || isMaximal(*i))
+                {
+                  numberOfOrbitsOutput++;
+                  // bool isMax=isMaximal(*i);
+                  // bool newOrbit=true;
+                  std::set<std::set<int> > temp;
+                  for(SymmetryGroup::ElementContainer::const_iterator k=sym.elements.begin();k!=sym.elements.end();k++)
+                    {
+                        Cone temp1=i->permuted(*k,*this,false);
+                        temp.insert(temp1.indexSet());
+                        if(compressed)break;
+                    }
+                  for(std::set<std::set<int> >::const_iterator j=temp.begin();j!=temp.end();j++)
+                    {
+                      IntVector temp;
+                      for(std::set<int>::const_iterator k=j->begin();k!=j->end();k++)temp.push_back(*k);
+                      if(conelist)(*conelist)[d-dimLow].push_back(temp);
+ /*                     if(isMax)if(multiplicities)
+                        {
+
+                          *multiplicities << i->multiplicity;
+                          if(group)if(newOrbit)*multiplicities << "\t# New orbit";
+                          if(newDimension)*multiplicities << "\t# Dimension "<<d;
+                          *multiplicities << std::endl;
+                        }*/
+                      // newOrbit=false;
+                      // newDimension=false;
+                    }
+                }
+            }
+        }
+    }
+
+}
+
+std::string SymmetricComplex::toStringJustCones(int dimLow, int dimHigh, bool onlyMaximal, bool group, std::ostream *multiplicities, bool compressed, bool /*tPlaneSort*/)const
+{
+  std::stringstream ret;
+
+  ZVector additionalSortKeys(cones.size());
+//  if(tPlaneSort)additionalSortKeys=dimensionsAtInfinity();
+//  Integer lowKey=additionalSortKeys.min();
+//  Integer highKey=additionalSortKeys.max();
+
+  for(int d=dimLow;d<=dimHigh;d++)
+    {
+      int numberOfOrbitsOutput=0;
+      int numberOfOrbitsOfThisDimension=0;
+      bool newDimension=true;
+ //     for(int key=lowKey;key<=highKey;key++)
+        {
+          int I=0;
+          for(ConeContainer::const_iterator i=cones.begin();i!=cones.end();i++,I++)
+ //           if(additionalSortKeys[I]==key)
+                  if(i->dimension==d)
+                    {
+                      numberOfOrbitsOfThisDimension++;
+              if(!onlyMaximal || isMaximal(*i))
+                {
+                  numberOfOrbitsOutput++;
+                  bool isMax=isMaximal(*i);
+                  bool newOrbit=true;
+                  std::set<std::set<int> > temp;
+                    for(SymmetryGroup::ElementContainer::const_iterator k=sym.elements.begin();k!=sym.elements.end();k++)
+                      {
+                        Cone temp1=i->permuted(*k,*this,false);
+                        temp.insert(temp1.indexSet());
+                        if(compressed)break;
+                    }
+                  for(std::set<std::set<int> >::const_iterator j=temp.begin();j!=temp.end();j++)
+                    {
+                      ret << "{";
+                      for(std::set<int>::const_iterator a=j->begin();a!=j->end();a++)
+                        {
+                          if(a!=j->begin())ret<<" ";
+                          ret << *a;
+                        }
+                      ret << "}";
+                      if(group)if(newOrbit)ret << "\t# New orbit";
+                      if(newDimension)ret << "\t# Dimension "<<d;
+                      ret <<std::endl;
+                      if(isMax)if(multiplicities)
+                        {
+                          *multiplicities << i->multiplicity;
+                          if(group)if(newOrbit)*multiplicities << "\t# New orbit";
+                          if(newDimension)*multiplicities << "\t# Dimension "<<d;
+                          *multiplicities << std::endl;
+                        }
+                      newOrbit=false;
+                      newDimension=false;
+                    }
+              }
+                    }
+        }
+    }
+
+  return ret.str();
+}
+
+
+std::string SymmetricComplex::toStringJustRaysAndMaximalCones(int flags)const
+{
+  PolymakeFile polymakeFile;
+  polymakeFile.create("NONAME","PolyhedralFan","PolyhedralFan",flags&FPF_xml);
+  polymakeFile.writeMatrixProperty("RAYS",vertices,true);
+  polymakeFile.writeStringProperty("MAXIMAL_CONES",toStringJustCones(getMinDim(),getMaxDim(),true,flags&FPF_group, 0,false,flags&FPF_tPlaneSort));
+
+  std::stringstream s;
+  polymakeFile.writeStream(s);
+  return s.str();
+}
+
+
+ZVector SymmetricComplex::fvector(bool boundedPart)const
+{
+  int min=getMinDim();
+  int dimHigh=getMaxDim();
+  if(dimHigh<min)dimHigh=min-1;
+  ZVector ret(dimHigh-min+1);
+
+  for(ConeContainer::const_iterator i=cones.begin();i!=cones.end();i++)
+    {
+      bool doAdd=!boundedPart;
+      if(boundedPart)
+        {
+          bool isBounded=true;
+          for(unsigned j=0;j<i->indices.size();j++)
+            if(vertices[i->indices[j]][0].sign()==0)isBounded=false;
+          doAdd=isBounded;
+        }
+      if(doAdd)
+        ret[i->dimension-min]+=Integer(sym.orbitSize(i->sortKey));
+    }
+  return ret;
+}
+
+
+bool SymmetricComplex::isPure()const
+{
+  int dim=-1;
+  for(ConeContainer::const_iterator i=cones.begin();i!=cones.end();i++)
+    {
+      if(isMaximal(*i))
+        {
+          int dim2=i->dimension;
+          if(dim==-1)dim=dim2;
+          if(dim!=dim2)return false;
+        }
+    }
+  return true;
+}
+
+
+bool SymmetricComplex::isSimplicial()const
+{
+  int linealityDim=getMinDim();
+  for(ConeContainer::const_iterator i=cones.begin();i!=cones.end();i++)
+    if(!i->isSimplicial(linealityDim))
+      return false;
+  return true;
+}
+
+
+void SymmetricComplex::remap()
+{
+  for(ConeContainer::iterator i=cones.begin();i!=cones.end();i++)
+    {
+      Cone const&j=*i;
+      Cone &j2=const_cast<Cone&>(j);//DANGER: cast away const. This does not change the sort key in the container, so should be OK.
+      j2.remap(*this);
+    }
+}
+
+
+int SymmetricComplex::numberOfConesOfDimension(int d)const
+{
+  assert(sym.isTrivial());
+
+  int ret=0;
+  for(ConeContainer::const_iterator i=cones.begin();i!=cones.end();i++)
+    if(d==i->dimension)
+      {
+        ret++;
+      }
+  return ret;
+}
+
+
+int SymmetricComplex::dimensionIndex(Cone const &c)
+{
+  assert(sym.isTrivial());
+
+  int ret=0;
+  for(ConeContainer::const_iterator i=cones.begin();i!=cones.end();i++)
+    if(c.dimension==i->dimension)
+      {
+        if(!(c<*i)&&!(*i<c))
+          return ret;
+        else
+          ret++;
+      }
+  return ret;
+}
+
+#if 0
+void SymmetricComplex::boundary(Cone const &c, vector<int> &indices_, vector<int> &signs)
+{
+  indices_=vector<int>();
+  signs=vector<int>();
+  int d=c.dimension;
+
+
+  IntegerVectorList l;
+  for(int i=0;i<c.indices.size();i++)
+    l.push_back(vertices[c.indices[i]]);
+  IntegerVectorList facetNormals=PolyhedralCone(l,IntegerVectorList(),n).extremeRays();
+  IntegerVectorList complementBasis=c.orthogonalComplement(*this);
+  for(IntegerVectorList::const_iterator i=facetNormals.begin();i!=facetNormals.end();i++)
+    {
+      IntegerVectorList complementBasis1=complementBasis;
+      complementBasis1.push_back(*i);
+      FieldMatrix m=integerMatrixToFieldMatrix(rowsToIntegerMatrix(complementBasis1,n),Q);
+      IntegerVectorList completion=fieldMatrixToIntegerMatrixPrimitive(m.reduceAndComputeKernel()).getRows();
+      for(IntegerVectorList::const_iterator j=completion.begin();j!=completion.end();j++)complementBasis1.push_back(*j);
+      int sign=determinantSign(complementBasis1);
+
+      set<int> indices;
+      for(vector<int>::const_iterator j=c.indices.begin();j!=c.indices.end();j++)if(dotLong(vertices[*j],*i)==0)indices.insert(*j);
+      Cone facet(indices,d-1,1,true,*this);
+      IntegerVectorList complementBasis2=facet.orthogonalComplement(*this);
+      for(IntegerVectorList::const_iterator j=completion.begin();j!=completion.end();j++)complementBasis2.push_back(*j);
+      indices_.push_back(dimensionIndex(facet));
+      signs.push_back(sign*determinantSign(complementBasis2));
+    }
+}
+
+
+IntegerMatrix SymmetricComplex::boundaryMap(int d)
+{
+  assert(sym.isTrivial());
+
+  IntegerMatrix ret(numberOfConesOfDimension(d-1),numberOfConesOfDimension(d));
+
+  for(ConeContainer::const_iterator i=cones.begin();i!=cones.end();i++)
+    if(d==i->dimension)
+      {
+        int I=dimensionIndex(*i);
+        vector<int> indices;
+        vector<int> signs;
+        boundary(*i,indices,signs);
+        for(int j=0;j<indices.size();j++)
+          {
+              ret[indices[j]][I]+=signs[j];
+          }
+      }
+  return ret;
+}
+#endif
+
+
+  std::string SymmetricComplex::toString(int flags)const
+  {
+    PolymakeFile polymakeFile;
+    polymakeFile.create("NONAME","PolyhedralFan","PolyhedralFan",flags&FPF_xml);
+
+
+
+
+
+    polymakeFile.writeCardinalProperty("AMBIENT_DIM",n);
+    polymakeFile.writeCardinalProperty("DIM",getMaxDim());
+    polymakeFile.writeCardinalProperty("LINEALITY_DIM",linealitySpace.getHeight());
+    //    polymakeFile.writeMatrixProperty("RAYS",rays,true,comments);
+    polymakeFile.writeMatrixProperty("RAYS",vertices,true);
+    polymakeFile.writeCardinalProperty("N_RAYS",vertices.getHeight());
+
+
+    polymakeFile.writeMatrixProperty("LINEALITY_SPACE",linealitySpace,n);
+    polymakeFile.writeMatrixProperty("ORTH_LINEALITY_SPACE",kernel(linealitySpace),n);
+
+/*
+    if(flags & FPF_primitiveRays)
+    {
+      ZMatrix primitiveRays;
+      for(int i=0;i<rays.getHeight();i++)
+        for(PolyhedralConeList::const_iterator j=cones.begin();j!=cones.end();j++)
+          if(j->contains(*i)&&(j->dimensionOfLinealitySpace()+1==j->dimension()))
+            primitiveRays.push_back(j->semiGroupGeneratorOfRay());
+
+      polymakeFile.writeMatrixProperty("PRIMITIVE_RAYS",rowsToIntegerMatrix(primitiveRays,n));
+    }
+*/
+#if 0
+    ZMatrix generatorsOfLinealitySpace=cones.begin()->generatorsOfLinealitySpace();
+
+    log1 fprintf(Stderr,"Building symmetric complex.\n");
+    for(PolyhedralConeList::const_iterator i=cones.begin();i!=cones.end();i++)
+      {
+        {
+          static int t;
+  //        log1 fprintf(Stderr,"Adding faces of cone %i\n",t++);
+        }
+  //      log2 fprintf(Stderr,"Dim: %i\n",i->dimension());
+
+        addFacesToSymmetricComplex(symCom,*i,i->getHalfSpaces(),generatorsOfLinealitySpace);
+      }
+
+  //  log1 cerr<<"Remapping";
+    symCom.remap();
+  //  log1 cerr<<"Done remapping";
+
+
+    PolyhedralFan f=*this;
+#endif
+
+  //  log1 fprintf(Stderr,"Computing f-vector.\n");
+    ZVector fvector=this->fvector();
+    polymakeFile.writeCardinalVectorProperty("F_VECTOR",fvector);
+  //  log1 fprintf(Stderr,"Done computing f-vector.\n");
+
+    if(flags&FPF_boundedInfo)
+      {
+  //      log1 fprintf(Stderr,"Computing bounded f-vector.\n");
+        ZVector fvectorBounded=this->fvector(true);
+        polymakeFile.writeCardinalVectorProperty("F_VECTOR_BOUNDED",fvectorBounded);
+  //      log1 fprintf(Stderr,"Done computing bounded f-vector.\n");
+      }
+#if 0
+    {
+      Integer euler;
+      int mul=-1;
+      for(int i=0;i<fvector.size();i++,mul*=-1)euler+=Integer(mul)*fvector[i];
+      polymakeFile.writeCardinalProperty("MY_EULER",euler);
+    }
+#endif
+  //  log1 fprintf(Stderr,"Checking if complex is simplicial and pure.\n");
+    polymakeFile.writeCardinalProperty("SIMPLICIAL",isSimplicial());
+    polymakeFile.writeCardinalProperty("PURE",isPure());
+  //  log1 fprintf(Stderr,"Done checking.\n");
+
+
+    polymakeFile.writeStringProperty("CONES",toStringJustCones(getMinDim(),getMaxDim(),false,flags&FPF_group, 0,false,flags&FPF_tPlaneSort));
+    polymakeFile.writeStringProperty("MAXIMAL_CONES",toStringJustCones(getMinDim(),getMaxDim(),true,flags&FPF_group, 0,false,flags&FPF_tPlaneSort));
+    polymakeFile.writeStringProperty("CONES_ORBITS",toStringJustCones(getMinDim(),getMaxDim(),false,flags&FPF_group, 0,true,flags&FPF_tPlaneSort));
+    polymakeFile.writeStringProperty("MAXIMAL_CONES_ORBITS",toStringJustCones(getMinDim(),getMaxDim(),true,flags&FPF_group, 0,true,flags&FPF_tPlaneSort));
+
+    if(!sym.isTrivial())
+      {
+        polymakeFile.writeMatrixProperty("SYMMETRY_GENERATORS",IntToZMatrix(sym.getGenerators()));
+      }
+
+    std::stringstream s;
+    polymakeFile.writeStream(s);
+    return s.str();
+
+    #if 0
+
+    if(flags&FPF_conesCompressed)
+    {
+  //    log1 fprintf(Stderr,"Producing list of cones up to symmetry.\n");
+      polymakeFile.writeStringProperty("CONES_ORBITS",symCom.toString(symCom.getMinDim(),symCom.getMaxDim(),false,flags&FPF_group,0,true,flags&FPF_tPlaneSort));
+  //    log1 fprintf(Stderr,"Done producing list of cones up to symmetry.\n");
+  //    log1 fprintf(Stderr,"Producing list of maximal cones up to symmetry.\n");
+      stringstream multiplicities;
+      polymakeFile.writeStringProperty("MAXIMAL_CONES_ORBITS",symCom.toString(symCom.getMinDim(),symCom.getMaxDim(),true,flags&FPF_group, &multiplicities,true,flags&FPF_tPlaneSort));
+      if(flags&FPF_multiplicities)polymakeFile.writeStringProperty("MULTIPLICITIES_ORBITS",multiplicities.str());
+  //    log1 fprintf(Stderr,"Done producing list of maximal cones up to symmetry.\n");
+    }
+
+    if(flags&FPF_conesExpanded)
+      {
+        if(flags&FPF_cones)
+          {
+  //          log1 fprintf(Stderr,"Producing list of cones.\n");
+            polymakeFile.writeStringProperty("CONES",symCom.toString(symCom.getMinDim(),symCom.getMaxDim(),false,flags&FPF_group,0,false,flags&FPF_tPlaneSort));
+  //          log1 fprintf(Stderr,"Done producing list of cones.\n");
+          }
+        if(flags&FPF_maximalCones)
+          {
+  //          log1 fprintf(Stderr,"Producing list of maximal cones.\n");
+            stringstream multiplicities;
+            polymakeFile.writeStringProperty("MAXIMAL_CONES",symCom.toString(symCom.getMinDim(),symCom.getMaxDim(),true,flags&FPF_group, &multiplicities,false,flags&FPF_tPlaneSort));
+            if(flags&FPF_multiplicities)polymakeFile.writeStringProperty("MULTIPLICITIES",multiplicities.str());
+  //          log1 fprintf(Stderr,"Done producing list of maximal cones.\n");
+          }
+      }
+  #endif
+    #if 0
+    if(flags&FPF_values)
+      {
+        {
+          ZMatrix values;
+          for(int i=0;i<linealitySpaceGenerators.getHeight();i++)
+            {
+              ZVector v(1);
+              v[0]=evaluatePiecewiseLinearFunction(linealitySpaceGenerators[i]);
+              values.appendRow(v);
+            }
+          polymakeFile.writeMatrixProperty("LINEALITY_VALUES",rowsToIntegerMatrix(values,1));
+        }
+        {
+          ZMatrix values;
+          for(IntegerVectorList::const_iterator i=rays.begin();i!=rays.end();i++)
+            {
+              ZVector v(1);
+              v[0]=evaluatePiecewiseLinearFunction(*i);
+              values.push_back(v);
+            }
+          polymakeFile.writeMatrixProperty("RAY_VALUES",rowsToIntegerMatrix(values,1));
+        }
+      }
+  #endif
+
+
+  //  log1 fprintf(Stderr,"Producing final string for output.\n");
+  /*  stringstream s;
+    polymakeFile.writeStream(s);
+    string S=s.str();
+  //  log1 fprintf(Stderr,"Printing string.\n");
+    p->printString(S.c_str());
+  *///  log1 fprintf(Stderr,"Done printing string.\n");
+  }
+
+  ZCone SymmetricComplex::makeZCone(IntVector const &indices)const
+  {
+    ZMatrix generators(indices.size(),getAmbientDimension());
+    for(unsigned i=0;i<indices.size();i++)
+      generators[i]=vertices[indices[i]];
+    return ZCone::givenByRays(generators,linealitySpace);
+  }
+}
diff --git a/gfanlib/gfanlib_symmetriccomplex.h b/gfanlib/gfanlib_symmetriccomplex.h
new file mode 100644
index 0000000..28f92c8
--- /dev/null
+++ b/gfanlib/gfanlib_symmetriccomplex.h
@@ -0,0 +1,122 @@
+/*
+ * gfanlib_symmetriccomplex.h
+ *
+ *  Created on: Nov 16, 2010
+ *      Author: anders
+ */
+
+#ifndef GFANLIB_SYMMETRICCOMPLEX_H_INCLUDED
+#define GFANLIB_SYMMETRICCOMPLEX_H_INCLUDED
+
+#include <set>
+#include <string>
+#include <map>
+
+#include "gfanlib_symmetry.h"
+#include "gfanlib_matrix.h"
+#include "gfanlib_zcone.h"
+
+namespace gfan{
+  enum FanPrintingFlags{
+    FPF_conesCompressed=1,
+    FPF_conesExpanded=2,
+    FPF_cones=4,
+    FPF_maximalCones=8,
+    FPF_boundedInfo=16,
+    FPF_values=32,
+    FPF_group=64,
+    FPF_multiplicities=128,
+    FPF_xml=256,
+    FPF_tPlaneSort=512,
+    FPF_primitiveRays=1024,
+
+    FPF_default=2+4+8
+  };
+
+  class SymmetricComplex{
+  int n;
+  ZMatrix linealitySpace;
+  ZMatrix vertices;
+  std::map<ZVector,int> indexMap;
+  SymmetryGroup sym;
+  IntVector dimensionsAtInfinity()const;
+ public:
+   int getAmbientDimension()const{return n;}
+   class Cone
+  {
+    bool isKnownToBeNonMaximalFlag;
+  public:
+    IntVector indices;//always sorted
+    Cone(std::set<int> const &indices_, int dimension_, Integer multiplicity_, bool sortWithSymmetry, SymmetricComplex const &complex);
+    std::set<int> indexSet()const;
+    int dimension;
+    Integer multiplicity;
+    bool isKnownToBeNonMaximal()const{return isKnownToBeNonMaximalFlag;}
+    void setKnownToBeNonMaximal(){isKnownToBeNonMaximalFlag=true;}
+    bool isSubsetOf(Cone const &c)const;
+    SymmetricComplex::Cone permuted(Permutation const &permutation, SymmetricComplex const &complex, bool withSymmetry)const;
+    ZVector sortKey;
+    Permutation sortKeyPermutation;
+    bool operator<(const Cone & b)const;
+    bool isSimplicial(int linealityDim)const;
+    void remap(SymmetricComplex &complex);
+/**
+ * This routine computes a basis for the orthogonal complement of the cone.
+ * Notice that the lineality space, which is unknown at the time, is ignored.
+ * This routine is deterministic and used for orienting the faces when computing homology.
+ */
+    ZMatrix orthogonalComplement(SymmetricComplex &complex)const;
+  };
+  typedef std::set<Cone> ConeContainer;
+  ConeContainer cones;
+  int dimension;
+  SymmetricComplex(ZMatrix const &rays, ZMatrix const &linealitySpace, SymmetryGroup const &sym_);
+  /**
+   * Returns a reference to the matrix of vertices on which the complex is build.
+   * The reference is valid as the Symmetric complex object exists.
+   */
+  ZMatrix const &getVertices()const{return vertices;}
+  bool contains(Cone const &c)const;
+  void insert(Cone const &c);
+  int getMaxDim()const;
+  int getMinDim()const;
+  int getLinDim()const;
+  bool isMaximal(Cone const &c)const;
+  bool isPure()const;
+  ZVector fvector(bool boundedPart=false)const;
+  void buildConeLists(bool onlyMaximal, bool compressed, std::vector<std::vector<IntVector > >*conelist/*, ZMatrix *multiplicities*/)const;
+  std::string toStringJustCones(int dimLow, int dimHigh, bool onlyMaximal, bool group, std::ostream *multiplicities=0, bool compressed=false, bool tPlaneSort=false)const;
+  std::string toStringJustRaysAndMaximalCones(int flags=0)const;
+  std::string toString(int flags=0)const;
+  bool isSimplicial()const;
+  /**
+     Calling this function will change the representative of each cone
+     orbit by "applying" the permutation which will give the sortkey to
+     the set of indices of the cone.
+   */
+  void remap();
+  /**
+   * Looks up the index of the vector among the vertices.
+   */
+  int indexOfVertex(ZVector const &v)const;
+  int numberOfConesOfDimension(int d)const;
+  /**
+   * Given a cone this returns its index among all cones of that dimension.
+   * Used for assigning "names" to cones.
+   */
+  int dimensionIndex(Cone const &c);
+#if 0
+  /**
+   * This routine is used for constructing the boundary map for homology computations.
+   */
+  void boundary(Cone const &c, IntVector &indices, IntVector &signs);
+/**
+ * This routine computes the ith boundary map for homology as a matrix.
+ */
+  ZMatrix boundaryMap(int i);
+#endif
+  ZCone makeZCone(IntVector const &indices)const;
+};
+}
+
+#endif
diff --git a/gfanlib/gfanlib_symmetry.cpp b/gfanlib/gfanlib_symmetry.cpp
new file mode 100644
index 0000000..cdce12c
--- /dev/null
+++ b/gfanlib/gfanlib_symmetry.cpp
@@ -0,0 +1,511 @@
+/*
+ * gfanlib_symmetry.cpp
+ *
+ *  Created on: Oct 22, 2010
+ *      Author: anders
+ */
+
+#include "gfanlib_symmetry.h"
+#include <map>
+
+using namespace std;
+
+namespace gfan{
+class Trie
+{
+        class TrieNode
+        {
+                typedef map<int,class TrieNode> Map;
+                Map m;
+        public:
+                TrieNode()
+                {
+
+                }
+                TrieNode(IntVector const &v, int i)
+                {
+                  if(i<(int)v.size())
+                        m[v[i]]=TrieNode(v,i+1);
+                }
+                int stabilizerSize(ZVector const &v, int i)const
+                {
+                  int ret=0;
+                  if(i==(int)v.size())return 1;
+                  for(Map::const_iterator j=m.begin();j!=m.end();j++)
+                    {
+                      if(v[i]==v[j->first])
+                        ret+=j->second.stabilizerSize(v,i+1);
+                    }
+                  return ret;
+                }
+                void search(ZVector const &v, ZVector  &building, Permutation &tempPerm, Permutation &ret, ZVector &optimal, int i, bool &isImproving)const
+                {
+                  if(i==(int)v.size()){ret=tempPerm;optimal=building;isImproving=false;return;}
+                        if(isImproving)
+                                building[i]=-0x7fffffff;
+                        else
+                                building[i]=optimal[i];
+                        for(Map::const_iterator j=m.begin();j!=m.end();j++)
+                                if(building[i]<v[j->first])
+                                {
+                                        isImproving=true;
+                                        building[i]=v[j->first];
+                                }
+                                for(Map::const_iterator j=m.begin();j!=m.end();j++)
+                                if(v[j->first]==building[i])
+                                {
+                                        tempPerm[i]=j->first;
+                                        j->second.search(v,building,tempPerm,ret,optimal,i+1,isImproving);
+                                }
+                }
+                void searchStabalizer(ZVector const &v, ZVector  &building, Permutation &tempPerm, Permutation &ret, ZVector &optimal, int i, bool &isImproving, ZVector const &toBeFixed)const
+                {
+                  if(i==(int)v.size())
+                                if(!(tempPerm.apply(v)<optimal))
+                                        {
+                                        ret=tempPerm;
+                                        optimal=tempPerm.apply(v);
+                                        return;
+                                        }
+                                for(Map::const_iterator j=m.begin();j!=m.end();j++)
+                                        if(toBeFixed[i]==toBeFixed[j->first])
+                                {
+                                        tempPerm[i]=j->first;
+                                        j->second.searchStabalizer(v,building,tempPerm,ret,optimal,i+1,isImproving,toBeFixed);
+                                }
+                }
+/* this code contains mistakes          void searchStabalizer(IntegerVector const &v, IntegerVector  &building, IntegerVector &tempPerm, IntegerVector &ret, IntegerVector &optimal, int i, bool &isImproving, IntegerVector const &toBeFixed)const
+                {
+                        if(i==v.size()){ret=tempPerm;optimal=building;isImproving=false;debug<<"DEEP";return;}
+                        if(isImproving)
+                                building[i]=-0x7fffffff;
+                        else
+                                building[i]=optimal[i];
+                        for(Map::const_iterator j=m.begin();j!=m.end();j++)
+                                if(toBeFixed[i]==toBeFixed[j->first])
+                                if(v[j->first]>building[i])
+                                {
+                                        isImproving=true;
+                                        building[i]=v[j->first];
+                                }
+                                for(Map::const_iterator j=m.begin();j!=m.end();j++)
+                                        if(toBeFixed[i]==toBeFixed[j->first])
+                                if(v[j->first]==building[i])
+                                {
+                                        debug.printInteger(i);debug<<":";
+                                        debug.printInteger(j->first);debug<<" ";
+                                        tempPerm[i]=j->first;
+                                        j->second.searchStabalizer(v,building,tempPerm,ret,optimal,i+1,isImproving,toBeFixed);
+                                }
+                }*/
+        //      void doubleSearch();
+                void insert(Permutation const &v, int i)
+                {
+                  if(i==(int)v.size())return;
+                        if(m.count(v[i]))
+                                m[v[i]].insert(v,i+1);
+                        else
+                                m[v[i]]=                TrieNode(v,i+1);
+                }
+/*                void print(int i, int n)const
+                {
+                        if(i==n)return;
+                        for(Map::const_iterator j=m.begin();j!=m.end();j++)
+                        {
+                                {for(int j=0;j<2*i;j++)debug<<" ";}
+                                debug.printInteger(j->first);
+                                debug<<"\n";
+                                j->second.print(i+1,n);
+                        }
+                        }*/
+                int size(int i,int n)const
+                {
+                        if(i==n)return 1;
+                        int ret=0;
+                        for(Map::const_iterator j=m.begin();j!=m.end();j++)
+                                ret+=j->second.size(i+1,n);
+                        return ret;
+                }
+        };
+public:
+        TrieNode theTree;
+        int n;
+        Trie(int n_):
+                theTree(Permutation(n_),0),
+                n(n_)
+        {
+        }
+        int size()const
+        {
+                return theTree.size(0,n);
+        }
+        void insert(Permutation const &v)
+        {
+                theTree.insert(v,0);
+//              debug<<v;
+//              theTree.print(0,v.size());
+
+//              debug<<"---------------------------------------------\n";
+        }
+        /**
+         * returns the sigma from the set with sigma(v) maximal in the lexicographic ordering.
+         */
+        Permutation search(ZVector const &v)
+        {
+                Permutation tempPerm(v.size());
+                Permutation ret(v.size());
+                ZVector building(v.size());
+                ZVector optimal=v;//the identity is always in the trie
+                bool isImproving=true;
+                theTree.search(v,building,tempPerm,ret,optimal,0,isImproving);
+                return ret;
+        }
+        Permutation searchStabalizer(ZVector const &v, ZVector const &toBeFixed)
+        {
+                Permutation tempPerm(v.size());
+                Permutation ret(v.size());
+                ZVector building(v.size());
+                ZVector optimal=v;//the identity is always in the trie
+                bool isImproving=true;
+                theTree.searchStabalizer(v,building,tempPerm,ret,optimal,0,isImproving,toBeFixed);
+                return ret;
+        }
+        int stabilizerSize(ZVector const &v)const
+        {
+          return theTree.stabilizerSize(v,0);
+        }
+};
+
+
+
+
+
+
+
+/*IntegerVector SymmetryGroup::identity(int n)
+{
+  IntegerVector v(n);
+  for(int i=0;i<n;i++)v[i]=i;
+
+  return v;
+}
+*/
+
+Permutation Permutation::inverse()const
+{
+  return applyInverse(Permutation(size()));
+}
+
+
+SymmetryGroup::SymmetryGroup(int n):
+//  byteTable(0),
+  trie(0)
+{
+  elements.insert(Permutation(n));
+}
+
+
+int SymmetryGroup::sizeOfBaseSet()const
+{
+  assert(!elements.empty());
+  return elements.begin()->size();
+}
+
+IntMatrix SymmetryGroup::getGenerators()const
+{
+  IntMatrix ret(0,this->sizeOfBaseSet());
+  for(ElementContainer::const_iterator i=elements.begin();i!=elements.end();i++)ret.appendRow(i->toIntVector());
+  return ret;
+}
+
+void SymmetryGroup::computeClosure(Permutation const &v) //does this work??
+{
+  ElementContainer newOnes;
+
+  newOnes.insert(v);
+
+  while(!newOnes.empty())
+    {
+      Permutation v=*newOnes.begin();
+      for(ElementContainer::const_iterator i=elements.begin();i!=elements.end();i++)
+        {
+          {
+            Permutation n=i->apply(v);
+            if(0==elements.count(n))
+              newOnes.insert(n);
+          }
+          {
+            Permutation n=v.apply(v);
+            if(0==elements.count(n))
+              newOnes.insert(n);
+          }
+        }
+      newOnes.erase(v);
+      elements.insert(v);
+    }
+}
+
+
+void SymmetryGroup::computeClosure(IntMatrix const &l)
+{
+  for(int i=0;i<l.getHeight();i++)computeClosure(Permutation(l[i]));
+}
+
+
+/*
+void SymmetryGroup::print(FILE *f)
+{
+  AsciiPrinter P(f);
+  P.printString("Printing SymmetryGroup\n");
+  IntegerVectorList l;
+  for(ElementContainer::const_iterator i=elements.begin();i!=elements.end();i++)
+    {
+      //      P.printVector(*i);
+      //      P.printNewLine();
+      l.push_back(*i);
+    }
+  P.printVectorList(l);
+  fprintf(f,"Group order=%i\n",elements.size());
+  P.printString("Done printing SymmetryGroup.\n");
+}
+*/
+
+
+Permutation Permutation::apply(Permutation const &b)const
+{
+  IntVector ret(size());
+  assert(size()==b.size());
+  for(unsigned i=0;i<size();i++)ret[i]=b[(*this)[i]];
+  return Permutation(ret);
+}
+
+Permutation Permutation::applyInverse(Permutation const &b)const
+{
+  IntVector ret(size());
+  assert(size()==b.size());
+  for(unsigned i=0;i<size();i++)ret[(*this)[i]]=b[i];
+  return Permutation(ret);
+}
+
+IntVector Permutation::apply(IntVector const &v)const
+{
+  IntVector ret(size());
+  assert(size()==v.size());
+  for(unsigned i=0;i<size();i++)ret[i]=v[(*this)[i]];
+  return ret;
+}
+
+ZVector Permutation::apply(ZVector const &v)const
+{
+  ZVector ret(size());
+  assert(size()==v.size());
+  for(unsigned i=0;i<size();i++)ret[i]=v[(*this)[i]];
+  return ret;
+}
+
+
+ZVector Permutation::applyInverse(ZVector const &v)const
+{
+  ZVector ret(size());
+  assert(size()==v.size());
+  for(unsigned i=0;i<size();i++)ret[(*this)[i]]=v[i];
+  return ret;
+}
+//ZVector apply(ZVector const &v)const;
+//ZMatrix apply(ZMatrix const &m)const;
+//IntVector applyInverse(IntVector const &v)const;
+//ZMatrix applyInverse(ZMatrix const &m)const;
+
+ZVector SymmetryGroup::orbitRepresentative(ZVector const &v, Permutation *usedPermutation)const
+{
+  if(trie){
+    if(usedPermutation)
+      {
+        *usedPermutation=trie->search(v);
+        return usedPermutation->apply(v);
+      }
+    return trie->search(v).apply(v);
+  }
+  ZVector ret=v;
+  ElementContainer::const_iterator usedPerm;
+  for(ElementContainer::const_iterator i=elements.begin();i!=elements.end();i++)
+    {
+      ZVector q=i->apply(v);
+      if(! (q<ret))//negation to make sure that usedPerm is set
+        {
+          usedPerm=i;
+          ret=q;
+        }
+    }
+
+  if(usedPermutation)*usedPermutation=*usedPerm;
+
+  if(trie)
+  {
+//        debug<<"Input"<<v<<"\n";
+//        debug<<"Bruteforce"<<ret<<"\n";
+          Permutation triePerm=trie->search(v);
+//        debug<<"Trie"<<compose(triePerm,v)<<"\n";
+          assert((triePerm.apply(v)-ret).isZero());
+  }
+
+  return ret;
+}
+#if 0
+IntegerVector SymmetryGroup::orbitRepresentativeFixing(IntegerVector const &v, IntegerVector const &fixed)const
+{
+        if(trie){
+                return compose(trie->searchStabalizer(v,fixed),v);
+        }
+  IntegerVector ret=v;
+
+  for(ElementContainer::const_iterator i=elements.begin();i!=elements.end();i++)
+    if(compose(*i,fixed)==fixed)
+      {
+        IntegerVector q=compose(*i,v);
+        if(ret<q)ret=q;
+      }
+        if(trie){
+                IntegerVector temp=compose(trie->searchStabalizer(v,fixed),v);
+//              debug<<"Input"<<v;
+//              debug<<"Brute"<<ret;
+//              debug<<"Quick"<<temp;
+                assert((temp-ret).isZero());
+//              return compose(trie->searchStabalizer(v,fixed),v);
+        }
+  return ret;
+}
+#endif
+
+bool Permutation::isPermutation(IntVector const &a)
+{
+  int n=a.size();
+  IntVector temp(n);
+  for(int i=0;i<n;i++)temp[i]=-1;
+  for(int i=0;i<n;i++)
+    {
+      if(a[i]<0 || a[i]>=n)return false;
+      temp[i]=i;
+    }
+  for(int i=0;i<n;i++)if(temp[i]<0)return false;
+  return true;
+}
+
+
+bool Permutation::arePermutations(IntMatrix const &m)
+{
+  for(int i=0;i<m.getHeight();i++)if(!isPermutation(m[i]))return false;
+  return true;
+}
+
+int SymmetryGroup::orbitSize(ZVector const &stable)const
+{
+  int groupSize=elements.size();
+
+  int n=stable.size();
+  int numFixed=0;
+
+  if(trie)
+    {
+      numFixed=trie->stabilizerSize(stable);
+    }
+  else
+    {
+      for(SymmetryGroup::ElementContainer::const_iterator j=elements.begin();j!=elements.end();j++)
+        {
+          bool doesFix=true;
+
+          for(int i=0;i<n;i++)
+            if(stable[i]!=stable[(*j)[i]])
+              {
+                doesFix=false;
+                break;
+              }
+          if(doesFix)numFixed++;
+        }
+    }
+  return groupSize/numFixed;
+}
+
+
+ZVector Permutation::fundamentalDomainInequality()const
+{
+  for(unsigned i=0;i<size();i++)
+    if((*this)[i]!=(int)i)
+      return ZVector::standardVector(size(),i)-ZVector::standardVector(size(),(*this)[i]);
+  return ZVector(size());
+}
+
+
+ZMatrix SymmetryGroup::fundamentalDomainInequalities()const
+{
+  set<ZVector> ret2;
+  for(ElementContainer::const_iterator i=elements.begin();i!=elements.end();i++)
+    ret2.insert(i->fundamentalDomainInequality());
+
+  ZMatrix ret(0,sizeOfBaseSet());
+  for(set<ZVector>::const_iterator i=ret2.begin();i!=ret2.end();i++)
+    if(!i->isZero())ret.appendRow(*i);
+
+  return ret;
+}
+
+
+void SymmetryGroup::createTrie()
+{
+  trie=new Trie(sizeOfBaseSet());
+  for(ElementContainer::const_iterator i=elements.begin();i!=elements.end();i++)
+    trie->insert(*i);
+}
+
+
+
+bool SymmetryGroup::isTrivial()const
+{
+  ElementContainer::const_iterator i=elements.begin();
+  assert(i!=elements.end());
+  i++;
+  return i==elements.end();
+}
+#if 0
+static int mergeSortRek(IntegerVector &v, int begin, int end, IntegerVector &temp)
+{
+  if(end-begin<2)return 0;
+  int med=(begin+end)>>1;
+  int nswaps=mergeSortRek(v,begin,med,temp);
+  nswaps+=mergeSortRek(v,med,end,temp);
+
+  {
+    int Astart=begin;
+    int Alength=med-begin;
+    int Bstart=med;
+    int Blength=end-med;
+    int nextFree=begin;
+    while(nextFree!=end)
+      {
+//        debug<<"Astart:"<<Astart<<"Alength:"<<Alength<<"Bstart:"<<Bstart<<"Blength:"<<Blength<<"nextFree:"<<nextFree<<"\n";
+        if(Blength==0 || (Alength!=0 && v[Astart]<v[Bstart]))
+          {
+            temp[nextFree++]=v[Astart++];
+            Alength--;
+          }
+        else
+          {
+            temp[nextFree++]=v[Bstart++];
+            nswaps+=Alength;
+            Blength--;
+          }
+      }
+    for(int i=begin;i!=end;i++)v[i]=temp[i];
+  }
+//debug<<"return\n";
+  return nswaps;
+}
+
+int mergeSort(IntegerVector &v)
+{
+  IntegerVector temp(v.size());
+  return mergeSortRek(v,0,v.size(),temp);
+}
+#endif
+}
diff --git a/gfanlib/gfanlib_symmetry.h b/gfanlib/gfanlib_symmetry.h
new file mode 100644
index 0000000..c2447ad
--- /dev/null
+++ b/gfanlib/gfanlib_symmetry.h
@@ -0,0 +1,154 @@
+/*
+ * gfan_symmetry.h
+ *
+ *  Created on: Oct 22, 2010
+ *      Author: anders
+ */
+
+#ifndef GFANLIB_SYMMETRY_H_INCLUDED
+#define GFANLIB_SYMMETRY_H_INCLUDED
+
+#include <set>
+#include "gfanlib_vector.h"
+#include "gfanlib_matrix.h"
+
+namespace gfan{
+
+/**
+ * The permutation class represents an element in the symmetric group S_n.
+ */
+class Permutation:public IntVector
+{
+//  IntVector data;
+public:
+  /**
+   * Returns true if a contains the elements from 0 up to a.size()-1.
+   */
+  static bool isPermutation(IntVector const &a);
+  /**
+   * Returns true if all rows of the matrix contains the elements 0 up to m.getWidth()-1.
+   */
+  static bool arePermutations(IntMatrix const &m);
+  /**
+   * Generates the identity permutation on n elements.
+   */
+  Permutation(int n):
+    IntVector(n)
+    {
+      for(int i=0;i<n;i++)(*this)[i]=i;
+    }
+  /**
+   * Generates a permutation from the vector v. The ith entry of v tells
+   * If the check flag is set to true, then it is checked whether the vector represents
+   * a permutation. If not, the code fails with an assertion.
+   */
+  Permutation(IntVector const &v, bool check=true):
+    IntVector(v)
+    {
+      if(check)assert(isPermutation(v));
+    }
+
+  static Permutation transposition(int n, int i, int j)
+  {
+    IntVector ret(n);
+    for(int k=0;k<n;k++)ret[k]=k;
+    ret[i]=j;
+    ret[j]=i;
+    return Permutation(ret);
+  }
+  static Permutation cycle(int n)
+  {
+    IntVector a(n);
+    for(int i=0;i<n-1;i++)a[i]=i+1;
+    a[n-1]=0;
+    return Permutation(a);
+  }
+  IntVector toIntVector()const
+  {
+    return IntVector(*this);
+  }
+
+  int sizeOfBaseSet()const
+  {
+    return size();
+  }
+  Permutation inverse()const;
+
+  /**
+   * Apply the permutation
+   */
+  Permutation apply(Permutation const &p)const;
+  IntVector apply(IntVector const &v)const;
+  ZVector apply(ZVector const &v)const;
+  ZMatrix apply(ZMatrix const &m)const;
+  Permutation applyInverse(Permutation const &p)const;
+  IntVector applyInverse(IntVector const &v)const;
+  ZVector applyInverse(ZVector const &v)const;
+  ZMatrix applyInverse(ZMatrix const &m)const;
+
+  /**
+     The set of vectors which are not improved lexicographically when
+     perm is applied to them is convex. Its closure is a
+     halfspace. This routine returns the inner normal of this
+     halfspace. The only exception is if perm is the identity then the
+     zero vector is returned.
+   */
+  ZVector fundamentalDomainInequality()const;
+};
+
+/**
+ * This object represents a subgroup of the symmetric group S_n.
+ */
+
+class SymmetryGroup{
+  int byteTableHeight;
+  class Trie *trie;
+public:
+  typedef std::set<Permutation/*,LexicographicTermOrder*/> ElementContainer;
+   ElementContainer elements;//Make this private
+   int size()const
+   {
+     return elements.size();
+   }
+   int sizeOfBaseSet()const;
+  /**
+     The set of vectors which cannot be improved lexicographically by
+     applying an element from the group is a convex set. Its closure
+     is a polyhedral cone. This routine returns a set of inequalities
+     The returned list does not contain the zero vector.
+   */
+  ZMatrix fundamentalDomainInequalities()const;
+  SymmetryGroup(int n);
+  void computeClosure(Permutation const &v);
+  void computeClosure(IntMatrix const &l);
+  IntMatrix getGenerators()const;
+  int orbitSize(ZVector const &stable)const;
+  bool isTrivial()const;
+  /**
+     The symmetry group acts on vectors by permuting the entries. The
+     following routine returns a unique representative for the orbit
+     containing v. This makes it easy to check if two elements are in
+     the same orbit. The permutation used to get this representative
+     is stored in *usedPermutation (if pointer not 0).
+   */
+  ZVector orbitRepresentative(ZVector const &v, Permutation *usedPermutation=0)const;
+  /**
+     This routine works as orbitRepresentative() except that the
+     symmetry group considered is only the subgroup keeping the vector
+     fixed fixed.
+   */
+  ZVector orbitRepresentativeFixing(ZVector const &v, ZVector const &fixed)const;
+
+  // Methods for highly optimized symmetry group computations:
+  void createTrie();
+};
+/**
+ * Sorts v and returns the number of swaps performed.
+ */
+int mergeSort(IntVector &v);
+}
+
+
+
+
+#endif /* GFAN_SYMMETRY_H_ */
diff --git a/gfanlib/gfanlib_vector.h b/gfanlib/gfanlib_vector.h
new file mode 100644
index 0000000..18b8639
--- /dev/null
+++ b/gfanlib/gfanlib_vector.h
@@ -0,0 +1,400 @@
+/*
+ * lib_zvector.h
+ *
+ *  Created on: Sep 6, 2010
+ *      Author: anders
+ */
+
+#ifndef GFANLIB_ZVECTOR_H_INCLUDED
+#define GFANLIB_ZVECTOR_H_INCLUDED
+
+#include <vector>
+#include <list>
+#include <assert.h>
+#include <algorithm>
+#include <iostream>
+
+#include "gfanlib_z.h"
+#include "gfanlib_q.h"
+
+namespace gfan{
+
+inline void outOfRange(int i, int n)
+{
+  std::cerr<<"Index out of range. i="<<i<<" n="<<n<<std::endl;
+  assert(0);
+}
+
+template <class typ> class Vector{
+private:
+  std::vector<typ> v;
+public:
+  //--------------
+  // Constructors
+  //--------------
+  Vector(const Vector &a):v(a.v){
+  }
+  Vector(int n):v(n){
+    assert(n>=0);
+  };
+/*  Vektor(const typ *p, int n):v(n){
+    assert(n>=0);
+    support=0;for(int i=0;i<n;i++)v[i]=p[i];
+  };*/
+  ~Vector(){
+  };
+  Vector(){
+  };
+  static Vector standardVector(int n, int i)
+    {
+      Vector v(n);
+      v[i]=typ(1);
+      return v;
+    }
+  static Vector allOnes(int n)
+    {
+      Vector v(n);
+      for(int i=0;i<n;i++)
+        v[i]=typ(1);
+      return v;
+    }
+  //-------------
+  // Conversions
+  //-------------
+/*  template<class T> Vektor(const Vektor<T>& c)
+          :v(c.size())
+        {
+          for(int i=0;i<size();i++)v[i]=typ(c[i]);
+        }
+*/
+  //--------
+  // Access
+  //--------
+  typ& operator[](int n)
+    {
+      if(!(n>=0 && n<(int)v.size()))outOfRange(n,v.size());
+      return (v[n]);
+    }
+  const typ& operator[](int n)const{assert(n>=0 && n<(int)v.size());return (v[n]);}
+  const typ& UNCHECKEDACCESS(int n)const{return (v[n]);}
+
+  //-------------
+  // STL related
+  //-------------
+  unsigned int size()const{return v.size();};
+  void resize(int n){v.resize(n,typ());};
+  void grow(int i){if(size()<i)resize(i);}
+  void push_back(typ a)
+  {
+    v.push_back(a);
+  }
+  void sort()
+    {
+      std::sort(v.begin(),v.end());
+    }
+  bool nextPermutation()
+    {
+      return std::next_permutation(v.begin(),v.end());
+    }
+  bool operator<(const Vector & b)const
+    {
+      if(size()<b.size())return true;
+      if(size()>b.size())return false;
+      for(unsigned i=0;i<size();i++)
+        {
+          if(v[i]<b[i])return true;
+          if(b[i]<v[i])return false;
+        }
+      return false;
+    }
+
+  //-----------------
+  // Arithmetic fast
+  //-----------------
+  typ sum()const{typ f;for(typename std::vector<typ>::const_iterator i=v.begin();i!=v.end();i++)f+=*i;return f;};
+  Vector& operator+=(const Vector& q){assert(size()==q.size());typename std::vector<typ>::const_iterator j=q.v.begin();for(typename std::vector<typ>::iterator i=v.begin();i!=v.end();++i,++j)(*i)+=(*j);return *this;}
+  Vector& operator-=(const Vector& q){assert(size()==q.size());typename std::vector<typ>::const_iterator j=q.v.begin();for(typename std::vector<typ>::iterator i=v.begin();i!=v.end();++i,++j)(*i)-=(*j);return *this;}
+  Vector& operator/=(const Vector& q){assert(size()==q.size());typename std::vector<typ>::const_iterator j=q.v.begin();for(typename std::vector<typ>::iterator i=v.begin();i!=v.end();++i,++j)(*i)/=(*j);return *this;}
+  inline friend typ dot(const Vector& p, const Vector& q){assert(p.size()==q.size());typ s;typename std::vector<typ>::const_iterator j=q.v.begin();for(typename std::vector<typ>::const_iterator i=p.v.begin();i!=p.v.end();++i,++j)s+=(*i)*(*j);return s;}
+//  inline friend int64 dotLong(const Vektor& p, const Vektor& q){assert(p.size()==q.size());int64 s=0;for(int i=0;i<p.size();i++)s+=(int64)p[i]*(int64)q[i];return s;}
+  bool operator==(const Vector & q)const{if(size()!=q.size())return false;typename std::vector<typ>::const_iterator j=q.v.begin();for(typename std::vector<typ>::const_iterator i=v.begin();i!=v.end();++i,++j)if((*i)!=(*j))return false;return true;}
+  bool operator!=(const Vector & q)const {return !(operator==(q));}
+  bool isZero() const
+    {
+      for(typename std::vector<typ>::const_iterator i=v.begin();i!=v.end();++i)if(!(*i).isZero())return false;
+      return true;
+    }
+  bool isPositive() const
+    {
+      for(typename std::vector<typ>::const_iterator i=v.begin();i!=v.end();++i)if((*i).sign()<=0)return false;
+      return true;
+    }
+  bool isNonNegative() const
+    {
+      for(typename std::vector<typ>::const_iterator i=v.begin();i!=v.end();++i)if(i->sign()<0)return false;
+      return true;
+    }
+/*  int max()const
+  {
+    int ret=-0x7fffffff; //not completely correct, but kind of works for 64bit
+    for(int i=0;i<v.size();i++)if(ret<v[i])ret=v[i];
+    return ret;
+  }
+  int min()const
+  {
+    int ret=0x7fffffff;
+    for(int i=0;i<v.size();i++)if(ret>v[i])ret=v[i];
+    return ret;
+  }
+*/
+  friend bool dependent(const Vector& p, const Vector& q)
+    {
+          /*
+      typ pp=dot(p,p);
+      typ qq=dot(q,q);
+      typ pq=dot(p,q);
+      return pq*pq==pp*qq;
+*/
+          unsigned n=p.size();
+          assert(n==q.size());
+          unsigned i;
+          for(i=0;i<n;i++)
+          {
+            if(!p.v[i].isZero())break;
+          }
+          if(i==n)return true;
+          if(q.v[i].isZero())return q.isZero();
+          typ a=p.v[i];
+          typ b=q.v[i];
+          for(unsigned j=0;j<n;j++)
+            if(a*q.v[j]!=b*p.v[j])return false;
+          return true;
+    }
+
+  //-----------------
+  // Arithmetic slow
+  //-----------------
+  inline friend Vector operator*(typ s, const Vector& q){Vector p=q;for(unsigned i=0;i<q.size();i++)p[i]*=s;return p;}
+//  inline friend Vektor operator/(const Vektor& q, typ s){Vektor p=q;for(int i=0;i<q.size();i++)p[i]/=s;return p;}
+/*  inline friend Vector operator*(const Vektor& p, const Vektor& q){assert(p.size()==q.size());Vektor p1=p;for(int i=0;i<p.size();i++)p1.v[i]*=q.v[i];return p1;}
+  inline friend Vektor operator+(const Vektor& p, const Vektor& q){assert(p.size()==q.size());Vektor p1=p;for(int i=0;i<p.size();i++)p1[i]+=q[i];return p1;}
+*/
+  inline friend Vector operator/(const Vector& p, typ const &s){Vector ret(p.size());for(unsigned i=0;i<p.size();i++)ret[i]=p[i]/s;return ret;}
+  inline friend Vector operator+(const Vector& p, const Vector& q){assert(p.size()==q.size());Vector p1=p;for(unsigned i=0;i<p.size();i++)p1[i]+=q[i];return p1;}
+  inline friend Vector operator-(const Vector& p, const Vector& q){assert(p.size()==q.size());Vector p1=p;for(unsigned i=0;i<p.size();i++)p1[i]-=q[i];return p1;}
+  inline friend Vector max(const Vector& p, const Vector& q){assert(p.size()==q.size());Vector p1=p;for(unsigned i=0;i<p.size();i++)if(p1[i]<q[i])p1[i]=q[i];return p1;}
+  inline friend Vector min(const Vector& p, const Vector& q){assert(p.size()==q.size());Vector p1=p;for(unsigned i=0;i<p.size();i++)if(p1[i]>q[i])p1[i]=q[i];return p1;}
+
+  friend Vector operator-(const Vector &b)
+  {
+    Vector ret(b.size());
+    for(unsigned i=0;i<b.size();i++)ret[i]=-b[i];
+    return ret;
+  }
+  //------------------
+  // Monomial related
+  //------------------
+/*  int divides(const Vektor& q) const
+    {
+      assert(size()==q.size());
+      int n=v.size();
+      for(int i=0;i<n;i++)
+        {
+          if(v[i]>0)if(q.v[i]<v[i])return 0;
+        }
+      return 1;
+    }
+  inline friend bool relativelyPrime(const Vektor& p, const Vektor& q)
+    {
+      assert(p.size()==q.size());
+      int n=p.size();
+      for(int t=0;t<n;t++)if((p[t]>0)&&(q[t]>0)) return false;
+      return true;
+    }
+  Vektor supportVector()const
+    {
+      Vektor r(v.size());
+      for(int i=0;i<size();i++)
+        r[i]=(v[i]!=0);
+      return r;
+    }
+*/
+  //------------------------------
+  // Subvectors and concatenation
+  //------------------------------
+  Vector subvector(int begin, int end)const
+    {
+      assert(begin>=0);
+      assert(end<=(int)size());
+      assert(end>=begin);
+      Vector ret(end-begin);
+      for(int i=0;i<end-begin;i++)
+        ret[i]=v[begin+i];
+      return ret;
+    }
+/*  Vektor subvector(list<int> const &chosenIndices)const
+  {
+    Vektor ret(chosenIndices.size());
+    int I=0;
+    for(list<int>::const_iterator i=chosenIndices.begin();i!=chosenIndices.end();i++,I++)ret[I]=v[*i];
+    return ret;
+  }
+*/
+  friend Vector concatenation(Vector const &a, Vector const &b)
+  {
+    Vector ret(a.size()+b.size());
+    for(int i=0;i<a.size();i++)ret[i]=a[i];
+    for(int i=0;i<b.size();i++)ret[i+a.size()]=b[i];
+    return ret;
+  }
+  //----------------------
+  // Zero/nonZero entries
+  //----------------------
+/*  int indexOfLargestNonzeroEntry()const
+  {
+    int ret=-1;
+    for(int i=0;i<v.size();i++)
+      {
+        if(v[i])ret=i;
+      }
+    return ret;
+  }
+  Vektor supportIndices()const
+  {
+    Vektor ret(0);
+    for(int i=0;i<v.size();i++)
+      if(v[i]!=0)ret.push_back(i);
+    return ret;
+  }
+  Vektor supportAsZeroOneVector()const
+  {
+    Vektor ret(v.size());
+    for(int i=0;i<v.size();i++)ret[i]=bool(v[i]);
+    return ret;
+  }
+  void calcsupport(void)
+    {
+      support=0;
+      for(int i=0;i<v.size();i++)support=(support<<1)|(((v[i]>0)==true)&1);
+    }
+*/
+  friend std::ostream &operator<<(std::ostream &f, Vector const &a)
+  {
+    f<<"(";
+    for(typename std::vector<typ>::const_iterator i=a.v.begin();i!=a.v.end();i++)
+    {
+      if(i!=a.v.begin()) f<<",";
+      f<<*i;
+    }
+    return f<<")";
+  }
+  typ gcd()const
+  {
+    typ temp1,temp2;
+    typ ret(1);
+    for(unsigned i=0;i<size();i++)
+      ret=typ::gcd(ret,v[i],temp1,temp2);
+    return ret;
+  }
+  Vector normalized()const
+  {
+    assert(!typ::isField());
+    return (*this)/gcd();
+  }
+};
+
+typedef Vector<Integer> ZVector;
+typedef Vector<Rational> QVector;
+typedef Vector<int> IntVector;
+
+inline QVector ZToQVector(ZVector const &v)
+{
+  QVector ret(v.size());
+  for(unsigned i=0;i<v.size();i++)ret[i]=Rational(v[i]);
+  return ret;
+}
+
+
+inline IntVector ZToIntVector(ZVector const &v)
+{
+  IntVector ret(v.size());
+  for(unsigned i=0;i<v.size();i++)ret[i]=v[i].toInt();
+  return ret;
+}
+
+
+inline ZVector IntToZVector(IntVector const &v)
+{
+  ZVector ret(v.size());
+  for(unsigned i=0;i<v.size();i++)ret[i]=Integer(v[i]);
+  return ret;
+}
+
+inline ZVector QToZVectorPrimitive(QVector const &v)
+{
+    int n=v.size();
+    ZVector ret(n);
+
+    mpz_t lcm;
+    mpz_t gcd;
+    mpz_init_set_ui(lcm, 1);
+    mpz_init_set_ui(gcd, 0);
+
+    mpq_t a;
+    mpq_init(a);
+    for(int j=0;j<n;j++)
+      {
+        v[j].setGmp(a);
+        if(mpz_cmp_si(mpq_denref(a),1)!=0)
+          mpz_lcm(lcm,lcm,mpq_denref(a));
+        if(mpz_sgn(mpq_numref(a))!=0)
+          mpz_gcd(gcd,gcd,mpq_numref(a));
+      }
+    mpq_clear(a);
+    if(mpz_sgn(gcd)!=0)//v is non-zero
+      {
+        if((mpz_cmp_si(lcm,1)==0)&&(mpz_cmp_si(gcd,1)==0)) //gcd=lcm=1
+          {
+            mpq_t a;
+            mpq_init(a);
+
+            for(int i=0;i<n;i++)
+              {
+                v[i].setGmp(a);
+                ret[i]=Integer(mpq_numref(a));
+              }
+            mpq_clear(a);
+          }
+        else
+          {
+            mpq_t a;
+            mpq_init(a);
+            mpz_t tempA;
+            mpz_t tempB;
+            mpz_init(tempA);
+            mpz_init(tempB);
+            for(int i=0;i<n;i++)
+              {
+                v[i].setGmp(a);
+                mpz_set(tempA,mpq_denref(a));
+                mpz_set(tempB,mpq_numref(a));
+                mpz_mul(tempA,gcd,tempA);
+                mpz_mul(tempB,lcm,tempB);
+                mpz_divexact(tempA,tempB,tempA);
+                ret[i]=Integer(tempA);
+              }
+            mpz_clear(tempB);
+            mpz_clear(tempA);
+            mpq_clear(a);
+          }
+      }
+    mpz_clear(gcd);
+    mpz_clear(lcm);
+
+    return ret;
+}
+
+}
+
+
+#endif /* LIB_ZVECTOR_H_ */
diff --git a/gfanlib/gfanlib_z.h b/gfanlib/gfanlib_z.h
new file mode 100644
index 0000000..c11a6cd
--- /dev/null
+++ b/gfanlib/gfanlib_z.h
@@ -0,0 +1,403 @@
+/*
+ * lib_z.h
+ *
+ *  Created on: Sep 28, 2010
+ *      Author: anders
+ */
+
+#ifndef LIB_Z_H_
+#define LIB_Z_H_
+
+#include <string.h>
+#include <ostream>
+
+#define OLD 1
+#if OLD
+#include "gmp.h"
+
+#if (__GNU_MP_VERSION == 4) && (__GNU_MP_VERSION_MINOR<2)
+extern void *  (*__gmp_allocate_func) __GMP_PROTO ((size_t));
+extern void *  (*__gmp_reallocate_func) __GMP_PROTO ((void *, size_t, size_t));
+extern void    (*__gmp_free_func) __GMP_PROTO ((void *, size_t));
+
+static inline void
+mp_get_memory_functions (void *(**alloc_func) (size_t),
+                         void *(**realloc_func) (void *, size_t, size_t),
+                         void (**free_func) (void *, size_t))
+{
+  if (alloc_func != NULL)
+    *alloc_func = __gmp_allocate_func;
+
+  if (realloc_func != NULL)
+    *realloc_func = __gmp_reallocate_func;
+
+  if (free_func != NULL)
+    *free_func = __gmp_free_func;
+}
+#endif
+
+namespace gfan{
+  class Rational;
+class Integer
+{
+  friend class Rational;
+  mpz_t value;
+public:
+  static bool isField()
+  {
+    return false;
+  }
+  Integer()
+  {
+    mpz_init(value);
+  }
+  Integer(signed long int value_)
+  {
+    mpz_init(value);
+    mpz_set_si(value,value_);
+  }
+  Integer(Integer const & value_)
+  {
+    mpz_init_set(value,value_.value);
+  }
+  Integer(mpz_t value_)
+  {
+    mpz_init_set(value,value_);
+  }
+  ~Integer()
+  {
+    mpz_clear(value);
+  }
+  Integer& operator=(const Integer& a)
+    {
+      const Integer *A=(const Integer*)&a;
+      if (this != A) {
+        mpz_clear(value);
+        mpz_init_set(value, a.value);
+      }
+      return *this;
+    }
+  bool isZero()const{
+    return mpz_sgn(value)==0;
+  }
+  friend std::ostream &operator<<(std::ostream &f, Integer const &a)
+  {
+    void (*freefunc)(void *, size_t);
+    mp_get_memory_functions(0,0,&freefunc);
+    char *str=mpz_get_str(0,10,a.value);
+    f<<str;
+    freefunc(str,strlen(str)+1);
+    return f;
+  }
+  Integer& operator+=(const Integer& a)
+    {
+      mpz_add(value,value,a.value);
+      return *this;
+    }
+  Integer& operator-=(const Integer& a)
+    {
+      mpz_sub(value,value,a.value);
+      return *this;
+    }
+  Integer& operator*=(const Integer& a)
+    {
+      mpz_mul(value,value,a.value);
+      return *this;
+    }
+  Integer& operator/=(const Integer& a)
+    {
+      mpz_div(value,value,a.value);
+      return *this;
+    }
+  friend Integer operator-(const Integer &b)
+  {
+    Integer ret;
+    ret-=b;
+    return ret;
+  }
+  Integer operator+(const Integer &a)const
+  {
+    Integer ret(*this);
+    ret+=a;
+    return ret;
+  }
+  Integer operator-(const Integer &a)const
+  {
+    Integer ret(*this);
+    ret-=a;
+    return ret;
+  }
+  Integer operator*(const Integer &a)const
+  {
+    Integer ret(*this);
+    ret*=a;
+    return ret;
+  }
+  Integer operator/(const Integer &a)const
+  {
+    Integer ret(*this);
+    ret/=a;
+    return ret;
+  }
+  void madd(const Integer &a,const Integer &b)
+    {
+      mpz_t temp;
+      mpz_init(temp);
+      mpz_mul(temp,a.value,b.value);
+      mpz_add(value,value,temp);
+      mpz_clear(temp);
+    }
+  bool operator<(const Integer &a)const
+  {
+    return mpz_cmp(value,a.value)<0;
+  }
+  bool operator==(const Integer &a)const
+  {
+    return mpz_cmp(value,a.value)==0;
+  }
+  bool operator!=(const Integer &a)const
+  {
+    return mpz_cmp(value,a.value)!=0;
+  }
+  int sign()const
+  {
+    return mpz_sgn(value);
+  }
+  static Integer gcd(Integer const &a, Integer const &b, Integer &s, Integer &t)
+  {
+    mpz_t r;
+    mpz_init(r);
+    mpz_gcdext(r,s.value,t.value,a.value,b.value);
+    Integer ret(r);
+    mpz_clear(r);
+    return ret;
+  }
+  /**
+   * Assigns the value to z. z must have been initialized as a gmp variable.
+   */
+  void setGmp(mpz_t z)const
+  {
+    mpz_set(z,value);
+  }
+  /**
+   * Returns a value which is useful for computing hash functions.
+   */
+  signed long int hashValue()const
+  {
+    return mpz_get_si(value);
+  }
+  bool fitsInInt()const
+  {
+    mpz_t v;
+    mpz_init(v);
+    this->setGmp(v);
+    bool ret=(mpz_fits_sint_p(v)!=0);
+    mpz_clear(v);
+    return ret;
+  }
+  int toInt()const
+  {
+    mpz_t v;
+    mpz_init(v);
+    this->setGmp(v);
+    int ret=0;
+    if(mpz_fits_sint_p(v))
+      ret=mpz_get_si(v);
+//    else
+//      ok=false;
+    mpz_clear(v);
+    return ret;
+  }
+};
+
+
+}
+
+#else
+namespace gfan{
+  typedef signed long int word;//processor type for integers
+  typedef int64_t LimbWord;//memory word. Assumed to be at least as big as word
+  typedef uint64_t uLimbWord;//memory word. Assumed to be at least as big as word
+  const int limbSizeInBytes=8;
+#include <stdint.h>
+  struct spec64malloc{
+    int64_t data;
+    bool hasLimbs()
+    {
+      return data&1;
+    }
+    word fitsMask()
+    {
+      return 0xc000000000000000;
+    }
+    void assign(word value)//assuming data fits
+    {
+      data=value<<1;
+    }
+    void alloc(int nlimbs)//one limb is added since that will tell the number of remaining limbs
+    {
+      int64_t temp=(int64_t)malloc((nlimbs+1)*limbSizeInBytes);
+      assert(temp);
+      data=temp+1;
+    }
+    LimbWord *limbs()//assuming that limbs exist
+    {
+      return (LimbWord*)(data-1);
+    }
+    word nlimbs()//assuming limbs exist
+    {
+      return (word)*limbs();
+    }
+    void copy(spec64malloc b)
+    {
+      if(hasLimbs())
+        {
+          word n2=b.nlimbs()+1;
+          int64_t temp=(int64_t)malloc((n2)*limbSizeInBytes);
+          assert(temp);
+
+          data=temp+1;
+          memcpy((LimbWord*)temp,limbs(),n2*limbSizeInBytes);
+        }
+      else
+        {
+          data=b.data;
+        }
+    }
+    void doFree()//assuming that limbs exist
+    {
+      free((void*)(data-1));
+    }
+    word valueToWord()//assume no limbs and that word is big enough to contain int64_t
+    {
+      return data>>1;
+    }
+  };
+  template <struct spec> struct IntegerTemplate : public spec
+  {
+  private:
+    bool fits(word v)
+    {
+      return !((value_&fitsMask())^((value_<<1)&fitsMask));
+    }
+  public:
+    static bool isField()
+    {
+      return false;
+    }
+    IntegerTemplate()
+    {
+      spec.data=0;
+    }
+    void assignWordNoFree()
+    {
+      if(fits(value_))
+        {
+          assign(value);
+        }
+      else
+        {
+          alloc(1);
+          limbs()[0]=1;
+          limbs()[1]=value_;
+        }
+    }
+    IntegerTemplate(word value_)
+    {
+      assignWordNoFree(value_);
+    }
+    IntegerTemplate(IntegerTemplate const & value_)
+    {
+      if(value_.hasLimbs())
+        {
+          copy(value_);
+        }
+      else
+        data=value.data;
+    }
+/*    Integer(mpz_t value_)
+    {
+      mpz_init_set(value,value_);
+    }*/
+    ~IntegerTemplate()
+    {
+      if(hasLimbs())doFree();
+    }
+    IntegerTemplate& operator=(const IntegerTemplate& a)
+      {
+        if(this!=&a)
+          {
+            if(hasLimps())doFree();
+            copy(a);
+          }
+        return *this;
+      }
+    bool isZero()const{
+      return data==0;
+    }
+    friend std::ostream &operator<<(std::ostream &f, IntegerTemplate const &a)
+    {
+      if(hasLimps())
+        {
+          LimpWord *p=limbs();
+          int l=*p++;
+          for(int i=0;i<l;i++)
+            f<<":"<<p[i];
+        }
+      else
+        {
+          f<<valueToWord();
+        }
+      return f;
+    }
+    LimbWord signExtension(LimbWord a)
+    {
+      return 0-(a<0);
+    }
+    void addWordToLimbs(word v)
+    {
+      int n=nlimbs();
+      LimbWord V=v;
+      LimbWord *p=limbs()+1;
+      LimbWord s=signExtension(V);
+      for(int i=0;i<n;i++)
+        {
+          LimbWord r=V+*p;
+          bool carry=(uLimbWord)r<(uLimbWord)V;
+          V=carry+s;
+        }
+
+    }
+
+
+    IntegerTemplate& operator+=(const IntegerTemplate& a)
+      {
+        if(hasLimbs()||a.hasLimbs())
+          {
+            if(!hasLimbs())
+              {
+
+              }
+            else
+              {
+              }
+
+          }
+        else
+          {
+            word C=valueToWord();
+            word A=a.valueToWord();
+            word D=A+C;
+            assignWordNoFree(D);
+          }
+        return *this;
+      }
+
+  };
+
+  typedef IntegerTemplate<spec64malloc> Integer;
+};
+#endif
+
+#endif /* LIB_Z_H_ */
+
diff --git a/gfanlib/gfanlib_zcone.cpp b/gfanlib/gfanlib_zcone.cpp
new file mode 100644
index 0000000..1214afd
--- /dev/null
+++ b/gfanlib/gfanlib_zcone.cpp
@@ -0,0 +1,1276 @@
+/*
+ * lib_cone.cpp
+ *
+ *  Created on: Sep 29, 2010
+ *      Author: anders
+ */
+
+#include "gfanlib_zcone.h"
+
+#include <vector>
+#include <set>
+
+
+#include "config.h"
+
+#ifdef HAVE_CDD_SETOPER_H
+#include "cdd/setoper.h"
+#include "cdd/cdd.h"
+#elif HAVE_CDDLIB_SETOPER_H
+#include "cddlib/setoper.h"
+#include "cddlib/cdd.h"
+#else
+#include "setoper.h"
+#include "cdd.h"
+#endif
+
+namespace gfan{
+
+  static void cddinitGmp()
+  {
+    static bool initialized;
+    if(!initialized)
+      {
+        dd_set_global_constants();  /* First, this must be called. */
+        initialized=true;
+      }
+  }
+
+
+class LpSolver
+{
+  static dd_MatrixPtr ZMatrix2MatrixGmp(ZMatrix const &g, dd_ErrorType *Error)
+  {
+    int n=g.getWidth();
+    dd_MatrixPtr M=NULL;
+    dd_rowrange m_input,i;
+    dd_colrange d_input,j;
+    dd_RepresentationType rep=dd_Inequality;
+    // dd_boolean found=dd_FALSE, newformat=dd_FALSE, successful=dd_FALSE;
+    // char command[dd_linelenmax], comsave[dd_linelenmax];
+    dd_NumberType NT;
+
+    (*Error)=dd_NoError;
+
+    rep=dd_Inequality; // newformat=dd_TRUE;
+
+    m_input=g.getHeight();
+    d_input=n+1;
+
+    NT=dd_Rational;
+
+    M=dd_CreateMatrix(m_input, d_input);
+    M->representation=rep;
+    M->numbtype=NT;
+
+    for (i = 0; i < m_input; i++) {
+      dd_set_si(M->matrix[i][0],0);
+      for (j = 1; j < d_input; j++) {
+        g[i][j-1].setGmp(mpq_numref(M->matrix[i][j]));
+        mpz_init_set_ui(mpq_denref(M->matrix[i][j]), 1);
+        mpq_canonicalize(M->matrix[i][j]);
+      }
+    }
+
+    // successful=dd_TRUE;
+
+    return M;
+  }
+  static dd_MatrixPtr ZMatrix2MatrixGmp(ZMatrix const &inequalities, ZMatrix const &equations, dd_ErrorType *err)
+  {
+    ZMatrix g=inequalities;
+    g.append(equations);
+    int numberOfInequalities=inequalities.getHeight();
+    int numberOfRows=g.getHeight();
+    dd_MatrixPtr A=NULL;
+    cddinitGmp();
+    A=ZMatrix2MatrixGmp(g, err);
+    for(int i=numberOfInequalities;i<numberOfRows;i++)
+      set_addelem(A->linset,i+1);
+    return A;
+  }
+  static ZMatrix getConstraints(dd_MatrixPtr A, bool returnEquations)
+  {
+    int rowsize=A->rowsize;
+    int n=A->colsize-1;
+
+    ZMatrix ret(0,n);
+    for(int i=0;i<rowsize;i++)
+      {
+        bool isEquation=set_member(i+1,A->linset);
+        if(isEquation==returnEquations)
+          {
+            QVector v(n);
+            for(int j=0;j<n;j++)v[j]=Rational(A->matrix[i][j+1]);
+            ret.appendRow(QToZVectorPrimitive(v));
+          }
+      }
+    return ret;
+  }
+  static bool isFacet(ZMatrix const &g, int index)
+  {
+    bool ret;
+    dd_MatrixPtr M=NULL/*,M2=NULL,M3=NULL*/;
+    // dd_colrange d;
+    dd_ErrorType err=dd_NoError;
+    // dd_rowset redrows,linrows,ignoredrows, basisrows;
+    // dd_colset ignoredcols, basiscols;
+    // dd_DataFileType inputfile;
+    // FILE *reading=NULL;
+
+    cddinitGmp();
+
+    M=ZMatrix2MatrixGmp(g, &err);
+    if (err!=dd_NoError) goto _L99;
+
+    // d=M->colsize;
+
+    static dd_Arow temp;
+    dd_InitializeArow(g.getWidth()+1,&temp);
+
+    ret= !dd_Redundant(M,index+1,temp,&err);
+
+    dd_FreeMatrix(M);
+    dd_FreeArow(g.getWidth()+1,temp);
+
+    if (err!=dd_NoError) goto _L99;
+    return ret;
+   _L99:
+    assert(0);
+    return false;
+  }
+
+  /*
+    Heuristic for checking if inequality of full dimensional cone is a
+    facet. If the routine returns true then the inequality is a
+    facet. If it returns false it is unknown.
+   */
+  static bool fastIsFacetCriterion(ZMatrix const &normals, int i)
+  {
+    int n=normals.getWidth();
+    for(int j=0;j<n;j++)
+      if(normals[i][j].sign()!=0)
+        {
+          int sign=normals[i][j].sign();
+          bool isTheOnly=true;
+          for(int k=0;k<normals.getHeight();k++)
+            if(k!=i)
+              {
+                if(normals[i][j].sign()==sign)
+                  {
+                    isTheOnly=false;
+                    break;
+                  }
+              }
+          if(isTheOnly)return true;
+        }
+    return false;
+  }
+
+  static bool fastIsFacet(ZMatrix const &normals, int i)
+  {
+    if(fastIsFacetCriterion(normals,i))return true;
+    return isFacet(normals,i);
+  }
+
+  class MyHashMap
+  {
+    typedef std::vector<std::set<ZVector> > Container;
+    Container container;
+    int tableSize;
+  public:
+    class iterator
+    {
+      class MyHashMap &hashMap;
+      int index; // having index==-1 means that we are before/after the elements.
+      std::set<ZVector>::iterator i;
+    public:
+      bool operator++()
+      {
+        if(index==-1)goto search;
+        i++;
+        while(i==hashMap.container[index].end())
+          {
+            search:
+            index++;
+            if(index>=hashMap.tableSize){
+              index=-1;
+              return false;
+            }
+            i=hashMap.container[index].begin();
+          }
+        return true;
+      }
+      ZVector const & operator*()const
+      {
+        return *i;
+      }
+      ZVector operator*()
+      {
+        return *i;
+      }
+      iterator(MyHashMap &hashMap_):
+        hashMap(hashMap_)
+        {
+          index=-1;
+        }
+    };
+    unsigned int function(const ZVector &v)
+    {
+      unsigned int ret=0;
+      int n=v.size();
+      for(int i=0;i<n;i++)
+        ret=(ret<<3)+(ret>>29)+v.UNCHECKEDACCESS(i).hashValue();
+      return ret%tableSize;
+    }
+    MyHashMap(int tableSize_):
+      container(tableSize_),
+      tableSize(tableSize_)
+      {
+        assert(tableSize_>0);
+      }
+    void insert(const ZVector &v)
+    {
+      container[function(v)].insert(v);
+    }
+    void erase(ZVector const &v)
+    {
+      container[function(v)].erase(v);
+    }
+    iterator begin()
+    {
+      iterator ret(*this);
+      ++    ret;
+      return ret;
+    }
+    int size()
+    {
+      iterator i=begin();
+      int ret=0;
+      do{ret++;}while(++i);
+      return ret;
+    }
+  };
+
+
+  static ZMatrix normalizedWithSumsAndDuplicatesRemoved(ZMatrix const &a)
+  {
+    // TODO: write a version of this function which will work faster if the entries fit in 32bit
+    if(a.getHeight()==0)return a;
+    int n=a.getWidth();
+    ZVector temp1(n);
+//    ZVector temp2(n);
+    ZMatrix ret(0,n);
+    MyHashMap b(a.getHeight());
+
+    for(int i=0;i<a.getHeight();i++)
+      {
+        assert(!(a[i].isZero()));
+        b.insert(a[i].normalized());
+      }
+
+      {
+        MyHashMap::iterator i=b.begin();
+
+        do
+          {
+            MyHashMap::iterator j=i;
+            while(++j)
+              {
+                ZVector const &I=*i;
+                ZVector const &J=*j;
+                for(int k=0;k<n;k++)temp1[k]=I.UNCHECKEDACCESS(k)+J.UNCHECKEDACCESS(k);
+//                normalizedLowLevel(temp1,temp2);
+//                b.erase(temp2);//this can never remove *i or *j
+                b.erase(temp1.normalized());//this can never remove *i or *j
+              }
+          }
+          while(++i);
+      }
+    ZMatrix original(0,n);
+    {
+      MyHashMap::iterator i=b.begin();
+      do
+        {
+          original.appendRow(*i);
+        }
+      while(++i);
+    }
+
+    for(int i=0;i!=original.getHeight();i++)
+      for(int j=0;j!=a.getHeight();j++)
+        if(!dependent(original[i],a[j]))
+            {
+              ZVector const &I=original[i];
+              ZVector const &J=a[j];
+              for(int k=0;k<n;k++)temp1[k]=I.UNCHECKEDACCESS(k)+J.UNCHECKEDACCESS(k);
+//              normalizedLowLevel(temp1,temp2);
+//              b.erase(temp2);//this can never remove *i or *j
+              b.erase(temp1.normalized());//this can never remove *i or *j
+            }
+        {
+          MyHashMap::iterator i=b.begin();
+          do
+          {
+            ZVector temp=*i;
+            ret.appendRow(temp);
+          }
+          while(++i);
+      }
+    return ret;
+  }
+public:
+  static ZMatrix fastNormals(ZMatrix const &inequalities)
+  {
+    ZMatrix normals=normalizedWithSumsAndDuplicatesRemoved(inequalities);
+    for(int i=0;i!=normals.getHeight();i++)
+      if(!fastIsFacet(normals,i))
+        {
+          normals[i]=normals[normals.getHeight()-1];
+          normals.eraseLastRow();
+          i--;
+        }
+    return normals;
+  }
+  void removeRedundantRows(ZMatrix &inequalities, ZMatrix &equations, bool removeInequalityRedundancies)
+  {
+    cddinitGmp();
+    int numberOfEqualities=equations.getHeight();
+    int numberOfInequalities=inequalities.getHeight();
+    int numberOfRows=numberOfEqualities+numberOfInequalities;
+
+    if(numberOfRows==0)return;//the full space, so description is already irredundant
+
+    // dd_rowset r=NULL;
+    ZMatrix g=inequalities;
+    g.append(equations);
+
+    // dd_LPSolverType solver=dd_DualSimplex;
+    dd_MatrixPtr A=NULL;
+    dd_ErrorType err=dd_NoError;
+
+    A=ZMatrix2MatrixGmp(g,&err);
+    if (err!=dd_NoError) goto _L99;
+
+    for(int i=numberOfInequalities;i<numberOfRows;i++)
+      set_addelem(A->linset,i+1);
+
+    A->objective=dd_LPmax;
+
+    dd_rowset impl_linset;
+    dd_rowset redset;
+    dd_rowindex newpos;
+
+    if(removeInequalityRedundancies)
+      dd_MatrixCanonicalize(&A, &impl_linset, &redset, &newpos, &err);
+    else
+      dd_MatrixCanonicalizeLinearity(&A, &impl_linset, &newpos, &err);
+
+    if (err!=dd_NoError) goto _L99;
+
+    {
+      int n=A->colsize-1;
+      equations=ZMatrix(0,n);     //TODO: the number of rows needed is actually known
+      inequalities=ZMatrix(0,n);  //is known by set_card(). That might save some copying.
+
+      {
+        int rowsize=A->rowsize;
+        QVector point(n);
+        for(int i=0;i<rowsize;i++)
+          {
+            for(int j=0;j<n;j++)point[j]=Rational(A->matrix[i][j+1]);
+            ((set_member(i+1,A->linset))?equations:inequalities).appendRow(QToZVectorPrimitive(point));
+          }
+      }
+      assert(set_card(A->linset)==equations.getHeight());
+      assert(A->rowsize==equations.getHeight()+inequalities.getHeight());
+
+      set_free(impl_linset);
+      if(removeInequalityRedundancies)
+        set_free(redset);
+      free(newpos);
+
+      dd_FreeMatrix(A);
+      return;
+    }
+   _L99:
+    assert(!"Cddlib reported error when called by Gfanlib.");
+  }
+  ZVector relativeInteriorPoint(const ZMatrix &inequalities, const ZMatrix &equations)
+  {
+    QVector retUnscaled(inequalities.getWidth());
+    cddinitGmp();
+    int numberOfEqualities=equations.getHeight();
+    int numberOfInequalities=inequalities.getHeight();
+    int numberOfRows=numberOfEqualities+numberOfInequalities;
+
+    // dd_rowset r=NULL;
+    ZMatrix g=inequalities;
+    g.append(equations);
+
+    dd_LPSolverType solver=dd_DualSimplex;
+    dd_MatrixPtr A=NULL;
+    dd_ErrorType err=dd_NoError;
+
+    A=ZMatrix2MatrixGmp(g,&err);
+    if (err!=dd_NoError) goto _L99;
+    {
+      dd_LPSolutionPtr lps1;
+      dd_LPPtr lp,lp1;
+
+      for(int i=0;i<numberOfInequalities;i++)
+        dd_set_si(A->matrix[i][0],-1);
+      for(int i=numberOfInequalities;i<numberOfRows;i++)
+        set_addelem(A->linset,i+1);
+
+      A->objective=dd_LPmax;
+      lp=dd_Matrix2LP(A, &err);
+      if (err!=dd_NoError) goto _L99;
+
+      lp1=dd_MakeLPforInteriorFinding(lp);
+      dd_LPSolve(lp1,solver,&err);
+      if (err!=dd_NoError) goto _L99;
+
+      lps1=dd_CopyLPSolution(lp1);
+
+      assert(!dd_Negative(lps1->optvalue));
+
+      for (int j=1; j <(lps1->d)-1; j++)
+        retUnscaled[j-1]=Rational(lps1->sol[j]);
+
+      dd_FreeLPData(lp);
+      dd_FreeLPSolution(lps1);
+      dd_FreeLPData(lp1);
+      dd_FreeMatrix(A);
+      return QToZVectorPrimitive(retUnscaled);
+    }
+_L99:
+    assert(0);
+    return QToZVectorPrimitive(retUnscaled);
+  }
+  void dual(ZMatrix const &inequalities, ZMatrix const &equations, ZMatrix &dualInequalities, ZMatrix &dualEquations)
+  {
+    // int result;
+
+    dd_MatrixPtr A=NULL;
+    dd_ErrorType err=dd_NoError;
+
+    cddinitGmp();
+
+    A=ZMatrix2MatrixGmp(inequalities, equations, &err);
+
+    dd_PolyhedraPtr poly;
+    poly=dd_DDMatrix2Poly2(A, dd_LexMin, &err);
+
+    if (poly->child==NULL || poly->child->CompStatus!=dd_AllFound) assert(0);
+
+    dd_MatrixPtr      A2=dd_CopyGenerators(poly);
+
+    dualInequalities=getConstraints(A2,false);
+    dualEquations=getConstraints(A2,true);
+
+    dd_FreeMatrix(A2);
+    dd_FreeMatrix(A);
+    dd_FreePolyhedra(poly);
+
+    return;
+   // _L99:
+   //  assert(0);
+  }
+  // this procedure is take from cddio.c.
+  static void dd_ComputeAinc(dd_PolyhedraPtr poly)
+  {
+  /* This generates the input incidence array poly->Ainc, and
+     two sets: poly->Ared, poly->Adom.
+  */
+    dd_bigrange k;
+    dd_rowrange i,m1;
+    dd_colrange j;
+    dd_boolean redundant;
+    dd_MatrixPtr M=NULL;
+    mytype sum,temp;
+
+    dd_init(sum); dd_init(temp);
+    if (poly->AincGenerated==dd_TRUE) goto _L99;
+
+    M=dd_CopyOutput(poly);
+    poly->n=M->rowsize;
+    m1=poly->m1;
+
+    /* this number is same as poly->m, except when
+        poly is given by nonhomogeneous inequalty:
+        !(poly->homogeneous) && poly->representation==Inequality,
+        it is poly->m+1.   See dd_ConeDataLoad.
+     */
+    poly->Ainc=(set_type*)calloc(m1, sizeof(set_type));
+    for(i=1; i<=m1; i++) set_initialize(&(poly->Ainc[i-1]),poly->n);
+    set_initialize(&(poly->Ared), m1);
+    set_initialize(&(poly->Adom), m1);
+
+    for (k=1; k<=poly->n; k++){
+      for (i=1; i<=poly->m; i++){
+        dd_set(sum,dd_purezero);
+        for (j=1; j<=poly->d; j++){
+          dd_mul(temp,poly->A[i-1][j-1],M->matrix[k-1][j-1]);
+          dd_add(sum,sum,temp);
+        }
+        if (dd_EqualToZero(sum)) {
+          set_addelem(poly->Ainc[i-1], k);
+        }
+      }
+      if (!(poly->homogeneous) && poly->representation==dd_Inequality){
+        if (dd_EqualToZero(M->matrix[k-1][0])) {
+          set_addelem(poly->Ainc[m1-1], k);  /* added infinity inequality (1,0,0,...,0) */
+        }
+      }
+    }
+
+    for (i=1; i<=m1; i++){
+      if (set_card(poly->Ainc[i-1])==M->rowsize){
+        set_addelem(poly->Adom, i);
+      }
+    }
+    for (i=m1; i>=1; i--){
+      if (set_card(poly->Ainc[i-1])==0){
+        redundant=dd_TRUE;
+        set_addelem(poly->Ared, i);
+      }else {
+        redundant=dd_FALSE;
+        for (k=1; k<=m1; k++) {
+          if (k!=i && !set_member(k, poly->Ared)  && !set_member(k, poly->Adom) &&
+              set_subset(poly->Ainc[i-1], poly->Ainc[k-1])){
+            if (!redundant){
+              redundant=dd_TRUE;
+            }
+            set_addelem(poly->Ared, i);
+          }
+        }
+      }
+    }
+    dd_FreeMatrix(M);
+    poly->AincGenerated=dd_TRUE;
+  _L99:;
+    dd_clear(sum);  dd_clear(temp);
+  }
+
+
+  std::vector<std::vector<int> > extremeRaysInequalityIndices(const ZMatrix &inequalities)
+  {
+    int dim2=inequalities.getHeight();
+    if(dim2==0)return std::vector<std::vector<int> >();
+    // int dimension=inequalities.getWidth();
+
+    dd_MatrixPtr A=NULL;
+    dd_ErrorType err=dd_NoError;
+
+    cddinitGmp();
+    A=ZMatrix2MatrixGmp(inequalities, &err);
+
+    dd_PolyhedraPtr poly;
+    poly=dd_DDMatrix2Poly2(A, dd_LexMin, &err);
+
+    if (poly->child==NULL || poly->child->CompStatus!=dd_AllFound) assert(0);
+    if (poly->AincGenerated==dd_FALSE) dd_ComputeAinc(poly);
+
+    std::vector<std::vector<int> > ret;
+
+    /*
+      How do we interpret the cddlib output?  For a long ting gfan has
+      been using poly->n as the number of rays of the cone and thus
+      returned sets of indices that actually gave the lineality
+      space. The mistake was then caught later in PolyhedralCone. On Feb
+      17 2009 gfan was changed to check the length of each set to make
+      sure that it does not specify the lineality space and only return
+      those sets giving rise to rays.  This does not seem to be the best
+      strategy and might even be wrong.
+     */
+
+
+    for (int k=1; k<=poly->n; k++)
+      {
+        int length=0;
+        for (int i=1; i<=poly->m1; i++)
+          if(set_member(k,poly->Ainc[i-1]))length++;
+        if(length!=dim2)
+          {
+            std::vector<int> v(length);
+            int j=0;
+            for (int i=1; i<=poly->m1; i++)
+              if(set_member(k,poly->Ainc[i-1]))v[j++]=i-1;
+            ret.push_back(v);
+          }
+      }
+
+    dd_FreeMatrix(A);
+    dd_FreePolyhedra(poly);
+
+    return ret;
+   // _L99:
+   //  assert(0);
+   //  return std::vector<std::vector<int> >();
+  }
+
+};
+
+LpSolver lpSolver;
+
+bool ZCone::isInStateMinimum(int s)const
+{
+  return state>=s;
+}
+
+
+bool operator<(ZCone const &a, ZCone const &b)
+{
+  assert(a.state>=3);
+  assert(b.state>=3);
+
+  if(a.n<b.n)return true;
+  if(a.n>b.n)return false;
+
+  if(a.equations<b.equations)return true;
+  if(b.equations<a.equations)return false;
+
+  if(a.inequalities<b.inequalities)return true;
+  if(b.inequalities<a.inequalities)return false;
+
+  return false;
+}
+
+
+bool operator!=(ZCone const &a, ZCone const &b)
+{
+  return (a<b)||(b<a);
+}
+
+
+void ZCone::ensureStateAsMinimum(int s)const
+{
+  if((state<1) && (s==1))
+    {
+     {
+        QMatrix m=ZToQMatrix(equations);
+        m.reduce();
+        m.removeZeroRows();
+
+        ZMatrix newInequalities(0,inequalities.getWidth());
+        for(int i=0;i<inequalities.getHeight();i++)
+          {
+            QVector w=ZToQVector(inequalities[i]);
+            w=m.canonicalize(w);
+            if(!w.isZero())
+              newInequalities.appendRow(QToZVectorPrimitive(w));
+          }
+
+        inequalities=newInequalities;
+        inequalities.sortAndRemoveDuplicateRows();
+        equations=QToZMatrixPrimitive(m);
+      }
+
+      if(!(preassumptions&PCP_impliedEquationsKnown))
+      if(inequalities.getHeight()>1)//there can be no implied equation unless we have at least two inequalities
+        lpSolver.removeRedundantRows(inequalities,equations,false);
+
+      assert(inequalities.getWidth()==equations.getWidth());
+      }
+  if((state<2) && (s>=2) && !(preassumptions&PCP_facetsKnown))
+    {
+/*       if(inequalities.size()>25)
+         {
+          IntegerVectorList h1;
+          IntegerVectorList h2;
+          bool a=false;
+          for(IntegerVectorList::const_iterator i=inequalities.begin();i!=inequalities.end();i++)
+            {
+              if(a)
+                h1.push_back(*i);
+              else
+                h2.push_back(*i);
+              a=!a;
+            }
+          PolyhedralCone c1(h1,equations);
+          PolyhedralCone c2(h2,equations);
+          c1.ensureStateAsMinimum(2);
+          c2.ensureStateAsMinimum(2);
+          inequalities=c1.inequalities;
+          for(IntegerVectorList::const_iterator i=c2.inequalities.begin();i!=c2.inequalities.end();i++)
+            inequalities.push_back(*i);
+        }
+*/
+      if(equations.getHeight())
+        {
+          QMatrix m=ZToQMatrix(equations);
+          m.reduce();
+          m.REformToRREform(true);
+          ZMatrix inequalities2(0,equations.getWidth());
+          for(int i=0;i<inequalities.getHeight();i++)
+            {
+              inequalities2.appendRow(QToZVectorPrimitive(m.canonicalize(ZToQVector(inequalities[i]))));
+            }
+          inequalities=LpSolver::fastNormals(inequalities2);
+          goto noFallBack;
+        // fallBack://alternativ (disabled)
+        //   lpSolver.removeRedundantRows(inequalities,equations,true);
+        noFallBack:;
+        }
+      else
+        inequalities=LpSolver::fastNormals(inequalities);
+    }
+  if((state<3) && (s>=3))
+    {
+      QMatrix equations2=ZToQMatrix(equations);
+      equations2.reduce(false,false,true);
+      equations2.REformToRREform();
+      for(int i=0;i<inequalities.getHeight();i++)
+        {
+          inequalities[i]=QToZVectorPrimitive(equations2.canonicalize(ZToQVector(inequalities[i])));
+        }
+      inequalities.sortRows();
+      equations=QToZMatrixPrimitive(equations2);
+    }
+  if(state<s)
+    state=s;
+}
+
+void operator<<(std::ostream &f, ZCone const &c)
+{
+  f<<"Ambient dimension:"<<c.n<<std::endl;
+  f<<"Inequalities:"<<std::endl;
+  f<<c.inequalities<<std::endl;
+  f<<"Equations:"<<std::endl;
+  f<<c.equations<<std::endl;
+}
+
+
+ZCone::ZCone(int ambientDimension):
+  preassumptions(PCP_impliedEquationsKnown|PCP_facetsKnown),
+  state(1),
+  n(ambientDimension),
+  multiplicity(1),
+  linearForms(ZMatrix(0,ambientDimension)),
+  inequalities(ZMatrix(0,ambientDimension)),
+  equations(ZMatrix(0,ambientDimension)),
+  haveExtremeRaysBeenCached(false)
+{
+}
+
+
+ZCone::ZCone(ZMatrix const &inequalities_, ZMatrix const &equations_, int preassumptions_):
+  preassumptions(preassumptions_),
+  state(0),
+  n(inequalities_.getWidth()),
+  multiplicity(1),
+  linearForms(ZMatrix(0,inequalities_.getWidth())),
+  inequalities(inequalities_),
+  equations(equations_),
+  haveExtremeRaysBeenCached(false)
+  {
+  assert(preassumptions_<4);//OTHERWISE WE ARE DOING SOMETHING STUPID LIKE SPECIFYING AMBIENT DIMENSION
+  assert(equations_.getWidth()==n);
+  ensureStateAsMinimum(1);
+}
+
+void ZCone::canonicalize()
+{
+  ensureStateAsMinimum(3);
+}
+
+void ZCone::findFacets()
+{
+  ensureStateAsMinimum(2);
+}
+
+ZMatrix ZCone::getFacets()const
+{
+  ensureStateAsMinimum(2);
+  return inequalities;
+}
+
+void ZCone::findImpliedEquations()
+{
+  ensureStateAsMinimum(1);
+}
+
+ZMatrix ZCone::getImpliedEquations()const
+{
+  ensureStateAsMinimum(1);
+  return equations;
+}
+
+ZVector ZCone::getRelativeInteriorPoint()const
+{
+  ensureStateAsMinimum(1);
+//  assert(state>=1);
+
+  return lpSolver.relativeInteriorPoint(inequalities,equations);
+}
+
+ZVector ZCone::getUniquePoint()const
+{
+  ZMatrix rays=extremeRays();
+  ZVector ret(n);
+  for(int i=0;i<rays.getHeight();i++)
+    ret+=rays[i];
+
+  return ret;
+}
+
+ZVector ZCone::getUniquePointFromExtremeRays(ZMatrix const &extremeRays)const
+{
+  ZVector ret(n);
+  for(int i=0;i<extremeRays.getHeight();i++)
+    if(contains(extremeRays[i]))ret+=extremeRays[i];
+  return ret;
+}
+
+
+int ZCone::ambientDimension()const
+{
+  return n;
+}
+
+
+int ZCone::codimension()const
+{
+  return ambientDimension()-dimension();
+}
+
+
+int ZCone::dimension()const
+{
+//  assert(state>=1);
+  ensureStateAsMinimum(1);
+  return ambientDimension()-equations.getHeight();
+}
+
+
+int ZCone::dimensionOfLinealitySpace()const
+{
+  ZMatrix temp=inequalities;
+  temp.append(equations);
+  ZCone temp2(ZMatrix(0,n),temp);
+  return temp2.dimension();
+}
+
+
+bool ZCone::isOrigin()const
+{
+  return dimension()==0;
+}
+
+
+bool ZCone::isFullSpace()const
+{
+  for(int i=0;i<inequalities.getHeight();i++)
+    if(!inequalities[i].isZero())return false;
+  for(int i=0;i<equations.getHeight();i++)
+    if(!equations[i].isZero())return false;
+  return true;
+}
+
+
+ZCone intersection(const ZCone &a, const ZCone &b)
+{
+  assert(a.ambientDimension()==b.ambientDimension());
+  ZMatrix inequalities=a.inequalities;
+  inequalities.append(b.inequalities);
+  ZMatrix equations=a.equations;
+  equations.append(b.equations);
+
+  equations.sortAndRemoveDuplicateRows();
+  inequalities.sortAndRemoveDuplicateRows();
+
+  {
+    ZMatrix Aequations=a.equations;
+    ZMatrix Ainequalities=a.inequalities;
+    Aequations.sortAndRemoveDuplicateRows();
+    Ainequalities.sortAndRemoveDuplicateRows();
+    if((Ainequalities.getHeight()==inequalities.getHeight()) && (Aequations.getHeight()==equations.getHeight()))return a;
+    ZMatrix Bequations=b.equations;
+    ZMatrix Binequalities=b.inequalities;
+    Bequations.sortAndRemoveDuplicateRows();
+    Binequalities.sortAndRemoveDuplicateRows();
+    if((Binequalities.getHeight()==inequalities.getHeight()) && (Bequations.getHeight()==equations.getHeight()))return b;
+  }
+
+  return ZCone(inequalities,equations);
+}
+
+/*
+PolyhedralCone product(const PolyhedralCone &a, const PolyhedralCone &b)
+{
+  IntegerVectorList equations2;
+  IntegerVectorList inequalities2;
+
+  int n1=a.n;
+  int n2=b.n;
+
+  for(IntegerVectorList::const_iterator i=a.equations.begin();i!=a.equations.end();i++)
+    equations2.push_back(concatenation(*i,IntegerVector(n2)));
+  for(IntegerVectorList::const_iterator i=b.equations.begin();i!=b.equations.end();i++)
+    equations2.push_back(concatenation(IntegerVector(n1),*i));
+  for(IntegerVectorList::const_iterator i=a.inequalities.begin();i!=a.inequalities.end();i++)
+    inequalities2.push_back(concatenation(*i,IntegerVector(n2)));
+  for(IntegerVectorList::const_iterator i=b.inequalities.begin();i!=b.inequalities.end();i++)
+    inequalities2.push_back(concatenation(IntegerVector(n1),*i));
+
+  PolyhedralCone ret(inequalities2,equations2,n1+n2);
+  ret.setMultiplicity(a.getMultiplicity()*b.getMultiplicity());
+  ret.setLinearForm(concatenation(a.getLinearForm(),b.getLinearForm()));
+
+  ret.ensureStateAsMinimum(a.state);
+  ret.ensureStateAsMinimum(b.state);
+
+  return ret;
+}*/
+
+
+ZCone ZCone::positiveOrthant(int dimension)
+{
+  return ZCone(ZMatrix::identity(dimension),ZMatrix(0,dimension));
+}
+
+
+ZCone ZCone::givenByRays(ZMatrix const &generators, ZMatrix const &linealitySpace)
+{
+  ZCone dual(generators,linealitySpace);
+  ZMatrix inequalities=dual.extremeRays();
+  ZMatrix equations=dual.generatorsOfLinealitySpace();
+
+  return ZCone(inequalities,equations,3);
+}
+
+
+bool ZCone::containsPositiveVector()const
+{
+  ZCone temp=intersection(*this,ZCone::positiveOrthant(n));
+  return temp.getRelativeInteriorPoint().isPositive();
+}
+
+
+bool ZCone::contains(ZVector const &v)const
+{
+  for(int i=0;i<equations.getHeight();i++)
+    {
+      if(!dot(equations[i],v).isZero())return false;
+    }
+  for(int i=0;i<inequalities.getHeight();i++)
+    {
+      if(dot(inequalities[i],v).sign()<0)return false;
+    }
+  return true;
+}
+
+
+bool ZCone::containsRowsOf(ZMatrix const &m)const
+{
+  for(int i=0;i<m.getHeight();i++)
+    if(!contains(m[i]))return false;
+  return true;
+}
+
+
+bool ZCone::contains(ZCone const &c)const
+{
+  ZCone c2=intersection(*this,c);
+  ZCone c3=c;
+  c2.canonicalize();
+  c3.canonicalize();
+  return !(c2!=c3);
+}
+
+
+bool ZCone::containsRelatively(ZVector const &v)const
+{
+  ensureStateAsMinimum(1);
+//  assert(state>=1);
+  for(int i=0;i<equations.getHeight();i++)
+    {
+      if(!dot(equations[i],v).isZero())return false;
+    }
+  for(int i=0;i<inequalities.getHeight();i++)
+    {
+      if(dot(inequalities[i],v).sign()<=0)return false;
+    }
+  return true;
+}
+
+
+bool ZCone::isSimplicial()const
+{
+//  assert(state>=2);
+  ensureStateAsMinimum(2);
+  return codimension()+inequalities.getHeight()+dimensionOfLinealitySpace()==n;
+}
+
+
+ZCone ZCone::linealitySpace()const
+{
+  ZCone ret(ZMatrix(0,n),combineOnTop(equations,inequalities));
+//  ret.ensureStateAsMinimum(state);
+  return ret;
+}
+
+
+ZCone ZCone::dualCone()const
+{
+  ensureStateAsMinimum(1);
+//  assert(state>=1);
+
+  ZMatrix dualInequalities,dualEquations;
+  lpSolver.dual(inequalities,equations,dualInequalities,dualEquations);
+  ZCone ret(dualInequalities,dualEquations);
+  ret.ensureStateAsMinimum(state);
+
+  return ret;
+}
+
+
+ZCone ZCone::negated()const
+{
+  ZCone ret(-inequalities,equations,(areFacetsKnown()?PCP_facetsKnown:0)|(areImpliedEquationsKnown()?PCP_impliedEquationsKnown:0));
+//  ret.ensureStateAsMinimum(state);
+  return ret;
+}
+
+
+ZMatrix ZCone::extremeRays(ZMatrix const *generatorsOfLinealitySpace)const
+{
+//  assert((dimension()==ambientDimension()) || (state>=3));
+  if(dimension()!=ambientDimension())
+    ensureStateAsMinimum(3);
+
+  if(haveExtremeRaysBeenCached)return cachedExtremeRays;
+  ZMatrix ret(0,n);
+  std::vector<std::vector<int> > indices=lpSolver.extremeRaysInequalityIndices(inequalities);
+
+  for(unsigned i=0;i<indices.size();i++)
+    {
+      /* At this point we know lineality space, implied equations and
+         also inequalities for the ray. To construct a vector on the
+         ray which is stable under (or indendent of) angle and
+         linarity preserving transformation we find the dimension 1
+         subspace orthorgonal to the implied equations and the
+         lineality space and pick a suitable primitive generator */
+
+          /* To be more precise,
+           * let E be the set of equations, and v the inequality defining a  ray R.
+           * We wish to find a vector satisfying these, but it must also be orthogonal
+           * to the lineality space of the cone, that is, in the span of {E,v}.
+           * One way to get such a vector is to project v to E an get a vector p.
+           * Then v-p is in the span of {E,v} by construction.
+           * The vector v-p is also in the orthogonal complement to E by construction,
+           * that is, the span of R.
+           * We wish to argue that it is not zero.
+           * That would imply that v=p, meaning that v is in the span of the equations.
+           * However, that would contradict that R is a ray.
+           * In case v-p does not satisfy the inequality v (is this possible?), we change the sign.
+           *
+           * As a consequence we need the following procedure
+           * primitiveProjection():
+           *    Input: E,v
+           *    Output: A primitive representation of the vector v-p, where p is the projection of v onto E
+           *
+           * Notice that the output is a Q linear combination of the input and that p is
+           * a linear combination of E. The check that p has been computed correctly,
+           * it suffices to check that v-p satisfies the equations E.
+           * The routine will actually first compute a multiple of v-p.
+           * It will do this using floating point arithmetics. It will then transform
+           * the coefficients to get the multiple of v-p into integers. Then it
+           * verifies in exact arithmetics, that with these coefficients we get a point
+           * satisfying E. It then returns the primitive vector on the ray v-p.
+           * In case of a failure it falls back to an implementation using rational arithmetics.
+           */
+
+
+          std::vector<int> asVector(inequalities.getHeight());
+          for(unsigned j=0;j<indices[i].size();j++){asVector[indices[i][j]]=1;}
+          ZMatrix equations=this->equations;
+          ZVector theInequality;
+
+          for(unsigned j=0;j<asVector.size();j++)
+            if(asVector[j])
+              equations.appendRow(inequalities[j]);
+            else
+              theInequality=inequalities[j];
+
+          assert(!theInequality.isZero());
+
+          ZVector thePrimitiveVector;
+          if(generatorsOfLinealitySpace)
+          {
+            QMatrix temp=ZToQMatrix(combineOnTop(equations,*generatorsOfLinealitySpace));
+            thePrimitiveVector=QToZVectorPrimitive(temp.reduceAndComputeVectorInKernel());
+          }
+          else
+          {
+            QMatrix linealitySpaceOrth=ZToQMatrix(combineOnTop(this->equations,inequalities));
+
+
+            QMatrix temp=combineOnTop(linealitySpaceOrth.reduceAndComputeKernel(),ZToQMatrix(equations));
+            thePrimitiveVector=QToZVectorPrimitive(temp.reduceAndComputeVectorInKernel());
+          }
+          if(!contains(thePrimitiveVector))thePrimitiveVector=-thePrimitiveVector;
+          ret.appendRow(thePrimitiveVector);
+    }
+
+  cachedExtremeRays=ret;
+  haveExtremeRaysBeenCached=true;
+
+  return ret;
+}
+
+
+Integer ZCone::getMultiplicity()const
+{
+  return multiplicity;
+}
+
+
+void ZCone::setMultiplicity(Integer const &m)
+{
+  multiplicity=m;
+}
+
+
+ZMatrix ZCone::getLinearForms()const
+{
+  return linearForms;
+}
+
+
+void ZCone::setLinearForms(ZMatrix const &linearForms_)
+{
+  linearForms=linearForms_;
+}
+
+
+ZMatrix ZCone::quotientLatticeBasis()const
+{
+//  assert(isInStateMinimum(1));// Implied equations must have been computed in order to know the span of the cone
+  ensureStateAsMinimum(1);
+
+
+  int a=equations.getHeight();
+  int b=inequalities.getHeight();
+
+  // Implementation below could be moved to nonLP part of code.
+
+  // small vector space defined by a+b equations.... big by a equations.
+
+  ZMatrix M=combineLeftRight(combineLeftRight(
+                                                  equations.transposed(),
+                                                  inequalities.transposed()),
+                                 ZMatrix::identity(n));
+  M.reduce(false,true);
+  /*
+    [A|B|I] is reduced to [A'|B'|C'] meaning [A'|B']=C'[A|B] and A'=C'A.
+
+    [A'|B'] is in row echelon form, implying that the rows of C' corresponding to zero rows
+    of [A'|B'] generate the lattice cokernel of [A|B] - that is the linealityspace intersected with Z^n.
+
+    [A'] is in row echelon form, implying that the rows of C' corresponding to zero rows of [A'] generate
+    the lattice cokernel of [A] - that is the span of the cone intersected with Z^n.
+
+    It is clear that the second row set is a superset of the first. Their difference is a basis for the quotient.
+   */
+  ZMatrix ret(0,n);
+
+  for(int i=0;i<M.getHeight();i++)
+    if(M[i].subvector(0,a).isZero()&&!M[i].subvector(a,a+b).isZero())
+      {
+        ret.appendRow(M[i].subvector(a+b,a+b+n));
+      }
+
+  return ret;
+}
+
+
+ZVector ZCone::semiGroupGeneratorOfRay()const
+{
+  ZMatrix temp=quotientLatticeBasis();
+  assert(temp.getHeight()==1);
+  for(int i=0;i<inequalities.getHeight();i++)
+    if(dot(temp[0],inequalities[i]).sign()<0)
+      {
+        temp[0]=-temp[0];
+        break;
+      }
+  return temp[0];
+}
+
+
+ZCone ZCone::link(ZVector const &w)const
+{
+  /* Observe that the inequalities giving rise to facets
+   * also give facets in the link, if they are kept as
+   * inequalities. This means that the state cannot decrease
+   * when taking links - that is why we specify the PCP flags.
+   */
+  ZMatrix inequalities2(0,n);
+  for(int j=0;j<inequalities.getHeight();j++)
+    if(dot(w,inequalities[j]).sign()==0)inequalities2.appendRow(inequalities[j]);
+  ZCone C(inequalities2,equations,(areImpliedEquationsKnown()?PCP_impliedEquationsKnown:0)|(areFacetsKnown()?PCP_facetsKnown:0));
+  C.ensureStateAsMinimum(state);
+
+  C.setLinearForms(getLinearForms());
+  C.setMultiplicity(getMultiplicity());
+
+  return C;
+}
+
+bool ZCone::hasFace(ZCone const &f)const
+{
+  if(!contains(f.getRelativeInteriorPoint()))return false;
+  ZCone temp1=faceContaining(f.getRelativeInteriorPoint());
+  temp1.canonicalize();
+  ZCone temp2=f;
+  temp2.canonicalize();
+  return !(temp2!=temp1);
+}
+
+ZCone ZCone::faceContaining(ZVector const &v)const
+{
+  assert(n==(int)v.size());
+  assert(contains(v));
+  ZMatrix newEquations=equations;
+  ZMatrix newInequalities(0,n);
+  for(int i=0;i<inequalities.getHeight();i++)
+    if(dot(inequalities[i],v).sign()!=0)
+      newInequalities.appendRow(inequalities[i]);
+    else
+      newEquations.appendRow(inequalities[i]);
+
+  ZCone ret(newInequalities,newEquations,(state>=1)?PCP_impliedEquationsKnown:0);
+  ret.ensureStateAsMinimum(state);
+  return ret;
+}
+
+
+ZMatrix ZCone::getInequalities()const
+{
+  return inequalities;
+}
+
+
+ZMatrix ZCone::getEquations()const
+{
+  return equations;
+}
+
+
+ZMatrix ZCone::generatorsOfSpan()const
+{
+  ensureStateAsMinimum(1);
+  QMatrix l=ZToQMatrix(equations);
+  return QToZMatrixPrimitive(l.reduceAndComputeKernel());
+}
+
+
+ZMatrix ZCone::generatorsOfLinealitySpace()const
+{
+  QMatrix l=ZToQMatrix(combineOnTop(inequalities,equations));
+  return QToZMatrixPrimitive(l.reduceAndComputeKernel());
+}
+
+};
diff --git a/gfanlib/gfanlib_zcone.h b/gfanlib/gfanlib_zcone.h
new file mode 100644
index 0000000..3ca63df
--- /dev/null
+++ b/gfanlib/gfanlib_zcone.h
@@ -0,0 +1,362 @@
+/*
+ * lib_cone.h
+ *
+ *  Created on: Sep 28, 2010
+ *      Author: anders
+ */
+
+#ifndef LIB_CONE_H_
+#define LIB_CONE_H_
+
+#include "gfanlib_matrix.h"
+
+namespace gfan{
+
+
+/**
+A PolyhedralCone is represented by linear inequalities and equations. The inequalities are non-strict
+and stored as the rows of a matrix and the equations are stored as rows of a second matrix.
+
+A cone can be in one of the four states:
+0) Nothing has been done to remove redundancies. This is the initial state.
+1) A basis for the true, implied equations space has been computed. This means that
+   the implied equations have been computed. In particular the dimension of the cone is known.
+2) Redundant inequalities have been computed and have been eliminated.
+   This means that the true set of facets is known - one for each element in halfSpaces.
+3) The inequalities and equations from 2) have been transformed into a canonical form. Besides having
+   a unique representation for the cone this also allows comparisons between cones with operator<().
+
+Since moving for one state to the next is expensive, the user of the PolyhedralCone can specify flags
+at the construction of the cone informing about which things are known.
+
+PCP_impliedEquationsKnown means that the given set of equations generate the space of implied equations.
+PCP_facetsKnown means that each inequalities describe define a (different) facet of the cone.
+
+Each cone has the additional information: multiplicity and linear forms.
+The multiplicity is an integer whose default value is one. It can be set by the user.
+When a cone is projected, it can happen that the multiplicity changes according to a lattice index.
+The linear forms are stored in a matrix linearForms, whose width equals the dimension of the ambient space.
+The idea is that a collection of cones in this way can represent a piecewise linear function (a tropical rational function).
+
+Caching:
+When new properties are computed by changing state the information is stored in the object by updating equations and inequalities.
+When some other properties are computed, such as rays the result is cached in the object. Each cached property has a corresponding flag telling if a cached value has been stored.
+These methods
+for these properties are considered const. Caching only works for extreme rays at the moment.
+
+Notice:
+The lineality space of a cone C is C\cap(-C).
+A cone is ray if its dimension is 1+the dimension of the its lineality space.
+
+Should the user of this class know about the states?
+
+need to think about this...
+Always putting the cone in state 1 after something has changed helps a lot.
+Then all operations can be performed except comparing and getting facets with
+out taking the cone to a special state.
+
+
+Things to change:
+- Thomas wants operations where the natural description is the dual to be fast.
+  One way to achieve this is as Frank suggests to have a state -1, in which only
+  the generator description is known. These should be stored in the cache. If it
+  is required to move to state 0, then the inequality description is computed.
+  This sounds like a reasonable solution, but of course, what we are really storing is the dual.
+
+ - Basically all data in the object should be mutable, while almost every method should be const.
+
+ - A method should set the cone in a given state if required. The reason for this is that
+   it will be difficult for the user to figure out which state is required and therefore
+   will tend to call canonicalize when not needed.
+
+ - Cache should be added for more properties.
+
+Optimization:
+- When inequalities can be represented in 32 bit some optimizations can be done.
+
+More things to consider:
+- Does it make sense to do dimension reduction when lineality space / linear span has been
+  computed?
+
+
+When calling generated by rays, two flags should be passed.
+
+ */
+
+enum PolyhedralConePreassumptions{
+  PCP_none=0,
+  PCP_impliedEquationsKnown=1,
+  PCP_facetsKnown=2
+};
+
+class ZCone;
+ZCone intersection(const ZCone &a, const ZCone &b);
+class ZCone
+{
+  int preassumptions;
+  mutable int state;
+  int n;
+  Integer multiplicity;
+  ZMatrix linearForms;
+  mutable ZMatrix inequalities;
+  mutable ZMatrix equations;
+  mutable ZMatrix cachedExtremeRays;
+/**
+ * If this bool is true it means that cachedExtremeRays contains the extreme rays as found by extremeRays().
+ */
+  mutable bool haveExtremeRaysBeenCached;
+  void ensureStateAsMinimum(int s)const;
+
+  bool isInStateMinimum(int s)const;
+  int getState()const;
+public:
+   /**
+    * Constructs a polyhedral cone with specified equations and ineqalities. They are read off as rows
+    * of the matrices. For efficiency it is possible to specifying a PolyhedralConePreassumptions flag
+    * which tells what is known about the description already.
+    */
+     ZCone(ZMatrix const &inequalities_, ZMatrix const &equations_, int preassumptions_=PCP_none);
+
+     /**
+      * Get the multiplicity of the cone.
+      */
+     Integer getMultiplicity()const;
+     /**
+      * Set the multiplicity of the cone.
+      */
+     void setMultiplicity(Integer const &m);
+     /**
+      * Returns the matrix of linear forms stored in the cone object.
+      */
+     ZMatrix getLinearForms()const;
+     /**
+      * Store a matrix of linear forms in the cone object.
+      */
+     void setLinearForms(ZMatrix const &linearForms_);
+
+     /**
+      * Get the inequalities in the description of the cone.
+      */
+     ZMatrix getInequalities()const;
+     /**
+      * Get the equations in the description of the cone.
+      */
+     ZMatrix getEquations()const;
+     /**
+      * Compute generators of the span of the cone. They are stored as rows of the returned matrix.
+      */
+     ZMatrix generatorsOfSpan()const;
+     /**
+      * Compute generators of the lineality space of the cone. They are stored as rows of the returned matrix.
+      */
+     ZMatrix generatorsOfLinealitySpace()const;
+     /**
+      * Returns true iff it is known that every inequalities in the description defines a different facets of the cone.
+      */
+     bool areFacetsKnown()const{return (state>=2)||(preassumptions&PCP_facetsKnown);}
+     /**
+      * Returns true iff it is known that the set of equations span the space of implied equations of the description.
+      */
+     bool areImpliedEquationsKnown()const{return (state>=1)||(preassumptions&PCP_impliedEquationsKnown);}
+     /**
+      * Returns true iff the extreme rays are known.
+      */
+     bool areExtremeRaysKnown()const{return haveExtremeRaysBeenCached;}
+     /**
+      * Takes the cone to a canonical form. After taking cones to canonical form, two cones are the same
+      * if and only if their matrices of equations and inequalities are the same.
+      */
+     void canonicalize();
+     /**
+      * Computes and returns the facet inequalities of the cone.
+      */
+     ZMatrix getFacets()const;
+     /**
+      * After this function has been called all inequalities describe different facets of the cone.
+      */
+     void findFacets();
+     /**
+      * The set of linear forms vanishing on the cone is a subspace. This routine returns a basis
+      * of this subspace as the rows of a matrix.
+      */
+     ZMatrix getImpliedEquations()const;
+     /**
+      * After this function has been called a minimal set of implied equations for the cone is known and is
+      * returned when calling getEquations(). The returned equations form a basis of the space of implied
+      * equations.
+      */
+     void findImpliedEquations();
+
+     /**
+      * Constructor for polyhedral cone with no inequalities or equations. Tthat is, the full space of some dimension.
+      */
+     ZCone(int ambientDimension=0);
+
+     /**
+      * Computes are relative interior point of the cone.
+      */
+     ZVector getRelativeInteriorPoint()const;
+  /**
+     Assuming that this cone C is in state at least 3 (why not 2?), this routine returns a relative interior point v(C) of C with the following properties:
+     1) v is a function, that is v(C) is found deterministically
+     2) for any angle preserving, lattice preserving and lineality space preserving transformation T of R^n we have that v(T(C))=T(v(C)). This makes it easy to check if two cones in the same fan are equal up to symmetry. Here preserving the lineality space L just means T(L)=L.
+  */
+     ZVector getUniquePoint()const;
+  /**
+   * Takes a list of possible extreme rays and add up those actually contained in the cone.
+   */
+     ZVector getUniquePointFromExtremeRays(ZMatrix const &extremeRays)const;
+     /**
+      * Returns the dimension of the ambient space.
+      */
+     int ambientDimension()const;
+     /**
+      * Returns the dimension of the cone.
+      */
+     int dimension()const;
+     /**
+      * Returns (ambient dimension)-(dimension).
+      */
+     int codimension()const;
+     /**
+      * Returns the dimension of the lineality space of the cone.
+      */
+     int dimensionOfLinealitySpace()const;
+     /**
+      * Returns true iff the cone is the origin.
+      */
+     bool isOrigin()const;
+     /**
+      * Returns true iff the cone is the full space.
+      */
+     bool isFullSpace()const;
+
+     /**
+      * Returns the intersection of cone a and b as a cone object.
+      */
+     friend ZCone intersection(const ZCone &a, const ZCone &b);
+     /**
+      * Returns the Cartesian product of the two cones a and b.
+      */
+     friend ZCone product(const ZCone &a, const ZCone &b);
+     /**
+      * Returns the positive orthant of some dimension as a polyhedral cone.
+      */
+     static ZCone positiveOrthant(int dimension);
+     /**
+      * Returns the cone which is the sum of row span of linealitySpace and
+      * the non-negative span of the rows of generators.
+      */
+     static ZCone givenByRays(ZMatrix const &generators, ZMatrix const &linealitySpace);
+
+     /**
+      * To use the comparison operator< the cones must have been canonicalized.
+      */
+     friend bool operator<(ZCone const &a, ZCone const &b);
+     /**
+      * To use the comparison operator!= the cones must have been canonicalized.
+      */
+     friend bool operator!=(ZCone const &a, ZCone const &b);
+
+     /**
+      * Returns true iff the cone contains a positive vector.
+      */
+     bool containsPositiveVector()const;
+     /**
+      * Returns true iff the cone contains the specified vector v.
+      */
+     bool contains(ZVector const &v)const;
+     /**
+      * Returns true iff the cone contains all rows of the matrix l.
+      */
+     bool containsRowsOf(ZMatrix const &l)const;
+     /**
+      * Returns true iff c is contained in the cone.
+      */
+     bool contains(ZCone const &c)const;
+     /**
+      * Returns true iff the PolyhedralCone contains v in its relative interior. False otherwise. The cone must be in state at least 1.
+      */
+     bool containsRelatively(ZVector const &v)const;
+     /*
+      * Returns true iff the cone is simplicial. That is, iff the dimension of the cone equals the number of facets.
+      */
+     bool isSimplicial()const;
+
+     //PolyhedralCone permuted(IntegerVector const &v)const;
+
+     /**
+      * Returns the lineality space of the cone as a polyhedral cone.
+      */
+     ZCone linealitySpace()const;
+
+     /**
+      * Returns the dual cone of the cone.
+      */
+     ZCone dualCone()const;
+     /**
+      * Return -C, where C is the cone.
+      */
+     ZCone negated()const;
+     /**
+      * Compute the extreme rays of the cone, and return generators of these as the rows of a matrix.
+      * The returned extreme rays are represented by vectors which are orthogonal to the lineality
+      * space and which are primitive primitive.
+      * This makes them unique and invariant under lattice and angle preserving linear transformations
+      * in the sense that a transformed cone would give the same set of extreme rays except the
+      * extreme rays have been transformed.
+      * If generators for the lineality space are known, they can be supplied. This can
+      * speed up computations a lot.
+      */
+    ZMatrix extremeRays(ZMatrix const *generatorsOfLinealitySpace=0)const;
+    /**
+       The cone defines two lattices, namely Z^n intersected with the
+       span of the cone and Z^n intersected with the lineality space of
+       the cone. Clearly the second is contained in the
+       first. Furthermore, the second is a saturated lattice of the
+       first. The quotient is torsion-free - hence a lattice. Generators
+       of this lattice as vectors in the span of the cone are computed
+       by this routine. The implied equations must be known when this
+       function is called - if not the routine asserts.
+     */
+    ZMatrix quotientLatticeBasis()const;
+    /**
+       For a ray (dim=linealitydim +1)
+       the quotent lattice described in quotientLatticeBasis() is
+       isomorphic to Z. In fact the ray intersected with Z^n modulo the
+       lineality space intersected with Z^n is a semigroup generated by
+       just one element. This routine computes that element as an
+       integer vector in the cone. Asserts if the cone is not a ray.
+       Asserts if the implied equations have not been computed.
+     */
+    ZVector semiGroupGeneratorOfRay()const;
+
+    /**
+       Computes the link of the face containing v in its relative
+       interior.
+     */
+    ZCone link(ZVector const &w)const;
+
+    /**
+       Tests if f is a face of the cone.
+     */
+    bool hasFace(ZCone const &f)const;
+  /**
+   Computes the face of the cone containing v in its relative interior.
+   The vector MUST be contained in the cone.
+   */
+    ZCone faceContaining(ZVector const &v)const;
+    /**
+     * Computes the projection of the cone to the first newn coordinates.
+     * The ambient space of the returned cone has dimension newn.
+     */
+   // PolyhedralCone projection(int newn)const;
+    friend void operator<<(std::ostream &f, ZCone const &c);
+};
+
+};
+
+
+
+
+#endif /* LIB_CONE_H_ */
diff --git a/gfanlib/gfanlib_zfan.cpp b/gfanlib/gfanlib_zfan.cpp
new file mode 100644
index 0000000..6220b56
--- /dev/null
+++ b/gfanlib/gfanlib_zfan.cpp
@@ -0,0 +1,401 @@
+/*
+ * gfanlib_zfan.cpp
+ *
+ *  Created on: Nov 17, 2010
+ *      Author: anders
+ */
+
+#include "gfanlib_zfan.h"
+#include "gfanlib_polymakefile.h"
+
+using namespace std;
+
+namespace gfan
+{
+  static int numberOf(std::vector<std::vector<IntVector> > T, int dimension)
+  {
+    assert(dimension>=0);
+    if(dimension>=(int)T.size())return 0;
+    return T[dimension].size();
+  }
+  std::vector<std::vector<IntVector> > &ZFan::table(bool orbit, bool maximal)const
+  {
+    if(orbit)
+      {
+        if(maximal)return maximalConeOrbits;
+        return coneOrbits;
+      }
+    if(maximal)return maximalCones;
+    return cones;
+  }
+  int ZFan::numberOfConesOfDimension(int d, bool orbit, bool maximal)const
+  {
+    this->ensureComplex();
+    return numberOf(table(orbit,maximal),d);
+  }
+  ZCone ZFan::getCone(int dimension, int index, bool orbit, bool maximal)const
+  {
+    IntVector indices=getConeIndices(dimension,index,orbit,maximal);
+    return this->complex->makeZCone(indices);
+  }
+  IntVector ZFan::getConeIndices(int dimension, int index, bool orbit, bool maximal)const
+  {
+    assert(index>=0);
+    assert(index<numberOfConesOfDimension(dimension,orbit,maximal));
+    return table(orbit,maximal)[dimension][index];
+  }
+  void ZFan::ensureConeCollection()const
+  {
+    if(!coneCollection)
+      {
+        assert(0);
+      }
+  }
+  void ZFan::ensureComplex()const
+  {
+    if(!complex)
+      {
+        assert(coneCollection);
+        complex = new SymmetricComplex(coneCollection->toSymmetricComplex());
+        complex->buildConeLists(false,false,&cones);
+        complex->buildConeLists(true,false,&maximalCones);
+        complex->buildConeLists(false,true,&coneOrbits);
+        complex->buildConeLists(true,true,&maximalConeOrbits);
+      }
+  }
+  void ZFan::killComplex()const
+  {
+    if(complex)
+      {
+        delete complex;
+        complex=0;
+      }
+  }
+
+  ZFan::ZFan(std::istream &f):
+    coneCollection(0),
+    complex(0)
+  {
+//    PolyhedralFan PolyhedralFan::readFan(string const &filename, bool onlyMaximal, IntegerVector *w, set<int> const *coneIndices, SymmetryGroup const *sym, bool readCompressedIfNotSym)
+    PolymakeFile inFile;
+    //assert(0);
+     inFile.open(f);
+
+    int n=inFile.readCardinalProperty("AMBIENT_DIM").toInt();
+    int nRays=inFile.readCardinalProperty("N_RAYS").toInt();
+    ZMatrix rays=inFile.readMatrixProperty("RAYS",nRays,n);
+    int linealityDim=inFile.readCardinalProperty("LINEALITY_DIM").toInt();
+    ZMatrix linealitySpace=inFile.readMatrixProperty("LINEALITY_SPACE",linealityDim,n);
+
+    SymmetryGroup sym(n);
+    bool readingSymmetricComplex=false;
+    if(inFile.hasProperty("SYMMETRY_GENERATORS"))
+      {
+        sym.computeClosure(ZToIntMatrix(inFile.readMatrixProperty("SYMMETRY_GENERATORS",-1,n)));
+        readingSymmetricComplex=true;
+      }
+
+
+    const char *sectionName=0;
+    const char *sectionNameMultiplicities=0;
+    if(readingSymmetricComplex)
+      {
+        if(inFile.hasProperty("MAXIMAL_CONES_ORBITS"))
+          {
+            sectionName="MAXIMAL_CONES_ORBITS";
+            sectionNameMultiplicities="MULTIPLICITIES_ORBITS";
+          }
+        else
+          {
+            sectionName="CONES_ORBITS";
+          }
+      }
+    else
+      {
+        if(inFile.hasProperty("MAXIMAL_CONES"))
+          {
+            sectionName="MAXIMAL_CONES";
+            sectionNameMultiplicities="MULTIPLICITIES";
+          }
+        else
+          {
+            sectionName="CONES";
+          }
+      }
+
+    /*    if(sym || readCompressedIfNotSym)
+      {
+        sectionName=(onlyMaximal)?"MAXIMAL_CONES_ORBITS":"CONES_ORBITS";
+        sectionNameMultiplicities=(onlyMaximal)?"MULTIPLICITIES_ORBITS":"DUMMY123";
+      }
+    else
+*/
+    /*{
+        sectionName="MAXIMAL_CONES";//(onlyMaximal)?"MAXIMAL_CONES":"CONES";
+        sectionNameMultiplicities="MULTIPLICITIES";//(onlyMaximal)?"MULTIPLICITIES":"DUMMY123";
+      }
+*/
+//    ZVector w2(n);
+//    if(w==0)w=&w2;
+
+ //       SymmetryGroup sym2(n);
+ //       if(sym==0)sym=&sym2;
+
+/*  sectionName=0;
+  if(inFile.hasProperty("MAXIMAL_CONES"))
+    sectionName="MAXIMAL_CONES";
+  else
+    {  if(inFile.hasProperty("CONES"))
+      sectionName="CONES";
+    else
+      assert(0);
+    }*/
+
+  vector<list<int> > cones=inFile.readMatrixIncidenceProperty(sectionName);
+//        IntegerVectorList r;
+
+        bool hasMultiplicities=inFile.hasProperty(sectionNameMultiplicities);
+        ZMatrix multiplicities(0,0);
+        if(hasMultiplicities)multiplicities=inFile.readMatrixProperty(sectionNameMultiplicities,cones.size(),1);
+
+        ZFan ret(sym);
+
+//        log2 cerr<< "Number of orbits to expand "<<cones.size()<<endl;
+        for(unsigned i=0;i<cones.size();i++)
+        //  if(coneIndices==0 || coneIndices->count(i))
+            {
+//              log2 cerr<<"Expanding symmetries of cone"<<endl;
+              {
+                ZMatrix coneRays(0,n);
+                for(list<int>::const_iterator j=cones[i].begin();j!=cones[i].end();j++)
+                  coneRays.appendRow((rays[*j]));
+                ZCone C=ZCone::givenByRays(coneRays,linealitySpace);
+                if(hasMultiplicities)C.setMultiplicity(multiplicities[i][0]);
+//                for(SymmetryGroup::ElementContainer::const_iterator perm=sym->elements.begin();perm!=sym->elements.end();perm++)
+                  {
+//                    if(C.contains(perm.applyInverse(*w)))
+//                      {
+ //                       PolyhedralCone C2=C.permuted(*perm);
+//                        C2.canonicalize();
+//                        ret.insert(C2);
+ //                     }
+                    ret.insert(C);
+                  }
+              }
+            }
+//        return ret;
+        *this=ret;
+  }
+
+  ZFan::~ZFan()
+  {
+    if(coneCollection)
+      {
+        delete coneCollection;
+        coneCollection=0;
+      }
+    if(complex)
+      {
+        delete complex;
+        complex=0;
+      }
+  }
+  ZFan::ZFan(ZFan const& f):
+    coneCollection(0),
+    complex(0),
+    cones(f.table(0,0)),
+    maximalCones(f.table(0,1)),
+    coneOrbits(f.table(1,0)),
+    maximalConeOrbits(f.table(1,1))
+  {
+    if(f.coneCollection)
+      {
+        coneCollection=new PolyhedralFan(*f.coneCollection);
+      }
+    if(f.complex)
+      {
+        complex=new SymmetricComplex(*f.complex);
+      }
+  }
+  ZFan& ZFan::operator=(ZFan const &f)
+  {
+    if(this!=&f)
+      {
+        if(complex)
+          {
+            delete complex;
+            complex=0;
+          }
+        if(coneCollection)
+          {
+            delete coneCollection;
+            coneCollection=0;
+          }
+        if(f.coneCollection)
+          {
+            coneCollection=new PolyhedralFan(*f.coneCollection);
+          }
+        if(f.complex)
+          {
+            complex=new SymmetricComplex(*f.complex);
+          }
+      }
+    return *this;
+  }
+  ZFan::ZFan(int ambientDimension):
+    complex(0)
+  {
+    coneCollection=new PolyhedralFan(ambientDimension);
+  }
+  ZFan::ZFan(SymmetryGroup const &sym_):
+    complex(0)
+  {
+    coneCollection=new PolyhedralFan(sym_);
+  }
+  ZFan ZFan::fullFan(int n)
+  {
+    ZFan ret(n);
+    ret.insert(ZCone(ZMatrix(0,n),ZMatrix(0,n)));
+    return ret;
+  }
+  ZFan ZFan::fullFan(SymmetryGroup const &sym_)
+  {
+    ZFan ret(sym_);
+    ret.insert(ZCone(ZMatrix(0,sym_.sizeOfBaseSet()),ZMatrix(0,sym_.sizeOfBaseSet())));
+    return ret;
+  }
+  int ZFan::getAmbientDimension()const
+  {
+    if(complex)
+      return complex->getAmbientDimension();
+    if(coneCollection)
+      return coneCollection->getAmbientDimension();
+    assert(0);
+    return 0;
+  }
+  int ZFan::getCodimension()const
+  {
+    if(complex)
+      return complex->getAmbientDimension()-complex->getMaxDim();
+    if(coneCollection)
+      return coneCollection->getAmbientDimension()-coneCollection->getMaxDimension();
+    assert(0);
+    return 0;
+  }
+  int ZFan::getDimension()const
+  {
+    if(complex)
+      return complex->getMaxDim();
+    if(coneCollection)
+      return coneCollection->getMaxDimension();
+    assert(0);
+    return 0;
+  }
+  int ZFan::getLinealityDimension()const
+  {
+    if(complex)
+      return complex->getLinDim();
+    if(coneCollection)
+      return coneCollection->dimensionOfLinealitySpace();
+    assert(0);
+    return 0;
+  }
+  ZVector ZFan::getFVector()const
+  {
+    ensureComplex();
+    return complex->fvector();
+  }
+  bool ZFan::isSimplicial()const
+  {
+    ensureComplex();
+    return complex->isSimplicial();
+  }
+  bool ZFan::isPure()const
+  {
+    ensureComplex();
+    return complex->isPure();
+  }
+  bool ZFan::isComplete()const
+  {
+    ensureConeCollection();
+    if(coneCollection->isEmpty())
+      return 0;
+    int ambientdim=coneCollection->getAmbientDimension();
+    int linealitydim=coneCollection->dimensionOfLinealitySpace();
+    return (ambientdim==linealitydim);
+  }
+  void ZFan::insert(ZCone const &c)
+  {
+    ensureConeCollection();
+    killComplex();
+    coneCollection->insert(c);
+  }
+  void ZFan::remove(ZCone const &c)
+  {
+    ensureConeCollection();
+    killComplex();
+    coneCollection->remove(c);
+  }
+
+/*  ZFan::ZFan(int ambientDimension):
+    theFan(ambientDimension)
+  {
+
+  }*/
+/*
+ZFan::ZFan(SymmetryGroup const &sym):
+  theFan(sym)
+{
+}
+*/
+
+std::string ZFan::toString(int flags)const
+{
+  ensureComplex();
+
+  //  std::string s=complex->toString(flags);
+//  killComplex();
+//  return s;//complex->getMinDim(),complex->getMaxDim(),0,0);
+  return complex->toString(flags);//complex->getMinDim(),complex->getMaxDim(),0,0);
+//  return "NEEDTOFIXTHIS";
+
+  //return theFan.toString();
+}
+
+std::string ZFan::toStringJustRaysAndMaximalCones(int flags)const
+{
+  ensureComplex();
+  return complex->toStringJustRaysAndMaximalCones(flags);
+}
+
+/*int ZFan::getAmbientDimension()const
+{
+  return theFan.getAmbientDimension();
+}
+
+
+void ZFan::insert(ZCone const &c)
+{
+  theFan.insert(c);
+}
+*/
+/*
+void ZFan::remove(ZCone const &c)
+{
+  theFan.remove(c);
+}
+*/
+/*
+ZFan::coneIterator ZFan::conesBegin()const
+{
+  return theFan.conesBegin();
+}
+
+ZFan::coneIterator ZFan::conesEnd()const
+{
+  return theFan.conesEnd();
+}
+*/
+  //  static PolyhedralFan readFan(string const &filename, bool onlyMaximal=true, IntegerVector *w=0, set<int> const *conesIndice=0, SymmetryGroup const *sym=0, bool readCompressedIfNotSym=false);
+
+}
diff --git a/gfanlib/gfanlib_zfan.h b/gfanlib/gfanlib_zfan.h
new file mode 100644
index 0000000..33dc306
--- /dev/null
+++ b/gfanlib/gfanlib_zfan.h
@@ -0,0 +1,172 @@
+/*
+ * gfanlib_zfan.h
+ *
+ *  Created on: Nov 17, 2010
+ *      Author: anders
+ */
+
+#ifndef GFANLIB_ZFAN_H_
+#define GFANLIB_ZFAN_H_
+
+/*
+ * gfanlib_polyhedralfan.h
+ *
+ *  Created on: Nov 16, 2010
+ *      Author: anders
+ */
+
+#ifndef GFANLIB_ZFAN_H_INCLUDED
+#define GFANLIB_ZFAN_H_INCLUDED
+
+#include <set>
+#include <list>
+#include <map>
+#include "gfanlib_polyhedralfan.h"
+#include "gfanlib_symmetriccomplex.h"
+
+namespace gfan{
+
+/**
+ * This class represents a Polyhedral fan with the combined features of a SymmetricComplex, and
+ * a PolyhedralFan (which we regards as some collection of cones of the fan with the property that every cone
+ * of the fan is a face of these (up to action by the group)).
+ * It is important to distinguis between the cones of the collection, the cones of the fan as a mathematical object, and the orbits of cones of the fan.
+ *
+ *
+ * TEMPLATES SHOULD BE HIDDEN
+ */
+class ZFan
+{
+  mutable PolyhedralFan *coneCollection;
+  mutable SymmetricComplex *complex;
+  mutable std::vector<std::vector<IntVector > > cones;
+  mutable std::vector<std::vector<IntVector > > maximalCones;
+  mutable std::vector<std::vector<IntVector > > coneOrbits;
+  mutable std::vector<std::vector<IntVector > > maximalConeOrbits;
+
+
+  //  SymmetryGroup sym;
+
+  /**
+   * Functions that makes the symmetric complex invalid:
+   * insert() and construction
+   *
+   * Functions that make the cone collection invalid:
+   * readFan()
+   *
+   */
+  void ensureConeCollection()const;
+  void ensureComplex()const;
+  void killComplex()const;
+public:
+  std::vector<std::vector<IntVector> > &table(bool orbit, bool maximal)const;
+  ~ZFan();
+  ZFan():
+    coneCollection(0),
+    complex(0)
+  {}
+  ZFan(ZFan const& f);
+  /**
+   *
+   * To read from string, do the following:
+   *       std::string test="TEST";
+   *   std::istringstream s(test);
+   *   ZFan G(s);
+   *
+   */
+  ZFan(std::istream  &f);
+  ZFan& operator=(ZFan const &f);
+  /**
+   * Creates an empty fan in the ambient space of dimension n.
+   * It is a mistake to:
+   *  specify a negative ambientDimension.
+   */
+  ZFan(int ambientDimension);
+  /**
+   * Creates an empty fan in the ambient space with dimension equal to the number of elements being permuted by the group.
+   * The fan will have the symmmetries given by sym_ associated.
+   */
+  ZFan(SymmetryGroup const &sym_);
+  /**
+   * Creates the fan in dimension n consisting of the n-dimensional space.
+   */
+  static ZFan fullFan(int n);
+  /**
+   * Creates the full space as a fan in the ambient space with dimension equal to the number of elements being permuted by the group.
+   * The fan will have the symmetries given by sym_ associated.
+   */
+  static ZFan fullFan(SymmetryGroup const &sym_);
+  /**
+   * Reads from stream
+   */
+//  static ZFan readFan(string const &filename, bool onlyMaximal=true, IntegerVector *w=0, set<int> const *conesIndice=0, SymmetryGroup const *sym=0, bool readCompressedIfNotSym=false);
+  /**
+   * Writes to string
+   */
+  std::string toString(int flags=0)const;
+  std::string toStringJustRaysAndMaximalCones(int flags=0)const;
+  /**
+   * Returns the dimension of the ambient space.
+   */
+  int getAmbientDimension()const;
+  int getCodimension()const;
+  int getDimension()const;
+  int getLinealityDimension()const;
+  ZVector getFVector()const;
+  bool isSimplicial()const;
+  bool isPure()const;
+  bool isComplete()const;
+  /**
+   * Inserts c into the fan.
+   * It is a mistake to insert a cone which live in a space of the wrong dimension.
+   * It is a mistake to insert a cone which does not result in a fan satisfying the nice intersection properties of a fan.
+   * However, the second mistake will not cause the code to crash, but only give undefined results.
+   *
+   * The method insert() is expensive in the sense that calling it may require part of the representation
+   * of the fan to be recomputed. The recomputation only happens on request. Therefore it is expensive
+   * to have alternating calls to for example "insert()" and "numberOfConesOfDimension()".
+   *
+   * Notice that insert() has the effect of reordering cones, orbits and rays of the fan.
+   */
+  void insert(ZCone const &c);
+  void remove(ZCone const &c);
+  /**
+   * Returns the number of cones of dimension d in the collection.
+   */
+  int numberOfConesOfDimension(int d, bool orbit, bool maximal)const;
+  int numberOfConesInCollection()const;
+  /**
+   * Returns the largest dimension of a cone in the fan. If the fan is empty, then -1 is returned.
+   */
+  int dimension()const;
+  /**
+   * Returns the dimension of the lineality space of the fan. Notice that the lineality space of the
+   * empty fan is the ambient space.
+   */
+  // int getLinealityDimension();
+  /**
+   * Returns the cone in the collection given by the index. It is a mistake to specify an index which
+   * is out of range.
+   */
+  ZCone const &getConeInCollection(int index)const;
+  /**
+   * Returns the cone in the cone of the fan
+   */
+  ZCone getCone(int dimension, int index, bool orbit, bool maximal)const;
+  IntVector getConeIndices(int dimension, int index, bool orbit, bool maximal)const;
+
+//  ZFan expand()const;
+//  SymmetryGorup recoverAllSymmetries()const;
+
+/*  typedef PolyhedralConeList::const_iterator coneIterator;
+  PolyhedralFan::coneIterator conesBegin()const;
+  PolyhedralFan::coneIterator conesEnd()const;
+*/
+
+};
+
+}
+
+#endif
+
+#endif /* GFANLIB_ZFAN_H_ */
diff --git a/git-version-gen b/git-version-gen
new file mode 100755
index 0000000..4f010f3
--- /dev/null
+++ b/git-version-gen
@@ -0,0 +1,24 @@
+#!/bin/bash
+
+export GIT_WORK_TREE=`dirname "$0"`
+export GIT_DIR="$GIT_WORK_TREE/.git"
+
+## :'%h on %ci by %an: "%s"' --abbrev-commit | sed 's/\"/\\\"/g'
+if [ -d "$GIT_WORK_TREE/.git" ] && v=`git log --pretty=format:'%h' --abbrev-commit -1 2>/dev/null` ;
+then
+ if dirty=`sh -c "git diff-index --name-status HEAD 2>/dev/null | sed -e 's|^\([A-Z]\).*|\1|g' | tr -d '\012'"` && [ -n "$dirty" ];
+ then
+   echo -n "$v|$dirty"
+ else
+   echo -n "$v"
+ fi
+# exit 0
+else
+ F="$1"
+ if [ -r "$F" ];
+ then
+   cat "$F"
+ else
+   echo -n "UNKNOWN_GIT_VERSION"
+ fi
+fi
diff --git a/kernel/COPYING b/kernel/COPYING
new file mode 100644
index 0000000..1b73f40
--- /dev/null
+++ b/kernel/COPYING
@@ -0,0 +1,30 @@
+                        SINGULAR version 4-0
+
+                     University of Kaiserslautern
+
+      Department of Mathematics and  Centre for Computer Algebra
+
+           Authors: G.-M. Greuel, G. Pfister, H. Schoenemann
+
+                        Copyright (C) 1986-2014
+
+
+
+                               *NOTICE*
+
+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 ( version 2 or version 3 of the License ).
+
+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 (see GPL)
+
+Please send any comments or bug reports to
+<singular at mathematik.uni-kl.de>.
+
diff --git a/kernel/ChangeLog b/kernel/ChangeLog
new file mode 100644
index 0000000..2c808ac
--- /dev/null
+++ b/kernel/ChangeLog
@@ -0,0 +1,856 @@
+Thu Jul 15 17:10:09 CEST 2010 dreyer:
+* ambigous overload of si_max resolved
+Fri Jan 19 17:56:20 CET 2001 hannes:
+* mod, div for intvec fixed
+* highcorner for global case fixed
+* highcorner for qring fixed
+Tue Feb  1 09:33:35 MET 2000 hannes: summary of changes
+* lift changed: - uses interanlly a different algorithm
+                  (for SB and NON-SB unified)
+                - can be used with an optional 3rd argument (a matrix name),
+                  if given, the "matrix of units" will be stored in it
+* new command: division (extension of lift)
+     division(M,SM) returns a list (T,U,R) with SM*U+R=M*T
+* new monomial ordering (internal change only):
+   use of inline function instead of a function pointer
+   (possible point for difficulties: mcompSchrB(polys.cc), pSetSchreyerOrdM
+   (polys.cc))
+* new Library:
+   spectrum.lib: interface to Stefan Endrass' spectrum routines
+   (Stefan Endrass/H.Schoenemann)
+   (still incomplete, requires a "special" Singular)
+* new Library:
+   CaMuReg.lib: PROCEDURES FOR COMPUTING CASTELNUOVO-MUMFORD REGULARITY
+   Authors:I.Bermejo/Ph.Gimenez/G.-M.Greuel
+   (not included in the documemtation, not included in the tests)
+* new command: hres
+    - computes a free resolution of an ideal using Hilbert-driven algorithm
+* new commands: convhull, simplex (M.Wenk)
+  (not documented, not included in the documemtation, not included in the tests)
+
+Fri Aug 13 13:20:01 MET DST 1999 hannes
+* made fe_fgets_stdin an function pointer instead of a macro
+  ( febase.cc febase.h feread.cc misc.cc sing_mp.cc tesths.cc)
+
+Thu Aug 12 12:57:49 MET DST 1999 hannes
+* integrated "spectrum" by Stefan Endrass, inactive by default
+  (Makefile.in claptmpl.cc feResource.cc iparith.cc mod2.h.in
+  tok.h GMPrat.h GMPrat.cc kmatrix.h multicnt.h multicnt.cc
+  npolygon.h npolygon.cc semic.h semic.cc spectrum.h spectrum.cc
+  splist.h splist.cc)
+
+Thu Apr 15 19:26:07 MET DST 1999 hannes
+  * start to implement debugger (sdb.h,sdb.cc, febase*, iplib,cc, scanner)
+
+Tue Mar 16 15:54:02 MET 1999 hannes
+  * introduced new routine ERROR(string) (iparith.cc, tok.h)
+  * added trace flag for proc (ipid.cc iplib.cc, febase*)
+
+Mon Mar  8 18:27:26 MET 1999 hannes
+  * access to coeff-description via functions (1. approach)
+    (rChar,  rInternalChar, rField_is_Zp, rField_is_Q,
+     rField_is_R, rField_is_GF, rField_is_Zp_a, rField_is_Q_a,
+     rField_has_simple_inverse)
+
+Wed Dec 16 16:02:07 1998  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+        * clapsing.cc: debugging output modified
+
+Thu Oct 22 14:21:17 MEST 1998 <krueger at mathematik.uni-kl.de>
+        * tesths.cc,subexpr.h,subexpr.cc,ipshell.h,ipshell.cc,iplib.cc
+        * ipid.h,ipid.cc,ipassign.cc,iparith.cc
+          - Added assignment <package>=<package> via ref-counter
+            rewriten killhdl for packages
+          - Added libname,language to packages
+          - exportto(Up,...) 'Up' defined in syMake
+          - listvar() shows toplevel-packages too.
+
+Mon Oct 19 16:01:18 MESZ 1998 hannes
+* hannes: limitations on length of arguments removed (was 200 chars)
+  (iplib.cc)
+
+Thu Oct 15 15:54:05 MEST 1998 <krueger at mathematik.uni-kl.de>
+        * extra.cc,grammar.y,ipid.cc,ipid.h,iplib.cc,ipshell.cc
+        * ipshell.h,ring.cc,structs.h,tesths.cc,mod2.h.in
+          Replaced ring *iiLocalRing[] by a stack (class namerec)
+          To use old method define USE_IILOCALRING in mod2.h
+          Old method incompatible with HAVE_NAMESPACES!
+
+1998-10-14  Olaf Bachmann  <obachman at mathematik.uni-kl.de>
+
+        * sing_mp.cc (slOpenMPLaunch): added slKill as link function
+        * added --MPrsh to slOpenLaunch
+
+Wed Jul  1 15:25:23 MET DST 1998 hannes:
+* fixed bug with quotient: M:module(0) returns (1), not ([1])
+
+Tue Jun 30 18:30:02 1998  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+        * claptmp.cc (tmax, tmin(Var, Var)): instantiations added
+
+Fri Jun 19 10:01:59 MET DST 1998 hannes
+* hannes: changed back: quot is now from standard.lib,
+                        quotient the C-version
+                        (iparith.cc LIB/standard.lib)
+
+Thu Jun 18 19:27:27 MET DST 1998 hannes
+        * error handling (grammar.y iparith.cc iplib.cc)
+          (leaving of levels, local vars, messages,..)
+          The reason:
+               proc p { intvec w; w[0]; }
+               proc p2 {int i;p();"huhu";}
+               p2(); int i; listvar();
+
+1998-06-13  Olaf Bachmann  <obachman at mathematik.uni-kl.de>
+
+        * feread.cc: explicit declaration of stuff we need from readline.h
+
+1998-06-12  Olaf Bachmann  <obachman at mathematik.uni-kl.de>
+
+        * polys.cc: pComp for simple orderings based on only three
+        routines (no variation for # of variables)
+
+        * spolys0.cc (spGSpolyLoop): globally replaced by spSpolyLoop_General
+
+Fri Jun 12 12:11:06 MET DST 1998 hannes
+        * minor optimizations in polys.cc, kutil.* kstd1.cc:
+          pass pointers, not structures to posIn[LT],
+          do not check for NULL in pDeg (as pFDeg does not check)
+
+Wed Jun  3 16:20:22 1998  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+        * Makefile.in (DOCS): target removed
+          (DISTFILES): reference to `$(DOC)' removed
+          (distclean): reference to `$(docdir)' removed
+
+Wed Jun 03 16:46:06 1998    <pohl at FUECHSE>
+
+        * claptmpl.cc: instantiation for operator == (CFFactor, CFFactor)
+          added
+
+Tue Jun  2 17:28:48 MET DST 1998 hannes
+        * introduced /* */ comments
+        * some code cleanups
+Fri May 29 17:00:27 MET DST 1998 hannes
+        * change res to nres (cmd), resu to res(standard.lib)
+          including changes to libs, docs (partially)
+Wed May 27 19:13:10 MET DST 1998 hannes
+        * removed #define HAVE_GMP and non-gmp-parts
+Wed May 20 15:03:28 1998  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+        * LIB/primdec.lib (info): info string reformated
+
+1998-05-19  Olaf Bachmann  <obachman at mathematik.uni-kl.de>
+
+        * find_exec.c (find_executable): add "." top path, if under WINNT
+        and MSDOS display
+
+        * mmutil.c (mmCheckDBMCB): use _end only #ifdef unix
+
+        * ideals.cc (idDelLmEquals): added idDelLmEqual == simplify(16),
+        and idDelDiv == simplify(32); improved pComparePolys
+
+1998-05-18  Olaf Bachmann  <obachman at mathematik.uni-kl.de>
+
+        * extra.cc (jjSYSTEM): changed "whoami" --> "Singular", added
+        "nblocks"
+
+Sat May 16 14:14:20 MET DST 1998 hannes
+* avoid multiple objects of the same name (fix keepring)
+Fri May 15 18:02:57 MET DST 1998 hannes
+* added type conversion: ideal(map) -> map
+Fri May 15 13:06:32 MET DST 1998 hannes
+* added syntax: kill (....)
+Thu May 14 16:40:43 MET DST 1998 hannes
+* fixed bug in CoeffOfKBase (ideals.cc)
+Thu May 14 12:01:53 MET DST 1998 hannes
+* a ring with a coeff. field GF(p,n) cannot be constructed
+  without gftables (ring.cc)
+Wed May 13 16:52:09 MET DST 1998 hannes
+        * changed syntax of NOT (does not require () any more)
+Tue May 12 16:58:13 MET DST 1998 hannes
+        * changed return type of option(): none -> string
+Tue May 12 11:57:50 MET DST 1998 hannes
+        * added "lres"
+1998-05-08  Olaf Bachmann  <obachman at mathematik.uni-kl.de>
+
+        * extra.cc (jjSYSTEM): put all undocumented system calls into
+        #ifdef HAVE_EXTENDED_SYSTEM which is _not_ defined by default
+
+        * exteded system("random") to always return the seed of the random
+        generator
+
+Thu May  7 19:49:34 MET DST 1998 hannes
+        * added syntax rule "proc <name> <arglist> <string> <body>"
+        * speedup for feReadLine
+
+Wed May  6 19:10:59 1998  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+        * find_exec.c (find_executable): bug fix.  Recognizes
+          `../Singular' properly.
+
+Tue May  5 14:06:12 1998  Jens/Kai
+
+        * libparse.l: message fix
+
+Thu Apr 30 19:16:45 MET DST 1998 hannes
+        * fixed "missing e-o-buffer" for long lines in febase.inc
+
+Wed Apr 29 18:26:19 MET DST 1998 hannes
+        * added filed list_length tossyStrategy
+        ( for conversion list <-> resolution): syz.h, syz1.cc, iparith.cc
+1998-04-29  Olaf Bachmann  <obachman at mathematik.uni-kl.de>
+
+        * mmutil.c (mmGetIndex): new implementation: Use generated lookup
+        table (mmutil.inc) instead of "binary" search on size
+
+Tue Apr 28 19:56:46 MET DST 1998 hannes
+  * ipassign.cc: fixed assignment of resolution to list: need ipMoveId
+1998-04-28  Olaf Bachmann  <obachman at mathematik.uni-kl.de>
+
+        * kstd2.cc (redHomog): Some more ouput for KDEBUG && TEST_OPT_DEBUG
+
+        * mminit.cc: introduced memory(2) which measures physical memory
+        consumption using the system call sbrk (this never lies!)
+
+Mon Apr 27 18:07:21 MET DST 1998 hannes
+        * use ReAlloc for enlargeT, enlargeL  (kutil.cc)
+Mon Apr 27 16:45:41 MET DST 1998 hannes
+        * fixed conversion of factory 0 to poly NULL (clapconv.cc)
+
+1998-04-27  Olaf Bachmann  <obachman at mathematik.uni-kl.de>
+
+        * febase.cc (myfread): introduced myfread and myfopen which assure
+        that newlines in text files are always \n
+
+Fri Apr 24 19:14:42 1998  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+        * clapsing.cc (FACTORY_GCD_STAT, singclap_divide_content):
+          dependency on FACTORY_GCD_TEST removed.  Statistics are now done
+           using `FACTORY_GCDSTAT' and `FCATORY_CONTSTAT' which are defined
+           to expand to nothing if `FACTORY_GCD_TIMING' is off.
+
+        * extra.cc (FACTORY_GCD_STAT): dependency on `FACTORY_GCD_TEST'
+          removed.  Includes `gcd_stat.h' in dependency on
+          `FACTORY_CGD_STAT'.
+
+        * extra.cc (jjSYSTEM): new command `gcdstat' in dependency on
+          `FACTORY_GCD_STAT'
+
+Fri Apr 24 18:25:23 MET DST 1998 hannes
+  * fixed bug in maps.cc: size of monom is not pMonomSize but mmGetSpecSize()
+  * changed header in tesths.cc
+  * changed handling of ring changes (polys*.cc ring.cc)
+Thu Apr 23 20:53:06 MET DST 1998 hannes
+  * removed END_GRAMMAR ("RETURN") from iparith.cc, grammar.y
+Thu Apr 23 20:16:24 MET DST 1998 hannes
+  * fixed bug in rKill of Q-rings (ring.cc, polys.cc)
+
+Thu Apr 23 11:12:48 1998  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+        * clapsing.cc (FACTORY_CFTROUT, FACTORY_CFAOUT): stuipd bug fix
+
+        * clapsing.cc (FACTORY_ALGOUT, FACTORY_CFTROUT, FACTORY_CFAOUT):
+          new macros for debugging data transfer to Factory
+           (singclap_divide_content, singclap_alglcm,
+           singclap_algdividecontent): use the new macros
+
+        * clapsing.cc (FACTORY_GCD_TIMING, singclap_divide_content,
+          singclap_alglcm, singclap_algdividecontent): dependency on
+          FACTORY_GCD_TEST removed.  Timings are now done directly using
+          `TIMING_START' and `TIMING_END' which are defined to expand to
+          nothing if `FACTORY_GCD_TIMING' is off.
+
+        * extra.cc (FACTORY_GCD_TIMING): dependency on FACTORY_GCD_TEST
+          removed
+
+        * longalg.cc (naNormalize): gcd calculation depends on #define
+          `FACTORY_GCD_TEST'
+
+Wed Apr 22 09:42:35 MET DST 1998 hannes
+  * several changes concerning stdfac
+    (kstdfac.cc, kutil.cc kutil.h)
+
+Tue Apr 21 15:19:10 MET DST 1998 hannes/jens
+  * gdc in Q(a) returns "not implemented" (clapsing.cc)
+
+Tue Apr 21 12:30:44 1998  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+        * clapsing.cc  (singclap_gcd): checks for `NULL' removed
+
+        * clapsing.cc, extra.cc (FACTORY_GCD_TEST, FACTORY_GCD_STAT,
+           FACTORY_GCD_DEBOUT, FACTORY_GCD_TIMING): new #defines for gcd
+          testing
+        * clapsing.cc (singclap_divide_content, singclap_alglcm,
+          singclap_algdividecontent): code added for factory testing.
+            Wrapped by #defines `FACTORY_GCD_TEST', `FACTORY_GCD_STAT',
+           `FACTORY_GCD_DEBOUT', and `FACTORY_GCD_TIMING'.
+        * extra.cc (jjSYSTEM): code added for factory testing.  Wrapped
+          by #defines `FACTORY_GCD_TEST' and `FACTORY_GCD_TIMING'.
+
+Fri Apr 17 09:53:53 MET DST 1998 hannes
+ * fixed a minor but very nasty bug: nlSetMap was resetting npPrimeM
+    (longrat.cc)
+
+1998-04-21  Olaf Bachmann  <obachman at mathematik.uni-kl.de>
+
+        * mmprivat.h: Got rid off mmheap.cc, "inlined" mmPutMemory
+
+        * longalg.h:  Exponents in parameter (polys) are typedef'ed to
+        EXPONENT_TYPE
+
+1998-04-20  Olaf Bachmann  <obachman at mathematik.uni-kl.de>
+
+        * mmallocb.c: Merged with mmheap.c.
+
+1998-04-16  Olaf Bachmann  <obachman at mathematik.uni-kl.de>
+
+        * mpsr_PutPoly.cc: Took out normalization of rational numbers
+        before they are put -- might have side effects
+
+        * extra.cc: added system("--option") which returns value of
+        option; in debug mode: system("OptionValues") lists all option
+        values
+
+        * sing_mp.cc: use long option names for MP link options
+        * MPtcp:launch: Uses find_exec as default application
+
+        *  tesths.cc: New (handling of) command line options (long
+        options, usage of getopt_long): Parse more than one argument
+        script, etc ..
+        *  added getopt.[c,h]for parsing of command lines
+
+        * mod2.h.in, configure.in: Got rid off str* tests
+
+1998-04-07  Olaf Bachmann  <obachman at mathematik.uni-kl.de>
+
+        * mpsr_Put.cc (mpsr_PutDump): dump does not dump LIB string any more
+
+        * extra.cc (jjSYSTEM): added System("whoami") to return full
+        executable pathname of running Singular
+
+Tue Apr  7 10:27:50 MET DST 1998 hannes
+        * fixed scanner bug: ignoring { and } in <block> (scanner.l)
+
+1998-04-06  Olaf Bachmann  <obachman at mathematik.uni-kl.de>
+
+        * spSpolyLoop.h: neww calling interface for spGetSpolyLoop
+
+        * kstd1.cc (kNF): moved strat->ak field initailization out of
+        initBuchMora into single routines
+
+        * febase.cc (feGetSearchPath): added feGetSearchPath; changed
+        algorithm for searching files: $SINGULARPATH -> relative to
+        executable -> burnt-in locations
+        * added find_exec.c to get absolute pathname of executable
+
+Mon Apr  6 14:23:52 1998  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+        * claptmpl.cc: instantiation for `tabs()' added
+
+Sat Apr  4 00:52:58 MET DST 1998 Kai Krueger <krueger at mathematik.uni-kl.de>
+        * iplib.cc libparse.cc libparse.h libparse.l misc.cc LIB/*.lib
+          Changed help for libraries.
+
+Wed Apr  1 20:55:15 MET DST 1998 hannes
+        * mpsr_Tok.cc,tok.h: minor fix, removed VERBOSE_CMD
+        * iparith.cc ipconv.cc: added conversion list <-> resolution
+        * lists.cc, syz1.cc : fixed bug in conversion (list<->res.):
+          handling "empty" case
+        * scanner.l: added option: %option always-interactive
+
+Tue Mar 31 10:47:06 MET DST 1998 hannes
+        * feread.cc: fixed handling of empty history
+        * clapsing.cc: fixed gcd(0,..) and gcd(..,0) -> pOne()
+        * febase.h/febase.inc: renaming of scanner variables
+          ( yy_blocklineno, yy_noeof)
+        * febase.inc: increased speed in feReadLine
+        * minor changes in scanner/grammar/iparith.cc (example)
+
+1998-03-27  Olaf Bachmann  <obachman at mathematik.uni-kl.de>
+
+        * longalg.cc (naDBTest): fixed lines for number tests
+
+        * added spSpolyLoop.inc to repository
+
+        * algmap.cc (maAlgpolyMap): fixed bug which changed preimage
+
+1998-03-23  Olaf Bachmann  <obachman at mathematik.uni-kl.de>
+
+        * taged version 1.1.7 -- unconditional fast version
+
+        * polys-impl.cc, polys.cc: No COMP_FAST any more
+
+        * Makefile.in: Introduced variable PERL, set by configure
+
+        * kstdfac.cc (kStratCopy): kModW iv is not copied, but just the
+        pointer is set
+
+1998-03-18  Olaf Bachmann  <obachman at mathematik.uni-kl.de>
+
+        * Makefile.in: added Singularb target for bprof
+
+        * polys-impl.h, polys-comp.h: Cleaned up COMP_FAST and related
+        #defines
+
+1998-03-16  Olaf Bachmann  <obachman at mathematik.uni-kl.de>
+
+        * polys-impl.h: no #define COMP_FAST
+
+        * configure.in,Makefile.in: check for flex -P; increased version
+        number to 1.1.7
+
+Fri Mar 13 16:16:27 MET 1998 hannes
+  * fixed: Singular crashed while changing the minpoly in GF(q)
+    (ipassign.cc)
+
+Fri Mar  6 13:27:45 MET 1998 Kai Krueger <krueger at mathematik.uni-kl.de>
+        * new: libparse.l,libparse.cc,utils.cc,ytils.h
+          scanner for a quick check of singular-libraries.
+        * Makefile.in,mod2.h.in,iplib.cc,structs.h,subexpr.h
+          use a scanner when loading libraries.
+        * grammar.y,ipassign.cc,subexpr.h
+          procinfo: added position of end of proc-definition
+                    added flag for 'static'-proc (proc that can only be used
+                          in the library they are defined).
+        * LIB: deform.lib,finvar.lib,hnoether.lib,normal.lib,presolve.lib
+               primdec.lib,tex.lib
+          made fixes requested by libparse (s.a. brackets, ....)
+
+1998-03-04  Olaf Bachmann  <obachman at mathematik.uni-kl.de>
+
+        * febase.h: added macro assume()
+
+        * spSpolyLoop.cc: Automatic generation of SpolyLoops using
+        spSpolyLoop.pl
+
+        * kstd*.cc: New calling interface to get SpolyLoop
+
+        * ring.h: Introduced rOrderType_t
+
+Mon Mar  2 16:18:25 MET 1998 hannes
+   * changed handling of "echo" in examples: do not report file + lineno
+     (febase.inc,lib0lib.res, inoutlib.res, mem.res, homlib.res)
+
+Fri Feb 27 15:02:10 MET 1998 hannes
+   * new input scheme: many modifications to febase.h, febase.inc,
+     febase.cc, scanner.l, grammar.y, iplib.cc
+
+Tue Feb 17 18:43:11 MET 1998 hannes
+        * added additional factorization check after redTail
+          (kstdfac.cc)
+
+1998-02-17  Olaf Bachmann  <obachman at mathematik.uni-kl.de>
+
+        * longalg.cc (napWrite): made it globally available to support
+        FACTORY_DEBUG_OUT
+
+        * clapsing.cc (singclap_algdividecontent): inserted
+        FACTORY_DEBUG_OUT
+
+Mon Feb 16 10:43:38 MET 1998 hannes
+   * added HAVE_TCL to ring.cc
+
+Mon Feb  9 12:28:21 MET 1998 hannes
+   * added tests for coeff-filed GF(q), added stbus for GF(q)-conversion
+     (clapconv.cc clapsing.cc clapconv.h)
+
+Tue Jan 27 19:45:19 MET 1998 hannes
+   *  bug fixes for TEST_MAC_ORDER (binom.* polys-impl.h, spSpolyLoop.cc)
+      (binom.* poly-impl.* spSpolyLoop.cc)
+
+Mon Jan 26 18:40:43 MET 1998 hannes
+   * changes in iparith.cc for define: PROC_BUG
+     useful, if c++ cannot type cast proc variables
+
+Sat Jan 24 18:21:24 MET 1998 hannes
+   * bug fixes for TEST_MAC_ORDER (binom.* polys-impl.h, spSpolyLoop.cc)
+
+Sat Jan 17 18:56:34 MET 1998 hannes
+   * changes for TEST_MAC_ORDER, part 3 (binom.cc, binom.h, spSpolyLoop.cc)
+
+Sat Jan 17 18:21:15 MET 1998 hannes
+        * removed duplicate _memcpyW from mmalloc.c
+        * fixed type cast in iplib.cc
+        * changes for TEST_MAC_ORDER, part 2 (binom.cc, binom.h, spSpolyLoop.cc)
+
+Fri Jan 16 15:30:07 MET 1998 Kai Krueger <krueger at mathematik.uni-kl.de>
+        * extra.cc,febase.cc,febase.inc,grammar.y,iparith.cc
+        * ipassign.cc,ipid.cc,ipid.h,iplib.cc,ipshell.h,misc.cc
+        * mpsr_Put.cc,mpsr_Put.h,silink.cc,structs.h,subexpr.cc,subexpr.h
+        * tesths.cc
+          Implementation of new proc-scheme done.
+
+Fri Jan 16 14:51:07 MET 1998 Kai Krueger <krueger at mathematik.uni-kl.de>
+        * Makefile.in,tests/mpcheck,teste/comparecheck:
+          fixed use of correct Singular during checks
+
+Fri Jan 16 09:23:07 MET 1998
+        * changes for TEST_MAC_ORDER, part 1 (hannes)
+
+Wed Jan 14 15:36:04 1998  Olaf Bachmann  <obachman at mathematik.uni-kl.de>
+
+        * polys-impl.h (pMonAddFast): fixed handling of component
+
+        * mmutil.c: added _memcpyW for DO_DEEP_PROFILE
+
+        * binom.h: #undef TEST_MAC_ORDER as default
+
+        * polys-impl.h: fixes to make things clearer and for
+          NO_EXP_VECTOR_OPS
+
+        * Makefile.in (Singularp): use static linking for
+
+Fri Dec 19 17:22:26 1997  Jens Schmidt  <schmidt at mathematik.uni-kl.de>
+
+        * claptmpl.cc: template instantiation for `Array<REvaluation>'
+          added
+
+        * fglmcomb.cc, fglmhom.cc, fglmzero.cc, claptmpl.cc: #include
+          directives fixed (templates/list.h renamed to
+           templates/ftmpl_list.h)
+
+Thu Dec 18 15:23:29 MET 1997
+        * hannes:
+        - removed type "binary" and handling routines
+        (iparith.cc ipid.cc subexpr.cc tok.h)
+        - fixed m16ex (doc/examples.doc)
+        - fixed reference (doc/singular.doc, doc/start.doc)
+
+Wed Dec 17 09:47:58 MEZ 1997 Kai Krueger <krueger at mathematik.uni-kl.de>
+        * test/dbm_test.[in/out]: rewrite of dbm-tests.
+
+Tue Dec 16 16:59:41 1997  Olaf Bachmann  <obachman at mathematik.uni-kl.de>
+
+        * polys-impl.h: Introduced COMP_NO_EXP_VECTOR_OPS -- which turns
+        off "vector techniques" of monomial operations, i.e. does
+        everything exponent-wise
+
+Mon Dec 15 23:31:56 1997  Olaf Bachmann  <obachman at mathematik.uni-kl.de>
+
+        * polys-impl.h: Various small bug - fixes and changes in
+          preparation of COMP_FAST merge: hilbert series, maps are
+          ok; sres and syz are still buggy; small things still need to be
+          checked;
+
+Fri Dec 12 15:38:19 1997  Olaf Bachmann  <obachman at mathematik.uni-kl.de>
+
+        * mmallocb.c (mmDBFreeBlock): introduced UNREG_MEM_PATTERN which,
+          when defined, inserts unregular memory pattern in
+          allocated/freed memory
+
+        * all: changed dangerous pNew calls to pInit's
+
+Fri Dec  5 18:43:47 MET 1997
+        * hannes: fix to ideals.cc: avoid pGetExp(p,0)
+
+Thu Dec  4 16:13:31 MEZ 1997 Kai Krueger <krueger at mathematik.uni-kl.de>
+        * ndbm.cc: don't replace bcopy by memcpy if possible, otherwise
+          the database (>1024 bytes) will be corrupted.
+        - added check for bcopy() in configure.
+
+Wed Dec  3 16:14:51 1997  Olaf Bachmann  <obachman at mathematik.uni-kl.de>
+
+        * Many changes to prepare for implementation of fast comparison
+                  schemes: Here are only a few:
+        - added file polys-impl.h which implements low-level poly stuff
+        - removed file polys2.cc, added polys-impl.cc
+        - added Singularp target to Make
+        - prepared configure for setting of exponent type
+        - got rid of as many direct p->exp[..] accesses as possible
+        - added file spSpolyLoop.cc spSpolyLoop.h polys-comp.h
+        * polys-impl.h: if you defined COMP_FAST, then fast polynomial
+                  comparsions are eanbled (still needs a lot of debugging)
+
+
+Fri Oct 31 05:45:25 1997  Olaf Bachman  <bachman at bombelli.dm.unipi.it>
+
+        * polys1.cc et al: got rid of p[Get/Set]ExpV routines, provided
+                  pCopy2 instead
+
+Wed Oct  8 12:22:47 1997  Olaf Bachmann  <obachman at mathematik.uni-kl.de>
+
+        * increased version number to 1.1.3
+
+        * ndbm.cc: Solaris compatibility: #define bcopy bzero, bcmp;
+                  #include <fcntl.h>
+        * configure.in: added check for fcntl.h sys/types.h sys/stat.h, ucblib
+          ensured that either lgmp or lsmallgmp is in $LIBS
+
+Tue Sep 16 15:45:44 MET DST 1997
+        * hannes: changed/corrected/clean naNormalize, naLcm, pCleardenom, pContent
+            (polys1.cc, longalg.cc)
+            added singclap_alglcm (clapconv.cc, clapsing.cc)
+
+Tue Sep  9 11:05:28 MET DST 1997
+        * hannes: flex-staff is now in febase.inc
+               changed tutorial (doc/examples.doc, version-no: doc/tutor.tex)
+
+Fri Aug 15 11:44:13 MESZ 1997  Kai Krueger <krueger at mathematik.uni-kl.de>
+        * ndbm.cc: fix open-bug  for dos
+          default mode of open is ascii, we need binary mode.
+
+Thu Aug 14 18:04:04 1997  Olaf Bachmann  <obachman at mathematik.uni-kl.de>
+        and anne
+
+        * Makefile.in, mod2.h.in, configure.in: cleaned up for dos
+          cross-compilation
+
+Tue Aug 12 19:08:20 MET DST 1997
+        * hannes: added nExactDiv to numbers
+        * hannes: corrected open bug in sing_dbm.cc (could only "r")
+                  simplified sing_dbm.cc (many tests already in silink.cc)
+                  added "mod" (as an alias to "%")
+                  updated singular.doc: div/mod
+                                        DBM: links
+        * hannes: ANSI-conversion in ndbm.cc
+          (added return types, include files)
+
+Fri Aug  8 14:54:28 1997  Olaf Bachmann  <obachman at mathematik.uni-kl.de>
+
+        * Makefile.in ndbm.[cc,h]: Together with krueger: Added files
+          ndbm.[cc,h]; no longer linking with libdbm, instead,
+          user supplied files; added dbm_test; small changes to sing_dbm.cc
+
+Fri Aug  8 12:56:44 MET DST 1997
+        * hannes: introduced "div" for integer division
+          grammar.*, iparith.cc, singular.doc
+        * changed version to 1.1.2/August
+
+Thu Aug  7 14:51:59 1997  Olaf Bachmann  <obachman at mathematik.uni-kl.de>
+
+        * mpsr_Get.cc (GetCopCommandLeftv): made +/* to binary ops
+
+        * longrat.[h,cc]: added number   nlInit(number i) to initialize a
+                  number, i.e. get it into the right Singular state
+
+Wed Jul 16 12:57:22 MET DST 1997: hannes
+        * introduced '.singularrc', modified loading of satndard.lib
+          (tesths.cc)
+Tue Jul 15 13:57:46 MET DST 1997: hannes
+        * added call to proc in from standard.lib in tesths.cc
+
+Wed Jul  9 17:50:23 MET DST 1997: hannes/siebert
+        * added new type (resolution)
+        -> extra.cc, ipid.cc, iparith.cc, ipconv.cc, syz.h, syz1.cc
+
+Fri Jun 20 12:18:10 1997  Olaf Bachmann  <obachman at ratchwum.mathematik.uni-kl.de (Olaf Bachmann)>
+
+        * tesths.cc (main): fixed condition of mprs_ttGen execution
+
+Thu Jun 19 10:49:10 1997  Olaf Bachmann  <obachman at ratchwum.mathematik.uni-kl.de (Olaf Bachmann)>
+
+        * mpsr_Put.h: corrected efinitions of MP_AnnotReqValTree, MP_AnnotReqValNode
+
+Tue Jun 17 11:47:47 1997  Olaf Bachmann  <obachman at ratchwum.mathematik.uni-kl.de (Olaf Bachmann)>
+
+        * Makefile.in (Singular): added mod2.h to dependencies of iparith.inc
+
+        * tok.h: no discrimination of mac for inline definition any more
+
+Wed Jun 11 09:56:05 1997  Olaf Bachmann  <obachman at ratchwum.mathematik.uni-kl.de (Olaf Bachmann)>
+
+        * mpsr_Tok.cc (cmd_dictcops): changed names of some MP_Cops
+
+        * longrat.[cc,h], tesths.cc, Makefile.in, configure.in:
+          added support for smallgmp
+
+Tue Jun 10 17:25:28 1997  Olaf Bachmann  <obachman at ratchwum.mathematik.uni-kl.de (Olaf Bachmann)>
+
+        * sing_mp.cc: Got rid off warnings, when incomplete link specs
+
+Thu Jun  5 15:16:19 1997  Olaf Bachmann  <obachman at ratchwum.mathematik.uni-kl.de (Olaf Bachmann)>
+
+        * tests/mpcheck: added check for correct remote shell
+
+Sun May 25 14:06:12 1997  Olaf Bachmann  <obachman at ratchwum.mathematik.uni-kl.de (Olaf Bachmann)>
+
+        * configure.in: Fixed handling of CXXFLAGS -- it is not touched if
+          set as env var
+
+Fri May 23 11:40:14 1997  Olaf Bachmann  <obachman at schlupp.mathematik.uni-kl.de (Olaf Bachmann)>
+
+        * Makefile.in: Changed dist target to cp; make distclean
+
+Wed May 21 08:56:19 1997  Olaf Bachmann  <obachman at ratchwum.mathematik.uni-kl.de (Olaf Bachmann)>
+
+        * mpsr_Tok.cc: fixed dependencies/generation of mpsr_Tok.inc
+
+        * tesths.cc (main): made -v option gmp v1.3 clean
+
+Tue May 20 14:02:42 1997  Olaf Bachmann  <obachman at ratchwum.mathematik.uni-kl.de (Olaf Bachmann)>
+
+        * misc.cc: Put #include <factory.h> into #ifdef HAVE_FACTORY brackets
+
+* hannes: ipshell.cc: fixed a bug in iiExport (multiple exports in rings)
+          subexpr.cc: implemented sleftv::Copy for ring/qring
+          syz1.cc: added missing idSkipZeros to LaScala*
+
+Wed May 14 16:40:19 1997  Olaf Bachmann  <obachman at ratchwum.mathematik.uni-kl.de (Olaf Bachmann)>
+
+        * Makefile.in: changed mpcheck.data so that the brain-dead sed on
+          the suns does not mess up the output on files with long lines
+
+Tue May 13 11:32:41 1997  Olaf Bachmann  <obachman at ratchwum.mathematik.uni-kl.de (Olaf Bachmann)>
+
+        * claptmpl.cc: changed template initializiation of libfac, so that
+          class.cc and tmpl_inst.h does not need to be included
+
+Mon May 12 16:48:14 1997  Olaf Bachmann  <obachman at ratchwum.mathematik.uni-kl.de (Olaf Bachmann)>
+
+        * misc.cc: Added / to Help_File and Info_File
+
+Tue May  6 08:29:57 1997  Olaf Bachmann  <obachman at ratchwum.mathematik.uni-kl.de (Olaf Bachmann)>
+
+        * added factorycheck target in Makefile.in
+
+        * Makefile.in (configure): took out rules which automatically
+          reruns autoconf. Print out warning, instead
+
+        * misc.cc, configure.in, mod2.h.in:
+            added SINGULAR_INFODIR to search for info files
+
+        * configure.in: Added AC_SUBST(WITH_LIBFAC, WITH_MP, WITH_FACTORY)
+
+Mon May  5 10:31:15 1997  Olaf Bachmann  <obachman at ratchwum.mathematik.uni-kl.de (Olaf Bachmann)>
+
+        * #include "factory" instead of include "singfactory"
+
+        * mod2.h.in: define buildin_gmp, if HAVE_GMP and macintosh
+
+Sun May  4 11:14:44 1997  Olaf Bachmann  <obachman at ratchwum.mathematik.uni-kl.de (Olaf Bachmann)>
+
+        * Added make target mpcheck; Update INSTALL file
+
+        * mpsr_PutPoly.cc (PutRationalNumber): Normalize if number->s == 0
+          and not if number->s == 2
+
+        * mpsr_GetPoly.cc (GetGaloisNumber): Introduced special routines,
+          since npInit op in GetModuloNumber messed things up
+
+Sat May  3 00:07:55 1997  Olaf Bachmann  <obachman at ratchwum.mathematik.uni-kl.de (Olaf Bachmann)>
+
+        * Makefile.in (CPPFLAGS): put -I. before other CPPFLAGS
+
+        * febase.cc (feFopen): fixed bug in opening library from
+          SINGULAR_DATADIR: SINGULAR_DATADIR is appended to
+          getenv("SINGULARPATH")
+
+        * small mpsr Changes to reflect some name changes of MP Dicts
+
+        * configure.in Makefile.in: new scheme for updating Makefile mod2.h
+          based on time-stamps
+
+Fri May  2 17:29:32 1997  Olaf Bachmann  <obachman at ratchwum.mathematik.uni-kl.de (Olaf Bachmann)>
+
+        * mpsr.h: reflected changes of MP version 1.1.2 (Dicts in MP.h)
+
+        * Fixed small bug in configure.in
+
+Mon Apr 28 21:00:07 1997  Olaf Bachmann  <obachman at ratchwum.mathematik.uni-kl.de (Olaf Bachmann)>
+
+        * Added README, INSTALL, COPYING file to distribution
+
+        * tesths.cc (main): slightly changed Singular banner; fixed
+          display of version number
+
+Fri Apr 25 16:59:31 1997  Olaf Bachmann  <obachman at ratchwum.mathematik.uni-kl.de (Olaf Bachmann)>
+
+        * fixed configure.in s.t. sprintf test is correct
+
+        * Changed SingularPath to SINGULARPATH
+
+        * fixed sys/times.h and sys/time.h confusion
+
+        * Various changes to reflect new configure (versions defined in
+          configure.in, changed HAVE_LIBFACTORY into HAVE_FACTORY, data
+          dir is pasted from configure into mod2.h and used from there in
+          feFopen.
+
+        * Added configure facility, repalced mod2.h by mod2.h.in Makefile
+          by Makefile.in
+
+Fri Apr 18 09:47:22 1997  Olaf Bachmann  <obachman at ratchwum.mathematik.uni-kl.de (Olaf Bachmann)>
+
+        * silink.cc (DumpAsciiIdhdl): LIB string is dumped without type
+          declaration
+
+        * mpsr_Get.cc (InitIdentifierLeftv): used mpsr_SetCurrRing(r,
+          TRUE) so that pOne works if no ring did previously exist.
+
+        * iparith.cc: Added jjPROC3.
+
+Tue Apr 15 12:07:17 1997  Olaf Bachmann  <obachman at ratchwum.mathematik.uni-kl.de (Olaf Bachmann)>
+
+        * silink.cc (slStandardInit): changed Ascii type specifyer from
+          "ascii" to "Ascii" for consistency
+
+        * iparith.cc : added #else branch to #ifdef HAVE_FGLM in proc table
+
+        *  (extra.cc): system("sh",command) returns exit status of command
+
+Thu Apr 10 11:59:41 1997  Olaf Bachmann  <obachman at ratchwum.mathematik.uni-kl.de (Olaf Bachmann)>
+
+        * remote quit is now arranged using MP_CopMpQuit
+
+        * Updated mpsr_* files for new naming convention of MP v:1.1.2
+
+Tue Apr  8 10:43:48 1997  Olaf Bachmann  <obachman at ratchwum.mathematik.uni-kl.de (Olaf Bachmann)>
+
+        * Reimplemented link structures. Cleaned it up. Introduced assignment
+link = link. Fixed some bugs in asciidump. Made proc's work for MP links.
+
+Sat Mar 29 16:01:39 1997  Olaf Bachmann  <obachman at ratchwum.mathematik.uni-kl.de (Olaf Bachmann)>
+
+        * silink.cc (DumpQring): Takes care of dumping a Qring
+        (slInit): enable ascii link specification of the form "filename
+        mode:w"
+
+Fri Mar 28 14:12:05 1997  Olaf Bachmann  <obachman at ratchwum.mathematik.uni-kl.de (Olaf Bachmann)>
+
+        * Added routines dump(link) and getdump(link) for ascii and MP
+          links
+
+        * ipconv.cc (dConvertTypes): added int->module conversion so that
+          'module m = 0' works
+
+        * iparith.cc (jjVAR1): added LINK_CMD to list of typeof(...)
+
+Thu Mar 27 21:20:20 1997  Olaf Bachmann  <obachman at ratchwum.mathematik.uni-kl.de (Olaf Bachmann)>
+
+        * added real time timer (rtimer) analog to timer
+
+        * added command-line option "-d ticks_per_second" and "-m
+          min_displayed_time_in_sec" and chahnged timer accordingly
+
+        * added some #ifdef HAVE_FGLM in fglm*.cc
+
+
+Wed Mar 26 14:02:15 1997  Olaf Bachmann  <obachman at ratchwum.mathematik.uni-kl.de (Olaf Bachmann)>
+
+        * added reference counter to links, updated slKill, slCopy, slInit
+        * various small bug fixes for Batch mode
+
+Mon Mar 24 14:27:26 1997  Olaf Bachmann  <obachman at ratchwum.mathematik.uni-kl.de (Olaf Bachmann)>
+
+        * sing_mp.cc (slOpenWriteMPFile): Added append and write mode to
+          open MP:file
+
+Sun Mar 23 20:48:41 1997  Olaf Bachmann  <obachman at ratchwum.mathematik.uni-kl.de (Olaf Bachmann)>
+
+        * mpsr_Get.cc (InitIdentifierLeftv): Fixed bug which did not do
+          pSetm(p) after creating a poly out of a variable
+
+Thu Mar 20 11:57:00 1997  Olaf Bachmann  <obachman at schlupp.mathematik.uni-kl.de (Olaf Bachmann)>
+
+        * sing_mp.cc (slInitBatchLink): initialized silink such that
+          l->argv[0] == "MP:connect" (otherwise, slInitMP failed)
+
+Wed Mar 19 15:38:08 1997  Olaf Bachmann  <obachman at schlupp.mathematik.uni-kl.de (Olaf Bachmann)>
+
+        * hannes fixed maFindPerm to reflect new names <->parameter scheme
+
+        * sing_mp.cc (mpsr_IsMPLink): fixed it
+
+        * Makefile (tags): added target tags
+
diff --git a/kernel/GBEngine/Makefile.am b/kernel/GBEngine/Makefile.am
new file mode 100644
index 0000000..5a221d4
--- /dev/null
+++ b/kernel/GBEngine/Makefile.am
@@ -0,0 +1,23 @@
+ACLOCAL_AMFLAGS=-I ../../m4
+AM_CPPFLAGS=-I${top_srcdir} -I${top_builddir} -I${top_srcdir}/libpolys -I${top_builddir}/libpolys \
+${FACTORY_INCLUDES} $(OMALLOC_INCLUDES) $(RESOURCES_INCLUDES) \
+${NTL_CFLAGS} $(FLINT_CFLAGS) ${GMP_CFLAGS}
+
+noinst_LTLIBRARIES=libGBEngine.la
+libGBEngine_la_SOURCES=khstd.cc kstdfac.cc kstd1.cc kstd2.cc kutil.cc nc.cc sca.cc gr_kstd2.cc kspoly.cc kpolys.cc syz.cc syz0.cc syz1.cc syz2.cc syz3.cc units.cc tgb.cc tgbgauss.cc f5data.cc f5lists.cc f5gb.cc f5c.cc ratgring.cc shiftgb.cc ringgb.cc janet.cc
+
+libGBEngine_la_includedir=$(includedir)/singular/kernel/GBEngine
+libGBEngine_la_include_HEADERS=syz.h kstdfac.h kutil.h khstd.h kstd1.h units.h ratgring.h shiftgb.h nc.h kInline.h tgb.h ringgb.h tgbgauss.h tgb_internal.h f5c.h f5data.h f5gb.h f5lists.h janet.h
+
+
+
+TESTS_ENVIRONMENT = SINGULARPATH='${abs_top_builddir}/libpolys/polys/.libs:${abs_top_builddir}/factory/gftables'
+TESTS_ENVIRONMENT += SINGULAR_ROOT_DIR='${abs_top_builddir}'
+
+TESTS = test
+check_PROGRAMS = $(TESTS)
+test_SOURCES = test.cc
+test_LDADD   = libGBEngine.la ${builddir}/../combinatorics/libcombinatorics.la ${builddir}/../libkernelCommon.la
+
+CLEANFILES = $(TESTS)
+
diff --git a/kernel/GBEngine/Makefile.in b/kernel/GBEngine/Makefile.in
new file mode 100644
index 0000000..5dc9528
--- /dev/null
+++ b/kernel/GBEngine/Makefile.in
@@ -0,0 +1,1113 @@
+# Makefile.in generated by automake 1.13.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 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@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+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@
+TESTS = test$(EXEEXT)
+check_PROGRAMS = $(am__EXEEXT_1)
+subdir = kernel/GBEngine
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/build-aux/depcomp \
+	$(libGBEngine_la_include_HEADERS) \
+	$(top_srcdir)/build-aux/test-driver
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_append_compile_flags.m4 \
+	$(top_srcdir)/m4/ax_append_flag.m4 \
+	$(top_srcdir)/m4/ax_append_link_flags.m4 \
+	$(top_srcdir)/m4/ax_check_compile_flag.m4 \
+	$(top_srcdir)/m4/ax_check_link_flag.m4 \
+	$(top_srcdir)/m4/ax_compute_relative_paths.m4 \
+	$(top_srcdir)/m4/ax_normalize_path.m4 \
+	$(top_srcdir)/m4/ax_prefix_config_h.m4 \
+	$(top_srcdir)/m4/ax_pthread.m4 \
+	$(top_srcdir)/m4/ax_python_embed.m4 \
+	$(top_srcdir)/m4/ax_python_with_version.m4 \
+	$(top_srcdir)/m4/cpu-check.m4 $(top_srcdir)/m4/dbm-check.m4 \
+	$(top_srcdir)/m4/flags.m4 $(top_srcdir)/m4/flint-check.m4 \
+	$(top_srcdir)/m4/gfanlib-check.m4 \
+	$(top_srcdir)/m4/gmp-check.m4 \
+	$(top_srcdir)/m4/google-perftools.m4 \
+	$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+	$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+	$(top_srcdir)/m4/lt~obsolete.m4 \
+	$(top_srcdir)/m4/mathic-check.m4 $(top_srcdir)/m4/ntl-check.m4 \
+	$(top_srcdir)/m4/options.m4 $(top_srcdir)/m4/p-procs.m4 \
+	$(top_srcdir)/m4/polymake-check.m4 \
+	$(top_srcdir)/m4/readline-check.m4 $(top_srcdir)/configure.ac
+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 =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+libGBEngine_la_LIBADD =
+am_libGBEngine_la_OBJECTS = khstd.lo kstdfac.lo kstd1.lo kstd2.lo \
+	kutil.lo nc.lo sca.lo gr_kstd2.lo kspoly.lo kpolys.lo syz.lo \
+	syz0.lo syz1.lo syz2.lo syz3.lo units.lo tgb.lo tgbgauss.lo \
+	f5data.lo f5lists.lo f5gb.lo f5c.lo ratgring.lo shiftgb.lo \
+	ringgb.lo janet.lo
+libGBEngine_la_OBJECTS = $(am_libGBEngine_la_OBJECTS)
+AM_V_lt = $(am__v_lt_ at AM_V@)
+am__v_lt_ = $(am__v_lt_ at AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 = 
+am__EXEEXT_1 = test$(EXEEXT)
+am_test_OBJECTS = test.$(OBJEXT)
+test_OBJECTS = $(am_test_OBJECTS)
+test_DEPENDENCIES = libGBEngine.la \
+	${builddir}/../combinatorics/libcombinatorics.la \
+	${builddir}/../libkernelCommon.la
+AM_V_P = $(am__v_P_ at AM_V@)
+am__v_P_ = $(am__v_P_ at AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_ at AM_V@)
+am__v_GEN_ = $(am__v_GEN_ at AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_ at AM_V@)
+am__v_at_ = $(am__v_at_ at AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+DEFAULT_INCLUDES = -I. at am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \
+	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+	$(AM_CXXFLAGS) $(CXXFLAGS)
+AM_V_CXX = $(am__v_CXX_ at AM_V@)
+am__v_CXX_ = $(am__v_CXX_ at AM_DEFAULT_V@)
+am__v_CXX_0 = @echo "  CXX     " $@;
+am__v_CXX_1 = 
+CXXLD = $(CXX)
+CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+	$(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CXXLD = $(am__v_CXXLD_ at AM_V@)
+am__v_CXXLD_ = $(am__v_CXXLD_ at AM_DEFAULT_V@)
+am__v_CXXLD_0 = @echo "  CXXLD   " $@;
+am__v_CXXLD_1 = 
+SOURCES = $(libGBEngine_la_SOURCES) $(test_SOURCES)
+DIST_SOURCES = $(libGBEngine_la_SOURCES) $(test_SOURCES)
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+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__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
+am__installdirs = "$(DESTDIR)$(libGBEngine_la_includedir)"
+HEADERS = $(libGBEngine_la_include_HEADERS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors_dummy = \
+  mgn= red= grn= lgn= blu= brg= std=; \
+  am__color_tests=no
+am__tty_colors = { \
+  $(am__tty_colors_dummy); \
+  if test "X$(AM_COLOR_TESTS)" = Xno; then \
+    am__color_tests=no; \
+  elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+    am__color_tests=yes; \
+  elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+    am__color_tests=yes; \
+  fi; \
+  if test $$am__color_tests = yes; then \
+    red=''; \
+    grn=''; \
+    lgn=''; \
+    blu=''; \
+    mgn=''; \
+    brg=''; \
+    std=''; \
+  fi; \
+}
+am__recheck_rx = ^[ 	]*:recheck:[ 	]*
+am__global_test_result_rx = ^[ 	]*:global-test-result:[ 	]*
+am__copy_in_global_log_rx = ^[ 	]*:copy-in-global-log:[ 	]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+  recheck = 1; \
+  while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+    { \
+      if (rc < 0) \
+        { \
+          if ((getline line2 < ($$0 ".log")) < 0) \
+	    recheck = 0; \
+          break; \
+        } \
+      else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+        { \
+          recheck = 0; \
+          break; \
+        } \
+      else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+        { \
+          break; \
+        } \
+    }; \
+  if (recheck) \
+    print $$0; \
+  close ($$0 ".trs"); \
+  close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+  print "fatal: making $@: " msg | "cat >&2"; \
+  exit 1; \
+} \
+function rst_section(header) \
+{ \
+  print header; \
+  len = length(header); \
+  for (i = 1; i <= len; i = i + 1) \
+    printf "="; \
+  printf "\n\n"; \
+} \
+{ \
+  copy_in_global_log = 1; \
+  global_test_result = "RUN"; \
+  while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+    { \
+      if (rc < 0) \
+         fatal("failed to read from " $$0 ".trs"); \
+      if (line ~ /$(am__global_test_result_rx)/) \
+        { \
+          sub("$(am__global_test_result_rx)", "", line); \
+          sub("[ 	]*$$", "", line); \
+          global_test_result = line; \
+        } \
+      else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+        copy_in_global_log = 0; \
+    }; \
+  if (copy_in_global_log) \
+    { \
+      rst_section(global_test_result ": " $$0); \
+      while ((rc = (getline line < ($$0 ".log"))) != 0) \
+      { \
+        if (rc < 0) \
+          fatal("failed to read from " $$0 ".log"); \
+        print line; \
+      }; \
+      printf "\n"; \
+    }; \
+  close ($$0 ".trs"); \
+  close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/   &   /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this.  Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+  --color-tests "$$am__color_tests" \
+  --enable-hard-errors "$$am__enable_hard_errors" \
+  --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test.  Creates the
+# directory for the log if needed.  Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log.  Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT.  Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup);					\
+$(am__vpath_adj_setup) $(am__vpath_adj)			\
+$(am__tty_colors);					\
+srcdir=$(srcdir); export srcdir;			\
+case "$@" in						\
+  */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;;	\
+    *) am__odir=.;; 					\
+esac;							\
+test "x$$am__odir" = x"." || test -d "$$am__odir" 	\
+  || $(MKDIR_P) "$$am__odir" || exit $$?;		\
+if test -f "./$$f"; then dir=./;			\
+elif test -f "$$f"; then dir=;				\
+else dir="$(srcdir)/"; fi;				\
+tst=$$dir$$f; log='$@'; 				\
+if test -n '$(DISABLE_HARD_ERRORS)'; then		\
+  am__enable_hard_errors=no; 				\
+else							\
+  am__enable_hard_errors=yes; 				\
+fi; 							\
+case " $(XFAIL_TESTS) " in				\
+  *[\ \	]$$f[\ \	]* | *[\ \	]$$dir$$f[\ \	]*) \
+    am__expect_failure=yes;;				\
+  *)							\
+    am__expect_failure=no;;				\
+esac; 							\
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed).  The result is saved in the shell variable
+# '$bases'.  This honors runtime overriding of TESTS and TEST_LOGS.  Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+  bases='$(TEST_LOGS)'; \
+  bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+  bases=`echo $$bases`
+RECHECK_LOGS = $(TEST_LOGS)
+AM_RECURSIVE_TARGETS = check recheck
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+  case '$@' in \
+    */*) \
+      case '$*' in \
+        */*) b='$*';; \
+          *) b=`echo '$@' | sed 's/\.log$$//'`; \
+       esac;; \
+    *) \
+      b='$*';; \
+  esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT at .log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+	$(TEST_LOG_FLAGS)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BUILTIN_LIBS = @BUILTIN_LIBS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CDDGMPCPPFLAGS = @CDDGMPCPPFLAGS@
+CDDGMPLDFLAGS = @CDDGMPLDFLAGS@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATA_DIR = @DATA_DIR@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DOC_DIR = @DOC_DIR@
+DOXYGEN = @DOXYGEN@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FACTORY_INCLUDES = @FACTORY_INCLUDES@
+FACTORY_LIBS = @FACTORY_LIBS@
+FGREP = @FGREP@
+FLINT_CFLAGS = @FLINT_CFLAGS@
+FLINT_HOME = @FLINT_HOME@
+FLINT_LIBS = @FLINT_LIBS@
+GMP_CFLAGS = @GMP_CFLAGS@
+GMP_HOME = @GMP_HOME@
+GMP_LIBS = @GMP_LIBS@
+GMP_VERSION = @GMP_VERSION@
+GREP = @GREP@
+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@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NTL_CFLAGS = @NTL_CFLAGS@
+NTL_LIBS = @NTL_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OMALLOC_INCLUDES = @OMALLOC_INCLUDES@
+OMALLOC_LIBS = @OMALLOC_LIBS@
+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@
+PKG_REQUIRE = @PKG_REQUIRE@
+PMCONFIG = @PMCONFIG@
+PM_CFLAGS = @PM_CFLAGS@
+PM_INC = @PM_INC@
+PM_LDFLAGS = @PM_LDFLAGS@
+PM_LIBS = @PM_LIBS@
+POLYMAKE_CXXFLAGS = @POLYMAKE_CXXFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LDFLAGS = @PTHREAD_LDFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
+PYTHON = @PYTHON@
+PYTHON_CSPEC = @PYTHON_CSPEC@
+PYTHON_EXECPREFIX = @PYTHON_EXECPREFIX@
+PYTHON_LSPEC = @PYTHON_LSPEC@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+RANLIB = @RANLIB@
+RESOURCES_INCLUDES = @RESOURCES_INCLUDES@
+RESOURCES_LIBS = @RESOURCES_LIBS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SINGULAR_CFLAGS = @SINGULAR_CFLAGS@
+SI_COUNTEDREF_AUTOLOAD = @SI_COUNTEDREF_AUTOLOAD@
+SI_CPU_I386 = @SI_CPU_I386@
+SI_CPU_IA64 = @SI_CPU_IA64@
+SI_CPU_PPC = @SI_CPU_PPC@
+SI_CPU_SPARC = @SI_CPU_SPARC@
+SI_CPU_X86_64 = @SI_CPU_X86_64@
+STRIP = @STRIP@
+USEPPROCSDYNAMICLD = @USEPPROCSDYNAMICLD@
+USEPPROCSDYNAMICLDFLAGS = @USEPPROCSDYNAMICLDFLAGS@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
+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@
+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@
+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@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+ACLOCAL_AMFLAGS = -I ../../m4
+AM_CPPFLAGS = -I${top_srcdir} -I${top_builddir} -I${top_srcdir}/libpolys -I${top_builddir}/libpolys \
+${FACTORY_INCLUDES} $(OMALLOC_INCLUDES) $(RESOURCES_INCLUDES) \
+${NTL_CFLAGS} $(FLINT_CFLAGS) ${GMP_CFLAGS}
+
+noinst_LTLIBRARIES = libGBEngine.la
+libGBEngine_la_SOURCES = khstd.cc kstdfac.cc kstd1.cc kstd2.cc kutil.cc nc.cc sca.cc gr_kstd2.cc kspoly.cc kpolys.cc syz.cc syz0.cc syz1.cc syz2.cc syz3.cc units.cc tgb.cc tgbgauss.cc f5data.cc f5lists.cc f5gb.cc f5c.cc ratgring.cc shiftgb.cc ringgb.cc janet.cc
+libGBEngine_la_includedir = $(includedir)/singular/kernel/GBEngine
+libGBEngine_la_include_HEADERS = syz.h kstdfac.h kutil.h khstd.h kstd1.h units.h ratgring.h shiftgb.h nc.h kInline.h tgb.h ringgb.h tgbgauss.h tgb_internal.h f5c.h f5data.h f5gb.h f5lists.h janet.h
+TESTS_ENVIRONMENT = SINGULARPATH='${abs_top_builddir}/libpolys/polys/.libs:${abs_top_builddir}/factory/gftables' \
+	SINGULAR_ROOT_DIR='${abs_top_builddir}'
+test_SOURCES = test.cc
+test_LDADD = libGBEngine.la ${builddir}/../combinatorics/libcombinatorics.la ${builddir}/../libkernelCommon.la
+CLEANFILES = $(TESTS)
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .cc .lo .log .o .obj .test .test$(EXEEXT) .trs
+$(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) --foreign kernel/GBEngine/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign kernel/GBEngine/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-noinstLTLIBRARIES:
+	-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+	@list='$(noinst_LTLIBRARIES)'; \
+	locs=`for p in $$list; do echo $$p; done | \
+	      sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+	      sort -u`; \
+	test -z "$$locs" || { \
+	  echo rm -f $${locs}; \
+	  rm -f $${locs}; \
+	}
+
+libGBEngine.la: $(libGBEngine_la_OBJECTS) $(libGBEngine_la_DEPENDENCIES) $(EXTRA_libGBEngine_la_DEPENDENCIES) 
+	$(AM_V_CXXLD)$(CXXLINK)  $(libGBEngine_la_OBJECTS) $(libGBEngine_la_LIBADD) $(LIBS)
+
+clean-checkPROGRAMS:
+	@list='$(check_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
+
+test$(EXEEXT): $(test_OBJECTS) $(test_DEPENDENCIES) $(EXTRA_test_DEPENDENCIES) 
+	@rm -f test$(EXEEXT)
+	$(AM_V_CXXLD)$(CXXLINK) $(test_OBJECTS) $(test_LDADD) $(LIBS)
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/f5c.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/f5data.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/f5gb.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/f5lists.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/gr_kstd2.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/janet.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/khstd.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/kpolys.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/kspoly.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/kstd1.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/kstd2.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/kstdfac.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/kutil.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/nc.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ratgring.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ringgb.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/sca.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/shiftgb.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/syz.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/syz0.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/syz1.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/syz2.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/syz3.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/test.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tgb.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tgbgauss.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/units.Plo at am__quote@
+
+.cc.o:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+ at am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXXCOMPILE) -c -o $@ $<
+
+.cc.obj:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+ at am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.cc.lo:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+ at am__fastdepCXX_TRUE@	$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LTCXXCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+install-libGBEngine_la_includeHEADERS: $(libGBEngine_la_include_HEADERS)
+	@$(NORMAL_INSTALL)
+	@list='$(libGBEngine_la_include_HEADERS)'; test -n "$(libGBEngine_la_includedir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(libGBEngine_la_includedir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(libGBEngine_la_includedir)" || exit 1; \
+	fi; \
+	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)$(libGBEngine_la_includedir)'"; \
+	  $(INSTALL_HEADER) $$files "$(DESTDIR)$(libGBEngine_la_includedir)" || exit $$?; \
+	done
+
+uninstall-libGBEngine_la_includeHEADERS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(libGBEngine_la_include_HEADERS)'; test -n "$(libGBEngine_la_includedir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	dir='$(DESTDIR)$(libGBEngine_la_includedir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	$(am__define_uniq_tagged_files); \
+	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-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	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"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'.  Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+	rm -f $< $@
+	$(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+	@:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+	@$(am__set_TESTS_bases); \
+	am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+	redo_bases=`for i in $$bases; do \
+	              am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+	            done`; \
+	if test -n "$$redo_bases"; then \
+	  redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+	  redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+	  if $(am__make_dryrun); then :; else \
+	    rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+	  fi; \
+	fi; \
+	if test -n "$$am__remaking_logs"; then \
+	  echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+	       "recursion detected" >&2; \
+	else \
+	  am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+	fi; \
+	if $(am__make_dryrun); then :; else \
+	  st=0;  \
+	  errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+	  for i in $$redo_bases; do \
+	    test -f $$i.trs && test -r $$i.trs \
+	      || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+	    test -f $$i.log && test -r $$i.log \
+	      || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+	  done; \
+	  test $$st -eq 0 || exit 1; \
+	fi
+	@$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+	ws='[ 	]'; \
+	results=`for b in $$bases; do echo $$b.trs; done`; \
+	test -n "$$results" || results=/dev/null; \
+	all=`  grep "^$$ws*:test-result:"           $$results | wc -l`; \
+	pass=` grep "^$$ws*:test-result:$$ws*PASS"  $$results | wc -l`; \
+	fail=` grep "^$$ws*:test-result:$$ws*FAIL"  $$results | wc -l`; \
+	skip=` grep "^$$ws*:test-result:$$ws*SKIP"  $$results | wc -l`; \
+	xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+	xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+	error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+	if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+	  success=true; \
+	else \
+	  success=false; \
+	fi; \
+	br='==================='; br=$$br$$br$$br$$br; \
+	result_count () \
+	{ \
+	    if test x"$$1" = x"--maybe-color"; then \
+	      maybe_colorize=yes; \
+	    elif test x"$$1" = x"--no-color"; then \
+	      maybe_colorize=no; \
+	    else \
+	      echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+	    fi; \
+	    shift; \
+	    desc=$$1 count=$$2; \
+	    if test $$maybe_colorize = yes && test $$count -gt 0; then \
+	      color_start=$$3 color_end=$$std; \
+	    else \
+	      color_start= color_end=; \
+	    fi; \
+	    echo "$${color_start}# $$desc $$count$${color_end}"; \
+	}; \
+	create_testsuite_report () \
+	{ \
+	  result_count $$1 "TOTAL:" $$all   "$$brg"; \
+	  result_count $$1 "PASS: " $$pass  "$$grn"; \
+	  result_count $$1 "SKIP: " $$skip  "$$blu"; \
+	  result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+	  result_count $$1 "FAIL: " $$fail  "$$red"; \
+	  result_count $$1 "XPASS:" $$xpass "$$red"; \
+	  result_count $$1 "ERROR:" $$error "$$mgn"; \
+	}; \
+	{								\
+	  echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" |	\
+	    $(am__rst_title);						\
+	  create_testsuite_report --no-color;				\
+	  echo;								\
+	  echo ".. contents:: :depth: 2";				\
+	  echo;								\
+	  for b in $$bases; do echo $$b; done				\
+	    | $(am__create_global_log);					\
+	} >$(TEST_SUITE_LOG).tmp || exit 1;				\
+	mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG);			\
+	if $$success; then						\
+	  col="$$grn";							\
+	 else								\
+	  col="$$red";							\
+	  test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG);		\
+	fi;								\
+	echo "$${col}$$br$${std}"; 					\
+	echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}";	\
+	echo "$${col}$$br$${std}"; 					\
+	create_testsuite_report --maybe-color;				\
+	echo "$$col$$br$$std";						\
+	if $$success; then :; else					\
+	  echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}";		\
+	  if test -n "$(PACKAGE_BUGREPORT)"; then			\
+	    echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}";	\
+	  fi;								\
+	  echo "$$col$$br$$std";					\
+	fi;								\
+	$$success || exit 1
+
+check-TESTS:
+	@list='$(RECHECK_LOGS)';           test -z "$$list" || rm -f $$list
+	@list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+	@test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+	@set +e; $(am__set_TESTS_bases); \
+	log_list=`for i in $$bases; do echo $$i.log; done`; \
+	trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+	log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+	$(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+	exit $$?;
+recheck: all $(check_PROGRAMS)
+	@test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+	@set +e; $(am__set_TESTS_bases); \
+	bases=`for i in $$bases; do echo $$i; done \
+	         | $(am__list_recheck_tests)` || exit 1; \
+	log_list=`for i in $$bases; do echo $$i.log; done`; \
+	log_list=`echo $$log_list`; \
+	$(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+	        am__force_recheck=am--force-recheck \
+	        TEST_LOGS="$$log_list"; \
+	exit $$?
+test.log: test$(EXEEXT)
+	@p='test$(EXEEXT)'; \
+	b='test'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+.test.log:
+	@p='$<'; \
+	$(am__set_b); \
+	$(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+ at am__EXEEXT_TRUE@.test$(EXEEXT).log:
+ at am__EXEEXT_TRUE@	@p='$<'; \
+ at am__EXEEXT_TRUE@	$(am__set_b); \
+ at am__EXEEXT_TRUE@	$(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ at am__EXEEXT_TRUE@	--log-file $$b.log --trs-file $$b.trs \
+ at am__EXEEXT_TRUE@	$(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ at am__EXEEXT_TRUE@	"$$tst" $(AM_TESTS_FD_REDIRECT)
+
+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_PROGRAMS)
+	$(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(HEADERS)
+installdirs:
+	for dir in "$(DESTDIR)$(libGBEngine_la_includedir)"; 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:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+	-test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+	-test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+	-test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+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-checkPROGRAMS clean-generic clean-libtool \
+	clean-noinstLTLIBRARIES 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-libGBEngine_la_includeHEADERS
+
+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: uninstall-libGBEngine_la_includeHEADERS
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am clean \
+	clean-checkPROGRAMS clean-generic clean-libtool \
+	clean-noinstLTLIBRARIES cscopelist-am ctags ctags-am 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-libGBEngine_la_includeHEADERS 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 \
+	recheck tags tags-am uninstall uninstall-am \
+	uninstall-libGBEngine_la_includeHEADERS
+
+
+# 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/kernel/GBEngine/f5c.cc b/kernel/GBEngine/f5c.cc
new file mode 100644
index 0000000..5bcab58
--- /dev/null
+++ b/kernel/GBEngine/f5c.cc
@@ -0,0 +1,32 @@
+
+
+
+#include <kernel/mod2.h>
+#ifdef HAVE_F5
+#include <unistd.h>
+#include <kernel/structs.h>
+#include <kernel/GBEngine/kutil.h>
+#include <omalloc/omalloc.h>
+#include <kernel/polys.h>
+#include <polys/monomials/p_polys.h>
+#include <polys/templates/p_Procs.h>
+#include <kernel/ideals.h>
+#include <kernel/GBEngine/kstd1.h>
+#include <kernel/GBEngine/khstd.h>
+#include <polys/kbuckets.h>
+#include <polys/weight.h>
+#include <misc/intvec.h>
+#include <kernel/polys.h>
+#include <kernel/GBEngine/f5c.h>
+/*
+==========================================================================
+MAIN:computes a gb of the ideal i in the ring r with our F5 implementation
+==========================================================================
+*/
+ideal f5cMain(ideal id, ring r) {
+
+  return id;
+}
+
+#endif
+// HAVE_F5
diff --git a/kernel/GBEngine/f5c.h b/kernel/GBEngine/f5c.h
new file mode 100644
index 0000000..6eafaf9
--- /dev/null
+++ b/kernel/GBEngine/f5c.h
@@ -0,0 +1,20 @@
+#ifndef F5C_HEADER
+#define F5C_HEADER
+
+#ifdef HAVE_F5C
+#include <kernel/F5cData.h>
+#include <kernel/F5cLists.h>
+
+/*!
+ * main function of the F5C implementation in SINGULAR
+ *
+ * INPUT:   Ideal i for which a gröbner basis should be computed;
+ *          ring r.
+ * OUTPUT:  ideal g (the gröbner basis of i computed via F5C)
+*/
+ideal f5cMain(ideal i, ring r);
+
+#endif
+// HAVE_F5C
+#endif
+// F5C_HEADER
diff --git a/kernel/GBEngine/f5data.cc b/kernel/GBEngine/f5data.cc
new file mode 100644
index 0000000..448161e
--- /dev/null
+++ b/kernel/GBEngine/f5data.cc
@@ -0,0 +1,34 @@
+//! \file f5data.h
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: lpolynomial definition
+*/
+
+
+
+#include <kernel/mod2.h>
+
+#ifdef HAVE_F5
+#include <kernel/GBEngine/kutil.h>
+#include <kernel/structs.h>
+#include <omalloc/omalloc.h>
+#include <kernel/polys.h>
+#include <polys/monomials/p_polys.h>
+#include <kernel/ideals.h>
+#include <kernel/GBEngine/kstd1.h>
+#include <kernel/GBEngine/khstd.h>
+#include <polys/kbuckets.h>
+#include <polys/weight.h>
+#include <misc/intvec.h>
+#include <kernel/polys.h>
+#include <kernel/GBEngine/f5gb.h>
+#include <kernel/GBEngine/f5data.h>
+#include <kernel/GBEngine/f5lists.h>
+/*
+=====================
+everything is inlined
+=====================
+*/
+#endif
diff --git a/kernel/GBEngine/f5data.h b/kernel/GBEngine/f5data.h
new file mode 100644
index 0000000..65e984b
--- /dev/null
+++ b/kernel/GBEngine/f5data.h
@@ -0,0 +1,260 @@
+//! \file f5data.cc
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: labeled polynomial interface
+*/
+#ifndef F5DATA_HEADER
+#define F5DATA_HEADER
+#ifdef HAVE_F5
+/*!
+=========================================================
+=========================================================
+classes for labeled polynomials/pairs/S-polynomials in F5
+=========================================================
+=========================================================
+*/
+class LPolyOld;
+class CPairOld;
+class RuleOld;
+
+
+/*!
+============================
+class of labeled polynomials
+============================
+*/
+class LPolyOld {
+    private:
+        poly    term;           //term of signature
+        int     index;          //index of signature
+        poly    polynomial;     //standard polynomial data
+        RuleOld*   _ruleOld;
+        bool    del;
+    public:
+        inline          LPolyOld(poly t, int i, poly p, RuleOld* r=NULL);
+ //       inline          LPolyOld(poly t, int i, poly p, RuleOld* r=NULL, bool b=0);
+        inline  void    setPoly(poly p);
+        inline  poly    getPoly();
+        inline  void    setTerm(poly t);
+        inline  poly    getTerm();
+        inline  void    setIndex(int i);
+        inline  int     getIndex();
+        inline  void    setRuleOld(RuleOld* r);
+        inline  RuleOld*   getRuleOld();
+        inline  void    setDel(bool d);
+        inline  bool    getDel();
+        inline  void    set(poly t, int i, poly p, RuleOld* r);
+        inline  LPolyOld*  get();
+};
+
+LPolyOld::LPolyOld(poly t,int i,poly p, RuleOld* r) {
+    set(t,i,p,r);
+    del =   0;
+}
+
+/*LPolyOld::LPolyOld(poly t,int i,poly p, RuleOld* r, bool b) {
+    set(t,i,p,r);
+    del =   b;
+}
+*/
+void LPolyOld::setPoly(poly p)  {
+    //poly _p     =   pInit();
+    //_p          =   pCopy(p);
+    polynomial = p;
+}
+
+void LPolyOld::setTerm(poly t) {
+    //poly _t     =   pInit();
+    //_t          =   pCopy(t);
+    term = t;
+}
+
+void LPolyOld::setIndex(int i) {
+    index = i;
+}
+
+void LPolyOld::setRuleOld(RuleOld* r) {
+    _ruleOld   =   r;
+}
+
+void LPolyOld::setDel(bool d) {
+    del =   d;
+}
+
+poly LPolyOld::getPoly() {
+    return polynomial;
+}
+
+poly LPolyOld::getTerm() {
+    return term;
+}
+
+int LPolyOld::getIndex() {
+    return index;
+}
+
+RuleOld* LPolyOld::getRuleOld() {
+    return _ruleOld;
+}
+
+bool LPolyOld::getDel() {
+    return del;
+}
+
+void LPolyOld::set(poly t, int i, poly p, RuleOld* r) {
+    this->setTerm(t);
+    this->setIndex(i);
+    this->setPoly(p);
+    this->setRuleOld(r);
+}
+
+LPolyOld* LPolyOld::get() {
+    return this;
+}
+
+
+/*!
+===================================
+structure of labeled critical pairs
+===================================
+*/
+class CPairOld {
+    private:
+        long    deg;            // total degree of the critical pair
+        poly    t1;             // first term for label
+        LPolyOld*  lp1;            // first labeled poly
+        poly    t2;             // second term for label
+        LPolyOld*  lp2;            // second labeled poly
+        RuleOld*   testedRuleOld;     // already tested by RuleOlds up to lastRuleOldTested
+        bool  del;
+    public:
+        inline          CPairOld(long degree, poly term1, LPolyOld* LPolyOld1, poly term2, LPolyOld* LPolyOld2, bool useless, RuleOld* r = NULL);
+        inline  long    getDeg();
+        inline  poly    getT1();
+        inline  poly*   getAdT1();
+        inline  LPolyOld*  getAdLp1();
+        inline  poly    getLp1Poly();
+        inline  poly    getLp1Term();
+        inline  int     getLp1Index();
+        inline  poly    getT2();
+        inline  poly*   getAdT2();
+        inline  LPolyOld*  getAdLp2();
+        inline  poly    getLp2Poly();
+        inline  poly    getLp2Term();
+        inline  int     getLp2Index();
+        inline  bool    getDel();
+        inline  RuleOld*   getTestedRuleOld();
+        inline  void    setTestedRuleOld(RuleOld* r);
+};
+
+CPairOld::CPairOld(long degree, poly term1, LPolyOld* LPolyOld1, poly term2, LPolyOld* LPolyOld2, bool useless, RuleOld* r) {
+   deg              =   degree;
+   t1               =   term1;
+   lp1              =   LPolyOld1;
+   t2               =   term2;
+   lp2              =   LPolyOld2;
+   testedRuleOld       =   r;
+   del              =   useless;
+}
+
+long CPairOld::getDeg() {
+    return deg;
+}
+
+poly CPairOld::getT1() {
+    return t1;
+}
+
+poly* CPairOld::getAdT1() {
+    return &t1;
+}
+
+poly* CPairOld::getAdT2() {
+    return &t2;
+}
+
+poly CPairOld::getT2() {
+    return t2;
+}
+
+LPolyOld* CPairOld::getAdLp1() {
+    return lp1;
+}
+
+LPolyOld* CPairOld::getAdLp2() {
+    return lp2;
+}
+
+poly CPairOld::getLp1Poly() {
+    return lp1->getPoly();
+}
+
+poly CPairOld::getLp2Poly() {
+    return lp2->getPoly();
+}
+
+poly CPairOld::getLp1Term() {
+    return lp1->getTerm();
+}
+
+poly CPairOld::getLp2Term() {
+    return lp2->getTerm();
+}
+
+int CPairOld::getLp1Index() {
+    return lp1->getIndex();
+}
+
+int CPairOld::getLp2Index() {
+    return lp2->getIndex();
+}
+
+bool CPairOld::getDel() {
+  return del;
+}
+
+RuleOld* CPairOld::getTestedRuleOld() {
+    return testedRuleOld;
+}
+
+void CPairOld::setTestedRuleOld(RuleOld* r) {
+    testedRuleOld      =   r;
+}
+
+
+/*!
+========================================================
+structure of RuleOlds(i.e. already computed / known labels)
+========================================================
+*/
+class RuleOld {
+    private:
+        int     index;      // index of the labeled polynomial the RuleOld comes from
+        poly    term;       // term of the labeled polynomial the RuleOld comes from
+    public:
+        inline          RuleOld(int i, poly term);
+        inline          ~RuleOld();
+        inline  int     getIndex();
+        inline  poly    getTerm();
+};
+
+RuleOld::RuleOld(int i, poly t) {
+    index   =   i;
+    term    =   t;
+}
+
+RuleOld::~RuleOld() {
+    //pDelete(&term);
+}
+
+int RuleOld::getIndex() {
+    return index;
+}
+
+poly RuleOld::getTerm() {
+    return term;
+}
+#endif
+#endif
diff --git a/kernel/GBEngine/f5gb.cc b/kernel/GBEngine/f5gb.cc
new file mode 100644
index 0000000..5777382
--- /dev/null
+++ b/kernel/GBEngine/f5gb.cc
@@ -0,0 +1,2146 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: f5gb interface
+*/
+
+
+
+
+#include <kernel/mod2.h>
+#ifdef HAVE_F5
+#include <unistd.h>
+#include <omp.h>
+#include <kernel/structs.h>
+#include <kernel/GBEngine/kutil.h>
+#include <omalloc/omalloc.h>
+#include <kernel/polys.h>
+#include <polys/monomials/p_polys.h>
+#include <polys/templates/p_Procs.h>
+#include <kernel/ideals.h>
+#include <kernel/GBEngine/kstd1.h>
+#include <kernel/GBEngine/khstd.h>
+#include <polys/kbuckets.h>
+#include <polys/weight.h>
+#include <misc/intvec.h>
+#include <kernel/polys.h>
+#include <kernel/GBEngine/f5gb.h>
+#include <kernel/GBEngine/f5data.h>
+#include <kernel/GBEngine/f5lists.h>
+int notInG              =   0;
+int numberOfRules       =   0;
+int reductionsToZero    =   0;
+int reductionTime       =   0;
+int spolsTime           =   0;
+int highestDegree       =   0;
+int degreeBound         =   0;
+int numberUsefulPairs   =   0;
+int numberUselessPairs  =   0;
+int numberUsefulPairsMinDeg = 0;
+int highestDegreeGBCriticalPair = 0;
+int numberRejectedF5CriticalPairs = 0;
+int numberOfReductions  = 0;
+int numberOfSpolys  = 0;
+/*
+====================================================================
+sorting ideals by decreasing total degree "left" and "right" are the
+pointer of the first and last polynomial in the considered ideal
+====================================================================
+*/
+void qsortDegree(poly* left, poly* right) {
+    poly* ptr1 = left;
+    poly* ptr2 = right;
+    poly p1,p2;
+    p2 = *(left + (right - left >> 1));
+    do {
+            while(pTotaldegree(*ptr1, currRing) < pTotaldegree(p2, currRing)) {
+                    ptr1++;
+            }
+            while(pTotaldegree(*ptr2, currRing) > pTotaldegree(p2,currRing)) {
+                    ptr2--;
+            }
+            if(ptr1 > ptr2) {
+                    break;
+            }
+            p1    = *ptr1;
+            *ptr1 = *ptr2;
+            *ptr2 = p1;
+    } while(++ptr1 <= --ptr2);
+
+    if(left < ptr2) {
+            qsortDegree(left,ptr2);
+    }
+    if(ptr1 < right) {
+            qsortDegree(ptr1,right);
+    }
+}
+
+/*!
+ * ======================================================================
+ * builds the sum of the entries of the exponent vectors, i.e. the degree
+ * of the corresponding monomial
+ * ======================================================================
+*/
+long sumVector(int* v, int k) {
+    int i;
+    long sum =  0;
+    for(i=1; i<=k; i++) {
+        Print("%d\n",v[i]);
+        Print("%ld\n",sum);
+        sum =   sum + v[i];
+    }
+    return sum;
+}
+
+/*!
+==========================================================================
+compares monomials, i.e. divisibility tests for criterion 1 and criterion 2
+==========================================================================
+*/
+bool compareMonomials(int* m1, int** m2, int numberOfRules, int k) {
+    int i,j;
+    long sumM1  =   sumVector(m1,k);
+    //int k   =   sizeof(m1) / sizeof(int);
+    for(i=0; i<numberOfRules; i++) {
+        if(sumVector(m2[i],k) <= sumM1) {
+            for(j=1; j<=k; j++) {
+                if(m1[j]>m2[i][j]) {
+                    return true;
+                }
+            }
+        }
+    }
+    return false;
+}
+
+/*
+==================================================
+computes incrementally gbs of subsets of the input
+gb{f_m} -> gb{f_m,f_(m-1)} -> gb{f_m,...,f_1}
+==================================================
+*/
+LList* F5inc(int i, poly f_i, LList* gPrev, LList* reducers, ideal gbPrev, poly ONE, LTagList* lTag, RList* rules, RTagList* rTag, int plus, int termination) {
+    //Print("in f5inc\n");
+    //pWrite(rules->getFirst()->getRuleTerm());
+    int iterationstep = i;
+    int j;
+    //Print("%p\n",gPrev->getFirst());
+    //pWrite(gPrev->getFirst()->getPoly());
+    poly tempNF =   kNF(gbPrev,currRing->qideal,f_i);
+    f_i         =   tempNF;
+    //gPrev->insert(ONE,i,f_i);
+    gPrev->insert(ONE,gPrev->getLength()+1,f_i);
+    // tag the first element in gPrev of the current index for findReductor()
+    lTag->setFirstCurrentIdx(gPrev->getLast());
+    //Print("1st gPrev: ");
+    //pWrite(gPrev->getFirst()->getPoly());
+    //Print("2nd gPrev: ");
+    //pWrite(gPrev->getFirst()->getNext()->getPoly());
+    //pWrite(gPrev->getFirst()->getNext()->getPoly());
+    CListOld* critPairs        =   new CListOld();
+    CNode* critPairsMinDeg  =   new CNode();
+    PList* rejectedGBList = new PList();
+    // computation of critical pairs with checking of criterion 1 and criterion 2 and saving them
+    // in the list critPairs
+    criticalPair(gPrev, critPairs, lTag, rTag, rules, rejectedGBList, plus);
+    static LList* sPolyList        =   new LList();
+    //sPolyList->print();
+    // labeled polynomials which have passed reduction() and have to be added to list gPrev
+    static LList* completed        =   new LList();
+    // the reduced labeled polynomials which are returned from subalgorithm reduction()
+    static LList* reducedLPolys     =   new LList();
+    // while there are critical pairs to be further checked and deleted/computed
+    while(NULL != critPairs->getFirst()) {
+        // critPairs->getMinDeg() deletes the first elements of minimal degree from
+        // critPairs, thus the while loop is not infinite.
+        // adds all to be reduced S-polynomials in the list sPolyList and adds
+        // the corresponding rules to the list rules
+        // NOTE: inside there is a second check of criterion 2 if new rules are
+        // added
+        //int timer4  =   initTimer();
+        //startTimer();
+        //critPairs->print();
+
+        //definition of a local numberUsefulPairs variable for the next degree
+        //step:
+        //if in this degree all pairs are useless, skip this degree step
+        //completely!
+        //long arrideg = critPairs->getFirst()->getData()->getDeg();
+        //if(plus && highestDegreeGBCriticalPair < critPairs->getFirst()->getData()->getDeg()) {
+        //  return gPrev;
+        //}
+        //else {
+        critPairsMinDeg =   critPairs->getMinDeg();
+        //numberUsefulPairsMinDeg = computeUsefulMinDeg(critPairsMinDeg);
+        //if(numberUsefulPairs > 0) {
+          //if(numberUsefulPairsMinDeg > 0) {
+            //Print("number of useful pairs:  %d\n",numberUsefulPairs);
+            //Print("number of useless pairs: %d\n\n",numberUselessPairs);
+          //Print("Degree of following reduction: %d\n",critPairsMinDeg->getData()->getDeg());
+        long degreecheck = critPairsMinDeg->getData()->getDeg();
+
+          computeSPols(critPairsMinDeg,rTag,rules,sPolyList, rejectedGBList);
+        //}
+          //}
+        //}
+        //else {
+        //  return gPrev;
+        //}
+        //timer4  =   getTimer();
+        //Print("SPOLS TIMER: %d\n",timer4);
+        //spolsTime  =   spolsTime  +   timer4;
+        // DEBUG STUFF FOR SPOLYLIST
+        LNode* temp     =   sPolyList->getFirst();
+        //while(NULL != temp && NULL != temp->getLPoly()) {
+            //Print("Spolylist element: ");
+            //pWrite(temp->getPoly());
+            //temp    =   temp->getNext();
+        //}
+        // reduction process of new S-polynomials and also adds new critical pairs to critPairs
+        //int timer3  =   initTimer();
+        //startTimer();
+        //sPolyList->print();
+        //reduction(sPolyList, critPairs, gPrev, rules, lTag, rTag, gbPrev);
+        //Print("BEFORE REDUCTION: \n");
+        //Print("number of useful pairs:  %d\n",numberUsefulPairs);
+        //Print("number of useless pairs: %d\n\n",numberUselessPairs);
+        newReduction(sPolyList, critPairs, gPrev, reducers, rules, lTag, rTag, gbPrev, termination, rejectedGBList, plus);
+        //Print("ITERATION:  %d",iterationstep);
+        //Print("NAECHSTER GRAD:  %ld",degreecheck);
+        //sleep(5);
+        //if(i == 5 && pDeg(gPrev->getLast()->getPoly()) == 8) {
+        //  Print("RAUS BEI DEG 8 \n");
+        //  return gPrev;
+        //}
+        //Print("ARRIS DEG: %ld\n",arrideg);
+        // Arris idea stated by John in an email
+        //if(arrisCheck(critPairs->getFirst(),gPrev->getFirst(),arrideg)) {
+        //  Print("ARRIS DEGREE: %ld\n", arrideg);
+        //  return gPrev;
+        //}
+
+
+        //bool aha = checkDGB(gPrev);
+
+
+        //timer3      =  getTimer();
+        //reductionTime = reductionTime + timer3;
+        //Print("REDUCTION TIMER: %d\n",timer3);
+        // DEBUG STUFF FOR GPREV
+        //temp    =   gPrev->getFirst();
+        //int number  =   1;
+        //Print("\n\n");
+        //while(NULL != temp) {
+        //    Print("%d.  ",number);
+        //    pWrite(temp->getPoly());
+        //    temp    =   temp->getNext();
+        //    number++;
+        //    Print("\n");
+        //}
+        //sleep(5);
+
+    }
+    //Print("REDUCTION DONE\n");
+    //Print("%p\n",rules->getFirst());
+    //Print("%p\n",rTag->getFirst());
+    //if(rules->getFirst() != rTag->getFirst()) {
+        //Print("+++++++++++++++++++++++++++++++++++++NEW RULES+++++++++++++++++++++++++++++++++++++\n");
+        //rTag->insert(rules->getFirst());
+    //}
+    //else {
+        //Print("+++++++++++++++++++++++++++++++++++NO NEW RULES++++++++++++++++++++++++++++++++++++\n");
+    //}
+    lTag->insert(lTag->getFirstCurrentIdx());
+    //Print("INDEX: %d\n",tempTag->getIndex());
+    //pWrite(tempTag->getPoly());
+    //Print("COMPLETED FIRST IN F5INC: \n");
+    //Print("1st gPrev: ");
+    //pWrite(gPrev->getFirst()->getPoly());
+    //Print("2nd gPrev: ");
+    //pWrite(gPrev->getFirst()->getNext()->getPoly());
+    //Print("3rd gPrev: ");
+    //pWrite(gPrev->getFirst()->getNext()->getNext()->getPoly());
+    //delete sPolyList;
+    //critPairs->print();
+    delete critPairs;
+    //Print("IN F5INC\n");
+    /*
+    Print("\n\n\nRULES: \n");
+        RNode* tempR    =   rules->getFirst();
+        Print("%p\n",tempR);
+        int t   = 1;
+        while(NULL != tempR) {
+            Print("ADDRESS OF %d RNODE: %p\n",t,tempR);
+            Print("ADDRESS OF RULE: %p\n",tempR->getRule());
+            pWrite(tempR->getRuleTerm());
+            Print("ADDRESS OF TERM: %p\n",tempR->getRuleTerm());
+            Print("%d\n\n",tempR->getRuleIndex());
+            tempR   =   tempR->getNext();
+            t++;
+        }
+    */
+    //gPrev->print();
+    //Print("COMPLETE REDUCTION TIME UNTIL NOW: %d\n",reductionTime);
+    //Print("COMPLETE SPOLS TIME UNTIL NOW:     %d\n",spolsTime);
+    degreeBound = 0;
+    return gPrev;
+}
+
+
+
+bool checkDGB(LList* gPrev) {
+  Print("D-GB CHECK at degree %ld\n",pDeg(gPrev->getLast()->getPoly()));
+  LNode* temp = gPrev->getFirst();
+  LNode* temp2;
+  bool isDGb = 0;
+  // construct the d-GB gb
+  ideal gb =   idInit(gPrev->getLength(),1);
+  for(int j=0;j<=gPrev->getLength()-1;j++) {
+          gb->m[j] =   temp->getPoly();
+          pWrite(gb->m[j]);
+          temp        =   temp->getNext();
+  }
+  /*
+  Kstd1_deg = pDeg(gPrev->getLast()->getPoly());
+  BITSET save = test;
+  test |= Sy_bit(OPT_DEGBOUND);
+  kStd();
+  test = save;
+  */
+  temp = gPrev->getFirst();
+  while(NULL != temp) {
+    temp2 = temp->getNext();
+    number nOne = nInit(1);
+    poly lcm = pOne();
+    poly sp = pOne();
+    while(NULL != temp2) {
+      pLcm(temp->getPoly(),temp2->getPoly(),lcm);
+      pSetCoeff(lcm,nOne);
+      pSetm(lcm);
+      Print("LCM:   ");
+      pWrite(lcm);
+      if(pDeg(lcm) <= pDeg(gPrev->getLast()->getPoly())) {
+        poly u1 = pOne();
+        poly u2 = pOne();
+        u1  = pDivide(lcm,pHead(temp->getPoly()));
+        pSetCoeff(u1,nOne);
+        u2  = pDivide(lcm,pHead(temp2->getPoly()));
+        pSetCoeff(u2,nOne);
+        sp      =   ksOldSpolyRedNew(ppMult_qq(u1,temp->getPoly()),
+            ppMult_qq(u2,temp2->getPoly()));
+        pNorm(sp);
+
+        poly reducer  = pOne();
+        //reducer       = gb->m[0];
+        int i         = 0;
+        pWrite(pHead(sp));
+
+        while(i<IDELEMS(gb)) {
+          reducer = gb->m[i];
+          if(pDivisibleBy(reducer,pHead(sp))) {
+            poly uReducer = pOne();
+            uReducer = pDivide(lcm,pHead(reducer));
+            pSetCoeff(uReducer,nOne);
+            sp = ksOldSpolyRedNew(sp,ppMult_qq(uReducer,reducer));
+            //pNorm(tempSP);
+            //sp = tempSP;
+            pNorm(sp);
+            pWrite(sp);
+            i = 0;
+          }
+          else {
+            i++;
+          }
+        }
+
+        pWrite(pHead(sp));
+      }
+      temp2 = temp2->getNext();
+    }
+    temp  = temp->getNext();
+  }
+  Print("------------------\n");
+  return isDGb;
+}
+
+/*
+ * Arris Check if we are finished after the current degree step:
+ * Checks all remaining critical pairs, i.e. those of higher degree,
+ * by the two Buchberger criteria.
+ * return value: 0, if all remaining critical pairs are deleted by
+ *                  Buchberger's criteria
+ *               1, otherwise
+ */
+bool arrisCheck(CNode* first, LNode* firstGCurr, long arrideg) {
+  CNode* temp = first;
+
+  //product criterion check
+  while(NULL != temp) {
+    if(!pLmEqual(pHead(temp->getLp2Poly()),temp->getT1())) {
+        return 0;
+    }
+    temp = temp->getNext();
+  }
+
+  // chain criterion
+  LNode* tempPoly = firstGCurr;
+  while(NULL != tempPoly) {
+    LNode* tempPoly2 = tempPoly->getNext();
+    while(NULL != tempPoly2) {
+      number nOne = nInit(1);
+      poly lcm = pOne();
+      pLcm(tempPoly->getPoly(),tempPoly2->getPoly(),lcm);
+      pSetCoeff(lcm,nOne);
+      pSetm(lcm);
+      if(pDeg(lcm) > arrideg) {
+        LNode* tempPoly3 = firstGCurr;
+        while(NULL != tempPoly3) {
+          if(tempPoly3 != tempPoly2 && tempPoly3 != tempPoly && pDivisibleBy(tempPoly3->getPoly(),lcm)) {
+        poly lcm1 = pOne();
+        poly lcm2 = pOne();
+        pLcm(tempPoly3->getPoly(),tempPoly->getPoly(),lcm1);
+        pSetCoeff(lcm1,nOne);
+        pSetm(lcm1);
+        pLcm(tempPoly3->getPoly(),tempPoly2->getPoly(),lcm2);
+        pSetCoeff(lcm2,nOne);
+        pSetm(lcm2);
+        if(pDeg(lcm1) < pDeg(lcm) && pDeg(lcm2) < pDeg(lcm)) {
+          return 0;
+        }
+      }
+        tempPoly3 = tempPoly3->getNext();
+        }
+      }
+      tempPoly2 = tempPoly2->getNext();
+    }
+    tempPoly = tempPoly->getNext();
+  }
+  return 1;
+}
+
+
+
+/*
+================================================================
+computes a list of critical pairs for the next reduction process
+the first element is always "useful" thus the critical pair
+computed is either "useful" or "useless" depending on the second
+element which generates the critical pair.
+first element in gPrev is always the newest element which must
+build critical pairs with all other elements in gPrev
+================================================================
+*/
+inline void criticalPair(LList* gPrev, CListOld* critPairs, LTagList* lTag, RTagList* rTag, RList* rules, PList* rejectedGBList, int plus) {
+    //Print("IN CRITPAIRS\n");
+    // initialization for usage in pLcm()
+    number nOne         =   nInit(1);
+    LNode* newElement   =   gPrev->getLast();
+    LNode* temp         =   gPrev->getFirst();
+    poly u1             =   pOne();
+    poly u2             =   pOne();
+    poly lcm            =   pOne();
+    poly t              =   pHead(newElement->getPoly());
+    RuleOld* testedRuleOld    =   NULL;
+    //Print("NEW:   ");
+    //pWrite(newElement->getPoly());
+    //Print("ADDRESS:  %p",newElement);
+    if(NULL != rules->getFirst()) {
+        testedRuleOld  =   rules->getFirst()->getRuleOld();
+    }
+    // computation of critical pairs
+    while( gPrev->getLast() != temp) {
+        //Print("TEMP:  ");
+        //pWrite(pHead(temp->getPoly()));
+        //Print("ADDRESS:  %p",temp);
+        pLcm(newElement->getPoly(), temp->getPoly(), lcm);
+        pSetCoeff(lcm,nOne);
+        // computing factors u2 for new labels
+        u1 = pDivide(lcm,t);
+        if(NULL == u1) {
+            break;
+        }
+        pSetCoeff(u1,nOne);
+        u2 = pDivide(lcm,pHead(temp->getPoly()));
+        pSetCoeff(u2,nOne);
+        int degree = pDeg(ppMult_qq(u2,pHead(temp->getPoly())));
+        // testing both new labels by the F5 Criterion
+        if(!temp->getDel()) {
+          if(plus && highestDegreeGBCriticalPair < degree) {
+            highestDegreeGBCriticalPair = degree;
+          }
+          if(!criterion2(gPrev->getFirst()->getIndex(), u2, temp, rules, rTag)
+            && !criterion2(gPrev->getFirst()->getIndex(), u1, newElement, rules, rTag)
+            && !criterion1(gPrev,u1,newElement,lTag) && !criterion1(gPrev,u2,temp,lTag)) {
+              // if they pass the test, add them to CListOld critPairs, having the LPolyOld with greater
+              // label as first element in the CPairOld
+              if(newElement->getIndex() == temp->getIndex() &&
+              -1 == pLmCmp(ppMult_qq(u1, newElement->getTerm()),ppMult_qq(u2, temp->getTerm()))) {
+                  CPairOld* cp   =   new CPairOld(pDeg(ppMult_qq(u2,pHead(temp->getPoly()))), u2,
+                                  temp->getLPolyOld(), u1, newElement->getLPolyOld(), 0 , testedRuleOld);
+                  critPairs->insert(cp);
+                  // counting the number of useful pairs
+                  numberUsefulPairs++;
+              }
+              else {
+                  CPairOld* cp   =   new CPairOld(pDeg(ppMult_qq(u2,pHead(temp->getPoly()))), u1,
+                                  newElement->getLPolyOld(), u2, temp->getLPolyOld(), 0, testedRuleOld);
+                  critPairs->insert(cp);
+                  // counting the number of useful pairs
+                  numberUsefulPairs++;
+              }
+          }
+          else {
+            // TODO: generate a list of lcms of rejected GB critical pairs and
+            //       check F5 critical pairs with it at their creation
+            //Print("--------------------------------------------------------------------\n");
+            //Print("--------------------------------------------------------------------\n");
+            pSetm(lcm);
+            rejectedGBList->insert(lcm);
+            //Print("-----------------------REJECTED IN CRIT PAIR------------------------\n");
+            //pWrite(lcm);
+            //Print("--------------------------------------------------------------------\n");
+            //rejectedGBList->print();
+          }
+        }
+        else {
+        //Print("LABEL:  ");
+        //pWrite(ppMult_qq(u1,newElement->getTerm()));
+          //if(rejectedGBList->check(lcm)) { // if there is equality of lcms then we need the F5 critical pair
+            if(!criterion2(gPrev->getFirst()->getIndex(), u2, temp, rules, rTag)
+              && !criterion2(gPrev->getFirst()->getIndex(), u1, newElement, rules, rTag)
+              && !criterion1(gPrev,u1,newElement,lTag) && !criterion1(gPrev,u2,temp,lTag)) {
+                // if they pass the test, add them to CListOld critPairs, having the LPolyOld with greater
+                // label as first element in the CPairOld
+                if(newElement->getIndex() == temp->getIndex() &&
+                -1 == pLmCmp(ppMult_qq(u1, newElement->getTerm()),ppMult_qq(u2, temp->getTerm()))) {
+                    CPairOld* cp   =   new CPairOld(pDeg(ppMult_qq(u2,pHead(temp->getPoly()))), u2,
+                                    temp->getLPolyOld(), u1, newElement->getLPolyOld(), 1 , testedRuleOld);
+                    critPairs->insert(cp);
+                    numberUselessPairs++;
+                }
+                else {
+                    CPairOld* cp   =   new CPairOld(pDeg(ppMult_qq(u2,pHead(temp->getPoly()))), u1,
+                                    newElement->getLPolyOld(), u2, temp->getLPolyOld(), 1, testedRuleOld);
+                    critPairs->insert(cp);
+                    numberUselessPairs++;
+                }
+            }
+          //}
+        }
+        temp    =   temp->getNext();
+    }
+}
+
+
+
+/*
+================================================================
+computes a list of critical pairs for the next reduction process
+the first element is always "useless" thus the critical pair
+computed is "useless".
+first element in gPrev is always the newest element which must
+build critical pairs with all other elements in gPrev
+================================================================
+*/
+inline void criticalPair2(LList* gPrev, CListOld* critPairs, LTagList* lTag, RTagList* rTag, RList* rules, PList* rejectedGBList) {
+    //Print("IN CRITPAIRS\n");
+    // initialization for usage in pLcm()
+    number nOne         =   nInit(1);
+    LNode* newElement   =   gPrev->getLast();
+    LNode* temp         =   gPrev->getFirst();
+    poly u1             =   pOne();
+    poly u2             =   pOne();
+    poly lcm            =   pOne();
+    poly t              =   pHead(newElement->getPoly());
+    RuleOld* testedRuleOld    =   NULL;
+    if(NULL != rules->getFirst()) {
+        testedRuleOld  =   rules->getFirst()->getRuleOld();
+    }
+    // computation of critical pairs
+    while( gPrev->getLast() != temp) {
+        pLcm(newElement->getPoly(), temp->getPoly(), lcm);
+        pSetCoeff(lcm,nOne);
+        // computing factors u2 for new labels
+        u1 = pDivide(lcm,t);
+        if(NULL == u1) {
+            break;
+        }
+        pSetCoeff(u1,nOne);
+        u2 = pDivide(lcm,pHead(temp->getPoly()));
+        pSetCoeff(u2,nOne);
+       // testing both new labels by the F5 Criterion
+        //Print("LABEL:  ");
+        //pWrite(ppMult_qq(u1,newElement->getTerm()));
+        //if(rejectedGBList->check(lcm)) { // if there is equality of lcms then we need the F5 critical pair
+          if(!criterion2(gPrev->getFirst()->getIndex(), u2, temp, rules, rTag)
+            && !criterion2(gPrev->getFirst()->getIndex(), u1, newElement, rules, rTag)
+            && !criterion1(gPrev,u1,newElement,lTag) && !criterion1(gPrev,u2,temp,lTag)) {
+              // if they pass the test, add them to CListOld critPairs, having the LPolyOld with greater
+              // label as first element in the CPairOld
+              if(newElement->getIndex() == temp->getIndex() &&
+              -1 == pLmCmp(ppMult_qq(u1, newElement->getTerm()),ppMult_qq(u2, temp->getTerm()))) {
+                  CPairOld* cp   =   new CPairOld(pDeg(ppMult_qq(u2,pHead(temp->getPoly()))), u2,
+                                  temp->getLPolyOld(), u1, newElement->getLPolyOld(), 1 , testedRuleOld);
+                  critPairs->insert(cp);
+                  numberUselessPairs++;
+              }
+              else {
+                  CPairOld* cp   =   new CPairOld(pDeg(ppMult_qq(u2,pHead(temp->getPoly()))), u1,
+                                  newElement->getLPolyOld(), u2, temp->getLPolyOld(), 1, testedRuleOld);
+                  critPairs->insert(cp);
+                  numberUselessPairs++;
+              }
+          }
+        //}
+        temp    =   temp->getNext();
+    }
+}
+
+
+
+/*
+========================================
+Criterion 1, i.e. Faugere's F5 Criterion
+========================================
+*/
+inline bool criterion1(LList* gPrev, poly t, LNode* l, LTagList* lTag) {
+    // starts at the first element in gPrev with index = (index of l)-1, these tags are saved in lTag
+    int idx =   l->getIndex();
+    int i;
+    if(idx == 1) {
+        //Print("HIER\n");
+        return false;
+    }
+    else {
+        LNode* testNode =   gPrev->getFirst();
+        // save the monom t1*label_term(l) as it is tested various times in the following
+        poly u1 = ppMult_qq(t,l->getTerm());
+        //Print("------------------------------IN CRITERION 1-----------------------------------------\n");
+        //Print("TESTED ELEMENT: ");
+        //pWrite(l->getPoly());
+        //pWrite(l->getTerm());
+        //pWrite(ppMult_qq(t,l->getTerm()));
+        //Print("%d\n\n",l->getIndex());
+        while(testNode->getIndex() < idx) { // && NULL != testNode->getLPoly()) {
+            //pWrite(testNode->getPoly());
+            //Print("%d\n",testNode->getIndex());
+            if(pLmDivisibleByNoComp(testNode->getPoly(),u1)) {
+                //Print("Criterion 1 NOT passed!\n");
+                if(idx != gPrev->getLast()->getIndex()) {
+                    //Print("DOCH!\n");
+                }
+                return true;
+            }
+            //pWrite(testNode->getNext()->getPoly());
+            testNode    =   testNode->getNext();
+        }
+        /*
+        ideal testId    =   idInit(idx-1,1);
+        for(i=0;i<idx-1;i++) {
+            testId->m[i]  =   pHead(testNode->getPoly());
+            testNode        =   testNode->getNext();
+        }
+        poly temp   =   kNF(testId,currRing->qideal,u1);
+        //pWrite(temp);
+        for(i=0;i<IDELEMS(testId);i++) {
+            testId->m[i]    =   NULL;
+        }
+        idDelete(&testId);
+        if(NULL == temp) {
+            //if(l->getIndex() != gPrev->getFirst()->getIndex()) {
+            //    Print("----------------------------Criterion1 not passed----------------------------------\n");
+            //}
+            return true;
+        }
+        */
+        return false;
+    }
+}
+
+
+
+/*
+=====================================
+Criterion 2, i.e. Rewritten Criterion
+=====================================
+*/
+inline bool criterion2(int idx, poly t, LNode* l, RList* rules, RTagList* rTag) {
+    //Print("------------------------------IN CRITERION 2/1-----------------------------------------\n");
+    /*
+    Print("RULES: \n");
+        RNode* tempR    =   rules->getFirst();
+        Print("%p\n",tempR);
+        int i   = 1;
+        while(NULL != tempR) {
+            Print("ADDRESS OF %d RNODE: %p\n",i,tempR);
+            Print("ADDRESS OF RULE: %p\n",tempR->getRule());
+            pWrite(tempR->getRuleTerm());
+            Print("ADDRESS OF TERM: %p\n",tempR->getRuleTerm());
+            Print("%d\n\n",tempR->getRuleIndex());
+            tempR   =   tempR->getNext();
+            i++;
+        }
+        //Print("TESTED ELEMENT: ");
+        //pWrite(l->getPoly());
+        //pWrite(l->getTerm());
+        //pWrite(ppMult_qq(t,l->getTerm()));
+        //Print("%d\n\n",l->getIndex());
+      */
+// start at the previously added element to gPrev, as all other elements will have the same index for sure
+    if(idx > l->getIndex()) {
+        return false;
+    }
+
+    RNode* testNode; // =   new RNode();
+    testNode    =   rules->getFirst();
+    /*
+     if(NULL == rTag->getFirst()) {
+        if(NULL != rules->getFirst()) {
+            testNode    =   rules->getFirst();
+        }
+        else {
+            return false;
+        }
+    }
+
+     else {
+
+        if(l->getIndex() > rTag->getFirst()->getRuleIndex()) {
+            testNode    =   rules->getFirst();
+        }
+        else {
+       //Print("HIER\n");
+            //Print("DEBUG\n");
+        //Print("L INDEX: %d\n",l->getIndex());
+            *-------------------------------------
+             * TODO: WHEN INTERREDUCING THE GB THE
+             *       INDEX OF THE PREVIOUS ELEMENTS
+             *       GETS HIGHER!
+             *-----------------------------------*
+            //testNode    =   rules->getFirst();
+            testNode    =   rTag->get(l->getIndex());
+            if(NULL == testNode) {
+                testNode    =   rules->getFirst();
+            }
+            //Print("TESTNODE ADDRESS: %p\n",testNode);
+        }
+    }
+    */
+    //testNode    =   rules->getFirst();
+    // save the monom t1*label_term(l) as it is tested various times in the following
+    poly u1 = ppMult_qq(t,l->getTerm());
+    // first element added to rTag was NULL, check for this
+    //Print("%p\n",testNode->getRule());
+    // NOTE: testNode is possibly NULL as rTag->get() returns NULL for elements of index <=1!
+    //Print("TESTNODE: %p\n",testNode);
+    //pWrite(testNode->getRuleTerm());
+    if(NULL != testNode ) {
+        //pWrite(testNode->getRuleTerm());
+    }
+    if(NULL != testNode) {
+        if(testNode->getRuleOld() == l->getRuleOld()) {
+            //Print("%p\n%p\n",testNode->getRule(),l->getRule());
+            //Print("EQUAL\n");
+        }
+        else {
+            //Print("NOT EQUAL\n");
+        }
+    }
+    while(NULL != testNode && testNode->getRuleOld() != l->getRuleOld()
+          && l->getIndex() == testNode->getRuleOldIndex()) {
+        //Print("%p\n",testNode);
+        //pWrite(testNode->getRuleTerm());
+        //pWrite(t);
+        //pWrite(l->getTerm());
+        //pWrite(u1);
+        //Print("%d\n",testNode->getRuleIndex());
+        if(pLmDivisibleByNoComp(testNode->getRuleOldTerm(),u1)) {
+            //Print("-----------------Criterion 2 NOT passed!-----------------------------------\n");
+            //Print("INDEX: %d\n",l->getIndex());
+            pDelete(&u1);
+    //Print("------------------------------IN CRITERION 2/1-----------------------------------------\n\n");
+            return true;
+        }
+        testNode    =   testNode->getNext();
+    }
+    //delete testNode;
+    pDelete(&u1);
+    //Print("------------------------------IN CRITERION 2/1-----------------------------------------\n\n");
+    return false;
+}
+
+
+
+/*
+=================================================================================================================
+Criterion 2, i.e. Rewritten Criterion, for its second call in computeSPols(), with added lastRuleTested parameter
+=================================================================================================================
+*/
+inline bool criterion2(poly t, LPolyOld* l, RList* rules, RuleOld* testedRuleOld) {
+    //Print("------------------------------IN CRITERION 2/2-----------------------------------------\n");
+    //Print("LAST RuleOld TESTED: %p",testedRuleOld);
+    /*
+    Print("RULES: \n");
+        RNode* tempR    =   rules->getFirst();
+        while(NULL != tempR) {
+            pWrite(tempR->getRuleTerm());
+            Print("%d\n\n",tempR->getRuleIndex());
+            tempR   =   tempR->getNext();
+        }
+        //Print("TESTED ELEMENT: ");
+        //pWrite(l->getPoly());
+        //pWrite(l->getTerm());
+        //pWrite(ppMult_qq(t,l->getTerm()));
+        //Print("%d\n\n",l->getIndex());
+    */
+// start at the previously added element to gPrev, as all other elements will have the same index for sure
+        RNode* testNode =   rules->getFirst();
+    // save the monom t1*label_term(l) as it is tested various times in the following
+    poly u1 = ppMult_qq(t,l->getTerm());
+        // first element added to rTag was NULL, check for this
+        while(NULL != testNode && testNode->getRuleOld() != testedRuleOld) {
+        //pWrite(testNode->getRuleTerm());
+        if(pLmDivisibleByNoComp(testNode->getRuleOldTerm(),u1)) {
+            //Print("--------------------------Criterion 2 NOT passed!------------------------------\n");
+            //Print("INDEX: %d\n",l->getIndex());
+            pDelete(&u1);
+    //Print("------------------------------IN CRITERION 2/2-----------------------------------------\n\n");
+            return true;
+        }
+                testNode    =   testNode->getNext();
+    }
+    pDelete(&u1);
+    //Print("------------------------------IN CRITERION 2/2-----------------------------------------\n\n");
+    return false;
+}
+
+/*
+ * check for useful pairs in the given subset of critical pairs
+ */
+int computeUsefulMinDeg(CNode* first) {
+  CNode* temp = first;
+  int numberUsefulPairsMinDeg = 0;
+  while(NULL != temp) {
+    if(!temp->getDel()) {
+      numberUsefulPairsMinDeg++;
+    }
+    temp = temp->getNext();
+  }
+  return numberUsefulPairsMinDeg;
+}
+/*
+==================================
+Computation of S-Polynomials in F5
+==================================
+*/
+void computeSPols(CNode* first, RTagList* rTag, RList* rules, LList* sPolyList, PList* rejectedGBList) {
+    CNode* temp         =   first;
+    //Print("\nDegree:  %d\n",temp->getData()->getDeg());
+    // only GB-critical pairs are computed
+    //while(NULL != temp && temp->getDel()) {
+    //  temp = temp->getNext();
+    //}
+    //if(temp->getData()->getDeg() == 11) {
+    //  Print("PAIRS OF DEG 11:\n");
+    //}
+    RList* f5rules = new RList();
+    CListOld* f5pairs = new CListOld();
+    poly sp     =   pInit();
+    number sign =   nInit(-1);
+    //Print("###############################IN SPOLS##############################\n");
+    //first->print();
+/*
+ * first of all: do everything for GB critical pairs
+ */
+    while(NULL != temp) {
+    //  if(temp->getData()->getDeg() == 11) {
+        //Print("--------------------------\n");
+        //Print("redundant? %d\n",temp->getDel());
+        //pWrite(pHead(temp->getLp1Poly()));
+        //Print("redundant: %d\n",temp->getAdLp1()->getDel());
+        //pWrite(pHead(temp->getLp2Poly()));
+        //Print("redundant: %d\n",temp->getAdLp2()->getDel());
+        //pWrite(pHead(ppMult_qq(temp->getT1(),temp->getLp1Poly())));
+        //  sp      =   ksOldSpolyRedNew(ppMult_qq(temp->getT1(),temp->getLp1Poly()),
+        //      ppMult_qq(temp->getT2(),temp->getLp2Poly()));
+          //Print("BEGIN SPOLY2\n====================\n");
+        //  pNorm(sp);
+        //  pWrite(pHead(sp));
+        //Print("--------------------------\n");
+      //}
+      if(!criterion2(temp->getT1(),temp->getAdLp1(),rules,temp->getTestedRuleOld())) {
+      //if(temp->getDel() == 0 && !criterion2(temp->getT1(),temp->getAdLp1(),rules,temp->getTestedRuleOld())) {
+        if(temp->getLp2Index() == temp->getLp1Index()) {
+          if(!criterion2(temp->getT2(),temp->getAdLp2(),rules,temp->getTestedRuleOld())) {
+            sp      =   ksOldSpolyRedNew(ppMult_qq(temp->getT1(),temp->getLp1Poly()),
+                ppMult_qq(temp->getT2(),temp->getLp2Poly()));
+            pNorm(sp);
+            if(NULL == sp) {
+              reductionsToZero++;
+              rules->insert(temp->getLp1Index(),ppMult_qq(temp->getT1(),temp->getLp1Term()));
+              numberOfRules++;
+              pDelete(&sp);
+            }
+            else {
+              rules->insert(temp->getLp1Index(),ppMult_qq(temp->getT1(),temp->getLp1Term()));
+              numberOfRules++;
+              sPolyList->insertByLabel(ppMult_qq(temp->getT1(),temp->getLp1Term()),temp->getLp1Index(),sp,rules->getFirst()->getRuleOld());
+            //Print("INSERTED\n");
+              numberOfSpolys++;
+            }
+          }
+          else {
+            if(highestDegreeGBCriticalPair < pDeg(ppMult_qq(temp->getT1(),temp->getLp1Poly()))) {
+              highestDegreeGBCriticalPair = pDeg(ppMult_qq(temp->getT1(),temp->getLp1Poly()));
+            }
+            rejectedGBList->insert(pHead(ppMult_qq(temp->getT1(),temp->getLp1Poly())));
+            //Print("rejected!\n");
+
+            //Print("CRITERION 2 in SPOLS 2nd generator\n");
+          }
+        }
+        else {
+          sp      =   ksOldSpolyRedNew(ppMult_qq(temp->getT1(),temp->getLp1Poly()),
+              ppMult_qq(temp->getT2(),temp->getLp2Poly()));
+          //Print("BEGIN SPOLY2\n====================\n");
+          pNorm(sp);
+          //pWrite(sp);
+          //Print("END SPOLY2\n====================\n");
+          if(NULL == sp) {
+            reductionsToZero++;
+            rules->insert(temp->getLp1Index(),ppMult_qq(temp->getT1(),temp->getLp1Term()));
+            numberOfRules++;
+            pDelete(&sp);
+          }
+          else {
+            rules->insert(temp->getLp1Index(),ppMult_qq(temp->getT1(),temp->getLp1Term()));
+            numberOfRules++;
+            sPolyList->insertByLabel(ppMult_qq(temp->getT1(),temp->getLp1Term()),temp->getLp1Index(),sp,rules->getFirst()->getRuleOld());
+            //Print("INSERTED\n");
+            numberOfSpolys++;
+          }
+        }
+      }
+      /*
+      if(temp->getDel() == 0 && criterion2(temp->getT1(),temp->getAdLp1(),rules,temp->getTestedRuleOld())) {
+        //Print("rejected!\n");
+        rejectedGBList->insert(pHead(ppMult_qq(temp->getT1(),temp->getLp1Poly())));
+      }
+
+
+      if(temp->getDel() == 1 && !criterion2(temp->getT1(),temp->getAdLp1(),rules,temp->getTestedRuleOld())) {
+        if(highestDegree < pDeg(ppMult_qq(temp->getT1(),temp->getLp1Poly()))) {
+          highestDegree   = pDeg(ppMult_qq(temp->getT1(),temp->getLp1Poly()));
+        }
+        if(temp->getLp2Index() == temp->getLp1Index()) {
+          if(!criterion2(temp->getT2(),temp->getAdLp2(),rules,temp->getTestedRuleOld())) {
+            sp      =   ksOldSpolyRedNew(ppMult_qq(temp->getT1(),temp->getLp1Poly()),
+                ppMult_qq(temp->getT2(),temp->getLp2Poly()));
+            pNorm(sp);
+            if(NULL == sp) {
+              reductionsToZero++;
+              rules->insert(temp->getLp1Index(),ppMult_qq(temp->getT1(),temp->getLp1Term()));
+              numberOfRules++;
+              pDelete(&sp);
+            }
+            else {
+              rules->insert(temp->getLp1Index(),ppMult_qq(temp->getT1(),temp->getLp1Term()));
+              numberOfRules++;
+
+
+              // save the address of the rule again in a different
+              // list
+
+              f5rules->insert(rules->getFirst()->getRuleOld());
+              f5pairs->insertWithoutSort(temp->getData());
+              ///////////////////////////////////////
+
+              //sPolyList->insertByLabel(ppMult_qq(temp->getT1(),temp->getLp1Term()),temp->getLp1Index(),sp,rules->getFirst()->getRuleOld());
+            }
+          }
+        }
+        else {
+          sp      =   ksOldSpolyRedNew(ppMult_qq(temp->getT1(),temp->getLp1Poly()),
+              ppMult_qq(temp->getT2(),temp->getLp2Poly()));
+          //Print("BEGIN SPOLY2\n====================\n");
+          pNorm(sp);
+          //pWrite(sp);
+          //Print("END SPOLY2\n====================\n");
+          if(NULL == sp) {
+            reductionsToZero++;
+            //rules->insert(temp->getLp1Index(),ppMult_qq(temp->getT1(),temp->getLp1Term()));
+            numberOfRules++;
+            pDelete(&sp);
+          }
+          else {
+            rules->insert(temp->getLp1Index(),ppMult_qq(temp->getT1(),temp->getLp1Term()));
+            numberOfRules++;
+            // save the address of the rule again in a different
+            // list
+
+            f5rules->insert(rules->getFirst()->getRuleOld());
+            f5pairs->insertWithoutSort(temp->getData());
+            ///////////////////////////////////////
+            //sPolyList->insertByLabel(ppMult_qq(temp->getT1(),temp->getLp1Term()),temp->getLp1Index(),sp,rules->getFirst()->getRuleOld());
+            //  numberOfSpolys++;
+          }
+        }
+      }
+        // the following else is not needed at all as we are checking
+        // F5-critical pairs in this step
+        /*
+           else {
+           if(!temp->getDel()) {
+           rejectedGBList->insert(pHead(ppMult_qq(temp->getT1(),temp->getLp1Poly())));
+           }
+
+           }
+           */
+
+        temp    =   temp->getNext();
+
+      }
+
+      /*
+      temp = f5pairs->getFirst();
+      RNode* tempRule = f5rules->getFirst();
+      int howmany = 1;
+      while(NULL != temp) {
+        //Print("RULE:  ");
+        //pWrite(ppMult_qq(temp->getT1(),temp->getLp1Term()));
+        sp      =   ksOldSpolyRedNew(ppMult_qq(temp->getT1(),temp->getLp1Poly()),
+                                     ppMult_qq(temp->getT2(),temp->getLp2Poly()));
+        pNorm(sp);
+        if(rejectedGBList->check(pHead(ppMult_qq(temp->getT1(),temp->getLp1Poly())))) { //|| (temp->getData()->getDeg() == 10 && howmany == 2)) {
+          if((temp->getData()->getDeg() == 10) && (howmany == 2)) {
+            //Print("HIER DRIN IM SAFTLADEN\n");
+          }
+          sPolyList->insertByLabel(ppMult_qq(temp->getT1(),temp->getLp1Term()),temp->getLp1Index(),sp,tempRule->getRuleOld());
+              numberOfSpolys++;
+              howmany++;
+        }
+        else {
+          numberRejectedF5CriticalPairs++;
+              howmany++;
+          if(numberRejectedF5CriticalPairs < -1) { // ||
+          }
+          else {
+             //numberRejectedF5CriticalPairs == 7) {
+            /*
+            Print("--------------------------------- rejected F5-critical pair-------------------------------------\n");
+            pWrite(pHead(ppMult_qq(temp->getT1(),temp->getLp1Poly())));
+            Print("Label: ");
+            pWrite(ppMult_qq(temp->getT1(),temp->getLp1Term()));
+            Print("%d\n",temp->getDel());
+            Print("Comes from:\n ");
+            pWrite(pHead(temp->getLp1Poly()));
+            Print("Label: ");
+            pWrite(temp->getLp1Term());
+            Print("%d\n",temp->getLp1Index());
+            pWrite(pHead(temp->getLp2Poly()));
+            Print("Label: ");
+            pWrite(temp->getLp2Term());
+            Print("%d\n",temp->getLp2Index());
+            //Print("--------------------------------------LIST OF GB PAIRS REJECTED-----------------------------------------\n");
+            //rejectedGBList->print();
+            Print("--------------------------------------------------------------------------------------------------------\n");
+            //if(temp->getLp1Index() < 7) {
+              sPolyList->insertByLabel(ppMult_qq(temp->getT1(),temp->getLp1Term()),temp->getLp1Index(),sp,tempRule->getRuleOld());
+
+            //}
+          //numberOfSpolys++;
+          }
+        //pSetExp(tempRule->getRuleOld()->getTerm(),1,1000);
+        }
+        temp      = temp->getNext();
+        tempRule  = tempRule->getNext();
+
+      }
+      */
+      // these critical pairs can be deleted now as they are either useless for further computations or
+      // already saved as an S-polynomial to be reduced in the following
+      delete first;
+//Print("NUMBER SPOLYS: %d\n", numberOfSpolys);
+//Print("SPOLY LIST: \n");
+//LNode* tempSpoly = sPolyList->getFirst();
+//if(NULL != tempSpoly) {
+//  pWrite(pHead(tempSpoly->getPoly()));
+//  tempSpoly = tempSpoly->getNext();
+//}
+//Print("-----SP------\n");
+//else {
+//  Print("EMPTY SPOLYLIST!\n");
+//}
+}
+
+/*
+========================================================================
+reduction including subalgorithm topReduction() using Faugere's criteria
+========================================================================
+*/
+void reduction(LList* sPolyList, CListOld* critPairs, LList* gPrev, RList* rules, LTagList* lTag, RTagList* rTag,
+                 ideal gbPrev, PList* rejectedGBList, int plus) {
+    //Print("##########################################In REDUCTION!########################################\n");
+    // check if sPolyList has any elements
+    // NOTE: due to initialization sPolyList always has a default NULL element
+    LNode* temp = sPolyList->getFirst();
+    while(NULL != temp) {
+        // temp is the first element in the sPolyList which should be reduced
+        // due to earlier sorting this is the element of minimal degree AND
+        // minimal label
+        // delete the above first element from sPolyList, temp will be either reduced to
+        // zero or added to gPrev, but never come back to sPolyList
+        //pWrite(sPolyList->getFirst()->getPoly());
+        //Print("LIST OF SPOLYNOMIALS!\n");
+        //sPolyList->print();
+        sPolyList->setFirst(temp->getNext());
+        poly tempNF = kNF(gbPrev,currRing->qideal,temp->getPoly());
+        if(NULL != tempNF) {
+            pNorm(tempNF);
+            temp->setPoly(tempNF);
+            // try further reductions of temp with polynomials in gPrev
+            // with label index = current label index: this is done such that there
+            // is no label corruption during the reduction process
+            //Print("lower label reduction:  ");
+            //pWrite(tempNF);
+            topReduction(temp,sPolyList,gPrev,critPairs,rules,lTag,rTag,gbPrev, rejectedGBList,plus);
+
+        }
+        else {
+            reductionsToZero++;
+            delete temp;
+        }
+        //if(NULL != temp->getPoly()) {
+        //    criticalPair(gPrev,critPairs,lTag,rTag,rules);
+        //}
+        temp =   sPolyList->getFirst();
+    }
+    //sPolyList->print();
+    //delete sPolyList;
+}
+
+/*
+========================================================================
+reduction including subalgorithm topReduction() using Faugere's criteria
+========================================================================
+*/
+void newReduction(LList* sPolyList, CListOld* critPairs, LList* gPrev, LList* reducers, RList* rules, LTagList* lTag, RTagList* rTag,
+                 ideal gbPrev, int termination, PList* rejectedGBList, int plus) {
+    //Print("##########################################In REDUCTION!########################################\n");
+    // check if sPolyList has any elements
+    // NOTE: due to initialization sPolyList always has a default NULL element
+    //Print("--1--\n");
+    LNode* temp = sPolyList->getFirst();
+    //Print("START OF REDUCTION:  ");
+    while(NULL != temp) {
+        numberOfReductions++;
+        // temp is the first element in the sPolyList which should be reduced
+        // due to earlier sorting this is the element of minimal degree AND
+        // minimal label
+        // delete the above first element from sPolyList, temp will be either reduced to
+        // zero or added to gPrev, but never come back to sPolyList
+        //Print("LIST OF SPOLYNOMIALS!\n");
+        //sPolyList->print();
+        //pWrite(sPolyList->getFirst()->getPoly());
+        sPolyList->setFirst(temp->getNext());
+        //if(pDeg(temp->getPoly()) > 11) {
+        //  Print("YES!!!!!!!!!!!!!!!!\n");
+        //}
+        //pWrite(temp->getPoly());
+        //poly tempNF = kNF(gbPrev,currRing->qideal,temp->getPoly());
+        //Print("!!!\n");
+        //if(NULL != tempNF) {
+            //pNorm(tempNF);
+            //temp->setPoly(tempNF);
+            //Print("lower label reduction:  ");
+            //pWrite(tempNF);
+            // try further reductions of temp with polynomials in gPrev
+            // with label index = current label index: this is done such that there
+            // is no label corruption during the reduction process
+            findReducers(temp,sPolyList,gbPrev,gPrev,reducers,critPairs,rules,lTag,rTag, termination, rejectedGBList,plus);
+        //}
+        //else {
+        //    reductionsToZero++;
+        //    delete temp;
+        //}
+        //if(NULL != temp->getPoly()) {
+        //    criticalPair(gPrev,critPairs,lTag,rTag,rules);
+        //}
+        //Print("HIER AUCH ?\n");
+        //Print("--2--\n");
+        //sPolyList->print();
+        //critPairs->print();
+        temp =   sPolyList->getFirst();
+        //Print("%p\n",temp);
+    }
+    //sPolyList->print();
+    //delete sPolyList;
+    //Print("REDUCTION FERTIG\n");
+}
+
+
+/*!
+ * ================================================================================
+ * searches for reducers of temp similar to the symbolic preprocessing of F4  and
+ * divides them into a "good" and "bad" part:
+ *
+ * the "good" ones are the reducers which do not corrupt the label of temp, with
+ * these the normal form of temp is computed
+ *
+ * the "bad" ones are the reducers which corrupt the label of temp, they are tested
+ * later on for possible new rules and S-polynomials to be added to the algorithm
+ * ================================================================================
+*/
+void findReducers(LNode* l, LList* sPolyList, ideal gbPrev, LList* gPrev, LList* reducers, CListOld* critPairs, RList* rules, LTagList* lTag, RTagList* rTag, int termination, PList* rejectedGBList, int plus) {
+    int canonicalize    =   0;
+    //int timerRed        =   0;
+    bool addToG         =   1;
+    number sign         =   nInit(-1);
+    LList* good         =   new LList();
+    LList* bad          =   new LList();
+    LList* monomials    =   new LList(l->getLPolyOld());
+    poly u              =   pOne();
+    number nOne         =   nInit(1);
+    LNode* tempRed      =   lTag->getFirstCurrentIdx();
+    LNode* tempMon      =   monomials->getFirst();
+    poly tempPoly       =   pInit();
+    poly redPoly        =   NULL;
+    int idx             =   l->getIndex();
+    //Print("IN FIND REDUCERS:  ");
+    //pWrite(l->getPoly());
+    tempPoly    =   pCopy(l->getPoly());
+    //tempMon->setPoly(tempPoly);
+    //while(NULL != tempMon) {
+        // iteration over all monomials in tempMon
+        kBucket* bucket  =   kBucketCreate(currRing);
+        kBucketInit(bucket,tempPoly,0);
+        tempPoly    =   kBucketGetLm(bucket);
+        //Print("\n\n\nTO BE REDUCED:  ");
+        //pWrite(l->getPoly());
+        //pWrite(l->getTerm());
+        //pWrite(tempPoly);
+        while(NULL != tempPoly) {
+            // iteration of all elements in gPrev of the current index
+            tempRed =   gPrev->getFirst();
+            while(NULL != tempRed) {
+                //Print("TEMPREDPOLY:  ");
+                //pWrite(tempRed->getPoly());
+                if(pLmDivisibleByNoComp(tempRed->getPoly(),tempPoly)) {
+                    u   =   pDivideM(pHead(tempPoly),pHead(tempRed->getPoly()));
+                    //Print("U:  ");
+                    //pWrite(u);
+                    if(pLmCmp(u,pOne()) != 0) { // else u = 1 and no test need to be done!
+                    if(tempRed->getIndex() != idx) {
+                            // passing criterion1 ?
+                            if(!criterion1(gPrev,u,tempRed,lTag)) {
+                                    poly tempRedPoly    =   tempRed->getPoly();
+                                    //Print("REDUCER: ");
+                                    //pWrite(tempRedPoly);
+                                    pIter(tempRedPoly);
+                                    int lTempRedPoly    =   pLength(tempRedPoly);
+                                    kBucketExtractLm(bucket);
+                                    kBucket_Minus_m_Mult_p(bucket,u,tempRedPoly,&lTempRedPoly);
+                                    canonicalize++;
+                                    //Print("Reduction\n");
+                                    if(!(canonicalize % 50)) {
+                                        kBucketCanonicalize(bucket);
+                                    }
+                                    tempPoly    =   kBucketGetLm(bucket);
+                                    //Print("TEMPPOLY:  ");
+                                    //pWrite(tempPoly);
+                                    if(NULL != tempPoly) {
+                                        tempRed     =   gPrev->getFirst();
+                                        continue;
+                                    }
+                                    else {
+                                        break;
+                                    }
+                             }
+
+                    }
+                    else {
+                        if(pLmCmp(ppMult_qq(u,tempRed->getTerm()),l->getTerm()) == 0) {
+                         //Print("NOT ALLOWED REDUCER, EQUAL LABELS:\n");
+                                      //pWrite(u);
+                                      //pWrite(tempRed->getTerm());
+                                      //pWrite(pHead(tempRed->getPoly()));
+                                      addToG  = 0;
+                        }
+                        if(pLmCmp(ppMult_qq(u,tempRed->getTerm()),l->getTerm()) != 0) {
+                            // passing criterion2 ?
+                            if(!criterion2(gPrev->getFirst()->getIndex(), u,tempRed,rules,rTag)) {
+                                // passing criterion1 ?
+                                if(!criterion1(gPrev,u,tempRed,lTag)) {
+                                    if(pLmCmp(ppMult_qq(u,tempRed->getTerm()),l->getTerm()) == 1) {
+                                        if(NULL == redPoly) {
+                                            bad->insert(tempRed->getLPolyOld());
+                                            addToG  = 1;
+                                            //poly tempRedPoly    =   tempRed->getPoly();
+                                            //break;
+                                        }
+                                    }
+                                    else {
+                                        poly tempRedPoly    =   tempRed->getPoly();
+                                        //Print("REDUCER: ");
+                                        //pWrite(tempRedPoly);
+                                        pIter(tempRedPoly);
+                                        int lTempRedPoly    =   pLength(tempRedPoly);
+                                        //Print("HEAD MONOMIAL KBUCKET: ");
+                                        //pWrite(kBucketGetLm(bucket));
+                                        kBucketExtractLm(bucket);
+                                        kBucket_Minus_m_Mult_p(bucket,u,tempRedPoly,&lTempRedPoly);
+                                        canonicalize++;
+                                        //Print("REDUCTION\n");
+                                        addToG  = 1;
+                                        if(!(canonicalize % 50)) {
+                                            kBucketCanonicalize(bucket);
+                                        }
+                                        //Print("HEAD MONOMIAL KBUCKET: ");
+                                        //pWrite(kBucketGetLm(bucket));
+                                        tempPoly    =   kBucketGetLm(bucket);
+                                        //Print("TEMPPOLY:  ");
+                                        //pWrite(tempPoly);
+                                        if(NULL != tempPoly) {
+                                            tempRed     =   gPrev->getFirst();
+                                            continue;
+                                        }
+                                        else {
+                                            break;
+                                        }
+                                    }
+                                }
+                            }
+                            else {
+                              //Print("CRIT 1  ");
+
+                                      if(pLmCmp(ppMult_qq(u,tempRed->getTerm()),l->getTerm()) == 1 ) {
+                                      //Print("NOT ALLOWED REDUCER, CRIT 1:\n");
+                                      //pWrite(u);
+                                      //pWrite(tempRed->getTerm());
+                                      //pWrite(tempRed->getPoly());
+                                      if(pLmDivisibleByNoComp(tempRed->getTerm(),l->getTerm())) {
+                                        //Print("REDUCER LABEL:  ");
+                                        //pWrite(tempRed->getTerm());
+addToG  = 0;
+                                      }
+                                    }
+                            }
+                        }
+                        else {
+                          //Print("CRIT 2  ");
+                                    if(pLmCmp(ppMult_qq(u,tempRed->getTerm()),l->getTerm()) == 1) {
+                                      //Print("NOT ALLOWED REDUCER, CRIT 2:\n");
+                                      //pWrite(u);
+                                      //pWrite(tempRed->getTerm());
+                                      //pWrite(tempRed->getPoly());
+                                      if(pLmDivisibleByNoComp(tempRed->getTerm(),l->getTerm())) {
+                                        //Print("REDUCER LABEL:  ");
+                                        //pWrite(tempRed->getTerm());
+addToG  = 0;
+                                      }
+                                    }
+                        }
+                    }
+                    }
+                    else { // u = 1 => reduce without checking criteria
+                        poly tempRedPoly    =   tempRed->getPoly();
+                        //Print("REDUCER: ");
+                        //pWrite(tempRedPoly);
+                        pIter(tempRedPoly);
+                        int lTempRedPoly    =   pLength(tempRedPoly);
+                        kBucketExtractLm(bucket);
+                        kBucket_Minus_m_Mult_p(bucket,u,tempRedPoly,&lTempRedPoly);
+                        canonicalize++;
+                        //Print("Reduction\n");
+                        if(!(canonicalize % 50)) {
+                            kBucketCanonicalize(bucket);
+                        }
+                        tempPoly    =   kBucketGetLm(bucket);
+                        //Print("TEMPPOLY:  ");
+                        //pWrite(tempPoly);
+                        if(NULL != tempPoly) {
+                            tempRed     =   gPrev->getFirst();
+                            continue;
+                        }
+                        else {
+                            break;
+                        }
+
+                    }
+                }
+                tempRed =   tempRed->getNext();
+            }
+            // reduction process with elements in LList* reducers
+          if(NULL != tempPoly) {
+            //Print("HERE\n");
+            tempRed =   reducers->getFirst();
+            while(NULL != tempRed) {
+                //Print("TEMPREDPOLY:  ");
+                //pWrite(tempRed->getPoly());
+              //pWrite(tempPoly);
+              if(pLmDivisibleByNoComp(tempRed->getPoly(),tempPoly)) {
+                    //Print("A\n");
+                    u   =   pDivideM(pHead(tempPoly),pHead(tempRed->getPoly()));
+                    //Print("U:  ");
+                    //pWrite(u);
+                    if(tempRed->getIndex() != idx) {
+                            // passing criterion1 ?
+                            if(!criterion1(gPrev,u,tempRed,lTag)) {
+                                    poly tempRedPoly    =   tempRed->getPoly();
+                                    //Print("REDUCER: ");
+                                    //pWrite(ppMult_qq(u,tempRedPoly));
+                                    pIter(tempRedPoly);
+                                    int lTempRedPoly    =   pLength(tempRedPoly);
+                                    kBucketExtractLm(bucket);
+                                    kBucket_Minus_m_Mult_p(bucket,u,tempRedPoly,&lTempRedPoly);
+                                    canonicalize++;
+                                    //Print("Reduction\n");
+                                    if(!(canonicalize % 50)) {
+                                        kBucketCanonicalize(bucket);
+                                    }
+                                    tempPoly    =   kBucketGetLm(bucket);
+                                    //Print("TEMPPOLY:  ");
+                                    //pWrite(tempPoly);
+                                    if(NULL != tempPoly) {
+                                        tempRed     =   gPrev->getFirst();
+                                        continue;
+                                    }
+                                    else {
+                                        break;
+                                    }
+                             }
+
+                    }
+                    else {
+                        if(pLmCmp(ppMult_qq(u,tempRed->getTerm()),l->getTerm()) == 0) {
+                         //Print("NOT ALLOWED REDUCER, EQUAL LABELS:\n");
+                                      //pWrite(u);
+                                      //pWrite(tempRed->getTerm());
+                                      //pWrite(pHead(tempRed->getPoly()));
+                                      //addToG  = 0;
+                        }
+                        if(pLmCmp(ppMult_qq(u,tempRed->getTerm()),l->getTerm()) != 0) {
+                            // passing criterion2 ?
+                            if(!criterion2(gPrev->getFirst()->getIndex(), u,tempRed,rules,rTag)) {
+                                // passing criterion1 ?
+                                if(!criterion1(gPrev,u,tempRed,lTag)) {
+                                    if(pLmCmp(ppMult_qq(u,tempRed->getTerm()),l->getTerm()) == 1) {
+                                        if(NULL == redPoly) {
+                                            bad->insert(tempRed->getLPolyOld());
+                                            addToG  = 1;
+                                            //poly tempRedPoly    =   tempRed->getPoly();
+                                            //break;
+                                        }
+                                    }
+                                    else {
+                                        poly tempRedPoly    =   tempRed->getPoly();
+                                        //Print("REDUCER: ");
+                                        //pWrite(ppMult_qq(u,tempRedPoly));
+                                        pIter(tempRedPoly);
+                                        int lTempRedPoly    =   pLength(tempRedPoly);
+                                        //Print("HEAD MONOMIAL KBUCKET: ");
+                                        //pWrite(kBucketGetLm(bucket));
+                                        kBucketExtractLm(bucket);
+                                        kBucket_Minus_m_Mult_p(bucket,u,tempRedPoly,&lTempRedPoly);
+                                        canonicalize++;
+                                        //Print("REDUCTION\n");
+                                        addToG  = 1;
+                                        if(!(canonicalize % 50)) {
+                                            kBucketCanonicalize(bucket);
+                                        }
+                                        //Print("HEAD MONOMIAL KBUCKET: ");
+                                        //pWrite(kBucketGetLm(bucket));
+                                        tempPoly    =   kBucketGetLm(bucket);
+                                        //Print("TEMPPOLY:  ");
+                                        //pWrite(tempPoly);
+                                        if(NULL != tempPoly) {
+                                            tempRed     =   gPrev->getFirst();
+                                            continue;
+                                        }
+                                        else {
+                                            break;
+                                        }
+                                    }
+                                }
+                            }
+                            else {
+                              //Print("CRIT 1  ");
+
+                                      if(pLmCmp(ppMult_qq(u,tempRed->getTerm()),l->getTerm()) == 1 ) {
+                                      //Print("NOT ALLOWED REDUCER, CRIT 1:\n");
+                                      //pWrite(u);
+                                      //pWrite(tempRed->getTerm());
+                                      //pWrite(tempRed->getPoly());
+                                      if(pLmDivisibleByNoComp(tempRed->getTerm(),l->getTerm())) {
+                                        //Print("REDUCER LABEL:  ");
+                                        //pWrite(tempRed->getTerm());
+                                        addToG  = 0;
+                                      }
+                                    }
+                            }
+                        }
+                        else {
+                          //Print("CRIT 2  ");
+                                    if(pLmCmp(ppMult_qq(u,tempRed->getTerm()),l->getTerm()) == 1) {
+                                      //Print("NOT ALLOWED REDUCER, CRIT 2:\n");
+                                      //pWrite(u);
+                                      //pWrite(tempRed->getTerm());
+                                      //pWrite(tempRed->getPoly());
+                                      if(pLmDivisibleByNoComp(tempRed->getTerm(),l->getTerm())) {
+                                        //Print("REDUCER LABEL:  ");
+                                        //pWrite(tempRed->getTerm());
+addToG  = 0;
+                                      }
+                                    }
+                        }
+                    }
+
+                }
+                tempRed =   tempRed->getNext();
+            }
+          }
+            if(NULL != tempPoly) {
+                if(NULL == redPoly) {
+                    redPoly =   kBucketExtractLm(bucket);
+                }
+                else {
+                    redPoly     =   p_Merge_q(redPoly,kBucketExtractLm(bucket),currRing);
+                }
+               // for top-reduction only
+               redPoly  = p_Merge_q(redPoly,kBucketClear(bucket),currRing);
+               break;
+               // end for top-reduction only
+               tempPoly    =   kBucketGetLm(bucket);
+
+            }
+        }
+        if(NULL == redPoly) {
+            reductionsToZero++;
+            //pDelete(&redPoly);
+        }
+        else {
+            Print("\nELEMENT ADDED TO GPREV: ");
+            pNorm(redPoly);
+              if(highestDegree < pDeg(redPoly)) {
+                  highestDegree   = pDeg(redPoly);
+              }
+            pWrite(pHead(redPoly));
+            //pWrite(l->getTerm());
+            //Print("%d\n",canonicalize);
+            l->setPoly(redPoly);
+            // give "l" the label if it is "useful" (addToG = 0) or "useless"
+            // (addToG = 1)
+            l->setDel(!addToG);
+            Print("redundant? %d\n\n",l->getDel());
+            if(addToG == 0 && termination == 1) {
+              reducers->insert(l->getLPolyOld());
+            }
+            else {
+              gPrev->insert(l->getLPolyOld());
+            }
+            //Print("%d\n\n",termination);
+            if(termination == 1) {
+            if(addToG) {
+              //Print("----------------HERE?-----------------\n");
+              criticalPair(gPrev,critPairs,lTag,rTag,rules, rejectedGBList,plus);
+            }
+            else {
+              notInG++;
+              //Print("\nNONONO");
+              //pWrite(pHead(l->getPoly()));
+              //pWrite(l->getTerm());
+            }
+            }
+            // case in which all new elements are added to gPrev!
+            // using boolean "addToG" to know if the element is "useful" (0) or
+            // "useless" (1)
+            else {
+              if(!l->getDel()) {
+                criticalPair(gPrev,critPairs,lTag,rTag,rules,rejectedGBList,plus);
+              }
+              else {
+                criticalPair2(gPrev,critPairs,lTag,rTag,rules, rejectedGBList);
+              }
+            }
+        }
+
+    // if there are "bad" reducers than try to compute new S-polynomials and rules
+
+    if(NULL != bad->getFirst()) {
+        //Print("BAD STUFF LIST:\n");
+        //bad->print();
+        LNode* tempBad  =   bad->getFirst();
+        //pWrite(l->getPoly());
+        while(NULL != tempBad) {
+            if(pDivisibleBy(tempBad->getPoly(),l->getPoly())) {
+                //Print("BAD STUFF\n");
+                //pWrite(l->getPoly());
+                //pWrite(tempBad->getPoly());
+                u   =   pDivide(pHead(l->getPoly()),pHead(tempBad->getPoly()));
+                //Print("MULTIPLIER:  ");
+                //pWrite(u);
+                pSetCoeff(u,nOne);
+                if(pLmCmp(ppMult_qq(u,tempBad->getTerm()),l->getTerm()) != 0) {
+                    // passing criterion2 ?
+                    if(!criterion2(gPrev->getFirst()->getIndex(), u,tempBad,rules,rTag)) {
+                        // passing criterion1 ?
+                        if(!criterion1(gPrev,u,tempBad,lTag)) {
+                            //Print("HIERHIERHIERHIERHIERHIER\n");
+                            rules->insert(tempBad->getIndex(),ppMult_qq(u,tempBad->getTerm()));
+                            numberOfRules++;
+                            //gPrev->print();
+                            //pWrite(l->getPoly());
+                            poly temp   =   ksOldSpolyRedNew(ppMult_qq(u,tempBad->getPoly()),l->getPoly());
+                            //pWrite(l->getPoly());
+                            //Print("%p\n",temp);
+                            //gPrev->print();
+                            if(NULL != temp) {
+                                pNorm(temp);
+                                LNode* tempBadNew   =   new LNode(ppMult_qq(u,tempBad->getTerm()),tempBad->getIndex(),temp,rules->getFirst()->getRuleOld());
+                                //pWrite(temp);
+                                //pWrite(tempBadNew->getPoly());
+                                //pWrite(tempBadNew->getTerm());
+                                //pWrite(pHead(tempBadNew->getPoly()));
+                                //Print("%p\n",tempBadNew->getPoly());
+                                //tempRed->getLPoly()->setRule(rules->getFirst()->getRule());
+                                tempBadNew->setDel(1);
+
+                                sPolyList->insertByLabel(tempBadNew);
+                                //Print("BAD SPOLYLIST: \n");
+                                //sPolyList->print();
+                            }
+                        }
+                    }
+                }
+            }
+        //Print("HIER\n");
+            tempBad =   tempBad->getNext();
+            //Print("%p\n",tempBad);
+        }
+       // Print("-------------------BAD STUFF LIST-----------------------------\n");
+    }
+        //Print("HIER AUCH\n");
+        //Print("SPOLYLIST IN BAD: \n");
+        //sPolyList->print();
+    //Print("END FIND REDUCERS\n");
+}
+
+/*
+=======================================================================================
+merging 2 polynomials p & q without requiring that all monomials of p & q are different
+if there are equal monomials in p & q only one of these monomials (always that of p!)
+is taken into account
+=======================================================================================
+
+poly p_MergeEq_q(poly p, poly q, const ring r) {
+  assume(p != NULL && q != NULL);
+  p_Test(p, r);
+  p_Test(q, r);
+#if PDEBUG > 0
+  int l = pLength(p) + pLength(q);
+#endif
+
+  spolyrec rp;
+  poly a = &rp;
+  DECLARE_LENGTH(const unsigned long length = r->CmpL_Size);
+  DECLARE_ORDSGN(const long* ordsgn = r->ordsgn);
+
+  Top:     // compare p and q w.r.t. monomial ordering
+  p_MemCmp(p->exp, q->exp, length, ordsgn, goto Equal, goto Greater , goto Smaller);
+
+  Equal:
+  a =   pNext(a)    =   p;
+  pIter(p);
+  pIter(q);
+  if(NULL == p) {
+      if(NULL == q) {
+          goto Finish;
+      }
+      else {
+          pNext(a)  =   q;
+          goto Finish;
+      }
+  }
+  goto Top;
+
+  Greater:
+  a = pNext(a) = p;
+  pIter(p);
+  if (p==NULL) { pNext(a) = q; goto Finish;}
+  goto Top;
+
+  Smaller:
+  a = pNext(a) = q;
+  pIter(q);
+  if (q==NULL) { pNext(a) = p; goto Finish;}
+  goto Top;
+
+  Finish:
+
+  p_Test(pNext(&rp), r);
+#if PDEBUG > 0
+  pAssume1(l - pLength(pNext(&rp)) == 0);
+#endif
+  return pNext(&rp);
+}
+*/
+
+/*
+=====================================================================================
+top reduction in F5, i.e. reduction of a given S-polynomial by labeled polynomials of
+the same index whereas the labels are taken into account
+=====================================================================================
+*/
+void topReduction(LNode* l, LList* sPolyList, LList* gPrev, CListOld* critPairs,  RList* rules, LTagList* lTag, RTagList* rTag, ideal gbPrev, PList* rejectedGBList, int plus) {
+    //Print("##########################################In topREDUCTION!########################################\n");
+    // try l as long as there are reductors found by findReductor()
+    LNode* gPrevRedCheck    =   lTag->getFirstCurrentIdx();
+    LNode* tempRed;
+    poly pOne               =   pOne();
+    do {
+        //int timer5  =   initTimer();
+        //startTimer();
+        //Print("TOP REDUCTION:  ");
+        //pWrite(l->getPoly());
+        tempRed  =   findReductor(l,sPolyList,gPrevRedCheck,gPrev,rules,lTag,rTag);
+        //timer5  =   getTimer();
+        //reductionTime   =   reductionTime   +   timer5;
+        // if a reductor for l is found and saved in tempRed
+        if(NULL != tempRed) {
+            // if label of reductor is greater than the label of l we have to built a new element
+            // and add it to sPolyList
+
+            if(pLmCmp(tempRed->getTerm(),l->getTerm()) == 1) {
+                // needed sinc pSub destroys the arguments!
+                //poly temp_poly_l    =   pInit();
+                //temp_poly_l         =   pCopy(l->getPoly());
+                //Print("VORHER: ");
+                //pWrite(tempRed->getPoly());
+                //poly temp           =   pMinus_mm_Mult_qq(tempRed->getPoly(),pOne,l->getPoly());
+                poly temp   =   ksOldSpolyRedNew(l->getPoly(),tempRed->getPoly());
+                rules->insert(tempRed->getIndex(),tempRed->getTerm());
+                //Print("NACHHER: ");
+                //pWrite(tempRed->getPoly());
+                //Print("TEMP: ");
+                //pWrite(temp);
+                if(NULL != temp) {
+                    pNorm(temp);
+                    //tempRed->setPoly(temp);
+                    //tempRed->setDel(1);
+                    //rules->insert(tempRed->getIndex(),tempRed->getTerm());
+                    LNode* tempRedNew   =   new LNode(tempRed->getTerm(),tempRed->getIndex(),temp,rules->getFirst()->getRuleOld());
+                    //tempRed->getLPoly()->setRule(rules->getFirst()->getRule());
+                    tempRedNew->setDel(1);
+                    sPolyList->insertByLabel(tempRedNew);
+                }
+                else {
+                    pDelete(&temp);
+                    reductionsToZero++;
+                    //delete tempRed;
+                }
+            }
+
+            // label of reductor is smaller than the label of l, subtract reductor from l and delete the
+            // gPrevRedCheck pointer added to l during findReductor() as the head term of l changes
+            // after subtraction
+            else {
+
+                //poly temp_poly_l    =   pInit();
+                //temp_poly_l         =   pCopy(l->getPoly());
+                //poly temp   =   pMinus_mm_Mult_qq(tempRed->getPoly(),pOne,l->getPoly());
+                //Print("REDUCER: ");
+                //pWrite(tempRed->getPoly());
+                //pWrite(tempRed->getTerm());
+                poly temp   =   ksOldSpolyRedNew(l->getPoly(),tempRed->getPoly());
+                //Print("REDUCED ELEMENT:  ");
+                if(NULL != temp) {
+                    pNorm(temp);
+                    //pWrite(temp);
+                    poly tempNF =   kNF(gbPrev,currRing->qideal,temp);
+                    pNorm(tempNF);
+                    if(NULL == tempNF) {
+                        reductionsToZero++;
+                        pDelete(&tempNF);
+                        l->setPoly(NULL);
+                        break;
+                    }
+                    l->setPoly(tempNF);
+
+                    gPrevRedCheck   =   lTag->getFirstCurrentIdx();
+                }
+                else {
+                    reductionsToZero++;
+                    pDelete(&temp);
+                    l->setPoly(NULL);
+                    break;
+                }
+            }
+        }
+        else {
+            if(NULL != l->getPoly()) {
+                pNorm(l->getPoly());
+                //Print("ELEMENT ADDED TO GPREV: ");
+                //pWrite(l->getPoly());
+                gPrev->insert(l->getLPolyOld());
+                //Print("TEMP RED == 0  ");
+                //pWrite(l->getPoly());
+                //pWrite(l->getTerm());
+                //rules->print();
+                criticalPair(gPrev,critPairs,lTag,rTag,rules, rejectedGBList,plus);
+                //Print("LIST OF CRITICAL PAIRS:    \n");
+                //critPairs->print();
+            }
+            break;
+        }
+    } while(1);
+}
+
+
+/*
+=====================================================================
+subalgorithm to find a possible reductor for the labeled polynomial l
+=====================================================================
+*/
+LNode* findReductor(LNode* l, LList* sPolyList, LNode* gPrevRedCheck, LList* gPrev, RList* rules, LTagList* lTag,RTagList* rTag, PList* rejectedGBList) {
+    // allociation of memory for the possible reductor
+    //Print("LPOLY:  ");
+    //pWrite(l->getPoly());
+    poly u      =   pOne();
+    poly red;
+    number nOne =   nInit(1);
+    LNode* temp;
+    // head term of actual element such that we do not have to call pHead at each new reductor test
+    poly t      =   pHead(l->getPoly());
+    // if l was already checked use the information in gPrevRedCheck such
+    // that we can start searching for new reducers from this point and
+    // not from the first element of gPrev with the current index
+    temp    =   gPrevRedCheck;
+    // search for reductors until we are at the end of gPrev resp. at the
+    // end of the elements of the current index
+    while(NULL != temp && temp->getIndex() == l->getIndex()) {
+        // does the head of the element of gPrev divides the head of
+        // the to be reduced element?
+        if(pLmDivisibleByNoComp(pHead(temp->getPoly()),t)) {
+            // get all the information needed for the following tests
+            // of the criteria
+            u   =   pDivide(t,pHead(temp->getPoly()));
+            pSetCoeff(u,nOne);
+            red =   ppMult_qq(u,temp->getPoly());
+            pNorm(red);
+            // check if both have the same label
+            if(pLmCmp(ppMult_qq(u,temp->getTerm()),l->getTerm()) != 0) {
+                // passing criterion2 ?
+                if(!criterion2(gPrev->getFirst()->getIndex(), u,temp,rules,rTag)) {
+                    // passing criterion1 ?
+                    if(!criterion1(gPrev,u,temp,lTag)) {
+                            gPrevRedCheck   =   temp->getNext();
+                            LNode* redNode  =   new LNode(ppMult_qq(u,temp->getTerm()),temp->getIndex(),red,NULL,NULL);
+                            return redNode;
+                    }
+                }
+            }
+            if(pLmCmp(ppMult_qq(u,temp->getTerm()),l->getTerm()) == 1) {
+                // passing criterion2 ?
+                if(!criterion2(gPrev->getFirst()->getIndex(), u,temp,rules,rTag)) {
+                    // passing criterion1 ?
+                    if(!criterion1(gPrev,u,temp,lTag)) {
+                        poly tempSpoly  =   ksOldSpolyRedNew(red,l->getPoly());
+                        rules->insert(temp->getIndex(),ppMult_qq(u,temp->getTerm()));
+                        gPrevRedCheck   =   temp->getNext();
+                        if(NULL != tempSpoly) {
+                            pNorm(tempSpoly);
+                            sPolyList->insertByLabel(ppMult_qq(u,temp->getTerm()),temp->getIndex(),tempSpoly,rules->getFirst()->getRuleOld());
+                    //Print("NEW ONE: ");
+                    //pWrite(tempSpoly);
+                    //Print("HIER\n");
+                            //sPolyList->print();
+                            //sleep(5);
+                        }
+                    }
+                }
+            }
+        }
+        //Print("AUCH HIER\n");
+        temp = temp->getNext();
+    }
+
+//    delete temp;
+ return NULL;
+}
+
+
+
+/*
+==========================================================================
+MAIN:computes a gb of the ideal i in the ring r with our F5 implementation
+OPTIONS: INTEGER "opt" is to be set "0" for F5, "1" for F5R, "2" for F5C
+==========================================================================
+*/
+ideal F5main(ideal id, ring r, int opt, int plus, int termination) {
+  switch(opt) {
+    case 0:
+      Print("\nComputations are done by the standard F5 Algorithm");
+      break;
+    case 1:
+      Print("\nComputations are done by the variant F5R of the F5 Algorithm");
+      break;
+    case 2:
+      Print("\nComputations are done by the variant F5C of the F5 Algorithm");
+      break;
+    default:
+      WerrorS("\nThe option can only be set to \"0\", \"1\" or \"2\":\n\"0\": standard F5 Algorithm\n\"1\": variant F5R\n\"2\": variant F5C\nComputations are aborted!\n");
+      return id;
+  }
+
+    int timer   =   initTimer();
+    startTimer();
+    int i,j,k,l;
+    int gbLength;
+    // 1 polynomial for defining initial labels & further tests
+    poly ONE = pOne();
+    poly pOne   =   pOne();
+    number nOne =   nInit(1);
+    // tag the first element of index i-1 for criterion 1
+    //Print("LTAG BEGINNING: %p\n",lTag);
+
+    // DEBUGGING STUFF START
+    //Print("NUMBER: %d\n",r->N);
+    /*
+    int* ev = new int[r->N +1];
+    for(i=0;i<IDELEMS(id);i++) {
+        pGetExpV(id->m[i],ev);
+        //ev2  =   pGetExp(id->m[i],1);
+        pWrite(id->m[i]);
+        Print("EXP1: %d\n",ev[1]);
+        Print("EXP2: %d\n",ev[2]);
+        Print("EXP3: %d\n\n",ev[3]);
+        Print("SUM: %ld\n\n\n",sumVector(ev,r->N));
+    }
+    delete ev;
+    */
+    /*DEBUGGING STUFF END */
+
+    // first element in rTag is first element of rules which is NULL RNode,
+    // this must be done due to possible later improvements
+    RList* rules    =   new RList();
+    //Print("RULES FIRST: %p\n",rules->getFirst());
+    //Print("RULES FIRST DATA: %p\n",rules->getFirst()->getRule());
+    //RTagList* rTag  =   new RTagList(rules->getFirst());
+    RTagList* rTag  =   NULL;
+    i = 1;
+    /*for(j=0; j<IDELEMS(id); j++) {
+        if(NULL != id->m[j]) {
+            if(pComparePolys(id->m[j],ONE)) {
+                Print("One Polynomial in Input => Computations stopped\n");
+                ideal idNew = idInit(1,1);
+                idNew->m[0] = ONE;
+                return(idNew);
+            }
+        }
+    }*/
+    ideal idNew     =   kInterRed(id);
+    id              =   idNew;
+    //qsortDegree(&id->m[0],&id->m[IDELEMS(id)-1]);
+    //idShow(id);
+    LList* gPrev    =   new LList(ONE, i, id->m[0]);
+    LList* reducers =   new LList();
+    //idShow(id);
+    //Print("%p\n",id->m[0]);
+    //pWrite(id->m[0]);
+    //Print("%p\n",gPrev->getFirst()->getPoly());
+    //pWrite(gPrev->getFirst()->getPoly());
+
+    LTagList* lTag  =   new LTagList(gPrev->getFirst());
+    //lTag->insert(gPrev->getFirst());
+    lTag->setFirstCurrentIdx(gPrev->getFirst());
+    // computing the groebner basis of the elements of index < actual index
+    gbLength    =   gPrev->getLength();
+    //Print("Laenge der bisherigen Groebner Basis: %d\n",gPrev->getLength());
+    ideal gbPrev    =   idInit(gbLength,1);
+    // initializing the groebner basis of elements of index < actual index
+    gbPrev->m[0]    =   gPrev->getFirst()->getPoly();
+    //idShow(gbPrev);
+    //idShow(currRing->qideal);
+    for(i=2; i<=IDELEMS(id); i++) {
+        LNode* gPrevTag =   gPrev->getLast();
+        //Print("Last POlynomial in GPREV: ");
+        //Print("%p\n",gPrevTag);
+        //pWrite(gPrevTag->getPoly());
+        Print("Iteration: %d\n\n",i);
+        gPrev   =   F5inc(i, id->m[i-1], gPrev, reducers, gbPrev, ONE, lTag, rules, rTag, plus, termination);
+        //Print("%d\n",gPrev->count(gPrevTag->getNext()));
+        //Print("%d\n",gPrev->getLength());
+        //Print("____________________________________ITERATION STEP DONE________________________________________\n");
+
+        // DEBUGGING STUFF
+        LNode* temp    =   gPrev->getFirst();
+
+
+        /////////////////////////////////////////////////////////////////////////////////
+        //                                                                             //
+        // one needs to choose one of the following 3 implementations of the algorithm //
+        // F5,F5R or F5C                                                               //
+        //                                                                             //
+        /////////////////////////////////////////////////////////////////////////////////
+
+
+        //
+        // standard "F5"
+        //
+        if(0 == opt) {
+          if(gPrev->getLength() > gbLength) {
+            if(i < IDELEMS(id)) {
+                ideal gbAdd =   idInit(gPrev->getLength()-gbLength,1);
+                LNode*  temp =   gPrevTag;
+                int counter =   0;
+                for(j=0;j<=gPrev->getLength()-gbLength-1;j++) {
+                    temp        =   temp->getNext();
+                    if(0 == temp->getDel()) {
+                        counter++;
+                        gbAdd->m[j] =   temp->getPoly();
+                    }
+                }
+                    gbPrev          =   idAdd(gbPrev,gbAdd);
+            }
+            else {
+                ideal gbAdd =   idInit(gPrev->getLength()-gbLength,1);
+                LNode*  temp =   gPrevTag;
+                for(j=0;j<=gPrev->getLength()-gbLength-1;j++) {
+                    temp        =   temp->getNext();
+                    gbAdd->m[j] =   temp->getPoly();
+                }
+                gbPrev          =   idAdd(gbPrev,gbAdd);
+            }
+            //if(i == IDELEMS(id)) {
+            //    ideal tempId        =   kInterRed(gbPrev);
+            //    gbPrev              =   tempId;
+            //}
+        }
+        gbLength    =   gPrev->getLength();
+        }
+
+
+        //
+        //  "F5R"
+        //
+        if(1 == opt) {
+        if(gPrev->getLength() > gbLength) {
+            if(i < IDELEMS(id)) {
+                ideal gbAdd =   idInit(gPrev->getLength()-gbLength,1);
+                LNode*  temp =   gPrevTag;
+                int counter =   0;
+                for(j=0;j<=gPrev->getLength()-gbLength-1;j++) {
+                    temp        =   temp->getNext();
+                    if(0 == temp->getDel()) {
+                        counter++;
+                        gbAdd->m[j] =   temp->getPoly();
+                    }
+                }
+                    gbPrev          =   idAdd(gbPrev,gbAdd);
+            }
+            else {
+                ideal gbAdd =   idInit(gPrev->getLength()-gbLength,1);
+                LNode*  temp =   gPrevTag;
+                for(j=0;j<=gPrev->getLength()-gbLength-1;j++) {
+                    temp        =   temp->getNext();
+                    gbAdd->m[j] =   temp->getPoly();
+                }
+                gbPrev          =   idAdd(gbPrev,gbAdd);
+            }
+            // interreduction stuff
+            // comment this out if you want F5 instead of F5R
+            if(i<IDELEMS(id)) {
+                ideal tempId    =   kInterRed(gbPrev);
+                gbPrev          =   tempId;
+            }
+        }
+        gbLength    =   gPrev->getLength();
+        }
+
+
+        //
+        // "F5C"
+        //
+        if(2 == opt) {
+        if(gPrev->getLength() > gbLength) {
+            if(i < IDELEMS(id)) {
+                ideal gbAdd =   idInit(gPrev->getLength()-gbLength,1);
+                LNode*  temp =   gPrevTag;
+                for(j=0;j<=gPrev->getLength()-gbLength-1;j++) {
+                    temp        =   temp->getNext();
+                        gbAdd->m[j] =   temp->getPoly();
+                }
+                    gbPrev          =   idAdd(gbPrev,gbAdd);
+            }
+            else {
+                ideal gbAdd =   idInit(gPrev->getLength()-gbLength,1);
+                LNode*  temp =   gPrevTag;
+                for(j=0;j<=gPrev->getLength()-gbLength-1;j++) {
+                    temp        =   temp->getNext();
+                    gbAdd->m[j] =   temp->getPoly();
+                }
+                gbPrev          =   idAdd(gbPrev,gbAdd);
+            }
+            if(i<IDELEMS(id)) {
+                ideal tempId    =   kInterRed(gbPrev);
+                gbPrev          =   tempId;
+                delete gPrev;
+                delete rules;
+                gPrev    =   new LList(pOne,1,gbPrev->m[0]);
+                gPrev->insert(pOne,1,gbPrev->m[1]);
+                rules    =   new RList();
+                //rTag     =   new RTagList(rules->getFirst());
+                for(k=2; k<IDELEMS(gbPrev); k++) {
+                    gPrev->insert(pOne,k+1,gbPrev->m[k]);
+                    /*
+                    for(l=0; l<k; l++) {
+                    }
+                    rTag->insert(rules->getFirst());
+                    */
+                }
+            }
+            gbLength    =   gPrev->getLength();
+        }
+        }
+
+
+    }
+    timer   =   getTimer();
+    //Print("\n\nADDING TIME IN REDUCTION: %d\n\n",reductionTime);
+    Print("\n\nNumber of zero-reductions:           %d\n",reductionsToZero);
+    Print("Number of rules:                     %d\n",numberOfRules);
+    Print("Number of rejected F5-critical pairs:%d\n",numberRejectedF5CriticalPairs);
+    Print("Number of reductions:                %d\n",numberOfReductions);
+    Print("Elements not added to G:             %d\n",notInG);
+    Print("Highest Degree during computations:  %d\n",highestDegree);
+    Print("Degree d_0 in F5+:                   %d\n",highestDegreeGBCriticalPair);
+    Print("Time for computations:               %d/1000 seconds\n",timer);
+    Print("Number of elements in gb:            %d\n",IDELEMS(gbPrev));
+    //LNode* temp    =   gPrev->getFirst();
+    //while(NULL != temp) {
+    //    pWrite(temp->getPoly());
+    //    temp    =   temp->getNext();
+    // }
+    //gPrev->print();
+    //delete lTag;
+    delete rTag;
+    delete gPrev;
+    notInG                        =   0;
+    numberOfRules                 =   0;
+    reductionsToZero              =   0;
+    highestDegree                 =   0;
+    highestDegreeGBCriticalPair   =   0;
+    reductionTime                 =   0;
+    spolsTime                     =   0;
+    numberUselessPairs            =   0;
+    numberUsefulPairs             =   0;
+    numberRejectedF5CriticalPairs =   0;
+    numberOfReductions            =   0;
+    numberOfSpolys                =   0;
+    return(gbPrev);
+
+
+}
+
+#endif
diff --git a/kernel/GBEngine/f5gb.h b/kernel/GBEngine/f5gb.h
new file mode 100644
index 0000000..d032999
--- /dev/null
+++ b/kernel/GBEngine/f5gb.h
@@ -0,0 +1,177 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: f5gb interface
+*/
+#ifndef F5_HEADER
+#define F5_HEADER
+
+#ifdef HAVE_F5
+#include <kernel/GBEngine/f5data.h>
+#include <kernel/GBEngine/f5lists.h>
+
+
+/*
+======================================================
+sort polynomials in ideal i by decreasing total degree
+======================================================
+*/
+void qsortDegree(poly* left, poly* right);
+
+/*!
+ * ======================================================================
+ * builds the sum of the entries of the exponent vectors, i.e. the degree
+ * of the corresponding monomial
+ * ======================================================================
+*/
+long sumVector(int* v, int k);
+
+/**
+==========================================================================
+compare monomials, i.e. divisibility tests for criterion 1 and criterion 2
+==========================================================================
+*/
+bool compareMonomials(int* m1, int** m2, int numberOfRuleOlds);
+
+
+/*
+==================================================
+computes incrementally gbs of subsets of the input
+gb{f_m} -> gb{f_m,f_(m-1)} -> gb{f_m,...,f_1}
+==================================================
+*/
+LList* F5inc(int i, poly f_i, LList* gPrev,LList* reducers, ideal gbPrev, poly ONE, LTagList* lTag, RList* rules, RTagList* rTag, int plus ,int termination);
+
+/*
+================================================================
+computes a list of critical pairs for the next reduction process
+the first element is always "useful" thus the critical pair
+computed is either "useful" or "useless" depending on the second
+element which generates the critical pair.
+first element in gPrev is always the newest element which must
+build critical pairs with all other elements in gPrev
+================================================================
+*/
+void criticalPair(LList* gPrev, CListOld* critPairs, LTagList* lTag, RTagList* rTag, RList* RuleOlds, PList* rejectedGBList, int plus);
+
+
+bool checkDGB(LList* gPrev);
+
+
+/*
+ * Arris Check if we are finished after the current degree step:
+ * Checks all remaining critical pairs, i.e. those of higher degree,
+ * by the two Buchberger criteria.
+ * return value: 0, if all remaining critical pairs are deleted by
+ *                  Buchberger's criteria
+ *               1, otherwise
+ */
+bool arrisCheck(CNode* first,LNode* firstGCurr, long arrisdeg);
+
+/*
+================================================================
+computes a list of critical pairs for the next reduction process
+the first element is always "useless" thus the critical pair
+computed is "useless".
+first element in gPrev is always the newest element which must
+build critical pairs with all other elements in gPrev
+================================================================
+*/
+void criticalPair2(LList* gPrev, CListOld* critPairs, LTagList* lTag, RTagList* rTag, RList* RuleOlds, PList* rejectedGBList);
+
+/*
+========================================
+Criterion 1, i.e. Faugere's F5 Criterion
+========================================
+*/
+inline bool criterion1(LList* gPrev, poly t, LNode* l, LTagList* lTag);
+
+/*
+=====================================
+Criterion 2, i.e. Rewritten Criterion
+=====================================
+*/
+inline bool criterion2(int idx, poly t, LNode* l, RList* RuleOlds, RTagList* rTag);
+
+/*
+==========================================================================================================
+Criterion 2, i.e. Rewritten Criterion, for its second call in sPols(), with added lastRuleOldTested parameter
+==========================================================================================================
+*/
+inline bool criterion2(poly t, LPolyOld* l, RList* RuleOlds, RuleOld* testedRuleOld);
+
+/*
+ * check for useful pairs in the given subset of critical pairs
+ */
+int computeUsefulMinDeg(CNode* first);
+
+/*
+==================================
+Computation of S-Polynomials in F5
+==================================
+*/
+inline void computeSPols(CNode* first, RTagList* rTag, RList* RuleOlds, LList* sPolyList, PList* rejectedGBList);
+
+/*
+========================================================================
+reduction including subalgorithm topReduction() using Faugere's criteria
+========================================================================
+*/
+inline void reduction(LList* sPolyList, CListOld* critPairs, LList* gPrev, RList* RuleOlds, LTagList* lTag, RTagList* rTag,
+                 ideal gbPrev, PList* rejectedGBList, int plus);
+
+/*
+========================================================================
+reduction including subalgorithm topReduction() using Faugere's criteria
+========================================================================
+*/
+inline void newReduction(LList* sPolyList, CListOld* critPairs, LList* gPrev, LList* reducers, RList* rules, LTagList* lTag, RTagList* rTag, ideal gbPrev, int termination, PList* rejectedGBList, int plus);
+
+/*!
+ * ================================================================================
+ * searches for reducers of temp similar to the symbolic preprocessing of F4  and
+ * divides them into a "good" and "bad" part:
+ *
+ * the "good" ones are the reducers which do not corrupt the label of temp, with
+ * these the normal form of temp is computed
+ *
+ * the "bad" ones are the reducers which corrupt the label of temp, they are tested
+ * later on for possible new RuleOlds and S-polynomials to be added to the algorithm
+ * ================================================================================
+ */
+void findReducers(LNode* l, LList* sPolyList, ideal gbPrev, LList* gPrev, LList* reducers, CListOld* critPairs, RList* rules, LTagList* lTag, RTagList* rTag, int termination, PList* rejectedGBList, int plus);
+
+/*
+=====================================================================================
+top reduction in F5, i.e. reduction of a given S-polynomial by labeled polynomials of
+the same index whereas the labels are taken into account
+=====================================================================================
+*/
+inline void topReduction(LNode* l, LList* sPolyList, LList* gPrev, CListOld* critPairs, RList* RuleOlds, LTagList* lTag, RTagList* rTag, ideal gbPrev, PList* rejectedGBList, int plus);
+
+/*
+=======================================================================================
+merging 2 polynomials p & q without requiring that all monomials of p & q are different
+if there are equal monomials in p & q only one of these monomials (always that of p!)
+is taken into account
+=======================================================================================
+
+poly p_MergeEq_q(poly p, poly q, const ring r);
+*/
+/*
+=====================================================================
+subalgorithm to find a possible reductor for the labeled polynomial l
+=====================================================================
+*/
+inline LNode* findReductor(LNode* l, LList* sPolyList, LNode* gPrevRedCheck, LList* gPrev, RList* RuleOlds, LTagList* lTag,RTagList* rTag);
+
+/*
+======================================
+main function of our F5 implementation
+======================================
+*/
+ideal F5main(ideal i, ring r, int opt, int plus, int termination);
+
+#endif
+#endif
diff --git a/kernel/GBEngine/f5lists.cc b/kernel/GBEngine/f5lists.cc
new file mode 100644
index 0000000..52e7cf6
--- /dev/null
+++ b/kernel/GBEngine/f5lists.cc
@@ -0,0 +1,1240 @@
+
+
+
+#include <kernel/mod2.h>
+
+#ifdef HAVE_F5
+#include <kernel/GBEngine/kutil.h>
+#include <kernel/structs.h>
+#include <omalloc/omalloc.h>
+#include <kernel/polys.h>
+#include <polys/monomials/p_polys.h>
+#include <kernel/ideals.h>
+#include <kernel/GBEngine/kstd1.h>
+#include <kernel/GBEngine/khstd.h>
+#include <polys/kbuckets.h>
+#include <polys/weight.h>
+#include <misc/intvec.h>
+#include <kernel/polys.h>
+#include <kernel/GBEngine/f5gb.h>
+#include <kernel/GBEngine/f5data.h>
+#include <kernel/GBEngine/f5lists.h>
+
+/**
+ * functions working on the class PNode
+ */
+PNode::PNode(poly p, PNode* n) {
+  data  = p;
+  next  = n;
+}
+
+poly PNode::getPoly() {
+  return this->data;
+}
+
+PNode* PNode::getNext() {
+  return this->next;
+}
+PNode* PNode::insert(poly p) {
+  poly q = pOne();
+  q = pCopy(p);
+  PNode* temp = this;
+  if(NULL == temp) {
+    PNode* pn = new PNode(q,temp);
+    return pn;
+  }
+  if(1 == pLmCmp(q,temp->getPoly())) {
+    PNode* pn = new PNode(q,temp);
+    return pn;
+  }
+  if(0 == pLmCmp(q,temp->getPoly())) {
+    return this;
+  }
+  if(-1 == pLmCmp(q,temp->getPoly())) {
+    while(NULL != temp->getNext() && -1 == pLmCmp(q,temp->getNext()->getPoly())) {
+      temp = temp->getNext();
+    }
+    if(NULL == temp->getNext() || 1 == pLmCmp(q,temp->getNext()->getPoly())) {
+      PNode* pn = new PNode(q,temp->getNext());
+      temp->next = pn;
+      return this;
+    }
+    if(0 == pLmCmp(q,temp->getNext()->getPoly())) {
+      return this;
+    }
+  }
+}
+/*
+PNode* PNode::insert(poly p) {
+  PNode* pn = new PNode(p,this);
+  return pn;
+}
+*/
+/**
+ * functions working on the class PList
+ */
+PList::PList() {
+  first = NULL;
+}
+
+
+void PList::insert(poly p) {
+  first = first->insert(p);
+}
+
+
+/*
+PNode* PList::insert(poly p) {
+  PNode* temp = first;
+  PNode* pn   = new PNode(p,temp);
+  first       = pn;
+  return first;
+}
+*/
+bool PList::check(poly p) {
+  PNode* temp = first;
+  //Print("\nCHECK: \n");
+  //pWrite(p);
+  //Print("-----\n");
+  while(NULL != temp) {
+    //pWrite(temp->getPoly());
+    //pWrite(p);
+    //Print("COMAPRE: %d\n",pLmEqual(p,temp->getPoly()));
+    if(1 == pLmEqual(p,temp->getPoly())) {
+      //Print("YES!\n");
+      //pWrite(pHead(temp->getPoly()));
+      //Print("YES!\n");
+      return 1;
+    }
+    temp = temp->getNext();
+  }
+  //Print("NOTHING!\n");
+  return 0;
+}
+
+void PList::print() {
+  Print("-----LIST-----\n");
+  PNode* temp = first;
+  while(NULL != temp) {
+    pWrite(temp->getPoly());
+    temp = temp->getNext();
+  }
+}
+/*
+====================================
+functions working on the class LNode
+====================================
+*/
+
+// generating new list elements (labeled / classical polynomial / LNode view)
+LNode::LNode() {
+    data                =   NULL;
+    next                =   NULL;
+}
+LNode::LNode(LPolyOld* lp) {
+    data                =   lp;
+    next                =   NULL;
+}
+
+LNode::LNode(LPolyOld* lp, LNode* l) {
+//Print("HIER LNODE\n");
+    data                =   lp;
+    next                =   l;
+}
+
+LNode::LNode(poly t, int i, poly p, RuleOld* r) {
+LPolyOld* lp           =   new LPolyOld(t,i,p,r);
+data                =   lp;
+next                =   NULL;
+}
+
+LNode::LNode(poly t, int i, poly p, RuleOld* r, LNode* l) {
+    LPolyOld* lp           =   new LPolyOld(t,i,p,r);
+    data                =   lp;
+    next                =   l;
+}
+
+LNode::LNode(LNode* ln) {
+    data                =   ln->getLPolyOld();
+    next                =   ln->getNext();
+}
+
+LNode::~LNode() {
+    //delete next;
+    //Print("DELETE LNODE\n");
+    delete data;
+}
+
+void LNode::deleteAll() {
+    while(NULL != next) {
+        //Print("%p\n",next);
+        //pWrite(next->data->getPoly());
+        next->deleteAll();
+    }
+    delete data;
+}
+
+// insert new elements to the list always at the end (labeled / classical polynomial view)
+// needed for list gPrev
+inline LNode* LNode::insert(LPolyOld* lp) {
+    //Print("LAST GPREV: ");
+    //pWrite(this->getPoly());
+    if(NULL == this) {
+        LNode* newElement   =   new LNode(lp,this);
+        return newElement;
+    }
+    else {
+        LNode* newElement   =   new LNode(lp, NULL);
+        this->next          =   newElement;
+        return newElement;
+    }
+}
+
+inline LNode* LNode::insert(poly t, int i, poly p, RuleOld* r) {
+    if(NULL == this) {
+        LNode* newElement   =   new LNode(t,i,p,r,this);
+        return newElement;
+    }
+    else {
+        LNode* newElement   =   new LNode(t, i, p, r, NULL);
+        this->next          =   newElement;
+        return newElement;
+    }
+}
+
+// insert new elements to the list always in front (labeled / classical polynomial view)
+// needed for sPolyList
+inline LNode* LNode::insertSP(LPolyOld* lp) {
+    LNode* newElement   =   new LNode(lp, this);
+    //Print("INSERTED IN SPOLYLIST: ");
+    //pWrite(lp->getTerm());
+    return newElement;
+}
+
+inline LNode* LNode::insertSP(poly t, int i, poly p, RuleOld* r) {
+    LNode* newElement   =   new LNode(t, i, p, r, this);
+     //Print("INSERTED IN SPOLYLIST: ");
+  //pWrite(t);
+return newElement;
+}
+// insert new elemets to the list w.r.t. increasing labels
+// only used for the S-polys to be reduced (TopReduction building new S-polys with higher label)
+inline LNode* LNode::insertByLabel(poly t, int i, poly p, RuleOld* r) {
+    //Print("ADDING SOLYS TO THE LIST\n");
+    //Print("new element: ");
+    //pWrite(t);
+       if(NULL == this) { // || NULL == data) {
+        LNode* newElement   =   new LNode(t, i, p, r, this);
+        return newElement;
+    }
+    else {
+         //Print("tested element1: ");
+    //pWrite(this->getTerm());
+        if(-1 == pLmCmp(t,this->getTerm())) {
+            //Print("HIERDRIN\n");
+            LNode* newElement   =   new LNode(t, i, p, r, this);
+            //Print("%p\n",this);
+            //Print("%p\n",newElement->next);
+            return newElement;
+        }
+        else {
+            LNode* temp = this;
+            while(NULL != temp->next && NULL != temp->next->data) {
+                //Print("tested element: ");
+                //pWrite(temp->getTerm());
+ if(-1 == pLmCmp(t,temp->next->getTerm())) {
+                    LNode* newElement   =   new LNode(t, i, p, r, temp->next);
+                    temp->next          =   newElement;
+                    return this;
+                }
+                else {
+                    temp = temp->next;
+                    //Print("%p\n",temp);
+                    //Print("%p\n",temp->data);
+
+                    //Print("%p\n",temp->next);
+                }
+            }
+        //Print("HIER\n");
+            LNode* newElement   =   new LNode(t, i, p, r, temp->next);
+            temp->next          =   newElement;
+            return this;
+        }
+    }
+}
+
+inline LNode* LNode::insertFirst(LNode* l) {
+    l->next =   this;
+    return l;
+}
+
+inline LNode* LNode::insertByLabel(LNode* l) {
+    //Print("ADDING SOLYS TO THE LIST\n");
+    //Print("new element: ");
+    //pWrite(t);
+       if(NULL == this) { // || NULL == data) {
+        l->next =   this;
+        return l;
+    }
+    else {
+         //Print("tested element1: ");
+    //pWrite(this->getTerm());
+        if(-1 == pLmCmp(l->getTerm(),this->getTerm())) {
+            //Print("HIERDRIN\n");
+            l->next =   this;
+            //Print("%p\n",this);
+            //Print("%p\n",newElement->next);
+            return l;
+        }
+        else {
+            LNode* temp = this;
+            while(NULL != temp->next && NULL != temp->next->data) {
+                //Print("tested element: ");
+                //pWrite(temp->getTerm());
+                if(-1 == pLmCmp(l->getTerm(),temp->next->getTerm())) {
+                    l->next     =   temp->next;
+                    temp->next  =   l;
+                    return this;
+                }
+                else {
+                    temp = temp->next;
+                    //Print("%p\n",temp);
+                    //Print("%p\n",temp->data);
+
+                    //Print("%p\n",temp->next);
+                }
+            }
+        //Print("HIER\n");
+            l->next     =   temp->next;
+            temp->next  =   l;
+            return this;
+        }
+    }
+}
+
+// deletes the first elements of the list with the same degree
+// only used for the S-polys, which are already sorted by increasing degree by CListOld
+LNode*  LNode::deleteByDeg() {
+    return this;
+}
+
+// get next from current LNode
+LNode* LNode::getNext() {
+    return next;
+}
+
+// get the LPolyOld* out of LNode*
+LPolyOld* LNode::getLPolyOld() {
+    return data;
+}
+
+// get the data from the LPolyOld saved in LNode
+poly LNode::getPoly() {
+    return data->getPoly();
+}
+
+poly LNode::getTerm() {
+    return data->getTerm();
+}
+
+int LNode::getIndex() {
+    return data->getIndex();
+}
+
+RuleOld* LNode::getRuleOld() {
+    return data->getRuleOld();
+}
+
+void LNode::setRuleOld(RuleOld* r) {
+    return data->setRuleOld(r);
+}
+
+bool LNode::getDel() {
+    return data->getDel();
+}
+
+// set the data from the LPolyOld saved in LNode
+void LNode::setPoly(poly p) {
+    data->setPoly(p);
+}
+
+void LNode::setTerm(poly t) {
+    data->setTerm(t);
+}
+
+void LNode::setIndex(int i) {
+    data->setIndex(i);
+}
+
+void LNode::setNext(LNode* l) {
+    next    =   l;
+}
+
+void LNode::setDel(bool d) {
+    data->setDel(d);
+}
+
+// test if for any list element the polynomial part of the data is equal to *p
+bool LNode::polyTest(poly* p) {
+    LNode* temp = new LNode(this);
+    while(NULL != temp) {
+        if(pComparePolys(temp->getPoly(),*p)) {
+            return 1;
+        }
+        temp = temp->next;
+    }
+    return 0;
+}
+
+LNode* LNode::getNext(LNode* l) {
+    return l->next;
+}
+
+// for debugging
+void LNode::print() {
+    LNode* temp = this;
+    Print("___________________List of S-polynomials______________________:\n");
+    while(NULL != temp && NULL != temp->data) {
+        Print("Index: %d\n",temp->getIndex());
+        Print("Term: ");
+        pWrite(temp->getTerm());
+        Print("Poly: ");
+        pWrite(temp->getPoly());
+        temp = temp->next;
+    }
+    Print("_______________________________________________________________\n");
+}
+
+int LNode::count(LNode* l) {
+    int nonDel  =   0;
+    LNode* temp =   l;
+    while(NULL != temp) {
+        if(!temp->getDel()) {
+            nonDel++;
+            temp    =   temp->next;
+        }
+        else {
+            temp    =   temp->next;
+        }
+    }
+    return nonDel;
+}
+
+/*
+====================================
+functions working on the class LList
+====================================
+*/
+
+LList::LList() {
+    first   =   last    =   NULL;;
+    length  =   0;
+}
+
+LList::LList(LPolyOld* lp) {
+    first   =   new LNode(lp);
+    last    =   first;
+    length  =   1;
+}
+
+LList::LList(poly t,int i,poly p,RuleOld* r) {
+    first   =   new LNode(t,i,p,r);
+    last    =   first;
+    length  =   1;
+}
+
+LList::~LList() {
+    LNode* temp;
+    while(first) {
+        temp    =   first;
+        first   =   first->getNext();
+        delete  temp;
+        //Print("%p\n",first);
+    }
+}
+
+// insertion at the end of the list, needed for gPrev
+void LList::insert(LPolyOld* lp) {
+    last = last->insert(lp);
+    if(NULL == first) {
+        first   =   last;
+    }
+    //Print("NEW LAST GPREV: ");
+    //pWrite(last->getPoly());
+    //Print("%p\n",first);
+    //pWrite(first->getPoly());
+    length++;
+    //Print("LENGTH %d\n",length);
+}
+
+void LList::insert(poly t,int i, poly p, RuleOld* r) {
+    last = last->insert(t,i,p,r);
+    if(NULL == first) {
+        first   =   last;
+    }
+    length++;
+    //Print("LENGTH %d\n",length);
+}
+
+// insertion in front of the list, needed for sPolyList
+void LList::insertSP(LPolyOld* lp) {
+    first = first->insertSP(lp);
+    length++;
+    //Print("LENGTH %d\n",length);
+}
+
+void LList::insertSP(poly t,int i, poly p, RuleOld* r) {
+    first = first->insertSP(t,i,p,r);
+    length++;
+    //Print("LENGTH %d\n",length);
+}
+
+
+void LList::insertByLabel(poly t, int i, poly p, RuleOld* r) {
+    first = first->insertByLabel(t,i,p,r);
+    length++;
+    //Print("LENGTH %d\n",length);
+}
+
+void LList::insertFirst(LNode* l) {
+    first = first->insertFirst(l);
+    length++;
+    //Print("LENGTH %d\n",length);
+}
+
+void LList::insertByLabel(LNode* l) {
+    first = first->insertByLabel(l);
+    length++;
+    //Print("LENGTH %d\n",length);
+}
+
+void LList::deleteByDeg() {
+    first = first->deleteByDeg();
+}
+
+bool LList::polyTest(poly* p) {
+    return first->polyTest(p);
+}
+
+LNode* LList::getFirst() {
+    return first;
+}
+
+LNode* LList::getLast() {
+    return last;
+}
+
+int LList::getLength() {
+    return length;
+}
+
+void LList::setFirst(LNode* l) {
+    LNode* temp =   first;
+    temp->setNext(NULL);
+    first       =   l;
+    length--;
+}
+
+void LList::print() {
+    first->print();
+}
+
+int LList::count(LNode* l) {
+    return first->count(l);
+}
+/*
+=======================================
+functions working on the class LTagNode
+=======================================
+*/
+LTagNode::LTagNode() {
+    data    =   NULL;
+    next    =   NULL;
+}
+
+LTagNode::LTagNode(LNode* l) {
+    data = l;
+    next = NULL;
+}
+
+LTagNode::LTagNode(LNode* l, LTagNode* n) {
+    data = l;
+    next = n;
+}
+
+ LTagNode::~LTagNode() {
+    delete data;
+}
+
+// declaration with first as parameter due to sorting of LTagList
+LTagNode* LTagNode::insert(LNode* l) {
+    LTagNode* newElement  = new LTagNode(l, this);
+    return newElement;
+}
+
+LNode* LTagNode::getLNode() {
+    return this->data;
+}
+
+LTagNode* LTagNode::getNext() {
+    return next;
+}
+
+// NOTE: We insert at the beginning of the list and length = i-1, where i is the actual index.
+//       Thus given actual index i and idx being the index of the LPolyOld under investigation
+//       the element on position length-idx is the right one
+LNode* LTagNode::get(int idx, int length) {
+    if(idx == 1) {
+        return NULL;
+    }
+    else {
+        int j;
+        LTagNode* temp = this; // last
+        for(j=1;j<=length-idx+1;j++) {
+            temp = temp->next;
+        }
+        return temp->data;
+    }
+}
+
+
+/*
+=======================================
+functions working on the class LTagList
+=======================================
+*/
+LTagList::LTagList() {
+    LTagNode* first =   new LTagNode();
+
+    length          =   0;
+}
+
+LTagList::LTagList(LNode* l) {
+    LTagNode* first =   new LTagNode(l);
+    length          =   1;
+}
+
+LTagList::~LTagList() {
+    LTagNode* temp;
+    while(first) {
+        temp    =   first;
+        first   =   first->getNext();
+        delete  temp;
+        //Print("%p\n",first);
+    }
+}
+
+// declaration with first as parameter in LTagNode due to sorting of LTagList
+void LTagList::insert(LNode* l) {
+    first   =   first->insert(l);
+    length++;
+}
+
+void LTagList::setFirstCurrentIdx(LNode* l) {
+    firstCurrentIdx =   l;
+}
+
+LNode* LTagList::get(int idx) {
+    return first->get(idx, length);
+}
+
+LNode* LTagList::getFirst() {
+    return first->getLNode();
+}
+
+LNode* LTagList::getFirstCurrentIdx() {
+    return firstCurrentIdx;
+}
+
+/*
+=====================================
+functions working on the class TopRed
+=====================================
+*/
+
+TopRed::TopRed() {
+    _completed  =   NULL;
+    _toDo       =   NULL;
+}
+
+TopRed::TopRed(LList* c, LList* t) {
+    _completed  =   c;
+    _toDo       =   t;
+}
+
+LList* TopRed::getCompleted() {
+    return _completed;
+}
+
+LList* TopRed::getToDo() {
+    return _toDo;
+}
+
+/*
+====================================
+functions working on the class CNode
+====================================
+*/
+
+CNode::CNode() {
+    data    =   NULL;
+    next    =   NULL;
+}
+
+CNode::CNode(CPairOld* c) {
+    data    =   c;
+    next    =   NULL;
+}
+
+CNode::CNode(CPairOld* c, CNode* n) {
+    data    =   c;
+    next    =   n;
+}
+
+CNode::~CNode() {
+    delete data;
+}
+
+// insert sorts the critical pairs firstly by increasing total degree, secondly by increasing label
+// note: as all critical pairs have the same index here, the second sort is done on the terms of the labels
+// working only with linked, but not doubly linked lists due to memory usage we have to check the
+// insertion around the first element separately from the insertion around all other elements in the list
+CNode* CNode::insert(CPairOld* c) {
+    if(NULL == this) {
+        CNode* newElement   =   new CNode(c, this);
+        return newElement;
+    }
+    else {
+        poly u1 = ppMult_qq(c->getT1(),c->getLp1Term());
+        if( c->getDeg() < this->data->getDeg() ) { // lower degree than the first list element
+            CNode* newElement   =   new CNode(c, this);
+            return newElement;
+        }
+        if( c->getDeg() == this->data->getDeg() ) { // same degree than the first list element
+            if(1 != pLmCmp(u1,ppMult_qq(this->data->getT1(), this->data->getLp1Term()))) {
+                //pWrite(u1);
+                //Print("Multi-Term in CritPairs Sortierung altes Element: ");
+                //pWrite(ppMult_qq(this->data->getT1(),this->data->getLp1Term()));
+                CNode* newElement   =   new CNode(c, this);
+                return newElement;
+            }
+            else {
+                //Print("Insert Deg\n");
+                CNode* temp = this;
+                while(  NULL != temp->next) {
+                    if(temp->next->data->getDeg() == c->getDeg() ) {
+                        if(1 == pLmCmp(u1,ppMult_qq(temp->next->data->getT1(),temp->next->data->getLp1Term()))) {
+                            temp = temp->next;
+                        }
+                        else {
+                            CNode* newElement   =   new CNode(c, temp->next);
+                            temp->next          =   newElement;
+                            return this;
+                        }
+                    }
+                    else {
+                        CNode* newElement   =   new CNode(c, temp->next);
+                        temp->next          =   newElement;
+                        return this;
+                    }
+                }
+                CNode* newElement   =   new CNode(c, NULL);
+                temp->next          =   newElement;
+                return this;
+            }
+        } // outer if-clause
+        if( c->getDeg() > this->data->getDeg() ) { // greater degree than the first list element
+            CNode* temp =   this;
+            while( NULL != temp->next ) {
+                if( c->getDeg() < temp->next->data->getDeg() ) {
+                    CNode* newElement   =   new CNode(c, temp->next);
+                    temp->next          =   newElement;
+                    return this;
+                }
+                if( c->getDeg() == temp->next->data->getDeg() ) {
+                    if(1 != pLmCmp(u1,ppMult_qq(temp->next->data->getT1(),temp->next->data->getLp1Term()))) {
+                        CNode* newElement   =   new CNode(c, temp->next);
+                        temp->next          =   newElement;
+                        return this;
+                    }
+                    else {
+                        temp = temp->next;
+                        while(  NULL != temp->next ) {
+                            if( temp->next->data->getDeg() == c->getDeg() ) {
+                                if(1 == pLmCmp(u1,ppMult_qq(temp->next->data->getT1(),
+                                               temp->next->data->getLp1Term()))) {
+                                    temp = temp->next;
+                                }
+                                else {
+                                    CNode* newElement   =   new CNode(c, temp->next);
+                                    temp->next          =   newElement;
+                                    return this;
+                                }
+                            }
+                            else {
+                                CNode* newElement   =   new CNode(c, temp->next);
+                                temp->next          =   newElement;
+                                return this;
+                            }
+                        }
+                        CNode* newElement   =   new CNode(c, NULL);
+                        temp->next          =   newElement;
+                        return this;
+                    }
+                }
+                if( c->getDeg() > temp->next->data->getDeg() ) {
+                    temp    =   temp->next;
+                }
+            }
+            CNode* newElement   =   new CNode(c, NULL);
+            temp->next          =   newElement;
+            return this;
+        }
+    }
+}
+
+
+CNode* CNode::insertWithoutSort(CPairOld* cp) {
+    CNode* newElement = new CNode(cp);
+    newElement->next  = this;
+    return newElement;
+}
+
+
+// get the first elements from CListOld which by the above sorting have minimal degree
+CNode* CNode::getMinDeg() {
+    CNode* temp = this;
+    while(NULL != temp) {
+        while(NULL != temp->next && temp->next->data->getDeg() == this->data->getDeg()) {
+            temp = temp->next;
+        }
+        CNode* returnCNode  =   temp->next;
+        // every CListOld should end with a (NULL,NULL) element for a similar behaviour
+        // using termination conditions throughout the algorithm
+        temp->next          =   NULL;
+        return returnCNode;
+    }
+    return NULL;
+}
+
+CPairOld* CNode::getData() {
+    return data;
+}
+
+CNode* CNode::getNext() {
+    return next;
+}
+
+LPolyOld* CNode::getAdLp1() {
+    return this->data->getAdLp1();
+}
+
+LPolyOld* CNode::getAdLp2() {
+    return this->data->getAdLp2();
+}
+
+poly CNode::getLp1Poly() {
+    return this->data->getLp1Poly();
+}
+
+poly CNode::getLp2Poly() {
+    return this->data->getLp2Poly();
+}
+
+poly CNode::getLp1Term() {
+    return this->data->getLp1Term();
+}
+
+poly CNode::getLp2Term() {
+    return this->data->getLp2Term();
+}
+
+int CNode::getLp1Index() {
+    return this->data->getLp1Index();
+}
+
+int CNode::getLp2Index() {
+    return this->data->getLp2Index();
+}
+
+poly CNode::getT1() {
+    return this->data->getT1();
+}
+
+poly* CNode::getAdT1() {
+    return this->data->getAdT1();
+}
+
+poly CNode::getT2() {
+    return this->data->getT2();
+}
+
+poly* CNode::getAdT2() {
+    return this->data->getAdT2();
+}
+
+bool CNode::getDel() {
+  return data->getDel();
+}
+
+RuleOld* CNode::getTestedRuleOld() {
+    return this->data->getTestedRuleOld();
+}
+
+// for debugging
+void CNode::print() {
+    CNode* temp = this;
+    Print("___________________List of critical pairs______________________:\n");
+    while(NULL != temp) {
+        pWrite(ppMult_qq(temp->getT1(),temp->getLp1Term()));
+        Print("LP1 Index: %d\n",temp->getLp1Index());
+        Print("T1: ");
+        pWrite(temp->getT1());
+        Print("%p\n",temp->getT1());
+        Print("LP1 Term: ");
+        pWrite(temp->getLp1Term());
+        Print("LP1 Poly: ");
+        pWrite(temp->getLp1Poly());
+        Print("LP2 Index: %d\n",temp->getLp2Index());
+        Print("T2: ");
+        pWrite(temp->getT2());
+        Print("%p\n",temp->getT2());
+        Print("LP2 Term: ");
+        pWrite(temp->getLp2Term());
+        Print("LP2 Poly: ");
+        pWrite(temp->getLp2Poly());
+        Print("\n");
+        temp = temp->next;
+    }
+}
+
+/*
+====================================
+functions working on the class CListOld
+====================================
+*/
+// for initialization of CListOlds, last element alwas has data=NULL and next=NULL
+CListOld::CListOld() {
+    first   =   NULL;
+}
+
+CListOld::CListOld(CPairOld* c) {
+    first   =   new CNode(c);
+}
+
+CListOld::~CListOld() {
+    CNode* temp;
+    while(NULL != first) {
+        temp    =   first;
+        first   =   first->getNext();
+        delete  temp;
+    }
+}
+
+// insert sorts the critical pairs firstly by increasing total degree, secondly by increasing label
+// note: as all critical pairs have the same index here, the second sort is done on the terms of the labels
+void CListOld::insert(CPairOld* c) {
+    first = first->insert(c);
+}
+
+void CListOld::insertWithoutSort(CPairOld* c) {
+    first = first->insertWithoutSort(c);
+}
+
+CNode* CListOld::getFirst() {
+    return first;
+}
+
+// get the first elements from CListOld which by the above sorting have minimal degree
+// returns the pointer on the first element of those
+CNode* CListOld::getMinDeg() {
+    CNode* temp     =   first;
+    first           =   first->getMinDeg();
+    return temp;
+}
+
+void CListOld::print() {
+    first->print();
+}
+
+/*
+====================================
+functions working on the class RNode
+====================================
+*/
+RNode::RNode() {
+    //Print("HIER RNODE CONSTRUCTOR\n");
+    data    =   NULL;
+    next    =   NULL;
+}
+
+RNode::RNode(RuleOld* r) {
+    data    =   r;
+    next    =   NULL;
+}
+
+RNode::~RNode() {
+    //Print("DELETE RuleOld\n");
+    delete  data;
+}
+
+RNode* RNode::insert(RuleOld* r) {
+    RNode* newElement   =   new RNode(r);
+    newElement->next    =   this;
+    return newElement;
+}
+
+RNode* RNode::insert(int i, poly t) {
+    //Print("IN INSERT: ");
+    //pWrite(t);
+    RuleOld*   r           =   new RuleOld(i,t);
+    //Print("ADDRESS OF RuleOld: %p\n",r);
+    RNode* newElement   =   new RNode(r);
+    //Print("ADDRESS OF RNODE: %p\n",newElement);
+    //Print("ADDRESS OF RNODE DATA: %p\n",newElement->getRuleOld());
+    newElement->next    =   this;
+    return newElement;
+}
+
+
+RNode* RNode::insertOrdered(RuleOld* r) {
+    RNode* newElement   =   new RNode(r);
+    RNode* temp         =   this;
+    if(NULL == temp) {
+        newElement->next =   temp;
+        return newElement;
+    }
+    if(1 == pLmCmp(newElement->getRuleOldTerm(),temp->getRuleOldTerm())) {
+        newElement->next =   temp;
+        return newElement;
+    }
+    else {
+        while(NULL != temp && 1 ==  pLmCmp(temp->getRuleOldTerm(),newElement->getRuleOldTerm())) {
+            temp    =   temp->getNext();
+        }
+        newElement->next =   temp;
+        return this;
+    }
+}
+
+
+RNode* RNode::getNext() {
+    return next;
+}
+
+RuleOld* RNode::getRuleOld() {
+    return data;
+}
+
+int RNode::getRuleOldIndex() {
+    return data->getIndex();
+}
+
+poly RNode::getRuleOldTerm() {
+    return data->getTerm();
+}
+
+void RNode::print() {
+    RNode* temp  =   this;
+    while(NULL != temp) {
+        pWrite(temp->getRuleOldTerm());
+        Print("%d\n\n",temp->getRuleOldIndex());
+        temp    =   temp->getNext();
+    }
+}
+
+/*
+====================================
+functions working on the class RList
+====================================
+*/
+RList::RList() {
+    first = NULL;
+}
+
+RList::RList(RuleOld* r) {
+    first = new RNode(r);
+}
+
+RList::~RList() {
+    RNode* temp;
+    //Print("%p\n",first);
+    while(first) {
+        temp    =   first;
+        first   =   first->getNext();
+        //Print("1 %p\n",first);
+        //if(first) {
+            //Print("1' %p\n",first->getRuleOld());
+            //Print("2 %p\n",first->getNext());
+            //Print("3 %p\n",first->getNext()->getRuleOld());
+            //Print("3 %p\n",first->getNext()->getRuleOldTerm());
+        //}
+        delete  temp;
+    }
+    //Print("FERTIG\n");
+}
+
+void RList::insert(int i, poly t) {
+    first = first->insert(i,t);
+}
+
+void RList::insert(RuleOld* r) {
+    first = first->insert(r);
+}
+
+void RList::insertOrdered(RuleOld* r) {
+    first   =   first->insertOrdered(r);
+}
+
+RNode* RList::getFirst() {
+    return first;
+}
+
+RuleOld* RList::getRuleOld() {
+    return this->getRuleOld();
+}
+
+void RList::print() {
+    first->print();
+}
+
+/*
+=======================================
+functions working on the class RTagNode
+=======================================
+*/
+
+RTagNode::RTagNode() {
+    data = NULL;
+    next = NULL;
+}
+
+RTagNode::RTagNode(RNode* r) {
+    data = r;
+    next = NULL;
+}
+
+RTagNode::RTagNode(RNode* r, RTagNode* n) {
+
+    data = r;
+    next = n;
+}
+
+RTagNode::~RTagNode() {
+    delete data;
+}
+
+// declaration with first as parameter due to sorting of RTagList
+RTagNode* RTagNode::insert(RNode* r) {
+    //Print("Hier1\n");
+    RTagNode* newElement  = new RTagNode(r, this);
+    //Print("Hier2\n");
+    return newElement;
+}
+
+RNode* RTagNode::getRNode() {
+    //Print("%p\n", this);
+    //Print("%p\n",this->data);
+    return this->data;
+}
+
+RTagNode* RTagNode::getNext() {
+    return next;
+}
+
+// NOTE: We insert at the beginning of the list and length = i-1, where i is the actual index.
+//       Thus given actual index i and idx being the index of the LPolyOld under investigation
+//       the element on position length-idx+1 is the right one
+RNode* RTagNode::get(int idx, int length) {
+    if(idx==1 || idx==0) {
+        // NOTE: We set this NULL as putting it the last element in the list, i.e. the element having
+        //       RNode* = NULL would cost lots of iterations at each step of F5inc, with increasing
+        //       length of the list this should be prevented
+        return NULL;
+    }
+    else {
+        int j;
+        RTagNode* temp = this;
+    //Print("\n\nHIER IN GET IDX\n");
+    //Print("FOR LOOP: %d\n",length-idx+1);
+    for(j=1; j<=length-idx+1; j++) {
+            temp = temp->next;
+        }
+        return temp->data;
+    }
+}
+
+void RTagNode::set(RNode* r) {
+    this->data  =   r;
+}
+
+
+void RTagNode::print() {
+    RTagNode* temp  =   this;
+    if(NULL != temp && NULL != temp->getRNode()) {
+        Print("1. element: %d,  ",getRNode()->getRuleOld()->getIndex());
+        pWrite(getRNode()->getRuleOld()->getTerm());
+        temp    =   temp->next;
+        int i   =   2;
+        while(NULL != temp->getRNode() && NULL != temp) {
+            Print("%d. element: %d,  ",i,getRNode()->getRuleOld()->getIndex());
+            pWrite(getRNode()->getRuleOld()->getTerm());
+            temp    =   temp->next;
+            i++;
+        }
+    }
+}
+
+/*
+=======================================
+functions working on the class LTagList
+=======================================
+*/
+
+RTagList::RTagList() {
+    RTagNode* first =   new RTagNode();
+    length          =   0;
+}
+
+RTagList::RTagList(RNode* r) {
+    RTagNode* first =   new RTagNode(r);
+    length          =   1;
+}
+
+RTagList::~RTagList() {
+    RTagNode* temp;
+    while(first) {
+        temp    =   first;
+        first   =   first->getNext();
+        delete  temp;
+    }
+}
+
+// declaration with first as parameter in LTagNode due to sorting of LTagList
+void RTagList::insert(RNode* r) {
+    first = first->insert(r);
+    //Print("LENGTH:%d\n",length);
+    length = length +1;
+    //Print("LENGTH:%d\n",length);
+}
+
+RNode* RTagList::getFirst() {
+    return first->getRNode();
+}
+
+RNode* RTagList::get(int idx) {
+    return first->get(idx, length);
+}
+
+void RTagList::setFirst(RNode* r) {
+    first->set(r);
+}
+
+void RTagList::print() {
+    first->print();
+}
+
+int RTagList::getLength() {
+    return length;
+}
+#endif
diff --git a/kernel/GBEngine/f5lists.h b/kernel/GBEngine/f5lists.h
new file mode 100644
index 0000000..393ded2
--- /dev/null
+++ b/kernel/GBEngine/f5lists.h
@@ -0,0 +1,378 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: list interface
+*/
+#include <kernel/GBEngine/f5data.h>
+#ifndef F5LISTS_HEADER
+#define F5LISTS_HEADER
+
+#ifdef HAVE_F5
+/*
+============================
+============================
+classes for lists used in F5
+============================
+============================
+*/
+class PNode;
+class PList;
+class LNode;
+class LList;
+class LTagNode;
+class LTagList;
+class CNode;
+class CListOld;
+class RList;
+class RNode;
+class RTagNode;
+class RTagList;
+
+
+/**
+ * class PNode of nodes of polynomials
+ */
+class PNode {
+  private:
+    poly   data;
+    PNode*  next;
+  public:
+    PNode(poly p, PNode* n);
+    poly getPoly();
+    PNode* getNext();
+    PNode* insert(poly p);
+};
+
+/**
+ * class PList of lists of PNodes
+ */
+class PList {
+  private:
+    PNode* first;
+  public:
+    PList();
+    void insert(poly p);
+    bool check(poly p);
+    void print();
+};
+
+/*
+=======================================
+class LNode (nodes for lists of LPolyOlds)
+=======================================
+*/
+class LNode {
+    private:
+        LPolyOld*  data;
+        LNode*  next;
+    public:
+        // generating new list elements from the labeled / classical polynomial view
+                LNode();
+                LNode(LPolyOld* lp);
+                LNode(LPolyOld* lp, LNode* l);
+                LNode(poly t, int i, poly p, RuleOld* r=NULL);
+                LNode(poly t, int i, poly p, RuleOld* r, LNode* l);
+                LNode(LNode* ln);
+                ~LNode();
+        void    deleteAll();
+        // insert new elements to the list at the end from the labeled / classical polynomial view
+        // needed for gPrev
+        LNode*  insert(LPolyOld* lp);
+        LNode*  insert(poly t, int i, poly p, RuleOld* r);
+        LNode*  insertByDeg(LPolyOld* lp);
+        // insert new elements to the list in front from the labeled / classical polynomial view
+        // needed for sPolyList
+        LNode*  insertSP(LPolyOld* lp);
+        LNode*  insertSP(poly t, int i, poly p, RuleOld* r);
+        // insert new elements to the list with resp. to increasing labels
+        // only used for the S-polys to be reduced (TopReduction building new S-polys with higher label)
+        LNode*  insertByLabel(poly t, int i, poly p, RuleOld* r);
+        LNode*  insertByLabel(LNode* l);
+        LNode*  insertFirst(LNode* l);
+        // deletes the first elements of the list with the same degree
+        // get next & prev from current LNode
+        LNode*  getNext();
+        LNode*  getPrev();
+        // only used for the S-polys, which are already sorted by increasing degree by CListOld
+        LNode*  deleteByDeg();
+        // get the LPolyOld* out of LNode*
+        LPolyOld*  getLPolyOld();
+        // get the data from the LPolyOld saved in LNode
+        poly    getPoly();
+        poly    getTerm();
+        int     getIndex();
+        RuleOld*   getRuleOld();
+        bool    getDel();
+        // set the data from the LPolyOld saved in LNode
+        void    setPoly(poly p);
+        void    setTerm(poly t);
+        void    setIndex(int i);
+        void    setNext(LNode* l);
+        void    setRuleOld(RuleOld* r);
+        void    setDel(bool d);
+        // test if for any list element the polynomial part of the data is equal to *p
+        bool    polyTest(poly* p);
+        LNode*  getNext(LNode* l);
+        void    print();
+        int     count(LNode* l);
+};
+
+
+/*
+============================
+class LList(lists of LPolyOlds)
+============================
+*/
+class LList {
+    private:
+        LNode*  first;
+        LNode*  last;
+        int     length;
+    public:
+                LList();
+                LList(LPolyOld* lp);
+                LList(poly t,int i,poly p, RuleOld* r = NULL);
+                ~LList();
+        // insertion at the end of the list
+        // needed for gPrev
+        void    insert(LPolyOld* lp);
+        void    insert(poly t,int i, poly p, RuleOld* r = NULL);
+        void    insertByDeg(LPolyOld* lp);
+        // insertion in front of the list
+        // needed for sPolyList
+        void    insertSP(LPolyOld* lp);
+        void    insertSP(poly t,int i, poly p, RuleOld* r = NULL);
+        void    insertByLabel(poly t, int i, poly p, RuleOld* r = NULL);
+        void    insertByLabel(LNode* l);
+        void    insertFirst(LNode* l);
+        void    deleteByDeg();
+        bool    polyTest(poly* p);
+        LNode*  getFirst();
+        LNode*  getLast();
+        int     getLength();
+        void    setFirst(LNode* l);
+        void    print();
+        int     count(LNode* l);
+};
+
+
+
+/*
+==============================================
+class LtagNode (nodes for lists of LPolyOld tags)
+==============================================
+*/
+class LTagNode {
+    private:
+        LNode*      data;
+        LTagNode*   next;
+    public:
+        LTagNode();
+        LTagNode(LNode* l);
+        LTagNode(LNode* l, LTagNode* n);
+        ~LTagNode();
+        // declaration with first as parameter due to sorting of LTagList
+        LTagNode*   insert(LNode* l);
+        LNode*      getLNode();
+        LTagNode*   getNext();
+        LNode*      get(int i, int length);
+};
+
+
+/*
+=========================================================================
+class LTagList(lists of LPolyOld tags, i.e. first elements of a given index)
+=========================================================================
+*/
+class LTagList {
+    private:
+        LTagNode*   first;
+        LNode*      firstCurrentIdx;
+        int         length;
+    public:
+                LTagList();
+                LTagList(LNode* l);
+                ~LTagList();
+        // declaration with first as parameter in LTagNode due to sorting of LTagList
+        void    insert(LNode* l);
+        void    setFirstCurrentIdx(LNode* l);
+        LNode*  get(int idx);
+        LNode*  getFirst();
+        LNode*  getFirstCurrentIdx();
+};
+
+LNode*  getGPrevRedCheck();
+LNode*  getcompletedRedCheck();
+
+
+/*
+======================================================================================
+class TopRed(return values of subalgorithm TopRed in f5gb.cc), i.e. the first elements
+             of the lists LList* completed & LList* sPolyList
+======================================================================================
+*/
+class TopRed {
+    private:
+        LList*  _completed;
+        LList*  _toDo;
+    public:
+                TopRed();
+                TopRed(LList* c, LList* t);
+        LList*  getCompleted();
+        LList*  getToDo();
+};
+
+
+/*
+=======================================
+class CNode (nodes for lists of CPairOlds)
+=======================================
+*/
+class CNode {
+    private:
+        CPairOld* data;
+        CNode* next;
+    public:
+                CNode();
+                CNode(CPairOld* c);
+                CNode(CPairOld* c, CNode* n);
+                ~CNode();
+        CNode*  insert(CPairOld* c);
+        CNode*  insertWithoutSort(CPairOld* cp);
+        CNode*  getMinDeg();
+        CPairOld*  getData();
+        CNode*  getNext();
+        LPolyOld*  getAdLp1();
+        LPolyOld*  getAdLp2();
+        poly    getLp1Poly();
+        poly    getLp2Poly();
+        poly    getLp1Term();
+        poly    getLp2Term();
+        poly    getT1();
+        poly*   getAdT1();
+        poly    getT2();
+        poly*   getAdT2();
+        int     getLp1Index();
+        int     getLp2Index();
+        bool    getDel();
+        RuleOld*   getTestedRuleOld();
+        void    print();
+};
+
+
+/*
+============================
+class CListOld(lists of CPairOlds)
+============================
+*/
+class CListOld {
+    private:
+        CNode*  first;
+    public:
+                // for initialization of CListOlds, last element alwas has data=NULL and next=NULL
+                CListOld();
+                CListOld(CPairOld* c);
+                ~CListOld();
+        CNode*  getFirst();
+        void    insert(CPairOld* c);
+        void    insertWithoutSort(CPairOld* c);
+        CNode*  getMinDeg();
+        void    print();
+};
+
+
+/*
+======================================
+class RNode (nodes for lists of RuleOlds)
+======================================
+*/
+class RNode {
+    private:
+        RuleOld*   data;
+        RNode*  next;
+    public:
+                RNode();
+                RNode(RuleOld* r);
+                ~RNode();
+        RNode*  insert(RuleOld* r);
+        RNode*  insert(int i, poly t);
+        RNode*  insertOrdered(RuleOld* r);
+        RNode*  getNext();
+        RuleOld*   getRuleOld();
+        int     getRuleOldIndex();
+        poly    getRuleOldTerm();
+        void    print();
+};
+
+/*
+============================
+class RList (lists of RuleOlds)
+============================
+*/
+class RList {
+    private:
+        RNode*  first;
+        // last alway has data=NULL and next=NULL, for initialization purposes used
+        RNode*  last;
+    public:
+                RList();
+                RList(RuleOld* r);
+                ~RList();
+        void    insert(RuleOld* r);
+        void    insert(int i, poly t);
+        void    insertOrdered(RuleOld* r);
+        RNode*  getFirst();
+        RuleOld*   getRuleOld();
+        void    print();
+};
+
+
+
+/*
+=============================================
+class RtagNode (nodes for lists of RuleOld tags)
+=============================================
+*/
+class RTagNode {
+    private:
+        RNode*      data;
+        RTagNode*   next;
+    public:
+                    RTagNode();
+                    RTagNode(RNode* r);
+                    RTagNode(RNode* r, RTagNode* n);
+                    ~RTagNode();
+        // declaration with first as parameter due to sorting of LTagList
+        RTagNode*   insert(RNode* r);
+        RNode*      getRNode();
+        RTagNode*   getNext();
+        RNode*      get(int idx, int length);
+        void        set(RNode*);
+        void        print();
+};
+
+
+/*
+========================================================================
+class RTagList(lists of RuleOld tags, i.e. first elements of a given index)
+========================================================================
+*/
+class RTagList {
+    private:
+        RTagNode*   first;
+        int         length;
+    public:
+                RTagList();
+                RTagList(RNode* r);
+                ~RTagList();
+        // declaration with first as parameter in LTagNode due to sorting of LTagList
+        void    insert(RNode* r);
+        RNode*  getFirst();
+        RNode*  get(int idx);
+        void    setFirst(RNode* r);
+        void    print();
+        int     getLength();
+};
+#endif
+#endif
diff --git a/kernel/GBEngine/gr_kstd2.cc b/kernel/GBEngine/gr_kstd2.cc
new file mode 100644
index 0000000..c6fc384
--- /dev/null
+++ b/kernel/GBEngine/gr_kstd2.cc
@@ -0,0 +1,1325 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+*  ABSTRACT -  Kernel: noncomm. alg. of Buchberger
+*/
+#define PLURAL_INTERNAL_DECLARATIONS
+
+
+
+
+#include <kernel/mod2.h>
+
+#ifdef HAVE_PLURAL
+
+
+#include <omalloc/omalloc.h>
+#include <misc/options.h>
+#include <misc/intvec.h>
+
+#include <polys/weight.h>
+#include <kernel/polys.h>
+#include <polys/monomials/ring.h>
+
+#include <polys/nc/gb_hack.h>
+#include <polys/nc/nc.h>
+#include <polys/nc/sca.h>
+
+
+#include <kernel/ideals.h>
+#include <kernel/GBEngine/kstd1.h>
+#include <kernel/GBEngine/khstd.h>
+//#include "spolys.h"
+//#include "cntrlc.h"
+#include <kernel/GBEngine/ratgring.h>
+#include <kernel/GBEngine/kutil.h>
+
+#include <kernel/GBEngine/nc.h>
+
+#if 0
+/*3
+* reduction of p2 with p1
+* do not destroy p1 and p2
+* p1 divides p2 -> for use in NF algorithm
+*/
+poly gnc_ReduceSpolyNew(const poly p1, poly p2/*,poly spNoether*/, const ring r)
+{
+  return(nc_ReduceSPoly(p1,p_Copy(p2,r)/*,spNoether*/,r));
+}
+#endif
+
+/*2
+*reduces h with elements from T choosing  the first possible
+* element in t with respect to the given pDivisibleBy
+*/
+int redGrFirst (LObject* h,kStrategy strat)
+{
+  int at,reddeg,d,i;
+  int pass = 0;
+  int j = 0;
+
+  d = currRing->pFDeg((*h).p,currRing)+(*h).ecart;
+  reddeg = strat->LazyDegree+d;
+  loop
+  {
+    if (j > strat->sl)
+    {
+#ifdef KDEBUG
+      if (TEST_OPT_DEBUG) PrintLn();
+#endif
+      return 0;
+    }
+#ifdef KDEBUG
+    if (TEST_OPT_DEBUG) Print("%d",j);
+#endif
+    if (pDivisibleBy(strat->S[j],(*h).p))
+    {
+#ifdef KDEBUG
+      if (TEST_OPT_DEBUG) PrintS("+\n");
+#endif
+      /*
+      * the polynomial to reduce with is;
+      * T[j].p
+      */
+      if (!TEST_OPT_INTSTRATEGY)
+        pNorm(strat->S[j]);
+#ifdef KDEBUG
+      if (TEST_OPT_DEBUG)
+      {
+        wrp(h->p);
+        PrintS(" with ");
+        wrp(strat->S[j]);
+      }
+#endif
+      (*h).p = nc_ReduceSpoly(strat->S[j],(*h).p, currRing);
+      //spSpolyRed(strat->T[j].p,(*h).p,strat->kNoether);
+
+#ifdef KDEBUG
+      if (TEST_OPT_DEBUG)
+      {
+        PrintS(" to ");
+        wrp(h->p);
+      }
+#endif
+      if ((*h).p == NULL)
+      {
+        if (h->lcm!=NULL) p_LmFree((*h).lcm, currRing);
+        return 0;
+      }
+      if (TEST_OPT_INTSTRATEGY)
+      {
+        if (rField_is_Zp_a(currRing)) p_Content(h->p,currRing);
+        else h->pCleardenom();// also does a p_Content
+      }
+      /*computes the ecart*/
+      d = currRing->pLDeg((*h).p,&((*h).length),currRing);
+      (*h).FDeg=currRing->pFDeg((*h).p,currRing);
+      (*h).ecart = d-(*h).FDeg; /*pFDeg((*h).p);*/
+      if ((strat->syzComp!=0) && !strat->honey)
+      {
+        if ((strat->syzComp>0) && (pMinComp((*h).p) > strat->syzComp))
+        {
+#ifdef KDEBUG
+          if (TEST_OPT_DEBUG) PrintS(" > sysComp\n");
+#endif
+          return 0;
+        }
+      }
+      /*- try to reduce the s-polynomial -*/
+      pass++;
+      /*
+      *test whether the polynomial should go to the lazyset L
+      *-if the degree jumps
+      *-if the number of pre-defined reductions jumps
+      */
+      if ((strat->Ll >= 0)
+      && ((d >= reddeg) || (pass > strat->LazyPass))
+      && !strat->homog)
+      {
+        at = strat->posInL(strat->L,strat->Ll,h,strat);
+        if (at <= strat->Ll)
+        {
+          i=strat->sl+1;
+          do
+          {
+            i--;
+            if (i<0) return 0;
+          } while (!pDivisibleBy(strat->S[i],(*h).p));
+          enterL(&strat->L,&strat->Ll,&strat->Lmax,*h,at);
+#ifdef KDEBUG
+          if (TEST_OPT_DEBUG) Print(" degree jumped; ->L%d\n",at);
+#endif
+          (*h).p = NULL;
+          return 0;
+        }
+      }
+      if ((TEST_OPT_PROT) && (strat->Ll < 0) && (d >= reddeg))
+      {
+        reddeg = d+1;
+        Print(".%d",d);mflush();
+      }
+      j = 0;
+#ifdef KDEBUG
+      if TEST_OPT_DEBUG PrintLn();
+#endif
+    }
+    else
+    {
+#ifdef KDEBUG
+      if (TEST_OPT_DEBUG) PrintS("-");
+#endif
+      j++;
+    }
+  }
+}
+void ratGB_divide_out(poly p)
+{
+  /* extracts monomial content from localized expression  */
+  /* searches for an m (monomial in var 1.. real_var_start-1)
+   * such that m divides p and divides p by this m if it exist*/
+  if (p==NULL) return;
+  poly root=p;
+  assume(rIsRatGRing(currRing));
+  poly f=pHead(p);
+  int i;
+  for (i=currRing->real_var_start;i<=currRing->real_var_end;i++)
+  {
+    pSetExp(f,i,0);
+  }
+  loop
+  {
+    pIter(p);
+    if (p==NULL) { pSetm(f); break;}
+    for (i=1;i<=rVar(currRing);i++)
+    {
+      pSetExp(f,i,si_min(pGetExp(f,i),pGetExp(p,i)));
+    }
+  }
+  if (!pIsConstant(f))
+  {
+#ifdef KDEBUG
+    if (TEST_OPT_DEBUG)
+    {
+      PrintS("divide out:");p_wrp(f,currRing);
+      PrintS(" from ");pWrite(root);
+    }
+#endif
+    p=root;
+    loop
+    {
+      if (p==NULL) break;
+      for (i=1;i<=rVar(currRing);i++)
+      {
+        pSetExp(p,i,pGetExp(p,i)-pGetExp(f,i));
+      }
+      pSetm(p);
+      pIter(p);
+    }
+  }
+  pDelete(&f);
+}
+
+#ifdef HAVE_RATGRING
+/*2
+*reduces h with elements from T choosing  the first possible
+* element in t with respect to the given pDivisibleBy
+* for use in ratGB
+*/
+int redGrRatGB (LObject* h,kStrategy strat)
+{
+  int at,reddeg,d,i;
+  int pass = 0;
+  int j = 0;
+  int c_j=-1, c_e=-2;
+  poly c_p=NULL;
+  assume(strat->tailRing==currRing);
+
+  ratGB_divide_out((*h).p);
+  d = currRing->pFDeg((*h).p,currRing)+(*h).ecart;
+  reddeg = strat->LazyDegree+d;
+  if (!TEST_OPT_INTSTRATEGY)
+  {
+    if (rField_is_Zp_a(currRing)) p_Content(h->p,currRing);
+    else h->pCleardenom();// also does a pContentRat
+  }
+  loop
+  {
+    if (j > strat->sl)
+    {
+      if (c_j>=0)
+      {
+        /*
+        * the polynomial to reduce with is;
+        * S[c_j]
+        */
+        if (!TEST_OPT_INTSTRATEGY)
+          pNorm(strat->S[c_j]);
+#ifdef KDEBUG
+    if (TEST_OPT_DEBUG)
+        if (TEST_OPT_DEBUG)
+        {
+          wrp(h->p);
+          Print(" with S[%d]= ",c_j);
+          wrp(strat->S[c_j]);
+        }
+#endif
+    //poly hh = nc_CreateSpoly(strat->S[c_j],(*h).p, currRing);
+    //        Print("vor nc_rat_ReduceSpolyNew (ce:%d) ",c_e);wrp(h->p);PrintLn();
+    //if(c_e==-1)
+    //  c_p = nc_CreateSpoly(pCopy(strat->S[c_j]),pCopy((*h).p), currRing);
+    //else
+    //          c_p=nc_rat_ReduceSpolyNew(strat->S[c_j],pCopy((*h).p), currRing->real_var_start-1,currRing);
+    //        Print("nach nc_rat_ReduceSpolyNew ");wrp(c_p);PrintLn();
+    //        pDelete(&((*h).p));
+
+        c_p=nc_rat_ReduceSpolyNew(strat->S[c_j],(*h).p, currRing->real_var_start-1,currRing);
+        (*h).p=c_p;
+        if (!TEST_OPT_INTSTRATEGY)
+        {
+          if (rField_is_Zp_a(currRing)) p_Content(h->p,currRing);
+          else h->pCleardenom();// also does a p_Content
+        }
+
+#ifdef KDEBUG
+        if (TEST_OPT_DEBUG)
+        {
+          PrintS(" to ");
+          wrp(h->p);
+          PrintLn();
+        }
+#endif
+        if ((*h).p == NULL)
+        {
+          if (h->lcm!=NULL) p_LmFree((*h).lcm, currRing);
+          return 0;
+        }
+        ratGB_divide_out((*h).p);
+        d = currRing->pLDeg((*h).p,&((*h).length),currRing);
+        (*h).FDeg=currRing->pFDeg((*h).p,currRing);
+        (*h).ecart = d-(*h).FDeg; /*pFDeg((*h).p);*/
+        /*- try to reduce the s-polynomial again -*/
+        pass++;
+        j=0;
+        c_j=-1; c_e=-2; c_p=NULL;
+      }
+      else
+      { // nothing found
+        return 0;
+      }
+    }
+    // first try usal division
+    if (p_LmDivisibleBy(strat->S[j],(*h).p,currRing))
+    {
+#ifdef KDEBUG
+      if(TEST_OPT_DEBUG)
+      {
+        p_wrp(h->p,currRing); Print(" divisible by S[%d]=",j);
+        p_wrp(strat->S[j],currRing); PrintS(" e=-1\n");
+      }
+#endif
+      if ((c_j<0)||(c_e>=0))
+      {
+        c_e=-1; c_j=j;
+      }
+    }
+    else
+    if (p_LmDivisibleByPart(strat->S[j],(*h).p,currRing,
+        currRing->real_var_start,currRing->real_var_end))
+    {
+      int a_e=(p_Totaldegree(strat->S[j],currRing)-currRing->pFDeg(strat->S[j],currRing));
+#ifdef KDEBUG
+      if(TEST_OPT_DEBUG)
+      {
+        p_wrp(h->p,currRing); Print(" divisibly by S[%d]=",j);
+        p_wrp(strat->S[j],currRing); Print(" e=%d\n",a_e);
+      }
+#endif
+      if ((c_j<0)||(c_e>a_e))
+      {
+        c_e=a_e; c_j=j;
+        //c_p = nc_CreateSpoly(pCopy(strat->S[c_j]),pCopy((*h).p), currRing);
+      }
+      /*computes the ecart*/
+      if ((strat->syzComp!=0) && !strat->honey)
+      {
+        if ((strat->syzComp>0) && (pMinComp((*h).p) > strat->syzComp))
+        {
+#ifdef KDEBUG
+          if (TEST_OPT_DEBUG) PrintS(" > sysComp\n");
+#endif
+          return 0;
+        }
+      }
+    }
+    else
+    {
+#ifdef KDEBUG
+      if(TEST_OPT_DEBUG)
+      {
+        p_wrp(h->p,currRing); Print(" not divisibly by S[%d]=",j);
+        p_wrp(strat->S[j],currRing); PrintLn();
+      }
+#endif
+    }
+    j++;
+  }
+}
+#endif
+
+/*2
+*  reduction procedure for the homogeneous case
+*  and the case of a degree-ordering
+*/
+static int nc_redHomog (LObject* h,kStrategy strat)
+{
+  if (strat->tl<0)
+  {
+    enterT((*h),strat);
+    return 1;
+  }
+
+  int j = 0;
+
+  if (TEST_OPT_DEBUG)
+  {
+    PrintS("red:");
+    wrp(h->p);
+    PrintS(" ");
+  }
+  loop
+  {
+    if (TEST_OPT_DEBUG) Print("%d",j);
+    if (pDivisibleBy(strat->S[j],(*h).p))
+    {
+      if (TEST_OPT_DEBUG)
+      {
+        PrintS("+\nwith ");
+        wrp(strat->S[j]);
+      }
+      /*- compute the s-polynomial -*/
+      (*h).p = nc_ReduceSpoly(strat->S[j],(*h).p,currRing);
+      if ((*h).p == NULL)
+      {
+        if (TEST_OPT_DEBUG) PrintS(" to 0\n");
+        if (h->lcm!=NULL) pLmFree((*h).lcm);
+        (*h).lcm=NULL;
+        return 0;
+      }
+/*
+*      else if (strat->syzComp)
+*      {
+*        if (pMinComp((*h).p) > strat->syzComp)
+*        {
+*          enterT((*h),strat);
+*          return;
+*        }
+*      }
+*/
+      /*- try to reduce the s-polynomial -*/
+      j = 0;
+    }
+    else
+    {
+      if (j >= strat->sl)
+      {
+        enterT((*h),strat);
+        return 1;
+      }
+      j++;
+    }
+  }
+}
+
+#if 0
+/*2
+*  reduction procedure for the homogeneous case
+*  and the case of a degree-ordering
+*/
+static int nc_redHomog0 (LObject* h,kStrategy strat)
+{
+  if (strat->tl<0)
+  {
+    enterT((*h),strat);
+    return 0;
+  }
+
+  int j = 0;
+  int k = 0;
+
+  if (TEST_OPT_DEBUG)
+  {
+    PrintS("red:");
+    wrp(h->p);
+    PrintS(" ");
+  }
+  loop
+  {
+    if (TEST_OPT_DEBUG) Print("%d",j);
+    if (pDivisibleBy(strat->T[j].p,(*h).p))
+    {
+      if (TEST_OPT_DEBUG)
+      {
+        PrintS("+\nwith ");
+        wrp(strat->S[j]);
+      }
+      /*- compute the s-polynomial -*/
+      (*h).p = nc_ReduceSpoly(strat->T[j].p,(*h).p,strat->kNoether,currRing);
+      if ((*h).p == NULL)
+      {
+        if (TEST_OPT_DEBUG) PrintS(" to 0\n");
+        if (h->lcm!=NULL) pLmFree((*h).lcm);
+        (*h).lcm=NULL;
+        return 0;
+      }
+      else
+      {
+        if (TEST_OPT_INTSTRATEGY)
+        {
+          if (rField_is_Zp_a(currRing)) p_Content(h->p,currRing);
+          else h->pCleardenom();// also does a pContent
+        }
+        if (strat->syzComp!=0)
+        {
+          if ((strat->syzComp>0) && (pMinComp((*h).p) > strat->syzComp))
+          {
+/*
+*           (*h).length=pLength0((*h).p);
+*/
+            enterT((*h),strat);
+            return 0;
+          }
+        }
+      }
+      /*- try to reduce the s-polynomial -*/
+      j = 0;
+    }
+    else
+    {
+      if (j >= strat->tl)
+      {
+        if (TEST_OPT_INTSTRATEGY)
+        {
+          if (rField_is_Zp_a(currRing)) p_Content(h->p,currRing);
+          else h->pCleardenom();// also does a p_Content
+        }
+/*
+*       (*h).length=pLength0((*h).p);
+*/
+        enterT((*h),strat);
+        return 0;
+      }
+      j++;
+    }
+  }
+}
+
+/*2
+*  reduction procedure for the inhomogeneous case
+*  and not a degree-ordering
+*/
+static int nc_redLazy (LObject* h,kStrategy strat)
+{
+  if (strat->tl<0)
+  {
+    enterT((*h),strat);
+    return 0;
+  }
+
+  int at,d,i;
+  int j = 0;
+  int pass = 0;
+  int reddeg = currRing->pFDeg((*h).p,currRing);
+
+  if (TEST_OPT_DEBUG)
+  {
+    PrintS("red:");
+    wrp(h->p);
+    PrintS(" ");
+  }
+  loop
+  {
+    if (TEST_OPT_DEBUG) Print("%d",j);
+    if (pDivisibleBy(strat->S[j],(*h).p))
+    {
+      if (TEST_OPT_DEBUG)
+      {
+        PrintS("+\nwith ");
+        wrp(strat->S[j]);
+      }
+      /*- compute the s-polynomial -*/
+      (*h).p = nc_ReduceSpoly(strat->S[j],(*h).p,strat->kNoether,currRing);
+      if ((*h).p == NULL)
+      {
+        if (TEST_OPT_DEBUG) PrintS(" to 0\n");
+        if (h->lcm!=NULL) pLmFree((*h).lcm);
+        (*h).lcm=NULL;
+        return 0;
+      }
+//      else if (strat->syzComp)
+//      {
+//        if ((strat->syzComp>0) && (pMinComp((*h).p) > strat->syzComp))
+//        {
+//          if (TEST_OPT_DEBUG) PrintS(" > syzComp\n");
+//          if (TEST_OPT_INTSTRATEGY) p_Content(h->p,currRing);
+//          enterTBba((*h),strat->tl+1,strat);
+//          return;
+//        }
+//      }
+      else
+      {
+        if (TEST_OPT_DEBUG)
+        {
+          PrintS("to:");
+          wrp((*h).p);
+          PrintLn();
+        }
+        if (TEST_OPT_INTSTRATEGY)
+        {
+          p_Content(h->p,currRing);
+          //pCleardenom(h->p);// also does a p_Content
+        }
+      }
+      /*- try to reduce the s-polynomial -*/
+      pass++;
+      d = currRing->pFDeg((*h).p,currRing);
+      if ((strat->Ll >= 0) && ((d > reddeg) || (pass > strat->LazyPass)))
+      {
+        at = posInL11(strat->L,strat->Ll,h,strat);
+        if (at <= strat->Ll)
+        {
+          i=strat->sl+1;
+          do
+          {
+            i--;
+            if (i<0)
+            {
+              enterT((*h),strat);
+              return 0;
+            }
+          }
+          while (!pDivisibleBy(strat->S[i],(*h).p));
+          if (TEST_OPT_DEBUG) Print(" ->L[%d]\n",at);
+          enterL(&strat->L,&strat->Ll,&strat->Lmax,*h,at);
+          (*h).p = NULL;
+          return 0;
+        }
+      }
+      else if ((TEST_OPT_PROT) && (strat->Ll < 0) && (d != reddeg))
+      {
+        Print(".%d",d);mflush();
+        reddeg = d;
+      }
+      j = 0;
+    }
+    else
+    {
+      if (TEST_OPT_DEBUG) PrintS("-");
+      if (j >= strat->sl)
+      {
+        if (TEST_OPT_DEBUG) PrintLn();
+        if (TEST_OPT_INTSTRATEGY)
+        {
+          if (rField_is_Zp_a(currRing)) p_Content(h->p,currRing);
+          else h->pCleardenom();// also does a p_Content
+        }
+        enterT((*h),strat);
+        return 0;
+      }
+      j++;
+    }
+  }
+}
+
+/*2
+*  reduction procedure for the sugar-strategy (honey)
+* reduces h with elements from T choosing first possible
+* element in T with respect to the given ecart
+*/
+static int nc_redHoney (LObject*  h,kStrategy strat)
+{
+  if (strat->tl<0)
+  {
+    enterT((*h),strat);
+    return 0;
+  }
+
+  poly pi;
+  int i,j,at,reddeg,d,pass,ei;
+
+  pass = j = 0;
+  d = reddeg = currRing->pFDeg((*h).p,currRing)+(*h).ecart;
+  if (TEST_OPT_DEBUG)
+  {
+    PrintS("red:");
+    wrp((*h).p);
+  }
+  loop
+  {
+    if (TEST_OPT_DEBUG) Print("%d",j);
+    if (pDivisibleBy(strat->T[j].p,(*h).p))
+    {
+      if (TEST_OPT_DEBUG) PrintS("+");
+      pi = strat->T[j].p;
+      ei = strat->T[j].ecart;
+      /*
+      * the polynomial to reduce with (up to the moment) is;
+      * pi with ecart ei
+      */
+      i = j;
+      loop
+      {
+        /*- takes the first possible with respect to ecart -*/
+        i++;
+        if (i > strat->tl)
+          break;
+        if ((!BTEST1(20)) && (ei <= (*h).ecart))
+          break;
+        if (TEST_OPT_DEBUG) Print("%d",i);
+        if ((strat->T[i].ecart < ei) && pDivisibleBy(strat->T[i].p,(*h).p))
+        {
+          if (TEST_OPT_DEBUG) PrintS("+");
+          /*
+          * the polynomial to reduce with is now;
+          */
+          pi = strat->T[i].p;
+          ei = strat->T[i].ecart;
+        }
+        else if (TEST_OPT_DEBUG) PrintS("-");
+      }
+
+      /*
+      * end of search: have to reduce with pi
+      */
+      if (ei > (*h).ecart)
+      {
+        /*
+        * It is not possible to reduce h with smaller ecart;
+        * if possible h goes to the lazy-set L,i.e
+        * if its position in L would be not the last one
+        */
+        if (strat->Ll >= 0) /* L is not empty */
+        {
+          at = strat->posInL(strat->L,strat->Ll,h,strat);
+          if(at <= strat->Ll)
+          /*- h will not become the next element to reduce -*/
+          {
+            enterL(&strat->L,&strat->Ll,&strat->Lmax,*h,at);
+            if (TEST_OPT_DEBUG) Print(" ecart too big: -> L%d\n",at);
+            (*h).p = NULL;
+            return 0;
+          }
+        }
+      }
+      if (TEST_OPT_DEBUG)
+      {
+        PrintS("\nwith ");
+        wrp(pi);
+      }
+      if (strat->fromT)
+      {
+        strat->fromT=FALSE;
+        (*h).p = nc_ReduceSpoly(pi,(*h).p,strat->kNoether,currRing);
+      }
+      else
+        (*h).p = nc_ReduceSpoly(pi,(*h).p,strat->kNoether,currRing);
+      if (TEST_OPT_DEBUG)
+      {
+        PrintS(" to ");
+        wrp((*h).p);
+        PrintLn();
+      }
+      if ((*h).p == NULL)
+      {
+        if (h->lcm!=NULL) pLmFree((*h).lcm);
+        (*h).lcm=NULL;
+        return 0;
+      }
+      if (TEST_OPT_INTSTRATEGY)
+      {
+        h->pCleardenom();// also does a p_Content
+      }
+      /* compute the ecart */
+      if (ei <= (*h).ecart)
+        (*h).ecart = d-currRing->pFDeg((*h).p,currRing);
+      else
+        (*h).ecart = d-currRing->pFDeg((*h).p,currRing)+ei-(*h).ecart;
+//      if (strat->syzComp)
+//      {
+//        if ((strat->syzComp>0) && (pMinComp((*h).p) > strat->syzComp))
+//        {
+//          if (TEST_OPT_DEBUG)
+//            PrintS("  >syzComp\n");
+//          if (TEST_OPT_INTSTRATEGY) p_Content(h->p,currRing);
+//          at=strat->posInT(strat->T,strat->tl,(*h));
+//          enterTBba((*h),at,strat);
+//          return;
+//        }
+//      }
+      /*
+      * try to reduce the s-polynomial h
+      *test first whether h should go to the lazyset L
+      *-if the degree jumps
+      *-if the number of pre-defined reductions jumps
+      */
+      pass++;
+      d = currRing->pFDeg((*h).p,currRing)+(*h).ecart;
+      if ((strat->Ll >= 0) && ((d > reddeg) || (pass > strat->LazyPass)))
+      {
+        at = strat->posInL(strat->L,strat->Ll,h,strat);
+        if (at <= strat->Ll)
+        {
+          /*test if h is already standardbasis element*/
+          i=strat->sl+1;
+          do
+          {
+            i--;
+            if (i<0)
+            {
+              enterT((*h),strat);
+              return 0;
+            }
+          } while (!pDivisibleBy(strat->S[i],(*h).p));
+          enterL(&strat->L,&strat->Ll,&strat->Lmax,*h,at);
+          if (TEST_OPT_DEBUG)
+            Print(" degree jumped: -> L%d\n",at);
+          (*h).p = NULL;
+          return 0;
+        }
+      }
+      else if (TEST_OPT_PROT && (strat->Ll < 0) && (d > reddeg))
+      {
+        reddeg = d;
+        Print(".%d",d); mflush();
+      }
+      j = 0;
+    }
+    else
+    {
+      if (TEST_OPT_DEBUG) PrintS("-");
+      if (j >= strat->tl)
+      {
+        if (TEST_OPT_DEBUG) PrintLn();
+        if (TEST_OPT_INTSTRATEGY)
+        {
+          h->pCleardenom();// also does a p_Content
+        }
+        enterT((*h),strat);
+        return 0;
+      }
+      j++;
+    }
+  }
+}
+
+/*2
+*  reduction procedure for tests only
+*  reduces with elements from T and chooses the best possible
+*/
+static int nc_redBest (LObject*  h,kStrategy strat)
+{
+  if (strat->tl<0)
+  {
+    enterT((*h),strat);
+    return 0;
+  }
+
+  int j,jbest,at,reddeg,d,pass;
+  poly     p,ph;
+  pass = j = 0;
+
+  if (strat->honey)
+    reddeg = currRing->pFDeg((*h).p,currRing)+(*h).ecart;
+  else
+    reddeg = currRing->pFDeg((*h).p,currRing);
+  loop
+  {
+    if (pDivisibleBy(strat->T[j].p,(*h).p))
+    {
+      /* compute the s-polynomial */
+      if (!TEST_OPT_INTSTRATEGY) pNorm((*h).p);
+#ifdef SDRING
+      // spSpolyShortBba will not work in the SRING case
+      if (pSDRING)
+      {
+        p=spSpolyCreate(strat->T[j].p,(*h).p,strat->kNoether);
+        if (p!=NULL) pDelete(&pNext(p));
+      }
+      else
+#endif
+      p = nc_CreateShortSpoly(strat->T[j].p,(*h).p);
+      /* computes only the first monomial of the spoly  */
+      if (p)
+      {
+        jbest = j;
+        /* looking for the best possible reduction */
+        if ((strat->syzComp==0) || (pMinComp(p) <= strat->syzComp))
+        {
+          loop
+          {
+            j++;
+            if (j > strat->tl)
+              break;
+            if (pDivisibleBy(strat->T[j].p,(*h).p))
+            {
+#ifdef SDRING
+              // spSpolyShortBba will not work in the SRING case
+              if (pSDRING)
+              {
+                ph=spSpolyCreate(strat->T[j].p,(*h).p,strat->kNoether);
+                if (ph!=NULL) pDelete(&pNext(ph));
+              }
+              else
+#endif
+              ph = nc_CreateShortSpoly(strat->T[j].p,(*h).p);
+              if (ph==NULL)
+              {
+                pLmFree(p);
+                pDelete(&((*h).p));
+                if (h->lcm!=NULL)
+                {
+                  pLmFree((*h).lcm);
+                  (*h).lcm=NULL;
+                }
+                return 0;
+              }
+              else if (pLmCmp(ph,p) == -1)
+              {
+                pLmFree(p);
+                p = ph;
+                jbest = j;
+              }
+              else
+              {
+                pLmFree(ph);
+              }
+            }
+          }
+        }
+        pLmFree(p);
+        (*h).p = nc_ReduceSpoly(strat->T[jbest].p,(*h).p,strat->kNoether,currRing);
+      }
+      else
+      {
+        if (h->lcm!=NULL)
+        {
+          pLmFree((*h).lcm);
+          (*h).lcm=NULL;
+        }
+        (*h).p = NULL;
+        return 0;
+      }
+      if (strat->honey && currRing->pLexOrder)
+        strat->initEcart(h);
+      /* h.length:=l; */
+      /* try to reduce the s-polynomial */
+//      if (strat->syzComp)
+//      {
+//        if ((strat->syzComp>0) && (pMinComp((*h).p) > strat->syzComp))
+//        {
+//          if (TEST_OPT_DEBUG)
+//            PrintS(" >syzComp\n");
+//          if (TEST_OPT_INTSTRATEGY) p_Content(h->p,currRing);
+//          at=strat->posInT(strat->T,strat->tl,(*h));
+//          enterTBba((*h),at,strat);
+//          return;
+//        }
+//      }
+      if (strat->honey || currRing->pLexOrder)
+      {
+        pass++;
+        d = currRing->pFDeg((*h).p,currRing);
+        if (strat->honey)
+          d += (*h).ecart;
+        if ((strat->Ll >= 0) && ((pass > strat->LazyPass) || (d > reddeg)))
+        {
+          at = strat->posInL(strat->L,strat->Ll,h,strat);
+          if (at <= strat->Ll)
+          {
+            enterL(&strat->L,&strat->Ll,&strat->Lmax,*h,at);
+            (*h).p = NULL;
+            return 0;
+          }
+        }
+        else if (TEST_OPT_PROT && (strat->Ll < 0) && (d != reddeg))
+        {
+          reddeg = d;
+          Print("%d.");
+          mflush();
+        }
+      }
+      j = 0;
+    }
+    else
+    {
+      if (j >= strat->tl)
+      {
+        if (TEST_OPT_INTSTRATEGY)
+        {
+          h->pCleardenom();// also does a p_Content
+        }
+        enterT((*h),strat);
+        return 0;
+      }
+      j++;
+    }
+  }
+}
+
+#endif
+
+#ifdef HAVE_RATGRING
+void nc_gr_initBba(ideal F, kStrategy strat)
+#else
+void nc_gr_initBba(ideal, kStrategy strat)
+#endif
+{
+  assume(rIsPluralRing(currRing));
+
+  // int i;
+//  idhdl h;
+ /* setting global variables ------------------- */
+  strat->enterS = enterSBba;
+
+/*
+  if ((BTEST1(20)) && (!strat->honey))
+    strat->red = nc_redBest;
+  else if (strat->honey)
+    strat->red = nc_redHoney;
+  else if (currRing->pLexOrder && !strat->homog)
+    strat->red = nc_redLazy;
+  else if (TEST_OPT_INTSTRATEGY && strat->homog)
+    strat->red = nc_redHomog0;
+  else
+    strat->red = nc_redHomog;
+*/
+
+//   if (rIsPluralRing(currRing))
+    strat->red = redGrFirst;
+#ifdef HAVE_RATGRING
+  if (rIsRatGRing(currRing))
+  {
+    int ii=IDELEMS(F)-1;
+    int jj;
+    BOOLEAN is_rat_id=FALSE;
+    for(;ii>=0;ii--)
+    {
+      for(jj=currRing->real_var_start;jj<=currRing->real_var_end;jj++)
+      {
+        if(pGetExp(F->m[ii],jj)>0) { is_rat_id=TRUE; break; }
+      }
+      if (is_rat_id) break;
+    }
+    if (is_rat_id) strat->red=redGrRatGB;
+  }
+#endif
+
+  if (currRing->pLexOrder && strat->honey)
+    strat->initEcart = initEcartNormal;
+  else
+    strat->initEcart = initEcartBBA;
+  if (strat->honey)
+    strat->initEcartPair = initEcartPairMora;
+  else
+    strat->initEcartPair = initEcartPairBba;
+//  if ((TEST_OPT_WEIGHTM)&&(F!=NULL))
+//  {
+//     //interred  machen   Aenderung
+//     pFDegOld=currRing->pFDeg;
+//     pLDegOld=currRing->pLDeg;
+//  //   h=ggetid("ecart");
+//  //   if ((h!=NULL) && (IDTYP(h)==INTVEC_CMD))
+//  //   {
+//  //     ecartWeights=iv2array(IDINTVEC(h));
+//  //   }
+//  //   else
+//    {
+//      ecartWeights=(short *)omAlloc(((currRing->N)+1)*sizeof(short));
+//      /*uses automatic computation of the ecartWeights to set them*/
+//      kEcartWeights(F->m,IDELEMS(F)-1,ecartWeights);
+//    }
+//    currRing->pFDeg=totaldegreeWecart;
+//    currRing->pLDeg=maxdegreeWecart;
+//    for(i=1; i<=(currRing->N); i++)
+//      Print(" %d",ecartWeights[i]);
+//    PrintLn();
+//    mflush();
+//  }
+}
+
+#define MYTEST 0
+
+ideal gnc_gr_bba(const ideal F, const ideal Q, const intvec *, const intvec *, kStrategy strat, const ring _currRing)
+{
+  const ring save = currRing; if( currRing != _currRing ) rChangeCurrRing(_currRing);
+
+#if MYTEST
+   PrintS("<gnc_gr_bba>\n");
+#endif
+
+#ifdef HAVE_PLURAL
+#if MYTEST
+   PrintS("currRing: \n");
+   rWrite(currRing);
+#ifdef RDEBUG
+   rDebugPrint(currRing);
+#endif
+
+   PrintS("F: \n");
+   idPrint(F);
+   PrintS("Q: \n");
+   idPrint(Q);
+#endif
+#endif
+
+  assume(currRing->OrdSgn != -1); // no mora!!! it terminates only for global ordering!!! (?)
+
+  // intvec *w=NULL;
+  // intvec *hilb=NULL;
+  int   olddeg,reduc;
+  int red_result=1;
+  int /*hilbeledeg=1,*/hilbcount=0/*,minimcnt=0*/;
+
+  initBuchMoraCrit(strat); /*set Gebauer, honey, sugarCrit*/
+  // initHilbCrit(F,Q,&hilb,strat);
+  /* in plural we don't need Hilb yet */
+  nc_gr_initBba(F,strat);
+  initBuchMoraPos(strat);
+  if (rIsRatGRing(currRing))
+  {
+    strat->posInL=posInL0; // by pCmp of lcm
+  }
+  /*set enterS, spSpolyShort, reduce, red, initEcart, initEcartPair*/
+  /*Shdl=*/initBuchMora(F, Q,strat);
+  strat->posInT=posInT110;
+  reduc = olddeg = 0;
+
+  /* compute------------------------------------------------------- */
+  while (strat->Ll >= 0)
+  {
+    if (TEST_OPT_DEBUG) messageSets(strat);
+
+    if (strat->Ll== 0) strat->interpt=TRUE;
+    if (TEST_OPT_DEGBOUND
+    && ((strat->honey
+    && (strat->L[strat->Ll].ecart+currRing->pFDeg(strat->L[strat->Ll].p,currRing)>Kstd1_deg))
+       || ((!strat->honey) && (currRing->pFDeg(strat->L[strat->Ll].p,currRing)>Kstd1_deg))))
+    {
+      /*
+      *stops computation if
+      * 24 IN test and the degree +ecart of L[strat->Ll] is bigger then
+      *a predefined number Kstd1_deg
+      */
+      while (strat->Ll >= 0) deleteInL(strat->L,&strat->Ll,strat->Ll,strat);
+      break;
+    }
+    /* picks the last element from the lazyset L */
+    strat->P = strat->L[strat->Ll];
+    strat->Ll--;
+    //kTest(strat);
+
+    if (strat->P.p != NULL)
+    if (pNext(strat->P.p) == strat->tail)
+    {
+      /* deletes the short spoly and computes */
+      pLmFree(strat->P.p);
+      /* the real one */
+//      if (ncRingType(currRing)==nc_lie) /* prod crit */
+//        if(pHasNotCF(strat->P.p1,strat->P.p2))
+//        {
+//          strat->cp++;
+//          /* prod.crit itself in nc_CreateSpoly */
+//        }
+
+
+      if( ! rIsRatGRing(currRing) )
+      {
+        strat->P.p = nc_CreateSpoly(strat->P.p1,strat->P.p2,currRing);
+      }
+#ifdef HAVE_RATGRING
+      else
+      {
+        /* rational case */
+        strat->P.p = nc_rat_CreateSpoly(strat->P.p1,strat->P.p2,currRing->real_var_start-1,currRing);
+      }
+#endif
+
+
+#ifdef PDEBUG
+      p_Test(strat->P.p, currRing);
+#endif
+
+#if MYTEST
+      if (TEST_OPT_DEBUG)
+      {
+        PrintS("p1: "); pWrite(strat->P.p1);
+        PrintS("p2: "); pWrite(strat->P.p2);
+        PrintS("SPoly: "); pWrite(strat->P.p);
+      }
+#endif
+    }
+
+
+    if (strat->P.p != NULL)
+    {
+      if (TEST_OPT_PROT)
+        message((strat->honey ? strat->P.ecart : 0) + strat->P.pFDeg(),
+              &olddeg,&reduc,strat, red_result);
+
+#if MYTEST
+      if (TEST_OPT_DEBUG)
+      {
+        PrintS("p1: "); pWrite(strat->P.p1);
+        PrintS("p2: "); pWrite(strat->P.p2);
+        PrintS("SPoly before: "); pWrite(strat->P.p);
+      }
+#endif
+
+      /* reduction of the element chosen from L */
+      strat->red(&strat->P,strat);
+
+#if MYTEST
+      if (TEST_OPT_DEBUG)
+      {
+        PrintS("red SPoly: "); pWrite(strat->P.p);
+      }
+#endif
+    }
+    if (strat->P.p != NULL)
+    {
+      if (TEST_OPT_PROT)
+      {
+        PrintS("s\n");
+      }
+      /* enter P.p into s and L */
+      {
+/* quick unit detection in the rational case */
+#ifdef HAVE_RATGRING
+        if( rIsRatGRing(currRing) )
+        {
+          if ( p_LmIsConstantRat(strat->P.p, currRing) )
+          {
+#ifdef PDEBUG
+             Print("unit element detected:");
+             p_wrp(strat->P.p,currRing);
+#endif
+            p_Delete(&strat->P.p,currRing, strat->tailRing);
+            strat->P.p = pOne();
+          }
+      }
+#endif
+        strat->P.sev=0;
+        int pos=posInS(strat,strat->sl,strat->P.p, strat->P.ecart);
+        {
+          if (TEST_OPT_INTSTRATEGY)
+          {
+            if ((strat->syzComp==0)||(!strat->homog))
+            {
+              #ifdef HAVE_RATGRING
+              if(!rIsRatGRing(currRing))
+              #endif
+                strat->P.p = redtailBba(strat->P.p,pos-1,strat);
+            }
+
+            strat->P.p=p_Cleardenom(strat->P.p, currRing);
+          }
+          else
+          {
+            pNorm(strat->P.p);
+            if ((strat->syzComp==0)||(!strat->homog))
+            {
+              strat->P.p = redtailBba(strat->P.p,pos-1,strat);
+            }
+          }
+          if (TEST_OPT_DEBUG)
+          {
+            PrintS("new s:"); wrp(strat->P.p);
+            PrintLn();
+#if MYTEST
+            Print("s: "); pWrite(strat->P.p);
+#endif
+
+          }
+          // kTest(strat);
+          //
+          enterpairs(strat->P.p,strat->sl,strat->P.ecart,pos,strat);
+
+          if (strat->sl==-1) pos=0;
+          else pos=posInS(strat,strat->sl,strat->P.p,strat->P.ecart);
+
+          strat->enterS(strat->P,pos,strat,-1);
+        }
+//      if (hilb!=NULL) khCheck(Q,w,hilb,hilbeledeg,hilbcount,strat);
+      }
+      if (strat->P.lcm!=NULL) pLmFree(strat->P.lcm);
+    }
+#ifdef KDEBUG
+    strat->P.lcm=NULL;
+#endif
+    //kTest(strat);
+  }
+  if (TEST_OPT_DEBUG) messageSets(strat);
+
+  /* complete reduction of the standard basis--------- */
+  if (TEST_OPT_SB_1)
+  {
+    int k=1;
+    int j;
+    while(k<=strat->sl)
+    {
+      j=0;
+      loop
+      {
+        if (j>=k) break;
+        clearS(strat->S[j],strat->sevS[j],&k,&j,strat);
+        j++;
+      }
+      k++;
+    }
+  }
+
+  if (TEST_OPT_REDSB)
+     completeReduce(strat);
+  /* release temp data-------------------------------- */
+  exitBuchMora(strat);
+//  if (TEST_OPT_WEIGHTM)
+//  {
+//    currRing->pFDeg=pFDegOld;
+//    currRing->pLDeg=pLDegOld;
+//    if (ecartWeights)
+//    {
+//      omFreeSize((ADDRESS)ecartWeights,((currRing->N)+1)*sizeof(short));
+//      ecartWeights=NULL;
+//    }
+//  }
+  if (TEST_OPT_PROT) messageStat(hilbcount,strat);
+  if (Q!=NULL) updateResult(strat->Shdl,Q,strat);
+
+
+#ifdef PDEBUG
+/* for counting number of pairs [enterL] in Plural */
+/*   extern int zaehler; */
+/*   Print("Total pairs considered:%d\n",zaehler); zaehler=0; */
+#endif /*PDEBUG*/
+
+#if MYTEST
+  PrintS("</gnc_gr_bba>\n");
+#endif
+
+  if( currRing != save )     rChangeCurrRing(save);
+
+  return (strat->Shdl);
+}
+
+ideal gnc_gr_mora(const ideal F, const ideal Q, const intvec *, const intvec *, kStrategy strat, const ring _currRing)
+{
+#ifndef SING_NDEBUG
+  // Not yet!
+  WarnS("Sorry, non-commutative mora is not yet implemented!");
+#endif
+
+  return gnc_gr_bba(F, Q, NULL, NULL, strat, _currRing);
+}
+
+#endif
+
diff --git a/kernel/GBEngine/janet.cc b/kernel/GBEngine/janet.cc
new file mode 100644
index 0000000..cdb5547
--- /dev/null
+++ b/kernel/GBEngine/janet.cc
@@ -0,0 +1,1100 @@
+
+
+
+
+#include <kernel/mod2.h>
+#include <omalloc/omalloc.h>
+
+#include <coeffs/numbers.h>
+// #include <coeffs/longrat.h>
+
+#include <polys/monomials/ring.h>
+#include <polys/monomials/p_polys.h>
+#include <polys/kbuckets.h>
+
+#include <kernel/ideals.h>
+#include <kernel/polys.h>
+#include <kernel/GBEngine/kutil.h>
+
+// #include "subexpr.h"
+
+#include <kernel/GBEngine/janet.h>
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <time.h>
+
+#if (defined(__CYGWIN__))
+#include <ctype.h>
+#endif
+
+
+//------GLOBALS-------
+static int /*m_s,v_s,vectorized,VarN1,*/offset;
+static jList *T,*Q;
+static TreeM *G;
+// static Poly *phD;
+static NodeM *FreeNodes;
+static int degree_compatible;
+static int (*ListGreatMove)(jList *,jList *,poly);
+static int Mask[8]={0x80,0x40,0x20,0x10,0x8,0x4,0x2,0x1};
+
+//#define DebugPrint
+
+//#define pow_(x) pTotaldegree((x))
+//#define pow_(x) p_Deg((x,currRing))
+pFDegProc jDeg;
+#define pow_(x) jDeg((x),currRing)
+
+#if 0
+void Debug()
+{
+  LCI it=T->root;
+
+  PrintS("T==================================\n");
+  while (it)
+  {
+    pWrite(it->info->root);
+    it=it->next;
+  }
+
+  it=Q->root;
+
+  PrintS("Q==================================\n");
+  while (it)
+  {
+    if (it->info->root) pWrite(it->info->root);
+    else
+    {
+      Print("%d.........",it->info->prolonged);
+      pWrite(it->info->history);
+    }
+    it=it->next;
+  }
+  PrintS("===================================\n");
+}
+#endif
+
+int ReducePolyLead(Poly *x,Poly *y)
+{
+  if (!x->root || !y->root)
+    return 0;
+
+/*  poly b1=pDivide(x->root,y->root);
+
+  number gcd=n_Gcd(pGetCoeff(x->root),pGetCoeff(y->root),currRing->cf);
+
+  number a1=nDiv(pGetCoeff(y->root),gcd);
+  pGetCoeff(b1)=nDiv(pGetCoeff(x->root),gcd);
+
+  x->root=pMult_nn(x->root,a1);
+  nDelete(&a1);
+
+  x->root=pMinus_mm_Mult_qq(x->root,b1,y->root);
+
+  pDelete(&b1);
+*/
+#if 1
+  if (x->root_b==NULL)
+  {
+    if (x->root_l<=0) x->root_l=pLength(x->root);
+    x->root_b=kBucketCreate(currRing);
+    kBucketInit(x->root_b,x->root,x->root_l);
+  }
+  number coef;
+  if (y->root_l<=0) y->root_l=pLength(y->root);
+  coef=kBucketPolyRed(x->root_b,y->root,y->root_l,NULL);
+  nDelete(&coef);
+  x->root=kBucketGetLm(x->root_b);
+  if (x->root==NULL)
+  {
+    kBucketDestroy(&x->root_b);
+    x->root_b=NULL;
+    x->root_l=0;
+  }
+#else
+  x->root=ksOldSpolyRed(y->root,x->root,NULL);
+#endif
+//  if (x->root) p_Content(x->root,currRing);
+//  if (x->root) pSimpleContent(x->root,5);
+
+  return 1;
+}
+
+int ReducePoly(Poly *x,poly from,Poly *y)
+{
+  if (!x->root || !y->root)
+    return 0;
+
+/*  poly b1=pDivide(from,y->root);
+
+  number gcd=n_Gcd(pGetCoeff(from),pGetCoeff(y->root),currRing->cf);
+
+  number a1=nDiv(pGetCoeff(y->root),gcd);
+  pGetCoeff(b1)=nDiv(pGetCoeff(from),gcd);
+
+  x->root=pMult_nn(x->root,a1);
+  nDelete(&a1);*/
+
+//  x->root=pMinus_mm_Mult_qq(x->root,b1,y->root);
+//  pDelete(&b1);
+
+  ksOldSpolyTail(y->root,x->root,from,NULL,currRing);
+  y->root_l=0;
+
+  return 1;
+}
+
+void PNF(Poly *p, TreeM *F)
+{
+  if (p->root==NULL) return;
+
+  Poly *f;
+  BOOLEAN done=FALSE;
+  poly temp=p->root;
+
+//  if (TEST_OPT_PROT) { PrintS("r"); mflush(); }
+  int count=0;
+  poly pp=p->root;
+  int old_size=nSize(pGetCoeff(pp));
+  p->root_l=0;
+  while(temp->next)
+  {
+    f=is_div_(F,temp->next);
+    if (f)
+    {
+      if (ReducePoly(p,temp,f)) //temp->next
+      {
+        count++;
+        //if (TEST_OPT_PROT) { PrintS("-"); mflush(); }
+        if ((f!=NULL)
+        && (count>20)
+        && (nSize(pGetCoeff(pp))>old_size)
+        )
+        {
+           //pSimpleContent(pp,2);
+           p_Content(pp,currRing);
+           count=0;
+         //  old_size=nSize(pGetCoeff(pp));
+        }
+      }
+      done=TRUE;
+    }
+    else
+      temp=temp->next;
+   }
+
+  if (done) p_Content(p->root,currRing);
+  //if (done) pSimpleContent(p->root,-1);
+  pTest(p->root);
+}
+
+void NFL(Poly *p, TreeM *F)
+{
+  Poly *f;
+  // int g1,f1,gg;
+
+  if ((f=is_div_(F,p->lead))==NULL) return;
+
+  int pX=pow_(p->lead);
+  int phX=pow_(p->history);
+
+  if (pX!=phX)
+  {
+    int phF=pow_(f->history);
+    if (pX >= (phX+phF))
+    {
+      pDelete(&p->root);
+      //p->root=NULL;
+      return;
+    }
+
+/*    poly p2=pInit();
+    pLcm(p->history,f->history,p2);
+    pSetm(p2);
+
+    if (pLmCmp(p->root,p2) > 0)
+    {
+      pLmDelete(&p2);
+      pDelete(&p->root);
+      //p->root=NULL;
+      return;
+    }
+
+    pLmDelete(&p2);
+*/
+/*    for(int i=0, gg=0 ; i<currRing->N;i++)
+      if ((g1=pGetExp(p->history,i+1)) > (f1=pGetExp(f->history,i+1)))
+        gg+=g1;
+      else gg+=f1;
+
+    if (pX > gg)
+      {
+        pDelete(&p->root);
+        //x->root=NULL;
+        return;
+    }
+*/
+    int pF=pow_(f->lead);
+
+    if ((pX == pF) && (pF == phF))
+    {
+      pLmDelete(&f->history);
+      f->history=pCopy(p->history);
+    }
+  }
+
+  //if (TEST_OPT_PROT) { PrintS("R"); mflush(); }
+  int /*old_size, */count;
+  count=0;
+  while(f && p->root)
+  {
+//    PrintS("R");
+//    if (TEST_OPT_PROT) { PrintS("R"); mflush(); }
+#if 0
+    old_size=nSize(pGetCoeff(p->root));
+#endif
+    if (ReducePolyLead(p,f) == 0) break;
+    if (p->root!=NULL)
+    {
+      count++;
+#if 0
+      if ((count>4) && (3<nSize(pGetCoeff(p->root)))
+      && (nSize(pGetCoeff(p->root))>old_size))
+      {
+        pSimpleContent(p->root,old_size);
+        count=0;
+      }
+#else
+      if (count>50)
+      {
+        kBucketClear(p->root_b,&p->root,&p->root_l);
+        p_SimpleContent(p->root,2,currRing);
+        kBucketInit(p->root_b,p->root,p->root_l);
+        count=0;
+        //PrintS(".");
+      }
+#endif
+      f=is_div_(F,p->root);
+    }
+  }
+#if 1
+  if (p->root_b!=NULL)
+  {
+    kBucketClear(p->root_b,&p->root,&p->root_l);
+    kBucketDestroy(&p->root_b);
+    p->root_b=NULL;
+  }
+#endif
+
+  if (!p->root)
+    return;
+
+  InitHistory(p);
+  InitProl(p);
+  InitLead(p);
+  p->changed=1;
+
+  p_Content(p->root,currRing);
+  //pSimpleContent(p->root,-1);
+  pTest(p->root);
+}
+
+int ValidatePoly(Poly *x, TreeM */*F*/)
+{
+  Poly /*f,*/*g;
+  // int g1,f1;
+
+  if (x->root) return 1;
+
+  g=is_present(T,x->history); //it's a prolongation - do we have a parent ?
+
+  if (!g)  return 0; //if not - kill him !
+
+  poly lmX=pDivide(x->lead,g->root);
+  pGetCoeff(lmX)=nInit(1);
+
+/*  if ((f=is_div_(F,lmX)) != NULL)
+  {
+    int pX=pow_(lmX);
+    int phX=pow_(x->history);
+
+    if (pX!=phX)
+    {
+      int phF=pow_(f->history);
+      if (pX >= (phX+phF))
+      {
+        pLmDelete(&lmX);
+        //x->root=NULL;
+        return 0;
+      }
+
+      for(int i=0, gg=0 ; i<currRing->N;i++)
+        if ((g1=pGetExp(x->history,i+1)) > (f1=pGetExp(f->history,i+1)))
+          gg+=g1;
+        else
+          gg+=f1;
+
+      if (pX > gg)
+      {
+        pLmDelete(&lmX);
+        return 0;
+      }
+      int pF=pow_(f->root);
+
+      if ((pX == pF) && (pF == phF))
+        f->history=x->history;
+    }
+  }
+
+  pLmDelete(&lmX);
+
+*/
+  x->root=pCopy(g->root);
+  x->root_l=g->root_l;
+
+  x->root=pMult(x->root,lmX);
+
+  pTest(x->root);
+
+  x->prolonged=-1;
+
+  return 1;
+}
+
+Poly *NewPoly(poly p)
+{
+  Poly *beg=(Poly *)GCM(sizeof(Poly));
+
+  beg->root=p;//(p == NULL ? pInit() : p);
+  beg->root_b=NULL;
+  beg->root_l=0;
+  beg->history=NULL;//pInit();
+  beg->lead=NULL;
+  beg->mult=(char *)GCMA(sizeof(char)*2*offset);
+
+  for (int i=0; i < currRing->N; i++)
+  {
+    ClearMult(beg,i);
+    ClearProl(beg,i);
+  };
+
+  beg->prolonged=-1;
+
+  return beg;
+}
+
+void DestroyPoly(Poly *x)
+{
+  pDelete(&x->root);
+  pDelete(&x->history);
+  if (x->lead) pDelete(&x->lead);
+  GCF(x->mult);
+  GCF(x);
+}
+
+void ControlProlong(Poly *x)
+{
+  for (int i = 0; i< offset; i++)
+  {
+    (x->mult+offset)[i]&=~((x->mult)[i]);
+//    if (!GetMult(x,i) && !GetProl(x,i))
+//      ProlVar(x,i);
+  }
+}
+
+void InitHistory(Poly *p)
+{
+  if (p->history) pLmDelete(&p->history);
+  p->history=pLmInit(p->root);
+  p->changed=0;
+}
+
+void InitLead(Poly *p)
+{
+  if (p->lead) pLmDelete(&p->lead);
+  p->lead=pLmInit(p->root);
+  p->prolonged=-1;
+}
+
+void InitProl(Poly *p)
+{
+  memset(p->mult+offset,0,sizeof(char)*offset);
+}
+
+int GetMult(Poly *x,int i)
+{
+  return x->mult[i/8] & Mask[i%8];
+}
+
+void SetMult(Poly *x,int i)
+{
+  x->mult[i/8] |= Mask[i%8];
+}
+
+void ClearMult(Poly *x,int i)
+{
+  x->mult[i/8] &= ~Mask[i%8];
+}
+
+int GetProl(Poly *x, int i)
+{
+  return (x->mult+offset)[i/8] & Mask[i%8];
+}
+
+void SetProl(Poly *x, int i)
+{
+  (x->mult+offset)[i/8] |= Mask[i%8];
+}
+
+void ClearProl(Poly *x, int i)
+{
+  (x->mult+offset)[i/8] &= ~Mask[i%8];
+}
+
+int LengthCompare(poly p1,poly p2)
+{
+  do
+  {
+    if (p1 == NULL) return 1;
+    if (p2 == NULL) return 0;
+    pIter(p1);
+    pIter(p2);
+  }while(p1 && p2);
+  return 1;
+}
+
+int ProlCompare(Poly *item1, Poly *item2)
+{
+  switch(pLmCmp(item1->lead,item2->lead))
+  {
+    case -1:
+      return 1;
+
+    case 1:
+      return 0;
+
+    default:
+      if ((item1->root_l<=0)||(item2->root_l<=0))
+        return LengthCompare(item1->root,item2->root);
+      return item1->root_l<=item2->root_l;
+  }
+}
+
+void ProlVar(Poly *temp,int i)
+{
+  Poly *Pr;
+
+  if (!GetProl(temp,i) && !GetMult(temp,i))
+  {
+    Pr=NewPoly();
+    SetProl(temp,i);
+
+    Pr->prolonged=i;
+    Pr->history=pLmInit(temp->history);
+    Pr->lead=pLmInit(temp->lead);
+    pIncrExp(Pr->lead,i+1);
+    pSetm(Pr->lead);
+     InitProl(temp);
+
+     Pr->changed=0;
+//    pTest(Pr->root);
+      InsertInCount(Q,Pr);
+   }
+}
+
+void DestroyListNode(ListNode *x)
+{
+  DestroyPoly(x->info);
+  GCF(x);
+}
+
+ListNode* CreateListNode(Poly *x)
+{
+  ListNode* ret=(ListNode *)GCM(sizeof(ListNode));
+  ret->info=x;
+  ret->next=NULL;
+  return ret;
+}
+
+
+Poly *FindMinList(jList *L)
+{
+  LI min=&(L->root);
+  LI l;
+  LCI xl;
+  Poly *x;
+
+  if (degree_compatible)
+  {
+    while ((*min) && ((*min)->info->root == NULL))
+      min=&((*min)->next);
+  }
+
+  if (!(*min)) return NULL;
+
+  l=&((*min)->next);
+
+  while (*l)
+  {
+    if ((*l)->info->root != NULL)
+    {
+      if (ProlCompare((*l)->info,(*min)->info))
+        min=l;
+    }
+
+    l=&((*l)->next);
+  }
+  x=(*min)->info;
+  xl=*min;
+  *min=(*min)->next;
+  GCF(xl);
+
+  return x;
+}
+
+void InsertInList(jList *x,Poly *y)
+{
+  ListNode *ins;
+  LI ix=&(x->root);
+
+  while (*ix)
+  {
+    if (pLmCmp(y->lead,(*ix)->info->lead) == -1)
+      ix=(ListNode **)&((*ix)->next);
+    else
+      break;
+  }
+
+  ins=CreateListNode(y);
+  ins->next=(ListNode *)(*ix);
+  *ix=ins;
+  return;
+}
+
+void InsertInCount(jList *x,Poly *y)
+{
+  ListNode *ins;
+  LI ix=&(x->root);
+
+  ins=CreateListNode(y);
+  ins->next=(ListNode *)(*ix);
+  *ix=ins;
+  return;
+}
+
+int ListGreatMoveOrder(jList *A,jList *B,poly x)
+{
+  LCI y=A->root;
+
+  if (!y || pLmCmp(y->info->lead,x) < 0) return 0;
+
+  while(y && pLmCmp(y->info->lead,x) >= 0)
+  {
+    InsertInCount(B,y->info);
+    A->root=y->next;
+    GCF(y);
+    y=A->root;
+  }
+
+  return 1;
+}
+
+int ListGreatMoveDegree(jList *A,jList *B,poly x)
+{
+  LCI y=A->root;
+  int pow_x=pow_(x);
+
+  if (!y || pow_(y->info->lead) <= pow_x) return 0;
+
+  while(y && pow_(y->info->lead) > pow_x)
+  {
+    InsertInCount(B,y->info);
+    A->root=y->next;
+    GCF(y);
+    y=A->root;
+  }
+
+  return 1;
+}
+
+int CountList(jList *Q)
+{
+  int i=0;
+  LCI y=Q->root;
+
+  while(y)
+  {
+    i++;
+    y=y->next;
+  }
+
+  return i;
+}
+
+void NFListQ()
+{
+  LCI ll;
+  int p,p1;
+  LI l;
+
+  do
+  {
+    if (!Q->root) break;
+
+    ll=Q->root;
+
+    p=pow_(Q->root->info->lead);
+
+    while (ll)
+    {
+      int ploc=pow_(ll->info->lead);
+      if (ploc < p) p=ploc;
+      ll=ll->next;
+    }
+
+    p1=1;
+
+    l=&(Q->root);
+
+    while (*l)
+    {
+//      PrintS("*");
+      int ploc=pow_((*l)->info->lead);
+
+      if (ploc == p)
+      {
+        if (!ValidatePoly((*l)->info,G))
+        {
+          ll=(*l);
+          *l=(*l)->next;
+          DestroyListNode(ll);
+          continue;
+        };
+
+        (*l)->info->changed=0;
+//        PrintS("!");
+        NFL((*l)->info,G);
+//                                PrintS("$");
+        if (!(*l)->info->root)
+        {
+          ll=(*l);
+          *l=(*l)->next;
+          DestroyListNode(ll);
+          continue;
+        };
+        p1=0;
+      }
+
+      l=&((*l)->next);
+    }
+  }while(p1);
+//  PrintLn();
+}
+
+
+void ForEachPNF(jList *x,int i)
+{
+  LCI y=x->root;
+
+  while(y)
+  {
+    if (pow_(y->info->root) == i) PNF(y->info,G);
+    y=y->next;
+  }
+}
+
+void ForEachControlProlong(jList *x)
+{
+  LCI y=x->root;
+
+  while(y)
+  {
+    ControlProlong(y->info);
+    y=y->next;
+  }
+}
+
+void DestroyList(jList *x)
+{
+  LCI y=x->root,z;
+
+  while(y)
+  {
+    z=y->next;
+    DestroyPoly(y->info);
+    GCF(y);
+    y=z;
+  }
+
+  GCF(x);
+}
+
+Poly* is_present(jList *F,poly x)
+{
+  LCI iF=F->root;
+  while(iF)
+    if (pLmCmp(iF->info->root,x) == 0)
+      return iF->info;
+    else iF=iF->next;
+
+  return NULL;
+}
+
+int GB_length()
+{
+  LCI iT=T->root;
+  int l=0;
+
+  while(iT)
+  {
+    if (pow_(iT->info->lead) == pow_(iT->info->history))
+      ++l;
+    iT=iT->next;
+  }
+
+  return l;
+}
+
+static Poly *temp_l;
+
+NodeM* create()
+{
+  NodeM *y;
+
+  if (FreeNodes == NULL)
+  {
+    y=(NodeM *)GCM(sizeof(NodeM));
+  }
+  else
+  {
+    y=FreeNodes;
+    FreeNodes=FreeNodes->left;
+  }
+
+  y->left=y->right=NULL;
+  y->ended=NULL;
+  return y;
+}
+
+void DestroyFreeNodes()
+{
+  NodeM *y;
+
+  while((y=FreeNodes)!=NULL)
+  {
+    FreeNodes=FreeNodes->left;
+    GCF(y);
+  }
+}
+
+#if 0
+static void go_right(NodeM *current,poly_function disp)
+{
+  if (current)
+  {
+    go_right(current->left,disp);
+    if (current->ended) disp(current->ended);
+    go_right(current->right,disp);
+  }
+}
+
+void ForEach(TreeM *t,poly_function disp)
+{
+  go_right(t->root,disp);
+}
+#endif
+
+void DestroyTree(NodeM *G)
+{
+  if (G)
+  {
+    DestroyTree(G->left);
+    DestroyTree(G->right);
+    G->left=FreeNodes;
+    FreeNodes=G;
+  }
+}
+
+void Define(TreeM **G)
+{
+  *G=(TreeM *)GCM(sizeof(TreeM));
+  (*G)->root=create();
+}
+
+int sp_div(poly m1,poly m2,int from)
+{
+
+  if (pow_(m2) == 0 && pow_(m1)) return 0;
+
+  for(int k=from; k < currRing->N; k++)
+    if (pGetExp(m1,k+1) < pGetExp(m2,k+1)) return 0;
+
+  return 1;
+}
+
+void div_l(poly item, NodeM *x,int from)
+{
+  if (x && !temp_l)
+  {
+    div_l(item,x->left,from);
+    if ((x->ended) && sp_div(item,x->ended->root,from))
+    {
+      temp_l=x->ended;
+      return;
+    };
+    div_l(item,x->right,from);
+  }
+}
+
+Poly* is_div_upper(poly item, NodeM *x,int from)
+{
+  temp_l=NULL;
+  div_l(item,x,from);
+  return temp_l;
+}
+
+Poly* is_div_(TreeM *tree, poly item)
+{
+  int power_tmp,i,i_con=currRing->N-1;
+  NodeM *curr=tree->root;
+
+  if (!curr) return NULL;
+  if (pow_(item) == 0) return NULL;
+
+  for ( ; i_con>=0 && !pGetExp(item,i_con+1) ; i_con--)
+    ;
+
+  for (i=0; i <= i_con ; i++)
+  {
+    power_tmp=pGetExp(item,i+1);
+
+    while (power_tmp)
+    {
+      if (curr->ended) return curr->ended;
+
+      if (!curr->left)
+      {
+        if (curr->right)
+          return is_div_upper(item,curr->right,i); //??????
+        return NULL;
+      }
+
+      curr=curr->left;
+      power_tmp--;
+    }
+
+    if (curr->ended) return curr->ended;
+
+    if (!curr->right) return NULL;
+
+    curr=curr->right;
+  }
+
+  if (curr->ended) return curr->ended;
+  else return NULL;
+}
+
+static void ClearMultiplicative(NodeM *xx,int i)
+{
+  if (!xx) return;
+
+  while (xx->left)
+  {
+    ClearMultiplicative(xx->right, i);
+    xx = xx->left;
+  }
+  if ((xx->ended) && (GetMult(xx->ended,i)))
+  {
+    ClearMult(xx->ended,i);
+    ProlVar(xx->ended,i);
+  }
+  else
+    ClearMultiplicative(xx->right,i);
+}
+//======================================================
+void insert_(TreeM **tree, Poly *item)
+{
+ int power_tmp,i,i_con=currRing->N-1;
+ NodeM *curr=(*tree)->root;
+
+ for ( ; (i_con>=0) && !pGetExp(item->root,i_con+1) ; i_con--)
+  SetMult(item,i_con);
+
+ for (i = 0; i<= i_con; i++)
+ //<=
+ {
+  power_tmp=pGetExp(item->root,i+1);
+
+  ClearMult(item,i);
+
+  while (power_tmp)
+  {
+   if (!curr->left)
+   {
+     SetMult(item,i);
+     ClearMultiplicative(curr->right,i);
+     curr->left=create();
+   };
+   curr=curr->left;
+   power_tmp--;
+  };
+
+  if (i<i_con)
+  {
+   if (!curr->left) SetMult(item,i);
+   if (!curr->right) curr->right=create();
+   curr=curr->right;
+
+   ProlVar(item,i);
+  }
+ }
+
+ curr->ended=item;
+}
+
+void Initialization(char *Ord)
+{
+  offset=(currRing->N % 8 == 0) ? (currRing->N/8)*8 : (currRing->N/8+1)*8;
+  if (strstr(Ord,"dp\0") || strstr(Ord,"Dp\0"))
+  {
+    degree_compatible=1;
+    jDeg=p_Deg;
+    ListGreatMove=ListGreatMoveDegree;
+  }
+  else
+  {
+    degree_compatible=0;
+    jDeg=p_Totaldegree;
+    ListGreatMove=ListGreatMoveOrder;
+  }
+
+  Define(&G);
+}
+
+static Poly *h/*,*f*/;
+
+#if 0
+void insert_in_G(Poly *x)
+{
+ insert_(&G,x);
+}
+#endif
+
+void T2G();
+
+#if 0
+void Q2TG()
+{
+  LCI t;
+  Poly *x;
+
+  while (Q->root)
+  {
+    t=Q->root;
+    x=t->info;
+    insert_(&G,x);
+    InsertInList(T,x);
+    Q->root=t->next;
+    GCF(t);
+  }
+}
+#endif
+
+int ComputeBasis(jList *_lT,jList *_lQ)
+{
+  // int gb_l,i,ret_value=1;
+
+  T=_lT; Q=_lQ;
+
+//  Debug();
+
+  while((h=FindMinList(Q))!=NULL)
+  {
+//        PrintS("New element\n");
+//  Debug();
+
+        if (!degree_compatible)
+        {
+          if (!ValidatePoly(h,G))
+          {
+            DestroyPoly(h);
+            continue;
+          }
+
+          h->changed=0;
+
+          NFL(h,G);
+
+          if (!h->root)
+          {
+            DestroyPoly(h);
+            continue;
+          }
+        }
+
+        if (h->root)
+        {
+          if (pIsConstant(h->root))
+          {
+            WarnS("Constant in basis\n");
+            return 0;
+          }
+
+          if (h->changed && ListGreatMove(T,Q,h->root))
+          {
+//      PrintS("<-\n");
+            DestroyTree(G->root);
+            G->root=create();
+            T2G();
+          }
+        }
+
+//  PrintS("PNF\n");
+        PNF(h,G);
+//        Print("{%d}\n",pow_(h->root));
+        insert_(&G,h);
+        InsertInList(T,h);
+
+//  PrintS("For each PNF\n");
+        if (degree_compatible)
+            ForEachPNF(T,pow_(h->root));
+
+//  PrintS("Control of prolongations\n");
+        if (h->changed)
+            ForEachControlProlong(T);
+        else
+            ControlProlong(h);
+
+//  Debug();
+
+//  PrintS("NFListQ\n");
+        if (degree_compatible)
+            NFListQ();
+//Debug();
+    }
+
+//    gb_l=GB_length();
+
+    Print("Length of Janet basis: %d\n",CountList(T));
+//    Print("Length of Groebner basis:    %d\n",gb_l);
+
+    DestroyTree(G->root);
+    GCF(G);
+    DestroyFreeNodes();
+
+    return 1;
+}
+
+void T2G()
+{
+ LCI i=T->root;
+ while (i)
+ {
+  insert_(&G,i->info);
+  i=i->next;
+ }
+}
diff --git a/kernel/GBEngine/janet.h b/kernel/GBEngine/janet.h
new file mode 100644
index 0000000..27f254d
--- /dev/null
+++ b/kernel/GBEngine/janet.h
@@ -0,0 +1,101 @@
+#ifndef __JANET_INTERFACE__
+#define __JANET_INTERFACE__
+
+#include <kernel/structs.h>
+
+#define GCM(sz) omAlloc((sz))
+#define GCMA(sz) omAlloc((sz))
+#define GCF(x) omFree((x))
+
+#define ListNode struct LISTNODE
+#define TreeM struct TREEM
+#define NodeM struct NODEM
+
+typedef struct
+{
+  poly root; //poly for parent, NULL for prol
+  kBucket_pt root_b;
+  int root_l;
+  poly history; //parent
+  poly lead; //leading monomial for prolongation
+  char *mult; //[multi].[prol]
+  int changed;
+  int prolonged; //number of prolonged variable for prolongation, otherwise = -1;
+} Poly;
+
+typedef void (*poly_function)(Poly *);
+
+ListNode
+{
+ Poly *info;
+ ListNode *next;
+};
+
+typedef struct
+{
+ ListNode *root;
+} jList;
+
+NodeM
+{
+ NodeM *left,*right;
+ Poly *ended;
+};
+
+TreeM
+{
+ NodeM *root;
+};
+
+typedef ListNode* LCI;
+typedef ListNode** LI;
+
+//-------FUNCS----------
+Poly* FindMinList(jList *);
+void DestroyTree(NodeM *);
+NodeM* create();
+//void ForEach(TreeM *,poly_function);
+void ControlProlong(Poly *);
+Poly* is_div_(TreeM *root, poly item);
+void insert_(TreeM **tree, Poly *item);
+Poly* NewPoly(poly p=NULL);
+void DestroyPoly();
+
+void NFL(Poly *,TreeM *);
+void PNF(Poly *,TreeM *);
+void ClearProl(Poly *x, int i);
+void InitProl(Poly *p);
+void InitHistory(Poly *p);
+Poly *is_present(jList *,poly);
+int GetMult(Poly *,int);
+int GB_length();
+
+void InsertInList(jList *,Poly *);
+void ForEachPNF(jList *,int);
+void ClearMult(Poly *,int);
+void ProlVar(Poly *,int);
+void SetMult(Poly *,int);
+void InitLead(Poly *);
+void InsertInCount(jList *,Poly *);
+int GetProl(Poly *, int);
+void SetProl(Poly *, int);
+int ProlCompare(Poly *, Poly *);
+int ValidatePoly(Poly *,TreeM *);
+int ListGreatMoveDegree(jList *,jList *,poly);
+int ListGreatMoveOrder(jList *,jList *,poly);
+void ForEachControlProlong(jList *);
+void NFListQ();
+int CountList(jList *);
+void DestroyList(jList *);
+
+int ReducePoly(Poly *x,Poly *y);
+int ReducePolyLead(Poly *x,Poly *y);
+void Define(TreeM **G);
+ListNode* CreateListNode(Poly *x);
+void DestroyListNode(ListNode *x);
+void DestroyFreeNodes();
+
+int ComputeBasis(jList *,jList *);
+void Initialization(char *);
+
+#endif //JANET_INTERFACE
diff --git a/kernel/GBEngine/kInline.h b/kernel/GBEngine/kInline.h
new file mode 100644
index 0000000..bf47f58
--- /dev/null
+++ b/kernel/GBEngine/kInline.h
@@ -0,0 +1,1164 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    kInline.h
+ *  Purpose: implementation of std related inline routines
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 8/00
+ *******************************************************************/
+#ifndef KINLINE_H
+#define KINLINE_H
+
+#if !defined(NO_KINLINE) || defined(KUTIL_CC)
+/* this file is a header file with inline routines,
+ *     if NO_KINLINE is not defined (AND ONLY THEN!)
+ * otherwise it is an part of kutil.cc and a source file!
+ * (remark: NO_KINLINE is defined by KDEBUG, i.e. in the debug version)
+ */
+
+#include <omalloc/omalloc.h>
+#include <misc/options.h>
+
+#include <polys/monomials/p_polys.h>
+#include <polys/kbuckets.h>
+
+#include <kernel/polys.h>
+
+
+#define HAVE_TAIL_BIN
+// This doesn't really work, fixme, if necessary
+// #define HAVE_LM_BIN
+
+
+
+KINLINE TObject* skStrategy::S_2_T(int i)
+{
+  assume(i>= 0 && i<=sl);
+  assume(S_2_R[i] >= 0 && S_2_R[i] <= tl);
+  TObject* TT = R[S_2_R[i]];
+  assume(TT != NULL && TT->p == S[i]);
+  return TT;
+}
+
+KINLINE TObject* skStrategy::s_2_t(int i)
+{
+  if (i >= 0 && i <= sl)
+  {
+    int sri= S_2_R[i];
+    if ((sri >= 0) && (sri <= tl))
+    {
+      TObject* t = R[sri];
+      if ((t != NULL) && (t->p == S[i]))
+        return t;
+    }
+    // last but not least, try kFindInT
+    sri = kFindInT(S[i], T, tl);
+    if (sri >= 0)
+      return &(T[sri]);
+  }
+  return NULL;
+}
+
+KINLINE poly skStrategy::kNoetherTail()
+{
+  if (tailRing == currRing)
+    return kNoether;
+  else
+  {
+    assume((kNoether == NULL && t_kNoether == NULL) ||
+           (kNoether != NULL && t_kNoether != NULL));
+    return t_kNoether;
+  }
+}
+
+/***************************************************************
+ *
+ * Operation on TObjects
+ *
+ ***************************************************************/
+
+KINLINE TSet initT ()
+{
+  TSet T = (TSet)omAlloc0(setmaxT*sizeof(TObject));
+  for (int i=setmaxT-1; i>=0; i--)
+  {
+    T[i].tailRing = currRing;
+    T[i].i_r = -1;
+  }
+  return T;
+}
+
+KINLINE TObject** initR()
+{
+  return (TObject**) omAlloc0(setmaxT*sizeof(TObject*));
+}
+
+KINLINE unsigned long* initsevT()
+{
+  return (unsigned long*) omAlloc0(setmaxT*sizeof(unsigned long));
+}
+
+// initialization
+KINLINE void sTObject::Set(ring r)
+{
+  tailRing = r;
+}
+KINLINE void sTObject::Init(ring r)
+{
+  memset(this, 0, sizeof(sTObject));
+  i_r = -1;
+  Set(r);
+}
+KINLINE sTObject::sTObject(ring r)
+{
+  Init(r);
+}
+KINLINE void sTObject::Set(poly p_in, ring r)
+{
+  if (r != currRing)
+  {
+    assume(r == tailRing);
+    p_Test(p_in, r);
+    t_p = p_in;
+  }
+  else
+  {
+    pp_Test(p_in, currRing, tailRing);
+    p = p_in;
+  }
+}
+
+KINLINE sTObject::sTObject(poly p_in, ring r)
+{
+  Init(r);
+  Set(p_in, r);
+}
+
+KINLINE void sTObject::Set(poly p_in, ring c_r, ring t_r)
+{
+  if (c_r != t_r)
+  {
+    assume(c_r == currRing && t_r == tailRing);
+    pp_Test(p_in, currRing, t_r);
+    p = p_in;
+  }
+  else
+  {
+    Set(p_in, c_r);
+  }
+}
+
+KINLINE sTObject::sTObject(poly p_in, ring c_r, ring t_r)
+{
+  Init(t_r);
+  Set(p_in, c_r, t_r);
+}
+
+KINLINE sTObject::sTObject(sTObject* T, int copy)
+{
+  *this = *T;
+  if (copy)
+  {
+    if (t_p != NULL)
+    {
+      t_p = p_Copy(t_p, tailRing);
+      p = k_LmInit_tailRing_2_currRing(t_p, tailRing);
+    }
+    else
+    {
+      p = p_Copy(p, currRing, tailRing);
+    }
+  }
+}
+
+KINLINE void sTObject::Delete()
+{
+  if (t_p != NULL)
+  {
+    p_Delete(&t_p, tailRing);
+    if (p != NULL)
+      p_LmFree(p, currRing);
+  }
+  else
+  {
+    p_Delete(&p, currRing, tailRing);
+  }
+}
+
+KINLINE void sTObject::Clear()
+{
+  p = NULL;
+  t_p = NULL;
+  ecart = 0;
+  length = 0;
+  pLength = 0;
+  FDeg = 0;
+  is_normalized = FALSE;
+}
+
+KINLINE void sTObject::Copy()
+{
+  if (t_p != NULL)
+  {
+    t_p = p_Copy(t_p, tailRing);
+    if (p != NULL)
+    {
+      p = p_Head(p, currRing);
+      if (pNext(t_p) != NULL) pNext(p) = pNext(t_p);
+    }
+  }
+  else
+  {
+    p = p_Copy(p, currRing, tailRing);
+  }
+}
+
+KINLINE poly sTObject::GetLmCurrRing()
+{
+  if (p == NULL && t_p != NULL)
+    p = k_LmInit_tailRing_2_currRing(t_p, tailRing);
+
+  return p;
+}
+KINLINE poly sTObject::GetLmTailRing()
+{
+  if (t_p == NULL)
+  {
+    if (p != NULL && tailRing != currRing)
+    {
+      t_p = k_LmInit_currRing_2_tailRing(p, tailRing);
+      return t_p;
+    }
+    return p;
+  }
+  return t_p;
+}
+KINLINE poly sTObject::GetLm(ring r)
+{
+  assume(r == tailRing || r == currRing);
+  if (r == currRing)
+    return GetLmCurrRing();
+
+  if (t_p == NULL && p != NULL)
+    t_p = k_LmInit_currRing_2_tailRing(p, tailRing);
+
+  return t_p;
+}
+
+KINLINE void sTObject::GetLm(poly &p_r, ring &r_r) const
+{
+  if (t_p != NULL)
+  {
+    p_r = t_p;
+    r_r = tailRing;
+  }
+  else
+  {
+    p_r = p;
+    r_r = currRing;
+  }
+}
+
+KINLINE BOOLEAN sTObject::IsNull() const
+{
+  return (p == NULL && t_p == NULL);
+}
+
+KINLINE int sTObject::GetpLength()
+{
+  if (pLength <= 0) pLength = ::pLength(p != NULL ? p : t_p);
+  return pLength;
+}
+
+KINLINE void sTObject::SetLmCurrRing()
+{
+  if (p == NULL && t_p != NULL)
+    p = k_LmInit_tailRing_2_currRing(t_p, tailRing);
+}
+
+KINLINE poly sTObject::Next()
+{
+  assume(p != NULL || t_p != NULL);
+  if (t_p != NULL) return pNext(t_p);
+  return pNext(p);
+}
+
+// Iterations
+KINLINE void sTObject::LmDeleteAndIter()
+{
+  assume(p != NULL || t_p != NULL);
+  if (t_p != NULL)
+  {
+    t_p = p_LmDeleteAndNext(t_p, tailRing);
+    if (p != NULL)
+    {
+      p_LmFree(p, currRing);
+      p = NULL;
+    }
+  }
+  else
+  {
+    p = p_LmDeleteAndNext(p, currRing);
+  }
+  is_normalized = FALSE;
+}
+
+
+// arithmetic
+KINLINE void sTObject::Mult_nn(number n)
+{
+  if (t_p != NULL)
+  {    t_p = p_Mult_nn(t_p, n, tailRing);
+    if (p != NULL) pSetCoeff0(p, pGetCoeff(t_p));
+  }
+  else
+  {
+    p = p_Mult_nn(p, n, currRing, tailRing);
+  }
+}
+
+KINLINE void sLObject::Normalize()
+{
+  if (t_p != NULL)
+  {
+    pNormalize(t_p);
+    if (p != NULL) pSetCoeff0(p, pGetCoeff(t_p));
+  }
+  else
+  {
+    pNormalize(p);
+  }
+}
+
+KINLINE void sLObject::HeadNormalize()
+{
+  if (t_p != NULL)
+  {
+    nNormalize(pGetCoeff(t_p));
+    if (p != NULL) pSetCoeff0(p, pGetCoeff(t_p));
+  }
+  else
+  {
+    nNormalize(pGetCoeff(p));
+  }
+}
+
+KINLINE void
+sTObject::ShallowCopyDelete(ring new_tailRing, omBin new_tailBin,
+                            pShallowCopyDeleteProc p_shallow_copy_delete,
+                            BOOLEAN set_max)
+{
+  if (new_tailBin == NULL) new_tailBin = new_tailRing->PolyBin;
+  if (t_p != NULL)
+  {
+    t_p = p_shallow_copy_delete(t_p, tailRing, new_tailRing, new_tailBin);
+    if (p != NULL)
+      pNext(p) = pNext(t_p);
+    if (new_tailRing == currRing)
+    {
+      if (p == NULL) p = t_p;
+      else p_LmFree(t_p, tailRing);
+      t_p = NULL;
+    }
+  }
+  else if (p != NULL)
+  {
+    if (pNext(p) != NULL)
+    {
+      pNext(p) = p_shallow_copy_delete(pNext(p),
+                                       tailRing, new_tailRing, new_tailBin);
+    }
+    if (new_tailRing != currRing)
+    {
+      t_p = k_LmInit_currRing_2_tailRing(p, new_tailRing);
+      pNext(t_p) = pNext(p);
+    }
+  }
+  if (max != NULL)
+  {
+    if (new_tailRing == currRing)
+    {
+      p_LmFree(max, tailRing);
+      max = NULL;
+    }
+    else
+      max = p_shallow_copy_delete(max,tailRing,new_tailRing,new_tailBin);
+  }
+  else if (set_max && new_tailRing != currRing && pNext(t_p) != NULL)
+  {
+    max = p_GetMaxExpP(pNext(t_p), new_tailRing);
+  }
+  tailRing = new_tailRing;
+}
+
+KINLINE long sTObject::pFDeg() const
+{
+  if (p != NULL) return p_FDeg(p, currRing);
+  return tailRing->pFDeg(t_p, tailRing);
+}
+KINLINE long sTObject::pTotalDeg() const
+{
+  if (p != NULL) return p_Totaldegree(p, currRing);
+  return p_Totaldegree(t_p,tailRing);
+}
+KINLINE long sTObject::SetpFDeg()
+{
+  FDeg = this->pFDeg();
+  return FDeg;
+}
+KINLINE long sTObject::GetpFDeg() const
+{
+  assume(FDeg == this->pFDeg());
+  return FDeg;
+}
+KINLINE long sTObject::pLDeg()
+{
+  return tailRing->pLDeg(GetLmTailRing(), &length, tailRing);
+}
+KINLINE long sTObject::SetDegStuffReturnLDeg()
+{
+  FDeg = this->pFDeg();
+  long d = this->pLDeg();
+  ecart = d - FDeg;
+  return d;
+}
+
+//extern void pCleardenom(poly p);
+// extern void pNorm(poly p);
+
+// manipulations
+KINLINE void  sTObject::pCleardenom()
+{
+  assume(p != NULL);
+  if (TEST_OPT_CONTENTSB)
+    {
+      number n;
+      if (t_p != NULL)
+        {
+          p_Cleardenom_n(t_p, tailRing, n);
+          pSetCoeff0(p, pGetCoeff(t_p));
+        }
+      else
+        {
+          p_Cleardenom_n(p, currRing, n);
+        }
+      if (!nIsOne(n))
+        {
+          denominator_list denom=(denominator_list)omAlloc(sizeof(denominator_list_s));
+          denom->n=nInvers(n);
+          denom->next=DENOMINATOR_LIST;
+          DENOMINATOR_LIST=denom;
+        }
+      nDelete(&n);
+    }
+  else
+    {
+      if (t_p != NULL)
+	{
+	  p_ProjectiveUnique(t_p, tailRing);
+	  pSetCoeff0(p, pGetCoeff(t_p));
+	}
+      else
+	{
+#ifdef HAVE_RATGRING
+          p_ProjectiveUnique(p, currRing);
+#else
+          p_ProjectiveUnique(p, currRing);
+#endif
+	}
+    }
+}
+
+KINLINE void sTObject::pNorm() // pNorm seems to be a _bad_ method name...
+{
+  assume(p != NULL);
+  if (! is_normalized)
+  {
+    p_Norm(p, currRing);
+    if (t_p != NULL)
+      pSetCoeff0(t_p, pGetCoeff(p));
+    is_normalized = TRUE;
+  }
+}
+
+
+
+/***************************************************************
+ *
+ * Operation on LObjects
+ *
+ ***************************************************************/
+// Initialization
+KINLINE void sLObject::Clear()
+{
+  sTObject::Clear();
+  sev = 0;
+}
+// Initialization
+KINLINE void sLObject::Delete()
+{
+  sTObject::Delete();
+  if (bucket != NULL)
+    kBucketDeleteAndDestroy(&bucket);
+}
+
+KINLINE void sLObject::Init(ring r)
+{
+  memset(this, 0, sizeof(sLObject));
+  i_r1 = -1;
+  i_r2 = -1;
+  i_r = -1;
+  Set(r);
+}
+KINLINE sLObject::sLObject(ring r)
+{
+  Init(r);
+}
+KINLINE sLObject::sLObject(poly p_in, ring r)
+{
+  Init(r);
+  Set(p_in, r);
+}
+
+KINLINE sLObject::sLObject(poly p_in, ring c_r, ring t_r)
+{
+  Init(t_r);
+  Set(p_in, c_r, t_r);
+}
+
+KINLINE void sLObject::PrepareRed(BOOLEAN use_bucket)
+{
+  if (bucket == NULL)
+  {
+    int l = GetpLength();
+    if (use_bucket && (l > 1))
+    {
+      poly tp = GetLmTailRing();
+      assume(l == ::pLength(tp));
+      bucket = kBucketCreate(tailRing);
+      kBucketInit(bucket, pNext(tp), l-1);
+      pNext(tp) = NULL;
+      if (p != NULL) pNext(p) = NULL;
+      pLength = 0;
+    }
+  }
+}
+
+KINLINE void sLObject::SetLmTail(poly lm, poly p_tail, int p_Length, int use_bucket, ring _tailRing)
+{
+
+  Set(lm, _tailRing);
+  if (use_bucket)
+  {
+    bucket = kBucketCreate(_tailRing);
+    kBucketInit(bucket, p_tail, p_Length);
+    pNext(lm) = NULL;
+    pLength = 0;
+  }
+  else
+  {
+    pNext(lm) = p_tail;
+    pLength = p_Length + 1;
+  }
+}
+
+KINLINE void sLObject::Tail_Mult_nn(number n)
+{
+  if (bucket != NULL)
+  {
+    kBucket_Mult_n(bucket, n);
+  }
+  else
+  {
+    poly _p = (t_p != NULL ? t_p : p);
+    assume(_p != NULL);
+    pNext(_p) = p_Mult_nn(pNext(_p), n, tailRing);
+  }
+}
+
+KINLINE void sLObject::Tail_Minus_mm_Mult_qq(poly m, poly q, int lq,
+                                             poly spNoether)
+{
+  if (bucket != NULL)
+  {
+    kBucket_Minus_m_Mult_p(bucket, m, q, &lq, spNoether);
+  }
+  else
+  {
+    if (lq<=0) lq= ::pLength(q);
+    poly _p = (t_p != NULL ? t_p : p);
+    assume(_p != NULL);
+
+    int lp=pLength-1;
+    pNext(_p) = p_Minus_mm_Mult_qq( pNext(_p), m, q, lp, lq,
+                                    spNoether, tailRing );
+    pLength=lp+1;
+//    tailRing->p_Procs->p_Minus_mm_Mult_qq(pNext(_p), m, q, shorter,spNoether, tailRing, last);
+//    pLength += lq - shorter;
+  }
+}
+
+KINLINE void sLObject::LmDeleteAndIter()
+{
+  sTObject::LmDeleteAndIter();
+  if (bucket != NULL)
+  {
+    poly _p = kBucketExtractLm(bucket);
+    if (_p == NULL)
+    {
+      kBucketDestroy(&bucket);
+      p = t_p = NULL;
+      return;
+    }
+    Set(_p, tailRing);
+  }
+  else
+  {
+    pLength--;
+  }
+}
+
+KINLINE poly sLObject::LmExtractAndIter()
+{
+  poly ret = GetLmTailRing();
+  poly pn;
+
+  assume(p != NULL || t_p != NULL);
+
+  if (bucket != NULL)
+  {
+    pn = kBucketExtractLm(bucket);
+    if (pn == NULL)
+      kBucketDestroy(&bucket);
+  }
+  else
+  {
+    pn = pNext(ret);
+  }
+  pLength--;
+  pNext(ret) = NULL;
+  if (p != NULL && t_p != NULL)
+    p_LmFree(p, currRing);
+
+  Set(pn, tailRing);
+  return ret;
+}
+
+KINLINE poly sLObject::CanonicalizeP()
+{
+  //kTest_L(this);
+  int i = -1;
+
+  if (bucket != NULL)
+    i = kBucketCanonicalize(bucket);
+
+  if (p == NULL)
+    p = k_LmInit_tailRing_2_currRing(t_p, tailRing);
+
+  if (i >= 0) pNext(p) = bucket->buckets[i];
+  return p;
+}
+
+KINLINE poly sLObject::GetTP()
+{
+  //kTest_L(this);
+  poly tp = GetLmTailRing();
+  assume(tp != NULL);
+
+  if (bucket != NULL)
+  {
+    kBucketClear(bucket, &pNext(tp), &pLength);
+    kBucketDestroy(&bucket);
+    pLength++;
+  }
+  return tp;
+}
+
+
+KINLINE poly sLObject::GetP(omBin lmBin)
+{
+  //kTest_L(this);
+  if (p == NULL)
+  {
+    p = k_LmInit_tailRing_2_currRing(t_p, tailRing,
+                                     (lmBin!=NULL?lmBin:currRing->PolyBin));
+    FDeg = pFDeg();
+  }
+  else if (lmBin != NULL && lmBin != currRing->PolyBin)
+  {
+    p = p_LmShallowCopyDelete(p, currRing);
+    FDeg = pFDeg();
+  }
+
+  if (bucket != NULL)
+  {
+    kBucketClear(bucket, &pNext(p), &pLength);
+    kBucketDestroy(&bucket);
+    pLength++;
+    if (t_p != NULL) pNext(t_p) = pNext(p);
+  }
+  //kTest_L(this);
+  return p;
+}
+
+KINLINE void
+sLObject::ShallowCopyDelete(ring new_tailRing,
+                            pShallowCopyDeleteProc p_shallow_copy_delete)
+{
+  if (bucket != NULL)
+    kBucketShallowCopyDelete(bucket, new_tailRing, new_tailRing->PolyBin,
+                             p_shallow_copy_delete);
+  sTObject::ShallowCopyDelete(new_tailRing,
+                              new_tailRing->PolyBin,p_shallow_copy_delete,
+                              FALSE);
+}
+
+KINLINE void sLObject::SetShortExpVector()
+{
+  if (t_p != NULL)
+  {
+    sev = p_GetShortExpVector(t_p, tailRing);
+  }
+  else
+  {
+    sev = p_GetShortExpVector(p, currRing);
+  }
+}
+
+KINLINE void sLObject::Copy()
+{
+  if (bucket != NULL)
+  {
+    int i = kBucketCanonicalize(bucket);
+    kBucket_pt new_bucket = kBucketCreate(tailRing);
+    kBucketInit(new_bucket,
+                p_Copy(bucket->buckets[i], tailRing),
+                bucket->buckets_length[i]);
+    bucket = new_bucket;
+    if (t_p != NULL) pNext(t_p) = NULL;
+    if (p != NULL) pNext(p) = NULL;
+  }
+  TObject::Copy();
+}
+
+KINLINE poly sLObject::CopyGetP()
+{
+  if (bucket != NULL)
+  {
+    int i = kBucketCanonicalize(bucket);
+    poly bp = p_Copy(bucket->buckets[i], tailRing);
+    pLength = bucket->buckets_length[i] + 1;
+    if (bp != NULL)
+    {
+      assume(t_p != NULL || p != NULL);
+      if (t_p != NULL) pNext(t_p) = bp;
+      else pNext(p) = bp;
+    }
+    bucket = NULL;
+  }
+  return sLObject::GetP();
+}
+
+
+KINLINE long sLObject::pLDeg()
+{
+  poly tp = GetLmTailRing();
+  assume(tp != NULL);
+  if (bucket != NULL)
+  {
+    int i = kBucketCanonicalize(bucket);
+    pNext(tp) = bucket->buckets[i];
+    long ldeg = tailRing->pLDeg(tp, &length, tailRing);
+    pNext(tp) = NULL;
+    return ldeg;
+  }
+  else
+    return tailRing->pLDeg(tp, &length, tailRing);
+}
+KINLINE long sLObject::pLDeg(BOOLEAN deg_last)
+{
+  if (! deg_last || bucket != NULL) return sLObject::pLDeg();
+
+  long ldeg;
+  ldeg = tailRing->pLDeg(GetLmTailRing(), &length, tailRing);
+#ifdef HAVE_ASSUME
+  if ( pLength == 0)
+    p_Last(GetLmTailRing(), pLength, tailRing);
+  assume ( pLength == length || rIsSyzIndexRing(currRing));
+#else
+  pLength=length;
+#endif
+  return ldeg;
+}
+
+KINLINE long sLObject::SetDegStuffReturnLDeg()
+{
+  FDeg = this->pFDeg();
+  long d = this->pLDeg();
+  ecart = d - FDeg;
+  return d;
+}
+KINLINE long sLObject::SetDegStuffReturnLDeg(BOOLEAN use_last)
+{
+  FDeg = this->pFDeg();
+  long d = this->pLDeg(use_last);
+  ecart = d - FDeg;
+  return d;
+}
+KINLINE int sLObject::GetpLength()
+{
+  if (bucket == NULL)
+    return sTObject::GetpLength();
+  int i = kBucketCanonicalize(bucket);
+  return bucket->buckets_length[i] + 1;
+}
+KINLINE int sLObject::SetLength(BOOLEAN length_pLength)
+{
+  if (length_pLength)
+  {
+    length = this->GetpLength();
+  }
+  else
+    this->pLDeg();
+  return length;
+}
+KINLINE long sLObject::MinComp()
+{
+  poly tp = GetLmTailRing();
+  assume(tp != NULL);
+  if (bucket != NULL)
+  {
+    int i = kBucketCanonicalize(bucket);
+    pNext(tp) = bucket->buckets[i];
+    long m = p_MinComp(tp, tailRing);
+    pNext(tp) = NULL;
+    return m;
+  }
+  else
+    return p_MinComp(tp, tailRing);
+}
+KINLINE long sLObject::Comp()
+{
+  poly pp;
+  ring r;
+  GetLm(pp, r);
+  assume(pp != NULL);
+  return p_GetComp(pp, r);
+}
+
+KINLINE sLObject& sLObject::operator=(const sTObject& t)
+{
+  memset(this, 0, sizeof(*this));
+  memcpy(this, &t, sizeof(sTObject));
+  return *this;
+}
+
+KINLINE TObject* sLObject::T_1(const skStrategy* s)
+{
+  if (p1 == NULL) return NULL;
+  if (i_r1 == -1) i_r1 = kFindInT(p1, s->T, s->tl);
+  assume(i_r1 >= 0 && i_r1 <= s->tl);
+  TObject* T = s->R[i_r1];
+  assume(T->p == p1);
+  return T;
+}
+
+KINLINE TObject* sLObject::T_2(const skStrategy* strat)
+{
+  if (p1 == NULL) return NULL;
+  assume(p2 != NULL);
+  if (i_r2 == -1) i_r2 = kFindInT(p2, strat->T, strat->tl);
+  assume(i_r2 >= 0 && i_r2 <= strat->tl);
+  TObject* T = strat->R[i_r2];
+  assume(T->p == p2);
+  return T;
+}
+
+KINLINE void    sLObject::T_1_2(const skStrategy* strat,
+                                TObject* &T_1, TObject* &T_2)
+{
+  if (p1 == NULL)
+  {
+    T_1 = NULL;
+    T_2 = NULL;
+    return;
+  }
+  assume(p1 != NULL && p2 != NULL);
+  if (i_r1 == -1) i_r1 = kFindInT(p1, strat->T, strat->tl);
+  if (i_r2 == -1) i_r2 = kFindInT(p2, strat->T, strat->tl);
+  assume(i_r1 >= 0 && i_r1 <= strat->tl);
+  assume(i_r2 >= 0 && i_r2 <= strat->tl);
+  T_1 = strat->R[i_r1];
+  T_2 = strat->R[i_r2];
+  assume(T_1->p == p1);
+  assume(T_2->p == p2);
+  return;
+}
+
+/***************************************************************
+ *
+ * Conversion of polys
+ *
+ ***************************************************************/
+
+KINLINE poly k_LmInit_currRing_2_tailRing(poly p, ring tailRing, omBin tailBin)
+{
+
+  poly np = p_LmInit(p, currRing, tailRing, tailBin);
+  pNext(np) = pNext(p);
+  pSetCoeff0(np, pGetCoeff(p));
+  return np;
+}
+
+KINLINE poly k_LmInit_tailRing_2_currRing(poly p, ring tailRing, omBin lmBin)
+{
+  poly np = p_LmInit(p, tailRing, currRing, lmBin);
+  pNext(np) = pNext(p);
+  pSetCoeff0(np, pGetCoeff(p));
+  return np;
+}
+
+// this should be made more efficient
+KINLINE poly k_LmShallowCopyDelete_currRing_2_tailRing(poly p, ring tailRing, omBin tailBin)
+{
+  poly np = k_LmInit_currRing_2_tailRing(p, tailRing, tailBin);
+  p_LmFree(p, currRing);
+  return np;
+}
+
+KINLINE poly k_LmShallowCopyDelete_tailRing_2_currRing(poly p, ring tailRing, omBin lmBin)
+{
+  poly np = k_LmInit_tailRing_2_currRing(p, tailRing, lmBin);
+  p_LmFree(p, tailRing);
+  return np;
+}
+
+KINLINE poly k_LmInit_currRing_2_tailRing(poly p, ring tailRing)
+{
+  return k_LmInit_currRing_2_tailRing(p, tailRing, tailRing->PolyBin);
+}
+
+KINLINE poly k_LmInit_tailRing_2_currRing(poly p, ring tailRing)
+{
+  return  k_LmInit_tailRing_2_currRing(p, tailRing, currRing->PolyBin);
+}
+
+KINLINE poly k_LmShallowCopyDelete_currRing_2_tailRing(poly p, ring tailRing)
+{
+  return k_LmShallowCopyDelete_currRing_2_tailRing(p, tailRing, tailRing->PolyBin);
+}
+
+KINLINE poly k_LmShallowCopyDelete_tailRing_2_currRing(poly p, ring tailRing)
+{
+  return  k_LmShallowCopyDelete_tailRing_2_currRing(p, tailRing, currRing->PolyBin);
+}
+
+/***************************************************************
+ *
+ * Lcm business
+ *
+ ***************************************************************/
+// get m1 = LCM(LM(p1), LM(p2))/LM(p1)
+//     m2 = LCM(LM(p1), LM(p2))/LM(p2)
+KINLINE BOOLEAN k_GetLeadTerms(const poly p1, const poly p2, const ring p_r,
+                               poly &m1, poly &m2, const ring m_r)
+{
+  p_LmCheckPolyRing(p1, p_r);
+  p_LmCheckPolyRing(p2, p_r);
+
+  int i;
+  long x;
+  m1 = p_Init(m_r);
+  m2 = p_Init(m_r);
+
+  for (i = p_r->N; i; i--)
+  {
+    x = p_GetExpDiff(p1, p2, i, p_r);
+    if (x > 0)
+    {
+      if (x > (long) m_r->bitmask) goto false_return;
+      p_SetExp(m2,i,x, m_r);
+      p_SetExp(m1,i,0, m_r);
+    }
+    else
+    {
+      if (-x > (long) m_r->bitmask) goto false_return;
+      p_SetExp(m1,i,-x, m_r);
+      p_SetExp(m2,i,0, m_r);
+    }
+  }
+
+  p_Setm(m1, m_r);
+  p_Setm(m2, m_r);
+  return TRUE;
+
+  false_return:
+  p_LmFree(m1, m_r);
+  p_LmFree(m2, m_r);
+  m1 = m2 = NULL;
+  return FALSE;
+}
+
+#ifdef HAVE_RINGS
+// get m1 = LCM(LM(p1), LM(p2))/LM(p1)
+//     m2 = LCM(LM(p1), LM(p2))/LM(p2)   in tailRing
+//    lcm = LCM(LM(p1), LM(p2))          in leadRing
+KINLINE void k_GetStrongLeadTerms(const poly p1, const poly p2, const ring leadRing,
+                               poly &m1, poly &m2, poly &lcm, const ring tailRing)
+{
+  p_LmCheckPolyRing(p1, leadRing);
+  p_LmCheckPolyRing(p2, leadRing);
+
+  int i;
+  int x;
+  int e1;
+  int e2;
+  int s;
+  m1 = p_Init(tailRing);
+  m2 = p_Init(tailRing);
+  lcm = p_Init(leadRing);
+
+  for (i = leadRing->N; i>=0; i--)
+  {
+    e1 = p_GetExp(p1,i,leadRing);
+    e2 = p_GetExp(p2,i,leadRing);
+    x = e1 - e2;
+    if (x > 0)
+    {
+      p_SetExp(m2,i,x, tailRing);
+      //p_SetExp(m1,i,0, tailRing); // done by p_Init
+      s = e1;
+    }
+    else if (x<0)
+    {
+      p_SetExp(m1,i,-x, tailRing);
+      //p_SetExp(m2,i,0, tailRing); // done by p_Init
+      s = e2;
+    }
+    else
+      s = e1; // e1==e2
+    p_SetExp(lcm,i,s, leadRing);
+  }
+
+  p_Setm(m1, tailRing);
+  p_Setm(m2, tailRing);
+  p_Setm(lcm, leadRing);
+}
+#endif
+
+/***************************************************************
+ *
+ * Misc things
+ *
+ ***************************************************************/
+KINLINE int ksReducePolyTail(LObject* PR, TObject* PW, LObject* Red)
+{
+  BOOLEAN ret;
+  number coef;
+
+  assume(PR->GetLmCurrRing() != PW->GetLmCurrRing());
+  Red->HeadNormalize();
+  ret = ksReducePoly(Red, PW, NULL, &coef);
+
+  if (!ret)
+  {
+    if (! n_IsOne(coef, currRing->cf))
+    {
+      PR->Mult_nn(coef);
+      // HANNES: mark for Normalize
+    }
+    n_Delete(&coef, currRing->cf);
+  }
+  return ret;
+}
+
+/***************************************************************
+ *
+ * Routines for backwards-Compatibility
+ *
+ *
+ ***************************************************************/
+KINLINE poly ksOldSpolyRed(poly p1, poly p2, poly spNoether)
+{
+  LObject L(p2);
+  TObject T(p1);
+
+  ksReducePoly(&L, &T, spNoether);
+
+  return L.GetLmCurrRing();
+}
+
+KINLINE poly ksOldSpolyRedNew(poly p1, poly p2, poly spNoether)
+{
+  LObject L(p_Copy(p2, currRing));
+  TObject T(p1);
+
+  ksReducePoly(&L, &T, spNoether);
+
+  return L.GetLmCurrRing();
+}
+
+KINLINE poly ksOldCreateSpoly(poly p1, poly p2, poly spNoether, ring r)
+{
+  LObject L(r);
+  L.p1 = p1;
+  L.p2 = p2;
+
+  ksCreateSpoly(&L, spNoether);
+  return L.GetLmCurrRing();
+}
+
+void ksOldSpolyTail(poly p1, poly q, poly q2, poly spNoether, ring r)
+{
+  LObject L(q,  currRing, r);
+  TObject T(p1, currRing, r);
+
+  ksReducePolyTail(&L, &T, q2, spNoether);
+}
+
+KINLINE poly redtailBba (poly p,int pos,kStrategy strat,BOOLEAN normalize)
+{
+  LObject L(p, currRing, strat->tailRing);
+  return redtailBba(&L, pos, strat,FALSE, normalize);
+}
+
+#ifdef HAVE_RINGS
+KINLINE poly redtailBba_Z (poly p,int pos,kStrategy strat)
+{
+  LObject L(p, currRing, strat->tailRing);
+  return redtailBba_Z(&L, pos, strat);
+}
+#endif
+
+KINLINE poly redtailBba(TObject *T, int pos,kStrategy strat)
+{
+  LObject L;
+  L = *T;
+  poly p = redtailBba(&L, pos, strat, FALSE);
+  *T = L;
+  //kTest_T(T);
+  assume( p == T->p);
+  return p;
+}
+
+KINLINE void clearS (poly p, unsigned long p_sev, int* at, int* k,
+                    kStrategy strat)
+{
+  assume(p_sev == pGetShortExpVector(p));
+  if (strat->noClearS) return;
+  if (!pLmShortDivisibleBy(p,p_sev, strat->S[*at], ~ strat->sevS[*at])) return;
+  deleteInS((*at),strat);
+  (*at)--;
+  (*k)--;
+}
+
+// dummy function for function pointer strat->rewCrit being usable in all
+// possible choices for criteria
+KINLINE BOOLEAN arriRewDummy(poly /*sig*/, unsigned long /*not_sevSig*/, poly /*lm*/, kStrategy /*strat*/, int /*start=0*/)
+{
+  return FALSE;
+}
+
+#endif // defined(KINLINE) || defined(KUTIL_CC)
+#endif // KINLINE_H
diff --git a/kernel/GBEngine/khstd.cc b/kernel/GBEngine/khstd.cc
new file mode 100644
index 0000000..401d676
--- /dev/null
+++ b/kernel/GBEngine/khstd.cc
@@ -0,0 +1,208 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT:utils for hilbert driven kStd
+*/
+
+
+
+
+
+#include <kernel/mod2.h>
+
+#include <misc/options.h>
+#include <misc/intvec.h>
+
+#include <polys/simpleideals.h>
+
+#include <kernel/combinatorics/stairc.h>
+#include <kernel/combinatorics/hilb.h>
+
+#include <kernel/GBEngine/kutil.h>
+#include <kernel/GBEngine/kstd1.h>
+#include <kernel/GBEngine/khstd.h>
+
+#include <kernel/polys.h>
+
+#define ADIDEBUG 0
+
+
+/*2
+* compare the given hilbert series with the current one,
+* delete not needed pairs (if possible)
+*/
+void khCheck( ideal Q, intvec *w, intvec *hilb, int &eledeg, int &count,
+              kStrategy strat)
+  /* ideal S=strat->Shdl, poly p=strat->P.p */
+/*
+* compute the number eledeg of elements with a degree >= deg(p) going into kStd,
+* p is already in S and for all further q going into S yields deg(q) >= deg(p),
+* the real computation is only done if the degree has changed,
+* then we have eledeg == 0 on this degree and we make:
+*   - compute the Hilbert series newhilb from S
+*     (hilb is the final Hilbert series)
+*   - in module case: check that all comp up to strat->ak are used
+*   - compute the eledeg from newhilb-hilb for the first degree deg with
+*     newhilb-hilb != 0
+*     (Remark: consider the Hilbert series with coeff. up to infinity)
+*   - clear the set L for degree < deg
+* the number count is only for statistics (in the caller initialise count = 0),
+* in order to get a first computation, initialise eledeg = 1 in the caller.
+* The weights w are needed in the module case, otherwise NULL.
+*/
+{
+  intvec *newhilb;
+  int deg,l,ln,mw;
+  pFDegProc degp;
+
+  eledeg--;
+  if (eledeg == 0)
+  {
+    if (strat->ak>0)
+    {
+      char *used_comp=(char*)omAlloc0(strat->ak+1);
+      int i;
+      for(i=strat->sl;i>0;i--)
+      {
+        used_comp[pGetComp(strat->S[i])]='\1';
+      }
+      for(i=strat->ak;i>0;i--)
+      {
+        if(used_comp[i]=='\0')
+        {
+          omFree((ADDRESS)used_comp);
+          return;
+        }
+      }
+      omFree((ADDRESS)used_comp);
+    }
+    degp=currRing->pFDeg;
+    // if weights for variables were given to std computations,
+    // then pFDeg == degp == kHomModDeg (see kStd)
+    if ((degp!=kModDeg) && (degp!=kHomModDeg)) degp=p_Totaldegree;
+    // degp = pWDegree;
+    l = hilb->length()-1;
+    mw = (*hilb)[l];
+    newhilb = hHstdSeries(strat->Shdl,w,strat->kHomW,Q,strat->tailRing);
+    ln = newhilb->length()-1;
+    deg = degp(strat->P.p,currRing)-mw;
+    loop // compare the series in degree deg, try to increase deg -----------
+    {
+      if (deg < ln) // deg may be out of range
+      {
+        if (deg < l)
+          eledeg = (*newhilb)[deg]-(*hilb)[deg];
+        else
+          eledeg = (*newhilb)[deg];
+      }
+      else
+      {
+        if (deg < l)
+          eledeg = -(*hilb)[deg];
+        else // we have newhilb = hilb
+        {
+          while (strat->Ll>=0)
+          {
+            count++;
+            if(TEST_OPT_PROT)
+            {
+              PrintS("h");
+              mflush();
+            }
+            deleteInL(strat->L,&strat->Ll,strat->Ll,strat);
+          }
+          delete newhilb;
+          return;
+        }
+      }
+      if (eledeg > 0) // elements to delete
+        break;
+      else if (eledeg <0) // strange....see bug_43
+        return;
+      deg++;
+    } /* loop */
+    delete newhilb;
+    while ((strat->Ll>=0) && (degp(strat->L[strat->Ll].p,currRing)-mw < deg)) // the essential step
+    {
+      count++;
+      if(TEST_OPT_PROT)
+      {
+        PrintS("h");
+        mflush();
+      }
+      deleteInL(strat->L,&strat->Ll,strat->Ll,strat);
+    }
+  }
+}
+
+
+void khCheckLocInhom(ideal Q, intvec *w, intvec *hilb, int &count,
+             kStrategy strat)
+
+/*
+This will be used for the local orderings in the case of the inhomogenous ideals.
+Assume f1,...,fs are already in the standard basis. Test if hilb(LM(f1),...,LM(fs),1)
+is equal to the inputed one.
+If no, do nothing.
+If Yes, we know that all polys that we need are already in the standard basis
+so delete all the remaining pairs
+*/
+{
+int i;
+ideal Lm;
+intvec *newhilb;
+
+Lm = id_Head(strat->Shdl,currRing);
+
+newhilb =hHstdSeries(Lm,w,strat->kHomW,Q,currRing); // ,strat->tailRing?
+
+#if ADIDEBUG
+PrintS("\nOriginal\n");
+int   i, j, l, k;
+  if (hilb == NULL)
+    return;
+  l = hilb->length()-1;
+  k = (*hilb)[l];
+  for (i = 0; i < l; i++)
+  {
+    j = (*hilb)[i];
+    if (j != 0)
+    {
+      Print("//  %8d t^%d\n", j, i+k);
+    }
+  }
+  PrintS("\nActual\n");
+  if (newhilb == NULL)
+    return;
+  l = newhilb->length()-1;
+  k = (*newhilb)[l];
+  for (i = 0; i < l; i++)
+  {
+    j = (*newhilb)[i];
+    if (j != 0)
+    {
+      Print("//  %8d t^%d\n", j, i+k);
+    }
+  }
+#endif
+
+if(newhilb->compare(hilb) == 0)
+	{
+		while (strat->Ll>=0)
+          {
+            count++;
+            if(TEST_OPT_PROT)
+            {
+              PrintS("h");
+              mflush();
+            }
+            deleteInL(strat->L,&strat->Ll,strat->Ll,strat);
+          }
+          delete newhilb;
+          return;
+   }
+
+id_Delete(&Lm,currRing);
+
+}
diff --git a/kernel/GBEngine/khstd.h b/kernel/GBEngine/khstd.h
new file mode 100644
index 0000000..901f9dd
--- /dev/null
+++ b/kernel/GBEngine/khstd.h
@@ -0,0 +1,18 @@
+#ifndef KHSTD_H
+#define KHSTD_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT:hilbert driven std
+*/
+
+#include <kernel/structs.h>
+
+void khCheck(ideal Q, intvec *w, intvec *hilb, int &eledeg, int &count,
+             kStrategy strat);
+                        /* ideal S=strat->Shdl, poly p=strat->P.p */
+
+void khCheckLocInhom(ideal Q, intvec *w, intvec *hilb, int &count,
+             kStrategy strat);
+#endif
diff --git a/kernel/GBEngine/kpolys.cc b/kernel/GBEngine/kpolys.cc
new file mode 100644
index 0000000..d8cdeeb
--- /dev/null
+++ b/kernel/GBEngine/kpolys.cc
@@ -0,0 +1,129 @@
+
+
+
+#include <kernel/mod2.h>
+
+#include <omalloc/omalloc.h>
+#include <misc/auxiliary.h>
+
+#include <kernel/polys.h>
+
+
+/* Returns TRUE if
+     * LM(p) | LM(lcm)
+     * LC(p) | LC(lcm) only if ring
+     * Exists i, j:
+         * LE(p, i)  != LE(lcm, i)
+         * LE(p1, i) != LE(lcm, i)   ==> LCM(p1, p) != lcm
+         * LE(p, j)  != LE(lcm, j)
+         * LE(p2, j) != LE(lcm, j)   ==> LCM(p2, p) != lcm
+*/
+BOOLEAN pCompareChain (poly p,poly p1,poly p2,poly lcm, const ring R)
+{
+  int k, j;
+
+  if (lcm==NULL) return FALSE;
+
+  for (j=(R->N); j; j--)
+    if ( p_GetExp(p,j, R) >  p_GetExp(lcm,j, R)) return FALSE;
+  if ( pGetComp(p) !=  pGetComp(lcm)) return FALSE;
+  for (j=(R->N); j; j--)
+  {
+    if (p_GetExp(p1,j, R)!=p_GetExp(lcm,j, R))
+    {
+      if (p_GetExp(p,j, R)!=p_GetExp(lcm,j, R))
+      {
+        for (k=(R->N); k>j; k--)
+        {
+          if ((p_GetExp(p,k, R)!=p_GetExp(lcm,k, R))
+          && (p_GetExp(p2,k, R)!=p_GetExp(lcm,k, R)))
+            return TRUE;
+        }
+        for (k=j-1; k; k--)
+        {
+          if ((p_GetExp(p,k, R)!=p_GetExp(lcm,k, R))
+          && (p_GetExp(p2,k, R)!=p_GetExp(lcm,k, R)))
+            return TRUE;
+        }
+        return FALSE;
+      }
+    }
+    else if (p_GetExp(p2,j, R)!=p_GetExp(lcm,j, R))
+    {
+      if (p_GetExp(p,j, R)!=p_GetExp(lcm,j, R))
+      {
+        for (k=(R->N); k>j; k--)
+        {
+          if ((p_GetExp(p,k, R)!=p_GetExp(lcm,k, R))
+          && (p_GetExp(p1,k, R)!=p_GetExp(lcm,k, R)))
+            return TRUE;
+        }
+        for (k=j-1; k!=0 ; k--)
+        {
+          if ((p_GetExp(p,k, R)!=p_GetExp(lcm,k, R))
+          && (p_GetExp(p1,k, R)!=p_GetExp(lcm,k, R)))
+            return TRUE;
+        }
+        return FALSE;
+      }
+    }
+  }
+  return FALSE;
+}
+
+#ifdef HAVE_RATGRING
+BOOLEAN pCompareChainPart (poly p,poly p1,poly p2,poly lcm, const ring R)
+{
+  int k, j;
+
+  if (lcm==NULL) return FALSE;
+
+  for (j=R->real_var_end; j>=R->real_var_start; j--)
+    if ( p_GetExp(p,j, R) >  p_GetExp(lcm,j, R)) return FALSE;
+  if ( pGetComp(p) !=  pGetComp(lcm)) return FALSE;
+  for (j=R->real_var_end; j>=R->real_var_start; j--)
+  {
+    if (p_GetExp(p1,j, R)!=p_GetExp(lcm,j, R))
+    {
+      if (p_GetExp(p,j, R)!=p_GetExp(lcm,j, R))
+      {
+        for (k=(R->N); k>j; k--)
+        for (k=R->real_var_end; k>j; k--)
+        {
+          if ((p_GetExp(p,k, R)!=p_GetExp(lcm,k, R))
+          && (p_GetExp(p2,k, R)!=p_GetExp(lcm,k, R)))
+            return TRUE;
+        }
+        for (k=j-1; k>=R->real_var_start; k--)
+        {
+          if ((p_GetExp(p,k, R)!=p_GetExp(lcm,k, R))
+          && (p_GetExp(p2,k, R)!=p_GetExp(lcm,k, R)))
+            return TRUE;
+        }
+        return FALSE;
+      }
+    }
+    else if (p_GetExp(p2,j, R)!=p_GetExp(lcm,j, R))
+    {
+      if (p_GetExp(p,j, R)!=p_GetExp(lcm,j, R))
+      {
+        for (k=R->real_var_end; k>j; k--)
+        {
+          if ((p_GetExp(p,k, R)!=p_GetExp(lcm,k, R))
+          && (p_GetExp(p1,k, R)!=p_GetExp(lcm,k, R)))
+            return TRUE;
+        }
+        for (k=j-1; k>=R->real_var_start; k--)
+        {
+          if ((p_GetExp(p,k, R)!=p_GetExp(lcm,k, R))
+          && (p_GetExp(p1,k, R)!=p_GetExp(lcm,k, R)))
+            return TRUE;
+        }
+        return FALSE;
+      }
+    }
+  }
+  return FALSE;
+}
+#endif
+
diff --git a/kernel/GBEngine/kspoly.cc b/kernel/GBEngine/kspoly.cc
new file mode 100644
index 0000000..c0c898a
--- /dev/null
+++ b/kernel/GBEngine/kspoly.cc
@@ -0,0 +1,853 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+*  ABSTRACT -  Routines for Spoly creation and reductions
+*/
+
+// #define PDEBUG 2
+
+
+
+#include <kernel/mod2.h>
+#include <misc/options.h>
+#include <kernel/GBEngine/kutil.h>
+#include <coeffs/numbers.h>
+#include <polys/monomials/p_polys.h>
+#include <polys/templates/p_Procs.h>
+#include <polys/nc/nc.h>
+#ifdef KDEBUG
+#endif
+#ifdef HAVE_RINGS
+#include <kernel/polys.h>
+#endif
+
+#ifdef KDEBUG
+int red_count = 0;
+int create_count = 0;
+// define this if reductions are reported on TEST_OPT_DEBUG
+#define TEST_OPT_DEBUG_RED
+#endif
+
+/***************************************************************
+ *
+ * Reduces PR with PW
+ * Assumes PR != NULL, PW != NULL, Lm(PW) divides Lm(PR)
+ *
+ ***************************************************************/
+int ksReducePoly(LObject* PR,
+                 TObject* PW,
+                 poly spNoether,
+                 number *coef,
+                 kStrategy strat)
+{
+#ifdef KDEBUG
+  red_count++;
+#ifdef TEST_OPT_DEBUG_RED
+  if (TEST_OPT_DEBUG)
+  {
+    Print("Red %d:", red_count); PR->wrp(); Print(" with:");
+    PW->wrp();
+  }
+#endif
+#endif
+  int ret = 0;
+  ring tailRing = PR->tailRing;
+  kTest_L(PR);
+  kTest_T(PW);
+
+  poly p1 = PR->GetLmTailRing();   // p2 | p1
+  poly p2 = PW->GetLmTailRing();   // i.e. will reduce p1 with p2; lm = LT(p1) / LM(p2)
+  poly t2 = pNext(p2), lm = p1;    // t2 = p2 - LT(p2); really compute P = LC(p2)*p1 - LT(p1)/LM(p2)*p2
+  assume(p1 != NULL && p2 != NULL);// Attention, we have rings and there LC(p2) and LC(p1) are special
+  p_CheckPolyRing(p1, tailRing);
+  p_CheckPolyRing(p2, tailRing);
+
+  pAssume1(p2 != NULL && p1 != NULL &&
+           p_DivisibleBy(p2,  p1, tailRing));
+
+  pAssume1(p_GetComp(p1, tailRing) == p_GetComp(p2, tailRing) ||
+           (p_GetComp(p2, tailRing) == 0 &&
+            p_MaxComp(pNext(p2),tailRing) == 0));
+
+#ifdef HAVE_PLURAL
+  if (rIsPluralRing(currRing))
+  {
+    // for the time being: we know currRing==strat->tailRing
+    // no exp-bound checking needed
+    // (only needed if exp-bound(tailring)<exp-b(currRing))
+    if (PR->bucket!=NULL)  nc_kBucketPolyRed(PR->bucket, p2,coef);
+    else
+    {
+      poly _p = (PR->t_p != NULL ? PR->t_p : PR->p);
+      assume(_p != NULL);
+      nc_PolyPolyRed(_p, p2,coef, currRing);
+      if (PR->t_p!=NULL) PR->t_p=_p; else PR->p=_p;
+      PR->pLength=0; // usually not used, GetpLength re-computes it if needed
+    }
+    return 0;
+  }
+#endif
+
+  if (t2==NULL)           // Divisor is just one term, therefore it will
+  {                       // just cancel the leading term
+    PR->LmDeleteAndIter();
+    if (coef != NULL) *coef = n_Init(1, tailRing);
+    return 0;
+  }
+
+  p_ExpVectorSub(lm, p2, tailRing); // Calculate the Monomial we must multiply to p2
+
+  if (tailRing != currRing)
+  {
+    // check that reduction does not violate exp bound
+    while (PW->max != NULL && !p_LmExpVectorAddIsOk(lm, PW->max, tailRing))
+    {
+      // undo changes of lm
+      p_ExpVectorAdd(lm, p2, tailRing);
+      if (strat == NULL) return 2;
+      if (! kStratChangeTailRing(strat, PR, PW)) return -1;
+      tailRing = strat->tailRing;
+      p1 = PR->GetLmTailRing();
+      p2 = PW->GetLmTailRing();
+      t2 = pNext(p2);
+      lm = p1;
+      p_ExpVectorSub(lm, p2, tailRing);
+      ret = 1;
+    }
+  }
+
+  // take care of coef buisness
+  if (! n_IsOne(pGetCoeff(p2), tailRing))
+  {
+    number bn = pGetCoeff(lm);
+    number an = pGetCoeff(p2);
+    int ct = ksCheckCoeff(&an, &bn, tailRing->cf);    // Calculate special LC
+    p_SetCoeff(lm, bn, tailRing);
+    if ((ct == 0) || (ct == 2))
+      PR->Tail_Mult_nn(an);
+    if (coef != NULL) *coef = an;
+    else n_Delete(&an, tailRing);
+  }
+  else
+  {
+    if (coef != NULL) *coef = n_Init(1, tailRing);
+  }
+
+
+  // and finally,
+  PR->Tail_Minus_mm_Mult_qq(lm, t2, PW->GetpLength() - 1, spNoether);
+  assume(PW->GetpLength() == pLength(PW->p != NULL ? PW->p : PW->t_p));
+  PR->LmDeleteAndIter();
+
+  // the following is commented out: shrinking
+#ifdef HAVE_SHIFTBBA_NONEXISTENT
+  if ( (currRing->isLPring) && (!strat->homog) )
+  {
+    // assume? h->p in currRing
+    PR->GetP();
+    poly qq = p_Shrink(PR->p, currRing->isLPring, currRing);
+    PR->Clear(); // does the right things
+    PR->p = qq;
+    PR->t_p = NULL;
+    PR->SetShortExpVector();
+  }
+#endif
+
+#if defined(KDEBUG) && defined(TEST_OPT_DEBUG_RED)
+  if (TEST_OPT_DEBUG)
+  {
+    Print(" to: "); PR->wrp(); Print("\n");
+  }
+#endif
+  return ret;
+}
+
+/***************************************************************
+ *
+ * Reduces PR with PW
+ * Assumes PR != NULL, PW != NULL, Lm(PW) divides Lm(PR)
+ *
+ ***************************************************************/
+int ksReducePolySig(LObject* PR,
+                 TObject* PW,
+                 long /*idx*/,
+                 poly spNoether,
+                 number *coef,
+                 kStrategy strat)
+{
+#ifdef KDEBUG
+  red_count++;
+#ifdef TEST_OPT_DEBUG_RED
+  if (TEST_OPT_DEBUG)
+  {
+    Print("Red %d:", red_count); PR->wrp(); Print(" with:");
+    PW->wrp();
+  }
+#endif
+#endif
+  int ret = 0;
+  ring tailRing = PR->tailRing;
+  kTest_L(PR);
+  kTest_T(PW);
+
+  // signature-based stuff:
+  // checking for sig-safeness first
+  // NOTE: This has to be done in the current ring
+  //
+  /**********************************************
+   *
+   * TODO:
+   * --------------------------------------------
+   * if strat->sbaOrder == 1
+   * Since we are subdividing lower index and
+   * current index reductions it is enough to
+   * look at the polynomial part of the signature
+   * for a check. This should speed-up checking
+   * a lot!
+   * if !strat->sbaOrder == 0
+   * We are not subdividing lower and current index
+   * due to the fact that we are using the induced
+   * Schreyer order
+   *
+   * nevertheless, this different behaviour is
+   * taken care of by is_sigsafe
+   * => one reduction procedure can be used for
+   * both, the incremental and the non-incremental
+   * attempt!
+   * --------------------------------------------
+   *
+   *********************************************/
+  //printf("COMPARE IDX: %ld -- %ld\n",idx,strat->currIdx);
+  if (!PW->is_sigsafe)
+  {
+    poly sigMult = pCopy(PW->sig);   // copy signature of reducer
+//#if 1
+#ifdef DEBUGF5
+    printf("IN KSREDUCEPOLYSIG: \n");
+    pWrite(pHead(f1));
+    pWrite(pHead(f2));
+    pWrite(sigMult);
+    printf("--------------\n");
+#endif
+    p_ExpVectorAddSub(sigMult,PR->GetLmCurrRing(),PW->GetLmCurrRing(),currRing);
+//#if 1
+#ifdef DEBUGF5
+    printf("------------------- IN KSREDUCEPOLYSIG: --------------------\n");
+    pWrite(pHead(f1));
+    pWrite(pHead(f2));
+    pWrite(sigMult);
+    pWrite(PR->sig);
+    printf("--------------\n");
+#endif
+    int sigSafe = p_LmCmp(PR->sig,sigMult,currRing);
+    // now we can delete the copied polynomial data used for checking for
+    // sig-safeness of the reduction step
+//#if 1
+#ifdef DEBUGF5
+    printf("%d -- %d sig\n",sigSafe,PW->is_sigsafe);
+
+#endif
+    //pDelete(&f1);
+    pDelete(&sigMult);
+    // go on with the computations only if the signature of p2 is greater than the
+    // signature of fm*p1
+    if(sigSafe != 1)
+    {
+      PR->is_redundant = TRUE;
+      return 3;
+    }
+    //PW->is_sigsafe  = TRUE;
+  }
+  PR->is_redundant = FALSE;
+  poly p1 = PR->GetLmTailRing();   // p2 | p1
+  poly p2 = PW->GetLmTailRing();   // i.e. will reduce p1 with p2; lm = LT(p1) / LM(p2)
+  poly t2 = pNext(p2), lm = p1;    // t2 = p2 - LT(p2); really compute P = LC(p2)*p1 - LT(p1)/LM(p2)*p2
+  assume(p1 != NULL && p2 != NULL);// Attention, we have rings and there LC(p2) and LC(p1) are special
+  p_CheckPolyRing(p1, tailRing);
+  p_CheckPolyRing(p2, tailRing);
+
+  pAssume1(p2 != NULL && p1 != NULL &&
+      p_DivisibleBy(p2,  p1, tailRing));
+
+  pAssume1(p_GetComp(p1, tailRing) == p_GetComp(p2, tailRing) ||
+      (p_GetComp(p2, tailRing) == 0 &&
+       p_MaxComp(pNext(p2),tailRing) == 0));
+
+#ifdef HAVE_PLURAL
+  if (rIsPluralRing(currRing))
+  {
+    // for the time being: we know currRing==strat->tailRing
+    // no exp-bound checking needed
+    // (only needed if exp-bound(tailring)<exp-b(currRing))
+    if (PR->bucket!=NULL)  nc_kBucketPolyRed(PR->bucket, p2,coef);
+    else
+    {
+      poly _p = (PR->t_p != NULL ? PR->t_p : PR->p);
+      assume(_p != NULL);
+      nc_PolyPolyRed(_p, p2, coef, currRing);
+      if (PR->t_p!=NULL) PR->t_p=_p; else PR->p=_p;
+      PR->pLength=0; // usaully not used, GetpLength re-comoutes it if needed
+    }
+    return 0;
+  }
+#endif
+
+  if (t2==NULL)           // Divisor is just one term, therefore it will
+  {                       // just cancel the leading term
+    PR->LmDeleteAndIter();
+    if (coef != NULL) *coef = n_Init(1, tailRing);
+    return 0;
+  }
+
+  p_ExpVectorSub(lm, p2, tailRing); // Calculate the Monomial we must multiply to p2
+
+  if (tailRing != currRing)
+  {
+    // check that reduction does not violate exp bound
+    while (PW->max != NULL && !p_LmExpVectorAddIsOk(lm, PW->max, tailRing))
+    {
+      // undo changes of lm
+      p_ExpVectorAdd(lm, p2, tailRing);
+      if (strat == NULL) return 2;
+      if (! kStratChangeTailRing(strat, PR, PW)) return -1;
+      tailRing = strat->tailRing;
+      p1 = PR->GetLmTailRing();
+      p2 = PW->GetLmTailRing();
+      t2 = pNext(p2);
+      lm = p1;
+      p_ExpVectorSub(lm, p2, tailRing);
+      ret = 1;
+    }
+  }
+
+  // take care of coef buisness
+  if (! n_IsOne(pGetCoeff(p2), tailRing))
+  {
+    number bn = pGetCoeff(lm);
+    number an = pGetCoeff(p2);
+    int ct = ksCheckCoeff(&an, &bn, tailRing->cf);    // Calculate special LC
+    p_SetCoeff(lm, bn, tailRing);
+    if ((ct == 0) || (ct == 2))
+      PR->Tail_Mult_nn(an);
+    if (coef != NULL) *coef = an;
+    else n_Delete(&an, tailRing);
+  }
+  else
+  {
+    if (coef != NULL) *coef = n_Init(1, tailRing);
+  }
+
+
+  // and finally,
+  PR->Tail_Minus_mm_Mult_qq(lm, t2, PW->GetpLength() - 1, spNoether);
+  assume(PW->GetpLength() == pLength(PW->p != NULL ? PW->p : PW->t_p));
+  PR->LmDeleteAndIter();
+
+  // the following is commented out: shrinking
+#ifdef HAVE_SHIFTBBA_NONEXISTENT
+  if ( (currRing->isLPring) && (!strat->homog) )
+  {
+    // assume? h->p in currRing
+    PR->GetP();
+    poly qq = p_Shrink(PR->p, currRing->isLPring, currRing);
+    PR->Clear(); // does the right things
+    PR->p = qq;
+    PR->t_p = NULL;
+    PR->SetShortExpVector();
+  }
+#endif
+
+#if defined(KDEBUG) && defined(TEST_OPT_DEBUG_RED)
+  if (TEST_OPT_DEBUG)
+  {
+    Print(" to: "); PR->wrp(); Print("\n");
+  }
+#endif
+  return ret;
+}
+
+/***************************************************************
+ *
+ * Creates S-Poly of p1 and p2
+ *
+ *
+ ***************************************************************/
+void ksCreateSpoly(LObject* Pair,   poly spNoether,
+                   int use_buckets, ring tailRing,
+                   poly m1, poly m2, TObject** R)
+{
+#ifdef KDEBUG
+  create_count++;
+#endif
+  kTest_L(Pair);
+  poly p1 = Pair->p1;
+  poly p2 = Pair->p2;
+  Pair->tailRing = tailRing;
+
+  assume(p1 != NULL);
+  assume(p2 != NULL);
+  assume(tailRing != NULL);
+
+  poly a1 = pNext(p1), a2 = pNext(p2);
+  number lc1 = pGetCoeff(p1), lc2 = pGetCoeff(p2);
+  int co=0/*, ct = ksCheckCoeff(&lc1, &lc2, currRing->cf)*/; // gcd and zero divisors
+  (void) ksCheckCoeff(&lc1, &lc2, currRing->cf);
+
+  int l1=0, l2=0;
+
+  if (p_GetComp(p1, currRing)!=p_GetComp(p2, currRing))
+  {
+    if (p_GetComp(p1, currRing)==0)
+    {
+      co=1;
+      p_SetCompP(p1,p_GetComp(p2, currRing), currRing, tailRing);
+    }
+    else
+    {
+      co=2;
+      p_SetCompP(p2, p_GetComp(p1, currRing), currRing, tailRing);
+    }
+  }
+
+  // get m1 = LCM(LM(p1), LM(p2))/LM(p1)
+  //     m2 = LCM(LM(p1), LM(p2))/LM(p2)
+  if (m1 == NULL)
+    k_GetLeadTerms(p1, p2, currRing, m1, m2, tailRing);
+
+  pSetCoeff0(m1, lc2);
+  pSetCoeff0(m2, lc1);  // and now, m1 * LT(p1) == m2 * LT(p2)
+
+  if (R != NULL)
+  {
+    if (Pair->i_r1 == -1)
+    {
+      l1 = pLength(p1) - 1;
+    }
+    else
+    {
+      l1 = (R[Pair->i_r1])->GetpLength() - 1;
+    }
+    if (Pair->i_r2 == -1)
+    {
+      l2 = pLength(p2) - 1;
+    }
+    else
+    {
+      l2 = (R[Pair->i_r2])->GetpLength() - 1;
+    }
+  }
+
+  // get m2 * a2
+  if (spNoether != NULL)
+  {
+    l2 = -1;
+    a2 = tailRing->p_Procs->pp_Mult_mm_Noether(a2, m2, spNoether, l2, tailRing);
+    assume(l2 == pLength(a2));
+  }
+  else
+    a2 = tailRing->p_Procs->pp_Mult_mm(a2, m2, tailRing);
+#ifdef HAVE_RINGS
+  if (!(rField_is_Domain(currRing))) l2 = pLength(a2);
+#endif
+
+  Pair->SetLmTail(m2, a2, l2, use_buckets, tailRing);
+
+  // get m2*a2 - m1*a1
+  Pair->Tail_Minus_mm_Mult_qq(m1, a1, l1, spNoether);
+
+  // Clean-up time
+  Pair->LmDeleteAndIter();
+  p_LmDelete(m1, tailRing);
+
+  if (co != 0)
+  {
+    if (co==1)
+    {
+      p_SetCompP(p1,0, currRing, tailRing);
+    }
+    else
+    {
+      p_SetCompP(p2,0, currRing, tailRing);
+    }
+  }
+
+  // the following is commented out: shrinking
+#ifdef HAVE_SHIFTBBA_NONEXISTENT
+  if (currRing->isLPring)
+  {
+    // assume? h->p in currRing
+    Pair->GetP();
+    poly qq = p_Shrink(Pair->p, currRing->isLPring, currRing);
+    Pair->Clear(); // does the right things
+    Pair->p = qq;
+    Pair->t_p = NULL;
+    Pair->SetShortExpVector();
+  }
+#endif
+
+}
+
+int ksReducePolyTail(LObject* PR, TObject* PW, poly Current, poly spNoether)
+{
+  BOOLEAN ret;
+  number coef;
+  poly Lp =     PR->GetLmCurrRing();
+  poly Save =   PW->GetLmCurrRing();
+
+  kTest_L(PR);
+  kTest_T(PW);
+  pAssume(pIsMonomOf(Lp, Current));
+
+  assume(Lp != NULL && Current != NULL && pNext(Current) != NULL);
+  assume(PR->bucket == NULL);
+
+  LObject Red(pNext(Current), PR->tailRing);
+  TObject With(PW, Lp == Save);
+
+  pAssume(!pHaveCommonMonoms(Red.p, With.p));
+  ret = ksReducePoly(&Red, &With, spNoether, &coef);
+
+  if (!ret)
+  {
+    if (! n_IsOne(coef, currRing))
+    {
+      pNext(Current) = NULL;
+      if (Current == PR->p && PR->t_p != NULL)
+        pNext(PR->t_p) = NULL;
+      PR->Mult_nn(coef);
+    }
+
+    n_Delete(&coef, currRing);
+    pNext(Current) = Red.GetLmTailRing();
+    if (Current == PR->p && PR->t_p != NULL)
+      pNext(PR->t_p) = pNext(Current);
+  }
+
+  if (Lp == Save)
+    With.Delete();
+
+  // the following is commented out: shrinking
+#ifdef HAVE_SHIFTBBA_NONEXISTENT
+  if (currRing->isLPring)
+  {
+    // assume? h->p in currRing
+    PR->GetP();
+    poly qq = p_Shrink(PR->p, currRing->isLPring, currRing);
+    PR->Clear(); // does the right things
+    PR->p = qq;
+    PR->t_p = NULL;
+    PR->SetShortExpVector();
+  }
+#endif
+
+  return ret;
+}
+
+/***************************************************************
+ *
+ * Auxillary Routines
+ *
+ *
+ ***************************************************************/
+
+/*2
+* creates the leading term of the S-polynomial of p1 and p2
+* do not destroy p1 and p2
+* remarks:
+*   1. the coefficient is 0 (nNew)
+*   1. a) in the case of coefficient ring, the coefficient is calculated
+*   2. pNext is undefined
+*/
+//static void bbb() { int i=0; }
+poly ksCreateShortSpoly(poly p1, poly p2, ring tailRing)
+{
+  poly a1 = pNext(p1), a2 = pNext(p2);
+  long c1=p_GetComp(p1, currRing),c2=p_GetComp(p2, currRing);
+  long c;
+  poly m1,m2;
+  number t1 = NULL,t2 = NULL;
+  int cm,i;
+  BOOLEAN equal;
+
+#ifdef HAVE_RINGS
+  BOOLEAN is_Ring=rField_is_Ring(currRing);
+  number lc1 = pGetCoeff(p1), lc2 = pGetCoeff(p2);
+  if (is_Ring)
+  {
+    ksCheckCoeff(&lc1, &lc2, currRing->cf); // gcd and zero divisors
+    if (a1 != NULL) t2 = nMult(pGetCoeff(a1),lc2);
+    if (a2 != NULL) t1 = nMult(pGetCoeff(a2),lc1);
+    while (a1 != NULL && nIsZero(t2))
+    {
+      pIter(a1);
+      nDelete(&t2);
+      if (a1 != NULL) t2 = nMult(pGetCoeff(a1),lc2);
+    }
+    while (a2 != NULL && nIsZero(t1))
+    {
+      pIter(a2);
+      nDelete(&t1);
+      if (a2 != NULL) t1 = nMult(pGetCoeff(a2),lc1);
+    }
+  }
+#endif
+
+  if (a1==NULL)
+  {
+    if(a2!=NULL)
+    {
+      m2=p_Init(currRing);
+x2:
+      for (i = (currRing->N); i; i--)
+      {
+        c = p_GetExpDiff(p1, p2,i, currRing);
+        if (c>0)
+        {
+          p_SetExp(m2,i,(c+p_GetExp(a2,i,tailRing)),currRing);
+        }
+        else
+        {
+          p_SetExp(m2,i,p_GetExp(a2,i,tailRing),currRing);
+        }
+      }
+      if ((c1==c2)||(c2!=0))
+      {
+        p_SetComp(m2,p_GetComp(a2,tailRing), currRing);
+      }
+      else
+      {
+        p_SetComp(m2,c1,currRing);
+      }
+      p_Setm(m2, currRing);
+#ifdef HAVE_RINGS
+      if (is_Ring)
+      {
+          nDelete(&lc1);
+          nDelete(&lc2);
+          nDelete(&t2);
+          pSetCoeff0(m2, t1);
+      }
+      else
+#endif
+        nNew(&(pGetCoeff(m2)));
+      return m2;
+    }
+    else
+    {
+#ifdef HAVE_RINGS
+      if (is_Ring)
+      {
+        nDelete(&lc1);
+        nDelete(&lc2);
+        nDelete(&t1);
+        nDelete(&t2);
+      }
+#endif
+      return NULL;
+    }
+  }
+  if (a2==NULL)
+  {
+    m1=p_Init(currRing);
+x1:
+    for (i = (currRing->N); i; i--)
+    {
+      c = p_GetExpDiff(p2, p1,i,currRing);
+      if (c>0)
+      {
+        p_SetExp(m1,i,(c+p_GetExp(a1,i, tailRing)),currRing);
+      }
+      else
+      {
+        p_SetExp(m1,i,p_GetExp(a1,i, tailRing), currRing);
+      }
+    }
+    if ((c1==c2)||(c1!=0))
+    {
+      p_SetComp(m1,p_GetComp(a1,tailRing),currRing);
+    }
+    else
+    {
+      p_SetComp(m1,c2,currRing);
+    }
+    p_Setm(m1, currRing);
+#ifdef HAVE_RINGS
+    if (is_Ring)
+    {
+      pSetCoeff0(m1, t2);
+      nDelete(&lc1);
+      nDelete(&lc2);
+      nDelete(&t1);
+    }
+    else
+#endif
+      nNew(&(pGetCoeff(m1)));
+    return m1;
+  }
+  m1 = p_Init(currRing);
+  m2 = p_Init(currRing);
+  loop
+  {
+    for (i = (currRing->N); i; i--)
+    {
+      c = p_GetExpDiff(p1, p2,i,currRing);
+      if (c > 0)
+      {
+        p_SetExp(m2,i,(c+p_GetExp(a2,i,tailRing)), currRing);
+        p_SetExp(m1,i,p_GetExp(a1,i, tailRing), currRing);
+      }
+      else
+      {
+        p_SetExp(m1,i,(p_GetExp(a1,i,tailRing)-c), currRing);
+        p_SetExp(m2,i,p_GetExp(a2,i, tailRing), currRing);
+      }
+    }
+    if(c1==c2)
+    {
+      p_SetComp(m1,p_GetComp(a1, tailRing), currRing);
+      p_SetComp(m2,p_GetComp(a2, tailRing), currRing);
+    }
+    else
+    {
+      if(c1!=0)
+      {
+        p_SetComp(m1,p_GetComp(a1, tailRing), currRing);
+        p_SetComp(m2,c1, currRing);
+      }
+      else
+      {
+        p_SetComp(m2,p_GetComp(a2, tailRing), currRing);
+        p_SetComp(m1,c2, currRing);
+      }
+    }
+    p_Setm(m1,currRing);
+    p_Setm(m2,currRing);
+    cm = p_LmCmp(m1, m2,currRing);
+    if (cm!=0)
+    {
+      if(cm==1)
+      {
+        p_LmFree(m2,currRing);
+#ifdef HAVE_RINGS
+        if (is_Ring)
+        {
+          pSetCoeff0(m1, t2);
+          nDelete(&lc1);
+          nDelete(&lc2);
+          nDelete(&t1);
+        }
+        else
+#endif
+          nNew(&(pGetCoeff(m1)));
+        return m1;
+      }
+      else
+      {
+        p_LmFree(m1,currRing);
+#ifdef HAVE_RINGS
+        if (is_Ring)
+        {
+          pSetCoeff0(m2, t1);
+          nDelete(&lc1);
+          nDelete(&lc2);
+          nDelete(&t2);
+        }
+        else
+#endif
+          nNew(&(pGetCoeff(m2)));
+        return m2;
+      }
+    }
+#ifdef HAVE_RINGS
+    if (is_Ring)
+    {
+      equal = nEqual(t1,t2);
+    }
+    else
+#endif
+    {
+      t1 = nMult(pGetCoeff(a2),pGetCoeff(p1));
+      t2 = nMult(pGetCoeff(a1),pGetCoeff(p2));
+      equal = nEqual(t1,t2);
+      nDelete(&t2);
+      nDelete(&t1);
+    }
+    if (!equal)
+    {
+      p_LmFree(m2,currRing);
+#ifdef HAVE_RINGS
+      if (is_Ring)
+      {
+          pSetCoeff0(m1, nSub(t1, t2));
+          nDelete(&lc1);
+          nDelete(&lc2);
+          nDelete(&t1);
+          nDelete(&t2);
+      }
+      else
+#endif
+        nNew(&(pGetCoeff(m1)));
+      return m1;
+    }
+    pIter(a1);
+    pIter(a2);
+#ifdef HAVE_RINGS
+    if (is_Ring)
+    {
+      if (a2 != NULL)
+      {
+        nDelete(&t1);
+        t1 = nMult(pGetCoeff(a2),lc1);
+      }
+      if (a1 != NULL)
+      {
+        nDelete(&t2);
+        t2 = nMult(pGetCoeff(a1),lc2);
+      }
+      while ((a1 != NULL) && nIsZero(t2))
+      {
+        pIter(a1);
+        if (a1 != NULL)
+        {
+          nDelete(&t2);
+          t2 = nMult(pGetCoeff(a1),lc2);
+        }
+      }
+      while ((a2 != NULL) && nIsZero(t1))
+      {
+        pIter(a2);
+        if (a2 != NULL)
+        {
+          nDelete(&t1);
+          t1 = nMult(pGetCoeff(a2),lc1);
+        }
+      }
+    }
+#endif
+    if (a2==NULL)
+    {
+      p_LmFree(m2,currRing);
+      if (a1==NULL)
+      {
+#ifdef HAVE_RINGS
+        if (is_Ring)
+        {
+          nDelete(&lc1);
+          nDelete(&lc2);
+          nDelete(&t1);
+          nDelete(&t2);
+        }
+#endif
+        p_LmFree(m1,currRing);
+        return NULL;
+      }
+      goto x1;
+    }
+    if (a1==NULL)
+    {
+      p_LmFree(m1,currRing);
+      goto x2;
+    }
+  }
+}
diff --git a/kernel/GBEngine/kstd1.cc b/kernel/GBEngine/kstd1.cc
new file mode 100644
index 0000000..a2a0f26
--- /dev/null
+++ b/kernel/GBEngine/kstd1.cc
@@ -0,0 +1,3160 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT:
+*/
+
+// TODO: why the following is here instead of mod2.h???
+
+
+// define if buckets should be used
+#define MORA_USE_BUCKETS
+
+#define MYTEST 0
+
+#define ADIDEBUG 0
+#define ADIDEBUG_NF 0
+
+#include <kernel/mod2.h>
+
+#include <omalloc/omalloc.h>
+
+#include <misc/options.h>
+#include <misc/intvec.h>
+
+#if MYTEST
+#ifdef HAVE_TAIL_RING
+#undef HAVE_TAIL_RING
+#endif /* ifdef HAVE_TAIL_RING */
+#endif /* if MYTEST */
+
+#include <polys/weight.h>
+#include <kernel/polys.h>
+
+#include <kernel/GBEngine/kutil.h>
+#include <kernel/GBEngine/kstd1.h>
+#include <kernel/GBEngine/khstd.h>
+#include <kernel/combinatorics/stairc.h>
+//#include "cntrlc.h"
+#include <kernel/ideals.h>
+//#include "../Singular/ipid.h"
+
+//#include "ipprint.h"
+
+#ifdef HAVE_PLURAL
+#include <polys/nc/nc.h>
+#include <polys/nc/sca.h>
+#include <kernel/GBEngine/nc.h>
+#endif
+
+#include <kernel/GBEngine/kInline.h>
+
+
+/* the list of all options which give a warning by test */
+BITSET kOptions=Sy_bit(OPT_PROT)           /*  0 */
+                |Sy_bit(OPT_REDSB)         /*  1 */
+                |Sy_bit(OPT_NOT_SUGAR)     /*  3 */
+                |Sy_bit(OPT_INTERRUPT)     /*  4 */
+                |Sy_bit(OPT_SUGARCRIT)     /*  5 */
+                |Sy_bit(OPT_REDTHROUGH)
+                |Sy_bit(OPT_OLDSTD)
+                |Sy_bit(OPT_FASTHC)        /* 10 */
+                |Sy_bit(OPT_INTSTRATEGY)   /* 26 */
+                |Sy_bit(OPT_INFREDTAIL)    /* 28 */
+                |Sy_bit(OPT_NOTREGULARITY) /* 30 */
+                |Sy_bit(OPT_WEIGHTM);      /* 31 */
+
+/* the list of all options which may be used by option and test */
+/* defintion of ALL options: libpolys/misc/options.h */
+BITSET validOpts=Sy_bit(0)
+                |Sy_bit(1)
+                |Sy_bit(2) // obachman 10/00: replaced by notBucket
+                |Sy_bit(3)
+                |Sy_bit(4)
+                |Sy_bit(5)
+                |Sy_bit(6)
+//                |Sy_bit(7) obachman 11/00 tossed: 12/00 used for redThrough
+                |Sy_bit(7) // OPT_REDTHROUGH
+                |Sy_bit(8) // obachman 11/00 tossed -> motsak 2011 experimental: OPT_NO_SYZ_MINIM
+                |Sy_bit(9)
+                |Sy_bit(10)
+                |Sy_bit(11)
+                |Sy_bit(12)
+                |Sy_bit(13)
+                |Sy_bit(14)
+                |Sy_bit(15)
+                |Sy_bit(16)
+                |Sy_bit(17)
+                |Sy_bit(18)
+                |Sy_bit(19)
+//                |Sy_bit(20) obachman 11/00 tossed: 12/00 used for redOldStd
+                |Sy_bit(OPT_OLDSTD)
+                |Sy_bit(21)
+                |Sy_bit(22)
+                /*|Sy_bit(23)*/
+                /*|Sy_bit(24)*/
+                |Sy_bit(OPT_REDTAIL)
+                |Sy_bit(OPT_INTSTRATEGY)
+                |Sy_bit(27)
+                |Sy_bit(28)
+                |Sy_bit(29)
+                |Sy_bit(30)
+                |Sy_bit(31);
+
+//static BOOLEAN posInLOldFlag;
+           /*FALSE, if posInL == posInL10*/
+// returns TRUE if mora should use buckets, false otherwise
+static BOOLEAN kMoraUseBucket(kStrategy strat);
+
+static void kOptimizeLDeg(pLDegProc ldeg, kStrategy strat)
+{
+//  if (strat->ak == 0 && !rIsSyzIndexRing(currRing))
+    strat->length_pLength = TRUE;
+//  else
+//    strat->length_pLength = FALSE;
+
+  if ((ldeg == pLDeg0c /*&& !rIsSyzIndexRing(currRing)*/) ||
+      (ldeg == pLDeg0 && strat->ak == 0))
+  {
+    strat->LDegLast = TRUE;
+  }
+  else
+  {
+    strat->LDegLast = FALSE;
+  }
+}
+
+
+static int doRed (LObject* h, TObject* with,BOOLEAN intoT,kStrategy strat)
+{
+  int ret;
+#if KDEBUG > 0
+  kTest_L(h);
+  kTest_T(with);
+#endif
+  // Hmmm ... why do we do this -- polys from T should already be normalized
+  if (!TEST_OPT_INTSTRATEGY)
+    with->pNorm();
+#ifdef KDEBUG
+  if (TEST_OPT_DEBUG)
+  {
+    PrintS("reduce ");h->wrp();PrintS(" with ");with->wrp();PrintLn();
+  }
+#endif
+  if (intoT)
+  {
+    // need to do it exacly like this: otherwise
+    // we might get errors
+    LObject L= *h;
+    L.Copy();
+    h->GetP();
+    h->SetLength(strat->length_pLength);
+    ret = ksReducePoly(&L, with, strat->kNoetherTail(), NULL, strat);
+    if (ret)
+    {
+      if (ret < 0) return ret;
+      if (h->tailRing != strat->tailRing)
+        h->ShallowCopyDelete(strat->tailRing,
+                             pGetShallowCopyDeleteProc(h->tailRing,
+                                                       strat->tailRing));
+    }
+    enterT(*h,strat);
+    *h = L;
+  }
+  else
+    ret = ksReducePoly(h, with, strat->kNoetherTail(), NULL, strat);
+#ifdef KDEBUG
+  if (TEST_OPT_DEBUG)
+  {
+    PrintS("to ");h->wrp();PrintLn();
+  }
+#endif
+  return ret;
+}
+
+int redEcart (LObject* h,kStrategy strat)
+{
+  int i,at,ei,li,ii;
+  int j = 0;
+  int pass = 0;
+  long d,reddeg;
+
+  d = h->GetpFDeg()+ h->ecart;
+  reddeg = strat->LazyDegree+d;
+  h->SetShortExpVector();
+  loop
+  {
+    j = kFindDivisibleByInT(strat->T, strat->sevT, strat->tl, h);
+    if (j < 0)
+    {
+      if (strat->honey) h->SetLength(strat->length_pLength);
+      return 1;
+    }
+
+    ei = strat->T[j].ecart;
+    ii = j;
+
+    if (ei > h->ecart && ii < strat->tl)
+    {
+      li = strat->T[j].length;
+      // the polynomial to reduce with (up to the moment) is;
+      // pi with ecart ei and length li
+      // look for one with smaller ecart
+      i = j;
+      loop
+      {
+        /*- takes the first possible with respect to ecart -*/
+        i++;
+#if 1
+        if (i > strat->tl) break;
+        if ((strat->T[i].ecart < ei || (strat->T[i].ecart == ei &&
+                                        strat->T[i].length < li))
+            &&
+            p_LmShortDivisibleBy(strat->T[i].GetLmTailRing(), strat->sevT[i], h->GetLmTailRing(), ~h->sev, strat->tailRing))
+#else
+          j = kFindDivisibleByInT(strat->T, strat->sevT, strat->tl, h, i);
+        if (j < 0) break;
+        i = j;
+        if (strat->T[i].ecart < ei || (strat->T[i].ecart == ei &&
+                                        strat->T[i].length < li))
+#endif
+        {
+          // the polynomial to reduce with is now
+          ii = i;
+          ei = strat->T[i].ecart;
+          if (ei <= h->ecart) break;
+          li = strat->T[i].length;
+        }
+      }
+    }
+
+    // end of search: have to reduce with pi
+    if (ei > h->ecart)
+    {
+      // It is not possible to reduce h with smaller ecart;
+      // if possible h goes to the lazy-set L,i.e
+      // if its position in L would be not the last one
+      strat->fromT = TRUE;
+      if (!TEST_OPT_REDTHROUGH && strat->Ll >= 0) /*- L is not empty -*/
+      {
+        h->SetLmCurrRing();
+        if (strat->honey && strat->posInLDependsOnLength)
+          h->SetLength(strat->length_pLength);
+        assume(h->FDeg == h->pFDeg());
+        at = strat->posInL(strat->L,strat->Ll,h,strat);
+        if (at <= strat->Ll)
+        {
+          /*- h will not become the next element to reduce -*/
+          enterL(&strat->L,&strat->Ll,&strat->Lmax,*h,at);
+#ifdef KDEBUG
+          if (TEST_OPT_DEBUG) Print(" ecart too big; -> L%d\n",at);
+#endif
+          h->Clear();
+          strat->fromT = FALSE;
+          return -1;
+        }
+      }
+    }
+
+    // now we finally can reduce
+    doRed(h,&(strat->T[ii]),strat->fromT,strat);
+    strat->fromT=FALSE;
+
+    // are we done ???
+    if (h->IsNull())
+    {
+      assume(!rField_is_Ring(currRing));
+      if (h->lcm!=NULL) pLmFree(h->lcm);
+      h->Clear();
+      return 0;
+    }
+
+    // NO!
+    h->SetShortExpVector();
+    h->SetpFDeg();
+    if (strat->honey)
+    {
+      if (ei <= h->ecart)
+        h->ecart = d-h->GetpFDeg();
+      else
+        h->ecart = d-h->GetpFDeg()+ei-h->ecart;
+    }
+    else
+      // this has the side effect of setting h->length
+      h->ecart = h->pLDeg(strat->LDegLast) - h->GetpFDeg();
+#if 0
+    if (strat->syzComp!=0)
+    {
+      if ((strat->syzComp>0) && (h->Comp() > strat->syzComp))
+      {
+        assume(h->MinComp() > strat->syzComp);
+        if (strat->honey) h->SetLength();
+#ifdef KDEBUG
+        if (TEST_OPT_DEBUG) PrintS(" > syzComp\n");
+#endif
+        return -2;
+      }
+    }
+#endif
+    /*- try to reduce the s-polynomial -*/
+    pass++;
+    d = h->GetpFDeg()+h->ecart;
+    /*
+     *test whether the polynomial should go to the lazyset L
+     *-if the degree jumps
+     *-if the number of pre-defined reductions jumps
+     */
+    if (!TEST_OPT_REDTHROUGH && (strat->Ll >= 0)
+        && ((d >= reddeg) || (pass > strat->LazyPass)))
+    {
+      h->SetLmCurrRing();
+      if (strat->honey && strat->posInLDependsOnLength)
+        h->SetLength(strat->length_pLength);
+      assume(h->FDeg == h->pFDeg());
+      at = strat->posInL(strat->L,strat->Ll,h,strat);
+      if (at <= strat->Ll)
+      {
+        int dummy=strat->sl;
+        if (kFindDivisibleByInS(strat, &dummy, h) < 0)
+        {
+          if (strat->honey && !strat->posInLDependsOnLength)
+            h->SetLength(strat->length_pLength);
+          return 1;
+        }
+        enterL(&strat->L,&strat->Ll,&strat->Lmax,*h,at);
+#ifdef KDEBUG
+        if (TEST_OPT_DEBUG) Print(" degree jumped; ->L%d\n",at);
+#endif
+        h->Clear();
+        return -1;
+      }
+    }
+    else if ((TEST_OPT_PROT) && (strat->Ll < 0) && (d >= reddeg))
+    {
+      Print(".%ld",d);mflush();
+      reddeg = d+1;
+      if (h->pTotalDeg()+h->ecart >= strat->tailRing->bitmask)
+      {
+        strat->overflow=TRUE;
+        //Print("OVERFLOW in redEcart d=%ld, max=%ld",d,strat->tailRing->bitmask);
+        h->GetP();
+        at = strat->posInL(strat->L,strat->Ll,h,strat);
+        enterL(&strat->L,&strat->Ll,&strat->Lmax,*h,at);
+        h->Clear();
+        return -1;
+      }
+    }
+  }
+}
+
+int redRiloc (LObject* h,kStrategy strat)
+{
+  int i,at,ei,li,ii;
+  int j = 0;
+  int pass = 0;
+  long d,reddeg;
+
+
+#if ADIDEBUG_NF
+  int iii;
+  PrintLn();
+  PrintS("---------------------------- NEW REDRILOC COMPUTATION ----------------------------");
+  PrintLn();
+  PrintS("    The pair h : "); PrintLn(); PrintLn();
+  PrintS("      p1 = "); p_Write(h->p1,strat->tailRing); PrintLn();
+  PrintS("      p2 = "); p_Write(h->p2,strat->tailRing); PrintLn();
+  PrintS("      p  = "); p_Write(h->p,strat->tailRing); PrintLn();
+  PrintLn();
+  PrintS("    The actual reducer T is: ");
+  if(strat->tl<0)
+    {PrintS(" Empty.\n");
+  else
+  for (iii=0;iii<=strat->tl;iii++)
+  {
+    PrintLn();
+    Print("      T[%i] = ",iii);p_Write(strat->T[iii].p,strat->tailRing);
+    PrintLn();
+  }
+#endif /* ADIDEBUG_NF */
+
+  d = h->GetpFDeg()+ h->ecart;
+  reddeg = strat->LazyDegree+d;
+  h->SetShortExpVector();
+#if ADIDEBUG_NF
+  Print("\n  Searching for a poly in T that divides h (of ecart %i) ...\n",h->ecart);
+#endif
+  loop
+  {
+    j = kFindDivisibleByInT(strat->T, strat->sevT, strat->tl, h);
+#if ADIDEBUG_NF
+    if(j != -1)
+    {
+      ei = strat->T[j].ecart;
+      Print("\n    Found one: T[%i] of ecart %i: ",j,ei);
+      p_Write(strat->T[j].p,strat->tailRing);
+      PrintS("\n    Try to find another with smaller ecart:\n");
+    }
+    else
+    {
+      PrintS("\n    No poly in T divides h.\n");
+    }
+#endif
+    if (j < 0)
+    {
+      if (strat->honey) h->SetLength(strat->length_pLength);
+      return 1;
+    }
+
+    ei = strat->T[j].ecart;
+    ii = j;
+#if ADIDEBUG_NF
+    iii=ii;
+#endif
+    if (ei > h->ecart && ii < strat->tl)
+    {
+      li = strat->T[j].length;
+      // the polynomial to reduce with (up to the moment) is;
+      // pi with ecart ei and length li
+      // look for one with smaller ecart
+      i = j;
+      loop
+      {
+        /*- takes the first possible with respect to ecart -*/
+        i++;
+#if 1
+        if (i > strat->tl) break;
+        if ((strat->T[i].ecart < ei || (strat->T[i].ecart == ei &&
+                                        strat->T[i].length < li))
+            &&
+            p_LmShortDivisibleBy(strat->T[i].GetLmTailRing(), strat->sevT[i], h->GetLmTailRing(), ~h->sev, strat->tailRing))
+#else
+          j = kFindDivisibleByInT(strat->T, strat->sevT, strat->tl, h, i);
+        if (j < 0) break;
+        i = j;
+        if (strat->T[i].ecart < ei || (strat->T[i].ecart == ei &&
+                                        strat->T[i].length < li))
+#endif
+        {
+          // the polynomial to reduce with is now
+          ii = i;
+          ei = strat->T[i].ecart;
+          if (ei <= h->ecart) break;
+          li = strat->T[i].length;
+        }
+      }
+
+#if ADIDEBUG_NF
+      if(iii == ii)
+      {
+        PrintS("\n    None was found.\n");
+      }
+      else
+      {
+        Print("\n    A better one (ecart = %i): T[%i] = ",ei,ii);
+        p_Write(strat->T[ii].p,strat->tailRing);
+        PrintLn();
+      }
+#endif
+    }
+
+    // end of search: have to reduce with pi
+    if (ei > h->ecart)
+    {
+      // It is not possible to reduce h with smaller ecart;
+      // if possible h goes to the lazy-set L,i.e
+      // if its position in L would be not the last one
+      strat->fromT = TRUE;
+      if (!TEST_OPT_REDTHROUGH && strat->Ll >= 0) /*- L is not empty -*/
+      {
+        h->SetLmCurrRing();
+        if (strat->honey && strat->posInLDependsOnLength)
+          h->SetLength(strat->length_pLength);
+        assume(h->FDeg == h->pFDeg());
+        at = strat->posInL(strat->L,strat->Ll,h,strat);
+        if (at <= strat->Ll)
+        {
+          /*- h will not become the next element to reduce -*/
+          enterL(&strat->L,&strat->Ll,&strat->Lmax,*h,at);
+#ifdef KDEBUG
+          if (TEST_OPT_DEBUG) Print(" ecart too big; -> L%d\n",at);
+#endif
+          h->Clear();
+          strat->fromT = FALSE;
+          return -1;
+        }
+      }
+    }
+
+    // now we finally can reduce
+    doRed(h,&(strat->T[ii]),strat->fromT,strat);
+    #if ADIDEBUG_NF
+    PrintS("\n  Partial Reduced h = ");p_Write(h->p,strat->tailRing);
+    PrintLn();
+    #endif
+    strat->fromT=FALSE;
+
+    // are we done ???
+    if (h->IsNull())
+    {
+      if (h->lcm!=NULL) pLmDelete(h->lcm);
+      h->Clear();
+      return 0;
+    }
+
+    // NO!
+    h->SetShortExpVector();
+    h->SetpFDeg();
+    if (strat->honey)
+    {
+      if (ei <= h->ecart)
+        h->ecart = d-h->GetpFDeg();
+      else
+        h->ecart = d-h->GetpFDeg()+ei-h->ecart;
+    }
+    else
+      // this has the side effect of setting h->length
+      h->ecart = h->pLDeg(strat->LDegLast) - h->GetpFDeg();
+
+    /*- try to reduce the s-polynomial -*/
+    pass++;
+    d = h->GetpFDeg()+h->ecart;
+    /*
+     *test whether the polynomial should go to the lazyset L
+     *-if the degree jumps
+     *-if the number of pre-defined reductions jumps
+     */
+    if (!TEST_OPT_REDTHROUGH && (strat->Ll >= 0)
+        && ((d >= reddeg) || (pass > strat->LazyPass)))
+    {
+      h->SetLmCurrRing();
+      if (strat->honey && strat->posInLDependsOnLength)
+        h->SetLength(strat->length_pLength);
+      assume(h->FDeg == h->pFDeg());
+      at = strat->posInL(strat->L,strat->Ll,h,strat);
+      if (at <= strat->Ll)
+      {
+        int dummy=strat->sl;
+        if (kFindDivisibleByInS(strat, &dummy, h) < 0)
+        {
+          if (strat->honey && !strat->posInLDependsOnLength)
+            h->SetLength(strat->length_pLength);
+          return 1;
+        }
+        enterL(&strat->L,&strat->Ll,&strat->Lmax,*h,at);
+#ifdef KDEBUG
+        if (TEST_OPT_DEBUG) Print(" degree jumped; ->L%d\n",at);
+#endif
+        h->Clear();
+        return -1;
+      }
+    }
+    else if ((TEST_OPT_PROT) && (strat->Ll < 0) && (d >= reddeg))
+    {
+      Print(".%ld",d);mflush();
+      reddeg = d+1;
+      if (h->pTotalDeg()+h->ecart >= strat->tailRing->bitmask)
+      {
+        strat->overflow=TRUE;
+        //Print("OVERFLOW in redEcart d=%ld, max=%ld",d,strat->tailRing->bitmask);
+        h->GetP();
+        at = strat->posInL(strat->L,strat->Ll,h,strat);
+        enterL(&strat->L,&strat->Ll,&strat->Lmax,*h,at);
+        h->Clear();
+        return -1;
+      }
+    }
+  }
+}
+
+/*2
+*reduces h with elements from T choosing  the first possible
+* element in t with respect to the given pDivisibleBy
+*/
+int redFirst (LObject* h,kStrategy strat)
+{
+  if (h->IsNull()) return 0;
+
+  int at;
+  long reddeg,d;
+  int pass = 0;
+  int j = 0;
+
+  if (! strat->homog)
+  {
+    d = h->GetpFDeg() + h->ecart;
+    reddeg = strat->LazyDegree+d;
+  }
+  h->SetShortExpVector();
+  loop
+  {
+    j = kFindDivisibleByInT(strat->T, strat->sevT, strat->tl, h);
+    if (j < 0)
+    {
+      h->SetDegStuffReturnLDeg(strat->LDegLast);
+      return 1;
+    }
+
+    if (!TEST_OPT_INTSTRATEGY)
+      strat->T[j].pNorm();
+#ifdef KDEBUG
+    if (TEST_OPT_DEBUG)
+    {
+      PrintS("reduce ");
+      h->wrp();
+      PrintS(" with ");
+      strat->T[j].wrp();
+    }
+#endif
+    ksReducePoly(h, &(strat->T[j]), strat->kNoetherTail(), NULL, strat);
+#ifdef KDEBUG
+    if (TEST_OPT_DEBUG)
+    {
+      PrintS(" to ");
+      wrp(h->p);
+      PrintLn();
+    }
+#endif
+    if (h->IsNull())
+    {
+      assume(!rField_is_Ring(currRing));
+      if (h->lcm!=NULL) pLmFree(h->lcm);
+      h->Clear();
+      return 0;
+    }
+    h->SetShortExpVector();
+
+#if 0
+    if ((strat->syzComp!=0) && !strat->honey)
+    {
+      if ((strat->syzComp>0) &&
+          (h->Comp() > strat->syzComp))
+      {
+        assume(h->MinComp() > strat->syzComp);
+#ifdef KDEBUG
+        if (TEST_OPT_DEBUG) PrintS(" > syzComp\n");
+#endif
+        if (strat->homog)
+          h->SetDegStuffReturnLDeg(strat->LDegLast);
+        return -2;
+      }
+    }
+#endif
+    if (!strat->homog)
+    {
+      if (!TEST_OPT_OLDSTD && strat->honey)
+      {
+        h->SetpFDeg();
+        if (strat->T[j].ecart <= h->ecart)
+          h->ecart = d - h->GetpFDeg();
+        else
+          h->ecart = d - h->GetpFDeg() + strat->T[j].ecart - h->ecart;
+
+        d = h->GetpFDeg() + h->ecart;
+      }
+      else
+        d = h->SetDegStuffReturnLDeg(strat->LDegLast);
+      /*- try to reduce the s-polynomial -*/
+      pass++;
+      /*
+       *test whether the polynomial should go to the lazyset L
+       *-if the degree jumps
+       *-if the number of pre-defined reductions jumps
+       */
+      if (!TEST_OPT_REDTHROUGH && (strat->Ll >= 0)
+          && ((d >= reddeg) || (pass > strat->LazyPass)))
+      {
+        h->SetLmCurrRing();
+        if (strat->posInLDependsOnLength)
+          h->SetLength(strat->length_pLength);
+        at = strat->posInL(strat->L,strat->Ll,h,strat);
+        if (at <= strat->Ll)
+        {
+          int dummy=strat->sl;
+          if (kFindDivisibleByInS(strat,&dummy, h) < 0)
+            return 1;
+          enterL(&strat->L,&strat->Ll,&strat->Lmax,*h,at);
+#ifdef KDEBUG
+          if (TEST_OPT_DEBUG) Print(" degree jumped; ->L%d\n",at);
+#endif
+          h->Clear();
+          return -1;
+        }
+      }
+      if ((TEST_OPT_PROT) && (strat->Ll < 0) && (d >= reddeg))
+      {
+        reddeg = d+1;
+        Print(".%ld",d);mflush();
+        if (h->pTotalDeg()+h->ecart >= strat->tailRing->bitmask)
+        {
+          strat->overflow=TRUE;
+          //Print("OVERFLOW in redFirst d=%ld, max=%ld",d,strat->tailRing->bitmask);
+          h->GetP();
+          at = strat->posInL(strat->L,strat->Ll,h,strat);
+          enterL(&strat->L,&strat->Ll,&strat->Lmax,*h,at);
+          h->Clear();
+          return -1;
+        }
+      }
+    }
+  }
+}
+
+/*2
+* reduces h with elements from T choosing first possible
+* element in T with respect to the given ecart
+* used for computing normal forms outside kStd
+*/
+static poly redMoraNF (poly h,kStrategy strat, int flag)
+{
+  LObject H;
+  H.p = h;
+  int j = 0;
+  int z = 10;
+  int o = H.SetpFDeg();
+  H.ecart = currRing->pLDeg(H.p,&H.length,currRing)-o;
+  if ((flag & 2) == 0) cancelunit(&H,TRUE);
+  H.sev = pGetShortExpVector(H.p);
+  unsigned long not_sev = ~ H.sev;
+  loop
+  {
+    if (j > strat->tl)
+    {
+      return H.p;
+    }
+    if (TEST_V_DEG_STOP)
+    {
+      if (kModDeg(H.p)>Kstd1_deg) pLmDelete(&H.p);
+      if (H.p==NULL) return NULL;
+    }
+    if (p_LmShortDivisibleBy(strat->T[j].GetLmTailRing(), strat->sevT[j], H.GetLmTailRing(), not_sev, strat->tailRing))
+    {
+      /*- remember the found T-poly -*/
+      // poly pi = strat->T[j].p;
+      int ei = strat->T[j].ecart;
+      int li = strat->T[j].length;
+      int ii = j;
+      /*
+      * the polynomial to reduce with (up to the moment) is;
+      * pi with ecart ei and length li
+      */
+      loop
+      {
+        /*- look for a better one with respect to ecart -*/
+        /*- stop, if the ecart is small enough (<=ecart(H)) -*/
+        j++;
+        if (j > strat->tl) break;
+        if (ei <= H.ecart) break;
+        if (((strat->T[j].ecart < ei)
+          || ((strat->T[j].ecart == ei)
+        && (strat->T[j].length < li)))
+        && pLmShortDivisibleBy(strat->T[j].p,strat->sevT[j], H.p, not_sev))
+        {
+          /*
+          * the polynomial to reduce with is now;
+          */
+          // pi = strat->T[j].p;
+          ei = strat->T[j].ecart;
+          li = strat->T[j].length;
+          ii = j;
+        }
+      }
+      /*
+      * end of search: have to reduce with pi
+      */
+      z++;
+      if (z>10)
+      {
+        pNormalize(H.p);
+        z=0;
+      }
+      if ((ei > H.ecart) && (!strat->kHEdgeFound))
+      {
+        /*
+        * It is not possible to reduce h with smaller ecart;
+        * we have to reduce with bad ecart: H has to enter in T
+        */
+        doRed(&H,&(strat->T[ii]),TRUE,strat);
+        if (H.p == NULL)
+          return NULL;
+      }
+      else
+      {
+        /*
+        * we reduce with good ecart, h need not to be put to T
+        */
+        doRed(&H,&(strat->T[ii]),FALSE,strat);
+        if (H.p == NULL)
+          return NULL;
+      }
+      /*- try to reduce the s-polynomial -*/
+      o = H.SetpFDeg();
+      if ((flag &2 ) == 0) cancelunit(&H,TRUE);
+      H.ecart = currRing->pLDeg(H.p,&(H.length),currRing)-o;
+      j = 0;
+      H.sev = pGetShortExpVector(H.p);
+      not_sev = ~ H.sev;
+    }
+    else
+    {
+      j++;
+    }
+  }
+}
+
+/*2
+*reorders  L with respect to posInL
+*/
+void reorderL(kStrategy strat)
+{
+  int i,j,at;
+  LObject p;
+
+  for (i=1; i<=strat->Ll; i++)
+  {
+    at = strat->posInL(strat->L,i-1,&(strat->L[i]),strat);
+    if (at != i)
+    {
+      p = strat->L[i];
+      for (j=i-1; j>=at; j--) strat->L[j+1] = strat->L[j];
+      strat->L[at] = p;
+    }
+  }
+}
+
+/*2
+*reorders  T with respect to length
+*/
+void reorderT(kStrategy strat)
+{
+  int i,j,at;
+  TObject p;
+  unsigned long sev;
+
+
+  for (i=1; i<=strat->tl; i++)
+  {
+    if (strat->T[i-1].length > strat->T[i].length)
+    {
+      p = strat->T[i];
+      sev = strat->sevT[i];
+      at = i-1;
+      loop
+      {
+        at--;
+        if (at < 0) break;
+        if (strat->T[i].length > strat->T[at].length) break;
+      }
+      for (j = i-1; j>at; j--)
+      {
+        strat->T[j+1]=strat->T[j];
+        strat->sevT[j+1]=strat->sevT[j];
+        strat->R[strat->T[j+1].i_r] = &(strat->T[j+1]);
+      }
+      strat->T[at+1]=p;
+      strat->sevT[at+1] = sev;
+      strat->R[p.i_r] = &(strat->T[at+1]);
+    }
+  }
+}
+
+/*2
+*looks whether exactly (currRing->N)-1 axis are used
+*returns last != 0 in this case
+*last is the (first) unused axis
+*/
+void missingAxis (int* last,kStrategy strat)
+{
+  int   i = 0;
+  int   k = 0;
+
+  *last = 0;
+  if (!currRing->MixedOrder)
+  {
+    loop
+    {
+      i++;
+      if (i > (currRing->N)) break;
+      if (strat->NotUsedAxis[i])
+      {
+        *last = i;
+        k++;
+      }
+      if (k>1)
+      {
+        *last = 0;
+        break;
+      }
+    }
+  }
+}
+
+/*2
+*last is the only non used axis, it looks
+*for a monomial in p being a pure power of this
+*variable and returns TRUE in this case
+*(*length) gives the length between the pure power and the leading term
+*(should be minimal)
+*/
+BOOLEAN hasPurePower (const poly p,int last, int *length,kStrategy strat)
+{
+  poly h;
+  int i;
+
+  if (pNext(p) == strat->tail)
+    return FALSE;
+  pp_Test(p, currRing, strat->tailRing);
+  if (strat->ak <= 0 || p_MinComp(p, currRing, strat->tailRing) == strat->ak)
+  {
+    i = p_IsPurePower(p, currRing);
+    if (i == last)
+    {
+      *length = 0;
+      return TRUE;
+    }
+    *length = 1;
+    h = pNext(p);
+    while (h != NULL)
+    {
+      i = p_IsPurePower(h, strat->tailRing);
+      if (i==last) return TRUE;
+      (*length)++;
+      pIter(h);
+    }
+  }
+  return FALSE;
+}
+
+BOOLEAN hasPurePower (LObject *L,int last, int *length,kStrategy strat)
+{
+  if (L->bucket != NULL)
+  {
+    poly p = L->CanonicalizeP();
+    BOOLEAN ret = hasPurePower(p, last, length, strat);
+    pNext(p) = NULL;
+    return ret;
+  }
+  else
+  {
+    return hasPurePower(L->p, last, length, strat);
+  }
+}
+
+/*2
+* looks up the position of polynomial p in L
+* in the case of looking for the pure powers
+*/
+int posInL10 (const LSet set,const int length, LObject* p,const kStrategy strat)
+{
+  int j,dp,dL;
+
+  if (length<0) return 0;
+  if (hasPurePower(p,strat->lastAxis,&dp,strat))
+  {
+    int op= p->GetpFDeg() +p->ecart;
+    for (j=length; j>=0; j--)
+    {
+      if (!hasPurePower(&(set[j]),strat->lastAxis,&dL,strat))
+        return j+1;
+      if (dp < dL)
+        return j+1;
+      if ((dp == dL)
+          && (set[j].GetpFDeg()+set[j].ecart >= op))
+        return j+1;
+    }
+  }
+  j=length;
+  loop
+  {
+    if (j<0) break;
+    if (!hasPurePower(&(set[j]),strat->lastAxis,&dL,strat)) break;
+    j--;
+  }
+  return strat->posInLOld(set,j,p,strat);
+}
+
+
+/*2
+* computes the s-polynomials L[ ].p in L
+*/
+void updateL(kStrategy strat)
+{
+  LObject p;
+  int dL;
+  int j=strat->Ll;
+  loop
+  {
+    if (j<0) break;
+    if (hasPurePower(&(strat->L[j]),strat->lastAxis,&dL,strat))
+    {
+      p=strat->L[strat->Ll];
+      strat->L[strat->Ll]=strat->L[j];
+      strat->L[j]=p;
+      break;
+    }
+    j--;
+  }
+  if (j<0)
+  {
+    j=strat->Ll;
+    loop
+    {
+      if (j<0) break;
+      if (pNext(strat->L[j].p) == strat->tail)
+      {
+#ifdef HAVE_RINGS
+        if (rField_is_Ring(currRing))
+          pLmDelete(strat->L[j].p);    /*deletes the short spoly and computes*/
+        else
+#else
+          pLmFree(strat->L[j].p);    /*deletes the short spoly and computes*/
+#endif
+        strat->L[j].p = NULL;
+        poly m1 = NULL, m2 = NULL;
+        // check that spoly creation is ok
+        while (strat->tailRing != currRing &&
+               !kCheckSpolyCreation(&(strat->L[j]), strat, m1, m2))
+        {
+          assume(m1 == NULL && m2 == NULL);
+          // if not, change to a ring where exponents are at least
+          // large enough
+          kStratChangeTailRing(strat);
+        }
+        /* create the real one */
+        ksCreateSpoly(&(strat->L[j]), strat->kNoetherTail(), FALSE,
+                      strat->tailRing, m1, m2, strat->R);
+
+        strat->L[j].SetLmCurrRing();
+        if (!strat->honey)
+          strat->initEcart(&strat->L[j]);
+        else
+          strat->L[j].SetLength(strat->length_pLength);
+
+        BOOLEAN pp = hasPurePower(&(strat->L[j]),strat->lastAxis,&dL,strat);
+
+        if (strat->use_buckets) strat->L[j].PrepareRed(TRUE);
+
+        if (pp)
+        {
+          p=strat->L[strat->Ll];
+          strat->L[strat->Ll]=strat->L[j];
+          strat->L[j]=p;
+          break;
+        }
+      }
+      j--;
+    }
+  }
+}
+
+/*2
+* computes the s-polynomials L[ ].p in L and
+* cuts elements in L above noether
+*/
+void updateLHC(kStrategy strat)
+{
+
+  int i = 0;
+  kTest_TS(strat);
+  while (i <= strat->Ll)
+  {
+    if (pNext(strat->L[i].p) == strat->tail)
+    {
+       /*- deletes the int spoly and computes -*/
+      if (pLmCmp(strat->L[i].p,strat->kNoether) == -1)
+      {
+        pLmFree(strat->L[i].p);
+        strat->L[i].p = NULL;
+      }
+      else
+      {
+        pLmFree(strat->L[i].p);
+        strat->L[i].p = NULL;
+        poly m1 = NULL, m2 = NULL;
+        // check that spoly creation is ok
+        while (strat->tailRing != currRing &&
+               !kCheckSpolyCreation(&(strat->L[i]), strat, m1, m2))
+        {
+          assume(m1 == NULL && m2 == NULL);
+          // if not, change to a ring where exponents are at least
+          // large enough
+          kStratChangeTailRing(strat);
+        }
+        /* create the real one */
+        ksCreateSpoly(&(strat->L[i]), strat->kNoetherTail(), FALSE,
+                      strat->tailRing, m1, m2, strat->R);
+        if (! strat->L[i].IsNull())
+        {
+          strat->L[i].SetLmCurrRing();
+          strat->L[i].SetpFDeg();
+          strat->L[i].ecart
+            = strat->L[i].pLDeg(strat->LDegLast) - strat->L[i].GetpFDeg();
+          if (strat->use_buckets) strat->L[i].PrepareRed(TRUE);
+        }
+      }
+    }
+    else
+      deleteHC(&(strat->L[i]), strat);
+   if (strat->L[i].IsNull())
+      deleteInL(strat->L,&strat->Ll,i,strat);
+    else
+    {
+#ifdef KDEBUG
+      kTest_L(&(strat->L[i]), strat->tailRing, TRUE, i, strat->T, strat->tl);
+#endif
+      i++;
+    }
+  }
+  kTest_TS(strat);
+}
+
+/*2
+* cuts in T above strat->kNoether and tries to cancel a unit
+*/
+void updateT(kStrategy strat)
+{
+  int i = 0;
+  LObject p;
+
+  while (i <= strat->tl)
+  {
+    p = strat->T[i];
+    deleteHC(&p,strat, TRUE);
+    /*- tries to cancel a unit: -*/
+    cancelunit(&p);
+    if (p.p != strat->T[i].p)
+    {
+      strat->sevT[i] = pGetShortExpVector(p.p);
+      p.SetpFDeg();
+    }
+    strat->T[i] = p;
+    i++;
+  }
+}
+
+/*2
+* arranges red, pos and T if strat->kHEdgeFound (first time)
+*/
+void firstUpdate(kStrategy strat)
+{
+  if (strat->update)
+  {
+    kTest_TS(strat);
+    strat->update = (strat->tl == -1);
+    if (TEST_OPT_WEIGHTM)
+    {
+      pRestoreDegProcs(currRing,strat->pOrigFDeg, strat->pOrigLDeg);
+      if (strat->tailRing != currRing)
+      {
+        strat->tailRing->pFDeg = strat->pOrigFDeg_TailRing;
+        strat->tailRing->pLDeg = strat->pOrigLDeg_TailRing;
+      }
+      int i;
+      for (i=strat->Ll; i>=0; i--)
+      {
+        strat->L[i].SetpFDeg();
+      }
+      for (i=strat->tl; i>=0; i--)
+      {
+        strat->T[i].SetpFDeg();
+      }
+      if (ecartWeights)
+      {
+        omFreeSize((ADDRESS)ecartWeights,(rVar(currRing)+1)*sizeof(short));
+        ecartWeights=NULL;
+      }
+    }
+    if (TEST_OPT_FASTHC)
+    {
+      strat->posInL = strat->posInLOld;
+      strat->lastAxis = 0;
+    }
+    if (TEST_OPT_FINDET)
+      return;
+
+#ifndef HAVE_RINGS
+    strat->red = redFirst;
+    strat->use_buckets = kMoraUseBucket(strat);
+#else
+    if ( (!rField_is_Ring(currRing)) || (rHasGlobalOrdering(currRing)))
+    {
+      strat->red = redFirst;
+      strat->use_buckets = kMoraUseBucket(strat);
+    }
+#endif
+    updateT(strat);
+
+#ifndef HAVE_RINGS
+    strat->posInT = posInT2;
+    reorderT(strat);
+#else
+    if ( (!rField_is_Ring(currRing)) || (rHasGlobalOrdering(currRing)))
+    {
+      strat->posInT = posInT2;
+      reorderT(strat);
+    }
+#endif
+  }
+  kTest_TS(strat);
+}
+
+/*2
+*-puts p to the standardbasis s at position at
+*-reduces the tail of p if TEST_OPT_REDTAIL
+*-tries to cancel a unit
+*-HEckeTest
+*  if TRUE
+*  - decides about reduction-strategies
+*  - computes noether
+*  - stops computation if TEST_OPT_FINDET
+*  - cuts the tails of the polynomials
+*    in s,t and the elements in L above noether
+*    and cancels units if possible
+*  - reorders s,L
+*/
+void enterSMora (LObject p,int atS,kStrategy strat, int atR = -1)
+{
+  enterSBba(p, atS, strat, atR);
+  #ifdef KDEBUG
+  if (TEST_OPT_DEBUG)
+  {
+    Print("new s%d:",atS);
+    p_wrp(p.p,currRing,strat->tailRing);
+    PrintLn();
+  }
+  #endif
+  if ((!strat->kHEdgeFound) || (strat->kNoether!=NULL)) HEckeTest(p.p,strat);
+  if (strat->kHEdgeFound)
+  {
+    if (newHEdge(strat))
+    {
+      firstUpdate(strat);
+      if (TEST_OPT_FINDET)
+        return;
+
+      /*- cuts elements in L above noether and reorders L -*/
+      updateLHC(strat);
+      /*- reorders L with respect to posInL -*/
+      reorderL(strat);
+    }
+  }
+  else if (strat->kNoether!=NULL)
+    strat->kHEdgeFound = TRUE;
+  else if (TEST_OPT_FASTHC)
+  {
+    if (strat->posInLOldFlag)
+    {
+      missingAxis(&strat->lastAxis,strat);
+      if (strat->lastAxis)
+      {
+        strat->posInLOld = strat->posInL;
+        strat->posInLOldFlag = FALSE;
+        strat->posInL = posInL10;
+        strat->posInLDependsOnLength = TRUE;
+        updateL(strat);
+        reorderL(strat);
+      }
+    }
+    else if (strat->lastAxis)
+      updateL(strat);
+  }
+}
+
+/*2
+*-puts p to the standardbasis s at position at
+*-HEckeTest
+*  if TRUE
+*  - computes noether
+*/
+void enterSMoraNF (LObject p, int atS,kStrategy strat, int atR = -1)
+{
+  enterSBba(p, atS, strat, atR);
+  if ((!strat->kHEdgeFound) || (strat->kNoether!=NULL)) HEckeTest(p.p,strat);
+  if (strat->kHEdgeFound)
+    newHEdge(strat);
+  else if (strat->kNoether!=NULL)
+    strat->kHEdgeFound = TRUE;
+}
+
+void initBba(ideal /*F*/,kStrategy strat)
+{
+ /* setting global variables ------------------- */
+  strat->enterS = enterSBba;
+    strat->red = redHoney;
+  if (strat->honey)
+    strat->red = redHoney;
+  else if (currRing->pLexOrder && !strat->homog)
+    strat->red = redLazy;
+  else
+  {
+    strat->LazyPass *=4;
+    strat->red = redHomog;
+  }
+#ifdef HAVE_RINGS  //TODO Oliver
+  if (rField_is_Ring(currRing))
+  {
+    strat->red = redRing;
+  }
+#endif
+  if (currRing->pLexOrder && strat->honey)
+    strat->initEcart = initEcartNormal;
+  else
+    strat->initEcart = initEcartBBA;
+  if (strat->honey)
+    strat->initEcartPair = initEcartPairMora;
+  else
+    strat->initEcartPair = initEcartPairBba;
+//  if ((TEST_OPT_WEIGHTM)&&(F!=NULL))
+//  {
+//    //interred  machen   Aenderung
+//    strat->pOrigFDeg=pFDeg;
+//    strat->pOrigLDeg=pLDeg;
+//    //h=ggetid("ecart");
+//    //if ((h!=NULL) /*&& (IDTYP(h)==INTVEC_CMD)*/)
+//    //{
+//    //  ecartWeights=iv2array(IDINTVEC(h));
+//    //}
+//    //else
+//    {
+//      ecartWeights=(short *)omAlloc(((currRing->N)+1)*sizeof(short));
+//      /*uses automatic computation of the ecartWeights to set them*/
+//      kEcartWeights(F->m,IDELEMS(F)-1,ecartWeights);
+//    }
+//    pRestoreDegProcs(currRing,totaldegreeWecart, maxdegreeWecart);
+//    if (TEST_OPT_PROT)
+//    {
+//      for(i=1; i<=(currRing->N); i++)
+//        Print(" %d",ecartWeights[i]);
+//      PrintLn();
+//      mflush();
+//    }
+//  }
+}
+
+void initSba(ideal F,kStrategy strat)
+{
+  int i;
+  //idhdl h;
+ /* setting global variables ------------------- */
+  strat->enterS = enterSSba;
+    strat->red2 = redHoney;
+  if (strat->honey)
+    strat->red2 = redHoney;
+  else if (currRing->pLexOrder && !strat->homog)
+    strat->red2 = redLazy;
+  else
+  {
+    strat->LazyPass *=4;
+    strat->red2 = redHomog;
+  }
+#if defined(HAVE_RINGS) || defined(HAVE_RINGS_LOC)  //TODO Oliver
+  if (rField_is_Ring(currRing))
+  {
+    if(rHasLocalOrMixedOrdering(currRing))
+      {strat->red = redRiloc;}
+    else
+      {strat->red2 = redRing;}
+  }
+#endif
+  if (currRing->pLexOrder && strat->honey)
+    strat->initEcart = initEcartNormal;
+  else
+    strat->initEcart = initEcartBBA;
+  if (strat->honey)
+    strat->initEcartPair = initEcartPairMora;
+  else
+    strat->initEcartPair = initEcartPairBba;
+  //strat->kIdeal = NULL;
+  //if (strat->ak==0) strat->kIdeal->rtyp=IDEAL_CMD;
+  //else              strat->kIdeal->rtyp=MODUL_CMD;
+  //strat->kIdeal->data=(void *)strat->Shdl;
+  if ((TEST_OPT_WEIGHTM)&&(F!=NULL))
+  {
+    //interred  machen   Aenderung
+    strat->pOrigFDeg  = currRing->pFDeg;
+    strat->pOrigLDeg  = currRing->pLDeg;
+    //h=ggetid("ecart");
+    //if ((h!=NULL) /*&& (IDTYP(h)==INTVEC_CMD)*/)
+    //{
+    //  ecartWeights=iv2array(IDINTVEC(h));
+    //}
+    //else
+    {
+      ecartWeights=(short *)omAlloc(((currRing->N)+1)*sizeof(short));
+      /*uses automatic computation of the ecartWeights to set them*/
+      kEcartWeights(F->m,IDELEMS(F)-1,ecartWeights, currRing);
+    }
+    pRestoreDegProcs(currRing, totaldegreeWecart, maxdegreeWecart);
+    if (TEST_OPT_PROT)
+    {
+      for(i=1; i<=(currRing->N); i++)
+        Print(" %d",ecartWeights[i]);
+      PrintLn();
+      mflush();
+    }
+  }
+  // for sig-safe reductions in signature-based
+  // standard basis computations
+  strat->red          = redSig;
+  //strat->sbaOrder  = 1;
+  strat->currIdx      = 1;
+}
+
+void initMora(ideal F,kStrategy strat)
+{
+  int i,j;
+
+  strat->NotUsedAxis = (BOOLEAN *)omAlloc(((currRing->N)+1)*sizeof(BOOLEAN));
+  for (j=(currRing->N); j>0; j--) strat->NotUsedAxis[j] = TRUE;
+  strat->enterS = enterSMora;
+  strat->initEcartPair = initEcartPairMora; /*- ecart approximation -*/
+  strat->posInLOld = strat->posInL;
+  strat->posInLOldFlag = TRUE;
+  strat->initEcart = initEcartNormal;
+  strat->kHEdgeFound = (currRing->ppNoether) != NULL;
+  if ( strat->kHEdgeFound )
+     strat->kNoether = pCopy((currRing->ppNoether));
+  else if (strat->kHEdgeFound || strat->homog)
+    strat->red = redFirst;  /*take the first possible in T*/
+  else
+    strat->red = redEcart;/*take the first possible in under ecart-restriction*/
+  if (strat->kHEdgeFound)
+  {
+    strat->HCord = currRing->pFDeg((currRing->ppNoether),currRing)+1;
+    strat->posInT = posInT2;
+  }
+  else
+  {
+    strat->HCord = 32000;/*- very large -*/
+  }
+
+#ifdef HAVE_RINGS
+  if (rField_is_Ring(currRing))
+    strat->red = redRiloc;
+#endif
+
+  /*reads the ecartWeights used for Graebes method from the
+   *intvec ecart and set ecartWeights
+   */
+  if ((TEST_OPT_WEIGHTM)&&(F!=NULL))
+  {
+    //interred  machen   Aenderung
+    strat->pOrigFDeg=currRing->pFDeg;
+    strat->pOrigLDeg=currRing->pLDeg;
+    ecartWeights=(short *)omAlloc(((currRing->N)+1)*sizeof(short));
+    /*uses automatic computation of the ecartWeights to set them*/
+    kEcartWeights(F->m,IDELEMS(F)-1,ecartWeights,currRing);
+
+    pSetDegProcs(currRing,totaldegreeWecart, maxdegreeWecart);
+    if (TEST_OPT_PROT)
+    {
+      for(i=1; i<=(currRing->N); i++)
+        Print(" %d",ecartWeights[i]);
+      PrintLn();
+      mflush();
+    }
+  }
+  kOptimizeLDeg(currRing->pLDeg, strat);
+}
+
+void kDebugPrint(kStrategy strat);
+
+ideal mora (ideal F, ideal Q,intvec *w,intvec *hilb,kStrategy strat)
+{
+#ifdef HAVE_RINGS
+#if ADIDEBUG
+int loop_count;
+loop_count = 1;
+#endif
+#endif
+  int olddeg = 0;
+  int reduc = 0;
+  int red_result = 1;
+  int hilbeledeg=1,hilbcount=0;
+  BITSET save1;
+  SI_SAVE_OPT1(save1);
+  if (currRing->MixedOrder)
+  {
+    si_opt_1 &= ~Sy_bit(OPT_REDSB);
+    si_opt_1 &= ~Sy_bit(OPT_REDTAIL);
+  }
+
+  strat->update = TRUE;
+  /*- setting global variables ------------------- -*/
+  initBuchMoraCrit(strat);
+  initHilbCrit(F,Q,&hilb,strat);
+  initMora(F,strat);
+  initBuchMoraPos(strat);
+  /*Shdl=*/initBuchMora(F,Q,strat);
+  if (TEST_OPT_FASTHC) missingAxis(&strat->lastAxis,strat);
+  /*updateS in initBuchMora has Hecketest
+  * and could have put strat->kHEdgdeFound FALSE*/
+  if ((currRing->ppNoether)!=NULL)
+  {
+    strat->kHEdgeFound = TRUE;
+  }
+  if (strat->kHEdgeFound && strat->update)
+  {
+    firstUpdate(strat);
+    updateLHC(strat);
+    reorderL(strat);
+  }
+  if (TEST_OPT_FASTHC && (strat->lastAxis) && strat->posInLOldFlag)
+  {
+    strat->posInLOld = strat->posInL;
+    strat->posInLOldFlag = FALSE;
+    strat->posInL = posInL10;
+    updateL(strat);
+    reorderL(strat);
+  }
+  kTest_TS(strat);
+  strat->use_buckets = kMoraUseBucket(strat);
+  /*- compute-------------------------------------------*/
+
+#ifdef HAVE_TAIL_RING
+//  if (strat->homog && strat->red == redFirst)
+  kStratInitChangeTailRing(strat);
+#endif
+
+  if (BVERBOSE(23))
+  {
+    kDebugPrint(strat);
+  }
+
+  while (strat->Ll >= 0)
+  {
+    #ifdef KDEBUG
+    if (TEST_OPT_DEBUG) messageSets(strat);
+    #endif
+    if (TEST_OPT_DEGBOUND
+    && (strat->L[strat->Ll].ecart+strat->L[strat->Ll].GetpFDeg()> Kstd1_deg))
+    {
+      /*
+      * stops computation if
+      * - 24 (degBound)
+      *   && upper degree is bigger than Kstd1_deg
+      */
+      while ((strat->Ll >= 0)
+        && (strat->L[strat->Ll].p1!=NULL) && (strat->L[strat->Ll].p2!=NULL)
+        && (strat->L[strat->Ll].ecart+strat->L[strat->Ll].GetpFDeg()> Kstd1_deg)
+      )
+      {
+        deleteInL(strat->L,&strat->Ll,strat->Ll,strat);
+        //if (TEST_OPT_PROT)
+        //{
+        //   PrintS("D"); mflush();
+        //}
+      }
+      if (strat->Ll<0) break;
+      else strat->noClearS=TRUE;
+    }
+
+#if ADIDEBUG
+#ifdef KDEBUG
+    Print("\n-------------------------------- LOOP %d ---------------------------------------\n",loop_count);
+    //print the list L: (p1,p2,p)
+    Print("\n    The pair list L -- in loop %d  -- is:\n",loop_count);
+    for(int iii=0;iii<=strat->Ll;iii++)
+    {
+      Print("\n    L[%d]:\n",iii);
+      PrintS("        ");p_Write(strat->L[iii].p1,strat->tailRing);
+      PrintS("        ");p_Write(strat->L[iii].p2,strat->tailRing);
+      PrintS("        ");p_Write(strat->L[iii].p,strat->tailRing);
+    }
+    PrintLn();
+#endif
+#endif
+
+    strat->P = strat->L[strat->Ll];/*- picks the last element from the lazyset L -*/
+    if (strat->Ll==0) strat->interpt=TRUE;
+    strat->Ll--;
+
+#if ADIDEBUG
+#ifdef KDEBUG
+    PrintS("    My new pair P = (p1,p2,p) is:\n");
+    PrintS("      p1 = "); p_Write(strat->P.p1,strat->tailRing);PrintLn();
+    PrintS("      p2 = "); p_Write(strat->P.p2,strat->tailRing);PrintLn();
+    PrintS("      p = "); p_Write(strat->P.p,strat->tailRing); PrintLn();
+    Print("\n    The old reducer list T -- at the beg of loop %d -- is :",loop_count);
+    if(strat->tl<0)
+    {PrintS(" Empty.\n");}
+    else
+    for(int iii=0;iii<=strat->tl;iii++)
+    {
+      Print("\n    T[%d]:",iii);
+      p_Write(strat->T[iii].p,strat->T->tailRing);
+    }
+    PrintLn();
+#endif /* ADIDEBUG */
+#endif
+
+    // create the real Spoly
+    if (pNext(strat->P.p) == strat->tail)
+    {
+      /*- deletes the short spoly and computes -*/
+#ifdef HAVE_RINGS
+      if (rField_is_Ring(currRing))
+        pLmDelete(strat->P.p);
+      else
+#endif
+      pLmFree(strat->P.p);
+      strat->P.p = NULL;
+      poly m1 = NULL, m2 = NULL;
+      // check that spoly creation is ok
+      while (strat->tailRing != currRing &&
+             !kCheckSpolyCreation(&(strat->P), strat, m1, m2))
+      {
+        assume(m1 == NULL && m2 == NULL);
+        // if not, change to a ring where exponents are large enough
+        kStratChangeTailRing(strat);
+      }
+      /* create the real one */
+      ksCreateSpoly(&(strat->P), strat->kNoetherTail(), strat->use_buckets,
+                    strat->tailRing, m1, m2, strat->R);
+      if (!strat->use_buckets)
+        strat->P.SetLength(strat->length_pLength);
+    }
+    else if (strat->P.p1 == NULL)
+    {
+      // for input polys, prepare reduction (buckets !)
+      strat->P.SetLength(strat->length_pLength);
+      strat->P.PrepareRed(strat->use_buckets);
+    }
+
+    if (!strat->P.IsNull())
+    {
+      // might be NULL from noether !!!
+      if (TEST_OPT_PROT)
+        message(strat->P.ecart+strat->P.GetpFDeg(),&olddeg,&reduc,strat, red_result);
+      // reduce
+      red_result = strat->red(&strat->P,strat);
+    }
+
+    if (! strat->P.IsNull())
+    {
+      strat->P.GetP();
+      // statistics
+      if (TEST_OPT_PROT) PrintS("s");
+      // normalization
+      if (!TEST_OPT_INTSTRATEGY)
+        strat->P.pNorm();
+      // tailreduction
+      strat->P.p = redtail(&(strat->P),strat->sl,strat);
+      // set ecart -- might have changed because of tail reductions
+      if ((!strat->noTailReduction) && (!strat->honey))
+        strat->initEcart(&strat->P);
+      // cancel unit
+      cancelunit(&strat->P);
+      // for char 0, clear denominators
+      if (TEST_OPT_INTSTRATEGY)
+        strat->P.pCleardenom();
+
+      // put in T
+      enterT(strat->P,strat);
+      // build new pairs
+#ifdef HAVE_RINGS
+      if (rField_is_Ring(currRing))
+      {
+        superenterpairs(strat->P.p,strat->sl,strat->P.ecart,0,strat, strat->tl);
+
+#if ADIDEBUG
+        Print("\n    The new pair list L -- after superenterpairs in loop %d -- is:\n",loop_count);
+        for(int iii=0;iii<=strat->Ll;iii++)
+        {
+          PrintS("\n    L[%d]:\n",iii);
+          PrintS("         ");p_Write(strat->L[iii].p1,strat->tailRing);
+          PrintS("         ");p_Write(strat->L[iii].p2,strat->tailRing);
+          PrintS("         ");p_Write(strat->L[iii].p,strat->tailRing);
+        }
+#endif
+      }
+      else
+#endif
+      enterpairs(strat->P.p,strat->sl,strat->P.ecart,0,strat, strat->tl);
+      // put in S
+      strat->enterS(strat->P,
+                    posInS(strat,strat->sl,strat->P.p, strat->P.ecart),
+                    strat, strat->tl);
+
+      // apply hilbert criterion
+      if (hilb!=NULL)
+      {
+        if (strat->homog==isHomog)
+          khCheck(Q,w,hilb,hilbeledeg,hilbcount,strat);
+        else
+          khCheckLocInhom(Q,w,hilb,hilbcount,strat);
+      }
+
+      // clear strat->P
+      if (strat->P.lcm!=NULL)
+#if defined(HAVE_RINGS) || defined(HAVE_RINGS_LOC)
+        pLmDelete(strat->P.lcm);
+#else
+        pLmFree(strat->P.lcm);
+#endif
+      strat->P.lcm=NULL;
+#ifdef KDEBUG
+      // make sure kTest_TS does not complain about strat->P
+      memset(&strat->P,0,sizeof(strat->P));
+#endif
+    }
+    if (strat->kHEdgeFound)
+    {
+      if ((TEST_OPT_FINDET)
+      || ((TEST_OPT_MULTBOUND) && (scMult0Int(strat->Shdl,NULL,strat->tailRing) < Kstd1_mu)))
+      {
+        // obachman: is this still used ???
+        /*
+        * stops computation if strat->kHEdgeFound and
+        * - 27 (finiteDeterminacyTest)
+        * or
+        * - 23
+        *   (multBound)
+        *   && multiplicity of the ideal is smaller then a predefined number mu
+        */
+        while (strat->Ll >= 0) deleteInL(strat->L,&strat->Ll,strat->Ll,strat);
+      }
+    }
+    kTest_TS(strat);
+
+#if ADIDEBUG
+    Print("\n    The new reducer list T -- at the end of loop %d -- is\n",loop_count);
+    for(int iii=0;iii<=strat->tl;iii++)
+    {
+      PrintS("\n    T[%d]:",iii);
+      p_Write(strat->T[iii].p,strat->tailRing);
+    }
+    PrintLn();
+
+    loop_count++;
+#endif /* ADIDEBUG */
+  }
+  /*- complete reduction of the standard basis------------------------ -*/
+  if (TEST_OPT_REDSB) completeReduce(strat);
+  else if (TEST_OPT_PROT) PrintLn();
+  /*- release temp data------------------------------- -*/
+  exitBuchMora(strat);
+  /*- polynomials used for HECKE: HC, noether -*/
+  if (TEST_OPT_FINDET)
+  {
+    if (strat->kHEdge!=NULL)
+      Kstd1_mu=currRing->pFDeg(strat->kHEdge,currRing);
+    else
+      Kstd1_mu=-1;
+  }
+  pDelete(&strat->kHEdge);
+  strat->update = TRUE; //???
+  strat->lastAxis = 0; //???
+  pDelete(&strat->kNoether);
+  omFreeSize((ADDRESS)strat->NotUsedAxis,((currRing->N)+1)*sizeof(BOOLEAN));
+  if (TEST_OPT_PROT) messageStat(hilbcount,strat);
+//  if (TEST_OPT_WEIGHTM)
+//  {
+//    pRestoreDegProcs(currRing,strat->pOrigFDeg, strat->pOrigLDeg);
+//    if (ecartWeights)
+//    {
+//      omFreeSize((ADDRESS)ecartWeights,((currRing->N)+1)*sizeof(short));
+//      ecartWeights=NULL;
+//    }
+//  }
+  if (Q!=NULL) updateResult(strat->Shdl,Q,strat);
+  SI_RESTORE_OPT1(save1);
+  idTest(strat->Shdl);
+  return (strat->Shdl);
+}
+
+poly kNF1 (ideal F,ideal Q,poly q, kStrategy strat, int lazyReduce)
+{
+  assume(q!=NULL);
+  assume(!(idIs0(F)&&(Q==NULL)));
+
+// lazy_reduce flags: can be combined by |
+//#define KSTD_NF_LAZY   1
+  // do only a reduction of the leading term
+//#define KSTD_NF_ECART  2
+  // only local: recude even with bad ecart
+  poly   p;
+  int   i;
+  int   j;
+  int   o;
+  LObject   h;
+  BITSET save1;
+  SI_SAVE_OPT1(save1);
+
+  //if ((idIs0(F))&&(Q==NULL))
+  //  return pCopy(q); /*F=0*/
+  //strat->ak = si_max(idRankFreeModule(F),pMaxComp(q));
+  /*- creating temp data structures------------------- -*/
+  strat->kHEdgeFound = (currRing->ppNoether) != NULL;
+  strat->kNoether    = pCopy((currRing->ppNoether));
+  si_opt_1|=Sy_bit(OPT_REDTAIL);
+  si_opt_1&=~Sy_bit(OPT_INTSTRATEGY);
+  if (TEST_OPT_STAIRCASEBOUND
+  && (! TEST_V_DEG_STOP)
+  && (0<Kstd1_deg)
+  && ((!strat->kHEdgeFound)
+    ||(TEST_OPT_DEGBOUND && (pWTotaldegree(strat->kNoether)<Kstd1_deg))))
+  {
+    pDelete(&strat->kNoether);
+    strat->kNoether=pOne();
+    pSetExp(strat->kNoether,1, Kstd1_deg+1);
+    pSetm(strat->kNoether);
+    strat->kHEdgeFound=TRUE;
+  }
+  initBuchMoraCrit(strat);
+  initBuchMoraPos(strat);
+  initMora(F,strat);
+  strat->enterS = enterSMoraNF;
+  /*- set T -*/
+  strat->tl = -1;
+  strat->tmax = setmaxT;
+  strat->T = initT();
+  strat->R = initR();
+  strat->sevT = initsevT();
+  /*- set S -*/
+  strat->sl = -1;
+  /*- init local data struct.-------------------------- -*/
+  /*Shdl=*/initS(F,Q,strat);
+  if ((strat->ak!=0)
+  && (strat->kHEdgeFound))
+  {
+    if (strat->ak!=1)
+    {
+      pSetComp(strat->kNoether,1);
+      pSetmComp(strat->kNoether);
+      poly p=pHead(strat->kNoether);
+      pSetComp(p,strat->ak);
+      pSetmComp(p);
+      p=pAdd(strat->kNoether,p);
+      strat->kNoether=pNext(p);
+      p_LmFree(p,currRing);
+    }
+  }
+  if ((lazyReduce & KSTD_NF_LAZY)==0)
+  {
+    for (i=strat->sl; i>=0; i--)
+      pNorm(strat->S[i]);
+  }
+  /*- puts the elements of S also to T -*/
+  for (i=0; i<=strat->sl; i++)
+  {
+    h.p = strat->S[i];
+    h.ecart = strat->ecartS[i];
+    if (strat->sevS[i] == 0) strat->sevS[i] = pGetShortExpVector(h.p);
+    else assume(strat->sevS[i] == pGetShortExpVector(h.p));
+    h.length = pLength(h.p);
+    h.sev = strat->sevS[i];
+    h.SetpFDeg();
+    enterT(h,strat);
+  }
+#ifdef KDEBUG
+//  kDebugPrint(strat);
+#endif
+  /*- compute------------------------------------------- -*/
+  p = pCopy(q);
+  deleteHC(&p,&o,&j,strat);
+  kTest(strat);
+  if (TEST_OPT_PROT) { PrintS("r"); mflush(); }
+  if (BVERBOSE(23)) kDebugPrint(strat);
+  if (p!=NULL) p = redMoraNF(p,strat, lazyReduce & KSTD_NF_ECART);
+  if ((p!=NULL)&&((lazyReduce & KSTD_NF_LAZY)==0))
+  {
+    if (TEST_OPT_PROT) { PrintS("t"); mflush(); }
+    p = redtail(p,strat->sl,strat);
+  }
+  /*- release temp data------------------------------- -*/
+  cleanT(strat);
+  assume(strat->L==NULL); /*strat->L unsed */
+  assume(strat->B==NULL); /*strat->B unused */
+  omFreeSize((ADDRESS)strat->T,strat->tmax*sizeof(TObject));
+  omFreeSize((ADDRESS)strat->ecartS,IDELEMS(strat->Shdl)*sizeof(int));
+  omFreeSize((ADDRESS)strat->sevS,IDELEMS(strat->Shdl)*sizeof(unsigned long));
+  omFreeSize((ADDRESS)strat->NotUsedAxis,((currRing->N)+1)*sizeof(BOOLEAN));
+  omFree(strat->sevT);
+  omFree(strat->S_2_R);
+  omFree(strat->R);
+
+  if ((Q!=NULL)&&(strat->fromQ!=NULL))
+  {
+    i=((IDELEMS(Q)+IDELEMS(F)+15)/16)*16;
+    omFreeSize((ADDRESS)strat->fromQ,i*sizeof(int));
+    strat->fromQ=NULL;
+  }
+  pDelete(&strat->kHEdge);
+  pDelete(&strat->kNoether);
+//  if ((TEST_OPT_WEIGHTM)&&(F!=NULL))
+//  {
+//    pRestoreDegProcs(currRing,strat->pOrigFDeg, strat->pOrigLDeg);
+//    if (ecartWeights)
+//    {
+//      omFreeSize((ADDRESS *)&ecartWeights,((currRing->N)+1)*sizeof(short));
+//      ecartWeights=NULL;
+//    }
+//  }
+  idDelete(&strat->Shdl);
+  SI_RESTORE_OPT1(save1);
+  if (TEST_OPT_PROT) PrintLn();
+  return p;
+}
+
+ideal kNF1 (ideal F,ideal Q,ideal q, kStrategy strat, int lazyReduce)
+{
+  assume(!idIs0(q));
+  assume(!(idIs0(F)&&(Q==NULL)));
+
+// lazy_reduce flags: can be combined by |
+//#define KSTD_NF_LAZY   1
+  // do only a reduction of the leading term
+//#define KSTD_NF_ECART  2
+  // only local: recude even with bad ecart
+  poly   p;
+  int   i;
+  int   j;
+  int   o;
+  LObject   h;
+  ideal res;
+  BITSET save1;
+  SI_SAVE_OPT1(save1);
+
+  //if (idIs0(q)) return idInit(IDELEMS(q),si_max(q->rank,F->rank));
+  //if ((idIs0(F))&&(Q==NULL))
+  //  return idCopy(q); /*F=0*/
+  //strat->ak = si_max(idRankFreeModule(F),idRankFreeModule(q));
+  /*- creating temp data structures------------------- -*/
+  strat->kHEdgeFound = (currRing->ppNoether) != NULL;
+  strat->kNoether=pCopy((currRing->ppNoether));
+  si_opt_1|=Sy_bit(OPT_REDTAIL);
+  if (TEST_OPT_STAIRCASEBOUND
+  && (0<Kstd1_deg)
+  && ((!strat->kHEdgeFound)
+    ||(TEST_OPT_DEGBOUND && (pWTotaldegree(strat->kNoether)<Kstd1_deg))))
+  {
+    pDelete(&strat->kNoether);
+    strat->kNoether=pOne();
+    pSetExp(strat->kNoether,1, Kstd1_deg+1);
+    pSetm(strat->kNoether);
+    strat->kHEdgeFound=TRUE;
+  }
+  initBuchMoraCrit(strat);
+  initBuchMoraPos(strat);
+  initMora(F,strat);
+  strat->enterS = enterSMoraNF;
+  /*- set T -*/
+  strat->tl = -1;
+  strat->tmax = setmaxT;
+  strat->T = initT();
+  strat->R = initR();
+  strat->sevT = initsevT();
+  /*- set S -*/
+  strat->sl = -1;
+  /*- init local data struct.-------------------------- -*/
+  /*Shdl=*/initS(F,Q,strat);
+  if ((strat->ak!=0)
+  && (strat->kHEdgeFound))
+  {
+    if (strat->ak!=1)
+    {
+      pSetComp(strat->kNoether,1);
+      pSetmComp(strat->kNoether);
+      poly p=pHead(strat->kNoether);
+      pSetComp(p,strat->ak);
+      pSetmComp(p);
+      p=pAdd(strat->kNoether,p);
+      strat->kNoether=pNext(p);
+      p_LmFree(p,currRing);
+    }
+  }
+  if (TEST_OPT_INTSTRATEGY && ((lazyReduce & KSTD_NF_LAZY)==0))
+  {
+    for (i=strat->sl; i>=0; i--)
+      pNorm(strat->S[i]);
+  }
+  /*- compute------------------------------------------- -*/
+  res=idInit(IDELEMS(q),strat->ak);
+  for (i=0; i<IDELEMS(q); i++)
+  {
+    if (q->m[i]!=NULL)
+    {
+      p = pCopy(q->m[i]);
+      deleteHC(&p,&o,&j,strat);
+      if (p!=NULL)
+      {
+        /*- puts the elements of S also to T -*/
+        for (j=0; j<=strat->sl; j++)
+        {
+          h.p = strat->S[j];
+          h.ecart = strat->ecartS[j];
+          h.pLength = h.length = pLength(h.p);
+          if (strat->sevS[j] == 0) strat->sevS[j] = pGetShortExpVector(h.p);
+          else assume(strat->sevS[j] == pGetShortExpVector(h.p));
+          h.sev = strat->sevS[j];
+          h.SetpFDeg();
+          enterT(h,strat);
+        }
+        if (TEST_OPT_PROT) { PrintS("r"); mflush(); }
+        p = redMoraNF(p,strat, lazyReduce & KSTD_NF_ECART);
+        if ((p!=NULL)&&((lazyReduce & KSTD_NF_LAZY)==0))
+        {
+          if (TEST_OPT_PROT) { PrintS("t"); mflush(); }
+          p = redtail(p,strat->sl,strat);
+        }
+        cleanT(strat);
+      }
+      res->m[i]=p;
+    }
+    //else
+    //  res->m[i]=NULL;
+  }
+  /*- release temp data------------------------------- -*/
+  assume(strat->L==NULL); /*strat->L unsed */
+  assume(strat->B==NULL); /*strat->B unused */
+  omFreeSize((ADDRESS)strat->T,strat->tmax*sizeof(TObject));
+  omFreeSize((ADDRESS)strat->ecartS,IDELEMS(strat->Shdl)*sizeof(int));
+  omFreeSize((ADDRESS)strat->sevS,IDELEMS(strat->Shdl)*sizeof(unsigned long));
+  omFreeSize((ADDRESS)strat->NotUsedAxis,((currRing->N)+1)*sizeof(BOOLEAN));
+  omFree(strat->sevT);
+  omFree(strat->S_2_R);
+  omFree(strat->R);
+  if ((Q!=NULL)&&(strat->fromQ!=NULL))
+  {
+    i=((IDELEMS(Q)+IDELEMS(F)+15)/16)*16;
+    omFreeSize((ADDRESS)strat->fromQ,i*sizeof(int));
+    strat->fromQ=NULL;
+  }
+  pDelete(&strat->kHEdge);
+  pDelete(&strat->kNoether);
+//  if ((TEST_OPT_WEIGHTM)&&(F!=NULL))
+//  {
+//    pFDeg=strat->pOrigFDeg;
+//    pLDeg=strat->pOrigLDeg;
+//    if (ecartWeights)
+//    {
+//      omFreeSize((ADDRESS *)&ecartWeights,((currRing->N)+1)*sizeof(short));
+//      ecartWeights=NULL;
+//    }
+//  }
+  idDelete(&strat->Shdl);
+  SI_RESTORE_OPT1(save1);
+  if (TEST_OPT_PROT) PrintLn();
+  return res;
+}
+
+intvec * kModW, * kHomW;
+
+long kModDeg(poly p, ring r)
+{
+  long o=p_WDegree(p, r);
+  long i=p_GetComp(p, r);
+  if (i==0) return o;
+  //assume((i>0) && (i<=kModW->length()));
+  if (i<=kModW->length())
+    return o+(*kModW)[i-1];
+  return o;
+}
+long kHomModDeg(poly p, ring r)
+{
+  int i;
+  long j=0;
+
+  for (i=r->N;i>0;i--)
+    j+=p_GetExp(p,i,r)*(*kHomW)[i-1];
+  if (kModW == NULL) return j;
+  i = p_GetComp(p,r);
+  if (i==0) return j;
+  return j+(*kModW)[i-1];
+}
+
+ideal kStd(ideal F, ideal Q, tHomog h,intvec ** w, intvec *hilb,int syzComp,
+          int newIdeal, intvec *vw)
+{
+  if(idIs0(F))
+    return idInit(1,F->rank);
+
+  ideal r;
+  BOOLEAN b=currRing->pLexOrder,toReset=FALSE;
+  BOOLEAN delete_w=(w==NULL);
+  kStrategy strat=new skStrategy;
+
+  if(!TEST_OPT_RETURN_SB)
+    strat->syzComp = syzComp;
+  if (TEST_OPT_SB_1
+    #ifdef HAVE_RINGS
+    &&(!rField_is_Ring(currRing))
+    #endif
+    )
+    strat->newIdeal = newIdeal;
+  if (rField_has_simple_inverse(currRing))
+    strat->LazyPass=20;
+  else
+    strat->LazyPass=2;
+  strat->LazyDegree = 1;
+  strat->enterOnePair=enterOnePairNormal;
+  strat->chainCrit=chainCritNormal;
+  strat->ak = id_RankFreeModule(F,currRing);
+  strat->kModW=kModW=NULL;
+  strat->kHomW=kHomW=NULL;
+  if (vw != NULL)
+  {
+    currRing->pLexOrder=FALSE;
+    strat->kHomW=kHomW=vw;
+    strat->pOrigFDeg = currRing->pFDeg;
+    strat->pOrigLDeg = currRing->pLDeg;
+    pSetDegProcs(currRing,kHomModDeg);
+    toReset = TRUE;
+  }
+  if (h==testHomog)
+  {
+    if (strat->ak == 0)
+    {
+      h = (tHomog)idHomIdeal(F,Q);
+      w=NULL;
+    }
+    else if (!TEST_OPT_DEGBOUND)
+    {
+      h = (tHomog)idHomModule(F,Q,w);
+    }
+  }
+  currRing->pLexOrder=b;
+  if (h==isHomog)
+  {
+    if (strat->ak > 0 && (w!=NULL) && (*w!=NULL))
+    {
+      strat->kModW = kModW = *w;
+      if (vw == NULL)
+      {
+        strat->pOrigFDeg = currRing->pFDeg;
+        strat->pOrigLDeg = currRing->pLDeg;
+        pSetDegProcs(currRing,kModDeg);
+        toReset = TRUE;
+      }
+    }
+    currRing->pLexOrder = TRUE;
+    if (hilb==NULL) strat->LazyPass*=2;
+  }
+  strat->homog=h;
+#ifdef KDEBUG
+  idTest(F);
+  idTest(Q);
+
+#if MYTEST
+  if (TEST_OPT_DEBUG)
+  {
+    PrintS("// kSTD: currRing: ");
+    rWrite(currRing);
+  }
+#endif
+
+#endif
+#ifdef HAVE_PLURAL
+  if (rIsPluralRing(currRing))
+  {
+    const BOOLEAN bIsSCA  = rIsSCA(currRing) && strat->z2homog; // for Z_2 prod-crit
+    strat->no_prod_crit   = ! bIsSCA;
+    if (w!=NULL)
+      r = nc_GB(F, Q, *w, hilb, strat, currRing);
+    else
+      r = nc_GB(F, Q, NULL, hilb, strat, currRing);
+  }
+  else
+#endif
+#ifdef HAVE_RINGS
+  if (rField_is_Ring(currRing))
+  {
+    if(rHasLocalOrMixedOrdering(currRing))
+      r=mora(F,Q,NULL,hilb,strat);
+    else
+      r=bba(F,Q,NULL,hilb,strat);
+  }
+  else
+#endif
+  {
+    if (rHasLocalOrMixedOrdering(currRing))
+    {
+      if (w!=NULL)
+        r=mora(F,Q,*w,hilb,strat);
+      else
+        r=mora(F,Q,NULL,hilb,strat);
+    }
+    else
+    {
+      if (w!=NULL)
+        r=bba(F,Q,*w,hilb,strat);
+      else
+        r=bba(F,Q,NULL,hilb,strat);
+    }
+  }
+#ifdef KDEBUG
+  idTest(r);
+#endif
+  if (toReset)
+  {
+    kModW = NULL;
+    pRestoreDegProcs(currRing,strat->pOrigFDeg, strat->pOrigLDeg);
+  }
+  currRing->pLexOrder = b;
+//Print("%d reductions canceled \n",strat->cel);
+  HCord=strat->HCord;
+  delete(strat);
+  if ((delete_w)&&(w!=NULL)&&(*w!=NULL)) delete *w;
+  return r;
+}
+
+ideal kSba(ideal F, ideal Q, tHomog h,intvec ** w, int sbaOrder, int arri, intvec *hilb,int syzComp,
+          int newIdeal, intvec *vw)
+{
+  if(idIs0(F))
+    return idInit(1,F->rank);
+
+  ideal r;
+  BOOLEAN b=currRing->pLexOrder,toReset=FALSE;
+  BOOLEAN delete_w=(w==NULL);
+  kStrategy strat=new skStrategy;
+  strat->sbaOrder = sbaOrder;
+  if (arri!=0)
+  {
+    strat->rewCrit1 = arriRewDummy;
+    strat->rewCrit2 = arriRewCriterion;
+    strat->rewCrit3 = arriRewCriterionPre;
+  }
+  else
+  {
+    strat->rewCrit1 = faugereRewCriterion;
+    strat->rewCrit2 = faugereRewCriterion;
+    strat->rewCrit3 = faugereRewCriterion;
+  }
+
+  if(!TEST_OPT_RETURN_SB)
+    strat->syzComp = syzComp;
+  if (TEST_OPT_SB_1)
+    #ifdef HAVE_RINGS
+    if(!rField_is_Ring(currRing))
+    #endif
+    strat->newIdeal = newIdeal;
+  if (rField_has_simple_inverse(currRing))
+    strat->LazyPass=20;
+  else
+    strat->LazyPass=2;
+  strat->LazyDegree = 1;
+  strat->enterOnePair=enterOnePairNormal;
+  strat->chainCrit=chainCritNormal;
+  strat->ak = id_RankFreeModule(F,currRing);
+  strat->kModW=kModW=NULL;
+  strat->kHomW=kHomW=NULL;
+  if (vw != NULL)
+  {
+    currRing->pLexOrder=FALSE;
+    strat->kHomW=kHomW=vw;
+    strat->pOrigFDeg = currRing->pFDeg;
+    strat->pOrigLDeg = currRing->pLDeg;
+    pSetDegProcs(currRing,kHomModDeg);
+    toReset = TRUE;
+  }
+  if (h==testHomog)
+  {
+    if (strat->ak == 0)
+    {
+      h = (tHomog)idHomIdeal(F,Q);
+      w=NULL;
+    }
+    else if (!TEST_OPT_DEGBOUND)
+    {
+      h = (tHomog)idHomModule(F,Q,w);
+    }
+  }
+  currRing->pLexOrder=b;
+  if (h==isHomog)
+  {
+    if (strat->ak > 0 && (w!=NULL) && (*w!=NULL))
+    {
+      strat->kModW = kModW = *w;
+      if (vw == NULL)
+      {
+        strat->pOrigFDeg = currRing->pFDeg;
+        strat->pOrigLDeg = currRing->pLDeg;
+        pSetDegProcs(currRing,kModDeg);
+        toReset = TRUE;
+      }
+    }
+    currRing->pLexOrder = TRUE;
+    if (hilb==NULL) strat->LazyPass*=2;
+  }
+  strat->homog=h;
+#ifdef KDEBUG
+  idTest(F);
+  idTest(Q);
+
+#if MYTEST
+  if (TEST_OPT_DEBUG)
+  {
+    PrintS("// kSTD: currRing: ");
+    rWrite(currRing);
+  }
+#endif
+
+#endif
+#ifdef HAVE_PLURAL
+  if (rIsPluralRing(currRing))
+  {
+    const BOOLEAN bIsSCA  = rIsSCA(currRing) && strat->z2homog; // for Z_2 prod-crit
+    strat->no_prod_crit   = ! bIsSCA;
+    if (w!=NULL)
+      r = nc_GB(F, Q, *w, hilb, strat, currRing);
+    else
+      r = nc_GB(F, Q, NULL, hilb, strat, currRing);
+  }
+  else
+#endif
+#ifdef HAVE_RINGS
+  if (rField_is_Ring(currRing))
+    r=bba(F,Q,NULL,hilb,strat);
+  else
+#endif
+  {
+    if (rHasLocalOrMixedOrdering(currRing))
+    {
+      if (w!=NULL)
+        r=mora(F,Q,*w,hilb,strat);
+      else
+        r=mora(F,Q,NULL,hilb,strat);
+    }
+    else
+    {
+      if (w!=NULL)
+        r=sba(F,Q,*w,hilb,strat);
+      else
+        r=sba(F,Q,NULL,hilb,strat);
+    }
+  }
+#ifdef KDEBUG
+  idTest(r);
+#endif
+  if (toReset)
+  {
+    kModW = NULL;
+    pRestoreDegProcs(currRing,strat->pOrigFDeg, strat->pOrigLDeg);
+  }
+  currRing->pLexOrder = b;
+//Print("%d reductions canceled \n",strat->cel);
+  HCord=strat->HCord;
+  delete(strat);
+  if ((delete_w)&&(w!=NULL)&&(*w!=NULL)) delete *w;
+  return r;
+}
+
+#ifdef HAVE_SHIFTBBA
+ideal kStdShift(ideal F, ideal Q, tHomog h,intvec ** w, intvec *hilb,int syzComp,
+                int newIdeal, intvec *vw, int uptodeg, int lV)
+{
+  ideal r;
+  BOOLEAN b=currRing->pLexOrder,toReset=FALSE;
+  BOOLEAN delete_w=(w==NULL);
+  kStrategy strat=new skStrategy;
+
+  if(!TEST_OPT_RETURN_SB)
+    strat->syzComp = syzComp;
+  if (TEST_OPT_SB_1)
+    #ifdef HAVE_RINGS
+    if(!rField_is_Ring(currRing))
+    #endif
+    strat->newIdeal = newIdeal;
+  if (rField_has_simple_inverse(currRing))
+    strat->LazyPass=20;
+  else
+    strat->LazyPass=2;
+  strat->LazyDegree = 1;
+  strat->ak = id_RankFreeModule(F,currRing);
+  strat->kModW=kModW=NULL;
+  strat->kHomW=kHomW=NULL;
+  if (vw != NULL)
+  {
+    currRing->pLexOrder=FALSE;
+    strat->kHomW=kHomW=vw;
+    strat->pOrigFDeg = currRing->pFDeg;
+    strat->pOrigLDeg = currRing->pLDeg;
+    pSetDegProcs(currRing,kHomModDeg);
+    toReset = TRUE;
+  }
+  if (h==testHomog)
+  {
+    if (strat->ak == 0)
+    {
+      h = (tHomog)idHomIdeal(F,Q);
+      w=NULL;
+    }
+    else if (!TEST_OPT_DEGBOUND)
+    {
+      h = (tHomog)idHomModule(F,Q,w);
+    }
+  }
+  currRing->pLexOrder=b;
+  if (h==isHomog)
+  {
+    if (strat->ak > 0 && (w!=NULL) && (*w!=NULL))
+    {
+      strat->kModW = kModW = *w;
+      if (vw == NULL)
+      {
+        strat->pOrigFDeg = currRing->pFDeg;
+        strat->pOrigLDeg = currRing->pLDeg;
+        pSetDegProcs(currRing,kModDeg);
+        toReset = TRUE;
+      }
+    }
+    currRing->pLexOrder = TRUE;
+    if (hilb==NULL) strat->LazyPass*=2;
+  }
+  strat->homog=h;
+#ifdef KDEBUG
+  idTest(F);
+#endif
+  if (rHasLocalOrMixedOrdering(currRing))
+  {
+    /* error: no local ord yet with shifts */
+    Print("No local ordering possible for shifts");
+    return(NULL);
+  }
+  else
+  {
+    /* global ordering */
+    if (w!=NULL)
+      r=bbaShift(F,Q,*w,hilb,strat,uptodeg,lV);
+    else
+      r=bbaShift(F,Q,NULL,hilb,strat,uptodeg,lV);
+  }
+#ifdef KDEBUG
+  idTest(r);
+#endif
+  if (toReset)
+  {
+    kModW = NULL;
+    pRestoreDegProcs(currRing,strat->pOrigFDeg, strat->pOrigLDeg);
+  }
+  currRing->pLexOrder = b;
+//Print("%d reductions canceled \n",strat->cel);
+  HCord=strat->HCord;
+  delete(strat);
+  if ((delete_w)&&(w!=NULL)&&(*w!=NULL)) delete *w;
+  return r;
+}
+#endif
+
+//##############################################################
+//##############################################################
+//##############################################################
+//##############################################################
+//##############################################################
+
+ideal kMin_std(ideal F, ideal Q, tHomog h,intvec ** w, ideal &M, intvec *hilb,
+              int syzComp, int reduced)
+{
+  if(idIs0(F))
+  {
+    M=idInit(1,F->rank);
+    return idInit(1,F->rank);
+  }
+  #ifdef HAVE_RINGS
+  if(rField_is_Ring(currRing))
+  {
+    ideal sb;
+    sb = kStd(F, Q, h, w, hilb);
+    idSkipZeroes(sb);
+    if(IDELEMS(sb) <= IDELEMS(F))
+    {
+        M = idCopy(sb);
+        idSkipZeroes(M);
+        return(sb);
+    }
+    else
+    {
+        M = idCopy(F);
+        idSkipZeroes(M);
+        return(sb);
+    }
+  }
+  #endif
+  ideal r=NULL;
+  int Kstd1_OldDeg = Kstd1_deg,i;
+  intvec* temp_w=NULL;
+  BOOLEAN b=currRing->pLexOrder,toReset=FALSE;
+  BOOLEAN delete_w=(w==NULL);
+  BOOLEAN oldDegBound=TEST_OPT_DEGBOUND;
+  kStrategy strat=new skStrategy;
+
+  if(!TEST_OPT_RETURN_SB)
+     strat->syzComp = syzComp;
+  if (rField_has_simple_inverse(currRing))
+    strat->LazyPass=20;
+  else
+    strat->LazyPass=2;
+  strat->LazyDegree = 1;
+  strat->minim=(reduced % 2)+1;
+  strat->ak = id_RankFreeModule(F,currRing);
+  if (delete_w)
+  {
+    temp_w=new intvec((strat->ak)+1);
+    w = &temp_w;
+  }
+  if (h==testHomog)
+  {
+    if (strat->ak == 0)
+    {
+      h = (tHomog)idHomIdeal(F,Q);
+      w=NULL;
+    }
+    else
+    {
+      h = (tHomog)idHomModule(F,Q,w);
+    }
+  }
+  if (h==isHomog)
+  {
+    if (strat->ak > 0 && (w!=NULL) && (*w!=NULL))
+    {
+      kModW = *w;
+      strat->kModW = *w;
+      assume(currRing->pFDeg != NULL && currRing->pLDeg != NULL);
+      strat->pOrigFDeg = currRing->pFDeg;
+      strat->pOrigLDeg = currRing->pLDeg;
+      pSetDegProcs(currRing,kModDeg);
+
+      toReset = TRUE;
+      if (reduced>1)
+      {
+        Kstd1_OldDeg=Kstd1_deg;
+        Kstd1_deg = -1;
+        for (i=IDELEMS(F)-1;i>=0;i--)
+        {
+          if ((F->m[i]!=NULL) && (currRing->pFDeg(F->m[i],currRing)>=Kstd1_deg))
+            Kstd1_deg = currRing->pFDeg(F->m[i],currRing)+1;
+        }
+      }
+    }
+    currRing->pLexOrder = TRUE;
+    strat->LazyPass*=2;
+  }
+  strat->homog=h;
+  if (rHasLocalOrMixedOrdering(currRing))
+  {
+    if (w!=NULL)
+      r=mora(F,Q,*w,hilb,strat);
+    else
+      r=mora(F,Q,NULL,hilb,strat);
+  }
+  else
+  {
+    if (w!=NULL)
+      r=bba(F,Q,*w,hilb,strat);
+    else
+      r=bba(F,Q,NULL,hilb,strat);
+  }
+#ifdef KDEBUG
+  {
+    int i;
+    for (i=IDELEMS(r)-1; i>=0; i--) pTest(r->m[i]);
+  }
+#endif
+  idSkipZeroes(r);
+  if (toReset)
+  {
+    pRestoreDegProcs(currRing,strat->pOrigFDeg, strat->pOrigLDeg);
+    kModW = NULL;
+  }
+  currRing->pLexOrder = b;
+  HCord=strat->HCord;
+  if ((delete_w)&&(temp_w!=NULL)) delete temp_w;
+  if ((IDELEMS(r)==1) && (r->m[0]!=NULL) && pIsConstant(r->m[0]) && (strat->ak==0))
+  {
+    M=idInit(1,F->rank);
+    M->m[0]=pOne();
+    //if (strat->ak!=0) { pSetComp(M->m[0],strat->ak); pSetmComp(M->m[0]); }
+    if (strat->M!=NULL) idDelete(&strat->M);
+  }
+  else if (strat->M==NULL)
+  {
+    M=idInit(1,F->rank);
+    Warn("no minimal generating set computed");
+  }
+  else
+  {
+    idSkipZeroes(strat->M);
+    M=strat->M;
+  }
+  delete(strat);
+  if (reduced>2)
+  {
+    Kstd1_deg=Kstd1_OldDeg;
+    if (!oldDegBound)
+      si_opt_1 &= ~Sy_bit(OPT_DEGBOUND);
+  }
+  else
+  {
+    if (IDELEMS(M)>IDELEMS(r)) {
+       idDelete(&M);
+       M=idCopy(r); }
+  }
+  return r;
+}
+
+poly kNF(ideal F, ideal Q, poly p,int syzComp, int lazyReduce)
+{
+  if (p==NULL)
+     return NULL;
+
+  poly pp = p;
+
+#ifdef HAVE_PLURAL
+  if(rIsSCA(currRing))
+  {
+    const unsigned int m_iFirstAltVar = scaFirstAltVar(currRing);
+    const unsigned int m_iLastAltVar  = scaLastAltVar(currRing);
+    pp = p_KillSquares(pp, m_iFirstAltVar, m_iLastAltVar, currRing);
+
+    if(Q == currRing->qideal)
+      Q = SCAQuotient(currRing);
+  }
+#endif
+
+  if ((idIs0(F))&&(Q==NULL))
+  {
+#ifdef HAVE_PLURAL
+    if(p != pp)
+      return pp;
+#endif
+    return pCopy(p); /*F+Q=0*/
+  }
+
+  kStrategy strat=new skStrategy;
+  strat->syzComp = syzComp;
+  strat->ak = si_max(id_RankFreeModule(F,currRing),pMaxComp(p));
+  poly res;
+
+  if (rHasLocalOrMixedOrdering(currRing))
+    res=kNF1(F,Q,pp,strat,lazyReduce);
+  else
+    res=kNF2(F,Q,pp,strat,lazyReduce);
+  delete(strat);
+
+#ifdef HAVE_PLURAL
+  if(pp != p)
+    p_Delete(&pp, currRing);
+#endif
+  return res;
+}
+
+ideal kNF(ideal F, ideal Q, ideal p,int syzComp,int lazyReduce)
+{
+  ideal res;
+  if (TEST_OPT_PROT)
+  {
+    Print("(S:%d)",IDELEMS(p));mflush();
+  }
+  if (idIs0(p))
+    return idInit(IDELEMS(p),si_max(p->rank,F->rank));
+
+  ideal pp = p;
+#ifdef HAVE_PLURAL
+  if(rIsSCA(currRing))
+  {
+    const unsigned int m_iFirstAltVar = scaFirstAltVar(currRing);
+    const unsigned int m_iLastAltVar  = scaLastAltVar(currRing);
+    pp = id_KillSquares(pp, m_iFirstAltVar, m_iLastAltVar, currRing, false);
+
+    if(Q == currRing->qideal)
+      Q = SCAQuotient(currRing);
+  }
+#endif
+
+  if ((idIs0(F))&&(Q==NULL))
+  {
+#ifdef HAVE_PLURAL
+    if(p != pp)
+      return pp;
+#endif
+    return idCopy(p); /*F+Q=0*/
+  }
+
+  kStrategy strat=new skStrategy;
+  strat->syzComp = syzComp;
+  strat->ak = si_max(id_RankFreeModule(F,currRing),id_RankFreeModule(p,currRing));
+  if (strat->ak>0) // only for module case, see Tst/Short/bug_reduce.tst
+  {
+    strat->ak = si_max(strat->ak,(int)F->rank);
+  }
+
+  if (rHasLocalOrMixedOrdering(currRing))
+    res=kNF1(F,Q,pp,strat,lazyReduce);
+  else
+    res=kNF2(F,Q,pp,strat,lazyReduce);
+  delete(strat);
+
+#ifdef HAVE_PLURAL
+  if(pp != p)
+    id_Delete(&pp, currRing);
+#endif
+
+  return res;
+}
+
+poly kNF (ideal F, ideal Q, poly p,int syzComp, int lazyReduce, const ring _currRing)
+{
+  const ring save = currRing; if( currRing != _currRing ) rChangeCurrRing(_currRing);
+  poly ret = kNF(F, Q, p, syzComp, lazyReduce);
+  if( currRing != save )     rChangeCurrRing(save);
+  return ret;
+}
+
+/*2
+*interreduces F
+*/
+// old version
+ideal kInterRedOld (ideal F, ideal Q)
+{
+  int j;
+  kStrategy strat = new skStrategy;
+
+  ideal tempF = F;
+  ideal tempQ = Q;
+
+#ifdef HAVE_PLURAL
+  if(rIsSCA(currRing))
+  {
+    const unsigned int m_iFirstAltVar = scaFirstAltVar(currRing);
+    const unsigned int m_iLastAltVar  = scaLastAltVar(currRing);
+    tempF = id_KillSquares(F, m_iFirstAltVar, m_iLastAltVar, currRing);
+
+    // this should be done on the upper level!!! :
+    //    tempQ = SCAQuotient(currRing);
+
+    if(Q == currRing->qideal)
+      tempQ = SCAQuotient(currRing);
+  }
+#endif
+
+//  if (TEST_OPT_PROT)
+//  {
+//    writeTime("start InterRed:");
+//    mflush();
+//  }
+  //strat->syzComp     = 0;
+  strat->kHEdgeFound = (currRing->ppNoether) != NULL;
+  strat->kNoether=pCopy((currRing->ppNoether));
+  strat->ak = id_RankFreeModule(tempF,currRing);
+  initBuchMoraCrit(strat);
+  strat->NotUsedAxis = (BOOLEAN *)omAlloc(((currRing->N)+1)*sizeof(BOOLEAN));
+  for (j=(currRing->N); j>0; j--) strat->NotUsedAxis[j] = TRUE;
+  strat->enterS      = enterSBba;
+  strat->posInT      = posInT17;
+  strat->initEcart   = initEcartNormal;
+  strat->sl   = -1;
+  strat->tl          = -1;
+  strat->tmax        = setmaxT;
+  strat->T           = initT();
+  strat->R           = initR();
+  strat->sevT        = initsevT();
+  if (rHasLocalOrMixedOrdering(currRing))   strat->honey = TRUE;
+  initS(tempF, tempQ, strat);
+  if (TEST_OPT_REDSB)
+    strat->noTailReduction=FALSE;
+  updateS(TRUE,strat);
+  if (TEST_OPT_REDSB && TEST_OPT_INTSTRATEGY)
+    completeReduce(strat);
+  //else if (TEST_OPT_PROT) PrintLn();
+  pDelete(&strat->kHEdge);
+  omFreeSize((ADDRESS)strat->T,strat->tmax*sizeof(TObject));
+  omFreeSize((ADDRESS)strat->ecartS,IDELEMS(strat->Shdl)*sizeof(int));
+  omFreeSize((ADDRESS)strat->sevS,IDELEMS(strat->Shdl)*sizeof(unsigned long));
+  omFreeSize((ADDRESS)strat->NotUsedAxis,((currRing->N)+1)*sizeof(BOOLEAN));
+  omfree(strat->sevT);
+  omfree(strat->S_2_R);
+  omfree(strat->R);
+
+  if (strat->fromQ)
+  {
+    for (j=IDELEMS(strat->Shdl)-1;j>=0;j--)
+    {
+      if(strat->fromQ[j]) pDelete(&strat->Shdl->m[j]);
+    }
+    omFreeSize((ADDRESS)strat->fromQ,IDELEMS(strat->Shdl)*sizeof(int));
+  }
+//  if (TEST_OPT_PROT)
+//  {
+//    writeTime("end Interred:");
+//    mflush();
+//  }
+  ideal shdl=strat->Shdl;
+  idSkipZeroes(shdl);
+  if (strat->fromQ)
+  {
+    strat->fromQ=NULL;
+    ideal res=kInterRed(shdl,NULL);
+    idDelete(&shdl);
+    shdl=res;
+  }
+  delete(strat);
+#ifdef HAVE_PLURAL
+  if( tempF != F )
+    id_Delete( &tempF, currRing);
+#endif
+  return shdl;
+}
+// new version
+ideal kInterRedBba (ideal F, ideal Q, int &need_retry)
+{
+  need_retry=0;
+  int   red_result = 1;
+  int   olddeg,reduc;
+  BOOLEAN withT = FALSE;
+  // BOOLEAN toReset=FALSE;
+  kStrategy strat=new skStrategy;
+  tHomog h;
+  intvec * w=NULL;
+
+  if (rField_has_simple_inverse(currRing))
+    strat->LazyPass=20;
+  else
+    strat->LazyPass=2;
+  strat->LazyDegree = 1;
+  strat->ak = id_RankFreeModule(F,currRing);
+  strat->syzComp = strat->ak;
+  strat->kModW=kModW=NULL;
+  strat->kHomW=kHomW=NULL;
+  if (strat->ak == 0)
+  {
+    h = (tHomog)idHomIdeal(F,Q);
+    w=NULL;
+  }
+  else if (!TEST_OPT_DEGBOUND)
+  {
+    h = (tHomog)idHomModule(F,Q,&w);
+  }
+  if (h==isHomog)
+  {
+    if (strat->ak > 0 && (w!=NULL) && (w!=NULL))
+    {
+      strat->kModW = kModW = w;
+      strat->pOrigFDeg = currRing->pFDeg;
+      strat->pOrigLDeg = currRing->pLDeg;
+      pSetDegProcs(currRing,kModDeg);
+      // toReset = TRUE;
+    }
+    strat->LazyPass*=2;
+  }
+  strat->homog=h;
+#ifdef KDEBUG
+  idTest(F);
+#endif
+
+  initBuchMoraCrit(strat); /*set Gebauer, honey, sugarCrit*/
+  initBuchMoraPos(strat);
+  initBba(F,strat);
+  /*set enterS, spSpolyShort, reduce, red, initEcart, initEcartPair*/
+  strat->posInL=posInL0; /* ord according pComp */
+
+  /*Shdl=*/initBuchMora(F, Q, strat);
+  reduc = olddeg = 0;
+
+#ifndef NO_BUCKETS
+  if (!TEST_OPT_NOT_BUCKETS)
+    strat->use_buckets = 1;
+#endif
+
+  // redtailBBa against T for inhomogenous input
+  if (!TEST_OPT_OLDSTD)
+    withT = ! strat->homog;
+
+  // strat->posInT = posInT_pLength;
+  kTest_TS(strat);
+
+#ifdef HAVE_TAIL_RING
+  kStratInitChangeTailRing(strat);
+#endif
+
+  /* compute------------------------------------------------------- */
+  while (strat->Ll >= 0)
+  {
+    #ifdef KDEBUG
+      if (TEST_OPT_DEBUG) messageSets(strat);
+    #endif
+    if (strat->Ll== 0) strat->interpt=TRUE;
+    /* picks the last element from the lazyset L */
+    strat->P = strat->L[strat->Ll];
+    strat->Ll--;
+
+    if (strat->P.p1 == NULL)
+    {
+      // for input polys, prepare reduction
+      strat->P.PrepareRed(strat->use_buckets);
+    }
+
+    if (strat->P.p == NULL && strat->P.t_p == NULL)
+    {
+      red_result = 0;
+    }
+    else
+    {
+      if (TEST_OPT_PROT)
+        message(strat->P.pFDeg(),
+                &olddeg,&reduc,strat, red_result);
+
+      /* reduction of the element choosen from L */
+      red_result = strat->red(&strat->P,strat);
+    }
+
+    // reduction to non-zero new poly
+    if (red_result == 1)
+    {
+      /* statistic */
+      if (TEST_OPT_PROT) PrintS("s");
+
+      // get the polynomial (canonicalize bucket, make sure P.p is set)
+      strat->P.GetP(strat->lmBin);
+
+      int pos=posInS(strat,strat->sl,strat->P.p,strat->P.ecart);
+
+      // reduce the tail and normalize poly
+      // in the ring case we cannot expect LC(f) = 1,
+      // therefore we call pContent instead of pNorm
+      if ((TEST_OPT_INTSTRATEGY) || (rField_is_Ring(currRing)))
+      {
+        strat->P.pCleardenom();
+        if (0)
+        //if ((TEST_OPT_REDSB)||(TEST_OPT_REDTAIL))
+        {
+          strat->P.p = redtailBba(&(strat->P),pos-1,strat, withT);
+          strat->P.pCleardenom();
+        }
+      }
+      else
+      {
+        strat->P.pNorm();
+        if (0)
+        //if ((TEST_OPT_REDSB)||(TEST_OPT_REDTAIL))
+          strat->P.p = redtailBba(&(strat->P),pos-1,strat, withT);
+      }
+
+#ifdef KDEBUG
+      if (TEST_OPT_DEBUG){PrintS("new s:");strat->P.wrp();PrintLn();}
+#endif
+
+      // enter into S, L, and T
+      if ((!TEST_OPT_IDLIFT) || (pGetComp(strat->P.p) <= strat->syzComp))
+      {
+        enterT(strat->P, strat);
+        // posInS only depends on the leading term
+        strat->enterS(strat->P, pos, strat, strat->tl);
+
+        if (pos<strat->sl)
+        {
+          need_retry++;
+          // move all "larger" elements fromS to L
+          // remove them from T
+          int ii=pos+1;
+          for(;ii<=strat->sl;ii++)
+          {
+            LObject h;
+            memset(&h,0,sizeof(h));
+            h.tailRing=strat->tailRing;
+            h.p=strat->S[ii]; strat->S[ii]=NULL;
+            strat->initEcart(&h);
+            h.sev=strat->sevS[ii];
+            int jj=strat->tl;
+            while (jj>=0)
+            {
+              if (strat->T[jj].p==h.p)
+              {
+                strat->T[jj].p=NULL;
+                if (jj<strat->tl)
+                {
+                  memmove(&(strat->T[jj]),&(strat->T[jj+1]),
+                          (strat->tl-jj)*sizeof(strat->T[jj]));
+                  memmove(&(strat->sevT[jj]),&(strat->sevT[jj+1]),
+                          (strat->tl-jj)*sizeof(strat->sevT[jj]));
+                }
+                strat->tl--;
+                break;
+              }
+              jj--;
+            }
+            int lpos=strat->posInL(strat->L,strat->Ll,&h,strat);
+            enterL(&strat->L,&strat->Ll,&strat->Lmax,h,lpos);
+            #ifdef KDEBUG
+            if (TEST_OPT_DEBUG)
+            {
+              Print("move S[%d] -> L[%d]: ",ii,pos);
+              p_wrp(h.p,currRing, strat->tailRing);
+              PrintLn();
+            }
+            #endif
+          }
+          if (strat->fromQ!=NULL)
+          {
+            for(ii=pos+1;ii<=strat->sl;ii++) strat->fromQ[ii]=0;
+          }
+          strat->sl=pos;
+        }
+      }
+      else
+      {
+        // clean P
+      }
+      if (strat->P.lcm!=NULL)
+#ifdef HAVE_RINGS
+        pLmDelete(strat->P.lcm);
+#else
+        pLmFree(strat->P.lcm);
+#endif
+    }
+
+#ifdef KDEBUG
+    if (TEST_OPT_DEBUG)
+    {
+      messageSets(strat);
+    }
+    memset(&(strat->P), 0, sizeof(strat->P));
+#endif
+    //kTest_TS(strat);: i_r out of sync in kInterRedBba, but not used!
+  }
+#ifdef KDEBUG
+  //if (TEST_OPT_DEBUG) messageSets(strat);
+#endif
+  /* complete reduction of the standard basis--------- */
+
+  if((need_retry<=0) && (TEST_OPT_REDSB))
+  {
+    completeReduce(strat);
+#ifdef HAVE_TAIL_RING
+    if (strat->completeReduce_retry)
+    {
+      // completeReduce needed larger exponents, retry
+      // to reduce with S (instead of T)
+      // and in currRing (instead of strat->tailRing)
+      cleanT(strat);strat->tailRing=currRing;
+      int i;
+      for(i=strat->sl;i>=0;i--) strat->S_2_R[i]=-1;
+      completeReduce(strat);
+    }
+#endif
+  }
+  else if (TEST_OPT_PROT) PrintLn();
+
+  /* release temp data-------------------------------- */
+  exitBuchMora(strat);
+//  if (TEST_OPT_WEIGHTM)
+//  {
+//    pRestoreDegProcs(currRing,strat->pOrigFDeg, strat->pOrigLDeg);
+//    if (ecartWeights)
+//    {
+//      omFreeSize((ADDRESS)ecartWeights,((currRing->N)+1)*sizeof(short));
+//      ecartWeights=NULL;
+//    }
+//  }
+  //if (TEST_OPT_PROT) messageStat(0/*hilbcount*/,strat);
+  if (Q!=NULL) updateResult(strat->Shdl,Q,strat);
+  ideal res=strat->Shdl;
+  strat->Shdl=NULL;
+  delete strat;
+  if (w!=NULL) delete w;
+  return res;
+}
+ideal kInterRed (ideal F, ideal Q)
+{
+#ifdef HAVE_PLURAL
+  if(rIsPluralRing(currRing)) return kInterRedOld(F,Q);
+#endif
+  if ((rHasLocalOrMixedOrdering(currRing))|| (rField_is_numeric(currRing))
+  #ifdef HAVE_RINGS
+  ||(rField_is_Ring(currRing))
+  #endif
+  )
+    return kInterRedOld(F,Q);
+
+    //return kInterRedOld(F,Q);
+
+  BITSET save1;
+  SI_SAVE_OPT1(save1);
+  //si_opt_1|=Sy_bit(OPT_NOT_SUGAR);
+  si_opt_1|=Sy_bit(OPT_REDTHROUGH);
+  //si_opt_1&= ~Sy_bit(OPT_REDTAIL);
+  //si_opt_1&= ~Sy_bit(OPT_REDSB);
+  //extern char * showOption() ;
+  //Print("%s\n",showOption());
+
+  int need_retry;
+  int counter=3;
+  ideal res, res1;
+  int elems;
+  ideal null=NULL;
+  if ((Q==NULL) || (!TEST_OPT_REDSB))
+  {
+    elems=idElem(F);
+    res=kInterRedBba(F,Q,need_retry);
+  }
+  else
+  {
+    ideal FF=idSimpleAdd(F,Q);
+    res=kInterRedBba(FF,NULL,need_retry);
+    idDelete(&FF);
+    null=idInit(1,1);
+    if (need_retry)
+      res1=kNF(null,Q,res,0,KSTD_NF_LAZY);
+    else
+      res1=kNF(null,Q,res);
+    idDelete(&res);
+    res=res1;
+    need_retry=1;
+  }
+  if (idElem(res)<=1) need_retry=0;
+  while (need_retry && (counter>0))
+  {
+    #ifdef KDEBUG
+    if (TEST_OPT_DEBUG) { Print("retry counter %d\n",counter); }
+    #endif
+    res1=kInterRedBba(res,Q,need_retry);
+    int new_elems=idElem(res1);
+    counter -= (new_elems >= elems);
+    elems = new_elems;
+    idDelete(&res);
+    if (idElem(res1)<=1) need_retry=0;
+    if ((Q!=NULL) && (TEST_OPT_REDSB))
+    {
+      if (need_retry)
+        res=kNF(null,Q,res1,0,KSTD_NF_LAZY);
+      else
+        res=kNF(null,Q,res1);
+      idDelete(&res1);
+    }
+    else
+      res = res1;
+    if (idElem(res)<=1) need_retry=0;
+  }
+  if (null!=NULL) idDelete(&null);
+  SI_RESTORE_OPT1(save1);
+  idSkipZeroes(res);
+  return res;
+}
+
+// returns TRUE if mora should use buckets, false otherwise
+static BOOLEAN kMoraUseBucket(kStrategy strat)
+{
+#ifdef MORA_USE_BUCKETS
+  if (TEST_OPT_NOT_BUCKETS)
+    return FALSE;
+  if (strat->red == redFirst)
+  {
+#ifdef NO_LDEG
+    if (strat->syzComp==0)
+      return TRUE;
+#else
+    if ((strat->homog || strat->honey) && (strat->syzComp==0))
+      return TRUE;
+#endif
+  }
+  else
+  {
+    assume(strat->red == redEcart || strat->red == redRiloc);
+    if (strat->honey && (strat->syzComp==0))
+      return TRUE;
+  }
+#endif
+  return FALSE;
+}
diff --git a/kernel/GBEngine/kstd1.h b/kernel/GBEngine/kstd1.h
new file mode 100644
index 0000000..5525517
--- /dev/null
+++ b/kernel/GBEngine/kstd1.h
@@ -0,0 +1,94 @@
+#ifndef KSTD1_H
+#define KSTD1_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT
+*/
+#include <kernel/structs.h>
+#include <polys/monomials/ring.h>
+
+ideal mora (ideal F, ideal Q,intvec *w,intvec *hilb,kStrategy strat);
+
+// lazy_reduce flags: can be combined by |
+#define KSTD_NF_LAZY   1
+  // do only a reduction of the leading term
+#define KSTD_NF_ECART  2
+  // only local: recude even with bad ecart
+#define KSTD_NF_NONORM 4
+  // only global: avoid normalization, return a multiply of NF
+
+poly kNF1(ideal F, ideal Q, poly q, kStrategy strat, int lazyReduce);
+ideal kNF1 (ideal F,ideal Q,ideal q, kStrategy strat, int lazyReduce);
+
+poly kNF (ideal F, ideal Q, poly p,int syzComp=0, int lazyReduce=0);
+ideal kNF(ideal F, ideal Q, ideal p,int syzComp=0, int lazyReduce=0);
+
+/// NOTE: this is just a wrapper which sets currRing for the actual kNF call
+poly kNF (ideal F, ideal Q, poly p,int syzComp, int lazyReduce, const ring _currRing);
+ideal kSba(ideal F,ideal Q, tHomog h, intvec ** mw, int incremental=0, int arri=0, intvec *hilb=NULL,
+          int syzComp=0,int newIdeal=0, intvec *vw=NULL);
+
+ideal kStd(ideal F, ideal Q, tHomog h, intvec ** mw,intvec *hilb=NULL,
+          int syzComp=0,int newIdeal=0, intvec *vw=NULL);
+
+ideal kStdShift(ideal F, ideal Q, tHomog h,intvec ** w, intvec *hilb,int syzComp,
+		int newIdeal, intvec *vw, int uptodeg, int lVblock);
+
+/* the following global data are defined in kutil.cc */
+//extern int syzComp;
+  /*stop building pairs after that component --> ideals.cc, syz.cc */
+extern int LazyPass,LazyDegree,Kstd1_mu,Kstd1_deg;
+  /*parameters for Lazy or global stops --> ipshell.cc, grammar.y*/
+extern BITSET kOptions;
+  /*the known test options (a constant)*/
+extern BITSET validOpts;
+
+void initMora(ideal F,kStrategy strat);
+
+ideal kInterRed (ideal F, ideal Q=NULL);
+ideal kInterRedOld (ideal F, ideal Q=NULL);
+long   kModDeg(poly p, ring r = currRing);
+long  kHomModDeg(poly p, ring r = currRing);
+
+ideal stdred(ideal F, ideal Q, tHomog h,intvec ** w);
+
+ideal kMin_std(ideal F, ideal Q, tHomog h,intvec ** w, ideal &M,
+              intvec *hilb=NULL, int syzComp=0,int reduced=0);
+
+
+extern intvec * kModW;
+extern intvec * kHomW;
+
+
+/* options:
+0 prot
+1 redSB
+2 notBucket
+3 notSugar
+4 interrupt
+5 sugarCrit
+6 teach
+7 cancel unit: obachman 11/00 tossed
+8 morepairs: obachman 11/00: tossed
+9 return SB (syz,quotient,intersect)
+10 fastHC
+11-19 sort in L/T
+20 redBest: obachman 11/00 tossed
+
+22 staircaseBound: in NF create a HC x1^degBound+1
+23 multBound
+24 degBound
+25 no redTail(p)/redTail(s)
+26 integer strategy
+27 stop at HC (finiteDeterminacyTest)
+28 infRedTail: ignore ecart in local redTail-calls
+29 kStd + 1 new element
+30 noRedSyz
+31 weight
+verbose:31 stop at certain weights
+*/
+
+#endif
+
diff --git a/kernel/GBEngine/kstd2.cc b/kernel/GBEngine/kstd2.cc
new file mode 100644
index 0000000..ded82c8
--- /dev/null
+++ b/kernel/GBEngine/kstd2.cc
@@ -0,0 +1,3415 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+*  ABSTRACT -  Kernel: alg. of Buchberger
+*/
+
+// #define PDEBUG 2
+
+
+
+
+
+#include <kernel/mod2.h>
+
+#ifndef SING_NDEBUG
+# define MYTEST 0
+#else /* ifndef SING_NDEBUG */
+# define MYTEST 0
+#endif /* ifndef SING_NDEBUG */
+
+#if MYTEST
+# ifdef HAVE_TAIL_RING
+#  undef HAVE_TAIL_RING
+# endif // ifdef HAVE_TAIL_RING
+#endif
+
+// define if no buckets should be used
+// #define NO_BUCKETS
+
+#ifdef HAVE_PLURAL
+#define PLURAL_INTERNAL_DECLARATIONS 1
+#endif
+
+/***********************************************
+ * SBA stuff -- start
+***********************************************/
+#define DEBUGF50  0
+#define DEBUGF51  0
+
+#ifdef DEBUGF5
+#undef DEBUGF5
+//#define DEBUGF5 1
+#endif
+
+#define F5C       1
+#if F5C
+  #define F5CTAILRED 1
+#endif
+
+#define SBA_INTERRED_START                  0
+#define SBA_TAIL_RED                        1
+#define SBA_PRODUCT_CRITERION               0
+#define SBA_PRINT_ZERO_REDUCTIONS           0
+#define SBA_PRINT_REDUCTION_STEPS           0
+#define SBA_PRINT_OPERATIONS                0
+#define SBA_PRINT_SIZE_G                    0
+#define SBA_PRINT_SIZE_SYZ                  0
+#define SBA_PRINT_PRODUCT_CRITERION         0
+
+// counts sba's reduction steps
+#if SBA_PRINT_REDUCTION_STEPS
+long sba_reduction_steps;
+long sba_interreduction_steps;
+#endif
+#if SBA_PRINT_OPERATIONS
+long sba_operations;
+long sba_interreduction_operations;
+#endif
+
+/***********************************************
+ * SBA stuff -- done
+***********************************************/
+
+#include <kernel/GBEngine/kutil.h>
+#include <misc/options.h>
+#include <omalloc/omalloc.h>
+#include <kernel/polys.h>
+#include <kernel/ideals.h>
+#include <kernel/GBEngine/kstd1.h>
+#include <kernel/GBEngine/khstd.h>
+#include <polys/kbuckets.h>
+#include <polys/prCopy.h>
+//#include "cntrlc.h"
+#include <polys/weight.h>
+#include <misc/intvec.h>
+#ifdef HAVE_PLURAL
+#include <polys/nc/nc.h>
+#endif
+// #include "timer.h"
+
+/* shiftgb stuff */
+#include <kernel/GBEngine/shiftgb.h>
+
+  int (*test_PosInT)(const TSet T,const int tl,LObject &h);
+  int (*test_PosInL)(const LSet set, const int length,
+                LObject* L,const kStrategy strat);
+
+// return -1 if no divisor is found
+//        number of first divisor, otherwise
+int kFindDivisibleByInT(const TSet &T, const unsigned long* sevT,
+                        const int tl, const LObject* L, const int start)
+{
+  unsigned long not_sev = ~L->sev;
+  int j = start;
+  poly p=L->p;
+  ring r=currRing;
+  L->GetLm(p, r);
+
+  pAssume(~not_sev == p_GetShortExpVector(p, r));
+
+  if (r == currRing)
+  {
+    loop
+    {
+      if (j > tl) return -1;
+#if defined(PDEBUG) || defined(PDIV_DEBUG)
+      if (p_LmShortDivisibleBy(T[j].p, sevT[j],
+                               p, not_sev, r))
+        return j;
+#else
+      if (!(sevT[j] & not_sev) &&
+          p_LmDivisibleBy(T[j].p, p, r))
+        return j;
+#endif
+      j++;
+    }
+  }
+  else
+  {
+    loop
+    {
+      if (j > tl) return -1;
+#if defined(PDEBUG) || defined(PDIV_DEBUG)
+      if (p_LmShortDivisibleBy(T[j].t_p, sevT[j],
+                               p, not_sev, r))
+        return j;
+#else
+      if (!(sevT[j] & not_sev) &&
+          p_LmDivisibleBy(T[j].t_p, p, r))
+        return j;
+#endif
+      j++;
+    }
+  }
+}
+
+// same as above, only with set S
+int kFindDivisibleByInS(const kStrategy strat, int* max_ind, LObject* L)
+{
+  unsigned long not_sev = ~L->sev;
+  poly p = L->GetLmCurrRing();
+  int j = 0;
+
+  pAssume(~not_sev == p_GetShortExpVector(p, currRing));
+#if 1
+  int ende;
+  if ((strat->ak>0) || currRing->pLexOrder) ende=strat->sl;
+  else ende=posInS(strat,*max_ind,p,0)+1;
+  if (ende>(*max_ind)) ende=(*max_ind);
+#else
+  int ende=strat->sl;
+#endif
+  (*max_ind)=ende;
+  loop
+  {
+    if (j > ende) return -1;
+#if defined(PDEBUG) || defined(PDIV_DEBUG)
+    if (p_LmShortDivisibleBy(strat->S[j], strat->sevS[j],
+                             p, not_sev, currRing))
+        return j;
+#else
+    if ( !(strat->sevS[j] & not_sev) &&
+         p_LmDivisibleBy(strat->S[j], p, currRing))
+      return j;
+#endif
+    j++;
+  }
+}
+
+int kFindNextDivisibleByInS(const kStrategy strat, int start,int max_ind, LObject* L)
+{
+  unsigned long not_sev = ~L->sev;
+  poly p = L->GetLmCurrRing();
+  int j = start;
+
+  pAssume(~not_sev == p_GetShortExpVector(p, currRing));
+#if 1
+  int ende=max_ind;
+#else
+  int ende=strat->sl;
+#endif
+  loop
+  {
+    if (j > ende) return -1;
+#if defined(PDEBUG) || defined(PDIV_DEBUG)
+    if (p_LmShortDivisibleBy(strat->S[j], strat->sevS[j],
+                             p, not_sev, currRing))
+        return j;
+#else
+    if ( !(strat->sevS[j] & not_sev) &&
+         p_LmDivisibleBy(strat->S[j], p, currRing))
+      return j;
+#endif
+    j++;
+  }
+}
+
+#ifdef HAVE_RINGS
+poly kFindZeroPoly(poly input_p, ring leadRing, ring tailRing)
+{
+  // m = currRing->ch
+
+  if (input_p == NULL) return NULL;
+
+  poly p = input_p;
+  poly zeroPoly = NULL;
+  unsigned long a = (unsigned long) pGetCoeff(p);
+
+  int k_ind2 = 0;
+  int a_ind2 = ind2(a);
+
+  // unsigned long k = 1;
+  // of interest is only k_ind2, special routine for improvement ... TODO OLIVER
+  for (int i = 1; i <= leadRing->N; i++)
+  {
+    k_ind2 = k_ind2 + ind_fact_2(p_GetExp(p, i, leadRing));
+  }
+
+  a = (unsigned long) pGetCoeff(p);
+
+  number tmp1;
+  poly tmp2, tmp3;
+  poly lead_mult = p_ISet(1, tailRing);
+  if (n_GetChar(leadRing->cf) <= k_ind2 + a_ind2)
+  {
+    int too_much = k_ind2 + a_ind2 - n_GetChar(leadRing->cf);
+    int s_exp;
+    zeroPoly = p_ISet(a, tailRing);
+    for (int i = 1; i <= leadRing->N; i++)
+    {
+      s_exp = p_GetExp(p, i,leadRing);
+      if (s_exp % 2 != 0)
+      {
+        s_exp = s_exp - 1;
+      }
+      while ( (0 < ind2(s_exp)) && (ind2(s_exp) <= too_much) )
+      {
+        too_much = too_much - ind2(s_exp);
+        s_exp = s_exp - 2;
+      }
+      p_SetExp(lead_mult, i, p_GetExp(p, i,leadRing) - s_exp, tailRing);
+      for (unsigned long j = 1; j <= s_exp; j++)
+      {
+        tmp1 = nInit(j);
+        tmp2 = p_ISet(1, tailRing);
+        p_SetExp(tmp2, i, 1, tailRing);
+        p_Setm(tmp2, tailRing);
+        if (nIsZero(tmp1))
+        { // should nowbe obsolet, test ! TODO OLIVER
+          zeroPoly = p_Mult_q(zeroPoly, tmp2, tailRing);
+        }
+        else
+        {
+          tmp3 = p_NSet(nCopy(tmp1), tailRing);
+          zeroPoly = p_Mult_q(zeroPoly, p_Add_q(tmp3, tmp2, tailRing), tailRing);
+        }
+      }
+    }
+    p_Setm(lead_mult, tailRing);
+    zeroPoly = p_Mult_mm(zeroPoly, lead_mult, tailRing);
+    tmp2 = p_NSet(nCopy(pGetCoeff(zeroPoly)), leadRing);
+    for (int i = 1; i <= leadRing->N; i++)
+    {
+      pSetExp(tmp2, i, p_GetExp(zeroPoly, i, tailRing));
+    }
+    p_Setm(tmp2, leadRing);
+    zeroPoly = p_LmDeleteAndNext(zeroPoly, tailRing);
+    pNext(tmp2) = zeroPoly;
+    return tmp2;
+  }
+/*  unsigned long alpha_k = twoPow(leadRing->ch - k_ind2);
+  if (1 == 0 && alpha_k <= a)
+  {  // Temporarly disabled, reducing coefficients not compatible with std TODO Oliver
+    zeroPoly = p_ISet((a / alpha_k)*alpha_k, tailRing);
+    for (int i = 1; i <= leadRing->N; i++)
+    {
+      for (unsigned long j = 1; j <= p_GetExp(p, i, leadRing); j++)
+      {
+        tmp1 = nInit(j);
+        tmp2 = p_ISet(1, tailRing);
+        p_SetExp(tmp2, i, 1, tailRing);
+        p_Setm(tmp2, tailRing);
+        if (nIsZero(tmp1))
+        {
+          zeroPoly = p_Mult_q(zeroPoly, tmp2, tailRing);
+        }
+        else
+        {
+          tmp3 = p_ISet((unsigned long) tmp1, tailRing);
+          zeroPoly = p_Mult_q(zeroPoly, p_Add_q(tmp2, tmp3, tailRing), tailRing);
+        }
+      }
+    }
+    tmp2 = p_ISet((unsigned long) pGetCoeff(zeroPoly), leadRing);
+    for (int i = 1; i <= leadRing->N; i++)
+    {
+      pSetExp(tmp2, i, p_GetExp(zeroPoly, i, tailRing));
+    }
+    p_Setm(tmp2, leadRing);
+    zeroPoly = p_LmDeleteAndNext(zeroPoly, tailRing);
+    pNext(tmp2) = zeroPoly;
+    return tmp2;
+  } */
+  return NULL;
+}
+#endif
+
+
+#ifdef HAVE_RINGS
+/*2
+*  reduction procedure for the ring Z/2^m
+*/
+int redRing (LObject* h,kStrategy strat)
+{
+  if (h->IsNull()) return 0; // spoly is zero (can only occure with zero divisors)
+  if (strat->tl<0) return 1;
+
+  int at/*,i*/;
+  long d;
+  int j = 0;
+  int pass = 0;
+  // poly zeroPoly = NULL;
+
+// TODO warum SetpFDeg notwendig?
+  h->SetpFDeg();
+  assume(h->pFDeg() == h->FDeg);
+  long reddeg = h->GetpFDeg();
+
+  h->SetShortExpVector();
+  loop
+  {
+    j = kFindDivisibleByInT(strat->T, strat->sevT, strat->tl, h);
+    if (j < 0) return 1;
+    ksReducePoly(h, &(strat->T[j]), NULL, NULL, strat); // with debug output
+
+    if (h->GetLmTailRing() == NULL)
+    {
+      if (h->lcm!=NULL) pLmDelete(h->lcm);
+#ifdef KDEBUG
+      h->lcm=NULL;
+#endif
+      h->Clear();
+      return 0;
+    }
+    h->SetShortExpVector();
+    d = h->SetpFDeg();
+    /*- try to reduce the s-polynomial -*/
+    pass++;
+    if (!TEST_OPT_REDTHROUGH &&
+        (strat->Ll >= 0) && ((d > reddeg) || (pass > strat->LazyPass)))
+    {
+      h->SetLmCurrRing();
+      if (strat->posInLDependsOnLength)
+        h->SetLength(strat->length_pLength);
+      at = strat->posInL(strat->L,strat->Ll,h,strat);
+      if (at <= strat->Ll)
+      {
+#ifdef KDEBUG
+        if (TEST_OPT_DEBUG) Print(" ->L[%d]\n",at);
+#endif
+        enterL(&strat->L,&strat->Ll,&strat->Lmax,*h,at);     // NOT RING CHECKED OLIVER
+        h->Clear();
+        return -1;
+      }
+    }
+    if (d != reddeg)
+    {
+      if (d >= strat->tailRing->bitmask)
+      {
+        if (h->pTotalDeg() >= strat->tailRing->bitmask)
+        {
+          strat->overflow=TRUE;
+          //Print("OVERFLOW in redRing d=%ld, max=%ld\n",d,strat->tailRing->bitmask);
+          h->GetP();
+          at = strat->posInL(strat->L,strat->Ll,h,strat);
+          enterL(&strat->L,&strat->Ll,&strat->Lmax,*h,at);
+          h->Clear();
+          return -1;
+        }
+      }
+      else if ((TEST_OPT_PROT) && (strat->Ll < 0))
+      {
+        Print(".%ld",d);mflush();
+        reddeg = d;
+      }
+    }
+  }
+}
+#endif
+
+/*2
+*  reduction procedure for the homogeneous case
+*  and the case of a degree-ordering
+*/
+int redHomog (LObject* h,kStrategy strat)
+{
+  if (strat->tl<0) return 1;
+  //if (h->GetLmTailRing()==NULL) return 0; // HS: SHOULD NOT BE NEEDED!
+  assume(h->FDeg == h->pFDeg());
+
+  poly h_p;
+  int i,j,at,pass, ii;
+  unsigned long not_sev;
+  // long reddeg,d;
+
+  pass = j = 0;
+  // d = reddeg = h->GetpFDeg();
+  h->SetShortExpVector();
+  int li;
+  h_p = h->GetLmTailRing();
+  not_sev = ~ h->sev;
+  loop
+  {
+    j = kFindDivisibleByInT(strat->T, strat->sevT, strat->tl, h);
+    if (j < 0) return 1;
+
+    li = strat->T[j].pLength;
+    ii = j;
+    /*
+     * the polynomial to reduce with (up to the moment) is;
+     * pi with length li
+     */
+    i = j;
+#if 1
+    if (TEST_OPT_LENGTH)
+    loop
+    {
+      /*- search the shortest possible with respect to length -*/
+      i++;
+      if (i > strat->tl)
+        break;
+      if (li<=1)
+        break;
+      if ((strat->T[i].pLength < li)
+         &&
+          p_LmShortDivisibleBy(strat->T[i].GetLmTailRing(), strat->sevT[i],
+                               h_p, not_sev, strat->tailRing))
+      {
+        /*
+         * the polynomial to reduce with is now;
+         */
+        li = strat->T[i].pLength;
+        ii = i;
+      }
+    }
+#endif
+
+    /*
+     * end of search: have to reduce with pi
+     */
+#ifdef KDEBUG
+    if (TEST_OPT_DEBUG)
+    {
+      PrintS("red:");
+      h->wrp();
+      PrintS(" with ");
+      strat->T[ii].wrp();
+    }
+#endif
+    assume(strat->fromT == FALSE);
+
+    ksReducePoly(h, &(strat->T[ii]), NULL, NULL, strat);
+#if SBA_PRINT_REDUCTION_STEPS
+    sba_interreduction_steps++;
+#endif
+#if SBA_PRINT_OPERATIONS
+    sba_interreduction_operations  +=  pLength(strat->T[ii].p);
+#endif
+
+#ifdef KDEBUG
+    if (TEST_OPT_DEBUG)
+    {
+      PrintS("\nto ");
+      h->wrp();
+      PrintLn();
+    }
+#endif
+
+    h_p = h->GetLmTailRing();
+    if (h_p == NULL)
+    {
+      if (h->lcm!=NULL) pLmFree(h->lcm);
+#ifdef KDEBUG
+      h->lcm=NULL;
+#endif
+      return 0;
+    }
+    h->SetShortExpVector();
+    not_sev = ~ h->sev;
+    /*
+     * try to reduce the s-polynomial h
+     *test first whether h should go to the lazyset L
+     *-if the degree jumps
+     *-if the number of pre-defined reductions jumps
+     */
+    pass++;
+    if (!TEST_OPT_REDTHROUGH && (strat->Ll >= 0) && (pass > strat->LazyPass))
+    {
+      h->SetLmCurrRing();
+      at = strat->posInL(strat->L,strat->Ll,h,strat);
+      if (at <= strat->Ll)
+      {
+        int dummy=strat->sl;
+        if (kFindDivisibleByInS(strat, &dummy, h) < 0)
+          return 1;
+        enterL(&strat->L,&strat->Ll,&strat->Lmax,*h,at);
+#ifdef KDEBUG
+        if (TEST_OPT_DEBUG)
+          Print(" lazy: -> L%d\n",at);
+#endif
+        h->Clear();
+        return -1;
+      }
+    }
+  }
+}
+
+KINLINE int ksReducePolyTailSig(LObject* PR, TObject* PW, LObject* Red)
+{
+  BOOLEAN ret;
+  number coef;
+
+  assume(PR->GetLmCurrRing() != PW->GetLmCurrRing());
+  Red->HeadNormalize();
+  /*
+  printf("------------------------\n");
+  pWrite(Red->GetLmCurrRing());
+  */
+  ret = ksReducePolySig(Red, PW, 1, NULL, &coef);
+
+
+  if (!ret)
+  {
+    if (! n_IsOne(coef, currRing->cf))
+    {
+      PR->Mult_nn(coef);
+      // HANNES: mark for Normalize
+    }
+    n_Delete(&coef, currRing->cf);
+  }
+  return ret;
+}
+
+/*2
+*  reduction procedure for signature-based standard
+*  basis algorithms:
+*  all reductions have to be sig-safe!
+*
+*  2 is returned if and only if the pair is rejected by the rewritten criterion
+*  at exactly this point of the computations. This is the last possible point
+*  such a check can be done => checks with the biggest set of available
+*  signatures
+*/
+int redSig (LObject* h,kStrategy strat)
+{
+  if (strat->tl<0) return 1;
+  //if (h->GetLmTailRing()==NULL) return 0; // HS: SHOULD NOT BE NEEDED!
+  //printf("FDEGS: %ld -- %ld\n",h->FDeg, h->pFDeg());
+  assume(h->FDeg == h->pFDeg());
+//#if 1
+#ifdef DEBUGF5
+  Print("------- IN REDSIG -------\n");
+  Print("p: ");
+  pWrite(pHead(h->p));
+  Print("p1: ");
+  pWrite(pHead(h->p1));
+  Print("p2: ");
+  pWrite(pHead(h->p2));
+  Print("---------------------------\n");
+#endif
+  poly h_p;
+  int i,j,at,pass, ii;
+  int start=0;
+  int sigSafe;
+  unsigned long not_sev;
+  // long reddeg,d;
+
+  pass = j = 0;
+  // d = reddeg = h->GetpFDeg();
+  h->SetShortExpVector();
+  int li;
+  h_p = h->GetLmTailRing();
+  not_sev = ~ h->sev;
+  loop
+  {
+    j = kFindDivisibleByInT(strat->T, strat->sevT, strat->tl, h, start);
+    if (j < 0)
+    {
+      return 1;
+    }
+
+    li = strat->T[j].pLength;
+    ii = j;
+    /*
+     * the polynomial to reduce with (up to the moment) is;
+     * pi with length li
+     */
+    i = j;
+#if 1
+    if (TEST_OPT_LENGTH)
+    loop
+    {
+      /*- search the shortest possible with respect to length -*/
+      i++;
+      if (i > strat->tl)
+        break;
+      if (li<=1)
+        break;
+      if ((strat->T[i].pLength < li)
+         &&
+          p_LmShortDivisibleBy(strat->T[i].GetLmTailRing(), strat->sevT[i],
+                               h_p, not_sev, strat->tailRing))
+      {
+        /*
+         * the polynomial to reduce with is now;
+         */
+        li = strat->T[i].pLength;
+        ii = i;
+      }
+    }
+    start = ii+1;
+#endif
+
+    /*
+     * end of search: have to reduce with pi
+     */
+#ifdef KDEBUG
+    if (TEST_OPT_DEBUG)
+    {
+      PrintS("red:");
+      h->wrp();
+      PrintS(" with ");
+      strat->T[ii].wrp();
+    }
+#endif
+    assume(strat->fromT == FALSE);
+//#if 1
+#ifdef DEBUGF5
+    Print("BEFORE REDUCTION WITH %d:\n",ii);
+    Print("--------------------------------\n");
+    pWrite(h->sig);
+    pWrite(strat->T[ii].sig);
+    pWrite(h->GetLmCurrRing());
+    pWrite(pHead(h->p1));
+    pWrite(pHead(h->p2));
+    pWrite(pHead(strat->T[ii].p));
+    Print("--------------------------------\n");
+    printf("INDEX OF REDUCER T: %d\n",ii);
+#endif
+    sigSafe = ksReducePolySig(h, &(strat->T[ii]), strat->S_2_R[ii], NULL, NULL, strat);
+#if SBA_PRINT_REDUCTION_STEPS
+    if (sigSafe != 3)
+      sba_reduction_steps++;
+#endif
+#if SBA_PRINT_OPERATIONS
+    if (sigSafe != 3)
+      sba_operations  +=  pLength(strat->T[ii].p);
+#endif
+    // if reduction has taken place, i.e. the reduction was sig-safe
+    // otherwise start is already at the next position and the loop
+    // searching reducers in T goes on from index start
+//#if 1
+#ifdef DEBUGF5
+    Print("SigSAFE: %d\n",sigSafe);
+#endif
+    if (sigSafe != 3)
+    {
+      // start the next search for reducers in T from the beginning
+      start = 0;
+#ifdef KDEBUG
+      if (TEST_OPT_DEBUG)
+      {
+        PrintS("\nto ");
+        h->wrp();
+        PrintLn();
+      }
+#endif
+
+      h_p = h->GetLmTailRing();
+      if (h_p == NULL)
+      {
+        if (h->lcm!=NULL) pLmFree(h->lcm);
+#ifdef KDEBUG
+        h->lcm=NULL;
+#endif
+        return 0;
+      }
+      h->SetShortExpVector();
+      not_sev = ~ h->sev;
+      /*
+      * try to reduce the s-polynomial h
+      *test first whether h should go to the lazyset L
+      *-if the degree jumps
+      *-if the number of pre-defined reductions jumps
+      */
+      pass++;
+      if (!TEST_OPT_REDTHROUGH && (strat->Ll >= 0) && (pass > strat->LazyPass))
+      {
+        h->SetLmCurrRing();
+        at = strat->posInL(strat->L,strat->Ll,h,strat);
+        if (at <= strat->Ll)
+        {
+          int dummy=strat->sl;
+          if (kFindDivisibleByInS(strat, &dummy, h) < 0)
+          {
+            return 1;
+          }
+          enterL(&strat->L,&strat->Ll,&strat->Lmax,*h,at);
+#ifdef KDEBUG
+          if (TEST_OPT_DEBUG)
+            Print(" lazy: -> L%d\n",at);
+#endif
+          h->Clear();
+          return -1;
+        }
+      }
+    }
+  }
+}
+
+// tail reduction for SBA
+poly redtailSba (LObject* L, int pos, kStrategy strat, BOOLEAN withT, BOOLEAN normalize)
+{
+#define REDTAIL_CANONICALIZE 100
+  strat->redTailChange=FALSE;
+  if (strat->noTailReduction) return L->GetLmCurrRing();
+  poly h, p;
+  p = h = L->GetLmTailRing();
+  if ((h==NULL) || (pNext(h)==NULL))
+    return L->GetLmCurrRing();
+
+  TObject* With;
+  // placeholder in case strat->tl < 0
+  TObject  With_s(strat->tailRing);
+
+  LObject Ln(pNext(h), strat->tailRing);
+  Ln.sig      = L->sig;
+  Ln.sevSig   = L->sevSig;
+  Ln.pLength  = L->GetpLength() - 1;
+
+  pNext(h) = NULL;
+  if (L->p != NULL) pNext(L->p) = NULL;
+  L->pLength = 1;
+
+  Ln.PrepareRed(strat->use_buckets);
+
+  int cnt=REDTAIL_CANONICALIZE;
+  while(!Ln.IsNull())
+  {
+    loop
+    {
+      Ln.SetShortExpVector();
+      if (withT)
+      {
+        int j;
+        j = kFindDivisibleByInT(strat->T, strat->sevT, strat->tl, &Ln);
+        if (j < 0) break;
+        With = &(strat->T[j]);
+      }
+      else
+      {
+        With = kFindDivisibleByInS(strat, pos, &Ln, &With_s);
+        if (With == NULL) break;
+      }
+      cnt--;
+      if (cnt==0)
+      {
+        cnt=REDTAIL_CANONICALIZE;
+        /*poly tmp=*/Ln.CanonicalizeP();
+        if (normalize)
+        {
+          Ln.Normalize();
+          //pNormalize(tmp);
+          //if (TEST_OPT_PROT) { PrintS("n"); mflush(); }
+        }
+      }
+      if (normalize && (!TEST_OPT_INTSTRATEGY) && (!nIsOne(pGetCoeff(With->p))))
+      {
+        With->pNorm();
+      }
+      strat->redTailChange=TRUE;
+      int ret = ksReducePolyTailSig(L, With, &Ln);
+#if SBA_PRINT_REDUCTION_STEPS
+      if (ret != 3)
+        sba_reduction_steps++;
+#endif
+#if SBA_PRINT_OPERATIONS
+      if (ret != 3)
+        sba_operations  +=  pLength(With->p);
+#endif
+      if (ret)
+      {
+        // reducing the tail would violate the exp bound
+        //  set a flag and hope for a retry (in bba)
+        strat->completeReduce_retry=TRUE;
+        if ((Ln.p != NULL) && (Ln.t_p != NULL)) Ln.p=NULL;
+        do
+        {
+          pNext(h) = Ln.LmExtractAndIter();
+          pIter(h);
+          L->pLength++;
+        } while (!Ln.IsNull());
+        goto all_done;
+      }
+      if (Ln.IsNull()) goto all_done;
+      if (! withT) With_s.Init(currRing);
+    }
+    pNext(h) = Ln.LmExtractAndIter();
+    pIter(h);
+    pNormalize(h);
+    L->pLength++;
+  }
+
+  all_done:
+  Ln.Delete();
+  if (L->p != NULL) pNext(L->p) = pNext(p);
+
+  if (strat->redTailChange)
+  {
+    L->length = 0;
+  }
+
+  //if (TEST_OPT_PROT) { PrintS("N"); mflush(); }
+  //L->Normalize(); // HANNES: should have a test
+  kTest_L(L);
+  return L->GetLmCurrRing();
+}
+
+/*2
+*  reduction procedure for the inhomogeneous case
+*  and not a degree-ordering
+*/
+int redLazy (LObject* h,kStrategy strat)
+{
+  if (strat->tl<0) return 1;
+  int at,i,ii,li;
+  int j = 0;
+  int pass = 0;
+  assume(h->pFDeg() == h->FDeg);
+  long reddeg = h->GetpFDeg();
+  long d;
+  unsigned long not_sev;
+
+  h->SetShortExpVector();
+  poly h_p = h->GetLmTailRing();
+  not_sev = ~ h->sev;
+  loop
+  {
+    j = kFindDivisibleByInT(strat->T, strat->sevT, strat->tl, h);
+    if (j < 0) return 1;
+
+    li = strat->T[j].pLength;
+    #if 0
+    if (li==0)
+    {
+      li=strat->T[j].pLength=pLength(strat->T[j].p);
+    }
+    #endif
+    ii = j;
+    /*
+     * the polynomial to reduce with (up to the moment) is;
+     * pi with length li
+     */
+
+    i = j;
+#if 1
+    if (TEST_OPT_LENGTH)
+    loop
+    {
+      /*- search the shortest possible with respect to length -*/
+      i++;
+      if (i > strat->tl)
+        break;
+      if (li<=1)
+        break;
+    #if 0
+      if (strat->T[i].pLength==0)
+      {
+        PrintS("!");
+        strat->T[i].pLength=pLength(strat->T[i].p);
+      }
+   #endif
+      if ((strat->T[i].pLength < li)
+         &&
+          p_LmShortDivisibleBy(strat->T[i].GetLmTailRing(), strat->sevT[i],
+                               h_p, not_sev, strat->tailRing))
+      {
+        /*
+         * the polynomial to reduce with is now;
+         */
+        PrintS("+");
+        li = strat->T[i].pLength;
+        ii = i;
+      }
+    }
+#endif
+
+    /*
+     * end of search: have to reduce with pi
+     */
+
+
+#ifdef KDEBUG
+    if (TEST_OPT_DEBUG)
+    {
+      PrintS("red:");
+      h->wrp();
+      PrintS(" with ");
+      strat->T[ii].wrp();
+    }
+#endif
+
+    ksReducePoly(h, &(strat->T[ii]), NULL, NULL, strat);
+#if SBA_PRINT_REDUCTION_STEPS
+    sba_interreduction_steps++;
+#endif
+#if SBA_PRINT_OPERATIONS
+    sba_interreduction_operations  +=  pLength(strat->T[ii].p);
+#endif
+
+#ifdef KDEBUG
+    if (TEST_OPT_DEBUG)
+    {
+      PrintS("\nto ");
+      h->wrp();
+      PrintLn();
+    }
+#endif
+
+    h_p=h->GetLmTailRing();
+
+    if (h_p == NULL)
+    {
+      if (h->lcm!=NULL) pLmFree(h->lcm);
+#ifdef KDEBUG
+      h->lcm=NULL;
+#endif
+      return 0;
+    }
+    h->SetShortExpVector();
+    not_sev = ~ h->sev;
+    d = h->SetpFDeg();
+    /*- try to reduce the s-polynomial -*/
+    pass++;
+    if (//!TEST_OPT_REDTHROUGH &&
+        (strat->Ll >= 0) && ((d > reddeg) || (pass > strat->LazyPass)))
+    {
+      h->SetLmCurrRing();
+      at = strat->posInL(strat->L,strat->Ll,h,strat);
+      if (at <= strat->Ll)
+      {
+#if 1
+        int dummy=strat->sl;
+        if (kFindDivisibleByInS(strat, &dummy, h) < 0)
+          return 1;
+#endif
+#ifdef KDEBUG
+        if (TEST_OPT_DEBUG) Print(" ->L[%d]\n",at);
+#endif
+        enterL(&strat->L,&strat->Ll,&strat->Lmax,*h,at);
+        h->Clear();
+        return -1;
+      }
+    }
+    else if (d != reddeg)
+    {
+      if (d>=strat->tailRing->bitmask)
+      {
+        if (h->pTotalDeg() >= strat->tailRing->bitmask)
+        {
+          strat->overflow=TRUE;
+          //Print("OVERFLOW in redLazy d=%ld, max=%ld\n",d,strat->tailRing->bitmask);
+          h->GetP();
+          at = strat->posInL(strat->L,strat->Ll,h,strat);
+          enterL(&strat->L,&strat->Ll,&strat->Lmax,*h,at);
+          h->Clear();
+          return -1;
+        }
+      }
+      else if ((TEST_OPT_PROT) && (strat->Ll < 0))
+      {
+        Print(".%ld",d);mflush();
+        reddeg = d;
+      }
+    }
+  }
+}
+/*2
+*  reduction procedure for the sugar-strategy (honey)
+* reduces h with elements from T choosing first possible
+* element in T with respect to the given ecart
+*/
+int redHoney (LObject* h, kStrategy strat)
+{
+  if (strat->tl<0) return 1;
+  //if (h->GetLmTailRing()==NULL) return 0; // HS: SHOULD NOT BE NEEDED!
+  assume(h->FDeg == h->pFDeg());
+  poly h_p;
+  int i,j,at,pass,ei, ii, h_d;
+  unsigned long not_sev;
+  long reddeg,d;
+
+  pass = j = 0;
+  d = reddeg = h->GetpFDeg() + h->ecart;
+  h->SetShortExpVector();
+  int li;
+  h_p = h->GetLmTailRing();
+  not_sev = ~ h->sev;
+
+  h->PrepareRed(strat->use_buckets);
+  loop
+  {
+    j=kFindDivisibleByInT(strat->T, strat->sevT, strat->tl, h);
+    if (j < 0) return 1;
+
+    ei = strat->T[j].ecart;
+    li = strat->T[j].pLength;
+    ii = j;
+    /*
+     * the polynomial to reduce with (up to the moment) is;
+     * pi with ecart ei
+     */
+    i = j;
+    if (TEST_OPT_LENGTH)
+    loop
+    {
+      /*- takes the first possible with respect to ecart -*/
+      i++;
+      if (i > strat->tl)
+        break;
+      //if (ei < h->ecart)
+      //  break;
+      if (li<=1)
+        break;
+      if ((((strat->T[i].ecart < ei) && (ei> h->ecart))
+         || ((strat->T[i].ecart <= h->ecart) && (strat->T[i].pLength < li)))
+         &&
+          p_LmShortDivisibleBy(strat->T[i].GetLmTailRing(), strat->sevT[i],
+                               h_p, not_sev, strat->tailRing))
+      {
+        /*
+         * the polynomial to reduce with is now;
+         */
+        ei = strat->T[i].ecart;
+        li = strat->T[i].pLength;
+        ii = i;
+      }
+    }
+
+    /*
+     * end of search: have to reduce with pi
+     */
+    if (!TEST_OPT_REDTHROUGH && (pass!=0) && (ei > h->ecart))
+    {
+      h->GetTP(); // clears bucket
+      h->SetLmCurrRing();
+      /*
+       * It is not possible to reduce h with smaller ecart;
+       * if possible h goes to the lazy-set L,i.e
+       * if its position in L would be not the last one
+       */
+      if (strat->Ll >= 0) /* L is not empty */
+      {
+        at = strat->posInL(strat->L,strat->Ll,h,strat);
+        if(at <= strat->Ll)
+          /*- h will not become the next element to reduce -*/
+        {
+          enterL(&strat->L,&strat->Ll,&strat->Lmax,*h,at);
+#ifdef KDEBUG
+          if (TEST_OPT_DEBUG) Print(" ecart too big: -> L%d\n",at);
+#endif
+          h->Clear();
+          return -1;
+        }
+      }
+    }
+#ifdef KDEBUG
+    if (TEST_OPT_DEBUG)
+    {
+      PrintS("red:");
+      h->wrp();
+      PrintS(" with ");
+      strat->T[ii].wrp();
+    }
+#endif
+    assume(strat->fromT == FALSE);
+
+    number coef;
+    ksReducePoly(h,&(strat->T[ii]),strat->kNoetherTail(),&coef,strat);
+#if SBA_PRINT_REDUCTION_STEPS
+    sba_interreduction_steps++;
+#endif
+#if SBA_PRINT_OPERATIONS
+    sba_interreduction_operations  +=  pLength(strat->T[ii].p);
+#endif
+#ifdef KDEBUG
+    if (TEST_OPT_DEBUG)
+    {
+      PrintS("\nto:");
+      h->wrp();
+      PrintLn();
+    }
+#endif
+    if(h->IsNull())
+    {
+      h->Clear();
+      if (h->lcm!=NULL) pLmFree(h->lcm);
+      #ifdef KDEBUG
+      h->lcm=NULL;
+      #endif
+      return 0;
+    }
+    h->SetShortExpVector();
+    not_sev = ~ h->sev;
+    h_d = h->SetpFDeg();
+    /* compute the ecart */
+    if (ei <= h->ecart)
+      h->ecart = d-h_d;
+    else
+      h->ecart = d-h_d+ei-h->ecart;
+
+    /*
+     * try to reduce the s-polynomial h
+     *test first whether h should go to the lazyset L
+     *-if the degree jumps
+     *-if the number of pre-defined reductions jumps
+     */
+    pass++;
+    d = h_d + h->ecart;
+    if (!TEST_OPT_REDTHROUGH && (strat->Ll >= 0) && ((d > reddeg) || (pass > strat->LazyPass)))
+    {
+      h->GetTP(); // clear bucket
+      h->SetLmCurrRing();
+      at = strat->posInL(strat->L,strat->Ll,h,strat);
+      if (at <= strat->Ll)
+      {
+        int dummy=strat->sl;
+        if (kFindDivisibleByInS(strat, &dummy, h) < 0)
+          return 1;
+        enterL(&strat->L,&strat->Ll,&strat->Lmax,*h,at);
+#ifdef KDEBUG
+        if (TEST_OPT_DEBUG)
+          Print(" degree jumped: -> L%d\n",at);
+#endif
+        h->Clear();
+        return -1;
+      }
+    }
+    else if (d > reddeg)
+    {
+      if (d>=strat->tailRing->bitmask)
+      {
+        if (h->pTotalDeg()+h->ecart >= strat->tailRing->bitmask)
+        {
+          strat->overflow=TRUE;
+          //Print("OVERFLOW in redHoney d=%ld, max=%ld\n",d,strat->tailRing->bitmask);
+          h->GetP();
+          at = strat->posInL(strat->L,strat->Ll,h,strat);
+          enterL(&strat->L,&strat->Ll,&strat->Lmax,*h,at);
+          h->Clear();
+          return -1;
+        }
+      }
+      else if (TEST_OPT_PROT && (strat->Ll < 0) )
+      {
+        //h->wrp(); Print("<%d>\n",h->GetpLength());
+        reddeg = d;
+        Print(".%ld",d); mflush();
+      }
+    }
+  }
+}
+
+/*2
+*  reduction procedure for the normal form
+*/
+
+poly redNF (poly h,int &max_ind,int nonorm,kStrategy strat)
+{
+  if (h==NULL) return NULL;
+  int j;
+  max_ind=strat->sl;
+
+  if (0 > strat->sl)
+  {
+    return h;
+  }
+  LObject P(h);
+  P.SetShortExpVector();
+  P.bucket = kBucketCreate(currRing);
+  kBucketInit(P.bucket,P.p,pLength(P.p));
+  kbTest(P.bucket);
+#ifdef HAVE_RINGS
+  BOOLEAN is_ring = rField_is_Ring(currRing);
+#endif
+#ifdef KDEBUG
+  if (TEST_OPT_DEBUG)
+  {
+    PrintS("redNF: starting S: ");
+    for( j = 0; j <= max_ind; j++ )
+    {
+      Print("S[%d] (of size: %d): ", j, pSize(strat->S[j]));
+      pWrite(strat->S[j]);
+    }
+  };
+#endif
+
+  loop
+  {
+    j=kFindDivisibleByInS(strat,&max_ind,&P);
+    if (j>=0)
+    {
+#ifdef HAVE_RINGS
+      if (!is_ring)
+      {
+#endif
+        int sl=pSize(strat->S[j]);
+        int jj=j;
+        loop
+        {
+          int sll;
+          jj=kFindNextDivisibleByInS(strat,jj+1,max_ind,&P);
+          if (jj<0) break;
+          sll=pSize(strat->S[jj]);
+          if (sll<sl)
+          {
+            #ifdef KDEBUG
+            if (TEST_OPT_DEBUG) Print("better(S%d:%d -> S%d:%d)\n",j,sl,jj,sll);
+            #endif
+            //else if (TEST_OPT_PROT) { PrintS("b"); mflush(); }
+            j=jj;
+            sl=sll;
+          }
+        }
+        if ((nonorm==0) && (!nIsOne(pGetCoeff(strat->S[j]))))
+        {
+          pNorm(strat->S[j]);
+          //if (TEST_OPT_PROT) { PrintS("n"); mflush(); }
+        }
+#ifdef HAVE_RINGS
+      }
+#endif
+      nNormalize(pGetCoeff(P.p));
+#ifdef KDEBUG
+      if (TEST_OPT_DEBUG)
+      {
+        PrintS("red:");
+        wrp(h);
+        PrintS(" with ");
+        wrp(strat->S[j]);
+      }
+#endif
+#ifdef HAVE_PLURAL
+      if (rIsPluralRing(currRing))
+      {
+        number coef;
+        nc_kBucketPolyRed(P.bucket,strat->S[j],&coef);
+        nDelete(&coef);
+      }
+      else
+#endif
+      {
+        number coef;
+        coef=kBucketPolyRed(P.bucket,strat->S[j],pLength(strat->S[j]),strat->kNoether);
+        nDelete(&coef);
+      }
+      h = kBucketGetLm(P.bucket);   // FRAGE OLIVER
+      if (h==NULL)
+      {
+        kBucketDestroy(&P.bucket);
+
+#ifdef KDEBUG
+        if (TEST_OPT_DEBUG)
+        {
+          PrintS("redNF: starting S: ");
+          for( j = 0; j <= max_ind; j++ )
+          {
+            Print("S[%d] (of size: %d): ", j, pSize(strat->S[j]));
+            pWrite(strat->S[j]);
+          }
+        };
+#endif
+
+        return NULL;
+      }
+      kbTest(P.bucket);
+      P.p=h;
+      P.t_p=NULL;
+      P.SetShortExpVector();
+#ifdef KDEBUG
+      if (TEST_OPT_DEBUG)
+      {
+        PrintS("\nto:");
+        wrp(h);
+        PrintLn();
+      }
+#endif
+    }
+    else
+    {
+      P.p=kBucketClear(P.bucket);
+      kBucketDestroy(&P.bucket);
+      pNormalize(P.p);
+
+#ifdef KDEBUG
+      if (TEST_OPT_DEBUG)
+      {
+        PrintS("redNF: starting S: ");
+        for( j = 0; j <= max_ind; j++ )
+        {
+          Print("S[%d] (of size: %d): ", j, pSize(strat->S[j]));
+          pWrite(strat->S[j]);
+        }
+      };
+#endif
+
+      return P.p;
+    }
+  }
+}
+
+#ifdef KDEBUG
+static int bba_count = 0;
+#endif /* KDEBUG */
+void kDebugPrint(kStrategy strat);
+
+ideal bba (ideal F, ideal Q,intvec *w,intvec *hilb,kStrategy strat)
+{
+#ifdef KDEBUG
+  bba_count++;
+  int loop_count = 0;
+#endif /* KDEBUG */
+  int   red_result = 1;
+  int   olddeg,reduc;
+  int hilbeledeg=1,hilbcount=0,minimcnt=0;
+  BOOLEAN withT = FALSE;
+  BITSET save;
+  SI_SAVE_OPT1(save);
+
+  initBuchMoraCrit(strat); /*set Gebauer, honey, sugarCrit*/
+  initBuchMoraPos(strat);
+  initHilbCrit(F,Q,&hilb,strat);
+  initBba(F,strat);
+  /*set enterS, spSpolyShort, reduce, red, initEcart, initEcartPair*/
+  /*Shdl=*/initBuchMora(F, Q,strat);
+  if (strat->minim>0) strat->M=idInit(IDELEMS(F),F->rank);
+  reduc = olddeg = 0;
+
+#ifndef NO_BUCKETS
+  if (!TEST_OPT_NOT_BUCKETS)
+    strat->use_buckets = 1;
+#endif
+  // redtailBBa against T for inhomogenous input
+  if (!TEST_OPT_OLDSTD)
+    withT = ! strat->homog;
+
+  // strat->posInT = posInT_pLength;
+  kTest_TS(strat);
+
+#ifdef KDEBUG
+#if MYTEST
+  if (TEST_OPT_DEBUG)
+  {
+    PrintS("bba start GB: currRing: ");
+    // rWrite(currRing);PrintLn();
+    rDebugPrint(currRing);
+    PrintLn();
+  }
+#endif /* MYTEST */
+#endif /* KDEBUG */
+
+#ifdef HAVE_TAIL_RING
+  if(!idIs0(F) &&(!rField_is_Ring(currRing)))  // create strong gcd poly computes with tailring and S[i] ->to be fixed
+    kStratInitChangeTailRing(strat);
+#endif
+  if (BVERBOSE(23))
+  {
+    if (test_PosInT!=NULL) strat->posInT=test_PosInT;
+    if (test_PosInL!=NULL) strat->posInL=test_PosInL;
+    kDebugPrint(strat);
+  }
+
+
+#ifdef KDEBUG
+  //kDebugPrint(strat);
+#endif
+  /* compute------------------------------------------------------- */
+  while (strat->Ll >= 0)
+  {
+    #ifdef KDEBUG
+      loop_count++;
+      if (TEST_OPT_DEBUG) messageSets(strat);
+    #endif
+    if (strat->Ll== 0) strat->interpt=TRUE;
+    if (TEST_OPT_DEGBOUND
+        && ((strat->honey && (strat->L[strat->Ll].ecart+currRing->pFDeg(strat->L[strat->Ll].p,currRing)>Kstd1_deg))
+            || ((!strat->honey) && (currRing->pFDeg(strat->L[strat->Ll].p,currRing)>Kstd1_deg))))
+    {
+      /*
+       *stops computation if
+       * 24 IN test and the degree +ecart of L[strat->Ll] is bigger then
+       *a predefined number Kstd1_deg
+       */
+      while ((strat->Ll >= 0)
+        && (strat->L[strat->Ll].p1!=NULL) && (strat->L[strat->Ll].p2!=NULL)
+        && ((strat->honey && (strat->L[strat->Ll].ecart+currRing->pFDeg(strat->L[strat->Ll].p,currRing)>Kstd1_deg))
+            || ((!strat->honey) && (currRing->pFDeg(strat->L[strat->Ll].p,currRing)>Kstd1_deg)))
+        )
+        deleteInL(strat->L,&strat->Ll,strat->Ll,strat);
+      if (strat->Ll<0) break;
+      else strat->noClearS=TRUE;
+    }
+    /* picks the last element from the lazyset L */
+    strat->P = strat->L[strat->Ll];
+    strat->Ll--;
+
+    if (pNext(strat->P.p) == strat->tail)
+    {
+      // deletes the short spoly
+#ifdef HAVE_RINGS
+      if (rField_is_Ring(currRing))
+        pLmDelete(strat->P.p);
+      else
+#endif
+        pLmFree(strat->P.p);
+      strat->P.p = NULL;
+      poly m1 = NULL, m2 = NULL;
+
+      // check that spoly creation is ok
+      while (strat->tailRing != currRing &&
+             !kCheckSpolyCreation(&(strat->P), strat, m1, m2))
+      {
+        assume(m1 == NULL && m2 == NULL);
+        // if not, change to a ring where exponents are at least
+        // large enough
+        if (!kStratChangeTailRing(strat))
+        {
+          WerrorS("OVERFLOW...");
+          break;
+        }
+      }
+      // create the real one
+      ksCreateSpoly(&(strat->P), NULL, strat->use_buckets,
+                    strat->tailRing, m1, m2, strat->R);
+    }
+    else if (strat->P.p1 == NULL)
+    {
+      if (strat->minim > 0)
+        strat->P.p2=p_Copy(strat->P.p, currRing, strat->tailRing);
+      // for input polys, prepare reduction
+      strat->P.PrepareRed(strat->use_buckets);
+    }
+
+    if (strat->P.p == NULL && strat->P.t_p == NULL)
+    {
+      red_result = 0;
+    }
+    else
+    {
+      if (TEST_OPT_PROT)
+        message((strat->honey ? strat->P.ecart : 0) + strat->P.pFDeg(),
+                &olddeg,&reduc,strat, red_result);
+
+      /* reduction of the element choosen from L */
+      red_result = strat->red(&strat->P,strat);
+      if (errorreported)  break;
+    }
+
+    if (strat->overflow)
+    {
+        if (!kStratChangeTailRing(strat)) { Werror("OVERFLOW.."); break;}
+    }
+
+    // reduction to non-zero new poly
+    if (red_result == 1)
+    {
+      // get the polynomial (canonicalize bucket, make sure P.p is set)
+      strat->P.GetP(strat->lmBin);
+      // in the homogeneous case FDeg >= pFDeg (sugar/honey)
+      // but now, for entering S, T, we reset it
+      // in the inhomogeneous case: FDeg == pFDeg
+      if (strat->homog) strat->initEcart(&(strat->P));
+
+      /* statistic */
+      if (TEST_OPT_PROT) PrintS("s");
+
+      int pos=posInS(strat,strat->sl,strat->P.p,strat->P.ecart);
+
+#ifdef KDEBUG
+#if MYTEST
+      PrintS("New S: "); p_DebugPrint(strat->P.p, currRing); PrintLn();
+#endif /* MYTEST */
+#endif /* KDEBUG */
+
+      // reduce the tail and normalize poly
+      // in the ring case we cannot expect LC(f) = 1,
+      // therefore we call pContent instead of pNorm
+      if ((TEST_OPT_INTSTRATEGY) || (rField_is_Ring(currRing)))
+      {
+        strat->P.pCleardenom();
+        if ((TEST_OPT_REDSB)||(TEST_OPT_REDTAIL))
+        {
+          strat->P.p = redtailBba(&(strat->P),pos-1,strat, withT);
+          strat->P.pCleardenom();
+        }
+      }
+      else
+      {
+        strat->P.pNorm();
+        if ((TEST_OPT_REDSB)||(TEST_OPT_REDTAIL))
+          strat->P.p = redtailBba(&(strat->P),pos-1,strat, withT);
+      }
+
+#ifdef KDEBUG
+      if (TEST_OPT_DEBUG){PrintS("new s:");strat->P.wrp();PrintLn();}
+#if MYTEST
+      PrintS("New (reduced) S: "); p_DebugPrint(strat->P.p, currRing); PrintLn();
+#endif /* MYTEST */
+#endif /* KDEBUG */
+
+      // min_std stuff
+      if ((strat->P.p1==NULL) && (strat->minim>0))
+      {
+        if (strat->minim==1)
+        {
+          strat->M->m[minimcnt]=p_Copy(strat->P.p,currRing,strat->tailRing);
+          p_Delete(&strat->P.p2, currRing, strat->tailRing);
+        }
+        else
+        {
+          strat->M->m[minimcnt]=strat->P.p2;
+          strat->P.p2=NULL;
+        }
+        if (strat->tailRing!=currRing && pNext(strat->M->m[minimcnt])!=NULL)
+          pNext(strat->M->m[minimcnt])
+            = strat->p_shallow_copy_delete(pNext(strat->M->m[minimcnt]),
+                                           strat->tailRing, currRing,
+                                           currRing->PolyBin);
+        minimcnt++;
+      }
+
+      // enter into S, L, and T
+      if ((!TEST_OPT_IDLIFT) || (pGetComp(strat->P.p) <= strat->syzComp))
+      {
+        enterT(strat->P, strat);
+#ifdef HAVE_RINGS
+        if (rField_is_Ring(currRing))
+          superenterpairs(strat->P.p,strat->sl,strat->P.ecart,pos,strat, strat->tl);
+        else
+#endif
+          enterpairs(strat->P.p,strat->sl,strat->P.ecart,pos,strat, strat->tl);
+        // posInS only depends on the leading term
+        strat->enterS(strat->P, pos, strat, strat->tl);
+#if 0
+        int pl=pLength(strat->P.p);
+        if (pl==1)
+        {
+          //if (TEST_OPT_PROT)
+          //PrintS("<1>");
+        }
+        else if (pl==2)
+        {
+          //if (TEST_OPT_PROT)
+          //PrintS("<2>");
+        }
+#endif
+      }
+      if (hilb!=NULL) khCheck(Q,w,hilb,hilbeledeg,hilbcount,strat);
+//      Print("[%d]",hilbeledeg);
+      if (strat->P.lcm!=NULL)
+#ifdef HAVE_RINGS
+        pLmDelete(strat->P.lcm);
+#else
+        pLmFree(strat->P.lcm);
+#endif
+    }
+    else if (strat->P.p1 == NULL && strat->minim > 0)
+    {
+      p_Delete(&strat->P.p2, currRing, strat->tailRing);
+    }
+
+#ifdef KDEBUG
+    memset(&(strat->P), 0, sizeof(strat->P));
+#endif /* KDEBUG */
+    kTest_TS(strat);
+  }
+#ifdef KDEBUG
+#if MYTEST
+  PrintS("bba finish GB: currRing: "); rWrite(currRing);
+#endif /* MYTEST */
+  if (TEST_OPT_DEBUG) messageSets(strat);
+#endif /* KDEBUG */
+
+  if (TEST_OPT_SB_1)
+  {
+    #ifdef HAVE_RINGS
+    if(!rField_is_Ring(currRing))
+    #endif
+    {
+        int k=1;
+        int j;
+        while(k<=strat->sl)
+        {
+          j=0;
+          loop
+          {
+            if (j>=k) break;
+            clearS(strat->S[j],strat->sevS[j],&k,&j,strat);
+            j++;
+          }
+          k++;
+        }
+    }
+  }
+
+  /* complete reduction of the standard basis--------- */
+  if (TEST_OPT_REDSB)
+  {
+    completeReduce(strat);
+#ifdef HAVE_TAIL_RING
+    if (strat->completeReduce_retry)
+    {
+      // completeReduce needed larger exponents, retry
+      // to reduce with S (instead of T)
+      // and in currRing (instead of strat->tailRing)
+      cleanT(strat);strat->tailRing=currRing;
+      int i;
+      for(i=strat->sl;i>=0;i--) strat->S_2_R[i]=-1;
+      completeReduce(strat);
+    }
+#endif
+  }
+  else if (TEST_OPT_PROT) PrintLn();
+
+  /* release temp data-------------------------------- */
+  exitBuchMora(strat);
+//  if (TEST_OPT_WEIGHTM)
+//  {
+//    pRestoreDegProcs(currRing,pFDegOld, pLDegOld);
+//    if (ecartWeights)
+//    {
+//      omFreeSize((ADDRESS)ecartWeights,((currRing->N)+1)*sizeof(short));
+//      ecartWeights=NULL;
+//    }
+//  }
+  if (TEST_OPT_PROT) messageStat(hilbcount,strat);
+  SI_RESTORE_OPT1(save);
+  if (Q!=NULL) updateResult(strat->Shdl,Q,strat);
+
+#ifdef KDEBUG
+#if MYTEST
+  PrintS("bba_end: currRing: "); rWrite(currRing);
+#endif /* MYTEST */
+#endif /* KDEBUG */
+  idTest(strat->Shdl);
+
+  return (strat->Shdl);
+}
+ideal sba (ideal F0, ideal Q,intvec *w,intvec *hilb,kStrategy strat)
+{
+  // ring order stuff:
+  // in sba we have (until now) two possibilities:
+  // 1. an incremental computation w.r.t. (C,monomial order)
+  // 2. a (possibly non-incremental) computation w.r.t. the
+  //    induced Schreyer order.
+  // The corresponding orders are computed in sbaRing(), depending
+  // on the flag strat->sbaOrder
+#if SBA_PRINT_ZERO_REDUCTIONS
+  long zeroreductions           = 0;
+#endif
+#if SBA_PRINT_PRODUCT_CRITERION
+  long product_criterion        = 0;
+#endif
+#if SBA_PRINT_SIZE_G
+  int size_g                    = 0;
+  int size_g_non_red            = 0;
+#endif
+#if SBA_PRINT_SIZE_SYZ
+  long size_syz                 = 0;
+#endif
+  // global variable
+#if SBA_PRINT_REDUCTION_STEPS
+  sba_reduction_steps           = 0;
+  sba_interreduction_steps      = 0;
+#endif
+#if SBA_PRINT_OPERATIONS
+  sba_operations                = 0;
+  sba_interreduction_operations = 0;
+#endif
+
+  ideal F1 = F0;
+  ring sRing, currRingOld;
+  currRingOld  = currRing;
+  if (strat->sbaOrder == 1 || strat->sbaOrder == 3)
+  {
+    sRing = sbaRing(strat);
+    if (sRing!=currRingOld)
+    {
+      rChangeCurrRing (sRing);
+      F1 = idrMoveR (F0, currRingOld, currRing);
+    }
+  }
+  // sort ideal F
+  ideal F       = idInit(IDELEMS(F1),F1->rank);
+  intvec *sort  = idSort(F1);
+  for (int i=0; i<sort->length();++i)
+    F->m[i] = F1->m[(*sort)[i]-1];
+#if SBA_INTERRED_START
+  F = kInterRed(F,NULL);
+#endif
+#if F5DEBUG
+  printf("SBA COMPUTATIONS DONE IN THE FOLLOWING RING:\n");
+  rWrite (currRing);
+  printf("ordSgn = %d\n",currRing->OrdSgn);
+  printf("\n");
+#endif
+#ifdef KDEBUG
+  bba_count++;
+  int loop_count = 0;
+#endif /* KDEBUG */
+  int   srmax,lrmax, red_result = 1;
+  int   olddeg,reduc;
+  int hilbeledeg=1,hilbcount=0,minimcnt=0;
+  LObject L;
+  BOOLEAN withT     = TRUE;
+  strat->max_lower_index = 0;
+
+  //initBuchMoraCrit(strat); /*set Gebauer, honey, sugarCrit*/
+  initSbaCrit(strat); /*set Gebauer, honey, sugarCrit*/
+  initSbaPos(strat);
+  //initBuchMoraPos(strat);
+  initHilbCrit(F,Q,&hilb,strat);
+  initSba(F,strat);
+  /*set enterS, spSpolyShort, reduce, red, initEcart, initEcartPair*/
+  /*Shdl=*/initSbaBuchMora(F, Q,strat);
+  if (strat->minim>0) strat->M=idInit(IDELEMS(F),F->rank);
+  srmax = strat->sl;
+  reduc = olddeg = lrmax = 0;
+
+#ifndef NO_BUCKETS
+  if (!TEST_OPT_NOT_BUCKETS)
+    strat->use_buckets = 1;
+#endif
+
+  // redtailBBa against T for inhomogenous input
+  // if (!TEST_OPT_OLDSTD)
+  //   withT = ! strat->homog;
+
+  // strat->posInT = posInT_pLength;
+  kTest_TS(strat);
+
+#ifdef KDEBUG
+#if MYTEST
+  if (TEST_OPT_DEBUG)
+  {
+    PrintS("bba start GB: currRing: ");
+    // rWrite(currRing);PrintLn();
+    rDebugPrint(currRing);
+    PrintLn();
+  }
+#endif /* MYTEST */
+#endif /* KDEBUG */
+
+#ifdef HAVE_TAIL_RING
+  if(!idIs0(F) &&(!rField_is_Ring(currRing)))  // create strong gcd poly computes with tailring and S[i] ->to be fixed
+    kStratInitChangeTailRing(strat);
+#endif
+  if (BVERBOSE(23))
+  {
+    if (test_PosInT!=NULL) strat->posInT=test_PosInT;
+    if (test_PosInL!=NULL) strat->posInL=test_PosInL;
+    kDebugPrint(strat);
+  }
+
+
+#ifdef KDEBUG
+  //kDebugPrint(strat);
+#endif
+  /* compute------------------------------------------------------- */
+  while (strat->Ll >= 0)
+  {
+    if (strat->Ll > lrmax) lrmax =strat->Ll;/*stat.*/
+    #ifdef KDEBUG
+      loop_count++;
+      if (TEST_OPT_DEBUG) messageSets(strat);
+    #endif
+    if (strat->Ll== 0) strat->interpt=TRUE;
+    /*
+    if (TEST_OPT_DEGBOUND
+        && ((strat->honey && (strat->L[strat->Ll].ecart+currRing->pFDeg(strat->L[strat->Ll].p,currRing)>Kstd1_deg))
+            || ((!strat->honey) && (currRing->pFDeg(strat->L[strat->Ll].p,currRing)>Kstd1_deg))))
+    {
+
+       //stops computation if
+       // 24 IN test and the degree +ecart of L[strat->Ll] is bigger then
+       //a predefined number Kstd1_deg
+      while ((strat->Ll >= 0)
+        && (strat->L[strat->Ll].p1!=NULL) && (strat->L[strat->Ll].p2!=NULL)
+        && ((strat->honey && (strat->L[strat->Ll].ecart+currRing->pFDeg(strat->L[strat->Ll].p,currRing)>Kstd1_deg))
+            || ((!strat->honey) && (currRing->pFDeg(strat->L[strat->Ll].p,currRing)>Kstd1_deg)))
+        )
+        deleteInL(strat->L,&strat->Ll,strat->Ll,strat);
+      if (strat->Ll<0) break;
+      else strat->noClearS=TRUE;
+    }
+    */
+    if (strat->sbaOrder == 1 && pGetComp(strat->L[strat->Ll].sig) != strat->currIdx)
+    {
+      strat->currIdx  = pGetComp(strat->L[strat->Ll].sig);
+#if F5C
+      // 1. interreduction of the current standard basis
+      // 2. generation of new principal syzygy rules for syzCriterion
+      f5c ( strat, olddeg, minimcnt, hilbeledeg, hilbcount, srmax,
+          lrmax, reduc, Q, w, hilb );
+#endif
+      // initialize new syzygy rules for the next iteration step
+      initSyzRules(strat);
+
+    }
+    /*********************************************************************
+      * interrreduction step is done, we can go on with the next iteration
+      * step of the signature-based algorithm
+      ********************************************************************/
+    /* picks the last element from the lazyset L */
+    strat->P = strat->L[strat->Ll];
+    strat->Ll--;
+    /* reduction of the element choosen from L */
+
+    if (!strat->rewCrit2(strat->P.sig, ~strat->P.sevSig, strat->P.GetLmCurrRing(), strat, strat->P.checked+1)) {
+      //#if 1
+#ifdef DEBUGF5
+      Print("SIG OF NEXT PAIR TO HANDLE IN SIG-BASED ALGORITHM\n");
+      Print("-------------------------------------------------\n");
+      pWrite(strat->P.sig);
+      pWrite(pHead(strat->P.p));
+      pWrite(pHead(strat->P.p1));
+      pWrite(pHead(strat->P.p2));
+      Print("-------------------------------------------------\n");
+#endif
+      if (pNext(strat->P.p) == strat->tail)
+      {
+        // deletes the short spoly
+        /*
+#ifdef HAVE_RINGS
+        if (rField_is_Ring(currRing))
+          pLmDelete(strat->P.p);
+        else
+#endif
+          pLmFree(strat->P.p);
+*/
+          // TODO: needs some masking
+          // TODO: masking needs to vanish once the signature
+          //       sutff is completely implemented
+          strat->P.p = NULL;
+        poly m1 = NULL, m2 = NULL;
+
+        // check that spoly creation is ok
+        while (strat->tailRing != currRing &&
+            !kCheckSpolyCreation(&(strat->P), strat, m1, m2))
+        {
+          assume(m1 == NULL && m2 == NULL);
+          // if not, change to a ring where exponents are at least
+          // large enough
+          if (!kStratChangeTailRing(strat))
+          {
+            WerrorS("OVERFLOW...");
+            break;
+          }
+        }
+        // create the real one
+        ksCreateSpoly(&(strat->P), NULL, strat->use_buckets,
+            strat->tailRing, m1, m2, strat->R);
+
+      }
+      else if (strat->P.p1 == NULL)
+      {
+        if (strat->minim > 0)
+          strat->P.p2=p_Copy(strat->P.p, currRing, strat->tailRing);
+        // for input polys, prepare reduction
+        strat->P.PrepareRed(strat->use_buckets);
+      }
+      if (strat->P.p == NULL && strat->P.t_p == NULL)
+      {
+        red_result = 0;
+      }
+      else
+      {
+        //#if 1
+#ifdef DEBUGF5
+        Print("Poly before red: ");
+        pWrite(pHead(strat->P.p));
+        pWrite(strat->P.sig);
+#endif
+#if SBA_PRODUCT_CRITERION
+        if (strat->P.prod_crit) {
+#if SBA_PRINT_PRODUCT_CRITERION
+          product_criterion++;
+#endif
+          int pos = posInSyz(strat, strat->P.sig);
+          enterSyz(strat->P, strat, pos);
+          if (strat->P.lcm!=NULL)
+            pLmFree(strat->P.lcm);
+          red_result = 2;
+        } else {
+          red_result = strat->red(&strat->P,strat);
+        }
+#else
+        red_result = strat->red(&strat->P,strat);
+#endif
+      }
+    } else {
+      /*
+      if (strat->P.lcm != NULL)
+        pLmFree(strat->P.lcm);
+        */
+      red_result = 2;
+    }
+    if (errorreported)  break;
+
+//#if 1
+#ifdef DEBUGF5
+    if (red_result != 0) {
+        Print("Poly after red: ");
+        pWrite(pHead(strat->P.p));
+        pWrite(strat->P.GetLmCurrRing());
+        pWrite(strat->P.sig);
+        printf("%d\n",red_result);
+    }
+#endif
+
+    if (strat->overflow)
+    {
+        if (!kStratChangeTailRing(strat)) { Werror("OVERFLOW.."); break;}
+    }
+
+    // reduction to non-zero new poly
+    if (red_result == 1)
+    {
+      // get the polynomial (canonicalize bucket, make sure P.p is set)
+      strat->P.GetP(strat->lmBin);
+
+      // sig-safe computations may lead to wrong FDeg computation, thus we need
+      // to recompute it to make sure everything is alright
+      (strat->P).FDeg = (strat->P).pFDeg();
+      // in the homogeneous case FDeg >= pFDeg (sugar/honey)
+      // but now, for entering S, T, we reset it
+      // in the inhomogeneous case: FDeg == pFDeg
+      if (strat->homog) strat->initEcart(&(strat->P));
+
+      /* statistic */
+      if (TEST_OPT_PROT) PrintS("s");
+
+      //int pos=posInS(strat,strat->sl,strat->P.p,strat->P.ecart);
+      // in F5E we know that the last reduced element is already the
+      // the one with highest signature
+      int pos = strat->sl+1;
+
+#ifdef KDEBUG
+#if MYTEST
+      PrintS("New S: "); pDebugPrint(strat->P.p); PrintLn();
+#endif /* MYTEST */
+#endif /* KDEBUG */
+
+      // reduce the tail and normalize poly
+      // in the ring case we cannot expect LC(f) = 1,
+      // therefore we call pContent instead of pNorm
+#if SBA_TAIL_RED
+      if (strat->sbaOrder != 2) {
+        if ((TEST_OPT_INTSTRATEGY) || (rField_is_Ring(currRing)))
+        {
+          strat->P.pCleardenom();
+          if ((TEST_OPT_REDSB)||(TEST_OPT_REDTAIL))
+          {
+            strat->P.p = redtailSba(&(strat->P),pos-1,strat, withT);
+            strat->P.pCleardenom();
+          }
+        }
+        else
+        {
+          strat->P.pNorm();
+          if ((TEST_OPT_REDSB)||(TEST_OPT_REDTAIL))
+            strat->P.p = redtailSba(&(strat->P),pos-1,strat, withT);
+        }
+      }
+#endif
+
+    // remove sigsafe label since it is no longer valid for the next element to
+    // be reduced
+    if (strat->sbaOrder == 1)
+    {
+      for (int jj = 0; jj<strat->tl+1; jj++)
+      {
+        if (pGetComp(strat->T[jj].sig) == strat->currIdx)
+        {
+          strat->T[jj].is_sigsafe = FALSE;
+        }
+      }
+    }
+    else
+    {
+      for (int jj = 0; jj<strat->tl+1; jj++)
+      {
+        strat->T[jj].is_sigsafe = FALSE;
+      }
+    }
+#ifdef KDEBUG
+      if (TEST_OPT_DEBUG){PrintS("new s:");strat->P.wrp();PrintLn();}
+#if MYTEST
+//#if 1
+      PrintS("New (reduced) S: "); pDebugPrint(strat->P.p); PrintLn();
+#endif /* MYTEST */
+#endif /* KDEBUG */
+
+      // min_std stuff
+      if ((strat->P.p1==NULL) && (strat->minim>0))
+      {
+        if (strat->minim==1)
+        {
+          strat->M->m[minimcnt]=p_Copy(strat->P.p,currRing,strat->tailRing);
+          p_Delete(&strat->P.p2, currRing, strat->tailRing);
+        }
+        else
+        {
+          strat->M->m[minimcnt]=strat->P.p2;
+          strat->P.p2=NULL;
+        }
+        if (strat->tailRing!=currRing && pNext(strat->M->m[minimcnt])!=NULL)
+          pNext(strat->M->m[minimcnt])
+            = strat->p_shallow_copy_delete(pNext(strat->M->m[minimcnt]),
+                                           strat->tailRing, currRing,
+                                           currRing->PolyBin);
+        minimcnt++;
+      }
+
+      // enter into S, L, and T
+      //if ((!TEST_OPT_IDLIFT) || (pGetComp(strat->P.p) <= strat->syzComp))
+      enterT(strat->P, strat);
+      strat->T[strat->tl].is_sigsafe = FALSE;
+      /*
+      printf("hier\n");
+      pWrite(strat->P.GetLmCurrRing());
+      pWrite(strat->P.sig);
+      */
+#ifdef HAVE_RINGS
+      if (rField_is_Ring(currRing))
+        superenterpairs(strat->P.p,strat->sl,strat->P.ecart,pos,strat, strat->tl);
+      else
+#endif
+        enterpairsSig(strat->P.p,strat->P.sig,strat->sl+1,strat->sl,strat->P.ecart,pos,strat, strat->tl);
+      // posInS only depends on the leading term
+      strat->enterS(strat->P, pos, strat, strat->tl);
+      if(strat->sbaOrder != 1)
+      {
+        BOOLEAN overwrite = FALSE;
+        for (int tk=0; tk<strat->sl+1; tk++)
+        {
+          if (pGetComp(strat->sig[tk]) == pGetComp(strat->P.sig))
+          {
+            //printf("TK %d / %d\n",tk,strat->sl);
+            overwrite = FALSE;
+            break;
+          }
+        }
+        //printf("OVERWRITE %d\n",overwrite);
+        if (overwrite)
+        {
+          int cmp = pGetComp(strat->P.sig);
+          int* vv = (int*)omAlloc((currRing->N+1)*sizeof(int));
+          pGetExpV (strat->P.p,vv);
+          pSetExpV (strat->P.sig, vv);
+          pSetComp (strat->P.sig,cmp);
+
+          strat->P.sevSig = pGetShortExpVector (strat->P.sig);
+          int i;
+          LObject Q;
+          for(int ps=0;ps<strat->sl+1;ps++)
+          {
+
+            strat->newt = TRUE;
+            if (strat->syzl == strat->syzmax)
+            {
+              pEnlargeSet(&strat->syz,strat->syzmax,setmaxTinc);
+              strat->sevSyz = (unsigned long*) omRealloc0Size(strat->sevSyz,
+                  (strat->syzmax)*sizeof(unsigned long),
+                  ((strat->syzmax)+setmaxTinc)
+                  *sizeof(unsigned long));
+              strat->syzmax += setmaxTinc;
+            }
+            Q.sig = pCopy(strat->P.sig);
+            // add LM(F->m[i]) to the signature to get a Schreyer order
+            // without changing the underlying polynomial ring at all
+            if (strat->sbaOrder == 0)
+              p_ExpVectorAdd (Q.sig,strat->S[ps],currRing);
+            // since p_Add_q() destroys all input
+            // data we need to recreate help
+            // each time
+            // ----------------------------------------------------------
+            // in the Schreyer order we always know that the multiplied
+            // module monomial strat->P.sig gives the leading monomial of
+            // the corresponding principal syzygy
+            // => we do not need to compute the "real" syzygy completely
+            poly help = p_Copy(strat->sig[ps],currRing);
+            p_ExpVectorAdd (help,strat->P.p,currRing);
+            Q.sig = p_Add_q(Q.sig,help,currRing);
+            //printf("%d. SYZ  ",i+1);
+            //pWrite(strat->syz[i]);
+            Q.sevSig = p_GetShortExpVector(Q.sig,currRing);
+            i = posInSyz(strat, Q.sig);
+            enterSyz(Q, strat, i);
+          }
+        }
+      }
+      // deg - idx - lp/rp
+      // => we need to add syzygies with indices > pGetComp(strat->P.sig)
+      if(strat->sbaOrder == 0 || strat->sbaOrder == 3)
+      {
+        int cmp     = pGetComp(strat->P.sig);
+        int max_cmp = IDELEMS(F);
+        int* vv = (int*)omAlloc((currRing->N+1)*sizeof(int));
+        pGetExpV (strat->P.p,vv);
+        LObject Q;
+        int pos;
+        int idx = p_GetComp(strat->P.sig,currRing);
+        //printf("++ -- adding syzygies -- ++\n");
+        // if new element is the first one in this index
+        if (strat->currIdx < idx) {
+          for (int i=0; i<strat->sl; ++i) {
+            Q.sig = p_Copy(strat->P.sig,currRing);
+            p_ExpVectorAdd(Q.sig,strat->S[i],currRing);
+            poly help = p_Copy(strat->sig[i],currRing);
+            p_ExpVectorAdd(help,strat->P.p,currRing);
+            Q.sig = p_Add_q(Q.sig,help,currRing);
+            //pWrite(Q.sig);
+            pos = posInSyz(strat, Q.sig);
+            enterSyz(Q, strat, pos);
+          }
+          strat->currIdx = idx;
+        } else {
+          // if the element is not the first one in the given index we build all
+          // possible syzygies with elements of higher index
+          for (int i=cmp+1; i<=max_cmp; ++i) {
+            pos = -1;
+            for (int j=0; j<strat->sl; ++j) {
+              if (p_GetComp(strat->sig[j],currRing) == i) {
+                pos = j;
+                break;
+              }
+            }
+            if (pos != -1) {
+              Q.sig = p_One(currRing);
+              p_SetExpV(Q.sig, vv, currRing);
+              // F->m[i-1] corresponds to index i
+              p_ExpVectorAdd(Q.sig,F->m[i-1],currRing);
+              p_SetComp(Q.sig, i, currRing);
+              poly help = p_Copy(strat->P.sig,currRing);
+              p_ExpVectorAdd(help,strat->S[pos],currRing);
+              Q.sig = p_Add_q(Q.sig,help,currRing);
+              if (strat->sbaOrder == 0) {
+                if (p_LmCmp(Q.sig,strat->syz[strat->syzl-1],currRing) == -currRing->OrdSgn) {
+                  pos = posInSyz(strat, Q.sig);
+                  enterSyz(Q, strat, pos);
+                }
+              } else {
+                pos = posInSyz(strat, Q.sig);
+                enterSyz(Q, strat, pos);
+              }
+            }
+          }
+          //printf("++ -- done adding syzygies -- ++\n");
+        }
+      }
+//#if 1
+#if DEBUGF50
+    printf("---------------------------\n");
+    Print(" %d. ELEMENT ADDED TO GCURR:\n",strat->sl+1);
+    Print("LEAD POLY:  "); pWrite(pHead(strat->S[strat->sl]));
+    Print("SIGNATURE:  "); pWrite(strat->sig[strat->sl]);
+#endif
+      /*
+      if (newrules)
+      {
+        newrules  = FALSE;
+      }
+      */
+#if 0
+      int pl=pLength(strat->P.p);
+      if (pl==1)
+      {
+        //if (TEST_OPT_PROT)
+        //PrintS("<1>");
+      }
+      else if (pl==2)
+      {
+        //if (TEST_OPT_PROT)
+        //PrintS("<2>");
+      }
+#endif
+      if (hilb!=NULL) khCheck(Q,w,hilb,hilbeledeg,hilbcount,strat);
+//      Print("[%d]",hilbeledeg);
+      if (strat->P.lcm!=NULL)
+#ifdef HAVE_RINGS
+        pLmDelete(strat->P.lcm);
+#else
+        pLmFree(strat->P.lcm);
+#endif
+      if (strat->sl>srmax) srmax = strat->sl;
+    }
+    else
+    {
+      // adds signature of the zero reduction to
+      // strat->syz. This is the leading term of
+      // syzygy and can be used in syzCriterion()
+      // the signature is added if and only if the
+      // pair was not detected by the rewritten criterion in strat->red = redSig
+      if (red_result!=2) {
+#if SBA_PRINT_ZERO_REDUCTIONS
+        zeroreductions++;
+#endif
+        int pos = posInSyz(strat, strat->P.sig);
+        enterSyz(strat->P, strat, pos);
+//#if 1
+#ifdef DEBUGF5
+        Print("ADDING STUFF TO SYZ :  ");
+        //pWrite(strat->P.p);
+        pWrite(strat->P.sig);
+#endif
+      }
+      if (strat->P.p1 == NULL && strat->minim > 0)
+      {
+        p_Delete(&strat->P.p2, currRing, strat->tailRing);
+      }
+    }
+
+#ifdef KDEBUG
+    memset(&(strat->P), 0, sizeof(strat->P));
+#endif /* KDEBUG */
+    kTest_TS(strat);
+  }
+#ifdef KDEBUG
+#if MYTEST
+  PrintS("bba finish GB: currRing: "); rWrite(currRing);
+#endif /* MYTEST */
+  if (TEST_OPT_DEBUG) messageSets(strat);
+#endif /* KDEBUG */
+
+  if (TEST_OPT_SB_1)
+  {
+    #ifdef HAVE_RINGS
+    if(!rField_is_Ring(currRing))
+    #endif
+    {
+        int k=1;
+        int j;
+        while(k<=strat->sl)
+        {
+          j=0;
+          loop
+          {
+            if (j>=k) break;
+            clearS(strat->S[j],strat->sevS[j],&k,&j,strat);
+            j++;
+          }
+          k++;
+        }
+    }
+  }
+
+  /* complete reduction of the standard basis--------- */
+  if (TEST_OPT_REDSB)
+  {
+    completeReduce(strat);
+#ifdef HAVE_TAIL_RING
+    if (strat->completeReduce_retry)
+    {
+      // completeReduce needed larger exponents, retry
+      // to reduce with S (instead of T)
+      // and in currRing (instead of strat->tailRing)
+      cleanT(strat);strat->tailRing=currRing;
+      int i;
+      for(i=strat->sl;i>=0;i--) strat->S_2_R[i]=-1;
+      completeReduce(strat);
+    }
+#endif
+  }
+  else if (TEST_OPT_PROT) PrintLn();
+
+#if SBA_PRINT_SIZE_SYZ
+  // that is correct, syzl is counting one too far
+  size_syz = strat->syzl;
+#endif
+  exitSba(strat);
+//  if (TEST_OPT_WEIGHTM)
+//  {
+//    pRestoreDegProcs(pFDegOld, pLDegOld);
+//    if (ecartWeights)
+//    {
+//      omFreeSize((ADDRESS)ecartWeights,(pVariables+1)*sizeof(short));
+//      ecartWeights=NULL;
+//    }
+//  }
+  if (TEST_OPT_PROT) messageStat(hilbcount,strat);
+  if (Q!=NULL) updateResult(strat->Shdl,Q,strat);
+
+#ifdef KDEBUG
+#if MYTEST
+  PrintS("bba_end: currRing: "); rWrite(currRing);
+#endif /* MYTEST */
+#endif /* KDEBUG */
+#if SBA_PRINT_SIZE_G
+  size_g_non_red  = IDELEMS(strat->Shdl);
+#endif
+  if ((strat->sbaOrder == 1 || strat->sbaOrder == 3) && sRing!=currRingOld)
+  {
+    rChangeCurrRing (currRingOld);
+    F0          = idrMoveR (F1, sRing, currRing);
+    strat->Shdl = idrMoveR_NoSort (strat->Shdl, sRing, currRing);
+    rDelete (sRing);
+  }
+  id_DelDiv(strat->Shdl, currRing);
+  idSkipZeroes(strat->Shdl);
+  idTest(strat->Shdl);
+
+#if SBA_PRINT_SIZE_G
+  size_g   = IDELEMS(strat->Shdl);
+#endif
+#ifdef DEBUGF5
+  printf("SIZE OF SHDL: %d\n",IDELEMS(strat->Shdl));
+  int oo = 0;
+  while (oo<IDELEMS(strat->Shdl))
+  {
+    printf(" %d.   ",oo+1);
+    pWrite(pHead(strat->Shdl->m[oo]));
+    oo++;
+  }
+#endif
+#if SBA_PRINT_ZERO_REDUCTIONS
+  printf("----------------------------------------------------------\n");
+  printf("ZERO REDUCTIONS:            %ld\n",zeroreductions);
+  zeroreductions  = 0;
+#endif
+#if SBA_PRINT_REDUCTION_STEPS
+  printf("----------------------------------------------------------\n");
+  printf("S-REDUCTIONS:               %ld\n",sba_reduction_steps);
+#endif
+#if SBA_PRINT_OPERATIONS
+  printf("OPERATIONS:                 %ld\n",sba_operations);
+#endif
+#if SBA_PRINT_REDUCTION_STEPS
+  printf("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - \n");
+  printf("INTERREDUCTIONS:            %ld\n",sba_interreduction_steps);
+#endif
+#if SBA_PRINT_OPERATIONS
+  printf("INTERREDUCTION OPERATIONS:  %ld\n",sba_interreduction_operations);
+#endif
+#if SBA_PRINT_REDUCTION_STEPS
+  printf("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - \n");
+  printf("ALL REDUCTIONS:             %ld\n",sba_reduction_steps+sba_interreduction_steps);
+  sba_interreduction_steps  = 0;
+  sba_reduction_steps       = 0;
+#endif
+#if SBA_PRINT_OPERATIONS
+  printf("ALL OPERATIONS:             %ld\n",sba_operations+sba_interreduction_operations);
+  sba_interreduction_operations = 0;
+  sba_operations                = 0;
+#endif
+#if SBA_PRINT_SIZE_G
+  printf("----------------------------------------------------------\n");
+  printf("SIZE OF G:                  %d / %d\n",size_g,size_g_non_red);
+  size_g          = 0;
+  size_g_non_red  = 0;
+#endif
+#if SBA_PRINT_SIZE_SYZ
+  printf("SIZE OF SYZ:                %ld\n",size_syz);
+  printf("----------------------------------------------------------\n");
+  size_syz  = 0;
+#endif
+#if SBA_PRINT_PRODUCT_CRITERION
+  printf("PRODUCT CRITERIA:           %ld\n",product_criterion);
+  product_criterion = 0;
+#endif
+  return (strat->Shdl);
+}
+
+poly kNF2 (ideal F,ideal Q,poly q,kStrategy strat, int lazyReduce)
+{
+  assume(q!=NULL);
+  assume(!(idIs0(F)&&(Q==NULL))); // NF(q, std(0) in polynomial ring?
+
+// lazy_reduce flags: can be combined by |
+//#define KSTD_NF_LAZY   1
+  // do only a reduction of the leading term
+//#define KSTD_NF_NONORM 4
+  // only global: avoid normalization, return a multiply of NF
+  poly   p;
+
+  //if ((idIs0(F))&&(Q==NULL))
+  //  return pCopy(q); /*F=0*/
+  //strat->ak = idRankFreeModule(F);
+  /*- creating temp data structures------------------- -*/
+  BITSET save1;
+  SI_SAVE_OPT1(save1);
+  si_opt_1|=Sy_bit(OPT_REDTAIL);
+  initBuchMoraCrit(strat);
+  strat->initEcart = initEcartBBA;
+  strat->enterS = enterSBba;
+#ifndef NO_BUCKETS
+  strat->use_buckets = (!TEST_OPT_NOT_BUCKETS) && (!rIsPluralRing(currRing));
+#endif
+  /*- set S -*/
+  strat->sl = -1;
+  /*- init local data struct.---------------------------------------- -*/
+  /*Shdl=*/initS(F,Q,strat);
+  /*- compute------------------------------------------------------- -*/
+  //if ((TEST_OPT_INTSTRATEGY)&&(lazyReduce==0))
+  //{
+  //  for (i=strat->sl;i>=0;i--)
+  //    pNorm(strat->S[i]);
+  //}
+  kTest(strat);
+  if (TEST_OPT_PROT) { PrintS("r"); mflush(); }
+  if (BVERBOSE(23)) kDebugPrint(strat);
+  int max_ind;
+  p = redNF(pCopy(q),max_ind,lazyReduce & KSTD_NF_NONORM,strat);
+  if ((p!=NULL)&&((lazyReduce & KSTD_NF_LAZY)==0))
+  {
+    if (TEST_OPT_PROT) { PrintS("t"); mflush(); }
+    #ifdef HAVE_RINGS
+    if (rField_is_Ring(currRing))
+    {
+      p = redtailBba_Z(p,max_ind,strat);
+    }
+    else
+    #endif
+    {
+      si_opt_1 &= ~Sy_bit(OPT_INTSTRATEGY);
+      p = redtailBba(p,max_ind,strat,(lazyReduce & KSTD_NF_NONORM)==0);
+    }
+  }
+  /*- release temp data------------------------------- -*/
+  assume(strat->L==NULL); /* strat->L unused */
+  assume(strat->B==NULL); /* strat->B unused */
+  omFree(strat->sevS);
+  omFree(strat->ecartS);
+  assume(strat->T==NULL);//omfree(strat->T);
+  assume(strat->sevT==NULL);//omfree(strat->sevT);
+  assume(strat->R==NULL);//omfree(strat->R);
+  omfree(strat->S_2_R);
+  omfree(strat->fromQ);
+  idDelete(&strat->Shdl);
+  SI_RESTORE_OPT1(save1);
+  if (TEST_OPT_PROT) PrintLn();
+  return p;
+}
+
+ideal kNF2 (ideal F,ideal Q,ideal q,kStrategy strat, int lazyReduce)
+{
+  assume(!idIs0(q));
+  assume(!(idIs0(F)&&(Q==NULL)));
+// lazy_reduce flags: can be combined by |
+//#define KSTD_NF_LAZY   1
+  // do only a reduction of the leading term
+//#define KSTD_NF_NONORM 4
+  // only global: avoid normalization, return a multiply of NF
+  poly   p;
+  int   i;
+  ideal res;
+  int max_ind;
+
+  //if (idIs0(q))
+  //  return idInit(IDELEMS(q),si_max(q->rank,F->rank));
+  //if ((idIs0(F))&&(Q==NULL))
+  //  return idCopy(q); /*F=0*/
+  //strat->ak = idRankFreeModule(F);
+  /*- creating temp data structures------------------- -*/
+  BITSET save1;
+  SI_SAVE_OPT1(save1);
+  si_opt_1|=Sy_bit(OPT_REDTAIL);
+  initBuchMoraCrit(strat);
+  strat->initEcart = initEcartBBA;
+  strat->enterS = enterSBba;
+  /*- set S -*/
+  strat->sl = -1;
+#ifndef NO_BUCKETS
+  strat->use_buckets = (!TEST_OPT_NOT_BUCKETS) && (!rIsPluralRing(currRing));
+#endif
+  /*- init local data struct.---------------------------------------- -*/
+  /*Shdl=*/initS(F,Q,strat);
+  /*- compute------------------------------------------------------- -*/
+  res=idInit(IDELEMS(q),si_max(q->rank,F->rank));
+  si_opt_1 &= ~Sy_bit(OPT_INTSTRATEGY);
+  for (i=IDELEMS(q)-1; i>=0; i--)
+  {
+    if (q->m[i]!=NULL)
+    {
+      if (TEST_OPT_PROT) { PrintS("r");mflush(); }
+      p = redNF(pCopy(q->m[i]),max_ind,lazyReduce & KSTD_NF_NONORM,strat);
+      if ((p!=NULL)&&((lazyReduce & KSTD_NF_LAZY)==0))
+      {
+        if (TEST_OPT_PROT) { PrintS("t"); mflush(); }
+        #ifdef HAVE_RINGS
+        if (rField_is_Ring(currRing))
+        {
+          p = redtailBba_Z(p,max_ind,strat);
+        }
+        else
+        #endif
+        {
+          p = redtailBba(p,max_ind,strat,(lazyReduce & KSTD_NF_NONORM)==0);
+        }
+      }
+      res->m[i]=p;
+    }
+    //else
+    //  res->m[i]=NULL;
+  }
+  /*- release temp data------------------------------- -*/
+  assume(strat->L==NULL); /* strat->L unused */
+  assume(strat->B==NULL); /* strat->B unused */
+  omFree(strat->sevS);
+  omFree(strat->ecartS);
+  assume(strat->T==NULL);//omfree(strat->T);
+  assume(strat->sevT==NULL);//omfree(strat->sevT);
+  assume(strat->R==NULL);//omfree(strat->R);
+  omfree(strat->S_2_R);
+  omfree(strat->fromQ);
+  idDelete(&strat->Shdl);
+  SI_RESTORE_OPT1(save1);
+  if (TEST_OPT_PROT) PrintLn();
+  return res;
+}
+
+#if F5C
+/*********************************************************************
+* interrreduction step of the signature-based algorithm:
+* 1. all strat->S are interpreted as new critical pairs
+* 2. those pairs need to be completely reduced by the usual (non sig-
+*    safe) reduction process (including tail reductions)
+* 3. strat->S and strat->T are completely new computed in these steps
+********************************************************************/
+void f5c (kStrategy strat, int& olddeg, int& minimcnt, int& hilbeledeg,
+          int& hilbcount, int& srmax, int& lrmax, int& reduc, ideal Q,
+          intvec *w,intvec *hilb )
+{
+  int Ll_old, red_result = 1;
+  int pos  = 0;
+  hilbeledeg=1;
+  hilbcount=0;
+  minimcnt=0;
+  srmax = 0; // strat->sl is 0 at this point
+  reduc = olddeg = lrmax = 0;
+  // we cannot use strat->T anymore
+  //cleanT(strat);
+  //strat->tl = -1;
+  Ll_old    = strat->Ll;
+  while (strat->tl >= 0)
+  {
+    if(!strat->T[strat->tl].is_redundant)
+    {
+      LObject h;
+      h.p = strat->T[strat->tl].p;
+      h.tailRing = strat->T[strat->tl].tailRing;
+      h.t_p = strat->T[strat->tl].t_p;
+      if (h.p!=NULL)
+      {
+        if (currRing->OrdSgn==-1)
+        {
+          cancelunit(&h);
+          deleteHC(&h, strat);
+        }
+        if (h.p!=NULL)
+        {
+          if (TEST_OPT_INTSTRATEGY)
+          {
+            //pContent(h.p);
+            h.pCleardenom(); // also does a pContent
+          }
+          else
+          {
+            h.pNorm();
+          }
+          strat->initEcart(&h);
+          pos = strat->Ll+1;
+          h.sev = pGetShortExpVector(h.p);
+          enterL(&strat->L,&strat->Ll,&strat->Lmax,h,pos);
+        }
+      }
+    }
+    strat->tl--;
+  }
+  strat->sl = -1;
+#if 0
+//#ifdef HAVE_TAIL_RING
+  if(!rField_is_Ring())  // create strong gcd poly computes with tailring and S[i] ->to be fixed
+    kStratInitChangeTailRing(strat);
+#endif
+  //enterpairs(pOne(),0,0,-1,strat,strat->tl);
+  //strat->sl = -1;
+  /* picks the last element from the lazyset L */
+  while (strat->Ll>Ll_old)
+  {
+    strat->P = strat->L[strat->Ll];
+    strat->Ll--;
+//#if 1
+#ifdef DEBUGF5
+    Print("NEXT PAIR TO HANDLE IN INTERRED ALGORITHM\n");
+    Print("-------------------------------------------------\n");
+    pWrite(pHead(strat->P.p));
+    pWrite(pHead(strat->P.p1));
+    pWrite(pHead(strat->P.p2));
+    printf("%d\n",strat->tl);
+    Print("-------------------------------------------------\n");
+#endif
+    if (pNext(strat->P.p) == strat->tail)
+    {
+      // deletes the short spoly
+#ifdef HAVE_RINGS
+      if (rField_is_Ring(currRing))
+        pLmDelete(strat->P.p);
+      else
+#endif
+        pLmFree(strat->P.p);
+
+      // TODO: needs some masking
+      // TODO: masking needs to vanish once the signature
+      //       sutff is completely implemented
+      strat->P.p = NULL;
+      poly m1 = NULL, m2 = NULL;
+
+      // check that spoly creation is ok
+      while (strat->tailRing != currRing &&
+          !kCheckSpolyCreation(&(strat->P), strat, m1, m2))
+      {
+        assume(m1 == NULL && m2 == NULL);
+        // if not, change to a ring where exponents are at least
+        // large enough
+        if (!kStratChangeTailRing(strat))
+        {
+          WerrorS("OVERFLOW...");
+          break;
+        }
+      }
+      // create the real one
+      ksCreateSpoly(&(strat->P), NULL, strat->use_buckets,
+          strat->tailRing, m1, m2, strat->R);
+    }
+    else if (strat->P.p1 == NULL)
+    {
+      if (strat->minim > 0)
+        strat->P.p2=p_Copy(strat->P.p, currRing, strat->tailRing);
+      // for input polys, prepare reduction
+      strat->P.PrepareRed(strat->use_buckets);
+    }
+
+    if (strat->P.p == NULL && strat->P.t_p == NULL)
+    {
+      red_result = 0;
+    }
+    else
+    {
+      if (TEST_OPT_PROT)
+        message((strat->honey ? strat->P.ecart : 0) + strat->P.pFDeg(),
+            &olddeg,&reduc,strat, red_result);
+
+#ifdef DEBUGF5
+      Print("Poly before red: ");
+      pWrite(strat->P.p);
+#endif
+      /* complete reduction of the element choosen from L */
+      red_result = strat->red2(&strat->P,strat);
+      if (errorreported)  break;
+    }
+
+    if (strat->overflow)
+    {
+      if (!kStratChangeTailRing(strat)) { Werror("OVERFLOW.."); break;}
+    }
+
+    // reduction to non-zero new poly
+    if (red_result == 1)
+    {
+      // get the polynomial (canonicalize bucket, make sure P.p is set)
+      strat->P.GetP(strat->lmBin);
+      // in the homogeneous case FDeg >= pFDeg (sugar/honey)
+      // but now, for entering S, T, we reset it
+      // in the inhomogeneous case: FDeg == pFDeg
+      if (strat->homog) strat->initEcart(&(strat->P));
+
+      /* statistic */
+      if (TEST_OPT_PROT) PrintS("s");
+
+      int pos=posInS(strat,strat->sl,strat->P.p,strat->P.ecart);
+
+#ifdef KDEBUG
+#if MYTEST
+      PrintS("New S: "); pDebugPrint(strat->P.p); PrintLn();
+#endif /* MYTEST */
+#endif /* KDEBUG */
+
+      // reduce the tail and normalize poly
+      // in the ring case we cannot expect LC(f) = 1,
+      // therefore we call pContent instead of pNorm
+#if F5CTAILRED
+      BOOLEAN withT = TRUE;
+      if ((TEST_OPT_INTSTRATEGY) || (rField_is_Ring(currRing)))
+      {
+        strat->P.pCleardenom();
+        if ((TEST_OPT_REDSB)||(TEST_OPT_REDTAIL))
+        {
+          strat->P.p = redtailBba(&(strat->P),pos-1,strat, withT);
+          strat->P.pCleardenom();
+        }
+      }
+      else
+      {
+        strat->P.pNorm();
+        if ((TEST_OPT_REDSB)||(TEST_OPT_REDTAIL))
+          strat->P.p = redtailBba(&(strat->P),pos-1,strat, withT);
+      }
+#endif
+#ifdef KDEBUG
+      if (TEST_OPT_DEBUG){PrintS("new s:");strat->P.wrp();PrintLn();}
+#if MYTEST
+//#if 1
+      PrintS("New (reduced) S: "); pDebugPrint(strat->P.p); PrintLn();
+#endif /* MYTEST */
+#endif /* KDEBUG */
+
+      // min_std stuff
+      if ((strat->P.p1==NULL) && (strat->minim>0))
+      {
+        if (strat->minim==1)
+        {
+          strat->M->m[minimcnt]=p_Copy(strat->P.p,currRing,strat->tailRing);
+          p_Delete(&strat->P.p2, currRing, strat->tailRing);
+        }
+        else
+        {
+          strat->M->m[minimcnt]=strat->P.p2;
+          strat->P.p2=NULL;
+        }
+        if (strat->tailRing!=currRing && pNext(strat->M->m[minimcnt])!=NULL)
+          pNext(strat->M->m[minimcnt])
+            = strat->p_shallow_copy_delete(pNext(strat->M->m[minimcnt]),
+                strat->tailRing, currRing,
+                currRing->PolyBin);
+        minimcnt++;
+      }
+
+      // enter into S, L, and T
+      // here we need to recompute new signatures, but those are trivial ones
+      if ((!TEST_OPT_IDLIFT) || (pGetComp(strat->P.p) <= strat->syzComp))
+      {
+        enterT(strat->P, strat);
+        // posInS only depends on the leading term
+        strat->enterS(strat->P, pos, strat, strat->tl);
+//#if 1
+#ifdef DEBUGF5
+        Print("ELEMENT ADDED TO GCURR DURING INTERRED: ");
+        pWrite(pHead(strat->S[strat->sl]));
+        pWrite(strat->sig[strat->sl]);
+#endif
+        if (hilb!=NULL) khCheck(Q,w,hilb,hilbeledeg,hilbcount,strat);
+      }
+      //      Print("[%d]",hilbeledeg);
+      if (strat->P.lcm!=NULL)
+#ifdef HAVE_RINGS
+        pLmDelete(strat->P.lcm);
+#else
+      pLmFree(strat->P.lcm);
+#endif
+      if (strat->sl>srmax) srmax = strat->sl;
+    }
+    else
+    {
+      // adds signature of the zero reduction to
+      // strat->syz. This is the leading term of
+      // syzygy and can be used in syzCriterion()
+      // the signature is added if and only if the
+      // pair was not detected by the rewritten criterion in strat->red = redSig
+      if (strat->P.p1 == NULL && strat->minim > 0)
+      {
+        p_Delete(&strat->P.p2, currRing, strat->tailRing);
+      }
+    }
+
+#ifdef KDEBUG
+    memset(&(strat->P), 0, sizeof(strat->P));
+#endif /* KDEBUG */
+  }
+  int cc = 0;
+  while (cc<strat->tl+1)
+  {
+    strat->T[cc].sig        = pOne();
+    p_SetComp(strat->T[cc].sig,cc+1,currRing);
+    strat->T[cc].sevSig     = pGetShortExpVector(strat->T[cc].sig);
+    strat->sig[cc]          = strat->T[cc].sig;
+    strat->sevSig[cc]       = strat->T[cc].sevSig;
+    strat->T[cc].is_sigsafe = TRUE;
+    cc++;
+  }
+  strat->max_lower_index = strat->tl;
+  // set current signature index of upcoming iteration step
+  // NOTE:  this needs to be set here, as otherwise initSyzRules cannot compute
+  //        the corresponding syzygy rules correctly
+  strat->currIdx = cc+1;
+  for (int cd=strat->Ll; cd>=0; cd--)
+  {
+    p_SetComp(strat->L[cd].sig,cc+1,currRing);
+    cc++;
+  }
+  for (cc=strat->sl+1; cc<IDELEMS(strat->Shdl); ++cc)
+    strat->Shdl->m[cc]  = NULL;
+//#if 1
+#if DEBUGF5
+  Print("------------------- STRAT S ---------------------\n");
+  cc = 0;
+  while (cc<strat->tl+1)
+  {
+    pWrite(pHead(strat->S[cc]));
+    pWrite(strat->sig[cc]);
+    printf("- - - - - -\n");
+    cc++;
+  }
+  Print("-------------------------------------------------\n");
+  Print("------------------- STRAT T ---------------------\n");
+  cc = 0;
+  while (cc<strat->tl+1)
+  {
+    pWrite(pHead(strat->T[cc].p));
+    pWrite(strat->T[cc].sig);
+    printf("- - - - - -\n");
+    cc++;
+  }
+  Print("-------------------------------------------------\n");
+  Print("------------------- STRAT L ---------------------\n");
+  cc = 0;
+  while (cc<strat->Ll+1)
+  {
+    pWrite(pHead(strat->L[cc].p));
+    pWrite(pHead(strat->L[cc].p1));
+    pWrite(pHead(strat->L[cc].p2));
+    pWrite(strat->L[cc].sig);
+    printf("- - - - - -\n");
+    cc++;
+  }
+  Print("-------------------------------------------------\n");
+  printf("F5C DONE\nSTRAT SL: %d -- %d\n",strat->sl, strat->currIdx);
+#endif
+
+}
+#endif
+
+/* shiftgb stuff */
+#ifdef HAVE_SHIFTBBA
+
+
+ideal bbaShift(ideal F, ideal Q,intvec *w,intvec *hilb,kStrategy strat, int uptodeg, int lV)
+{
+#ifdef KDEBUG
+  bba_count++;
+  int loop_count = 0;
+#endif
+  int   red_result = 1;
+  int   olddeg,reduc;
+  int hilbeledeg=1,hilbcount=0,minimcnt=0;
+  BOOLEAN withT = TRUE; // very important for shifts
+
+  initBuchMoraCrit(strat); /*set Gebauer, honey, sugarCrit, NO CHANGES */
+  initBuchMoraPos(strat); /*NO CHANGES YET: perhaps later*/
+  initHilbCrit(F,Q,&hilb,strat); /*NO CHANGES*/
+  initBbaShift(F,strat); /* DONE */
+  /*set enterS, spSpolyShort, reduce, red, initEcart, initEcartPair*/
+  /*Shdl=*/initBuchMoraShift(F, Q,strat); /* updateS with no toT, i.e. no init for T */
+  updateSShift(strat,uptodeg,lV); /* initializes T */
+
+  if (strat->minim>0) strat->M=idInit(IDELEMS(F),F->rank);
+  reduc = olddeg = 0;
+  strat->lV=lV;
+
+#ifndef NO_BUCKETS
+  if (!TEST_OPT_NOT_BUCKETS)
+    strat->use_buckets = 1;
+#endif
+
+  // redtailBBa against T for inhomogenous input
+  //  if (!TEST_OPT_OLDSTD)
+  //    withT = ! strat->homog;
+
+  // strat->posInT = posInT_pLength;
+  kTest_TS(strat);
+
+#ifdef HAVE_TAIL_RING
+  kStratInitChangeTailRing(strat);
+#endif
+
+  /* compute------------------------------------------------------- */
+  while (strat->Ll >= 0)
+  {
+#ifdef KDEBUG
+    loop_count++;
+    if (TEST_OPT_DEBUG) messageSets(strat);
+#endif
+    if (strat->Ll== 0) strat->interpt=TRUE;
+    if (TEST_OPT_DEGBOUND
+        && ((strat->honey && (strat->L[strat->Ll].ecart+currRing->pFDeg(strat->L[strat->Ll].p,currRing)>Kstd1_deg))
+            || ((!strat->honey) && (currRing->pFDeg(strat->L[strat->Ll].p,currRing)>Kstd1_deg))))
+    {
+      /*
+       *stops computation if
+       * 24 IN test and the degree +ecart of L[strat->Ll] is bigger then
+       *a predefined number Kstd1_deg
+       */
+      while ((strat->Ll >= 0)
+        && (strat->L[strat->Ll].p1!=NULL) && (strat->L[strat->Ll].p2!=NULL)
+        && ((strat->honey && (strat->L[strat->Ll].ecart+currRing->pFDeg(strat->L[strat->Ll].p,currRing)>Kstd1_deg))
+            || ((!strat->honey) && (currRing->pFDeg(strat->L[strat->Ll].p,currRing)>Kstd1_deg)))
+        )
+        deleteInL(strat->L,&strat->Ll,strat->Ll,strat);
+      if (strat->Ll<0) break;
+      else strat->noClearS=TRUE;
+    }
+    /* picks the last element from the lazyset L */
+    strat->P = strat->L[strat->Ll];
+    strat->Ll--;
+
+    if (pNext(strat->P.p) == strat->tail)
+    {
+      // deletes the short spoly
+      pLmFree(strat->P.p);
+      strat->P.p = NULL;
+      poly m1 = NULL, m2 = NULL;
+
+      // check that spoly creation is ok
+      while (strat->tailRing != currRing &&
+             !kCheckSpolyCreation(&(strat->P), strat, m1, m2))
+      {
+        assume(m1 == NULL && m2 == NULL);
+        // if not, change to a ring where exponents are at least
+        // large enough
+        kStratChangeTailRing(strat);
+      }
+      // create the real one
+      ksCreateSpoly(&(strat->P), NULL, strat->use_buckets,
+                    strat->tailRing, m1, m2, strat->R);
+    }
+    else if (strat->P.p1 == NULL)
+    {
+      if (strat->minim > 0)
+        strat->P.p2=p_Copy(strat->P.p, currRing, strat->tailRing);
+      // for input polys, prepare reduction
+      strat->P.PrepareRed(strat->use_buckets);
+    }
+
+    poly qq;
+
+    /* here in the nonhomog case we shrink the new spoly */
+
+    if ( ! strat->homog)
+    {
+      strat->P.GetP(strat->lmBin); // because shifts are counted with .p structure
+      /* in the nonhomog case we have to shrink the polynomial */
+      assume(strat->P.t_p!=NULL);
+      qq = p_Shrink(strat->P.t_p, lV, strat->tailRing); // direct shrink
+      if (qq != NULL)
+      {
+         /* we're here if Shrink is nonzero */
+        //         strat->P.p =  NULL;
+        //        strat->P.Delete(); /* deletes P.p and P.t_p */ //error
+        strat->P.p   =  NULL; // is not set by Delete
+        strat->P.t_p =  qq;
+        strat->P.GetP(strat->lmBin);
+        // update sev and length
+        strat->initEcart(&(strat->P));
+        strat->P.sev = pGetShortExpVector(strat->P.p);
+//         strat->P.FDeg = strat->P.pFDeg();
+//         strat->P.length = strat->P.pLDeg();
+//         strat->P.pLength =strat->P.GetpLength(); //pLength(strat->P.p);
+      }
+      else
+      {
+         /* Shrink is zero, like y(1)*y(2) - y(1)*y(3)*/
+#ifdef KDEBUG
+         if (TEST_OPT_DEBUG){PrintS("nonzero s shrinks to 0");PrintLn();}
+#endif
+         //         strat->P.Delete();  // cause error
+         strat->P.p = NULL;
+         strat->P.t_p = NULL;
+           //         strat->P.p = NULL; // or delete strat->P.p ?
+       }
+    }
+      /* end shrinking poly in the nonhomog case */
+
+    if (strat->P.p == NULL && strat->P.t_p == NULL)
+    {
+      red_result = 0;
+    }
+    else
+    {
+      if (TEST_OPT_PROT)
+        message((strat->honey ? strat->P.ecart : 0) + strat->P.pFDeg(),
+                &olddeg,&reduc,strat, red_result);
+
+      /* reduction of the element choosen from L */
+      red_result = strat->red(&strat->P,strat);
+    }
+
+    // reduction to non-zero new poly
+    if (red_result == 1)
+    {
+      /* statistic */
+      if (TEST_OPT_PROT) PrintS("s");
+
+      // get the polynomial (canonicalize bucket, make sure P.p is set)
+      strat->P.GetP(strat->lmBin);
+
+      int pos=posInS(strat,strat->sl,strat->P.p,strat->P.ecart);
+
+      // reduce the tail and normalize poly
+      if (TEST_OPT_INTSTRATEGY)
+      {
+        strat->P.pCleardenom();
+        if ((TEST_OPT_REDSB)||(TEST_OPT_REDTAIL))
+        {
+          strat->P.p = redtailBba(&(strat->P),pos-1,strat, withT);
+          strat->P.pCleardenom();
+        }
+      }
+      else
+      {
+        strat->P.pNorm();
+        if ((TEST_OPT_REDSB)||(TEST_OPT_REDTAIL))
+          strat->P.p = redtailBba(&(strat->P),pos-1,strat, withT);
+      }
+
+      // here we must shrink again! and optionally reduce again
+      // or build shrink into redtailBba!
+
+#ifdef KDEBUG
+      if (TEST_OPT_DEBUG){PrintS("new s:");strat->P.wrp();PrintLn();}
+#endif
+
+      // min_std stuff
+      if ((strat->P.p1==NULL) && (strat->minim>0))
+      {
+        if (strat->minim==1)
+        {
+          strat->M->m[minimcnt]=p_Copy(strat->P.p,currRing,strat->tailRing);
+          p_Delete(&strat->P.p2, currRing, strat->tailRing);
+        }
+        else
+        {
+          strat->M->m[minimcnt]=strat->P.p2;
+          strat->P.p2=NULL;
+        }
+        if (strat->tailRing!=currRing && pNext(strat->M->m[minimcnt])!=NULL)
+          pNext(strat->M->m[minimcnt])
+            = strat->p_shallow_copy_delete(pNext(strat->M->m[minimcnt]),
+                                           strat->tailRing, currRing,
+                                           currRing->PolyBin);
+        minimcnt++;
+      }
+
+    /* here in the nonhomog case we shrink the reduced poly AGAIN */
+
+    if ( ! strat->homog)
+    {
+      strat->P.GetP(strat->lmBin); // because shifts are counted with .p structure
+      /* assume strat->P.t_p != NULL */
+      /* in the nonhomog case we have to shrink the polynomial */
+      assume(strat->P.t_p!=NULL); // poly qq defined above
+      qq = p_Shrink(strat->P.t_p, lV, strat->tailRing); // direct shrink
+      if (qq != NULL)
+      {
+         /* we're here if Shrink is nonzero */
+        //         strat->P.p =  NULL;
+        //        strat->P.Delete(); /* deletes P.p and P.t_p */ //error
+        strat->P.p   =  NULL; // is not set by Delete
+        strat->P.t_p =  qq;
+        strat->P.GetP(strat->lmBin);
+        // update sev and length
+        strat->initEcart(&(strat->P));
+        strat->P.sev = pGetShortExpVector(strat->P.p);
+      }
+      else
+      {
+         /* Shrink is zero, like y(1)*y(2) - y(1)*y(3)*/
+#ifdef PDEBUG
+         if (TEST_OPT_DEBUG){PrintS("nonzero s shrinks to 0");PrintLn();}
+#endif
+         //         strat->P.Delete();  // cause error
+         strat->P.p = NULL;
+         strat->P.t_p = NULL;
+           //         strat->P.p = NULL; // or delete strat->P.p ?
+         goto     red_shrink2zero;
+       }
+    }
+      /* end shrinking poly AGAIN in the nonhomog case */
+
+
+      // enter into S, L, and T
+      //if ((!TEST_OPT_IDLIFT) || (pGetComp(strat->P.p) <= strat->syzComp))
+      //        enterT(strat->P, strat); // this was here before Shift stuff
+      //enterTShift(LObject p, kStrategy strat, int atT, int uptodeg, int lV); // syntax
+      // the default value for atT = -1 as in bba
+      /*   strat->P.GetP(); */
+      // because shifts are counted with .p structure // done before, but ?
+      enterTShift(strat->P,strat,-1,uptodeg, lV);
+      enterpairsShift(strat->P.p,strat->sl,strat->P.ecart,pos,strat, strat->tl,uptodeg,lV);
+      //      enterpairsShift(vw,strat->sl,strat->P.ecart,pos,strat, strat->tl,uptodeg,lV);
+      // posInS only depends on the leading term
+      strat->enterS(strat->P, pos, strat, strat->tl);
+
+      if (hilb!=NULL) khCheck(Q,w,hilb,hilbeledeg,hilbcount,strat);
+//      Print("[%d]",hilbeledeg);
+      if (strat->P.lcm!=NULL) pLmFree(strat->P.lcm);
+    }
+    else
+    {
+    red_shrink2zero:
+      if (strat->P.p1 == NULL && strat->minim > 0)
+      {
+        p_Delete(&strat->P.p2, currRing, strat->tailRing);
+      }
+    }
+#ifdef KDEBUG
+    memset(&(strat->P), 0, sizeof(strat->P));
+#endif
+    kTest_TS(strat);
+  }
+#ifdef KDEBUG
+  if (TEST_OPT_DEBUG) messageSets(strat);
+#endif
+  /* complete reduction of the standard basis--------- */
+  /*  shift case: look for elt's in S such that they are divisible by elt in T */
+  //  if (TEST_OPT_SB_1)
+  if (TEST_OPT_REDSB)
+  {
+    int k=0;
+    int j=-1;
+    while(k<=strat->sl)
+    {
+//       loop
+//       {
+//         if (j>=k) break;
+//         clearS(strat->S[j],strat->sevS[j],&k,&j,strat);
+//         j++;
+//       }
+      LObject Ln (strat->S[k],currRing, strat->tailRing);
+      Ln.SetShortExpVector();
+      j = kFindDivisibleByInT(strat->T, strat->sevT, strat->tl, &Ln, j+1);
+      if (j<0) {  k++; j=-1;}
+      else
+      {
+        if ( pLmCmp(strat->S[k],strat->T[j].p) == 0)
+        {
+          j = kFindDivisibleByInT(strat->T, strat->sevT, strat->tl, &Ln, j+1);
+          if (j<0) {  k++; j=-1;}
+          else
+          {
+            deleteInS(k,strat);
+          }
+        }
+        else
+        {
+          deleteInS(k,strat);
+        }
+      }
+    }
+  }
+
+  if (TEST_OPT_REDSB)
+  {    completeReduce(strat, TRUE); //shift: withT = TRUE
+    if (strat->completeReduce_retry)
+    {
+      // completeReduce needed larger exponents, retry
+      // to reduce with S (instead of T)
+      // and in currRing (instead of strat->tailRing)
+      cleanT(strat);strat->tailRing=currRing;
+      int i;
+      for(i=strat->sl;i>=0;i--) strat->S_2_R[i]=-1;
+      completeReduce(strat, TRUE);
+    }
+  }
+  else if (TEST_OPT_PROT) PrintLn();
+
+  /* release temp data-------------------------------- */
+  exitBuchMora(strat);
+//  if (TEST_OPT_WEIGHTM)
+//  {
+//    pRestoreDegProcs(currRing,pFDegOld, pLDegOld);
+//    if (ecartWeights)
+//    {
+//      omFreeSize((ADDRESS)ecartWeights,((currRing->N)+1)*sizeof(short));
+//      ecartWeights=NULL;
+//    }
+//  }
+  if (TEST_OPT_PROT) messageStat(hilbcount,strat);
+  if (Q!=NULL) updateResult(strat->Shdl,Q,strat);
+  return (strat->Shdl);
+}
+
+
+ideal freegb(ideal I, int uptodeg, int lVblock)
+{
+  /* todo main call */
+
+  /* assume: ring is prepared, ideal is copied into shifted ring */
+  /* uptodeg and lVblock are correct - test them! */
+
+  /* check whether the ideal is in V */
+
+//  if (0)
+  if (! ideal_isInV(I,lVblock) )
+  {
+    WerrorS("The input ideal contains incorrectly encoded elements! ");
+    return(NULL);
+  }
+
+  //  kStrategy strat = new skStrategy;
+  /* ideal bbaShift(ideal F, ideal Q,intvec *w,intvec *hilb,kStrategy strat, int uptodeg, int lV) */
+  /* at the moment:
+- no quotient (check)
+- no *w, no *hilb
+  */
+  /* ideal F, ideal Q, tHomog h,intvec ** w, intvec *hilb,int syzComp,
+     int newIdeal, intvec *vw) */
+  ideal RS = kStdShift(I,NULL, testHomog, NULL,NULL,0,0,NULL, uptodeg, lVblock);
+    //bbaShift(I,NULL, NULL, NULL, strat, uptodeg, lVblock);
+  idSkipZeroes(RS);
+  return(RS);
+}
+
+/*2
+*reduces h with elements from T choosing  the first possible
+* element in t with respect to the given pDivisibleBy
+*/
+int redFirstShift (LObject* h,kStrategy strat)
+{
+  if (h->IsNull()) return 0;
+
+  int at, reddeg,d;
+  int pass = 0;
+  int j = 0;
+
+  if (! strat->homog)
+  {
+    d = h->GetpFDeg() + h->ecart;
+    reddeg = strat->LazyDegree+d;
+  }
+  h->SetShortExpVector();
+  loop
+  {
+    j = kFindDivisibleByInT(strat->T, strat->sevT, strat->tl, h);
+    if (j < 0)
+    {
+      h->SetDegStuffReturnLDeg(strat->LDegLast);
+      return 1;
+    }
+
+    if (!TEST_OPT_INTSTRATEGY)
+      strat->T[j].pNorm();
+#ifdef KDEBUG
+    if (TEST_OPT_DEBUG)
+    {
+      PrintS("reduce ");
+      h->wrp();
+      PrintS(" with ");
+      strat->T[j].wrp();
+    }
+#endif
+    ksReducePoly(h, &(strat->T[j]), strat->kNoetherTail(), NULL, strat);
+    if (!h->IsNull())
+    {
+      poly qq=p_Shrink(h->GetTP(),strat->lV,strat->tailRing);
+      h->p=NULL;
+      h->t_p=qq;
+      if (qq!=NULL) h->GetP(strat->lmBin);
+    }
+
+#ifdef KDEBUG
+    if (TEST_OPT_DEBUG)
+    {
+      PrintS(" to ");
+      wrp(h->p);
+      PrintLn();
+    }
+#endif
+    if (h->IsNull())
+    {
+      if (h->lcm!=NULL) pLmFree(h->lcm);
+      h->Clear();
+      return 0;
+    }
+    h->SetShortExpVector();
+
+#if 0
+    if ((strat->syzComp!=0) && !strat->honey)
+    {
+      if ((strat->syzComp>0) &&
+          (h->Comp() > strat->syzComp))
+      {
+        assume(h->MinComp() > strat->syzComp);
+#ifdef KDEBUG
+        if (TEST_OPT_DEBUG) PrintS(" > syzComp\n");
+#endif
+        if (strat->homog)
+          h->SetDegStuffReturnLDeg(strat->LDegLast);
+        return -2;
+      }
+    }
+#endif
+    if (!strat->homog)
+    {
+      if (!TEST_OPT_OLDSTD && strat->honey)
+      {
+        h->SetpFDeg();
+        if (strat->T[j].ecart <= h->ecart)
+          h->ecart = d - h->GetpFDeg();
+        else
+          h->ecart = d - h->GetpFDeg() + strat->T[j].ecart - h->ecart;
+
+        d = h->GetpFDeg() + h->ecart;
+      }
+      else
+        d = h->SetDegStuffReturnLDeg(strat->LDegLast);
+      /*- try to reduce the s-polynomial -*/
+      pass++;
+      /*
+       *test whether the polynomial should go to the lazyset L
+       *-if the degree jumps
+       *-if the number of pre-defined reductions jumps
+       */
+      if (!TEST_OPT_REDTHROUGH && (strat->Ll >= 0)
+          && ((d >= reddeg) || (pass > strat->LazyPass)))
+      {
+        h->SetLmCurrRing();
+        if (strat->posInLDependsOnLength)
+          h->SetLength(strat->length_pLength);
+        at = strat->posInL(strat->L,strat->Ll,h,strat);
+        if (at <= strat->Ll)
+        {
+          int dummy=strat->sl;
+          /*          if (kFindDivisibleByInS(strat,&dummy, h) < 0) */
+          if (kFindDivisibleByInT(strat->T,strat->sevT, dummy, h) < 0)
+            return 1;
+          enterL(&strat->L,&strat->Ll,&strat->Lmax,*h,at);
+#ifdef KDEBUG
+          if (TEST_OPT_DEBUG) Print(" degree jumped; ->L%d\n",at);
+#endif
+          h->Clear();
+          return -1;
+        }
+      }
+      if ((TEST_OPT_PROT) && (strat->Ll < 0) && (d >= reddeg))
+      {
+        reddeg = d+1;
+        Print(".%d",d);mflush();
+      }
+    }
+  }
+}
+
+void initBbaShift(ideal /*F*/,kStrategy strat)
+{
+ /* setting global variables ------------------- */
+  strat->enterS = enterSBba; /* remains as is, we change enterT! */
+
+  strat->red = redFirstShift; /* no redHomog ! */
+
+  if (currRing->pLexOrder && strat->honey)
+    strat->initEcart = initEcartNormal;
+  else
+    strat->initEcart = initEcartBBA;
+  if (strat->honey)
+    strat->initEcartPair = initEcartPairMora;
+  else
+    strat->initEcartPair = initEcartPairBba;
+//  if ((TEST_OPT_WEIGHTM)&&(F!=NULL))
+//  {
+//    //interred  machen   Aenderung
+//    pFDegOld=currRing->pFDeg;
+//    pLDegOld=pLDeg;
+//    //h=ggetid("ecart");
+//    //if ((h!=NULL) /*&& (IDTYP(h)==INTVEC_CMD)*/)
+//    //{
+//    //  ecartWeights=iv2array(IDINTVEC(h));
+//    //}
+//    //else
+//    {
+//      ecartWeights=(short *)omAlloc(((currRing->N)+1)*sizeof(short));
+//      /*uses automatic computation of the ecartWeights to set them*/
+//      kEcartWeights(F->m,IDELEMS(F)-1,ecartWeights,currRing);
+//    }
+//    pRestoreDegProcs(currRing,totaldegreeWecart, maxdegreeWecart);
+//    if (TEST_OPT_PROT)
+//    {
+//      for(int i=1; i<=rVar(currRing); i++)
+//        Print(" %d",ecartWeights[i]);
+//      PrintLn();
+//      mflush();
+//    }
+//  }
+}
+#endif
diff --git a/kernel/GBEngine/kstdfac.cc b/kernel/GBEngine/kstdfac.cc
new file mode 100644
index 0000000..8459334
--- /dev/null
+++ b/kernel/GBEngine/kstdfac.cc
@@ -0,0 +1,1033 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+*  ABSTRACT -  Kernel: factorizing alg. of Buchberger
+*/
+
+
+
+
+#include <kernel/mod2.h>
+#include <omalloc/omalloc.h>
+#include <misc/options.h>
+#include <kernel/polys.h>
+#include <kernel/ideals.h>
+#include <kernel/GBEngine/kutil.h>
+#include <kernel/GBEngine/kstd1.h>
+#include <kernel/GBEngine/khstd.h>
+//#include "cntrlc.h"
+#include <polys/weight.h>
+//#include "ipshell.h"
+#include <misc/intvec.h>
+#include <polys/clapsing.h>
+#include <kernel/ideals.h>
+#include <kernel/GBEngine/kstdfac.h>
+
+#ifndef SING_NDEBUG
+int strat_nr=0;
+int strat_fac_debug=0;
+#endif
+/*3
+* copy o->T to n->T, assumes that n->S is already copied
+*/
+static void copyT (kStrategy o,kStrategy n)
+{
+  int i,j;
+  poly  p;
+  TSet t=(TSet)omAlloc0(o->tmax*sizeof(TObject));
+  TObject** r = (TObject**)omAlloc0(o->tmax*sizeof(TObject*));
+
+  for (j=0; j<=o->tl; j++)
+  {
+    t[j] = o->T[j];
+    r[t[j].i_r] = &t[j];
+    p = o->T[j].p;
+    i = -1;
+    loop
+    {
+      i++;
+      if (i>o->sl)
+      {
+        t[j].p=pCopy(p);
+        break;
+      }
+      if (p == o->S[i])
+      {
+        t[j].p=n->S[i];
+        break;
+      }
+    }
+    t[j].t_p = NULL; // ?? or t[j].p ??
+    t[j].max = NULL; // ?? or p_GetMaxExpP(t[j].t_p,o->tailRing); ??
+    t[j].pLength =  pLength(p);
+  }
+  n->T=t;
+  n->R=r;
+}
+
+/*3
+* copy o->L to n->L, assumes that n->T,n->tail is already copied
+*/
+static void copyL (kStrategy o,kStrategy n)
+{
+  int i,j;
+  poly  p;
+  LSet l=(LSet)omAlloc(o->Lmax*sizeof(LObject));
+
+  for (j=0; j<=o->Ll; j++)
+  {
+    l[j] = o->L[j];
+    // copy .p ----------------------------------------------
+    if (pNext(o->L[j].p)!=o->tail)
+      l[j].p=pCopy(o->L[j].p);
+    else
+    {
+      l[j].p=pHead(o->L[j].p);
+      pNext(l[j].p)=n->tail;
+    }
+    // copy .lcm ----------------------------------------------
+    if (o->L[j].lcm!=NULL)
+      l[j].lcm=pLmInit(o->L[j].lcm);
+    else
+      l[j].lcm=NULL;
+    l[j].p1=NULL;
+    l[j].p2=NULL;
+    l[j].t_p = NULL;
+
+    // copy .p1 , i_r1----------------------------------------------
+    p = o->L[j].p1;
+    i = -1;
+    loop
+    {
+      if(p==NULL) break;
+      i++;
+      if(i>o->tl)
+      {
+        Warn("poly p1 not found in T:");wrp(p);PrintLn();
+        l[j].p1=pCopy(p);
+        l[j].i_r1=-1;
+        break;
+      }
+      if (p == o->T[i].p)
+      {
+        l[j].p1=n->T[i].p;
+        l[j].i_r1=n->T[i].i_r;
+        break;
+      }
+    }
+
+    // copy .p2 , i_r2----------------------------------------------
+    p = o->L[j].p2;
+    i = -1;
+    loop
+    {
+      if(p==NULL) break;
+      i++;
+      if(i>o->tl)
+      {
+        Warn("poly p2 not found in T:");wrp(p);PrintLn();
+        l[j].p2=pCopy(p);
+        l[j].i_r2=-1;
+        break;
+      }
+      if (p == o->T[i].p)
+      {
+        l[j].p2=n->T[i].p;
+        l[j].i_r2=n->T[i].i_r;
+        break;
+      }
+    }
+
+    // copy .ecart ---------------------------------------------
+    l[j].ecart=o->L[j].ecart;
+    // copy .length --------------------------------------------
+    l[j].length=o->L[j].length;
+    // copy .pLength -------------------------------------------
+    l[j].pLength=o->L[j].pLength;
+    // copy .sev -----------------------------------------------
+    l[j].sev=o->L[j].sev;
+    l[j].i_r = o->L[j].i_r;
+    //l[j].i_r1 = o->L[j].i_r1;
+    //l[j].i_r2 = o->L[j].i_r2;
+  }
+  n->L=l;
+}
+
+kStrategy kStratCopy(kStrategy o)
+{
+  // int i;
+  kTest_TS(o);
+  kStrategy s=new skStrategy;
+  s->next=NULL;
+  s->red=o->red;
+  s->initEcart=o->initEcart;
+  s->posInT=o->posInT;
+  s->posInL=o->posInL;
+  s->enterS=o->enterS;
+  s->initEcartPair=o->initEcartPair;
+  s->posInLOld=o->posInLOld;
+  s->enterOnePair=o->enterOnePair;
+  s->chainCrit=o->chainCrit;
+  s->Shdl=idCopy(o->Shdl);
+  s->S=s->Shdl->m;
+  s->tailRing = o->tailRing;
+  if (o->D!=NULL) s->D=idCopy(o->D);
+  else            s->D=NULL;
+  s->ecartS=(int *)omAlloc(IDELEMS(o->Shdl)*sizeof(int));
+  memcpy(s->ecartS,o->ecartS,IDELEMS(o->Shdl)*sizeof(int));
+  s->sevS=(unsigned long *)omAlloc(IDELEMS(o->Shdl)*sizeof(unsigned long));
+  memcpy(s->sevS,o->sevS,IDELEMS(o->Shdl)*sizeof(unsigned long));
+  s->S_2_R=(int*)omAlloc(IDELEMS(o->Shdl)*sizeof(int));
+  memcpy(s->S_2_R,o->S_2_R,IDELEMS(o->Shdl)*sizeof(int));
+  s->sevT=(unsigned long *)omAlloc(o->tmax*sizeof(unsigned long));
+  memcpy(s->sevT,o->sevT,o->tmax*sizeof(unsigned long));
+  if(o->fromQ!=NULL)
+  {
+    s->fromQ=(int *)omAlloc(IDELEMS(o->Shdl)*sizeof(int));
+    memcpy(s->fromQ,o->fromQ,IDELEMS(o->Shdl)*sizeof(int));
+  }
+  else
+    s->fromQ=NULL;
+  copyT(o,s);//s->T=...
+  s->tail = pInit();
+  copyL(o,s);//s->L=...
+  s->B=initL();
+  s->kHEdge=pCopy(o->kHEdge);
+  s->kNoether=pCopy(o->kNoether);
+  if (o->NotUsedAxis!=NULL)
+  {
+    s->NotUsedAxis=(BOOLEAN *)omAlloc(currRing->N*sizeof(BOOLEAN));
+    memcpy(s->NotUsedAxis,o->NotUsedAxis,currRing->N*sizeof(BOOLEAN));
+  }
+  //s->P=s->L[s->Ll+1];
+  s->P.Init(o->tailRing);
+  s->update=o->update;
+  s->posInLOldFlag=o->posInLOldFlag;
+  s->kModW = o->kModW;
+//   if (o->kModW!=NULL)
+//     s->kModW=ivCopy(o->kModW);
+//   else
+//     s->kModW=NULL;
+  s->pairtest=NULL;
+  s->sl=o->sl;
+  s->mu=o->mu;
+  s->tl=o->tl;
+  s->tmax=o->tmax;
+  s->Ll=o->Ll;
+  s->Lmax=o->Lmax;
+  s->Bl=-1;
+  s->Bmax=setmaxL;
+  s->ak=o->ak;
+  s->syzComp=o->syzComp;
+  s->LazyPass=o->LazyPass;
+  s->LazyDegree=o->LazyDegree;
+  s->HCord=o->HCord;
+  s->lastAxis=o->lastAxis;
+  s->interpt=o->interpt;
+  s->homog=o->homog;
+  s->news=o->news;
+  s->newt=o->newt;
+  s->kHEdgeFound=o->kHEdgeFound;
+  s->honey=o->honey;
+  s->sugarCrit=o->sugarCrit;
+  s->Gebauer=o->Gebauer;
+  s->noTailReduction=o->noTailReduction;
+  s->fromT=o->fromT;
+  s->noetherSet=o->noetherSet;
+#ifdef HAVE_SHIFTBBA
+  s->lV=o->lV;
+#endif
+#ifdef HAVE_PLURAL
+  s->no_prod_crit=o->no_prod_crit;
+#endif
+  kTest_TS(s);
+  return s;
+}
+
+BOOLEAN k_factorize(poly p,ideal &rfac, ideal &fac_copy)
+{
+  int facdeg=currRing->pFDeg(p,currRing);
+  ideal fac=singclap_factorize(pCopy(p),NULL,1,currRing);
+  int fac_elems;
+  fac_elems=IDELEMS(fac);
+  rfac=fac;
+  fac_copy=idInit(fac_elems,1);
+
+  if ((fac_elems!=1)||(facdeg!=currRing->pFDeg(fac->m[0],currRing)))
+  {
+    if (TEST_OPT_DEBUG)
+    {
+      Print("-> %d factors\n",fac_elems);
+      if (fac_elems!=1)
+      {
+        pWrite(p); PrintS(" ->\n");
+        int ii=fac_elems;
+        while(ii>0) { ii--;pWrite(fac->m[ii]); }
+      }
+    }
+    else if (TEST_OPT_PROT)
+    {
+      int ii=fac_elems;
+      if (ii>1)
+      {
+        while(ii>0) { PrintS("F"); ii--; }
+      }
+    }
+#ifndef SING_NDEBUG
+    else if (strat_fac_debug)
+    {
+      pWrite(p);
+      Print("-> %d factors\n",fac_elems);
+      if (fac_elems!=1)
+      {
+        int ii=fac_elems;
+        while(ii>0) { ii--;pWrite(fac->m[ii]); }
+      }
+    }
+#endif
+    return TRUE;
+  }
+  else
+  {
+    pDelete(&(fac->m[0]));
+    fac->m[0]=pCopy(p);
+  }
+  return FALSE;
+}
+
+static void completeReduceFac (kStrategy strat, ideal_list FL)
+{
+  int si;
+
+  strat->noTailReduction = FALSE;
+  if (TEST_OPT_PROT)
+  {
+    PrintLn();
+//    if (timerv) writeTime("standard base computed:");
+  }
+  if (TEST_OPT_PROT)
+  {
+    Print("(S:%d)",strat->sl);mflush();
+  }
+  for (si=strat->sl; si>0; si--)
+  {
+    strat->S[si] = redtailBba(strat->S[si],si-1,strat);
+    if (TEST_OPT_INTSTRATEGY)
+    {
+      strat->S[si]=p_Cleardenom(strat->S[si], currRing);
+    }
+    if (TEST_OPT_PROT)
+    {
+      PrintS("-");mflush();
+    }
+    int i;
+    if (strat->redTailChange)
+    {
+      for(i=strat->tl;i>=0;i--)
+      {
+        strat->initEcart(&strat->T[i]);
+      }
+    }
+    ideal fac;
+    ideal fac_copy;
+
+    if (!k_factorize(strat->S[si],fac,fac_copy))
+    {
+      idDelete(&fac);
+      idDelete(&fac_copy);
+      continue;
+    }
+
+    deleteInS(si,strat);
+
+    for(i=IDELEMS(fac)-1;i>=0;i--)
+    {
+      kStrategy n=strat;
+      if (i>=1)
+      {
+        n=kStratCopy(strat); // includes: memset(&n->P,0,sizeof(n->P));
+        n->next=strat->next;
+        strat->next=n;
+      }
+      else
+      {
+        n->P.Init(strat->tailRing);
+      }
+
+      n->P.p=fac->m[i];
+      n->P.pLength=0;
+      n->initEcart(&n->P);
+      /* enter P.p into s and L */
+      int pos;
+      if (n->sl==-1) pos=0;
+      else pos=posInS(n,n->sl,n->P.p,n->P.ecart);
+      if (TEST_OPT_INTSTRATEGY)
+      {
+        n->P.p = redtailBba(n->P.p,pos-1,n);
+        n->P.pCleardenom();
+      }
+      else
+      {
+        pNorm(n->P.p);
+        n->P.p = redtailBba(n->P.p,pos-1,n);
+      }
+      n->P.pLength=0;
+      if (TEST_OPT_DEBUG)
+      {
+        PrintS("new s:");
+        wrp(n->P.p);
+        PrintLn();
+      }
+      enterpairs(n->P.p,n->sl,n->P.ecart,pos,n);
+      enterT(n->P,n);
+      n->enterS(n->P,pos,n, n->tl);
+
+      /* construct D */
+      if (IDELEMS(fac)>1)
+      {
+        if (n->D==NULL)
+        {
+          n->D=idCopy(fac_copy);
+          idSkipZeroes(n->D);
+        }
+        else
+        {
+          idTest(n->D);
+          ideal r=idAdd(n->D,fac_copy);
+          idDelete(&n->D);
+          n->D=r;
+        }
+        if (TEST_OPT_DEBUG)
+        {
+          PrintS("new D:\n");
+          iiWriteMatrix((matrix)n->D,"D",1,currRing,0);
+          PrintLn();
+        }
+      }
+#ifndef SING_NDEBUG
+      if(strat_fac_debug)
+      {
+        int ii;
+        Print("---------------------------------------------------------------\ns(%d), set S\n",n->nr);
+        for(ii=0;ii<n->sl;ii++)
+        { Print("s(%d->S[%d]= ",n->nr,ii);pWrite(n->S[ii]);}
+        Print("s(%d), set D\n",n->nr);
+        if (n->D!=NULL)
+        {
+          for(ii=0;ii<IDELEMS(n->D);ii++)
+          { Print("s(%d->D[%d]= ",n->nr,ii);pWrite(n->D->m[ii]);}
+        }
+        else PrintS(" empty\n");
+      }
+#endif
+
+      fac_copy->m[i]=pCopy(fac->m[i]);
+      fac->m[i]=NULL;
+
+      /* check for empty sets */
+      if (n->D!=NULL)
+      {
+        int j=IDELEMS(n->D)-1;
+        while(j>=0)
+        {
+          if (n->D->m[j]!=NULL)
+          {
+            poly r=kNF(n->Shdl,NULL,n->D->m[j],0,KSTD_NF_LAZY | KSTD_NF_NONORM);
+            if (r==NULL)
+            {
+#ifndef SING_NDEBUG
+              if(strat_fac_debug)
+              {
+                Print("empty set s(%d) because: D[%d] -> 0\n",
+                       n->nr, j);
+                Print("s(%d)->D[%d]= ",n->nr,j);pWrite(n->D->m[j]);
+              }
+#endif
+              if (TEST_OPT_DEBUG)
+              {
+                PrintS("empty set because:");
+                wrp(n->D->m[j]);
+                PrintLn();
+                messageSets(n);
+              }
+              while (n->Ll >= 0) deleteInL(n->L,&n->Ll,n->Ll,n);
+              while (n->tl >= 0)
+              {
+                int i=n->sl;
+                while (i>=0)
+                {
+                  if (n->S[i]==n->T[n->tl].p)
+                  {
+                    n->T[n->tl].p=NULL; n->S[i]=NULL;
+                    break;
+                  }
+                  i--;
+                }
+                pDelete(&n->T[n->tl].p);
+                n->tl--;
+              }
+              memset(n->Shdl->m,0,IDELEMS(n->Shdl)*sizeof(poly));
+              n->sl=-1;
+              if (strat==n) si=-1;
+              break;
+            }
+            else
+            {
+              pDelete(&r);
+            }
+          }
+          j--;
+        }
+      }
+      /* check for empty sets */
+      {
+        ideal_list Lj=FL;
+        while (Lj!=NULL)
+        {
+          if ((n->sl>=0)&&(n->S[0]!=NULL))
+          {
+            ideal r=kNF(n->Shdl,NULL,Lj->d,0,KSTD_NF_LAZY | KSTD_NF_NONORM);
+#ifndef SING_NDEBUG
+              if(strat_fac_debug)
+              {
+                Print("empty set s(%d) because:L[%d]\n",n->nr,Lj->nr);
+                PrintS("L:\n");
+                iiWriteMatrix((matrix)Lj->d,"L",1,currRing,0);
+              }
+#endif
+            if (idIs0(r))
+            {
+              if (TEST_OPT_DEBUG)
+              {
+                Print("empty set because:L[%p]\n",(void *)Lj);
+              }
+              while (n->Ll >= 0) deleteInL(n->L,&n->Ll,n->Ll,n);
+              while (n->tl >= 0)
+              {
+                int i=n->sl;
+                while (i>=0)
+                {
+                  if (n->S[i]==n->T[n->tl].p)
+                  {
+                    n->T[n->tl].p=NULL; n->S[i]=NULL;
+                    break;
+                  }
+                  i--;
+                }
+                pDelete(&n->T[n->tl].p);
+                n->tl--;
+              }
+              memset(n->Shdl->m,0,IDELEMS(n->Shdl)*sizeof(poly));
+              n->sl=-1;
+              if (strat==n) si=-1;
+              idDelete(&r);
+              break;
+            }
+            idDelete(&r);
+          }
+          Lj=Lj->next;
+        }
+      }
+    } /* for */
+    for(i=0;i<IDELEMS(fac);i++) fac->m[i]=NULL;
+    idDelete(&fac);
+    idDelete(&fac_copy);
+    if ((strat->Ll>=0) && (strat->sl>=0)) break;
+    else si=strat->sl+1;
+  }
+}
+
+ideal bbafac (ideal /*F*/, ideal Q,intvec */*w*/,kStrategy strat, ideal_list FL)
+{
+  int   olddeg,reduc=0;
+  int red_result = 1;
+  reduc = olddeg = 0;
+  /* compute------------------------------------------------------- */
+  if ((strat->Ll==-1) && (strat->sl>=0))
+  {
+    if (TEST_OPT_REDSB) completeReduceFac(strat,FL);
+  }
+  kTest_TS(strat);
+  while (strat->Ll >= 0)
+  {
+    if (TEST_OPT_DEBUG) messageSets(strat);
+    if (strat->Ll== 0) strat->interpt=TRUE;
+    if (TEST_OPT_DEGBOUND
+    && ((strat->honey
+        && (strat->L[strat->Ll].ecart+currRing->pFDeg(strat->L[strat->Ll].p,currRing)>Kstd1_deg))
+      || ((!strat->honey) && (currRing->pFDeg(strat->L[strat->Ll].p,currRing)>Kstd1_deg))))
+    {
+      /*
+      *stops computation if
+      * 24 IN test and the degree +ecart of L[strat->Ll] is bigger then
+      *a predefined number Kstd1_deg
+      */
+      while (strat->Ll >= 0) deleteInL(strat->L,&strat->Ll,strat->Ll,strat);
+      break;
+    }
+    /* picks the last element from the lazyset L */
+    strat->P = strat->L[strat->Ll];
+    strat->Ll--;
+    if (pNext(strat->P.p) == strat->tail)
+    {
+      /* deletes the short spoly and computes */
+      pLmFree(strat->P.p);
+      /* the real one */
+      strat->P.p = ksOldCreateSpoly(strat->P.p1,
+                                    strat->P.p2,
+                                    strat->kNoether);
+    }
+    if (strat->honey)
+    {
+      if (TEST_OPT_PROT)
+        message(strat->P.ecart+currRing->pFDeg(strat->P.p,currRing),&olddeg,&reduc,strat, red_result);
+    }
+    else
+    {
+      if (TEST_OPT_PROT)
+        message(currRing->pFDeg(strat->P.p,currRing),&olddeg,&reduc,strat, red_result);
+    }
+    /* reduction of the element choosen from L */
+    kTest_TS(strat);
+    red_result = strat->red(&strat->P,strat);
+    if (strat->P.p != NULL)
+    {
+      /* statistic */
+      if (TEST_OPT_PROT) PrintS("s");
+      ideal fac;
+      ideal fac_copy;
+
+      if (!k_factorize(strat->P.p,fac,fac_copy))
+      {
+        if (TEST_OPT_INTSTRATEGY)
+        {
+          strat->P.p = redtailBba(strat->P.p,strat->sl,strat);
+          if (strat->redTailChange) strat->P.pCleardenom();
+        }
+        else
+        {
+          pNorm(strat->P.p);
+          strat->P.p = redtailBba(strat->P.p,strat->sl,strat);
+        }
+        if (strat->redTailChange)
+        {
+          idDelete(&fac);
+          idDelete(&fac_copy);
+          if (!k_factorize(strat->P.p,fac,fac_copy))
+          {
+            pDelete(&(fac->m[0]));
+            fac->m[0]=strat->P.p;
+            strat->P.p=NULL;
+          }
+          else
+          {
+            pDelete(&strat->P.p);
+          }
+        }
+      }
+      if (strat->P.lcm!=NULL) pLmFree(strat->P.lcm);
+      int i;
+
+      for(i=IDELEMS(fac)-1;i>=0;i--)
+      {
+        int ii;
+        kStrategy n=strat;
+        if (i>=1)
+        {
+          n=kStratCopy(strat); // includes memset(&n->P,0,sizeof(n->P));
+          kTest_TS(n);
+          n->next=strat->next;
+          strat->next=n;
+        }
+        else
+        {
+          n->P.Init(strat->tailRing);
+        }
+
+        n->P.pLength=0;
+        n->P.p=fac->m[i];
+        n->initEcart(&n->P);
+        kTest_TS(n);
+
+        /* enter P.p into s and L */
+        int pos;
+        if (n->sl==-1) pos=0;
+        else pos=posInS(n,n->sl,n->P.p,n->P.ecart);
+
+        // we have already reduced all elements from fac....
+        if (TEST_OPT_INTSTRATEGY)
+        {
+          n->P.p = redtailBba(n->P.p,pos-1,n);
+          if (n->redTailChange)
+          {
+            n->P.pCleardenom();
+            n->P.pLength=0;
+          }
+        }
+        else
+        {
+          pNorm(n->P.p);
+          n->P.p = redtailBba(n->P.p,pos-1,n);
+          if (n->redTailChange)
+          {
+            n->P.pLength=0;
+          }
+        }
+        kTest_TS(n);
+
+        if (TEST_OPT_DEBUG)
+        {
+          PrintS("new s:");
+          wrp(n->P.p);
+          PrintLn();
+        }
+        enterpairs(n->P.p,n->sl,n->P.ecart,pos,n);
+        enterT(n->P,n);
+        n->enterS(n->P,pos,n, n->tl);
+        {
+          int i=n->Ll;
+          for(;i>=0;i--)
+          {
+            n->L[i].i_r1= -1;
+            for(ii=0; ii<=n->tl; ii++)
+            {
+              if (n->R[ii]->p==n->L[i].p1)  { n->L[i].i_r1=ii;break; }
+            }
+            n->L[i].i_r2= -1;
+            for(ii=0; ii<=n->tl; ii++)
+            {
+              if (n->R[ii]->p==n->L[i].p2)  { n->L[i].i_r2=ii;break; }
+            }
+          }
+        }
+        kTest_TS(n);
+        /* construct D */
+        if (IDELEMS(fac)>1)
+        {
+          if (n->D==NULL)
+          {
+            n->D=idCopy(fac_copy);
+            idSkipZeroes(n->D);
+          }
+          else
+          {
+            idTest(n->D);
+            ideal r=idAdd(n->D,fac_copy);
+            idDelete(&n->D);
+            n->D=r;
+          }
+          if (TEST_OPT_DEBUG)
+          {
+            PrintS("new D:\n");
+            iiWriteMatrix((matrix)n->D,"D",1,currRing,0);
+            PrintLn();
+          }
+        }
+#ifndef SING_NDEBUG
+        if(strat_fac_debug)
+        {
+          int ii;
+          Print("-------------------------------------------------------------\ns(%d), set S\n",n->nr);
+          for(ii=0;ii<n->sl;ii++)
+          { Print("s(%d->S[%d]= ",n->nr,ii);pWrite(n->S[ii]);}
+          Print("s(%d), set D\n",n->nr);
+          if (n->D!=NULL)
+          {
+            for(ii=0;ii<IDELEMS(n->D);ii++)
+            { Print("s(%d->D[%d]= ",n->nr,ii);pWrite(n->D->m[ii]);}
+          }
+          else PrintS(" empty\n");
+        }
+#endif
+
+        fac_copy->m[i]=pCopy(fac->m[i]);
+        fac->m[i]=NULL;
+
+        /* check for empty sets */
+        if (n->D!=NULL)
+        {
+          int j=IDELEMS(n->D)-1;
+          while(j>=0)
+          {
+            if (n->D->m[j]!=NULL)
+            {
+              poly r=kNF(n->Shdl,NULL,n->D->m[j],0,KSTD_NF_LAZY | KSTD_NF_NONORM);
+              if (r==NULL)
+              {
+#ifndef SING_NDEBUG
+                if(strat_fac_debug)
+                {
+                  Print("empty set s(%d) because: D[%d] -> 0\n",
+                       n->nr, j);
+                  Print("s(%d)->D[%d]= ",n->nr,j);pWrite(n->D->m[j]);
+                }
+#endif
+                if (TEST_OPT_DEBUG)
+                {
+                  PrintS("empty set because:");
+                  wrp(n->D->m[j]);
+                  PrintLn();
+                  messageSets(n);
+                }
+                //if (n->Ll >=0) Print("Ll:%d|",n->Ll);
+                while (n->Ll >= 0) deleteInL(n->L,&n->Ll,n->Ll,n);
+                //if (n->tl >=0) Print("tl:%d|",n->tl);
+                while (n->tl >= 0)
+                {
+                  int i=n->sl;
+                  while (i>=0)
+                  {
+                    if (n->S[i]==n->T[n->tl].p)
+                    {
+                      n->T[n->tl].p=NULL; n->S[i]=NULL;
+                      break;
+                    }
+                    i--;
+                  }
+                  pDelete(&n->T[n->tl].p);
+                  n->tl--;
+                }
+                memset(n->Shdl->m,0,IDELEMS(n->Shdl)*sizeof(poly));
+                n->sl=-1;
+                break;
+              }
+              else
+              {
+                pDelete(&r);
+              }
+            }
+            j--;
+          }
+        }
+
+        /* check for empty sets */
+        {
+          ideal_list Lj=FL;
+          while (Lj!=NULL)
+          {
+            if ((n->sl>=0)&&(n->S[0]!=NULL))
+            {
+              ideal r=kNF(n->Shdl,NULL,Lj->d,0,KSTD_NF_LAZY | KSTD_NF_NONORM);
+              if (idIs0(r))
+              {
+#ifndef SING_NDEBUG
+                if(strat_fac_debug)
+                {
+                  Print("empty set s(%d) because:L[%d]\n",n->nr,Lj->nr);
+                  PrintS("L:\n");
+                  iiWriteMatrix((matrix)Lj->d,"L",1,currRing,0);
+                }
+#endif
+                if (TEST_OPT_DEBUG)
+                {
+                  Print("empty set because:L[%p]\n",(void*)Lj);
+                }
+                while (n->Ll >= 0) deleteInL(n->L,&n->Ll,n->Ll,n);
+                while (n->tl >= 0)
+                {
+                  int i=n->sl;
+                  while (i>=0)
+                  {
+                    if (n->S[i]==n->T[n->tl].p)
+                    {
+                      n->T[n->tl].p=NULL; n->S[i]=NULL;
+                      break;
+                    }
+                    i--;
+                  }
+                  pDelete(&n->T[n->tl].p);
+                  n->tl--;
+                }
+                memset(n->Shdl->m,0,IDELEMS(n->Shdl)*sizeof(poly));
+                n->sl=-1;
+                idDelete(&r);
+                break;
+              }
+              idDelete(&r);
+            }
+            Lj=Lj->next;
+          }
+        }
+      } /* for */
+      for(i=0;i<IDELEMS(fac);i++) fac->m[i]=NULL;
+      idDelete(&fac);
+      idDelete(&fac_copy);
+    }
+#ifdef KDEBUG
+    strat->P.lcm=NULL;
+#endif
+    kTest_TS(strat);
+    if ((strat->Ll==-1) && (strat->sl>=0))
+    {
+      if (TEST_OPT_REDSB) completeReduceFac(strat,FL);
+    }
+    kTest_TS(strat);
+  }
+  if (TEST_OPT_DEBUG) messageSets(strat);
+  /* complete reduction of the standard basis--------- */
+  /* release temp data-------------------------------- */
+  if (TEST_OPT_WEIGHTM)
+  {
+    pRestoreDegProcs(currRing,strat->pOrigFDeg, strat->pOrigLDeg);
+    if (ecartWeights)
+    {
+      omFreeSize((ADDRESS)ecartWeights,((currRing->N)+1)*sizeof(short));
+      ecartWeights=NULL;
+    }
+  }
+  exitBuchMora(strat);
+  if (TEST_OPT_PROT) { PrintLn(); messageStat(0,strat); }
+  if (Q!=NULL) updateResult(strat->Shdl,Q,strat);
+  return (strat->Shdl);
+}
+
+ideal_list kStdfac(ideal F, ideal Q, tHomog h,intvec ** w,ideal D)
+{
+  ideal r;
+  BOOLEAN b=currRing->pLexOrder,toReset=FALSE;
+  BOOLEAN delete_w=(w==NULL);
+  kStrategy strat=new skStrategy;
+  kStrategy orgstrat=strat;
+  ideal_list L=NULL;
+
+  if (rField_has_simple_inverse(currRing))
+    strat->LazyPass=20;
+  else
+    strat->LazyPass=2;
+  strat->LazyDegree = 1;
+  strat->ak = id_RankFreeModule(F,currRing);
+  if (h==testHomog)
+  {
+    if (strat->ak==0)
+    {
+      h = (tHomog)idHomIdeal(F,Q);
+      w=NULL;
+    }
+    else
+      h = (tHomog)idHomModule(F,Q,w);
+  }
+  if (h==isHomog)
+  {
+    if ((w!=NULL) && (*w!=NULL))
+    {
+      kModW = *w;
+      strat->kModW = *w;
+      strat->pOrigFDeg = currRing->pFDeg;
+      strat->pOrigLDeg = currRing->pLDeg;
+      pSetDegProcs(currRing,kModDeg);
+      toReset = TRUE;
+    }
+    currRing->pLexOrder = TRUE;
+    strat->LazyPass*=2;
+  }
+  strat->homog=h;
+  initBuchMoraCrit(strat); /*set Gebauer, honey, sugarCrit*/
+  initBuchMoraPos(strat);
+  initBba(F,strat);
+  initBuchMora(F, Q,strat);
+  if (D!=NULL)
+  {
+    strat->D=idCopy(D);
+  }
+// Ende der Initalisierung
+  while (strat!=NULL)
+  {
+    if (TEST_OPT_DEBUG)
+      PrintS("====================================\n");
+    if (w!=NULL)
+      r=bbafac(F,Q,*w,strat,L);
+    else
+      r=bbafac(F,Q,NULL,strat,L);
+#ifdef KDEBUG
+    int i;
+    for (i=0; i<IDELEMS(r); i++) pTest(r->m[i]);
+#endif
+    idSkipZeroes(r);
+    // Testausgabe:
+    //if (!idIs0(r))
+    //{
+    //  PrintS("===================================================\n");
+    //  iiWriteMatrix((matrix)r,"S",1,currRing,0);
+    //  PrintS("\n===================================================\n");
+    //}
+    //else
+    //{
+    //  PrintS("=========empty============================\n");
+    //}
+    if(!idIs0(r))
+    {
+      ideal_list LL=(ideal_list)omAlloc(sizeof(*LL));
+      LL->d=r;
+#ifndef SING_NDEBUG
+      LL->nr=strat->nr;
+#endif
+      LL->next=L;
+      L=LL;
+    }
+    strat=strat->next;
+  }
+  /* check for empty sets */
+  if (L!=NULL)
+  {
+    ideal_list Lj=L->next;
+    ideal_list Lj_prev=L;
+    while (Lj!=NULL)
+    {
+      ideal_list Li=L;
+      while(Li!=Lj)
+      {
+        ideal r=kNF(Lj->d,NULL,Li->d,0,KSTD_NF_LAZY | KSTD_NF_NONORM);
+        if (idIs0(r))
+        {
+#ifndef SING_NDEBUG
+          if(strat_fac_debug)
+          {
+            Print("empty set L(%d) because:L(%d)\n",Lj->nr,Li->nr);
+          }
+#endif
+          if (TEST_OPT_DEBUG)
+          {
+            Print("empty set L[%p] because:L[%p]\n",(void*)Lj,(void*)Li);
+          }
+          // delete L[j],
+          Li=L;
+          if (Lj_prev!=NULL)
+          {
+            Lj=Lj_prev;
+            if (Lj==L) Lj_prev=NULL;
+            else
+            {
+              Lj_prev=L;
+              while(Lj_prev->next!=Lj) Lj_prev=Lj_prev->next;
+            }
+          }
+          else Lj=NULL;
+        }
+        else
+        {
+          Li=Li->next;
+        }
+        idDelete (&r);
+      }
+      if (Lj!=NULL) Lj=Lj->next;
+    }
+  }
+// Ende: aufraeumen
+  if (toReset)
+  {
+    pRestoreDegProcs(currRing,strat->pOrigFDeg, strat->pOrigLDeg);
+    kModW = NULL;
+  }
+  currRing->pLexOrder = b;
+  delete(strat);
+  strat=orgstrat;
+  while (strat!=NULL)
+  {
+    orgstrat=strat->next;
+    delete(strat);
+    strat=orgstrat;
+  }
+  if ((delete_w)&&(w!=NULL)&&(*w!=NULL)) delete *w;
+  return L;
+}
diff --git a/kernel/GBEngine/kstdfac.h b/kernel/GBEngine/kstdfac.h
new file mode 100644
index 0000000..d51cf84
--- /dev/null
+++ b/kernel/GBEngine/kstdfac.h
@@ -0,0 +1,14 @@
+#ifndef KSTDFAC_H
+#define KSTDFAC_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+*  ABSTRACT -  Kernel: factorizing alg. of Buchberger
+*/
+#include <kernel/structs.h>
+#include <polys/simpleideals.h>
+
+ideal_list kStdfac(ideal F, ideal Q, tHomog h,intvec ** w, ideal D=NULL);
+#endif
+
diff --git a/kernel/GBEngine/kutil.cc b/kernel/GBEngine/kutil.cc
new file mode 100644
index 0000000..2a1c19e
--- /dev/null
+++ b/kernel/GBEngine/kutil.cc
@@ -0,0 +1,9795 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: kernel: utils for kStd
+*/
+
+// #define PDEBUG 2
+// #define PDIV_DEBUG
+#define KUTIL_CC
+
+#define MYTEST 0
+
+#include <kernel/mod2.h>
+
+#include <misc/mylimits.h>
+#include <misc/options.h>
+#include <polys/nc/nc.h>
+#include <polys/nc/sca.h>
+#include <polys/weight.h> /* for kDebugPrint: maxdegreeWecart*/
+
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef KDEBUG
+#undef KDEBUG
+#define KDEBUG 2
+#endif
+
+#ifdef DEBUGF5
+#undef DEBUGF5
+//#define DEBUGF5 1
+#endif
+
+#ifdef HAVE_RINGS
+#include <kernel/ideals.h>
+#endif
+
+// define if enterL, enterT should use memmove instead of doing it manually
+// on topgun, this is slightly faster (see monodromy_l.tst, homog_gonnet.sing)
+#ifndef SunOS_4
+#define ENTER_USE_MEMMOVE
+#endif
+
+// define, if the my_memmove inlines should be used instead of
+// system memmove -- it does not seem to pay off, though
+// #define ENTER_USE_MYMEMMOVE
+
+#include <kernel/GBEngine/kutil.h>
+#include <polys/kbuckets.h>
+#include <omalloc/omalloc.h>
+#include <coeffs/numbers.h>
+#include <kernel/polys.h>
+#include <polys/monomials/ring.h>
+#include <kernel/ideals.h>
+//#include "cntrlc.h"
+#include <kernel/combinatorics/stairc.h>
+#include <kernel/GBEngine/kstd1.h>
+#include <polys/operations/pShallowCopyDelete.h>
+
+/* shiftgb stuff */
+#include <kernel/GBEngine/shiftgb.h>
+#include <polys/prCopy.h>
+
+#ifdef HAVE_RATGRING
+#include <kernel/GBEngine/ratgring.h>
+#endif
+
+#ifdef KDEBUG
+#undef KDEBUG
+#define KDEBUG 2
+#endif
+
+#ifdef DEBUGF5
+#undef DEBUGF5
+#define DEBUGF5 2
+#endif
+
+#define ADIDEBUG 0
+
+denominator_list DENOMINATOR_LIST=NULL;
+
+
+#ifdef ENTER_USE_MYMEMMOVE
+inline void _my_memmove_d_gt_s(unsigned long* d, unsigned long* s, long l)
+{
+  register unsigned long* _dl = (unsigned long*) d;
+  register unsigned long* _sl = (unsigned long*) s;
+  register long _i = l - 1;
+
+  do
+  {
+    _dl[_i] = _sl[_i];
+    _i--;
+  }
+  while (_i >= 0);
+}
+
+inline void _my_memmove_d_lt_s(unsigned long* d, unsigned long* s, long l)
+{
+  register long _ll = l;
+  register unsigned long* _dl = (unsigned long*) d;
+  register unsigned long* _sl = (unsigned long*) s;
+  register long _i = 0;
+
+  do
+  {
+    _dl[_i] = _sl[_i];
+    _i++;
+  }
+  while (_i < _ll);
+}
+
+inline void _my_memmove(void* d, void* s, long l)
+{
+  unsigned long _d = (unsigned long) d;
+  unsigned long _s = (unsigned long) s;
+  unsigned long _l = ((l) + SIZEOF_LONG - 1) >> LOG_SIZEOF_LONG;
+
+  if (_d > _s) _my_memmove_d_gt_s(_d, _s, _l);
+  else _my_memmove_d_lt_s(_d, _s, _l);
+}
+
+#undef memmove
+#define memmove(d,s,l) _my_memmove(d, s, l)
+#endif
+
+static poly redMora (poly h,int maxIndex,kStrategy strat);
+static poly redBba (poly h,int maxIndex,kStrategy strat);
+
+#ifdef HAVE_RINGS
+#define pDivComp_EQUAL 2
+#define pDivComp_LESS 1
+#define pDivComp_GREATER -1
+#define pDivComp_INCOMP 0
+/* Checks the relation of LM(p) and LM(q)
+     LM(p) = LM(q) => return pDivComp_EQUAL
+     LM(p) | LM(q) => return pDivComp_LESS
+     LM(q) | LM(p) => return pDivComp_GREATER
+     else return pDivComp_INCOMP */
+static inline int pDivCompRing(poly p, poly q)
+{
+  if (pGetComp(p) == pGetComp(q))
+  {
+    BOOLEAN a=FALSE, b=FALSE;
+    int i;
+    unsigned long la, lb;
+    unsigned long divmask = currRing->divmask;
+    for (i=0; i<currRing->VarL_Size; i++)
+    {
+      la = p->exp[currRing->VarL_Offset[i]];
+      lb = q->exp[currRing->VarL_Offset[i]];
+      if (la != lb)
+      {
+        if (la < lb)
+        {
+          if (b) return pDivComp_INCOMP;
+          if (((la & divmask) ^ (lb & divmask)) != ((lb - la) & divmask))
+            return pDivComp_INCOMP;
+          a = TRUE;
+        }
+        else
+        {
+          if (a) return pDivComp_INCOMP;
+          if (((la & divmask) ^ (lb & divmask)) != ((la - lb) & divmask))
+            return pDivComp_INCOMP;
+          b = TRUE;
+        }
+      }
+    }
+    if (a) return pDivComp_LESS;
+    if (b) return pDivComp_GREATER;
+    if (!a & !b) return pDivComp_EQUAL;
+  }
+  return pDivComp_INCOMP;
+}
+#endif
+
+static inline int pDivComp(poly p, poly q)
+{
+  if (pGetComp(p) == pGetComp(q))
+  {
+#ifdef HAVE_RATGRING
+    if (rIsRatGRing(currRing))
+    {
+      if (_p_LmDivisibleByPart(p,currRing,
+                           q,currRing,
+                           currRing->real_var_start, currRing->real_var_end))
+        return 0;
+      return pLmCmp(q,p); // ONLY FOR GLOBAL ORDER!
+    }
+#endif
+    BOOLEAN a=FALSE, b=FALSE;
+    int i;
+    unsigned long la, lb;
+    unsigned long divmask = currRing->divmask;
+    for (i=0; i<currRing->VarL_Size; i++)
+    {
+      la = p->exp[currRing->VarL_Offset[i]];
+      lb = q->exp[currRing->VarL_Offset[i]];
+      if (la != lb)
+      {
+        if (la < lb)
+        {
+          if (b) return 0;
+          if (((la & divmask) ^ (lb & divmask)) != ((lb - la) & divmask))
+            return 0;
+          a = TRUE;
+        }
+        else
+        {
+          if (a) return 0;
+          if (((la & divmask) ^ (lb & divmask)) != ((la - lb) & divmask))
+            return 0;
+          b = TRUE;
+        }
+      }
+    }
+    if (a) { /*assume(pLmCmp(q,p)==1);*/ return 1; }
+    if (b) { /*assume(pLmCmp(q,p)==-1);*/return -1; }
+    /*assume(pLmCmp(q,p)==0);*/
+  }
+  return 0;
+}
+
+
+int     HCord;
+int     Kstd1_deg;
+int     Kstd1_mu=32000;
+
+/*2
+*deletes higher monomial of p, re-compute ecart and length
+*works only for orderings with ecart =pFDeg(end)-pFDeg(start)
+*/
+void deleteHC(LObject *L, kStrategy strat, BOOLEAN fromNext)
+{
+  if (strat->kHEdgeFound)
+  {
+    kTest_L(L);
+    poly p1;
+    poly p = L->GetLmTailRing();
+    int l = 1;
+    kBucket_pt bucket = NULL;
+    if (L->bucket != NULL)
+    {
+      kBucketClear(L->bucket, &pNext(p), &L->pLength);
+      L->pLength++;
+      bucket = L->bucket;
+      L->bucket = NULL;
+    }
+
+    if (!fromNext && p_Cmp(p,strat->kNoetherTail(), L->tailRing) == -1)
+    {
+      L->Delete();
+      L->Clear();
+      L->ecart = -1;
+      if (bucket != NULL) kBucketDestroy(&bucket);
+      return;
+    }
+    p1 = p;
+    while (pNext(p1)!=NULL)
+    {
+    if (p_LmCmp(pNext(p1), strat->kNoetherTail(), L->tailRing) == -1)
+      {
+        p_Delete(&pNext(p1), L->tailRing);
+        if (p1 == p)
+        {
+          if (L->t_p != NULL)
+          {
+            assume(L->p != NULL && p == L->t_p);
+            pNext(L->p) = NULL;
+          }
+          L->max  = NULL;
+        }
+        else if (fromNext)
+          L->max  = p_GetMaxExpP(pNext(L->p), L->tailRing ); // p1;
+        //if (L->pLength != 0)
+        L->pLength = l;
+        // Hmmm when called from updateT, then only
+        // reset ecart when cut
+        if (fromNext)
+          L->ecart = L->pLDeg() - L->GetpFDeg();
+        break;
+      }
+      l++;
+      pIter(p1);
+    }
+    if (! fromNext)
+    {
+      L->SetpFDeg();
+      L->ecart = L->pLDeg(strat->LDegLast) - L->GetpFDeg();
+    }
+    if (bucket != NULL)
+    {
+      if (L->pLength > 1)
+      {
+        kBucketInit(bucket, pNext(p), L->pLength - 1);
+        pNext(p) = NULL;
+        if (L->t_p != NULL) pNext(L->t_p) = NULL;
+        L->pLength = 0;
+        L->bucket = bucket;
+      }
+      else
+        kBucketDestroy(&bucket);
+    }
+    kTest_L(L);
+  }
+}
+
+void deleteHC(poly* p, int* e, int* l,kStrategy strat)
+{
+  LObject L(*p, currRing, strat->tailRing);
+
+  deleteHC(&L, strat);
+  *p = L.p;
+  *e = L.ecart;
+  *l = L.length;
+  if (L.t_p != NULL) p_LmFree(L.t_p, strat->tailRing);
+}
+
+/*2
+*tests if p.p=monomial*unit and cancels the unit
+*/
+void cancelunit (LObject* L,BOOLEAN inNF)
+{
+  int  i;
+  poly h;
+  number lc;
+
+  if(rHasGlobalOrdering (currRing)) return;
+  if(TEST_OPT_CANCELUNIT) return;
+
+  ring r = L->tailRing;
+  poly p = L->GetLmTailRing();
+
+#ifdef HAVE_RINGS
+    if (rField_is_Ring(r) /*&& (rHasLocalOrMixedOrdering(r))*/)
+      lc = p_GetCoeff(p,r);
+#endif
+
+#ifdef HAVE_RINGS_LOC
+  // Leading coef have to be a unit
+  if ( !(nIsUnit(p_GetCoeff(p, r))) ) return;
+#endif
+
+  if(p_GetComp(p, r) != 0 && !p_OneComp(p, r)) return;
+
+//    for(i=r->N;i>0;i--)
+//    {
+//      if ((p_GetExp(p,i,r)>0) && (rIsPolyVar(i, r)==TRUE)) return;
+//    }
+  h = pNext(p);
+
+  loop
+  {
+    if (h==NULL)
+    {
+      p_Delete(&pNext(p), r);
+      if (!inNF)
+      {
+        number eins;
+#ifdef HAVE_RINGS
+        if (rField_is_Ring(r) /*&& (rHasLocalOrMixedOrdering(r))*/)
+          eins = nCopy(lc);
+        else
+#endif
+          eins=nInit(1);
+        if (L->p != NULL)
+        {
+          pSetCoeff(L->p,eins);
+          if (L->t_p != NULL)
+            pSetCoeff0(L->t_p,eins);
+        }
+        else
+          pSetCoeff(L->t_p,eins);
+        /* p and t_p share the same coeff, if both are !=NULL */
+        /* p==NULL==t_p cannot happen here */
+      }
+      L->ecart = 0;
+      L->length = 1;
+      //if (L->pLength > 0)
+      L->pLength = 1;
+      L->max = NULL;
+
+      if (L->t_p != NULL && pNext(L->t_p) != NULL)
+        p_Delete(&pNext(L->t_p),r);
+      if (L->p != NULL && pNext(L->p) != NULL)
+        pNext(L->p) = NULL;
+
+      return;
+    }
+    i = 0;
+    loop
+    {
+      i++;
+      if (p_GetExp(p,i,r) > p_GetExp(h,i,r)) return ; // does not divide
+      #ifdef HAVE_RINGS
+      // Note: As long as qring j forbidden if j contains integer (i.e. ground rings are
+      //       domains), no zerodivisor test needed  CAUTION
+      if (rField_is_Ring(r) /*&&(rHasLocalOrMixedOrdering(r)) */)
+        if(n_DivBy(p_GetCoeff(h,r->cf),lc,r->cf) == 0)
+          return;
+      #endif
+      if (i == r->N) break; // does divide, try next monom
+    }
+    pIter(h);
+  }
+}
+
+/*2
+*pp is the new element in s
+*returns TRUE (in strat->kHEdgeFound) if
+*-HEcke is allowed
+*-we are in the last componente of the vector
+*-on all axis are monomials (all elements in NotUsedAxis are FALSE)
+*returns FALSE for pLexOrderings,
+*assumes in module case an ordering of type c* !!
+* HEckeTest is only called with strat->kHEdgeFound==FALSE !
+*/
+void HEckeTest (poly pp,kStrategy strat)
+{
+  int   j,/*k,*/p;
+
+  strat->kHEdgeFound=FALSE;
+  if (currRing->pLexOrder || currRing->MixedOrder)
+  {
+    return;
+  }
+  if (strat->ak > 1)           /*we are in the module case*/
+  {
+    return; // until ....
+    //if (!pVectorOut)     /*pVectorOut <=> order = c,* */
+    //  return FALSE;
+    //if (pGetComp(pp) < strat->ak) /* ak is the number of the last component */
+    //  return FALSE;
+  }
+  // k = 0;
+  p=pIsPurePower(pp);
+  if (p!=0) strat->NotUsedAxis[p] = FALSE;
+  /*- the leading term of pp is a power of the p-th variable -*/
+  for (j=(currRing->N);j>0; j--)
+  {
+    if (strat->NotUsedAxis[j])
+    {
+      return;
+    }
+  }
+  strat->kHEdgeFound=TRUE;
+}
+
+/*2
+*utilities for TSet, LSet
+*/
+inline static intset initec (const int maxnr)
+{
+  return (intset)omAlloc(maxnr*sizeof(int));
+}
+
+inline static unsigned long* initsevS (const int maxnr)
+{
+  return (unsigned long*)omAlloc0(maxnr*sizeof(unsigned long));
+}
+inline static int* initS_2_R (const int maxnr)
+{
+  return (int*)omAlloc0(maxnr*sizeof(int));
+}
+
+static inline void enlargeT (TSet &T, TObject** &R, unsigned long* &sevT,
+                             int &length, const int incr)
+{
+  assume(T!=NULL);
+  assume(sevT!=NULL);
+  assume(R!=NULL);
+  assume((length+incr) > 0);
+
+  int i;
+  T = (TSet)omRealloc0Size(T, length*sizeof(TObject),
+                           (length+incr)*sizeof(TObject));
+
+  sevT = (unsigned long*) omReallocSize(sevT, length*sizeof(long*),
+                           (length+incr)*sizeof(long*));
+
+  R = (TObject**)omRealloc0Size(R,length*sizeof(TObject*),
+                                (length+incr)*sizeof(TObject*));
+  for (i=length-1;i>=0;i--) R[T[i].i_r] = &(T[i]);
+  length += incr;
+}
+
+void cleanT (kStrategy strat)
+{
+  int i,j;
+  poly  p;
+  assume(currRing == strat->tailRing || strat->tailRing != NULL);
+
+  pShallowCopyDeleteProc p_shallow_copy_delete =
+    (strat->tailRing != currRing ?
+     pGetShallowCopyDeleteProc(strat->tailRing, currRing) :
+     NULL);
+
+  for (j=0; j<=strat->tl; j++)
+  {
+    p = strat->T[j].p;
+    strat->T[j].p=NULL;
+    if (strat->T[j].max != NULL)
+    {
+      p_LmFree(strat->T[j].max, strat->tailRing);
+    }
+    i = -1;
+    loop
+    {
+      i++;
+      if (i>strat->sl)
+      {
+        if (strat->T[j].t_p != NULL)
+        {
+          p_Delete(&(strat->T[j].t_p), strat->tailRing);
+          p_LmFree(p, currRing);
+        }
+        else
+          pDelete(&p);
+        break;
+      }
+      if (p == strat->S[i])
+      {
+        if (strat->T[j].t_p != NULL)
+        {
+          assume(p_shallow_copy_delete != NULL);
+          pNext(p) = p_shallow_copy_delete(pNext(p),strat->tailRing,currRing,
+                                           currRing->PolyBin);
+          p_LmFree(strat->T[j].t_p, strat->tailRing);
+        }
+        break;
+      }
+    }
+  }
+  strat->tl=-1;
+}
+
+//LSet initL ()
+//{
+//  int i;
+//  LSet l = (LSet)omAlloc(setmaxL*sizeof(LObject));
+//  return l;
+//}
+
+static inline void enlargeL (LSet* L,int* length,const int incr)
+{
+  assume((*L)!=NULL);
+  assume((length+incr)>0);
+
+  *L = (LSet)omReallocSize((*L),(*length)*sizeof(LObject),
+                                   ((*length)+incr)*sizeof(LObject));
+  (*length) += incr;
+}
+
+void initPairtest(kStrategy strat)
+{
+  strat->pairtest = (BOOLEAN *)omAlloc0((strat->sl+2)*sizeof(BOOLEAN));
+}
+
+/*2
+*test whether (p1,p2) or (p2,p1) is in L up position length
+*it returns TRUE if yes and the position k
+*/
+BOOLEAN isInPairsetL(int length,poly p1,poly p2,int*  k,kStrategy strat)
+{
+  LObject *p=&(strat->L[length]);
+
+  *k = length;
+  loop
+  {
+    if ((*k) < 0) return FALSE;
+    if (((p1 == (*p).p1) && (p2 == (*p).p2))
+    ||  ((p1 == (*p).p2) && (p2 == (*p).p1)))
+      return TRUE;
+    (*k)--;
+    p--;
+  }
+}
+
+/*2
+*in B all pairs have the same element p on the right
+*it tests whether (q,p) is in B and returns TRUE if yes
+*and the position k
+*/
+BOOLEAN isInPairsetB(poly q,int*  k,kStrategy strat)
+{
+  LObject *p=&(strat->B[strat->Bl]);
+
+  *k = strat->Bl;
+  loop
+  {
+    if ((*k) < 0) return FALSE;
+    if (q == (*p).p1)
+      return TRUE;
+    (*k)--;
+    p--;
+  }
+}
+
+int kFindInT(poly p, TSet T, int tlength)
+{
+  int i;
+
+  for (i=0; i<=tlength; i++)
+  {
+    if (T[i].p == p) return i;
+  }
+  return -1;
+}
+
+int kFindInT(poly p, kStrategy strat)
+{
+  int i;
+  do
+  {
+    i = kFindInT(p, strat->T, strat->tl);
+    if (i >= 0) return i;
+    strat = strat->next;
+  }
+  while (strat != NULL);
+  return -1;
+}
+
+#ifdef KDEBUG
+
+void sTObject::wrp()
+{
+  if (t_p != NULL) p_wrp(t_p, tailRing);
+  else if (p != NULL) p_wrp(p, currRing, tailRing);
+  else ::wrp(NULL);
+}
+
+#define kFalseReturn(x) do { if (!x) return FALSE;} while (0)
+
+// check that Lm's of a poly from T are "equal"
+static const char* kTest_LmEqual(poly p, poly t_p, ring tailRing)
+{
+  int i;
+  for (i=1; i<=tailRing->N; i++)
+  {
+    if (p_GetExp(p, i, currRing) != p_GetExp(t_p, i, tailRing))
+      return "Lm[i] different";
+  }
+  if (p_GetComp(p, currRing) != p_GetComp(t_p, tailRing))
+    return "Lm[0] different";
+  if (pNext(p) != pNext(t_p))
+    return "Lm.next different";
+  if (pGetCoeff(p) != pGetCoeff(t_p))
+    return "Lm.coeff different";
+  return NULL;
+}
+
+static BOOLEAN sloppy_max = FALSE;
+BOOLEAN kTest_T(TObject * T, ring strat_tailRing, int i, char TN)
+{
+  ring tailRing = T->tailRing;
+  if (strat_tailRing == NULL) strat_tailRing = tailRing;
+  r_assume(strat_tailRing == tailRing);
+
+  poly p = T->p;
+  // ring r = currRing;
+
+  if (T->p == NULL && T->t_p == NULL && i >= 0)
+    return dReportError("%c[%d].poly is NULL", TN, i);
+
+  if (T->tailRing != currRing)
+  {
+    if (T->t_p == NULL && i > 0)
+      return dReportError("%c[%d].t_p is NULL", TN, i);
+    pFalseReturn(p_Test(T->t_p, T->tailRing));
+    if (T->p != NULL) pFalseReturn(p_LmTest(T->p, currRing));
+    if (T->p != NULL && T->t_p != NULL)
+    {
+      const char* msg = kTest_LmEqual(T->p, T->t_p, T->tailRing);
+      if (msg != NULL)
+        return dReportError("%c[%d] %s", TN, i, msg);
+      // r = T->tailRing;
+      p = T->t_p;
+    }
+    if (T->p == NULL)
+    {
+      p = T->t_p;
+      // r = T->tailRing;
+    }
+    if (T->t_p != NULL && i >= 0 && TN == 'T')
+    {
+      if (pNext(T->t_p) == NULL)
+      {
+        if (T->max != NULL)
+          return dReportError("%c[%d].max is not NULL as it should be", TN, i);
+      }
+      else
+      {
+        if (T->max == NULL)
+          return dReportError("%c[%d].max is NULL", TN, i);
+        if (pNext(T->max) != NULL)
+          return dReportError("pNext(%c[%d].max) != NULL", TN, i);
+
+        pFalseReturn(p_CheckPolyRing(T->max, tailRing));
+        omCheckBinAddrSize(T->max, (omSizeWOfBin(tailRing->PolyBin))*SIZEOF_LONG);
+#if KDEBUG > 0
+        if (! sloppy_max)
+        {
+          poly test_max = p_GetMaxExpP(pNext(T->t_p), tailRing);
+          p_Setm(T->max, tailRing);
+          p_Setm(test_max, tailRing);
+          BOOLEAN equal = p_ExpVectorEqual(T->max, test_max, tailRing);
+          if (! equal)
+            return dReportError("%c[%d].max out of sync", TN, i);
+          p_LmFree(test_max, tailRing);
+        }
+#endif
+      }
+    }
+  }
+  else
+  {
+    if (T->max != NULL)
+      return dReportError("%c[%d].max != NULL but tailRing == currRing",TN,i);
+    if (T->t_p != NULL)
+      return dReportError("%c[%d].t_p != NULL but tailRing == currRing",TN,i);
+    if (T->p == NULL && i > 0)
+      return dReportError("%c[%d].p is NULL", TN, i);
+    pFalseReturn(p_Test(T->p, currRing));
+  }
+
+  if ((i >= 0) && (T->pLength != 0)
+  && (! rIsSyzIndexRing(currRing)) && (T->pLength != pLength(p)))
+  {
+    int l=T->pLength;
+    T->pLength=pLength(p);
+    return dReportError("%c[%d] pLength error: has %d, specified to have %d",
+                        TN, i , pLength(p), l);
+  }
+
+  // check FDeg,  for elements in L and T
+  if (i >= 0 && (TN == 'T' || TN == 'L'))
+  {
+    // FDeg has ir element from T of L set
+    if (T->FDeg  != T->pFDeg())
+    {
+      int d=T->FDeg;
+      T->FDeg=T->pFDeg();
+      return dReportError("%c[%d] FDeg error: has %d, specified to have %d",
+                          TN, i , T->pFDeg(), d);
+    }
+  }
+
+  // check is_normalized for elements in T
+  if (i >= 0 && TN == 'T')
+  {
+    if (T->is_normalized && ! nIsOne(pGetCoeff(p)))
+      return dReportError("T[%d] is_normalized error", i);
+
+  }
+  return TRUE;
+}
+
+BOOLEAN kTest_L(LObject *L, ring strat_tailRing,
+                BOOLEAN testp, int lpos, TSet T, int tlength)
+{
+  if (testp)
+  {
+    poly pn = NULL;
+    if (L->bucket != NULL)
+    {
+      kFalseReturn(kbTest(L->bucket));
+      r_assume(L->bucket->bucket_ring == L->tailRing);
+      if (L->p != NULL && pNext(L->p) != NULL)
+      {
+        pn = pNext(L->p);
+        pNext(L->p) = NULL;
+      }
+    }
+    kFalseReturn(kTest_T(L, strat_tailRing, lpos, 'L'));
+    if (pn != NULL)
+      pNext(L->p) = pn;
+
+    ring r;
+    poly p;
+    L->GetLm(p, r);
+    if (L->sev != 0 && p_GetShortExpVector(p, r) != L->sev)
+    {
+      return dReportError("L[%d] wrong sev: has %o, specified to have %o",
+                          lpos, p_GetShortExpVector(p, r), L->sev);
+    }
+  }
+  if (L->p1 == NULL)
+  {
+    // L->p2 either NULL or "normal" poly
+    pFalseReturn(pp_Test(L->p2, currRing, L->tailRing));
+  }
+  else if (tlength > 0 && T != NULL && (lpos >=0))
+  {
+    // now p1 and p2 must be != NULL and must be contained in T
+    int i;
+    i = kFindInT(L->p1, T, tlength);
+    if (i < 0)
+      return dReportError("L[%d].p1 not in T",lpos);
+    i = kFindInT(L->p2, T, tlength);
+    if (i < 0)
+      return dReportError("L[%d].p2 not in T",lpos);
+  }
+  return TRUE;
+}
+
+BOOLEAN kTest (kStrategy strat)
+{
+  int i;
+
+  // test P
+  kFalseReturn(kTest_L(&(strat->P), strat->tailRing,
+                       (strat->P.p != NULL && pNext(strat->P.p)!=strat->tail),
+                       -1, strat->T, strat->tl));
+
+  // test T
+  if (strat->T != NULL)
+  {
+    for (i=0; i<=strat->tl; i++)
+    {
+      kFalseReturn(kTest_T(&(strat->T[i]), strat->tailRing, i, 'T'));
+      if (strat->sevT[i] != pGetShortExpVector(strat->T[i].p))
+        return dReportError("strat->sevT[%d] out of sync", i);
+    }
+  }
+
+  // test L
+  if (strat->L != NULL)
+  {
+    for (i=0; i<=strat->Ll; i++)
+    {
+      kFalseReturn(kTest_L(&(strat->L[i]), strat->tailRing,
+                           strat->L[i].Next() != strat->tail, i,
+                           strat->T, strat->tl));
+      // may be unused
+      //if (strat->use_buckets && strat->L[i].Next() != strat->tail &&
+      //    strat->L[i].Next() != NULL && strat->L[i].p1 != NULL)
+      //{
+      //  assume(strat->L[i].bucket != NULL);
+      //}
+    }
+  }
+
+  // test S
+  if (strat->S != NULL)
+    kFalseReturn(kTest_S(strat));
+
+  return TRUE;
+}
+
+BOOLEAN kTest_S(kStrategy strat)
+{
+  int i;
+  BOOLEAN ret = TRUE;
+  for (i=0; i<=strat->sl; i++)
+  {
+    if (strat->S[i] != NULL &&
+        strat->sevS[i] != pGetShortExpVector(strat->S[i]))
+    {
+      return dReportError("S[%d] wrong sev: has %o, specified to have %o",
+                          i , pGetShortExpVector(strat->S[i]), strat->sevS[i]);
+    }
+  }
+  return ret;
+}
+
+
+
+BOOLEAN kTest_TS(kStrategy strat)
+{
+  int i, j;
+  // BOOLEAN ret = TRUE;
+  kFalseReturn(kTest(strat));
+
+  // test strat->R, strat->T[i].i_r
+  for (i=0; i<=strat->tl; i++)
+  {
+    if (strat->T[i].i_r < 0 || strat->T[i].i_r > strat->tl)
+      return dReportError("strat->T[%d].i_r == %d out of bounds", i,
+                          strat->T[i].i_r);
+    if (strat->R[strat->T[i].i_r] != &(strat->T[i]))
+      return dReportError("T[%d].i_r with R out of sync", i);
+  }
+  // test containment of S inT
+  if (strat->S != NULL)
+  {
+    for (i=0; i<=strat->sl; i++)
+    {
+      j = kFindInT(strat->S[i], strat->T, strat->tl);
+      if (j < 0)
+        return dReportError("S[%d] not in T", i);
+      if (strat->S_2_R[i] != strat->T[j].i_r)
+        return dReportError("S_2_R[%d]=%d != T[%d].i_r=%d\n",
+                            i, strat->S_2_R[i], j, strat->T[j].i_r);
+    }
+  }
+  // test strat->L[i].i_r1
+  for (i=0; i<=strat->Ll; i++)
+  {
+    if (strat->L[i].p1 != NULL && strat->L[i].p2)
+    {
+      if (strat->L[i].i_r1 < 0 ||
+          strat->L[i].i_r1 > strat->tl ||
+          strat->L[i].T_1(strat)->p != strat->L[i].p1)
+        return dReportError("L[%d].i_r1 out of sync", i);
+      if (strat->L[i].i_r2 < 0 ||
+          strat->L[i].i_r2 > strat->tl ||
+          strat->L[i].T_2(strat)->p != strat->L[i].p2);
+    }
+    else
+    {
+      if (strat->L[i].i_r1 != -1)
+        return dReportError("L[%d].i_r1 out of sync", i);
+      if (strat->L[i].i_r2 != -1)
+        return dReportError("L[%d].i_r2 out of sync", i);
+    }
+    if (strat->L[i].i_r != -1)
+      return dReportError("L[%d].i_r out of sync", i);
+  }
+  return TRUE;
+}
+
+#endif // KDEBUG
+
+/*2
+*cancels the i-th polynomial in the standardbase s
+*/
+void deleteInS (int i,kStrategy strat)
+{
+#ifdef ENTER_USE_MEMMOVE
+  memmove(&(strat->S[i]), &(strat->S[i+1]), (strat->sl - i)*sizeof(poly));
+  memmove(&(strat->ecartS[i]),&(strat->ecartS[i+1]),(strat->sl - i)*sizeof(int));
+  memmove(&(strat->sevS[i]),&(strat->sevS[i+1]),(strat->sl - i)*sizeof(unsigned long));
+  memmove(&(strat->S_2_R[i]),&(strat->S_2_R[i+1]),(strat->sl - i)*sizeof(int));
+#else
+  int j;
+  for (j=i; j<strat->sl; j++)
+  {
+    strat->S[j] = strat->S[j+1];
+    strat->ecartS[j] = strat->ecartS[j+1];
+    strat->sevS[j] = strat->sevS[j+1];
+    strat->S_2_R[j] = strat->S_2_R[j+1];
+  }
+#endif
+  if (strat->lenS!=NULL)
+  {
+#ifdef ENTER_USE_MEMMOVE
+    memmove(&(strat->lenS[i]),&(strat->lenS[i+1]),(strat->sl - i)*sizeof(int));
+#else
+    for (j=i; j<strat->sl; j++) strat->lenS[j] = strat->lenS[j+1];
+#endif
+  }
+  if (strat->lenSw!=NULL)
+  {
+#ifdef ENTER_USE_MEMMOVE
+    memmove(&(strat->lenSw[i]),&(strat->lenSw[i+1]),(strat->sl - i)*sizeof(wlen_type));
+#else
+    for (j=i; j<strat->sl; j++) strat->lenSw[j] = strat->lenSw[j+1];
+#endif
+  }
+  if (strat->fromQ!=NULL)
+  {
+#ifdef ENTER_USE_MEMMOVE
+    memmove(&(strat->fromQ[i]),&(strat->fromQ[i+1]),(strat->sl - i)*sizeof(int));
+#else
+    for (j=i; j<strat->sl; j++)
+    {
+      strat->fromQ[j] = strat->fromQ[j+1];
+    }
+#endif
+  }
+  strat->S[strat->sl] = NULL;
+  strat->sl--;
+}
+
+
+/*2
+*cancels the i-th polynomial in the standardbase s
+*/
+void deleteInSSba (int i,kStrategy strat)
+{
+#ifdef ENTER_USE_MEMMOVE
+  memmove(&(strat->S[i]), &(strat->S[i+1]), (strat->sl - i)*sizeof(poly));
+  memmove(&(strat->sig[i]), &(strat->sig[i+1]), (strat->sl - i)*sizeof(poly));
+  memmove(&(strat->ecartS[i]),&(strat->ecartS[i+1]),(strat->sl - i)*sizeof(int));
+  memmove(&(strat->sevS[i]),&(strat->sevS[i+1]),(strat->sl - i)*sizeof(unsigned long));
+  memmove(&(strat->sevSig[i]),&(strat->sevSig[i+1]),(strat->sl - i)*sizeof(unsigned long));
+  memmove(&(strat->S_2_R[i]),&(strat->S_2_R[i+1]),(strat->sl - i)*sizeof(int));
+#else
+  int j;
+  for (j=i; j<strat->sl; j++)
+  {
+    strat->S[j] = strat->S[j+1];
+    strat->sig[j] = strat->sig[j+1];
+    strat->ecartS[j] = strat->ecartS[j+1];
+    strat->sevS[j] = strat->sevS[j+1];
+    strat->sevSig[j] = strat->sevSig[j+1];
+    strat->S_2_R[j] = strat->S_2_R[j+1];
+  }
+#endif
+  if (strat->lenS!=NULL)
+  {
+#ifdef ENTER_USE_MEMMOVE
+    memmove(&(strat->lenS[i]),&(strat->lenS[i+1]),(strat->sl - i)*sizeof(int));
+#else
+    for (j=i; j<strat->sl; j++) strat->lenS[j] = strat->lenS[j+1];
+#endif
+  }
+  if (strat->lenSw!=NULL)
+  {
+#ifdef ENTER_USE_MEMMOVE
+    memmove(&(strat->lenSw[i]),&(strat->lenSw[i+1]),(strat->sl - i)*sizeof(wlen_type));
+#else
+    for (j=i; j<strat->sl; j++) strat->lenSw[j] = strat->lenSw[j+1];
+#endif
+  }
+  if (strat->fromQ!=NULL)
+  {
+#ifdef ENTER_USE_MEMMOVE
+    memmove(&(strat->fromQ[i]),&(strat->fromQ[i+1]),(strat->sl - i)*sizeof(int));
+#else
+    for (j=i; j<strat->sl; j++)
+    {
+      strat->fromQ[j] = strat->fromQ[j+1];
+    }
+#endif
+  }
+  strat->S[strat->sl] = NULL;
+  strat->sl--;
+}
+
+/*2
+*cancels the j-th polynomial in the set
+*/
+void deleteInL (LSet set, int *length, int j,kStrategy strat)
+{
+  if (set[j].lcm!=NULL)
+  {
+#ifdef HAVE_RINGS
+    if (pGetCoeff(set[j].lcm) != NULL)
+      pLmDelete(set[j].lcm);
+    else
+#endif
+      pLmFree(set[j].lcm);
+  }
+  if (set[j].sig!=NULL)
+  {
+#ifdef HAVE_RINGS
+    if (pGetCoeff(set[j].sig) != NULL)
+      pLmDelete(set[j].sig);
+    else
+#endif
+      pLmFree(set[j].sig);
+  }
+  if (set[j].p!=NULL)
+  {
+    if (pNext(set[j].p) == strat->tail)
+    {
+#ifdef HAVE_RINGS
+      if (pGetCoeff(set[j].p) != NULL)
+        pLmDelete(set[j].p);
+      else
+#endif
+        pLmFree(set[j].p);
+      /*- tail belongs to several int spolys -*/
+    }
+    else
+    {
+      // search p in T, if it is there, do not delete it
+      if (rHasGlobalOrdering(currRing) || (kFindInT(set[j].p, strat) < 0))
+      {
+        // assure that for global orderings kFindInT fails
+        //assume((rHasLocalOrMixedOrdering(currRing)) && (kFindInT(set[j].p, strat) >= 0));
+        set[j].Delete();
+      }
+    }
+  }
+  if (*length > 0 && j < *length)
+  {
+#ifdef ENTER_USE_MEMMOVE
+    memmove(&(set[j]), &(set[j+1]), (*length - j)*sizeof(LObject));
+#else
+    int i;
+    for (i=j; i < (*length); i++)
+      set[i] = set[i+1];
+#endif
+  }
+#ifdef KDEBUG
+  memset(&(set[*length]),0,sizeof(LObject));
+#endif
+  (*length)--;
+}
+
+/*2
+*enters p at position at in L
+*/
+void enterL (LSet *set,int *length, int *LSetmax, LObject p,int at)
+{
+  // this should be corrected
+  assume(p.FDeg == p.pFDeg());
+
+  if ((*length)>=0)
+  {
+    if ((*length) == (*LSetmax)-1) enlargeL(set,LSetmax,setmaxLinc);
+    if (at <= (*length))
+#ifdef ENTER_USE_MEMMOVE
+      memmove(&((*set)[at+1]), &((*set)[at]), ((*length)-at+1)*sizeof(LObject));
+#else
+    for (i=(*length)+1; i>=at+1; i--) (*set)[i] = (*set)[i-1];
+#endif
+  }
+  else at = 0;
+  (*set)[at] = p;
+  (*length)++;
+}
+
+/*2
+* computes the normal ecart;
+* used in mora case and if pLexOrder & sugar in bba case
+*/
+void initEcartNormal (TObject* h)
+{
+  h->FDeg = h->pFDeg();
+  h->ecart = h->pLDeg() - h->FDeg;
+  // h->length is set by h->pLDeg
+  h->length=h->pLength=pLength(h->p);
+}
+
+void initEcartBBA (TObject* h)
+{
+  h->FDeg = h->pFDeg();
+  (*h).ecart = 0;
+  h->length=h->pLength=pLength(h->p);
+}
+
+void initEcartPairBba (LObject* Lp,poly /*f*/,poly /*g*/,int /*ecartF*/,int /*ecartG*/)
+{
+  Lp->FDeg = Lp->pFDeg();
+  (*Lp).ecart = 0;
+  (*Lp).length = 0;
+}
+
+void initEcartPairMora (LObject* Lp,poly /*f*/,poly /*g*/,int ecartF,int ecartG)
+{
+  Lp->FDeg = Lp->pFDeg();
+  (*Lp).ecart = si_max(ecartF,ecartG);
+  (*Lp).ecart = (*Lp).ecart- (Lp->FDeg -p_FDeg((*Lp).lcm,currRing));
+  (*Lp).length = 0;
+}
+
+/*2
+*if ecart1<=ecart2 it returns TRUE
+*/
+static inline BOOLEAN sugarDivisibleBy(int ecart1, int ecart2)
+{
+  return (ecart1 <= ecart2);
+}
+
+#ifdef HAVE_RINGS
+/*2
+* put the pair (s[i],p)  into the set B, ecart=ecart(p) (ring case)
+*/
+void enterOnePairRing (int i,poly p,int ecart, int isFromQ,kStrategy strat, int atR = -1)
+{
+  assume(i<=strat->sl);
+  int      l,j,compare,compareCoeff;
+  LObject  Lp;
+
+  if (strat->interred_flag) return;
+#ifdef KDEBUG
+  Lp.ecart=0; Lp.length=0;
+#endif
+  /*- computes the lcm(s[i],p) -*/
+  Lp.lcm = pInit();
+  pSetCoeff0(Lp.lcm, n_Lcm(pGetCoeff(p), pGetCoeff(strat->S[i]), currRing->cf));
+
+  #if ADIDEBUG
+  PrintS("\nLp.lcm (lc) = ");pWrite(Lp.lcm);
+  #endif
+
+  // Lp.lcm == 0
+  if (nIsZero(pGetCoeff(Lp.lcm)))
+  {
+#ifdef KDEBUG
+      if (TEST_OPT_DEBUG)
+      {
+        PrintS("--- Lp.lcm == 0\n");
+        PrintS("p:");
+        wrp(p);
+        Print("  strat->S[%d]:", i);
+        wrp(strat->S[i]);
+        PrintLn();
+      }
+#endif
+      strat->cp++;
+      pLmDelete(Lp.lcm);
+      return;
+  }
+  // basic product criterion
+  pLcm(p,strat->S[i],Lp.lcm);
+  pSetm(Lp.lcm);
+
+  #if ADIDEBUG
+  PrintS("\nLp.lcm (lcm) = ");pWrite(Lp.lcm);
+  #endif
+
+  assume(!strat->sugarCrit);
+  if (pHasNotCF(p,strat->S[i]) && n_IsUnit(pGetCoeff(p),currRing->cf)
+      && n_IsUnit(pGetCoeff(strat->S[i]),currRing->cf))
+  {
+#ifdef KDEBUG
+      if (TEST_OPT_DEBUG)
+      {
+        PrintS("--- product criterion func enterOnePairRing type 1\n");
+        PrintS("p:");
+        wrp(p);
+        Print("  strat->S[%d]:", i);
+        wrp(strat->S[i]);
+        PrintLn();
+      }
+#endif
+      strat->cp++;
+      pLmDelete(Lp.lcm);
+      return;
+  }
+  assume(!strat->fromT);
+  /*
+  *the set B collects the pairs of type (S[j],p)
+  *suppose (r,p) is in B and (s,p) is the new pair and lcm(s,p) != lcm(r,p)
+  *if the leading term of s devides lcm(r,p) then (r,p) will be canceled
+  *if the leading term of r devides lcm(s,p) then (s,p) will not enter B
+  */
+  for(j = strat->Bl;j>=0;j--)
+  {
+    compare=pDivCompRing(strat->B[j].lcm,Lp.lcm);
+    compareCoeff = n_DivComp(pGetCoeff(strat->B[j].lcm), pGetCoeff(Lp.lcm), currRing->cf);
+    if ((compareCoeff == pDivComp_EQUAL) || (compare == compareCoeff))
+    {
+      if (compare == 1)
+      {
+        strat->c3++;
+#ifdef KDEBUG
+        if (TEST_OPT_DEBUG)
+        {
+          PrintS("--- chain criterion type 1\n");
+          PrintS("strat->B[j]:");
+          wrp(strat->B[j].lcm);
+          PrintS("  Lp.lcm:");
+          wrp(Lp.lcm);
+          PrintLn();
+        }
+#endif
+        if ((strat->fromQ==NULL) || (isFromQ==0) || (strat->fromQ[i]==0))
+        {
+          pLmDelete(Lp.lcm);
+          return;
+        }
+        break;
+      }
+      else if (compare == -1)
+      {
+#ifdef KDEBUG
+        if (TEST_OPT_DEBUG)
+        {
+          PrintS("--- chain criterion type 2\n");
+          Print("strat->B[%d].lcm:",j);
+          wrp(strat->B[j].lcm);
+          PrintS("  Lp.lcm:");
+          wrp(Lp.lcm);
+          PrintLn();
+        }
+#endif
+        deleteInL(strat->B,&strat->Bl,j,strat);
+        strat->c3++;
+      }
+    }
+    if ((compare == pDivComp_EQUAL) && (compareCoeff != 2))
+    {
+      if (compareCoeff == pDivComp_LESS)
+      {
+#ifdef KDEBUG
+        if (TEST_OPT_DEBUG)
+        {
+          PrintS("--- chain criterion type 3\n");
+          Print("strat->B[%d].lcm:", j);
+          wrp(strat->B[j].lcm);
+          PrintS("  Lp.lcm:");
+          wrp(Lp.lcm);
+          PrintLn();
+        }
+#endif
+        strat->c3++;
+        if ((strat->fromQ==NULL) || (isFromQ==0) || (strat->fromQ[i]==0))
+        {
+          pLmDelete(Lp.lcm);
+          return;
+        }
+        break;
+      }
+      else
+      // Add hint for same LM and LC (later) (TODO Oliver)
+      // if (compareCoeff == pDivComp_GREATER)
+      {
+#ifdef KDEBUG
+        if (TEST_OPT_DEBUG)
+        {
+          PrintS("--- chain criterion type 4\n");
+          Print("strat->B[%d].lcm:", j);
+          wrp(strat->B[j].lcm);
+          PrintS("  Lp.lcm:");
+          wrp(Lp.lcm);
+          PrintLn();
+        }
+#endif
+        deleteInL(strat->B,&strat->Bl,j,strat);
+        strat->c3++;
+      }
+    }
+  }
+  /*
+  *the pair (S[i],p) enters B if the spoly != 0
+  */
+  /*-  compute the short s-polynomial -*/
+  if ((strat->S[i]==NULL) || (p==NULL))
+  {
+#ifdef KDEBUG
+    if (TEST_OPT_DEBUG)
+    {
+      PrintS("--- spoly = NULL\n");
+    }
+#endif
+    pLmDelete(Lp.lcm);
+    return;
+  }
+  if ((strat->fromQ!=NULL) && (isFromQ!=0) && (strat->fromQ[i]!=0))
+  {
+    // Is from a previous computed GB, therefore we know that spoly will
+    // reduce to zero. Oliver.
+    WarnS("Could we come here? 8738947389");
+    Lp.p=NULL;
+  }
+  else
+  {
+    Lp.p = ksCreateShortSpoly(strat->S[i], p, strat->tailRing);
+  }
+  if (Lp.p == NULL)
+  {
+#ifdef KDEBUG
+    if (TEST_OPT_DEBUG)
+    {
+      PrintS("--- spoly = NULL\n");
+    }
+#endif
+    /*- the case that the s-poly is 0 -*/
+    if (strat->pairtest==NULL) initPairtest(strat);
+    strat->pairtest[i] = TRUE;/*- hint for spoly(S^[i],p)=0 -*/
+    strat->pairtest[strat->sl+1] = TRUE;
+    /*hint for spoly(S[i],p) == 0 for some i,0 <= i <= sl*/
+    /*
+    *suppose we have (s,r),(r,p),(s,p) and spoly(s,p) == 0 and (r,p) is
+    *still in B (i.e. lcm(r,p) == lcm(s,p) or the leading term of s does not
+    *devide lcm(r,p)). In the last case (s,r) can be canceled if the leading
+    *term of p devides the lcm(s,r)
+    *(this canceling should be done here because
+    *the case lcm(s,p) == lcm(s,r) is not covered in chainCrit)
+    *the first case is handeled in chainCrit
+    */
+    pLmDelete(Lp.lcm);
+  }
+  else
+  {
+    /*- the pair (S[i],p) enters B -*/
+    Lp.p1 = strat->S[i];
+    Lp.p2 = p;
+
+    pNext(Lp.p) = strat->tail;
+
+    if (atR >= 0)
+    {
+      Lp.i_r2 = atR;
+      Lp.i_r1 = strat->S_2_R[i];
+    }
+    strat->initEcartPair(&Lp,strat->S[i],p,strat->ecartS[i],ecart);
+    l = strat->posInL(strat->B,strat->Bl,&Lp,strat);
+    enterL(&strat->B,&strat->Bl,&strat->Bmax,Lp,l);
+  }
+}
+
+
+/*2
+* put the  lcm(s[i],p)  into the set B
+*/
+
+BOOLEAN enterOneStrongPoly (int i,poly p,int /*ecart*/, int /*isFromQ*/,kStrategy strat, int atR = -1)
+{
+  number d, s, t;
+  assume(i<=strat->sl);
+  assume(atR >= 0);
+  poly m1, m2, gcd;
+
+  d = n_ExtGcd(pGetCoeff(p), pGetCoeff(strat->S[i]), &s, &t, currRing->cf);
+
+  if (nIsZero(s) || nIsZero(t))  // evtl. durch divBy tests ersetzen
+  {
+    nDelete(&d);
+    nDelete(&s);
+    nDelete(&t);
+    return FALSE;
+  }
+
+  k_GetStrongLeadTerms(p, strat->S[i], currRing, m1, m2, gcd, strat->tailRing);
+  //p_Test(m1,strat->tailRing);
+  //p_Test(m2,strat->tailRing);
+  while (! kCheckStrongCreation(atR, m1, i, m2, strat) )
+  {
+    memset(&(strat->P), 0, sizeof(strat->P));
+    kStratChangeTailRing(strat);
+    strat->P = *(strat->R[atR]);
+    p_LmFree(m1, strat->tailRing);
+    p_LmFree(m2, strat->tailRing);
+    p_LmFree(gcd, currRing);
+    k_GetStrongLeadTerms(p, strat->S[i], currRing, m1, m2, gcd, strat->tailRing);
+  }
+  pSetCoeff0(m1, s);
+  pSetCoeff0(m2, t);
+  pSetCoeff0(gcd, d);
+  p_Test(m1,strat->tailRing);
+  p_Test(m2,strat->tailRing);
+
+#ifdef KDEBUG
+  if (TEST_OPT_DEBUG)
+  {
+    // Print("t = %d; s = %d; d = %d\n", nInt(t), nInt(s), nInt(d));
+    PrintS("m1 = ");
+    p_wrp(m1, strat->tailRing);
+    PrintS(" ; m2 = ");
+    p_wrp(m2, strat->tailRing);
+    PrintS(" ; gcd = ");
+    wrp(gcd);
+    PrintS("\n--- create strong gcd poly: ");
+    Print("\n p: ", i);
+    wrp(p);
+    Print("\n strat->S[%d]: ", i);
+    wrp(strat->S[i]);
+    PrintS(" ---> ");
+  }
+#endif
+
+  pNext(gcd) = p_Add_q(pp_Mult_mm(pNext(p), m1, strat->tailRing), pp_Mult_mm(pNext(strat->S[i]), m2, strat->tailRing), strat->tailRing);
+  p_LmDelete(m1, strat->tailRing);
+  p_LmDelete(m2, strat->tailRing);
+
+#ifdef KDEBUG
+  if (TEST_OPT_DEBUG)
+  {
+    wrp(gcd);
+    PrintLn();
+  }
+#endif
+
+  LObject h;
+  h.p = gcd;
+  h.tailRing = strat->tailRing;
+  int posx;
+  h.pCleardenom();
+  strat->initEcart(&h);
+  if (strat->Ll==-1)
+    posx =0;
+  else
+    posx = strat->posInL(strat->L,strat->Ll,&h,strat);
+  h.sev = pGetShortExpVector(h.p);
+  if (currRing!=strat->tailRing)
+    h.t_p = k_LmInit_currRing_2_tailRing(h.p, strat->tailRing);
+  enterL(&strat->L,&strat->Ll,&strat->Lmax,h,posx);
+  return TRUE;
+}
+#endif
+
+/*2
+* put the pair (s[i],p)  into the set B, ecart=ecart(p)
+*/
+
+void enterOnePairNormal (int i,poly p,int ecart, int isFromQ,kStrategy strat, int atR = -1)
+{
+  assume(i<=strat->sl);
+  if (strat->interred_flag) return;
+
+  int      l,j,compare;
+  LObject  Lp;
+  Lp.i_r = -1;
+
+#ifdef KDEBUG
+  Lp.ecart=0; Lp.length=0;
+#endif
+  /*- computes the lcm(s[i],p) -*/
+  Lp.lcm = pInit();
+
+#ifndef HAVE_RATGRING
+  pLcm(p,strat->S[i],Lp.lcm);
+#elif defined(HAVE_RATGRING)
+  //  if (rIsRatGRing(currRing))
+  pLcmRat(p,strat->S[i],Lp.lcm, currRing->real_var_start); // int rat_shift
+#endif
+  pSetm(Lp.lcm);
+
+
+  if (strat->sugarCrit && ALLOW_PROD_CRIT(strat))
+  {
+    if((!((strat->ecartS[i]>0)&&(ecart>0)))
+    && pHasNotCF(p,strat->S[i]))
+    {
+    /*
+    *the product criterion has applied for (s,p),
+    *i.e. lcm(s,p)=product of the leading terms of s and p.
+    *Suppose (s,r) is in L and the leading term
+    *of p divides lcm(s,r)
+    *(==> the leading term of p divides the leading term of r)
+    *but the leading term of s does not divide the leading term of r
+    *(notice that tis condition is automatically satisfied if r is still
+    *in S), then (s,r) can be cancelled.
+    *This should be done here because the
+    *case lcm(s,r)=lcm(s,p) is not covered by chainCrit.
+    *
+    *Moreover, skipping (s,r) holds also for the noncommutative case.
+    */
+      strat->cp++;
+      pLmFree(Lp.lcm);
+      Lp.lcm=NULL;
+      return;
+    }
+    else
+      Lp.ecart = si_max(ecart,strat->ecartS[i]);
+    if (strat->fromT && (strat->ecartS[i]>ecart))
+    {
+      pLmFree(Lp.lcm);
+      Lp.lcm=NULL;
+      return;
+      /*the pair is (s[i],t[.]), discard it if the ecart is too big*/
+    }
+    /*
+    *the set B collects the pairs of type (S[j],p)
+    *suppose (r,p) is in B and (s,p) is the new pair and lcm(s,p)#lcm(r,p)
+    *if the leading term of s devides lcm(r,p) then (r,p) will be canceled
+    *if the leading term of r devides lcm(s,p) then (s,p) will not enter B
+    */
+    {
+      j = strat->Bl;
+      loop
+      {
+        if (j < 0)  break;
+        compare=pDivComp(strat->B[j].lcm,Lp.lcm);
+        if ((compare==1)
+        &&(sugarDivisibleBy(strat->B[j].ecart,Lp.ecart)))
+        {
+          strat->c3++;
+          if ((strat->fromQ==NULL) || (isFromQ==0) || (strat->fromQ[i]==0))
+          {
+            pLmFree(Lp.lcm);
+            return;
+          }
+          break;
+        }
+        else
+        if ((compare ==-1)
+        && sugarDivisibleBy(Lp.ecart,strat->B[j].ecart))
+        {
+          deleteInL(strat->B,&strat->Bl,j,strat);
+          strat->c3++;
+        }
+        j--;
+      }
+    }
+  }
+  else /*sugarcrit*/
+  {
+    if (ALLOW_PROD_CRIT(strat))
+    {
+      // if currRing->nc_type!=quasi (or skew)
+      // TODO: enable productCrit for super commutative algebras...
+      if(/*(strat->ak==0) && productCrit(p,strat->S[i])*/
+      pHasNotCF(p,strat->S[i]))
+      {
+      /*
+      *the product criterion has applied for (s,p),
+      *i.e. lcm(s,p)=product of the leading terms of s and p.
+      *Suppose (s,r) is in L and the leading term
+      *of p devides lcm(s,r)
+      *(==> the leading term of p devides the leading term of r)
+      *but the leading term of s does not devide the leading term of r
+      *(notice that tis condition is automatically satisfied if r is still
+      *in S), then (s,r) can be canceled.
+      *This should be done here because the
+      *case lcm(s,r)=lcm(s,p) is not covered by chainCrit.
+      */
+          strat->cp++;
+          pLmFree(Lp.lcm);
+          Lp.lcm=NULL;
+          return;
+      }
+      if (strat->fromT && (strat->ecartS[i]>ecart))
+      {
+        pLmFree(Lp.lcm);
+        Lp.lcm=NULL;
+        return;
+        /*the pair is (s[i],t[.]), discard it if the ecart is too big*/
+      }
+      /*
+      *the set B collects the pairs of type (S[j],p)
+      *suppose (r,p) is in B and (s,p) is the new pair and lcm(s,p)#lcm(r,p)
+      *if the leading term of s devides lcm(r,p) then (r,p) will be canceled
+      *if the leading term of r devides lcm(s,p) then (s,p) will not enter B
+      */
+      for(j = strat->Bl;j>=0;j--)
+      {
+        compare=pDivComp(strat->B[j].lcm,Lp.lcm);
+        if (compare==1)
+        {
+          strat->c3++;
+          if ((strat->fromQ==NULL) || (isFromQ==0) || (strat->fromQ[i]==0))
+          {
+            pLmFree(Lp.lcm);
+            return;
+          }
+          break;
+        }
+        else
+        if (compare ==-1)
+        {
+          deleteInL(strat->B,&strat->Bl,j,strat);
+          strat->c3++;
+        }
+      }
+    }
+  }
+  /*
+  *the pair (S[i],p) enters B if the spoly != 0
+  */
+  /*-  compute the short s-polynomial -*/
+  if (strat->fromT && !TEST_OPT_INTSTRATEGY)
+    pNorm(p);
+
+  if ((strat->S[i]==NULL) || (p==NULL))
+    return;
+
+  if ((strat->fromQ!=NULL) && (isFromQ!=0) && (strat->fromQ[i]!=0))
+    Lp.p=NULL;
+  else
+  {
+    #ifdef HAVE_PLURAL
+    if ( rIsPluralRing(currRing) )
+    {
+      if(pHasNotCF(p, strat->S[i]))
+      {
+         if(ncRingType(currRing) == nc_lie)
+         {
+             // generalized prod-crit for lie-type
+             strat->cp++;
+             Lp.p = nc_p_Bracket_qq(pCopy(p),strat->S[i], currRing);
+         }
+         else
+        if( ALLOW_PROD_CRIT(strat) )
+        {
+            // product criterion for homogeneous case in SCA
+            strat->cp++;
+            Lp.p = NULL;
+        }
+        else
+        {
+          Lp.p = // nc_CreateSpoly(strat->S[i],p,currRing);
+                nc_CreateShortSpoly(strat->S[i], p, currRing);
+
+          assume(pNext(Lp.p)==NULL); // TODO: this may be violated whenever ext.prod.crit. for Lie alg. is used
+          pNext(Lp.p) = strat->tail; // !!!
+        }
+      }
+      else
+      {
+        Lp.p = // nc_CreateSpoly(strat->S[i],p,currRing);
+              nc_CreateShortSpoly(strat->S[i], p, currRing);
+
+        assume(pNext(Lp.p)==NULL); // TODO: this may be violated whenever ext.prod.crit. for Lie alg. is used
+        pNext(Lp.p) = strat->tail; // !!!
+
+      }
+
+
+#if MYTEST
+      if (TEST_OPT_DEBUG)
+      {
+        PrintS("enterOnePairNormal::\n strat->S[i]: "); pWrite(strat->S[i]);
+        PrintS("p: "); pWrite(p);
+        PrintS("SPoly: "); pWrite(Lp.p);
+      }
+#endif
+
+    }
+    else
+    #endif
+    {
+      assume(!rIsPluralRing(currRing));
+      Lp.p = ksCreateShortSpoly(strat->S[i], p, strat->tailRing);
+#if MYTEST
+      if (TEST_OPT_DEBUG)
+      {
+        PrintS("enterOnePairNormal::\n strat->S[i]: "); pWrite(strat->S[i]);
+        PrintS("p: "); pWrite(p);
+        PrintS("commutative SPoly: "); pWrite(Lp.p);
+      }
+#endif
+
+      }
+  }
+  if (Lp.p == NULL)
+  {
+    /*- the case that the s-poly is 0 -*/
+    if (strat->pairtest==NULL) initPairtest(strat);
+    strat->pairtest[i] = TRUE;/*- hint for spoly(S^[i],p)=0 -*/
+    strat->pairtest[strat->sl+1] = TRUE;
+    /*hint for spoly(S[i],p) == 0 for some i,0 <= i <= sl*/
+    /*
+    *suppose we have (s,r),(r,p),(s,p) and spoly(s,p) == 0 and (r,p) is
+    *still in B (i.e. lcm(r,p) == lcm(s,p) or the leading term of s does not
+    *devide lcm(r,p)). In the last case (s,r) can be canceled if the leading
+    *term of p devides the lcm(s,r)
+    *(this canceling should be done here because
+    *the case lcm(s,p) == lcm(s,r) is not covered in chainCrit)
+    *the first case is handeled in chainCrit
+    */
+    if (Lp.lcm!=NULL) pLmFree(Lp.lcm);
+  }
+  else
+  {
+    /*- the pair (S[i],p) enters B -*/
+    Lp.p1 = strat->S[i];
+    Lp.p2 = p;
+
+    if (
+        (!rIsPluralRing(currRing))
+//      ||  (rIsPluralRing(currRing) && (ncRingType(currRing) != nc_lie))
+       )
+    {
+      assume(pNext(Lp.p)==NULL); // TODO: this may be violated whenever ext.prod.crit. for Lie alg. is used
+      pNext(Lp.p) = strat->tail; // !!!
+    }
+
+    if (atR >= 0)
+    {
+      Lp.i_r1 = strat->S_2_R[i];
+      Lp.i_r2 = atR;
+    }
+    else
+    {
+      Lp.i_r1 = -1;
+      Lp.i_r2 = -1;
+    }
+    strat->initEcartPair(&Lp,strat->S[i],p,strat->ecartS[i],ecart);
+
+    if (TEST_OPT_INTSTRATEGY)
+    {
+      if (!rIsPluralRing(currRing))
+        nDelete(&(Lp.p->coef));
+    }
+
+    l = strat->posInL(strat->B,strat->Bl,&Lp,strat);
+    enterL(&strat->B,&strat->Bl,&strat->Bmax,Lp,l);
+  }
+}
+
+/*2
+* put the pair (s[i],p)  into the set B, ecart=ecart(p)
+* NOTE: here we need to add the signature-based criteria
+*/
+
+#ifdef DEBUGF5
+void enterOnePairSig (int i, poly p, poly pSig, int from, int ecart, int isFromQ, kStrategy strat, int atR = -1)
+#else
+void enterOnePairSig (int i, poly p, poly pSig, int, int ecart, int isFromQ, kStrategy strat, int atR = -1)
+#endif
+{
+  assume(i<=strat->sl);
+  if (strat->interred_flag) return;
+
+  int      l;
+  poly m1 = NULL,m2 = NULL; // we need the multipliers for the s-polynomial to compute
+              // the corresponding signatures for criteria checks
+  LObject  Lp;
+  poly pSigMult = p_Copy(pSig,currRing);
+  poly sSigMult = p_Copy(strat->sig[i],currRing);
+  unsigned long pSigMultNegSev,sSigMultNegSev;
+  Lp.i_r = -1;
+
+#ifdef KDEBUG
+  Lp.ecart=0; Lp.length=0;
+#endif
+  /*- computes the lcm(s[i],p) -*/
+  Lp.lcm = pInit();
+  k_GetLeadTerms(p,strat->S[i],currRing,m1,m2,currRing);
+#ifndef HAVE_RATGRING
+  pLcm(p,strat->S[i],Lp.lcm);
+#elif defined(HAVE_RATGRING)
+  //  if (rIsRatGRing(currRing))
+  pLcmRat(p,strat->S[i],Lp.lcm, currRing->real_var_start); // int rat_shift
+#endif
+  pSetm(Lp.lcm);
+
+  // set coeffs of multipliers m1 and m2
+  pSetCoeff0(m1, nInit(1));
+  pSetCoeff0(m2, nInit(1));
+//#if 1
+#ifdef DEBUGF5
+  Print("P1  ");
+  pWrite(pHead(p));
+  Print("P2  ");
+  pWrite(pHead(strat->S[i]));
+  Print("M1  ");
+  pWrite(m1);
+  Print("M2  ");
+  pWrite(m2);
+#endif
+  // get multiplied signatures for testing
+  pSigMult = currRing->p_Procs->pp_Mult_mm(pSigMult,m1,currRing);
+  pSigMultNegSev = ~p_GetShortExpVector(pSigMult,currRing);
+  sSigMult = currRing->p_Procs->pp_Mult_mm(sSigMult,m2,currRing);
+  sSigMultNegSev = ~p_GetShortExpVector(sSigMult,currRing);
+
+//#if 1
+#ifdef DEBUGF5
+  Print("----------------\n");
+  pWrite(pSigMult);
+  pWrite(sSigMult);
+  Print("----------------\n");
+  Lp.checked  = 0;
+#endif
+  int sigCmp = p_LmCmp(pSigMult,sSigMult,currRing);
+//#if 1
+#if DEBUGF5
+  Print("IN PAIR GENERATION - COMPARING SIGS: %d\n",sigCmp);
+  pWrite(pSigMult);
+  pWrite(sSigMult);
+#endif
+  if(sigCmp==0)
+  {
+    // printf("!!!!   EQUAL SIGS   !!!!\n");
+    // pSig = sSig, delete element due to Rewritten Criterion
+    pDelete(&pSigMult);
+    pDelete(&sSigMult);
+    pLmFree(Lp.lcm);
+    Lp.lcm=NULL;
+    pDelete (&m1);
+    pDelete (&m2);
+    return;
+  }
+  // testing by syzCrit = F5 Criterion
+  // testing by rewCrit1 = Rewritten Criterion
+  // NOTE: Arri's Rewritten Criterion is tested below, we need Lp.p for it!
+  if  ( strat->syzCrit(pSigMult,pSigMultNegSev,strat) ||
+        strat->syzCrit(sSigMult,sSigMultNegSev,strat)
+        || strat->rewCrit1(sSigMult,sSigMultNegSev,Lp.lcm,strat,i+1)
+      )
+  {
+    pDelete(&pSigMult);
+    pDelete(&sSigMult);
+    pLmFree(Lp.lcm);
+    Lp.lcm=NULL;
+    pDelete (&m1);
+    pDelete (&m2);
+    return;
+  }
+  /*
+  *the pair (S[i],p) enters B if the spoly != 0
+  */
+  /*-  compute the short s-polynomial -*/
+  if (strat->fromT && !TEST_OPT_INTSTRATEGY)
+    pNorm(p);
+
+  if ((strat->S[i]==NULL) || (p==NULL))
+    return;
+
+  if ((strat->fromQ!=NULL) && (isFromQ!=0) && (strat->fromQ[i]!=0))
+    Lp.p=NULL;
+  else
+  {
+    #ifdef HAVE_PLURAL
+    if ( rIsPluralRing(currRing) )
+    {
+      if(pHasNotCF(p, strat->S[i]))
+      {
+         if(ncRingType(currRing) == nc_lie)
+         {
+             // generalized prod-crit for lie-type
+             strat->cp++;
+             Lp.p = nc_p_Bracket_qq(pCopy(p),strat->S[i], currRing);
+         }
+         else
+        if( ALLOW_PROD_CRIT(strat) )
+        {
+            // product criterion for homogeneous case in SCA
+            strat->cp++;
+            Lp.p = NULL;
+        }
+        else
+        {
+          Lp.p = // nc_CreateSpoly(strat->S[i],p,currRing);
+                nc_CreateShortSpoly(strat->S[i], p, currRing);
+
+          assume(pNext(Lp.p)==NULL); // TODO: this may be violated whenever ext.prod.crit. for Lie alg. is used
+          pNext(Lp.p) = strat->tail; // !!!
+        }
+      }
+      else
+      {
+        Lp.p = // nc_CreateSpoly(strat->S[i],p,currRing);
+              nc_CreateShortSpoly(strat->S[i], p, currRing);
+
+        assume(pNext(Lp.p)==NULL); // TODO: this may be violated whenever ext.prod.crit. for Lie alg. is used
+        pNext(Lp.p) = strat->tail; // !!!
+
+      }
+
+
+#if MYTEST
+      if (TEST_OPT_DEBUG)
+      {
+        PrintS("enterOnePairNormal::\n strat->S[i]: "); pWrite(strat->S[i]);
+        PrintS("p: "); pWrite(p);
+        PrintS("SPoly: "); pWrite(Lp.p);
+      }
+#endif
+
+    }
+    else
+    #endif
+    {
+      assume(!rIsPluralRing(currRing));
+      Lp.p = ksCreateShortSpoly(strat->S[i], p, strat->tailRing);
+#if MYTEST
+      if (TEST_OPT_DEBUG)
+      {
+        PrintS("enterOnePairNormal::\n strat->S[i]: "); pWrite(strat->S[i]);
+        PrintS("p: "); pWrite(p);
+        PrintS("commutative SPoly: "); pWrite(Lp.p);
+      }
+#endif
+
+      }
+  }
+  // store from which element this pair comes from for further tests
+  //Lp.from = strat->sl+1;
+  if(sigCmp==currRing->OrdSgn)
+  {
+    // pSig > sSig
+    pDelete (&sSigMult);
+    Lp.sig    = pSigMult;
+    Lp.sevSig = ~pSigMultNegSev;
+  }
+  else
+  {
+    // pSig < sSig
+    pDelete (&pSigMult);
+    Lp.sig    = sSigMult;
+    Lp.sevSig = ~sSigMultNegSev;
+  }
+  if (Lp.p == NULL)
+  {
+    if (Lp.lcm!=NULL) pLmFree(Lp.lcm);
+    int pos = posInSyz(strat, Lp.sig);
+    enterSyz(Lp, strat, pos);
+  }
+  else
+  {
+    // testing by rewCrit3 = Arris Rewritten Criterion (for F5 nothing happens!)
+    if (strat->rewCrit3(Lp.sig,~Lp.sevSig,Lp.p,strat,strat->sl+1)) {
+      pLmFree(Lp.lcm);
+      pDelete(&Lp.sig);
+      Lp.lcm=NULL;
+      pDelete (&m1);
+      pDelete (&m2);
+      return;
+    }
+    // in any case Lp is checked up to the next strat->P which is added
+    // to S right after this critical pair creation.
+    // NOTE: this even holds if the 2nd generator gives the bigger signature
+    //       moreover, this improves rewCriterion,
+    //       i.e. strat->checked > strat->from if and only if the 2nd generator
+    //       gives the bigger signature.
+    Lp.checked = strat->sl+1;
+    // at this point it is clear that the pair will be added to L, since it has
+    // passed all tests up to now
+
+  // adds buchberger's first criterion
+    if (pLmCmp(m2,pHead(p)) == 0) {
+      Lp.prod_crit = TRUE; // Product Criterion
+#if 0
+      int pos = posInSyz(strat, Lp.sig);
+      enterSyz(Lp, strat, pos);
+      Lp.lcm=NULL;
+      pDelete (&m1);
+      pDelete (&m2);
+      return;
+#endif
+    }
+    pDelete (&m1);
+    pDelete (&m2);
+#if DEBUGF5
+    PrintS("SIGNATURE OF PAIR:  ");
+    pWrite(Lp.sig);
+#endif
+    /*- the pair (S[i],p) enters B -*/
+    Lp.p1 = strat->S[i];
+    Lp.p2 = p;
+
+    if (
+        (!rIsPluralRing(currRing))
+//      ||  (rIsPluralRing(currRing) && (ncRingType(currRing) != nc_lie))
+       )
+    {
+      assume(pNext(Lp.p)==NULL); // TODO: this may be violated whenever ext.prod.crit. for Lie alg. is used
+      pNext(Lp.p) = strat->tail; // !!!
+    }
+
+    if (atR >= 0)
+    {
+      Lp.i_r1 = strat->S_2_R[i];
+      Lp.i_r2 = atR;
+    }
+    else
+    {
+      Lp.i_r1 = -1;
+      Lp.i_r2 = -1;
+    }
+    strat->initEcartPair(&Lp,strat->S[i],p,strat->ecartS[i],ecart);
+
+    if (TEST_OPT_INTSTRATEGY)
+    {
+      if (!rIsPluralRing(currRing))
+        nDelete(&(Lp.p->coef));
+    }
+
+    l = strat->posInLSba(strat->B,strat->Bl,&Lp,strat);
+    enterL(&strat->B,&strat->Bl,&strat->Bmax,Lp,l);
+  }
+}
+
+/*2
+* put the pair (s[i],p) into the set L, ecart=ecart(p)
+* in the case that s forms a SB of (s)
+*/
+void enterOnePairSpecial (int i,poly p,int ecart,kStrategy strat, int atR = -1)
+{
+  //PrintS("try ");wrp(strat->S[i]);PrintS(" and ");wrp(p);PrintLn();
+  if(pHasNotCF(p,strat->S[i]))
+  {
+    //PrintS("prod-crit\n");
+    if(ALLOW_PROD_CRIT(strat))
+    {
+      //PrintS("prod-crit\n");
+      strat->cp++;
+      return;
+    }
+  }
+
+  int      l,j,compare;
+  LObject  Lp;
+  Lp.i_r = -1;
+
+  Lp.lcm = pInit();
+  pLcm(p,strat->S[i],Lp.lcm);
+  pSetm(Lp.lcm);
+  for(j = strat->Ll;j>=0;j--)
+  {
+    compare=pDivComp(strat->L[j].lcm,Lp.lcm);
+    if ((compare==1) || (pLmEqual(strat->L[j].lcm,Lp.lcm)))
+    {
+      //PrintS("c3-crit\n");
+      strat->c3++;
+      pLmFree(Lp.lcm);
+      return;
+    }
+    else if (compare ==-1)
+    {
+      //Print("c3-crit with L[%d]\n",j);
+      deleteInL(strat->L,&strat->Ll,j,strat);
+      strat->c3++;
+    }
+  }
+  /*-  compute the short s-polynomial -*/
+
+  #ifdef HAVE_PLURAL
+  if (rIsPluralRing(currRing))
+  {
+    Lp.p = nc_CreateShortSpoly(strat->S[i],p, currRing); // ??? strat->tailRing?
+  }
+  else
+  #endif
+    Lp.p = ksCreateShortSpoly(strat->S[i],p,strat->tailRing);
+
+  if (Lp.p == NULL)
+  {
+     //PrintS("short spoly==NULL\n");
+     pLmFree(Lp.lcm);
+  }
+  else
+  {
+    /*- the pair (S[i],p) enters L -*/
+    Lp.p1 = strat->S[i];
+    Lp.p2 = p;
+    if (atR >= 0)
+    {
+      Lp.i_r1 = strat->S_2_R[i];
+      Lp.i_r2 = atR;
+    }
+    else
+    {
+      Lp.i_r1 = -1;
+      Lp.i_r2 = -1;
+    }
+    assume(pNext(Lp.p) == NULL);
+    pNext(Lp.p) = strat->tail;
+    strat->initEcartPair(&Lp,strat->S[i],p,strat->ecartS[i],ecart);
+    if (TEST_OPT_INTSTRATEGY)
+    {
+      nDelete(&(Lp.p->coef));
+    }
+    l = strat->posInL(strat->L,strat->Ll,&Lp,strat);
+    //Print("-> L[%d]\n",l);
+    enterL(&strat->L,&strat->Ll,&strat->Lmax,Lp,l);
+  }
+}
+
+/*2
+* merge set B into L
+*/
+void kMergeBintoL(kStrategy strat)
+{
+  int j=strat->Ll+strat->Bl+1;
+  if (j>strat->Lmax)
+  {
+    j=((j+setmaxLinc-1)/setmaxLinc)*setmaxLinc;
+    strat->L = (LSet)omReallocSize(strat->L,strat->Lmax*sizeof(LObject),
+                                 j*sizeof(LObject));
+    strat->Lmax=j;
+  }
+  j = strat->Ll;
+  int i;
+  for (i=strat->Bl; i>=0; i--)
+  {
+    j = strat->posInL(strat->L,j,&(strat->B[i]),strat);
+    enterL(&strat->L,&strat->Ll,&strat->Lmax,strat->B[i],j);
+  }
+  strat->Bl = -1;
+}
+
+/*2
+* merge set B into L
+*/
+void kMergeBintoLSba(kStrategy strat)
+{
+  int j=strat->Ll+strat->Bl+1;
+  if (j>strat->Lmax)
+  {
+    j=((j+setmaxLinc-1)/setmaxLinc)*setmaxLinc;
+    strat->L = (LSet)omReallocSize(strat->L,strat->Lmax*sizeof(LObject),
+                                 j*sizeof(LObject));
+    strat->Lmax=j;
+  }
+  j = strat->Ll;
+  int i;
+  for (i=strat->Bl; i>=0; i--)
+  {
+    j = strat->posInLSba(strat->L,j,&(strat->B[i]),strat);
+    enterL(&strat->L,&strat->Ll,&strat->Lmax,strat->B[i],j);
+  }
+  strat->Bl = -1;
+}
+/*2
+*the pairset B of pairs of type (s[i],p) is complete now. It will be updated
+*using the chain-criterion in B and L and enters B to L
+*/
+void chainCritNormal (poly p,int ecart,kStrategy strat)
+{
+  int i,j,l;
+
+  /*
+  *pairtest[i] is TRUE if spoly(S[i],p) == 0.
+  *In this case all elements in B such
+  *that their lcm is divisible by the leading term of S[i] can be canceled
+  */
+  if (strat->pairtest!=NULL)
+  {
+    {
+      /*- i.e. there is an i with pairtest[i]==TRUE -*/
+      for (j=0; j<=strat->sl; j++)
+      {
+        if (strat->pairtest[j])
+        {
+          for (i=strat->Bl; i>=0; i--)
+          {
+            if (pDivisibleBy(strat->S[j],strat->B[i].lcm))
+            {
+              deleteInL(strat->B,&strat->Bl,i,strat);
+              strat->c3++;
+            }
+          }
+        }
+      }
+    }
+    omFreeSize(strat->pairtest,(strat->sl+2)*sizeof(BOOLEAN));
+    strat->pairtest=NULL;
+  }
+  if (strat->Gebauer || strat->fromT)
+  {
+    if (strat->sugarCrit)
+    {
+    /*
+    *suppose L[j] == (s,r) and p/lcm(s,r)
+    *and lcm(s,r)#lcm(s,p) and lcm(s,r)#lcm(r,p)
+    *and in case the sugar is o.k. then L[j] can be canceled
+    */
+      for (j=strat->Ll; j>=0; j--)
+      {
+        if (sugarDivisibleBy(ecart,strat->L[j].ecart)
+        && ((pNext(strat->L[j].p) == strat->tail) || (rHasGlobalOrdering(currRing)))
+        && pCompareChain(p,strat->L[j].p1,strat->L[j].p2,strat->L[j].lcm))
+        {
+          if (strat->L[j].p == strat->tail)
+          {
+              deleteInL(strat->L,&strat->Ll,j,strat);
+              strat->c3++;
+          }
+        }
+      }
+      /*
+      *this is GEBAUER-MOELLER:
+      *in B all elements with the same lcm except the "best"
+      *(i.e. the last one in B with this property) will be canceled
+      */
+      j = strat->Bl;
+      loop /*cannot be changed into a for !!! */
+      {
+        if (j <= 0) break;
+        i = j-1;
+        loop
+        {
+          if (i <  0) break;
+          if (pLmEqual(strat->B[j].lcm,strat->B[i].lcm))
+          {
+            strat->c3++;
+            if (sugarDivisibleBy(strat->B[j].ecart,strat->B[i].ecart))
+            {
+              deleteInL(strat->B,&strat->Bl,i,strat);
+              j--;
+            }
+            else
+            {
+              deleteInL(strat->B,&strat->Bl,j,strat);
+              break;
+            }
+          }
+          i--;
+        }
+        j--;
+      }
+    }
+    else /*sugarCrit*/
+    {
+      /*
+      *suppose L[j] == (s,r) and p/lcm(s,r)
+      *and lcm(s,r)#lcm(s,p) and lcm(s,r)#lcm(r,p)
+      *and in case the sugar is o.k. then L[j] can be canceled
+      */
+      for (j=strat->Ll; j>=0; j--)
+      {
+        if (pCompareChain(p,strat->L[j].p1,strat->L[j].p2,strat->L[j].lcm))
+        {
+          if ((pNext(strat->L[j].p) == strat->tail)||(rHasGlobalOrdering(currRing)))
+          {
+            deleteInL(strat->L,&strat->Ll,j,strat);
+            strat->c3++;
+          }
+        }
+      }
+      /*
+      *this is GEBAUER-MOELLER:
+      *in B all elements with the same lcm except the "best"
+      *(i.e. the last one in B with this property) will be canceled
+      */
+      j = strat->Bl;
+      loop   /*cannot be changed into a for !!! */
+      {
+        if (j <= 0) break;
+        for(i=j-1; i>=0; i--)
+        {
+          if (pLmEqual(strat->B[j].lcm,strat->B[i].lcm))
+          {
+            strat->c3++;
+            deleteInL(strat->B,&strat->Bl,i,strat);
+            j--;
+          }
+        }
+        j--;
+      }
+    }
+    /*
+    *the elements of B enter L
+    */
+    kMergeBintoL(strat);
+  }
+  else
+  {
+    for (j=strat->Ll; j>=0; j--)
+    {
+      if (pCompareChain(p,strat->L[j].p1,strat->L[j].p2,strat->L[j].lcm))
+      {
+        if ((pNext(strat->L[j].p) == strat->tail)||(rHasGlobalOrdering(currRing)))
+        {
+          deleteInL(strat->L,&strat->Ll,j,strat);
+          strat->c3++;
+        }
+      }
+    }
+    /*
+    *this is our MODIFICATION of GEBAUER-MOELLER:
+    *First the elements of B enter L,
+    *then we fix a lcm and the "best" element in L
+    *(i.e the last in L with this lcm and of type (s,p))
+    *and cancel all the other elements of type (r,p) with this lcm
+    *except the case the element (s,r) has also the same lcm
+    *and is on the worst position with respect to (s,p) and (r,p)
+    */
+    /*
+    *B enters to L/their order with respect to B is permutated for elements
+    *B[i].p with the same leading term
+    */
+    kMergeBintoL(strat);
+    j = strat->Ll;
+    loop  /*cannot be changed into a for !!! */
+    {
+      if (j <= 0)
+      {
+        /*now L[0] cannot be canceled any more and the tail can be removed*/
+        if (strat->L[0].p2 == strat->tail) strat->L[0].p2 = p;
+        break;
+      }
+      if (strat->L[j].p2 == p)
+      {
+        i = j-1;
+        loop
+        {
+          if (i < 0)  break;
+          if ((strat->L[i].p2 == p) && pLmEqual(strat->L[j].lcm,strat->L[i].lcm))
+          {
+            /*L[i] could be canceled but we search for a better one to cancel*/
+            strat->c3++;
+            if (isInPairsetL(i-1,strat->L[j].p1,strat->L[i].p1,&l,strat)
+            && (pNext(strat->L[l].p) == strat->tail)
+            && (!pLmEqual(strat->L[i].p,strat->L[l].p))
+            && pDivisibleBy(p,strat->L[l].lcm))
+            {
+              /*
+              *"NOT equal(...)" because in case of "equal" the element L[l]
+              *is "older" and has to be from theoretical point of view behind
+              *L[i], but we do not want to reorder L
+              */
+              strat->L[i].p2 = strat->tail;
+              /*
+              *L[l] will be canceled, we cannot cancel L[i] later on,
+              *so we mark it with "tail"
+              */
+              deleteInL(strat->L,&strat->Ll,l,strat);
+              i--;
+            }
+            else
+            {
+              deleteInL(strat->L,&strat->Ll,i,strat);
+            }
+            j--;
+          }
+          i--;
+        }
+      }
+      else if (strat->L[j].p2 == strat->tail)
+      {
+        /*now L[j] cannot be canceled any more and the tail can be removed*/
+        strat->L[j].p2 = p;
+      }
+      j--;
+    }
+  }
+}
+/*2
+*the pairset B of pairs of type (s[i],p) is complete now. It will be updated
+*using the chain-criterion in B and L and enters B to L
+*/
+void chainCritSig (poly p,int /*ecart*/,kStrategy strat)
+{
+  int i,j,l;
+  kMergeBintoLSba(strat);
+  j = strat->Ll;
+  loop  /*cannot be changed into a for !!! */
+  {
+    if (j <= 0)
+    {
+      /*now L[0] cannot be canceled any more and the tail can be removed*/
+      if (strat->L[0].p2 == strat->tail) strat->L[0].p2 = p;
+      break;
+    }
+    if (strat->L[j].p2 == p)
+    {
+      i = j-1;
+      loop
+      {
+        if (i < 0)  break;
+        if ((strat->L[i].p2 == p) && pLmEqual(strat->L[j].lcm,strat->L[i].lcm))
+        {
+          /*L[i] could be canceled but we search for a better one to cancel*/
+          strat->c3++;
+          if (isInPairsetL(i-1,strat->L[j].p1,strat->L[i].p1,&l,strat)
+              && (pNext(strat->L[l].p) == strat->tail)
+              && (!pLmEqual(strat->L[i].p,strat->L[l].p))
+              && pDivisibleBy(p,strat->L[l].lcm))
+          {
+            /*
+             *"NOT equal(...)" because in case of "equal" the element L[l]
+             *is "older" and has to be from theoretical point of view behind
+             *L[i], but we do not want to reorder L
+             */
+            strat->L[i].p2 = strat->tail;
+            /*
+             *L[l] will be canceled, we cannot cancel L[i] later on,
+             *so we mark it with "tail"
+             */
+            deleteInL(strat->L,&strat->Ll,l,strat);
+            i--;
+          }
+          else
+          {
+            deleteInL(strat->L,&strat->Ll,i,strat);
+          }
+          j--;
+        }
+        i--;
+      }
+    }
+    else if (strat->L[j].p2 == strat->tail)
+    {
+      /*now L[j] cannot be canceled any more and the tail can be removed*/
+      strat->L[j].p2 = p;
+    }
+    j--;
+  }
+}
+#ifdef HAVE_RATGRING
+void chainCritPart (poly p,int ecart,kStrategy strat)
+{
+  int i,j,l;
+
+  /*
+  *pairtest[i] is TRUE if spoly(S[i],p) == 0.
+  *In this case all elements in B such
+  *that their lcm is divisible by the leading term of S[i] can be canceled
+  */
+  if (strat->pairtest!=NULL)
+  {
+    {
+      /*- i.e. there is an i with pairtest[i]==TRUE -*/
+      for (j=0; j<=strat->sl; j++)
+      {
+        if (strat->pairtest[j])
+        {
+          for (i=strat->Bl; i>=0; i--)
+          {
+            if (_p_LmDivisibleByPart(strat->S[j],currRing,
+               strat->B[i].lcm,currRing,
+               currRing->real_var_start,currRing->real_var_end))
+            {
+              if(TEST_OPT_DEBUG)
+              {
+                 Print("chain-crit-part: S[%d]=",j);
+                 p_wrp(strat->S[j],currRing);
+                 Print(" divide B[%d].lcm=",i);
+                 p_wrp(strat->B[i].lcm,currRing);
+                 PrintLn();
+              }
+              deleteInL(strat->B,&strat->Bl,i,strat);
+              strat->c3++;
+            }
+          }
+        }
+      }
+    }
+    omFreeSize(strat->pairtest,(strat->sl+2)*sizeof(BOOLEAN));
+    strat->pairtest=NULL;
+  }
+  if (strat->Gebauer || strat->fromT)
+  {
+    if (strat->sugarCrit)
+    {
+    /*
+    *suppose L[j] == (s,r) and p/lcm(s,r)
+    *and lcm(s,r)#lcm(s,p) and lcm(s,r)#lcm(r,p)
+    *and in case the sugar is o.k. then L[j] can be canceled
+    */
+      for (j=strat->Ll; j>=0; j--)
+      {
+        if (sugarDivisibleBy(ecart,strat->L[j].ecart)
+        && ((pNext(strat->L[j].p) == strat->tail) || (rHasGlobalOrdering(currRing)))
+        && pCompareChainPart(p,strat->L[j].p1,strat->L[j].p2,strat->L[j].lcm))
+        {
+          if (strat->L[j].p == strat->tail)
+          {
+              if(TEST_OPT_DEBUG)
+              {
+                 PrintS("chain-crit-part: pCompareChainPart p=");
+                 p_wrp(p,currRing);
+                 Print(" delete L[%d]",j);
+                 p_wrp(strat->L[j].lcm,currRing);
+                 PrintLn();
+              }
+              deleteInL(strat->L,&strat->Ll,j,strat);
+              strat->c3++;
+          }
+        }
+      }
+      /*
+      *this is GEBAUER-MOELLER:
+      *in B all elements with the same lcm except the "best"
+      *(i.e. the last one in B with this property) will be canceled
+      */
+      j = strat->Bl;
+      loop /*cannot be changed into a for !!! */
+      {
+        if (j <= 0) break;
+        i = j-1;
+        loop
+        {
+          if (i <  0) break;
+          if (pLmEqual(strat->B[j].lcm,strat->B[i].lcm))
+          {
+            strat->c3++;
+            if (sugarDivisibleBy(strat->B[j].ecart,strat->B[i].ecart))
+            {
+              if(TEST_OPT_DEBUG)
+              {
+                 Print("chain-crit-part: sugar B[%d].lcm=",j);
+                 p_wrp(strat->B[j].lcm,currRing);
+                 Print(" delete B[%d]",i);
+                 p_wrp(strat->B[i].lcm,currRing);
+                 PrintLn();
+              }
+              deleteInL(strat->B,&strat->Bl,i,strat);
+              j--;
+            }
+            else
+            {
+              if(TEST_OPT_DEBUG)
+              {
+                 Print("chain-crit-part: sugar B[%d].lcm=",i);
+                 p_wrp(strat->B[i].lcm,currRing);
+                 Print(" delete B[%d]",j);
+                 p_wrp(strat->B[j].lcm,currRing);
+                 PrintLn();
+              }
+              deleteInL(strat->B,&strat->Bl,j,strat);
+              break;
+            }
+          }
+          i--;
+        }
+        j--;
+      }
+    }
+    else /*sugarCrit*/
+    {
+      /*
+      *suppose L[j] == (s,r) and p/lcm(s,r)
+      *and lcm(s,r)#lcm(s,p) and lcm(s,r)#lcm(r,p)
+      *and in case the sugar is o.k. then L[j] can be canceled
+      */
+      for (j=strat->Ll; j>=0; j--)
+      {
+        if (pCompareChainPart(p,strat->L[j].p1,strat->L[j].p2,strat->L[j].lcm))
+        {
+          if ((pNext(strat->L[j].p) == strat->tail)||(rHasGlobalOrdering(currRing)))
+          {
+              if(TEST_OPT_DEBUG)
+              {
+                 PrintS("chain-crit-part: sugar:pCompareChainPart p=");
+                 p_wrp(p,currRing);
+                 Print(" delete L[%d]",j);
+                 p_wrp(strat->L[j].lcm,currRing);
+                 PrintLn();
+              }
+            deleteInL(strat->L,&strat->Ll,j,strat);
+            strat->c3++;
+          }
+        }
+      }
+      /*
+      *this is GEBAUER-MOELLER:
+      *in B all elements with the same lcm except the "best"
+      *(i.e. the last one in B with this property) will be canceled
+      */
+      j = strat->Bl;
+      loop   /*cannot be changed into a for !!! */
+      {
+        if (j <= 0) break;
+        for(i=j-1; i>=0; i--)
+        {
+          if (pLmEqual(strat->B[j].lcm,strat->B[i].lcm))
+          {
+              if(TEST_OPT_DEBUG)
+              {
+                 Print("chain-crit-part: equal lcm B[%d].lcm=",j);
+                 p_wrp(strat->B[j].lcm,currRing);
+                 Print(" delete B[%d]\n",i);
+              }
+            strat->c3++;
+            deleteInL(strat->B,&strat->Bl,i,strat);
+            j--;
+          }
+        }
+        j--;
+      }
+    }
+    /*
+    *the elements of B enter L
+    */
+    kMergeBintoL(strat);
+  }
+  else
+  {
+    for (j=strat->Ll; j>=0; j--)
+    {
+      if (pCompareChainPart(p,strat->L[j].p1,strat->L[j].p2,strat->L[j].lcm))
+      {
+        if ((pNext(strat->L[j].p) == strat->tail)||(rHasGlobalOrdering(currRing)))
+        {
+              if(TEST_OPT_DEBUG)
+              {
+                 PrintS("chain-crit-part: pCompareChainPart p=");
+                 p_wrp(p,currRing);
+                 Print(" delete L[%d]",j);
+                 p_wrp(strat->L[j].lcm,currRing);
+                 PrintLn();
+              }
+          deleteInL(strat->L,&strat->Ll,j,strat);
+          strat->c3++;
+        }
+      }
+    }
+    /*
+    *this is our MODIFICATION of GEBAUER-MOELLER:
+    *First the elements of B enter L,
+    *then we fix a lcm and the "best" element in L
+    *(i.e the last in L with this lcm and of type (s,p))
+    *and cancel all the other elements of type (r,p) with this lcm
+    *except the case the element (s,r) has also the same lcm
+    *and is on the worst position with respect to (s,p) and (r,p)
+    */
+    /*
+    *B enters to L/their order with respect to B is permutated for elements
+    *B[i].p with the same leading term
+    */
+    kMergeBintoL(strat);
+    j = strat->Ll;
+    loop  /*cannot be changed into a for !!! */
+    {
+      if (j <= 0)
+      {
+        /*now L[0] cannot be canceled any more and the tail can be removed*/
+        if (strat->L[0].p2 == strat->tail) strat->L[0].p2 = p;
+        break;
+      }
+      if (strat->L[j].p2 == p)
+      {
+        i = j-1;
+        loop
+        {
+          if (i < 0)  break;
+          if ((strat->L[i].p2 == p) && pLmEqual(strat->L[j].lcm,strat->L[i].lcm))
+          {
+            /*L[i] could be canceled but we search for a better one to cancel*/
+            strat->c3++;
+            if (isInPairsetL(i-1,strat->L[j].p1,strat->L[i].p1,&l,strat)
+            && (pNext(strat->L[l].p) == strat->tail)
+            && (!pLmEqual(strat->L[i].p,strat->L[l].p))
+            && _p_LmDivisibleByPart(p,currRing,
+                           strat->L[l].lcm,currRing,
+                           currRing->real_var_start, currRing->real_var_end))
+
+            {
+              /*
+              *"NOT equal(...)" because in case of "equal" the element L[l]
+              *is "older" and has to be from theoretical point of view behind
+              *L[i], but we do not want to reorder L
+              */
+              strat->L[i].p2 = strat->tail;
+              /*
+              *L[l] will be canceled, we cannot cancel L[i] later on,
+              *so we mark it with "tail"
+              */
+              if(TEST_OPT_DEBUG)
+              {
+                 PrintS("chain-crit-part: divisible_by p=");
+                 p_wrp(p,currRing);
+                 Print(" delete L[%d]",l);
+                 p_wrp(strat->L[l].lcm,currRing);
+                 PrintLn();
+              }
+              deleteInL(strat->L,&strat->Ll,l,strat);
+              i--;
+            }
+            else
+            {
+              if(TEST_OPT_DEBUG)
+              {
+                 PrintS("chain-crit-part: divisible_by(2) p=");
+                 p_wrp(p,currRing);
+                 Print(" delete L[%d]",i);
+                 p_wrp(strat->L[i].lcm,currRing);
+                 PrintLn();
+              }
+              deleteInL(strat->L,&strat->Ll,i,strat);
+            }
+            j--;
+          }
+          i--;
+        }
+      }
+      else if (strat->L[j].p2 == strat->tail)
+      {
+        /*now L[j] cannot be canceled any more and the tail can be removed*/
+        strat->L[j].p2 = p;
+      }
+      j--;
+    }
+  }
+}
+#endif
+
+/*2
+*(s[0],h),...,(s[k],h) will be put to the pairset L
+*/
+void initenterpairs (poly h,int k,int ecart,int isFromQ,kStrategy strat, int atR = -1)
+{
+
+  if ((strat->syzComp==0)
+  || (pGetComp(h)<=strat->syzComp))
+  {
+    int j;
+    BOOLEAN new_pair=FALSE;
+
+    if (pGetComp(h)==0)
+    {
+      /* for Q!=NULL: build pairs (f,q),(f1,f2), but not (q1,q2)*/
+      if ((isFromQ)&&(strat->fromQ!=NULL))
+      {
+        for (j=0; j<=k; j++)
+        {
+          if (!strat->fromQ[j])
+          {
+            new_pair=TRUE;
+            strat->enterOnePair(j,h,ecart,isFromQ,strat, atR);
+          //Print("j:%d, Ll:%d\n",j,strat->Ll);
+          }
+        }
+      }
+      else
+      {
+        new_pair=TRUE;
+        for (j=0; j<=k; j++)
+        {
+          #if ADIDEBUG
+          PrintS("\n initenterpairs: \n");
+          PrintS("                ");p_Write(h, strat->tailRing);
+          PrintS("                ");p_Write(strat->S[j],strat->tailRing);
+          #endif
+          strat->enterOnePair(j,h,ecart,isFromQ,strat, atR);
+          //Print("j:%d, Ll:%d\n",j,strat->Ll);
+        }
+      }
+    }
+    else
+    {
+      for (j=0; j<=k; j++)
+      {
+        if ((pGetComp(h)==pGetComp(strat->S[j]))
+        || (pGetComp(strat->S[j])==0))
+        {
+          new_pair=TRUE;
+          strat->enterOnePair(j,h,ecart,isFromQ,strat, atR);
+        //Print("j:%d, Ll:%d\n",j,strat->Ll);
+        }
+      }
+    }
+
+    if (new_pair)
+    {
+#ifdef HAVE_RATGRING
+      if (currRing->real_var_start>0)
+        chainCritPart(h,ecart,strat);
+      else
+#endif
+      strat->chainCrit(h,ecart,strat);
+    }
+  }
+}
+
+/*2
+*(s[0],h),...,(s[k],h) will be put to the pairset L
+*using signatures <= only for signature-based standard basis algorithms
+*/
+void initenterpairsSig (poly h,poly hSig,int hFrom,int k,int ecart,int isFromQ,kStrategy strat, int atR = -1)
+{
+
+  if ((strat->syzComp==0)
+  || (pGetComp(h)<=strat->syzComp))
+  {
+    int j;
+    BOOLEAN new_pair=FALSE;
+
+    if (pGetComp(h)==0)
+    {
+      /* for Q!=NULL: build pairs (f,q),(f1,f2), but not (q1,q2)*/
+      if ((isFromQ)&&(strat->fromQ!=NULL))
+      {
+        for (j=0; j<=k; j++)
+        {
+          if (!strat->fromQ[j])
+          {
+            new_pair=TRUE;
+            enterOnePairSig(j,h,hSig,hFrom,ecart,isFromQ,strat, atR);
+          //Print("j:%d, Ll:%d\n",j,strat->Ll);
+          }
+        }
+      }
+      else
+      {
+        new_pair=TRUE;
+        for (j=0; j<=k; j++)
+        {
+          enterOnePairSig(j,h,hSig,hFrom,ecart,isFromQ,strat, atR);
+          //Print("j:%d, Ll:%d\n",j,strat->Ll);
+        }
+      }
+    }
+    else
+    {
+      for (j=0; j<=k; j++)
+      {
+        if ((pGetComp(h)==pGetComp(strat->S[j]))
+        || (pGetComp(strat->S[j])==0))
+        {
+          new_pair=TRUE;
+          enterOnePairSig(j,h,hSig,hFrom,ecart,isFromQ,strat, atR);
+        //Print("j:%d, Ll:%d\n",j,strat->Ll);
+        }
+      }
+    }
+
+    if (new_pair)
+    {
+#ifdef HAVE_RATGRING
+      if (currRing->real_var_start>0)
+        chainCritPart(h,ecart,strat);
+      else
+#endif
+      strat->chainCrit(h,ecart,strat);
+    }
+  }
+}
+
+#ifdef HAVE_RINGS
+/*2
+*the pairset B of pairs of type (s[i],p) is complete now. It will be updated
+*using the chain-criterion in B and L and enters B to L
+*/
+void chainCritRing (poly p,int, kStrategy strat)
+{
+  int i,j,l;
+  /*
+  *pairtest[i] is TRUE if spoly(S[i],p) == 0.
+  *In this case all elements in B such
+  *that their lcm is divisible by the leading term of S[i] can be canceled
+  */
+  if (strat->pairtest!=NULL)
+  {
+    {
+      /*- i.e. there is an i with pairtest[i]==TRUE -*/
+      for (j=0; j<=strat->sl; j++)
+      {
+        if (strat->pairtest[j])
+        {
+          for (i=strat->Bl; i>=0; i--)
+          {
+            if (pDivisibleBy(strat->S[j],strat->B[i].lcm))
+            {
+#ifdef KDEBUG
+              if (TEST_OPT_DEBUG)
+              {
+                PrintS("--- chain criterion func chainCritRing type 1\n");
+                PrintS("strat->S[j]:");
+                wrp(strat->S[j]);
+                PrintS("  strat->B[i].lcm:");
+                wrp(strat->B[i].lcm);
+                PrintLn();
+              }
+#endif
+              deleteInL(strat->B,&strat->Bl,i,strat);
+              strat->c3++;
+            }
+          }
+        }
+      }
+    }
+    omFreeSize(strat->pairtest,(strat->sl+2)*sizeof(BOOLEAN));
+    strat->pairtest=NULL;
+  }
+  assume(!(strat->Gebauer || strat->fromT));
+  for (j=strat->Ll; j>=0; j--)
+  {
+    if ((strat->L[j].lcm != NULL) && n_DivBy(pGetCoeff(strat->L[j].lcm), pGetCoeff(p), currRing->cf))
+    {
+      if (pCompareChain(p,strat->L[j].p1,strat->L[j].p2,strat->L[j].lcm))
+      {
+        if ((pNext(strat->L[j].p) == strat->tail) || (rHasGlobalOrdering(currRing)))
+        {
+          deleteInL(strat->L,&strat->Ll,j,strat);
+          strat->c3++;
+#ifdef KDEBUG
+              if (TEST_OPT_DEBUG)
+              {
+                PrintS("--- chain criterion func chainCritRing type 2\n");
+                PrintS("strat->L[j].p:");
+                wrp(strat->L[j].p);
+                PrintS("  p:");
+                wrp(p);
+                PrintLn();
+              }
+#endif
+        }
+      }
+    }
+  }
+  /*
+  *this is our MODIFICATION of GEBAUER-MOELLER:
+  *First the elements of B enter L,
+  *then we fix a lcm and the "best" element in L
+  *(i.e the last in L with this lcm and of type (s,p))
+  *and cancel all the other elements of type (r,p) with this lcm
+  *except the case the element (s,r) has also the same lcm
+  *and is on the worst position with respect to (s,p) and (r,p)
+  */
+  /*
+  *B enters to L/their order with respect to B is permutated for elements
+  *B[i].p with the same leading term
+  */
+  kMergeBintoL(strat);
+  j = strat->Ll;
+  loop  /*cannot be changed into a for !!! */
+  {
+    if (j <= 0)
+    {
+      /*now L[0] cannot be canceled any more and the tail can be removed*/
+      if (strat->L[0].p2 == strat->tail) strat->L[0].p2 = p;
+      break;
+    }
+    if (strat->L[j].p2 == p) // Was the element added from B?
+    {
+      i = j-1;
+      loop
+      {
+        if (i < 0)  break;
+        // Element is from B and has the same lcm as L[j]
+        if ((strat->L[i].p2 == p) && n_DivBy(pGetCoeff(strat->L[j].lcm), pGetCoeff(strat->L[i].lcm), currRing->cf)
+             && pLmEqual(strat->L[j].lcm,strat->L[i].lcm))
+        {
+          /*L[i] could be canceled but we search for a better one to cancel*/
+          strat->c3++;
+#ifdef KDEBUG
+          if (TEST_OPT_DEBUG)
+          {
+            PrintS("--- chain criterion func chainCritRing type 3\n");
+            PrintS("strat->L[j].lcm:");
+            wrp(strat->L[j].lcm);
+            PrintS("  strat->L[i].lcm:");
+            wrp(strat->L[i].lcm);
+            PrintLn();
+          }
+#endif
+          if (isInPairsetL(i-1,strat->L[j].p1,strat->L[i].p1,&l,strat)
+          && (pNext(strat->L[l].p) == strat->tail)
+          && (!pLmEqual(strat->L[i].p,strat->L[l].p))
+          && pDivisibleBy(p,strat->L[l].lcm))
+          {
+            /*
+            *"NOT equal(...)" because in case of "equal" the element L[l]
+            *is "older" and has to be from theoretical point of view behind
+            *L[i], but we do not want to reorder L
+            */
+            strat->L[i].p2 = strat->tail;
+            /*
+            *L[l] will be canceled, we cannot cancel L[i] later on,
+            *so we mark it with "tail"
+            */
+            deleteInL(strat->L,&strat->Ll,l,strat);
+            i--;
+          }
+          else
+          {
+            deleteInL(strat->L,&strat->Ll,i,strat);
+          }
+          j--;
+        }
+        i--;
+      }
+    }
+    else if (strat->L[j].p2 == strat->tail)
+    {
+      /*now L[j] cannot be canceled any more and the tail can be removed*/
+      strat->L[j].p2 = p;
+    }
+    j--;
+  }
+}
+#endif
+
+#ifdef HAVE_RINGS
+long ind2(long arg)
+{
+  long ind = 0;
+  if (arg <= 0) return 0;
+  while (arg%2 == 0)
+  {
+    arg = arg / 2;
+    ind++;
+  }
+  return ind;
+}
+
+long ind_fact_2(long arg)
+{
+  long ind = 0;
+  if (arg <= 0) return 0;
+  if (arg%2 == 1) { arg--; }
+  while (arg > 0)
+  {
+    ind += ind2(arg);
+    arg = arg - 2;
+  }
+  return ind;
+}
+#endif
+
+#ifdef HAVE_VANIDEAL
+long twoPow(long arg)
+{
+  return 1L << arg;
+}
+
+/*2
+* put the pair (p, f) in B and f in T
+*/
+void enterOneZeroPairRing (poly f, poly t_p, poly p, int ecart, kStrategy strat, int atR = -1)
+{
+  int      l,j,compare,compareCoeff;
+  LObject  Lp;
+
+  if (strat->interred_flag) return;
+#ifdef KDEBUG
+  Lp.ecart=0; Lp.length=0;
+#endif
+  /*- computes the lcm(s[i],p) -*/
+  Lp.lcm = pInit();
+
+  pLcm(p,f,Lp.lcm);
+  pSetm(Lp.lcm);
+  pSetCoeff(Lp.lcm, nLcm(pGetCoeff(p), pGetCoeff(f), currRing));
+  assume(!strat->sugarCrit);
+  assume(!strat->fromT);
+  /*
+  *the set B collects the pairs of type (S[j],p)
+  *suppose (r,p) is in B and (s,p) is the new pair and lcm(s,p) != lcm(r,p)
+  *if the leading term of s devides lcm(r,p) then (r,p) will be canceled
+  *if the leading term of r devides lcm(s,p) then (s,p) will not enter B
+  */
+  for(j = strat->Bl;j>=0;j--)
+  {
+    compare=pDivCompRing(strat->B[j].lcm,Lp.lcm);
+    compareCoeff = nDivComp(pGetCoeff(strat->B[j].lcm), pGetCoeff(Lp.lcm));
+    if (compareCoeff == 0 || compare == compareCoeff)
+    {
+      if (compare == 1)
+      {
+        strat->c3++;
+        pLmDelete(Lp.lcm);
+        return;
+      }
+      else
+      if (compare == -1)
+      {
+        deleteInL(strat->B,&strat->Bl,j,strat);
+        strat->c3++;
+      }
+    }
+    if (compare == pDivComp_EQUAL)
+    {
+      // Add hint for same LM and direction of LC (later) (TODO Oliver)
+      if (compareCoeff == 1)
+      {
+        strat->c3++;
+        pLmDelete(Lp.lcm);
+        return;
+      }
+      else
+      if (compareCoeff == -1)
+      {
+        deleteInL(strat->B,&strat->Bl,j,strat);
+        strat->c3++;
+      }
+    }
+  }
+  /*
+  *the pair (S[i],p) enters B if the spoly != 0
+  */
+  /*-  compute the short s-polynomial -*/
+  if ((f==NULL) || (p==NULL)) return;
+  pNorm(p);
+  {
+    Lp.p = ksCreateShortSpoly(f, p, strat->tailRing);
+  }
+  if (Lp.p == NULL) //deactivated, as we are adding pairs with zeropoly and not from S
+  {
+    /*- the case that the s-poly is 0 -*/
+//    if (strat->pairtest==NULL) initPairtest(strat);
+//    strat->pairtest[i] = TRUE;/*- hint for spoly(S^[i],p)=0 -*/
+//    strat->pairtest[strat->sl+1] = TRUE;
+    /*hint for spoly(S[i],p) == 0 for some i,0 <= i <= sl*/
+    /*
+    *suppose we have (s,r),(r,p),(s,p) and spoly(s,p) == 0 and (r,p) is
+    *still in B (i.e. lcm(r,p) == lcm(s,p) or the leading term of s does not
+    *devide lcm(r,p)). In the last case (s,r) can be canceled if the leading
+    *term of p devides the lcm(s,r)
+    *(this canceling should be done here because
+    *the case lcm(s,p) == lcm(s,r) is not covered in chainCrit)
+    *the first case is handeled in chainCrit
+    */
+    if (Lp.lcm!=NULL) pLmDelete(Lp.lcm);
+  }
+  else
+  {
+    /*- the pair (S[i],p) enters B -*/
+    Lp.p1 = f;
+    Lp.p2 = p;
+
+    pNext(Lp.p) = strat->tail;
+
+    LObject tmp_h(f, currRing, strat->tailRing);
+    tmp_h.SetShortExpVector();
+    strat->initEcart(&tmp_h);
+    tmp_h.sev = pGetShortExpVector(tmp_h.p);
+    tmp_h.t_p = t_p;
+
+    enterT(tmp_h, strat, strat->tl + 1);
+
+    if (atR >= 0)
+    {
+      Lp.i_r2 = atR;
+      Lp.i_r1 = strat->tl;
+    }
+
+    strat->initEcartPair(&Lp,f,p,0/*strat->ecartS[i]*/,ecart);     // Attention: TODO: break ecart
+    l = strat->posInL(strat->B,strat->Bl,&Lp,strat);
+    enterL(&strat->B, &strat->Bl, &strat->Bmax, Lp, l);
+  }
+}
+
+/* Helper for kCreateZeroPoly
+ * enumerating the exponents
+ring r = 2^2, (a, b, c), lp; ideal G0 = system("createG0"); ideal G = interred(G0); ncols(G0); ncols(G);
+ */
+
+int nextZeroSimplexExponent (long exp[], long ind[], long cexp[], long cind[], long* cabsind, long step[], long bound, long N)
+/* gives the next exponent from the set H_1 */
+{
+  long add = ind2(cexp[1] + 2);
+  if ((*cabsind < bound) && (*cabsind - step[1] + add < bound))
+  {
+    cexp[1] += 2;
+    cind[1] += add;
+    *cabsind += add;
+  }
+  else
+  {
+    // cabsind >= habsind
+    if (N == 1) return 0;
+    int i = 1;
+    while (exp[i] == cexp[i] && i <= N) i++;
+    cexp[i] = exp[i];
+    *cabsind -= cind[i];
+    cind[i] = ind[i];
+    step[i] = 500000;
+    *cabsind += cind[i];
+    // Print("in: %d\n", *cabsind);
+    i += 1;
+    if (i > N) return 0;
+    do
+    {
+      step[1] = 500000;
+      for (int j = i + 1; j <= N; j++)
+      {
+        if (step[1] > step[j]) step[1] = step[j];
+      }
+      add = ind2(cexp[i] + 2);
+      if (*cabsind - step[1] + add >= bound)
+      {
+        cexp[i] = exp[i];
+        *cabsind -= cind[i];
+        cind[i] = ind[i];
+        *cabsind += cind[i];
+        step[i] = 500000;
+        i += 1;
+        if (i > N) return 0;
+      }
+      else step[1] = -1;
+    } while (step[1] != -1);
+    step[1] = 500000;
+    cexp[i] += 2;
+    cind[i] += add;
+    *cabsind += add;
+    if (add < step[i]) step[i] = add;
+    for (i = 2; i <= N; i++)
+    {
+      if (step[1] > step[i]) step[1] = step[i];
+    }
+  }
+  return 1;
+}
+
+/*
+ * Creates the zero Polynomial on position exp
+ * long exp[] : exponent of leading term
+ * cabsind    : total 2-ind of exp (if -1 will be computed)
+ * poly* t_p  : will hold the LT in tailRing
+ * leadRing   : ring for the LT
+ * tailRing   : ring for the tail
+ */
+
+poly kCreateZeroPoly(long exp[], long cabsind, poly* t_p, ring leadRing, ring tailRing)
+{
+
+  poly zeroPoly = NULL;
+
+  number tmp1;
+  poly tmp2, tmp3;
+
+  if (cabsind == -1)
+  {
+    cabsind = 0;
+    for (int i = 1; i <= leadRing->N; i++)
+    {
+      cabsind += ind_fact_2(exp[i]);
+    }
+//    Print("cabsind: %d\n", cabsind);
+  }
+  if (cabsind < leadRing->ch)
+  {
+    zeroPoly = p_ISet(twoPow(leadRing->ch - cabsind), tailRing);
+  }
+  else
+  {
+    zeroPoly = p_ISet(1, tailRing);
+  }
+  for (int i = 1; i <= leadRing->N; i++)
+  {
+    for (long j = 1; j <= exp[i]; j++)
+    {
+      tmp1 = nInit(j);
+      tmp2 = p_ISet(1, tailRing);
+      p_SetExp(tmp2, i, 1, tailRing);
+      p_Setm(tmp2, tailRing);
+      if (nIsZero(tmp1))
+      { // should nowbe obsolet, test ! TODO OLIVER
+        zeroPoly = p_Mult_q(zeroPoly, tmp2, tailRing);
+      }
+      else
+      {
+        tmp3 = p_NSet(nCopy(tmp1), tailRing);
+        zeroPoly = p_Mult_q(zeroPoly, p_Add_q(tmp3, tmp2, tailRing), tailRing);
+      }
+    }
+  }
+  tmp2 = p_NSet(nCopy(pGetCoeff(zeroPoly)), leadRing);
+  for (int i = 1; i <= leadRing->N; i++)
+  {
+    pSetExp(tmp2, i, p_GetExp(zeroPoly, i, tailRing));
+  }
+  p_Setm(tmp2, leadRing);
+  *t_p = zeroPoly;
+  zeroPoly = pNext(zeroPoly);
+  pNext(*t_p) = NULL;
+  pNext(tmp2) = zeroPoly;
+  return tmp2;
+}
+
+// #define OLI_DEBUG
+
+/*
+ * Generate the s-polynomial for the virtual set of zero-polynomials
+ */
+
+void initenterzeropairsRing (poly p, int ecart, kStrategy strat, int atR)
+{
+  // Initialize
+  long exp[50];            // The exponent of \hat{X} (basepoint)
+  long cexp[50];           // The current exponent for iterating over all
+  long ind[50];            // The power of 2 in the i-th component of exp
+  long cind[50];           // analog for cexp
+  long mult[50];           // How to multiply the elements of G
+  long cabsind = 0;        // The abs. index of cexp, i.e. the sum of cind
+  long habsind = 0;        // The abs. index of the coefficient of h
+  long step[50];           // The last increases
+  for (int i = 1; i <= currRing->N; i++)
+  {
+    exp[i] = p_GetExp(p, i, currRing);
+    if (exp[i] & 1 != 0)
+    {
+      exp[i] = exp[i] - 1;
+      mult[i] = 1;
+    }
+    cexp[i] = exp[i];
+    ind[i] = ind_fact_2(exp[i]);
+    cabsind += ind[i];
+    cind[i] = ind[i];
+    step[i] = 500000;
+  }
+  step[1] = 500000;
+  habsind = ind2((long) p_GetCoeff(p, currRing));
+  long bound = currRing->ch - habsind;
+#ifdef OLI_DEBUG
+  PrintS("-------------\npoly  :");
+  wrp(p);
+  Print("\nexp   : (%d, %d)\n", exp[1] + mult[1], exp[2] + mult[1]);
+  Print("cexp  : (%d, %d)\n", cexp[1], cexp[2]);
+  Print("cind  : (%d, %d)\n", cind[1], cind[2]);
+  Print("bound : %d\n", bound);
+  Print("cind  : %d\n", cabsind);
+#endif
+  if (cabsind == 0)
+  {
+    if (!(nextZeroSimplexExponent(exp, ind, cexp, cind, &cabsind, step, bound, currRing->N)))
+    {
+      return;
+    }
+  }
+  // Now the whole simplex
+  do
+  {
+    // Build s-polynomial
+    // 2**ind-def * mult * g - exp-def * h
+    poly t_p;
+    poly zeroPoly = kCreateZeroPoly(cexp, cabsind, &t_p, currRing, strat->tailRing);
+#ifdef OLI_DEBUG
+    Print("%d, (%d, %d), ind = (%d, %d)\n", cabsind, cexp[1], cexp[2], cind[1], cind[2]);
+    Print("zPoly : ");
+    wrp(zeroPoly);
+    Print("\n");
+#endif
+    enterOneZeroPairRing(zeroPoly, t_p, p, ecart, strat, atR);
+  }
+  while ( nextZeroSimplexExponent(exp, ind, cexp, cind, &cabsind, step, bound, currRing->N) );
+}
+
+/*
+ * Create the Groebner basis of the vanishing polynomials.
+ */
+
+ideal createG0()
+{
+  // Initialize
+  long exp[50];            // The exponent of \hat{X} (basepoint)
+  long cexp[50];           // The current exponent for iterating over all
+  long ind[50];            // The power of 2 in the i-th component of exp
+  long cind[50];           // analog for cexp
+  long mult[50];           // How to multiply the elements of G
+  long cabsind = 0;        // The abs. index of cexp, i.e. the sum of cind
+  long habsind = 0;        // The abs. index of the coefficient of h
+  long step[50];           // The last increases
+  for (int i = 1; i <= currRing->N; i++)
+  {
+    exp[i] = 0;
+    cexp[i] = exp[i];
+    ind[i] = 0;
+    step[i] = 500000;
+    cind[i] = ind[i];
+  }
+  long bound = currRing->ch;
+  step[1] = 500000;
+#ifdef OLI_DEBUG
+  PrintS("-------------\npoly  :");
+//  wrp(p);
+  Print("\nexp   : (%d, %d)\n", exp[1] + mult[1], exp[2] + mult[1]);
+  Print("cexp  : (%d, %d)\n", cexp[1], cexp[2]);
+  Print("cind  : (%d, %d)\n", cind[1], cind[2]);
+  Print("bound : %d\n", bound);
+  Print("cind  : %d\n", cabsind);
+#endif
+  if (cabsind == 0)
+  {
+    if (!(nextZeroSimplexExponent(exp, ind, cexp, cind, &cabsind, step, bound, currRing->N)))
+    {
+      return idInit(1, 1);
+    }
+  }
+  ideal G0 = idInit(1, 1);
+  // Now the whole simplex
+  do
+  {
+    // Build s-polynomial
+    // 2**ind-def * mult * g - exp-def * h
+    poly t_p;
+    poly zeroPoly = kCreateZeroPoly(cexp, cabsind, &t_p, currRing, currRing);
+#ifdef OLI_DEBUG
+    Print("%d, (%d, %d), ind = (%d, %d)\n", cabsind, cexp[1], cexp[2], cind[1], cind[2]);
+    Print("zPoly : ");
+    wrp(zeroPoly);
+    Print("\n");
+#endif
+    // Add to ideal
+    pEnlargeSet(&(G0->m), IDELEMS(G0), 1);
+    IDELEMS(G0) += 1;
+    G0->m[IDELEMS(G0) - 1] = zeroPoly;
+  }
+  while ( nextZeroSimplexExponent(exp, ind, cexp, cind, &cabsind, step, bound, currRing->N) );
+  idSkipZeroes(G0);
+  return G0;
+}
+#endif
+
+#ifdef HAVE_RINGS
+/*2
+*(s[0],h),...,(s[k],h) will be put to the pairset L
+*/
+void initenterstrongPairs (poly h,int k,int ecart,int isFromQ,kStrategy strat, int atR = -1)
+{
+  const unsigned long iCompH = pGetComp(h);
+  if (!nIsOne(pGetCoeff(h)))
+  {
+    int j;
+
+    for (j=0; j<=k; j++)
+    {
+      // Print("j:%d, Ll:%d\n",j,strat->Ll);
+//      if (((unsigned long) pGetCoeff(h) % (unsigned long) pGetCoeff(strat->S[j]) != 0) &&
+//         ((unsigned long) pGetCoeff(strat->S[j]) % (unsigned long) pGetCoeff(h) != 0))
+      if (((iCompH == pGetComp(strat->S[j]))
+      || (0 == pGetComp(strat->S[j])))
+      && ((iCompH<=strat->syzComp)||(strat->syzComp==0)))
+      {
+        enterOneStrongPoly(j,h,ecart,isFromQ,strat, atR);
+      }
+    }
+  }
+/*
+ring r=256,(x,y,z),dp;
+ideal I=12xz-133y, 2xy-z;
+*/
+
+}
+
+/*2
+* Generates spoly(0, h) if applicable. Assumes ring in Z/2^n.
+*/
+void enterExtendedSpoly(poly h,kStrategy strat)
+{
+  if (nIsOne(pGetCoeff(h))) return;
+  number gcd;
+  bool go = false;
+  if (n_DivBy((number) 0, pGetCoeff(h), currRing->cf))
+  {
+    gcd = n_Ann(pGetCoeff(h),currRing->cf);
+    go = true;
+  }
+  else
+    gcd = n_Gcd((number) 0, pGetCoeff(h), strat->tailRing->cf);
+  if (go || !nIsOne(gcd))
+  {
+    poly p = h->next;
+    if (!go)
+    {
+      number tmp = gcd;
+      gcd = n_Ann(gcd,currRing->cf);
+      nDelete(&tmp);
+    }
+    p_Test(p,strat->tailRing);
+    p = pp_Mult_nn(p, gcd, strat->tailRing);
+    nDelete(&gcd);
+
+    if (p != NULL)
+    {
+      if (TEST_OPT_PROT)
+      {
+        PrintS("Z");
+      }
+#ifdef KDEBUG
+      if (TEST_OPT_DEBUG)
+      {
+        PrintS("--- create zero spoly: ");
+        p_wrp(h,currRing,strat->tailRing);
+        PrintS(" ---> ");
+      }
+#endif
+      poly tmp = pInit();
+      pSetCoeff0(tmp, pGetCoeff(p));
+      for (int i = 1; i <= rVar(currRing); i++)
+      {
+        pSetExp(tmp, i, p_GetExp(p, i, strat->tailRing));
+      }
+      if (rRing_has_Comp(currRing) && rRing_has_Comp(strat->tailRing))
+      {
+        p_SetComp(tmp, p_GetComp(p, strat->tailRing), currRing);
+      }
+      p_Setm(tmp, currRing);
+      p = p_LmFreeAndNext(p, strat->tailRing);
+      pNext(tmp) = p;
+      LObject h;
+      h.Init();
+      h.p = tmp;
+      h.tailRing = strat->tailRing;
+      int posx;
+      if (h.p!=NULL)
+      {
+        if (TEST_OPT_INTSTRATEGY)
+        {
+          //pContent(h.p);
+          h.pCleardenom(); // also does a pContent
+        }
+        else
+        {
+          h.pNorm();
+        }
+        strat->initEcart(&h);
+        if (strat->Ll==-1)
+          posx =0;
+        else
+          posx = strat->posInL(strat->L,strat->Ll,&h,strat);
+        h.sev = pGetShortExpVector(h.p);
+        if (strat->tailRing != currRing)
+        {
+          h.t_p = k_LmInit_currRing_2_tailRing(h.p, strat->tailRing);
+        }
+#ifdef KDEBUG
+        if (TEST_OPT_DEBUG)
+        {
+          p_wrp(tmp,currRing,strat->tailRing);
+          PrintLn();
+        }
+#endif
+        enterL(&strat->L,&strat->Ll,&strat->Lmax,h,posx);
+      }
+    }
+  }
+  nDelete(&gcd);
+}
+
+void clearSbatch (poly h,int k,int pos,kStrategy strat)
+{
+  int j = pos;
+  if ( (!strat->fromT)
+  && ((strat->syzComp==0)
+    ||(pGetComp(h)<=strat->syzComp)
+  ))
+  {
+    // Print("start clearS k=%d, pos=%d, sl=%d\n",k,pos,strat->sl);
+    unsigned long h_sev = pGetShortExpVector(h);
+    loop
+    {
+      if (j > k) break;
+      clearS(h,h_sev, &j,&k,strat);
+      j++;
+    }
+    // Print("end clearS sl=%d\n",strat->sl);
+  }
+}
+
+/*2
+* Generates a sufficient set of spolys (maybe just a finite generating
+* set of the syzygys)
+*/
+void superenterpairs (poly h,int k,int ecart,int pos,kStrategy strat, int atR)
+{
+#if ADIDEBUG
+  PrintS("\nEnter superenterpairs\n");
+  int iii = strat->Ll;
+#endif
+  assume (rField_is_Ring(currRing));
+  // enter also zero divisor * poly, if this is non zero and of smaller degree
+  if (!(rField_is_Domain(currRing))) enterExtendedSpoly(h, strat);
+#if ADIDEBUG
+  if(iii==strat->Ll)
+  {
+    PrintS("\n                enterExtendedSpoly has not changed the list L.\n");
+  }
+  else
+  {
+    PrintLn();
+    PrintS("\n                enterExtendedSpoly changed the list L:\n");
+    for(iii=0;iii<=strat->Ll;iii++)
+    {
+      Print("\n                L[%d]:\n",iii);
+      PrintS("                     ");p_Write(strat->L[iii].p1,strat->tailRing);
+      PrintS("                     ");p_Write(strat->L[iii].p2,strat->tailRing);
+      PrintS("                     ");p_Write(strat->L[iii].p,strat->tailRing);
+    }
+  }
+  iii = strat->Ll;
+#endif
+  initenterpairs(h, k, ecart, 0, strat, atR);
+#if ADIDEBUG
+  if(iii==strat->Ll)
+  {
+    PrintS("\n                initenterpairs has not changed the list L.\n");
+  }
+  else
+  {
+    PrintS("\n                initenterpairs changed the list L:\n");
+    for(iii=0;iii<=strat->Ll;iii++)
+    {
+      Print("\n                L[%d]:\n",iii);
+      PrintS("                     ");p_Write(strat->L[iii].p1,strat->tailRing);
+      PrintS("                     ");p_Write(strat->L[iii].p2,strat->tailRing);
+      PrintS("                     ");p_Write(strat->L[iii].p,strat->tailRing);
+    }
+  }
+  iii = strat->Ll;
+#endif
+  initenterstrongPairs(h, k, ecart, 0, strat, atR);
+#if ADIDEBUG
+  if(iii==strat->Ll)
+  {
+    PrintS("\n                initenterstrongPairs has not changed the list L.\n");
+  }
+  else
+  {
+    PrintS("\n                initenterstrongPairs changed the list L:\n");
+    for(iii=0;iii<=strat->Ll;iii++)
+    {
+      Print("\n                L[%d]:\n",iii);
+      PrintS("                     ");p_Write(strat->L[iii].p1,strat->tailRing);
+      PrintS("                     ");p_Write(strat->L[iii].p2,strat->tailRing);
+      PrintS("                     ");p_Write(strat->L[iii].p,strat->tailRing);
+    }
+  }
+  PrintS("\nEnd of superenterpairs\n");
+#endif
+  clearSbatch(h, k, pos, strat);
+}
+#endif
+
+/*2
+*(s[0],h),...,(s[k],h) will be put to the pairset L(via initenterpairs)
+*superfluous elements in S will be deleted
+*/
+void enterpairs (poly h,int k,int ecart,int pos,kStrategy strat, int atR)
+{
+  int j=pos;
+
+#ifdef HAVE_RINGS
+  assume (!rField_is_Ring(currRing));
+#endif
+
+  initenterpairs(h,k,ecart,0,strat, atR);
+  if ( (!strat->fromT)
+  && ((strat->syzComp==0)
+    ||(pGetComp(h)<=strat->syzComp)))
+  {
+    //Print("start clearS k=%d, pos=%d, sl=%d\n",k,pos,strat->sl);
+    unsigned long h_sev = pGetShortExpVector(h);
+    loop
+    {
+      if (j > k) break;
+      clearS(h,h_sev, &j,&k,strat);
+      j++;
+    }
+    //Print("end clearS sl=%d\n",strat->sl);
+  }
+ // PrintS("end enterpairs\n");
+}
+
+/*2
+*(s[0],h),...,(s[k],h) will be put to the pairset L(via initenterpairs)
+*superfluous elements in S will be deleted
+*this is a special variant of signature-based algorithms including the
+*signatures for criteria checks
+*/
+void enterpairsSig (poly h,poly hSig,int hFrom,int k,int ecart,int pos,kStrategy strat, int atR)
+{
+int j=pos;
+
+#ifdef HAVE_RINGS
+assume (!rField_is_Ring(currRing));
+#endif
+
+initenterpairsSig(h,hSig,hFrom,k,ecart,0,strat, atR);
+if ( (!strat->fromT)
+&& ((strat->syzComp==0)
+  ||(pGetComp(h)<=strat->syzComp)))
+{
+  //Print("start clearS k=%d, pos=%d, sl=%d\n",k,pos,strat->sl);
+  unsigned long h_sev = pGetShortExpVector(h);
+  loop
+  {
+    if (j > k) break;
+    clearS(h,h_sev, &j,&k,strat);
+    j++;
+  }
+  //Print("end clearS sl=%d\n",strat->sl);
+}
+// PrintS("end enterpairs\n");
+}
+
+/*2
+*(s[0],h),...,(s[k],h) will be put to the pairset L(via initenterpairs)
+*superfluous elements in S will be deleted
+*/
+void enterpairsSpecial (poly h,int k,int ecart,int pos,kStrategy strat, int atR = -1)
+{
+  int j;
+  const int iCompH = pGetComp(h);
+
+#ifdef HAVE_RINGS
+  if (rField_is_Ring(currRing))
+  {
+    for (j=0; j<=k; j++)
+    {
+      const int iCompSj = pGetComp(strat->S[j]);
+      if ((iCompH==iCompSj)
+          //|| (0==iCompH) // can only happen,if iCompSj==0
+          || (0==iCompSj))
+      {
+        enterOnePairRing(j,h,ecart,FALSE,strat, atR);
+      }
+    }
+    kMergeBintoL(strat);
+  }
+  else
+#endif
+  for (j=0; j<=k; j++)
+  {
+    const int iCompSj = pGetComp(strat->S[j]);
+    if ((iCompH==iCompSj)
+        //|| (0==iCompH) // can only happen,if iCompSj==0
+        || (0==iCompSj))
+    {
+      enterOnePairSpecial(j,h,ecart,strat, atR);
+    }
+  }
+
+  if (strat->noClearS) return;
+
+//   #ifdef HAVE_PLURAL
+/*
+  if (rIsPluralRing(currRing))
+  {
+    j=pos;
+    loop
+    {
+      if (j > k) break;
+
+      if (pLmDivisibleBy(h, strat->S[j]))
+      {
+        deleteInS(j, strat);
+        j--;
+        k--;
+      }
+
+      j++;
+    }
+  }
+  else
+*/
+//   #endif // ??? Why was the following cancelation disabled for non-commutative rings?
+  {
+    j=pos;
+    loop
+    {
+      unsigned long h_sev = pGetShortExpVector(h);
+      if (j > k) break;
+      clearS(h,h_sev,&j,&k,strat);
+      j++;
+    }
+  }
+}
+
+/*2
+*reorders  s with respect to posInS,
+*suc is the first changed index or zero
+*/
+
+void reorderS (int* suc,kStrategy strat)
+{
+  int i,j,at,ecart, s2r;
+  int fq=0;
+  unsigned long sev;
+  poly  p;
+  int new_suc=strat->sl+1;
+  i= *suc;
+  if (i<0) i=0;
+
+  for (; i<=strat->sl; i++)
+  {
+    at = posInS(strat,i-1,strat->S[i],strat->ecartS[i]);
+    if (at != i)
+    {
+      if (new_suc > at) new_suc = at;
+      p = strat->S[i];
+      ecart = strat->ecartS[i];
+      sev = strat->sevS[i];
+      s2r = strat->S_2_R[i];
+      if (strat->fromQ!=NULL) fq=strat->fromQ[i];
+      for (j=i; j>=at+1; j--)
+      {
+        strat->S[j] = strat->S[j-1];
+        strat->ecartS[j] = strat->ecartS[j-1];
+        strat->sevS[j] = strat->sevS[j-1];
+        strat->S_2_R[j] = strat->S_2_R[j-1];
+      }
+      strat->S[at] = p;
+      strat->ecartS[at] = ecart;
+      strat->sevS[at] = sev;
+      strat->S_2_R[at] = s2r;
+      if (strat->fromQ!=NULL)
+      {
+        for (j=i; j>=at+1; j--)
+        {
+          strat->fromQ[j] = strat->fromQ[j-1];
+        }
+        strat->fromQ[at]=fq;
+      }
+    }
+  }
+  if (new_suc <= strat->sl) *suc=new_suc;
+  else                      *suc=-1;
+}
+
+
+/*2
+*looks up the position of p in set
+*set[0] is the smallest with respect to the ordering-procedure deg/pComp
+* Assumption: posInS only depends on the leading term
+*             otherwise, bba has to be changed
+*/
+int posInS (const kStrategy strat, const int length,const poly p,
+            const int ecart_p)
+{
+  if(length==-1) return 0;
+  polyset set=strat->S;
+  int i;
+  int an = 0;
+  int en = length;
+  int cmp_int = currRing->OrdSgn;
+  if ((currRing->MixedOrder)
+#ifdef HAVE_PLURAL
+  && (currRing->real_var_start==0)
+#endif
+#if 0
+  || ((strat->ak>0) && ((currRing->order[0]==ringorder_c)||((currRing->order[0]==ringorder_C))))
+#endif
+  )
+  {
+    int o=p_Deg(p,currRing);
+    int oo=p_Deg(set[length],currRing);
+
+    if ((oo<o)
+    || ((o==oo) && (pLmCmp(set[length],p)!= cmp_int)))
+      return length+1;
+
+    loop
+    {
+      if (an >= en-1)
+      {
+        if ((p_Deg(set[an],currRing)>=o) && (pLmCmp(set[an],p) == cmp_int))
+        {
+          return an;
+        }
+        return en;
+      }
+      i=(an+en) / 2;
+      if ((p_Deg(set[i],currRing)>=o) && (pLmCmp(set[i],p) == cmp_int)) en=i;
+      else                              an=i;
+    }
+  }
+  else
+  {
+#ifdef HAVE_RINGS
+    if (rField_is_Ring(currRing))
+    {
+      if (pLmCmp(set[length],p)== -cmp_int)
+        return length+1;
+      int cmp;
+      loop
+      {
+        if (an >= en-1)
+        {
+          cmp = pLmCmp(set[an],p);
+          if (cmp == cmp_int)  return an;
+          if (cmp == -cmp_int) return en;
+          if (n_DivBy(pGetCoeff(p), pGetCoeff(set[an]), currRing->cf)) return en;
+          return an;
+        }
+        i = (an+en) / 2;
+        cmp = pLmCmp(set[i],p);
+        if (cmp == cmp_int)         en = i;
+        else if (cmp == -cmp_int)   an = i;
+        else
+        {
+          if (n_DivBy(pGetCoeff(p), pGetCoeff(set[i]), currRing->cf)) an = i;
+          else en = i;
+        }
+      }
+    }
+    else
+#endif
+    if (pLmCmp(set[length],p)== -cmp_int)
+      return length+1;
+
+    loop
+    {
+      if (an >= en-1)
+      {
+        if (pLmCmp(set[an],p) == cmp_int) return an;
+        if (pLmCmp(set[an],p) == -cmp_int) return en;
+        if ((cmp_int!=1)
+        && ((strat->ecartS[an])>ecart_p))
+          return an;
+        return en;
+      }
+      i=(an+en) / 2;
+      if (pLmCmp(set[i],p) == cmp_int) en=i;
+      else if (pLmCmp(set[i],p) == -cmp_int) an=i;
+      else
+      {
+        if ((cmp_int!=1)
+        &&((strat->ecartS[i])<ecart_p))
+          en=i;
+        else
+          an=i;
+      }
+    }
+  }
+}
+
+
+/*2
+* looks up the position of p in set
+* the position is the last one
+*/
+int posInT0 (const TSet,const int length,LObject &)
+{
+  return (length+1);
+}
+
+
+/*2
+* looks up the position of p in T
+* set[0] is the smallest with respect to the ordering-procedure
+* pComp
+*/
+int posInT1 (const TSet set,const int length,LObject &p)
+{
+  if (length==-1) return 0;
+
+  if (pLmCmp(set[length].p,p.p)!= currRing->OrdSgn) return length+1;
+
+  int i;
+  int an = 0;
+  int en= length;
+
+  loop
+  {
+    if (an >= en-1)
+    {
+      if (pLmCmp(set[an].p,p.p) == currRing->OrdSgn) return an;
+      return en;
+    }
+    i=(an+en) / 2;
+    if (pLmCmp(set[i].p,p.p) == currRing->OrdSgn) en=i;
+    else                                 an=i;
+  }
+}
+
+/*2
+* looks up the position of p in T
+* set[0] is the smallest with respect to the ordering-procedure
+* length
+*/
+int posInT2 (const TSet set,const int length,LObject &p)
+{
+  p.GetpLength();
+  if (length==-1)
+    return 0;
+  if (set[length].length<p.length)
+    return length+1;
+
+  int i;
+  int an = 0;
+  int en= length;
+
+  loop
+  {
+    if (an >= en-1)
+    {
+      if (set[an].length>p.length) return an;
+      return en;
+    }
+    i=(an+en) / 2;
+    if (set[i].length>p.length) en=i;
+    else                        an=i;
+  }
+}
+
+/*2
+* looks up the position of p in T
+* set[0] is the smallest with respect to the ordering-procedure
+* totaldegree,pComp
+*/
+int posInT11 (const TSet set,const int length,LObject &p)
+/*{
+ * int j=0;
+ * int o;
+ *
+ * o = p.GetpFDeg();
+ * loop
+ * {
+ *   if ((pFDeg(set[j].p) > o)
+ *   || ((pFDeg(set[j].p) == o) && (pLmCmp(set[j].p,p.p) == currRing->OrdSgn)))
+ *   {
+ *     return j;
+ *   }
+ *   j++;
+ *   if (j > length) return j;
+ * }
+ *}
+ */
+{
+  if (length==-1) return 0;
+
+  int o = p.GetpFDeg();
+  int op = set[length].GetpFDeg();
+
+  if ((op < o)
+  || ((op == o) && (pLmCmp(set[length].p,p.p) != currRing->OrdSgn)))
+    return length+1;
+
+  int i;
+  int an = 0;
+  int en= length;
+
+  loop
+  {
+    if (an >= en-1)
+    {
+      op= set[an].GetpFDeg();
+      if ((op > o)
+      || (( op == o) && (pLmCmp(set[an].p,p.p) == currRing->OrdSgn)))
+        return an;
+      return en;
+    }
+    i=(an+en) / 2;
+    op = set[i].GetpFDeg();
+    if (( op > o)
+    || (( op == o) && (pLmCmp(set[i].p,p.p) == currRing->OrdSgn)))
+      en=i;
+    else
+      an=i;
+  }
+}
+
+/*2 Pos for rings T: Here I am
+* looks up the position of p in T
+* set[0] is the smallest with respect to the ordering-procedure
+* totaldegree,pComp
+*/
+int posInTrg0 (const TSet set,const int length,LObject &p)
+{
+  if (length==-1) return 0;
+  int o = p.GetpFDeg();
+  int op = set[length].GetpFDeg();
+  int i;
+  int an = 0;
+  int en = length;
+  int cmp_int = currRing->OrdSgn;
+  if ((op < o) || (pLmCmp(set[length].p,p.p)== -cmp_int))
+    return length+1;
+  int cmp;
+  loop
+  {
+    if (an >= en-1)
+    {
+      op = set[an].GetpFDeg();
+      if (op > o) return an;
+      if (op < 0) return en;
+      cmp = pLmCmp(set[an].p,p.p);
+      if (cmp == cmp_int)  return an;
+      if (cmp == -cmp_int) return en;
+      if (nGreater(pGetCoeff(p.p), pGetCoeff(set[an].p))) return en;
+      return an;
+    }
+    i = (an + en) / 2;
+    op = set[i].GetpFDeg();
+    if (op > o)       en = i;
+    else if (op < o)  an = i;
+    else
+    {
+      cmp = pLmCmp(set[i].p,p.p);
+      if (cmp == cmp_int)                                     en = i;
+      else if (cmp == -cmp_int)                               an = i;
+      else if (nGreater(pGetCoeff(p.p), pGetCoeff(set[i].p))) an = i;
+      else                                                    en = i;
+    }
+  }
+}
+/*
+  int o = p.GetpFDeg();
+  int op = set[length].GetpFDeg();
+
+  if ((op < o)
+  || ((op == o) && (pLmCmp(set[length].p,p.p) != currRing->OrdSgn)))
+    return length+1;
+
+  int i;
+  int an = 0;
+  int en= length;
+
+  loop
+  {
+    if (an >= en-1)
+    {
+      op= set[an].GetpFDeg();
+      if ((op > o)
+      || (( op == o) && (pLmCmp(set[an].p,p.p) == currRing->OrdSgn)))
+        return an;
+      return en;
+    }
+    i=(an+en) / 2;
+    op = set[i].GetpFDeg();
+    if (( op > o)
+    || (( op == o) && (pLmCmp(set[i].p,p.p) == currRing->OrdSgn)))
+      en=i;
+    else
+      an=i;
+  }
+}
+  */
+/*2
+* looks up the position of p in T
+* set[0] is the smallest with respect to the ordering-procedure
+* totaldegree,pComp
+*/
+int posInT110 (const TSet set,const int length,LObject &p)
+{
+  p.GetpLength();
+  if (length==-1) return 0;
+
+  int o = p.GetpFDeg();
+  int op = set[length].GetpFDeg();
+
+  if (( op < o)
+  || (( op == o) && (set[length].length<p.length))
+  || (( op == o) && (set[length].length == p.length)
+     && (pLmCmp(set[length].p,p.p) != currRing->OrdSgn)))
+    return length+1;
+
+  int i;
+  int an = 0;
+  int en= length;
+  loop
+  {
+    if (an >= en-1)
+    {
+      op = set[an].GetpFDeg();
+      if (( op > o)
+      || (( op == o) && (set[an].length > p.length))
+      || (( op == o) && (set[an].length == p.length)
+         && (pLmCmp(set[an].p,p.p) == currRing->OrdSgn)))
+        return an;
+      return en;
+    }
+    i=(an+en) / 2;
+    op = set[i].GetpFDeg();
+    if (( op > o)
+    || (( op == o) && (set[i].length > p.length))
+    || (( op == o) && (set[i].length == p.length)
+       && (pLmCmp(set[i].p,p.p) == currRing->OrdSgn)))
+      en=i;
+    else
+      an=i;
+  }
+}
+
+/*2
+* looks up the position of p in set
+* set[0] is the smallest with respect to the ordering-procedure
+* pFDeg
+*/
+int posInT13 (const TSet set,const int length,LObject &p)
+{
+  if (length==-1) return 0;
+
+  int o = p.GetpFDeg();
+
+  if (set[length].GetpFDeg() <= o)
+    return length+1;
+
+  int i;
+  int an = 0;
+  int en= length;
+  loop
+  {
+    if (an >= en-1)
+    {
+      if (set[an].GetpFDeg() > o)
+        return an;
+      return en;
+    }
+    i=(an+en) / 2;
+    if (set[i].GetpFDeg() > o)
+      en=i;
+    else
+      an=i;
+  }
+}
+
+// determines the position based on: 1.) Ecart 2.) pLength
+int posInT_EcartpLength(const TSet set,const int length,LObject &p)
+{
+  int ol = p.GetpLength();
+  if (length==-1) return 0;
+
+  int op=p.ecart;
+
+  int oo=set[length].ecart;
+  if ((oo < op) || ((oo==op) && (set[length].length < ol)))
+    return length+1;
+
+  int i;
+  int an = 0;
+  int en= length;
+  loop
+    {
+      if (an >= en-1)
+      {
+        int oo=set[an].ecart;
+        if((oo > op)
+           || ((oo==op) && (set[an].pLength > ol)))
+          return an;
+        return en;
+      }
+      i=(an+en) / 2;
+      int oo=set[i].ecart;
+      if ((oo > op)
+          || ((oo == op) && (set[i].pLength > ol)))
+        en=i;
+      else
+        an=i;
+    }
+}
+
+/*2
+* looks up the position of p in set
+* set[0] is the smallest with respect to the ordering-procedure
+* maximaldegree, pComp
+*/
+int posInT15 (const TSet set,const int length,LObject &p)
+/*{
+ *int j=0;
+ * int o;
+ *
+ * o = p.GetpFDeg()+p.ecart;
+ * loop
+ * {
+ *   if ((set[j].GetpFDeg()+set[j].ecart > o)
+ *   || ((set[j].GetpFDeg()+set[j].ecart == o)
+ *     && (pLmCmp(set[j].p,p.p) == currRing->OrdSgn)))
+ *   {
+ *     return j;
+ *   }
+ *   j++;
+ *   if (j > length) return j;
+ * }
+ *}
+ */
+{
+  if (length==-1) return 0;
+
+  int o = p.GetpFDeg() + p.ecart;
+  int op = set[length].GetpFDeg()+set[length].ecart;
+
+  if ((op < o)
+  || ((op == o)
+     && (pLmCmp(set[length].p,p.p) != currRing->OrdSgn)))
+    return length+1;
+
+  int i;
+  int an = 0;
+  int en= length;
+  loop
+  {
+    if (an >= en-1)
+    {
+      op = set[an].GetpFDeg()+set[an].ecart;
+      if (( op > o)
+      || (( op  == o) && (pLmCmp(set[an].p,p.p) == currRing->OrdSgn)))
+        return an;
+      return en;
+    }
+    i=(an+en) / 2;
+    op = set[i].GetpFDeg()+set[i].ecart;
+    if (( op > o)
+    || (( op == o) && (pLmCmp(set[i].p,p.p) == currRing->OrdSgn)))
+      en=i;
+    else
+      an=i;
+  }
+}
+
+/*2
+* looks up the position of p in set
+* set[0] is the smallest with respect to the ordering-procedure
+* pFDeg+ecart, ecart, pComp
+*/
+int posInT17 (const TSet set,const int length,LObject &p)
+/*
+*{
+* int j=0;
+* int  o;
+*
+*  o = p.GetpFDeg()+p.ecart;
+*  loop
+*  {
+*    if ((pFDeg(set[j].p)+set[j].ecart > o)
+*    || (((pFDeg(set[j].p)+set[j].ecart == o)
+*      && (set[j].ecart < p.ecart)))
+*    || ((pFDeg(set[j].p)+set[j].ecart == o)
+*      && (set[j].ecart==p.ecart)
+*      && (pLmCmp(set[j].p,p.p)==currRing->OrdSgn)))
+*      return j;
+*    j++;
+*    if (j > length) return j;
+*  }
+* }
+*/
+{
+  if (length==-1) return 0;
+
+  int o = p.GetpFDeg() + p.ecart;
+  int op = set[length].GetpFDeg()+set[length].ecart;
+
+  if ((op < o)
+  || (( op == o) && (set[length].ecart > p.ecart))
+  || (( op == o) && (set[length].ecart==p.ecart)
+     && (pLmCmp(set[length].p,p.p) != currRing->OrdSgn)))
+    return length+1;
+
+  int i;
+  int an = 0;
+  int en= length;
+  loop
+  {
+    if (an >= en-1)
+    {
+      op = set[an].GetpFDeg()+set[an].ecart;
+      if (( op > o)
+      || (( op == o) && (set[an].ecart < p.ecart))
+      || (( op  == o) && (set[an].ecart==p.ecart)
+         && (pLmCmp(set[an].p,p.p) == currRing->OrdSgn)))
+        return an;
+      return en;
+    }
+    i=(an+en) / 2;
+    op = set[i].GetpFDeg()+set[i].ecart;
+    if ((op > o)
+    || (( op == o) && (set[i].ecart < p.ecart))
+    || (( op == o) && (set[i].ecart == p.ecart)
+       && (pLmCmp(set[i].p,p.p) == currRing->OrdSgn)))
+      en=i;
+    else
+      an=i;
+  }
+}
+/*2
+* looks up the position of p in set
+* set[0] is the smallest with respect to the ordering-procedure
+* pGetComp, pFDeg+ecart, ecart, pComp
+*/
+int posInT17_c (const TSet set,const int length,LObject &p)
+{
+  if (length==-1) return 0;
+
+  int cc = (-1+2*currRing->order[0]==ringorder_c);
+  /* cc==1 for (c,..), cc==-1 for (C,..) */
+  int o = p.GetpFDeg() + p.ecart;
+  unsigned long c = pGetComp(p.p)*cc;
+
+  if (pGetComp(set[length].p)*cc < c)
+    return length+1;
+  if (pGetComp(set[length].p)*cc == c)
+  {
+    int op = set[length].GetpFDeg()+set[length].ecart;
+    if ((op < o)
+    || ((op == o) && (set[length].ecart > p.ecart))
+    || ((op == o) && (set[length].ecart==p.ecart)
+       && (pLmCmp(set[length].p,p.p) != currRing->OrdSgn)))
+      return length+1;
+  }
+
+  int i;
+  int an = 0;
+  int en= length;
+  loop
+  {
+    if (an >= en-1)
+    {
+      if (pGetComp(set[an].p)*cc < c)
+        return en;
+      if (pGetComp(set[an].p)*cc == c)
+      {
+        int op = set[an].GetpFDeg()+set[an].ecart;
+        if ((op > o)
+        || ((op == o) && (set[an].ecart < p.ecart))
+        || ((op == o) && (set[an].ecart==p.ecart)
+           && (pLmCmp(set[an].p,p.p) == currRing->OrdSgn)))
+          return an;
+      }
+      return en;
+    }
+    i=(an+en) / 2;
+    if (pGetComp(set[i].p)*cc > c)
+      en=i;
+    else if (pGetComp(set[i].p)*cc == c)
+    {
+      int op = set[i].GetpFDeg()+set[i].ecart;
+      if ((op > o)
+      || ((op == o) && (set[i].ecart < p.ecart))
+      || ((op == o) && (set[i].ecart == p.ecart)
+         && (pLmCmp(set[i].p,p.p) == currRing->OrdSgn)))
+        en=i;
+      else
+        an=i;
+    }
+    else
+      an=i;
+  }
+}
+
+/*2
+* looks up the position of p in set
+* set[0] is the smallest with respect to
+* ecart, pFDeg, length
+*/
+int posInT19 (const TSet set,const int length,LObject &p)
+{
+  p.GetpLength();
+  if (length==-1) return 0;
+
+  int o = p.ecart;
+  int op=p.GetpFDeg();
+
+  if (set[length].ecart < o)
+    return length+1;
+  if (set[length].ecart == o)
+  {
+     int oo=set[length].GetpFDeg();
+     if ((oo < op) || ((oo==op) && (set[length].length < p.length)))
+       return length+1;
+  }
+
+  int i;
+  int an = 0;
+  int en= length;
+  loop
+  {
+    if (an >= en-1)
+    {
+      if (set[an].ecart > o)
+        return an;
+      if (set[an].ecart == o)
+      {
+         int oo=set[an].GetpFDeg();
+         if((oo > op)
+         || ((oo==op) && (set[an].length > p.length)))
+           return an;
+      }
+      return en;
+    }
+    i=(an+en) / 2;
+    if (set[i].ecart > o)
+      en=i;
+    else if (set[i].ecart == o)
+    {
+       int oo=set[i].GetpFDeg();
+       if ((oo > op)
+       || ((oo == op) && (set[i].length > p.length)))
+         en=i;
+       else
+        an=i;
+    }
+    else
+      an=i;
+  }
+}
+
+/*2
+*looks up the position of polynomial p in set
+*set[length] is the smallest element in set with respect
+*to the ordering-procedure pComp
+*/
+int posInLSpecial (const LSet set, const int length,
+                   LObject *p,const kStrategy)
+{
+  if (length<0) return 0;
+
+  int d=p->GetpFDeg();
+  int op=set[length].GetpFDeg();
+
+  if ((op > d)
+  || ((op == d) && (p->p1!=NULL)&&(set[length].p1==NULL))
+  || (pLmCmp(set[length].p,p->p)== currRing->OrdSgn))
+     return length+1;
+
+  int i;
+  int an = 0;
+  int en= length;
+  loop
+  {
+    if (an >= en-1)
+    {
+      op=set[an].GetpFDeg();
+      if ((op > d)
+      || ((op == d) && (p->p1!=NULL) && (set[an].p1==NULL))
+      || (pLmCmp(set[an].p,p->p)== currRing->OrdSgn))
+         return en;
+      return an;
+    }
+    i=(an+en) / 2;
+    op=set[i].GetpFDeg();
+    if ((op>d)
+    || ((op==d) && (p->p1!=NULL) && (set[i].p1==NULL))
+    || (pLmCmp(set[i].p,p->p) == currRing->OrdSgn))
+      an=i;
+    else
+      en=i;
+  }
+}
+
+/*2
+*looks up the position of polynomial p in set
+*set[length] is the smallest element in set with respect
+*to the ordering-procedure pComp
+*/
+int posInL0 (const LSet set, const int length,
+             LObject* p,const kStrategy)
+{
+  if (length<0) return 0;
+
+  if (pLmCmp(set[length].p,p->p)== currRing->OrdSgn)
+    return length+1;
+
+  int i;
+  int an = 0;
+  int en= length;
+  loop
+  {
+    if (an >= en-1)
+    {
+      if (pLmCmp(set[an].p,p->p) == currRing->OrdSgn) return en;
+      return an;
+    }
+    i=(an+en) / 2;
+    if (pLmCmp(set[i].p,p->p) == currRing->OrdSgn) an=i;
+    else                                 en=i;
+    /*aend. fuer lazy == in !=- machen */
+  }
+}
+
+/*2
+* looks up the position of polynomial p in set
+* e is the ecart of p
+* set[length] is the smallest element in set with respect
+* to the signature order
+*/
+int posInLSig (const LSet set, const int length,
+               LObject* p,const kStrategy /*strat*/)
+{
+if (length<0) return 0;
+if (pLmCmp(set[length].sig,p->sig)== currRing->OrdSgn)
+  return length+1;
+
+int i;
+int an = 0;
+int en= length;
+loop
+{
+  if (an >= en-1)
+  {
+    if (pLmCmp(set[an].sig,p->sig) == currRing->OrdSgn) return en;
+    return an;
+  }
+  i=(an+en) / 2;
+  if (pLmCmp(set[i].sig,p->sig) == currRing->OrdSgn) an=i;
+  else                                      en=i;
+  /*aend. fuer lazy == in !=- machen */
+}
+}
+
+// for sba, sorting syzygies
+int posInSyz (const kStrategy strat, poly sig)
+{
+if (strat->syzl==0) return 0;
+if (pLmCmp(strat->syz[strat->syzl-1],sig) != currRing->OrdSgn)
+  return strat->syzl;
+int i;
+int an = 0;
+int en= strat->syzl-1;
+loop
+{
+  if (an >= en-1)
+  {
+    if (pLmCmp(strat->syz[an],sig) != currRing->OrdSgn) return en;
+    return an;
+  }
+  i=(an+en) / 2;
+  if (pLmCmp(strat->syz[i],sig) != currRing->OrdSgn) an=i;
+  else                                      en=i;
+  /*aend. fuer lazy == in !=- machen */
+}
+}
+
+/*2
+*
+* is only used in F5C, must ensure that the interreduction process does add new
+* critical pairs to strat->L only behind all other critical pairs which are
+* still in strat->L!
+*/
+int posInLF5C (const LSet /*set*/, const int /*length*/,
+               LObject* /*p*/,const kStrategy strat)
+{
+  return strat->Ll+1;
+}
+
+/*2
+* looks up the position of polynomial p in set
+* e is the ecart of p
+* set[length] is the smallest element in set with respect
+* to the ordering-procedure totaldegree,pComp
+*/
+int posInL11 (const LSet set, const int length,
+              LObject* p,const kStrategy)
+/*{
+ * int j=0;
+ * int o;
+ *
+ * o = p->GetpFDeg();
+ * loop
+ * {
+ *   if (j > length)            return j;
+ *   if ((set[j].GetpFDeg() < o)) return j;
+ *   if ((set[j].GetpFDeg() == o) && (pLmCmp(set[j].p,p->p) == -currRing->OrdSgn))
+ *   {
+ *     return j;
+ *   }
+ *   j++;
+ * }
+ *}
+ */
+{
+  if (length<0) return 0;
+
+  int o = p->GetpFDeg();
+  int op = set[length].GetpFDeg();
+
+  if ((op > o)
+  || ((op == o) && (pLmCmp(set[length].p,p->p) != -currRing->OrdSgn)))
+    return length+1;
+  int i;
+  int an = 0;
+  int en= length;
+  loop
+  {
+    if (an >= en-1)
+    {
+      op = set[an].GetpFDeg();
+      if ((op > o)
+      || ((op == o) && (pLmCmp(set[an].p,p->p) != -currRing->OrdSgn)))
+        return en;
+      return an;
+    }
+    i=(an+en) / 2;
+    op = set[i].GetpFDeg();
+    if ((op > o)
+    || ((op == o) && (pLmCmp(set[i].p,p->p) != -currRing->OrdSgn)))
+      an=i;
+    else
+      en=i;
+  }
+}
+
+/*2 Position for rings L: Here I am
+* looks up the position of polynomial p in set
+* e is the ecart of p
+* set[length] is the smallest element in set with respect
+* to the ordering-procedure totaldegree,pComp
+*/
+inline int getIndexRng(long coeff)
+{
+  if (coeff == 0) return -1;
+  long tmp = coeff;
+  int ind = 0;
+  while (tmp % 2 == 0)
+  {
+    tmp = tmp / 2;
+    ind++;
+  }
+  return ind;
+}
+
+int posInLrg0 (const LSet set, const int length,
+              LObject* p,const kStrategy)
+/*          if (nGreater(pGetCoeff(p), pGetCoeff(set[an]))) return en;
+        if (pLmCmp(set[i],p) == cmp_int)         en = i;
+        else if (pLmCmp(set[i],p) == -cmp_int)   an = i;
+        else
+        {
+          if (nGreater(pGetCoeff(p), pGetCoeff(set[i]))) an = i;
+          else en = i;
+        }*/
+{
+  if (length < 0) return 0;
+
+  int o = p->GetpFDeg();
+  int op = set[length].GetpFDeg();
+
+  if ((op > o) || ((op == o) && (pLmCmp(set[length].p,p->p) != -currRing->OrdSgn)))
+    return length + 1;
+  int i;
+  int an = 0;
+  int en = length;
+  loop
+  {
+    if (an >= en - 1)
+    {
+      op = set[an].GetpFDeg();
+      if ((op > o) || ((op == o) && (pLmCmp(set[an].p,p->p) != -currRing->OrdSgn)))
+        return en;
+      return an;
+    }
+    i = (an+en) / 2;
+    op = set[i].GetpFDeg();
+    if ((op > o) || ((op == o) && (pLmCmp(set[i].p,p->p) != -currRing->OrdSgn)))
+      an = i;
+    else
+      en = i;
+  }
+}
+
+/*{
+  if (length < 0) return 0;
+
+  int o = p->GetpFDeg();
+  int op = set[length].GetpFDeg();
+
+  int inde = getIndexRng((unsigned long) pGetCoeff(set[length].p));
+  int indp = getIndexRng((unsigned long) pGetCoeff(p->p));
+  int inda;
+  int indi;
+
+  if ((inda > indp) || ((inda == inde) && ((op > o) || ((op == o) && (pLmCmp(set[length].p,p->p) != -currRing->OrdSgn)))))
+    return length + 1;
+  int i;
+  int an = 0;
+  inda = getIndexRng((unsigned long) pGetCoeff(set[an].p));
+  int en = length;
+  loop
+  {
+    if (an >= en-1)
+    {
+      op = set[an].GetpFDeg();
+      if ((indp > inda) || ((indp == inda) && ((op > o) || ((op == o) && (pLmCmp(set[an].p,p->p) != -currRing->OrdSgn)))))
+        return en;
+      return an;
+    }
+    i = (an + en) / 2;
+    indi = getIndexRng((unsigned long) pGetCoeff(set[i].p));
+    op = set[i].GetpFDeg();
+    if ((indi > indp) || ((indi == indp) && ((op > o) || ((op == o) && (pLmCmp(set[i].p,p->p) != -currRing->OrdSgn)))))
+    // if ((op > o) || ((op == o) && (pLmCmp(set[i].p,p->p) != -currRing->OrdSgn)))
+    {
+      an = i;
+      inda = getIndexRng((unsigned long) pGetCoeff(set[an].p));
+    }
+    else
+      en = i;
+  }
+} */
+
+/*2
+* looks up the position of polynomial p in set
+* set[length] is the smallest element in set with respect
+* to the ordering-procedure totaldegree,pLength0
+*/
+int posInL110 (const LSet set, const int length,
+               LObject* p,const kStrategy)
+{
+  if (length<0) return 0;
+
+  int o = p->GetpFDeg();
+  int op = set[length].GetpFDeg();
+
+  if ((op > o)
+  || ((op == o) && (set[length].length >p->length))
+  || ((op == o) && (set[length].length <= p->length)
+     && (pLmCmp(set[length].p,p->p) != -currRing->OrdSgn)))
+    return length+1;
+  int i;
+  int an = 0;
+  int en= length;
+  loop
+  {
+    if (an >= en-1)
+    {
+      op = set[an].GetpFDeg();
+      if ((op > o)
+      || ((op == o) && (set[an].length >p->length))
+      || ((op == o) && (set[an].length <=p->length)
+         && (pLmCmp(set[an].p,p->p) != -currRing->OrdSgn)))
+        return en;
+      return an;
+    }
+    i=(an+en) / 2;
+    op = set[i].GetpFDeg();
+    if ((op > o)
+    || ((op == o) && (set[i].length > p->length))
+    || ((op == o) && (set[i].length <= p->length)
+       && (pLmCmp(set[i].p,p->p) != -currRing->OrdSgn)))
+      an=i;
+    else
+      en=i;
+  }
+}
+
+/*2
+* looks up the position of polynomial p in set
+* e is the ecart of p
+* set[length] is the smallest element in set with respect
+* to the ordering-procedure totaldegree
+*/
+int posInL13 (const LSet set, const int length,
+              LObject* p,const kStrategy)
+{
+  if (length<0) return 0;
+
+  int o = p->GetpFDeg();
+
+  if (set[length].GetpFDeg() > o)
+    return length+1;
+
+  int i;
+  int an = 0;
+  int en= length;
+  loop
+  {
+    if (an >= en-1)
+    {
+      if (set[an].GetpFDeg() >= o)
+        return en;
+      return an;
+    }
+    i=(an+en) / 2;
+    if (set[i].GetpFDeg() >= o)
+      an=i;
+    else
+      en=i;
+  }
+}
+
+/*2
+* looks up the position of polynomial p in set
+* e is the ecart of p
+* set[length] is the smallest element in set with respect
+* to the ordering-procedure maximaldegree,pComp
+*/
+int posInL15 (const LSet set, const int length,
+              LObject* p,const kStrategy)
+/*{
+ * int j=0;
+ * int o;
+ *
+ * o = p->ecart+p->GetpFDeg();
+ * loop
+ * {
+ *   if (j > length)                       return j;
+ *   if (set[j].GetpFDeg()+set[j].ecart < o) return j;
+ *   if ((set[j].GetpFDeg()+set[j].ecart == o)
+ *   && (pLmCmp(set[j].p,p->p) == -currRing->OrdSgn))
+ *   {
+ *     return j;
+ *   }
+ *   j++;
+ * }
+ *}
+ */
+{
+  if (length<0) return 0;
+
+  int o = p->GetpFDeg() + p->ecart;
+  int op = set[length].GetpFDeg() + set[length].ecart;
+
+  if ((op > o)
+  || ((op == o) && (pLmCmp(set[length].p,p->p) != -currRing->OrdSgn)))
+    return length+1;
+  int i;
+  int an = 0;
+  int en= length;
+  loop
+  {
+    if (an >= en-1)
+    {
+      op = set[an].GetpFDeg() + set[an].ecart;
+      if ((op > o)
+      || ((op == o) && (pLmCmp(set[an].p,p->p) != -currRing->OrdSgn)))
+        return en;
+      return an;
+    }
+    i=(an+en) / 2;
+    op = set[i].GetpFDeg() + set[i].ecart;
+    if ((op > o)
+    || ((op == o) && (pLmCmp(set[i].p,p->p) != -currRing->OrdSgn)))
+      an=i;
+    else
+      en=i;
+  }
+}
+
+/*2
+* looks up the position of polynomial p in set
+* e is the ecart of p
+* set[length] is the smallest element in set with respect
+* to the ordering-procedure totaldegree
+*/
+int posInL17 (const LSet set, const int length,
+              LObject* p,const kStrategy)
+{
+  if (length<0) return 0;
+
+  int o = p->GetpFDeg() + p->ecart;
+
+  if ((set[length].GetpFDeg() + set[length].ecart > o)
+  || ((set[length].GetpFDeg() + set[length].ecart == o)
+     && (set[length].ecart > p->ecart))
+  || ((set[length].GetpFDeg() + set[length].ecart == o)
+     && (set[length].ecart == p->ecart)
+     && (pLmCmp(set[length].p,p->p) != -currRing->OrdSgn)))
+    return length+1;
+  int i;
+  int an = 0;
+  int en= length;
+  loop
+  {
+    if (an >= en-1)
+    {
+      if ((set[an].GetpFDeg() + set[an].ecart > o)
+      || ((set[an].GetpFDeg() + set[an].ecart == o)
+         && (set[an].ecart > p->ecart))
+      || ((set[an].GetpFDeg() + set[an].ecart == o)
+         && (set[an].ecart == p->ecart)
+         && (pLmCmp(set[an].p,p->p) != -currRing->OrdSgn)))
+        return en;
+      return an;
+    }
+    i=(an+en) / 2;
+    if ((set[i].GetpFDeg() + set[i].ecart > o)
+    || ((set[i].GetpFDeg() + set[i].ecart == o)
+       && (set[i].ecart > p->ecart))
+    || ((set[i].GetpFDeg() +set[i].ecart == o)
+       && (set[i].ecart == p->ecart)
+       && (pLmCmp(set[i].p,p->p) != -currRing->OrdSgn)))
+      an=i;
+    else
+      en=i;
+  }
+}
+/*2
+* looks up the position of polynomial p in set
+* e is the ecart of p
+* set[length] is the smallest element in set with respect
+* to the ordering-procedure pComp
+*/
+int posInL17_c (const LSet set, const int length,
+                LObject* p,const kStrategy)
+{
+  if (length<0) return 0;
+
+  int cc = (-1+2*currRing->order[0]==ringorder_c);
+  /* cc==1 for (c,..), cc==-1 for (C,..) */
+  unsigned long c = pGetComp(p->p)*cc;
+  int o = p->GetpFDeg() + p->ecart;
+
+  if (pGetComp(set[length].p)*cc > c)
+    return length+1;
+  if (pGetComp(set[length].p)*cc == c)
+  {
+    if ((set[length].GetpFDeg() + set[length].ecart > o)
+    || ((set[length].GetpFDeg() + set[length].ecart == o)
+       && (set[length].ecart > p->ecart))
+    || ((set[length].GetpFDeg() + set[length].ecart == o)
+       && (set[length].ecart == p->ecart)
+       && (pLmCmp(set[length].p,p->p) != -currRing->OrdSgn)))
+      return length+1;
+  }
+  int i;
+  int an = 0;
+  int en= length;
+  loop
+  {
+    if (an >= en-1)
+    {
+      if (pGetComp(set[an].p)*cc > c)
+        return en;
+      if (pGetComp(set[an].p)*cc == c)
+      {
+        if ((set[an].GetpFDeg() + set[an].ecart > o)
+        || ((set[an].GetpFDeg() + set[an].ecart == o)
+           && (set[an].ecart > p->ecart))
+        || ((set[an].GetpFDeg() + set[an].ecart == o)
+           && (set[an].ecart == p->ecart)
+           && (pLmCmp(set[an].p,p->p) != -currRing->OrdSgn)))
+          return en;
+      }
+      return an;
+    }
+    i=(an+en) / 2;
+    if (pGetComp(set[i].p)*cc > c)
+      an=i;
+    else if (pGetComp(set[i].p)*cc == c)
+    {
+      if ((set[i].GetpFDeg() + set[i].ecart > o)
+      || ((set[i].GetpFDeg() + set[i].ecart == o)
+         && (set[i].ecart > p->ecart))
+      || ((set[i].GetpFDeg() +set[i].ecart == o)
+         && (set[i].ecart == p->ecart)
+         && (pLmCmp(set[i].p,p->p) != -currRing->OrdSgn)))
+        an=i;
+      else
+        en=i;
+    }
+    else
+      en=i;
+  }
+}
+
+/*
+ * SYZYGY CRITERION for signature-based standard basis algorithms
+ */
+BOOLEAN syzCriterion(poly sig, unsigned long not_sevSig, kStrategy strat)
+{
+//#if 1
+#ifdef DEBUGF5
+  Print("syzygy criterion checks:  ");
+  pWrite(sig);
+#endif
+  for (int k=0; k<strat->syzl; k++)
+  {
+    //printf("-%d",k);
+//#if 1
+#ifdef DEBUGF5
+    Print("checking with: %d / %d --  \n",k,strat->syzl);
+    pWrite(pHead(strat->syz[k]));
+#endif
+    if (p_LmShortDivisibleBy(strat->syz[k], strat->sevSyz[k], sig, not_sevSig, currRing))
+    {
+//#if 1
+#ifdef DEBUGF5
+      PrintS("DELETE!\n");
+#endif
+      //printf("- T -\n\n");
+      return TRUE;
+    }
+  }
+  //printf("- F -\n\n");
+  return FALSE;
+}
+
+/*
+ * SYZYGY CRITERION for signature-based standard basis algorithms
+ */
+BOOLEAN syzCriterionInc(poly sig, unsigned long not_sevSig, kStrategy strat)
+{
+//#if 1
+#ifdef DEBUGF5
+  Print("--- syzygy criterion checks:  ");
+  pWrite(sig);
+#endif
+  int comp = p_GetComp(sig, currRing);
+  int min, max;
+  if (comp<=1)
+    return FALSE;
+  else
+  {
+    min = strat->syzIdx[comp-2];
+    //printf("SYZIDX %d/%d\n",strat->syzIdx[comp-2],comp-2);
+    //printf("SYZIDX %d/%d\n",strat->syzIdx[comp-1],comp-1);
+    //printf("SYZIDX %d/%d\n",strat->syzIdx[comp],comp);
+    if (comp == strat->currIdx)
+    {
+      max = strat->syzl;
+    }
+    else
+    {
+      max = strat->syzIdx[comp-1];
+    }
+    for (int k=min; k<max; k++)
+    {
+#ifdef F5DEBUG
+      Print("COMP %d/%d - MIN %d - MAX %d - SYZL %ld\n",comp,strat->currIdx,min,max,strat->syzl);
+      Print("checking with: %d --  ",k);
+      pWrite(pHead(strat->syz[k]));
+#endif
+      if (p_LmShortDivisibleBy(strat->syz[k], strat->sevSyz[k], sig, not_sevSig, currRing))
+        return TRUE;
+    }
+    return FALSE;
+  }
+}
+
+/*
+ * REWRITTEN CRITERION for signature-based standard basis algorithms
+ */
+BOOLEAN faugereRewCriterion(poly sig, unsigned long not_sevSig, poly /*lm*/, kStrategy strat, int start=0)
+{
+  //printf("Faugere Rewritten Criterion\n");
+//#if 1
+#ifdef DEBUGF5
+  PrintS("rewritten criterion checks:  ");
+  pWrite(sig);
+#endif
+  for(int k = strat->sl; k>=start; k--)
+  {
+//#if 1
+#ifdef DEBUGF5
+    Print("checking with:  ");
+    pWrite(strat->sig[k]);
+    pWrite(pHead(strat->S[k]));
+#endif
+    if (p_LmShortDivisibleBy(strat->sig[k], strat->sevSig[k], sig, not_sevSig, currRing))
+    {
+//#if 1
+#ifdef DEBUGF5
+      PrintS("DELETE!\n");
+#endif
+      return TRUE;
+    }
+    //k--;
+  }
+#ifdef DEBUGF5
+  Print("ALL ELEMENTS OF S\n----------------------------------------\n");
+  for(int kk = 0; kk<strat->sl+1; kk++)
+  {
+    pWrite(pHead(strat->S[kk]));
+  }
+  Print("------------------------------\n");
+#endif
+  return FALSE;
+}
+
+/*
+ * REWRITTEN CRITERION for signature-based standard basis algorithms
+ ***************************************************************************
+ * TODO:This should become the version of Arri/Perry resp. Bjarke/Stillman *
+ ***************************************************************************
+ */
+
+// real implementation of arri's rewritten criterion, only called once in
+// kstd2.cc, right before starting reduction
+// IDEA:  Arri says that it is enough to consider 1 polynomial for each unique
+//        signature appearing during the computations. Thus we first of all go
+//        through strat->L and delete all other pairs of the same signature,
+//        keeping only the one with least possible leading monomial. After this
+//        we check if we really need to compute this critical pair at all: There
+//        can be elements already in strat->S whose signatures divide the
+//        signature of the critical pair in question and whose multiplied
+//        leading monomials are smaller than the leading monomial of the
+//        critical pair. In this situation we can discard the critical pair
+//        completely.
+BOOLEAN arriRewCriterion(poly /*sig*/, unsigned long /*not_sevSig*/, poly /*lm*/, kStrategy strat, int start=0)
+{
+  poly p1 = pOne();
+  poly p2 = pOne();
+  for (int ii=strat->sl; ii>start; ii--)
+  {
+    if (p_LmShortDivisibleBy(strat->sig[ii], strat->sevSig[ii], strat->P.sig, ~strat->P.sevSig, currRing))
+    {
+      p_ExpVectorSum(p1,strat->P.sig,strat->S[ii],currRing);
+      p_ExpVectorSum(p2,strat->sig[ii],strat->P.p,currRing);
+      if (!(pLmCmp(p1,p2) == 1))
+      {
+        pDelete(&p1);
+        pDelete(&p2);
+        return TRUE;
+      }
+    }
+  }
+  pDelete(&p1);
+  pDelete(&p2);
+  return FALSE;
+}
+
+BOOLEAN arriRewCriterionPre(poly sig, unsigned long not_sevSig, poly lm, kStrategy strat, int /*start=0*/)
+{
+  int found = -1;
+  for (int i=strat->Bl; i>-1; i--) {
+    if (pLmEqual(strat->B[i].sig,sig)) {
+      found = i;
+      break;
+    }
+  }
+  if (found != -1) {
+    if (pLmCmp(lm,strat->B[found].GetLmCurrRing()) == -1) {
+      deleteInL(strat->B,&strat->Bl,found,strat);
+    } else {
+      return TRUE;
+    }
+  }
+  poly p1 = pOne();
+  poly p2 = pOne();
+  for (int ii=strat->sl; ii>-1; ii--)
+  {
+    if (p_LmShortDivisibleBy(strat->sig[ii], strat->sevSig[ii], sig, not_sevSig, currRing))
+    {
+      p_ExpVectorSum(p1,sig,strat->S[ii],currRing);
+      p_ExpVectorSum(p2,strat->sig[ii],lm,currRing);
+      if (!(pLmCmp(p1,p2) == 1))
+      {
+        pDelete(&p1);
+        pDelete(&p2);
+        return TRUE;
+      }
+    }
+  }
+  pDelete(&p1);
+  pDelete(&p2);
+  return FALSE;
+}
+
+/***************************************************************
+ *
+ * Tail reductions
+ *
+ ***************************************************************/
+TObject*
+kFindDivisibleByInS(kStrategy strat, int pos, LObject* L, TObject *T,
+                    long ecart)
+{
+  int j = 0;
+  const unsigned long not_sev = ~L->sev;
+  const unsigned long* sev = strat->sevS;
+  poly p;
+  ring r;
+  L->GetLm(p, r);
+
+  assume(~not_sev == p_GetShortExpVector(p, r));
+
+  if (r == currRing)
+  {
+    loop
+    {
+      if (j > pos) return NULL;
+#if defined(PDEBUG) || defined(PDIV_DEBUG)
+      if (p_LmShortDivisibleBy(strat->S[j], sev[j], p, not_sev, r) &&
+          (ecart== LONG_MAX || ecart>= strat->ecartS[j]))
+        break;
+#else
+      if (!(sev[j] & not_sev) &&
+          (ecart== LONG_MAX || ecart>= strat->ecartS[j]) &&
+          p_LmDivisibleBy(strat->S[j], p, r))
+        break;
+
+#endif
+      j++;
+    }
+    // if called from NF, T objects do not exist:
+    if (strat->tl < 0 || strat->S_2_R[j] == -1)
+    {
+      T->Set(strat->S[j], r, strat->tailRing);
+      return T;
+    }
+    else
+    {
+/////      assume (j >= 0 && j <= strat->tl && strat->S_2_T(j) != NULL
+/////      && strat->S_2_T(j)->p == strat->S[j]); // wrong?
+//      assume (j >= 0 && j <= strat->sl && strat->S_2_T(j) != NULL && strat->S_2_T(j)->p == strat->S[j]);
+      return strat->S_2_T(j);
+    }
+  }
+  else
+  {
+    TObject* t;
+    loop
+    {
+      if (j > pos) return NULL;
+      assume(strat->S_2_R[j] != -1);
+#if defined(PDEBUG) || defined(PDIV_DEBUG)
+      t = strat->S_2_T(j);
+      assume(t != NULL && t->t_p != NULL && t->tailRing == r);
+      if (p_LmShortDivisibleBy(t->t_p, sev[j], p, not_sev, r) &&
+          (ecart== LONG_MAX || ecart>= strat->ecartS[j]))
+        return t;
+#else
+      if (! (sev[j] & not_sev) && (ecart== LONG_MAX || ecart>= strat->ecartS[j]))
+      {
+        t = strat->S_2_T(j);
+        assume(t != NULL && t->t_p != NULL && t->tailRing == r && t->p == strat->S[j]);
+        if (p_LmDivisibleBy(t->t_p, p, r)) return t;
+      }
+#endif
+      j++;
+    }
+  }
+}
+
+poly redtail (LObject* L, int pos, kStrategy strat)
+{
+  poly h, hn;
+  strat->redTailChange=FALSE;
+
+  poly p = L->p;
+  if (strat->noTailReduction || pNext(p) == NULL)
+    return p;
+
+  LObject Ln(strat->tailRing);
+  TObject* With;
+  // placeholder in case strat->tl < 0
+  TObject  With_s(strat->tailRing);
+  h = p;
+  hn = pNext(h);
+  long op = strat->tailRing->pFDeg(hn, strat->tailRing);
+  long e;
+  int l;
+  BOOLEAN save_HE=strat->kHEdgeFound;
+  strat->kHEdgeFound |=
+    ((Kstd1_deg>0) && (op<=Kstd1_deg)) || TEST_OPT_INFREDTAIL;
+
+  while(hn != NULL)
+  {
+    op = strat->tailRing->pFDeg(hn, strat->tailRing);
+    if ((Kstd1_deg>0)&&(op>Kstd1_deg)) goto all_done;
+    e = strat->tailRing->pLDeg(hn, &l, strat->tailRing) - op;
+    loop
+    {
+      Ln.Set(hn, strat->tailRing);
+      Ln.sev = p_GetShortExpVector(hn, strat->tailRing);
+      if (strat->kHEdgeFound)
+        With = kFindDivisibleByInS(strat, pos, &Ln, &With_s);
+      else
+        With = kFindDivisibleByInS(strat, pos, &Ln, &With_s, e);
+      if (With == NULL) break;
+      With->length=0;
+      With->pLength=0;
+      strat->redTailChange=TRUE;
+      if (ksReducePolyTail(L, With, h, strat->kNoetherTail()))
+      {
+        // reducing the tail would violate the exp bound
+        if (kStratChangeTailRing(strat, L))
+        {
+          strat->kHEdgeFound = save_HE;
+          return redtail(L, pos, strat);
+        }
+        else
+          return NULL;
+      }
+      hn = pNext(h);
+      if (hn == NULL) goto all_done;
+      op = strat->tailRing->pFDeg(hn, strat->tailRing);
+      if ((Kstd1_deg>0)&&(op>Kstd1_deg)) goto all_done;
+      e = strat->tailRing->pLDeg(hn, &l, strat->tailRing) - op;
+    }
+    h = hn;
+    hn = pNext(h);
+  }
+
+  all_done:
+  if (strat->redTailChange)
+  {
+    L->pLength = 0;
+  }
+  strat->kHEdgeFound = save_HE;
+  return p;
+}
+
+poly redtail (poly p, int pos, kStrategy strat)
+{
+  LObject L(p, currRing);
+  return redtail(&L, pos, strat);
+}
+
+poly redtailBba (LObject* L, int pos, kStrategy strat, BOOLEAN withT, BOOLEAN normalize)
+{
+#define REDTAIL_CANONICALIZE 100
+  strat->redTailChange=FALSE;
+  if (strat->noTailReduction) return L->GetLmCurrRing();
+  poly h, p;
+  p = h = L->GetLmTailRing();
+  if ((h==NULL) || (pNext(h)==NULL))
+    return L->GetLmCurrRing();
+
+  TObject* With;
+  // placeholder in case strat->tl < 0
+  TObject  With_s(strat->tailRing);
+
+  LObject Ln(pNext(h), strat->tailRing);
+  Ln.pLength = L->GetpLength() - 1;
+
+  pNext(h) = NULL;
+  if (L->p != NULL) pNext(L->p) = NULL;
+  L->pLength = 1;
+
+  Ln.PrepareRed(strat->use_buckets);
+
+  int cnt=REDTAIL_CANONICALIZE;
+  while(!Ln.IsNull())
+  {
+    loop
+    {
+      Ln.SetShortExpVector();
+      if (withT)
+      {
+        int j;
+        j = kFindDivisibleByInT(strat->T, strat->sevT, strat->tl, &Ln);
+        if (j < 0) break;
+        With = &(strat->T[j]);
+      }
+      else
+      {
+        With = kFindDivisibleByInS(strat, pos, &Ln, &With_s);
+        if (With == NULL) break;
+      }
+      cnt--;
+      if (cnt==0)
+      {
+        cnt=REDTAIL_CANONICALIZE;
+        /*poly tmp=*/Ln.CanonicalizeP();
+        if (normalize)
+        {
+          Ln.Normalize();
+          //pNormalize(tmp);
+          //if (TEST_OPT_PROT) { PrintS("n"); mflush(); }
+        }
+      }
+      if (normalize && (!TEST_OPT_INTSTRATEGY) && (!nIsOne(pGetCoeff(With->p))))
+      {
+        With->pNorm();
+      }
+      strat->redTailChange=TRUE;
+      if (ksReducePolyTail(L, With, &Ln))
+      {
+        // reducing the tail would violate the exp bound
+        //  set a flag and hope for a retry (in bba)
+        strat->completeReduce_retry=TRUE;
+        if ((Ln.p != NULL) && (Ln.t_p != NULL)) Ln.p=NULL;
+        do
+        {
+          pNext(h) = Ln.LmExtractAndIter();
+          pIter(h);
+          L->pLength++;
+        } while (!Ln.IsNull());
+        goto all_done;
+      }
+      if (Ln.IsNull()) goto all_done;
+      if (! withT) With_s.Init(currRing);
+    }
+    pNext(h) = Ln.LmExtractAndIter();
+    pIter(h);
+    pNormalize(h);
+    L->pLength++;
+  }
+
+  all_done:
+  Ln.Delete();
+  if (L->p != NULL) pNext(L->p) = pNext(p);
+
+  if (strat->redTailChange)
+  {
+    L->length = 0;
+    L->pLength = 0;
+  }
+
+  //if (TEST_OPT_PROT) { PrintS("N"); mflush(); }
+  //L->Normalize(); // HANNES: should have a test
+  kTest_L(L);
+  return L->GetLmCurrRing();
+}
+
+#ifdef HAVE_RINGS
+poly redtailBba_Z (LObject* L, int pos, kStrategy strat )
+// normalize=FALSE, withT=FALSE, coeff=Z
+{
+  strat->redTailChange=FALSE;
+  if (strat->noTailReduction) return L->GetLmCurrRing();
+  poly h, p;
+  p = h = L->GetLmTailRing();
+  if ((h==NULL) || (pNext(h)==NULL))
+    return L->GetLmCurrRing();
+
+  TObject* With;
+  // placeholder in case strat->tl < 0
+  TObject  With_s(strat->tailRing);
+
+  LObject Ln(pNext(h), strat->tailRing);
+  Ln.pLength = L->GetpLength() - 1;
+
+  pNext(h) = NULL;
+  if (L->p != NULL) pNext(L->p) = NULL;
+  L->pLength = 1;
+
+  Ln.PrepareRed(strat->use_buckets);
+
+  int cnt=REDTAIL_CANONICALIZE;
+  while(!Ln.IsNull())
+  {
+    loop
+    {
+      Ln.SetShortExpVector();
+      With = kFindDivisibleByInS(strat, pos, &Ln, &With_s);
+      if (With == NULL) break;
+      cnt--;
+      if (cnt==0)
+      {
+        cnt=REDTAIL_CANONICALIZE;
+        /*poly tmp=*/Ln.CanonicalizeP();
+      }
+      // we are in Z, do not call pNorm
+      strat->redTailChange=TRUE;
+      // test divisibility of coefs:
+      poly p_Ln=Ln.GetLmCurrRing();
+      poly p_With=With->GetLmCurrRing();
+      number z=n_IntMod(pGetCoeff(p_Ln),pGetCoeff(p_With), currRing->cf);
+      if (!nIsZero(z))
+      {
+        // subtract z*Ln, add z.Ln to L
+        poly m=pHead(p_Ln);
+        pSetCoeff(m,z);
+        poly mm=pHead(m);
+        pNext(h) = m;
+        pIter(h);
+        L->pLength++;
+        mm=pNeg(mm);
+        if (Ln.bucket!=NULL)
+        {
+          int dummy=1;
+          kBucket_Add_q(Ln.bucket,mm,&dummy);
+        }
+        else
+        {
+          if ((Ln.t_p!=NULL)&&(Ln.p==NULL))
+            Ln.GetP();
+          if (Ln.p!=NULL)
+          {
+            Ln.p=pAdd(Ln.p,mm);
+            if (Ln.t_p!=NULL)
+            {
+              pNext(Ln.t_p)=NULL;
+              p_LmDelete(Ln.t_p,strat->tailRing);
+            }
+          }
+        }
+      }
+      else
+        nDelete(&z);
+
+      if (ksReducePolyTail(L, With, &Ln))
+      {
+        // reducing the tail would violate the exp bound
+        //  set a flag and hope for a retry (in bba)
+        strat->completeReduce_retry=TRUE;
+        if ((Ln.p != NULL) && (Ln.t_p != NULL)) Ln.p=NULL;
+        do
+        {
+          pNext(h) = Ln.LmExtractAndIter();
+          pIter(h);
+          L->pLength++;
+        } while (!Ln.IsNull());
+        goto all_done;
+      }
+      if (Ln.IsNull()) goto all_done;
+      With_s.Init(currRing);
+    }
+    pNext(h) = Ln.LmExtractAndIter();
+    pIter(h);
+    pNormalize(h);
+    L->pLength++;
+  }
+
+  all_done:
+  Ln.Delete();
+  if (L->p != NULL) pNext(L->p) = pNext(p);
+
+  if (strat->redTailChange)
+  {
+    L->length = 0;
+  }
+
+  //if (TEST_OPT_PROT) { PrintS("N"); mflush(); }
+  //L->Normalize(); // HANNES: should have a test
+  kTest_L(L);
+  return L->GetLmCurrRing();
+}
+#endif
+
+/*2
+*checks the change degree and write progress report
+*/
+void message (int i,int* reduc,int* olddeg,kStrategy strat, int red_result)
+{
+  if (i != *olddeg)
+  {
+    Print("%d",i);
+    *olddeg = i;
+  }
+  if (TEST_OPT_OLDSTD)
+  {
+    if (strat->Ll != *reduc)
+    {
+      if (strat->Ll != *reduc-1)
+        Print("(%d)",strat->Ll+1);
+      else
+        PrintS("-");
+      *reduc = strat->Ll;
+    }
+    else
+      PrintS(".");
+    mflush();
+  }
+  else
+  {
+    if (red_result == 0)
+      PrintS("-");
+    else if (red_result < 0)
+      PrintS(".");
+    if ((red_result > 0) || ((strat->Ll % 100)==99))
+    {
+      if (strat->Ll != *reduc && strat->Ll > 0)
+      {
+        Print("(%d)",strat->Ll+1);
+        *reduc = strat->Ll;
+      }
+    }
+  }
+}
+
+/*2
+*statistics
+*/
+void messageStat (int hilbcount,kStrategy strat)
+{
+  //PrintS("\nUsage/Allocation of temporary storage:\n");
+  //Print("%d/%d polynomials in standard base\n",srmax,IDELEMS(Shdl));
+  //Print("%d/%d polynomials in set L (for lazy alg.)",lrmax+1,strat->Lmax);
+  Print("product criterion:%d chain criterion:%d\n",strat->cp,strat->c3);
+  if (hilbcount!=0) Print("hilbert series criterion:%d\n",hilbcount);
+  /* in usual case strat->cv is 0, it gets changed only in shift routines */
+  if (strat->cv!=0) Print("shift V criterion:%d\n",strat->cv);
+  /*mflush();*/
+}
+
+#ifdef KDEBUG
+/*2
+*debugging output: all internal sets, if changed
+*for testing purpuse only/has to be changed for later use
+*/
+void messageSets (kStrategy strat)
+{
+  int i;
+  if (strat->news)
+  {
+    PrintS("set S");
+    for (i=0; i<=strat->sl; i++)
+    {
+      Print("\n  %d:",i);
+      p_wrp(strat->S[i], currRing, strat->tailRing);
+    }
+    strat->news = FALSE;
+  }
+  if (strat->newt)
+  {
+    PrintS("\nset T");
+    for (i=0; i<=strat->tl; i++)
+    {
+      Print("\n  %d:",i);
+      strat->T[i].wrp();
+      Print(" o:%ld e:%d l:%d",
+        strat->T[i].pFDeg(),strat->T[i].ecart,strat->T[i].length);
+    }
+    strat->newt = FALSE;
+  }
+  PrintS("\nset L");
+  for (i=strat->Ll; i>=0; i--)
+  {
+    Print("\n%d:",i);
+    p_wrp(strat->L[i].p1, currRing, strat->tailRing);
+    PrintS("  ");
+    p_wrp(strat->L[i].p2, currRing, strat->tailRing);
+    PrintS(" lcm: ");p_wrp(strat->L[i].lcm, currRing);
+    PrintS("\n  p : ");
+    strat->L[i].wrp();
+    Print("  o:%ld e:%d l:%d",
+          strat->L[i].pFDeg(),strat->L[i].ecart,strat->L[i].length);
+  }
+  PrintLn();
+}
+
+#endif
+
+
+/*2
+*construct the set s from F
+*/
+void initS (ideal F, ideal Q, kStrategy strat)
+{
+  int   i,pos;
+
+  if (Q!=NULL) i=((IDELEMS(F)+IDELEMS(Q)+(setmaxTinc-1))/setmaxTinc)*setmaxTinc;
+  else         i=((IDELEMS(F)+(setmaxTinc-1))/setmaxTinc)*setmaxTinc;
+  strat->ecartS=initec(i);
+  strat->sevS=initsevS(i);
+  strat->S_2_R=initS_2_R(i);
+  strat->fromQ=NULL;
+  strat->Shdl=idInit(i,F->rank);
+  strat->S=strat->Shdl->m;
+  /*- put polys into S -*/
+  if (Q!=NULL)
+  {
+    strat->fromQ=initec(i);
+    memset(strat->fromQ,0,i*sizeof(int));
+    for (i=0; i<IDELEMS(Q); i++)
+    {
+      if (Q->m[i]!=NULL)
+      {
+        LObject h;
+        h.p = pCopy(Q->m[i]);
+        if (TEST_OPT_INTSTRATEGY)
+        {
+          //pContent(h.p);
+          h.pCleardenom(); // also does a pContent
+        }
+        else
+        {
+          h.pNorm();
+        }
+        if (rHasLocalOrMixedOrdering(currRing))
+        {
+          deleteHC(&h, strat);
+        }
+        if (h.p!=NULL)
+        {
+          strat->initEcart(&h);
+          if (strat->sl==-1)
+            pos =0;
+          else
+          {
+            pos = posInS(strat,strat->sl,h.p,h.ecart);
+          }
+          h.sev = pGetShortExpVector(h.p);
+          strat->enterS(h,pos,strat,-1);
+          strat->fromQ[pos]=1;
+        }
+      }
+    }
+  }
+  for (i=0; i<IDELEMS(F); i++)
+  {
+    if (F->m[i]!=NULL)
+    {
+      LObject h;
+      h.p = pCopy(F->m[i]);
+      if (rHasLocalOrMixedOrdering(currRing))
+      {
+                    /*#ifdef HAVE_RINGS
+                          if (rField_is_Ring(currRing))
+                            {
+                            h.pCleardenom();
+                            }
+                          else
+                                #endif*/
+        cancelunit(&h);  /*- tries to cancel a unit -*/
+        deleteHC(&h, strat);
+      }
+      if (h.p!=NULL)
+      // do not rely on the input being a SB!
+      {
+        if (TEST_OPT_INTSTRATEGY)
+        {
+          //pContent(h.p);
+          h.pCleardenom(); // also does a pContent
+        }
+        else
+        {
+          h.pNorm();
+        }
+        strat->initEcart(&h);
+        if (strat->sl==-1)
+          pos =0;
+        else
+          pos = posInS(strat,strat->sl,h.p,h.ecart);
+        h.sev = pGetShortExpVector(h.p);
+        strat->enterS(h,pos,strat,-1);
+      }
+    }
+  }
+  /*- test, if a unit is in F -*/
+  if ((strat->sl>=0)
+#ifdef HAVE_RINGS
+       && n_IsUnit(pGetCoeff(strat->S[0]),currRing->cf)
+#endif
+       && pIsConstant(strat->S[0]))
+  {
+    while (strat->sl>0) deleteInS(strat->sl,strat);
+  }
+}
+
+void initSL (ideal F, ideal Q,kStrategy strat)
+{
+  int   i,pos;
+
+  if (Q!=NULL) i=((IDELEMS(Q)+(setmaxTinc-1))/setmaxTinc)*setmaxTinc;
+  else i=setmaxT;
+  strat->ecartS=initec(i);
+  strat->sevS=initsevS(i);
+  strat->S_2_R=initS_2_R(i);
+  strat->fromQ=NULL;
+  strat->Shdl=idInit(i,F->rank);
+  strat->S=strat->Shdl->m;
+  /*- put polys into S -*/
+  if (Q!=NULL)
+  {
+    strat->fromQ=initec(i);
+    memset(strat->fromQ,0,i*sizeof(int));
+    for (i=0; i<IDELEMS(Q); i++)
+    {
+      if (Q->m[i]!=NULL)
+      {
+        LObject h;
+        h.p = pCopy(Q->m[i]);
+        if (rHasLocalOrMixedOrdering(currRing))
+        {
+          deleteHC(&h,strat);
+        }
+        if (TEST_OPT_INTSTRATEGY)
+        {
+          //pContent(h.p);
+          h.pCleardenom(); // also does a pContent
+        }
+        else
+        {
+          h.pNorm();
+        }
+        if (h.p!=NULL)
+        {
+          strat->initEcart(&h);
+          if (strat->sl==-1)
+            pos =0;
+          else
+          {
+            pos = posInS(strat,strat->sl,h.p,h.ecart);
+          }
+          h.sev = pGetShortExpVector(h.p);
+          strat->enterS(h,pos,strat,-1);
+          strat->fromQ[pos]=1;
+        }
+      }
+    }
+  }
+  for (i=0; i<IDELEMS(F); i++)
+  {
+    if (F->m[i]!=NULL)
+    {
+      LObject h;
+      h.p = pCopy(F->m[i]);
+      if (h.p!=NULL)
+      {
+        if (rHasLocalOrMixedOrdering(currRing))
+        {
+          cancelunit(&h);  /*- tries to cancel a unit -*/
+          deleteHC(&h, strat);
+        }
+        if (h.p!=NULL)
+        {
+          if (TEST_OPT_INTSTRATEGY)
+          {
+            //pContent(h.p);
+            h.pCleardenom(); // also does a pContent
+          }
+          else
+          {
+            h.pNorm();
+          }
+          strat->initEcart(&h);
+          if (strat->Ll==-1)
+            pos =0;
+          else
+            pos = strat->posInL(strat->L,strat->Ll,&h,strat);
+          h.sev = pGetShortExpVector(h.p);
+          enterL(&strat->L,&strat->Ll,&strat->Lmax,h,pos);
+        }
+      }
+    }
+  }
+  /*- test, if a unit is in F -*/
+
+  if ((strat->Ll>=0)
+#ifdef HAVE_RINGS
+       && n_IsUnit(pGetCoeff(strat->L[strat->Ll].p), currRing->cf)
+#endif
+       && pIsConstant(strat->L[strat->Ll].p))
+  {
+    while (strat->Ll>0) deleteInL(strat->L,&strat->Ll,strat->Ll-1,strat);
+  }
+}
+
+void initSLSba (ideal F, ideal Q,kStrategy strat)
+{
+  int   i,pos;
+  if (Q!=NULL) i=((IDELEMS(Q)+(setmaxTinc-1))/setmaxTinc)*setmaxTinc;
+  else i=setmaxT;
+  strat->ecartS =   initec(i);
+  strat->sevS   =   initsevS(i);
+  strat->sevSig =   initsevS(i);
+  strat->S_2_R  =   initS_2_R(i);
+  strat->fromQ  =   NULL;
+  strat->Shdl   =   idInit(i,F->rank);
+  strat->S      =   strat->Shdl->m;
+  strat->sig    =   (poly *)omAlloc0(i*sizeof(poly));
+  if (strat->sbaOrder != 1)
+  {
+    strat->syz    = (poly *)omAlloc0(i*sizeof(poly));
+    strat->sevSyz = initsevS(i);
+    strat->syzmax = i;
+    strat->syzl   = 0;
+  }
+  /*- put polys into S -*/
+  if (Q!=NULL)
+  {
+    strat->fromQ=initec(i);
+    memset(strat->fromQ,0,i*sizeof(int));
+    for (i=0; i<IDELEMS(Q); i++)
+    {
+      if (Q->m[i]!=NULL)
+      {
+        LObject h;
+        h.p = pCopy(Q->m[i]);
+        if (rHasLocalOrMixedOrdering(currRing))
+        {
+          deleteHC(&h,strat);
+        }
+        if (TEST_OPT_INTSTRATEGY)
+        {
+          //pContent(h.p);
+          h.pCleardenom(); // also does a pContent
+        }
+        else
+        {
+          h.pNorm();
+        }
+        if (h.p!=NULL)
+        {
+          strat->initEcart(&h);
+          if (strat->sl==-1)
+            pos =0;
+          else
+          {
+            pos = posInS(strat,strat->sl,h.p,h.ecart);
+          }
+          h.sev = pGetShortExpVector(h.p);
+          strat->enterS(h,pos,strat,-1);
+          strat->fromQ[pos]=1;
+        }
+      }
+    }
+  }
+  for (i=0; i<IDELEMS(F); i++)
+  {
+    if (F->m[i]!=NULL)
+    {
+      LObject h;
+      h.p = pCopy(F->m[i]);
+      h.sig = pOne();
+      //h.sig = pInit();
+      //p_SetCoeff(h.sig,nInit(1),currRing);
+      p_SetComp(h.sig,i+1,currRing);
+      // if we are working with the Schreyer order we generate it
+      // by multiplying the initial signatures with the leading monomial
+      // of the corresponding initial polynomials generating the ideal
+      // => we can keep the underlying monomial order and get a Schreyer
+      //    order without any bigger overhead
+      if (strat->sbaOrder == 0 || strat->sbaOrder == 3)
+      {
+        p_ExpVectorAdd (h.sig,F->m[i],currRing);
+      }
+      h.sevSig = pGetShortExpVector(h.sig);
+#ifdef DEBUGF5
+      pWrite(h.p);
+      pWrite(h.sig);
+#endif
+      if (h.p!=NULL)
+      {
+        if (rHasLocalOrMixedOrdering(currRing))
+        {
+          cancelunit(&h);  /*- tries to cancel a unit -*/
+          deleteHC(&h, strat);
+        }
+        if (h.p!=NULL)
+        {
+          if (TEST_OPT_INTSTRATEGY)
+          {
+            //pContent(h.p);
+            h.pCleardenom(); // also does a pContent
+          }
+          else
+          {
+            h.pNorm();
+          }
+          strat->initEcart(&h);
+          if (strat->Ll==-1)
+            pos =0;
+          else
+            pos = strat->posInLSba(strat->L,strat->Ll,&h,strat);
+          h.sev = pGetShortExpVector(h.p);
+          enterL(&strat->L,&strat->Ll,&strat->Lmax,h,pos);
+        }
+      }
+      /*
+      if (strat->sbaOrder != 1)
+      {
+        for(j=0;j<i;j++)
+        {
+          strat->syz[ctr] = pCopy(F->m[j]);
+          p_SetCompP(strat->syz[ctr],i+1,currRing);
+          // add LM(F->m[i]) to the signature to get a Schreyer order
+          // without changing the underlying polynomial ring at all
+          p_ExpVectorAdd (strat->syz[ctr],F->m[i],currRing);
+          // since p_Add_q() destroys all input
+          // data we need to recreate help
+          // each time
+          poly help = pCopy(F->m[i]);
+          p_SetCompP(help,j+1,currRing);
+          pWrite(strat->syz[ctr]);
+          pWrite(help);
+          printf("%d\n",pLmCmp(strat->syz[ctr],help));
+          strat->syz[ctr] = p_Add_q(strat->syz[ctr],help,currRing);
+          printf("%d. SYZ  ",ctr);
+          pWrite(strat->syz[ctr]);
+          strat->sevSyz[ctr] = p_GetShortExpVector(strat->syz[ctr],currRing);
+          ctr++;
+        }
+        strat->syzl = ps;
+      }
+      */
+    }
+  }
+  /*- test, if a unit is in F -*/
+
+  if ((strat->Ll>=0)
+#ifdef HAVE_RINGS
+       && n_IsUnit(pGetCoeff(strat->L[strat->Ll].p), currRing->cf)
+#endif
+       && pIsConstant(strat->L[strat->Ll].p))
+  {
+    while (strat->Ll>0) deleteInL(strat->L,&strat->Ll,strat->Ll-1,strat);
+  }
+}
+
+void initSyzRules (kStrategy strat)
+{
+  if( strat->S[0] )
+  {
+    if( strat->S[1] )
+    {
+      omFreeSize(strat->syzIdx,(strat->syzidxmax)*sizeof(int));
+      omFreeSize(strat->sevSyz,(strat->syzmax)*sizeof(unsigned long));
+      omFreeSize(strat->syz,(strat->syzmax)*sizeof(poly));
+    }
+    int i, j, k, diff, comp, comp_old, ps=0, ctr=0;
+    /************************************************************
+     * computing the length of the syzygy array needed
+     ***********************************************************/
+    for(i=1; i<=strat->sl; i++)
+    {
+      if (pGetComp(strat->sig[i-1]) != pGetComp(strat->sig[i]))
+      {
+        ps += i;
+      }
+    }
+    ps += strat->sl+1;
+    //comp              = pGetComp (strat->P.sig);
+    comp              = strat->currIdx;
+    strat->syzIdx     = initec(comp);
+    strat->sevSyz     = initsevS(ps);
+    strat->syz        = (poly *)omAlloc(ps*sizeof(poly));
+    strat->syzmax     = ps;
+    strat->syzl       = 0;
+    strat->syzidxmax  = comp;
+#if defined(DEBUGF5) || defined(DEBUGF51)
+    PrintS("------------- GENERATING SYZ RULES NEW ---------------\n");
+#endif
+    i = 1;
+    j = 0;
+    /************************************************************
+     * generating the leading terms of the principal syzygies
+     ***********************************************************/
+    while (i <= strat->sl)
+    {
+      /**********************************************************
+       * principal syzygies start with component index 2
+       * the array syzIdx starts with index 0
+       * => the rules for a signature with component comp start
+       *    at strat->syz[strat->syzIdx[comp-2]] !
+       *********************************************************/
+      if (pGetComp(strat->sig[i-1]) != pGetComp(strat->sig[i]))
+      {
+        comp      = pGetComp(strat->sig[i]);
+        comp_old  = pGetComp(strat->sig[i-1]);
+        diff      = comp - comp_old - 1;
+        // diff should be zero, but sometimes also the initial generating
+        // elements of the input ideal reduce to zero. then there is an
+        // index-gap between the signatures. for these inbetween signatures we
+        // can safely set syzIdx[j] = 0 as no such element will be ever computed
+        // in the following.
+        // doing this, we keep the relation "j = comp - 2" alive, which makes
+        // jumps way easier when checking criteria
+        while (diff>0)
+        {
+          strat->syzIdx[j]  = 0;
+          diff--;
+          j++;
+        }
+        strat->syzIdx[j]  = ctr;
+        j++;
+        LObject Q;
+        int pos;
+        for (k = 0; k<i; k++)
+        {
+          Q.sig          = pOne();
+          p_ExpVectorCopy(Q.sig,strat->S[k],currRing);
+          p_SetCompP (Q.sig, comp, currRing);
+          poly q          = p_One(currRing);
+          p_ExpVectorCopy(q,strat->S[i],currRing);
+          q               = p_Neg (q, currRing);
+          p_SetCompP (q, p_GetComp(strat->sig[k], currRing), currRing);
+          Q.sig = p_Add_q (Q.sig, q, currRing);
+          Q.sevSig  = p_GetShortExpVector(Q.sig,currRing);
+          pos = posInSyz(strat, Q.sig);
+          enterSyz(Q, strat, pos);
+          ctr++;
+        }
+      }
+      i++;
+    }
+    /**************************************************************
+    * add syzygies for upcoming first element of new iteration step
+    **************************************************************/
+    comp      = strat->currIdx;
+    comp_old  = pGetComp(strat->sig[i-1]);
+    diff      = comp - comp_old - 1;
+    // diff should be zero, but sometimes also the initial generating
+    // elements of the input ideal reduce to zero. then there is an
+    // index-gap between the signatures. for these inbetween signatures we
+    // can safely set syzIdx[j] = 0 as no such element will be ever computed
+    // in the following.
+    // doing this, we keep the relation "j = comp - 2" alive, which makes
+    // jumps way easier when checking criteria
+    while (diff>0)
+    {
+      strat->syzIdx[j]  = 0;
+      diff--;
+      j++;
+    }
+    strat->syzIdx[j]  = ctr;
+    LObject Q;
+    int pos;
+    for (k = 0; k<strat->sl+1; k++)
+    {
+      Q.sig          = pOne();
+      p_ExpVectorCopy(Q.sig,strat->S[k],currRing);
+      p_SetCompP (Q.sig, comp, currRing);
+      poly q          = p_One(currRing);
+      p_ExpVectorCopy(q,strat->L[strat->Ll].p,currRing);
+      q               = p_Neg (q, currRing);
+      p_SetCompP (q, p_GetComp(strat->sig[k], currRing), currRing);
+      Q.sig = p_Add_q (Q.sig, q, currRing);
+      Q.sevSig = p_GetShortExpVector(Q.sig,currRing);
+      pos = posInSyz(strat, Q.sig);
+      enterSyz(Q, strat, pos);
+      ctr++;
+    }
+//#if 1
+#ifdef DEBUGF5
+    PrintS("Principal syzygies:\n");
+    Print("syzl   %d\n",strat->syzl);
+    Print("syzmax %d\n",strat->syzmax);
+    Print("ps     %d\n",ps);
+    PrintS("--------------------------------\n");
+    for(i=0;i<=strat->syzl-1;i++)
+    {
+      Print("%d - ",i);
+      pWrite(strat->syz[i]);
+    }
+    for(i=0;i<strat->currIdx;i++)
+    {
+      Print("%d - %d\n",i,strat->syzIdx[i]);
+    }
+    PrintS("--------------------------------\n");
+#endif
+  }
+}
+
+
+
+/*2
+*construct the set s from F and {P}
+*/
+void initSSpecial (ideal F, ideal Q, ideal P,kStrategy strat)
+{
+  int   i,pos;
+
+  if (Q!=NULL) i=((IDELEMS(Q)+(setmaxTinc-1))/setmaxTinc)*setmaxTinc;
+  else i=setmaxT;
+  i=((i+IDELEMS(F)+IDELEMS(P)+15)/16)*16;
+  strat->ecartS=initec(i);
+  strat->sevS=initsevS(i);
+  strat->S_2_R=initS_2_R(i);
+  strat->fromQ=NULL;
+  strat->Shdl=idInit(i,F->rank);
+  strat->S=strat->Shdl->m;
+
+  /*- put polys into S -*/
+  if (Q!=NULL)
+  {
+    strat->fromQ=initec(i);
+    memset(strat->fromQ,0,i*sizeof(int));
+    for (i=0; i<IDELEMS(Q); i++)
+    {
+      if (Q->m[i]!=NULL)
+      {
+        LObject h;
+        h.p = pCopy(Q->m[i]);
+        //if (TEST_OPT_INTSTRATEGY)
+        //{
+        //  //pContent(h.p);
+        //  h.pCleardenom(); // also does a pContent
+        //}
+        //else
+        //{
+        //  h.pNorm();
+        //}
+        if (rHasLocalOrMixedOrdering(currRing))
+        {
+          deleteHC(&h,strat);
+        }
+        if (h.p!=NULL)
+        {
+          strat->initEcart(&h);
+          if (strat->sl==-1)
+            pos =0;
+          else
+          {
+            pos = posInS(strat,strat->sl,h.p,h.ecart);
+          }
+          h.sev = pGetShortExpVector(h.p);
+          strat->enterS(h,pos,strat, strat->tl+1);
+          enterT(h, strat);
+          strat->fromQ[pos]=1;
+        }
+      }
+    }
+  }
+  /*- put polys into S -*/
+  for (i=0; i<IDELEMS(F); i++)
+  {
+    if (F->m[i]!=NULL)
+    {
+      LObject h;
+      h.p = pCopy(F->m[i]);
+      if (rHasLocalOrMixedOrdering(currRing))
+      {
+        deleteHC(&h,strat);
+      }
+      else
+      {
+        h.p=redtailBba(h.p,strat->sl,strat);
+      }
+      if (h.p!=NULL)
+      {
+        strat->initEcart(&h);
+        if (strat->sl==-1)
+          pos =0;
+        else
+          pos = posInS(strat,strat->sl,h.p,h.ecart);
+        h.sev = pGetShortExpVector(h.p);
+        strat->enterS(h,pos,strat, strat->tl+1);
+        enterT(h,strat);
+      }
+    }
+  }
+  for (i=0; i<IDELEMS(P); i++)
+  {
+    if (P->m[i]!=NULL)
+    {
+      LObject h;
+      h.p=pCopy(P->m[i]);
+      if (TEST_OPT_INTSTRATEGY)
+      {
+        h.pCleardenom();
+      }
+      else
+      {
+        h.pNorm();
+      }
+      if(strat->sl>=0)
+      {
+        if (rHasGlobalOrdering(currRing))
+        {
+          h.p=redBba(h.p,strat->sl,strat);
+          if (h.p!=NULL)
+          {
+            h.p=redtailBba(h.p,strat->sl,strat);
+          }
+        }
+        else
+        {
+          h.p=redMora(h.p,strat->sl,strat);
+        }
+        if(h.p!=NULL)
+        {
+          strat->initEcart(&h);
+          if (TEST_OPT_INTSTRATEGY)
+          {
+            h.pCleardenom();
+          }
+          else
+          {
+            h.is_normalized = 0;
+            h.pNorm();
+          }
+          h.sev = pGetShortExpVector(h.p);
+          h.SetpFDeg();
+          pos = posInS(strat,strat->sl,h.p,h.ecart);
+          enterpairsSpecial(h.p,strat->sl,h.ecart,pos,strat,strat->tl+1);
+          strat->enterS(h,pos,strat, strat->tl+1);
+          enterT(h,strat);
+        }
+      }
+      else
+      {
+        h.sev = pGetShortExpVector(h.p);
+        strat->initEcart(&h);
+        strat->enterS(h,0,strat, strat->tl+1);
+        enterT(h,strat);
+      }
+    }
+  }
+}
+/*2
+*construct the set s from F and {P}
+*/
+
+void initSSpecialSba (ideal F, ideal Q, ideal P,kStrategy strat)
+{
+  int   i,pos;
+
+  if (Q!=NULL) i=((IDELEMS(Q)+(setmaxTinc-1))/setmaxTinc)*setmaxTinc;
+  else i=setmaxT;
+  i=((i+IDELEMS(F)+IDELEMS(P)+15)/16)*16;
+  strat->sevS=initsevS(i);
+  strat->sevSig=initsevS(i);
+  strat->S_2_R=initS_2_R(i);
+  strat->fromQ=NULL;
+  strat->Shdl=idInit(i,F->rank);
+  strat->S=strat->Shdl->m;
+  strat->sig=(poly *)omAlloc0(i*sizeof(poly));
+  /*- put polys into S -*/
+  if (Q!=NULL)
+  {
+    strat->fromQ=initec(i);
+    memset(strat->fromQ,0,i*sizeof(int));
+    for (i=0; i<IDELEMS(Q); i++)
+    {
+      if (Q->m[i]!=NULL)
+      {
+        LObject h;
+        h.p = pCopy(Q->m[i]);
+        //if (TEST_OPT_INTSTRATEGY)
+        //{
+        //  //pContent(h.p);
+        //  h.pCleardenom(); // also does a pContent
+        //}
+        //else
+        //{
+        //  h.pNorm();
+        //}
+        if (rHasLocalOrMixedOrdering(currRing))
+        {
+          deleteHC(&h,strat);
+        }
+        if (h.p!=NULL)
+        {
+          strat->initEcart(&h);
+          if (strat->sl==-1)
+            pos =0;
+          else
+          {
+            pos = posInS(strat,strat->sl,h.p,h.ecart);
+          }
+          h.sev = pGetShortExpVector(h.p);
+          strat->enterS(h,pos,strat, strat->tl+1);
+          enterT(h, strat);
+          strat->fromQ[pos]=1;
+        }
+      }
+    }
+  }
+  /*- put polys into S -*/
+  for (i=0; i<IDELEMS(F); i++)
+  {
+    if (F->m[i]!=NULL)
+    {
+      LObject h;
+      h.p = pCopy(F->m[i]);
+      if (rHasLocalOrMixedOrdering(currRing))
+      {
+        deleteHC(&h,strat);
+      }
+      else
+      {
+        h.p=redtailBba(h.p,strat->sl,strat);
+      }
+      if (h.p!=NULL)
+      {
+        strat->initEcart(&h);
+        if (strat->sl==-1)
+          pos =0;
+        else
+          pos = posInS(strat,strat->sl,h.p,h.ecart);
+        h.sev = pGetShortExpVector(h.p);
+        strat->enterS(h,pos,strat, strat->tl+1);
+        enterT(h,strat);
+      }
+    }
+  }
+  for (i=0; i<IDELEMS(P); i++)
+  {
+    if (P->m[i]!=NULL)
+    {
+      LObject h;
+      h.p=pCopy(P->m[i]);
+      if (TEST_OPT_INTSTRATEGY)
+      {
+        h.pCleardenom();
+      }
+      else
+      {
+        h.pNorm();
+      }
+      if(strat->sl>=0)
+      {
+        if (rHasGlobalOrdering(currRing))
+        {
+          h.p=redBba(h.p,strat->sl,strat);
+          if (h.p!=NULL)
+          {
+            h.p=redtailBba(h.p,strat->sl,strat);
+          }
+        }
+        else
+        {
+          h.p=redMora(h.p,strat->sl,strat);
+        }
+        if(h.p!=NULL)
+        {
+          strat->initEcart(&h);
+          if (TEST_OPT_INTSTRATEGY)
+          {
+            h.pCleardenom();
+          }
+          else
+          {
+            h.is_normalized = 0;
+            h.pNorm();
+          }
+          h.sev = pGetShortExpVector(h.p);
+          h.SetpFDeg();
+          pos = posInS(strat,strat->sl,h.p,h.ecart);
+          enterpairsSpecial(h.p,strat->sl,h.ecart,pos,strat,strat->tl+1);
+          strat->enterS(h,pos,strat, strat->tl+1);
+          enterT(h,strat);
+        }
+      }
+      else
+      {
+        h.sev = pGetShortExpVector(h.p);
+        strat->initEcart(&h);
+        strat->enterS(h,0,strat, strat->tl+1);
+        enterT(h,strat);
+      }
+    }
+  }
+}
+/*2
+* reduces h using the set S
+* procedure used in cancelunit1
+*/
+static poly redBba1 (poly h,int maxIndex,kStrategy strat)
+{
+  int j = 0;
+  unsigned long not_sev = ~ pGetShortExpVector(h);
+
+  while (j <= maxIndex)
+  {
+    if (pLmShortDivisibleBy(strat->S[j],strat->sevS[j],h, not_sev))
+       return ksOldSpolyRedNew(strat->S[j],h,strat->kNoetherTail());
+    else j++;
+  }
+  return h;
+}
+
+/*2
+*tests if p.p=monomial*unit and cancels the unit
+*/
+void cancelunit1 (LObject* p,int *suc, int index,kStrategy strat )
+{
+  int k;
+  poly r,h,h1,q;
+
+  if (!pIsVector((*p).p) && ((*p).ecart != 0))
+  {
+#ifdef HAVE_RINGS_LOC
+    // Leading coef have to be a unit
+    if ( !(nIsUnit(p_GetCoeff((*p).p, r))) ) return;
+#endif
+    k = 0;
+    h1 = r = pCopy((*p).p);
+    h =pNext(r);
+    loop
+    {
+      if (h==NULL)
+      {
+        pDelete(&r);
+        pDelete(&(pNext((*p).p)));
+        (*p).ecart = 0;
+        (*p).length = 1;
+#ifdef HAVE_RINGS_LOC
+        (*p).pLength = 1;  // Why wasn't this set already?
+#endif
+        (*suc)=0;
+        return;
+      }
+      if (!pDivisibleBy(r,h))
+      {
+        q=redBba1(h,index ,strat);
+        if (q != h)
+        {
+          k++;
+          pDelete(&h);
+          pNext(h1) = h = q;
+        }
+        else
+        {
+          pDelete(&r);
+          return;
+        }
+      }
+      else
+      {
+        h1 = h;
+        pIter(h);
+      }
+      if (k > 10)
+      {
+        pDelete(&r);
+        return;
+      }
+    }
+  }
+}
+
+#if 0
+/*2
+* reduces h using the elements from Q in the set S
+* procedure used in updateS
+* must not be used for elements of Q or elements of an ideal !
+*/
+static poly redQ (poly h, int j, kStrategy strat)
+{
+  int start;
+  unsigned long not_sev = ~ pGetShortExpVector(h);
+  while ((j <= strat->sl) && (pGetComp(strat->S[j])!=0)) j++;
+  start=j;
+  while (j<=strat->sl)
+  {
+    if (pLmShortDivisibleBy(strat->S[j],strat->sevS[j], h, not_sev))
+    {
+      h = ksOldSpolyRed(strat->S[j],h,strat->kNoetherTail());
+      if (h==NULL) return NULL;
+      j = start;
+      not_sev = ~ pGetShortExpVector(h);
+    }
+    else j++;
+  }
+  return h;
+}
+#endif
+
+/*2
+* reduces h using the set S
+* procedure used in updateS
+*/
+static poly redBba (poly h,int maxIndex,kStrategy strat)
+{
+  int j = 0;
+  unsigned long not_sev = ~ pGetShortExpVector(h);
+
+  while (j <= maxIndex)
+  {
+    if (pLmShortDivisibleBy(strat->S[j],strat->sevS[j], h, not_sev))
+    {
+      h = ksOldSpolyRed(strat->S[j],h,strat->kNoetherTail());
+      if (h==NULL) return NULL;
+      j = 0;
+      not_sev = ~ pGetShortExpVector(h);    }
+    else j++;
+  }
+  return h;
+}
+
+/*2
+* reduces h using the set S
+*e is the ecart of h
+*procedure used in updateS
+*/
+static poly redMora (poly h,int maxIndex,kStrategy strat)
+{
+  int  j=0;
+  int  e,l;
+  unsigned long not_sev = ~ pGetShortExpVector(h);
+
+  if (maxIndex >= 0)
+  {
+    e = currRing->pLDeg(h,&l,currRing)-p_FDeg(h,currRing);
+    do
+    {
+      if (pLmShortDivisibleBy(strat->S[j],strat->sevS[j], h, not_sev)
+      && ((e >= strat->ecartS[j]) || strat->kHEdgeFound))
+      {
+#ifdef KDEBUG
+        if (TEST_OPT_DEBUG)
+          {PrintS("reduce ");wrp(h);Print(" with S[%d] (",j);wrp(strat->S[j]);}
+#endif
+        h = ksOldSpolyRed(strat->S[j],h,strat->kNoetherTail());
+#ifdef KDEBUG
+        if(TEST_OPT_DEBUG)
+          {PrintS(")\nto "); wrp(h); PrintLn();}
+#endif
+        // pDelete(&h);
+        if (h == NULL) return NULL;
+        e = currRing->pLDeg(h,&l,currRing)-p_FDeg(h,currRing);
+        j = 0;
+        not_sev = ~ pGetShortExpVector(h);
+      }
+      else j++;
+    }
+    while (j <= maxIndex);
+  }
+  return h;
+}
+
+/*2
+*updates S:
+*the result is a set of polynomials which are in
+*normalform with respect to S
+*/
+void updateS(BOOLEAN toT,kStrategy strat)
+{
+  LObject h;
+  int i, suc=0;
+  poly redSi=NULL;
+  BOOLEAN change,any_change;
+//  Print("nach initS: updateS start mit sl=%d\n",(strat->sl));
+//  for (i=0; i<=(strat->sl); i++)
+//  {
+//    Print("s%d:",i);
+//    if (strat->fromQ!=NULL) Print("(Q:%d) ",strat->fromQ[i]);
+//    pWrite(strat->S[i]);
+//  }
+//  Print("currRing->OrdSgn=%d\n", currRing->OrdSgn);
+  any_change=FALSE;
+  if (rHasGlobalOrdering(currRing))
+  {
+    while (suc != -1)
+    {
+      i=suc+1;
+      while (i<=strat->sl)
+      {
+        change=FALSE;
+        #ifdef HAVE_RINGS
+        if(rField_is_Ring(currRing))
+            any_change = FALSE;
+        #endif
+        if (((strat->fromQ==NULL) || (strat->fromQ[i]==0)) && (i>0))
+        {
+          redSi = pHead(strat->S[i]);
+          strat->S[i] = redBba(strat->S[i],i-1,strat);
+          //if ((strat->ak!=0)&&(strat->S[i]!=NULL))
+          //  strat->S[i]=redQ(strat->S[i],i+1,strat); /*reduce S[i] mod Q*/
+          if (pCmp(redSi,strat->S[i])!=0)
+          {
+            change=TRUE;
+            any_change=TRUE;
+            #ifdef KDEBUG
+            if (TEST_OPT_DEBUG)
+            {
+              PrintS("reduce:");
+              wrp(redSi);PrintS(" to ");p_wrp(strat->S[i], currRing, strat->tailRing);PrintLn();
+            }
+            #endif
+            if (TEST_OPT_PROT)
+            {
+              if (strat->S[i]==NULL)
+                PrintS("V");
+              else
+                PrintS("v");
+              mflush();
+            }
+          }
+          pLmDelete(&redSi);
+          if (strat->S[i]==NULL)
+          {
+            deleteInS(i,strat);
+            i--;
+          }
+          else if (change)
+          {
+            if (TEST_OPT_INTSTRATEGY)
+            {
+              if (TEST_OPT_CONTENTSB)
+                {
+                  number n;
+                  p_Cleardenom_n(strat->S[i], currRing, n);// also does a pContent
+                  if (!nIsOne(n))
+                    {
+                      denominator_list denom=(denominator_list)omAlloc(sizeof(denominator_list_s));
+                      denom->n=nInvers(n);
+                      denom->next=DENOMINATOR_LIST;
+                      DENOMINATOR_LIST=denom;
+                    }
+                  nDelete(&n);
+                }
+              else
+                {
+                  //pContent(strat->S[i]);
+                  strat->S[i]=p_Cleardenom(strat->S[i], currRing);// also does a pContent
+                }
+            }
+            else
+            {
+              pNorm(strat->S[i]);
+            }
+            strat->sevS[i] = pGetShortExpVector(strat->S[i]);
+          }
+        }
+        i++;
+      }
+      if (any_change) reorderS(&suc,strat);
+      else break;
+    }
+    if (toT)
+    {
+      for (i=0; i<=strat->sl; i++)
+      {
+        if ((strat->fromQ==NULL) || (strat->fromQ[i]==0))
+        {
+          h.p = redtailBba(strat->S[i],i-1,strat);
+          if (TEST_OPT_INTSTRATEGY)
+          {
+            h.pCleardenom();// also does a pContent
+          }
+        }
+        else
+        {
+          h.p = strat->S[i];
+        }
+        strat->initEcart(&h);
+        if (strat->honey)
+        {
+          strat->ecartS[i] = h.ecart;
+        }
+        if (strat->sevS[i] == 0) {strat->sevS[i] = pGetShortExpVector(h.p);}
+        else assume(strat->sevS[i] == pGetShortExpVector(h.p));
+        h.sev = strat->sevS[i];
+        /*puts the elements of S also to T*/
+        strat->initEcart(&h);
+        enterT(h,strat);
+        strat->S_2_R[i] = strat->tl;
+      }
+    }
+  }
+  else
+  {
+    while (suc != -1)
+    {
+      i=suc;
+      while (i<=strat->sl)
+      {
+        change=FALSE;
+        if (((strat->fromQ==NULL) || (strat->fromQ[i]==0)) && (i>0))
+        {
+          redSi=pHead((strat->S)[i]);
+          (strat->S)[i] = redMora((strat->S)[i],i-1,strat);
+          if ((strat->S)[i]==NULL)
+          {
+            deleteInS(i,strat);
+            i--;
+          }
+          else if (pCmp((strat->S)[i],redSi)!=0)
+          {
+            any_change=TRUE;
+            h.p = strat->S[i];
+            strat->initEcart(&h);
+            strat->ecartS[i] = h.ecart;
+            if (TEST_OPT_INTSTRATEGY)
+            {
+              if (TEST_OPT_CONTENTSB)
+                {
+                  number n;
+                  p_Cleardenom_n(strat->S[i], currRing, n);// also does a pContent
+                  if (!nIsOne(n))
+                    {
+                      denominator_list denom=(denominator_list)omAlloc(sizeof(denominator_list_s));
+                      denom->n=nInvers(n);
+                      denom->next=DENOMINATOR_LIST;
+                      DENOMINATOR_LIST=denom;
+                    }
+                  nDelete(&n);
+                }
+              else
+                {
+                  //pContent(strat->S[i]);
+                  strat->S[i]=p_Cleardenom(strat->S[i], currRing);// also does a pContent
+                }
+            }
+            else
+            {
+              pNorm(strat->S[i]); // == h.p
+            }
+            h.sev =  pGetShortExpVector(h.p);
+            strat->sevS[i] = h.sev;
+          }
+          pLmDelete(&redSi);
+          kTest(strat);
+        }
+        i++;
+      }
+#ifdef KDEBUG
+      kTest(strat);
+#endif
+      if (any_change) reorderS(&suc,strat);
+      else { suc=-1; break; }
+      if (h.p!=NULL)
+      {
+        if (!strat->kHEdgeFound)
+        {
+          /*strat->kHEdgeFound =*/ HEckeTest(h.p,strat);
+        }
+        if (strat->kHEdgeFound)
+          newHEdge(strat);
+      }
+    }
+    for (i=0; i<=strat->sl; i++)
+    {
+      if ((strat->fromQ==NULL) || (strat->fromQ[i]==0))
+      {
+        strat->S[i] = h.p = redtail(strat->S[i],strat->sl,strat);
+        strat->initEcart(&h);
+        strat->ecartS[i] = h.ecart;
+        h.sev = pGetShortExpVector(h.p);
+        strat->sevS[i] = h.sev;
+      }
+      else
+      {
+        h.p = strat->S[i];
+        h.ecart=strat->ecartS[i];
+        h.sev = strat->sevS[i];
+        h.length = h.pLength = pLength(h.p);
+      }
+      if ((strat->fromQ==NULL) || (strat->fromQ[i]==0))
+        cancelunit1(&h,&suc,strat->sl,strat);
+      h.SetpFDeg();
+      /*puts the elements of S also to T*/
+      enterT(h,strat);
+      strat->S_2_R[i] = strat->tl;
+    }
+    if (suc!= -1) updateS(toT,strat);
+  }
+#ifdef KDEBUG
+  kTest(strat);
+#endif
+}
+
+
+/*2
+* -puts p to the standardbasis s at position at
+* -saves the result in S
+*/
+void enterSBba (LObject p,int atS,kStrategy strat, int atR)
+{
+  strat->news = TRUE;
+  /*- puts p to the standardbasis s at position at -*/
+  if (strat->sl == IDELEMS(strat->Shdl)-1)
+  {
+    strat->sevS = (unsigned long*) omRealloc0Size(strat->sevS,
+                                    IDELEMS(strat->Shdl)*sizeof(unsigned long),
+                                    (IDELEMS(strat->Shdl)+setmaxTinc)
+                                                  *sizeof(unsigned long));
+    strat->ecartS = (intset)omReallocSize(strat->ecartS,
+                                          IDELEMS(strat->Shdl)*sizeof(int),
+                                          (IDELEMS(strat->Shdl)+setmaxTinc)
+                                                  *sizeof(int));
+    strat->S_2_R = (int*) omRealloc0Size(strat->S_2_R,
+                                         IDELEMS(strat->Shdl)*sizeof(int),
+                                         (IDELEMS(strat->Shdl)+setmaxTinc)
+                                                  *sizeof(int));
+    if (strat->lenS!=NULL)
+      strat->lenS=(int*)omRealloc0Size(strat->lenS,
+                                       IDELEMS(strat->Shdl)*sizeof(int),
+                                       (IDELEMS(strat->Shdl)+setmaxTinc)
+                                                 *sizeof(int));
+    if (strat->lenSw!=NULL)
+      strat->lenSw=(wlen_type*)omRealloc0Size(strat->lenSw,
+                                       IDELEMS(strat->Shdl)*sizeof(wlen_type),
+                                       (IDELEMS(strat->Shdl)+setmaxTinc)
+                                                 *sizeof(wlen_type));
+    if (strat->fromQ!=NULL)
+    {
+      strat->fromQ = (intset)omReallocSize(strat->fromQ,
+                                    IDELEMS(strat->Shdl)*sizeof(int),
+                                    (IDELEMS(strat->Shdl)+setmaxTinc)*sizeof(int));
+    }
+    pEnlargeSet(&strat->S,IDELEMS(strat->Shdl),setmaxTinc);
+    IDELEMS(strat->Shdl)+=setmaxTinc;
+    strat->Shdl->m=strat->S;
+  }
+  if (atS <= strat->sl)
+  {
+#ifdef ENTER_USE_MEMMOVE
+// #if 0
+    memmove(&(strat->S[atS+1]), &(strat->S[atS]),
+            (strat->sl - atS + 1)*sizeof(poly));
+    memmove(&(strat->ecartS[atS+1]), &(strat->ecartS[atS]),
+            (strat->sl - atS + 1)*sizeof(int));
+    memmove(&(strat->sevS[atS+1]), &(strat->sevS[atS]),
+            (strat->sl - atS + 1)*sizeof(unsigned long));
+    memmove(&(strat->S_2_R[atS+1]), &(strat->S_2_R[atS]),
+            (strat->sl - atS + 1)*sizeof(int));
+    if (strat->lenS!=NULL)
+    memmove(&(strat->lenS[atS+1]), &(strat->lenS[atS]),
+            (strat->sl - atS + 1)*sizeof(int));
+    if (strat->lenSw!=NULL)
+    memmove(&(strat->lenSw[atS+1]), &(strat->lenSw[atS]),
+            (strat->sl - atS + 1)*sizeof(wlen_type));
+#else
+    for (i=strat->sl+1; i>=atS+1; i--)
+    {
+      strat->S[i] = strat->S[i-1];
+      strat->ecartS[i] = strat->ecartS[i-1];
+      strat->sevS[i] = strat->sevS[i-1];
+      strat->S_2_R[i] = strat->S_2_R[i-1];
+    }
+    if (strat->lenS!=NULL)
+    for (i=strat->sl+1; i>=atS+1; i--)
+      strat->lenS[i] = strat->lenS[i-1];
+    if (strat->lenSw!=NULL)
+    for (i=strat->sl+1; i>=atS+1; i--)
+      strat->lenSw[i] = strat->lenSw[i-1];
+#endif
+  }
+  if (strat->fromQ!=NULL)
+  {
+#ifdef ENTER_USE_MEMMOVE
+    memmove(&(strat->fromQ[atS+1]), &(strat->fromQ[atS]),
+                  (strat->sl - atS + 1)*sizeof(int));
+#else
+    for (i=strat->sl+1; i>=atS+1; i--)
+    {
+      strat->fromQ[i] = strat->fromQ[i-1];
+    }
+#endif
+    strat->fromQ[atS]=0;
+  }
+
+  /*- save result -*/
+  strat->S[atS] = p.p;
+  if (strat->honey) strat->ecartS[atS] = p.ecart;
+  if (p.sev == 0)
+    p.sev = pGetShortExpVector(p.p);
+  else
+    assume(p.sev == pGetShortExpVector(p.p));
+  strat->sevS[atS] = p.sev;
+  strat->ecartS[atS] = p.ecart;
+  strat->S_2_R[atS] = atR;
+  strat->sl++;
+}
+
+/*2
+* -puts p to the standardbasis s at position at
+* -saves the result in S
+*/
+void enterSSba (LObject p,int atS,kStrategy strat, int atR)
+{
+  strat->news = TRUE;
+  /*- puts p to the standardbasis s at position at -*/
+  if (strat->sl == IDELEMS(strat->Shdl)-1)
+  {
+    strat->sevS = (unsigned long*) omRealloc0Size(strat->sevS,
+                                    IDELEMS(strat->Shdl)*sizeof(unsigned long),
+                                    (IDELEMS(strat->Shdl)+setmaxTinc)
+                                                  *sizeof(unsigned long));
+    strat->sevSig = (unsigned long*) omRealloc0Size(strat->sevSig,
+                                    IDELEMS(strat->Shdl)*sizeof(unsigned long),
+                                    (IDELEMS(strat->Shdl)+setmaxTinc)
+                                                  *sizeof(unsigned long));
+    strat->ecartS = (intset)omReallocSize(strat->ecartS,
+                                          IDELEMS(strat->Shdl)*sizeof(int),
+                                          (IDELEMS(strat->Shdl)+setmaxTinc)
+                                                  *sizeof(int));
+    strat->S_2_R = (int*) omRealloc0Size(strat->S_2_R,
+                                         IDELEMS(strat->Shdl)*sizeof(int),
+                                         (IDELEMS(strat->Shdl)+setmaxTinc)
+                                                  *sizeof(int));
+    if (strat->lenS!=NULL)
+      strat->lenS=(int*)omRealloc0Size(strat->lenS,
+                                       IDELEMS(strat->Shdl)*sizeof(int),
+                                       (IDELEMS(strat->Shdl)+setmaxTinc)
+                                                 *sizeof(int));
+    if (strat->lenSw!=NULL)
+      strat->lenSw=(wlen_type*)omRealloc0Size(strat->lenSw,
+                                       IDELEMS(strat->Shdl)*sizeof(wlen_type),
+                                       (IDELEMS(strat->Shdl)+setmaxTinc)
+                                                 *sizeof(wlen_type));
+    if (strat->fromQ!=NULL)
+    {
+      strat->fromQ = (intset)omReallocSize(strat->fromQ,
+                                    IDELEMS(strat->Shdl)*sizeof(int),
+                                    (IDELEMS(strat->Shdl)+setmaxTinc)*sizeof(int));
+    }
+    pEnlargeSet(&strat->S,IDELEMS(strat->Shdl),setmaxTinc);
+    pEnlargeSet(&strat->sig,IDELEMS(strat->Shdl),setmaxTinc);
+    IDELEMS(strat->Shdl)+=setmaxTinc;
+    strat->Shdl->m=strat->S;
+  }
+  // in a signature-based algorithm the following situation will never
+  // appear due to the fact that the critical pairs are already sorted
+  // by increasing signature.
+  if (atS <= strat->sl)
+  {
+#ifdef ENTER_USE_MEMMOVE
+// #if 0
+    memmove(&(strat->S[atS+1]), &(strat->S[atS]),
+            (strat->sl - atS + 1)*sizeof(poly));
+    memmove(&(strat->ecartS[atS+1]), &(strat->ecartS[atS]),
+            (strat->sl - atS + 1)*sizeof(int));
+    memmove(&(strat->sevS[atS+1]), &(strat->sevS[atS]),
+            (strat->sl - atS + 1)*sizeof(unsigned long));
+    memmove(&(strat->S_2_R[atS+1]), &(strat->S_2_R[atS]),
+            (strat->sl - atS + 1)*sizeof(int));
+    if (strat->lenS!=NULL)
+    memmove(&(strat->lenS[atS+1]), &(strat->lenS[atS]),
+            (strat->sl - atS + 1)*sizeof(int));
+    if (strat->lenSw!=NULL)
+    memmove(&(strat->lenSw[atS+1]), &(strat->lenSw[atS]),
+            (strat->sl - atS + 1)*sizeof(wlen_type));
+#else
+    for (i=strat->sl+1; i>=atS+1; i--)
+    {
+      strat->S[i] = strat->S[i-1];
+      strat->ecartS[i] = strat->ecartS[i-1];
+      strat->sevS[i] = strat->sevS[i-1];
+      strat->S_2_R[i] = strat->S_2_R[i-1];
+    }
+    if (strat->lenS!=NULL)
+    for (i=strat->sl+1; i>=atS+1; i--)
+      strat->lenS[i] = strat->lenS[i-1];
+    if (strat->lenSw!=NULL)
+    for (i=strat->sl+1; i>=atS+1; i--)
+      strat->lenSw[i] = strat->lenSw[i-1];
+#endif
+  }
+  if (strat->fromQ!=NULL)
+  {
+#ifdef ENTER_USE_MEMMOVE
+    memmove(&(strat->fromQ[atS+1]), &(strat->fromQ[atS]),
+                  (strat->sl - atS + 1)*sizeof(int));
+#else
+    for (i=strat->sl+1; i>=atS+1; i--)
+    {
+      strat->fromQ[i] = strat->fromQ[i-1];
+    }
+#endif
+    strat->fromQ[atS]=0;
+  }
+
+  /*- save result -*/
+  strat->S[atS] = p.p;
+  strat->sig[atS] = p.sig; // TODO: get ths correct signature in here!
+  if (strat->honey) strat->ecartS[atS] = p.ecart;
+  if (p.sev == 0)
+    p.sev = pGetShortExpVector(p.p);
+  else
+    assume(p.sev == pGetShortExpVector(p.p));
+  strat->sevS[atS] = p.sev;
+  // during the interreduction process of a signature-based algorithm we do not
+  // compute the signature at this point, but when the whole interreduction
+  // process finishes, i.e. f5c terminates!
+  if (p.sig != NULL)
+  {
+    if (p.sevSig == 0)
+      p.sevSig = pGetShortExpVector(p.sig);
+    else
+      assume(p.sevSig == pGetShortExpVector(p.sig));
+    strat->sevSig[atS] = p.sevSig; // TODO: get the correct signature in here!
+  }
+  strat->ecartS[atS] = p.ecart;
+  strat->S_2_R[atS] = atR;
+  strat->sl++;
+#ifdef DEBUGF5
+  int k;
+  Print("--- LIST S: %d ---\n",strat->sl);
+  for(k=0;k<=strat->sl;k++)
+  {
+    pWrite(strat->sig[k]);
+  }
+  Print("--- LIST S END ---\n");
+#endif
+}
+
+/*2
+* puts p to the set T at position atT
+*/
+void enterT(LObject p, kStrategy strat, int atT)
+{
+  int i;
+
+  pp_Test(p.p, currRing, p.tailRing);
+  assume(strat->tailRing == p.tailRing);
+  // redMoraNF complains about this -- but, we don't really
+  // neeed this so far
+  assume(p.pLength == 0 || pLength(p.p) == p.pLength || rIsSyzIndexRing(currRing)); // modulo syzring
+  assume(p.FDeg == p.pFDeg());
+  assume(!p.is_normalized || nIsOne(pGetCoeff(p.p)));
+
+#ifdef KDEBUG
+  // do not put an LObject twice into T:
+  for(i=strat->tl;i>=0;i--)
+  {
+    if (p.p==strat->T[i].p)
+    {
+      printf("already in T at pos %d of %d, atT=%d\n",i,strat->tl,atT);
+      return;
+    }
+  }
+#endif
+#ifdef HAVE_TAIL_RING
+  if (currRing!=strat->tailRing)
+  {
+    p.t_p=p.GetLmTailRing();
+  }
+#endif
+  strat->newt = TRUE;
+  if (atT < 0)
+    atT = strat->posInT(strat->T, strat->tl, p);
+  if (strat->tl == strat->tmax-1)
+    enlargeT(strat->T,strat->R,strat->sevT,strat->tmax,setmaxTinc);
+  if (atT <= strat->tl)
+  {
+#ifdef ENTER_USE_MEMMOVE
+    memmove(&(strat->T[atT+1]), &(strat->T[atT]),
+            (strat->tl-atT+1)*sizeof(TObject));
+    memmove(&(strat->sevT[atT+1]), &(strat->sevT[atT]),
+            (strat->tl-atT+1)*sizeof(unsigned long));
+#endif
+    for (i=strat->tl+1; i>=atT+1; i--)
+    {
+#ifndef ENTER_USE_MEMMOVE
+      strat->T[i] = strat->T[i-1];
+      strat->sevT[i] = strat->sevT[i-1];
+#endif
+      strat->R[strat->T[i].i_r] = &(strat->T[i]);
+    }
+  }
+
+  if ((strat->tailBin != NULL) && (pNext(p.p) != NULL))
+  {
+    pNext(p.p)=p_ShallowCopyDelete(pNext(p.p),
+                                   (strat->tailRing != NULL ?
+                                    strat->tailRing : currRing),
+                                   strat->tailBin);
+    if (p.t_p != NULL) pNext(p.t_p) = pNext(p.p);
+  }
+  strat->T[atT] = (TObject) p;
+
+  if (strat->tailRing != currRing && pNext(p.p) != NULL)
+    strat->T[atT].max = p_GetMaxExpP(pNext(p.p), strat->tailRing);
+  else
+    strat->T[atT].max = NULL;
+
+  strat->tl++;
+  strat->R[strat->tl] = &(strat->T[atT]);
+  strat->T[atT].i_r = strat->tl;
+  assume(p.sev == 0 || pGetShortExpVector(p.p) == p.sev);
+  strat->sevT[atT] = (p.sev == 0 ? pGetShortExpVector(p.p) : p.sev);
+  kTest_T(&(strat->T[atT]));
+}
+
+
+/*2
+* puts signature p.sig to the set syz
+*/
+void enterSyz(LObject p, kStrategy strat, int atT)
+{
+  int i;
+  strat->newt = TRUE;
+  if (strat->syzl == strat->syzmax-1)
+  {
+    pEnlargeSet(&strat->syz,strat->syzmax,setmaxTinc);
+    strat->sevSyz = (unsigned long*) omRealloc0Size(strat->sevSyz,
+                                    (strat->syzmax)*sizeof(unsigned long),
+                                    ((strat->syzmax)+setmaxTinc)
+                                                  *sizeof(unsigned long));
+    strat->syzmax += setmaxTinc;
+  }
+  if (atT < strat->syzl)
+  {
+#ifdef ENTER_USE_MEMMOVE
+    memmove(&(strat->syz[atT+1]), &(strat->syz[atT]),
+            (strat->syzl-atT+1)*sizeof(poly));
+    memmove(&(strat->sevSyz[atT+1]), &(strat->sevSyz[atT]),
+            (strat->syzl-atT+1)*sizeof(unsigned long));
+#endif
+    for (i=strat->syzl; i>=atT+1; i--)
+    {
+#ifndef ENTER_USE_MEMMOVE
+      strat->syz[i] = strat->syz[i-1];
+      strat->sevSyz[i] = strat->sevSyz[i-1];
+#endif
+    }
+  }
+  //i = strat->syzl;
+  i = atT;
+  strat->syz[atT] = p.sig;
+  strat->sevSyz[atT] = p.sevSig;
+  strat->syzl++;
+#if F5DEBUG
+  Print("element in strat->syz: %d--%d  ",atT+1,strat->syzmax);
+  pWrite(strat->syz[atT]);
+#endif
+  // recheck pairs in strat->L with new rule and delete correspondingly
+  int cc = strat->Ll;
+  while (cc>-1)
+  {
+    if (p_LmShortDivisibleBy( strat->syz[atT], strat->sevSyz[atT],
+                              strat->L[cc].sig, ~strat->L[cc].sevSig, currRing))
+    {
+      deleteInL(strat->L,&strat->Ll,cc,strat);
+    }
+    cc--;
+  }
+//#if 1
+#ifdef DEBUGF5
+    PrintS("--- Syzygies ---\n");
+    Print("syzl   %d\n",strat->syzl);
+    Print("syzmax %d\n",strat->syzmax);
+    PrintS("--------------------------------\n");
+    for(i=0;i<=strat->syzl-1;i++)
+    {
+      Print("%d - ",i);
+      pWrite(strat->syz[i]);
+    }
+    PrintS("--------------------------------\n");
+#endif
+}
+
+
+void initHilbCrit(ideal/*F*/, ideal /*Q*/, intvec **hilb,kStrategy strat)
+{
+
+  //if the ordering is local, then hilb criterion
+  //can be used also if tzhe ideal is not homogenous
+  if((rHasLocalOrMixedOrdering(currRing)) && (currRing->MixedOrder == 0 ))
+  #ifdef HAVE_RINGS
+  {
+  if(rField_is_Ring(currRing))
+          *hilb=NULL;
+  else
+           return;
+  }
+#endif
+  if (strat->homog!=isHomog)
+  {
+    *hilb=NULL;
+  }
+}
+
+void initBuchMoraCrit(kStrategy strat)
+{
+  strat->enterOnePair=enterOnePairNormal;
+  strat->chainCrit=chainCritNormal;
+#ifdef HAVE_RINGS
+  if (rField_is_Ring(currRing))
+  {
+    strat->enterOnePair=enterOnePairRing;
+    strat->chainCrit=chainCritRing;
+  }
+#endif
+#ifdef HAVE_RATGRING
+  if (rIsRatGRing(currRing))
+  {
+     strat->chainCrit=chainCritPart;
+     /* enterOnePairNormal get rational part in it */
+  }
+#endif
+
+  strat->sugarCrit =        TEST_OPT_SUGARCRIT;
+  strat->Gebauer =          strat->homog || strat->sugarCrit;
+  strat->honey =            !strat->homog || strat->sugarCrit || TEST_OPT_WEIGHTM;
+  if (TEST_OPT_NOT_SUGAR) strat->honey = FALSE;
+  strat->pairtest = NULL;
+  /* alway use tailreduction, except:
+  * - in local rings, - in lex order case, -in ring over extensions */
+  strat->noTailReduction = !TEST_OPT_REDTAIL;
+
+#ifdef HAVE_PLURAL
+  // and r is plural_ring
+  //  hence this holds for r a rational_plural_ring
+  if( rIsPluralRing(currRing) || (rIsSCA(currRing) && !strat->z2homog) )
+  {    //or it has non-quasi-comm type... later
+    strat->sugarCrit = FALSE;
+    strat->Gebauer = FALSE;
+    strat->honey = FALSE;
+  }
+#endif
+
+#ifdef HAVE_RINGS
+  // Coefficient ring?
+  if (rField_is_Ring(currRing))
+  {
+    strat->sugarCrit = FALSE;
+    strat->Gebauer = FALSE ;
+    strat->honey = FALSE;
+  }
+#endif
+  #ifdef KDEBUG
+  if (TEST_OPT_DEBUG)
+  {
+    if (strat->homog) PrintS("ideal/module is homogeneous\n");
+    else              PrintS("ideal/module is not homogeneous\n");
+  }
+  #endif
+}
+
+void initSbaCrit(kStrategy strat)
+{
+  //strat->enterOnePair=enterOnePairNormal;
+  strat->enterOnePair = enterOnePairNormal;
+  //strat->chainCrit=chainCritNormal;
+  strat->chainCrit    = chainCritSig;
+  /******************************************
+   * rewCrit1 and rewCrit2 are already set in
+   * kSba() in kstd1.cc
+   *****************************************/
+  //strat->rewCrit1     = faugereRewCriterion;
+  if (strat->sbaOrder == 1)
+  {
+    strat->syzCrit  = syzCriterionInc;
+  }
+  else
+  {
+    strat->syzCrit  = syzCriterion;
+  }
+#ifdef HAVE_RINGS
+  if (rField_is_Ring(currRing))
+  {
+    strat->enterOnePair=enterOnePairRing;
+    strat->chainCrit=chainCritRing;
+  }
+#endif
+#ifdef HAVE_RATGRING
+  if (rIsRatGRing(currRing))
+  {
+     strat->chainCrit=chainCritPart;
+     /* enterOnePairNormal get rational part in it */
+  }
+#endif
+
+  strat->sugarCrit =        TEST_OPT_SUGARCRIT;
+  strat->Gebauer =          strat->homog || strat->sugarCrit;
+  strat->honey =            !strat->homog || strat->sugarCrit || TEST_OPT_WEIGHTM;
+  if (TEST_OPT_NOT_SUGAR) strat->honey = FALSE;
+  strat->pairtest = NULL;
+  /* alway use tailreduction, except:
+  * - in local rings, - in lex order case, -in ring over extensions */
+  strat->noTailReduction = !TEST_OPT_REDTAIL;
+  //strat->noTailReduction = NULL;
+
+#ifdef HAVE_PLURAL
+  // and r is plural_ring
+  //  hence this holds for r a rational_plural_ring
+  if( rIsPluralRing(currRing) || (rIsSCA(currRing) && !strat->z2homog) )
+  {    //or it has non-quasi-comm type... later
+    strat->sugarCrit = FALSE;
+    strat->Gebauer = FALSE;
+    strat->honey = FALSE;
+  }
+#endif
+
+#ifdef HAVE_RINGS
+  // Coefficient ring?
+  if (rField_is_Ring(currRing))
+  {
+    strat->sugarCrit = FALSE;
+    strat->Gebauer = FALSE ;
+    strat->honey = FALSE;
+  }
+#endif
+  #ifdef KDEBUG
+  if (TEST_OPT_DEBUG)
+  {
+    if (strat->homog) PrintS("ideal/module is homogeneous\n");
+    else              PrintS("ideal/module is not homogeneous\n");
+  }
+  #endif
+}
+
+BOOLEAN kPosInLDependsOnLength(int (*pos_in_l)
+                               (const LSet set, const int length,
+                                LObject* L,const kStrategy strat))
+{
+  if (pos_in_l == posInL110 ||
+      pos_in_l == posInL10)
+    return TRUE;
+
+  return FALSE;
+}
+
+void initBuchMoraPos (kStrategy strat)
+{
+  if (rHasGlobalOrdering(currRing))
+  {
+    if (strat->honey)
+    {
+      strat->posInL = posInL15;
+      // ok -- here is the deal: from my experiments for Singular-2-0
+      // I conclude that that posInT_EcartpLength is the best of
+      // posInT15, posInT_EcartFDegpLength, posInT_FDegLength, posInT_pLength
+      // see the table at the end of this file
+      if (TEST_OPT_OLDSTD)
+        strat->posInT = posInT15;
+      else
+        strat->posInT = posInT_EcartpLength;
+    }
+    else if (currRing->pLexOrder && !TEST_OPT_INTSTRATEGY)
+    {
+      strat->posInL = posInL11;
+      strat->posInT = posInT11;
+    }
+    else if (TEST_OPT_INTSTRATEGY)
+    {
+      strat->posInL = posInL11;
+      strat->posInT = posInT11;
+    }
+    else
+    {
+      strat->posInL = posInL0;
+      strat->posInT = posInT0;
+    }
+    //if (strat->minim>0) strat->posInL =posInLSpecial;
+    if (strat->homog)
+    {
+       strat->posInL = posInL110;
+       strat->posInT = posInT110;
+    }
+  }
+  else
+  {
+    if (strat->homog)
+    {
+      strat->posInL = posInL11;
+      strat->posInT = posInT11;
+    }
+    else
+    {
+      if ((currRing->order[0]==ringorder_c)
+      ||(currRing->order[0]==ringorder_C))
+      {
+        strat->posInL = posInL17_c;
+        strat->posInT = posInT17_c;
+      }
+      else
+      {
+        strat->posInL = posInL17;
+        strat->posInT = posInT17;
+      }
+    }
+  }
+  if (strat->minim>0) strat->posInL =posInLSpecial;
+  // for further tests only
+  if ((BTEST1(11)) || (BTEST1(12)))
+    strat->posInL = posInL11;
+  else if ((BTEST1(13)) || (BTEST1(14)))
+    strat->posInL = posInL13;
+  else if ((BTEST1(15)) || (BTEST1(16)))
+    strat->posInL = posInL15;
+  else if ((BTEST1(17)) || (BTEST1(18)))
+    strat->posInL = posInL17;
+  if (BTEST1(11))
+    strat->posInT = posInT11;
+  else if (BTEST1(13))
+    strat->posInT = posInT13;
+  else if (BTEST1(15))
+    strat->posInT = posInT15;
+  else if ((BTEST1(17)))
+    strat->posInT = posInT17;
+  else if ((BTEST1(19)))
+    strat->posInT = posInT19;
+  else if (BTEST1(12) || BTEST1(14) || BTEST1(16) || BTEST1(18))
+    strat->posInT = posInT1;
+#ifdef HAVE_RINGS
+  if (rField_is_Ring(currRing))
+  {
+    strat->posInL = posInL11;
+    strat->posInT = posInT11;
+  }
+#endif
+  strat->posInLDependsOnLength = kPosInLDependsOnLength(strat->posInL);
+}
+
+void initBuchMora (ideal F,ideal Q,kStrategy strat)
+{
+  strat->interpt = BTEST1(OPT_INTERRUPT);
+  strat->kHEdge=NULL;
+  if (rHasGlobalOrdering(currRing)) strat->kHEdgeFound=FALSE;
+  /*- creating temp data structures------------------- -*/
+  strat->cp = 0;
+  strat->c3 = 0;
+  strat->tail = pInit();
+  /*- set s -*/
+  strat->sl = -1;
+  /*- set L -*/
+  strat->Lmax = ((IDELEMS(F)+setmaxLinc-1)/setmaxLinc)*setmaxLinc;
+  strat->Ll = -1;
+  strat->L = initL(((IDELEMS(F)+setmaxLinc-1)/setmaxLinc)*setmaxLinc);
+  /*- set B -*/
+  strat->Bmax = setmaxL;
+  strat->Bl = -1;
+  strat->B = initL();
+  /*- set T -*/
+  strat->tl = -1;
+  strat->tmax = setmaxT;
+  strat->T = initT();
+  strat->R = initR();
+  strat->sevT = initsevT();
+  /*- init local data struct.---------------------------------------- -*/
+  strat->P.ecart=0;
+  strat->P.length=0;
+  if (rHasLocalOrMixedOrdering(currRing))
+  {
+    if (strat->kHEdge!=NULL) pSetComp(strat->kHEdge, strat->ak);
+    if (strat->kNoether!=NULL) pSetComp(strat->kNoetherTail(), strat->ak);
+  }
+  #ifdef HAVE_RINGS
+  if(rField_is_Ring(currRing))
+  {
+    /*Shdl=*/initSL(F, Q,strat); /*sets also S, ecartS, fromQ */
+  }
+  else
+  #endif
+  {
+    if(TEST_OPT_SB_1)
+    {
+        int i;
+        ideal P=idInit(IDELEMS(F)-strat->newIdeal,F->rank);
+        for (i=strat->newIdeal;i<IDELEMS(F);i++)
+        {
+          P->m[i-strat->newIdeal] = F->m[i];
+          F->m[i] = NULL;
+        }
+        initSSpecial(F,Q,P,strat);
+        for (i=strat->newIdeal;i<IDELEMS(F);i++)
+        {
+          F->m[i] = P->m[i-strat->newIdeal];
+          P->m[i-strat->newIdeal] = NULL;
+        }
+        idDelete(&P);
+    }
+
+    else
+    {
+      /*Shdl=*/initSL(F, Q,strat); /*sets also S, ecartS, fromQ */
+      // /*Shdl=*/initS(F, Q,strat); /*sets also S, ecartS, fromQ */
+    }
+  }
+  strat->fromT = FALSE;
+  strat->noTailReduction = !TEST_OPT_REDTAIL;
+  if ((!TEST_OPT_SB_1)
+  #ifdef HAVE_RINGS
+  || (rField_is_Ring(currRing))
+  #endif
+  )
+  {
+    updateS(TRUE,strat);
+  }
+  if (strat->fromQ!=NULL) omFreeSize(strat->fromQ,IDELEMS(strat->Shdl)*sizeof(int));
+  strat->fromQ=NULL;
+}
+
+void exitBuchMora (kStrategy strat)
+{
+  /*- release temp data -*/
+  cleanT(strat);
+  omFreeSize(strat->T,(strat->tmax)*sizeof(TObject));
+  omFreeSize(strat->R,(strat->tmax)*sizeof(TObject*));
+  omFreeSize(strat->sevT, (strat->tmax)*sizeof(unsigned long));
+  omFreeSize(strat->ecartS,IDELEMS(strat->Shdl)*sizeof(int));
+  omFreeSize((ADDRESS)strat->sevS,IDELEMS(strat->Shdl)*sizeof(unsigned long));
+  omFreeSize(strat->S_2_R,IDELEMS(strat->Shdl)*sizeof(int));
+  /*- set L: should be empty -*/
+  omFreeSize(strat->L,(strat->Lmax)*sizeof(LObject));
+  /*- set B: should be empty -*/
+  omFreeSize(strat->B,(strat->Bmax)*sizeof(LObject));
+  pLmDelete(&strat->tail);
+  strat->syzComp=0;
+}
+
+void initSbaPos (kStrategy strat)
+{
+  if (rHasGlobalOrdering(currRing))
+  {
+    if (strat->honey)
+    {
+      strat->posInL = posInL15;
+      // ok -- here is the deal: from my experiments for Singular-2-0
+      // I conclude that that posInT_EcartpLength is the best of
+      // posInT15, posInT_EcartFDegpLength, posInT_FDegLength, posInT_pLength
+      // see the table at the end of this file
+      if (TEST_OPT_OLDSTD)
+        strat->posInT = posInT15;
+      else
+        strat->posInT = posInT_EcartpLength;
+    }
+    else if (currRing->pLexOrder && !TEST_OPT_INTSTRATEGY)
+    {
+      strat->posInL = posInL11;
+      strat->posInT = posInT11;
+    }
+    else if (TEST_OPT_INTSTRATEGY)
+    {
+      strat->posInL = posInL11;
+      strat->posInT = posInT11;
+    }
+    else
+    {
+      strat->posInL = posInL0;
+      strat->posInT = posInT0;
+    }
+    //if (strat->minim>0) strat->posInL =posInLSpecial;
+    if (strat->homog)
+    {
+       strat->posInL = posInL110;
+       strat->posInT = posInT110;
+    }
+  }
+  else
+  {
+    if (strat->homog)
+    {
+      strat->posInL = posInL11;
+      strat->posInT = posInT11;
+    }
+    else
+    {
+      if ((currRing->order[0]==ringorder_c)
+      ||(currRing->order[0]==ringorder_C))
+      {
+        strat->posInL = posInL17_c;
+        strat->posInT = posInT17_c;
+      }
+      else
+      {
+        strat->posInL = posInL17;
+        strat->posInT = posInT17;
+      }
+    }
+  }
+  if (strat->minim>0) strat->posInL =posInLSpecial;
+  // for further tests only
+  if ((BTEST1(11)) || (BTEST1(12)))
+    strat->posInL = posInL11;
+  else if ((BTEST1(13)) || (BTEST1(14)))
+    strat->posInL = posInL13;
+  else if ((BTEST1(15)) || (BTEST1(16)))
+    strat->posInL = posInL15;
+  else if ((BTEST1(17)) || (BTEST1(18)))
+    strat->posInL = posInL17;
+  if (BTEST1(11))
+    strat->posInT = posInT11;
+  else if (BTEST1(13))
+    strat->posInT = posInT13;
+  else if (BTEST1(15))
+    strat->posInT = posInT15;
+  else if ((BTEST1(17)))
+    strat->posInT = posInT17;
+  else if ((BTEST1(19)))
+    strat->posInT = posInT19;
+  else if (BTEST1(12) || BTEST1(14) || BTEST1(16) || BTEST1(18))
+    strat->posInT = posInT1;
+#ifdef HAVE_RINGS
+  if (rField_is_Ring(currRing))
+  {
+    strat->posInL = posInL11;
+    strat->posInT = posInT11;
+  }
+#endif
+  strat->posInLDependsOnLength = FALSE;
+  strat->posInLSba  = posInLSig;
+  //strat->posInL     = posInLSig;
+  strat->posInL     = posInLF5C;
+  //strat->posInT     = posInTSig;
+}
+
+void initSbaBuchMora (ideal F,ideal Q,kStrategy strat)
+{
+  strat->interpt = BTEST1(OPT_INTERRUPT);
+  strat->kHEdge=NULL;
+  if (rHasGlobalOrdering(currRing)) strat->kHEdgeFound=FALSE;
+  /*- creating temp data structures------------------- -*/
+  strat->cp = 0;
+  strat->c3 = 0;
+  strat->tail = pInit();
+  /*- set s -*/
+  strat->sl = -1;
+  /*- set ps -*/
+  strat->syzl = -1;
+  /*- set L -*/
+  strat->Lmax = ((IDELEMS(F)+setmaxLinc-1)/setmaxLinc)*setmaxLinc;
+  strat->Ll = -1;
+  strat->L = initL(((IDELEMS(F)+setmaxLinc-1)/setmaxLinc)*setmaxLinc);
+  /*- set B -*/
+  strat->Bmax = setmaxL;
+  strat->Bl = -1;
+  strat->B = initL();
+  /*- set T -*/
+  strat->tl = -1;
+  strat->tmax = setmaxT;
+  strat->T = initT();
+  strat->R = initR();
+  strat->sevT = initsevT();
+  /*- init local data struct.---------------------------------------- -*/
+  strat->P.ecart=0;
+  strat->P.length=0;
+  if (rHasLocalOrMixedOrdering(currRing))
+  {
+    if (strat->kHEdge!=NULL) pSetComp(strat->kHEdge, strat->ak);
+    if (strat->kNoether!=NULL) pSetComp(strat->kNoetherTail(), strat->ak);
+  }
+  #ifdef HAVE_RINGS
+  if(rField_is_Ring(currRing))
+  {
+    /*Shdl=*/initSLSba(F, Q,strat); /*sets also S, ecartS, fromQ */
+  }
+  else
+  #endif
+  {
+    if(TEST_OPT_SB_1)
+    {
+        int i;
+        ideal P=idInit(IDELEMS(F)-strat->newIdeal,F->rank);
+        for (i=strat->newIdeal;i<IDELEMS(F);i++)
+        {
+          P->m[i-strat->newIdeal] = F->m[i];
+          F->m[i] = NULL;
+        }
+        initSSpecialSba(F,Q,P,strat);
+        for (i=strat->newIdeal;i<IDELEMS(F);i++)
+        {
+          F->m[i] = P->m[i-strat->newIdeal];
+          P->m[i-strat->newIdeal] = NULL;
+        }
+        idDelete(&P);
+    }
+    else
+    {
+      /*Shdl=*/initSLSba(F, Q,strat); /*sets also S, ecartS, fromQ */
+      // /*Shdl=*/initS(F, Q,strat); /*sets also S, ecartS, fromQ */
+    }
+  }
+  strat->fromT = FALSE;
+  strat->noTailReduction = !TEST_OPT_REDTAIL;
+  if (!TEST_OPT_SB_1)
+  {
+    #ifdef HAVE_RINGS
+    if(!rField_is_Ring(currRing))
+    #endif
+    updateS(TRUE,strat);
+  }
+  if (strat->fromQ!=NULL) omFreeSize(strat->fromQ,IDELEMS(strat->Shdl)*sizeof(int));
+  strat->fromQ=NULL;
+}
+
+void exitSba (kStrategy strat)
+{
+  /*- release temp data -*/
+  cleanT(strat);
+  omFreeSize(strat->T,(strat->tmax)*sizeof(TObject));
+  omFreeSize(strat->R,(strat->tmax)*sizeof(TObject*));
+  omFreeSize(strat->sevT, (strat->tmax)*sizeof(unsigned long));
+  omFreeSize(strat->ecartS,IDELEMS(strat->Shdl)*sizeof(int));
+  omFreeSize((ADDRESS)strat->sevS,IDELEMS(strat->Shdl)*sizeof(unsigned long));
+  omFreeSize((ADDRESS)strat->sevSig,IDELEMS(strat->Shdl)*sizeof(unsigned long));
+  omFreeSize((ADDRESS)strat->syz,(strat->syzmax)*sizeof(poly));
+  omFreeSize((ADDRESS)strat->sevSyz,(strat->syzmax)*sizeof(unsigned long));
+  if (strat->sbaOrder == 1)
+  {
+    omFreeSize(strat->syzIdx,(strat->syzidxmax)*sizeof(int));
+  }
+  omFreeSize(strat->S_2_R,IDELEMS(strat->Shdl)*sizeof(int));
+  /*- set L: should be empty -*/
+  omFreeSize(strat->L,(strat->Lmax)*sizeof(LObject));
+  /*- set B: should be empty -*/
+  omFreeSize(strat->B,(strat->Bmax)*sizeof(LObject));
+  /*- set sig: no need for the signatures anymore -*/
+  omFreeSize(strat->sig,IDELEMS(strat->Shdl)*sizeof(poly));
+  pLmDelete(&strat->tail);
+  strat->syzComp=0;
+}
+
+/*2
+* in the case of a standardbase of a module over a qring:
+* replace polynomials in i by ak vectors,
+* (the polynomial * unit vectors gen(1)..gen(ak)
+* in every case (also for ideals:)
+* deletes divisible vectors/polynomials
+*/
+void updateResult(ideal r,ideal Q, kStrategy strat)
+{
+  int l;
+  if (strat->ak>0)
+  {
+    for (l=IDELEMS(r)-1;l>=0;l--)
+    {
+      if ((r->m[l]!=NULL) && (pGetComp(r->m[l])==0))
+      {
+        pDelete(&r->m[l]); // and set it to NULL
+      }
+    }
+    int q;
+    poly p;
+    for (l=IDELEMS(r)-1;l>=0;l--)
+    {
+      if ((r->m[l]!=NULL)
+      //&& (strat->syzComp>0)
+      //&& (pGetComp(r->m[l])<=strat->syzComp)
+      )
+      {
+        for(q=IDELEMS(Q)-1; q>=0;q--)
+        {
+          if ((Q->m[q]!=NULL)
+          &&(pLmDivisibleBy(Q->m[q],r->m[l])))
+          {
+            if (TEST_OPT_REDSB)
+            {
+              p=r->m[l];
+              r->m[l]=kNF(Q,NULL,p);
+              pDelete(&p);
+            }
+            else
+            {
+              pDelete(&r->m[l]); // and set it to NULL
+            }
+            break;
+          }
+        }
+      }
+    }
+  }
+  else
+  {
+    int q;
+    poly p;
+    BOOLEAN reduction_found=FALSE;
+    if (!rField_is_Ring(currRing))
+    {
+      for (l=IDELEMS(r)-1;l>=0;l--)
+      {
+        if (r->m[l]!=NULL)
+        {
+          for(q=IDELEMS(Q)-1; q>=0;q--)
+          {
+            if ((Q->m[q]!=NULL)&&(pLmEqual(Q->m[q],r->m[l])))
+            {
+              if (TEST_OPT_REDSB)
+              {
+                p=r->m[l];
+                r->m[l]=kNF(Q,NULL,p);
+                pDelete(&p);
+                reduction_found=TRUE;
+              }
+              else
+              {
+                pDelete(&r->m[l]); // and set it to NULL
+              }
+              break;
+            }
+          }
+        }
+      }
+    }
+    #ifdef HAVE_RINGS
+    //Also need divisibility of the leading coefficients
+    else
+    {
+      for (l=IDELEMS(r)-1;l>=0;l--)
+      {
+        if (r->m[l]!=NULL)
+        {
+          for(q=IDELEMS(Q)-1; q>=0;q--)
+          {
+            if ((Q->m[q]!=NULL)&&(pLmEqual(Q->m[q],r->m[l]))
+            && pDivisibleBy(Q->m[q],r->m[l]))
+            {
+              if (TEST_OPT_REDSB)
+              {
+                p=r->m[l];
+                r->m[l]=kNF(Q,NULL,p);
+                pDelete(&p);
+                reduction_found=TRUE;
+              }
+              else
+              {
+                pDelete(&r->m[l]); // and set it to NULL
+              }
+              break;
+            }
+          }
+        }
+      }
+    }
+    #endif
+    if (/*TEST_OPT_REDSB &&*/ reduction_found)
+    {
+      for (l=IDELEMS(r)-1;l>=0;l--)
+      {
+        if (r->m[l]!=NULL)
+        {
+          for(q=IDELEMS(r)-1;q>=0;q--)
+          {
+            if ((l!=q)
+            && (r->m[q]!=NULL)
+            &&(pLmDivisibleBy(r->m[l],r->m[q])))
+            {
+              pDelete(&r->m[q]);
+            }
+          }
+        }
+      }
+    }
+  }
+  idSkipZeroes(r);
+}
+
+void completeReduce (kStrategy strat, BOOLEAN withT)
+{
+  int i;
+  int low = (((rHasGlobalOrdering(currRing)) && (strat->ak==0)) ? 1 : 0);
+  LObject L;
+
+#ifdef KDEBUG
+  // need to set this: during tailreductions of T[i], T[i].max is out of
+  // sync
+  sloppy_max = TRUE;
+#endif
+
+  strat->noTailReduction = FALSE;
+  if (TEST_OPT_PROT)
+  {
+    PrintLn();
+//    if (timerv) writeTime("standard base computed:");
+  }
+  if (TEST_OPT_PROT)
+  {
+    Print("(S:%d)",strat->sl);mflush();
+  }
+  for (i=strat->sl; i>=low; i--)
+  {
+    int end_pos=strat->sl;
+    if ((strat->fromQ!=NULL) && (strat->fromQ[i])) continue; // do not reduce Q_i
+    if (strat->ak==0) end_pos=i-1;
+    TObject* T_j = strat->s_2_t(i);
+    if ((T_j != NULL)&&(T_j->p==strat->S[i]))
+    {
+      L = *T_j;
+      #ifdef KDEBUG
+      if (TEST_OPT_DEBUG)
+      {
+        Print("test S[%d]:",i);
+        p_wrp(L.p,currRing,strat->tailRing);
+        PrintLn();
+      }
+      #endif
+      if (rHasGlobalOrdering(currRing))
+        strat->S[i] = redtailBba(&L, end_pos, strat, withT);
+      else
+        strat->S[i] = redtail(&L, strat->sl, strat);
+      #ifdef KDEBUG
+      if (TEST_OPT_DEBUG)
+      {
+        Print("to (tailR) S[%d]:",i);
+        p_wrp(strat->S[i],currRing,strat->tailRing);
+        PrintLn();
+      }
+      #endif
+
+      if (strat->redTailChange && strat->tailRing != currRing)
+      {
+        if (T_j->max != NULL) p_LmFree(T_j->max, strat->tailRing);
+        if (pNext(T_j->p) != NULL)
+          T_j->max = p_GetMaxExpP(pNext(T_j->p), strat->tailRing);
+        else
+          T_j->max = NULL;
+      }
+      if (TEST_OPT_INTSTRATEGY)
+        T_j->pCleardenom();
+    }
+    else
+    {
+      assume(currRing == strat->tailRing);
+      #ifdef KDEBUG
+      if (TEST_OPT_DEBUG)
+      {
+        Print("test S[%d]:",i);
+        p_wrp(strat->S[i],currRing,strat->tailRing);
+        PrintLn();
+      }
+      #endif
+      if (rHasGlobalOrdering(currRing))
+        strat->S[i] = redtailBba(strat->S[i], end_pos, strat, withT);
+      else
+        strat->S[i] = redtail(strat->S[i], strat->sl, strat);
+      if (TEST_OPT_INTSTRATEGY)
+      {
+        if (TEST_OPT_CONTENTSB)
+        {
+          number n;
+          p_Cleardenom_n(strat->S[i], currRing, n);// also does a pContent
+          if (!nIsOne(n))
+          {
+            denominator_list denom=(denominator_list)omAlloc(sizeof(denominator_list_s));
+            denom->n=nInvers(n);
+            denom->next=DENOMINATOR_LIST;
+            DENOMINATOR_LIST=denom;
+          }
+          nDelete(&n);
+        }
+        else
+        {
+          //pContent(strat->S[i]);
+          strat->S[i]=p_Cleardenom(strat->S[i], currRing);// also does a pContent
+        }
+      }
+      #ifdef KDEBUG
+      if (TEST_OPT_DEBUG)
+      {
+        Print("to (-tailR) S[%d]:",i);
+        p_wrp(strat->S[i],currRing,strat->tailRing);
+        PrintLn();
+      }
+      #endif
+    }
+    if (TEST_OPT_PROT)
+      PrintS("-");
+  }
+  if (TEST_OPT_PROT) PrintLn();
+#ifdef KDEBUG
+  sloppy_max = FALSE;
+#endif
+}
+
+
+/*2
+* computes the new strat->kHEdge and the new pNoether,
+* returns TRUE, if pNoether has changed
+*/
+BOOLEAN newHEdge(kStrategy strat)
+{
+  int i,j;
+  poly newNoether;
+
+#if 0
+  if (currRing->weight_all_1)
+    scComputeHC(strat->Shdl,NULL,strat->ak,strat->kHEdge, strat->tailRing);
+  else
+    scComputeHCw(strat->Shdl,NULL,strat->ak,strat->kHEdge, strat->tailRing);
+#else
+  scComputeHC(strat->Shdl,NULL,strat->ak,strat->kHEdge, strat->tailRing);
+#endif
+  if (strat->t_kHEdge != NULL) p_LmFree(strat->t_kHEdge, strat->tailRing);
+  if (strat->tailRing != currRing)
+    strat->t_kHEdge = k_LmInit_currRing_2_tailRing(strat->kHEdge, strat->tailRing);
+  /* compare old and new noether*/
+  newNoether = pLmInit(strat->kHEdge);
+  j = p_FDeg(newNoether,currRing);
+/*  #ifdef HAVE_RINGS
+  if (!rField_is_Ring(currRing))
+  #endif */
+  for (i=1; i<=(currRing->N); i++)
+  {
+    if (pGetExp(newNoether, i) > 0) pDecrExp(newNoether,i);
+  }
+  pSetm(newNoether);
+  if (j < strat->HCord) /*- statistics -*/
+  {
+    if (TEST_OPT_PROT)
+    {
+      Print("H(%d)",j);
+      mflush();
+    }
+    strat->HCord=j;
+    #ifdef KDEBUG
+    if (TEST_OPT_DEBUG)
+    {
+      Print("H(%d):",j);
+      wrp(strat->kHEdge);
+      PrintLn();
+    }
+    #endif
+  }
+  if (pCmp(strat->kNoether,newNoether)!=1)
+  {
+    pDelete(&strat->kNoether);
+    strat->kNoether=newNoether;
+    if (strat->t_kNoether != NULL) p_LmFree(strat->t_kNoether, strat->tailRing);
+    if (strat->tailRing != currRing)
+      strat->t_kNoether = k_LmInit_currRing_2_tailRing(strat->kNoether, strat->tailRing);
+
+    return TRUE;
+  }
+  pLmFree(newNoether);
+  return FALSE;
+}
+
+/***************************************************************
+ *
+ * Routines related for ring changes during std computations
+ *
+ ***************************************************************/
+BOOLEAN kCheckSpolyCreation(LObject *L, kStrategy strat, poly &m1, poly &m2)
+{
+  if (strat->overflow) return FALSE;
+  assume(L->p1 != NULL && L->p2 != NULL);
+  // shift changes: from 0 to -1
+  assume(L->i_r1 >= -1 && L->i_r1 <= strat->tl);
+  assume(L->i_r2 >= -1 && L->i_r2 <= strat->tl);
+  assume(strat->tailRing != currRing);
+
+  if (! k_GetLeadTerms(L->p1, L->p2, currRing, m1, m2, strat->tailRing))
+    return FALSE;
+  // shift changes: extra case inserted
+  if ((L->i_r1 == -1) || (L->i_r2 == -1) )
+  {
+    return TRUE;
+  }
+  poly p1_max = (strat->R[L->i_r1])->max;
+  poly p2_max = (strat->R[L->i_r2])->max;
+
+  if (((p1_max != NULL) && !p_LmExpVectorAddIsOk(m1, p1_max, strat->tailRing)) ||
+      ((p2_max != NULL) && !p_LmExpVectorAddIsOk(m2, p2_max, strat->tailRing)))
+  {
+    p_LmFree(m1, strat->tailRing);
+    p_LmFree(m2, strat->tailRing);
+    m1 = NULL;
+    m2 = NULL;
+    return FALSE;
+  }
+  return TRUE;
+}
+
+#ifdef HAVE_RINGS
+/***************************************************************
+ *
+ * Checks, if we can compute the gcd poly / strong pair
+ * gcd-poly = m1 * R[atR] + m2 * S[atS]
+ *
+ ***************************************************************/
+BOOLEAN kCheckStrongCreation(int atR, poly m1, int atS, poly m2, kStrategy strat)
+{
+  assume(strat->S_2_R[atS] >= -1 && strat->S_2_R[atS] <= strat->tl);
+  //assume(strat->tailRing != currRing);
+
+  poly p1_max = (strat->R[atR])->max;
+  poly p2_max = (strat->R[strat->S_2_R[atS]])->max;
+
+  if (((p1_max != NULL) && !p_LmExpVectorAddIsOk(m1, p1_max, strat->tailRing)) ||
+      ((p2_max != NULL) && !p_LmExpVectorAddIsOk(m2, p2_max, strat->tailRing)))
+  {
+    return FALSE;
+  }
+  return TRUE;
+}
+#endif
+
+BOOLEAN kStratChangeTailRing(kStrategy strat, LObject *L, TObject* T, unsigned long expbound)
+{
+  assume((strat->tailRing == currRing) || (strat->tailRing->bitmask < currRing->bitmask));
+  /* initial setup or extending */
+
+  if (expbound == 0) expbound = strat->tailRing->bitmask << 1;
+  if (expbound >= currRing->bitmask) return FALSE;
+  strat->overflow=FALSE;
+  ring new_tailRing = rModifyRing(currRing,
+  // Hmmm .. the condition pFDeg == p_Deg
+  // might be too strong
+#ifdef HAVE_RINGS
+  (strat->homog && currRing->pFDeg == p_Deg && !(rField_is_Ring(currRing))), // TODO Oliver
+#else
+  (strat->homog && currRing->pFDeg == p_Deg), // omit_degree
+#endif
+  (strat->ak==0), // omit_comp if the input is an ideal
+  expbound); // exp_limit
+
+  if (new_tailRing == currRing) return TRUE;
+
+  strat->pOrigFDeg_TailRing = new_tailRing->pFDeg;
+  strat->pOrigLDeg_TailRing = new_tailRing->pLDeg;
+
+  if (currRing->pFDeg != currRing->pFDegOrig)
+  {
+    new_tailRing->pFDeg = currRing->pFDeg;
+    new_tailRing->pLDeg = currRing->pLDeg;
+  }
+
+  if (TEST_OPT_PROT)
+    Print("[%lu:%d", (unsigned long) new_tailRing->bitmask, new_tailRing->ExpL_Size);
+  kTest_TS(strat);
+  assume(new_tailRing != strat->tailRing);
+  pShallowCopyDeleteProc p_shallow_copy_delete
+    = pGetShallowCopyDeleteProc(strat->tailRing, new_tailRing);
+
+  omBin new_tailBin = omGetStickyBinOfBin(new_tailRing->PolyBin);
+
+  int i;
+  for (i=0; i<=strat->tl; i++)
+  {
+    strat->T[i].ShallowCopyDelete(new_tailRing, new_tailBin,
+                                  p_shallow_copy_delete);
+  }
+  for (i=0; i<=strat->Ll; i++)
+  {
+    assume(strat->L[i].p != NULL);
+    if (pNext(strat->L[i].p) != strat->tail)
+      strat->L[i].ShallowCopyDelete(new_tailRing, p_shallow_copy_delete);
+  }
+  if ((strat->P.t_p != NULL) ||
+      ((strat->P.p != NULL) && pNext(strat->P.p) != strat->tail))
+    strat->P.ShallowCopyDelete(new_tailRing, p_shallow_copy_delete);
+
+  if ((L != NULL) && (L->tailRing != new_tailRing))
+  {
+    if (L->i_r < 0)
+      L->ShallowCopyDelete(new_tailRing, p_shallow_copy_delete);
+    else
+    {
+      assume(L->i_r <= strat->tl);
+      TObject* t_l = strat->R[L->i_r];
+      assume(t_l != NULL);
+      L->tailRing = new_tailRing;
+      L->p = t_l->p;
+      L->t_p = t_l->t_p;
+      L->max = t_l->max;
+    }
+  }
+
+  if ((T != NULL) && (T->tailRing != new_tailRing && T->i_r < 0))
+    T->ShallowCopyDelete(new_tailRing, new_tailBin, p_shallow_copy_delete);
+
+  omMergeStickyBinIntoBin(strat->tailBin, strat->tailRing->PolyBin);
+  if (strat->tailRing != currRing)
+    rKillModifiedRing(strat->tailRing);
+
+  strat->tailRing = new_tailRing;
+  strat->tailBin = new_tailBin;
+  strat->p_shallow_copy_delete
+    = pGetShallowCopyDeleteProc(currRing, new_tailRing);
+
+  if (strat->kHEdge != NULL)
+  {
+    if (strat->t_kHEdge != NULL)
+      p_LmFree(strat->t_kHEdge, strat->tailRing);
+    strat->t_kHEdge=k_LmInit_currRing_2_tailRing(strat->kHEdge, new_tailRing);
+  }
+
+  if (strat->kNoether != NULL)
+  {
+    if (strat->t_kNoether != NULL)
+      p_LmFree(strat->t_kNoether, strat->tailRing);
+    strat->t_kNoether=k_LmInit_currRing_2_tailRing(strat->kNoether,
+                                                   new_tailRing);
+  }
+  kTest_TS(strat);
+  if (TEST_OPT_PROT)
+    PrintS("]");
+  return TRUE;
+}
+
+void kStratInitChangeTailRing(kStrategy strat)
+{
+  unsigned long l = 0;
+  int i;
+  long e;
+
+  assume(strat->tailRing == currRing);
+
+  for (i=0; i<= strat->Ll; i++)
+  {
+    l = p_GetMaxExpL(strat->L[i].p, currRing, l);
+  }
+  for (i=0; i<=strat->tl; i++)
+  {
+    // Hmm ... this we could do in one Step
+    l = p_GetMaxExpL(strat->T[i].p, currRing, l);
+  }
+  if (rField_is_Ring(currRing))
+  {
+    l *= 2;
+  }
+  e = p_GetMaxExp(l, currRing);
+  if (e <= 1) e = 2;
+
+  kStratChangeTailRing(strat, NULL, NULL, e);
+}
+
+ring sbaRing (kStrategy strat, const ring r, BOOLEAN /*complete*/, int /*sgn*/)
+{
+  int n = rBlocks(r); // Including trailing zero!
+  // if sbaOrder == 1 => use (C,monomial order from r)
+  if (strat->sbaOrder == 1)
+  {
+    if (r->order[0] == ringorder_C || r->order[0] == ringorder_c)
+    {
+      return r;
+    }
+    ring res = rCopy0(r, TRUE, FALSE);
+    res->order  = (int *)omAlloc0((n+1)*sizeof(int));
+    res->block0 = (int *)omAlloc0((n+1)*sizeof(int));
+    res->block1 = (int *)omAlloc0((n+1)*sizeof(int));
+    int **wvhdl = (int **)omAlloc0((n+1)*sizeof(int*));
+    res->wvhdl  = wvhdl;
+    for (int i=1; i<n; i++)
+    {
+      res->order[i]   = r->order[i-1];
+      res->block0[i]  = r->block0[i-1];
+      res->block1[i]  = r->block1[i-1];
+      res->wvhdl[i]   = r->wvhdl[i-1];
+    }
+
+    // new 1st block
+    res->order[0]   = ringorder_C; // Prefix
+    // removes useless secondary component order if defined in old ring
+    for (int i=rBlocks(res); i>0; --i) {
+      if (res->order[i] == ringorder_C || res->order[i] == ringorder_c) {
+        res->order[i] = 0;
+      }
+    }
+    rComplete(res, 1);
+#ifdef HAVE_PLURAL
+    if (rIsPluralRing(r))
+    {
+      if ( nc_rComplete(r, res, false) ) // no qideal!
+      {
+#ifndef SING_NDEBUG
+        WarnS("error in nc_rComplete");
+#endif
+        // cleanup?
+
+        //      rDelete(res);
+        //      return r;
+
+        // just go on..
+      }
+    }
+#endif
+    strat->tailRing = res;
+    return (res);
+  }
+  // if sbaOrder == 3 => degree - position - ring order
+  if (strat->sbaOrder == 3)
+  {
+    ring res = rCopy0(r, TRUE, FALSE);
+    res->order  = (int *)omAlloc0((n+2)*sizeof(int));
+    res->block0 = (int *)omAlloc0((n+2)*sizeof(int));
+    res->block1 = (int *)omAlloc0((n+2)*sizeof(int));
+    int **wvhdl = (int **)omAlloc0((n+2)*sizeof(int*));
+    res->wvhdl  = wvhdl;
+    for (int i=2; i<n+2; i++)
+    {
+      res->order[i]   = r->order[i-2];
+      res->block0[i]  = r->block0[i-2];
+      res->block1[i]  = r->block1[i-2];
+      res->wvhdl[i]   = r->wvhdl[i-2];
+    }
+
+    // new 1st block
+    res->order[0]   = ringorder_a; // Prefix
+    res->block0[0]  = 1;
+    res->wvhdl[0]   = (int *)omAlloc(res->N*sizeof(int));
+    for (int i=0; i<res->N; ++i)
+      res->wvhdl[0][i]  = 1;
+    res->block1[0]  = si_min(res->N, rVar(res));
+    // new 2nd block
+    res->order[1]   = ringorder_C; // Prefix
+    res->wvhdl[1]   = NULL;
+    // removes useless secondary component order if defined in old ring
+    for (int i=rBlocks(res); i>1; --i) {
+      if (res->order[i] == ringorder_C || res->order[i] == ringorder_c) {
+        res->order[i] = 0;
+      }
+    }
+    rComplete(res, 1);
+#ifdef HAVE_PLURAL
+    if (rIsPluralRing(r))
+    {
+      if ( nc_rComplete(r, res, false) ) // no qideal!
+      {
+#ifndef SING_NDEBUG
+        WarnS("error in nc_rComplete");
+#endif
+        // cleanup?
+
+        //      rDelete(res);
+        //      return r;
+
+        // just go on..
+      }
+    }
+#endif
+    strat->tailRing = res;
+    return (res);
+  }
+
+  // not sbaOrder == 1 => use Schreyer order
+  // this is done by a trick when initializing the signatures
+  // in initSLSba():
+  // Instead of using the signature 1e_i for F->m[i], we start
+  // with the signature LM(F->m[i])e_i for F->m[i]. Doing this we get a
+  // Schreyer order w.r.t. the underlying monomial order.
+  // => we do not need to change the underlying polynomial ring at all!
+
+  // UPDATE/NOTE/TODO: use induced Schreyer ordering 'IS'!!!!????
+
+  /*
+  else
+  {
+    ring res = rCopy0(r, FALSE, FALSE);
+    // Create 2 more blocks for prefix/suffix:
+    res->order=(int *)omAlloc0((n+2)*sizeof(int)); // 0  ..  n+1
+    res->block0=(int *)omAlloc0((n+2)*sizeof(int));
+    res->block1=(int *)omAlloc0((n+2)*sizeof(int));
+    int ** wvhdl =(int **)omAlloc0((n+2)*sizeof(int**));
+
+    // Encapsulate all existing blocks between induced Schreyer ordering markers: prefix and suffix!
+    // Note that prefix and suffix have the same ringorder marker and only differ in block[] parameters!
+
+    // new 1st block
+    int j = 0;
+    res->order[j] = ringorder_IS; // Prefix
+    res->block0[j] = res->block1[j] = 0;
+    // wvhdl[j] = NULL;
+    j++;
+
+    for(int i = 0; (i < n) && (r->order[i] != 0); i++, j++) // i = [0 .. n-1] <- non-zero old blocks
+    {
+      res->order [j] = r->order [i];
+      res->block0[j] = r->block0[i];
+      res->block1[j] = r->block1[i];
+
+      if (r->wvhdl[i] != NULL)
+      {
+        wvhdl[j] = (int*) omMemDup(r->wvhdl[i]);
+      } // else wvhdl[j] = NULL;
+    }
+
+    // new last block
+    res->order [j] = ringorder_IS; // Suffix
+    res->block0[j] = res->block1[j] = sgn; // Sign of v[o]: 1 for C, -1 for c
+    // wvhdl[j] = NULL;
+    j++;
+
+    // res->order [j] = 0; // The End!
+    res->wvhdl = wvhdl;
+
+    // j == the last zero block now!
+    assume(j == (n+1));
+    assume(res->order[0]==ringorder_IS);
+    assume(res->order[j-1]==ringorder_IS);
+    assume(res->order[j]==0);
+
+    if (complete)
+    {
+      rComplete(res, 1);
+
+#ifdef HAVE_PLURAL
+      if (rIsPluralRing(r))
+      {
+        if ( nc_rComplete(r, res, false) ) // no qideal!
+        {
+        }
+      }
+      assume(rIsPluralRing(r) == rIsPluralRing(res));
+#endif
+
+
+#ifdef HAVE_PLURAL
+      ring old_ring = r;
+
+#endif
+
+      if (r->qideal!=NULL)
+      {
+        res->qideal= idrCopyR_NoSort(r->qideal, r, res);
+
+        assume(idRankFreeModule(res->qideal, res) == 0);
+
+#ifdef HAVE_PLURAL
+        if( rIsPluralRing(res) )
+          if( nc_SetupQuotient(res, r, true) )
+          {
+            //          WarnS("error in nc_SetupQuotient"); // cleanup?      rDelete(res);       return r;  // just go on...?
+          }
+
+#endif
+        assume(idRankFreeModule(res->qideal, res) == 0);
+      }
+
+#ifdef HAVE_PLURAL
+      assume((res->qideal==NULL) == (old_ring->qideal==NULL));
+      assume(rIsPluralRing(res) == rIsPluralRing(old_ring));
+      assume(rIsSCA(res) == rIsSCA(old_ring));
+      assume(ncRingType(res) == ncRingType(old_ring));
+#endif
+    }
+    strat->tailRing = res;
+    return res;
+  }
+  */
+
+  assume(FALSE);
+  return(NULL);
+}
+
+skStrategy::skStrategy()
+{
+  memset(this, 0, sizeof(skStrategy));
+#ifndef SING_NDEBUG
+  strat_nr++;
+  nr=strat_nr;
+  if (strat_fac_debug) Print("s(%d) created\n",nr);
+#endif
+  tailRing = currRing;
+  P.tailRing = currRing;
+  tl = -1;
+  sl = -1;
+#ifdef HAVE_LM_BIN
+  lmBin = omGetStickyBinOfBin(currRing->PolyBin);
+#endif
+#ifdef HAVE_TAIL_BIN
+  tailBin = omGetStickyBinOfBin(currRing->PolyBin);
+#endif
+  pOrigFDeg = currRing->pFDeg;
+  pOrigLDeg = currRing->pLDeg;
+}
+
+
+skStrategy::~skStrategy()
+{
+  if (lmBin != NULL)
+    omMergeStickyBinIntoBin(lmBin, currRing->PolyBin);
+  if (tailBin != NULL)
+    omMergeStickyBinIntoBin(tailBin,
+                            (tailRing != NULL ? tailRing->PolyBin:
+                             currRing->PolyBin));
+  if (t_kHEdge != NULL)
+    p_LmFree(t_kHEdge, tailRing);
+  if (t_kNoether != NULL)
+    p_LmFree(t_kNoether, tailRing);
+
+  if (currRing != tailRing)
+    rKillModifiedRing(tailRing);
+  pRestoreDegProcs(currRing,pOrigFDeg, pOrigLDeg);
+}
+
+#if 0
+Timings for the different possibilities of posInT:
+            T15           EDL         DL          EL            L         1-2-3
+Gonnet      43.26       42.30       38.34       41.98       38.40      100.04
+Hairer_2_1   1.11        1.15        1.04        1.22        1.08        4.7
+Twomat3      1.62        1.69        1.70        1.65        1.54       11.32
+ahml         4.48        4.03        4.03        4.38        4.96       26.50
+c7          15.02       13.98       15.16       13.24       17.31       47.89
+c8         505.09      407.46      852.76      413.21      499.19        n/a
+f855        12.65        9.27       14.97        8.78       14.23       33.12
+gametwo6    11.47       11.35       14.57       11.20       12.02       35.07
+gerhard_3    2.73        2.83        2.93        2.64        3.12        6.24
+ilias13     22.89       22.46       24.62       20.60       23.34       53.86
+noon8       40.68       37.02       37.99       36.82       35.59      877.16
+rcyclic_19  48.22       42.29       43.99       45.35       51.51      204.29
+rkat9       82.37       79.46       77.20       77.63       82.54      267.92
+schwarz_11  16.46       16.81       16.76       16.81       16.72       35.56
+test016     16.39       14.17       14.40       13.50       14.26       34.07
+test017     34.70       36.01       33.16       35.48       32.75       71.45
+test042     10.76       10.99       10.27       11.57       10.45       23.04
+test058      6.78        6.75        6.51        6.95        6.22        9.47
+test066     10.71       10.94       10.76       10.61       10.56       19.06
+test073     10.75       11.11       10.17       10.79        8.63       58.10
+test086     12.23       11.81       12.88       12.24       13.37       66.68
+test103      5.05        4.80        5.47        4.64        4.89       11.90
+test154     12.96       11.64       13.51       12.46       14.61       36.35
+test162     65.27       64.01       67.35       59.79       67.54      196.46
+test164      7.50        6.50        7.68        6.70        7.96       17.13
+virasoro     3.39        3.50        3.35        3.47        3.70        7.66
+#endif
+
+
+//#ifdef HAVE_MORE_POS_IN_T
+#if 1
+// determines the position based on: 1.) Ecart 2.) FDeg 3.) pLength
+int posInT_EcartFDegpLength(const TSet set,const int length,LObject &p)
+{
+
+  if (length==-1) return 0;
+
+  int o = p.ecart;
+  int op=p.GetpFDeg();
+  int ol = p.GetpLength();
+
+  if (set[length].ecart < o)
+    return length+1;
+  if (set[length].ecart == o)
+  {
+     int oo=set[length].GetpFDeg();
+     if ((oo < op) || ((oo==op) && (set[length].length < ol)))
+       return length+1;
+  }
+
+  int i;
+  int an = 0;
+  int en= length;
+  loop
+  {
+    if (an >= en-1)
+    {
+      if (set[an].ecart > o)
+        return an;
+      if (set[an].ecart == o)
+      {
+         int oo=set[an].GetpFDeg();
+         if((oo > op)
+         || ((oo==op) && (set[an].pLength > ol)))
+           return an;
+      }
+      return en;
+    }
+    i=(an+en) / 2;
+    if (set[i].ecart > o)
+      en=i;
+    else if (set[i].ecart == o)
+    {
+       int oo=set[i].GetpFDeg();
+       if ((oo > op)
+       || ((oo == op) && (set[i].pLength > ol)))
+         en=i;
+       else
+        an=i;
+    }
+    else
+      an=i;
+  }
+}
+
+// determines the position based on: 1.) FDeg 2.) pLength
+int posInT_FDegpLength(const TSet set,const int length,LObject &p)
+{
+
+  if (length==-1) return 0;
+
+  int op=p.GetpFDeg();
+  int ol = p.GetpLength();
+
+  int oo=set[length].GetpFDeg();
+  if ((oo < op) || ((oo==op) && (set[length].length < ol)))
+    return length+1;
+
+  int i;
+  int an = 0;
+  int en= length;
+  loop
+    {
+      if (an >= en-1)
+      {
+        int oo=set[an].GetpFDeg();
+        if((oo > op)
+           || ((oo==op) && (set[an].pLength > ol)))
+          return an;
+        return en;
+      }
+      i=(an+en) / 2;
+      int oo=set[i].GetpFDeg();
+      if ((oo > op)
+          || ((oo == op) && (set[i].pLength > ol)))
+        en=i;
+      else
+        an=i;
+    }
+}
+
+
+// determines the position based on: 1.) pLength
+int posInT_pLength(const TSet set,const int length,LObject &p)
+{
+  int ol = p.GetpLength();
+  if (length==-1)
+    return 0;
+  if (set[length].length<p.length)
+    return length+1;
+
+  int i;
+  int an = 0;
+  int en= length;
+
+  loop
+  {
+    if (an >= en-1)
+    {
+      if (set[an].pLength>ol) return an;
+      return en;
+    }
+    i=(an+en) / 2;
+    if (set[i].pLength>ol) en=i;
+    else                        an=i;
+  }
+}
+#endif
+
+// kstd1.cc:
+int redFirst (LObject* h,kStrategy strat);
+int redEcart (LObject* h,kStrategy strat);
+void enterSMora (LObject p,int atS,kStrategy strat, int atR=-1);
+void enterSMoraNF (LObject p,int atS,kStrategy strat, int atR=-1);
+// ../Singular/misc.cc:
+extern char *  showOption();
+
+void kDebugPrint(kStrategy strat)
+{
+  PrintS("red: ");
+    if (strat->red==redFirst) PrintS("redFirst\n");
+    else if (strat->red==redHoney) PrintS("redHoney\n");
+    else if (strat->red==redEcart) PrintS("redEcart\n");
+    else if (strat->red==redHomog) PrintS("redHomog\n");
+    else  Print("%p\n",(void*)strat->red);
+  PrintS("posInT: ");
+    if (strat->posInT==posInT0) PrintS("posInT0\n");
+    else if (strat->posInT==posInT1) PrintS("posInT1\n");
+    else if (strat->posInT==posInT11) PrintS("posInT11\n");
+    else if (strat->posInT==posInT110) PrintS("posInT110\n");
+    else if (strat->posInT==posInT13) PrintS("posInT13\n");
+    else if (strat->posInT==posInT15) PrintS("posInT15\n");
+    else if (strat->posInT==posInT17) PrintS("posInT17\n");
+    else if (strat->posInT==posInT17_c) PrintS("posInT17_c\n");
+    else if (strat->posInT==posInT19) PrintS("posInT19\n");
+    else if (strat->posInT==posInT2) PrintS("posInT2\n");
+#ifdef HAVE_MORE_POS_IN_T
+    else if (strat->posInT==posInT_EcartFDegpLength) PrintS("posInT_EcartFDegpLength\n");
+    else if (strat->posInT==posInT_FDegpLength) PrintS("posInT_FDegpLength\n");
+    else if (strat->posInT==posInT_pLength) PrintS("posInT_pLength\n");
+#endif
+    else if (strat->posInT==posInT_EcartpLength) PrintS("posInT_EcartpLength\n");
+    else if (strat->posInT==posInTrg0) PrintS("posInTrg0\n");
+    else  Print("%p\n",(void*)strat->posInT);
+  PrintS("posInL: ");
+    if (strat->posInL==posInL0) PrintS("posInL0\n");
+    else if (strat->posInL==posInL10) PrintS("posInL10\n");
+    else if (strat->posInL==posInL11) PrintS("posInL11\n");
+    else if (strat->posInL==posInL110) PrintS("posInL110\n");
+    else if (strat->posInL==posInL13) PrintS("posInL13\n");
+    else if (strat->posInL==posInL15) PrintS("posInL15\n");
+    else if (strat->posInL==posInL17) PrintS("posInL17\n");
+    else if (strat->posInL==posInL17_c) PrintS("posInL17_c\n");
+    else if (strat->posInL==posInLSpecial) PrintS("posInLSpecial\n");
+    else if (strat->posInL==posInLrg0) PrintS("posInLrg0\n");
+    else  Print("%p\n",(void*)strat->posInL);
+  PrintS("enterS: ");
+    if (strat->enterS==enterSBba) PrintS("enterSBba\n");
+    else if (strat->enterS==enterSMora) PrintS("enterSMora\n");
+    else if (strat->enterS==enterSMoraNF) PrintS("enterSMoraNF\n");
+    else  Print("%p\n",(void*)strat->enterS);
+  PrintS("initEcart: ");
+    if (strat->initEcart==initEcartBBA) PrintS("initEcartBBA\n");
+    else if (strat->initEcart==initEcartNormal) PrintS("initEcartNormal\n");
+    else  Print("%p\n",(void*)strat->initEcart);
+  PrintS("initEcartPair: ");
+    if (strat->initEcartPair==initEcartPairBba) PrintS("initEcartPairBba\n");
+    else if (strat->initEcartPair==initEcartPairMora) PrintS("initEcartPairMora\n");
+    else  Print("%p\n",(void*)strat->initEcartPair);
+  Print("homog=%d, LazyDegree=%d, LazyPass=%d, ak=%d,\n",
+         strat->homog, strat->LazyDegree,strat->LazyPass, strat->ak);
+  Print("honey=%d, sugarCrit=%d, Gebauer=%d, noTailReduction=%d, use_buckets=%d\n",
+         strat->honey,strat->sugarCrit,strat->Gebauer,strat->noTailReduction,strat->use_buckets);
+  Print("posInLDependsOnLength=%d\n",
+         strat->posInLDependsOnLength);
+  PrintS(showOption());PrintLn();
+  PrintS("LDeg: ");
+    if (currRing->pLDeg==pLDeg0) PrintS("pLDeg0");
+    else if (currRing->pLDeg==pLDeg0c) PrintS("pLDeg0c");
+    else if (currRing->pLDeg==pLDegb) PrintS("pLDegb");
+    else if (currRing->pLDeg==pLDeg1) PrintS("pLDeg1");
+    else if (currRing->pLDeg==pLDeg1c) PrintS("pLDeg1c");
+    else if (currRing->pLDeg==pLDeg1_Deg) PrintS("pLDeg1_Deg");
+    else if (currRing->pLDeg==pLDeg1c_Deg) PrintS("pLDeg1c_Deg");
+    else if (currRing->pLDeg==pLDeg1_Totaldegree) PrintS("pLDeg1_Totaldegree");
+    else if (currRing->pLDeg==pLDeg1c_Totaldegree) PrintS("pLDeg1c_Totaldegree");
+    else if (currRing->pLDeg==pLDeg1_WFirstTotalDegree) PrintS("pLDeg1_WFirstTotalDegree");
+    else if (currRing->pLDeg==pLDeg1c_WFirstTotalDegree) PrintS("pLDeg1c_WFirstTotalDegree");
+    else if (currRing->pLDeg==maxdegreeWecart) PrintS("maxdegreeWecart");
+    else Print("? (%lx)", (long)currRing->pLDeg);
+    PrintS(" / ");
+    if (strat->tailRing->pLDeg==pLDeg0) PrintS("pLDeg0");
+    else if (strat->tailRing->pLDeg==pLDeg0c) PrintS("pLDeg0c");
+    else if (strat->tailRing->pLDeg==pLDegb) PrintS("pLDegb");
+    else if (strat->tailRing->pLDeg==pLDeg1) PrintS("pLDeg1");
+    else if (strat->tailRing->pLDeg==pLDeg1c) PrintS("pLDeg1c");
+    else if (strat->tailRing->pLDeg==pLDeg1_Deg) PrintS("pLDeg1_Deg");
+    else if (strat->tailRing->pLDeg==pLDeg1c_Deg) PrintS("pLDeg1c_Deg");
+    else if (strat->tailRing->pLDeg==pLDeg1_Totaldegree) PrintS("pLDeg1_Totaldegree");
+    else if (strat->tailRing->pLDeg==pLDeg1c_Totaldegree) PrintS("pLDeg1c_Totaldegree");
+    else if (strat->tailRing->pLDeg==pLDeg1_WFirstTotalDegree) PrintS("pLDeg1_WFirstTotalDegree");
+    else if (strat->tailRing->pLDeg==pLDeg1c_WFirstTotalDegree) PrintS("pLDeg1c_WFirstTotalDegree");
+    else if (strat->tailRing->pLDeg==maxdegreeWecart) PrintS("maxdegreeWecart");
+    else Print("? (%lx)", (long)strat->tailRing->pLDeg);
+    PrintLn();
+  PrintS("currRing->pFDeg: ");
+    if (currRing->pFDeg==p_Totaldegree) PrintS("p_Totaldegree");
+    else if (currRing->pFDeg==p_WFirstTotalDegree) PrintS("pWFirstTotalDegree");
+    else if (currRing->pFDeg==p_Deg) PrintS("p_Deg");
+    else if (currRing->pFDeg==kHomModDeg) PrintS("kHomModDeg");
+    else if (currRing->pFDeg==totaldegreeWecart) PrintS("totaldegreeWecart");
+    else if (currRing->pFDeg==p_WTotaldegree) PrintS("p_WTotaldegree");
+    else Print("? (%lx)", (long)currRing->pFDeg);
+    PrintLn();
+    Print(" syzring:%d, syzComp(strat):%d limit:%d\n",rIsSyzIndexRing(currRing),strat->syzComp,rGetCurrSyzLimit(currRing));
+    if(TEST_OPT_DEGBOUND)
+      Print(" degBound: %d\n", Kstd1_deg);
+
+    if( ecartWeights != NULL )
+    {
+       PrintS("ecartWeights: ");
+       for (int i = rVar(currRing); i > 0; i--)
+         Print("%hd ", ecartWeights[i]);
+       PrintLn();
+       assume( TEST_OPT_WEIGHTM );
+    }
+
+#ifndef SING_NDEBUG
+    rDebugPrint(currRing);
+#endif
+}
+
+
+#ifdef HAVE_SHIFTBBA
+poly pMove2CurrTail(poly p, kStrategy strat)
+{
+  /* assume: p is completely in currRing */
+  /* produces an object with LM in curring
+     and TAIL in tailring */
+  if (pNext(p)!=NULL)
+  {
+    pNext(p) = prMoveR(pNext(p), /* src */ currRing, /* dest */ strat->tailRing);
+  }
+  return(p);
+}
+#endif
+
+#ifdef HAVE_SHIFTBBA
+poly pMoveCurrTail2poly(poly p, kStrategy strat)
+{
+  /* assume: p has  LM in curring and TAIL in tailring */
+  /* convert it to complete currRing */
+
+  /* check that LM is in currRing */
+  assume(p_LmCheckIsFromRing(p, currRing));
+
+  if (pNext(p)!=NULL)
+  {
+    pNext(p) = prMoveR(pNext(p), /* src */ strat->tailRing, /* dest */currRing);
+  }
+  return(p);
+}
+#endif
+
+#ifdef HAVE_SHIFTBBA
+poly pCopyL2p(LObject H, kStrategy strat)
+{
+    /* restores a poly in currRing from LObject */
+    LObject h = H;
+    h.Copy();
+    poly p;
+    if (h.p == NULL)
+    {
+      if (h.t_p != NULL)
+      {
+         p = prMoveR(h.t_p, /* source ring: */ strat->tailRing, /* dest. ring: */ currRing);
+        return(p);
+      }
+      else
+      {
+        /* h.tp == NULL -> the object is NULL */
+        return(NULL);
+      }
+    }
+    /* we're here if h.p != NULL */
+    if (h.t_p == NULL)
+    {
+       /* then h.p is the whole poly in currRing */
+       p = h.p;
+      return(p);
+    }
+    /* we're here if h.p != NULL and h.t_p != NULL */
+    // clean h.p, get poly from t_p
+     pNext(h.p)=NULL;
+     pDelete(&h.p);
+     p = prMoveR(h.t_p, /* source ring: */ strat->tailRing,
+                         /* dest. ring: */ currRing);
+     // no need to clean h: we re-used the polys
+    return(p);
+}
+#endif
+
+//LObject pCopyp2L(poly p, kStrategy strat)
+//{
+    /* creates LObject from the poly in currRing */
+  /* actually put p into L.p and make L.t_p=NULL : does not work */
+
+//}
+
+// poly pCopyL2p(LObject H, kStrategy strat)
+// {
+//   /* restores a poly in currRing from LObject */
+//   LObject h = H;
+//   h.Copy();
+//   poly p;
+//   if (h.p == NULL)
+//   {
+//     if (h.t_p != NULL)
+//     {
+//       p = p_ShallowCopyDelete(h.t_p, (strat->tailRing != NULL ? strat->tailRing : currRing), strat->tailBin);
+//       return(p);
+//     }
+//     else
+//     {
+//       /* h.tp == NULL -> the object is NULL */
+//       return(NULL);
+//     }
+//   }
+//   /* we're here if h.p != NULL */
+
+//   if (h.t_p == NULL)
+//   {
+//     /* then h.p is the whole poly in tailRing */
+//     if (strat->tailBin != NULL && (pNext(h.p) != NULL))
+//     {
+//       p = p_ShallowCopyDelete(h.p, (strat->tailRing != NULL ? strat->tailRing : currRing), strat->tailBin);
+//     }
+//     return(p);
+//   }
+//   /* we're here if h.p != NULL and h.t_p != NULL */
+//   p = pCopy(pHead(h.p)); // in currRing
+//   if (strat->tailBin != NULL && (pNext(h.p) != NULL))
+//   {
+//     //    pNext(p) = p_ShallowCopyDelete(pNext(h.t_p), (strat->tailRing != NULL ? strat->tailRing : currRing), strat->tailBin);
+//     poly pp = p_Copy(pNext(h.p), strat->tailRing);
+//     //    poly p3 = p_Copy(pNext(h.p), currRing); // error
+//       // p_ShallowCopyDelete(pNext(h.p), currRing, strat->tailBin); // the same as pp
+//     poly p5 = p_ShallowCopyDelete(pNext(h.p), strat->tailRing, strat->tailBin);
+//     pNext(p) = p_ShallowCopyDelete(h.t_p, strat->tailRing, strat->tailBin);
+//     poly p4 = p_Copy(h.t_p, strat->tailRing);
+//     //    if (p.t_p != NULL) pNext(p.t_p) = pNext(p.p);
+//   }
+//   //  pTest(p);
+//   return(p);
+// }
+
+#ifdef HAVE_SHIFTBBA
+/* including the self pairs */
+void updateSShift(kStrategy strat,int uptodeg,int lV)
+{
+  /* to use after updateS(toT=FALSE,strat) */
+  /* fills T with shifted elt's of S */
+  int i;
+  LObject h;
+  int atT = -1; // or figure out smth better
+  strat->tl = -1; // init
+  for (i=0; i<=strat->sl; i++)
+  {
+    memset(&h,0,sizeof(h));
+    h.p =  strat->S[i]; // lm in currRing, tail in TR
+    strat->initEcart(&h);
+    h.sev = strat->sevS[i];
+    h.t_p = NULL;
+    h.GetTP(); // creates correct t_p
+    /*puts the elements of S with their shifts to T*/
+    //    int atT, int uptodeg, int lV)
+    strat->S_2_R[i] = strat->tl + 1; // the el't with shift 0 will be inserted first
+    // need a small check for above; we insert >=1 elements
+    // insert this check into kTest_TS ?
+    enterTShift(h,strat,atT,uptodeg,lV);
+  }
+  /* what about setting strat->tl? */
+}
+#endif
+
+#ifdef HAVE_SHIFTBBA
+void initBuchMoraShift (ideal F,ideal Q,kStrategy strat)
+{
+  strat->interpt = BTEST1(OPT_INTERRUPT);
+  strat->kHEdge=NULL;
+  if (rHasGlobalOrdering(currRing)) strat->kHEdgeFound=FALSE;
+  /*- creating temp data structures------------------- -*/
+  strat->cp = 0;
+  strat->c3 = 0;
+  strat->cv = 0;
+  strat->tail = pInit();
+  /*- set s -*/
+  strat->sl = -1;
+  /*- set L -*/
+  strat->Lmax = setmaxL;
+  strat->Ll = -1;
+  strat->L = initL();
+  /*- set B -*/
+  strat->Bmax = setmaxL;
+  strat->Bl = -1;
+  strat->B = initL();
+  /*- set T -*/
+  strat->tl = -1;
+  strat->tmax = setmaxT;
+  strat->T = initT();
+  strat->R = initR();
+  strat->sevT = initsevT();
+  /*- init local data struct.---------------------------------------- -*/
+  strat->P.ecart=0;
+  strat->P.length=0;
+  if (rHasLocalOrMixedOrdering(currRing))
+  {
+    if (strat->kHEdge!=NULL) pSetComp(strat->kHEdge, strat->ak);
+    if (strat->kNoether!=NULL) pSetComp(strat->kNoetherTail(), strat->ak);
+  }
+  #ifdef HAVE_RINGS
+  if(rField_is_Ring(currRing))
+  {
+    /*Shdl=*/initSL(F, Q,strat); /*sets also S, ecartS, fromQ */
+  }
+  #endif
+  {
+    if(TEST_OPT_SB_1)
+    {
+        int i;
+        ideal P=idInit(IDELEMS(F)-strat->newIdeal,F->rank);
+        for (i=strat->newIdeal;i<IDELEMS(F);i++)
+        {
+          P->m[i-strat->newIdeal] = F->m[i];
+          F->m[i] = NULL;
+        }
+        initSSpecial(F,Q,P,strat);
+        for (i=strat->newIdeal;i<IDELEMS(F);i++)
+        {
+          F->m[i] = P->m[i-strat->newIdeal];
+          P->m[i-strat->newIdeal] = NULL;
+        }
+        idDelete(&P);
+    }
+    else
+    {
+      /*Shdl=*/initSL(F, Q,strat); /*sets also S, ecartS, fromQ */
+      // /*Shdl=*/initS(F, Q,strat); /*sets also S, ecartS, fromQ */
+    }
+  }
+  strat->fromT = FALSE;
+  strat->noTailReduction = !TEST_OPT_REDTAIL;
+  if (!TEST_OPT_SB_1)
+  {
+    /* the only change: we do not fill the set T*/
+    #ifdef HAVE_RINGS
+    if(!rField_is_Ring(currRing))
+    #endif
+    updateS(FALSE,strat);
+  }
+  if (strat->fromQ!=NULL) omFreeSize(strat->fromQ,IDELEMS(strat->Shdl)*sizeof(int));
+  strat->fromQ=NULL;
+  /* more changes: fill the set T with all the shifts of elts of S*/
+  /* is done by other procedure */
+}
+#endif
+
+#ifdef HAVE_SHIFTBBA
+/*1
+* put the pairs (sh \dot s[i],p)  into the set B, ecart=ecart(p)
+*/
+void enterOnePairManyShifts (int i, poly p, int ecart, int isFromQ, kStrategy strat, int /*atR*/, int uptodeg, int lV)
+{
+  /* p comes from strat->P.p, that is LObject with LM in currRing and Tail in tailRing */
+
+  assume(p_LmCheckIsFromRing(p,currRing));
+  assume(p_CheckIsFromRing(pNext(p),strat->tailRing));
+
+  /* cycles through all shifts of s[i] until uptodeg - lastVblock(s[i]) */
+  /* that is create the pairs (f, s \dot g)  */
+
+  poly qq = strat->S[i]; //  lm in currRing, tail in tailRing
+
+  //  poly q = pCopy(pHead(strat->S[i])); // lm in currRing
+  //  pNext(q) = prCopyR(pNext(strat->S[i]),strat->tailRing,currRing); // zero shift
+
+ /* determine how many elements we have to insert for a given s[i] */
+  /* x(0)y(1)z(2) : lastVblock-1=2, to add until lastVblock=uptodeg-1 */
+  /* hence, a total number of elt's to add is: */
+  /*  int toInsert = 1 + (uptodeg-1) - (pLastVblock(p.p, lV) -1);  */
+  int toInsert =  itoInsert(qq, uptodeg,  lV, strat->tailRing);
+
+#ifdef KDEBUG
+    if (TEST_OPT_DEBUG)
+    {
+      //      Print("entered ManyShifts: with toInsert=%d",toInsert); PrintLn();
+    }
+#endif
+
+  assume(i<=strat->sl); // from OnePair
+  if (strat->interred_flag) return; // ?
+
+  /* these vars hold for all shifts of s[i] */
+  int ecartq = 0; //Hans says it's ok; we're in the homog case, no ecart
+
+  int qfromQ;
+  if (strat->fromQ != NULL)
+  {
+    qfromQ = strat->fromQ[i];
+  }
+  else
+  {
+    qfromQ = -1;
+  }
+
+  int j;
+
+  poly q/*, s*/;
+
+  // for the 0th shift: insert the orig. pair
+  enterOnePairShift(qq, p, ecart, isFromQ, strat, -1, ecartq, qfromQ, 0, i, uptodeg, lV);
+
+  for (j=1; j<= toInsert; j++)
+  {
+    //    q = pLPshift(strat->S[i],j,uptodeg,lV);
+    q = p_LPshiftT(qq, j, uptodeg, lV, strat, currRing);
+    //    q = p_mLPshift(qq,j,uptodeg,lV,currRing); // lm in currRing, shift this monomial
+    //    s = p_LPshift(pNext(qq), j, uptodeg, lV, strat->tailRing); // from tailRing
+    //    pNext(q) = s; // in tailRing
+    /* here we need to call enterOnePair with two polys ... */
+
+#ifdef KDEBUG
+    if (TEST_OPT_DEBUG)
+    {
+      //      PrintS("ManyShifts: calling enterOnePairShift(q,p)");      PrintLn();
+    }
+#endif
+    enterOnePairShift(q, p, ecart, isFromQ, strat, -1, ecartq, qfromQ, j, i, uptodeg, lV);
+  }
+}
+#endif
+
+#ifdef HAVE_SHIFTBBA
+/*1
+* put the pairs (sh \dot qq,p)  into the set B, ecart=ecart(p)
+* despite the name, not only self shifts
+*/
+void enterOnePairSelfShifts (poly qq, poly p, int ecart, int isFromQ, kStrategy strat, int /*atR*/, int uptodeg, int lV)
+{
+
+  /* format: p,qq are in LObject form: lm in CR, tail in TR */
+  /* for true self pairs qq ==p  */
+  /* we test both qq and p */
+  assume(p_LmCheckIsFromRing(qq,currRing));
+  assume(p_CheckIsFromRing(pNext(qq),strat->tailRing));
+  assume(p_LmCheckIsFromRing(p,currRing));
+  assume(p_CheckIsFromRing(pNext(p),strat->tailRing));
+
+  /* since this proc is applied twice for (h, s*g) and (g,s*h), init j with 1 only */
+
+  //  int j = 0;
+  int j = 1;
+
+  /* for such self pairs start with 1, not with 0 */
+  if (qq == p) j=1;
+
+  /* should cycle through all shifts of q until uptodeg - lastVblock(q) */
+  /* that is create the pairs (f, s \dot g)  */
+
+  int toInsert =  itoInsert(qq, uptodeg,  lV, strat->tailRing);
+
+#ifdef KDEBUG
+    if (TEST_OPT_DEBUG)
+    {
+      //      Print("entered SelfShifts: with toInsert=%d",toInsert); PrintLn();
+    }
+#endif
+
+  poly q;
+
+  if (strat->interred_flag) return; // ?
+
+  /* these vars hold for all shifts of s[i] */
+  int ecartq = 0; //Hans says it's ok; we're in the homog case, no ecart
+  int qfromQ = 0; // strat->fromQ[i];
+
+  for (; j<= toInsert; j++)
+  {
+    //    q = pLPshift(strat->S[i],j,uptodeg,lV);
+    /* we increase shifts by one; must delete q there*/
+    //    q = qq; q = pMoveCurrTail2poly(q,strat);
+    //    q = pLPshift(q,j,uptodeg,lV); //,currRing);
+    q = p_LPshiftT(qq, j, uptodeg, lV, strat, currRing);
+    //    q = p_mLPshift(qq,j,uptodeg,lV,currRing); // lm in currRing, shift this monomial
+    //    s = p_LPshift(pNext(qq), j, uptodeg, lV, strat->tailRing); // from tailRing
+    //    pNext(q) = s; // in tailRing
+    /* here we need to call enterOnePair with two polys ... */
+#ifdef KDEBUG
+    if (TEST_OPT_DEBUG)
+    {
+      //      PrintS("SelfShifts: calling enterOnePairShift(q,p)");      PrintLn();
+    }
+#endif
+    enterOnePairShift(q, p, ecart, isFromQ, strat, -1, ecartq, qfromQ, j, -1, uptodeg, lV);
+  }
+}
+#endif
+
+#ifdef HAVE_SHIFTBBA
+/*2
+* put the pair (q,p)  into the set B, ecart=ecart(p), q is the shift of some s[i]
+*/
+void enterOnePairShift (poly q, poly p, int ecart, int isFromQ, kStrategy strat, int atR, int ecartq, int qisFromQ, int shiftcount, int ifromS, int /*uptodeg*/, int lV)
+{
+
+  /* Format: q and p are like strat->P.p, so lm in CR, tail in TR */
+
+  /* check this Formats: */
+  assume(p_LmCheckIsFromRing(q,currRing));
+  assume(p_CheckIsFromRing(pNext(q),strat->tailRing));
+  assume(p_LmCheckIsFromRing(p,currRing));
+  assume(p_CheckIsFromRing(pNext(p),strat->tailRing));
+
+#ifdef KDEBUG
+    if (TEST_OPT_DEBUG)
+    {
+//       PrintS("enterOnePairShift(q,p) invoked with q = ");
+//       wrp(q); //      wrp(pHead(q));
+//       PrintS(", p = ");
+//       wrp(p); //wrp(pHead(p));
+//       PrintLn();
+    }
+#endif
+
+  /* poly q stays for s[i], ecartq = ecart(q), qisFromQ = applies to q */
+
+  int qfromQ = qisFromQ;
+
+  /* need additionally: int up_to_degree, poly V0 with the variables in (0)  or just the number lV = the length of the first block */
+
+  if (strat->interred_flag) return;
+
+  int      l,j,compare;
+  LObject  Lp;
+  Lp.i_r = -1;
+
+#ifdef KDEBUG
+  Lp.ecart=0; Lp.length=0;
+#endif
+  /*- computes the lcm(s[i],p) -*/
+  Lp.lcm = pInit();
+
+  pLcm(p,q, Lp.lcm); // q is what was strat->S[i], so a poly in LM/TR presentation
+  pSetm(Lp.lcm);
+
+  /* apply the V criterion */
+  if (!isInV(Lp.lcm, lV))
+  {
+#ifdef KDEBUG
+    if (TEST_OPT_DEBUG)
+    {
+      PrintS("V crit applied to q = ");
+      wrp(q); //      wrp(pHead(q));
+      PrintS(", p = ");
+      wrp(p); //wrp(pHead(p));
+      PrintLn();
+    }
+#endif
+    pLmFree(Lp.lcm);
+    Lp.lcm=NULL;
+    /* + counter for applying the V criterion */
+    strat->cv++;
+    return;
+  }
+
+  if (strat->sugarCrit && ALLOW_PROD_CRIT(strat))
+  {
+    if((!((ecartq>0)&&(ecart>0)))
+    && pHasNotCF(p,q))
+    {
+    /*
+    *the product criterion has applied for (s,p),
+    *i.e. lcm(s,p)=product of the leading terms of s and p.
+    *Suppose (s,r) is in L and the leading term
+    *of p divides lcm(s,r)
+    *(==> the leading term of p divides the leading term of r)
+    *but the leading term of s does not divide the leading term of r
+    *(notice that this condition is automatically satisfied if r is still
+    *in S), then (s,r) can be cancelled.
+    *This should be done here because the
+    *case lcm(s,r)=lcm(s,p) is not covered by chainCrit.
+    *
+    *Moreover, skipping (s,r) holds also for the noncommutative case.
+    */
+      strat->cp++;
+      pLmFree(Lp.lcm);
+      Lp.lcm=NULL;
+      return;
+    }
+    else
+      Lp.ecart = si_max(ecart,ecartq);
+    if (strat->fromT && (ecartq>ecart))
+    {
+      pLmFree(Lp.lcm);
+      Lp.lcm=NULL;
+      return;
+      /*the pair is (s[i],t[.]), discard it if the ecart is too big*/
+    }
+    /*
+    *the set B collects the pairs of type (S[j],p)
+    *suppose (r,p) is in B and (s,p) is the new pair and lcm(s,p)#lcm(r,p)
+    *if the leading term of s devides lcm(r,p) then (r,p) will be canceled
+    *if the leading term of r devides lcm(s,p) then (s,p) will not enter B
+    */
+    {
+      j = strat->Bl;
+      loop
+      {
+        if (j < 0)  break;
+        compare=pDivComp(strat->B[j].lcm,Lp.lcm);
+        if ((compare==1)
+        &&(sugarDivisibleBy(strat->B[j].ecart,Lp.ecart)))
+        {
+          strat->c3++;
+          if ((strat->fromQ==NULL) || (isFromQ==0) || (qfromQ==0))
+          {
+            pLmFree(Lp.lcm);
+            return;
+          }
+          break;
+        }
+        else
+        if ((compare ==-1)
+        && sugarDivisibleBy(Lp.ecart,strat->B[j].ecart))
+        {
+          deleteInL(strat->B,&strat->Bl,j,strat);
+          strat->c3++;
+        }
+        j--;
+      }
+    }
+  }
+  else /*sugarcrit*/
+  {
+    if (ALLOW_PROD_CRIT(strat))
+    {
+      // if currRing->nc_type!=quasi (or skew)
+      // TODO: enable productCrit for super commutative algebras...
+      if(/*(strat->ak==0) && productCrit(p,strat->S[i])*/
+      pHasNotCF(p,q))
+      {
+      /*
+      *the product criterion has applied for (s,p),
+      *i.e. lcm(s,p)=product of the leading terms of s and p.
+      *Suppose (s,r) is in L and the leading term
+      *of p devides lcm(s,r)
+      *(==> the leading term of p devides the leading term of r)
+      *but the leading term of s does not devide the leading term of r
+      *(notice that tis condition is automatically satisfied if r is still
+      *in S), then (s,r) can be canceled.
+      *This should be done here because the
+      *case lcm(s,r)=lcm(s,p) is not covered by chainCrit.
+      */
+          strat->cp++;
+          pLmFree(Lp.lcm);
+          Lp.lcm=NULL;
+          return;
+      }
+      if (strat->fromT && (ecartq>ecart))
+      {
+        pLmFree(Lp.lcm);
+        Lp.lcm=NULL;
+        return;
+        /*the pair is (s[i],t[.]), discard it if the ecart is too big*/
+      }
+      /*
+      *the set B collects the pairs of type (S[j],p)
+      *suppose (r,p) is in B and (s,p) is the new pair and lcm(s,p)#lcm(r,p)
+      *if the leading term of s devides lcm(r,p) then (r,p) will be canceled
+      *if the leading term of r devides lcm(s,p) then (s,p) will not enter B
+      */
+      for(j = strat->Bl;j>=0;j--)
+      {
+        compare=pDivComp(strat->B[j].lcm,Lp.lcm);
+        if (compare==1)
+        {
+          strat->c3++;
+          if ((strat->fromQ==NULL) || (isFromQ==0) || (qfromQ==0))
+          {
+            pLmFree(Lp.lcm);
+            return;
+          }
+          break;
+        }
+        else
+        if (compare ==-1)
+        {
+          deleteInL(strat->B,&strat->Bl,j,strat);
+          strat->c3++;
+        }
+      }
+    }
+  }
+  /*
+  *the pair (S[i],p) enters B if the spoly != 0
+  */
+  /*-  compute the short s-polynomial -*/
+  if (strat->fromT && !TEST_OPT_INTSTRATEGY)
+    pNorm(p);
+  if ((q==NULL) || (p==NULL))
+    return;
+  if ((strat->fromQ!=NULL) && (isFromQ!=0) && (qfromQ!=0))
+    Lp.p=NULL;
+  else
+  {
+//     if ( rIsPluralRing(currRing) )
+//     {
+//       if(pHasNotCF(p, q))
+//       {
+//         if(ncRingType(currRing) == nc_lie)
+//         {
+//             // generalized prod-crit for lie-type
+//             strat->cp++;
+//             Lp.p = nc_p_Bracket_qq(pCopy(p),q, currRing);
+//         }
+//         else
+//         if( ALLOW_PROD_CRIT(strat) )
+//         {
+//             // product criterion for homogeneous case in SCA
+//             strat->cp++;
+//             Lp.p = NULL;
+//         }
+//         else
+//           Lp.p = nc_CreateSpoly(q,p,currRing); // ?
+//       }
+//       else  Lp.p = nc_CreateSpoly(q,p,currRing);
+//     }
+//     else
+//     {
+
+    /* ksCreateShortSpoly needs two Lobject-kind presentations */
+    /* p is already in this form, so convert q */
+    //    q = pMove2CurrTail(q, strat);
+    Lp.p = ksCreateShortSpoly(q, p, strat->tailRing);
+      //  }
+  }
+  if (Lp.p == NULL)
+  {
+    /*- the case that the s-poly is 0 -*/
+    /* TEMPORARILY DISABLED FOR SHIFTS because there is no i*/
+//      if (strat->pairtest==NULL) initPairtest(strat);
+//      strat->pairtest[i] = TRUE;/*- hint for spoly(S^[i],p)=0 -*/
+//      strat->pairtest[strat->sl+1] = TRUE;
+    /* END _ TEMPORARILY DISABLED FOR SHIFTS */
+    /*hint for spoly(S[i],p) == 0 for some i,0 <= i <= sl*/
+    /*
+    *suppose we have (s,r),(r,p),(s,p) and spoly(s,p) == 0 and (r,p) is
+    *still in B (i.e. lcm(r,p) == lcm(s,p) or the leading term of s does not
+    *devide lcm(r,p)). In the last case (s,r) can be canceled if the leading
+    *term of p devides the lcm(s,r)
+    *(this canceling should be done here because
+    *the case lcm(s,p) == lcm(s,r) is not covered in chainCrit)
+    *the first case is handeled in chainCrit
+    */
+    if (Lp.lcm!=NULL) pLmFree(Lp.lcm);
+  }
+  else
+  {
+    /*- the pair (S[i],p) enters B -*/
+    /* both of them should have their LM in currRing and TAIL in tailring */
+    Lp.p1 = q;  // already in the needed form
+    Lp.p2 = p; // already in the needed form
+
+    if ( !rIsPluralRing(currRing) )
+      pNext(Lp.p) = strat->tail;
+
+    /* TEMPORARILY DISABLED FOR SHIFTS because there's no i*/
+    /* at the beginning we DO NOT set atR = -1 ANYMORE*/
+    if ( (atR >= 0) && (shiftcount==0) && (ifromS >=0) )
+    {
+      Lp.i_r1 = kFindInT(Lp.p1,strat); //strat->S_2_R[ifromS];
+      Lp.i_r2 = atR;
+    }
+    else
+    {
+      /* END _ TEMPORARILY DISABLED FOR SHIFTS */
+      Lp.i_r1 = -1;
+      Lp.i_r2 = -1;
+     }
+    strat->initEcartPair(&Lp,q,p,ecartq,ecart);
+
+    if (TEST_OPT_INTSTRATEGY)
+    {
+      if (!rIsPluralRing(currRing))
+        nDelete(&(Lp.p->coef));
+    }
+
+    l = strat->posInL(strat->B,strat->Bl,&Lp,strat);
+    enterL(&strat->B,&strat->Bl,&strat->Bmax,Lp,l);
+  }
+}
+#endif
+
+#ifdef HAVE_SHIFTBBA
+/*2
+*(s[0],h),...,(s[k],h) will be put to the pairset L(via initenterpairs)
+*superfluous elements in S will be deleted
+*/
+void enterpairsShift (poly h,int k,int ecart,int pos,kStrategy strat, int atR,int uptodeg, int lV)
+{
+  /* h is strat->P.p, that is LObject with LM in currRing and Tail in tailRing */
+  /* Q: what is exactly the strat->fromT ? A: a local case trick; don't need it yet*/
+  int j=pos;
+
+#ifdef HAVE_RINGS
+  assume (!rField_is_Ring(currRing));
+#endif
+  initenterpairsShift(h,k,ecart,0,strat, atR,uptodeg,lV);
+  if ( (!strat->fromT)
+  && ((strat->syzComp==0)
+    ||(pGetComp(h)<=strat->syzComp)))
+  {
+    //Print("start clearS k=%d, pos=%d, sl=%d\n",k,pos,strat->sl);
+    unsigned long h_sev = pGetShortExpVector(h);
+    loop
+    {
+      if (j > k) break;
+      clearS(h,h_sev, &j,&k,strat);
+      j++;
+    }
+    //Print("end clearS sl=%d\n",strat->sl);
+  }
+ // PrintS("end enterpairs\n");
+}
+#endif
+
+#ifdef HAVE_SHIFTBBA
+/*3
+*(s[0], s \dot h),...,(s[k],s \dot h) will be put to the pairset L
+* also the pairs (h, s\dot s[0]), ..., (h, s\dot s[k]) enter L
+* additionally we put the pairs (h, s \sdot h) for s>=1 to L
+*/
+void initenterpairsShift (poly h,int k,int ecart,int isFromQ, kStrategy strat, int atR, int uptodeg, int lV)
+{
+  /* h comes from strat->P.p, that is LObject with LM in currRing and Tail in tailRing */
+  //  atR = -1;
+  if ((strat->syzComp==0)
+  || (pGetComp(h)<=strat->syzComp))
+  {
+    int j;
+    BOOLEAN new_pair=FALSE;
+
+    if (pGetComp(h)==0)
+    {
+      /* for Q!=NULL: build pairs (f,q),(f1,f2), but not (q1,q2)*/
+      if ((isFromQ)&&(strat->fromQ!=NULL))
+      {
+        for (j=0; j<=k; j++)
+        {
+          if (!strat->fromQ[j])
+          {
+            new_pair=TRUE;
+            enterOnePairManyShifts(j,h,ecart,isFromQ,strat, atR,uptodeg,lV);
+            // other side pairs:
+            enterOnePairSelfShifts(h,strat->S[j],ecart,isFromQ,strat, atR,uptodeg,lV);
+          //Print("j:%d, Ll:%d\n",j,strat->Ll);
+          }
+        }
+      }
+      else
+      {
+        new_pair=TRUE;
+        for (j=0; j<=k; j++)
+        {
+          enterOnePairManyShifts(j,h,ecart,isFromQ,strat, atR,uptodeg,lV);
+          // other side pairs
+          enterOnePairSelfShifts(h,strat->S[j],ecart,isFromQ,strat, atR,uptodeg,lV);
+        }
+        /* HERE we put (h, s*h) pairs */
+       /* enterOnePairSelfShifts (poly qq, poly p, int ecart, int isFromQ, kStrategy strat, int atR, int uptodeg, int lV); */
+       enterOnePairSelfShifts (h, h, ecart, isFromQ, strat, atR, uptodeg, lV);
+      }
+    }
+    else
+    {
+      for (j=0; j<=k; j++)
+      {
+        if ((pGetComp(h)==pGetComp(strat->S[j]))
+        || (pGetComp(strat->S[j])==0))
+        {
+          new_pair=TRUE;
+          enterOnePairManyShifts(j,h,ecart,isFromQ,strat, atR, uptodeg, lV);
+          // other side pairs
+          enterOnePairSelfShifts(h,strat->S[j],ecart,isFromQ,strat, atR,uptodeg,lV);
+        //Print("j:%d, Ll:%d\n",j,strat->Ll);
+        }
+      }
+      /* HERE we put (h, s*h) pairs */
+      enterOnePairSelfShifts (h, h, ecart, isFromQ, strat, atR, uptodeg, lV);
+    }
+
+    if (new_pair)
+    {
+      strat->chainCrit(h,ecart,strat);
+    }
+
+  }
+}
+#endif
+
+#ifdef HAVE_SHIFTBBA
+/*2
+* puts p to the set T, starting with the at position atT
+* and inserts all admissible shifts of p
+*/
+void enterTShift(LObject p, kStrategy strat, int atT, int uptodeg, int lV)
+{
+  /* determine how many elements we have to insert */
+  /* x(0)y(1)z(2) : lastVblock-1=2, to add until lastVblock=uptodeg-1 */
+  /* hence, a total number of elt's to add is: */
+  /*  int toInsert = 1 + (uptodeg-1) - (pLastVblock(p.p, lV) -1);  */
+
+  int toInsert =  itoInsert(p.p, uptodeg,  lV, strat->tailRing);
+
+#ifdef PDEBUG
+  //  Print("enterTShift uses toInsert: %d", toInsert);  PrintLn();
+#endif
+  int i;
+
+  if (atT < 0)
+    atT = strat->posInT(strat->T, strat->tl, p);
+
+  /* can call enterT in a sequence, e.g. */
+
+  /* shift0 = it's our model for further shifts */
+  enterT(p,strat,atT);
+  LObject qq;
+  for (i=1; i<=toInsert; i++) // toIns - 1?
+  {
+    qq      = p; //qq.Copy();
+    qq.p    = NULL;
+    qq.max  = NULL;
+    qq.t_p = p_LPshift(p_Copy(p.t_p,strat->tailRing), i, uptodeg, lV, strat->tailRing); // direct shift
+    qq.GetP();
+    // update q.sev
+    qq.sev = pGetShortExpVector(qq.p);
+    /* enter it into T, first el't is with the shift 0 */
+    // compute the position for qq
+    atT = strat->posInT(strat->T, strat->tl, qq);
+    enterT(qq,strat,atT);
+  }
+/* Q: what to do with this one in the orig enterT ? */
+/*  strat->R[strat->tl] = &(strat->T[atT]); */
+/* Solution: it is done by enterT each time separately */
+}
+#endif
+
+#ifdef HAVE_SHIFTBBA
+poly redtailBbaShift (LObject* L, int pos, kStrategy strat, BOOLEAN withT, BOOLEAN normalize)
+{
+  /* for the shift case need to run it with withT = TRUE */
+  strat->redTailChange=FALSE;
+  if (strat->noTailReduction) return L->GetLmCurrRing();
+  poly h, p;
+  p = h = L->GetLmTailRing();
+  if ((h==NULL) || (pNext(h)==NULL))
+    return L->GetLmCurrRing();
+
+  TObject* With;
+  // placeholder in case strat->tl < 0
+  TObject  With_s(strat->tailRing);
+
+  LObject Ln(pNext(h), strat->tailRing);
+  Ln.pLength = L->GetpLength() - 1;
+
+  pNext(h) = NULL;
+  if (L->p != NULL) pNext(L->p) = NULL;
+  L->pLength = 1;
+
+  Ln.PrepareRed(strat->use_buckets);
+
+  while(!Ln.IsNull())
+  {
+    loop
+    {
+      Ln.SetShortExpVector();
+      if (withT)
+      {
+        int j;
+        j = kFindDivisibleByInT(strat->T, strat->sevT, strat->tl, &Ln);
+        if (j < 0) break;
+        With = &(strat->T[j]);
+      }
+      else
+      {
+        With = kFindDivisibleByInS(strat, pos, &Ln, &With_s);
+        if (With == NULL) break;
+      }
+      if (normalize && (!TEST_OPT_INTSTRATEGY) && (!nIsOne(pGetCoeff(With->p))))
+      {
+        With->pNorm();
+        //if (TEST_OPT_PROT) { PrintS("n"); mflush(); }
+      }
+      strat->redTailChange=TRUE;
+      if (ksReducePolyTail(L, With, &Ln))
+      {
+        // reducing the tail would violate the exp bound
+        //  set a flag and hope for a retry (in bba)
+        strat->completeReduce_retry=TRUE;
+        if ((Ln.p != NULL) && (Ln.t_p != NULL)) Ln.p=NULL;
+        do
+        {
+          pNext(h) = Ln.LmExtractAndIter();
+          pIter(h);
+          L->pLength++;
+        } while (!Ln.IsNull());
+        goto all_done;
+      }
+      if (Ln.IsNull()) goto all_done;
+      if (! withT) With_s.Init(currRing);
+    }
+    pNext(h) = Ln.LmExtractAndIter();
+    pIter(h);
+    L->pLength++;
+  }
+
+  all_done:
+  Ln.Delete();
+  if (L->p != NULL) pNext(L->p) = pNext(p);
+
+  if (strat->redTailChange)
+  {
+    L->length = 0;
+  }
+  L->Normalize(); // HANNES: should have a test
+  kTest_L(L);
+  return L->GetLmCurrRing();
+}
+#endif
diff --git a/kernel/GBEngine/kutil.h b/kernel/GBEngine/kutil.h
new file mode 100644
index 0000000..266477a
--- /dev/null
+++ b/kernel/GBEngine/kutil.h
@@ -0,0 +1,799 @@
+#ifndef KUTIL_H
+#define KUTIL_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: kernel: utils for kStd
+*/
+
+
+#include <string.h>
+
+#include <omalloc/omalloc.h>
+#include <misc/mylimits.h>
+
+
+#include <kernel/polys.h>
+#include <polys/operations/pShallowCopyDelete.h>
+
+#include <kernel/structs.h>
+
+// define if tailrings should be used
+#define HAVE_TAIL_RING
+
+#if 1
+#define setmax 16
+#define setmaxL ((4096-12)/sizeof(LObject))
+#define setmaxLinc ((4096)/sizeof(LObject))
+
+#define setmaxT 64
+#define setmaxTinc 32
+#else
+#define setmax 16
+#define setmaxL 16
+#define setmaxLinc 16
+#define setmaxT 16
+#define setmaxTinc 16
+#endif
+
+// if you want std computations as in Singular version < 2:
+// This disables RedThrough, tailReductions against T (bba),
+// sets posInT = posInT15 (bba, strat->honey), and enables redFirst with LDeg
+// NOTE: can be achieved with option(oldStd)
+
+#undef NO_KINLINE
+#if !defined(KDEBUG) && !defined(NO_INLINE)
+#define KINLINE inline
+#else
+#define KINLINE
+#define NO_KINLINE 1
+#endif
+
+typedef int* intset;
+typedef int64  wlen_type;
+typedef wlen_type* wlen_set;
+
+typedef class sTObject TObject;
+typedef class sLObject LObject;
+typedef TObject * TSet;
+typedef LObject * LSet;
+
+typedef struct denominator_list_s denominator_list_s;
+typedef denominator_list_s *denominator_list;
+
+struct denominator_list_s{number n; denominator_list next;};
+extern denominator_list DENOMINATOR_LIST;
+
+class sTObject
+{
+public:
+  unsigned long sevSig;
+  poly sig;   // the signature of the element
+  poly p;       // Lm(p) \in currRing Tail(p) \in tailRing
+  poly t_p;     // t_p \in tailRing: as monomials Lm(t_p) == Lm(p)
+  poly max;     // p_GetMaxExpP(pNext(p))
+  ring tailRing;
+  long FDeg;    // pFDeg(p)
+  int ecart,
+    length,     // as of pLDeg
+    pLength,    // either == 0, or == pLength(p)
+    i_r;        // index of TObject in R set, or -1 if not in T
+  BOOLEAN is_normalized; // true, if pNorm was called on p, false otherwise
+  // used in incremental sba() with F5C:
+  // we know some of the redundant elements in
+  // strat->T beforehand, so we can just discard
+  // them and do not need to consider them in the
+  // interreduction process
+  BOOLEAN is_redundant;
+  // used in sba's sig-safe reduction:
+  // sometimes we already know that a reducer
+  // is sig-safe, so no need for a real
+  // sig-safeness check
+  BOOLEAN is_sigsafe;
+
+
+#ifdef HAVE_PLURAL
+  BOOLEAN is_special; // true, it is a new special S-poly (e.g. for SCA)
+#endif
+
+  // initialization
+  KINLINE void Init(ring r = currRing);
+  KINLINE sTObject(ring tailRing = currRing);
+  KINLINE sTObject(poly p, ring tailRing = currRing);
+  KINLINE sTObject(poly p, ring c_r, ring tailRing);
+  KINLINE sTObject(sTObject* T, int copy);
+
+  KINLINE void Set(ring r=currRing);
+  KINLINE void Set(poly p_in, ring r=currRing);
+  KINLINE void Set(poly p_in, ring c_r, ring t_r);
+
+  // Frees the polys of T
+  KINLINE void Delete();
+  // Sets polys to NULL
+  KINLINE void Clear();
+  // makes a copy of the poly of T
+  KINLINE void Copy();
+
+  // ring-dependent Lm access: these might result in allocation of monomials
+  KINLINE poly GetLmCurrRing();
+  KINLINE poly GetLmTailRing();
+  KINLINE poly GetLm(ring r);
+  // this returns Lm and ring r (preferably from tailRing), but does not
+  // allocate a new poly
+  KINLINE void GetLm(poly &p, ring &r) const;
+
+#ifdef OLIVER_PRIVAT_LT
+  // routines for calc. with rings
+  KINLINE poly GetLtCurrRing();
+  KINLINE poly GetLtTailRing();
+  KINLINE poly GetLt(ring r);
+  KINLINE void GetLt(poly &p, ring &r) const;
+#endif
+
+  KINLINE BOOLEAN IsNull() const;
+
+  KINLINE int GetpLength();
+
+  // makes sure that T.p exists
+  KINLINE void SetLmCurrRing();
+
+  // Iterations
+  // simply get the next monomial
+  KINLINE poly Next();
+  KINLINE void LmDeleteAndIter();
+
+  // deg stuff
+  // compute pTotalDegree
+  KINLINE long pTotalDeg() const;
+  // computes pFDeg
+  KINLINE long pFDeg() const;
+  // computes and sets FDeg
+  KINLINE long SetpFDeg();
+  // gets stored FDeg
+  KINLINE long GetpFDeg() const;
+
+  // computes pLDeg
+  KINLINE long pLDeg();
+  // sets length, FDeg, returns LDeg
+  KINLINE long SetDegStuffReturnLDeg();
+
+  // arithmetic
+  KINLINE void Mult_nn(number n);
+  KINLINE void ShallowCopyDelete(ring new_tailRing, omBin new_tailBin,
+                                 pShallowCopyDeleteProc p_shallow_copy_delete,
+                                 BOOLEAN set_max = TRUE);
+  // manipulations
+  KINLINE void pNorm();
+  KINLINE void pCleardenom();
+
+#ifdef KDEBUG
+  void wrp();
+#endif
+};
+
+#ifndef SING_NDEBUG
+extern int strat_nr;
+extern int strat_fac_debug;
+#endif
+
+class sLObject : public sTObject
+{
+
+public:
+  unsigned long sev;
+  unsigned long checked; // this is the index of S up to which
+                      // the corresponding LObject was already checked in
+                      // critical pair creation => when entering the
+                      // reduction process it is enough to start a second
+                      // rewritten criterion check from checked+1 onwards
+  BOOLEAN prod_crit;
+                      // NOTE: If prod_crit = TRUE then the corresponding pair is
+                      // detected by Buchberger's Product Criterion and can be
+                      // deleted
+  poly  p1,p2; /*- the pair p comes from,
+                 lm(pi) in currRing, tail(pi) in tailring -*/
+
+  poly  lcm;   /*- the lcm of p1,p2 -*/
+  kBucket_pt bucket;
+  int   i_r1, i_r2;
+
+  // initialization
+  KINLINE void Init(ring tailRing = currRing);
+  KINLINE sLObject(ring tailRing = currRing);
+  KINLINE sLObject(poly p, ring tailRing = currRing);
+  KINLINE sLObject(poly p, ring c_r, ring tailRing);
+
+  // Frees the polys of L
+  KINLINE void Delete();
+  KINLINE void Clear();
+
+  // Iterations
+  KINLINE void LmDeleteAndIter();
+  KINLINE poly LmExtractAndIter();
+
+  // spoly related things
+  // preparation for reduction if not spoly
+  KINLINE void PrepareRed(BOOLEAN use_bucket);
+  KINLINE void SetLmTail(poly lm, poly new_p, int length,
+                         int use_bucket, ring r);
+  KINLINE void Tail_Minus_mm_Mult_qq(poly m, poly qq, int lq, poly spNoether);
+  KINLINE void Tail_Mult_nn(number n);
+  // deletes bucket, makes sure that p and t_p exists
+  KINLINE poly GetP(omBin lmBin = NULL);
+  // similar, except that only t_p exists
+  KINLINE poly GetTP();
+
+  // does not delete bucket, just canonicalizes it
+  // returned poly is such that Lm(p) \in currRing, Tail(p) \in tailRing
+  KINLINE poly CanonicalizeP();
+
+  // makes a copy of the poly of L
+  KINLINE void Copy();
+  // gets the poly and makes a copy of it
+  KINLINE poly CopyGetP();
+
+  KINLINE int GetpLength();
+  KINLINE long pLDeg(BOOLEAN use_last);
+  KINLINE long pLDeg();
+  KINLINE int SetLength(BOOLEAN lengt_pLength = FALSE);
+  KINLINE long SetDegStuffReturnLDeg();
+  KINLINE long SetDegStuffReturnLDeg(BOOLEAN use_last);
+
+  // returns minimal component of p
+  KINLINE long MinComp();
+  // returns component of p
+  KINLINE long Comp();
+
+  KINLINE void ShallowCopyDelete(ring new_tailRing,
+                                 pShallowCopyDeleteProc p_shallow_copy_delete);
+
+  // sets sev
+  KINLINE void SetShortExpVector();
+
+  // enable assignment from TObject
+  KINLINE sLObject& operator=(const sTObject&);
+
+  // get T's corresponding to p1, p2: they might return NULL
+  KINLINE TObject* T_1(const skStrategy* strat);
+  KINLINE TObject* T_2(const skStrategy* strat);
+  KINLINE void     T_1_2(const skStrategy* strat,
+                         TObject* &T_1, TObject* &T_2);
+
+  // simplify coefficients
+  KINLINE void Normalize();
+  KINLINE void HeadNormalize();
+};
+
+
+extern int HCord;
+
+class skStrategy;
+typedef skStrategy * kStrategy;
+class skStrategy
+{
+public:
+  kStrategy next;
+  int (*red)(LObject * L,kStrategy strat);
+  int (*red2)(LObject * L,kStrategy strat);
+  void (*initEcart)(TObject * L);
+  int (*posInT)(const TSet T,const int tl,LObject &h);
+  int (*posInLSba)(const LSet set, const int length,
+                LObject* L,const kStrategy strat);
+  int (*posInL)(const LSet set, const int length,
+                LObject* L,const kStrategy strat);
+  void (*enterS)(LObject h, int pos,kStrategy strat, int atR/* =-1*/ );
+  void (*initEcartPair)(LObject * h, poly f, poly g, int ecartF, int ecartG);
+  int (*posInLOld)(const LSet Ls,const int Ll,
+                   LObject* Lo,const kStrategy strat);
+  void (*enterOnePair) (int i,poly p,int ecart, int isFromQ,kStrategy strat, int atR /*= -1*/);
+  void (*chainCrit) (poly p,int ecart,kStrategy strat);
+  BOOLEAN (*syzCrit) (poly sig, unsigned long not_sevSig, kStrategy strat);
+  BOOLEAN (*rewCrit1) (poly sig, unsigned long not_sevSig, poly lm, kStrategy strat, int start /*= 0*/);
+  BOOLEAN (*rewCrit2) (poly sig, unsigned long not_sevSig, poly lm, kStrategy strat, int start /*= 0*/);
+  BOOLEAN (*rewCrit3) (poly sig, unsigned long not_sevSig, poly lm, kStrategy strat, int start /*= 0*/);
+  pFDegProc pOrigFDeg;
+  pLDegProc pOrigLDeg;
+  pFDegProc pOrigFDeg_TailRing;
+  pLDegProc pOrigLDeg_TailRing;
+
+  LObject P;
+  ideal Shdl;
+  ideal D; /*V(S) is in D(D)*/
+  ideal M; /*set of minimal generators*/
+  polyset S;
+  polyset syz;
+  polyset sig;
+  intset ecartS;
+  intset fromS; // from which S[i] S[j] comes from
+                // this is important for signature-based
+                // algorithms
+  intset syzIdx;// index in the syz array at which the first
+                // syzygy of component i comes up
+                // important for signature-based algorithms
+  unsigned sbaOrder;
+  unsigned long currIdx;
+  int max_lower_index;
+  intset lenS;
+  wlen_set lenSw; /* for tgb.ccc */
+  intset fromQ;
+  unsigned long* sevS;
+  unsigned long* sevSyz;
+  unsigned long* sevSig;
+  unsigned long* sevT;
+  TSet T;
+  LSet L;
+  LSet    B;
+  poly    kHEdge;
+  poly    kNoether;
+  poly    t_kHEdge; // same polys in tailring
+  KINLINE poly    kNoetherTail();
+  poly    t_kNoether;
+  BOOLEAN * NotUsedAxis;
+  BOOLEAN * pairtest;/*used for enterOnePair*/
+  poly tail;
+  intvec * kModW;
+  intvec * kHomW;
+  // procedure for ShalloCopy from tailRing  to currRing
+  pShallowCopyDeleteProc p_shallow_copy_delete;
+  // pointers to Tobjects R[i] is ith Tobject which is generated
+  TObject**  R;
+  // S_2_R[i] yields Tobject which corresponds to S[i]
+  int*      S_2_R;
+  ring tailRing;
+  omBin lmBin;
+  omBin tailBin;
+#ifndef SING_NDEBUG
+  int nr;
+#endif
+  int cp,c3;
+  int cv; // in shift bases: counting V criterion
+  int sl,mu;
+  int syzl,syzmax,syzidxmax;
+  int tl,tmax;
+  int Ll,Lmax;
+  int Bl,Bmax;
+  int ak,LazyDegree,LazyPass;
+  int syzComp;
+  int HCord;
+  int lastAxis;
+  int newIdeal;
+  int minim;
+  #ifdef HAVE_SHIFTBBA
+  int lV;
+  #endif
+  BOOLEAN interpt;
+  BOOLEAN homog;
+#ifdef HAVE_PLURAL
+  BOOLEAN z2homog; // Z_2 - homogeneous input allows product criterion in commutative and SCA cases!
+#endif
+  BOOLEAN kHEdgeFound;
+  BOOLEAN honey,sugarCrit;
+  BOOLEAN Gebauer,noTailReduction;
+  BOOLEAN fromT;
+  BOOLEAN noetherSet;
+  BOOLEAN update;
+  BOOLEAN posInLOldFlag;
+  BOOLEAN use_buckets;
+  BOOLEAN interred_flag;
+  // if set, pLDeg(p, l) == (pFDeg(pLast(p), pLength)
+  BOOLEAN LDegLast;
+  // if set, then L.length == L.pLength
+  BOOLEAN length_pLength;
+  // if set, then posInL does not depend on L.length
+  BOOLEAN posInLDependsOnLength;
+  /*FALSE, if posInL == posInL10*/
+#ifdef HAVE_PLURAL
+  // set this flag to 1 to stop the product criteria
+  // use ALLOW_PROD_CRIT(strat) to test
+  BOOLEAN no_prod_crit;
+#define ALLOW_PROD_CRIT(A) (!(A)->no_prod_crit)
+#else
+#define ALLOW_PROD_CRIT(A) (1)
+#endif
+  char    redTailChange;
+  char    news;
+  char    newt;/*used for messageSets*/
+  char    noClearS;
+  char    completeReduce_retry;
+  char    overflow;
+
+  skStrategy();
+  ~skStrategy();
+
+  // return TObject corresponding to S[i]: assume that it exists
+  // i.e. no error checking is done
+  KINLINE TObject* S_2_T(int i);
+  // like S_2_T, except that NULL is returned if it can not be found
+  KINLINE TObject* s_2_t(int i);
+};
+
+void deleteHC(poly *p, int *e, int *l, kStrategy strat);
+void deleteHC(LObject* L, kStrategy strat, BOOLEAN fromNext = FALSE);
+void deleteInS (int i,kStrategy strat);
+void deleteInSSba (int i,kStrategy strat);
+void cleanT (kStrategy strat);
+static inline LSet initL (int nr=setmaxL)
+{ return (LSet)omAlloc(nr*sizeof(LObject)); }
+void deleteInL(LSet set, int *length, int j,kStrategy strat);
+void enterL (LSet *set,int *length, int *LSetmax, LObject p,int at);
+void enterSBba (LObject p,int atS,kStrategy strat, int atR = -1);
+void enterSSba (LObject p,int atS,kStrategy strat, int atR = -1);
+void initEcartPairBba (LObject* Lp,poly f,poly g,int ecartF,int ecartG);
+void initEcartPairMora (LObject* Lp,poly f,poly g,int ecartF,int ecartG);
+int posInS (const kStrategy strat, const int length, const poly p,
+            const int ecart_p);
+int posInT0 (const TSet set,const int length,LObject &p);
+int posInT1 (const TSet set,const int length,LObject &p);
+int posInT2 (const TSet set,const int length,LObject &p);
+int posInT11 (const TSet set,const int length,LObject &p);
+int posInTSig (const TSet set,const int length,LObject &p);
+int posInT110 (const TSet set,const int length,LObject &p);
+int posInT13 (const TSet set,const int length,LObject &p);
+int posInT15 (const TSet set,const int length,LObject &p);
+int posInT17 (const TSet set,const int length,LObject &p);
+int posInT19 (const TSet set,const int length,LObject &p);
+int posInT_EcartpLength(const TSet set,const int length,LObject &p);
+
+#ifdef HAVE_MORE_POS_IN_T
+int posInT_EcartFDegpLength(const TSet set,const int length,LObject &p);
+int posInT_FDegpLength(const TSet set,const int length,LObject &p);
+int posInT_pLength(const TSet set,const int length,LObject &p);
+#endif
+
+
+void reorderS (int* suc,kStrategy strat);
+int posInLF5C (const LSet set, const int length,
+               LObject* L,const kStrategy strat);
+int posInLSig (const LSet set, const int length,
+               LObject* L,const kStrategy strat);
+int posInSyz (const kStrategy strat, const poly sig);
+int posInL0 (const LSet set, const int length,
+             LObject* L,const kStrategy strat);
+int posInL11 (const LSet set, const int length,
+             LObject* L,const kStrategy strat);
+int posInL13 (const LSet set, const int length,
+             LObject* L,const kStrategy strat);
+int posInL15 (const LSet set, const int length,
+             LObject* L,const kStrategy strat);
+int posInL17 (const LSet set, const int length,
+             LObject* L,const kStrategy strat);
+int posInL10 (const LSet set, const int length,
+             LObject* L,const kStrategy strat);
+int posInL110 (const LSet set, const int length,
+             LObject* L,const kStrategy strat);
+KINLINE poly redtailBba (poly p,int pos,kStrategy strat,BOOLEAN normalize=FALSE);
+#ifdef HAVE_RINGS
+KINLINE poly redtailBba_Z (poly p,int pos,kStrategy strat);
+poly redtailBba_Z (LObject* L, int pos, kStrategy strat );
+#endif
+poly redtailBba (LObject *L, int pos,kStrategy strat,
+                 BOOLEAN withT = FALSE,BOOLEAN normalize=FALSE);
+poly redtailSba (LObject *L, int pos,kStrategy strat,
+                 BOOLEAN withT = FALSE,BOOLEAN normalize=FALSE);
+poly redtailBba (TObject *T, int pos,kStrategy strat);
+poly redtail (poly p,int pos,kStrategy strat);
+poly redtail (LObject *L,int pos,kStrategy strat);
+poly redNF (poly h,int & max_ind,int nonorm,kStrategy strat);
+int redNF0 (LObject *P,kStrategy strat);
+poly redNFTail (poly h,const int sl,kStrategy strat);
+int redHoney (LObject* h, kStrategy strat);
+#ifdef HAVE_RINGS
+int redRing (LObject* h,kStrategy strat);
+int redRiloc (LObject* h,kStrategy strat);
+void enterExtendedSpoly(poly h,kStrategy strat);
+void superenterpairs (poly h,int k,int ecart,int pos,kStrategy strat, int atR = -1);
+poly kCreateZeroPoly(long exp[], long cabsind, poly* t_p, ring leadRing, ring tailRing);
+long ind2(long arg);
+
+long ind_fact_2(long arg);
+long twoPow(long arg);
+ideal createG0();
+#endif
+int redLazy (LObject* h,kStrategy strat);
+int redHomog (LObject* h,kStrategy strat);
+int redSig (LObject* h,kStrategy strat);
+//adds hSig to be able to check with F5's criteria when entering pairs!
+void enterpairsSig (poly h, poly hSig, int from, int k, int ec, int pos,kStrategy strat, int atR = -1);
+void enterpairs (poly h, int k, int ec, int pos,kStrategy strat, int atR = -1);
+void entersets (LObject h);
+void pairs ();
+void message (int i,int* reduc,int* olddeg,kStrategy strat,int red_result);
+void messageStat (int hilbcount,kStrategy strat);
+#ifdef KDEBUG
+void messageSets (kStrategy strat);
+#else
+#define messageSets(s)  do {} while (0)
+#endif
+
+void initEcartNormal (TObject* h);
+void initEcartBBA (TObject* h);
+void initS (ideal F, ideal Q,kStrategy strat);
+void initSL (ideal F, ideal Q,kStrategy strat);
+void initSLSba (ideal F, ideal Q,kStrategy strat);
+/*************************************************
+ * when initializing a new bunch of principal
+ * syzygies at the beginning of a new iteration
+ * step in a signature-based algorithm we
+ * compute ONLY the leading elements of those
+ * syzygies, NOT the whole syzygy
+ * NOTE: this needs to be adjusted for a more
+ * general approach on signature-based algorithms
+ ***********************************************/
+void initSyzRules (kStrategy strat);
+void updateS(BOOLEAN toT,kStrategy strat);
+void enterSyz (LObject p,kStrategy strat, int atT);
+void enterT (LObject p,kStrategy strat, int atT = -1);
+void cancelunit (LObject* p,BOOLEAN inNF=FALSE);
+void HEckeTest (poly pp,kStrategy strat);
+void initBuchMoraCrit(kStrategy strat);
+void initSbaCrit(kStrategy strat);
+void initHilbCrit(ideal F, ideal Q, intvec **hilb,kStrategy strat);
+void initBuchMoraPos(kStrategy strat);
+void initSbaPos(kStrategy strat);
+void initBuchMora (ideal F, ideal Q,kStrategy strat);
+void initSbaBuchMora (ideal F, ideal Q,kStrategy strat);
+void exitBuchMora (kStrategy strat);
+void exitSba (kStrategy strat);
+void updateResult(ideal r,ideal Q,kStrategy strat);
+void completeReduce (kStrategy strat, BOOLEAN withT=FALSE);
+void kFreeStrat(kStrategy strat);
+void enterOnePairNormal (int i,poly p,int ecart, int isFromQ,kStrategy strat, int atR);
+void enterOnePairSig (int i,poly p,poly pSig,int ecart, int isFromQ,kStrategy strat, int atR);
+void chainCritNormal (poly p,int ecart,kStrategy strat);
+void chainCritSig (poly p,int ecart,kStrategy strat);
+BOOLEAN homogTest(polyset F, int Fmax);
+BOOLEAN newHEdge(kStrategy strat);
+BOOLEAN syzCriterion(poly sig, unsigned long not_sevSig, kStrategy strat);
+BOOLEAN syzCriterionInc(poly sig, unsigned long not_sevSig, kStrategy strat);
+KINLINE BOOLEAN arriRewDummy(poly sig, unsigned long not_sevSig, poly lm, kStrategy strat, int start);
+BOOLEAN arriRewCriterion(poly sig, unsigned long not_sevSig, poly lm, kStrategy strat, int start);
+BOOLEAN arriRewCriterionPre(poly sig, unsigned long not_sevSig, poly lm, kStrategy strat, int start);
+BOOLEAN faugereRewCriterion(poly sig, unsigned long not_sevSig, poly lm, kStrategy strat, int start);
+BOOLEAN findMinLMPair(poly sig, unsigned long not_sevSig, kStrategy strat, int start);
+
+/// returns index of p in TSet, or -1 if not found
+int kFindInT(poly p, TSet T, int tlength);
+
+/// return -1 if no divisor is found
+///        number of first divisor in T, otherwise
+int kFindDivisibleByInT(const TSet &T, const unsigned long* sevT,
+                        const int tl, const LObject* L, const int start=0);
+
+/// return -1 if no divisor is found
+///        number of first divisor in S, otherwise
+int kFindDivisibleByInS(const kStrategy strat, int *max_ind, LObject* L);
+
+int kFindNextDivisibleByInS(const kStrategy strat, int start,int max_ind, LObject* L);
+TObject*
+kFindDivisibleByInS(kStrategy strat, int pos, LObject* L, TObject *T,
+                    long ecart = LONG_MAX);
+
+/***************************************************************
+ *
+ * stuff to be inlined
+ *
+ ***************************************************************/
+
+KINLINE TSet initT ();
+KINLINE TObject** initR();
+KINLINE unsigned long* initsevT();
+KINLINE poly k_LmInit_currRing_2_tailRing(poly p, ring tailRing, omBin bin);
+KINLINE poly k_LmInit_tailRing_2_currRing(poly p, ring tailRing, omBin bin);
+KINLINE poly k_LmShallowCopyDelete_currRing_2_tailRing(poly p, ring tailRing, omBin bin);
+KINLINE poly k_LmShallowCopyDelete_tailRing_2_currRing(poly p, ring tailRing,  omBin bin);
+
+KINLINE poly k_LmInit_currRing_2_tailRing(poly p, ring tailRing);
+KINLINE poly k_LmInit_tailRing_2_currRing(poly p, ring tailRing);
+KINLINE poly k_LmShallowCopyDelete_currRing_2_tailRing(poly p, ring tailRing);
+KINLINE poly k_LmShallowCopyDelete_tailRing_2_currRing(poly p, ring tailRing);
+
+// if exp bound is not violated, return TRUE and
+//                               get m1 = LCM(LM(p1), LM(p2))/LM(p1)
+//                                   m2 = LCM(LM(p1), LM(p2))/LM(p2)
+// return FALSE and m1 == NULL, m2 == NULL     , otherwise
+KINLINE BOOLEAN k_GetLeadTerms(const poly p1, const poly p2, const ring p_r,
+                               poly &m1, poly &m2, const ring m_r);
+#ifdef HAVE_RINGS
+KINLINE void k_GetStrongLeadTerms(const poly p1, const poly p2, const ring leadRing,
+                               poly &m1, poly &m2, poly &lcm, const ring taiRing);
+#endif
+#ifdef KDEBUG
+// test strat
+BOOLEAN kTest(kStrategy strat);
+// test strat, and test that S is contained in T
+BOOLEAN kTest_TS(kStrategy strat);
+// test LObject
+BOOLEAN kTest_L(LObject* L, ring tailRing = NULL,
+                 BOOLEAN testp = FALSE, int lpos = -1,
+                 TSet T = NULL, int tlength = -1);
+// test TObject
+BOOLEAN kTest_T(TObject* T, ring tailRing = NULL, int tpos = -1, char TN = '?');
+// test set strat->SevS
+BOOLEAN kTest_S(kStrategy strat);
+#else
+#define kTest(A)        (TRUE)
+#define kTest_TS(A)     (TRUE)
+#define kTest_T(T)      (TRUE)
+#define kTest_S(T)      (TRUE)
+#define kTest_L(T)      (TRUE)
+#endif
+
+
+/***************************************************************
+ *
+ * From kstd2.cc
+ *
+ ***************************************************************/
+poly kFindZeroPoly(poly input_p, ring leadRing, ring tailRing);
+ideal bba (ideal F, ideal Q,intvec *w,intvec *hilb,kStrategy strat);
+ideal sba (ideal F, ideal Q,intvec *w,intvec *hilb,kStrategy strat);
+poly kNF2 (ideal F, ideal Q, poly q, kStrategy strat, int lazyReduce);
+ideal kNF2 (ideal F,ideal Q,ideal q, kStrategy strat, int lazyReduce);
+void initBba(ideal F,kStrategy strat);
+void initSba(ideal F,kStrategy strat);
+void f5c (kStrategy strat, int& olddeg, int& minimcnt, int& hilbeledeg,
+          int& hilbcount, int& srmax, int& lrmax, int& reduc, ideal Q,
+          intvec *w,intvec *hilb );
+
+/***************************************************************
+ *
+ * From kspoly.cc
+ *
+ ***************************************************************/
+// Reduces PR with PW
+// Assumes PR != NULL, PW != NULL, Lm(PW) divides Lm(PR)
+// Changes: PR
+// Const:   PW
+// If coef != NULL, then *coef is a/gcd(a,b), where a = LC(PR), b = LC(PW)
+// If strat != NULL, tailRing is changed if reduction would violate exp bound
+// of tailRing
+// Returns: 0 everything ok, no tailRing change
+//          1 tailRing has successfully changed (strat != NULL)
+//          2 no reduction performed, tailRing needs to be changed first
+//            (strat == NULL)
+//         -1 tailRing change could not be performed due to exceeding exp
+//            bound of currRing
+int ksReducePoly(LObject* PR,
+                 TObject* PW,
+                 poly spNoether = NULL,
+                 number *coef = NULL,
+                 kStrategy strat = NULL);
+
+// Reduces PR with PW
+// Assumes PR != NULL, PW != NULL, Lm(PW) divides Lm(PR)
+// Changes: PR
+// Const:   PW
+// If coef != NULL, then *coef is a/gcd(a,b), where a = LC(PR), b = LC(PW)
+// If strat != NULL, tailRing is changed if reduction would violate exp bound
+// of tailRing
+// Returns: 0 everything ok, no tailRing change
+//          1 tailRing has successfully changed (strat != NULL)
+//          2 no reduction performed, tailRing needs to be changed first
+//            (strat == NULL)
+//          3 no reduction performed, not sig-safe!!!
+//         -1 tailRing change could not be performed due to exceeding exp
+//            bound of currRing
+int ksReducePolySig(LObject* PR,
+                 TObject* PW,
+                 long idx,
+                 poly spNoether = NULL,
+                 number *coef = NULL,
+                 kStrategy strat = NULL);
+
+// Reduces PR at Current->next with PW
+// Assumes PR != NULL, Current contained in PR
+//         Current->next != NULL, LM(PW) devides LM(Current->next)
+// Changes: PR
+// Const:   PW
+// Return: see ksReducePoly
+int ksReducePolyTail(LObject* PR,
+                     TObject* PW,
+                     poly Current,
+                     poly spNoether = NULL);
+
+KINLINE int ksReducePolyTail(LObject* PR, TObject* PW, LObject* Red);
+
+// Creates S-Poly of Pair
+// Const:   Pair->p1, Pair->p2
+// Changes: Pair->p == S-Poly of p1, p2
+// Assume:  Pair->p1 != NULL && Pair->p2
+void ksCreateSpoly(LObject* Pair, poly spNoether = NULL,
+                   int use_buckets=0, ring tailRing=currRing,
+                   poly m1 = NULL, poly m2 = NULL, TObject** R = NULL);
+
+/*2
+* creates the leading term of the S-polynomial of p1 and p2
+* do not destroy p1 and p2
+* remarks:
+*   1. the coefficient is 0 (nNew)
+*   2. pNext is undefined
+*/
+poly ksCreateShortSpoly(poly p1, poly p2, ring tailRing);
+
+
+// old stuff
+KINLINE poly ksOldSpolyRed(poly p1, poly p2, poly spNoether = NULL);
+KINLINE poly ksOldSpolyRedNew(poly p1, poly p2, poly spNoether = NULL);
+KINLINE poly ksOldCreateSpoly(poly p1, poly p2, poly spNoether = NULL, ring r = currRing);
+KINLINE void ksOldSpolyTail(poly p1, poly q, poly q2, poly spNoether, ring r = currRing);
+
+/***************************************************************
+ *
+ * Routines related for ring changes during std computations
+ *
+ ***************************************************************/
+// return TRUE and set m1, m2 to k_GetLcmTerms,
+//             if spoly creation of strat->P does not violate
+//             exponent bound of strat->tailRing
+//      FALSE, otherwise
+BOOLEAN kCheckSpolyCreation(LObject* L, kStrategy strat, poly &m1, poly &m2);
+#ifdef HAVE_RINGS
+// return TRUE if gcdpoly creation of R[atR] and S[atS] does not violate
+//             exponent bound of strat->tailRing
+//      FALSE, otherwise
+BOOLEAN kCheckStrongCreation(int atR, poly m1, int atS, poly m2, kStrategy strat);
+#endif
+// change strat->tailRing and adjust all data in strat, L, and T:
+// new tailRing has larger exponent bound
+// do nothing and return FALSE if exponent bound increase would result in
+// larger exponent bound that that of currRing
+BOOLEAN kStratChangeTailRing(kStrategy strat,
+                             LObject* L = NULL, TObject* T = NULL,
+                             // take this as new_expbound: if 0
+                             // new expbound is 2*expbound of tailRing
+                             unsigned long new_expbound = 0);
+// initiate a change of the tailRing of strat -- should be called
+// right before main loop in bba
+void kStratInitChangeTailRing(kStrategy strat);
+
+/// Output some debug info about a given strategy
+void kDebugPrint(kStrategy strat);
+
+// getting sb order for sba computations
+ring sbaRing(kStrategy strat, const ring r=currRing, BOOLEAN complete=TRUE, int sgn=1);
+
+KINLINE void clearS (poly p, unsigned long p_sev, int* at, int* k,
+  kStrategy strat);
+
+#include <kernel/GBEngine/kInline.h>
+
+/* shiftgb stuff */
+#include <kernel/GBEngine/shiftgb.h>
+
+poly pMove2CurrTail(poly p, kStrategy strat);
+
+poly pMoveCurrTail2poly(poly p, kStrategy strat);
+
+poly pCopyL2p(LObject h, kStrategy strat);
+
+void enterTShift(LObject p, kStrategy strat, int atT, int uptodeg, int lV);
+
+void initBuchMoraShift (ideal F,ideal Q,kStrategy strat);
+
+void enterOnePairManyShifts (int i, poly p, int ecart, int isFromQ, kStrategy strat, int atR, int uptodeg, int lV); // ok
+
+void enterOnePairSelfShifts (poly qq, poly p, int ecart, int isFromQ, kStrategy strat, int atR, int uptodeg, int lV);
+
+void enterOnePairShift (poly q, poly p, int ecart, int isFromQ, kStrategy strat, int atR, int ecartq, int qisFromQ, int shiftcount, int ifromS, int uptodeg, int lV); // ok
+
+void enterpairsShift (poly h,int k,int ecart,int pos,kStrategy strat, int atR,int uptodeg, int lV);
+
+void initenterpairsShift (poly h,int k,int ecart,int isFromQ,kStrategy strat, int atR,int uptodeg, int lV);
+
+void updateSShift(kStrategy strat,int uptodeg,int lV);
+
+void initBbaShift(ideal F,kStrategy strat);
+
+poly redtailBbaShift (LObject* L, int pos, kStrategy strat, BOOLEAN withT, BOOLEAN normalize);
+
+int redFirstShift (LObject* h,kStrategy strat); // ok
+
+ideal freegb(ideal I, int uptodeg, int lVblock);
+
+ideal bbaShift(ideal F, ideal Q,intvec *w,intvec *hilb,kStrategy strat, int uptodeg, int lV);
+// test syz strategy: // will be removed soon
+extern  int (*test_PosInT)(const TSet T,const int tl,LObject &h);
+extern  int (*test_PosInL)(const LSet set, const int length,
+                LObject* L,const kStrategy strat);
+#endif
diff --git a/kernel/GBEngine/nc.cc b/kernel/GBEngine/nc.cc
new file mode 100644
index 0000000..2aa6a49
--- /dev/null
+++ b/kernel/GBEngine/nc.cc
@@ -0,0 +1,419 @@
+#define PLURAL_INTERNAL_DECLARATIONS
+
+
+
+
+#include <kernel/mod2.h>
+#include <misc/auxiliary.h>
+
+#include <misc/options.h>
+
+#include <polys/simpleideals.h>
+#include <polys/prCopy.h>
+#include <polys/nc/gb_hack.h>
+
+#include <kernel/polys.h>
+
+#include <kernel/ideals.h>
+#include <kernel/GBEngine/kstd1.h>
+
+#include <kernel/GBEngine/nc.h>
+
+ideal twostd(ideal I) // works in currRing only!
+{
+  ideal J = kStd(I, currRing->qideal, testHomog, NULL, NULL, 0, 0, NULL); // in currRing!!!
+  idSkipZeroes(J); // ring independent!
+
+  const int rN = currRing->N;
+
+  loop
+  {
+    ideal     K    = NULL;
+    const int s    = idElem(J); // ring independent
+
+    for(int i = 0; i < s; i++)
+    {
+      const poly p = J->m[i];
+
+#ifdef PDEBUG
+      p_Test(p, currRing);
+#if 0
+      Print("p: "); // !
+      p_Write(p, currRing);
+#endif
+#endif
+
+      for (int j = 1; j <= rN; j++) // for all j = 1..N
+      {
+        poly varj = p_One( currRing);
+        p_SetExp(varj, j, 1, currRing);
+        p_Setm(varj, currRing);
+
+        poly q = pp_Mult_mm(p, varj, currRing); // q = J[i] * var(j),
+
+#ifdef PDEBUG
+        p_Test(varj, currRing);
+        p_Test(p, currRing);
+        p_Test(q, currRing);
+#if 0
+        Print("Reducing p: "); // !
+        p_Write(p, currRing);
+        Print("With q: "); // !
+        p_Write(q, currRing);
+#endif
+#endif
+
+        p_Delete(&varj, currRing);
+
+        if (q != NULL)
+        {
+#ifdef PDEBUG
+#if 0
+          Print("Reducing q[j = %d]: ", j); // !
+          p_Write(q, currRing);
+
+          Print("With p:");
+          p_Write(p, currRing);
+
+#endif
+#endif
+
+          // bug: lm(p) may not divide lm(p * var(i)) in a SCA!
+          if( p_LmDivisibleBy(p, q, currRing) )
+            q = nc_ReduceSpoly(p, q, currRing);
+
+
+#ifdef PDEBUG
+          p_Test(q, currRing);
+#if 0
+          Print("reductum q/p: ");
+          p_Write(q, currRing);
+
+          // Print("With J!\n");
+#endif
+#endif
+
+//          if( q != NULL)
+          q = kNF(J, currRing->qideal, q, 0, KSTD_NF_NONORM); // in currRing!!!
+
+#ifdef PDEBUG
+          p_Test(q, currRing);
+#if 0
+          Print("NF(J/currRing->qideal)=> q: "); // !
+          p_Write(q, currRing);
+#endif
+#endif
+          if (q!=NULL)
+          {
+            if (p_IsConstant(q, currRing)) // => return (1)!
+            {
+              p_Delete(&q, currRing);
+              id_Delete(&J, currRing);
+
+              if (K != NULL)
+                id_Delete(&K, currRing);
+
+              ideal Q = idInit(1,1); // ring independent!
+              Q->m[0] = p_One(currRing);
+
+              return(Q);
+            }
+
+//            flag = false;
+
+            // K += q:
+
+            ideal Q = idInit(1,1); // ring independent
+            Q->m[0]=q;
+
+            if( K == NULL )
+              K = Q;
+            else
+            {
+              ideal id_tmp = idSimpleAdd(K, Q); // in currRing
+              id_Delete(&K, currRing);
+              id_Delete(&Q, currRing);
+              K = id_tmp; // K += Q
+            }
+          }
+
+
+        } // if q != NULL
+      } // for all variables
+
+    }
+
+    if (K == NULL) // nothing new: i.e. all elements are two-sided
+      return(J);
+    // now we update GrBasis J with K
+    //    iSize=IDELEMS(J);
+#ifdef PDEBUG
+    idTest(J); // in currRing!
+#if 0
+    Print("J:");
+    idPrint(J);
+    PrintLn();
+#endif // debug
+#endif
+
+
+
+#ifdef PDEBUG
+    idTest(K); // in currRing!
+#if 0
+    Print("+K:");
+    idPrint(K);
+    PrintLn();
+#endif // debug
+#endif
+
+
+    int iSize = idElem(J); // ring independent
+
+    // J += K:
+    ideal id_tmp = idSimpleAdd(J,K); // in currRing
+    id_Delete(&K, currRing); id_Delete(&J, currRing);
+
+#if 1
+    BITSET save1;
+    SI_SAVE_OPT1(save1);
+    si_opt_1|=Sy_bit(OPT_SB_1); // ring independent
+    J = kStd(id_tmp, currRing->qideal, testHomog, NULL, NULL, 0, iSize); // J = J + K, J - std // in currRing!
+    SI_RESTORE_OPT1(save1);
+#else
+    J=kStd(id_tmp, currRing->qideal,testHomog,NULL,NULL,0,0,NULL);
+#endif
+
+    id_Delete(&id_tmp, currRing);
+    idSkipZeroes(J); // ring independent
+
+#ifdef PDEBUG
+    idTest(J); // in currRing!
+#if 0
+    Print("J:");
+    idPrint(J);
+    PrintLn();
+#endif // debug
+#endif
+  } // loop
+}
+
+
+
+
+static ideal idPrepareStd(ideal T, ideal s,  int k)
+{
+  // T is a left SB, without zeros, s is a list with zeros
+#ifdef PDEBUG
+  if (IDELEMS(s)!=IDELEMS(T))
+  {
+    Print("ideals of diff. size!!!");
+  }
+#endif
+  ideal t = idCopy(T);
+  int j,rs=id_RankFreeModule(s, currRing);
+  poly p,q;
+
+  ideal res = idInit(2*idElem(t),1+idElem(t));
+  if (rs == 0)
+  {
+    for (j=0; j<IDELEMS(t); j++)
+    {
+      if (s->m[j]!=NULL) pSetCompP(s->m[j],1);
+      if (t->m[j]!=NULL) pSetCompP(t->m[j],1);
+    }
+    k = si_max(k,1);
+  }
+  for (j=0; j<IDELEMS(t); j++)
+  {
+    if (s->m[j]!=NULL)
+    {
+      p = s->m[j];
+      q = pOne();
+      pSetComp(q,k+1+j);
+      pSetmComp(q);
+#if 0
+      while (pNext(p)) pIter(p);
+      pNext(p) = q;
+#else
+      p = pAdd(p,q);
+      s->m[j] = p;
+#ifdef PDEBUG
+    pTest(p);
+#endif
+#endif
+    }
+  }
+  res = idSimpleAdd(t,s);
+  idDelete(&t);
+  res->rank = 1+idElem(T);
+  return(res);
+}
+
+
+ideal Approx_Step(ideal L)
+{
+  int N=currRing->N;
+  int i,j; // k=syzcomp
+  int flag, flagcnt=0, syzcnt=0;
+  int syzcomp = 0;
+  ideal I = kStd(L, currRing->qideal,testHomog,NULL,NULL,0,0,NULL);
+  idSkipZeroes(I);
+  ideal s_I;
+  int idI = idElem(I);
+  ideal trickyQuotient;
+  if (currRing->qideal !=NULL)
+  {
+    trickyQuotient = idSimpleAdd(currRing->qideal,I);
+  }
+  else
+    trickyQuotient = I;
+  idSkipZeroes(trickyQuotient);
+  poly *var = (poly *)omAlloc0((N+1)*sizeof(poly));
+  //  poly *W = (poly *)omAlloc0((2*N+1)*sizeof(poly));
+  resolvente S = (resolvente)omAlloc0((N+1)*sizeof(ideal));
+  ideal SI, res;
+  matrix MI;
+  poly x=pOne();
+  var[0]=x;
+  ideal   h2, s_h2, s_h3;
+  poly    p,q;
+  // init vars
+  for (i=1; i<=N; i++ )
+  {
+    x = pOne();
+    pSetExp(x,i,1);
+    pSetm(x);
+    var[i]=pCopy(x);
+  }
+  // init NF's
+  for (i=1; i<=N; i++ )
+  {
+    h2 = idInit(idI,1);
+    flag = 0;
+    for (j=0; j< idI; j++ )
+    {
+      q = pp_Mult_mm(I->m[j],var[i],currRing);
+      q = kNF(I,currRing->qideal,q,0,0);
+      if (q!=0)
+      {
+    h2->m[j]=pCopy(q);
+    //  p_Shift(&(h2->m[flag]),1, currRing);
+    flag++;
+    pDelete(&q);
+      }
+      else
+    h2->m[j]=0;
+    }
+    // W[1..idElems(I)]
+    if (flag >0)
+    {
+      // compute syzygies with values in I
+      //      idSkipZeroes(h2);
+      //      h2 = idSimpleAdd(h2,I);
+      //      h2->rank=flag+idI+1;
+      idTest(h2);
+      //idShow(h2);
+      ring orig_ring = currRing;
+      ring syz_ring = rAssure_SyzComp(orig_ring, TRUE);
+      syzcomp = 1;
+      rSetSyzComp(syzcomp, syz_ring);
+      if (orig_ring != syz_ring)
+      {
+        rChangeCurrRing(syz_ring);
+        s_h2=idrCopyR_NoSort(h2,orig_ring, syz_ring);
+        //  s_trickyQuotient=idrCopyR_NoSort(trickyQuotient,orig_ring);
+        //  rDebugPrint(syz_ring);
+        s_I=idrCopyR_NoSort(I,orig_ring, syz_ring);
+      }
+      else
+      {
+        s_h2 = h2;
+        s_I  = I;
+        //  s_trickyQuotient=trickyQuotient;
+      }
+      idTest(s_h2);
+      //      idTest(s_trickyQuotient);
+      Print(".proceeding with the variable %d\n",i);
+      s_h3 = idPrepareStd(s_I, s_h2, 1);
+      BITSET save1;
+      SI_SAVE_OPT1(save1);
+      si_opt_1|=Sy_bit(OPT_SB_1);
+      idTest(s_h3);
+      idDelete(&s_h2);
+      s_h2=idCopy(s_h3);
+      idDelete(&s_h3);
+      Print("...computing Syz");
+      s_h3 = kStd(s_h2, currRing->qideal,(tHomog)FALSE,NULL,NULL,syzcomp,idI);
+      SI_RESTORE_OPT1(save1);
+      //idShow(s_h3);
+      if (orig_ring != syz_ring)
+      {
+        idDelete(&s_h2);
+        for (j=0; j<IDELEMS(s_h3); j++)
+        {
+          if (s_h3->m[j] != NULL)
+          {
+            if (p_MinComp(s_h3->m[j],syz_ring) > syzcomp) // i.e. it is a syzygy
+              p_Shift(&s_h3->m[j], -syzcomp, currRing);
+            else
+              pDelete(&s_h3->m[j]);
+          }
+        }
+        idSkipZeroes(s_h3);
+        s_h3->rank -= syzcomp;
+        rChangeCurrRing(orig_ring);
+        //  s_h3 = idrMoveR_NoSort(s_h3, syz_ring, orig_ring);
+        s_h3 = idrMoveR_NoSort(s_h3, syz_ring, orig_ring);
+        rDelete(syz_ring);
+      }
+      idTest(s_h3);
+      S[syzcnt]=kStd(s_h3,currRing->qideal,(tHomog)FALSE,NULL,NULL);
+      syzcnt++;
+      idDelete(&s_h3);
+    } // end if flag >0
+    else
+    {
+      flagcnt++;
+    }
+  }
+  if (flagcnt == N)
+  {
+    Print("the input is a two--sided ideal");
+    return(I);
+  }
+  if (syzcnt >0)
+  {
+    Print("..computing Intersect of %d modules\n",syzcnt);
+    if (syzcnt == 1)
+      SI = S[0];
+    else
+      SI = idMultSect(S, syzcnt);
+    //idShow(SI);
+    MI = id_Module2Matrix(SI,currRing);
+    res= idInit(MATCOLS(MI),1);
+    for (i=1; i<= MATCOLS(MI); i++)
+    {
+      p = NULL;
+      for (j=0; j< idElem(I); j++)
+      {
+        q = pCopy(MATELEM(MI,j+1,i));
+        if (q!=NULL)
+        {
+          q = pMult(q,pCopy(I->m[j]));
+          p = pAdd(p,q);
+        }
+      }
+      res->m[i-1]=p;
+    }
+    Print("final std");
+    res = kStd(res, currRing->qideal,testHomog,NULL,NULL,0,0,NULL);
+    idSkipZeroes(res);
+    return(res);
+  }
+  else
+  {
+    Print("No syzygies");
+    return(I);
+  }
+}
diff --git a/kernel/GBEngine/nc.h b/kernel/GBEngine/nc.h
new file mode 100644
index 0000000..cd016f3
--- /dev/null
+++ b/kernel/GBEngine/nc.h
@@ -0,0 +1,74 @@
+#ifndef KERNEL_NC_H
+#define KERNEL_NC_H
+
+#ifdef HAVE_PLURAL
+
+#ifdef PLURAL_INTERNAL_DECLARATIONS
+
+# include <polys/nc/gb_hack.h>
+
+#else // #ifdef PLURAL_INTERNAL_DECLARATIONS
+
+# define PLURAL_INTERNAL_DECLARATIONS
+# include <polys/nc/gb_hack.h>
+# undef PLURAL_INTERNAL_DECLARATIONS
+
+#endif // #ifdef PLURAL_INTERNAL_DECLARATIONS
+
+
+#include <misc/auxiliary.h>
+
+#include <polys/nc/nc.h>
+#include <polys/simpleideals.h>
+
+#include <kernel/polys.h>
+
+
+
+static inline ideal nc_GB(const ideal F, const ideal Q, const intvec *w, const intvec *hilb, kStrategy strat, const ring r)
+{
+  assume(rIsPluralRing(r));
+  assume(r->GetNC()->p_Procs.GB!=NULL);
+
+  GB_Proc_Ptr gb = cast_A_to_B<void*, GB_Proc_Ptr>(r->GetNC()->p_Procs.GB);
+
+  // NOTE: the following code block is a hack in order to make a linker to
+  // believe in these functions but in reallity it should not be used.
+  // Although it can also serve as an illustration for the
+  // NC-initialization procedure for GB hidden away (hackedly) in
+  // libpolys.
+  // The only other solution would be to separate GB and the whole NC
+  // subsystems from both libpolys AND kernel... which would require
+  // too much effort and thus cannot be done right now.
+  // Therefore this is a TODO for a future (large-scale) cleanup.
+  if( gb == NULL)
+  {
+    if( rIsSCA(r) )
+    {
+      if (rHasLocalOrMixedOrdering(r))
+        gb = sca_mora;
+      else
+        gb = sca_bba; // sca_gr_bba???
+    } else
+    {
+      if (rHasLocalOrMixedOrdering(r))
+        gb = gnc_gr_mora;
+      else
+        gb = gnc_gr_bba;
+    }
+
+    r->GetNC()->p_Procs.GB = cast_A_to_vptr(gb);
+  }
+
+  return gb(F, Q, w, hilb, strat, r);
+}
+
+/// Compute two-sided GB:
+ideal twostd(ideal I);
+
+/// Ann: ???
+ideal Approx_Step(ideal L);
+
+#endif // HAVE_PLURAL
+
+#endif // KERNEL_NC_H
diff --git a/kernel/GBEngine/ratgring.cc b/kernel/GBEngine/ratgring.cc
new file mode 100644
index 0000000..4815c8e
--- /dev/null
+++ b/kernel/GBEngine/ratgring.cc
@@ -0,0 +1,663 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    ratgring.cc
+ *  Purpose: Ore-noncommutative kernel procedures
+ *  Author:  levandov (Viktor Levandovsky)
+ *  Created: 8/00 - 11/00
+ *******************************************************************/
+
+
+
+#include <kernel/mod2.h>
+#include <kernel/GBEngine/ratgring.h>
+#ifdef HAVE_RATGRING
+#include <polys/nc/nc.h>
+#include <polys/monomials/ring.h>
+#include <kernel/polys.h>
+#include <coeffs/numbers.h>
+#include <kernel/ideals.h>
+#include <polys/matpol.h>
+#include <polys/kbuckets.h>
+#include <kernel/GBEngine/kstd1.h>
+#include <polys/sbuckets.h>
+#include <polys/prCopy.h>
+#include <polys/operations/p_Mult_q.h>
+#include <polys/clapsing.h>
+#include <misc/options.h>
+
+void pLcmRat(poly a, poly b, poly m, int rat_shift)
+{
+  /* rat_shift is the last exp one should count with */
+  int i;
+  for (i=(currRing->N); i>=rat_shift; i--)
+  {
+    pSetExp(m,i, si_max( pGetExp(a,i), pGetExp(b,i)));
+  }
+  pSetComp(m, si_max(pGetComp(a), pGetComp(b)));
+  /* Don't do a pSetm here, otherwise hres/lres chockes */
+}
+
+// void pLcmRat(poly a, poly b, poly m, poly pshift)
+// {
+//   /* shift is the exp of rational elements */
+//   int i;
+//   for (i=(currRing->N); i; i--)
+//   {
+//     if (!pGetExp(pshift,i))
+//     {
+//       pSetExp(m,i, si_max( pGetExp(a,i), pGetExp(b,i)));
+//     }
+//     else
+//     {
+//       /* do we really need it? */
+//       pSetExp(m,i,0);
+//     }
+//   }
+//   pSetComp(m, si_max(pGetComp(a), pGetComp(b)));
+//   /* Don't do a pSetm here, otherwise hres/lres chockes */
+// }
+
+/* returns a subpoly of p, s.t. its monomials have the same D-part */
+
+poly p_HeadRat(poly p, int ishift, ring r)
+{
+  poly q   = pNext(p);
+  if (q == NULL) return p;
+  poly res = p_Head(p,r);
+  const long cmp = p_GetComp(p, r);
+  while ( (q!=NULL) && (p_Comp_k_n(p, q, ishift+1, r)) && (p_GetComp(q, r) == cmp) )
+  {
+    res = p_Add_q(res,p_Head(q,r),r);
+    q   = pNext(q);
+  }
+  p_SetCompP(res,cmp,r);
+  return res;
+}
+
+/* to test!!! */
+/* ExpVector(pr) = ExpVector(p1) - ExpVector(p2) */
+void p_ExpVectorDiffRat(poly pr, poly p1, poly p2, int ishift, ring r)
+{
+  p_LmCheckPolyRing1(p1, r);
+  p_LmCheckPolyRing1(p2, r);
+  p_LmCheckPolyRing1(pr, r);
+  int i;
+  poly t=pr;
+  int e1,e2;
+  for (i=ishift+1; i<=r->N; i++)
+  {
+    e1 = p_GetExp(p1, i, r);
+    e2 = p_GetExp(p2, i, r);
+    //    pAssume1(p_GetExp(p1, i, r) >= p_GetExp(p2, i, r));
+    if (e1 < e2)
+    {
+#ifdef PDEBUG
+      PrintS("negative ExpVectorDiff\n");
+#endif
+      p_Delete(&t,r);
+      break;
+    }
+    else
+    {
+      p_SetExp(t,i, e1-e2,r);
+    }
+  }
+  p_Setm(t,r);
+}
+
+/* returns ideal (u,v) s.t. up + vq = 0 */
+
+ideal ncGCD2(poly p, poly q, const ring r)
+{
+  // todo: must destroy p,q
+  intvec *w = NULL;
+  ideal h = idInit(2,1);
+  h->m[0] = p_Copy(p,r);
+  h->m[1] = p_Copy(q,r);
+#ifdef PDEBUG
+  PrintS("running syzygy comp. for nc_GCD:\n");
+#endif
+  ideal sh = idSyzygies(h, testHomog, &w);
+#ifdef PDEBUG
+  PrintS("done syzygy comp. for nc_GCD\n");
+#endif
+  /* in comm case, there is only 1 syzygy */
+  /*   singclap_gcd(); */
+  poly K, K1, K2;
+  K  = sh->m[0]; /* take just the first element - to be enhanced later */
+  K1 = pTakeOutComp(&K, 1); // 1st component is taken out from K
+//  pShift(&K,-2); // 2nd component to 0th comp.
+  K2 = pTakeOutComp(&K, 1);
+//  K2 = K;
+
+  PrintS("syz1: "); p_wrp(K1,r);
+  PrintS("syz2: "); p_wrp(K2,r);
+
+  /* checking signs before multiplying */
+  number ck1 = p_GetCoeff(K1,r);
+  number ck2 = p_GetCoeff(K2,r);
+  BOOLEAN bck1, bck2;
+  bck1 = n_GreaterZero(ck1,r);
+  bck2 = n_GreaterZero(ck2,r);
+  /* K1 <0, K2 <0 (-K1,-K2)    */
+//   if ( !(bck1 && bck2) ) /* - , - */
+//   {
+//     K1 = p_Neg(K1,r);
+//     K2 = p_Neg(K2,r);
+//   }
+  id_Delete(&h,r);
+  h = idInit(2,1);
+  h->m[0] = p_Copy(K1,r);
+  h->m[1] = p_Copy(K2,r);
+  id_Delete(&sh,r);
+  return(h);
+}
+
+/* returns ideal (u,v) s.t. up + vq = 0 */
+
+ideal ncGCD(poly p, poly q, const ring r)
+{
+  // destroys p and q
+  // assume: p,q are in the comm. ring
+  // to be used in the coeff business
+#ifdef PDEBUG
+  PrintS(" GCD_start:");
+#endif
+  poly g = singclap_gcd(p_Copy(p,r),p_Copy(q,r), r);
+#ifdef PDEBUG
+  p_wrp(g,r);
+  PrintS(" GCD_end;\n");
+#endif
+  poly u = singclap_pdivide(q, g, r); //q/g
+  poly v = singclap_pdivide(p, g, r); //p/g
+  v = p_Neg(v,r);
+  p_Delete(&p,r);
+  p_Delete(&q,r);
+  ideal h = idInit(2,1);
+  h->m[0] = u; // p_Copy(u,r);
+  h->m[1] = v; // p_Copy(v,r);
+  return(h);
+}
+
+/* PINLINE1 void p_ExpVectorDiff
+   remains as is -> BUT we can do memory shift on smaller number of exp's */
+
+
+/*4 - follow the numbering of gring.cc
+* creates the S-polynomial of p1 and p2
+* do not destroy p1 and p2
+*/
+// poly nc_rat_CreateSpoly(poly p1, poly p2, poly spNoether, int ishift, const ring r)
+// {
+//   if ((p_GetComp(p1,r)!=p_GetComp(p2,r))
+//   && (p_GetComp(p1,r)!=0)
+//   && (p_GetComp(p2,r)!=0))
+//   {
+// #ifdef PDEBUG
+//     Print("nc_CreateSpoly : different components!");
+// #endif
+//     return(NULL);
+//   }
+//   /* prod. crit does not apply yet */
+// //   if ((r->nc->type==nc_lie) && pHasNotCF(p1,p2)) /* prod crit */
+// //   {
+// //     return(nc_p_Bracket_qq(pCopy(p2),p1));
+// //   }
+//   poly pL=pOne();
+//   poly m1=pOne();
+//   poly m2=pOne();
+//   /* define shift */
+//   int is = ishift; /* TODO */
+//   pLcmRat(p1,p2,pL,is);
+//   p_Setm(pL,r);
+//   poly pr1 = p_GetExp_k_n(p1,1,ishift-1,r); /* rat D-exp of p1 */
+//   poly pr2 = p_GetExp_k_n(p2,1,ishift-1,r); /* rat D-exp of p2 */
+// #ifdef PDEBUG
+//   p_Test(pL,r);
+// #endif
+//   p_ExpVectorDiff(m1,pL,p1,r); /* purely in D part by construction */
+//   //p_SetComp(m1,0,r);
+//   //p_Setm(m1,r);
+// #ifdef PDEBUG
+//   p_Test(m1,r);
+// #endif
+//   p_ExpVectorDiff(m2,pL,p2,r); /* purely in D part by construction */
+//   //p_SetComp(m2,0,r);
+//   //p_Setm(m2,r);
+// #ifdef PDEBUG
+//   p_Test(m2,r);
+// #endif
+//   p_Delete(&pL,r);
+//   /* zero exponents ! */
+
+//   /* EXTRACT LEADCOEF */
+
+//   poly H1  = p_HeadRat(p1,is,r);
+//   poly M1  = r->nc->p_Procs.mm_Mult_p(m1,p_Copy(H1,r),r);
+
+//   /* POLY:  number C1  = n_Copy(p_GetCoeff(M1,r),r); */
+//   /* RAT: */
+
+//   poly C1  = p_GetCoeffRat(M1,ishift,r);
+
+//   poly H2  = p_HeadRat(p2,is,r);
+//   poly M2  = r->nc->p_Procs.mm_Mult_p(m2,p_Copy(H2,r),r);
+
+//   /* POLY:  number C2  = n_Copy(p_GetCoeff(M2,r),r); */
+//   /* RAT: */
+
+//   poly C2  = p_GetCoeffRat(M2,ishift,r);
+
+// /* we do not assume that X's commute */
+// /* we just run NC syzygies */
+
+// /* NEW IDEA: change the ring to K<X>, map things there
+//    and return the result back; seems to be a good optimization */
+// /* to be done later */
+// /* problem: map to subalgebra. contexts, induced (non-unique) orderings etc. */
+
+//   intvec *w = NULL;
+//   ideal h = idInit(2,1);
+//   h->m[0] = p_Copy(C1,r);
+//   h->m[1] = p_Copy(C2,r);
+// #ifdef PDEBUG
+//   Print("running syzygy comp. for coeffs");
+// #endif
+//   ideal sh = idSyzygies(h, testHomog, &w);
+//   /* in comm case, there is only 1 syzygy */
+//   /*   singclap_gcd(); */
+//   poly K,K1,K2;
+//   K  = sh->m[0];
+//   K1 = pTakeOutComp(&K, 1); // 1st component is taken out from K
+//   pShift(&K,-2); // 2nd component to 0th comp.
+//   K2 = K;
+
+//   /* checking signs before multiplying */
+//   number ck1 = p_GetCoeff(K1,r);
+//   number ck2 = p_GetCoeff(K2,r);
+//   BOOLEAN bck1, bck2;
+//   bck1 = n_GreaterZero(ck1,r);
+//   bck2 = n_GreaterZero(ck2,r);
+//   /* K1 >0, K2 >0 (K1,-K2)    */
+//   /* K1 >0, K2 <0 (K1,-K2)    */
+//   /* K1 <0, K2 >0 (-K1,K2)    */
+//   /* K1 <0, K2 <0 (-K1,K2)    */
+//   if ( (bck1) && (bck2) ) /* +, + */
+//   {
+//     K2 = p_Neg(K2,r);
+//   }
+//   if ( (bck1) && (!bck2) ) /* + , - */
+//   {
+//     K2 = p_Neg(K2,r);
+//   }
+//   if ( (!bck1) && (bck2) ) /* - , + */
+//   {
+//     K1 = p_Neg(K1,r);
+//   }
+//   if ( !(bck1 && bck2) ) /* - , - */
+//   {
+//     K1 = p_Neg(K1,r);
+//   }
+
+//   poly P1,P2;
+
+//   //  p_LmDeleteRat(M1,ishift,r); // get tail(D^(gamma-alpha) * lm(p1)) = h_f
+//   P1 = p_Copy(p1,r);
+//   p_LmDeleteAndNextRat(P1,ishift,r); // get tail(p1) = t_f
+//   P1 = r->nc->p_Procs.mm_Mult_p(m1,P1,r);
+//   P1 = p_Add_q(P1,M1,r);
+
+//   //  p_LmDeleteRat(M2,ishift,r);
+//   P2 = p_Copy(p2,r);
+//   p_LmDeleteAndNextRat(P2,ishift,r);// get tail(p2)=t_g
+//   P2 = r->nc->p_Procs.mm_Mult_p(m2,P2,r);
+//   P2 = p_Add_q(P2,M2,r);
+
+//   /* coeff business */
+
+//   P1 = p_Mult_q(P1,K1,r);
+//   P2 = p_Mult_q(P2,K2,r);
+//   P1 = p_Add_q(P1,P2,r);
+
+//   /* cleaning up */
+
+// #ifdef PDEBUG
+//   p_Test(p1,r);
+// #endif
+//   /* questionable: */
+//   if (P1!=NULL) pCleardenom(P1);
+//   if (P1!=NULL) pContent(P1);
+//   return(P1);
+// }
+
+#undef CC
+
+/*4 - follow the numbering of gring.cc
+* creates the S-polynomial of p1 and p2
+* do not destroy p1 and p2
+*/
+poly nc_rat_CreateSpoly(poly pp1, poly pp2, int ishift, const ring r)
+{
+
+  poly p1 = p_Copy(pp1,r);
+  poly p2 = p_Copy(pp2,r);
+
+  const long lCompP1 = p_GetComp(p1,r);
+  const long lCompP2 = p_GetComp(p2,r);
+
+  if ((lCompP1!=lCompP2) && (lCompP1!=0) && (lCompP2!=0))
+  {
+#ifdef PDEBUG
+    Werror("nc_rat_CreateSpoly: different non-zero components!");
+#endif
+    return(NULL);
+  }
+
+  if ( (p_LmIsConstantRat(p1,r)) || (p_LmIsConstantRat(p2,r)) )
+  {
+    p_Delete(&p1,r);
+    p_Delete(&p2,r);
+    return( NULL );
+  }
+
+
+/* note: prod. crit does not apply! */
+  poly pL=pOne();
+  poly m1=pOne();
+  poly m2=pOne();
+  int is = ishift; /* TODO */
+  pLcmRat(p1,p2,pL,is);
+  p_Setm(pL,r);
+#ifdef PDEBUG
+  p_Test(pL,r);
+#endif
+  poly pr1 = p_GetExp_k_n(p1,1,ishift,r); /* rat D-exp of p1 */
+  poly pr2 = p_GetExp_k_n(p2,1,ishift,r); /* rat D-exp of p2 */
+  p_ExpVectorDiff(m1,pL,pr1,r); /* purely in D part by construction */
+  p_ExpVectorDiff(m2,pL,pr2,r); /* purely in D part by construction */
+  p_Delete(&pr1,r);
+  p_Delete(&pr2,r);
+  p_Delete(&pL,r);
+#ifdef PDEBUG
+  p_Test(m1,r);
+  PrintS("d^{gamma-alpha} = "); p_wrp(m1,r); PrintLn();
+  p_Test(m2,r);
+  PrintS("d^{gamma-beta} = "); p_wrp(m2,r); PrintLn();
+#endif
+
+  poly HF = NULL;
+  HF = p_HeadRat(p1,is,r); // lm_D(f)
+  HF  = nc_mm_Mult_p(m1, HF, r); // // d^{gamma-alpha} lm_D(f)
+  poly C  = p_GetCoeffRat(HF,  is, r); // c = lc_D(h_f) in the paper
+
+  poly HG = NULL;
+  HG = p_HeadRat(p2,is,r); // lm_D(g)
+  HG  = nc_mm_Mult_p(m2, HG, r); // // d^{gamma-beta} lm_D(g)
+  poly K  = p_GetCoeffRat(HG,  is, r); // k = lc_D(h_g) in the paper
+
+#ifdef PDEBUG
+  PrintS("f: "); p_wrp(p1,r); PrintS("\n");
+  PrintS("c: "); p_wrp(C,r); PrintS("\n");
+  PrintS("g: "); p_wrp(p2,r); PrintS("\n");
+  PrintS("k: "); p_wrp(K,r); PrintS("\n");
+#endif
+
+  ideal ncsyz = ncGCD(C,K,r);
+  poly KK = ncsyz->m[0]; ncsyz->m[0]=NULL; //p_Copy(ncsyz->m[0],r); // k'
+  poly CC = ncsyz->m[1]; ncsyz->m[1]= NULL; //p_Copy(ncsyz->m[1],r); // c'
+  id_Delete(&ncsyz,r);
+
+  p_LmDeleteAndNextRat(&p1, is, r); // t_f
+  p_LmDeleteAndNextRat(&HF, is, r); // r_f = h_f - lt_D(h_f)
+
+  p_LmDeleteAndNextRat(&p2, is, r); // t_g
+  p_LmDeleteAndNextRat(&HG, is, r); // r_g = h_g - lt_D(h_g)
+
+
+#ifdef PDEBUG
+  PrintS(" t_f: "); p_wrp(p1,r); PrintS("\n");
+  PrintS(" t_g: "); p_wrp(p2,r); PrintS("\n");
+  PrintS(" r_f: "); p_wrp(HF,r); PrintS("\n");
+  PrintS(" r_g: "); p_wrp(HG,r); PrintS("\n");
+  PrintS(" c': "); p_wrp(CC,r); PrintS("\n");
+  PrintS(" k': "); p_wrp(KK,r); PrintS("\n");
+
+#endif
+
+  // k'(r_f + d^{gamma-alpha} t_f)
+
+  p1 = p_Mult_q(m1, p1, r); // p1 = d^{gamma-alpha} t_f
+  p1 = p_Add_q(p1,HF,r); // p1 = r_f + d^{gamma-alpha} t_f
+  p1 = p_Mult_q(KK,p1,r); // p1 = k'(r_f + d^{gamma-alpha} t_f)
+
+  // c'(r_f + d^{gamma-beta} t_g)
+
+  p2 = p_Mult_q(m2, p2, r); // p2 = d^{gamma-beta} t_g
+  p2 = p_Add_q(p2,HG,r); // p2 = r_g + d^{gamma-beta} t_g
+  p2 = p_Mult_q(CC,p2,r); // p2 = c'(r_g + d^{gamma-beta} t_g)
+
+#ifdef PDEBUG
+  p_Test(p1,r);
+  p_Test(p2,r);
+  PrintS(" k'(r_f + d^{gamma-alpha} t_f): "); p_wrp(p1,r);
+  PrintS(" c'(r_g + d^{gamma-beta} t_g): "); p_wrp(p2,r);
+#endif
+
+  poly out = p_Add_q(p1,p2,r); // delete p1, p2; // the sum
+
+#ifdef PDEBUG
+  p_Test(out,r);
+#endif
+
+  //  if ( out!=NULL ) pContent(out); // postponed to enterS
+  return(out);
+}
+
+
+/*2
+* reduction of p2 with p1
+* do not destroy p1, but p2
+* p1 divides p2 -> for use in NF algorithm
+* works in an integer fashion
+*/
+
+poly nc_rat_ReduceSpolyNew(const poly p1, poly p2, int ishift, const ring r)
+{
+  const long lCompP1 = p_GetComp(p1,r);
+  const long lCompP2 = p_GetComp(p2,r);
+
+  if ((lCompP1!=lCompP2) && (lCompP1!=0) && (lCompP2!=0))
+  {
+#ifdef PDEBUG
+    Werror("nc_rat_ReduceSpolyNew: different non-zero components!");
+#endif
+    return(NULL);
+  }
+
+  if (p_LmIsConstantRat(p1,r))
+  {
+    return( NULL );
+  }
+
+
+  int is = ishift; /* TODO */
+
+  poly m = pOne();
+  p_ExpVectorDiffRat(m, p2, p1, ishift, r); // includes X and D parts
+  //p_Setm(m,r);
+  //  m = p_GetExp_k_n(m,1,ishift,r); /* rat D-exp of m */
+#ifdef PDEBUG
+  p_Test(m,r);
+  PrintS("d^alpha = "); p_wrp(m,r); PrintLn();
+#endif
+
+  /* pSetComp(m,r)=0? */
+  poly HH = NULL;
+  poly H  = NULL;
+  HH = p_HeadRat(p1,is,r); //p_Copy(p_HeadRat(p1,is,r),r); // lm_D(g)
+//  H  = r->nc->p_Procs.mm_Mult_p(m, p_Copy(HH, r), r); // d^aplha lm_D(g)
+  H  = nc_mm_Mult_p(m, HH, r); // d^aplha lm_D(g) == h_g in the paper
+
+  poly K  = p_GetCoeffRat(H,  is, r); //p_Copy( p_GetCoeffRat(H,  is, r), r); // k in the paper
+  poly P  = p_GetCoeffRat(p2, is, r); //p_Copy( p_GetCoeffRat(p2, is, r), r); // lc_D(p_2) == lc_D(f)
+
+#ifdef PDEBUG
+  PrintS("k: "); p_wrp(K,r); PrintS("\n");
+  PrintS("p: "); p_wrp(P,r); PrintS("\n");
+  PrintS("f: "); p_wrp(p2,r); PrintS("\n");
+  PrintS("g: "); p_wrp(p1,r); PrintS("\n");
+#endif
+  // alt:
+  poly out = p_Copy(p1,r);
+  p_LmDeleteAndNextRat(&out, is, r); // out == t_g
+
+  ideal ncsyz = ncGCD(P,K,r);
+  poly KK = ncsyz->m[0]; ncsyz->m[0]=NULL; //p_Copy(ncsyz->m[0],r); // k'
+  poly PP = ncsyz->m[1]; ncsyz->m[1]= NULL; //p_Copy(ncsyz->m[1],r); // p'
+
+#ifdef PDEBUG
+  PrintS("t_g: "); p_wrp(out,r);
+  PrintS("k': "); p_wrp(KK,r); PrintS("\n");
+  PrintS("p': "); p_wrp(PP,r); PrintS("\n");
+#endif
+  id_Delete(&ncsyz,r);
+  p_LmDeleteAndNextRat(&p2, is, r); // t_f
+  p_LmDeleteAndNextRat(&H, is, r); // r_g = h_g - lt_D(h_g)
+
+#ifdef PDEBUG
+  PrintS(" t_f: "); p_wrp(p2,r);
+  PrintS(" r_g: "); p_wrp(H,r);
+#endif
+
+  p2 = p_Mult_q(KK, p2, r); // p2 = k' t_f
+
+#ifdef PDEBUG
+  p_Test(p2,r);
+  PrintS(" k' t_f: "); p_wrp(p2,r);
+#endif
+
+//  out = r->nc->p_Procs.mm_Mult_p(m, out, r); // d^aplha t_g
+  out = nc_mm_Mult_p(m, out, r); // d^aplha t_g
+  p_Delete(&m,r);
+
+#ifdef PDEBUG
+  PrintS(" d^a t_g: "); p_wrp(out,r);
+  PrintS(" end reduction\n");
+#endif
+
+  out = p_Add_q(H, out, r); // r_g + d^a t_g
+
+#ifdef PDEBUG
+  p_Test(out,r);
+#endif
+  out = p_Mult_q(PP, out, r); // p' (r_g + d^a t_g)
+  out = p_Add_q(p2,out,r); // delete out, p2; // the sum
+
+#ifdef PDEBUG
+  p_Test(out,r);
+#endif
+
+  //  if ( out!=NULL ) pContent(out); // postponed to enterS
+  return(out);
+}
+
+// return: FALSE, if there exists i in ishift..r->N,
+//                 such that a->exp[i] > b->exp[i]
+//         TRUE, otherwise
+
+BOOLEAN p_DivisibleByRat(poly a, poly b, int ishift, const ring r)
+{
+#ifdef PDEBUG
+  PrintS("invoke p_DivByRat with a = ");
+  p_wrp(p_Head(a,r),r);
+  PrintS(" and b= ");
+  p_wrp(p_Head(b,r),r);
+  PrintLn();
+#endif
+  int i;
+  for(i=r->N; i>ishift; i--)
+  {
+#ifdef PDEBUG
+    Print("i=%d,",i);
+#endif
+    if (p_GetExp(a,i,r) > p_GetExp(b,i,r)) return FALSE;
+  }
+  return ((p_GetComp(a,r)==p_GetComp(b,r)) || (p_GetComp(a,r)==0));
+}
+/*2
+*reduces h with elements from reducer choosing the best possible
+* element in t with respect to the given red_length
+* arrays reducer and red_length are [0..(rl-1)]
+*/
+int redRat (poly* h, poly *reducer, int *red_length, int rl, int ishift, ring r)
+{
+  if ((*h)==NULL) return 0;
+
+  int j,i,l;
+
+  loop
+  {
+    j=rl;l=MAX_INT_VAL;
+    for(i=rl-1;i>=0;i--)
+    {
+      //      Print("test %d, l=%d (curr=%d, l=%d\n",i,red_length[i],j,l);
+      if ((l>red_length[i]) && (p_DivisibleByRat(reducer[i],*h,ishift,r)))
+      {
+        j=i; l=red_length[i];
+        //        PrintS(" yes\n");
+      }
+      //      else PrintS(" no\n");
+    }
+    if (j >=rl)
+    {
+      return 1; // not reducible
+    }
+
+    if (TEST_OPT_DEBUG)
+    {
+      PrintS("reduce ");
+      p_wrp(*h,r);
+      PrintS(" with ");
+      p_wrp(reducer[j],r);
+    }
+    poly hh=nc_rat_ReduceSpolyNew(reducer[j], *h, ishift, r);
+    //    p_Delete(h,r);
+    *h=hh;
+    if (TEST_OPT_DEBUG)
+    {
+      PrintS(" to ");
+      p_wrp(*h,r);
+      PrintLn();
+    }
+    if ((*h)==NULL)
+    {
+      return 0;
+    }
+  }
+}
+
+// test if monomial is a constant, i.e. if all exponents and the component
+// is zero
+BOOLEAN p_LmIsConstantRat(const poly p, const ring r)
+{
+  if (p_LmIsConstantCompRat(p, r))
+    return (p_GetComp(p, r) == 0);
+  return FALSE;
+}
+
+// test if the monomial is a constant as a vector component
+// i.e., test if all exponents are zero
+BOOLEAN p_LmIsConstantCompRat(const poly p, const ring r)
+{
+  int i = r->real_var_end;
+
+  while ( (p_GetExp(p,i,r)==0) && (i>=r->real_var_start))
+  {
+    i--;
+  }
+  return ( i+1 == r->real_var_start );
+}
+
+#endif
diff --git a/kernel/GBEngine/ratgring.h b/kernel/GBEngine/ratgring.h
new file mode 100644
index 0000000..7d76bfe
--- /dev/null
+++ b/kernel/GBEngine/ratgring.h
@@ -0,0 +1,117 @@
+#ifndef RATGRING_H
+#define RATGRING_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT additional defines etc for --with-plural
+*/
+// #define HAVE_RATGRING to activate
+
+#ifdef HAVE_RATGRING
+#include <kernel/structs.h>
+#include <polys/nc/nc.h>
+#include <polys/monomials/p_polys.h>
+
+/* MACROS */
+
+/* the part, related to the interface */
+
+/* ring nc_rCreateNCcomm(ring r); */
+
+void pLcmRat(poly a, poly b, poly m, int rat_shift);
+
+poly p_HeadRat(poly p, int ishift, ring r);
+
+void p_ExpVectorDiffRat(poly pr, poly p1, poly p2, int ishift, ring r);
+
+ideal ncGCD2(poly p, poly q, ring r); // real nc stuff
+
+ideal ncGCD(poly p, poly q, ring r); // for p,q from a commutative ring
+
+poly nc_rat_CreateSpoly(poly p1, poly p2, int ishift, ring r);
+
+poly nc_rat_ReduceSpolyNew(poly p1, poly p2, int ishift, ring r);
+
+
+/* poly functions defined in p_Procs : */
+// poly nc_pp_Mult_mm(poly p, poly m, const ring r, poly &last);
+// poly nc_p_Mult_mm(poly p, const poly m, const ring r);
+// poly nc_p_Minus_mm_Mult_qq(poly p, const poly m, poly q, const ring r);
+// poly nc_p_Minus_mm_Mult_qq_ign(poly p, const poly m, poly q, int & d1, poly d2, const ring ri, poly &d3);
+
+/* other routines we need in addition : */
+// poly nc_p_Mult_mm_Common(poly p, const poly m, int side, const ring r);
+// poly nc_mm_Mult_p(const poly m, poly p, const ring r);
+// poly nc_mm_Mult_nn (int *F, int *G, const ring r);
+// poly nc_mm_Mult_uu (int *F,int jG,int bG, const ring r);
+
+// /* subst: */
+// poly nc_pSubst(poly p, int n, poly e);
+
+// /* copy : */
+// poly nc_p_CopyGet(poly a, const ring r);
+// poly nc_p_CopyPut(poly a, const ring r);
+
+// /* syzygies : */
+// /* former nc_spGSpolyCreate */
+// poly nc_CreateSpoly(poly p1, poly p2, poly spNoether, const ring r);
+// /* former nc_spGSpolyRed */
+// poly nc_ReduceSpoly(poly p1, poly p2, poly spNoether, const ring r);
+// /* former nc_spGSpolyRedNew */
+// poly nc_ReduceSpolyNew(poly p1, poly p2, poly spNoether, const ring r);
+// /* former nc_spGSpolyRedTail */
+// void nc_ReduceSpolyTail(poly p1, poly q, poly q2, poly spNoether, const ring r);
+// /* former nc_spShort */
+// poly nc_CreateShortSpoly(poly p1, poly p2, const ring r=currRing);
+
+// ideal gr_bba (ideal F, ideal Q,kStrategy strat);
+
+// /* brackets: */
+// poly nc_p_Bracket_qq(poly p, poly q);
+// poly nc_mm_Bracket_nn(poly m1, poly m2);
+
+// /* twostd: */
+// ideal twostd(ideal I);
+// /* Ann: */
+// ideal Approx_Step(ideal L);
+
+// /* complete reduction routines */
+
+// /* void nc_kBucketPolyRed(kBucket_pt b, poly p); */
+// void nc_kBucketPolyRed(kBucket_pt b, poly p, number *c);
+// void nc_kBucketPolyRed_Z(kBucket_pt b, poly p, number *c);
+// void nc_PolyPolyRed(poly &b, poly p, number *c);
+
+// matrix nc_PrintMat(int a, int b, ring r, int metric);
+
+// poly p_CopyEmbed(poly p, ring srcRing, int shift, int par_shift);
+// poly pOppose(ring Rop, poly p);
+// ideal idOppose(ring Rop, ideal I);
+
+// #else
+// /* dummy definition to make gcc happy */
+// #define nc_kBucketPolyRed(A,B,C) 0
+// #define nc_PolyPolyRed(A,B,C) 0
+
+// return: FALSE, if there exists i in ishift..r->N,
+//                 such that a->exp[i] > b->exp[i]
+//         TRUE, otherwise
+BOOLEAN p_DivisibleByRat(poly a, poly b, int ishift, const ring r);
+
+/*2
+*reduces h with elements from reducer choosing the best possible
+* element in t with respect to the given red_length
+* arrays reducer and red_length are [0..(rl-1)]
+*/
+int redRat (poly* h,poly *reducer, int *red_length,int rl, int ishift, ring r);
+
+// Content stuff
+static inline void pContentRat(poly &ph, const ring r = currRing){ p_ContentRat(ph, r); } ;
+
+BOOLEAN p_LmIsConstantRat(const poly p, const ring r);
+
+BOOLEAN p_LmIsConstantCompRat(const poly p, const ring r);
+
+#endif /* HAVE_PLURAL */
+#endif
diff --git a/kernel/GBEngine/ringgb.cc b/kernel/GBEngine/ringgb.cc
new file mode 100644
index 0000000..98691c5
--- /dev/null
+++ b/kernel/GBEngine/ringgb.cc
@@ -0,0 +1,304 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: ringgb interface
+*/
+//#define HAVE_TAIL_RING
+#define NO_BUCKETS
+
+
+
+
+#include <kernel/mod2.h>
+#include <kernel/GBEngine/kutil.h>
+#include <kernel/structs.h>
+#include <omalloc/omalloc.h>
+#include <kernel/polys.h>
+#include <polys/monomials/p_polys.h>
+#include <kernel/ideals.h>
+#include <kernel/GBEngine/kstd1.h>
+#include <kernel/GBEngine/khstd.h>
+#include <polys/kbuckets.h>
+#include <polys/weight.h>
+#include <misc/intvec.h>
+#include <kernel/polys.h>
+#ifdef HAVE_PLURAL
+#include <polys/nc/nc.h>
+#endif
+
+#include <kernel/GBEngine/ringgb.h>
+
+#ifdef HAVE_RINGS
+poly reduce_poly_fct(poly p, ring r)
+{
+   return kFindZeroPoly(p, r, r);
+}
+
+/*
+ * Returns maximal k, such that
+ * 2^k | n
+ */
+int indexOf2(number n)
+{
+  long test = (long) n;
+  int i = 0;
+  while (test%2 == 0)
+  {
+    i++;
+    test = test / 2;
+  }
+  return i;
+}
+
+/***************************************************************
+ *
+ * Lcm business
+ *
+ ***************************************************************/
+// get m1 = LCM(LM(p1), LM(p2))/LM(p1)
+//     m2 = LCM(LM(p1), LM(p2))/LM(p2)
+BOOLEAN ring2toM_GetLeadTerms(const poly p1, const poly p2, const ring p_r,
+                               poly &m1, poly &m2, const ring m_r)
+{
+  int i;
+  int x;
+  m1 = p_Init(m_r);
+  m2 = p_Init(m_r);
+
+  for (i = p_r->N; i; i--)
+  {
+    x = p_GetExpDiff(p1, p2, i, p_r);
+    if (x > 0)
+    {
+      p_SetExp(m2,i,x, m_r);
+      p_SetExp(m1,i,0, m_r);
+    }
+    else
+    {
+      p_SetExp(m1,i,-x, m_r);
+      p_SetExp(m2,i,0, m_r);
+    }
+  }
+  p_Setm(m1, m_r);
+  p_Setm(m2, m_r);
+  long cp1 = (long) pGetCoeff(p1);
+  long cp2 = (long) pGetCoeff(p2);
+  if (cp1 != 0 && cp2 != 0)
+  {
+    while (cp1%2 == 0 && cp2%2 == 0)
+    {
+      cp1 = cp1 / 2;
+      cp2 = cp2 / 2;
+    }
+  }
+  p_SetCoeff(m1, (number) cp2, m_r);
+  p_SetCoeff(m2, (number) cp1, m_r);
+  return TRUE;
+}
+
+void printPolyMsg(const char * start, poly f, const char * end)
+{
+  PrintS(start);
+  wrp(f);
+  PrintS(end);
+}
+
+poly spolyRing2toM(poly f, poly g, ring r)
+{
+  poly m1 = NULL;
+  poly m2 = NULL;
+  ring2toM_GetLeadTerms(f, g, r, m1, m2, r);
+  // printPolyMsg("spoly: m1=", m1, " | ");
+  // printPolyMsg("m2=", m2, "");
+  // PrintLn();
+  poly sp = pSub(p_Mult_mm(f, m1, r), pp_Mult_mm(g, m2, r));
+  pDelete(&m1);
+  pDelete(&m2);
+  return(sp);
+}
+
+poly ringRedNF (poly f, ideal G, ring r)
+{
+  // If f = 0, then normal form is also 0
+  if (f == NULL) { return NULL; }
+  poly h = NULL;
+  poly g = pCopy(f);
+  int c = 0;
+  while (g != NULL)
+  {
+    Print("%d-step RedNF - g=", c);
+    wrp(g);
+    PrintS(" | h=");
+    wrp(h);
+    PrintLn();
+    g = ringNF(g, G, r);
+    if (g != NULL) {
+      h = pAdd(h, pHead(g));
+      pLmDelete(&g);
+    }
+    c++;
+  }
+  return h;
+}
+
+#endif
+
+#ifdef HAVE_RINGS
+
+/*
+ * Find an index i from G, such that
+ * LT(rside) = x * LT(G[i]) has a solution
+ * or -1 if rside is not in the
+ * ideal of the leading coefficients
+ * of the suitable g from G.
+ */
+int findRingSolver(poly rside, ideal G, ring r)
+{
+  if (rside == NULL) return -1;
+  int i;
+//  int iO2rside = indexOf2(pGetCoeff(rside));
+  for (i = 0; i < IDELEMS(G); i++)
+  {
+    if // (indexOf2(pGetCoeff(G->m[i])) <= iO2rside &&    / should not be necessary any more
+       (p_LmDivisibleBy(G->m[i], rside, r))
+    {
+      return i;
+    }
+  }
+  return -1;
+}
+
+poly plain_spoly(poly f, poly g)
+{
+  number cf = nCopy(pGetCoeff(f)), cg = nCopy(pGetCoeff(g));
+  (void)ksCheckCoeff(&cf, &cg, currRing->cf); // gcd and zero divisors
+  poly fm, gm;
+  k_GetLeadTerms(f, g, currRing, fm, gm, currRing);
+  pSetCoeff0(fm, cg);
+  pSetCoeff0(gm, cf);  // and now, m1 * LT(p1) == m2 * LT(p2)
+  poly sp = pSub(ppMult_mm(f, fm), ppMult_mm(g, gm));
+  pDelete(&fm);
+  pDelete(&gm);
+  return(sp);
+}
+
+/*2
+* Generates spoly(0, h) if applicable. Assumes ring in Z/2^n.
+*/
+poly plain_zero_spoly(poly h)
+{
+  poly p = NULL;
+  number gcd = n_Gcd((number) 0, pGetCoeff(h), currRing->cf);
+  if (!n_IsOne( gcd,  currRing->cf ))
+  {
+    number tmp=n_Ann(gcd,currRing->cf);
+    p = p_Copy(h->next, currRing);
+    p = p_Mult_nn(p, tmp, currRing);
+    n_Delete(&tmp,currRing->cf);
+  }
+  return p;
+}
+
+poly ringNF(poly f, ideal G, ring r)
+{
+  // If f = 0, then normal form is also 0
+  if (f == NULL) { return NULL; }
+  poly tmp = NULL;
+  poly h = pCopy(f);
+  int i = findRingSolver(h, G, r);
+  int c = 1;
+  while (h != NULL && i >= 0) {
+//    Print("%d-step NF - h:", c);
+//    wrp(h);
+//    PrintS(" ");
+//    PrintS("G->m[i]:");
+//    wrp(G->m[i]);
+//    PrintLn();
+    tmp = h;
+    h = plain_spoly(h, G->m[i]);
+    pDelete(&tmp);
+//    PrintS("=> h=");
+//    wrp(h);
+//    PrintLn();
+    i = findRingSolver(h, G, r);
+    c++;
+  }
+  return h;
+}
+
+int testGB(ideal I, ideal GI) {
+  poly f, g, h, nf;
+  int i = 0;
+  int j = 0;
+  PrintS("I included?");
+  for (i = 0; i < IDELEMS(I); i++) {
+    if (ringNF(I->m[i], GI, currRing) != NULL) {
+      PrintS("Not reduced to zero from I: ");
+      wrp(I->m[i]);
+      PrintS(" --> ");
+      wrp(ringNF(I->m[i], GI, currRing));
+      PrintLn();
+      return(0);
+    }
+    PrintS("-");
+  }
+  PrintS(" Yes!\nspoly --> 0?");
+  for (i = 0; i < IDELEMS(GI); i++)
+  {
+    for (j = i + 1; j < IDELEMS(GI); j++)
+    {
+      f = pCopy(GI->m[i]);
+      g = pCopy(GI->m[j]);
+      h = plain_spoly(f, g);
+      nf = ringNF(h, GI, currRing);
+      if (nf != NULL)
+      {
+        PrintS("spoly(");
+        wrp(GI->m[i]);
+        PrintS(", ");
+        wrp(GI->m[j]);
+        PrintS(") = ");
+        wrp(h);
+        PrintS(" --> ");
+        wrp(nf);
+        PrintLn();
+        return(0);
+      }
+      pDelete(&f);
+      pDelete(&g);
+      pDelete(&h);
+      pDelete(&nf);
+      PrintS("-");
+    }
+  }
+  if (!(rField_is_Domain(currRing)))
+  {
+    PrintS(" Yes!\nzero-spoly --> 0?");
+    for (i = 0; i < IDELEMS(GI); i++)
+    {
+      f = plain_zero_spoly(GI->m[i]);
+      nf = ringNF(f, GI, currRing);
+      if (nf != NULL) {
+        PrintS("spoly(");
+        wrp(GI->m[i]);
+        PrintS(", ");
+        wrp(0);
+        PrintS(") = ");
+        wrp(h);
+        PrintS(" --> ");
+        wrp(nf);
+        PrintLn();
+        return(0);
+      }
+      pDelete(&f);
+      pDelete(&nf);
+      PrintS("-");
+    }
+  }
+  PrintS(" Yes!");
+  PrintLn();
+  return(1);
+}
+
+#endif
diff --git a/kernel/GBEngine/ringgb.h b/kernel/GBEngine/ringgb.h
new file mode 100644
index 0000000..5617f4b
--- /dev/null
+++ b/kernel/GBEngine/ringgb.h
@@ -0,0 +1,22 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: ringgb interface
+*/
+#ifndef RINGGB_HEADER
+#define RINGGB_HEADER
+// #include <kernel/mod2.h>
+
+#ifdef HAVE_RINGS
+#include <kernel/polys.h>
+
+poly ringNF(poly f, ideal G, ring r);
+poly plain_spoly(poly f, poly g);
+int testGB(ideal I, ideal GI);
+
+poly reduce_poly_fct(poly p, ring r);
+poly ringRedNF(poly f, ideal G, ring r);
+
+#endif
+#endif
diff --git a/kernel/GBEngine/sca.cc b/kernel/GBEngine/sca.cc
new file mode 100644
index 0000000..431a249
--- /dev/null
+++ b/kernel/GBEngine/sca.cc
@@ -0,0 +1,1237 @@
+#define PLURAL_INTERNAL_DECLARATIONS
+
+
+
+
+#include <kernel/mod2.h>
+#include <misc/auxiliary.h>
+
+#include <misc/options.h>
+
+#include <polys/simpleideals.h>
+#include <polys/prCopy.h>
+
+#include <polys/nc/sca.h>
+#include <polys/nc/gb_hack.h>
+
+#include <kernel/polys.h>
+#include <kernel/ideals.h>
+#include <kernel/GBEngine/kstd1.h>
+#include <kernel/GBEngine/kutil.h>
+
+#include <kernel/GBEngine/nc.h>
+
+/// nc_gr_initBba is needed for sca_gr_bba and gr_bba.
+void nc_gr_initBba(ideal F, kStrategy strat); // from gr_kstd2.cc!
+
+void addLObject(LObject& h, kStrategy& strat)
+{
+  if(h.IsNull()) return;
+
+  strat->initEcart(&h);
+  h.sev=0; // pGetShortExpVector(h.p);
+
+  // add h into S and L
+  int pos=posInS(strat, strat->sl, h.p, h.ecart);
+
+  if ( (pos <= strat->sl) && (p_ComparePolys(h.p, strat->S[pos], currRing)) )
+  {
+    if (TEST_OPT_PROT)
+      PrintS("d\n");
+  }
+  else
+  {
+    if (TEST_OPT_INTSTRATEGY)
+    {
+      p_Cleardenom(h.p, currRing);
+    }
+    else
+    {
+      pNorm(h.p);
+      p_Content(h.p,currRing);
+    }
+
+    if ((strat->syzComp==0)||(!strat->homog))
+    {
+      h.p = redtailBba(h.p,pos-1,strat);
+
+      if (TEST_OPT_INTSTRATEGY)
+      {
+//        pCleardenom(h.p);
+        p_Content(h.p,currRing);
+      }
+      else
+      {
+        pNorm(h.p);
+      }
+    }
+
+    if(h.IsNull()) return;
+
+    // statistic
+    if (TEST_OPT_PROT)
+    {
+      PrintS("s\n");
+    }
+
+#ifdef KDEBUG
+    if (TEST_OPT_DEBUG)
+    {
+      PrintS("new s:");
+      wrp(h.p);
+      PrintLn();
+    }
+#endif
+
+    enterpairs(h.p, strat->sl, h.ecart, 0, strat);
+
+    pos=0;
+
+    if (strat->sl!=-1) pos = posInS(strat, strat->sl, h.p, h.ecart);
+    strat->enterS(h, pos, strat, -1);
+//    enterT(h, strat); // ?!
+
+    if (h.lcm!=NULL) pLmFree(h.lcm);
+  }
+
+
+}
+
+
+ideal sca_gr_bba(const ideal F, const ideal Q, const intvec *, const intvec *, kStrategy strat, const ring _currRing)
+{
+  const ring save = currRing;
+  if( currRing != _currRing ) rChangeCurrRing(_currRing);
+  assume( currRing == _currRing );
+
+
+#if MYTEST
+   PrintS("<sca_gr_bba>\n");
+#endif
+
+  assume(rIsSCA(currRing));
+
+#ifndef SING_NDEBUG
+  idTest(F);
+  idTest(Q);
+#endif
+
+#ifdef HAVE_PLURAL
+#if MYTEST
+  PrintS("currRing: \n");
+  rWrite(currRing);
+#ifdef RDEBUG
+  rDebugPrint(currRing);
+#endif
+
+  PrintS("F: \n");
+  idPrint(F);
+  PrintS("Q: \n");
+  idPrint(Q);
+#endif
+#endif
+
+
+  const unsigned int m_iFirstAltVar = scaFirstAltVar(currRing);
+  const unsigned int m_iLastAltVar  = scaLastAltVar(currRing);
+
+  ideal tempF = id_KillSquares(F, m_iFirstAltVar, m_iLastAltVar, currRing);
+  ideal tempQ = Q;
+
+  if(Q == currRing->qideal)
+    tempQ = SCAQuotient(currRing);
+
+  strat->z2homog = id_IsSCAHomogeneous(tempF, NULL, NULL, currRing); // wCx == wCy == NULL!
+  // redo: no_prod_crit
+  const BOOLEAN bIsSCA  = rIsSCA(currRing) && strat->z2homog; // for Z_2 prod-crit
+  strat->no_prod_crit   = ! bIsSCA;
+
+//  strat->homog = strat->homog && strat->z2homog; // ?
+
+#if MYTEST
+  {
+    PrintS("ideal tempF: \n");
+    idPrint(tempF);
+    PrintS("ideal tempQ: \n");
+    idPrint(tempQ);
+  }
+#endif
+
+  int olddeg, reduc;
+  int red_result = 1;
+//  int hilbeledeg = 1, minimcnt = 0;
+  int hilbcount = 0;
+
+  initBuchMoraCrit(strat); // set Gebauer, honey, sugarCrit
+
+  nc_gr_initBba(tempF,strat); // set enterS, red, initEcart, initEcartPair
+
+  initBuchMoraPos(strat);
+
+
+  // ?? set spSpolyShort, reduce ???
+
+  initBuchMora(tempF, tempQ, strat); // SCAQuotient(currRing) instead of Q == squares!!!!!!!
+
+  strat->posInT=posInT110; // !!!
+
+  reduc = olddeg = 0;
+
+
+  // compute-------------------------------------------------------
+  for(; strat->Ll >= 0;
+#ifdef KDEBUG
+    strat->P.lcm = NULL,
+#endif
+    kTest(strat)
+    )
+  {
+#ifdef KDEBUG
+    if (TEST_OPT_DEBUG) messageSets(strat);
+#endif
+
+    if (strat->Ll== 0) strat->interpt=TRUE;
+
+    if (TEST_OPT_DEGBOUND
+    && ((strat->honey
+    && (strat->L[strat->Ll].ecart+ currRing->pFDeg(strat->L[strat->Ll].p,currRing)>Kstd1_deg))
+       || ((!strat->honey) && (currRing->pFDeg(strat->L[strat->Ll].p,currRing)>Kstd1_deg))))
+    {
+      // stops computation if
+      // 24 IN test and the degree +ecart of L[strat->Ll] is bigger then
+      // a predefined number Kstd1_deg
+      while (strat->Ll >= 0) deleteInL(strat->L,&strat->Ll,strat->Ll,strat);
+      break;
+    }
+
+    // picks the last element from the lazyset L
+    strat->P = strat->L[strat->Ll];
+    strat->Ll--;
+
+    //kTest(strat);
+
+//    assume(pNext(strat->P.p) != strat->tail); // !???
+    if(strat->P.IsNull()) continue;
+
+
+    if( pNext(strat->P.p) == strat->tail )
+    {
+      // deletes the int spoly and computes SPoly
+      pLmFree(strat->P.p); // ???
+      strat->P.p = nc_CreateSpoly(strat->P.p1, strat->P.p2, currRing);
+    }
+
+    if(strat->P.IsNull()) continue;
+
+//     poly save = NULL;
+//
+//     if(pNext(strat->P.p) != NULL)
+//       save = p_Copy(strat->P.p, currRing);
+
+    strat->initEcart(&strat->P); // remove it?
+
+    if (TEST_OPT_PROT)
+      message((strat->honey ? strat->P.ecart : 0) + strat->P.pFDeg(), &olddeg,&reduc,strat, red_result);
+
+    // reduction of the element chosen from L wrt S
+    strat->red(&strat->P,strat);
+
+    if(strat->P.IsNull()) continue;
+
+    addLObject(strat->P, strat);
+
+    const poly save = strat->P.p;
+
+#ifdef PDEBUG
+      p_Test(save, currRing);
+#endif
+    assume( save != NULL );
+
+    // SCA Specials:
+
+    {
+      const poly p_next = pNext(save);
+
+      if( p_next != NULL )
+      for( unsigned int i = m_iFirstAltVar; i <= m_iLastAltVar; i++ )
+      if( p_GetExp(save, i, currRing) != 0 )
+      {
+        assume(p_GetExp(save, i, currRing) == 1);
+
+        const poly tt = sca_pp_Mult_xi_pp(i, p_next, currRing);
+
+#ifdef PDEBUG
+        p_Test(tt, currRing);
+#endif
+
+        if( tt == NULL) continue;
+
+        LObject h(tt); // h = x_i * P
+
+        if (TEST_OPT_INTSTRATEGY)
+        {
+//           h.pCleardenom(); // also does a p_Content
+          p_Content(h.p,currRing);
+        }
+        else
+        {
+          h.pNorm();
+        }
+
+        strat->initEcart(&h);
+
+
+//         if (pOrdSgn==-1)
+//         {
+//           cancelunit(&h);  // tries to cancel a unit
+//           deleteHC(&h, strat);
+//         }
+
+//         if(h.IsNull()) continue;
+
+//         if (TEST_OPT_PROT)
+//           message((strat->honey ? h.ecart : 0) + h.pFDeg(), &olddeg, &reduc, strat, red_result);
+
+//         strat->red(&h, strat); // wrt S
+//         if(h.IsNull()) continue;
+
+//         poly save = p_Copy(h.p, currRing);
+
+        int pos;
+
+        if (strat->Ll==-1)
+          pos =0;
+        else
+          pos = strat->posInL(strat->L,strat->Ll,&h,strat);
+
+        h.sev = pGetShortExpVector(h.p);
+        enterL(&strat->L,&strat->Ll,&strat->Lmax,h,pos);
+
+  //       h.p = save;
+  //       addLObject(h, strat);
+      }
+
+      // p_Delete( &save, currRing );
+    }
+
+
+  } // for(;;)
+
+
+#ifdef KDEBUG
+  if (TEST_OPT_DEBUG) messageSets(strat);
+#endif
+
+  if (TEST_OPT_REDSB){
+    completeReduce(strat); // ???
+  }
+
+  // release temp data--------------------------------
+  exitBuchMora(strat);
+
+//  if (TEST_OPT_WEIGHTM)
+//  {
+//    pRestoreDegProcs(currRing,pFDegOld, pLDegOld);
+//     if (ecartWeights)
+//     {
+//       omFreeSize((ADDRESS)ecartWeights,(rVar(currRing)+1)*sizeof(int));
+//       ecartWeights=NULL;
+//     }
+//  }
+
+  if (TEST_OPT_PROT) messageStat(hilbcount,strat);
+
+  if (tempQ!=NULL) updateResult(strat->Shdl,tempQ,strat);
+
+  id_Delete(&tempF, currRing);
+
+
+  // complete reduction of the standard basis---------
+  if (TEST_OPT_REDSB){
+    ideal I = strat->Shdl;
+    ideal erg = kInterRedOld(I,tempQ);
+    assume(I!=erg);
+    id_Delete(&I, currRing);
+    strat->Shdl = erg;
+  }
+
+
+#if MYTEST
+//   PrintS("</sca_gr_bba>\n");
+#endif
+
+  if( currRing != save )     rChangeCurrRing(save);
+
+  return (strat->Shdl);
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////////////////
+//************* SCA BBA *************************************************************//
+///////////////////////////////////////////////////////////////////////////////////////
+
+// Under development!!!
+ideal sca_bba (const ideal F, const ideal Q, const intvec */*w*/, const intvec * /*hilb*/, kStrategy strat, const ring _currRing)
+{
+  const ring save = currRing;
+  if( currRing != _currRing ) rChangeCurrRing(_currRing);
+  assume( currRing == _currRing );
+
+#if MYTEST
+  PrintS("\n\n<sca_bba>\n\n");
+#endif
+
+  assume(rIsSCA(currRing));
+
+#ifndef SING_NDEBUG
+  idTest(F);
+  idTest(Q);
+#endif
+
+#if MYTEST
+  PrintS("\ncurrRing: \n");
+  rWrite(currRing);
+#ifdef RDEBUG
+//  rDebugPrint(currRing);
+#endif
+
+  PrintS("\n\nF: \n");
+  idPrint(F);
+  PrintS("\n\nQ: \n");
+  idPrint(Q);
+
+  PrintLn();
+#endif
+
+
+  const unsigned int m_iFirstAltVar = scaFirstAltVar(currRing);
+  const unsigned int m_iLastAltVar  = scaLastAltVar(currRing);
+
+  ideal tempF = id_KillSquares(F, m_iFirstAltVar, m_iLastAltVar, currRing);
+
+  ideal tempQ = Q;
+
+  if(Q == currRing->qideal)
+    tempQ = SCAQuotient(currRing);
+
+  // Q or tempQ will not be used below :(((
+
+
+#if MYTEST
+
+  PrintS("tempF: \n");
+  idPrint(tempF);
+  PrintS("tempQ: \n");
+  idPrint(tempQ);
+#endif
+
+  strat->z2homog = id_IsSCAHomogeneous(tempF, NULL, NULL, currRing); // wCx == wCy == NULL!
+   // redo no_prod_crit:
+  const BOOLEAN bIsSCA  = rIsSCA(currRing) && strat->z2homog; // for Z_2 prod-crit
+  strat->no_prod_crit   = ! bIsSCA;
+
+//  strat->homog = strat->homog && strat->z2homog; // ?
+
+  int   red_result = 1;
+  int   olddeg, reduc;
+
+//  int hilbeledeg = 1, minimcnt = 0;
+  int hilbcount = 0;
+
+  BOOLEAN withT = FALSE;
+
+  initBuchMoraCrit(strat); // sets Gebauer, honey, sugarCrit // sca - ok???
+  initBuchMoraPos(strat); // sets strat->posInL, strat->posInT // check!! (Plural's: )
+
+//   initHilbCrit(F, Q, &hilb, strat);
+
+//  nc_gr_initBba(F,strat);
+  initBba(tempF, strat); // set enterS, red, initEcart, initEcartPair
+
+  // set enterS, spSpolyShort, reduce, red, initEcart, initEcartPair
+  // ?? set spSpolyShort, reduce ???
+  initBuchMora(tempF, tempQ, strat); // tempQ = Q without squares!!!
+
+//   if (strat->minim>0) strat->M = idInit(IDELEMS(F),F->rank);
+
+  reduc = olddeg = 0;
+
+#define NO_BUCKETS
+
+#ifndef NO_BUCKETS
+  if (!TEST_OPT_NOT_BUCKETS)
+    strat->use_buckets = 1;
+#endif
+
+  // redtailBBa against T for inhomogenous input
+  if (!TEST_OPT_OLDSTD)
+    withT = ! strat->homog;
+
+  // strat->posInT = posInT_pLength;
+  kTest_TS(strat);
+
+#undef HAVE_TAIL_RING
+
+#ifdef HAVE_TAIL_RING
+  if(!idIs0(F) &&(!rField_is_Ring()))  // create strong gcd poly computes with tailring and S[i] ->to be fixed
+    kStratInitChangeTailRing(strat);
+#endif
+  if (BVERBOSE(23))
+  {
+    if (test_PosInT!=NULL) strat->posInT=test_PosInT;
+    if (test_PosInL!=NULL) strat->posInL=test_PosInL;
+    kDebugPrint(strat);
+  }
+
+
+  ///////////////////////////////////////////////////////////////
+  // SCA:
+
+  //  due to std( SB, p).
+  // Note that after initBuchMora :: initSSpecial all these additional
+  // elements are in S and T (and some pairs are in L, which also has no initiall
+  // elements!!!)
+  if(TEST_OPT_SB_1)
+  {
+    // For all additional elements...
+    for (int iNewElement = strat->newIdeal; iNewElement < IDELEMS(tempF); iNewElement++)
+    {
+      const poly pSave = tempF->m[iNewElement];
+
+      if( pSave != NULL )
+      {
+//        tempF->m[iNewElement] = NULL;
+
+        const poly p_next = pNext(pSave);
+
+        if(p_next != NULL)
+          for( unsigned int i = m_iFirstAltVar; i <= m_iLastAltVar; i++ )
+            if( p_GetExp(pSave, i, currRing) != 0 )
+            {
+              assume(p_GetExp(pSave, i, currRing) == 1);
+
+              const poly p_new = sca_pp_Mult_xi_pp(i, p_next, currRing);
+
+#ifdef PDEBUG
+              p_Test(p_new, currRing);
+#endif
+
+              if( p_new == NULL) continue;
+
+              LObject h(p_new); // h = x_i * strat->P
+              h.is_special = TRUE;
+
+              if (TEST_OPT_INTSTRATEGY)
+                h.pCleardenom(); // also does a p_Content
+              else
+                h.pNorm();
+
+              strat->initEcart(&h);
+              h.sev = pGetShortExpVector(h.p);
+
+              int pos = 0;
+
+              if (strat->Ll != -1)
+                pos = strat->posInL(strat->L,strat->Ll,&h,strat);
+
+              enterL(&strat->L,&strat->Ll,&strat->Lmax,h,pos);
+            }
+      }
+    }
+  }
+
+  // compute-------------------------------------------------------
+  while (strat->Ll >= 0)
+  {
+#ifdef KDEBUG
+//     loop_count++;
+    if (TEST_OPT_DEBUG) messageSets(strat);
+#endif
+
+    if (strat->Ll== 0) strat->interpt=TRUE;
+
+    if (TEST_OPT_DEGBOUND
+        && ((strat->honey && (strat->L[strat->Ll].ecart+currRing->pFDeg(strat->L[strat->Ll].p,currRing)>Kstd1_deg))
+            || ((!strat->honey) && (currRing->pFDeg(strat->L[strat->Ll].p,currRing)>Kstd1_deg))))
+    {
+
+#ifdef KDEBUG
+//      if (TEST_OPT_DEBUG){PrintS("^^^^?");}
+#endif
+
+      // *stops computation if
+      // * 24 IN test and the degree +ecart of L[strat->Ll] is bigger then
+      // *a predefined number Kstd1_deg
+      while ((strat->Ll >= 0)
+        && ( (strat->homog==isHomog) || strat->L[strat->Ll].is_special || ((strat->L[strat->Ll].p1!=NULL) && (strat->L[strat->Ll].p2!=NULL)) )
+        && ((strat->honey && (strat->L[strat->Ll].ecart+currRing->pFDeg(strat->L[strat->Ll].p,currRing)>Kstd1_deg))
+            || ((!strat->honey) && (currRing->pFDeg(strat->L[strat->Ll].p,currRing)>Kstd1_deg)))
+            )
+      {
+#ifdef KDEBUG
+//        if (TEST_OPT_DEBUG){PrintS("^^^^^^^^^^^^!!!!");}
+#endif
+        deleteInL(strat->L,&strat->Ll,strat->Ll,strat);
+//        if (TEST_OPT_PROT) PrintS("^!");
+      }
+      if (strat->Ll<0) break;
+      else strat->noClearS=TRUE;
+    }
+
+    // picks the last element from the lazyset L
+    strat->P = strat->L[strat->Ll];
+    strat->Ll--;
+
+
+//    assume(pNext(strat->P.p) != strat->tail);
+
+    if(strat->P.IsNull()) continue;
+
+    if (pNext(strat->P.p) == strat->tail)
+    {
+      // deletes the short spoly
+      pLmFree(strat->P.p);
+
+      strat->P.p = nc_CreateSpoly(strat->P.p1, strat->P.p2, currRing);
+      if (strat->P.p!=NULL) strat->initEcart(&strat->P);
+    }//    else
+
+
+    if(strat->P.IsNull()) continue;
+
+    if (strat->P.p1 == NULL)
+    {
+//       if (strat->minim > 0)
+//         strat->P.p2=p_Copy(strat->P.p, currRing, strat->tailRing);
+
+
+      // for input polys, prepare reduction
+        strat->P.PrepareRed(strat->use_buckets);
+    }
+
+    if (TEST_OPT_PROT)
+      message((strat->honey ? strat->P.ecart : 0) + strat->P.pFDeg(),
+              &olddeg,&reduc,strat, red_result);
+
+    // reduction of the element choosen from L
+    red_result = strat->red(&strat->P,strat);
+
+
+    // reduction to non-zero new poly
+    if (red_result == 1)
+    {
+      // statistic
+      if (TEST_OPT_PROT) PrintS("s");
+
+      // get the polynomial (canonicalize bucket, make sure P.p is set)
+      strat->P.GetP(strat->lmBin);
+
+      int pos = posInS(strat,strat->sl,strat->P.p,strat->P.ecart);
+
+      // reduce the tail and normalize poly
+      if (TEST_OPT_INTSTRATEGY)
+      {
+        strat->P.pCleardenom();
+        if ((TEST_OPT_REDSB)||(TEST_OPT_REDTAIL))
+        {
+          strat->P.p = redtailBba(&(strat->P),pos-1,strat, withT); // !!!
+          strat->P.pCleardenom();
+        }
+      }
+      else
+      {
+        strat->P.pNorm();
+        if ((TEST_OPT_REDSB)||(TEST_OPT_REDTAIL))
+          strat->P.p = redtailBba(&(strat->P),pos-1,strat, withT);
+      }
+      strat->P.is_normalized=nIsOne(pGetCoeff(strat->P.p));
+
+#ifdef KDEBUG
+      if (TEST_OPT_DEBUG){PrintS(" ns:");p_wrp(strat->P.p,currRing);PrintLn();}
+#endif
+
+//       // min_std stuff
+//       if ((strat->P.p1==NULL) && (strat->minim>0))
+//       {
+//         if (strat->minim==1)
+//         {
+//           strat->M->m[minimcnt]=p_Copy(strat->P.p,currRing,strat->tailRing);
+//           p_Delete(&strat->P.p2, currRing, strat->tailRing);
+//         }
+//         else
+//         {
+//           strat->M->m[minimcnt]=strat->P.p2;
+//           strat->P.p2=NULL;
+//         }
+//         if (strat->tailRing!=currRing && pNext(strat->M->m[minimcnt])!=NULL)
+//           pNext(strat->M->m[minimcnt])
+//             = strat->p_shallow_copy_delete(pNext(strat->M->m[minimcnt]),
+//                                            strat->tailRing, currRing,
+//                                            currRing->PolyBin);
+//         minimcnt++;
+//       }
+
+      // enter into S, L, and T
+      //if(withT)
+      {
+        strat->P.SetpFDeg();
+        enterT(strat->P, strat);
+      }
+
+      // L
+      enterpairs(strat->P.p,strat->sl,strat->P.ecart,pos,strat, strat->tl);
+
+      // posInS only depends on the leading term
+      strat->enterS(strat->P, pos, strat, strat->tl);
+
+//       if (hilb!=NULL) khCheck(Q,w,hilb,hilbeledeg,hilbcount,strat);
+
+//      Print("[%d]",hilbeledeg);
+      if (strat->P.lcm!=NULL) pLmFree(strat->P.lcm);
+
+      // //////////////////////////////////////////////////////////
+      // SCA:
+      const poly pSave = strat->P.p;
+      const poly p_next = pNext(pSave);
+
+//       if(0)
+      if( p_next != NULL )
+      for( unsigned int i = m_iFirstAltVar; i <= m_iLastAltVar; i++ )
+      if( p_GetExp(pSave, i, currRing) != 0 )
+      {
+        assume(p_GetExp(pSave, i, currRing) == 1);
+        const poly p_new = sca_pp_Mult_xi_pp(i, p_next, currRing);
+
+#ifdef PDEBUG
+        p_Test(p_new, currRing);
+#endif
+
+        if( p_new == NULL) continue;
+
+        LObject h(p_new); // h = x_i * strat->P
+
+        h.is_special = TRUE;
+
+        if (TEST_OPT_INTSTRATEGY)
+        {
+//          p_Content(h.p);
+          h.pCleardenom(); // also does a p_Content
+        }
+        else
+        {
+          h.pNorm();
+        }
+
+        strat->initEcart(&h);
+        h.sev = pGetShortExpVector(h.p);
+
+        int pos = 0;
+
+        if (strat->Ll != -1)
+          pos = strat->posInL(strat->L,strat->Ll,&h,strat);
+
+        enterL(&strat->L,&strat->Ll,&strat->Lmax,h,pos);
+
+
+
+
+#if 0
+        h.sev = pGetShortExpVector(h.p);
+        strat->initEcart(&h);
+
+        h.PrepareRed(strat->use_buckets);
+
+        // reduction of the element choosen from L(?)
+        red_result = strat->red(&h,strat);
+
+        // reduction to non-zero new poly
+        if (red_result != 1) continue;
+
+
+        int pos = posInS(strat,strat->sl,h.p,h.ecart);
+
+        // reduce the tail and normalize poly
+        if (TEST_OPT_INTSTRATEGY)
+        {
+          h.pCleardenom();
+          if ((TEST_OPT_REDSB)||(TEST_OPT_REDTAIL))
+          {
+            h.p = redtailBba(&(h),pos-1,strat, withT); // !!!
+            h.pCleardenom();
+          }
+        }
+        else
+        {
+          h.pNorm();
+          if ((TEST_OPT_REDSB)||(TEST_OPT_REDTAIL))
+            h.p = redtailBba(&(h),pos-1,strat, withT);
+        }
+
+#ifdef KDEBUG
+        if (TEST_OPT_DEBUG){PrintS(" N:");h.wrp();PrintLn();}
+#endif
+
+//        h.PrepareRed(strat->use_buckets); // ???
+
+        h.sev = pGetShortExpVector(h.p);
+        strat->initEcart(&h);
+
+        if (strat->Ll==-1)
+          pos = 0;
+        else
+          pos = strat->posInL(strat->L,strat->Ll,&h,strat);
+
+         enterL(&strat->L,&strat->Ll,&strat->Lmax,h,pos);
+// the end of "#if 0" (comment)
+#endif
+
+      } // for all x_i \in Ann(lm(P))
+    } // if red(P) != NULL
+
+//     else if (strat->P.p1 == NULL && strat->minim > 0)
+//     {
+//       p_Delete(&strat->P.p2, currRing, strat->tailRing);
+//     }
+
+#ifdef KDEBUG
+//    memset(&(strat->P), 0, sizeof(strat->P));
+#endif
+
+    kTest_TS(strat); // even of T is not used!
+
+//     Print("\n$\n");
+
+  }
+
+#ifdef KDEBUG
+  if (TEST_OPT_DEBUG) messageSets(strat);
+#endif
+
+  // complete reduction of the standard basis---------
+
+  if (TEST_OPT_REDSB)
+  {
+    completeReduce(strat);
+  }
+
+  //release temp data--------------------------------
+
+  exitBuchMora(strat); // cleanT!
+
+  id_Delete(&tempF, currRing);
+
+//  if (TEST_OPT_WEIGHTM)
+//  {
+//    pRestoreDegProcs(currRing, pFDegOld, pLDegOld);
+//     if (ecartWeights)
+//     {
+//       omFreeSize((ADDRESS)ecartWeights,(rVar(currRing)+1)*sizeof(short));
+//       ecartWeights=NULL;
+//     }
+//  }
+
+  if (TEST_OPT_PROT) messageStat(hilbcount,strat);
+
+
+
+  if (tempQ!=NULL) updateResult(strat->Shdl,tempQ,strat);
+
+
+  if (TEST_OPT_REDSB) // ???
+  {
+    // must be at the very end (after exitBuchMora) as it changes the S set!!!
+    ideal I = strat->Shdl;
+    ideal erg = kInterRedOld(I,tempQ);
+    assume(I!=erg);
+    id_Delete(&I, currRing);
+    strat->Shdl = erg;
+  }
+
+#if MYTEST
+  PrintS("\n\n</sca_bba>\n\n");
+#endif
+
+  if( currRing != save )     rChangeCurrRing(save);
+
+  return (strat->Shdl);
+}
+
+// //////////////////////////////////////////////////////////////////////////////
+// sca mora...
+
+// returns TRUE if mora should use buckets, false otherwise
+#ifdef MORA_USE_BUCKETS
+static BOOLEAN kMoraUseBucket(kStrategy strat)
+#else
+static BOOLEAN kMoraUseBucket(kStrategy)
+#endif
+{
+#ifdef MORA_USE_BUCKETS
+  if (TEST_OPT_NOT_BUCKETS)
+    return FALSE;
+  if (strat->red == redFirst)
+  {
+#ifdef NO_LDEG
+    if (!strat->syzComp)
+      return TRUE;
+#else
+    if ((strat->homog || strat->honey) && !strat->syzComp)
+      return TRUE;
+#endif
+  }
+  else
+  {
+    assume(strat->red == redEcart);
+    if (strat->honey && !strat->syzComp)
+      return TRUE;
+  }
+#endif
+  return FALSE;
+}
+
+#ifdef HAVE_ASSUME
+static int sca_mora_count = 0;
+static int sca_mora_loop_count;
+#endif
+
+// ideal sca_mora (ideal F, ideal Q, intvec *w, intvec *, kStrategy strat)
+ideal sca_mora(const ideal F, const ideal Q, const intvec */*w*/, const intvec *, kStrategy strat, const ring _currRing)
+{
+  const ring save = currRing;
+  if( currRing != _currRing ) rChangeCurrRing(_currRing);
+  assume( currRing == _currRing );
+
+  assume(rIsSCA(currRing));
+
+  const unsigned int m_iFirstAltVar = scaFirstAltVar(currRing);
+  const unsigned int m_iLastAltVar  = scaLastAltVar(currRing);
+
+  ideal tempF = id_KillSquares(F, m_iFirstAltVar, m_iLastAltVar, currRing);
+
+  ideal tempQ = Q;
+
+  if(Q == currRing->qideal)
+    tempQ = SCAQuotient(currRing);
+
+  bool bIdHomog = id_IsSCAHomogeneous(tempF, NULL, NULL, currRing); // wCx == wCy == NULL!
+
+  assume( !bIdHomog || strat->homog ); //  bIdHomog =====[implies]>>>>> strat->homog
+
+  strat->homog = strat->homog && bIdHomog;
+
+#ifdef PDEBUG
+  assume( strat->homog == bIdHomog );
+#endif
+
+#ifdef HAVE_ASSUME
+  sca_mora_count++;
+  sca_mora_loop_count = 0;
+#endif
+
+  strat->update = TRUE;
+  //- setting global variables ------------------- -
+  initBuchMoraCrit(strat);
+//   initHilbCrit(F,NULL,&hilb,strat); // no Q!
+  initMora(tempF, strat);
+  initBuchMoraPos(strat);
+  //Shdl=
+    initBuchMora(tempF, tempQ, strat); // temp Q, F!
+//   if (TEST_OPT_FASTHC) missingAxis(&strat->lastAxis,strat);
+  // updateS in initBuchMora has Hecketest
+  // * and could have put strat->kHEdgdeFound FALSE
+#if 0
+  if (ppNoether!=NULL)
+  {
+    strat->kHEdgeFound = TRUE;
+  }
+  if (strat->kHEdgeFound && strat->update)
+  {
+    firstUpdate(strat);
+    updateLHC(strat);
+    reorderL(strat);
+  }
+  if (TEST_OPT_FASTHC && (strat->lastAxis) && strat->posInLOldFlag)
+  {
+    strat->posInLOld = strat->posInL;
+    strat->posInLOldFlag = FALSE;
+    strat->posInL = posInL10;
+    updateL(strat);
+    reorderL(strat);
+  }
+#endif
+  strat->use_buckets = kMoraUseBucket(strat);
+
+  kTest_TS(strat);
+
+
+  int olddeg = 0;
+  int reduc = 0;
+  int red_result = 1;
+//  int hilbeledeg=1;
+  int hilbcount=0;
+
+
+  //- compute-------------------------------------------
+
+#undef HAVE_TAIL_RING
+
+#ifdef HAVE_TAIL_RING
+//  if (strat->homog && strat->red == redFirst)
+//     kStratInitChangeTailRing(strat);
+#endif
+
+
+
+
+
+//  due to std( SB, p)
+  if(TEST_OPT_SB_1)
+  {
+    for (int iNewElement = strat->newIdeal; iNewElement < IDELEMS(tempF); iNewElement++)
+    {
+
+      const poly pSave = tempF->m[iNewElement];
+
+      if( pSave != NULL )
+      {
+//        tempF->m[iNewElement] = NULL;
+
+        const poly p_next = pNext(pSave);
+
+        if(p_next != NULL)
+          for( unsigned int i = m_iFirstAltVar; i <= m_iLastAltVar; i++ )
+            if( p_GetExp(pSave, i, currRing) != 0 )
+            {
+
+              assume(p_GetExp(pSave, i, currRing) == 1);
+
+              const poly p_new = sca_pp_Mult_xi_pp(i, p_next, currRing);
+
+#ifdef PDEBUG
+              p_Test(p_new, currRing);
+#endif
+
+              if( p_new == NULL) continue;
+
+              LObject h(p_new); // h = x_i * strat->P
+
+              if (TEST_OPT_INTSTRATEGY)
+                h.pCleardenom(); // also does a p_Content
+              else
+                h.pNorm();
+
+              strat->initEcart(&h);
+              h.sev = pGetShortExpVector(h.p);
+
+              int pos = 0;
+
+              if (strat->Ll != -1)
+                pos = strat->posInL(strat->L,strat->Ll,&h,strat);
+
+              enterL(&strat->L,&strat->Ll,&strat->Lmax,h,pos);
+            }
+      }
+
+    }
+  }
+
+
+
+
+  while (strat->Ll >= 0)
+  {
+#ifdef HAVE_ASSUME
+    sca_mora_loop_count++;
+#endif
+    //test_int_std(strat->kIdeal);
+#ifdef KDEBUG
+    if (TEST_OPT_DEBUG) messageSets(strat);
+#endif
+    if (TEST_OPT_DEGBOUND
+    && (strat->L[strat->Ll].ecart+strat->L[strat->Ll].GetpFDeg()> Kstd1_deg))
+    {
+      // * stops computation if
+      // * - 24 (degBound)
+      // *   && upper degree is bigger than Kstd1_deg
+      while ((strat->Ll >= 0)
+        && (strat->L[strat->Ll].p1!=NULL) && (strat->L[strat->Ll].p2!=NULL)
+        && (strat->L[strat->Ll].ecart+strat->L[strat->Ll].GetpFDeg()> Kstd1_deg)
+      )
+      {
+        deleteInL(strat->L,&strat->Ll,strat->Ll,strat);
+        //if (TEST_OPT_PROT)
+        //{
+        //   PrintS("D"); mflush();
+        //}
+      }
+      if (strat->Ll<0) break;
+      else strat->noClearS=TRUE;
+    }
+    strat->P = strat->L[strat->Ll];// - picks the last element from the lazyset L -
+    if (strat->Ll==0) strat->interpt=TRUE;
+    strat->Ll--;
+
+    // create the real Spoly
+//    assume(pNext(strat->P.p) != strat->tail);
+
+    if(strat->P.IsNull()) continue;
+
+
+    if( pNext(strat->P.p) == strat->tail )
+    {
+      // deletes the int spoly and computes SPoly
+      pLmFree(strat->P.p); // ???
+      strat->P.p = nc_CreateSpoly(strat->P.p1, strat->P.p2, currRing);
+    }
+
+
+
+    if (strat->P.p1 == NULL)
+    {
+      // for input polys, prepare reduction (buckets !)
+      strat->P.SetLength(strat->length_pLength);
+      strat->P.PrepareRed(strat->use_buckets);
+    }
+
+    if (!strat->P.IsNull())
+    {
+      // might be NULL from noether !!!
+      if (TEST_OPT_PROT)
+        message(strat->P.ecart+strat->P.GetpFDeg(),&olddeg,&reduc,strat, red_result);
+      // reduce
+      red_result = strat->red(&strat->P,strat);
+    }
+
+    if (! strat->P.IsNull())
+    {
+      strat->P.GetP();
+      // statistics
+      if (TEST_OPT_PROT) PrintS("s");
+      // normalization
+      if (!TEST_OPT_INTSTRATEGY)
+        strat->P.pNorm();
+      // tailreduction
+      strat->P.p = redtail(&(strat->P),strat->sl,strat);
+      // set ecart -- might have changed because of tail reductions
+      if ((!strat->noTailReduction) && (!strat->honey))
+        strat->initEcart(&strat->P);
+      // cancel unit
+      cancelunit(&strat->P);
+      // for char 0, clear denominators
+      if (TEST_OPT_INTSTRATEGY)
+        strat->P.pCleardenom();
+
+      // put in T
+      enterT(strat->P,strat);
+      // build new pairs
+      enterpairs(strat->P.p,strat->sl,strat->P.ecart,0,strat, strat->tl);
+      // put in S
+      strat->enterS(strat->P,
+                    posInS(strat,strat->sl,strat->P.p, strat->P.ecart),
+                    strat, strat->tl);
+
+
+      // clear strat->P
+      if (strat->P.lcm!=NULL) pLmFree(strat->P.lcm);
+      strat->P.lcm=NULL;
+
+      // //////////////////////////////////////////////////////////
+      // SCA:
+      const poly pSave = strat->P.p;
+      const poly p_next = pNext(pSave);
+
+      if(p_next != NULL)
+      for( unsigned int i = m_iFirstAltVar; i <= m_iLastAltVar; i++ )
+      if( p_GetExp(pSave, i, currRing) != 0 )
+      {
+
+        assume(p_GetExp(pSave, i, currRing) == 1);
+
+        const poly p_new = sca_pp_Mult_xi_pp(i, p_next, currRing);
+
+#ifdef PDEBUG
+        p_Test(p_new, currRing);
+#endif
+
+        if( p_new == NULL) continue;
+
+        LObject h(p_new); // h = x_i * strat->P
+
+        if (TEST_OPT_INTSTRATEGY)
+           h.pCleardenom(); // also does a p_Content
+        else
+          h.pNorm();
+
+        strat->initEcart(&h);
+        h.sev = pGetShortExpVector(h.p);
+
+        int pos = 0;
+
+        if (strat->Ll != -1)
+          pos = strat->posInL(strat->L,strat->Ll,&h,strat);
+
+        enterL(&strat->L,&strat->Ll,&strat->Lmax,h,pos);
+      }
+
+#ifdef KDEBUG
+      // make sure kTest_TS does not complain about strat->P
+      memset(&strat->P,0,sizeof(strat->P));
+#endif
+    }
+#if 0
+    if (strat->kHEdgeFound)
+    {
+      if ((TEST_OPT_FINDET)
+      || ((TEST_OPT_MULTBOUND) && (scMult0Int((strat->Shdl)) < mu)))
+      {
+        // obachman: is this still used ???
+        // * stops computation if strat->kHEdgeFound and
+        // * - 27 (finiteDeterminacyTest)
+        // * or
+        // * - 23
+        // *   (multBound)
+        // *   && multiplicity of the ideal is smaller then a predefined number mu
+        while (strat->Ll >= 0) deleteInL(strat->L,&strat->Ll,strat->Ll,strat);
+      }
+    }
+#endif
+    kTest_TS(strat);
+  }
+  // - complete reduction of the standard basis------------------------ -
+  if (TEST_OPT_REDSB) completeReduce(strat);
+  // - release temp data------------------------------- -
+  exitBuchMora(strat);
+  // - polynomials used for HECKE: HC, noether -
+  if (TEST_OPT_FINDET)
+  {
+    if (strat->kHEdge!=NULL)
+      Kstd1_mu=currRing->pFDeg(strat->kHEdge,currRing);
+    else
+      Kstd1_mu=-1;
+  }
+  pDelete(&strat->kHEdge);
+  strat->update = TRUE; //???
+  strat->lastAxis = 0; //???
+  pDelete(&strat->kNoether);
+  omFreeSize((ADDRESS)strat->NotUsedAxis,(rVar(currRing)+1)*sizeof(BOOLEAN));
+  if (TEST_OPT_PROT) messageStat(hilbcount,strat);
+//  if (TEST_OPT_WEIGHTM)
+//  {
+//    pRestoreDegProcs(currRing, pFDegOld, pLDegOld);
+//     if (ecartWeights)
+//     {
+//       omFreeSize((ADDRESS)ecartWeights,(rVar(currRing)+1)*sizeof(short));
+//       ecartWeights=NULL;
+//     }
+//  }
+  if (tempQ!=NULL) updateResult(strat->Shdl,tempQ,strat);
+  idTest(strat->Shdl);
+
+  id_Delete( &tempF, currRing);
+
+  if( currRing != save )     rChangeCurrRing(save);
+
+  return (strat->Shdl);
+}
+
diff --git a/kernel/GBEngine/shiftgb.cc b/kernel/GBEngine/shiftgb.cc
new file mode 100644
index 0000000..abfe463
--- /dev/null
+++ b/kernel/GBEngine/shiftgb.cc
@@ -0,0 +1,604 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: kernel: utils for shift GB and free GB
+*/
+
+
+
+
+#include <kernel/mod2.h>
+
+#ifdef HAVE_SHIFTBBA
+#include <polys/monomials/ring.h>
+#include <kernel/polys.h>
+#include <coeffs/numbers.h>
+#include <kernel/ideals.h>
+#include <polys/matpol.h>
+#include <polys/kbuckets.h>
+#include <kernel/GBEngine/kstd1.h>
+#include <polys/sbuckets.h>
+#include <polys/operations/p_Mult_q.h>
+#include <kernel/GBEngine/kutil.h>
+#include <kernel/structs.h>
+#include <omalloc/omalloc.h>
+#include <kernel/GBEngine/khstd.h>
+#include <polys/kbuckets.h>
+#include <polys/weight.h>
+#include <misc/intvec.h>
+#include <kernel/structs.h>
+#include <kernel/GBEngine/kInline.h>
+#include <kernel/combinatorics/stairc.h>
+#include <polys/weight.h>
+#include <misc/intvec.h>
+#include <kernel/GBEngine/shiftgb.h>
+#include <polys/nc/sca.h>
+
+
+#define freeT(A,v) omFreeSize((ADDRESS)A,(v+1)*sizeof(int))
+
+
+/* TODO: write p* stuff as instances of p_* for all the functions */
+/* p_* functions are new, p* are old */
+
+poly p_LPshiftT(poly p, int sh, int uptodeg, int lV, kStrategy strat, const ring r)
+{
+  /* assume shift takes place, shifts the poly p by sh */
+  /* p is like TObject: lm in currRing = r, tail in tailRing  */
+
+  if (p==NULL) return(p);
+
+  assume(p_LmCheckIsFromRing(p,r));
+  assume(p_CheckIsFromRing(pNext(p),strat->tailRing));
+
+  /* assume sh and uptodeg agree  TODO check */
+
+  if (sh == 0) return(p); /* the zero shift */
+
+  poly q   = NULL;
+  poly s   = p_mLPshift(p, sh, uptodeg, lV, r); // lm in currRing
+  poly pp = pNext(p);
+
+  while (pp != NULL)
+  {
+    q = p_Add_q(q, p_mLPshift(pp,sh,uptodeg,lV,strat->tailRing),strat->tailRing);
+    pIter(pp);
+  }
+  pNext(s) = q;
+  /* int version: returns TRUE if it was successful */
+  return(s);
+}
+
+
+poly p_LPshift(poly p, int sh, int uptodeg, int lV, const ring r)
+{
+  /* assume shift takes place */
+  /* shifts the poly p from the ring r by sh */
+
+  /* assume sh and uptodeg agree TODO check */
+
+  if (p==NULL) return(p);
+  if (sh == 0) return(p); /* the zero shift */
+
+  poly q  = NULL;
+  poly pp = p; // do not take copies
+  while (pp!=NULL)
+  {
+    q = p_Add_q(q, p_mLPshift(pp,sh,uptodeg,lV,r),r);
+    pIter(pp);
+  }
+  return(q);
+}
+
+poly p_mLPshift(poly p, int sh, int uptodeg, int lV, const ring r)
+{
+  /* p is a monomial from the ring r */
+
+  if (sh == 0) return(p); /* the zero shift */
+
+  if (sh < 0 )
+  {
+#ifdef PDEBUG
+    PrintS("pmLPshift: negative shift requested\n");
+#endif
+    return(NULL); /* violation, 2check */
+  }
+
+  int L = p_mLastVblock(p,lV,r);
+  if (L+sh-1 > uptodeg)
+  {
+#ifdef PDEBUG
+    PrintS("p_mLPshift: too big shift requested\n");
+#endif
+    return(NULL); /* violation, 2check */
+  }
+  int *e=(int *)omAlloc0((r->N+1)*sizeof(int));
+  int *s=(int *)omAlloc0((r->N+1)*sizeof(int));
+  p_GetExpV(p,e,r);
+
+  int j;
+  //  for (j=1; j<=r->N; j++)
+  // L*lV gives the last position of the last block
+  for (j=1; j<= L*lV ; j++)
+  {
+    if (e[j]==1)
+    {
+      s[j + (sh*lV)] = e[j]; /* actually 1 */
+#ifdef PDEBUG
+      omCheckAddr(s);
+#endif
+    }
+#ifdef PDEBUG
+    else
+    {
+      if (e[j]!=0)
+      {
+         //         Print("p_mLPshift: ex[%d]=%d\n",j,e[j]);
+      }
+    }
+#endif
+  }
+  poly m = p_One(r);
+  p_SetExpV(m,s,r);
+  freeT(e, r->N);
+  freeT(s, r->N);
+  /*  pSetm(m); */ /* done in the pSetExpV */
+  /* think on the component and coefficient */
+  //  number c = pGetCoeff(p);
+  //  p_SetCoeff0(m,p_GetCoeff(p,r),r);
+  p_SetComp(m,p_GetComp(p,r),r); // component is preserved
+  p_SetCoeff0(m,n_Copy(p_GetCoeff(p,r),r->cf),r);  // coeff is preserved
+  return(m);
+}
+
+poly pLPshift(poly p, int sh, int uptodeg, int lV)
+{
+  /* assume shift takes place */
+  /* shifts the poly p by sh */
+  /* deletes p */
+
+  /* assume sh and uptodeg agree */
+
+  if (sh == 0) return(p); /* the zero shift */
+
+  poly q  = NULL;
+  poly pp = p; // pCopy(p);
+  while (pp!=NULL)
+  {
+    q = p_Add_q(q, pmLPshift(pp,sh,uptodeg,lV),currRing);
+    pIter(pp);
+  }
+  /* delete pp? */
+  /* int version: returns TRUE if it was successful */
+  return(q);
+}
+
+poly pmLPshift(poly p, int sh, int uptodeg, int lV)
+{
+  /* TODO: use a shortcut with p_ version */
+  /* pm is a monomial */
+
+  if (sh == 0) return(p); /* the zero shift */
+
+  if (sh < 0 )
+  {
+#ifdef PDEBUG
+    PrintS("pmLPshift: negative shift requested\n");
+#endif
+    return(NULL); /* violation, 2check */
+  }
+
+  int L = pmLastVblock(p,lV);
+  if (L+sh-1 > uptodeg)
+  {
+#ifdef PDEBUG
+    PrintS("pmLPshift: too big shift requested\n");
+#endif
+    return(NULL); /* violation, 2check */
+  }
+  int *e=(int *)omAlloc0((currRing->N+1)*sizeof(int));
+  int *s=(int *)omAlloc0((currRing->N+1)*sizeof(int));
+  pGetExpV(p,e);
+  number c = pGetCoeff(p);
+  int j;
+  for (j=1; j<=currRing->N; j++)
+  {
+    if (e[j]==1)
+    {
+      s[j + (sh*lV)] = e[j]; /* actually 1 */
+    }
+  }
+  poly m = pOne();
+  pSetExpV(m,s);
+  /*  pSetm(m); */ /* done in the pSetExpV */
+  /* think on the component */
+  pSetCoeff0(m,c);
+  freeT(e, currRing->N);
+  freeT(s, currRing->N);
+  return(m);
+}
+
+int pLastVblock(poly p, int lV)
+{
+  /* returns the number of maximal block */
+  /* appearing among the monomials of p */
+  /* the 0th block is the 1st one */
+  poly q = p; //p_Copy(p,currRing); /* need it ? */
+  int ans = 0;
+  int ansnew = 0;
+  while (q!=NULL)
+  {
+    ansnew = pmLastVblock(q,lV);
+    ans    = si_max(ans,ansnew);
+    pIter(q);
+  }
+  /* do not need to delete q */
+  return(ans);
+}
+
+int pmLastVblock(poly p, int lV)
+{
+  /* for a monomial p, returns the number of the last block */
+  /* where a nonzero exponent is sitting */
+  if (pIsConstantPoly(p))
+  {
+    return(int(0));
+  }
+  int *e=(int *)omAlloc0((currRing->N+1)*sizeof(int));
+  pGetExpV(p,e);
+  int j,b;
+  j = currRing->N;
+  while ( (!e[j]) && (j>=1) ) j--;
+  freeT(e, currRing->N);
+  if (j==0)
+  {
+#ifdef PDEBUG
+    PrintS("pmLastVblock: unexpected zero exponent vector\n");
+#endif
+    return(j);
+  }
+  b = (int)(j/lV) + 1; /* the number of the block, >=1 */
+  return (b);
+}
+
+int p_LastVblockT(poly p, int lV, kStrategy strat, const ring r)
+{
+  /* returns the number of maximal block */
+  /* appearing among the monomials of p */
+  /* the 0th block is the 1st one */
+
+  /* p is like TObject: lm in currRing = r, tail in tailRing  */
+  assume(p_LmCheckIsFromRing(p,r));
+  assume(p_CheckIsFromRing(pNext(p),strat->tailRing));
+
+  int ans = p_mLastVblock(p, lV, r); // Block of LM
+  poly q = pNext(p);
+  int ansnew = 0;
+  while (q != NULL)
+  {
+    ansnew = p_mLastVblock(q, lV, strat->tailRing);
+    ans       = si_max(ans,ansnew);
+    pIter(q);
+  }
+  /* do not need to delete q */
+  return(ans);
+}
+
+int p_LastVblock(poly p, int lV, const ring r)
+{
+  /* returns the number of maximal block */
+  /* appearing among the monomials of p */
+  /* the 0th block is the 1st one */
+  poly q = p; //p_Copy(p,currRing); /* need it ? */
+  int ans = 0;
+  int ansnew = 0;
+  while (q!=NULL)
+  {
+    ansnew = p_mLastVblock(q, lV, r);
+    ans    = si_max(ans,ansnew);
+    pIter(q);
+  }
+  /* do not need to delete q */
+  return(ans);
+}
+
+int p_mLastVblock(poly p, int lV, const ring r)
+{
+  /* for a monomial p, returns the number of the last block */
+  /* where a nonzero exponent is sitting */
+  if (p_LmIsConstant(p,r))
+  {
+    return(0);
+  }
+  int *e=(int *)omAlloc0((r->N+1)*sizeof(int));
+  p_GetExpV(p,e,r);
+  int j,b;
+  j = r->N;
+  while ( (!e[j]) && (j>=1) ) j--;
+  if (j==0)
+  {
+#ifdef PDEBUG
+    PrintS("pmLastVblock: unexpected zero exponent vector\n");
+#endif
+    return(j);
+  }
+  b = (int)((j+lV-1)/lV); /* the number of the block, >=1 */
+  freeT(e,r->N);
+  return (b);
+}
+
+int pFirstVblock(poly p, int lV)
+{
+  /* returns the number of maximal block */
+  /* appearing among the monomials of p */
+  /* the 0th block is the 1st one */
+  poly q = p; //p_Copy(p,currRing); /* need it ? */
+  int ans = 0;
+  int ansnew = 0;
+  while (q!=NULL)
+  {
+    ansnew = pmFirstVblock(q,lV);
+    ans    = si_min(ans,ansnew);
+    pIter(q);
+  }
+  /* do not need to delete q */
+  return(ans);
+}
+
+int pmFirstVblock(poly p, int lV)
+{
+  if (pIsConstantPoly(p))
+  {
+    return(int(0));
+  }
+  /* for a monomial p, returns the number of the first block */
+  /* where a nonzero exponent is sitting */
+  int *e=(int *)omAlloc0((currRing->N+1)*sizeof(int));
+  pGetExpV(p,e);
+  int j,b;
+  j = 1;
+  while ( (!e[j]) && (j<=currRing->N-1) ) j++;
+  if (j==currRing->N + 1)
+  {
+#ifdef PDEBUG
+    PrintS("pmFirstVblock: unexpected zero exponent vector\n");
+#endif
+    return(j);
+  }
+  b = (int)(j/lV)+1; /* the number of the block, 1<= N <= currRing->N  */
+  return (b);
+}
+
+  /* there should be two routines: */
+  /* 1. test place-squarefreeness: in homog this suffices: isInV */
+  /* 2. test the presence of a hole -> in the tail??? */
+
+int isInV(poly p, int lV)
+{
+  /* investigate only the leading monomial of p in currRing */
+  if ( pIsConstant(p) ) return(1);
+  if (lV <= 0) return(0);
+  /* returns 1 iff p is in V */
+  /* that is in each block up to a certain one there is only one nonzero exponent */
+  /* lV = the length of V = the number of orig vars */
+  int *e = (int *)omAlloc0((currRing->N+1)*sizeof(int));
+  int  b = (int)((currRing->N +lV-1)/lV); /* the number of blocks */
+  //int b  = (int)(currRing->N)/lV;
+  int *B = (int *)omAlloc0((b+1)*sizeof(int)); /* the num of elements in a block */
+  pGetExpV(p,e);
+  int i,j;
+  for (j=1; j<=b; j++)
+  {
+    /* we go through all the vars */
+    /* by blocks in lV vars */
+    for (i=(j-1)*lV + 1; i<= j*lV; i++)
+    {
+      if (e[i]) B[j] = B[j]+1;
+    }
+  }
+  //  j = b;
+  //  while ( (!B[j]) && (j>=1)) j--;
+  for (j=b; j>=1; j--)
+  {
+    if (B[j]!=0) break;
+  }
+  /* do not need e anymore */
+  freeT(e, currRing->N);
+
+  if (j==0) goto ret_true;
+//   {
+//     /* it is a zero exp vector, which is in V */
+//     freeT(B, b);
+//     return(1);
+//   }
+  /* now B[j] != 0 and we test place-squarefreeness */
+  for (; j>=1; j--)
+  {
+    if (B[j]!=1)
+    {
+      freeT(B, b);
+      return(0);
+    }
+  }
+ ret_true:
+  freeT(B, b);
+  return(1);
+}
+
+int poly_isInV(poly p, int lV)
+{
+  /* tests whether the whole polynomial p in in V */
+  poly q = p;
+  while (q!=NULL)
+  {
+    if ( !isInV(q,lV) )
+    {
+      return(0);
+    }
+    q = pNext(q);
+  }
+  return(1);
+}
+
+int ideal_isInV(ideal I, int lV)
+{
+  /* tests whether each polynomial of an ideal I lies in in V */
+  int i;
+  int s    = IDELEMS(I)-1;
+  for(i = 0; i <= s; i++)
+  {
+    if ( !poly_isInV(I->m[i],lV) )
+    {
+      return(0);
+    }
+  }
+  return(1);
+}
+
+
+int itoInsert(poly p, int uptodeg, int lV, const ring r)
+{
+  /* for poly in lmCR/tailTR presentation */
+  /* the below situation (commented out) might happen! */
+//   if (r == currRing)
+//   {
+//     "Current ring is not expected in toInsert";
+//     return(0);
+//   }
+  /* compute the number of insertions */
+  int i = p_mLastVblock(p, lV, currRing);
+  if (pNext(p) != NULL)
+  {
+    i = si_max(i, p_LastVblock(pNext(p), lV, r) );
+  }
+  //  i = uptodeg  - i +1;
+  i = uptodeg  - i;
+  //  p_wrp(p,currRing,r); Print("----i:%d",i); PrintLn();
+  return(i);
+}
+
+poly p_ShrinkT(poly p, int lV, kStrategy strat, const ring r)
+//poly p_Shrink(poly p, int uptodeg, int lV, kStrategy strat, const ring r)
+{
+  /* p is like TObject: lm in currRing = r, tail in tailRing  */
+  /* proc shrinks the poly p in ring r */
+  /* lV = the length of V = the number of orig vars */
+  /* check assumes/exceptions */
+  /* r->N is a multiple of lV */
+
+  if (p==NULL) return(p);
+
+  assume(p_LmCheckIsFromRing(p,r));
+  assume(p_CheckIsFromRing(pNext(p),strat->tailRing));
+
+  poly q   = NULL;
+  poly s   = p_mShrink(p, lV, r); // lm in currRing
+  poly pp = pNext(p);
+
+  while (pp != NULL)
+  {
+    //    q = p_Add_q(q, p_mShrink(pp,uptodeg,lV,strat->tailRing),strat->tailRing);
+    q = p_Add_q(q, p_mShrink(pp,lV,strat->tailRing),strat->tailRing);
+    pIter(pp);
+  }
+  pNext(s) = q;
+  return(s);
+}
+
+poly p_Shrink(poly p, int lV, const ring r)
+{
+  /* proc shrinks the poly p in ring r */
+  /* lV = the length of V = the number of orig vars */
+  /* check assumes/exceptions */
+  /* r->N is a multiple of lV */
+
+  if (p==NULL) return(p);
+  assume(p_CheckIsFromRing(p,r));
+  poly q = NULL;
+  poly pp = p;
+
+  while (pp != NULL)
+  {
+    q = p_Add_q(q, p_mShrink(pp,lV,r),r);
+    pIter(pp);
+  }
+  return(q);
+}
+
+poly p_mShrink(poly p, int lV, const ring r)
+{
+  /* shrinks the monomial p in ring r */
+  /* lV = the length of V = the number of orig vars */
+
+  /* check assumes/exceptions */
+  /* r->N is a multiple of lV */
+
+  int *e = (int *)omAlloc0((r->N+1)*sizeof(int));
+  int  b = (int)((r->N +lV-1)/lV); /* the number of blocks */
+  //  int *B = (int *)omAlloc0((b+1)*sizeof(int)); /* the num of elements in a block */
+  int *S = (int *)omAlloc0((r->N+1)*sizeof(int)); /* the shrinked exponent */
+  p_GetExpV(p,e,r);
+  int i,j; int cnt = 1; //counter for blocks in S
+  for (j=1; j<=b; j++)
+  {
+    /* we go through all the vars */
+    /* by blocks in lV vars */
+    for (i=(j-1)*lV + 1; i<= j*lV; i++)
+    {
+      if (e[i]==1)
+      {
+         //      B[j] = B[j]+1; // for control in V?
+         S[(cnt-1)*lV + (i - (j-1)*lV)] = e[i];
+         /* assuming we are in V, can interrupt here */
+         cnt++;
+         //  break; //results in incomplete shrink!
+         i = j*lV; // manual break under assumption p is in V
+      }
+    }
+  }
+#ifdef PDEBUG
+  //  Print("p_mShrink: cnt = [%d], b = %d\n",cnt,b);
+#endif
+  // cnt -1 <= b  must hold!
+  //  freeT(B, b);
+  poly s = p_One(r);
+  p_SetExpV(s,S,r);
+  freeT(e, r->N);
+  freeT(S, r->N);
+  /*  p_Setm(s,r); // done by p_SetExpV */
+  p_SetComp(s,p_GetComp(p,r),r); // component is preserved
+  p_SetCoeff(s,p_GetCoeff(p,r),r);  // coeff is preserved
+#ifdef PDEBUG
+  //  Print("p_mShrink: from "); p_wrp(p,r); Print(" to "); p_wrp(s,r); PrintLn();
+#endif
+  return(s);
+}
+
+/* shiftgb stuff */
+
+
+/*2
+ *if the leading term of p
+ *divides the leading term of some T[i] it will be canceled
+ */
+// static inline void clearSShift (poly p, unsigned long p_sev,int l, int* at, int* k,
+//                            kStrategy strat)
+// {
+//   assume(p_sev == pGetShortExpVector(p));
+//   if (!pLmShortDivisibleBy(p,p_sev, strat->T[*at].p, ~ strat->sevT[*at])) return;
+//   //  if (l>=strat->lenS[*at]) return;
+//   if (TEST_OPT_PROT)
+//     PrintS("!");
+//   mflush();
+//   //pDelete(&strat->S[*at]);
+//   deleteInS((*at),strat);
+//   (*at)--;
+//   (*k)--;
+// //  assume(lenS_correct(strat));
+// }
+
+/* remarks: cleanT : just deletion
+enlargeT: just reallocation */
+
+#endif
diff --git a/kernel/GBEngine/shiftgb.h b/kernel/GBEngine/shiftgb.h
new file mode 100644
index 0000000..68c6e4a
--- /dev/null
+++ b/kernel/GBEngine/shiftgb.h
@@ -0,0 +1,45 @@
+#ifndef SHIFTGB_H
+#define SHIFTGB_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: kernel: utils for kStd
+*/
+
+#include <kernel/structs.h>
+#ifdef HAVE_SHIFTBBA
+#include <polys/nc/nc.h>
+
+poly p_LPshiftT(poly p, int sh, int uptodeg, int lV, kStrategy strat, const ring r);
+int p_LastVblockT(poly p, int lV, kStrategy strat, const ring r);
+
+poly p_ShrinkT(poly p, int lV, kStrategy strat, const ring r);
+poly p_Shrink(poly p, int lV, const ring r);
+poly p_mShrink(poly p, int lV, const ring r);
+//poly p_Shrink(poly p, int uptodeg, int lV, kStrategy strat, const ring r);
+//poly p_mShrink(poly p, int uptodeg, int lV, const ring r);
+
+poly p_LPshift(poly p, int sh, int uptodeg, int lV,const ring r);
+poly p_mLPshift(poly p, int sh, int uptodeg, int lV,const ring r);
+
+int p_mLastVblock(poly p, int lV,const ring r);
+int p_LastVblock(poly p, int lV, const ring r);
+
+poly pLPshift(poly p, int sh, int uptodeg, int lV);
+poly pmLPshift(poly p, int sh, int uptodeg, int lV);
+
+int pLastVblock(poly p, int lV);
+int pmLastVblock(poly p, int lV);
+
+int pFirstVblock(poly p, int lV);
+int pmFirstVblock(poly p, int lV);
+
+int isInV(poly p, int lV);
+int poly_isInV(poly p, int lV);
+int ideal_isInV(ideal I, int lV);
+
+int itoInsert(poly p, int uptodeg, int lV, const ring r);
+
+#endif
+#endif
diff --git a/kernel/GBEngine/syz.cc b/kernel/GBEngine/syz.cc
new file mode 100644
index 0000000..9617e23
--- /dev/null
+++ b/kernel/GBEngine/syz.cc
@@ -0,0 +1,1186 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+
+/*
+* ABSTRACT: resolutions
+*/
+
+
+
+
+
+#include <kernel/mod2.h>
+#include <misc/options.h>
+#include <omalloc/omalloc.h>
+#include <kernel/polys.h>
+#include <kernel/GBEngine/kstd1.h>
+#include <kernel/GBEngine/kutil.h>
+#include <kernel/combinatorics/stairc.h>
+#include <misc/intvec.h>
+#include <coeffs/numbers.h>
+#include <kernel/ideals.h>
+#include <misc/intvec.h>
+#include <polys/monomials/ring.h>
+#include <kernel/GBEngine/syz.h>
+#include <polys/prCopy.h>
+
+#include <polys/nc/sca.h>
+
+static intvec * syPrepareModComp(ideal arg,intvec ** w)
+{
+  intvec *w1 = NULL;
+  int i;
+  BOOLEAN isIdeal=FALSE;
+
+  if ((w==NULL) || (*w==NULL)) return w1;
+  int maxxx = (*w)->length();
+  if (maxxx==1)
+  {
+    maxxx = 2;
+    isIdeal = TRUE;
+  }
+  w1 = new intvec(maxxx+IDELEMS(arg));
+  if (!isIdeal)
+  {
+    for (i=0;i<maxxx;i++)
+    {
+      (*w1)[i] = (**w)[i];
+    }
+  }
+  for (i=maxxx;i<maxxx+IDELEMS(arg);i++)
+  {
+    if (arg->m[i-maxxx]!=NULL)
+    {
+      (*w1)[i] = p_FDeg(arg->m[i-maxxx],currRing);
+      if (pGetComp(arg->m[i-maxxx])!=0)
+      {
+        (*w1)[i]+=(**w)[pGetComp(arg->m[i-maxxx])-1];
+      }
+    }
+  }
+  delete (*w);
+  *w = new intvec(IDELEMS(arg)+1);
+  for (i=0;i<IDELEMS(arg);i++)
+  {
+     (**w)[i+1] = (*w1)[i+maxxx];
+  }
+  return w1;
+}
+
+static void syDeleteAbove(ideal up, int k)
+{
+  if (up!=NULL)
+  {
+    for (int i=0;i<IDELEMS(up);i++)
+    {
+      if (up->m[i]!=NULL)
+        pDeleteComp(&(up->m[i]),k+1);
+    }
+  }
+}
+
+/*2
+*minimizes the module mod and cancel superfluous syzygies
+*from syz
+*/
+static void syMinStep(ideal mod,ideal syz,BOOLEAN final=FALSE,ideal up=NULL,
+                      tHomog h=isNotHomog)
+{
+  ideal deg0=NULL;
+  poly Unit1,Unit2,actWith;
+  int len,i,j,ModComp,m,k,l;
+  BOOLEAN searchUnit,existsUnit;
+
+  if (TEST_OPT_PROT) PrintS("m");
+  if ((final) && (h==isHomog))
+  /*minim is TRUE, we are in the module: maxlength, maxlength <>0*/
+  {
+    deg0=id_Jet(syz,0,currRing);
+    idSkipZeroes(deg0);
+    syz=deg0;
+  }
+/*--cancels empty entees and their related components above--*/
+  j = IDELEMS(syz);
+  while ((j>0) && (!syz->m[j-1])) j--;
+  k = 0;
+  while (k<j)
+  {
+    if (syz->m[k]!=NULL)
+      k++;
+    else
+    {
+      if (TEST_OPT_PROT) PrintS(".");
+      for (l=k;l<j-1;l++) syz->m[l] = syz->m[l+1];
+      syz->m[j-1] = NULL;
+      syDeleteAbove(up,k);
+      j--;
+    }
+  }
+/*--searches for syzygies coming from superfluous elements
+* in the module below--*/
+  searchUnit = TRUE;
+  int curr_syz_limit = rGetCurrSyzLimit(currRing);
+  while (searchUnit)
+  {
+    i=0;
+    j=IDELEMS(syz);
+    while ((j>0) && (syz->m[j-1]==NULL)) j--;
+    existsUnit = FALSE;
+    if (rHasGlobalOrdering_currRing())
+    {
+      while ((i<j) && (!existsUnit))
+      {
+        existsUnit = pVectorHasUnitB(syz->m[i],&ModComp);
+        i++;
+      }
+    }
+    else
+    {
+      int I=0;
+      l = 0;
+      len=0;
+      for (i=0;i<IDELEMS(syz);i++)
+      {
+        if (syz->m[i]!=NULL)
+        {
+          pVectorHasUnit(syz->m[i],&m, &l);
+          if ((len==0) ||((l>0) && (l<len)))
+          {
+            len = l;
+            ModComp = m;
+            I = i;
+          }
+        }
+      }
+//Print("Laenge ist: %d\n",len);
+      if (len>0) existsUnit = TRUE;
+      i = I+1;
+    }
+    if (existsUnit)
+    {
+      i--;
+//--takes out the founded syzygy--
+      if (TEST_OPT_PROT) PrintS("f");
+      actWith = syz->m[i];
+      if (!rField_has_simple_inverse(currRing)) p_Cleardenom(actWith, currRing);
+//Print("actWith: ");pWrite(actWith);
+      syz->m[i] = NULL;
+      for (k=i;k<j-1;k++)  syz->m[k] = syz->m[k+1];
+      syz->m[j-1] = NULL;
+      syDeleteAbove(up,i);
+      j--;
+//--makes Gauss alg. for the column ModComp--
+      Unit1 = pTakeOutComp(&(actWith), ModComp);
+//PrintS("actWith now: ");pWrite(actWith);
+//Print("Unit1: ");pWrite(Unit1);
+      k=0;
+//Print("j= %d",j);
+      while (k<j)
+      {
+        if (syz->m[k]!=NULL)
+        {
+          Unit2 = pTakeOutComp(&(syz->m[k]), ModComp);
+//Print("element %d: ",k);pWrite(syz->m[k]);
+//PrintS("Unit2: ");pWrite(Unit2);
+          syz->m[k] = pMult(pCopy(Unit1),syz->m[k]);
+          syz->m[k] = pSub(syz->m[k],
+            pMult(Unit2,pCopy(actWith)));
+          if (syz->m[k]==NULL)
+          {
+            for (l=k;l<j-1;l++)
+              syz->m[l] = syz->m[l+1];
+            syz->m[j-1] = NULL;
+            j--;
+            syDeleteAbove(up,k);
+            k--;
+          }
+        }
+        k++;
+      }
+      pDelete(&actWith);
+      pDelete(&Unit1);
+//--deletes superfluous elements from the module below---
+      pDelete(&(mod->m[ModComp-1 - curr_syz_limit]));
+      for (k=ModComp-1 - curr_syz_limit;k<IDELEMS(mod)-1;k++)
+        mod->m[k] = mod->m[k+1];
+      mod->m[IDELEMS(mod)-1] = NULL;
+    }
+    else
+      searchUnit = FALSE;
+  }
+  if (TEST_OPT_PROT) PrintLn();
+  idSkipZeroes(mod);
+  idSkipZeroes(syz);
+  if (deg0!=NULL)
+    idDelete(&deg0);
+}
+
+/*2
+* make Gauss with the element elnum in the module component ModComp
+* for the generators from - till
+*/
+void syGaussForOne(ideal syz, int elnum, int ModComp,int from,int till)
+{
+  int /*k,j,i,*/lu;
+  poly unit1,unit2;
+  poly actWith=syz->m[elnum];
+
+  if (from<0) from = 0;
+  if ((till<=0) || (till>IDELEMS(syz))) till = IDELEMS(syz);
+  syz->m[elnum] = NULL;
+  if (!rField_has_simple_inverse(currRing)) p_Cleardenom(actWith, currRing);
+/*--makes Gauss alg. for the column ModComp--*/
+  pTakeOutComp(&(actWith), ModComp, &unit1, &lu);
+  while (from<till)
+  {
+    poly tmp=syz->m[from];
+    if (/*syz->m[from]*/ tmp!=NULL)
+    {
+      pTakeOutComp(&(tmp), ModComp, &unit2, &lu);
+      tmp = pMult(pCopy(unit1),tmp);
+      syz->m[from] = pSub(tmp,
+        pMult(unit2,pCopy(actWith)));
+    }
+    from++;
+  }
+  pDelete(&actWith);
+  pDelete(&unit1);
+}
+static void syDeleteAbove1(ideal up, int k)
+{
+  poly p/*,pp*/;
+  if (up!=NULL)
+  {
+    for (int i=0;i<IDELEMS(up);i++)
+    {
+      p = up->m[i];
+      while ((p!=NULL) && (pGetComp(p)==k))
+      {
+        /*
+        pp = pNext(p);
+        pNext(p) = NULL;
+        pDelete(&p);
+        p = pp;
+        */
+        pLmDelete(&p);
+      }
+      up->m[i] = p;
+      if (p!=NULL)
+      {
+        while (pNext(p)!=NULL)
+        {
+          if (pGetComp(pNext(p))==k)
+          {
+            /*
+            pp = pNext(pNext(p));
+            pNext(pNext(p)) = NULL;
+            pDelete(&pNext(p));
+            pNext(p) = pp;
+            */
+            pLmDelete(&pNext(p));
+          }
+          else
+            pIter(p);
+        }
+      }
+    }
+  }
+}
+/*2
+*minimizes the resolution res
+*assumes homogeneous or local case
+*/
+static void syMinStep1(resolvente res, int length)
+{
+  int i,j,k,index=0;
+  poly p;
+  ideal deg0=NULL,reddeg0=NULL;
+  intvec *have_del=NULL,*to_del=NULL;
+
+  while ((index<length) && (res[index]!=NULL))
+  {
+/*---we take out dependend elements from syz---------------------*/
+    if (res[index+1]!=NULL)
+    {
+      deg0 = id_Jet(res[index+1],0,currRing);
+      reddeg0 = kInterRedOld(deg0);
+      idDelete(&deg0);
+      have_del = new intvec(IDELEMS(res[index]));
+      for (i=0;i<IDELEMS(reddeg0);i++)
+      {
+        if (reddeg0->m[i]!=NULL)
+        {
+          j = pGetComp(reddeg0->m[i]);
+          pDelete(&(res[index]->m[j-1]));
+          /*res[index]->m[j-1] = NULL;*/
+          (*have_del)[j-1] = 1;
+        }
+      }
+      idDelete(&reddeg0);
+    }
+    if (index>0)
+    {
+/*--- we search for units and perform Gaussian elimination------*/
+      j = to_del->length();
+      while (j>0)
+      {
+        if ((*to_del)[j-1]==1)
+        {
+          k = 0;
+          while (k<IDELEMS(res[index]))
+          {
+            p = res[index]->m[k];
+            while ((p!=NULL) && ((!pLmIsConstantComp(p)) || (pGetComp(p)!=(unsigned)j)))
+              pIter(p);
+            if ((p!=NULL) && (pLmIsConstantComp(p)) && (pGetComp(p)==(unsigned)j)) break;
+            k++;
+          }
+          if (k>=IDELEMS(res[index]))
+          {
+            PrintS("out of range\n");
+          }
+          syGaussForOne(res[index],k,j);
+          if (res[index+1]!=NULL)
+            syDeleteAbove1(res[index+1],k+1);
+          (*to_del)[j-1] = 0;
+        }
+        j--;
+      }
+    }
+    if (to_del!=NULL) delete to_del;
+    to_del = have_del;
+    have_del = NULL;
+    index++;
+  }
+  if (TEST_OPT_PROT) PrintLn();
+  syKillEmptyEntres(res,length);
+}
+
+void syMinimizeResolvente(resolvente res, int length, int first)
+{
+  int syzIndex=first;
+  intvec *dummy;
+
+  if (syzIndex<1) syzIndex=1;
+  if ((syzIndex==1) && (idHomModule(res[0],currRing->qideal,&dummy)) && (!rIsPluralRing(currRing)))
+  {
+    syMinStep1(res,length);
+    delete dummy;
+    return;
+  }
+  while ((syzIndex<length-1) && (res[syzIndex]!=NULL) && (res[syzIndex+1]!=NULL))
+  {
+    syMinStep(res[syzIndex-1],res[syzIndex],FALSE,res[syzIndex+1]);
+    syzIndex++;
+  }
+  if (res[syzIndex]!=NULL)
+    syMinStep(res[syzIndex-1],res[syzIndex]);
+  if (!idIs0(res[0]))
+    idMinEmbedding(res[0],TRUE);
+}
+
+/*2
+* resolution of ideal/module arg, <=maxlength steps, (r[0..maxlength])
+*   no limitation in length if maxlength==0
+* input:arg
+*       minim: TRUE means mres cmd, FALSE nres cmd.
+*       if *len!=0: module weights: weights[0]
+*          (and weights is defined:weights[0..len-1]
+*
+* output:resolvente r[0..length-1],
+*        module weights: weights[0..length-1]
+*/
+resolvente syResolvente(ideal arg, int maxlength, int * length,
+                        intvec *** weights, BOOLEAN minim)
+{
+  BITSET save1;
+  SI_SAVE_OPT1(save1);
+  resolvente res;
+  resolvente newres;
+  tHomog hom=isNotHomog;
+  ideal temp=NULL;
+  intvec *w = NULL,**tempW;
+  int i,k,syzIndex = 0,j,rk_arg=si_max(1,(int)id_RankFreeModule(arg,currRing));
+  int Kstd1_OldDeg=Kstd1_deg;
+  BOOLEAN completeMinim;
+  BOOLEAN oldDegBound=TEST_OPT_DEGBOUND;
+  BOOLEAN setRegularity=TRUE;
+  int wlength=*length;
+
+  if (maxlength!=-1) *length = maxlength+1;
+  else              *length = 5;
+  if ((wlength!=0) && (*length!=wlength))
+  {
+    intvec **wtmp = (intvec**)omAlloc0((*length)*sizeof(intvec*));
+    wtmp[0]=(*weights)[0];
+    omFreeSize((ADDRESS)*weights,wlength*sizeof(intvec*));
+    *weights=wtmp;
+  }
+  res = (resolvente)omAlloc0((*length)*sizeof(ideal));
+
+/*--- initialize the syzygy-ring -----------------------------*/
+  ring origR = currRing;
+  ring syz_ring = rAssure_SyzComp(origR, TRUE); // will do rChangeCurrRing if needed
+  rSetSyzComp(rk_arg, syz_ring);
+
+  if (syz_ring != origR)
+  {
+    rChangeCurrRing(syz_ring);
+    res[0] = idrCopyR_NoSort(arg, origR, syz_ring);
+  }
+  else
+  {
+    res[0] = idCopy(arg);
+  }
+
+/*--- creating weights for the module components ---------------*/
+  if ((weights!=NULL) && (*weights!=NULL)&& ((*weights)[0]!=NULL))
+  {
+    if (!idTestHomModule(res[0],currRing->qideal,(*weights)[0]))
+    {
+      WarnS("wrong weights given(1):"); (*weights)[0]->show();PrintLn();
+      idHomModule(res[0],currRing->qideal,&w);
+      w->show();PrintLn();
+      *weights=NULL;
+    }
+  }
+
+  if ((weights==NULL) || (*weights==NULL) || ((*weights)[0]==NULL))
+  {
+    hom=(tHomog)idHomModule(res[0],currRing->qideal,&w);
+    if (hom==isHomog)
+    {
+      *weights = (intvec**)omAlloc0((*length)*sizeof(intvec*));
+      if (w!=NULL) (*weights)[0] = ivCopy(w);
+    }
+  }
+  else
+  {
+    if ((weights!=NULL) && (*weights!=NULL)&& ((*weights)[0]!=NULL))
+    {
+      w = ivCopy((*weights)[0]);
+      hom = isHomog;
+    }
+  }
+
+#ifdef HAVE_PLURAL
+  if (rIsPluralRing(currRing) && !rIsSCA(currRing) )
+  {
+// quick solution; need theory to apply homog GB stuff for G-Algebras
+    hom = isNotHomog;
+  }
+#endif // HAVE_PLURAL
+
+  if (hom==isHomog)
+  {
+    intvec *w1 = syPrepareModComp(res[0],&w);
+    if (w!=NULL) { delete w;w=NULL; }
+    w = w1;
+    j = 0;
+    while ((j<IDELEMS(res[0])) && (res[0]->m[j]==NULL)) j++;
+    if (j<IDELEMS(res[0]))
+    {
+      if (p_FDeg(res[0]->m[j],currRing)!=pTotaldegree(res[0]->m[j]))
+        setRegularity = FALSE;
+    }
+  }
+  else
+  {
+    setRegularity = FALSE;
+  }
+
+/*--- the main loop --------------------------------------*/
+  while ((!idIs0(res[syzIndex])) &&
+         ((maxlength==-1) || (syzIndex<=maxlength)))
+   // (syzIndex<maxlength+(int)minim)))
+/*--- compute one step more for minimizing-----------------*/
+  {
+    if (Kstd1_deg!=0) Kstd1_deg++;
+    if (syzIndex+1==*length)
+    {
+      newres = (resolvente)omAlloc0((*length+5)*sizeof(ideal));
+      tempW = (intvec**)omAlloc0((*length+5)*sizeof(intvec*));
+      for (j=0;j<*length;j++)
+      {
+        newres[j] = res[j];
+        if (*weights!=NULL) tempW[j] = (*weights)[j];
+        /*else              tempW[j] = NULL;*/
+      }
+      omFreeSize((ADDRESS)res,*length*sizeof(ideal));
+      if (*weights != NULL) omFreeSize((ADDRESS)*weights,*length*sizeof(intvec*));
+      *length += 5;
+      res=newres;
+      *weights = tempW;
+    }
+/*--- interreducing first -----------------------------------*/
+    if (syzIndex>0)
+    {
+      int rkI=id_RankFreeModule(res[syzIndex],currRing);
+      rSetSyzComp(rkI, currRing);
+    }
+    if(! TEST_OPT_NO_SYZ_MINIM )
+    if (minim || (syzIndex!=0))
+    {
+      temp = kInterRedOld(res[syzIndex],currRing->qideal);
+      idDelete(&res[syzIndex]);
+      idSkipZeroes(temp);
+      res[syzIndex] = temp;
+    }
+    temp = NULL;
+/*--- computing the syzygy modules --------------------------------*/
+    if ((currRing->qideal==NULL)&&(syzIndex==0)&& (!TEST_OPT_DEGBOUND))
+    {
+      res[/*syzIndex+*/1] = idSyzygies(res[0/*syzIndex*/],hom,&w,FALSE,setRegularity,&Kstd1_deg);
+      if ((!TEST_OPT_NOTREGULARITY) && (Kstd1_deg>0)
+      #ifdef HAVE_RINGS
+      && (!rField_is_Ring(currRing))
+      #endif
+      ) si_opt_1 |= Sy_bit(OPT_DEGBOUND);
+    }
+    else
+    {
+        res[syzIndex+1] = idSyzygies(res[syzIndex],hom,&w,FALSE);
+    }
+    completeMinim=(syzIndex!=maxlength) || (maxlength ==-1) || (hom!=isHomog);
+    syzIndex++;
+    if (TEST_OPT_PROT) Print("[%d]\n",syzIndex);
+
+    if(! TEST_OPT_NO_SYZ_MINIM )
+    {
+      if ((minim)||(syzIndex>1))
+        syMinStep(res[syzIndex-1],res[syzIndex],!completeMinim,NULL,hom);
+      if (!completeMinim)
+      /*minim is TRUE, we are in the module: maxlength, maxlength <>0*/
+      {
+        idDelete(&res[syzIndex]);
+      }
+    }
+/*---creating the iterated weights for module components ---------*/
+    if ((hom == isHomog) && (!idIs0(res[syzIndex])))
+    {
+//Print("die %d Modulegewichte sind:\n",w1->length());
+//w1->show();
+//PrintLn();
+      int max_comp = id_RankFreeModule(res[syzIndex],currRing);
+      k = max_comp - rGetCurrSyzLimit(currRing);
+      assume(w != NULL);
+      if (w != NULL)
+        w->resize(max_comp+IDELEMS(res[syzIndex]));
+      else
+        w = new intvec(max_comp+IDELEMS(res[syzIndex]));
+      (*weights)[syzIndex] = new intvec(k);
+      for (i=0;i<k;i++)
+      {
+        if (res[syzIndex-1]->m[i]!=NULL) // hs
+        {
+          (*w)[i + rGetCurrSyzLimit(currRing)] = p_FDeg(res[syzIndex-1]->m[i],currRing);
+          if (pGetComp(res[syzIndex-1]->m[i])>0)
+            (*w)[i + rGetCurrSyzLimit(currRing)]
+              += (*w)[pGetComp(res[syzIndex-1]->m[i])-1];
+          (*((*weights)[syzIndex]))[i] = (*w)[i+rGetCurrSyzLimit(currRing)];
+        }
+      }
+      for (i=k;i<k+IDELEMS(res[syzIndex]);i++)
+      {
+        if (res[syzIndex]->m[i-k]!=NULL)
+          (*w)[i+rGetCurrSyzLimit(currRing)] = p_FDeg(res[syzIndex]->m[i-k],currRing)
+                    +(*w)[pGetComp(res[syzIndex]->m[i-k])-1];
+      }
+    }
+  }
+/*--- end of the main loop --------------------------------------*/
+/*--- deleting the temporare data structures --------------------*/
+  if ((syzIndex!=0) && (res[syzIndex]!=NULL) && (idIs0(res[syzIndex])))
+    idDelete(&res[syzIndex]);
+  if (w !=NULL) delete w;
+
+  Kstd1_deg=Kstd1_OldDeg;
+  if (!oldDegBound)
+    si_opt_1 &= ~Sy_bit(OPT_DEGBOUND);
+
+  for (i=1; i<=syzIndex; i++)
+  {
+    if (! idIs0(res[i]))
+    {
+      for (j=0; j<IDELEMS(res[i]); j++)
+      {
+        p_Shift(&res[i]->m[j], -rGetMaxSyzComp(i, currRing),currRing);
+      }
+    }
+  }
+/*--- going back to the original ring -------------------------*/
+  if (origR != syz_ring)
+  {
+    rChangeCurrRing(origR); // should not be needed now?
+    for (i=0; i<=syzIndex; i++)
+    {
+      res[i] = idrMoveR_NoSort(res[i], syz_ring, origR);
+    }
+    rDelete(syz_ring);
+  }
+  SI_RESTORE_OPT1(save1);
+  return res;
+}
+
+syStrategy syResolution(ideal arg, int maxlength,intvec * w, BOOLEAN minim)
+{
+
+#ifdef HAVE_PLURAL
+
+  const ideal idSaveCurrRingQuotient = currRing->qideal;
+
+  if( rIsSCA(currRing) )
+  {
+
+#ifdef RDEBUG
+//    rWrite(currRing);
+//    rDebugPrint(currRing);
+#endif
+
+    if( ncExtensions(TESTSYZSCAMASK) )
+    {
+      currRing->qideal = SCAQuotient(currRing);
+    }
+
+    const unsigned int m_iFirstAltVar = scaFirstAltVar(currRing);
+    const unsigned int m_iLastAltVar  = scaLastAltVar(currRing);
+
+    arg = id_KillSquares(arg, m_iFirstAltVar, m_iLastAltVar, currRing, false); // kill suares in input!
+  }
+#endif
+
+  syStrategy result=(syStrategy)omAlloc0(sizeof(ssyStrategy));
+
+  if ((w!=NULL) && (!idTestHomModule(arg,currRing->qideal,w))) // is this right in SCA case???
+  {
+    WarnS("wrong weights given(2):");w->show();PrintLn();
+    idHomModule(arg,currRing->qideal,&w);
+    w->show();PrintLn();
+    w=NULL;
+  }
+  if (w!=NULL)
+  {
+    result->weights = (intvec**)omAlloc0Bin(char_ptr_bin);
+    (result->weights)[0] = ivCopy(w);
+    result->length = 1;
+  }
+  resolvente fr = syResolvente(arg,maxlength,&(result->length),&(result->weights),minim),fr1;
+  if (minim)
+  {
+    result->minres = (resolvente)omAlloc0((result->length+1)*sizeof(ideal));
+    fr1 =  result->minres;
+  }
+  else
+  {
+    result->fullres = (resolvente)omAlloc0((result->length+1)*sizeof(ideal));
+    fr1 =  result->fullres;
+  }
+  for (int i=result->length-1;i>=0;i--)
+  {
+    if (fr[i]!=NULL)
+      fr1[i] = fr[i];
+    fr[i] = NULL;
+  }
+  omFreeSize((ADDRESS)fr,(result->length)*sizeof(ideal));
+
+
+#ifdef HAVE_PLURAL
+  if( rIsSCA(currRing) )
+  {
+
+    if( ncExtensions(TESTSYZSCAMASK) )
+    {
+      currRing->qideal = idSaveCurrRingQuotient;
+    }
+
+    id_Delete(&arg, currRing);
+  }
+#endif
+
+
+  return result;
+}
+
+static poly sypCopyConstant(poly inp)
+{
+  poly outp=NULL,q;
+
+  while (inp!=NULL)
+  {
+    if (pLmIsConstantComp(inp))
+    {
+      if (outp==NULL)
+      {
+        q = outp = pHead(inp);
+      }
+      else
+      {
+        pNext(q) = pHead(inp);
+        pIter(q);
+      }
+    }
+    pIter(inp);
+  }
+  return outp;
+}
+int syDetect(ideal id,int index,BOOLEAN homog,int * degrees,int * tocancel)
+{
+  int i, j, k, subFromRank=0;
+  ideal temp;
+
+  if (idIs0(id)) return 0;
+  temp = idInit(IDELEMS(id),id->rank);
+  for (i=0;i<IDELEMS(id);i++)
+  {
+    temp->m[i] = sypCopyConstant(id->m[i]);
+  }
+  i = IDELEMS(id);
+  while ((i>0) && (temp->m[i-1]==NULL)) i--;
+  if (i==0)
+  {
+    idDelete(&temp);
+    return 0;
+  }
+  j = 0;
+  while ((j<i) && (temp->m[j]==NULL)) j++;
+  while (j<i)
+  {
+    if (homog)
+    {
+      if (index==0) k = p_FDeg(temp->m[j],currRing)+degrees[pGetComp(temp->m[j])];
+      else          k = degrees[pGetComp(temp->m[j])];
+      if (k>=index) tocancel[k-index]++;
+      if ((k>=0) && (index==0)) subFromRank++;
+    }
+    else
+    {
+      tocancel[0]--;
+    }
+    syGaussForOne(temp,j,pGetComp(temp->m[j]),j+1,i);
+    j++;
+    while ((j<i) && (temp->m[j]==NULL)) j++;
+  }
+  idDelete(&temp);
+  return subFromRank;
+}
+
+void syDetect(ideal id,int index,int rsmin, BOOLEAN homog,
+              intvec * degrees,intvec * tocancel)
+{
+  int * deg=NULL;
+  int * tocan=(int*) omAlloc0(tocancel->length()*sizeof(int));
+  int i;
+
+  if (homog)
+  {
+    deg = (int*) omAlloc0(degrees->length()*sizeof(int));
+    for (i=degrees->length();i>0;i--)
+      deg[i-1] = (*degrees)[i-1]-rsmin;
+  }
+  syDetect(id,index,homog,deg,tocan);
+  for (i=tocancel->length();i>0;i--)
+    (*tocancel)[i-1] = tocan[i-1];
+  if (homog)
+    omFreeSize((ADDRESS)deg,degrees->length()*sizeof(int));
+  omFreeSize((ADDRESS)tocan,tocancel->length()*sizeof(int));
+}
+
+/*2
+* computes the betti numbers from a given resolution
+* of length 'length' (0..length-1), not necessairily minimal,
+* (if weights are given, they are used)
+* returns the int matrix of betti numbers
+* and the regularity
+*/
+intvec * syBetti(resolvente res,int length, int * regularity,
+                 intvec* weights,BOOLEAN tomin,int * row_shift)
+{
+//#define BETTI_WITH_ZEROS
+  //tomin = FALSE;
+  int i,j=0,k=0,l,rows,cols,mr;
+  int *temp1,*temp2,*temp3;/*used to compute degrees*/
+  int *tocancel; /*(BOOLEAN)tocancel[i]=element is superfluous*/
+  int r0_len;
+
+  /*------ compute size --------------*/
+  *regularity = -1;
+  cols = length;
+  while ((cols>0)
+  && ((res[cols-1]==NULL)
+    || (idIs0(res[cols-1]))))
+  {
+    cols--;
+  }
+  intvec * result;
+  if (idIs0(res[0]))
+  {
+    if (res[0]==NULL)
+      result = new intvec(1,1,1);
+    else
+      result = new intvec(1,1,res[0]->rank);
+    return result;
+  }
+  intvec *w=NULL;
+  if (weights!=NULL)
+  {
+    if (!idTestHomModule(res[0],currRing->qideal,weights))
+    {
+      WarnS("wrong weights given(3):");weights->show();PrintLn();
+      idHomModule(res[0],currRing->qideal,&w);
+      if (w!=NULL) { w->show();PrintLn();}
+      weights=NULL;
+    }
+  }
+#if 0
+  if (idHomModule(res[0],currRing->qideal,&w)!=isHomog)
+  {
+    Warn("betti-command: Input is not homogeneous!");
+    weights=NULL;
+  }
+#endif
+  if (weights==NULL) weights=w;
+  else delete w;
+  r0_len=IDELEMS(res[0]);
+  while ((r0_len>0) && (res[0]->m[r0_len-1]==NULL)) r0_len--;
+  #ifdef SHOW_W
+  PrintS("weights:");if (weights!=NULL) weights->show(); else Print("NULL"); PrintLn();
+  #endif
+  int rkl=l = si_max(id_RankFreeModule(res[0],currRing),res[0]->rank);
+  i = 0;
+  while ((i<length) && (res[i]!=NULL))
+  {
+    if (IDELEMS(res[i])>l) l = IDELEMS(res[i]);
+    i++;
+  }
+  temp1 = (int*)omAlloc0((l+1)*sizeof(int));
+  temp2 = (int*)omAlloc((l+1)*sizeof(int));
+  rows = 1;
+  mr = 1;
+  cols++;
+  for (i=0;i<cols-1;i++)
+  {
+    if ((i==0) && (weights!=NULL)) p_SetModDeg(weights, currRing);
+    memset(temp2,0,(l+1)*sizeof(int));
+    for (j=0;j<IDELEMS(res[i]);j++)
+    {
+      if (res[i]->m[j]!=NULL)
+      {
+        if ((pGetComp(res[i]->m[j])>(unsigned)l)
+        || ((i>1) && (res[i-1]->m[pGetComp(res[i]->m[j])-1]==NULL)))
+        {
+          WerrorS("input not a resolvent");
+          omFreeSize((ADDRESS)temp1,(l+1)*sizeof(int));
+          omFreeSize((ADDRESS)temp2,(l+1)*sizeof(int));
+          return NULL;
+        }
+        temp2[j+1] = p_FDeg(res[i]->m[j],currRing)+temp1[pGetComp(res[i]->m[j])];
+        if (temp2[j+1]-i>rows) rows = temp2[j+1]-i;
+        if (temp2[j+1]-i<mr) mr = temp2[j+1]-i;
+      }
+    }
+    if ((i==0) && (weights!=NULL)) p_SetModDeg(NULL, currRing);
+    temp3 = temp1;
+    temp1 = temp2;
+    temp2 = temp3;
+  }
+  mr--;
+  if (weights!=NULL)
+  {
+    for(j=0;j<weights->length();j++)
+    {
+      if (rows <(*weights)[j]+1) rows=(-mr)+(*weights)[j]+1;
+    }
+  }
+  /*------ computation betti numbers --------------*/
+  rows -= mr;
+  result = new intvec(rows+1,cols,0);
+  if (weights!=NULL)
+  {
+    for(j=0;j<weights->length();j++)
+    {
+      IMATELEM((*result),(-mr)+(*weights)[j]+1,1) ++;
+      //Print("imat(%d,%d)++ -> %d\n",(-mr)+(*weights)[j]+1, 1, IMATELEM((*result),(-mr)+(*weights)[j]+1,1));
+    }
+  }
+  else
+  {
+    (*result)[(-mr)*cols] = /*idRankFreeModule(res[0])*/ rkl;
+    if ((!idIs0(res[0])) && ((*result)[(-mr)*cols]==0))
+      (*result)[(-mr)*cols] = 1;
+  }
+  tocancel = (int*)omAlloc0((rows+1)*sizeof(int));
+  memset(temp1,0,(l+1)*sizeof(int));
+  if (weights!=NULL)
+  {
+    memset(temp2,0,l*sizeof(int));
+    p_SetModDeg(weights, currRing);
+  }
+  else
+    memset(temp2,0,l*sizeof(int));
+  syDetect(res[0],0,TRUE,temp2,tocancel);
+  if (weights!=NULL) p_SetModDeg(NULL, currRing);
+  if (tomin)
+  {
+    //(*result)[(-mr)*cols] -= dummy;
+    for(j=0;j<=rows+mr;j++)
+    {
+      //Print("tocancel[%d]=%d imat(%d,%d)=%d\n",j,tocancel[j],(-mr)+j+1,1,IMATELEM((*result),(-mr)+j+1,1));
+      IMATELEM((*result),(-mr)+j+1,1) -= tocancel[j];
+    }
+  }
+  for (i=0;i<cols-1;i++)
+  {
+    if ((i==0) && (weights!=NULL)) p_SetModDeg(weights, currRing);
+    memset(temp2,0,l*sizeof(int));
+    for (j=0;j<IDELEMS(res[i]);j++)
+    {
+      if (res[i]->m[j]!=NULL)
+      {
+        temp2[j+1] = p_FDeg(res[i]->m[j],currRing)+temp1[pGetComp(res[i]->m[j])];
+        //(*result)[i+1+(temp2[j+1]-i-1)*cols]++;
+        //if (temp2[j+1]>i) IMATELEM((*result),temp2[j+1]-i-mr,i+2)++;
+        IMATELEM((*result),temp2[j+1]-i-mr,i+2)++;
+      }
+      else if (i==0)
+      {
+        if (j<r0_len) IMATELEM((*result),-mr,2)++;
+      }
+    }
+  /*------ computation betti numbers, if res not minimal --------------*/
+    if (tomin)
+    {
+      for (j=mr;j<rows+mr;j++)
+      {
+        //(*result)[i+1+j*cols] -= tocancel[j+1];
+        IMATELEM((*result),j+1-mr,i+2) -= tocancel[j+1];
+      }
+      if ((i<length-1) && (res[i+1]!=NULL))
+      {
+        memset(tocancel,0,(rows+1)*sizeof(int));
+        syDetect(res[i+1],i+1,TRUE,temp2,tocancel);
+        for (j=0;j<rows;j++)
+        {
+          //(*result)[i+1+j*cols] -= tocancel[j];
+          IMATELEM((*result),j+1,i+2) -= tocancel[j];
+        }
+      }
+    }
+    temp3 = temp1;
+    temp1 = temp2;
+    temp2 = temp3;
+    for (j=0;j<=rows;j++)
+    {
+    //  if (((*result)[i+1+j*cols]!=0) && (j>*regularity)) *regularity = j;
+      if ((IMATELEM((*result),j+1,i+2)!=0) && (j>*regularity)) *regularity = j;
+    }
+    if ((i==0) && (weights!=NULL)) p_SetModDeg(NULL, currRing);
+  }
+  // Print("nach minim:\n"); result->show(); PrintLn();
+  /*------ clean up --------------*/
+  omFreeSize((ADDRESS)tocancel,(rows+1)*sizeof(int));
+  omFreeSize((ADDRESS)temp1,(l+1)*sizeof(int));
+  omFreeSize((ADDRESS)temp2,(l+1)*sizeof(int));
+  if ((tomin) && (mr<0))  // deletes the first (zero) line
+  {
+    for (j=1;j<=rows+mr+1;j++)
+    {
+      for (k=1;k<=cols;k++)
+      {
+        IMATELEM((*result),j,k) = IMATELEM((*result),j-mr,k);
+      }
+    }
+    for (j=rows+mr+1;j<=rows+1;j++)
+    {
+      for (k=1;k<=cols;k++)
+      {
+        IMATELEM((*result),j,k) = 0;
+      }
+    }
+  }
+  j = 0;
+  k = 0;
+  for (i=1;i<=result->rows();i++)
+  {
+    for(l=1;l<=result->cols();l++)
+    if (IMATELEM((*result),i,l) != 0)
+    {
+      j = si_max(j, i-1);
+      k = si_max(k, l-1);
+    }
+  }
+  intvec * exactresult=new intvec(j+1,k+1,0);
+  for (i=0;i<exactresult->rows();i++)
+  {
+    for (j=0;j<exactresult->cols();j++)
+    {
+      IMATELEM(*exactresult,i+1,j+1) = IMATELEM(*result,i+1,j+1);
+    }
+  }
+  if (row_shift!=NULL) *row_shift = mr;
+  delete result;
+  return exactresult;
+}
+
+/*2
+* minbare via syzygies
+*/
+ideal syMinBase(ideal arg)
+{
+  intvec ** weights=NULL;
+  int leng;
+  if (idIs0(arg)) return idInit(1,arg->rank);
+  resolvente res=syResolvente(arg,1,&leng,&weights,TRUE);
+  ideal result=res[0];
+  omFreeSize((ADDRESS)res,leng*sizeof(ideal));
+  if (weights!=NULL)
+  {
+    if (*weights!=NULL)
+    {
+      delete (*weights);
+      *weights=NULL;
+    }
+    if ((leng>=1) && (*(weights+1)!=NULL))
+    {
+      delete *(weights+1);
+      *(weights+1)=NULL;
+    }
+  }
+  idSkipZeroes(result);
+  return result;
+}
+
+#if 0  /* currently used: syBetti */
+/*2
+* computes Betti-numbers from a resolvente of
+* (non-)homogeneous objects
+* the numbers of entrees !=NULL in res and weights must be equal
+* and < length
+*/
+intvec * syNewBetti(resolvente res, intvec ** weights, int length)
+{
+  intvec * result,*tocancel;
+  int i,j,k,rsmin=0,rsmax=0,rs=0;
+  BOOLEAN homog=TRUE;
+
+  if (weights!=NULL)           //---homogeneous Betti numbers
+  {
+/*--------------computes size of the field----------------------*/
+    for (i=1;i<length;i++)
+    {
+      if (weights[i] != NULL)
+      {
+        for (j=1;j<(weights[i])->length();j++)
+        {
+          if ((*(weights[i]))[j]-i<rsmin) rsmin = (*(weights[i]))[j]-i;
+          if ((*(weights[i]))[j]-i>rsmax) rsmax = (*(weights[i]))[j]-i;
+        }
+      }
+    }
+    i = 0;
+    while (weights[i] != NULL) i++;
+    i--;
+    for (j=0;j<IDELEMS(res[i]);j++)
+    {
+      if (res[i]->m[j]!=NULL)
+      {
+        k = p_FDeg(res[i]->m[j],currRing)+(*(weights[i]))[pGetComp(res[i]->m[j])]-i-1;
+        if (k>rsmax) rsmax = k;
+        if (k<rsmin) rsmin = k;
+      }
+    }
+    for (j=1;j<(weights[0])->length();j++)
+    {
+      if ((*weights[0])[j]>rsmax) rsmax = (*weights[0])[j];
+      if ((*weights[0])[j]<rsmin) rsmin = (*weights[0])[j];
+    }
+//Print("rsmax = %d\n",rsmax);
+//Print("rsmin = %d\n",rsmin);
+    rs = rsmax-rsmin+1;
+    result = new intvec(rs,i+2,0);
+    tocancel = new intvec(rs);
+/*-----------enter the Betti numbers-------------------------------*/
+    if (/*idRankFreeModule(res[0])*/ res[0]->rank==0)
+    {
+      IMATELEM(*result,1-rsmin,1)=1;
+    }
+    else
+    {
+      for (i=1;i<(weights[0])->length();i++)
+        IMATELEM(*result,(*weights[0])[i]+1-rsmin,1)++;
+    }
+    i = 1;
+    while (weights[i]!=NULL)
+    {
+      for (j=1;j<(weights[i])->length();j++)
+      {
+        IMATELEM(*result,(*(weights[i]))[j]-i+1-rsmin,i+1)++;
+      }
+      i++;
+    }
+    i--;
+    for (j=0;j<IDELEMS(res[i]);j++)
+    {
+      if (res[i]->m[j]!=NULL)
+      {
+        k = p_FDeg(res[i]->m[j],currRing)+(*(weights[i]))[pGetComp(res[i]->m[j])]-i;
+        IMATELEM(*result,k-rsmin,i+2)++;
+      }
+    }
+  }
+  else                //-----the non-homgeneous case
+  {
+    homog = FALSE;
+    tocancel = new intvec(1);
+    k = length;
+    while ((k>0) && (idIs0(res[k-1]))) k--;
+    result = new intvec(1,k+1,0);
+    (*result)[0] = res[0]->rank;
+    for (i=0;i<length;i++)
+    {
+      if (res[i]!=NULL)
+      {
+        for (j=0;j<IDELEMS(res[i]);j++)
+        {
+          if (res[i]->m[j]!=NULL) (*result)[i+1]++;
+        }
+      }
+    }
+  }
+/*--------computes the Betti numbers for the minimized reolvente----*/
+
+  i = 1;
+  while ((res[i]!=NULL) && (weights[i]!=NULL))
+  {
+    syDetect(res[i],i,rsmin,homog,weights[i],tocancel);
+    if (homog)
+    {
+      for (j=0;j<rs-1;j++)
+      {
+        IMATELEM((*result),j+1,i+1) -= (*tocancel)[j];
+        IMATELEM((*result),j+1,i+2) -= (*tocancel)[j+1];
+      }
+      IMATELEM((*result),rs,i+1) -= (*tocancel)[rs-1];
+    }
+    else
+    {
+      (*result)[i+1] -= (*tocancel)[0];
+      (*result)[i+2] -= (*tocancel)[0];
+    }
+    i++;
+  }
+
+/*--------print Betti numbers for control---------------------------*/
+  for(i=rsmin;i<=rsmax;i++)
+  {
+    Print("%2d:",i);
+    for(j=1;j<=result->cols();j++)
+    {
+      Print(" %5d",IMATELEM(*result,i-rsmin+1,j));
+    }
+    PrintLn();
+  }
+  return result;
+}
+#endif
+
diff --git a/kernel/GBEngine/syz.h b/kernel/GBEngine/syz.h
new file mode 100644
index 0000000..ea6634b
--- /dev/null
+++ b/kernel/GBEngine/syz.h
@@ -0,0 +1,138 @@
+#ifndef SYZ_H
+#define SYZ_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: Resolutions
+*/
+#include <misc/mylimits.h>
+#include <kernel/structs.h>
+#include <polys/monomials/ring.h>
+#include <kernel/ideals.h>
+
+// Logarithm of estimate of maximal number of new components
+#define SYZ_SHIFT_MAX_NEW_COMP_ESTIMATE 8
+// Logarithm of "distance" between a new component and prev component
+#define SYZ_SHIFT_BASE_LOG (BIT_SIZEOF_LONG - 1 - SYZ_SHIFT_MAX_NEW_COMP_ESTIMATE)
+#define SYZ_SHIFT_BASE (((long)1) << SYZ_SHIFT_BASE_LOG)
+struct sSObject{
+                 poly  p;
+                 poly  p1,p2; /*- the pair p comes from -*/
+                 poly  lcm;   /*- the lcm of p1,p2 -*/
+                 poly  syz;   /*- the syzygy associated to p1,p2 -*/
+                 int   ind1,ind2; /*- the indeces of p1,p2 -*/
+                 poly  isNotMinimal;
+                 int   syzind;
+                 int   order;
+                 int   length;
+                 int   reference;
+               };
+typedef struct sSObject SObject;
+typedef SObject * SSet;
+typedef SSet * SRes;
+
+class ssyStrategy;
+typedef ssyStrategy * syStrategy;
+class ssyStrategy{
+  public:
+  int ** truecomponents;
+  long** ShiftedComponents;
+  int ** backcomponents;
+  int ** Howmuch;
+  int ** Firstelem;
+  int ** elemLength;
+  intvec ** weights;
+  intvec ** hilb_coeffs;
+  resolvente res;              //polynomial data for internal use only
+  resolvente orderedRes;       //polynomial data for internal use only
+  SRes resPairs;               //polynomial data for internal use only
+  intvec * Tl;
+  intvec * resolution;
+  intvec * cw;
+  intvec * betti;
+  kBucket_pt bucket;
+  kBucket_pt syz_bucket;
+  ring syRing;
+  resolvente fullres;
+  resolvente minres;
+  unsigned long ** sev;
+  int length;
+  int regularity;
+  short list_length;
+  short references;
+};
+
+void sySchreyersSyzygiesM(polyset F,int Fmax,polyset* Shdl,int* Smax,
+   BOOLEAN noSort);
+
+void sySchreyersSyzygiesB(polyset F,int Fmax,polyset* Shdl,int* Smax,
+   BOOLEAN noSort);
+
+resolvente sySchreyerResolvente(ideal arg, int maxlength, int * length,
+   BOOLEAN isMonomial=FALSE, BOOLEAN notReplace=FALSE);
+
+syStrategy sySchreyer(ideal arg, int maxlength);
+
+resolvente syResolvente(ideal arg, int maxlength, int * length,
+                        intvec *** weights, BOOLEAN minim);
+
+syStrategy syResolution(ideal arg, int maxlength,intvec * w, BOOLEAN minim);
+
+void syMinimizeResolvente(resolvente res, int length, int first);
+
+intvec * syBetti(resolvente res,int length, int * regularity,
+         intvec* weights=NULL,BOOLEAN tomin=TRUE, int * row_shift=NULL);
+
+ideal syMinBase(ideal arg);
+
+BOOLEAN syTestOrder(ideal i);
+
+void syReOrderResolventFB(resolvente res,int length, int initial=1);
+
+resolvente syLaScala1(ideal arg,int * length);
+syStrategy syLaScala3(ideal arg,int * length);
+
+syStrategy syLaScala(ideal arg, int& maxlength, intvec* weights = NULL);
+
+syStrategy syHilb(ideal arg,int * length);
+syStrategy syKosz(ideal arg,int * length);
+
+void syKillComputation(syStrategy syzstr, ring r=currRing);
+intvec * syBettiOfComputation(syStrategy syzstr, BOOLEAN minim=TRUE,int * row_shift=NULL, intvec *weights=NULL);
+
+
+int sySize(syStrategy syzstr);
+int syDim(syStrategy syzstr);
+syStrategy syCopy(syStrategy syzstr);
+void syPrint(syStrategy syzstr,   const char *currRingName /* = currRingHdl->id */);
+
+syStrategy syMinimize(syStrategy syzstr);
+void syKillEmptyEntres(resolvente res,int length);
+
+extern int *  currcomponents;
+extern long *  currShiftedComponents;
+
+void syDeletePair(SObject * so);
+void syInitializePair(SObject * so);
+void syCopyPair(SObject * argso, SObject * imso);
+void syCompactifyPairSet(SSet sPairs, int sPlength, int first);
+void syCompactify1(SSet sPairs, int* sPlength, int first);
+SRes syInitRes(ideal arg,int * length, intvec * Tl, intvec * cw=NULL);
+void syResetShiftedComponents(syStrategy syzstr, int index,int hilb=0);
+void syEnlargeFields(syStrategy syzstr,int index);
+void syEnterPair(syStrategy syzstr, SObject * so, int * sPlength,int index);
+SSet syChosePairs(syStrategy syzstr, int *index, int *howmuch, int * actdeg);
+int syInitSyzMod(syStrategy syzstr, int index, int init=17);
+long syReorderShiftedComponents(long * sc, int n);
+void syGaussForOne(ideal arg,int gen,int ModComp,int from=-1,int till=0);
+void syEnterPair(SSet sPairs, SObject * so, int * sPlength,int index);
+void syEnterPair(syStrategy syzstr, SObject * so, int * sPlength,int index);
+syStrategy syKosz(ideal arg,int * length);
+
+resolvente syReorder(resolvente res,int length,
+        syStrategy syzstr,BOOLEAN toCopy=TRUE,resolvente totake=NULL);
+resolvente syReorder(resolvente res,int length,
+        syStrategy syzstr,BOOLEAN toCopy/*=TRUE*/,resolvente totake/*=NULL*/);
+
+#endif
diff --git a/kernel/GBEngine/syz0.cc b/kernel/GBEngine/syz0.cc
new file mode 100644
index 0000000..e177996
--- /dev/null
+++ b/kernel/GBEngine/syz0.cc
@@ -0,0 +1,1068 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: resolutions
+*/
+
+
+
+
+
+#include <kernel/mod2.h>
+#include <misc/options.h>
+#include <omalloc/omalloc.h>
+#include <kernel/polys.h>
+#include <kernel/GBEngine/kstd1.h>
+#include <kernel/GBEngine/kutil.h>
+#include <kernel/combinatorics/stairc.h>
+//#include "cntrlc.h"
+#include <misc/intvec.h>
+#include <coeffs/numbers.h>
+#include <kernel/ideals.h>
+#include <misc/intvec.h>
+#include <polys/monomials/ring.h>
+#include <kernel/GBEngine/syz.h>
+#include <polys/kbuckets.h>
+#include <polys/prCopy.h>
+
+static void syInitSort(ideal arg,intvec **modcomp)
+{
+  int i,j,k,kk,kkk,jj;
+  idSkipZeroes(arg);
+  polyset F,oldF=arg->m;
+  int Fl=IDELEMS(arg);
+  int rkF=id_RankFreeModule(arg,currRing);
+  int syComponentOrder=currRing->ComponentOrder;
+
+  while ((Fl!=0) && (oldF[Fl-1]==NULL)) Fl--;
+  if (*modcomp!=NULL) delete modcomp;
+  *modcomp = new intvec(rkF+2);
+  F=(polyset)omAlloc0(IDELEMS(arg)*sizeof(poly));
+  j=0;
+  for(i=0;i<=rkF;i++)
+  {
+    k=0;
+    jj = j;
+    (**modcomp)[i] = j;
+    while (k<Fl)
+    {
+      while ((k<Fl) && (pGetComp(oldF[k]) != i)) k++;
+      if (k<Fl)
+      {
+        kk=jj;
+        while ((kk<Fl) && (F[kk]) && (pLmCmp(oldF[k],F[kk])!=syComponentOrder))
+        {
+            kk++;
+        }
+        for (kkk=j;kkk>kk;kkk--)
+        {
+          F[kkk] = F[kkk-1];
+        }
+        F[kk] = oldF[k];
+//Print("Element %d: ",kk);pWrite(F[kk]);
+        j++;
+        k++;
+      }
+    }
+  }
+  (**modcomp)[rkF+1] = Fl;
+  arg->m = F;
+  omFreeSize((ADDRESS)oldF,IDELEMS(arg)*sizeof(poly));
+}
+
+static void syCreatePairs(polyset F,int lini,int wend,int k,int j,int i,
+           polyset pairs,int regularPairs=0,ideal mW=NULL)
+{
+  int l,ii=0,jj;
+  poly p,q;
+
+  while (((k<wend) && (pGetComp(F[k]) == i)) ||
+         ((currRing->qideal!=NULL) && (k<regularPairs+IDELEMS(currRing->qideal))))
+  {
+    p = pOne();
+    if ((k<wend) && (pGetComp(F[k]) == i) && (k!=j))
+      pLcm(F[j],F[k],p);
+    else if (ii<IDELEMS(currRing->qideal))
+    {
+      q = pHead(F[j]);
+      if (mW!=NULL)
+      {
+        for(jj=1;jj<=(currRing->N);jj++)
+          pSetExp(q,jj,pGetExp(q,jj) -pGetExp(mW->m[pGetComp(q)-1],jj));
+        pSetm(q);
+      }
+      pLcm(q,currRing->qideal->m[ii],p);
+      if (mW!=NULL)
+      {
+        for(jj=1;jj<=(currRing->N);jj++)
+          pSetExp(p,jj,pGetExp(p,jj) +pGetExp(mW->m[pGetComp(p)-1],jj));
+        pSetm(p);
+      }
+      pDelete(&q);
+      k = regularPairs+ii;
+      ii++;
+    }
+    l=lini;
+    while ((l<k) && ((pairs[l]==NULL) || (!pDivisibleBy(pairs[l],p))))
+    {
+      if ((pairs[l]!=NULL) && (pDivisibleBy(p,pairs[l])))
+        pDelete(&(pairs[l]));
+      l++;
+    }
+    if (l==k)
+    {
+      pSetm(p);
+      pairs[l] = p;
+    }
+    else
+      pDelete(&p);
+    k++;
+  }
+}
+
+static poly syRedtail2(poly p, polyset redWith, intvec *modcomp)
+{
+  poly h, hn;
+  int hncomp,nxt;
+  int j;
+
+  h = p;
+  hn = pNext(h);
+  while(hn != NULL)
+  {
+    hncomp = pGetComp(hn);
+    j = (*modcomp)[hncomp];
+    nxt = (*modcomp)[hncomp+1];
+    while (j < nxt)
+    {
+      if (pLmDivisibleByNoComp(redWith[j], hn))
+      {
+        //if (TEST_OPT_PROT) PrintS("r");
+        hn = ksOldSpolyRed(redWith[j],hn);
+        if (hn == NULL)
+        {
+          pNext(h) = NULL;
+          return p;
+        }
+        hncomp = pGetComp(hn);
+        j = (*modcomp)[hncomp];
+        nxt = (*modcomp)[hncomp+1];
+      }
+      else
+      {
+        j++;
+      }
+    }
+    h = pNext(h) = hn;
+    hn = pNext(h);
+  }
+  return p;
+}
+
+/*2
+* computes the Schreyer syzygies in the local case
+* input: arg   (only allocated: Shdl, Smax)
+* output: Shdl, Smax
+*/
+static ideal sySchreyersSyzygiesFM(ideal arg,intvec ** modcomp)
+{
+  int Fl=IDELEMS(arg);
+  while ((Fl!=0) && (arg->m[Fl-1]==NULL)) Fl--;
+  ideal result=idInit(16,arg->rank+Fl);
+  polyset F=arg->m,*Shdl=&(result->m);
+  if (Fl==0) return result;
+
+  int i,j,l,k,totalToRed,ecartToRed,kk;
+  int bestEcart,totalmax,rkF,Sl=0,smax,tmax,tl;
+  int *ecartS, *ecartT, *totalS,
+    *totalT=NULL, *temp=NULL;
+  polyset pairs,S,T,ST/*,oldF*/;
+  poly p,q,toRed;
+  BOOLEAN notFound = FALSE;
+  intvec * newmodcomp = new intvec(Fl+2);
+  intvec * tempcomp;
+
+//Print("Naechster Modul\n");
+//idPrint(arg);
+/*-------------initializing the sets--------------------*/
+  ST=(polyset)omAlloc0(Fl*sizeof(poly));
+  S=(polyset)omAlloc0(Fl*sizeof(poly));
+  ecartS=(int*)omAlloc(Fl*sizeof(int));
+  totalS=(int*)omAlloc(Fl*sizeof(int));
+  T=(polyset)omAlloc0(2*Fl*sizeof(poly));
+  ecartT=(int*)omAlloc(2*Fl*sizeof(int));
+  totalT=(int*)omAlloc(2*Fl*sizeof(int));
+  pairs=(polyset)omAlloc0(Fl*sizeof(poly));
+
+  smax = Fl;
+  tmax = 2*Fl;
+  for (j=1;j<IDELEMS(arg);j++)
+  {
+    if (arg->m[j] != NULL)
+    {
+      assume (arg->m[j-1] != NULL);
+      assume (pGetComp(arg->m[j-1])-pGetComp(arg->m[j])<=0);
+    }
+  }
+  rkF=id_RankFreeModule(arg,currRing);
+/*----------------construction of the new ordering----------*/
+  if (rkF>0)
+    rSetSyzComp(rkF, currRing);
+  else
+    rSetSyzComp(1, currRing);
+/*----------------creating S--------------------------------*/
+  for(j=0;j<Fl;j++)
+  {
+    S[j] = pCopy(F[j]);
+    totalS[j] = p_LDeg(S[j],&k,currRing);
+    ecartS[j] = totalS[j]-p_FDeg(S[j],currRing);
+//Print("%d", pGetComp(S[j]));PrintS("  ");
+    p = S[j];
+    if (rkF==0) pSetCompP(p,1);
+    while (pNext(p)!=NULL) pIter(p);
+    pNext(p) = pHead(F[j]);
+    pIter(p);
+    if (rkF==0)
+      pSetComp(p,j+2);
+    else
+      pSetComp(p,rkF+j+1);
+    pSetmComp(p);
+  }
+//PrintLn();
+  if (rkF==0) rkF = 1;
+/*---------------creating the initial for T----------------*/
+  j=0;
+  l=-1;
+  totalmax=-1;
+  for (k=0;k<smax;k++)
+    if (totalS[k]>totalmax) totalmax=totalS[k];
+  for (kk=1;kk<=rkF;kk++)
+  {
+    for (k=0;k<=totalmax;k++)
+    {
+      for (l=0;l<smax;l++)
+      {
+        if ((pGetComp(S[l])==kk) && (totalS[l]==k))
+        {
+          ST[j] = S[l];
+          totalT[j] = totalS[l];
+          ecartT[j] = ecartS[l];
+//Print("%d", totalS[l]);PrintS("  ");
+          j++;
+        }
+      }
+    }
+  }
+//PrintLn();
+  for (j=0;j<smax;j++)
+  {
+     totalS[j] = totalT[j];
+     ecartS[j] = ecartT[j];
+  }
+
+/*---------------computing---------------------------------*/
+  for(j=0;j<smax;j++)
+  {
+    (*newmodcomp)[j+1] = Sl;
+    i = pGetComp(S[j]);
+    int syComponentOrder= currRing->ComponentOrder;
+    int lini,wend;
+    if (syComponentOrder==1)
+    {
+      lini=k=j+1;
+      wend=Fl;
+    }
+    else
+    {
+      lini=k=0;
+      while ((k<j) && (pGetComp(S[k]) != i)) k++;
+      wend=j;
+    }
+    if (TEST_OPT_PROT)
+    {
+      Print("(%d)",Fl-j);
+      mflush();
+    }
+    syCreatePairs(S,lini,wend,k,j,i,pairs);
+    for (k=lini;k<wend;k++)
+    {
+      if (pairs[k]!=NULL)
+      {
+/*--------------creating T----------------------------------*/
+        for (l=0;l<smax;l++)
+        {
+          ecartT[l] = ecartS[l];
+          totalT[l] = totalS[l];
+          T[l] = ST[l];
+        }
+        tl = smax;
+        tempcomp = ivCopy(*modcomp);
+/*--------------begin to reduce-----------------------------*/
+        toRed = ksOldCreateSpoly(S[j],S[k]);
+        ecartToRed = 1;
+        bestEcart = 1;
+        if (TEST_OPT_DEBUG)
+        {
+          PrintS("pair: ");pWrite0(S[j]);PrintS(" ");pWrite(S[k]);
+        }
+        if (TEST_OPT_PROT)
+        {
+           PrintS(".");
+           mflush();
+        }
+//Print("Reduziere Paar %d,%d (ecart %d): \n",j,k,ecartToRed);
+//Print("Poly %d: ",j);pWrite(S[j]);
+//Print("Poly %d: ",k);pWrite(S[k]);
+//Print("Spoly: ");pWrite(toRed);
+        while (pGetComp(toRed)<=rkF)
+        {
+          if (TEST_OPT_DEBUG)
+          {
+            PrintS("toRed: ");pWrite(toRed);
+          }
+/*
+*         if ((bestEcart) || (ecartToRed!=0))
+*         {
+*/
+            totalToRed = p_LDeg(toRed,&kk,currRing);
+            ecartToRed = totalToRed-p_FDeg(toRed,currRing);
+/*
+*         }
+*/
+//Print("toRed now (neuer ecart %d): ",ecartToRed);pWrite(toRed);
+          notFound = TRUE;
+          bestEcart = 32000;  //a very large integer
+          p = NULL;
+          int l=0;
+#define OLD_SEARCH
+#ifdef OLD_SEARCH
+          while ((l<tl) && (pGetComp(T[l])<pGetComp(toRed))) l++;
+          //assume (l==(**modcomp)[pGetComp(toRed)]);
+          while ((l<tl) && (notFound))
+#else
+          l = (**modcomp)[pGetComp(toRed)];
+          int kkk = (**modcomp)[pGetComp(toRed)+1];
+          while ((l<kkk) && (notFound))
+#endif
+          {
+            if ((ecartT[l]<bestEcart) && (pDivisibleBy(T[l],toRed)))
+            {
+              if (ecartT[l]<=ecartToRed) notFound = FALSE;
+              p = T[l];
+              bestEcart = ecartT[l];
+            }
+            l++;
+          }
+          if (p==NULL)
+          {
+            WerrorS("ideal not a standard basis");//no polynom for reduction
+            pDelete(&toRed);
+            for(k=j;k<Fl;k++) pDelete(&(pairs[k]));
+            omFreeSize((ADDRESS)pairs,Fl*sizeof(poly));
+            omFreeSize((ADDRESS)ST,Fl*sizeof(poly));
+            omFreeSize((ADDRESS)S,Fl*sizeof(poly));
+            omFreeSize((ADDRESS)T,tmax*sizeof(poly));
+            omFreeSize((ADDRESS)ecartT,tmax*sizeof(int));
+            omFreeSize((ADDRESS)totalT,tmax*sizeof(int));
+            omFreeSize((ADDRESS)ecartS,Fl*sizeof(int));
+            omFreeSize((ADDRESS)totalS,Fl*sizeof(int));
+            for(k=0;k<IDELEMS(result);k++) pDelete(&((*Shdl)[k]));
+            return result;
+          }
+          else
+          {
+//Print("reduced with (ecart %d): ",bestEcart);wrp(p);PrintLn();
+            if (notFound)
+            {
+              if (tl>=tmax)
+              {
+                pEnlargeSet(&T,tmax,16);
+                tmax += 16;
+                temp = (int*)omAlloc((tmax+16)*sizeof(int));
+                for(l=0;l<tmax;l++) temp[l]=totalT[l];
+                totalT = temp;
+                temp = (int*)omAlloc((tmax+16)*sizeof(int));
+                for(l=0;l<tmax;l++) temp[l]=ecartT[l];
+                ecartT = temp;
+              }
+//PrintS("t");
+              int comptR=pGetComp(toRed);
+              for (l=tempcomp->length()-1;l>comptR;l--)
+              {
+                if ((*tempcomp)[l]>0)
+                  (*tempcomp)[l]++;
+              }
+              l=0;
+              while ((l<tl) && (comptR>pGetComp(T[l]))) l++;
+              while ((l<tl) && (totalT[l]<=totalToRed)) l++;
+              for (kk=tl;kk>l;kk--)
+              {
+                T[kk]=T[kk-1];
+                totalT[kk]=totalT[kk-1];
+                ecartT[kk]=ecartT[kk-1];
+              }
+              q = pCopy(toRed);
+              pNorm(q);
+              T[l] = q;
+              totalT[l] = totalToRed;
+              ecartT[l] = ecartToRed;
+              tl++;
+            }
+            toRed = ksOldSpolyRed(p,toRed);
+          }
+        }
+//Print("toRed finally (neuer ecart %d): ",ecartToRed);pWrite(toRed);
+//PrintS("s");
+        if (pGetComp(toRed)>rkF)
+        {
+          if (Sl>=IDELEMS(result))
+          {
+            pEnlargeSet(Shdl,IDELEMS(result),16);
+            IDELEMS(result) += 16;
+          }
+          //p_Shift(&toRed,-rkF,currRing);
+          pNorm(toRed);
+          (*Shdl)[Sl] = toRed;
+          Sl++;
+        }
+/*----------------deleting all polys not from ST--------------*/
+        for(l=0;l<tl;l++)
+        {
+          kk=0;
+          while ((kk<smax) && (T[l] != S[kk])) kk++;
+          if (kk>=smax)
+          {
+            pDelete(&T[l]);
+//Print ("#");
+          }
+        }
+        delete tempcomp;
+      }
+    }
+    for(k=lini;k<wend;k++) pDelete(&(pairs[k]));
+  }
+  (*newmodcomp)[Fl+1] = Sl;
+  omFreeSize((ADDRESS)pairs,Fl*sizeof(poly));
+  omFreeSize((ADDRESS)ST,Fl*sizeof(poly));
+  omFreeSize((ADDRESS)S,Fl*sizeof(poly));
+  omFreeSize((ADDRESS)T,tmax*sizeof(poly));
+  omFreeSize((ADDRESS)ecartT,tmax*sizeof(int));
+  omFreeSize((ADDRESS)totalT,tmax*sizeof(int));
+  omFreeSize((ADDRESS)ecartS,Fl*sizeof(int));
+  omFreeSize((ADDRESS)totalS,Fl*sizeof(int));
+  delete *modcomp;
+  *modcomp = newmodcomp;
+  return result;
+}
+
+/*3
+*special Normalform for Schreyer in factor rings
+*/
+poly sySpecNormalize(poly toNorm,ideal mW=NULL)
+{
+  int j,i=0;
+  poly p;
+
+  if (toNorm==NULL) return NULL;
+  p = pHead(toNorm);
+  if (mW!=NULL)
+  {
+    for(j=1;j<=(currRing->N);j++)
+      pSetExp(p,j,pGetExp(p,j) -pGetExp(mW->m[pGetComp(p)-1],j));
+  }
+  while ((p!=NULL) && (i<IDELEMS(currRing->qideal)))
+  {
+    if (pDivisibleBy(currRing->qideal->m[i],p))
+    {
+      //pNorm(toNorm);
+      toNorm = ksOldSpolyRed(currRing->qideal->m[i],toNorm);
+      pDelete(&p);
+      if (toNorm==NULL) return NULL;
+      p = pHead(toNorm);
+      if (mW!=NULL)
+      {
+        for(j=1;j<=(currRing->N);j++)
+          pSetExp(p,j,pGetExp(p,j) -pGetExp(mW->m[pGetComp(p)-1],j));
+      }
+      i = 0;
+    }
+    else
+    {
+      i++;
+    }
+  }
+  pDelete(&p);
+  return toNorm;
+}
+
+/*2
+* computes the Schreyer syzygies in the global case
+* input: F
+* output: Shdl, Smax
+* modcomp, length stores the start position of the module comp. in arg
+*/
+static ideal sySchreyersSyzygiesFB(ideal arg,intvec ** modcomp,ideal mW,BOOLEAN redTail=TRUE)
+{
+  kBucket_pt sy0buck = kBucketCreate(currRing);
+
+  int Fl=IDELEMS(arg);
+  while ((Fl!=0) && (arg->m[Fl-1]==NULL)) Fl--;
+  ideal result=idInit(16,Fl);
+  int i,j,l,k,kkk,/*rkF,*/Sl=0,syComponentOrder=currRing->ComponentOrder;
+  int /*fstart,*/wend,lini,ltR,gencQ=0;
+  intvec *newmodcomp;
+  int *Flength;
+  polyset pairs,F=arg->m,*Shdl=&(result->m);
+  poly /*p,*/q,toRed,syz,lastmonom,multWith;
+  BOOLEAN isNotReduced=TRUE;
+
+//#define WRITE_BUCKETS
+#ifdef WRITE_BUCKETS
+  PrintS("Input: \n");
+  ideal twr=idHead(arg);
+  idPrint(arg);
+  idDelete(&twr);
+  if (modcomp!=NULL) (*modcomp)->show(0,0);
+#endif
+
+  newmodcomp = new intvec(Fl+2);
+  //for (j=0;j<Fl;j++) pWrite(F[j]);
+  //PrintLn();
+  if (currRing->qideal==NULL)
+    pairs=(polyset)omAlloc0(Fl*sizeof(poly));
+  else
+  {
+    gencQ = IDELEMS(currRing->qideal);
+    pairs=(polyset)omAlloc0((Fl+gencQ)*sizeof(poly));
+  }
+  // rkF=id_RankFreeModule(arg,currRing);
+  Flength = (int*)omAlloc0(Fl*sizeof(int));
+  for(j=0;j<Fl;j++)
+  {
+    Flength[j] = pLength(F[j]);
+  }
+  for(j=0;j<Fl;j++)
+  {
+    (*newmodcomp)[j+1] = Sl;
+    if (TEST_OPT_PROT)
+    {
+      Print("(%d)",Fl-j);
+      mflush();
+    }
+    i = pGetComp(F[j]);
+    if (syComponentOrder==1)
+    {
+      lini=k=j+1;
+      wend=Fl;
+    }
+    else
+    {
+      lini=k=0;
+      while ((k<j) && (pGetComp(F[k]) != i)) k++;
+      wend=j;
+    }
+    syCreatePairs(F,lini,wend,k,j,i,pairs,Fl,mW);
+    if (currRing->qideal!=NULL) wend = Fl+gencQ;
+    for (k=lini;k<wend;k++)
+    {
+      if (pairs[k]!=NULL)
+      {
+        if (TEST_OPT_PROT)
+        {
+           PrintS(".");
+           mflush();
+        }
+        //begins to construct the syzygy
+        if (k<Fl)
+        {
+          number an=nCopy(pGetCoeff(F[k])),bn=nCopy(pGetCoeff(F[j]));
+          /*int ct =*/ (void) ksCheckCoeff(&an, &bn, currRing->cf);
+          syz = pCopy(pairs[k]);
+          //syz->coef = nCopy(F[k]->coef);
+          syz->coef = an;
+          //syz->coef = nInpNeg(syz->coef);
+          pNext(syz) = pairs[k];
+          lastmonom = pNext(syz);
+          //lastmonom->coef = nCopy(F[j]->coef);
+          lastmonom->coef = bn;
+          lastmonom->coef = nInpNeg(lastmonom->coef);
+          pSetComp(lastmonom,k+1);
+        }
+        else
+        {
+          syz = pairs[k];
+          syz->coef = nCopy(currRing->qideal->m[k-Fl]->coef);
+          syz->coef = nInpNeg(syz->coef);
+          lastmonom = syz;
+          multWith = pDivide(syz,F[j]);
+          multWith->coef = nCopy(currRing->qideal->m[k-Fl]->coef);
+        }
+        pSetComp(syz,j+1);
+        pairs[k] = NULL;
+        //the next term of the syzygy
+        //constructs the spoly
+        if (TEST_OPT_DEBUG)
+        {
+          if (k<Fl)
+          {
+            PrintS("pair: ");pWrite0(F[j]);PrintS("  ");pWrite(F[k]);
+          }
+          else
+          {
+            PrintS("pair: ");pWrite0(F[j]);PrintS("  ");pWrite(currRing->qideal->m[k-Fl]);
+          }
+        }
+        if (k<Fl)
+          toRed = ksOldCreateSpoly(F[j],F[k]);
+        else
+        {
+          q = pMult_mm(pCopy(F[j]),multWith);
+          toRed = sySpecNormalize(q,mW);
+          pDelete(&multWith);
+        }
+        kBucketInit(sy0buck,toRed,-1);
+        toRed = kBucketGetLm(sy0buck);
+        isNotReduced = TRUE;
+        while (toRed!=NULL)
+        {
+          if (TEST_OPT_DEBUG)
+          {
+            PrintS("toRed: ");pWrite(toRed);
+          }
+//          l=0;
+//          while ((l<Fl) && (!pDivisibleBy(F[l],toRed))) l++;
+//          if (l>=Fl)
+          l = (**modcomp)[pGetComp(toRed)+1]-1;
+          kkk = (**modcomp)[pGetComp(toRed)];
+          while ((l>=kkk) && (!pDivisibleBy(F[l],toRed))) l--;
+#ifdef WRITE_BUCKETS
+          kBucketClear(sy0buck,&toRed,&ltR);
+          printf("toRed in Pair[%d, %d]:", j, k);
+          pWrite(toRed);
+          kBucketInit(sy0buck,toRed,-1);
+#endif
+
+          if (l<kkk)
+          {
+            if ((currRing->qideal!=NULL) && (isNotReduced))
+            {
+              kBucketClear(sy0buck,&toRed,&ltR);
+              toRed = sySpecNormalize(toRed,mW);
+#ifdef WRITE_BUCKETS
+              printf("toRed in Pair[%d, %d]:", j, k);
+              pWrite(toRed);
+#endif
+              kBucketInit(sy0buck,toRed,-1);
+              toRed = kBucketGetLm(sy0buck);
+              isNotReduced = FALSE;
+            }
+            else
+            {
+              //no polynom for reduction
+              WerrorS("ideal not a standard basis");
+              pDelete(&toRed);
+              pDelete(&syz);
+              for(k=j;k<Fl;k++) pDelete(&(pairs[k]));
+              omFreeSize((ADDRESS)pairs,(Fl + gencQ)*sizeof(poly));
+              for(k=0;k<IDELEMS(result);k++) pDelete(&((*Shdl)[k]));
+
+	      kBucketDestroy(&(sy0buck));
+              return result;
+            }
+          }
+          else
+          {
+            //the next monom of the syzygy
+            isNotReduced = TRUE;
+            if (TEST_OPT_DEBUG)
+            {
+              PrintS("reduced with: ");pWrite(F[l]);
+            }
+            pNext(lastmonom) = pHead(toRed);
+            pIter(lastmonom);
+            lastmonom->coef = nDiv(lastmonom->coef,F[l]->coef);
+            //lastmonom->coef = nInpNeg(lastmonom->coef);
+            pSetComp(lastmonom,l+1);
+            //computes the new toRed
+            number up = kBucketPolyRed(sy0buck,F[l],Flength[l],NULL);
+            if (! nIsOne(up))
+            {
+              // Thomas: Now do whatever you need to do
+#ifdef WRITE_BUCKETS
+              PrintS("multiplied with: ");nWrite(up);PrintLn();
+#endif
+              pMult_nn(syz,up);
+            }
+            nDelete(&up);
+
+            toRed = kBucketGetLm(sy0buck);
+            //the module component of the new monom
+//pWrite(toRed);
+          }
+        }
+        kBucketClear(sy0buck,&toRed,&ltR); //Zur Sichereheit
+//PrintLn();
+        if (syz!=NULL)
+        {
+          if (Sl>=IDELEMS(result))
+          {
+            pEnlargeSet(Shdl,IDELEMS(result),16);
+            IDELEMS(result) += 16;
+          }
+          pNorm(syz);
+          if (BTEST1(OPT_REDTAIL) && redTail)
+          {
+            (*newmodcomp)[j+2] = Sl;
+            (*Shdl)[Sl] = syRedtail2(syz,*Shdl,newmodcomp);
+            (*newmodcomp)[j+2] = 0;
+          }
+          else
+            (*Shdl)[Sl] = syz;
+          Sl++;
+        }
+      }
+    }
+//    for(k=j;k<Fl;k++) pDelete(&(pairs[k]));
+  }
+  (*newmodcomp)[Fl+1] = Sl;
+  if (currRing->qideal==NULL)
+    omFreeSize((ADDRESS)pairs,Fl*sizeof(poly));
+  else
+    omFreeSize((ADDRESS)pairs,(Fl+IDELEMS(currRing->qideal))*sizeof(poly));
+  omFreeSize((ADDRESS)Flength,Fl*sizeof(int));
+  delete *modcomp;
+  *modcomp = newmodcomp;
+
+  kBucketDestroy(&(sy0buck));
+  return result;
+}
+
+void syReOrderResolventFB(resolvente res,int length, int initial)
+{
+  int syzIndex=length-1,i,j;
+  poly p;
+
+  while ((syzIndex!=0) && (res[syzIndex]==NULL)) syzIndex--;
+  while (syzIndex>=initial)
+  {
+    for(i=0;i<IDELEMS(res[syzIndex]);i++)
+    {
+      p = res[syzIndex]->m[i];
+
+      while (p!=NULL)
+      {
+        if (res[syzIndex-1]->m[pGetComp(p)-1]!=NULL)
+        {
+          for(j=1;j<=(currRing->N);j++)
+          {
+            pSetExp(p,j,pGetExp(p,j)
+                        -pGetExp(res[syzIndex-1]->m[pGetComp(p)-1],j));
+          }
+        }
+        else
+          PrintS("error in the resolvent\n");
+        pSetm(p);
+        pIter(p);
+      }
+    }
+    syzIndex--;
+  }
+}
+
+#if 0
+static void syMergeSortResolventFB(resolvente res,int length, int initial=1)
+{
+  int syzIndex=length-1,i,j;
+  poly qq,pp,result=NULL;
+  poly p;
+
+  while ((syzIndex!=0) && (res[syzIndex]==NULL)) syzIndex--;
+  while (syzIndex>=initial)
+  {
+    for(i=0;i<IDELEMS(res[syzIndex]);i++)
+    {
+      p = res[syzIndex]->m[i];
+      if (p != NULL)
+      {
+        for (;;)
+        {
+          qq = p;
+          for(j=1;j<=(currRing->N);j++)
+          {
+            pSetExp(p,j,pGetExp(p,j)
+                        -pGetExp(res[syzIndex-1]->m[pGetComp(p)-1],j));
+          }
+          pSetm(p);
+          for (;;)
+          {
+            if (pNext(p) == NULL)
+            {
+              pAdd(result, qq);
+              break;
+            }
+            pp = pNext(p);
+            for(j=1;j<=(currRing->N);j++)
+            {
+              pSetExp(pp,j,pGetExp(pp,j)
+                          -pGetExp(res[syzIndex-1]->m[pGetComp(pp)-1],j));
+            }
+            pSetm(pp);
+            if (pCmp(p,pNext(p)) != 1)
+            {
+              pp = p;
+              pIter(p);
+              pNext(pp) = NULL;
+              result = pAdd(result, qq);
+              break;
+            }
+            pIter(p);
+          }
+        }
+      }
+      res[syzIndex]->m[i] = p;
+    }
+    syzIndex--;
+  }
+}
+#endif
+
+BOOLEAN syTestOrder(ideal M)
+{
+  int i=id_RankFreeModule(M,currRing);
+  if (i == 0) return FALSE;
+  int j=0;
+
+  while ((currRing->order[j]!=ringorder_c) && (currRing->order[j]!=ringorder_C))
+    j++;
+  if (currRing->order[j+1]!=0)
+    return TRUE;
+  return FALSE;
+}
+
+static void idShift(ideal arg,int index)
+{
+  int i,j=rGetMaxSyzComp(index, currRing);
+  for (i=0;i<IDELEMS(arg);i++)
+  {
+    if (arg->m[i]!=NULL)
+      p_Shift(&arg->m[i],-j,currRing);
+  }
+}
+
+#if 0 /*debug only */
+static void syPrintResolution(resolvente res,int start,int length)
+{
+  while ((start < length) && (res[start]))
+  {
+    Print("Syz(%d): \n",start);
+    idTest(res[start]);
+    //idPrint(res[start]);
+    start++;
+  }
+}
+#endif
+
+resolvente sySchreyerResolvente(ideal arg, int maxlength, int * length,
+                                BOOLEAN isMonomial, BOOLEAN /*notReplace*/)
+{
+  ideal mW=NULL;
+  int i,syzIndex = 0,j=0;
+  intvec * modcomp=NULL,*w=NULL;
+  // int ** wv=NULL;
+  tHomog hom=(tHomog)idHomModule(arg,NULL,&w);
+  ring origR = currRing;
+  ring syRing = NULL;
+
+  if ((!isMonomial) && syTestOrder(arg))
+  {
+    WerrorS("sres only implemented for modules with ordering  ..,c or ..,C");
+    return NULL;
+  }
+  *length = 4;
+  resolvente res = (resolvente)omAlloc0(4*sizeof(ideal)),newres;
+  res[0] = idCopy(arg);
+
+  while ((!idIs0(res[syzIndex])) && ((maxlength==-1) || (syzIndex<maxlength)))
+  {
+    i = IDELEMS(res[syzIndex]);
+    //while ((i!=0) && (!res[syzIndex]->m[i-1])) i--;
+    if (syzIndex+1==*length)
+    {
+      newres = (resolvente)omAlloc0((*length+4)*sizeof(ideal));
+      // for (j=0;j<*length+4;j++) newres[j] = NULL;
+      for (j=0;j<*length;j++) newres[j] = res[j];
+      omFreeSize((ADDRESS)res,*length*sizeof(ideal));
+      *length += 4;
+      res=newres;
+    }
+
+    if ((hom==isHomog)|| (rHasGlobalOrdering(origR)))
+    {
+      if (syzIndex==0) syInitSort(res[0],&modcomp);
+
+      if ((syzIndex==0) && !rRing_has_CompLastBlock(currRing))
+        res[syzIndex+1] = sySchreyersSyzygiesFB(res[syzIndex],&modcomp,mW,FALSE);
+      else
+        res[syzIndex+1] = sySchreyersSyzygiesFB(res[syzIndex],&modcomp,mW);
+
+      mW = res[syzIndex];
+    }
+//idPrint(res[syzIndex+1]);
+
+    if ( /*(*/ syzIndex==0 /*)*/ )
+    {
+      if ((hom==isHomog)|| (rHasGlobalOrdering(origR)))
+      {
+        syRing = rAssure_CompLastBlock(origR, TRUE);
+        if (syRing != origR)
+        {
+	  rChangeCurrRing(syRing);
+          for (i=0; i<IDELEMS(res[1]); i++)
+          {
+            res[1]->m[i] = prMoveR( res[1]->m[i], origR, syRing);
+          }
+        }
+        idTest(res[1]);
+      }
+      else
+      {
+        syRing = rAssure_SyzComp_CompLastBlock(origR, TRUE);
+        if (syRing != origR)
+        {
+	  rChangeCurrRing(syRing);
+          for (i=0; i<IDELEMS(res[0]); i++)
+          {
+            res[0]->m[i] = prMoveR( res[0]->m[i], origR, syRing);
+          }
+        }
+        idTest(res[0]);
+      }
+    }
+    if ((hom!=isHomog) && (rHasLocalOrMixedOrdering(origR)))
+    {
+      if (syzIndex==0) syInitSort(res[0],&modcomp);
+      res[syzIndex+1] = sySchreyersSyzygiesFM(res[syzIndex],&modcomp);
+    }
+    syzIndex++;
+    if (TEST_OPT_PROT) Print("[%d]\n",syzIndex);
+  }
+  //syPrintResolution(res,1,*length);
+  if ((hom!=isHomog) && (rHasLocalOrMixedOrdering(origR)))
+  {
+    syzIndex = 1;
+    while ((syzIndex < *length) && (!idIs0(res[syzIndex])))
+    {
+      idShift(res[syzIndex],syzIndex);
+      syzIndex++;
+    }
+  }
+  if ((hom==isHomog) || (rHasGlobalOrdering(origR)))
+    syzIndex = 1;
+  else
+    syzIndex = 0;
+  syReOrderResolventFB(res,*length,syzIndex+1);
+  if (/*ringOrderChanged:*/ origR!=syRing && syRing != NULL)
+  {
+    rChangeCurrRing(origR);
+    // Thomas: Here I assume that all (!) polys of res live in tmpR
+    while ((syzIndex < *length) && (res[syzIndex]))
+    {
+      for (i=0;i<IDELEMS(res[syzIndex]);i++)
+      {
+        if (res[syzIndex]->m[i])
+        {
+          res[syzIndex]->m[i] = prMoveR( res[syzIndex]->m[i], syRing, origR);
+        }
+      }
+      syzIndex++;
+    }
+//    j = 0; while (currRing->order[j]!=0) j++; // What was this for???!
+    rDelete(syRing);
+  }
+  else
+  {
+    // Thomas -- are you sure that you have to "reorder" here?
+    while ((syzIndex < *length) && (res[syzIndex]))
+    {
+      for (i=0;i<IDELEMS(res[syzIndex]);i++)
+      {
+        if (res[syzIndex]->m[i])
+          res[syzIndex]->m[i] = pSortCompCorrect(res[syzIndex]->m[i]);
+      }
+      syzIndex++;
+    }
+  }
+  if ((hom==isHomog) || (rHasGlobalOrdering(origR)))
+  {
+    if (res[1]!=NULL)
+    {
+      syReOrderResolventFB(res,2,1);
+      for (i=0;i<IDELEMS(res[1]);i++)
+      {
+        if (res[1]->m[i])
+          res[1]->m[i] = pSort(res[1]->m[i]);
+      }
+    }
+  }
+  //syPrintResolution(res,0,*length);
+
+  //syMergeSortResolventFB(res,*length);
+  if (modcomp!=NULL) delete modcomp;
+  if (w!=NULL) delete w;
+  return res;
+}
+
+syStrategy sySchreyer(ideal arg, int maxlength)
+{
+  int rl;
+  resolvente fr = sySchreyerResolvente(arg,maxlength,&(rl));
+  if (fr==NULL) return NULL;
+
+  // int typ0;
+  syStrategy result=(syStrategy)omAlloc0(sizeof(ssyStrategy));
+  result->length=rl;
+  result->fullres = (resolvente)omAlloc0((rl /*result->length*/+1)*sizeof(ideal));
+  for (int i=rl /*result->length*/-1;i>=0;i--)
+  {
+    if (fr[i]!=NULL)
+      result->fullres[i] = fr[i];
+      fr[i] = NULL;
+  }
+  if (currRing->qideal!=NULL)
+  {
+    for (int i=0; i<rl; i++)
+    {
+      if (result->fullres[i]!=NULL)
+      {
+        ideal t=kNF(currRing->qideal,NULL,result->fullres[i]);
+        idDelete(&result->fullres[i]);
+        result->fullres[i]=t;
+        if (i<rl-1)
+        {
+          for(int j=IDELEMS(t)-1;j>=0; j--)
+          {
+            if ((t->m[j]==NULL) && (result->fullres[i+1]!=NULL))
+            {
+              for(int k=IDELEMS(result->fullres[i+1])-1;k>=0; k--)
+              {
+                if (result->fullres[i+1]->m[k]!=NULL)
+                {
+                  pDeleteComp(&(result->fullres[i+1]->m[k]),j+1);
+                }
+              }
+            }
+          }
+        }
+        idSkipZeroes(result->fullres[i]);
+      }
+    }
+    if ((rl>maxlength) && (result->fullres[rl-1]!=NULL))
+    {
+      idDelete(&result->fullres[rl-1]);
+    }
+  }
+  omFreeSize((ADDRESS)fr,(rl /*result->length*/)*sizeof(ideal));
+  return result;
+}
+
diff --git a/kernel/GBEngine/syz1.cc b/kernel/GBEngine/syz1.cc
new file mode 100644
index 0000000..8efc418
--- /dev/null
+++ b/kernel/GBEngine/syz1.cc
@@ -0,0 +1,2688 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: resolutions
+*/
+
+
+
+
+#include <kernel/mod2.h>
+
+#include <misc/mylimits.h>
+#include <omalloc/omalloc.h>
+
+#include <misc/options.h>
+#include <misc/intvec.h>
+#include <coeffs/numbers.h>
+
+#include <polys/monomials/ring.h>
+#include <polys/kbuckets.h>
+#include <polys/prCopy.h>
+
+#include <kernel/polys.h>
+
+#include <kernel/GBEngine/kstd1.h>
+#include <kernel/GBEngine/kutil.h>
+#include <kernel/combinatorics/stairc.h>
+//#include "cntrlc.h"
+#include <kernel/ideals.h>
+#include <kernel/GBEngine/syz.h>
+// #include <kernel/idrec.h>
+
+extern void p_Setm_Syz(poly p, ring r,
+                       int* Components, long* ShiftedComponents);
+
+/*--------------static variables------------------------*/
+/*---points to the real components, shifted of the actual module-*/
+int *  currcomponents=NULL;
+long *  currShiftedComponents=NULL;
+
+
+/*---head-term-polynomials for the reduction------------*/
+static poly redpol=NULL;
+/*---counts number of applications of GM-criteria-------*/
+//static int crit;
+//static int euler;
+
+/*3
+* deletes all entres of a pair
+*/
+void syDeletePair(SObject * so)
+{
+  pDelete(&(*so).p);
+  pDelete(&(*so).lcm);
+  pDelete(&(*so).syz);
+  (*so).p1 = NULL;
+  (*so).p2 = NULL;
+  (*so).ind1 = 0;
+  (*so).ind2 = 0;
+  (*so).syzind = -1;
+  (*so).order = 0;
+  (*so).isNotMinimal = NULL;
+  (*so).length = -1;
+  (*so).reference = -1;
+}
+
+/*3
+* initializes all entres of a pair
+*/
+void syInitializePair(SObject * so)
+{
+  (*so).p = NULL;
+  (*so).lcm = NULL;
+  (*so).syz = NULL;
+  (*so).p1 = NULL;
+  (*so).p2 = NULL;
+  (*so).ind1 = 0;
+  (*so).ind2 = 0;
+  (*so).syzind = -1;
+  (*so).order = 0;
+  (*so).isNotMinimal = NULL;
+  (*so).length = -1;
+  (*so).reference = -1;
+}
+
+/*3
+* puts all entres of a pair to another
+*/
+void syCopyPair(SObject * argso, SObject * imso)
+{
+  *imso=*argso;
+  (*argso).p = NULL;
+  (*argso).p1 = NULL;
+  (*argso).p2 = NULL;
+  (*argso).lcm = NULL;
+  (*argso).syz = NULL;
+  (*argso).ind1 = 0;
+  (*argso).ind2 = 0;
+  (*argso).syzind = -1;
+  (*argso).order = 0;
+  (*argso).isNotMinimal = NULL;
+  (*argso).length = -1;
+  (*argso).reference = -1;
+}
+
+/*3
+* deletes empty objects from a pair set beginning with
+* pair first
+* assumes a pair to be empty if .lcm does so
+*/
+void syCompactifyPairSet(SSet sPairs, int sPlength, int first)
+{
+  int k=first,kk=0;
+
+  while (k+kk<sPlength)
+  {
+    if (sPairs[k+kk].lcm!=NULL)
+    {
+      if (kk>0) syCopyPair(&sPairs[k+kk],&sPairs[k]);
+      k++;
+    }
+    else
+    {
+      kk++;
+    }
+  }
+  while (k<sPlength)
+  {
+    syInitializePair(&sPairs[k]);
+    k++;
+  }
+}
+
+/*3
+* deletes empty objects from a pair set beginning with
+* pair first
+* assumes a pair to be empty if .lcm does so
+*/
+void syCompactify1(SSet sPairs, int* sPlength, int first)
+{
+  int k=first,kk=0;
+
+  while (k+kk<*sPlength)
+  {
+    if (sPairs[k+kk].lcm!=NULL)
+    {
+      if (kk>0) syCopyPair(&sPairs[k+kk],&sPairs[k]);
+      k++;
+    }
+    else
+    {
+      kk++;
+    }
+  }
+  while (k<*sPlength)
+  {
+    syInitializePair(&sPairs[k]);
+    k++;
+  }
+  *sPlength -= kk;
+}
+
+/*3
+* replaces comp1dpc during homogeneous syzygy-computations
+* compares with components of currcomponents instead of the
+* exp[0]
+*/
+
+#ifdef PDEBUG
+static int syzcomp2dpc_test(poly p1, poly p2)
+{
+  long c1, c2, cc1, cc2, ccc1, ccc2, ec1, ec2;
+  c1 = pGetComp(p1);
+  c2 = pGetComp(p2);
+  cc1 = currcomponents[c1];
+  cc2 = currcomponents[c2];
+  ccc1 = currShiftedComponents[cc1];
+  ccc2 = currShiftedComponents[cc2];
+  ec1 = p1->exp[currRing->typ[1].data.syzcomp.place];
+  ec2 = p2->exp[currRing->typ[1].data.syzcomp.place];
+
+  if (ec1 != ccc1)
+  {
+    Warn("Shifted comp of p1 out of sync. should %d, is %d", ccc1, ec1);
+    //mmDBInfoBlock(p1);
+  }
+  if (ec2 != ccc2)
+  {
+    Warn("Shifted comp of p2 out of sync. should %d, is %d", ccc2, ec2);
+    //mmDBInfoBlock(p2);
+  }
+
+  if (c1 == c2)
+  {
+    assume(ccc1 == ccc2);
+  }
+  else if (cc1 > cc2)
+  {
+    assume(ccc1 > ccc2);
+  }
+  else
+  {
+    assume (cc1 < cc2);
+    assume (ccc1 < ccc2);
+  }
+  int o1=pGetOrder(p1), o2=pGetOrder(p2);
+  if (o1 > o2) return 1;
+  if (o1 < o2) return -1;
+
+  //if (o1>0)
+  {
+    int i = (currRing->N);
+    while ((i>1) && (pGetExp(p1,i)==pGetExp(p2,i)))
+      i--;
+    //(*orderingdepth)[(currRing->N)-i]++;
+    if (i>1)
+    {
+      if (pGetExp(p1,i) < pGetExp(p2,i)) return 1;
+      return -1;
+    }
+  }
+  o1=pGetComp(p1);
+  o2=pGetComp(p2);
+  if (o1==o2/*pGetComp(p1)==pGetComp(p2)*/) return 0;
+  if (currcomponents[o1]>currcomponents[o2]) return 1;
+  return -1;
+}
+#endif // PDEBUG
+
+poly syRedtail (poly p, syStrategy syzstr, int index)
+{
+  poly h, hn;
+  int j,pos;
+  ideal redWith=syzstr->orderedRes[index];
+
+  h = p;
+  hn = pNext(h);
+  while(hn != NULL)
+  {
+    j = syzstr->Firstelem[index-1][pGetComp(hn)]-1;
+    if (j>=0)
+    {
+      pos = j+syzstr->Howmuch[index-1][pGetComp(hn)];
+      while (j < pos)
+      {
+        if (pLmDivisibleByNoComp(redWith->m[j], hn))
+        {
+          //hn = sySPolyRed(hn,redWith->m[j]);
+          hn = ksOldSpolyRed(redWith->m[j],hn);
+          if (hn == NULL)
+          {
+            pNext(h) = NULL;
+            return p;
+          }
+          j = syzstr->Firstelem[index-1][pGetComp(hn)]-1;
+          pos = j+syzstr->Howmuch[index-1][pGetComp(hn)];
+        }
+        else
+        {
+          j++;
+        }
+      }
+    }
+    h = pNext(h) = hn;
+    hn = pNext(h);
+  }
+  return p;
+}
+
+
+/*3
+* local procedure for of syInitRes for the module case
+*/
+static int syChMin(intvec * iv)
+{
+  int i,j=-1,r=-1;
+
+  for (i=iv->length()-1;i>=0;i--)
+  {
+    if ((*iv)[i]>=0)
+    {
+      if ((j<0) || ((*iv)[i]<j))
+      {
+        j = (*iv)[i];
+        r = i;
+      }
+    }
+  }
+  return r;
+}
+
+/*3
+* initialize the resolution and puts in the argument as
+* zeroth entre, length must be > 0
+* assumes that the basering is degree-compatible
+*/
+SRes syInitRes(ideal arg,int * length, intvec * Tl, intvec * cw)
+{
+  if (idIs0(arg)) return NULL;
+  SRes resPairs = (SRes)omAlloc0(*length*sizeof(SSet));
+  resPairs[0] = (SSet)omAlloc0(IDELEMS(arg)*sizeof(SObject));
+  intvec * iv=NULL;
+  int i,j;
+
+  if (id_RankFreeModule(arg,currRing)==0)
+  {
+    iv = idSort(arg);
+    for (i=0;i<IDELEMS(arg);i++)
+    {
+      (resPairs[0])[i].syz = /*pCopy*/(arg->m[(*iv)[i]-1]);
+      arg->m[(*iv)[i]-1] = NULL;
+      (resPairs[0])[i].order = pTotaldegree((resPairs[0])[i].syz);
+    }
+  }
+  else
+  {
+    iv = new intvec(IDELEMS(arg),1,-1);
+    for (i=0;i<IDELEMS(arg);i++)
+    {
+      (*iv)[i] = pTotaldegree(arg->m[i])+(*cw)[pGetComp(arg->m[i])-1];
+    }
+    for (i=0;i<IDELEMS(arg);i++)
+    {
+      j = syChMin(iv);
+      if (j<0) break;
+      (resPairs[0])[i].syz = arg->m[j];
+      arg->m[j] = NULL;
+      (resPairs[0])[i].order = (*iv)[j];
+      (*iv)[j] = -1;
+    }
+  }
+  if (iv!=NULL)  delete iv;
+  (*Tl)[0] = IDELEMS(arg);
+  return resPairs;
+}
+
+// rearrange shifted components
+long syReorderShiftedComponents(long * sc, int n)
+{
+  long holes = 0;
+  int i;
+  long new_comps = 0, new_space, max;
+
+  // count number of holes
+  for (i=1; i<n; i++)
+  {
+    if (sc[i-1] + 1 < sc[i]) holes++;
+  }
+
+  if (LONG_MAX - SYZ_SHIFT_BASE <= sc[n-1])
+  {
+    // need new components
+    new_comps = (((long) 1) << SYZ_SHIFT_MAX_NEW_COMP_ESTIMATE) - 1;
+    max = LONG_MAX;
+  }
+  else
+  {
+    max = sc[n-1] + SYZ_SHIFT_BASE;
+  }
+
+  // no we arrange things such that
+  // (n - holes) + holes*new_space + new_comps*SYZ_SHIFT_BASE= LONG_MAX
+  new_space = (max - n + holes - new_comps*SYZ_SHIFT_BASE) / holes;
+
+  assume(new_space < SYZ_SHIFT_BASE && new_space >= 4);
+
+  long* tc = ( long*) omAlloc(n*sizeof(long));
+  tc[0] = sc[0];
+  // rearrange things
+  for (i=1; i<n; i++)
+  {
+    if (sc[i-1] + 1 < sc[i])
+    {
+      tc[i] = tc[i-1] + new_space;
+    }
+    else
+    {
+      tc[i] = tc[i-1] + 1;
+    }
+    assume(tc[i] > tc[i-1]);
+  }
+
+  assume(LONG_MAX -  SYZ_SHIFT_BASE > tc[n-1]);
+#ifdef HAVE_ASSUME
+  for (i=1; i<n; i++)
+  {
+    assume(tc[i] >= 0);
+    assume(tc[i-1] + 1 <= tc[i]);
+  }
+#endif
+
+  omMemcpyW(sc, tc, n);
+  omFreeSize(tc, n*sizeof(long));
+  return new_space;
+}
+
+// this make a Setm on p
+static void pResetSetm(poly p)
+{
+#ifdef PDEBUG
+  poly q = p;
+#endif
+  while (p!= NULL)
+  {
+    pSetm(p);
+    pIter(p);
+  }
+#ifdef PDEBUG
+  pTest(q);
+#endif
+}
+
+void syResetShiftedComponents(syStrategy syzstr, int index,int hilb)
+{
+  assume(index > 0);
+  int i;
+  if (syzstr->res[index] != NULL)
+  {
+    long * prev_s;
+    int* prev_c;
+    int p_length;
+    rGetSComps(&prev_c, &prev_s, &p_length, currRing);
+    currcomponents = syzstr->truecomponents[index-1];
+    currShiftedComponents = syzstr->ShiftedComponents[index-1];
+    rChangeSComps(currcomponents,
+                  currShiftedComponents,
+                  IDELEMS(syzstr->res[index-1]), currRing);
+    if (hilb==0)
+    {
+      ideal id = syzstr->res[index];
+      for (i=0; i<IDELEMS(id); i++)
+      {
+        pResetSetm(id->m[i]);
+      }
+    }
+    else if (hilb==1)
+    {
+      assume (index>1);
+      assume (syzstr->resPairs[index-1]!=NULL);
+      SSet Pairs=syzstr->resPairs[index-1];
+      SSet Pairs1=syzstr->resPairs[index];
+      int till=(*syzstr->Tl)[index-1];
+      for (i=0;i<till;i++)
+      {
+        if (Pairs[i].syz!=NULL)
+          pResetSetm(Pairs[i].syz);
+      }
+      till=(*syzstr->Tl)[index];
+      for (i=0;i<till;i++)
+      {
+        if (Pairs1[i].p!=NULL)
+          pResetSetm(Pairs1[i].p);
+      }
+    }
+    currcomponents  = prev_c;
+    currShiftedComponents = prev_s;
+    rChangeSComps(prev_c, prev_s, p_length, currRing);
+  }
+}
+
+/*3
+* determines the place of a polynomial in the right ordered resolution
+* set the vectors of truecomponents
+*/
+static BOOLEAN syOrder(poly p,syStrategy syzstr,int index,
+                    int realcomp)
+{
+  int i=IDELEMS(syzstr->res[index-1])+1,j=0,k,tc,orc,ie=realcomp-1;
+  int *trind1=syzstr->truecomponents[index-1];
+  int *trind=syzstr->truecomponents[index];
+  long *shind=syzstr->ShiftedComponents[index];
+  int *bc=syzstr->backcomponents[index];
+  int *F1=syzstr->Firstelem[index-1];
+  int *H1=syzstr->Howmuch[index-1];
+  polyset o_r=syzstr->orderedRes[index]->m;
+  BOOLEAN ret = FALSE;
+
+  // if != 0, then new element can go into same component
+  // i.e., we do not need to leave space in shifted components
+  long same_comp = 0;
+
+  if (p==NULL) return FALSE;
+  if (realcomp==0) realcomp=1;
+
+  if (index>1)
+    tc = trind1[pGetComp(p)]-1;
+  else
+    tc = pGetComp(p)-1;
+  loop         //while ((j<ie) && (trind1[orc]<=tc+1))
+  {
+    if (j>=ie)
+      break;
+    else
+    {
+      orc = pGetComp(o_r[j]);
+      if (trind1[orc]>tc+1) break;
+      else if (trind1[orc] == tc+1)
+      {
+        same_comp = 1;
+      }
+      else
+      {
+        assume(same_comp == 0);
+      }
+      j += H1[orc];
+    }
+  }
+  if (j>ie)
+  {
+    WerrorS("orderedRes to small");
+    return FALSE;
+  }
+  ie++;
+  if (j == (ie -1))
+  {
+    // new element is the last in ordered module
+    if (same_comp == 0)
+      same_comp = SYZ_SHIFT_BASE;
+
+    // test wheter we have enough space for new shifted component
+    if ((LONG_MAX - same_comp) <= shind[ie-1])
+    {
+      long new_space = syReorderShiftedComponents(shind, ie);
+      assume((LONG_MAX - same_comp) > shind[ie-1]);
+      ret = TRUE;
+      if (TEST_OPT_PROT) Print("(T%ld)", new_space);
+    }
+
+    // yes, then set new shifted component
+    assume(ie == 1 || shind[ie-1] > 0);
+    shind[ie] = shind[ie-1] + same_comp;
+  }
+  else
+  {
+    // new element must come in between
+    // i.e. at place j+1
+    long prev, next;
+
+    // test whether new component can get shifted value
+    prev = shind[j];
+    next = shind[j+1];
+    assume(next > prev);
+    if ((same_comp && prev + 2 >= next) || (!same_comp && next - prev < 4))
+    {
+       long new_space = syReorderShiftedComponents(shind, ie);
+      prev = shind[j];
+      next = shind[j+1];
+      assume((same_comp && prev + 2 < next) || (!same_comp && next - prev >= 4));
+      ret = TRUE;
+     if (TEST_OPT_PROT) Print("(B%ld)", new_space);
+    }
+
+    // make room for insertion of j+1 shifted component
+    for (k=ie; k > j+1; k--) shind[k] = shind[k-1];
+
+    if (same_comp)
+    {
+      // can simply add one
+      shind[j+1] = prev + 1;
+      assume(shind[j+1] + 1 < shind[j+2]);
+    }
+    else
+    {
+      // need to leave more breathing room - i.e. value goes in
+      // between
+      shind[j+1]  = prev + ((next - prev) >> 1);
+      assume (shind[j] + 1 < shind[j+1] && shind[j+1] + 1 < shind[j+2]);
+    }
+  }
+
+  if (o_r[j]!=NULL)
+  {
+    for (k=ie-1;k>j;k--)
+    {
+      o_r[k] = o_r[k-1];
+      bc[k] = bc[k-1];
+    }
+  }
+  o_r[j] = p;
+  bc[j] = realcomp-1;
+  (H1[pGetComp(p)])++;
+  for (k=0;k<i;k++)
+  {
+    if (F1[k]>j)
+      (F1[k])++;
+  }
+  if (F1[pGetComp(p)]==0)
+    F1[pGetComp(p)]=j+1;
+  for (k=0;k<IDELEMS((syzstr->res)[index]);k++)
+  {
+    if (trind[k]>j)
+      trind[k] += 1;
+  }
+  for (k=IDELEMS((syzstr->res)[index])-1;k>realcomp;k--)
+    trind[k] = trind[k-1];
+  trind[realcomp] = j+1;
+  return ret;
+}
+
+//#define OLD_PAIR_ORDER
+#ifdef OLD_PAIR_ORDER
+static intvec* syLinStrat(SSet nextPairs, syStrategy syzstr,
+                          int howmuch, int index)
+{
+  int i=howmuch-1,i1=0,l,ll;
+  int ** Fin=syzstr->Firstelem;
+  int ** Hin=syzstr->Howmuch;
+  int ** bin=syzstr->backcomponents;
+  ideal o_r=syzstr->orderedRes[index+1];
+  intvec *result=new intvec(howmuch+1);
+  BOOLEAN isDivisible;
+  SObject tso;
+
+  while (i>=0)
+  {
+    tso = nextPairs[i];
+    isDivisible = FALSE;
+    if (syzstr->res[index+1]!=NULL)
+    {
+      l = Fin[index][pGetComp(tso.lcm)]-1;
+      if (l>=0)
+      {
+        ll = l+Hin[index][pGetComp(tso.lcm)];
+        while ((l<ll) && (!isDivisible))
+        {
+          if (o_r->m[l]!=NULL)
+          {
+            isDivisible = isDivisible ||
+              pLmDivisibleByNoComp(o_r->m[l],tso.lcm);
+          }
+          l++;
+        }
+      }
+    }
+    if (isDivisible)
+    {
+      syDeletePair(&nextPairs[i]);
+      //crit++;
+    }
+    else
+    {
+      nextPairs[i].p =
+        //sySPoly(tso.p1, tso.p2,tso.lcm);
+        spSpolyCreate(tso.p2, tso.p1,NULL,spSpolyLoop_General);
+      (*result)[i1] = i+1;
+      i1++;
+    }
+    i--;
+  }
+  return result;
+}
+#else
+static intvec* syLinStrat(SSet nextPairs, syStrategy syzstr,
+                          int howmuch, int index)
+{
+  int i=howmuch-1,i1=0,i2,i3,l,ll;
+  int ** Fin=syzstr->Firstelem;
+  int ** Hin=syzstr->Howmuch;
+  ideal o_r=syzstr->orderedRes[index+1];
+  intvec *result=new intvec(howmuch+1);
+  intvec *spl=new intvec(howmuch,1,-1);
+  BOOLEAN isDivisible;
+  SObject tso;
+
+  while (i>=0)
+  {
+    tso = nextPairs[i];
+    isDivisible = FALSE;
+    if (syzstr->res[index+1]!=NULL)
+    {
+      l = Fin[index][pGetComp(tso.lcm)]-1;
+      if (l>=0)
+      {
+        ll = l+Hin[index][pGetComp(tso.lcm)];
+        while ((l<ll) && (!isDivisible))
+        {
+          if (o_r->m[l]!=NULL)
+          {
+            isDivisible = isDivisible ||
+              pLmDivisibleByNoComp(o_r->m[l],tso.lcm);
+          }
+          l++;
+        }
+      }
+    }
+    if (isDivisible)
+    {
+      syDeletePair(&nextPairs[i]);
+      //crit++;
+    }
+    else
+    {
+      pTest(tso.p2);
+      pTest(tso.p1);
+      nextPairs[i].p =
+        ksOldCreateSpoly(tso.p2, tso.p1,NULL);
+      (*spl)[i] = pLength(nextPairs[i].p);
+    }
+    i--;
+  }
+  i3 = 0;
+  loop
+  {
+    i2 = -1;
+    for (i1=0;i1<howmuch;i1++)
+    {
+      if (i2==-1)
+      {
+        if ((*spl)[i1]!=-1)
+        {
+          i2 = i1;
+        }
+      }
+      else
+      {
+        if (((*spl)[i1]>=0) && ((*spl)[i1]<(*spl)[i2]))
+        {
+          i2 = i1;
+        }
+      }
+    }
+    if (i2>=0)
+    {
+      (*result)[i3] = i2+1;
+      (*spl)[i2] = -1;
+      i3++;
+    }
+    else
+    {
+      break;
+    }
+  }
+  delete spl;
+  return result;
+}
+#endif
+
+void syEnlargeFields(syStrategy syzstr,int index)
+{
+  pEnlargeSet(&(syzstr->res[index]->m),IDELEMS(syzstr->res[index]),16);
+  syzstr->truecomponents[index]=(int*)omRealloc0Size((ADDRESS)syzstr->truecomponents[index],
+                               (IDELEMS(syzstr->res[index])+1)*sizeof(int),
+                               (IDELEMS(syzstr->res[index])+17)*sizeof(int));
+  syzstr->ShiftedComponents[index]
+    =(long*)omRealloc0Size((ADDRESS)syzstr->ShiftedComponents[index],
+                              (IDELEMS(syzstr->res[index])+1)*sizeof(long),
+                              (IDELEMS(syzstr->res[index])+17)*sizeof(long));
+  syzstr->backcomponents[index]=(int*)omRealloc0Size((ADDRESS)syzstr->backcomponents[index],
+                               (IDELEMS(syzstr->res[index])+1)*sizeof(int),
+                               (IDELEMS(syzstr->res[index])+17)*sizeof(int));
+  syzstr->Howmuch[index]=(int*)omRealloc0Size((ADDRESS)syzstr->Howmuch[index],
+                               (IDELEMS(syzstr->res[index])+1)*sizeof(int),
+                               (IDELEMS(syzstr->res[index])+17)*sizeof(int));
+  syzstr->Firstelem[index]=(int*)omRealloc0Size((ADDRESS)syzstr->Firstelem[index],
+                               (IDELEMS(syzstr->res[index])+1)*sizeof(int),
+                               (IDELEMS(syzstr->res[index])+17)*sizeof(int));
+  syzstr->elemLength[index]=(int*)omRealloc0Size((ADDRESS)syzstr->elemLength[index],
+                               (IDELEMS(syzstr->res[index])+1)*sizeof(int),
+                               (IDELEMS(syzstr->res[index])+17)*sizeof(int));
+  syzstr->sev[index]=(unsigned long*)omRealloc0Size((ADDRESS)syzstr->sev[index],
+                                    (IDELEMS(syzstr->res[index])+1)*sizeof(unsigned long),
+                               (IDELEMS(syzstr->res[index])+17)*sizeof(unsigned long));
+  IDELEMS(syzstr->res[index]) += 16;
+  pEnlargeSet(&(syzstr->orderedRes[index]->m),IDELEMS(syzstr->orderedRes[index]),16);
+  IDELEMS(syzstr->orderedRes[index]) += 16;
+}
+/*3
+* reduces all pairs of degree deg in the module index
+* put the reduced generators to the resolvente which contains
+* the truncated kStd
+*/
+static void syRedNextPairs(SSet nextPairs, syStrategy syzstr,
+               int howmuch, int index)
+{
+  int i,j,k=IDELEMS(syzstr->res[index]);
+  int ks=IDELEMS(syzstr->res[index+1]);
+  int * Fin=syzstr->Firstelem[index-1];
+  int * Hin=syzstr->Howmuch[index-1];
+  int * bin=syzstr->backcomponents[index];
+  int * elL=syzstr->elemLength[index];
+  number coefgcd;
+  polyset redset=syzstr->orderedRes[index]->m;
+  poly p=NULL,q;
+  intvec *spl1;
+  SObject tso;
+  long * ShiftedComponents = syzstr->ShiftedComponents[index];
+  int* Components = syzstr->truecomponents[index];
+  assume(Components != NULL && ShiftedComponents != NULL);
+  BOOLEAN need_reset;
+
+  if ((nextPairs==NULL) || (howmuch==0)) return;
+  while ((k>0) && (syzstr->res[index]->m[k-1]==NULL)) k--;
+  while ((ks>0) && (syzstr->res[index+1]->m[ks-1]==NULL)) ks--;
+  spl1 = syLinStrat(nextPairs,syzstr,howmuch,index);
+  i=0;
+  while ((*spl1)[i]>0)
+  {
+    need_reset = FALSE;
+    tso = nextPairs[(*spl1)[i]-1];
+    if ((tso.p1!=NULL) && (tso.p2!=NULL))
+    {
+      nNormalize(pGetCoeff(tso.p1));
+      nNormalize(pGetCoeff(tso.p2));
+      coefgcd =
+        n_SubringGcd(pGetCoeff(tso.p1),pGetCoeff(tso.p2),currRing->cf);
+      tso.syz = pHead(tso.lcm);
+      p = tso.syz;
+      pSetCoeff(p,nDiv(pGetCoeff(tso.p1),coefgcd));
+      pGetCoeff(p) = nInpNeg(pGetCoeff(p));
+      pSetComp(p,tso.ind2+1);
+      p_Setm_Syz(p, currRing, Components, ShiftedComponents); // actueller index
+      pNext(p) = pHead(tso.lcm);
+      pIter(p);
+      pSetComp(p,tso.ind1+1);
+      p_Setm_Syz(p, currRing, Components, ShiftedComponents); // actueller index
+      pSetCoeff(p,nDiv(pGetCoeff(tso.p2),coefgcd));
+      nDelete(&coefgcd);
+      if (tso.p != NULL)
+      {
+        kBucketInit(syzstr->bucket,tso.p,-1);
+        q = kBucketGetLm(syzstr->bucket);
+        j = Fin[pGetComp(q)]-1;
+        int pos = j+Hin[pGetComp(q)];
+        loop
+        {
+          if (j<0) break;
+          if (pLmDivisibleByNoComp(redset[j],q))
+          {
+            pNext(p) = pHead(q);
+            pIter(p);
+            pSetComp(p,bin[j]+1);
+            p_Setm_Syz(p, currRing, Components, ShiftedComponents); // actueller index
+//if (pLength(redset[j])!=syzstr->elemLength[index][bin[j]])
+//Print("Halt");
+//if (pLength(redset[j])!=syzstr->elemLength[index][bin[j]])
+//Print("Halt");
+            pGetCoeff(p) = nInpNeg(pGetCoeff(p));
+            number up = kBucketPolyRed(syzstr->bucket,redset[j],elL[bin[j]],
+                                       NULL);
+            // Thomas: Check whether you need number here
+            nDelete(&up);
+            q = kBucketGetLm(syzstr->bucket);
+            if (q==NULL) break;
+            j = Fin[pGetComp(q)]-1;
+            pos = j+Hin[pGetComp(q)];
+          }
+          else
+          {
+            j++;
+            if (j==pos) break;
+          }
+        }
+        int lb;
+        kBucketClear(syzstr->bucket,&tso.p,&lb);
+      }
+      if (tso.p != NULL)
+      {
+        if (TEST_OPT_PROT) PrintS("g");
+        if (k==IDELEMS((syzstr->res)[index]))
+        {
+          syEnlargeFields(syzstr,index);
+          bin=syzstr->backcomponents[index];
+          elL=syzstr->elemLength[index];
+          redset=syzstr->orderedRes[index]->m;
+          Components = syzstr->truecomponents[index];
+          ShiftedComponents = syzstr->ShiftedComponents[index];
+        }
+        pNext(p) = pHead(tso.p);
+        pIter(p);
+
+        assume(p!= NULL);
+        k++;
+        syzstr->res[index]->m[k-1] = tso.p;
+        syzstr->elemLength[index][k-1] = pLength(tso.p);
+        pNorm(syzstr->res[index]->m[k-1]);
+        need_reset = syOrder(syzstr->res[index]->m[k-1],syzstr,index,k);
+        pSetComp(p,k); // actueller index
+        p_Setm_Syz(p, currRing, Components, ShiftedComponents);
+        pGetCoeff(p) = nInpNeg(pGetCoeff(p));
+
+        tso.isNotMinimal = p;
+        tso.p = NULL;
+      }
+      else
+      {
+        if (TEST_OPT_PROT) PrintS(".");
+        //if (index % 2==0)
+          //euler++;
+        //else
+          //euler--;
+      }
+      if (ks==IDELEMS(syzstr->res[index+1]))
+      {
+        syEnlargeFields(syzstr,index+1);
+      }
+      syzstr->res[index+1]->m[ks] = tso.syz;
+      syzstr->elemLength[index+1][ks] = pLength(tso.syz);
+      pNorm(syzstr->res[index+1]->m[ks]);
+      tso.syz =NULL;
+      tso.syzind = ks;
+      if (need_reset)
+        syResetShiftedComponents(syzstr, index+1);
+      if (syOrder(syzstr->res[index+1]->m[ks],syzstr,index+1,ks+1))
+         syResetShiftedComponents(syzstr, index+2);
+      ks++;
+      p = NULL;
+      nextPairs[(*spl1)[i]-1] = tso;
+    }
+    i++;
+  }
+  delete spl1;
+}
+
+/*3
+* reduces the generators of the module index in degree deg
+* (which are actual syzygies of the module index-1)
+* wrt. the ideal generated by elements of lower degrees
+*/
+static void syRedGenerOfCurrDeg(syStrategy syzstr, int deg, int index)
+{
+  ideal res=syzstr->res[index];
+  int i=0,j,k=IDELEMS(res);
+  SSet sPairs=syzstr->resPairs[index-1];
+
+  while ((k>0) && (res->m[k-1]==NULL)) k--;
+  while ((i<(*syzstr->Tl)[index-1]) && (((sPairs)[i].syz==NULL) ||
+          ((sPairs)[i].order<deg)))
+    i++;
+  if ((i>=(*syzstr->Tl)[index-1]) || ((sPairs)[i].order>deg)) return;
+  while ((i<(*syzstr->Tl)[index-1]) && (((sPairs)[i].syz==NULL) ||
+         ((sPairs)[i].order==deg)))
+  {
+    if ((sPairs)[i].syz!=NULL)
+    {
+      j = k-1;
+      while ((j>=0) && (res->m[j]!=NULL) &&
+             ((sPairs)[i].syz!=NULL))
+      {
+        if (pLmDivisibleBy(res->m[j],(sPairs)[i].syz))
+        {
+          (sPairs)[i].syz =
+            ksOldSpolyRed(res->m[j],(sPairs)[i].syz);
+            //sySPolyRed((sPairs)[i].syz,res->m[j]);
+          j = k-1;
+        }
+        else
+        {
+          j--;
+        }
+      }
+      if ((sPairs)[i].syz != NULL)
+      {
+        if (k==IDELEMS(res))
+        {
+          syEnlargeFields(syzstr,index);
+          res=syzstr->res[index];
+        }
+        if (TEST_OPT_DEBUG)
+        {
+          if ((sPairs)[i].isNotMinimal==NULL)
+          {
+            PrintLn();
+            PrintS("minimal generator: ");pWrite((syzstr->resPairs[index-1])[i].syz);
+            PrintS("comes from: ");pWrite((syzstr->resPairs[index-1])[i].p1);
+            PrintS("and: ");pWrite((syzstr->resPairs[index-1])[i].p2);
+          }
+        }
+        //res->m[k] = (sPairs)[i].syz;
+        res->m[k] = syRedtail((sPairs)[i].syz,syzstr,index);
+        (sPairs)[i].syzind = k;
+        syzstr->elemLength[index][k] = pLength((sPairs)[i].syz);
+        pNorm(res->m[k]);
+  //      (sPairs)[i].syz = NULL;
+        k++;
+        if (syOrder(res->m[k-1],syzstr,index,k))
+          syResetShiftedComponents(syzstr, index);
+        //euler++;
+      }
+      else
+        (sPairs)[i].syzind = -1;
+    }
+    i++;
+  }
+}
+
+/*3
+* puts a pair into the right place in resPairs
+*/
+void syEnterPair(SSet sPairs, SObject * so, int * sPlength,int /*index*/)
+{
+  int ll,k,no=(*so).order,sP=*sPlength,i;
+
+  if ((sP==0) || (sPairs[sP-1].order<=no))
+    ll = sP;
+  else if (sP==1)
+    ll = 0;
+  else
+  {
+    int an=0,en=sP-1;
+    loop
+    {
+      if (an>=en-1)
+      {
+        if ((sPairs[an].order<=no) && (sPairs[an+1].order>no))
+        {
+          ll = an+1;
+          break;
+        }
+        else if ((sPairs[en].order<=no) && (sPairs[en+1].order>no))
+        {
+          ll = en+1;
+          break;
+        }
+        else if (sPairs[an].order>no)
+        {
+          ll = an;
+          break;
+        }
+        else
+        {
+          PrintS("Hier ist was faul!\n");
+          break;
+        }
+      }
+      i=(an+en) / 2;
+      if (sPairs[i].order <= no)
+        an=i;
+      else
+        en=i;
+    }
+  }
+  for (k=(*sPlength);k>ll;k--)
+  {
+    syCopyPair(&sPairs[k-1],&sPairs[k]);
+  }
+  syCopyPair(so,&sPairs[ll]);
+  (*sPlength)++;
+}
+void syEnterPair(syStrategy syzstr, SObject * so, int * sPlength,int index)
+{
+  int ll;
+
+  if (*sPlength>=(*syzstr->Tl)[index])
+  {
+    SSet temp = (SSet)omAlloc0(((*syzstr->Tl)[index]+16)*sizeof(SObject));
+    for (ll=0;ll<(*syzstr->Tl)[index];ll++)
+    {
+      temp[ll].p = (syzstr->resPairs[index])[ll].p;
+      temp[ll].p1 = (syzstr->resPairs[index])[ll].p1;
+      temp[ll].p2 = (syzstr->resPairs[index])[ll].p2;
+      temp[ll].syz = (syzstr->resPairs[index])[ll].syz;
+      temp[ll].lcm = (syzstr->resPairs[index])[ll].lcm;
+      temp[ll].ind1 = (syzstr->resPairs[index])[ll].ind1;
+      temp[ll].ind2 = (syzstr->resPairs[index])[ll].ind2;
+      temp[ll].syzind = (syzstr->resPairs[index])[ll].syzind;
+      temp[ll].order = (syzstr->resPairs[index])[ll].order;
+      temp[ll].isNotMinimal = (syzstr->resPairs[index])[ll].isNotMinimal;
+      temp[ll].length = (syzstr->resPairs[index])[ll].length;
+      temp[ll].reference = (syzstr->resPairs[index])[ll].reference;
+    }
+    if (syzstr->resPairs[index] != NULL) // OB: ?????
+      omFreeSize((ADDRESS)syzstr->resPairs[index],(*syzstr->Tl)[index]*sizeof(SObject));
+    (*syzstr->Tl)[index] += 16;
+    syzstr->resPairs[index] = temp;
+  }
+  syEnterPair(syzstr->resPairs[index],so,sPlength,index);
+}
+
+/*3
+* computes pairs from the new elements (beginning with the element newEl)
+* in the module index
+*/
+static void syCreateNewPairs(syStrategy syzstr, int index, int newEl)
+{
+  SSet temp;
+  SObject tso;
+  int i,ii,j,k=IDELEMS(syzstr->res[index]),l=(*syzstr->Tl)[index],ll;
+  int first,pos,jj,j1;
+  int * bci=syzstr->backcomponents[index];
+  poly p,q;
+  polyset rs=syzstr->res[index]->m,nPm;
+
+
+  while ((k>0) && (rs[k-1]==NULL)) k--;
+  if (newEl>=k) return;
+
+  long * ShiftedComponents = syzstr->ShiftedComponents[index];
+  int* Components = syzstr->truecomponents[index];
+
+  ideal nP=idInit(k,syzstr->res[index]->rank);
+  nPm=nP->m;
+  while ((l>0) && ((syzstr->resPairs[index])[l-1].p1==NULL)) l--;
+  for (j=newEl;j<k;j++)
+  {
+    q = rs[j];
+    first = syzstr->Firstelem[index-1][pGetComp(q)]-1;
+    pos = first+syzstr->Howmuch[index-1][pGetComp(q)];
+    for (i=first;i<pos;i++)
+    {
+      jj = bci[i];
+      if (jj>=j) break;
+      p = pOne();
+      pLcm(rs[jj],q,p);
+      pSetComp(p,j+1);
+      p_Setm_Syz(p, currRing, Components, ShiftedComponents);
+      ii = first;
+      loop
+      {
+        j1 = bci[ii];
+        if (nPm[j1]!=NULL)
+        {
+          if (pLmDivisibleByNoComp(nPm[j1],p))
+          {
+            pDelete(&p);
+            break;
+          }
+          else if (pLmDivisibleByNoComp(p,nPm[j1]))
+          {
+            pDelete(&(nPm[j1]));
+            //break;
+          }
+        }
+        ii++;
+        if (ii>=pos) break;
+      }
+      if (p!=NULL)
+      {
+        nPm[jj] = p;
+      }
+    }
+    for (i=first;i<pos;i++)
+    {
+      ii = bci[i];
+      if (nPm[ii]!=NULL)
+      {
+        if (l>=(*syzstr->Tl)[index])
+        {
+          temp = (SSet)omAlloc0(((*syzstr->Tl)[index]+16)*sizeof(SObject));
+          for (ll=0;ll<(*syzstr->Tl)[index];ll++)
+          {
+            temp[ll].p = (syzstr->resPairs[index])[ll].p;
+            temp[ll].p1 = (syzstr->resPairs[index])[ll].p1;
+            temp[ll].p2 = (syzstr->resPairs[index])[ll].p2;
+            temp[ll].syz = (syzstr->resPairs[index])[ll].syz;
+            temp[ll].lcm = (syzstr->resPairs[index])[ll].lcm;
+            temp[ll].ind1 = (syzstr->resPairs[index])[ll].ind1;
+            temp[ll].ind2 = (syzstr->resPairs[index])[ll].ind2;
+            temp[ll].syzind = (syzstr->resPairs[index])[ll].syzind;
+            temp[ll].order = (syzstr->resPairs[index])[ll].order;
+            temp[ll].isNotMinimal = (syzstr->resPairs[index])[ll].isNotMinimal;
+          }
+          if (syzstr->resPairs[index] != NULL) // OB: ????
+            omFreeSize((ADDRESS)syzstr->resPairs[index],(*syzstr->Tl)[index]*sizeof(SObject));
+          (*syzstr->Tl)[index] += 16;
+          syzstr->resPairs[index] = temp;
+        }
+        tso.lcm = p = nPm[ii];
+        nPm[ii] = NULL;
+        tso.order = pTotaldegree(p);
+        if ((syzstr->cw!=NULL) && (index>0) && (pGetComp(q)>0))
+        {
+          int ii=index-1,jj=pGetComp(q);
+          while (ii>0)
+          {
+            jj = pGetComp(syzstr->res[ii]->m[jj-1]);
+            ii--;
+          }
+          tso.order += (*syzstr->cw)[jj-1];
+        }
+        tso.p1 = rs[ii];
+        tso.p2 = q;
+        tso.ind1 = ii;
+        tso.ind2 = j;
+        tso.syzind = -1;
+        tso.isNotMinimal = NULL;
+        tso.p = NULL;
+        tso.syz = NULL;
+        syEnterPair(syzstr->resPairs[index],&tso,&l,index);
+      }
+    }
+  }
+  idDelete(&nP);
+}
+
+static SSet syChosePairsPutIn(syStrategy syzstr, int *index,
+               int *howmuch, int * actdeg, int an, int en)
+{
+  int newdeg=*actdeg,newindex=-1,i,t,sldeg;
+  SSet result;
+  SRes resPairs=syzstr->resPairs;
+
+  if (an>syzstr->length) return NULL;
+  if (en>syzstr->length) en=syzstr->length;
+  while (*index<en)
+  {
+    if (resPairs[*index]!=NULL)
+    {
+      sldeg = (*actdeg)+*index;
+      i = 0;
+      if (*index!=0)
+      {
+        while ((i<(*syzstr->Tl)[*index]))
+        {
+          if ((resPairs[*index])[i].lcm!=NULL)
+          {
+            if ((resPairs[*index])[i].order == sldeg)
+            {
+              result = &(resPairs[*index])[i];
+              *howmuch =1;
+              i++;
+              while ((i<(*syzstr->Tl)[*index]) && ((resPairs[*index])[i].lcm!=NULL)
+                      && ((resPairs[*index])[i].order == sldeg))
+              {
+                i++;
+                (*howmuch)++;
+              }
+              return result;
+            }
+          }
+          i++;
+        }
+      }
+      else
+      {
+        while ((i<(*syzstr->Tl)[*index]))
+        {
+          if ((resPairs[*index])[i].syz!=NULL)
+          {
+            if ((resPairs[*index])[i].order == sldeg)
+            {
+              result = &(resPairs[*index])[i];
+              (*howmuch) =1;
+              i++;
+              while ((i<(*syzstr->Tl)[*index]) && ((resPairs[*index])[i].syz!=NULL)
+                      && ((resPairs[*index])[i].order == *actdeg))
+              {
+                i++;
+                (*howmuch)++;
+              }
+              return result;
+            }
+          }
+          i++;
+        }
+      }
+    }
+    (*index)++;
+  }
+  *index = an;
+  //if (TEST_OPT_PROT) Print("(Euler:%d)",euler);
+  while (*index<en)
+  {
+    if (resPairs[*index]!=NULL)
+    {
+      i = 0;
+      while ((i<(*syzstr->Tl)[*index]))
+      {
+        t = *actdeg+*index;
+        if (((resPairs[*index])[i].lcm!=NULL) ||
+              ((resPairs[*index])[i].syz!=NULL))
+        {
+          if ((resPairs[*index])[i].order > t)
+            t = (resPairs[*index])[i].order;
+        }
+        if ((t>*actdeg+*index) && ((newdeg==*actdeg) || (t<newdeg+*index)))
+        {
+          newdeg = t-*index;
+          newindex = *index;
+          break;
+        }
+        i++;
+      }
+    }
+    (*index)++;
+  }
+  if (newdeg>*actdeg)
+  {
+    *actdeg = newdeg;
+    *index = newindex;
+    return syChosePairsPutIn(syzstr,index,howmuch,actdeg,an,en);
+  }
+  else return NULL;
+}
+
+/*3
+* FOR THE HOMOGENEOUS CASE ONLY!
+* looks through the pair set and the given module for
+* remaining pairs or generators to consider
+* returns a pointer to the first pair and the number of them in the given module
+* works with slanted degree (i.e. deg=realdeg-index)
+*/
+SSet syChosePairs(syStrategy syzstr, int *index, int *howmuch, int * actdeg)
+{
+  return syChosePairsPutIn(syzstr,index,howmuch,actdeg,0,syzstr->length);
+}
+
+/*3
+* FOR THE INHOMOGENEOUS CASE ONLY!
+* looks through the pair set and the given module for
+* remaining pairs or generators to consider
+* returns a pointer to the first pair and the number of them in the given module
+* works with slanted degree (i.e. deg=realdeg-index)
+* looks first through the 0 and 1 module then through the other
+*/
+static SSet syChosePairsIH(syStrategy syzstr, int *index,
+               int *howmuch, int * actdeg, int mindeg)
+{
+  SSet result=NULL;
+
+  result = syChosePairsPutIn(syzstr,index,howmuch,actdeg,0,2);
+  if (result == NULL)
+  {
+    *actdeg = mindeg;
+    result = syChosePairsPutIn(syzstr,index,howmuch,actdeg,2,syzstr->length);
+  }
+  return result;
+}
+
+/*3
+* looks through the pair set and the given module for
+* remaining pairs or generators to consider
+* returns a pointer to the first pair and the number of them in the given module
+* works deg by deg
+*/
+/*
+*static SSet syChosePairs1(SRes resPairs,intvec * Tl, int *index, int *howmuch,
+*                   int length,int * actdeg)
+*{
+*  int newdeg=*actdeg,newindex=-1,i,t;
+*  SSet result;
+*
+*  while (*index>=0)
+*  {
+*    if (resPairs[*index]!=NULL)
+*    {
+*      i = 0;
+*      if (*index!=0)
+*      {
+*        while ((i<(*Tl)[*index]))
+*        {
+*          if ((resPairs[*index])[i].lcm!=NULL)
+*          {
+*            if (pGetOrder((resPairs[*index])[i].lcm) == *actdeg)
+*            {
+*              result = &(resPairs[*index])[i];
+*              *howmuch =1;
+*              i++;
+*              while ((i<(*Tl)[*index]) && ((resPairs[*index])[i].lcm!=NULL)
+*                      && (pGetOrder((resPairs[*index])[i].lcm) == *actdeg))
+*              {
+*                i++;
+*                (*howmuch)++;
+*              }
+*              return result;
+*            }
+*          }
+*          i++;
+*        }
+*      }
+*      else
+*      {
+*        while ((i<(*Tl)[*index]))
+*        {
+*          if ((resPairs[*index])[i].syz!=NULL)
+*          {
+*            if ((resPairs[*index])[i].order == *actdeg)
+*            {
+*              result = &(resPairs[*index])[i];
+*              (*howmuch) =1;
+*              i++;
+*              while ((i<(*Tl)[*index]) && ((resPairs[*index])[i].syz!=NULL)
+*                      && ((resPairs[*index])[i].order == *actdeg))
+*              {
+*                i++;
+*                (*howmuch)++;
+*              }
+*              return result;
+*            }
+*          }
+*          i++;
+*        }
+*      }
+*    }
+*    (*index)--;
+*  }
+*  *index = length-1;
+*  while (*index>=0)
+*  {
+*    if (resPairs[*index]!=NULL)
+*    {
+*      i = 0;
+*      while ((i<(*Tl)[*index]))
+*      {
+*        t = *actdeg;
+*        if ((resPairs[*index])[i].lcm!=NULL)
+*        {
+*          if (pGetOrder((resPairs[*index])[i].lcm) > *actdeg)
+*            t = pGetOrder((resPairs[*index])[i].lcm);
+*        }
+*        else if ((resPairs[*index])[i].syz!=NULL)
+*        {
+*          if ((resPairs[*index])[i].order > *actdeg)
+*            t = (resPairs[*index])[i].order;
+*        }
+*        if ((t>*actdeg) && ((newdeg==*actdeg) || (t<newdeg)))
+*        {
+*          newdeg = t;
+*          newindex = *index;
+*          break;
+*        }
+*        i++;
+*      }
+*    }
+*    (*index)--;
+*  }
+*  if (newdeg>*actdeg)
+*  {
+*    *actdeg = newdeg;
+*    *index = newindex;
+*    return syChosePairs1(resPairs,Tl,index,howmuch,length,actdeg);
+*  }
+*  else return NULL;
+*}
+*/
+#if 0 /* only debugging */
+/*3
+* statistics of the resolution
+*/
+static void syStatistics(resolvente res,int length)
+{
+  int i,j=1,k;
+  long deg = 0;
+
+  PrintLn();
+  while ((j<length) && (res[j]!=NULL))
+  {
+    Print("In module %d: \n",j);
+    k = 0;
+    while ((k<IDELEMS(res[j])) && (res[j]->m[k]!=NULL))
+    {
+      i = 1;
+      deg = pGetOrder(res[j]->m[k]);
+      k++;
+      while ((k<IDELEMS(res[j])) && (res[j]->m[k]!=NULL) &&
+              (pGetOrder(res[j]->m[k])==deg))
+      {
+        i++;
+        k++;
+      }
+      Print("%d elements of degree %ld\n",i,deg);
+    }
+    j++;
+  }
+}
+#endif
+
+/*3
+* initialize a module
+*/
+int syInitSyzMod(syStrategy syzstr, int index, int init)
+{
+  int result;
+
+  if (syzstr->res[index]==NULL)
+  {
+    syzstr->res[index] = idInit(init-1,1);
+    syzstr->truecomponents[index] = (int*)omAlloc0(init*sizeof(int));
+    syzstr->ShiftedComponents[index] = (long*)omAlloc0(init*sizeof(long));
+    if (index==0)
+    {
+      for (int i=0;i<init;i++)
+      {
+        syzstr->truecomponents[0][i] = i;
+        syzstr->ShiftedComponents[0][i] = (i)*SYZ_SHIFT_BASE;
+      }
+    }
+    syzstr->backcomponents[index] = (int*)omAlloc0(init*sizeof(int));
+    syzstr->Howmuch[index] = (int*)omAlloc0(init*sizeof(int));
+    syzstr->Firstelem[index] = (int*)omAlloc0(init*sizeof(int));
+    syzstr->elemLength[index] = (int*)omAlloc0(init*sizeof(int));
+    syzstr->orderedRes[index] = idInit(init-1,1);
+    syzstr->sev[index] = (unsigned long*) omAlloc0(init*sizeof(unsigned long));
+    result = 0;
+  }
+  else
+  {
+    result = IDELEMS(syzstr->res[index]);
+    while ((result>0) && (syzstr->res[index]->m[result-1]==NULL)) result--;
+  }
+  return result;
+}
+
+/*3
+* deletes a resolution
+*/
+void syKillComputation(syStrategy syzstr, ring r)
+{
+  if (syzstr->references>0)
+  {
+    (syzstr->references)--;
+  }
+  else
+  {
+    int i,j;
+    if (syzstr->minres!=NULL)
+    {
+      for (i=0;i<syzstr->length;i++)
+      {
+        if (syzstr->minres[i]!=NULL)
+        {
+          for (j=0;j<IDELEMS(syzstr->minres[i]);j++)
+          {
+            if (syzstr->minres[i]->m[j]!=NULL)
+              p_Delete(&(syzstr->minres[i]->m[j]),r);
+          }
+        }
+        id_Delete(&(syzstr->minres[i]),r);
+      }
+      omFreeSize((ADDRESS)syzstr->minres,(syzstr->length+1)*sizeof(ideal));
+    }
+    if (syzstr->fullres!=NULL)
+    {
+      for (i=0;i<syzstr->length;i++)
+      {
+        if (syzstr->fullres[i]!=NULL)
+        {
+          for (j=0;j<IDELEMS(syzstr->fullres[i]);j++)
+          {
+            if (syzstr->fullres[i]->m[j]!=NULL)
+              p_Delete(&(syzstr->fullres[i]->m[j]),r);
+          }
+        }
+        id_Delete(&(syzstr->fullres[i]),r);
+      }
+      omFreeSize((ADDRESS)syzstr->fullres,(syzstr->length+1)*sizeof(ideal));
+    }
+    if (syzstr->weights!=0)
+    {
+      for (i=0;i<syzstr->length;i++)
+      {
+        if (syzstr->weights[i]!=NULL)
+        {
+          delete syzstr->weights[i];
+        }
+      }
+      omFreeSize((ADDRESS)syzstr->weights,syzstr->length*sizeof(intvec*));
+    }
+
+    ring sr=syzstr->syRing;
+    if (sr==NULL) sr=r;
+
+    if (syzstr->resPairs!=NULL)
+    {
+      for (i=0;i<syzstr->length;i++)
+      {
+        for (j=0;j<(*syzstr->Tl)[i];j++)
+        {
+          if ((syzstr->resPairs[i])[j].lcm!=NULL)
+            p_Delete(&((syzstr->resPairs[i])[j].lcm),sr);
+          if ((i>0) && ((syzstr->resPairs[i])[j].syz!=NULL))
+            p_Delete(&((syzstr->resPairs[i])[j].syz),sr);
+        }
+        if (syzstr->orderedRes[i]!=NULL)
+        {
+          for (j=0;j<IDELEMS(syzstr->orderedRes[i]);j++)
+          {
+            syzstr->orderedRes[i]->m[j] = NULL;
+          }
+        }
+        id_Delete(&(syzstr->orderedRes[i]),sr);
+        if (syzstr->truecomponents[i]!=NULL)
+        {
+          omFreeSize((ADDRESS)syzstr->truecomponents[i],(IDELEMS(syzstr->res[i])+1)*sizeof(int));
+          syzstr->truecomponents[i]=NULL;
+          omFreeSize((ADDRESS)syzstr->ShiftedComponents[i],(IDELEMS(syzstr->res[i])+1)*sizeof(long));
+          syzstr->ShiftedComponents[i]=NULL;
+        }
+        if (syzstr->backcomponents[i]!=NULL)
+        {
+          omFreeSize((ADDRESS)syzstr->backcomponents[i],(IDELEMS(syzstr->res[i])+1)*sizeof(int));
+          syzstr->backcomponents[i]=NULL;
+        }
+        if (syzstr->Howmuch[i]!=NULL)
+        {
+          omFreeSize((ADDRESS)syzstr->Howmuch[i],(IDELEMS(syzstr->res[i])+1)*sizeof(int));
+          syzstr->Howmuch[i]=NULL;
+        }
+        if (syzstr->Firstelem[i]!=NULL)
+        {
+          omFreeSize((ADDRESS)syzstr->Firstelem[i],(IDELEMS(syzstr->res[i])+1)*sizeof(int));
+          syzstr->Firstelem[i]=NULL;
+        }
+        if (syzstr->elemLength[i]!=NULL)
+        {
+          omFreeSize((ADDRESS)syzstr->elemLength[i],(IDELEMS(syzstr->res[i])+1)*sizeof(int));
+          syzstr->elemLength[i]=NULL;
+        }
+        if (syzstr->res[i]!=NULL)
+        {
+          for (j=0;j<IDELEMS(syzstr->res[i]);j++)
+          {
+            if (syzstr->res[i]->m[j]!=NULL)
+              p_Delete(&(syzstr->res[i]->m[j]),sr);
+          }
+        }
+        if ((syzstr->hilb_coeffs!=NULL)
+        && (syzstr->hilb_coeffs[i]!=NULL))
+          delete syzstr->hilb_coeffs[i];
+        if (syzstr->sev[i] != NULL)
+          omFreeSize((ADDRESS)syzstr->sev[i], (IDELEMS(syzstr->res[i])+1)*sizeof(unsigned long));
+        id_Delete(&(syzstr->res[i]),sr);
+        if (syzstr->resPairs[i] != NULL) // OB: ????
+          omFreeSize((ADDRESS)syzstr->resPairs[i],(*syzstr->Tl)[i]*sizeof(SObject));
+      }
+      omFreeSize((ADDRESS)syzstr->resPairs,syzstr->length*sizeof(SObject*));
+      omFreeSize((ADDRESS)syzstr->res,(syzstr->length+1)*sizeof(ideal));
+      omFreeSize((ADDRESS)syzstr->orderedRes,(syzstr->length+1)*sizeof(ideal));
+      omFreeSize((ADDRESS)syzstr->elemLength,(syzstr->length+1)*sizeof(int*));
+      omFreeSize((ADDRESS)syzstr->truecomponents,(syzstr->length+1)*sizeof(int*));
+      omFreeSize((ADDRESS)syzstr->ShiftedComponents,(syzstr->length+1)*sizeof(long*));
+      if (syzstr->sev != NULL)
+        omFreeSize(((ADDRESS)syzstr->sev), (syzstr->length+1)*sizeof(unsigned long*));
+      omFreeSize((ADDRESS)syzstr->backcomponents,(syzstr->length+1)*sizeof(int*));
+      omFreeSize((ADDRESS)syzstr->Howmuch,(syzstr->length+1)*sizeof(int*));
+      omFreeSize((ADDRESS)syzstr->Firstelem,(syzstr->length+1)*sizeof(int*));
+      if (syzstr->hilb_coeffs!=NULL)
+        omFreeSize((ADDRESS)syzstr->hilb_coeffs,(syzstr->length+1)*sizeof(intvec*));
+    }
+    if (syzstr->cw!=NULL)
+      delete syzstr->cw;
+    if (syzstr->betti!=NULL)
+      delete syzstr->betti;
+    if (syzstr->resolution!=NULL)
+      delete syzstr->resolution;
+    if (syzstr->Tl!=NULL)
+      delete syzstr->Tl;
+    if ((syzstr->syRing != NULL) && (syzstr->syRing != r))
+    {
+      if(syzstr->syRing->typ[1].ord_typ == ro_syzcomp)
+        rChangeSComps(NULL, NULL, 0, syzstr->syRing);
+
+      rDelete(syzstr->syRing);
+    }
+    omFreeSize((ADDRESS)syzstr, sizeof(ssyStrategy));
+  }
+}
+
+/*2
+* divides out the weight monomials (given by the Schreyer-ordering)
+* from the LaScala-resolution
+*/
+resolvente syReorder(resolvente res,int length,
+        syStrategy syzstr,BOOLEAN toCopy,resolvente totake)
+{
+  int i,j,l;
+  poly p,q,tq;
+  polyset ri1;
+  resolvente fullres;
+  ring origR=syzstr->syRing;
+  fullres = (resolvente)omAlloc0((length+1)*sizeof(ideal));
+  if (totake==NULL)
+    totake = res;
+  for (i=length-1;i>0;i--)
+  {
+    if (res[i]!=NULL)
+    {
+      if (i>1)
+      {
+        j = IDELEMS(res[i-1]);
+        while ((j>0) && (res[i-1]->m[j-1]==NULL)) j--;
+        fullres[i-1] = idInit(IDELEMS(res[i]),j);
+        ri1 = totake[i-1]->m;
+        for (j=IDELEMS(res[i])-1;j>=0;j--)
+        {
+          p = res[i]->m[j];
+          q = NULL;
+          while (p!=NULL)
+          {
+            if (toCopy)
+            {
+              if (origR!=NULL)
+                tq = prHeadR(p,origR, currRing);
+              else
+                tq = pHead(p);
+              pIter(p);
+            }
+            else
+            {
+              res[i]->m[j] = NULL;
+              if (origR!=NULL)
+              {
+                poly pp=p;
+                pIter(p);
+                pNext(pp)=NULL;
+                tq = prMoveR(pp, origR, currRing);
+              }
+              else
+              {
+                tq = p;
+                pIter(p);
+                pNext(tq) = NULL;
+              }
+            }
+//            pWrite(tq);
+            pTest(tq);
+            for (l=(currRing->N);l>0;l--)
+            {
+              if (origR!=NULL)
+                pSubExp(tq,l, p_GetExp(ri1[pGetComp(tq)-1],l,origR));
+              else
+                pSubExp(tq,l, pGetExp(ri1[pGetComp(tq)-1],l));
+            }
+            pSetm(tq);
+            pTest(tq);
+            q = pAdd(q,tq);
+            pTest(q);
+          }
+          fullres[i-1]->m[j] = q;
+        }
+      }
+      else
+      {
+        if (origR!=NULL)
+        {
+          fullres[i-1] = idInit(IDELEMS(res[i]),res[i]->rank);
+          for (j=IDELEMS(res[i])-1;j>=0;j--)
+          {
+            if (toCopy)
+              fullres[i-1]->m[j] = prCopyR(res[i]->m[j], origR, currRing);
+            else
+            {
+              fullres[i-1]->m[j] = prMoveR(res[i]->m[j], origR, currRing);
+              res[i]->m[j] = NULL;
+            }
+          }
+        }
+        else
+        {
+          if (toCopy)
+            fullres[i-1] = idCopy(res[i]);
+          else
+          {
+            fullres[i-1] = res[i];
+            res[i] = NULL;
+          }
+        }
+        for (j=IDELEMS(fullres[i-1])-1;j>=0;j--)
+          fullres[i-1]->m[j] = pSortCompCorrect(fullres[i-1]->m[j]);
+      }
+      if (!toCopy)
+      {
+        if (res[i]!=NULL) idDelete(&res[i]);
+      }
+    }
+  }
+  if (!toCopy)
+    omFreeSize((ADDRESS)res,(length+1)*sizeof(ideal));
+  //syzstr->length = length;
+  return fullres;
+}
+
+/*3
+* read out the Betti numbers from resolution
+* (if not LaScala calls the traditional Betti procedure)
+*/
+intvec * syBettiOfComputation(syStrategy syzstr, BOOLEAN minim,int * row_shift,
+                              intvec* weights)
+{
+  int dummy;
+  BOOLEAN std_weights=TRUE;
+  if ((weights!=NULL)
+  && (syzstr->betti!=NULL)
+  && (syzstr->weights!=NULL) && (syzstr->weights[0]!=NULL))
+  {
+    int i;
+    for(i=weights->length()-1; i>=0; i--)
+    {
+      //Print("test %d: %d - %d\n",i,(*weights)[i], (*(syzstr->weights[0]))[i]);
+      if ((*weights)[i]!=(*(syzstr->weights[0]))[i])
+      {
+        std_weights=FALSE;
+        break;
+      }
+    }
+  }
+  if ((syzstr->betti!=NULL)
+  && (std_weights))
+  {
+    if (minim || (syzstr->resPairs!=NULL))
+      return ivCopy(syzstr->betti);
+  }
+
+  resolvente fullres = syzstr->fullres;
+  resolvente minres = syzstr->minres;
+  const int length = syzstr->length;
+
+  if ((fullres==NULL) && (minres==NULL))
+  {
+     if (syzstr->hilb_coeffs==NULL)
+     { // LA SCALA
+        fullres = syReorder(syzstr->res, length, syzstr);
+     }
+     else
+     { //  HRES
+        minres = syReorder(syzstr->orderedRes, length, syzstr);
+        syKillEmptyEntres(minres, length);
+     }
+  }
+
+  intvec *result=NULL;
+
+  if (fullres!=NULL)
+    result = syBetti(fullres,length,&dummy,weights,minim,row_shift);
+  else
+    result = syBetti(minres,length,&dummy,weights,minim,row_shift);
+
+
+  return result; /// Don't change the syzstr???
+
+  // TODO: cleanup thses!
+  if( fullres != NULL && syzstr->fullres == NULL )
+    syzstr->fullres = fullres;
+  if( minres != NULL && syzstr->minres == NULL )
+    syzstr->minres = minres;
+
+  if ((result!=NULL)
+  && ((minim) || (syzstr->resPairs!=NULL))
+  && std_weights)
+  {
+    syzstr->betti = ivCopy(result); // cache the result...
+  }
+
+  return result;
+}
+
+/*3
+* computes the real length of the resolution
+*/
+int sySize(syStrategy syzstr)
+{
+  resolvente r=syzstr->res;
+  if (r==NULL)
+    r = syzstr->fullres;
+  if (r==NULL)
+    r = syzstr->minres;
+  if (r==NULL)
+  {
+    WerrorS("No resolution found");
+    return 0;
+  }
+  int i=syzstr->length;
+  while ((i>0) && (r[i-1]==NULL)) i--;
+  return i;
+}
+
+/*3
+* computes the cohomological dimension of res[1]
+*/
+int syDim(syStrategy syzstr)
+{
+  int i,l;
+  if (syzstr->resPairs!=NULL)
+  {
+    SRes rP=syzstr->resPairs;
+
+    l = syzstr->length;
+    while ((l>0) && (rP[l-1]==NULL)) l--;
+    if (l==0) return -1;
+    l--;
+    while (l>=0)
+    {
+      i = 0;
+      while ((i<(*syzstr->Tl)[l]) &&
+        ((rP[l][i].lcm!=NULL) || (rP[l][i].syz!=NULL)) &&
+        (rP[l][i].isNotMinimal!=NULL))
+      {
+        i++;
+      }
+      if ((i<(*syzstr->Tl)[l]) &&
+        ((rP[l][i].lcm!=NULL) || (rP[l][i].syz!=NULL)) &&
+        (rP[l][i].isNotMinimal==NULL))
+        return l;
+      l--;
+    }
+    return l;
+  }
+  else
+    return sySize(syzstr);
+}
+
+/*3
+* copies the resolution (by increment the reference counter)
+*/
+syStrategy syCopy(syStrategy syzstr)
+{
+  syStrategy result=syzstr;
+  (result->references)++;
+  return result;
+}
+
+/*2
+* local print procedure used in syPrint
+*/
+static void syPrintEmptySpaces(int i)
+{
+  if (i!=0)
+  {
+    PrintS(" ");
+    syPrintEmptySpaces(i/10);
+  }
+}
+
+/*2
+* local print procedure used in syPrint
+*/
+static void syPrintEmptySpaces1(int i)
+{
+  if (i!=0)
+  {
+    PrintS(" ");
+    syPrintEmptySpaces1(i-1);
+  }
+}
+
+/*2
+* local print procedure used in syPrint
+*/
+static int syLengthInt(int i)
+{
+  int j=0;
+
+  if (i==0) return 1;
+  while (i!=0)
+  {
+    j++;
+    i = i/10;
+  }
+  return j;
+}
+
+/*3
+* prints the resolution as sequence of free modules
+*/
+void syPrint(syStrategy syzstr, const char *sn)
+{
+  if ( (syzstr->resPairs==NULL) &&
+       (syzstr->fullres==NULL)  &&
+       (syzstr->minres==NULL) &&
+       (syzstr->resolution == NULL) )
+  {
+    PrintS("No resolution defined\n");
+    return;
+  }
+
+  intvec* resolution = syzstr->resolution;
+
+  if (resolution==NULL)
+  {
+    if (syzstr->resPairs!=NULL)
+    {
+      resolution = new intvec(syzstr->length+1);
+      SRes rP = syzstr->resPairs;
+//      assume(idRankFreeModule(syzstr->res[1], (syzstr->syRing != NULL ? syzstr->syRing : currRing))==syzstr->res[1]->rank);
+      (*resolution)[0] = syzstr->res[1]->rank;
+      int k=0;
+      while ((k<syzstr->length) && (rP[k]!=NULL))
+      {
+        int j = 0;
+        while ((j<(*syzstr->Tl)[k]) &&
+          ((rP[k][j].lcm!=NULL) || (rP[k][j].syz!=NULL)))
+        {
+          if (rP[k][j].isNotMinimal==NULL)
+            ((*resolution)[k+1])++;
+          j++;
+        }
+        k++;
+      }
+    }
+    else
+    {
+      resolution = new intvec(syzstr->length+2);
+      resolvente rr;
+      if (syzstr->minres!=NULL)
+        rr = syzstr->minres;
+      else
+        rr = syzstr->fullres;
+      (*resolution)[0]
+        = si_max(1,(int)id_RankFreeModule(rr[0],
+                                 (syzstr->syRing != NULL ? syzstr->syRing : currRing)));
+      int k=0;
+      while ((k<syzstr->length) && (rr[k]!=NULL))
+      {
+        (*resolution)[k+1] = idSize(rr[k]);
+        k++;
+      }
+    }
+  }
+
+  int sl=strlen(sn);
+  syPrintEmptySpaces1(sl);
+  int k = 0;
+  loop
+  {
+    if ((k>=resolution->length()) || ((*resolution)[k]==0))
+      break;
+    Print("%d",(*resolution)[k]);
+    syPrintEmptySpaces1(sl+5);
+    k++;
+  }
+  PrintLn();
+  k = 0;
+  loop
+  {
+    if ((k>=resolution->length()) || ((*resolution)[k]==0))
+      break;
+    PrintS(sn);
+    if (((k+1)>=resolution->length()) || ((*resolution)[(k+1)]==0))
+      break;
+    PrintS(" <-- ");
+    syPrintEmptySpaces((*resolution)[k]);
+    k++;
+  }
+  PrintLn();
+  PrintLn();
+  k = 0;
+  loop
+  {
+    if ((k>=resolution->length()) || ((*resolution)[k]==0))
+      break;
+    Print("%d",k);
+    syPrintEmptySpaces1(sl+5+syLengthInt((*resolution)[k])-
+                         syLengthInt(k));
+    k++;
+  }
+  PrintLn();
+  if (syzstr->minres==NULL)
+  {
+    PrintS("resolution not minimized yet");
+    PrintLn();
+  }
+
+  if (syzstr->resolution == NULL) syzstr->resolution = resolution;
+}
+
+/*2
+* deleting all monomials the component of which correspond
+* to non-minimal generators
+*/
+static poly syStripOut(poly p,intvec * toStrip)
+{
+  if (toStrip==NULL) return p;
+  poly pp=p;
+
+  while ((pp!=NULL) && ((*toStrip)[pGetComp(pp)]!=0))
+    pLmDelete(&pp);
+  p = pp;
+  if (pp!=NULL)
+  {
+    while (pNext(pp)!=NULL)
+    {
+      if ((*toStrip)[pGetComp(pNext(pp))]!=0)
+        pLmDelete(&pNext(pp));
+      else
+        pIter(pp);
+    }
+  }
+  return p;
+}
+
+/*2
+* copies only those monomials the component of which correspond
+* to minimal generators
+*/
+static poly syStripOutCopy(poly p,intvec * toStrip)
+{
+  if (toStrip==NULL) return pCopy(p);
+  poly result=NULL,pp;
+
+  while (p!=NULL)
+  {
+    if ((*toStrip)[pGetComp(p)]==0)
+    {
+      if (result==NULL)
+      {
+        result = pp = pHead(p);
+      }
+      else
+      {
+        pNext(pp) = pHead(p);
+        pIter(pp);
+      }
+    }
+    pIter(p);
+  }
+  return result;
+}
+
+/*2
+* minimizes toMin
+*/
+#if 0 /* unused */
+static poly syMinimizeP(int toMin,syStrategy syzstr,intvec * ordn,int index,
+                        intvec * toStrip)
+{
+  int ii=0,i,j,tc;
+  poly p,pp,q=NULL,tq,pisN;
+  SSet sPairs=syzstr->resPairs[index];
+  poly tempStripped=NULL;
+
+  //pp=pCopy(syzstr->res[index+1]->m[toMin]);
+  pp = syStripOutCopy(syzstr->res[index+1]->m[toMin],toStrip);
+  while ((ii<ordn->length()) && ((*ordn)[ii]!=-1) &&
+             (sPairs[(*ordn)[ii]].syzind!=toMin))
+  {
+    ii++;
+  }
+  while (ii>=0)
+  {
+    i = (*ordn)[ii];
+    if (sPairs[i].isNotMinimal!=NULL)
+    {
+      tempStripped =
+        syStripOutCopy(syzstr->res[index+1]->m[sPairs[i].syzind],toStrip);
+      pisN = sPairs[i].isNotMinimal;
+      tc = pGetComp(pisN);
+      p = pp;
+      while (p!=NULL)
+      {
+        if (pGetComp(p)==(unsigned)tc)
+        {
+          tq = pInit();
+          for(j=(currRing->N); j>0; j--)
+            pSetExp(tq,j, pGetExp(p,j)-pGetExp(pisN,j));
+          pSetComp(tq, 0);
+          pSetCoeff0(tq,nDiv(pGetCoeff(p),pGetCoeff(pisN)));
+          pGetCoeff(tq) = nInpNeg(pGetCoeff(tq));
+          pSetm(tq);
+          q = pAdd(q,pMult_mm(pCopy(tempStripped),tq));
+          pDelete(&tq);
+        }
+        pIter(p);
+      }
+      if (q!=NULL)
+      {
+        pp = pAdd(pp,q);
+        q = NULL;
+      }
+      pDelete(&tempStripped);
+    }
+    ii--;
+  }
+  return pp;
+}
+#endif
+
+/*2
+* minimizes toMin
+*/
+static poly syMinimizeP1(int toMin,syStrategy syzstr,intvec * ordn,int index,
+                        intvec * toStrip)
+{
+  int ii=0,i,tc,lp,ltS=-1;
+  poly p,mp=NULL,pp;
+  SSet sPairs=syzstr->resPairs[index];
+  poly tempStripped=NULL;
+
+  pp = syStripOutCopy(syzstr->res[index+1]->m[toMin],toStrip);
+  kBucketInit(syzstr->bucket,pp,-1);
+  while ((ii<ordn->length()) && ((*ordn)[ii]!=-1) &&
+             (sPairs[(*ordn)[ii]].syzind!=toMin))
+  {
+    ii++;
+  }
+  while (ii>=0)
+  {
+    i = (*ordn)[ii];
+    if (sPairs[i].isNotMinimal!=NULL)
+    {
+      tempStripped =
+        syStripOutCopy(syzstr->res[index+1]->m[sPairs[i].syzind],toStrip);
+      tc = pGetComp(sPairs[i].isNotMinimal);
+      //p = pTakeOutComp1(&tempStripped,tc);
+      int lu;
+      pTakeOutComp(&tempStripped,tc,&p,&lu);
+      kBucketTakeOutComp(syzstr->bucket,tc,&mp,&lp);
+      mp = pDivideM(mp,p);
+      while (mp!=NULL)
+      {
+        p = pNext(mp);
+        pNext(mp) = NULL;
+        ltS = -1;
+        kBucket_Minus_m_Mult_p(syzstr->bucket,mp,tempStripped,&ltS);
+        pDelete(&mp);
+        mp = p;
+      }
+      pDelete(&mp);
+      pDelete(&tempStripped);
+    }
+    ii--;
+  }
+  kBucketClear(syzstr->bucket,&pp,&lp);
+  return pp;
+}
+
+/*2
+* deletes empty components after minimization
+*/
+void syKillEmptyEntres(resolvente res,int length)
+{
+  int i,j,jj,k,rj;
+  intvec * changes;
+  poly p;
+  ideal ri;
+
+  for (i=0;i<length;i++)
+  {
+    ri = res[i];
+    if (ri!=NULL)
+    {
+      rj = IDELEMS(ri);
+      changes = new intvec(rj+1,1,-1);
+      while ((rj>0) && (ri->m[rj-1]==NULL)) rj--;
+      j = k = 0;
+      while (j+k<rj)
+      {
+        if (ri->m[j+k]!=NULL)
+        {
+          ri->m[j] = ri->m[j+k];
+          (*changes)[j+k+1] = j+1;
+          j++;
+        }
+        else
+        {
+          k++;
+        }
+      }
+      for (jj=j;jj<rj;jj++)
+        ri->m[jj] = NULL;
+      if (res[i+1]!=NULL)
+      {
+        ri = res[i+1];
+        for (j=IDELEMS(ri)-1;j>=0;j--)
+        {
+          p = ri->m[j];
+          while (p!=NULL)
+          {
+            pSetComp(p,(*changes)[pGetComp(p)]);
+            pSetm(p);
+            pIter(p);
+          }
+        }
+      }
+      delete changes;
+    }
+  }
+}
+
+/*2
+* determines the components for minimization
+*/
+static intvec * syToStrip(syStrategy syzstr, int index)
+{
+  intvec * result=NULL;
+
+  if ((syzstr->resPairs[index-1]!=NULL) && (!idIs0(syzstr->res[index])))
+  {
+    result=new intvec(IDELEMS(syzstr->res[index])+1);
+    for (int i=(*syzstr->Tl)[index-1]-1;i>=0;i--)
+    {
+      if (syzstr->resPairs[index-1][i].isNotMinimal!=NULL)
+      {
+        (*result)[syzstr->resPairs[index-1][i].syzind+1] = 1;
+      }
+    }
+  }
+  return result;
+}
+
+/*2
+* re-computes the order of pairs during the algorithm
+* this ensures to procede with a triangular matrix
+*/
+static intvec * syOrdPairs(SSet sPairs, int length)
+{
+  intvec * result=new intvec(length,1,-1);
+  int i,j=0,k=-1,l,ii;
+
+  loop
+  {
+    l = -1;
+    for(i=0;i<length;i++)
+    {
+      if (sPairs[i].syzind>k)
+      {
+        if (l==-1)
+        {
+          l = sPairs[i].syzind;
+          ii = i;
+        }
+        else
+        {
+          if (sPairs[i].syzind<l)
+          {
+            l = sPairs[i].syzind;
+            ii = i;
+          }
+        }
+      }
+    }
+    if (l==-1) break;
+    (*result)[j] = ii;
+    j++;
+    k = l;
+  }
+  return result;
+}
+
+/*2
+* minimizes the output of LaScala
+*/
+static resolvente syReadOutMinimalRes(syStrategy syzstr,
+           BOOLEAN computeStd=FALSE)
+{
+  intvec * Strip, * ordn;
+  resolvente tres=(resolvente)omAlloc0((syzstr->length+1)*sizeof(ideal));
+  ring origR = currRing;
+
+//Print("Hier ");
+  if (computeStd)
+  {
+    tres[0] = syzstr->res[1];
+    syzstr->res[1] = idInit(IDELEMS(tres[0]),tres[0]->rank);
+    return tres;
+  }
+  int i,l,index,i1;
+  SSet sPairs;
+
+  assume(syzstr->syRing != NULL);
+  rChangeCurrRing(syzstr->syRing);
+//Print("laeufts ");
+  syzstr->bucket = kBucketCreate(syzstr->syRing);
+  for (index=syzstr->length-1;index>0;index--)
+  {
+    if (syzstr->resPairs[index]!=NULL)
+    {
+//Print("ideal %d: \n",index);
+      currcomponents = syzstr->truecomponents[index];
+      currShiftedComponents = syzstr->ShiftedComponents[index];
+      rChangeSComps(currcomponents, currShiftedComponents,
+                    IDELEMS(syzstr->res[index]), currRing);
+      sPairs = syzstr->resPairs[index];
+      Strip = syToStrip(syzstr,index);
+      tres[index+1] = idInit(IDELEMS(syzstr->res[index+1]),syzstr->res[index+1]->rank);
+      i1 = (*syzstr->Tl)[index];
+//Print("i1= %d\n",i1);
+      ordn = syOrdPairs(sPairs,i1);
+      for (i=0;i<i1;i++)
+      {
+        if ((sPairs[i].isNotMinimal==NULL) && (sPairs[i].lcm!=NULL))
+        {
+          l = sPairs[i].syzind;
+//Print("Minimiere Poly %d: ",l);pWrite(syzstr->res[index+1]->m[l]);
+          tres[index+1]->m[l] =
+            syMinimizeP1(l,syzstr,ordn,index,Strip);
+        }
+      }
+      delete Strip;
+      delete ordn;
+      Strip = NULL;
+    }
+  }
+  currcomponents = syzstr->truecomponents[0];
+  currShiftedComponents = syzstr->ShiftedComponents[0];
+  rChangeSComps( currcomponents, currShiftedComponents,
+                 IDELEMS(syzstr->res[0]), currRing);
+  tres[1] = idInit(IDELEMS(syzstr->res[1]),syzstr->res[1]->rank);
+  sPairs = syzstr->resPairs[0];
+  for (i=(*syzstr->Tl)[0]-1;i>=0;i--)
+  {
+    if (sPairs[i].syzind>=0)
+    {
+      tres[1]->m[sPairs[i].syzind] = pCopy(syzstr->res[1]->m[sPairs[i].syzind]);
+    }
+  }
+/*--- changes to the original ring------------------*/
+  kBucketDestroy(&syzstr->bucket);
+  if (syzstr->syRing != NULL)
+  {
+    rChangeCurrRing(origR);
+    // Thomas: now make sure that all data which you need is pFetchCopied
+    // maybe incoporate it into syReorder ??
+  }
+  tres = syReorder(tres,syzstr->length,syzstr,FALSE,syzstr->res);
+  syKillEmptyEntres(tres,syzstr->length);
+  idSkipZeroes(tres[0]);
+  return tres;
+}
+
+/*3
+* minimizes any kind of resolution
+*/
+syStrategy syMinimize(syStrategy syzstr)
+{
+  if (syzstr->minres==NULL)
+  {
+    if (syzstr->resPairs!=NULL)
+    {
+      if (syzstr->hilb_coeffs==NULL)
+      {
+        // La Scala Resolution
+        syzstr->minres = syReadOutMinimalRes(syzstr);
+      }
+      else
+      { // HRES
+        syzstr->minres = syReorder(syzstr->orderedRes,syzstr->length,syzstr);
+      }
+    }
+    else if (syzstr->fullres!=NULL)
+    {
+      syMinimizeResolvente(syzstr->fullres,syzstr->length,1);
+      syzstr->minres = syzstr->fullres;
+      syzstr->fullres = NULL;
+    }
+  }
+  (syzstr->references)++;
+  return syzstr;
+}
+
+/*2
+* implementation of LaScala's algorithm
+* assumes that the given module is homogeneous
+* works with slanted degree, uses syChosePairs
+*/
+syStrategy syLaScala3(ideal arg,int * length)
+{
+  int i,j,actdeg=32000,index=0;
+  int howmuch;
+  ideal temp;
+  SSet nextPairs;
+  syStrategy syzstr=(syStrategy)omAlloc0(sizeof(ssyStrategy));
+  ring origR = currRing;
+
+  if ((idIs0(arg)) ||
+      ((id_RankFreeModule(arg,currRing)>0) && (!idHomModule(arg,NULL,&(syzstr->cw)))))
+  {
+    syzstr->minres = (resolvente)omAlloc0Bin(char_ptr_bin);
+    syzstr->length = 1;
+    syzstr->minres[0] = idInit(1,arg->rank);
+    return syzstr;
+  }
+
+  //crit = 0;
+  //euler = -1;
+  redpol = pInit();
+  syzstr->length = *length = (currRing->N)+2;
+
+  // Creare dp,S ring and change to it
+  syzstr->syRing = rAssure_dp_S(origR);
+  assume(syzstr->syRing != origR); // why?
+  rChangeCurrRing(syzstr->syRing);
+
+  // set initial ShiftedComps
+  currcomponents = (int*)omAlloc0((arg->rank+1)*sizeof(int));
+  currShiftedComponents = (long*)omAlloc0((arg->rank+1)*sizeof(long));
+  for (i=0;i<=arg->rank;i++)
+  {
+    currShiftedComponents[i] = (i)*SYZ_SHIFT_BASE;
+    currcomponents[i] = i;
+  }
+  rChangeSComps(currcomponents, currShiftedComponents, arg->rank, syzstr->syRing);
+/*--- initializes the data structures---------------*/
+  syzstr->Tl = new intvec(*length);
+  temp = idInit(IDELEMS(arg),arg->rank);
+  for (i=0;i<IDELEMS(arg);i++)
+  {
+    temp->m[i] = prCopyR( arg->m[i], origR, syzstr->syRing);
+    if (temp->m[i]!=NULL)
+    {
+      j = pTotaldegree(temp->m[i]);
+      if (j<actdeg) actdeg = j;
+    }
+  }
+  idTest(temp);
+  idSkipZeroes(temp);
+  idTest(temp);
+  syzstr->resPairs = syInitRes(temp,length,syzstr->Tl,syzstr->cw);
+  omFreeSize((ADDRESS)currcomponents,(arg->rank+1)*sizeof(int));
+  omFreeSize((ADDRESS)currShiftedComponents,(arg->rank+1)*sizeof(long));
+  syzstr->res = (resolvente)omAlloc0((*length+1)*sizeof(ideal));
+  syzstr->orderedRes = (resolvente)omAlloc0((*length+1)*sizeof(ideal));
+  syzstr->elemLength = (int**)omAlloc0((*length+1)*sizeof(int*));
+  syzstr->truecomponents = (int**)omAlloc0((*length+1)*sizeof(int*));
+  syzstr->ShiftedComponents = (long**)omAlloc0((*length+1)*sizeof(long*));
+  syzstr->backcomponents = (int**)omAlloc0((*length+1)*sizeof(int*));
+  syzstr->Howmuch = (int**)omAlloc0((*length+1)*sizeof(int*));
+  syzstr->Firstelem = (int**)omAlloc0((*length+1)*sizeof(int*));
+  syzstr->sev = (unsigned long **) omAlloc0((*length+1)*sizeof(unsigned long *));
+  syzstr->bucket = kBucketCreate(currRing);
+  int len0=id_RankFreeModule(temp,currRing)+1;
+
+  nextPairs = syChosePairs(syzstr,&index,&howmuch,&actdeg);
+  //if (TEST_OPT_PROT) Print("(%d,%d)",howmuch,index);
+/*--- computes the resolution ----------------------*/
+  while (nextPairs!=NULL)
+  {
+    if (TEST_OPT_PROT) Print("%d",actdeg);
+    if (TEST_OPT_PROT) Print("(m%d)",index);
+    if (index==0)
+      i = syInitSyzMod(syzstr,index,len0);
+    else
+      i = syInitSyzMod(syzstr,index);
+    currcomponents = syzstr->truecomponents[si_max(index-1,0)];
+    currShiftedComponents = syzstr->ShiftedComponents[si_max(index-1,0)];
+    rChangeSComps(currcomponents, currShiftedComponents,
+                  IDELEMS(syzstr->res[si_max(index-1,0)]), currRing);
+    j = syInitSyzMod(syzstr,index+1);
+    if (index>0)
+    {
+      syRedNextPairs(nextPairs,syzstr,howmuch,index);
+      syCompactifyPairSet(syzstr->resPairs[index],(*syzstr->Tl)[index],0);
+    }
+    else
+      syRedGenerOfCurrDeg(syzstr,actdeg,index+1);
+/*--- creates new pairs -----------------------------*/
+    syCreateNewPairs(syzstr,index,i);
+    if (index<(*length)-1)
+    {
+      syCreateNewPairs(syzstr,index+1,j);
+    }
+    index++;
+    nextPairs = syChosePairs(syzstr,&index,&howmuch,&actdeg);
+    //if (TEST_OPT_PROT) Print("(%d,%d)",howmuch,index);
+  }
+  if (temp!=NULL) idDelete(&temp);
+  kBucketDestroy(&(syzstr->bucket));
+
+  if (origR != syzstr->syRing)
+    rChangeCurrRing(origR);
+  pLmDelete(&redpol);
+
+  if (TEST_OPT_PROT) PrintLn();
+
+  assume(syzstr->minres==NULL); assume(syzstr->fullres ==NULL);
+  assume(syzstr->resPairs!=NULL);  assume(syzstr->hilb_coeffs==NULL);
+  assume(syzstr->res!=NULL);
+
+  if(! TEST_OPT_NO_SYZ_MINIM )
+    syzstr->minres = syReadOutMinimalRes(syzstr);
+  else
+    syzstr->fullres = syReorder(syzstr->res, syzstr->length, syzstr); // buggy? (betti...?)
+
+  return syzstr;
+}
+
+
+
+/*2
+* more general implementation of LaScala's algorithm
+* assumes that the given module is (quasi-)homogeneous
+* works with slanted degree, uses syChosePairs
+*/
+syStrategy syLaScala(ideal arg, int& maxlength, intvec* weights)
+{
+  int i,j,actdeg=32000,index=0;
+  int howmuch;
+  ideal temp;
+  SSet nextPairs;
+  syStrategy syzstr=(syStrategy)omAlloc0(sizeof(ssyStrategy));
+  ring origR = currRing;
+
+  if(weights!= NULL)
+    syzstr->cw = new intvec(weights);
+  else
+    syzstr->cw = NULL;
+
+  if ((idIs0(arg)) ||
+      ((id_RankFreeModule(arg,currRing)>0) && (!idTestHomModule(arg, NULL, syzstr->cw))))
+  {
+    syzstr->minres = (resolvente)omAlloc0Bin(char_ptr_bin);
+    syzstr->length = 1;
+    syzstr->minres[0] = idInit(1,arg->rank);
+    return syzstr;
+  }
+
+
+  //crit = 0;
+  //euler = -1;
+  redpol = pInit();
+
+  if( maxlength > 0 )
+    syzstr->length = maxlength; //  = (currRing->N)+2;
+  else
+    syzstr->length = maxlength = (currRing->N)+2;
+
+  // Creare dp,S ring and change to it
+  syzstr->syRing = rAssure_dp_S(origR);
+  assume(syzstr->syRing != origR);
+  assume(syzstr->syRing->typ[1].ord_typ == ro_syzcomp);
+  rChangeCurrRing(syzstr->syRing);
+
+  // set initial ShiftedComps
+  currcomponents = (int*)omAlloc0((arg->rank+1)*sizeof(int));
+  currShiftedComponents = (long*)omAlloc0((arg->rank+1)*sizeof(long));
+  for (i=0;i<=arg->rank;i++)
+  {
+    currShiftedComponents[i] = (i)*SYZ_SHIFT_BASE;
+    currcomponents[i] = i;
+  }
+  rChangeSComps(currcomponents, currShiftedComponents, arg->rank, currRing);
+/*--- initializes the data structures---------------*/
+  syzstr->Tl = new intvec(maxlength);
+  temp = idInit(IDELEMS(arg),arg->rank);
+  for (i=0;i<IDELEMS(arg);i++)
+  {
+    temp->m[i] = prCopyR( arg->m[i], origR, currRing);
+    if (temp->m[i]!=NULL)
+    {
+      j = pTotaldegree(temp->m[i]);
+      if (j<actdeg) actdeg = j;
+    }
+  }
+  idTest(temp);
+  idSkipZeroes(temp);
+  idTest(temp);
+  syzstr->resPairs = syInitRes(temp,&maxlength,syzstr->Tl,syzstr->cw);
+  omFreeSize((ADDRESS)currcomponents,(arg->rank+1)*sizeof(int));
+  omFreeSize((ADDRESS)currShiftedComponents,(arg->rank+1)*sizeof(long));
+
+  syzstr->res = (resolvente)omAlloc0((maxlength+1)*sizeof(ideal));
+  syzstr->orderedRes = (resolvente)omAlloc0((maxlength+1)*sizeof(ideal));
+  syzstr->elemLength = (int**)omAlloc0((maxlength+1)*sizeof(int*));
+
+  syzstr->truecomponents = (int**)omAlloc0((maxlength+1)*sizeof(int*));
+  syzstr->ShiftedComponents = (long**)omAlloc0((maxlength+1)*sizeof(long*));
+
+  syzstr->backcomponents = (int**)omAlloc0((maxlength+1)*sizeof(int*));
+  syzstr->Howmuch = (int**)omAlloc0((maxlength+1)*sizeof(int*));
+  syzstr->Firstelem = (int**)omAlloc0((maxlength+1)*sizeof(int*));
+  syzstr->sev = (unsigned long **) omAlloc0((maxlength+1)*sizeof(unsigned long *));
+
+  assume( syzstr->length == maxlength );
+
+  syzstr->bucket = kBucketCreate(currRing);
+  int len0=id_RankFreeModule(temp,currRing)+1;
+
+  nextPairs = syChosePairs(syzstr,&index,&howmuch,&actdeg);
+  //if (TEST_OPT_PROT) Print("(%d,%d)",howmuch,index);
+/*--- computes the resolution ----------------------*/
+  while (nextPairs!=NULL)
+  {
+    if (TEST_OPT_PROT) Print("%d",actdeg);
+    if (TEST_OPT_PROT) Print("(m%d)",index);
+    if (index==0)
+      i = syInitSyzMod(syzstr,index,len0);
+    else
+      i = syInitSyzMod(syzstr,index);
+    currcomponents = syzstr->truecomponents[si_max(index-1,0)];
+    currShiftedComponents = syzstr->ShiftedComponents[si_max(index-1,0)];
+    rChangeSComps(currcomponents, currShiftedComponents,
+                  IDELEMS(syzstr->res[si_max(index-1,0)]), currRing);
+    j = syInitSyzMod(syzstr,index+1);
+    if (index>0)
+    {
+      syRedNextPairs(nextPairs,syzstr,howmuch,index);
+      syCompactifyPairSet(syzstr->resPairs[index],(*syzstr->Tl)[index],0);
+    }
+    else
+      syRedGenerOfCurrDeg(syzstr,actdeg,index+1);
+/*--- creates new pairs -----------------------------*/
+    syCreateNewPairs(syzstr,index,i);
+    if (index<(maxlength-1))
+    {
+      syCreateNewPairs(syzstr,index+1,j);
+    }
+    index++;
+    nextPairs = syChosePairs(syzstr,&index,&howmuch,&actdeg);
+    //if (TEST_OPT_PROT) Print("(%d,%d)",howmuch,index);
+  }
+  if (temp!=NULL) idDelete(&temp);
+  kBucketDestroy(&(syzstr->bucket));
+  if (origR != syzstr->syRing)
+    rChangeCurrRing(origR);
+  pLmDelete(&redpol);
+  if (TEST_OPT_PROT) PrintLn();
+  return syzstr;
+}
+
diff --git a/kernel/GBEngine/syz2.cc b/kernel/GBEngine/syz2.cc
new file mode 100644
index 0000000..f087558
--- /dev/null
+++ b/kernel/GBEngine/syz2.cc
@@ -0,0 +1,1095 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: resolutions
+*/
+
+
+
+
+
+#include <kernel/mod2.h>
+
+#include <omalloc/omalloc.h>
+
+#include <misc/mylimits.h>
+#include <misc/options.h>
+#include <misc/intvec.h>
+//#include "cntrlc.h"
+
+#include <coeffs/coeffs.h>
+#include <coeffs/numbers.h>
+
+#include <polys/monomials/ring.h>
+#include <polys/kbuckets.h>
+#include <polys/prCopy.h>
+
+#include <kernel/combinatorics/stairc.h>
+#include <kernel/combinatorics/hilb.h>
+
+#include <kernel/GBEngine/kstd1.h>
+#include <kernel/GBEngine/kutil.h>
+#include <kernel/GBEngine/syz.h>
+
+#include <kernel/ideals.h>
+#include <kernel/polys.h>
+
+
+
+
+
+//#define SHOW_PROT
+//#define SHOW_RED
+//#define SHOW_HILB
+//#define SHOW_RESULT
+//#define INVERT_PAIRS
+//#define SHOW_CRIT
+//#define SHOW_SPRFL
+#define USE_CHAINCRIT
+#define poly_write(p) wrp(p);PrintLn()
+/*--- some heuristics to optimize the pair sets---*/
+/*--- chose only one (!!!) at the same time ------*/
+//#define USE_HEURISTIC1
+#define USE_HEURISTIC2
+
+#ifdef SHOW_CRIT
+static int crit;
+static int crit1;
+static int spfl;
+static int cons_pairs;
+static int crit_fails;
+#endif
+typedef struct sopen_pairs open_pairs;
+typedef open_pairs* crit_pairs;
+struct sopen_pairs
+{
+  crit_pairs next;
+  int first_poly;
+  int second_poly;
+};
+/*3
+* computes pairs from the new elements (beginning with the element newEl)
+* in the module index
+*/
+static void syCreateNewPairs_Hilb(syStrategy syzstr, int index,
+            int actdeg)
+{
+  SObject tso;
+  poly toHandle,p,pp;
+  int r1,r2=0,rr,l=(*syzstr->Tl)[index];
+  int i,j,r=0,ti;
+  BOOLEAN toComp=FALSE;
+#ifdef USE_CHAINCRIT
+  crit_pairs cp=NULL,tcp;
+#endif
+  actdeg += index;
+
+  while ((l>0) && ((syzstr->resPairs[index])[l-1].lcm==NULL)) l--;
+  rr = l-1;
+  while ((rr>=0) && (((syzstr->resPairs[index])[rr].p==NULL) ||
+        ((syzstr->resPairs[index])[rr].order>actdeg))) rr--;
+  r2 = rr+1;
+  while ((rr>=0) && ((syzstr->resPairs[index])[rr].order==actdeg)
+         && ((syzstr->resPairs[index])[rr].syzind<0))
+  {
+    rr--;
+    r++;
+  }
+  if (r==0) return;
+  ideal nP=idInit(l,syzstr->res[index]->rank);
+#ifdef INVERT_PAIRS
+  r1 = rr+1;
+#else
+  r1 = r2-1;
+#endif
+/*---------- there are new pairs ------------------------------*/
+  loop
+  {
+/*--- chose first new elements --------------------------------*/
+    toComp = FALSE;
+    toHandle = (syzstr->resPairs[index])[r1].p;
+    if (toHandle!=NULL)
+    {
+      int tc=pGetComp(toHandle);
+      (syzstr->resPairs[index])[r1].syzind = 0;
+      for (i=0; i<r1;i++)
+      {
+        if (((syzstr->resPairs[index])[i].p!=NULL) &&
+            (pGetComp((syzstr->resPairs[index])[i].p)==(unsigned)tc))
+        {
+#ifdef USE_CHAINCRIT
+          tcp = cp;
+          if (tcp!=NULL)
+          {
+            while ((tcp!=NULL) &&
+              ((tcp->first_poly!=i)||(tcp->second_poly!=r1))) tcp = tcp->next;
+          }
+          if (tcp==NULL)
+          {
+#endif
+            p = pOne();
+            pLcm((syzstr->resPairs[index])[i].p,toHandle,p);
+            pSetm(p);
+            j = 0;
+            while (j<i)
+            {
+              if (nP->m[j]!=NULL)
+              {
+                if (pLmDivisibleByNoComp(nP->m[j],p))
+                {
+                  pDelete(&p);
+                  /* p = NULL;*/
+                  break;
+                }
+                else if (pLmDivisibleByNoComp(p,nP->m[j]))
+                {
+                  pDelete(&(nP->m[j]));
+                  /* nP->m[j] = NULL;*/
+                }
+#ifdef USE_CHAINCRIT
+                else
+                {
+                  poly p1,p2;
+                  int ip= currRing->N;
+                  p1 = pDivide(p,(syzstr->resPairs[index])[i].p);
+                  p2 = pDivide(nP->m[j],(syzstr->resPairs[index])[j].p);
+                  while ((ip>0) && (pGetExp(p1,ip)*pGetExp(p2,ip)==0)) ip--;
+                  if (ip==0)
+                  {
+#ifdef SHOW_SPRFL
+Print("Hier: %d, %d\n",j,i);
+#endif
+                    if (i>rr)
+                    {
+                      tcp=(crit_pairs)omAlloc0(sizeof(sopen_pairs));
+                      tcp->next = cp;
+                      tcp->first_poly = j;
+                      tcp->second_poly = i;
+                      cp = tcp;
+                      tcp = NULL;
+                    }
+                    else
+                    {
+                      ti=0;
+                      while ((ti<l) && (((syzstr->resPairs[index])[ti].ind1!=j)||
+                             ((syzstr->resPairs[index])[ti].ind2!=i))) ti++;
+                      if (ti<l)
+                      {
+#ifdef SHOW_SPRFL
+Print("gefunden in Mod %d: ",index); poly_write((syzstr->resPairs[index])[ti].lcm);
+#endif
+                        syDeletePair(&(syzstr->resPairs[index])[ti]);
+#ifdef SHOW_CRIT
+                        crit1++;
+#endif
+                        toComp = TRUE;
+                      }
+                    }
+                  }
+                  pLmDelete(&p1);
+                  pLmDelete(&p2);
+                }
+#endif
+              }
+              j++;
+            }
+            if (p!=NULL)
+            {
+              nP->m[i] = p;
+            }
+#ifdef USE_CHAINCRIT
+          }
+          else
+          {
+#ifdef SHOW_CRIT
+            crit1++;
+#endif
+          }
+#endif
+        }
+      }
+      if (toComp) syCompactify1(syzstr->resPairs[index],&l,r1);
+      for (i=0;i<r1;i++)
+      {
+        if (nP->m[i]!=NULL)
+        {
+          tso.lcm = p = nP->m[i];
+          nP->m[i] = NULL;
+          tso.order = pTotaldegree(p);
+          if ((syzstr->cw!=NULL) && (index>0) && (pGetComp(p)>0))
+          {
+            int ii=index-1,jj=pGetComp(p);
+            while (ii>0)
+            {
+              jj = pGetComp(syzstr->res[ii]->m[jj-1]);
+              ii--;
+            }
+            tso.order += (*syzstr->cw)[jj-1];
+          }
+          tso.p1 = (syzstr->resPairs[index])[i].p;
+          tso.p2 = toHandle;
+          tso.ind1 = i;
+          tso.ind2 = r1;
+          tso.syzind = -1;
+          tso.isNotMinimal = (poly)1;
+          tso.p = NULL;
+          tso.length = -1;
+          number coefgcd =
+            n_SubringGcd(pGetCoeff(tso.p1),pGetCoeff(tso.p2),currRing->cf);
+          tso.syz = pCopy((syzstr->resPairs[index])[i].syz);
+          poly tt = pDivide(tso.lcm,tso.p1);
+          pSetCoeff(tt,nDiv(pGetCoeff(tso.p1),coefgcd));
+          tso.syz = pMult_mm(tso.syz,tt);
+          pLmDelete(&tt);
+          coefgcd = nInpNeg(coefgcd);
+          pp = pCopy((syzstr->resPairs[index])[r1].syz);
+          tt = pDivide(tso.lcm,tso.p2);
+          pSetCoeff(tt,nDiv(pGetCoeff(tso.p2),coefgcd));
+          pp = pMult_mm(pp,tt);
+          pLmDelete(&tt);
+          tso.syz = pAdd(pp,tso.syz);
+          nDelete(&coefgcd);
+          pSetComp(tso.lcm,pGetComp((syzstr->resPairs[index])[r1].syz));
+#ifdef SHOW_PROT
+Print("erzeuge Paar im Modul %d,%d mit: \n",index,tso.order);
+PrintS("poly1: ");poly_write(tso.p1);
+PrintS("poly2: ");poly_write(tso.p2);
+PrintS("syz: ");poly_write(tso.syz);
+PrintS("sPoly: ");poly_write(tso.p);
+PrintLn();
+#endif
+          syEnterPair(syzstr,&tso,&l,index);
+        }
+      }
+    }
+#ifdef INVERT_PAIRS
+    r1++;
+    if (r1>=r2) break;
+#else
+    r1--;
+    if (r1<=rr) break;
+#endif
+  }
+  idDelete(&nP);
+#ifdef USE_CHAINCRIT
+  while (cp!=NULL)
+  {
+    tcp = cp;
+    cp = cp->next;
+    omFreeSize((ADDRESS)tcp,sizeof(sopen_pairs));
+  }
+#endif
+}
+
+/*3
+* determines the place of a polynomial in the right ordered resolution
+* set the vectors of truecomponents
+*/
+static void syOrder_Hilb(poly p,syStrategy syzstr,int index)
+{
+  int i=IDELEMS(syzstr->orderedRes[index]);
+
+  while ((i>0) && (syzstr->orderedRes[index]->m[i-1]==NULL)) i--;
+  syzstr->orderedRes[index]->m[i] = p;
+}
+
+static void syHalfPair(poly syz, int newEl, syStrategy syzstr, int index)
+{
+  SObject tso;
+  memset(&tso,0,sizeof(tso));
+  int l=(*syzstr->Tl)[index];
+
+  while ((l>0) && ((syzstr->resPairs[index])[l-1].syz==NULL)) l--;
+  if ((syzstr->cw!=NULL) && (index>0) && (pGetComp(syz)>0))
+  {
+    int ii=index-1,jj=pGetComp(syz);
+    while (ii>0)
+    {
+      jj = pGetComp(syzstr->res[ii]->m[jj-1]);
+      ii--;
+    }
+    tso.order += (*syzstr->cw)[jj-1];
+  }
+  tso.p1 = NULL;
+  tso.p2 = NULL;
+  tso.ind1 = 0;
+  tso.ind2 = 0;
+  tso.syzind = -1;
+  tso.isNotMinimal = NULL;
+  tso.p = syz;
+  tso.order = pTotaldegree(syz);
+  tso.syz = pHead(syz);
+  pSetComp(tso.syz,newEl+1);
+  pSetm(tso.syz);
+  tso.lcm = pHead(tso.syz);
+  tso.length = pLength(syz);
+  syOrder_Hilb(syz,syzstr,index);
+#ifdef SHOW_PROT
+Print("erzeuge Halbpaar im Module %d,%d mit: \n",index,tso.order);
+PrintS("syz: ");poly_write(tso.syz);
+PrintS("sPoly: ");poly_write(tso.p);
+PrintLn();
+#endif
+  syEnterPair(syzstr,&tso,&l,index);
+}
+/*3
+* computes the order of pairs of same degree
+* must be monoton
+*/
+static intvec* syLinStrat2(SSet nextPairs, syStrategy syzstr,
+                          int howmuch, int index,intvec ** secondpairs)
+{
+  ideal o_r=syzstr->res[index+1];
+  int i=0,i1=0,i2=0,l,ll=IDELEMS(o_r);
+  intvec *result=new intvec(howmuch+1);
+  BOOLEAN isDivisible;
+  SObject tso;
+
+#ifndef USE_HEURISTIC2
+  while (i1<howmuch)
+  {
+    (*result)[i1] = i1+1;
+    i1++;
+  }
+  return result;
+#else
+  while ((ll>0) && (o_r->m[ll-1]==NULL)) ll--;
+  while (i<howmuch)
+  {
+    tso = nextPairs[i];
+    isDivisible = FALSE;
+    l = 0;
+    while ((l<ll) && (!isDivisible))
+    {
+      if (o_r->m[l]!=NULL)
+      {
+        isDivisible = isDivisible ||
+          pLmDivisibleBy(o_r->m[l],tso.lcm);
+      }
+      l++;
+    }
+    if (isDivisible)
+    {
+#ifdef SHOW_PROT
+Print("streiche Paar im Modul %d,%d mit: \n",index,nextPairs[i].order);
+PrintS("poly1: ");poly_write(nextPairs[i].p1);
+PrintS("poly2: ");poly_write(nextPairs[i].p2);
+PrintS("syz: ");poly_write(nextPairs[i].syz);
+PrintS("sPoly: ");poly_write(nextPairs[i].p);
+PrintLn();
+#endif
+      //syDeletePair(&nextPairs[i]);
+      if (*secondpairs==NULL) *secondpairs = new intvec(howmuch);
+      (**secondpairs)[i2] = i+1;
+      i2++;
+#ifdef SHOW_CRIT
+      crit++;
+#endif
+    }
+    else
+    {
+//      nextPairs[i].p = sySPoly(tso.p1, tso.p2,tso.lcm);
+      (*result)[i1] = i+1;
+      i1++;
+    }
+    i++;
+  }
+  return result;
+#endif
+}
+
+inline void sySPRedSyz(syStrategy syzstr,sSObject redWith,poly q=NULL)
+{
+  poly p=pDivide(q,redWith.p);
+  pSetCoeff(p,nDiv(pGetCoeff(q),pGetCoeff(redWith.p)));
+  int il=-1;
+  kBucket_Minus_m_Mult_p(syzstr->syz_bucket,p,redWith.syz,&il,NULL);
+  pLmDelete(&p);
+}
+
+static poly syRed_Hilb(poly toRed,syStrategy syzstr,int index)
+{
+  ideal redWith=syzstr->res[index];
+  if (redWith==NULL) return toRed;
+  int j=IDELEMS(redWith),i;
+  poly q,result=NULL,resultp;
+
+  while ((j>0) && (redWith->m[j-1]==NULL)) j--;
+  if ((toRed==NULL) || (j==0)) return toRed;
+  kBucketInit(syzstr->bucket,toRed,-1);
+  q = kBucketGetLm(syzstr->bucket);
+  loop
+  {
+    if (q==NULL)
+    {
+      break;
+    }
+    i = 0;
+    loop
+    {
+      if (pLmDivisibleBy(redWith->m[i],q))
+      {
+        number up = kBucketPolyRed(syzstr->bucket,redWith->m[i],
+                         pLength(redWith->m[i]), NULL);
+        nDelete(&up);
+        q = kBucketGetLm(syzstr->bucket);
+        if (toRed==NULL) break;
+        i = 0;
+      }
+      else
+      {
+        i++;
+      }
+      if ((i>=j) || (q==NULL)) break;
+    }
+    if (q!=NULL)
+    {
+      if (result==NULL)
+      {
+        resultp = result = kBucketExtractLm(syzstr->bucket);
+      }
+      else
+      {
+        pNext(resultp) = kBucketExtractLm(syzstr->bucket);
+        pIter(resultp);
+      }
+      q = kBucketGetLm(syzstr->bucket);
+    }
+  }
+  kBucketClear(syzstr->bucket,&q,&i);
+  if (q!=NULL) PrintS("Hier ist was schief gelaufen!\n");
+  return result;
+}
+
+#ifdef USE_HEURISTIC1
+intvec *ivStrip(intvec* arg)
+{
+  int l=arg->rows()*arg->cols(),i=0,ii=0;
+  intvec *tempV=new intvec(l);
+
+  while (i+ii<l)
+  {
+    if ((*arg)[i+ii]==0)
+    {
+      ii++;
+    }
+    else
+    {
+      (*tempV)[i] = (*arg)[i+ii];
+      i++;
+    }
+  }
+  if (i==0)
+  {
+    delete tempV;
+    return NULL;
+  }
+  intvec * result=new intvec(i+1);
+  for (ii=0;ii<i;ii++)
+   (*result)[ii] = (*tempV)[ii];
+  delete tempV;
+  return result;
+}
+#endif
+
+/*3
+* reduces all pairs of degree deg in the module index
+* put the reduced generators to the resolvente which contains
+* the truncated kStd
+*/
+static void syRedNextPairs_Hilb(SSet nextPairs, syStrategy syzstr,
+               int howmuch, int index,int actord,int* toSub,
+               int *maxindex,int *maxdeg)
+{
+  int i,j,k=IDELEMS(syzstr->res[index]);
+  int ks=IDELEMS(syzstr->res[index+1]),kk;
+  int ks1=IDELEMS(syzstr->orderedRes[index+1]);
+  int kres=(*syzstr->Tl)[index];
+  int toGo=0;
+  int il;
+  SSet redset=syzstr->resPairs[index];
+  poly q;
+  intvec *spl1;
+  SObject tso;
+  intvec *spl3=NULL;
+#ifdef USE_HEURISTIC1
+  intvec *spl2=new intvec(howmuch+1,howmuch+1,0);
+  int there_are_superfluous=0;
+  int step=1,jj,j1,j2;
+#endif
+  assume((syzstr->truecomponents[index]) != NULL && (syzstr->ShiftedComponents[index]) != NULL);
+
+  actord += index;
+  if ((nextPairs==NULL) || (howmuch==0)) return;
+  while ((k>0) && (syzstr->res[index]->m[k-1]==NULL)) k--;
+  while ((ks>0) && (syzstr->res[index+1]->m[ks-1]==NULL)) ks--;
+  while ((ks1>0) && (syzstr->orderedRes[index+1]->m[ks1-1]==NULL)) ks1--;
+  while ((kres>0) &&
+        ((redset[kres-1].p==NULL) || (redset[kres-1].order>actord))) kres--;
+  while ((kres<(*syzstr->Tl)[index]) &&
+         (redset[kres-1].order!=0) && (redset[kres-1].order<=actord)) kres++;
+  spl1 = syLinStrat2(nextPairs,syzstr,howmuch,index,&spl3);
+#ifdef SHOW_PROT
+PrintS("spl1 ist hier: ");spl1->show(0,0);
+#endif
+  i=0;
+  kk = (*spl1)[i]-1;
+  if (index==1)
+  {
+    intvec * temp1_hilb = hHstdSeries(syzstr->res[index],NULL,NULL,NULL);
+    if (actord<temp1_hilb->length())
+    {
+      toGo = (*temp1_hilb)[actord];
+#ifdef SHOW_HILB
+Print("\nStze toGo im Modul %d und Grad %d auf: %d\n",1,actord-1,toGo);
+#endif
+    }
+    delete temp1_hilb;
+  }
+  else
+  {
+    if (actord<=(syzstr->hilb_coeffs[index])->length())
+    {
+      toGo = (*syzstr->hilb_coeffs[index])[actord-1];
+#ifdef SHOW_HILB
+Print("\nStze toGo im Modul %d und Grad %d auf: %d\n",index,actord-1,toGo);
+#endif
+    }
+  }
+  if ((syzstr->hilb_coeffs[index+1]!=NULL) &&
+      (actord<=(syzstr->hilb_coeffs[index+1])->length()))
+  {
+    toGo += (*syzstr->hilb_coeffs[index+1])[actord-1];
+#ifdef SHOW_HILB
+Print("\nAddiere zu toGo aus Modul %d und Grad %d: %d\n",index+1,actord-1,(*syzstr->hilb_coeffs[index+1])[actord-1]);
+#endif
+  }
+#ifdef SHOW_HILB
+Print("<H%d>",toGo);
+#endif
+  while (kk>=0)
+  {
+    if (toGo==0)
+    {
+      while (kk>=0)
+      {
+        pDelete(&nextPairs[kk].p);
+        pDelete(&nextPairs[kk].syz);
+        syDeletePair(&nextPairs[kk]);
+        nextPairs[kk].p = nextPairs[kk].syz = nextPairs[kk].lcm = NULL;
+        i++;
+        kk = (*spl1)[i]-1;
+#ifdef USE_HEURISTIC2
+        if (kk<0)
+        {
+          i = 0;
+          delete spl1;
+          spl1 = spl3;
+          spl3 = NULL;
+          if (spl1!=NULL)
+            kk = (*spl1)[i]-1;
+        }
+#endif
+      }
+      if (spl1!=NULL) delete spl1;
+      break;
+    }
+    tso = nextPairs[kk];
+    if ((tso.p1!=NULL) && (tso.p2!=NULL))
+    {
+#ifdef SHOW_CRIT
+      cons_pairs++;
+#endif
+      //tso.p = sySPoly(tso.p1, tso.p2,tso.lcm);
+      tso.p = ksOldCreateSpoly(tso.p2, tso.p1);
+#ifdef SHOW_PROT
+PrintS("reduziere Paar mit: \n");
+PrintS("poly1: ");poly_write(tso.p1);
+PrintS("poly2: ");poly_write(tso.p2);
+PrintS("syz: ");poly_write(tso.syz);
+PrintS("sPoly: ");poly_write(tso.p);
+#endif
+      if (tso.p != NULL)
+      {
+        kBucketInit(syzstr->bucket,tso.p,-1);
+        kBucketInit(syzstr->syz_bucket,tso.syz,-1);
+        q = kBucketGetLm(syzstr->bucket);
+        j = 0;
+        while (j<kres)
+        {
+          if ((redset[j].p!=NULL) && (pLmDivisibleBy(redset[j].p,q))
+              && ((redset[j].ind1!=tso.ind1) || (redset[j].ind2!=tso.ind2)))
+          {
+#ifdef SHOW_RED
+kBucketClear(syzstr->bucket,&tso.p,&tso.length);
+kBucketClear(syzstr->syz_bucket,&tso.syz,&il);
+PrintS("reduziere: ");poly_write(tso.p);
+PrintS("syz: ");poly_write(tso.syz);
+PrintS("mit: ");poly_write(redset[j].p);
+PrintS("syz: ");poly_write(redset[j].syz);
+kBucketInit(syzstr->bucket,tso.p,tso.length);
+kBucketInit(syzstr->syz_bucket,tso.syz,il);
+#endif
+            sySPRedSyz(syzstr,redset[j],q);
+            number up = kBucketPolyRed(syzstr->bucket,redset[j].p,
+                         redset[j].length, NULL);
+            nDelete(&up);
+            q = kBucketGetLm(syzstr->bucket);
+#ifdef SHOW_RED
+kBucketClear(syzstr->bucket,&tso.p,&tso.length);
+kBucketClear(syzstr->syz_bucket,&tso.syz,&il);
+PrintS("zu: ");poly_write(tso.p);
+PrintS("syz: ");poly_write(tso.syz);
+kBucketInit(syzstr->bucket,tso.p,tso.length);
+kBucketInit(syzstr->syz_bucket,tso.syz,il);
+PrintLn();
+#endif
+            if (q==NULL) break;
+            j = 0;
+          }
+          else
+          {
+            j++;
+          }
+        }
+        kBucketClear(syzstr->bucket,&tso.p,&tso.length);
+        kBucketClear(syzstr->syz_bucket,&tso.syz,&il);
+      }
+#ifdef SHOW_PROT
+PrintS("erhalte Paar mit: \n");
+PrintS("syz: ");poly_write(tso.syz);
+PrintS("sPoly: ");poly_write(tso.p);
+PrintLn();
+#endif
+#ifdef SHOW_SPRFL
+//PrintLn();
+wrp(tso.lcm);
+Print(" mit index %d, %d ",tso.ind1,tso.ind2);
+#endif
+      if (tso.p != NULL)
+      {
+        if (TEST_OPT_PROT) PrintS("g");
+        (*toSub)++;
+        toGo--;
+        if (!nIsOne(pGetCoeff(tso.p)))
+        {
+          number n=nInvers(pGetCoeff(tso.p));
+          pNorm(tso.p);
+          pMult_nn(tso.syz,n);
+          nDelete(&n);
+        }
+        if (k==IDELEMS((syzstr->res)[index]))
+          syEnlargeFields(syzstr,index);
+        syzstr->res[index]->m[k] = tso.p;
+        k++;
+      }
+      else
+      {
+        if (ks==IDELEMS(syzstr->res[index+1]))
+          syEnlargeFields(syzstr,index+1);
+        syzstr->res[index+1]->m[ks] = syRed_Hilb(tso.syz,syzstr,index+1);
+        if (syzstr->res[index+1]->m[ks]!=NULL)
+        {
+          if (TEST_OPT_PROT) PrintS("s");
+          toGo--;
+          pNorm(syzstr->res[index+1]->m[ks]);
+          syHalfPair(syzstr->res[index+1]->m[ks],ks1,syzstr,index+1);
+          ks++;
+          ks1++;
+          if (index+1>*maxindex) *maxindex = index+1;
+          if (actord-index>*maxdeg) *maxdeg = actord-index;
+        }
+        else
+        {
+          if (TEST_OPT_PROT) PrintS("-");
+#ifdef SHOW_CRIT
+          spfl++;
+#endif
+#ifdef USE_HEURISTIC1
+          if (there_are_superfluous>=0)
+          {
+            j = i+1;
+            jj = (*spl1)[j]-1;
+            j1 = 1;
+            while (jj>=0)
+            {
+              if (tso.ind2==nextPairs[jj].ind2)
+              {
+                IMATELEM(*spl2,j1,step) = jj+1;
+                j1++;
+                for (j2=j;j2<spl1->length()-1;j2++)
+                {
+                  (*spl1)[j2] = (*spl1)[j2+1];
+                }
+              }
+              else
+              {
+                j++;
+              }
+              jj = (*spl1)[j]-1;
+            }
+            step++;
+            if (there_are_superfluous==0) there_are_superfluous = 1;
+          }
+#endif
+#ifdef SHOW_SPRFL
+Print("ist ueberfluessig in Mod %d",index);
+//Print("\n ueberfluessig in Mod %d:",index);
+//wrp(tso.lcm);
+//PrintLn();
+#endif
+        }
+        tso.syz = NULL;
+        syDeletePair(&tso);
+        tso.p = tso.syz = tso.lcm = NULL;
+      }
+      nextPairs[kk] = tso;
+    }
+#ifdef SHOW_SPRFL
+PrintLn();
+#endif
+    i++;
+#ifdef SHOW_PROT
+PrintS("spl1 ist hier: ");spl1->show(0,0);
+Print("naechstes i ist: %d",i);
+#endif
+    kk = (*spl1)[i]-1;
+#ifdef USE_HEURISTIC1
+    if ((kk<0) && (there_are_superfluous>0))
+    {
+      i = 0;
+      delete spl1;
+      spl1 = ivStrip(spl2);
+      delete spl2;
+      if (spl1!=NULL)
+      {
+        there_are_superfluous = -1;
+        kk = (*spl1)[i]-1;
+      }
+    }
+#endif
+#ifdef USE_HEURISTIC2
+    if ((kk<0) && (toGo>0))
+    {
+#ifdef SHOW_CRIT
+      crit_fails++;
+#endif
+      i = 0;
+      delete spl1;
+      spl1 = spl3;
+      spl3 = NULL;
+      if (spl1!=NULL)
+        kk = (*spl1)[i]-1;
+    }
+#endif
+  }
+  delete spl1;
+  if (spl3!=NULL) delete spl3;
+}
+
+void sySetNewHilb(syStrategy syzstr, int toSub,int index,int actord)
+{
+  int i;
+  actord += index;
+  intvec * temp_hilb = hHstdSeries(syzstr->res[index+1],NULL,NULL,NULL);
+  intvec * cont_hilb = hHstdSeries(syzstr->res[index],NULL,NULL,NULL);
+  if ((index+1<syzstr->length) && (syzstr->hilb_coeffs[index+1]==NULL))
+  {
+    syzstr->hilb_coeffs[index+1] = new intvec(16*((actord/16)+1));
+  }
+  else if (actord>=syzstr->hilb_coeffs[index+1]->length())
+  {
+    intvec * ttt=new intvec(16*((actord/16)+1));
+    for (i=syzstr->hilb_coeffs[index+1]->length()-1;i>=0;i--)
+    {
+      (*ttt)[i] = (*(syzstr->hilb_coeffs[index+1]))[i];
+    }
+    delete syzstr->hilb_coeffs[index+1];
+    syzstr->hilb_coeffs[index+1] = ttt;
+  }
+  if (actord+1<temp_hilb->length())
+  {
+#ifdef SHOW_HILB
+Print("\nSetze fuer Modul %d im Grad %d die Wert: \n",index+1,actord);
+(temp_hilb)->show(0,0);
+#endif
+    int k=si_min(temp_hilb->length()-1,(syzstr->hilb_coeffs[index+1])->length());
+    for (int j=k;j>actord;j--)
+      (*(syzstr->hilb_coeffs[index+1]))[j-1] = (*temp_hilb)[j];
+  }
+  else
+  {
+    (*(syzstr->hilb_coeffs[index+1]))[actord] = 0;
+  }
+  delete temp_hilb;
+  if ((index>1) && (actord<=syzstr->hilb_coeffs[index]->length()))
+  {
+#ifdef SHOW_HILB
+Print("\nSubtrahiere im Modul %d im Grad %d den Wert: %d\n",index,actord-1,toSub);
+#endif
+    (*syzstr->hilb_coeffs[index])[actord-1]-=toSub;
+  }
+  if (syzstr->hilb_coeffs[index]!=NULL)
+  {
+    if (cont_hilb->length()>syzstr->hilb_coeffs[index]->length())
+      syzstr->hilb_coeffs[index]->resize(cont_hilb->length());
+    for (int j=cont_hilb->length()-1;j>actord;j--)
+      (*(syzstr->hilb_coeffs[index]))[j-1] = (*cont_hilb)[j];
+  }
+  delete cont_hilb;
+#ifdef SHOW_HILB
+Print("<h,%d>",(*(syzstr->hilb_coeffs[index+1]))[actord]);
+#endif
+}
+
+/*3
+* reduces the generators of the module index in degree deg
+* (which are actual syzygies of the module index-1)
+* wrt. the ideal generated by elements of lower degrees
+*/
+static void syRedGenerOfCurrDeg_Hilb(syStrategy syzstr, int deg,int *maxindex,int *maxdeg)
+{
+  ideal res=syzstr->res[1];
+  int i=0,k=IDELEMS(res),k1=IDELEMS(syzstr->orderedRes[1]);
+  SSet sPairs=syzstr->resPairs[0];
+
+  while ((k>0) && (res->m[k-1]==NULL)) k--;
+  while ((k1>0) && (syzstr->orderedRes[1]->m[k1-1]==NULL)) k1--;
+  while ((i<(*syzstr->Tl)[0]) && (((sPairs)[i].syz==NULL) ||
+          ((sPairs)[i].order<deg)))
+    i++;
+  if ((i>=(*syzstr->Tl)[0]) || ((sPairs)[i].order>deg)) return;
+  while ((i<(*syzstr->Tl)[0]) && (((sPairs)[i].syz==NULL) ||
+         ((sPairs)[i].order==deg)))
+  {
+    if ((sPairs)[i].syz!=NULL)
+    {
+#ifdef SHOW_PROT
+PrintS("reduziere Erzeuger: \n");
+PrintS("syz: ");poly_write((sPairs)[i].syz);
+#endif
+      (sPairs)[i].syz = syRed_Hilb((sPairs)[i].syz,syzstr,1);
+#ifdef SHOW_PROT
+PrintS("erhalte Erzeuger: \n");
+PrintS("syz: ");poly_write((sPairs)[i].syz);
+PrintLn();
+#endif
+      if ((sPairs)[i].syz != NULL)
+      {
+        if (k==IDELEMS(res))
+        {
+          syEnlargeFields(syzstr,1);
+          res=syzstr->res[1];
+        }
+        if (TEST_OPT_DEBUG)
+        {
+          if ((sPairs)[i].isNotMinimal==NULL)
+          {
+            PrintS("\nminimal generator: ");
+            pWrite((syzstr->resPairs[0])[i].syz);
+            PrintS("comes from: ");pWrite((syzstr->resPairs[0])[i].p1);
+            PrintS("and: ");pWrite((syzstr->resPairs[0])[i].p2);
+          }
+        }
+        res->m[k] = (sPairs)[i].syz;
+        pNorm(res->m[k]);
+        syHalfPair(res->m[k],k1,syzstr,1);
+        k1++;
+        k++;
+        if (1>*maxindex) *maxindex = 1;
+        if (deg-1>*maxdeg) *maxdeg = deg-1;
+      }
+    }
+    i++;
+  }
+}
+
+/*3
+* reorders the result (stored in orderedRes) according
+* to the seqence given by res
+*/
+static void syReOrdResult_Hilb(syStrategy syzstr,int maxindex,int maxdeg)
+{
+  ideal reor,toreor;
+  int i,j,k,l,m,togo;
+  syzstr->betti = new intvec(maxdeg,maxindex+1,0);
+  (*syzstr->betti)[0] = 1;
+  for (i=1;i<=syzstr->length;i++)
+  {
+    if (!idIs0(syzstr->orderedRes[i]))
+    {
+      toreor = syzstr->orderedRes[i];
+      k = IDELEMS(toreor);
+      while ((k>0) && (toreor->m[k-1]==NULL)) k--;
+      reor = idInit(k,toreor->rank);
+      togo = IDELEMS(syzstr->res[i]);
+      for (j=0;j<k;j++)
+      {
+        if (toreor->m[j]!=NULL) (IMATELEM(*syzstr->betti,p_FDeg(toreor->m[j],currRing)-i+1,i+1))++;
+        reor->m[j] = toreor->m[j];
+        toreor->m[j] = NULL;
+      }
+      m = 0;
+      for (j=0;j<togo;j++)
+      {
+        if (syzstr->res[i]->m[j]!=NULL)
+        {
+          l = 0;
+          while ((l<k) && (syzstr->res[i]->m[j]!=reor->m[l])) l++;
+          if (l<k)
+          {
+            toreor->m[m] = reor->m[l];
+            reor->m[l] = NULL;
+            m++;
+          }
+        }
+      }
+      idDelete(&reor);
+    }
+  }
+}
+
+/*2
+* the CoCoA-algorithm for free resolutions, using a formula
+* for remaining pairs based on Hilbert-functions
+*/
+syStrategy syHilb(ideal arg,int * length)
+{
+  int i,j,actdeg=32000,index=0;
+  int howmuch,toSub=0;
+  int maxindex=0,maxdeg=0;
+  ideal temp=NULL;
+  SSet nextPairs;
+  ring origR = currRing;
+  syStrategy syzstr=(syStrategy)omAlloc0(sizeof(ssyStrategy));
+
+  if ((idIs0(arg)) || (id_RankFreeModule(arg,currRing)>0))
+  {
+    syzstr->minres = (resolvente)omAllocBin(sip_sideal_bin);
+    syzstr->length = 1;
+    syzstr->minres[0] = idInit(1,arg->rank);
+    return syzstr;
+  }
+
+  // Creare dp,S ring and change to it
+  syzstr->syRing = rAssure_dp_C(origR);
+  rChangeCurrRing(syzstr->syRing);
+
+  // set initial ShiftedComps
+  currcomponents = (int*)omAlloc0((arg->rank+1)*sizeof(int));
+  currShiftedComponents = (long*)omAlloc0((arg->rank+1)*sizeof(long));
+
+/*--- initializes the data structures---------------*/
+#ifdef SHOW_CRIT
+  crit = 0;
+  crit1 = 0;
+  spfl = 0;
+  cons_pairs = 0;
+  crit_fails = 0;
+#endif
+  syzstr->length = *length = currRing->N+2;
+  syzstr->Tl = new intvec(*length+1);
+  temp = idInit(IDELEMS(arg),arg->rank);
+  for (i=0;i<IDELEMS(arg);i++)
+  {
+    if (origR != syzstr->syRing)
+      temp->m[i] = prCopyR( arg->m[i], origR, syzstr->syRing);
+    else
+      temp->m[i] = pCopy( arg->m[i]);
+    if (temp->m[i]!=NULL)
+    {
+      j = pTotaldegree(temp->m[i]);
+      if (j<actdeg) actdeg = j;
+    }
+  }
+  idTest(temp);
+  idSkipZeroes(temp);
+  syzstr->resPairs = syInitRes(temp,length,syzstr->Tl,syzstr->cw);
+  omFreeSize((ADDRESS)currcomponents,(arg->rank+1)*sizeof(int));
+  omFreeSize((ADDRESS)currShiftedComponents,(arg->rank+1)*sizeof(int));
+  syzstr->res = (resolvente)omAlloc0((*length+1)*sizeof(ideal));
+  syzstr->orderedRes = (resolvente)omAlloc0((*length+1)*sizeof(ideal));
+  syzstr->elemLength = (int**)omAlloc0((*length+1)*sizeof(int*));
+  syzstr->truecomponents = (int**)omAlloc0((*length+1)*sizeof(int*));
+  syzstr->backcomponents = (int**)omAlloc0((*length+1)*sizeof(int*));
+  syzstr->ShiftedComponents = (long**)omAlloc0((*length+1)*sizeof(long*));
+  syzstr->Howmuch = (int**)omAlloc0((*length+1)*sizeof(int*));
+  syzstr->Firstelem = (int**)omAlloc0((*length+1)*sizeof(int*));
+  syzstr->hilb_coeffs = (intvec**)omAlloc0((*length+1)*sizeof(intvec*));
+  syzstr->sev = (unsigned long **)omAlloc0((*length+1)*sizeof(unsigned long*));
+  syzstr->bucket = kBucketCreate(currRing);
+  syzstr->syz_bucket = kBucketCreate(currRing);
+  nextPairs = syChosePairs(syzstr,&index,&howmuch,&actdeg);
+/*--- computes the resolution ----------------------*/
+  while (nextPairs!=NULL)
+  {
+#ifdef SHOW_PROT
+Print("compute %d Paare im Module %d im Grad %d \n",howmuch,index,actdeg+index);
+#endif
+    if (TEST_OPT_PROT) Print("%d",actdeg);
+    if (TEST_OPT_PROT) Print("(m%d)",index);
+    if (index==0)
+      i = syInitSyzMod(syzstr,index,id_RankFreeModule(arg, origR)+1);
+    else
+      i = syInitSyzMod(syzstr,index);
+    j = syInitSyzMod(syzstr,index+1);
+    if (index>0)
+    {
+      syRedNextPairs_Hilb(nextPairs,syzstr,howmuch,index,actdeg,&toSub,&maxindex,&maxdeg);
+      sySetNewHilb(syzstr,toSub,index,actdeg);
+      toSub = 0;
+      syCompactifyPairSet(syzstr->resPairs[index],(*syzstr->Tl)[index],0);
+    }
+    else
+      syRedGenerOfCurrDeg_Hilb(syzstr,actdeg,&maxindex,&maxdeg);
+/*--- creates new pairs -----------------------------*/
+#ifdef SHOW_PROT
+Print("Bilde neue Paare in Modul %d!\n",index);
+#endif
+    syCreateNewPairs_Hilb(syzstr,index,actdeg);
+    if (index<(*length)-1)
+    {
+#ifdef SHOW_PROT
+Print("Bilde neue Paare in Modul %d!\n",index+1);
+#endif
+      syCreateNewPairs_Hilb(syzstr,index+1,actdeg-1);
+    }
+    index++;
+    nextPairs = syChosePairs(syzstr,&index,&howmuch,&actdeg);
+  }
+  syReOrdResult_Hilb(syzstr,maxindex,maxdeg);
+#ifdef SHOW_RESULT
+PrintS("minimal resolution:\n");
+for (int ti=1;ti<=*length;ti++)
+{
+  if (!idIs0(syzstr->orderedRes[ti])) idPrint(syzstr->orderedRes[ti]);
+}
+PrintS("full resolution:\n");
+for (int ti=1;ti<=*length;ti++)
+{
+  if (!idIs0(syzstr->res[ti])) idPrint(syzstr->res[ti]);
+}
+#endif
+#ifdef SHOW_CRIT
+Print("Criterion %d times applied\n",crit);
+Print("Criterion1 %d times applied\n",crit1);
+Print("%d superfluous pairs\n",spfl);
+Print("%d pairs considered\n",cons_pairs);
+Print("Criterion fails %d times\n",crit_fails);
+crit = 0;
+crit1 = 0;
+spfl = 0;
+cons_pairs = 0;
+crit_fails = 0;
+#endif
+  if (temp!=NULL) idDelete(&temp);
+  kBucketDestroy(&(syzstr->bucket));
+  kBucketDestroy(&(syzstr->syz_bucket));
+  if (origR != syzstr->syRing)
+    rChangeCurrRing(origR);
+  else
+    currRing =  origR;
+  if (TEST_OPT_PROT) PrintLn();
+  return syzstr;
+}
diff --git a/kernel/GBEngine/syz3.cc b/kernel/GBEngine/syz3.cc
new file mode 100644
index 0000000..73a327d
--- /dev/null
+++ b/kernel/GBEngine/syz3.cc
@@ -0,0 +1,2046 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: resolutions
+*/
+
+#include <kernel/mod2.h>
+#include <omalloc/omalloc.h>
+
+#include <misc/mylimits.h>
+#include <misc/options.h>
+#include <misc/intvec.h>
+
+#include <coeffs/numbers.h>
+
+#include <polys/monomials/ring.h>
+#include <polys/kbuckets.h>
+#include <polys/prCopy.h>
+#include <polys/matpol.h>
+
+#include <kernel/combinatorics/stairc.h>
+#include <kernel/combinatorics/hilb.h>
+
+#include <kernel/GBEngine/kstd1.h>
+#include <kernel/GBEngine/kutil.h>
+#include <kernel/GBEngine/syz.h>
+
+#include <kernel/ideals.h>
+#include <kernel/polys.h>
+
+//#define SHOW_PROT
+//#define SHOW_RED
+//#define SHOW_Kosz
+//#define SHOW_RESULT
+//#define INVERT_PAIRS
+//#define ONLY_STD
+//#define EXPERIMENT1    //Hier stimmt was mit der Anzahl der Erzeuger in xyz11 nicht!!
+#define EXPERIMENT2
+#define EXPERIMENT3
+#define WITH_BUCKET     //Use of buckets in EXPERIMENT3 (Product criterion)
+#define WITH_SCHREYER_ORD
+#define USE_CHAINCRIT
+#define USE_CHAINCRIT0
+#define USE_PROD_CRIT
+#define USE_REGULARITY
+#define WITH_SORT
+//#define FULL_TOTAKE
+int discard_pairs;
+int short_pairs;
+
+/*3
+* assumes the ideals old_ideal and new_ideal to be homogeneous
+* tests wether the new_ideal is a regular extension of the old_ideal
+*/
+static BOOLEAN syIsRegular(ideal old_ideal,ideal new_ideal,int deg)
+{
+  intvec * old_hilbs=hHstdSeries(old_ideal,NULL,NULL,NULL);
+  intvec * new_hilbs=hHstdSeries(new_ideal,NULL,NULL,NULL);
+  int biggest_length=si_max(old_hilbs->length()+deg,new_hilbs->length());
+  intvec * shifted_old_hilbs=new intvec(biggest_length);
+  intvec * old_hilb1=new intvec(biggest_length);
+  intvec * new_hilb1=new intvec(biggest_length);
+  int i;
+  BOOLEAN isRegular=TRUE;
+
+  for (i=old_hilbs->length()+deg-1;i>=deg;i--)
+    (*shifted_old_hilbs)[i] = (*old_hilbs)[i-deg];
+  for (i=old_hilbs->length()-1;i>=0;i--)
+    (*old_hilb1)[i] = (*old_hilbs)[i]-(*shifted_old_hilbs)[i];
+  for (i=old_hilbs->length()+deg-1;i>=old_hilbs->length();i--)
+    (*old_hilb1)[i] = -(*shifted_old_hilbs)[i];
+  for (i=new_hilbs->length()-1;i>=0;i--)
+    (*new_hilb1)[i] = (*new_hilbs)[i];
+  i = 0;
+  while ((i<biggest_length) && isRegular)
+  {
+    isRegular = isRegular && ((*old_hilb1)[i] == (*new_hilb1)[i]);
+    i++;
+  }
+  delete old_hilbs;
+  delete new_hilbs;
+  delete old_hilb1;
+  delete new_hilb1;
+  delete shifted_old_hilbs;
+  return isRegular;
+}
+
+/*3
+* shows the resolution stored in syzstr->orderedRes
+*/
+#if 0 /* unused*/
+static void syShowRes(syStrategy syzstr)
+{
+  int i=0;
+
+  while ((i<syzstr->length) && (!idIs0(syzstr->res[i])))
+  {
+    Print("aktueller hoechster index ist: %d\n",(*syzstr->Tl)[i]);
+    Print("der %d-te modul ist:\n",i);
+    idPrint(syzstr->res[i]);
+    PrintS("Seine Darstellung:\n");
+    idPrint(syzstr->orderedRes[i]);
+    i++;
+  }
+}
+#endif
+
+/*3
+* produces the next subresolution for a regular extension
+*/
+static void syCreateRegularExtension(syStrategy syzstr,ideal old_ideal,
+            ideal old_repr,int old_tl, poly next_generator,resolvente totake)
+{
+  int index=syzstr->length-1,i,j,start,start_ttk/*,new_tl*/;
+  poly gen=pCopy(next_generator),p;
+  poly neg_gen=pCopy(next_generator);
+  ideal current_ideal,current_repr;
+  int current_tl;
+  poly w_gen=pHead(next_generator);
+  pSetComp(w_gen,0);
+  pSetmComp(w_gen);
+
+  //syShowRes(syzstr);
+  neg_gen = pNeg(neg_gen);
+  if (pGetComp(gen)>0)
+  {
+    p_Shift(&gen,-1,currRing);
+    p_Shift(&neg_gen,-1,currRing);
+  }
+  while (index>0)
+  {
+    if (index%2==0)
+      p = gen;
+    else
+      p = neg_gen;
+    if (index>1)
+    {
+      current_ideal = syzstr->res[index-1];
+      current_repr = syzstr->orderedRes[index-1];
+      current_tl = (*syzstr->Tl)[index-1];
+    }
+    else
+    {
+      current_ideal = old_ideal;
+      current_repr = old_repr;
+      current_tl = old_tl;
+    }
+    if (!idIs0(current_ideal))
+    {
+      if (idIs0(syzstr->res[index]))
+      {
+        syzstr->res[index] = idInit(IDELEMS(current_ideal),
+          current_ideal->rank+current_tl);
+        syzstr->orderedRes[index] = idInit(IDELEMS(current_ideal),
+          current_ideal->rank);
+        start = 0;
+      }
+      else
+      {
+        start = IDELEMS(syzstr->res[index]);
+        while ((start>0) && (syzstr->res[index]->m[start-1]==NULL)) start--;
+        if (IDELEMS(syzstr->res[index])<start+IDELEMS(current_ideal))
+        {
+          pEnlargeSet(&syzstr->res[index]->m,IDELEMS(syzstr->res[index]),
+                   IDELEMS(current_ideal));
+          IDELEMS(syzstr->res[index]) += IDELEMS(current_ideal);
+          pEnlargeSet(&syzstr->orderedRes[index]->m,IDELEMS(syzstr->orderedRes[index]),
+                   IDELEMS(current_ideal));
+          IDELEMS(syzstr->orderedRes[index]) += IDELEMS(current_ideal);
+        }
+      }
+      if (idIs0(totake[index]))
+      {
+        totake[index] = idInit(IDELEMS(current_ideal),
+          current_ideal->rank+current_tl);
+        start_ttk = 0;
+      }
+      else
+      {
+        start_ttk = IDELEMS(totake[index]);
+        while ((start_ttk>0) && (totake[index]->m[start_ttk-1]==NULL)) start_ttk--;
+        if (IDELEMS(totake[index])<start_ttk+IDELEMS(current_ideal))
+        {
+          pEnlargeSet(&totake[index]->m,IDELEMS(totake[index]),
+                   IDELEMS(current_ideal));
+          for (j=IDELEMS(totake[index]);j<IDELEMS(totake[index])+
+                                  IDELEMS(current_ideal);j++)
+            totake[index]->m[j] = NULL;
+          IDELEMS(totake[index]) += IDELEMS(current_ideal);
+        }
+      }
+      for (i=0;i<IDELEMS(current_ideal);i++)
+      {
+        if (current_ideal->m[i]!=NULL)
+        {
+          syzstr->res[index]->m[i+start] = pCopy(current_ideal->m[i]);
+          syzstr->res[index]->m[i+start] = pMult_mm(syzstr->res[index]->m[i+start],w_gen);
+          p_Shift(&syzstr->res[index]->m[i+start],current_tl,currRing);
+          syzstr->res[index]->m[i+start] = pAdd(syzstr->res[index]->m[i+start],
+            ppMult_qq(current_repr->m[i],p));
+          syzstr->orderedRes[index]->m[i+start] = pCopy(current_repr->m[i]);
+          syzstr->orderedRes[index]->m[i+start] =
+            pMult_mm(syzstr->orderedRes[index]->m[i+start],w_gen);
+          if ((*syzstr->Tl)[index]!=0)
+            p_Shift(&syzstr->orderedRes[index]->m[i+start],(*syzstr->Tl)[index],currRing);
+        }
+      }
+      for (i=0;i<IDELEMS(totake[index-1]);i++)
+      {
+        if (totake[index-1]->m[i]!=NULL)
+        {
+          if ((index==1) && ((i==IDELEMS(current_ideal) ||
+               (totake[index-1]->m[i+1]==NULL)))) break;
+          totake[index]->m[i+start_ttk] =
+            pMult_mm(pCopy(totake[index-1]->m[i]),w_gen);
+          p_Shift(&totake[index]->m[i+start_ttk],current_tl,currRing);
+#ifdef FULL_TOTAKE
+          poly pp=pCopy(p);
+          p_Shift(&pp,i+1,currRing);
+          totake[index]->m[i+start_ttk] = pAdd(totake[index]->m[i+start_ttk],pp);
+#endif
+        }
+      }
+      (*syzstr->Tl)[index] += current_tl;
+    }
+    index--;
+  }
+  pDelete(&gen);
+  pDelete(&neg_gen);
+  pDelete(&w_gen);
+  //syShowRes(syzstr);
+}
+
+/*3
+* proves the consistence of the pairset resPairs with the corresponding
+* set of generators;
+* only for tests
+*/
+#ifdef SING_NDEBUG
+static void syTestPairs(SSet resPairs,int length,ideal /*old_generators*/)
+#else
+static void syTestPairs(SSet resPairs,int length,ideal old_generators)
+#endif
+{
+  int i=0;
+
+  while (i<length)
+  {
+    if (resPairs[i].lcm!=NULL)
+    {
+      if (resPairs[i].p1!=NULL)
+        assume(resPairs[i].p1==old_generators->m[resPairs[i].ind1]);
+      if (resPairs[i].p2!=NULL)
+        assume(resPairs[i].p2==old_generators->m[resPairs[i].ind2]);
+    }
+    i++;
+  }
+}
+
+/*3
+* cancels the weight monomials given by the leading terms of totake
+* from the resolution res;
+* works in place on res, but reads only from totake
+*/
+void syReorder_Kosz(syStrategy syzstr)
+{
+  int length=syzstr->length;
+  int syzIndex=length-1,i,j;
+  resolvente res=syzstr->fullres;
+  poly p;
+
+  while ((syzIndex!=0) && (res[syzIndex]==NULL)) syzIndex--;
+  while (syzIndex>0)
+  {
+    for(i=0;i<IDELEMS(res[syzIndex]);i++)
+    {
+#ifdef USE_REGULARITY
+      if ((syzstr->regularity>0) && (res[syzIndex]->m[i]!=NULL))
+      {
+        if (p_FDeg(res[syzIndex]->m[i],currRing)>=syzstr->regularity+syzIndex)
+          pDelete(&res[syzIndex]->m[i]);
+      }
+#endif
+      p = res[syzIndex]->m[i];
+      while (p!=NULL)
+      {
+        if (res[syzIndex-1]->m[pGetComp(p)-1]!=NULL)
+        {
+          for(j=1;j<=(currRing->N);j++)
+          {
+            pSetExp(p,j,pGetExp(p,j)
+                        -pGetExp(res[syzIndex-1]->m[pGetComp(p)-1],j));
+          }
+        }
+        else
+          PrintS("error in the resolvent\n");
+        pSetm(p);
+        pIter(p);
+      }
+    }
+    syzIndex--;
+  }
+}
+
+/*3
+* updates the pairset resPairs by generating all pairs including the
+* new_generators in the 0-th modul;
+* the new_generators are inserted in the old_generators;
+* new_generators is empty after the procedure;
+*/
+static void updatePairs(SSet *resPairs,int *l_pairs,syStrategy syzstr,
+       int index,ideal new_generators,ideal new_repr,int crit_comp)
+{
+  if (idIs0(new_generators)) return;
+  ideal old_generators=syzstr->res[index];
+  ideal old_repr=syzstr->orderedRes[index];
+  int i=0,j,k,kk,og_elem=0,og_idel=IDELEMS(old_generators),l=*l_pairs,jj,ll,j1;
+  int og_ini=0;
+  ideal pairs=idInit(og_idel+IDELEMS(new_generators),old_generators->rank);
+  polyset prs=pairs->m;
+  poly p=NULL;
+  SObject tso;
+
+  syInitializePair(&tso);
+  while ((og_elem<og_idel) && (old_generators->m[og_elem]!=NULL))
+  {
+    if ((index>0) && (pGetComp(old_generators->m[og_elem])<=crit_comp))
+      og_ini = og_elem;
+    og_elem++;
+  }
+  while ((l>0) && ((*resPairs)[l-1].lcm==NULL)) l--;
+  while ((i<IDELEMS(new_generators)) && (new_generators->m[i]!=NULL))
+  {
+    syTestPairs(*resPairs,*l_pairs,old_generators);
+    if (IDELEMS(old_generators)==og_elem)
+    {
+      pEnlargeSet(&old_generators->m,IDELEMS(old_generators),16);
+      IDELEMS(old_generators) += 16;
+      pEnlargeSet(&old_repr->m,IDELEMS(old_repr),16);
+      IDELEMS(old_repr) += 16;
+    }
+    k = p_FDeg(new_generators->m[i],currRing);
+    kk = pGetComp(new_generators->m[i]);
+    j = og_ini;
+    while ((j<og_elem) && (old_generators->m[j]!=NULL) &&
+           (pGetComp(old_generators->m[j])<kk)) j++;
+    while ((j<og_elem) && (old_generators->m[j]!=NULL) &&
+           (p_FDeg(old_generators->m[j],currRing)<=k)) j++;
+    for (jj=og_elem;jj>j;jj--)
+    {
+      old_generators->m[jj] = old_generators->m[jj-1];
+      old_repr->m[jj] = old_repr->m[jj-1];
+    }
+    old_generators->m[j] = new_generators->m[i];
+    new_generators->m[i] = NULL;
+    old_repr->m[j] = new_repr->m[i];
+    new_repr->m[i] = NULL;
+    og_elem++;
+    for (jj=0;jj<*l_pairs;jj++)
+    {
+      if ((*resPairs)[jj].lcm!=NULL)
+      {
+        if ((*resPairs)[jj].ind1>=j) (*resPairs)[jj].ind1++;
+        if ((*resPairs)[jj].ind2>=j) (*resPairs)[jj].ind2++;
+      }
+    }
+    syTestPairs(*resPairs,*l_pairs,old_generators);
+    for (jj=og_ini;jj<og_elem;jj++)
+    {
+      if ((j!=jj) && (pGetComp(old_generators->m[jj])==pGetComp(old_generators->m[j])))
+      {
+        p = pOne();
+        pLcm(old_generators->m[jj],old_generators->m[j],p);
+        pSetComp(p,j+1);
+        pSetm(p);
+        j1 = 0;
+        while (j1<jj)
+        {
+          if (prs[j1]!=NULL)
+          {
+            if (pLmDivisibleByNoComp(prs[j1],p))
+            {
+              pDelete(&p);
+              break;
+            }
+            else if (pLmDivisibleByNoComp(p,prs[j1]))
+            {
+              pDelete(&(prs[j1]));
+            }
+#ifdef USE_CHAINCRIT0
+            else
+            {
+              poly p1,p2;
+              int ip=(currRing->N);
+              p1 = pDivide(p,old_generators->m[jj]);
+              p2 = pDivide(prs[j1],old_generators->m[j1]);
+              while ((ip>0) && (pGetExp(p1,ip)*pGetExp(p2,ip)==0)) ip--;
+              if (ip==0)
+              {
+                int ti=0;
+                while ((ti<l) && (((*resPairs)[ti].ind1!=j1)|| ((*resPairs)[ti].ind2!=jj))) ti++;
+                if (ti<l)
+                {
+                  if (TEST_OPT_PROT) PrintS("cc");
+                  syDeletePair(&(*resPairs)[ti]);
+                  syCompactifyPairSet(*resPairs,*l_pairs,ti);
+                  l--;
+                }
+              }
+              pDelete(&p1);
+              pDelete(&p2);
+            }
+#endif
+          }
+          j1++;
+        }
+        if (p!=NULL)
+          prs[jj] = p;
+      }
+    }
+    for (jj=og_ini;jj<og_elem;jj++)
+    {
+      if (prs[jj] !=NULL)
+      {
+        if (l>=*l_pairs)
+        {
+          SSet temp = (SSet)omAlloc0((*l_pairs+16)*sizeof(SObject));
+          for (ll=0;ll<*l_pairs;ll++)
+          {
+            temp[ll].p = (*resPairs)[ll].p;
+            temp[ll].p1 = (*resPairs)[ll].p1;
+            temp[ll].p2 = (*resPairs)[ll].p2;
+            temp[ll].syz = (*resPairs)[ll].syz;
+            temp[ll].lcm = (*resPairs)[ll].lcm;
+            temp[ll].ind1 = (*resPairs)[ll].ind1;
+            temp[ll].ind2 = (*resPairs)[ll].ind2;
+            temp[ll].syzind = (*resPairs)[ll].syzind;
+            temp[ll].order = (*resPairs)[ll].order;
+            temp[ll].isNotMinimal = (*resPairs)[ll].isNotMinimal;
+          }
+          omFreeSize((ADDRESS)(*resPairs),*l_pairs*sizeof(SObject));
+          *l_pairs += 16;
+          (*resPairs) = temp;
+        }
+        tso.lcm = prs[jj];
+        prs[jj] = NULL;
+        tso.order = p_FDeg(tso.lcm,currRing);
+        tso.p1 = old_generators->m[jj];
+        tso.p2 = old_generators->m[j];
+        tso.ind1 = jj;
+        tso.ind2 = j;
+        tso.syzind = -1;
+        tso.isNotMinimal = NULL;
+        tso.p = NULL;
+        tso.syz = NULL;
+        SSet rP=*resPairs;
+#ifdef SHOW_PROT
+Print("erzeuge Paar im Modul %d,%d mit: \n",index,tso.order);
+PrintS("poly1: ");pWrite(tso.p1);
+PrintS("poly2: ");pWrite(tso.p2);
+PrintS("syz: ");pWrite(tso.syz);
+PrintS("sPoly: ");pWrite(tso.p);
+PrintLn();
+#endif
+        syEnterPair(rP,&tso,&l,index);
+        syInitializePair(&tso);
+      }
+    }
+    i++;
+  }
+  idDelete(&pairs);
+}
+
+/*3
+* performs the modification of a single reduction on the syzygy-level
+*/
+inline void sySPRedSyz_Kosz(syStrategy syzstr,poly redWith,poly syz,poly q=NULL,int l_syz=-1)
+{
+  poly p=pDivide(q,redWith);
+  pSetCoeff(p,nDiv(pGetCoeff(q),pGetCoeff(redWith)));
+  kBucket_Minus_m_Mult_p(syzstr->syz_bucket,p,syz,&l_syz,NULL);
+  pDelete(&p);
+}
+
+/*3
+* normalizes the poly bucket by the ideal;
+* stops the reduction whenever the leading component is less than the
+* crit_comp;
+* returns the changing status
+*/
+static BOOLEAN syRedSyz(kBucket_pt bucket,ideal red,int crit_comp,int* g_l)
+{
+  poly p = kBucketGetLm(bucket);
+  int j = 0,i=IDELEMS(red)-1;
+  number n;
+  BOOLEAN isChanged=FALSE;
+
+  loop
+  {
+    if ((j>=i) || (p==NULL) || (pGetComp(p)<=crit_comp)) break;
+    if ((red->m[j]!=NULL) && (pDivisibleBy(red->m[j],p)))
+    {
+      n = kBucketPolyRed(bucket,red->m[j], g_l[j], NULL);
+      nDelete(&n);
+      p = kBucketGetLm(bucket);
+      isChanged = TRUE;
+      j = 0;
+    }
+    else
+      j++;
+  }
+  return isChanged;
+}
+
+/*3
+* a tail reduction for the syzygies yielding new generators
+*/
+static poly syRedTailSyz(poly tored,ideal red,ideal sec_red,int crit_comp,syStrategy syzstr,
+            int * gen_length,int * secgen_length,int * tored_length)
+{
+  int i=IDELEMS(red)-1,num_mon,num_tail;
+  poly h,hn;
+  // BOOLEAN dummy;
+
+  while ((i>0) && (red->m[i-1]==NULL)) i--;
+  i--;
+  h = tored;
+  if ((h!=NULL) && (pGetComp(h)>crit_comp))
+  {
+    num_mon = 1;
+    hn = pNext(h);
+    num_tail = *tored_length-1;
+    while (hn!=NULL)
+    {
+      kBucketInit(syzstr->syz_bucket,hn,num_tail);
+      /*dummy =*/ (void) syRedSyz(syzstr->syz_bucket,red,crit_comp,gen_length);
+      kBucketClear(syzstr->syz_bucket,&hn,&num_tail);
+      pNext(h) = hn;
+      if ((hn==NULL) || (pGetComp(hn)<=crit_comp))
+        break;
+      else
+      {
+        pIter(h);
+        pIter(hn);
+        num_mon++;
+        num_tail--;
+      }
+    }
+    if (sec_red!=NULL)
+    {
+      while (hn!=NULL)
+      {
+        kBucketInit(syzstr->syz_bucket,hn,num_tail);
+        /*dummy =*/ (void) syRedSyz(syzstr->syz_bucket,sec_red,crit_comp,secgen_length);
+        kBucketClear(syzstr->syz_bucket,&hn,&num_tail);
+        pNext(h) = hn;
+        if (hn==NULL)
+          break;
+        else
+        {
+          pIter(h);
+          pIter(hn);
+          num_mon++;
+          num_tail--;
+        }
+      }
+    }
+    *tored_length = num_mon+num_tail;
+  }
+  assume(pLength(tored)==*tored_length);
+  return tored;
+}
+
+/*3
+* the complete reduction of a single pair which is just stored
+* in bucket and syz_bucket
+*/
+static BOOLEAN syRedSyzPair(syStrategy syzstr,int index,int* g_l,int* orp_l)
+{
+  kBucket_pt bucket=syzstr->bucket;
+  poly p = kBucketGetLm(bucket);
+  ideal red=syzstr->res[index],repr=syzstr->orderedRes[index];
+  int j = 0,i=IDELEMS(red)-1;
+  number n;
+  BOOLEAN isChanged=FALSE;
+
+  loop
+  {
+    if ((j>=i) || (p==NULL)) break;
+    if ((red->m[j]!=NULL) && (pDivisibleBy(red->m[j],p)))
+    {
+      sySPRedSyz_Kosz(syzstr,red->m[j],repr->m[j],p,orp_l[j]);
+      n = kBucketPolyRed(bucket,red->m[j], g_l[j], NULL);
+      nDelete(&n);
+      p = kBucketGetLm(bucket);
+      isChanged = TRUE;
+      j = 0;
+    }
+    else
+      j++;
+  }
+  return isChanged;
+}
+
+/*3
+* the tailreduction for generators (which includes the correction of
+* the corresponding representation)
+*/
+#if 0 /*unused*/
+static void syRedTailSyzPair(SObject tso,syStrategy syzstr,int index,
+            int * gen_length,int* orp_l,int * tored_l,int * syzred_l)
+{
+  int num_mon,num_tail,syz_l;
+  poly h,hn;
+  BOOLEAN dummy;
+
+  h = tso.p;
+  kBucketInit(syzstr->syz_bucket,tso.syz,*syzred_l);
+  if (h!=NULL)
+  {
+    num_mon = 1;
+    hn = pNext(h);
+    num_tail = *tored_l-1;
+    while (hn!=NULL)
+    {
+      kBucketInit(syzstr->bucket,hn,num_tail);
+      dummy = syRedSyzPair(syzstr,index,gen_length,orp_l);
+      kBucketClear(syzstr->bucket,&hn,&num_tail);
+      pNext(h) = hn;
+      if (hn==NULL)
+        break;
+      else
+      {
+        pIter(h);
+        pIter(hn);
+        num_mon++;
+        num_tail--;
+      }
+    }
+    *tored_l = num_mon+num_tail;
+  }
+  kBucketClear(syzstr->syz_bucket,&tso.syz,&syz_l);
+  assume(pLength(tso.syz)==syz_l);
+  assume(pLength(tso.p)==*tored_l);
+}
+#endif
+
+/*3
+* the reduction of a pair in the 0-th module
+*/
+static void redOnePair(SSet resPairs,int itso,int l, ideal syzygies,
+            int crit_comp, syStrategy syzstr,int index,ideal new_generators,
+            ideal new_repr,int * ogm_l,int * orp_l)
+{
+  SObject tso = resPairs[itso];
+  assume (tso.lcm!=NULL);
+  ideal old_generators=syzstr->res[index];
+  ideal old_repr=syzstr->orderedRes[index];
+  int og_idel=IDELEMS(old_generators),ng_place=IDELEMS(new_generators);
+  int toReplace=0;
+  int i,j,syz_l;
+  number /*coefgcd,*/n;
+  polyset ogm=old_generators->m;
+  poly p;
+  BOOLEAN deleteP=FALSE;
+#ifdef EXPERIMENT1
+  poly syzp;
+#endif
+  int syz_place=IDELEMS(syzygies);
+
+  while ((syz_place>0) && (syzygies->m[syz_place-1]==NULL)) syz_place--;
+  while ((ng_place>0) && (new_generators->m[ng_place-1]==NULL)) ng_place--;
+  while ((og_idel>0) && (old_generators->m[og_idel-1]==NULL)) og_idel--;
+  assume (tso.ind1<og_idel);
+  assume (tso.ind2<og_idel);
+  assume (tso.ind1!=tso.ind2);
+  assume (tso.p1 == old_generators->m[tso.ind1]);
+  assume (tso.p2 == old_generators->m[tso.ind2]);
+  tso.p1 = old_generators->m[tso.ind1];
+  tso.p2 = old_generators->m[tso.ind2];
+  if ((tso.p1!=NULL) && (tso.p2!=NULL))
+  {
+    if (TEST_OPT_PROT)
+      PrintS(".");
+    if (index==0)
+    {
+/*--- tests wether a generator must be replaced (lt(f1)|lt(f2)!)--*/
+      if (p_FDeg(tso.p1,currRing)==p_FDeg(tso.lcm,currRing))
+        toReplace = tso.ind1+1;
+      else if (p_FDeg(tso.p2,currRing)==p_FDeg(tso.lcm,currRing))
+        toReplace = tso.ind2+1;
+    }
+#ifdef EXPERIMENT3
+/*--- tests wether the product criterion applies --------------*/
+    if ((index==0) && (old_generators->rank==1) &&
+        (p_FDeg(tso.p1,currRing)+p_FDeg(tso.p2,currRing)==tso.order))
+    {
+      tso.p = NULL;
+      p = pCopy(tso.p1);
+      p_Shift(&p,-1,currRing);
+#ifdef WITH_BUCKET
+      poly pp;
+      pp = pMult_mm(pCopy(old_repr->m[tso.ind2]),p);
+      kBucketInit(syzstr->syz_bucket,pp,-1);
+      pLmDelete(&p);
+      p = pNeg(p);
+      pp = pCopy(old_repr->m[tso.ind2]);
+      int il=-1;
+      while (p!=NULL)
+      {
+        kBucket_Minus_m_Mult_p(syzstr->syz_bucket,p,pp,&il,NULL);
+        pLmDelete(&p);
+      }
+      pDelete(&pp);
+      p = pCopy(tso.p2);
+      p_Shift(&p,-1,currRing);
+      pp = pCopy(old_repr->m[tso.ind1]);
+      il=-1;
+      while (p!=NULL)
+      {
+        kBucket_Minus_m_Mult_p(syzstr->syz_bucket,p,pp,&il,NULL);
+        pLmDelete(&p);
+      }
+      pDelete(&pp);
+      kBucketClear(syzstr->syz_bucket,&tso.syz,&j);
+#else
+      tso.syz = pMult(p,pCopy(old_repr->m[tso.ind2]));
+      p = pCopy(tso.p2);
+      p_Shift(&p,-1,currRing);
+      tso.syz = pSub(tso.syz,pMult(p,pCopy(old_repr->m[tso.ind1])));
+#endif
+    }
+    else
+#endif
+/*--- the product criterion does not apply --------------------*/
+    {
+      tso.p = ksOldCreateSpoly(tso.p2,tso.p1);
+      number coefgcd = n_Gcd(pGetCoeff(tso.p1),pGetCoeff(tso.p2),currRing->cf);
+      assume (old_repr->m[tso.ind1]!=NULL);
+      tso.syz = pCopy(old_repr->m[tso.ind1]);
+      poly tt = pDivide(tso.lcm,tso.p1);
+      pSetComp(tt,0);
+      pSetmComp(tt);
+      pSetCoeff(tt,nDiv(pGetCoeff(tso.p1),coefgcd));
+      tso.syz = pMult_mm(tso.syz,tt);
+      pDelete(&tt);
+      coefgcd = nInpNeg(coefgcd);
+      assume (old_repr->m[tso.ind2]!=NULL);
+      p = pCopy(old_repr->m[tso.ind2]);
+      tt = pDivide(tso.lcm,tso.p2);
+      pSetComp(tt,0);
+      pSetmComp(tt);
+      pSetCoeff(tt,nDiv(pGetCoeff(tso.p2),coefgcd));
+      p = pMult_mm(p,tt);
+      pDelete(&tt);
+      tso.syz = pAdd(p,tso.syz);
+#ifdef EXPERIMENT2
+      if ((tso.syz!=NULL) && (pGetComp(tso.syz)<=crit_comp))
+      {
+/*--- breaks when the leading component is less than crit_comp ------*/
+        deleteP = TRUE;
+        discard_pairs++;
+      }
+#endif
+      nDelete(&coefgcd);
+    }                             //End of the else-part of EXPERIMENT3
+#ifdef SHOW_PROT
+Print("reduziere Paar im Module %d mit: \n",index);
+PrintS("poly1: ");pWrite(tso.p1);
+PrintS("poly2: ");pWrite(tso.p2);
+PrintS("syz: ");pWrite(tso.syz);
+PrintS("sPoly: ");pWrite(tso.p);
+#endif
+    assume(tso.syz!=NULL);
+    kBucketInit(syzstr->syz_bucket,tso.syz,-1);
+    if ((tso.p!=NULL) && (!deleteP))
+    {
+      kBucketInit(syzstr->bucket,tso.p,-1);
+      p = kBucketGetLm(syzstr->bucket);
+      j = 0;
+      loop
+      {
+        if (j>=og_idel)
+        {
+/*--- reduction with generators computed in this procedure ---*/
+          j = 0;
+          while ((j<ng_place) && (!pDivisibleBy(new_generators->m[j],p))) j++;
+          if (j>=ng_place) break;
+          assume (new_repr->m[j]!=NULL);
+          sySPRedSyz_Kosz(syzstr,new_generators->m[j],new_repr->m[j],p);
+          n = kBucketPolyRed(syzstr->bucket,new_generators->m[j],pLength(new_generators->m[j]), NULL);
+          p = kBucketGetLm(syzstr->bucket);
+#ifdef EXPERIMENT1
+          syzp = kBucketGetLm(syzstr->syz_bucket);
+          if ((syzp!=NULL) && (pGetComp(syzp)<=crit_comp))
+          {
+            deleteP =TRUE;
+            break;
+          }
+          //if (syzp==NULL)
+            //assume(p==NULL);
+          //else
+            //if (pGetComp(syzp)<=crit_comp) short_pairs++;
+#endif
+          if (p==NULL) break;
+          j = 0;
+        }
+        if (pDivisibleBy(ogm[j],p))
+        {
+/*--- reduction with general old generators ---------------------*/
+          assume (old_repr->m[j]!=NULL);
+          sySPRedSyz_Kosz(syzstr,ogm[j],old_repr->m[j],p,orp_l[j]);
+          n = kBucketPolyRed(syzstr->bucket,ogm[j],ogm_l[j], NULL);
+          p = kBucketGetLm(syzstr->bucket);
+#ifdef EXPERIMENT1
+          syzp = kBucketGetLm(syzstr->syz_bucket);
+          if ((syzp!=NULL) && (pGetComp(syzp)<=crit_comp))
+          {
+            break;
+            deleteP =TRUE;
+          }
+          //if (syzp==NULL)
+            //assume(p==NULL);
+          //else
+            //if ((pGetComp(syzp)<=crit_comp) && (p!=NULL)) short_pairs++;
+#endif
+          if (p==NULL) break;
+          j = 0;
+        }
+        else
+          j++;
+      }
+      kBucketClear(syzstr->bucket,&tso.p,&tso.length);
+    }
+    kBucketClear(syzstr->syz_bucket,&tso.syz,&syz_l);
+    if (deleteP)
+    {
+      pDelete(&tso.p);
+      pDelete(&tso.syz);
+    }
+  }
+  else
+  {
+    PrintS("Shit happens!\n");
+  }
+#ifdef SHOW_PROT
+Print("erhalte Paar im Module %d mit: \n",index);
+PrintS("syz: ");pWrite(tso.syz);
+PrintS("sPoly: ");pWrite(tso.p);
+PrintLn();
+#endif
+  if (toReplace)
+  {
+/*-- replaces the generator if neccesary ------------------*/
+    pDelete(&old_generators->m[toReplace-1]);
+    pDelete(&old_repr->m[toReplace-1]);
+    for (i=toReplace-1;i<og_idel-1;i++)
+    {
+      old_generators->m[i] = old_generators->m[i+1];
+      old_repr->m[i] = old_repr->m[i+1];
+    }
+    old_generators->m[og_idel-1] = NULL;
+    old_repr->m[og_idel-1] = NULL;
+    for (i=itso+1;i<l;i++)
+    {
+      if (resPairs[i].lcm!=NULL)
+      {
+        if ((resPairs[i].ind1==toReplace-1)||(resPairs[i].ind2==toReplace-1))
+          syDeletePair(&resPairs[i]);
+        else
+        {
+          if (resPairs[i].ind1>=toReplace)
+            (resPairs[i].ind1)--;
+          if (resPairs[i].ind2>=toReplace)
+            (resPairs[i].ind2)--;
+        }
+      }
+    }
+    syCompactifyPairSet(resPairs,l,itso+1);
+  }
+  if (tso.p!=NULL)
+  {
+/*-- stores the new generator ---------------------------------*/
+    //syRedTailSyzPair(tso,syzstr,index,ogm_l,orp_l,&tso.length,&syz_l);
+    if (ng_place>=IDELEMS(new_generators))
+    {
+      pEnlargeSet(&new_generators->m,IDELEMS(new_generators),16);
+      IDELEMS(new_generators) += 16;
+      pEnlargeSet(&new_repr->m,IDELEMS(new_repr),16);
+      IDELEMS(new_repr) += 16;
+    }
+    if (!nIsOne(pGetCoeff(tso.p)))
+    {
+      n=nInvers(pGetCoeff(tso.p));
+      pNorm(tso.p);
+      pMult_nn(tso.syz,n);
+      nDelete(&n);
+    }
+    new_generators->m[ng_place] = tso.p;
+    tso.p = NULL;
+    new_repr->m[ng_place] = tso.syz;
+    tso.syz = NULL;
+  }
+  else
+  {
+/*--- takes the syzygy as new generator of the next module ---*/
+    if (tso.syz==NULL)
+    {
+#ifndef EXPERIMENT2
+#ifdef EXPERIMENT3
+      short_pairs++;
+#endif
+#endif
+    }
+    else if (pGetComp(tso.syz)<=crit_comp)
+    {
+      pDelete(&tso.syz);
+    }
+    else
+    {
+      if (syz_place>=IDELEMS(syzygies))
+      {
+        pEnlargeSet(&syzygies->m,IDELEMS(syzygies),16);
+        IDELEMS(syzygies) += 16;
+      }
+      syzygies->m[syz_place] = tso.syz;
+      tso.syz = NULL;
+      pNorm(syzygies->m[syz_place]);
+    }
+  }
+  resPairs[itso] = tso;
+  syDeletePair(&resPairs[itso]);
+  syTestPairs(resPairs,l,old_generators);
+}
+
+/*3
+* reduction of all pairs of a fixed degree of the 0-th module
+*/
+static BOOLEAN redPairs(SSet resPairs,int l_pairs, ideal syzygies,
+  ideal new_generators,ideal new_repr, int crit_comp,syStrategy syzstr,
+  int index)
+{
+  if (resPairs[0].lcm==NULL) return TRUE;
+  int i,j,actdeg=resPairs[0].order;
+  int * ogm_l=(int*)omAlloc0(IDELEMS(syzstr->res[index])*sizeof(int));
+  int * orp_l=(int*)omAlloc0(IDELEMS(syzstr->orderedRes[index])*sizeof(int));
+  // int t1=IDELEMS(syzstr->res[index]),t2=IDELEMS(syzstr->orderedRes[index]);
+
+  for (j=IDELEMS(syzstr->res[index])-1;j>=0;j--)
+  {
+    if (syzstr->res[index]->m[j]!=NULL)
+      ogm_l[j] = pLength(syzstr->res[index]->m[j]);
+  }
+  for (j=IDELEMS(syzstr->orderedRes[index])-1;j>=0;j--)
+  {
+    if (syzstr->orderedRes[index]->m[j]!=NULL)
+      orp_l[j] = pLength(syzstr->orderedRes[index]->m[j]);
+  }
+  loop
+  {
+    i = 0;
+    if (TEST_OPT_PROT)
+      Print("(%d,%d)",index,resPairs[0].order);
+    while (resPairs[i].order==actdeg)
+    {
+      syTestPairs(resPairs,l_pairs,syzstr->res[index]);
+      redOnePair(resPairs,i,l_pairs,syzygies,crit_comp,syzstr,index,
+                 new_generators, new_repr,ogm_l,orp_l);
+      i++;
+      syTestPairs(resPairs,l_pairs,syzstr->res[index]);
+    }
+    syTestPairs(resPairs,l_pairs,syzstr->res[index]);
+    syCompactifyPairSet(resPairs,l_pairs,0);
+    syTestPairs(resPairs,l_pairs,syzstr->res[index]);
+    if (!idIs0(new_generators))
+      break;
+    else if (resPairs[0].lcm==NULL)  //there are no pairs left and no new_gens
+    {
+      omFreeSize((ADDRESS)ogm_l,IDELEMS(syzstr->res[index])*sizeof(int));
+      omFreeSize((ADDRESS)orp_l,IDELEMS(syzstr->orderedRes[index])*sizeof(int));
+      return TRUE;
+    }
+    else
+      actdeg = resPairs[0].order;
+  }
+  syTestPairs(resPairs,l_pairs,syzstr->res[index]);
+  omFreeSize((ADDRESS)ogm_l,IDELEMS(syzstr->res[index])*sizeof(int));
+  omFreeSize((ADDRESS)orp_l,IDELEMS(syzstr->orderedRes[index])*sizeof(int));
+  return FALSE;
+}
+
+/*3
+* extends the standard basis old_generators with new_generators;
+* returns the syzygies which involve the new elements;
+* assumes that the components of the new_generators are sperated
+* from those of old_generators, i.e. whenever the leading term
+* of a syzygy lies in the part of the old_generators, the syzygy
+* lie just in the module old_generators
+* assumes that the new_generators are reduced w.r.t. old_generators
+*/
+static ideal kosz_std(ideal new_generators,ideal new_repr,syStrategy syzstr,
+                      int index,int next_comp)
+{
+  int og_idel=IDELEMS(syzstr->res[index]);
+  int l_pairs=2*og_idel;
+  ideal syzygies=idInit(16,syzstr->res[index]->rank+1);
+  if ((idIs0(new_generators)) || (new_generators->m[0]==NULL))
+  {
+    Werror("Hier ist was faul!\n");
+    return NULL;
+  }
+  SSet resPairs=(SSet)omAlloc0(l_pairs*sizeof(SObject));
+  loop
+  {
+    updatePairs(&resPairs,&l_pairs,syzstr,index,
+                new_generators,new_repr,next_comp);
+    if (redPairs(resPairs,l_pairs,syzygies, new_generators,new_repr,
+                 next_comp,syzstr,index)) break;
+  }
+  omFreeSize((SSet)resPairs,l_pairs*sizeof(SObject));
+  return syzygies;
+}
+
+/*3
+* normalizes the incoming generators
+*/
+static poly normalize(poly next_p,ideal add_generators, syStrategy syzstr,
+                      int * g_l,int * p_l,int crit_comp)
+{
+  int j=0,i=IDELEMS(add_generators);
+  kBucketInit(syzstr->bucket,next_p,pLength(next_p));
+  poly p = kBucketGetLm(syzstr->bucket),result;
+  number n;
+
+  loop
+  {
+    if ((j>=i) || (p==NULL) || (pGetComp(p)<=crit_comp)) break;
+    if ((add_generators->m[j]!=NULL) && (pDivisibleBy(add_generators->m[j],p)))
+    {
+      n = kBucketPolyRed(syzstr->bucket,add_generators->m[j], g_l[j], NULL);
+      nDelete(&n);
+      p = kBucketGetLm(syzstr->bucket);
+      j = 0;
+    }
+    else
+      j++;
+  }
+  kBucketClear(syzstr->bucket,&result,p_l);
+  return result;
+}
+
+/*3
+* updates the pairs inthe higher modules
+*/
+static void updatePairsHIndex(SSet *resPairs,int *l_pairs,syStrategy /*syzstr*/,
+       int index,ideal add_generators,ideal /*add_repr*/,ideal /*new_generators*/,
+       ideal /*new_repr*/,int /*crit_comp*/,int* first_new)
+{
+  int i=*first_new,l=*l_pairs,j,ll,j1,add_idel=IDELEMS(add_generators);
+  ideal pairs=idInit(add_idel,add_generators->rank);
+  polyset prs=pairs->m;
+  poly p=NULL;
+  SObject tso;
+
+  syInitializePair(&tso);
+  while ((l>0) && ((*resPairs)[l-1].lcm==NULL)) l--;
+  while ((i<add_idel) && (add_generators->m[i]!=NULL))
+  {
+    for (j=0;j<i;j++)
+    {
+      if (pGetComp(add_generators->m[j]) == pGetComp(add_generators->m[i]))
+      {
+        p = pOne();
+        pLcm(add_generators->m[j],add_generators->m[i],p);
+        pSetComp(p,i+1);
+        pSetm(p);
+        j1 = 0;
+        while (j1<j)
+        {
+          if (prs[j1]!=NULL)
+          {
+            if (pLmDivisibleByNoComp(prs[j1],p))
+            {
+              pDelete(&p);
+              break;
+            }
+            else if (pLmDivisibleByNoComp(p,prs[j1]))
+            {
+              pDelete(&(prs[j1]));
+            }
+#ifdef USE_CHAINCRIT
+            else
+            {
+              poly p1,p2;
+              int ip=(currRing->N);
+              p1 = pDivide(p,add_generators->m[j]);
+              p2 = pDivide(prs[j1],add_generators->m[j1]);
+              while ((ip>0) && (pGetExp(p1,ip)*pGetExp(p2,ip)==0)) ip--;
+              if (ip==0)
+              {
+                int ti=0;
+                while ((ti<l) && (((*resPairs)[ti].ind1!=j1)|| ((*resPairs)[ti].ind2!=j))) ti++;
+                if (ti<l)
+                {
+                  if (TEST_OPT_PROT) PrintS("cc");
+                  syDeletePair(&(*resPairs)[ti]);
+                  syCompactifyPairSet(*resPairs,*l_pairs,ti);
+                  l--;
+                }
+              }
+              pDelete(&p1);
+              pDelete(&p2);
+            }
+#endif
+          }
+          j1++;
+        }
+        if (p!=NULL)
+          prs[j] = p;
+      }
+    }
+    for (j=0;j<i;j++)
+    {
+      if (prs[j] !=NULL)
+      {
+        if (l>=*l_pairs)
+        {
+          SSet temp = (SSet)omAlloc0((*l_pairs+16)*sizeof(SObject));
+          for (ll=0;ll<*l_pairs;ll++)
+          {
+            temp[ll].p = (*resPairs)[ll].p;
+            temp[ll].p1 = (*resPairs)[ll].p1;
+            temp[ll].p2 = (*resPairs)[ll].p2;
+            temp[ll].syz = (*resPairs)[ll].syz;
+            temp[ll].lcm = (*resPairs)[ll].lcm;
+            temp[ll].ind1 = (*resPairs)[ll].ind1;
+            temp[ll].ind2 = (*resPairs)[ll].ind2;
+            temp[ll].syzind = (*resPairs)[ll].syzind;
+            temp[ll].order = (*resPairs)[ll].order;
+            temp[ll].isNotMinimal = (*resPairs)[ll].isNotMinimal;
+          }
+          omFreeSize((ADDRESS)(*resPairs),*l_pairs*sizeof(SObject));
+          *l_pairs += 16;
+          (*resPairs) = temp;
+        }
+        tso.lcm = prs[j];
+        prs[j] = NULL;
+        tso.order = p_FDeg(tso.lcm,currRing);
+        tso.p1 = add_generators->m[j];
+        tso.p2 = add_generators->m[i];
+        tso.ind1 = j;
+        tso.ind2 = i;
+        tso.syzind = -1;
+        tso.isNotMinimal = NULL;
+        tso.p = NULL;
+        tso.syz = NULL;
+        SSet rP=*resPairs;
+#ifdef SHOW_PROT
+Print("erzeuge Paar im Modul %d,%d mit: \n",index,tso.order);
+PrintS("poly1: ");pWrite(tso.p1);
+PrintS("poly2: ");pWrite(tso.p2);
+PrintS("syz: ");pWrite(tso.syz);
+PrintS("sPoly: ");pWrite(tso.p);
+PrintLn();
+#endif
+        syEnterPair(rP,&tso,&l,index);
+        syInitializePair(&tso);
+      }
+    }
+    i++;
+  }
+  *first_new = i;
+  idDelete(&pairs);
+}
+
+/*3
+* reduction of a single pair in the higher moduls
+*/
+#ifdef SHOW_PROT
+static void redOnePairHIndex(SSet resPairs,int itso, int crit_comp,
+            syStrategy syzstr,int index,ideal add_generators, ideal add_repr,
+            ideal new_generators, ideal new_repr,int * next_place_add,int ** g_l,
+            poly deg_soc)
+#else
+static void redOnePairHIndex(SSet resPairs,int itso, int crit_comp,
+            syStrategy syzstr,int /*index*/,ideal add_generators, ideal add_repr,
+            ideal new_generators, ideal new_repr,int * next_place_add,int ** g_l,
+            poly deg_soc)
+#endif
+{
+  SObject tso = resPairs[itso];
+  assume (tso.lcm!=NULL);
+  int ng_place=IDELEMS(new_generators);
+  int i,j;
+  number n;
+  poly p;
+#ifdef EXPERIMENT1
+  poly syzp;
+#endif
+
+  assume (tso.ind1<*next_place_add);
+  assume (tso.ind2<*next_place_add);
+  assume (tso.ind1!=tso.ind2);
+  assume (tso.p1 == add_generators->m[tso.ind1]);
+  assume (tso.p2 == add_generators->m[tso.ind2]);
+  tso.p1 = add_generators->m[tso.ind1];
+  tso.p2 = add_generators->m[tso.ind2];
+  if ((tso.p1!=NULL) && (tso.p2!=NULL))
+  {
+    if (TEST_OPT_PROT)
+      PrintS(".");
+#ifdef USE_PROD_CRIT
+    if (p_FDeg(tso.p1,currRing)+p_FDeg(tso.p2,currRing)==tso.order+p_FDeg(deg_soc,currRing))
+    {
+      if (TEST_OPT_PROT) PrintS("pc");
+      int ac=pGetComp(tso.p1);
+      assume(ac=pGetComp(tso.p2));
+      poly p1=pCopy(tso.p1);
+      poly p2=pCopy(tso.p2);
+      poly pp1,pp2,tp1,tp2;
+      poly sp1=pCopy(add_repr->m[tso.ind1]),sp2=pCopy(add_repr->m[tso.ind2]);
+      pp1 = p1;
+      pp2 = p2;
+      loop
+      {
+        assume(pp1!=NULL);
+        for(i=(int)(currRing->N); i; i--)
+          pSetExp(pp1,i, pGetExp(pp1,i)- pGetExp(deg_soc,i));
+        pSetComp(pp1, 0);
+        pSetm(pp1);
+        if ((pNext(pp1)!=NULL) && (pGetComp(pNext(pp1))!=ac))  break;
+        pIter(pp1);
+      }
+      loop
+      {
+        assume(pp2!=NULL);
+        for(i=(int)(currRing->N); i; i--)
+          pSetExp(pp2,i, pGetExp(pp2,i)- pGetExp(deg_soc,i));
+        pSetComp(pp2, 0);
+        pSetm(pp2);
+        if ((pNext(pp2)!=NULL) && (pGetComp(pNext(pp2))!=ac)) break;
+        pIter(pp2);
+      }
+      tp1 = pNext(pp1);
+      tp2 = pNext(pp2);
+      pNext(pp1) = NULL;
+      pNext(pp2) = NULL;
+      //p_Shift(&p1,-ac,currRing);
+      //p_Shift(&p2,-ac,currRing);
+      tp1 = pMult(tp1,pCopy(p2));
+      tp2 = pMult(tp2,pCopy(p1));
+      sp1 = pMult(p2,sp1);
+      sp2 = pMult(p1,sp2);
+      tso.p = pSub(tp1,tp2);
+      tso.syz = pSub(sp1,sp2);
+    }
+    else
+#endif
+    {
+      tso.p = ksOldCreateSpoly(tso.p2,tso.p1);
+      number coefgcd = n_Gcd(pGetCoeff(tso.p1),pGetCoeff(tso.p2),currRing->cf);
+      assume (add_repr->m[tso.ind1]!=NULL);
+      tso.syz = pCopy(add_repr->m[tso.ind1]);
+      poly tt = pDivide(tso.lcm,tso.p1);
+      pSetComp(tt,0);
+      pSetmComp(tt);
+      pSetCoeff(tt,nDiv(pGetCoeff(tso.p1),coefgcd));
+      tso.syz = pMult_mm(tso.syz,tt);
+      pDelete(&tt);
+      coefgcd = nInpNeg(coefgcd);
+      assume (add_repr->m[tso.ind2]!=NULL);
+      p = pCopy(add_repr->m[tso.ind2]);
+      tt = pDivide(tso.lcm,tso.p2);
+      pSetComp(tt,0);
+      pSetmComp(tt);
+      pSetCoeff(tt,nDiv(pGetCoeff(tso.p2),coefgcd));
+      p = pMult_mm(p,tt);
+      pDelete(&tt);
+      tso.syz = pAdd(p,tso.syz);
+      nDelete(&coefgcd);
+    }
+#ifdef SHOW_PROT
+Print("reduziere Paar im Module %d mit: \n",index);
+PrintS("poly1: ");pWrite(tso.p1);
+PrintS("poly2: ");pWrite(tso.p2);
+PrintS("syz: ");pWrite(tso.syz);
+PrintS("sPoly: ");pWrite(tso.p);
+#endif
+    assume(tso.syz!=NULL);
+    kBucketInit(syzstr->syz_bucket,tso.syz,-1);
+    if (tso.p!=NULL)
+    {
+      kBucketInit(syzstr->bucket,tso.p,-1);
+      p = kBucketGetLm(syzstr->bucket);
+      j = 0;
+      loop
+      {
+        if (j>=*next_place_add) break;
+        if (pDivisibleBy(add_generators->m[j],p))
+        {
+          assume (add_repr->m[j]!=NULL);
+          sySPRedSyz_Kosz(syzstr,add_generators->m[j],add_repr->m[j],p);
+          n = kBucketPolyRed(syzstr->bucket,add_generators->m[j],
+                   pLength(add_generators->m[j]), NULL);
+          p = kBucketGetLm(syzstr->bucket);
+          if ((p==NULL) || (pGetComp(p)<=crit_comp)) break;
+          j = 0;
+        }
+        else
+          j++;
+      }
+      kBucketClear(syzstr->bucket,&tso.p,&tso.length);
+    }
+    kBucketClear(syzstr->syz_bucket,&tso.syz,&j);
+  }
+  else
+  {
+    PrintS("Shit happens!\n");
+  }
+#ifdef SHOW_PROT
+Print("erhalte Paar im Module %d mit: \n",index);
+PrintS("syz: ");pWrite(tso.syz);
+PrintS("sPoly: ");pWrite(tso.p);
+PrintLn();
+#endif
+  if (tso.p!=NULL)
+  {
+    if (!nIsOne(pGetCoeff(tso.p)))
+    {
+      n=nInvers(pGetCoeff(tso.p));
+      pNorm(tso.p);
+      pMult_nn(tso.syz,n);
+      nDelete(&n);
+    }
+  }
+  if ((TEST_OPT_PROT) && (tso.syz==NULL)) PrintS("null");
+  if ((tso.p!=NULL) && (pGetComp(tso.p)>crit_comp))
+  {
+    if (*next_place_add>=IDELEMS(add_generators))
+    {
+      pEnlargeSet(&add_generators->m,IDELEMS(add_generators),16);
+      pEnlargeSet(&add_repr->m,IDELEMS(add_repr),16);
+      *g_l = (int*)omRealloc0Size((ADDRESS)*g_l, IDELEMS(add_generators)*sizeof(int),
+                            (IDELEMS(add_generators)+16)*sizeof(int));
+      IDELEMS(add_generators) += 16;
+      IDELEMS(add_repr) += 16;
+    }
+    assume(add_repr->m[*next_place_add]==NULL);
+    add_generators->m[*next_place_add] = tso.p;
+    add_repr->m[*next_place_add] = tso.syz;
+    (*g_l)[*next_place_add] = tso.length;
+    (*next_place_add)++;
+  }
+  else
+  {
+    while ((ng_place>0) && (new_generators->m[ng_place-1]==NULL) &&
+          (new_repr->m[ng_place-1]==NULL)) ng_place--;
+    if (ng_place>=IDELEMS(new_generators))
+    {
+      pEnlargeSet(&new_generators->m,IDELEMS(new_generators),16);
+      IDELEMS(new_generators) += 16;
+      pEnlargeSet(&new_repr->m,IDELEMS(new_repr),16);
+      IDELEMS(new_repr) += 16;
+    }
+    new_generators->m[ng_place] = tso.p;
+    new_repr->m[ng_place] = tso.syz;
+  }
+  tso.p = NULL;
+  tso.syz = NULL;
+  resPairs[itso] = tso;
+  syDeletePair(&resPairs[itso]);
+}
+
+/*3
+* reduction of all pairs of a fixed degree of a fixed module
+*/
+static BOOLEAN reducePairsHIndex(SSet resPairs,int l_pairs,syStrategy syzstr,
+       int index,ideal add_generators,ideal add_repr,ideal new_generators,
+       ideal new_repr,int crit_comp,int * red_deg,int * next_place_add,int **g_l,
+       resolvente totake)
+{
+  if (resPairs[0].lcm==NULL) return FALSE;
+  int i=0;
+  poly deg_soc;
+
+  if (TEST_OPT_PROT)
+    Print("(%d,%d)",index,resPairs[0].order);
+  while ((i<l_pairs) && (resPairs[i].order==*red_deg))
+  {
+    assume(totake[index-1]!=NULL);
+    assume(pGetComp(resPairs[i].p1)<=IDELEMS(totake[index-1]));
+    assume(totake[index-1]->m[pGetComp(resPairs[i].p1)-1]!=NULL);
+    deg_soc = totake[index-1]->m[pGetComp(resPairs[i].p1)-1];
+    redOnePairHIndex(resPairs,i,crit_comp,syzstr,index, add_generators,add_repr,
+                     new_generators, new_repr,next_place_add,g_l,deg_soc);
+    i++;
+  }
+  syCompactifyPairSet(resPairs,l_pairs,0);
+  if (resPairs[0].lcm==NULL)  //there are no pairs left and no new_gens
+    return FALSE;
+  else
+    *red_deg = resPairs[0].order;
+  return TRUE;
+}
+
+/*3
+* we proceed the generators of the next module;
+* they are stored in add_generators and add_repr;
+* if the normal form of a new genrators w.r.t. add_generators has
+* pGetComp<crit_comp it is skipped from the reduction;
+* new_generators and new_repr (which are empty) stores the result of the
+* reduction which is normalized afterwards
+*/
+static void procedeNextGenerators(ideal temp_generators,ideal /*temp_repr*/,
+      ideal new_generators, ideal new_repr, ideal add_generators,
+      ideal add_repr, syStrategy syzstr,int index, int crit_comp,
+      resolvente totake)
+{
+  int i=0,j,next_new_el;
+  int idel_temp=IDELEMS(temp_generators);
+  int next_place_add;
+  int p_length,red_deg,l_pairs=IDELEMS(add_generators);
+  poly next_p;
+  int * gen_length=(int*)omAlloc0(IDELEMS(add_generators)*sizeof(int));
+  int * secgen_length=(int*)omAlloc0(IDELEMS(syzstr->res[index])*sizeof(int));
+  BOOLEAN pairs_left;
+  SSet resPairs=(SSet)omAlloc0(l_pairs*sizeof(SObject));
+
+  for (j=IDELEMS(syzstr->res[index])-1;j>=0;j--)
+  {
+    if (syzstr->res[index]->m[j]!=NULL)
+      secgen_length[j] = pLength(syzstr->res[index]->m[j]);
+  }
+  assume(idIs0(new_generators));
+  next_place_add = IDELEMS(add_generators);
+  while ((next_place_add>0) && (add_generators->m[next_place_add-1]==NULL))
+    next_place_add--;
+  int next_deg = p_FDeg(temp_generators->m[i],currRing);
+  next_new_el = next_place_add;
+/*--- loop about all all elements-----------------------------------*/
+  while ((i<idel_temp) && (temp_generators->m[i]!=NULL))
+  {
+/*--- separates elements of equal degree----------------------------*/
+#ifdef USE_REGULARITY
+    if (syzstr->regularity>0)
+    {
+      if (next_deg >= syzstr->regularity+index)
+      {
+        while ((i<idel_temp) && (temp_generators->m[i]!=NULL))
+        {
+          pDelete(&temp_generators->m[i]);
+          i++;
+        }
+        break;
+      }
+    }
+#endif
+    while ((i<idel_temp) && (p_FDeg(temp_generators->m[i],currRing)==next_deg))
+    {
+      next_p = temp_generators->m[i];
+      temp_generators->m[i] = NULL;
+      next_p = normalize(next_p,add_generators,syzstr,gen_length,&p_length,
+                crit_comp);
+      if (next_p!=NULL)
+      {
+        if (pGetComp(next_p)<=(unsigned)crit_comp)
+        {
+          pDelete(&next_p);
+          //if (TEST_OPT_PROT) Print("u(%d)",index);
+        }
+        else
+        {
+          next_p = syRedTailSyz(next_p,add_generators,syzstr->res[index],crit_comp,syzstr,
+            gen_length,secgen_length,&p_length);
+          if (!nIsOne(pGetCoeff(next_p)))
+            pNorm(next_p);
+          if (next_place_add>=IDELEMS(add_generators))
+          {
+            pEnlargeSet(&add_generators->m,IDELEMS(add_generators),16);
+            pEnlargeSet(&add_repr->m,IDELEMS(add_repr),16);
+            gen_length = (int*)omRealloc0Size((ADDRESS)gen_length, IDELEMS(add_generators)*sizeof(int),
+                                        (IDELEMS(add_generators)+16)*sizeof(int));
+            IDELEMS(add_generators) += 16;
+            IDELEMS(add_repr) += 16;
+          }
+          add_generators->m[next_place_add] = next_p;
+          if (totake[index]==NULL)
+            totake[index] = idInit(16,new_generators->rank);
+          if ((*syzstr->Tl)[index]==IDELEMS(totake[index]))
+          {
+            pEnlargeSet(&totake[index]->m,IDELEMS(totake[index]),
+                        (*syzstr->Tl)[index]+16-IDELEMS(totake[index]));
+            for (j=IDELEMS(totake[index]);j<(*syzstr->Tl)[index]+16;j++)
+              totake[index]->m[j] = NULL;
+            IDELEMS(totake[index]) = (*syzstr->Tl)[index]+16;
+          }
+#ifdef FULL_TOTAKE
+          totake[index]->m[(*syzstr->Tl)[index]] = pCopy(next_p);
+#else
+          totake[index]->m[(*syzstr->Tl)[index]] = pHead(next_p);
+#endif
+          assume(add_repr->m[next_place_add]==NULL);
+#ifdef WITH_SCHREYER_ORD
+          add_repr->m[next_place_add] = pHead(add_generators->m[next_place_add]);
+#else
+          add_repr->m[next_place_add] = pOne();
+#endif
+          ((*syzstr->Tl)[index])++;
+          pSetComp(add_repr->m[next_place_add],(*syzstr->Tl)[index]);
+          pSetmComp(add_repr->m[next_place_add]);
+          gen_length[next_place_add] = p_length;
+          next_place_add++;
+        }
+      }
+      i++;
+    }                        //end inner loop
+    red_deg = next_deg;
+    if (i<idel_temp)
+      next_deg = p_FDeg(temp_generators->m[i],currRing);
+    else
+      next_deg = -1;
+    if ((next_place_add>next_new_el) || (next_deg<0))  //there are new generators or pairs
+    {
+/*-reducing and generating pairs untill the degree of the next generators-*/
+      pairs_left = TRUE;
+      while (pairs_left && ((next_deg<0) || (red_deg<= next_deg)))
+      {
+        updatePairsHIndex(&resPairs,&l_pairs,syzstr,index,add_generators,
+          add_repr,new_generators,new_repr,crit_comp,&next_new_el);
+        pairs_left = reducePairsHIndex(resPairs,l_pairs,syzstr,index,add_generators,
+           add_repr,new_generators,new_repr,crit_comp,&red_deg,&next_place_add,&gen_length,
+           totake);
+      }
+    }
+  }
+  omFreeSize((SSet)resPairs,l_pairs*sizeof(SObject));
+  omFreeSize((ADDRESS)gen_length,IDELEMS(add_generators)*sizeof(int));
+  omFreeSize((ADDRESS)secgen_length,IDELEMS(syzstr->res[index])*sizeof(int));
+}
+
+/*3
+* normalizes the part of the next reduction lying within the block
+* of former generators (old_generators);
+*/
+static ideal normalizeOldPart(ideal new_generators,ideal new_repr,
+                      syStrategy syzstr,int index,int /*crit_comp*/)
+{
+  ideal old_generators= syzstr->res[index];
+  ideal old_repr= syzstr->orderedRes[index];
+  int i,j=0,ii=IDELEMS(old_generators)-1,dummy;
+  poly p;
+  number n;
+  int * g_l=(int*)omAlloc0(IDELEMS(old_generators)*sizeof(int));
+
+  for (i=0;i<IDELEMS(old_generators);i++)
+  {
+    if (old_generators->m[i]!=NULL)
+    {
+      g_l[i] = pLength(old_generators->m[i]);
+    }
+  }
+  for (i=IDELEMS(new_generators)-1;i>=0;i--)
+  {
+    if (new_generators->m[i]!=NULL)
+    {
+      kBucketInit(syzstr->bucket,new_generators->m[i],
+                   pLength(new_generators->m[i]));
+      kBucketInit(syzstr->syz_bucket,new_repr->m[i],
+                   pLength(new_repr->m[i]));
+      p = kBucketGetLm(syzstr->bucket);
+      loop
+      {
+        if ((j>=ii) || (p==NULL)) break;
+        if ((old_generators->m[j]!=NULL) &&
+            (pDivisibleBy(old_generators->m[j],p)))
+        {
+          sySPRedSyz_Kosz(syzstr,old_generators->m[j],old_repr->m[j],p);
+          n = kBucketPolyRed(syzstr->bucket,old_generators->m[j], g_l[j], NULL);
+          nDelete(&n);
+          p = kBucketGetLm(syzstr->bucket);
+          j = 0;
+        }
+        else
+          j++;
+      }
+      assume (p==NULL);
+      kBucketClear(syzstr->bucket,&new_generators->m[i],&dummy);
+      kBucketClear(syzstr->syz_bucket,&new_repr->m[i],&dummy);
+    }
+  }
+  ideal result=idInit(IDELEMS(new_repr),new_repr->rank);
+  for (j=IDELEMS(new_repr)-1;j>=0;j--)
+  {
+    result->m[j] = new_repr->m[j];
+    if ((result->m[j]!=NULL) && (!nIsOne(pGetCoeff(result->m[j]))))
+      pNorm(result->m[j]);
+    new_repr->m[j] = NULL;
+  }
+  omFreeSize((ADDRESS)g_l,IDELEMS(old_generators)*sizeof(int));
+  return result;
+}
+
+/*3
+* constructs the new subresolution for a nonregular extension
+*/
+static ideal kosz_ext(ideal new_generators,ideal new_repr,syStrategy syzstr,
+                      int index,int next_comp,resolvente totake)
+{
+  ideal temp_generators =idInit(IDELEMS(new_generators),new_generators->rank);
+  ideal temp_repr=idInit(IDELEMS(new_repr),new_repr->rank);
+  ideal add_generators =idInit(IDELEMS(new_generators),new_generators->rank);
+  ideal add_repr=idInit(IDELEMS(new_repr),new_repr->rank);
+  int min_deg=-1;
+  int j,jj,k,deg_p,idel_temp=IDELEMS(temp_generators);
+  poly p;
+/*--reorder w.r.t. the degree----------------------------------------*/
+  for (j=IDELEMS(new_generators)-1;j>=0;j--)
+  {
+    if (new_generators->m[j]!=NULL)
+    {
+      p = new_generators->m[j];
+      new_generators->m[j] = NULL;
+      deg_p = p_FDeg(p,currRing);
+      if (min_deg<0)
+      {
+        min_deg = deg_p;
+      }
+      else
+      {
+        if (deg_p<min_deg) min_deg = deg_p;
+      }
+      k = 0;
+      while ((k<idel_temp) && (temp_generators->m[k]!=NULL) &&
+             (p_FDeg(temp_generators->m[k],currRing)<=deg_p)) k++;
+      for (jj=idel_temp-1;jj>k;jj--)
+      {
+        temp_generators->m[jj] = temp_generators->m[jj-1];
+      }
+      temp_generators->m[k] = p;
+    }
+  }
+/*--- computing the standard basis in the resolution of the extension -*/
+  procedeNextGenerators(temp_generators,temp_repr,new_generators,new_repr,
+    add_generators,add_repr,syzstr,index,next_comp,totake);
+  j = IDELEMS(syzstr->res[index]);
+  while ((j>0) && (syzstr->res[index]->m[j-1]==NULL)) j--;
+  jj = IDELEMS(add_generators);
+  while ((jj>0) && (add_generators->m[jj-1]==NULL)) jj--;
+  if (j+jj>=IDELEMS(syzstr->res[index]))
+  {
+    pEnlargeSet(&syzstr->res[index]->m,IDELEMS(syzstr->res[index]),
+                j+jj+1-IDELEMS(syzstr->res[index]));
+    IDELEMS(syzstr->res[index]) = j+jj+1;
+    pEnlargeSet(&syzstr->orderedRes[index]->m,IDELEMS(syzstr->orderedRes[index]),
+                j+jj+1-IDELEMS(syzstr->orderedRes[index]));
+    IDELEMS(syzstr->orderedRes[index]) = j+jj+1;
+  }
+  for (k=0;k<jj;k++)
+  {
+    syzstr->res[index]->m[j+k] = add_generators->m[k];
+    syzstr->orderedRes[index]->m[j+k] = add_repr->m[k];
+    add_generators->m[k] = NULL;
+    add_repr->m[k] = NULL;
+  }
+  assume(idIs0(add_generators));
+  assume(idIs0(add_repr));
+  idDelete(&add_generators);
+  idDelete(&add_repr);
+  idDelete(&temp_generators);
+  idDelete(&temp_repr);
+/*--- normalizing the rest to get the syzygies ------------------------*/
+  return normalizeOldPart(new_generators,new_repr,syzstr,index,next_comp);
+}
+
+/*
+* this procedure assumes that the first order is C !!!
+* INPUT: old_generators - the generators of the actual module
+*                         computed so far (they are mixed vectors)
+*        old_repr       - the representations of the old generators
+*        new_generators - generators coming from reductions below,
+*                         they must have leading terms in new components
+*                         (they live only in the module part)
+*  (*syzstr->Tl)[index] - the last used component in the syzygy
+* OUTPUT: old_generators is updated
+*         new_generators is empty
+*         the return value is a set of new generators for the syzygies,
+*/
+static ideal syAppendSyz(ideal new_generators, syStrategy syzstr,int index,int crit_comp,
+                         resolvente totake)
+{
+  int i,j;
+  ideal result;
+  int rk_new_gens = id_RankFreeModule(new_generators,currRing);
+  if (syzstr->res[index]==NULL)
+  {
+    syzstr->res[index] = idInit(1,si_max(rk_new_gens,1));
+    syzstr->orderedRes[index] = idInit(1,si_max(rk_new_gens,1));
+  }
+  int ng_idel=IDELEMS(new_generators);
+  ideal new_repr =idInit(ng_idel, crit_comp+ng_idel);
+
+  if (index==0)
+  {
+    //int * og_l=(int*)omAlloc0(IDELEMS(syzstr->res[0])*sizeof(int));
+    //for (i=IDELEMS(syzstr->res[0])-1;i>=0;i--)
+    //{
+      //if (syzstr->res[0]->m[i]!=NULL)
+        //og_l[i] = pLength(syzstr->res[0]->m[i]);
+    //}
+    for (i=0;i<ng_idel;i++)
+    {
+      if (new_generators->m[i]!=NULL)
+      {
+        //int ng_l=pLength(new_generators->m[i]);
+        //new_generators->m[i] = syRedTailSyz(new_generators->m[i],syzstr->res[0],NULL,0,syzstr,
+            //og_l,NULL,&ng_l);
+        if (totake[index]==NULL)
+          totake[index] = idInit(16,new_generators->rank);
+        if ((*syzstr->Tl)[index]>=IDELEMS(totake[index]))
+        {
+          pEnlargeSet(&totake[index]->m,IDELEMS(totake[index]),
+                      (*syzstr->Tl)[index]+16-IDELEMS(totake[index]));
+          for (j=IDELEMS(totake[index]);j<(*syzstr->Tl)[index]+16;j++)
+            totake[index]->m[j] = NULL;
+          IDELEMS(totake[index]) = (*syzstr->Tl)[index]+16;
+        }
+#ifdef FULL_TOTAKE
+        totake[index]->m[(*syzstr->Tl)[index]] = pCopy(new_generators->m[i]);
+#else
+        totake[index]->m[(*syzstr->Tl)[index]] = pHead(new_generators->m[i]);
+#endif
+#ifdef WITH_SCHREYER_ORD
+        new_repr->m[i] = pHead(new_generators->m[i]);
+#else
+        new_repr->m[i] = pOne();
+#endif
+        ((*syzstr->Tl)[index])++;
+        pSetComp(new_repr->m[i],(*syzstr->Tl)[index]);
+        pSetmComp(new_repr->m[i]);
+      }
+    }
+    //omFreeSize((ADDRESS)og_l,IDELEMS(syzstr->res[0])*sizeof(int));
+#ifdef SHOW_PROT
+PrintS("Add new generators:\n");
+idPrint(new_generators);
+PrintS("with representaions:\n");
+idPrint(new_repr);
+#endif
+    result = kosz_std(new_generators,new_repr,syzstr,index,crit_comp);
+  }
+  else
+  {
+    result = kosz_ext(new_generators,new_repr,syzstr,index,crit_comp,totake);
+  }
+  idSkipZeroes(result);
+  assume(idIs0(new_repr));
+  idDelete(&new_repr);
+  return result;
+}
+
+/*
+* main call of the extended Koszul-resolution
+*/
+syStrategy syKosz(ideal arg,int * length)
+{
+  int i,j,jj,k=0,index=0,rk_arg/*,next_syz=0*/;
+  int crit_comp,t_comp,next_deg,old_tl;
+  ideal temp=NULL,old_ideal,old_repr;
+  ring origR = currRing;
+  poly next_gen;
+  BOOLEAN isRegular;
+
+  discard_pairs = 0;
+  short_pairs = 0;
+  if (idIs0(arg)) return NULL;
+  rk_arg = id_RankFreeModule(arg,currRing);
+  syStrategy syzstr=(syStrategy)omAlloc0(sizeof(ssyStrategy));
+/*--- changes to a Cdp-ring ----------------------------*/
+  syzstr->syRing = rAssure_C_dp(origR); rChangeCurrRing(syzstr->syRing);
+/*--- initializes the data structures---------------*/
+  syzstr->length = *length = (syzstr->syRing->N)+2;
+  syzstr->regularity = -1;
+  if (origR!=syzstr->syRing)
+    temp = idrCopyR(arg, origR, syzstr->syRing);
+  else
+    temp = idCopy(arg);
+  if (rk_arg==0)
+  {
+    for (j=0;j<IDELEMS(temp);j++)
+    {
+      if (temp->m[j]!=NULL)
+        p_Shift(&temp->m[j],1,currRing);
+    }
+  }
+  idSkipZeroes(temp);
+#ifdef WITH_SORT
+  if (temp->m[0]!=NULL)
+  {
+    int md;
+    int maxdeg=p_FDeg(temp->m[IDELEMS(temp)-1],currRing);
+    ideal temp1=idInit(IDELEMS(temp),temp->rank);
+    for (j=IDELEMS(temp)-2;j>=0;j--)
+    {
+      jj = p_FDeg(temp->m[j],currRing);
+      if (jj>maxdeg) maxdeg = jj;
+    }
+    while (!idIs0(temp))
+    {
+      md = maxdeg;
+      for (j=IDELEMS(temp)-1;j>=0;j--)
+      {
+        if (temp->m[j]!=NULL)
+        {
+          jj = p_FDeg(temp->m[j],currRing);
+          if (jj<md) md = jj;
+        }
+      }
+      for (j=0;j<IDELEMS(temp);j++)
+      {
+        if ((temp->m[j]!=NULL) && (p_FDeg(temp->m[j],currRing)==md))
+        {
+          temp1->m[k] = temp->m[j];
+          temp->m[j] = NULL;
+          k++;
+        }
+      }
+    }
+    idDelete(&temp);
+    temp = temp1;
+    temp1 = NULL;
+  }
+#endif
+#ifdef USE_REGULARITY
+  int last_generator=IDELEMS(temp)-1;
+  while ((last_generator>=0) && (temp->m[last_generator]==NULL))
+    last_generator--;
+#endif
+  syzstr->res = (resolvente)omAlloc0((*length+1)*sizeof(ideal));
+  syzstr->orderedRes = (resolvente)omAlloc0((*length+1)*sizeof(ideal));
+  resolvente totake=(resolvente)omAlloc0((*length+1)*sizeof(ideal));
+  syzstr->Tl = new intvec(*length+1);
+  syzstr->bucket = kBucketCreate(currRing);
+  syzstr->syz_bucket = kBucketCreate(currRing);
+  ideal new_generators=idInit(1,si_max(rk_arg,1));
+  ideal temp_gens,old_std;
+  syzstr->res[0] = idInit(1,1);
+  if (rk_arg>1) syzstr->res[0]->rank = rk_arg;
+  syzstr->orderedRes[0] = idInit(1,1);
+/*--- computes the resolution ----------------------*/
+  i = 0;
+  while (i<IDELEMS(temp))
+  {
+    if (temp->m[i]!=NULL)
+    {
+      new_generators->m[0] = kNF(syzstr->res[0],currRing->qideal,temp->m[i]);
+      if (!nIsOne(pGetCoeff(new_generators->m[0])))
+        pNorm(new_generators->m[0]);
+      next_deg = p_FDeg(new_generators->m[0],currRing);
+      next_gen = pCopy(new_generators->m[0]);
+    }
+    if (!idIs0(new_generators))
+    {
+      index = 0;
+      while (index<=*length)
+      {
+        if (index==0)
+        {
+          old_ideal = idCopy(syzstr->res[0]);
+          old_repr = idCopy(syzstr->orderedRes[0]);
+          old_tl = (*syzstr->Tl)[0];
+          old_std = id_Head(syzstr->res[0],currRing);
+        }
+        t_comp = (*syzstr->Tl)[index];
+        if (index==0) crit_comp = t_comp;
+        temp_gens = syAppendSyz(new_generators,syzstr, index,crit_comp,totake);
+        crit_comp = t_comp;
+        if (index==0)
+        {
+          isRegular = syIsRegular(old_std,syzstr->res[0],next_deg);
+#ifndef ONLY_STD
+          if (isRegular)
+            syCreateRegularExtension(syzstr,old_ideal,old_repr,old_tl,next_gen,
+                                     totake);
+#ifdef USE_REGULARITY
+        if ((index==0) && (!isRegular) && (i==last_generator))
+        {
+/*----------- we are computing the regularity -----------------------*/
+          ideal initial=id_Head(syzstr->res[0],currRing);
+          int len=0,reg=0;
+          intvec *w=NULL;
+          ring dp_C_ring = rAssure_dp_C(currRing); rChangeCurrRing(dp_C_ring);
+          initial = idrMoveR_NoSort(initial, syzstr->syRing, dp_C_ring);
+          resolvente res = sySchreyerResolvente(initial,-1,&len,TRUE, TRUE);
+          intvec * dummy = syBetti(res,len,&reg, w);
+          syzstr->regularity = reg+2;
+          delete dummy;
+          delete w;
+          for (j=0;j<len;j++)
+          {
+            if (res[j]!=NULL) idDelete(&(res[j]));
+          }
+          omFreeSize((ADDRESS)res,len*sizeof(ideal));
+          idDelete(&initial);
+          rChangeCurrRing(syzstr->syRing);
+          rDelete(dp_C_ring);
+        }
+#endif
+#endif
+          idDelete(&old_ideal);
+          idDelete(&old_repr);
+          idDelete(&old_std);
+          if (TEST_OPT_PROT)
+          {
+            if (isRegular)
+              PrintS("\n regular\n");
+            else
+              PrintS("\n not regular\n");
+          }
+          if (next_gen!=NULL)
+            pDelete(&next_gen);
+          if (isRegular)
+          {
+            idDelete(&temp_gens);
+            break;
+          }
+        }
+        idDelete(&new_generators);
+        new_generators = temp_gens;
+#ifdef ONLY_STD
+        break;
+#endif
+        if (idIs0(new_generators)) break;
+        index++;
+      }
+      if (!idIs0(new_generators))
+      {
+        for (j=0;j<IDELEMS(new_generators);j++)
+        {
+          if (new_generators->m[j]!=NULL)
+          {
+            pDelete(&new_generators->m[j]);
+            new_generators->m[j] = NULL;
+          }
+        }
+      }
+    }
+    i++;
+  }
+  if (idIs0(new_generators) && new_generators!=NULL) idDelete(&new_generators);
+  if (temp!=NULL) idDelete(&temp);
+  kBucketDestroy(&(syzstr->bucket));
+  kBucketDestroy(&(syzstr->syz_bucket));
+  index = 0;
+  syzstr->fullres = syzstr->res;
+  syzstr->res = NULL;
+  index = 0;
+  while ((index<=*length) && (syzstr->fullres[index]!=NULL))
+  {
+#ifdef SHOW_RESULT
+    Print("The %d-th syzygy-module is now:\n",index);
+    ideal ttt=id_Head(syzstr->fullres[index],currRing);
+    idShow(ttt);
+    idDelete(&ttt);
+    //if (index>0)
+    //{
+      //Print("The related module is: \n");
+      //idPrint(totake[index-1]);
+    //}
+    //Print("The %d-th module of the minimal resolution is:\n",index);
+    if (!idIs0(totake[index]))
+      idShow(totake[index]);
+    //Print("with standard basis:\n");
+    //idPrint(syzstr->fullres[index]);
+    //if ((index<*length) && (totake[index+1]!=NULL))
+    //{
+      //Print("The %d-th syzygy-module is now:\n",index+1);
+      //idPrint(totake[index+1]);
+      //matrix m1=idModule2Matrix(totake[index]);
+      //matrix m2=idModule2Matrix(totake[index+1]);
+      //matrix m3=mpMult(m1,m2);
+      //idPrint((ideal)m3);
+    //}
+#endif
+    if (!idIs0(totake[index]))
+    {
+      for(i=0;i<IDELEMS(totake[index]);i++)
+      {
+        if (totake[index]->m[i]!=NULL)
+        {
+          j=0;
+          while ((j<IDELEMS(syzstr->fullres[index])) &&
+            ((syzstr->fullres[index]->m[j]==NULL) ||
+            (!pLmEqual(syzstr->fullres[index]->m[j],totake[index]->m[i])))) j++;
+          if (j<IDELEMS(syzstr->fullres[index]))
+          {
+            pDelete(&totake[index]->m[i]);
+            totake[index]->m[i] = syzstr->fullres[index]->m[j];
+            syzstr->fullres[index]->m[j] = NULL;
+          }
+          else
+          {
+            PrintS("Da ist was faul!!!\n");
+            Print("Aber: Regularitaet %d, Grad %ld\n",
+		   syzstr->regularity,p_FDeg(totake[index]->m[i],currRing));
+          }
+        }
+      }
+      idDelete(&syzstr->fullres[index]);
+      syzstr->fullres[index] = totake[index];
+    }
+#ifdef SHOW_RESULT
+    idShow(syzstr->fullres[index]);
+#endif
+    index++;
+  }
+  syReorder_Kosz(syzstr);
+  index = 0;
+  while ((index<=*length) && (syzstr->orderedRes[index]!=NULL))
+  {
+    idDelete(&(syzstr->orderedRes[index]));
+    index++;
+  }
+  if (origR!=syzstr->syRing)
+  {
+    rChangeCurrRing(origR);
+    index = 0;
+    while ((index<=*length) && (syzstr->fullres[index]!=NULL))
+    {
+      syzstr->fullres[index] = idrMoveR(syzstr->fullres[index],syzstr->syRing, origR);
+      index++;
+    }
+  }
+  delete syzstr->Tl;
+  syzstr->Tl = NULL;
+  rDelete(syzstr->syRing);
+  syzstr->syRing = NULL;
+  omFreeSize((ADDRESS)totake,(*length+1)*sizeof(ideal));
+  omFreeSize((ADDRESS)syzstr->orderedRes,(*length+1)*sizeof(ideal));
+//Print("Pairs to discard: %d\n",discard_pairs);
+//Print("Pairs shorter reduced: %d\n",short_pairs);
+//discard_pairs = 0;
+//short_pairs = 0;
+  return syzstr;
+}
+
diff --git a/kernel/GBEngine/test.cc b/kernel/GBEngine/test.cc
new file mode 100644
index 0000000..76571de
--- /dev/null
+++ b/kernel/GBEngine/test.cc
@@ -0,0 +1,508 @@
+#include <kernel/mod2.h>
+
+#include <omalloc/omalloc.h>
+
+#include <resources/feFopen.h>
+#include <resources/feResource.h>
+
+#include <factory/factory.h> // :(
+
+#include <misc/auxiliary.h>
+#include <misc/intvec.h>
+#include <misc/int64vec.h>
+#include <misc/mylimits.h>
+#include <misc/options.h>
+
+#include <reporter/reporter.h>
+
+#include <coeffs/si_gmp.h>
+#include <coeffs/coeffs.h>
+#include <coeffs/numbers.h>
+
+#include <polys/kbuckets.h>
+#include <polys/matpol.h>
+#include <polys/mod_raw.h>
+#include <polys/prCopy.h>
+#include <polys/sbuckets.h>
+#include <polys/simpleideals.h>
+#include <polys/weight.h>
+#include <polys/monomials/maps.h>
+#include <polys/monomials/monomials.h>
+#include <polys/monomials/p_polys.h>
+#include <polys/monomials/ring.h>
+#include <polys/nc/nc.h>
+#include <polys/nc/ncSACache.h>
+#include <polys/nc/ncSAFormula.h>
+#include <polys/nc/ncSAMult.h>
+#include <polys/nc/sca.h>
+#include <polys/nc/summator.h>
+#include <polys/templates/p_MemAdd.h>
+#include <polys/templates/p_Procs.h>
+#include <polys/operations/pShallowCopyDelete.h>
+#include <polys/clapsing.h>
+
+
+// // TODO: DUE to the use of HALT in npolygon.cc :(((
+//extern "C" {void m2_end(int i){exit(i);}}
+
+// TODO: DUE to its use in kutil.cc :(((
+char * showOption(){return NULL;}
+
+#include <kernel/combinatorics/stairc.h>
+#include <kernel/GBEngine/syz.h>
+#include <kernel/GBEngine/khstd.h>
+#include <kernel/GBEngine/kstd1.h>
+#include <kernel/GBEngine/kstdfac.h>
+#include <kernel/GBEngine/units.h>
+#include <kernel/GBEngine/ratgring.h>
+#include <kernel/GBEngine/shiftgb.h>
+#include <kernel/GBEngine/kutil.h>
+#include <kernel/GBEngine/f5c.h>
+#include <kernel/GBEngine/f5data.h>
+#include <kernel/GBEngine/f5gb.h>
+#include <kernel/GBEngine/f5lists.h>
+#include <kernel/GBEngine/nc.h>
+#include <kernel/GBEngine/ratgring.h>
+#include <kernel/GBEngine/ringgb.h>
+#include <kernel/GBEngine/shiftgb.h>
+#include <kernel/GBEngine/syz.h>
+#include <kernel/GBEngine/tgbgauss.h>
+#include <kernel/GBEngine/tgb.h>
+#include <kernel/GBEngine/units.h>
+#include <kernel/GBEngine/janet.h>
+
+void TestGBEngine()
+{
+
+  //  R = MPolynomialRing_polydict(QQ,5,'w,x,y,z,C', order='degrevlex')
+  //  J = (w*w - x*z, w*x - y*z, x*x - w*y, x*y - z*z, y*y - w*z)
+
+  const short w = 1;
+  const short x = 2;
+  const short y = 3;
+  const short z = 4;
+
+  const short N = (z - w + 1);
+
+  char **n=(char**)omalloc(N*sizeof(char*));
+
+
+  n[w-1]=omStrDup("w");
+  n[x-1]=omStrDup("x");
+  n[y-1]=omStrDup("y");
+  n[z-1]=omStrDup("z");
+
+
+  const int D = 3;
+  int *order = (int *) omAlloc0(D* sizeof(int));
+  int *block0 = (int *)omAlloc0(D * sizeof(int));
+  int *block1 = (int *)omAlloc0(D * sizeof(int));
+
+  order[0]  = ringorder_dp;
+  block0[0] = 1;
+  block1[0] = N;
+
+  order[1]  = ringorder_C;
+  block0[1] = 1;
+  block1[1] = N;
+
+  ring R = rDefault(0, N, n, D, order, block0, block1);
+
+//   ring R = rDefault(0, N, n);
+
+  rWrite(R); PrintLn();
+
+#ifdef RDEBUG
+  rDebugPrint(R);
+#endif
+
+  ideal I = idInit(5, 1);
+
+  int gen = 0;
+
+  {
+    // -xz
+    poly p = p_ISet(-1,R);
+
+    p_SetExp(p, x, 1, R);
+    p_SetExp(p, z, 1, R);
+    p_Setm(p, R);
+
+    assume( p_GetExp(p, x, R) == 1 );
+    assume( p_GetExp(p, z, R) == 1 );
+    assume( p_GetExp(p, w, R) == 0 );
+    assume( p_GetExp(p, y, R) == 0 );
+
+    // +w2
+    poly lp = p_ISet(1,R);
+    p_SetExp(lp, w, 2, R);
+    p_Setm(lp, R);
+
+    assume( p_GetExp(lp, w, R) == 2 );
+    assume( p_GetExp(lp, x, R) == 0 );
+    assume( p_GetExp(lp, y, R) == 0 );
+    assume( p_GetExp(lp, z, R) == 0 );
+
+    MATELEM(I, 1, ++gen) = p_Add_q(lp, p, R); // w2 - xz
+  }
+
+  {
+    // -yz
+    poly p = p_ISet(-1,R);
+
+    p_SetExp(p, y, 1, R);
+    p_SetExp(p, z, 1, R);
+    p_Setm(p, R);
+
+    assume( p_GetExp(p, y, R) == 1 );
+    assume( p_GetExp(p, z, R) == 1 );
+    assume( p_GetExp(p, w, R) == 0 );
+    assume( p_GetExp(p, x, R) == 0 );
+
+    // +wx
+    poly lp = p_ISet(1,R);
+    p_SetExp(lp, w, 1, R);
+    p_SetExp(lp, x, 1, R);
+    p_Setm(lp, R);
+
+    assume( p_GetExp(lp, w, R) == 1 );
+    assume( p_GetExp(lp, x, R) == 1 );
+    assume( p_GetExp(lp, y, R) == 0 );
+    assume( p_GetExp(lp, z, R) == 0 );
+
+    MATELEM(I, 1, ++gen) = p_Add_q(lp, p, R); // wx - yz
+  }
+
+
+  {
+    // -wy
+    poly p = p_ISet(-1,R);
+
+    p_SetExp(p, y, 1, R);
+    p_SetExp(p, w, 1, R);
+    p_Setm(p, R);
+
+    assume( p_GetExp(p, y, R) == 1 );
+    assume( p_GetExp(p, w, R) == 1 );
+    assume( p_GetExp(p, z, R) == 0 );
+    assume( p_GetExp(p, x, R) == 0 );
+
+    // +x2
+    poly lp = p_ISet(1,R);
+    p_SetExp(lp, x, 2, R);
+    p_Setm(lp, R);
+
+    assume( p_GetExp(lp, w, R) == 0 );
+    assume( p_GetExp(lp, x, R) == 2 );
+    assume( p_GetExp(lp, y, R) == 0 );
+    assume( p_GetExp(lp, z, R) == 0 );
+
+    MATELEM(I, 1, ++gen) = p_Add_q(lp, p, R); // x2 - wy
+  }
+
+
+  {
+    // -z2
+    poly p = p_ISet(-1,R);
+
+    p_SetExp(p, z, 2, R);
+    p_Setm(p, R);
+
+    assume( p_GetExp(p, y, R) == 0 );
+    assume( p_GetExp(p, w, R) == 0 );
+    assume( p_GetExp(p, z, R) == 2 );
+    assume( p_GetExp(p, x, R) == 0 );
+
+    // +xy
+    poly lp = p_ISet(1,R);
+    p_SetExp(lp, x, 1, R);
+    p_SetExp(lp, y, 1, R);
+    p_Setm(lp, R);
+
+    assume( p_GetExp(lp, w, R) == 0 );
+    assume( p_GetExp(lp, x, R) == 1 );
+    assume( p_GetExp(lp, y, R) == 1 );
+    assume( p_GetExp(lp, z, R) == 0 );
+
+    MATELEM(I, 1, ++gen) = p_Add_q(lp, p, R); // xy - z2
+  }
+
+
+  {
+    // -wz
+    poly p = p_ISet(-1,R);
+
+    p_SetExp(p, w, 1, R);
+    p_SetExp(p, z, 1, R);
+    p_Setm(p, R);
+
+    assume( p_GetExp(p, y, R) == 0 );
+    assume( p_GetExp(p, w, R) == 1 );
+    assume( p_GetExp(p, z, R) == 1 );
+    assume( p_GetExp(p, x, R) == 0 );
+
+    // +y2
+    poly lp = p_ISet(1,R);
+    p_SetExp(lp, y, 2, R);
+    p_Setm(lp, R);
+
+    assume( p_GetExp(lp, w, R) == 0 );
+    assume( p_GetExp(lp, x, R) == 0 );
+    assume( p_GetExp(lp, y, R) == 2 );
+    assume( p_GetExp(lp, z, R) == 0 );
+
+    MATELEM(I, 1, ++gen) = p_Add_q(lp, p, R); // y2 - wz
+  }
+#ifdef PDEBUG
+  PrintS("I: ");
+  idShow(I, R, R, 0);
+#endif
+
+
+//  ideal kStd(ideal F, ideal Q, tHomog h, intvec ** mw,intvec *hilb=NULL,
+//             int syzComp=0,int newIdeal=0, intvec *vw=NULL);
+  // make R the default ring:
+  rChangeCurrRing(R);
+
+  {
+    ideal G = kStd(I, currRing->qideal, testHomog, NULL);
+
+#ifdef PDEBUG
+    PrintS("GB: ");
+    idShow(G, R, R, 0);
+#endif
+
+    idDelete( &G, R);
+  }
+
+  {
+    intvec *weights = NULL;
+    ideal SYZ = idSyzygies(I, testHomog, &weights);
+
+#ifdef PDEBUG
+    PrintS("SYZ: ");
+    idShow(SYZ, R, R, 0);
+#endif
+
+    idDelete(&SYZ, R);
+    if (weights!=NULL) { PrintS("weights: "); weights->show(); delete weights; }
+  }
+
+
+  {
+    PrintS("\n**********************************\n");
+    PrintS("lres: \n");
+    int dummy;
+    syStrategy r = syLaScala3(I,&dummy);
+
+    intvec *b = syBettiOfComputation(r, FALSE);
+    PrintS("non-min. betti: \n");    b->show();    PrintLn();
+    delete b;
+
+    Print("length: %d\n", sySize(r));
+
+    syPrint(r, "R");
+
+    r =  syMinimize(r); // syzstr->references ++ ==> memory leak :(((
+
+    b = syBettiOfComputation(r, TRUE);
+    PrintS("min. betti: \n");    b->show();    PrintLn();
+    delete b;
+
+    Print("length: %d\n", sySize(r));
+
+    syPrint(r, "R");
+
+    syKillComputation(r, R);
+  }
+
+  {
+    PrintS("\n**********************************\n");
+    PrintS("sres: \n");
+    const int maxl = rVar(R)-1; // +2*(1);
+
+    syStrategy r = sySchreyer(I, rVar(R));
+
+    intvec *b = syBettiOfComputation(r, FALSE);
+    PrintS("non-min. betti: \n");    b->show();    PrintLn();
+    delete b;
+
+    Print("length: %d\n", sySize(r));
+
+    syPrint(r, "R");
+
+    r =  syMinimize(r); // syzstr->references ++ ==> memory leak :(((
+
+    b = syBettiOfComputation(r, TRUE);
+    PrintS("min. betti: \n");    b->show();    PrintLn();
+    delete b;
+
+    Print("length: %d\n", sySize(r));
+
+    syPrint(r, "R");
+
+    syKillComputation(r, R);
+  }
+
+
+
+  {
+    PrintS("\n**********************************\n");
+    PrintS("nres: \n");
+    intvec *weights=NULL;
+//    const int maxl = rVar(R)-1 + 2*(1);
+    syStrategy r = syResolution(I, rVar(R)-1, weights, FALSE/*iiOp==MRES_CMD*/);
+
+    intvec *b = syBettiOfComputation(r, FALSE);
+    PrintS("non-min. betti: \n");    b->show();    PrintLn();
+    delete b;
+
+    Print("length: %d\n", sySize(r));
+
+    syPrint(r, "R");
+
+    r =  syMinimize(r); // syzstr->references ++ ==> memory leak :(((
+
+    b = syBettiOfComputation(r, TRUE);
+    PrintS("min. betti: \n");    b->show();    PrintLn();
+    delete b;
+
+    Print("length: %d\n", sySize(r));
+
+    syPrint(r, "R");
+
+    syKillComputation(r, R);
+  }
+
+
+  {
+    PrintS("\n**********************************\n");
+    PrintS("mres: \n");
+    intvec *weights=NULL;
+//    const int maxl = rVar(R)-1 + 2*(1);
+    syStrategy r = syResolution(I, rVar(R)+1, weights, TRUE/*iiOp==MRES_CMD*/);
+
+    intvec *b = syBettiOfComputation(r, FALSE);
+    PrintS("non-min. betti: \n");    b->show();    PrintLn();
+    delete b;
+
+    Print("length: %d\n", sySize(r));
+
+    syPrint(r, "R");
+
+    r =  syMinimize(r); // syzstr->references ++ ==> memory leak :(((
+
+    b = syBettiOfComputation(r, TRUE);
+    PrintS("min. betti: \n");    b->show();    PrintLn();
+    delete b;
+
+    Print("length: %d\n", sySize(r));
+
+    syPrint(r, "R");
+
+    syKillComputation(r, R);
+  }
+
+
+
+
+  idDelete( &I, R);
+  rDelete(R); // should cleanup every belonging polynomial, right!?
+
+}
+
+
+
+void TestSimpleRingArithmetcs()
+{
+  // Libpolys tests:
+
+  // construct the ring Z/32003[x,y,z]
+  // the variable names
+  char **n=(char**)omalloc(3*sizeof(char*));
+  n[0]=omStrDup("x");
+  n[1]=omStrDup("y");
+  n[2]=omStrDup("z2");
+
+  ring R = rDefault(32003,3,n); //  ring R = rDefault(0,3,n);
+
+  rWrite(R); PrintLn();
+
+#ifdef RDEBUG
+  rDebugPrint(R);
+#endif
+
+
+  poly p = p_ISet(1,R); p_SetExp(p,1,1, R); p_Setm(p, R);
+
+  assume( p_GetExp(p,1, R) == 1 );
+
+  poly pp = pp_Mult_qq( p, p, R);
+
+  Print("p: "); p_Write0(p, R); Print(", deg(p): %ld", p_Totaldegree(p, R)); assume( 1 == p_Totaldegree(p, R) );
+
+  Print("; p*p : "); p_Write0(pp, R); Print("deg(pp): %ld\n", p_Totaldegree(pp, R)); assume( 2 == p_Totaldegree(pp, R) );
+
+
+  p_Delete(&p, R);
+
+  assume( p_GetExp(pp,1, R) == 2 );
+
+  p_Delete(&pp, R);
+
+
+//  rDelete(R);
+
+  // make R the default ring:
+  rChangeCurrRing(R);
+
+  // create the polynomial 1
+  poly p1=pISet(1);
+
+  // create tthe polynomial 2*x^3*z^2
+  poly p2=p_ISet(2,R);
+  pSetExp(p2,1,3);
+  pSetExp(p2,3,2);
+  pSetm(p2);
+
+  // print p1 + p2
+  Print("p1: "); pWrite0(p1);
+  Print(" + p2: "); pWrite0(p2);
+  Print("  ---- >>>> ");
+
+  // compute p1+p2
+  p1=p_Add_q(p1,p2,R); p2=NULL;
+  pWrite(p1);
+
+  // clean up:
+//  pDelete(&p1);
+
+  rDelete(R); // should cleanup every belonging polynomial, right!?
+}
+
+
+int main( int, char *argv[] )
+{
+  assume( sizeof(long) == SIZEOF_LONG );
+
+  if( sizeof(long) != SIZEOF_LONG )
+  {
+    WerrorS("Bad config.h: wrong size of long!");
+
+    return(1);
+  }
+
+
+  feInitResources(argv[0]);
+
+  StringSetS("ressources in use (as reported by feStringAppendResources(0):\n");
+  feStringAppendResources(0);
+
+  PrintLn();
+  { char* s = StringEndS(); PrintS(s); omFree(s); }
+
+  TestGBEngine();
+  TestSimpleRingArithmetcs();
+
+  return 0;
+}
diff --git a/kernel/GBEngine/tgb.cc b/kernel/GBEngine/tgb.cc
new file mode 100644
index 0000000..a1dd02a
--- /dev/null
+++ b/kernel/GBEngine/tgb.cc
@@ -0,0 +1,5198 @@
+//! \file tgb.cc
+//       multiple rings
+//       shorten_tails und dessen Aufrufe pruefen wlength!!!
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: slimgb and F4 implementation
+*/
+//#include <vector>
+//using namespace std;
+
+///@TODO: delay nur auf Sugarvergr?erung
+///@TODO: grade aus ecartS, setze dazu strat->honey; und nutze p.ecart
+///@TODO: no tail reductions in syz comp
+#include <kernel/mod2.h>
+
+#include <kernel/GBEngine/tgb.h>
+#include <kernel/GBEngine/tgb_internal.h>
+#include <kernel/GBEngine/tgbgauss.h>
+
+#include <misc/options.h>
+#include <kernel/digitech.h>
+#include <polys/nc/nc.h>
+#include <polys/nc/sca.h>
+#include <polys/prCopy.h>
+
+#include <coeffs/longrat.h> // nlQlogSize
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <queue>
+
+#define BUCKETS_FOR_NORO_RED 1
+#define SR_HDL(A) ((long)(A))
+static const int bundle_size = 100;
+static const int bundle_size_noro = 10000;
+static const int delay_factor = 3;
+#define ADD_LATER_SIZE 500
+#if 1
+static omBin lm_bin = NULL;
+static int add_to_reductors(slimgb_alg* c, poly h, int len, int ecart, BOOLEAN simplified=FALSE);
+static void multi_reduction(red_object* los, int & losl, slimgb_alg* c);
+static void multi_reduce_step(find_erg & erg, red_object* r, slimgb_alg* c);
+static BOOLEAN extended_product_criterion(poly p1, poly gcd1, poly p2, poly gcd2, slimgb_alg* c);
+static poly gcd_of_terms(poly p, ring r);
+static int tgb_pair_better_gen(const void* ap,const void* bp);
+static BOOLEAN pair_better(sorted_pair_node* a,sorted_pair_node* b, slimgb_alg* c=NULL);
+static BOOLEAN state_is(calc_state state, const int & i, const int & j, slimgb_alg* c);
+static void super_clean_top_of_pair_list(slimgb_alg* c);
+static int simple_posInS (kStrategy strat, poly p,int len, wlen_type wlen);
+static int* make_connections(int from, int to, poly bound, slimgb_alg* c);
+static BOOLEAN has_t_rep(const int & arg_i, const int & arg_j, slimgb_alg* state);
+static void shorten_tails(slimgb_alg* c, poly monom);
+static poly redNF2 (poly h,slimgb_alg* c , int &len, number&  m,int n=0);
+static poly redNFTail (poly h,const int sl,kStrategy strat, int len);
+static int bucket_guess(kBucket* bucket);
+
+static void simplify_poly (poly p, ring r)
+{
+  assume (r == currRing);
+  if(!rField_is_Zp (r))
+  {
+    p_Cleardenom (p, r);
+    //p_Content(p,r); //is a duplicate call, but belongs here
+  }
+  else
+    pNorm (p);
+}
+
+//static const BOOLEAN up_to_radical=TRUE;
+
+int slim_nsize (number n, ring r)
+{
+  if(rField_is_Zp (r))
+  {
+    return 1;
+  }
+  if(rField_is_Q (r))
+  {
+    return nlQlogSize (n, r->cf);
+  }
+  else
+  {
+    return n_Size (n, r);
+  }
+}
+
+static BOOLEAN monomial_root (poly m, ring r)
+{
+  BOOLEAN changed = FALSE;
+  int i;
+  for(i = 1; i <= rVar (r); i++)
+  {
+    int e = p_GetExp (m, i, r);
+    if(e > 1)
+    {
+      p_SetExp (m, i, 1, r);
+      changed = TRUE;
+    }
+  }
+  if(changed)
+  {
+    p_Setm (m, r);
+  }
+  return changed;
+}
+
+static BOOLEAN polynomial_root (poly h, ring r)
+{
+  poly got = gcd_of_terms (h, r);
+  BOOLEAN changed = FALSE;
+  if((got != NULL) && (TEST_V_UPTORADICAL))
+  {
+    poly copy = p_Copy (got, r);
+    //p_wrp(got,c->r);
+    changed = monomial_root (got, r);
+    if(changed)
+    {
+      poly div_by = pDivide (copy, got);
+      poly iter = h;
+      while(iter)
+      {
+        pExpVectorSub (iter, div_by);
+        pIter (iter);
+      }
+      p_Delete (&div_by, r);
+      if(TEST_OPT_PROT)
+        PrintS ("U");
+    }
+    p_Delete (&copy, r);
+  }
+  p_Delete (&got, r);
+  return changed;
+}
+
+static inline poly p_Init_Special (const ring r)
+{
+  return p_Init (r, lm_bin);
+}
+
+static inline poly pOne_Special (const ring r = currRing)
+{
+  poly rc = p_Init_Special (r);
+  pSetCoeff0 (rc, n_Init (1, r));
+  return rc;
+}
+
+// zum Initialiseren: in t_rep_gb plazieren:
+
+#endif
+#define LEN_VAR3
+#define degbound(p) assume(pTotaldegree(p)<10)
+//#define inDebug(p) assume((debug_Ideal==NULL)||(kNF(debug_Ideal,NULL,p,0,0)==0))
+
+//die meisten Varianten stossen sich an coef_buckets
+
+#ifdef LEN_VAR1
+// erste Variante: Laenge: Anzahl der Monome
+static inline int pSLength (poly p, int l)
+{
+  return l;
+}
+
+static inline int kSBucketLength (kBucket * bucket, poly lm)
+{
+  return bucket_guess (bucket);
+}
+#endif
+
+#ifdef LEN_VAR2
+// 2. Variante: Laenge: Platz fuer die Koeff.
+int pSLength (poly p, int l)
+{
+  int s = 0;
+  while(p != NULL)
+  {
+    s += nSize (pGetCoeff (p));
+    pIter (p);
+  }
+  return s;
+}
+
+int kSBucketLength (kBucket * b, poly lm)
+{
+  int s = 0;
+  int i;
+  for(i = MAX_BUCKET; i >= 0; i--)
+  {
+    s += pSLength (b->buckets[i], 0);
+  }
+  return s;
+}
+#endif
+
+#ifdef LEN_VAR3
+static inline wlen_type pSLength (poly p, int l)
+{
+  wlen_type c;
+  number coef = pGetCoeff (p);
+  if(rField_is_Q (currRing))
+  {
+    c = nlQlogSize (coef, currRing->cf);
+  }
+  else
+    c = nSize (coef);
+  if(!(TEST_V_COEFSTRAT))
+  {
+    return (wlen_type) c *(wlen_type) l /*pLength(p) */ ;
+  }
+  else
+  {
+    wlen_type res = l;
+    res *= c;
+    res *= c;
+    return res;
+  }
+}
+
+//! TODO CoefBuckets bercksichtigen
+wlen_type kSBucketLength (kBucket * b, poly lm = NULL)
+{
+  int s = 0;
+  wlen_type c;
+  number coef;
+  if(lm == NULL)
+    coef = pGetCoeff (kBucketGetLm (b));
+  //c=nSize(pGetCoeff(kBucketGetLm(b)));
+  else
+    coef = pGetCoeff (lm);
+  //c=nSize(pGetCoeff(lm));
+  if(rField_is_Q (currRing))
+  {
+    c = nlQlogSize (coef, currRing->cf);
+  }
+  else
+    c = nSize (coef);
+
+  int i;
+  for(i = b->buckets_used; i >= 0; i--)
+  {
+    assume ((b->buckets_length[i] == 0) || (b->buckets[i] != NULL));
+    s += b->buckets_length[i] /*pLength(b->buckets[i]) */ ;
+  }
+#ifdef HAVE_COEF_BUCKETS
+  assume (b->buckets[0] == kBucketGetLm (b));
+  if(b->coef[0] != NULL)
+  {
+    if(rField_is_Q (currRing))
+    {
+      int modifier = nlQlogSize (pGetCoeff (b->coef[0]), currRing->cf);
+      c += modifier;
+    }
+    else
+    {
+      int modifier = nSize (pGetCoeff (b->coef[0]));
+      c *= modifier;
+    }
+  }
+#endif
+  if(!(TEST_V_COEFSTRAT))
+  {
+    return s * c;
+  }
+  else
+  {
+    wlen_type res = s;
+    res *= c;
+    res *= c;
+    return res;
+  }
+}
+#endif
+#ifdef LEN_VAR5
+static inline wlen_type pSLength (poly p, int l)
+{
+  int c;
+  number coef = pGetCoeff (p);
+  if(rField_is_Q (currRing))
+  {
+    c = nlQlogSize (coef, currRing->cf);
+  }
+  else
+    c = nSize (coef);
+  wlen_type erg = l;
+  erg *= c;
+  erg *= c;
+  //PrintS("lenvar 5");
+  assume (erg >= 0);
+  return erg; /*pLength(p) */ ;
+}
+
+//! TODO CoefBuckets bercksichtigen
+wlen_type kSBucketLength (kBucket * b, poly lm = NULL)
+{
+  wlen_type s = 0;
+  int c;
+  number coef;
+  if(lm == NULL)
+    coef = pGetCoeff (kBucketGetLm (b));
+  //c=nSize(pGetCoeff(kBucketGetLm(b)));
+  else
+    coef = pGetCoeff (lm);
+  //c=nSize(pGetCoeff(lm));
+  if(rField_is_Q (currRing))
+  {
+    c = nlQlogSize (coef, currRing->cf);
+  }
+  else
+    c = nSize (coef);
+
+  int i;
+  for(i = b->buckets_used; i >= 0; i--)
+  {
+    assume ((b->buckets_length[i] == 0) || (b->buckets[i] != NULL));
+    s += b->buckets_length[i] /*pLength(b->buckets[i]) */ ;
+  }
+#ifdef HAVE_COEF_BUCKETS
+  assume (b->buckets[0] == kBucketGetLm (b));
+  if(b->coef[0] != NULL)
+  {
+    if(rField_is_Q (currRing))
+    {
+      int modifier = nlQlogSize (pGetCoeff (b->coef[0]), currRing->cf);
+      c += modifier;
+    }
+    else
+    {
+      int modifier = nSize (pGetCoeff (b->coef[0]));
+      c *= modifier;
+    }
+  }
+#endif
+  wlen_type erg = s;
+  erg *= c;
+  erg *= c;
+  return erg;
+}
+#endif
+
+#ifdef LEN_VAR4
+// 4.Variante: Laenge: Platz fuer Leitk * (1+Platz fuer andere Koeff.)
+int pSLength (poly p, int l)
+{
+  int s = 1;
+  int c = nSize (pGetCoeff (p));
+  pIter (p);
+  while(p != NULL)
+  {
+    s += nSize (pGetCoeff (p));
+    pIter (p);
+  }
+  return s * c;
+}
+
+int kSBucketLength (kBucket * b)
+{
+  int s = 1;
+  int c = nSize (pGetCoeff (kBucketGetLm (b)));
+  int i;
+  for(i = MAX_BUCKET; i > 0; i--)
+  {
+    if(b->buckets[i] == NULL)
+      continue;
+    s += pSLength (b->buckets[i], 0);
+  }
+  return s * c;
+}
+#endif
+//BUG/TODO this stuff will fail on internal Schreyer orderings
+static BOOLEAN elength_is_normal_length (poly p, slimgb_alg * c)
+{
+  ring r = c->r;
+  if(p_GetComp (p, r) != 0)
+    return FALSE;
+  if(c->lastDpBlockStart <= (currRing->N))
+  {
+    int i;
+    for(i = 1; i < c->lastDpBlockStart; i++)
+    {
+      if(p_GetExp (p, i, r) != 0)
+      {
+        break;
+      }
+    }
+    if(i >= c->lastDpBlockStart)
+    {
+      //wrp(p);
+      //PrintS("\n");
+      return TRUE;
+    }
+    else
+      return FALSE;
+  }
+  else
+    return FALSE;
+}
+
+static BOOLEAN lies_in_last_dp_block (poly p, slimgb_alg * c)
+{
+  ring r = c->r;
+  if(p_GetComp (p, r) != 0)
+    return FALSE;
+  if(c->lastDpBlockStart <= (currRing->N))
+  {
+    int i;
+    for(i = 1; i < c->lastDpBlockStart; i++)
+    {
+      if(p_GetExp (p, i, r) != 0)
+      {
+        break;
+      }
+    }
+    if(i >= c->lastDpBlockStart)
+    {
+      //wrp(p);
+      //PrintS("\n");
+      return TRUE;
+    }
+    else
+      return FALSE;
+  }
+  else
+    return FALSE;
+}
+
+static int get_last_dp_block_start (ring r)
+{
+  //ring r=c->r;
+  int last_block;
+
+  if(rRing_has_CompLastBlock (r))
+  {
+    last_block = rBlocks (r) - 3;
+  }
+  else
+  {
+    last_block = rBlocks (r) - 2;
+  }
+  assume (last_block >= 0);
+  if(r->order[last_block] == ringorder_dp)
+    return r->block0[last_block];
+  return (currRing->N) + 1;
+}
+
+static wlen_type do_pELength (poly p, slimgb_alg * c, int dlm = -1)
+{
+  if(p == NULL)
+    return 0;
+  wlen_type s = 0;
+  poly pi = p;
+  if(dlm < 0)
+  {
+    dlm = c->pTotaldegree (p);
+    s = 1;
+    pi = p->next;
+  }
+
+  while(pi)
+  {
+    int d = c->pTotaldegree (pi);
+    if(d > dlm)
+      s += 1 + d - dlm;
+    else
+      ++s;
+    pi = pi->next;
+  }
+  return s;
+}
+
+wlen_type pELength (poly p, slimgb_alg * c, ring /*r*/)
+{
+  if(p == NULL)
+    return 0;
+  wlen_type s = 0;
+  poly pi = p;
+  int dlm;
+  dlm = c->pTotaldegree (p);
+  s = 1;
+  pi = p->next;
+
+  while(pi)
+  {
+    int d = c->pTotaldegree (pi);
+    if(d > dlm)
+      s += 1 + d - dlm;
+    else
+      ++s;
+    pi = pi->next;
+  }
+  return s;
+}
+
+wlen_type kEBucketLength (kBucket * b, poly lm, slimgb_alg * ca)
+{
+  wlen_type s = 0;
+  if(lm == NULL)
+  {
+    lm = kBucketGetLm (b);
+  }
+  if(lm == NULL)
+    return 0;
+  if(elength_is_normal_length (lm, ca))
+  {
+    return bucket_guess (b);
+  }
+  int d = ca->pTotaldegree (lm);
+#if 0
+  assume (sugar >= d);
+  s = 1 + (bucket_guess (b) - 1) * (sugar - d + 1);
+  return s;
+#else
+
+  //int d=pTotaldegree(lm,ca->r);
+  int i;
+  for(i = b->buckets_used; i >= 0; i--)
+  {
+    if(b->buckets[i] == NULL)
+      continue;
+
+    if((ca->pTotaldegree (b->buckets[i]) <= d)
+       && (elength_is_normal_length (b->buckets[i], ca)))
+    {
+      s += b->buckets_length[i];
+    }
+    else
+    {
+      s += do_pELength (b->buckets[i], ca, d);
+    }
+  }
+  return s;
+#endif
+}
+
+static inline int pELength (poly p, slimgb_alg * c, int l)
+{
+  if(p == NULL)
+    return 0;
+  if((l > 0) && (elength_is_normal_length (p, c)))
+    return l;
+  return do_pELength (p, c);
+}
+
+static inline wlen_type pQuality (poly p, slimgb_alg * c, int l = -1)
+{
+  if(l < 0)
+    l = pLength (p);
+  if(c->isDifficultField)
+  {
+    if(c->eliminationProblem)
+    {
+      wlen_type cs;
+      number coef = pGetCoeff (p);
+      if(rField_is_Q (currRing))
+      {
+        cs = nlQlogSize (coef, currRing->cf);
+      }
+      else
+        cs = nSize (coef);
+      wlen_type erg = cs;
+      if(TEST_V_COEFSTRAT)
+        erg *= cs;
+      //erg*=cs;//for quadratic
+      erg *= pELength (p, c, l);
+      //FIXME: not quadratic coeff size
+      //return cs*pELength(p,c,l);
+      return erg;
+    }
+    //PrintS("I am here");
+    wlen_type r = pSLength (p, l);
+    assume (r >= 0);
+    return r;
+  }
+  if(c->eliminationProblem)
+    return pELength (p, c, l);
+  return l;
+}
+
+static inline int pTotaldegree_full (poly p)
+{
+  int r = 0;
+  while(p)
+  {
+    int d = pTotaldegree (p);
+    r = si_max (r, d);
+    pIter (p);
+  }
+  return r;
+}
+
+wlen_type red_object::guess_quality (slimgb_alg * c)
+{
+  //works at the moment only for lenvar 1, because in different
+  //case, you have to look on coefs
+  wlen_type s = 0;
+  if(c->isDifficultField)
+  {
+    //s=kSBucketLength(bucket,this->p);
+    if(c->eliminationProblem)
+    {
+      wlen_type cs;
+      number coef;
+
+      coef = pGetCoeff (kBucketGetLm (bucket));
+      //c=nSize(pGetCoeff(kBucketGetLm(b)));
+
+      //c=nSize(pGetCoeff(lm));
+      if(rField_is_Q (currRing))
+      {
+        cs = nlQlogSize (coef, currRing->cf);
+      }
+      else
+        cs = nSize (coef);
+#ifdef HAVE_COEF_BUCKETS
+      if(bucket->coef[0] != NULL)
+      {
+        if(rField_is_Q (currRing))
+        {
+          int modifier = nlQlogSize (pGetCoeff (bucket->coef[0]), currRing->cf);
+          cs += modifier;
+        }
+        else
+        {
+          int modifier = nSize (pGetCoeff (bucket->coef[0]));
+          cs *= modifier;
+        }
+      }
+#endif
+      //FIXME:not quadratic
+      wlen_type erg = kEBucketLength (this->bucket, this->p, c);
+      //erg*=cs;//for quadratic
+      erg *= cs;
+      if(TEST_V_COEFSTRAT)
+        erg *= cs;
+      //return cs*kEBucketLength(this->bucket,this->p,c);
+      return erg;
+    }
+    s = kSBucketLength (bucket, NULL);
+  }
+  else
+  {
+    if(c->eliminationProblem)
+      //if (false)
+      s = kEBucketLength (this->bucket, this->p, c);
+    else
+      s = bucket_guess (bucket);
+  }
+  return s;
+}
+
+#if 0                           //currently unused
+static void finalize_reduction_step (reduction_step * r)
+{
+  delete r;
+}
+#endif
+#if 0                           //currently unused
+static int LObject_better_gen (const void *ap, const void *bp)
+{
+  LObject *a = *(LObject **) ap;
+  LObject *b = *(LObject **) bp;
+  return (pLmCmp (a->p, b->p));
+}
+#endif
+static int red_object_better_gen (const void *ap, const void *bp)
+{
+  return (pLmCmp (((red_object *) ap)->p, ((red_object *) bp)->p));
+}
+
+#if 0                           //currently unused
+static int pLmCmp_func_inverted (const void *ap1, const void *ap2)
+{
+  poly p1, p2;
+  p1 = *((poly *) ap1);
+  p2 = *((poly *) ap2);
+  return -pLmCmp (p1, p2);
+}
+#endif
+
+int tgb_pair_better_gen2 (const void *ap, const void *bp)
+{
+  return (-tgb_pair_better_gen (ap, bp));
+}
+
+int kFindDivisibleByInS_easy (kStrategy strat, const red_object & obj)
+{
+  int i;
+  long not_sev = ~obj.sev;
+  poly p = obj.p;
+  for(i = 0; i <= strat->sl; i++)
+  {
+    if(pLmShortDivisibleBy (strat->S[i], strat->sevS[i], p, not_sev))
+      return i;
+  }
+  return -1;
+}
+
+int kFindDivisibleByInS_easy (kStrategy strat, poly p, long sev)
+{
+  int i;
+  long not_sev = ~sev;
+  for(i = 0; i <= strat->sl; i++)
+  {
+    if(pLmShortDivisibleBy (strat->S[i], strat->sevS[i], p, not_sev))
+      return i;
+  }
+  return -1;
+}
+
+static int
+posInPairs (sorted_pair_node ** p, int pn, sorted_pair_node * qe,
+            slimgb_alg * c, int an = 0)
+{
+  if(pn == 0)
+    return 0;
+
+  int length = pn - 1;
+  int i;
+  //int an = 0;
+  int en = length;
+
+  if(pair_better (qe, p[en], c))
+    return length + 1;
+
+  while(1)
+  {
+    //if (an >= en-1)
+    if(en - 1 <= an)
+    {
+      if(pair_better (p[an], qe, c))
+        return an;
+      return en;
+    }
+    i = (an + en) / 2;
+    if(pair_better (p[i], qe, c))
+      en = i;
+    else
+      an = i;
+  }
+}
+
+static BOOLEAN ascending (int *i, int top)
+{
+  if(top < 1)
+    return TRUE;
+  if(i[top] < i[top - 1])
+    return FALSE;
+  return ascending (i, top - 1);
+}
+
+sorted_pair_node **spn_merge (sorted_pair_node ** p, int pn,
+                              sorted_pair_node ** q, int qn, slimgb_alg * c)
+{
+  int i;
+  int *a = (int *) omalloc (qn * sizeof (int));
+//   int mc;
+//   PrintS("Debug\n");
+//   for(mc=0;mc<qn;mc++)
+// {
+//     wrp(q[mc]->lcm_of_lm);
+//     PrintS("\n");
+// }
+//    PrintS("Debug they are in\n");
+//   for(mc=0;mc<pn;mc++)
+// {
+//     wrp(p[mc]->lcm_of_lm);
+//     PrintS("\n");
+// }
+  int lastpos = 0;
+  for(i = 0; i < qn; i++)
+  {
+    lastpos = posInPairs (p, pn, q[i], c, si_max (lastpos - 1, 0));
+    //   cout<<lastpos<<"\n";
+    a[i] = lastpos;
+  }
+  if((pn + qn) > c->max_pairs)
+  {
+    p =
+      (sorted_pair_node **) omrealloc (p,
+                                       2 * (pn +
+                                            qn) *
+                                       sizeof (sorted_pair_node *));
+    c->max_pairs = 2 * (pn + qn);
+  }
+  for(i = qn - 1; i >= 0; i--)
+  {
+    size_t size;
+    if(qn - 1 > i)
+      size = (a[i + 1] - a[i]) * sizeof (sorted_pair_node *);
+    else
+      size = (pn - a[i]) * sizeof (sorted_pair_node *); //as indices begin with 0
+    memmove (p + a[i] + (1 + i), p + a[i], size);
+    p[a[i] + i] = q[i];
+  }
+  omfree (a);
+  return p;
+}
+
+static BOOLEAN
+trivial_syzygie (int pos1, int pos2, poly bound, slimgb_alg * c)
+{
+  poly p1 = c->S->m[pos1];
+  poly p2 = c->S->m[pos2];
+
+  if(pGetComp (p1) > 0 || pGetComp (p2) > 0)
+    return FALSE;
+  int i = 1;
+  poly m = NULL;
+  poly gcd1 = c->gcd_of_terms[pos1];
+  poly gcd2 = c->gcd_of_terms[pos2];
+
+  if((gcd1 != NULL) && (gcd2 != NULL))
+  {
+    gcd1->next = gcd2;          //may ordered incorrect
+    m = gcd_of_terms (gcd1, c->r);
+    gcd1->next = NULL;
+  }
+  if(m == NULL)
+  {
+    loop
+    {
+      if(pGetExp (p1, i) + pGetExp (p2, i) > pGetExp (bound, i))
+        return FALSE;
+      if(i == (currRing->N))
+      {
+        //PrintS("trivial");
+        return TRUE;
+      }
+      i++;
+    }
+  }
+  else
+  {
+    loop
+    {
+      if(pGetExp (p1, i) - pGetExp (m, i) + pGetExp (p2, i) >
+         pGetExp (bound, i))
+      {
+        pDelete (&m);
+        return FALSE;
+      }
+      if(i == (currRing->N))
+      {
+        pDelete (&m);
+        //PrintS("trivial");
+        return TRUE;
+      }
+      i++;
+    }
+  }
+}
+
+//! returns position sets w as weight
+int find_best (red_object * r, int l, int u, wlen_type & w, slimgb_alg * c)
+{
+  int best = l;
+  int i;
+  w = r[l].guess_quality (c);
+  for(i = l + 1; i <= u; i++)
+  {
+    wlen_type w2 = r[i].guess_quality (c);
+    if(w2 < w)
+    {
+      w = w2;
+      best = i;
+    }
+  }
+  return best;
+}
+
+void red_object::canonicalize ()
+{
+  kBucketCanonicalize (bucket);
+}
+
+BOOLEAN good_has_t_rep (int i, int j, slimgb_alg * c)
+{
+  assume (i >= 0);
+  assume (j >= 0);
+  if(has_t_rep (i, j, c))
+    return TRUE;
+  //poly lm=pOne();
+  assume (c->tmp_lm != NULL);
+  poly lm = c->tmp_lm;
+
+  pLcm (c->S->m[i], c->S->m[j], lm);
+  pSetm (lm);
+  assume (lm != NULL);
+  //int deciding_deg= pTotaldegree(lm);
+  int *i_con = make_connections (i, j, lm, c);
+  //p_Delete(&lm,c->r);
+
+  for(int n = 0; ((n < c->n) && (i_con[n] >= 0)); n++)
+  {
+    if(i_con[n] == j)
+    {
+      now_t_rep (i, j, c);
+      omFree (i_con);
+      return TRUE;
+    }
+  }
+  omfree (i_con);
+
+  return FALSE;
+}
+
+BOOLEAN lenS_correct (kStrategy strat)
+{
+  int i;
+  for(i = 0; i <= strat->sl; i++)
+  {
+    if(strat->lenS[i] != pLength (strat->S[i]))
+      return FALSE;
+  }
+  return TRUE;
+}
+
+
+static void cleanS (kStrategy strat, slimgb_alg * c)
+{
+  int i = 0;
+  LObject P;
+  while(i <= strat->sl)
+  {
+    P.p = strat->S[i];
+    P.sev = strat->sevS[i];
+    //int dummy=strat->sl;
+    //if(kFindDivisibleByInS(strat,&dummy,&P)!=i)
+    if(kFindDivisibleByInS_easy (strat, P.p, P.sev) != i)
+    {
+      deleteInS (i, strat);
+      //remember destroying poly
+      BOOLEAN found = FALSE;
+      int j;
+      for(j = 0; j < c->n; j++)
+      {
+        if(c->S->m[j] == P.p)
+        {
+          found = TRUE;
+          break;
+        }
+      }
+      if(!found)
+        pDelete (&P.p);
+      //remember additional reductors
+    }
+    else
+      i++;
+  }
+}
+
+static int bucket_guess (kBucket * bucket)
+{
+  int sum = 0;
+  int i;
+  for(i = bucket->buckets_used; i >= 0; i--)
+  {
+    if(bucket->buckets[i])
+      sum += bucket->buckets_length[i];
+  }
+  return sum;
+}
+
+static int
+add_to_reductors (slimgb_alg * c, poly h, int len, int ecart,
+                  BOOLEAN simplified)
+{
+  //inDebug(h);
+  assume (lenS_correct (c->strat));
+  assume (len == pLength (h));
+  int i;
+//   if (c->isDifficultField)
+//        i=simple_posInS(c->strat,h,pSLength(h,len),c->isDifficultField);
+//   else
+//     i=simple_posInS(c->strat,h,len,c->isDifficultField);
+
+  LObject P;
+  memset (&P, 0, sizeof (P));
+  P.tailRing = c->r;
+  P.p = h;                      /*p_Copy(h,c->r); */
+  P.ecart = ecart;
+  P.FDeg = c->r->pFDeg (P.p, c->r);
+  if(!(simplified))
+  {
+    if(!rField_is_Zp (c->r))
+    {
+      p_Cleardenom (P.p, c->r);
+      //p_Content(P.p,c->r ); //is a duplicate call, but belongs here
+
+    }
+    else
+      pNorm (P.p);
+    pNormalize (P.p);
+  }
+  wlen_type pq = pQuality (h, c, len);
+  i = simple_posInS (c->strat, h, len, pq);
+  c->strat->enterS (P, i, c->strat, -1);
+
+  c->strat->lenS[i] = len;
+  assume (pLength (c->strat->S[i]) == c->strat->lenS[i]);
+  if(c->strat->lenSw != NULL)
+    c->strat->lenSw[i] = pq;
+
+  return i;
+}
+
+static void length_one_crit (slimgb_alg * c, int pos, int len)
+{
+  if(c->nc)
+    return;
+  if(len == 1)
+  {
+    int i;
+    for(i = 0; i < pos; i++)
+    {
+      if(c->lengths[i] == 1)
+        c->states[pos][i] = HASTREP;
+    }
+    for(i = pos + 1; i < c->n; i++)
+    {
+      if(c->lengths[i] == 1)
+        c->states[i][pos] = HASTREP;
+    }
+    if(!c->nc)
+      shorten_tails (c, c->S->m[pos]);
+  }
+}
+
+static void move_forward_in_S (int old_pos, int new_pos, kStrategy strat)
+{
+  assume (old_pos >= new_pos);
+  poly p = strat->S[old_pos];
+  int ecart = strat->ecartS[old_pos];
+  long sev = strat->sevS[old_pos];
+  int s_2_r = strat->S_2_R[old_pos];
+  int length = strat->lenS[old_pos];
+  assume (length == pLength (strat->S[old_pos]));
+  wlen_type length_w;
+  if(strat->lenSw != NULL)
+    length_w = strat->lenSw[old_pos];
+  int i;
+  for(i = old_pos; i > new_pos; i--)
+  {
+    strat->S[i] = strat->S[i - 1];
+    strat->ecartS[i] = strat->ecartS[i - 1];
+    strat->sevS[i] = strat->sevS[i - 1];
+    strat->S_2_R[i] = strat->S_2_R[i - 1];
+  }
+  if(strat->lenS != NULL)
+    for(i = old_pos; i > new_pos; i--)
+      strat->lenS[i] = strat->lenS[i - 1];
+  if(strat->lenSw != NULL)
+    for(i = old_pos; i > new_pos; i--)
+      strat->lenSw[i] = strat->lenSw[i - 1];
+
+  strat->S[new_pos] = p;
+  strat->ecartS[new_pos] = ecart;
+  strat->sevS[new_pos] = sev;
+  strat->S_2_R[new_pos] = s_2_r;
+  strat->lenS[new_pos] = length;
+  if(strat->lenSw != NULL)
+    strat->lenSw[new_pos] = length_w;
+  //assume(lenS_correct(strat));
+}
+
+static void move_backward_in_S (int old_pos, int new_pos, kStrategy strat)
+{
+  assume (old_pos <= new_pos);
+  poly p = strat->S[old_pos];
+  int ecart = strat->ecartS[old_pos];
+  long sev = strat->sevS[old_pos];
+  int s_2_r = strat->S_2_R[old_pos];
+  int length = strat->lenS[old_pos];
+  assume (length == pLength (strat->S[old_pos]));
+  wlen_type length_w;
+  if(strat->lenSw != NULL)
+    length_w = strat->lenSw[old_pos];
+  int i;
+  for(i = old_pos; i < new_pos; i++)
+  {
+    strat->S[i] = strat->S[i + 1];
+    strat->ecartS[i] = strat->ecartS[i + 1];
+    strat->sevS[i] = strat->sevS[i + 1];
+    strat->S_2_R[i] = strat->S_2_R[i + 1];
+  }
+  if(strat->lenS != NULL)
+    for(i = old_pos; i < new_pos; i++)
+      strat->lenS[i] = strat->lenS[i + 1];
+  if(strat->lenSw != NULL)
+    for(i = old_pos; i < new_pos; i++)
+      strat->lenSw[i] = strat->lenSw[i + 1];
+
+  strat->S[new_pos] = p;
+  strat->ecartS[new_pos] = ecart;
+  strat->sevS[new_pos] = sev;
+  strat->S_2_R[new_pos] = s_2_r;
+  strat->lenS[new_pos] = length;
+  if(strat->lenSw != NULL)
+    strat->lenSw[new_pos] = length_w;
+  //assume(lenS_correct(strat));
+}
+
+static int *make_connections (int from, int to, poly bound, slimgb_alg * c)
+{
+  ideal I = c->S;
+  int *cans = (int *) omAlloc (c->n * sizeof (int));
+  int *connected = (int *) omAlloc (c->n * sizeof (int));
+  cans[0] = to;
+  int cans_length = 1;
+  connected[0] = from;
+  int last_cans_pos = -1;
+  int connected_length = 1;
+  long neg_bounds_short = ~p_GetShortExpVector (bound, c->r);
+
+  int not_yet_found = cans_length;
+  int con_checked = 0;
+  int pos;
+
+  while(TRUE)
+  {
+    if((con_checked < connected_length) && (not_yet_found > 0))
+    {
+      pos = connected[con_checked];
+      for(int i = 0; i < cans_length; i++)
+      {
+        if(cans[i] < 0)
+          continue;
+        //FIXME: triv. syz. does not hold on noncommutative, check it for modules
+        if((has_t_rep (pos, cans[i], c))
+           || ((!rIsPluralRing (c->r))
+               && (trivial_syzygie (pos, cans[i], bound, c))))
+        {
+          connected[connected_length] = cans[i];
+          connected_length++;
+          cans[i] = -1;
+          --not_yet_found;
+
+          if(connected[connected_length - 1] == to)
+          {
+            if(connected_length < c->n)
+            {
+              connected[connected_length] = -1;
+            }
+            omFree (cans);
+            return connected;
+          }
+        }
+      }
+      con_checked++;
+    }
+    else
+    {
+      for(last_cans_pos++; last_cans_pos <= c->n; last_cans_pos++)
+      {
+        if(last_cans_pos == c->n)
+        {
+          if(connected_length < c->n)
+          {
+            connected[connected_length] = -1;
+          }
+          omfree (cans);
+          return connected;
+        }
+        if((last_cans_pos == from) || (last_cans_pos == to))
+          continue;
+        if(p_LmShortDivisibleBy
+           (I->m[last_cans_pos], c->short_Exps[last_cans_pos], bound,
+            neg_bounds_short, c->r))
+        {
+          cans[cans_length] = last_cans_pos;
+          cans_length++;
+          break;
+        }
+      }
+      not_yet_found++;
+      for(int i = 0; i < con_checked; i++)
+      {
+        if(has_t_rep (connected[i], last_cans_pos, c))
+        {
+          connected[connected_length] = last_cans_pos;
+          connected_length++;
+          cans[cans_length - 1] = -1;
+          --not_yet_found;
+          if(connected[connected_length - 1] == to)
+          {
+            if(connected_length < c->n)
+            {
+              connected[connected_length] = -1;
+            }
+            omFree (cans);
+            return connected;
+          }
+          break;
+        }
+      }
+    }
+  }
+  if(connected_length < c->n)
+  {
+    connected[connected_length] = -1;
+  }
+  omfree (cans);
+  return connected;
+}
+
+#ifdef HEAD_BIN
+static inline poly p_MoveHead (poly p, omBin b)
+{
+  poly np;
+  omTypeAllocBin (poly, np, b);
+  memmove (np, p, omSizeWOfBin(b) * sizeof (long));
+  omFreeBinAddr (p);
+  return np;
+}
+#endif
+
+static void replace_pair (int &i, int &j, slimgb_alg * c)
+{
+  if(i < 0)
+    return;
+  c->soon_free = NULL;
+  int syz_deg;
+  poly lm = pOne ();
+
+  pLcm (c->S->m[i], c->S->m[j], lm);
+  pSetm (lm);
+
+  int *i_con = make_connections (i, j, lm, c);
+
+  for(int n = 0; ((n < c->n) && (i_con[n] >= 0)); n++)
+  {
+    if(i_con[n] == j)
+    {
+      now_t_rep (i, j, c);
+      omFree (i_con);
+      p_Delete (&lm, c->r);
+      return;
+    }
+  }
+
+  int *j_con = make_connections (j, i, lm, c);
+
+//   if(c->n>1)
+//   {
+//     if (i_con[1]>=0)
+//       i=i_con[1];
+//     else
+//     {
+//       if (j_con[1]>=0)
+//         j=j_con[1];
+//     }
+  // }
+
+  int sugar = syz_deg = c->pTotaldegree (lm);
+
+  p_Delete (&lm, c->r);
+  if(c->T_deg_full)             //Sugar
+  {
+    int t_i = c->T_deg_full[i] - c->T_deg[i];
+    int t_j = c->T_deg_full[j] - c->T_deg[j];
+    sugar += si_max (t_i, t_j);
+    //Print("\n max: %d\n",max(t_i,t_j));
+  }
+
+  for(int m = 0; ((m < c->n) && (i_con[m] >= 0)); m++)
+  {
+    if(c->T_deg_full != NULL)
+    {
+      int s1 = c->T_deg_full[i_con[m]] + syz_deg - c->T_deg[i_con[m]];
+      if(s1 > sugar)
+        continue;
+    }
+    if(c->weighted_lengths[i_con[m]] < c->weighted_lengths[i])
+      i = i_con[m];
+  }
+  for(int m = 0; ((m < c->n) && (j_con[m] >= 0)); m++)
+  {
+    if(c->T_deg_full != NULL)
+    {
+      int s1 = c->T_deg_full[j_con[m]] + syz_deg - c->T_deg[j_con[m]];
+      if(s1 > sugar)
+        continue;
+    }
+    if(c->weighted_lengths[j_con[m]] < c->weighted_lengths[j])
+      j = j_con[m];
+  }
+
+  //can also try dependend search
+  omfree (i_con);
+  omfree (j_con);
+  return;
+}
+
+static void add_later (poly p, const char *prot, slimgb_alg * c)
+{
+  int i = 0;
+  //check, if it is already in the queue
+
+  while(c->add_later->m[i] != NULL)
+  {
+    if(p_LmEqual (c->add_later->m[i], p, c->r))
+      return;
+    i++;
+  }
+  if(TEST_OPT_PROT)
+    PrintS (prot);
+  c->add_later->m[i] = p;
+}
+
+static int simple_posInS (kStrategy strat, poly p, int len, wlen_type wlen)
+{
+  if(strat->sl == -1)
+    return 0;
+  if(strat->lenSw)
+    return pos_helper (strat, p, (wlen_type) wlen, (wlen_set) strat->lenSw,
+                       strat->S);
+  return pos_helper (strat, p, len, strat->lenS, strat->S);
+}
+
+/*2
+ *if the leading term of p
+ *divides the leading term of some S[i] it will be canceled
+ */
+static inline void
+clearS (poly p, unsigned long p_sev, int l, int *at, int *k, kStrategy strat)
+{
+  assume (p_sev == pGetShortExpVector (p));
+  if(!pLmShortDivisibleBy (p, p_sev, strat->S[*at], ~strat->sevS[*at]))
+    return;
+  if(l >= strat->lenS[*at])
+    return;
+  if(TEST_OPT_PROT)
+    PrintS ("!");
+  mflush ();
+  //pDelete(&strat->S[*at]);
+  deleteInS ((*at), strat);
+  (*at)--;
+  (*k)--;
+//  assume(lenS_correct(strat));
+}
+
+static int iq_crit (const void *ap, const void *bp)
+{
+  sorted_pair_node *a = *((sorted_pair_node **) ap);
+  sorted_pair_node *b = *((sorted_pair_node **) bp);
+  assume (a->i > a->j);
+  assume (b->i > b->j);
+
+  if(a->deg < b->deg)
+    return -1;
+  if(a->deg > b->deg)
+    return 1;
+  int comp = pLmCmp (a->lcm_of_lm, b->lcm_of_lm);
+  if(comp != 0)
+    return comp;
+  if(a->expected_length < b->expected_length)
+    return -1;
+  if(a->expected_length > b->expected_length)
+    return 1;
+  if(a->j > b->j)
+    return 1;
+  if(a->j < b->j)
+    return -1;
+  return 0;
+}
+
+static wlen_type coeff_mult_size_estimate (int s1, int s2, ring r)
+{
+  if(rField_is_Q (r))
+    return s1 + s2;
+  else
+    return s1 * s2;
+}
+
+static wlen_type pair_weighted_length (int i, int j, slimgb_alg * c)
+{
+  if((c->isDifficultField) && (c->eliminationProblem))
+  {
+    int c1 = slim_nsize (p_GetCoeff (c->S->m[i], c->r), c->r);
+    int c2 = slim_nsize (p_GetCoeff (c->S->m[j], c->r), c->r);
+    wlen_type el1 = c->weighted_lengths[i] / c1;
+    assume (el1 != 0);
+    assume (c->weighted_lengths[i] % c1 == 0);
+    wlen_type el2 = c->weighted_lengths[j] / c2;
+    assume (el2 != 0);
+    //assume (c->weighted_lengths[j] % c2 == 0); // fails in Tst/Plural/dmod_lib.tst
+    //should be * for function fields
+    //return (c1+c2) * (el1+el2-2);
+    wlen_type res = coeff_mult_size_estimate (c1, c2, c->r);
+    res *= el1 + el2 - 2;
+    return res;
+
+  }
+  if(c->isDifficultField)
+  {
+    //int cs=slim_nsize(p_GetCoeff(c->S->m[i],c->r),c->r)+
+    //    slim_nsize(p_GetCoeff(c->S->m[j],c->r),c->r);
+    if(!(TEST_V_COEFSTRAT))
+    {
+      wlen_type cs =
+        coeff_mult_size_estimate (slim_nsize
+                                  (p_GetCoeff (c->S->m[i], c->r), c->r),
+                                  slim_nsize (p_GetCoeff (c->S->m[j], c->r),
+                                              c->r), c->r);
+      return (wlen_type) (c->lengths[i] + c->lengths[j] - 2) * (wlen_type) cs;
+    }
+    else
+    {
+
+      wlen_type cs =
+        coeff_mult_size_estimate (slim_nsize
+                                  (p_GetCoeff (c->S->m[i], c->r), c->r),
+                                  slim_nsize (p_GetCoeff (c->S->m[j], c->r),
+                                              c->r), c->r);
+      cs *= cs;
+      return (wlen_type) (c->lengths[i] + c->lengths[j] - 2) * (wlen_type) cs;
+    }
+  }
+  if(c->eliminationProblem)
+  {
+
+    return (c->weighted_lengths[i] + c->weighted_lengths[j] - 2);
+  }
+  return c->lengths[i] + c->lengths[j] - 2;
+
+}
+
+sorted_pair_node **add_to_basis_ideal_quotient (poly h, slimgb_alg * c,
+                                                int *ip)
+{
+  p_Test (h, c->r);
+  assume (h != NULL);
+  poly got = gcd_of_terms (h, c->r);
+  if((got != NULL) && (TEST_V_UPTORADICAL))
+  {
+    poly copy = p_Copy (got, c->r);
+    //p_wrp(got,c->r);
+    BOOLEAN changed = monomial_root (got, c->r);
+    if(changed)
+    {
+      poly div_by = pDivide (copy, got);
+      poly iter = h;
+      while(iter)
+      {
+        pExpVectorSub (iter, div_by);
+        pIter (iter);
+      }
+      p_Delete (&div_by, c->r);
+      PrintS ("U");
+    }
+    p_Delete (&copy, c->r);
+  }
+
+#define ENLARGE(pointer, type) pointer=(type*) omrealloc(pointer, c->array_lengths*sizeof(type))
+
+#define ENLARGE_ALIGN(pointer, type) {if(pointer)\
+         pointer=(type*)omReallocAligned(pointer, c->array_lengths*sizeof(type));\
+         else pointer=(type*)omAllocAligned(c->array_lengths*sizeof(type));}
+//  BOOLEAN corr=lenS_correct(c->strat);
+  int sugar;
+  int ecart = 0;
+  ++(c->n);
+  ++(c->S->ncols);
+  int i, j;
+  i = c->n - 1;
+  sorted_pair_node **nodes =
+    (sorted_pair_node **) omalloc (sizeof (sorted_pair_node *) * i);
+  int spc = 0;
+  if(c->n > c->array_lengths)
+  {
+    c->array_lengths = c->array_lengths * 2;
+    assume (c->array_lengths >= c->n);
+    ENLARGE (c->T_deg, int);
+    ENLARGE_ALIGN (c->tmp_pair_lm, poly);
+    ENLARGE_ALIGN (c->tmp_spn, sorted_pair_node *);
+
+    ENLARGE_ALIGN (c->short_Exps, long);
+    ENLARGE (c->lengths, int);
+#ifndef HAVE_BOOST
+#ifndef USE_STDVECBOOL
+
+    ENLARGE_ALIGN (c->states, char *);
+#endif
+#endif
+    ENLARGE_ALIGN (c->gcd_of_terms, poly);
+    //if (c->weighted_lengths!=NULL) {
+    ENLARGE_ALIGN (c->weighted_lengths, wlen_type);
+    //}
+    //ENLARGE_ALIGN(c->S->m,poly);
+  }
+  pEnlargeSet (&c->S->m, c->n - 1, 1);
+  if(c->T_deg_full)
+    ENLARGE (c->T_deg_full, int);
+  sugar = c->T_deg[i] = c->pTotaldegree (h);
+  if(c->T_deg_full)
+  {
+    sugar = c->T_deg_full[i] = c->pTotaldegree_full (h);
+    ecart = sugar - c->T_deg[i];
+    assume (ecart >= 0);
+  }
+  c->tmp_pair_lm[i] = pOne_Special (c->r);
+
+  c->tmp_spn[i] = (sorted_pair_node *) omAlloc (sizeof (sorted_pair_node));
+
+  c->lengths[i] = pLength (h);
+
+  //necessary for correct weighted length
+
+  if(!rField_is_Zp (c->r))
+  {
+    p_Cleardenom (h, c->r);
+    //p_Content(h,c->r); //is a duplicate call, but belongs here
+  }
+  else
+    pNorm (h);
+  pNormalize (h);
+
+  c->weighted_lengths[i] = pQuality (h, c, c->lengths[i]);
+  c->gcd_of_terms[i] = got;
+#ifdef HAVE_BOOST
+  c->states.push_back (dynamic_bitset <> (i));
+
+#else
+#ifdef USE_STDVECBOOL
+
+  c->states.push_back (vector < bool > (i));
+
+#else
+  if(i > 0)
+    c->states[i] = (char *) omAlloc (i * sizeof (char));
+  else
+    c->states[i] = NULL;
+#endif
+#endif
+
+  c->S->m[i] = h;
+  c->short_Exps[i] = p_GetShortExpVector (h, c->r);
+
+#undef ENLARGE
+#undef ENLARGE_ALIGN
+  if(p_GetComp (h, currRing) <= c->syz_comp)
+  {
+    for(j = 0; j < i; j++)
+    {
+
+
+#ifndef HAVE_BOOST
+      c->states[i][j] = UNCALCULATED;
+#endif
+      assume (p_LmDivisibleBy (c->S->m[i], c->S->m[j], c->r) ==
+              p_LmShortDivisibleBy (c->S->m[i], c->short_Exps[i], c->S->m[j],
+                                    ~(c->short_Exps[j]), c->r));
+
+      if(__p_GetComp (c->S->m[i], c->r) != __p_GetComp (c->S->m[j], c->r))
+      {
+        //c->states[i][j]=UNCALCULATED;
+        //WARNUNG: be careful
+        continue;
+      }
+      else if((!c->nc) && (c->lengths[i] == 1) && (c->lengths[j] == 1))
+      {
+        c->states[i][j] = HASTREP;
+      }
+      else if(((!c->nc) || (c->is_homog && rIsSCA (c->r)))
+              && (pHasNotCF (c->S->m[i], c->S->m[j])))
+//     else if ((!(c->nc)) &&  (pHasNotCF(c->S->m[i],c->S->m[j])))
+      {
+        c->easy_product_crit++;
+        c->states[i][j] = HASTREP;
+        continue;
+      }
+      else
+        if(extended_product_criterion
+           (c->S->m[i], c->gcd_of_terms[i], c->S->m[j], c->gcd_of_terms[j],
+            c))
+      {
+        c->states[i][j] = HASTREP;
+        c->extended_product_crit++;
+        //PrintS("E");
+      }
+      //  if (c->states[i][j]==UNCALCULATED)
+      //  {
+
+      if((TEST_V_FINDMONOM) && (!c->nc))
+      {
+        //PrintS("COMMU");
+        //  if (c->lengths[i]==c->lengths[j])
+        //  {
+//             poly short_s=ksCreateShortSpoly(c->S->m[i],c->S->m[j],c->r);
+//             if (short_s==NULL)
+//             {
+//                 c->states[i][j]=HASTREP;
+//             }
+//             else
+//             {
+//                 p_Delete(&short_s, currRing);
+//             }
+//         }
+        if(c->lengths[i] + c->lengths[j] == 3)
+        {
+
+
+          poly short_s = ksCreateShortSpoly (c->S->m[i], c->S->m[j], c->r);
+          if(short_s == NULL)
+          {
+            c->states[i][j] = HASTREP;
+          }
+          else
+          {
+            assume (pLength (short_s) == 1);
+            if(TEST_V_UPTORADICAL)
+              monomial_root (short_s, c->r);
+            int iS = kFindDivisibleByInS_easy (c->strat, short_s,
+                                               p_GetShortExpVector (short_s,
+                                                                    c->r));
+            if(iS < 0)
+            {
+              //PrintS("N");
+              if(TRUE)
+              {
+                c->states[i][j] = HASTREP;
+                add_later (short_s, "N", c);
+              }
+              else
+                p_Delete (&short_s, currRing);
+            }
+            else
+            {
+              if(c->strat->lenS[iS] > 1)
+              {
+                //PrintS("O");
+                if(TRUE)
+                {
+                  c->states[i][j] = HASTREP;
+                  add_later (short_s, "O", c);
+                }
+                else
+                  p_Delete (&short_s, currRing);
+              }
+              else
+                p_Delete (&short_s, currRing);
+              c->states[i][j] = HASTREP;
+            }
+
+
+          }
+        }
+      }
+      //    if (short_s)
+      //    {
+      assume (spc <= j);
+      sorted_pair_node *s = c->tmp_spn[spc];    //(sorted_pair_node*) omalloc(sizeof(sorted_pair_node));
+      s->i = si_max (i, j);
+      s->j = si_min (i, j);
+      assume (s->j == j);
+      s->expected_length = pair_weighted_length (i, j, c);      //c->lengths[i]+c->lengths[j]-2;
+
+      poly lm = c->tmp_pair_lm[spc];    //=pOne_Special();
+
+      pLcm (c->S->m[i], c->S->m[j], lm);
+      pSetm (lm);
+      p_Test (lm, c->r);
+      s->deg = c->pTotaldegree (lm);
+
+      if(c->T_deg_full)         //Sugar
+      {
+        int t_i = c->T_deg_full[s->i] - c->T_deg[s->i];
+        int t_j = c->T_deg_full[s->j] - c->T_deg[s->j];
+        s->deg += si_max (t_i, t_j);
+        //Print("\n max: %d\n",max(t_i,t_j));
+      }
+      p_Test (lm, c->r);
+      s->lcm_of_lm = lm;
+      //          pDelete(&short_s);
+      //assume(lm!=NULL);
+      nodes[spc] = s;
+      spc++;
+
+      // }
+      //else
+      //{
+      //c->states[i][j]=HASTREP;
+      //}
+    }
+  }                             //if syz_comp end
+
+  assume (spc <= i);
+  //now ideal quotient crit
+  qsort (nodes, spc, sizeof (sorted_pair_node *), iq_crit);
+
+  sorted_pair_node **nodes_final =
+    (sorted_pair_node **) omalloc (sizeof (sorted_pair_node *) * i);
+  int spc_final = 0;
+  j = 0;
+  while(j < spc)
+  {
+    int lower = j;
+    int upper;
+    BOOLEAN has = FALSE;
+    for(upper = lower + 1; upper < spc; upper++)
+    {
+      if(!pLmEqual (nodes[lower]->lcm_of_lm, nodes[upper]->lcm_of_lm))
+      {
+        break;
+      }
+      if(has_t_rep (nodes[upper]->i, nodes[upper]->j, c))
+        has = TRUE;
+    }
+    upper = upper - 1;
+    int z;
+    assume (spc_final <= j);
+    for(z = 0; z < spc_final; z++)
+    {
+      if(p_LmDivisibleBy
+         (nodes_final[z]->lcm_of_lm, nodes[lower]->lcm_of_lm, c->r))
+      {
+        has = TRUE;
+        break;
+      }
+    }
+
+    if(has)
+    {
+      for(; lower <= upper; lower++)
+      {
+        //free_sorted_pair_node(nodes[lower],c->r);
+        //omfree(nodes[lower]);
+        nodes[lower] = NULL;
+      }
+      j = upper + 1;
+      continue;
+    }
+    else
+    {
+      p_Test (nodes[lower]->lcm_of_lm, c->r);
+      nodes[lower]->lcm_of_lm = pCopy (nodes[lower]->lcm_of_lm);
+      assume (__p_GetComp (c->S->m[nodes[lower]->i], c->r) ==
+              __p_GetComp (c->S->m[nodes[lower]->j], c->r));
+      nodes_final[spc_final] =
+        (sorted_pair_node *) omAlloc (sizeof (sorted_pair_node));
+
+      *(nodes_final[spc_final++]) = *(nodes[lower]);
+      //c->tmp_spn[nodes[lower]->j]=(sorted_pair_node*) omalloc(sizeof(sorted_pair_node));
+      nodes[lower] = NULL;
+      for(lower = lower + 1; lower <= upper; lower++)
+      {
+        //  free_sorted_pair_node(nodes[lower],c->r);
+        //omfree(nodes[lower]);
+        nodes[lower] = NULL;
+      }
+      j = upper + 1;
+      continue;
+    }
+  }
+
+  //  Print("i:%d,spc_final:%d",i,spc_final);
+
+  assume (spc_final <= spc);
+  omfree (nodes);
+  nodes = NULL;
+
+  add_to_reductors (c, h, c->lengths[c->n - 1], ecart, TRUE);
+  //i=posInS(c->strat,c->strat->sl,h,0 ecart);
+  if(!(c->nc))
+  {
+    if(c->lengths[c->n - 1] == 1)
+      shorten_tails (c, c->S->m[c->n - 1]);
+  }
+  //you should really update c->lengths, c->strat->lenS, and the oder of polys in strat if you sort after lengths
+
+  //for(i=c->strat->sl; i>0;i--)
+  //  if(c->strat->lenS[i]<c->strat->lenS[i-1]) printf("fehler bei %d\n",i);
+  if(c->Rcounter > 50)
+  {
+    c->Rcounter = 0;
+    cleanS (c->strat, c);
+  }
+
+#ifdef HAVE_PLURAL
+  // for SCA:
+  // here write at the end of nodes_final[spc_final,...,spc_final+lmdeg-1]
+  if(rIsSCA (c->r))
+  {
+    const poly pNext = pNext (h);
+
+    if(pNext != NULL)
+    {
+      // for additional polynomials
+      const unsigned int m_iFirstAltVar = scaFirstAltVar (c->r);
+      const unsigned int m_iLastAltVar = scaLastAltVar (c->r);
+
+      int N =                   // c->r->N;
+        m_iLastAltVar - m_iFirstAltVar + 1;     // should be enough
+      // TODO: but we may also use got = gcd({m}_{m\in f}))!
+
+      poly *array_arg = (poly *) omalloc (N * sizeof (poly));   // !
+      int j = 0;
+
+
+      for(unsigned short v = m_iFirstAltVar; v <= m_iLastAltVar; v++)
+        // for all x_v | Ann(lm(h))
+        if(p_GetExp (h, v, c->r))       // TODO: use 'got' here!
+        {
+          assume (p_GetExp (h, v, c->r) == 1);
+
+          poly p = sca_pp_Mult_xi_pp (v, pNext, c->r);  // x_v * h;
+
+          if(p != NULL)         // if (x_v * h != 0)
+            array_arg[j++] = p;
+        }                       // for all x_v | Ann(lm(h))
+
+      c->introduceDelayedPairs (array_arg, j);
+
+      omFree (array_arg);       // !!!
+    }
+//     PrintS("Saturation - done!!!\n");
+  }
+#endif // if SCAlgebra
+
+
+  if(!ip)
+  {
+    qsort (nodes_final, spc_final, sizeof (sorted_pair_node *),
+           tgb_pair_better_gen2);
+
+
+    c->apairs =
+      spn_merge (c->apairs, c->pair_top + 1, nodes_final, spc_final, c);
+    c->pair_top += spc_final;
+    clean_top_of_pair_list (c);
+    omfree (nodes_final);
+    return NULL;
+  }
+  {
+    *ip = spc_final;
+    return nodes_final;
+  }
+}
+
+static poly redNF2 (poly h, slimgb_alg * c, int &len, number & m, int n)
+{
+  m = nInit (1);
+  if(h == NULL)
+    return NULL;
+
+  assume (len == pLength (h));
+  kStrategy strat = c->strat;
+  if(0 > strat->sl)
+  {
+    return h;
+  }
+  int j;
+
+  LObject P (h);
+  P.SetShortExpVector ();
+  P.bucket = kBucketCreate (currRing);
+  // BOOLEAN corr=lenS_correct(strat);
+  kBucketInit (P.bucket, P.p, len /*pLength(P.p) */ );
+  //wlen_set lenSw=(wlen_set) c->strat->lenS;
+  //FIXME: plainly wrong
+  //strat->lenS;
+  //if (strat->lenSw!=NULL)
+  //  lenSw=strat->lenSw;
+  //int max_pos=simple_posInS(strat,P.p);
+  loop
+  {
+    //int dummy=strat->sl;
+    j = kFindDivisibleByInS_easy (strat, P.p, P.sev);
+    //j=kFindDivisibleByInS(strat,&dummy,&P);
+    if((j >= 0) && ((!n) ||
+                    ((strat->lenS[j] <= n) &&
+                     ((strat->lenSw == NULL) || (strat->lenSw[j] <= n)))))
+    {
+      nNormalize (pGetCoeff (P.p));
+#ifdef KDEBUG
+      if(TEST_OPT_DEBUG)
+      {
+        PrintS ("red:");
+        wrp (h);
+        PrintS (" with ");
+        wrp (strat->S[j]);
+      }
+#endif
+
+      number coef = kBucketPolyRed (P.bucket, strat->S[j],
+                                    strat->lenS[j] /*pLength(strat->S[j]) */ ,
+                                    strat->kNoether);
+      number m2 = nMult (m, coef);
+      nDelete (&m);
+      m = m2;
+      nDelete (&coef);
+      h = kBucketGetLm (P.bucket);
+
+      if(h == NULL)
+      {
+        len = 0;
+        kBucketDestroy (&P.bucket);
+        return NULL;
+      }
+      P.p = h;
+      P.t_p = NULL;
+      P.SetShortExpVector ();
+#ifdef KDEBUG
+      if(TEST_OPT_DEBUG)
+      {
+        PrintS ("\nto:");
+        wrp (h);
+        PrintLn ();
+      }
+#endif
+    }
+    else
+    {
+      kBucketClear (P.bucket, &(P.p), &len);
+      kBucketDestroy (&P.bucket);
+      pNormalize (P.p);
+      assume (len == (pLength (P.p)));
+      return P.p;
+    }
+  }
+}
+
+static poly redTailShort (poly h, kStrategy strat)
+{
+  if(h == NULL)
+    return NULL;                //n_Init(1,currRing);
+  if(TEST_V_MODPSOLVSB)
+  {
+    bit_reduce (pNext (h), strat->tailRing);
+  }
+  int i;
+  int len = pLength (h);
+  for(i = 0; i <= strat->sl; i++)
+  {
+    if((strat->lenS[i] > 2)
+       || ((strat->lenSw != NULL) && (strat->lenSw[i] > 2)))
+      break;
+  }
+  return (redNFTail (h, i - 1, strat, len));
+}
+
+static void line_of_extended_prod (int fixpos, slimgb_alg * c)
+{
+  if(c->gcd_of_terms[fixpos] == NULL)
+  {
+    c->gcd_of_terms[fixpos] = gcd_of_terms (c->S->m[fixpos], c->r);
+    if(c->gcd_of_terms[fixpos])
+    {
+      int i;
+      for(i = 0; i < fixpos; i++)
+        if((c->states[fixpos][i] != HASTREP)
+           &&
+           (extended_product_criterion
+            (c->S->m[fixpos], c->gcd_of_terms[fixpos], c->S->m[i],
+             c->gcd_of_terms[i], c)))
+        {
+          c->states[fixpos][i] = HASTREP;
+          c->extended_product_crit++;
+        }
+      for(i = fixpos + 1; i < c->n; i++)
+        if((c->states[i][fixpos] != HASTREP)
+           &&
+           (extended_product_criterion
+            (c->S->m[fixpos], c->gcd_of_terms[fixpos], c->S->m[i],
+             c->gcd_of_terms[i], c)))
+        {
+          c->states[i][fixpos] = HASTREP;
+          c->extended_product_crit++;
+        }
+    }
+  }
+}
+
+static void c_S_element_changed_hook (int pos, slimgb_alg * c)
+{
+  length_one_crit (c, pos, c->lengths[pos]);
+  if(!c->nc)
+    line_of_extended_prod (pos, c);
+}
+
+class poly_tree_node
+{
+public:
+  poly p;
+  poly_tree_node *l;
+  poly_tree_node *r;
+  int n;
+  poly_tree_node (int sn):l (NULL), r (NULL), n (sn)
+  {
+  }
+};
+class exp_number_builder
+{
+public:
+  poly_tree_node * top_level;
+  int n;
+  int get_n (poly p);
+  exp_number_builder ():top_level (0), n (0)
+  {
+  }
+};
+int exp_number_builder::get_n (poly p)
+{
+  poly_tree_node **node = &top_level;
+  while(*node != NULL)
+  {
+    int c = pLmCmp (p, (*node)->p);
+    if(c == 0)
+      return (*node)->n;
+    if(c == -1)
+      node = &((*node)->r);
+    else
+      node = &((*node)->l);
+  }
+  (*node) = new poly_tree_node (n);
+  n++;
+  (*node)->p = pLmInit (p);
+  return (*node)->n;
+}
+
+//mac_polys exp are smaller iff they are greater by monomial ordering
+//corresponding to solving linear equations notation
+
+//! obsolete
+struct int_poly_pair
+{
+  poly p;
+  int n;
+};
+
+
+//! obsolete
+void t2ippa_rec (poly * ip, int *ia, poly_tree_node * k, int &offset)
+{
+  if(!k)
+    return;
+  t2ippa_rec (ip, ia, k->l, offset);
+  ip[offset] = k->p;
+  ia[k->n] = offset;
+  ++offset;
+
+  t2ippa_rec (ip, ia, k->r, offset);
+  delete k;
+}
+
+//! obsolete
+void t2ippa (poly * ip, int *ia, exp_number_builder & e)
+{
+
+  int o = 0;
+  t2ippa_rec (ip, ia, e.top_level, o);
+}
+
+int anti_poly_order (const void *a, const void *b)
+{
+  return -pLmCmp (((int_poly_pair *) a)->p, ((int_poly_pair *) b)->p);
+}
+
+BOOLEAN is_valid_ro (red_object & ro)
+{
+  red_object r2 = ro;
+  ro.validate ();
+  if((r2.p != ro.p) || (r2.sev != ro.sev))
+    return FALSE;
+  return TRUE;
+}
+
+int terms_sort_crit (const void *a, const void *b)
+{
+  return -pLmCmp (*((poly *) a), *((poly *) b));
+}
+
+#if 0                           // currently unused
+static void unify_terms (poly * terms, int &sum)
+{
+  if(sum == 0)
+    return;
+  int last = 0;
+  int curr = 1;
+  while(curr < sum)
+  {
+    if(!(pLmEqual (terms[curr], terms[last])))
+    {
+      terms[++last] = terms[curr];
+    }
+    ++curr;
+  }
+  sum = last + 1;
+}
+#endif
+#if 0                           // currently unused
+static void
+export_mat (number * number_array, int pn, int tn, const char *format_str,
+            int mat_nr)
+{
+  char matname[20];
+  sprintf (matname, format_str, mat_nr);
+  FILE *out = fopen (matname, "w");
+  int i, j;
+  fprintf (out, "mat=[\n");
+  for(i = 0; i < pn; i++)
+  {
+    fprintf (out, "[\n");
+    for(j = 0; j < tn; j++)
+    {
+      if(j > 0)
+      {
+        fprintf (out, ", ");
+      }
+      fprintf (out, "%i", npInt (number_array[i * tn + j], currRing));
+    }
+    if(i < pn - 1)
+      fprintf (out, "],\n");
+    else
+      fprintf (out, "],\n");
+  }
+  fprintf (out, "]\n");
+  fclose (out);
+}
+#endif
+//typedef unsigned short number_type;
+
+
+#ifdef USE_NORO
+#ifndef NORO_CACHE
+static void
+linalg_step_modp (poly * p, poly * p_out, int &pn, poly * terms, int tn,
+                  slimgb_alg * c)
+{
+  static int export_n = 0;
+  assume (terms[tn - 1] != NULL);
+  assume (rField_is_Zp (c->r));
+  //I don't do deletes, copies of number_types ...
+  const number_type zero = 0;   //npInit(0);
+  int array_size = pn * tn;
+  number_type *number_array =
+    (number_type *) omalloc (pn * tn * sizeof (number_type));
+  int i;
+  for(i = 0; i < array_size; i++)
+  {
+    number_array[i] = zero;
+  }
+  for(i = 0; i < pn; i++)
+  {
+    poly h = p[i];
+    //int base=tn*i;
+    write_poly_to_row (number_array + tn * i, h, terms, tn, c->r);
+
+  }
+#if 0
+  //export matrix
+  export_mat (number_array, pn, tn, "mat%i.py", ++export_n);
+#endif
+  int rank = pn;
+  simplest_gauss_modp (number_array, rank, tn);
+  int act_row = 0;
+  int p_pos = 0;
+  for(i = 0; i < pn; i++)
+  {
+    poly h = NULL;
+    int j;
+    int base = tn * i;
+    number *row = number_array + base;
+    h = row_to_poly (row, terms, tn, c->r);
+
+    if(h != NULL)
+    {
+      p_out[p_pos++] = h;
+    }
+  }
+  pn = p_pos;
+  //assert(p_pos==rank)
+  while(p_pos < pn)
+  {
+    p_out[p_pos++] = NULL;
+  }
+#if 0
+  export_mat (number_array, pn, tn, "mat%i.py", ++export_n);
+#endif
+}
+#endif
+#endif
+static void mass_add (poly * p, int pn, slimgb_alg * c)
+{
+  int j;
+  int *ibuf = (int *) omalloc (pn * sizeof (int));
+  sorted_pair_node ***sbuf =
+    (sorted_pair_node ***) omalloc (pn * sizeof (sorted_pair_node **));
+  for(j = 0; j < pn; j++)
+  {
+    p_Test (p[j], c->r);
+    sbuf[j] = add_to_basis_ideal_quotient (p[j], c, ibuf + j);
+  }
+  int sum = 0;
+  for(j = 0; j < pn; j++)
+  {
+    sum += ibuf[j];
+  }
+  sorted_pair_node **big_sbuf =
+    (sorted_pair_node **) omalloc (sum * sizeof (sorted_pair_node *));
+  int partsum = 0;
+  for(j = 0; j < pn; j++)
+  {
+    memmove (big_sbuf + partsum, sbuf[j],
+             ibuf[j] * sizeof (sorted_pair_node *));
+    omFree (sbuf[j]);
+    partsum += ibuf[j];
+  }
+
+  qsort (big_sbuf, sum, sizeof (sorted_pair_node *), tgb_pair_better_gen2);
+  c->apairs = spn_merge (c->apairs, c->pair_top + 1, big_sbuf, sum, c);
+  c->pair_top += sum;
+  clean_top_of_pair_list (c);
+  omfree (big_sbuf);
+  omfree (sbuf);
+  omfree (ibuf);
+  //omfree(buf);
+#ifdef TGB_DEBUG
+  int z;
+  for(z = 1; z <= c->pair_top; z++)
+  {
+    assume (pair_better (c->apairs[z], c->apairs[z - 1], c));
+  }
+#endif
+
+}
+
+#ifdef NORO_CACHE
+#ifndef NORO_NON_POLY
+void NoroCache::evaluateRows ()
+{
+  //after that can evaluate placeholders
+  int i;
+  buffer = (number *) omAlloc (nIrreducibleMonomials * sizeof (number));
+  for(i = 0; i < root.branches_len; i++)
+  {
+    evaluateRows (1, root.branches[i]);
+  }
+  omFree (buffer);
+  buffer = NULL;
+}
+
+void NoroCache::evaluateRows (int level, NoroCacheNode * node)
+{
+  assume (level >= 0);
+  if(node == NULL)
+    return;
+  if(level < (currRing->N))
+  {
+    int i, sum;
+    for(i = 0; i < node->branches_len; i++)
+    {
+      evaluateRows (level + 1, node->branches[i]);
+    }
+  }
+  else
+  {
+    DataNoroCacheNode *dn = (DataNoroCacheNode *) node;
+    if(dn->value_len != backLinkCode)
+    {
+      poly p = dn->value_poly;
+#ifndef NORO_SPARSE_ROWS_PRE
+      dn->row = new DenseRow ();
+      DenseRow *row = dn->row;
+      memset (buffer, 0, sizeof (number) * nIrreducibleMonomials);
+
+      if(p == NULL)
+      {
+        row->array = NULL;
+        row->begin = 0;
+        row->end = 0;
+        return;
+      }
+      int i = 0;
+      int idx;
+      number *a = buffer;
+      while(p)
+      {
+        DataNoroCacheNode *ref = getCacheReference (p);
+
+        idx = ref->term_index;
+        assume (idx >= 0);
+        a[idx] = p_GetCoeff (p, currRing);
+        if(i == 0)
+          row->begin = idx;
+        i++;
+        pIter (p);
+      }
+      row->end = idx + 1;
+      assume (row->end > row->begin);
+      int len = row->end - row->begin;
+      row->array = (number *) omalloc ((len) * sizeof (number));
+      memcpy (row->array, a + row->begin, len * sizeof (number));
+#else
+      assume (dn->value_len == pLength (dn->value_poly));
+      dn->row = new SparseRow (dn->value_len);
+      SparseRow *row = dn->row;
+      int i = 0;
+      while(p)
+      {
+        DataNoroCacheNode *ref = getCacheReference (p);
+
+        int idx = ref->term_index;
+        assume (idx >= 0);
+        row->idx_array[i] = idx;
+        row->coef_array[i] = p_GetCoeff (p, currRing);
+        i++;
+        pIter (p);
+      }
+      if(i != dn->value_len)
+      {
+        PrintS ("F4 calc wrong, as poly len was wrong\n");
+      }
+      assume (i == dn->value_len);
+#endif
+    }
+  }
+}
+
+void
+  NoroCache::evaluatePlaceHolder (number * row,
+                                  std::vector < NoroPlaceHolder >
+                                  &place_holders)
+{
+  int i;
+  int s = place_holders.size ();
+  for(i = 0; i < s; i++)
+  {
+    DataNoroCacheNode *ref = place_holders[i].ref;
+    number coef = place_holders[i].coef;
+    if(ref->value_len == backLinkCode)
+    {
+      row[ref->term_index] = npAddM (row[ref->term_index], coef);
+    }
+    else
+    {
+#ifndef NORO_SPARSE_ROWS_PRE
+      DenseRow *ref_row = ref->row;
+      if(ref_row == NULL)
+        continue;
+      number *ref_begin = ref_row->array;
+      number *ref_end = ref_row->array + (ref_row->end - ref_row->begin);
+      number *my_pos = row + ref_row->begin;
+      //TODO npisOne distinction
+      if(!(npIsOne (coef)))
+      {
+        while(ref_begin != ref_end)
+        {
+
+          *my_pos = npAddM (*my_pos, npMult (coef, *ref_begin));
+          ++ref_begin;
+          ++my_pos;
+        }
+      }
+      else
+      {
+        while(ref_begin != ref_end)
+        {
+
+          *my_pos = npAddM (*my_pos, *ref_begin);
+          ++ref_begin;
+          ++my_pos;
+        }
+      }
+
+#else
+      SparseRow *ref_row = ref->row;
+      if(ref_row == NULL)
+        continue;
+      int n = ref_row->len;
+      int j;
+      int *idx_array = ref_row->idx_array;
+      number *coef_array = ref_row->coef_array;
+      for(j = 0; j < n; j++)
+      {
+        int idx = idx_array[j];
+        number ref_coef = coef_array[j];
+        row[idx] = npAddM (row[idx], npMult (coef, ref_coef));
+      }
+#endif
+    }
+  }
+}
+#endif
+
+//poly noro_red_non_unique(poly p, int &len, NoroCache* cache,slimgb_alg* c);
+
+#ifndef NORO_NON_POLY
+MonRedRes
+noro_red_mon (poly t, BOOLEAN force_unique, NoroCache * cache, slimgb_alg * c)
+{
+  MonRedRes res_holder;
+
+  //wrp(t);
+  res_holder.changed = TRUE;
+  if(force_unique)
+  {
+    DataNoroCacheNode *ref = cache->getCacheReference (t);
+    if(ref != NULL)
+    {
+      res_holder.len = ref->value_len;
+      if(res_holder.len == NoroCache::backLinkCode)
+      {
+        res_holder.len = 1;
+      }
+      res_holder.coef = p_GetCoeff (t, c->r);
+      res_holder.p = ref->value_poly;
+      res_holder.ref = ref;
+      res_holder.onlyBorrowed = TRUE;
+      res_holder.changed = TRUE;
+      p_Delete (&t, c->r);
+      return res_holder;
+    }
+  }
+  else
+  {
+    BOOLEAN succ;
+    poly cache_lookup = cache->lookup (t, succ, res_holder.len);        //don't own this yet
+    if(succ)
+    {
+      if(cache_lookup == t)
+      {
+        //know they are equal
+        //res_holder.len=1;
+
+        res_holder.changed = FALSE;
+        res_holder.p = t;
+        res_holder.coef = npInit (1);
+
+        res_holder.onlyBorrowed = FALSE;
+        return res_holder;
+      }
+
+      res_holder.coef = p_GetCoeff (t, c->r);
+      p_Delete (&t, c->r);
+
+      res_holder.p = cache_lookup;
+
+      res_holder.onlyBorrowed = TRUE;
+      return res_holder;
+
+    }
+  }
+
+  unsigned long sev = p_GetShortExpVector (t, currRing);
+  int i = kFindDivisibleByInS_easy (c->strat, t, sev);
+  if(i >= 0)
+  {
+    number coef_bak = p_GetCoeff (t, c->r);
+
+    p_SetCoeff (t, npInit (1), c->r);
+    assume (npIsOne (p_GetCoeff (c->strat->S[i], c->r)));
+    number coefstrat = p_GetCoeff (c->strat->S[i], c->r);
+
+    //poly t_copy_mon=p_Copy(t,c->r);
+    poly exp_diff = cache->temp_term;
+    p_ExpVectorDiff (exp_diff, t, c->strat->S[i], c->r);
+    p_SetCoeff (exp_diff, npNeg (nInvers (coefstrat)), c->r);
+    // nInvers may be npInvers or nvInvers
+    p_Setm (exp_diff, c->r);
+    assume (c->strat->S[i] != NULL);
+    //poly t_to_del=t;
+    poly res;
+    res = pp_Mult_mm (pNext (c->strat->S[i]), exp_diff, c->r);
+
+    res_holder.len = c->strat->lenS[i] - 1;
+    res = noro_red_non_unique (res, res_holder.len, cache, c);
+
+    DataNoroCacheNode *ref = cache->insert (t, res, res_holder.len);
+    p_Delete (&t, c->r);
+    //p_Delete(&t_copy_mon,c->r);
+    //res=pMult_nn(res,coef_bak);
+    res_holder.changed = TRUE;
+    res_holder.p = res;
+    res_holder.coef = coef_bak;
+    res_holder.onlyBorrowed = TRUE;
+    res_holder.ref = ref;
+    return res_holder;
+  }
+  else
+  {
+    number coef_bak = p_GetCoeff (t, c->r);
+    number one = npInit (1);
+    p_SetCoeff (t, one, c->r);
+    res_holder.len = 1;
+    if(!(force_unique))
+    {
+      res_holder.ref = cache->insert (t, t, res_holder.len);
+      p_SetCoeff (t, coef_bak, c->r);
+      //return t;
+
+      //we need distinction
+      res_holder.changed = FALSE;
+      res_holder.p = t;
+
+      res_holder.coef = npInit (1);
+      res_holder.onlyBorrowed = FALSE;
+      return res_holder;
+    }
+    else
+    {
+      res_holder.ref = cache->insertAndTransferOwnerShip (t, c->r);
+      res_holder.coef = coef_bak;
+      res_holder.onlyBorrowed = TRUE;
+      res_holder.changed = FALSE;
+      res_holder.p = t;
+      return res_holder;
+    }
+  }
+
+}
+#endif
+//SparseRow* noro_red_to_non_poly(poly p, int &len, NoroCache* cache,slimgb_alg* c);
+#ifndef NORO_NON_POLY
+//len input and out: Idea: reverse addition
+poly noro_red_non_unique (poly p, int &len, NoroCache * cache, slimgb_alg * c)
+{
+  assume (len == pLength (p));
+  poly orig_p = p;
+  if(p == NULL)
+  {
+    len = 0;
+    return NULL;
+  }
+  kBucket_pt bucket = kBucketCreate (currRing);
+  kBucketInit (bucket, NULL, 0);
+  poly unchanged_head = NULL;
+  poly unchanged_tail = NULL;
+  int unchanged_size = 0;
+
+  while(p)
+  {
+    poly t = p;
+    pIter (p);
+    pNext (t) = NULL;
+#ifndef SING_NDEBUG
+    number coef_debug = p_GetCoeff (t, currRing);
+#endif
+    MonRedRes red = noro_red_mon (t, FALSE, cache, c);
+    if((!(red.changed)) && (!(red.onlyBorrowed)))
+    {
+      unchanged_size++;
+      assume (npIsOne (red.coef));
+      assume (p_GetCoeff (red.p, currRing) == coef_debug);
+      if(unchanged_head)
+      {
+        pNext (unchanged_tail) = red.p;
+        pIter (unchanged_tail);
+      }
+      else
+      {
+        unchanged_tail = red.p;
+        unchanged_head = red.p;
+      }
+    }
+    else
+    {
+      assume (red.len == pLength (red.p));
+      if(red.onlyBorrowed)
+      {
+        if(npIsOne (red.coef))
+        {
+          t = p_Copy (red.p, currRing);
+        }
+        else
+          t = pp_Mult_nn (red.p, red.coef, currRing);
+      }
+      else
+      {
+        if(npIsOne (red.coef))
+          t = red.p;
+        else
+          t = p_Mult_nn (red.p, red.coef, currRing);
+      }
+      kBucket_Add_q (bucket, t, &red.len);
+    }
+  }
+  poly res = NULL;
+  len = 0;
+  kBucket_Add_q (bucket, unchanged_head, &unchanged_size);
+  kBucketClear (bucket, &res, &len);
+  kBucketDestroy (&bucket);
+  return res;
+}
+#endif
+#ifdef NORO_SPARSE_ROWS_PRE
+//len input and out: Idea: reverse addition
+
+/*template <class number_type> SparseRow<number_type>* noro_red_to_non_poly(poly p, int &len, NoroCache<number_type>* cache,slimgb_alg* c)
+ * {
+  if (n_GetChar(currRing->cf)<255)
+  {
+    return noro_red_to_non_poly_t<tgb_uint8>(p,len,cache,c);
+  }
+  else
+  {
+    if (n_GetChar(currRing->cf)<65000)
+    {
+      return noro_red_to_non_poly_t<tgb_uint16>(p,len,cache,c);
+    }
+    else
+    {
+      return noro_red_to_non_poly_t<tgb_uint32>(p,len,cache,c);
+    }
+  }
+}*/
+#endif
+//len input and out: Idea: reverse addition
+#ifndef NORO_NON_POLY
+std::vector < NoroPlaceHolder > noro_red (poly p, int &len, NoroCache * cache,
+                                          slimgb_alg * c)
+{
+  std::vector < NoroPlaceHolder > res;
+  while(p)
+  {
+    poly t = p;
+    pIter (p);
+    pNext (t) = NULL;
+
+    MonRedRes red = noro_red_mon (t, TRUE, cache, c);
+    assume (red.onlyBorrowed);
+    assume (red.coef);
+    assume (red.ref);
+    NoroPlaceHolder h;
+    h.ref = red.ref;
+    h.coef = red.coef;
+    assume (!((h.ref->value_poly == NULL) && (h.ref->value_len != 0)));
+    if(h.ref->value_poly)
+      res.push_back (h);
+  }
+  return res;
+}
+#endif
+
+#endif
+#ifdef USE_NORO
+#ifndef NORO_CACHE
+void noro_step (poly * p, int &pn, slimgb_alg * c)
+{
+  poly *reduced = (poly *) omalloc (pn * sizeof (poly));
+  int j;
+  int *reduced_len = (int *) omalloc (pn * sizeof (int));
+  int reduced_c = 0;
+  //if (TEST_OPT_PROT)
+  //  PrintS("reduced system:\n");
+#ifdef NORO_CACHE
+  NoroCache cache;
+#endif
+  for(j = 0; j < pn; j++)
+  {
+
+    poly h = p[j];
+    int h_len = pLength (h);
+
+    number coef;
+#ifndef NORO_CACHE
+    h = redNF2 (p_Copy (h, c->r), c, h_len, coef, 0);
+#else
+    h = noro_red (p_Copy (h, c->r), h_len, &cache, c);
+    assume (pLength (h) == h_len);
+#endif
+    if(h != NULL)
+    {
+#ifndef NORO_CACHE
+
+      h = redNFTail (h, c->strat->sl, c->strat, h_len);
+      h_len = pLength (h);
+#endif
+      reduced[reduced_c] = h;
+      reduced_len[reduced_c] = h_len;
+      reduced_c++;
+      if(TEST_OPT_PROT)
+        Print ("%d ", h_len);
+    }
+  }
+  int reduced_sum = 0;
+  for(j = 0; j < reduced_c; j++)
+  {
+    reduced_sum += reduced_len[j];
+  }
+  poly *terms = (poly *) omalloc (reduced_sum * sizeof (poly));
+  int tc = 0;
+  for(j = 0; j < reduced_c; j++)
+  {
+    poly h = reduced[j];
+
+    while(h != NULL)
+    {
+      terms[tc++] = h;
+      pIter (h);
+      assume (tc <= reduced_sum);
+    }
+  }
+  assume (tc == reduced_sum);
+  qsort (terms, reduced_sum, sizeof (poly), terms_sort_crit);
+  int nterms = reduced_sum;
+  //if (TEST_OPT_PROT)
+  //Print("orig estimation:%i\n",reduced_sum);
+  unify_terms (terms, nterms);
+  //if (TEST_OPT_PROT)
+  //    Print("actual number of columns:%i\n",nterms);
+  int rank = reduced_c;
+  linalg_step_modp (reduced, p, rank, terms, nterms, c);
+  omfree (terms);
+
+  pn = rank;
+  omfree (reduced);
+
+  if(TEST_OPT_PROT)
+    PrintS ("\n");
+}
+#else
+
+#endif
+#endif
+static void go_on (slimgb_alg * c)
+{
+  //set limit of 1000 for multireductions, at the moment for
+  //programming reasons
+#ifdef USE_NORO
+  //Print("module rank%d\n",c->S->rank);
+  const BOOLEAN use_noro = c->use_noro;
+#else
+  const BOOLEAN use_noro = FALSE;
+#endif
+  int i = 0;
+  c->average_length = 0;
+  for(i = 0; i < c->n; i++)
+  {
+    c->average_length += c->lengths[i];
+  }
+  c->average_length = c->average_length / c->n;
+  i = 0;
+  int max_pairs = bundle_size;
+
+#ifdef USE_NORO
+  if((use_noro) || (c->use_noro_last_block))
+    max_pairs = bundle_size_noro;
+#endif
+  poly *p = (poly *) omalloc ((max_pairs + 1) * sizeof (poly)); //nullterminated
+
+  int curr_deg = -1;
+  while(i < max_pairs)
+  {
+    sorted_pair_node *s = top_pair (c); //here is actually chain criterium done
+
+    if(!s)
+      break;
+
+    if(curr_deg >= 0)
+    {
+      if(s->deg > curr_deg)
+        break;
+    }
+
+    else
+      curr_deg = s->deg;
+    quick_pop_pair (c);
+    if(s->i >= 0)
+    {
+      //be careful replace_pair use createShortSpoly which is not noncommutative
+      now_t_rep (s->i, s->j, c);
+      replace_pair (s->i, s->j, c);
+
+      if(s->i == s->j)
+      {
+        free_sorted_pair_node (s, c->r);
+        continue;
+      }
+      now_t_rep (s->i, s->j, c);
+    }
+    poly h;
+    if(s->i >= 0)
+    {
+#ifdef HAVE_PLURAL
+      if(c->nc)
+      {
+        h = nc_CreateSpoly (c->S->m[s->i], c->S->m[s->j] /*, NULL */ , c->r);
+
+        if(h != NULL)
+          p_Cleardenom (h, c->r);
+      }
+      else
+#endif
+        h = ksOldCreateSpoly (c->S->m[s->i], c->S->m[s->j], NULL, c->r);
+      p_Test (h, c->r);
+    }
+    else
+    {
+      h = s->lcm_of_lm;
+      p_Test (h, c->r);
+    }
+    // if(s->i>=0)
+//       now_t_rep(s->j,s->i,c);
+    number coef;
+    int mlen = pLength (h);
+    p_Test (h, c->r);
+    if((!c->nc) & (!(use_noro)))
+    {
+      h = redNF2 (h, c, mlen, coef, 2);
+      redTailShort (h, c->strat);
+      nDelete (&coef);
+    }
+    p_Test (h, c->r);
+    free_sorted_pair_node (s, c->r);
+    if(!h)
+      continue;
+    p[i] = h;
+    i++;
+  }
+  p[i] = NULL;
+//  pre_comp(p,i,c);
+  if(i == 0)
+  {
+    omfree (p);
+    return;
+  }
+#ifdef TGB_RESORT_PAIRS
+  c->replaced = new bool[c->n];
+  c->used_b = FALSE;
+#endif
+
+  c->normal_forms += i;
+  int j;
+#ifdef USE_NORO
+  //if ((!(c->nc))&&(rField_is_Zp(c->r)))
+  //{
+  if(use_noro)
+  {
+    int pn = i;
+    if(pn == 0)
+    {
+      omfree (p);
+      return;
+    }
+    {
+      if(n_GetChar(currRing->cf) < 255)
+      {
+        noro_step < tgb_uint8 > (p, pn, c);
+      }
+      else
+      {
+        if(n_GetChar(currRing->cf) < 65000)
+        {
+          noro_step < tgb_uint16 > (p, pn, c);
+        }
+        else
+        {
+          noro_step < tgb_uint32 > (p, pn, c);
+        }
+      }
+    }
+
+    //if (TEST_OPT_PROT)
+    //{
+    //  Print("reported rank:%i\n",pn);
+    //}
+    mass_add (p, pn, c);
+    omfree (p);
+    return;
+    /*if (TEST_OPT_PROT)
+       for(j=0;j<pn;j++)
+       {
+       p_wrp(p[j],c->r);
+       } */
+  }
+#endif
+  red_object *buf = (red_object *) omalloc (i * sizeof (red_object));
+  for(j = 0; j < i; j++)
+  {
+    p_Test (p[j], c->r);
+    buf[j].p = p[j];
+    buf[j].sev = pGetShortExpVector (p[j]);
+    buf[j].bucket = kBucketCreate (currRing);
+    p_Test (p[j], c->r);
+    int len = pLength (p[j]);
+    kBucketInit (buf[j].bucket, buf[j].p, len);
+    buf[j].initial_quality = buf[j].guess_quality (c);
+    assume (buf[j].initial_quality >= 0);
+  }
+  omfree (p);
+  qsort (buf, i, sizeof (red_object), red_object_better_gen);
+//    Print("\ncurr_deg:%i\n",curr_deg);
+  if(TEST_OPT_PROT)
+  {
+    Print ("%dM[%d,", curr_deg, i);
+  }
+
+  multi_reduction (buf, i, c);
+#ifdef TGB_RESORT_PAIRS
+  if(c->used_b)
+  {
+    if(TEST_OPT_PROT)
+      PrintS ("B");
+    int e;
+    for(e = 0; e <= c->pair_top; e++)
+    {
+      if(c->apairs[e]->i < 0)
+        continue;
+      assume (c->apairs[e]->j >= 0);
+      if((c->replaced[c->apairs[e]->i]) || (c->replaced[c->apairs[e]->j]))
+      {
+        sorted_pair_node *s = c->apairs[e];
+        s->expected_length = pair_weighted_length (s->i, s->j, c);
+      }
+    }
+    qsort (c->apairs, c->pair_top + 1, sizeof (sorted_pair_node *),
+           tgb_pair_better_gen2);
+  }
+#endif
+#ifdef TGB_DEBUG
+  {
+    int k;
+    for(k = 0; k < i; k++)
+    {
+      assume (kFindDivisibleByInS_easy (c->strat, buf[k]) < 0);
+      int k2;
+      for(k2 = 0; k2 < i; k2++)
+      {
+        if(k == k2)
+          continue;
+        assume ((!(p_LmDivisibleBy (buf[k].p, buf[k2].p, c->r)))
+                || (wrp (buf[k].p), Print (" k %d k2 %d ", k, k2),
+                    wrp (buf[k2].p), FALSE));
+      }
+    }
+  }
+#endif
+  //resort S
+
+  if(TEST_OPT_PROT)
+    Print ("%i]", i);
+
+  poly *add_those = (poly *) omalloc (i * sizeof (poly));
+  for(j = 0; j < i; j++)
+  {
+    int len;
+    poly p;
+    buf[j].flatten ();
+    kBucketClear (buf[j].bucket, &p, &len);
+    kBucketDestroy (&buf[j].bucket);
+    p_Test (p, c->r);
+    //if (!c->nc) {
+    if((c->tailReductions) || (lies_in_last_dp_block (p, c)))
+    {
+      p = redNFTail (p, c->strat->sl, c->strat, 0);
+    }
+    else
+    {
+      p = redTailShort (p, c->strat);
+    }
+    //}
+    p_Test (p, c->r);
+    add_those[j] = p;
+
+    //sbuf[j]=add_to_basis(p,-1,-1,c,ibuf+j);
+  }
+  mass_add (add_those, i, c);
+  omfree (add_those);
+  omfree (buf);
+
+  if(TEST_OPT_PROT)
+    Print ("(%d)", c->pair_top + 1);
+  //TODO: implement that while(!(idIs0(c->add_later)))
+#ifdef TGB_RESORT_PAIRS
+  delete c->replaced;
+  c->replaced = NULL;
+  c->used_b = FALSE;
+#endif
+  return;
+}
+
+#ifdef REDTAIL_S
+
+static poly redNFTail (poly h, const int sl, kStrategy strat, int len)
+{
+  BOOLEAN nc = rIsPluralRing (currRing);
+  if(h == NULL)
+    return NULL;
+  pTest (h);
+  if(0 > sl)
+    return h;
+  if(pNext (h) == NULL)
+    return h;
+
+  int j;
+  poly res = h;
+  poly act = res;
+  LObject P (pNext (h));
+  pNext (res) = NULL;
+  P.bucket = kBucketCreate (currRing);
+  len--;
+  h = P.p;
+  if(len <= 0)
+    len = pLength (h);
+  kBucketInit (P.bucket, h /*P.p */ , len /*pLength(P.p) */ );
+  pTest (h);
+  loop
+  {
+    P.p = h;
+    P.t_p = NULL;
+    P.SetShortExpVector ();
+    loop
+    {
+      //int dummy=strat->sl;
+      j = kFindDivisibleByInS_easy (strat, P.p, P.sev); //kFindDivisibleByInS(strat,&dummy,&P);
+      if(j >= 0)
+      {
+#ifdef REDTAIL_PROT
+        PrintS ("r");
+#endif
+        nNormalize (pGetCoeff (P.p));
+#ifdef KDEBUG
+        if(TEST_OPT_DEBUG)
+        {
+          PrintS ("red tail:");
+          wrp (h);
+          PrintS (" with ");
+          wrp (strat->S[j]);
+        }
+#endif
+        number coef;
+        pTest (strat->S[j]);
+#ifdef HAVE_PLURAL
+        if(nc)
+        {
+          nc_BucketPolyRed_Z (P.bucket, strat->S[j], &coef);
+        }
+        else
+#endif
+          coef = kBucketPolyRed (P.bucket, strat->S[j],
+                                 strat->lenS[j] /*pLength(strat->S[j]) */ ,
+                                 strat->kNoether);
+        pMult_nn (res, coef);
+        nDelete (&coef);
+        h = kBucketGetLm (P.bucket);
+        pTest (h);
+        if(h == NULL)
+        {
+#ifdef REDTAIL_PROT
+          PrintS (" ");
+#endif
+          kBucketDestroy (&P.bucket);
+          return res;
+        }
+        pTest (h);
+        P.p = h;
+        P.t_p = NULL;
+        P.SetShortExpVector ();
+#ifdef KDEBUG
+        if(TEST_OPT_DEBUG)
+        {
+          PrintS ("\nto tail:");
+          wrp (h);
+          PrintLn ();
+        }
+#endif
+      }
+      else
+      {
+#ifdef REDTAIL_PROT
+        PrintS ("n");
+#endif
+        break;
+      }
+    }                           /* end loop current mon */
+    //   poly tmp=pHead(h /*kBucketGetLm(P.bucket)*/);
+    //act->next=tmp;pIter(act);
+    act->next = kBucketExtractLm (P.bucket);
+    pIter (act);
+    h = kBucketGetLm (P.bucket);
+    if(h == NULL)
+    {
+#ifdef REDTAIL_PROT
+      PrintS (" ");
+#endif
+      kBucketDestroy (&P.bucket);
+      return res;
+    }
+    pTest (h);
+  }
+}
+#endif
+
+
+//try to fill, return FALSE iff queue is empty
+
+//transfers ownership of m to mat
+void init_with_mac_poly (tgb_sparse_matrix * mat, int row, mac_poly m)
+{
+  assume (mat->mp[row] == NULL);
+  mat->mp[row] = m;
+#ifdef TGB_DEBUG
+  mac_poly r = m;
+  while(r)
+  {
+    assume (r->exp < mat->columns);
+    r = r->next;
+  }
+#endif
+}
+
+poly
+free_row_to_poly (tgb_sparse_matrix * mat, int row, poly * monoms,
+                  int monom_index)
+{
+  poly p = NULL;
+  poly *set_this = &p;
+  mac_poly r = mat->mp[row];
+  mat->mp[row] = NULL;
+  while(r)
+  {
+    (*set_this) = pLmInit (monoms[monom_index - 1 - r->exp]);
+    pSetCoeff ((*set_this), r->coef);
+    set_this = &((*set_this)->next);
+    mac_poly old = r;
+    r = r->next;
+    delete old;
+
+  }
+  return p;
+}
+
+static int poly_crit (const void *ap1, const void *ap2)
+{
+  poly p1, p2;
+  p1 = *((poly *) ap1);
+  p2 = *((poly *) ap2);
+
+  int c = pLmCmp (p1, p2);
+  if(c != 0)
+    return c;
+  int l1 = pLength (p1);
+  int l2 = pLength (p2);
+  if(l1 < l2)
+    return -1;
+  if(l1 > l2)
+    return 1;
+  return 0;
+}
+
+void slimgb_alg::introduceDelayedPairs (poly * pa, int s)
+{
+  if(s == 0)
+    return;
+  sorted_pair_node **si_array =
+    (sorted_pair_node **) omalloc (s * sizeof (sorted_pair_node *));
+
+  for(int i = 0; i < s; i++)
+  {
+    sorted_pair_node *si =
+      (sorted_pair_node *) omalloc (sizeof (sorted_pair_node));
+    si->i = -1;
+    si->j = -2;
+    poly p = pa[i];
+    simplify_poly (p, r);
+    si->expected_length = pQuality (p, this, pLength (p));
+    p_Test (p, r);
+    si->deg = this->pTotaldegree_full (p);
+    /*if (!rField_is_Zp(r))
+       {
+       p_Content(p,r);
+       p_Cleardenom(p,r);
+       } */
+
+    si->lcm_of_lm = p;
+
+    //      c->apairs[n-1-i]=si;
+    si_array[i] = si;
+  }
+
+  qsort (si_array, s, sizeof (sorted_pair_node *), tgb_pair_better_gen2);
+  apairs = spn_merge (apairs, pair_top + 1, si_array, s, this);
+  pair_top += s;
+  omfree (si_array);
+}
+
+slimgb_alg::slimgb_alg (ideal I, int syz_comp, BOOLEAN F4, int deg_pos)
+{
+  this->deg_pos = deg_pos;
+  lastCleanedDeg = -1;
+  completed = FALSE;
+  this->syz_comp = syz_comp;
+  r = currRing;
+  nc = rIsPluralRing (r);
+  this->lastDpBlockStart = get_last_dp_block_start (r);
+  //Print("last dp Block start: %i\n", this->lastDpBlockStart);
+  is_homog = TRUE;
+  {
+    int hzz;
+    for(hzz = 0; hzz < IDELEMS (I); hzz++)
+    {
+      assume (I->m[hzz] != NULL);
+      int d = this->pTotaldegree (I->m[hzz]);
+      poly t = I->m[hzz]->next;
+      while(t)
+      {
+        if(d != this->pTotaldegree (t))
+        {
+          is_homog = FALSE;
+          break;
+        }
+        t = t->next;
+      }
+      if(!(is_homog))
+        break;
+    }
+  }
+  eliminationProblem = ((!(is_homog)) && ((currRing->pLexOrder) || (I->rank > 1)));
+  tailReductions = ((is_homog) || ((TEST_OPT_REDTAIL) && (!(I->rank > 1))));
+  //  Print("is homog:%d",c->is_homog);
+  void *h;
+  int i;
+  to_destroy = NULL;
+  easy_product_crit = 0;
+  extended_product_crit = 0;
+  if(rField_is_Zp (r))
+    isDifficultField = FALSE;
+  else
+    isDifficultField = TRUE;
+  //not fully correct
+  //(rChar()==0);
+  F4_mode = F4;
+
+  reduction_steps = 0;
+  last_index = -1;
+
+  F = NULL;
+  F_minus = NULL;
+
+  Rcounter = 0;
+
+  soon_free = NULL;
+
+  tmp_lm = pOne ();
+
+  normal_forms = 0;
+  current_degree = 1;
+
+  max_pairs = 5 * IDELEMS (I);
+
+  apairs =
+    (sorted_pair_node **) omalloc (sizeof (sorted_pair_node *) * max_pairs);
+  pair_top = -1;
+
+  int n = IDELEMS (I);
+  array_lengths = n;
+
+
+  i = 0;
+  this->n = 0;
+  T_deg = (int *) omalloc (n * sizeof (int));
+  if(eliminationProblem)
+    T_deg_full = (int *) omalloc (n * sizeof (int));
+  else
+    T_deg_full = NULL;
+  tmp_pair_lm = (poly *) omalloc (n * sizeof (poly));
+  tmp_spn = (sorted_pair_node **) omalloc (n * sizeof (sorted_pair_node *));
+  lm_bin = omGetSpecBin (POLYSIZE + (r->ExpL_Size) * sizeof (long));
+#ifdef HEAD_BIN
+  HeadBin = omGetSpecBin (POLYSIZE + (currRing->ExpL_Size) * sizeof (long));
+#endif
+  /* omUnGetSpecBin(&(c->HeadBin)); */
+#ifndef HAVE_BOOST
+#ifdef USE_STDVECBOOL
+#else
+  h = omalloc (n * sizeof (char *));
+
+  states = (char **) h;
+#endif
+#endif
+  h = omalloc (n * sizeof (int));
+  lengths = (int *) h;
+  weighted_lengths = (wlen_type *) omAllocAligned (n * sizeof (wlen_type));
+  gcd_of_terms = (poly *) omAlloc (n * sizeof (poly));
+
+  short_Exps = (long *) omalloc (n * sizeof (long));
+  if(F4_mode)
+    S = idInit (n, I->rank);
+  else
+    S = idInit (1, I->rank);
+  strat = new skStrategy;
+  if(eliminationProblem)
+    strat->honey = TRUE;
+  strat->syzComp = 0;
+  initBuchMoraCrit (strat);
+  initBuchMoraPos (strat);
+  strat->initEcart = initEcartBBA;
+  strat->tailRing = r;
+  strat->enterS = enterSBba;
+  strat->sl = -1;
+  i = n;
+  i = 1;                        //some strange bug else
+  /* initS(c->S,NULL,c->strat); */
+  /* intS start: */
+  // i=((i+IDELEMS(c->S)+15)/16)*16;
+  strat->ecartS = (intset) omAlloc (i * sizeof (int));  /*initec(i); */
+  strat->sevS = (unsigned long *) omAlloc0 (i * sizeof (unsigned long));
+  /*initsevS(i); */
+  strat->S_2_R = (int *) omAlloc0 (i * sizeof (int));   /*initS_2_R(i); */
+  strat->fromQ = NULL;
+  strat->Shdl = idInit (1, 1);
+  strat->S = strat->Shdl->m;
+  strat->lenS = (int *) omAlloc0 (i * sizeof (int));
+  if((isDifficultField) || (eliminationProblem))
+    strat->lenSw = (wlen_type *) omAlloc0 (i * sizeof (wlen_type));
+  else
+    strat->lenSw = NULL;
+  assume (n > 0);
+  add_to_basis_ideal_quotient (I->m[0], this, NULL);
+
+  assume (strat->sl == IDELEMS (strat->Shdl) - 1);
+  if(!(F4_mode))
+  {
+    poly *array_arg = I->m;
+    array_arg++;
+    introduceDelayedPairs (array_arg, n - 1);
+    /*
+       for (i=1;i<n;i++)//the 1 is wanted, because first element is added to basis
+       {
+       //     add_to_basis(I->m[i],-1,-1,c);
+       si=(sorted_pair_node*) omalloc(sizeof(sorted_pair_node));
+       si->i=-1;
+       si->j=-2;
+       si->expected_length=pQuality(I->m[i],this,pLength(I->m[i]));
+       si->deg=pTotaldegree(I->m[i]);
+       if (!rField_is_Zp(r))
+       {
+       p_Cleardenom(I->m[i], r);
+       }
+       si->lcm_of_lm=I->m[i];
+
+       //      c->apairs[n-1-i]=si;
+       apairs[n-i-1]=si;
+       ++(pair_top);
+       } */
+  }
+  else
+  {
+    for(i = 1; i < n; i++)      //the 1 is wanted, because first element is added to basis
+      add_to_basis_ideal_quotient (I->m[i], this, NULL);
+  }
+  for(i = 0; i < IDELEMS (I); i++)
+  {
+    I->m[i] = NULL;
+  }
+  idDelete (&I);
+  add_later = idInit (ADD_LATER_SIZE, S->rank);
+#ifdef USE_NORO
+  use_noro = ((!(nc)) && (S->rank <= 1) && (rField_is_Zp (r))
+              && (!(eliminationProblem)) && (n_GetChar(currRing->cf) <= 32003));
+  use_noro_last_block = false;
+  if((!(use_noro)) && (lastDpBlockStart <= (currRing->N)))
+  {
+    use_noro_last_block = ((!(nc)) && (S->rank <= 1) && (rField_is_Zp (r))
+                           && (n_GetChar(currRing->cf) <= 32003));
+  }
+#else
+  use_noro = false;
+  use_noro_last_block = false;
+#endif
+  //Print("NORO last block %i",use_noro_last_block);
+  memset (add_later->m, 0, ADD_LATER_SIZE * sizeof (poly));
+}
+
+slimgb_alg::~slimgb_alg ()
+{
+
+  if(!(completed))
+  {
+    poly *add = (poly *) omalloc ((pair_top + 2) * sizeof (poly));
+    int piter;
+    int pos = 0;
+    for(piter = 0; piter <= pair_top; piter++)
+    {
+      sorted_pair_node *s = apairs[piter];
+      if(s->i < 0)
+      {
+        //delayed element
+        if(s->lcm_of_lm != NULL)
+        {
+          add[pos] = s->lcm_of_lm;
+          pos++;
+        }
+      }
+      free_sorted_pair_node (s, r);
+      apairs[piter] = NULL;
+    }
+    pair_top = -1;
+    add[pos] = NULL;
+    pos = 0;
+    while(add[pos] != NULL)
+    {
+      add_to_basis_ideal_quotient (add[pos], this, NULL);
+      pos++;
+    }
+    for(piter = 0; piter <= pair_top; piter++)
+    {
+      sorted_pair_node *s = apairs[piter];
+      assume (s->i >= 0);
+      free_sorted_pair_node (s, r);
+      apairs[piter] = NULL;
+    }
+    pair_top = -1;
+  }
+  id_Delete (&add_later, r);
+  int i, j;
+  slimgb_alg *c = this;
+  while(c->to_destroy)
+  {
+    pDelete (&(c->to_destroy->p));
+    poly_list_node *old = c->to_destroy;
+    c->to_destroy = c->to_destroy->next;
+    omfree (old);
+  }
+  while(c->F)
+  {
+    for(i = 0; i < c->F->size; i++)
+    {
+      pDelete (&(c->F->mp[i].m));
+    }
+    omfree (c->F->mp);
+    c->F->mp = NULL;
+    mp_array_list *old = c->F;
+    c->F = c->F->next;
+    omfree (old);
+  }
+  while(c->F_minus)
+  {
+    for(i = 0; i < c->F_minus->size; i++)
+    {
+      pDelete (&(c->F_minus->p[i]));
+    }
+    omfree (c->F_minus->p);
+    c->F_minus->p = NULL;
+    poly_array_list *old = c->F_minus;
+    c->F_minus = c->F_minus->next;
+    omfree (old);
+  }
+#ifndef HAVE_BOOST
+#ifndef USE_STDVECBOOL
+  for(int z = 1 /* zero length at 0 */ ; z < c->n; z++)
+  {
+    omfree (c->states[z]);
+  }
+  omfree (c->states);
+#endif
+#endif
+
+  omfree (c->lengths);
+  omfree (c->weighted_lengths);
+  for(int z = 0; z < c->n; z++)
+  {
+    pDelete (&c->tmp_pair_lm[z]);
+    omfree (c->tmp_spn[z]);
+  }
+  omfree (c->tmp_pair_lm);
+  omfree (c->tmp_spn);
+
+  omfree (c->T_deg);
+  if(c->T_deg_full)
+    omfree (c->T_deg_full);
+
+  omFree (c->strat->ecartS);
+  omFree (c->strat->sevS);
+//   initsevS(i);
+  omFree (c->strat->S_2_R);
+
+
+  omFree (c->strat->lenS);
+
+  if(c->strat->lenSw)
+    omFree (c->strat->lenSw);
+
+  for(i = 0; i < c->n; i++)
+  {
+    if(c->gcd_of_terms[i])
+      pDelete (&(c->gcd_of_terms[i]));
+  }
+  omfree (c->gcd_of_terms);
+
+  omfree (c->apairs);
+  if(TEST_OPT_PROT)
+  {
+    //Print("calculated %d NFs\n",c->normal_forms);
+    Print ("\nNF:%i product criterion:%i, ext_product criterion:%i \n",
+           c->normal_forms, c->easy_product_crit, c->extended_product_crit);
+  }
+
+  for(i = 0; i <= c->strat->sl; i++)
+  {
+    if(!c->strat->S[i])
+      continue;
+    BOOLEAN found = FALSE;
+    for(j = 0; j < c->n; j++)
+    {
+      if(c->S->m[j] == c->strat->S[i])
+      {
+        found = TRUE;
+        break;
+      }
+    }
+    if(!found)
+      pDelete (&c->strat->S[i]);
+  }
+//   for(i=0;i<c->n;i++)
+//   {
+//     if (c->rep[i]!=i)
+//     {
+// //       for(j=0;j<=c->strat->sl;j++)
+// {
+// //   if(c->strat->S[j]==c->S->m[i])
+// {
+// //     c->strat->S[j]=NULL;
+// //     break;
+// //   }
+// //       }
+// //      PrintS("R_delete");
+//       pDelete(&c->S->m[i]);
+//     }
+//   }
+
+  if(completed)
+  {
+    for(i = 0; i < c->n; i++)
+    {
+      assume (c->S->m[i] != NULL);
+      if(p_GetComp (c->S->m[i], currRing) > this->syz_comp)
+        continue;
+      for(j = 0; j < c->n; j++)
+      {
+        if((c->S->m[j] == NULL) || (i == j))
+          continue;
+        assume (p_LmShortDivisibleBy (c->S->m[j], c->short_Exps[j],
+                                      c->S->m[i], ~c->short_Exps[i],
+                                      c->r) == p_LmDivisibleBy (c->S->m[j],
+                                                                c->S->m[i],
+                                                                c->r));
+        if(p_LmShortDivisibleBy (c->S->m[j], c->short_Exps[j],
+                                 c->S->m[i], ~c->short_Exps[i], c->r))
+        {
+          pDelete (&c->S->m[i]);
+          break;
+        }
+      }
+    }
+  }
+  omfree (c->short_Exps);
+
+  ideal I = c->S;
+  IDELEMS (I) = c->n;
+  idSkipZeroes (I);
+  for(i = 0; i <= c->strat->sl; i++)
+    c->strat->S[i] = NULL;
+  id_Delete (&c->strat->Shdl, c->r);
+  pDelete (&c->tmp_lm);
+  omUnGetSpecBin (&lm_bin);
+  delete c->strat;
+}
+
+ideal t_rep_gb (ring r, ideal arg_I, int syz_comp, BOOLEAN F4_mode)
+{
+  assume (r == currRing);
+  ring orig_ring = r;
+  int pos;
+  ring new_ring = rAssure_TDeg (orig_ring, 1, rVar (orig_ring), pos);
+  ideal s_h;
+  if(orig_ring != new_ring)
+  {
+    rChangeCurrRing (new_ring);
+    s_h = idrCopyR_NoSort (arg_I, orig_ring, new_ring);
+    idTest (s_h);
+    /*int i;
+       for(i=0;i<IDELEMS(s_h);i++)
+       {
+       poly p=s_h->m[i];
+       while(p)
+       {
+       p_Setm(p,new_ring);
+       pIter(p);
+       }
+       } */
+  }
+  else
+  {
+    s_h = id_Copy (arg_I, orig_ring);
+  }
+
+  ideal s_result = do_t_rep_gb (new_ring, s_h, syz_comp, F4_mode, pos);
+  ideal result;
+  if(orig_ring != new_ring)
+  {
+    idTest (s_result);
+    rChangeCurrRing (orig_ring);
+    result = idrMoveR_NoSort (s_result, new_ring, orig_ring);
+
+    idTest (result);
+    //rChangeCurrRing(new_ring);
+    rDelete(new_ring);
+    //rChangeCurrRing(orig_ring);
+  }
+  else
+    result = s_result;
+  idTest (result);
+  return result;
+}
+
+ideal
+do_t_rep_gb (ring /*r*/, ideal arg_I, int syz_comp, BOOLEAN F4_mode, int deg_pos)
+{
+  //  Print("QlogSize(0) %d, QlogSize(1) %d,QlogSize(-2) %d, QlogSize(5) %d\n", QlogSize(nlInit(0)),QlogSize(nlInit(1)),QlogSize(nlInit(-2)),QlogSize(nlInit(5)));
+
+  if(TEST_OPT_PROT)
+    if(F4_mode)
+      PrintS ("F4 Modus \n");
+
+  //debug_Ideal=arg_debug_Ideal;
+  //if (debug_Ideal) PrintS("DebugIdeal received\n");
+  // Print("Idelems %i \n----------\n",IDELEMS(arg_I));
+  ideal I = arg_I;
+  id_Compactify (I,currRing);
+  if(idIs0 (I))
+    return I;
+  int i;
+  for(i = 0; i < IDELEMS (I); i++)
+  {
+    assume (I->m[i] != NULL);
+    simplify_poly (I->m[i], currRing);
+  }
+
+  qsort (I->m, IDELEMS (I), sizeof (poly), poly_crit);
+  //Print("Idelems %i \n----------\n",IDELEMS(I));
+  //slimgb_alg* c=(slimgb_alg*) omalloc(sizeof(slimgb_alg));
+  //int syz_comp=arg_I->rank;
+  slimgb_alg *c = new slimgb_alg (I, syz_comp, F4_mode, deg_pos);
+
+  while((c->pair_top >= 0)
+        && ((!(TEST_OPT_DEGBOUND))
+            || (c->apairs[c->pair_top]->deg <= Kstd1_deg)))
+  {
+#ifdef HAVE_F4
+    if(F4_mode)
+      go_on_F4 (c);
+    else
+#endif
+      go_on (c);
+  }
+  if(c->pair_top < 0)
+    c->completed = TRUE;
+  I = c->S;
+  delete c;
+  if(TEST_OPT_REDSB)
+  {
+    ideal erg = kInterRed (I, NULL);
+    assume (I != erg);
+    id_Delete (&I, currRing);
+    return erg;
+  }
+  //qsort(I->m, IDELEMS(I),sizeof(poly),pLmCmp_func);
+  assume (I->rank >= id_RankFreeModule (I,currRing));
+  return (I);
+}
+
+void now_t_rep (const int &arg_i, const int &arg_j, slimgb_alg * c)
+{
+  int i, j;
+  if(arg_i == arg_j)
+  {
+    return;
+  }
+  if(arg_i > arg_j)
+  {
+    i = arg_j;
+    j = arg_i;
+  }
+  else
+  {
+    i = arg_i;
+    j = arg_j;
+  }
+  c->states[j][i] = HASTREP;
+}
+
+static BOOLEAN
+has_t_rep (const int &arg_i, const int &arg_j, slimgb_alg * state)
+{
+  assume (0 <= arg_i);
+  assume (0 <= arg_j);
+  assume (arg_i < state->n);
+  assume (arg_j < state->n);
+  if(arg_i == arg_j)
+  {
+    return (TRUE);
+  }
+  if(arg_i > arg_j)
+  {
+    return (state->states[arg_i][arg_j] == HASTREP);
+  }
+  else
+  {
+    return (state->states[arg_j][arg_i] == HASTREP);
+  }
+}
+
+#if 0                           // unused
+static int pLcmDeg (poly a, poly b)
+{
+  int i;
+  int n = 0;
+  for(i = (currRing->N); i; i--)
+  {
+    n += si_max (pGetExp (a, i), pGetExp (b, i));
+  }
+  return n;
+}
+#endif
+
+static void shorten_tails (slimgb_alg * c, poly monom)
+{
+  return;
+// BOOLEAN corr=lenS_correct(c->strat);
+  for(int i = 0; i < c->n; i++)
+  {
+    //enter tail
+
+    if(c->S->m[i] == NULL)
+      continue;
+    poly tail = c->S->m[i]->next;
+    poly prev = c->S->m[i];
+    BOOLEAN did_something = FALSE;
+    while((tail != NULL) && (pLmCmp (tail, monom) >= 0))
+    {
+      if(p_LmDivisibleBy (monom, tail, c->r))
+      {
+        did_something = TRUE;
+        prev->next = tail->next;
+        tail->next = NULL;
+        p_Delete (&tail, c->r);
+        tail = prev;
+        //PrintS("Shortened");
+        c->lengths[i]--;
+      }
+      prev = tail;
+      tail = tail->next;
+    }
+    if(did_something)
+    {
+      int new_pos;
+      wlen_type q;
+      q = pQuality (c->S->m[i], c, c->lengths[i]);
+      new_pos = simple_posInS (c->strat, c->S->m[i], c->lengths[i], q);
+
+      int old_pos = -1;
+      //assume new_pos<old_pos
+      for(int z = 0; z <= c->strat->sl; z++)
+      {
+        if(c->strat->S[z] == c->S->m[i])
+        {
+          old_pos = z;
+          break;
+        }
+      }
+      if(old_pos == -1)
+        for(int z = new_pos - 1; z >= 0; z--)
+        {
+          if(c->strat->S[z] == c->S->m[i])
+          {
+            old_pos = z;
+            break;
+          }
+        }
+      assume (old_pos >= 0);
+      assume (new_pos <= old_pos);
+      assume (pLength (c->strat->S[old_pos]) == c->lengths[i]);
+      c->strat->lenS[old_pos] = c->lengths[i];
+      if(c->strat->lenSw)
+        c->strat->lenSw[old_pos] = q;
+      if(new_pos < old_pos)
+        move_forward_in_S (old_pos, new_pos, c->strat);
+      length_one_crit (c, i, c->lengths[i]);
+    }
+  }
+}
+
+#if 0                           // currently unused
+static sorted_pair_node *pop_pair (slimgb_alg * c)
+{
+  clean_top_of_pair_list (c);
+
+  if(c->pair_top < 0)
+    return NULL;
+  else
+    return (c->apairs[c->pair_top--]);
+}
+#endif
+
+void slimgb_alg::cleanDegs (int lower, int upper)
+{
+  assume (is_homog);
+  int deg;
+  if(TEST_OPT_PROT)
+  {
+    PrintS ("C");
+  }
+  for(deg = lower; deg <= upper; deg++)
+  {
+    int i;
+    for(i = 0; i < n; i++)
+    {
+      if(T_deg[i] == deg)
+      {
+        poly h;
+        h = S->m[i];
+        h = redNFTail (h, strat->sl, strat, lengths[i]);
+        if(!rField_is_Zp (r))
+        {
+          p_Cleardenom (h, r);
+          //p_Content(h,r);
+        }
+        else
+          pNorm (h);
+        //TODO:GCD of TERMS
+        poly got =::gcd_of_terms (h, r);
+        p_Delete (&gcd_of_terms[i], r);
+        gcd_of_terms[i] = got;
+        int len = pLength (h);
+        wlen_type wlen = pQuality (h, this, len);
+        if(weighted_lengths)
+          weighted_lengths[i] = wlen;
+        lengths[i] = len;
+        assume (h == S->m[i]);
+        int j;
+        for(j = 0; j <= strat->sl; j++)
+        {
+          if(h == strat->S[j])
+          {
+            int new_pos = simple_posInS (strat, h, len, wlen);
+            if(strat->lenS)
+            {
+              strat->lenS[j] = len;
+            }
+            if(strat->lenSw)
+            {
+              strat->lenSw[j] = wlen;
+            }
+            if(new_pos < j)
+            {
+              move_forward_in_S (j, new_pos, strat);
+            }
+            else
+            {
+              if(new_pos > j)
+                new_pos = new_pos - 1;  //is identical with one element
+              if(new_pos > j)
+                move_backward_in_S (j, new_pos, strat);
+            }
+            break;
+          }
+        }
+      }
+    }
+  }
+  {
+    int i, j;
+    for(i = 0; i < this->n; i++)
+    {
+      for(j = 0; j < i; j++)
+      {
+        if(T_deg[i] + T_deg[j] <= upper)
+        {
+          now_t_rep (i, j, this);
+        }
+      }
+    }
+  }
+  //TODO resort and update strat->S,strat->lenSw
+  //TODO mark pairs
+}
+
+sorted_pair_node *top_pair (slimgb_alg * c)
+{
+  while(c->pair_top >= 0)
+  {
+    super_clean_top_of_pair_list (c);   //yeah, I know, it's odd that I use a different proc here
+    if((c->is_homog) && (c->pair_top >= 0)
+       && (c->apairs[c->pair_top]->deg >= c->lastCleanedDeg + 2))
+    {
+      int upper = c->apairs[c->pair_top]->deg - 1;
+      c->cleanDegs (c->lastCleanedDeg + 1, upper);
+      c->lastCleanedDeg = upper;
+    }
+    else
+    {
+      break;
+    }
+  }
+
+  if(c->pair_top < 0)
+    return NULL;
+  else
+    return (c->apairs[c->pair_top]);
+}
+
+sorted_pair_node *quick_pop_pair (slimgb_alg * c)
+{
+  if(c->pair_top < 0)
+    return NULL;
+  else
+    return (c->apairs[c->pair_top--]);
+}
+
+static void super_clean_top_of_pair_list (slimgb_alg * c)
+{
+  while((c->pair_top >= 0)
+        && (c->apairs[c->pair_top]->i >= 0)
+        &&
+        (good_has_t_rep
+         (c->apairs[c->pair_top]->j, c->apairs[c->pair_top]->i, c)))
+  {
+    free_sorted_pair_node (c->apairs[c->pair_top], c->r);
+    c->pair_top--;
+  }
+}
+
+void clean_top_of_pair_list (slimgb_alg * c)
+{
+  while((c->pair_top >= 0) && (c->apairs[c->pair_top]->i >= 0)
+        &&
+        (!state_is
+         (UNCALCULATED, c->apairs[c->pair_top]->j, c->apairs[c->pair_top]->i,
+          c)))
+  {
+    free_sorted_pair_node (c->apairs[c->pair_top], c->r);
+    c->pair_top--;
+  }
+}
+
+static BOOLEAN
+state_is (calc_state state, const int &arg_i, const int &arg_j,
+          slimgb_alg * c)
+{
+  assume (0 <= arg_i);
+  assume (0 <= arg_j);
+  assume (arg_i < c->n);
+  assume (arg_j < c->n);
+  if(arg_i == arg_j)
+  {
+    return (TRUE);
+  }
+  if(arg_i > arg_j)
+  {
+    return (c->states[arg_i][arg_j] == state);
+  }
+  else
+    return (c->states[arg_j][arg_i] == state);
+}
+
+void free_sorted_pair_node (sorted_pair_node * s, ring r)
+{
+  if(s->i >= 0)
+    p_Delete (&s->lcm_of_lm, r);
+  omfree (s);
+}
+
+static BOOLEAN
+pair_better (sorted_pair_node * a, sorted_pair_node * b, slimgb_alg * /*c*/)
+{
+  if(a->deg < b->deg)
+    return TRUE;
+  if(a->deg > b->deg)
+    return FALSE;
+
+  int comp = pLmCmp (a->lcm_of_lm, b->lcm_of_lm);
+  if(comp == 1)
+    return FALSE;
+  if(-1 == comp)
+    return TRUE;
+  if(a->expected_length < b->expected_length)
+    return TRUE;
+  if(a->expected_length > b->expected_length)
+    return FALSE;
+  if(a->i + a->j < b->i + b->j)
+    return TRUE;
+  if(a->i + a->j > b->i + b->j)
+    return FALSE;
+  if(a->i < b->i)
+    return TRUE;
+  if(a->i > b->i)
+    return FALSE;
+  return TRUE;
+}
+
+static int tgb_pair_better_gen (const void *ap, const void *bp)
+{
+  sorted_pair_node *a = *((sorted_pair_node **) ap);
+  sorted_pair_node *b = *((sorted_pair_node **) bp);
+  assume ((a->i > a->j) || (a->i < 0));
+  assume ((b->i > b->j) || (b->i < 0));
+  if(a->deg < b->deg)
+    return -1;
+  if(a->deg > b->deg)
+    return 1;
+
+  int comp = pLmCmp (a->lcm_of_lm, b->lcm_of_lm);
+
+  if(comp == 1)
+    return 1;
+  if(-1 == comp)
+    return -1;
+  if(a->expected_length < b->expected_length)
+    return -1;
+  if(a->expected_length > b->expected_length)
+    return 1;
+  if(a->i + a->j < b->i + b->j)
+    return -1;
+  if(a->i + a->j > b->i + b->j)
+    return 1;
+  if(a->i < b->i)
+    return -1;
+  if(a->i > b->i)
+    return 1;
+  return 0;
+}
+
+static poly gcd_of_terms (poly p, ring r)
+{
+  int max_g_0 = 0;
+  assume (p != NULL);
+  int i;
+  poly m = pOne ();
+  poly t;
+  for(i = (currRing->N); i; i--)
+  {
+    pSetExp (m, i, pGetExp (p, i));
+    if(max_g_0 == 0)
+      if(pGetExp (m, i) > 0)
+        max_g_0 = i;
+  }
+
+  t = p->next;
+  while(t != NULL)
+  {
+    if(max_g_0 == 0)
+      break;
+    for(i = max_g_0; i; i--)
+    {
+      pSetExp (m, i, si_min (pGetExp (t, i), pGetExp (m, i)));
+      if(max_g_0 == i)
+        if(pGetExp (m, i) == 0)
+          max_g_0 = 0;
+      if((max_g_0 == 0) && (pGetExp (m, i) > 0))
+      {
+        max_g_0 = i;
+      }
+    }
+    t = t->next;
+  }
+  p_Setm (m, r);
+  if(max_g_0 > 0)
+    return m;
+  pDelete (&m);
+  return NULL;
+}
+
+static inline BOOLEAN pHasNotCFExtended (poly p1, poly p2, poly m)
+{
+
+  if(pGetComp (p1) > 0 || pGetComp (p2) > 0)
+    return FALSE;
+  int i = 1;
+  loop
+  {
+    if((pGetExp (p1, i) - pGetExp (m, i) > 0)
+       && (pGetExp (p2, i) - pGetExp (m, i) > 0))
+      return FALSE;
+    if(i == (currRing->N))
+      return TRUE;
+    i++;
+  }
+}
+
+//for impl reasons may return false if the the normal product criterion matches
+static inline BOOLEAN
+extended_product_criterion (poly p1, poly gcd1, poly p2, poly gcd2,
+                            slimgb_alg * c)
+{
+  if(c->nc)
+    return FALSE;
+  if(gcd1 == NULL)
+    return FALSE;
+  if(gcd2 == NULL)
+    return FALSE;
+  gcd1->next = gcd2;            //may ordered incorrect
+  poly m = gcd_of_terms (gcd1, c->r);
+  gcd1->next = NULL;
+  if(m == NULL)
+    return FALSE;
+
+  BOOLEAN erg = pHasNotCFExtended (p1, p2, m);
+  pDelete (&m);
+  return erg;
+}
+
+#if 0                           //currently unused
+static poly kBucketGcd (kBucket * b, ring r)
+{
+  int s = 0;
+  int i;
+  poly m, n;
+  BOOLEAN initialized = FALSE;
+  for(i = MAX_BUCKET - 1; i >= 0; i--)
+  {
+    if(b->buckets[i] != NULL)
+    {
+      if(!initialized)
+      {
+        m = gcd_of_terms (b->buckets[i], r);
+        initialized = TRUE;
+        if(m == NULL)
+          return NULL;
+      }
+      else
+      {
+        n = gcd_of_terms (b->buckets[i], r);
+        if(n == NULL)
+        {
+          pDelete (&m);
+          return NULL;
+        }
+        n->next = m;
+        poly t = gcd_of_terms (n, r);
+        n->next = NULL;
+        pDelete (&m);
+        pDelete (&n);
+        m = t;
+        if(m == NULL)
+          return NULL;
+
+      }
+    }
+  }
+  return m;
+}
+#endif
+
+static inline wlen_type quality_of_pos_in_strat_S (int pos, slimgb_alg * c)
+{
+  if(c->strat->lenSw != NULL)
+    return c->strat->lenSw[pos];
+  return c->strat->lenS[pos];
+}
+
+#ifdef HAVE_PLURAL
+static inline wlen_type
+quality_of_pos_in_strat_S_mult_high (int pos, poly high, slimgb_alg * c)
+  //meant only for nc
+{
+  poly m = pOne ();
+  pExpVectorDiff (m, high, c->strat->S[pos]);
+  poly product = nc_mm_Mult_pp (m, c->strat->S[pos], c->r);
+  wlen_type erg = pQuality (product, c);
+  pDelete (&m);
+  pDelete (&product);
+  return erg;
+}
+#endif
+
+static void
+multi_reduction_lls_trick (red_object * los, int /*losl*/, slimgb_alg * c,
+                           find_erg & erg)
+{
+  erg.expand = NULL;
+  BOOLEAN swap_roles;           //from reduce_by, to_reduce_u if fromS
+  if(erg.fromS)
+  {
+    if(pLmEqual (c->strat->S[erg.reduce_by], los[erg.to_reduce_u].p))
+    {
+      wlen_type quality_a = quality_of_pos_in_strat_S (erg.reduce_by, c);
+      int best = erg.to_reduce_u + 1;
+/*
+      for (i=erg.to_reduce_u;i>=erg.to_reduce_l;i--)
+      {
+  int qc=los[i].guess_quality(c);
+  if (qc<quality_a)
+  {
+    best=i;
+    quality_a=qc;
+  }
+      }
+      if(best!=erg.to_reduce_u+1)
+      {*/
+      wlen_type qc;
+      best = find_best (los, erg.to_reduce_l, erg.to_reduce_u, qc, c);
+      if(qc < quality_a)
+      {
+        los[best].flatten ();
+        int b_pos = kBucketCanonicalize (los[best].bucket);
+        los[best].p = los[best].bucket->buckets[b_pos];
+        qc = pQuality (los[best].bucket->buckets[b_pos], c);
+        if(qc < quality_a)
+        {
+          red_object h = los[erg.to_reduce_u];
+          los[erg.to_reduce_u] = los[best];
+          los[best] = h;
+          swap_roles = TRUE;
+        }
+        else
+          swap_roles = FALSE;
+      }
+      else
+      {
+        swap_roles = FALSE;
+      }
+    }
+    else
+    {
+      if(erg.to_reduce_u > erg.to_reduce_l)
+      {
+        wlen_type quality_a = quality_of_pos_in_strat_S (erg.reduce_by, c);
+#ifdef HAVE_PLURAL
+        if((c->nc) && (!(rIsSCA (c->r))))
+          quality_a =
+            quality_of_pos_in_strat_S_mult_high (erg.reduce_by,
+                                                 los[erg.to_reduce_u].p, c);
+#endif
+        int best = erg.to_reduce_u + 1;
+        wlen_type qc;
+        best = find_best (los, erg.to_reduce_l, erg.to_reduce_u, qc, c);
+        assume (qc == los[best].guess_quality (c));
+        if(qc < quality_a)
+        {
+          los[best].flatten ();
+          int b_pos = kBucketCanonicalize (los[best].bucket);
+          los[best].p = los[best].bucket->buckets[b_pos];
+          qc = pQuality (los[best].bucket->buckets[b_pos], c);
+          //(best!=erg.to_reduce_u+1)
+          if(qc < quality_a)
+          {
+            red_object h = los[erg.to_reduce_u];
+            los[erg.to_reduce_u] = los[best];
+            los[best] = h;
+            erg.reduce_by = erg.to_reduce_u;
+            erg.fromS = FALSE;
+            erg.to_reduce_u--;
+          }
+        }
+      }
+      else
+      {
+        assume (erg.to_reduce_u == erg.to_reduce_l);
+        wlen_type quality_a = quality_of_pos_in_strat_S (erg.reduce_by, c);
+        wlen_type qc = los[erg.to_reduce_u].guess_quality (c);
+        if(qc < 0)
+          PrintS ("Wrong wlen_type");
+        if(qc < quality_a)
+        {
+          int best = erg.to_reduce_u;
+          los[best].flatten ();
+          int b_pos = kBucketCanonicalize (los[best].bucket);
+          los[best].p = los[best].bucket->buckets[b_pos];
+          qc = pQuality (los[best].bucket->buckets[b_pos], c);
+          assume (qc >= 0);
+          if(qc < quality_a)
+          {
+            BOOLEAN exp = FALSE;
+            if(qc <= 2)
+            {
+              //Print("\n qc is %lld \n",qc);
+              exp = TRUE;
+            }
+            else
+            {
+              if(qc < quality_a / 2)
+                exp = TRUE;
+              else if(erg.reduce_by < c->n / 4)
+                exp = TRUE;
+            }
+            if(exp)
+            {
+              poly clear_into;
+              los[erg.to_reduce_u].flatten ();
+              kBucketClear (los[erg.to_reduce_u].bucket, &clear_into,
+                            &erg.expand_length);
+              erg.expand = pCopy (clear_into);
+              kBucketInit (los[erg.to_reduce_u].bucket, clear_into,
+                           erg.expand_length);
+              if(TEST_OPT_PROT)
+                PrintS ("e");
+            }
+          }
+        }
+      }
+
+      swap_roles = FALSE;
+      return;
+    }
+  }
+  else
+  {
+    if(erg.reduce_by > erg.to_reduce_u)
+    {
+      //then lm(rb)>= lm(tru) so =
+      assume (erg.reduce_by == erg.to_reduce_u + 1);
+      int best = erg.reduce_by;
+      wlen_type quality_a = los[erg.reduce_by].guess_quality (c);
+      wlen_type qc;
+      best = find_best (los, erg.to_reduce_l, erg.to_reduce_u, qc, c);
+
+      if(qc < quality_a)
+      {
+        red_object h = los[erg.reduce_by];
+        los[erg.reduce_by] = los[best];
+        los[best] = h;
+      }
+      swap_roles = FALSE;
+      return;
+    }
+    else
+    {
+      assume (!pLmEqual (los[erg.reduce_by].p, los[erg.to_reduce_l].p));
+      assume (erg.to_reduce_u == erg.to_reduce_l);
+      //further assume, that reduce_by is the above all other polys
+      //with same leading term
+      int il = erg.reduce_by;
+      wlen_type quality_a = los[erg.reduce_by].guess_quality (c);
+      wlen_type qc;
+      while((il > 0) && pLmEqual (los[il - 1].p, los[il].p))
+      {
+        il--;
+        qc = los[il].guess_quality (c);
+        if(qc < quality_a)
+        {
+          quality_a = qc;
+          erg.reduce_by = il;
+        }
+      }
+      swap_roles = FALSE;
+    }
+  }
+  if(swap_roles)
+  {
+    if(TEST_OPT_PROT)
+      PrintS ("b");
+    poly clear_into;
+    int new_length;
+    int bp = erg.to_reduce_u;   //bucket_positon
+    //kBucketClear(los[bp].bucket,&clear_into,&new_length);
+    new_length = los[bp].clear_to_poly ();
+    clear_into = los[bp].p;
+    poly p = c->strat->S[erg.reduce_by];
+    int j = erg.reduce_by;
+    int old_length = c->strat->lenS[j]; // in view of S
+    los[bp].p = p;
+    kBucketInit (los[bp].bucket, p, old_length);
+    wlen_type qal = pQuality (clear_into, c, new_length);
+    int pos_in_c = -1;
+    int z;
+    int new_pos;
+    new_pos = simple_posInS (c->strat, clear_into, new_length, qal);
+    assume (new_pos <= j);
+    for(z = c->n; z; z--)
+    {
+      if(p == c->S->m[z - 1])
+      {
+        pos_in_c = z - 1;
+        break;
+      }
+    }
+
+    int tdeg_full = -1;
+    int tdeg = -1;
+    if(pos_in_c >= 0)
+    {
+#ifdef TGB_RESORT_PAIRS
+      c->used_b = TRUE;
+      c->replaced[pos_in_c] = TRUE;
+#endif
+      tdeg = c->T_deg[pos_in_c];
+      c->S->m[pos_in_c] = clear_into;
+      c->lengths[pos_in_c] = new_length;
+      c->weighted_lengths[pos_in_c] = qal;
+      if(c->gcd_of_terms[pos_in_c] == NULL)
+        c->gcd_of_terms[pos_in_c] = gcd_of_terms (clear_into, c->r);
+      if(c->T_deg_full)
+        tdeg_full = c->T_deg_full[pos_in_c] =
+          c->pTotaldegree_full (clear_into);
+      else
+        tdeg_full = tdeg;
+      c_S_element_changed_hook (pos_in_c, c);
+    }
+    else
+    {
+      if(c->eliminationProblem)
+      {
+        tdeg_full = c->pTotaldegree_full (clear_into);
+        tdeg = c->pTotaldegree (clear_into);
+      }
+    }
+    c->strat->S[j] = clear_into;
+    c->strat->lenS[j] = new_length;
+
+    assume (pLength (clear_into) == new_length);
+    if(c->strat->lenSw != NULL)
+      c->strat->lenSw[j] = qal;
+    if(!rField_is_Zp (c->r))
+    {
+      p_Cleardenom (clear_into, c->r);  //should be unnecessary
+      //p_Content(clear_into, c->r);
+    }
+    else
+      pNorm (clear_into);
+#ifdef FIND_DETERMINISTIC
+    erg.reduce_by = j;
+    //resort later see diploma thesis, find_in_S must be deterministic
+    //during multireduction if spolys are only in the span of the
+    //input polys
+#else
+    if(new_pos < j)
+    {
+      if(c->strat->honey)
+        c->strat->ecartS[j] = tdeg_full - tdeg;
+      move_forward_in_S (j, new_pos, c->strat);
+      erg.reduce_by = new_pos;
+    }
+#endif
+  }
+}
+
+static int fwbw (red_object * los, int i)
+{
+  int i2 = i;
+  int step = 1;
+
+  BOOLEAN bw = FALSE;
+  BOOLEAN incr = TRUE;
+
+  while(1)
+  {
+    if(!bw)
+    {
+      step = si_min (i2, step);
+      if(step == 0)
+        break;
+      i2 -= step;
+
+      if(!pLmEqual (los[i].p, los[i2].p))
+      {
+        bw = TRUE;
+        incr = FALSE;
+      }
+      else
+      {
+        if((!incr) && (step == 1))
+          break;
+      }
+    }
+    else
+    {
+      step = si_min (i - i2, step);
+      if(step == 0)
+        break;
+      i2 += step;
+      if(pLmEqual (los[i].p, los[i2].p))
+      {
+        if(step == 1)
+          break;
+        else
+        {
+          bw = FALSE;
+        }
+      }
+    }
+    if(incr)
+      step *= 2;
+    else
+    {
+      if(step % 2 == 1)
+        step = (step + 1) / 2;
+      else
+        step /= 2;
+    }
+  }
+  return i2;
+}
+
+static void
+canonicalize_region (red_object * los, int l, int u, slimgb_alg * /*c*/)
+{
+  assume (l <= u + 1);
+  int i;
+  for(i = l; i <= u; i++)
+  {
+    kBucketCanonicalize (los[i].bucket);
+  }
+}
+
+#ifdef SING_NDEBUG
+static void
+multi_reduction_find (red_object * los, int /*losl*/, slimgb_alg * c, int startf,
+                      find_erg & erg)
+#else
+static void
+multi_reduction_find (red_object * los, int losl, slimgb_alg * c, int startf,
+                      find_erg & erg)
+#endif
+{
+  kStrategy strat = c->strat;
+
+  assume (startf <= losl);
+  assume ((startf == losl - 1)
+          || (pLmCmp (los[startf].p, los[startf + 1].p) == -1));
+  int i = startf;
+
+  int j;
+  while(i >= 0)
+  {
+    assume ((i == losl - 1) || (pLmCmp (los[i].p, los[i + 1].p) <= 0));
+    assume (is_valid_ro (los[i]));
+    j = kFindDivisibleByInS_easy (strat, los[i]);
+    if(j >= 0)
+    {
+      erg.to_reduce_u = i;
+      erg.reduce_by = j;
+      erg.fromS = TRUE;
+      int i2 = fwbw (los, i);
+      assume (pLmEqual (los[i].p, los[i2].p));
+      assume ((i2 == 0) || (!pLmEqual (los[i2].p, los[i2 - 1].p)));
+      assume (i >= i2);
+
+      erg.to_reduce_l = i2;
+      assume ((i == losl - 1) || (pLmCmp (los[i].p, los[i + 1].p) == -1));
+      canonicalize_region (los, erg.to_reduce_u + 1, startf, c);
+      return;
+    }
+    if(j < 0)
+    {
+      //not reduceable, try to use this for reducing higher terms
+      int i2 = fwbw (los, i);
+      assume (pLmEqual (los[i].p, los[i2].p));
+      assume ((i2 == 0) || (!pLmEqual (los[i2].p, los[i2 - 1].p)));
+      assume (i >= i2);
+      if(i2 != i)
+      {
+        erg.to_reduce_u = i - 1;
+        erg.to_reduce_l = i2;
+        erg.reduce_by = i;
+        erg.fromS = FALSE;
+        assume ((i == losl - 1) || (pLmCmp (los[i].p, los[i + 1].p) == -1));
+        canonicalize_region (los, erg.to_reduce_u + 1, startf, c);
+        return;
+      }
+      i--;
+    }
+  }
+  erg.reduce_by = -1;           //error code
+  return;
+}
+
+ //  nicht reduzierbare eintraege in ergebnisliste schreiben
+//   nullen loeschen
+//   while(finde_groessten leitterm reduzierbar(c,erg))
+//   {
+
+static int
+multi_reduction_clear_zeroes (red_object * los, int losl, int l, int u)
+{
+  int deleted = 0;
+  int i = l;
+  int last = -1;
+  while(i <= u)
+  {
+    if(los[i].p == NULL)
+    {
+      kBucketDestroy (&los[i].bucket);
+//      delete los[i];//here we assume los are constructed with new
+      //destroy resources, must be added here
+      if(last >= 0)
+      {
+        memmove (los + (int) (last + 1 - deleted), los + (last + 1),
+                 sizeof (red_object) * (i - 1 - last));
+      }
+      last = i;
+      deleted++;
+    }
+    i++;
+  }
+  if((last >= 0) && (last != losl - 1))
+    memmove (los + (int) (last + 1 - deleted), los + last + 1,
+             sizeof (red_object) * (losl - 1 - last));
+  return deleted;
+}
+
+int search_red_object_pos (red_object * a, int top, red_object * key)
+{
+  int an = 0;
+  int en = top;
+  if(top == -1)
+    return 0;
+  if(pLmCmp (key->p, a[top].p) == 1)
+    return top + 1;
+  int i;
+  loop
+  {
+    if(an >= en - 1)
+    {
+      if(pLmCmp (key->p, a[an].p) == -1)
+        return an;
+      return en;
+    }
+    i = (an + en) / 2;
+    if(pLmCmp (key->p, a[i].p) == -1)
+      en = i;
+    else
+      an = i;
+  }
+}
+
+static void sort_region_down (red_object * los, int l, int u, slimgb_alg * /*c*/)
+{
+  int r_size = u - l + 1;
+  qsort (los + l, r_size, sizeof (red_object), red_object_better_gen);
+  int i;
+  int *new_indices = (int *) omalloc ((r_size) * sizeof (int));
+  int bound = 0;
+  BOOLEAN at_end = FALSE;
+  for(i = l; i <= u; i++)
+  {
+    if(!(at_end))
+    {
+      bound = new_indices[i - l] =
+        bound + search_red_object_pos (los + bound, l - bound - 1, los + i);
+      if(bound == l)
+        at_end = TRUE;
+    }
+    else
+    {
+      new_indices[i - l] = l;
+    }
+  }
+  red_object *los_region =
+    (red_object *) omalloc (sizeof (red_object) * (u - l + 1));
+  for(int i = 0; i < r_size; i++)
+  {
+    new_indices[i] += i;
+    los_region[i] = los[l + i];
+    assume ((i == 0) || (new_indices[i] > new_indices[i - 1]));
+  }
+
+  i = r_size - 1;
+  int j = u;
+  int j2 = l - 1;
+  while(i >= 0)
+  {
+    if(new_indices[i] == j)
+    {
+      los[j] = los_region[i];
+      i--;
+      j--;
+    }
+    else
+    {
+      assume (new_indices[i] < j);
+      los[j] = los[j2];
+      assume (j2 >= 0);
+      j2--;
+      j--;
+    }
+  }
+  omfree (los_region);
+  omfree (new_indices);
+}
+
+//assume that los is ordered ascending by leading term, all non zero
+static void multi_reduction (red_object * los, int &losl, slimgb_alg * c)
+{
+  poly *delay = (poly *) omalloc (losl * sizeof (poly));
+  int delay_s = 0;
+  //initialize;
+  assume (c->strat->sl >= 0);
+  assume (losl > 0);
+  int i;
+  wlen_type max_initial_quality = 0;
+
+  for(i = 0; i < losl; i++)
+  {
+    los[i].sev = pGetShortExpVector (los[i].p);
+//SetShortExpVector();
+    los[i].p = kBucketGetLm (los[i].bucket);
+    if(los[i].initial_quality > max_initial_quality)
+      max_initial_quality = los[i].initial_quality;
+    // else
+//         Print("init2_qal=%lld;", los[i].initial_quality);
+//     Print("initial_quality=%lld;",max_initial_quality);
+  }
+
+  int curr_pos = losl - 1;
+
+//  nicht reduzierbare eintr�e in ergebnisliste schreiben
+  // nullen loeschen
+  while(curr_pos >= 0)
+  {
+    if((c->use_noro_last_block)
+       && (lies_in_last_dp_block (los[curr_pos].p, c)))
+    {
+      int pn_noro = curr_pos + 1;
+      poly *p_noro = (poly *) omalloc (pn_noro * sizeof (poly));
+      for(i = 0; i < pn_noro; i++)
+      {
+        int dummy_len;
+        poly p;
+        los[i].p = NULL;
+        kBucketClear (los[i].bucket, &p, &dummy_len);
+        p_noro[i] = p;
+      }
+      if(n_GetChar(currRing->cf) < 255)
+      {
+        noro_step < tgb_uint8 > (p_noro, pn_noro, c);
+      }
+      else
+      {
+        if(n_GetChar(currRing->cf) < 65000)
+        {
+          noro_step < tgb_uint16 > (p_noro, pn_noro, c);
+        }
+        else
+        {
+          noro_step < tgb_uint32 > (p_noro, pn_noro, c);
+        }
+      }
+      for(i = 0; i < pn_noro; i++)
+      {
+        los[i].p = p_noro[i];
+        los[i].sev = pGetShortExpVector (los[i].p);
+        //ignore quality
+        kBucketInit (los[i].bucket, los[i].p, pLength (los[i].p));
+      }
+      qsort (los, pn_noro, sizeof (red_object), red_object_better_gen);
+      int deleted =
+        multi_reduction_clear_zeroes (los, losl, pn_noro, curr_pos);
+      losl -= deleted;
+      curr_pos -= deleted;
+      break;
+    }
+    find_erg erg;
+
+    multi_reduction_find (los, losl, c, curr_pos, erg); //last argument should be curr_pos
+    if(erg.reduce_by < 0)
+      break;
+
+    erg.expand = NULL;
+
+    multi_reduction_lls_trick (los, losl, c, erg);
+
+    int i;
+    //    wrp(los[erg.to_reduce_u].p);
+    //PrintLn();
+    multi_reduce_step (erg, los, c);
+
+
+    if(!TEST_OPT_REDTHROUGH)
+    {
+      for(i = erg.to_reduce_l; i <= erg.to_reduce_u; i++)
+      {
+        if(los[i].p != NULL)    //the check (los[i].p!=NULL) might be invalid
+        {
+          //
+          assume (los[i].initial_quality > 0);
+          if(los[i].guess_quality (c)
+             > 1.5 * delay_factor * max_initial_quality)
+          {
+            if(TEST_OPT_PROT)
+              PrintS ("v");
+            los[i].canonicalize ();
+            if(los[i].guess_quality (c) > delay_factor * max_initial_quality)
+            {
+              if(TEST_OPT_PROT)
+                PrintS (".");
+              los[i].clear_to_poly ();
+              //delay.push_back(los[i].p);
+              delay[delay_s] = los[i].p;
+              delay_s++;
+              los[i].p = NULL;
+            }
+          }
+        }
+      }
+    }
+    int deleted = multi_reduction_clear_zeroes (los, losl, erg.to_reduce_l,
+                                                erg.to_reduce_u);
+    if(erg.fromS == FALSE)
+      curr_pos = si_max (erg.to_reduce_u, erg.reduce_by);
+    else
+      curr_pos = erg.to_reduce_u;
+    losl -= deleted;
+    curr_pos -= deleted;
+
+    //Print("deleted %i \n",deleted);
+    if((TEST_V_UPTORADICAL) && (!(erg.fromS)))
+      sort_region_down (los, si_min (erg.to_reduce_l, erg.reduce_by),
+                        (si_max (erg.to_reduce_u, erg.reduce_by)) - deleted,
+                        c);
+    else
+      sort_region_down (los, erg.to_reduce_l, erg.to_reduce_u - deleted, c);
+
+    if(erg.expand)
+    {
+#ifdef FIND_DETERMINISTIC
+      int i;
+      for(i = 0; c->expandS[i]; i++) ;
+      c->expandS = (poly *) omrealloc (c->expandS, (i + 2) * sizeof (poly));
+      c->expandS[i] = erg.expand;
+      c->expandS[i + 1] = NULL;
+#else
+      int ecart = 0;
+      if(c->eliminationProblem)
+      {
+        ecart =
+          c->pTotaldegree_full (erg.expand) - c->pTotaldegree (erg.expand);
+      }
+      add_to_reductors (c, erg.expand, erg.expand_length, ecart);
+#endif
+    }
+  }
+
+  //sorted_pair_node** pairs=(sorted_pair_node**)
+  //  omalloc(delay_s*sizeof(sorted_pair_node*));
+  c->introduceDelayedPairs (delay, delay_s);
+  /*
+     for(i=0;i<delay_s;i++)
+     {
+     poly p=delay[i];
+     //if (rPar(c->r)==0)
+     simplify_poly(p,c->r);
+     sorted_pair_node* si=(sorted_pair_node*) omalloc(sizeof(sorted_pair_node));
+     si->i=-1;
+     si->j=-1;
+     if (!rField_is_Zp(c->r))
+     {
+     if (!c->nc)
+     p=redTailShort(p, c->strat);
+     p_Cleardenom(p, c->r);
+     p_Content(p, c->r);
+     }
+     si->expected_length=pQuality(p,c,pLength(p));
+     si->deg=pTotaldegree(p);
+     si->lcm_of_lm=p;
+     pairs[i]=si;
+     }
+     qsort(pairs,delay_s,sizeof(sorted_pair_node*),tgb_pair_better_gen2);
+     c->apairs=spn_merge(c->apairs,c->pair_top+1,pairs,delay_s,c);
+     c->pair_top+=delay_s; */
+  omfree (delay);
+  //omfree(pairs);
+  return;
+}
+
+void red_object::flatten ()
+{
+  assume (p == kBucketGetLm (bucket));
+}
+
+void red_object::validate ()
+{
+  p = kBucketGetLm (bucket);
+  if(p)
+    sev = pGetShortExpVector (p);
+}
+
+int red_object::clear_to_poly ()
+{
+  flatten ();
+  int l;
+  kBucketClear (bucket, &p, &l);
+  return l;
+}
+
+void reduction_step::reduce (red_object * /*r*/, int /*l*/, int /*u*/)
+{
+}
+
+void simple_reducer::do_reduce (red_object & ro)
+{
+  number coef;
+#ifdef HAVE_PLURAL
+  if(c->nc)
+    nc_BucketPolyRed_Z (ro.bucket, p, &coef);
+  else
+#endif
+    coef = kBucketPolyRed (ro.bucket, p, p_len, c->strat->kNoether);
+  nDelete (&coef);
+}
+
+void simple_reducer::reduce (red_object * r, int l, int u)
+{
+  this->pre_reduce (r, l, u);
+  int i;
+//debug start
+
+  if(c->eliminationProblem)
+  {
+    assume (p_LmEqual (r[l].p, r[u].p, c->r));
+    /*int lm_deg=pTotaldegree(r[l].p);
+       reducer_deg=lm_deg+pTotaldegree_full(p)-pTotaldegree(p); */
+  }
+
+  for(i = l; i <= u; i++)
+  {
+    this->do_reduce (r[i]);
+  }
+  for(i = l; i <= u; i++)
+  {
+    kBucketSimpleContent (r[i].bucket);
+    r[i].validate ();
+#ifdef TGB_DEBUG
+#endif
+  }
+}
+
+reduction_step::~reduction_step ()
+{
+}
+
+simple_reducer::~simple_reducer ()
+{
+  if(fill_back != NULL)
+  {
+    kBucketInit (fill_back, p, p_len);
+  }
+  fill_back = NULL;
+}
+
+void multi_reduce_step (find_erg & erg, red_object * r, slimgb_alg * c)
+{
+  static int id = 0;
+  id++;
+  unsigned long sev;
+  BOOLEAN lt_changed = FALSE;
+  int rn = erg.reduce_by;
+  poly red;
+  int red_len;
+  simple_reducer *pointer;
+  BOOLEAN work_on_copy = FALSE;
+  if(erg.fromS)
+  {
+    red = c->strat->S[rn];
+    red_len = c->strat->lenS[rn];
+    assume (red_len == pLength (red));
+  }
+  else
+  {
+    r[rn].flatten ();
+    kBucketClear (r[rn].bucket, &red, &red_len);
+
+    if(!rField_is_Zp (c->r))
+    {
+      p_Cleardenom (red, c->r); //should be unnecessary
+      //p_Content(red, c->r);
+    }
+    pNormalize (red);
+
+    if((!(erg.fromS)) && (TEST_V_UPTORADICAL))
+    {
+      if(polynomial_root (red, c->r))
+        lt_changed = TRUE;
+      sev = p_GetShortExpVector (red, c->r);
+    }
+    red_len = pLength (red);
+  }
+  if(((TEST_V_MODPSOLVSB) && (red_len > 1))
+     || ((c->nc) || (erg.to_reduce_u - erg.to_reduce_l > 5)))
+  {
+    work_on_copy = TRUE;
+    // poly m=pOne();
+    poly m = c->tmp_lm;
+    pSetCoeff (m, nInit (1));
+    pSetComp (m, 0);
+    for(int i = 1; i <= (currRing->N); i++)
+      pSetExp (m, i, (pGetExp (r[erg.to_reduce_l].p, i) - pGetExp (red, i)));
+    pSetm (m);
+    poly red_cp;
+#ifdef HAVE_PLURAL
+    if(c->nc)
+      red_cp = nc_mm_Mult_pp (m, red, c->r);
+    else
+#endif
+      red_cp = ppMult_mm (red, m);
+    if(!erg.fromS)
+    {
+      kBucketInit (r[rn].bucket, red, red_len);
+    }
+    //now reduce the copy
+    //static poly redNF2 (poly h,slimgb_alg* c , int &len, number&  m,int n)
+
+    if(!c->nc)
+      redTailShort (red_cp, c->strat);
+    //number mul;
+    // red_len--;
+//     red_cp->next=redNF2(red_cp->next,c,red_len,mul,c->average_length);
+//     pSetCoeff(red_cp,nMult(red_cp->coef,mul));
+//     nDelete(&mul);
+//     red_len++;
+    red = red_cp;
+    red_len = pLength (red);
+    // pDelete(&m);
+  }
+
+  assume (red_len == pLength (red));
+
+  int reducer_deg = 0;
+  if(c->eliminationProblem)
+  {
+    int lm_deg = c->pTotaldegree (r[erg.to_reduce_l].p);
+    int ecart;
+    if(erg.fromS)
+    {
+      ecart = c->strat->ecartS[erg.reduce_by];
+    }
+    else
+    {
+      ecart = c->pTotaldegree_full (red) - lm_deg;
+    }
+    reducer_deg = lm_deg + ecart;
+  }
+  pointer = new simple_reducer (red, red_len, reducer_deg, c);
+
+  if((!work_on_copy) && (!erg.fromS))
+    pointer->fill_back = r[rn].bucket;
+  else
+    pointer->fill_back = NULL;
+  pointer->reduction_id = id;
+  pointer->c = c;
+
+  pointer->reduce (r, erg.to_reduce_l, erg.to_reduce_u);
+  if(work_on_copy)
+    pDelete (&pointer->p);
+  delete pointer;
+  if(lt_changed)
+  {
+    assume (!erg.fromS);
+    r[erg.reduce_by].sev = sev;
+  }
+}
+
+void simple_reducer::pre_reduce (red_object * /*r*/, int /*l*/, int /*u*/)
+{
+}
+
+#if 0
+template int pos_helper<int, int*>(skStrategy*, spolyrec*, int, int*, spolyrec**);
+template int pos_helper<long, long*>(skStrategy*, spolyrec*, long, long*, spolyrec**);
+
+template void noro_step<unsigned char>(spolyrec**, int&, slimgb_alg*);
+template void noro_step<unsigned int>(spolyrec**, int&, slimgb_alg*);
+template void noro_step<unsigned short>(spolyrec**, int&, slimgb_alg*);
+
+
+template int term_nodes_sort_crit<unsigned char>(void const*, void const*);
+template int term_nodes_sort_crit<unsigned int>(void const*, void const*);
+template int term_nodes_sort_crit<unsigned short>(void const*, void const*);
+
+template spolyrec* row_to_poly<unsigned char>(unsigned char*, spolyrec**, int, ip_sring*);
+template spolyrec* row_to_poly<unsigned int>(unsigned int*, spolyrec**, int, ip_sring*);
+template spolyrec* row_to_poly<unsigned short>(unsigned short*, spolyrec**, int, ip_sring*);
+
+template void simplest_gauss_modp<unsigned char>(unsigned char*, int, int);
+template void simplest_gauss_modp<unsigned int>(unsigned int*, int, int);
+template void simplest_gauss_modp<unsigned short>(unsigned short*, int, int);
+
+
+template int modP_lastIndexRow<unsigned char>(unsigned char*, int);
+template int modP_lastIndexRow<unsigned int>(unsigned int*, int);
+template int modP_lastIndexRow<unsigned short>(unsigned short*, int);
+
+template SparseRow<unsigned char>* noro_red_to_non_poly_t<unsigned char>(spolyrec*, int&, NoroCache<unsigned char>*, slimgb_alg*);
+template SparseRow<unsigned int>* noro_red_to_non_poly_t<unsigned int>(spolyrec*, int&, NoroCache<unsigned int>*, slimgb_alg*);
+template SparseRow<unsigned short>* noro_red_to_non_poly_t<unsigned short>(spolyrec*, int&, NoroCache<unsigned short>*, slimgb_alg*);
+
+
+template MonRedResNP<unsigned char> noro_red_mon_to_non_poly<unsigned char>(spolyrec*, NoroCache<unsigned char>*, slimgb_alg*);
+template MonRedResNP<unsigned int> noro_red_mon_to_non_poly<unsigned int>(spolyrec*, NoroCache<unsigned int>*, slimgb_alg*);
+template MonRedResNP<unsigned short> noro_red_mon_to_non_poly<unsigned short>(spolyrec*, NoroCache<unsigned short>*, slimgb_alg*);
+
+template SparseRow<unsigned char>* noro_red_to_non_poly_dense<unsigned char>(MonRedResNP<unsigned char>*, int, NoroCache<unsigned char>*);
+template SparseRow<unsigned char>* noro_red_to_non_poly_sparse<unsigned char>(MonRedResNP<unsigned char>*, int, NoroCache<unsigned char>*);
+template SparseRow<unsigned int>* noro_red_to_non_poly_dense<unsigned int>(MonRedResNP<unsigned int>*, int, NoroCache<unsigned int>*);
+template SparseRow<unsigned int>* noro_red_to_non_poly_sparse<unsigned int>(MonRedResNP<unsigned int>*, int, NoroCache<unsigned int>*);
+template SparseRow<unsigned short>* noro_red_to_non_poly_dense<unsigned short>(MonRedResNP<unsigned short>*, int, NoroCache<unsigned short>*);
+template SparseRow<unsigned short>* noro_red_to_non_poly_sparse<unsigned short>(MonRedResNP<unsigned short>*, int, NoroCache<unsigned short>*);
+
+
+
+template class DataNoroCacheNode<unsigned char>;
+template class DataNoroCacheNode<unsigned int>;
+template class DataNoroCacheNode<unsigned short>;
+
+template class NoroCache<unsigned char>;
+template class NoroCache<unsigned int>;
+template class NoroCache<unsigned short>;
+
+
+
+template void add_coef_times_dense<unsigned char>(unsigned char*, int, unsigned char const*, int, snumber*);
+template void add_coef_times_dense<unsigned int>(unsigned int*, int, unsigned int const*, int, snumber*);
+template void add_coef_times_dense<unsigned short>(unsigned short*, int, unsigned short const*, int, snumber*);
+template void add_coef_times_sparse<unsigned char>(unsigned char*, int, SparseRow<unsigned char>*, snumber*);
+template void add_coef_times_sparse<unsigned int>(unsigned int*, int, SparseRow<unsigned int>*, snumber*);
+template void add_coef_times_sparse<unsigned short>(unsigned short*, int, SparseRow<unsigned short>*, snumber*);
+template void add_dense<unsigned char>(unsigned char*, int, unsigned char const*, int);
+template void add_dense<unsigned int>(unsigned int*, int, unsigned int const*, int);
+template void add_dense<unsigned short>(unsigned short*, int, unsigned short const*, int);
+template void add_sparse<unsigned char>(unsigned char*, int, SparseRow<unsigned char>*);
+template void add_sparse<unsigned int>(unsigned int*, int, SparseRow<unsigned int>*);
+template void add_sparse<unsigned short>(unsigned short*, int, SparseRow<unsigned short>*);
+
+
+template void sub_dense<unsigned char>(unsigned char*, int, unsigned char const*, int);
+template void sub_dense<unsigned int>(unsigned int*, int, unsigned int const*, int);
+template void sub_dense<unsigned short>(unsigned short*, int, unsigned short const*, int);
+template void sub_sparse<unsigned char>(unsigned char*, int, SparseRow<unsigned char>*);
+template void sub_sparse<unsigned int>(unsigned int*, int, SparseRow<unsigned int>*);
+template void sub_sparse<unsigned short>(unsigned short*, int, SparseRow<unsigned short>*);
+template void write_coef_idx_to_buffer_dense<unsigned char>(CoefIdx<unsigned char>*, int&, unsigned char*, int);
+template void write_coef_idx_to_buffer_dense<unsigned int>(CoefIdx<unsigned int>*, int&, unsigned int*, int);
+template void write_coef_idx_to_buffer_dense<unsigned short>(CoefIdx<unsigned short>*, int&, unsigned short*, int);
+template void write_coef_idx_to_buffer<unsigned char>(CoefIdx<unsigned char>*, int&, int*, unsigned char*, int);
+template void write_coef_idx_to_buffer<unsigned int>(CoefIdx<unsigned int>*, int&, int*, unsigned int*, int);
+template void write_coef_idx_to_buffer<unsigned short>(CoefIdx<unsigned short>*, int&, int*, unsigned short*, int);
+template void write_coef_times_xx_idx_to_buffer_dense<unsigned char>(CoefIdx<unsigned char>*, int&, unsigned char*, int, snumber*);
+template void write_coef_times_xx_idx_to_buffer_dense<unsigned int>(CoefIdx<unsigned int>*, int&, unsigned int*, int, snumber*);
+template void write_coef_times_xx_idx_to_buffer_dense<unsigned short>(CoefIdx<unsigned short>*, int&, unsigned short*, int, snumber*);
+template void write_coef_times_xx_idx_to_buffer<unsigned char>(CoefIdx<unsigned char>*, int&, int*, unsigned char*, int, snumber*);
+template void write_coef_times_xx_idx_to_buffer<unsigned int>(CoefIdx<unsigned int>*, int&, int*, unsigned int*, int, snumber*);
+template void write_coef_times_xx_idx_to_buffer<unsigned short>(CoefIdx<unsigned short>*, int&, int*, unsigned short*, int, snumber*);
+template void write_minus_coef_idx_to_buffer_dense<unsigned char>(CoefIdx<unsigned char>*, int&, unsigned char*, int);
+template void write_minus_coef_idx_to_buffer_dense<unsigned int>(CoefIdx<unsigned int>*, int&, unsigned int*, int);
+template void write_minus_coef_idx_to_buffer_dense<unsigned short>(CoefIdx<unsigned short>*, int&, unsigned short*, int);
+template void write_minus_coef_idx_to_buffer<unsigned char>(CoefIdx<unsigned char>*, int&, int*, unsigned char*, int);
+template void write_minus_coef_idx_to_buffer<unsigned int>(CoefIdx<unsigned int>*, int&, int*, unsigned int*, int);
+template void write_minus_coef_idx_to_buffer<unsigned short>(CoefIdx<unsigned short>*, int&, int*, unsigned short*, int);
+
+
+template class std::vector<DataNoroCacheNode<unsigned char>*>;
+template class std::vector<DataNoroCacheNode<unsigned int>*>;
+template class std::vector<DataNoroCacheNode<unsigned short>*>;
+template class std::vector<PolySimple>;
+
+template void std::sort( CoefIdx<unsigned char>* , CoefIdx<unsigned char>*  );
+template void std::sort( CoefIdx<unsigned int>*  , CoefIdx<unsigned int>*   );
+template void std::sort( CoefIdx<unsigned short>*, CoefIdx<unsigned short>* );
+
+template void std::sort_heap<CoefIdx<unsigned char>*>(CoefIdx<unsigned char>*, CoefIdx<unsigned char>*);
+template void std::sort_heap<CoefIdx<unsigned int>*>(CoefIdx<unsigned int>*, CoefIdx<unsigned int>*);
+template void std::sort_heap<CoefIdx<unsigned short>*>(CoefIdx<unsigned short>*, CoefIdx<unsigned short>*);
+
+template void std::make_heap<CoefIdx<unsigned char>*>(CoefIdx<unsigned char>*, CoefIdx<unsigned char>*);
+template void std::make_heap<CoefIdx<unsigned int>*>(CoefIdx<unsigned int>*, CoefIdx<unsigned int>*);
+template void std::make_heap<CoefIdx<unsigned short>*>(CoefIdx<unsigned short>*, CoefIdx<unsigned short>*);
+#endif
+
+#if 0
+template void std::__final_insertion_sort<CoefIdx<unsigned char>*>(CoefIdx<unsigned char>*, CoefIdx<unsigned char>*);
+template void std::__final_insertion_sort<CoefIdx<unsigned int>*>(CoefIdx<unsigned int>*, CoefIdx<unsigned int>*);
+template void std::__final_insertion_sort<CoefIdx<unsigned short>*>(CoefIdx<unsigned short>*, CoefIdx<unsigned short>*);
+
+template void std::__introsort_loop<CoefIdx<unsigned char>*, long>(CoefIdx<unsigned char>*, CoefIdx<unsigned char>*, long);
+template void std::__introsort_loop<CoefIdx<unsigned int>*, long>(CoefIdx<unsigned int>*, CoefIdx<unsigned int>*, long);
+template void std::__introsort_loop<CoefIdx<unsigned short>*, long>(CoefIdx<unsigned short>*, CoefIdx<unsigned short>*, long);
+
+template void std::__heap_select<CoefIdx<unsigned char>*>(CoefIdx<unsigned char>*, CoefIdx<unsigned char>*, CoefIdx<unsigned char>*);
+template void std::__heap_select<CoefIdx<unsigned int>*>(CoefIdx<unsigned int>*, CoefIdx<unsigned int>*, CoefIdx<unsigned int>*);
+template void std::__heap_select<CoefIdx<unsigned short>*>(CoefIdx<unsigned short>*, CoefIdx<unsigned short>*, CoefIdx<unsigned short>*);
+
+template void std::__insertion_sort<CoefIdx<unsigned char>*>(CoefIdx<unsigned char>*, CoefIdx<unsigned char>*);
+template void std::__insertion_sort<CoefIdx<unsigned int>*>(CoefIdx<unsigned int>*, CoefIdx<unsigned int>*);
+template void std::__insertion_sort<CoefIdx<unsigned short>*>(CoefIdx<unsigned short>*, CoefIdx<unsigned short>*);
+
+template void std::__move_median_first<CoefIdx<unsigned char>*>(CoefIdx<unsigned char>*, CoefIdx<unsigned char>*, CoefIdx<unsigned char>*);
+template void std::__move_median_first<CoefIdx<unsigned int>*>(CoefIdx<unsigned int>*, CoefIdx<unsigned int>*, CoefIdx<unsigned int>*);
+template void std::__move_median_first<CoefIdx<unsigned short>*>(CoefIdx<unsigned short>*, CoefIdx<unsigned short>*, CoefIdx<unsigned short>*);
+
+template void std::__unguarded_linear_insert<CoefIdx<unsigned char>*>(CoefIdx<unsigned char>*);
+template void std::__unguarded_linear_insert<CoefIdx<unsigned int>*>(CoefIdx<unsigned int>*);
+template void std::__unguarded_linear_insert<CoefIdx<unsigned short>*>(CoefIdx<unsigned short>*);
+
+template void std::__adjust_heap<CoefIdx<unsigned char>*, long, CoefIdx<unsigned char> >(CoefIdx<unsigned char>*, long, long, CoefIdx<unsigned char>);
+template void std::__adjust_heap<CoefIdx<unsigned int>*, long, CoefIdx<unsigned int> >(CoefIdx<unsigned int>*, long, long, CoefIdx<unsigned int>);
+template void std::__adjust_heap<CoefIdx<unsigned short>*, long, CoefIdx<unsigned short> >(CoefIdx<unsigned short>*, long, long, CoefIdx<unsigned short>);
+
+template void std::__push_heap<CoefIdx<unsigned char>*, long, CoefIdx<unsigned char> >(CoefIdx<unsigned char>*, long, long, CoefIdx<unsigned char>);
+template void std::__push_heap<CoefIdx<unsigned int>*, long, CoefIdx<unsigned int> >(CoefIdx<unsigned int>*, long, long, CoefIdx<unsigned int>);
+template void std::__push_heap<CoefIdx<unsigned short>*, long, CoefIdx<unsigned short> >(CoefIdx<unsigned short>*, long, long, CoefIdx<unsigned short>);
+
+template CoefIdx<unsigned char>* std::__unguarded_partition<CoefIdx<unsigned char>*, CoefIdx<unsigned char> >(CoefIdx<unsigned char>*, CoefIdx<unsigned char>*, CoefIdx<unsigned char> const&);
+template CoefIdx<unsigned int>* std::__unguarded_partition<CoefIdx<unsigned int>*, CoefIdx<unsigned int> >(CoefIdx<unsigned int>*, CoefIdx<unsigned int>*, CoefIdx<unsigned int> const&);
+template CoefIdx<unsigned short>* std::__unguarded_partition<CoefIdx<unsigned short>*, CoefIdx<unsigned short> >(CoefIdx<unsigned short>*, CoefIdx<unsigned short>*, CoefIdx<unsigned short> const&);
+
+#endif
+
diff --git a/kernel/GBEngine/tgb.h b/kernel/GBEngine/tgb.h
new file mode 100644
index 0000000..bb648ed
--- /dev/null
+++ b/kernel/GBEngine/tgb.h
@@ -0,0 +1,21 @@
+#ifndef TGB_H
+#define TGB_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: trepgb interface
+*/
+
+//! \file tgb.h
+//#define OM_CHECK 3
+//#define OM_TRACK 5
+
+#include <polys/monomials/ring.h>
+
+#include <kernel/structs.h>
+
+
+
+ideal t_rep_gb(ring r,ideal arg_I, int syz_comp, BOOLEAN F4_mode=FALSE);
+#endif
diff --git a/kernel/GBEngine/tgb_internal.h b/kernel/GBEngine/tgb_internal.h
new file mode 100644
index 0000000..c37ea03
--- /dev/null
+++ b/kernel/GBEngine/tgb_internal.h
@@ -0,0 +1,1960 @@
+#ifndef TGB_INTERNAL_H
+#define TGB_INTERNAL_H
+//!\file tgb_internal.h
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+ * ABSTRACT: tgb internal .h file
+*/
+#define USE_NORO 1
+
+#include <omalloc/omalloc.h>
+
+//#define TGB_DEBUG
+#define FULLREDUCTIONS
+#define HANS_IDEA
+//#define HALFREDUCTIONS
+//#define HEAD_BIN
+//#define HOMOGENEOUS_EXAMPLE
+#define REDTAIL_S
+#define PAR_N 100
+#define PAR_N_F4 5000
+#define AC_NEW_MIN 2
+#define AC_FLATTEN 1
+
+//#define FIND_DETERMINISTIC
+//#define REDTAIL_PROT
+//#define QUICK_SPOLY_TEST
+#ifdef USE_NORO
+#define NORO_CACHE 1
+#define NORO_SPARSE_ROWS_PRE 1
+#define NORO_NON_POLY 1
+#include <algorithm>
+#endif
+#ifdef NORO_CACHE
+//#include <map>
+#include <vector>
+#endif
+#ifdef HAVE_BOOST_DYNAMIC_BITSET_HPP
+#define  HAVE_BOOST 1
+#endif
+//#define HAVE_BOOST 1
+//#define USE_STDVECBOOL 1
+#ifdef HAVE_BOOST
+#include <vector>
+using boost::dynamic_bitset;
+using std::vector;
+#endif
+#ifdef USE_STDVECBOOL
+#include <vector>
+using std::vector;
+#endif
+#include <stdlib.h>
+
+#include <misc/options.h>
+
+#include <coeffs/modulop.h>
+
+#include <polys/monomials/p_polys.h>
+#include <polys/monomials/ring.h>
+#include <polys/kbuckets.h>
+
+#include <kernel/ideals.h>
+#include <kernel/polys.h>
+
+#include <kernel/GBEngine/kutil.h>
+#include <kernel/GBEngine/kInline.h>
+#include <kernel/GBEngine/kstd1.h>
+
+
+#if 1
+
+#define npInit n_Init
+#define npNeg n_InpNeg
+#define npInvers n_Invers
+#define npMult n_Mult
+#define npIsOne n_IsOne
+#define npIsZero n_IsZero
+
+#else
+#error Please do NOT call internal functions directly!
+#endif
+
+
+class PolySimple
+{
+public:
+  PolySimple(poly p)
+  {
+    impl=p;
+  }
+  PolySimple()
+  {
+    impl=NULL;
+  }
+  PolySimple(const PolySimple& a)
+  {
+    //impl=p_Copy(a.impl,currRing);
+    impl=a.impl;
+  }
+  PolySimple& operator=(const PolySimple& p2)
+  {
+    //p_Delete(&impl,currRing);
+    //impl=p_Copy(p2.impl,currRing);
+    impl=p2.impl;
+    return *this;
+  }
+  ~PolySimple()
+  {
+    //p_Delete(&impl,currRing);
+  }
+  bool operator< (const PolySimple& other) const
+  {
+    return pLmCmp(impl,other.impl)<0;
+  }
+  bool operator==(const PolySimple& other)
+  {
+    return pLmEqual(impl,other.impl);
+  }
+  poly impl;
+
+};
+template<class number_type> class DataNoroCacheNode;
+/*class MonRedRes{
+public:
+  poly p;
+  number coef;
+  BOOLEAN changed;
+  int len;
+  BOOLEAN onlyBorrowed;
+  bool operator<(const MonRedRes& other) const{
+    int cmp=p_LmCmp(p,other.p,currRing);
+    if ((cmp<0)||((cmp==0)&&((onlyBorrowed)&&(!(other.onlyBorrowed))))){
+      return true;
+    } else return false;
+  }
+  DataNoroCacheNode* ref;
+  MonRedRes(){
+    ref=NULL;
+    p=NULL;
+  }
+};*/
+template <class number_type> class MonRedResNP
+{
+public:
+  number coef;
+
+
+  DataNoroCacheNode<number_type>* ref;
+  MonRedResNP()
+  {
+    ref=NULL;
+  }
+};
+struct sorted_pair_node
+{
+  //criterium, which is stable 0. small lcm 1. small i 2. small j
+  wlen_type expected_length;
+  poly lcm_of_lm;
+  int i;
+  int j;
+  int deg;
+
+
+};
+#ifdef NORO_CACHE
+#ifndef NORO_NON_POLY
+class NoroPlaceHolder
+{
+public:
+  DataNoroCacheNode* ref;
+  number coef;
+};
+#endif
+#endif
+//static ideal debug_Ideal;
+
+
+struct poly_list_node
+{
+  poly p;
+  poly_list_node* next;
+};
+
+struct int_pair_node
+{
+  int_pair_node* next;
+  int a;
+  int b;
+};
+struct monom_poly
+{
+  poly m;
+  poly f;
+};
+struct mp_array_list
+{
+  monom_poly* mp;
+  int size;
+  mp_array_list* next;
+};
+
+
+struct poly_array_list
+{
+  poly* p;
+  int size;
+  poly_array_list* next;
+};
+class slimgb_alg
+{
+  public:
+    slimgb_alg(ideal I, int syz_comp,BOOLEAN F4,int deg_pos);
+                void introduceDelayedPairs(poly* pa,int s);
+    virtual ~slimgb_alg();
+    void cleanDegs(int lower, int upper);
+#ifndef HAVE_BOOST
+#ifdef USE_STDVECBOOL
+  vector<vector<bool> > states;
+#else
+  char** states;
+#endif
+#else
+  vector<dynamic_bitset<> > states;
+#endif
+  ideal add_later;
+  ideal S;
+  ring r;
+  int* lengths;
+  wlen_type* weighted_lengths;
+  long* short_Exps;
+  kStrategy strat;
+  int* T_deg;
+  int* T_deg_full;
+  poly tmp_lm;
+  poly* tmp_pair_lm;
+  sorted_pair_node** tmp_spn;
+  poly* expandS;
+  poly* gcd_of_terms;
+  int_pair_node* soon_free;
+  sorted_pair_node** apairs;
+  #if 0
+  BOOLEAN* modifiedS;
+  #endif
+  #ifdef TGB_RESORT_PAIRS
+  bool* replaced;
+  #endif
+  poly_list_node* to_destroy;
+  //for F4
+  mp_array_list* F;
+  poly_array_list* F_minus;
+
+  //end for F4
+#ifdef HEAD_BIN
+  omBin   HeadBin;
+#endif
+  unsigned int reduction_steps;
+  int n;
+  //! array_lengths should be greater equal n;
+  int syz_comp;
+  int array_lengths;
+  int normal_forms;
+  int current_degree;
+  int Rcounter;
+  int last_index;
+  int max_pairs;
+  int pair_top;
+  int easy_product_crit;
+  int extended_product_crit;
+  int average_length;
+  int lastDpBlockStart;
+  int lastCleanedDeg;
+  int deg_pos;
+  BOOLEAN use_noro;
+  BOOLEAN use_noro_last_block;
+  BOOLEAN isDifficultField;
+  BOOLEAN completed;
+  BOOLEAN is_homog;
+  BOOLEAN tailReductions;
+  BOOLEAN eliminationProblem;
+  BOOLEAN F4_mode;
+  BOOLEAN nc;
+  #ifdef TGB_RESORT_PAIRS
+  BOOLEAN used_b;
+  #endif
+  unsigned long pTotaldegree(poly p)
+  {
+      pTest(p);
+      //assume(pDeg(p,r)==::p_Totaldegree(p,r));
+      assume(((unsigned long)::p_Totaldegree(p,r))==p->exp[deg_pos]);
+      return p->exp[deg_pos];
+      //return ::pTotaldegree(p,this->r);
+  }
+  int pTotaldegree_full(poly p)
+  {
+    int rr=0;
+    while(p)
+    {
+      int d=this->pTotaldegree(p);
+      rr=si_max(rr,d);
+      pIter(p);
+    }
+    return rr;
+  }
+};
+class red_object
+{
+ public:
+  kBucket_pt bucket;
+  poly p;
+  unsigned long sev;
+  void flatten();
+  void validate();
+  wlen_type initial_quality;
+  void adjust_coefs(number c_r, number c_ac_r);
+  wlen_type guess_quality(slimgb_alg* c);
+  int clear_to_poly();
+  void canonicalize();
+};
+
+
+enum calc_state
+  {
+    UNCALCULATED,
+    HASTREP//,
+    //UNIMPORTANT,
+    //SOONTREP
+  };
+template <class len_type, class set_type>  int pos_helper(kStrategy strat, poly p, len_type len, set_type setL, polyset set);
+void free_sorted_pair_node(sorted_pair_node* s, ring r);
+ideal do_t_rep_gb(ring r,ideal arg_I, int syz_comp, BOOLEAN F4_mode,int deg_pos);
+void now_t_rep(const int & arg_i, const int & arg_j, slimgb_alg* c);
+
+void clean_top_of_pair_list(slimgb_alg* c);
+int slim_nsize(number n, ring r);
+sorted_pair_node* quick_pop_pair(slimgb_alg* c);
+sorted_pair_node* top_pair(slimgb_alg* c);
+sorted_pair_node** add_to_basis_ideal_quotient(poly h, slimgb_alg* c, int* ip);//, BOOLEAN new_pairs=TRUE);
+sorted_pair_node**  spn_merge(sorted_pair_node** p, int pn,sorted_pair_node **q, int qn,slimgb_alg* c);
+int kFindDivisibleByInS_easy(kStrategy strat,const red_object & obj);
+int tgb_pair_better_gen2(const void* ap,const void* bp);
+int kFindDivisibleByInS_easy(kStrategy strat,poly p, long sev);
+/**
+   makes on each red_object in a region a single_step
+ **/
+class reduction_step
+{
+ public:
+  /// we assume hat all occuring red_objects have same lm, and all
+  /// occ. lm's in r[l...u] are the same, only reductor does not occur
+  virtual void reduce(red_object* r, int l, int u);
+  //int reduction_id;
+  virtual ~reduction_step();
+  slimgb_alg* c;
+  int reduction_id;
+};
+class simple_reducer:public reduction_step
+{
+ public:
+  poly p;
+  kBucket_pt fill_back;
+  int p_len;
+  int reducer_deg;
+  simple_reducer(poly pp, int pp_len,int pp_reducer_deg, slimgb_alg* pp_c =NULL)
+  {
+    this->p=pp;
+    this->reducer_deg=pp_reducer_deg;
+    assume(pp_len==pLength(pp));
+    this->p_len=pp_len;
+    this->c=pp_c;
+  }
+  virtual void pre_reduce(red_object* r, int l, int u);
+  virtual void reduce(red_object* r, int l, int u);
+  ~simple_reducer();
+
+
+  virtual void do_reduce(red_object & ro);
+};
+
+//class sum_canceling_reducer:public reduction_step {
+//  void reduce(red_object* r, int l, int u);
+//};
+struct find_erg
+{
+  poly expand;
+  int expand_length;
+  int to_reduce_u;
+  int to_reduce_l;
+  int reduce_by;//index of reductor
+  BOOLEAN fromS;//else from los
+
+};
+
+template <class len_type, class set_type>  int pos_helper(kStrategy strat, poly p, len_type len, set_type setL, polyset set)
+{
+  //Print("POSHELER:%d",sizeof(wlen_type));
+  int length=strat->sl;
+  int i;
+  int an = 0;
+  int en= length;
+
+  if ((len>setL[length])
+      || ((len==setL[length]) && (pLmCmp(set[length],p)== -1)))
+    return length+1;
+
+  loop
+  {
+    if (an >= en-1)
+    {
+      if ((len<setL[an])
+          || ((len==setL[an]) && (pLmCmp(set[an],p) == 1))) return an;
+      return en;
+    }
+    i=(an+en) / 2;
+    if ((len<setL[i])
+        || ((len==setL[i]) && (pLmCmp(set[i],p) == 1))) en=i;
+    //else if ((len>setL[i])
+    //|| ((len==setL[i]) && (pLmCmp(set[i],p) == -1))) an=i;
+    else an=i;
+  }
+
+}
+#ifdef NORO_CACHE
+#define slim_prec_cast(a) (unsigned int) (unsigned long) (a)
+#define F4mat_to_number_type(a) (number_type) slim_prec_cast(a)
+typedef unsigned short tgb_uint16;
+typedef unsigned char tgb_uint8;
+typedef unsigned int tgb_uint32;
+class NoroCacheNode
+{
+public:
+  NoroCacheNode** branches;
+  int branches_len;
+
+
+  NoroCacheNode()
+  {
+    branches=NULL;
+    branches_len=0;
+
+  }
+  NoroCacheNode* setNode(int branch, NoroCacheNode* node)
+  {
+    if (branch>=branches_len)
+    {
+      if (branches==NULL)
+      {
+        branches_len=branch+1;
+        branches_len=si_max(branches_len,3);
+        branches=(NoroCacheNode**) omAlloc(branches_len*sizeof(NoroCacheNode*));
+        int i;
+        for(i=0;i<branches_len;i++)
+        {
+          branches[i]=NULL;
+        }
+      }
+      else
+      {
+        int branches_len_old=branches_len;
+        branches_len=branch+1;
+        branches=(NoroCacheNode**) omrealloc(branches,branches_len*sizeof(NoroCacheNode*));
+        int i;
+        for(i=branches_len_old;i<branches_len;i++)
+        {
+          branches[i]=NULL;
+        }
+      }
+    }
+    assume(branches[branch]==NULL);
+    branches[branch]=node;
+    return node;
+  }
+  NoroCacheNode* getBranch(int branch)
+  {
+    if (branch<branches_len) return branches[branch];
+    return NULL;
+  }
+  virtual ~NoroCacheNode()
+  {
+    int i;
+    for(i=0;i<branches_len;i++)
+    {
+      delete branches[i];
+    }
+    omfree(branches);
+  }
+  NoroCacheNode* getOrInsertBranch(int branch)
+  {
+    if ((branch<branches_len)&&(branches[branch]))
+      return branches[branch];
+    else
+    {
+      return setNode(branch,new NoroCacheNode());
+    }
+  }
+};
+class DenseRow{
+public:
+  number* array;
+  int begin;
+  int end;
+  DenseRow()
+  {
+    array=NULL;
+  }
+  ~DenseRow()
+  {
+    omfree(array);
+  }
+};
+template <class number_type> class SparseRow
+{
+public:
+  int* idx_array;
+  number_type* coef_array;
+  int len;
+  SparseRow()
+  {
+    len=0;
+    idx_array=NULL;
+    coef_array=NULL;
+  }
+  SparseRow<number_type>(int n)
+  {
+    len=n;
+    idx_array=(int*) omAlloc(n*sizeof(int));
+    coef_array=(number_type*) omAlloc(n*sizeof(number_type));
+  }
+  SparseRow<number_type>(int n, const number_type* source)
+  {
+    len=n;
+    idx_array=NULL;
+    coef_array=(number_type*) omAlloc(n*sizeof(number_type));
+    memcpy(coef_array,source,n*sizeof(number_type));
+  }
+  ~SparseRow<number_type>()
+  {
+    omfree(idx_array);
+    omfree(coef_array);
+  }
+};
+
+template <class number_type> class DataNoroCacheNode:public NoroCacheNode
+{
+public:
+
+  int value_len;
+  poly value_poly;
+  #ifdef NORO_SPARSE_ROWS_PRE
+  SparseRow<number_type>* row;
+  #else
+  DenseRow* row;
+  #endif
+  int term_index;
+  DataNoroCacheNode(poly p, int len)
+  {
+    value_len=len;
+    value_poly=p;
+    row=NULL;
+    term_index=-1;
+  }
+  #ifdef NORO_SPARSE_ROWS_PRE
+  DataNoroCacheNode(SparseRow<number_type>* row)
+  {
+    if (row!=NULL)
+      value_len=row->len;
+    else
+      value_len=0;
+    value_poly=NULL;
+    this->row=row;
+    term_index=-1;
+  }
+  #endif
+  ~DataNoroCacheNode()
+  {
+    //p_Delete(&value_poly,currRing);
+    if (row) delete row;
+  }
+};
+template <class number_type> class TermNoroDataNode
+{
+public:
+  DataNoroCacheNode<number_type>* node;
+  poly t;
+};
+
+template <class number_type> class NoroCache
+{
+public:
+  poly temp_term;
+#ifndef NORO_NON_POLY
+  void evaluatePlaceHolder(number* row,std::vector<NoroPlaceHolder>& place_holders);
+  void evaluateRows();
+  void evaluateRows(int level, NoroCacheNode* node);
+#endif
+  void collectIrreducibleMonomials( std::vector<DataNoroCacheNode<number_type>* >& res);
+  void collectIrreducibleMonomials(int level,  NoroCacheNode* node, std::vector<DataNoroCacheNode<number_type>* >& res);
+
+#ifdef NORO_RED_ARRAY_RESERVER
+  int reserved;
+  poly* recursionPolyBuffer;
+#endif
+  static const int backLinkCode=-222;
+  DataNoroCacheNode<number_type>* insert(poly term, poly nf, int len)
+  {
+    //assume(impl.find(p_Copy(term,currRing))==impl.end());
+    //assume(len==pLength(nf));
+    assume(npIsOne(p_GetCoeff(term,currRing),currRing->cf));
+    if (term==nf)
+    {
+      term=p_Copy(term,currRing);
+
+      ressources.push_back(term);
+      nIrreducibleMonomials++;
+      return treeInsertBackLink(term);
+
+    }
+    else
+    {
+      if (nf)
+      {
+        //nf=p_Copy(nf,currRing);
+        assume(p_LmCmp(nf,term,currRing)==-1);
+        ressources.push_back(nf);
+      }
+      return treeInsert(term,nf,len);
+
+    }
+
+    //impl[term]=std::pair<PolySimple,int> (nf,len);
+  }
+  #ifdef NORO_SPARSE_ROWS_PRE
+  DataNoroCacheNode<number_type>* insert(poly term, SparseRow<number_type>* srow)
+  {
+    //assume(impl.find(p_Copy(term,currRing))==impl.end());
+    //assume(len==pLength(nf));
+
+      return treeInsert(term,srow);
+
+
+    //impl[term]=std::pair<PolySimple,int> (nf,len);
+  }
+  #endif
+  DataNoroCacheNode<number_type>* insertAndTransferOwnerShip(poly t, ring /*r*/)
+  {
+    ressources.push_back(t);
+    DataNoroCacheNode<number_type>* res=treeInsertBackLink(t);
+    res->term_index=nIrreducibleMonomials;
+    nIrreducibleMonomials++;
+    return res;
+  }
+  poly lookup(poly term, BOOLEAN& succ, int & len);
+  DataNoroCacheNode<number_type>* getCacheReference(poly term);
+  NoroCache()
+  {
+    buffer=NULL;
+#ifdef NORO_RED_ARRAY_RESERVER
+    reserved=0;
+    recursionPolyBuffer=(poly*)omAlloc(1000000*sizeof(poly));
+#endif
+    nIrreducibleMonomials=0;
+    nReducibleMonomials=0;
+    temp_term=pOne();
+    tempBufferSize=3000;
+    tempBuffer=omAlloc(tempBufferSize);
+  }
+  void ensureTempBufferSize(size_t size)
+  {
+    if (tempBufferSize<size)
+    {
+      tempBufferSize=2*size;
+      omFree(tempBuffer);
+      tempBuffer=omAlloc(tempBufferSize);
+    }
+  }
+#ifdef NORO_RED_ARRAY_RESERVER
+  poly* reserve(int n)
+  {
+    poly* res=recursionPolyBuffer+reserved;
+    reserved+=n;
+    return res;
+  }
+  void free(int n)
+  {
+    reserved-=n;
+  }
+#endif
+  ~NoroCache()
+  {
+    int s=ressources.size();
+    int i;
+    for(i=0;i<s;i++)
+    {
+      p_Delete(&ressources[i].impl,currRing);
+    }
+    p_Delete(&temp_term,currRing);
+#ifdef NORO_RED_ARRAY_RESERVER
+    omfree(recursionPolyBuffer);
+#endif
+   omFree(tempBuffer);
+  }
+
+  int nIrreducibleMonomials;
+  int nReducibleMonomials;
+  void* tempBuffer;
+  size_t tempBufferSize;
+protected:
+  DataNoroCacheNode<number_type>* treeInsert(poly term,poly nf,int len)
+  {
+    int i;
+    nReducibleMonomials++;
+    int nvars=(currRing->N);
+    NoroCacheNode* parent=&root;
+    for(i=1;i<nvars;i++)
+    {
+      parent=parent->getOrInsertBranch(p_GetExp(term,i,currRing));
+    }
+    return (DataNoroCacheNode<number_type>*) parent->setNode(p_GetExp(term,nvars,currRing),new DataNoroCacheNode<number_type>(nf,len));
+  }
+  #ifdef NORO_SPARSE_ROWS_PRE
+  DataNoroCacheNode<number_type>* treeInsert(poly term,SparseRow<number_type>* srow)
+  {
+    int i;
+    nReducibleMonomials++;
+    int nvars=(currRing->N);
+    NoroCacheNode* parent=&root;
+    for(i=1;i<nvars;i++)
+    {
+      parent=parent->getOrInsertBranch(p_GetExp(term,i,currRing));
+    }
+    return (DataNoroCacheNode<number_type>*) parent->setNode(p_GetExp(term,nvars,currRing),new DataNoroCacheNode<number_type>(srow));
+  }
+  #endif
+  DataNoroCacheNode<number_type>* treeInsertBackLink(poly term)
+  {
+    int i;
+    int nvars=(currRing->N);
+    NoroCacheNode* parent=&root;
+    for(i=1;i<nvars;i++)
+    {
+      parent=parent->getOrInsertBranch(p_GetExp(term,i,currRing));
+    }
+    return (DataNoroCacheNode<number_type>*) parent->setNode(p_GetExp(term,nvars,currRing),new DataNoroCacheNode<number_type>(term,backLinkCode));
+  }
+
+  //@TODO descruct nodes;
+  typedef std::vector<PolySimple> poly_vec;
+  poly_vec ressources;
+  //typedef std::map<PolySimple,std::pair<PolySimple,int> > cache_map;
+  //cache_map impl;
+  NoroCacheNode root;
+  number* buffer;
+};
+template<class number_type> SparseRow<number_type> * noro_red_to_non_poly_t(poly p, int &len, NoroCache<number_type>* cache,slimgb_alg* c);
+template<class number_type> MonRedResNP<number_type> noro_red_mon_to_non_poly(poly t,  NoroCache<number_type> * cache,slimgb_alg* c)
+{
+  MonRedResNP<number_type> res_holder;
+
+
+    DataNoroCacheNode<number_type>* ref=cache->getCacheReference(t);
+    if (ref!=NULL)
+    {
+      res_holder.coef=p_GetCoeff(t,c->r);
+
+      res_holder.ref=ref;
+      p_Delete(&t,c->r);
+      return res_holder;
+    }
+
+  unsigned long sev=p_GetShortExpVector(t,currRing);
+  int i=kFindDivisibleByInS_easy(c->strat,t,sev);
+  if (i>=0)
+  {
+    number coef_bak=p_GetCoeff(t,c->r);
+
+    p_SetCoeff(t,npInit(1,c->r->cf),c->r);
+    assume(npIsOne(p_GetCoeff(c->strat->S[i],c->r),c->r->cf));
+    number coefstrat=p_GetCoeff(c->strat->S[i],c->r);
+
+
+    poly exp_diff=cache->temp_term;
+    p_ExpVectorDiff(exp_diff,t,c->strat->S[i],c->r);
+    p_SetCoeff(exp_diff,npNeg(npInvers(coefstrat,c->r->cf),c->r->cf),c->r);
+    p_Setm(exp_diff,c->r);
+    assume(c->strat->S[i]!=NULL);
+
+    poly res;
+    res=pp_Mult_mm(pNext(c->strat->S[i]),exp_diff,c->r);
+
+    int len=c->strat->lenS[i]-1;
+    SparseRow<number_type>* srow;
+    srow=noro_red_to_non_poly_t<number_type>(res,len,cache,c);
+    ref=cache->insert(t,srow);
+    p_Delete(&t,c->r);
+
+
+    res_holder.coef=coef_bak;
+    res_holder.ref=ref;
+    return res_holder;
+
+  } else {
+    number coef_bak=p_GetCoeff(t,c->r);
+    number one=npInit(1, c->r->cf);
+    p_SetCoeff(t,one,c->r);
+
+    res_holder.ref=cache->insertAndTransferOwnerShip(t,c->r);
+    assume(res_holder.ref!=NULL);
+    res_holder.coef=coef_bak;
+
+    return res_holder;
+
+  }
+
+}
+/*
+poly tree_add(poly* a,int begin, int end,ring r)
+{
+  int d=end-begin;
+  switch(d)
+  {
+    case 0:
+      return NULL;
+    case 1:
+      return a[begin];
+    case 2:
+      return p_Add_q(a[begin],a[begin+1],r);
+    default:
+      int s=d/2;
+      return p_Add_q(tree_add(a,begin,begin+s,r),tree_add(a,begin+s,end,r),r);
+  }
+}
+*/
+#ifdef __GNUC__
+#define LIKELY(expression) (__builtin_expect(!!(expression), 1))
+#define UNLIKELY(expression) (__builtin_expect(!!(expression), 0))
+#else
+#define LIKELY(expression) (expression)
+#define UNLIKELY(expression) (expression)
+#endif
+
+template<class number_type> SparseRow<number_type>* convert_to_sparse_row(number_type* temp_array,int temp_size,int non_zeros){
+SparseRow<number_type>* res=new SparseRow<number_type>(non_zeros);
+//int pos=0;
+//Print("denseness:%f\n",((double) non_zeros/(double) temp_size));
+number_type* it_coef=res->coef_array;
+int* it_idx=res->idx_array;
+#if 0
+for(i=0;i<cache->nIrreducibleMonomials;i++){
+  if (!(0==temp_array[i])){
+
+    res->idx_array[pos]=i;
+    res->coef_array[pos]=temp_array[i];
+
+    pos++;
+    non_zeros--;
+    if (non_zeros==0) break;
+  }
+
+}
+#else
+int64* start=(int64*) ((void*)temp_array);
+int64* end;
+const int multiple=sizeof(int64)/sizeof(number_type);
+if (temp_size==0) end=start;
+
+else
+{
+  int temp_size_rounded=temp_size+(multiple-(temp_size%multiple));
+  assume(temp_size_rounded>=temp_size);
+  assume(temp_size_rounded%multiple==0);
+  assume(temp_size_rounded<temp_size+multiple);
+  number_type* nt_end=temp_array+temp_size_rounded;
+  end=(int64*)((void*)nt_end);
+}
+int64* it=start;
+while(it!=end)
+{
+  if UNLIKELY((*it)!=0)
+  {
+    int small_i;
+    const int temp_index=((number_type*)((void*) it))-temp_array;
+    const int bound=temp_index+multiple;
+    number_type c;
+    for(small_i=temp_index;small_i<bound;small_i++)
+    {
+      if((c=temp_array[small_i])!=0)
+      {
+        //res->idx_array[pos]=small_i;
+        //res->coef_array[pos]=temp_array[small_i];
+        (*(it_idx++))=small_i;
+        (*(it_coef++))=c;
+        //pos++;
+        non_zeros--;
+
+      }
+      if UNLIKELY(non_zeros==0) break;
+    }
+
+  }
+  ++it;
+}
+#endif
+return res;
+}
+#ifdef SING_NDEBUG
+template <class number_type> void add_coef_times_sparse(number_type* const temp_array,
+int /*temp_size*/,SparseRow<number_type>* row, number coef)
+#else
+template <class number_type> void add_coef_times_sparse(number_type* const temp_array,
+int temp_size,SparseRow<number_type>* row, number coef)
+#endif
+{
+  int j;
+  number_type* const coef_array=row->coef_array;
+  int* const idx_array=row->idx_array;
+  const int len=row->len;
+  tgb_uint32 buffer[256];
+  const tgb_uint32 prime=n_GetChar(currRing->cf);
+  const tgb_uint32 c=F4mat_to_number_type(coef);
+  assume(!(npIsZero(coef,currRing->cf)));
+  for(j=0;j<len;j=j+256)
+  {
+    const int bound=std::min(j+256,len);
+    int i;
+    int bpos=0;
+    for(i=j;i<bound;i++)
+    {
+      buffer[bpos++]=coef_array[i];
+    }
+    int bpos_bound=bound-j;
+    for(i=0;i<bpos_bound;i++)
+    {
+       buffer[i]*=c;
+     }
+    for(i=0;i<bpos_bound;i++)
+    {
+       buffer[i]=buffer[i]%prime;
+    }
+    bpos=0;
+    for(i=j;i<bound;i++)
+    {
+      int idx=idx_array[i];
+      assume(bpos<256);
+      assume(!(npIsZero((number)(long) buffer[bpos],currRing->cf)));
+      STATISTIC(n_Add); temp_array[idx]=F4mat_to_number_type(npAddM((number)(long) temp_array[idx], (number)(long) buffer[bpos++],currRing->cf));
+      assume(idx<temp_size);
+    }
+
+  }
+}
+#ifdef SING_NDEBUG
+template <class number_type> void add_coef_times_dense(number_type* const temp_array,
+int /*temp_size*/,const number_type* row, int len,number coef)
+#else
+template <class number_type> void add_coef_times_dense(number_type* const temp_array,
+int temp_size,const number_type* row, int len,number coef)
+#endif
+{
+  int j;
+  const number_type* const coef_array=row;
+  //int* const idx_array=row->idx_array;
+  //const int len=temp_size;
+  tgb_uint32 buffer[256];
+  const tgb_uint32 prime=n_GetChar(currRing->cf);
+  const tgb_uint32 c=F4mat_to_number_type(coef);
+  assume(!(npIsZero(coef,currRing->cf)));
+  for(j=0;j<len;j=j+256)
+  {
+    const int bound=std::min(j+256,len);
+    int i;
+    int bpos=0;
+    for(i=j;i<bound;i++)
+    {
+      buffer[bpos++]=coef_array[i];
+    }
+    int bpos_bound=bound-j;
+    for(i=0;i<bpos_bound;i++)
+    {
+       buffer[i]*=c;
+     }
+    for(i=0;i<bpos_bound;i++)
+    {
+       buffer[i]=buffer[i]%prime;
+    }
+    bpos=0;
+    for(i=j;i<bound;i++)
+    {
+      //int idx=idx_array[i];
+      assume(bpos<256);
+      //assume(!(npIsZero((number) buffer[bpos])));
+      STATISTIC(n_Add); temp_array[i]=F4mat_to_number_type(npAddM((number)(long) temp_array[i], (number)(long) buffer[bpos++],currRing->cf));
+      assume(i<temp_size);
+    }
+
+  }
+}
+#ifdef SING_NDEBUG
+template <class number_type> void add_dense(number_type* const temp_array,
+int /*temp_size*/,const number_type* row, int len)
+#else
+template <class number_type> void add_dense(number_type* const temp_array,
+int temp_size,const number_type* row, int len)
+#endif
+{
+  //int j;
+  //const number_type* const coef_array=row;
+  //int* const idx_array=row->idx_array;
+  //const int len=temp_size;
+  //tgb_uint32 buffer[256];
+  //const tgb_uint32 prime=npPrimeM;
+  //const tgb_uint32 c=F4mat_to_number_type(coef);
+
+  int i;
+  for(i=0;i<len;i++)
+  {
+      STATISTIC(n_Add); temp_array[i]=F4mat_to_number_type(npAddM((number)(long) temp_array[i], (number)(long) row[i],currRing->cf));
+      assume(i<temp_size);
+  }
+
+}
+#ifdef SING_NDEBUG
+template <class number_type> void sub_dense(number_type* const temp_array,
+int /*temp_size*/,const number_type* row, int len)
+#else
+template <class number_type> void sub_dense(number_type* const temp_array,
+int temp_size,const number_type* row, int len)
+#endif
+{
+  //int j;
+  //const number_type* const coef_array=row;
+  //int* const idx_array=row->idx_array;
+  //const int len=temp_size;
+  //tgb_uint32 buffer[256];
+  //const tgb_uint32 prime=npPrimeM;
+  //const tgb_uint32 c=F4mat_to_number_type(coef);
+
+  int i;
+  for(i=0;i<len;i++)
+  {
+
+      STATISTIC(n_Sub); temp_array[i]=F4mat_to_number_type(npSubM((number)(long) temp_array[i], (number)(long) row[i],currRing->cf));
+      assume(i<temp_size);
+  }
+
+}
+
+#ifdef SING_NDEBUG
+template <class number_type> void add_sparse(number_type* const temp_array,int /*temp_size*/,SparseRow<number_type>* row)
+#else
+template <class number_type> void add_sparse(number_type* const temp_array,int temp_size,SparseRow<number_type>* row)
+#endif
+{
+  int j;
+
+          number_type* const coef_array=row->coef_array;
+          int* const idx_array=row->idx_array;
+          const int len=row->len;
+        for(j=0;j<len;j++)
+        {
+          int idx=idx_array[j];
+          STATISTIC(n_Add); temp_array[idx]=F4mat_to_number_type(   (number_type)(long)npAddM((number) (long)temp_array[idx],(number)(long) coef_array[j],currRing->cf));
+          assume(idx<temp_size);
+        }
+}
+#ifdef SING_NDEBUG
+template <class number_type> void sub_sparse(number_type* const temp_array,int /*temp_size*/,SparseRow<number_type>* row)
+#else
+template <class number_type> void sub_sparse(number_type* const temp_array,int temp_size,SparseRow<number_type>* row)
+#endif
+{
+  int j;
+
+          number_type* const coef_array=row->coef_array;
+          int* const idx_array=row->idx_array;
+          const int len=row->len;
+        for(j=0;j<len;j++)
+        {
+          int idx=idx_array[j];
+          STATISTIC(n_Sub); temp_array[idx]=F4mat_to_number_type(  (number_type)(long) npSubM((number) (long)temp_array[idx],(number)(long) coef_array[j],currRing->cf));
+          assume(idx<temp_size);
+        }
+}
+template <class number_type> SparseRow<number_type>* noro_red_to_non_poly_dense(MonRedResNP<number_type>* mon, int len,NoroCache<number_type>* cache)
+{
+  size_t temp_size_bytes=cache->nIrreducibleMonomials*sizeof(number_type)+8;//use 8bit int for testing
+   assume(sizeof(int64)==8);
+   cache->ensureTempBufferSize(temp_size_bytes);
+   number_type* temp_array=(number_type*) cache->tempBuffer;//omalloc(cache->nIrreducibleMonomials*sizeof(number_type));
+   int temp_size=cache->nIrreducibleMonomials;
+   memset(temp_array,0,temp_size_bytes);
+   number minus_one=npInit(-1,currRing->cf);
+   int i;
+   for(i=0;i<len;i++)
+   {
+     MonRedResNP<number_type> red=mon[i];
+     if ( /*(*/ red.ref /*)*/ )
+     {
+       if (red.ref->row)
+       {
+         SparseRow<number_type>* row=red.ref->row;
+         number coef=red.coef;
+         if (row->idx_array)
+         {
+           if (!((coef==(number)(long) 1)||(coef==minus_one)))
+           {
+             add_coef_times_sparse(temp_array,temp_size,row,coef);
+           }
+           else
+           {
+             if (coef==(number)(long) 1)
+             {
+               add_sparse(temp_array,temp_size,row);
+             }
+             else
+             {
+               sub_sparse(temp_array,temp_size,row);
+             }
+           }
+         }
+         else
+         //TODO: treat, 1,-1
+         if (!((coef==(number)(long) 1)||(coef==minus_one)))
+         {
+          add_coef_times_dense(temp_array,temp_size,row->coef_array,row->len,coef);
+         }
+         else
+         {
+           if (coef==(number)(long)1)
+             add_dense(temp_array,temp_size,row->coef_array,row->len);
+           else
+           {
+             assume(coef==minus_one);
+             sub_dense(temp_array,temp_size,row->coef_array,row->len);
+             //add_coef_times_dense(temp_array,temp_size,row->coef_array,row->len,coef);
+           }
+         }
+       }
+       else
+       {
+         if (red.ref->value_len==NoroCache<number_type>::backLinkCode)
+         {
+           STATISTIC(n_Add); temp_array[red.ref->term_index]=F4mat_to_number_type( npAddM((number)(long) temp_array[red.ref->term_index],red.coef,currRing->cf));
+         }
+         else
+         {
+           //PrintS("third case\n");
+         }
+       }
+     }
+   }
+   int non_zeros=0;
+   for(i=0;i<cache->nIrreducibleMonomials;i++)
+   {
+     //if (!(temp_array[i]==0)){
+     //  non_zeros++;
+     //}
+     assume(((temp_array[i]!=0)==0)|| (((temp_array[i]!=0)==1)));
+     non_zeros+=(temp_array[i]!=0);
+   }
+
+   if (non_zeros==0)
+   {
+     //omfree(mon);
+     return NULL;
+   }
+   SparseRow<number_type>* res=new SparseRow<number_type>(temp_size,temp_array);//convert_to_sparse_row(temp_array,temp_size, non_zeros);
+
+   //omfree(temp_array);
+
+
+   return res;
+}
+template<class number_type> class CoefIdx
+{
+public:
+  number_type coef;
+  int idx;
+  bool operator<(const CoefIdx<number_type>& other) const
+  {
+    return (idx<other.idx);
+  }
+};
+template<class number_type> void write_coef_times_xx_idx_to_buffer(CoefIdx<number_type>* const pairs,int& pos,int* const idx_array, number_type* const coef_array,const int rlen, const number coef)
+{
+  int j;
+  for(j=0;j<rlen;j++)
+  {
+    assume(coef_array[j]!=0);
+    CoefIdx<number_type> ci;
+    STATISTIC(n_Mult); ci.coef=F4mat_to_number_type(npMultM((number)(long) coef,(number)(long) coef_array[j],currRing->cf));
+    ci.idx=idx_array[j];
+    pairs[pos++]=ci;
+  }
+}
+template<class number_type> void write_coef_times_xx_idx_to_buffer_dense(CoefIdx<number_type>* const pairs,int& pos, number_type* const coef_array,const int rlen, const number coef)
+{
+  int j;
+
+  for(j=0;j<rlen;j++)
+  {
+    if (coef_array[j]!=0)
+    {
+      assume(coef_array[j]!=0);
+      CoefIdx<number_type> ci;
+      STATISTIC(n_Mult); ci.coef=F4mat_to_number_type(npMultM((number)(long) coef,(number)(long) coef_array[j],currRing->cf));
+      assume(ci.coef!=0);
+      ci.idx=j;
+      pairs[pos++]=ci;
+    }
+  }
+}
+template<class number_type> void write_coef_idx_to_buffer_dense(CoefIdx<number_type>* const pairs,int& pos, number_type* const coef_array,const int rlen)
+{
+  int j;
+
+  for(j=0;j<rlen;j++)
+  {
+    if (coef_array[j]!=0)
+    {
+      assume(coef_array[j]!=0);
+      CoefIdx<number_type> ci;
+      ci.coef=coef_array[j];
+      assume(ci.coef!=0);
+      ci.idx=j;
+      pairs[pos++]=ci;
+    }
+  }
+}
+
+template<class number_type> void write_minus_coef_idx_to_buffer_dense(CoefIdx<number_type>* const pairs,int& pos, number_type* const coef_array,const int rlen)
+{
+  int j;
+
+  for(j=0;j<rlen;j++)
+  {
+    if (coef_array[j]!=0)
+    {
+      assume(coef_array[j]!=0);
+      CoefIdx<number_type> ci;
+      STATISTIC(n_InpNeg); ci.coef=F4mat_to_number_type(npNegM((number)(long) coef_array[j],currRing->cf)); // FIXME: inplace negation! // TODO: check if this is not a bug!?
+      assume(ci.coef!=0);
+      ci.idx=j;
+      pairs[pos++]=ci;
+    }
+  }
+}
+template<class number_type> void write_coef_idx_to_buffer(CoefIdx<number_type>* const pairs,int& pos,int* const idx_array, number_type* const coef_array,const int rlen)
+{
+  int j;
+  for(j=0;j<rlen;j++)
+  {
+    assume(coef_array[j]!=0);
+    CoefIdx<number_type> ci;
+    ci.coef=coef_array[j];
+    ci.idx=idx_array[j];
+    pairs[pos++]=ci;
+  }
+}
+
+template<class number_type> void write_minus_coef_idx_to_buffer(CoefIdx<number_type>* const pairs,int& pos,int* const idx_array, number_type* const coef_array,const int rlen)
+{
+  int j;
+  for(j=0;j<rlen;j++)
+  {
+    assume(coef_array[j]!=0);
+    CoefIdx<number_type> ci;
+    STATISTIC(n_InpNeg); ci.coef=F4mat_to_number_type(npNegM((number)(unsigned long)coef_array[j],currRing->cf));  // FIXME: inplace negation! // TODO: check if this is not a bug!?
+    ci.idx=idx_array[j];
+    pairs[pos++]=ci;
+  }
+}
+template <class number_type> SparseRow<number_type>* noro_red_to_non_poly_sparse(MonRedResNP<number_type>* mon, int len,NoroCache<number_type>* cache)
+{
+  int i;
+  int together=0;
+  for(i=0;i<len;i++)
+  {
+    MonRedResNP<number_type> red=mon[i];
+    if ((red.ref) &&( red.ref->row))
+    {
+      together+=red.ref->row->len;
+    }
+    else
+    {
+      if ((red.ref) &&(red.ref->value_len==NoroCache<number_type>::backLinkCode))
+      together++;
+    }
+  }
+  //PrintS("here\n");
+  if (together==0) return 0;
+  //PrintS("there\n");
+  cache->ensureTempBufferSize(together*sizeof(CoefIdx<number_type>));
+  CoefIdx<number_type>* pairs=(CoefIdx<number_type>*) cache->tempBuffer; //omalloc(together*sizeof(CoefIdx<number_type>));
+  int pos=0;
+  const number one=npInit(1, currRing->cf);
+  const number minus_one=npInit(-1, currRing->cf);
+  for(i=0;i<len;i++)
+  {
+    MonRedResNP<number_type> red=mon[i];
+    if ((red.ref) &&( red.ref->row))
+    {
+      //together+=red.ref->row->len;
+      int* idx_array=red.ref->row->idx_array;
+      number_type* coef_array=red.ref->row->coef_array;
+      int rlen=red.ref->row->len;
+      number coef=red.coef;
+      if (idx_array)
+      {
+        if ((coef!=one)&&(coef!=minus_one))
+        {
+          write_coef_times_xx_idx_to_buffer(pairs,pos,idx_array, coef_array,rlen, coef);
+        }
+        else
+        {
+          if (coef==one)
+          {
+            write_coef_idx_to_buffer(pairs,pos,idx_array, coef_array,rlen);
+          }
+          else
+          {
+            assume(coef==minus_one);
+            write_minus_coef_idx_to_buffer(pairs,pos,idx_array, coef_array,rlen);
+          }
+        }
+      }
+      else
+      {
+        if ((coef!=one)&&(coef!=minus_one))
+        {
+          write_coef_times_xx_idx_to_buffer_dense(pairs,pos,coef_array,rlen,coef);
+        }
+        else
+        {
+          if (coef==one)
+            write_coef_idx_to_buffer_dense(pairs,pos,coef_array,rlen);
+          else
+          {
+            assume(coef==minus_one);
+            write_minus_coef_idx_to_buffer_dense(pairs,pos,coef_array,rlen);
+          }
+        }
+      }
+    }
+    else
+    {
+      if ((red.ref) &&(red.ref->value_len==NoroCache<number_type>::backLinkCode))
+      {
+        CoefIdx<number_type> ci;
+        ci.coef=F4mat_to_number_type(red.coef);
+        ci.idx=red.ref->term_index;
+        pairs[pos++]=ci;
+      }
+    }
+  }
+  assume(pos<=together);
+  together=pos;
+
+  std::sort(pairs,pairs+together);
+
+  int act=0;
+
+  assume(pairs[0].coef!=0);
+  for(i=1;i<together;i++)
+  {
+    if (pairs[i].idx!=pairs[act].idx)
+    {
+      if (pairs[act].coef!=0)
+      {
+        act=act+1;
+      }
+      pairs[act]=pairs[i];
+    }
+    else
+    {
+      STATISTIC(n_Add); pairs[act].coef=F4mat_to_number_type(npAddM((number)(long)pairs[act].coef,(number)(long)pairs[i].coef,currRing->cf));
+    }
+  }
+
+  if (pairs[act].coef==0)
+  {
+    act--;
+  }
+  int sparse_row_len=act+1;
+  //Print("res len:%d",sparse_row_len);
+  if (sparse_row_len==0) {return NULL;}
+  SparseRow<number_type>* res=new SparseRow<number_type>(sparse_row_len);
+  {
+    number_type* coef_array=res->coef_array;
+    int* idx_array=res->idx_array;
+    for(i=0;i<sparse_row_len;i++)
+    {
+      idx_array[i]=pairs[i].idx;
+      coef_array[i]=pairs[i].coef;
+    }
+  }
+  //omfree(pairs);
+
+  return res;
+}
+template<class number_type> SparseRow<number_type> * noro_red_to_non_poly_t(poly p, int &len, NoroCache<number_type>* cache,slimgb_alg* c){
+  assume(len==pLength(p));
+  if (p==NULL)
+  {
+    len=0;
+    return NULL;
+  }
+
+  MonRedResNP<number_type>* mon=(MonRedResNP<number_type>*) omalloc(len*sizeof(MonRedResNP<number_type>));
+  int i=0;
+  double max_density=0.0;
+  while(p!=NULL)
+  {
+    poly t=p;
+    pIter(p);
+    pNext(t)=NULL;
+
+    MonRedResNP<number_type> red=noro_red_mon_to_non_poly(t,cache,c);
+    if ((red.ref) && (red.ref->row))
+    {
+      double act_density=(double) red.ref->row->len;
+      act_density/=(double) cache->nIrreducibleMonomials;
+      max_density=std::max(act_density,max_density);
+    }
+    mon[i]=red;
+    i++;
+  }
+
+  assume(i==len);
+  len=i;
+  bool dense=true;
+  if (max_density<0.3) dense=false;
+  if (dense){
+    SparseRow<number_type>* res=noro_red_to_non_poly_dense(mon,len,cache);
+    omfree(mon);
+    return res;
+  } else   {
+      SparseRow<number_type>* res=noro_red_to_non_poly_sparse(mon,len,cache);
+      omfree(mon);
+      return res;
+    }
+  //in the loop before nIrreducibleMonomials increases, so position here is important
+
+}
+#endif
+wlen_type pELength(poly p, ring r);
+int terms_sort_crit(const void* a, const void* b);
+//void simplest_gauss_modp(number* a, int nrows,int ncols);
+// a: a[0,0],a[0,1]....a[nrows-1,ncols-1]
+// assume: field is Zp
+#ifdef USE_NORO
+
+
+template <class number_type > void write_poly_to_row(number_type* row, poly h, poly*terms, int tn, ring r){
+  //poly* base=row;
+  while(h!=NULL){
+    //Print("h:%i\n",h);
+    number coef=p_GetCoeff(h,r);
+    poly* ptr_to_h=(poly*) bsearch(&h,terms,tn,sizeof(poly),terms_sort_crit);
+    assume(ptr_to_h!=NULL);
+    int pos=ptr_to_h-terms;
+    row[pos]=F4mat_to_number_type(coef);
+    //number_type_array[base+pos]=coef;
+    pIter(h);
+  }
+}
+template <class number_type > poly row_to_poly(number_type* row, poly* terms, int tn, ring r){
+  poly h=NULL;
+  int j;
+  number_type zero=0;//;npInit(0);
+  for(j=tn-1;j>=0;j--){
+    if (!(zero==(row[j]))){
+      poly t=terms[j];
+      t=p_LmInit(t,r);
+      p_SetCoeff(t,(number)(long) row[j],r);
+      pNext(t)=h;
+      h=t;
+    }
+
+  }
+  return h;
+}
+template <class number_type > int modP_lastIndexRow(number_type* row,int ncols)
+{
+  int lastIndex;
+  const number_type zero=0;//npInit(0);
+  for(lastIndex=ncols-1;lastIndex>=0;lastIndex--)
+  {
+    if (!(row[lastIndex]==zero))
+    {
+      return lastIndex;
+    }
+  }
+  return -1;
+}
+template <class number_type> int term_nodes_sort_crit(const void* a, const void* b)
+{
+  return -pLmCmp(((TermNoroDataNode<number_type>*) a)->t,((TermNoroDataNode<number_type>*) b)->t);
+}
+
+template <class number_type>class ModPMatrixBackSubstProxyOnArray;
+template <class number_type > class ModPMatrixProxyOnArray
+{
+public:
+  friend class ModPMatrixBackSubstProxyOnArray<number_type>;
+
+  int ncols,nrows;
+  ModPMatrixProxyOnArray(number_type* array, int nnrows, int nncols)
+  {
+    this->ncols=nncols;
+    this->nrows=nnrows;
+    rows=(number_type**) omalloc(nnrows*sizeof(number_type*));
+    startIndices=(int*)omalloc(nnrows*sizeof(int));
+    int i;
+    for(i=0;i<nnrows;i++)
+    {
+      rows[i]=array+(i*nncols);
+      updateStartIndex(i,-1);
+    }
+  }
+  ~ModPMatrixProxyOnArray()
+  {
+    omfree(rows);
+    omfree(startIndices);
+  }
+
+  void permRows(int i, int j)
+  {
+    number_type* h=rows[i];
+    rows[i]=rows[j];
+    rows[j]=h;
+    int hs=startIndices[i];
+    startIndices[i]=startIndices[j];
+    startIndices[j]=hs;
+  }
+  void multiplyRow(int row, number_type coef)
+  {
+    int i;
+    number_type* row_array=rows[row];
+    for(i=startIndices[row];i<ncols;i++)
+    {
+      row_array[i]=F4mat_to_number_type(npMult((number)(long) row_array[i],(number)(long) coef,currRing->cf));
+    }
+  }
+  void reduceOtherRowsForward(int r)
+  {
+    //assume rows "under r" have bigger or equal start index
+    number_type* row_array=rows[r];
+    number_type zero=F4mat_to_number_type((number)0 /*npInit(0, currRing)*/);
+    int start=startIndices[r];
+    number_type coef=row_array[start];
+    assume(start<ncols);
+    int other_row;
+    assume(!(npIsZero((number)(long) row_array[start],currRing->cf)));
+    if (!(npIsOne((number)(long) coef,currRing->cf)))
+      multiplyRow(r,F4mat_to_number_type(npInvers((number)(long) coef,currRing->cf)));
+    assume(npIsOne((number)(long) row_array[start],currRing->cf));
+    int lastIndex=modP_lastIndexRow(row_array, ncols);
+    number minus_one=npInit(-1, currRing->cf);
+    for (other_row=r+1;other_row<nrows;other_row++)
+    {
+      assume(startIndices[other_row]>=start);
+      if (startIndices[other_row]==start)
+      {
+        int i;
+        number_type* other_row_array=rows[other_row];
+        number coef2=npNeg((number)(long) other_row_array[start],currRing->cf);
+        if (coef2==minus_one)
+        {
+          for(i=start;i<=lastIndex;i++)
+          {
+            if (row_array[i]!=zero)
+	    { STATISTIC(n_Sub);
+              other_row_array[i]=F4mat_to_number_type(npSubM((number)(long) other_row_array[i], (number)(long) row_array[i],currRing->cf));
+	    }
+
+          }
+      }
+      else
+      {
+          //assume(FALSE);
+          for(i=start;i<=lastIndex;i++)
+          {
+            if (row_array[i]!=zero)
+	    { STATISTIC(n_Add);
+              other_row_array[i]=F4mat_to_number_type(npAddM(npMult(coef2,(number)(long) row_array[i],currRing->cf),(number)(long) other_row_array[i],currRing->cf));
+	    }
+
+          }
+        }
+        updateStartIndex(other_row,start);
+        assume(npIsZero((number)(long) other_row_array[start],currRing->cf));
+      }
+    }
+  }
+  void updateStartIndex(int row,int lower_bound)
+  {
+    number_type* row_array=rows[row];
+    assume((lower_bound<0)||(npIsZero((number)(long) row_array[lower_bound],currRing->cf)));
+    int i;
+    //number_type zero=npInit(0);
+    for(i=lower_bound+1;i<ncols;i++)
+    {
+      if (!(row_array[i]==0))
+        break;
+    }
+    startIndices[row]=i;
+  }
+  int getStartIndex(int row)
+  {
+    return startIndices[row];
+  }
+  BOOLEAN findPivot(int &r, int &c)
+  {
+    //row>=r, col>=c
+
+    while(c<ncols)
+    {
+      int i;
+      for(i=r;i<nrows;i++)
+      {
+        assume(startIndices[i]>=c);
+        if (startIndices[i]==c)
+        {
+          //r=i;
+          if (r!=i)
+            permRows(r,i);
+          return TRUE;
+        }
+      }
+      c++;
+    }
+    return FALSE;
+  }
+protected:
+  number_type** rows;
+  int* startIndices;
+};
+template <class number_type > class ModPMatrixBackSubstProxyOnArray
+{
+  int *startIndices;
+  number_type** rows;
+  int *lastReducibleIndices;
+  int ncols;
+  int nrows;
+  int nonZeroUntil;
+public:
+  void multiplyRow(int row, number_type coef)
+  {
+    int i;
+    number_type* row_array=rows[row];
+    for(i=startIndices[row];i<ncols;i++)
+    {
+      row_array[i]=F4mat_to_number_type(npMult((number)(long) row_array[i],(number)(long) coef,currRing->cf));
+    }
+  }
+  ModPMatrixBackSubstProxyOnArray<number_type> (ModPMatrixProxyOnArray<number_type> & p)
+  {
+//  (number_type* array, int nrows, int ncols, int* startIndices, number_type** rows){
+    //we borrow some parameters ;-)
+    //we assume, that nobody changes the order of the rows
+    this->startIndices=p.startIndices;
+    this->rows=p.rows;
+    this->ncols=p.ncols;
+    this->nrows=p.nrows;
+    lastReducibleIndices=(int*) omalloc(nrows*sizeof(int));
+    nonZeroUntil=0;
+    while(nonZeroUntil<nrows)
+    {
+      if (startIndices[nonZeroUntil]<ncols)
+      {
+        nonZeroUntil++;
+      }
+      else break;
+    }
+    if (TEST_OPT_PROT)
+      Print("rank:%i\n",nonZeroUntil);
+    nonZeroUntil--;
+    int i;
+    for(i=0;i<=nonZeroUntil;i++)
+    {
+      assume(startIndices[i]<ncols);
+      assume(!(npIsZero((number)(long) rows[i][startIndices[i]],currRing->cf)));
+      assume(startIndices[i]>=i);
+      updateLastReducibleIndex(i,nonZeroUntil+1);
+    }
+  }
+  void updateLastReducibleIndex(int r, int upper_bound)
+  {
+    number_type* row_array=rows[r];
+    if (upper_bound>nonZeroUntil) upper_bound=nonZeroUntil+1;
+    int i;
+    const number_type zero=0;//npInit(0);
+    for(i=upper_bound-1;i>r;i--)
+    {
+      int start=startIndices[i];
+      assume(start<ncols);
+      if (!(row_array[start]==zero))
+      {
+        lastReducibleIndices[r]=start;
+        return;
+      }
+    }
+    lastReducibleIndices[r]=-1;
+  }
+  void backwardSubstitute(int r)
+  {
+    int start=startIndices[r];
+    assume(start<ncols);
+    number_type zero=0;//npInit(0);
+    number_type* row_array=rows[r];
+    assume((!(npIsZero((number)(long) row_array[start],currRing->cf))));
+    assume(start<ncols);
+    int other_row;
+    if (!(npIsOne((number)(long) row_array[r],currRing->cf)))
+    {
+      //it should be one, but this safety is not expensive
+      multiplyRow(r, F4mat_to_number_type(npInvers((number)(long) row_array[start],currRing->cf)));
+    }
+    int lastIndex=modP_lastIndexRow(row_array, ncols);
+    assume(lastIndex<ncols);
+    assume(lastIndex>=0);
+    for(other_row=r-1;other_row>=0;other_row--)
+    {
+      assume(lastReducibleIndices[other_row]<=start);
+      if (lastReducibleIndices[other_row]==start)
+      {
+        number_type* other_row_array=rows[other_row];
+        number coef=npNeg((number)(long) other_row_array[start],currRing->cf);
+        assume(!(npIsZero(coef,currRing->cf)));
+        int i;
+        assume(start>startIndices[other_row]);
+        for(i=start;i<=lastIndex;i++)
+        {
+          if (row_array[i]!=zero)
+	  {
+	    STATISTIC(n_Add);
+            other_row_array[i]=F4mat_to_number_type(npAddM(npMult(coef,(number)(long)row_array[i],currRing->cf),(number)(long)other_row_array[i],currRing->cf));
+	  }
+        }
+        updateLastReducibleIndex(other_row,r);
+      }
+    }
+  }
+  ~ModPMatrixBackSubstProxyOnArray<number_type>()
+  {
+    omfree(lastReducibleIndices);
+  }
+  void backwardSubstitute()
+  {
+    int i;
+    for(i=nonZeroUntil;i>0;i--)
+    {
+      backwardSubstitute(i);
+    }
+  }
+};
+template <class number_type > void simplest_gauss_modp(number_type* a, int nrows,int ncols)
+{
+  //use memmoves for changing rows
+  //if (TEST_OPT_PROT)
+  //    PrintS("StartGauss\n");
+  ModPMatrixProxyOnArray<number_type> mat(a,nrows,ncols);
+
+  int c=0;
+  int r=0;
+  while(mat.findPivot(r,c)){
+    //int pivot=find_pivot()
+      mat.reduceOtherRowsForward(r);
+    r++;
+    c++;
+  }
+  ModPMatrixBackSubstProxyOnArray<number_type> backmat(mat);
+  backmat.backwardSubstitute();
+  //backward substitutions
+  //if (TEST_OPT_PROT)
+  //PrintS("StopGauss\n");
+}
+//int term_nodes_sort_crit(const void* a, const void* b);
+template <class number_type> void noro_step(poly*p,int &pn,slimgb_alg* c){
+  //Print("Input rows %d\n",pn);
+  int j;
+  if (TEST_OPT_PROT)
+  {
+    Print("Input rows %d\n",pn);
+  }
+
+  NoroCache<number_type> cache;
+
+  SparseRow<number_type> ** srows=(SparseRow<number_type>**) omAlloc(pn*sizeof(SparseRow<number_type>*));
+  int non_zeros=0;
+  for(j=0;j<pn;j++)
+  {
+    poly h=p[j];
+    int h_len=pLength(h);
+    //number coef;
+    srows[non_zeros]=noro_red_to_non_poly_t<number_type>(h,h_len,&cache,c);
+    if (srows[non_zeros]!=NULL) non_zeros++;
+  }
+  std::vector<DataNoroCacheNode<number_type>*> irr_nodes;
+  cache.collectIrreducibleMonomials(irr_nodes);
+  //now can build up terms array
+  //Print("historic irred Mon%d\n",cache.nIrreducibleMonomials);
+  int n=irr_nodes.size();//cache.countIrreducibleMonomials();
+  cache.nIrreducibleMonomials=n;
+  if (TEST_OPT_PROT)
+  {
+    Print("Irred Mon:%d\n",n);
+    Print("red Mon:%d\n",cache.nReducibleMonomials);
+  }
+  TermNoroDataNode<number_type>* term_nodes=(TermNoroDataNode<number_type>*) omalloc(n*sizeof(TermNoroDataNode<number_type>));
+
+  for(j=0;j<n;j++)
+  {
+    assume(irr_nodes[j]!=NULL);
+    assume(irr_nodes[j]->value_len==NoroCache<number_type>::backLinkCode);
+    term_nodes[j].t=irr_nodes[j]->value_poly;
+    assume(term_nodes[j].t!=NULL);
+    term_nodes[j].node=irr_nodes[j];
+  }
+
+  qsort(term_nodes,n,sizeof(TermNoroDataNode<number_type>),term_nodes_sort_crit<number_type>);
+  poly* terms=(poly*) omalloc(n*sizeof(poly));
+
+  int* old_to_new_indices=(int*) omalloc(cache.nIrreducibleMonomials*sizeof(int));
+  for(j=0;j<n;j++)
+  {
+    old_to_new_indices[term_nodes[j].node->term_index]=j;
+    term_nodes[j].node->term_index=j;
+    terms[j]=term_nodes[j].t;
+  }
+
+  //if (TEST_OPT_PROT)
+  //  Print("Evaluate Rows \n");
+  pn=non_zeros;
+  number_type* number_array=(number_type*) omalloc0(n*pn*sizeof(number_type));
+
+  for(j=0;j<pn;j++)
+  {
+    int i;
+    number_type* row=number_array+n*j;
+    /*for(i=0;i<n;i++)
+    {
+      row[i]=zero;
+    }*/
+
+    SparseRow<number_type>* srow=srows[j];
+
+    if (srow)
+    {
+      int* const idx_array=srow->idx_array;
+      number_type* const coef_array=srow->coef_array;
+      const int len=srow->len;
+      if (srow->idx_array)
+      {
+        for(i=0;i<len;i++)
+	{
+         int idx=old_to_new_indices[idx_array[i]];
+         row[idx]=F4mat_to_number_type(coef_array[i]);
+        }
+      }
+      else
+      {
+        for(i=0;i<len;i++)
+	{
+          row[old_to_new_indices[i]]=F4mat_to_number_type(coef_array[i]);
+        }
+      }
+      delete srow;
+    }
+  }
+
+  //static int export_n=0;
+  //export_mat(number_array,pn,n,"mat%i.py",++export_n);
+  simplest_gauss_modp(number_array,pn,n);
+
+  int p_pos=0;
+  for(j=0;j<pn;j++){
+    poly h=row_to_poly(number_array+j*n,terms,n,c->r);
+    if(h!=NULL){
+      p[p_pos++]=h;
+    }
+  }
+  pn=p_pos;
+  omfree(terms);
+  omfree(term_nodes);
+  omfree(number_array);
+  #ifdef NORO_NON_POLY
+  omfree(srows);
+  omfree(old_to_new_indices);
+  #endif
+  //don't forget the rank
+
+}
+
+template <class number_type> void NoroCache<number_type>::collectIrreducibleMonomials( std::vector<DataNoroCacheNode<number_type> *>& res){
+  int i;
+  for(i=0;i<root.branches_len;i++){
+    collectIrreducibleMonomials(1,root.branches[i],res);
+  }
+}
+template <class number_type> void NoroCache<number_type>::collectIrreducibleMonomials(int level, NoroCacheNode* node, std::vector<DataNoroCacheNode<number_type>*>& res){
+  assume(level>=0);
+  if (node==NULL) return;
+  if (level<(currRing->N))
+  {
+    int i;
+    for(i=0;i<node->branches_len;i++)
+    {
+      collectIrreducibleMonomials(level+1,node->branches[i],res);
+    }
+  }
+  else
+  {
+    DataNoroCacheNode<number_type>* dn=(DataNoroCacheNode<number_type>*) node;
+    if (dn->value_len==backLinkCode)
+    {
+      res.push_back(dn);
+    }
+  }
+}
+
+template<class number_type> DataNoroCacheNode<number_type>* NoroCache<number_type>::getCacheReference(poly term){
+  int i;
+  NoroCacheNode* parent=&root;
+  for(i=1;i<(currRing->N);i++){
+    parent=parent->getBranch(p_GetExp(term,i,currRing));
+    if (!(parent)){
+      return NULL;
+    }
+  }
+  DataNoroCacheNode<number_type>* res_holder=(DataNoroCacheNode<number_type>*) parent->getBranch(p_GetExp(term,i,currRing));
+  return res_holder;
+}
+template<class number_type> poly NoroCache<number_type>::lookup(poly term, BOOLEAN& succ, int & len){
+  int i;
+  NoroCacheNode* parent=&root;
+  for(i=1;i<(currRing->N);i++){
+    parent=parent->getBranch(p_GetExp(term,i,currRing));
+    if (!(parent)){
+      succ=FALSE;
+      return NULL;
+    }
+  }
+  DataNoroCacheNode<number_type>* res_holder=(DataNoroCacheNode<number_type>*) parent->getBranch(p_GetExp(term,i,currRing));
+  if (res_holder){
+    succ=TRUE;
+    if ( /*(*/ res_holder->value_len==backLinkCode /*)*/ ){
+      len=1;
+      return term;
+    }
+    len=res_holder->value_len;
+    return res_holder->value_poly;
+  } else {
+    succ=FALSE;
+    return NULL;
+  }
+}
+#endif
+
+#endif
diff --git a/kernel/GBEngine/tgbgauss.cc b/kernel/GBEngine/tgbgauss.cc
new file mode 100644
index 0000000..81ca785
--- /dev/null
+++ b/kernel/GBEngine/tgbgauss.cc
@@ -0,0 +1,945 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: gauss implementation for F4
+*/
+
+
+
+#include <kernel/mod2.h>
+#include <misc/options.h>
+#include <kernel/GBEngine/tgbgauss.h>
+#include <omalloc/omalloc.h>
+#include <stdlib.h>
+#include <kernel/GBEngine/kutil.h>
+#include <kernel/polys.h>
+static const int bundle_size=100;
+
+mac_poly mac_p_add_ff_qq(mac_poly a, number f,mac_poly b)
+{
+  mac_poly erg;
+  mac_poly* set_this;
+  set_this=&erg;
+  while((a!=NULL) &&(b!=NULL))
+  {
+    if (a->exp<b->exp)
+    {
+      (*set_this)=a;
+      a=a->next;
+      set_this= &((*set_this)->next);
+    }
+    else
+    {
+      if (a->exp>b->exp)
+      {
+        mac_poly in =new mac_poly_r();
+        in->exp=b->exp;
+        in->coef=nMult(b->coef,f);
+        (*set_this)=in;
+        b=b->next;
+        set_this= &((*set_this)->next);
+      }
+      else
+      {
+        //a->exp==b->ecp
+        number n=nMult(b->coef,f);
+        number n2=nAdd(a->coef,n);
+        nDelete(&n);
+        nDelete(&(a->coef));
+        if (nIsZero(n2))
+        {
+          nDelete(&n2);
+          mac_poly ao=a;
+          a=a->next;
+          delete ao;
+          b=b->next;
+        }
+        else
+        {
+          a->coef=n2;
+          b=b->next;
+          (*set_this)=a;
+          a=a->next;
+          set_this= &((*set_this)->next);
+        }
+      }
+    }
+  }
+  if((a==NULL)&&(b==NULL))
+  {
+    (*set_this)=NULL;
+    return erg;
+  }
+  if (b==NULL)
+  {
+    (*set_this=a);
+    return erg;
+  }
+
+  //a==NULL
+  while(b!=NULL)
+  {
+    mac_poly mp= new mac_poly_r();
+    mp->exp=b->exp;
+    mp->coef=nMult(f,b->coef);
+    (*set_this)=mp;
+    set_this=&(mp->next);
+    b=b->next;
+  }
+  (*set_this)=NULL;
+  return erg;
+}
+
+void mac_mult_cons(mac_poly p,number c)
+{
+  while(p)
+  {
+    number m=nMult(p->coef,c);
+    nDelete(&(p->coef));
+    p->coef=m;
+    p=p->next;
+  }
+}
+
+int mac_length(mac_poly p)
+{
+  int l=0;
+  while(p){
+    l++;
+    p=p->next;
+  }
+  return l;
+}
+
+//contrary to delete on the mac_poly_r, the coefficients are also destroyed here
+void mac_destroy(mac_poly p)
+{
+  mac_poly iter=p;
+  while(iter)
+  {
+    mac_poly next=iter->next;
+    nDelete(&iter->coef);
+    delete iter;
+    iter=next;
+  }
+}
+
+void simple_gauss(tgb_sparse_matrix* mat, slimgb_alg* /*c*/)
+{
+  int col, row;
+  int* row_cache=(int*) omAlloc(mat->get_rows()*sizeof(int));
+  col=0;
+  row=0;
+  int i;
+  int pn=mat->get_rows();
+  int matcol=mat->get_columns();
+  int* area=(int*) omAlloc(sizeof(int)*((matcol-1)/bundle_size+1));
+  const int max_area_index=(matcol-1)/bundle_size;
+    //rows are divided in areas
+  //if row begins with columns col, it is located in [area[col/bundle_size],area[col/bundle_size+1]-1]
+  assume(pn>0);
+  //first clear zeroes
+  for(i=0;i<pn;i++)
+  {
+    if(mat->zero_row(i))
+    {
+      mat->perm_rows(i,pn-1);
+      pn--;
+      if(i!=pn){i--;}
+    }
+
+  }
+  mat->sort_rows();
+  for(i=0;i<pn;i++)
+  {
+      row_cache[i]=mat->min_col_not_zero_in_row(i);
+      // Print("row_cache:%d\n",row_cache[i]);
+  }
+  int last_area=-1;
+  for(i=0;i<pn;i++)
+  {
+    int this_area=row_cache[i]/bundle_size;
+    assume(this_area>=last_area);
+    if(this_area>last_area)
+    {
+      int j;
+      for(j=last_area+1;j<=this_area;j++)
+        area[j]=i;
+      last_area=this_area;
+    }
+  }
+  for(i=last_area+1;i<=max_area_index;i++)
+  {
+    area[i]=pn;
+  }
+  while(row<pn-1)
+  {
+    //row is the row where pivot should be
+    // row== pn-1 means we have only to act on one row so no red nec.
+    //we assume further all rows till the pn-1 row are non-zero
+
+    //select column
+
+    //col=mat->min_col_not_zero_in_row(row);
+    int max_in_area;
+    {
+      int tai=row_cache[row]/bundle_size;
+      assume(tai<=max_area_index);
+      if(tai==max_area_index)
+        max_in_area=pn-1;
+      else
+        max_in_area=area[tai+1]-1;
+    }
+    assume(row_cache[row]==mat->min_col_not_zero_in_row(row));
+    col=row_cache[row];
+
+    assume(col!=matcol);
+    int found_in_row;
+
+    found_in_row=row;
+    BOOLEAN must_reduce=FALSE;
+    assume(pn<=mat->get_rows());
+    for(i=row+1;i<=max_in_area;i++)
+    {
+      int first;//=mat->min_col_not_zero_in_row(i);
+      assume(row_cache[i]==mat->min_col_not_zero_in_row(i));
+      first=row_cache[i];
+      assume(first!=matcol);
+      if(first<col)
+      {
+        col=first;
+        found_in_row=i;
+        must_reduce=FALSE;
+      }
+      else
+      {
+        if(first==col)
+          must_reduce=TRUE;
+      }
+    }
+    //select pivot
+    int act_l=nSize(mat->get(found_in_row,col))*mat->non_zero_entries(found_in_row);
+    if(must_reduce)
+    {
+      for(i=found_in_row+1;i<=max_in_area;i++)
+      {
+        assume(mat->min_col_not_zero_in_row(i)>=col);
+        assume(row_cache[i]==mat->min_col_not_zero_in_row(i));
+#ifndef SING_NDEBUG
+        int first=row_cache[i];
+        assume(first!=matcol);
+#endif
+        //      if((!(mat->is_zero_entry(i,col)))&&(mat->non_zero_entries(i)<act_l))
+        int nz;
+        if((row_cache[i]==col)&&((nz=nSize(mat->get(i,col))*mat->non_zero_entries(i))<act_l))
+        {
+          found_in_row=i;
+          act_l=nz;
+        }
+
+      }
+    }
+    mat->perm_rows(row,found_in_row);
+    int h=row_cache[row];
+    row_cache[row]=row_cache[found_in_row];
+    row_cache[found_in_row]=h;
+
+    if(!must_reduce)
+    {
+      row++;
+      continue;
+    }
+    //reduction
+    //must extract content and normalize here
+    mat->row_content(row);
+    mat->row_normalize(row);
+
+    //for(i=row+1;i<pn;i++){
+    for(i=max_in_area;i>row;i--)
+    {
+      int col_area_index=col/bundle_size;
+      assume(col_area_index<=max_area_index);
+      assume(mat->min_col_not_zero_in_row(i)>=col);
+      assume(row_cache[i]==mat->min_col_not_zero_in_row(i));
+#ifndef SING_NDEBUG
+      int first=row_cache[i];
+      assume(first!=matcol);
+#endif
+      if(row_cache[i]==col)
+      {
+
+        number c1=mat->get(i,col);
+        number c2=mat->get(row,col);
+        number n1=c1;
+        number n2=c2;
+
+        ksCheckCoeff(&n1,&n2,currRing->cf);
+        //nDelete(&c1);
+        n1=nInpNeg(n1);
+        mat->mult_row(i,n2);
+        mat->add_lambda_times_row(i,row,n1);
+        nDelete(&n1);
+        nDelete(&n2);
+        assume(mat->is_zero_entry(i,col));
+        row_cache[i]=mat->min_col_not_zero_in_row(i);
+        assume(mat->min_col_not_zero_in_row(i)>col);
+        if(row_cache[i]==matcol)
+        {
+          int index;
+          index=i;
+          int last_in_area;
+          int this_cai=col_area_index;
+          while(this_cai<max_area_index)
+          {
+            last_in_area=area[this_cai+1]-1;
+            int h_c=row_cache[last_in_area];
+            row_cache[last_in_area]=row_cache[index];
+            row_cache[index]=h_c;
+            mat->perm_rows(index,last_in_area);
+            index=last_in_area;
+            this_cai++;
+            area[this_cai]--;
+          }
+          mat->perm_rows(index,pn-1);
+          row_cache[index]=row_cache[pn-1];
+          row_cache[pn-1]=matcol;
+          pn--;
+        }
+        else
+        {
+          int index;
+          index=i;
+          int last_in_area;
+          int this_cai=col_area_index;
+          int final_cai=row_cache[index]/bundle_size;
+          assume(final_cai<=max_area_index);
+          while(this_cai<final_cai)
+          {
+            last_in_area=area[this_cai+1]-1;
+            int h_c=row_cache[last_in_area];
+            row_cache[last_in_area]=row_cache[index];
+            row_cache[index]=h_c;
+            mat->perm_rows(index,last_in_area);
+            index=last_in_area;
+            this_cai++;
+            area[this_cai]--;
+          }
+        }
+      }
+      else
+        assume(mat->min_col_not_zero_in_row(i)>col);
+    }
+//     for(i=row+1;i<pn;i++)
+//     {
+//       assume(mat->min_col_not_zero_in_row(i)==row_cache[i]);
+//       // if(mat->zero_row(i))
+//       assume(matcol==mat->get_columns());
+//       if(row_cache[i]==matcol)
+//       {
+//         assume(mat->zero_row(i));
+//         mat->perm_rows(i,pn-1);
+//         row_cache[i]=row_cache[pn-1];
+//         row_cache[pn-1]=matcol;
+//         pn--;
+//         if(i!=pn){i--;}
+//       }
+//     }
+#ifdef TGB_DEBUG
+  {
+    int last=-1;
+    for(i=0;i<pn;i++)
+    {
+      int act=mat->min_col_not_zero_in_row(i);
+      assume(act>last);
+    }
+    for(i=pn;i<mat->get_rows();i++)
+    {
+      assume(mat->zero_row(i));
+    }
+  }
+#endif
+    row++;
+  }
+  omFree(area);
+  omFree(row_cache);
+}
+
+void simple_gauss2(tgb_matrix* mat)
+{
+  int col, row;
+  col=0;
+  row=0;
+  int i;
+  int pn=mat->get_rows();
+  assume(pn>0);
+  //first clear zeroes
+//   for(i=0;i<pn;i++)
+//   {
+//     if(mat->zero_row(i))
+//     {
+//       mat->perm_rows(i,pn-1);
+//       pn--;
+//       if(i!=pn){i--;}
+//     }
+//   }
+  while((row<pn-1)&&(col<mat->get_columns())){
+    //row is the row where pivot should be
+    // row== pn-1 means we have only to act on one row so no red nec.
+    //we assume further all rows till the pn-1 row are non-zero
+
+    //select column
+
+    //    col=mat->min_col_not_zero_in_row(row);
+    assume(col!=mat->get_columns());
+    int found_in_row=-1;
+
+    //    found_in_row=row;
+    assume(pn<=mat->get_rows());
+    for(i=row;i<pn;i++)
+    {
+      //    int first=mat->min_col_not_zero_in_row(i);
+      //  if(first<col)
+      if(!(mat->is_zero_entry(i,col)))
+      {
+        found_in_row=i;
+        break;
+      }
+    }
+    if(found_in_row!=-1)
+    {
+    //select pivot
+      int act_l=mat->non_zero_entries(found_in_row);
+      for(i=i+1;i<pn;i++)
+      {
+        int vgl;
+        assume(mat->min_col_not_zero_in_row(i)>=col);
+        if((!(mat->is_zero_entry(i,col)))
+        &&((vgl=mat->non_zero_entries(i))<act_l))
+        {
+          found_in_row=i;
+          act_l=vgl;
+        }
+
+      }
+      mat->perm_rows(row,found_in_row);
+
+      //reduction
+      for(i=row+1;i<pn;i++){
+        assume(mat->min_col_not_zero_in_row(i)>=col);
+        if(!(mat->is_zero_entry(i,col)))
+        {
+          number c1=nCopy(mat->get(i,col));
+          c1=nInpNeg(c1);
+          number c2=mat->get(row,col);
+          number n1=c1;
+          number n2=c2;
+
+          ksCheckCoeff(&n1,&n2,currRing->cf);
+          nDelete(&c1);
+          mat->mult_row(i,n2);
+          mat->add_lambda_times_row(i,row,n1);
+          assume(mat->is_zero_entry(i,col));
+        }
+        assume(mat->min_col_not_zero_in_row(i)>col);
+      }
+      row++;
+    }
+    col++;
+    // for(i=row+1;i<pn;i++)
+//     {
+//       if(mat->zero_row(i))
+//       {
+//         mat->perm_rows(i,pn-1);
+//         pn--;
+//         if(i!=pn){i--;}
+//       }
+//     }
+  }
+}
+
+
+tgb_matrix::tgb_matrix(int i, int j)
+{
+  n=(number**) omAlloc(i*sizeof (number*));;
+  int z;
+  int z2;
+  for(z=0;z<i;z++)
+  {
+    n[z]=(number*)omAlloc(j*sizeof(number));
+    for(z2=0;z2<j;z2++)
+    {
+      n[z][z2]=nInit(0);
+    }
+  }
+  columns=j;
+  rows=i;
+  free_numbers=FALSE;
+}
+
+tgb_matrix::~tgb_matrix()
+{
+  int z;
+  for(z=0;z<rows;z++)
+  {
+    if(n[z])
+    {
+      if(free_numbers)
+      {
+        int z2;
+        for(z2=0;z2<columns;z2++)
+        {
+          nDelete(&(n[z][z2]));
+        }
+      }
+      omFree(n[z]);
+    }
+  }
+  omfree(n);
+}
+
+void tgb_matrix::print()
+{
+  int i;
+  int j;
+  PrintLn();
+  for(i=0;i<rows;i++)
+  {
+    PrintS("(");
+    for(j=0;j<columns;j++)
+    {
+      StringSetS("");
+      n_Write(n[i][j],currRing);
+      char *s=StringEndS();
+      PrintS(s);
+      omFree(s);
+      PrintS("\t");
+    }
+    PrintS(")\n");
+  }
+}
+
+//transfers ownership of n to the matrix
+void tgb_matrix::set(int i, int j, number nn)
+{
+  assume(i<rows);
+  assume(j<columns);
+  n[i][j]=nn;
+}
+
+int tgb_matrix::get_rows()
+{
+  return rows;
+}
+
+int tgb_matrix::get_columns()
+{
+  return columns;
+}
+
+number tgb_matrix::get(int i, int j)
+{
+  assume(i<rows);
+  assume(j<columns);
+  return n[i][j];
+}
+
+BOOLEAN tgb_matrix::is_zero_entry(int i, int j)
+{
+  return (nIsZero(n[i][j]));
+}
+
+void tgb_matrix::perm_rows(int i, int j)
+{
+  number* h;
+  h=n[i];
+  n[i]=n[j];
+  n[j]=h;
+}
+
+int tgb_matrix::min_col_not_zero_in_row(int row)
+{
+  int i;
+  for(i=0;i<columns;i++)
+  {
+    if(!(nIsZero(n[row][i])))
+      return i;
+  }
+  return columns;//error code
+}
+
+int tgb_matrix::next_col_not_zero(int row,int pre)
+{
+  int i;
+  for(i=pre+1;i<columns;i++)
+  {
+    if(!(nIsZero(n[row][i])))
+      return i;
+  }
+  return columns;//error code
+}
+
+BOOLEAN tgb_matrix::zero_row(int row)
+{
+  int i;
+  for(i=0;i<columns;i++)
+  {
+    if(!(nIsZero(n[row][i])))
+      return FALSE;
+  }
+  return TRUE;
+}
+
+int tgb_matrix::non_zero_entries(int row)
+{
+  int i;
+  int z=0;
+  for(i=0;i<columns;i++)
+  {
+    if(!(nIsZero(n[row][i])))
+      z++;
+  }
+  return z;
+}
+
+//row add_to=row add_to +row summand*factor
+void tgb_matrix::add_lambda_times_row(int add_to,int summand,number factor)
+{
+  int i;
+  for(i=0;i<columns;i++)
+  {
+    if(!(nIsZero(n[summand][i])))
+    {
+      number n1=n[add_to][i];
+      number n2=nMult(factor,n[summand][i]);
+      n[add_to][i]=nAdd(n1,n2);
+      nDelete(&n1);
+      nDelete(&n2);
+    }
+  }
+}
+
+void tgb_matrix::mult_row(int row,number factor)
+{
+  if (nIsOne(factor))
+    return;
+  int i;
+  for(i=0;i<columns;i++)
+  {
+    if(!(nIsZero(n[row][i])))
+    {
+      number n1=n[row][i];
+      n[row][i]=nMult(n1,factor);
+      nDelete(&n1);
+    }
+  }
+}
+
+void tgb_matrix::free_row(int row, BOOLEAN free_non_zeros)
+{
+  int i;
+  for(i=0;i<columns;i++)
+    if((free_non_zeros)||(!(nIsZero(n[row][i]))))
+      nDelete(&(n[row][i]));
+  omFree(n[row]);
+  n[row]=NULL;
+}
+
+tgb_sparse_matrix::tgb_sparse_matrix(int i, int j, ring rarg)
+{
+  mp=(mac_poly*) omAlloc(i*sizeof (mac_poly));;
+  int z;
+  for(z=0;z<i;z++)
+  {
+    mp[z]=NULL;
+  }
+  columns=j;
+  rows=i;
+  free_numbers=FALSE;
+  r=rarg;
+}
+
+tgb_sparse_matrix::~tgb_sparse_matrix()
+{
+  int z;
+  for(z=0;z<rows;z++)
+  {
+    if(mp[z]!=NULL)
+    {
+      if(free_numbers)
+      {
+        mac_destroy(mp[z]);
+      }
+      else {
+        while(mp[z]!=NULL)
+        {
+          mac_poly next=mp[z]->next;
+          delete mp[z];
+          mp[z]=next;
+        }
+      }
+    }
+  }
+  omfree(mp);
+}
+
+static int row_cmp_gen(const void* a, const void* b)
+{
+  const mac_poly ap= *((mac_poly*) a);
+  const mac_poly bp=*((mac_poly*) b);
+  if (ap==NULL) return 1;
+  if (bp==NULL) return -1;
+  if (ap->exp<bp->exp) return -1;
+  return 1;
+}
+
+void tgb_sparse_matrix::sort_rows()
+{
+  qsort(mp,rows,sizeof(mac_poly),row_cmp_gen);
+}
+
+void tgb_sparse_matrix::print()
+{
+  int i;
+  int j;
+  PrintLn();
+  for(i=0;i<rows;i++)
+  {
+    PrintS("(");
+    for(j=0;j<columns;j++)
+    {
+      StringSetS("");
+      number n=get(i,j);
+      n_Write(n,currRing);
+      char *s=StringEndS();
+      PrintS(s);
+      omFree(s);
+      PrintS("\t");
+    }
+    PrintS(")\n");
+  }
+}
+
+//transfers ownership of n to the matrix
+void tgb_sparse_matrix::set(int i, int j, number n)
+{
+  assume(i<rows);
+  assume(j<columns);
+  mac_poly* set_this=&mp[i];
+  //  while(((*set_this)!=NULL)&&((*set_this)\AD>exp<j))
+  while(((*set_this)!=NULL) && ((*set_this)->exp<j))
+    set_this=&((*set_this)->next);
+
+  if (((*set_this)==NULL)||((*set_this)->exp>j))
+  {
+    if (nIsZero(n)) return;
+    mac_poly old=(*set_this);
+    (*set_this)=new mac_poly_r();
+    (*set_this)->exp=j;
+    (*set_this)->coef=n;
+    (*set_this)->next=old;
+    return;
+  }
+  assume((*set_this)->exp==j);
+  if(!nIsZero(n))
+  {
+    nDelete(&(*set_this)->coef);
+    (*set_this)->coef=n;
+  }
+  else
+  {
+    nDelete(&(*set_this)->coef);
+    mac_poly dt=(*set_this);
+    (*set_this)=dt->next;
+    delete dt;
+  }
+  return;
+}
+
+int tgb_sparse_matrix::get_rows()
+{
+  return rows;
+}
+
+int tgb_sparse_matrix::get_columns()
+{
+  return columns;
+}
+
+number tgb_sparse_matrix::get(int i, int j)
+{
+  assume(i<rows);
+  assume(j<columns);
+  mac_poly rr=mp[i];
+  while((rr!=NULL)&&(rr->exp<j))
+    rr=rr->next;
+  if ((rr==NULL)||(rr->exp>j))
+  {
+    number n=nInit(0);
+    return n;
+  }
+  assume(rr->exp==j);
+  return rr->coef;
+}
+
+BOOLEAN tgb_sparse_matrix::is_zero_entry(int i, int j)
+{
+  assume(i<rows);
+  assume(j<columns);
+  mac_poly rr=mp[i];
+  while((rr!=NULL)&&(rr->exp<j))
+    rr=rr->next;
+  if ((rr==NULL)||(rr->exp>j))
+  {
+    return TRUE;
+  }
+  assume(!nIsZero(rr->coef));
+  assume(rr->exp==j);
+  return FALSE;
+}
+
+int tgb_sparse_matrix::min_col_not_zero_in_row(int row)
+{
+  if(mp[row]!=NULL)
+  {
+    assume(!nIsZero(mp[row]->coef));
+    return mp[row]->exp;
+  }
+  else
+    return columns;//error code
+}
+
+int tgb_sparse_matrix::next_col_not_zero(int row,int pre)
+{
+  mac_poly rr=mp[row];
+  while((rr!=NULL)&&(rr->exp<=pre))
+    rr=rr->next;
+  if(rr!=NULL)
+  {
+    assume(!nIsZero(rr->coef));
+    return rr->exp;
+  }
+  return columns;//error code
+}
+
+BOOLEAN tgb_sparse_matrix::zero_row(int row)
+{
+  assume((mp[row]==NULL)||(!nIsZero(mp[row]->coef)));
+  if (mp[row]==NULL)
+    return TRUE;
+  else
+    return FALSE;
+}
+
+void tgb_sparse_matrix::row_normalize(int row)
+{
+  if (!rField_has_simple_inverse(r))  /* Z/p, GF(p,n), R, long R/C */
+  {
+    mac_poly m=mp[row];
+    while (m!=NULL)
+    {
+      #ifndef SING_NDEBUG
+      if (currRing==r) {nTest(m->coef);}
+      #endif
+      n_Normalize(m->coef,r);
+      m=m->next;
+    }
+  }
+}
+
+void tgb_sparse_matrix::row_content(int row)
+{
+  mac_poly ph=mp[row];
+  number h,d;
+  mac_poly p;
+
+  if(TEST_OPT_CONTENTSB) return;
+  if(ph->next==NULL)
+  {
+    nDelete(&ph->coef);
+    ph->coef=nInit(1);
+  }
+  else
+  {
+    nNormalize(ph->coef);
+    if(!nGreaterZero(ph->coef))
+    {
+      //ph = pNeg(ph);
+      p=ph;
+      while(p!=NULL)
+      {
+        p->coef=nInpNeg(p->coef);
+        p=p->next;
+      }
+    }
+
+    h=nCopy(ph->coef);
+    p = ph->next;
+
+    while (p!=NULL)
+    {
+      nNormalize(p->coef);
+      d=n_Gcd(h,p->coef,currRing->cf);
+      nDelete(&h);
+      h = d;
+      if(nIsOne(h))
+      {
+        break;
+      }
+      p=p->next;
+    }
+    p = ph;
+    //number tmp;
+    if(!nIsOne(h))
+    {
+      while (p!=NULL)
+      {
+        d = nExactDiv(p->coef,h);
+        nDelete(&p->coef);
+        p->coef=d;
+        p=p->next;
+      }
+    }
+    nDelete(&h);
+  }
+}
+int tgb_sparse_matrix::non_zero_entries(int row)
+{
+  return mac_length(mp[row]);
+}
+
+//row add_to=row add_to +row summand*factor
+void tgb_sparse_matrix::add_lambda_times_row(int add_to,int summand,number factor)
+{
+  mp[add_to]= mac_p_add_ff_qq(mp[add_to], factor,mp[summand]);
+}
+
+void tgb_sparse_matrix::mult_row(int row,number factor)
+{
+  if (nIsZero(factor))
+  {
+    mac_destroy(mp[row]);
+    mp[row]=NULL;
+
+    return;
+  }
+  if(nIsOne(factor))
+    return;
+  mac_mult_cons(mp[row],factor);
+}
+
+void tgb_sparse_matrix::free_row(int row, BOOLEAN free_non_zeros)
+{
+  if(free_non_zeros)
+    mac_destroy(mp[row]);
+  else
+  {
+    while(mp[row]!=NULL)
+    {
+      mac_poly next=mp[row]->next;
+      delete mp[row];
+      mp[row]=next;
+    }
+  }
+  mp[row]=NULL;
+}
diff --git a/kernel/GBEngine/tgbgauss.h b/kernel/GBEngine/tgbgauss.h
new file mode 100644
index 0000000..c526007
--- /dev/null
+++ b/kernel/GBEngine/tgbgauss.h
@@ -0,0 +1,102 @@
+#ifndef TGBGAUSS_HEADER
+#define TGBGAUSS_HEADER
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: gauss implementation for F4 header
+*/
+// #include <kernel/mod2.h>
+#include <coeffs/numbers.h>
+#include <polys/monomials/p_polys.h>
+//#include "tgb_internal.h"
+
+class slimgb_alg;
+
+class tgb_matrix{
+ private:
+  number** n;
+  int columns;
+  int rows;
+  BOOLEAN free_numbers;
+ public:
+  tgb_matrix(int i, int j);
+  ~tgb_matrix();
+  int get_rows();
+  int get_columns();
+  void print();
+  void perm_rows(int i, int j);
+  void set(int i, int j, number n);
+  number get(int i, int j);
+  BOOLEAN is_zero_entry(int i, int j);
+  void free_row(int row, BOOLEAN free_non_zeros=TRUE);
+  int min_col_not_zero_in_row(int row);
+  int next_col_not_zero(int row,int pre);
+  BOOLEAN zero_row(int row);
+  void mult_row(int row,number factor);
+  void add_lambda_times_row(int add_to,int summand,number factor);
+  int non_zero_entries(int row);
+};
+
+class mac_poly_r{
+public:
+  number coef;
+  mac_poly_r* next;
+  int exp;
+  mac_poly_r():next(NULL){}
+};
+//mac_polys exp are smaller iff they are greater by monomial ordering
+//corresponding to solving linear equations notation
+
+typedef mac_poly_r* mac_poly;
+
+class tgb_sparse_matrix{
+ private:
+  ring r;
+  mac_poly* mp;
+  int columns;
+  int rows;
+  BOOLEAN free_numbers;
+ public:
+  void sort_rows();
+  friend poly free_row_to_poly(tgb_sparse_matrix* mat, int row, poly* monoms, int monom_index);
+  friend void init_with_mac_poly(tgb_sparse_matrix* mat, int row, mac_poly m);
+  tgb_sparse_matrix(int i, int j, ring rarg);
+  ~tgb_sparse_matrix();
+  int get_rows();
+  int get_columns();
+  void print();
+  void row_normalize(int row);
+  void row_content(int row);
+  //  void perm_rows(int i, int j);
+  void perm_rows(int i, int j){
+  mac_poly h;
+  h=mp[i];
+  mp[i]=mp[j];
+  mp[j]=h;
+  }
+  void set(int i, int j, number n);
+  number get(int i, int j);
+  BOOLEAN is_zero_entry(int i, int j);
+  void free_row(int row, BOOLEAN free_non_zeros=TRUE);
+  int min_col_not_zero_in_row(int row);
+  int next_col_not_zero(int row,int pre);
+  BOOLEAN zero_row(int row);
+  void mult_row(int row,number factor);
+  void add_lambda_times_row(int add_to,int summand,number factor);
+  int non_zero_entries(int row);
+};
+void simple_gauss(tgb_sparse_matrix* mat, slimgb_alg* c);
+void simple_gauss2(tgb_matrix* mat);
+
+
+
+mac_poly mac_p_add_ff_qq(mac_poly a, number f,mac_poly b);
+
+void mac_mult_cons(mac_poly p,number c);
+int mac_length(mac_poly p);
+
+//contrary to delete on the mac_poly_r, the coefficients are also destroyed here
+void mac_destroy(mac_poly p);
+
+#endif
diff --git a/kernel/GBEngine/units.cc b/kernel/GBEngine/units.cc
new file mode 100644
index 0000000..4460b57
--- /dev/null
+++ b/kernel/GBEngine/units.cc
@@ -0,0 +1,78 @@
+/*****************************************
+*  Computer Algebra System SINGULAR      *
+*****************************************/
+/*
+* ABSTRACT: procedures to compute with units
+*/
+
+
+
+
+#include <kernel/mod2.h>
+#include <kernel/structs.h>
+#include <coeffs/numbers.h>
+#include <kernel/polys.h>
+#include <kernel/ideals.h>
+#include <misc/intvec.h>
+#include <polys/matpol.h>
+#include <kernel/GBEngine/kstd1.h>
+#include <kernel/GBEngine/units.h>
+
+ideal redNF(ideal N,ideal M,matrix U,int d,intvec *w)
+{
+  matrix U0=NULL;
+  if(U!=NULL)
+  {
+    U0=mp_Copy(U,currRing);
+    number u0;
+    for(int i=IDELEMS(M)-1;i>=0;i--)
+    {
+      u0=nInvers(pGetCoeff(MATELEM(U0,i+1,i+1)));
+      MATELEM(U0,i+1,i+1)=pMult_nn(MATELEM(U0,i+1,i+1),u0);
+      M->m[i]=pMult_nn(M->m[i],u0);
+    }
+  }
+  ideal M0=idInit(IDELEMS(M),M->rank);
+  ideal M1=kNF(N,currRing->qideal,M,0,KSTD_NF_ECART);
+  while(idElem(M1)>0&&(d==-1||id_MinDegW(M1,w,currRing)<=d))
+  {
+    for(int i=IDELEMS(M)-1;i>=0;i--)
+    {
+      M0->m[i]=pAdd(M0->m[i],pHead(pCopy(M1->m[i])));
+      if(U0!=NULL)
+        M->m[i]=pSub(M->m[i],pMult(pHead(pCopy(M1->m[i])),
+                                   pCopy(MATELEM(U0,i+1,i+1))));
+      else
+        M->m[i]=pSub(M->m[i],pHead(pCopy(M1->m[i])));
+    }
+    idDelete(&M1);
+    M1=kNF(N,currRing->qideal,M,0,KSTD_NF_ECART);
+  }
+  idDelete(&M1);
+  idDelete(&N);
+  idDelete(&M);
+  if(U0!=NULL)
+    idDelete((ideal*)&U0);
+  return M0;
+}
+
+poly redNF(ideal N,poly p,poly u,int d,intvec *w)
+{
+  ideal M=idInit(1,pGetComp(p));
+  M->m[0]=p;
+  ideal M0;
+  if(u==NULL)
+    M0=redNF(N,M,NULL,d,w);
+  else
+  {
+    matrix U=mpNew(1,1);
+    MATELEM(U,1,1)=u;
+    M0=redNF(N,M,U,d,w);
+    idDelete((ideal*)&U);
+  }
+  poly p0=M0->m[0];
+  M0->m[0]=NULL;
+  idDelete(&M0);
+  return p0;
+}
+
diff --git a/kernel/GBEngine/units.h b/kernel/GBEngine/units.h
new file mode 100644
index 0000000..9634b08
--- /dev/null
+++ b/kernel/GBEngine/units.h
@@ -0,0 +1,14 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: procedures to compute with units
+*/
+
+#ifndef UNITS_H
+#define UNITS_H
+
+ideal redNF(ideal N,ideal M,matrix U=NULL,int d=-1,intvec *w=NULL);
+poly redNF(ideal N,poly p,poly u=NULL,int d=-1,intvec *w=NULL);
+
+#endif
diff --git a/kernel/Makefile.am b/kernel/Makefile.am
new file mode 100644
index 0000000..93ab5d7
--- /dev/null
+++ b/kernel/Makefile.am
@@ -0,0 +1,64 @@
+ACLOCAL_AMFLAGS = -I ../m4
+
+noinst_LTLIBRARIES = libkernelCommon.la libkernel.la
+
+AM_CPPFLAGS = \
+-I${top_srcdir} -I${top_builddir} -I${top_srcdir}/libpolys -I${top_builddir}/libpolys \
+$(FACTORY_INCLUDES) $(NTL_CFLAGS) $(FLINT_CFLAGS) $(GMP_CFLAGS)
+
+SOURCES = polys.cc \
+    ideals.cc \
+    fast_mult.cc digitech.cc \
+    preimage.cc \
+    mod2.h
+
+libkernelCommon_la_SOURCES  = $(SOURCES)
+libkernelCommon_la_LIBADD   = ${USEPPROCSDYNAMICLDFLAGS} ${USEPPROCSDYNAMICLD} \
+${abs_top_builddir}/libpolys/polys/libpolys.la
+
+###### libkerneldir = $(libdir)/singular
+
+KERNELHEADERS = mod2.h structs.h polys.h ideals.h \
+	preimage.h fast_mult.h digitech.h
+
+libkernel_la_SOURCES=$(KERNELHEADERS)
+
+libkernel_la_includedir=${includedir}/singular/kernel
+libkernel_la_include_HEADERS=$(KERNELHEADERS)
+
+SUBDIRS=numeric fglm groebner_walk combinatorics spectrum linear_algebra maps GBEngine oswrapper
+
+libkernel_la_LIBADD   = \
+${builddir}/numeric/libnumeric.la \
+${builddir}/fglm/libfglm.la \
+${builddir}/groebner_walk/libgroebner_walk.la \
+${builddir}/combinatorics/libcombinatorics.la \
+${builddir}/spectrum/libspectrum.la \
+${builddir}/linear_algebra/liblinear_algebra.la \
+${builddir}/maps/libmaps.la \
+${builddir}/GBEngine/libGBEngine.la \
+${builddir}/oswrapper/liboswrapper.la \
+${builddir}/libkernelCommon.la
+
+### TODO: the following has to be addapted...
+TESTS_ENVIRONMENT = SINGULARPATH='${abs_top_builddir}/libpolys/polys/.libs:${abs_top_builddir}/factory/gftables'
+TESTS_ENVIRONMENT += SINGULAR_ROOT_DIR='${abs_top_builddir}'
+
+TESTS = test
+
+check_PROGRAMS = $(TESTS)
+
+test_SOURCES = test.cc
+test_LDADD   = libkernel.la
+
+# These files are built first
+# BUILT_SOURCES = MOD
+
+# MOD: ${top_builddir}/libpolys/tests/MOD
+# 	ln -snf ${top_builddir}/libpolys/tests/MOD ${builddir}/MOD
+
+
+CLEANFILES = $(TESTS)
+# $(BUILT_SOURCES)
+
+
diff --git a/kernel/Makefile.in b/kernel/Makefile.in
new file mode 100644
index 0000000..9623601
--- /dev/null
+++ b/kernel/Makefile.in
@@ -0,0 +1,1278 @@
+# Makefile.in generated by automake 1.13.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 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@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+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@
+TESTS = test$(EXEEXT)
+check_PROGRAMS = $(am__EXEEXT_1)
+subdir = kernel
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/build-aux/depcomp \
+	$(libkernel_la_include_HEADERS) \
+	$(top_srcdir)/build-aux/test-driver COPYING ChangeLog README \
+	mkinstalldirs
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_append_compile_flags.m4 \
+	$(top_srcdir)/m4/ax_append_flag.m4 \
+	$(top_srcdir)/m4/ax_append_link_flags.m4 \
+	$(top_srcdir)/m4/ax_check_compile_flag.m4 \
+	$(top_srcdir)/m4/ax_check_link_flag.m4 \
+	$(top_srcdir)/m4/ax_compute_relative_paths.m4 \
+	$(top_srcdir)/m4/ax_normalize_path.m4 \
+	$(top_srcdir)/m4/ax_prefix_config_h.m4 \
+	$(top_srcdir)/m4/ax_pthread.m4 \
+	$(top_srcdir)/m4/ax_python_embed.m4 \
+	$(top_srcdir)/m4/ax_python_with_version.m4 \
+	$(top_srcdir)/m4/cpu-check.m4 $(top_srcdir)/m4/dbm-check.m4 \
+	$(top_srcdir)/m4/flags.m4 $(top_srcdir)/m4/flint-check.m4 \
+	$(top_srcdir)/m4/gfanlib-check.m4 \
+	$(top_srcdir)/m4/gmp-check.m4 \
+	$(top_srcdir)/m4/google-perftools.m4 \
+	$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+	$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+	$(top_srcdir)/m4/lt~obsolete.m4 \
+	$(top_srcdir)/m4/mathic-check.m4 $(top_srcdir)/m4/ntl-check.m4 \
+	$(top_srcdir)/m4/options.m4 $(top_srcdir)/m4/p-procs.m4 \
+	$(top_srcdir)/m4/polymake-check.m4 \
+	$(top_srcdir)/m4/readline-check.m4 $(top_srcdir)/configure.ac
+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 =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+libkernel_la_DEPENDENCIES = ${builddir}/numeric/libnumeric.la \
+	${builddir}/fglm/libfglm.la \
+	${builddir}/groebner_walk/libgroebner_walk.la \
+	${builddir}/combinatorics/libcombinatorics.la \
+	${builddir}/spectrum/libspectrum.la \
+	${builddir}/linear_algebra/liblinear_algebra.la \
+	${builddir}/maps/libmaps.la \
+	${builddir}/GBEngine/libGBEngine.la \
+	${builddir}/oswrapper/liboswrapper.la \
+	${builddir}/libkernelCommon.la
+am__objects_1 =
+am_libkernel_la_OBJECTS = $(am__objects_1)
+libkernel_la_OBJECTS = $(am_libkernel_la_OBJECTS)
+AM_V_lt = $(am__v_lt_ at AM_V@)
+am__v_lt_ = $(am__v_lt_ at AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 = 
+am__DEPENDENCIES_1 =
+libkernelCommon_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \
+	$(am__DEPENDENCIES_1) \
+	${abs_top_builddir}/libpolys/polys/libpolys.la
+am__objects_2 = polys.lo ideals.lo fast_mult.lo digitech.lo \
+	preimage.lo
+am_libkernelCommon_la_OBJECTS = $(am__objects_2)
+libkernelCommon_la_OBJECTS = $(am_libkernelCommon_la_OBJECTS)
+am__EXEEXT_1 = test$(EXEEXT)
+am_test_OBJECTS = test.$(OBJEXT)
+test_OBJECTS = $(am_test_OBJECTS)
+test_DEPENDENCIES = libkernel.la
+AM_V_P = $(am__v_P_ at AM_V@)
+am__v_P_ = $(am__v_P_ at AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_ at AM_V@)
+am__v_GEN_ = $(am__v_GEN_ at AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_ at AM_V@)
+am__v_at_ = $(am__v_at_ at AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+DEFAULT_INCLUDES = -I. at am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \
+	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+	$(AM_CXXFLAGS) $(CXXFLAGS)
+AM_V_CXX = $(am__v_CXX_ at AM_V@)
+am__v_CXX_ = $(am__v_CXX_ at AM_DEFAULT_V@)
+am__v_CXX_0 = @echo "  CXX     " $@;
+am__v_CXX_1 = 
+CXXLD = $(CXX)
+CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+	$(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CXXLD = $(am__v_CXXLD_ at AM_V@)
+am__v_CXXLD_ = $(am__v_CXXLD_ at AM_DEFAULT_V@)
+am__v_CXXLD_0 = @echo "  CXXLD   " $@;
+am__v_CXXLD_1 = 
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+	$(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_ at AM_V@)
+am__v_CC_ = $(am__v_CC_ at AM_DEFAULT_V@)
+am__v_CC_0 = @echo "  CC      " $@;
+am__v_CC_1 = 
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+	$(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_ at AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_ at AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo "  CCLD    " $@;
+am__v_CCLD_1 = 
+DIST_SOURCES = $(libkernel_la_SOURCES) $(libkernelCommon_la_SOURCES) \
+	$(test_SOURCES)
+RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
+	ctags-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 \
+	tags-recursive uninstall-recursive
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+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__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
+am__installdirs = "$(DESTDIR)$(libkernel_la_includedir)"
+HEADERS = $(libkernel_la_include_HEADERS)
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive	\
+  distclean-recursive maintainer-clean-recursive
+am__recursive_targets = \
+  $(RECURSIVE_TARGETS) \
+  $(RECURSIVE_CLEAN_TARGETS) \
+  $(am__extra_recursive_targets)
+AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
+	check recheck distdir
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors_dummy = \
+  mgn= red= grn= lgn= blu= brg= std=; \
+  am__color_tests=no
+am__tty_colors = { \
+  $(am__tty_colors_dummy); \
+  if test "X$(AM_COLOR_TESTS)" = Xno; then \
+    am__color_tests=no; \
+  elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+    am__color_tests=yes; \
+  elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+    am__color_tests=yes; \
+  fi; \
+  if test $$am__color_tests = yes; then \
+    red=''; \
+    grn=''; \
+    lgn=''; \
+    blu=''; \
+    mgn=''; \
+    brg=''; \
+    std=''; \
+  fi; \
+}
+am__recheck_rx = ^[ 	]*:recheck:[ 	]*
+am__global_test_result_rx = ^[ 	]*:global-test-result:[ 	]*
+am__copy_in_global_log_rx = ^[ 	]*:copy-in-global-log:[ 	]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+  recheck = 1; \
+  while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+    { \
+      if (rc < 0) \
+        { \
+          if ((getline line2 < ($$0 ".log")) < 0) \
+	    recheck = 0; \
+          break; \
+        } \
+      else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+        { \
+          recheck = 0; \
+          break; \
+        } \
+      else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+        { \
+          break; \
+        } \
+    }; \
+  if (recheck) \
+    print $$0; \
+  close ($$0 ".trs"); \
+  close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+  print "fatal: making $@: " msg | "cat >&2"; \
+  exit 1; \
+} \
+function rst_section(header) \
+{ \
+  print header; \
+  len = length(header); \
+  for (i = 1; i <= len; i = i + 1) \
+    printf "="; \
+  printf "\n\n"; \
+} \
+{ \
+  copy_in_global_log = 1; \
+  global_test_result = "RUN"; \
+  while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+    { \
+      if (rc < 0) \
+         fatal("failed to read from " $$0 ".trs"); \
+      if (line ~ /$(am__global_test_result_rx)/) \
+        { \
+          sub("$(am__global_test_result_rx)", "", line); \
+          sub("[ 	]*$$", "", line); \
+          global_test_result = line; \
+        } \
+      else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+        copy_in_global_log = 0; \
+    }; \
+  if (copy_in_global_log) \
+    { \
+      rst_section(global_test_result ": " $$0); \
+      while ((rc = (getline line < ($$0 ".log"))) != 0) \
+      { \
+        if (rc < 0) \
+          fatal("failed to read from " $$0 ".log"); \
+        print line; \
+      }; \
+      printf "\n"; \
+    }; \
+  close ($$0 ".trs"); \
+  close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/   &   /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this.  Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+  --color-tests "$$am__color_tests" \
+  --enable-hard-errors "$$am__enable_hard_errors" \
+  --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test.  Creates the
+# directory for the log if needed.  Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log.  Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT.  Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup);					\
+$(am__vpath_adj_setup) $(am__vpath_adj)			\
+$(am__tty_colors);					\
+srcdir=$(srcdir); export srcdir;			\
+case "$@" in						\
+  */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;;	\
+    *) am__odir=.;; 					\
+esac;							\
+test "x$$am__odir" = x"." || test -d "$$am__odir" 	\
+  || $(MKDIR_P) "$$am__odir" || exit $$?;		\
+if test -f "./$$f"; then dir=./;			\
+elif test -f "$$f"; then dir=;				\
+else dir="$(srcdir)/"; fi;				\
+tst=$$dir$$f; log='$@'; 				\
+if test -n '$(DISABLE_HARD_ERRORS)'; then		\
+  am__enable_hard_errors=no; 				\
+else							\
+  am__enable_hard_errors=yes; 				\
+fi; 							\
+case " $(XFAIL_TESTS) " in				\
+  *[\ \	]$$f[\ \	]* | *[\ \	]$$dir$$f[\ \	]*) \
+    am__expect_failure=yes;;				\
+  *)							\
+    am__expect_failure=no;;				\
+esac; 							\
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed).  The result is saved in the shell variable
+# '$bases'.  This honors runtime overriding of TESTS and TEST_LOGS.  Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+  bases='$(TEST_LOGS)'; \
+  bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+  bases=`echo $$bases`
+RECHECK_LOGS = $(TEST_LOGS)
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+  case '$@' in \
+    */*) \
+      case '$*' in \
+        */*) b='$*';; \
+          *) b=`echo '$@' | sed 's/\.log$$//'`; \
+       esac;; \
+    *) \
+      b='$*';; \
+  esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT at .log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+	$(TEST_LOG_FLAGS)
+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@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BUILTIN_LIBS = @BUILTIN_LIBS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CDDGMPCPPFLAGS = @CDDGMPCPPFLAGS@
+CDDGMPLDFLAGS = @CDDGMPLDFLAGS@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATA_DIR = @DATA_DIR@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DOC_DIR = @DOC_DIR@
+DOXYGEN = @DOXYGEN@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FACTORY_INCLUDES = @FACTORY_INCLUDES@
+FACTORY_LIBS = @FACTORY_LIBS@
+FGREP = @FGREP@
+FLINT_CFLAGS = @FLINT_CFLAGS@
+FLINT_HOME = @FLINT_HOME@
+FLINT_LIBS = @FLINT_LIBS@
+GMP_CFLAGS = @GMP_CFLAGS@
+GMP_HOME = @GMP_HOME@
+GMP_LIBS = @GMP_LIBS@
+GMP_VERSION = @GMP_VERSION@
+GREP = @GREP@
+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@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NTL_CFLAGS = @NTL_CFLAGS@
+NTL_LIBS = @NTL_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OMALLOC_INCLUDES = @OMALLOC_INCLUDES@
+OMALLOC_LIBS = @OMALLOC_LIBS@
+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@
+PKG_REQUIRE = @PKG_REQUIRE@
+PMCONFIG = @PMCONFIG@
+PM_CFLAGS = @PM_CFLAGS@
+PM_INC = @PM_INC@
+PM_LDFLAGS = @PM_LDFLAGS@
+PM_LIBS = @PM_LIBS@
+POLYMAKE_CXXFLAGS = @POLYMAKE_CXXFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LDFLAGS = @PTHREAD_LDFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
+PYTHON = @PYTHON@
+PYTHON_CSPEC = @PYTHON_CSPEC@
+PYTHON_EXECPREFIX = @PYTHON_EXECPREFIX@
+PYTHON_LSPEC = @PYTHON_LSPEC@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+RANLIB = @RANLIB@
+RESOURCES_INCLUDES = @RESOURCES_INCLUDES@
+RESOURCES_LIBS = @RESOURCES_LIBS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SINGULAR_CFLAGS = @SINGULAR_CFLAGS@
+SI_COUNTEDREF_AUTOLOAD = @SI_COUNTEDREF_AUTOLOAD@
+SI_CPU_I386 = @SI_CPU_I386@
+SI_CPU_IA64 = @SI_CPU_IA64@
+SI_CPU_PPC = @SI_CPU_PPC@
+SI_CPU_SPARC = @SI_CPU_SPARC@
+SI_CPU_X86_64 = @SI_CPU_X86_64@
+STRIP = @STRIP@
+USEPPROCSDYNAMICLD = @USEPPROCSDYNAMICLD@
+USEPPROCSDYNAMICLDFLAGS = @USEPPROCSDYNAMICLDFLAGS@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
+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@
+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@
+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@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+ACLOCAL_AMFLAGS = -I ../m4
+noinst_LTLIBRARIES = libkernelCommon.la libkernel.la
+AM_CPPFLAGS = \
+-I${top_srcdir} -I${top_builddir} -I${top_srcdir}/libpolys -I${top_builddir}/libpolys \
+$(FACTORY_INCLUDES) $(NTL_CFLAGS) $(FLINT_CFLAGS) $(GMP_CFLAGS)
+
+SOURCES = polys.cc \
+    ideals.cc \
+    fast_mult.cc digitech.cc \
+    preimage.cc \
+    mod2.h
+
+libkernelCommon_la_SOURCES = $(SOURCES)
+libkernelCommon_la_LIBADD = ${USEPPROCSDYNAMICLDFLAGS} ${USEPPROCSDYNAMICLD} \
+${abs_top_builddir}/libpolys/polys/libpolys.la
+
+
+###### libkerneldir = $(libdir)/singular
+KERNELHEADERS = mod2.h structs.h polys.h ideals.h \
+	preimage.h fast_mult.h digitech.h
+
+libkernel_la_SOURCES = $(KERNELHEADERS)
+libkernel_la_includedir = ${includedir}/singular/kernel
+libkernel_la_include_HEADERS = $(KERNELHEADERS)
+SUBDIRS = numeric fglm groebner_walk combinatorics spectrum linear_algebra maps GBEngine oswrapper
+libkernel_la_LIBADD = \
+${builddir}/numeric/libnumeric.la \
+${builddir}/fglm/libfglm.la \
+${builddir}/groebner_walk/libgroebner_walk.la \
+${builddir}/combinatorics/libcombinatorics.la \
+${builddir}/spectrum/libspectrum.la \
+${builddir}/linear_algebra/liblinear_algebra.la \
+${builddir}/maps/libmaps.la \
+${builddir}/GBEngine/libGBEngine.la \
+${builddir}/oswrapper/liboswrapper.la \
+${builddir}/libkernelCommon.la
+
+
+### TODO: the following has to be addapted...
+TESTS_ENVIRONMENT = SINGULARPATH='${abs_top_builddir}/libpolys/polys/.libs:${abs_top_builddir}/factory/gftables' \
+	SINGULAR_ROOT_DIR='${abs_top_builddir}'
+test_SOURCES = test.cc
+test_LDADD = libkernel.la
+
+# These files are built first
+# BUILT_SOURCES = MOD
+
+# MOD: ${top_builddir}/libpolys/tests/MOD
+# 	ln -snf ${top_builddir}/libpolys/tests/MOD ${builddir}/MOD
+CLEANFILES = $(TESTS)
+all: all-recursive
+
+.SUFFIXES:
+.SUFFIXES: .cc .lo .log .o .obj .test .test$(EXEEXT) .trs
+$(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) --foreign kernel/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign kernel/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-noinstLTLIBRARIES:
+	-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+	@list='$(noinst_LTLIBRARIES)'; \
+	locs=`for p in $$list; do echo $$p; done | \
+	      sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+	      sort -u`; \
+	test -z "$$locs" || { \
+	  echo rm -f $${locs}; \
+	  rm -f $${locs}; \
+	}
+
+libkernel.la: $(libkernel_la_OBJECTS) $(libkernel_la_DEPENDENCIES) $(EXTRA_libkernel_la_DEPENDENCIES) 
+	$(AM_V_CCLD)$(LINK)  $(libkernel_la_OBJECTS) $(libkernel_la_LIBADD) $(LIBS)
+
+libkernelCommon.la: $(libkernelCommon_la_OBJECTS) $(libkernelCommon_la_DEPENDENCIES) $(EXTRA_libkernelCommon_la_DEPENDENCIES) 
+	$(AM_V_CXXLD)$(CXXLINK)  $(libkernelCommon_la_OBJECTS) $(libkernelCommon_la_LIBADD) $(LIBS)
+
+clean-checkPROGRAMS:
+	@list='$(check_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
+
+test$(EXEEXT): $(test_OBJECTS) $(test_DEPENDENCIES) $(EXTRA_test_DEPENDENCIES) 
+	@rm -f test$(EXEEXT)
+	$(AM_V_CXXLD)$(CXXLINK) $(test_OBJECTS) $(test_LDADD) $(LIBS)
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/digitech.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/fast_mult.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ideals.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/polys.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/preimage.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/test.Po at am__quote@
+
+.cc.o:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+ at am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXXCOMPILE) -c -o $@ $<
+
+.cc.obj:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+ at am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.cc.lo:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+ at am__fastdepCXX_TRUE@	$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LTCXXCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+install-libkernel_la_includeHEADERS: $(libkernel_la_include_HEADERS)
+	@$(NORMAL_INSTALL)
+	@list='$(libkernel_la_include_HEADERS)'; test -n "$(libkernel_la_includedir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(libkernel_la_includedir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(libkernel_la_includedir)" || exit 1; \
+	fi; \
+	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)$(libkernel_la_includedir)'"; \
+	  $(INSTALL_HEADER) $$files "$(DESTDIR)$(libkernel_la_includedir)" || exit $$?; \
+	done
+
+uninstall-libkernel_la_includeHEADERS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(libkernel_la_include_HEADERS)'; test -n "$(libkernel_la_includedir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	dir='$(DESTDIR)$(libkernel_la_includedir)'; $(am__uninstall_files_from_dir)
+
+# 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.
+$(am__recursive_targets):
+	@fail=; \
+	if $(am__make_keepgoing); then \
+	  failcom='fail=yes'; \
+	else \
+	  failcom='exit 1'; \
+	fi; \
+	dot_seen=no; \
+	target=`echo $@ | sed s/-recursive//`; \
+	case "$@" in \
+	  distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+	  *) list='$(SUBDIRS)' ;; \
+	esac; \
+	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"
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-recursive
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	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; \
+	$(am__define_uniq_tagged_files); \
+	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-recursive
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	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"
+cscopelist: cscopelist-recursive
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'.  Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+	rm -f $< $@
+	$(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+	@:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+	@$(am__set_TESTS_bases); \
+	am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+	redo_bases=`for i in $$bases; do \
+	              am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+	            done`; \
+	if test -n "$$redo_bases"; then \
+	  redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+	  redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+	  if $(am__make_dryrun); then :; else \
+	    rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+	  fi; \
+	fi; \
+	if test -n "$$am__remaking_logs"; then \
+	  echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+	       "recursion detected" >&2; \
+	else \
+	  am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+	fi; \
+	if $(am__make_dryrun); then :; else \
+	  st=0;  \
+	  errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+	  for i in $$redo_bases; do \
+	    test -f $$i.trs && test -r $$i.trs \
+	      || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+	    test -f $$i.log && test -r $$i.log \
+	      || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+	  done; \
+	  test $$st -eq 0 || exit 1; \
+	fi
+	@$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+	ws='[ 	]'; \
+	results=`for b in $$bases; do echo $$b.trs; done`; \
+	test -n "$$results" || results=/dev/null; \
+	all=`  grep "^$$ws*:test-result:"           $$results | wc -l`; \
+	pass=` grep "^$$ws*:test-result:$$ws*PASS"  $$results | wc -l`; \
+	fail=` grep "^$$ws*:test-result:$$ws*FAIL"  $$results | wc -l`; \
+	skip=` grep "^$$ws*:test-result:$$ws*SKIP"  $$results | wc -l`; \
+	xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+	xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+	error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+	if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+	  success=true; \
+	else \
+	  success=false; \
+	fi; \
+	br='==================='; br=$$br$$br$$br$$br; \
+	result_count () \
+	{ \
+	    if test x"$$1" = x"--maybe-color"; then \
+	      maybe_colorize=yes; \
+	    elif test x"$$1" = x"--no-color"; then \
+	      maybe_colorize=no; \
+	    else \
+	      echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+	    fi; \
+	    shift; \
+	    desc=$$1 count=$$2; \
+	    if test $$maybe_colorize = yes && test $$count -gt 0; then \
+	      color_start=$$3 color_end=$$std; \
+	    else \
+	      color_start= color_end=; \
+	    fi; \
+	    echo "$${color_start}# $$desc $$count$${color_end}"; \
+	}; \
+	create_testsuite_report () \
+	{ \
+	  result_count $$1 "TOTAL:" $$all   "$$brg"; \
+	  result_count $$1 "PASS: " $$pass  "$$grn"; \
+	  result_count $$1 "SKIP: " $$skip  "$$blu"; \
+	  result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+	  result_count $$1 "FAIL: " $$fail  "$$red"; \
+	  result_count $$1 "XPASS:" $$xpass "$$red"; \
+	  result_count $$1 "ERROR:" $$error "$$mgn"; \
+	}; \
+	{								\
+	  echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" |	\
+	    $(am__rst_title);						\
+	  create_testsuite_report --no-color;				\
+	  echo;								\
+	  echo ".. contents:: :depth: 2";				\
+	  echo;								\
+	  for b in $$bases; do echo $$b; done				\
+	    | $(am__create_global_log);					\
+	} >$(TEST_SUITE_LOG).tmp || exit 1;				\
+	mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG);			\
+	if $$success; then						\
+	  col="$$grn";							\
+	 else								\
+	  col="$$red";							\
+	  test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG);		\
+	fi;								\
+	echo "$${col}$$br$${std}"; 					\
+	echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}";	\
+	echo "$${col}$$br$${std}"; 					\
+	create_testsuite_report --maybe-color;				\
+	echo "$$col$$br$$std";						\
+	if $$success; then :; else					\
+	  echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}";		\
+	  if test -n "$(PACKAGE_BUGREPORT)"; then			\
+	    echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}";	\
+	  fi;								\
+	  echo "$$col$$br$$std";					\
+	fi;								\
+	$$success || exit 1
+
+check-TESTS:
+	@list='$(RECHECK_LOGS)';           test -z "$$list" || rm -f $$list
+	@list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+	@test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+	@set +e; $(am__set_TESTS_bases); \
+	log_list=`for i in $$bases; do echo $$i.log; done`; \
+	trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+	log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+	$(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+	exit $$?;
+recheck: all $(check_PROGRAMS)
+	@test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+	@set +e; $(am__set_TESTS_bases); \
+	bases=`for i in $$bases; do echo $$i; done \
+	         | $(am__list_recheck_tests)` || exit 1; \
+	log_list=`for i in $$bases; do echo $$i.log; done`; \
+	log_list=`echo $$log_list`; \
+	$(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+	        am__force_recheck=am--force-recheck \
+	        TEST_LOGS="$$log_list"; \
+	exit $$?
+test.log: test$(EXEEXT)
+	@p='test$(EXEEXT)'; \
+	b='test'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+.test.log:
+	@p='$<'; \
+	$(am__set_b); \
+	$(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+ at am__EXEEXT_TRUE@.test$(EXEEXT).log:
+ at am__EXEEXT_TRUE@	@p='$<'; \
+ at am__EXEEXT_TRUE@	$(am__set_b); \
+ at am__EXEEXT_TRUE@	$(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ at am__EXEEXT_TRUE@	--log-file $$b.log --trs-file $$b.trs \
+ at am__EXEEXT_TRUE@	$(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ at am__EXEEXT_TRUE@	"$$tst" $(AM_TESTS_FD_REDIRECT)
+
+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 \
+	    $(am__make_dryrun) \
+	      || test -d "$(distdir)/$$subdir" \
+	      || $(MKDIR_P) "$(distdir)/$$subdir" \
+	      || exit 1; \
+	    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
+	$(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS)
+	$(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-recursive
+all-am: Makefile $(LTLIBRARIES) $(HEADERS)
+installdirs: installdirs-recursive
+installdirs-am:
+	for dir in "$(DESTDIR)$(libkernel_la_includedir)"; do \
+	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+	done
+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:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+	-test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+	-test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+	-test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+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-recursive
+
+clean-am: clean-checkPROGRAMS clean-generic clean-libtool \
+	clean-noinstLTLIBRARIES 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-libkernel_la_includeHEADERS
+
+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 -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-libkernel_la_includeHEADERS
+
+.MAKE: $(am__recursive_targets) check-am install-am install-strip
+
+.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \
+	check-TESTS check-am clean clean-checkPROGRAMS clean-generic \
+	clean-libtool clean-noinstLTLIBRARIES cscopelist-am ctags \
+	ctags-am 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-libkernel_la_includeHEADERS \
+	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-compile \
+	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+	recheck tags tags-am uninstall uninstall-am \
+	uninstall-libkernel_la_includeHEADERS
+
+# $(BUILT_SOURCES)
+
+# 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/kernel/README b/kernel/README
new file mode 100644
index 0000000..4af070d
--- /dev/null
+++ b/kernel/README
@@ -0,0 +1,16 @@
+This directory contains the source files for the Singular kernel.
+(i.e. all algorithms which still require currRing
+and needs to rewritten)
+
+Subdirectories:
+- combinatorics: hilbert function and related
+- fglm: FGLM algorithm
+- GBEngine: Buchbergers/Moras algorithm and related
+- groebner_walk: Groebner walk
+- linear_algebra: minor, LU decomposition
+- maps: polynomial maps between commutative polynomial rings
+- numeric: find zeroes of (univariate) polynomials
+- spectrum: spectrum of isolated curve singularities and related
+- oswrapper: terminal input, os limits, timer
+
+
diff --git a/kernel/combinatorics/Makefile.am b/kernel/combinatorics/Makefile.am
new file mode 100644
index 0000000..63a52ec
--- /dev/null
+++ b/kernel/combinatorics/Makefile.am
@@ -0,0 +1,22 @@
+ACLOCAL_AMFLAGS=-I ../../m4
+AM_CPPFLAGS=-I${top_srcdir} -I${top_builddir} -I${top_srcdir}/libpolys -I${top_builddir}/libpolys \
+${FACTORY_INCLUDES} $(OMALLOC_INCLUDES) $(RESOURCES_INCLUDES) \
+${NTL_CFLAGS} $(FLINT_CFLAGS) ${GMP_CFLAGS}
+
+noinst_LTLIBRARIES=libcombinatorics.la
+libcombinatorics_la_SOURCES=hdegree.cc hilb.cc hutil.cc
+
+libcombinatorics_la_includedir=$(includedir)/singular/kernel/combinatorics
+libcombinatorics_la_include_HEADERS=hutil.h stairc.h hilb.h
+
+
+
+TESTS_ENVIRONMENT = SINGULARPATH='${abs_top_builddir}/libpolys/polys/.libs:${abs_top_builddir}/factory/gftables'
+TESTS_ENVIRONMENT += SINGULAR_ROOT_DIR='${abs_top_builddir}'
+
+TESTS = test
+check_PROGRAMS = $(TESTS)
+test_SOURCES = test.cc
+test_LDADD   = libcombinatorics.la ${builddir}/../libkernelCommon.la
+
+CLEANFILES = $(TESTS)
diff --git a/kernel/combinatorics/Makefile.in b/kernel/combinatorics/Makefile.in
new file mode 100644
index 0000000..0c74de0
--- /dev/null
+++ b/kernel/combinatorics/Makefile.in
@@ -0,0 +1,1085 @@
+# Makefile.in generated by automake 1.13.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 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@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+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@
+TESTS = test$(EXEEXT)
+check_PROGRAMS = $(am__EXEEXT_1)
+subdir = kernel/combinatorics
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/build-aux/depcomp \
+	$(libcombinatorics_la_include_HEADERS) \
+	$(top_srcdir)/build-aux/test-driver
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_append_compile_flags.m4 \
+	$(top_srcdir)/m4/ax_append_flag.m4 \
+	$(top_srcdir)/m4/ax_append_link_flags.m4 \
+	$(top_srcdir)/m4/ax_check_compile_flag.m4 \
+	$(top_srcdir)/m4/ax_check_link_flag.m4 \
+	$(top_srcdir)/m4/ax_compute_relative_paths.m4 \
+	$(top_srcdir)/m4/ax_normalize_path.m4 \
+	$(top_srcdir)/m4/ax_prefix_config_h.m4 \
+	$(top_srcdir)/m4/ax_pthread.m4 \
+	$(top_srcdir)/m4/ax_python_embed.m4 \
+	$(top_srcdir)/m4/ax_python_with_version.m4 \
+	$(top_srcdir)/m4/cpu-check.m4 $(top_srcdir)/m4/dbm-check.m4 \
+	$(top_srcdir)/m4/flags.m4 $(top_srcdir)/m4/flint-check.m4 \
+	$(top_srcdir)/m4/gfanlib-check.m4 \
+	$(top_srcdir)/m4/gmp-check.m4 \
+	$(top_srcdir)/m4/google-perftools.m4 \
+	$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+	$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+	$(top_srcdir)/m4/lt~obsolete.m4 \
+	$(top_srcdir)/m4/mathic-check.m4 $(top_srcdir)/m4/ntl-check.m4 \
+	$(top_srcdir)/m4/options.m4 $(top_srcdir)/m4/p-procs.m4 \
+	$(top_srcdir)/m4/polymake-check.m4 \
+	$(top_srcdir)/m4/readline-check.m4 $(top_srcdir)/configure.ac
+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 =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+libcombinatorics_la_LIBADD =
+am_libcombinatorics_la_OBJECTS = hdegree.lo hilb.lo hutil.lo
+libcombinatorics_la_OBJECTS = $(am_libcombinatorics_la_OBJECTS)
+AM_V_lt = $(am__v_lt_ at AM_V@)
+am__v_lt_ = $(am__v_lt_ at AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 = 
+am__EXEEXT_1 = test$(EXEEXT)
+am_test_OBJECTS = test.$(OBJEXT)
+test_OBJECTS = $(am_test_OBJECTS)
+test_DEPENDENCIES = libcombinatorics.la \
+	${builddir}/../libkernelCommon.la
+AM_V_P = $(am__v_P_ at AM_V@)
+am__v_P_ = $(am__v_P_ at AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_ at AM_V@)
+am__v_GEN_ = $(am__v_GEN_ at AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_ at AM_V@)
+am__v_at_ = $(am__v_at_ at AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+DEFAULT_INCLUDES = -I. at am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \
+	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+	$(AM_CXXFLAGS) $(CXXFLAGS)
+AM_V_CXX = $(am__v_CXX_ at AM_V@)
+am__v_CXX_ = $(am__v_CXX_ at AM_DEFAULT_V@)
+am__v_CXX_0 = @echo "  CXX     " $@;
+am__v_CXX_1 = 
+CXXLD = $(CXX)
+CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+	$(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CXXLD = $(am__v_CXXLD_ at AM_V@)
+am__v_CXXLD_ = $(am__v_CXXLD_ at AM_DEFAULT_V@)
+am__v_CXXLD_0 = @echo "  CXXLD   " $@;
+am__v_CXXLD_1 = 
+SOURCES = $(libcombinatorics_la_SOURCES) $(test_SOURCES)
+DIST_SOURCES = $(libcombinatorics_la_SOURCES) $(test_SOURCES)
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+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__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
+am__installdirs = "$(DESTDIR)$(libcombinatorics_la_includedir)"
+HEADERS = $(libcombinatorics_la_include_HEADERS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors_dummy = \
+  mgn= red= grn= lgn= blu= brg= std=; \
+  am__color_tests=no
+am__tty_colors = { \
+  $(am__tty_colors_dummy); \
+  if test "X$(AM_COLOR_TESTS)" = Xno; then \
+    am__color_tests=no; \
+  elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+    am__color_tests=yes; \
+  elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+    am__color_tests=yes; \
+  fi; \
+  if test $$am__color_tests = yes; then \
+    red=''; \
+    grn=''; \
+    lgn=''; \
+    blu=''; \
+    mgn=''; \
+    brg=''; \
+    std=''; \
+  fi; \
+}
+am__recheck_rx = ^[ 	]*:recheck:[ 	]*
+am__global_test_result_rx = ^[ 	]*:global-test-result:[ 	]*
+am__copy_in_global_log_rx = ^[ 	]*:copy-in-global-log:[ 	]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+  recheck = 1; \
+  while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+    { \
+      if (rc < 0) \
+        { \
+          if ((getline line2 < ($$0 ".log")) < 0) \
+	    recheck = 0; \
+          break; \
+        } \
+      else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+        { \
+          recheck = 0; \
+          break; \
+        } \
+      else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+        { \
+          break; \
+        } \
+    }; \
+  if (recheck) \
+    print $$0; \
+  close ($$0 ".trs"); \
+  close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+  print "fatal: making $@: " msg | "cat >&2"; \
+  exit 1; \
+} \
+function rst_section(header) \
+{ \
+  print header; \
+  len = length(header); \
+  for (i = 1; i <= len; i = i + 1) \
+    printf "="; \
+  printf "\n\n"; \
+} \
+{ \
+  copy_in_global_log = 1; \
+  global_test_result = "RUN"; \
+  while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+    { \
+      if (rc < 0) \
+         fatal("failed to read from " $$0 ".trs"); \
+      if (line ~ /$(am__global_test_result_rx)/) \
+        { \
+          sub("$(am__global_test_result_rx)", "", line); \
+          sub("[ 	]*$$", "", line); \
+          global_test_result = line; \
+        } \
+      else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+        copy_in_global_log = 0; \
+    }; \
+  if (copy_in_global_log) \
+    { \
+      rst_section(global_test_result ": " $$0); \
+      while ((rc = (getline line < ($$0 ".log"))) != 0) \
+      { \
+        if (rc < 0) \
+          fatal("failed to read from " $$0 ".log"); \
+        print line; \
+      }; \
+      printf "\n"; \
+    }; \
+  close ($$0 ".trs"); \
+  close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/   &   /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this.  Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+  --color-tests "$$am__color_tests" \
+  --enable-hard-errors "$$am__enable_hard_errors" \
+  --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test.  Creates the
+# directory for the log if needed.  Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log.  Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT.  Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup);					\
+$(am__vpath_adj_setup) $(am__vpath_adj)			\
+$(am__tty_colors);					\
+srcdir=$(srcdir); export srcdir;			\
+case "$@" in						\
+  */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;;	\
+    *) am__odir=.;; 					\
+esac;							\
+test "x$$am__odir" = x"." || test -d "$$am__odir" 	\
+  || $(MKDIR_P) "$$am__odir" || exit $$?;		\
+if test -f "./$$f"; then dir=./;			\
+elif test -f "$$f"; then dir=;				\
+else dir="$(srcdir)/"; fi;				\
+tst=$$dir$$f; log='$@'; 				\
+if test -n '$(DISABLE_HARD_ERRORS)'; then		\
+  am__enable_hard_errors=no; 				\
+else							\
+  am__enable_hard_errors=yes; 				\
+fi; 							\
+case " $(XFAIL_TESTS) " in				\
+  *[\ \	]$$f[\ \	]* | *[\ \	]$$dir$$f[\ \	]*) \
+    am__expect_failure=yes;;				\
+  *)							\
+    am__expect_failure=no;;				\
+esac; 							\
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed).  The result is saved in the shell variable
+# '$bases'.  This honors runtime overriding of TESTS and TEST_LOGS.  Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+  bases='$(TEST_LOGS)'; \
+  bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+  bases=`echo $$bases`
+RECHECK_LOGS = $(TEST_LOGS)
+AM_RECURSIVE_TARGETS = check recheck
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+  case '$@' in \
+    */*) \
+      case '$*' in \
+        */*) b='$*';; \
+          *) b=`echo '$@' | sed 's/\.log$$//'`; \
+       esac;; \
+    *) \
+      b='$*';; \
+  esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT at .log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+	$(TEST_LOG_FLAGS)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BUILTIN_LIBS = @BUILTIN_LIBS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CDDGMPCPPFLAGS = @CDDGMPCPPFLAGS@
+CDDGMPLDFLAGS = @CDDGMPLDFLAGS@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATA_DIR = @DATA_DIR@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DOC_DIR = @DOC_DIR@
+DOXYGEN = @DOXYGEN@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FACTORY_INCLUDES = @FACTORY_INCLUDES@
+FACTORY_LIBS = @FACTORY_LIBS@
+FGREP = @FGREP@
+FLINT_CFLAGS = @FLINT_CFLAGS@
+FLINT_HOME = @FLINT_HOME@
+FLINT_LIBS = @FLINT_LIBS@
+GMP_CFLAGS = @GMP_CFLAGS@
+GMP_HOME = @GMP_HOME@
+GMP_LIBS = @GMP_LIBS@
+GMP_VERSION = @GMP_VERSION@
+GREP = @GREP@
+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@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NTL_CFLAGS = @NTL_CFLAGS@
+NTL_LIBS = @NTL_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OMALLOC_INCLUDES = @OMALLOC_INCLUDES@
+OMALLOC_LIBS = @OMALLOC_LIBS@
+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@
+PKG_REQUIRE = @PKG_REQUIRE@
+PMCONFIG = @PMCONFIG@
+PM_CFLAGS = @PM_CFLAGS@
+PM_INC = @PM_INC@
+PM_LDFLAGS = @PM_LDFLAGS@
+PM_LIBS = @PM_LIBS@
+POLYMAKE_CXXFLAGS = @POLYMAKE_CXXFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LDFLAGS = @PTHREAD_LDFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
+PYTHON = @PYTHON@
+PYTHON_CSPEC = @PYTHON_CSPEC@
+PYTHON_EXECPREFIX = @PYTHON_EXECPREFIX@
+PYTHON_LSPEC = @PYTHON_LSPEC@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+RANLIB = @RANLIB@
+RESOURCES_INCLUDES = @RESOURCES_INCLUDES@
+RESOURCES_LIBS = @RESOURCES_LIBS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SINGULAR_CFLAGS = @SINGULAR_CFLAGS@
+SI_COUNTEDREF_AUTOLOAD = @SI_COUNTEDREF_AUTOLOAD@
+SI_CPU_I386 = @SI_CPU_I386@
+SI_CPU_IA64 = @SI_CPU_IA64@
+SI_CPU_PPC = @SI_CPU_PPC@
+SI_CPU_SPARC = @SI_CPU_SPARC@
+SI_CPU_X86_64 = @SI_CPU_X86_64@
+STRIP = @STRIP@
+USEPPROCSDYNAMICLD = @USEPPROCSDYNAMICLD@
+USEPPROCSDYNAMICLDFLAGS = @USEPPROCSDYNAMICLDFLAGS@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
+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@
+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@
+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@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+ACLOCAL_AMFLAGS = -I ../../m4
+AM_CPPFLAGS = -I${top_srcdir} -I${top_builddir} -I${top_srcdir}/libpolys -I${top_builddir}/libpolys \
+${FACTORY_INCLUDES} $(OMALLOC_INCLUDES) $(RESOURCES_INCLUDES) \
+${NTL_CFLAGS} $(FLINT_CFLAGS) ${GMP_CFLAGS}
+
+noinst_LTLIBRARIES = libcombinatorics.la
+libcombinatorics_la_SOURCES = hdegree.cc hilb.cc hutil.cc
+libcombinatorics_la_includedir = $(includedir)/singular/kernel/combinatorics
+libcombinatorics_la_include_HEADERS = hutil.h stairc.h hilb.h
+TESTS_ENVIRONMENT = SINGULARPATH='${abs_top_builddir}/libpolys/polys/.libs:${abs_top_builddir}/factory/gftables' \
+	SINGULAR_ROOT_DIR='${abs_top_builddir}'
+test_SOURCES = test.cc
+test_LDADD = libcombinatorics.la ${builddir}/../libkernelCommon.la
+CLEANFILES = $(TESTS)
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .cc .lo .log .o .obj .test .test$(EXEEXT) .trs
+$(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) --foreign kernel/combinatorics/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign kernel/combinatorics/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-noinstLTLIBRARIES:
+	-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+	@list='$(noinst_LTLIBRARIES)'; \
+	locs=`for p in $$list; do echo $$p; done | \
+	      sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+	      sort -u`; \
+	test -z "$$locs" || { \
+	  echo rm -f $${locs}; \
+	  rm -f $${locs}; \
+	}
+
+libcombinatorics.la: $(libcombinatorics_la_OBJECTS) $(libcombinatorics_la_DEPENDENCIES) $(EXTRA_libcombinatorics_la_DEPENDENCIES) 
+	$(AM_V_CXXLD)$(CXXLINK)  $(libcombinatorics_la_OBJECTS) $(libcombinatorics_la_LIBADD) $(LIBS)
+
+clean-checkPROGRAMS:
+	@list='$(check_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
+
+test$(EXEEXT): $(test_OBJECTS) $(test_DEPENDENCIES) $(EXTRA_test_DEPENDENCIES) 
+	@rm -f test$(EXEEXT)
+	$(AM_V_CXXLD)$(CXXLINK) $(test_OBJECTS) $(test_LDADD) $(LIBS)
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/hdegree.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/hilb.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/hutil.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/test.Po at am__quote@
+
+.cc.o:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+ at am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXXCOMPILE) -c -o $@ $<
+
+.cc.obj:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+ at am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.cc.lo:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+ at am__fastdepCXX_TRUE@	$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LTCXXCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+install-libcombinatorics_la_includeHEADERS: $(libcombinatorics_la_include_HEADERS)
+	@$(NORMAL_INSTALL)
+	@list='$(libcombinatorics_la_include_HEADERS)'; test -n "$(libcombinatorics_la_includedir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(libcombinatorics_la_includedir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(libcombinatorics_la_includedir)" || exit 1; \
+	fi; \
+	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)$(libcombinatorics_la_includedir)'"; \
+	  $(INSTALL_HEADER) $$files "$(DESTDIR)$(libcombinatorics_la_includedir)" || exit $$?; \
+	done
+
+uninstall-libcombinatorics_la_includeHEADERS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(libcombinatorics_la_include_HEADERS)'; test -n "$(libcombinatorics_la_includedir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	dir='$(DESTDIR)$(libcombinatorics_la_includedir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	$(am__define_uniq_tagged_files); \
+	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-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	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"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'.  Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+	rm -f $< $@
+	$(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+	@:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+	@$(am__set_TESTS_bases); \
+	am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+	redo_bases=`for i in $$bases; do \
+	              am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+	            done`; \
+	if test -n "$$redo_bases"; then \
+	  redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+	  redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+	  if $(am__make_dryrun); then :; else \
+	    rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+	  fi; \
+	fi; \
+	if test -n "$$am__remaking_logs"; then \
+	  echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+	       "recursion detected" >&2; \
+	else \
+	  am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+	fi; \
+	if $(am__make_dryrun); then :; else \
+	  st=0;  \
+	  errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+	  for i in $$redo_bases; do \
+	    test -f $$i.trs && test -r $$i.trs \
+	      || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+	    test -f $$i.log && test -r $$i.log \
+	      || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+	  done; \
+	  test $$st -eq 0 || exit 1; \
+	fi
+	@$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+	ws='[ 	]'; \
+	results=`for b in $$bases; do echo $$b.trs; done`; \
+	test -n "$$results" || results=/dev/null; \
+	all=`  grep "^$$ws*:test-result:"           $$results | wc -l`; \
+	pass=` grep "^$$ws*:test-result:$$ws*PASS"  $$results | wc -l`; \
+	fail=` grep "^$$ws*:test-result:$$ws*FAIL"  $$results | wc -l`; \
+	skip=` grep "^$$ws*:test-result:$$ws*SKIP"  $$results | wc -l`; \
+	xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+	xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+	error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+	if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+	  success=true; \
+	else \
+	  success=false; \
+	fi; \
+	br='==================='; br=$$br$$br$$br$$br; \
+	result_count () \
+	{ \
+	    if test x"$$1" = x"--maybe-color"; then \
+	      maybe_colorize=yes; \
+	    elif test x"$$1" = x"--no-color"; then \
+	      maybe_colorize=no; \
+	    else \
+	      echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+	    fi; \
+	    shift; \
+	    desc=$$1 count=$$2; \
+	    if test $$maybe_colorize = yes && test $$count -gt 0; then \
+	      color_start=$$3 color_end=$$std; \
+	    else \
+	      color_start= color_end=; \
+	    fi; \
+	    echo "$${color_start}# $$desc $$count$${color_end}"; \
+	}; \
+	create_testsuite_report () \
+	{ \
+	  result_count $$1 "TOTAL:" $$all   "$$brg"; \
+	  result_count $$1 "PASS: " $$pass  "$$grn"; \
+	  result_count $$1 "SKIP: " $$skip  "$$blu"; \
+	  result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+	  result_count $$1 "FAIL: " $$fail  "$$red"; \
+	  result_count $$1 "XPASS:" $$xpass "$$red"; \
+	  result_count $$1 "ERROR:" $$error "$$mgn"; \
+	}; \
+	{								\
+	  echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" |	\
+	    $(am__rst_title);						\
+	  create_testsuite_report --no-color;				\
+	  echo;								\
+	  echo ".. contents:: :depth: 2";				\
+	  echo;								\
+	  for b in $$bases; do echo $$b; done				\
+	    | $(am__create_global_log);					\
+	} >$(TEST_SUITE_LOG).tmp || exit 1;				\
+	mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG);			\
+	if $$success; then						\
+	  col="$$grn";							\
+	 else								\
+	  col="$$red";							\
+	  test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG);		\
+	fi;								\
+	echo "$${col}$$br$${std}"; 					\
+	echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}";	\
+	echo "$${col}$$br$${std}"; 					\
+	create_testsuite_report --maybe-color;				\
+	echo "$$col$$br$$std";						\
+	if $$success; then :; else					\
+	  echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}";		\
+	  if test -n "$(PACKAGE_BUGREPORT)"; then			\
+	    echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}";	\
+	  fi;								\
+	  echo "$$col$$br$$std";					\
+	fi;								\
+	$$success || exit 1
+
+check-TESTS:
+	@list='$(RECHECK_LOGS)';           test -z "$$list" || rm -f $$list
+	@list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+	@test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+	@set +e; $(am__set_TESTS_bases); \
+	log_list=`for i in $$bases; do echo $$i.log; done`; \
+	trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+	log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+	$(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+	exit $$?;
+recheck: all $(check_PROGRAMS)
+	@test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+	@set +e; $(am__set_TESTS_bases); \
+	bases=`for i in $$bases; do echo $$i; done \
+	         | $(am__list_recheck_tests)` || exit 1; \
+	log_list=`for i in $$bases; do echo $$i.log; done`; \
+	log_list=`echo $$log_list`; \
+	$(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+	        am__force_recheck=am--force-recheck \
+	        TEST_LOGS="$$log_list"; \
+	exit $$?
+test.log: test$(EXEEXT)
+	@p='test$(EXEEXT)'; \
+	b='test'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+.test.log:
+	@p='$<'; \
+	$(am__set_b); \
+	$(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+ at am__EXEEXT_TRUE@.test$(EXEEXT).log:
+ at am__EXEEXT_TRUE@	@p='$<'; \
+ at am__EXEEXT_TRUE@	$(am__set_b); \
+ at am__EXEEXT_TRUE@	$(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ at am__EXEEXT_TRUE@	--log-file $$b.log --trs-file $$b.trs \
+ at am__EXEEXT_TRUE@	$(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ at am__EXEEXT_TRUE@	"$$tst" $(AM_TESTS_FD_REDIRECT)
+
+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_PROGRAMS)
+	$(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(HEADERS)
+installdirs:
+	for dir in "$(DESTDIR)$(libcombinatorics_la_includedir)"; 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:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+	-test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+	-test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+	-test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+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-checkPROGRAMS clean-generic clean-libtool \
+	clean-noinstLTLIBRARIES 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-libcombinatorics_la_includeHEADERS
+
+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: uninstall-libcombinatorics_la_includeHEADERS
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am clean \
+	clean-checkPROGRAMS clean-generic clean-libtool \
+	clean-noinstLTLIBRARIES cscopelist-am ctags ctags-am 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-libcombinatorics_la_includeHEADERS 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 recheck tags tags-am uninstall \
+	uninstall-am uninstall-libcombinatorics_la_includeHEADERS
+
+
+# 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/kernel/combinatorics/hdegree.cc b/kernel/combinatorics/hdegree.cc
new file mode 100644
index 0000000..06cb77b
--- /dev/null
+++ b/kernel/combinatorics/hdegree.cc
@@ -0,0 +1,1482 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+*  ABSTRACT -  dimension, multiplicity, HC, kbase
+*/
+
+#include <kernel/mod2.h>
+
+#include <omalloc/omalloc.h>
+#include <misc/intvec.h>
+#include <coeffs/numbers.h>
+
+#include <kernel/structs.h>
+#include <kernel/ideals.h>
+#include <kernel/polys.h>
+
+#include <kernel/combinatorics/hutil.h>
+#include <kernel/combinatorics/hilb.h>
+#include <kernel/combinatorics/stairc.h>
+
+int  hCo, hMu, hMu2;
+omBin indlist_bin = omGetSpecBin(sizeof(indlist));
+
+/*0 implementation*/
+
+// dimension
+
+void hDimSolve(scmon pure, int Npure, scfmon rad, int Nrad,
+ varset var, int Nvar)
+{
+  int  dn, iv, rad0, b, c, x;
+  scmon pn;
+  scfmon rn;
+  if (Nrad < 2)
+  {
+    dn = Npure + Nrad;
+    if (dn < hCo)
+      hCo = dn;
+    return;
+  }
+  if (Npure+1 >= hCo)
+    return;
+  iv = Nvar;
+  while(pure[var[iv]]) iv--;
+  hStepR(rad, Nrad, var, iv, &rad0);
+  if (rad0!=0)
+  {
+    iv--;
+    if (rad0 < Nrad)
+    {
+      pn = hGetpure(pure);
+      rn = hGetmem(Nrad, rad, radmem[iv]);
+      hDimSolve(pn, Npure + 1, rn, rad0, var, iv);
+      b = rad0;
+      c = Nrad;
+      hElimR(rn, &rad0, b, c, var, iv);
+      hPure(rn, b, &c, var, iv, pn, &x);
+      hLex2R(rn, rad0, b, c, var, iv, hwork);
+      rad0 += (c - b);
+      hDimSolve(pn, Npure + x, rn, rad0, var, iv);
+    }
+    else
+    {
+      hDimSolve(pure, Npure, rad, Nrad, var, iv);
+    }
+  }
+  else
+    hCo = Npure + 1;
+}
+
+int  scDimInt(ideal S, ideal Q)
+{
+  id_Test(S, currRing);
+  id_Test(Q, currRing);
+  int  mc;
+  hexist = hInit(S, Q, &hNexist, currRing);
+  if (!hNexist)
+    return (currRing->N);
+  hwork = (scfmon)omAlloc(hNexist * sizeof(scmon));
+  hvar = (varset)omAlloc(((currRing->N) + 1) * sizeof(int));
+  hpure = (scmon)omAlloc((1 + ((currRing->N) * (currRing->N))) * sizeof(int));
+  mc = hisModule;
+  if (!mc)
+  {
+    hrad = hexist;
+    hNrad = hNexist;
+  }
+  else
+    hrad = (scfmon)omAlloc(hNexist * sizeof(scmon));
+  radmem = hCreate((currRing->N) - 1);
+  hCo = (currRing->N) + 1;
+  loop
+  {
+    if (mc)
+      hComp(hexist, hNexist, mc, hrad, &hNrad);
+    if (hNrad)
+    {
+      hNvar = (currRing->N);
+      hRadical(hrad, &hNrad, hNvar);
+      hSupp(hrad, hNrad, hvar, &hNvar);
+      if (hNvar)
+      {
+        memset(hpure, 0, ((currRing->N) + 1) * sizeof(int));
+        hPure(hrad, 0, &hNrad, hvar, hNvar, hpure, &hNpure);
+        hLexR(hrad, hNrad, hvar, hNvar);
+        hDimSolve(hpure, hNpure, hrad, hNrad, hvar, hNvar);
+      }
+    }
+    else
+    {
+      hCo = 0;
+      break;
+    }
+    mc--;
+    if (mc <= 0)
+      break;
+  }
+  hKill(radmem, (currRing->N) - 1);
+  omFreeSize((ADDRESS)hpure, (1 + ((currRing->N) * (currRing->N))) * sizeof(int));
+  omFreeSize((ADDRESS)hvar, ((currRing->N) + 1) * sizeof(int));
+  omFreeSize((ADDRESS)hwork, hNexist * sizeof(scmon));
+  hDelete(hexist, hNexist);
+  if (hisModule)
+    omFreeSize((ADDRESS)hrad, hNexist * sizeof(scmon));
+  return (currRing->N) - hCo;
+}
+
+// independent set
+static scmon hInd;
+
+static void hIndSolve(scmon pure, int Npure, scfmon rad, int Nrad,
+ varset var, int Nvar)
+{
+  int  dn, iv, rad0, b, c, x;
+  scmon pn;
+  scfmon rn;
+  if (Nrad < 2)
+  {
+    dn = Npure + Nrad;
+    if (dn < hCo)
+    {
+      hCo = dn;
+      for (iv=(currRing->N); iv; iv--)
+      {
+        if (pure[iv])
+          hInd[iv] = 0;
+        else
+          hInd[iv] = 1;
+      }
+      if (Nrad)
+      {
+        pn = *rad;
+        iv = Nvar;
+        loop
+        {
+          x = var[iv];
+          if (pn[x])
+          {
+            hInd[x] = 0;
+            break;
+          }
+          iv--;
+        }
+      }
+    }
+    return;
+  }
+  if (Npure+1 >= hCo)
+    return;
+  iv = Nvar;
+  while(pure[var[iv]]) iv--;
+  hStepR(rad, Nrad, var, iv, &rad0);
+  if (rad0)
+  {
+    iv--;
+    if (rad0 < Nrad)
+    {
+      pn = hGetpure(pure);
+      rn = hGetmem(Nrad, rad, radmem[iv]);
+      pn[var[iv + 1]] = 1;
+      hIndSolve(pn, Npure + 1, rn, rad0, var, iv);
+      pn[var[iv + 1]] = 0;
+      b = rad0;
+      c = Nrad;
+      hElimR(rn, &rad0, b, c, var, iv);
+      hPure(rn, b, &c, var, iv, pn, &x);
+      hLex2R(rn, rad0, b, c, var, iv, hwork);
+      rad0 += (c - b);
+      hIndSolve(pn, Npure + x, rn, rad0, var, iv);
+    }
+    else
+    {
+      hIndSolve(pure, Npure, rad, Nrad, var, iv);
+    }
+  }
+  else
+  {
+    hCo = Npure + 1;
+    for (x=(currRing->N); x; x--)
+    {
+      if (pure[x])
+        hInd[x] = 0;
+      else
+        hInd[x] = 1;
+    }
+    hInd[var[iv]] = 0;
+  }
+}
+
+intvec * scIndIntvec(ideal S, ideal Q)
+{
+  id_Test(S, currRing);
+  id_Test(Q, currRing);
+  intvec *Set=new intvec((currRing->N));
+  int  mc,i;
+  hexist = hInit(S, Q, &hNexist, currRing);
+  if (hNexist==0)
+  {
+    for(i=0; i<(currRing->N); i++)
+      (*Set)[i]=1;
+    return Set;
+  }
+  hwork = (scfmon)omAlloc(hNexist * sizeof(scmon));
+  hvar = (varset)omAlloc(((currRing->N) + 1) * sizeof(int));
+  hpure = (scmon)omAlloc((1 + ((currRing->N) * (currRing->N))) * sizeof(int));
+  hInd = (scmon)omAlloc0((1 + (currRing->N)) * sizeof(int));
+  mc = hisModule;
+  if (mc==0)
+  {
+    hrad = hexist;
+    hNrad = hNexist;
+  }
+  else
+    hrad = (scfmon)omAlloc(hNexist * sizeof(scmon));
+  radmem = hCreate((currRing->N) - 1);
+  hCo = (currRing->N) + 1;
+  loop
+  {
+    if (mc!=0)
+      hComp(hexist, hNexist, mc, hrad, &hNrad);
+    if (hNrad!=0)
+    {
+      hNvar = (currRing->N);
+      hRadical(hrad, &hNrad, hNvar);
+      hSupp(hrad, hNrad, hvar, &hNvar);
+      if (hNvar!=0)
+      {
+        memset(hpure, 0, ((currRing->N) + 1) * sizeof(int));
+        hPure(hrad, 0, &hNrad, hvar, hNvar, hpure, &hNpure);
+        hLexR(hrad, hNrad, hvar, hNvar);
+        hIndSolve(hpure, hNpure, hrad, hNrad, hvar, hNvar);
+      }
+    }
+    else
+    {
+      hCo = 0;
+      break;
+    }
+    mc--;
+    if (mc <= 0)
+      break;
+  }
+  for(i=0; i<(currRing->N); i++)
+    (*Set)[i] = hInd[i+1];
+  hKill(radmem, (currRing->N) - 1);
+  omFreeSize((ADDRESS)hpure, (1 + ((currRing->N) * (currRing->N))) * sizeof(int));
+  omFreeSize((ADDRESS)hInd, (1 + (currRing->N)) * sizeof(int));
+  omFreeSize((ADDRESS)hvar, ((currRing->N) + 1) * sizeof(int));
+  omFreeSize((ADDRESS)hwork, hNexist * sizeof(scmon));
+  hDelete(hexist, hNexist);
+  if (hisModule)
+    omFreeSize((ADDRESS)hrad, hNexist * sizeof(scmon));
+  return Set;
+}
+
+indset ISet, JSet;
+
+static BOOLEAN hNotZero(scfmon rad, int Nrad, varset var, int Nvar)
+{
+  int  k1, i;
+  k1 = var[Nvar];
+  i = 0;
+  loop
+  {
+    if (rad[i][k1]==0)
+      return FALSE;
+    i++;
+    if (i == Nrad)
+      return TRUE;
+  }
+}
+
+static void hIndep(scmon pure)
+{
+  int iv;
+  intvec *Set;
+
+  Set = ISet->set = new intvec((currRing->N));
+  for (iv=(currRing->N); iv!=0 ; iv--)
+  {
+    if (pure[iv])
+      (*Set)[iv-1] = 0;
+    else
+      (*Set)[iv-1] = 1;
+  }
+  ISet = ISet->nx = (indset)omAlloc0Bin(indlist_bin);
+  hMu++;
+}
+
+void hIndMult(scmon pure, int Npure, scfmon rad, int Nrad,
+ varset var, int Nvar)
+{
+  int  dn, iv, rad0, b, c, x;
+  scmon pn;
+  scfmon rn;
+  if (Nrad < 2)
+  {
+    dn = Npure + Nrad;
+    if (dn == hCo)
+    {
+      if (Nrad==0)
+        hIndep(pure);
+      else
+      {
+        pn = *rad;
+        for (iv = Nvar; iv!=0; iv--)
+        {
+          x = var[iv];
+          if (pn[x])
+          {
+            pure[x] = 1;
+            hIndep(pure);
+            pure[x] = 0;
+          }
+        }
+      }
+    }
+    return;
+  }
+  iv = Nvar;
+  dn = Npure+1;
+  if (dn >= hCo)
+  {
+    if (dn > hCo)
+      return;
+    loop
+    {
+      if(!pure[var[iv]])
+      {
+        if(hNotZero(rad, Nrad, var, iv))
+        {
+          pure[var[iv]] = 1;
+          hIndep(pure);
+          pure[var[iv]] = 0;
+        }
+      }
+      iv--;
+      if (!iv)
+        return;
+    }
+  }
+  while(pure[var[iv]]) iv--;
+  hStepR(rad, Nrad, var, iv, &rad0);
+  iv--;
+  if (rad0 < Nrad)
+  {
+    pn = hGetpure(pure);
+    rn = hGetmem(Nrad, rad, radmem[iv]);
+    pn[var[iv + 1]] = 1;
+    hIndMult(pn, Npure + 1, rn, rad0, var, iv);
+    pn[var[iv + 1]] = 0;
+    b = rad0;
+    c = Nrad;
+    hElimR(rn, &rad0, b, c, var, iv);
+    hPure(rn, b, &c, var, iv, pn, &x);
+    hLex2R(rn, rad0, b, c, var, iv, hwork);
+    rad0 += (c - b);
+    hIndMult(pn, Npure + x, rn, rad0, var, iv);
+  }
+  else
+  {
+    hIndMult(pure, Npure, rad, Nrad, var, iv);
+  }
+}
+
+/*3
+* consider indset x := !pure
+* (for all i) (if(sm(i) > x) return FALSE)
+* else return TRUE
+*/
+static BOOLEAN hCheck1(indset sm, scmon pure)
+{
+  int iv;
+  intvec *Set;
+  while (sm->nx != NULL)
+  {
+    Set = sm->set;
+    iv=(currRing->N);
+    loop
+    {
+      if (((*Set)[iv-1] == 0) && (pure[iv] == 0))
+        break;
+      iv--;
+      if (iv == 0)
+        return FALSE;
+    }
+    sm = sm->nx;
+  }
+  return TRUE;
+}
+
+/*3
+* consider indset x := !pure
+* (for all i) if(x > sm(i)) delete sm(i))
+* return (place for x)
+*/
+static indset hCheck2(indset sm, scmon pure)
+{
+  int iv;
+  intvec *Set;
+  indset be, a1 = NULL;
+  while (sm->nx != NULL)
+  {
+    Set = sm->set;
+    iv=(currRing->N);
+    loop
+    {
+      if ((pure[iv] == 1) && ((*Set)[iv-1] == 1))
+        break;
+      iv--;
+      if (iv == 0)
+      {
+        if (a1 == NULL)
+        {
+          a1 = sm;
+        }
+        else
+        {
+          hMu2--;
+          be->nx = sm->nx;
+          delete Set;
+          omFreeBin((ADDRESS)sm, indlist_bin);
+          sm = be;
+        }
+        break;
+      }
+    }
+    be = sm;
+    sm = sm->nx;
+  }
+  if (a1 != NULL)
+  {
+    return a1;
+  }
+  else
+  {
+    hMu2++;
+    sm->set = new intvec((currRing->N));
+    sm->nx = (indset)omAlloc0Bin(indlist_bin);
+    return sm;
+  }
+}
+
+/*2
+*  definition x >= y
+*      x(i) == 0 => y(i) == 0
+*      > ex. j with x(j) == 1 and y(j) == 0
+*/
+static void hCheckIndep(scmon pure)
+{
+  intvec *Set;
+  indset res;
+  int iv;
+  if (hCheck1(ISet, pure))
+  {
+    if (hCheck1(JSet, pure))
+    {
+      res = hCheck2(JSet,pure);
+      if (res == NULL)
+        return;
+      Set = res->set;
+      for (iv=(currRing->N); iv; iv--)
+      {
+        if (pure[iv])
+          (*Set)[iv-1] = 0;
+        else
+          (*Set)[iv-1] = 1;
+      }
+    }
+  }
+}
+
+void hIndAllMult(scmon pure, int Npure, scfmon rad, int Nrad,
+ varset var, int Nvar)
+{
+  int  dn, iv, rad0, b, c, x;
+  scmon pn;
+  scfmon rn;
+  if (Nrad < 2)
+  {
+    dn = Npure + Nrad;
+    if (dn > hCo)
+    {
+      if (!Nrad)
+        hCheckIndep(pure);
+      else
+      {
+        pn = *rad;
+        for (iv = Nvar; iv; iv--)
+        {
+          x = var[iv];
+          if (pn[x])
+          {
+            pure[x] = 1;
+            hCheckIndep(pure);
+            pure[x] = 0;
+          }
+        }
+      }
+    }
+    return;
+  }
+  iv = Nvar;
+  while(pure[var[iv]]) iv--;
+  hStepR(rad, Nrad, var, iv, &rad0);
+  iv--;
+  if (rad0 < Nrad)
+  {
+    pn = hGetpure(pure);
+    rn = hGetmem(Nrad, rad, radmem[iv]);
+    pn[var[iv + 1]] = 1;
+    hIndAllMult(pn, Npure + 1, rn, rad0, var, iv);
+    pn[var[iv + 1]] = 0;
+    b = rad0;
+    c = Nrad;
+    hElimR(rn, &rad0, b, c, var, iv);
+    hPure(rn, b, &c, var, iv, pn, &x);
+    hLex2R(rn, rad0, b, c, var, iv, hwork);
+    rad0 += (c - b);
+    hIndAllMult(pn, Npure + x, rn, rad0, var, iv);
+  }
+  else
+  {
+    hIndAllMult(pure, Npure, rad, Nrad, var, iv);
+  }
+}
+
+// multiplicity
+
+static int hZeroMult(scmon pure, scfmon stc, int Nstc, varset var, int Nvar)
+{
+  int  iv = Nvar -1, sum, a, a0, a1, b, i;
+  int  x, x0;
+  scmon pn;
+  scfmon sn;
+  if (!iv)
+    return pure[var[1]];
+  else if (!Nstc)
+  {
+    sum = 1;
+    for (i = Nvar; i; i--)
+      sum *= pure[var[i]];
+    return sum;
+  }
+  x = a = 0;
+  pn = hGetpure(pure);
+  sn = hGetmem(Nstc, stc, stcmem[iv]);
+  hStepS(sn, Nstc, var, Nvar, &a, &x);
+  if (a == Nstc)
+    return pure[var[Nvar]] * hZeroMult(pn, sn, a, var, iv);
+  else
+    sum = x * hZeroMult(pn, sn, a, var, iv);
+  b = a;
+  loop
+  {
+    a0 = a;
+    x0 = x;
+    hStepS(sn, Nstc, var, Nvar, &a, &x);
+    hElimS(sn, &b, a0, a, var, iv);
+    a1 = a;
+    hPure(sn, a0, &a1, var, iv, pn, &i);
+    hLex2S(sn, b, a0, a1, var, iv, hwork);
+    b += (a1 - a0);
+    if (a < Nstc)
+    {
+      sum += (x - x0) * hZeroMult(pn, sn, b, var, iv);
+    }
+    else
+    {
+      sum += (pure[var[Nvar]] - x0) * hZeroMult(pn, sn, b, var, iv);
+      return sum;
+    }
+  }
+}
+
+static void hProject(scmon pure, varset sel)
+{
+  int  i, i0, k;
+  i0 = 0;
+  for (i = 1; i <= (currRing->N); i++)
+  {
+    if (pure[i])
+    {
+      i0++;
+      sel[i0] = i;
+    }
+  }
+  i = hNstc;
+  memcpy(hwork, hstc, i * sizeof(scmon));
+  hStaircase(hwork, &i, sel, i0);
+  if ((i0 > 2) && (i > 10))
+    hOrdSupp(hwork, i, sel, i0);
+  memset(hpur0, 0, ((currRing->N) + 1) * sizeof(int));
+  hPure(hwork, 0, &i, sel, i0, hpur0, &k);
+  hLexS(hwork, i, sel, i0);
+  hMu += hZeroMult(hpur0, hwork, i, sel, i0);
+}
+
+static void hDimMult(scmon pure, int Npure, scfmon rad, int Nrad,
+ varset var, int Nvar)
+{
+  int  dn, iv, rad0, b, c, x;
+  scmon pn;
+  scfmon rn;
+  if (Nrad < 2)
+  {
+    dn = Npure + Nrad;
+    if (dn == hCo)
+    {
+      if (!Nrad)
+        hProject(pure, hsel);
+      else
+      {
+        pn = *rad;
+        for (iv = Nvar; iv; iv--)
+        {
+          x = var[iv];
+          if (pn[x])
+          {
+            pure[x] = 1;
+            hProject(pure, hsel);
+            pure[x] = 0;
+          }
+        }
+      }
+    }
+    return;
+  }
+  iv = Nvar;
+  dn = Npure+1;
+  if (dn >= hCo)
+  {
+    if (dn > hCo)
+      return;
+    loop
+    {
+      if(!pure[var[iv]])
+      {
+        if(hNotZero(rad, Nrad, var, iv))
+        {
+          pure[var[iv]] = 1;
+          hProject(pure, hsel);
+          pure[var[iv]] = 0;
+        }
+      }
+      iv--;
+      if (!iv)
+        return;
+    }
+  }
+  while(pure[var[iv]]) iv--;
+  hStepR(rad, Nrad, var, iv, &rad0);
+  iv--;
+  if (rad0 < Nrad)
+  {
+    pn = hGetpure(pure);
+    rn = hGetmem(Nrad, rad, radmem[iv]);
+    pn[var[iv + 1]] = 1;
+    hDimMult(pn, Npure + 1, rn, rad0, var, iv);
+    pn[var[iv + 1]] = 0;
+    b = rad0;
+    c = Nrad;
+    hElimR(rn, &rad0, b, c, var, iv);
+    hPure(rn, b, &c, var, iv, pn, &x);
+    hLex2R(rn, rad0, b, c, var, iv, hwork);
+    rad0 += (c - b);
+    hDimMult(pn, Npure + x, rn, rad0, var, iv);
+  }
+  else
+  {
+    hDimMult(pure, Npure, rad, Nrad, var, iv);
+  }
+}
+
+static void hDegree(ideal S, ideal Q)
+{
+  id_Test(S, currRing);
+  id_Test(Q, currRing);
+  int  di;
+  int  mc;
+  hexist = hInit(S, Q, &hNexist, currRing);
+  if (!hNexist)
+  {
+    hCo = 0;
+    hMu = 1;
+    return;
+  }
+  //hWeight();
+  hwork = (scfmon)omAlloc(hNexist * sizeof(scmon));
+  hvar = (varset)omAlloc(((currRing->N) + 1) * sizeof(int));
+  hsel = (varset)omAlloc(((currRing->N) + 1) * sizeof(int));
+  hpure = (scmon)omAlloc((1 + ((currRing->N) * (currRing->N))) * sizeof(int));
+  hpur0 = (scmon)omAlloc((1 + ((currRing->N) * (currRing->N))) * sizeof(int));
+  mc = hisModule;
+  hrad = (scfmon)omAlloc(hNexist * sizeof(scmon));
+  if (!mc)
+  {
+    memcpy(hrad, hexist, hNexist * sizeof(scmon));
+    hstc = hexist;
+    hNrad = hNstc = hNexist;
+  }
+  else
+    hstc = (scfmon)omAlloc(hNexist * sizeof(scmon));
+  radmem = hCreate((currRing->N) - 1);
+  stcmem = hCreate((currRing->N) - 1);
+  hCo = (currRing->N) + 1;
+  di = hCo + 1;
+  loop
+  {
+    if (mc)
+    {
+      hComp(hexist, hNexist, mc, hrad, &hNrad);
+      hNstc = hNrad;
+      memcpy(hstc, hrad, hNrad * sizeof(scmon));
+    }
+    if (hNrad)
+    {
+      hNvar = (currRing->N);
+      hRadical(hrad, &hNrad, hNvar);
+      hSupp(hrad, hNrad, hvar, &hNvar);
+      if (hNvar)
+      {
+        hCo = hNvar;
+        memset(hpure, 0, ((currRing->N) + 1) * sizeof(int));
+        hPure(hrad, 0, &hNrad, hvar, hNvar, hpure, &hNpure);
+        hLexR(hrad, hNrad, hvar, hNvar);
+        hDimSolve(hpure, hNpure, hrad, hNrad, hvar, hNvar);
+      }
+    }
+    else
+    {
+      hNvar = 1;
+      hCo = 0;
+    }
+    if (hCo < di)
+    {
+      di = hCo;
+      hMu = 0;
+    }
+    if (hNvar && (hCo == di))
+    {
+      if (di && (di < (currRing->N)))
+        hDimMult(hpure, hNpure, hrad, hNrad, hvar, hNvar);
+      else if (!di)
+        hMu++;
+      else
+      {
+        hStaircase(hstc, &hNstc, hvar, hNvar);
+        if ((hNvar > 2) && (hNstc > 10))
+          hOrdSupp(hstc, hNstc, hvar, hNvar);
+        memset(hpur0, 0, ((currRing->N) + 1) * sizeof(int));
+        hPure(hstc, 0, &hNstc, hvar, hNvar, hpur0, &hNpure);
+        hLexS(hstc, hNstc, hvar, hNvar);
+        hMu += hZeroMult(hpur0, hstc, hNstc, hvar, hNvar);
+      }
+    }
+    mc--;
+    if (mc <= 0)
+      break;
+  }
+  hCo = di;
+  hKill(stcmem, (currRing->N) - 1);
+  hKill(radmem, (currRing->N) - 1);
+  omFreeSize((ADDRESS)hpur0, (1 + ((currRing->N) * (currRing->N))) * sizeof(int));
+  omFreeSize((ADDRESS)hpure, (1 + ((currRing->N) * (currRing->N))) * sizeof(int));
+  omFreeSize((ADDRESS)hsel, ((currRing->N) + 1) * sizeof(int));
+  omFreeSize((ADDRESS)hvar, ((currRing->N) + 1) * sizeof(int));
+  omFreeSize((ADDRESS)hwork, hNexist * sizeof(scmon));
+  omFreeSize((ADDRESS)hrad, hNexist * sizeof(scmon));
+  hDelete(hexist, hNexist);
+  if (hisModule)
+    omFreeSize((ADDRESS)hstc, hNexist * sizeof(scmon));
+}
+
+int  scMultInt(ideal S, ideal Q)
+{
+  id_Test(S, currRing);
+  id_Test(Q, currRing);
+  hDegree(S, Q);
+  return hMu;
+}
+
+void scPrintDegree(int co, int mu)
+{
+  int di = (currRing->N)-co;
+  if (currRing->OrdSgn == 1)
+  {
+    if (di>0)
+      Print("// dimension (proj.)  = %d\n// degree (proj.)   = %d\n", di-1, mu);
+    else
+      Print("// dimension (affine) = 0\n// degree (affine)  = %d\n",       mu);
+  }
+  else
+    Print("// dimension (local)   = %d\n// multiplicity = %d\n", di, mu);
+}
+
+void scDegree(ideal S, intvec *modulweight, ideal Q)
+{
+  id_Test(S, currRing);
+  id_Test(Q, currRing);
+  int co, mu, l;
+  intvec *hseries2;
+  intvec *hseries1 = hFirstSeries(S, modulweight, Q);
+  l = hseries1->length()-1;
+  if (l > 1)
+    hseries2 = hSecondSeries(hseries1);
+  else
+    hseries2 = hseries1;
+  hDegreeSeries(hseries1, hseries2, &co, &mu);
+  if ((l == 1) &&(mu == 0))
+    scPrintDegree((currRing->N)+1, 0);
+  else
+    scPrintDegree(co, mu);
+  if (l>1)
+    delete hseries1;
+  delete hseries2;
+}
+
+static void hDegree0(ideal S, ideal Q, const ring tailRing)
+{
+  id_TestTail(S, currRing, tailRing);
+  id_TestTail(Q, currRing, tailRing);
+
+  int  mc;
+  hexist = hInit(S, Q, &hNexist, tailRing);
+  if (!hNexist)
+  {
+    hMu = -1;
+    return;
+  }
+  else
+    hMu = 0;
+
+  const ring r = currRing;
+
+  hwork = (scfmon)omAlloc(hNexist * sizeof(scmon));
+  hvar = (varset)omAlloc(((r->N) + 1) * sizeof(int));
+  hpur0 = (scmon)omAlloc((1 + ((r->N) * (r->N))) * sizeof(int));
+  mc = hisModule;
+  if (!mc)
+  {
+    hstc = hexist;
+    hNstc = hNexist;
+  }
+  else
+    hstc = (scfmon)omAlloc(hNexist * sizeof(scmon));
+  stcmem = hCreate((r->N) - 1);
+  loop
+  {
+    if (mc)
+    {
+      hComp(hexist, hNexist, mc, hstc, &hNstc);
+      if (!hNstc)
+      {
+        hMu = -1;
+        break;
+      }
+    }
+    hNvar = (r->N);
+    for (int i = hNvar; i; i--)
+      hvar[i] = i;
+    hStaircase(hstc, &hNstc, hvar, hNvar);
+    hSupp(hstc, hNstc, hvar, &hNvar);
+    if ((hNvar == (r->N)) && (hNstc >= (r->N)))
+    {
+      if ((hNvar > 2) && (hNstc > 10))
+        hOrdSupp(hstc, hNstc, hvar, hNvar);
+      memset(hpur0, 0, ((r->N) + 1) * sizeof(int));
+      hPure(hstc, 0, &hNstc, hvar, hNvar, hpur0, &hNpure);
+      if (hNpure == hNvar)
+      {
+        hLexS(hstc, hNstc, hvar, hNvar);
+        hMu += hZeroMult(hpur0, hstc, hNstc, hvar, hNvar);
+      }
+      else
+        hMu = -1;
+    }
+    else if (hNvar)
+      hMu = -1;
+    mc--;
+    if (mc <= 0 || hMu < 0)
+      break;
+  }
+  hKill(stcmem, (r->N) - 1);
+  omFreeSize((ADDRESS)hpur0, (1 + ((r->N) * (r->N))) * sizeof(int));
+  omFreeSize((ADDRESS)hvar, ((r->N) + 1) * sizeof(int));
+  omFreeSize((ADDRESS)hwork, hNexist * sizeof(scmon));
+  hDelete(hexist, hNexist);
+  if (hisModule)
+    omFreeSize((ADDRESS)hstc, hNexist * sizeof(scmon));
+}
+
+int  scMult0Int(ideal S, ideal Q, const ring tailRing)
+{
+  id_TestTail(S, currRing, tailRing);
+  id_TestTail(Q, currRing, tailRing);
+  hDegree0(S, Q, tailRing);
+  return hMu;
+}
+
+
+// HC
+
+static poly pWork;
+
+static void hHedge(poly hEdge)
+{
+  pSetm(pWork);
+  if (pLmCmp(pWork, hEdge) == currRing->OrdSgn)
+  {
+    for (int i = hNvar; i>0; i--)
+      pSetExp(hEdge,i, pGetExp(pWork,i));
+    pSetm(hEdge);
+  }
+}
+
+
+static void hHedgeStep(scmon pure, scfmon stc,
+                       int Nstc, varset var, int Nvar,poly hEdge)
+{
+  int  iv = Nvar -1, k = var[Nvar], a, a0, a1, b, i;
+  int  x/*, x0*/;
+  scmon pn;
+  scfmon sn;
+  if (iv==0)
+  {
+    pSetExp(pWork, k, pure[k]);
+    hHedge(hEdge);
+    return;
+  }
+  else if (Nstc==0)
+  {
+    for (i = Nvar; i>0; i--)
+      pSetExp(pWork, var[i], pure[var[i]]);
+    hHedge(hEdge);
+    return;
+  }
+  x = a = 0;
+  pn = hGetpure(pure);
+  sn = hGetmem(Nstc, stc, stcmem[iv]);
+  hStepS(sn, Nstc, var, Nvar, &a, &x);
+  if (a == Nstc)
+  {
+    pSetExp(pWork, k, pure[k]);
+    hHedgeStep(pn, sn, a, var, iv,hEdge);
+    return;
+  }
+  else
+  {
+    pSetExp(pWork, k, x);
+    hHedgeStep(pn, sn, a, var, iv,hEdge);
+  }
+  b = a;
+  loop
+  {
+    a0 = a;
+    // x0 = x;
+    hStepS(sn, Nstc, var, Nvar, &a, &x);
+    hElimS(sn, &b, a0, a, var, iv);
+    a1 = a;
+    hPure(sn, a0, &a1, var, iv, pn, &i);
+    hLex2S(sn, b, a0, a1, var, iv, hwork);
+    b += (a1 - a0);
+    if (a < Nstc)
+    {
+      pSetExp(pWork, k, x);
+      hHedgeStep(pn, sn, b, var, iv,hEdge);
+    }
+    else
+    {
+      pSetExp(pWork, k, pure[k]);
+      hHedgeStep(pn, sn, b, var, iv,hEdge);
+      return;
+    }
+  }
+}
+
+void scComputeHC(ideal S, ideal Q, int ak, poly &hEdge, ring tailRing)
+{
+  id_TestTail(S, currRing, tailRing);
+  id_TestTail(Q, currRing, tailRing);
+  int  i;
+  int  k = ak;
+
+  #if HAVE_RINGS
+  if (rField_is_Ring(currRing) && (currRing->OrdSgn == -1))
+  {
+  //consider just monic generators (over rings with zero-divisors)
+  ideal SS=id_Copy(S,tailRing);
+  for(i=0;i<=idElem(SS);i++)
+  	{
+  	if(pIsPurePower(SS->m[i])==0)
+  		p_Delete(&SS->m[i],tailRing);
+  	}
+  	S=id_Copy(SS,tailRing);
+  }
+  #endif
+
+  hNvar = (currRing->N);
+  hexist = hInit(S, Q, &hNexist, tailRing); // tailRing?
+  if (k!=0)
+    hComp(hexist, hNexist, k, hexist, &hNstc);
+  else
+    hNstc = hNexist;
+  hwork = (scfmon)omAlloc(hNexist * sizeof(scmon));
+  hvar = (varset)omAlloc((hNvar + 1) * sizeof(int));
+  hpure = (scmon)omAlloc((1 + (hNvar * hNvar)) * sizeof(int));
+  stcmem = hCreate(hNvar - 1);
+  for (i = hNvar; i>0; i--)
+    hvar[i] = i;
+  hStaircase(hexist, &hNstc, hvar, hNvar);
+  if ((hNvar > 2) && (hNstc > 10))
+    hOrdSupp(hexist, hNstc, hvar, hNvar);
+  memset(hpure, 0, (hNvar + 1) * sizeof(int));
+  hPure(hexist, 0, &hNstc, hvar, hNvar, hpure, &hNpure);
+  hLexS(hexist, hNstc, hvar, hNvar);
+  if (hEdge!=NULL)
+    pLmFree(hEdge);
+  hEdge = pInit();
+  pWork = pInit();
+  hHedgeStep(hpure, hexist, hNstc, hvar, hNvar,hEdge);
+  pSetComp(hEdge,ak);
+  hKill(stcmem, hNvar - 1);
+  omFreeSize((ADDRESS)hwork, hNexist * sizeof(scmon));
+  omFreeSize((ADDRESS)hvar, (hNvar + 1) * sizeof(int));
+  omFreeSize((ADDRESS)hpure, (1 + (hNvar * hNvar)) * sizeof(int));
+  hDelete(hexist, hNexist);
+  pLmFree(pWork);
+}
+
+
+
+//  kbase
+
+static poly last;
+static scmon act;
+
+static void scElKbase()
+{
+  poly q = pInit();
+  pSetCoeff0(q,nInit(1));
+  pSetExpV(q,act);
+  pNext(q) = NULL;
+  last = pNext(last) = q;
+}
+
+static int scMax( int i, scfmon stc, int Nvar)
+{
+  int x, y=stc[0][Nvar];
+  for (; i;)
+  {
+    i--;
+    x = stc[i][Nvar];
+    if (x > y) y = x;
+  }
+  return y;
+}
+
+static int scMin( int i, scfmon stc, int Nvar)
+{
+  int x, y=stc[0][Nvar];
+  for (; i;)
+  {
+    i--;
+    x = stc[i][Nvar];
+    if (x < y) y = x;
+  }
+  return y;
+}
+
+static int scRestrict( int &Nstc, scfmon stc, int Nvar)
+{
+  int x, y;
+  int i, j, Istc = Nstc;
+
+  y = MAX_INT_VAL;
+  for (i=Nstc-1; i>=0; i--)
+  {
+    j = Nvar-1;
+    loop
+    {
+      if(stc[i][j] != 0) break;
+      j--;
+      if (j == 0)
+      {
+        Istc--;
+        x = stc[i][Nvar];
+        if (x < y) y = x;
+        stc[i] = NULL;
+        break;
+      }
+    }
+  }
+  if (Istc < Nstc)
+  {
+    for (i=Nstc-1; i>=0; i--)
+    {
+      if (stc[i] && (stc[i][Nvar] >= y))
+      {
+        Istc--;
+        stc[i] = NULL;
+      }
+    }
+    j = 0;
+    while (stc[j]) j++;
+    i = j+1;
+    for(; i<Nstc; i++)
+    {
+      if (stc[i])
+      {
+        stc[j] = stc[i];
+        j++;
+      }
+    }
+    Nstc = Istc;
+    return y;
+  }
+  else
+    return -1;
+}
+
+static void scAll( int Nvar, int deg)
+{
+  int i;
+  int d = deg;
+  if (d == 0)
+  {
+    for (i=Nvar; i; i--) act[i] = 0;
+    scElKbase();
+    return;
+  }
+  if (Nvar == 1)
+  {
+    act[1] = d;
+    scElKbase();
+    return;
+  }
+  do
+  {
+    act[Nvar] = d;
+    scAll(Nvar-1, deg-d);
+    d--;
+  } while (d >= 0);
+}
+
+static void scAllKbase( int Nvar, int ideg, int deg)
+{
+  do
+  {
+    act[Nvar] = ideg;
+    scAll(Nvar-1, deg-ideg);
+    ideg--;
+  } while (ideg >= 0);
+}
+
+static void scDegKbase( scfmon stc, int Nstc, int Nvar, int deg)
+{
+  int  Ivar, Istc, i, j;
+  scfmon sn;
+  int x, ideg;
+
+  if (deg == 0)
+  {
+    for (i=Nstc-1; i>=0; i--)
+    {
+      for (j=Nvar;j;j--){ if(stc[i][j]) break; }
+      if (j==0){return;}
+    }
+    for (i=Nvar; i; i--) act[i] = 0;
+    scElKbase();
+    return;
+  }
+  if (Nvar == 1)
+  {
+    for (i=Nstc-1; i>=0; i--) if(deg >= stc[i][1]) return;
+    act[1] = deg;
+    scElKbase();
+    return;
+  }
+  Ivar = Nvar-1;
+  sn = hGetmem(Nstc, stc, stcmem[Ivar]);
+  x = scRestrict(Nstc, sn, Nvar);
+  if (x <= 0)
+  {
+    if (x == 0) return;
+    ideg = deg;
+  }
+  else
+  {
+    if (deg < x) ideg = deg;
+    else ideg = x-1;
+    if (Nstc == 0)
+    {
+      scAllKbase(Nvar, ideg, deg);
+      return;
+    }
+  }
+  loop
+  {
+    x = scMax(Nstc, sn, Nvar);
+    while (ideg >= x)
+    {
+      act[Nvar] = ideg;
+      scDegKbase(sn, Nstc, Ivar, deg-ideg);
+      ideg--;
+    }
+    if (ideg < 0) return;
+    Istc = Nstc;
+    for (i=Nstc-1; i>=0; i--)
+    {
+      if (ideg < sn[i][Nvar])
+      {
+        Istc--;
+        sn[i] = NULL;
+      }
+    }
+    if (Istc == 0)
+    {
+      scAllKbase(Nvar, ideg, deg);
+      return;
+    }
+    j = 0;
+    while (sn[j]) j++;
+    i = j+1;
+    for (; i<Nstc; i++)
+    {
+      if (sn[i])
+      {
+        sn[j] = sn[i];
+        j++;
+      }
+    }
+    Nstc = Istc;
+  }
+}
+
+static void scInKbase( scfmon stc, int Nstc, int Nvar)
+{
+  int  Ivar, Istc, i, j;
+  scfmon sn;
+  int x, ideg;
+
+  if (Nvar == 1)
+  {
+    ideg = scMin(Nstc, stc, 1);
+    while (ideg > 0)
+    {
+      ideg--;
+      act[1] = ideg;
+      scElKbase();
+    }
+    return;
+  }
+  Ivar = Nvar-1;
+  sn = hGetmem(Nstc, stc, stcmem[Ivar]);
+  x = scRestrict(Nstc, sn, Nvar);
+  if (x == 0) return;
+  ideg = x-1;
+  loop
+  {
+    x = scMax(Nstc, sn, Nvar);
+    while (ideg >= x)
+    {
+      act[Nvar] = ideg;
+      scInKbase(sn, Nstc, Ivar);
+      ideg--;
+    }
+    if (ideg < 0) return;
+    Istc = Nstc;
+    for (i=Nstc-1; i>=0; i--)
+    {
+      if (ideg < sn[i][Nvar])
+      {
+        Istc--;
+        sn[i] = NULL;
+      }
+    }
+    j = 0;
+    while (sn[j]) j++;
+    i = j+1;
+    for (; i<Nstc; i++)
+    {
+      if (sn[i])
+      {
+        sn[j] = sn[i];
+        j++;
+      }
+    }
+    Nstc = Istc;
+  }
+}
+
+static ideal scIdKbase(poly q, const int rank)
+{
+  ideal res = idInit(pLength(q), rank);
+  polyset mm = res->m;
+  int i = 0;
+  do
+  {
+    *mm = q; ++mm;
+
+    const poly p = pNext(q);
+    pNext(q) = NULL;
+    q = p;
+
+  } while (q!=NULL);
+
+  id_Test(res, currRing);   // WRONG RANK!!!???
+  return res;
+}
+
+ideal scKBase(int deg, ideal s, ideal Q, intvec * mv)
+{
+  id_Test(Q, currRing);
+  int  i, di;
+  poly p;
+
+  if (deg < 0)
+  {
+    di = scDimInt(s, Q);
+    if (di != 0)
+    {
+      //Werror("KBase not finite");
+      return idInit(1,s->rank);
+    }
+  }
+  stcmem = hCreate((currRing->N) - 1);
+  hexist = hInit(s, Q, &hNexist, currRing);
+  p = last = pInit();
+  /*pNext(p) = NULL;*/
+  act = (scmon)omAlloc(((currRing->N) + 1) * sizeof(int));
+  *act = 0;
+  if (!hNexist)
+  {
+    scAll((currRing->N), deg);
+    goto ende;
+  }
+  if (!hisModule)
+  {
+    if (deg < 0) scInKbase(hexist, hNexist, (currRing->N));
+    else scDegKbase(hexist, hNexist, (currRing->N), deg);
+  }
+  else
+  {
+    hstc = (scfmon)omAlloc(hNexist * sizeof(scmon));
+    for (i = 1; i <= hisModule; i++)
+    {
+      *act = i;
+      hComp(hexist, hNexist, i, hstc, &hNstc);
+      int deg_ei=deg;
+      if (mv!=NULL) deg_ei -= (*mv)[i-1];
+      if ((deg < 0) || (deg_ei>=0))
+      {
+        if (hNstc)
+        {
+          if (deg < 0) scInKbase(hstc, hNstc, (currRing->N));
+          else scDegKbase(hstc, hNstc, (currRing->N), deg_ei);
+        }
+        else
+          scAll((currRing->N), deg_ei);
+      }
+    }
+    omFreeSize((ADDRESS)hstc, hNexist * sizeof(scmon));
+  }
+ende:
+  hDelete(hexist, hNexist);
+  omFreeSize((ADDRESS)act, ((currRing->N) + 1) * sizeof(int));
+  hKill(stcmem, (currRing->N) - 1);
+  pLmDelete(&p);
+  if (p == NULL)
+    return idInit(1,s->rank);
+
+  last = p;
+  return scIdKbase(p, s->rank);
+}
+
+#if 0 //-- alternative implementation of scComputeHC
+/*
+void scComputeHCw(ideal ss, ideal Q, int ak, poly &hEdge, ring tailRing)
+{
+  id_TestTail(ss, currRing, tailRing);
+  id_TestTail(Q, currRing, tailRing);
+
+  int  i, di;
+  poly p;
+
+  if (hEdge!=NULL)
+    pLmFree(hEdge);
+
+  ideal s=idInit(IDELEMS(ss),ak);
+  for(i=IDELEMS(ss)-1;i>=0;i--)
+  {
+    if (ss->m[i]!=NULL) s->m[i]=pHead(ss->m[i]);
+  }
+  di = scDimInt(s, Q);
+  stcmem = hCreate((currRing->N) - 1);
+  hexist = hInit(s, Q, &hNexist, currRing);
+  p = last = pInit();
+  // pNext(p) = NULL;
+  act = (scmon)omAlloc(((currRing->N) + 1) * sizeof(int));
+  *act = 0;
+  if (!hNexist)
+  {
+    scAll((currRing->N), -1);
+    goto ende;
+  }
+  if (!hisModule)
+  {
+    scInKbase(hexist, hNexist, (currRing->N));
+  }
+  else
+  {
+    hstc = (scfmon)omAlloc(hNexist * sizeof(scmon));
+    for (i = 1; i <= hisModule; i++)
+    {
+      *act = i;
+      hComp(hexist, hNexist, i, hstc, &hNstc);
+      if (hNstc)
+      {
+        scInKbase(hstc, hNstc, (currRing->N));
+      }
+      else
+        scAll((currRing->N), -1);
+    }
+    omFreeSize((ADDRESS)hstc, hNexist * sizeof(scmon));
+  }
+ende:
+  hDelete(hexist, hNexist);
+  omFreeSize((ADDRESS)act, ((currRing->N) + 1) * sizeof(int));
+  hKill(stcmem, (currRing->N) - 1);
+  pDeleteLm(&p);
+  idDelete(&s);
+  if (p == NULL)
+  {
+    return; // no HEdge
+  }
+  else
+  {
+    last = p;
+    ideal res=scIdKbase(p, ss->rank);
+    poly p_ind=res->m[0]; int ind=0;
+    for(i=IDELEMS(res)-1;i>0;i--)
+    {
+      if (pCmp(res->m[i],p_ind)==-1) { p_ind=res->m[i]; ind=i; }
+    }
+    assume(p_ind!=NULL);
+    assume(res->m[ind]==p_ind);
+    hEdge=p_ind;
+    res->m[ind]=NULL;
+    nDelete(&pGetCoeff(hEdge));
+    pGetCoeff(hEdge)=NULL;
+    for(i=(currRing->N);i>0;i--)
+      pIncrExp(hEdge,i);
+    pSetm(hEdge);
+
+    idDelete(&res);
+    return;
+  }
+}
+ */
+#endif
diff --git a/kernel/combinatorics/hilb.cc b/kernel/combinatorics/hilb.cc
new file mode 100644
index 0000000..2ad5c87
--- /dev/null
+++ b/kernel/combinatorics/hilb.cc
@@ -0,0 +1,1405 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+*  ABSTRACT -  Hilbert series
+*/
+
+#include <kernel/mod2.h>
+
+#include <omalloc/omalloc.h>
+#include <misc/auxiliary.h>
+#include <misc/mylimits.h>
+#include <misc/intvec.h>
+
+#include <kernel/combinatorics/hilb.h>
+#include <kernel/combinatorics/stairc.h>
+#include <kernel/combinatorics/hutil.h>
+
+#include <polys/monomials/ring.h>
+#include <polys/monomials/p_polys.h>
+#include <polys/simpleideals.h>
+
+
+// #include <kernel/structs.h>
+// #include <kernel/polys.h>
+//ADICHANGES:
+#include <kernel/ideals.h>
+// #include <kernel/GBEngine/kstd1.h>
+// #include<gmp.h>
+// #include<vector>
+
+
+static int  **Qpol;
+static int  *Q0, *Ql;
+static int  hLength;
+
+
+static int hMinModulweight(intvec *modulweight)
+{
+  int i,j,k;
+
+  if(modulweight==NULL) return 0;
+  j=(*modulweight)[0];
+  for(i=modulweight->rows()-1;i!=0;i--)
+  {
+    k=(*modulweight)[i];
+    if(k<j) j=k;
+  }
+  return j;
+}
+
+static void hHilbEst(scfmon stc, int Nstc, varset var, int Nvar)
+{
+  int  i, j;
+  int  x, y, z = 1;
+  int  *p;
+  for (i = Nvar; i>0; i--)
+  {
+    x = 0;
+    for (j = 0; j < Nstc; j++)
+    {
+      y = stc[j][var[i]];
+      if (y > x)
+        x = y;
+    }
+    z += x;
+    j = i - 1;
+    if (z > Ql[j])
+    {
+      if (z>(MAX_INT_VAL)/2)
+      {
+       Werror("interal arrays too big");
+       return;
+      }
+      p = (int *)omAlloc((unsigned long)z * sizeof(int));
+      if (Ql[j]!=0)
+      {
+        if (j==0)
+          memcpy(p, Qpol[j], Ql[j] * sizeof(int));
+        omFreeSize((ADDRESS)Qpol[j], Ql[j] * sizeof(int));
+      }
+      if (j==0)
+      {
+        for (x = Ql[j]; x < z; x++)
+          p[x] = 0;
+      }
+      Ql[j] = z;
+      Qpol[j] = p;
+    }
+  }
+}
+
+static int  *hAddHilb(int Nv, int x, int *pol, int *lp)
+{
+  int  l = *lp, ln, i;
+  int  *pon;
+  *lp = ln = l + x;
+  pon = Qpol[Nv];
+  memcpy(pon, pol, l * sizeof(int));
+  if (l > x)
+  {
+    for (i = x; i < l; i++)
+      pon[i] -= pol[i - x];
+    for (i = l; i < ln; i++)
+      pon[i] = -pol[i - x];
+  }
+  else
+  {
+    for (i = l; i < x; i++)
+      pon[i] = 0;
+    for (i = x; i < ln; i++)
+      pon[i] = -pol[i - x];
+  }
+  return pon;
+}
+
+static void hLastHilb(scmon pure, int Nv, varset var, int *pol, int lp)
+{
+  int  l = lp, x, i, j;
+  int  *p, *pl;
+  p = pol;
+  for (i = Nv; i>0; i--)
+  {
+    x = pure[var[i + 1]];
+    if (x!=0)
+      p = hAddHilb(i, x, p, &l);
+  }
+  pl = *Qpol;
+  j = Q0[Nv + 1];
+  for (i = 0; i < l; i++)
+    pl[i + j] += p[i];
+  x = pure[var[1]];
+  if (x!=0)
+  {
+    j += x;
+    for (i = 0; i < l; i++)
+      pl[i + j] -= p[i];
+  }
+  j += l;
+  if (j > hLength)
+    hLength = j;
+}
+
+static void hHilbStep(scmon pure, scfmon stc, int Nstc, varset var,
+ int Nvar, int *pol, int Lpol)
+{
+  int  iv = Nvar -1, ln, a, a0, a1, b, i;
+  int  x, x0;
+  scmon pn;
+  scfmon sn;
+  int  *pon;
+  if (Nstc==0)
+  {
+    hLastHilb(pure, iv, var, pol, Lpol);
+    return;
+  }
+  x = a = 0;
+  pn = hGetpure(pure);
+  sn = hGetmem(Nstc, stc, stcmem[iv]);
+  hStepS(sn, Nstc, var, Nvar, &a, &x);
+  Q0[iv] = Q0[Nvar];
+  ln = Lpol;
+  pon = pol;
+  if (a == Nstc)
+  {
+    x = pure[var[Nvar]];
+    if (x!=0)
+      pon = hAddHilb(iv, x, pon, &ln);
+    hHilbStep(pn, sn, a, var, iv, pon, ln);
+    return;
+  }
+  else
+  {
+    pon = hAddHilb(iv, x, pon, &ln);
+    hHilbStep(pn, sn, a, var, iv, pon, ln);
+  }
+  b = a;
+  x0 = 0;
+  loop
+  {
+    Q0[iv] += (x - x0);
+    a0 = a;
+    x0 = x;
+    hStepS(sn, Nstc, var, Nvar, &a, &x);
+    hElimS(sn, &b, a0, a, var, iv);
+    a1 = a;
+    hPure(sn, a0, &a1, var, iv, pn, &i);
+    hLex2S(sn, b, a0, a1, var, iv, hwork);
+    b += (a1 - a0);
+    ln = Lpol;
+    if (a < Nstc)
+    {
+      pon = hAddHilb(iv, x - x0, pol, &ln);
+      hHilbStep(pn, sn, b, var, iv, pon, ln);
+    }
+    else
+    {
+      x = pure[var[Nvar]];
+      if (x!=0)
+        pon = hAddHilb(iv, x - x0, pol, &ln);
+      else
+        pon = pol;
+      hHilbStep(pn, sn, b, var, iv, pon, ln);
+      return;
+    }
+  }
+}
+
+/*
+*basic routines
+*/
+static void hWDegree(intvec *wdegree)
+{
+  int i, k;
+  int x;
+
+  for (i=(currRing->N); i; i--)
+  {
+    x = (*wdegree)[i-1];
+    if (x != 1)
+    {
+      for (k=hNexist-1; k>=0; k--)
+      {
+        hexist[k][i] *= x;
+      }
+    }
+  }
+}
+// ---------------------------------- ADICHANGES ---------------------------------------------
+//!!!!!!!!!!!!!!!!!!!!! Just for Monomial Ideals !!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+//returns the degree of the monomial
+static int DegMon(poly p)
+{
+    #if 1
+    int i,deg;
+    deg = 0;
+    for(i=1;i<=currRing->N;i++)
+    {
+        deg = deg + p_GetExp(p, i, currRing);
+    }
+    return(deg);
+    #else
+    return(p_Deg(p, currRing));
+    #endif
+}
+
+//Tests if the ideal is sorted by degree
+static bool idDegSortTest(ideal I)
+{
+    if((I == NULL)||(idIs0(I)))
+    {
+        return(TRUE);
+    }
+    for(int i = 0; i<IDELEMS(I)-1; i++)
+    {
+        if(DegMon(I->m[i])>DegMon(I->m[i+1]))
+        {
+            idPrint(I);
+            Werror("Ideal is not deg sorted!!");
+            return(FALSE);
+        }
+    }
+    return(TRUE);
+}
+
+//adds the new polynomial at the coresponding position
+//and simplifies the ideal
+static ideal SortByDeg_p(ideal I, poly p)
+{
+    int i,j;
+    if((I == NULL) || (idIs0(I)))
+    {
+        ideal res = idInit(1,1);
+        res->m[0] = p;
+        return(res);
+    }
+    idSkipZeroes(I);
+    #if 1
+    for(i = 0; (i<IDELEMS(I)) && (DegMon(I->m[i])<=DegMon(p)); i++)
+    {
+        if(p_DivisibleBy( I->m[i],p, currRing))
+        {
+            return(I);
+        }
+    }
+    for(i = IDELEMS(I)-1; (i>=0) && (DegMon(I->m[i])>=DegMon(p)); i--)
+    {
+        if(p_DivisibleBy(p,I->m[i], currRing))
+        {
+            I->m[i] = NULL;
+        }
+    }
+    if(idIs0(I))
+    {
+        idSkipZeroes(I);
+        I->m[0] = p;
+        return(I);
+    }
+    #endif
+    idSkipZeroes(I);
+    //First I take the case when all generators have the same degree
+    if(DegMon(I->m[0]) == DegMon(I->m[IDELEMS(I)-1]))
+    {
+        if(DegMon(p)<DegMon(I->m[0]))
+        {
+            idInsertPoly(I,p);
+            idSkipZeroes(I);
+            for(i=IDELEMS(I)-1;i>=1; i--)
+            {
+                I->m[i] = I->m[i-1];
+            }
+            I->m[0] = p;
+            return(I);
+        }
+        if(DegMon(p)>=DegMon(I->m[IDELEMS(I)-1]))
+        {
+            idInsertPoly(I,p);
+            idSkipZeroes(I);
+            return(I);
+        }
+    }
+    if(DegMon(p)<=DegMon(I->m[0]))
+    {
+        idInsertPoly(I,p);
+        idSkipZeroes(I);
+        for(i=IDELEMS(I)-1;i>=1; i--)
+        {
+            I->m[i] = I->m[i-1];
+        }
+        I->m[0] = p;
+        return(I);
+    }
+    if(DegMon(p)>=DegMon(I->m[IDELEMS(I)-1]))
+    {
+        idInsertPoly(I,p);
+        idSkipZeroes(I);
+        return(I);
+    }
+    for(i = IDELEMS(I)-2; ;)
+    {
+        if(DegMon(p)==DegMon(I->m[i]))
+        {
+            idInsertPoly(I,p);
+            idSkipZeroes(I);
+            for(j = IDELEMS(I)-1; j>=i+1;j--)
+            {
+                I->m[j] = I->m[j-1];
+            }
+            I->m[i] = p;
+            return(I);
+        }
+        if(DegMon(p)>DegMon(I->m[i]))
+        {
+            idInsertPoly(I,p);
+            idSkipZeroes(I);
+            for(j = IDELEMS(I)-1; j>=i+2;j--)
+            {
+                I->m[j] = I->m[j-1];
+            }
+            I->m[i+1] = p;
+            return(I);
+        }
+        i--;
+    }
+}
+
+//it sorts the ideal by the degrees
+static ideal SortByDeg(ideal I)
+{
+    if(idIs0(I))
+    {
+        return(I);
+    }
+    idSkipZeroes(I);
+    int i;
+    ideal res;
+    idSkipZeroes(I);
+    res = idInit(1,1);
+    res->m[0] = poly(0);
+    for(i = 0; i<=IDELEMS(I)-1;i++)
+    {
+        res = SortByDeg_p(res, I->m[i]);
+    }
+    idSkipZeroes(res);
+    //idDegSortTest(res);
+    return(res);
+}
+
+//idQuot(I,p) for I monomial ideal, p a ideal with a single monomial.
+ideal idQuotMon(ideal Iorig, ideal p)
+{
+    if(idIs0(Iorig))
+    {
+        ideal res = idInit(1,1);
+        res->m[0] = poly(0);
+        return(res);
+    }
+    if(idIs0(p))
+    {
+        ideal res = idInit(1,1);
+        res->m[0] = pOne();
+        return(res);
+    }
+    ideal I = idCopy(Iorig);
+    ideal res = idInit(IDELEMS(I),1);
+    int i,j;
+    int dummy;
+    for(i = 0; i<IDELEMS(I); i++)
+    {
+        res->m[i] = p_Copy(I->m[i], currRing);
+        for(j = 1; (j<=currRing->N) ; j++)
+        {
+            dummy = p_GetExp(p->m[0], j, currRing);
+            if(dummy > 0)
+            {
+                if(p_GetExp(I->m[i], j, currRing) < dummy)
+                {
+                    p_SetExp(res->m[i], j, 0, currRing);
+                }
+                else
+                {
+                    p_SetExp(res->m[i], j, p_GetExp(I->m[i], j, currRing) - dummy, currRing);
+                }
+            }
+        }
+        p_Setm(res->m[i], currRing);
+        if(DegMon(res->m[i]) == DegMon(I->m[i]))
+        {
+            res->m[i] = NULL;
+        }
+        else
+        {
+            I->m[i] = NULL;
+        }
+    }
+    idSkipZeroes(res);
+    idSkipZeroes(I);
+    if(!idIs0(res))
+    {
+    for(i = 0; i<=IDELEMS(res)-1; i++)
+    {
+        I = SortByDeg_p(I,res->m[i]);
+    }
+    }
+    //idDegSortTest(I);
+    return(I);
+}
+
+//id_Add for monomials
+static ideal idAddMon(ideal I, ideal p)
+{
+    #if 1
+    I = SortByDeg_p(I,p->m[0]);
+    #else
+    I = id_Add(I,p,currRing);
+    #endif
+    //idSkipZeroes(I);
+    return(I);
+}
+
+//searches for a variable that is not yet used (assumes that the ideal is sqrfree)
+static poly ChoosePVar (ideal I)
+{
+    bool flag=TRUE;
+    int i,j;
+    poly res;
+    for(i=1;i<=currRing->N;i++)
+    {
+        flag=TRUE;
+        for(j=IDELEMS(I)-1;(j>=0)&&(flag);j--)
+        {
+            if(p_GetExp(I->m[j], i, currRing)>0)
+            {
+                flag=FALSE;
+            }
+        }
+
+        if(flag == TRUE)
+        {
+            res = p_ISet(1, currRing);
+            p_SetExp(res, i, 1, currRing);
+            p_Setm(res,currRing);
+            return(res);
+        }
+        else
+        {
+            p_Delete(&res, currRing);
+        }
+    }
+    return(NULL); //i.e. it is the maximal ideal
+}
+
+//choice XL: last entry divided by x (xy10z15 -> y9z14)
+static poly ChoosePXL(ideal I)
+{
+    int i,j,dummy=0;
+    poly m;
+    for(i = IDELEMS(I)-1; (i>=0) && (dummy == 0); i--)
+    {
+        for(j = 1; (j<=currRing->N) && (dummy == 0); j++)
+        {
+            if(p_GetExp(I->m[i],j, currRing)>1)
+            {
+                dummy = 1;
+            }
+        }
+    }
+    m = p_Copy(I->m[i+1],currRing);
+    for(j = 1; j<=currRing->N; j++)
+    {
+        dummy = p_GetExp(m,j,currRing);
+        if(dummy >= 1)
+        {
+            p_SetExp(m, j, dummy-1, currRing);
+        }
+    }
+    if(!p_IsOne(m, currRing))
+    {
+        p_Setm(m, currRing);
+        return(m);
+    }
+    m = ChoosePVar(I);
+    return(m);
+}
+
+//choice XF: first entry divided by x (xy10z15 -> y9z14)
+static poly ChoosePXF(ideal I)
+{
+    int i,j,dummy=0;
+    poly m;
+    for(i =0 ; (i<=IDELEMS(I)-1) && (dummy == 0); i++)
+    {
+        for(j = 1; (j<=currRing->N) && (dummy == 0); j++)
+        {
+            if(p_GetExp(I->m[i],j, currRing)>1)
+            {
+                dummy = 1;
+            }
+        }
+    }
+    m = p_Copy(I->m[i-1],currRing);
+    for(j = 1; j<=currRing->N; j++)
+    {
+        dummy = p_GetExp(m,j,currRing);
+        if(dummy >= 1)
+        {
+            p_SetExp(m, j, dummy-1, currRing);
+        }
+    }
+    if(!p_IsOne(m, currRing))
+    {
+        p_Setm(m, currRing);
+        return(m);
+    }
+    m = ChoosePVar(I);
+    return(m);
+}
+
+//choice OL: last entry the first power (xy10z15 -> xy9z15)
+static poly ChoosePOL(ideal I)
+{
+    int i,j,dummy;
+    poly m;
+    for(i = IDELEMS(I)-1;i>=0;i--)
+    {
+        m = p_Copy(I->m[i],currRing);
+        for(j=1;j<=currRing->N;j++)
+        {
+            dummy = p_GetExp(m,j,currRing);
+            if(dummy > 0)
+            {
+                p_SetExp(m,j,dummy-1,currRing);
+                p_Setm(m,currRing);
+            }
+        }
+        if(!p_IsOne(m, currRing))
+        {
+            return(m);
+        }
+        else
+        {
+            p_Delete(&m,currRing);
+        }
+    }
+    m = ChoosePVar(I);
+    return(m);
+}
+
+//choice OF: first entry the first power (xy10z15 -> xy9z15)
+static poly ChoosePOF(ideal I)
+{
+    int i,j,dummy;
+    poly m;
+    for(i = 0 ;i<=IDELEMS(I)-1;i++)
+    {
+        m = p_Copy(I->m[i],currRing);
+        for(j=1;j<=currRing->N;j++)
+        {
+            dummy = p_GetExp(m,j,currRing);
+            if(dummy > 0)
+            {
+                p_SetExp(m,j,dummy-1,currRing);
+                p_Setm(m,currRing);
+            }
+        }
+        if(!p_IsOne(m, currRing))
+        {
+            return(m);
+        }
+        else
+        {
+            p_Delete(&m,currRing);
+        }
+    }
+    m = ChoosePVar(I);
+    return(m);
+}
+
+//choice VL: last entry the first variable with power (xy10z15 -> y)
+static poly ChoosePVL(ideal I)
+{
+    int i,j,dummy;
+    bool flag = TRUE;
+    poly m = p_ISet(1,currRing);
+    for(i = IDELEMS(I)-1;(i>=0) && (flag);i--)
+    {
+        flag = TRUE;
+        for(j=1;(j<=currRing->N) && (flag);j++)
+        {
+            dummy = p_GetExp(I->m[i],j,currRing);
+            if(dummy >= 2)
+            {
+                p_SetExp(m,j,1,currRing);
+                p_Setm(m,currRing);
+                flag = FALSE;
+            }
+        }
+        if(!p_IsOne(m, currRing))
+        {
+            return(m);
+        }
+    }
+    m = ChoosePVar(I);
+    return(m);
+}
+
+//choice VF: first entry the first variable with power (xy10z15 -> y)
+static poly ChoosePVF(ideal I)
+{
+    int i,j,dummy;
+    bool flag = TRUE;
+    poly m = p_ISet(1,currRing);
+    for(i = 0;(i<=IDELEMS(I)-1) && (flag);i++)
+    {
+        flag = TRUE;
+        for(j=1;(j<=currRing->N) && (flag);j++)
+        {
+            dummy = p_GetExp(I->m[i],j,currRing);
+            if(dummy >= 2)
+            {
+                p_SetExp(m,j,1,currRing);
+                p_Setm(m,currRing);
+                flag = FALSE;
+            }
+        }
+        if(!p_IsOne(m, currRing))
+        {
+            return(m);
+        }
+    }
+    m = ChoosePVar(I);
+    return(m);
+}
+
+//choice JL: last entry just variable with power (xy10z15 -> y10)
+static poly ChoosePJL(ideal I)
+{
+    int i,j,dummy;
+    bool flag = TRUE;
+    poly m = p_ISet(1,currRing);
+    for(i = IDELEMS(I)-1;(i>=0) && (flag);i--)
+    {
+        flag = TRUE;
+        for(j=1;(j<=currRing->N) && (flag);j++)
+        {
+            dummy = p_GetExp(I->m[i],j,currRing);
+            if(dummy >= 2)
+            {
+                p_SetExp(m,j,dummy-1,currRing);
+                p_Setm(m,currRing);
+                flag = FALSE;
+            }
+        }
+        if(!p_IsOne(m, currRing))
+        {
+            return(m);
+        }
+    }
+    m = ChoosePVar(I);
+    return(m);
+}
+
+//choice JF: last entry just variable with power -1 (xy10z15 -> y9)
+static poly ChoosePJF(ideal I)
+{
+    int i,j,dummy;
+    bool flag = TRUE;
+    poly m = p_ISet(1,currRing);
+    for(i = 0;(i<=IDELEMS(I)-1) && (flag);i++)
+    {
+        flag = TRUE;
+        for(j=1;(j<=currRing->N) && (flag);j++)
+        {
+            dummy = p_GetExp(I->m[i],j,currRing);
+            if(dummy >= 2)
+            {
+                p_SetExp(m,j,dummy-1,currRing);
+                p_Setm(m,currRing);
+                flag = FALSE;
+            }
+        }
+        if(!p_IsOne(m, currRing))
+        {
+            return(m);
+        }
+    }
+    m = ChoosePVar(I);
+    return(m);
+}
+
+//chooses 1 \neq p \not\in S. This choice should be made optimal
+static poly ChooseP(ideal I)
+{
+    poly m;
+    //  TEST TO SEE WHICH ONE IS BETTER
+    //m = ChoosePXL(I);
+    //m = ChoosePXF(I);
+    //m = ChoosePOL(I);
+    //m = ChoosePOF(I);
+    //m = ChoosePVL(I);
+    //m = ChoosePVF(I);
+    m = ChoosePJL(I);
+    //m = ChoosePJF(I);
+    return(m);
+}
+
+///searches for a monomial of degree d>=2 and divides it by a variable (result monomial of deg d-1)
+static poly SearchP(ideal I)
+{
+    int i,j,exp;
+    poly res;
+    if(DegMon(I->m[IDELEMS(I)-1])<=1)
+    {
+        res = ChoosePVar(I);
+        return(res);
+    }
+    i = IDELEMS(I)-1;
+    res = p_Copy(I->m[i], currRing);
+    for(j=1;j<=currRing->N;j++)
+    {
+        exp = p_GetExp(I->m[i], j, currRing);
+        if(exp > 0)
+        {
+            p_SetExp(res, j, exp - 1, currRing);
+            p_Setm(res,currRing);
+            break;
+        }
+    }
+    assume( j <= currRing->N );
+    return(res);
+}
+
+//test if the ideal is of the form (x1, ..., xr)
+static bool JustVar(ideal I)
+{
+    #if 0
+    int i,j;
+    bool foundone;
+    for(i=0;i<=IDELEMS(I)-1;i++)
+    {
+        foundone = FALSE;
+        for(j = 1;j<=currRing->N;j++)
+        {
+            if(p_GetExp(I->m[i], j, currRing)>0)
+            {
+                if(foundone == TRUE)
+                {
+                    return(FALSE);
+                }
+                foundone = TRUE;
+            }
+        }
+    }
+    return(TRUE);
+    #else
+    if(DegMon(I->m[IDELEMS(I)-1])>1)
+    {
+        return(FALSE);
+    }
+    return(TRUE);
+    #endif
+}
+
+//computes the Euler Characteristic of the ideal
+static void eulerchar (ideal I, int variables, mpz_ptr ec)
+{
+  loop
+  {
+    mpz_t dummy;
+    if(JustVar(I) == TRUE)
+    {
+        if(IDELEMS(I) == variables)
+        {
+            mpz_init(dummy);
+            if((variables % 2) == 0)
+                {mpz_set_si(dummy, 1);}
+            else
+                {mpz_set_si(dummy, -1);}
+            mpz_add(ec, ec, dummy);
+        }
+        //mpz_clear(dummy);
+        return;
+    }
+    ideal p = idInit(1,1);
+    p->m[0] = SearchP(I);
+    //idPrint(I);
+    //idPrint(p);
+    //printf("\nNow get in idQuotMon\n");
+    ideal Ip = idQuotMon(I,p);
+    //idPrint(Ip);
+    //Ip = SortByDeg(Ip);
+    int i,howmanyvarinp = 0;
+    for(i = 1;i<=currRing->N;i++)
+    {
+        if(p_GetExp(p->m[0],i,currRing)>0)
+        {
+            howmanyvarinp++;
+        }
+    }
+    eulerchar(Ip, variables-howmanyvarinp, ec);
+    id_Delete(&Ip, currRing);
+    I = idAddMon(I,p);
+  }
+}
+
+//tests if an ideal is Square Free, if no, returns the variable which appears at powers >1
+static poly SqFree (ideal I)
+{
+    int i,j;
+    bool flag=TRUE;
+    poly notsqrfree = NULL;
+    if(DegMon(I->m[IDELEMS(I)-1])<=1)
+    {
+        return(notsqrfree);
+    }
+    for(i=IDELEMS(I)-1;(i>=0)&&(flag);i--)
+    {
+        for(j=1;(j<=currRing->N)&&(flag);j++)
+        {
+            if(p_GetExp(I->m[i],j,currRing)>1)
+            {
+                flag=FALSE;
+                notsqrfree = p_ISet(1,currRing);
+                p_SetExp(notsqrfree,j,1,currRing);
+            }
+        }
+    }
+    if(notsqrfree != NULL)
+    {
+        p_Setm(notsqrfree,currRing);
+    }
+    return(notsqrfree);
+}
+
+//checks if a polynomial is in I
+static bool IsIn(poly p, ideal I)
+{
+    //assumes that I is ordered by degree
+    if(idIs0(I))
+    {
+        if(p==poly(0))
+        {
+            return(TRUE);
+        }
+        else
+        {
+            return(FALSE);
+        }
+    }
+    if(p==poly(0))
+    {
+        return(FALSE);
+    }
+    int i,j;
+    bool flag;
+    for(i = 0;i<IDELEMS(I);i++)
+    {
+        flag = TRUE;
+        for(j = 1;(j<=currRing->N) &&(flag);j++)
+        {
+            if(p_GetExp(p, j, currRing)<p_GetExp(I->m[i], j, currRing))
+            {
+                flag = FALSE;
+            }
+        }
+        if(flag)
+        {
+            return(TRUE);
+        }
+    }
+    return(FALSE);
+}
+
+//computes the lcm of min I, I monomial ideal
+static poly LCMmon(ideal I)
+{
+    if(idIs0(I))
+    {
+        return(NULL);
+    }
+    poly m;
+    int dummy,i,j;
+    m = p_ISet(1,currRing);
+    for(i=1;i<=currRing->N;i++)
+    {
+        dummy=0;
+        for(j=IDELEMS(I)-1;j>=0;j--)
+        {
+            if(p_GetExp(I->m[j],i,currRing) > dummy)
+            {
+                dummy = p_GetExp(I->m[j],i,currRing);
+            }
+        }
+        p_SetExp(m,i,dummy,currRing);
+    }
+    p_Setm(m,currRing);
+    return(m);
+}
+
+//the Roune Slice Algorithm
+void rouneslice(ideal I, ideal S, poly q, poly x, int &prune, int &moreprune, int &steps, int &NNN, mpz_ptr &hilbertcoef, int* &hilbpower)
+{
+  loop
+  {
+    (steps)++;
+    int i,j;
+    int dummy;
+    poly m;
+    ideal p, koszsimp;
+    //----------- PRUNING OF S ---------------
+    //S SHOULD IN THIS POINT BE ORDERED BY DEGREE
+    for(i=IDELEMS(S)-1;i>=0;i--)
+    {
+        if(IsIn(S->m[i],I))
+        {
+            S->m[i]=NULL;
+            prune++;
+        }
+    }
+    idSkipZeroes(S);
+    //----------------------------------------
+    for(i=IDELEMS(I)-1;i>=0;i--)
+    {
+        m = p_Copy(I->m[i],currRing);
+        for(j=1;j<=currRing->N;j++)
+        {
+            dummy = p_GetExp(m,j,currRing);
+            if(dummy > 0)
+            {
+                p_SetExp(m,j,dummy-1,currRing);
+            }
+        }
+        p_Setm(m, currRing);
+        if(IsIn(m,S))
+        {
+            I->m[i]=NULL;
+            //printf("\n Deleted, since pi(m) is in S\n");pWrite(m);
+        }
+    }
+    idSkipZeroes(I);
+    //----------- MORE PRUNING OF S ------------
+    m = LCMmon(I);
+    if(m != NULL)
+    {
+        for(i=0;i<IDELEMS(S);i++)
+        {
+            if(!(p_DivisibleBy(S->m[i], m, currRing)))
+            {
+                S->m[i] = NULL;
+                j++;
+                moreprune++;
+            }
+            else
+            {
+                if(pLmEqual(S->m[i],m))
+                {
+                    S->m[i] = NULL;
+                    moreprune++;
+                }
+            }
+        }
+    idSkipZeroes(S);
+    }
+    /*printf("\n---------------------------\n");
+    printf("\n      I\n");idPrint(I);
+    printf("\n      S\n");idPrint(S);
+    printf("\n      q\n");pWrite(q);
+    getchar();*/
+
+    if(idIs0(I))
+    {
+        id_Delete(&I, currRing);
+        id_Delete(&S, currRing);
+        p_Delete(&m, currRing);
+        break;
+    }
+    m = LCMmon(I);
+    if(!p_DivisibleBy(x,m, currRing))
+    {
+        //printf("\nx does not divide lcm(I)");
+        //printf("\nEmpty set");pWrite(q);
+        id_Delete(&I, currRing);
+        id_Delete(&S, currRing);
+        p_Delete(&m, currRing);
+        break;
+    }
+    m = SqFree(I);
+    if(m==NULL)
+    {
+        //printf("\n      Corner: ");
+        //pWrite(q);
+        //printf("\n      With the facets of the dual simplex:\n");
+        //idPrint(I);
+        mpz_t ec;
+        mpz_init(ec);
+        mpz_ptr ec_ptr = ec;
+        eulerchar(I, currRing->N, ec_ptr);
+        bool flag = FALSE;
+        if(NNN==0)
+            {
+                hilbertcoef = (mpz_ptr)omAlloc((NNN+1)*sizeof(mpz_t));
+                hilbpower = (int*)omAlloc((NNN+1)*sizeof(int));
+                mpz_init( &hilbertcoef[NNN]);
+                mpz_set(  &hilbertcoef[NNN], ec);
+                mpz_clear(ec);
+                hilbpower[NNN] = DegMon(q);
+                NNN++;
+            }
+        else
+        {
+            //I look if the power appears already
+            for(i = 0;(i<NNN)&&(flag == FALSE)&&(DegMon(q)>=hilbpower[i]);i++)
+            {
+                if((hilbpower[i]) == (DegMon(q)))
+                {
+                    flag = TRUE;
+                    mpz_add(&hilbertcoef[i],&hilbertcoef[i],ec_ptr);
+                }
+            }
+            if(flag == FALSE)
+            {
+                hilbertcoef = (mpz_ptr)omRealloc(hilbertcoef, (NNN+1)*sizeof(mpz_t));
+                hilbpower = (int*)omRealloc(hilbpower, (NNN+1)*sizeof(int));
+                mpz_init(&hilbertcoef[NNN]);
+                for(j = NNN; j>i; j--)
+                {
+                    mpz_set(&hilbertcoef[j],&hilbertcoef[j-1]);
+                    hilbpower[j] = hilbpower[j-1];
+                }
+                mpz_set(  &hilbertcoef[i], ec);
+                mpz_clear(ec);
+                hilbpower[i] = DegMon(q);
+                NNN++;
+            }
+        }
+        break;
+    }
+    m = ChooseP(I);
+    p = idInit(1,1);
+    p->m[0] = m;
+    ideal Ip = idQuotMon(I,p);
+    ideal Sp = idQuotMon(S,p);
+    poly pq = pp_Mult_mm(q,m,currRing);
+    rouneslice(Ip, Sp, pq, x, prune, moreprune, steps, NNN, hilbertcoef,hilbpower);
+    //id_Delete(&Ip, currRing);
+    //id_Delete(&Sp, currRing);
+    S = idAddMon(S,p);
+    p->m[0]=NULL;
+    id_Delete(&p, currRing); // p->m[0] was also in S
+    p_Delete(&pq,currRing);
+  }
+}
+
+//it computes the first hilbert series by means of Roune Slice Algorithm
+void slicehilb(ideal I)
+{
+    //printf("Adi changes are here: \n");
+    int i, NNN = 0;
+    int steps = 0, prune = 0, moreprune = 0;
+    mpz_ptr hilbertcoef;
+    int *hilbpower;
+    ideal S = idInit(1,1);
+    poly q = p_ISet(1,currRing);
+    ideal X = idInit(1,1);
+    X->m[0]=p_One(currRing);
+    for(i=1;i<=currRing->N;i++)
+    {
+            p_SetExp(X->m[0],i,1,currRing);
+    }
+    p_Setm(X->m[0],currRing);
+    I = id_Mult(I,X,currRing);
+    I = SortByDeg(I);
+    //printf("\n-------------RouneSlice--------------\n");
+    rouneslice(I,S,q,X->m[0],prune, moreprune, steps, NNN, hilbertcoef, hilbpower);
+    //printf("\nIn total Prune got rid of %i elements\n",prune);
+    //printf("\nIn total More Prune got rid of %i elements\n",moreprune);
+    //printf("\nSteps of rouneslice: %i\n\n", steps);
+    mpz_t coefhilb;
+    mpz_t dummy;
+    mpz_init(coefhilb);
+    mpz_init(dummy);
+    printf("\n//  %8d t^0",1);
+    for(i = 0; i<NNN; i++)
+    {
+        if(mpz_sgn(&hilbertcoef[i])!=0)
+        {
+            gmp_printf("\n//  %8Zd t^%d",&hilbertcoef[i],hilbpower[i]);
+        }
+    }
+    omFreeSize(hilbertcoef, (NNN)*sizeof(mpz_t));
+    omFreeSize(hilbpower, (NNN)*sizeof(int));
+    //printf("\n-------------------------------------\n");
+}
+
+// -------------------------------- END OF CHANGES -------------------------------------------
+static intvec * hSeries(ideal S, intvec *modulweight,
+                int /*notstc*/, intvec *wdegree, ideal Q, ring tailRing)
+{
+//  id_TestTail(S, currRing, tailRing);
+
+  intvec *work, *hseries1=NULL;
+  int  mc;
+  int  p0;
+  int  i, j, k, l, ii, mw;
+  hexist = hInit(S, Q, &hNexist, tailRing);
+  if (hNexist==0)
+  {
+    hseries1=new intvec(2);
+    (*hseries1)[0]=1;
+    (*hseries1)[1]=0;
+    return hseries1;
+  }
+
+  #if 0
+  if (wdegree == NULL)
+    hWeight();
+  else
+    hWDegree(wdegree);
+  #else
+  if (wdegree != NULL) hWDegree(wdegree);
+  #endif
+
+  p0 = 1;
+  hwork = (scfmon)omAlloc(hNexist * sizeof(scmon));
+  hvar = (varset)omAlloc(((currRing->N) + 1) * sizeof(int));
+  hpure = (scmon)omAlloc((1 + ((currRing->N) * (currRing->N))) * sizeof(int));
+  stcmem = hCreate((currRing->N) - 1);
+  Qpol = (int **)omAlloc(((currRing->N) + 1) * sizeof(int *));
+  Ql = (int *)omAlloc0(((currRing->N) + 1) * sizeof(int));
+  Q0 = (int *)omAlloc(((currRing->N) + 1) * sizeof(int));
+  *Qpol = NULL;
+  hLength = k = j = 0;
+  mc = hisModule;
+  if (mc!=0)
+  {
+    mw = hMinModulweight(modulweight);
+    hstc = (scfmon)omAlloc(hNexist * sizeof(scmon));
+  }
+  else
+  {
+    mw = 0;
+    hstc = hexist;
+    hNstc = hNexist;
+  }
+  loop
+  {
+    if (mc!=0)
+    {
+      hComp(hexist, hNexist, mc, hstc, &hNstc);
+      if (modulweight != NULL)
+        j = (*modulweight)[mc-1]-mw;
+    }
+    if (hNstc!=0)
+    {
+      hNvar = (currRing->N);
+      for (i = hNvar; i>=0; i--)
+        hvar[i] = i;
+      //if (notstc) // TODO: no mon divides another
+        hStaircase(hstc, &hNstc, hvar, hNvar);
+      hSupp(hstc, hNstc, hvar, &hNvar);
+      if (hNvar!=0)
+      {
+        if ((hNvar > 2) && (hNstc > 10))
+          hOrdSupp(hstc, hNstc, hvar, hNvar);
+        hHilbEst(hstc, hNstc, hvar, hNvar);
+        memset(hpure, 0, ((currRing->N) + 1) * sizeof(int));
+        hPure(hstc, 0, &hNstc, hvar, hNvar, hpure, &hNpure);
+        hLexS(hstc, hNstc, hvar, hNvar);
+        Q0[hNvar] = 0;
+        hHilbStep(hpure, hstc, hNstc, hvar, hNvar, &p0, 1);
+      }
+    }
+    else
+    {
+      if(*Qpol!=NULL)
+        (**Qpol)++;
+      else
+      {
+        *Qpol = (int *)omAlloc(sizeof(int));
+        hLength = *Ql = **Qpol = 1;
+      }
+    }
+    if (*Qpol!=NULL)
+    {
+      i = hLength;
+      while ((i > 0) && ((*Qpol)[i - 1] == 0))
+        i--;
+      if (i > 0)
+      {
+        l = i + j;
+        if (l > k)
+        {
+          work = new intvec(l);
+          for (ii=0; ii<k; ii++)
+            (*work)[ii] = (*hseries1)[ii];
+          if (hseries1 != NULL)
+            delete hseries1;
+          hseries1 = work;
+          k = l;
+        }
+        while (i > 0)
+        {
+          (*hseries1)[i + j - 1] += (*Qpol)[i - 1];
+          (*Qpol)[i - 1] = 0;
+          i--;
+        }
+      }
+    }
+    mc--;
+    if (mc <= 0)
+      break;
+  }
+  if (k==0)
+  {
+    hseries1=new intvec(2);
+    (*hseries1)[0]=0;
+    (*hseries1)[1]=0;
+  }
+  else
+  {
+    l = k+1;
+    while ((*hseries1)[l-2]==0) l--;
+    if (l!=k)
+    {
+      work = new intvec(l);
+      for (ii=l-2; ii>=0; ii--)
+        (*work)[ii] = (*hseries1)[ii];
+      delete hseries1;
+      hseries1 = work;
+    }
+    (*hseries1)[l-1] = mw;
+  }
+  for (i = 0; i <= (currRing->N); i++)
+  {
+    if (Ql[i]!=0)
+      omFreeSize((ADDRESS)Qpol[i], Ql[i] * sizeof(int));
+  }
+  omFreeSize((ADDRESS)Q0, ((currRing->N) + 1) * sizeof(int));
+  omFreeSize((ADDRESS)Ql, ((currRing->N) + 1) * sizeof(int));
+  omFreeSize((ADDRESS)Qpol, ((currRing->N) + 1) * sizeof(int *));
+  hKill(stcmem, (currRing->N) - 1);
+  omFreeSize((ADDRESS)hpure, (1 + ((currRing->N) * (currRing->N))) * sizeof(int));
+  omFreeSize((ADDRESS)hvar, ((currRing->N) + 1) * sizeof(int));
+  omFreeSize((ADDRESS)hwork, hNexist * sizeof(scmon));
+  hDelete(hexist, hNexist);
+  if (hisModule!=0)
+    omFreeSize((ADDRESS)hstc, hNexist * sizeof(scmon));
+  return hseries1;
+}
+
+
+intvec * hHstdSeries(ideal S, intvec *modulweight, intvec *wdegree, ideal Q, ring tailRing)
+{
+  id_TestTail(S, currRing, tailRing);
+  id_TestTail(Q, currRing, tailRing);
+  return hSeries(S, modulweight, 0, wdegree, Q, tailRing);
+}
+
+intvec * hFirstSeries(ideal S, intvec *modulweight, ideal Q, intvec *wdegree, ring tailRing)
+{
+  id_TestTail(S, currRing, tailRing);
+  id_TestTail(Q, currRing, tailRing);
+  return hSeries(S, modulweight, 1, wdegree, Q, tailRing);
+}
+
+intvec * hSecondSeries(intvec *hseries1)
+{
+  intvec *work, *hseries2;
+  int i, j, k, s, t, l;
+  if (hseries1 == NULL)
+    return NULL;
+  work = new intvec(hseries1);
+  k = l = work->length()-1;
+  s = 0;
+  for (i = k-1; i >= 0; i--)
+    s += (*work)[i];
+  loop
+  {
+    if ((s != 0) || (k == 1))
+      break;
+    s = 0;
+    t = (*work)[k-1];
+    k--;
+    for (i = k-1; i >= 0; i--)
+    {
+      j = (*work)[i];
+      (*work)[i] = -t;
+      s += t;
+      t += j;
+    }
+  }
+  hseries2 = new intvec(k+1);
+  for (i = k-1; i >= 0; i--)
+    (*hseries2)[i] = (*work)[i];
+  (*hseries2)[k] = (*work)[l];
+  delete work;
+  return hseries2;
+}
+
+void hDegreeSeries(intvec *s1, intvec *s2, int *co, int *mu)
+{
+  int m, i, j, k;
+  *co = *mu = 0;
+  if ((s1 == NULL) || (s2 == NULL))
+    return;
+  i = s1->length();
+  j = s2->length();
+  if (j > i)
+    return;
+  m = 0;
+  for(k=j-2; k>=0; k--)
+    m += (*s2)[k];
+  *mu = m;
+  *co = i - j;
+}
+
+static void hPrintHilb(intvec *hseries)
+{
+  int  i, j, l, k;
+  if (hseries == NULL)
+    return;
+  l = hseries->length()-1;
+  k = (*hseries)[l];
+  for (i = 0; i < l; i++)
+  {
+    j = (*hseries)[i];
+    if (j != 0)
+    {
+      Print("//  %8d t^%d\n", j, i+k);
+    }
+  }
+}
+
+/*
+*caller
+*/
+void hLookSeries(ideal S, intvec *modulweight, ideal Q, intvec *wdegree, ring tailRing)
+{
+  id_TestTail(S, currRing, tailRing);
+
+  intvec *hseries1 = hFirstSeries(S, modulweight, Q, wdegree, tailRing);
+
+  hPrintHilb(hseries1);
+
+  const int l = hseries1->length()-1;
+
+  intvec *hseries2 = (l > 1) ? hSecondSeries(hseries1) : hseries1;
+
+  int co, mu;
+  hDegreeSeries(hseries1, hseries2, &co, &mu);
+
+  PrintLn();
+  hPrintHilb(hseries2);
+  if ((l == 1) &&(mu == 0))
+    scPrintDegree(rVar(currRing)+1, 0);
+  else
+    scPrintDegree(co, mu);
+  if (l>1)
+    delete hseries1;
+  delete hseries2;
+}
+
+
+
diff --git a/kernel/combinatorics/hilb.h b/kernel/combinatorics/hilb.h
new file mode 100644
index 0000000..bb9de80
--- /dev/null
+++ b/kernel/combinatorics/hilb.h
@@ -0,0 +1,27 @@
+#ifndef HILB_H
+#define HILB_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT
+*/
+
+struct spolyrec  ; typedef struct spolyrec polyrec; typedef polyrec * poly;
+struct ip_sring  ; typedef struct ip_sring                          * ring;
+struct sip_sideal; typedef struct sip_sideal                        * ideal;
+
+class intvec;
+
+extern ring currRing;
+
+intvec * hHstdSeries(ideal S, intvec *modulweight, intvec *wdegree, ideal Q=NULL, ring tailRing = currRing);
+intvec * hFirstSeries(ideal S, intvec *modulweight, ideal Q=NULL, intvec *wdegree=NULL, ring tailRing = currRing);
+
+intvec * hSecondSeries(intvec *hseries1);
+
+void hLookSeries(ideal S, intvec *modulweight, ideal Q=NULL, intvec *wdegree=NULL, ring tailRing = currRing);
+
+#endif
+
+
diff --git a/kernel/combinatorics/hutil.cc b/kernel/combinatorics/hutil.cc
new file mode 100644
index 0000000..fcb00fd
--- /dev/null
+++ b/kernel/combinatorics/hutil.cc
@@ -0,0 +1,1068 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: Utilities for staircase operations
+*/
+
+#include <kernel/mod2.h>
+// #include <kernel/structs.h>
+#include <omalloc/omalloc.h>
+
+#include <polys/simpleideals.h>
+#include <polys/monomials/p_polys.h>
+
+// #include <kernel/ideals.h>
+// #include <kernel/polys.h>
+#include <kernel/combinatorics/hutil.h>
+
+scfmon hexist, hstc, hrad, hwork;
+scmon hpure, hpur0;
+varset hvar, hsel;
+int  hNexist, hNstc, hNrad, hNvar, hNpure;
+int hisModule;
+monf stcmem, radmem;
+
+// Making a global "security" copy of the allocated exponent vectors
+// is a dirty fix for correct memory disallocation: It would be
+// better, if either the fields of heist are never touched
+// (i.e. changed) except in hInit, or, if hInit would return the
+// "security" copy as well. But then, all the relevant data is held in
+// global variables, so we might do that here, as well.
+static scfmon hsecure= NULL;
+
+scfmon hInit(ideal S, ideal Q, int *Nexist, ring tailRing)
+{
+  id_TestTail(S, currRing, tailRing);
+  id_TestTail(Q, currRing, tailRing);
+
+//   if (tailRing != currRing)
+    hisModule = id_RankFreeModule(S, currRing, tailRing);
+//  else
+//    hisModule = id_RankFreeModule(S, currRing);
+
+  if (hisModule < 0)
+    hisModule = 0;
+
+  int  sl, ql, i, k = 0;
+  polyset si, qi, ss;
+  scfmon ex, ek;
+
+  if (S!=NULL)
+  {
+    si = S->m;
+    sl = IDELEMS(S);
+  }
+  else
+  {
+    si = NULL;
+    sl = 0;
+  }
+  if (Q!=NULL)
+  {
+    qi = Q->m;
+    ql = IDELEMS(Q);
+  }
+  else
+  {
+    qi = NULL;
+    ql = 0;
+  }
+  if ((sl + ql) == 0)
+  {
+    *Nexist = 0;
+    return NULL;
+  }
+  ss = si;
+  for (i = sl; i>0; i--)
+  {
+    if (*ss!=0)
+      k++;
+    ss++;
+  }
+  ss = qi;
+  for (i = ql; i>0; i--)
+  {
+    if (*ss!=0)
+      k++;
+    ss++;
+  }
+  *Nexist = k;
+  if (k==0)
+    return NULL;
+  ek = ex = (scfmon)omAlloc0(k * sizeof(scmon));
+  hsecure = (scfmon) omAlloc0(k * sizeof(scmon));
+  for (i = sl; i>0; i--)
+  {
+    if (*si!=NULL)
+    {
+      *ek = (scmon) omAlloc(((currRing->N)+1)*sizeof(int));
+      p_GetExpV(*si, *ek, currRing);
+      ek++;
+    }
+    si++;
+  }
+  for (i = ql; i>0; i--)
+  {
+    if (*qi!=NULL)
+    {
+      *ek = (scmon) omAlloc(((currRing->N)+1)*sizeof(int));
+      p_GetExpV(*qi, *ek, currRing);
+      ek++;
+    }
+    qi++;
+  }
+  memcpy(hsecure, ex, k * sizeof(scmon));
+  return ex;
+}
+
+#if 0
+void hWeight()
+{
+  int i, k;
+  int x;
+
+  i = (currRing->N);
+  loop
+  {
+    if (pWeight(i) != 1) break;
+    i--;
+    if (i == 0) return;
+  }
+  for (i=(currRing->N); i>0; i--)
+  {
+    x = pWeight(i);
+    if (x != 1)
+    {
+      for (k=hNexist-1; k>=0; k--)
+      {
+        hexist[k][i] *= x;
+      }
+    }
+  }
+}
+#endif
+
+void hDelete(scfmon ev, int ev_length)
+{
+  int i;
+
+  if (ev_length>0)
+  {
+    for (i=ev_length-1;i>=0;i--)
+      omFreeSize(hsecure[i],((currRing->N)+1)*sizeof(int));
+    omFreeSize(hsecure, ev_length*sizeof(scmon));
+    omFreeSize(ev,  ev_length*sizeof(scmon));
+  }
+}
+
+
+void hComp(scfmon exist, int Nexist, int ak, scfmon stc, int *Nstc)
+{
+  int k = 0;
+  scfmon ex = exist, co = stc;
+  int i;
+
+  for (i = Nexist; i>0; i--)
+  {
+    if (((**ex) == 0) || ((**ex) == ak))
+    {
+      *co = *ex;
+      co++;
+      k++;
+    }
+    ex++;
+  }
+  *Nstc = k;
+}
+
+
+void hSupp(scfmon stc, int Nstc, varset var, int *Nvar)
+{
+  int  nv, i0, i1, i, j;
+  nv = i0 = *Nvar;
+  i1 = 0;
+  for (i = 1; i <= nv; i++)
+  {
+    j = 0;
+    loop
+    {
+      if (stc[j][i]>0)
+      {
+        i1++;
+        var[i1] = i;
+        break;
+      }
+      j++;
+      if (j == Nstc)
+      {
+        var[i0] = i;
+        i0--;
+        break;
+      }
+    }
+  }
+  *Nvar = i1;
+}
+
+void hOrdSupp(scfmon stc, int Nstc, varset var, int Nvar)
+{
+  int  i, i1, j, jj, k, l;
+  int  x;
+  scmon temp, count;
+  float o, h, g, *v1;
+
+  v1 = (float *)omAlloc(Nvar * sizeof(float));
+  temp = (int *)omAlloc(Nstc * sizeof(int));
+  count = (int *)omAlloc(Nstc * sizeof(int));
+  for (i = 1; i <= Nvar; i++)
+  {
+    i1 = var[i];
+    *temp = stc[0][i1];
+    *count = 1;
+    jj = 1;
+    for (j = 1; j < Nstc; j++)
+    {
+      x = stc[j][i1];
+      k = 0;
+      loop
+      {
+        if (x > temp[k])
+        {
+          k++;
+          if (k == jj)
+          {
+            temp[k] = x;
+            count[k] = 1;
+            jj++;
+            break;
+          }
+        }
+        else if (x < temp[k])
+        {
+          for (l = jj; l > k; l--)
+          {
+            temp[l] = temp[l-1];
+            count[l] = count[l-1];
+          }
+          temp[k] = x;
+          count[k] = 1;
+          jj++;
+          break;
+        }
+        else
+        {
+          count[k]++;
+          break;
+        }
+      }
+    }
+    h = 0.0;
+    o = (float)Nstc/(float)jj;
+    for(j = 0; j < jj; j++)
+    {
+       g = (float)count[j];
+       if (g > o)
+         g -= o;
+       else
+         g = o - g;
+       if (g > h)
+         h = g;
+    }
+    v1[i-1] = h * (float)jj;
+  }
+  omFreeSize((ADDRESS)count, Nstc * sizeof(int));
+  omFreeSize((ADDRESS)temp, Nstc * sizeof(int));
+  for (i = 1; i < Nvar; i++)
+  {
+    i1 = var[i+1];
+    h = v1[i];
+    j = 0;
+    loop
+    {
+      if (h > v1[j])
+      {
+        for (l = i; l > j; l--)
+        {
+          v1[l] = v1[l-1];
+          var[l+1] = var[l];
+        }
+        v1[j] = h;
+        var[j+1] = i1;
+        break;
+      }
+      j++;
+      if (j == i)
+        break;
+    }
+  }
+  omFreeSize((ADDRESS)v1, Nvar * sizeof(float));
+}
+
+
+static void hShrink(scfmon co, int a, int Nco)
+{
+  while ((co[a]!=NULL) && (a<Nco)) a++;
+  int i = a;
+  int j;
+  for (j = a; j < Nco; j++)
+  {
+    if (co[j]!=NULL)
+    {
+      co[i] = co[j];
+      i++;
+    }
+  }
+}
+
+
+void hStaircase(scfmon stc, int *Nstc, varset var, int Nvar)
+{
+  int  nc = *Nstc;
+  if (nc < 2)
+    return;
+  int z = 0;
+  int i = 0;
+  int j = 1;
+  scmon n = stc[1 /*j*/];
+  scmon o = stc[0];
+  int k = Nvar;
+  loop
+  {
+    int k1 = var[k];
+    if (o[k1] > n[k1])
+    {
+      loop
+      {
+        k--;
+        if (k==0)
+        {
+          stc[i] = NULL;
+          z++;
+          break;
+        }
+        else
+        {
+          k1 = var[k];
+          if (o[k1] < n[k1])
+            break;
+        }
+      }
+      k = Nvar;
+    }
+    else if (o[k1] < n[k1])
+    {
+      loop
+      {
+        k--;
+        if (k==0)
+        {
+          stc[j] = NULL;
+          z++;
+          break;
+        }
+        else
+        {
+          k1 = var[k];
+          if (o[k1] > n[k1])
+            break;
+        }
+      }
+      k = Nvar;
+    }
+    else
+    {
+      k--;
+      if (k==0)
+      {
+        stc[j] = NULL;
+        z++;
+        k = Nvar;
+      }
+    }
+    if (k == Nvar)
+    {
+      if (stc[j]==NULL)
+        i = j - 1;
+      loop
+      {
+        i++;
+        if (i == j)
+        {
+          i = -1;
+          j++;
+          if (j < nc)
+            n = stc[j];
+          else
+          {
+            if (z!=0)
+            {
+              *Nstc -= z;
+              hShrink(stc, 0, nc);
+            }
+            return;
+          }
+        }
+        else if (stc[i]!=NULL)
+        {
+          o = stc[i];
+          break;
+        }
+      }
+    }
+  }
+}
+
+
+void hRadical(scfmon rad, int *Nrad, int Nvar)
+{
+  int  nc = *Nrad, z = 0, i, j, k;
+  scmon n, o;
+  if (nc < 2)
+    return;
+  i = 0;
+  j = 1;
+  n = rad[j];
+  o = rad[0];
+  k = Nvar;
+  loop
+  {
+    if ((o[k]!=0) && (n[k]==0))
+    {
+      loop
+      {
+        k--;
+        if (k==0)
+        {
+          rad[i] = NULL;
+          z++;
+          break;
+        }
+        else
+        {
+          if ((o[k]==0) && (n[k]!=0))
+            break;
+        }
+      }
+      k = Nvar;
+    }
+    else if (!o[k] && n[k])
+    {
+      loop
+      {
+        k--;
+        if (!k)
+        {
+          rad[j] = NULL;
+          z++;
+          break;
+        }
+        else
+        {
+          if (o[k] && !n[k])
+            break;
+        }
+      }
+      k = Nvar;
+    }
+    else
+    {
+      k--;
+      if (!k)
+      {
+        rad[j] = NULL;
+        z++;
+        k = Nvar;
+      }
+    }
+    if (k == Nvar)
+    {
+      if (!rad[j])
+        i = j - 1;
+      loop
+      {
+        i++;
+        if (i == j)
+        {
+          i = -1;
+          j++;
+          if (j < nc)
+            n = rad[j];
+          else
+          {
+            if (z)
+            {
+              *Nrad -= z;
+              hShrink(rad, 0, nc);
+            }
+            return;
+          }
+        }
+        else if (rad[i])
+        {
+          o = rad[i];
+          break;
+        }
+      }
+    }
+  }
+}
+
+
+void hLexS(scfmon stc, int Nstc, varset var, int Nvar)
+{
+  if (Nstc < 2)
+    return;
+  int  j = 1, i = 0;
+  scmon n = stc[j];
+  scmon o = stc[0];
+  int k = Nvar;
+  loop
+  {
+    int k1 = var[k];
+    if (o[k1] < n[k1])
+    {
+      i++;
+      if (i < j)
+      {
+        o = stc[i];
+        k = Nvar;
+      }
+      else
+      {
+        j++;
+        if (j < Nstc)
+        {
+          i = 0;
+          o = stc[0];
+          n = stc[j];
+          k = Nvar;
+        }
+        else
+          return;
+      }
+    }
+    else if (o[k1] > n[k1])
+    {
+      int tmp_k;
+      for (tmp_k = j; tmp_k > i; tmp_k--)
+        stc[tmp_k] = stc[tmp_k - 1];
+      stc[i] = n;
+      j++;
+      if (j < Nstc)
+      {
+        i = 0;
+        o = stc[0];
+        n = stc[j];
+        k = Nvar;
+      }
+      else
+        return;
+    }
+    else
+    {
+      k--;
+      if (k<=0) return;
+    }
+  }
+}
+
+
+void hLexR(scfmon rad, int Nrad, varset var, int Nvar)
+{
+  int  j = 1, i = 0, k, k1;
+  scmon n, o;
+  if (Nrad < 2)
+    return;
+  n = rad[j];
+  o = rad[0];
+  k = Nvar;
+  loop
+  {
+    k1 = var[k];
+    if (!o[k1] && n[k1])
+    {
+      i++;
+      if (i < j)
+      {
+        o = rad[i];
+        k = Nvar;
+      }
+      else
+      {
+        j++;
+        if (j < Nrad)
+        {
+          i = 0;
+          o = rad[0];
+          n = rad[j];
+          k = Nvar;
+        }
+        else
+          return;
+      }
+    }
+    else if (o[k1] && !n[k1])
+    {
+      for (k = j; k > i; k--)
+        rad[k] = rad[k - 1];
+      rad[i] = n;
+      j++;
+      if (j < Nrad)
+      {
+        i = 0;
+        o = rad[0];
+        n = rad[j];
+        k = Nvar;
+      }
+      else
+        return;
+    }
+    else
+      k--;
+  }
+}
+
+
+void hPure(scfmon stc, int a, int *Nstc, varset var, int Nvar,
+ scmon pure, int *Npure)
+{
+  int  nc = *Nstc, np = 0, nq = 0, j, i, i1, c, l;
+  scmon x;
+  for (j = a; j < nc; j++)
+  {
+    x = stc[j];
+    i = Nvar;
+    c = 2;
+    l = 0;
+    loop
+    {
+      i1 = var[i];
+      if (x[i1])
+      {
+        c--;
+        if (!c)
+        {
+          l = 0;
+          break;
+        }
+        else if (c == 1)
+          l = i1;
+      }
+      i--;
+      if (!i)
+        break;
+    }
+    if (l)
+    {
+      if (!pure[l])
+      {
+        np++;
+        pure[l] = x[l];
+      }
+      else if (x[l] < pure[l])
+        pure[l] = x[l];
+      stc[j] = NULL;
+      nq++;
+    }
+  }
+  *Npure = np;
+  if (nq!=0)
+  {
+    *Nstc -= nq;
+    hShrink(stc, a, nc);
+  }
+}
+
+
+void hElimS(scfmon stc, int *e1, int a2, int e2, varset var, int Nvar)
+{
+  int  nc = *e1, z = 0, i, j, k, k1;
+  scmon n, o;
+  if (!nc || (a2 == e2))
+    return;
+  j = 0;
+  i = a2;
+  o = stc[i];
+  n = stc[0];
+  k = Nvar;
+  loop
+  {
+    k1 = var[k];
+    if (o[k1] > n[k1])
+    {
+      k = Nvar;
+      i++;
+      if (i < e2)
+        o = stc[i];
+      else
+      {
+        j++;
+        if (j < nc)
+        {
+          i = a2;
+          o = stc[i];
+          n = stc[j];
+        }
+        else
+        {
+          if (z!=0)
+          {
+            *e1 -= z;
+            hShrink(stc, 0, nc);
+          }
+          return;
+        }
+      }
+    }
+    else
+    {
+      k--;
+      if (k==0)
+      {
+        stc[j] = NULL;
+        z++;
+        j++;
+        if (j < nc)
+        {
+          i = a2;
+          o = stc[i];
+          n = stc[j];
+          k = Nvar;
+        }
+        else
+        {
+          if (z!=0)
+          {
+            *e1 -= z;
+            hShrink(stc, 0, nc);
+          }
+          return;
+        }
+      }
+    }
+  }
+}
+
+
+void hElimR(scfmon rad, int *e1, int a2, int e2, varset var, int Nvar)
+{
+  int  nc = *e1, z = 0, i, j, k, k1;
+  scmon n, o;
+  if (!nc || (a2 == e2))
+    return;
+  j = 0;
+  i = a2;
+  o = rad[i];
+  n = rad[0];
+  k = Nvar;
+  loop
+  {
+    k1 = var[k];
+    if (o[k1] && !n[k1])
+    {
+      k = Nvar;
+      i++;
+      if (i < e2)
+        o = rad[i];
+      else
+      {
+        j++;
+        if (j < nc)
+        {
+          i = a2;
+          o = rad[i];
+          n = rad[j];
+        }
+        else
+        {
+          if (z!=0)
+          {
+            *e1 -= z;
+            hShrink(rad, 0, nc);
+          }
+          return;
+        }
+      }
+    }
+    else
+    {
+      k--;
+      if (!k)
+      {
+        rad[j] = NULL;
+        z++;
+        j++;
+        if (j < nc)
+        {
+          i = a2;
+          o = rad[i];
+          n = rad[j];
+          k = Nvar;
+        }
+        else
+        {
+          if (z!=0)
+          {
+            *e1 -= z;
+            hShrink(rad, 0, nc);
+          }
+          return;
+        }
+      }
+    }
+  }
+}
+
+
+void hLex2S(scfmon rad, int e1, int a2, int e2, varset var,
+ int Nvar, scfmon w)
+{
+  int  j0 = 0, j = 0, i = a2, k, k1;
+  scmon n, o;
+  if (!e1)
+  {
+    for (; i < e2; i++)
+      rad[i - a2] = rad[i];
+    return;
+  }  else if (i == e2)
+    return;
+  n = rad[j];
+  o = rad[i];
+  loop
+  {
+    k = Nvar;
+    loop
+    {
+      k1 = var[k];
+      if (o[k1] < n[k1])
+      {
+        w[j0] = o;
+        j0++;
+        i++;
+        if (i < e2)
+        {
+          o = rad[i];
+          break;
+        }
+        else
+        {
+          for (; j < e1; j++)
+          {
+            w[j0] = rad[j];
+            j0++;
+          }
+          memcpy(rad, w, (e1 + e2 - a2) * sizeof(scmon));
+          return;
+        }
+      }
+      else if (o[k1] > n[k1])
+      {
+        w[j0] = n;
+        j0++;
+        j++;
+        if (j < e1)
+        {
+          n = rad[j];
+          break;
+        }
+        else
+        {
+          for (; i < e2; i++)
+          {
+            w[j0] = rad[i];
+            j0++;
+          }
+          memcpy(rad, w, (e1 + e2 - a2) * sizeof(scmon));
+          return;
+        }
+      }
+      k--;
+    }
+  }
+}
+
+
+void hLex2R(scfmon rad, int e1, int a2, int e2, varset var,
+ int Nvar, scfmon w)
+{
+  int  j0 = 0, j = 0, i = a2, k, k1;
+  scmon n, o;
+  if (!e1)
+  {
+    for (; i < e2; i++)
+      rad[i - a2] = rad[i];
+    return;
+  }
+  else if (i == e2)
+    return;
+  n = rad[j];
+  o = rad[i];
+  loop
+  {
+    k = Nvar;
+    loop
+    {
+      k1 = var[k];
+      if (!o[k1] && n[k1])
+      {
+        w[j0] = o;
+        j0++;
+        i++;
+        if (i < e2)
+        {
+          o = rad[i];
+          break;
+        }
+        else
+        {
+          for (; j < e1; j++)
+          {
+            w[j0] = rad[j];
+            j0++;
+          }
+          memcpy(rad, w, (e1 + e2 - a2) * sizeof(scmon));
+          return;
+        }
+      }
+      else if (o[k1] && !n[k1])
+      {
+        w[j0] = n;
+        j0++;
+        j++;
+        if (j < e1)
+        {
+          n = rad[j];
+          break;
+        }
+        else
+        {
+          for (; i < e2; i++)
+          {
+            w[j0] = rad[i];
+            j0++;
+          }
+          memcpy(rad, w, (e1 + e2 - a2) * sizeof(scmon));
+          return;
+        }
+      }
+      k--;
+    }
+  }
+}
+
+
+void hStepS(scfmon stc, int Nstc, varset var, int Nvar, int *a, int *x)
+{
+  int  k1, i;
+  int  y;
+  k1 = var[Nvar];
+  y = *x;
+  i = *a;
+  loop
+  {
+    if (y < stc[i][k1])
+    {
+      *a = i;
+      *x = stc[i][k1];
+      return;
+    }
+    i++;
+    if (i == Nstc)
+    {
+      *a = i;
+      return;
+    }
+  }
+}
+
+
+void hStepR(scfmon rad, int Nrad, varset var, int Nvar, int *a)
+{
+  int  k1, i;
+  k1 = var[Nvar];
+  i = 0;
+  loop
+  {
+    if (rad[i][k1])
+    {
+      *a = i;
+      return;
+    }
+    i++;
+    if (i == Nrad)
+    {
+      *a = i;
+      return;
+    }
+  }
+}
+
+
+monf hCreate(int Nvar)
+{
+  monf xmem;
+  int  i;
+  xmem = (monf)omAlloc((Nvar + 1) * sizeof(monp));
+  for (i = Nvar; i>0; i--)
+  {
+    xmem[i] = (monp)omAlloc(LEN_MON);
+    xmem[i]->mo = NULL;
+  }
+  return xmem;
+}
+
+
+void hKill(monf xmem, int Nvar)
+{
+  int  i;
+  for (i = Nvar; i!=0; i--)
+  {
+    if (xmem[i]->mo!=NULL)
+      omFreeSize((ADDRESS)xmem[i]->mo, xmem[i]->a * sizeof(scmon));
+    omFreeSize((ADDRESS)xmem[i], LEN_MON);
+  }
+  omFreeSize((ADDRESS)xmem, (Nvar + 1) * sizeof(monp));
+}
+
+
+scfmon hGetmem(int lm, scfmon old, monp monmem)
+{
+  scfmon x = monmem->mo;
+  int  lx = monmem->a;
+  if ((x==NULL) || (lm > lx))
+  {
+    /* according to http://www.singular.uni-kl.de:8002/trac/ticket/463#comment:4
+     * we need to work around a compiler bug:
+    * if ((x!=NULL)&&(lx>0)) omFreeSize((ADDRESS)x, lx * sizeof(scmon));
+    */
+    if (x!=NULL) if (lx>0) omFreeSize((ADDRESS)x, lx * sizeof(scmon));
+    monmem->mo = x = (scfmon)omAlloc(lm * sizeof(scmon));
+    monmem->a = lm;
+  }
+  memcpy(x, old, lm * sizeof(scmon));
+  return x;
+}
+
+/*
+* a bug in Metrowerks with "lifetime analysis"
+*scmon hGetpure(scmon p)
+*{
+*  scmon p1, pn;
+*  p1 = p + 1;
+*  pn = p1 + (currRing->N);
+*  memcpy(pn, p1, (currRing->N) * sizeof(int));
+*  return pn - 1;
+*}
+*/
+scmon hGetpure(scmon p)
+{
+  scmon p1 = p;
+  scmon pn;
+  p1++;
+  pn = p1;
+  pn += (currRing->N);
+  memcpy(pn, p1, (currRing->N) * sizeof(int));
+  return pn - 1;
+}
+
diff --git a/kernel/combinatorics/hutil.h b/kernel/combinatorics/hutil.h
new file mode 100644
index 0000000..df31ca9
--- /dev/null
+++ b/kernel/combinatorics/hutil.h
@@ -0,0 +1,90 @@
+#ifndef HUTIL_H
+#define HUTIL_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT
+*/
+
+class intvec;
+
+struct omBin_s   ; typedef struct omBin_s omBin_t ; typedef omBin_t * omBin;
+
+struct ip_sring  ; typedef struct ip_sring                          * ring;
+struct sip_sideal; typedef struct sip_sideal                        * ideal;
+struct spolyrec  ; typedef struct spolyrec polyrec; typedef polyrec * poly;
+typedef                                                     poly    * polyset;
+
+extern ring currRing;
+
+typedef int * scmon;
+typedef scmon * scfmon;
+typedef int * varset;
+struct monrec;
+typedef struct monrec monh;
+typedef monh * monp;
+typedef monp * monf;
+struct monrec
+{
+  scfmon mo;
+  int a;
+};
+
+typedef struct sindlist indlist;
+typedef indlist * indset;
+struct sindlist
+{
+  indset nx;
+  intvec * set;
+};
+
+#define LEN_MON (sizeof(scfmon) + sizeof(int))
+
+extern omBin indlist_bin;
+
+extern scfmon hexist, hstc, hrad, hwork;
+extern scmon hpure, hpur0;
+extern varset hvar, hsel;
+extern int hNexist, hNstc, hNrad, hNvar, hNpure;
+extern monf stcmem, radmem;
+extern int hisModule;
+extern monf stcmem, radmem;
+extern indset ISet, JSet;
+extern int  hCo, hMu, hMu2;
+
+
+void hDelete(scfmon ev, int ev_length);
+void hComp(scfmon exist, int Nexist, int ak, scfmon stc, int * Nstc);
+void hSupp(scfmon stc, int Nstc, varset var, int * Nvar);
+void hOrdSupp(scfmon stc, int Nstc, varset var, int Nvar);
+void hStaircase(scfmon stc, int * Nstc, varset var, int Nvar);
+void hRadical(scfmon rad, int * Nrad, int Nvar);
+void hLexS(scfmon stc, int Nstc, varset var, int Nvar);
+void hLexR(scfmon rad, int Nrad, varset var, int Nvar);
+void hPure(scfmon stc, int a, int *Nstc, varset var, int Nvar,
+ scmon pure, int *Npure);
+void hElimS(scfmon stc, int * e1, int a2, int e2,varset var, int Nvar);
+void hElimR(scfmon rad, int * e1, int a2, int e2,varset var, int Nvar);
+void hLex2S(scfmon stc, int e1, int a2, int e2,varset var,
+ int Nvar, scfmon w);
+void hLex2R(scfmon rad, int e1, int a2, int e2,varset var,
+ int Nvar, scfmon w);
+void hStepS(scfmon stc, int Nstc, varset var, int Nvar,int *a, int *x);
+void hStepR(scfmon rad, int Nrad, varset var, int Nvar,int *a);
+monf hCreate(int Nvar);
+void hKill(monf xmem, int Nvar);
+scfmon hGetmem(int lm, scfmon old, monp monmem);
+scmon hGetpure(scmon p);
+void hDimSolve(scmon pure, int Npure, scfmon rad, int Nrad,
+ varset var, int Nvar);
+void hIndMult(scmon pure, int Npure, scfmon rad, int Nrad,
+ varset var, int Nvar);
+void hIndAllMult(scmon pure, int Npure, scfmon rad, int Nrad,
+ varset var, int Nvar);
+void hDegreeSeries(intvec *s1, intvec *s2, int *co, int *mu);
+
+
+scfmon hInit(ideal S, ideal Q, int * Nexist, ring tailRing);
+void slicehilb(ideal I);
+#endif
diff --git a/kernel/combinatorics/stairc.h b/kernel/combinatorics/stairc.h
new file mode 100644
index 0000000..8769523
--- /dev/null
+++ b/kernel/combinatorics/stairc.h
@@ -0,0 +1,37 @@
+#ifndef STAIRC_H
+#define STAIRC_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT
+*/
+
+struct spolyrec  ; typedef struct spolyrec polyrec; typedef polyrec * poly;
+struct ip_sring  ; typedef struct ip_sring                          * ring;
+struct sip_sideal; typedef struct sip_sideal                        * ideal;
+
+class intvec;
+
+extern ring currRing;
+
+void scComputeHC(ideal s,ideal Q, int  k,poly &hEdge, ring tailRing = currRing);
+#if 0 // - alternative implementation for tests
+void scComputeHCw(ideal s,ideal Q, int  k,poly &hEdge, ring tailRing = currRing);
+#endif
+
+intvec * scIndIntvec(ideal S, ideal Q=NULL);
+
+// lists scIndIndset(ideal S, BOOLEAN all, ideal Q=NULL); // TODO: move to Singular/
+
+int scDimInt(ideal  s,ideal Q=NULL);
+int scMultInt(ideal  s,ideal Q=NULL);
+int scMult0Int(ideal  s,ideal Q=NULL, const ring tailRing = currRing);
+void scPrintDegree(int co, int mu);
+void scDegree(ideal  s,intvec *modulweight,ideal Q=NULL);
+
+ideal scKBase(int deg, ideal  s, ideal Q=NULL, intvec * mv=NULL);
+
+#endif
+
+
diff --git a/kernel/combinatorics/test.cc b/kernel/combinatorics/test.cc
new file mode 100644
index 0000000..546cdc8
--- /dev/null
+++ b/kernel/combinatorics/test.cc
@@ -0,0 +1,378 @@
+#include <kernel/mod2.h>
+
+#include <omalloc/omalloc.h>
+
+#include <resources/feFopen.h>
+#include <resources/feResource.h>
+
+
+#include <factory/factory.h> // :(
+
+#include <misc/auxiliary.h>
+#include <misc/intvec.h>
+#include <misc/int64vec.h>
+#include <misc/mylimits.h>
+#include <misc/options.h>
+
+#include <reporter/reporter.h>
+
+#include <coeffs/si_gmp.h>
+#include <coeffs/coeffs.h>
+#include <coeffs/numbers.h>
+
+#ifndef PLURAL_INTERNAL_DECLARATIONS
+#define PLURAL_INTERNAL_DECLARATIONS
+#endif
+
+#ifndef PLURAL_INTERNAL_DECLARATIONS_GB_HACK
+#define PLURAL_INTERNAL_DECLARATIONS_GB_HACK
+#endif
+
+#include <polys/nc/gb_hack.h>
+#include <polys/nc/nc.h>
+#include <polys/nc/ncSACache.h>
+#include <polys/nc/ncSAFormula.h>
+#include <polys/nc/ncSAMult.h>
+#include <polys/nc/sca.h>
+#include <polys/nc/summator.h>
+
+#include <polys/kbuckets.h>
+#include <polys/matpol.h>
+#include <polys/mod_raw.h>
+#include <polys/prCopy.h>
+#include <polys/sbuckets.h>
+#include <polys/simpleideals.h>
+#include <polys/weight.h>
+
+#include <polys/monomials/maps.h>
+#include <polys/monomials/monomials.h>
+#include <polys/monomials/p_polys.h>
+#include <polys/monomials/ring.h>
+
+#include <polys/templates/p_MemAdd.h>
+#include <polys/templates/p_Procs.h>
+
+#include <polys/operations/pShallowCopyDelete.h>
+
+#include <polys/clapsing.h>
+
+
+// // TODO: DUE to the use of HALT in npolygon.cc :(((
+extern "C" {void m2_end(int i){exit(i);}}
+
+// // TODO: DUE to its use in kutil.cc :(((
+// char * showOption(){return NULL;}
+
+
+// #include "structs.h"
+
+
+// HEADERS:
+#include <kernel/combinatorics/hutil.h>
+#include <kernel/combinatorics/hilb.h>
+#include <kernel/combinatorics/stairc.h>
+
+#include <kernel/ideals.h>
+#include <kernel/digitech.h>
+#include <kernel/fast_mult.h>
+
+// #include <kernel/spectrum/kmatrix.h>
+#include <kernel/preimage.h>
+#include <kernel/structs.h>
+#include <kernel/polys.h>
+
+void TestGBEngine()
+{
+
+  //  R = MPolynomialRing_polydict(QQ,5,'w,x,y,z,C', order='degrevlex')
+  //  J = (w*w - x*z, w*x - y*z, x*x - w*y, x*y - z*z, y*y - w*z)
+
+  const short w = 1;
+  const short x = 2;
+  const short y = 3;
+  const short z = 4;
+
+  const short N = (z - w + 1);
+
+  char **n=(char**)omalloc(N*sizeof(char*));
+
+
+  n[w-1]=omStrDup("w");
+  n[x-1]=omStrDup("x");
+  n[y-1]=omStrDup("y");
+  n[z-1]=omStrDup("z");
+
+
+  const int D = 3;
+  int *order = (int *) omAlloc0(D* sizeof(int));
+  int *block0 = (int *)omAlloc0(D * sizeof(int));
+  int *block1 = (int *)omAlloc0(D * sizeof(int));
+
+  order[0]  = ringorder_dp;
+  block0[0] = 1;
+  block1[0] = N;
+
+  order[1]  = ringorder_C;
+  block0[1] = 1;
+  block1[1] = N;
+
+  ring R = rDefault(0, N, n, D, order, block0, block1);
+
+//   ring R = rDefault(0, N, n);
+
+  rWrite(R); PrintLn();
+
+#ifdef RDEBUG
+  rDebugPrint(R);
+#endif
+
+  ideal I = idInit(5, 1);
+
+  int gen = 0;
+
+  {
+    // -xz
+    poly p = p_ISet(-1,R);
+
+    p_SetExp(p, x, 1, R);
+    p_SetExp(p, z, 1, R);
+    p_Setm(p, R);
+
+    assume( p_GetExp(p, x, R) == 1 );
+    assume( p_GetExp(p, z, R) == 1 );
+    assume( p_GetExp(p, w, R) == 0 );
+    assume( p_GetExp(p, y, R) == 0 );
+
+    // +w2
+    poly lp = p_ISet(1,R);
+    p_SetExp(lp, w, 2, R);
+    p_Setm(lp, R);
+
+    assume( p_GetExp(lp, w, R) == 2 );
+    assume( p_GetExp(lp, x, R) == 0 );
+    assume( p_GetExp(lp, y, R) == 0 );
+    assume( p_GetExp(lp, z, R) == 0 );
+
+    MATELEM(I, 1, ++gen) = p_Add_q(lp, p, R); // w2 - xz
+  }
+
+  {
+    // -yz
+    poly p = p_ISet(-1,R);
+
+    p_SetExp(p, y, 1, R);
+    p_SetExp(p, z, 1, R);
+    p_Setm(p, R);
+
+    assume( p_GetExp(p, y, R) == 1 );
+    assume( p_GetExp(p, z, R) == 1 );
+    assume( p_GetExp(p, w, R) == 0 );
+    assume( p_GetExp(p, x, R) == 0 );
+
+    // +wx
+    poly lp = p_ISet(1,R);
+    p_SetExp(lp, w, 1, R);
+    p_SetExp(lp, x, 1, R);
+    p_Setm(lp, R);
+
+    assume( p_GetExp(lp, w, R) == 1 );
+    assume( p_GetExp(lp, x, R) == 1 );
+    assume( p_GetExp(lp, y, R) == 0 );
+    assume( p_GetExp(lp, z, R) == 0 );
+
+    MATELEM(I, 1, ++gen) = p_Add_q(lp, p, R); // wx - yz
+  }
+
+
+  {
+    // -wy
+    poly p = p_ISet(-1,R);
+
+    p_SetExp(p, y, 1, R);
+    p_SetExp(p, w, 1, R);
+    p_Setm(p, R);
+
+    assume( p_GetExp(p, y, R) == 1 );
+    assume( p_GetExp(p, w, R) == 1 );
+    assume( p_GetExp(p, z, R) == 0 );
+    assume( p_GetExp(p, x, R) == 0 );
+
+    // +x2
+    poly lp = p_ISet(1,R);
+    p_SetExp(lp, x, 2, R);
+    p_Setm(lp, R);
+
+    assume( p_GetExp(lp, w, R) == 0 );
+    assume( p_GetExp(lp, x, R) == 2 );
+    assume( p_GetExp(lp, y, R) == 0 );
+    assume( p_GetExp(lp, z, R) == 0 );
+
+    MATELEM(I, 1, ++gen) = p_Add_q(lp, p, R); // x2 - wy
+  }
+
+
+  {
+    // -z2
+    poly p = p_ISet(-1,R);
+
+    p_SetExp(p, z, 2, R);
+    p_Setm(p, R);
+
+    assume( p_GetExp(p, y, R) == 0 );
+    assume( p_GetExp(p, w, R) == 0 );
+    assume( p_GetExp(p, z, R) == 2 );
+    assume( p_GetExp(p, x, R) == 0 );
+
+    // +xy
+    poly lp = p_ISet(1,R);
+    p_SetExp(lp, x, 1, R);
+    p_SetExp(lp, y, 1, R);
+    p_Setm(lp, R);
+
+    assume( p_GetExp(lp, w, R) == 0 );
+    assume( p_GetExp(lp, x, R) == 1 );
+    assume( p_GetExp(lp, y, R) == 1 );
+    assume( p_GetExp(lp, z, R) == 0 );
+
+    MATELEM(I, 1, ++gen) = p_Add_q(lp, p, R); // xy - z2
+  }
+
+
+  {
+    // -wz
+    poly p = p_ISet(-1,R);
+
+    p_SetExp(p, w, 1, R);
+    p_SetExp(p, z, 1, R);
+    p_Setm(p, R);
+
+    assume( p_GetExp(p, y, R) == 0 );
+    assume( p_GetExp(p, w, R) == 1 );
+    assume( p_GetExp(p, z, R) == 1 );
+    assume( p_GetExp(p, x, R) == 0 );
+
+    // +y2
+    poly lp = p_ISet(1,R);
+    p_SetExp(lp, y, 2, R);
+    p_Setm(lp, R);
+
+    assume( p_GetExp(lp, w, R) == 0 );
+    assume( p_GetExp(lp, x, R) == 0 );
+    assume( p_GetExp(lp, y, R) == 2 );
+    assume( p_GetExp(lp, z, R) == 0 );
+
+    MATELEM(I, 1, ++gen) = p_Add_q(lp, p, R); // y2 - wz
+  }
+#ifdef PDEBUG
+  PrintS("I: ");
+  idShow(I, R, R, 0);
+#endif
+
+
+//  ideal kStd(ideal F, ideal Q, tHomog h, intvec ** mw,intvec *hilb=NULL,
+//             int syzComp=0,int newIdeal=0, intvec *vw=NULL);
+  // make R the default ring:
+  rChangeCurrRing(R);
+
+ ////
+
+  idDelete( &I, R);
+  rDelete(R); // should cleanup every belonging polynomial, right!?
+
+}
+
+
+
+void TestSimpleRingArithmetcs()
+{
+  // Libpolys tests:
+
+  // construct the ring Z/32003[x,y,z]
+  // the variable names
+  char **n=(char**)omalloc(3*sizeof(char*));
+  n[0]=omStrDup("x");
+  n[1]=omStrDup("y");
+  n[2]=omStrDup("z2");
+
+  ring R = rDefault(32003,3,n); //  ring R = rDefault(0,3,n);
+
+  rWrite(R); PrintLn();
+
+#ifdef RDEBUG
+  rDebugPrint(R);
+#endif
+
+
+  poly p = p_ISet(1,R); p_SetExp(p,1,1, R); p_Setm(p, R);
+
+  assume( p_GetExp(p,1, R) == 1 );
+
+  poly pp = pp_Mult_qq( p, p, R);
+
+  Print("p: "); p_Write0(p, R); Print(", deg(p): %ld", p_Totaldegree(p, R)); assume( 1 == p_Totaldegree(p, R) );
+
+  Print("; p*p : "); p_Write0(pp, R); Print("deg(pp): %ld\n", p_Totaldegree(pp, R)); assume( 2 == p_Totaldegree(pp, R) );
+
+
+  p_Delete(&p, R);
+
+  assume( p_GetExp(pp,1, R) == 2 );
+
+  p_Delete(&pp, R);
+
+
+//  rDelete(R);
+
+  // make R the default ring:
+  rChangeCurrRing(R);
+
+  // create the polynomial 1
+  poly p1=pISet(1);
+
+  // create tthe polynomial 2*x^3*z^2
+  poly p2=p_ISet(2,R);
+  pSetExp(p2,1,3);
+  pSetExp(p2,3,2);
+  pSetm(p2);
+
+  // print p1 + p2
+  Print("p1: "); pWrite0(p1);
+  Print(" + p2: "); pWrite0(p2);
+  Print("  ---- >>>> ");
+
+  // compute p1+p2
+  p1=p_Add_q(p1,p2,R); p2=NULL;
+  pWrite(p1);
+
+  // clean up:
+//  pDelete(&p1);
+
+  rDelete(R); // should cleanup every belonging polynomial, right!?
+}
+
+
+int main( int, char *argv[] )
+{
+  assume( sizeof(long) == SIZEOF_LONG );
+
+  if( sizeof(long) != SIZEOF_LONG )
+  {
+    WerrorS("Bad config.h: wrong size of long!");
+
+    return(1);
+  }
+
+
+  feInitResources(argv[0]);
+
+  StringSetS("ressources in use (as reported by feStringAppendResources(0):\n");
+  feStringAppendResources(0);
+
+  PrintLn();
+  { char* s = StringEndS(); PrintS(s); omFree(s); }
+
+  TestGBEngine();
+  TestSimpleRingArithmetcs();
+
+  return 0;
+}
diff --git a/kernel/digitech.cc b/kernel/digitech.cc
new file mode 100644
index 0000000..9463ace
--- /dev/null
+++ b/kernel/digitech.cc
@@ -0,0 +1,87 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+
+
+
+#include <kernel/mod2.h>
+#include <polys/monomials/ring.h>
+
+#include <kernel/digitech.h>
+#include <polys/kbuckets.h>
+#include <kernel/ideals.h>
+static ideal zero_ideal;
+
+void bit_reduce(poly & f,ring r)
+{
+  poly p=f;
+  kBucket_pt erg_bucket= kBucketCreate(r);
+  kBucketInit(erg_bucket,NULL,0 /*pLength(P.p)*/);
+  while(p)
+  {
+    poly next=pNext(p);
+    pNext(p)=NULL;
+
+    int i;
+    int max=rVar(r);
+    for(i=1;i<=max;i++)
+    {
+      unsigned long exp=p_GetExp(p,i,r);
+      if(exp!=0)
+        p_SetExp(p,i,1,r);
+
+    }
+    p_Setm(p,r);
+    int pseudo_len=0;
+    kBucket_Add_q(erg_bucket,p,&pseudo_len);
+    p=next;
+  }
+
+  int len=0;
+  poly erg;
+  kBucketClear(erg_bucket,&erg, &len);
+  kBucketDestroy(&erg_bucket);
+  f=erg;
+}
+
+poly uni_subst_bits(poly outer_uni, poly inner_multi, ring r)
+{
+  zero_ideal=idInit(0,1);
+  //assumes outer_uni is univariate and ordering global
+  int d_max=p_GetExp(outer_uni,1,r);
+  poly* potences=(poly*) omAlloc((d_max+1)*sizeof(poly));
+  potences[0]=p_ISet(1,r);
+  int i;
+  for(i=1;i<=d_max;i++)
+  {
+    potences[i]=pp_Mult_qq(potences[i-1],inner_multi,r);
+    bit_reduce(potences[i],r);
+  }
+
+  poly p=outer_uni;
+  kBucket_pt erg_bucket= kBucketCreate(r);
+  kBucketInit(erg_bucket,NULL,0 /*pLength(P.p)*/);
+
+
+  while(p)
+  {
+    int d=p_GetExp(p,1,r);
+    assume(potences[d]!=NULL); //mustn't always hold, but for most input
+    int pseudo_len=0;
+    kBucket_Add_q(erg_bucket,p_Mult_nn(potences[d],p_GetCoeff(p,r),r),&pseudo_len);
+    potences[d]=NULL;
+    p=pNext(p);
+  }
+
+  //free potences
+  for(i=0;i<=d_max;i++)
+  {
+    p_Delete(&potences[i],r);
+  }
+  omfree(potences);
+  int len=0;
+  poly erg;
+  kBucketClear(erg_bucket,&erg, &len);
+  kBucketDestroy(&erg_bucket);
+  return(erg);
+}
diff --git a/kernel/digitech.h b/kernel/digitech.h
new file mode 100644
index 0000000..1928cd8
--- /dev/null
+++ b/kernel/digitech.h
@@ -0,0 +1,7 @@
+#ifndef DIGITECH_HEADER
+#define DIGITECH_HEADER
+// #include <kernel/mod2.h>
+#include <kernel/polys.h>
+void bit_reduce(poly & f,ring r);
+poly uni_subst_bits(poly outer_uni, poly inner_multi, ring r);
+#endif
diff --git a/kernel/fast_mult.cc b/kernel/fast_mult.cc
new file mode 100644
index 0000000..5e8d99a
--- /dev/null
+++ b/kernel/fast_mult.cc
@@ -0,0 +1,670 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+
+#include <kernel/mod2.h>
+
+#include <polys/monomials/ring.h>
+#include <kernel/fast_mult.h>
+#include <polys/kbuckets.h>
+
+typedef poly fastmultrec(poly f, poly g, ring r);
+static const int pass_option=1;
+static int mults=0;
+int Mults()
+{
+  return mults;
+}
+static void degsplit(poly p,int n,poly &p1,poly&p2, int vn, ring r)
+{
+  poly erg1_i, erg2_i;
+  erg1_i=NULL;
+  erg2_i=NULL;
+  while(p)
+  {
+    if(p_GetExp(p,vn,r)>=n)
+    {
+      if (p1==NULL)
+      {
+        p1=p;
+      }
+      else
+      {
+        pNext(erg1_i)=p;
+      }
+      erg1_i=p;
+    }
+    else
+    {
+      if (p2==NULL)
+      {
+        p2=p;
+      }
+      else
+      {
+        pNext(erg2_i)=p;
+      }
+      erg2_i=p;
+    }
+    p=pNext(p);
+  }
+  if(erg2_i)
+  {
+    pNext(erg2_i)=NULL;
+  }
+  if (erg1_i)
+  {
+    pNext(erg1_i)=NULL;
+  }
+
+}
+static void div_by_x_power_n(poly p, int n, int vn, ring r)
+{
+  while(p)
+  {
+    assume(p_GetExp(p,vn,r)>=n);
+    int e=p_GetExp(p,vn,r);
+    p_SetExp(p,vn,e-n,r);
+    p=pNext(p);
+  }
+}
+
+static poly do_unifastmult(poly f,int df,poly g,int dg, int vn, fastmultrec rec, ring r)
+{
+  int n=1;
+  if ((f==NULL)||(g==NULL)) return NULL;
+  //int df=pGetExp(f,vn);//pFDeg(f);
+  //  int dg=pGetExp(g,vn);//pFDeg(g);
+
+  int dm;
+  if(df>dg)
+  {
+    dm=df;
+  }
+  else
+  {
+    dm=dg;
+  }
+  while(n<=dm)
+    {
+      n*=2;
+    }
+  if(n==1)
+  {
+    return(pp_Mult_qq(f,g,r));
+  }
+
+  int pot=n/2;
+  assume(pot*2==n);
+
+
+  //splitting
+  poly f1=NULL;
+  poly f0=NULL;//f-(x^(pot)*F1);
+  degsplit(p_Copy(f,r),pot,f1,f0,vn,r);
+  div_by_x_power_n(f1,pot,vn,r);
+
+  poly g1=NULL;
+  poly g0=NULL;
+  degsplit(p_Copy(g,r),pot,g1,g0,vn,r);
+  div_by_x_power_n(g1,pot,vn,r);
+
+  //p00, p11
+  poly p00=rec(f0,g0,r);//unifastmult(f0,g0);
+  poly p11=rec(f1,g1,r);
+
+  //construct erg, factor
+  poly erg=NULL;
+  poly factor=p_ISet(1,r);
+
+  p_SetExp(factor,vn,n,r);
+  erg=pp_Mult_mm(p11,factor,r);
+  erg=p_Add_q(erg,p_Copy(p00,r),r);
+
+
+
+
+
+  if((f1!=NULL) &&(f0!=NULL) &&(g0!=NULL) && (g1!=NULL))
+  {
+    //if(true){
+    //eat up f0,f1,g0,g1
+    poly s1=p_Add_q(f0,f1,r);
+    poly s2=p_Add_q(g0,g1,r);
+    poly pbig=rec(s1,s2,r);
+    p_Delete(&s1,r);
+    p_Delete(&s2,r);
+
+
+    //eat up pbig
+    poly sum=pbig;
+    p_SetExp(factor,vn,pot,r);
+
+    //eat up p00
+    sum=p_Add_q(sum,p_Neg(p00,r),r);
+
+    //eat up p11
+    sum=p_Add_q(sum,p_Neg(p11,r),r);
+
+
+    sum=p_Mult_mm(sum,factor,r);
+
+
+    //eat up sum
+    erg=p_Add_q(sum,erg,r);
+  }
+  else
+  {
+    //eat up f0,f1,g0,g1
+    poly s1=rec(f0,g1,r);
+    poly s2=rec(g0,f1,r);
+    p_SetExp(factor,vn,pot,r);
+    poly h=p_Mult_mm(((s1!=NULL)?s1:s2),factor,r);
+    p_Delete(&f1,r);
+    p_Delete(&f0,r);
+    p_Delete(&g0,r);
+    p_Delete(&g1,r);
+    p_Delete(&p00,r);
+    p_Delete(&p11,r);
+    erg=p_Add_q(erg,h,r);
+  }
+
+
+  p_Delete(&factor,r);
+
+
+
+  return(erg);
+}
+
+// poly do_unifastmult_buckets(poly f,poly g){
+
+
+
+
+//   int n=1;
+//   if ((f==NULL)||(g==NULL)) return NULL;
+//   int df=pGetExp(f,1);//pFDeg(f);
+//     int dg=pGetExp(g,1);//pFDeg(g);
+
+//   int dm;
+//   if(df>dg){
+//     dm=df;
+//   }else{
+//     dm=dg;
+//   }
+//   while(n<=dm)
+//     {
+//       n*=2;
+//     }
+//   int pseudo_len=0;
+//   if(n==1){
+//     return ppMult_qq(f,g);
+
+//   }
+//   kBucket_pt erg_bucket= kBucketCreate(currRing);
+//   kBucketInit(erg_bucket,NULL,0 /*pLength(P.p)*/);
+
+//   int pot=n/2;
+//   assume(pot*2==n);
+
+
+//   //splitting
+//   poly f1=NULL;
+//   poly f0=NULL;//f-(x^(pot)*F1);
+//   degsplit(pCopy(f),pot,f1,f0);
+//   div_by_x_power_n(f1,pot);
+//   poly g1=NULL;
+//   poly g0=NULL;
+//   degsplit(pCopy(g),pot,g1,g0);
+//   div_by_x_power_n(g1,pot);
+
+//   //p00
+//   //p11
+//   poly p00=unifastmult(f0,g0);
+//   poly p11=unifastmult(f1,g1);
+
+
+
+
+//   //eat up f0,f1,g0,g1
+//   poly pbig=unifastmult(pAdd(f0,f1),pAdd(g0,g1));
+//   poly factor=pOne();//pCopy(erg_mult);
+//   pSetExp(factor,1,n);
+//   pseudo_len=0;
+//   kBucket_Add_q(erg_bucket,ppMult_mm(p11,factor),&pseudo_len);
+//   pseudo_len=0;
+//   kBucket_Add_q(erg_bucket,pCopy(p00),&pseudo_len);
+//   pSetExp(factor,1,pot);
+
+//   //eat up pbig
+//   pseudo_len=0;
+//   kBucket_Add_q(erg_bucket,pMult_mm(pbig,factor),&pseudo_len);
+//   pseudo_len=0;
+//   //eat up p00
+//   kBucket_Add_q(erg_bucket,pMult_mm(pNeg(p00),factor),&pseudo_len);
+//   pseudo_len=0;
+//   //eat up p11
+//   kBucket_Add_q(erg_bucket,pMult_mm(pNeg(p11),factor),&pseudo_len);
+
+
+//   pseudo_len=0;
+
+
+//   pDelete(&factor);
+
+//   int len=0;
+//   poly erg=NULL;
+//   kBucketClear(erg_bucket,&erg,&len);
+//   kBucketDestroy(&erg_bucket);
+
+//   return erg;
+// }
+
+static inline int max(int a, int b)
+{
+  return (a>b)? a:b;
+}
+static inline int min(int a, int b)
+{
+  return (a>b)? b:a;
+}
+poly unifastmult(poly f,poly g, ring r)
+{
+  int vn=1;
+  if((f==NULL)||(g==NULL)) return NULL;
+  int df=p_GetExp(f,vn,r);
+  int dg=p_GetExp(g,vn,r);
+  if ((df==0)||(dg==0))
+    return pp_Mult_qq(f,g,r);
+  if (df*dg<100)
+    return pp_Mult_qq(f,g,r);
+  // if (df*dg>10000)
+  //  return
+  //    do_unifastmult_buckets(f,g);
+  //else
+  return do_unifastmult(f,df,g,dg,vn,unifastmult,r);
+
+}
+
+poly multifastmult(poly f, poly g, ring r)
+{
+  mults++;
+  if((f==NULL)||(g==NULL)) return NULL;
+  if (pLength(f)*pLength(g)<100)
+    return pp_Mult_qq(f,g,r);
+  //find vn
+  //determine df,dg simultaneously
+  int i;
+  int can_i=-1;
+  int can_df=0;
+  int can_dg=0;
+  int can_crit=0;
+  for(i=1;i<=rVar(r);i++)
+  {
+    poly p;
+    int df=0;
+    int dg=0;
+    //max min max Strategie
+    p=f;
+    while(p)
+    {
+      df=max(df,p_GetExp(p,i,r));
+      p=pNext(p);
+    }
+    if(df>can_crit)
+    {
+      p=g;
+      while(p)
+      {
+        dg=max(dg,p_GetExp(p,i,r));
+        p=pNext(p);
+      }
+      int crit=min(df,dg);
+      if (crit>can_crit)
+      {
+        can_crit=crit;
+        can_i=i;
+        can_df=df;
+        can_dg=dg;
+      }
+    }
+  }
+  if(can_crit==0)
+    return pp_Mult_qq(f,g,r);
+  else
+    {
+      poly erg=do_unifastmult(f,can_df,g,can_dg,can_i,multifastmult,r);
+      p_Normalize(erg,r);
+      return(erg);
+    }
+}
+poly pFastPower(poly f, int n, ring r)
+{
+  if (n==1) return f;
+  if (n==0) return p_ISet(1,r);
+  assume(n>=0);
+  int i_max=1;
+  int pot_max=0;
+  while(i_max*2<=n)
+  {
+    i_max*=2;
+    pot_max++;
+  }
+  int field_size=pot_max+1;
+  int* int_pot_array=(int*) omAlloc(field_size*sizeof(int));
+  poly* pot_array=(poly*) omAlloc(field_size*sizeof(poly));
+  int i;
+  int pot=1;
+  //initializing int_pot
+  for(i=0;i<field_size;i++)
+  {
+    int_pot_array[i]=pot;
+    pot*=2;
+  }
+  //calculating pot_array
+  pot_array[0]=f; //do not delete it
+  for(i=1;i<field_size;i++)
+  {
+    poly p=pot_array[i-1];
+    if(rVar(r)==1)
+      pot_array[i]=multifastmult(p,p,r);
+    else
+      pot_array[i]=pp_Mult_qq(p,p,r);
+  }
+
+
+
+  int work_n=n;
+  assume(work_n>=int_pot_array[field_size-1]);
+  poly erg=p_ISet(1,r);
+
+
+  //forward maybe faster, later
+  // for(i=field_size-1;i>=0;i--){
+
+//       assume(work_n<2*int_pot_array[i]);
+//       if(int_pot_array[i]<=work_n){
+//         work_n-=int_pot_array[i];
+//         poly prod=multifastmult(erg,pot_array[i],r);
+//         pDelete(&erg);
+//         erg=prod;
+//       }
+
+//       if(i!=0) pDelete(&pot_array[i]);
+//   }
+
+
+  for(i=field_size-1;i>=0;i--)
+  {
+
+      assume(work_n<2*int_pot_array[i]);
+      if(int_pot_array[i]<=work_n)
+      {
+        work_n-=int_pot_array[i];
+        int_pot_array[i]=1;
+      }
+      else int_pot_array[i]=0;
+
+  }
+  for(i=0;i<field_size;i++)
+  {
+    if(int_pot_array[i]==1)
+    {
+      poly prod;
+      if(rVar(r)==1)
+        prod=multifastmult(erg,pot_array[i],r);
+      else
+        prod=pp_Mult_qq(erg,pot_array[i],r);
+      pDelete(&erg);
+      erg=prod;
+    }
+    if(i!=0) pDelete(&pot_array[i]);
+  }
+  //free res
+  omfree(pot_array);
+  omfree(int_pot_array);
+  return erg;
+}
+static omBin lm_bin=NULL;
+/*3
+* compute for monomials p*q
+* destroys p, keeps q
+*/
+static void p_MonMultMB(poly p, poly q,ring r)
+{
+  number x, y;
+  // int i;
+
+  y = p_GetCoeff(p,r);
+  x = n_Mult(y,pGetCoeff(q),r->cf);
+  n_Delete(&y,r->cf);
+  p_SetCoeff0(p,x,r);
+  //for (i=(currRing->N); i!=0; i--)
+  //{
+  //  pAddExp(p,i, pGetExp(q,i));
+  //}
+  //p->Order += q->Order;
+  p_ExpVectorAdd(p,q,r);
+}
+/*3
+* compute for monomials p*q
+* keeps p, q
+* uses bin only available in MCPower
+*/
+static poly p_MonMultCMB(poly p, poly q, ring r)
+{
+  number x;
+  poly res = p_Init(r,lm_bin);
+
+  x = n_Mult(p_GetCoeff(p,r),p_GetCoeff(q,r),r->cf);
+  p_SetCoeff0(res,x,r);
+  p_ExpVectorSum(res,p, q,r);
+  return res;
+}
+static poly p_MonPowerMB(poly p, int exp, ring r)
+{
+  int i;
+
+  if(!n_IsOne(p_GetCoeff(p,r),r->cf))
+  {
+    number x, y;
+    y = p_GetCoeff(p,r);
+    n_Power(y,exp,&x,r->cf);
+    n_Delete(&y,r->cf);
+    p_SetCoeff0(p,x,r);
+  }
+  for (i=rVar(r); i!=0; i--)
+  {
+    p_MultExp(p,i, exp,r);
+  }
+  p_Setm(p,r);
+  return p;
+}
+static void buildTermAndAdd(int /*n*/,number* /*facult*/,poly* /*f_terms*/,int* exp,int f_len,kBucket_pt /*erg_bucket*/,ring r, number coef, poly & zw, poly /*tmp*/, poly** term_pot){
+
+  int i;
+  //  poly term=p_Init(r);
+
+   //  number denom=n_Init(1,r);
+//   for(i=0;i<f_len;i++){
+//     if(exp[i]!=0){
+//       number trash=denom;
+//       denom=n_Mult(denom,facult[exp[i]],r);
+//       n_Delete(&trash,r);
+//     }
+
+//   }
+//   number coef=n_IntDiv(facult[n],denom,r);   //right function here?
+//   n_Delete(&denom,r);
+//   poly erg=p_NSet(coef,r);
+  poly erg=p_Init(r,lm_bin);
+  p_SetCoeff0(erg, coef,r);
+  //p_NSet(n_Copy(coef,r),r);
+  for(i=0;i<f_len;i++){
+    if(exp[i]!=0){
+      ///poly term=p_Copy(f_terms[i],r);
+      poly term=term_pot[i][exp[i]];
+        //tmp;
+        //p_ExpVectorCopy(term,f_terms[i],r);
+        //p_SetCoeff(term, n_Copy(p_GetCoeff(f_terms[i],r),r),r);
+
+      //term->next=NULL;
+
+      //p_MonPowerMB(term, exp[i],r);
+      p_MonMultMB(erg,term,r);
+      //p_Delete(&term,r);
+    }
+
+  }
+  zw=erg;
+}
+
+
+
+static void MC_iterate(poly f, int n, ring r, int f_len,number* facult, int* exp,poly* f_terms,kBucket_pt erg_bucket,int pos,int sum, number coef, poly & zw, poly tmp, poly** term_pot){
+  int i;
+
+  if (pos<f_len-1)
+  {
+    poly zw_l=NULL;
+    number new_coef;
+    for(i=0;i<=n-sum;i++)
+    {
+      exp[pos]=i;
+      if(i==0)
+      {
+        new_coef=n_Copy(coef,r->cf);
+      }
+      else
+      {
+        number old=new_coef;
+        number old_rest=n_Init(n-sum-(i-1),r->cf);
+        new_coef=n_Mult(new_coef,old_rest,r->cf);
+        n_Delete(&old_rest,r->cf);
+        n_Delete(&old,r->cf);
+        number i_number=n_Init(i,r->cf);
+        old=new_coef;
+        new_coef=n_Div(new_coef,i_number,r->cf);
+        n_Normalize(new_coef,r->cf);
+        n_Delete(&old,r->cf);
+        n_Delete(&i_number,r->cf);
+      }
+      //new_coef is
+      //(n                          )
+      //(exp[0]..exp[pos] 0 0 0 rest)
+      poly zw_real=NULL;
+      MC_iterate(f, n, r, f_len,facult, exp,f_terms,erg_bucket,pos+1,sum+i,new_coef,zw_real,tmp,term_pot);
+      if (pos==f_len-2)
+      {
+        //get first small polys
+
+        zw_real->next=zw_l;
+        zw_l=zw_real;
+      }
+      //n_Delete(& new_coef,r->cf);
+    }
+    n_Delete(&new_coef,r->cf);
+    if (pos==f_len-2)
+    {
+      int len=n-sum+1;
+      kBucket_Add_q(erg_bucket,zw_l,&len);
+    }
+    return;
+  }
+  if(pos==f_len-1)
+  {
+    i=n-sum;
+    exp[pos]=i;
+    number new_coef=n_Copy(coef,r->cf);//n_IntDiv(coef,facult[i],r); //really consumed???????
+    buildTermAndAdd(n,facult,f_terms,exp,f_len,erg_bucket,r, new_coef,zw, tmp,term_pot);
+    // n_Delete(& new_coef,r);
+  }
+  assume(pos<=f_len-1);
+}
+poly pFastPowerMC(poly f, int n, ring r)
+{
+  //only char=0
+
+  if(rChar(r)!=0)
+    Werror("Char not 0, pFastPowerMC not implemented for this case");
+  if (n<=1)
+    Werror("not implemented for so small n, recursion fails");//should be length(f)
+   if (pLength(f)<=1)
+    Werror("not implemented for so small lenght of f, recursion fails");
+  //  number null_number=n_Init(0,r);
+  number* facult=(number*) omAlloc((n+1)*sizeof(number));
+  facult[0]=n_Init(1,r->cf);
+  int i;
+  for(i=1;i<=n;i++)
+  {
+    number this_n=n_Init(i,r->cf);
+    facult[i]=n_Mult(this_n,facult[i-1],r->cf);
+    n_Delete(&this_n,r->cf);
+  }
+
+  lm_bin=omGetSpecBin(POLYSIZE + (r->ExpL_Size)*sizeof(long));
+
+  kBucket_pt erg_bucket= kBucketCreate(currRing);
+  kBucketInit(erg_bucket,NULL,0);
+  const int f_len=pLength(f);
+  int* exp=(int*)omAlloc(f_len*sizeof(int));
+  //poly f_terms[f_len];
+  poly* f_terms=(poly*)omAlloc(f_len*sizeof(poly));
+  poly** term_potences=(poly**) omAlloc(f_len*sizeof(poly*));
+
+  poly f_iter=f;
+  for(i=0;i<f_len;i++)
+  {
+    f_terms[i]=f_iter;
+    f_iter=pNext(f_iter);
+  }
+  for(i=0;i<f_len;i++)
+  {
+    term_potences[i]=(poly*)omAlloc((n+1)*sizeof(poly));
+    term_potences[i][0]=p_ISet(1,r);
+    int j;
+    for(j=1;j<=n;j++){
+      term_potences[i][j]=p_MonMultCMB(f_terms[i],term_potences[i][j-1],r);
+    }
+  }
+  assume(f_iter==NULL);
+  poly zw=NULL;
+  poly tmp=p_Init(r);
+  number one=n_Init(1,r->cf);
+  MC_iterate(f,n,r,f_len,&facult[0], &exp[0], &f_terms[0],erg_bucket,0,0,one/*facult[n]*/,zw,tmp, term_potences);
+
+
+  n_Delete(&one,r->cf);
+
+
+
+  //free res
+
+  //free facult
+  for(i=0;i<=n;i++)
+  {
+    n_Delete(&facult[i],r->cf);
+  }
+  int i2;
+  for (i=0;i<f_len;i++)
+  {
+    for(i2=0;i2<=n;i2++)
+    {
+      p_Delete(&term_potences[i][i2],r);
+    }
+    omfree(term_potences[i]);
+
+  }
+  omfree(term_potences);
+  p_Delete(&tmp,r);
+  omfree(exp);
+  omfree(facult);
+  omfree(f_terms);
+  int len=0;
+  poly erg;
+  kBucketClear(erg_bucket,&erg, &len);
+  kBucketDestroy(&erg_bucket);
+  omUnGetSpecBin(&lm_bin);
+  return erg;
+}
diff --git a/kernel/fast_mult.h b/kernel/fast_mult.h
new file mode 100644
index 0000000..43a4344
--- /dev/null
+++ b/kernel/fast_mult.h
@@ -0,0 +1,10 @@
+#ifndef fast_mult_header
+#define fast_mult_header
+#include <kernel/mod2.h>
+#include <kernel/polys.h>
+poly unifastmult(poly f,poly g, ring r);
+poly multifastmult(poly f, poly g, ring r);
+int Mults();
+poly pFastPower(poly f, int n, ring r);
+poly pFastPowerMC(poly f, int n, ring r);
+#endif
diff --git a/kernel/fglm/Makefile.am b/kernel/fglm/Makefile.am
new file mode 100644
index 0000000..e66ae1a
--- /dev/null
+++ b/kernel/fglm/Makefile.am
@@ -0,0 +1,22 @@
+ACLOCAL_AMFLAGS=-I ../../m4
+AM_CPPFLAGS=-I${top_srcdir} -I${top_builddir} -I${top_srcdir}/libpolys -I${top_builddir}/libpolys \
+${FACTORY_INCLUDES} $(OMALLOC_INCLUDES) $(RESOURCES_INCLUDES) \
+${NTL_CFLAGS} $(FLINT_CFLAGS) ${GMP_CFLAGS}
+
+noinst_LTLIBRARIES=libfglm.la
+libfglm_la_SOURCES=fglmzero.cc fglmvec.cc fglmgauss.cc fglmhom.cc fglmcomb.cc
+
+libfglm_la_includedir=$(includedir)/singular/kernel/fglm
+libfglm_la_include_HEADERS=fglm.h fglmgauss.h fglmvec.h
+
+
+
+TESTS_ENVIRONMENT = SINGULARPATH='${abs_top_builddir}/libpolys/polys/.libs:${abs_top_builddir}/factory/gftables'
+TESTS_ENVIRONMENT += SINGULAR_ROOT_DIR='${abs_top_builddir}'
+
+TESTS = test
+check_PROGRAMS = $(TESTS)
+test_SOURCES = test.cc
+test_LDADD   = libfglm.la ${builddir}/../libkernelCommon.la
+
+CLEANFILES = $(TESTS)
diff --git a/kernel/fglm/Makefile.in b/kernel/fglm/Makefile.in
new file mode 100644
index 0000000..67dccf9
--- /dev/null
+++ b/kernel/fglm/Makefile.in
@@ -0,0 +1,1086 @@
+# Makefile.in generated by automake 1.13.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 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@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+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@
+TESTS = test$(EXEEXT)
+check_PROGRAMS = $(am__EXEEXT_1)
+subdir = kernel/fglm
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/build-aux/depcomp $(libfglm_la_include_HEADERS) \
+	$(top_srcdir)/build-aux/test-driver
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_append_compile_flags.m4 \
+	$(top_srcdir)/m4/ax_append_flag.m4 \
+	$(top_srcdir)/m4/ax_append_link_flags.m4 \
+	$(top_srcdir)/m4/ax_check_compile_flag.m4 \
+	$(top_srcdir)/m4/ax_check_link_flag.m4 \
+	$(top_srcdir)/m4/ax_compute_relative_paths.m4 \
+	$(top_srcdir)/m4/ax_normalize_path.m4 \
+	$(top_srcdir)/m4/ax_prefix_config_h.m4 \
+	$(top_srcdir)/m4/ax_pthread.m4 \
+	$(top_srcdir)/m4/ax_python_embed.m4 \
+	$(top_srcdir)/m4/ax_python_with_version.m4 \
+	$(top_srcdir)/m4/cpu-check.m4 $(top_srcdir)/m4/dbm-check.m4 \
+	$(top_srcdir)/m4/flags.m4 $(top_srcdir)/m4/flint-check.m4 \
+	$(top_srcdir)/m4/gfanlib-check.m4 \
+	$(top_srcdir)/m4/gmp-check.m4 \
+	$(top_srcdir)/m4/google-perftools.m4 \
+	$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+	$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+	$(top_srcdir)/m4/lt~obsolete.m4 \
+	$(top_srcdir)/m4/mathic-check.m4 $(top_srcdir)/m4/ntl-check.m4 \
+	$(top_srcdir)/m4/options.m4 $(top_srcdir)/m4/p-procs.m4 \
+	$(top_srcdir)/m4/polymake-check.m4 \
+	$(top_srcdir)/m4/readline-check.m4 $(top_srcdir)/configure.ac
+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 =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+libfglm_la_LIBADD =
+am_libfglm_la_OBJECTS = fglmzero.lo fglmvec.lo fglmgauss.lo fglmhom.lo \
+	fglmcomb.lo
+libfglm_la_OBJECTS = $(am_libfglm_la_OBJECTS)
+AM_V_lt = $(am__v_lt_ at AM_V@)
+am__v_lt_ = $(am__v_lt_ at AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 = 
+am__EXEEXT_1 = test$(EXEEXT)
+am_test_OBJECTS = test.$(OBJEXT)
+test_OBJECTS = $(am_test_OBJECTS)
+test_DEPENDENCIES = libfglm.la ${builddir}/../libkernelCommon.la
+AM_V_P = $(am__v_P_ at AM_V@)
+am__v_P_ = $(am__v_P_ at AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_ at AM_V@)
+am__v_GEN_ = $(am__v_GEN_ at AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_ at AM_V@)
+am__v_at_ = $(am__v_at_ at AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+DEFAULT_INCLUDES = -I. at am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \
+	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+	$(AM_CXXFLAGS) $(CXXFLAGS)
+AM_V_CXX = $(am__v_CXX_ at AM_V@)
+am__v_CXX_ = $(am__v_CXX_ at AM_DEFAULT_V@)
+am__v_CXX_0 = @echo "  CXX     " $@;
+am__v_CXX_1 = 
+CXXLD = $(CXX)
+CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+	$(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CXXLD = $(am__v_CXXLD_ at AM_V@)
+am__v_CXXLD_ = $(am__v_CXXLD_ at AM_DEFAULT_V@)
+am__v_CXXLD_0 = @echo "  CXXLD   " $@;
+am__v_CXXLD_1 = 
+SOURCES = $(libfglm_la_SOURCES) $(test_SOURCES)
+DIST_SOURCES = $(libfglm_la_SOURCES) $(test_SOURCES)
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+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__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
+am__installdirs = "$(DESTDIR)$(libfglm_la_includedir)"
+HEADERS = $(libfglm_la_include_HEADERS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors_dummy = \
+  mgn= red= grn= lgn= blu= brg= std=; \
+  am__color_tests=no
+am__tty_colors = { \
+  $(am__tty_colors_dummy); \
+  if test "X$(AM_COLOR_TESTS)" = Xno; then \
+    am__color_tests=no; \
+  elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+    am__color_tests=yes; \
+  elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+    am__color_tests=yes; \
+  fi; \
+  if test $$am__color_tests = yes; then \
+    red=''; \
+    grn=''; \
+    lgn=''; \
+    blu=''; \
+    mgn=''; \
+    brg=''; \
+    std=''; \
+  fi; \
+}
+am__recheck_rx = ^[ 	]*:recheck:[ 	]*
+am__global_test_result_rx = ^[ 	]*:global-test-result:[ 	]*
+am__copy_in_global_log_rx = ^[ 	]*:copy-in-global-log:[ 	]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+  recheck = 1; \
+  while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+    { \
+      if (rc < 0) \
+        { \
+          if ((getline line2 < ($$0 ".log")) < 0) \
+	    recheck = 0; \
+          break; \
+        } \
+      else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+        { \
+          recheck = 0; \
+          break; \
+        } \
+      else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+        { \
+          break; \
+        } \
+    }; \
+  if (recheck) \
+    print $$0; \
+  close ($$0 ".trs"); \
+  close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+  print "fatal: making $@: " msg | "cat >&2"; \
+  exit 1; \
+} \
+function rst_section(header) \
+{ \
+  print header; \
+  len = length(header); \
+  for (i = 1; i <= len; i = i + 1) \
+    printf "="; \
+  printf "\n\n"; \
+} \
+{ \
+  copy_in_global_log = 1; \
+  global_test_result = "RUN"; \
+  while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+    { \
+      if (rc < 0) \
+         fatal("failed to read from " $$0 ".trs"); \
+      if (line ~ /$(am__global_test_result_rx)/) \
+        { \
+          sub("$(am__global_test_result_rx)", "", line); \
+          sub("[ 	]*$$", "", line); \
+          global_test_result = line; \
+        } \
+      else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+        copy_in_global_log = 0; \
+    }; \
+  if (copy_in_global_log) \
+    { \
+      rst_section(global_test_result ": " $$0); \
+      while ((rc = (getline line < ($$0 ".log"))) != 0) \
+      { \
+        if (rc < 0) \
+          fatal("failed to read from " $$0 ".log"); \
+        print line; \
+      }; \
+      printf "\n"; \
+    }; \
+  close ($$0 ".trs"); \
+  close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/   &   /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this.  Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+  --color-tests "$$am__color_tests" \
+  --enable-hard-errors "$$am__enable_hard_errors" \
+  --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test.  Creates the
+# directory for the log if needed.  Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log.  Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT.  Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup);					\
+$(am__vpath_adj_setup) $(am__vpath_adj)			\
+$(am__tty_colors);					\
+srcdir=$(srcdir); export srcdir;			\
+case "$@" in						\
+  */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;;	\
+    *) am__odir=.;; 					\
+esac;							\
+test "x$$am__odir" = x"." || test -d "$$am__odir" 	\
+  || $(MKDIR_P) "$$am__odir" || exit $$?;		\
+if test -f "./$$f"; then dir=./;			\
+elif test -f "$$f"; then dir=;				\
+else dir="$(srcdir)/"; fi;				\
+tst=$$dir$$f; log='$@'; 				\
+if test -n '$(DISABLE_HARD_ERRORS)'; then		\
+  am__enable_hard_errors=no; 				\
+else							\
+  am__enable_hard_errors=yes; 				\
+fi; 							\
+case " $(XFAIL_TESTS) " in				\
+  *[\ \	]$$f[\ \	]* | *[\ \	]$$dir$$f[\ \	]*) \
+    am__expect_failure=yes;;				\
+  *)							\
+    am__expect_failure=no;;				\
+esac; 							\
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed).  The result is saved in the shell variable
+# '$bases'.  This honors runtime overriding of TESTS and TEST_LOGS.  Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+  bases='$(TEST_LOGS)'; \
+  bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+  bases=`echo $$bases`
+RECHECK_LOGS = $(TEST_LOGS)
+AM_RECURSIVE_TARGETS = check recheck
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+  case '$@' in \
+    */*) \
+      case '$*' in \
+        */*) b='$*';; \
+          *) b=`echo '$@' | sed 's/\.log$$//'`; \
+       esac;; \
+    *) \
+      b='$*';; \
+  esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT at .log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+	$(TEST_LOG_FLAGS)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BUILTIN_LIBS = @BUILTIN_LIBS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CDDGMPCPPFLAGS = @CDDGMPCPPFLAGS@
+CDDGMPLDFLAGS = @CDDGMPLDFLAGS@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATA_DIR = @DATA_DIR@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DOC_DIR = @DOC_DIR@
+DOXYGEN = @DOXYGEN@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FACTORY_INCLUDES = @FACTORY_INCLUDES@
+FACTORY_LIBS = @FACTORY_LIBS@
+FGREP = @FGREP@
+FLINT_CFLAGS = @FLINT_CFLAGS@
+FLINT_HOME = @FLINT_HOME@
+FLINT_LIBS = @FLINT_LIBS@
+GMP_CFLAGS = @GMP_CFLAGS@
+GMP_HOME = @GMP_HOME@
+GMP_LIBS = @GMP_LIBS@
+GMP_VERSION = @GMP_VERSION@
+GREP = @GREP@
+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@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NTL_CFLAGS = @NTL_CFLAGS@
+NTL_LIBS = @NTL_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OMALLOC_INCLUDES = @OMALLOC_INCLUDES@
+OMALLOC_LIBS = @OMALLOC_LIBS@
+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@
+PKG_REQUIRE = @PKG_REQUIRE@
+PMCONFIG = @PMCONFIG@
+PM_CFLAGS = @PM_CFLAGS@
+PM_INC = @PM_INC@
+PM_LDFLAGS = @PM_LDFLAGS@
+PM_LIBS = @PM_LIBS@
+POLYMAKE_CXXFLAGS = @POLYMAKE_CXXFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LDFLAGS = @PTHREAD_LDFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
+PYTHON = @PYTHON@
+PYTHON_CSPEC = @PYTHON_CSPEC@
+PYTHON_EXECPREFIX = @PYTHON_EXECPREFIX@
+PYTHON_LSPEC = @PYTHON_LSPEC@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+RANLIB = @RANLIB@
+RESOURCES_INCLUDES = @RESOURCES_INCLUDES@
+RESOURCES_LIBS = @RESOURCES_LIBS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SINGULAR_CFLAGS = @SINGULAR_CFLAGS@
+SI_COUNTEDREF_AUTOLOAD = @SI_COUNTEDREF_AUTOLOAD@
+SI_CPU_I386 = @SI_CPU_I386@
+SI_CPU_IA64 = @SI_CPU_IA64@
+SI_CPU_PPC = @SI_CPU_PPC@
+SI_CPU_SPARC = @SI_CPU_SPARC@
+SI_CPU_X86_64 = @SI_CPU_X86_64@
+STRIP = @STRIP@
+USEPPROCSDYNAMICLD = @USEPPROCSDYNAMICLD@
+USEPPROCSDYNAMICLDFLAGS = @USEPPROCSDYNAMICLDFLAGS@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
+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@
+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@
+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@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+ACLOCAL_AMFLAGS = -I ../../m4
+AM_CPPFLAGS = -I${top_srcdir} -I${top_builddir} -I${top_srcdir}/libpolys -I${top_builddir}/libpolys \
+${FACTORY_INCLUDES} $(OMALLOC_INCLUDES) $(RESOURCES_INCLUDES) \
+${NTL_CFLAGS} $(FLINT_CFLAGS) ${GMP_CFLAGS}
+
+noinst_LTLIBRARIES = libfglm.la
+libfglm_la_SOURCES = fglmzero.cc fglmvec.cc fglmgauss.cc fglmhom.cc fglmcomb.cc
+libfglm_la_includedir = $(includedir)/singular/kernel/fglm
+libfglm_la_include_HEADERS = fglm.h fglmgauss.h fglmvec.h
+TESTS_ENVIRONMENT = SINGULARPATH='${abs_top_builddir}/libpolys/polys/.libs:${abs_top_builddir}/factory/gftables' \
+	SINGULAR_ROOT_DIR='${abs_top_builddir}'
+test_SOURCES = test.cc
+test_LDADD = libfglm.la ${builddir}/../libkernelCommon.la
+CLEANFILES = $(TESTS)
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .cc .lo .log .o .obj .test .test$(EXEEXT) .trs
+$(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) --foreign kernel/fglm/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign kernel/fglm/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-noinstLTLIBRARIES:
+	-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+	@list='$(noinst_LTLIBRARIES)'; \
+	locs=`for p in $$list; do echo $$p; done | \
+	      sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+	      sort -u`; \
+	test -z "$$locs" || { \
+	  echo rm -f $${locs}; \
+	  rm -f $${locs}; \
+	}
+
+libfglm.la: $(libfglm_la_OBJECTS) $(libfglm_la_DEPENDENCIES) $(EXTRA_libfglm_la_DEPENDENCIES) 
+	$(AM_V_CXXLD)$(CXXLINK)  $(libfglm_la_OBJECTS) $(libfglm_la_LIBADD) $(LIBS)
+
+clean-checkPROGRAMS:
+	@list='$(check_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
+
+test$(EXEEXT): $(test_OBJECTS) $(test_DEPENDENCIES) $(EXTRA_test_DEPENDENCIES) 
+	@rm -f test$(EXEEXT)
+	$(AM_V_CXXLD)$(CXXLINK) $(test_OBJECTS) $(test_LDADD) $(LIBS)
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/fglmcomb.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/fglmgauss.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/fglmhom.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/fglmvec.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/fglmzero.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/test.Po at am__quote@
+
+.cc.o:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+ at am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXXCOMPILE) -c -o $@ $<
+
+.cc.obj:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+ at am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.cc.lo:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+ at am__fastdepCXX_TRUE@	$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LTCXXCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+install-libfglm_la_includeHEADERS: $(libfglm_la_include_HEADERS)
+	@$(NORMAL_INSTALL)
+	@list='$(libfglm_la_include_HEADERS)'; test -n "$(libfglm_la_includedir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(libfglm_la_includedir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(libfglm_la_includedir)" || exit 1; \
+	fi; \
+	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)$(libfglm_la_includedir)'"; \
+	  $(INSTALL_HEADER) $$files "$(DESTDIR)$(libfglm_la_includedir)" || exit $$?; \
+	done
+
+uninstall-libfglm_la_includeHEADERS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(libfglm_la_include_HEADERS)'; test -n "$(libfglm_la_includedir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	dir='$(DESTDIR)$(libfglm_la_includedir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	$(am__define_uniq_tagged_files); \
+	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-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	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"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'.  Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+	rm -f $< $@
+	$(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+	@:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+	@$(am__set_TESTS_bases); \
+	am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+	redo_bases=`for i in $$bases; do \
+	              am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+	            done`; \
+	if test -n "$$redo_bases"; then \
+	  redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+	  redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+	  if $(am__make_dryrun); then :; else \
+	    rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+	  fi; \
+	fi; \
+	if test -n "$$am__remaking_logs"; then \
+	  echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+	       "recursion detected" >&2; \
+	else \
+	  am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+	fi; \
+	if $(am__make_dryrun); then :; else \
+	  st=0;  \
+	  errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+	  for i in $$redo_bases; do \
+	    test -f $$i.trs && test -r $$i.trs \
+	      || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+	    test -f $$i.log && test -r $$i.log \
+	      || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+	  done; \
+	  test $$st -eq 0 || exit 1; \
+	fi
+	@$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+	ws='[ 	]'; \
+	results=`for b in $$bases; do echo $$b.trs; done`; \
+	test -n "$$results" || results=/dev/null; \
+	all=`  grep "^$$ws*:test-result:"           $$results | wc -l`; \
+	pass=` grep "^$$ws*:test-result:$$ws*PASS"  $$results | wc -l`; \
+	fail=` grep "^$$ws*:test-result:$$ws*FAIL"  $$results | wc -l`; \
+	skip=` grep "^$$ws*:test-result:$$ws*SKIP"  $$results | wc -l`; \
+	xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+	xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+	error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+	if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+	  success=true; \
+	else \
+	  success=false; \
+	fi; \
+	br='==================='; br=$$br$$br$$br$$br; \
+	result_count () \
+	{ \
+	    if test x"$$1" = x"--maybe-color"; then \
+	      maybe_colorize=yes; \
+	    elif test x"$$1" = x"--no-color"; then \
+	      maybe_colorize=no; \
+	    else \
+	      echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+	    fi; \
+	    shift; \
+	    desc=$$1 count=$$2; \
+	    if test $$maybe_colorize = yes && test $$count -gt 0; then \
+	      color_start=$$3 color_end=$$std; \
+	    else \
+	      color_start= color_end=; \
+	    fi; \
+	    echo "$${color_start}# $$desc $$count$${color_end}"; \
+	}; \
+	create_testsuite_report () \
+	{ \
+	  result_count $$1 "TOTAL:" $$all   "$$brg"; \
+	  result_count $$1 "PASS: " $$pass  "$$grn"; \
+	  result_count $$1 "SKIP: " $$skip  "$$blu"; \
+	  result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+	  result_count $$1 "FAIL: " $$fail  "$$red"; \
+	  result_count $$1 "XPASS:" $$xpass "$$red"; \
+	  result_count $$1 "ERROR:" $$error "$$mgn"; \
+	}; \
+	{								\
+	  echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" |	\
+	    $(am__rst_title);						\
+	  create_testsuite_report --no-color;				\
+	  echo;								\
+	  echo ".. contents:: :depth: 2";				\
+	  echo;								\
+	  for b in $$bases; do echo $$b; done				\
+	    | $(am__create_global_log);					\
+	} >$(TEST_SUITE_LOG).tmp || exit 1;				\
+	mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG);			\
+	if $$success; then						\
+	  col="$$grn";							\
+	 else								\
+	  col="$$red";							\
+	  test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG);		\
+	fi;								\
+	echo "$${col}$$br$${std}"; 					\
+	echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}";	\
+	echo "$${col}$$br$${std}"; 					\
+	create_testsuite_report --maybe-color;				\
+	echo "$$col$$br$$std";						\
+	if $$success; then :; else					\
+	  echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}";		\
+	  if test -n "$(PACKAGE_BUGREPORT)"; then			\
+	    echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}";	\
+	  fi;								\
+	  echo "$$col$$br$$std";					\
+	fi;								\
+	$$success || exit 1
+
+check-TESTS:
+	@list='$(RECHECK_LOGS)';           test -z "$$list" || rm -f $$list
+	@list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+	@test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+	@set +e; $(am__set_TESTS_bases); \
+	log_list=`for i in $$bases; do echo $$i.log; done`; \
+	trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+	log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+	$(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+	exit $$?;
+recheck: all $(check_PROGRAMS)
+	@test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+	@set +e; $(am__set_TESTS_bases); \
+	bases=`for i in $$bases; do echo $$i; done \
+	         | $(am__list_recheck_tests)` || exit 1; \
+	log_list=`for i in $$bases; do echo $$i.log; done`; \
+	log_list=`echo $$log_list`; \
+	$(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+	        am__force_recheck=am--force-recheck \
+	        TEST_LOGS="$$log_list"; \
+	exit $$?
+test.log: test$(EXEEXT)
+	@p='test$(EXEEXT)'; \
+	b='test'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+.test.log:
+	@p='$<'; \
+	$(am__set_b); \
+	$(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+ at am__EXEEXT_TRUE@.test$(EXEEXT).log:
+ at am__EXEEXT_TRUE@	@p='$<'; \
+ at am__EXEEXT_TRUE@	$(am__set_b); \
+ at am__EXEEXT_TRUE@	$(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ at am__EXEEXT_TRUE@	--log-file $$b.log --trs-file $$b.trs \
+ at am__EXEEXT_TRUE@	$(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ at am__EXEEXT_TRUE@	"$$tst" $(AM_TESTS_FD_REDIRECT)
+
+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_PROGRAMS)
+	$(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(HEADERS)
+installdirs:
+	for dir in "$(DESTDIR)$(libfglm_la_includedir)"; 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:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+	-test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+	-test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+	-test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+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-checkPROGRAMS clean-generic clean-libtool \
+	clean-noinstLTLIBRARIES 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-libfglm_la_includeHEADERS
+
+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: uninstall-libfglm_la_includeHEADERS
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am clean \
+	clean-checkPROGRAMS clean-generic clean-libtool \
+	clean-noinstLTLIBRARIES cscopelist-am ctags ctags-am 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-libfglm_la_includeHEADERS 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 \
+	recheck tags tags-am uninstall uninstall-am \
+	uninstall-libfglm_la_includeHEADERS
+
+
+# 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/kernel/fglm/fglm.h b/kernel/fglm/fglm.h
new file mode 100644
index 0000000..8f31b78
--- /dev/null
+++ b/kernel/fglm/fglm.h
@@ -0,0 +1,85 @@
+// emacs edit mode for this file is -*- C++ -*-
+
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT - The FGLM-Algorithm
+*   The main header file for the fglm algorithm
+*   (See fglm.cc for details)
+*/
+
+#ifndef FGLM_H
+#define FGLM_H
+
+#include <kernel/polys.h>
+#include <kernel/structs.h>
+#include <kernel/fglm/fglmvec.h>
+
+#define PROT(msg)
+#define STICKYPROT(msg) if (BTEST1(OPT_PROT)) Print(msg)
+#define PROT2(msg,arg)
+#define STICKYPROT2(msg,arg) if (BTEST1(OPT_PROT)) Print(msg,arg)
+#define fglmASSERT(ignore1,ignore2)
+
+// internal Version: 1.10.1.4
+// Some data types needed by the fglm algorithm. claptmpl.cc has to know them.
+class fglmSelem
+{
+public:
+    int * divisors;
+    poly monom;
+    int numVars;
+    fglmSelem( poly p, int var );
+
+    void cleanup();
+    BOOLEAN isBasisOrEdge() const { return ( (divisors[0] == numVars) ? TRUE : FALSE ); }
+    void newDivisor( int var ) { divisors[ ++divisors[0] ]= var; }
+//#ifndef NOSTREAMIO
+//friend OSTREAM & operator <<(OSTREAM &, fglmSelem);
+//#endif
+};
+//#ifndef NOSTREAMIO
+//inline OSTREAM & operator <<(OSTREAM & os, fglmSelem) { return os;};
+//#endif
+
+class fglmDelem
+{
+public:
+    poly monom;
+    fglmVector v;
+    int insertions;
+    int var;
+    fglmDelem( poly & m, fglmVector mv, int v );
+
+    void cleanup();
+    BOOLEAN isBasisOrEdge() const { return ( (insertions == 0) ? TRUE : FALSE ); }
+    void newDivisor() { insertions--; }
+//#ifndef NOSTREAMIO
+//friend OSTREAM & operator <<(OSTREAM &, fglmDelem);
+//#endif
+};
+//#ifndef NOSTREAMIO
+//inline OSTREAM & operator <<(OSTREAM & os, fglmDelem) { return os;};
+//#endif
+
+// fglmzero(...):
+// The fglm algorithm for 0-dimensional ideals. ( fglmzero is defined in fglmzero.cc )
+// Calculates the reduced groebner basis of sourceIdeal in destRing.
+// The sourceIdeal has to be a reduced, 0-dimensional groebner basis in sourceRing.
+// Warning: There is no check, if the ideal is really 0-dimensional and minimal.
+// If it is minimal but not reduced, then it returns FALSE, otherwise TRUE.
+// Warning: There is no check, if the rings are compatible for fglm (see
+// fglm.cc for functions to check this)
+// if switchBack==TRUE, then the procedure sets the ring as currentRing which was
+// current when it was called ( When called there may be currRing != sourceRing ).
+// if switchBack==FALSE, then currRing==destRing at the end.
+// if deleteIdeal==TRUE then sourceIdeal is deleted (in any case, even if the
+// procedure fails)
+// if deleteIdeal==FALSE, then nothing happens to sourceIdeal
+BOOLEAN
+fglmzero( ring sourceRing, ideal & sourceIdeal, ring destRing, ideal & destideal, BOOLEAN switchBack = TRUE, BOOLEAN deleteIdeal = FALSE );
+
+BOOLEAN fglmquot( ideal sourceIdeal, poly quot, ideal & destIdeal );
+
+#endif
diff --git a/kernel/fglm/fglmcomb.cc b/kernel/fglm/fglmcomb.cc
new file mode 100644
index 0000000..31510fa
--- /dev/null
+++ b/kernel/fglm/fglmcomb.cc
@@ -0,0 +1,557 @@
+// emacs edit mode for this file is -*- C++ -*-
+
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT -
+*/
+
+
+
+
+#include <kernel/mod2.h>
+
+#include <factory/factory.h>
+#include <misc/options.h>
+#include <kernel/polys.h>
+#include <kernel/ideals.h>
+#include <polys/monomials/ring.h>
+#include <polys/monomials/maps.h>
+#include <omalloc/omalloc.h>
+#include "fglmvec.h"
+#include "fglmgauss.h"
+#include <kernel/GBEngine/kstd1.h>
+
+#include "fglm.h"
+
+#ifndef NOSTREAMIO
+#  ifdef HAVE_IOSTREAM
+#    include <iostream>
+#  else
+#    include <iostream.h>
+#  endif
+#endif
+
+static void
+fglmEliminateMonomials( poly * pptr, fglmVector & v, polyset monomials, int numMonoms )
+{
+    poly temp = *pptr;
+    poly pretemp = NULL;
+    int point = 0;
+    int state;
+
+    while ( (temp != NULL) && (point < numMonoms) ) {
+        state= pCmp( temp, monomials[point] );
+        if ( state == 0 ) {
+            // Eliminate this monomial
+            poly todelete;
+            if ( pretemp == NULL ) {
+                todelete = temp;
+                pIter( *pptr );
+                temp= *pptr;
+            }
+            else {
+                todelete= temp;
+                pIter( temp );
+                pretemp->next= temp;
+            }
+            pGetCoeff( todelete )= nInpNeg( pGetCoeff( todelete ) );
+            number newelem = nAdd( pGetCoeff( todelete ), v.getconstelem( point+1 ) );
+            v.setelem( point+1, newelem );
+            nDelete( & pGetCoeff( todelete ) );
+            pLmFree( todelete );
+            point++;
+        }
+        else if ( state < 0 )
+            point++;
+        else {
+            pretemp= temp;
+            pIter( temp );
+        }
+    }
+}
+
+static BOOLEAN
+fglmReductionStep( poly * pptr, ideal source, int * w )
+{
+// returns TRUE if the leading monomial was reduced
+    if ( *pptr == NULL ) return FALSE;
+    int k;
+    int best = 0;
+    for ( k= IDELEMS( source ) - 1; k >= 0; k-- ) {
+        if ( pDivisibleBy( (source->m)[k], *pptr ) ) {
+            if ( best == 0 ) {
+                best= k + 1;
+            }
+            else {
+                if ( w[k] < w[best-1] ) {
+                    best= k + 1;
+                }
+            }
+        }
+    }
+    if ( best > 0 ) {
+        // OwnSPoly
+        poly p2 = (source->m)[best-1];
+        int i, diff;
+
+        poly m = pOne();
+        for ( i= (currRing->N); i > 0; i-- )
+	{
+            diff= pGetExp( *pptr, i ) - pGetExp( p2, i );
+            pSetExp( m, i, diff );
+        }
+        pSetm( m );
+        number n1 = nCopy( pGetCoeff( *pptr ) );
+        number n2 = pGetCoeff( p2 );
+
+        p2= pCopy( p2 );
+        pLmDelete(pptr);
+        pLmDelete( & p2 );
+        p2= pMult( m, p2 );
+
+        number temp = nDiv( n1, n2 );
+        n_Normalize( temp, currRing );
+        nDelete( & n1 );
+        n1= temp;
+        n1= nInpNeg( n1 );
+        pMult_nn( p2, n1 );
+//         pNormalize( p2 );
+        nDelete( & n1 );
+        *pptr= pAdd( *pptr, p2 );
+    }
+    return ( (best > 0) );
+}
+
+static void
+fglmReduce( poly * pptr, fglmVector & v, polyset m, int numMonoms, ideal source, int * w )
+{
+    BOOLEAN reduced = FALSE;
+    reduced= fglmReductionStep( pptr, source, w );
+    while ( reduced == TRUE ) {
+        fglmEliminateMonomials( pptr, v, m, numMonoms );
+        reduced= fglmReductionStep( pptr, source, w );
+    }
+    STICKYPROT( "<" );
+    poly temp = * pptr;
+    if ( temp != NULL ) {
+        while ( pNext( temp ) != NULL ) {
+            STICKYPROT( ">" );
+            reduced= fglmReductionStep( & pNext( temp ), source, w );
+            while ( reduced == TRUE ) {
+                fglmEliminateMonomials( & pNext( temp ), v, m, numMonoms );
+                reduced= fglmReductionStep( & pNext( temp ), source, w );
+            }
+            if ( pNext( temp ) != NULL ) {
+                pIter( temp );
+            }
+        }
+    }
+}
+
+static poly
+fglmNewLinearCombination( ideal source, poly monset )
+{
+    polyset m = NULL;
+    polyset nf = NULL;
+    fglmVector * mv = NULL;
+
+    fglmVector * v = NULL;
+    polyset basis = NULL;
+    int basisSize = 0;
+    int basisBS = 16;
+    int basisMax = basisBS;
+
+    int * weights = NULL;
+    int * lengthes = NULL;
+    int * order = NULL;
+
+    int numMonoms = 0;
+    int k;
+
+    // get number of monoms
+    numMonoms= pLength( monset );
+    STICKYPROT2( "%i monoms\n", numMonoms );
+
+    // Allcoate Memory and initialize sets
+    m= (polyset)omAlloc( numMonoms * sizeof( poly ) );
+    poly temp= monset;
+    for ( k= 0; k < numMonoms; k++ ) {
+//         m[k]= pOne();
+//         pSetExpV( m[k], temp->exp );
+//         pSetm( m[k] );
+        m[k]=pLmInit(temp);
+        pSetCoeff( m[k], nInit(1) );
+        pIter( temp );
+    }
+
+    nf= (polyset)omAlloc( numMonoms * sizeof( poly ) );
+
+#ifndef HAVE_EXPLICIT_CONSTR
+    mv= new fglmVector[ numMonoms ];
+#else
+    mv= (fglmVector *)omAlloc( numMonoms * sizeof( fglmVector ) );
+#endif
+
+#ifndef HAVE_EXPLICIT_CONSTR
+    v= new fglmVector[ numMonoms ];
+#else
+    v= (fglmVector *)omAlloc( numMonoms * sizeof( fglmVector ) );
+#endif
+
+    basisMax= basisBS;
+    basis= (polyset)omAlloc( basisMax * sizeof( poly ) );
+
+    weights= (int *)omAlloc( IDELEMS( source ) * sizeof( int ) );
+    STICKYPROT( "weights: " );
+    for ( k= 0; k < IDELEMS( source ); k++ ) {
+        poly temp= (source->m)[k];
+        int w = 0;
+        while ( temp != NULL ) {
+            w+= nSize( pGetCoeff( temp ) );
+            pIter( temp );
+        }
+        weights[k]= w;
+        STICKYPROT2( "%i ", w );
+    }
+    STICKYPROT( "\n" );
+    lengthes= (int *)omAlloc( numMonoms * sizeof( int ) );
+    order= (int *)omAlloc( numMonoms * sizeof( int ) );
+
+    // calculate the NormalForm in a special way
+    for ( k= 0; k < numMonoms; k++ )
+    {
+        STICKYPROT( "#" );
+        poly current = pCopy( m[k] );
+        fglmVector currV( numMonoms, k+1 );
+
+        fglmReduce( & current, currV, m, numMonoms, source, weights );
+        poly temp = current;
+        int b;
+        while ( temp != NULL )
+        {
+            BOOLEAN found = FALSE;
+            for ( b= 0; (b < basisSize) && (found == FALSE); b++ )
+            {
+                if ( pLmEqual( temp, basis[b] ) )
+                {
+                    found= TRUE;
+                }
+            }
+            if ( found == FALSE )
+            {
+                if ( basisSize == basisMax )
+                {
+                    // Expand the basis
+                    basis= (polyset)omReallocSize( basis, basisMax * sizeof( poly ), (basisMax + basisBS ) * sizeof( poly ) );
+                    basisMax+= basisBS;
+                }
+//                 basis[basisSize]= pOne();
+//                 pSetExpV( basis[basisSize], temp->exp );
+//                 pSetm( basis[basisSize] );
+                basis[basisSize]=pLmInit(temp);
+                pSetCoeff( basis[basisSize], nInit(1) );
+                basisSize++;
+            }
+            pIter( temp );
+        }
+        nf[k]= current;
+#ifndef HAVE_EXPLICIT_CONSTR
+        mv[k].mac_constr( currV );
+#else
+        mv[k].fglmVector( currV );
+#endif
+        STICKYPROT( "\n" );
+    }
+    // get the vector representation
+    for ( k= 0; k < numMonoms; k++ ) {
+        STICKYPROT( "." );
+
+#ifndef HAVE_EXPLICIT_CONSTR
+        v[k].mac_constr_i( basisSize );
+#else
+        v[k].fglmVector( basisSize );
+#endif
+        poly mon= nf[k];
+        while ( mon != NULL ) {
+            BOOLEAN found = FALSE;
+            int b= 0;
+            while ( found == FALSE ) {
+                if ( pLmEqual( mon, basis[b] ) ) {
+                    found= TRUE;
+                }
+                else {
+                    b++;
+                }
+            }
+            number coeff = nCopy( pGetCoeff( mon ) );
+            v[k].setelem( b+1, coeff );
+            pIter( mon );
+        }
+        pDelete( nf + k );
+    }
+    // Free Memory not needed anymore
+    omFreeSize( (ADDRESS)nf, numMonoms * sizeof( poly ) );
+    omFreeSize( (ADDRESS)weights, IDELEMS( source ) * sizeof( int ) );
+
+    STICKYPROT2( "\nbasis size: %i\n", basisSize );
+    STICKYPROT( "(clear basis" );
+    for ( k= 0; k < basisSize; k++ )
+        pDelete( basis + k );
+    STICKYPROT( ")\n" );
+    // gauss reduce
+    gaussReducer gauss( basisSize );
+    BOOLEAN isZero = FALSE;
+    fglmVector p;
+
+    STICKYPROT( "sizes: " );
+    for ( k= 0; k < numMonoms; k++ ) {
+        lengthes[k]= v[k].numNonZeroElems();
+        STICKYPROT2( "%i ", lengthes[k] );
+    }
+    STICKYPROT( "\n" );
+
+    int act = 0;
+    while ( (isZero == FALSE) && (act < numMonoms) ) {
+        int best = 0;
+        for ( k= numMonoms - 1; k >= 0; k-- ) {
+            if ( lengthes[k] > 0 ) {
+                if ( best == 0 ) {
+                    best= k+1;
+                }
+                else {
+                    if ( lengthes[k] < lengthes[best-1] ) {
+                        best= k+1;
+                    }
+                }
+            }
+        }
+        lengthes[best-1]= 0;
+        order[act]= best-1;
+        STICKYPROT2( " (%i) ", best );
+        if ( ( isZero= gauss.reduce( v[best-1] )) == TRUE ) {
+            p= gauss.getDependence();
+        }
+        else {
+            STICKYPROT( "+" );
+            gauss.store();
+            act++;
+        }
+#ifndef HAVE_EXPLICIT_CONSTR
+        v[best-1].clearelems();
+#else
+        v[best-1].~fglmVector();
+#endif
+    }
+    poly result = NULL;
+    if ( isZero == TRUE ) {
+        number gcd = p.gcd();
+        if ( ! nIsZero( gcd ) && ! ( nIsOne( gcd ) ) ) {
+            p/= gcd;
+        }
+        nDelete( & gcd );
+        fglmVector temp( numMonoms );
+        for ( k= 0; k < p.size(); k++ ) {
+            if ( ! p.elemIsZero( k+1 ) ) {
+                temp+= p.getconstelem( k+1 ) * mv[order[k]];
+            }
+        }
+        number denom = temp.clearDenom();
+        nDelete( & denom );
+        gcd = temp.gcd();
+        if ( ! nIsZero( gcd ) && ! nIsOne( gcd ) ) {
+            temp/= gcd;
+        }
+        nDelete( & gcd );
+
+        poly sum = NULL;
+        for ( k= 1; k <= numMonoms; k++ ) {
+            if ( ! temp.elemIsZero( k ) ) {
+                if ( result == NULL ) {
+                    result= pCopy( m[k-1] );
+                    sum= result;
+                }
+                else {
+                    sum->next= pCopy( m[k-1] );
+                    pIter( sum );
+                }
+                pSetCoeff( sum, nCopy( temp.getconstelem( k ) ) );
+            }
+        }
+        p_Content( result, currRing );
+        if ( ! nGreaterZero( pGetCoeff( result ) ) ) result= pNeg( result );
+    }
+    // Free Memory
+    omFreeSize( (ADDRESS)lengthes, numMonoms * sizeof( int ) );
+    omFreeSize( (ADDRESS)order, numMonoms * sizeof( int ) );
+//     for ( k= 0; k < numMonoms; k++ )
+//         v[k].~fglmVector();
+#ifndef HAVE_EXPLICIT_CONSTR
+    delete [] v;
+#else
+    omFreeSize( (ADDRESS)v, numMonoms * sizeof( fglmVector ) );
+#endif
+
+    for ( k= 0; k < basisSize; k++ )
+        pDelete( basis + k );
+    omFreeSize( (ADDRESS)basis, basisMax * sizeof( poly ) );
+
+#ifndef HAVE_EXPLICIT_CONSTR
+    delete [] mv;
+#else
+    for ( k= 0; k < numMonoms; k++ )
+        mv[k].~fglmVector();
+    omFreeSize( (ADDRESS)mv, numMonoms * sizeof( fglmVector ) );
+#endif
+
+    for ( k= 0; k < numMonoms; k++ )
+        pDelete( m + k );
+    omFreeSize( (ADDRESS)m, numMonoms * sizeof( poly ) );
+
+    STICKYPROT( "\n" );
+    return result;
+}
+
+
+static poly
+fglmLinearCombination( ideal source, poly monset )
+{
+    int k;
+    poly temp;
+
+    polyset m;
+    polyset nf;
+    fglmVector * v;
+
+    polyset basis;
+    int basisSize = 0;
+    int basisBS = 16;
+    int basisMax;
+    // get number of monomials in monset
+    int numMonoms = 0;
+    temp = monset;
+    while ( temp != NULL ) {
+        numMonoms++;
+        pIter( temp );
+    }
+    // Allocate Memory
+    m= (polyset)omAlloc( numMonoms * sizeof( poly ) );
+    nf= (polyset)omAlloc( numMonoms * sizeof( poly ) );
+    // Warning: The fglmVectors in v are yet not initialized
+    v= (fglmVector *)omAlloc( numMonoms * sizeof( fglmVector ) );
+    basisMax= basisBS;
+    basis= (polyset)omAlloc( basisMax * sizeof( poly ) );
+
+    // get the NormalForm and the basis monomials
+    temp= monset;
+    for ( k= 0; k < numMonoms; k++ ) {
+        poly mon= pHead( temp );
+        if ( ! nIsOne( pGetCoeff( mon ) ) ) {
+            nDelete( & pGetCoeff( mon ) );
+            pSetCoeff( mon, nInit( 1 ) );
+        }
+        STICKYPROT( "(" );
+        nf[k]= kNF( source, currRing->qideal, mon );
+        STICKYPROT( ")" );
+
+        // search through basis
+        STICKYPROT( "[" );
+        poly sm = nf[k];
+        while ( sm != NULL ) {
+            BOOLEAN found = FALSE;
+            int b;
+            for ( b= 0; (b < basisSize) && (found == FALSE); b++ )
+                if ( pLmEqual( sm, basis[b] ) ) found= TRUE;
+            if ( found == FALSE ) {
+                // Expand the basis
+                if ( basisSize == basisMax ) {
+                    basis= (polyset)omReallocSize( basis, basisMax * sizeof( poly ), (basisMax + basisBS ) * sizeof( poly ) );
+                    basisMax+= basisBS;
+                }
+                basis[basisSize]= pHead( sm );
+                nDelete( & pGetCoeff( basis[basisSize] ) );
+                pSetCoeff( basis[basisSize], nInit( 1 ) );
+                basisSize++;
+            }
+            pIter( sm );
+        }
+        STICKYPROT( "]" );
+        m[k]= mon;
+        pIter( temp );
+    }
+    // get the vector representation
+    STICKYPROT2( "(%i)", basisSize );
+    for ( k= 0; k < numMonoms; k++ ) {
+#ifndef HAVE_EXPLICIT_CONSTR
+        v[k].mac_constr_i( basisSize );
+#else
+        v[k].fglmVector( basisSize );
+#endif
+        STICKYPROT( "(+" );
+        poly mon= nf[k];
+        while ( mon != NULL ) {
+            BOOLEAN found = FALSE;
+            int b= 0;
+            while ( found == FALSE ) {
+                if ( pLmEqual( mon, basis[b] ) )
+                    found= TRUE;
+                else
+                    b++;
+            }
+            number coeff = nCopy( pGetCoeff( mon ) );
+            v[k].setelem( b+1, coeff );
+            pIter( mon );
+        }
+        STICKYPROT( ")" );
+    }
+    // gauss reduce
+    gaussReducer gauss( basisSize );
+    BOOLEAN isZero = FALSE;
+    fglmVector p;
+    for ( k= 0; (k < numMonoms) && (isZero == FALSE); k++ ) {
+        STICKYPROT( "(-" );
+        if ( ( isZero= gauss.reduce( v[k] )) == TRUE )
+            p= gauss.getDependence();
+        else
+            gauss.store();
+        STICKYPROT( ")" );
+    }
+    poly comb = NULL;
+    if ( isZero == TRUE ) {
+        number gcd = p.gcd();
+        if ( ! nIsZero( gcd ) && ! ( nIsOne( gcd ) ) )
+            p/= gcd;
+        nDelete( & gcd );
+        for ( k= 1; k <= p.size(); k++ ) {
+            if ( ! p.elemIsZero( k ) ) {
+                poly temp = pCopy( m[k-1] );
+                pSetCoeff( temp, nCopy( p.getconstelem( k ) ) );
+                comb= pAdd( comb, temp );
+            }
+        }
+        if ( ! nGreaterZero( pGetCoeff( comb ) ) ) comb= pNeg( comb );
+    }
+
+    // Free Memory
+    for ( k= 0; k < numMonoms; k++ ) {
+        pDelete( m + k );
+        pDelete( nf + k );
+    }
+    omFreeSize( (ADDRESS)m, numMonoms * sizeof( poly ) );
+    omFreeSize( (ADDRESS)nf, numMonoms * sizeof( poly ) );
+    // Warning: At this point all Vectors in v have to be initialized
+    for ( k= numMonoms - 1; k >= 0; k-- ) v[k].~fglmVector();
+    omFreeSize( (ADDRESS)v, numMonoms * sizeof( fglmVector ) );
+    for ( k= 0; k < basisSize; k++ )
+        pDelete( basis + k );
+    omFreeSize( (ADDRESS)basis, basisMax * sizeof( poly ) );
+    STICKYPROT( "\n" );
+    return comb;
+}
+
+// Local Variables: ***
+// compile-command: "make Singular" ***
+// page-delimiter: "^\\(
\\|//!\\)" ***
+// fold-internal-margins: nil ***
+// End: ***
diff --git a/kernel/fglm/fglmgauss.cc b/kernel/fglm/fglmgauss.cc
new file mode 100644
index 0000000..f4424eb
--- /dev/null
+++ b/kernel/fglm/fglmgauss.cc
@@ -0,0 +1,212 @@
+// emacs edit mode for this file is -*- C++ -*-
+
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT - class gaussReducer. Used in fglmzero.cc and fglmhom.cc
+*  to find linear dependecies of fglmVectors.
+*/
+
+
+
+
+#include <kernel/mod2.h>
+
+#include <kernel/structs.h>
+#include <coeffs/numbers.h>
+#include <polys/monomials/ring.h>
+#include <omalloc/omalloc.h>
+
+#include "fglmvec.h"
+#include "fglmgauss.h"
+
+class gaussElem
+{
+public:
+    fglmVector v;
+    fglmVector p;
+    number pdenom;
+    number fac;
+    gaussElem( const fglmVector newv, const fglmVector newp, number & newpdenom, number & newfac ) : v( newv ), p( newp ), pdenom( newpdenom ), fac( newfac )
+    {
+        newpdenom= NULL;
+        newfac= NULL;
+    }
+
+#ifndef HAVE_EXPLICIT_CONSTR
+  gaussElem() : v(), p(), pdenom(NULL), fac(NULL) {}
+
+  void mac_gaussElem( const fglmVector newv, const fglmVector newp, number & newpdenom, number & newfac )
+    {
+    v= newv;
+    p= newp;
+    pdenom=newpdenom;
+    fac=newfac;
+        newpdenom= NULL;
+        newfac= NULL;
+    }
+#endif
+
+    ~gaussElem()
+    {
+        nDelete( & pdenom );
+        nDelete( & fac );
+    }
+};
+
+gaussReducer::gaussReducer( int dimen )
+{
+    int k;
+    size= 0;
+    max= dimen;
+#ifndef HAVE_EXPLICIT_CONSTR
+    elems= new gaussElem[ max+1 ];
+#else
+    elems= (gaussElem *)omAlloc( (max+1)*sizeof( gaussElem ) );
+#endif
+    isPivot= (BOOLEAN *)omAlloc( (max+1)*sizeof( BOOLEAN ) );
+    for ( k= max; k > 0; k-- )
+            isPivot[k]= FALSE;
+    perm= (int *)omAlloc( (max+1)*sizeof( int ) );
+}
+
+gaussReducer::~gaussReducer()
+{
+#ifndef HAVE_EXPLICIT_CONSTR
+    delete [] elems;
+#else
+    int k;
+    for ( k= size; k > 0; k-- )
+        elems[k].~gaussElem();
+    omFreeSize( (ADDRESS)elems, (max+1)*sizeof( gaussElem ) );
+#endif
+
+    omFreeSize( (ADDRESS)isPivot, (max+1)*sizeof( BOOLEAN ) );
+    omFreeSize( (ADDRESS)perm, (max+1)*sizeof( int ) );
+}
+
+BOOLEAN
+gaussReducer::reduce( fglmVector thev )
+{
+    number fac1, fac2;
+    number temp;
+    // Hier ueberlegen, ob thev als referenz, oder wie wann was kopiert usw.
+    v= thev;
+    p= fglmVector( size + 1, size + 1 );
+    // fglmASSERT( pdenom == NULL );
+    pdenom= nInit( 1 );
+    number vdenom = v.clearDenom();
+    if ( ! nIsOne( vdenom ) && ! nIsZero( vdenom ) ) {
+        p.setelem( p.size(), vdenom );
+    }
+    else {
+        nDelete( & vdenom );
+    }
+    number gcd = v.gcd();
+    if ( ! nIsOne( gcd ) && ! nIsZero( gcd ) ) {
+        v /= gcd;
+        number temp= nMult( pdenom, gcd );
+        nDelete( & pdenom );
+        pdenom= temp;
+    }
+    nDelete( & gcd );
+
+    int k;
+    for ( k= 1; k <= size; k++ ) {
+        if ( ! v.elemIsZero( perm[k] ) ) {
+            fac1= elems[k].fac;
+            fac2= nCopy( v.getconstelem( perm[k] ) );
+            v.nihilate( fac1, fac2, elems[k].v );
+            fac1= nMult( fac1, elems[k].pdenom );
+            temp= nMult( fac2, pdenom );
+            nDelete( & fac2 );
+            fac2= temp;
+            p.nihilate( fac1, fac2, elems[k].p );
+            temp= nMult( pdenom, elems[k].pdenom );
+            nDelete( & pdenom );
+            pdenom= temp;
+
+            nDelete( & fac1 );
+            nDelete( & fac2 );
+            number gcd = v.gcd();
+            if ( ! nIsOne( gcd ) && ! nIsZero( gcd ) )
+            {
+                v/= gcd;
+                number temp = nMult( pdenom, gcd );
+                nDelete( & pdenom );
+                pdenom= temp;
+            }
+            nDelete( & gcd );
+            gcd= p.gcd();
+            temp= n_SubringGcd( pdenom, gcd, currRing->cf );
+            nDelete( & gcd );
+            gcd= temp;
+            if ( ! nIsZero( gcd ) && ! nIsOne( gcd ) )
+            {
+                p/= gcd;
+                temp= nDiv( pdenom, gcd );
+                nDelete( & pdenom );
+                pdenom= temp;
+                nNormalize( pdenom );
+            }
+            nDelete( & gcd );
+        }
+    }
+    return ( v.isZero() );
+}
+
+void
+gaussReducer::store()
+{
+    // fglmASSERT( size < max );
+    // number fac;
+    // find the pivot-element in v:
+
+    size++;
+    int k= 1;
+    while ( nIsZero(v.getconstelem(k)) || isPivot[k] ) {
+        k++;
+    }
+    // fglmASSERT( k <= dimen, "Error(1) in fglmDdata::pivot-search");
+    number pivot= v.getconstelem( k );
+    int pivotcol = k;
+    k++;
+    while ( k <= max ) {
+        if ( ! nIsZero( v.getconstelem(k) ) && ! isPivot[k] ) {
+            if ( nGreater( v.getconstelem( k ), pivot ) ) {
+                pivot= v.getconstelem( k );
+                pivotcol= k;
+            }
+        }
+        k++;
+    }
+    // fglmASSERT( ! nIsZero( pivot ), "Error(2) fglmDdata::Pivotelement ist Null" );
+    isPivot[ pivotcol ]= TRUE;
+    perm[size]= pivotcol;
+
+    pivot= nCopy( v.getconstelem( pivotcol ) );
+#ifndef HAVE_EXPLICIT_CONSTR
+    elems[size].mac_gaussElem( v, p, pdenom, pivot );
+#else
+    elems[size].gaussElem( v, p, pdenom, pivot );
+#endif
+}
+
+fglmVector
+gaussReducer::getDependence()
+{
+    nDelete( & pdenom );
+    // hier kann p noch gekuerzt werden, je nach Charakteristik
+    fglmVector result = p;
+    p= fglmVector();
+    return ( result );
+}
+// ================================================================================
+
+// ----------------------------------------------------------------------------
+// Local Variables: ***
+// compile-command: "make Singular" ***
+// page-delimiter: "^\\(
\\|//!\\)" ***
+// fold-internal-margins: nil ***
+// End: ***
diff --git a/kernel/fglm/fglmgauss.h b/kernel/fglm/fglmgauss.h
new file mode 100644
index 0000000..e26e0cd
--- /dev/null
+++ b/kernel/fglm/fglmgauss.h
@@ -0,0 +1,47 @@
+// emacs edit mode for this file is -*- C++ -*-
+
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT - header file for the gauss - reducer
+*            (used by fglm)
+*/
+#ifndef FGLMGAUSS_H
+#define FGLMGAUSS_H
+
+#include <kernel/structs.h>
+#include <kernel/fglm/fglmvec.h>
+
+class gaussElem;
+
+class gaussReducer
+{
+private:
+    gaussElem * elems;
+    BOOLEAN * isPivot;
+    int * perm;
+    fglmVector v;
+    fglmVector p;
+    number pdenom;
+    int size;
+    int max;
+public:
+    gaussReducer( int dimen );
+    ~gaussReducer();
+
+    // reduce returns TRUE, if v reduces to 0, FALSE otherwise;
+    BOOLEAN reduce( fglmVector v );
+
+    // if a vector does not reduce to zero, then it can be stored as a new gauss
+    // vector.
+    // Has to be called after reduce!
+    void store();
+
+    // if a vector reduces to zero, then one can get the corresponding fglmVector
+    // of the linear dependence
+    // Has to be called after reduce!
+    fglmVector getDependence();
+};
+
+#endif
diff --git a/kernel/fglm/fglmhom.cc b/kernel/fglm/fglmhom.cc
new file mode 100644
index 0000000..655fa59
--- /dev/null
+++ b/kernel/fglm/fglmhom.cc
@@ -0,0 +1,454 @@
+// emacs edit mode for this file is -*- C++ -*-
+
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT - The FGLM-Algorithm extended for homogeneous ideals.
+*   Calculates via the hilbert-function a groebner basis.
+*/
+
+
+
+
+
+#include <kernel/mod2.h>
+#if 0
+#include <factoryconf.h>
+#ifndef NOSTREAMIO
+#include <iostream.h>
+#endif
+// #include <Singular/tok.h>
+#include <kernel/structs.h>
+#include <kernel/subexpr.h>
+#include <kernel/polys.h>
+#include <kernel/ideals.h>
+#include <polys/monomials/ring.h>
+#include <kernel/ipid.h>
+#include <kernel/ipshell.h>
+#include <polys/monomials/maps.h>
+#include <omalloc/omalloc.h>
+#include "fglm.h"
+#include "fglmvec.h"
+#include "fglmgauss.h"
+#include <misc/intvec.h>
+#include <kernel/GBEngine/kstd1.h>
+#include <kernel/combinatorics/stairc.h>
+#include <factory/templates/ftmpl_list.h>
+
+// obachman: Got rid off those "redefiende messages by includeing fglm.h
+#include "fglm.h"
+#if 0
+#define PROT(msg) if (BTEST1(OPT_PROT)) Print(msg)
+#define STICKYPROT(msg) if (BTEST1(OPT_PROT)) Print(msg)
+#define PROT2(msg,arg) if (BTEST1(OPT_PROT)) Print(msg,arg)
+#define STICKYPROT2(msg,arg) if (BTEST1(OPT_PROT)) Print(msg,arg)
+#define fglmASSERT(ignore1,ignore2)
+#endif
+
+struct doublepoly
+{
+    poly sm;
+    poly dm;
+};
+
+class homogElem
+{
+public:
+    doublepoly mon;
+    fglmVector v;
+    fglmVector dv;
+    int basis;
+    int destbasis;
+    BOOLEAN inDest;
+    homogElem() : v(), dv(), basis(0), destbasis(0), inDest(FALSE) {}
+    homogElem( poly m, int b, BOOLEAN ind ) :
+        basis(b), inDest(ind)
+    {
+        mon.dm= m;
+        mon.sm= NULL;
+    }
+#ifndef HAVE_EXPLICIT_CONSTR
+    void initialize( poly m, int b, BOOLEAN ind )
+    {
+	basis = b;
+	inDest = ind;
+	mon.dm = m;
+	mon.sm = NULL;
+    }
+    void initialize( const homogElem h )
+    {
+	basis = h.basis;
+	inDest = h.inDest;
+	mon.dm = h.mon.dm;
+	mon.sm = h.mon.sm;
+    }
+#endif
+};
+
+struct homogData
+{
+    ideal sourceIdeal;
+    doublepoly * sourceHeads;
+    int numSourceHeads;
+    ideal destIdeal;
+    int numDestPolys;
+    homogElem * monlist;
+    int monlistmax;
+    int monlistblock;
+    int numMonoms;
+    int basisSize;
+    int overall;  // nur zum testen.
+    int numberofdestbasismonoms;
+//     homogData() : sourceHeads(NULL), numSourceHeads(0), monlist(NULL),
+//         numMonoms(0), basisSize(0) {}
+};
+
+int
+hfglmNextdegree( intvec * source, ideal current, int & deg )
+{
+    int numelems;
+    intvec * newhilb = hHstdSeries( current, NULL, currRing->qideal );
+
+    loop
+    {
+        if ( deg < newhilb->length() )
+        {
+            if ( deg < source->length() )
+                numelems= (*newhilb)[deg]-(*source)[deg];
+            else
+                numelems= (*newhilb)[deg];
+        }
+        else
+        {
+            if (deg < source->length())
+                numelems= -(*source)[deg];
+            else
+            {
+                deg= 0;
+                return 0;
+            }
+        }
+        if (numelems != 0)
+            return numelems;
+        deg++;
+    }
+    delete newhilb;
+}
+
+void
+generateMonoms( poly m, int var, int deg, homogData * dat )
+{
+    if ( var == (currRing->N) ) {
+        BOOLEAN inSource = FALSE;
+        BOOLEAN inDest = FALSE;
+        poly mon = pCopy( m );
+        pSetExp( mon, var, deg );
+        pSetm( mon );
+        ++dat->overall;
+        int i;
+        for ( i= dat->numSourceHeads - 1; (i >= 0) && (inSource==FALSE); i-- ) {
+            if ( pDivisibleBy( dat->sourceHeads[i].dm, mon ) ) {
+                inSource= TRUE;
+            }
+        }
+        for ( i= dat->numDestPolys - 1; (i >= 0) && (inDest==FALSE); i-- ) {
+            if ( pDivisibleBy( (dat->destIdeal->m)[i], mon ) ) {
+                inDest= TRUE;
+            }
+        }
+        if ( (!inSource) || (!inDest) ) {
+            int basis = 0;
+            if ( !inSource )
+                basis= ++(dat->basisSize);
+            if ( !inDest )
+                ++dat->numberofdestbasismonoms;
+            if ( dat->numMonoms == dat->monlistmax ) {
+                int k;
+#ifdef HAVE_EXPLICIT_CONSTR
+		// Expand array using Singulars ReAlloc function
+                dat->monlist=
+		    (homogElem * )omReallocSize( dat->monlist,
+					   (dat->monlistmax)*sizeof( homogElem ),
+					   (dat->monlistmax+dat->monlistblock) * sizeof( homogElem ) );
+                for ( k= dat->monlistmax; k < (dat->monlistmax+dat->monlistblock); k++ )
+                    dat->monlist[k].homogElem();
+#else
+		// Expand array by generating new one and copying
+		int newsize = dat->monlistmax  + dat->monlistblock;
+		homogElem * tempelem = new homogElem[ newsize ];
+		// Copy old elements
+		for ( k= dat->monlistmax - 1; k >= 0; k-- )
+		    tempelem[k].initialize( dat->monlist[k] );
+		delete [] homogElem;
+		homogElem = tempelem;
+#endif
+                dat->monlistmax+= dat->monlistblock;
+            }
+#ifdef HAVE_EXPLICIT_CONSTR
+            dat->monlist[dat->numMonoms]= homogElem( mon, basis, inDest );
+#else
+	    dat->monlist[dat->numMonoms].initialize( mon, basis, inDest );
+#endif
+            dat->numMonoms++;
+            if ( inSource && ! inDest ) PROT( "\\" );
+            if ( ! inSource && inDest ) PROT( "/" );
+            if ( ! inSource && ! inDest ) PROT( "." );
+        }
+        else {
+            pDelete( & mon );
+        }
+        return;
+    }
+    else {
+        poly newm = pCopy( m );
+        while ( deg >= 0 ) {
+            generateMonoms( newm, var+1, deg, dat );
+            pIncrExp( newm, var );
+            pSetm( newm );
+            deg--;
+        }
+        pDelete( & newm );
+    }
+    return;
+}
+
+void
+mapMonoms( ring oldRing, homogData & dat )
+{
+    int * vperm = (int *)omAlloc( (currRing->N + 1)*sizeof(int) );
+    maFindPerm( oldRing->names, oldRing->N, NULL, 0, currRing->names, currRing->N, NULL, 0, vperm, NULL );
+    //nSetMap( oldRing->ch, oldRing->parameter, oldRing->P, oldRing->minpoly );
+    nSetMap( oldRing );
+    int s;
+    for ( s= dat.numMonoms - 1; s >= 0; s-- ) {
+//        dat.monlist[s].mon.sm= pPermPoly( dat.monlist[s].mon.dm, vperm, currRing->N, NULL, 0 );
+      // obachman: changed the folowing to reflect the new calling interface of
+      // pPermPoly -- Tim please check whether this is correct!
+        dat.monlist[s].mon.sm= pPermPoly( dat.monlist[s].mon.dm, vperm, oldRing, NULL, 0 );
+    }
+}
+
+void
+getVectorRep( homogData & dat )
+{
+    // Calculate the NormalForms
+    int s;
+    for ( s= 0;  s < dat.numMonoms; s++ ) {
+        if ( dat.monlist[s].inDest == FALSE ) {
+            fglmVector v;
+            if ( dat.monlist[s].basis == 0 ) {
+                v= fglmVector( dat.basisSize );
+                // now the monom is in L(source)
+                PROT( "(" );
+                poly nf = kNF( dat.sourceIdeal, NULL, dat.monlist[s].mon.sm );
+                PROT( ")" );
+                poly temp = nf;
+                while (temp != NULL ) {
+                    int t;
+                    for ( t= dat.numMonoms - 1; t >= 0; t-- ) {
+                        if ( dat.monlist[t].basis > 0 ) {
+                            if ( pLmEqual( dat.monlist[t].mon.sm, temp ) ) {
+                                number coeff= nCopy( pGetCoeff( temp ) );
+                                v.setelem( dat.monlist[t].basis, coeff );
+                            }
+                        }
+                    }
+                    pIter(temp);
+                }
+                pDelete( & nf );
+            }
+            else {
+                PROT( "." );
+                v= fglmVector( dat.basisSize, dat.monlist[s].basis );
+            }
+            dat.monlist[s].v= v;
+        }
+    }
+}
+
+void
+remapVectors( ring oldring, homogData & dat )
+{
+    //nSetMap( oldring->ch, oldring->parameter, oldring->P, oldring->minpoly );
+    nSetMap( oldring );
+    int s;
+    for ( s= dat.numMonoms - 1; s >= 0; s-- ) {
+        if ( dat.monlist[s].inDest == FALSE ) {
+            int k;
+            fglmVector newv( dat.basisSize );
+            for ( k= dat.basisSize; k > 0; k-- ){
+                number newnum= nMap( dat.monlist[s].v.getelem( k ) );
+                newv.setelem( k, newnum );
+            }
+            dat.monlist[s].dv= newv;
+        }
+    }
+}
+
+void
+gaussreduce( homogData & dat, int maxnum, int BS )
+{
+    int s;
+    int found= 0;
+
+    int destbasisSize = 0;
+    gaussReducer gauss( dat.basisSize );
+
+    for ( s= 0; (s < dat.numMonoms) && (found < maxnum); s++ ) {
+        if ( dat.monlist[s].inDest == FALSE ) {
+            if ( gauss.reduce( dat.monlist[s].dv ) == FALSE ) {
+                destbasisSize++;
+                dat.monlist[s].destbasis= destbasisSize;
+                gauss.store();
+                PROT( "." );
+            }
+            else {
+                fglmVector p= gauss.getDependence();
+                poly result = pCopy( dat.monlist[s].mon.dm );
+                pSetCoeff( result, nCopy( p.getconstelem( p.size() ) ) );
+                int l = 0;
+                int k;
+                for ( k= 1; k < p.size(); k++ ) {
+                    if ( ! p.elemIsZero( k ) ) {
+                        while ( dat.monlist[l].destbasis != k )
+                            l++;
+                        poly temp = pCopy( dat.monlist[l].mon.dm );
+                        pSetCoeff( temp, nCopy( p.getconstelem( k ) ) );
+                        result= pAdd( result, temp );
+                    }
+                }
+                if ( ! nGreaterZero( pGetCoeff( result ) ) ) result= pNeg( result );
+//                PROT2( "(%s)", pString( result ) );
+                PROT( "+" );
+                found++;
+                (dat.destIdeal->m)[dat.numDestPolys]= result;
+                dat.numDestPolys++;
+                if ( IDELEMS(dat.destIdeal) == dat.numDestPolys ) {
+                    pEnlargeSet( & dat.destIdeal->m, IDELEMS( dat.destIdeal ), BS );
+                    IDELEMS( dat.destIdeal )+= BS;
+                }
+
+            }
+
+        }
+    }
+    PROT2( "(%i", s );
+    PROT2( "/%i)", dat.numberofdestbasismonoms );
+}
+
+
+BOOLEAN
+fglmhomog( ring sourceRing, ideal sourceIdeal, ring destRing, ideal & destIdeal )
+{
+#define groebnerBS 16
+    int numGBelems;
+    int deg = 0;
+
+    homogData dat;
+
+    // get the hilbert series and the leading monomials of the sourceIdeal:
+    rChangeCurrRing( sourceRing );
+
+    intvec * hilb = hHstdSeries( sourceIdeal, NULL, currRing->qideal );
+    int s;
+    dat.sourceIdeal= sourceIdeal;
+    dat.sourceHeads= (doublepoly *)omAlloc( IDELEMS( sourceIdeal ) * sizeof( doublepoly ) );
+    for ( s= IDELEMS( sourceIdeal ) - 1; s >= 0; s-- )
+    {
+        dat.sourceHeads[s].sm= pHead( (sourceIdeal->m)[s] );
+    }
+    dat.numSourceHeads= IDELEMS( sourceIdeal );
+    rChangeCurrRing( destRing );
+
+    // Map the sourceHeads to the destRing
+    int * vperm = (int *)omAlloc( (sourceRing->N + 1)*sizeof(int) );
+    maFindPerm( sourceRing->names, sourceRing->N, NULL, 0, currRing->names,
+                currRing->N, NULL, 0, vperm, NULL, currRing->ch);
+    //nSetMap( sourceRing->ch, sourceRing->parameter, sourceRing->P, sourceRing->minpoly );
+    nSetMap( sourceRing );
+    for ( s= IDELEMS( sourceIdeal ) - 1; s >= 0; s-- )
+    {
+        dat.sourceHeads[s].dm= pPermPoly( dat.sourceHeads[s].sm, vperm, sourceRing, NULL, 0 );
+    }
+
+    dat.destIdeal= idInit( groebnerBS, 1 );
+    dat.numDestPolys= 0;
+
+    while ( (numGBelems= hfglmNextdegree( hilb, dat.destIdeal, deg )) != 0 )
+    {
+        int num = 0;  // the number of monoms of degree deg
+        PROT2( "deg= %i ", deg );
+        PROT2( "num= %i\ngen>", numGBelems );
+        dat.monlistblock= 512;
+        dat.monlistmax= dat.monlistblock;
+#ifdef HAVE_EXPLICIT_CONSTR
+        dat.monlist= (homogElem *)omAlloc( dat.monlistmax*sizeof( homogElem ) );
+        int j;
+        for ( j= dat.monlistmax - 1; j >= 0; j-- ) dat.monlist[j].homogElem();
+#else
+	dat.monlist = new homogElem[ dat.monlistmax ];
+#endif
+        dat.numMonoms= 0;
+        dat.basisSize= 0;
+        dat.overall= 0;
+        dat.numberofdestbasismonoms= 0;
+
+        poly start= pOne();
+        generateMonoms( start, 1, deg, &dat );
+        pDelete( & start );
+
+        PROT2( "(%i/", dat.basisSize );
+        PROT2( "%i)\nvec>", dat.overall );
+        // switch to sourceRing and map monoms
+        rChangeCurrRing( sourceRing );
+        mapMonoms( destRing, dat );
+        getVectorRep( dat );
+
+        // switch to destination Ring and remap the vectors
+        rChangeCurrRing( destRing );
+        remapVectors( sourceRing, dat );
+
+        PROT( "<\nred>" );
+        // now do gaussian reduction
+        gaussreduce( dat, numGBelems, groebnerBS );
+
+#ifdef HAVE_EXPLICIT_CONSTR
+        omFreeSize( (ADDRESS)dat.monlist, dat.monlistmax*sizeof( homogElem ) );
+#else
+	delete [] dat.monlist;
+#endif
+        PROT( "<\n" );
+    }
+    PROT( "\n" );
+    destIdeal= dat.destIdeal;
+    idSkipZeroes( destIdeal );
+    return TRUE;
+}
+
+/* ideal fglmhomProc(leftv first, leftv second) // TODO: Move to Singular/
+{
+    idhdl dest= currRingHdl;
+    ideal result;
+    // in den durch das erste Argument angegeben Ring schalten:
+    rSetHdl( (idhdl)first->data, TRUE );
+    idhdl ih= currRing->idroot->get( second->name, myynest );
+    ASSERT( ih!=NULL, "Error: Can't find ideal in ring");
+    rSetHdl( dest, TRUE );
+
+    ideal i= IDIDEAL(ih);
+    fglmhomog( IDRING((idhdl)first->data), i, IDRING(dest), result );
+
+    return( result );
+} */
+
+#endif
+
+// Questions:
+// Muss ich einen intvec freigeben?
+// ----------------------------------------------------------------------------
+// Local Variables: ***
+// compile-command: "make Singular" ***
+// page-delimiter: "^\\(
\\|//!\\)" ***
+// fold-internal-margins: nil ***
+// End: ***
diff --git a/kernel/fglm/fglmvec.cc b/kernel/fglm/fglmvec.cc
new file mode 100644
index 0000000..bbd78fb
--- /dev/null
+++ b/kernel/fglm/fglmvec.cc
@@ -0,0 +1,538 @@
+// emacs edit mode for this file is -*- C++ -*-
+
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT - The FGLM-Algorithm
+*   Implementation of number-vectors for the fglm algorithm.
+*   (See fglm.cc). Based on a letter-envelope implementation, mainly
+*   written to be used by the fglm algorithm. Hence they are
+*   specialized for this purpose.
+*/
+
+
+
+
+#include <kernel/mod2.h>
+
+#include <omalloc/omalloc.h>
+#include <kernel/structs.h>
+#include <coeffs/numbers.h>
+#include "fglm.h"
+#include "fglmvec.h"
+
+#define PROT(msg)
+#define STICKYPROT(msg) if (BTEST1(OPT_PROT)) Print(msg)
+#define PROT2(msg,arg)
+#define STICKYPROT2(msg,arg) if (BTEST1(OPT_PROT)) Print(msg,arg)
+#define fglmASSERT(ignore1,ignore2)
+
+class fglmVectorRep
+{
+private:
+  int ref_count;
+  int N;
+  number *elems;
+public:
+    fglmVectorRep ():ref_count (1), N (0), elems (0)
+  {
+  }
+  fglmVectorRep (int n, number * e):ref_count (1), N (n), elems (e)
+  {
+  }
+  fglmVectorRep (int n):ref_count (1), N (n)
+  {
+    fglmASSERT (N >= 0, "illegal Vector representation");
+    if(N == 0)
+      elems = 0;
+    else
+    {
+      elems = (number *) omAlloc (N * sizeof (number));
+      for(int i = N - 1; i >= 0; i--)
+        elems[i] = nInit (0);
+    }
+  }
+  ~fglmVectorRep ()
+  {
+    if(N > 0)
+    {
+      for(int i = N - 1; i >= 0; i--)
+        nDelete (elems + i);
+      omFreeSize ((ADDRESS) elems, N * sizeof (number));
+    }
+  }
+
+  fglmVectorRep *clone () const
+  {
+    if(N > 0)
+    {
+      number *elems_clone;
+        elems_clone = (number *) omAlloc (N * sizeof (number));
+      for(int i = N - 1; i >= 0; i--)
+          elems_clone[i] = nCopy (elems[i]);
+        return new fglmVectorRep (N, elems_clone);
+    }
+    else
+        return new fglmVectorRep (N, 0);
+  }
+  BOOLEAN deleteObject ()
+  {
+    return --ref_count == 0;
+  }
+  fglmVectorRep *copyObject ()
+  {
+    ref_count++;
+    return this;
+  }
+  int refcount () const
+  {
+    return ref_count;
+  }
+  BOOLEAN isUnique () const
+  {
+    return ref_count == 1;
+  }
+
+  int size () const
+  {
+    return N;
+  }
+  int isZero () const
+  {
+    int k;
+    for(k = N; k > 0; k--)
+      if(!nIsZero (getconstelem (k)))
+          return 0;
+      return 1;
+  }
+  int numNonZeroElems () const
+  {
+    int num = 0;
+    int k;
+    for(k = N; k > 0; k--)
+      if(!nIsZero (getconstelem (k)))
+          num++;
+      return num;
+  }
+  void setelem (int i, number n)
+  {
+    fglmASSERT (0 < i && i <= N, "setelem: wrong index");
+    nDelete (elems + i - 1);
+    elems[i - 1] = n;
+  }
+  number ejectelem (int i, number n)
+  {
+    fglmASSERT (isUnique (), "should only be called if unique!");
+    number temp = elems[i - 1];
+    elems[i - 1] = n;
+    return temp;
+  }
+  number & getelem (int i)
+  {
+    fglmASSERT (0 < i && i <= N, "getelem: wrong index");
+    return elems[i - 1];
+  }
+  number getconstelem (int i) const
+  {
+    fglmASSERT (0 < i && i <= N, "getconstelem: wrong index");
+    return elems[i - 1];
+  }
+  friend class fglmVector;
+};
+
+
+///--------------------------------------------------------------------------------
+/// Implementation of class fglmVector
+///--------------------------------------------------------------------------------
+
+fglmVector::fglmVector (fglmVectorRep * r):rep (r)
+{
+}
+
+fglmVector::fglmVector ():rep (new fglmVectorRep ())
+{
+}
+
+fglmVector::fglmVector (int size):rep (new fglmVectorRep (size))
+{
+}
+
+fglmVector::fglmVector (int size, int basis):rep (new fglmVectorRep (size))
+{
+  rep->setelem (basis, nInit (1));
+}
+
+fglmVector::fglmVector (const fglmVector & v)
+{
+  rep = v.rep->copyObject ();
+}
+
+fglmVector::~fglmVector ()
+{
+  if(rep->deleteObject ())
+    delete rep;
+}
+
+#ifndef HAVE_EXPLICIT_CONSTR
+void fglmVector::mac_constr (const fglmVector & v)
+{
+  rep = v.rep->copyObject ();
+}
+
+void fglmVector::mac_constr_i (int size)
+{
+  rep = new fglmVectorRep (size);
+}
+
+void fglmVector::clearelems ()
+{
+  if(rep->deleteObject ())
+    delete rep;
+}
+#endif
+
+void fglmVector::makeUnique ()
+{
+  if(rep->refcount () != 1)
+  {
+    rep->deleteObject ();
+    rep = rep->clone ();
+  }
+}
+
+int fglmVector::size () const
+{
+  return rep->size ();
+}
+
+int fglmVector::numNonZeroElems () const
+{
+  return rep->numNonZeroElems ();
+}
+
+void
+  fglmVector::nihilate (const number fac1, const number fac2,
+                        const fglmVector v)
+{
+  int i;
+  int vsize = v.size ();
+  number term1, term2;
+  fglmASSERT (vsize <= rep->size (), "v has to be smaller oder equal");
+  if(rep->isUnique ())
+  {
+    for(i = vsize; i > 0; i--)
+    {
+      term1 = nMult (fac1, rep->getconstelem (i));
+      term2 = nMult (fac2, v.rep->getconstelem (i));
+      rep->setelem (i, nSub (term1, term2));
+      nDelete (&term1);
+      nDelete (&term2);
+    }
+    for(i = rep->size (); i > vsize; i--)
+    {
+      rep->setelem (i, nMult (fac1, rep->getconstelem (i)));
+    }
+  }
+  else
+  {
+    number *newelems;
+    newelems = (number *) omAlloc (rep->size () * sizeof (number));
+    for(i = vsize; i > 0; i--)
+    {
+      term1 = nMult (fac1, rep->getconstelem (i));
+      term2 = nMult (fac2, v.rep->getconstelem (i));
+      newelems[i - 1] = nSub (term1, term2);
+      nDelete (&term1);
+      nDelete (&term2);
+    }
+    for(i = rep->size (); i > vsize; i--)
+    {
+      newelems[i - 1] = nMult (fac1, rep->getconstelem (i));
+    }
+    rep->deleteObject ();
+    rep = new fglmVectorRep (rep->size (), newelems);
+  }
+}
+
+fglmVector & fglmVector::operator = (const fglmVector & v)
+{
+  if(this != &v)
+  {
+    if(rep->deleteObject ())
+      delete rep;
+    rep = v.rep->copyObject ();
+  }
+  return *this;
+}
+
+int fglmVector::operator == (const fglmVector & v)
+{
+  if(rep->size () == v.rep->size ())
+  {
+    if(rep == v.rep)
+      return 1;
+    else
+    {
+      int i;
+      for(i = rep->size (); i > 0; i--)
+        if(!nEqual (rep->getconstelem (i), v.rep->getconstelem (i)))
+          return 0;
+      return 1;
+    }
+  }
+  return 0;
+}
+
+int fglmVector::operator != (const fglmVector & v)
+{
+  return !(*this == v);
+}
+
+int fglmVector::isZero ()
+{
+  return rep->isZero ();
+}
+
+int fglmVector::elemIsZero (int i)
+{
+  return nIsZero (rep->getconstelem (i));
+}
+
+fglmVector & fglmVector::operator += (const fglmVector & v)
+{
+  fglmASSERT (size () == v.size (), "incompatible vectors");
+  // ACHTUNG : Das Verhalten hier mit gcd genau ueberpruefen!
+  int i;
+  if(rep->isUnique ())
+  {
+    for(i = rep->size (); i > 0; i--)
+      rep->setelem (i, nAdd (rep->getconstelem (i), v.rep->getconstelem (i)));
+  }
+  else
+  {
+    int n = rep->size ();
+    number *newelems;
+    newelems = (number *) omAlloc (n * sizeof (number));
+    for(i = n; i > 0; i--)
+      newelems[i - 1] = nAdd (rep->getconstelem (i), v.rep->getconstelem (i));
+    rep->deleteObject ();
+    rep = new fglmVectorRep (n, newelems);
+  }
+  return *this;
+}
+
+fglmVector & fglmVector::operator -= (const fglmVector & v)
+{
+  fglmASSERT (size () == v.size (), "incompatible vectors");
+  int i;
+  if(rep->isUnique ())
+  {
+    for(i = rep->size (); i > 0; i--)
+      rep->setelem (i, nSub (rep->getconstelem (i), v.rep->getconstelem (i)));
+  }
+  else
+  {
+    int n = rep->size ();
+    number *newelems;
+    newelems = (number *) omAlloc (n * sizeof (number));
+    for(i = n; i > 0; i--)
+      newelems[i - 1] = nSub (rep->getconstelem (i), v.rep->getconstelem (i));
+    rep->deleteObject ();
+    rep = new fglmVectorRep (n, newelems);
+  }
+  return *this;
+}
+
+fglmVector & fglmVector::operator *= (const number & n)
+{
+  int s = rep->size ();
+  int i;
+  if(!rep->isUnique ())
+  {
+    number *temp;
+    temp = (number *) omAlloc (s * sizeof (number));
+    for(i = s; i > 0; i--)
+      temp[i - 1] = nMult (rep->getconstelem (i), n);
+    rep->deleteObject ();
+    rep = new fglmVectorRep (s, temp);
+  }
+  else
+  {
+    for(i = s; i > 0; i--)
+      rep->setelem (i, nMult (rep->getconstelem (i), n));
+  }
+  return *this;
+}
+
+fglmVector & fglmVector::operator /= (const number & n)
+{
+  int s = rep->size ();
+  int i;
+  if(!rep->isUnique ())
+  {
+    number *temp;
+    temp = (number *) omAlloc (s * sizeof (number));
+    for(i = s; i > 0; i--)
+    {
+      temp[i - 1] = nDiv (rep->getconstelem (i), n);
+      nNormalize (temp[i - 1]);
+    }
+    rep->deleteObject ();
+    rep = new fglmVectorRep (s, temp);
+  }
+  else
+  {
+    for(i = s; i > 0; i--)
+    {
+      rep->setelem (i, nDiv (rep->getconstelem (i), n));
+      nNormalize (rep->getelem (i));
+    }
+  }
+  return *this;
+}
+
+fglmVector operator - (const fglmVector & v)
+{
+  fglmVector temp (v.size ());
+  int i;
+  number n;
+  for(i = v.size (); i > 0; i--)
+  {
+    n = nCopy (v.getconstelem (i));
+    n = nInpNeg (n);
+    temp.setelem (i, n);
+  }
+  return temp;
+}
+
+fglmVector operator + (const fglmVector & lhs, const fglmVector & rhs)
+{
+  fglmVector temp = lhs;
+  temp += rhs;
+  return temp;
+}
+
+fglmVector operator - (const fglmVector & lhs, const fglmVector & rhs)
+{
+  fglmVector temp = lhs;
+  temp -= rhs;
+  return temp;
+}
+
+fglmVector operator * (const fglmVector & v, const number n)
+{
+  fglmVector temp = v;
+  temp *= n;
+  return temp;
+}
+
+fglmVector operator * (const number n, const fglmVector & v)
+{
+  fglmVector temp = v;
+  temp *= n;
+  return temp;
+}
+
+number & fglmVector::getelem (int i)
+{
+  makeUnique ();
+  return rep->getelem (i);
+}
+
+number fglmVector::getconstelem (int i) const
+{
+  return rep->getconstelem (i);
+}
+
+void fglmVector::setelem (int i, number & n)
+{
+  makeUnique ();
+  rep->setelem (i, n);
+  n = n_Init (0, currRing->cf);
+}
+
+number fglmVector::gcd () const
+{
+  int i = rep->size ();
+  BOOLEAN found = FALSE;
+  BOOLEAN gcdIsOne = FALSE;
+  number theGcd;
+  number current;
+  while(i > 0 && !found)
+  {
+    current = rep->getconstelem (i);
+    if(!nIsZero (current))
+    {
+      theGcd = nCopy (current);
+      found = TRUE;
+      if(!nGreaterZero (theGcd))
+      {
+        theGcd = nInpNeg (theGcd);
+      }
+      if(nIsOne (theGcd))
+        gcdIsOne = TRUE;
+    }
+    i--;
+  }
+  if(found)
+  {
+    while(i > 0 && !gcdIsOne)
+    {
+      current = rep->getconstelem (i);
+      if(!nIsZero (current))
+      {
+        number temp = n_SubringGcd (theGcd, current, currRing->cf);
+        nDelete (&theGcd);
+        theGcd = temp;
+        if(nIsOne (theGcd))
+          gcdIsOne = TRUE;
+      }
+      i--;
+    }
+  }
+  else
+    theGcd = nInit (0);
+  return theGcd;
+}
+
+number fglmVector::clearDenom ()
+{
+  number theLcm = nInit (1);
+  BOOLEAN isZero = TRUE;
+  int i;
+  for(i = size (); i > 0; i--)
+  {
+    if(!nIsZero (rep->getconstelem (i)))
+    {
+      isZero = FALSE;
+      number temp = n_NormalizeHelper (theLcm, rep->getconstelem (i), currRing->cf);
+      nDelete (&theLcm);
+      theLcm = temp;
+    }
+  }
+  if(isZero)
+  {
+    nDelete (&theLcm);
+    theLcm = nInit (0);
+  }
+  else
+  {
+    if(!nIsOne (theLcm))
+    {
+      *this *= theLcm;
+      for(i = size (); i > 0; i--)
+      {
+        nNormalize (rep->getelem (i));
+      }
+    }
+  }
+  return theLcm;
+}
+
+// ----------------------------------------------------------------------------
+// Local Variables: ***
+// compile-command: "make Singular" ***
+// page-delimiter: "^\\(
\\|//!\\)" ***
+// fold-internal-margins: nil ***
+// End: ***
diff --git a/kernel/fglm/fglmvec.h b/kernel/fglm/fglmvec.h
new file mode 100644
index 0000000..1c52bea
--- /dev/null
+++ b/kernel/fglm/fglmvec.h
@@ -0,0 +1,64 @@
+// emacs edit mode for this file is -*- C++ -*-
+
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT - The FGLM-Algorithm
+*   header file for fglmvec.cc. See fglmvec.cc for details.
+*/
+
+#ifndef FGLMVEC_H
+#define FGLMVEC_H
+
+#include <coeffs/numbers.h>
+
+class fglmVectorRep;
+
+class fglmVector
+{
+protected:
+    fglmVectorRep * rep;
+    void makeUnique();
+    fglmVector( fglmVectorRep * rep );
+public:
+    fglmVector();
+    fglmVector( int size );
+    fglmVector( int size, int basis );
+    fglmVector( const fglmVector & v );
+    ~fglmVector();
+#ifndef HAVE_EXPLICIT_CONSTR
+    void mac_constr( const fglmVector & v);
+    void mac_constr_i( int size);
+    void clearelems();
+#endif
+    int size() const;
+    int numNonZeroElems() const;
+
+    void nihilate( const number fac1, const number fac2, const fglmVector v );
+    fglmVector & operator = ( const fglmVector & v );
+
+    int operator == ( const fglmVector & );
+    int operator != ( const fglmVector & );
+    int isZero();
+    int elemIsZero( int i );
+
+    fglmVector & operator += ( const fglmVector & );
+    fglmVector & operator -= ( const fglmVector & );
+    fglmVector & operator *= ( const number & );
+    fglmVector & operator /= ( const number & );
+    friend fglmVector operator - ( const fglmVector & v );
+    friend fglmVector operator + ( const fglmVector & lhs, const fglmVector & rhs );
+    friend fglmVector operator - ( const fglmVector & lhs, const fglmVector & rhs );
+    friend fglmVector operator * ( const fglmVector & v, const number n );
+    friend fglmVector operator * ( const number n, const fglmVector & v );
+
+    number getconstelem( int i ) const;
+    number & getelem( int i );
+    void setelem( int i, number & n );
+
+    number gcd() const;
+    number clearDenom();
+};
+
+#endif
diff --git a/kernel/fglm/fglmzero.cc b/kernel/fglm/fglmzero.cc
new file mode 100644
index 0000000..2db4e20
--- /dev/null
+++ b/kernel/fglm/fglmzero.cc
@@ -0,0 +1,1252 @@
+// emacs edit mode for this file is -*- C++ -*-
+
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT - The FGLM-Algorithm
+*   Implementation of the fglm algorithm for 0-dimensional ideals,
+*   based on an idea by Faugere/Gianni/Lazard and Mora.
+*   The procedure CalculateFunctionals calculates the functionals
+*   which define the given ideal in the source ring. They build the
+*   input for GroebnerViaFunctionals, which defines the reduced
+*   groebner basis for the ideal in the destination ring.
+*/
+
+/* Changes:
+ * o FindUnivariatePolys added
+ */
+
+
+
+
+#include <kernel/mod2.h>
+
+
+// assumes, that NOSTREAMIO is set in factoryconf.h, which is included
+// by templates/list.h.
+
+#include <factory/factory.h>
+
+#include <factory/templates/ftmpl_list.h>
+#include <factory/templates/ftmpl_list.cc>
+
+#include <omalloc/omalloc.h>
+
+#include <misc/options.h>
+#include <misc/intvec.h>
+
+#include <polys/monomials/maps.h>
+#include <polys/monomials/ring.h>
+
+#include <kernel/polys.h>
+#include <kernel/ideals.h>
+#include <kernel/GBEngine/kstd1.h>
+
+#include "fglm.h"
+#include "fglmvec.h"
+#include "fglmgauss.h"
+
+#define PROT(msg)
+#define STICKYPROT(msg) if (BTEST1(OPT_PROT)) Print(msg)
+#define PROT2(msg,arg)
+#define STICKYPROT2(msg,arg) if (BTEST1(OPT_PROT)) Print(msg,arg)
+#define fglmASSERT(ignore1,ignore2)
+
+
+
+// internal Version: 1.3.1.12
+// ============================================================
+//!      The idealFunctionals
+// ============================================================
+
+struct matElem
+{
+    int row;
+    number elem;
+};
+
+struct matHeader
+{
+    int size;
+    BOOLEAN owner;
+    matElem * elems;
+};
+
+class idealFunctionals
+{
+private:
+    int _block;
+    int _max;
+    int _size;
+    int _nfunc;
+    int * currentSize;
+    matHeader ** func;
+    matHeader * grow( int var );
+public:
+    idealFunctionals( int blockSize, int numFuncs );
+    ~idealFunctionals();
+
+    int dimen() const { fglmASSERT( _size>0, "called too early"); return _size; }
+    void endofConstruction();
+    void map( ring source );
+    void insertCols( int * divisors, int to );
+    void insertCols( int * divisors, const fglmVector to );
+    fglmVector addCols( const int var, int basisSize, const fglmVector v ) const;
+    fglmVector multiply( const fglmVector v, int var ) const;
+};
+
+
+idealFunctionals::idealFunctionals( int blockSize, int numFuncs )
+{
+    int k;
+    _block= blockSize;
+    _max= _block;
+    _size= 0;
+    _nfunc= numFuncs;
+
+    currentSize= (int *)omAlloc0( _nfunc*sizeof( int ) );
+    //for ( k= _nfunc-1; k >= 0; k-- )
+    //    currentSize[k]= 0;
+
+    func= (matHeader **)omAlloc( _nfunc*sizeof( matHeader * ) );
+    for ( k= _nfunc-1; k >= 0; k-- )
+        func[k]= (matHeader *)omAlloc( _max*sizeof( matHeader ) );
+}
+
+idealFunctionals::~idealFunctionals()
+{
+    int k;
+    int l;
+    int row;
+    matHeader * colp;
+    matElem * elemp;
+    for ( k= _nfunc-1; k >= 0; k-- ) {
+        for ( l= _size-1, colp= func[k]; l >= 0; l--, colp++ ) {
+            if ( ( colp->owner == TRUE ) && ( colp->size > 0 ) ) {
+                for ( row= colp->size-1, elemp= colp->elems; row >= 0; row--, elemp++ )
+                    nDelete( & elemp->elem );
+                omFreeSize( (ADDRESS)colp->elems, colp->size*sizeof( matElem ) );
+            }
+        }
+        omFreeSize( (ADDRESS)func[k], _max*sizeof( matHeader ) );
+    }
+    omFreeSize( (ADDRESS)func, _nfunc*sizeof( matHeader * ) );
+    omFreeSize( (ADDRESS)currentSize, _nfunc*sizeof( int ) );
+}
+
+void
+idealFunctionals::endofConstruction()
+{
+    _size= currentSize[0];
+}
+
+void
+idealFunctionals::map( ring source )
+{
+    // maps from ring source to currentRing.
+    int var, col, row;
+    matHeader * colp;
+    matElem * elemp;
+    number newelem;
+
+    int * perm = (int *)omAlloc0( (_nfunc+1)*sizeof( int ) );
+    maFindPerm( source->names, source->N, NULL, 0, currRing->names,
+                currRing->N, NULL, 0, perm, NULL , currRing->cf->type);
+    nMapFunc nMap=n_SetMap( source, currRing);
+
+    matHeader ** temp = (matHeader **)omAlloc( _nfunc*sizeof( matHeader * ));
+    for ( var= 0; var < _nfunc; var ++ ) {
+        for ( col= 0, colp= func[var]; col < _size; col++, colp++ ) {
+            if ( colp->owner == TRUE ) {
+                for ( row= colp->size-1, elemp= colp->elems; row >= 0;
+                  row--, elemp++ )
+                {
+                    newelem= nMap( elemp->elem, source->cf, currRing->cf );
+                    nDelete( & elemp->elem );
+                    elemp->elem= newelem;
+                }
+            }
+        }
+        temp[ perm[var+1]-1 ]= func[var];
+    }
+    omFreeSize( (ADDRESS)func, _nfunc*sizeof( matHeader * ) );
+    omFreeSize( (ADDRESS)perm, (_nfunc+1)*sizeof( int ) );
+    func= temp;
+}
+
+matHeader *
+idealFunctionals::grow( int var )
+{
+    if ( currentSize[var-1] == _max ) {
+        int k;
+        for ( k= _nfunc; k > 0; k-- )
+            func[k-1]= (matHeader *)omReallocSize( func[k-1], _max*sizeof( matHeader ), (_max + _block)*sizeof( matHeader ) );
+        _max+= _block;
+    }
+    currentSize[var-1]++;
+    return func[var-1] + currentSize[var-1] - 1;
+}
+
+void
+idealFunctionals::insertCols( int * divisors, int to )
+{
+    fglmASSERT( 0 < divisors[0] && divisors[0] <= _nfunc, "wrong number of divisors" );
+    int k;
+    BOOLEAN owner = TRUE;
+    matElem * elems = (matElem *)omAlloc( sizeof( matElem ) );
+    elems->row= to;
+    elems->elem= nInit( 1 );
+    for ( k= divisors[0]; k > 0; k-- ) {
+        fglmASSERT( 0 < divisors[k] && divisors[k] <= _nfunc, "wrong divisor" );
+        matHeader * colp = grow( divisors[k] );
+        colp->size= 1;
+        colp->elems= elems;
+        colp->owner= owner;
+        owner= FALSE;
+    }
+}
+
+
+void
+idealFunctionals::insertCols( int * divisors, const fglmVector to )
+{
+    // divisors runs from divisors[0]..divisors[size-1]
+    fglmASSERT( 0 < divisors[0] && divisors[0] <= _nfunc, "wrong number of divisors" );
+    int k, l;
+    int numElems= to.numNonZeroElems();
+    matElem * elems;
+    matElem * elemp;
+    BOOLEAN owner = TRUE;
+    if ( numElems > 0 ) {
+        elems= (matElem *)omAlloc( numElems * sizeof( matElem ) );
+        for ( k= 1, l= 1, elemp= elems; k <= numElems; k++, elemp++ ) {
+            while ( nIsZero( to.getconstelem(l) ) ) l++;
+            elemp->row= l;
+            elemp->elem= nCopy( to.getconstelem( l ) );
+            l++; // hochzaehlen, damit wir nicht noch einmal die gleiche Stelle testen
+        }
+    }
+    else
+        elems= NULL;
+    for ( k= divisors[0]; k > 0; k-- ) {
+        fglmASSERT( 0 < divisors[k] && divisors[k] <= _nfunc, "wrong divisor" );
+        matHeader * colp = grow( divisors[k] );
+        colp->size= numElems;
+        colp->elems= elems;
+        colp->owner= owner;
+        owner= FALSE;
+    }
+}
+
+fglmVector
+idealFunctionals::addCols( const int var, int basisSize, const fglmVector v ) const
+{
+    fglmVector result( basisSize );
+    matHeader * colp;
+    matElem * elemp;
+    number factor, temp;
+    int k, l;
+    int vsize = v.size();
+
+    fglmASSERT( currentSize[var-1]+1 >= vsize, "wrong v.size()" );
+    for ( k= 1, colp= func[var-1]; k <= vsize; k++, colp++ ) {
+        factor= v.getconstelem( k );
+        if ( ! nIsZero( factor ) ) {
+            for ( l= colp->size-1, elemp= colp->elems; l >= 0; l--, elemp++ ) {
+                temp= nMult( factor, elemp->elem );
+                number newelem= nAdd( result.getconstelem( elemp->row ), temp );
+                nDelete( & temp );
+                nNormalize( newelem );
+                result.setelem( elemp->row, newelem );
+            }
+        }
+    }
+    return result;
+}
+
+fglmVector
+idealFunctionals::multiply( const fglmVector v, int var ) const
+{
+    fglmASSERT( v.size() == _size, "multiply: v has wrong size");
+    fglmVector result( _size );
+    matHeader * colp;
+    matElem * elemp;
+    number factor, temp;
+    int k, l;
+    for ( k= 1, colp= func[var-1]; k <= _size; k++, colp++ ) {
+        factor= v.getconstelem( k );
+        if ( ! nIsZero( factor ) ) {
+            for ( l= colp->size-1, elemp= colp->elems; l >= 0; l--, elemp++ ) {
+                temp= nMult( factor, elemp->elem );
+                number newelem= nAdd( result.getconstelem( elemp->row ), temp );
+                nDelete( & temp );
+                nNormalize( newelem );
+                result.setelem( elemp->row, newelem );
+            }
+        }
+    }
+    return result;
+}
+
+// ============================================================
+//!      The old basis
+// ============================================================
+
+//     Contains the data for a border-monomial, i.e. the monom itself
+//      ( as a Singular-poly ) and its normal-form, described by an
+//      fglmVector. The size of the Vector depends on the current size of
+//      the basis when the normalForm was computed.
+//     monom gets deleted when borderElem comes out of scope.
+class borderElem
+{
+public:
+    poly monom;
+    fglmVector nf;
+    borderElem() : monom(NULL), nf() {}
+    borderElem( poly p, fglmVector n ) : monom( p ), nf( n ) {}
+    ~borderElem() { if (monom!=NULL) pLmDelete(&monom); }
+#ifndef HAVE_EXPLICIT_CONSTR
+    void insertElem( poly p, fglmVector n )
+    {
+        monom= p;
+        nf= n;
+    }
+#endif
+};
+
+//     This class contains the relevant data for the 'candidates'
+//     The declaration of class fglmSelem is found in fglm.h
+
+fglmSelem::fglmSelem( poly p, int var ) : monom( p ), numVars( 0 )
+{
+    for ( int k = (currRing->N); k > 0; k-- )
+        if ( pGetExp( monom, k ) > 0 )
+            numVars++;
+    divisors= (int *)omAlloc( (numVars+1)*sizeof( int ) );
+    divisors[0]= 0;
+    newDivisor( var );
+}
+
+void
+fglmSelem::cleanup()
+{
+    omFreeSize( (ADDRESS)divisors, (numVars+1)*sizeof( int ) );
+}
+
+//     The data-structure for the Functional-Finding-Algorithm.
+class fglmSdata
+{
+private:
+    ideal theIdeal;
+    int idelems;
+    int* varpermutation;
+
+    int basisBS;
+    int basisMax;
+    int basisSize;
+    polyset basis;  //. rem: runs from basis[1]..basis[dimen]
+
+    int borderBS;
+    int borderMax;
+    int borderSize;
+    borderElem * border;  //. rem: runs from border[1]..border[dimen]
+
+    List<fglmSelem> nlist;
+    BOOLEAN _state;
+public:
+    fglmSdata( const ideal thisIdeal );
+    ~fglmSdata();
+
+    BOOLEAN state() const { return _state; };
+    int getBasisSize() const { return basisSize; };
+    int newBasisElem( poly & p );
+    void newBorderElem( poly & m, fglmVector v );
+    BOOLEAN candidatesLeft() const { return ( nlist.isEmpty() ? FALSE : TRUE ); }
+    fglmSelem nextCandidate();
+    void updateCandidates();
+    int getEdgeNumber( const poly m ) const;
+    poly getSpanPoly( int number ) const { return pCopy( (theIdeal->m)[number-1] ); }
+    fglmVector getVectorRep( const poly m );
+    fglmVector getBorderDiv( const poly m, int & var ) const;
+};
+
+fglmSdata::fglmSdata( const ideal thisIdeal )
+{
+    // An dieser Stelle kann die BlockSize ( =BS ) noch sinnvoller berechnet
+    // werden, jenachdem wie das Ideal aussieht.
+    theIdeal= thisIdeal;
+    idelems= IDELEMS( theIdeal );
+    varpermutation = (int*)omAlloc( ((currRing->N)+1)*sizeof(int) );
+    // Sort ring variables by increasing values (because of weighted orderings)
+    ideal perm = idMaxIdeal(1);
+    intvec *iv = idSort(perm,TRUE);
+    idDelete(&perm);
+    for(int i = (currRing->N); i > 0; i--) varpermutation[(currRing->N)+1-i] = (*iv)[i-1];
+    delete iv;
+
+    basisBS= 100;
+    basisMax= basisBS;
+    basisSize= 0;
+    basis= (polyset)omAlloc( basisMax*sizeof( poly ) );
+
+    borderBS= 100;
+    borderMax= borderBS;
+    borderSize= 0;
+#ifndef HAVE_EXPLICIT_CONSTR
+    border= new borderElem[ borderMax ];
+#else
+    border= (borderElem *)omAlloc( borderMax*sizeof( borderElem ) );
+#endif
+    // rem: the constructors are called in newBorderElem().
+    _state= TRUE;
+}
+
+fglmSdata::~fglmSdata()
+{
+    omFreeSize( (ADDRESS)varpermutation, ((currRing->N)+1)*sizeof(int) );
+    for ( int k = basisSize; k > 0; k-- )
+        pLmDelete( basis + k );  //. rem: basis runs from basis[1]..basis[basisSize]
+    omFreeSize( (ADDRESS)basis, basisMax*sizeof( poly ) );
+#ifndef HAVE_EXPLICIT_CONSTR
+    delete [] border;
+#else
+    for ( int l = borderSize; l > 0; l-- )
+        // rem: the polys of borderElem are deleted via ~borderElem()
+        border[l].~borderElem();
+    omFreeSize( (ADDRESS)border, borderMax*sizeof( borderElem ) );
+#endif
+}
+
+//     Inserts poly p without copying into basis, reAllocs Memory if necessary,
+//      increases basisSize and returns the new basisSize.
+//     Remember: The elements of basis are deleted via pDelete in ~fglmSdata!
+//     Sets m= NULL to indicate that now basis is ow(e?)ing the poly.
+int
+fglmSdata::newBasisElem( poly & m )
+{
+    basisSize++;
+    if ( basisSize == basisMax ) {
+        basis= (polyset)omReallocSize( basis, basisMax*sizeof( poly ), (basisMax + basisBS)*sizeof( poly ) );
+        basisMax+= basisBS;
+    }
+    basis[basisSize]= m;
+    m= NULL;
+    return basisSize;
+}
+
+//     Inserts poly p and fglmvector v without copying into border, reAllocs Memory
+//      if necessary, and increases borderSize.
+//     Remember: The poly of border is deleted via ~borderElem in ~fglmSdata!
+//     Sets m= NULL to indicate that now border is ow(e?)ing the poly.
+void
+fglmSdata::newBorderElem( poly & m, fglmVector v )
+{
+    borderSize++;
+    if ( borderSize == borderMax ) {
+#ifndef HAVE_EXPLICIT_CONSTR
+        borderElem * tempborder = new borderElem[ borderMax+borderBS ];
+        for ( int k = 0; k < borderMax; k++ ) {
+            tempborder[k]= border[k];
+            border[k].insertElem( NULL, fglmVector() );
+        }
+        delete [] border;
+        border= tempborder;
+#else
+        border= (borderElem *)omReallocSize( border, borderMax*sizeof( borderElem ), (borderMax + borderBS)*sizeof( borderElem ) );
+#endif
+        borderMax+= borderBS;
+    }
+#ifndef HAVE_EXPLICIT_CONSTR
+    border[borderSize].insertElem( m, v );
+#else
+    border[borderSize].borderElem( m, v );
+#endif
+    m= NULL;
+}
+
+fglmSelem
+fglmSdata::nextCandidate()
+{
+    fglmSelem result = nlist.getFirst();
+    nlist.removeFirst();
+    return result;
+}
+
+//     Multiplies basis[basisSize] with all ringvariables and inserts the new monomials
+//      into the list of candidates, according to the given order. If a monomial already
+//      exists, then "insertions" and "divisors" are updated.
+//     Assumes that ringvar(varperm[k]) < ringvar(varperm[l]) for k > l
+void
+fglmSdata::updateCandidates()
+{
+    ListIterator<fglmSelem> list = nlist;
+    fglmASSERT( basisSize > 0 && basisSize < basisMax, "Error(1) in fglmSdata::updateCandidates - wrong bassSize" );
+    poly m = basis[basisSize];
+    poly newmonom = NULL;
+    int k = (currRing->N);
+    BOOLEAN done = FALSE;
+    int state = 0;
+    while ( k >= 1 )
+    {
+        newmonom = pCopy( m );
+        pIncrExp( newmonom, varpermutation[k] );
+        pSetm( newmonom );
+        done= FALSE;
+        while ( list.hasItem() && (!done) )
+        {
+            if ( (state= pCmp( list.getItem().monom, newmonom )) < 0 )
+                list++;
+            else done= TRUE;
+        }
+        if ( !done )
+        {
+            nlist.append( fglmSelem( newmonom, varpermutation[k] ) );
+            break;
+        }
+        if ( state == 0 )
+        {
+            list.getItem().newDivisor( varpermutation[k] );
+            pLmDelete(&newmonom);
+        }
+        else
+        {
+            list.insert( fglmSelem( newmonom, varpermutation[k] ) );
+        }
+        k--;
+    }
+    while ( --k >= 1 )
+    {
+        newmonom= pCopy( m ); // HIER
+        pIncrExp( newmonom, varpermutation[k] );
+        pSetm( newmonom );
+        nlist.append( fglmSelem( newmonom, varpermutation[k] ) );
+    }
+}
+
+//     if p == pHead( (theIdeal->m)[k] ) return k, 0 otherwise
+//     (Assumes that pLmEqual just checks the leading monomials without
+//      coefficients.)
+int
+fglmSdata::getEdgeNumber( const poly m ) const
+{
+    for ( int k = idelems; k > 0; k-- )
+        if ( pLmEqual( m, (theIdeal->m)[k-1] ) )
+            return k;
+    return 0;
+}
+
+//     Returns the fglmVector v, s.t.
+//        p = v[1]*basis(1) + .. + v[basisSize]*basis(basisSize)
+//     So the size of v depends on the current size of the basis.
+//     Assumes that such an representation exists, i.e. all monoms in p have to be
+//      smaller than basis[basisSize] and that basis[k] < basis[l] for k < l.
+fglmVector
+fglmSdata::getVectorRep( const poly p )
+{
+    fglmVector temp( basisSize );
+    poly m = p;
+    int num = basisSize;
+    while ( m != NULL ) {
+        int comp = pCmp( m, basis[num] );
+        if ( comp == 0 ) {
+            fglmASSERT( num > 0, "Error(1) in fglmSdata::getVectorRep" );
+            number newelem = nCopy( pGetCoeff( m ) );
+            temp.setelem( num, newelem );
+            num--;
+            pIter( m );
+        }
+        else {
+            if ( comp < 0 ) {
+                num--;
+            }
+            else {
+                // This is the place where we can detect if the sourceIdeal
+                // is not reduced. In this case m is not in basis[]. Since basis[]
+                // is ordered this is the case, if and only if basis[i]<m
+                // and basis[j]>m for all j>i
+                _state= FALSE;
+                return temp;
+            }
+        }
+    }
+    return temp;
+}
+
+//     Searches through the border for a monomoial bm which devides m and returns
+//      its normalform in vector representation.
+//     var contains the number of the variable v, s.t. bm = m * v
+fglmVector
+fglmSdata::getBorderDiv( const poly m, int & var ) const
+{
+//     int num2 = borderSize;
+//     while ( num2 > 0 ) {
+//         poly temp = border[num2].monom;
+//         if ( pDivisibleBy( temp, m ) ) {
+//             poly divisor = pDivideM( m, temp );
+//             int var = pIsPurePower( divisor );
+//             if ( (var != 0) && (pGetCoeff( divisor, var ) == 1) ) {
+//                 Print( "poly %s divides poly %s", pString( temp ), pString( m ) );
+//             }
+//         }
+//         num2--;
+//     }
+    int num = borderSize;
+    while ( num > 0 ) {
+        poly temp = border[num].monom;
+        if ( pDivisibleBy( temp, m ) ) {
+            var = (currRing->N);
+            while ( var > 0 ) {
+                if ( (pGetExp( m, var ) - pGetExp( temp, var )) == 1 )
+                    return border[num].nf;
+                var--;
+            }
+        }
+        num--;
+    }
+    return fglmVector();
+}
+
+void
+internalCalculateFunctionals( const ideal /*& theIdeal*/, idealFunctionals & l,
+                              fglmSdata & data )
+{
+
+    // insert pOne() into basis and update the workingList:
+    poly one = pOne();
+    data.newBasisElem( one );
+    data.updateCandidates();
+
+    STICKYPROT(".");
+    while ( data.candidatesLeft() == TRUE ) {
+        fglmSelem candidate = data.nextCandidate();
+        if ( candidate.isBasisOrEdge() == TRUE ) {
+            int edge = data.getEdgeNumber( candidate.monom );
+            if ( edge != 0 )
+            {
+                // now candidate is an edge, i.e. we know its normalform:
+                // NF(p) = - ( tail(p)/LC(p) )
+                poly nf = data.getSpanPoly( edge );
+                pNorm( nf );
+                pLmDelete(&nf);  //. deletes the leadingmonomial
+                nf= pNeg( nf );
+                fglmVector nfv = data.getVectorRep( nf );
+                l.insertCols( candidate.divisors, nfv );
+                data.newBorderElem( candidate.monom, nfv );
+                pDelete( &nf );
+                STICKYPROT( "+" );
+            }
+            else
+            {
+                int basis= data.newBasisElem( candidate.monom );
+                data.updateCandidates();
+                l.insertCols( candidate.divisors, basis );
+                STICKYPROT( "." );
+            }
+        }
+        else {
+            int var = 0;
+            fglmVector temp = data.getBorderDiv( candidate.monom, var );
+            fglmASSERT( var > 0, "this should never happen" );
+            fglmVector nfv = l.addCols( var, data.getBasisSize(), temp );
+            data.newBorderElem( candidate.monom, nfv );
+            l.insertCols( candidate.divisors, nfv );
+            STICKYPROT( "-" );
+        }
+        candidate.cleanup();
+    } //. while ( data.candidatesLeft() == TRUE )
+    l.endofConstruction();
+    STICKYPROT2( "\nvdim= %i\n", data.getBasisSize() );
+    return;
+}
+
+//     Calculates the defining Functionals for the ideal "theIdeal" and
+//     returns them in "l".
+//     The ideal has to be zero-dimensional and reduced and has to be a
+//     real subset of the polynomal ring.
+//     In any case it has to be zero-dimensional and minimal (check this
+//      via fglmIdealcheck). Any minimal but not reduced ideal is detected.
+//      In this case it returns FglmNotReduced.
+//     If the base domain is Q, the leading coefficients of the polys
+//     have to be in Z.
+//     returns TRUE if the result is valid, FALSE if theIdeal
+//      is not reduced.
+static BOOLEAN
+CalculateFunctionals( const ideal & theIdeal, idealFunctionals & l )
+{
+    fglmSdata data( theIdeal );
+    internalCalculateFunctionals( theIdeal, l, data );
+    return ( data.state() );
+}
+
+static BOOLEAN
+CalculateFunctionals( const ideal & theIdeal, idealFunctionals & l,
+                      poly & p, fglmVector & v )
+{
+    fglmSdata data( theIdeal );
+    internalCalculateFunctionals( theIdeal, l, data );
+    //    STICKYPROT("Calculating vector rep\n");
+    v = data.getVectorRep( p );
+    // if ( v.isZero() )
+    //   STICKYPROT("vectorrep is 0\n");
+    return ( data.state() );
+}
+
+// ============================================================
+//!      The new basis
+// ============================================================
+
+//     The declaration of class fglmDelem is found in fglm.h
+
+fglmDelem::fglmDelem( poly & m, fglmVector mv, int v ) : v( mv ), insertions( 0 ), var( v )
+{
+    monom= m;
+    m= NULL;
+    for ( int k = (currRing->N); k > 0; k-- )
+        if ( pGetExp( monom, k ) > 0 )
+            insertions++;
+    // Wir gehen davon aus, dass ein fglmDelem direkt bei der Erzeugung
+    // auch in eine Liste eingefuegt wird. Daher wird hier automatisch
+    // newDivisor aufgerufen ( v teilt ja m )
+    newDivisor();
+}
+
+void
+fglmDelem::cleanup()
+{
+    if ( monom != NULL )
+    {
+        pLmDelete(&monom);
+    }
+}
+
+class oldGaussElem
+{
+public:
+    fglmVector v;
+    fglmVector p;
+    number pdenom;
+    number fac;
+
+#ifndef HAVE_EXPLICIT_CONSTR
+    oldGaussElem() : v(), p(), pdenom( NULL ), fac( NULL ) {}
+#endif
+    oldGaussElem( const fglmVector newv, const fglmVector newp, number & newpdenom, number & newfac ) : v( newv ), p( newp ), pdenom( newpdenom ), fac( newfac )
+    {
+        newpdenom= NULL;
+        newfac= NULL;
+    }
+    ~oldGaussElem();
+#ifndef HAVE_EXPLICIT_CONSTR
+    void insertElem( const fglmVector newv, const fglmVector newp, number & newpdenom, number & newfac )
+    {
+        v= newv;
+        p= newp;
+        pdenom= newpdenom;
+        fac= newfac;
+        newpdenom= NULL;
+        newfac= NULL;
+    }
+#endif
+};
+
+oldGaussElem::~oldGaussElem()
+{
+    nDelete( & fac );
+    nDelete( & pdenom );
+}
+
+
+class fglmDdata
+{
+private:
+    int dimen;
+    oldGaussElem * gauss;
+    BOOLEAN * isPivot;  // [1]..[dimen]
+    int * perm;  // [1]..[dimen]
+    int basisSize;  //. the CURRENT basisSize, i.e. basisSize <= dimen
+    polyset basis;  // [1]..[dimen]. The monoms of the new Vectorspace-basis
+
+    int* varpermutation;
+
+    int groebnerBS;
+    int groebnerSize;
+    ideal destId;
+
+    List<fglmDelem> nlist;
+public:
+    fglmDdata( int dimension );
+    ~fglmDdata();
+
+    int getBasisSize() const { return basisSize; }
+    BOOLEAN candidatesLeft() const { return ( nlist.isEmpty() ? FALSE : TRUE ); }
+    fglmDelem nextCandidate();
+    void newBasisElem( poly & m, fglmVector v, fglmVector p, number & denom );
+    void updateCandidates( poly m, const fglmVector v );
+    void newGroebnerPoly( fglmVector & v, poly & p );
+    void gaussreduce( fglmVector & v, fglmVector & p, number & denom );
+    ideal buildIdeal()
+    {
+        idSkipZeroes( destId );
+        return destId;
+    }
+};
+
+fglmDdata::fglmDdata( int dimension )
+{
+    int k;
+    dimen= dimension;
+    basisSize= 0;
+    //. All arrays run from [1]..[dimen], thus omAlloc( dimen + 1 )!
+#ifndef HAVE_EXPLICIT_CONSTR
+    gauss= new oldGaussElem[ dimen+1 ];
+#else
+    gauss= (oldGaussElem *)omAlloc( (dimen+1)*sizeof( oldGaussElem ) );
+#endif
+    isPivot= (BOOLEAN *)omAlloc( (dimen+1)*sizeof( BOOLEAN ) );
+    for ( k= dimen; k > 0; k-- ) isPivot[k]= FALSE;
+    perm= (int *)omAlloc( (dimen+1)*sizeof( int ) );
+    basis= (polyset)omAlloc( (dimen+1)*sizeof( poly ) );
+    varpermutation = (int*)omAlloc( ((currRing->N)+1)*sizeof(int) );
+    // Sort ring variables by increasing values (because of weighted orderings)
+    ideal perm_id = idMaxIdeal(1);
+    intvec *iv = idSort(perm_id,TRUE);
+    idDelete(&perm_id);
+    for(int i = (currRing->N); i > 0; i--) varpermutation[(currRing->N)+1-i] = (*iv)[i-1];
+    delete iv;
+
+    groebnerBS= 16;
+    groebnerSize= 0;
+    destId= idInit( groebnerBS, 1 );
+}
+
+fglmDdata::~fglmDdata()
+{
+  // STICKYPROT2("dimen= %i", dimen);
+  // STICKYPROT2("basisSize= %i", basisSize);
+  //    fglmASSERT( dimen == basisSize, "Es wurden nicht alle BasisElemente gefunden!" );
+    int k;
+#ifndef HAVE_EXPLICIT_CONSTR
+    delete [] gauss;
+#else
+    // use basisSize instead of dimen because of fglmquot!
+    for ( k= basisSize; k > 0; k-- )
+        gauss[k].~oldGaussElem();
+    omFreeSize( (ADDRESS)gauss, (dimen+1)*sizeof( oldGaussElem ) );
+#endif
+    omFreeSize( (ADDRESS)isPivot, (dimen+1)*sizeof( BOOLEAN ) );
+    omFreeSize( (ADDRESS)perm, (dimen+1)*sizeof( int ) );
+    // use basisSize instead of dimen because of fglmquot!
+    //. Remember: There is no poly in basis[0], thus k > 0
+    for ( k= basisSize; k > 0; k-- )
+        pLmDelete( basis[k]);
+    omFreeSize( (ADDRESS)basis, (dimen+1)*sizeof( poly ) );
+    omFreeSize( (ADDRESS)varpermutation, ((currRing->N)+1)*sizeof(int) );
+}
+
+fglmDelem
+fglmDdata::nextCandidate()
+{
+    fglmDelem result = nlist.getFirst();
+    nlist.removeFirst();
+    return result;
+}
+
+void
+fglmDdata::newBasisElem( poly & m, fglmVector v, fglmVector p, number & denom )
+{
+// inserts m as a new basis monom. m is NOT copied but directly inserted.
+// returns m=NULL to indicate, that now basis is oweing m.
+    basisSize++;
+    basis[basisSize]= m;
+    m= NULL;
+    int k= 1;
+    while ( nIsZero(v.getconstelem(k)) || isPivot[k] ) {
+        k++;
+    }
+    fglmASSERT( k <= dimen, "Error(1) in fglmDdata::pivot-search");
+    number pivot= v.getconstelem( k );
+    int pivotcol = k;
+    k++;
+    while ( k <= dimen ) {
+        if ( ! nIsZero( v.getconstelem(k) ) && ! isPivot[k] ) {
+            if ( nGreater( v.getconstelem( k ), pivot ) ) {
+                pivot= v.getconstelem( k );
+                pivotcol= k;
+            }
+        }
+        k++;
+    }
+    fglmASSERT( ! nIsZero( pivot ), "Error(2) fglmDdata::Pivotelement ist Null" );
+    isPivot[ pivotcol ]= TRUE;
+    perm[basisSize]= pivotcol;
+
+    pivot= nCopy( v.getconstelem( pivotcol ) );
+#ifndef HAVE_EXPLICIT_CONSTR
+    gauss[basisSize].insertElem( v, p, denom, pivot );
+#else
+    gauss[basisSize].oldGaussElem( v, p, denom, pivot );
+#endif
+}
+
+void
+fglmDdata::updateCandidates( poly m, const fglmVector v )
+{
+    ListIterator<fglmDelem> list = nlist;
+    poly newmonom = NULL;
+    int k = (currRing->N);
+    BOOLEAN done = FALSE;
+    int state = 0;
+    while ( k >= 1 )
+    {
+        newmonom = pCopy( m );
+        pIncrExp( newmonom, varpermutation[k] );
+        pSetm( newmonom );
+        done= FALSE;
+        while ( list.hasItem() && (!done) )
+        {
+            if ( (state= pCmp( list.getItem().monom, newmonom )) < 0 )
+                list++;
+            else done= TRUE;
+        }
+        if ( !done )
+        {
+            nlist.append( fglmDelem( newmonom, v, k ) );
+            break;
+        }
+        if ( state == 0 )
+        {
+            list.getItem().newDivisor();
+            pLmDelete( & newmonom );
+        }
+        else
+        {
+            list.insert( fglmDelem( newmonom, v, k ) );
+        }
+        k--;
+    }
+    while ( --k >= 1 )
+    {
+        newmonom= pCopy( m );
+        pIncrExp( newmonom, varpermutation[k] );
+        pSetm( newmonom );
+        nlist.append( fglmDelem( newmonom, v, k ) );
+    }
+}
+
+void
+fglmDdata::newGroebnerPoly( fglmVector & p, poly & m )
+// Inserts gp = p[1]*basis(1)+..+p[basisSize]*basis(basisSize)+p[basisSize+1]*m as
+//  a new groebner polynomial for the ideal.
+// All elements (monomials and coefficients) of gp are copied, instead of m.
+// Assumes that p.length() == basisSize+1.
+{
+    //. Baue das Polynom von oben nach unten:
+    fglmASSERT( p.size() == basisSize+1, "GP::newGroebnerPoly: p has wrong size" );
+    int k;
+    poly result = m;
+    poly temp = result;
+    m= NULL;
+    if ( nGetChar() > 0 ) {
+        number lead = nCopy( p.getconstelem( basisSize+1 ) );
+        p /= lead;
+        nDelete( & lead );
+    }
+    if ( nGetChar() == 0 ) {
+        number gcd= p.gcd();
+        fglmASSERT( ! nIsZero( gcd ), "FATAL: gcd and thus p is zero" );
+        if ( ! nIsOne( gcd ) )
+            p /= gcd;
+        nDelete( & gcd );
+    }
+    pSetCoeff( result, nCopy( p.getconstelem( basisSize+1 ) ) );
+    for ( k= basisSize; k > 0; k-- ) {
+        if ( ! nIsZero( p.getconstelem( k ) ) ) {
+            temp->next= pCopy( basis[k] );
+            pIter( temp );
+            pSetCoeff( temp, nCopy( p.getconstelem( k ) ) );
+        }
+    }
+    pSetm( result );
+    if ( ! nGreaterZero( pGetCoeff( result ) ) ) result= pNeg( result );
+    if ( groebnerSize == IDELEMS( destId ) ) {
+        pEnlargeSet( & destId->m, IDELEMS( destId ), groebnerBS );
+        IDELEMS( destId )+= groebnerBS;
+    }
+    (destId->m)[groebnerSize]= result;
+    groebnerSize++;
+}
+
+void
+fglmDdata::gaussreduce( fglmVector & v, fglmVector & p, number & pdenom )
+{
+    int k;
+    number fac1, fac2;
+    number temp;
+    fglmASSERT( pdenom == NULL, "pdenom in gaussreduce should be NULL" );
+    pdenom= nInit( 1 );
+    number vdenom = v.clearDenom();
+    if ( ! nIsZero( vdenom ) && ! nIsOne( vdenom ) ) {
+        p.setelem( p.size(), vdenom );
+    }
+    else {
+        nDelete( &vdenom );
+    }
+    number gcd = v.gcd();
+    if ( ! nIsZero( gcd ) && ! nIsOne( gcd ) ) {
+        v /= gcd;
+        number temp= nMult( pdenom, gcd );
+        nDelete( &pdenom );
+        pdenom= temp;
+    }
+    nDelete( & gcd );
+
+    for ( k= 1; k <= basisSize; k++ ) {
+
+        if ( ! v.elemIsZero( perm[k] ) ) {
+            fac1= gauss[k].fac;
+            fac2= nCopy( v.getconstelem( perm[k] ) );
+            v.nihilate( fac1, fac2, gauss[k].v );
+            fac1= nMult( fac1, gauss[k].pdenom );
+            temp= nMult( fac2, pdenom );
+            nDelete( &fac2 );
+            fac2= temp;
+              p.nihilate( fac1, fac2, gauss[k].p );
+            temp= nMult( pdenom, gauss[k].pdenom );
+            nDelete( &pdenom );
+            pdenom= temp;
+
+            nDelete( & fac1 );
+            nDelete( & fac2 );
+            number gcd = v.gcd();
+            if ( ! nIsZero( gcd ) && ! nIsOne( gcd ) )
+            {
+                v /= gcd;
+                number temp= nMult( pdenom, gcd );
+                nDelete( &pdenom );
+                pdenom= temp;
+            }
+            nDelete( & gcd );
+            gcd= p.gcd();
+            temp= n_SubringGcd( pdenom, gcd, currRing->cf );
+            nDelete( &gcd );
+            gcd= temp;
+            if ( ! nIsZero( gcd ) && ! nIsOne( gcd ) )
+            {
+                p /= gcd;
+                temp= nDiv( pdenom, gcd );
+                nDelete( & pdenom );
+                pdenom= temp;
+                nNormalize( pdenom );
+            }
+            nDelete( & gcd );
+        }
+    }
+}
+
+static ideal
+GroebnerViaFunctionals( const idealFunctionals & l,
+                        fglmVector iv = fglmVector() )
+// If iv is zero, calculates the groebnerBasis for the ideal which is
+// defined by l.
+// If iv is not zero, then the groebnerBasis if i:p is calculated where
+// i is defined by l and iv is the vector-representation of nf(p) wrt. i
+// The dimension of l has to be finite.
+// The result is in reduced form.
+{
+    fglmDdata data( l.dimen() );
+
+    // insert pOne() and update workinglist according to iv:
+    fglmVector initv;
+    if ( iv.isZero() ) {
+      // STICKYPROT("initv is zero\n");
+      initv = fglmVector( l.dimen(), 1 );
+    }
+    else {
+      // STICKYPROT("initv is not zero\n");
+      initv = iv;
+    }
+
+    poly one = pOne();
+    data.updateCandidates( one, initv );
+    number nOne = nInit( 1 );
+    data.newBasisElem( one, initv, fglmVector( 1, 1 ), nOne );
+    STICKYPROT( "." );
+    while ( data.candidatesLeft() == TRUE ) {
+        fglmDelem candidate = data.nextCandidate();
+        if ( candidate.isBasisOrEdge() == TRUE ) {
+            // Now we have the chance to find a new groebner polynomial
+
+            // v is the vector-representation of candidate.monom
+            // some elements of v are zeroed in data.gaussreduce(). Which
+            // ones and how this was done is stored in p.
+            // originalV containes the unchanged v, which is later inserted
+            // into the working list (via data.updateCandidates().
+            fglmVector v = l.multiply( candidate.v, candidate.var );
+            fglmVector originalV = v;
+            fglmVector p( data.getBasisSize()+1, data.getBasisSize()+1 );
+            number pdenom = NULL;
+            data.gaussreduce( v, p, pdenom );
+            if ( v.isZero() ) {
+                // Now v is linear dependend to the already found basis elements.
+                // This means that v (rsp. candidate.monom) is the leading
+                // monomial of the next groebner-basis polynomial.
+                data.newGroebnerPoly( p, candidate.monom );
+                nDelete( & pdenom );
+                STICKYPROT( "+" );
+            }
+            else {
+                // no linear dependence could be found, so v ( rsp. monom )
+                // is a basis monomial. We store the zeroed version ( i.e. v
+                // and not originalV ) as well as p, the denomiator and all
+                // the other stuff.
+                // erst updateCandidates, dann newBasisELem!!!
+                data.updateCandidates( candidate.monom, originalV );
+                data.newBasisElem( candidate.monom, v, p, pdenom );
+                STICKYPROT( "." );
+            }
+        }
+        else {
+            STICKYPROT( "-" );
+            candidate.cleanup();
+        }
+    }  //. while data.candidatesLeft()
+    STICKYPROT( "\n" );
+    return ( data.buildIdeal() );
+}
+//<-
+
+static ideal
+FindUnivariatePolys( const idealFunctionals & l )
+{
+    fglmVector v;
+    fglmVector p;
+    ideal destIdeal = idInit( (currRing->N), 1 );
+
+    int i;
+    BOOLEAN isZero;
+    int *varpermutation = (int*)omAlloc( ((currRing->N)+1)*sizeof(int) );
+    ideal perm = idMaxIdeal(1);
+    intvec *iv = idSort(perm,TRUE);
+    idDelete(&perm);
+    for(i = (currRing->N); i > 0; i--) varpermutation[(currRing->N)+1-i] = (*iv)[i-1];
+    delete iv;
+
+    for (i= 1; i <= (currRing->N); i++ )
+    {
+        // main loop
+        STICKYPROT2( "(%i)", i /*varpermutation[i]*/);
+        gaussReducer gauss( l.dimen() );
+        isZero= FALSE;
+        v= fglmVector( l.dimen(), 1 );
+        while ( !isZero )
+        {
+            if ( (isZero= gauss.reduce( v )))
+            {
+                STICKYPROT( "+" );
+                p= gauss.getDependence();
+                number gcd= p.gcd();
+                if ( ! nIsOne( gcd ) )
+                {
+                    p /= gcd;
+                }
+                nDelete( & gcd );
+                int k;
+                poly temp = NULL;
+                poly result;
+                for ( k= p.size(); k > 0; k-- ) {
+                    number n = nCopy( p.getconstelem( k ) );
+                    if ( ! nIsZero( n ) ) {
+                        if ( temp == NULL ) {
+                            result= pOne();
+                            temp= result;
+                        }
+                        else {
+                            temp->next= pOne();
+                            pIter( temp );
+                        }
+                        pSetCoeff( temp, n );
+                        pSetExp( temp, i /*varpermutation[i]*/, k-1 );
+                        pSetm( temp );
+                    }
+                }
+                if ( ! nGreaterZero( pGetCoeff( result ) ) ) result= pNeg( result );
+                (destIdeal->m)[i-1]= result;
+            }
+            else {
+                STICKYPROT( "." );
+                gauss.store();
+                v= l.multiply( v, i /*varpermutation[i]*/ );
+            }
+        }
+    }
+    STICKYPROT( "\n" );
+    omFreeSize( (ADDRESS)varpermutation, ((currRing->N)+1)*sizeof(int) );
+    return destIdeal;
+}
+
+// for a descritption of the parameters see fglm.h
+BOOLEAN
+fglmzero( ring sourceRing, ideal & sourceIdeal, ring destRing, ideal & destIdeal, BOOLEAN switchBack, BOOLEAN deleteIdeal )
+{
+    ring initialRing = currRing;
+    BOOLEAN fglmok;
+
+    if ( currRing != sourceRing )
+    {
+        rChangeCurrRing( sourceRing );
+    }
+    idealFunctionals L( 100, rVar(currRing) );
+    fglmok = CalculateFunctionals( sourceIdeal, L );
+    if ( deleteIdeal == TRUE )
+        idDelete( & sourceIdeal );
+    rChangeCurrRing( destRing );
+    if ( fglmok == TRUE )
+    {
+        L.map( sourceRing );
+        destIdeal= GroebnerViaFunctionals( L );
+    }
+    if ( (switchBack) && (currRing != initialRing) )
+      rChangeCurrRing( initialRing );
+    return fglmok;
+}
+
+BOOLEAN
+fglmquot( ideal sourceIdeal, poly quot, ideal & destIdeal)
+{
+    BOOLEAN fglmok;
+    fglmVector v;
+
+    idealFunctionals L( 100, (currRing->N) );
+    // STICKYPROT("calculating normal form\n");
+    // poly p = kNF( sourceIdeal, currRing->qideal, quot );
+    // STICKYPROT("calculating functionals\n");
+    fglmok = CalculateFunctionals( sourceIdeal, L, quot, v );
+    if ( fglmok == TRUE ) {
+      // STICKYPROT("calculating groebner basis\n");
+        destIdeal= GroebnerViaFunctionals( L, v );
+    }
+    return fglmok;
+}
+
+BOOLEAN
+FindUnivariateWrapper( ideal source, ideal & destIdeal )
+{
+    BOOLEAN fglmok;
+
+    idealFunctionals L( 100, (currRing->N) );
+    fglmok = CalculateFunctionals( source, L );
+    if ( fglmok == TRUE ) {
+        destIdeal= FindUnivariatePolys( L );
+        return TRUE;
+    }
+    else
+        return FALSE;
+}
+
+// ----------------------------------------------------------------------------
+// Local Variables: ***
+// compile-command: "make Singular" ***
+// page-delimiter: "^\\(
\\|//!\\)" ***
+// fold-internal-margins: nil ***
+// End: ***
diff --git a/kernel/fglm/test.cc b/kernel/fglm/test.cc
new file mode 100644
index 0000000..bb2c248
--- /dev/null
+++ b/kernel/fglm/test.cc
@@ -0,0 +1,376 @@
+#include <kernel/mod2.h>
+
+#include <omalloc/omalloc.h>
+
+#include <resources/feFopen.h>
+#include <resources/feResource.h>
+
+
+#include <factory/factory.h> // :(
+
+#include <misc/auxiliary.h>
+#include <misc/intvec.h>
+#include <misc/int64vec.h>
+#include <misc/mylimits.h>
+#include <misc/options.h>
+
+#include <reporter/reporter.h>
+
+#include <coeffs/si_gmp.h>
+#include <coeffs/coeffs.h>
+#include <coeffs/numbers.h>
+
+#ifndef PLURAL_INTERNAL_DECLARATIONS
+#define PLURAL_INTERNAL_DECLARATIONS
+#endif
+
+#ifndef PLURAL_INTERNAL_DECLARATIONS_GB_HACK
+#define PLURAL_INTERNAL_DECLARATIONS_GB_HACK
+#endif
+
+#include <polys/nc/gb_hack.h>
+#include <polys/nc/nc.h>
+#include <polys/nc/ncSACache.h>
+#include <polys/nc/ncSAFormula.h>
+#include <polys/nc/ncSAMult.h>
+#include <polys/nc/sca.h>
+#include <polys/nc/summator.h>
+
+#include <polys/kbuckets.h>
+#include <polys/matpol.h>
+#include <polys/mod_raw.h>
+#include <polys/prCopy.h>
+#include <polys/sbuckets.h>
+#include <polys/simpleideals.h>
+#include <polys/weight.h>
+
+#include <polys/monomials/maps.h>
+#include <polys/monomials/monomials.h>
+#include <polys/monomials/p_polys.h>
+#include <polys/monomials/ring.h>
+
+#include <polys/templates/p_MemAdd.h>
+#include <polys/templates/p_Procs.h>
+
+#include <polys/operations/pShallowCopyDelete.h>
+
+#include <polys/clapsing.h>
+
+
+// // TODO: DUE to the use of HALT in npolygon.cc :(((
+extern "C" {void m2_end(int i){exit(i);}}
+
+// // TODO: DUE to its use in kutil.cc :(((
+// char * showOption(){return NULL;}
+
+
+// #include "structs.h"
+
+
+// HEADERS:
+#include <kernel/ideals.h>
+#include <kernel/digitech.h>
+#include <kernel/fast_mult.h>
+
+// #include <kernel/spectrum/kmatrix.h>
+#include <kernel/preimage.h>
+
+#include <kernel/structs.h>
+
+#include <kernel/polys.h>
+
+void TestGBEngine()
+{
+
+  //  R = MPolynomialRing_polydict(QQ,5,'w,x,y,z,C', order='degrevlex')
+  //  J = (w*w - x*z, w*x - y*z, x*x - w*y, x*y - z*z, y*y - w*z)
+
+  const short w = 1;
+  const short x = 2;
+  const short y = 3;
+  const short z = 4;
+
+  const short N = (z - w + 1);
+
+  char **n=(char**)omalloc(N*sizeof(char*));
+
+
+  n[w-1]=omStrDup("w");
+  n[x-1]=omStrDup("x");
+  n[y-1]=omStrDup("y");
+  n[z-1]=omStrDup("z");
+
+
+  const int D = 3;
+  int *order = (int *) omAlloc0(D* sizeof(int));
+  int *block0 = (int *)omAlloc0(D * sizeof(int));
+  int *block1 = (int *)omAlloc0(D * sizeof(int));
+
+  order[0]  = ringorder_dp;
+  block0[0] = 1;
+  block1[0] = N;
+
+  order[1]  = ringorder_C;
+  block0[1] = 1;
+  block1[1] = N;
+
+  ring R = rDefault(0, N, n, D, order, block0, block1);
+
+//   ring R = rDefault(0, N, n);
+
+  rWrite(R); PrintLn();
+
+#ifdef RDEBUG
+  rDebugPrint(R);
+#endif
+
+  ideal I = idInit(5, 1);
+
+  int gen = 0;
+
+  {
+    // -xz
+    poly p = p_ISet(-1,R);
+
+    p_SetExp(p, x, 1, R);
+    p_SetExp(p, z, 1, R);
+    p_Setm(p, R);
+
+    assume( p_GetExp(p, x, R) == 1 );
+    assume( p_GetExp(p, z, R) == 1 );
+    assume( p_GetExp(p, w, R) == 0 );
+    assume( p_GetExp(p, y, R) == 0 );
+
+    // +w2
+    poly lp = p_ISet(1,R);
+    p_SetExp(lp, w, 2, R);
+    p_Setm(lp, R);
+
+    assume( p_GetExp(lp, w, R) == 2 );
+    assume( p_GetExp(lp, x, R) == 0 );
+    assume( p_GetExp(lp, y, R) == 0 );
+    assume( p_GetExp(lp, z, R) == 0 );
+
+    MATELEM(I, 1, ++gen) = p_Add_q(lp, p, R); // w2 - xz
+  }
+
+  {
+    // -yz
+    poly p = p_ISet(-1,R);
+
+    p_SetExp(p, y, 1, R);
+    p_SetExp(p, z, 1, R);
+    p_Setm(p, R);
+
+    assume( p_GetExp(p, y, R) == 1 );
+    assume( p_GetExp(p, z, R) == 1 );
+    assume( p_GetExp(p, w, R) == 0 );
+    assume( p_GetExp(p, x, R) == 0 );
+
+    // +wx
+    poly lp = p_ISet(1,R);
+    p_SetExp(lp, w, 1, R);
+    p_SetExp(lp, x, 1, R);
+    p_Setm(lp, R);
+
+    assume( p_GetExp(lp, w, R) == 1 );
+    assume( p_GetExp(lp, x, R) == 1 );
+    assume( p_GetExp(lp, y, R) == 0 );
+    assume( p_GetExp(lp, z, R) == 0 );
+
+    MATELEM(I, 1, ++gen) = p_Add_q(lp, p, R); // wx - yz
+  }
+
+
+  {
+    // -wy
+    poly p = p_ISet(-1,R);
+
+    p_SetExp(p, y, 1, R);
+    p_SetExp(p, w, 1, R);
+    p_Setm(p, R);
+
+    assume( p_GetExp(p, y, R) == 1 );
+    assume( p_GetExp(p, w, R) == 1 );
+    assume( p_GetExp(p, z, R) == 0 );
+    assume( p_GetExp(p, x, R) == 0 );
+
+    // +x2
+    poly lp = p_ISet(1,R);
+    p_SetExp(lp, x, 2, R);
+    p_Setm(lp, R);
+
+    assume( p_GetExp(lp, w, R) == 0 );
+    assume( p_GetExp(lp, x, R) == 2 );
+    assume( p_GetExp(lp, y, R) == 0 );
+    assume( p_GetExp(lp, z, R) == 0 );
+
+    MATELEM(I, 1, ++gen) = p_Add_q(lp, p, R); // x2 - wy
+  }
+
+
+  {
+    // -z2
+    poly p = p_ISet(-1,R);
+
+    p_SetExp(p, z, 2, R);
+    p_Setm(p, R);
+
+    assume( p_GetExp(p, y, R) == 0 );
+    assume( p_GetExp(p, w, R) == 0 );
+    assume( p_GetExp(p, z, R) == 2 );
+    assume( p_GetExp(p, x, R) == 0 );
+
+    // +xy
+    poly lp = p_ISet(1,R);
+    p_SetExp(lp, x, 1, R);
+    p_SetExp(lp, y, 1, R);
+    p_Setm(lp, R);
+
+    assume( p_GetExp(lp, w, R) == 0 );
+    assume( p_GetExp(lp, x, R) == 1 );
+    assume( p_GetExp(lp, y, R) == 1 );
+    assume( p_GetExp(lp, z, R) == 0 );
+
+    MATELEM(I, 1, ++gen) = p_Add_q(lp, p, R); // xy - z2
+  }
+
+
+  {
+    // -wz
+    poly p = p_ISet(-1,R);
+
+    p_SetExp(p, w, 1, R);
+    p_SetExp(p, z, 1, R);
+    p_Setm(p, R);
+
+    assume( p_GetExp(p, y, R) == 0 );
+    assume( p_GetExp(p, w, R) == 1 );
+    assume( p_GetExp(p, z, R) == 1 );
+    assume( p_GetExp(p, x, R) == 0 );
+
+    // +y2
+    poly lp = p_ISet(1,R);
+    p_SetExp(lp, y, 2, R);
+    p_Setm(lp, R);
+
+    assume( p_GetExp(lp, w, R) == 0 );
+    assume( p_GetExp(lp, x, R) == 0 );
+    assume( p_GetExp(lp, y, R) == 2 );
+    assume( p_GetExp(lp, z, R) == 0 );
+
+    MATELEM(I, 1, ++gen) = p_Add_q(lp, p, R); // y2 - wz
+  }
+#ifdef PDEBUG
+  PrintS("I: ");
+  idShow(I, R, R, 0);
+#endif
+
+
+//  ideal kStd(ideal F, ideal Q, tHomog h, intvec ** mw,intvec *hilb=NULL,
+//             int syzComp=0,int newIdeal=0, intvec *vw=NULL);
+  // make R the default ring:
+  rChangeCurrRing(R);
+
+ ////
+
+  idDelete( &I, R);
+  rDelete(R); // should cleanup every belonging polynomial, right!?
+
+}
+
+
+
+void TestSimpleRingArithmetcs()
+{
+  // Libpolys tests:
+
+  // construct the ring Z/32003[x,y,z]
+  // the variable names
+  char **n=(char**)omalloc(3*sizeof(char*));
+  n[0]=omStrDup("x");
+  n[1]=omStrDup("y");
+  n[2]=omStrDup("z2");
+
+  ring R = rDefault(32003,3,n); //  ring R = rDefault(0,3,n);
+
+  rWrite(R); PrintLn();
+
+#ifdef RDEBUG
+  rDebugPrint(R);
+#endif
+
+
+  poly p = p_ISet(1,R); p_SetExp(p,1,1, R); p_Setm(p, R);
+
+  assume( p_GetExp(p,1, R) == 1 );
+
+  poly pp = pp_Mult_qq( p, p, R);
+
+  Print("p: "); p_Write0(p, R); Print(", deg(p): %ld", p_Totaldegree(p, R)); assume( 1 == p_Totaldegree(p, R) );
+
+  Print("; p*p : "); p_Write0(pp, R); Print("deg(pp): %ld\n", p_Totaldegree(pp, R)); assume( 2 == p_Totaldegree(pp, R) );
+
+
+  p_Delete(&p, R);
+
+  assume( p_GetExp(pp,1, R) == 2 );
+
+  p_Delete(&pp, R);
+
+
+//  rDelete(R);
+
+  // make R the default ring:
+  rChangeCurrRing(R);
+
+  // create the polynomial 1
+  poly p1=pISet(1);
+
+  // create tthe polynomial 2*x^3*z^2
+  poly p2=p_ISet(2,R);
+  pSetExp(p2,1,3);
+  pSetExp(p2,3,2);
+  pSetm(p2);
+
+  // print p1 + p2
+  Print("p1: "); pWrite0(p1);
+  Print(" + p2: "); pWrite0(p2);
+  Print("  ---- >>>> ");
+
+  // compute p1+p2
+  p1=p_Add_q(p1,p2,R); p2=NULL;
+  pWrite(p1);
+
+  // clean up:
+//  pDelete(&p1);
+
+  rDelete(R); // should cleanup every belonging polynomial, right!?
+}
+
+
+int main( int, char *argv[] )
+{
+  assume( sizeof(long) == SIZEOF_LONG );
+
+  if( sizeof(long) != SIZEOF_LONG )
+  {
+    WerrorS("Bad config.h: wrong size of long!");
+
+    return(1);
+  }
+
+
+  feInitResources(argv[0]);
+
+  StringSetS("ressources in use (as reported by feStringAppendResources(0):\n");
+  feStringAppendResources(0);
+
+  PrintLn();
+  { char* s = StringEndS(); PrintS(s); omFree(s); }
+
+  TestGBEngine();
+  TestSimpleRingArithmetcs();
+
+  return 0;
+}
diff --git a/kernel/groebner_walk/Makefile.am b/kernel/groebner_walk/Makefile.am
new file mode 100644
index 0000000..dbca137
--- /dev/null
+++ b/kernel/groebner_walk/Makefile.am
@@ -0,0 +1,22 @@
+ACLOCAL_AMFLAGS=-I ../../m4
+AM_CPPFLAGS=-I${top_srcdir} -I${top_builddir} -I${top_srcdir}/libpolys -I${top_builddir}/libpolys \
+${FACTORY_INCLUDES} $(OMALLOC_INCLUDES) $(RESOURCES_INCLUDES) \
+${NTL_CFLAGS} $(FLINT_CFLAGS) ${GMP_CFLAGS}
+
+noinst_LTLIBRARIES=libgroebner_walk.la
+libgroebner_walk_la_SOURCES=walkProc.cc walkMain.cc walkSupport.cc
+
+libgroebner_walk_la_includedir=$(includedir)/singular/kernel/groebner_walk
+libgroebner_walk_la_include_HEADERS=walkProc.h walkMain.h walkSupport.h
+
+
+
+TESTS_ENVIRONMENT = SINGULARPATH='${abs_top_builddir}/libpolys/polys/.libs:${abs_top_builddir}/factory/gftables'
+TESTS_ENVIRONMENT += SINGULAR_ROOT_DIR='${abs_top_builddir}'
+
+TESTS = test
+check_PROGRAMS = $(TESTS)
+test_SOURCES = test.cc
+test_LDADD   = libgroebner_walk.la ${builddir}/../libkernelCommon.la
+
+CLEANFILES = $(TESTS)
diff --git a/kernel/groebner_walk/Makefile.in b/kernel/groebner_walk/Makefile.in
new file mode 100644
index 0000000..dfb3614
--- /dev/null
+++ b/kernel/groebner_walk/Makefile.in
@@ -0,0 +1,1086 @@
+# Makefile.in generated by automake 1.13.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 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@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+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@
+TESTS = test$(EXEEXT)
+check_PROGRAMS = $(am__EXEEXT_1)
+subdir = kernel/groebner_walk
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/build-aux/depcomp \
+	$(libgroebner_walk_la_include_HEADERS) \
+	$(top_srcdir)/build-aux/test-driver
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_append_compile_flags.m4 \
+	$(top_srcdir)/m4/ax_append_flag.m4 \
+	$(top_srcdir)/m4/ax_append_link_flags.m4 \
+	$(top_srcdir)/m4/ax_check_compile_flag.m4 \
+	$(top_srcdir)/m4/ax_check_link_flag.m4 \
+	$(top_srcdir)/m4/ax_compute_relative_paths.m4 \
+	$(top_srcdir)/m4/ax_normalize_path.m4 \
+	$(top_srcdir)/m4/ax_prefix_config_h.m4 \
+	$(top_srcdir)/m4/ax_pthread.m4 \
+	$(top_srcdir)/m4/ax_python_embed.m4 \
+	$(top_srcdir)/m4/ax_python_with_version.m4 \
+	$(top_srcdir)/m4/cpu-check.m4 $(top_srcdir)/m4/dbm-check.m4 \
+	$(top_srcdir)/m4/flags.m4 $(top_srcdir)/m4/flint-check.m4 \
+	$(top_srcdir)/m4/gfanlib-check.m4 \
+	$(top_srcdir)/m4/gmp-check.m4 \
+	$(top_srcdir)/m4/google-perftools.m4 \
+	$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+	$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+	$(top_srcdir)/m4/lt~obsolete.m4 \
+	$(top_srcdir)/m4/mathic-check.m4 $(top_srcdir)/m4/ntl-check.m4 \
+	$(top_srcdir)/m4/options.m4 $(top_srcdir)/m4/p-procs.m4 \
+	$(top_srcdir)/m4/polymake-check.m4 \
+	$(top_srcdir)/m4/readline-check.m4 $(top_srcdir)/configure.ac
+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 =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+libgroebner_walk_la_LIBADD =
+am_libgroebner_walk_la_OBJECTS = walkProc.lo walkMain.lo \
+	walkSupport.lo
+libgroebner_walk_la_OBJECTS = $(am_libgroebner_walk_la_OBJECTS)
+AM_V_lt = $(am__v_lt_ at AM_V@)
+am__v_lt_ = $(am__v_lt_ at AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 = 
+am__EXEEXT_1 = test$(EXEEXT)
+am_test_OBJECTS = test.$(OBJEXT)
+test_OBJECTS = $(am_test_OBJECTS)
+test_DEPENDENCIES = libgroebner_walk.la \
+	${builddir}/../libkernelCommon.la
+AM_V_P = $(am__v_P_ at AM_V@)
+am__v_P_ = $(am__v_P_ at AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_ at AM_V@)
+am__v_GEN_ = $(am__v_GEN_ at AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_ at AM_V@)
+am__v_at_ = $(am__v_at_ at AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+DEFAULT_INCLUDES = -I. at am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \
+	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+	$(AM_CXXFLAGS) $(CXXFLAGS)
+AM_V_CXX = $(am__v_CXX_ at AM_V@)
+am__v_CXX_ = $(am__v_CXX_ at AM_DEFAULT_V@)
+am__v_CXX_0 = @echo "  CXX     " $@;
+am__v_CXX_1 = 
+CXXLD = $(CXX)
+CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+	$(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CXXLD = $(am__v_CXXLD_ at AM_V@)
+am__v_CXXLD_ = $(am__v_CXXLD_ at AM_DEFAULT_V@)
+am__v_CXXLD_0 = @echo "  CXXLD   " $@;
+am__v_CXXLD_1 = 
+SOURCES = $(libgroebner_walk_la_SOURCES) $(test_SOURCES)
+DIST_SOURCES = $(libgroebner_walk_la_SOURCES) $(test_SOURCES)
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+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__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
+am__installdirs = "$(DESTDIR)$(libgroebner_walk_la_includedir)"
+HEADERS = $(libgroebner_walk_la_include_HEADERS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors_dummy = \
+  mgn= red= grn= lgn= blu= brg= std=; \
+  am__color_tests=no
+am__tty_colors = { \
+  $(am__tty_colors_dummy); \
+  if test "X$(AM_COLOR_TESTS)" = Xno; then \
+    am__color_tests=no; \
+  elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+    am__color_tests=yes; \
+  elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+    am__color_tests=yes; \
+  fi; \
+  if test $$am__color_tests = yes; then \
+    red=''; \
+    grn=''; \
+    lgn=''; \
+    blu=''; \
+    mgn=''; \
+    brg=''; \
+    std=''; \
+  fi; \
+}
+am__recheck_rx = ^[ 	]*:recheck:[ 	]*
+am__global_test_result_rx = ^[ 	]*:global-test-result:[ 	]*
+am__copy_in_global_log_rx = ^[ 	]*:copy-in-global-log:[ 	]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+  recheck = 1; \
+  while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+    { \
+      if (rc < 0) \
+        { \
+          if ((getline line2 < ($$0 ".log")) < 0) \
+	    recheck = 0; \
+          break; \
+        } \
+      else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+        { \
+          recheck = 0; \
+          break; \
+        } \
+      else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+        { \
+          break; \
+        } \
+    }; \
+  if (recheck) \
+    print $$0; \
+  close ($$0 ".trs"); \
+  close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+  print "fatal: making $@: " msg | "cat >&2"; \
+  exit 1; \
+} \
+function rst_section(header) \
+{ \
+  print header; \
+  len = length(header); \
+  for (i = 1; i <= len; i = i + 1) \
+    printf "="; \
+  printf "\n\n"; \
+} \
+{ \
+  copy_in_global_log = 1; \
+  global_test_result = "RUN"; \
+  while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+    { \
+      if (rc < 0) \
+         fatal("failed to read from " $$0 ".trs"); \
+      if (line ~ /$(am__global_test_result_rx)/) \
+        { \
+          sub("$(am__global_test_result_rx)", "", line); \
+          sub("[ 	]*$$", "", line); \
+          global_test_result = line; \
+        } \
+      else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+        copy_in_global_log = 0; \
+    }; \
+  if (copy_in_global_log) \
+    { \
+      rst_section(global_test_result ": " $$0); \
+      while ((rc = (getline line < ($$0 ".log"))) != 0) \
+      { \
+        if (rc < 0) \
+          fatal("failed to read from " $$0 ".log"); \
+        print line; \
+      }; \
+      printf "\n"; \
+    }; \
+  close ($$0 ".trs"); \
+  close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/   &   /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this.  Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+  --color-tests "$$am__color_tests" \
+  --enable-hard-errors "$$am__enable_hard_errors" \
+  --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test.  Creates the
+# directory for the log if needed.  Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log.  Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT.  Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup);					\
+$(am__vpath_adj_setup) $(am__vpath_adj)			\
+$(am__tty_colors);					\
+srcdir=$(srcdir); export srcdir;			\
+case "$@" in						\
+  */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;;	\
+    *) am__odir=.;; 					\
+esac;							\
+test "x$$am__odir" = x"." || test -d "$$am__odir" 	\
+  || $(MKDIR_P) "$$am__odir" || exit $$?;		\
+if test -f "./$$f"; then dir=./;			\
+elif test -f "$$f"; then dir=;				\
+else dir="$(srcdir)/"; fi;				\
+tst=$$dir$$f; log='$@'; 				\
+if test -n '$(DISABLE_HARD_ERRORS)'; then		\
+  am__enable_hard_errors=no; 				\
+else							\
+  am__enable_hard_errors=yes; 				\
+fi; 							\
+case " $(XFAIL_TESTS) " in				\
+  *[\ \	]$$f[\ \	]* | *[\ \	]$$dir$$f[\ \	]*) \
+    am__expect_failure=yes;;				\
+  *)							\
+    am__expect_failure=no;;				\
+esac; 							\
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed).  The result is saved in the shell variable
+# '$bases'.  This honors runtime overriding of TESTS and TEST_LOGS.  Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+  bases='$(TEST_LOGS)'; \
+  bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+  bases=`echo $$bases`
+RECHECK_LOGS = $(TEST_LOGS)
+AM_RECURSIVE_TARGETS = check recheck
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+  case '$@' in \
+    */*) \
+      case '$*' in \
+        */*) b='$*';; \
+          *) b=`echo '$@' | sed 's/\.log$$//'`; \
+       esac;; \
+    *) \
+      b='$*';; \
+  esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT at .log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+	$(TEST_LOG_FLAGS)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BUILTIN_LIBS = @BUILTIN_LIBS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CDDGMPCPPFLAGS = @CDDGMPCPPFLAGS@
+CDDGMPLDFLAGS = @CDDGMPLDFLAGS@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATA_DIR = @DATA_DIR@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DOC_DIR = @DOC_DIR@
+DOXYGEN = @DOXYGEN@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FACTORY_INCLUDES = @FACTORY_INCLUDES@
+FACTORY_LIBS = @FACTORY_LIBS@
+FGREP = @FGREP@
+FLINT_CFLAGS = @FLINT_CFLAGS@
+FLINT_HOME = @FLINT_HOME@
+FLINT_LIBS = @FLINT_LIBS@
+GMP_CFLAGS = @GMP_CFLAGS@
+GMP_HOME = @GMP_HOME@
+GMP_LIBS = @GMP_LIBS@
+GMP_VERSION = @GMP_VERSION@
+GREP = @GREP@
+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@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NTL_CFLAGS = @NTL_CFLAGS@
+NTL_LIBS = @NTL_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OMALLOC_INCLUDES = @OMALLOC_INCLUDES@
+OMALLOC_LIBS = @OMALLOC_LIBS@
+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@
+PKG_REQUIRE = @PKG_REQUIRE@
+PMCONFIG = @PMCONFIG@
+PM_CFLAGS = @PM_CFLAGS@
+PM_INC = @PM_INC@
+PM_LDFLAGS = @PM_LDFLAGS@
+PM_LIBS = @PM_LIBS@
+POLYMAKE_CXXFLAGS = @POLYMAKE_CXXFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LDFLAGS = @PTHREAD_LDFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
+PYTHON = @PYTHON@
+PYTHON_CSPEC = @PYTHON_CSPEC@
+PYTHON_EXECPREFIX = @PYTHON_EXECPREFIX@
+PYTHON_LSPEC = @PYTHON_LSPEC@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+RANLIB = @RANLIB@
+RESOURCES_INCLUDES = @RESOURCES_INCLUDES@
+RESOURCES_LIBS = @RESOURCES_LIBS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SINGULAR_CFLAGS = @SINGULAR_CFLAGS@
+SI_COUNTEDREF_AUTOLOAD = @SI_COUNTEDREF_AUTOLOAD@
+SI_CPU_I386 = @SI_CPU_I386@
+SI_CPU_IA64 = @SI_CPU_IA64@
+SI_CPU_PPC = @SI_CPU_PPC@
+SI_CPU_SPARC = @SI_CPU_SPARC@
+SI_CPU_X86_64 = @SI_CPU_X86_64@
+STRIP = @STRIP@
+USEPPROCSDYNAMICLD = @USEPPROCSDYNAMICLD@
+USEPPROCSDYNAMICLDFLAGS = @USEPPROCSDYNAMICLDFLAGS@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
+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@
+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@
+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@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+ACLOCAL_AMFLAGS = -I ../../m4
+AM_CPPFLAGS = -I${top_srcdir} -I${top_builddir} -I${top_srcdir}/libpolys -I${top_builddir}/libpolys \
+${FACTORY_INCLUDES} $(OMALLOC_INCLUDES) $(RESOURCES_INCLUDES) \
+${NTL_CFLAGS} $(FLINT_CFLAGS) ${GMP_CFLAGS}
+
+noinst_LTLIBRARIES = libgroebner_walk.la
+libgroebner_walk_la_SOURCES = walkProc.cc walkMain.cc walkSupport.cc
+libgroebner_walk_la_includedir = $(includedir)/singular/kernel/groebner_walk
+libgroebner_walk_la_include_HEADERS = walkProc.h walkMain.h walkSupport.h
+TESTS_ENVIRONMENT = SINGULARPATH='${abs_top_builddir}/libpolys/polys/.libs:${abs_top_builddir}/factory/gftables' \
+	SINGULAR_ROOT_DIR='${abs_top_builddir}'
+test_SOURCES = test.cc
+test_LDADD = libgroebner_walk.la ${builddir}/../libkernelCommon.la
+CLEANFILES = $(TESTS)
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .cc .lo .log .o .obj .test .test$(EXEEXT) .trs
+$(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) --foreign kernel/groebner_walk/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign kernel/groebner_walk/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-noinstLTLIBRARIES:
+	-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+	@list='$(noinst_LTLIBRARIES)'; \
+	locs=`for p in $$list; do echo $$p; done | \
+	      sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+	      sort -u`; \
+	test -z "$$locs" || { \
+	  echo rm -f $${locs}; \
+	  rm -f $${locs}; \
+	}
+
+libgroebner_walk.la: $(libgroebner_walk_la_OBJECTS) $(libgroebner_walk_la_DEPENDENCIES) $(EXTRA_libgroebner_walk_la_DEPENDENCIES) 
+	$(AM_V_CXXLD)$(CXXLINK)  $(libgroebner_walk_la_OBJECTS) $(libgroebner_walk_la_LIBADD) $(LIBS)
+
+clean-checkPROGRAMS:
+	@list='$(check_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
+
+test$(EXEEXT): $(test_OBJECTS) $(test_DEPENDENCIES) $(EXTRA_test_DEPENDENCIES) 
+	@rm -f test$(EXEEXT)
+	$(AM_V_CXXLD)$(CXXLINK) $(test_OBJECTS) $(test_LDADD) $(LIBS)
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/test.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/walkMain.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/walkProc.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/walkSupport.Plo at am__quote@
+
+.cc.o:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+ at am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXXCOMPILE) -c -o $@ $<
+
+.cc.obj:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+ at am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.cc.lo:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+ at am__fastdepCXX_TRUE@	$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LTCXXCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+install-libgroebner_walk_la_includeHEADERS: $(libgroebner_walk_la_include_HEADERS)
+	@$(NORMAL_INSTALL)
+	@list='$(libgroebner_walk_la_include_HEADERS)'; test -n "$(libgroebner_walk_la_includedir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(libgroebner_walk_la_includedir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(libgroebner_walk_la_includedir)" || exit 1; \
+	fi; \
+	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)$(libgroebner_walk_la_includedir)'"; \
+	  $(INSTALL_HEADER) $$files "$(DESTDIR)$(libgroebner_walk_la_includedir)" || exit $$?; \
+	done
+
+uninstall-libgroebner_walk_la_includeHEADERS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(libgroebner_walk_la_include_HEADERS)'; test -n "$(libgroebner_walk_la_includedir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	dir='$(DESTDIR)$(libgroebner_walk_la_includedir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	$(am__define_uniq_tagged_files); \
+	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-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	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"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'.  Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+	rm -f $< $@
+	$(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+	@:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+	@$(am__set_TESTS_bases); \
+	am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+	redo_bases=`for i in $$bases; do \
+	              am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+	            done`; \
+	if test -n "$$redo_bases"; then \
+	  redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+	  redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+	  if $(am__make_dryrun); then :; else \
+	    rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+	  fi; \
+	fi; \
+	if test -n "$$am__remaking_logs"; then \
+	  echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+	       "recursion detected" >&2; \
+	else \
+	  am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+	fi; \
+	if $(am__make_dryrun); then :; else \
+	  st=0;  \
+	  errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+	  for i in $$redo_bases; do \
+	    test -f $$i.trs && test -r $$i.trs \
+	      || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+	    test -f $$i.log && test -r $$i.log \
+	      || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+	  done; \
+	  test $$st -eq 0 || exit 1; \
+	fi
+	@$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+	ws='[ 	]'; \
+	results=`for b in $$bases; do echo $$b.trs; done`; \
+	test -n "$$results" || results=/dev/null; \
+	all=`  grep "^$$ws*:test-result:"           $$results | wc -l`; \
+	pass=` grep "^$$ws*:test-result:$$ws*PASS"  $$results | wc -l`; \
+	fail=` grep "^$$ws*:test-result:$$ws*FAIL"  $$results | wc -l`; \
+	skip=` grep "^$$ws*:test-result:$$ws*SKIP"  $$results | wc -l`; \
+	xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+	xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+	error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+	if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+	  success=true; \
+	else \
+	  success=false; \
+	fi; \
+	br='==================='; br=$$br$$br$$br$$br; \
+	result_count () \
+	{ \
+	    if test x"$$1" = x"--maybe-color"; then \
+	      maybe_colorize=yes; \
+	    elif test x"$$1" = x"--no-color"; then \
+	      maybe_colorize=no; \
+	    else \
+	      echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+	    fi; \
+	    shift; \
+	    desc=$$1 count=$$2; \
+	    if test $$maybe_colorize = yes && test $$count -gt 0; then \
+	      color_start=$$3 color_end=$$std; \
+	    else \
+	      color_start= color_end=; \
+	    fi; \
+	    echo "$${color_start}# $$desc $$count$${color_end}"; \
+	}; \
+	create_testsuite_report () \
+	{ \
+	  result_count $$1 "TOTAL:" $$all   "$$brg"; \
+	  result_count $$1 "PASS: " $$pass  "$$grn"; \
+	  result_count $$1 "SKIP: " $$skip  "$$blu"; \
+	  result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+	  result_count $$1 "FAIL: " $$fail  "$$red"; \
+	  result_count $$1 "XPASS:" $$xpass "$$red"; \
+	  result_count $$1 "ERROR:" $$error "$$mgn"; \
+	}; \
+	{								\
+	  echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" |	\
+	    $(am__rst_title);						\
+	  create_testsuite_report --no-color;				\
+	  echo;								\
+	  echo ".. contents:: :depth: 2";				\
+	  echo;								\
+	  for b in $$bases; do echo $$b; done				\
+	    | $(am__create_global_log);					\
+	} >$(TEST_SUITE_LOG).tmp || exit 1;				\
+	mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG);			\
+	if $$success; then						\
+	  col="$$grn";							\
+	 else								\
+	  col="$$red";							\
+	  test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG);		\
+	fi;								\
+	echo "$${col}$$br$${std}"; 					\
+	echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}";	\
+	echo "$${col}$$br$${std}"; 					\
+	create_testsuite_report --maybe-color;				\
+	echo "$$col$$br$$std";						\
+	if $$success; then :; else					\
+	  echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}";		\
+	  if test -n "$(PACKAGE_BUGREPORT)"; then			\
+	    echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}";	\
+	  fi;								\
+	  echo "$$col$$br$$std";					\
+	fi;								\
+	$$success || exit 1
+
+check-TESTS:
+	@list='$(RECHECK_LOGS)';           test -z "$$list" || rm -f $$list
+	@list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+	@test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+	@set +e; $(am__set_TESTS_bases); \
+	log_list=`for i in $$bases; do echo $$i.log; done`; \
+	trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+	log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+	$(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+	exit $$?;
+recheck: all $(check_PROGRAMS)
+	@test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+	@set +e; $(am__set_TESTS_bases); \
+	bases=`for i in $$bases; do echo $$i; done \
+	         | $(am__list_recheck_tests)` || exit 1; \
+	log_list=`for i in $$bases; do echo $$i.log; done`; \
+	log_list=`echo $$log_list`; \
+	$(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+	        am__force_recheck=am--force-recheck \
+	        TEST_LOGS="$$log_list"; \
+	exit $$?
+test.log: test$(EXEEXT)
+	@p='test$(EXEEXT)'; \
+	b='test'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+.test.log:
+	@p='$<'; \
+	$(am__set_b); \
+	$(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+ at am__EXEEXT_TRUE@.test$(EXEEXT).log:
+ at am__EXEEXT_TRUE@	@p='$<'; \
+ at am__EXEEXT_TRUE@	$(am__set_b); \
+ at am__EXEEXT_TRUE@	$(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ at am__EXEEXT_TRUE@	--log-file $$b.log --trs-file $$b.trs \
+ at am__EXEEXT_TRUE@	$(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ at am__EXEEXT_TRUE@	"$$tst" $(AM_TESTS_FD_REDIRECT)
+
+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_PROGRAMS)
+	$(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(HEADERS)
+installdirs:
+	for dir in "$(DESTDIR)$(libgroebner_walk_la_includedir)"; 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:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+	-test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+	-test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+	-test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+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-checkPROGRAMS clean-generic clean-libtool \
+	clean-noinstLTLIBRARIES 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-libgroebner_walk_la_includeHEADERS
+
+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: uninstall-libgroebner_walk_la_includeHEADERS
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am clean \
+	clean-checkPROGRAMS clean-generic clean-libtool \
+	clean-noinstLTLIBRARIES cscopelist-am ctags ctags-am 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-libgroebner_walk_la_includeHEADERS 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 recheck tags tags-am uninstall \
+	uninstall-am uninstall-libgroebner_walk_la_includeHEADERS
+
+
+# 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/kernel/groebner_walk/test.cc b/kernel/groebner_walk/test.cc
new file mode 100644
index 0000000..bb2c248
--- /dev/null
+++ b/kernel/groebner_walk/test.cc
@@ -0,0 +1,376 @@
+#include <kernel/mod2.h>
+
+#include <omalloc/omalloc.h>
+
+#include <resources/feFopen.h>
+#include <resources/feResource.h>
+
+
+#include <factory/factory.h> // :(
+
+#include <misc/auxiliary.h>
+#include <misc/intvec.h>
+#include <misc/int64vec.h>
+#include <misc/mylimits.h>
+#include <misc/options.h>
+
+#include <reporter/reporter.h>
+
+#include <coeffs/si_gmp.h>
+#include <coeffs/coeffs.h>
+#include <coeffs/numbers.h>
+
+#ifndef PLURAL_INTERNAL_DECLARATIONS
+#define PLURAL_INTERNAL_DECLARATIONS
+#endif
+
+#ifndef PLURAL_INTERNAL_DECLARATIONS_GB_HACK
+#define PLURAL_INTERNAL_DECLARATIONS_GB_HACK
+#endif
+
+#include <polys/nc/gb_hack.h>
+#include <polys/nc/nc.h>
+#include <polys/nc/ncSACache.h>
+#include <polys/nc/ncSAFormula.h>
+#include <polys/nc/ncSAMult.h>
+#include <polys/nc/sca.h>
+#include <polys/nc/summator.h>
+
+#include <polys/kbuckets.h>
+#include <polys/matpol.h>
+#include <polys/mod_raw.h>
+#include <polys/prCopy.h>
+#include <polys/sbuckets.h>
+#include <polys/simpleideals.h>
+#include <polys/weight.h>
+
+#include <polys/monomials/maps.h>
+#include <polys/monomials/monomials.h>
+#include <polys/monomials/p_polys.h>
+#include <polys/monomials/ring.h>
+
+#include <polys/templates/p_MemAdd.h>
+#include <polys/templates/p_Procs.h>
+
+#include <polys/operations/pShallowCopyDelete.h>
+
+#include <polys/clapsing.h>
+
+
+// // TODO: DUE to the use of HALT in npolygon.cc :(((
+extern "C" {void m2_end(int i){exit(i);}}
+
+// // TODO: DUE to its use in kutil.cc :(((
+// char * showOption(){return NULL;}
+
+
+// #include "structs.h"
+
+
+// HEADERS:
+#include <kernel/ideals.h>
+#include <kernel/digitech.h>
+#include <kernel/fast_mult.h>
+
+// #include <kernel/spectrum/kmatrix.h>
+#include <kernel/preimage.h>
+
+#include <kernel/structs.h>
+
+#include <kernel/polys.h>
+
+void TestGBEngine()
+{
+
+  //  R = MPolynomialRing_polydict(QQ,5,'w,x,y,z,C', order='degrevlex')
+  //  J = (w*w - x*z, w*x - y*z, x*x - w*y, x*y - z*z, y*y - w*z)
+
+  const short w = 1;
+  const short x = 2;
+  const short y = 3;
+  const short z = 4;
+
+  const short N = (z - w + 1);
+
+  char **n=(char**)omalloc(N*sizeof(char*));
+
+
+  n[w-1]=omStrDup("w");
+  n[x-1]=omStrDup("x");
+  n[y-1]=omStrDup("y");
+  n[z-1]=omStrDup("z");
+
+
+  const int D = 3;
+  int *order = (int *) omAlloc0(D* sizeof(int));
+  int *block0 = (int *)omAlloc0(D * sizeof(int));
+  int *block1 = (int *)omAlloc0(D * sizeof(int));
+
+  order[0]  = ringorder_dp;
+  block0[0] = 1;
+  block1[0] = N;
+
+  order[1]  = ringorder_C;
+  block0[1] = 1;
+  block1[1] = N;
+
+  ring R = rDefault(0, N, n, D, order, block0, block1);
+
+//   ring R = rDefault(0, N, n);
+
+  rWrite(R); PrintLn();
+
+#ifdef RDEBUG
+  rDebugPrint(R);
+#endif
+
+  ideal I = idInit(5, 1);
+
+  int gen = 0;
+
+  {
+    // -xz
+    poly p = p_ISet(-1,R);
+
+    p_SetExp(p, x, 1, R);
+    p_SetExp(p, z, 1, R);
+    p_Setm(p, R);
+
+    assume( p_GetExp(p, x, R) == 1 );
+    assume( p_GetExp(p, z, R) == 1 );
+    assume( p_GetExp(p, w, R) == 0 );
+    assume( p_GetExp(p, y, R) == 0 );
+
+    // +w2
+    poly lp = p_ISet(1,R);
+    p_SetExp(lp, w, 2, R);
+    p_Setm(lp, R);
+
+    assume( p_GetExp(lp, w, R) == 2 );
+    assume( p_GetExp(lp, x, R) == 0 );
+    assume( p_GetExp(lp, y, R) == 0 );
+    assume( p_GetExp(lp, z, R) == 0 );
+
+    MATELEM(I, 1, ++gen) = p_Add_q(lp, p, R); // w2 - xz
+  }
+
+  {
+    // -yz
+    poly p = p_ISet(-1,R);
+
+    p_SetExp(p, y, 1, R);
+    p_SetExp(p, z, 1, R);
+    p_Setm(p, R);
+
+    assume( p_GetExp(p, y, R) == 1 );
+    assume( p_GetExp(p, z, R) == 1 );
+    assume( p_GetExp(p, w, R) == 0 );
+    assume( p_GetExp(p, x, R) == 0 );
+
+    // +wx
+    poly lp = p_ISet(1,R);
+    p_SetExp(lp, w, 1, R);
+    p_SetExp(lp, x, 1, R);
+    p_Setm(lp, R);
+
+    assume( p_GetExp(lp, w, R) == 1 );
+    assume( p_GetExp(lp, x, R) == 1 );
+    assume( p_GetExp(lp, y, R) == 0 );
+    assume( p_GetExp(lp, z, R) == 0 );
+
+    MATELEM(I, 1, ++gen) = p_Add_q(lp, p, R); // wx - yz
+  }
+
+
+  {
+    // -wy
+    poly p = p_ISet(-1,R);
+
+    p_SetExp(p, y, 1, R);
+    p_SetExp(p, w, 1, R);
+    p_Setm(p, R);
+
+    assume( p_GetExp(p, y, R) == 1 );
+    assume( p_GetExp(p, w, R) == 1 );
+    assume( p_GetExp(p, z, R) == 0 );
+    assume( p_GetExp(p, x, R) == 0 );
+
+    // +x2
+    poly lp = p_ISet(1,R);
+    p_SetExp(lp, x, 2, R);
+    p_Setm(lp, R);
+
+    assume( p_GetExp(lp, w, R) == 0 );
+    assume( p_GetExp(lp, x, R) == 2 );
+    assume( p_GetExp(lp, y, R) == 0 );
+    assume( p_GetExp(lp, z, R) == 0 );
+
+    MATELEM(I, 1, ++gen) = p_Add_q(lp, p, R); // x2 - wy
+  }
+
+
+  {
+    // -z2
+    poly p = p_ISet(-1,R);
+
+    p_SetExp(p, z, 2, R);
+    p_Setm(p, R);
+
+    assume( p_GetExp(p, y, R) == 0 );
+    assume( p_GetExp(p, w, R) == 0 );
+    assume( p_GetExp(p, z, R) == 2 );
+    assume( p_GetExp(p, x, R) == 0 );
+
+    // +xy
+    poly lp = p_ISet(1,R);
+    p_SetExp(lp, x, 1, R);
+    p_SetExp(lp, y, 1, R);
+    p_Setm(lp, R);
+
+    assume( p_GetExp(lp, w, R) == 0 );
+    assume( p_GetExp(lp, x, R) == 1 );
+    assume( p_GetExp(lp, y, R) == 1 );
+    assume( p_GetExp(lp, z, R) == 0 );
+
+    MATELEM(I, 1, ++gen) = p_Add_q(lp, p, R); // xy - z2
+  }
+
+
+  {
+    // -wz
+    poly p = p_ISet(-1,R);
+
+    p_SetExp(p, w, 1, R);
+    p_SetExp(p, z, 1, R);
+    p_Setm(p, R);
+
+    assume( p_GetExp(p, y, R) == 0 );
+    assume( p_GetExp(p, w, R) == 1 );
+    assume( p_GetExp(p, z, R) == 1 );
+    assume( p_GetExp(p, x, R) == 0 );
+
+    // +y2
+    poly lp = p_ISet(1,R);
+    p_SetExp(lp, y, 2, R);
+    p_Setm(lp, R);
+
+    assume( p_GetExp(lp, w, R) == 0 );
+    assume( p_GetExp(lp, x, R) == 0 );
+    assume( p_GetExp(lp, y, R) == 2 );
+    assume( p_GetExp(lp, z, R) == 0 );
+
+    MATELEM(I, 1, ++gen) = p_Add_q(lp, p, R); // y2 - wz
+  }
+#ifdef PDEBUG
+  PrintS("I: ");
+  idShow(I, R, R, 0);
+#endif
+
+
+//  ideal kStd(ideal F, ideal Q, tHomog h, intvec ** mw,intvec *hilb=NULL,
+//             int syzComp=0,int newIdeal=0, intvec *vw=NULL);
+  // make R the default ring:
+  rChangeCurrRing(R);
+
+ ////
+
+  idDelete( &I, R);
+  rDelete(R); // should cleanup every belonging polynomial, right!?
+
+}
+
+
+
+void TestSimpleRingArithmetcs()
+{
+  // Libpolys tests:
+
+  // construct the ring Z/32003[x,y,z]
+  // the variable names
+  char **n=(char**)omalloc(3*sizeof(char*));
+  n[0]=omStrDup("x");
+  n[1]=omStrDup("y");
+  n[2]=omStrDup("z2");
+
+  ring R = rDefault(32003,3,n); //  ring R = rDefault(0,3,n);
+
+  rWrite(R); PrintLn();
+
+#ifdef RDEBUG
+  rDebugPrint(R);
+#endif
+
+
+  poly p = p_ISet(1,R); p_SetExp(p,1,1, R); p_Setm(p, R);
+
+  assume( p_GetExp(p,1, R) == 1 );
+
+  poly pp = pp_Mult_qq( p, p, R);
+
+  Print("p: "); p_Write0(p, R); Print(", deg(p): %ld", p_Totaldegree(p, R)); assume( 1 == p_Totaldegree(p, R) );
+
+  Print("; p*p : "); p_Write0(pp, R); Print("deg(pp): %ld\n", p_Totaldegree(pp, R)); assume( 2 == p_Totaldegree(pp, R) );
+
+
+  p_Delete(&p, R);
+
+  assume( p_GetExp(pp,1, R) == 2 );
+
+  p_Delete(&pp, R);
+
+
+//  rDelete(R);
+
+  // make R the default ring:
+  rChangeCurrRing(R);
+
+  // create the polynomial 1
+  poly p1=pISet(1);
+
+  // create tthe polynomial 2*x^3*z^2
+  poly p2=p_ISet(2,R);
+  pSetExp(p2,1,3);
+  pSetExp(p2,3,2);
+  pSetm(p2);
+
+  // print p1 + p2
+  Print("p1: "); pWrite0(p1);
+  Print(" + p2: "); pWrite0(p2);
+  Print("  ---- >>>> ");
+
+  // compute p1+p2
+  p1=p_Add_q(p1,p2,R); p2=NULL;
+  pWrite(p1);
+
+  // clean up:
+//  pDelete(&p1);
+
+  rDelete(R); // should cleanup every belonging polynomial, right!?
+}
+
+
+int main( int, char *argv[] )
+{
+  assume( sizeof(long) == SIZEOF_LONG );
+
+  if( sizeof(long) != SIZEOF_LONG )
+  {
+    WerrorS("Bad config.h: wrong size of long!");
+
+    return(1);
+  }
+
+
+  feInitResources(argv[0]);
+
+  StringSetS("ressources in use (as reported by feStringAppendResources(0):\n");
+  feStringAppendResources(0);
+
+  PrintLn();
+  { char* s = StringEndS(); PrintS(s); omFree(s); }
+
+  TestGBEngine();
+  TestSimpleRingArithmetcs();
+
+  return 0;
+}
diff --git a/kernel/groebner_walk/walkMain.cc b/kernel/groebner_walk/walkMain.cc
new file mode 100644
index 0000000..20b9add
--- /dev/null
+++ b/kernel/groebner_walk/walkMain.cc
@@ -0,0 +1,662 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+ * ABSTRACT: fractal walk stuff
+ *
+*/
+#include <kernel/mod2.h>
+
+#include <misc/options.h>
+#include <misc/intvec.h>
+#include <misc/int64vec.h>
+
+#include <polys/prCopy.h>
+#include <polys/matpol.h>
+#include <polys/monomials/ring.h>
+
+#include <kernel/polys.h>
+#include <kernel/ideals.h>
+#include <kernel/groebner_walk/walkMain.h>
+#include <kernel/groebner_walk/walkSupport.h>
+#include <kernel/GBEngine/kstd1.h>
+
+#include <string.h>
+
+///////////////////////////////////////////////////////////////////
+//Groebner Walk and Fractal Walk
+///////////////////////////////////////////////////////////////////
+//v1.3 2004-11-15
+///////////////////////////////////////////////////////////////////
+//implemented by Henrik Strohmayer
+///////////////////////////////////////////////////////////////////
+//in C++:
+///////////////////////////////////////////////////////////////////
+
+
+int overflow_error; //global variable
+
+/*
+overflow_error table
+ 1: Miv64DotProduct mult
+ 2: Miv64DotProduct add
+ 3: gett64 zaehler mult
+ 4: gett64 zaehler add
+ 5: gett64 nenner mult
+ 6: gett64 nenner add
+ 7: nextw64 mult a
+ 8: nextw64 mult b
+ 9: nextw64 add
+10: getinveps64 mult
+11: getinveps64 add
+12: getTaun64 mult
+13: getTaun64 add
+*/
+
+///////////////////////////////////////////////////////////////////
+//fistWalkStep64
+///////////////////////////////////////////////////////////////////
+//Description: adapts currRing for the algorithm and moves G into
+//it, calculating the appropriate GB if currw not is inside of
+//the current groebner cone
+///////////////////////////////////////////////////////////////////
+//Assumes: that the option redSB is turned off
+///////////////////////////////////////////////////////////////////
+//Uses: init64, rCopy0AndAddA, rComplete, rChangeCurrRing, matIdLift,
+//mpMult, idInterRed, idStd, idCopy, idrMoveR,currwOnBorder64
+///////////////////////////////////////////////////////////////////
+
+WalkState firstWalkStep64(ideal & G,int64vec* currw64, ring destRing){
+  WalkState state=WalkOk;
+  /* OLDRING **************************************************** */
+  ideal nextG;
+
+  if (currwOnBorder64(G,currw64))
+  {
+    ideal Gw=init64(G,currw64);
+    ring oldRing=currRing;
+  /* NEWRING **************************************************** */
+    ring rnew=rCopy0AndAddA(destRing,currw64);
+    rComplete(rnew);
+    rChangeCurrRing(rnew);
+
+    ideal newGw=idrMoveR(Gw, oldRing, rnew);
+
+
+ //HIER GEANDERT
+  matrix L=mpNew(1,1);
+  idLiftStd(newGw,&L);
+
+//       //turn off bucket representation of polynomials and on redSB
+//     optionState=test;
+//     //test|=Sy_bit(OPT_NOT_BUCKETS);
+//     test|=Sy_bit(OPT_REDSB);
+
+//     ideal newStdGw=idStd(newGw);
+
+//    //turn on bucket representation of polynomials and off redSB
+//    test=optionState;
+
+//     matrix L=matIdLift(newGw,newStdGw);
+//     idDelete(&newStdGw);
+
+    idDelete(&newGw);
+
+    nextG=idrMoveR(G,oldRing, rnew); idTest(nextG);
+
+    matrix nextGmat=(matrix)nextG;
+
+    matrix resMat=mp_Mult(nextGmat,L,rnew);
+    idDelete((ideal *)&nextGmat);
+    idDelete((ideal *)&L);
+
+    nextG=(ideal)resMat;
+
+    BITSET save1,save2;
+    SI_SAVE_OPT(save1,save2);
+    si_opt_1|=Sy_bit(OPT_REDSB);
+    nextG = idInterRed(nextG);
+    SI_RESTORE_OPT(save1,save2);
+  }
+  else
+  {
+    ring oldRing=currRing;
+    ring rnew=rCopy0AndAddA(destRing,currw64);
+    rComplete(rnew);
+    rChangeCurrRing(rnew);
+    nextG=idrMoveR(G,oldRing, rnew);
+  }
+
+  G=nextG;
+  return(state);
+}
+
+///////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////
+//walkStep64
+///////////////////////////////////////////////////////////////////
+//Description: one step in the groebner walk
+///////////////////////////////////////////////////////////////////
+//Assumes: that the option redSB is turned off
+///////////////////////////////////////////////////////////////////
+//Uses: init, rCopyAndChangeA, matIdLift, mpMult,
+//idInterRed, mStd, idCopy, idrMoveR
+///////////////////////////////////////////////////////////////////
+
+WalkState walkStep64(ideal & G,int64vec* currw64, int step)
+{
+  WalkState state=WalkOk;
+
+/* OLDRING ****************************************************** */
+  ideal Gw=init64(G,currw64);
+
+  ring oldRing=currRing;
+
+/* NEWRING ****************************************************** */
+  rCopyAndChangeA(currw64);
+
+  ideal newGw=idrMoveR(Gw, oldRing,currRing);
+
+  //HIER GEANDERT
+  matrix L=mpNew(1,1);
+  ideal newStdGw=idLiftStd(newGw,&L);
+
+//what it looked like before idStd and idLift were replaced
+//by idLiftStd
+//   optionState=test;
+//   test|=Sy_bit(OPT_REDSB);
+//   test|=Sy_bit(OPT_NOT_BUCKETS);
+
+//   //PrintS("  new initial forms:\n");
+//   for (int ii=0; ii <IDELEMS(newGw); ii++) pCleardenom(newGw->m[ii]);
+//   //idShow(newGw);
+//   ideal newStdGw=idStd(newGw);
+//     PrintS("  std for initial forms done\n");
+
+//   test=optionState;
+
+//  matrix L=matIdLift(newGw,newStdGw);
+
+//  idDelete(&newStdGw);
+
+  idDelete(&newGw);
+    //PrintS("  lift for initial forms done\n");
+
+  ideal nextG=idrMoveR(G,oldRing,currRing);
+  rDelete(oldRing);
+
+  matrix nextGmat=(matrix)nextG;
+
+  matrix resMat=mp_Mult(nextGmat,L,currRing);
+  idDelete((ideal *)&nextGmat);
+  idDelete((ideal *)&L);
+    //PrintS("  lift done\n");
+
+  nextG=(ideal)resMat;
+
+  BITSET save1,save2;
+  SI_SAVE_OPT(save1,save2);
+  si_opt_1|=Sy_bit(OPT_REDSB);
+  nextG = idInterRed(nextG);
+  SI_RESTORE_OPT(save1,save2);
+
+  G=nextG;
+  return(state);
+}
+
+///////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////
+//walk64
+///////////////////////////////////////////////////////////////////
+//Description: the main function of groebner walk, keeping
+//everything together
+///////////////////////////////////////////////////////////////////
+//Uses: mStd, getnthrow, firstwalkStep64, nextt64,
+//nextw64, walkStep64, changecurrRing
+///////////////////////////////////////////////////////////////////
+
+WalkState walk64(ideal I,int64vec* currw64,ring destRing,
+int64vec* destVec64,ideal  & destIdeal,BOOLEAN sourceIsSB)
+{
+  //some initializations
+  WalkState state=WalkOk;
+  BITSET save1,save2;
+  SI_SAVE_OPT(save1,save2);
+
+  si_opt_1|=Sy_bit(OPT_REDTAIL);
+  overflow_error=FALSE;
+  int step=0;
+  ideal G=I;
+
+  si_opt_1|=Sy_bit(OPT_REDSB);
+  if(!sourceIsSB)
+  {
+    ideal GG=idStd(G);
+    idDelete(&G); G=GG;
+  }
+  else
+    G=idInterRed(G);
+  SI_RESTORE_OPT(save1,save2);
+
+  ideal nextG;
+  state=firstWalkStep64(G,currw64,destRing);
+  nextG=G;
+
+  if(overflow_error)
+  {
+    state=WalkOverFlowError;
+    return(state);
+  }
+
+  int64 nexttvec0,nexttvec1;
+  //int64vec* nexttvec64=nextt64(nextG,currw64,destVec64);
+  nextt64(nextG,currw64,destVec64,nexttvec0,nexttvec1);
+
+  //while(0<t<=1) ( t=((*nexttvec64)[0])/((*nexttvec64)[1]) )
+  //while( (*nexttvec64)[0]<=(*nexttvec64)[1] ) {
+  while (nexttvec0<=nexttvec1 )
+  {
+    step=step+1;
+
+    //int64vec *tt=nextw64(currw64,destVec64,nexttvec64);
+    int64vec *tt=nextw64(currw64,destVec64,nexttvec0,nexttvec1);
+    delete currw64; currw64=tt; tt=NULL;
+
+    if (TEST_OPT_PROT)
+    {
+      PrintS("walk step:"); currw64->show(); PrintLn();
+    }
+
+    state=walkStep64(nextG,currw64,step);
+    //uppdates nextG if all is OK
+
+    if(overflow_error)
+      return(WalkOverFlowError);
+
+    //delete nexttvec64;
+    //nexttvec64=nextt64(nextG,currw64,destVec64);
+    nextt64(nextG,currw64,destVec64,nexttvec0,nexttvec1);
+
+  }
+
+  destIdeal=sortRedSB(nextG);
+  return(state);
+}
+
+///////////////////////////////////////////////////////////////////
+
+
+
+///////////////////////////////////////////////////////////////////
+//FRACTAL WALK PART BEGINS HERE
+///////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////
+//firstFractalWalkStep64
+///////////////////////////////////////////////////////////////////
+//Description: called once before fractalRec64 is called, to set up
+//the ring and move G into it, has two different strategies
+///////////////////////////////////////////////////////////////////
+//Uses: firstWalkStep64,currwOnBorder64,getTaun64,rCopy0AndAddA,
+//getiv64,iv64Size,rComplete,rChangeCurrRing,idrMoveR,idStd,matIdLift
+///////////////////////////////////////////////////////////////////
+
+
+//unperturbedStartVectorStrategy IS NOW NOT ALLWAYS AS DEFAULT SET
+//TO TRUE BUT IS INPUT FROM fractalWalk64
+WalkState firstFractalWalkStep64(ideal & G,int64vec* & currw64,
+intvec* currMat, ring destRing,
+BOOLEAN unperturbedStartVectorStrategy){
+
+    //This strategy Uses the ordinary walk for the first step
+    if(unperturbedStartVectorStrategy){
+      return(unperturbedFirstStep64(G,currw64,destRing));
+    //here G is updated since its adress is given as argument
+    }
+
+    //This strategy makes sure that the start vector lies inside the start cone
+    //thus no step is needed within the start cone.
+    else{
+      if(currwOnBorder64(G,currw64))
+      {
+        int64 dummy64;
+        getTaun64(G,currMat,iv64Size(currw64),&currw64,dummy64);
+        //currw64=getiv64(getTaun64(G,currMat,iv64Size(currw64)));
+      }
+      ring oldRing=currRing;
+      ring newRing=rCopy0AndAddA(destRing,currw64);
+      rComplete(newRing);
+      rChangeCurrRing(newRing);
+      G=idrMoveR(G,oldRing,newRing);
+    }
+
+  return(WalkOk);
+}
+
+///////////////////////////////////////////////////////////////////
+
+
+
+//DIESE FUNKTION ERSETZT firstWalkStep FUR fractalWalk
+///////////////////////////////////////////////////////////////////
+//unperturbedFirstStep64
+///////////////////////////////////////////////////////////////////
+//Description: adapts currRing for the algorithm and moves G into
+//it, calculating the appropriate GB if currw not is inside of
+//the current groebner cone
+///////////////////////////////////////////////////////////////////
+//Assumes: that the option redSB is turned off
+///////////////////////////////////////////////////////////////////
+//Uses: init64, rCopy0AndAddA, rComplete, rChangeCurrRing, matIdLift,
+//mpMult, idInterRed, idStd, idCopy, idrMoveR,currwOnBorder64
+///////////////////////////////////////////////////////////////////
+
+WalkState unperturbedFirstStep64(ideal & G,int64vec* currw64, ring destRing)
+{
+  WalkState state=WalkOk;
+  /* OLDRING **************************************************** */
+  ideal nextG;
+  BITSET save1,save2;
+  SI_SAVE_OPT(save1,save2);
+
+  if (currwOnBorder64(G,currw64))
+  {
+    ideal Gw=init64(G,currw64);
+    ring oldRing=currRing;
+  /* NEWRING **************************************************** */
+    ring rnew=rCopy0AndAddA(destRing,currw64);
+    rComplete(rnew);
+    rChangeCurrRing(rnew);
+
+    ideal newGw=idrMoveR(Gw, oldRing,rnew);
+
+      //turn off bucket representation of polynomials and on redSB
+    //si_opt_1|=Sy_bit(OPT_NOT_BUCKETS);
+    si_opt_1|=Sy_bit(OPT_REDSB);
+
+    ideal newStdGw=idStd(newGw);
+
+    //turn on bucket representation of polynomials and off redSB
+    SI_RESTORE_OPT(save1,save2);
+
+    matrix L=matIdLift(newGw,newStdGw);
+    idDelete(&newStdGw);
+    idDelete(&newGw);
+
+    nextG=idrMoveR(G,oldRing,rnew); idTest(nextG);
+
+    matrix nextGmat=(matrix)nextG;
+
+    matrix resMat=mp_Mult(nextGmat,L,rnew);
+    idDelete((ideal *)&nextGmat);
+    idDelete((ideal *)&L);
+
+    nextG=(ideal)resMat;
+
+    si_opt_1|=Sy_bit(OPT_REDSB);
+    nextG = idInterRed(nextG);
+    SI_RESTORE_OPT(save1,save2);
+  }
+  else
+  {
+    ring oldRing=currRing;
+    ring rnew=rCopy0AndAddA(destRing,currw64);
+    rComplete(rnew);
+    rChangeCurrRing(rnew);
+    nextG=idrMoveR(G,oldRing,rnew);
+  }
+
+  G=nextG;
+  return(state);
+}
+
+///////////////////////////////////////////////////////////////////
+
+
+
+///////////////////////////////////////////////////////////////////
+//fractalRec64
+///////////////////////////////////////////////////////////////////
+//Description: the recursion function used in fractalWalk64
+//(see appropriate par of thesis for more details)
+///////////////////////////////////////////////////////////////////
+//Assumes: that the option redSB is turned off
+///////////////////////////////////////////////////////////////////
+//Uses: getTaun64,getint64,getiv64,invEpsOk64,nextt64,nextw64,
+//init64,idCopy,noPolysOfMoreThanTwoTerms,rCopy0,rComplete,
+//rChangeCurrRing,rSetWeightVec,idrMoveR,mpMult,idInterRed
+///////////////////////////////////////////////////////////////////
+
+WalkState fractalRec64(ideal  & G,int64vec* currw64, intvec* destMat,
+                       int level,int step)
+{
+
+if (TEST_OPT_PROT)
+{  PrintS("fractal walk, weights");currw64->show();PrintLn(); }
+WalkState state=WalkOk;
+BITSET save1,save2;
+SI_SAVE_OPT(save1,save2);
+
+//1
+int64vec* w=(currw64);
+int64vec* old_w=(currw64);
+int64vec* sigma=(currw64);
+
+//lists taunpair64=getTaun64(G,destMat,level);
+//int64vec* w2=getiv64(taunpair64);
+//int64 inveps64=getint64(taunpair64);
+int64vec* w2;
+int64 inveps64;
+getTaun64(G,destMat,level,&w2,inveps64);
+
+//2
+while(1){
+
+  //int64vec* tvec64=nextt64(G,w,w2);
+  int64 tvec0,tvec1;
+  nextt64(G,w,w2,tvec0,tvec1);
+
+  if(overflow_error){
+    return WalkOverFlowError;
+  }
+
+  //tvec[1]>tvec[2] iff t>1 or t ist undefined i.e.is (2,0)
+  //if ((*tvec64)[0]>(*tvec64)[1])
+  if (tvec0>tvec1)
+  {
+    if(invEpsOk64(G,destMat,level,inveps64)) {
+      return(state);
+  }
+  else
+  {
+      //taunpair64=getTaun64(G,destMat,level);
+      //w2=getiv64(taunpair64);
+      //inveps64=getint64(taunpair64);
+      delete w2;
+      getTaun64(G,destMat,level,&w2,inveps64);
+
+      //tvec64=nextt64(G,w,w2);
+      nextt64(G,w,w2,tvec0,tvec1);
+
+      if(overflow_error){
+        return WalkOverFlowError;
+      }
+
+      //if((*tvec64)[0]>(*tvec64)[1])
+      if(tvec0>tvec1)
+      {
+        return(state);
+      }
+    }
+  }
+
+  //i.e. t=1 and we have reached the target vector
+  //if( ((*tvec64)[0]==(*tvec64)[1]) && (level!=iv64Size(w)) )
+  if( (tvec0==tvec1) && (level!=iv64Size(w)) )
+  {
+    state=fractalRec64(G,old_w,destMat,level+1,step);
+    return(state);
+  }
+  else
+  {
+    w=nextw64(w,w2,tvec0,tvec1);
+
+//3
+    ideal Gw=init64(G,w);  //finding initial ideal for new w
+
+    ring oldRing=currRing;
+
+    ideal GwCp=idCopy(Gw);
+    ideal GCp=idCopy(G);
+
+    ideal newGw;
+    ideal newStdGw;
+    ideal newG;
+
+//4
+    if ( level==iv64Size(w) || noPolysWithMoreThanTwoTerms(Gw) ){
+
+//5
+/*NEWRING**********************************************************/
+
+      //this assumes order has A-vector as first vector
+      ring newring=rCopy0(currRing);
+      rComplete(newring);
+      rSetWeightVec(newring,w->iv64GetVec());
+      rChangeCurrRing(newring);
+      //rSetWeightVec(newring,w->iv64GetVec());
+      //rComplete(newring,1);
+
+      newGw=idrMoveR(GwCp,oldRing,newring);
+
+      si_opt_1|=Sy_bit(OPT_REDSB);
+      newStdGw=idStd(newGw); //computes new reduced GB of Gw
+      SI_RESTORE_OPT(save1,save2);
+    }
+    else
+    {
+//7
+/*THE RING FROM THE RECURSION STEP BELOW***************************/
+      //Here we can choose whether to call fractalrec with old_w,
+      //which is the last w from the top level, or with sigma,
+      //the original start vector. The impact on the algorithm is not obvious.
+
+      state=fractalRec64(Gw,sigma,destMat,level+1,step);
+
+      //The resulting GB is Gw since its adress is given as argument.
+      ideal recG=Gw;
+      ring temp=currRing;
+
+/*NEWRING**********************************************************/
+
+      //this assumes order has A-vector as first vector
+      ring newring=rCopy0(currRing);
+      rComplete(newring);
+      rChangeCurrRing(newring);
+      rSetWeightVec(currRing,w->iv64GetVec());
+      rComplete(newring,1);
+
+      newGw=idrMoveR(GwCp,oldRing,newring);
+
+      newStdGw=idrMoveR(recG,temp,newring);
+    }
+
+//8
+    //lifting comes either after level=nvars(ring), after Gw has
+    //no poly with more than two terms or after
+    //fractalRec64(Gw,level+1) has returned
+
+    //si_opt_1|=Sy_bit(OPT_NOT_BUCKETS);
+    matrix L=matIdLift(newGw,newStdGw);
+    SI_RESTORE_OPT(save1,save2);
+
+    newG=idrMoveR(GCp,oldRing,currRing);
+    matrix MG=(matrix)newG;
+
+    matrix resMat=mp_Mult(MG,L,currRing);
+    idDelete((ideal *)&MG);
+    idDelete((ideal *)&L);
+    G=(ideal)resMat;
+
+//9
+
+    si_opt_1|=Sy_bit(OPT_REDSB);
+    G=idInterRed(G);
+    SI_RESTORE_OPT(save1,save2);
+
+    old_w=iv64Copy(w);
+    if(level==1) step=step+1;
+
+  }
+
+}
+}
+
+
+///////////////////////////////////////////////////////////////////
+
+
+//ANOTHER INPUT-VARIABLE ADDED: unperturbedStartVectorStrategy
+//THIS SHOULD BE SET IN walkProc.cc BY THE USER
+///////////////////////////////////////////////////////////////////
+//fractalWalk64
+///////////////////////////////////////////////////////////////////
+//Description:
+///////////////////////////////////////////////////////////////////
+//Uses:fractalRec64,firstFractalWalkStep64,idStd,idInterRed,
+//int64VecToIntVec,getNthRow,sortRedSB
+///////////////////////////////////////////////////////////////////
+
+WalkState fractalWalk64(ideal sourceIdeal,ring destRing,
+ideal & destIdeal,BOOLEAN sourceIsSB,
+BOOLEAN unperturbedStartVectorStrategy)
+{
+
+  overflow_error=FALSE; //global
+  WalkState state=WalkOk;
+  BITSET save1,save2;
+  SI_SAVE_OPT(save1,save2);
+
+  si_opt_1|= (Sy_bit(OPT_REDTAIL)|Sy_bit(OPT_REDSB));
+  ideal G;
+
+  if(!sourceIsSB)
+  {
+    G=idStd(sourceIdeal);
+  }
+
+  else
+  {
+    G=idInterRed(idCopy(sourceIdeal));
+  }
+
+  SI_RESTORE_OPT(save1,save2); //switches REDSB off
+
+  //matrices for the orders of the rings
+  intvec *destMat=int64VecToIntVec(rGetGlobalOrderMatrix(destRing));
+  intvec *currMat=int64VecToIntVec(rGetGlobalOrderMatrix(currRing));
+
+  int64vec* currw64=getNthRow64(currMat,1); //start vector
+
+  state=firstFractalWalkStep64(G,currw64,currMat,destRing,
+                               unperturbedStartVectorStrategy);
+  delete currMat;
+
+  state=fractalRec64(G,currw64,destMat,1,1);
+  if(state==WalkOk)
+    destIdeal=G;
+
+  if(overflow_error)
+    state=WalkOverFlowError;
+
+  delete currw64;
+  delete destMat;
+  return state;
+}
+
+
+/////////////////////////////////////////////////////////////
diff --git a/kernel/groebner_walk/walkMain.h b/kernel/groebner_walk/walkMain.h
new file mode 100644
index 0000000..c707ebd
--- /dev/null
+++ b/kernel/groebner_walk/walkMain.h
@@ -0,0 +1,61 @@
+#ifndef WALKMAIN_H
+#define WALKMAIN_H
+
+#include <misc/intvec.h>
+#include <misc/int64vec.h>
+
+enum WalkState{
+    WalkNoIdeal,
+    WalkIncompatibleRings,
+    WalkIntvecProblem,
+    WalkOverFlowError,
+    /*
+    these could be defined to make error management more elegant
+    WalkOverFlowError1,
+    WalkOverFlowError2,
+    WalkOverFlowError3,
+    WalkOverFlowError4,
+    WalkOverFlowError5,
+    WalkOverFlowError6,
+    WalkOverFlowError7,
+    WalkOverFlowError8,
+    WalkOverFlowError9,
+    WalkOverFlowError10,
+    WalkOverFlowError11,
+    WalkOverFlowError12,
+    WalkOverFlowError13,
+    */
+    WalkIncompatibleDestRing,
+    WalkIncompatibleSourceRing,
+    WalkOk
+
+};
+
+/*
+overflow_error table
+ 1: Miv64DotProduct mult
+ 2: Miv64DotProduct add
+ 3: gett64 zaehler mult
+ 4: gett64 zaehler add (not necessarily overflow but quite probable)
+ 5: gett64 nenner mult
+ 6: gett64 nenner add (not necessarily overflow but quite probable)
+ 7: nextw64 mult a
+ 8: nextw64 mult b
+ 9: nextw64 add (not necessarily overflow but quite probable)
+10: getinveps64 mult
+11: getinveps64 add
+12: gettaun64 mult
+13: gettaun64 add (not necessarily overflow but quite probable)
+*/
+
+
+WalkState walkstep64(ideal & G,int64vec* currw,int step);
+WalkState walk64(ideal I,int64vec* currw64,ring destRing,int64vec* destVec64,ideal  & destIdeal,BOOLEAN sourceIsSB=FALSE);
+
+//ANOTHER INPUT-VARIABLE ADDED: unperturbedStartVectorStrategy
+//THIS SHOULD BE SET IN walkProc.cc BY THE USER
+WalkState fractalWalk64(ideal sourceIdeal,ring destRing,ideal & destIdeal,BOOLEAN sourceIsSB,BOOLEAN unperturbedStartVectorStrategy);
+//REPLACES firstWalkStep64 FOR fractalWalk64
+WalkState unperturbedFirstStep64(ideal & G,int64vec* currw64, ring destRing);
+
+#endif
diff --git a/kernel/groebner_walk/walkProc.cc b/kernel/groebner_walk/walkProc.cc
new file mode 100644
index 0000000..4a34441
--- /dev/null
+++ b/kernel/groebner_walk/walkProc.cc
@@ -0,0 +1,361 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+
+
+
+
+#include <kernel/mod2.h>
+#include <kernel/structs.h>
+#include <kernel/structs.h>
+#include <kernel/polys.h>
+#include <kernel/ideals.h>
+#include <polys/monomials/ring.h>
+#include <polys/monomials/maps.h>
+#include <omalloc/omalloc.h>
+#include <kernel/GBEngine/kstd1.h>
+#include <kernel/fglm/fglm.h>
+#include <kernel/groebner_walk/walkMain.h>
+#include <kernel/groebner_walk/walkSupport.h>
+#include <kernel/groebner_walk/walkProc.h>
+#include <polys/prCopy.h>
+
+///////////////////////////////////////////////////////////////////
+//Frame procedures for Groebner Walk and Fractal Walk
+///////////////////////////////////////////////////////////////////
+//v1.3 2004-11-15
+///////////////////////////////////////////////////////////////////
+//implemented by Henrik Strohmayer
+///////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////
+//walkConsistency
+///////////////////////////////////////////////////////////////////
+//Description:
+// Checks if the two rings sringHdl and dringHdl are compatible
+// enough to be used for the Walk. This means:
+// 1) Same Characteristic
+// 2) globalOrderings in both rings,
+// 3) Same number of variables
+// 4) same number of parameters
+// 5) variables in one ring have the same names
+//    and order as variables of the other
+// 6) parameters in one ring have the same names
+//    and order as parameters of the other
+// 7) none of the rings are qrings
+// vperm must be a vector of length (currRing->N)+1, initialized by 0.
+// If both rings are compatible, it stores the permutation of the
+// variables if mapped from sringHdl to dringHdl.
+// if the rings are compatible, it returns WalkOk.
+// Should be called with currRing= IDRING( sringHdl );
+///////////////////////////////////////////////////////////////////
+//Uses: IDRING,WerrorS,rPar,omAlloc0,maFindPerm,omFreeSize,sizeof
+///////////////////////////////////////////////////////////////////
+
+WalkState
+walkConsistency( ring sring, ring dring, int * vperm )
+{
+    int k;
+    WalkState state= WalkOk;
+
+    if ( rChar(sring) != rChar(dring) )
+    {
+        WerrorS( "rings must have same characteristic" );
+        state= WalkIncompatibleRings;
+    }
+    else if ( (rHasLocalOrMixedOrdering(sring))
+    || (rHasLocalOrMixedOrdering(dring)) )
+    {
+        WerrorS( "only works for global orderings" );
+        state= WalkIncompatibleRings;
+    }
+    else if ( sring->N != dring->N )
+    {
+        WerrorS( "rings must have same number of variables" );
+        state= WalkIncompatibleRings;
+    }
+    else if ( rPar(sring) != rPar(dring) )
+    {
+        WerrorS( "rings must have same number of parameters" );
+        state= WalkIncompatibleRings;
+    }
+
+    if ( state != WalkOk ) return state;
+    // now the rings have the same number of variables resp. parameters.
+    // check if the names of the variables resp. parameters do agree:
+
+    int nvar = rVar(sring);
+    int npar = rPar(sring);
+    int * pperm;
+    char **snames;
+    char **dnames;
+    if ( npar > 0 )
+    {
+        snames=sring->cf->extRing->names;
+	dnames=dring->cf->extRing->names;
+        pperm= (int *)omAlloc0( (npar+1)*sizeof( int ) );
+    }
+    else
+    {
+        snames=NULL;
+	dnames=NULL;
+        pperm= NULL;
+    }
+
+    maFindPerm( sring->names, nvar, snames, npar,
+                dring->names, nvar, dnames, npar, vperm, pperm,
+                dring->cf->type);
+
+    for ( k= nvar; (k > 0) && (state == WalkOk); k-- )
+        if ( vperm[k] <= 0 )
+        {
+            WerrorS( "variable names do not agree" );
+            state= WalkIncompatibleRings;
+        }
+
+    for ( k= npar-1; (k >= 0) && (state == WalkOk); k-- )
+        if ( pperm[k] >= 0 )
+        {
+            WerrorS( "paramater names do not agree" );
+            state= WalkIncompatibleRings;
+        }
+
+    //remove this to if you want to allow permutations of variables
+    for ( k= nvar; (k > 0) && (state == WalkOk); k-- )
+      if ( vperm[k] != (k) )
+      {
+        WerrorS( "orders of variables do not agree" );
+        state= WalkIncompatibleRings;
+      }
+
+    //remove this to if you want to allow permutations of parameters
+    for ( k= npar; (k > 0) && (state == WalkOk); k-- )
+      if ( pperm[k-1] != (-k) )
+      {
+        WerrorS( "orders of parameters do not agree" );
+        state= WalkIncompatibleRings;
+      }
+
+      if (pperm != NULL)
+        omFreeSize( (ADDRESS)pperm, (npar+1)*sizeof( int ) );
+
+    if ( state != WalkOk ) return state;
+
+    // check if any of the rings are qrings or not
+    if ( (sring->qideal != NULL) || (dring->qideal != NULL) )
+    {
+          WerrorS( "rings are not allowed to be qrings");
+          return WalkIncompatibleRings;
+    }
+
+    int i=0;
+    while(dring->order[i]!=0)
+    {
+      if(
+           !(dring->order[i]==ringorder_a) &&
+           !(dring->order[i]==ringorder_a64) &&
+           !(dring->order[i]==ringorder_lp) &&
+           !(dring->order[i]==ringorder_dp) &&
+           !(dring->order[i]==ringorder_Dp) &&
+           !(dring->order[i]==ringorder_wp) &&
+           !(dring->order[i]==ringorder_Wp) &&
+           !(dring->order[i]==ringorder_C)  &&
+           !(dring->order[i]==ringorder_M)
+         )
+      {
+        state=WalkIncompatibleDestRing;
+      }
+      i++;
+    }
+
+    i=0;
+    while(sring->order[i]!=0)
+    {
+      if(
+           !(sring->order[i]==ringorder_a) &&
+           !(sring->order[i]==ringorder_a64) &&
+           !(sring->order[i]==ringorder_lp) &&
+           !(sring->order[i]==ringorder_dp) &&
+           !(sring->order[i]==ringorder_Dp) &&
+           !(sring->order[i]==ringorder_wp) &&
+           !(sring->order[i]==ringorder_Wp) &&
+           !(sring->order[i]==ringorder_C)  &&
+           !(sring->order[i]==ringorder_M)
+         )
+      {
+       state=WalkIncompatibleSourceRing;
+      }
+      i++;
+    }
+
+    return state;
+}
+
+///////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////
+//fractalWalkConsistency
+///////////////////////////////////////////////////////////////////
+//Description:
+// Checks if the two rings sringHdl and dringHdl are compatible
+// enough to be used for the Walk. This means:
+// 1) Same Characteristic
+// 2) globalOrderings in both rings,
+// 3) Same number of variables
+// 4) same number of parameters
+// 5) variables in one ring have the same names
+//    and order as variables of the other
+// 6) parameters in one ring have the same names
+//    and order as parameters of the other
+// 7) none of the rings are qrings
+// vperm must be a vector of length (currRing->N)+1, initialized by 0.
+// If both rings are compatible, it stores the permutation of the
+// variables if mapped from sringHdl to dringHdl.
+// if the rings are compatible, it returns WalkOk.
+// Should be called with currRing= IDRING( sringHdl );
+///////////////////////////////////////////////////////////////////
+//Uses: IDRING,WerrorS,rPar,omAlloc0,maFindPerm,omFreeSize,sizeof
+///////////////////////////////////////////////////////////////////
+
+WalkState
+fractalWalkConsistency( ring sring, ring dring, int * vperm )
+{
+    int k;
+    WalkState state= WalkOk;
+
+    if ( rChar(sring) != rChar(dring) )
+    {
+        WerrorS( "rings must have same characteristic" );
+        state= WalkIncompatibleRings;
+    }
+
+    if ( (rHasLocalOrMixedOrdering(sring))
+    || (rHasLocalOrMixedOrdering(dring)) )
+    {
+        WerrorS( "only works for global orderings" );
+        state= WalkIncompatibleRings;
+    }
+
+    if ( rVar(sring) != rVar(dring) )
+    {
+        WerrorS( "rings must have same number of variables" );
+        state= WalkIncompatibleRings;
+    }
+
+    if ( rPar(sring) != rPar(dring) )
+    {
+        WerrorS( "rings must have same number of parameters" );
+        state= WalkIncompatibleRings;
+    }
+
+    if ( state != WalkOk ) return state;
+
+    // now the rings have the same number of variables resp. parameters.
+    // check if the names of the variables resp. parameters do agree:
+    int nvar = sring->N;
+    int npar = rPar(sring);
+    int * pperm;
+    char **snames;
+    char **dnames;
+
+    if ( npar > 0 )
+    {
+        snames=sring->cf->extRing->names;
+	dnames=dring->cf->extRing->names;
+        pperm= (int *)omAlloc0( (npar+1)*sizeof( int ) );
+    }
+    else
+    {
+        pperm= NULL;
+	snames=NULL;
+	dnames=NULL;
+    }
+
+    maFindPerm( sring->names, nvar, snames, npar,
+                dring->names, nvar, dnames, npar, vperm, pperm,
+                dring->cf->type);
+
+    for ( k= nvar; (k > 0) && (state == WalkOk); k-- )
+      if ( vperm[k] <= 0 )
+      {
+        WerrorS( "variable names do not agree" );
+        state= WalkIncompatibleRings;
+      }
+
+    for ( k= npar; (k > 0) && (state == WalkOk); k-- )
+      if ( pperm[k-1] >= 0 )
+      {
+        WerrorS( "parameter names do not agree" );
+        state= WalkIncompatibleRings;
+      }
+
+    //check if order of variables resp. parameters does agree
+    //remove this to if you want to allow permutations of variables
+    for ( k= nvar; (k > 0) && (state == WalkOk); k-- )
+      if ( vperm[k] != (k) )
+      {
+        WerrorS( "orders of variables do not agree" );
+        state= WalkIncompatibleRings;
+      }
+
+    //remove this to if you want to allow permutations of parameters
+    for ( k= npar; (k > 0) && (state == WalkOk); k-- )
+      if ( pperm[k-1] != (-k) )
+      {
+        WerrorS( "orders of parameters do not agree" );
+        state= WalkIncompatibleRings;
+      }
+
+    if (pperm != NULL)
+      omFreeSize( (ADDRESS)pperm, (npar+1)*sizeof( int ) );
+
+    if ( state != WalkOk ) return state;
+
+    // check if any of the rings are qrings or not
+    if ( (sring->qideal != NULL) || (dring->qideal != NULL) )
+    {
+          WerrorS( "rings are not allowed to be qrings");
+          return WalkIncompatibleRings;
+    }
+
+    int i=0;
+    while(dring->order[i]!=0){
+      if(  !(dring->order[i]==ringorder_lp) &&
+           !(dring->order[i]==ringorder_dp) &&
+           !(dring->order[i]==ringorder_Dp) &&
+           !(dring->order[i]==ringorder_wp) &&
+           !(dring->order[i]==ringorder_Wp) &&
+           !(dring->order[i]==ringorder_C)  &&
+           !(dring->order[0]==ringorder_M)
+         )
+      {
+        state=WalkIncompatibleDestRing;
+      }
+      i++;
+    }
+
+    i=0;
+    while(sring->order[i]!=0)
+    {
+      if(  !(sring->order[i]==ringorder_lp) &&
+           !(sring->order[i]==ringorder_dp) &&
+           !(sring->order[i]==ringorder_Dp) &&
+           !(sring->order[i]==ringorder_wp) &&
+           !(sring->order[i]==ringorder_Wp) &&
+           !(sring->order[i]==ringorder_C)  &&
+           !(dring->order[0]==ringorder_M)
+         )
+      {
+        state=WalkIncompatibleSourceRing;
+      }
+      i++;
+    }
+
+    return state;
+}
+
+///////////////////////////////////////////////////////////////////
+
+
diff --git a/kernel/groebner_walk/walkProc.h b/kernel/groebner_walk/walkProc.h
new file mode 100644
index 0000000..4f2eb0e
--- /dev/null
+++ b/kernel/groebner_walk/walkProc.h
@@ -0,0 +1,9 @@
+#ifndef WALKPROC_H
+#define WALKPROC_H
+#include <kernel/groebner_walk/walkMain.h>
+ideal walkProc(leftv first, leftv second);
+ideal fractalWalkProc(leftv first, leftv second);
+WalkState walkConsistency( ring sring, ring dring, int * vperm );
+WalkState fractalWalkConsistency( ring sring, ring dring, int * vperm );
+#endif
+
diff --git a/kernel/groebner_walk/walkSupport.cc b/kernel/groebner_walk/walkSupport.cc
new file mode 100644
index 0000000..72a3344
--- /dev/null
+++ b/kernel/groebner_walk/walkSupport.cc
@@ -0,0 +1,1200 @@
+#include <kernel/mod2.h>
+
+#include <misc/intvec.h>
+#include <misc/int64vec.h>
+
+#include <polys/monomials/ring.h>
+#include <polys/prCopy.h>
+#include <polys/matpol.h>
+
+#include <kernel/polys.h>
+#include <kernel/ideals.h>
+#include <kernel/groebner_walk/walkSupport.h>
+#include <kernel/GBEngine/kstd1.h>
+
+#include <string.h>
+#include <math.h>
+
+extern BOOLEAN overflow_error;
+
+///////////////////////////////////////////////////////////////////
+//Support functions for Groebner Walk and Fractal Walk
+///////////////////////////////////////////////////////////////////
+//v1.2 2004-06-17
+///////////////////////////////////////////////////////////////////
+//implemented by Henrik Strohmayer
+///////////////////////////////////////////////////////////////////
+
+
+
+///////////////////////////////////////////////////////////////////
+//tdeg
+///////////////////////////////////////////////////////////////////
+//Description: returns the normal degree of the input polynomial
+///////////////////////////////////////////////////////////////////
+//Uses: pTotaldegree
+///////////////////////////////////////////////////////////////////
+
+int tdeg(poly p)
+{
+  int res=0;
+  if(p!=NULL) res=pTotaldegree(p);
+  return(res);
+}
+
+///////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////
+//getMaxTdeg
+///////////////////////////////////////////////////////////////////
+//Description: returns the maximum normal degree of the
+//polynomials of the input ideal
+///////////////////////////////////////////////////////////////////
+//Uses: pTotaldegree
+///////////////////////////////////////////////////////////////////
+
+int getMaxTdeg(ideal I)
+{
+  int res=-1;
+  int length=(int)I->ncols;
+  for(int j=length-1;j>=0;j--)
+  {
+    if ((I->m)[j]!=NULL)
+    {
+      int temp=pTotaldegree((I->m)[j]);
+      if(temp>res) {res=temp;}
+    }
+  }
+  return(res);
+}
+///////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////
+//getMaxPosOfNthRow
+///////////////////////////////////////////////////////////////////
+//Description: returns the greatest integer of row n of the
+//input intvec
+///////////////////////////////////////////////////////////////////
+//Uses: none
+///////////////////////////////////////////////////////////////////
+
+int getMaxPosOfNthRow(intvec *v,int n)
+{
+  int res=0;
+  assume( (0<n) && (n<=(v->rows())) );
+  {
+    int c=v->cols();
+    int cc=(n-1)*c;
+    res=abs((*v)[0+cc /*(n-1)*c*/]);
+    for (int i=c-1;i>=0;i--)
+    {
+      int temp=abs((*v)[i+cc /*(n-1)*c*/]);
+      if(temp>res){res=temp;}
+    }
+  }
+ return(res);
+}
+
+///////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////
+//getInvEps64
+///////////////////////////////////////////////////////////////////
+//Description: returns the inverse of epsilon (see relevant
+//part of thesis for definition of epsilon)
+///////////////////////////////////////////////////////////////////
+//Uses: getMaxPosOfNthRow
+///////////////////////////////////////////////////////////////////
+
+int64 getInvEps64(ideal G,intvec *targm,int pertdeg)
+{
+  int n;
+  int64 temp64;
+  int64 sum64=0;
+//think n=2 is enough (instead of n=1)
+  for (n=pertdeg; n>1; n--)
+  {
+    temp64=getMaxPosOfNthRow(targm,n);
+    sum64 += temp64;
+  }
+  int64 inveps64=getMaxTdeg(G)*sum64+1;
+
+  //overflow test
+  if( sum64!=0 && (((inveps64-1)/sum64)!=getMaxTdeg(G)) )
+    overflow_error=11;
+
+  return(inveps64);
+}
+
+///////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////
+//invEpsOk64
+///////////////////////////////////////////////////////////////////
+//Description: checks whether the input inveps64 is the same
+//as the one you get from the current ideal I
+///////////////////////////////////////////////////////////////////
+//Uses: getInvEps64
+///////////////////////////////////////////////////////////////////
+
+int invEpsOk64(ideal I, intvec *targm, int pertdeg, int64 inveps64)
+{
+  int64 temp64=getInvEps64(I,targm,pertdeg);
+  if (inveps64>=temp64)
+  {
+    return(1);
+  }
+  else
+  {
+    return(0);
+  }
+}
+
+///////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////
+//getNthRow
+///////////////////////////////////////////////////////////////////
+//Description: returns an intvec containing the nth row of v
+///////////////////////////////////////////////////////////////////
+//Uses: none
+///////////////////////////////////////////////////////////////////
+
+intvec* getNthRow(intvec *v, int n)
+{
+  int r=v->rows();
+  int c=v->cols();
+  intvec *res=new intvec(c);
+  if((0<n) && (n<=r))
+  {
+    int cc=(n-1)*c;
+    for (int i=0; i<c; i++)
+    {
+      (*res)[i]=(*v)[i+cc /*(n-1)*c*/ ];
+    }
+  }
+  return(res);
+}
+
+int64vec* getNthRow64(intvec *v, int n)
+{
+  int r=v->rows();
+  int c=v->cols();
+  int64vec *res=new int64vec(c);
+  if((0<n) && (n<=r))
+  {
+    int cc=(n-1)*c;
+    for (int i=0; i<c; i++)
+    {
+      (*res)[i]=(int64)(*v)[i+cc /*(n-1)*c*/ ];
+    }
+  }
+  return(res);
+}
+
+///////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////
+//getTaun64
+///////////////////////////////////////////////////////////////////
+//Description: returns a list containing the nth perturbed vector
+//and the inveps64 used to calculate the vector
+///////////////////////////////////////////////////////////////////
+//Uses: getNthRow,getInvEps64
+///////////////////////////////////////////////////////////////////
+
+void getTaun64(ideal G,intvec* targm,int pertdeg, int64vec** v64, int64 & i64)
+{
+  int64vec* taun64=getNthRow64(targm,1);
+  int64vec *temp64,*add64;
+  int64 inveps64=1;
+  if (pertdeg>1) inveps64=getInvEps64(G,targm,pertdeg);
+
+  int n;
+  //temp64 is used to check for overflow:
+  for (n=2; n<=pertdeg; n++)
+  {
+    if (inveps64!=1)
+    {
+      temp64=iv64Copy(taun64);
+      (*taun64)*=inveps64;
+      for(int i=0; i<rVar(currRing);i++)
+      {
+        if((*temp64)[i]!=0 && (((*taun64)[i])/((*temp64)[i]))!=inveps64)
+        overflow_error=12;
+      }
+      delete temp64;
+    }
+    temp64=iv64Copy(taun64);
+    add64=getNthRow64(targm,n);
+    taun64=iv64Add(add64,taun64);
+    for(int i=0; i<rVar(currRing);i++)
+    {
+      if( ( ((*temp64)[i]) > 0 ) && ( ((*add64)[i]) > 0 ) )
+      {
+        if( ((*taun64)[i]) < ((*temp64)[i])  )
+          overflow_error=13;
+      }
+      if( ( ((*temp64)[i]) < 0 ) && ( ((*add64)[i]) < 0 ) )
+      {
+        if( ((*taun64)[i]) > ((*temp64)[i])  )
+          overflow_error=13;
+      }
+    }
+    delete temp64;
+  }
+
+  //lists taunlist64=makeTaunList64(taun64,inveps64);
+  //return(taunlist64);
+  *v64=taun64;
+  i64=inveps64;
+}
+
+///////////////////////////////////////////////////////////////////
+//scalarProduct64
+///////////////////////////////////////////////////////////////////
+//Description: returns the scalar product of int64vecs a and b
+///////////////////////////////////////////////////////////////////
+//Assume: Overflow tests assumes input has nonnegative entries
+///////////////////////////////////////////////////////////////////
+//Uses: none
+///////////////////////////////////////////////////////////////////
+
+static inline int64  scalarProduct64(int64vec* a, int64vec* b)
+{
+  assume( a->length() ==  b->length());
+  int i, n = a->length();
+  int64 result = 0;
+  int64 temp1,temp2;
+  for(i=n-1; i>=0; i--)
+  {
+    temp1=(*a)[i] * (*b)[i];
+    if((*a)[i]!=0 && (temp1/(*a)[i])!=(*b)[i]) overflow_error=1;
+
+    temp2=result;
+    result += temp1;
+
+    //since both vectors always have nonnegative entries in init64
+    //result should be >=temp2
+    if(temp2>result) overflow_error=2;
+  }
+
+  return result;
+}
+///////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////
+//init64
+///////////////////////////////////////////////////////////////////
+//Description: returns the initial form ideal of the input ideal
+//I w.r.t. the weight vector currw64
+///////////////////////////////////////////////////////////////////
+//Uses: idealSize,getNthPolyOfId,leadExp64,pLength
+///////////////////////////////////////////////////////////////////
+
+ideal init64(ideal G,int64vec *currw64)
+{
+  int length=IDELEMS(G);
+  ideal I=idInit(length,G->rank);
+  int j;
+  int64 leadingweight,templeadingweight;
+  poly p=NULL;
+  poly leadp=NULL;
+  for (j=1; j<=length; j++)
+  {
+    p=getNthPolyOfId(G,j);
+    int64vec *tt=leadExp64(p);
+    leadingweight=scalarProduct64(currw64,tt /*leadExp64(p)*/);
+    delete tt;
+    while (p!=NULL)
+    {
+      tt=leadExp64(p);
+      templeadingweight=scalarProduct64(currw64,tt /*leadExp64(p)*/);
+      delete tt;
+      if(templeadingweight==leadingweight)
+      {
+        leadp=pAdd(leadp,pHead(p));
+      }
+      if(templeadingweight>leadingweight)
+      {
+        pDelete(&leadp);
+        leadp=pHead(p);
+        leadingweight=templeadingweight;
+      }
+      pIter(p);
+    }
+    (I->m)[j-1]=leadp;
+    p=NULL;
+    leadp=NULL;
+  }
+  return(I);
+}
+
+///////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////
+//currwOnBorder64
+///////////////////////////////////////////////////////////////////
+//Description: returns TRUE if currw64 lies on the border of the
+//groebner cone of the order w.r.t. which the reduced GB G
+//is calculated, otherwise FALSE
+///////////////////////////////////////////////////////////////////
+//Uses: init64
+///////////////////////////////////////////////////////////////////
+
+BOOLEAN currwOnBorder64(ideal G, int64vec* currw64)
+{
+  ideal J=init64(G,currw64);
+  int length=idealSize(J);
+  BOOLEAN res=FALSE;
+  for(int i=length; i>0; i--)
+  {
+    //if(pLength(getNthPolyOfId(J,i))>1)
+    poly p=getNthPolyOfId(J,i);
+    if ((p!=NULL) && (pNext(p)!=NULL))
+    {
+      res=TRUE;break;
+    }
+  }
+  idDelete(&J);
+  return res;
+}
+
+///////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////
+//noPolysWithMoreThanTwoTerms
+///////////////////////////////////////////////////////////////////
+//Description: returns TRUE if all polynomials of Gw are of length
+//<=2, otherwise FALSE
+///////////////////////////////////////////////////////////////////
+//Uses: idealSize, getNthPolyOfId
+///////////////////////////////////////////////////////////////////
+
+BOOLEAN noPolysWithMoreThanTwoTerms(ideal Gw)
+{
+  int length=idealSize(Gw);
+  for(int i=length; i>0; i--)
+  {
+    //if(pLength(getNthPolyOfId(Gw,i))>2)
+    poly p=getNthPolyOfId(Gw,i);
+    if ((p!=NULL) && (pNext(p)!=NULL) && (pNext(pNext(p))!=NULL))
+    {
+      return FALSE;
+    }
+  }
+  return TRUE;
+}
+
+///////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////
+//DIFFspy
+///////////////////////////////////////////////////////////////////
+//Description: returns the length of the list to be created in
+//DIFF
+///////////////////////////////////////////////////////////////////
+//Uses: idealSize,pLength,getNthPolyOfId
+///////////////////////////////////////////////////////////////////
+
+int DIFFspy(ideal G)
+{
+  int s=idealSize(G);
+  int j;
+  int temp;
+  int sum=0;
+  poly p;
+  for (j=1; j<=s; j++)
+  {
+    p=getNthPolyOfId(G,j);
+    if((temp=pLength(p))>0) {sum += (temp-1);}
+  }
+  return(sum);
+}
+
+///////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////
+//DIFF
+///////////////////////////////////////////////////////////////////
+//Description: returns a list of all differences of leading
+//exponents and nonleading exponents of elements of the current
+//GB (see relevant part of thesis for further details)
+///////////////////////////////////////////////////////////////////
+//Uses: DIFFspy,idealSize,getNthPolyOfId,leadExp,pLength
+///////////////////////////////////////////////////////////////////
+
+intvec* DIFF(ideal G)
+{
+  intvec  *v,*w;
+  poly p;
+  int s=idealSize(G);
+  int n=rVar(currRing);
+  int m=DIFFspy(G);
+  intvec* diffm=new intvec(m,n,0);
+  int j,l;
+  int inc=0;
+  for (j=1; j<=s; j++)
+  {
+    p=getNthPolyOfId(G,j);
+    v=leadExp(p);
+    pIter(p);
+    while(p!=NULL)
+    {
+      inc++;
+      intvec *lep=leadExp(p);
+      w=ivSub(v,lep /*leadExp(p)*/);
+      delete lep;
+      pIter(p);
+      for (l=1; l<=n; l++)
+      {
+        // setPosOfIM(diffm,inc,l,(*w)[l-1]);
+        IMATELEM(*diffm,inc,l) =(*w)[l-1] ;
+      }
+      delete w;
+    }
+    delete v;
+  }
+  return(diffm);
+}
+
+///////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////
+//gett64
+///////////////////////////////////////////////////////////////////
+//Description: returns the t corresponding to the vector listw
+//which contains a vector from the list returned by DIFF
+///////////////////////////////////////////////////////////////////
+//Uses: ivSize
+///////////////////////////////////////////////////////////////////
+
+void gett64(intvec* listw, int64vec* currw64, int64vec* targw64, int64 &tvec0, int64 &tvec1)
+{
+  int s=ivSize(listw);
+  int j;
+  int64 zaehler64=0;
+  int64 nenner64=0;
+  int64 temp1,temp2,temp3,temp4; //overflowstuff
+  for(j=1; j<=s; j++)
+  {
+
+    temp3=zaehler64;
+    temp1=((int64)((*listw)[j-1]));
+    temp2=((*currw64)[j-1]);
+    temp4=temp1*temp2;
+    zaehler64=temp3-temp4;
+
+    //overflow test
+    if(temp1!=0 && (temp4/temp1)!=temp2) overflow_error=3;
+
+    if( ( temp3<0 && temp4>0 ) || ( temp3>0 && temp4<0 ) )
+    {
+      int64 abs_t3=abs64(temp3);
+      if( (abs_t3+abs64(temp4))<abs_t3 ) overflow_error=4;
+    }
+
+    //overflow test
+    temp1=((*targw64)[j-1])-((*currw64)[j-1]);
+    //this subtraction can never yield an overflow since both number
+    //will always be positive
+    temp2=((int64)((*listw)[j-1]));
+    temp3=nenner64;
+    temp4=temp1*temp2;
+    nenner64=temp3+temp4;
+
+    //overflow test
+    if(temp1!=0 && ((temp1*temp2)/temp1)!=temp2) overflow_error=5;
+
+    if( (temp3>0 && temp4>0) ||
+      (temp3<0 && temp4<0)    )
+    {
+      int64 abs_t3=abs64(temp3);
+      if( (abs_t3+abs64(temp4))<abs_t3 )
+      {
+        overflow_error=6;
+      }
+    }
+  }
+
+  if (nenner64==0)
+  {
+    zaehler64=2;
+  }
+  else
+  {
+    if ( (zaehler64<=0) && (nenner64<0) )
+    {
+      zaehler64=-zaehler64;
+      nenner64=-nenner64;
+    }
+  }
+
+  int64 g=gcd64(zaehler64,nenner64);
+
+  tvec0=zaehler64/g;
+  tvec1=nenner64/g;
+
+}
+
+///////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////
+//nextt64
+///////////////////////////////////////////////////////////////////
+//Description: returns the t determining the next weight vector
+///////////////////////////////////////////////////////////////////
+//Uses:
+///////////////////////////////////////////////////////////////////
+
+void nextt64(ideal G,int64vec* currw64,int64vec* targw64, int64 & tvec0, int64 & tvec1)
+{
+  intvec* diffm=DIFF(G);
+  int s=diffm->rows();
+  tvec0=(int64)2;
+  tvec1=(int64)0;
+  intvec *tt;
+  for(int j=1; j<=s; j++)
+  {
+    tt=getNthRow(diffm,j);
+    int64 temptvec0, temptvec1;
+    gett64(tt,currw64,targw64,temptvec0, temptvec1);
+    delete tt;
+
+    //if tempt>0 both parts will be>0
+    if ( (temptvec1!=0) //that tempt is defined
+       &&
+       (temptvec0>0) && (temptvec1>0) //that tempt>0
+     )
+    {
+      if( ( (temptvec0) <= (temptvec1) ) //that tempt<=1
+        &&
+        ( ( (temptvec0) * (tvec1) ) <
+          ( (temptvec1) * (tvec0) ) )
+      )
+      {  //that tempt<t
+        tvec0=temptvec0;
+        tvec1=temptvec1;
+      }
+    }
+  }
+  delete diffm;
+  return;
+}
+
+///////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////
+//nextw64
+///////////////////////////////////////////////////////////////////
+//Uses:iv64Size,gcd,
+///////////////////////////////////////////////////////////////////
+
+int64vec* nextw64(int64vec* currw, int64vec* targw,
+                  int64 nexttvec0, int64 nexttvec1)
+{
+  //to do (targw-currw)*tvec[0]+currw*tvec[1]
+  int64vec* tempv;
+  int64vec* nextweight;
+  int64vec* a=iv64Sub(targw,currw);
+  //no overflow can occur since both are>=0
+
+  //to test overflow
+  tempv=iv64Copy(a);
+  *a *= (nexttvec0);
+  for(int i=0; i<rVar(currRing); i++)
+  {
+    if( (nexttvec0) !=0 &&
+        (((*a)[i])/(nexttvec0))!=((*tempv)[i]) )
+    {
+      overflow_error=7;
+      break;
+    }
+  }
+  delete tempv;
+  int64vec* b=currw;
+  tempv=iv64Copy(b);
+  *b *= (nexttvec1);
+  for(int i=0; i<rVar(currRing); i++)
+  {
+    if( (nexttvec1) !=0 &&
+        (((*b)[i])/(nexttvec1))!=((*tempv)[i]) )
+    {
+      overflow_error=8;
+      break;
+    }
+  }
+  delete tempv;
+  nextweight=iv64Add(a,b);
+
+  for(int i=0; i<rVar(currRing); i++)
+  {
+    if( (((*a)[i])>=0 && ((*b)[i])>=0) ||
+        (((*a)[i])<0 && ((*b)[i])<0) )
+    {
+      if( (abs64((*a)[i]))>abs64((*nextweight)[i]) ||
+          (abs64((*b)[i]))>abs64((*nextweight)[i])
+        )
+      {
+        overflow_error=9;
+        break;
+      }
+    }
+  }
+
+  //to reduce common factors of nextweight
+  int s=iv64Size(nextweight);
+  int64 g,temp;
+  g=(*nextweight)[0];
+  for (int i=1; i<s; i++)
+  {
+    temp=(*nextweight)[i];
+    g=gcd64(g,temp);
+    if (g==1) break;
+  }
+
+  if (g!=1) *nextweight /= g;
+
+  return(nextweight);
+}
+
+///////////////////////////////////////////////////////////////////
+
+
+
+///////////////////////////////////////////////////////////////////
+//FUNCTIONS NOT ORIGINATING FROM THE SINGULAR IMPLEMENTATION CODE
+///////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////
+//getNthPolyOfId
+///////////////////////////////////////////////////////////////////
+//Description: returns the nth poly of ideal I
+///////////////////////////////////////////////////////////////////
+poly getNthPolyOfId(ideal I,int n)
+{
+  if(0<n && n<=((int)I->ncols))
+  {
+    return (I->m)[n-1];
+  }
+  else
+  {
+    return(NULL);
+  }
+}
+
+///////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////
+//idealSize
+///////////////////////////////////////////////////////////////////
+//Description: returns the number of generator of input ideal I
+///////////////////////////////////////////////////////////////////
+//Uses: none
+///////////////////////////////////////////////////////////////////
+// #define idealSize(I) IDELEMS(I)
+///////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////
+//ivSize
+///////////////////////////////////////////////////////////////////
+//Description: returns the number of entries of v
+///////////////////////////////////////////////////////////////////
+//Uses: none
+///////////////////////////////////////////////////////////////////
+
+// inline int ivSize(intvec* v){ return((v->rows())*(v->cols())); }
+
+///////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////
+//iv64Size
+///////////////////////////////////////////////////////////////////
+//Description: returns the number of entries of v
+///////////////////////////////////////////////////////////////////
+//Uses: none
+///////////////////////////////////////////////////////////////////
+
+// int iv64Size(int64vec* v){ return((v->rows())*(v->cols())); }
+
+///////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////
+//leadExp
+///////////////////////////////////////////////////////////////////
+//Description: returns an intvec containg the exponet vector of p
+///////////////////////////////////////////////////////////////////
+//Uses: sizeof,omAlloc,omFree
+///////////////////////////////////////////////////////////////////
+
+intvec* leadExp(poly p)
+{
+  int N=rVar(currRing);
+  int *e=(int*)omAlloc((N+1)*sizeof(int));
+  pGetExpV(p,e);
+  intvec* iv=new intvec(N);
+  for(int i=N;i>0;i--) { (*iv)[i-1]=e[i];}
+  omFree(e);
+  return(iv);
+}
+
+///////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////
+//leadExp64
+///////////////////////////////////////////////////////////////////
+//Description: returns an int64vec containing the exponent
+//vector of p
+///////////////////////////////////////////////////////////////////
+//Uses: sizeof,omAlloc,omFree
+///////////////////////////////////////////////////////////////////
+
+int64vec* leadExp64(poly p)
+{
+  int N=rVar(currRing);
+  int *e=(int*)omAlloc((N+1)*sizeof(int));
+  pGetExpV(p,e);
+  int64vec* iv64=new int64vec(N);
+  for(int i=N;i>0;i--) { (*iv64)[i-1]=(int64)e[i];}
+  omFree(e);
+  return(iv64);
+}
+
+///////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////
+//setPosOfIM
+///////////////////////////////////////////////////////////////////
+//Description: sets entry i,j of im to val
+///////////////////////////////////////////////////////////////////
+//Uses: none
+///////////////////////////////////////////////////////////////////
+
+//void setPosOfIM(intvec* im,int i,int j,int val){
+//  int r=im->rows();
+//  int c=im->cols();
+//  if( (0<i && i<=r) && (0<j && j<=c) ){
+//    (*im)[(i-1)*c+j-1]=val;
+//    }
+//  return;
+//}
+
+///////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////
+//scalarProduct
+///////////////////////////////////////////////////////////////////
+//Description: returns the scalar product of intvecs a and b
+///////////////////////////////////////////////////////////////////
+//Uses: none
+///////////////////////////////////////////////////////////////////
+
+static inline long  scalarProduct(intvec* a, intvec* b)
+{
+  assume( a->length() ==  b->length());
+  int i, n = a->length();
+  long result = 0;
+  for(i=n-1; i>=0; i--)
+    result += (*a)[i] * (*b)[i];
+  return result;
+}
+
+///////////////////////////////////////////////////////////////////
+
+
+
+///////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////
+//gcd
+///////////////////////////////////////////////////////////////////
+//Description: returns the gcd of a and b
+///////////////////////////////////////////////////////////////////
+//Uses: none
+///////////////////////////////////////////////////////////////////
+
+int gcd(int a, int b)
+{
+  int r, p0 = a, p1 = b;
+  if(p0 < 0)
+    p0 = -p0;
+
+  if(p1 < 0)
+    p1 = -p1;
+  while(p1 != 0)
+  {
+    r = p0 % p1;
+    p0 = p1;
+    p1 = r;
+  }
+  return p0;
+}
+
+///////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////
+//gcd64
+///////////////////////////////////////////////////////////////////
+//Description: returns the gcd of a and b
+///////////////////////////////////////////////////////////////////
+//Uses: none
+///////////////////////////////////////////////////////////////////
+
+int64 gcd64(int64 a, int64 b)
+{
+  int64 r, p0 = a, p1 = b;
+  if(p0 < 0)
+    p0 = -p0;
+
+  if(p1 < 0)
+    p1 = -p1;
+
+  while(p1 != ((int64)0) )
+  {
+    r = p0 % p1;
+    p0 = p1;
+    p1 = r;
+  }
+
+  return p0;
+}
+
+///////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////
+//abs64
+///////////////////////////////////////////////////////////////////
+//Description: returns the absolute value of int64 i
+///////////////////////////////////////////////////////////////////
+//Uses: none
+///////////////////////////////////////////////////////////////////
+
+//int64 abs64(int64 i)
+//{
+//  if(i>=0)
+//  return(i);
+//else
+//  return((-i));
+//}
+
+///////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////
+//makeTaunList64
+///////////////////////////////////////////////////////////////////
+//Description: makes a list of an int64vec and an int64
+///////////////////////////////////////////////////////////////////
+//Uses: omAllocBin
+///////////////////////////////////////////////////////////////////
+
+#if 0
+lists makeTaunList64(int64vec *iv64,int64 i64)
+{
+  lists l=(lists)omAllocBin(slists_bin);
+  l->Init(2);
+  l->m[0].rtyp=INTVEC_CMD;
+  l->m[1].rtyp=INT_CMD;
+  l->m[0].data=(void *)iv64;
+  l->m[1].data=(void *)i64;
+  return l;
+}
+#endif
+
+///////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////
+//idStd
+///////////////////////////////////////////////////////////////////
+//Description: returns the GB of G calculated w.r.t. the order of
+//currRing
+///////////////////////////////////////////////////////////////////
+//Uses: kStd,idSkipZeroes
+///////////////////////////////////////////////////////////////////
+
+ideal idStd(ideal G)
+{
+  ideal GG = kStd(G, NULL, testHomog, NULL);
+  idSkipZeroes(GG);
+  return GG;
+}
+
+///////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////
+//idInterRed
+///////////////////////////////////////////////////////////////////
+//Description: returns the interreduction of G
+///////////////////////////////////////////////////////////////////
+//Assumes: that the input is a GB
+///////////////////////////////////////////////////////////////////
+//Uses: kInterRed,idSkipZeroes
+///////////////////////////////////////////////////////////////////
+
+ideal idInterRed(ideal G)
+{
+  assume(G != NULL);
+
+  ideal GG = kInterRedOld(G, NULL);
+  idDelete(&G);
+  return GG;
+}
+
+///////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////
+//matIdLift
+///////////////////////////////////////////////////////////////////
+//Description: yields the same reslut as lift in Singular
+///////////////////////////////////////////////////////////////////
+//Uses: idLift,idModule2formatedMatrix
+///////////////////////////////////////////////////////////////////
+
+matrix matIdLift(ideal Gomega, ideal M)
+{
+  ideal Mtmp = idLift(Gomega, M, NULL, FALSE, FALSE, TRUE, NULL);
+  int rows=IDELEMS(Gomega);
+  int cols=IDELEMS(Mtmp);
+  matrix res=id_Module2formatedMatrix(Mtmp,rows,cols,currRing);
+  return res;
+}
+///////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////
+//rCopyAndChangeA
+///////////////////////////////////////////////////////////////////
+//Description: changes currRing to a copy of currRing with the
+//int64vec w instead of the old one
+///////////////////////////////////////////////////////////////////
+//Assumes: that currRing is alterd as mentioned in rCopy0AndAddA
+///////////////////////////////////////////////////////////////////
+//Uses: rCopy0,rComplete,rChangeCurrRing,rSetWeightVec
+///////////////////////////////////////////////////////////////////
+
+void rCopyAndChangeA(int64vec* w)
+{
+  ring rnew=rCopy0(currRing);
+  rComplete(rnew);
+  rSetWeightVec(rnew,w->iv64GetVec());
+  rChangeCurrRing(rnew);
+}
+
+///////////////////////////////////////////////////////////////////
+//rGetGlobalOrderMatrix
+///////////////////////////////////////////////////////////////////
+//Description: returns a matrix corresponding to the order of r
+///////////////////////////////////////////////////////////////////
+//Assumes: the order of r is a combination of the orders M,lp,dp,
+//Dp,wp,Wp,C
+///////////////////////////////////////////////////////////////////
+//Uses: none
+///////////////////////////////////////////////////////////////////
+
+int64vec* rGetGlobalOrderMatrix(ring r)
+{
+  int n=rVar(r);
+  int64vec* res=new int64vec(n,n,(int64)0);
+  if (rHasLocalOrMixedOrdering(r)) return res;
+  int pos1=0;
+  int pos2=0;
+  int temp;
+  int i=0;
+  while(r->order[i]!=0 && pos2<n)
+  {
+    pos2=pos2+r->block1[i] - r->block0[i];
+
+    if(r->order[i]==ringorder_lp)
+    {
+      temp=pos1;
+      for(int j=pos1; j<=pos2; j++)
+        (*res)[j*n+j]=(int64)1;
+    }
+    else if(r->order[i]==ringorder_dp)
+    {
+      for(int j=pos1;j<=pos2;j++)
+        (*res)[pos1*n+j]=(int64)1;
+      for(int j=1;j<=(pos2-pos1);j++)
+        (*res)[(pos1+j)*n+(pos2+1-j)]=(int64)-1;
+    }
+    else if(r->order[i]==ringorder_Dp)
+    {
+      for(int j=pos1;j<=pos2;j++)
+        (*res)[pos1*n+j]=(int64)1;
+      for(int j=1;j<=(pos2-pos1);j++)
+        (*res)[(pos1+j)*n+(pos1+j-1)]=(int64)1;
+    }
+    else if(r->order[i]==ringorder_wp)
+    {
+      int* weights=r->wvhdl[i];
+      for(int j=pos1;j<=pos2;j++)
+        (*res)[pos1*n+j]=(int64)weights[j-pos1];
+      for(int j=1;j<=(pos2-pos1);j++)
+        (*res)[(pos1+j)*n+(pos2+1-j)]=(int64)-1;
+    }
+    else if(r->order[i]==ringorder_Wp)
+    {
+      int* weights=r->wvhdl[i];
+      for(int j=pos1;j<=pos2;j++)
+        (*res)[pos1*n+j]=(int64)weights[j-pos1];
+      for(int j=1;j<=(pos2-pos1);j++)
+        (*res)[(pos1+j)*n+(pos1+j-1)]=(int64)1;
+    }
+
+    else if(r->order[0]==ringorder_M)
+    {
+      int* weights=r->wvhdl[0];
+      for(int j=pos1;j<((pos2+1)*(pos2+1));j++)
+        (*res)[j]=(int64)weights[j];
+    }
+
+    pos1=pos2+1;
+    pos2=pos2+1;
+    i++;
+  }
+
+  return(res);
+}
+
+///////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////
+//rGetGlobalOrderWeightVec
+///////////////////////////////////////////////////////////////////
+//Description: returns a weight vector corresponding to the first
+//row of a matrix corresponding to the order of r
+///////////////////////////////////////////////////////////////////
+//Uses: none
+///////////////////////////////////////////////////////////////////
+
+int64vec* rGetGlobalOrderWeightVec(ring r)
+{
+  int n=rVar(r);
+  int64vec* res=new int64vec(n);
+
+  if (rHasLocalOrMixedOrdering(r)) return res;
+
+  int length;
+
+  if(r->order[0]==ringorder_lp)
+  {
+    (*res)[0]=(int64)1;
+  }
+  else if( (r->order[0]==ringorder_dp) || (r->order[0]==ringorder_Dp) )
+  {
+    length=r->block1[0] - r->block0[0];
+    for (int j=0;j<=length;j++)
+      (*res)[j]=(int64)1;
+  }
+  else if( (r->order[0]==ringorder_wp) || (r->order[0]==ringorder_Wp) ||
+      (r->order[0]==ringorder_a)  || (r->order[0]==ringorder_M)    )
+  {
+    int* weights=r->wvhdl[0];
+    length=r->block1[0] - r->block0[0];
+    for (int j=0;j<=length;j++)
+      (*res)[j]=(int64)weights[j];
+  }
+  else if(  /*(*/ r->order[0]==ringorder_a64 /*)*/  )
+  {
+    int64* weights=(int64*)r->wvhdl[0];
+    length=r->block1[0] - r->block0[0];
+    for (int j=0;j<=length;j++)
+      (*res)[j]=weights[j];
+  }
+
+  return(res);
+}
+
+///////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////
+//sortRedSB
+///////////////////////////////////////////////////////////////////
+//Description: sorts a reduced GB of an ideal after the leading
+//terms of the polynomials with the smallest one first
+///////////////////////////////////////////////////////////////////
+//Assumes: that the given input is a minimal GB
+///////////////////////////////////////////////////////////////////
+//Uses:idealSize,idCopy,pLmCmp
+///////////////////////////////////////////////////////////////////
+
+ideal sortRedSB(ideal G)
+{
+  int s=idealSize(G);
+  poly* m=G->m;
+  poly p,q;
+  for (int i=0; i<(s-1); i++)
+  {
+    for (int j=0; j<((s-1)-i); j++)
+    {
+      p=m[j];
+      q=m[j+1];
+      if (pLmCmp(p,q)==1)
+      {
+        m[j+1]=p;
+        m[j]=q;
+      }
+    }
+  }
+  return(G);
+}
+
+///////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////
+//int64VecToIntVec
+///////////////////////////////////////////////////////////////////
+//Description: converts an int64vec to an intvec
+// deletes the input
+///////////////////////////////////////////////////////////////////
+//Assumes: that the int64vec contains no entries larger than 2^32
+///////////////////////////////////////////////////////////////////
+//Uses: none
+///////////////////////////////////////////////////////////////////
+
+intvec* int64VecToIntVec(int64vec* source)
+{
+  int r=source->rows();
+  int c=source->cols();
+  intvec* res=new intvec(r,c,0);
+  for(int i=0;i<r;i++){
+    for(int j=0;j<c;j++){
+      (*res)[i*c+j]=(int)(*source)[i*c+j];
+    }
+  }
+  delete source;
+  return(res);
+}
+
+///////////////////////////////////////////////////////////////////
diff --git a/kernel/groebner_walk/walkSupport.h b/kernel/groebner_walk/walkSupport.h
new file mode 100644
index 0000000..646cb5d
--- /dev/null
+++ b/kernel/groebner_walk/walkSupport.h
@@ -0,0 +1,51 @@
+#ifndef WALKSUPPORT_H
+#define WALKSUPPORT_H
+
+#include <misc/intvec.h>
+#include <misc/int64vec.h>
+
+int tdeg(poly p);
+int getMaxTdeg(ideal I);
+int getMaxPosOfNthRow(intvec *v,int n);
+int64 getInvEps64(ideal G,intvec *targm,int pertdeg);
+int invEpsOk64(ideal I, intvec *targm, int pertdeg, int64 inveps64);
+intvec* getNthRow(intvec *v, int n);
+int64vec* getNthRow64(intvec *v, int n);
+//int64vec* gett64(int64vec* listw, int64vec* currw, int64vec* targw);
+void gett64(int64vec* listw, int64vec* currw, int64vec* targw, int64 &t1, int64 &t2);
+void nextt64(ideal G, int64vec* currw, int64vec* targw, int64 &t1, int64 &t2);
+int64vec* nextw64(int64vec* currw, int64vec* targw, int64 nexttvec0, int64 nexttvec1);
+int DIFFspy(ideal G);
+intvec* DIFF(ideal G);
+ideal init64(ideal G,int64vec* currw);
+BOOLEAN currwOnBorder64(ideal I, int64vec* currw64);
+void getTaun64(ideal G,intvec* targm,int pertdeg, int64vec** v64, int64 & i64);
+//int64vec* getiv64(lists l);
+//int64 getint64(lists l);// not used
+
+
+//functions not originating from the oroginal SINGULAR implementation
+ideal idStd(ideal G);
+ideal idInterRed(ideal G);
+matrix matIdLift(ideal Gomega, ideal M);
+void rCopyAndChangeA(int64vec* w);
+int64vec* rGetGlobalOrderMatrix(ring r);
+int64vec* rGetGlobalOrderWeightVec(ring r);
+BOOLEAN noPolysWithMoreThanTwoTerms(ideal Gw);
+#define idealSize(I) IDELEMS(I)
+inline int ivSize(intvec* v){ return((v->rows())*(v->cols())); }
+inline int iv64Size(int64vec* v){ return((v->rows())*(v->cols())); }
+intvec* leadExp(poly p);
+int64vec* leadExp64(poly p);
+void setPosOfIM(intvec* im,int i,int j,int val);
+poly getNthPolyOfId(ideal I,int n);
+int gcd(int a, int b);
+int64 gcd64(int64 a, int64 b);
+inline int64 abs64(int64 i) { return ABS(i); }
+//static inline long  scalarProduct(intvec* a, intvec* b);
+//static inline int64  scalarProduct64(int64vec* a, int64vec* b);
+ideal sortRedSB(ideal G);
+intvec* int64VecToIntVec(int64vec* source);
+int64vec* rGetGlobalOrderWeightVec(ring r);
+
+#endif
diff --git a/kernel/ideals.cc b/kernel/ideals.cc
new file mode 100644
index 0000000..46a6e4a
--- /dev/null
+++ b/kernel/ideals.cc
@@ -0,0 +1,2678 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT - all basic methods to manipulate ideals
+*/
+
+/* includes */
+
+#include <kernel/mod2.h>
+
+#include <omalloc/omalloc.h>
+
+#ifndef SING_NDEBUG
+# define MYTEST 0
+#else /* ifndef SING_NDEBUG */
+# define MYTEST 0
+#endif /* ifndef SING_NDEBUG */
+
+#include <omalloc/omalloc.h>
+
+#include <misc/options.h>
+#include <misc/intvec.h>
+
+#include <coeffs/coeffs.h>
+#include <coeffs/numbers.h>
+// #include <coeffs/longrat.h>
+
+
+#include <polys/monomials/ring.h>
+#include <polys/matpol.h>
+#include <polys/weight.h>
+#include <polys/sparsmat.h>
+#include <polys/prCopy.h>
+#include <polys/nc/nc.h>
+
+
+#include <kernel/ideals.h>
+
+#include <kernel/polys.h>
+
+#include <kernel/GBEngine/kstd1.h>
+#include <kernel/GBEngine/syz.h>
+
+
+/* #define WITH_OLD_MINOR */
+
+/*0 implementation*/
+
+/*2
+*returns a minimized set of generators of h1
+*/
+ideal idMinBase (ideal h1)
+{
+  ideal h2, h3,h4,e;
+  int j,k;
+  int i,l,ll;
+  intvec * wth;
+  BOOLEAN homog;
+  #ifdef HAVE_RINGS
+  if(rField_is_Ring(currRing))
+  {
+      WarnS("minbase applies only to the local or homogeneous case over coefficient fields");
+      e=idCopy(h1);
+      return e;
+  }
+  #endif
+  homog = idHomModule(h1,currRing->qideal,&wth);
+  if (rHasGlobalOrdering(currRing))
+  {
+    if(!homog)
+    {
+      WarnS("minbase applies only to the local or homogeneous case over coefficient fields");
+      e=idCopy(h1);
+      return e;
+    }
+    else
+    {
+      ideal re=kMin_std(h1,currRing->qideal,(tHomog)homog,&wth,h2,NULL,0,3);
+      idDelete(&re);
+      return h2;
+    }
+  }
+  e=idInit(1,h1->rank);
+  if (idIs0(h1))
+  {
+    return e;
+  }
+  pEnlargeSet(&(e->m),IDELEMS(e),15);
+  IDELEMS(e) = 16;
+  h2 = kStd(h1,currRing->qideal,isNotHomog,NULL);
+  h3 = idMaxIdeal(1);
+  h4=idMult(h2,h3);
+  idDelete(&h3);
+  h3=kStd(h4,currRing->qideal,isNotHomog,NULL);
+  k = IDELEMS(h3);
+  while ((k > 0) && (h3->m[k-1] == NULL)) k--;
+  j = -1;
+  l = IDELEMS(h2);
+  while ((l > 0) && (h2->m[l-1] == NULL)) l--;
+  for (i=l-1; i>=0; i--)
+  {
+    if (h2->m[i] != NULL)
+    {
+      ll = 0;
+      while ((ll < k) && ((h3->m[ll] == NULL)
+      || !pDivisibleBy(h3->m[ll],h2->m[i])))
+        ll++;
+      if (ll >= k)
+      {
+        j++;
+        if (j > IDELEMS(e)-1)
+        {
+          pEnlargeSet(&(e->m),IDELEMS(e),16);
+          IDELEMS(e) += 16;
+        }
+        e->m[j] = pCopy(h2->m[i]);
+      }
+    }
+  }
+  idDelete(&h2);
+  idDelete(&h3);
+  idDelete(&h4);
+  if (currRing->qideal!=NULL)
+  {
+    h3=idInit(1,e->rank);
+    h2=kNF(h3,currRing->qideal,e);
+    idDelete(&h3);
+    idDelete(&e);
+    e=h2;
+  }
+  idSkipZeroes(e);
+  return e;
+}
+
+
+/*2
+*initialized a field with r numbers between beg and end for the
+*procedure idNextChoise
+*/
+ideal idSectWithElim (ideal h1,ideal h2)
+// does not destroy h1,h2
+{
+  if (TEST_OPT_PROT) PrintS("intersect by elimination method\n");
+  assume(!idIs0(h1));
+  assume(!idIs0(h2));
+  assume(IDELEMS(h1)<=IDELEMS(h2));
+  assume(id_RankFreeModule(h1,currRing)==0);
+  assume(id_RankFreeModule(h2,currRing)==0);
+  // add a new variable:
+  int j;
+  ring origRing=currRing;
+  ring r=rCopy0(origRing);
+  r->N++;
+  r->block0[0]=1;
+  r->block1[0]= r->N;
+  omFree(r->order);
+  r->order=(int*)omAlloc0(3*sizeof(int*));
+  r->order[0]=ringorder_dp;
+  r->order[1]=ringorder_C;
+  char **names=(char**)omAlloc0(rVar(r) * sizeof(char_ptr));
+  for (j=0;j<r->N-1;j++) names[j]=r->names[j];
+  names[r->N-1]=omStrDup("@");
+  omFree(r->names);
+  r->names=names;
+  rComplete(r,TRUE);
+  // fetch h1, h2
+  ideal h;
+  h1=idrCopyR(h1,origRing,r);
+  h2=idrCopyR(h2,origRing,r);
+  // switch to temp. ring r
+  rChangeCurrRing(r);
+  // create 1-t, t
+  poly omt=p_One(currRing);
+  p_SetExp(omt,r->N,1,currRing);
+  poly t=p_Copy(omt,currRing);
+  p_Setm(omt,currRing);
+  omt=p_Neg(omt,currRing);
+  omt=p_Add_q(omt,pOne(),currRing);
+  // compute (1-t)*h1
+  h1=(ideal)mp_MultP((matrix)h1,omt,currRing);
+  // compute t*h2
+  h2=(ideal)mp_MultP((matrix)h2,pCopy(t),currRing);
+  // (1-t)h1 + t*h2
+  h=idInit(IDELEMS(h1)+IDELEMS(h2),1);
+  int l;
+  for (l=IDELEMS(h1)-1; l>=0; l--)
+  {
+    h->m[l] = h1->m[l];  h1->m[l]=NULL;
+  }
+  j=IDELEMS(h1);
+  for (l=IDELEMS(h2)-1; l>=0; l--)
+  {
+    h->m[l+j] = h2->m[l];  h2->m[l]=NULL;
+  }
+  idDelete(&h1);
+  idDelete(&h2);
+  // eliminate t:
+
+  ideal res=idElimination(h,t);
+  // cleanup
+  idDelete(&h);
+  if (res!=NULL) res=idrMoveR(res,r,origRing);
+  rChangeCurrRing(origRing);
+  rDelete(r);
+  return res;
+}
+/*2
+* h3 := h1 intersect h2
+*/
+ideal idSect (ideal h1,ideal h2)
+{
+  int i,j,k,length;
+  int flength = id_RankFreeModule(h1,currRing);
+  int slength = id_RankFreeModule(h2,currRing);
+  int rank=si_max(h1->rank,h2->rank);
+  if ((idIs0(h1)) || (idIs0(h2)))  return idInit(1,rank);
+
+  ideal first,second,temp,temp1,result;
+  poly p,q;
+
+  if (IDELEMS(h1)<IDELEMS(h2))
+  {
+    first = h1;
+    second = h2;
+  }
+  else
+  {
+    first = h2;
+    second = h1;
+    int t=flength; flength=slength; slength=t;
+  }
+  length  = si_max(flength,slength);
+  if (length==0)
+  {
+    if ((currRing->qideal==NULL)
+    && (currRing->OrdSgn==1)
+    && (!rIsPluralRing(currRing))
+    && ((TEST_V_INTERSECT_ELIM) || (!TEST_V_INTERSECT_SYZ)))
+      return idSectWithElim(first,second);
+    else length = 1;
+  }
+  if (TEST_OPT_PROT) PrintS("intersect by syzygy methods\n");
+  j = IDELEMS(first);
+
+  ring orig_ring=currRing;
+  ring syz_ring=rAssure_SyzComp(orig_ring,TRUE); rChangeCurrRing(syz_ring);
+  rSetSyzComp(length, syz_ring);
+
+  while ((j>0) && (first->m[j-1]==NULL)) j--;
+  temp = idInit(j /*IDELEMS(first)*/+IDELEMS(second),length+j);
+  k = 0;
+  for (i=0;i<j;i++)
+  {
+    if (first->m[i]!=NULL)
+    {
+      if (syz_ring==orig_ring)
+        temp->m[k] = pCopy(first->m[i]);
+      else
+        temp->m[k] = prCopyR(first->m[i], orig_ring, syz_ring);
+      q = pOne();
+      pSetComp(q,i+1+length);
+      pSetmComp(q);
+      if (flength==0) p_Shift(&(temp->m[k]),1,currRing);
+      p = temp->m[k];
+      while (pNext(p)!=NULL) pIter(p);
+      pNext(p) = q;
+      k++;
+    }
+  }
+  for (i=0;i<IDELEMS(second);i++)
+  {
+    if (second->m[i]!=NULL)
+    {
+      if (syz_ring==orig_ring)
+        temp->m[k] = pCopy(second->m[i]);
+      else
+        temp->m[k] = prCopyR(second->m[i], orig_ring,currRing);
+      if (slength==0) p_Shift(&(temp->m[k]),1,currRing);
+      k++;
+    }
+  }
+  intvec *w=NULL;
+  temp1 = kStd(temp,currRing->qideal,testHomog,&w,NULL,length);
+  if (w!=NULL) delete w;
+  idDelete(&temp);
+  if(syz_ring!=orig_ring)
+    rChangeCurrRing(orig_ring);
+
+  result = idInit(IDELEMS(temp1),rank);
+  j = 0;
+  for (i=0;i<IDELEMS(temp1);i++)
+  {
+    if ((temp1->m[i]!=NULL)
+    && (p_GetComp(temp1->m[i],syz_ring)>length))
+    {
+      if(syz_ring==orig_ring)
+      {
+        p = temp1->m[i];
+      }
+      else
+      {
+        p = prMoveR(temp1->m[i], syz_ring,orig_ring);
+      }
+      temp1->m[i]=NULL;
+      while (p!=NULL)
+      {
+        q = pNext(p);
+        pNext(p) = NULL;
+        k = pGetComp(p)-1-length;
+        pSetComp(p,0);
+        pSetmComp(p);
+        /* Warning! multiply only from the left! it's very important for Plural */
+        result->m[j] = pAdd(result->m[j],pMult(p,pCopy(first->m[k])));
+        p = q;
+      }
+      j++;
+    }
+  }
+  if(syz_ring!=orig_ring)
+  {
+    rChangeCurrRing(syz_ring);
+    idDelete(&temp1);
+    rChangeCurrRing(orig_ring);
+    rDelete(syz_ring);
+  }
+  else
+  {
+    idDelete(&temp1);
+  }
+
+  idSkipZeroes(result);
+  if (TEST_OPT_RETURN_SB)
+  {
+     w=NULL;
+     temp1=kStd(result,currRing->qideal,testHomog,&w);
+     if (w!=NULL) delete w;
+     idDelete(&result);
+     idSkipZeroes(temp1);
+     return temp1;
+  }
+  else //temp1=kInterRed(result,currRing->qideal);
+    return result;
+}
+
+/*2
+* ideal/module intersection for a list of objects
+* given as 'resolvente'
+*/
+ideal idMultSect(resolvente arg, int length)
+{
+  int i,j=0,k=0,syzComp,l,maxrk=-1,realrki;
+  ideal bigmat,tempstd,result;
+  poly p;
+  int isIdeal=0;
+  intvec * w=NULL;
+
+  /* find 0-ideals and max rank -----------------------------------*/
+  for (i=0;i<length;i++)
+  {
+    if (!idIs0(arg[i]))
+    {
+      realrki=id_RankFreeModule(arg[i],currRing);
+      k++;
+      j += IDELEMS(arg[i]);
+      if (realrki>maxrk) maxrk = realrki;
+    }
+    else
+    {
+      if (arg[i]!=NULL)
+      {
+        return idInit(1,arg[i]->rank);
+      }
+    }
+  }
+  if (maxrk == 0)
+  {
+    isIdeal = 1;
+    maxrk = 1;
+  }
+  /* init -----------------------------------------------------------*/
+  j += maxrk;
+  syzComp = k*maxrk;
+
+  ring orig_ring=currRing;
+  ring syz_ring=rAssure_SyzComp(orig_ring,TRUE); rChangeCurrRing(syz_ring);
+  rSetSyzComp(syzComp, syz_ring);
+
+  bigmat = idInit(j,(k+1)*maxrk);
+  /* create unit matrices ------------------------------------------*/
+  for (i=0;i<maxrk;i++)
+  {
+    for (j=0;j<=k;j++)
+    {
+      p = pOne();
+      pSetComp(p,i+1+j*maxrk);
+      pSetmComp(p);
+      bigmat->m[i] = pAdd(bigmat->m[i],p);
+    }
+  }
+  /* enter given ideals ------------------------------------------*/
+  i = maxrk;
+  k = 0;
+  for (j=0;j<length;j++)
+  {
+    if (arg[j]!=NULL)
+    {
+      for (l=0;l<IDELEMS(arg[j]);l++)
+      {
+        if (arg[j]->m[l]!=NULL)
+        {
+          if (syz_ring==orig_ring)
+            bigmat->m[i] = pCopy(arg[j]->m[l]);
+          else
+            bigmat->m[i] = prCopyR(arg[j]->m[l], orig_ring,currRing);
+          p_Shift(&(bigmat->m[i]),k*maxrk+isIdeal,currRing);
+          i++;
+        }
+      }
+      k++;
+    }
+  }
+  /* std computation --------------------------------------------*/
+  tempstd = kStd(bigmat,currRing->qideal,testHomog,&w,NULL,syzComp);
+  if (w!=NULL) delete w;
+  idDelete(&bigmat);
+
+  if(syz_ring!=orig_ring)
+    rChangeCurrRing(orig_ring);
+
+  /* interprete result ----------------------------------------*/
+  result = idInit(IDELEMS(tempstd),maxrk);
+  k = 0;
+  for (j=0;j<IDELEMS(tempstd);j++)
+  {
+    if ((tempstd->m[j]!=NULL) && (p_GetComp(tempstd->m[j],syz_ring)>syzComp))
+    {
+      if (syz_ring==orig_ring)
+        p = pCopy(tempstd->m[j]);
+      else
+        p = prCopyR(tempstd->m[j], syz_ring,currRing);
+      p_Shift(&p,-syzComp-isIdeal,currRing);
+      result->m[k] = p;
+      k++;
+    }
+  }
+  /* clean up ----------------------------------------------------*/
+  if(syz_ring!=orig_ring)
+    rChangeCurrRing(syz_ring);
+  idDelete(&tempstd);
+  if(syz_ring!=orig_ring)
+  {
+    rChangeCurrRing(orig_ring);
+    rDelete(syz_ring);
+  }
+  idSkipZeroes(result);
+  return result;
+}
+
+/*2
+*computes syzygies of h1,
+*if quot != NULL it computes in the quotient ring modulo "quot"
+*works always in a ring with ringorder_s
+*/
+static ideal idPrepare (ideal  h1, tHomog hom, int syzcomp, intvec **w)
+{
+  ideal   h2, h3;
+  int     i;
+  int     j,k;
+  poly    p,q;
+
+  if (idIs0(h1)) return NULL;
+  k = id_RankFreeModule(h1,currRing);
+  h2=idCopy(h1);
+  i = IDELEMS(h2)-1;
+  if (k == 0)
+  {
+    for (j=0; j<=i; j++) p_Shift(&(h2->m[j]),1,currRing);
+    k = 1;
+  }
+  if (syzcomp<k)
+  {
+    Warn("syzcomp too low, should be %d instead of %d",k,syzcomp);
+    syzcomp = k;
+    rSetSyzComp(k,currRing);
+  }
+  h2->rank = syzcomp+i+1;
+
+  //if (hom==testHomog)
+  //{
+  //  if(idHomIdeal(h1,currRing->qideal))
+  //  {
+  //    hom=TRUE;
+  //  }
+  //}
+
+#if MYTEST
+#ifdef RDEBUG
+  Print("Prepare::h2: ");
+  idPrint(h2);
+
+  for(j=0;j<IDELEMS(h2);j++) pTest(h2->m[j]);
+
+#endif
+#endif
+
+  for (j=0; j<=i; j++)
+  {
+    p = h2->m[j];
+    q = pOne();
+    pSetComp(q,syzcomp+1+j);
+    pSetmComp(q);
+    if (p!=NULL)
+    {
+      while (pNext(p)) pIter(p);
+      p->next = q;
+    }
+    else
+      h2->m[j]=q;
+  }
+
+#ifdef PDEBUG
+  for(j=0;j<IDELEMS(h2);j++) pTest(h2->m[j]);
+
+#if MYTEST
+#ifdef RDEBUG
+  Print("Prepare::Input: ");
+  idPrint(h2);
+
+  Print("Prepare::currQuotient: ");
+  idPrint(currRing->qideal);
+#endif
+#endif
+
+#endif
+
+  idTest(h2);
+
+  h3 = kStd(h2,currRing->qideal,hom,w,NULL,syzcomp);
+
+#if MYTEST
+#ifdef RDEBUG
+  Print("Prepare::Output: ");
+  idPrint(h3);
+  for(j=0;j<IDELEMS(h2);j++) pTest(h3->m[j]);
+#endif
+#endif
+
+
+  idDelete(&h2);
+  return h3;
+}
+
+/*2
+* compute the syzygies of h1 in R/quot,
+* weights of components are in w
+* if setRegularity, return the regularity in deg
+* do not change h1,  w
+*/
+ideal idSyzygies (ideal  h1, tHomog h,intvec **w, BOOLEAN setSyzComp,
+                  BOOLEAN setRegularity, int *deg)
+{
+  ideal s_h1;
+  int   j, k, length=0,reg;
+  BOOLEAN isMonomial=TRUE;
+  int ii, idElemens_h1;
+
+  assume(h1 != NULL);
+
+  idElemens_h1=IDELEMS(h1);
+#ifdef PDEBUG
+  for(ii=0;ii<idElemens_h1 /*IDELEMS(h1)*/;ii++) pTest(h1->m[ii]);
+#endif
+  if (idIs0(h1))
+  {
+    ideal result=idFreeModule(idElemens_h1/*IDELEMS(h1)*/);
+    int curr_syz_limit=rGetCurrSyzLimit(currRing);
+    if (curr_syz_limit>0)
+    for (ii=0;ii<idElemens_h1/*IDELEMS(h1)*/;ii++)
+    {
+      if (h1->m[ii]!=NULL)
+        p_Shift(&h1->m[ii],curr_syz_limit,currRing);
+    }
+    return result;
+  }
+  int slength=(int)id_RankFreeModule(h1,currRing);
+  k=si_max(1,slength /*id_RankFreeModule(h1)*/);
+
+  assume(currRing != NULL);
+  ring orig_ring=currRing;
+  ring syz_ring=rAssure_SyzComp(orig_ring,TRUE); rChangeCurrRing(syz_ring);
+
+  if (setSyzComp)
+    rSetSyzComp(k,syz_ring);
+
+  if (orig_ring != syz_ring)
+  {
+    s_h1=idrCopyR_NoSort(h1,orig_ring,syz_ring);
+  }
+  else
+  {
+    s_h1 = h1;
+  }
+
+  idTest(s_h1);
+
+  ideal s_h3=idPrepare(s_h1,h,k,w); // main (syz) GB computation
+
+  if (s_h3==NULL)
+  {
+    return idFreeModule( idElemens_h1 /*IDELEMS(h1)*/);
+  }
+
+  if (orig_ring != syz_ring)
+  {
+    idDelete(&s_h1);
+    for (j=0; j<IDELEMS(s_h3); j++)
+    {
+      if (s_h3->m[j] != NULL)
+      {
+        if (p_MinComp(s_h3->m[j],syz_ring) > k)
+          p_Shift(&s_h3->m[j], -k,syz_ring);
+        else
+          p_Delete(&s_h3->m[j],syz_ring);
+      }
+    }
+    idSkipZeroes(s_h3);
+    s_h3->rank -= k;
+    rChangeCurrRing(orig_ring);
+    s_h3 = idrMoveR_NoSort(s_h3, syz_ring, orig_ring);
+    rDelete(syz_ring);
+    #ifdef HAVE_PLURAL
+    if (rIsPluralRing(orig_ring))
+    {
+      id_DelMultiples(s_h3,orig_ring);
+      idSkipZeroes(s_h3);
+    }
+    #endif
+    idTest(s_h3);
+    return s_h3;
+  }
+
+  ideal e = idInit(IDELEMS(s_h3), s_h3->rank);
+
+  for (j=IDELEMS(s_h3)-1; j>=0; j--)
+  {
+    if (s_h3->m[j] != NULL)
+    {
+      if (p_MinComp(s_h3->m[j],syz_ring) <= k)
+      {
+        e->m[j] = s_h3->m[j];
+        isMonomial=isMonomial && (pNext(s_h3->m[j])==NULL);
+        p_Delete(&pNext(s_h3->m[j]),syz_ring);
+        s_h3->m[j] = NULL;
+      }
+    }
+  }
+
+  idSkipZeroes(s_h3);
+  idSkipZeroes(e);
+
+  if ((deg != NULL)
+  && (!isMonomial)
+  && (!TEST_OPT_NOTREGULARITY)
+  && (setRegularity)
+  && (h==isHomog)
+  && (!rIsPluralRing(currRing))
+  #ifdef HAVE_RINGS
+  && (!rField_is_Ring(currRing))
+  #endif
+  )
+  {
+    ring dp_C_ring = rAssure_dp_C(syz_ring); // will do rChangeCurrRing later
+    if (dp_C_ring != syz_ring)
+    {
+      rChangeCurrRing(dp_C_ring);
+      e = idrMoveR_NoSort(e, syz_ring, dp_C_ring);
+    }
+    resolvente res = sySchreyerResolvente(e,-1,&length,TRUE, TRUE);
+    intvec * dummy = syBetti(res,length,&reg, *w);
+    *deg = reg+2;
+    delete dummy;
+    for (j=0;j<length;j++)
+    {
+      if (res[j]!=NULL) idDelete(&(res[j]));
+    }
+    omFreeSize((ADDRESS)res,length*sizeof(ideal));
+    idDelete(&e);
+    if (dp_C_ring != syz_ring)
+    {
+      rChangeCurrRing(syz_ring);
+      rDelete(dp_C_ring);
+    }
+  }
+  else
+  {
+    idDelete(&e);
+  }
+  idTest(s_h3);
+  if (currRing->qideal != NULL)
+  {
+    ideal ts_h3=kStd(s_h3,currRing->qideal,h,w);
+    idDelete(&s_h3);
+    s_h3 = ts_h3;
+  }
+  return s_h3;
+}
+
+/*2
+*/
+ideal idXXX (ideal  h1, int k)
+{
+  ideal s_h1;
+  intvec *w=NULL;
+
+  assume(currRing != NULL);
+  ring orig_ring=currRing;
+  ring syz_ring=rAssure_SyzComp(orig_ring,TRUE); rChangeCurrRing(syz_ring);
+
+  rSetSyzComp(k,syz_ring);
+
+  if (orig_ring != syz_ring)
+  {
+    s_h1=idrCopyR_NoSort(h1,orig_ring, syz_ring);
+  }
+  else
+  {
+    s_h1 = h1;
+  }
+
+  ideal s_h3=kStd(s_h1,NULL,testHomog,&w,NULL,k);
+
+  if (s_h3==NULL)
+  {
+    return idFreeModule(IDELEMS(h1));
+  }
+
+  if (orig_ring != syz_ring)
+  {
+    idDelete(&s_h1);
+    idSkipZeroes(s_h3);
+    rChangeCurrRing(orig_ring);
+    s_h3 = idrMoveR_NoSort(s_h3, syz_ring, orig_ring);
+    rDelete(syz_ring);
+    idTest(s_h3);
+    return s_h3;
+  }
+
+  idSkipZeroes(s_h3);
+  idTest(s_h3);
+  return s_h3;
+}
+
+/*
+*computes a standard basis for h1 and stores the transformation matrix
+* in ma
+*/
+ideal idLiftStd (ideal  h1, matrix* ma, tHomog hi, ideal * syz)
+{
+  int  i, j, t, inputIsIdeal=id_RankFreeModule(h1,currRing);
+  long k;
+  poly  p=NULL, q;
+  intvec *w=NULL;
+
+  idDelete((ideal*)ma);
+  BOOLEAN lift3=FALSE;
+  if (syz!=NULL) { lift3=TRUE; idDelete(syz); }
+  if (idIs0(h1))
+  {
+    *ma=mpNew(1,0);
+    if (lift3)
+    {
+      *syz=idFreeModule(IDELEMS(h1));
+      int curr_syz_limit=rGetCurrSyzLimit(currRing);
+      if (curr_syz_limit>0)
+      for (int ii=0;ii<IDELEMS(h1);ii++)
+      {
+        if (h1->m[ii]!=NULL)
+          p_Shift(&h1->m[ii],curr_syz_limit,currRing);
+      }
+    }
+    return idInit(1,h1->rank);
+  }
+
+  BITSET save2;
+  SI_SAVE_OPT2(save2);
+
+  k=si_max((long)1,id_RankFreeModule(h1,currRing));
+
+  if ((k==1) && (!lift3)) si_opt_2 |=Sy_bit(V_IDLIFT);
+
+  ring orig_ring = currRing;
+  ring syz_ring = rAssure_SyzComp(orig_ring,TRUE);  rChangeCurrRing(syz_ring);
+  rSetSyzComp(k,syz_ring);
+
+  ideal s_h1=h1;
+
+  if (orig_ring != syz_ring)
+    s_h1 = idrCopyR_NoSort(h1,orig_ring,syz_ring);
+  else
+    s_h1 = h1;
+
+  ideal s_h3=idPrepare(s_h1,hi,k,&w); // main (syz) GB computation
+
+  ideal s_h2 = idInit(IDELEMS(s_h3), s_h3->rank);
+
+  if (lift3) (*syz)=idInit(IDELEMS(s_h3),IDELEMS(h1));
+
+  if (w!=NULL) delete w;
+  i = 0;
+
+  // now sort the result, SB : leave in s_h3
+  //                      T:  put in s_h2
+  //                      syz: put in *syz
+  for (j=0; j<IDELEMS(s_h3); j++)
+  {
+    if (s_h3->m[j] != NULL)
+    {
+      //if (p_MinComp(s_h3->m[j],syz_ring) <= k)
+      if (pGetComp(s_h3->m[j]) <= k) // syz_ring == currRing
+      {
+        i++;
+        q = s_h3->m[j];
+        while (pNext(q) != NULL)
+        {
+          if (pGetComp(pNext(q)) > k)
+          {
+            s_h2->m[j] = pNext(q);
+            pNext(q) = NULL;
+          }
+          else
+          {
+            pIter(q);
+          }
+        }
+        if (!inputIsIdeal) p_Shift(&(s_h3->m[j]), -1,currRing);
+      }
+      else
+      {
+        // we a syzygy here:
+        if (lift3)
+        {
+          p_Shift(&s_h3->m[j], -k,currRing);
+          (*syz)->m[j]=s_h3->m[j];
+          s_h3->m[j]=NULL;
+        }
+        else
+          p_Delete(&(s_h3->m[j]),currRing);
+      }
+    }
+  }
+  idSkipZeroes(s_h3);
+  //extern char * iiStringMatrix(matrix im, int dim,char ch);
+  //PrintS("SB: ----------------------------------------\n");
+  //PrintS(iiStringMatrix((matrix)s_h3,k,'\n'));
+  //PrintLn();
+  //PrintS("T: ----------------------------------------\n");
+  //PrintS(iiStringMatrix((matrix)s_h2,h1->rank,'\n'));
+  //PrintLn();
+
+  if (lift3) idSkipZeroes(*syz);
+
+  j = IDELEMS(s_h1);
+
+
+  if (syz_ring!=orig_ring)
+  {
+    idDelete(&s_h1);
+    rChangeCurrRing(orig_ring);
+  }
+
+  *ma = mpNew(j,i);
+
+  i = 1;
+  for (j=0; j<IDELEMS(s_h2); j++)
+  {
+    if (s_h2->m[j] != NULL)
+    {
+      q = prMoveR( s_h2->m[j], syz_ring,orig_ring);
+      s_h2->m[j] = NULL;
+
+      while (q != NULL)
+      {
+        p = q;
+        pIter(q);
+        pNext(p) = NULL;
+        t=pGetComp(p);
+        pSetComp(p,0);
+        pSetmComp(p);
+        MATELEM(*ma,t-k,i) = pAdd(MATELEM(*ma,t-k,i),p);
+      }
+      i++;
+    }
+  }
+  idDelete(&s_h2);
+
+  for (i=0; i<IDELEMS(s_h3); i++)
+  {
+    s_h3->m[i] = prMoveR_NoSort(s_h3->m[i], syz_ring,orig_ring);
+  }
+  if (lift3)
+  {
+    for (i=0; i<IDELEMS(*syz); i++)
+    {
+      (*syz)->m[i] = prMoveR_NoSort((*syz)->m[i], syz_ring,orig_ring);
+    }
+  }
+
+  if (syz_ring!=orig_ring) rDelete(syz_ring);
+  SI_RESTORE_OPT2(save2);
+  return s_h3;
+}
+
+static void idPrepareStd(ideal s_temp, int k)
+{
+  int j,rk=id_RankFreeModule(s_temp,currRing);
+  poly p,q;
+
+  if (rk == 0)
+  {
+    for (j=0; j<IDELEMS(s_temp); j++)
+    {
+      if (s_temp->m[j]!=NULL) pSetCompP(s_temp->m[j],1);
+    }
+    k = si_max(k,1);
+  }
+  for (j=0; j<IDELEMS(s_temp); j++)
+  {
+    if (s_temp->m[j]!=NULL)
+    {
+      p = s_temp->m[j];
+      q = pOne();
+      //pGetCoeff(q)=nInpNeg(pGetCoeff(q));   //set q to -1
+      pSetComp(q,k+1+j);
+      pSetmComp(q);
+      while (pNext(p)) pIter(p);
+      pNext(p) = q;
+    }
+  }
+}
+
+/*2
+*computes a representation of the generators of submod with respect to those
+* of mod
+*/
+
+ideal idLift(ideal mod, ideal submod,ideal *rest, BOOLEAN goodShape,
+             BOOLEAN isSB, BOOLEAN divide, matrix *unit)
+{
+  int lsmod =id_RankFreeModule(submod,currRing), j, k;
+  int comps_to_add=0;
+  poly p;
+
+  if (idIs0(submod))
+  {
+    if (unit!=NULL)
+    {
+      *unit=mpNew(1,1);
+      MATELEM(*unit,1,1)=pOne();
+    }
+    if (rest!=NULL)
+    {
+      *rest=idInit(1,mod->rank);
+    }
+    return idInit(1,mod->rank);
+  }
+  if (idIs0(mod)) /* and not idIs0(submod) */
+  {
+    WerrorS("2nd module does not lie in the first");
+    return NULL;
+  }
+  if (unit!=NULL)
+  {
+    comps_to_add = IDELEMS(submod);
+    while ((comps_to_add>0) && (submod->m[comps_to_add-1]==NULL))
+      comps_to_add--;
+  }
+  k=si_max(id_RankFreeModule(mod,currRing),id_RankFreeModule(submod,currRing));
+  if  ((k!=0) && (lsmod==0)) lsmod=1;
+  k=si_max(k,(int)mod->rank);
+  if (k<submod->rank) { WarnS("rk(submod) > rk(mod) ?");k=submod->rank; }
+
+  ring orig_ring=currRing;
+  ring syz_ring=rAssure_SyzComp(orig_ring,TRUE);  rChangeCurrRing(syz_ring);
+  rSetSyzComp(k,syz_ring);
+
+  ideal s_mod, s_temp;
+  if (orig_ring != syz_ring)
+  {
+    s_mod = idrCopyR_NoSort(mod,orig_ring,syz_ring);
+    s_temp = idrCopyR_NoSort(submod,orig_ring,syz_ring);
+  }
+  else
+  {
+    s_mod = mod;
+    s_temp = idCopy(submod);
+  }
+  ideal s_h3;
+  if (isSB)
+  {
+    s_h3 = idCopy(s_mod);
+    idPrepareStd(s_h3, k+comps_to_add);
+  }
+  else
+  {
+    s_h3 = idPrepare(s_mod,(tHomog)FALSE,k+comps_to_add,NULL);
+  }
+  if (!goodShape)
+  {
+    for (j=0;j<IDELEMS(s_h3);j++)
+    {
+      if ((s_h3->m[j] != NULL) && (pMinComp(s_h3->m[j]) > k))
+        p_Delete(&(s_h3->m[j]),currRing);
+    }
+  }
+  idSkipZeroes(s_h3);
+  if (lsmod==0)
+  {
+    for (j=IDELEMS(s_temp);j>0;j--)
+    {
+      if (s_temp->m[j-1]!=NULL)
+        p_Shift(&(s_temp->m[j-1]),1,currRing);
+    }
+  }
+  if (unit!=NULL)
+  {
+    for(j = 0;j<comps_to_add;j++)
+    {
+      p = s_temp->m[j];
+      if (p!=NULL)
+      {
+        while (pNext(p)!=NULL) pIter(p);
+        pNext(p) = pOne();
+        pIter(p);
+        pSetComp(p,1+j+k);
+        pSetmComp(p);
+        p = pNeg(p);
+      }
+    }
+  }
+  ideal s_result = kNF(s_h3,currRing->qideal,s_temp,k);
+  s_result->rank = s_h3->rank;
+  ideal s_rest = idInit(IDELEMS(s_result),k);
+  idDelete(&s_h3);
+  idDelete(&s_temp);
+
+  for (j=0;j<IDELEMS(s_result);j++)
+  {
+    if (s_result->m[j]!=NULL)
+    {
+      if (pGetComp(s_result->m[j])<=k)
+      {
+        if (!divide)
+        {
+          if (isSB)
+          {
+            WarnS("first module not a standardbasis\n"
+              "// ** or second not a proper submodule");
+          }
+          else
+            WerrorS("2nd module does not lie in the first");
+          idDelete(&s_result);
+          idDelete(&s_rest);
+          s_result=idInit(IDELEMS(submod),submod->rank);
+          break;
+        }
+        else
+        {
+          p = s_rest->m[j] = s_result->m[j];
+          while ((pNext(p)!=NULL) && (pGetComp(pNext(p))<=k)) pIter(p);
+          s_result->m[j] = pNext(p);
+          pNext(p) = NULL;
+        }
+      }
+      p_Shift(&(s_result->m[j]),-k,currRing);
+      pNeg(s_result->m[j]);
+    }
+  }
+  if ((lsmod==0) && (!idIs0(s_rest)))
+  {
+    for (j=IDELEMS(s_rest);j>0;j--)
+    {
+      if (s_rest->m[j-1]!=NULL)
+      {
+        p_Shift(&(s_rest->m[j-1]),-1,currRing);
+        s_rest->m[j-1] = s_rest->m[j-1];
+      }
+    }
+  }
+  if(syz_ring!=orig_ring)
+  {
+    idDelete(&s_mod);
+    rChangeCurrRing(orig_ring);
+    s_result = idrMoveR_NoSort(s_result, syz_ring, orig_ring);
+    s_rest = idrMoveR_NoSort(s_rest, syz_ring, orig_ring);
+    rDelete(syz_ring);
+  }
+  if (rest!=NULL)
+    *rest = s_rest;
+  else
+    idDelete(&s_rest);
+//idPrint(s_result);
+  if (unit!=NULL)
+  {
+    *unit=mpNew(comps_to_add,comps_to_add);
+    int i;
+    for(i=0;i<IDELEMS(s_result);i++)
+    {
+      poly p=s_result->m[i];
+      poly q=NULL;
+      while(p!=NULL)
+      {
+        if(pGetComp(p)<=comps_to_add)
+        {
+          pSetComp(p,0);
+          if (q!=NULL)
+          {
+            pNext(q)=pNext(p);
+          }
+          else
+          {
+            pIter(s_result->m[i]);
+          }
+          pNext(p)=NULL;
+          MATELEM(*unit,i+1,i+1)=pAdd(MATELEM(*unit,i+1,i+1),p);
+          if(q!=NULL)   p=pNext(q);
+          else          p=s_result->m[i];
+        }
+        else
+        {
+          q=p;
+          pIter(p);
+        }
+      }
+      p_Shift(&s_result->m[i],-comps_to_add,currRing);
+    }
+  }
+  return s_result;
+}
+
+/*2
+*computes division of P by Q with remainder up to (w-weighted) degree n
+*P, Q, and w are not changed
+*/
+void idLiftW(ideal P,ideal Q,int n,matrix &T, ideal &R,short *w)
+{
+  long N=0;
+  int i;
+  for(i=IDELEMS(Q)-1;i>=0;i--)
+    if(w==NULL)
+      N=si_max(N,p_Deg(Q->m[i],currRing));
+    else
+      N=si_max(N,p_DegW(Q->m[i],w,currRing));
+  N+=n;
+
+  T=mpNew(IDELEMS(Q),IDELEMS(P));
+  R=idInit(IDELEMS(P),P->rank);
+
+  for(i=IDELEMS(P)-1;i>=0;i--)
+  {
+    poly p;
+    if(w==NULL)
+      p=ppJet(P->m[i],N);
+    else
+      p=ppJetW(P->m[i],N,w);
+
+    int j=IDELEMS(Q)-1;
+    while(p!=NULL)
+    {
+      if(pDivisibleBy(Q->m[j],p))
+      {
+        poly p0=p_DivideM(pHead(p),pHead(Q->m[j]),currRing);
+        if(w==NULL)
+          p=pJet(pSub(p,ppMult_mm(Q->m[j],p0)),N);
+        else
+          p=pJetW(pSub(p,ppMult_mm(Q->m[j],p0)),N,w);
+        pNormalize(p);
+        if(((w==NULL)&&(p_Deg(p0,currRing)>n))||((w!=NULL)&&(p_DegW(p0,w,currRing)>n)))
+          p_Delete(&p0,currRing);
+        else
+          MATELEM(T,j+1,i+1)=pAdd(MATELEM(T,j+1,i+1),p0);
+        j=IDELEMS(Q)-1;
+      }
+      else
+      {
+        if(j==0)
+        {
+          poly p0=p;
+          pIter(p);
+          pNext(p0)=NULL;
+          if(((w==NULL)&&(p_Deg(p0,currRing)>n))
+          ||((w!=NULL)&&(p_DegW(p0,w,currRing)>n)))
+            p_Delete(&p0,currRing);
+          else
+            R->m[i]=pAdd(R->m[i],p0);
+          j=IDELEMS(Q)-1;
+        }
+        else
+          j--;
+      }
+    }
+  }
+}
+
+/*2
+*computes the quotient of h1,h2 : internal routine for idQuot
+*BEWARE: the returned ideals may contain incorrectly ordered polys !
+*
+*/
+static ideal idInitializeQuot (ideal  h1, ideal h2, BOOLEAN h1IsStb, BOOLEAN *addOnlyOne, int *kkmax)
+{
+  idTest(h1);
+  idTest(h2);
+
+  ideal temph1;
+  poly     p,q = NULL;
+  int i,l,ll,k,kkk,kmax;
+  int j = 0;
+  int k1 = id_RankFreeModule(h1,currRing);
+  int k2 = id_RankFreeModule(h2,currRing);
+  tHomog   hom=isNotHomog;
+  k=si_max(k1,k2);
+  if (k==0)
+    k = 1;
+  if ((k2==0) && (k>1)) *addOnlyOne = FALSE;
+  intvec * weights;
+  hom = (tHomog)idHomModule(h1,currRing->qideal,&weights);
+  if /**addOnlyOne &&*/ (/*(*/ !h1IsStb /*)*/)
+    temph1 = kStd(h1,currRing->qideal,hom,&weights,NULL);
+  else
+    temph1 = idCopy(h1);
+  if (weights!=NULL) delete weights;
+  idTest(temph1);
+/*--- making a single vector from h2 ---------------------*/
+  for (i=0; i<IDELEMS(h2); i++)
+  {
+    if (h2->m[i] != NULL)
+    {
+      p = pCopy(h2->m[i]);
+      if (k2 == 0)
+        p_Shift(&p,j*k+1,currRing);
+      else
+        p_Shift(&p,j*k,currRing);
+      q = pAdd(q,p);
+      j++;
+    }
+  }
+  *kkmax = kmax = j*k+1;
+/*--- adding a monomial for the result (syzygy) ----------*/
+  p = q;
+  while (pNext(p)!=NULL) pIter(p);
+  pNext(p) = pOne();
+  pIter(p);
+  pSetComp(p,kmax);
+  pSetmComp(p);
+/*--- constructing the big matrix ------------------------*/
+  ideal h4 = idInit(16,kmax+k-1);
+  h4->m[0] = q;
+  if (k2 == 0)
+  {
+    if (k > IDELEMS(h4))
+    {
+      pEnlargeSet(&(h4->m),IDELEMS(h4),k-IDELEMS(h4));
+      IDELEMS(h4) = k;
+    }
+    for (i=1; i<k; i++)
+    {
+      if (h4->m[i-1]!=NULL)
+      {
+        p = p_Copy_noCheck(h4->m[i-1], currRing); p_Shift(&p,1,currRing);
+	// pTest(p);
+        h4->m[i] = p;
+      }
+    }
+  }
+  idSkipZeroes(h4);
+  kkk = IDELEMS(h4);
+  i = IDELEMS(temph1);
+  for (l=0; l<i; l++)
+  {
+    if(temph1->m[l]!=NULL)
+    {
+      for (ll=0; ll<j; ll++)
+      {
+        p = pCopy(temph1->m[l]);
+        if (k1 == 0)
+          p_Shift(&p,ll*k+1,currRing);
+        else
+          p_Shift(&p,ll*k,currRing);
+        if (kkk >= IDELEMS(h4))
+        {
+          pEnlargeSet(&(h4->m),IDELEMS(h4),16);
+          IDELEMS(h4) += 16;
+        }
+        h4->m[kkk] = p;
+        kkk++;
+      }
+    }
+  }
+/*--- if h2 goes in as single vector - the h1-part is just SB ---*/
+  if (*addOnlyOne)
+  {
+    idSkipZeroes(h4);
+    p = h4->m[0];
+    for (i=0;i<IDELEMS(h4)-1;i++)
+    {
+      h4->m[i] = h4->m[i+1];
+    }
+    h4->m[IDELEMS(h4)-1] = p;
+    #ifdef HAVE_RINGS
+    if(!rField_is_Ring(currRing))
+    #endif
+    si_opt_1 |= Sy_bit(OPT_SB_1);
+  }
+  idDelete(&temph1);
+  //idTest(h4);//see remark at the beginning
+  return h4;
+}
+/*2
+*computes the quotient of h1,h2
+*/
+ideal idQuot (ideal  h1, ideal h2, BOOLEAN h1IsStb, BOOLEAN resultIsIdeal)
+{
+  // first check for special case h1:(0)
+  if (idIs0(h2))
+  {
+    ideal res;
+    if (resultIsIdeal)
+    {
+      res = idInit(1,1);
+      res->m[0] = pOne();
+    }
+    else
+      res = idFreeModule(h1->rank);
+    return res;
+  }
+  BITSET old_test1;
+  SI_SAVE_OPT1(old_test1);
+  int i, kmax;
+  BOOLEAN  addOnlyOne=TRUE;
+  tHomog   hom=isNotHomog;
+  intvec * weights1;
+
+  ideal s_h4 = idInitializeQuot (h1,h2,h1IsStb,&addOnlyOne,&kmax);
+
+  hom = (tHomog)idHomModule(s_h4,currRing->qideal,&weights1);
+
+  ring orig_ring=currRing;
+  ring syz_ring=rAssure_SyzComp(orig_ring,TRUE);  rChangeCurrRing(syz_ring);
+  rSetSyzComp(kmax-1,syz_ring);
+  if (orig_ring!=syz_ring)
+  //  s_h4 = idrMoveR_NoSort(s_h4,orig_ring, syz_ring);
+    s_h4 = idrMoveR(s_h4,orig_ring, syz_ring);
+  idTest(s_h4);
+  #if 0
+  void ipPrint_MA0(matrix m, const char *name);
+  matrix m=idModule2Matrix(idCopy(s_h4));
+  PrintS("start:\n");
+  ipPrint_MA0(m,"Q");
+  idDelete((ideal *)&m);
+  PrintS("last elem:");wrp(s_h4->m[IDELEMS(s_h4)-1]);PrintLn();
+  #endif
+  ideal s_h3;
+  if (addOnlyOne)
+  {
+    s_h3 = kStd(s_h4,currRing->qideal,hom,&weights1,NULL,0/*kmax-1*/,IDELEMS(s_h4)-1);
+  }
+  else
+  {
+    s_h3 = kStd(s_h4,currRing->qideal,hom,&weights1,NULL,kmax-1);
+  }
+  SI_RESTORE_OPT1(old_test1);
+  #if 0
+  // only together with the above debug stuff
+  idSkipZeroes(s_h3);
+  m=idModule2Matrix(idCopy(s_h3));
+  Print("result, kmax=%d:\n",kmax);
+  ipPrint_MA0(m,"S");
+  idDelete((ideal *)&m);
+  #endif
+  idTest(s_h3);
+  if (weights1!=NULL) delete weights1;
+  idDelete(&s_h4);
+
+  for (i=0;i<IDELEMS(s_h3);i++)
+  {
+    if ((s_h3->m[i]!=NULL) && (pGetComp(s_h3->m[i])>=kmax))
+    {
+      if (resultIsIdeal)
+        p_Shift(&s_h3->m[i],-kmax,currRing);
+      else
+        p_Shift(&s_h3->m[i],-kmax+1,currRing);
+    }
+    else
+      p_Delete(&s_h3->m[i],currRing);
+  }
+  if (resultIsIdeal)
+    s_h3->rank = 1;
+  else
+    s_h3->rank = h1->rank;
+  if(syz_ring!=orig_ring)
+  {
+    rChangeCurrRing(orig_ring);
+    s_h3 = idrMoveR_NoSort(s_h3, syz_ring, orig_ring);
+    rDelete(syz_ring);
+  }
+  idSkipZeroes(s_h3);
+  idTest(s_h3);
+  return s_h3;
+}
+
+/*2
+* eliminate delVar (product of vars) in h1
+*/
+ideal idElimination (ideal h1,poly delVar,intvec *hilb)
+{
+  int    i,j=0,k,l;
+  ideal  h,hh, h3;
+  int    *ord,*block0,*block1;
+  int    ordersize=2;
+  int    **wv;
+  tHomog hom;
+  intvec * w;
+  ring tmpR;
+  ring origR = currRing;
+
+  if (delVar==NULL)
+  {
+    return idCopy(h1);
+  }
+  if ((currRing->qideal!=NULL) && rIsPluralRing(origR))
+  {
+    WerrorS("cannot eliminate in a qring");
+    return NULL;
+  }
+  if (idIs0(h1)) return idInit(1,h1->rank);
+#ifdef HAVE_PLURAL
+  if (rIsPluralRing(origR))
+    /* in the NC case, we have to check the admissibility of */
+    /* the subalgebra to be intersected with */
+  {
+    if ((ncRingType(origR) != nc_skew) && (ncRingType(origR) != nc_exterior)) /* in (quasi)-commutative algebras every subalgebra is admissible */
+    {
+      if (nc_CheckSubalgebra(delVar,origR))
+      {
+        WerrorS("no elimination is possible: subalgebra is not admissible");
+        return NULL;
+      }
+    }
+  }
+#endif
+  hom=(tHomog)idHomModule(h1,NULL,&w); //sets w to weight vector or NULL
+  h3=idInit(16,h1->rank);
+  for (k=0;; k++)
+  {
+    if (origR->order[k]!=0) ordersize++;
+    else break;
+  }
+#if 0
+  if (rIsPluralRing(origR)) // we have too keep the odering: it may be needed
+                            // for G-algebra
+  {
+    for (k=0;k<ordersize-1; k++)
+    {
+      block0[k+1] = origR->block0[k];
+      block1[k+1] = origR->block1[k];
+      ord[k+1] = origR->order[k];
+      if (origR->wvhdl[k]!=NULL) wv[k+1] = (int*) omMemDup(origR->wvhdl[k]);
+    }
+  }
+  else
+  {
+    block0[1] = 1;
+    block1[1] = (currRing->N);
+    if (origR->OrdSgn==1) ord[1] = ringorder_wp;
+    else                  ord[1] = ringorder_ws;
+    wv[1]=(int*)omAlloc0((currRing->N)*sizeof(int));
+    double wNsqr = (double)2.0 / (double)(currRing->N);
+    wFunctional = wFunctionalBuch;
+    int  *x= (int * )omAlloc(2 * ((currRing->N) + 1) * sizeof(int));
+    int sl=IDELEMS(h1) - 1;
+    wCall(h1->m, sl, x, wNsqr);
+    for (sl = (currRing->N); sl!=0; sl--)
+      wv[1][sl-1] = x[sl + (currRing->N) + 1];
+    omFreeSize((ADDRESS)x, 2 * ((currRing->N) + 1) * sizeof(int));
+
+    ord[2]=ringorder_C;
+    ord[3]=0;
+  }
+#else
+#endif
+  if ((hom==TRUE) && (origR->OrdSgn==1) && (!rIsPluralRing(origR)))
+  {
+    #if 1
+    // we change to an ordering:
+    // aa(1,1,1,...,0,0,0),wp(...),C
+    // this seems to be better than version 2 below,
+    // according to Tst/../elimiate_[3568].tat (- 17 %)
+    ord=(int*)omAlloc0(4*sizeof(int));
+    block0=(int*)omAlloc0(4*sizeof(int));
+    block1=(int*)omAlloc0(4*sizeof(int));
+    wv=(int**) omAlloc0(4*sizeof(int**));
+    block0[0] = block0[1] = 1;
+    block1[0] = block1[1] = rVar(origR);
+    wv[0]=(int*)omAlloc0((rVar(origR) + 1)*sizeof(int));
+    // use this special ordering: like ringorder_a, except that pFDeg, pWeights
+    // ignore it
+    ord[0] = ringorder_aa;
+    for (j=0;j<rVar(origR);j++)
+      if (pGetExp(delVar,j+1)!=0) wv[0][j]=1;
+    BOOLEAN wp=FALSE;
+    for (j=0;j<rVar(origR);j++)
+      if (pWeight(j+1,origR)!=1) { wp=TRUE;break; }
+    if (wp)
+    {
+      wv[1]=(int*)omAlloc0((rVar(origR) + 1)*sizeof(int));
+      for (j=0;j<rVar(origR);j++)
+        wv[1][j]=pWeight(j+1,origR);
+      ord[1] = ringorder_wp;
+    }
+    else
+      ord[1] = ringorder_dp;
+    #else
+    // we change to an ordering:
+    // a(w1,...wn),wp(1,...0.....),C
+    ord=(int*)omAlloc0(4*sizeof(int));
+    block0=(int*)omAlloc0(4*sizeof(int));
+    block1=(int*)omAlloc0(4*sizeof(int));
+    wv=(int**) omAlloc0(4*sizeof(int**));
+    block0[0] = block0[1] = 1;
+    block1[0] = block1[1] = rVar(origR);
+    wv[0]=(int*)omAlloc0((rVar(origR) + 1)*sizeof(int));
+    wv[1]=(int*)omAlloc0((rVar(origR) + 1)*sizeof(int));
+    ord[0] = ringorder_a;
+    for (j=0;j<rVar(origR);j++)
+      wv[0][j]=pWeight(j+1,origR);
+    ord[1] = ringorder_wp;
+    for (j=0;j<rVar(origR);j++)
+      if (pGetExp(delVar,j+1)!=0) wv[1][j]=1;
+    #endif
+    ord[2] = ringorder_C;
+    ord[3] = 0;
+  }
+  else
+  {
+    // we change to an ordering:
+    // aa(....),orig_ordering
+    ord=(int*)omAlloc0(ordersize*sizeof(int));
+    block0=(int*)omAlloc0(ordersize*sizeof(int));
+    block1=(int*)omAlloc0(ordersize*sizeof(int));
+    wv=(int**) omAlloc0(ordersize*sizeof(int**));
+    for (k=0;k<ordersize-1; k++)
+    {
+      block0[k+1] = origR->block0[k];
+      block1[k+1] = origR->block1[k];
+      ord[k+1] = origR->order[k];
+      if (origR->wvhdl[k]!=NULL) wv[k+1] = (int*) omMemDup(origR->wvhdl[k]);
+    }
+    block0[0] = 1;
+    block1[0] = rVar(origR);
+    wv[0]=(int*)omAlloc0((rVar(origR) + 1)*sizeof(int));
+    for (j=0;j<rVar(origR);j++)
+      if (pGetExp(delVar,j+1)!=0) wv[0][j]=1;
+    // use this special ordering: like ringorder_a, except that pFDeg, pWeights
+    // ignore it
+    ord[0] = ringorder_aa;
+  }
+  // fill in tmp ring to get back the data later on
+  tmpR  = rCopy0(origR,FALSE,FALSE); // qring==NULL
+  //rUnComplete(tmpR);
+  tmpR->p_Procs=NULL;
+  tmpR->order = ord;
+  tmpR->block0 = block0;
+  tmpR->block1 = block1;
+  tmpR->wvhdl = wv;
+  rComplete(tmpR, 1);
+
+#ifdef HAVE_PLURAL
+  /* update nc structure on tmpR */
+  if (rIsPluralRing(origR))
+  {
+    if ( nc_rComplete(origR, tmpR, false) ) // no quotient ideal!
+    {
+      Werror("no elimination is possible: ordering condition is violated");
+      // cleanup
+      rDelete(tmpR);
+      if (w!=NULL)
+        delete w;
+      return NULL;
+    }
+  }
+#endif
+  // change into the new ring
+  //pChangeRing((currRing->N),currRing->OrdSgn,ord,block0,block1,wv);
+  rChangeCurrRing(tmpR);
+
+  //h = idInit(IDELEMS(h1),h1->rank);
+  // fetch data from the old ring
+  //for (k=0;k<IDELEMS(h1);k++) h->m[k] = prCopyR( h1->m[k], origR);
+  h=idrCopyR(h1,origR,currRing);
+  if (origR->qideal!=NULL)
+  {
+    WarnS("eliminate in q-ring: experimental");
+    ideal q=idrCopyR(origR->qideal,origR,currRing);
+    ideal s=idSimpleAdd(h,q);
+    idDelete(&h);
+    idDelete(&q);
+    h=s;
+  }
+  // compute kStd
+#if 1
+  //rWrite(tmpR);PrintLn();
+  //BITSET save1;
+  //SI_SAVE_OPT1(save1);
+  //si_opt_1 |=1;
+  //Print("h: %d gen, rk=%d\n",IDELEMS(h),h->rank);
+  //extern char * showOption();
+  //Print("%s\n",showOption());
+  hh = kStd(h,NULL,hom,&w,hilb);
+  //SI_RESTORE_OPT1(save1);
+  idDelete(&h);
+#else
+  extern ideal kGroebner(ideal F, ideal Q);
+  hh=kGroebner(h,NULL);
+#endif
+  // go back to the original ring
+  rChangeCurrRing(origR);
+  i = IDELEMS(hh)-1;
+  while ((i >= 0) && (hh->m[i] == NULL)) i--;
+  j = -1;
+  // fetch data from temp ring
+  for (k=0; k<=i; k++)
+  {
+    l=(currRing->N);
+    while ((l>0) && (p_GetExp( hh->m[k],l,tmpR)*pGetExp(delVar,l)==0)) l--;
+    if (l==0)
+    {
+      j++;
+      if (j >= IDELEMS(h3))
+      {
+        pEnlargeSet(&(h3->m),IDELEMS(h3),16);
+        IDELEMS(h3) += 16;
+      }
+      h3->m[j] = prMoveR( hh->m[k], tmpR,origR);
+      hh->m[k] = NULL;
+    }
+  }
+  id_Delete(&hh, tmpR);
+  idSkipZeroes(h3);
+  rDelete(tmpR);
+  if (w!=NULL)
+    delete w;
+  return h3;
+}
+
+#ifdef WITH_OLD_MINOR
+/*2
+* compute the which-th ar-minor of the matrix a
+*/
+poly idMinor(matrix a, int ar, unsigned long which, ideal R)
+{
+  int     i,j/*,k,size*/;
+  unsigned long curr;
+  int *rowchoise,*colchoise;
+  BOOLEAN rowch,colch;
+  // ideal result;
+  matrix tmp;
+  poly p,q;
+
+  i = binom(a->rows(),ar);
+  j = binom(a->cols(),ar);
+
+  rowchoise=(int *)omAlloc(ar*sizeof(int));
+  colchoise=(int *)omAlloc(ar*sizeof(int));
+  // if ((i>512) || (j>512) || (i*j >512)) size=512;
+  // else size=i*j;
+  // result=idInit(size,1);
+  tmp=mpNew(ar,ar);
+  // k = 0; /* the index in result*/
+  curr = 0; /* index of current minor */
+  idInitChoise(ar,1,a->rows(),&rowch,rowchoise);
+  while (!rowch)
+  {
+    idInitChoise(ar,1,a->cols(),&colch,colchoise);
+    while (!colch)
+    {
+      if (curr == which)
+      {
+        for (i=1; i<=ar; i++)
+        {
+          for (j=1; j<=ar; j++)
+          {
+            MATELEM(tmp,i,j) = MATELEM(a,rowchoise[i-1],colchoise[j-1]);
+          }
+        }
+        p = mp_DetBareiss(tmp,currRing);
+        if (p!=NULL)
+        {
+          if (R!=NULL)
+          {
+            q = p;
+            p = kNF(R,currRing->qideal,q);
+            p_Delete(&q,currRing);
+          }
+          /*delete the matrix tmp*/
+          for (i=1; i<=ar; i++)
+          {
+            for (j=1; j<=ar; j++) MATELEM(tmp,i,j) = NULL;
+          }
+          idDelete((ideal*)&tmp);
+          omFreeSize((ADDRESS)rowchoise,ar*sizeof(int));
+          omFreeSize((ADDRESS)colchoise,ar*sizeof(int));
+          return (p);
+        }
+      }
+      curr++;
+      idGetNextChoise(ar,a->cols(),&colch,colchoise);
+    }
+    idGetNextChoise(ar,a->rows(),&rowch,rowchoise);
+  }
+  return (poly) 1;
+}
+
+/*2
+* compute all ar-minors of the matrix a
+*/
+ideal idMinors(matrix a, int ar, ideal R)
+{
+  int     i,j,/*k,*/size;
+  int *rowchoise,*colchoise;
+  BOOLEAN rowch,colch;
+  ideal result;
+  matrix tmp;
+  poly p,q;
+
+  i = binom(a->rows(),ar);
+  j = binom(a->cols(),ar);
+
+  rowchoise=(int *)omAlloc(ar*sizeof(int));
+  colchoise=(int *)omAlloc(ar*sizeof(int));
+  if ((i>512) || (j>512) || (i*j >512)) size=512;
+  else size=i*j;
+  result=idInit(size,1);
+  tmp=mpNew(ar,ar);
+  // k = 0; /* the index in result*/
+  idInitChoise(ar,1,a->rows(),&rowch,rowchoise);
+  while (!rowch)
+  {
+    idInitChoise(ar,1,a->cols(),&colch,colchoise);
+    while (!colch)
+    {
+      for (i=1; i<=ar; i++)
+      {
+        for (j=1; j<=ar; j++)
+        {
+          MATELEM(tmp,i,j) = MATELEM(a,rowchoise[i-1],colchoise[j-1]);
+        }
+      }
+      p = mp_DetBareiss(tmp,vcurrRing);
+      if (p!=NULL)
+      {
+        if (R!=NULL)
+        {
+          q = p;
+          p = kNF(R,currRing->qideal,q);
+          p_Delete(&q,currRing);
+        }
+        if (p!=NULL)
+        {
+          if (k>=size)
+          {
+            pEnlargeSet(&result->m,size,32);
+            size += 32;
+          }
+          result->m[k] = p;
+          k++;
+        }
+      }
+      idGetNextChoise(ar,a->cols(),&colch,colchoise);
+    }
+    idGetNextChoise(ar,a->rows(),&rowch,rowchoise);
+  }
+  /*delete the matrix tmp*/
+  for (i=1; i<=ar; i++)
+  {
+    for (j=1; j<=ar; j++) MATELEM(tmp,i,j) = NULL;
+  }
+  idDelete((ideal*)&tmp);
+  if (k==0)
+  {
+    k=1;
+    result->m[0]=NULL;
+  }
+  omFreeSize((ADDRESS)rowchoise,ar*sizeof(int));
+  omFreeSize((ADDRESS)colchoise,ar*sizeof(int));
+  pEnlargeSet(&result->m,size,k-size);
+  IDELEMS(result) = k;
+  return (result);
+}
+#else
+/*2
+* compute all ar-minors of the matrix a
+* the caller of mpRecMin
+* the elements of the result are not in R (if R!=NULL)
+*/
+ideal idMinors(matrix a, int ar, ideal R)
+{
+  int elems=0;
+  int r=a->nrows,c=a->ncols;
+  int i;
+  matrix b;
+  ideal result,h;
+  ring origR=currRing;
+  ring tmpR;
+  long bound;
+
+  if((ar<=0) || (ar>r) || (ar>c))
+  {
+    Werror("%d-th minor, matrix is %dx%d",ar,r,c);
+    return NULL;
+  }
+  h = id_Matrix2Module(mp_Copy(a,origR),origR);
+  bound = sm_ExpBound(h,c,r,ar,origR);
+  idDelete(&h);
+  tmpR=sm_RingChange(origR,bound);
+  b = mpNew(r,c);
+  for (i=r*c-1;i>=0;i--)
+  {
+    if (a->m[i])
+      b->m[i] = prCopyR(a->m[i],origR,tmpR);
+  }
+  if (R!=NULL)
+  {
+    R = idrCopyR(R,origR,tmpR);
+    //if (ar>1) // otherwise done in mpMinorToResult
+    //{
+    //  matrix bb=(matrix)kNF(R,currRing->qideal,(ideal)b);
+    //  bb->rank=b->rank; bb->nrows=b->nrows; bb->ncols=b->ncols;
+    //  idDelete((ideal*)&b); b=bb;
+    //}
+  }
+  result=idInit(32,1);
+  if(ar>1) mp_RecMin(ar-1,result,elems,b,r,c,NULL,R,tmpR);
+  else mp_MinorToResult(result,elems,b,r,c,R,tmpR);
+  idDelete((ideal *)&b);
+  if (R!=NULL) idDelete(&R);
+  idSkipZeroes(result);
+  rChangeCurrRing(origR);
+  result = idrMoveR(result,tmpR,origR);
+  sm_KillModifiedRing(tmpR);
+  idTest(result);
+  return result;
+}
+#endif
+
+/*2
+*returns TRUE if id1 is a submodule of id2
+*/
+BOOLEAN idIsSubModule(ideal id1,ideal id2)
+{
+  int i;
+  poly p;
+
+  if (idIs0(id1)) return TRUE;
+  for (i=0;i<IDELEMS(id1);i++)
+  {
+    if (id1->m[i] != NULL)
+    {
+      p = kNF(id2,currRing->qideal,id1->m[i]);
+      if (p != NULL)
+      {
+        p_Delete(&p,currRing);
+        return FALSE;
+      }
+    }
+  }
+  return TRUE;
+}
+
+BOOLEAN idTestHomModule(ideal m, ideal Q, intvec *w)
+{
+  if ((Q!=NULL) && (!idHomIdeal(Q,NULL)))  { PrintS(" Q not hom\n"); return FALSE;}
+  if (idIs0(m)) return TRUE;
+
+  int cmax=-1;
+  int i;
+  poly p=NULL;
+  int length=IDELEMS(m);
+  polyset P=m->m;
+  for (i=length-1;i>=0;i--)
+  {
+    p=P[i];
+    if (p!=NULL) cmax=si_max(cmax,(int)pMaxComp(p)+1);
+  }
+  if (w != NULL)
+  if (w->length()+1 < cmax)
+  {
+    // Print("length: %d - %d \n", w->length(),cmax);
+    return FALSE;
+  }
+
+  if(w!=NULL)
+    p_SetModDeg(w, currRing);
+
+  for (i=length-1;i>=0;i--)
+  {
+    p=P[i];
+    if (p!=NULL)
+    {
+      int d=currRing->pFDeg(p,currRing);
+      loop
+      {
+        pIter(p);
+        if (p==NULL) break;
+        if (d!=currRing->pFDeg(p,currRing))
+        {
+          //pWrite(q); wrp(p); Print(" -> %d - %d\n",d,pFDeg(p,currRing));
+          if(w!=NULL)
+            p_SetModDeg(NULL, currRing);
+          return FALSE;
+        }
+      }
+    }
+  }
+
+  if(w!=NULL)
+    p_SetModDeg(NULL, currRing);
+
+  return TRUE;
+}
+
+ideal idSeries(int n,ideal M,matrix U,intvec *w)
+{
+  for(int i=IDELEMS(M)-1;i>=0;i--)
+  {
+    if(U==NULL)
+      M->m[i]=pSeries(n,M->m[i],NULL,w);
+    else
+    {
+      M->m[i]=pSeries(n,M->m[i],MATELEM(U,i+1,i+1),w);
+      MATELEM(U,i+1,i+1)=NULL;
+    }
+  }
+  if(U!=NULL)
+    idDelete((ideal*)&U);
+  return M;
+}
+
+matrix idDiff(matrix i, int k)
+{
+  int e=MATCOLS(i)*MATROWS(i);
+  matrix r=mpNew(MATROWS(i),MATCOLS(i));
+  r->rank=i->rank;
+  int j;
+  for(j=0; j<e; j++)
+  {
+    r->m[j]=pDiff(i->m[j],k);
+  }
+  return r;
+}
+
+matrix idDiffOp(ideal I, ideal J,BOOLEAN multiply)
+{
+  matrix r=mpNew(IDELEMS(I),IDELEMS(J));
+  int i,j;
+  for(i=0; i<IDELEMS(I); i++)
+  {
+    for(j=0; j<IDELEMS(J); j++)
+    {
+      MATELEM(r,i+1,j+1)=pDiffOp(I->m[i],J->m[j],multiply);
+    }
+  }
+  return r;
+}
+
+/*3
+*handles for some ideal operations the ring/syzcomp managment
+*returns all syzygies (componentwise-)shifted by -syzcomp
+*or -syzcomp-1 (in case of ideals as input)
+static ideal idHandleIdealOp(ideal arg,int syzcomp,int isIdeal=FALSE)
+{
+  ring orig_ring=currRing;
+  ring syz_ring=rAssure_SyzComp(orig_ring, TRUE); rChangeCurrRing(syz_ring);
+  rSetSyzComp(length, syz_ring);
+
+  ideal s_temp;
+  if (orig_ring!=syz_ring)
+    s_temp=idrMoveR_NoSort(arg,orig_ring, syz_ring);
+  else
+    s_temp=arg;
+
+  ideal s_temp1 = kStd(s_temp,currRing->qideal,testHomog,&w,NULL,length);
+  if (w!=NULL) delete w;
+
+  if (syz_ring!=orig_ring)
+  {
+    idDelete(&s_temp);
+    rChangeCurrRing(orig_ring);
+  }
+
+  idDelete(&temp);
+  ideal temp1=idRingCopy(s_temp1,syz_ring);
+
+  if (syz_ring!=orig_ring)
+  {
+    rChangeCurrRing(syz_ring);
+    idDelete(&s_temp1);
+    rChangeCurrRing(orig_ring);
+    rDelete(syz_ring);
+  }
+
+  for (i=0;i<IDELEMS(temp1);i++)
+  {
+    if ((temp1->m[i]!=NULL)
+    && (pGetComp(temp1->m[i])<=length))
+    {
+      pDelete(&(temp1->m[i]));
+    }
+    else
+    {
+      p_Shift(&(temp1->m[i]),-length,currRing);
+    }
+  }
+  temp1->rank = rk;
+  idSkipZeroes(temp1);
+
+  return temp1;
+}
+*/
+/*2
+* represents (h1+h2)/h2=h1/(h1 intersect h2)
+*/
+//ideal idModulo (ideal h2,ideal h1)
+ideal idModulo (ideal h2,ideal h1, tHomog hom, intvec ** w)
+{
+  intvec *wtmp=NULL;
+
+  int i,k,rk,flength=0,slength,length;
+  poly p,q;
+
+  if (idIs0(h2))
+    return idFreeModule(si_max(1,h2->ncols));
+  if (!idIs0(h1))
+    flength = id_RankFreeModule(h1,currRing);
+  slength = id_RankFreeModule(h2,currRing);
+  length  = si_max(flength,slength);
+  if (length==0)
+  {
+    length = 1;
+  }
+  ideal temp = idInit(IDELEMS(h2),length+IDELEMS(h2));
+  if ((w!=NULL)&&((*w)!=NULL))
+  {
+    //Print("input weights:");(*w)->show(1);PrintLn();
+    int d;
+    int k;
+    wtmp=new intvec(length+IDELEMS(h2));
+    for (i=0;i<length;i++)
+      ((*wtmp)[i])=(**w)[i];
+    for (i=0;i<IDELEMS(h2);i++)
+    {
+      poly p=h2->m[i];
+      if (p!=NULL)
+      {
+        d = p_Deg(p,currRing);
+        k= pGetComp(p);
+        if (slength>0) k--;
+        d +=((**w)[k]);
+        ((*wtmp)[i+length]) = d;
+      }
+    }
+    //Print("weights:");wtmp->show(1);PrintLn();
+  }
+  for (i=0;i<IDELEMS(h2);i++)
+  {
+    temp->m[i] = pCopy(h2->m[i]);
+    q = pOne();
+    pSetComp(q,i+1+length);
+    pSetmComp(q);
+    if(temp->m[i]!=NULL)
+    {
+      if (slength==0) p_Shift(&(temp->m[i]),1,currRing);
+      p = temp->m[i];
+      while (pNext(p)!=NULL) pIter(p);
+      pNext(p) = q;
+    }
+    else
+      temp->m[i]=q;
+  }
+  rk = k = IDELEMS(h2);
+  if (!idIs0(h1))
+  {
+    pEnlargeSet(&(temp->m),IDELEMS(temp),IDELEMS(h1));
+    IDELEMS(temp) += IDELEMS(h1);
+    for (i=0;i<IDELEMS(h1);i++)
+    {
+      if (h1->m[i]!=NULL)
+      {
+        temp->m[k] = pCopy(h1->m[i]);
+        if (flength==0) p_Shift(&(temp->m[k]),1,currRing);
+        k++;
+      }
+    }
+  }
+
+  ring orig_ring=currRing;
+  ring syz_ring=rAssure_SyzComp(orig_ring, TRUE); rChangeCurrRing(syz_ring);
+  if (TEST_OPT_RETURN_SB)
+    rSetSyzComp(id_RankFreeModule(temp,orig_ring), syz_ring);
+  else
+    rSetSyzComp(length, syz_ring);
+  ideal s_temp;
+
+  if (syz_ring != orig_ring)
+  {
+    s_temp = idrMoveR_NoSort(temp, orig_ring, syz_ring);
+  }
+  else
+  {
+    s_temp = temp;
+  }
+
+  idTest(s_temp);
+  ideal s_temp1 = kStd(s_temp,currRing->qideal,hom,&wtmp,NULL,length);
+
+  //if (wtmp!=NULL)  Print("output weights:");wtmp->show(1);PrintLn();
+  if ((w!=NULL) && (*w !=NULL) && (wtmp!=NULL))
+  {
+    delete *w;
+    *w=new intvec(IDELEMS(h2));
+    for (i=0;i<IDELEMS(h2);i++)
+      ((**w)[i])=(*wtmp)[i+length];
+  }
+  if (wtmp!=NULL) delete wtmp;
+
+  for (i=0;i<IDELEMS(s_temp1);i++)
+  {
+    if ((s_temp1->m[i]!=NULL)
+    && (((int)pGetComp(s_temp1->m[i]))<=length))
+    {
+      p_Delete(&(s_temp1->m[i]),currRing);
+    }
+    else
+    {
+      p_Shift(&(s_temp1->m[i]),-length,currRing);
+    }
+  }
+  s_temp1->rank = rk;
+  idSkipZeroes(s_temp1);
+
+  if (syz_ring!=orig_ring)
+  {
+    rChangeCurrRing(orig_ring);
+    s_temp1 = idrMoveR_NoSort(s_temp1, syz_ring, orig_ring);
+    rDelete(syz_ring);
+    // Hmm ... here seems to be a memory leak
+    // However, simply deleting it causes memory trouble
+    // idDelete(&s_temp);
+  }
+  else
+  {
+    idDelete(&temp);
+  }
+  idTest(s_temp1);
+  return s_temp1;
+}
+
+/*
+*computes module-weights for liftings of homogeneous modules
+*/
+intvec * idMWLift(ideal mod,intvec * weights)
+{
+  if (idIs0(mod)) return new intvec(2);
+  int i=IDELEMS(mod);
+  while ((i>0) && (mod->m[i-1]==NULL)) i--;
+  intvec *result = new intvec(i+1);
+  while (i>0)
+  {
+    (*result)[i]=currRing->pFDeg(mod->m[i],currRing)+(*weights)[pGetComp(mod->m[i])];
+  }
+  return result;
+}
+
+/*2
+*sorts the kbase for idCoef* in a special way (lexicographically
+*with x_max,...,x_1)
+*/
+ideal idCreateSpecialKbase(ideal kBase,intvec ** convert)
+{
+  int i;
+  ideal result;
+
+  if (idIs0(kBase)) return NULL;
+  result = idInit(IDELEMS(kBase),kBase->rank);
+  *convert = idSort(kBase,FALSE);
+  for (i=0;i<(*convert)->length();i++)
+  {
+    result->m[i] = pCopy(kBase->m[(**convert)[i]-1]);
+  }
+  return result;
+}
+
+/*2
+*returns the index of a given monom in the list of the special kbase
+*/
+int idIndexOfKBase(poly monom, ideal kbase)
+{
+  int j=IDELEMS(kbase);
+
+  while ((j>0) && (kbase->m[j-1]==NULL)) j--;
+  if (j==0) return -1;
+  int i=(currRing->N);
+  while (i>0)
+  {
+    loop
+    {
+      if (pGetExp(monom,i)>pGetExp(kbase->m[j-1],i)) return -1;
+      if (pGetExp(monom,i)==pGetExp(kbase->m[j-1],i)) break;
+      j--;
+      if (j==0) return -1;
+    }
+    if (i==1)
+    {
+      while(j>0)
+      {
+        if (pGetComp(monom)==pGetComp(kbase->m[j-1])) return j-1;
+        if (pGetComp(monom)>pGetComp(kbase->m[j-1])) return -1;
+        j--;
+      }
+    }
+    i--;
+  }
+  return -1;
+}
+
+/*2
+*decomposes the monom in a part of coefficients described by the
+*complement of how and a monom in variables occuring in how, the
+*index of which in kbase is returned as integer pos (-1 if it don't
+*exists)
+*/
+poly idDecompose(poly monom, poly how, ideal kbase, int * pos)
+{
+  int i;
+  poly coeff=pOne(), base=pOne();
+
+  for (i=1;i<=(currRing->N);i++)
+  {
+    if (pGetExp(how,i)>0)
+    {
+      pSetExp(base,i,pGetExp(monom,i));
+    }
+    else
+    {
+      pSetExp(coeff,i,pGetExp(monom,i));
+    }
+  }
+  pSetComp(base,pGetComp(monom));
+  pSetm(base);
+  pSetCoeff(coeff,nCopy(pGetCoeff(monom)));
+  pSetm(coeff);
+  *pos = idIndexOfKBase(base,kbase);
+  if (*pos<0)
+    p_Delete(&coeff,currRing);
+  p_Delete(&base,currRing);
+  return coeff;
+}
+
+/*2
+*returns a matrix A of coefficients with kbase*A=arg
+*if all monomials in variables of how occur in kbase
+*the other are deleted
+*/
+matrix idCoeffOfKBase(ideal arg, ideal kbase, poly how)
+{
+  matrix result;
+  ideal tempKbase;
+  poly p,q;
+  intvec * convert;
+  int i=IDELEMS(kbase),j=IDELEMS(arg),k,pos;
+#if 0
+  while ((i>0) && (kbase->m[i-1]==NULL)) i--;
+  if (idIs0(arg))
+    return mpNew(i,1);
+  while ((j>0) && (arg->m[j-1]==NULL)) j--;
+  result = mpNew(i,j);
+#else
+  result = mpNew(i, j);
+  while ((j>0) && (arg->m[j-1]==NULL)) j--;
+#endif
+
+  tempKbase = idCreateSpecialKbase(kbase,&convert);
+  for (k=0;k<j;k++)
+  {
+    p = arg->m[k];
+    while (p!=NULL)
+    {
+      q = idDecompose(p,how,tempKbase,&pos);
+      if (pos>=0)
+      {
+        MATELEM(result,(*convert)[pos],k+1) =
+            pAdd(MATELEM(result,(*convert)[pos],k+1),q);
+      }
+      else
+        p_Delete(&q,currRing);
+      pIter(p);
+    }
+  }
+  idDelete(&tempKbase);
+  return result;
+}
+
+static void idDeleteComps(ideal arg,int* red_comp,int del)
+// red_comp is an array [0..args->rank]
+{
+  int i,j;
+  poly p;
+
+  for (i=IDELEMS(arg)-1;i>=0;i--)
+  {
+    p = arg->m[i];
+    while (p!=NULL)
+    {
+      j = pGetComp(p);
+      if (red_comp[j]!=j)
+      {
+        pSetComp(p,red_comp[j]);
+        pSetmComp(p);
+      }
+      pIter(p);
+    }
+  }
+  (arg->rank) -= del;
+}
+
+/*2
+* returns the presentation of an isomorphic, minimally
+* embedded  module (arg represents the quotient!)
+*/
+ideal idMinEmbedding(ideal arg,BOOLEAN inPlace, intvec **w)
+{
+  if (idIs0(arg)) return idInit(1,arg->rank);
+  int i,next_gen,next_comp;
+  ideal res=arg;
+  if (!inPlace) res = idCopy(arg);
+  res->rank=si_max(res->rank,id_RankFreeModule(res,currRing));
+  int *red_comp=(int*)omAlloc((res->rank+1)*sizeof(int));
+  for (i=res->rank;i>=0;i--) red_comp[i]=i;
+
+  int del=0;
+  loop
+  {
+    next_gen = id_ReadOutPivot(res, &next_comp, currRing);
+    if (next_gen<0) break;
+    del++;
+    syGaussForOne(res,next_gen,next_comp,0,IDELEMS(res));
+    for(i=next_comp+1;i<=arg->rank;i++) red_comp[i]--;
+    if ((w !=NULL)&&(*w!=NULL))
+    {
+      for(i=next_comp;i<(*w)->length();i++) (**w)[i-1]=(**w)[i];
+    }
+  }
+
+  idDeleteComps(res,red_comp,del);
+  idSkipZeroes(res);
+  omFree(red_comp);
+
+  if ((w !=NULL)&&(*w!=NULL) &&(del>0))
+  {
+    int nl=si_max((*w)->length()-del,1);
+    intvec *wtmp=new intvec(nl);
+    for(i=0;i<res->rank;i++) (*wtmp)[i]=(**w)[i];
+    delete *w;
+    *w=wtmp;
+  }
+  return res;
+}
+
+#include <polys/clapsing.h>
+
+#if 0
+poly id_GCD(poly f, poly g, const ring r)
+{
+  ring save_r=currRing;
+  rChangeCurrRing(r);
+  ideal I=idInit(2,1); I->m[0]=f; I->m[1]=g;
+  intvec *w = NULL;
+  ideal S=idSyzygies(I,testHomog,&w);
+  if (w!=NULL) delete w;
+  poly gg=pTakeOutComp(&(S->m[0]),2);
+  idDelete(&S);
+  poly gcd_p=singclap_pdivide(f,gg,r);
+  p_Delete(&gg,r);
+  rChangeCurrRing(save_r);
+  return gcd_p;
+}
+#else
+poly id_GCD(poly f, poly g, const ring r)
+{
+  ideal I=idInit(2,1); I->m[0]=f; I->m[1]=g;
+  intvec *w = NULL;
+
+  ring save_r = currRing; rChangeCurrRing(r); ideal S=idSyzygies(I,testHomog,&w); rChangeCurrRing(save_r);
+
+  if (w!=NULL) delete w;
+  poly gg=p_TakeOutComp(&(S->m[0]), 2, r);
+  id_Delete(&S, r);
+  poly gcd_p=singclap_pdivide(f,gg, r);
+  p_Delete(&gg, r);
+
+  return gcd_p;
+}
+#endif
+
+#if 0
+/*2
+* xx,q: arrays of length 0..rl-1
+* xx[i]: SB mod q[i]
+* assume: char=0
+* assume: q[i]!=0
+* destroys xx
+*/
+ideal id_ChineseRemainder(ideal *xx, number *q, int rl, const ring R)
+{
+  int cnt=IDELEMS(xx[0])*xx[0]->nrows;
+  ideal result=idInit(cnt,xx[0]->rank);
+  result->nrows=xx[0]->nrows; // for lifting matrices
+  result->ncols=xx[0]->ncols; // for lifting matrices
+  int i,j;
+  poly r,h,hh,res_p;
+  number *x=(number *)omAlloc(rl*sizeof(number));
+  for(i=cnt-1;i>=0;i--)
+  {
+    res_p=NULL;
+    loop
+    {
+      r=NULL;
+      for(j=rl-1;j>=0;j--)
+      {
+        h=xx[j]->m[i];
+        if ((h!=NULL)
+        &&((r==NULL)||(p_LmCmp(r,h,R)==-1)))
+          r=h;
+      }
+      if (r==NULL) break;
+      h=p_Head(r, R);
+      for(j=rl-1;j>=0;j--)
+      {
+        hh=xx[j]->m[i];
+        if ((hh!=NULL) && (p_LmCmp(r,hh, R)==0))
+        {
+          x[j]=p_GetCoeff(hh, R);
+          hh=p_LmFreeAndNext(hh, R);
+          xx[j]->m[i]=hh;
+        }
+        else
+          x[j]=n_Init(0, R->cf); // is R->cf really n_Q???, yes!
+      }
+
+      number n=n_ChineseRemainder(x,q,rl, R->cf);
+
+      for(j=rl-1;j>=0;j--)
+      {
+        x[j]=NULL; // nlInit(0...) takes no memory
+      }
+      if (n_IsZero(n, R->cf)) p_Delete(&h, R);
+      else
+      {
+        p_SetCoeff(h,n, R);
+        //Print("new mon:");pWrite(h);
+        res_p=p_Add_q(res_p, h, R);
+      }
+    }
+    result->m[i]=res_p;
+  }
+  omFree(x);
+  for(i=rl-1;i>=0;i--) id_Delete(&(xx[i]), R);
+  omFree(xx);
+  return result;
+}
+#endif
+/* currently unsed:
+ideal idChineseRemainder(ideal *xx, intvec *iv)
+{
+  int rl=iv->length();
+  number *q=(number *)omAlloc(rl*sizeof(number));
+  int i;
+  for(i=0; i<rl; i++)
+  {
+    q[i]=nInit((*iv)[i]);
+  }
+  return idChineseRemainder(xx,q,rl);
+}
+*/
+/*
+ * lift ideal with coeffs over Z (mod N) to Q via Farey
+ */
+ideal id_Farey(ideal x, number N, const ring r)
+{
+  int cnt=IDELEMS(x)*x->nrows;
+  ideal result=idInit(cnt,x->rank);
+  result->nrows=x->nrows; // for lifting matrices
+  result->ncols=x->ncols; // for lifting matrices
+
+  int i;
+  for(i=cnt-1;i>=0;i--)
+  {
+    result->m[i]=p_Farey(x->m[i],N,r);
+  }
+  return result;
+}
+
+
+
+
+// uses glabl vars via pSetModDeg
+/*
+BOOLEAN idTestHomModule(ideal m, ideal Q, intvec *w)
+{
+  if ((Q!=NULL) && (!idHomIdeal(Q,NULL)))  { PrintS(" Q not hom\n"); return FALSE;}
+  if (idIs0(m)) return TRUE;
+
+  int cmax=-1;
+  int i;
+  poly p=NULL;
+  int length=IDELEMS(m);
+  poly* P=m->m;
+  for (i=length-1;i>=0;i--)
+  {
+    p=P[i];
+    if (p!=NULL) cmax=si_max(cmax,(int)pMaxComp(p)+1);
+  }
+  if (w != NULL)
+  if (w->length()+1 < cmax)
+  {
+    // Print("length: %d - %d \n", w->length(),cmax);
+    return FALSE;
+  }
+
+  if(w!=NULL)
+    p_SetModDeg(w, currRing);
+
+  for (i=length-1;i>=0;i--)
+  {
+    p=P[i];
+    poly q=p;
+    if (p!=NULL)
+    {
+      int d=p_FDeg(p,currRing);
+      loop
+      {
+        pIter(p);
+        if (p==NULL) break;
+        if (d!=p_FDeg(p,currRing))
+        {
+          //pWrite(q); wrp(p); Print(" -> %d - %d\n",d,pFDeg(p,currRing));
+          if(w!=NULL)
+            p_SetModDeg(NULL, currRing);
+          return FALSE;
+        }
+      }
+    }
+  }
+
+  if(w!=NULL)
+    p_SetModDeg(NULL, currRing);
+
+  return TRUE;
+}
+*/
+
+/// keeps the first k (>= 1) entries of the given ideal
+/// (Note that the kept polynomials may be zero.)
+void idKeepFirstK(ideal id, const int k)
+{
+   for (int i = IDELEMS(id)-1; i >= k; i--)
+   {
+      if (id->m[i] != NULL) pDelete(&id->m[i]);
+   }
+   int kk=k;
+   if (k==0) kk=1; /* ideals must have at least one element(0)*/
+   pEnlargeSet(&(id->m), IDELEMS(id), kk-IDELEMS(id));
+   IDELEMS(id) = kk;
+}
+
+/*
+* compare the leading terms of a and b
+*/
+static int tCompare(const poly a, const poly b)
+{
+  if (b == NULL) return(a != NULL);
+  if (a == NULL) return(-1);
+
+  /* a != NULL && b != NULL */
+  int r = pLmCmp(a, b);
+  if (r != 0) return(r);
+  number h = nSub(pGetCoeff(a), pGetCoeff(b));
+  r = -1 + nIsZero(h) + 2*nGreaterZero(h);   /* -1: <, 0:==, 1: > */
+  nDelete(&h);
+  return(r);
+}
+
+/*
+* compare a and b (rev-lex on terms)
+*/
+static int pCompare(const poly a, const poly b)
+{
+  int r = tCompare(a, b);
+  if (r != 0) return(r);
+
+  poly aa = a;
+  poly bb = b;
+  while (r == 0 && aa != NULL && bb != NULL)
+  {
+    pIter(aa);
+    pIter(bb);
+    r = tCompare(aa, bb);
+  }
+  return(r);
+}
+
+typedef struct
+{
+  poly p;
+  int index;
+} poly_sort;
+
+int pCompare_qsort(const void *a, const void *b)
+{
+  int res = pCompare(((poly_sort *)a)->p, ((poly_sort *)b)->p);
+  return(res);
+}
+
+void idSort_qsort(poly_sort *id_sort, int idsize)
+{
+  qsort(id_sort, idsize, sizeof(poly_sort), pCompare_qsort);
+}
+
+/*2
+* ideal id = (id[i])
+* if id[i] = id[j] then id[j] is deleted for j > i
+*/
+void idDelEquals(ideal id)
+{
+  int idsize = IDELEMS(id);
+  poly_sort *id_sort = (poly_sort *)omAlloc0(idsize*sizeof(poly_sort));
+  for (int i = 0; i < idsize; i++)
+  {
+    id_sort[i].p = id->m[i];
+    id_sort[i].index = i;
+  }
+  idSort_qsort(id_sort, idsize);
+  int index, index_i, index_j;
+  int i = 0;
+  for (int j = 1; j < idsize; j++)
+  {
+    if (id_sort[i].p != NULL && pEqualPolys(id_sort[i].p, id_sort[j].p))
+    {
+      index_i = id_sort[i].index;
+      index_j = id_sort[j].index;
+      if (index_j > index_i)
+      {
+        index = index_j;
+      }
+      else
+      {
+        index = index_i;
+        i = j;
+      }
+      pDelete(&id->m[index]);
+    }
+    else
+    {
+      i = j;
+    }
+  }
+  omFreeSize((ADDRESS)(id_sort), idsize*sizeof(poly_sort));
+}
diff --git a/kernel/ideals.h b/kernel/ideals.h
new file mode 100644
index 0000000..6e2fbbd
--- /dev/null
+++ b/kernel/ideals.h
@@ -0,0 +1,212 @@
+#ifndef IDEALS_H
+#define IDEALS_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT - all basic methods to manipulate ideals
+*/
+
+#include <polys/monomials/ring.h>
+#include <polys/monomials/p_polys.h>
+#include <polys/simpleideals.h>
+
+extern ring currRing;
+
+#include <kernel/structs.h> // for tHomog
+
+//typedef struct sip_sideal *        ideal;
+//typedef struct sip_smap *          map;
+typedef ideal *            resolvente;
+
+inline ideal idCopyFirstK (const ideal ide, const int k, ring R = currRing)
+{
+  return id_CopyFirstK(ide, k, R);
+}
+
+void idKeepFirstK(ideal ide, const int k);
+void idDelEquals(ideal id);
+
+/// delete an ideal
+inline void idDelete (ideal* h, ring r = currRing)
+{
+  id_Delete(h, r);
+}
+
+/// initialise the maximal ideal (at 0)
+//ideal id_MaxIdeal(int deg, const ring r);
+#define idMaxIdeal(D) id_MaxIdeal(D,currRing)
+
+/// index of generator with leading term in ground ring (if any); otherwise -1
+//int id_PosConstant(ideal id, const ring r)
+#define idPosConstant(I) id_PosConstant(I,currRing)
+
+/// Count the effective size of an ideal
+/// (without the trailing allocated zero-elements)
+static inline int idSize(const ideal id)
+{
+  int j = IDELEMS(id) - 1;
+  poly* mm = id->m;
+  while ((j >= 0) && (mm[j] == NULL)) j--;
+  return (j + 1);
+}
+
+
+//BOOLEAN id_IsConstant(ideal id, const ring r);
+#define idIsConstant(I) id_IsConstant(I,currRing)
+
+#define idSimpleAdd(A,B) id_SimpleAdd(A,B,currRing)
+
+ideal id_Copy (ideal h1, const ring r);
+
+#define idPrint(id) id_Print(id, currRing, currRing)
+#define idTest(id)  id_Test(id, currRing)
+
+#if 0
+
+// ifdef PDEBUG // Sorry: the following was lost........ :((((((((
+ideal idDBCopy(ideal h1,const char *f,int l,const ring r);
+#define id_DBCopy(A,r) idDBCopy(A,__FILE__,__LINE__,r)
+
+inline ideal idCopy(ideal A, const ring R = currRing)
+{
+  return id_DBCopy(A,R); // well, just for now... ok? Macros can't  have default args values :(
+}
+#else
+inline ideal idCopy(ideal A, const ring R = currRing)
+{
+  return id_Copy(A, R);
+}
+#endif
+
+
+/// h1 + h2
+inline ideal idAdd (ideal h1, ideal h2, const ring R = currRing)
+{
+  return id_Add(h1, h2, R);
+}
+
+BOOLEAN idInsertPoly (ideal h1,poly h2);  /* h1 + h2 */
+inline BOOLEAN idInsertPolyWithTests (ideal h1, const int validEntries, const poly h2, const bool zeroOk, const bool duplicateOk, const ring R = currRing)
+{
+  return id_InsertPolyWithTests (h1, validEntries, h2, zeroOk, duplicateOk, R);
+}
+
+
+/* h1 + h2 */
+
+/// hh := h1 * h2
+inline ideal idMult (ideal h1, ideal h2, const ring R = currRing)
+{
+  return id_Mult(h1, h2, R);
+}
+
+BOOLEAN idIs0 (ideal h);
+
+// returns TRUE, if idRankFreeModule(m) > 0
+BOOLEAN idIsModule(ideal m, const ring r);
+
+inline BOOLEAN idHomIdeal (ideal id, ideal Q=NULL, const ring R = currRing)
+{
+  return id_HomIdeal(id, Q, R);
+}
+
+inline BOOLEAN idHomModule(ideal m, ideal Q,intvec **w, const ring R = currRing)
+{
+   return id_HomModule(m, Q, w, R);
+}
+
+BOOLEAN idTestHomModule(ideal m, ideal Q, intvec *w);
+
+ideal idMinBase (ideal h1);
+  /*returns a minimized set of generators of h1*/
+void    idInitChoise (int r,int beg,int end,BOOLEAN *endch,int * choise);
+void    idGetNextChoise (int r,int end,BOOLEAN *endch,int * choise);
+int     idGetNumberOfChoise(int t, int d, int begin, int end, int * choise);
+
+int     binom (int n,int r);
+
+inline ideal idFreeModule (int i, const ring R = currRing)
+{
+  return id_FreeModule (i, R);
+}
+
+
+ideal   idSect (ideal h1,ideal h2);
+ideal   idMultSect(resolvente arg, int length);
+
+//ideal   idSyzygies (ideal h1, tHomog h,intvec **w);
+ideal   idSyzygies (ideal h1, tHomog h,intvec **w, BOOLEAN setSyzComp=TRUE,
+                    BOOLEAN setRegularity=FALSE, int *deg = NULL);
+ideal   idLiftStd  (ideal h1, matrix *m, tHomog h=testHomog, ideal *syz=NULL);
+
+ideal   idLift (ideal mod, ideal sumod,ideal * rest=NULL,
+             BOOLEAN goodShape=FALSE, BOOLEAN isSB=TRUE,BOOLEAN divide=FALSE,
+             matrix *unit=NULL);
+
+void idLiftW(ideal P,ideal Q,int n,matrix &T, ideal &R, short *w= NULL );
+
+intvec * idMWLift(ideal mod,intvec * weights);
+
+ideal   idQuot (ideal h1,ideal h2,
+                BOOLEAN h1IsStb=FALSE, BOOLEAN resultIsIdeal=FALSE);
+
+// ideal   idPower(ideal gid,int deg);
+
+//ideal   idElimination (ideal h1,poly delVar);
+ideal   idElimination (ideal h1,poly delVar, intvec *hilb=NULL);
+
+#ifdef WITH_OLD_MINOR
+poly idMinor(matrix a, int ar, unsigned long which, ideal R = NULL);
+#endif
+ideal   idMinors(matrix a, int ar, ideal R = NULL);
+
+ideal idMinEmbedding(ideal arg,BOOLEAN inPlace=FALSE, intvec **w=NULL);
+
+ideal   idHead(ideal h);
+
+// ideal   idHomogen(ideal h, int varnum);
+
+BOOLEAN idIsSubModule(ideal id1,ideal id2);
+
+inline ideal idVec2Ideal(poly vec, const ring R = currRing)
+{
+  return id_Vec2Ideal(vec, R);
+}
+
+ideal   idSeries(int n,ideal M,matrix U=NULL,intvec *w=NULL);
+
+inline BOOLEAN idIsZeroDim(ideal i, const ring R = currRing)
+{
+  return id_IsZeroDim(i, R);
+}
+
+matrix  idDiff(matrix i, int k);
+matrix  idDiffOp(ideal I, ideal J,BOOLEAN multiply=TRUE);
+
+inline intvec *idSort(ideal id,BOOLEAN nolex=TRUE, const ring R = currRing)
+{
+  return id_Sort(id, nolex, R);
+}
+
+ideal   idModulo (ideal h1,ideal h2, tHomog h=testHomog, intvec ** w=NULL);
+matrix  idCoeffOfKBase(ideal arg, ideal kbase, poly how);
+
+/// transpose a module
+inline ideal   idTransp(ideal a, const ring R = currRing)
+{
+  return id_Transp(a, R);
+}
+
+// intvec *idQHomWeight(ideal id);
+
+ideal idXXX (ideal  h1, int k);
+
+poly id_GCD(poly f, poly g, const ring r);
+
+ideal id_Farey(ideal x, number N, const ring r);
+
+ideal id_TensorModuleMult(const int m, const ideal M, const ring rRing); // image of certain map for BGG
+
+
+#endif
diff --git a/kernel/linear_algebra/Cache.h b/kernel/linear_algebra/Cache.h
new file mode 100644
index 0000000..2d440f6
--- /dev/null
+++ b/kernel/linear_algebra/Cache.h
@@ -0,0 +1,329 @@
+#ifndef CACHE_H
+#define CACHE_H
+
+#include <string>
+#include <list>
+
+// #include <assert.h>
+// using namespace std;
+
+/*! \class Cache
+    \brief Class Cache is a template-implementation of a cache with
+    arbitrary classes for representing keys and values, respectively.
+
+    Each entry of the cache is of the form <em>key --> value</em>,
+    where \e key is an instance of some \c KeyClass, and \e value
+    an instance of some \c ValueClass.<br><br>
+    This implementation comes with the possibility to define bounds
+    on both the number of cached pairs <em>key --> value</em> and on
+    the total \e weight of the cache.<br>
+    Here, the \e weight of a cache is defined as the sum
+    of \e weights of all cached values, where the \e weight of each value
+    needs to be implemented in the actual class \c ValueClass.
+    An example for the weight of a cached value
+    may simply be its size in bytes, or may capture some other useful notion
+    of how \e heavy the value is. E.g., when caching polynomials, the \e weight
+    may be defined to be equal to the number of its monomials.<br><br>
+    The <em>key --> value</em> pairs of a cache are being stored in two
+    standard lists \c _key and \c _value of equal length <em>L</em>.<br>
+    In order to enable a fast
+    value lookup, the vector \c _key maintains an ordering such that<br>
+    <em> i < j  ==>  _key[i] < _key[j],</em><br>
+    where the right-hand side comparator
+    \e < needs to be implemented by class \c KeyClass. Note that this
+    ordering allows for value lookup in time <em>O(log(L))</em>, when given
+    a specific key.<br><br>
+    In addition to \c _key and \c _value, there is a third book-keeping
+    structure in Cache: The vector \c _rank of integers captures ranking
+    information among all cached values. More concretely,<br>
+    <em>_rank : {0, 1, 2, ..., L - 1} --> {0, 1, 2, ..., L - 1}</em><br>
+    is a bijection with the semantic<br>
+    <em>_rank[s] < _rank[t] :<==> _value[_rank[s]] < _value[_rank[t]],</em><br>
+    where the right-hand side comparator \e < needs to be
+    implemented by class \c ValueClass. The intention here is that any relation
+    <em>_rank[s] < _rank[t]</em>
+    is to imply that the key-value pair
+    <em>_key[_rank[t]] --> _value[_rank[t]]</em> will be kept at least as
+    long in cache as <em> _key[_rank[s]] --> _value[_rank[s]]</em>.
+    (I.e., loosely speaking, the higher the rank, the longer a pair is going
+    to be cached.)<br><br>
+    Whenever the cache becomes either too large (in terms of number of
+    entries), or too \e heavy (in terms of accumulated weight), it will
+    automatically shrink until both bounds will have been re-established. To
+    this end, the <em>key --> value</em> pair with least value rank will be
+    erased from the cache. This process is repeated until the cache is small
+    enough again, in terms of both the number of entries and the \e weight.
+    (Note that it may be necessary to erase numerous pairs after inserting
+    just one <em>key --> value</em> when this value's \e weight is
+    unproportionally high.)<br><br>
+    In order to make the above procedures work, the two template classes
+    \c KeyClass and \c ValueClass need to implement the following methods:<br>
+    <c>bool KeyClass::operator< (const KeyClass& key),</c><br>
+    <c>bool KeyClass::operator== (const KeyClass& key),</c><br>
+    <c>bool ValueClass::operator< (const ValueClass& key),</c><br>
+    <c>bool ValueClass::operator== (const ValueClass& key),</c><br>
+    <c>int ValueClass::getWeight ().</c>
+    \author Frank Seelisch, http://www.mathematik.uni-kl.de/~seelisch
+*/
+template<class KeyClass, class ValueClass> class Cache
+{
+  private:
+     /**
+     * A bijection on the set {0, ..., _key.size() - 1}.<br>
+     * Semantically, <c>_rank(j) > _rank(i)</c> means that the pair
+     * <c>key(_rank(j)) --> value(_rank(j))</c> will be cached at least
+     * as long as the pair <c>key(_rank(i)) -->  value(_rank(i))</c>.
+     */
+   std::list<int> _rank;
+
+     /**
+     * _key is sorted in ascending order, i.e.,
+     * <em>j < i  ==>  _key(j) < _key(i),</em>
+     * where the right-hand side comparator "<" needs to be implemented
+     * in KeyClass.
+     */
+     std::list<KeyClass> _key;
+
+     /**
+     *  _value captures the actual objects of interest;<br>
+     * \c _value[i] corresponds to \c _key[i] and may be retrieved
+     * by calling Cache::getValue (const KeyClass&) const with the
+     * argument \c _key[i]).
+     */
+     std::list<ValueClass> _value;
+
+     /**
+     * container for the weights of all cached values
+     */
+     std::list<int> _weights;
+
+     /**
+     * a pointer to some element of _key;
+     * We make this mutable so that methods which leave the cache
+     * unmodified but which alter _itKey can still be declared as
+     * const, as the user would expect for these methods.
+     */
+     mutable typename std::list<KeyClass>::const_iterator _itKey;
+
+     /**
+     * a pointer to some element of _value;
+     * We make this mutable so that methods which leave the cache
+     * unmodified but which alter _itValue can still be declared as
+     * const, as the user would expect for these methods.
+     */
+     mutable typename std::list<ValueClass>::const_iterator _itValue;
+
+     /**
+     * for storing the momentary weight of the given cache;<br>
+     * This is the sum of \c _value[i].getWeight() over all \e i,
+     * i.e., over all cached values. Equivalently, this is equal
+     * to all weights stored in _weights.
+     */
+     int _weight;
+
+     /**
+     * the bound for the number of cached <c>key --> value</c> pairs;<br>
+     * The cache will automatically ensure that this bound will never be
+     * exceeded;
+     * see Cache::shrink (const KeyClass&) and Cache::deleteLast ().
+     */
+     int _maxEntries;
+
+     /**
+     * the bound on total cache weight;<br>
+     * The cache will automatically ensure that this bound will never be
+     * exceeded; see
+     * see Cache::shrink (const KeyClass&) and Cache::deleteLast ().
+     */
+     int _maxWeight;
+
+     /**
+     * A method for providing the index of a given key in the vector _key.
+     * Either _key contains the given key, then its index will be returned.
+     * Otherwise the position in _key, at which the given key should be placed
+     * (with respect to the ordering in _key) is returned.
+     * @param key an instance of KeyClass
+     * @return the actual or would-be index of key in _key
+     * @see Cache::hasKey (const KeyClass&) const
+     */
+     int getIndexInKey (const KeyClass& key) const;
+
+     /**
+     * A method for providing the index of a given value in the vector _rank.
+     * Based on the rank of the given value, the position in _rank at which
+     * the given value should be inserted, is returned.
+     * (The method also works, when the given value is already contained in
+     * the cache.)
+     * @param value an instance of ValueClass
+     * @return the actual or would-be index of value in _rank
+     */
+     int getIndexInRank (const ValueClass& value) const;
+
+     /**
+     * A method for shrinking the given cache so that it meet the bounds on
+     * the maximum number of entries and total weight again.
+     * The method returns true iff the process of shrinking deleted a pair
+     * (k --> v) from the cache such that k equals the given key.
+     * @param key an instance of KeyClass
+     * @return true iff shrinking deleted a pair (key --> *)
+     */
+     bool shrink (const KeyClass& key);
+
+     /**
+     * A method for deleting the least-ranked cache entry.
+     * The method returns true iff the deleted pair (k --> v)
+     * satisfies k == key.
+     * @param key an instance of KeyClass
+     * @return true iff a pair (key --> *) was deleted
+     */
+     bool deleteLast (const KeyClass& key);
+  public:
+     /**
+     * A constructor for class Cache.
+     * The method makes sure that all member vectors be empty.
+     */
+     Cache();
+
+     /**
+     * A destructor for class Cache.
+     * The method clears all member vectors. (This includes that
+     * destructors are invoked, accordingly.)
+     */
+     ~Cache();
+
+     /**
+     * Copy implementation for class Cache.
+     * Apart from copying all flat members, all vectors are being
+     * deep-copied.
+     */
+     Cache (const Cache& c);
+
+     /**
+     * A user-suited constructor for class Cache.
+     * The method makes sure that all member vectors be empty.
+     * Moreover, the user can provide bounds for the maximum
+     * number of entries in the cache, and for the total weight
+     * of the cache.
+     * @param maxEntries the (positive) maximum number of pairs
+              (key --> value) in the cache
+     * @param maxWeight the (positive) maximum weight of the cache
+     */
+     Cache (const int maxEntries, const int maxWeight);
+
+     /**
+     * A method for retrieving the momentary weight of the cache.
+     * The return value will always be less than or equal to the result
+     * of Cache::getMaxWeight () const.<br>
+     * Semantically, the total weight of a cache is the sum of weights
+     * of all cached values.
+     * @return the momentary weight of the cache
+     * @see Cache::getMaxWeight () const
+     * @see MinorValue::getWeight () const
+     */
+     int getWeight () const;
+
+     /**
+     * A method for retrieving the momentary number of (key --> value) pairs
+     * in the cache.
+     * The return value will always be less than or equal to the result of
+     * Cache::getMaxNumberOfEntries () const.
+     * @return the momentary number of cached values of the cache
+     * @see Cache::getMaxNumberOfEntries () const
+     */
+     int getNumberOfEntries () const;
+
+     /**
+     * A method for retrieving the maximum number of (key --> value) pairs
+     * in the cache.
+     * @return the maximum number of cached values of the cache
+     * @see Cache::getNumberOfEntries () const
+     * @see Cache::Cache (const int, const int)
+     */
+     int getMaxNumberOfEntries () const;
+
+     /**
+     * A method for retrieving the maximum weight of the cache.
+     * @return the maximum weight of the cache
+     * @see Cache::getWeight () const
+     * @see Cache::Cache (const int, const int)
+     */
+     int getMaxWeight () const;
+
+     /**
+     * Checks whether the cache contains a pair (k --> v) such that
+     * k equals the given key.
+     * If so, the method returns true; false otherwise.
+     * In order to make Cache::getValue (const KeyClass&) const
+     * work properly, the user is strongly adviced to always check key
+     * containment by means of Cache::hasKey (const KeyClass&) const.
+     * (The implementation at hand ensures that invoking hasKey and
+     * getValue does not result in extra computational efforts.)
+     * @param key the key for which containment is to be checked
+     * @return true iff the cache contains the given key
+     * @see Cache::getValue (const KeyClass&) const
+     */
+     bool hasKey (const KeyClass& key) const;
+
+     /**
+     * Returns the value for a given key.
+     * The method assumes that there is actually an entry of the form
+     * (key --> *) in the cache. This can be checked before using
+     * Cache::hasKey (const KeyClass&) const. (Note that calling
+     * both methods in direct succession does not result in extra
+     * computational efforts.)
+     * \par Assertions
+     * If the given key is not contained in the cache, program execution
+     * will be stopped.
+     * @param key the key, for which the corresponding value is to be returned
+     * @return the value corresponding to the given key
+     * @see Cache::hasKey (const KeyClass&) const
+     */
+     ValueClass getValue (const KeyClass& key) const;
+
+     /**
+     * Inserts the pair (key --> value) in the cache.
+     * If there is already some entry (key --> value'), then value will be
+     * replaced by value'.
+     * As putting some new pair in the cache may result in a violation
+     * of the maximal number of entries or the weight of the cache, or both,
+     * Cache::put (const KeyClass&, const ValueClass&) will always finalize by
+     * calling the private method Cache::shrink(const KeyClass&), in order to
+     * re-establish both bounds. Note that this may even result in deleting the
+     * newly inserted pair (key --> value).<br>
+     * Because of that undesirable but possible effect, the method returns
+     * whether the pair is actually contained in the cache after invokation of
+     * Cache::put (const KeyClass&, const ValueClass&).
+     * @param key an instance of KeyClass
+     * @param value an instance of ValueClass
+     * @return whether the pair (key --> value) is contained in the modified
+     *         cache
+     * @see Cache::getValue (const KeyClass&) const
+     */
+     bool put (const KeyClass& key, const ValueClass& value);
+
+     /**
+     * Clears the cache so that it has no entry. This method will also
+     * enforce destruction of all former entries of the cache.
+     */
+     void clear ();
+
+     /**
+     * A method for providing a printable version of the represented
+     * cache, including all contained (key --> value) pairs.
+     * @return a printable version of the given instance as instance of class
+     *         string
+     */
+   std::string toString () const;
+
+     /**
+     * A method for printing a string representation of the given cache to
+     * std::cout. This includes string representations of all contained
+     * (key --> value) pairs.
+     */
+     void print () const;
+};
+
+#include <kernel/linear_algebra/CacheImplementation.h>
+
+#endif
+/* CACHE_H */
diff --git a/kernel/linear_algebra/CacheImplementation.h b/kernel/linear_algebra/CacheImplementation.h
new file mode 100644
index 0000000..d2691dd
--- /dev/null
+++ b/kernel/linear_algebra/CacheImplementation.h
@@ -0,0 +1,436 @@
+#ifndef CACHE_IMPLEMENTATION_H
+#define CACHE_IMPLEMENTATION_H
+
+#include <reporter/reporter.h>
+
+#include <cstdio> // for sprintf
+#include <iostream>
+
+template<class KeyClass, class ValueClass>
+Cache<KeyClass, ValueClass>::Cache (const int maxEntries, const int maxWeight)
+{
+  _maxEntries = maxEntries;
+  _maxWeight = maxWeight;
+  _rank.clear();
+  _key.clear();
+  _value.clear();
+  _weights.clear();
+  _itKey = _key.end(); /* referring to past-the-end element in the list */
+  _itValue = _value.end(); /* referring to past-the-end element in the list */
+  _weight = 0;
+}
+
+template<class KeyClass, class ValueClass>
+int Cache<KeyClass, ValueClass>::getWeight() const
+{
+  return _weight;
+}
+
+template<class KeyClass, class ValueClass>
+int Cache<KeyClass, ValueClass>::getNumberOfEntries() const
+{
+  return _rank.size();
+}
+
+template<class KeyClass, class ValueClass>
+void Cache<KeyClass, ValueClass>::clear()
+{
+  _rank.clear();
+  _key.clear();
+  _value.clear();
+  _weights.clear();
+}
+
+template<class KeyClass, class ValueClass>
+Cache<KeyClass, ValueClass>::~Cache()
+{
+  _rank.clear();
+  _key.clear();
+  _value.clear();
+  _weights.clear();
+}
+
+template<class KeyClass, class ValueClass>
+bool Cache<KeyClass, ValueClass>::hasKey (const KeyClass& key) const
+{
+  _itKey = _key.end(); // referring to past-the-end element in the list
+   typename std::list<KeyClass>::const_iterator itKey;
+  _itValue = _value.begin();
+  /* As _key is a sorted list, the following could actually be implemented
+     in logarithmic time, by bisection. However, for lists this does not work.
+     But often, we can still terminate the linear loop before having visited
+     all elements. */
+  for (itKey = _key.begin(); itKey != _key.end(); itKey++)
+  {
+    int c = key.compare(*itKey);
+    if (c == 0)
+    {
+      _itKey = itKey;
+      return true;
+    }
+    if (c == -1) return false;
+    _itValue++;
+  }
+  return false;
+}
+
+template<class KeyClass, class ValueClass>
+ValueClass Cache<KeyClass, ValueClass>::getValue (const KeyClass& /*key*/) const
+{
+  if (_itKey == _key.end())
+    /* _itKey refers to past-the-end element in the list;
+       thus, getValue has been called although hasKey
+       produced no match */
+    assume(false);
+
+  return *_itValue;
+}
+
+template<class KeyClass, class ValueClass>
+bool Cache<KeyClass, ValueClass>::shrink(const KeyClass& key)
+{
+  /* We need to return true iff the pair with given key needed to
+     be erased during the shrinking procedure. So far, we assume no: */
+  bool result = false;
+  /* Shrink until both bounds will be met again: */
+  while (int(_key.size()) > _maxEntries || _weight > _maxWeight)
+  {
+    if (deleteLast(key)) result = true;
+  }
+  return result;
+}
+
+template<class KeyClass, class ValueClass>
+int Cache<KeyClass, ValueClass>::getMaxNumberOfEntries() const
+{
+  return _maxEntries;
+}
+
+template<class KeyClass, class ValueClass>
+int Cache<KeyClass, ValueClass>::getMaxWeight() const
+{
+  return _maxWeight;
+}
+
+template<class KeyClass, class ValueClass>
+bool Cache<KeyClass, ValueClass>::deleteLast(const KeyClass& key)
+{
+  if (_rank.size() == 0)
+  {
+    return false; /* nothing to do */
+  };
+  /* We need to perform the following (empty) loop in order to
+     obtain a forward-iterator pointing to the last entry of _rank.
+     Note: We cannot use rbegin() because we need the iterator for
+     erasing the last entry which is only implemented for forward
+     iterators by std::list. */
+   std::list<int>::iterator itRank;
+  for (itRank = _rank.begin(); itRank != _rank.end(); itRank++) { }
+  itRank--; /* Now, this forward iterator points to the last list entry. */
+  int deleteIndex = *itRank; /* index of (_key, _value)-pair with worst,
+                                i.e., highest _rank */
+  bool result = false;
+
+  /* now delete entries in _key and _value with index deleteIndex */
+  int k = 0;
+  typename std::list<KeyClass>::iterator itKey;
+  typename std::list<ValueClass>::iterator itValue = _value.begin();
+  typename std::list<int>::iterator itWeights = _weights.begin();
+  for (itKey = _key.begin(); itKey != _key.end(); itKey++)
+  {
+    if (k == deleteIndex)
+    {
+      result = (key.compare(*itKey) == 0);
+      break;
+    }
+    itValue++;
+    itWeights++;
+    k++;
+  }
+  _key.erase(itKey);
+  int deleteWeight = *itWeights;
+  _value.erase(itValue);
+  _weights.erase(itWeights);
+
+  /* adjust total weight of this cache */
+  _weight -= deleteWeight;
+
+  /* now delete last entry of _rank and decrement all those indices
+  // in _rank by 1 which are larger than deleteIndex */
+  _rank.erase(itRank);
+  for (itRank = _rank.begin(); itRank != _rank.end(); itRank++)
+  {
+    if (*itRank > deleteIndex) *itRank -= 1;
+  }
+
+  return result;
+}
+
+template<class KeyClass, class ValueClass>
+bool Cache<KeyClass, ValueClass>::put (const KeyClass& key,
+                                       const ValueClass& value)
+{
+  bool keyWasContained = false;
+  int oldIndexInKey = -1;
+  int newIndexInKey = _key.size();  /* default to enter new (key, value)-pair
+                                       is at the end of the two lists;
+                                       only used in the case
+                                       keyWasContained == false */
+  int k = 0;
+  typename std::list<KeyClass>::iterator itKey;
+  // itOldValue will later only be used in the case keyWasContained == true: */
+  typename std::list<ValueClass>::iterator itOldValue = _value.begin();
+  /* itOldWeights will later only be used in the case
+     keyWasContained == true */
+  typename std::list<int>::iterator itOldWeights = _weights.begin();
+  for (itKey = _key.begin(); itKey != _key.end(); itKey++)
+  {
+    int c = key.compare(*itKey);
+    if (c == -1)
+    {
+      newIndexInKey = k;
+      break;
+    }
+    if (c == 0)
+    {
+      keyWasContained = true;
+      oldIndexInKey = k;
+      break;
+    }
+    itOldValue++;
+    itOldWeights++;
+    k++;
+  }
+  int utility = value.getUtility();
+  int newWeight = value.getWeight();
+  k = 0;
+  typename std::list<ValueClass>::iterator itValue = _value.begin();
+  for (itValue = _value.begin(); itValue != _value.end(); itValue++)
+  {
+    if (itValue->getUtility() > utility) k++;
+  }
+  int newIndexInRank = k;
+
+  if (keyWasContained)
+  {
+    /* There was already a pair of the form (key --> *). */
+
+    /*adjusting the weight of the cache */
+    ValueClass oldValue = *itOldValue;
+    _weight += newWeight - *itOldWeights;
+
+    /* overwriting old value by argument value */
+    itOldValue = _value.erase(itOldValue);
+    itOldWeights = _weights.erase(itOldWeights);
+    ValueClass myValueCopy = value;
+    _value.insert(itOldValue, myValueCopy);
+    _weights.insert(itOldWeights, newWeight);
+
+    int oldIndexInRank = -1;
+    /* oldIndexInRank is to be the position in _rank such that
+       _rank[oldIndexInRank] == oldIndexInKey, i.e.
+       _key[_rank[oldIndexInRank]] == key: */
+    std::list<int>::iterator itRank;
+    k = 0;
+    for (itRank = _rank.begin(); itRank != _rank.end(); itRank++)
+    {
+      if (*itRank == oldIndexInKey)
+      {
+          oldIndexInRank = k;
+      }
+      k++;
+    }
+    /* Although the key stays the same, the ranking of the (key --> value)
+       pair may be completely different from before. Thus, we need to repair
+       the entries of _rank: */
+    if (oldIndexInRank < newIndexInRank)
+    {  /* first insert, then erase */
+      k = 0;
+      /* insert 'oldIndexInKey' at new position 'newIndexInRank': */
+      for (itRank = _rank.begin(); itRank != _rank.end(); itRank++)
+      {
+        if (k == newIndexInRank) break;
+        k++;
+      }
+      _rank.insert(itRank, oldIndexInKey); /* note that this may also insert
+                                              at position itRank == _rank.end(),
+                                              i.e. when above loop did not
+                                              terminate because of a 'break'
+                                              statement */
+      k = 0;
+      /* erase 'oldIndexInKey' at old position 'oldIndexInRank': */
+      for (itRank = _rank.begin(); itRank != _rank.end(); itRank++)
+      {
+        if (k == oldIndexInRank)
+        {
+          _rank.erase(itRank);
+          break;
+        }
+        k++;
+      }
+    }
+    else
+    {  /* oldIndexInRank >= newIndexInRank */
+      if (oldIndexInRank > newIndexInRank)
+      { /* first erase, then insert */
+        k = 0;
+        /* erase 'oldIndexInKey' at old position 'oldIndexInRank': */
+        for (itRank = _rank.begin(); itRank != _rank.end(); itRank++)
+        {
+          if (k == oldIndexInRank)
+          {
+            _rank.erase(itRank);
+            break;
+          }
+          k++;
+        }
+        k = 0;
+        /* insert 'oldIndexInKey' at new position 'newIndexInRank': */
+        for (itRank = _rank.begin(); itRank != _rank.end(); itRank++)
+        {
+          if (k == newIndexInRank)
+          {
+            _rank.insert(itRank, oldIndexInKey);
+            break;
+          }
+          k++;
+        }
+      }
+    }
+  }
+  else
+  {
+    /* There is no pair of the form (key --> *). We are about to insert
+       a completely new (key, value)-pair.
+       After this "else" branch, we shall have _key[newIndexInKey] = key;
+       _value[newIndexInKey] = value. Note that, after the above computation,
+       newIndexInKey contains the correct target position.
+       Let's make room for the assignment
+       _rank[newIndexInRank] := newIndexInKey: */
+    std::list<int>::iterator itRank;
+    for (itRank = _rank.begin(); itRank != _rank.end(); itRank++)
+    {
+      if (newIndexInKey <= *itRank)
+      {
+        *itRank += 1;
+      }
+    }
+    k = 0;
+    for (itRank = _rank.begin(); itRank != _rank.end(); itRank++)
+    {
+      if (k == newIndexInRank) break;
+      k++;
+    }
+    _rank.insert(itRank, newIndexInKey);
+    /* let's insert new key and new value at index newIndexInKey: */
+    itValue = _value.begin();
+    typename std::list<int>::iterator itWeights = _weights.begin();
+    k = 0;
+    for (itKey = _key.begin(); itKey != _key.end(); itKey++)
+    {
+      if (k == newIndexInKey) break;
+      itValue++;
+      itWeights++;
+      k++;
+    }
+    KeyClass myKeyCopy = key;
+    ValueClass myValueCopy = value;
+    _key.insert(itKey, myKeyCopy);
+    _value.insert(itValue, myValueCopy);
+    _weights.insert(itWeights, newWeight);
+    /* adjusting the total weight of the cache: */
+    _weight += newWeight;
+  };
+  /* We may now have to shrink the cache: */
+  bool result = shrink(key);  /* true iff shrinking deletes the
+                                 new (key, value)-pair */
+
+  assume(_rank.size() == _key.size());
+  assume(_rank.size() == _value.size());
+  return !result; /* true iff the new (key --> value) pair is
+                     actually in the cache now */
+}
+
+template<class KeyClass, class ValueClass>
+std::string Cache<KeyClass, ValueClass>::toString() const
+{
+  char h[10];
+  std::string s = "Cache:";
+  s += "\n   entries: ";
+  sprintf(h, "%d", getNumberOfEntries()); s += h;
+  s += " of at most ";
+  sprintf(h, "%d", getMaxNumberOfEntries()); s += h;
+  s += "\n   weight: ";
+  sprintf(h, "%d", getWeight()); s += h;
+  s += " of at most ";
+  sprintf(h, "%d", getMaxWeight()); s += h;
+  if (_key.size() == 0)
+  {
+    s += "\n   no pairs, i.e. cache is empty";
+  }
+  else
+  {
+    int k = 1;
+    s += "\n   (key --> value) pairs in ascending order of keys:";
+    typename std::list<KeyClass>::const_iterator itKey;
+    typename std::list<ValueClass>::const_iterator itValue = _value.begin();
+    for (itKey = _key.begin(); itKey != _key.end(); itKey++)
+    {
+      s += "\n      ";
+      sprintf(h, "%d", k); s += h;
+      s += ". ";
+      s += itKey->toString();
+      s += " --> ";
+      s += itValue->toString();
+      itValue++;
+      k++;
+    }
+    s += "\n   (key --> value) pairs in descending order of ranks:";
+    std::list<int>::const_iterator itRank;
+    int r = 1;
+    for (itRank = _rank.begin(); itRank != _rank.end(); itRank++)
+    {
+     int index = *itRank;
+     itValue = _value.begin();
+     k = 0;
+     for (itKey = _key.begin(); itKey != _key.end(); itKey++)
+     {
+         if (k == index) break;
+         k++;
+         itValue++;
+     }
+     s += "\n      ";
+     sprintf(h, "%d", r); s += h;
+     s += ". ";
+     s += itKey->toString();
+     s += " --> ";
+     s += itValue->toString();
+     r++;
+    }
+  }
+  return s;
+}
+
+template<class KeyClass, class ValueClass>
+void Cache<KeyClass, ValueClass>::print() const
+{
+  PrintS(this->toString().c_str());
+}
+
+template<class KeyClass, class ValueClass>
+Cache<KeyClass, ValueClass>::Cache() { }
+
+template<class KeyClass, class ValueClass>
+Cache<KeyClass, ValueClass>::Cache(const Cache& c)
+{
+  _rank = c._rank;
+  _value = c._value;
+  _weights = c._weights;
+  _key = c._key;
+  _weight = c._weight;
+  _maxEntries = c._maxEntries;
+  _maxWeight = c._maxWeight;
+}
+
+#endif
+/* CACHE_IMPLEMENTATION_H */
diff --git a/kernel/linear_algebra/Makefile.am b/kernel/linear_algebra/Makefile.am
new file mode 100644
index 0000000..84e78cb
--- /dev/null
+++ b/kernel/linear_algebra/Makefile.am
@@ -0,0 +1,28 @@
+ACLOCAL_AMFLAGS=-I ../../m4
+AM_CPPFLAGS=-I${top_srcdir} -I${top_builddir} -I${top_srcdir}/libpolys -I${top_builddir}/libpolys \
+${FACTORY_INCLUDES} $(OMALLOC_INCLUDES) $(RESOURCES_INCLUDES) \
+${NTL_CFLAGS} $(FLINT_CFLAGS) ${GMP_CFLAGS}
+
+noinst_LTLIBRARIES=liblinear_algebra.la
+liblinear_algebra_la_SOURCES= \
+Minor.cc MinorInterface.cc MinorProcessor.cc \
+linearAlgebra.cc eigenval.cc interpolation.cc minpoly.cc
+
+
+liblinear_algebra_la_includedir=$(includedir)/singular/kernel/linear_algebra
+liblinear_algebra_la_include_HEADERS= \
+  Minor.h MinorInterface.h MinorProcessor.h \
+  linearAlgebra.h eigenval.h interpolation.h minpoly.h \
+  Cache.h CacheImplementation.h
+
+
+
+TESTS_ENVIRONMENT = SINGULARPATH='${abs_top_builddir}/libpolys/polys/.libs:${abs_top_builddir}/factory/gftables'
+TESTS_ENVIRONMENT += SINGULAR_ROOT_DIR='${abs_top_builddir}'
+
+TESTS = test
+check_PROGRAMS = $(TESTS)
+test_SOURCES = test.cc
+test_LDADD   = liblinear_algebra.la ${builddir}/../libkernelCommon.la
+
+CLEANFILES = $(TESTS)
diff --git a/kernel/linear_algebra/Makefile.in b/kernel/linear_algebra/Makefile.in
new file mode 100644
index 0000000..fc66aa3
--- /dev/null
+++ b/kernel/linear_algebra/Makefile.in
@@ -0,0 +1,1098 @@
+# Makefile.in generated by automake 1.13.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 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@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+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@
+TESTS = test$(EXEEXT)
+check_PROGRAMS = $(am__EXEEXT_1)
+subdir = kernel/linear_algebra
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/build-aux/depcomp \
+	$(liblinear_algebra_la_include_HEADERS) \
+	$(top_srcdir)/build-aux/test-driver
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_append_compile_flags.m4 \
+	$(top_srcdir)/m4/ax_append_flag.m4 \
+	$(top_srcdir)/m4/ax_append_link_flags.m4 \
+	$(top_srcdir)/m4/ax_check_compile_flag.m4 \
+	$(top_srcdir)/m4/ax_check_link_flag.m4 \
+	$(top_srcdir)/m4/ax_compute_relative_paths.m4 \
+	$(top_srcdir)/m4/ax_normalize_path.m4 \
+	$(top_srcdir)/m4/ax_prefix_config_h.m4 \
+	$(top_srcdir)/m4/ax_pthread.m4 \
+	$(top_srcdir)/m4/ax_python_embed.m4 \
+	$(top_srcdir)/m4/ax_python_with_version.m4 \
+	$(top_srcdir)/m4/cpu-check.m4 $(top_srcdir)/m4/dbm-check.m4 \
+	$(top_srcdir)/m4/flags.m4 $(top_srcdir)/m4/flint-check.m4 \
+	$(top_srcdir)/m4/gfanlib-check.m4 \
+	$(top_srcdir)/m4/gmp-check.m4 \
+	$(top_srcdir)/m4/google-perftools.m4 \
+	$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+	$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+	$(top_srcdir)/m4/lt~obsolete.m4 \
+	$(top_srcdir)/m4/mathic-check.m4 $(top_srcdir)/m4/ntl-check.m4 \
+	$(top_srcdir)/m4/options.m4 $(top_srcdir)/m4/p-procs.m4 \
+	$(top_srcdir)/m4/polymake-check.m4 \
+	$(top_srcdir)/m4/readline-check.m4 $(top_srcdir)/configure.ac
+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 =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+liblinear_algebra_la_LIBADD =
+am_liblinear_algebra_la_OBJECTS = Minor.lo MinorInterface.lo \
+	MinorProcessor.lo linearAlgebra.lo eigenval.lo \
+	interpolation.lo minpoly.lo
+liblinear_algebra_la_OBJECTS = $(am_liblinear_algebra_la_OBJECTS)
+AM_V_lt = $(am__v_lt_ at AM_V@)
+am__v_lt_ = $(am__v_lt_ at AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 = 
+am__EXEEXT_1 = test$(EXEEXT)
+am_test_OBJECTS = test.$(OBJEXT)
+test_OBJECTS = $(am_test_OBJECTS)
+test_DEPENDENCIES = liblinear_algebra.la \
+	${builddir}/../libkernelCommon.la
+AM_V_P = $(am__v_P_ at AM_V@)
+am__v_P_ = $(am__v_P_ at AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_ at AM_V@)
+am__v_GEN_ = $(am__v_GEN_ at AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_ at AM_V@)
+am__v_at_ = $(am__v_at_ at AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+DEFAULT_INCLUDES = -I. at am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \
+	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+	$(AM_CXXFLAGS) $(CXXFLAGS)
+AM_V_CXX = $(am__v_CXX_ at AM_V@)
+am__v_CXX_ = $(am__v_CXX_ at AM_DEFAULT_V@)
+am__v_CXX_0 = @echo "  CXX     " $@;
+am__v_CXX_1 = 
+CXXLD = $(CXX)
+CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+	$(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CXXLD = $(am__v_CXXLD_ at AM_V@)
+am__v_CXXLD_ = $(am__v_CXXLD_ at AM_DEFAULT_V@)
+am__v_CXXLD_0 = @echo "  CXXLD   " $@;
+am__v_CXXLD_1 = 
+SOURCES = $(liblinear_algebra_la_SOURCES) $(test_SOURCES)
+DIST_SOURCES = $(liblinear_algebra_la_SOURCES) $(test_SOURCES)
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+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__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
+am__installdirs = "$(DESTDIR)$(liblinear_algebra_la_includedir)"
+HEADERS = $(liblinear_algebra_la_include_HEADERS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors_dummy = \
+  mgn= red= grn= lgn= blu= brg= std=; \
+  am__color_tests=no
+am__tty_colors = { \
+  $(am__tty_colors_dummy); \
+  if test "X$(AM_COLOR_TESTS)" = Xno; then \
+    am__color_tests=no; \
+  elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+    am__color_tests=yes; \
+  elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+    am__color_tests=yes; \
+  fi; \
+  if test $$am__color_tests = yes; then \
+    red=''; \
+    grn=''; \
+    lgn=''; \
+    blu=''; \
+    mgn=''; \
+    brg=''; \
+    std=''; \
+  fi; \
+}
+am__recheck_rx = ^[ 	]*:recheck:[ 	]*
+am__global_test_result_rx = ^[ 	]*:global-test-result:[ 	]*
+am__copy_in_global_log_rx = ^[ 	]*:copy-in-global-log:[ 	]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+  recheck = 1; \
+  while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+    { \
+      if (rc < 0) \
+        { \
+          if ((getline line2 < ($$0 ".log")) < 0) \
+	    recheck = 0; \
+          break; \
+        } \
+      else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+        { \
+          recheck = 0; \
+          break; \
+        } \
+      else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+        { \
+          break; \
+        } \
+    }; \
+  if (recheck) \
+    print $$0; \
+  close ($$0 ".trs"); \
+  close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+  print "fatal: making $@: " msg | "cat >&2"; \
+  exit 1; \
+} \
+function rst_section(header) \
+{ \
+  print header; \
+  len = length(header); \
+  for (i = 1; i <= len; i = i + 1) \
+    printf "="; \
+  printf "\n\n"; \
+} \
+{ \
+  copy_in_global_log = 1; \
+  global_test_result = "RUN"; \
+  while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+    { \
+      if (rc < 0) \
+         fatal("failed to read from " $$0 ".trs"); \
+      if (line ~ /$(am__global_test_result_rx)/) \
+        { \
+          sub("$(am__global_test_result_rx)", "", line); \
+          sub("[ 	]*$$", "", line); \
+          global_test_result = line; \
+        } \
+      else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+        copy_in_global_log = 0; \
+    }; \
+  if (copy_in_global_log) \
+    { \
+      rst_section(global_test_result ": " $$0); \
+      while ((rc = (getline line < ($$0 ".log"))) != 0) \
+      { \
+        if (rc < 0) \
+          fatal("failed to read from " $$0 ".log"); \
+        print line; \
+      }; \
+      printf "\n"; \
+    }; \
+  close ($$0 ".trs"); \
+  close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/   &   /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this.  Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+  --color-tests "$$am__color_tests" \
+  --enable-hard-errors "$$am__enable_hard_errors" \
+  --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test.  Creates the
+# directory for the log if needed.  Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log.  Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT.  Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup);					\
+$(am__vpath_adj_setup) $(am__vpath_adj)			\
+$(am__tty_colors);					\
+srcdir=$(srcdir); export srcdir;			\
+case "$@" in						\
+  */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;;	\
+    *) am__odir=.;; 					\
+esac;							\
+test "x$$am__odir" = x"." || test -d "$$am__odir" 	\
+  || $(MKDIR_P) "$$am__odir" || exit $$?;		\
+if test -f "./$$f"; then dir=./;			\
+elif test -f "$$f"; then dir=;				\
+else dir="$(srcdir)/"; fi;				\
+tst=$$dir$$f; log='$@'; 				\
+if test -n '$(DISABLE_HARD_ERRORS)'; then		\
+  am__enable_hard_errors=no; 				\
+else							\
+  am__enable_hard_errors=yes; 				\
+fi; 							\
+case " $(XFAIL_TESTS) " in				\
+  *[\ \	]$$f[\ \	]* | *[\ \	]$$dir$$f[\ \	]*) \
+    am__expect_failure=yes;;				\
+  *)							\
+    am__expect_failure=no;;				\
+esac; 							\
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed).  The result is saved in the shell variable
+# '$bases'.  This honors runtime overriding of TESTS and TEST_LOGS.  Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+  bases='$(TEST_LOGS)'; \
+  bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+  bases=`echo $$bases`
+RECHECK_LOGS = $(TEST_LOGS)
+AM_RECURSIVE_TARGETS = check recheck
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+  case '$@' in \
+    */*) \
+      case '$*' in \
+        */*) b='$*';; \
+          *) b=`echo '$@' | sed 's/\.log$$//'`; \
+       esac;; \
+    *) \
+      b='$*';; \
+  esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT at .log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+	$(TEST_LOG_FLAGS)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BUILTIN_LIBS = @BUILTIN_LIBS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CDDGMPCPPFLAGS = @CDDGMPCPPFLAGS@
+CDDGMPLDFLAGS = @CDDGMPLDFLAGS@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATA_DIR = @DATA_DIR@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DOC_DIR = @DOC_DIR@
+DOXYGEN = @DOXYGEN@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FACTORY_INCLUDES = @FACTORY_INCLUDES@
+FACTORY_LIBS = @FACTORY_LIBS@
+FGREP = @FGREP@
+FLINT_CFLAGS = @FLINT_CFLAGS@
+FLINT_HOME = @FLINT_HOME@
+FLINT_LIBS = @FLINT_LIBS@
+GMP_CFLAGS = @GMP_CFLAGS@
+GMP_HOME = @GMP_HOME@
+GMP_LIBS = @GMP_LIBS@
+GMP_VERSION = @GMP_VERSION@
+GREP = @GREP@
+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@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NTL_CFLAGS = @NTL_CFLAGS@
+NTL_LIBS = @NTL_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OMALLOC_INCLUDES = @OMALLOC_INCLUDES@
+OMALLOC_LIBS = @OMALLOC_LIBS@
+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@
+PKG_REQUIRE = @PKG_REQUIRE@
+PMCONFIG = @PMCONFIG@
+PM_CFLAGS = @PM_CFLAGS@
+PM_INC = @PM_INC@
+PM_LDFLAGS = @PM_LDFLAGS@
+PM_LIBS = @PM_LIBS@
+POLYMAKE_CXXFLAGS = @POLYMAKE_CXXFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LDFLAGS = @PTHREAD_LDFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
+PYTHON = @PYTHON@
+PYTHON_CSPEC = @PYTHON_CSPEC@
+PYTHON_EXECPREFIX = @PYTHON_EXECPREFIX@
+PYTHON_LSPEC = @PYTHON_LSPEC@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+RANLIB = @RANLIB@
+RESOURCES_INCLUDES = @RESOURCES_INCLUDES@
+RESOURCES_LIBS = @RESOURCES_LIBS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SINGULAR_CFLAGS = @SINGULAR_CFLAGS@
+SI_COUNTEDREF_AUTOLOAD = @SI_COUNTEDREF_AUTOLOAD@
+SI_CPU_I386 = @SI_CPU_I386@
+SI_CPU_IA64 = @SI_CPU_IA64@
+SI_CPU_PPC = @SI_CPU_PPC@
+SI_CPU_SPARC = @SI_CPU_SPARC@
+SI_CPU_X86_64 = @SI_CPU_X86_64@
+STRIP = @STRIP@
+USEPPROCSDYNAMICLD = @USEPPROCSDYNAMICLD@
+USEPPROCSDYNAMICLDFLAGS = @USEPPROCSDYNAMICLDFLAGS@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
+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@
+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@
+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@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+ACLOCAL_AMFLAGS = -I ../../m4
+AM_CPPFLAGS = -I${top_srcdir} -I${top_builddir} -I${top_srcdir}/libpolys -I${top_builddir}/libpolys \
+${FACTORY_INCLUDES} $(OMALLOC_INCLUDES) $(RESOURCES_INCLUDES) \
+${NTL_CFLAGS} $(FLINT_CFLAGS) ${GMP_CFLAGS}
+
+noinst_LTLIBRARIES = liblinear_algebra.la
+liblinear_algebra_la_SOURCES = \
+Minor.cc MinorInterface.cc MinorProcessor.cc \
+linearAlgebra.cc eigenval.cc interpolation.cc minpoly.cc
+
+liblinear_algebra_la_includedir = $(includedir)/singular/kernel/linear_algebra
+liblinear_algebra_la_include_HEADERS = \
+  Minor.h MinorInterface.h MinorProcessor.h \
+  linearAlgebra.h eigenval.h interpolation.h minpoly.h \
+  Cache.h CacheImplementation.h
+
+TESTS_ENVIRONMENT = SINGULARPATH='${abs_top_builddir}/libpolys/polys/.libs:${abs_top_builddir}/factory/gftables' \
+	SINGULAR_ROOT_DIR='${abs_top_builddir}'
+test_SOURCES = test.cc
+test_LDADD = liblinear_algebra.la ${builddir}/../libkernelCommon.la
+CLEANFILES = $(TESTS)
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .cc .lo .log .o .obj .test .test$(EXEEXT) .trs
+$(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) --foreign kernel/linear_algebra/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign kernel/linear_algebra/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-noinstLTLIBRARIES:
+	-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+	@list='$(noinst_LTLIBRARIES)'; \
+	locs=`for p in $$list; do echo $$p; done | \
+	      sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+	      sort -u`; \
+	test -z "$$locs" || { \
+	  echo rm -f $${locs}; \
+	  rm -f $${locs}; \
+	}
+
+liblinear_algebra.la: $(liblinear_algebra_la_OBJECTS) $(liblinear_algebra_la_DEPENDENCIES) $(EXTRA_liblinear_algebra_la_DEPENDENCIES) 
+	$(AM_V_CXXLD)$(CXXLINK)  $(liblinear_algebra_la_OBJECTS) $(liblinear_algebra_la_LIBADD) $(LIBS)
+
+clean-checkPROGRAMS:
+	@list='$(check_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
+
+test$(EXEEXT): $(test_OBJECTS) $(test_DEPENDENCIES) $(EXTRA_test_DEPENDENCIES) 
+	@rm -f test$(EXEEXT)
+	$(AM_V_CXXLD)$(CXXLINK) $(test_OBJECTS) $(test_LDADD) $(LIBS)
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/Minor.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/MinorInterface.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/MinorProcessor.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/eigenval.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/interpolation.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/linearAlgebra.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/minpoly.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/test.Po at am__quote@
+
+.cc.o:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+ at am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXXCOMPILE) -c -o $@ $<
+
+.cc.obj:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+ at am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.cc.lo:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+ at am__fastdepCXX_TRUE@	$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LTCXXCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+install-liblinear_algebra_la_includeHEADERS: $(liblinear_algebra_la_include_HEADERS)
+	@$(NORMAL_INSTALL)
+	@list='$(liblinear_algebra_la_include_HEADERS)'; test -n "$(liblinear_algebra_la_includedir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(liblinear_algebra_la_includedir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(liblinear_algebra_la_includedir)" || exit 1; \
+	fi; \
+	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)$(liblinear_algebra_la_includedir)'"; \
+	  $(INSTALL_HEADER) $$files "$(DESTDIR)$(liblinear_algebra_la_includedir)" || exit $$?; \
+	done
+
+uninstall-liblinear_algebra_la_includeHEADERS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(liblinear_algebra_la_include_HEADERS)'; test -n "$(liblinear_algebra_la_includedir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	dir='$(DESTDIR)$(liblinear_algebra_la_includedir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	$(am__define_uniq_tagged_files); \
+	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-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	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"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'.  Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+	rm -f $< $@
+	$(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+	@:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+	@$(am__set_TESTS_bases); \
+	am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+	redo_bases=`for i in $$bases; do \
+	              am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+	            done`; \
+	if test -n "$$redo_bases"; then \
+	  redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+	  redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+	  if $(am__make_dryrun); then :; else \
+	    rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+	  fi; \
+	fi; \
+	if test -n "$$am__remaking_logs"; then \
+	  echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+	       "recursion detected" >&2; \
+	else \
+	  am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+	fi; \
+	if $(am__make_dryrun); then :; else \
+	  st=0;  \
+	  errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+	  for i in $$redo_bases; do \
+	    test -f $$i.trs && test -r $$i.trs \
+	      || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+	    test -f $$i.log && test -r $$i.log \
+	      || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+	  done; \
+	  test $$st -eq 0 || exit 1; \
+	fi
+	@$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+	ws='[ 	]'; \
+	results=`for b in $$bases; do echo $$b.trs; done`; \
+	test -n "$$results" || results=/dev/null; \
+	all=`  grep "^$$ws*:test-result:"           $$results | wc -l`; \
+	pass=` grep "^$$ws*:test-result:$$ws*PASS"  $$results | wc -l`; \
+	fail=` grep "^$$ws*:test-result:$$ws*FAIL"  $$results | wc -l`; \
+	skip=` grep "^$$ws*:test-result:$$ws*SKIP"  $$results | wc -l`; \
+	xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+	xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+	error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+	if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+	  success=true; \
+	else \
+	  success=false; \
+	fi; \
+	br='==================='; br=$$br$$br$$br$$br; \
+	result_count () \
+	{ \
+	    if test x"$$1" = x"--maybe-color"; then \
+	      maybe_colorize=yes; \
+	    elif test x"$$1" = x"--no-color"; then \
+	      maybe_colorize=no; \
+	    else \
+	      echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+	    fi; \
+	    shift; \
+	    desc=$$1 count=$$2; \
+	    if test $$maybe_colorize = yes && test $$count -gt 0; then \
+	      color_start=$$3 color_end=$$std; \
+	    else \
+	      color_start= color_end=; \
+	    fi; \
+	    echo "$${color_start}# $$desc $$count$${color_end}"; \
+	}; \
+	create_testsuite_report () \
+	{ \
+	  result_count $$1 "TOTAL:" $$all   "$$brg"; \
+	  result_count $$1 "PASS: " $$pass  "$$grn"; \
+	  result_count $$1 "SKIP: " $$skip  "$$blu"; \
+	  result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+	  result_count $$1 "FAIL: " $$fail  "$$red"; \
+	  result_count $$1 "XPASS:" $$xpass "$$red"; \
+	  result_count $$1 "ERROR:" $$error "$$mgn"; \
+	}; \
+	{								\
+	  echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" |	\
+	    $(am__rst_title);						\
+	  create_testsuite_report --no-color;				\
+	  echo;								\
+	  echo ".. contents:: :depth: 2";				\
+	  echo;								\
+	  for b in $$bases; do echo $$b; done				\
+	    | $(am__create_global_log);					\
+	} >$(TEST_SUITE_LOG).tmp || exit 1;				\
+	mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG);			\
+	if $$success; then						\
+	  col="$$grn";							\
+	 else								\
+	  col="$$red";							\
+	  test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG);		\
+	fi;								\
+	echo "$${col}$$br$${std}"; 					\
+	echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}";	\
+	echo "$${col}$$br$${std}"; 					\
+	create_testsuite_report --maybe-color;				\
+	echo "$$col$$br$$std";						\
+	if $$success; then :; else					\
+	  echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}";		\
+	  if test -n "$(PACKAGE_BUGREPORT)"; then			\
+	    echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}";	\
+	  fi;								\
+	  echo "$$col$$br$$std";					\
+	fi;								\
+	$$success || exit 1
+
+check-TESTS:
+	@list='$(RECHECK_LOGS)';           test -z "$$list" || rm -f $$list
+	@list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+	@test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+	@set +e; $(am__set_TESTS_bases); \
+	log_list=`for i in $$bases; do echo $$i.log; done`; \
+	trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+	log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+	$(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+	exit $$?;
+recheck: all $(check_PROGRAMS)
+	@test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+	@set +e; $(am__set_TESTS_bases); \
+	bases=`for i in $$bases; do echo $$i; done \
+	         | $(am__list_recheck_tests)` || exit 1; \
+	log_list=`for i in $$bases; do echo $$i.log; done`; \
+	log_list=`echo $$log_list`; \
+	$(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+	        am__force_recheck=am--force-recheck \
+	        TEST_LOGS="$$log_list"; \
+	exit $$?
+test.log: test$(EXEEXT)
+	@p='test$(EXEEXT)'; \
+	b='test'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+.test.log:
+	@p='$<'; \
+	$(am__set_b); \
+	$(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+ at am__EXEEXT_TRUE@.test$(EXEEXT).log:
+ at am__EXEEXT_TRUE@	@p='$<'; \
+ at am__EXEEXT_TRUE@	$(am__set_b); \
+ at am__EXEEXT_TRUE@	$(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ at am__EXEEXT_TRUE@	--log-file $$b.log --trs-file $$b.trs \
+ at am__EXEEXT_TRUE@	$(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ at am__EXEEXT_TRUE@	"$$tst" $(AM_TESTS_FD_REDIRECT)
+
+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_PROGRAMS)
+	$(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(HEADERS)
+installdirs:
+	for dir in "$(DESTDIR)$(liblinear_algebra_la_includedir)"; 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:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+	-test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+	-test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+	-test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+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-checkPROGRAMS clean-generic clean-libtool \
+	clean-noinstLTLIBRARIES 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-liblinear_algebra_la_includeHEADERS
+
+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: uninstall-liblinear_algebra_la_includeHEADERS
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am clean \
+	clean-checkPROGRAMS clean-generic clean-libtool \
+	clean-noinstLTLIBRARIES cscopelist-am ctags ctags-am 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-liblinear_algebra_la_includeHEADERS 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 recheck tags tags-am uninstall \
+	uninstall-am uninstall-liblinear_algebra_la_includeHEADERS
+
+
+# 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/kernel/linear_algebra/Minor.cc b/kernel/linear_algebra/Minor.cc
new file mode 100644
index 0000000..e905abf
--- /dev/null
+++ b/kernel/linear_algebra/Minor.cc
@@ -0,0 +1,1170 @@
+
+
+
+#include <kernel/mod2.h>
+
+#include <kernel/linear_algebra/Minor.h>
+
+#include <kernel/structs.h>
+#include <kernel/polys.h>
+
+using namespace std;
+
+void MinorKey::reset()
+{
+  _numberOfRowBlocks = 0;
+  _numberOfColumnBlocks = 0;
+  delete [] _rowKey;
+  delete [] _columnKey;
+  _rowKey = 0;
+  _columnKey = 0;
+}
+
+MinorKey::MinorKey (const MinorKey& mk)
+{
+  _numberOfRowBlocks = mk.getNumberOfRowBlocks();
+  _numberOfColumnBlocks = mk.getNumberOfColumnBlocks();;
+
+  /* allocate memory for new entries in _rowKey and _columnKey */
+  _rowKey = new unsigned int[_numberOfRowBlocks];
+  _columnKey = new unsigned int[_numberOfColumnBlocks];
+
+  /* copying values from parameter arrays to private arrays */
+  for (int r = 0; r < _numberOfRowBlocks; r++)
+    _rowKey[r] = mk.getRowKey(r);
+  for (int c = 0; c < _numberOfColumnBlocks; c++)
+    _columnKey[c] = mk.getColumnKey(c);
+}
+
+MinorKey& MinorKey::operator=(const MinorKey& mk)
+{
+  if (_numberOfRowBlocks != 0)    delete [] _rowKey;
+  if (_numberOfColumnBlocks != 0) delete [] _columnKey;
+  _numberOfRowBlocks = 0;
+  _numberOfColumnBlocks = 0;
+  _rowKey = 0;
+  _columnKey = 0;
+
+  _numberOfRowBlocks = mk.getNumberOfRowBlocks();
+  _numberOfColumnBlocks = mk.getNumberOfColumnBlocks();;
+
+  /* allocate memory for new entries in _rowKey and _columnKey */
+  _rowKey = new unsigned int[_numberOfRowBlocks];
+  _columnKey = new unsigned int[_numberOfColumnBlocks];
+
+  /* copying values from parameter arrays to private arrays */
+  for (int r = 0; r < _numberOfRowBlocks; r++)
+      _rowKey[r] = mk.getRowKey(r);
+  for (int c = 0; c < _numberOfColumnBlocks; c++)
+      _columnKey[c] = mk.getColumnKey(c);
+
+  return *this;
+}
+
+void MinorKey::set(const int lengthOfRowArray, const unsigned int* rowKey,
+                   const int lengthOfColumnArray,
+                   const unsigned int* columnKey)
+{
+  /* free memory of _rowKey and _columnKey */
+  if (_numberOfRowBlocks > 0) { delete [] _rowKey; }
+  if (_numberOfColumnBlocks > 0) { delete [] _columnKey; }
+
+  _numberOfRowBlocks = lengthOfRowArray;
+  _numberOfColumnBlocks = lengthOfColumnArray;
+
+  /* allocate memory for new entries in _rowKey and _columnKey; */
+  _rowKey = new unsigned int[_numberOfRowBlocks];
+  _columnKey = new unsigned int[_numberOfColumnBlocks];
+
+  /* copying values from parameter arrays to private arrays */
+  for (int r = 0; r < _numberOfRowBlocks; r++)
+    _rowKey[r] = rowKey[r];
+  for (int c = 0; c < _numberOfColumnBlocks; c++)
+    _columnKey[c] = columnKey[c];
+}
+
+MinorKey::MinorKey(const int lengthOfRowArray,
+                   const unsigned int* const rowKey,
+                   const int lengthOfColumnArray,
+                   const unsigned int* const columnKey)
+{
+  _numberOfRowBlocks = lengthOfRowArray;
+  _numberOfColumnBlocks = lengthOfColumnArray;
+
+  /* allocate memory for new entries in _rowKey and _columnKey */
+  _rowKey = new unsigned int[_numberOfRowBlocks];
+  _columnKey = new unsigned int[_numberOfColumnBlocks];
+
+  /* copying values from parameter arrays to private arrays */
+  for (int r = 0; r < _numberOfRowBlocks; r++)
+    _rowKey[r] = rowKey[r];
+
+  for (int c = 0; c < _numberOfColumnBlocks; c++)
+    _columnKey[c] = columnKey[c];
+}
+
+MinorKey::~MinorKey()
+{
+  _numberOfRowBlocks = 0;
+  _numberOfColumnBlocks = 0;
+  delete [] _rowKey;
+  delete [] _columnKey;
+  _rowKey = 0;
+  _columnKey = 0;
+}
+
+//void MinorKey::print() const
+//{
+//  PrintS(this->toString().c_str());
+//}
+
+int MinorKey::getAbsoluteRowIndex(const int i) const
+{
+  /* This method is to return the absolute (0-based) index of the i-th
+     row encoded in \a this.
+     Example: bit-pattern of rows: "10010001101", i = 3:
+        This should yield the 0-based absolute index of the 3-rd bit
+        (counted from the right), i.e. 7. */
+
+  int matchedBits = -1; /* counter for matched bits;
+                           this needs to reach i, then we're done */
+  for (int block = 0; block < getNumberOfRowBlocks(); block ++)
+  {
+    /* start with lowest bits, i.e. in block No. 0 */
+    /* the bits in this block of 32 bits: */
+    unsigned int blockBits = getRowKey(block);
+    unsigned int shiftedBit = 1;
+    int exponent = 0;
+    /* The invariant "shiftedBit = 2^exponent" will hold throughout the
+       entire while loop. */
+    while (exponent < 32)
+    {
+      if (shiftedBit & blockBits) matchedBits++;
+      if (matchedBits == i) return exponent + (32 * block);
+      shiftedBit = shiftedBit << 1;
+      exponent++;
+    }
+  }
+  /* We should never reach this line of code. */
+  assume(false);
+  return -1;
+}
+
+int MinorKey::getAbsoluteColumnIndex(const int i) const
+{
+  /* This method is to return the absolute (0-based) index of the i-th
+     column encoded in \a this.
+     Example: bit-pattern of columns: "10010001101", i = 3:
+        This should yield the 0-based absolute index of the 3-rd bit
+        (counted from the right), i.e. 7. */
+
+  int matchedBits = -1; /* counter for matched bits; this needs to reach i,
+                           then we're done */
+  for (int block = 0; block < getNumberOfColumnBlocks(); block ++)
+  {
+    /* start with lowest bits, i.e. in block No. 0 */
+    /* the bits in this block of 32 bits: */
+    unsigned int blockBits = getColumnKey(block);
+    unsigned int shiftedBit = 1;
+    int exponent = 0;
+    /* The invariant "shiftedBit = 2^exponent" will hold throughout the
+       entire while loop. */
+    while (exponent < 32)
+    {
+      if (shiftedBit & blockBits) matchedBits++;
+      if (matchedBits == i) return exponent + (32 * block);
+      shiftedBit = shiftedBit << 1;
+      exponent++;
+    }
+  }
+  /* We should never reach this line of code. */
+  assume(false);
+  return -1;
+}
+
+void MinorKey::getAbsoluteRowIndices(int* const target) const
+{
+  int i = 0; /* index for filling the target array */
+  for (int block = 0; block < getNumberOfRowBlocks(); block ++)
+  {
+    /* start with lowest bits, i.e. in block No. 0 */
+    /* the bits in this block of 32 bits: */
+    unsigned int blockBits = getRowKey(block);
+    unsigned int shiftedBit = 1;
+    int exponent = 0;
+    /* The invariant "shiftedBit = 2^exponent" will hold throughout the
+       entire while loop. */
+    while (exponent < 32)
+    {
+      if (shiftedBit & blockBits) target[i++] = exponent + (32 * block);
+      shiftedBit = shiftedBit << 1;
+      exponent++;
+    }
+  }
+}
+
+void MinorKey::getAbsoluteColumnIndices(int* const target) const
+{
+  int i = 0; /* index for filling the target array */
+  for (int block = 0; block < getNumberOfColumnBlocks(); block ++)
+  {
+    /* start with lowest bits, i.e. in block No. 0 */
+    /* the bits in this block of 32 bits: */
+    unsigned int blockBits = getColumnKey(block);
+    unsigned int shiftedBit = 1;
+    int exponent = 0;
+    /* The invariant "shiftedBit = 2^exponent" will hold throughout the
+       entire while loop. */
+    while (exponent < 32)
+    {
+      if (shiftedBit & blockBits) target[i++] = exponent + (32 * block);
+      shiftedBit = shiftedBit << 1;
+      exponent++;
+    }
+  }
+}
+
+int MinorKey::getRelativeRowIndex(const int i) const
+{
+  /* This method is to return the relative (0-based) index of the row
+     with absolute index \c i.
+     Example: bit-pattern of rows: "10010001101", i = 7:
+        This should yield the 0-based relative index of the bit
+        corresponding to row no. 7, i.e. 3. */
+
+  int matchedBits = -1; /* counter for matched bits; this is going to
+                           contain our return value */
+  for (int block = 0; block < getNumberOfRowBlocks(); block ++)
+  {
+    /* start with lowest bits, i.e. in block No. 0 */
+    /* the bits in this block of 32 bits: */
+    unsigned int blockBits = getRowKey(block);
+    unsigned int shiftedBit = 1;
+    int exponent = 0;
+    /* The invariant "shiftedBit = 2^exponent" will hold throughout the
+       entire while loop. */
+    while (exponent < 32)
+    {
+      if (shiftedBit & blockBits) matchedBits++;
+      if (exponent + (32 * block) == i) return matchedBits;
+      shiftedBit = shiftedBit << 1;
+      exponent++;
+    }
+  }
+  /* We should never reach this line of code. */
+  assume(false);
+  return -1;
+}
+
+int MinorKey::getRelativeColumnIndex(const int i) const
+{
+  /* This method is to return the relative (0-based) index
+     of the column with absolute index \c i.
+     Example: bit-pattern of columns: "10010001101", i = 7:
+        This should yield the 0-based relative index of the bit
+        corresponding to column no. 7, i.e. 3. */
+
+  int matchedBits = -1; /* counter for matched bits; this is going
+                           to contain our return value */
+  for (int block = 0; block < getNumberOfColumnBlocks(); block ++)
+  {
+    /* start with lowest bits, i.e. in block No. 0 */
+    /* the bits in this block of 32 bits: */
+    unsigned int blockBits = getColumnKey(block);
+    unsigned int shiftedBit = 1;
+    int exponent = 0;
+    /* The invariant "shiftedBit = 2^exponent" will hold
+       throughout the entire while loop. */
+    while (exponent < 32)
+    {
+      if (shiftedBit & blockBits) matchedBits++;
+      if (exponent + (32 * block) == i) return matchedBits;
+      shiftedBit = shiftedBit << 1;
+      exponent++;
+    }
+  }
+  /* We should never reach this line of code. */
+  assume(false);
+  return -1;
+}
+
+unsigned int MinorKey::getRowKey(const int blockIndex) const
+{
+  return _rowKey[blockIndex];
+}
+
+unsigned int MinorKey::getColumnKey(const int blockIndex) const
+{
+  return _columnKey[blockIndex];
+}
+
+int MinorKey::getNumberOfRowBlocks() const
+{
+  return _numberOfRowBlocks;
+}
+
+int MinorKey::getNumberOfColumnBlocks() const
+{
+  return _numberOfColumnBlocks;
+}
+
+#ifndef SING_NDEBUG
+int MinorKey::getSetBits(const int a) const
+{
+  int b = 0;
+  if (a == 1)
+  { /* rows */
+    for (int i = 0; i < _numberOfRowBlocks; i++)
+    {
+      unsigned int m = _rowKey[i];
+      unsigned int k = 1;
+      for (int j = 0; j < 32; j++)
+      {
+        /* k = 2^j */
+        if (m & k) b++;
+        k = k << 1;
+      }
+    }
+  }
+  else
+  { /* columns */
+    for (int i = 0; i < _numberOfColumnBlocks; i++)
+    {
+      unsigned int m = _columnKey[i];
+      unsigned int k = 1;
+      for (int j = 0; j < 32; j++)
+      {
+        /* k = 2^j */
+        if (m & k) b++;
+        k = k << 1;
+      }
+    }
+  }
+  return b;
+}
+#endif
+
+MinorKey MinorKey::getSubMinorKey (const int absoluteEraseRowIndex,
+                                   const int absoluteEraseColumnIndex) const
+{
+  int rowBlock = absoluteEraseRowIndex / 32;
+  int exponent = absoluteEraseRowIndex % 32;
+  unsigned int newRowBits = getRowKey(rowBlock) - (1 << exponent);
+  int highestRowBlock = getNumberOfRowBlocks() - 1;
+  /* highestRowBlock will finally contain the highest block index with
+     non-zero bit pattern */
+  if ((newRowBits == 0) && (rowBlock == highestRowBlock))
+  {
+    /* we have thus nullified the highest block;
+       we can now forget about the highest block... */
+    highestRowBlock -= 1;
+    while (getRowKey(highestRowBlock) == 0) /* ...and maybe even some more
+                                               zero-blocks */
+      highestRowBlock -= 1;
+  }
+  /* highestRowBlock now contains the highest row block index with non-zero
+     bit pattern */
+
+  int columnBlock = absoluteEraseColumnIndex / 32;
+  exponent = absoluteEraseColumnIndex % 32;
+  unsigned int newColumnBits = getColumnKey(columnBlock) - (1 << exponent);
+  int highestColumnBlock = getNumberOfColumnBlocks() - 1;
+  /* highestColumnBlock will finally contain the highest block index with
+     non-zero bit pattern */
+  if ((newColumnBits == 0) && (columnBlock == highestColumnBlock))
+  {
+    /* we have thus nullified the highest block;
+       we can now forget about the highest block... */
+    highestColumnBlock -= 1;
+    while (getColumnKey(highestColumnBlock) == 0) /* ...and maybe even some
+                                                     more zero-blocks */
+      highestColumnBlock -= 1;
+  }
+  /* highestColumnBlock now contains the highest column block index with
+     non-zero bit pattern */
+
+  MinorKey result(highestRowBlock + 1, _rowKey, highestColumnBlock + 1,
+                  _columnKey);
+  /* This is just a copy with maybe some leading bit blocks omitted. We still
+     need to re-define the row block at index 'rowBlock' and the column block
+     at index 'columnBlock': */
+  if ((newRowBits != 0) || (rowBlock < getNumberOfRowBlocks() - 1))
+    result.setRowKey(rowBlock, newRowBits);
+  if ((newColumnBits != 0) || (columnBlock < getNumberOfColumnBlocks() - 1))
+    result.setColumnKey(columnBlock, newColumnBits);
+
+  /* let's check that the number of selected rows and columns are equal;
+     (this check is only performed in the debug version) */
+  assume(result.getSetBits(1) == result.getSetBits(2));
+
+  return result;
+}
+
+void MinorKey::setRowKey (const int blockIndex, const unsigned int rowKey)
+{
+    _rowKey[blockIndex] = rowKey;
+}
+
+void MinorKey::setColumnKey (const int blockIndex,
+                             const unsigned int columnKey)
+{
+    _columnKey[blockIndex] = columnKey;
+}
+
+int MinorKey::compare (const MinorKey& that) const
+{
+  /* compare by rowKeys first; in case of equality, use columnKeys */
+  if (this->getNumberOfRowBlocks() < that.getNumberOfRowBlocks())
+    return -1;
+  if (this->getNumberOfRowBlocks() > that.getNumberOfRowBlocks())
+    return 1;
+  /* Here, numbers of rows are equal. */
+  for (int r = this->getNumberOfRowBlocks() - 1; r >= 0; r--)
+  {
+    if (this->getRowKey(r) < that.getRowKey(r)) return -1;
+    if (this->getRowKey(r) > that.getRowKey(r)) return 1;
+  }
+  /* Here, this and that encode ecaxtly the same sets of rows.
+     Now, we take a look at the columns. */
+  if (this->getNumberOfColumnBlocks() < that.getNumberOfColumnBlocks())
+    return -1;
+  if (this->getNumberOfColumnBlocks() > that.getNumberOfColumnBlocks())
+    return 1;
+  /* Here, numbers of columns are equal. */
+  for (int c = this->getNumberOfColumnBlocks() - 1; c >= 0; c--)
+  {
+    if (this->getColumnKey(c) < that.getColumnKey(c)) return -1;
+    if (this->getColumnKey(c) > that.getColumnKey(c)) return 1;
+  }
+  /* Here, this and that encode exactly the same sets of rows and columns. */
+  return 0;
+}
+
+/* just to make the compiler happy;
+   this method should never be called */
+bool MinorKey::operator==(const MinorKey& mk) const
+{
+  assume(false);
+  return this->compare(mk) == 0;
+}
+
+/* just to make the compiler happy;
+   this method should never be called */
+bool MinorKey::operator<(const MinorKey& mk) const
+{
+  assume(false);
+  return this->compare(mk) == -1;
+}
+
+void MinorKey::selectFirstRows (const int k, const MinorKey& mk)
+{
+  int hitBits = 0;      /* the number of bits we have hit; in the end, this
+                           has to be equal to k, the dimension of the minor */
+  int blockIndex = -1;  /* the index of the current int in mk */
+  unsigned int highestInt = 0;  /* the new highest block of this MinorKey */
+  /* We determine which ints of mk we can copy. Their indices will be
+     0, 1, ..., blockIndex - 1. And highestInt is going to capture the highest
+     int (which may be only a portion of the corresponding int in mk.
+     We loop until hitBits = k: */
+  while (hitBits < k)
+  {
+    blockIndex++;
+    highestInt = 0;
+    unsigned int currentInt = mk.getRowKey(blockIndex);
+    unsigned int shiftedBit = 1;
+    int exponent = 0;
+    /* invariant in the loop: shiftedBit = 2^exponent */
+    while (exponent < 32 && hitBits < k)
+    {
+      if (shiftedBit & currentInt)
+      {
+        highestInt += shiftedBit;
+        hitBits++;
+      }
+      shiftedBit = shiftedBit << 1;
+      exponent++;
+    }
+  }
+  /* free old memory */
+  delete [] _rowKey; _rowKey = 0;
+  _numberOfRowBlocks = blockIndex + 1;
+  /* allocate memory for new entries in _rowKey; */
+  _rowKey = new unsigned int[_numberOfRowBlocks];
+  /* copying values from mk to this MinorKey */
+  for (int r = 0; r < blockIndex; r++)
+    _rowKey[r] = mk.getRowKey(r);
+  _rowKey[blockIndex] = highestInt;
+}
+
+void MinorKey::selectFirstColumns (const int k, const MinorKey& mk)
+{
+  int hitBits = 0;      /* the number of bits we have hit; in the end, this
+                           has to be equal to k, the dimension of the minor */
+  int blockIndex = -1;  /* the index of the current int in mk */
+  unsigned int highestInt = 0;  /* the new highest block of this MinorKey */
+  /* We determine which ints of mk we can copy. Their indices will be
+     0, 1, ..., blockIndex - 1. And highestInt is going to capture the highest
+     int (which may be only a portion of the corresponding int in mk.
+     We loop until hitBits = k: */
+  while (hitBits < k)
+  {
+    blockIndex++;
+    highestInt = 0;
+    unsigned int currentInt = mk.getColumnKey(blockIndex);
+    unsigned int shiftedBit = 1;
+    int exponent = 0;
+    /* invariant in the loop: shiftedBit = 2^exponent */
+    while (exponent < 32 && hitBits < k)
+    {
+      if (shiftedBit & currentInt)
+      {
+        highestInt += shiftedBit;
+        hitBits++;
+      }
+      shiftedBit = shiftedBit << 1;
+      exponent++;
+    }
+  }
+  /* free old memory */
+  delete [] _columnKey; _columnKey = 0;
+  _numberOfColumnBlocks = blockIndex + 1;
+  /* allocate memory for new entries in _columnKey; */
+  _columnKey = new unsigned int[_numberOfColumnBlocks];
+  /*  copying values from mk to this MinorKey */
+  for (int c = 0; c < blockIndex; c++)
+    _columnKey[c] = mk.getColumnKey(c);
+  _columnKey[blockIndex] = highestInt;
+}
+
+bool MinorKey::selectNextRows (const int k, const MinorKey& mk)
+{
+  /* We need to compute the set of k rows which must all be contained in mk.
+     AND: This set must be the least possible of this kind which is larger
+          than the currently encoded set of rows. (Here, '<' is w.r.t. to the
+          natural ordering on multi-indices.
+     Example: mk encodes the rows according to the bit pattern 11010111,
+              k = 3, this MinorKey encodes 10010100. Then, the method must
+              shift the set of rows in this MinorKey to 11000001 (, and
+              return true). */
+
+  /* The next two variables will finally name a row which is
+     (1) currently not yet among the rows in this MinorKey, but
+     (2) among the rows in mk, and
+     (3) which is "higher" than the lowest row in this MinorKey, and
+     (4) which is the lowest possible choice such that (1) - (3) hold.
+     If we should not be able to find such a row, then there is no next
+     subset of rows. In this case, the method will return false; otherwise
+     always true. */
+  int newBitBlockIndex = 0;        /* the block index of the bit */
+  unsigned int newBitToBeSet = 0;  /* the bit as 2^e, where 0 <= e <= 31 */
+
+  /* number of ints (representing rows) in this MinorKey: */
+  int blockCount = this->getNumberOfRowBlocks();
+  /* for iterating along the blocks of mk: */
+  int mkBlockIndex = mk.getNumberOfRowBlocks();
+
+  int hitBits = 0;    /* the number of bits we have hit */
+  int bitCounter = 0; /* for storing the number of bits hit before a
+                         specific moment; see below */
+  while (hitBits < k)
+  {
+    mkBlockIndex--;
+    unsigned int currentInt = mk.getRowKey(mkBlockIndex);
+    unsigned int shiftedBit = 1 << 31; /* initially, this equals 2^31, i.e.
+                                          the highest bit */
+    while (hitBits < k && shiftedBit > 0)
+    {
+      if ((blockCount - 1 >= mkBlockIndex) &&
+        (shiftedBit & this->getRowKey(mkBlockIndex))) hitBits++;
+      else if (shiftedBit & currentInt)
+      {
+        newBitToBeSet = shiftedBit;
+        newBitBlockIndex = mkBlockIndex;
+        bitCounter = hitBits; /* So, whenever we set newBitToBeSet, we want
+                                 to remember the momentary number of hit
+                                 bits. This will later be needed; see below. */
+      }
+      shiftedBit = shiftedBit >> 1;
+    }
+  }
+  if (newBitToBeSet == 0)
+  {
+    return false;
+  }
+  else
+  {
+    /* Note that the following must hold when reaching this line of code:
+       (1) The row with bit newBitToBeSet in this->getRowKey(newBitBlockIndex)
+           is currently not among the rows in this MinorKey, but
+       (2) it is among the rows in mk, and
+       (3) it is higher than the lowest row in this MinorKey, and
+       (4) it is the lowest possible choice such that (1) - (3) hold.
+       In the above example, we would reach this line with
+       newBitToBeSet == 2^6 and bitCounter == 1 (resulting from the bit 2^7).
+       */
+
+    if (blockCount - 1 < newBitBlockIndex)
+    { /* In this case, _rowKey is too small. */
+      /* free old memory */
+      delete [] _rowKey; _rowKey = 0;
+      _numberOfRowBlocks = newBitBlockIndex + 1;
+      /* allocate memory for new entries in _rowKey; */
+      _rowKey = new unsigned int[_numberOfRowBlocks];
+      /* initializing entries to zero */
+        for (int r = 0; r < _numberOfRowBlocks; r++) _rowKey[r] = 0;
+    }
+    else
+    {
+      /* We need to delete all bits in _rowKey[newBitBlockIndex] that are
+         below newBitToBeSet: */
+      unsigned int anInt = this->getRowKey(newBitBlockIndex);
+      unsigned int deleteBit = newBitToBeSet >> 1; // in example: = 2^5
+      while (deleteBit > 0)
+      {
+        if (anInt & deleteBit) anInt -= deleteBit;
+        deleteBit = deleteBit >> 1;
+      };
+      _rowKey[newBitBlockIndex] = anInt;
+      /* ...and we delete all entries in _rowKey[i] for
+         0 <= i < newBitBlockIndex */
+      for (int i = 0; i < newBitBlockIndex; i++)
+        _rowKey[i] = 0;
+    }
+
+    /* We have now deleted all bits from _rowKey[...] below the bit
+       2^newBitToBeSet.
+       In the example we shall have at this point: _rowKey[...] = 10000000.
+       Now let's set the new bit: */
+    _rowKey[newBitBlockIndex] += newBitToBeSet;
+    /* in the example: _rowKey[newBitBlockIndex] = 11000000 */
+    bitCounter++; /* This is now the number of correct bits in _rowKey[...];
+                     i.e. in the example this will be equal to 2. */
+
+    /* Now we only need to fill _rowKey[...] with the lowest possible bits
+       until it consists of exactly k bits. (We know that we need to set
+       exactly (k - bitCounter) additional bits.) */
+    mkBlockIndex = -1;
+    while (bitCounter < k)
+    {
+      mkBlockIndex++;
+      unsigned int currentInt = mk.getRowKey(mkBlockIndex);
+      unsigned int shiftedBit = 1;
+      int exponent = 0;
+      /* invariant: shiftedBit = 2^exponent */
+      while (bitCounter < k && exponent < 32)
+      {
+        if (shiftedBit & currentInt)
+        {
+          _rowKey[mkBlockIndex] += shiftedBit;
+          bitCounter++;
+        };
+        shiftedBit = shiftedBit << 1;
+        exponent++;
+      }
+    };
+    /* in the example, we shall obtain _rowKey[...] = 11000001 */
+    return true;
+  }
+}
+
+bool MinorKey::selectNextColumns (const int k, const MinorKey& mk)
+{
+  /* We need to compute the set of k columns which must all be contained in mk.
+     AND: This set must be the least possible of this kind which is larger
+          than the currently encoded set of columns. (Here, '<' is w.r.t. to
+          the natural ordering on multi-indices.
+     Example: mk encodes the columns according to the bit pattern 11010111,
+              k = 3, this MinorKey encodes 10010100. Then, the method must
+              shift the set of columns in this MinorKey to 11000001 (, and
+              return true). */
+
+  /* The next two variables will finally name a column which is
+     (1) currently not yet among the columns in this MinorKey, but
+     (2) among the columns in mk, and
+     (3) which is "higher" than the lowest column in this MinorKey, and
+     (4) which is the lowest possible choice such that (1) - (3) hold.
+     If we should not be able to find such a column, then there is no next
+     subset of columns. In this case, the method will return false; otherwise
+     always true. */
+  int newBitBlockIndex = 0;        /* the block index of the bit */
+  unsigned int newBitToBeSet = 0;  /* the bit as 2^e, where 0 <= e <= 31 */
+
+   /* number of ints (representing columns) in this MinorKey: */
+  int blockCount = this->getNumberOfColumnBlocks();
+  /* for iterating along the blocks of mk: */
+  int mkBlockIndex = mk.getNumberOfColumnBlocks();
+
+  int hitBits = 0;    /* the number of bits we have hit */
+  int bitCounter = 0; /* for storing the number of bits hit before a specific
+                         moment; see below */
+  while (hitBits < k)
+  {
+    mkBlockIndex--;
+    unsigned int currentInt = mk.getColumnKey(mkBlockIndex);
+    unsigned int shiftedBit = 1 << 31; /* initially, this equals 2^31, i.e.
+                                          the highest bit */
+    while (hitBits < k && shiftedBit > 0)
+    {
+      if ((blockCount - 1 >= mkBlockIndex) &&
+        (shiftedBit & this->getColumnKey(mkBlockIndex))) hitBits++;
+      else if (shiftedBit & currentInt)
+      {
+        newBitToBeSet = shiftedBit;
+        newBitBlockIndex = mkBlockIndex;
+        bitCounter = hitBits; /* So, whenever we set newBitToBeSet, we want to
+                                 remember the momentary number of hit bits.
+                                 This will later be needed; see below. */
+      }
+      shiftedBit = shiftedBit >> 1;
+    }
+  }
+  if (newBitToBeSet == 0)
+  {
+    return false;
+  }
+  else
+  {
+    /* Note that the following must hold when reaching this line of code:
+       (1) The column with bit newBitToBeSet in
+           this->getColumnKey(newBitBlockIndex) is currently not among the
+           columns in this MinorKey, but
+       (2) it is among the columns in mk, and
+       (3) it is higher than the lowest columns in this MinorKey, and
+       (4) it is the lowest possible choice such that (1) - (3) hold.
+       In the above example, we would reach this line with
+       newBitToBeSet == 2^6 and bitCounter == 1 (resulting from the bit 2^7).
+       */
+
+    if (blockCount - 1 < newBitBlockIndex)
+    { /* In this case, _columnKey is too small. */
+        /* free old memory */
+        delete [] _columnKey; _columnKey = 0;
+        _numberOfColumnBlocks = newBitBlockIndex + 1;
+        /* allocate memory for new entries in _columnKey; */
+        _columnKey = new unsigned int[_numberOfColumnBlocks];
+        /* initializing entries to zero */
+        for (int c = 0; c < _numberOfColumnBlocks; c++) _columnKey[c] = 0;
+    }
+    else
+    {
+      /* We need to delete all bits in _columnKey[newBitBlockIndex] that are
+         below newBitToBeSet: */
+      unsigned int anInt = this->getColumnKey(newBitBlockIndex);
+      unsigned int deleteBit = newBitToBeSet >> 1; /* in example: = 2^5 */
+      while (deleteBit > 0)
+      {
+        if (anInt & deleteBit) anInt -= deleteBit;
+        deleteBit = deleteBit >> 1;
+      };
+      _columnKey[newBitBlockIndex] = anInt;
+      /* ...and we delete all entries in _columnKey[i] fo
+         0 <= i < newBitBlockIndex */
+      for (int i = 0; i < newBitBlockIndex; i++)
+        _columnKey[i] = 0;
+    }
+    /* We have now deleted all bits from _columnKey[...] below the bit
+       2^newBitToBeSet. In the example we shall have at this point:
+       _columnKey[...] = 10000000. Now let's set the new bit: */
+    _columnKey[newBitBlockIndex] += newBitToBeSet;
+    /* in the example: _columnKey[newBitBlockIndex] = 11000000 */
+    bitCounter++; /* This is now the number of correct bits in
+                     _columnKey[...]; i.e. in the example this will be equal
+                     to 2. */
+
+    /* Now we only need to fill _columnKey[...] with the lowest possible bits
+       until it consists of exactly k bits. (We know that we need to set
+       exactly (k - bitCounter) additional bits.) */
+    mkBlockIndex = -1;
+    while (bitCounter < k)
+    {
+      mkBlockIndex++;
+      unsigned int currentInt = mk.getColumnKey(mkBlockIndex);
+      unsigned int shiftedBit = 1;
+      int exponent = 0;
+      /* invariant: shiftedBit = 2^exponent */
+      while (bitCounter < k && exponent < 32)
+      {
+        if (shiftedBit & currentInt)
+        {
+          _columnKey[mkBlockIndex] += shiftedBit;
+          bitCounter++;
+        };
+        shiftedBit = shiftedBit << 1;
+        exponent++;
+      }
+    };
+    /* in the example, we shall obtain _columnKey[...] = 11000001 */
+    return true;
+  }
+}
+
+string MinorKey::toString() const
+{ return ""; }
+/*
+  string t;
+  string s = "(";
+  unsigned int z = 0;
+  for (int r = this->getNumberOfRowBlocks() - 1; r >= 0; r--)
+  {
+    t = "";
+    z = this->getRowKey(r);
+    while (z != 0)
+    {
+      if ((z % 2) != 0) t = "1" + t; else t = "0" + t;
+      z = z / 2;
+    }
+    if (r < this->getNumberOfRowBlocks() - 1)
+      t = string(32 - t.length(), '0') + t;
+    s += t;
+  }
+  s += ", ";
+  for (int c = this->getNumberOfColumnBlocks() - 1; c >= 0; c--)
+  {
+    t = "";
+    z = this->getColumnKey(c);
+    while (z != 0)
+    {
+      if ((z % 2) != 0) t = "1" + t; else t = "0" + t;
+      z = z / 2;
+    }
+    if (c < this->getNumberOfColumnBlocks() - 1)
+      t = string(32 - t.length(), '0') + t;
+    s += t;
+  }
+  s += ")";
+  return s;
+}
+*/
+
+int MinorValue::g_rankingStrategy = -1;
+
+int MinorValue::getWeight () const
+{
+  assume(false);  /* must be overridden in derived classes */
+  return 0;
+}
+
+/* just to make the compiler happy;
+   this method should never be called */
+bool MinorValue::operator==(const MinorValue& mv) const
+{
+  assume(false);
+  return (this == &mv);  /* compare addresses of both objects */
+}
+
+string MinorValue::toString () const
+{
+  assume(false);  /* must be overridden in derived classes */
+  return "";
+}
+
+/* just to make the compiler happy;
+   this method should never be called */
+bool MinorValue::operator<(const MinorValue& mv) const
+{
+  assume(false);
+  return (this < &mv);  /* compare addresses of both objects */
+}
+
+int MinorValue::getRetrievals() const
+{
+  return _retrievals;
+}
+
+void MinorValue::incrementRetrievals()
+{
+  _retrievals++;
+}
+
+int MinorValue::getPotentialRetrievals() const
+{
+  return _potentialRetrievals;
+}
+
+int MinorValue::getMultiplications() const
+{
+  return _multiplications;
+}
+
+int MinorValue::getAdditions() const
+{
+  return _additions;
+}
+
+int MinorValue::getAccumulatedMultiplications() const
+{
+  return _accumulatedMult;
+}
+
+int MinorValue::getAccumulatedAdditions() const
+{
+  return _accumulatedSum;
+}
+
+void MinorValue::print() const
+{
+  PrintS(this->toString().c_str());
+}
+
+
+void MinorValue::SetRankingStrategy (const int rankingStrategy)
+{
+  g_rankingStrategy = rankingStrategy;
+  //if (g_rankingStrategy == 6) : rand() is never used
+  //{
+  //  /* initialize the random generator with system time */
+  //  srand ( time(NULL) );
+  //}
+}
+
+int MinorValue::GetRankingStrategy()
+{
+  return g_rankingStrategy;
+}
+
+/* this is for generically accessing the rank measure regardless of
+   which strategy has been set */
+int MinorValue::getUtility () const
+{
+  switch (this->GetRankingStrategy())
+  {
+    case 1: return this->rankMeasure1();
+    case 2: return this->rankMeasure2();
+    case 3: return this->rankMeasure3();
+    case 4: return this->rankMeasure4();
+    case 5: return this->rankMeasure5();
+    default: return this->rankMeasure1();
+  }
+}
+
+/* here are some sensible caching strategies: */
+int MinorValue::rankMeasure1 () const
+{
+  /* number of actually performed multiplications */
+  return this->getMultiplications();
+}
+
+int MinorValue::rankMeasure2 () const
+{
+  /* accumulated number of performed multiplications, i.e. all including
+     nested multiplications */
+  return this->getAccumulatedMultiplications();
+}
+
+int MinorValue::rankMeasure3 () const
+{
+  /* number of performed multiplications, weighted with the ratio of
+     not yet performed retrievals over the maximal number of retrievals */
+  return this->getMultiplications()
+         * (this->getPotentialRetrievals()
+         - this->getRetrievals())
+         / this->getPotentialRetrievals();
+}
+
+int MinorValue::rankMeasure4 () const
+{
+  /* number of performed multiplications,
+     multiplied with the number of not yet performed retrievals */
+  return this->getMultiplications()
+         * (this->getPotentialRetrievals()
+         - this->getRetrievals());
+}
+
+int MinorValue::rankMeasure5 () const
+{
+  /* number of not yet performed retrievals;
+     tends to cache entries longer when they are going to be retrieved more
+     often in the future */
+  return this->getPotentialRetrievals() - this->getRetrievals();
+}
+
+int IntMinorValue::getWeight () const
+{
+  /* put measure for size of MinorValue here, i.e. number of monomials in
+     polynomial; so far, we use the accumulated number of multiplications
+     (i.e., including all nested ones) to simmulate the size of a polynomial */
+  return _accumulatedMult;
+}
+
+IntMinorValue::IntMinorValue (const int result, const int multiplications,
+                              const int additions,
+                              const int accumulatedMultiplications,
+                              const int accumulatedAdditions,
+                              const int retrievals,
+                              const int potentialRetrievals)
+{
+  _result = result;
+  _multiplications = multiplications;
+  _additions = additions;
+  _accumulatedMult = accumulatedMultiplications;
+  _accumulatedSum = accumulatedAdditions;
+  _potentialRetrievals = potentialRetrievals;
+  _retrievals = retrievals;
+}
+
+IntMinorValue::IntMinorValue ()
+{
+  _result = -1;
+  _multiplications = -1;
+  _additions = -1;
+  _accumulatedMult = -1;
+  _accumulatedSum = -1;
+  _potentialRetrievals = -1;
+  _retrievals = -1;
+}
+
+IntMinorValue::~IntMinorValue()
+{
+}
+
+int IntMinorValue::getResult() const
+{
+  return _result;
+}
+
+string IntMinorValue::toString () const
+{
+  char h[10];
+
+  /* Let's see whether a cache has been used to compute this MinorValue: */
+  bool cacheHasBeenUsed = true;
+  if (this->getRetrievals() == -1) cacheHasBeenUsed = false;
+
+  sprintf(h, "%d", this->getResult());
+  string s = h;
+  s += " [retrievals: ";
+  if (cacheHasBeenUsed) { sprintf(h, "%d", this->getRetrievals()); s += h; }
+  else s += "/";
+  s += " (of ";
+  if (cacheHasBeenUsed)
+  {
+    sprintf(h, "%d", this->getPotentialRetrievals());
+    s += h;
+  }
+  else s += "/";
+  s += "), *: ";
+  sprintf(h, "%d", this->getMultiplications()); s += h;
+  s += " (accumulated: ";
+  sprintf(h, "%d", this->getAccumulatedMultiplications()); s += h;
+  s += "), +: ";
+  sprintf(h, "%d", this->getAdditions()); s += h;
+  s += " (accumulated: ";
+  sprintf(h, "%d", this->getAccumulatedAdditions()); s += h;
+  s += "), rank: ";
+  if (cacheHasBeenUsed) { sprintf(h, "%d", this->getUtility()); s += h; }
+  else s += "/";
+  s += "]";
+  return s;
+}
+
+IntMinorValue::IntMinorValue (const IntMinorValue& mv)
+{
+  _result = mv.getResult();
+  _retrievals = mv.getRetrievals();
+  _potentialRetrievals = mv.getPotentialRetrievals();
+  _multiplications = mv.getMultiplications();
+  _additions = mv.getAdditions();
+  _accumulatedMult = mv.getAccumulatedMultiplications();
+  _accumulatedSum = mv.getAccumulatedAdditions();
+}
+
+PolyMinorValue::PolyMinorValue (const poly result, const int multiplications,
+                                const int additions,
+                                const int accumulatedMultiplications,
+                                const int accumulatedAdditions,
+                                const int retrievals,
+                                const int potentialRetrievals)
+{
+  _result = pCopy(result);
+  _multiplications = multiplications;
+  _additions = additions;
+  _accumulatedMult = accumulatedMultiplications;
+  _accumulatedSum = accumulatedAdditions;
+  _potentialRetrievals = potentialRetrievals;
+  _retrievals = retrievals;
+}
+
+PolyMinorValue::PolyMinorValue ()
+{
+  _result = NULL;
+  _multiplications = -1;
+  _additions = -1;
+  _accumulatedMult = -1;
+  _accumulatedSum = -1;
+  _potentialRetrievals = -1;
+  _retrievals = -1;
+}
+
+PolyMinorValue::~PolyMinorValue()
+{
+  p_Delete(&_result, currRing);
+}
+
+poly PolyMinorValue::getResult() const
+{
+  return _result;
+}
+
+int PolyMinorValue::getWeight () const
+{
+  /* put measure for size of PolyMinorValue here, e.g. the number of monomials
+     in the cached polynomial */
+  return pLength(_result); // the number of monomials in the polynomial
+}
+
+string PolyMinorValue::toString () const
+{
+  char h[20];
+
+  /* Let's see whether a cache has been used to compute this MinorValue: */
+  bool cacheHasBeenUsed = true;
+  if (this->getRetrievals() == -1) cacheHasBeenUsed = false;
+
+  string s = pString(_result);
+  s += " [retrievals: ";
+  if (cacheHasBeenUsed) { sprintf(h, "%d", this->getRetrievals()); s += h; }
+  else s += "/";
+  s += " (of ";
+  if (cacheHasBeenUsed)
+  {
+    sprintf(h, "%d", this->getPotentialRetrievals());
+    s += h;
+  }
+  else s += "/";
+  s += "), *: ";
+  sprintf(h, "%d", this->getMultiplications()); s += h;
+  s += " (accumulated: ";
+  sprintf(h, "%d", this->getAccumulatedMultiplications()); s += h;
+  s += "), +: ";
+  sprintf(h, "%d", this->getAdditions()); s += h;
+  s += " (accumulated: ";
+  sprintf(h, "%d", this->getAccumulatedAdditions()); s += h;
+  s += "), rank: ";
+  if (cacheHasBeenUsed) { sprintf(h, "%d", this->getUtility()); s += h; }
+  else s += "/";
+  s += "]";
+  return s;
+}
+
+PolyMinorValue::PolyMinorValue (const PolyMinorValue& mv)
+{
+  _result = pCopy(mv.getResult());
+  _retrievals = mv.getRetrievals();
+  _potentialRetrievals = mv.getPotentialRetrievals();
+  _multiplications = mv.getMultiplications();
+  _additions = mv.getAdditions();
+  _accumulatedMult = mv.getAccumulatedMultiplications();
+  _accumulatedSum = mv.getAccumulatedAdditions();
+}
+
+void PolyMinorValue::operator= (const PolyMinorValue& mv)
+{
+  if (_result != mv.getResult()) pDelete(&_result);
+  _result = pCopy(mv.getResult());
+  _retrievals = mv.getRetrievals();
+  _potentialRetrievals = mv.getPotentialRetrievals();
+  _multiplications = mv.getMultiplications();
+  _additions = mv.getAdditions();
+  _accumulatedMult = mv.getAccumulatedMultiplications();
+  _accumulatedSum = mv.getAccumulatedAdditions();
+}
diff --git a/kernel/linear_algebra/Minor.h b/kernel/linear_algebra/Minor.h
new file mode 100644
index 0000000..2127c2d
--- /dev/null
+++ b/kernel/linear_algebra/Minor.h
@@ -0,0 +1,869 @@
+#ifndef MINOR_H
+#define MINOR_H
+
+// #include <assert.h>
+#include <string>
+
+struct spolyrec; typedef struct spolyrec polyrec; typedef polyrec* poly;
+struct ip_sring; typedef struct ip_sring* ring; typedef struct ip_sring const* const_ring;
+
+struct sip_sideal; typedef struct sip_sideal *       ideal;
+
+// using namespace std;
+
+/*! \class MinorKey
+    \brief Class MinorKey can be used for representing keys in a cache for
+    sub-determinantes; see class Cache.
+
+    As such, it is a realization of the template class KeyClass which is used
+    in the declaration of class Cache. Following the documentation of class
+    Cache, we need to implement at least the methods:<br>
+    <c>bool MinorKey::operator< (const MinorKey& key),</c><br>
+    <c>bool MinorKey::operator== (const MinorKey& key),</c><br>
+    MinorKey uses two private arrays of ints \c _rowKey and \c _columnKey to
+    encode rows and columns of a pre-defined matrix. Semantically, the row
+    indices and column indices form the key for caching the value of the
+    corresponding minor.<br>
+    More concretely, let us assume that the pre-defined matrix has
+    <em>32*R+r, r<32,</em> rows and <em>32*C+c, c<32,</em> columns. All row
+    indices can then be captured using R+1 ints, since an int is a
+    32-bit-number (regardless of the platform). The analog holds for the
+    columns. Consequently, each instance of MinorKey encodes the sets of rows
+    and columns which shall belong to the minor of interest (and which shall
+    not).<br>
+    Example: The \c _rowKey with \c _rowKey[1] = 0...011 and
+    \c _rowKey[0] = 0...01101 encodes the rows with indices 33, 32, 3, 2,
+    and 0.
+    \author Frank Seelisch, http://www.mathematik.uni-kl.de/~seelisch
+*/
+class MinorKey
+{
+  private:
+     /**
+     * a pointer to an array[0..k-1] of ints, capturing k*32 bits for
+     * determining which rows of a pre-defined matrix shall belong to the
+     * minor of interest;
+     * for i < j, _rowKey[i] holds lower bits than _rowKey[j]
+     */
+     unsigned int* _rowKey;
+
+     /**
+     * a pointer to an array[0..k-1] of ints, capturing k*32 bits for
+     * determining which columns of a pre-defined matrix shall belong to the
+     * minor of interest;
+     * for i < j, _columnKey[i] holds lower bits than _columnKey[j]
+     */
+     unsigned int* _columnKey;
+
+     /**
+     * the number of ints (i.e. 32-bit-numbers) we need to encode the set of
+     * rows;
+     * If the higest row index is 70, we need 3 blocks of 32 bits to also
+     * encode the 70th bit.
+     */
+     int _numberOfRowBlocks;
+
+     /**
+     * the number of ints (i.e. 32-bit-numbers) we need to encode the set of
+     * columns;
+     * If the higest column index is 70, we need 3 blocks of 32 bits to also
+     * encode the 70th bit.
+     */
+     int _numberOfColumnBlocks;
+
+     /**
+     * Inlined accessor of blockIndex-th element of _rowKey.
+     * @param blockIndex the index of the int to be retrieved
+     * @return an entry of _rowKey
+     */
+     unsigned int getRowKey (const int blockIndex) const;
+
+     /**
+     * Accessor of blockIndex-th element of _columnKey.
+     * @param blockIndex the index of the int to be retrieved
+     * @return an entry of _columnKey
+     */
+     unsigned int getColumnKey (const int blockIndex) const;
+
+     /**
+     * A method for setting the blockIndex-th element of _rowKey.
+     * @param blockIndex the index of the int to be retrieved
+     * @param rowKey the row key to be set
+     */
+     void setRowKey (const int blockIndex, const unsigned int rowKey);
+
+     /**
+     * A method for setting the blockIndex-th element of _columnKey.
+     * @param blockIndex the index of the int to be retrieved
+     * @param columnKey the column key to be set
+     */
+     void setColumnKey (const int blockIndex, const unsigned int columnKey);
+
+     /**
+     * Accessor of _numberOfRowBlocks.
+     * @return the number of 32-bit-blocks needed to encode all rows of the
+     *         minor as a sequence of bits
+     */
+     int getNumberOfRowBlocks () const;
+
+     /**
+     * Accessor of _numberOfColumnBlocks.
+     * @return the number of 32-bit-blocks needed to encode all columns of
+     *         the minor as a sequence of bits
+     */
+     int getNumberOfColumnBlocks () const;
+
+     /**
+     * A method for deleting all entries of _rowKey and _columnKey.
+     */
+     void reset();
+
+     #ifndef SING_NDEBUG
+     /**
+     * A method for counting the number of set bits.
+     * For a == 1, the number of set bits in _rowKey will be counted;
+     * for a == 2 in _columnKey.
+     * This method will only be called in the debug version.
+     * @param a for controlling whether to count in _rowKey or _columnKey
+     * @return the number of set bits either in _rowKey or _columnKey
+     */
+     int getSetBits (const int a) const;
+     #endif
+
+     /**
+     * For letting MinorProcessor see the private methods of this class.
+     */
+     friend class MinorProcessor;
+  public:
+     /**
+     * A constructor for class MinorKey.
+     * The ints given in the array rowKey encode all rows which shall belong
+     * to the minor. Each array entry encodes 32 rows, e.g. the i-th array
+     * entry 0...01101 encodes the rows with absolute matrix row indices
+     * 3+i*32, 2+i*32, and 0+i*32. Analog for columns.
+     * @param lengthOfRowArray the length of the array rowKey
+     * @param rowKey a pointer to an array of ints encoding the set of rows of
+     *        the minor
+     * @param lengthOfColumnArray the length of the array columnKey
+     * @param columnKey a pointer to an array of ints encoding the set of
+     +        columns of the minor
+     */
+     MinorKey (const int lengthOfRowArray = 0,
+               const unsigned int* const rowKey = 0,
+               const int lengthOfColumnArray = 0,
+               const unsigned int* const columnKey = 0);
+
+     /**
+     * A setter method for class MinorKey.
+     * Just like the constructor of this class, this method will set all
+     * private fields according to the given parameters. Note that this method
+     * will change the given instance of MinorKey.
+     * @param lengthOfRowArray the length of the array rowKey
+     * @param rowKey a pointer to an array of ints encoding the set of rows of
+     * the minor
+     * @param lengthOfColumnArray the length of the array columnKey
+     * @param columnKey a pointer to an array of ints encoding the set of
+     *        columns of the minor
+     * @see MinorKey::MinorKey (const int lengthOfRowArray, const int* rowKey,
+                                const int lengthOfColumnArray,
+                                const int* columnKey)
+     */
+     void set(const int lengthOfRowArray, const unsigned int* rowKey,
+              const int lengthOfColumnArray, const unsigned int* columnKey);
+
+     /**
+     * A copy constructor.
+     * This method overrides the shallow copy constructor by a self-written
+     * deep copy version.
+     * @param mk the MinorKey to be deep copied
+     */
+     MinorKey (const MinorKey& mk);
+
+     /**
+     * A destructor for deleting an instance.
+     */
+     ~MinorKey ();
+
+     /**
+     * just to make the compiler happy
+     */
+     MinorKey& operator=(const MinorKey&);
+
+     /**
+     * just to make the compiler happy
+     */
+     bool operator==(const MinorKey&) const;
+
+     /**
+     * just to make the compiler happy
+     */
+     bool operator<(const MinorKey&) const;
+
+     /**
+     * A method for retrieving the (0-based) index of the i-th row in the set
+     * of rows encoded in \a this.
+     * Lower values for \c i result in lower absolute row indices.
+     * \par Example:
+     * Applied to the row pattern 10010001101 and i = 3, we get the 0-based
+     * index of the 3-rd set bit counted from the right, i.e. 7.
+     * \par Assertion
+     * The method assumes that there are at least \c i rows encoded in the
+     * given MinorKey.
+     * @param i the relative index of the row, as encoded in \a this
+     * @return (0-based) absolute row index of the i-th row in \a this
+     */
+     int getAbsoluteRowIndex (const int i) const;
+
+     /**
+     * A method for retrieving the (0-based) index of the i-th column in the
+     * set of columns encoded in \a this.
+     * Lower values for \c i result in lower absolute column indices.
+     * \par Example:
+     * Applied to the column pattern 10010001101 and i = 3, we get the 0-based
+     * index of the 3-rd set bit counted from the right, i.e. 7.
+     * \par Assertion
+     * The method assumes that there are at least \c i columns encoded in the
+     * given MinorKey.
+     * @param i the relative index of the column, as encoded in \a this
+     * @return (0-based) absolute column index of the i-th row in \a this
+     */
+     int getAbsoluteColumnIndex (const int i) const;
+
+     /**
+     * A method for retrieving the (0-based) relative index of the i-th row
+     * in \a this MinorKey.
+     * Lower values for \c i result in lower relative row indices. Note that
+     * the absolute index \c i is 0-based, too.
+     * \par Example:
+     * Applied to the row pattern 10010001101 and i = 7, we get the relative
+     * 0-based position of the bit representing the absolute index 7, i.e. 3.
+     * \par Assertion
+     * The method assumes that the bit which corresponds to the absolute index
+     * i is actually set.
+     * @param i the absolute 0-based index of a row encoded in \a this
+     * @return (0-based) relative row index corresponding to \c i
+     */
+     int getRelativeRowIndex (const int i) const;
+
+     /**
+     * A method for retrieving the (0-based) relative index of the i-th column
+     * in \a this MinorKey.
+     * Lower values for \c i result in lower relative column indices. Note that
+     * the absolute index \c i is 0-based, too.
+     * \par Example:
+     * Applied to the column pattern 10010001101 and i = 7, we get the
+     * relative 0-based position of the bit representing the absolute index 7,
+     * i.e. 3.
+     * \par Assertion
+     * The method assumes that the bit which corresponds to the absolute index
+     * i is actually set.
+     * @param i the absolute 0-based index of a column encoded in \a this
+     * @return (0-based) relative column index corresponding to \c i
+     */
+     int getRelativeColumnIndex (const int i) const;
+
+     /**
+     * A method for retrieving the 0-based indices of all rows encoded in \a
+     * this MinorKey.
+     * The user of this method needs to know the number of rows in \a this,
+     * in order to know which indices in \c target[k] will be valid.
+     * \par Example:
+     * The bit pattern <c>0...01101</c> will give rise to the settings
+     * <c>target[0] = 0, target[1] = 2, target[2] = 3</c>, and the user needs
+     * to know in advance that there are three rows in \a this MinorKey.
+     * \par Assertion
+     * The method assumes that target has enough positions for all rows
+     * encoded in \a this MinorKey.
+     * @param target a pointer to some array of ints that is to be filled with
+     *        the requested indices
+     */
+     void getAbsoluteRowIndices(int* const target) const;
+
+     /**
+     * A method for retrieving the 0-based indices of all columns encoded in
+     * \a this MinorKey.
+     * The user of this method needs to know the number of columns in \a this,
+     * in order to know which indices in \c target[k] will be valid.
+     * \par Example:
+     * The bit pattern <c>0...01101</c> will give rise to the settings
+     * <c>target[0] = 0, target[1] = 2, target[2] = 3</c>, and the user needs
+     * to know in advance that there are three columns in \a this MinorKey.
+     * \par Assertion
+     * The method assumes that target has enough positions for all columns
+     * encoded in \a this MinorKey.
+     * @param target a pointer to some array of ints that is to be filled
+     *        with the requested indices
+     */
+     void getAbsoluteColumnIndices(int* const target) const;
+
+     /**
+     * A method for retrieving a sub-MinorKey resulting from omitting one row
+     * and one column of \a this MinorKey.
+     * \par Assertion
+     * The method assumes that the row with absolute index
+     * \c absoluteEraseRowIndex (counted from lower bits to higher bits) and
+     * the column with absolute index \c absoluteEraseColumnIndex are actually
+     * set in \c mk.
+     * @param absoluteEraseRowIndex the 0-based absolute index of a row in
+     *        \a mk
+     * @param absoluteEraseColumnIndex the 0-based absolute index of a column
+     *        in \a mk
+     * @return the MinorKey when omitting the specified row and column
+     */
+     MinorKey getSubMinorKey (const int absoluteEraseRowIndex,
+                              const int absoluteEraseColumnIndex) const;
+
+     /**
+     * A comparator for two instances of MinorKey.
+     * The ordering induced by this implementation determines the ordering of
+     * all (key --> value) pairs in a cache that uses MinorKey as KeyClass.
+     * @param mk a second MinorKey to be compared with \a this instance
+     * @return -1 iff \a this instance is smaller than \a mk; 0 for equality;
+     *         +1 otherwise
+     * @see MinorKey::operator== (const MinorKey&) const
+     */
+     int compare (const MinorKey& mk) const;
+
+     /**
+     * This method redefines the set of rows represented by \a this MinorKey.
+     * After the method, the defined set of rows coincides with the lowest
+     * \c k rows of \c mk. (Here, lowest means w.r.t. indices.)<br>
+     * Note that the method modifies the given instance of MinorKey.
+     * \par Assertion
+     * It is assumed that \c mk represents at least \c k rows.
+     * @param k the number of rows
+     * @param mk the MinorKey from which to choose the lowest \c k rows
+     * @see MinorKey::selectNextRows (const int k, const MinorKey& mk)
+     */
+     void selectFirstRows (const int k, const MinorKey& mk);
+
+     /**
+     * This method redefines the set of rows represented by \a this MinorKey.
+     * Both the old and the new set of \c k rows are subsets of the rows
+     * represented by \c mk. After the method, the defined set of rows is
+     * the next sensible choice of \c k rows of \c mk. (Here, next means
+     * the next w.r.t. the increasing index ordering on multi-indices of
+     * natural numbers.)<br>
+     * Note that the method modifies the given instance of MinorKey.
+     * \par Assertion
+     * It is assumed that \c mk represents at least \c k rows. Furthermore,
+     * the method assumes that the old set of rows represented by \a this
+     * is also a subset of the rows given by \c mk.
+     * @param k the number of rows
+     * @param mk the MinorKey from which to choose the lowest \c k rows
+     * @return true iff there is a next choice of \c k rows
+     * @see MinorKey::selectFirstRows (const int k, const MinorKey& mk)
+     */
+     bool selectNextRows (const int k, const MinorKey& mk);
+
+     /**
+     * This method redefines the set of columns represented by \a this
+     * MinorKey.
+     * After the method, the defined set of columns coincides with the lowest
+     * \c k columns of \c mk. (Here, lowest means w.r.t. indices.)<br>
+     * Note that the method modifies the given instance of MinorKey.
+     * \par Assertion
+     * It is assumed that \c mk represents at least \c k columns.
+     * @param k the number of columns
+     * @param mk the MinorKey from which to choose the lowest \c k columns
+     * @see MinorKey::selectNextColumns (const int k, const MinorKey& mk)
+     */
+     void selectFirstColumns (const int k, const MinorKey& mk);
+
+     /**
+     * This method redefines the set of columns represented by \a this
+     * MinorKey.
+     * Both the old and the new set of \c k columns are subsets of the columns
+     * represented by \c mk. After the method, the defined set of columns is
+     * the next sensible choice of \c k columns of \c mk. (Here, next means
+     * the next w.r.t. the increasing index ordering on multi-indices of
+     * natural numbers.)<br>
+     * Note that the method modifies the given instance of MinorKey.
+     * \par Assertion
+     * It is assumed that \c mk represents at least \c k columns. Furthermore,
+     * the method assumes that the old set of columns represented by \a this
+     * is also a subset of the columns given by \c mk.
+     * @param k the number of columns
+     * @param mk the MinorKey from which to choose the lowest \c k columns
+     * @return true iff there is a next choice of \c k columns
+     * @see MinorKey::selectFirstColumns (const int k, const MinorKey& mk)
+     */
+     bool selectNextColumns (const int k, const MinorKey& mk);
+
+     /**
+     * A method for providing a printable version of the represented MinorKey.
+     * @return a printable version of the given instance as instance of class
+     * string
+     */
+     std::string toString () const;
+
+     /**
+     * A method for printing a string representation of the given MinorKey to
+     * std::cout.
+     */
+     //void print () const;
+};
+
+class MinorValue
+{
+  protected:
+    /**
+    * -1 iff cache is not used, otherwise the number of retrievals so far of
+    * the current minor
+    */
+    int _retrievals;
+
+    /**
+    * -1 iff cache is not used, otherwise the maximum number of potential
+    * retrievals of this minor (e.g. when the minor would be kept in cache
+    * forever)
+    */
+    int _potentialRetrievals;
+
+    /**
+    * a store for the actual number of multiplications to compute the current
+    * minor
+    */
+    int _multiplications;
+
+    /**
+    * a store for the actual number of additions to compute the current minor
+    */
+    int _additions;
+
+    /**
+    * a store for the accumulated number of multiplications to compute the
+    * current minor;
+    * This also includes all multiplications nested in sub-minors which may be
+    * retrieved from a cache. (Thus, these nested operations do not need to be
+    * performed again.)
+    */
+    int _accumulatedMult;
+
+    /**
+    * a store for the accumulated number of additions to compute the current
+    * minor;
+    * This also includes all additions nested in sub-minors which may be
+    * retrieved from a cache. (Thus, these nested operations do not need to be
+    * performed again.)
+    */
+    int _accumulatedSum;
+
+    /**
+    * A method for obtaining a rank measure for the given MinorValue.<br>
+    * Rank measures are used to compare any two instances of MinorValue. The
+    * induced ordering
+    * on MinorValues has an impact on the caching behaviour in a given cache:
+    * Greater MinorValues will be cached longer than lower ones.<br>
+    * More explicitely, this means: Make the return value of this method
+    * greater, and the given MinorValue will be cached longer when caching
+    * strategy 1 is deployed.<br>
+    * Rank measure 1 is equal to the number of actually performed
+    * multiplications to compute \a mv.
+    * @return an integer rank measure of \c this
+    * @see MinorValue::operator< (const MinorValue& mv)
+    */
+    int rankMeasure1 () const;
+
+    /**
+    * A method for obtaining a rank measure for the given MinorValue.<br>
+    * Rank measures are used to compare any two instances of MinorValue. The
+    * induced ordering on MinorValues has an impact on the caching behaviour
+    * in a given cache: Greater MinorValues will be cached longer than lower
+    * ones.<br>
+    * More explicitely, this means: Make the return value of this method
+    * greater, and the given MinorValue will be cached longer when caching
+    * strategy 1 is deployed.<br>
+    * Rank measure 2 is equal to the number of accumulated multiplications to
+    * compute the given MinorValue. This also includes all nested
+    * multiplications which were performed to compute all sub-minors which
+    * could be reused from cache.
+    * @return an integer rank measure of \c this
+    * @see MinorValue::operator< (const MinorValue& mv)
+    */
+    int rankMeasure2 () const;
+
+    /**
+    * A method for obtaining a rank measure for the given MinorValue.<br>
+    * Rank measures are used to compare any two instances of MinorValue. The
+    * induced ordering on MinorValues has an impact on the caching behaviour
+    * in a given cache: Greater MinorValues will be cached longer than lower
+    * ones.<br>
+    * More explicitely, this means: Make the return value of this method
+    * greater, and the given MinorValue will be cached longer when caching
+    * strategy 1 is deployed.<br>
+    * Rank measure 3 is equal to the number of actually performed
+    * multiplications, weighted with the ratio of not yet performed retrievals
+    * over the maximum number of retrievals.
+    * @return an integer rank measure of \c this
+    * @see MinorValue::operator< (const MinorValue& mv)
+    */
+    int rankMeasure3 () const;
+
+    /**
+    * A method for obtaining a rank measure for the given MinorValue.<br>
+    * Rank measures are used to compare any two instances of MinorValue. The
+    * induced ordering on MinorValues has an impact on the caching behaviour
+    * in a given cache: Greater MinorValues will be cached longer than lower
+    * ones.<br>
+    * More explicitely, this means: Make the return value of this method
+    * greater, and the given MinorValue will be cached longer when caching
+    * strategy 1 is deployed.<br>
+    * Rank measure 4 is equal to the number of actually performed
+    * multiplications, multiplied with the number of not yet performed
+    * retrievals.
+    * @return an integer rank measure of \c this
+    * @see MinorValue::operator< (const MinorValue& mv)
+    */
+    int rankMeasure4 () const;
+
+    /**
+    * A method for obtaining a rank measure for the given MinorValue.<br>
+    * Rank measures are used to compare any two instances of MinorValue. The
+    * induced ordering on MinorValues has an impact on the caching behaviour
+    * in a given cache: Greater MinorValues will be cached longer than lower
+    * ones.<br>
+    * More explicitely, this means: Make the return value of this method
+    * greater, and the given MinorValue will be cached longer when caching
+    * strategy 1 is deployed.<br>
+    * Rank measure 5 is equal to the number of not yet performed retrievals.
+    * This strategy tends to cache MinorValues longer which have a high
+    * maximum number of potential retrievals.
+    * @return an integer rank measure of \c this
+    * @see MinorValue::operator< (const MinorValue& mv)
+    */
+    int rankMeasure5 () const;
+
+    /**
+    * private store for the current value ranking strategy;
+    * This member can be set using MinorValue::SetRankingStrategy (const int).
+    */
+    static int g_rankingStrategy;
+
+    /**
+    * Accessor for the static private field g_rankingStrategy.
+    */
+    static int GetRankingStrategy();
+  public:
+    /**
+    * just to make the compiler happy
+    */
+    bool operator== (const MinorValue& mv) const;
+
+    /**
+    * just to make the compiler happy
+    */
+    bool operator< (const MinorValue& mv) const;
+
+    /**
+    * A method for retrieving the weight of a given MinorValue.
+    * The implementation of Cache uses this function to determine the total
+    * weight of an entire cache. As the user can instantiate Cache by
+    * determining its maximum total weight
+    * (see Cache::Cache(const int, const int)),
+    * the definition of weight of a MinorValue
+    * may have an impact on the behaviour of the cache.
+    * @return the weight of a given instance of MinorValue
+    * @see Cache::getWeight () const
+    */
+    virtual int getWeight () const;
+
+    /**
+    * A method for accessing the number of retrievals of this minor. Multiple
+    * retrievals will occur when computing large minors by means of cached
+    * sub-minors. (Then, the latter ones may be retrieved multiple times.)
+    * @return the number of retrievals of this minor
+    * @see MinorValue::getPotentialRetrievals () const
+    */
+    int getRetrievals () const;
+
+    /**
+    * A method for accessing the maximum number of potential retrievals of
+    * this minor. Multiple retrievals will occur when computing large minors
+    * by means of cached sub-minors. (Then, the latter ones may be retrieved
+    * multiple times.)
+    * @return the maximum number of potential retrievals of this minor
+    * @see MinorValue::getRetrievals () const
+    */
+    int getPotentialRetrievals () const;
+
+    /**
+    * A method for accessing the multiplications performed while computing
+    * this minor.
+    * Due to multiplication with zero entries of the underlying matrix, some
+    * sub-minors may be irrelevant. In this case, the multiplications needed
+    * to compute these sub-minors will not be counted (, as they need not be
+    * performed).
+    * Moreover, multiplications that were needed to compute cached sub-minors
+    * will not be counted either, as the value of those sub-minors can be
+    * directly retrieved from the cache.
+    * @return the number of multiplications performed
+    * @see MinorValue::getAccumulatedMultiplications () const
+    */
+    int getMultiplications () const;
+
+    /**
+    * A method for accessing the multiplications performed while computing
+    * this minor, including all nested multiplications.
+    * Contrary to MinorValue::getMultiplications () const, this method will
+    * also count multiplications needed to compute all cached sub-minors
+    * (, although they need not be performed again in order to compute the
+    * given instance of MinorValue).
+    * @return the number of multiplications performed, including nested
+    *         multiplications
+    * @see MinorValue::getMultiplications () const
+    */
+    int getAccumulatedMultiplications () const;
+
+    /**
+    * A method for accessing the additions performed while computing this
+    * minor.
+    * Additions that were needed to compute cached sub-minors will not be
+    * counted, as the value of those sub-minors can be directly retrieved
+    * from the cache.
+    * @return the number of additions performed
+    * @see MinorValue::getAccumulatedAdditions () const
+    */
+    int getAdditions () const;
+
+    /**
+    * A method for accessing the additions performed while computing this
+    * minor, including all nested additions.
+    * Contrary to MinorValue::getAdditions () const, this method will also
+    * count additions needed to compute all cached sub-minors (, although
+    * they need not be performed again in order to compute the given instance
+    * of MinorValue).
+    * @return the number of additions performed, including nested additions
+    * @see MinorValue::getAdditions () const
+    */
+    int getAccumulatedAdditions () const;
+
+    /**
+    * A method for incrementing the number of performed retrievals of \a this
+    * instance of MinorValue.<br>
+    * Note that, when calling MinorValue::incrementRetrievals () for some
+    * instance \a mv of MinorValue which has been cached in a Cache under
+    * MinorKey \a mk, the user should be careful: After incrementing the
+    * number of retrievals for \a mv, the user should always put the value
+    * again into cache, i.e. should perform
+    * Cache::put (const KeyClass&, const ValueClass&)
+    * with \a mk and the modified \a mv as arguments. This is due to the fact
+    * that changing the number of performed retrievals of a MinorValue may
+    * have an impact on its ranking in Cache. Only by calling
+    * Cache::put (const KeyClass&, const ValueClass&) can the user ensure
+    * that the pair (\a mk --> \a mv) will be correctly re-positioned within
+    * the Cache.
+    */
+    void incrementRetrievals ();
+
+    /**
+    * A method for obtaining a rank measure for theiven MinorValue.<br>
+    * Rank measures are used to compare any two instances of MinorValue. The
+    * induced ordering on MinorValues has an impact on the caching behaviour
+    * of the underlying cache: Greater MinorValues will be cached longer than
+    * lower ones.<br>
+    * More explicitely, this means: Make the return value of this method
+    * greater, and the given MinorValue will be cached longer.<br>
+    * Internally, this method will call one of several implementations,
+    * depending on the pre-defined caching strategy; see
+    * MinorProcessor::SetCacheStrategy (const int).
+    * @return an integer rank measure of \c this
+    * @see MinorValue::operator< (const MinorValue& mv)
+    * @see MinorProcessor::SetCacheStrategy (const int)
+    */
+    int getUtility () const;
+
+    /**
+    * A method for determining the value ranking strategy.<br>
+    * This setting has a direct effect on how long the given MinorValue
+    * will be cached in any cache that uses MinorValue to represent its
+    * cached values.
+    * @param rankingStrategy an int, so far one of 1, 2, ..., 5
+    */
+    static void SetRankingStrategy (const int rankingStrategy);
+
+    /**
+    * A method for providing a printable version of the represented MinorValue.
+    * @return a printable version of the given instance as instance of class
+    *         string
+    */
+   virtual std::string toString () const;
+
+    /**
+    * A method for printing a string representation of the given MinorValue
+    * to std::cout.
+    */
+    void print () const;
+};
+
+/*! \class IntMinorValue
+    \brief Class IntMinorValue is derived from MinorValue and can be used for
+    representing values in a cache for sub-determinantes; see class Cache.
+
+    As such, it is a realization of the template class ValueClass which is
+    used in the declaration of class Cache. Following the documentation of
+    class Cache, we need to implement at least the methods:<br>
+    <c>bool IntMinorValue::operator< (const IntMinorValue& key),</c><br>
+    <c>bool IntMinorValue::operator== (const IntMinorValue& key),</c><br>
+    <c>int IntMinorValue::getWeight ().</c><br><br>
+    The main purpose of IntMinorValue is to represent values of
+    sub-determinantes of a pre-defined matrix. Class MinorKey is used to
+    determine which rows and columns of this pre-defined matrix ought to
+    belong to the respective sub-determinante of interest. So far,
+    IntMinorValue is just an example implementation which assumes matrices
+    with int entries, such that the result of any minor is again an int.
+    \author Frank Seelisch, http://www.mathematik.uni-kl.de/~seelisch
+*/
+class IntMinorValue : public MinorValue
+{
+  private:
+    /**
+    * a store for the actual value of the minor
+    */
+    int _result;
+  public:
+    /**
+    * A constructor for class MinorValue.
+    * @param result the actual value of the represented minor
+    * @param multiplications number of multiplications to compute \a this
+             minor
+    * @param additions number of additions to compute \a this minor
+    * @param accumulatedMultiplications number of multiplications to compute
+             \a this minor, including nested operations
+    * @param accumulatedAdditions number of additions to compute \a this minor,
+             including nested operations
+    * @param retrievals number of times this minor has been retrieved from
+             cache
+    * @param potentialRetrievals maximum number of times this minor may be
+             retrieved from cache
+    */
+    IntMinorValue (const int result, const int multiplications,
+                   const int additions,
+                   const int accumulatedMultiplications,
+                   const int accumulatedAdditions, const int retrievals,
+                   const int potentialRetrievals);
+
+    /**
+    * Copy constructor
+    */
+    IntMinorValue (const IntMinorValue& mv);
+
+    /**
+    * just to make the compiler happy
+    */
+    IntMinorValue ();
+
+    /**
+    * Destructor
+    */
+    virtual ~IntMinorValue ();
+
+    /**
+    * Accessor for the private field _result.
+    * @result the result encoded in this class instance
+    */
+    int getResult() const;
+
+    /**
+    * Accessor for the current weight of this class instance.
+    * @result the current weight of this class instance
+    */
+    int getWeight () const;
+
+    /**
+    * A method for providing a printable version of the represented MinorValue.
+    * @return a printable version of the given instance as instance of class
+    * string
+    */
+   std::string toString () const;
+};
+
+/*! \class PolyMinorValue
+    \brief Class PolyMinorValue is derived from MinorValue and can be used for
+    representing values in a cache for sub-determinantes; see class Cache.
+
+    As such, it is a realization of the template class ValueClass which is
+    used in the declaration of class Cache. Following the documentation of
+    class Cache, we need to implement at least the methods:<br>
+    <c>bool IntMinorValue::operator< (const IntMinorValue& key),</c><br>
+    <c>bool IntMinorValue::operator== (const IntMinorValue& key),</c><br>
+    <c>int IntMinorValue::getWeight ().</c><br><br>
+    The main purpose of PolyMinorValue is to represent values of
+    sub-determinantes of a pre-defined matrix. Class MinorKey is used to
+    determine which rows and columns of this pre-defined matrix ought to
+    belong to the respective sub-determinante of interest. PolyMinorValue is
+    a special implementation which assumes matrices with polynomial entries,
+    such that the result of any minor is again a polynomial.
+    \author Frank Seelisch, http://www.mathematik.uni-kl.de/~seelisch
+*/
+class PolyMinorValue : public MinorValue
+{
+  private:
+    /**
+    * a store for the actual value of the minor
+    */
+    poly _result;
+  public:
+    /**
+    * A constructor for class MinorValue.
+    * @param result the actual value of the represented minor
+    * @param multiplications number of multiplications to compute \a this
+             minor
+    * @param additions number of additions to compute \a this minor
+    * @param accumulatedMultiplications number of multiplications to compute
+             \a this minor, including nested operations
+    * @param accumulatedAdditions number of additions to compute \a this
+             minor, including nested operations
+    * @param retrievals number of times this minor has been retrieved from
+             cache
+    * @param potentialRetrievals maximum number of times this minor may be
+             retrieved from cache
+    */
+    PolyMinorValue (const poly result, const int multiplications,
+                    const int additions,
+                    const int accumulatedMultiplications,
+                    const int accumulatedAdditions, const int retrievals,
+                    const int potentialRetrievals);
+
+    /**
+    * Copy constructor for creating a deep copy.
+    */
+    PolyMinorValue (const PolyMinorValue& mv);
+
+    /**
+    * Assignment operator which creates a deep copy.
+    */
+    void operator= (const PolyMinorValue& mv);
+
+    /**
+    * just to make the compiler happy
+    */
+    PolyMinorValue ();
+
+    /**
+    * Destructor
+    */
+    virtual ~PolyMinorValue ();
+
+    /**
+    * Accessor for the private field _result.
+    * @result the result encoded in this class instance
+    */
+    poly getResult() const;
+
+    /**
+    * Accessor for the current weight of this class instance.
+    * @result the current weight of this class instance
+    */
+    int getWeight () const;
+
+    /**
+    * A method for providing a printable version of the represented MinorValue.
+    * @return a printable version of the given instance as instance of class
+    * string
+    */
+   std::string toString () const;
+};
+
+#endif
+/* MINOR_H */
diff --git a/kernel/linear_algebra/MinorInterface.cc b/kernel/linear_algebra/MinorInterface.cc
new file mode 100644
index 0000000..2dffc91
--- /dev/null
+++ b/kernel/linear_algebra/MinorInterface.cc
@@ -0,0 +1,559 @@
+
+
+
+#include <kernel/mod2.h>
+
+// include before anything to avoid clashes with stdio.h included elsewhere
+// #include <cstdio>
+
+#include <kernel/linear_algebra/MinorInterface.h>
+#include <kernel/linear_algebra/MinorProcessor.h>
+
+#include <polys/simpleideals.h>
+
+#include <kernel/polys.h>
+#include <kernel/structs.h>
+#include <kernel/GBEngine/kstd1.h>
+#include <kernel/ideals.h>
+
+using namespace std;
+
+bool currRingIsOverIntegralDomain ()
+{
+  if (rField_is_Ring_PtoM(currRing)) return false;
+  if (rField_is_Ring_2toM(currRing)) return false;
+  if (rField_is_Ring_ModN(currRing)) return false;
+  return true;
+}
+
+bool currRingIsOverField ()
+{
+  if (rField_is_Ring_PtoM(currRing)) return false;
+  if (rField_is_Ring_2toM(currRing)) return false;
+  if (rField_is_Ring_ModN(currRing)) return false;
+  if (rField_is_Ring_Z(currRing))    return false;
+  return true;
+}
+
+/* returns true iff the given polyArray has only number entries;
+   if so, the int's corresponding to these numbers will be written
+   into intArray[0..(length-1)];
+   the method assumes that both polyArray and intArray have valid
+   entries for the indices 0..(length-1);
+   after the call, zeroCounter contains the number of zero entries
+   in the matrix */
+bool arrayIsNumberArray (const poly* polyArray, const ideal iSB,
+                         const int length, int* intArray,
+                         poly* nfPolyArray, int& zeroCounter)
+{
+  int n = 0; if (currRing != 0) n = currRing->N;
+  int characteristic = 0; if (currRing != 0) characteristic = rChar(currRing);
+  zeroCounter = 0;
+  bool result = true;
+
+  for (int i = 0; i < length; i++)
+  {
+    nfPolyArray[i] = pCopy(polyArray[i]);
+    if (iSB != 0) nfPolyArray[i] = kNF(iSB, currRing->qideal, nfPolyArray[i]);
+    if (nfPolyArray[i] == NULL)
+    {
+      intArray[i] = 0;
+      zeroCounter++;
+    }
+    else
+    {
+      bool isConstant = true;
+      for (int j = 1; j <= n; j++)
+        if (pGetExp(nfPolyArray[i], j) > 0)
+          isConstant = false;
+      if (!isConstant) result = false;
+      else
+      {
+        intArray[i] = n_Int(pGetCoeff(nfPolyArray[i]), currRing->cf);
+        if (characteristic != 0) intArray[i] = intArray[i] % characteristic;
+        if (intArray[i] == 0) zeroCounter++;
+      }
+    }
+  }
+  return result;
+}
+
+/* special implementation for the case that the matrix has only number entries;
+   if i is not the zero pointer, then it is assumed to contain a std basis, and
+   the number entries of the matrix are then assumed to be reduced w.r.t. i and
+   modulo the characteristic of the gound field/ring;
+   this method should also work when currRing == null, i.e. when no ring has
+   been declared */
+ideal getMinorIdeal_Int (const int* intMatrix, const int rowCount,
+                         const int columnCount, const int minorSize,
+                         const int k, const char* algorithm,
+                         const ideal i, const bool allDifferent)
+{
+  /* setting up a MinorProcessor for matrices with integer entries: */
+  IntMinorProcessor mp;
+  mp.defineMatrix(rowCount, columnCount, intMatrix);
+  int *myRowIndices=new int[rowCount];
+  for (int j = 0; j < rowCount; j++) myRowIndices[j] = j;
+  int *myColumnIndices=new int[columnCount];
+  for (int j = 0; j < columnCount; j++) myColumnIndices[j] = j;
+  mp.defineSubMatrix(rowCount, myRowIndices, columnCount, myColumnIndices);
+  mp.setMinorSize(minorSize);
+
+  /* containers for all upcoming results: */
+  IntMinorValue theMinor;
+  // int value = 0;
+  int collectedMinors = 0;
+  int characteristic = 0; if (currRing != 0) characteristic = rChar(currRing);
+
+  /* the ideal to be returned: */
+  ideal iii = idInit(1);
+
+  bool zeroOk = ((k < 0) ? true : false); /* for k = 0, all minors are requested,
+                                             omitting zero minors */
+  bool duplicatesOk = (allDifferent ? false : true);
+  int kk = ((k < 0) ? -k : k); /* absolute value of k */
+
+  /* looping over all minors: */
+  while (mp.hasNextMinor() && ((kk == 0) || (collectedMinors < kk)))
+  {
+    /* retrieving the next minor: */
+    theMinor = mp.getNextMinor(characteristic, i, algorithm);
+    poly f = NULL;
+    if (theMinor.getResult() != 0) f = pISet(theMinor.getResult());
+    if (idInsertPolyWithTests(iii, collectedMinors, f, zeroOk, duplicatesOk))
+      collectedMinors++;
+  }
+
+  /* before we return the result, let's omit zero generators
+     in iii which come after the computed minors */
+  ideal jjj;
+  if (collectedMinors == 0) jjj = idInit(1);
+  else                      jjj = idCopyFirstK(iii, collectedMinors);
+  idDelete(&iii);
+  delete[] myColumnIndices;
+  delete[] myRowIndices;
+  return jjj;
+}
+
+/* special implementation for the case that the matrix has non-number,
+   i.e., actual polynomial entries;
+   if i is not the zero pointer than it is assumed to be a std basis (ideal),
+   and the poly matrix is assumed to be already reduced w.r.t. i */
+ideal getMinorIdeal_Poly (const poly* polyMatrix, const int rowCount,
+                          const int columnCount, const int minorSize,
+                          const int k, const char* algorithm,
+                          const ideal i, const bool allDifferent)
+{
+  /* setting up a MinorProcessor for matrices with polynomial entries: */
+  PolyMinorProcessor mp;
+  mp.defineMatrix(rowCount, columnCount, polyMatrix);
+  int *myRowIndices=new int[rowCount];
+  for (int j = 0; j < rowCount; j++) myRowIndices[j] = j;
+  int *myColumnIndices=new int[columnCount];
+  for (int j = 0; j < columnCount; j++) myColumnIndices[j] = j;
+  mp.defineSubMatrix(rowCount, myRowIndices, columnCount, myColumnIndices);
+  mp.setMinorSize(minorSize);
+
+  /* containers for all upcoming results: */
+  PolyMinorValue theMinor;
+  poly f = NULL;
+  int collectedMinors = 0;
+
+  /* the ideal to be returned: */
+  ideal iii = idInit(1);
+
+  bool zeroOk = ((k < 0) ? true : false); /* for k = 0, all minors are
+                                             requested, omitting zero minors */
+  bool duplicatesOk = (allDifferent ? false : true);
+  int kk = ((k < 0) ? -k : k); /* absolute value of k */
+#ifdef COUNT_AND_PRINT_OPERATIONS
+  printCounters ("starting", true);
+  int qqq = 0;
+#endif
+  /* looping over all minors: */
+  while (mp.hasNextMinor() && ((kk == 0) || (collectedMinors < kk)))
+  {
+    /* retrieving the next minor: */
+    theMinor = mp.getNextMinor(algorithm, i);
+#if (defined COUNT_AND_PRINT_OPERATIONS) && (COUNT_AND_PRINT_OPERATIONS > 1)
+    qqq++;
+    Print("after %d", qqq);
+    printCounters ("-th minor", false);
+#endif
+    f = theMinor.getResult();
+    if (idInsertPolyWithTests(iii, collectedMinors, pCopy(f),
+                              zeroOk, duplicatesOk))
+      collectedMinors++;
+  }
+#ifdef COUNT_AND_PRINT_OPERATIONS
+  printCounters ("ending", true);
+#endif
+
+  /* before we return the result, let's omit zero generators
+     in iii which come after the computed minors */
+  idKeepFirstK(iii, collectedMinors);
+  delete[] myColumnIndices;
+  delete[] myRowIndices;
+  return(iii);
+}
+
+ideal getMinorIdeal_toBeDone (const matrix mat, const int minorSize,
+                              const int k, const char* algorithm,
+                              const ideal i, const bool allDifferent)
+{
+  int rowCount = mat->nrows;
+  int columnCount = mat->ncols;
+  poly* myPolyMatrix = (poly*)(mat->m);
+  ideal iii; /* the ideal to be filled and returned */
+  int zz = 0;
+
+  /* divert to special implementations for pure number matrices and actual
+     polynomial matrices: */
+  int*  myIntMatrix  = new int [rowCount * columnCount];
+  poly* nfPolyMatrix = new poly[rowCount * columnCount];
+  if (arrayIsNumberArray(myPolyMatrix, i, rowCount * columnCount,
+                         myIntMatrix, nfPolyMatrix, zz))
+    iii = getMinorIdeal_Int(myIntMatrix, rowCount, columnCount, minorSize, k,
+                            algorithm, i, allDifferent);
+  else
+  {
+    if ((k == 0) && (strcmp(algorithm, "Bareiss") == 0)
+        && (!rField_is_Ring_Z(currRing)) && (!allDifferent))
+    {
+      /* In this case, we call an optimized procedure, dating back to
+         Wilfried Pohl. It may be used whenever
+         - all minors are requested,
+         - requested minors need not be mutually distinct, and
+         - coefficients come from a field (i.e., Z is also not allowed
+           for this implementation). */
+      iii = (i == 0 ? idMinors(mat, minorSize) : idMinors(mat, minorSize, i));
+    }
+    else
+    {
+      iii = getMinorIdeal_Poly(nfPolyMatrix, rowCount, columnCount, minorSize,
+                               k, algorithm, i, allDifferent);
+    }
+  }
+
+  /* clean up */
+  delete [] myIntMatrix;
+  for (int j = 0; j < rowCount * columnCount; j++) pDelete(&nfPolyMatrix[j]);
+  delete [] nfPolyMatrix;
+
+  return iii;
+}
+
+/* When called with algorithm == "Bareiss", the coefficients are assumed
+   to come from a field or from a ring which does not have zero-divisors
+   (other than 0), i.e. from an integral domain.
+   E.g. Bareiss may be used over fields or over Z but not over
+        Z/6 (which has non-zero zero divisors, namely 2 and 3). */
+ideal getMinorIdeal (const matrix mat, const int minorSize, const int k,
+                     const char* algorithm, const ideal iSB,
+                     const bool allDifferent)
+{
+  /* Note that this method should be replaced by getMinorIdeal_toBeDone,
+     to enable faster computations in the case of matrices which contain
+     only numbers. But so far, this method is not yet usable as it replaces
+     the numbers by ints which may result in overflows during computations
+     of minors. */
+  int rowCount = mat->nrows;
+  int columnCount = mat->ncols;
+  poly* myPolyMatrix = (poly*)(mat->m);
+  int length = rowCount * columnCount;
+  poly* nfPolyMatrix = new poly[length];
+  ideal iii; /* the ideal to be filled and returned */
+
+  /* copy all polynomials and reduce them w.r.t. iSB
+     (if iSB is present, i.e., not the NULL pointer) */
+  for (int i = 0; i < length; i++)
+  {
+    nfPolyMatrix[i] = pCopy(myPolyMatrix[i]);
+    if (iSB != 0) nfPolyMatrix[i] = kNF(iSB, currRing->qideal,
+                                        nfPolyMatrix[i]);
+  }
+
+  if ((k == 0) && (strcmp(algorithm, "Bareiss") == 0)
+      && (!rField_is_Ring_Z(currRing)) && (!allDifferent))
+  {
+    /* In this case, we call an optimized procedure, dating back to
+       Wilfried Pohl. It may be used whenever
+       - all minors are requested,
+       - requested minors need not be mutually distinct, and
+       - coefficients come from a field (i.e., the ring Z is not
+         allowed for this implementation). */
+    iii = (iSB == 0 ? idMinors(mat, minorSize) : idMinors(mat, minorSize,
+                                                          iSB));
+  }
+  else
+  {
+    iii = getMinorIdeal_Poly(nfPolyMatrix, rowCount, columnCount, minorSize,
+                             k, algorithm, iSB, allDifferent);
+  }
+
+  /* clean up */
+  for (int j = 0; j < length; j++) pDelete(&nfPolyMatrix[j]);
+  delete [] nfPolyMatrix;
+
+  return iii;
+}
+
+/* special implementation for the case that the matrix has only number entries;
+   if i is not the zero pointer, then it is assumed to contain a std basis, and
+   the number entries of the matrix are then assumed to be reduced w.r.t. i and
+   modulo the characteristic of the gound field/ring;
+   this method should also work when currRing == null, i.e. when no ring has
+   been declared */
+ideal getMinorIdealCache_Int(const int* intMatrix, const int rowCount,
+                             const int columnCount, const int minorSize,
+                             const int k, const ideal i,
+                             const int cacheStrategy, const int cacheN,
+                             const int cacheW, const bool allDifferent)
+{
+  /* setting up a MinorProcessor for matrices with integer entries: */
+  IntMinorProcessor mp;
+  mp.defineMatrix(rowCount, columnCount, intMatrix);
+  int *myRowIndices=new int[rowCount];
+  for (int j = 0; j < rowCount; j++) myRowIndices[j] = j;
+  int *myColumnIndices=new int[columnCount];
+  for (int j = 0; j < columnCount; j++) myColumnIndices[j] = j;
+  mp.defineSubMatrix(rowCount, myRowIndices, columnCount, myColumnIndices);
+  mp.setMinorSize(minorSize);
+  MinorValue::SetRankingStrategy(cacheStrategy);
+  Cache<MinorKey, IntMinorValue> cch(cacheN, cacheW);
+
+  /* containers for all upcoming results: */
+  IntMinorValue theMinor;
+  // int value = 0;
+  int collectedMinors = 0;
+  int characteristic = 0; if (currRing != 0) characteristic = rChar(currRing);
+
+  /* the ideal to be returned: */
+  ideal iii = idInit(1);
+
+  bool zeroOk = ((k < 0) ? true : false); /* for k = 0, all minors are
+                                             requested, omitting zero minors */
+  bool duplicatesOk = (allDifferent ? false : true);
+  int kk = ((k < 0) ? -k : k); /* absolute value of k */
+
+  /* looping over all minors: */
+  while (mp.hasNextMinor() && ((kk == 0) || (collectedMinors < kk)))
+  {
+    /* retrieving the next minor: */
+    theMinor = mp.getNextMinor(cch, characteristic, i);
+    poly f = NULL;
+    if (theMinor.getResult() != 0) f = pISet(theMinor.getResult());
+    if (idInsertPolyWithTests(iii, collectedMinors, f, zeroOk, duplicatesOk))
+      collectedMinors++;
+  }
+
+  /* before we return the result, let's omit zero generators
+     in iii which come after the computed minors */
+  ideal jjj;
+  if (collectedMinors == 0) jjj = idInit(1);
+  else                      jjj = idCopyFirstK(iii, collectedMinors);
+  idDelete(&iii);
+  delete[] myColumnIndices;
+  delete[] myRowIndices;
+  return jjj;
+}
+
+/* special implementation for the case that the matrix has non-number,
+   i.e. real poly entries;
+   if i is not the zero pointer, then it is assumed to contain a std basis,
+   and the entries of the matrix are then assumed to be reduced w.r.t. i */
+ideal getMinorIdealCache_Poly(const poly* polyMatrix, const int rowCount,
+                              const int columnCount, const int minorSize,
+                              const int k, const ideal i,
+                              const int cacheStrategy, const int cacheN,
+                              const int cacheW, const bool allDifferent)
+{
+  /* setting up a MinorProcessor for matrices with polynomial entries: */
+  PolyMinorProcessor mp;
+  mp.defineMatrix(rowCount, columnCount, polyMatrix);
+  int *myRowIndices=new int[rowCount];
+  for (int j = 0; j < rowCount; j++) myRowIndices[j] = j;
+  int *myColumnIndices=new int[columnCount];
+  for (int j = 0; j < columnCount; j++) myColumnIndices[j] = j;
+  mp.defineSubMatrix(rowCount, myRowIndices, columnCount, myColumnIndices);
+  mp.setMinorSize(minorSize);
+  MinorValue::SetRankingStrategy(cacheStrategy);
+  Cache<MinorKey, PolyMinorValue> cch(cacheN, cacheW);
+
+  /* containers for all upcoming results: */
+  PolyMinorValue theMinor;
+  poly f = NULL;
+  int collectedMinors = 0;
+
+  /* the ideal to be returned: */
+  ideal iii = idInit(1);
+
+  bool zeroOk = ((k < 0) ? true : false); /* for k = 0, all minors are
+                                             requested, omitting zero minors */
+  bool duplicatesOk = (allDifferent ? false : true);
+  int kk = ((k < 0) ? -k : k); /* absolute value of k */
+#ifdef COUNT_AND_PRINT_OPERATIONS
+  printCounters ("starting", true);
+  int qqq = 0;
+#endif
+  /* looping over all minors: */
+  while (mp.hasNextMinor() && ((kk == 0) || (collectedMinors < kk)))
+  {
+    /* retrieving the next minor: */
+    theMinor = mp.getNextMinor(cch, i);
+#if (defined COUNT_AND_PRINT_OPERATIONS) && (COUNT_AND_PRINT_OPERATIONS > 1)
+    qqq++;
+    Print("after %d", qqq);
+    printCounters ("-th minor", false);
+#endif
+    f = theMinor.getResult();
+    if (idInsertPolyWithTests(iii, collectedMinors, pCopy(f), zeroOk,
+                              duplicatesOk))
+      collectedMinors++;
+  }
+#ifdef COUNT_AND_PRINT_OPERATIONS
+  printCounters ("ending", true);
+#endif
+
+  /* before we return the result, let's omit zero generators
+     in iii which come after the computed minors */
+  ideal jjj;
+  if (collectedMinors == 0) jjj = idInit(1);
+  else                      jjj = idCopyFirstK(iii, collectedMinors);
+  idDelete(&iii);
+  delete[] myColumnIndices;
+  delete[] myRowIndices;
+  return jjj;
+}
+
+ideal getMinorIdealCache_toBeDone (const matrix mat, const int minorSize,
+                                   const int k, const ideal iSB,
+                                   const int cacheStrategy, const int cacheN,
+                                   const int cacheW, const bool allDifferent)
+{
+  int rowCount = mat->nrows;
+  int columnCount = mat->ncols;
+  poly* myPolyMatrix = (poly*)(mat->m);
+  ideal iii; /* the ideal to be filled and returned */
+  int zz = 0;
+
+  /* divert to special implementation when myPolyMatrix has only number
+     entries: */
+  int*  myIntMatrix  = new int [rowCount * columnCount];
+  poly* nfPolyMatrix = new poly[rowCount * columnCount];
+  if (arrayIsNumberArray(myPolyMatrix, iSB, rowCount * columnCount,
+                         myIntMatrix, nfPolyMatrix, zz))
+    iii = getMinorIdealCache_Int(myIntMatrix, rowCount, columnCount,
+                                 minorSize, k, iSB, cacheStrategy, cacheN,
+                                 cacheW, allDifferent);
+  else
+    iii = getMinorIdealCache_Poly(nfPolyMatrix, rowCount, columnCount,
+                                  minorSize, k, iSB, cacheStrategy, cacheN,
+                                  cacheW, allDifferent);
+
+  /* clean up */
+  delete [] myIntMatrix;
+  for (int j = 0; j < rowCount * columnCount; j++) pDelete(&nfPolyMatrix[j]);
+  delete [] nfPolyMatrix;
+
+  return iii;
+}
+
+ideal getMinorIdealCache (const matrix mat, const int minorSize, const int k,
+                          const ideal iSB, const int cacheStrategy,
+                          const int cacheN, const int cacheW,
+                          const bool allDifferent)
+{
+  /* Note that this method should be replaced by getMinorIdealCache_toBeDone,
+     to enable faster computations in the case of matrices which contain
+     only numbers. But so far, this method is not yet usable as it replaces
+     the numbers by ints which may result in overflows during computations
+     of minors. */
+  int rowCount = mat->nrows;
+  int columnCount = mat->ncols;
+  poly* myPolyMatrix = (poly*)(mat->m);
+  int length = rowCount * columnCount;
+  poly* nfPolyMatrix = new poly[length];
+  ideal iii; /* the ideal to be filled and returned */
+
+  /* copy all polynomials and reduce them w.r.t. iSB
+     (if iSB is present, i.e., not the NULL pointer) */
+  for (int i = 0; i < length; i++)
+  {
+    nfPolyMatrix[i] = pCopy(myPolyMatrix[i]);
+    if (iSB != 0) nfPolyMatrix[i] = kNF(iSB, currRing->qideal,
+                                        nfPolyMatrix[i]);
+  }
+
+  iii = getMinorIdealCache_Poly(nfPolyMatrix, rowCount, columnCount,
+                                minorSize, k, iSB, cacheStrategy,
+                                cacheN, cacheW, allDifferent);
+
+  /* clean up */
+  for (int j = 0; j < length; j++) pDelete(&nfPolyMatrix[j]);
+  delete [] nfPolyMatrix;
+
+  return iii;
+}
+
+ideal getMinorIdealHeuristic (const matrix mat, const int minorSize,
+                              const int k, const ideal iSB,
+                              const bool allDifferent)
+{
+  int vars = 0; if (currRing != 0) vars = currRing->N;
+  int rowCount = mat->nrows;
+  int columnCount = mat->ncols;
+
+  /* here comes the heuristic, as of 29 January 2010:
+
+     integral domain and minorSize <= 2                -> Bareiss
+     integral domain and minorSize >= 3 and vars <= 2  -> Bareiss
+     field case and minorSize >= 3 and vars = 3
+       and c in {2, 3, ..., 32003}                     -> Bareiss
+
+     otherwise:
+     if not all minors are requested                   -> Laplace, no Caching
+     otherwise:
+     minorSize >= 3 and vars <= 4 and
+       (rowCount over minorSize)*(columnCount over minorSize) >= 100
+                                                       -> Laplace with Caching
+     minorSize >= 3 and vars >= 5 and
+       (rowCount over minorSize)*(columnCount over minorSize) >= 40
+                                                       -> Laplace with Caching
+
+     otherwise:                                        -> Laplace, no Caching
+  */
+
+  bool b = false; /* Bareiss */
+  bool l = false; /* Laplace without caching */
+  // bool c = false; /* Laplace with caching */
+  if (currRingIsOverIntegralDomain())
+  { /* the field case or ring Z */
+    if      (minorSize <= 2)                                     b = true;
+    else if (vars <= 2)                                          b = true;
+    else if (currRingIsOverField() && (vars == 3)
+             && (currRing->cf->ch >= 2) && (currRing->cf->ch <= 32003))
+          b = true;
+  }
+  if (!b)
+  { /* the non-Bareiss cases */
+    if (k != 0) /* this means, not all minors are requested */   l = true;
+    else
+    { /* k == 0, i.e., all minors are requested */
+      int minorCount = binom(rowCount, minorSize);
+      minorCount *= binom(columnCount, minorSize);
+      // if      ((minorSize >= 3) && (vars <= 4)
+      //          && (minorCount >= 100))                           c = true;
+      // else if ((minorSize >= 3) && (vars >= 5)
+      //          && (minorCount >= 40))                            c = true;
+      /*else*/                                                      l = true;
+    }
+  }
+
+  if      (b)    return getMinorIdeal(mat, minorSize, k, "Bareiss", iSB,
+                                      allDifferent);
+  else if (l)    return getMinorIdeal(mat, minorSize, k, "Laplace", iSB,
+                                      allDifferent);
+  else /* (c) */ return getMinorIdealCache(mat, minorSize, k, iSB,
+                                      3, 200, 100000, allDifferent);
+}
diff --git a/kernel/linear_algebra/MinorInterface.h b/kernel/linear_algebra/MinorInterface.h
new file mode 100644
index 0000000..ac54501
--- /dev/null
+++ b/kernel/linear_algebra/MinorInterface.h
@@ -0,0 +1,110 @@
+#ifndef MINOR_INTERFACE_H
+#define MINOR_INTERFACE_H
+
+
+struct spolyrec; typedef struct spolyrec polyrec; typedef polyrec* poly;
+struct ip_sring; typedef struct ip_sring* ring; typedef struct ip_sring const* const_ring;
+
+struct sip_sideal; typedef struct sip_sideal *       ideal;
+
+class ip_smatrix; typedef ip_smatrix *       matrix;
+
+/* all computations are module char, if char <> 0;
+   if additionally, an ideal i != NULL is given, then computations are
+   modulo i (in this case, i is assumed to be a standard basis);
+   if k = 0, then all non-zero minors are requested, otherwise
+   if k > 0, then the first k non-zero minors are requested,
+   if k < 0, then the first |k| minors (zero is allowed) are requested,
+   (note that k <> 0 may result in a smaller number k' of
+   minors if there are only k' < |k| minors;
+   if an algorithm is provided, it must be one of "Bareiss" or
+   "Laplace"; when a cache is used, the underlying algorithm
+   is automatically Laplace */
+
+/**
+* Returns the specified set of minors (= subdeterminantes) of the
+* given matrix. These minors form the set of generators of the ideal
+* which is actually returned.<br>
+* If k == 0, all non-zero minors will be computed. For k > 0, only
+* the first k non-zero minors (to some fixed ordering among all minors)
+* will be computed. Use k < 0 to compute the first |k| minors (including
+* zero minors).<br>
+* algorithm must be one of "Bareiss" and "Laplace".<br>
+* i must be either NULL or an ideal capturing a standard basis. In the
+* later case all minors will be reduced w.r.t. i.
+* If allDifferent is true, each minor will be included as generator
+* in the resulting ideal only once; otherwise as often as it occurs as
+* minor value during the computation.
+* @param m the matrix from which to compute minors
+* @param minorSize the size of the minors to be computed
+* @param k the number of minors to be computed
+* @param algorithm the algorithm to be used for the computation
+* @param i NULL or an ideal which encodes a standard basis
+* @param allDifferent if true each minor is considered only once
+* @return the ideal which has as generators the specified set of minors
+*/
+ideal getMinorIdeal (const matrix m, const int minorSize, const int k,
+                     const char* algorithm, const ideal i,
+                     const bool allDifferent);
+
+/**
+* Returns the specified set of minors (= subdeterminantes) of the
+* given matrix. These minors form the set of generators of the ideal
+* which is actually returned.<br>
+* If k == 0, all non-zero minors will be computed. For k > 0, only
+* the first k non-zero minors (to some fixed ordering among all minors)
+* will be computed. Use k < 0 to compute the first |k| minors (including
+* zero minors).<br>
+* The underlying algorithm is Laplace's algorithm with caching of certain
+* subdeterminantes. The caching strategy can be set; see
+* int MinorValue::getUtility () const in Minor.cc. cacheN is the maximum
+* number of cached polynomials (=subdeterminantes); cacheW the maximum
+* weight of the cache during all computations.<br>
+* i must be either NULL or an ideal capturing a standard basis. In the
+* later case all minors will be reduced w.r.t. i.
+* If allDifferent is true, each minor will be included as generator
+* in the resulting ideal only once; otherwise as often as it occurs as
+* minor value during the computation.
+* @param m the matrix from which to compute minors
+* @param minorSize the size of the minors to be computed
+* @param k the number of minors to be computed
+* @param i NULL or an ideal which encodes a standard basis
+* @param cacheStrategy one of {1, .., 5}; see Minor.cc
+* @param cacheN maximum number of cached polynomials (=subdeterminantes)
+* @param cacheW maximum weight of the cache
+* @param allDifferent if true each minor is considered only once
+* @return the ideal which has as generators the specified set of minors
+*/
+ideal getMinorIdealCache (const matrix m, const int minorSize, const int k,
+                          const ideal i, const int cacheStrategy,
+                          const int cacheN, const int cacheW,
+                          const bool allDifferent);
+
+/**
+* Returns the specified set of minors (= subdeterminantes) of the
+* given matrix. These minors form the set of generators of the ideal
+* which is actually returned.<br>
+* If k == 0, all non-zero minors will be computed. For k > 0, only
+* the first k non-zero minors (to some fixed ordering among all minors)
+* will be computed. Use k < 0 to compute the first |k| minors (including
+* zero minors).<br>
+* The algorithm is heuristically chosen among "Bareiss", "Laplace",
+* and Laplace with caching (of subdeterminants).<br>
+* i must be either NULL or an ideal capturing a standard basis. In the
+* later case all minors will be reduced w.r.t. i.
+* If allDifferent is true, each minor will be included as generator
+* in the resulting ideal only once; otherwise as often as it occurs as
+* minor value during the computation.
+* @param m the matrix from which to compute minors
+* @param minorSize the size of the minors to be computed
+* @param k the number of minors to be computed
+* @param i NULL or an ideal which encodes a standard basis
+* @param allDifferent if true each minor is considered only once
+* @return the ideal which has as generators the specified set of minors
+*/
+ideal getMinorIdealHeuristic (const matrix m, const int minorSize,
+                              const int k, const ideal i,
+                              const bool allDifferent);
+
+#endif
+/* MINOR_INTERFACE_H */
diff --git a/kernel/linear_algebra/MinorProcessor.cc b/kernel/linear_algebra/MinorProcessor.cc
new file mode 100644
index 0000000..52985e3
--- /dev/null
+++ b/kernel/linear_algebra/MinorProcessor.cc
@@ -0,0 +1,1549 @@
+
+
+
+#include <kernel/mod2.h>
+
+#include <kernel/linear_algebra/MinorProcessor.h>
+
+#include <polys/kbuckets.h>
+
+#include <kernel/structs.h>
+#include <kernel/polys.h>
+#include <kernel/GBEngine/kstd1.h>
+
+#include <kernel/ideals.h>
+
+using namespace std;
+
+#ifdef COUNT_AND_PRINT_OPERATIONS
+long addsPoly        = 0;    /* for the number of additions of two polynomials */
+long multsPoly       = 0;    /* for the number of multiplications of two polynomials */
+long addsPolyForDiv  = 0;    /* for the number of additions of two polynomials for
+                                polynomial division part */
+long multsPolyForDiv = 0;    /* for the number of multiplications of two polynomials
+                                for polynomial division part */
+long multsMon        = 0;    /* for the number of multiplications of two monomials */
+long multsMonForDiv  = 0;    /* for the number of m-m-multiplications for polynomial
+                                division part */
+long savedMultsMFD   = 0;    /* number of m-m-multiplications that could be saved
+                                when polynomial division would be optimal
+                                (if p / t1 = t2 + ..., then t1 * t2 = LT(p), i.e.,
+                                this multiplication need not be performed which
+                                would save one m-m-multiplication) */
+long divsMon         = 0;    /* for the number of divisions of two monomials;
+                                these are all guaranteed to work, i.e., m1/m2 only
+                                when exponentVector(m1) >= exponentVector(m2) */
+void printCounters (char* prefix, bool resetToZero)
+{
+  printf("%s [p+p(div) | p*p(div) | m*m(div, -save) | m/m ]", prefix);
+  printf(" = [%ld(%ld) | %ld(%ld) | %ld(%d, -%ld) | %ld]\n",
+         addsPoly, addsPolyForDiv, multsPoly, multsPolyForDiv,
+         multsMon, multsMonForDiv, savedMultsMFD, divsMon);
+  if (resetToZero)
+  {
+    multsMon = 0; addsPoly = 0; multsPoly = 0; divsMon = 0;
+    savedMultsMFD = 0; multsMonForDiv = 0; addsPolyForDiv = 0;
+    multsPolyForDiv = 0;
+  }
+}
+#endif
+/* COUNT_AND_PRINT_OPERATIONS */
+
+void MinorProcessor::print() const
+{
+  PrintS(this->toString().c_str());
+}
+
+int MinorProcessor::getBestLine (const int k, const MinorKey& mk) const
+{
+  /* This method identifies the row or column with the most zeros.
+     The returned index (bestIndex) is absolute within the pre-
+     defined matrix.
+     If some row has the most zeros, then the absolute (0-based)
+     row index is returned.
+     If, contrariwise, some column has the most zeros, then -1 minus
+     the absolute (0-based) column index is returned. */
+  int numberOfZeros = 0;
+  int bestIndex = 100000;    /* We start with an invalid row/column index. */
+  int maxNumberOfZeros = -1; /* We update this variable whenever we find
+                                a new so-far optimal row or column. */
+  for (int r = 0; r < k; r++)
+  {
+    /* iterate through all k rows of the momentary minor */
+    int absoluteR = mk.getAbsoluteRowIndex(r);
+    numberOfZeros = 0;
+    for (int c = 0; c < k; c++)
+    {
+      int absoluteC = mk.getAbsoluteColumnIndex(c);
+      if (isEntryZero(absoluteR, absoluteC)) numberOfZeros++;
+    }
+    if (numberOfZeros > maxNumberOfZeros)
+    {
+      /* We found a new best line which is a row. */
+      bestIndex = absoluteR;
+      maxNumberOfZeros = numberOfZeros;
+    }
+  };
+  for (int c = 0; c < k; c++)
+  {
+    int absoluteC = mk.getAbsoluteColumnIndex(c);
+    numberOfZeros = 0;
+    for (int r = 0; r < k; r++)
+    {
+      int absoluteR = mk.getAbsoluteRowIndex(r);
+      if (isEntryZero(absoluteR, absoluteC)) numberOfZeros++;
+    }
+    if (numberOfZeros > maxNumberOfZeros)
+    {
+      /* We found a new best line which is a column. So we transform
+         the return value. Note that we can easily retrieve absoluteC
+         from bestLine: absoluteC = - 1 - bestLine. */
+      bestIndex = - absoluteC - 1;
+      maxNumberOfZeros = numberOfZeros;
+    }
+  };
+  return bestIndex;
+}
+
+void MinorProcessor::setMinorSize(const int minorSize)
+{
+  _minorSize = minorSize;
+  _minor.reset();
+}
+
+bool MinorProcessor::hasNextMinor()
+{
+  return setNextKeys(_minorSize);
+}
+
+void MinorProcessor::getCurrentRowIndices(int* const target) const
+{
+  return _minor.getAbsoluteRowIndices(target);
+}
+
+void MinorProcessor::getCurrentColumnIndices(int* const target) const
+{
+  return _minor.getAbsoluteColumnIndices(target);
+}
+
+void MinorProcessor::defineSubMatrix(const int numberOfRows,
+                                     const int* rowIndices,
+                                     const int numberOfColumns,
+                                     const int* columnIndices)
+{
+  /* The method assumes ascending row and column indices in the
+     two argument arrays. These indices are understood to be zero-based.
+     The method will set the two arrays of ints in _container.
+     Example: The indices 0, 2, 3, 7 will be converted to an array with
+     one int representing the binary number 10001101
+     (check bits from right to left). */
+
+  _containerRows = numberOfRows;
+  int highestRowIndex = rowIndices[numberOfRows - 1];
+  int rowBlockCount = (highestRowIndex / 32) + 1;
+  unsigned int *rowBlocks=new unsigned int[rowBlockCount];
+  for (int i = 0; i < rowBlockCount; i++) rowBlocks[i] = 0;
+  for (int i = 0; i < numberOfRows; i++)
+  {
+    int blockIndex = rowIndices[i] / 32;
+    int offset = rowIndices[i] % 32;
+    rowBlocks[blockIndex] += (1 << offset);
+  }
+
+  _containerColumns = numberOfColumns;
+  int highestColumnIndex = columnIndices[numberOfColumns - 1];
+  int columnBlockCount = (highestColumnIndex / 32) + 1;
+  unsigned *columnBlocks=new unsigned[columnBlockCount];
+  for (int i = 0; i < columnBlockCount; i++) columnBlocks[i] = 0;
+  for (int i = 0; i < numberOfColumns; i++)
+  {
+    int blockIndex = columnIndices[i] / 32;
+    int offset = columnIndices[i] % 32;
+    columnBlocks[blockIndex] += (1 << offset);
+  }
+
+  _container.set(rowBlockCount, rowBlocks, columnBlockCount, columnBlocks);
+  delete[] columnBlocks;
+  delete[] rowBlocks;
+}
+
+bool MinorProcessor::setNextKeys(const int k)
+{
+  /* This method moves _minor to the next valid (k x k)-minor within
+     _container. It returns true iff this is successful, i.e. iff
+     _minor did not already encode the terminal (k x k)-minor. */
+  if (_minor.compare(MinorKey(0, 0, 0, 0)) == 0)
+  {
+    /* This means that we haven't started yet. Thus, we are about
+       to compute the first (k x k)-minor. */
+    _minor.selectFirstRows(k, _container);
+    _minor.selectFirstColumns(k, _container);
+    return true;
+  }
+  else if (_minor.selectNextColumns(k, _container))
+  {
+    /* Here we were able to pick a next subset of columns
+       within the same subset of rows. */
+    return true;
+  }
+  else if (_minor.selectNextRows(k, _container))
+  {
+    /* Here we were not able to pick a next subset of columns
+       within the same subset of rows. But we could pick a next
+       subset of rows. We must hence reset the subset of columns: */
+    _minor.selectFirstColumns(k, _container);
+    return true;
+  }
+  else
+  {
+    /* We were neither able to pick a next subset
+       of columns nor of rows. I.e., we have iterated through
+       all sensible choices of subsets of rows and columns. */
+    return false;
+  }
+}
+
+bool MinorProcessor::isEntryZero (const int /*absoluteRowIndex*/,
+                                  const int /*absoluteColumnIndex*/) const
+{
+  assume(false);
+  return false;
+}
+
+string MinorProcessor::toString () const
+{
+  assume(false);
+  return "";
+}
+
+int MinorProcessor::IOverJ(const int i, const int j)
+{
+  /* This is a non-recursive implementation. */
+  assume( (i >= 0) && (j >= 0) && (i >= j));
+  if (j == 0 || i == j) return 1;
+  int result = 1;
+  for (int k = i - j + 1; k <= i; k++) result *= k;
+  /* Now, result = (i - j + 1) * ... * i. */
+  for (int k = 2; k <= j; k++) result /= k;
+  /* Now, result = (i - j + 1) * ... * i / 1 / 2 ...
+     ... / j = i! / j! / (i - j)!. */
+  return result;
+}
+
+int MinorProcessor::Faculty(const int i)
+{
+  /* This is a non-recursive implementation. */
+  assume(i >= 0);
+  int result = 1;
+  for (int j = 1; j <= i; j++) result *= j;
+  // Now, result = 1 * 2 * ... * i = i!
+  return result;
+}
+
+int MinorProcessor::NumberOfRetrievals (const int rows, const int columns,
+                                        const int containerMinorSize,
+                                        const int minorSize,
+                                        const bool multipleMinors)
+{
+  /* This method computes the number of potential retrievals
+     of a single minor when computing all minors of a given size
+     within a matrix of given size. */
+  int result = 0;
+  if (multipleMinors)
+  {
+    /* Here, we would like to compute all minors of size
+       containerMinorSize x containerMinorSize in a matrix
+       of size rows x columns.
+       Then, we need to retrieve any minor of size
+       minorSize x minorSize exactly n times, where n is as
+       follows: */
+    result = IOverJ(rows - minorSize, containerMinorSize - minorSize)
+           * IOverJ(columns - minorSize, containerMinorSize - minorSize)
+           * Faculty(containerMinorSize - minorSize);
+  }
+  else
+  {
+    /* Here, we would like to compute just one minor of size
+       containerMinorSize x containerMinorSize. Then, we need
+       to retrieve any minor of size minorSize x minorSize exactly
+       (containerMinorSize - minorSize)! times: */
+    result = Faculty(containerMinorSize - minorSize);
+  }
+  return result;
+}
+
+MinorProcessor::MinorProcessor ()
+{
+  _container = MinorKey(0, 0, 0, 0);
+  _minor = MinorKey(0, 0, 0, 0);
+  _containerRows = 0;
+  _containerColumns = 0;
+  _minorSize = 0;
+  _rows = 0;
+  _columns = 0;
+}
+
+MinorProcessor::~MinorProcessor () { }
+
+IntMinorProcessor::IntMinorProcessor ()
+{
+  _intMatrix = 0;
+}
+
+string IntMinorProcessor::toString () const
+{
+  char h[32];
+  string t = "";
+  string s = "IntMinorProcessor:";
+  s += "\n   matrix: ";
+  sprintf(h, "%d", _rows); s += h;
+  s += " x ";
+  sprintf(h, "%d", _columns); s += h;
+  for (int r = 0; r < _rows; r++)
+  {
+    s += "\n      ";
+    for (int c = 0; c < _columns; c++)
+    {
+      sprintf(h, "%d", getEntry(r, c)); t = h;
+      for (int k = 0; k < int(4 - strlen(h)); k++) s += " ";
+      s += t;
+    }
+  }
+  int myIndexArray[500];
+  s += "\n   considered submatrix has row indices: ";
+  _container.getAbsoluteRowIndices(myIndexArray);
+  for (int k = 0; k < _containerRows; k++)
+  {
+    if (k != 0) s += ", ";
+    sprintf(h, "%d", myIndexArray[k]); s += h;
+  }
+  s += " (first row of matrix has index 0)";
+  s += "\n   considered submatrix has column indices: ";
+  _container.getAbsoluteColumnIndices(myIndexArray);
+  for (int k = 0; k < _containerColumns; k++)
+  {
+    if (k != 0) s += ", ";
+    sprintf(h, "%d", myIndexArray[k]); s += h;
+  }
+  s += " (first column of matrix has index 0)";
+  s += "\n   size of considered minor(s): ";
+  sprintf(h, "%d", _minorSize); s += h;
+  s += "x";
+  s += h;
+  return s;
+}
+
+IntMinorProcessor::~IntMinorProcessor()
+{
+  /* free memory of _intMatrix */
+  delete [] _intMatrix; _intMatrix = 0;
+}
+
+bool IntMinorProcessor::isEntryZero (const int absoluteRowIndex,
+                                     const int absoluteColumnIndex) const
+{
+  return getEntry(absoluteRowIndex, absoluteColumnIndex) == 0;
+}
+
+void IntMinorProcessor::defineMatrix (const int numberOfRows,
+                                      const int numberOfColumns,
+                                      const int* matrix)
+{
+  /* free memory of _intMatrix */
+  delete [] _intMatrix; _intMatrix = 0;
+
+  _rows = numberOfRows;
+  _columns = numberOfColumns;
+
+  /* allocate memory for new entries in _intMatrix */
+  int n = _rows * _columns;
+  _intMatrix = new int[n];
+
+  /* copying values from one-dimensional method
+     parameter "matrix" */
+  for (int i = 0; i < n; i++)
+    _intMatrix[i] = matrix[i];
+}
+
+IntMinorValue IntMinorProcessor::getMinor(const int dimension,
+                                          const int* rowIndices,
+                                          const int* columnIndices,
+                                          Cache<MinorKey, IntMinorValue>& c,
+                                          const int characteristic,
+                                          const ideal& iSB)
+{
+  defineSubMatrix(dimension, rowIndices, dimension, columnIndices);
+  _minorSize = dimension;
+  /* call a helper method which recursively computes the minor using the
+     cache c: */
+  return getMinorPrivateLaplace(dimension, _container, false, c,
+                                characteristic, iSB);
+}
+
+IntMinorValue IntMinorProcessor::getMinor(const int dimension,
+                                          const int* rowIndices,
+                                          const int* columnIndices,
+                                          const int characteristic,
+                                          const ideal& iSB,
+                                          const char* algorithm)
+{
+  defineSubMatrix(dimension, rowIndices, dimension, columnIndices);
+  _minorSize = dimension;
+
+  /* call a helper method which computes the minor (without a cache): */
+  if (strcmp(algorithm, "Laplace") == 0)
+    return getMinorPrivateLaplace(_minorSize, _container, characteristic,
+                                  iSB);
+  else if (strcmp(algorithm, "Bareiss") == 0)
+    return getMinorPrivateBareiss(_minorSize, _container, characteristic,
+                                  iSB);
+  else assume(false);
+
+  /* The following code is never reached and just there to make the
+     compiler happy: */
+  return IntMinorValue();
+}
+
+IntMinorValue IntMinorProcessor::getNextMinor(const int characteristic,
+                                              const ideal& iSB,
+                                              const char* algorithm)
+{
+  /* call a helper method which computes the minor (without a cache): */
+  if (strcmp(algorithm, "Laplace") == 0)
+    return getMinorPrivateLaplace(_minorSize, _minor, characteristic, iSB);
+  else if (strcmp(algorithm, "Bareiss") == 0)
+    return getMinorPrivateBareiss(_minorSize, _minor, characteristic, iSB);
+  else assume(false);
+
+  /* The following code is never reached and just there to make the
+     compiler happy: */
+  return IntMinorValue();
+}
+
+IntMinorValue IntMinorProcessor::getNextMinor(Cache<MinorKey,
+                                              IntMinorValue>& c,
+                                              const int characteristic,
+                                              const ideal& iSB)
+{
+    /* computation with cache */
+    return getMinorPrivateLaplace(_minorSize, _minor, true, c, characteristic,
+                                  iSB);
+}
+
+/* computes the reduction of an integer i modulo an ideal
+   which captures a std basis */
+int getReduction (const int i, const ideal& iSB)
+{
+  if (i == 0) return 0;
+  poly f = pISet(i);
+  poly g = kNF(iSB, currRing->qideal, f);
+  int result = 0;
+  if (g != NULL) result = n_Int(pGetCoeff(g), currRing->cf);
+  pDelete(&f);
+  pDelete(&g);
+  return result;
+}
+
+IntMinorValue IntMinorProcessor::getMinorPrivateLaplace(
+     const int k,
+     const MinorKey& mk,
+     const int characteristic,
+     const ideal& iSB)
+{
+  assume(k > 0); /* k is the minor's dimension; the minor must be at least
+                    1x1 */
+  /* The method works by recursion, and using Lapace's Theorem along the
+     row/column with the most zeros. */
+  if (k == 1)
+  {
+    int e = getEntry(mk.getAbsoluteRowIndex(0), mk.getAbsoluteColumnIndex(0));
+    if (characteristic != 0) e = e % characteristic;
+    if (iSB != 0) e = getReduction(e, iSB);
+    return IntMinorValue(e, 0, 0, 0, 0, -1, -1); /* "-1" is to signal that any
+                                                    statistics about the number
+                                                    of retrievals does not make
+                                                    sense, as we do not use a
+                                                    cache. */
+  }
+  else
+  {
+    /* Here, the minor must be 2x2 or larger. */
+    int b = getBestLine(k, mk);                   /* row or column with most
+                                                     zeros */
+    int result = 0;                               /* This will contain the
+                                                     value of the minor. */
+    int s = 0; int m = 0; int as = 0; int am = 0; /* counters for additions and
+                                                     multiplications, ..."a*"
+                                                     for accumulated operation
+                                                     counters */
+    bool hadNonZeroEntry = false;
+    if (b >= 0)
+    {
+      /* This means that the best line is the row with absolute (0-based)
+         index b.
+         Using Laplace, the sign of the contributing minors must be iterating;
+         the initial sign depends on the relative index of b in minorRowKey: */
+      int sign = (mk.getRelativeRowIndex(b) % 2 == 0 ? 1 : -1);
+      for (int c = 0; c < k; c++) /* This iterates over all involved columns. */
+      {
+        int absoluteC = mk.getAbsoluteColumnIndex(c);
+        if (getEntry(b, absoluteC) != 0) /* Only then do we have to consider
+                                            this sub-determinante. */
+        {
+          hadNonZeroEntry = true;
+          /* Next MinorKey is mk with row b and column absoluteC omitted: */
+          MinorKey subMk = mk.getSubMinorKey(b, absoluteC);
+          IntMinorValue mv = getMinorPrivateLaplace(k - 1, subMk,
+                             characteristic, iSB);  /* recursive call */
+          m += mv.getMultiplications();
+          s += mv.getAdditions();
+          am += mv.getAccumulatedMultiplications();
+          as += mv.getAccumulatedAdditions();
+          /* adding sub-determinante times matrix entry
+             times appropriate sign: */
+          result += sign * mv.getResult() * getEntry(b, absoluteC);
+
+          if (characteristic != 0) result = result % characteristic;
+          s++; m++; as++, am++; /* This is for the last addition and
+                                   multiplication. */
+        }
+        sign = - sign; /* alternating the sign */
+      }
+    }
+    else
+    {
+      b = - b - 1;
+      /* This means that the best line is the column with absolute (0-based)
+         index b.
+         Using Laplace, the sign of the contributing minors must be iterating;
+         the initial sign depends on the relative index of b in
+         minorColumnKey: */
+      int sign = (mk.getRelativeColumnIndex(b) % 2 == 0 ? 1 : -1);
+      for (int r = 0; r < k; r++) /* This iterates over all involved rows. */
+      {
+        int absoluteR = mk.getAbsoluteRowIndex(r);
+        if (getEntry(absoluteR, b) != 0) /* Only then do we have to consider
+                                            this sub-determinante. */
+        {
+          hadNonZeroEntry = true;
+          /* Next MinorKey is mk with row absoluteR and column b omitted. */
+          MinorKey subMk = mk.getSubMinorKey(absoluteR, b);
+          IntMinorValue mv = getMinorPrivateLaplace(k - 1, subMk, characteristic, iSB); /* recursive call */
+          m += mv.getMultiplications();
+          s += mv.getAdditions();
+          am += mv.getAccumulatedMultiplications();
+          as += mv.getAccumulatedAdditions();
+          /* adding sub-determinante times matrix entry
+             times appropriate sign: */
+          result += sign * mv.getResult() * getEntry(absoluteR, b);
+          if (characteristic != 0) result = result % characteristic;
+          s++; m++; as++, am++; /* This is for the last addition and
+                                   multiplication. */
+        }
+        sign = - sign; /* alternating the sign */
+      }
+    }
+    if (hadNonZeroEntry)
+    {
+      s--; as--; /* first addition was 0 + ..., so we do not count it */
+    }
+    if (s < 0) s = 0; /* may happen when all subminors are zero and no
+                         addition needs to be performed */
+    if (as < 0) as = 0; /* may happen when all subminors are zero and no
+                           addition needs to be performed */
+    if (iSB != 0) result = getReduction(result, iSB);
+    IntMinorValue newMV(result, m, s, am, as, -1, -1);
+    /* "-1" is to signal that any statistics about the number of retrievals
+       does not make sense, as we do not use a cache. */
+    return newMV;
+  }
+}
+
+/* This method can only be used in the case of coefficients
+   coming from a field or at least from an integral domain. */
+IntMinorValue IntMinorProcessor::getMinorPrivateBareiss(
+     const int k,
+     const MinorKey& mk,
+     const int characteristic,
+     const ideal& iSB)
+{
+  assume(k > 0); /* k is the minor's dimension; the minor must be at least
+                    1x1 */
+  int *theRows=new int[k]; mk.getAbsoluteRowIndices(theRows);
+  int *theColumns=new int[k]; mk.getAbsoluteColumnIndices(theColumns);
+  /* the next line provides the return value for the case k = 1 */
+  int e = getEntry(theRows[0], theColumns[0]);
+  if (characteristic != 0) e = e % characteristic;
+  if (iSB != 0) e = getReduction(e, iSB);
+  IntMinorValue mv(e, 0, 0, 0, 0, -1, -1);
+  if (k > 1)
+  {
+    /* the matrix to perform Bareiss with */
+    long *tempMatrix=new long[k * k];
+    /* copy correct set of entries from _intMatrix to tempMatrix */
+    int i = 0;
+    for (int r = 0; r < k; r++)
+      for (int c = 0; c < k; c++)
+      {
+        e = getEntry(theRows[r], theColumns[c]);
+        if (characteristic != 0) e = e % characteristic;
+        tempMatrix[i++] = e;
+      }
+    /* Bareiss algorithm operating on tempMatrix which is at least 2x2 */
+    int sign = 1;   /* This will store the correct sign resulting
+                       from permuting the rows of tempMatrix. */
+    int *rowPermutation=new int[k];
+                    /* This is for storing the permutation of rows
+                       resulting from searching for a non-zero
+                       pivot element. */
+    for (int i = 0; i < k; i++) rowPermutation[i] = i;
+    int divisor = 1;   /* the Bareiss divisor */
+    for (int r = 0; r <= k - 2; r++)
+    {
+      /* look for a non-zero entry in column r: */
+      int i = r;
+      while ((i < k) && (tempMatrix[rowPermutation[i] * k + r] == 0))
+        i++;
+      if (i == k)
+        /* There is no non-zero entry; hence the minor is zero. */
+        return IntMinorValue(0, 0, 0, 0, 0, -1, -1);
+      if (i != r)
+      {
+        /* We swap the rows with indices r and i: */
+        int j = rowPermutation[i];
+        rowPermutation[i] = rowPermutation[r];
+        rowPermutation[r] = j;
+        /* Now we know that tempMatrix[rowPermutation[r] * k + r] is not zero.
+           But carefull; we have to negate the sign, as there is always an odd
+           number of row transpositions to swap two given rows of a matrix. */
+        sign = -sign;
+      }
+      if (r >= 1) divisor = tempMatrix[rowPermutation[r - 1] * k + r - 1];
+      for (int rr = r + 1; rr < k; rr++)
+        for (int cc = r + 1; cc < k; cc++)
+        {
+          e = rowPermutation[rr] * k + cc;
+          /* Attention: The following may cause an overflow and
+             thus a wrong result: */
+          tempMatrix[e] = tempMatrix[e] * tempMatrix[rowPermutation[r] * k + r]
+                         - tempMatrix[rowPermutation[r] * k + cc]
+                         * tempMatrix[rowPermutation[rr] * k + r];
+          /* The following is, by theory, always a division without
+             remainder: */
+          tempMatrix[e] = tempMatrix[e] / divisor;
+          if (characteristic != 0)
+            tempMatrix[e] = tempMatrix[e] % characteristic;
+        }
+      delete[] rowPermutation;
+      delete[] tempMatrix;
+    }
+    int theValue = sign * tempMatrix[rowPermutation[k - 1] * k + k - 1];
+    if (iSB != 0) theValue = getReduction(theValue, iSB);
+    mv = IntMinorValue(theValue, 0, 0, 0, 0, -1, -1);
+  }
+  delete [] theRows;
+  delete [] theColumns;
+  return mv;
+}
+
+int IntMinorProcessor::getEntry (const int rowIndex,
+                                 const int columnIndex) const
+{
+  return _intMatrix[rowIndex * _columns + columnIndex];
+}
+
+IntMinorValue IntMinorProcessor::getMinorPrivateLaplace(
+     const int k, const MinorKey& mk,
+     const bool multipleMinors,
+     Cache<MinorKey, IntMinorValue>& cch,
+     const int characteristic, const ideal& iSB)
+{
+  assume(k > 0); /* k is the minor's dimension; the minor must be at least
+                    1x1 */
+  /* The method works by recursion, and using Lapace's Theorem along
+     the row/column with the most zeros. */
+  if (k == 1)
+  {
+    int e = getEntry(mk.getAbsoluteRowIndex(0), mk.getAbsoluteColumnIndex(0));
+    if (characteristic != 0) e = e % characteristic;
+    if (iSB != 0) e = getReduction(e, iSB);
+    return IntMinorValue(e, 0, 0, 0, 0, -1, -1);
+    /* we set "-1" as, for k == 1, we do not have any cache retrievals */
+  }
+  else
+  {
+    int b = getBestLine(k, mk);                   /* row or column with
+                                                     most zeros */
+    int result = 0;                               /* This will contain the
+                                                     value of the minor. */
+    int s = 0; int m = 0; int as = 0; int am = 0; /* counters for additions
+                                                     and multiplications,
+                                                     ..."a*" for
+                                                     accumulated operation
+                                                     counters */
+    IntMinorValue mv(0, 0, 0, 0, 0, 0, 0);        /* for storing all
+                                                     intermediate minors */
+    bool hadNonZeroEntry = false;
+    if (b >= 0)
+    {
+      /* This means that the best line is the row with absolute (0-based)
+         index b.
+         Using Laplace, the sign of the contributing minors must be
+         iterating; the initial sign depends on the relative index of b
+         in minorRowKey: */
+      int sign = (mk.getRelativeRowIndex(b) % 2 == 0 ? 1 : -1);
+      for (int c = 0; c < k; c++) /* This iterates over all involved
+                                     columns. */
+      {
+        int absoluteC = mk.getAbsoluteColumnIndex(c);
+        if (getEntry(b, absoluteC) != 0) /* Only then do we have to consider
+                                            this sub-determinante. */
+        {
+          hadNonZeroEntry = true;
+          /* Next MinorKey is mk with row b and column absoluteC omitted. */
+          MinorKey subMk = mk.getSubMinorKey(b, absoluteC);
+          if (cch.hasKey(subMk))
+          { /* trying to find the result in the cache */
+              mv = cch.getValue(subMk);
+              mv.incrementRetrievals(); /* once more, we made use of the cached
+                                           value for key mk */
+              cch.put(subMk, mv); /* We need to do this with "put", as the
+                                     (altered) number of retrievals may have
+                                     an impact on the internal ordering among
+                                     the cached entries. */
+          }
+          else
+          {
+              mv = getMinorPrivateLaplace(k - 1, subMk, multipleMinors, cch,
+                   characteristic, iSB); /* recursive call */
+              /* As this minor was not in the cache, we count the additions
+                 and multiplications that we needed to perform in the
+                 recursive call: */
+              m += mv.getMultiplications();
+              s += mv.getAdditions();
+          }
+          /* In any case, we count all nested operations in the accumulative
+             counters: */
+          am += mv.getAccumulatedMultiplications();
+          as += mv.getAccumulatedAdditions();
+          /* adding sub-determinante times matrix entry times appropriate
+             sign */
+          result += sign * mv.getResult() * getEntry(b, absoluteC);
+          if (characteristic != 0) result = result % characteristic;
+          s++; m++; as++; am++; /* This is for the last addition and
+                                   multiplication. */
+        }
+        sign = - sign; /* alternating the sign */
+      }
+    }
+    else
+    {
+      b = - b - 1;
+      /* This means that the best line is the column with absolute (0-based)
+         index b.
+         Using Laplace, the sign of the contributing minors must be iterating;
+         the initial sign depends on the relative index of b in
+         minorColumnKey: */
+      int sign = (mk.getRelativeColumnIndex(b) % 2 == 0 ? 1 : -1);
+      for (int r = 0; r < k; r++) /* This iterates over all involved rows. */
+      {
+        int absoluteR = mk.getAbsoluteRowIndex(r);
+        if (getEntry(absoluteR, b) != 0) /* Only then do we have to consider
+                                            this sub-determinante. */
+        {
+          hadNonZeroEntry = true;
+          /* Next MinorKey is mk with row absoluteR and column b omitted. */
+          MinorKey subMk = mk.getSubMinorKey(absoluteR, b);
+          if (cch.hasKey(subMk))
+          { /* trying to find the result in the cache */
+            mv = cch.getValue(subMk);
+            mv.incrementRetrievals(); /* once more, we made use of the cached
+                                         value for key mk */
+            cch.put(subMk, mv); /* We need to do this with "put", as the
+                                   (altered) number of retrievals may have an
+                                   impact on the internal ordering among the
+                                   cached entries. */
+          }
+          else
+          {
+            mv = getMinorPrivateLaplace(k - 1, subMk, multipleMinors, cch, characteristic, iSB); /* recursive call */
+            /* As this minor was not in the cache, we count the additions and
+               multiplications that we needed to do in the recursive call: */
+            m += mv.getMultiplications();
+            s += mv.getAdditions();
+          }
+          /* In any case, we count all nested operations in the accumulative
+             counters: */
+          am += mv.getAccumulatedMultiplications();
+          as += mv.getAccumulatedAdditions();
+          /* adding sub-determinante times matrix entry times appropriate
+             sign: */
+          result += sign * mv.getResult() * getEntry(absoluteR, b);
+          if (characteristic != 0) result = result % characteristic;
+          s++; m++; as++; am++; /* This is for the last addition and
+                                   multiplication. */
+        }
+        sign = - sign; /* alternating the sign */
+      }
+    }
+    /* Let's cache the newly computed minor: */
+    int potentialRetrievals = NumberOfRetrievals(_containerRows,
+                                                 _containerColumns,
+                                                 _minorSize, k,
+                                                 multipleMinors);
+    if (hadNonZeroEntry)
+    {
+      s--; as--; /* first addition was 0 + ..., so we do not count it */
+    }
+    if (s < 0) s = 0; /* may happen when all subminors are zero and no
+                         addition needs to be performed */
+    if (as < 0) as = 0; /* may happen when all subminors are zero and no
+                           addition needs to be performed */
+    if (iSB != 0) result = getReduction(result, iSB);
+    IntMinorValue newMV(result, m, s, am, as, 1, potentialRetrievals);
+    cch.put(mk, newMV); /* Here's the actual put inside the cache. */
+    return newMV;
+  }
+}
+
+PolyMinorProcessor::PolyMinorProcessor ()
+{
+  _polyMatrix = 0;
+}
+
+poly PolyMinorProcessor::getEntry (const int rowIndex,
+                                   const int columnIndex) const
+{
+  return _polyMatrix[rowIndex * _columns + columnIndex];
+}
+
+bool PolyMinorProcessor::isEntryZero (const int absoluteRowIndex,
+                                      const int absoluteColumnIndex) const
+{
+  return getEntry(absoluteRowIndex, absoluteColumnIndex) == NULL;
+}
+
+string PolyMinorProcessor::toString () const
+{
+  char h[32];
+  string t = "";
+  string s = "PolyMinorProcessor:";
+  s += "\n   matrix: ";
+  sprintf(h, "%d", _rows); s += h;
+  s += " x ";
+  sprintf(h, "%d", _columns); s += h;
+  int myIndexArray[500];
+  s += "\n   considered submatrix has row indices: ";
+  _container.getAbsoluteRowIndices(myIndexArray);
+  for (int k = 0; k < _containerRows; k++)
+  {
+    if (k != 0) s += ", ";
+    sprintf(h, "%d", myIndexArray[k]); s += h;
+  }
+  s += " (first row of matrix has index 0)";
+  s += "\n   considered submatrix has column indices: ";
+  _container.getAbsoluteColumnIndices(myIndexArray);
+  for (int k = 0; k < _containerColumns; k++)
+  {
+    if (k != 0) s += ", ";
+    sprintf(h, "%d", myIndexArray[k]); s += h;
+  }
+  s += " (first column of matrix has index 0)";
+  s += "\n   size of considered minor(s): ";
+  sprintf(h, "%d", _minorSize); s += h;
+  s += "x";
+  s += h;
+  return s;
+}
+
+PolyMinorProcessor::~PolyMinorProcessor()
+{
+  /* free memory of _polyMatrix */
+  int n = _rows * _columns;
+  for (int i = 0; i < n; i++)
+    p_Delete(&_polyMatrix[i], currRing);
+  delete [] _polyMatrix; _polyMatrix = 0;
+}
+
+void PolyMinorProcessor::defineMatrix (const int numberOfRows,
+                                       const int numberOfColumns,
+                                       const poly* polyMatrix)
+{
+  /* free memory of _polyMatrix */
+  int n = _rows * _columns;
+  for (int i = 0; i < n; i++)
+    p_Delete(&_polyMatrix[i], currRing);
+  delete [] _polyMatrix; _polyMatrix = 0;
+
+  _rows = numberOfRows;
+  _columns = numberOfColumns;
+  n = _rows * _columns;
+
+  /* allocate memory for new entries in _polyMatrix */
+  _polyMatrix = new poly[n];
+
+  /* copying values from one-dimensional method
+     parameter "polyMatrix" */
+  for (int i = 0; i < n; i++)
+    _polyMatrix[i] = pCopy(polyMatrix[i]);
+}
+
+PolyMinorValue PolyMinorProcessor::getMinor(const int dimension,
+                                            const int* rowIndices,
+                                            const int* columnIndices,
+                                            Cache<MinorKey, PolyMinorValue>& c,
+                                            const ideal& iSB)
+{
+  defineSubMatrix(dimension, rowIndices, dimension, columnIndices);
+  _minorSize = dimension;
+  /* call a helper method which recursively computes the minor using the cache
+     c: */
+  return getMinorPrivateLaplace(dimension, _container, false, c, iSB);
+}
+
+PolyMinorValue PolyMinorProcessor::getMinor(const int dimension,
+                                            const int* rowIndices,
+                                            const int* columnIndices,
+                                            const char* algorithm,
+                                            const ideal& iSB)
+{
+  defineSubMatrix(dimension, rowIndices, dimension, columnIndices);
+  _minorSize = dimension;
+  /* call a helper method which computes the minor (without using a cache): */
+  if (strcmp(algorithm, "Laplace") == 0)
+    return getMinorPrivateLaplace(_minorSize, _container, iSB);
+  else if (strcmp(algorithm, "Bareiss") == 0)
+    return getMinorPrivateBareiss(_minorSize, _container, iSB);
+  else assume(false);
+
+  /* The following code is never reached and just there to make the
+     compiler happy: */
+  return PolyMinorValue();
+}
+
+PolyMinorValue PolyMinorProcessor::getNextMinor(const char* algorithm,
+                                                const ideal& iSB)
+{
+  /* call a helper method which computes the minor (without using a
+     cache): */
+  if (strcmp(algorithm, "Laplace") == 0)
+    return getMinorPrivateLaplace(_minorSize, _minor, iSB);
+  else if (strcmp(algorithm, "Bareiss") == 0)
+    return getMinorPrivateBareiss(_minorSize, _minor, iSB);
+  else assume(false);
+
+  /* The following code is never reached and just there to make the
+     compiler happy: */
+  return PolyMinorValue();
+}
+
+PolyMinorValue PolyMinorProcessor::getNextMinor(Cache<MinorKey,
+                                                PolyMinorValue>& c,
+                                                const ideal& iSB)
+{
+    /* computation with cache */
+    return getMinorPrivateLaplace(_minorSize, _minor, true, c, iSB);
+}
+
+/* assumes that all entries in polyMatrix are already reduced w.r.t. iSB */
+PolyMinorValue PolyMinorProcessor::getMinorPrivateLaplace(const int k,
+                                                          const MinorKey& mk,
+                                                          const ideal& iSB)
+{
+  assume(k > 0); /* k is the minor's dimension; the minor must be at least
+                    1x1 */
+  /* The method works by recursion, and using Lapace's Theorem along the
+     row/column with the most zeros. */
+  if (k == 1)
+  {
+    PolyMinorValue pmv(getEntry(mk.getAbsoluteRowIndex(0),
+                                mk.getAbsoluteColumnIndex(0)),
+                       0, 0, 0, 0, -1, -1);
+    /* "-1" is to signal that any statistics about the number of retrievals
+       does not make sense, as we do not use a cache. */
+    return pmv;
+  }
+  else
+  {
+    /* Here, the minor must be 2x2 or larger. */
+    int b = getBestLine(k, mk);                   /* row or column with most
+                                                     zeros */
+    poly result = NULL;                           /* This will contain the
+                                                     value of the minor. */
+    int s = 0; int m = 0; int as = 0; int am = 0; /* counters for additions
+                                                     and multiplications,
+                                                     ..."a*" for accumulated
+                                                     operation counters */
+    bool hadNonZeroEntry = false;
+    if (b >= 0)
+    {
+      /* This means that the best line is the row with absolute (0-based)
+         index b.
+         Using Laplace, the sign of the contributing minors must be iterating;
+         the initial sign depends on the relative index of b in minorRowKey: */
+      int sign = (mk.getRelativeRowIndex(b) % 2 == 0 ? 1 : -1);
+      poly signPoly = NULL;
+      for (int c = 0; c < k; c++) /* This iterates over all involved columns. */
+      {
+        int absoluteC = mk.getAbsoluteColumnIndex(c);
+        if (!isEntryZero(b, absoluteC)) /* Only then do we have to consider
+                                           this sub-determinante. */
+        {
+          hadNonZeroEntry = true;
+          /* Next MinorKey is mk with row b and column absoluteC omitted. */
+          MinorKey subMk = mk.getSubMinorKey(b, absoluteC);
+          /* recursive call: */
+          PolyMinorValue mv = getMinorPrivateLaplace(k - 1, subMk, iSB);
+          m += mv.getMultiplications();
+          s += mv.getAdditions();
+          am += mv.getAccumulatedMultiplications();
+          as += mv.getAccumulatedAdditions();
+          pDelete(&signPoly);
+          signPoly = pISet(sign);
+          poly temp = pp_Mult_qq(mv.getResult(), getEntry(b, absoluteC),
+                                 currRing);
+          temp = p_Mult_q(signPoly, temp, currRing);
+          result = p_Add_q(result, temp, currRing);
+#ifdef COUNT_AND_PRINT_OPERATIONS
+          multsPoly++;
+          addsPoly++;
+          multsMon += pLength(mv.getResult()) * pLength(getEntry(b, absoluteC));
+#endif
+          signPoly = NULL;
+          s++; m++; as++, am++; /* This is for the addition and multiplication
+                                   in the previous lines of code. */
+        }
+        sign = - sign; /* alternating the sign */
+      }
+    }
+    else
+    {
+      b = - b - 1;
+      /* This means that the best line is the column with absolute (0-based)
+         index b.
+         Using Laplace, the sign of the contributing minors must be iterating;
+         the initial sign depends on the relative index of b in
+         minorColumnKey: */
+      int sign = (mk.getRelativeColumnIndex(b) % 2 == 0 ? 1 : -1);
+      poly signPoly = NULL;
+      for (int r = 0; r < k; r++) /* This iterates over all involved rows. */
+      {
+        int absoluteR = mk.getAbsoluteRowIndex(r);
+        if (!isEntryZero(absoluteR, b)) /* Only then do we have to consider
+                                           this sub-determinante. */
+        {
+          hadNonZeroEntry = true;
+          /* This is mk with row absoluteR and column b omitted. */
+          MinorKey subMk = mk.getSubMinorKey(absoluteR, b);
+          /* recursive call: */
+          PolyMinorValue mv = getMinorPrivateLaplace(k - 1, subMk, iSB);
+          m += mv.getMultiplications();
+          s += mv.getAdditions();
+          am += mv.getAccumulatedMultiplications();
+          as += mv.getAccumulatedAdditions();
+          pDelete(&signPoly);
+          signPoly = pISet(sign);
+          poly temp = pp_Mult_qq(mv.getResult(), getEntry(absoluteR, b),
+                                 currRing);
+          temp = p_Mult_q(signPoly, temp, currRing);
+          result = p_Add_q(result, temp, currRing);
+#ifdef COUNT_AND_PRINT_OPERATIONS
+          multsPoly++;
+          addsPoly++;
+          multsMon += pLength(mv.getResult()) * pLength(getEntry(absoluteR, b));
+#endif
+          signPoly = NULL;
+          s++; m++; as++, am++; /* This is for the addition and multiplication
+                                   in the previous lines of code. */
+        }
+        sign = - sign; /* alternating the sign */
+      }
+    }
+    if (hadNonZeroEntry)
+    {
+      s--; as--; /* first addition was 0 + ..., so we do not count it */
+#ifdef COUNT_AND_PRINT_OPERATIONS
+      addsPoly--;
+#endif
+    }
+    if (s < 0) s = 0; /* may happen when all subminors are zero and no
+                         addition needs to be performed */
+    if (as < 0) as = 0; /* may happen when all subminors are zero and no
+                           addition needs to be performed */
+    if (iSB != 0) result = kNF(iSB, currRing->qideal, result);
+    PolyMinorValue newMV(result, m, s, am, as, -1, -1);
+    /* "-1" is to signal that any statistics about the number of retrievals
+       does not make sense, as we do not use a cache. */
+    pDelete(&result);
+    return newMV;
+  }
+}
+
+/* assumes that all entries in polyMatrix are already reduced w.r.t. iSB */
+PolyMinorValue PolyMinorProcessor::getMinorPrivateLaplace(
+     const int k,
+     const MinorKey& mk,
+     const bool multipleMinors,
+     Cache<MinorKey, PolyMinorValue>& cch,
+     const ideal& iSB)
+{
+  assume(k > 0); /* k is the minor's dimension; the minor must be at least
+                    1x1 */
+  /* The method works by recursion, and using Lapace's Theorem along
+     the row/column with the most zeros. */
+  if (k == 1)
+  {
+    PolyMinorValue pmv(getEntry(mk.getAbsoluteRowIndex(0),
+                                mk.getAbsoluteColumnIndex(0)),
+                       0, 0, 0, 0, -1, -1);
+    /* we set "-1" as, for k == 1, we do not have any cache retrievals */
+    return pmv;
+  }
+  else
+  {
+    int b = getBestLine(k, mk);                   /* row or column with most
+                                                     zeros */
+    poly result = NULL;                           /* This will contain the
+                                                     value of the minor. */
+    int s = 0; int m = 0; int as = 0; int am = 0; /* counters for additions
+                                                     and multiplications,
+                                                     ..."a*" for accumulated
+                                                     operation counters */
+    bool hadNonZeroEntry = false;
+    if (b >= 0)
+    {
+      /* This means that the best line is the row with absolute (0-based)
+         index b.
+         Using Laplace, the sign of the contributing minors must be iterating;
+         the initial sign depends on the relative index of b in
+         minorRowKey: */
+      int sign = (mk.getRelativeRowIndex(b) % 2 == 0 ? 1 : -1);
+      poly signPoly = NULL;
+      for (int c = 0; c < k; c++) /* This iterates over all involved columns. */
+      {
+        int absoluteC = mk.getAbsoluteColumnIndex(c);
+        if (!isEntryZero(b, absoluteC)) /* Only then do we have to consider
+                                           this sub-determinante. */
+        {
+          hadNonZeroEntry = true;
+          PolyMinorValue mv; /* for storing all intermediate minors */
+          /* Next MinorKey is mk with row b and column absoluteC omitted. */
+          MinorKey subMk = mk.getSubMinorKey(b, absoluteC);
+          if (cch.hasKey(subMk))
+          { /* trying to find the result in the cache */
+            mv = cch.getValue(subMk);
+            mv.incrementRetrievals(); /* once more, we made use of the cached
+                                         value for key mk */
+            cch.put(subMk, mv); /* We need to do this with "put", as the
+                                   (altered) number of retrievals may have an
+                                   impact on the internal ordering among cache
+                                   entries. */
+          }
+          else
+          {
+            /* recursive call: */
+            mv = getMinorPrivateLaplace(k - 1, subMk, multipleMinors, cch,
+                                        iSB);
+            /* As this minor was not in the cache, we count the additions and
+               multiplications that we needed to do in the recursive call: */
+            m += mv.getMultiplications();
+            s += mv.getAdditions();
+          }
+          /* In any case, we count all nested operations in the accumulative
+             counters: */
+          am += mv.getAccumulatedMultiplications();
+          as += mv.getAccumulatedAdditions();
+          pDelete(&signPoly);
+          signPoly = pISet(sign);
+          poly temp = pp_Mult_qq(mv.getResult(), getEntry(b, absoluteC),
+                                 currRing);
+          temp = p_Mult_q(signPoly, temp, currRing);
+          result = p_Add_q(result, temp, currRing);
+#ifdef COUNT_AND_PRINT_OPERATIONS
+          multsPoly++;
+          addsPoly++;
+          multsMon += pLength(mv.getResult()) * pLength(getEntry(b, absoluteC));
+#endif
+          signPoly = NULL;
+          s++; m++; as++; am++; /* This is for the addition and multiplication
+                                   in the previous lines of code. */
+        }
+        sign = - sign; /* alternating the sign */
+      }
+    }
+    else
+    {
+      b = - b - 1;
+      /* This means that the best line is the column with absolute (0-based)
+         index b.
+         Using Laplace, the sign of the contributing minors must be iterating;
+         the initial sign depends on the relative index of b in
+         minorColumnKey: */
+      int sign = (mk.getRelativeColumnIndex(b) % 2 == 0 ? 1 : -1);
+      poly signPoly = NULL;
+      for (int r = 0; r < k; r++) /* This iterates over all involved rows. */
+      {
+        int absoluteR = mk.getAbsoluteRowIndex(r);
+        if (!isEntryZero(absoluteR, b)) /* Only then do we have to consider
+                                           this sub-determinante. */
+        {
+          hadNonZeroEntry = true;
+          PolyMinorValue mv; /* for storing all intermediate minors */
+          /* Next MinorKey is mk with row absoluteR and column b omitted. */
+          MinorKey subMk = mk.getSubMinorKey(absoluteR, b);
+          if (cch.hasKey(subMk))
+          { /* trying to find the result in the cache */
+            mv = cch.getValue(subMk);
+            mv.incrementRetrievals(); /* once more, we made use of the cached
+                                         value for key mk */
+            cch.put(subMk, mv); /* We need to do this with "put", as the
+                                   (altered) number of retrievals may have an
+                                   impact on the internal ordering among the
+                                   cached entries. */
+          }
+          else
+          {
+            mv = getMinorPrivateLaplace(k - 1, subMk, multipleMinors, cch,
+                                        iSB); /* recursive call */
+            /* As this minor was not in the cache, we count the additions and
+               multiplications that we needed to do in the recursive call: */
+            m += mv.getMultiplications();
+            s += mv.getAdditions();
+          }
+          /* In any case, we count all nested operations in the accumulative
+             counters: */
+          am += mv.getAccumulatedMultiplications();
+          as += mv.getAccumulatedAdditions();
+          pDelete(&signPoly);
+          signPoly = pISet(sign);
+          poly temp = pp_Mult_qq(mv.getResult(), getEntry(absoluteR, b),
+                                 currRing);
+          temp = p_Mult_q(signPoly, temp, currRing);
+          result = p_Add_q(result, temp, currRing);
+#ifdef COUNT_AND_PRINT_OPERATIONS
+          multsPoly++;
+          addsPoly++;
+          multsMon += pLength(mv.getResult()) * pLength(getEntry(absoluteR, b));
+#endif
+          signPoly = NULL;
+          s++; m++; as++; am++; /* This is for the addition and multiplication
+                                   in the previous lines of code. */
+        }
+        sign = - sign; /* alternating the sign */
+      }
+    }
+    /* Let's cache the newly computed minor: */
+    int potentialRetrievals = NumberOfRetrievals(_containerRows,
+                                                 _containerColumns,
+                                                 _minorSize,
+                                                 k,
+                                                 multipleMinors);
+    if (hadNonZeroEntry)
+    {
+      s--; as--; /* first addition was 0 + ..., so we do not count it */
+#ifdef COUNT_AND_PRINT_OPERATIONS
+      addsPoly--;
+#endif
+    }
+    if (s < 0) s = 0; /* may happen when all subminors are zero and no
+                         addition needs to be performed */
+    if (as < 0) as = 0; /* may happen when all subminors are zero and no
+                           addition needs to be performed */
+    if (iSB != 0) result = kNF(iSB, currRing->qideal, result);
+    PolyMinorValue newMV(result, m, s, am, as, 1, potentialRetrievals);
+    pDelete(&result); result = NULL;
+    cch.put(mk, newMV); /* Here's the actual put inside the cache. */
+    return newMV;
+  }
+}
+
+/* This can only be used in the case of coefficients coming from a field
+   or at least an integral domain. */
+void addOperationBucket(poly& f1, poly& f2, kBucket_pt& bucket)
+{
+  /* fills all terms of f1 * f2 into the bucket */
+  poly a = f1; poly b = f2;
+  int aLen = pLength(a); int bLen = pLength(b);
+  if (aLen > bLen)
+  {
+    b = f1; a = f2; bLen = aLen;
+  }
+  pNormalize(b);
+
+  while (a != NULL)
+  {
+    /* The next line actually uses only LT(a): */
+    kBucket_Plus_mm_Mult_pp(bucket, a, b, bLen);
+    a = pNext(a);
+  }
+}
+
+/* computes the polynomial (p1 * p2 - p3 * p4) and puts result into p1;
+   the method destroys the old value of p1;
+   p2, p3, and p4 may be pNormalize-d but must, apart from that,
+   not be changed;
+   This can only be used in the case of coefficients coming from a field
+   or at least an integral domain. */
+void elimOperationBucketNoDiv(poly &p1, poly &p2, poly &p3, poly &p4)
+{
+#ifdef COUNT_AND_PRINT_OPERATIONS
+  if ((pLength(p1) != 0) && (pLength(p2) != 0))
+  {
+    multsPoly++;
+    multsMon += pLength(p1) * pLength(p2);
+  }
+  if ((pLength(p3) != 0) && (pLength(p4) != 0))
+  {
+    multsPoly++;
+    multsMon += pLength(p3) * pLength(p4);
+  }
+  if ((pLength(p1) != 0) && (pLength(p2) != 0) &&
+      (pLength(p3) != 0) && (pLength(p4) != 0))
+    addsPoly++;
+#endif
+  kBucket_pt myBucket = kBucketCreate(currRing);
+  addOperationBucket(p1, p2, myBucket);
+  poly p3Neg = pNeg(pCopy(p3));
+  addOperationBucket(p3Neg, p4, myBucket);
+  pDelete(&p3Neg);
+  pDelete(&p1);
+  p1 = kBucketClear(myBucket);
+  kBucketDestroy(&myBucket);
+}
+
+/* computes the polynomial (p1 * p2 - p3 * p4) / p5 and puts result into p1;
+   the method destroys the old value of p1;
+   p2, p3, p4, and p5 may be pNormalize-d but must, apart from that,
+   not be changed;
+   c5 is assumed to be the leading coefficient of p5;
+   p5Len is assumed to be the length of p5;
+   This can only be used in the case of coefficients coming from a field
+   or at least an integral domain. */
+void elimOperationBucket(poly &p1, poly &p2, poly &p3, poly &p4, poly &p5,
+                         number &c5, int p5Len)
+{
+#ifdef COUNT_AND_PRINT_OPERATIONS
+  if ((pLength(p1) != 0) && (pLength(p2) != 0))
+  {
+    multsPoly++;
+    multsMon += pLength(p1) * pLength(p2);
+  }
+  if ((pLength(p3) != 0) && (pLength(p4) != 0))
+  {
+    multsPoly++;
+    multsMon += pLength(p3) * pLength(p4);
+  }
+  if ((pLength(p1) != 0) && (pLength(p2) != 0) &&
+      (pLength(p3) != 0) && (pLength(p4) != 0))
+    addsPoly++;
+#endif
+  kBucket_pt myBucket = kBucketCreate(currRing);
+  addOperationBucket(p1, p2, myBucket);
+  poly p3Neg = pNeg(pCopy(p3));
+  addOperationBucket(p3Neg, p4, myBucket);
+  pDelete(&p3Neg);
+
+  /* Now, myBucket contains all terms of p1 * p2 - p3 * p4.
+     Now we need to perform the polynomial division myBucket / p5
+     which is known to work without remainder: */
+  pDelete(&p1); poly helperPoly = NULL;
+
+  poly bucketLm = pCopy(kBucketGetLm(myBucket));
+  while (bucketLm != NULL)
+  {
+    /* divide bucketLm by the leading term of p5 and put result into bucketLm;
+       we start with the coefficients;
+       note that bucketLm will always represent a term */
+    number coeff = nDiv(pGetCoeff(bucketLm), c5);
+    nNormalize(coeff);
+    pSetCoeff(bucketLm, coeff);
+    /* subtract exponent vector of p5 from that of quotient; modifies
+       quotient */
+    p_ExpVectorSub(bucketLm, p5, currRing);
+#ifdef COUNT_AND_PRINT_OPERATIONS
+    divsMon++;
+    multsMonForDiv += p5Len;
+    multsMon += p5Len;
+    savedMultsMFD++;
+    multsPoly++;
+    multsPolyForDiv++;
+    addsPoly++;
+    addsPolyForDiv++;
+#endif
+    kBucket_Minus_m_Mult_p(myBucket, bucketLm, p5, &p5Len);
+    /* The following lines make bucketLm the new leading term of p1,
+       i.e., put bucketLm in front of everything which is already in p1.
+       Thus, after the while loop, we need to revert p1. */
+    helperPoly = bucketLm;
+    helperPoly->next = p1;
+    p1 = helperPoly;
+
+    bucketLm = pCopy(kBucketGetLm(myBucket));
+  }
+  p1 = pReverse(p1);
+  kBucketDestroy(&myBucket);
+}
+
+/* assumes that all entries in polyMatrix are already reduced w.r.t. iSB
+   This can only be used in the case of coefficients coming from a field!!! */
+PolyMinorValue PolyMinorProcessor::getMinorPrivateBareiss(const int k,
+                                                          const MinorKey& mk,
+                                                          const ideal& iSB)
+{
+  assume(k > 0); /* k is the minor's dimension; the minor must be at least
+                    1x1 */
+  int *theRows=new int[k]; mk.getAbsoluteRowIndices(theRows);
+  int *theColumns=new int[k]; mk.getAbsoluteColumnIndices(theColumns);
+  if (k == 1)
+  {
+    PolyMinorValue tmp=PolyMinorValue(getEntry(theRows[0], theColumns[0]),
+                          0, 0, 0, 0, -1, -1);
+    delete[] theColumns;
+    delete[] theRows;
+    return tmp;
+  }
+  else /* k > 0 */
+  {
+    /* the matrix to perform Bareiss with */
+    poly* tempMatrix = (poly*)omAlloc(k * k * sizeof(poly));
+    /* copy correct set of entries from _polyMatrix to tempMatrix */
+    int i = 0;
+    for (int r = 0; r < k; r++)
+      for (int c = 0; c < k; c++)
+        tempMatrix[i++] = pCopy(getEntry(theRows[r], theColumns[c]));
+
+    /* Bareiss algorithm operating on tempMatrix which is at least 2x2 */
+    int sign = 1; /* This will store the correct sign resulting from
+                     permuting the rows of tempMatrix. */
+    int *rowPermutation=new int[k];   /* This is for storing the permutation of rows
+                                resulting from searching for a non-zero pivot
+                                element. */
+    for (int i = 0; i < k; i++) rowPermutation[i] = i;
+    poly divisor = NULL;
+    int divisorLength = 0;
+    number divisorLC;
+    for (int r = 0; r <= k - 2; r++)
+    {
+      /* look for a non-zero entry in column r, rows = r .. (k - 1)
+         s.t. the polynomial has least complexity: */
+      int minComplexity = -1; int complexity = 0; int bestRow = -1;
+      poly pp = NULL;
+      for (int i = r; i < k; i++)
+      {
+        pp = tempMatrix[rowPermutation[i] * k + r];
+        if (pp != NULL)
+        {
+          if (minComplexity == -1)
+          {
+            minComplexity = pSize(pp);
+            bestRow = i;
+          }
+          else
+          {
+            complexity = 0;
+            while ((pp != NULL) && (complexity < minComplexity))
+            {
+              complexity += nSize(pGetCoeff(pp)); pp = pNext(pp);
+            }
+            if (complexity < minComplexity)
+            {
+              minComplexity = complexity;
+              bestRow = i;
+            }
+          }
+          if (minComplexity <= 1) break; /* terminate the search */
+        }
+      }
+      if (bestRow == -1)
+      {
+        /* There is no non-zero entry; hence the minor is zero. */
+        for (int i = 0; i < k * k; i++) pDelete(&tempMatrix[i]);
+        return PolyMinorValue(NULL, 0, 0, 0, 0, -1, -1);
+      }
+      pNormalize(tempMatrix[rowPermutation[bestRow] * k + r]);
+      if (bestRow != r)
+      {
+        /* We swap the rows with indices r and i: */
+        int j = rowPermutation[bestRow];
+        rowPermutation[bestRow] = rowPermutation[r];
+        rowPermutation[r] = j;
+        /* Now we know that tempMatrix[rowPermutation[r] * k + r] is not zero.
+           But carefull; we have to negate the sign, as there is always an odd
+           number of row transpositions to swap two given rows of a matrix. */
+        sign = -sign;
+      }
+#if (defined COUNT_AND_PRINT_OPERATIONS) && (COUNT_AND_PRINT_OPERATIONS > 2)
+      poly w = NULL; int wl = 0;
+      printf("matrix after %d steps:\n", r);
+      for (int u = 0; u < k; u++)
+      {
+        for (int v = 0; v < k; v++)
+        {
+          if ((v < r) && (u > v))
+            wl = 0;
+          else
+          {
+            w = tempMatrix[rowPermutation[u] * k + v];
+            wl = pLength(w);
+          }
+          printf("%5d  ", wl);
+        }
+        printf("\n");
+      }
+      printCounters ("", false);
+#endif
+      if (r != 0)
+      {
+        divisor = tempMatrix[rowPermutation[r - 1] * k + r - 1];
+        pNormalize(divisor);
+        divisorLength = pLength(divisor);
+        divisorLC = pGetCoeff(divisor);
+      }
+      for (int rr = r + 1; rr < k; rr++)
+        for (int cc = r + 1; cc < k; cc++)
+        {
+          if (r == 0)
+            elimOperationBucketNoDiv(tempMatrix[rowPermutation[rr] * k + cc],
+                                     tempMatrix[rowPermutation[r]  * k + r],
+                                     tempMatrix[rowPermutation[r]  * k + cc],
+                                     tempMatrix[rowPermutation[rr] * k + r]);
+          else
+            elimOperationBucket(tempMatrix[rowPermutation[rr] * k + cc],
+                                tempMatrix[rowPermutation[r]  * k + r],
+                                tempMatrix[rowPermutation[r]  * k + cc],
+                                tempMatrix[rowPermutation[rr] * k + r],
+                                divisor, divisorLC, divisorLength);
+        }
+    }
+#if (defined COUNT_AND_PRINT_OPERATIONS) && (COUNT_AND_PRINT_OPERATIONS > 2)
+    poly w = NULL; int wl = 0;
+    printf("matrix after %d steps:\n", k - 1);
+    for (int u = 0; u < k; u++)
+    {
+      for (int v = 0; v < k; v++)
+      {
+        if ((v < k - 1) && (u > v))
+          wl = 0;
+        else
+        {
+          w = tempMatrix[rowPermutation[u] * k + v];
+          wl = pLength(w);
+        }
+        printf("%5d  ", wl);
+      }
+      printf("\n");
+    }
+#endif
+    poly result = tempMatrix[rowPermutation[k - 1] * k + k - 1];
+    if (sign == -1) result = pNeg(result);
+    if (iSB != 0) result = kNF(iSB, currRing->qideal, result);
+    PolyMinorValue mv(result, 0, 0, 0, 0, -1, -1);
+    for (int i = 0; i < k * k; i++) pDelete(&tempMatrix[i]);
+    omFreeSize(tempMatrix, k * k * sizeof(poly));
+    delete[] rowPermutation;
+    delete[] theColumns;
+    delete[] theRows;
+    return mv;
+  }
+}
+
diff --git a/kernel/linear_algebra/MinorProcessor.h b/kernel/linear_algebra/MinorProcessor.h
new file mode 100644
index 0000000..1e3fa46
--- /dev/null
+++ b/kernel/linear_algebra/MinorProcessor.h
@@ -0,0 +1,772 @@
+#ifndef MINOR_PROCESSOR_H
+#define MINOR_PROCESSOR_H
+
+#include <kernel/linear_algebra/Cache.h>
+#include <kernel/linear_algebra/Minor.h>
+
+struct spolyrec; typedef struct spolyrec polyrec; typedef polyrec* poly;
+struct ip_sring; typedef struct ip_sring* ring; typedef struct ip_sring const* const_ring;
+
+struct sip_sideal; typedef struct sip_sideal *       ideal;
+
+// #include <assert.h>
+#include <string>
+
+/* write "##define COUNT_AND_PRINT_OPERATIONS x" if you want
+   to count all basic operations and have them printed when
+   one of the methods documented herein will be invoked;
+   otherwise, comment this line;
+   x = 1: only final counters (after computing ALL
+          specified minors) will be printed, i.e., no
+          intermediate results;
+   x = 2: print counters after the computation of each
+          minor; this will be much more information
+   x = 3: print also all intermediate matrices with the
+          numbers of monomials in each entry;
+          this will be much much more information */
+//#define COUNT_AND_PRINT_OPERATIONS 2
+
+void printCounters (char* prefix, bool resetToZero);
+
+/*! \class MinorProcessor
+    \brief Class MinorProcessor implements the key methods for computing one
+    or all sub-determinantes of a given size in a pre-defined matrix; either
+    without caching or by using a cache.
+
+    After defining the entire matrix (e.g. 10 x 14) using<br>
+    MinorProcessor::defineMatrix (const int, const int, const int*),<br>
+    the user may do two different things:<br>
+    1. He/she can simply compute a minor in this matrix using<br>
+    MinorProcessor::getMinor (const int, const int*, const int*,
+                              Cache<MinorKey, MinorValue>&), or<br>
+    MinorProcessor::getMinor (const int, const int*, const int*);<br>
+    depending on whether a cache shall or shall not be used, respectively.<br>
+    In the first case, the user simply provides all row and column indices of
+    the desired minor.
+    2. He/she may define a smaller sub-matrix (e.g. 8 x 7) using
+    MinorValue::defineSubMatrix (const int, const int*, const int, const int*).
+    Afterwards, he/she may compute all minors of an even smaller size (e.g.
+    5 x 5) that consist exclusively of rows and columns of this (8 x 7)
+    sub-matrix (inside the entire 10 x 14 matrix).<br>
+    The implementation at hand eases the iteration over all such minors. Also
+    in the second case there are both implementations, i.e., with and without
+    using a cache.<br><br>
+    MinorProcessor makes use of MinorKey, MinorValue, and Cache. The
+    implementation of all mentioned classes (MinorKey, MinorValue, and
+    MinorProcessor) is generic to allow for the use of different types of
+    keys and values.
+    \author Frank Seelisch, http://www.mathematik.uni-kl.de/~seelisch
+*/
+class MinorProcessor
+{
+  protected:
+    /**
+    * A static method for computing the maximum number of retrievals of a
+    * minor.<br>
+    * More concretely, we are given a matrix of size \c rows x \c columns. We
+    * furthermore assume that we have - as part of this matrix - a minor of
+    * size \c containerMinorSize x \c containerMinorSize. Now we are
+    * interested in the number of times a minor of yet smaller size
+    * \c minorSize x \c minorSize will be needed when we compute the
+    * containerMinor by Laplace's Theorem.<br>
+    * The method returns the combinatorial results for both cases:
+    * containerMinor is fixed within the matrix
+    * (<c>multipleMinors == false</c>), or it can vary inside the matrix
+    * (<c>multipleMinors == true</c>).<br>
+    * The notion is here that we want to cache the small minor of size
+    * \c minorSize x \c minorSize, i.e. compute it just once.
+    * @param rows the number of rows of the underlying matrix
+    * @param columns the number of columns of the underlying matrix
+    * @param containerMinorSize the size of the container minor
+    * @param minorSize the size of the small minor (which may be retrieved
+    *        multiple times)
+    * @param multipleMinors decides whether containerMinor is fixed within
+    *        the underlying matrix or not
+    * @return the number of times, the small minor will be needed when
+    *         computing one or all containerMinors
+    */
+    static int NumberOfRetrievals (const int rows, const int columns,
+                                   const int containerMinorSize,
+                                   const int minorSize,
+                                   const bool multipleMinors);
+    /**
+    * A static method for computing the binomial coefficient i over j.
+    * \par Assert
+    * The method checks whether <em>i >= j >= 0</em>.
+    * @param i a positive integer greater than or equal to \a j
+    * @param j a positive integer less than or equal to \a i, and greater
+    *        than or equal to \e 0.
+    * @return the binomial coefficient i over j
+    */
+    static int IOverJ (const int i, const int j);
+
+    /**
+    * A static method for computing the factorial of i.
+    * \par Assert
+    * The method checks whether <em>i >= 0</em>.
+    * @param i an integer greater than or equal to \a 0
+    * @return the factorial of i
+    */
+    static int Faculty (const int i);
+
+    /**
+    * A method for iterating through all possible subsets of \c k rows and
+    * \c k columns inside a pre-defined submatrix of a pre-defined matrix.<br>
+    * The method will set \c _rowKey and \c columnKey to represent the
+    * next possbile subsets of \c k rows and columns inside the submatrix
+    * determined by \c _globalRowKey and \c _globalColumnKey.<br>
+    * When first called, this method will just shift \c _rowKey and
+    * \c _columnKey to point to the first sensible choices. Every subsequent
+    * call will move to the next \c _columnKey until there is no next.
+    * In this situation, a next \c _rowKey will be set, and \c _columnKey
+    * again to the first possible choice.<br>
+    * Finally, in case there is also no next \c _rowkey, the method returns
+    * \c false. (Otherwise \c true is returned.)
+    * @param k the size of the minor / all minors of interest
+    * @return true iff there is a next possible choice of rows and columns
+    */
+    bool setNextKeys (const int k);
+
+    /**
+    * private store for the rows and columns of the container minor within
+    * the underlying matrix;
+    * \c _container will be used to fix a submatrix (e.g. 40 x 50) of a
+    * larger matrix (e.g. 70 x 100). This is usefull when we would like to
+    * compute all minors of a given size (e.g. 4 x 4) inside such a
+    * pre-defined submatrix.
+    */
+    MinorKey _container;
+
+    /**
+    * private store for the number of rows in the container minor;
+    * This is set by MinorProcessor::defineSubMatrix (const int, const int*,
+    *                                                 const int, const int*).
+    */
+    int _containerRows;
+
+    /**
+    * private store for the number of columns in the container minor;
+    * This is set by MinorProcessor::defineSubMatrix (const int, const int*,
+    *                                                 const int, const int*).
+    */
+    int _containerColumns;
+
+    /**
+    * private store for the rows and columns of the minor of interest;
+    * Usually, this minor will encode subsets of the rows and columns in
+    * _container.
+    */
+    MinorKey _minor;
+
+    /**
+    * private store for the dimension of the minor(s) of interest
+    */
+    int _minorSize;
+
+    /**
+    * private store for the number of rows in the underlying matrix
+    */
+    int _rows;
+
+    /**
+    * private store for the number of columns in the underlying matrix
+    */
+    int _columns;
+
+    /**
+    * A method for identifying the row or column with the most zeros.<br>
+    * Using Laplace's Theorem, a minor can more efficiently be computed when
+    * developing along this best line.
+    * The returned index \c bestIndex is 0-based within the pre-defined
+    * matrix. If some row has the most zeros, then the (0-based) row index is
+    * returned. If, contrarywise, some column has the most zeros, then
+    * <c>x = - 1 - c</c> where \c c is the column index, is returned.
+    * (Note that in this case \c c can be reconstructed by computing
+    * <c>c = - 1 - x</c>.)
+    * @param k the size of the minor / all minors of interest
+    * @param mk the representation of rows and columns of the minor of
+    *        interest
+    * @return an int encoding which row or column has the most zeros
+    */
+    int getBestLine (const int k, const MinorKey& mk) const;
+
+    /**
+    * A method for testing whether a matrix entry is zero.
+    * @param absoluteRowIndex the absolute (zero-based) row index
+    * @param absoluteColumnIndex the absolute (zero-based) column index
+    * @return true iff the specified matrix entry is zero
+    */
+    virtual bool isEntryZero (const int absoluteRowIndex,
+                              const int absoluteColumnIndex) const;
+  public:
+    /**
+    * The default constructor
+    */
+    MinorProcessor ();
+
+    /**
+     * A destructor for deleting an instance. We must make this destructor
+     * virtual so that destructors of all derived classes will automatically
+     * also call the destructor of the base class MinorProcessor.
+     */
+     virtual ~MinorProcessor ();
+
+    /**
+    * A method for defining a sub-matrix within a pre-defined matrix.
+    * @param numberOfRows the number of rows in the sub-matrix
+    * @param rowIndices an array with the (0-based) indices of rows inside
+    *        the pre-defined matrix
+    * @param numberOfColumns the number of columns in the sub-matrix
+    * @param columnIndices an array with the (0-based) indices of columns
+    *        inside the pre-defined matrix
+    * @see MinorValue::defineMatrix (const int, const int, const int*)
+    */
+    void defineSubMatrix (const int numberOfRows, const int* rowIndices,
+                          const int numberOfColumns, const int* columnIndices);
+
+    /**
+    * Sets the size of the minor(s) of interest.<br>
+    * This method needs to be performed before beginning to compute all minors
+    * of size \a minorSize inside a pre-defined submatrix of an underlying
+    * (also pre-defined) matrix.
+    * @param minorSize the size of the minor(s) of interest
+    * @see MinorValue::defineSubMatrix (const int, const int*, const int,
+    *                                   const int*)
+    */
+    void setMinorSize (const int minorSize);
+
+    /**
+    * A method for checking whether there is a next choice of rows and columns
+    * when iterating through all minors of a given size within a pre-defined
+    * sub-matrix of an underlying matrix.<br>
+    * The number of rows and columns has to be set before using
+    * MinorValue::setMinorSize(const int).<br>
+    * After calling MinorValue::hasNextMinor (), the current sets of rows and
+    * columns may be inspected using
+    * MinorValue::getCurrentRowIndices(int* const) const and
+    * MinorValue::getCurrentColumnIndices(int* const) const.
+    * @return true iff there is a next choice of rows and columns
+    * @see MinorProcessor::getMinor (const int, const int*, const int*)
+    * @see MinorValue::getCurrentRowIndices(int* const) const
+    * @see MinorValue::getCurrentColumnIndices(int* const) const
+    */
+    bool hasNextMinor ();
+
+    /**
+    * A method for obtaining the current set of rows corresponding to the
+    * current minor when iterating through all minors of a given size within
+    * a pre-defined sub-matrix of an underlying matrix.<br>
+    * This method should only be called after MinorProcessor::hasNextMinor ()
+    * had been called and yielded \c true.<br>
+    * The user of this method needs to know the number of rows in order to
+    * know which entries of the newly filled \c target will be valid.
+    * @param target an int array to be filled with the row indices
+    * @see MinorProcessor::hasNextMinor ()
+    */
+    void getCurrentRowIndices (int* const target) const;
+
+    /**
+    * A method for obtaining the current set of columns corresponding to the
+    * current minor when iterating through all minors of a given size within
+    * a pre-defined sub-matrix of an underlying matrix.<br>
+    * This method should only be called after MinorProcessor::hasNextMinor ()
+    * had been called and yielded \c true.<br>
+    * The user of this method needs to know the number of columns in order to
+    * know which entries of the newly filled \c target will be valid.
+    * @param target an int array to be filled with the column indices
+    * @see MinorProcessor::hasNextMinor ()
+    */
+    void getCurrentColumnIndices (int* const target) const;
+
+    /**
+    * A method for providing a printable version of the represented
+    * MinorProcessor.
+    * @return a printable version of the given instance as instance of class
+    * string
+    */
+   virtual std::string toString () const;
+
+    /**
+    * A method for printing a string representation of the given
+    * MinorProcessor to std::cout.
+    */
+    void print () const;
+};
+
+/*! \class IntMinorProcessor
+    \brief Class IntMinorProcessor is derived from class MinorProcessor.
+
+    This class implements the special case of integer matrices.
+    \author Frank Seelisch, http://www.mathematik.uni-kl.de/~seelisch
+*/
+class IntMinorProcessor : public MinorProcessor
+{
+  private:
+    /**
+    * private store for integer matrix entries
+    */
+    int* _intMatrix;
+
+    /**
+    * A method for retrieving the matrix entry.
+    * @param rowIndex the absolute (zero-based) row index
+    * @param columnIndex the absolute (zero-based) column index
+    * @return the specified matrix entry
+    */
+    int getEntry (const int rowIndex, const int columnIndex) const;
+
+    /**
+    * A method for computing the value of a minor, using a cache.<br>
+    * The sub-matrix is specified by \c mk. Computation works recursively
+    * using Laplace's Theorem. We always develop along the row or column with
+    * the most zeros; see
+    * MinorProcessor::getBestLine (const int k, const MinorKey& mk).
+    * If an ideal is given, it is assumed to be a standard basis. In this case,
+    * all results will be reduced w.r.t. to this basis. Moreover, if the given
+    * characteristic is non-zero, all results will be computed modulo this
+    * characteristic.
+    * @param k the number of rows and columns in the minor to be comuted
+    * @param mk the representation of rows and columns of the minor to be
+    *        comuted
+    * @param multipleMinors decides whether we compute just one or all minors
+    *        of a specified size
+    * @param c a cache to be used for caching reusable sub-minors
+    * @param characteristic 0 or the characteristic of the underlying
+    *        coefficient ring/field
+    * @param iSB NULL or a standard basis
+    * @return an instance of MinorValue representing the value of the
+    *         corresponding minor
+    * @see MinorProcessor::getMinorPrivateLaplace (const int k,
+                                                   const MinorKey& mk,
+                                                   const int characteristic,
+                                                   const ideal& iSB)
+    */
+    IntMinorValue getMinorPrivateLaplace (const int k, const MinorKey& mk,
+                                          const bool multipleMinors,
+                                          Cache<MinorKey, IntMinorValue>& c,
+                                          int characteristic,
+                                          const ideal& iSB);
+
+    /**
+    * A method for computing the value of a minor, without using a cache.<br>
+    * The sub-matrix is specified by \c mk. Computation works recursively
+    * using Laplace's Theorem. We always develop along the row or column with
+    * the most zeros; see
+    * MinorProcessor::getBestLine (const int k, const MinorKey& mk).
+    * If an ideal is given, it is assumed to be a standard basis. In this case,
+    * all results will be reduced w.r.t. to this basis. Moreover, if the given
+    * characteristic is non-zero, all results will be computed modulo this
+    * characteristic.
+    * @param k the number of rows and columns in the minor to be comuted
+    * @param mk the representation of rows and columns of the minor to be
+    *        comuted
+    * @param characteristic 0 or the characteristic of the underlying
+    *        coefficient ring/field
+    * @param iSB NULL or a standard basis
+    * @return an instance of MinorValue representing the value of the
+    *         corresponding minor
+    * @see MinorProcessor::getMinorPrivateLaplace (const int k,
+                                                   const MinorKey& mk,
+                                                   const bool multipleMinors,
+                                                   Cache<MinorKey,
+                                                         IntMinorValue>& c,
+                                                   int characteristic,
+                                                   const ideal& iSB)
+    */
+    IntMinorValue getMinorPrivateLaplace (const int k, const MinorKey& mk,
+                                          const int characteristic,
+                                          const ideal& iSB);
+
+    /**
+    * A method for computing the value of a minor using Bareiss's
+    * algorithm.<br>
+    * The sub-matrix is specified by \c mk.
+    * If an ideal is given, it is assumed to be a standard basis. In this
+    * case, all results will be reduced w.r.t. to this basis. Moreover, if the
+    * given characteristic is non-zero, all results will be computed modulo
+    * this characteristic.
+    * @param k the number of rows and columns in the minor to be comuted
+    * @param mk the representation of rows and columns of the minor to be
+    *        computed
+    * @param characteristic 0 or the characteristic of the underlying
+    *        coefficient ring/field
+    * @param iSB NULL or a standard basis
+    * @return an instance of MinorValue representing the value of the
+    *         corresponding minor
+    * @see MinorProcessor::getMinorPrivateLaplace (const int k,
+                                                   const MinorKey& mk,
+                                                   const int characteristic,
+                                                   const ideal& iSB)
+    */
+    IntMinorValue getMinorPrivateBareiss (const int k, const MinorKey& mk,
+                                          const int characteristic,
+                                          const ideal& iSB);
+  protected:
+    /**
+    * A method for testing whether a matrix entry is zero.
+    * @param absoluteRowIndex the absolute (zero-based) row index
+    * @param absoluteColumnIndex the absolute (zero-based) column index
+    * @return true iff the specified matrix entry is zero
+    */
+    bool isEntryZero (const int absoluteRowIndex,
+                      const int absoluteColumnIndex) const;
+  public:
+    /**
+    * A constructor for creating an instance.
+    */
+    IntMinorProcessor ();
+
+    /**
+    * A destructor for deleting an instance.
+    */
+    ~IntMinorProcessor ();
+
+    /**
+    * A method for defining a matrix with integer entries.
+    * @param numberOfRows the number of rows
+    * @param numberOfColumns the number of columns
+    * @param matrix the matrix entries in a linear array, i.e., from left to
+    *        right and top to bottom
+    * @see MinorValue::defineSubMatrix (const int, const int*, const int,
+    *                                   const int*)
+    */
+    void defineMatrix (const int numberOfRows, const int numberOfColumns,
+                       const int* matrix);
+
+    /**
+    * A method for computing the value of a minor without using a cache.<br>
+    * The sub-matrix is determined by \c rowIndices and \c columnIndices.
+    * Computation works either by Laplace's algorithm or by Bareiss's
+    * algorithm.<br>
+    * If an ideal is given, it is assumed to be a standard basis. In this
+    * case, all results will be reduced w.r.t. to this basis. Moreover, if the
+    * given characteristic is non-zero, all results will be computed modulo
+    * this characteristic.
+    * @param dimension the size of the minor to be computed
+    * @param rowIndices 0-based indices of the rows of the minor
+    * @param columnIndices 0-based indices of the column of the minor
+    * @param characteristic 0 or the characteristic of the underlying
+    *        coefficient ring/field
+    * @param iSB NULL or a standard basis
+    * @param algorithm either "Bareiss" or "Laplace"
+    * @return an instance of MinorValue representing the value of the
+    *         corresponding minor
+    * @see MinorProcessor::getMinor (const int dimension,
+                                     const int* rowIndices,
+                                     const int* columnIndices,
+                                     Cache<MinorKey, IntMinorValue>& c,
+                                     const int characteristic,
+                                     const ideal& iSB)
+    */
+    IntMinorValue getMinor (const int dimension, const int* rowIndices,
+                            const int* columnIndices,
+                            const int characteristic, const ideal& iSB,
+                            const char* algorithm);
+
+    /**
+    * A method for computing the value of a minor using a cache.<br>
+    * The sub-matrix is determined by \c rowIndices and \c columnIndices.
+    * Computation works by Laplace's algorithm together with caching of
+    * subdeterminants.<br>
+    * If an ideal is given, it is assumed to be a standard basis. In this case,
+    * all results will be reduced w.r.t. to this basis. Moreover, if the given
+    * characteristic is non-zero, all results will be computed modulo this
+    * characteristic.
+    * @param dimension the size of the minor to be computed
+    * @param rowIndices 0-based indices of the rows of the minor
+    * @param columnIndices 0-based indices of the column of the minor
+    * @param c the cache for storing subdeterminants
+    * @param characteristic 0 or the characteristic of the underlying
+    *        coefficient ring/field
+    * @param iSB NULL or a standard basis
+    * @return an instance of MinorValue representing the value of the
+    *         corresponding minor
+    * @see MinorProcessor::getMinor (const int dimension,
+                                     const int* rowIndices,
+                                     const int* columnIndices,
+                                     const int characteristic,
+                                     const ideal& iSB,
+                                     const char* algorithm)
+    */
+    IntMinorValue getMinor (const int dimension, const int* rowIndices,
+                            const int* columnIndices,
+                            Cache<MinorKey, IntMinorValue>& c,
+                            const int characteristic,  const ideal& iSB);
+
+    /**
+    * A method for obtaining the next minor when iterating
+    * through all minors of a given size within a pre-defined sub-matrix of an
+    * underlying matrix.<br>
+    * This method should only be called after MinorProcessor::hasNextMinor ()
+    * had been called and yielded \c true.<br>
+    * Computation works by Laplace's algorithm (without using a cache) or by
+    * Bareiss's algorithm.<br>
+    * If an ideal is given, it is assumed to be a standard basis. In this case,
+    * all results will be reduced w.r.t. to this basis. Moreover, if the given
+    * characteristic is non-zero, all results will be computed modulo this
+    * characteristic.
+    * @param characteristic 0 or the characteristic of the underlying
+    *        coefficient ring/field
+    * @param iSB NULL or a standard basis
+    * @param algorithm either "Bareiss" or "Laplace"
+    * @return the next minor
+    * @see IntMinorValue::getNextMinor (Cache<MinorKey, IntMinorValue>& c,
+    *                                   const int characteristic,
+    *                                   const ideal& iSB)
+    */
+    IntMinorValue getNextMinor (const int characteristic, const ideal& iSB,
+                                const char* algorithm);
+
+    /**
+    * A method for obtaining the next minor when iterating
+    * through all minors of a given size within a pre-defined sub-matrix of an
+    * underlying matrix.<br>
+    * This method should only be called after MinorProcessor::hasNextMinor ()
+    * had been called and yielded \c true.<br>
+    * Computation works using the cache \a c which may already contain useful
+    * results from previous calls of
+    * IntMinorValue::getNextMinor (Cache<MinorKey, IntMinorValue>& c,
+                                   const int characteristic,
+                                   const ideal& iSB).
+    * If an ideal is given, it is assumed to be a standard basis. In this case,
+    * all results will be reduced w.r.t. to this basis. Moreover, if the given
+    * characteristic is non-zero, all results will be computed modulo this
+    * characteristic.
+    * @param c the cache
+    * @param characteristic 0 or the characteristic of the underlying
+    *        coefficient ring/field
+    * @param iSB NULL or a standard basis
+    * @return the next minor
+    * @see IntMinorValue::getNextMinor (const int characteristic,
+    *                                   const ideal& iSB,
+    *                                   const char* algorithm)
+    */
+    IntMinorValue getNextMinor (Cache<MinorKey, IntMinorValue>& c,
+                                const int characteristic,
+                                const ideal& iSB);
+
+    /**
+    * A method for providing a printable version of the represented
+    * MinorProcessor.
+    * @return a printable version of the given instance as instance of class
+    *         string
+    */
+   std::string toString () const;
+};
+
+/*! \class PolyMinorProcessor
+    \brief Class PolyMinorProcessor is derived from class MinorProcessor.
+
+    This class implements the special case of polynomial matrices.
+    \author Frank Seelisch, http://www.mathematik.uni-kl.de/~seelisch
+*/
+class PolyMinorProcessor : public MinorProcessor
+{
+  private:
+    /**
+    * private store for polynomial matrix entries
+    */
+    poly* _polyMatrix;
+
+    /**
+    * A method for retrieving the matrix entry.
+    * @param rowIndex the absolute (zero-based) row index
+    * @param columnIndex the absolute (zero-based) column index
+    * @return the specified matrix entry
+    */
+    poly getEntry (const int rowIndex, const int columnIndex) const;
+
+    /**
+    * A method for computing the value of a minor, using a cache.<br>
+    * The sub-matrix is specified by \c mk. Computation works recursively
+    * using Laplace's Theorem. We always develop along the row or column with
+    * the most zeros; see
+    * MinorProcessor::getBestLine (const int k, const MinorKey& mk).
+    * If an ideal is given, it is assumed to be a standard basis. In this case,
+    * all results will be reduced w.r.t. to this basis.
+    * @param k the number of rows and columns in the minor to be comuted
+    * @param mk the representation of rows and columns of the minor to be
+    *        comuted
+    * @param multipleMinors decides whether we compute just one or all minors
+    *        of a specified size
+    * @param c a cache to be used for caching reusable sub-minors
+    * @param iSB NULL or a standard basis
+    * @return an instance of MinorValue representing the value of the
+    *         corresponding minor
+    * @see MinorProcessor::getMinorPrivateLaplace (const int k,
+    *                                              const MinorKey& mk,
+    *                                              const ideal& iSB)
+    */
+    PolyMinorValue getMinorPrivateLaplace (const int k, const MinorKey& mk,
+                                           const bool multipleMinors,
+                                           Cache<MinorKey, PolyMinorValue>& c,
+                                           const ideal& iSB);
+
+    /**
+    * A method for computing the value of a minor, without using a cache.<br>
+    * The sub-matrix is specified by \c mk. Computation works recursively
+    * using Laplace's Theorem. We always develop along the row or column with
+    * the most zeros; see
+    * MinorProcessor::getBestLine (const int k, const MinorKey& mk).
+    * If an ideal is given, it is assumed to be a standard basis. In this case,
+    * all results will be reduced w.r.t. to this basis.
+    * @param k the number of rows and columns in the minor to be comuted
+    * @param mk the representation of rows and columns of the minor to be
+    *        comuted
+    * @param iSB NULL or a standard basis
+    * @return an instance of MinorValue representing the value of the
+    *         corresponding minor
+    * @see MinorProcessor::getMinorPrivate (const int, const MinorKey&,
+    *                                       const bool,
+    *                                       Cache<MinorKey, MinorValue>&)
+    */
+    PolyMinorValue getMinorPrivateLaplace (const int k, const MinorKey& mk,
+                                           const ideal& iSB);
+
+    /**
+    * A method for computing the value of a minor, without using a cache.<br>
+    * The sub-matrix is specified by \c mk. Computation works
+    * using Bareiss's algorithm.
+    * If an ideal is given, it is assumed to be a standard basis. In this case,
+    * all results will be reduced w.r.t. to this basis.
+    * @param k the number of rows and columns in the minor to be comuted
+    * @param mk the representation of rows and columns of the minor to be
+    *        comuted
+    * @param iSB NULL or a standard basis
+    * @return an instance of MinorValue representing the value of the
+    *         corresponding minor
+    * @see MinorProcessor::getMinorPrivateLaplace (const int k,
+    *                                              const MinorKey& mk,
+    *                                              const ideal& iSB)
+    */
+    PolyMinorValue getMinorPrivateBareiss (const int k, const MinorKey& mk,
+                                           const ideal& iSB);
+  protected:
+    /**
+    * A method for testing whether a matrix entry is zero.
+    * @param absoluteRowIndex the absolute (zero-based) row index
+    * @param absoluteColumnIndex the absolute (zero-based) column index
+    * @return true iff the specified matrix entry is zero
+    */
+    bool isEntryZero (const int absoluteRowIndex,
+                      const int absoluteColumnIndex) const;
+  public:
+    /**
+    * A constructor for creating an instance.
+    */
+    PolyMinorProcessor ();
+
+    /**
+    * A destructor for deleting an instance.
+    */
+    ~PolyMinorProcessor ();
+
+    /**
+    * A method for defining a matrix with polynomial entries.
+    * @param numberOfRows the number of rows
+    * @param numberOfColumns the number of columns
+    * @param polyMatrix the matrix entries in a linear array, i.e., from left
+    *        to right and top to bottom
+    * @see MinorValue::defineSubMatrix (const int, const int*, const int,
+    *                                   const int*)
+    */
+    void defineMatrix (const int numberOfRows, const int numberOfColumns,
+                       const poly* polyMatrix);
+
+    /**
+    * A method for computing the value of a minor, without using a cache.<br>
+    * The sub-matrix is determined by \c rowIndices and \c columnIndices.
+    * Computation works either by Laplace's algorithm or by Bareiss's
+    * algorithm.<br>
+    * If an ideal is given, it is assumed to be a standard basis. In this case,
+    * all results will be reduced w.r.t. to this basis.
+    * @param dimension the size of the minor to be computed
+    * @param rowIndices 0-based indices of the rows of the minor
+    * @param columnIndices 0-based indices of the column of the minor
+    * @param algorithm either "Laplace" or "Bareiss"
+    * @param iSB NULL or a standard basis
+    * @return an instance of MinorValue representing the value of the
+    *         corresponding minor
+    * @see MinorProcessor::getMinor (const int dimension,
+    *                                const int* rowIndices,
+    *                                const int* columnIndices,
+    *                                Cache<MinorKey, PolyMinorValue>& c,
+    *                                const ideal& iSB)
+    */
+    PolyMinorValue getMinor (const int dimension, const int* rowIndices,
+                             const int* columnIndices, const char* algorithm,
+                             const ideal& iSB);
+
+    /**
+    * A method for computing the value of a minor, using a cache.<br>
+    * The sub-matrix is determined by \c rowIndices and \c columnIndices.
+    * Computation works recursively using Laplace's Theorem. We always develop
+    * along the row or column with most zeros; see
+    * MinorProcessor::getBestLine (const int, const int, const int).
+    * If an ideal is given, it is assumed to be a standard basis. In this case,
+    * all results will be reduced w.r.t. to this basis.
+    * @param dimension the size of the minor to be computed
+    * @param rowIndices 0-based indices of the rows of the minor
+    * @param columnIndices 0-based indices of the column of the minor
+    * @param c a cache to be used for caching reusable sub-minors
+    * @param iSB NULL or a standard basis
+    * @return an instance of MinorValue representing the value of the
+    *         corresponding minor
+    * @see MinorProcessor::(const int dimension, const int* rowIndices,
+    *                       const int* columnIndices, const char* algorithm,
+    *                       const ideal& iSB)
+    */
+    PolyMinorValue getMinor (const int dimension, const int* rowIndices,
+                             const int* columnIndices,
+                             Cache<MinorKey, PolyMinorValue>& c,
+                             const ideal& iSB);
+
+    /**
+    * A method for obtaining the next minor when iterating
+    * through all minors of a given size within a pre-defined sub-matrix of an
+    * underlying matrix.<br>
+    * This method should only be called after MinorProcessor::hasNextMinor ()
+    * had been called and yielded \c true.<br>
+    * Computation works either by Laplace's algorithm (without using a cache)
+    * or by Bareiss's algorithm.<br>
+    * If an ideal is given, it is assumed to be a standard basis. In this case,
+    * all results will be reduced w.r.t. to this basis.
+    * @param algorithm either "Laplace" or "Bareiss"
+    * @param iSB NULL or a standard basis
+    * @return true iff there is a next choice of rows and columns
+    * @see PolyMinorValue::getNextMinor (Cache<MinorKey, PolyMinorValue>& c,
+    *                                    const ideal& iSB)
+    */
+    PolyMinorValue getNextMinor (const char* algorithm, const ideal& iSB);
+
+    /**
+    * A method for obtaining the next minor when iterating
+    * through all minors of a given size within a pre-defined sub-matrix of an
+    * underlying matrix.<br>
+    * This method should only be called after MinorProcessor::hasNextMinor ()
+    * had been called and yielded \c true.<br>
+    * Computation works using Laplace's algorithm and a cache \a c which may
+    * already contain useful results from previous calls of
+    * PolyMinorValue::getNextMinor (Cache<MinorKey, PolyMinorValue>& c,
+    *                               const ideal& iSB).
+    * If an ideal is given, it is assumed to be a standard basis. In this case,
+    * all results will be reduced w.r.t. to this basis.
+    * @param iSB NULL or a standard basis
+    * @return the next minor
+    * @see PolyMinorValue::getNextMinor (const char* algorithm,
+    *                                    const ideal& iSB)
+    */
+    PolyMinorValue getNextMinor (Cache<MinorKey, PolyMinorValue>& c,
+                                 const ideal& iSB);
+
+    /**
+    * A method for providing a printable version of the represented
+    * MinorProcessor.
+    * @return a printable version of the given instance as instance of class
+    *         string
+    */
+   std::string toString () const;
+};
+
+#endif
+/* MINOR_PROCESSOR_H */
diff --git a/kernel/linear_algebra/eigenval.cc b/kernel/linear_algebra/eigenval.cc
new file mode 100644
index 0000000..295d4b4
--- /dev/null
+++ b/kernel/linear_algebra/eigenval.cc
@@ -0,0 +1,125 @@
+/*****************************************
+*  Computer Algebra System SINGULAR      *
+*****************************************/
+/*
+* ABSTRACT: eigenvalues of constant square matrices
+*/
+
+
+
+
+#include <kernel/mod2.h>
+
+#ifdef HAVE_EIGENVAL
+
+#include <kernel/structs.h>
+#include <misc/intvec.h>
+#include <coeffs/numbers.h>
+#include <kernel/polys.h>
+#include <kernel/ideals.h>
+#include <polys/matpol.h>
+#include <polys/clapsing.h>
+#include <kernel/linear_algebra/eigenval.h>
+
+
+matrix evSwap(matrix M,int i,int j)
+{
+  if(i==j)
+    return(M);
+
+  for(int k=1;k<=MATROWS(M);k++)
+  {
+    poly p=MATELEM(M,i,k);
+    MATELEM(M,i,k)=MATELEM(M,j,k);
+    MATELEM(M,j,k)=p;
+  }
+
+  for(int k=1;k<=MATCOLS(M);k++)
+  {
+    poly p=MATELEM(M,k,i);
+    MATELEM(M,k,i)=MATELEM(M,k,j);
+    MATELEM(M,k,j)=p;
+  }
+
+  return(M);
+}
+
+matrix evRowElim(matrix M,int i,int j,int k)
+{
+  if(MATELEM(M,i,k)==NULL||MATELEM(M,j,k)==NULL)
+    return(M);
+  poly p1=pp_Jet(MATELEM(M,i,k),0,currRing);
+  poly p2=pp_Jet(MATELEM(M,j,k),0,currRing);
+  if ((p1==NULL)||(p2==NULL)) return (M);
+
+  poly p=pNSet(nDiv(pGetCoeff(p1),pGetCoeff(p2)));
+  pNormalize(p);
+
+  for(int l=1;l<=MATCOLS(M);l++)
+  {
+    MATELEM(M,i,l)=pSub(MATELEM(M,i,l),ppMult_qq(p,MATELEM(M,j,l)));
+    pNormalize(MATELEM(M,i,l));
+  }
+  for(int l=1;l<=MATROWS(M);l++)
+  {
+    MATELEM(M,l,j)=pAdd(MATELEM(M,l,j),ppMult_qq(p,MATELEM(M,l,i)));
+    pNormalize(MATELEM(M,l,j));
+  }
+
+  pDelete(&p);
+  pDelete(&p1);
+  pDelete(&p2);
+
+  return(M);
+}
+
+matrix evColElim(matrix M,int i,int j,int k)
+{
+  if(MATELEM(M,k,i)==0||MATELEM(M,k,j)==0)
+    return(M);
+
+  poly p=pNSet(nDiv(pGetCoeff(MATELEM(M,k,i)),pGetCoeff(MATELEM(M,k,j))));
+  pNormalize(p);
+
+  for(int l=1;l<=MATROWS(M);l++)
+  {
+    MATELEM(M,l,i)=pSub(MATELEM(M,l,i),ppMult_qq(p,MATELEM(M,l,j)));
+    pNormalize(MATELEM(M,l,i));
+  }
+  for(int l=1;l<=MATCOLS(M);l++)
+  {
+    MATELEM(M,j,l)=pAdd(MATELEM(M,j,l),ppMult_qq(p,MATELEM(M,i,l)));
+    pNormalize(MATELEM(M,j,l));
+  }
+
+  pDelete(&p);
+
+  return(M);
+}
+
+matrix evHessenberg(matrix M)
+{
+  int n=MATROWS(M);
+  if(n!=MATCOLS(M))
+    return(M);
+
+  for(int k=1,j=2;k<n-1;k++,j=k+1)
+  {
+    while((j<=n)
+    &&((MATELEM(M,j,k)==NULL)
+      || (p_Totaldegree(MATELEM(M,j,k),currRing)!=0)))
+      j++;
+
+    if(j<=n)
+    {
+      M=evSwap(M,j,k+1);
+
+      for(int i=j+1;i<=n;i++)
+        M=evRowElim(M,i,k+1,k);
+    }
+  }
+
+  return(M);
+}
+
+#endif /* HAVE_EIGENVAL */
diff --git a/kernel/linear_algebra/eigenval.h b/kernel/linear_algebra/eigenval.h
new file mode 100644
index 0000000..cbab5f7
--- /dev/null
+++ b/kernel/linear_algebra/eigenval.h
@@ -0,0 +1,18 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: eigenvalues of constant square matrices
+*/
+
+#ifndef EIGENVAL_H
+#define EIGENVAL_H
+#ifdef HAVE_EIGENVAL
+
+matrix evSwap(matrix M,int i,int j);
+matrix evRowElim(matrix M,int i,int j,int k);
+matrix evColElim(matrix M,int i,int j,int k);
+matrix evHessenberg(matrix M);
+
+#endif /* ifdef HAVE_EIGENVAL */
+#endif /* EIGENVAL_H */
diff --git a/kernel/linear_algebra/interpolation.cc b/kernel/linear_algebra/interpolation.cc
new file mode 100644
index 0000000..ed7b9e0
--- /dev/null
+++ b/kernel/linear_algebra/interpolation.cc
@@ -0,0 +1,1772 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+
+#include <kernel/mod2.h>
+
+#include <factory/factory.h>
+
+#include <misc/options.h>
+#include <misc/intvec.h>
+
+#include <coeffs/longrat.h> // snumber ...
+
+#include <polys/monomials/ring.h>
+
+#include <kernel/polys.h>
+#include <kernel/ideals.h>
+
+#include "interpolation.h"
+
+// parameters to debug
+//#define shmat
+//#define checksize
+//#define writemsg
+
+// possible strategies
+#define unsortedmatrix
+//#define integerstrategy
+
+#define modp_number int
+#define exponent int
+
+static modp_number myp;  // all modp computation done mod myp
+static int myp_index; // index of small prime in Singular table of primes
+
+static inline modp_number modp_mul (modp_number x,modp_number y)
+{
+//    return (x*y)%myp;
+   return (modp_number)(((unsigned long)x)*((unsigned long)y)%((unsigned long)myp));
+}
+static inline modp_number modp_sub (modp_number x,modp_number y)
+{
+//   if (x>=y) return x-y; else return x+myp-y;
+     return (x+myp-y)%myp;
+}
+
+typedef exponent *mono_type;
+typedef struct {mono_type mon; unsigned int point_ref;} condition_type;
+typedef modp_number *coordinate_products;
+typedef coordinate_products *coordinates;
+
+struct mon_list_entry_struct {mono_type mon;
+                              struct mon_list_entry_struct *next;};
+typedef struct mon_list_entry_struct mon_list_entry;
+
+struct row_list_entry_struct {modp_number *row_matrix;
+                              modp_number *row_solve;
+                              int first_col;
+                              struct row_list_entry_struct *next;};
+
+typedef struct row_list_entry_struct row_list_entry;
+
+struct generator_struct {modp_number *coef;
+                         mono_type lt;
+                         modp_number ltcoef;
+                         struct generator_struct *next;};
+
+typedef struct generator_struct generator_entry;
+
+struct modp_result_struct {modp_number p;
+                           generator_entry *generator;
+                           int n_generators;
+                           struct modp_result_struct *next;
+                           struct modp_result_struct *prev;};
+
+typedef struct modp_result_struct modp_result_entry;
+
+typedef modp_number *modp_coordinates;
+typedef mpq_t *q_coordinates;
+typedef mpz_t *int_coordinates;
+typedef bool *coord_exist_table;
+
+static int final_base_dim;    // dimension of the quotient space, known from the beginning
+static int last_solve_column;  // last non-zero column in "solve" part of matrix, used for speed up
+static int n_points;  // modp_number of ideals (points)
+static int *multiplicity;  // multiplicities of points
+static int variables;  // modp_number of variables
+static int max_coord;  // maximal possible coordinate product used during Evaluation
+static bool only_modp;  // perform only one modp computations
+
+static modp_coordinates *modp_points; // coordinates of points for modp problem - used by Evaluate (this is also initial data for only modp)
+static q_coordinates *q_points; // coordinates of points for rational data (not used for modp)
+static int_coordinates *int_points; // coordinates of points for integer data - used to check generators (not used for modp)
+static coord_exist_table *coord_exist; // checks whether all coordinates has been initialized
+static mon_list_entry *check_list; // monomials to be checked in next stages
+static coordinates *points; // power products of coordinates of points used in modp cycles
+static condition_type *condition_list; // conditions stored in an array
+static mon_list_entry *lt_list; // leading terms found so far
+static mon_list_entry *base_list; // standard monomials found so far
+static row_list_entry *row_list; // rows of the matrix (both parts)
+static modp_number *my_row; // one special row to perform operations
+static modp_number *my_solve_row; // one special row to find the linear dependence ("solve" part)
+static mono_type *column_name; // monomials assigned to columns in solve_row
+
+static int n_results;  // modp_number of performed modp computations (not discarded)
+static modp_number modp_denom; // denominator of mod p computations
+static modp_result_entry *modp_result; // list of results for various mod p calculations (used for modp - first result is the desired one)
+static modp_result_entry *cur_result; // pointer to current result (as before)
+static modp_number *congr; // primes used in computations (chinese remainder theorem) (not used for modp)
+static modp_number *in_gamma; // inverts used in chinese remainder theorem (not used for modp)
+static mpz_t bigcongr; // result, in fact, is given in mod bigcongr (not used for modp)
+
+static mpz_t *polycoef; // polynomial integercoefficients (not used for modp)
+static mono_type *polyexp; // polynomial exponents
+
+struct gen_list_struct {mpz_t *polycoef;
+                        mono_type *polyexp;
+                        struct gen_list_struct *next;};
+typedef struct gen_list_struct gen_list_entry;
+
+static gen_list_entry *gen_list=NULL; // list of resulting generators - output data (integer version)
+
+static int generic_n_generators; // modp_number of generators - should be the same for all modp comp (not used for modp)
+static mono_type *generic_column_name; // monomials assigned to columns in solve_row - should be the same for all modp comp (!!! used for modp)
+static mon_list_entry *generic_lt=NULL; // leading terms for ordered generators - should be the same for all modp comp (not used for modp)
+static int good_primes; // modp_number of good primes so far;
+static int bad_primes; // modp_number of bad primes so far;
+static mpz_t common_denom; // common denominator used to force points coordinates to Z (not used for modp)
+static bool denom_divisible; // common denominator is divisible by p (not used for modp)
+
+static poly comparizon_p1;  //polynomials used to do comparizons by Singular
+static poly comparizon_p2;
+
+static modp_number *modp_Reverse; // reverses in mod p
+
+static bool protocol; // true to show the protocol
+
+#ifdef checksize
+static int maximal_size=0;
+#endif
+
+#if 0  /* only for debuggig*/
+void WriteMono (mono_type m) // Writes a monomial on the screen - only for debug
+{
+     int i;
+     for (i=0;i<variables;i++) Print("_%d", m[i]);
+     PrintS(" ");
+}
+
+void WriteMonoList (mon_list_entry *list)
+{
+     mon_list_entry *ptr;
+     ptr=list;
+     while (ptr!=NULL)
+     {
+           WriteMono(ptr->mon);
+           ptr=ptr->next;
+     }
+}
+
+void Info ()
+{
+     int i;
+     row_list_entry *curptr;
+     modp_number *row;
+     modp_number *solve;
+     char ch;
+     cout << endl << "quotient basis: ";
+     WriteMonoList (base_list);
+     cout << endl << "leading terms: ";
+     WriteMonoList (lt_list);
+     cout << endl << "to be checked: ";
+     WriteMonoList (check_list);
+#ifdef shmat
+     cout << endl << "Matrix:" << endl;
+     cout << "                                      ";
+     for (i=0;i<final_base_dim;i++)
+     {
+         WriteMono (column_name[i]);
+     }
+     cout << endl;
+     curptr=row_list;
+     while (curptr!=NULL)
+     {
+           row=curptr->row_matrix;
+           solve=curptr->row_solve;
+           for (i=0;i<final_base_dim;i++)
+           {
+               cout << *row << " , ";
+               row++;
+           }
+           cout << "        ";
+           for (i=0;i<final_base_dim;i++)
+           {
+               cout << *solve << " , ";
+               solve++;
+           }
+           curptr=curptr->next;
+           cout << endl;}
+     cout << "Special row:                           Solve row:" << endl;
+     row=my_row;
+     for (i=0;i<final_base_dim;i++)
+     {
+         cout << *row << " , ";
+         row++;
+     }
+     cout << "          ";
+     row=my_solve_row;
+     for (i=0;i<final_base_dim;i++)
+     {
+         cout << *row << " , ";
+         row++;
+     }
+#endif
+     cout << endl;
+     cin >> ch;
+     cout << endl << endl;
+}
+#endif
+
+static modp_number OneInverse(modp_number a,modp_number p) // computes inverse of d mod p without using tables
+{
+   long  u, v, u0, u1, u2, q, r;
+   u1=1; u2=0;
+   u = a; v = p;
+   while (v != 0)
+   {
+      q = u / v;
+      r = u % v;
+      u = v;
+      v = r;
+      u0 = u2;
+      u2 = u1 - q*u2;
+      u1 = u0;
+   }
+   if (u1 < 0) u1=u1+p;
+// now it should be ok, but for any case...
+   if ((u1<0)||((u1*a)%p!=1))
+   {
+     PrintS("?");
+     modp_number i;
+     for (i=1;i<p;i++)
+     {
+       if ((a*i)%p==1) return i;
+     }
+   }
+   return (modp_number)u1;
+}
+
+static int CalcBaseDim () // returns the maximal (expected) dimension of quotient space
+{
+    int c;
+    int i,j;
+    int s=0;
+    max_coord=1;
+    for (i=0;i<n_points;i++) max_coord=max_coord+multiplicity[i];
+    for (j=0;j<n_points;j++)
+    {
+        c=1;
+        for (i=1;i<=variables;i++)
+        {
+            c=(c*(multiplicity[j]+i-1))/i;
+        }
+        s=s+c;
+    }
+    return s;
+}
+
+static bool EqualMon (mono_type m1, mono_type m2)  // compares two monomials, true if equal, false otherwise
+{
+     int i;
+     for (i=0;i<variables;i++)
+         if (m1[i]!=m2[i]) return false;;
+     return true;
+}
+
+static exponent MonDegree (mono_type mon)  // computes the degree of a monomial
+{
+     exponent v=0;
+     int i;
+     for (i=0;i<variables;i++) v=v+mon[i];
+     return v;
+}
+
+static bool Greater (mono_type m1, mono_type m2) // true if m1 > m2, false otherwise. uses Singular comparing function
+{
+     for (int j = variables; j; j--)
+     {
+       pSetExp(comparizon_p1, j, m1[j-1]);
+       pSetExp(comparizon_p2, j, m2[j-1]);
+     }
+     pSetm(comparizon_p1);
+     pSetm(comparizon_p2);
+     bool res=(pLmCmp(comparizon_p1,comparizon_p2)>0);
+     return res;
+}
+
+static mon_list_entry* MonListAdd (mon_list_entry *list, mono_type mon)  // adds one entry to the list of monomials structure
+{
+     mon_list_entry *curptr=list;
+     mon_list_entry *prevptr=NULL;
+     mon_list_entry *temp;
+
+     while (curptr!=NULL)
+     {
+           if (EqualMon (mon,(*curptr).mon)) return list;
+           if (Greater ((*curptr).mon,mon)) break;
+           prevptr=curptr;
+           curptr=curptr->next;
+     }
+     temp=(mon_list_entry*)omAlloc0(sizeof(mon_list_entry));
+     (*temp).next=curptr;
+     (*temp).mon=(exponent*)omAlloc(sizeof(exponent)*variables);
+     memcpy(temp->mon,mon,sizeof(exponent)*variables);
+     if (prevptr==NULL) return temp;
+     else
+     {
+          prevptr->next=temp;
+          return list;
+     }
+}
+
+static mono_type MonListElement (mon_list_entry *list, int n)  // returns ith element from list of monomials - no error checking!
+{
+     mon_list_entry *cur=list;
+     int i;
+     for (i=0;i<n;i++) cur=cur->next;
+     return cur->mon;
+}
+
+static mono_type ZeroMonomial ()  // allocates memory for new monomial with all enries equal 0
+{
+     mono_type m;
+     m=(exponent*)omAlloc0(sizeof(exponent)*variables);
+     return m;
+}
+
+static void GeneralInit ()  // general initialization
+{
+     int i,j;
+     points=(coordinates*)omAlloc(sizeof(coordinates)*n_points);
+     for (i=0;i<n_points;i++)
+     {
+         points[i]=(coordinate_products*)omAlloc(sizeof(coordinate_products)*variables);
+         for (j=0;j<variables;j++) points[i][j]=(modp_number*)omAlloc0(sizeof(modp_number)*(max_coord));
+     }
+     condition_list=(condition_type*)omAlloc0(sizeof(condition_type)*final_base_dim);
+     for (i=0;i<final_base_dim;i++) condition_list[i].mon=(exponent*)omAlloc0(sizeof(exponent)*variables);
+     modp_points=(modp_coordinates*)omAlloc(sizeof(modp_coordinates)*n_points);
+     for (i=0;i<n_points;i++) modp_points[i]=(modp_number*)omAlloc0(sizeof(modp_number)*variables);
+     if (!only_modp)
+     {
+        q_points=(q_coordinates*)omAlloc0(sizeof(q_coordinates)*n_points);
+        for (i=0;i<n_points;i++)
+        {
+            q_points[i]=(mpq_t*)omAlloc(sizeof(mpq_t)*variables);
+            for (j=0;j<variables;j++) mpq_init(q_points[i][j]);
+        }
+        int_points=(int_coordinates*)omAlloc0(sizeof(int_coordinates)*n_points);
+        for (i=0;i<n_points;i++)
+        {
+            int_points[i]=(mpz_t*)omAlloc(sizeof(mpz_t)*variables);
+            for (j=0;j<variables;j++) mpz_init(int_points[i][j]);
+        }
+     }
+     coord_exist=(coord_exist_table*)omAlloc(sizeof(coord_exist_table)*n_points);
+     for (i=0;i<n_points;i++)
+     {
+         coord_exist[i]=(bool*)omAlloc0(sizeof(bool)*variables);
+     }
+     generic_column_name=(mono_type*)omAlloc(sizeof(mono_type)*final_base_dim);
+     for (i=0;i<final_base_dim;i++) generic_column_name[i]=ZeroMonomial ();
+     good_primes=0;
+     bad_primes=1;
+     generic_n_generators=0;
+     if (!only_modp)
+     {
+        polycoef=(mpz_t*)omAlloc(sizeof(mpz_t)*(final_base_dim+1));
+        polyexp=(mono_type*)omAlloc(sizeof(mono_type)*(final_base_dim+1));
+        for (i=0;i<=final_base_dim;i++)
+        {
+             mpz_init(polycoef[i]);
+             polyexp[i]=ZeroMonomial ();
+        }
+        mpz_init(common_denom);
+     }
+
+// set all globally used lists to be initially empty
+     modp_result=NULL;
+     cur_result=NULL;
+     gen_list=NULL;
+     n_results=0;
+
+// creates polynomials to compare by Singular
+     comparizon_p1=pOne();
+     comparizon_p2=pOne();
+}
+
+static void InitProcData ()  // initialization for procedures which do computations mod p
+{
+     int i;
+     check_list=MonListAdd (check_list,ZeroMonomial ());
+     my_row=(modp_number*)omAlloc0(sizeof(modp_number)*final_base_dim);
+     my_solve_row=(modp_number*)omAlloc0(sizeof(modp_number)*final_base_dim);
+     column_name=(mono_type*)omAlloc(sizeof(mono_type)*final_base_dim);
+     for (i=0;i<final_base_dim;i++) column_name[i]=ZeroMonomial ();
+     last_solve_column=0;
+     modp_number *gen_table;
+     modp_number pos_gen;
+     bool gen_ok;
+     modp_Reverse=(modp_number*)omAlloc0(sizeof(modp_number)*myp);
+
+// produces table of modp inverts by finding a generator of (Z_myp*,*)
+     gen_table=(modp_number*)omAlloc(sizeof(modp_number)*myp);
+     gen_table[1]=1;
+     for (pos_gen=2;pos_gen<myp;pos_gen++)
+     {
+         gen_ok=true;
+         for (i=2;i<myp;i++)
+         {
+             gen_table[i]=modp_mul(gen_table[i-1],pos_gen);
+             if (gen_table[i]==1)
+             {
+                gen_ok=false;
+                break;
+             }
+         }
+         if (gen_ok) break;
+     }
+     for (i=2;i<myp;i++) modp_Reverse[gen_table[i]]=gen_table[myp-i+1];
+     modp_Reverse[1]=1;
+     omFree(gen_table);
+}
+
+static mon_list_entry* FreeMonList (mon_list_entry *list)  // destroys a list of monomials, returns NULL pointer
+{
+     mon_list_entry *ptr;
+     mon_list_entry *pptr;
+     ptr=list;
+     while (ptr!=NULL)
+     {
+           pptr=ptr->next;
+           omFree(ptr->mon);
+           omFree(ptr);
+           ptr=pptr;}
+     return NULL;
+}
+
+static void GeneralDone ()  // to be called before exit to free memory
+{
+     int i,j;
+     for (i=0;i<n_points;i++)
+     {
+         for (j=0;j<variables;j++)
+         {
+             omFree(points[i][j]);
+         }
+         omFree(points[i]);
+     }
+     omFree(points);
+     for (i=0;i<final_base_dim;i++) omFree(condition_list[i].mon);
+     omFree(condition_list);
+     for (i=0;i<n_points;i++) omFree(modp_points[i]);
+     omFree(modp_points);
+     if (!only_modp)
+     {
+        for (i=0;i<n_points;i++)
+        {
+            for (j=0;j<variables;j++) mpq_clear(q_points[i][j]);
+            omFree(q_points[i]);
+        }
+        omFree(q_points);
+        for (i=0;i<n_points;i++)
+        {
+            for (j=0;j<variables;j++) mpz_clear(int_points[i][j]);
+            omFree(int_points[i]);
+        }
+        omFree(int_points);
+        generic_lt=FreeMonList (generic_lt);
+        for (i=0;i<=final_base_dim;i++)
+        {
+            mpz_clear(polycoef[i]);
+            omFree(polyexp[i]);
+        }
+        omFree(polycoef);
+        omFree(polyexp);
+        if (!only_modp) mpz_clear(common_denom);
+     }
+     for (i=0;i<final_base_dim;i++)
+     {
+         omFree(generic_column_name[i]);
+     }
+     omFree(generic_column_name);
+     for (i=0;i<n_points;i++) omFree(coord_exist[i]);
+     omFree(coord_exist);
+     pDelete(&comparizon_p1);
+     pDelete(&comparizon_p2);
+}
+
+static void FreeProcData ()  // to be called after one modp computation to free memory
+{
+     int i;
+     row_list_entry *ptr;
+     row_list_entry *pptr;
+     check_list=FreeMonList (check_list);
+     lt_list=FreeMonList (lt_list);
+     base_list=FreeMonList (base_list);
+     omFree(my_row);
+     my_row=NULL;
+     omFree(my_solve_row);
+     my_solve_row=NULL;
+     ptr=row_list;
+     while (ptr!=NULL)
+     {
+           pptr=ptr->next;
+           omFree(ptr->row_matrix);
+           omFree(ptr->row_solve);
+           omFree(ptr);
+           ptr=pptr;
+     }
+     row_list=NULL;
+     for (i=0;i<final_base_dim;i++) omFree(column_name[i]);
+     omFree(column_name);
+     omFree(modp_Reverse);
+}
+
+static void modp_Evaluate(modp_number *ev, mono_type mon, condition_type con)  // evaluates monomial on condition (modp)
+{
+    int i;
+    *ev=0;
+    for (i=0;i<variables;i++)
+        if (con.mon[i] > mon[i]) return ;;
+    *ev=1;
+    int j,k;
+    mono_type mn;
+    mn=(exponent*)omAlloc(sizeof(exponent)*variables);
+    memcpy(mn,mon,sizeof(exponent)*variables);
+    for (k=0;k<variables;k++)
+    {
+        for (j=1;j<=con.mon[k];j++) // this loop computes the coefficient from derivation
+        {
+            *ev=modp_mul(*ev,mn[k]);
+            mn[k]--;
+        }
+        *ev=modp_mul(*ev,points[con.point_ref][k][mn[k]]);
+    }
+    omFree(mn);
+}
+
+static void int_Evaluate(mpz_t ev, mono_type mon, condition_type con) // (***) evaluates monomial on condition for integer numbers
+{
+    int i;
+    mpz_set_si(ev,0);
+    for (i=0;i<variables;i++)
+        if (con.mon[i] > mon[i]) return ;;
+    mpz_set_si(ev,1);
+    mpz_t mon_conv;
+    mpz_init(mon_conv);
+    int j,k;
+    mono_type mn;
+    mn=(exponent*)omAlloc(sizeof(exponent)*variables);
+    memcpy(mn,mon,sizeof(exponent)*variables);
+    for (k=0;k<variables;k++)
+    {
+        for (j=1;j<=con.mon[k];j++) // this loop computes the coefficient from derivation
+        {
+            mpz_set_si(mon_conv,mn[k]); // (***)
+            mpz_mul(ev,ev,mon_conv);
+            mn[k]--;
+        }
+        for (j=1;j<=mn[k];j++) mpz_mul(ev,ev,int_points[con.point_ref][k]);  // this loop computes the product of coordinate
+    }
+    omFree(mn);
+    mpz_clear(mon_conv);
+}
+
+static void ProduceRow(mono_type mon)  // produces a row for monomial - first part is an evaluated part, second 0 to obtain the coefs of dependence
+{
+     modp_number *row;
+     condition_type *con;
+     int i;
+     row=my_row;
+     con=condition_list;
+     for (i=0;i<final_base_dim;i++)
+     {
+         modp_Evaluate (row, mon, *con);
+         row++;
+         con++;
+     }
+     row=my_solve_row;
+     for (i=0;i<final_base_dim;i++)
+     {
+         *row=0;
+         row++;
+     }
+}
+
+static void IntegerPoints ()  // produces integer points from rationals by scaling the coordinate system
+{
+     int i,j;
+     mpz_set_si(common_denom,1); // this is common scaling factor
+     for (i=0;i<n_points;i++)
+     {
+         for (j=0;j<variables;j++)
+         {
+             mpz_lcm(common_denom,common_denom,mpq_denref(q_points[i][j]));
+         }
+     }
+     mpq_t temp;
+     mpq_init(temp);
+     mpq_t denom_q;
+     mpq_init(denom_q);
+     mpq_set_z(denom_q,common_denom);
+     for (i=0;i<n_points;i++)
+     {
+         for (j=0;j<variables;j++)
+         {
+             mpq_mul(temp,q_points[i][j],denom_q);  // multiplies by common denominator
+             mpz_set(int_points[i][j],mpq_numref(temp));  // and changes into integer
+         }
+     }
+     mpq_clear(temp);
+     mpq_clear(denom_q);
+}
+
+static void int_PrepareProducts ()  // prepares coordinates of points and products for modp case (from integer coefs)
+{
+     int i,j,k;
+     mpz_t big_myp;
+     mpz_init(big_myp);
+     mpz_set_si(big_myp,myp);
+     mpz_t temp;
+     mpz_init(temp);
+     for (i=0;i<n_points;i++)
+     {
+         for (j=0;j<variables;j++)
+         {
+             mpz_mod(temp,int_points[i][j],big_myp);  // coordinate is now modulo myp
+             points[i][j][1]=mpz_get_ui(temp);
+             points[i][j][0]=1;
+             for (k=2;k<max_coord;k++) points[i][j][k]=modp_mul(points[i][j][k-1],points[i][j][1]);
+         }
+     }
+     mpz_mod(temp,common_denom,big_myp);  // computes the common denominator (from rational data) modulo myp
+     denom_divisible=(mpz_sgn(temp)==0);  // checks whether it is divisible by modp
+     mpz_clear(temp);
+     mpz_clear(big_myp);
+}
+
+static void modp_PrepareProducts () // prepares products for modp computation from modp data
+{
+     int i,j,k;
+     for (i=0;i<n_points;i++)
+     {
+         for (j=0;j<variables;j++)
+         {
+             points[i][j][1]=modp_points[i][j];
+             points[i][j][0]=1;
+             for (k=2;k<max_coord;k++) points[i][j][k]=modp_mul(points[i][j][k-1],points[i][j][1]);
+         }
+     }
+}
+
+static void MakeConditions ()  // prepares a list of conditions from list of multiplicities
+{
+     condition_type *con;
+     int n,i,k;
+     mono_type mon;
+     mon=ZeroMonomial ();
+     con=condition_list;
+     for (n=0;n<n_points;n++)
+     {
+         for (i=0;i<variables;i++) mon[i]=0;
+         while (mon[0]<multiplicity[n])
+         {
+             if (MonDegree (mon) < multiplicity[n])
+             {
+                memcpy(con->mon,mon,sizeof(exponent)*variables);
+                con->point_ref=n;
+                con++;
+             }
+             k=variables-1;
+             mon[k]++;
+             while ((k>0)&&(mon[k]>=multiplicity[n]))
+             {
+                 mon[k]=0;
+                 k--;
+                 mon[k]++;
+             }
+         }
+     }
+     omFree(mon);
+}
+
+static void ReduceRow ()  // reduces my_row by previous rows, does the same for solve row
+{
+     if (row_list==NULL) return ;
+     row_list_entry *row_ptr;
+     modp_number *cur_row_ptr;
+     modp_number *solve_row_ptr;
+     modp_number *my_row_ptr;
+     modp_number *my_solve_row_ptr;
+     int first_col;
+     int i;
+     modp_number red_val;
+     modp_number mul_val;
+#ifdef integerstrategy
+     modp_number *m_row_ptr;
+     modp_number prep_val;
+#endif
+     row_ptr=row_list;
+     while (row_ptr!=NULL)
+     {
+           cur_row_ptr=row_ptr->row_matrix;
+           solve_row_ptr=row_ptr->row_solve;
+           my_row_ptr=my_row;
+           my_solve_row_ptr=my_solve_row;
+           first_col=row_ptr->first_col;
+           cur_row_ptr=cur_row_ptr+first_col;  // reduction begins at first_col position
+           my_row_ptr=my_row_ptr+first_col;
+           red_val=*my_row_ptr;
+           if (red_val!=0)
+           {
+#ifdef integerstrategy
+              prep_val=*cur_row_ptr;
+              if (prep_val!=1)
+              {
+                 m_row_ptr=my_row;
+                 for (i=0;i<final_base_dim;i++)
+                 {
+                     if (*m_row_ptr!=0) *m_row_ptr=modp_mul(*m_row_ptr,prep_val);
+                     m_row_ptr++;
+                 }
+                 m_row_ptr=my_solve_row;
+                 for (i=0;i<last_solve_column;i++)
+                 {
+                     if (*m_row_ptr!=0) *m_row_ptr=modp_mul(*m_row_ptr,prep_val);
+                     m_row_ptr++;
+                 }
+              }
+#endif
+              for (i=first_col;i<final_base_dim;i++)
+              {
+                  if (*cur_row_ptr!=0)
+                  {
+                    mul_val=modp_mul(*cur_row_ptr,red_val);
+                    *my_row_ptr=modp_sub(*my_row_ptr,mul_val);
+                  }
+                  my_row_ptr++;
+                  cur_row_ptr++;
+              }
+              for (i=0;i<=last_solve_column;i++)  // last_solve_column stores the last non-enmpty entry in solve matrix
+              {
+                  if (*solve_row_ptr!=0)
+                  {
+                     mul_val=modp_mul(*solve_row_ptr,red_val);
+                     *my_solve_row_ptr=modp_sub(*my_solve_row_ptr,mul_val);
+                  }
+                  solve_row_ptr++;
+                  my_solve_row_ptr++;
+              }
+           }
+           row_ptr=row_ptr->next;
+#if 0 /* only debugging */
+           PrintS("reduction by row ");
+           Info ();
+#endif
+     }
+}
+
+static bool RowIsZero () // check whether a row is zero
+{
+     bool zero=1;
+     int i;
+     modp_number *row;
+     row=my_row;
+     for (i=0;i<final_base_dim;i++)
+     {
+         if (*row!=0) {zero=0; break;}
+         row++;
+     }
+     return zero;
+}
+
+static bool DivisibleMon (mono_type m1, mono_type m2) // checks whether m1 is divisible by m2
+{
+     int i;
+     for (i=0;i<variables;i++)
+         if (m1[i]>m2[i]) return false;;
+     return true;
+}
+
+static void ReduceCheckListByMon (mono_type m)  // from check_list monomials divisible by m are thrown out
+{
+     mon_list_entry *c_ptr;
+     mon_list_entry *p_ptr;
+     mon_list_entry *n_ptr;
+     c_ptr=check_list;
+     p_ptr=NULL;
+     while (c_ptr!=NULL)
+     {
+          if (DivisibleMon (m,c_ptr->mon))
+          {
+             if (p_ptr==NULL)
+                check_list=c_ptr->next;
+             else
+                p_ptr->next=c_ptr->next;
+             n_ptr=c_ptr->next;
+             omFree(c_ptr->mon);
+             omFree(c_ptr);
+             c_ptr=n_ptr;
+          }
+          else
+          {
+              p_ptr=c_ptr;
+              c_ptr=c_ptr->next;
+          }
+     }
+}
+
+static void TakeNextMonomial (mono_type mon)  // reads first monomial from check_list, then it is deleted
+{
+     mon_list_entry *n_check_list;
+     if (check_list!=NULL)
+     {
+        memcpy(mon,check_list->mon,sizeof(exponent)*variables);
+        n_check_list=check_list->next;
+        omFree(check_list->mon);
+        omFree(check_list);
+        check_list=n_check_list;
+     }
+}
+
+static void UpdateCheckList (mono_type m) // adds all monomials which are "next" to m (divisible by m and degree +1)
+{
+     int i;
+     for (i=0;i<variables;i++)
+     {
+         m[i]++;
+         check_list=MonListAdd (check_list,m);
+         m[i]--;
+     }
+}
+
+static void ReduceCheckListByLTs ()  // deletes all monomials from check_list which are divisible by one of the leading terms
+{
+     mon_list_entry *ptr;
+     ptr=lt_list;
+     while (ptr!=NULL)
+     {
+           ReduceCheckListByMon (ptr->mon);
+           ptr=ptr->next;
+     }
+}
+
+static void RowListAdd (int first_col, mono_type mon) // puts a row into matrix
+{
+     row_list_entry *ptr;
+     row_list_entry *pptr;
+     row_list_entry *temp;
+     ptr=row_list;
+     pptr=NULL;
+     while (ptr!=NULL)
+     {
+#ifndef unsortedmatrix
+         if (  first_col <= ptr->first_col ) break;
+#endif
+         pptr=ptr;
+         ptr=ptr->next;
+     }
+     temp=(row_list_entry*)omAlloc0(sizeof(row_list_entry));
+     (*temp).row_matrix=(modp_number*)omAlloc0(sizeof(modp_number)*final_base_dim);
+     memcpy((*temp).row_matrix,my_row,sizeof(modp_number)*(final_base_dim));
+     (*temp).row_solve=(modp_number*)omAlloc0(sizeof(modp_number)*final_base_dim);
+     memcpy((*temp).row_solve,my_solve_row,sizeof(modp_number)*(final_base_dim));
+     (*temp).first_col=first_col;
+     temp->next=ptr;
+     if (pptr==NULL) row_list=temp; else pptr->next=temp;
+     memcpy(column_name[first_col],mon,sizeof(exponent)*variables);
+}
+
+
+static void PrepareRow (mono_type mon) // prepares a row and puts it into matrix
+{
+     modp_number *row;
+     int first_col=-1;
+     int col;
+     modp_number red_val=1;
+     row=my_row;
+#ifdef integerstrategy
+     for (col=0;col<final_base_dim;col++)
+     {
+         if (*row!=0)
+         {
+            first_col=col;
+            break;
+         }
+         row++;
+     }
+     my_solve_row[first_col]=1;
+     if (first_col > last_solve_column) last_solve_column=first_col;
+#else
+     for (col=0;col<final_base_dim;col++)
+     {
+         if (*row!=0)
+         {
+            first_col=col;
+            red_val=modp_Reverse[*row]; // first non-zero entry, should multiply all row by inverse to obtain 1
+            modp_denom=modp_mul(modp_denom,*row);  // remembers the divisor
+            *row=1;
+            break;
+         }
+         row++;
+     }
+     my_solve_row[first_col]=1;
+     if (first_col > last_solve_column) last_solve_column=first_col;
+     if (red_val!=1)
+     {
+        row++;
+        for (col=first_col+1;col<final_base_dim;col++)
+        {
+            if (*row!=0) *row=modp_mul(*row,red_val);
+            row++;
+        }
+        row=my_solve_row;
+        for (col=0;col<=last_solve_column;col++)
+        {
+            if (*row!=0) *row=modp_mul(*row,red_val);
+            row++;
+        }
+     }
+#endif
+     RowListAdd (first_col, mon);
+}
+
+static void NewResultEntry ()  // creates an entry for new modp result
+{
+    modp_result_entry *temp;
+    temp=(modp_result_entry*)omAlloc0(sizeof(modp_result_entry));
+    if (cur_result==NULL)
+    {
+       modp_result=temp;
+       temp->prev=NULL;
+    }
+    else
+    {
+       temp->prev=cur_result;
+       cur_result->next=temp;
+    }
+    cur_result=temp;
+    cur_result->next=NULL;
+    cur_result->p=myp;
+    cur_result->generator=NULL;
+    cur_result->n_generators=0;
+    n_results++;
+}
+
+static void FreeResultEntry (modp_result_entry *e) // destroys the result entry, without worrying about where it is
+{
+     generator_entry *cur_gen;
+     generator_entry *next_gen;
+     cur_gen=e->generator;
+     while (cur_gen!=NULL)
+     {
+         next_gen=cur_gen->next;
+         omFree(cur_gen->coef);
+         omFree(cur_gen->lt);
+         omFree(cur_gen);
+         cur_gen=next_gen;
+     }
+     omFree(e);
+}
+
+
+static void NewGenerator (mono_type mon)  // new generator in modp comp found, shoul be stored on the list
+{
+     generator_entry *cur_ptr;
+     generator_entry *prev_ptr;
+     generator_entry *temp;
+     cur_ptr=cur_result->generator;
+     prev_ptr=NULL;
+     while (cur_ptr!=NULL)
+     {
+         prev_ptr=cur_ptr;
+         cur_ptr=cur_ptr->next;
+     }
+     temp=(generator_entry*)omAlloc0(sizeof(generator_entry));
+     if (prev_ptr==NULL) cur_result->generator=temp;
+     else prev_ptr->next=temp;
+     temp->next=NULL;
+     temp->coef=(modp_number*)omAlloc0(sizeof(modp_number)*final_base_dim);
+     memcpy(temp->coef,my_solve_row,sizeof(modp_number)*final_base_dim);
+     temp->lt=ZeroMonomial ();
+     memcpy(temp->lt,mon,sizeof(exponent)*variables);
+     temp->ltcoef=1;
+     cur_result->n_generators++;
+}
+
+static void MultGenerators () // before reconstructing, all denominators must be cancelled
+{
+#ifndef integerstrategy
+     int i;
+     generator_entry *cur_ptr;
+     cur_ptr=cur_result->generator;
+     while (cur_ptr!=NULL)
+     {
+         for (i=0;i<final_base_dim;i++)
+             cur_ptr->coef[i]=modp_mul(cur_ptr->coef[i],modp_denom);
+         cur_ptr->ltcoef=modp_denom;
+         cur_ptr=cur_ptr->next;
+     }
+#endif
+}
+#if 0 /* only debbuging */
+void PresentGenerator (int i)  // only for debuging, writes a generator in its form in program
+{
+     int j;
+     modp_result_entry *cur_ptr;
+     generator_entry *cur_gen;
+     cur_ptr=modp_result;
+     while (cur_ptr!=NULL)
+     {
+        cur_gen=cur_ptr->generator;
+        for (j=0;j<i;j++) cur_gen=cur_gen->next;
+        for (j=0;j<final_base_dim;j++)
+        {
+            Print("%d;", cur_gen->coef[j]);
+        }
+        PrintS(" and LT = ");
+        WriteMono (cur_gen->lt);
+        Print(" ( %d )  prime = %d\n", cur_gen->ltcoef, cur_ptr->p);
+        cur_ptr=cur_ptr->next;
+     }
+}
+#endif
+
+static modp_number TakePrime (modp_number /*p*/)  // takes "previous" (smaller) prime
+{
+    myp_index--;
+    return cf_getSmallPrime(myp_index);
+}
+
+static void PrepareChinese (int n) // initialization for CRA
+{
+     int i,k;
+     modp_result_entry *cur_ptr;
+     cur_ptr=modp_result;
+     modp_number *congr_ptr;
+     modp_number prod;
+     in_gamma=(modp_number*)omAlloc0(sizeof(modp_number)*n);
+     congr=(modp_number*)omAlloc0(sizeof(modp_number)*n);
+     congr_ptr=congr;
+     while (cur_ptr!=NULL)
+     {
+        *congr_ptr=cur_ptr->p;
+        cur_ptr=cur_ptr->next;
+        congr_ptr++;
+     }
+     for (k=1;k<n;k++)
+     {
+         prod=congr[0]%congr[k];
+         for (i=1;i<=k-1;i++) prod=(prod*congr[i])%congr[k];
+         in_gamma[i]=OneInverse(prod,congr[k]);
+     }
+     mpz_init(bigcongr);
+     mpz_set_ui(bigcongr,congr[0]);
+     for (k=1;k<n;k++) mpz_mul_ui(bigcongr,bigcongr,congr[k]);
+}
+
+static void CloseChinese () // after CRA
+{
+     omFree(in_gamma);
+     omFree(congr);
+     mpz_clear(bigcongr);
+}
+
+static void ClearGCD () // divides polynomials in basis by gcd of coefficients
+{
+     bool first_gcd=true;
+     int i;
+     mpz_t g;
+     mpz_init(g);
+     for (i=0;i<=final_base_dim;i++)
+     {
+         if (mpz_sgn(polycoef[i])!=0)
+         {
+            if (first_gcd)
+            {
+               first_gcd=false;
+               mpz_set(g,polycoef[i]);
+            }
+            else
+               mpz_gcd(g,g,polycoef[i]);
+         }
+     }
+     for (i=0;i<=final_base_dim;i++) mpz_divexact(polycoef[i],polycoef[i],g);
+     mpz_clear(g);
+}
+
+static void ReconstructGenerator (int ngen,int n) // recostruction of generator from various modp comp
+{
+     int i,j,k;
+     int coef;
+     char *str=NULL;
+     str=(char*)omAlloc0(sizeof(char)*1000);
+     modp_result_entry *cur_ptr;
+     generator_entry *cur_gen;
+     modp_number *u;
+     modp_number *v;
+     modp_number temp;
+     mpz_t sol;
+     mpz_t nsol;
+     mpz_init(sol);
+     mpz_init(nsol);
+     u=(modp_number*)omAlloc0(sizeof(modp_number)*n);
+     v=(modp_number*)omAlloc0(sizeof(modp_number)*n);
+     for (coef=0;coef<=final_base_dim;coef++)
+     {
+         i=0;
+         cur_ptr=modp_result;
+         while (cur_ptr!=NULL)
+         {
+            cur_gen=cur_ptr->generator;
+            for (j=0;j<ngen;j++) cur_gen=cur_gen->next; // we have to take jth generator
+            if (coef<final_base_dim) u[i]=cur_gen->coef[coef]; else u[i]=cur_gen->ltcoef;
+            cur_ptr=cur_ptr->next;
+            i++;
+         }
+         v[0]=u[0]; // now CRA begins
+         for (k=1;k<n;k++)
+         {
+             temp=v[k-1];
+             for (j=k-2;j>=0;j--) temp=(temp*congr[j]+v[j])%congr[k];
+             temp=u[k]-temp;
+             if (temp<0) temp=temp+congr[k];
+             v[k]=(temp*in_gamma[k])%congr[k];
+         }
+         mpz_set_si(sol,v[n-1]);
+         for (k=n-2;k>=0;k--)
+         {
+             mpz_mul_ui(sol,sol,congr[k]);
+             mpz_add_ui(sol,sol,v[k]);
+         }          // now CRA ends
+         mpz_sub(nsol,sol,bigcongr);
+         int s=mpz_cmpabs(sol,nsol);
+         if (s>0) mpz_set(sol,nsol); // chooses representation closer to 0
+         mpz_set(polycoef[coef],sol);
+         if (coef<final_base_dim)
+            memcpy(polyexp[coef],generic_column_name[coef],sizeof(exponent)*variables);
+         else
+            memcpy(polyexp[coef],MonListElement (generic_lt,ngen),sizeof(exponent)*variables);
+#ifdef checksize
+         size=mpz_sizeinbase(sol,10);
+         if (size>maximal_size) maximal_size=size;
+#endif
+     }
+     omFree(u);
+     omFree(v);
+     omFree(str);
+     ClearGCD ();
+     mpz_clear(sol);
+     mpz_clear(nsol);
+}
+
+static void Discard ()  // some unlucky prime occures
+{
+     modp_result_entry *temp;
+#ifdef writemsg
+     Print(", prime=%d", cur_result->p);
+#endif
+     bad_primes++;
+     if (good_primes>bad_primes)
+     {
+#ifdef writemsg
+        Print("-discarding this comp (%dth)\n", n_results);
+#endif
+        temp=cur_result;
+        cur_result=cur_result->prev;
+        cur_result->next=NULL;
+        n_results--;
+        FreeResultEntry (temp);
+     }
+     else
+     {
+#ifdef writemsg
+        PrintS("-discarding ALL.\n");
+#endif
+        int i;
+        modp_result_entry *ntfree;
+        generator_entry *cur_gen;
+        temp=cur_result->prev;
+        while (temp!=NULL)
+        {
+            ntfree=temp->prev;
+            FreeResultEntry (temp);
+            temp=ntfree;
+        }
+        modp_result=cur_result;
+        cur_result->prev=NULL;
+        n_results=1;
+        good_primes=1;
+        bad_primes=0;
+        generic_n_generators=cur_result->n_generators;
+        cur_gen=cur_result->generator;
+        generic_lt=FreeMonList (generic_lt);
+        for (i=0;i<generic_n_generators;i++)
+        {
+            generic_lt=MonListAdd (generic_lt,cur_gen->lt);
+            cur_gen=cur_gen->next;
+        }
+        for (i=0;i<final_base_dim;i++) memcpy(generic_column_name[i],column_name[i],sizeof(exponent)*variables);
+     }
+}
+
+static void modp_SetColumnNames ()  // used by modp - sets column names, the old table will be destroyed
+{
+    int i;
+    for (i=0;i<final_base_dim;i++) memcpy(generic_column_name[i],column_name[i],sizeof(exponent)*variables);
+}
+
+static void CheckColumnSequence () // checks if scheme of computations is as generic one
+{
+     int i;
+     if (cur_result->n_generators!=generic_n_generators)
+     {
+#ifdef writemsg
+        PrintS("wrong number of generators occured");
+#else
+        if (protocol) PrintS("ng");
+#endif
+        Discard ();
+        return;
+     }
+     if (denom_divisible)
+     {
+#ifdef writemsg
+        PrintS("denom of coef divisible by p");
+#else
+        if (protocol) PrintS("dp");
+#endif
+        Discard ();
+        return;
+     }
+     generator_entry *cur_gen;
+     mon_list_entry *cur_mon;
+     cur_gen=cur_result->generator;
+     cur_mon=generic_lt;
+     for (i=0;i<generic_n_generators;i++)
+     {
+         if (!EqualMon(cur_mon->mon,cur_gen->lt))
+         {
+#ifdef writemsg
+            PrintS("wrong leading term occured");
+#else
+            if (protocol) PrintS("lt");
+#endif
+            Discard ();
+            return;
+         }
+         cur_gen=cur_gen->next;
+         cur_mon=cur_mon->next;
+     }
+     for (i=0;i<final_base_dim;i++)
+     {
+         if (!EqualMon(generic_column_name[i],column_name[i]))
+         {
+#ifdef writemsg
+            PrintS("wrong seq of cols occured");
+#else
+            if (protocol) PrintS("sc");
+#endif
+            Discard ();
+            return;
+         }
+     }
+     good_primes++;
+}
+#if 0 /* only debuggig */
+void WriteGenerator () // writes generator (only for debugging)
+{
+     char *str;
+     str=(char*)omAlloc0(sizeof(char)*1000);
+     int i;
+     for (i=0;i<=final_base_dim;i++)
+     {
+         str=mpz_get_str(str,10,polycoef[i]);
+         PrintS(str);
+         PrintS("*");
+         WriteMono(polyexp[i]);
+         PrintS(" ");
+     }
+     omFree(str);
+     PrintLn();
+}
+#endif
+
+static bool CheckGenerator () // evaluates generator to check whether it is good
+{
+     mpz_t val,sum;
+     int con,i;
+     mpz_init(val);
+     mpz_init(sum);
+     for (con=0;con<final_base_dim;con++)
+     {
+       mpz_set_si(sum,0);
+       for (i=0;i<=final_base_dim;i++)
+       {
+         int_Evaluate(val, polyexp[i], condition_list[con]);
+         mpz_mul(val,val,polycoef[i]);
+         mpz_add(sum,sum,val);
+       }
+       if (mpz_sgn(sum)!=0)
+       {
+          mpz_clear(val);
+          mpz_clear(sum);
+          return false;
+       }
+    }
+    mpz_clear(val);
+    mpz_clear(sum);
+    return true;
+}
+
+static void ClearGenList ()
+{
+     gen_list_entry *temp;
+     int i;
+     while (gen_list!=NULL)
+     {
+         temp=gen_list->next;
+         for (i=0;i<=final_base_dim;i++)
+         {
+             mpz_clear(gen_list->polycoef[i]);
+             omFree(gen_list->polyexp[i]);
+         }
+         omFree(gen_list->polycoef);
+         omFree(gen_list->polyexp);
+         omFree(gen_list);
+         gen_list=temp;
+      }
+}
+
+static void UpdateGenList ()
+{
+     gen_list_entry *temp,*prev;
+     int i,j;
+     prev=NULL;
+     temp=gen_list;
+     exponent deg;
+     for (i=0;i<=final_base_dim;i++)
+     {
+         deg=MonDegree(polyexp[i]);
+         for (j=0;j<deg;j++)
+         {
+             mpz_mul(polycoef[i],polycoef[i],common_denom);
+         }
+     }
+     ClearGCD ();
+     while (temp!=NULL)
+     {
+         prev=temp;
+         temp=temp->next;
+     }
+     temp=(gen_list_entry*)omAlloc0(sizeof(gen_list_entry));
+     if (prev==NULL) gen_list=temp; else prev->next=temp;
+     temp->next=NULL;
+     temp->polycoef=(mpz_t*)omAlloc(sizeof(mpz_t)*(final_base_dim+1));
+     temp->polyexp=(mono_type*)omAlloc(sizeof(mono_type)*(final_base_dim+1));
+     for (i=0;i<=final_base_dim;i++)
+     {
+         mpz_init(temp->polycoef[i]);
+         mpz_set(temp->polycoef[i],polycoef[i]);
+         temp->polyexp[i]=ZeroMonomial ();
+         memcpy(temp->polyexp[i],polyexp[i],sizeof(exponent)*variables);
+     }
+}
+
+#if 0 /* only debugging */
+void ShowGenList ()
+{
+     gen_list_entry *temp;
+     int i;
+     char *str;
+     str=(char*)omAlloc0(sizeof(char)*1000);
+     temp=gen_list;
+     while (temp!=NULL)
+     {
+         PrintS("generator: ");
+         for (i=0;i<=final_base_dim;i++)
+         {
+             str=mpz_get_str(str,10,temp->polycoef[i]);
+             PrintS(str);
+             PrintS("*");
+             WriteMono(temp->polyexp[i]);
+         }
+         PrintLn();
+         temp=temp->next;
+     }
+     omFree(str);
+}
+#endif
+
+
+static void modp_Main ()
+{
+     mono_type cur_mon;
+     cur_mon= ZeroMonomial ();
+     modp_denom=1;
+     bool row_is_zero;
+
+#if 0 /* only debugging */
+     Info ();
+#endif
+
+     while (check_list!=NULL)
+     {
+           TakeNextMonomial (cur_mon);
+           ProduceRow (cur_mon);
+#if 0 /* only debugging */
+           cout << "row produced for monomial ";
+           WriteMono (cur_mon);
+           cout << endl;
+           Info ();
+#endif
+           ReduceRow ();
+           row_is_zero = RowIsZero ();
+           if (row_is_zero)
+           {
+              lt_list=MonListAdd (lt_list,cur_mon);
+              ReduceCheckListByMon (cur_mon);
+              NewGenerator (cur_mon);
+#if 0 /* only debugging */
+              cout << "row is zero - linear dependence found (should be seen in my_solve_row)" << endl;
+              cout << "monomial added to leading terms list" << endl;
+              cout << "check list updated" << endl;
+              Info ();
+#endif
+           }
+           else
+           {
+              base_list= MonListAdd (base_list,cur_mon);
+              UpdateCheckList (cur_mon);
+              ReduceCheckListByLTs ();
+#if 0 /* only debugging */
+              cout << "row is non-zero" << endl;
+              cout << "monomial added to quotient basis list" << endl;
+              cout << "new monomials added to check list" << endl;
+              cout << "check list reduced by monomials from leading term list" << endl;
+              Info ();
+#endif
+              PrepareRow (cur_mon);
+#if 0 /* only debugging */
+              cout << "row prepared and put into matrix" << endl;
+              Info ();
+#endif
+           }
+        }
+        omFree(cur_mon);
+}
+
+static void ResolveCoeff (mpq_t c, number m)
+{
+  if ((long)m & SR_INT)
+  {
+    long m_val=SR_TO_INT(m);
+    mpq_set_si(c,m_val,1);
+  }
+  else
+  {
+    if (m->s<2)
+    {
+      mpz_set(mpq_numref(c),m->z);
+      mpz_set(mpq_denref(c),m->n);
+      mpq_canonicalize(c);
+    }
+    else
+    {
+      mpq_set_z(c,m->z);
+    }
+  }
+}
+
+ideal interpolation(const std::vector<ideal>& L, intvec *v)
+{
+  protocol=TEST_OPT_PROT;  // should be set if option(prot) is enabled
+
+  bool data_ok=true;
+
+  // reading the ring data ***************************************************
+  if ((currRing==NULL) || ((!rField_is_Zp (currRing))&&(!rField_is_Q (currRing))))
+  {
+     WerrorS("coefficient field should be Zp or Q!");
+     return NULL;
+  }
+  if ((currRing->qideal)!=NULL)
+  {
+     WerrorS("quotient ring not supported!");
+     return NULL;
+  }
+  if ((currRing->OrdSgn)!=1)
+  {
+     WerrorS("ordering must be global!");
+     return NULL;
+  }
+  n_points=v->length ();
+  if (n_points!=L.size())
+  {
+     WerrorS("list and intvec must have the same length!");
+     return NULL;
+  }
+  assume( n_points > 0 );
+  variables=currRing->N;
+  only_modp=rField_is_Zp(currRing);
+  if (only_modp) myp=rChar(currRing);
+  // ring data read **********************************************************
+
+
+  multiplicity=(int*)malloc(sizeof(int)*n_points); // TODO: use omalloc!
+  int i;
+  for (i=0;i<n_points;i++) multiplicity[i]=(*v)[i];
+
+  final_base_dim = CalcBaseDim ();
+
+#ifdef writemsg
+  Print("number of variables: %d\n", variables);
+  Print("number of points: %d\n", n_points);
+  PrintS("multiplicities: ");
+  for (i=0;i<n_points;i++) Print("%d ", multiplicity[i]);
+  PrintLn();
+  Print("general initialization for dimension %d ...\n", final_base_dim);
+#endif
+
+  GeneralInit ();
+
+// reading coordinates of points from ideals **********************************
+  mpq_t divisor;
+  if (!only_modp) mpq_init(divisor);
+  int j;
+  for(i=0; i<L.size();i++)
+  {
+    ideal I = L[i];
+    for(j=0;j<IDELEMS(I);j++)
+    {
+      poly p=I->m[j];
+      if (p!=NULL)
+      {
+        poly ph=pHead(p);
+        int pcvar=pVar(ph);
+        if (pcvar!=0)
+        {
+          pcvar--;
+          if (coord_exist[i][pcvar])
+          {
+             Print("coordinate %d for point %d initialized twice!\n",pcvar+1,i+1);
+             data_ok=false;
+          }
+          number m;
+          m=pGetCoeff(p); // possible coefficient standing by a leading monomial
+          if (!only_modp) ResolveCoeff (divisor,m);
+          number n;
+          if (pNext(p)!=NULL) n=pGetCoeff(pNext(p));
+          else n=nInit(0);
+          if (only_modp)
+          {
+            n=nInpNeg(n);
+            n=nDiv(n,m);
+            modp_points[i][pcvar]=(int)((long)n);
+          }
+          else
+          {
+            ResolveCoeff (q_points[i][pcvar],n);
+            mpq_neg(q_points[i][pcvar],q_points[i][pcvar]);
+            mpq_div(q_points[i][pcvar],q_points[i][pcvar],divisor);
+          }
+          coord_exist[i][pcvar]=true;
+        }
+        else
+        {
+          PrintS("not a variable? ");
+          wrp(p);
+          PrintLn();
+          data_ok=false;
+        }
+        pDelete(&ph);
+      }
+    }
+  }
+  if (!only_modp) mpq_clear(divisor);
+  // data from ideal read *******************************************************
+
+  // ckecking if all coordinates are initialized
+  for (i=0;i<n_points;i++)
+  {
+      for (j=0;j<variables;j++)
+      {
+          if (!coord_exist[i][j])
+          {
+             Print("coordinate %d for point %d not known!\n",j+1,i+1);
+             data_ok=false;
+          }
+      }
+  }
+
+  if (!data_ok)
+  {
+     GeneralDone();
+     WerrorS("data structure is invalid");
+     return NULL;
+  }
+
+  if (!only_modp) IntegerPoints ();
+  MakeConditions ();
+#ifdef writemsg
+  PrintS("done.\n");
+#else
+  if (protocol) Print("[vdim %d]",final_base_dim);
+#endif
+
+
+// main procedure *********************************************************************
+  int modp_cycles=10;
+  bool correct_gen=false;
+  if (only_modp) modp_cycles=1;
+  myp_index=cf_getNumSmallPrimes ();
+
+  while ((!correct_gen)&&(myp_index>1))
+  {
+#ifdef writemsg
+        Print("trying %d cycles mod p...\n",modp_cycles);
+#else
+        if (protocol) Print("(%d)",modp_cycles);
+#endif
+        while ((n_results<modp_cycles)&&(myp_index>1))  // some computations mod p
+        {
+            if (!only_modp) myp=TakePrime (myp);
+            NewResultEntry ();
+            InitProcData ();
+            if (only_modp) modp_PrepareProducts (); else int_PrepareProducts ();
+
+            modp_Main ();
+
+            if (!only_modp)
+            {
+               MultGenerators ();
+               CheckColumnSequence ();
+            }
+            else
+            {
+               modp_SetColumnNames ();
+            }
+            FreeProcData ();
+        }
+
+        if (!only_modp)
+        {
+           PrepareChinese (modp_cycles);
+           correct_gen=true;
+           for (i=0;i<generic_n_generators;i++)
+           {
+               ReconstructGenerator (i,modp_cycles);
+               correct_gen=CheckGenerator ();
+               if (!correct_gen)
+               {
+#ifdef writemsg
+                  PrintS("wrong generator!\n");
+#else
+//                  if (protocol) PrintS("!g");
+#endif
+                  ClearGenList ();
+                  break;
+               }
+               else
+               {
+                  UpdateGenList ();
+               }
+           }
+#ifdef checksize
+           Print("maximal size of output: %d, precision bound: %d.\n",maximalsize,mpz_sizeinbase(bigcongr,10));
+#endif
+           CloseChinese ();
+           modp_cycles=modp_cycles+10;
+        }
+        else
+        {
+           correct_gen=true;
+        }
+  }
+// end of main procedure ************************************************************************************
+
+#ifdef writemsg
+  PrintS("computations finished.\n");
+#else
+  if (protocol) PrintLn();
+#endif
+
+  if (!correct_gen)
+  {
+     GeneralDone ();
+     ClearGenList ();
+     WerrorS("internal error - coefficient too big!");
+     return NULL;
+  }
+
+// passing data to ideal *************************************************************************************
+  ideal ret;
+
+  if (only_modp)
+  {
+    mono_type mon;
+    ret=idInit(modp_result->n_generators,1);
+    generator_entry *cur_gen=modp_result->generator;
+    for(i=0;i<IDELEMS(ret);i++)
+    {
+      poly p,sum;
+      sum=NULL;
+      int a;
+      int cf;
+      for (a=final_base_dim;a>=0;a--)
+      {
+        if (a==final_base_dim) cf=cur_gen->ltcoef; else cf=cur_gen->coef[a];
+        if (cf!=0)
+        {
+            p=pISet(cf);
+            if (a==final_base_dim) mon=cur_gen->lt; else mon=generic_column_name[a];
+            for (j=0;j<variables;j++) pSetExp(p,j+1,mon[j]);
+            pSetm(p);
+            sum=pAdd(sum,p);
+        }
+      }
+      ret->m[i]=sum;
+      cur_gen=cur_gen->next;
+    }
+  }
+  else
+  {
+    ret=idInit(generic_n_generators,1);
+    gen_list_entry *temp=gen_list;
+    for(i=0;i<IDELEMS(ret);i++)
+    {
+      poly p,sum;
+      sum=NULL;
+      int a;
+      for (a=final_base_dim;a>=0;a--) // build one polynomial
+      {
+          if (mpz_sgn(temp->polycoef[a])!=0)
+          {
+             number n=ALLOC_RNUMBER();
+#ifdef LDEBUG
+             n->debug=123456;
+#endif
+             mpz_init_set(n->z,temp->polycoef[a]);
+             n->s=3;
+             n_Normalize(n, currRing->cf);
+             p=pNSet(n); //a monomial
+             for (j=0;j<variables;j++) pSetExp(p,j+1,temp->polyexp[a][j]);
+             pSetm(p); // after all pSetExp
+             sum=pAdd(sum,p);
+          }
+      }
+      ret->m[i]=sum;
+      temp=temp->next;
+    }
+  }
+// data transferred ****************************************************************************
+
+
+  GeneralDone ();
+  ClearGenList ();
+  return ret;
+}
+
+
diff --git a/kernel/linear_algebra/interpolation.h b/kernel/linear_algebra/interpolation.h
new file mode 100644
index 0000000..ec414fc
--- /dev/null
+++ b/kernel/linear_algebra/interpolation.h
@@ -0,0 +1,20 @@
+/*****************************************
+*  Computer Algebra System SINGULAR      *
+*****************************************/
+/*
+* ABSTRACT: ideals of points (with multiplicities)
+*/
+
+#ifndef INTERPOLATION_H
+#define INTERPOLATION_H
+
+#include <vector>
+
+class intvec;
+struct sip_sideal; typedef struct sip_sideal * ideal;
+
+ideal interpolation(const std::vector<ideal>& L, intvec *v);
+
+
+#endif
+
diff --git a/kernel/linear_algebra/linearAlgebra.cc b/kernel/linear_algebra/linearAlgebra.cc
new file mode 100644
index 0000000..750d3e3
--- /dev/null
+++ b/kernel/linear_algebra/linearAlgebra.cc
@@ -0,0 +1,1597 @@
+/*****************************************************************************\
+ * Computer Algebra System SINGULAR
+\*****************************************************************************/
+/** @file lineareAlgebra.cc
+ *
+ * This file implements basic linear algebra functionality.
+ *
+ * For more general information, see the documentation in
+ * lineareAlgebra.h.
+ *
+ * @author Frank Seelisch
+ *
+ *
+ **/
+/*****************************************************************************/
+
+// include header files
+
+
+
+#include <kernel/mod2.h>
+
+#include <coeffs/coeffs.h>
+#include <coeffs/numbers.h>
+
+#include <coeffs/mpr_complex.h>
+#include <polys/monomials/p_polys.h>
+#include <polys/simpleideals.h>
+#include <polys/matpol.h>
+
+// #include <kernel/polys.h>
+
+#include <kernel/structs.h>
+#include <kernel/ideals.h>
+#include <kernel/linear_algebra/linearAlgebra.h>
+
+/**
+ * The returned score is based on the implementation of 'nSize' for
+ * numbers (, see numbers.h): nSize(n) provides a measure for the
+ * complexity of n. Thus, less complex pivot elements will be
+ * prefered, and get therefore a smaller pivot score. Consequently,
+ * we simply return the value of nSize.
+ * An exception to this rule are the ground fields R, long R, and
+ * long C: In these, the result of nSize relates to |n|. And since
+ * a larger modulus of the pivot element ensures a numerically more
+ * stable Gauss elimination, we would like to have a smaller score
+ * for larger values of |n|. Therefore, in R, long R, and long C,
+ * the negative of nSize will be returned.
+ **/
+int pivotScore(number n, const ring r)
+{
+  int s = n_Size(n, r->cf);
+  if (rField_is_long_C(r) ||
+      rField_is_long_R(r) ||
+      rField_is_R(r))
+    return -s;
+  else
+    return s;
+}
+
+/**
+ * This code computes a score for each non-zero matrix entry in
+ * aMat[r1..r2, c1..c2]. If all entries are zero, false is returned,
+ * otherwise true. In the latter case, the minimum of all scores
+ * is sought, and the row and column indices of the corresponding
+ * matrix entry are stored in bestR and bestC.
+ **/
+bool pivot(const matrix aMat, const int r1, const int r2, const int c1,
+           const int c2, int* bestR, int* bestC, const ring R)
+{
+  int bestScore; int score; bool foundBestScore = false; poly matEntry;
+
+  for (int c = c1; c <= c2; c++)
+  {
+    for (int r = r1; r <= r2; r++)
+    {
+      matEntry = MATELEM(aMat, r, c);
+      if (matEntry != NULL)
+      {
+        score = pivotScore(pGetCoeff(matEntry), R);
+        if ((!foundBestScore) || (score < bestScore))
+        {
+          bestScore = score;
+          *bestR = r;
+          *bestC = c;
+        }
+        foundBestScore = true;
+      }
+    }
+  }
+
+  return foundBestScore;
+}
+
+bool unitMatrix(const int n, matrix &unitMat, const ring R)
+{
+  if (n < 1) return false;
+  unitMat = mpNew(n, n);
+  for (int r = 1; r <= n; r++) MATELEM(unitMat, r, r) = p_One(R);
+  return true;
+}
+
+void luDecomp(const matrix aMat, matrix &pMat, matrix &lMat, matrix &uMat,
+              const ring R)
+{
+  int rr = aMat->rows();
+  int cc = aMat->cols();
+  pMat = mpNew(rr, rr);
+  uMat = mp_Copy(aMat,R); /* copy aMat into uMat: */
+
+  /* we use an int array to store all row permutations;
+     note that we only make use of the entries [1..rr] */
+  int* permut = new int[rr + 1];
+  for (int i = 1; i <= rr; i++) permut[i] = i;
+
+  /* fill lMat with the (rr x rr) unit matrix */
+  unitMatrix(rr, lMat,R);
+
+  int bestR; int bestC; int intSwap; poly pSwap; int cOffset = 0;
+  for (int r = 1; r < rr; r++)
+  {
+    if (r > cc) break;
+    while ((r + cOffset <= cc) &&
+           (!pivot(uMat, r, rr, r + cOffset, r + cOffset, &bestR, &bestC, R)))
+      cOffset++;
+    if (r + cOffset <= cc)
+    {
+      /* swap rows with indices r and bestR in permut */
+      intSwap = permut[r];
+      permut[r] = permut[bestR];
+      permut[bestR] = intSwap;
+
+      /* swap rows with indices r and bestR in uMat;
+         it is sufficient to do this for columns >= r + cOffset*/
+      for (int c = r + cOffset; c <= cc; c++)
+      {
+        pSwap = MATELEM(uMat, r, c);
+        MATELEM(uMat, r, c) = MATELEM(uMat, bestR, c);
+        MATELEM(uMat, bestR, c) = pSwap;
+      }
+
+      /* swap rows with indices r and bestR in lMat;
+         we must do this only for columns < r */
+      for (int c = 1; c < r; c++)
+      {
+        pSwap = MATELEM(lMat, r, c);
+        MATELEM(lMat, r, c) = MATELEM(lMat, bestR, c);
+        MATELEM(lMat, bestR, c) = pSwap;
+      }
+
+      /* perform next Gauss elimination step, i.e., below the
+         row with index r;
+         we need to adjust lMat and uMat;
+         we are certain that the matrix entry at [r, r + cOffset]
+         is non-zero: */
+      number pivotElement = pGetCoeff(MATELEM(uMat, r, r + cOffset));
+      poly p;
+      for (int rGauss = r + 1; rGauss <= rr; rGauss++)
+      {
+        p = MATELEM(uMat, rGauss, r + cOffset);
+        if (p != NULL)
+        {
+          number n = n_Div(pGetCoeff(p), pivotElement, R->cf);
+          n_Normalize(n,R->cf);
+
+          /* filling lMat;
+             old entry was zero, so no need to call pDelete(.) */
+          MATELEM(lMat, rGauss, r) = p_NSet(n_Copy(n,R->cf),R);
+
+          /* adjusting uMat: */
+          MATELEM(uMat, rGauss, r + cOffset) = NULL; p_Delete(&p,R);
+          n = n_InpNeg(n,R->cf);
+          for (int cGauss = r + cOffset + 1; cGauss <= cc; cGauss++)
+          {
+            MATELEM(uMat, rGauss, cGauss)
+              = p_Add_q(MATELEM(uMat, rGauss, cGauss),
+                     pp_Mult_nn(MATELEM(uMat, r, cGauss), n, R), R);
+            p_Normalize(MATELEM(uMat, rGauss, cGauss),R);
+          }
+
+          n_Delete(&n,R->cf); /* clean up n */
+        }
+      }
+    }
+  }
+
+  /* building the permutation matrix from 'permut' */
+  for (int r = 1; r <= rr; r++)
+    MATELEM(pMat, r, permut[r]) = p_One(R);
+  delete[] permut;
+
+  return;
+}
+
+/**
+ * This code first computes the LU-decomposition of aMat,
+ * and then calls the method for inverting a matrix which
+ * is given by its LU-decomposition.
+ **/
+bool luInverse(const matrix aMat, matrix &iMat, const ring R)
+{ /* aMat is guaranteed to be an (n x n)-matrix */
+  matrix pMat;
+  matrix lMat;
+  matrix uMat;
+  luDecomp(aMat, pMat, lMat, uMat, R);
+  bool result = luInverseFromLUDecomp(pMat, lMat, uMat, iMat, R);
+
+  /* clean-up */
+  id_Delete((ideal*)&pMat,R);
+  id_Delete((ideal*)&lMat,R);
+  id_Delete((ideal*)&uMat,R);
+
+  return result;
+}
+
+/* Assumes that aMat is already in row echelon form */
+int rankFromRowEchelonForm(const matrix aMat)
+{
+  int rank = 0;
+  int rr = aMat->rows(); int cc = aMat->cols();
+  int r = 1; int c = 1;
+  while ((r <= rr) && (c <= cc))
+  {
+    if (MATELEM(aMat, r, c) == NULL) c++;
+    else { rank++; r++; }
+  }
+  return rank;
+}
+
+int luRank(const matrix aMat, const bool isRowEchelon, const ring R)
+{
+  if (isRowEchelon) return rankFromRowEchelonForm(aMat);
+  else
+  { /* compute the LU-decomposition and read off the rank from
+       the upper triangular matrix of that decomposition */
+    matrix pMat;
+    matrix lMat;
+    matrix uMat;
+    luDecomp(aMat, pMat, lMat, uMat,R);
+    int result = rankFromRowEchelonForm(uMat);
+
+    /* clean-up */
+    id_Delete((ideal*)&pMat,R);
+    id_Delete((ideal*)&lMat,R);
+    id_Delete((ideal*)&uMat,R);
+
+    return result;
+  }
+}
+
+bool upperRightTriangleInverse(const matrix uMat, matrix &iMat,
+                               bool diagonalIsOne, const ring R)
+{
+  int d = uMat->rows();
+  poly p; poly q;
+
+  /* check whether uMat is invertible */
+  bool invertible = diagonalIsOne;
+  if (!invertible)
+  {
+    invertible = true;
+    for (int r = 1; r <= d; r++)
+    {
+      if (MATELEM(uMat, r, r) == NULL)
+      {
+        invertible = false;
+        break;
+      }
+    }
+  }
+
+  if (invertible)
+  {
+    iMat = mpNew(d, d);
+    for (int r = d; r >= 1; r--)
+    {
+      if (diagonalIsOne)
+        MATELEM(iMat, r, r) = p_One(R);
+      else
+        MATELEM(iMat, r, r) = p_NSet(n_Invers(p_GetCoeff(MATELEM(uMat, r, r),R),R->cf),R);
+      for (int c = r + 1; c <= d; c++)
+      {
+        p = NULL;
+        for (int k = r + 1; k <= c; k++)
+        {
+          q = pp_Mult_qq(MATELEM(uMat, r, k), MATELEM(iMat, k, c),R);
+          p = p_Add_q(p, q,R);
+        }
+        p = p_Neg(p,R);
+        p = p_Mult_q(p, p_Copy(MATELEM(iMat, r, r),R),R);
+        p_Normalize(p,R);
+        MATELEM(iMat, r, c) = p;
+      }
+    }
+  }
+
+  return invertible;
+}
+
+bool lowerLeftTriangleInverse(const matrix lMat, matrix &iMat,
+                              bool diagonalIsOne)
+{
+  int d = lMat->rows(); poly p; poly q;
+
+  /* check whether lMat is invertible */
+  bool invertible = diagonalIsOne;
+  if (!invertible)
+  {
+    invertible = true;
+    for (int r = 1; r <= d; r++)
+    {
+      if (MATELEM(lMat, r, r) == NULL)
+      {
+        invertible = false;
+        break;
+      }
+    }
+  }
+
+  if (invertible)
+  {
+    iMat = mpNew(d, d);
+    for (int c = d; c >= 1; c--)
+    {
+      if (diagonalIsOne)
+        MATELEM(iMat, c, c) = pOne();
+      else
+        MATELEM(iMat, c, c) = pNSet(nInvers(pGetCoeff(MATELEM(lMat, c, c))));
+      for (int r = c + 1; r <= d; r++)
+      {
+        p = NULL;
+        for (int k = c; k <= r - 1; k++)
+        {
+          q = ppMult_qq(MATELEM(lMat, r, k), MATELEM(iMat, k, c));
+          p = pAdd(p, q);
+        }
+        p = pNeg(p);
+        p = pMult(p, pCopy(MATELEM(iMat, c, c)));
+        pNormalize(p);
+        MATELEM(iMat, r, c) = p;
+      }
+    }
+  }
+
+  return invertible;
+}
+
+/**
+ * This code computes the inverse by inverting lMat and uMat, and
+ * then performing two matrix multiplications.
+ **/
+bool luInverseFromLUDecomp(const matrix pMat, const matrix lMat,
+                           const matrix uMat, matrix &iMat, const ring R)
+{ /* uMat is guaranteed to be quadratic */
+  //int d = uMat->rows();
+
+  matrix lMatInverse; /* for storing the inverse of lMat;
+                         this inversion will always work                */
+  matrix uMatInverse; /* for storing the inverse of uMat, if invertible */
+
+  bool result = upperRightTriangleInverse(uMat, uMatInverse, false);
+  if (result)
+  {
+    /* next will always work, since lMat is known to have all diagonal
+       entries equal to 1 */
+    lowerLeftTriangleInverse(lMat, lMatInverse, true);
+    iMat = mp_Mult(mp_Mult(uMatInverse, lMatInverse,R), pMat,R);
+
+    /* clean-up */
+    idDelete((ideal*)&lMatInverse);
+    idDelete((ideal*)&uMatInverse);
+  }
+
+  return result;
+}
+
+bool luSolveViaLUDecomp(const matrix pMat, const matrix lMat,
+                        const matrix uMat, const matrix bVec,
+                        matrix &xVec, matrix &H)
+{
+  int m = uMat->rows(); int n = uMat->cols();
+  matrix cVec = mpNew(m, 1);  /* for storing pMat * bVec */
+  matrix yVec = mpNew(m, 1);  /* for storing the unique solution of
+                                 lMat * yVec = cVec */
+
+  /* compute cVec = pMat * bVec but without actual multiplications */
+  for (int r = 1; r <= m; r++)
+  {
+    for (int c = 1; c <= m; c++)
+    {
+      if (MATELEM(pMat, r, c) != NULL)
+        { MATELEM(cVec, r, 1) = pCopy(MATELEM(bVec, c, 1)); break; }
+    }
+  }
+
+  /* solve lMat * yVec = cVec; this will always work as lMat is invertible;
+     moreover, no divisions are needed, since lMat[i, i] = 1, for all i */
+  for (int r = 1; r <= m; r++)
+  {
+    poly p = pNeg(pCopy(MATELEM(cVec, r, 1)));
+    for (int c = 1; c < r; c++)
+      p = pAdd(p, ppMult_qq(MATELEM(lMat, r, c), MATELEM(yVec, c, 1) ));
+    MATELEM(yVec, r, 1) = pNeg(p);
+    pNormalize(MATELEM(yVec, r, 1));
+  }
+
+  /* determine whether uMat * xVec = yVec is solvable */
+  bool isSolvable = true;
+  bool isZeroRow;
+  int nonZeroRowIndex = 0 ;   // handle case that the matrix is zero
+  for (int r = m; r >= 1; r--)
+  {
+    isZeroRow = true;
+    for (int c = 1; c <= n; c++)
+      if (MATELEM(uMat, r, c) != NULL) { isZeroRow = false; break; }
+    if (isZeroRow)
+    {
+      if (MATELEM(yVec, r, 1) != NULL) { isSolvable = false; break; }
+    }
+    else { nonZeroRowIndex = r; break; }
+  }
+
+  if (isSolvable)
+  {
+    xVec = mpNew(n, 1);
+    matrix N = mpNew(n, n); int dim = 0;
+    poly p; poly q;
+    /* solve uMat * xVec = yVec and determine a basis of the solution
+       space of the homogeneous system uMat * xVec = 0;
+       We do not know in advance what the dimension (dim) of the latter
+       solution space will be. Thus, we start with the possibly too wide
+       matrix N and later copy the relevant columns of N into H. */
+    int nonZeroC  =  0 ; 
+    int lastNonZeroC = n + 1;
+
+    for (int r = nonZeroRowIndex; r >= 1; r--)
+    {
+      for (nonZeroC = 1; nonZeroC <= n; nonZeroC++)
+        if (MATELEM(uMat, r, nonZeroC) != NULL) break;
+
+      for (int w = lastNonZeroC - 1; w >= nonZeroC + 1; w--)
+      {
+        /* this loop will only be done when the given linear system has
+           more than one, i.e., infinitely many solutions */
+        dim++;
+        /* now we fill two entries of the dim-th column of N */
+        MATELEM(N, w, dim) = pNeg(pCopy(MATELEM(uMat, r, nonZeroC)));
+        MATELEM(N, nonZeroC, dim) = pCopy(MATELEM(uMat, r, w));
+      }
+      for (int d = 1; d <= dim; d++)
+      {
+        /* here we fill the entry of N at [r, d], for each valid vector
+           that we already have in N;
+           again, this will only be done when the given linear system has
+           more than one, i.e., infinitely many solutions */
+        p = NULL;
+        for (int c = nonZeroC + 1; c <= n; c++)
+          if (MATELEM(N, c, d) != NULL)
+            p = pAdd(p, ppMult_qq(MATELEM(uMat, r, c), MATELEM(N, c, d)));
+        q = pNSet(nInvers(pGetCoeff(MATELEM(uMat, r, nonZeroC))));
+        MATELEM(N, nonZeroC, d) = pMult(pNeg(p), q);
+        pNormalize(MATELEM(N, nonZeroC, d));
+      }
+      p = pNeg(pCopy(MATELEM(yVec, r, 1)));
+      for (int c = nonZeroC + 1; c <= n; c++)
+        if (MATELEM(xVec, c, 1) != NULL)
+          p = pAdd(p, ppMult_qq(MATELEM(uMat, r, c), MATELEM(xVec, c, 1)));
+      q = pNSet(nInvers(pGetCoeff(MATELEM(uMat, r, nonZeroC))));
+      MATELEM(xVec, nonZeroC, 1) = pMult(pNeg(p), q);
+      pNormalize(MATELEM(xVec, nonZeroC, 1));
+      lastNonZeroC = nonZeroC;
+    }
+    for (int w = lastNonZeroC - 1; w >= 1; w--)
+    {
+       // remaining variables are free
+       dim++;
+       MATELEM(N, w, dim) = pOne();
+    }
+
+    if (dim == 0)
+    {
+      /* that means the given linear system has exactly one solution;
+         we return as H the 1x1 matrix with entry zero */
+      H = mpNew(1, 1);
+    }
+    else
+    {
+      /* copy the first 'dim' columns of N into H */
+      H = mpNew(n, dim);
+      for (int r = 1; r <= n; r++)
+        for (int c = 1; c <= dim; c++)
+          MATELEM(H, r, c) = pCopy(MATELEM(N, r, c));
+    }
+    /* clean up N */
+    idDelete((ideal*)&N);
+  }
+  idDelete((ideal*)&cVec);
+  idDelete((ideal*)&yVec);
+
+  return isSolvable;
+}
+
+/* for debugging:
+   for printing numbers to the console
+   DELETE LATER */
+void printNumber(const number z)
+{
+  if (nIsZero(z)) printf("number = 0\n");
+  else
+  {
+    poly p = pOne();
+    pSetCoeff(p, nCopy(z));
+    pSetm(p);
+    printf("number = %s\n", pString(p));
+    pDelete(&p);
+  }
+}
+
+/* for debugging:
+   for printing matrices to the console
+   DELETE LATER */
+void printMatrix(const matrix m)
+{
+  int rr = MATROWS(m); int cc = MATCOLS(m);
+  printf("\n-------------\n");
+  for (int r = 1; r <= rr; r++)
+  {
+    for (int c = 1; c <= cc; c++)
+      printf("%s  ", pString(MATELEM(m, r, c)));
+    printf("\n");
+  }
+  printf("-------------\n");
+}
+
+/**
+ * Creates a new complex number from real and imaginary parts given
+ * by doubles.
+ *
+ * @return the new complex number
+ **/
+number complexNumber(const double r, const double i)
+{
+  gmp_complex* n= new gmp_complex(r, i);
+  return (number)n;
+}
+
+/**
+ * Returns one over the exponent-th power of ten.
+ *
+ * The method assumes that the base ring is the complex numbers.
+ *
+ * return one over the exponent-th power of 10
+ **/
+number tenToTheMinus(
+       const int exponent  /**< [in]  the exponent for 1/10 */
+                    )
+{
+  number ten = complexNumber(10.0, 0.0);
+  number result = complexNumber(1.0, 0.0);
+  number tmp;
+  /* compute 10^{-exponent} inside result by subsequent divisions by 10 */
+  for (int i = 1; i <= exponent; i++)
+  {
+    tmp = nDiv(result, ten);
+    nDelete(&result);
+    result = tmp;
+  }
+  nDelete(&ten);
+  return result;
+}
+
+/* for debugging:
+   for printing numbers to the console
+   DELETE LATER */
+void printSolutions(const int a, const int b, const int c)
+{
+  printf("\n------\n");
+  /* build the polynomial a*x^2 + b*x + c: */
+  poly p = NULL; poly q = NULL; poly r = NULL;
+  if (a != 0)
+  { p = pOne(); pSetExp(p, 1, 2); pSetm(p); pSetCoeff(p, nInit(a)); }
+  if (b != 0)
+  { q = pOne(); pSetExp(q, 1, 1); pSetm(q); pSetCoeff(q, nInit(b)); }
+  if (c != 0)
+  { r = pOne(); pSetCoeff(r, nInit(c)); }
+  p = pAdd(p, q); p = pAdd(p, r);
+  printf("poly = %s\n", pString(p));
+  number tol = tenToTheMinus(20);
+  number s1; number s2; int nSol = quadraticSolve(p, s1, s2, tol);
+  nDelete(&tol);
+  printf("solution code = %d\n", nSol);
+  if ((1 <= nSol) && (nSol <= 3))
+  {
+    if (nSol != 3) { printNumber(s1); nDelete(&s1); }
+    else { printNumber(s1); nDelete(&s1); printNumber(s2); nDelete(&s2); }
+  }
+  printf("------\n");
+  pDelete(&p);
+}
+
+bool realSqrt(const number n, const number tolerance, number &root)
+{
+  if (!nGreaterZero(n)) return false;
+  if (nIsZero(n)) return nInit(0);
+
+  number oneHalf = complexNumber(0.5, 0.0);
+  number nHalf   = nMult(n, oneHalf);
+  root           = nCopy(n);
+  number nOld    = complexNumber(10.0, 0.0);
+  number nDiff   = nCopy(nOld);
+
+  while (nGreater(nDiff, tolerance))
+  {
+    nDelete(&nOld);
+    nOld = root;
+    root = nAdd(nMult(oneHalf, nOld), nDiv(nHalf, nOld));
+    nDelete(&nDiff);
+    nDiff = nSub(nOld, root);
+    if (!nGreaterZero(nDiff)) nDiff = nInpNeg(nDiff);
+  }
+
+  nDelete(&nOld); nDelete(&nDiff); nDelete(&oneHalf); nDelete(&nHalf);
+  return true;
+}
+
+int quadraticSolve(const poly p, number &s1, number &s2,
+                   const number tolerance)
+{
+  poly q = pCopy(p);
+  int result;
+
+  if (q == NULL) result = -1;
+  else
+  {
+    int degree = pGetExp(q, 1);
+    if (degree == 0) result = 0;   /* constant polynomial <> 0 */
+    else
+    {
+      number c2 = nInit(0);   /* coefficient of var(1)^2 */
+      number c1 = nInit(0);   /* coefficient of var(1)^1 */
+      number c0 = nInit(0);   /* coefficient of var(1)^0 */
+      if (pGetExp(q, 1) == 2)
+      { nDelete(&c2); c2 = nCopy(pGetCoeff(q)); q = q->next; }
+      if ((q != NULL) && (pGetExp(q, 1) == 1))
+      { nDelete(&c1); c1 = nCopy(pGetCoeff(q)); q = q->next; }
+      if ((q != NULL) && (pGetExp(q, 1) == 0))
+      { nDelete(&c0); c0 = nCopy(pGetCoeff(q)); q = q->next; }
+
+      if (degree == 1)
+      {
+        c0 = nInpNeg(c0);
+        s1 = nDiv(c0, c1);
+        result = 1;
+      }
+      else
+      {
+        number tmp = nMult(c0, c2);
+        number tmp2 = nAdd(tmp, tmp); nDelete(&tmp);
+        number tmp4 = nAdd(tmp2, tmp2); nDelete(&tmp2);
+        number discr = nSub(nMult(c1, c1), tmp4); nDelete(&tmp4);
+        if (nIsZero(discr))
+        {
+          tmp = nAdd(c2, c2);
+          s1 = nDiv(c1, tmp); nDelete(&tmp);
+          s1 = nInpNeg(s1);
+          result = 2;
+        }
+        else if (nGreaterZero(discr))
+        {
+          realSqrt(discr, tolerance, tmp);   /* sqrt of the discriminant */
+          tmp2 = nSub(tmp, c1);
+          tmp4 = nAdd(c2, c2);
+          s1 = nDiv(tmp2, tmp4); nDelete(&tmp2);
+          tmp = nInpNeg(tmp);
+          tmp2 = nSub(tmp, c1); nDelete(&tmp);
+          s2 = nDiv(tmp2, tmp4); nDelete(&tmp2); nDelete(&tmp4);
+          result = 3;
+        }
+        else
+        {
+          discr = nInpNeg(discr);
+          realSqrt(discr, tolerance, tmp);   /* sqrt of |discriminant| */
+          tmp2 = nAdd(c2, c2);
+          tmp4 = nDiv(tmp, tmp2); nDelete(&tmp);
+          tmp = nDiv(c1, tmp2); nDelete(&tmp2);
+          tmp = nInpNeg(tmp);
+          s1 = (number)new gmp_complex(((gmp_complex*)tmp)->real(),
+                                       ((gmp_complex*)tmp4)->real());
+          tmp4 = nInpNeg(tmp4);
+          s2 = (number)new gmp_complex(((gmp_complex*)tmp)->real(),
+                                       ((gmp_complex*)tmp4)->real());
+          nDelete(&tmp); nDelete(&tmp4);
+          result = 3;
+        }
+        nDelete(&discr);
+      }
+      nDelete(&c0); nDelete(&c1); nDelete(&c2);
+    }
+  }
+  pDelete(&q);
+
+  return result;
+}
+
+number euclideanNormSquared(const matrix aMat)
+{
+  int rr = MATROWS(aMat);
+  number result = nInit(0);
+  number tmp1; number tmp2;
+  for (int r = 1; r <= rr; r++)
+    if (MATELEM(aMat, r, 1) != NULL)
+    {
+      tmp1 = nMult(pGetCoeff(MATELEM(aMat, r, 1)),
+                   pGetCoeff(MATELEM(aMat, r, 1)));
+      tmp2 = nAdd(result, tmp1); nDelete(&result); nDelete(&tmp1);
+      result = tmp2;
+    }
+  return result;
+}
+
+/* Returns a new number which is the absolute value of the coefficient
+   of the given polynomial.
+ *
+ * The method assumes that the coefficient has imaginary part zero. */
+number absValue(poly p)
+{
+  if (p == NULL) return nInit(0);
+  number result = nCopy(pGetCoeff(p));
+  if (!nGreaterZero(result)) result = nInpNeg(result);
+  return result;
+}
+
+bool subMatrix(const matrix aMat, const int rowIndex1, const int rowIndex2,
+               const int colIndex1, const int colIndex2, matrix &subMat)
+{
+  if (rowIndex1 > rowIndex2) return false;
+  if (colIndex1 > colIndex2) return false;
+  int rr = rowIndex2 - rowIndex1 + 1;
+  int cc = colIndex2 - colIndex1 + 1;
+  subMat = mpNew(rr, cc);
+  for (int r = 1; r <= rr; r++)
+    for (int c = 1; c <= cc; c++)
+      MATELEM(subMat, r, c) =
+        pCopy(MATELEM(aMat, rowIndex1 + r - 1, colIndex1 + c - 1));
+  return true;
+}
+
+bool charPoly(const matrix aMat, poly &charPoly)
+{
+  if (MATROWS(aMat) != 2) return false;
+  if (MATCOLS(aMat) != 2) return false;
+  number b = nInit(0); number t;
+  if (MATELEM(aMat, 1, 1) != NULL)
+  { t = nAdd(b, pGetCoeff(MATELEM(aMat, 1, 1))); nDelete(&b); b = t;}
+  if (MATELEM(aMat, 2, 2) != NULL)
+  { t = nAdd(b, pGetCoeff(MATELEM(aMat, 2, 2))); nDelete(&b); b = t;}
+  b = nInpNeg(b);
+  number t1;
+  if ((MATELEM(aMat, 1, 1) != NULL) && (MATELEM(aMat, 2, 2) != NULL))
+    t1 = nMult(pGetCoeff(MATELEM(aMat, 1, 1)),
+               pGetCoeff(MATELEM(aMat, 2, 2)));
+  else t1 = nInit(0);
+  number t2;
+  if ((MATELEM(aMat, 1, 2) != NULL) && (MATELEM(aMat, 2, 1) != NULL))
+    t2 = nMult(pGetCoeff(MATELEM(aMat, 1, 2)),
+               pGetCoeff(MATELEM(aMat, 2, 1)));
+  else t2 = nInit(0);
+  number c = nSub(t1, t2); nDelete(&t1); nDelete(&t2);
+  poly p = pOne(); pSetExp(p, 1, 2); pSetm(p);
+  poly q = NULL;
+  if (!nIsZero(b))
+  { q = pOne(); pSetExp(q, 1, 1); pSetm(q); pSetCoeff(q, b); }
+  poly r = NULL;
+  if (!nIsZero(c))
+  { r = pOne(); pSetCoeff(r, c); }
+  p = pAdd(p, q); p = pAdd(p, r);
+  charPoly = p;
+  return true;
+}
+
+void swapRows(int row1, int row2, matrix& aMat)
+{
+  poly p;
+  int cc = MATCOLS(aMat);
+  for (int c = 1; c <= cc; c++)
+  {
+    p = MATELEM(aMat, row1, c);
+    MATELEM(aMat, row1, c) = MATELEM(aMat, row2, c);
+    MATELEM(aMat, row2, c) = p;
+  }
+}
+
+void swapColumns(int column1, int column2,  matrix& aMat)
+{
+  poly p;
+  int rr = MATROWS(aMat);
+  for (int r = 1; r <= rr; r++)
+  {
+    p = MATELEM(aMat, r, column1);
+    MATELEM(aMat, r, column1) = MATELEM(aMat, r, column2);
+    MATELEM(aMat, r, column2) = p;
+  }
+}
+
+void matrixBlock(const matrix aMat, const matrix bMat, matrix &block)
+{
+  int rowsA = MATROWS(aMat);
+  int rowsB = MATROWS(bMat);
+  int n = rowsA + rowsB;
+  block = mpNew(n, n);
+  for (int i = 1; i <= rowsA; i++)
+    for (int j = 1; j <= rowsA; j++)
+      MATELEM(block, i, j) = pCopy(MATELEM(aMat, i, j));
+  for (int i = 1; i <= rowsB; i++)
+    for (int j = 1; j <= rowsB; j++)
+      MATELEM(block, i + rowsA, j + rowsA) = pCopy(MATELEM(bMat, i, j));
+}
+
+/**
+ * Computes information related to one householder transformation step for
+ * constructing the Hessenberg form of a given non-derogative matrix.
+ *
+ * The method assumes that all matrix entries are numbers coming from some
+ * subfield of the reals. And that v has a non-zero first entry v_1 and a
+ * second non-zero entry somewhere else.
+ * Given such a vector v, it computes a number r (which will be the return
+ * value of the method), a vector u and a matrix P such that:
+ * 1) P * v = r * e_1,
+ * 2) P = E - u * u^T,
+ * 3) P = P^{-1}.
+ * Note that enforcing norm(u) = sqrt(2), which is done in the algorithm,
+ * guarantees property 3). This can be checked by expanding P^2 using
+ * property 2).
+ *
+ * @return the number r
+ **/
+number hessenbergStep(
+      const matrix vVec,     /**< [in]  the input vector v */
+      matrix &uVec,          /**< [out] the output vector u */
+      matrix &pMat,          /**< [out] the output matrix P */
+      const number tolerance /**< [in]  accuracy for square roots */
+                      )
+{
+  int rr = MATROWS(vVec);
+  number vNormSquared = euclideanNormSquared(vVec);
+  number vNorm; realSqrt(vNormSquared, tolerance, vNorm);
+  /* v1 is guaranteed to be non-zero: */
+  number v1 = pGetCoeff(MATELEM(vVec, 1, 1));
+  bool v1Sign = true; if (nGreaterZero(v1)) v1Sign = false;
+
+  number v1Abs = nCopy(v1); if (v1Sign) v1Abs = nInpNeg(v1Abs);
+  number t1 = nDiv(v1Abs, vNorm);
+  number one = nInit(1);
+  number t2 = nAdd(t1, one); nDelete(&t1);
+  number denominator; realSqrt(t2, tolerance, denominator); nDelete(&t2);
+  uVec = mpNew(rr, 1);
+  t1 = nDiv(v1Abs, vNorm);
+  t2 = nAdd(t1, one); nDelete(&t1);
+  t1 = nDiv(t2, denominator); nDelete(&t2);
+  MATELEM(uVec, 1, 1) = pOne();
+  pSetCoeff(MATELEM(uVec, 1, 1), t1);   /* we know that t1 != 0 */
+  for (int r = 2; r <= rr; r++)
+  {
+    if (MATELEM(vVec, r, 1) != NULL)
+      t1 = nCopy(pGetCoeff(MATELEM(vVec, r, 1)));
+    else t1 = nInit(0);
+    if (v1Sign) t1 = nInpNeg(t1);
+    t2 = nDiv(t1, vNorm); nDelete(&t1);
+    t1 = nDiv(t2, denominator); nDelete(&t2);
+    if (!nIsZero(t1))
+    {
+      MATELEM(uVec, r, 1) = pOne();
+      pSetCoeff(MATELEM(uVec, r, 1), t1);
+    }
+    else nDelete(&t1);
+  }
+  nDelete(&denominator);
+
+  /* finished building vector u; now turn to pMat */
+  pMat = mpNew(rr, rr);
+  /* we set P := E - u * u^T, as desired */
+  for (int r = 1; r <= rr; r++)
+    for (int c = 1; c <= rr; c++)
+    {
+      if ((MATELEM(uVec, r, 1) != NULL) && (MATELEM(uVec, c, 1) != NULL))
+        t1 = nMult(pGetCoeff(MATELEM(uVec, r, 1)),
+                   pGetCoeff(MATELEM(uVec, c, 1)));
+      else t1 = nInit(0);
+      if (r == c) { t2 = nSub(one, t1); nDelete(&t1); }
+      else          t2 = nInpNeg(t1);
+      if (!nIsZero(t2))
+      {
+        MATELEM(pMat, r, c) = pOne();
+        pSetCoeff(MATELEM(pMat, r, c), t2);
+      }
+      else nDelete(&t2);
+    }
+  nDelete(&one);
+  /* finished building pMat; now compute the return value */
+  t1 = vNormSquared; if (v1Sign) t1 = nInpNeg(t1);
+  t2 = nMult(v1, vNorm);
+  number t3 = nAdd(t1, t2); nDelete(&t1); nDelete(&t2);
+  t1 = nAdd(v1Abs, vNorm); nDelete(&v1Abs); nDelete(&vNorm);
+  t2 = nDiv(t3, t1); nDelete(&t1); nDelete(&t3);
+  t2 = nInpNeg(t2);
+  return t2;
+}
+
+void hessenberg(const matrix aMat, matrix &pMat, matrix &hessenbergMat,
+                const number tolerance, const ring R)
+{
+  int n = MATROWS(aMat);
+  unitMatrix(n, pMat);
+  subMatrix(aMat, 1, n, 1, n, hessenbergMat);
+  for (int c = 1; c <= n; c++)
+  {
+    /* find one or two non-zero entries in the current column */
+    int r1 = 0; int r2 = 0;
+    for (int r = c + 1; r <= n; r++)
+      if (MATELEM(hessenbergMat, r, c) != NULL)
+      {
+        if      (r1 == 0)   r1 = r;
+        else if (r2 == 0) { r2 = r; break; }
+      }
+    if (r1 != 0)
+    { /* At least one entry in the current column is non-zero. */
+      if (r1 != c + 1)
+      { /* swap rows to bring non-zero element to row with index c + 1 */
+        swapRows(r1, c + 1, hessenbergMat);
+        /* now also swap columns to reflect action of permutation
+           from the right-hand side */
+        swapColumns(r1, c + 1, hessenbergMat);
+        /* include action of permutation also in pMat */
+        swapRows(r1, c + 1, pMat);
+      }
+      if (r2 != 0)
+      { /* There is at least one more non-zero element in the current
+           column. So let us perform a hessenberg step in order to make
+           all additional non-zero elements zero. */
+        matrix v; subMatrix(hessenbergMat, c + 1, n, c, c, v);
+        matrix u; matrix pTmp;
+        number r = hessenbergStep(v, u, pTmp, tolerance);
+        idDelete((ideal*)&v); idDelete((ideal*)&u); nDelete(&r);
+        /* pTmp just acts on the lower right block of hessenbergMat;
+           i.e., it needs to be extended by a unit matrix block at the top
+           left in order to define a whole transformation matrix;
+           this code may be optimized */
+        unitMatrix(c, u);
+        matrix pTmpFull; matrixBlock(u, pTmp, pTmpFull);
+        idDelete((ideal*)&u); idDelete((ideal*)&pTmp);
+        /* now include pTmpFull in pMat (by letting it act from the left) */
+        pTmp = mp_Mult(pTmpFull, pMat,R); idDelete((ideal*)&pMat);
+        pMat = pTmp;
+        /* now let pTmpFull act on hessenbergMat from the left and from the
+           right (note that pTmpFull is self-inverse) */
+        pTmp = mp_Mult(pTmpFull, hessenbergMat,R);
+        idDelete((ideal*)&hessenbergMat);
+        hessenbergMat = mp_Mult(pTmp, pTmpFull, R);
+        idDelete((ideal*)&pTmp); idDelete((ideal*)&pTmpFull);
+        /* as there may be inaccuracy, we erase those entries of hessenbergMat
+           which must have become zero by the last transformation */
+        for (int r = c + 2; r <= n; r++)
+          pDelete(&MATELEM(hessenbergMat, r, c));
+      }
+    }
+  }
+}
+
+/**
+ * Performs one transformation step on the given matrix H as part of
+ * the gouverning QR double shift algorith.
+ * The method will change the given matrix H side-effect-wise. The resulting
+ * matrix H' will be in Hessenberg form.
+ * The iteration index is needed, since for the 11th and 21st iteration,
+ * the transformation step is different from the usual step, to avoid
+ * convergence problems of the gouverning QR double shift process (who is
+ * also the only caller of this method).
+ **/
+void mpTrafo(
+      matrix &H,             /**< [in/out]  the matrix to be transformed */
+      int it,                /**< [in]      iteration index */
+      const number tolerance,/**< [in]      accuracy for square roots */
+      const ring R
+            )
+{
+  int n = MATROWS(H);
+  number trace; number det; number tmp1; number tmp2; number tmp3;
+
+  if ((it != 11) && (it != 21)) /* the standard case */
+  {
+    /* in this case 'trace' will really be the trace of the lowermost
+       (2x2) block of hMat */
+    trace = nInit(0);
+    det = nInit(0);
+    if (MATELEM(H, n - 1, n - 1) != NULL)
+    {
+      tmp1 = nAdd(trace, pGetCoeff(MATELEM(H, n - 1, n - 1)));
+      nDelete(&trace);
+      trace = tmp1;
+    }
+    if (MATELEM(H, n, n) != NULL)
+    {
+      tmp1 = nAdd(trace, pGetCoeff(MATELEM(H, n, n)));
+      nDelete(&trace);
+      trace = tmp1;
+    }
+    /* likewise 'det' will really be the determinante of the lowermost
+       (2x2) block of hMat */
+    if ((MATELEM(H, n - 1, n - 1 ) != NULL) && (MATELEM(H, n, n) != NULL))
+    {
+      tmp1 = nMult(pGetCoeff(MATELEM(H, n - 1, n - 1)),
+                   pGetCoeff(MATELEM(H, n, n)));
+      tmp2 = nAdd(tmp1, det); nDelete(&tmp1); nDelete(&det);
+      det = tmp2;
+    }
+    if ((MATELEM(H, n - 1, n) != NULL) && (MATELEM(H, n, n - 1) != NULL))
+    {
+      tmp1 = nMult(pGetCoeff(MATELEM(H, n - 1, n)),
+                   pGetCoeff(MATELEM(H, n, n - 1)));
+      tmp2 = nSub(det, tmp1); nDelete(&tmp1); nDelete(&det);
+      det = tmp2;
+    }
+  }
+  else
+  {
+    /* for it = 11 or it = 21, we use special formulae to avoid convergence
+       problems of the gouverning QR double shift algorithm (who is the only
+       caller of this method) */
+    /* trace = 3/2 * (|hMat[n, n-1]| + |hMat[n-1, n-2]|) */
+    tmp1 = nInit(0);
+    if (MATELEM(H, n, n - 1) != NULL)
+    { nDelete(&tmp1); tmp1 = nCopy(pGetCoeff(MATELEM(H, n, n - 1))); }
+    if (!nGreaterZero(tmp1)) tmp1 = nInpNeg(tmp1);
+    tmp2 = nInit(0);
+    if (MATELEM(H, n - 1, n - 2) != NULL)
+    { nDelete(&tmp2); tmp2 = nCopy(pGetCoeff(MATELEM(H, n - 1, n - 2))); }
+    if (!nGreaterZero(tmp2)) tmp2 = nInpNeg(tmp2);
+    tmp3 = nAdd(tmp1, tmp2); nDelete(&tmp1); nDelete(&tmp2);
+    tmp1 = nInit(3); tmp2 = nInit(2);
+    trace = nDiv(tmp1, tmp2); nDelete(&tmp1); nDelete(&tmp2);
+    tmp1 = nMult(tmp3, trace); nDelete(&trace);
+    trace = tmp1;
+    /* det = (|hMat[n, n-1]| + |hMat[n-1, n-2]|)^2 */
+    det = nMult(tmp3, tmp3); nDelete(&tmp3);
+  }
+  matrix c = mpNew(n, 1);
+  trace = nInpNeg(trace);
+  MATELEM(c,1,1) = pAdd(pAdd(pAdd(ppMult_qq(MATELEM(H,1,1), MATELEM(H,1,1)),
+                                  ppMult_qq(MATELEM(H,1,2), MATELEM(H,2,1))),
+                             ppMult_nn(MATELEM(H,1,1), trace)),
+                        pMult_nn(pOne(), det));
+  MATELEM(c,2,1) = pAdd(pMult(pCopy(MATELEM(H,2,1)),
+                              pAdd(pCopy(MATELEM(H,1,1)),
+                                   pCopy(MATELEM(H,2,2)))),
+                        ppMult_nn(MATELEM(H,2,1), trace));
+  MATELEM(c,3,1) = ppMult_qq(MATELEM(H,2,1), MATELEM(H,3,2));
+  nDelete(&trace); nDelete(&det);
+
+  /* for applying hessenbergStep, we need to make sure that c[1, 1] is
+     not zero */
+  if ((MATELEM(c,1,1) != NULL) &&
+      ((MATELEM(c,2,1) != NULL) || (MATELEM(c,3,1) != NULL)))
+  {
+    matrix uVec; matrix hMat;
+    tmp1 = hessenbergStep(c, uVec, hMat, tolerance); nDelete(&tmp1);
+    /* now replace H by hMat * H * hMat: */
+    matrix wMat = mp_Mult(hMat, H,R); idDelete((ideal*)&H);
+    matrix H1 = mp_Mult(wMat, hMat,R);
+    idDelete((ideal*)&wMat); idDelete((ideal*)&hMat);
+    /* now need to re-establish Hessenberg form of H1 and put it in H */
+    hessenberg(H1, wMat, H, tolerance,R);
+    idDelete((ideal*)&wMat); idDelete((ideal*)&H1);
+  }
+  else if ((MATELEM(c,1,1) == NULL) && (MATELEM(c,2,1) != NULL))
+  {
+    swapRows(1, 2, H);
+    swapColumns(1, 2, H);
+  }
+  else if ((MATELEM(c,1,1) == NULL) && (MATELEM(c,3,1) != NULL))
+  {
+    swapRows(1, 3, H);
+    swapColumns(1, 3, H);
+  }
+  else
+  { /* c is the zero vector or a multiple of e_1;
+       no hessenbergStep needed */ }
+}
+
+/* helper for qrDoubleShift */
+bool qrDS(
+       const int /*n*/,
+       matrix* queue,
+       int& queueL,
+       number* eigenValues,
+       int& eigenValuesL,
+       const number tol1,
+       const number tol2,
+       const ring R
+         )
+{
+  bool deflationFound = true;
+  /* we loop until the working queue is empty,
+     provided we always find deflation */
+  while (deflationFound && (queueL > 0))
+  {
+    /* take out last queue entry */
+    matrix currentMat = queue[queueL - 1]; queueL--;
+    int m = MATROWS(currentMat);
+    if (m == 1)
+    {
+      number newEigenvalue;
+      /* the entry at [1, 1] is the eigenvalue */
+      if (MATELEM(currentMat, 1, 1) == NULL) newEigenvalue = nInit(0);
+      else newEigenvalue = nCopy(pGetCoeff(MATELEM(currentMat, 1, 1)));
+      eigenValues[eigenValuesL++] = newEigenvalue;
+    }
+    else if (m == 2)
+    {
+      /* there are two eigenvalues which come as zeros of the characteristic
+         polynomial */
+      poly p; charPoly(currentMat, p);
+      number s1; number s2;
+      int nSol = quadraticSolve(p, s1, s2, tol2); pDelete(&p);
+      assume(nSol >= 2);
+      eigenValues[eigenValuesL++] = s1;
+      /* if nSol = 2, then s1 is a double zero, and s2 is invalid: */
+      if (nSol == 2) s2 = nCopy(s1);
+      eigenValues[eigenValuesL++] = s2;
+    }
+    else /* m > 2 */
+    {
+      /* bring currentMat into Hessenberg form to fasten computations: */
+      matrix mm1; matrix mm2;
+      hessenberg(currentMat, mm1, mm2, tol2,R);
+      idDelete((ideal*)&currentMat); idDelete((ideal*)&mm1);
+      currentMat = mm2;
+      int it = 1; bool doLoop = true;
+      while (doLoop && (it <= 30 * m))
+      {
+        /* search for deflation */
+        number w1; number w2;
+        number test1; number test2; bool stopCriterion = false; int k;
+        for (k = 1; k < m; k++)
+        {
+          test1 = absValue(MATELEM(currentMat, k + 1, k));
+          w1 = absValue(MATELEM(currentMat, k, k));
+          w2 = absValue(MATELEM(currentMat, k + 1, k + 1));
+          test2 = nMult(tol1, nAdd(w1, w2));
+          nDelete(&w1); nDelete(&w2);
+          if (!nGreater(test1, test2)) stopCriterion = true;
+          nDelete(&test1); nDelete(&test2);
+          if (stopCriterion) break;
+        }
+        if (k < m)   /* found deflation at position (k + 1, k) */
+        {
+          pDelete(&MATELEM(currentMat, k + 1, k)); /* make this entry zero */
+          subMatrix(currentMat, 1, k, 1, k, queue[queueL++]);
+          subMatrix(currentMat, k + 1, m, k + 1, m, queue[queueL++]);
+          doLoop = false;
+        }
+        else   /* no deflation found yet */
+        {
+          mpTrafo(currentMat, it, tol2,R);
+          it++;   /* try again */
+        }
+      }
+      if (doLoop)   /* could not find deflation for currentMat */
+      {
+        deflationFound = false;
+      }
+      idDelete((ideal*)&currentMat);
+    }
+  }
+  return deflationFound;
+}
+
+/**
+ * Tries to find the number n in the array nn[0..nnLength-1].
+ *
+ * The method assumes that the ground field is the complex numbers.
+ * n and an entry of nn will be regarded equal when the absolute
+ * value of their difference is not larger than the given tolerance.
+ * In this case, the index of the respective entry of nn is returned,
+ * otherwise -1.
+ *
+ * @return the index of n in nn (up to tolerance) or -1
+ **/
+int similar(
+       const number* nn,       /**< [in] array of numbers to look-up */
+       const int nnLength,     /**< [in] length of nn                */
+       const number n,         /**< [in] number to loop-up in nn     */
+       const number tolerance  /**< [in] tolerance for comparison    */
+           )
+{
+  int result = -1;
+  number tt = nMult(tolerance, tolerance);
+  number nr = (number)new gmp_complex(((gmp_complex*)n)->real());
+  number ni = (number)new gmp_complex(((gmp_complex*)n)->imag());
+  number rr; number ii;
+  number w1; number w2; number w3; number w4; number w5;
+  for (int i = 0; i < nnLength; i++)
+  {
+    rr = (number)new gmp_complex(((gmp_complex*)nn[i])->real());
+    ii = (number)new gmp_complex(((gmp_complex*)nn[i])->imag());
+    w1 = nSub(nr, rr); w2 = nMult(w1, w1);
+    w3 = nSub(ni, ii); w4 = nMult(w3, w3);
+    w5 = nAdd(w2, w4);
+    if (!nGreater(w5, tt)) result = i;
+    nDelete(&w1); nDelete(&w2); nDelete(&w3); nDelete(&w4);
+                nDelete(&w5); nDelete(&rr); nDelete(&ii);
+    if (result != -1) break;
+  }
+  nDelete(&tt); nDelete(&nr); nDelete(&ni);
+  return result;
+}
+
+/* This codes assumes that there are at least two variables in the current
+   base ring. No assumption is made regarding the monomial ordering. */
+void henselFactors(const int xIndex, const int yIndex, const poly h,
+                   const poly f0, const poly g0, const int d, poly &f, poly &g)
+{
+  int n = (int)p_Deg(f0,currRing);
+  int m = (int)p_Deg(g0,currRing);
+  matrix aMat = mpNew(n + m, n + m);     /* matrix A for linear system */
+  matrix pMat; matrix lMat; matrix uMat; /* for the decomposition of A */
+  f = pCopy(f0); g = pCopy(g0);          /* initially: h = f*g mod <x^1> */
+
+  /* initial step: read off coefficients of f0, and g0 */
+  poly p = f0; poly matEntry; number c;
+  while (p != NULL)
+  {
+    c = nCopy(pGetCoeff(p));
+    matEntry = pOne(); pSetCoeff(matEntry, c);
+    MATELEM(aMat, pGetExp(p, yIndex) + 1, 1) = matEntry;
+    p = pNext(p);
+  }
+  p = g0;
+  while (p != NULL)
+  {
+    c = nCopy(pGetCoeff(p));
+    matEntry = pOne(); pSetCoeff(matEntry, c);
+    MATELEM(aMat, pGetExp(p, yIndex) + 1, m + 1) = matEntry;
+    p = pNext(p);
+  }
+  /* fill the rest of A */
+  for (int row = 2; row <= n + 1; row++)
+    for (int col = 2; col <= m; col++)
+    {
+      if (col > row) break;
+      MATELEM(aMat, row, col) = pCopy(MATELEM(aMat, row - 1, col - 1));
+    }
+  for (int row = n + 2; row <= n + m; row++)
+    for (int col = row - n; col <= m; col++)
+      MATELEM(aMat, row, col) = pCopy(MATELEM(aMat, row - 1, col - 1));
+  for (int row = 2; row <= m + 1; row++)
+    for (int col = m + 2; col <= m + n; col++)
+    {
+      if (col - m > row) break;
+      MATELEM(aMat, row, col) = pCopy(MATELEM(aMat, row - 1, col - 1));
+    }
+  for (int row = m + 2; row <= n + m; row++)
+    for (int col = row; col <= m + n; col++)
+      MATELEM(aMat, row, col) = pCopy(MATELEM(aMat, row - 1, col - 1));
+
+  /* constructing the LU-decomposition of A */
+  luDecomp(aMat, pMat, lMat, uMat);
+
+  /* Before the xExp-th loop, we know that h = f*g mod <x^xExp>.
+     Afterwards the algorithm ensures      h = f*g mod <x^(xExp + 1)>.
+     Hence in the end we obtain f and g as required, i.e.,
+                                           h = f*g mod <x^(d+1)>.
+     The algorithm works by solving a (m+n)x(m+n) linear equation system
+     A*x = b with constant matrix A (as decomposed above). By theory, the
+     system is guaranteed to have a unique solution. */
+  poly fg = ppMult_qq(f, g);   /* for storing the product of f and g */
+  for (int xExp = 1; xExp <= d; xExp++)
+  {
+    matrix bVec = mpNew(n + m, 1);     /* b */
+    matrix xVec = mpNew(n + m, 1);     /* x */
+
+    p = pCopy(fg);
+    p = pAdd(pCopy(h), pNeg(p));       /* p = h - f*g */
+    /* we collect all terms in p with x-exponent = xExp and use their
+       coefficients to build the vector b */
+    int bIsZeroVector = true;
+    while (p != NULL)
+    {
+      if (pGetExp(p, xIndex) == xExp)
+      {
+        number c = nCopy(pGetCoeff(p));
+        poly matEntry = pOne(); pSetCoeff(matEntry, c);
+        MATELEM(bVec, pGetExp(p, yIndex) + 1, 1) = matEntry;
+        if (matEntry != NULL) bIsZeroVector = false;
+      }
+      pLmDelete(&p); /* destruct leading term of p and move to next term */
+    }
+    /* solve the linear equation system */
+    if (!bIsZeroVector) /* otherwise x = 0 and f, g do not change */
+    {
+      matrix notUsedMat;
+      luSolveViaLUDecomp(pMat, lMat, uMat, bVec, xVec, notUsedMat);
+      idDelete((ideal*)&notUsedMat);
+      /* update f and g by newly computed terms, and update f*g */
+      poly fNew = NULL; poly gNew = NULL;
+      for (int row = 1; row <= m; row++)
+      {
+        if (MATELEM(xVec, row, 1) != NULL)
+        {
+          p = pCopy(MATELEM(xVec, row, 1));   /* p = c                  */
+          pSetExp(p, xIndex, xExp);           /* p = c * x^xExp         */
+          pSetExp(p, yIndex, row - 1);        /* p = c * x^xExp * y^i   */
+          pSetm(p);
+          gNew = pAdd(gNew, p);
+        }
+      }
+      for (int row = m + 1; row <= m + n; row++)
+      {
+        if (MATELEM(xVec, row, 1) != NULL)
+        {
+          p = pCopy(MATELEM(xVec, row, 1));   /* p = c                  */
+          pSetExp(p, xIndex, xExp);           /* p = c * x^xExp         */
+          pSetExp(p, yIndex, row - m - 1);    /* p = c * x^xExp * y^i   */
+          pSetm(p);
+          fNew = pAdd(fNew, p);
+        }
+      }
+      fg = pAdd(fg, ppMult_qq(f, gNew));
+      fg = pAdd(fg, ppMult_qq(g, fNew));
+      fg = pAdd(fg, ppMult_qq(fNew, gNew));
+      f = pAdd(f, fNew);
+      g = pAdd(g, gNew);
+    }
+    /* clean-up loop-dependent vectors */
+    idDelete((ideal*)&bVec); idDelete((ideal*)&xVec);
+  }
+
+  /* clean-up matrices A, P, L and U, and polynomial fg */
+  idDelete((ideal*)&aMat); idDelete((ideal*)&pMat);
+  idDelete((ideal*)&lMat); idDelete((ideal*)&uMat);
+  pDelete(&fg);
+}
+
+void lduDecomp(const matrix aMat, matrix &pMat, matrix &lMat, matrix &dMat,
+               matrix &uMat, poly &l, poly &u, poly &lTimesU)
+{
+  int rr = aMat->rows();
+  int cc = aMat->cols();
+  /* we use an int array to store all row permutations;
+     note that we only make use of the entries [1..rr] */
+  int* permut = new int[rr + 1];
+  for (int i = 1; i <= rr; i++) permut[i] = i;
+  /* fill lMat and dMat with the (rr x rr) unit matrix */
+  unitMatrix(rr, lMat);
+  unitMatrix(rr, dMat);
+  uMat = mpNew(rr, cc);
+  /* copy aMat into uMat: */
+  for (int r = 1; r <= rr; r++)
+    for (int c = 1; c <= cc; c++)
+      MATELEM(uMat, r, c) = pCopy(MATELEM(aMat, r, c));
+  u = pOne(); l = pOne();
+
+  int col = 1; int row = 1;
+  while ((col <= cc) & (row < rr))
+  {
+    int pivotR; int pivotC; bool pivotValid = false;
+    while (col <= cc)
+    {
+      pivotValid = pivot(uMat, row, rr, col, col, &pivotR, &pivotC);
+      if (pivotValid)  break;
+      col++;
+    }
+    if (pivotValid)
+    {
+      if (pivotR != row)
+      {
+        swapRows(row, pivotR, uMat);
+        poly p = MATELEM(dMat, row, row);
+        MATELEM(dMat, row, row) = MATELEM(dMat, pivotR, pivotR);
+        MATELEM(dMat, pivotR, pivotR) = p;
+        swapColumns(row, pivotR, lMat);
+        swapRows(row, pivotR, lMat);
+        int temp = permut[row];
+        permut[row] = permut[pivotR]; permut[pivotR] = temp;
+      }
+      /* in gg, we compute the gcd of all non-zero elements in
+         uMat[row..rr, col];
+         the next number is the pivot and thus guaranteed to be different
+         from zero: */
+      number gg = nCopy(pGetCoeff(MATELEM(uMat, row, col))); number t;
+      for (int r = row + 1; r <= rr; r++)
+      {
+        if (MATELEM(uMat, r, col) != NULL)
+        {
+          t = gg;
+          gg = n_Gcd(t, pGetCoeff(MATELEM(uMat, r, col)),currRing->cf);
+          nDelete(&t);
+        }
+      }
+      t = nDiv(pGetCoeff(MATELEM(uMat, row, col)), gg);
+      nNormalize(t);   /* this division works without remainder */
+      if (!nIsOne(t))
+      {
+        for (int r = row; r <= rr; r++)
+          pMult_nn(MATELEM(dMat, r, r), t);
+        pMult_nn(MATELEM(lMat, row, row), t);
+      }
+      l = pMult(l, pCopy(MATELEM(lMat, row, row)));
+      u = pMult(u, pCopy(MATELEM(uMat, row, col)));
+
+      for (int r = row + 1; r <= rr; r++)
+      {
+        if (MATELEM(uMat, r, col) != NULL)
+        {
+          number g = n_Gcd(pGetCoeff(MATELEM(uMat, row, col)),
+                          pGetCoeff(MATELEM(uMat, r, col)),
+                          currRing->cf);
+          number f1 = nDiv(pGetCoeff(MATELEM(uMat, r, col)), g);
+          nNormalize(f1);   /* this division works without remainder */
+          number f2 = nDiv(pGetCoeff(MATELEM(uMat, row, col)), g);
+          nNormalize(f2);   /* this division works without remainder */
+          pDelete(&MATELEM(uMat, r, col)); MATELEM(uMat, r, col) = NULL;
+          for (int c = col + 1; c <= cc; c++)
+          {
+            poly p = MATELEM(uMat, r, c);
+            pMult_nn(p, f2);
+            poly q = pCopy(MATELEM(uMat, row, c));
+            pMult_nn(q, f1); q = pNeg(q);
+            MATELEM(uMat, r, c) = pAdd(p, q);
+          }
+          number tt = nDiv(g, gg);
+          nNormalize(tt);   /* this division works without remainder */
+          pMult_nn(MATELEM(lMat, r, r), tt); nDelete(&tt);
+          MATELEM(lMat, r, row) = pCopy(MATELEM(lMat, r, r));
+          pMult_nn(MATELEM(lMat, r, row), f1);
+          nDelete(&f1); nDelete(&f2); nDelete(&g);
+        }
+        else pMult_nn(MATELEM(lMat, r, r), t);
+      }
+      nDelete(&t); nDelete(&gg);
+      col++; row++;
+    }
+  }
+  /* one factor in the product u might be missing: */
+  if (row == rr)
+  {
+    while ((col <= cc) && (MATELEM(uMat, row, col) == NULL)) col++;
+    if (col <= cc) u = pMult(u, pCopy(MATELEM(uMat, row, col)));
+  }
+
+  /* building the permutation matrix from 'permut' and computing l */
+  pMat = mpNew(rr, rr);
+  for (int r = 1; r <= rr; r++)
+    MATELEM(pMat, r, permut[r]) = pOne();
+  delete[] permut;
+
+  lTimesU = ppMult_qq(l, u);
+}
+
+bool luSolveViaLDUDecomp(const matrix pMat, const matrix lMat,
+                         const matrix dMat, const matrix uMat,
+                         const poly l, const poly u, const poly lTimesU,
+                         const matrix bVec, matrix &xVec, matrix &H)
+{
+  int m = uMat->rows(); int n = uMat->cols();
+  matrix cVec = mpNew(m, 1);  /* for storing l * pMat * bVec */
+  matrix yVec = mpNew(m, 1);  /* for storing the unique solution of
+                                 lMat * yVec = cVec */
+
+  /* compute cVec = l * pMat * bVec but without actual matrix mult. */
+  for (int r = 1; r <= m; r++)
+  {
+    for (int c = 1; c <= m; c++)
+    {
+      if (MATELEM(pMat, r, c) != NULL)
+        { MATELEM(cVec, r, 1) = ppMult_qq(l, MATELEM(bVec, c, 1)); break; }
+    }
+  }
+
+  /* solve lMat * yVec = cVec; this will always work as lMat is invertible;
+     moreover, all divisions are guaranteed to be without remainder */
+  poly p; poly q;
+  for (int r = 1; r <= m; r++)
+  {
+    p = pNeg(pCopy(MATELEM(cVec, r, 1)));
+    for (int c = 1; c < r; c++)
+      p = pAdd(p, ppMult_qq(MATELEM(lMat, r, c), MATELEM(yVec, c, 1) ));
+    /* The following division is without remainder. */
+    q = pNSet(nInvers(pGetCoeff(MATELEM(lMat, r, r))));
+    MATELEM(yVec, r, 1) = pMult(pNeg(p), q);
+    pNormalize(MATELEM(yVec, r, 1));
+  }
+
+  /* compute u * dMat * yVec and put result into yVec */
+  for (int r = 1; r <= m; r++)
+  {
+    p = ppMult_qq(u, MATELEM(dMat, r, r));
+    MATELEM(yVec, r, 1) = pMult(p, MATELEM(yVec, r, 1));
+  }
+
+  /* determine whether uMat * xVec = yVec is solvable */
+  bool isSolvable = true;
+  bool isZeroRow; int nonZeroRowIndex;
+  for (int r = m; r >= 1; r--)
+  {
+    isZeroRow = true;
+    for (int c = 1; c <= n; c++)
+      if (MATELEM(uMat, r, c) != NULL) { isZeroRow = false; break; }
+    if (isZeroRow)
+    {
+      if (MATELEM(yVec, r, 1) != NULL) { isSolvable = false; break; }
+    }
+    else { nonZeroRowIndex = r; break; }
+  }
+
+  if (isSolvable)
+  {
+    xVec = mpNew(n, 1);
+    matrix N = mpNew(n, n); int dim = 0;
+    /* solve uMat * xVec = yVec and determine a basis of the solution
+       space of the homogeneous system uMat * xVec = 0;
+       We do not know in advance what the dimension (dim) of the latter
+       solution space will be. Thus, we start with the possibly too wide
+       matrix N and later copy the relevant columns of N into H. */
+    int nonZeroC; int lastNonZeroC = n + 1;
+    for (int r = nonZeroRowIndex; r >= 1; r--)
+    {
+      for (nonZeroC = 1; nonZeroC <= n; nonZeroC++)
+        if (MATELEM(uMat, r, nonZeroC) != NULL) break;
+      for (int w = lastNonZeroC - 1; w >= nonZeroC + 1; w--)
+      {
+        /* this loop will only be done when the given linear system has
+           more than one, i.e., infinitely many solutions */
+        dim++;
+        /* now we fill two entries of the dim-th column of N */
+        MATELEM(N, w, dim) = pNeg(pCopy(MATELEM(uMat, r, nonZeroC)));
+        MATELEM(N, nonZeroC, dim) = pCopy(MATELEM(uMat, r, w));
+      }
+      for (int d = 1; d <= dim; d++)
+      {
+        /* here we fill the entry of N at [r, d], for each valid vector
+           that we already have in N;
+           again, this will only be done when the given linear system has
+           more than one, i.e., infinitely many solutions */
+        p = NULL;
+        for (int c = nonZeroC + 1; c <= n; c++)
+          if (MATELEM(N, c, d) != NULL)
+            p = pAdd(p, ppMult_qq(MATELEM(uMat, r, c), MATELEM(N, c, d)));
+        /* The following division may be with remainder but only takes place
+           when dim > 0. */
+        q = pNSet(nInvers(pGetCoeff(MATELEM(uMat, r, nonZeroC))));
+        MATELEM(N, nonZeroC, d) = pMult(pNeg(p), q);
+        pNormalize(MATELEM(N, nonZeroC, d));
+      }
+      p = pNeg(pCopy(MATELEM(yVec, r, 1)));
+      for (int c = nonZeroC + 1; c <= n; c++)
+        if (MATELEM(xVec, c, 1) != NULL)
+          p = pAdd(p, ppMult_qq(MATELEM(uMat, r, c), MATELEM(xVec, c, 1)));
+      /* The following division is without remainder. */
+      q = pNSet(nInvers(pGetCoeff(MATELEM(uMat, r, nonZeroC))));
+      MATELEM(xVec, nonZeroC, 1) = pMult(pNeg(p), q);
+      pNormalize(MATELEM(xVec, nonZeroC, 1));
+      lastNonZeroC = nonZeroC;
+    }
+
+    /* divide xVec by l*u = lTimesU and put result in xVec */
+    number z = nInvers(pGetCoeff(lTimesU));
+    for (int c = 1; c <= n; c++)
+    {
+      pMult_nn(MATELEM(xVec, c, 1), z);
+      pNormalize(MATELEM(xVec, c, 1));
+    }
+    nDelete(&z);
+
+    if (dim == 0)
+    {
+      /* that means the given linear system has exactly one solution;
+         we return as H the 1x1 matrix with entry zero */
+      H = mpNew(1, 1);
+    }
+    else
+    {
+      /* copy the first 'dim' columns of N into H */
+      H = mpNew(n, dim);
+      for (int r = 1; r <= n; r++)
+        for (int c = 1; c <= dim; c++)
+          MATELEM(H, r, c) = pCopy(MATELEM(N, r, c));
+    }
+    /* clean up N */
+    idDelete((ideal*)&N);
+  }
+
+  idDelete((ideal*)&cVec);
+  idDelete((ideal*)&yVec);
+
+  return isSolvable;
+}
+
diff --git a/kernel/linear_algebra/linearAlgebra.h b/kernel/linear_algebra/linearAlgebra.h
new file mode 100644
index 0000000..68631c8
--- /dev/null
+++ b/kernel/linear_algebra/linearAlgebra.h
@@ -0,0 +1,582 @@
+/*****************************************************************************\
+ * Computer Algebra System SINGULAR
+\*****************************************************************************/
+/** @file lineareAlgebra.h
+ *
+ * This file provides basic linear algebra functionality.
+ *
+ * ABSTRACT: This file provides basic algorithms from linear algebra over
+ * any SINGULAR-supported field.
+ * For the time being, the procedures defined in this file expect matrices
+ * containing objects of the SINGULAR type 'number'. This means that, when
+ * 'currentRing' represents some polynomial ring K[x_1, x_2, ..., x_n], then
+ * the entries of the matrices are 'numbers' representing elements of K (and
+ * NOT 'polys' in K[x_1, x_2, ..., x_n]).
+ * This restriction may become obselete in the future.
+ *
+ * @author Frank Seelisch
+ *
+ *
+ **/
+/*****************************************************************************/
+
+#ifndef LINEAR_ALGEBRA_H
+#define LINEAR_ALGEBRA_H
+
+// include basic SINGULAR structures
+#include <kernel/structs.h>
+
+/**
+ * LU-decomposition of a given (m x n)-matrix.
+ *
+ * Given an (m x n) matrix A, the method computes its LU-decomposition,
+ * that is, it computes matrices P, L, and U such that<br>
+ * - P * A = L * U,<br>
+ * - P is an (m x m) permutation matrix, i.e., its row/columns form the
+ *   standard basis of K^m,<br>
+ * - L is an (m x m) matrix in lower triangular form with all diagonal
+ *   entries equal to 1,<br>
+ * - U is an (m x n) matrix in upper row echelon form.<br>
+ * From these conditions, it follows immediately that also A = P * L * U,
+ * since P is self-inverse.<br>
+ *
+ * The method will modify all argument matrices except aMat, so that
+ * they will finally contain the matrices P, L, and U as specified
+ * above.
+ **/
+void luDecomp(
+       const matrix aMat, /**< [in]  the initial matrix A,          */
+       matrix &pMat,      /**< [out] the row permutation matrix P   */
+       matrix &lMat,      /**< [out] the lower triangular matrix L  */
+       matrix &uMat,      /**< [out] the upper row echelon matrix U */
+       const ring r= currRing       /**< [in] current ring */
+             );
+
+/**
+ * Returns a pivot score for any non-zero matrix entry.
+ *
+ * The smaller the score the better will n serve as a pivot element
+ * in subsequent Gauss elimination steps.
+ *
+ * @return the pivot score of n
+ **/
+int pivotScore(
+               number n,    /**< [in] a non-zero matrix entry */
+               const ring r= currRing /**< [in] current ring */
+              );
+
+/**
+ * Finds the best pivot element in some part of a given matrix.
+ *
+ * Given any matrix A with valid row indices r1..r2 and valid column
+ * indices c1..c2, this method finds the best pivot element for
+ * subsequent Gauss elimination steps in A[r1..r2, c1..c2]. "Best"
+ * here means best with respect to the implementation of the method
+ * 'pivotScore(number n)'.<br>
+ * In the case that all elements in A[r1..r2, c1..c2] are zero, the
+ * method returns false, otherwise true.
+ *
+ * @return false if all relevant matrix entries are zero, true otherwise
+ * @sa pivotScore(number n)
+ **/
+bool pivot(
+           const matrix aMat, /**< [in]  any matrix with number entries */
+           const int r1,      /**< [in]  lower row index                */
+           const int r2,      /**< [in]  upper row index                */
+           const int c1,      /**< [in]  lower column index             */
+           const int c2,      /**< [in]  upper column index             */
+           int* bestR,        /**< [out] address of row index of best
+                                         pivot element                  */
+           int* bestC,        /**< [out] address of column index of
+                                         best pivot element             */
+           const ring r= currRing       /**< [in] current ring */
+          );
+
+/**
+ * Computes the inverse of a given (n x n)-matrix.
+ *
+ * This method expects an (n x n)-matrix, that is, it must have as many
+ * rows as columns. Inversion of the first argument is attempted via the
+ * LU-decomposition. There are two cases:<br>
+ * 1) The matrix is not invertible. Then the method returns false, and
+ *    &iMat remains unchanged.<br>
+ * 2) The matrix is invertible. Then the method returns true, and the
+ *    content of iMat is the inverse of aMat.
+ *
+ * @return true iff aMat is invertible, false otherwise
+ * @sa luInverseFromLUDecomp(const matrix pMat, const matrix lMat,
+ *                           const matrix uMat, matrix &iMat)
+ **/
+bool luInverse(
+               const matrix aMat, /**< [in]  matrix to be inverted */
+               matrix &iMat,      /**< [out] inverse of aMat if
+                                             invertible            */
+               const ring r=currRing /**< [in] current ring */
+              );
+
+/**
+ * Computes the inverse of a given (n x n)-matrix in upper right
+ * triangular form.
+ *
+ * This method expects a quadratic matrix, that is, it must have as
+ * many rows as columns. Moreover, uMat[i, j] = 0, at least for all
+ * i > j, that is, u is in upper right triangular form.<br>
+ * If the argument diagonalIsOne is true, then we know additionally,
+ * that uMat[i, i] = 1, for all i. In this case uMat is invertible.
+ * Contrariwise, if diagonalIsOne is false, we do not know anything
+ * about the diagonal entries. (Note that they may still all be
+ * 1.)<br>
+ * In general, there are two cases:<br>
+ * 1) The matrix is not invertible. Then the method returns false,
+ *    and &iMat remains unchanged.<br>
+ * 2) The matrix is invertible. Then the method returns true, and
+ *    the content of iMat is the inverse of uMat.
+ *
+ * @return true iff uMat is invertible, false otherwise
+ **/
+bool upperRightTriangleInverse(
+       const matrix uMat, /**< [in]  (n x n)-matrix in upper right
+                                     triangular form               */
+       matrix &iMat,      /**< [out] inverse of uMat if invertible */
+       bool diagonalIsOne,/**< [in]  if true, then all diagonal
+                                     entries of uMat are 1         */
+       const ring r= currRing /**< [in] current ring */
+                              );
+
+/**
+ * Computes the inverse of a given (n x n)-matrix in lower left
+ * triangular form.
+ *
+ * This method expects an (n x n)-matrix, that is, it must have as
+ * many rows as columns. Moreover, lMat[i,j] = 0, at least for all
+ * j > i, that ism lMat is in lower left triangular form.<br>
+ * If the argument diagonalIsOne is true, then we know additionally,
+ * that lMat[i, i] = 1, for all i. In this case lMat is invertible.
+ * Contrariwise, if diagonalIsOne is false, we do not know anything
+ * about the diagonal entries. (Note that they may still all be
+ * 1.)<br>
+ * In general, there are two cases:<br>
+ * 1) The matrix is not invertible. Then the method returns false,
+ *    and &iMat remains unchanged.<br>
+ * 2) The matrix is invertible. Then the method returns true, and
+ *    the content of iMat is the inverse of lMat.
+ *
+ * @return true iff lMat is invertible, false otherwise
+ **/
+bool lowerLeftTriangleInverse(
+       const matrix lMat, /**< [in]  (n x n)-matrix in lower left
+                                     triangular form               */
+       matrix &iMat,      /**< [out] inverse of lMat if invertible */
+       bool diagonalIsOne /**< [in]  if true, then all diagonal
+                                     entries of lMat are 1         */
+                              );
+
+/**
+ * Computes the inverse of an (n x n)-matrix which is given by its LU-
+ * decomposition.
+ *
+ * With A denoting the matrix to be inverted, the method expects the
+ * LU-decomposition of A, that is, pMat * A = lMat * uMat, where
+ * the argument matrices have the appropriate proteries; see method
+ * 'luDecomp(const matrix aMat, matrix &pMat, matrix &lMat,
+ * matrix &uMat)'.<br>
+ * Furthermore, uMat is expected to be an (n x n)-matrix. Then A^(-1)
+ * is computed according to A^(-1) = uMat^(-1) * lMat^(-1) * pMat,
+ * since pMat is self-inverse. This will work if and only if uMat is
+ * invertible, because lMat and pMat are in any case invertible.<br>
+ * In general, there are two cases:<br>
+ * 1) uMat and hence A is not invertible. Then the method returns
+ *    false, and &iMat remains unchanged.<br>
+ * 2) uMat and hence A is invertible. Then the method returns true,
+ *    and the content of iMat is the inverse of A.
+ *
+ * @return true if A is invertible, false otherwise
+ * @sa luInverse(const matrix aMat, matrix &iMat)
+ **/
+bool luInverseFromLUDecomp(
+       const matrix pMat, /**< [in]  permutation matrix of an LU-
+                                     decomposition                */
+       const matrix lMat, /**< [in]  lower left matrix of an LU-
+                                     decomposition                */
+       const matrix uMat, /**< [in]  upper right matrix of an LU-
+                                     decomposition                */
+       matrix &iMat,      /**< [out] inverse of A if invertible   */
+       const ring r= currRing
+                          );
+
+/**
+ * Computes the rank of a given (m x n)-matrix.
+ *
+ * The matrix may already be given in row echelon form, e.g., when
+ * the user has before called luDecomp and passes the upper triangular
+ * matrix U to luRank. In this case, the second argument can be set to
+ * true in order to pass this piece of information to the method.
+ * Otherwise, luDecomp will be called first to compute the matrix U.
+ * The rank is then read off the matrix U.
+ *
+ * @return the rank as an int
+ * @sa luDecomp(const matrix aMat, matrix &pMat, matrix &lMat, matrix &uMat)
+ **/
+int luRank(
+       const matrix aMat,      /**< [in]  input matrix */
+       const bool isRowEchelon,/**< [in]  if true then aMat is assumed to be
+                                          already in row echelon form */
+       const ring r= currRing
+          );
+
+/**
+ * Solves the linear system A * x = b, where A is an (m x n)-matrix
+ * which is given by its LU-decomposition.
+ *
+ * The method expects the LU-decomposition of A, that is,
+ * pMat * A = lMat * uMat, where the argument matrices have the
+ * appropriate proteries; see method
+ * 'luDecomp(const matrix aMat, matrix &pMat, matrix &lMat,
+ * matrix &uMat)'.<br>
+ * Instead of trying to invert A and return x = A^(-1)*b, this
+ * method
+ * 1) computes b' = pMat * b,
+ * 2) solves the simple system L * y = b', and then
+ * 3) solves the simple system U * x = y.
+ * Note that steps 1) and 2) will always work, as L is in any case
+ * invertible. Moreover, y is uniquely determined. Step 3) will only
+ * work if and only if y is in the column span of U. In that case,
+ * there may be infinitely many solutions.
+ * Thus, there are three cases:<br>
+ * 1) There is no solution. Then the method returns false, and &xVec
+ *    as well as &H remain unchanged.<br>
+ * 2) There is a unique solution. Then the method returns true and
+ *    H is the 1x1 matrix with zero entry.<br>
+ * 3) There are infinitely many solutions. Then the method returns
+ *    true and some solution of the given original linear system.
+ *    Furthermore, the columns of H span the solution space of the
+ *    homogeneous linear system. The dimension of the solution
+ *    space is then the number of columns of H.
+ *
+ * @return true if there is at least one solution, false otherwise
+ **/
+bool luSolveViaLUDecomp(
+       const matrix pMat, /**< [in]  permutation matrix of an LU-
+                                     decomposition                */
+       const matrix lMat, /**< [in]  lower left matrix of an LU-
+                                     decomposition                */
+       const matrix uMat, /**< [in]  upper right matrix of an LU-
+                                     decomposition                */
+       const matrix bVec, /**< [in]  right-hand side of the linear
+                                     system to be solved          */
+       matrix &xVec,      /**< [out] solution of A*x = b          */
+       matrix &H          /**< [out] matrix with columns spanning
+                                     homogeneous solution space   */
+                          );
+
+/**
+ * Solves the linear system A * x = b, where A is an (m x n)-matrix
+ * which is given by its LDU-decomposition.
+ *
+ * The method expects the LDU-decomposition of A, that is,
+ * pMat * A = lMat * dMat^(-1) * uMat, where the argument matrices have
+ * the appropriate proteries; see method
+ * 'lduDecomp(const matrix aMat, matrix &pMat, matrix &lMat,
+ * matrix &dMat, matrix &uMat, poly &l, poly &u, poly &lTimesU)'.<br>
+ * Instead of trying to invert A and return x = A^(-1)*b, this
+ * method
+ * 1) computes b' = l * pMat * b,
+ * 2) solves the simple system L * y = b',
+ * 3) computes y' = u * dMat * y,
+ * 4) solves the simple system U * y'' = y',
+ * 5) computes x = 1/(lTimesU) * y''.
+ * Note that steps 1), 2) and 3) will always work, as L is in any case
+ * invertible. Moreover, y and thus y' are uniquely determined.
+ * Step 4) will only work if and only if y' is in the column span of U.
+ * In that case, there may be infinitely many solutions.
+ * In contrast to luSolveViaLUDecomp, this algorithm guarantees that
+ * all divisions which have to be performed in steps 2) and 4) will
+ * work without remainder. This is due to properties of the given LDU-
+ * decomposition. Only the final step 5) performs a division of a vector
+ * by a member of the ground field. (Suppose the ground field is Q or
+ * some rational function field. Then, if A contains only integers or
+ * polynomials, respectively, then steps 1) - 4) will keep all data
+ * integer or polynomial, respectively. This may speed up computations
+ * considerably.)
+ * For the outcome, there are three cases:<br>
+ * 1) There is no solution. Then the method returns false, and &xVec
+ *    as well as &H remain unchanged.<br>
+ * 2) There is a unique solution. Then the method returns true and
+ *    H is the 1x1 matrix with zero entry.<br>
+ * 3) There are infinitely many solutions. Then the method returns
+ *    true and some solution of the given original linear system.
+ *    Furthermore, the columns of H span the solution space of the
+ *    homogeneous linear system. The dimension of the solution
+ *    space is then the number of columns of H.
+ *
+ * @return true if there is at least one solution, false otherwise
+ **/
+bool luSolveViaLDUDecomp(
+       const matrix pMat,  /**< [in]  permutation matrix of an LDU-
+                                      decomposition                     */
+       const matrix lMat,  /**< [in]  lower left matrix of an LDU-
+                                      decomposition                     */
+       const matrix dMat,  /**< [in]  diagonal matrix of an LDU-
+                                      decomposition                     */
+       const matrix uMat,  /**< [in]  upper right matrix of an LDU-
+                                      decomposition                     */
+       const poly l,       /**< [in]  pivot product l of an LDU decomp. */
+       const poly u,       /**< [in]  pivot product u of an LDU decomp. */
+       const poly lTimesU, /**< [in]  product of l and u                */
+       const matrix bVec,  /**< [in]  right-hand side of the linear
+                                      system to be solved               */
+       matrix &xVec,       /**< [out] solution of A*x = b               */
+       matrix &H           /**< [out] matrix with columns spanning
+                                      homogeneous solution space        */
+                          );
+
+/**
+ * Creates a new matrix which is the (nxn) unit matrix, and returns true
+ * in case of success.
+ *
+ * The method will be successful whenever n >= 1. In this case and only then
+ * true will be returned and the new (nxn) unit matrix will reside inside
+ * the second argument.
+ *
+ * @return true iff the (nxn) unit matrix could be build
+ **/
+bool unitMatrix(
+       const int n,     /**< [in]  size of the matrix */
+       matrix &unitMat,  /**< [out] the new (nxn) unit matrix */
+       const ring r= currRing /** [in] current ring */
+               );
+
+/**
+ * Creates a new matrix which is a submatrix of the first argument, and
+ * returns true in case of success.
+ *
+ * The method will be successful whenever rowIndex1 <= rowIndex2 and
+ * colIndex1 <= colIndex2. In this case and only then true will be
+ * returned and the last argument will afterwards contain a copy of the
+ * respective submatrix of the first argument.
+ * Note that this method may also be used to copy an entire matrix.
+ *
+ * @return true iff the submatrix could be build
+ **/
+bool subMatrix(
+       const matrix aMat,    /**< [in]  the input matrix */
+       const int rowIndex1,  /**< [in]  lower row index */
+       const int rowIndex2,  /**< [in]  higher row index */
+       const int colIndex1,  /**< [in]  lower column index */
+       const int colIndex2,  /**< [in]  higher column index */
+       matrix &subMat        /**< [out] the new submatrix */
+              );
+
+/**
+ * Swaps two rows of a given matrix and thereby modifies it.
+ *
+ * The method expects two valid, distinct row indices, i.e. in
+ * [1..n], where n is the number of rows in aMat.
+ **/
+void swapRows(
+       int row1,     /**< [in]     index of first row to swap */
+       int row2,     /**< [in]     index of second row to swap */
+       matrix& aMat  /**< [in/out] matrix subject to swapping */
+             );
+
+/**
+ * Swaps two columns of a given matrix and thereby modifies it.
+ *
+ * The method expects two valid, distinct column indices, i.e. in
+ * [1..n], where n is the number of columns in aMat.
+ **/
+void swapColumns(
+       int column1,  /**< [in]     index of first column to swap */
+       int column2,  /**< [in]     index of second column to swap */
+       matrix& aMat  /**< [in/out] matrix subject to swapping */
+             );
+
+/**
+ * Creates a new matrix which contains the first argument in the top left
+ * corner, and the second in the bottom right.
+ *
+ * All other entries of the resulting matrix which will be created in the
+ * third argument, are zero.
+ **/
+void matrixBlock(
+       const matrix aMat,    /**< [in]  the top left input matrix */
+       const matrix bMat,    /**< [in]  the bottom right input matrix */
+       matrix &block         /**< [out] the new block matrix */
+                );
+
+/**
+ * Computes the characteristic polynomial from a quadratic (2x2) matrix
+ * and returns true in case of success.
+ *
+ * The method will be successful whenever the input matrix is a (2x2) matrix.
+ * In this case, the resulting polynomial will be a univariate polynomial in
+ * the first ring variable of degree 2 and it will reside in the second
+ * argument.
+ * The method assumes that the matrix entries are all numbers, i.e., elements
+ * from the ground field/ring.
+ *
+ * @return true iff the input matrix was (2x2)
+ **/
+bool charPoly(
+       const matrix aMat,    /**< [in]  the input matrix */
+       poly &charPoly        /**< [out] the characteristic polynomial */
+             );
+
+/**
+ * Computes the square root of a non-negative real number and returns
+ * it as a new number.
+ *
+ * The method assumes that the current ground field is the complex
+ * numbers, and that the argument has imaginary part zero.
+ * If the real part is negative, then false is returned, otherwise true.
+ * The square root will be computed in the last argument by Heron's
+ * iteration formula with the first argument as the starting value. The
+ * iteration will stop as soon as two successive values (in the resulting
+ * sequence) differ by no more than the given tolerance, which is assumed
+ * to be a positive real number.
+ *
+ * @return the square root of the non-negative argument number
+ **/
+bool realSqrt(
+       const number n,          /**< [in]  the input number */
+       const number tolerance,  /**< [in]  accuracy of iteration */
+       number &root             /**< [out] the root of n */
+             );
+
+/**
+ * Computes the Hessenberg form of a given square matrix.
+ *
+ * The method assumes that all matrix entries are numbers coming from some
+ * subfield of the reals..
+ * Afterwards, the following conditions will hold:
+ * 1) hessenbergMat = pMat * aMat * pMat^{-1},
+ * 2) hessenbergMat is in Hessenberg form.
+ * During the algorithm, pMat will be constructed as the product of self-
+ * inverse matrices.
+ * The algorithm relies on computing square roots of floating point numbers.
+ * These will be combuted by Heron's iteration formula, with iteration
+ * stopping when two successive approximations of the square root differ by
+ * no more than the given tolerance, which is assumed to be a positve real
+ * number.
+ **/
+void hessenberg(
+       const matrix aMat,      /**< [in]  the square input matrix */
+       matrix &pMat,           /**< [out] the transformation matrix */
+       matrix &hessenbergMat,  /**< [out] the Hessenberg form of aMat */
+       const number tolerance, /**< [in]  accuracy */
+       const ring r
+               );
+
+/**
+ * Returns all solutions of a quadratic polynomial relation with real
+ * coefficients.
+ *
+ * The method assumes that the polynomial is univariate in the first
+ * ring variable, and that the current ground field is the complex numbers.
+ * The polynomial has degree <= 2. Thus, there may be
+ * a) infinitely many zeros, when p == 0; then -1 is returned;
+ * b) no zero, when p == constant <> 0; then 0 is returned;
+ * c) one zero, when p is linear; then 1 is returned;
+ * d) one double zero; then 2 is returned;
+ * e) two distinct zeros; then 3 is returned;
+ * In the case e), s1 and s2 will contain the two distinct solutions.
+ * In cases c) and d) s1 will contain the single/double solution.
+ *
+ * @return the number of distinct zeros
+ **/
+int quadraticSolve(
+       const poly p,           /**< [in]  the polynomial        */
+       number &s1,             /**< [out] first zero, if any    */
+       number &s2,             /**< [out] second zero, if any   */
+       const number tolerance  /**< [in] accuracy               */
+                  );
+
+
+/**
+ * Computes a factorization of a polynomial h(x, y) in K[[x]][y] up to a
+ * certain degree in x, whenever a factorization of h(0, y) is given.
+ *
+ * The algorithm is based on Hensel's lemma: Let h(x, y) denote a monic
+ * polynomial in y of degree m + n with coefficients in K[[x]]. Suppose there
+ * are two monic factors f_0(y) (of degree n) and g_0(y) of degree (m) such
+ * that h(0, y) = f_0(y) * g_0(y) and <f_0, g_0> = K[y]. Fix an integer d >= 0.
+ * Then there are monic polynomials in y with coefficients in K[[x]], namely
+ * f(x, y) of degree n and g(x, y) of degree m such that
+ *    h(x, y) = f(x, y) * g(x, y) modulo <x^(d+1)>   (*).
+ *
+ * This implementation expects h, f0, g0, and d as described and computes the
+ * factors f and g. Effectively, h will be given as an element of K[x, y] since
+ * all terms of h with x-degree larger than d can be ignored due to (*).
+ * The method expects the ground ring to contain at least two variables; then
+ * x is the first ring variable, specified by the input index xIndex, and y the
+ * second one, specified by yIndex.
+ *
+ * This code was placed here since the algorithm works by successively solving
+ * d linear equation systems. It is hence an application of other methods
+ * defined in this h-file and its corresponding cc-file.
+ *
+ **/
+void henselFactors(
+       const int xIndex,  /**< [in]  index of x in {1, ..., nvars(basering)} */
+       const int yIndex,  /**< [in]  index of y in {1, ..., nvars(basering)} */
+       const poly h,      /**< [in]  the polynomial h(x, y) as above         */
+       const poly f0,     /**< [in]  the first univariate factor of h(0, y)  */
+       const poly g0,     /**< [in]  the second univariate factor of h(0, y) */
+       const int d,       /**< [in]  the degree bound, d >= 0                */
+       poly &f,           /**< [out] the first factor of h(x, y)             */
+       poly &g            /**< [out] the second factor of h(x, y)            */
+                              );
+
+/**
+ * LU-decomposition of a given (m x n)-matrix with performing only those
+ * divisions that yield zero remainders.
+ *
+ * Given an (m x n) matrix A, the method computes its LDU-decomposition,
+ * that is, it computes matrices P, L, D, and U such that<br>
+ * - P * A = L * D^(-1) * U,<br>
+ * - P is an (m x m) permutation matrix, i.e., its row/columns form the
+ *   standard basis of K^m,<br>
+ * - L is an (m x m) matrix in lower triangular form of full rank,<br>
+ * - D is an (m x m) diagonal matrix with full rank, and<br>
+ * - U is an (m x n) matrix in upper row echelon form.<br>
+ * From these conditions, it follows immediately that also
+ * A = P * L * D^(-1) * U, since P is self-inverse.<br>
+ *
+ * In contrast to luDecomp, this method only performs those divisions which
+ * yield zero remainders. Hence, when e.g. computing over a rational function
+ * field and starting with polynomial entries only (or over Q and starting
+ * with integer entries only), then any newly computed matrix entry will again
+ * be polynomial (or integer).
+ *
+ * The method will modify all argument matrices except aMat, so that
+ * they will finally contain the matrices P, L, D, and U as specified
+ * above. Moreover, in order to further speed up subsequent calls of
+ * luSolveViaLDUDecomp, the two denominators and their product will also be
+ * returned.
+ **/
+void lduDecomp(
+       const matrix aMat, /**< [in]  the initial matrix A,          */
+       matrix &pMat,      /**< [out] the row permutation matrix P   */
+       matrix &lMat,      /**< [out] the lower triangular matrix L  */
+       matrix &dMat,      /**< [out] the diagonal matrix D          */
+       matrix &uMat,      /**< [out] the upper row echelon matrix U */
+       poly &l,           /**< [out] the product of pivots of L     */
+       poly &u,           /**< [out] the product of pivots of U     */
+       poly &lTimesU      /**< [out] the product of l and u         */
+             );
+
+/* helper for qrDoubleShift */
+bool qrDS( const int n, matrix* queue, int& queueL, number* eigenValues,
+       int& eigenValuesL, const number tol1, const number tol2, const ring R);
+
+/**
+ * Tries to find the number n in the array nn[0..nnLength-1].
+ **/
+int similar(
+       const number* nn,       /**< [in] array of numbers to look-up */
+       const int nnLength,     /**< [in] length of nn                */
+       const number n,         /**< [in] number to loop-up in nn     */
+       const number tolerance  /**< [in] tolerance for comparison    */
+           );
+#endif
+/* LINEAR_ALGEBRA_H */
diff --git a/kernel/linear_algebra/minpoly.cc b/kernel/linear_algebra/minpoly.cc
new file mode 100644
index 0000000..e75eb39
--- /dev/null
+++ b/kernel/linear_algebra/minpoly.cc
@@ -0,0 +1,777 @@
+/*************************************************
+ * Author: Sebastian Jambor, 2011                *
+ * GPL (e-mail from June 6, 2012, 17:00:31 MESZ) *
+ * sebastian at momo.math.rwth-aachen.de            *
+ ************************************************/
+
+
+#include<cmath>
+#include <cstdlib>
+
+
+
+#include<kernel/mod2.h>
+
+//#include<iomanip>
+
+#include "minpoly.h"
+
+// TODO: avoid code copying, use subclassing instead!
+
+LinearDependencyMatrix::LinearDependencyMatrix (unsigned n, unsigned long p)
+{
+  this->n = n;
+  this->p = p;
+
+  matrix = new unsigned long *[n];
+  for(int i = 0; i < n; i++)
+  {
+    matrix[i] = new unsigned long[2 * n + 1];
+  }
+  pivots = new unsigned[n];
+  tmprow = new unsigned long[2 * n + 1];
+  rows = 0;
+}
+
+LinearDependencyMatrix::~LinearDependencyMatrix ()
+{
+  delete[]tmprow;
+  delete[]pivots;
+
+  for(int i = 0; i < n; i++)
+  {
+    delete[](matrix[i]);
+  }
+  delete[]matrix;
+}
+
+void LinearDependencyMatrix::resetMatrix ()
+{
+  rows = 0;
+}
+
+int LinearDependencyMatrix::firstNonzeroEntry (unsigned long *row)
+{
+  for(int i = 0; i < n; i++)
+    if(row[i] != 0)
+      return i;
+
+  return -1;
+}
+
+void LinearDependencyMatrix::reduceTmpRow ()
+{
+  for(int i = 0; i < rows; i++)
+  {
+    unsigned piv = pivots[i];
+    unsigned x = tmprow[piv];
+    // if the corresponding entry in the row is zero, there is nothing to do
+    if(x != 0)
+    {
+      // subtract tmprow[i] times the i-th row
+      for(int j = piv; j < n + rows + 1; j++)
+      {
+        if (matrix[i][j] != 0)
+        {
+          unsigned long tmp = multMod (matrix[i][j], x, p);
+          tmp = p - tmp;
+          tmprow[j] += tmp;
+          if (tmprow[j] >= p)
+          {
+            tmprow[j] -= p;
+          }
+        }
+      }
+    }
+  }
+}
+
+
+void LinearDependencyMatrix::normalizeTmp (unsigned i)
+{
+  unsigned long inv = modularInverse (tmprow[i], p);
+  tmprow[i] = 1;
+  for(int j = i + 1; j < 2 * n + 1; j++)
+    tmprow[j] = multMod (tmprow[j], inv, p);
+}
+
+bool LinearDependencyMatrix::findLinearDependency (unsigned long *newRow,
+                                                   unsigned long *dep)
+{
+  // Copy newRow to tmprow (we need to add RHS)
+  for(int i = 0; i < n; i++)
+  {
+    tmprow[i] = newRow[i];
+    tmprow[n + i] = 0;
+  }
+  tmprow[2 * n] = 0;
+  tmprow[n + rows] = 1;
+
+  reduceTmpRow ();
+
+  // Is tmprow reduced to zero? Then we have found a linear dependence.
+  // Otherwise, we just add tmprow to the matrix.
+  unsigned newpivot = firstNonzeroEntry (tmprow);
+  if(newpivot == -1)
+  {
+    for(int i = 0; i <= n; i++)
+    {
+      dep[i] = tmprow[n + i];
+    }
+
+    return true;
+  }
+  else
+  {
+    normalizeTmp (newpivot);
+
+    for(int i = 0; i < 2 * n + 1; i++)
+    {
+      matrix[rows][i] = tmprow[i];
+    }
+
+    pivots[rows] = newpivot;
+    rows++;
+
+    return false;
+  }
+}
+
+#if 0
+std::ostream & operator<< (std::ostream & out,
+                           const LinearDependencyMatrix & mat)
+{
+  int width = ((int) log10 (mat.p)) + 1;
+
+  out << "Pivots: " << std::endl;
+  for(int j = 0; j < mat.n; j++)
+  {
+    out << std::setw (width) << mat.pivots[j] << " ";
+  }
+  out << std::endl;
+  out << "matrix:" << std::endl;
+  for(int i = 0; i < mat.rows; i++)
+  {
+    for(int j = 0; j < mat.n; j++)
+    {
+      out << std::setw (width) << mat.matrix[i][j] << " ";
+    }
+    out << "| ";
+    for(int j = mat.n; j <= 2 * mat.n; j++)
+    {
+      out << std::setw (width) << mat.matrix[i][j] << " ";
+    }
+    out << std::endl;
+  }
+  out << "tmprow: " << std::endl;
+  for(int j = 0; j < mat.n; j++)
+  {
+    out << std::setw (width) << mat.tmprow[j] << " ";
+  }
+  out << "| ";
+  for(int j = mat.n; j <= 2 * mat.n; j++)
+  {
+    out << std::setw (width) << mat.tmprow[j] << " ";
+  }
+  out << std::endl;
+
+  return out;
+}
+#endif
+
+
+NewVectorMatrix::NewVectorMatrix (unsigned n, unsigned long p)
+{
+  this->n = n;
+  this->p = p;
+
+  matrix = new unsigned long *[n];
+  for(int i = 0; i < n; i++)
+  {
+    matrix[i] = new unsigned long[n];
+  }
+
+  pivots = new unsigned[n];
+
+  nonPivots = new unsigned[n];
+
+  for (int i = 0; i < n; i++)
+  {
+     nonPivots[i] = i;
+  }
+
+  rows = 0;
+}
+
+NewVectorMatrix::~NewVectorMatrix ()
+{
+  delete nonPivots;
+  delete pivots;
+
+  for(int i = 0; i < n; i++)
+  {
+    delete[]matrix[i];
+  }
+  delete matrix;
+}
+
+int NewVectorMatrix::firstNonzeroEntry (unsigned long *row)
+{
+  for(int i = 0; i < n; i++)
+    if(row[i] != 0)
+      return i;
+
+  return -1;
+}
+
+void NewVectorMatrix::normalizeRow (unsigned long *row, unsigned i)
+{
+  unsigned long inv = modularInverse (row[i], p);
+  row[i] = 1;
+
+  for(int j = i + 1; j < n; j++)
+  {
+    row[j] = multMod (row[j], inv, p);
+  }
+}
+
+void NewVectorMatrix::insertRow (unsigned long *row)
+{
+  for(int i = 0; i < rows; i++)
+  {
+    unsigned piv = pivots[i];
+    unsigned x = row[piv];
+    // if the corresponding entry in the row is zero, there is nothing to do
+    if(x != 0)
+    {
+      // subtract row[i] times the i-th row
+      // only the non-pivot entries have to be considered
+      // (and also the first entry)
+      row[piv] = 0;
+
+      int smallestNonPivIndex = 0;
+      while (nonPivots[smallestNonPivIndex] < piv)
+      {
+        smallestNonPivIndex++;
+      }
+
+      for (int j = smallestNonPivIndex; j < n-rows; j++)
+      {
+        unsigned ind = nonPivots[j];
+        if (matrix[i][ind] != 0)
+        {
+          unsigned long tmp = multMod (matrix[i][ind], x, p);
+          tmp = p - tmp;
+          row[ind] += tmp;
+          if (row[ind] >= p)
+          {
+            row[ind] -= p;
+          }
+        }
+      }
+    }
+  }
+
+  unsigned piv = firstNonzeroEntry (row);
+
+  if(piv != -1)
+  {
+    // Normalize and insert row into the matrix.
+    // Then reduce upwards.
+    normalizeRow (row, piv);
+    for(int i = 0; i < n; i++)
+    {
+      matrix[rows][i] = row[i];
+    }
+
+
+    for (int i = 0; i < rows; i++)
+    {
+      unsigned x = matrix[i][piv];
+      // if the corresponding entry in the matrix is zero,
+      // there is nothing to do
+      if (x != 0)
+      {
+        for (int j = piv; j < n; j++)
+        {
+          if (row[j] != 0)
+          {
+            unsigned long tmp = multMod(row[j], x, p);
+            tmp = p - tmp;
+            matrix[i][j] += tmp;
+            if (matrix[i][j] >= p)
+            {
+              matrix[i][j] -= p;
+            }
+          }
+        }
+      }
+    }
+
+    pivots[rows] = piv;
+
+    // update nonPivots
+    for (int i = 0; i < n-rows; i++)
+    {
+      if (nonPivots[i] == piv)
+      {
+        // shift everything one position to the left
+        for (int j = i; j < n-rows-1; j++)
+        {
+          nonPivots[j] = nonPivots[j+1];
+        }
+
+        break;
+      }
+    }
+
+    rows++;
+  }
+}
+
+
+void NewVectorMatrix::insertMatrix (LinearDependencyMatrix & mat)
+{
+  for(int i = 0; i < mat.rows; i++)
+  {
+    insertRow (mat.matrix[i]);
+  }
+}
+
+int NewVectorMatrix::findSmallestNonpivot ()
+{
+  // This method isn't very efficient, but it is called at most a few times,
+  // so efficiency is not important.
+  if(rows == n)
+    return -1;
+
+  for(int i = 0; i < n; i++)
+  {
+    bool isPivot = false;
+    for(int j = 0; j < rows; j++)
+    {
+      if(pivots[j] == i)
+      {
+        isPivot = true;
+        break;
+      }
+    }
+
+    if(!isPivot)
+    {
+      return i;
+    }
+  }
+  abort();
+}
+
+int NewVectorMatrix::findLargestNonpivot ()
+{
+  // This method isn't very efficient, but it is called at most a few times, so efficiency is not important.
+  if(rows == n)
+    return -1;
+
+  for(int i = n-1; i >= 0; i--)
+  {
+    bool isPivot = false;
+    for(int j = 0; j < rows; j++)
+    {
+      if(pivots[j] == i)
+      {
+        isPivot = true;
+        break;
+      }
+    }
+
+    if(!isPivot)
+    {
+      return i;
+    }
+  }
+  abort();
+}
+
+
+void vectorMatrixMult (unsigned long *vec, unsigned long **mat,
+                       unsigned **nonzeroIndices, unsigned *nonzeroCounts,
+                       unsigned long *result, unsigned n, unsigned long p)
+{
+  unsigned long tmp;
+
+  for(int i = 0; i < n; i++)
+  {
+    result[i] = 0;
+    for(int j = 0; j < nonzeroCounts[i]; j++)
+    {
+      tmp = multMod (vec[nonzeroIndices[i][j]], mat[nonzeroIndices[i][j]][i], p);
+      result[i] += tmp;
+      if (result[i] >= p)
+      {
+        result[i] -= p;
+      }
+    }
+  }
+}
+
+
+#if 0
+void printVec (unsigned long *vec, int n)
+{
+  for(int i = 0; i < n; i++)
+  {
+    std::cout << vec[i] << ", ";
+  }
+
+  std::cout << std::endl;
+}
+#endif
+
+
+unsigned long *computeMinimalPolynomial (unsigned long **matrix, unsigned n,
+                                         unsigned long p)
+{
+  LinearDependencyMatrix lindepmat (n, p);
+  NewVectorMatrix newvectormat (n, p);
+
+  unsigned long *result = new unsigned long[n + 1];
+  unsigned long *mpvec = new unsigned long[n + 1];
+  unsigned long *tmp = new unsigned long[n + 1];
+
+  // initialize result = 1
+  for(int i = 0; i <= n; i++)
+  {
+    result[i] = 0;
+  }
+  result[0] = 1;
+
+  int degresult = 0;
+
+
+  // Store the indices where the matrix has non-zero entries.
+  // This has a huge impact on spares matrices.
+  unsigned* nonzeroCounts = new unsigned[n];
+  unsigned** nonzeroIndices = new unsigned*[n];
+  for (int i = 0; i < n; i++)
+  {
+    nonzeroIndices[i] = new unsigned[n];
+    nonzeroCounts[i] = 0;
+    for (int j = 0; j < n; j++)
+    {
+      if (matrix[j][i] != 0)
+      {
+        nonzeroIndices[i][nonzeroCounts[i]] = j;
+        nonzeroCounts[i]++;
+      }
+    }
+  }
+
+  int i = n-1;
+
+  unsigned long *vec = new unsigned long[n];
+  unsigned long *vecnew = new unsigned long[n];
+
+  unsigned loopsEven = true;
+  while(i != -1)
+  {
+    for(int j = 0; j < n; j++)
+    {
+      vec[j] = 0;
+    }
+    vec[i] = 1;
+
+    lindepmat.resetMatrix ();
+
+    while(true)
+    {
+      bool ld = lindepmat.findLinearDependency (vec, mpvec);
+
+      if(ld)
+      {
+        break;
+      }
+
+      vectorMatrixMult (vec, matrix, nonzeroIndices, nonzeroCounts, vecnew, n, p);
+      unsigned long *swap = vec;
+      vec = vecnew;
+      vecnew = swap;
+    }
+
+
+    unsigned degmpvec = n;
+    while(mpvec[degmpvec] == 0)
+    {
+      degmpvec--;
+    }
+
+    // if the dimension is already maximal, i.e., the minimal polynomial of vec has the highest possible degree,
+    // then we are done.
+    if(degmpvec == n)
+    {
+      unsigned long *swap = result;
+      result = mpvec;
+      mpvec = swap;
+      i = -1;
+    }
+    else
+    {
+      // otherwise, we have to compute the lcm of mpvec and prior result
+
+      // tmp = zeropol
+      for(int j = 0; j <= n; j++)
+      {
+        tmp[j] = 0;
+      }
+      degresult = lcm (tmp, result, mpvec, p, degresult, degmpvec);
+      unsigned long *swap = result;
+      result = tmp;
+      tmp = swap;
+
+      if(degresult == n)
+      {
+        // minimal polynomial has highest possible degree, so we are done.
+        i = -1;
+      }
+      else
+      {
+        newvectormat.insertMatrix (lindepmat);
+
+        // choose new unit vector from the front or the end, alternating
+        // for each round. If the matrix is the companion matrix for x^n,
+        // then taking vectors from the end is best. If it is the transpose,
+        // taking vectors from the front is best.
+        // This tries to take the middle way
+        if (loopsEven)
+        {
+          i = newvectormat.findSmallestNonpivot ();
+        }
+        else
+        {
+          i = newvectormat.findLargestNonpivot ();
+        }
+      }
+    }
+
+    loopsEven = !loopsEven;
+  }
+
+  for (int i = 0; i < n; i++)
+  {
+    delete[] nonzeroIndices[i];
+  }
+  delete[] nonzeroIndices;
+  delete[] nonzeroCounts;
+
+
+  delete[]vecnew;
+  delete[]vec;
+  delete[]tmp;
+  delete[]mpvec;
+
+  return result;
+}
+
+
+void rem (unsigned long *a, unsigned long *q, unsigned long p, int &dega,
+          int degq)
+{
+  while(degq <= dega)
+  {
+    unsigned d = dega - degq;
+    long factor = multMod (a[dega], modularInverse (q[degq], p), p);
+    for(int i = degq; i >= 0; i--)
+    {
+      long tmp = p - multMod (factor, q[i], p);
+      a[d + i] += tmp;
+      if (a[d + i] >= p)
+      {
+        a[d + i] -= p;
+      }
+    }
+
+    while(dega >= 0 && a[dega] == 0)
+    {
+      dega--;
+    }
+  }
+}
+
+
+void quo (unsigned long *a, unsigned long *q, unsigned long p, int &dega,
+          int degq)
+{
+  unsigned degres = dega - degq;
+  unsigned long *result = new unsigned long[degres + 1];
+
+  // initialize to zero
+  for (int i = 0; i <= degres; i++)
+  {
+    result[i] = 0;
+  }
+
+  while(degq <= dega)
+  {
+    unsigned d = dega - degq;
+    unsigned long inv = modularInverse (q[degq], p);
+    result[d] = multMod (a[dega], inv, p);
+    for(int i = degq; i >= 0; i--)
+    {
+      unsigned long tmp = p - multMod (result[d], q[i], p);
+      a[d + i] += tmp;
+      if (a[d + i] >= p)
+      {
+        a[d + i] -= p;
+      }
+    }
+
+    while(dega >= 0 && a[dega] == 0)
+    {
+      dega--;
+    }
+  }
+
+  // copy result into a
+  for(int i = 0; i <= degres; i++)
+  {
+    a[i] = result[i];
+  }
+  // set all following entries of a to zero
+  for(int i = degres + 1; i <= degq + degres; i++)
+  {
+    a[i] = 0;
+  }
+
+  dega = degres;
+
+  delete[]result;
+}
+
+
+void mult (unsigned long *result, unsigned long *a, unsigned long *b,
+           unsigned long p, int dega, int degb)
+{
+  // NOTE: we assume that every entry in result is preinitialized to zero!
+
+  for(int i = 0; i <= dega; i++)
+  {
+    for(int j = 0; j <= degb; j++)
+    {
+      result[i + j] += multMod (a[i], b[j], p);
+      if (result[i + j] >= p)
+      {
+        result[i + j] -= p;
+      }
+    }
+  }
+}
+
+
+int gcd (unsigned long *g, unsigned long *a, unsigned long *b,
+         unsigned long p, int dega, int degb)
+{
+  unsigned long *tmp1 = new unsigned long[dega + 1];
+  unsigned long *tmp2 = new unsigned long[degb + 1];
+  for(int i = 0; i <= dega; i++)
+  {
+    tmp1[i] = a[i];
+  }
+  for(int i = 0; i <= degb; i++)
+  {
+    tmp2[i] = b[i];
+  }
+  int degtmp1 = dega;
+  int degtmp2 = degb;
+
+  unsigned long *swappol;
+  int swapdeg;
+
+  while(degtmp2 >= 0)
+  {
+    rem (tmp1, tmp2, p, degtmp1, degtmp2);
+    swappol = tmp1;
+    tmp1 = tmp2;
+    tmp2 = swappol;
+
+    swapdeg = degtmp1;
+    degtmp1 = degtmp2;
+    degtmp2 = swapdeg;
+  }
+
+  for(int i = 0; i <= degtmp1; i++)
+  {
+    g[i] = tmp1[i];
+  }
+
+  delete[]tmp1;
+  delete[]tmp2;
+
+  return degtmp1;
+}
+
+
+int lcm (unsigned long *l, unsigned long *a, unsigned long *b,
+         unsigned long p, int dega, int degb)
+{
+  unsigned long *g = new unsigned long[dega + 1];
+  // initialize entries of g to zero
+  for(int i = 0; i <= dega; i++)
+  {
+    g[i] = 0;
+  }
+
+  int degg = gcd (g, a, b, p, dega, degb);
+
+  if(degg > 0)
+  {
+    // non-trivial gcd, so compute a = (a/g)
+    quo (a, g, p, dega, degg);
+  }
+  mult (l, a, b, p, dega, degb);
+
+  // normalize
+  if(l[dega + degb + 1] != 1)
+  {
+    unsigned long inv = modularInverse (l[dega + degb], p);
+    for(int i = 0; i <= dega + degb; i++)
+    {
+      l[i] = multMod (l[i], inv, p);
+    }
+  }
+
+  return dega + degb;
+}
+
+
+// computes the gcd and the cofactors of u and v
+// gcd(u,v) = u3 = u*u1 + v*u2
+unsigned long modularInverse (long long x, long long p)
+{
+  long long u1 = 1;
+  long long u2 = 0;
+  long long u3 = x;
+  long long v1 = 0;
+  long long v2 = 1;
+  long long v3 = p;
+
+  long long q, t1, t2, t3;
+  while(v3 != 0)
+  {
+    q = u3 / v3;
+    t1 = u1 - q * v1;
+    t2 = u2 - q * v2;
+    t3 = u3 - q * v3;
+    u1 = v1;
+    u2 = v2;
+    u3 = v3;
+    v1 = t1;
+    v2 = t2;
+    v3 = t3;
+  }
+
+  if(u1 < 0)
+  {
+    u1 += p;
+  }
+
+  return (unsigned long) u1;
+}
+
diff --git a/kernel/linear_algebra/minpoly.h b/kernel/linear_algebra/minpoly.h
new file mode 100644
index 0000000..65c185e
--- /dev/null
+++ b/kernel/linear_algebra/minpoly.h
@@ -0,0 +1,214 @@
+/***********************************************************************************
+ * Author: Sebastian Jambor, 2011                                                  *
+ * (C) GPL (e-mail from June 6, 2012, 17:00:31 MESZ)                               *
+ * sebastian at momo.math.rwth-aachen.de                                              *
+ *                                                                                 *
+ * Implementation of an algorithm to compute the minimal polynomial of a           *
+ * square matrix A \in \F_p^{n \times n}.                                          *
+ *                                                                                 *
+ * Let V_1, \dotsc, V_k \in \F_p^{1 \times n} be vectors such that                 *
+ * V_1, V_1*A, V_1*A^2, \dotsc, V_2, V_2*A, V_2*A^2, \dotsc                        *
+ * generate \F_p^{1 \times n}.                                                     *
+ * Let mpV_i be the monic polynomial of smallest degree such that                  *
+ * V_i*mpV_i(A) = 0.                                                               *
+ * Then the minimal polynomial of A is the least common multiple of the mpV_i.     *
+ *                                                                                 *
+ *                                                                                 *
+ * The algorithm uses two classes:                                                 *
+ *                                                                                 *
+ * 1. LinearDependencyMatrix                                                       *
+ * This is used to find a linear dependency between the vectors V, V*A, \ldotsc.   *
+ * To to this, it has an internal n \times (2n + 1) matrix.                        *
+ * Every time a new row VA^i is inserted, it is reduced via Gauss' Algorithm,      *
+ * using right hand sides. If VA^i is reduced to zero, then the vectors are        *
+ * linearly dependend, and the dependency can be read of at the right hand sides.  *
+ *                                                                                 *
+ * Example: Compute the minimal polynomial of A = [[0,1],[1,1]] with V = [1,0]     *
+ * over F_5.                                                                       *
+ * Then LinearDependencyMatrix will be:                                            *
+ * After the first step (i.e., after inserting V = [1,0]):                         *
+ *       ( 1 0 | 1 0 0 )                                                           *
+ * After the second step (i.e., after inserting VA = [0,1]):                       *
+ *       ( 1 0 | 1 0 0 )                                                           *
+ *       ( 0 1 | 0 1 0 )                                                           *
+ * In the third step, where VA^2 = [1,1] is inserted, the row                      *
+ *       ( 1 1 | 0 0 1 )                                                           *
+ * is reduced to                                                                   *
+ *       ( 0 0 | 4 4 1)                                                            *
+ * Thus VA^2 + 4*VA + 4*V = 0, so mpV = t^2 + 4*t + 4.                             *
+ *                                                                                 *
+ *                                                                                 *
+ *                                                                                 *
+ * 2. NewVectorMatrix                                                              *
+ * If one vector V_1 is not enough to compute the minimal polynomial, i.e. the     *
+ * vectors V_1, V_1*A, V_1*A^2, \dotsc don't generate \F_p^{1 \times n}, then      *
+ * we have to find a vector V_2 which is not in the span of the V_1*A^i.           *
+ * This is done with NewVectorMatrix, which simply holds a reduced n \times n      *
+ * matrix, where the rows generate the span of the V_jA^i.                         *
+ * To find a vector which is not in the span, simply take the k-th standard        *
+ * vector, where k is not a pivot element of A.                                    *
+ *                                                                                 *
+ *                                                                                 *
+ * For efficiency reasons, the matrix entries in LinearDependencyMatrix            *
+ * and NewVectorMatrix are not initialized to zero. Instead, a variable rows       *
+ * is used to indicate the number of rows which are nonzero (all further           *
+ * rows are regarded as zero rows). Furthermore, the array pivots stores the       *
+ * pivot entries of the rows, i.e., pivots[i] indicates the position of the        *
+ * first non-zero entry in the i-th row, which is normalized to 1.                 *
+ ***********************************************************************************/
+
+
+
+
+#ifndef MINPOLY_H
+#define MINPOLY_H
+
+//#include<iostream>
+
+class NewVectorMatrix;
+
+class LinearDependencyMatrix {
+    friend class NewVectorMatrix;
+private:
+    unsigned p;
+    unsigned long n;
+    unsigned long **matrix;
+    unsigned long *tmprow;
+    unsigned *pivots;
+    unsigned rows;
+
+public:
+    LinearDependencyMatrix(unsigned n, unsigned long p);
+    ~LinearDependencyMatrix();
+
+    // reset the matrix, so that we can use it to find another linear dependence
+    // Note: there is no need to reinitalize the matrix and vectors!
+    void resetMatrix();
+
+
+    // return the first nonzero entry in row (only the first n entries are checked,
+    // regardless of the size, since we will also apply this for rows with
+    // right hand sides).
+    // If the first n entries are all zero, return -1 (so this gives a check if row is the zero vector)
+    int firstNonzeroEntry(unsigned long *row);
+
+    void reduceTmpRow();
+
+    void normalizeTmp(unsigned i);
+
+    bool findLinearDependency(unsigned long* newRow, unsigned long* dep);
+
+    //friend std::ostream& operator<<(std::ostream& out, const LinearDependencyMatrix& mat);
+};
+
+
+// This class is used to find a new vector for the next step in the
+// minimal polynomial algorithm.
+class NewVectorMatrix {
+private:
+    unsigned p;
+    unsigned long n;
+    unsigned long **matrix;
+    unsigned *pivots;
+    unsigned *nonPivots;
+    unsigned rows;
+
+public:
+    NewVectorMatrix(unsigned n, unsigned long p);
+    ~NewVectorMatrix();
+
+    // return the first nonzero entry in row (only the first n entries are checked,
+    // regardless of the size, since we will also apply this for rows with
+    // right hand sides).
+    // If the first n entries are all zero, return -1 (so this gives a check if row is the zero vector)
+    int firstNonzeroEntry(unsigned long *row);
+
+//    // let piv be the pivot position of row i. then this method eliminates entry piv of row
+//    void subtractIthRow(unsigned long *row, unsigned i);
+
+    void normalizeRow(unsigned long *row, unsigned i);
+
+    void insertRow(unsigned long* row);
+
+    // insert each row of the matrix
+    void insertMatrix(LinearDependencyMatrix& mat);
+
+    // Finds the smallest integer between 0 and n-1, which is not a pivot position.
+    // If no such number exists, return -1.
+    int findSmallestNonpivot();
+
+    int findLargestNonpivot();
+};
+
+
+// compute the minimal polynomial of matrix \in \F_p^{n \times n}.
+// The result is an array of length n + 1, where the i-th entry represents the i-th coefficient
+// of the minimal polynomial.
+//
+// result should be deleted with delete[]
+unsigned long* computeMinimalPolynomial(unsigned long** matrix, unsigned n, unsigned long p);
+
+
+
+/////////////////////////////////
+// auxiliary methods
+/////////////////////////////////
+
+
+// compute x^(-1) mod p
+//
+// NOTE: this uses long long instead of unsigned long, for the XEA to work.
+// This shouldn't be a problem, since p has to be < 2^31 for the multiplication to work anyway.
+//
+// There is no need to distinguish between 32bit and 64bit architectures: On 64bit, long long
+// is the same as long, and on 32bit, we need long long so that the variables can hold negative values.
+unsigned long modularInverse(long long x, long long p);
+
+void vectorMatrixMult(unsigned long* vec, unsigned long **mat, unsigned **nonzeroIndices, unsigned *nonzeroCounts, unsigned long* result, unsigned n, unsigned long p);
+
+// a is a vector of length at least dega + 1, and q is a vector of length at least degq + 1,
+// representing polynomials \sum_i a[i]t^i \in \F_p[t].
+// After this method, a will be a mod q.
+// Method will change dega accordingly.
+void rem(unsigned long* a, unsigned long* q, unsigned long p, int & dega, int degq);
+
+// a is a vector of length at least dega + 1, and q is a vector of length at least degq + 1,
+// representing polynomials \sum_i a[i]t^i \in \F_p[t].
+// After this method, a will be a / q.
+// Method will change dega accordingly.
+void quo(unsigned long* a, unsigned long* q, unsigned long p, int & dega, int degq);
+
+
+// NOTE: since we don't know the size of result (the list can be longer than the degree of the polynomial),
+// every entry has to be preinitialized to zero!
+void mult(unsigned long* result, unsigned long* a, unsigned long* b, unsigned long p, int dega, int degb);
+
+
+// g = gcd(a,b).
+// returns deg(g)
+//
+// NOTE: since we don't know the size of g, every entry has to be preinitialized to zero!
+int gcd(unsigned long* g, unsigned long* a, unsigned long* b, unsigned long p, int dega, int degb);
+
+// l = lcm(a,b).
+// returns deg(l)
+//
+// has side effects for a
+//
+// NOTE: since we don't know the size of l, every entry has to be preinitialized to zero!
+int lcm(unsigned long* l, unsigned long* a, unsigned long* b, unsigned long p, int dega, int degb);
+
+
+// method suggested by Hans Schoenemann to multiply elements in finite fields
+// on 32bit and 64bit machines
+static inline unsigned long multMod(unsigned long a, unsigned long b, unsigned long p)
+{
+#if SIZEOF_LONG == 4
+#define ULONG64 (unsigned long long)
+#else
+#define ULONG64 (unsigned long)
+#endif
+  return (unsigned long)((ULONG64 a)*(ULONG64 b) % (ULONG64 p));
+}
+
+#endif // MINPOLY_H
diff --git a/kernel/linear_algebra/test.cc b/kernel/linear_algebra/test.cc
new file mode 100644
index 0000000..bb2c248
--- /dev/null
+++ b/kernel/linear_algebra/test.cc
@@ -0,0 +1,376 @@
+#include <kernel/mod2.h>
+
+#include <omalloc/omalloc.h>
+
+#include <resources/feFopen.h>
+#include <resources/feResource.h>
+
+
+#include <factory/factory.h> // :(
+
+#include <misc/auxiliary.h>
+#include <misc/intvec.h>
+#include <misc/int64vec.h>
+#include <misc/mylimits.h>
+#include <misc/options.h>
+
+#include <reporter/reporter.h>
+
+#include <coeffs/si_gmp.h>
+#include <coeffs/coeffs.h>
+#include <coeffs/numbers.h>
+
+#ifndef PLURAL_INTERNAL_DECLARATIONS
+#define PLURAL_INTERNAL_DECLARATIONS
+#endif
+
+#ifndef PLURAL_INTERNAL_DECLARATIONS_GB_HACK
+#define PLURAL_INTERNAL_DECLARATIONS_GB_HACK
+#endif
+
+#include <polys/nc/gb_hack.h>
+#include <polys/nc/nc.h>
+#include <polys/nc/ncSACache.h>
+#include <polys/nc/ncSAFormula.h>
+#include <polys/nc/ncSAMult.h>
+#include <polys/nc/sca.h>
+#include <polys/nc/summator.h>
+
+#include <polys/kbuckets.h>
+#include <polys/matpol.h>
+#include <polys/mod_raw.h>
+#include <polys/prCopy.h>
+#include <polys/sbuckets.h>
+#include <polys/simpleideals.h>
+#include <polys/weight.h>
+
+#include <polys/monomials/maps.h>
+#include <polys/monomials/monomials.h>
+#include <polys/monomials/p_polys.h>
+#include <polys/monomials/ring.h>
+
+#include <polys/templates/p_MemAdd.h>
+#include <polys/templates/p_Procs.h>
+
+#include <polys/operations/pShallowCopyDelete.h>
+
+#include <polys/clapsing.h>
+
+
+// // TODO: DUE to the use of HALT in npolygon.cc :(((
+extern "C" {void m2_end(int i){exit(i);}}
+
+// // TODO: DUE to its use in kutil.cc :(((
+// char * showOption(){return NULL;}
+
+
+// #include "structs.h"
+
+
+// HEADERS:
+#include <kernel/ideals.h>
+#include <kernel/digitech.h>
+#include <kernel/fast_mult.h>
+
+// #include <kernel/spectrum/kmatrix.h>
+#include <kernel/preimage.h>
+
+#include <kernel/structs.h>
+
+#include <kernel/polys.h>
+
+void TestGBEngine()
+{
+
+  //  R = MPolynomialRing_polydict(QQ,5,'w,x,y,z,C', order='degrevlex')
+  //  J = (w*w - x*z, w*x - y*z, x*x - w*y, x*y - z*z, y*y - w*z)
+
+  const short w = 1;
+  const short x = 2;
+  const short y = 3;
+  const short z = 4;
+
+  const short N = (z - w + 1);
+
+  char **n=(char**)omalloc(N*sizeof(char*));
+
+
+  n[w-1]=omStrDup("w");
+  n[x-1]=omStrDup("x");
+  n[y-1]=omStrDup("y");
+  n[z-1]=omStrDup("z");
+
+
+  const int D = 3;
+  int *order = (int *) omAlloc0(D* sizeof(int));
+  int *block0 = (int *)omAlloc0(D * sizeof(int));
+  int *block1 = (int *)omAlloc0(D * sizeof(int));
+
+  order[0]  = ringorder_dp;
+  block0[0] = 1;
+  block1[0] = N;
+
+  order[1]  = ringorder_C;
+  block0[1] = 1;
+  block1[1] = N;
+
+  ring R = rDefault(0, N, n, D, order, block0, block1);
+
+//   ring R = rDefault(0, N, n);
+
+  rWrite(R); PrintLn();
+
+#ifdef RDEBUG
+  rDebugPrint(R);
+#endif
+
+  ideal I = idInit(5, 1);
+
+  int gen = 0;
+
+  {
+    // -xz
+    poly p = p_ISet(-1,R);
+
+    p_SetExp(p, x, 1, R);
+    p_SetExp(p, z, 1, R);
+    p_Setm(p, R);
+
+    assume( p_GetExp(p, x, R) == 1 );
+    assume( p_GetExp(p, z, R) == 1 );
+    assume( p_GetExp(p, w, R) == 0 );
+    assume( p_GetExp(p, y, R) == 0 );
+
+    // +w2
+    poly lp = p_ISet(1,R);
+    p_SetExp(lp, w, 2, R);
+    p_Setm(lp, R);
+
+    assume( p_GetExp(lp, w, R) == 2 );
+    assume( p_GetExp(lp, x, R) == 0 );
+    assume( p_GetExp(lp, y, R) == 0 );
+    assume( p_GetExp(lp, z, R) == 0 );
+
+    MATELEM(I, 1, ++gen) = p_Add_q(lp, p, R); // w2 - xz
+  }
+
+  {
+    // -yz
+    poly p = p_ISet(-1,R);
+
+    p_SetExp(p, y, 1, R);
+    p_SetExp(p, z, 1, R);
+    p_Setm(p, R);
+
+    assume( p_GetExp(p, y, R) == 1 );
+    assume( p_GetExp(p, z, R) == 1 );
+    assume( p_GetExp(p, w, R) == 0 );
+    assume( p_GetExp(p, x, R) == 0 );
+
+    // +wx
+    poly lp = p_ISet(1,R);
+    p_SetExp(lp, w, 1, R);
+    p_SetExp(lp, x, 1, R);
+    p_Setm(lp, R);
+
+    assume( p_GetExp(lp, w, R) == 1 );
+    assume( p_GetExp(lp, x, R) == 1 );
+    assume( p_GetExp(lp, y, R) == 0 );
+    assume( p_GetExp(lp, z, R) == 0 );
+
+    MATELEM(I, 1, ++gen) = p_Add_q(lp, p, R); // wx - yz
+  }
+
+
+  {
+    // -wy
+    poly p = p_ISet(-1,R);
+
+    p_SetExp(p, y, 1, R);
+    p_SetExp(p, w, 1, R);
+    p_Setm(p, R);
+
+    assume( p_GetExp(p, y, R) == 1 );
+    assume( p_GetExp(p, w, R) == 1 );
+    assume( p_GetExp(p, z, R) == 0 );
+    assume( p_GetExp(p, x, R) == 0 );
+
+    // +x2
+    poly lp = p_ISet(1,R);
+    p_SetExp(lp, x, 2, R);
+    p_Setm(lp, R);
+
+    assume( p_GetExp(lp, w, R) == 0 );
+    assume( p_GetExp(lp, x, R) == 2 );
+    assume( p_GetExp(lp, y, R) == 0 );
+    assume( p_GetExp(lp, z, R) == 0 );
+
+    MATELEM(I, 1, ++gen) = p_Add_q(lp, p, R); // x2 - wy
+  }
+
+
+  {
+    // -z2
+    poly p = p_ISet(-1,R);
+
+    p_SetExp(p, z, 2, R);
+    p_Setm(p, R);
+
+    assume( p_GetExp(p, y, R) == 0 );
+    assume( p_GetExp(p, w, R) == 0 );
+    assume( p_GetExp(p, z, R) == 2 );
+    assume( p_GetExp(p, x, R) == 0 );
+
+    // +xy
+    poly lp = p_ISet(1,R);
+    p_SetExp(lp, x, 1, R);
+    p_SetExp(lp, y, 1, R);
+    p_Setm(lp, R);
+
+    assume( p_GetExp(lp, w, R) == 0 );
+    assume( p_GetExp(lp, x, R) == 1 );
+    assume( p_GetExp(lp, y, R) == 1 );
+    assume( p_GetExp(lp, z, R) == 0 );
+
+    MATELEM(I, 1, ++gen) = p_Add_q(lp, p, R); // xy - z2
+  }
+
+
+  {
+    // -wz
+    poly p = p_ISet(-1,R);
+
+    p_SetExp(p, w, 1, R);
+    p_SetExp(p, z, 1, R);
+    p_Setm(p, R);
+
+    assume( p_GetExp(p, y, R) == 0 );
+    assume( p_GetExp(p, w, R) == 1 );
+    assume( p_GetExp(p, z, R) == 1 );
+    assume( p_GetExp(p, x, R) == 0 );
+
+    // +y2
+    poly lp = p_ISet(1,R);
+    p_SetExp(lp, y, 2, R);
+    p_Setm(lp, R);
+
+    assume( p_GetExp(lp, w, R) == 0 );
+    assume( p_GetExp(lp, x, R) == 0 );
+    assume( p_GetExp(lp, y, R) == 2 );
+    assume( p_GetExp(lp, z, R) == 0 );
+
+    MATELEM(I, 1, ++gen) = p_Add_q(lp, p, R); // y2 - wz
+  }
+#ifdef PDEBUG
+  PrintS("I: ");
+  idShow(I, R, R, 0);
+#endif
+
+
+//  ideal kStd(ideal F, ideal Q, tHomog h, intvec ** mw,intvec *hilb=NULL,
+//             int syzComp=0,int newIdeal=0, intvec *vw=NULL);
+  // make R the default ring:
+  rChangeCurrRing(R);
+
+ ////
+
+  idDelete( &I, R);
+  rDelete(R); // should cleanup every belonging polynomial, right!?
+
+}
+
+
+
+void TestSimpleRingArithmetcs()
+{
+  // Libpolys tests:
+
+  // construct the ring Z/32003[x,y,z]
+  // the variable names
+  char **n=(char**)omalloc(3*sizeof(char*));
+  n[0]=omStrDup("x");
+  n[1]=omStrDup("y");
+  n[2]=omStrDup("z2");
+
+  ring R = rDefault(32003,3,n); //  ring R = rDefault(0,3,n);
+
+  rWrite(R); PrintLn();
+
+#ifdef RDEBUG
+  rDebugPrint(R);
+#endif
+
+
+  poly p = p_ISet(1,R); p_SetExp(p,1,1, R); p_Setm(p, R);
+
+  assume( p_GetExp(p,1, R) == 1 );
+
+  poly pp = pp_Mult_qq( p, p, R);
+
+  Print("p: "); p_Write0(p, R); Print(", deg(p): %ld", p_Totaldegree(p, R)); assume( 1 == p_Totaldegree(p, R) );
+
+  Print("; p*p : "); p_Write0(pp, R); Print("deg(pp): %ld\n", p_Totaldegree(pp, R)); assume( 2 == p_Totaldegree(pp, R) );
+
+
+  p_Delete(&p, R);
+
+  assume( p_GetExp(pp,1, R) == 2 );
+
+  p_Delete(&pp, R);
+
+
+//  rDelete(R);
+
+  // make R the default ring:
+  rChangeCurrRing(R);
+
+  // create the polynomial 1
+  poly p1=pISet(1);
+
+  // create tthe polynomial 2*x^3*z^2
+  poly p2=p_ISet(2,R);
+  pSetExp(p2,1,3);
+  pSetExp(p2,3,2);
+  pSetm(p2);
+
+  // print p1 + p2
+  Print("p1: "); pWrite0(p1);
+  Print(" + p2: "); pWrite0(p2);
+  Print("  ---- >>>> ");
+
+  // compute p1+p2
+  p1=p_Add_q(p1,p2,R); p2=NULL;
+  pWrite(p1);
+
+  // clean up:
+//  pDelete(&p1);
+
+  rDelete(R); // should cleanup every belonging polynomial, right!?
+}
+
+
+int main( int, char *argv[] )
+{
+  assume( sizeof(long) == SIZEOF_LONG );
+
+  if( sizeof(long) != SIZEOF_LONG )
+  {
+    WerrorS("Bad config.h: wrong size of long!");
+
+    return(1);
+  }
+
+
+  feInitResources(argv[0]);
+
+  StringSetS("ressources in use (as reported by feStringAppendResources(0):\n");
+  feStringAppendResources(0);
+
+  PrintLn();
+  { char* s = StringEndS(); PrintS(s); omFree(s); }
+
+  TestGBEngine();
+  TestSimpleRingArithmetcs();
+
+  return 0;
+}
diff --git a/kernel/maps/Makefile.am b/kernel/maps/Makefile.am
new file mode 100644
index 0000000..aecc6b3
--- /dev/null
+++ b/kernel/maps/Makefile.am
@@ -0,0 +1,22 @@
+ACLOCAL_AMFLAGS=-I ../../m4
+AM_CPPFLAGS=-I${top_srcdir} -I${top_builddir} -I${top_srcdir}/libpolys -I${top_builddir}/libpolys \
+${FACTORY_INCLUDES} $(OMALLOC_INCLUDES) $(RESOURCES_INCLUDES) \
+${NTL_CFLAGS} $(FLINT_CFLAGS) ${GMP_CFLAGS}
+
+noinst_LTLIBRARIES=libmaps.la
+libmaps_la_SOURCES=fast_maps.cc
+
+libmaps_la_includedir=$(includedir)/singular/kernel/maps
+libmaps_la_include_HEADERS=fast_maps.h
+
+
+
+TESTS_ENVIRONMENT = SINGULARPATH='${abs_top_builddir}/libpolys/polys/.libs:${abs_top_builddir}/factory/gftables'
+TESTS_ENVIRONMENT += SINGULAR_ROOT_DIR='${abs_top_builddir}'
+
+TESTS = test
+check_PROGRAMS = $(TESTS)
+test_SOURCES = test.cc
+test_LDADD   = libmaps.la ${builddir}/../libkernelCommon.la
+
+CLEANFILES = $(TESTS)
diff --git a/kernel/maps/Makefile.in b/kernel/maps/Makefile.in
new file mode 100644
index 0000000..b8037bd
--- /dev/null
+++ b/kernel/maps/Makefile.in
@@ -0,0 +1,1081 @@
+# Makefile.in generated by automake 1.13.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 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@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+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@
+TESTS = test$(EXEEXT)
+check_PROGRAMS = $(am__EXEEXT_1)
+subdir = kernel/maps
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/build-aux/depcomp $(libmaps_la_include_HEADERS) \
+	$(top_srcdir)/build-aux/test-driver
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_append_compile_flags.m4 \
+	$(top_srcdir)/m4/ax_append_flag.m4 \
+	$(top_srcdir)/m4/ax_append_link_flags.m4 \
+	$(top_srcdir)/m4/ax_check_compile_flag.m4 \
+	$(top_srcdir)/m4/ax_check_link_flag.m4 \
+	$(top_srcdir)/m4/ax_compute_relative_paths.m4 \
+	$(top_srcdir)/m4/ax_normalize_path.m4 \
+	$(top_srcdir)/m4/ax_prefix_config_h.m4 \
+	$(top_srcdir)/m4/ax_pthread.m4 \
+	$(top_srcdir)/m4/ax_python_embed.m4 \
+	$(top_srcdir)/m4/ax_python_with_version.m4 \
+	$(top_srcdir)/m4/cpu-check.m4 $(top_srcdir)/m4/dbm-check.m4 \
+	$(top_srcdir)/m4/flags.m4 $(top_srcdir)/m4/flint-check.m4 \
+	$(top_srcdir)/m4/gfanlib-check.m4 \
+	$(top_srcdir)/m4/gmp-check.m4 \
+	$(top_srcdir)/m4/google-perftools.m4 \
+	$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+	$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+	$(top_srcdir)/m4/lt~obsolete.m4 \
+	$(top_srcdir)/m4/mathic-check.m4 $(top_srcdir)/m4/ntl-check.m4 \
+	$(top_srcdir)/m4/options.m4 $(top_srcdir)/m4/p-procs.m4 \
+	$(top_srcdir)/m4/polymake-check.m4 \
+	$(top_srcdir)/m4/readline-check.m4 $(top_srcdir)/configure.ac
+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 =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+libmaps_la_LIBADD =
+am_libmaps_la_OBJECTS = fast_maps.lo
+libmaps_la_OBJECTS = $(am_libmaps_la_OBJECTS)
+AM_V_lt = $(am__v_lt_ at AM_V@)
+am__v_lt_ = $(am__v_lt_ at AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 = 
+am__EXEEXT_1 = test$(EXEEXT)
+am_test_OBJECTS = test.$(OBJEXT)
+test_OBJECTS = $(am_test_OBJECTS)
+test_DEPENDENCIES = libmaps.la ${builddir}/../libkernelCommon.la
+AM_V_P = $(am__v_P_ at AM_V@)
+am__v_P_ = $(am__v_P_ at AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_ at AM_V@)
+am__v_GEN_ = $(am__v_GEN_ at AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_ at AM_V@)
+am__v_at_ = $(am__v_at_ at AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+DEFAULT_INCLUDES = -I. at am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \
+	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+	$(AM_CXXFLAGS) $(CXXFLAGS)
+AM_V_CXX = $(am__v_CXX_ at AM_V@)
+am__v_CXX_ = $(am__v_CXX_ at AM_DEFAULT_V@)
+am__v_CXX_0 = @echo "  CXX     " $@;
+am__v_CXX_1 = 
+CXXLD = $(CXX)
+CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+	$(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CXXLD = $(am__v_CXXLD_ at AM_V@)
+am__v_CXXLD_ = $(am__v_CXXLD_ at AM_DEFAULT_V@)
+am__v_CXXLD_0 = @echo "  CXXLD   " $@;
+am__v_CXXLD_1 = 
+SOURCES = $(libmaps_la_SOURCES) $(test_SOURCES)
+DIST_SOURCES = $(libmaps_la_SOURCES) $(test_SOURCES)
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+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__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
+am__installdirs = "$(DESTDIR)$(libmaps_la_includedir)"
+HEADERS = $(libmaps_la_include_HEADERS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors_dummy = \
+  mgn= red= grn= lgn= blu= brg= std=; \
+  am__color_tests=no
+am__tty_colors = { \
+  $(am__tty_colors_dummy); \
+  if test "X$(AM_COLOR_TESTS)" = Xno; then \
+    am__color_tests=no; \
+  elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+    am__color_tests=yes; \
+  elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+    am__color_tests=yes; \
+  fi; \
+  if test $$am__color_tests = yes; then \
+    red=''; \
+    grn=''; \
+    lgn=''; \
+    blu=''; \
+    mgn=''; \
+    brg=''; \
+    std=''; \
+  fi; \
+}
+am__recheck_rx = ^[ 	]*:recheck:[ 	]*
+am__global_test_result_rx = ^[ 	]*:global-test-result:[ 	]*
+am__copy_in_global_log_rx = ^[ 	]*:copy-in-global-log:[ 	]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+  recheck = 1; \
+  while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+    { \
+      if (rc < 0) \
+        { \
+          if ((getline line2 < ($$0 ".log")) < 0) \
+	    recheck = 0; \
+          break; \
+        } \
+      else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+        { \
+          recheck = 0; \
+          break; \
+        } \
+      else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+        { \
+          break; \
+        } \
+    }; \
+  if (recheck) \
+    print $$0; \
+  close ($$0 ".trs"); \
+  close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+  print "fatal: making $@: " msg | "cat >&2"; \
+  exit 1; \
+} \
+function rst_section(header) \
+{ \
+  print header; \
+  len = length(header); \
+  for (i = 1; i <= len; i = i + 1) \
+    printf "="; \
+  printf "\n\n"; \
+} \
+{ \
+  copy_in_global_log = 1; \
+  global_test_result = "RUN"; \
+  while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+    { \
+      if (rc < 0) \
+         fatal("failed to read from " $$0 ".trs"); \
+      if (line ~ /$(am__global_test_result_rx)/) \
+        { \
+          sub("$(am__global_test_result_rx)", "", line); \
+          sub("[ 	]*$$", "", line); \
+          global_test_result = line; \
+        } \
+      else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+        copy_in_global_log = 0; \
+    }; \
+  if (copy_in_global_log) \
+    { \
+      rst_section(global_test_result ": " $$0); \
+      while ((rc = (getline line < ($$0 ".log"))) != 0) \
+      { \
+        if (rc < 0) \
+          fatal("failed to read from " $$0 ".log"); \
+        print line; \
+      }; \
+      printf "\n"; \
+    }; \
+  close ($$0 ".trs"); \
+  close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/   &   /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this.  Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+  --color-tests "$$am__color_tests" \
+  --enable-hard-errors "$$am__enable_hard_errors" \
+  --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test.  Creates the
+# directory for the log if needed.  Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log.  Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT.  Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup);					\
+$(am__vpath_adj_setup) $(am__vpath_adj)			\
+$(am__tty_colors);					\
+srcdir=$(srcdir); export srcdir;			\
+case "$@" in						\
+  */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;;	\
+    *) am__odir=.;; 					\
+esac;							\
+test "x$$am__odir" = x"." || test -d "$$am__odir" 	\
+  || $(MKDIR_P) "$$am__odir" || exit $$?;		\
+if test -f "./$$f"; then dir=./;			\
+elif test -f "$$f"; then dir=;				\
+else dir="$(srcdir)/"; fi;				\
+tst=$$dir$$f; log='$@'; 				\
+if test -n '$(DISABLE_HARD_ERRORS)'; then		\
+  am__enable_hard_errors=no; 				\
+else							\
+  am__enable_hard_errors=yes; 				\
+fi; 							\
+case " $(XFAIL_TESTS) " in				\
+  *[\ \	]$$f[\ \	]* | *[\ \	]$$dir$$f[\ \	]*) \
+    am__expect_failure=yes;;				\
+  *)							\
+    am__expect_failure=no;;				\
+esac; 							\
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed).  The result is saved in the shell variable
+# '$bases'.  This honors runtime overriding of TESTS and TEST_LOGS.  Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+  bases='$(TEST_LOGS)'; \
+  bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+  bases=`echo $$bases`
+RECHECK_LOGS = $(TEST_LOGS)
+AM_RECURSIVE_TARGETS = check recheck
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+  case '$@' in \
+    */*) \
+      case '$*' in \
+        */*) b='$*';; \
+          *) b=`echo '$@' | sed 's/\.log$$//'`; \
+       esac;; \
+    *) \
+      b='$*';; \
+  esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT at .log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+	$(TEST_LOG_FLAGS)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BUILTIN_LIBS = @BUILTIN_LIBS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CDDGMPCPPFLAGS = @CDDGMPCPPFLAGS@
+CDDGMPLDFLAGS = @CDDGMPLDFLAGS@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATA_DIR = @DATA_DIR@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DOC_DIR = @DOC_DIR@
+DOXYGEN = @DOXYGEN@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FACTORY_INCLUDES = @FACTORY_INCLUDES@
+FACTORY_LIBS = @FACTORY_LIBS@
+FGREP = @FGREP@
+FLINT_CFLAGS = @FLINT_CFLAGS@
+FLINT_HOME = @FLINT_HOME@
+FLINT_LIBS = @FLINT_LIBS@
+GMP_CFLAGS = @GMP_CFLAGS@
+GMP_HOME = @GMP_HOME@
+GMP_LIBS = @GMP_LIBS@
+GMP_VERSION = @GMP_VERSION@
+GREP = @GREP@
+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@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NTL_CFLAGS = @NTL_CFLAGS@
+NTL_LIBS = @NTL_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OMALLOC_INCLUDES = @OMALLOC_INCLUDES@
+OMALLOC_LIBS = @OMALLOC_LIBS@
+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@
+PKG_REQUIRE = @PKG_REQUIRE@
+PMCONFIG = @PMCONFIG@
+PM_CFLAGS = @PM_CFLAGS@
+PM_INC = @PM_INC@
+PM_LDFLAGS = @PM_LDFLAGS@
+PM_LIBS = @PM_LIBS@
+POLYMAKE_CXXFLAGS = @POLYMAKE_CXXFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LDFLAGS = @PTHREAD_LDFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
+PYTHON = @PYTHON@
+PYTHON_CSPEC = @PYTHON_CSPEC@
+PYTHON_EXECPREFIX = @PYTHON_EXECPREFIX@
+PYTHON_LSPEC = @PYTHON_LSPEC@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+RANLIB = @RANLIB@
+RESOURCES_INCLUDES = @RESOURCES_INCLUDES@
+RESOURCES_LIBS = @RESOURCES_LIBS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SINGULAR_CFLAGS = @SINGULAR_CFLAGS@
+SI_COUNTEDREF_AUTOLOAD = @SI_COUNTEDREF_AUTOLOAD@
+SI_CPU_I386 = @SI_CPU_I386@
+SI_CPU_IA64 = @SI_CPU_IA64@
+SI_CPU_PPC = @SI_CPU_PPC@
+SI_CPU_SPARC = @SI_CPU_SPARC@
+SI_CPU_X86_64 = @SI_CPU_X86_64@
+STRIP = @STRIP@
+USEPPROCSDYNAMICLD = @USEPPROCSDYNAMICLD@
+USEPPROCSDYNAMICLDFLAGS = @USEPPROCSDYNAMICLDFLAGS@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
+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@
+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@
+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@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+ACLOCAL_AMFLAGS = -I ../../m4
+AM_CPPFLAGS = -I${top_srcdir} -I${top_builddir} -I${top_srcdir}/libpolys -I${top_builddir}/libpolys \
+${FACTORY_INCLUDES} $(OMALLOC_INCLUDES) $(RESOURCES_INCLUDES) \
+${NTL_CFLAGS} $(FLINT_CFLAGS) ${GMP_CFLAGS}
+
+noinst_LTLIBRARIES = libmaps.la
+libmaps_la_SOURCES = fast_maps.cc
+libmaps_la_includedir = $(includedir)/singular/kernel/maps
+libmaps_la_include_HEADERS = fast_maps.h
+TESTS_ENVIRONMENT = SINGULARPATH='${abs_top_builddir}/libpolys/polys/.libs:${abs_top_builddir}/factory/gftables' \
+	SINGULAR_ROOT_DIR='${abs_top_builddir}'
+test_SOURCES = test.cc
+test_LDADD = libmaps.la ${builddir}/../libkernelCommon.la
+CLEANFILES = $(TESTS)
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .cc .lo .log .o .obj .test .test$(EXEEXT) .trs
+$(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) --foreign kernel/maps/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign kernel/maps/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-noinstLTLIBRARIES:
+	-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+	@list='$(noinst_LTLIBRARIES)'; \
+	locs=`for p in $$list; do echo $$p; done | \
+	      sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+	      sort -u`; \
+	test -z "$$locs" || { \
+	  echo rm -f $${locs}; \
+	  rm -f $${locs}; \
+	}
+
+libmaps.la: $(libmaps_la_OBJECTS) $(libmaps_la_DEPENDENCIES) $(EXTRA_libmaps_la_DEPENDENCIES) 
+	$(AM_V_CXXLD)$(CXXLINK)  $(libmaps_la_OBJECTS) $(libmaps_la_LIBADD) $(LIBS)
+
+clean-checkPROGRAMS:
+	@list='$(check_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
+
+test$(EXEEXT): $(test_OBJECTS) $(test_DEPENDENCIES) $(EXTRA_test_DEPENDENCIES) 
+	@rm -f test$(EXEEXT)
+	$(AM_V_CXXLD)$(CXXLINK) $(test_OBJECTS) $(test_LDADD) $(LIBS)
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/fast_maps.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/test.Po at am__quote@
+
+.cc.o:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+ at am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXXCOMPILE) -c -o $@ $<
+
+.cc.obj:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+ at am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.cc.lo:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+ at am__fastdepCXX_TRUE@	$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LTCXXCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+install-libmaps_la_includeHEADERS: $(libmaps_la_include_HEADERS)
+	@$(NORMAL_INSTALL)
+	@list='$(libmaps_la_include_HEADERS)'; test -n "$(libmaps_la_includedir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(libmaps_la_includedir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(libmaps_la_includedir)" || exit 1; \
+	fi; \
+	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)$(libmaps_la_includedir)'"; \
+	  $(INSTALL_HEADER) $$files "$(DESTDIR)$(libmaps_la_includedir)" || exit $$?; \
+	done
+
+uninstall-libmaps_la_includeHEADERS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(libmaps_la_include_HEADERS)'; test -n "$(libmaps_la_includedir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	dir='$(DESTDIR)$(libmaps_la_includedir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	$(am__define_uniq_tagged_files); \
+	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-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	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"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'.  Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+	rm -f $< $@
+	$(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+	@:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+	@$(am__set_TESTS_bases); \
+	am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+	redo_bases=`for i in $$bases; do \
+	              am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+	            done`; \
+	if test -n "$$redo_bases"; then \
+	  redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+	  redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+	  if $(am__make_dryrun); then :; else \
+	    rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+	  fi; \
+	fi; \
+	if test -n "$$am__remaking_logs"; then \
+	  echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+	       "recursion detected" >&2; \
+	else \
+	  am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+	fi; \
+	if $(am__make_dryrun); then :; else \
+	  st=0;  \
+	  errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+	  for i in $$redo_bases; do \
+	    test -f $$i.trs && test -r $$i.trs \
+	      || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+	    test -f $$i.log && test -r $$i.log \
+	      || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+	  done; \
+	  test $$st -eq 0 || exit 1; \
+	fi
+	@$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+	ws='[ 	]'; \
+	results=`for b in $$bases; do echo $$b.trs; done`; \
+	test -n "$$results" || results=/dev/null; \
+	all=`  grep "^$$ws*:test-result:"           $$results | wc -l`; \
+	pass=` grep "^$$ws*:test-result:$$ws*PASS"  $$results | wc -l`; \
+	fail=` grep "^$$ws*:test-result:$$ws*FAIL"  $$results | wc -l`; \
+	skip=` grep "^$$ws*:test-result:$$ws*SKIP"  $$results | wc -l`; \
+	xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+	xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+	error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+	if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+	  success=true; \
+	else \
+	  success=false; \
+	fi; \
+	br='==================='; br=$$br$$br$$br$$br; \
+	result_count () \
+	{ \
+	    if test x"$$1" = x"--maybe-color"; then \
+	      maybe_colorize=yes; \
+	    elif test x"$$1" = x"--no-color"; then \
+	      maybe_colorize=no; \
+	    else \
+	      echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+	    fi; \
+	    shift; \
+	    desc=$$1 count=$$2; \
+	    if test $$maybe_colorize = yes && test $$count -gt 0; then \
+	      color_start=$$3 color_end=$$std; \
+	    else \
+	      color_start= color_end=; \
+	    fi; \
+	    echo "$${color_start}# $$desc $$count$${color_end}"; \
+	}; \
+	create_testsuite_report () \
+	{ \
+	  result_count $$1 "TOTAL:" $$all   "$$brg"; \
+	  result_count $$1 "PASS: " $$pass  "$$grn"; \
+	  result_count $$1 "SKIP: " $$skip  "$$blu"; \
+	  result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+	  result_count $$1 "FAIL: " $$fail  "$$red"; \
+	  result_count $$1 "XPASS:" $$xpass "$$red"; \
+	  result_count $$1 "ERROR:" $$error "$$mgn"; \
+	}; \
+	{								\
+	  echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" |	\
+	    $(am__rst_title);						\
+	  create_testsuite_report --no-color;				\
+	  echo;								\
+	  echo ".. contents:: :depth: 2";				\
+	  echo;								\
+	  for b in $$bases; do echo $$b; done				\
+	    | $(am__create_global_log);					\
+	} >$(TEST_SUITE_LOG).tmp || exit 1;				\
+	mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG);			\
+	if $$success; then						\
+	  col="$$grn";							\
+	 else								\
+	  col="$$red";							\
+	  test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG);		\
+	fi;								\
+	echo "$${col}$$br$${std}"; 					\
+	echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}";	\
+	echo "$${col}$$br$${std}"; 					\
+	create_testsuite_report --maybe-color;				\
+	echo "$$col$$br$$std";						\
+	if $$success; then :; else					\
+	  echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}";		\
+	  if test -n "$(PACKAGE_BUGREPORT)"; then			\
+	    echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}";	\
+	  fi;								\
+	  echo "$$col$$br$$std";					\
+	fi;								\
+	$$success || exit 1
+
+check-TESTS:
+	@list='$(RECHECK_LOGS)';           test -z "$$list" || rm -f $$list
+	@list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+	@test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+	@set +e; $(am__set_TESTS_bases); \
+	log_list=`for i in $$bases; do echo $$i.log; done`; \
+	trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+	log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+	$(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+	exit $$?;
+recheck: all $(check_PROGRAMS)
+	@test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+	@set +e; $(am__set_TESTS_bases); \
+	bases=`for i in $$bases; do echo $$i; done \
+	         | $(am__list_recheck_tests)` || exit 1; \
+	log_list=`for i in $$bases; do echo $$i.log; done`; \
+	log_list=`echo $$log_list`; \
+	$(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+	        am__force_recheck=am--force-recheck \
+	        TEST_LOGS="$$log_list"; \
+	exit $$?
+test.log: test$(EXEEXT)
+	@p='test$(EXEEXT)'; \
+	b='test'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+.test.log:
+	@p='$<'; \
+	$(am__set_b); \
+	$(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+ at am__EXEEXT_TRUE@.test$(EXEEXT).log:
+ at am__EXEEXT_TRUE@	@p='$<'; \
+ at am__EXEEXT_TRUE@	$(am__set_b); \
+ at am__EXEEXT_TRUE@	$(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ at am__EXEEXT_TRUE@	--log-file $$b.log --trs-file $$b.trs \
+ at am__EXEEXT_TRUE@	$(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ at am__EXEEXT_TRUE@	"$$tst" $(AM_TESTS_FD_REDIRECT)
+
+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_PROGRAMS)
+	$(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(HEADERS)
+installdirs:
+	for dir in "$(DESTDIR)$(libmaps_la_includedir)"; 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:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+	-test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+	-test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+	-test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+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-checkPROGRAMS clean-generic clean-libtool \
+	clean-noinstLTLIBRARIES 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-libmaps_la_includeHEADERS
+
+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: uninstall-libmaps_la_includeHEADERS
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am clean \
+	clean-checkPROGRAMS clean-generic clean-libtool \
+	clean-noinstLTLIBRARIES cscopelist-am ctags ctags-am 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-libmaps_la_includeHEADERS 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 \
+	recheck tags tags-am uninstall uninstall-am \
+	uninstall-libmaps_la_includeHEADERS
+
+
+# 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/kernel/maps/fast_maps.cc b/kernel/maps/fast_maps.cc
new file mode 100644
index 0000000..c92e319
--- /dev/null
+++ b/kernel/maps/fast_maps.cc
@@ -0,0 +1,741 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    fast_maps.cc
+ *  Purpose: implementation of fast maps
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 02/01
+ *******************************************************************/
+
+
+
+#include <kernel/mod2.h>
+#include <omalloc/omalloc.h>
+#include <misc/options.h>
+#include <polys/monomials/p_polys.h>
+#include <polys/prCopy.h>
+#include <kernel/ideals.h>
+#include <polys/monomials/ring.h>
+#include <polys/sbuckets.h>
+#include <kernel/maps/fast_maps.h>
+
+// define if you want to use special dest_ring
+#define HAVE_DEST_R 1
+// define if you want to use special src_ring
+#define HAVE_SRC_R 1
+// define if you want to use optimization step
+#define HAVE_MAP_OPTIMIZE 1
+
+/*******************************************************************************
+**
+*F  maMaxExp  . . . . . . . .  returns bound on maximal exponent of result of map
+*/
+// return maximal monomial if max_map_monomials are substituted into pi_m
+static poly maGetMaxExpP(poly* max_map_monomials,
+                         int n_max_map_monomials, ring map_r,
+                         poly pi_m, ring pi_r)
+{
+  int n = si_min(pi_r->N, n_max_map_monomials);
+  int i, j;
+  unsigned long e_i, e_j;
+  poly m_i=NULL;
+  poly map_j = p_Init(map_r);
+
+  for (i=1; i <= n; i++)
+  {
+    e_i = p_GetExp(pi_m, i, pi_r);
+    if (e_i==0) e_i=1;
+    m_i = max_map_monomials[i-1];
+    if (m_i != NULL && ! p_IsConstantComp(m_i, map_r))
+    {
+      for (j = 1; j<= map_r->N; j++)
+      {
+        e_j = p_GetExp(m_i, j, map_r);
+        if (e_j == 0) e_j=1;
+        p_AddExp(map_j, j, e_j*e_i, map_r);
+      }
+    }
+  }
+  return map_j;
+}
+
+// returns maximal exponent if map_id is applied to pi_id
+static unsigned long maGetMaxExp(ideal pi_id, ring pi_r, ideal map_id, ring map_r)
+{
+  unsigned long max=0;
+  poly* max_map_monomials = (poly*) omAlloc(IDELEMS(map_id)*sizeof(poly));
+  poly max_pi_i, max_map_i;
+
+  int i;
+  for (i=0; i<IDELEMS(map_id); i++)
+  {
+    max_map_monomials[i] = p_GetMaxExpP(map_id->m[i], map_r);
+  }
+
+  for (i=0; i<IDELEMS(pi_id); i++)
+  {
+    max_pi_i = p_GetMaxExpP(pi_id->m[i], pi_r);
+    max_map_i = maGetMaxExpP(max_map_monomials, IDELEMS(map_id), map_r,
+                              max_pi_i, pi_r);
+    unsigned long temp = p_GetMaxExp(max_map_i, map_r);
+    if (temp > max){ max=temp; }
+
+    p_LmFree(max_pi_i, pi_r);
+    p_LmFree(max_map_i, map_r);
+  }
+  for (i=0; i<IDELEMS(map_id); i++)
+  {
+    p_Delete(&max_map_monomials[i], map_r);
+  }
+  omFreeSize(max_map_monomials,IDELEMS(map_id)*sizeof(poly));
+
+  return max;
+}
+
+
+/*******************************************************************************
+**
+*F  debugging stuff
+*/
+#ifndef SING_NDEBUG
+void maMonomial_Out(mapoly monomial, ring src_r, ring dest_r)
+{
+  p_wrp(monomial->src, src_r);
+  printf(" ref:%d", monomial->ref);
+  if (dest_r != NULL)
+  {
+    printf(" dest:");
+    p_wrp(monomial->dest, dest_r);
+  }
+  if (monomial->f1!=NULL) { printf(" f1:%lx", (long)monomial->f1->src);
+                            // p_wrp(monomial->f1->src, src_r);
+                          }
+  if (monomial->f2!=NULL) { printf(" f2:%lx",(long)monomial->f2->src);
+                            // p_wrp(monomial->f2->src, src_r);
+                          }
+  printf("\n");
+  fflush(stdout);
+}
+
+void maPoly_Out(mapoly mpoly, ring src_r, ring dest_r)
+{
+  while (mpoly != NULL)
+  {
+    maMonomial_Out(mpoly, src_r, dest_r);
+    mpoly = mpoly->next;
+  }
+}
+#endif
+
+/*******************************************************************************
+**
+*F  mapolyCreate  . . . . . . . . . . . . . . .  Creates mapoly
+*/
+static omBin mapolyBin = omGetSpecBin(sizeof(mapoly_s));
+static omBin macoeffBin = omGetSpecBin(sizeof(macoeff_s));
+
+mapoly maMonomial_Create(poly p, ring /*r_p*/, sBucket_pt bucket)
+{
+  mapoly mp = (mapoly) omAlloc0Bin(mapolyBin);
+  //p_wrp(p,r_p);printf(" (%x) created\n",mp);
+  mp->src = p;
+  p->next = NULL;
+
+  if (bucket != NULL)
+  {
+    mp->coeff = (macoeff) omAlloc0Bin(macoeffBin);
+    mp->coeff->bucket = bucket;
+    mp->coeff->n = pGetCoeff(p);
+  }
+  mp->ref = 1;
+  return mp;
+}
+
+void maMonomial_Destroy(mapoly mp, ring src_r, ring dest_r)
+{
+  if (mp != NULL)
+  {
+    p_LmFree(mp->src, src_r);
+    if (mp->coeff != NULL)
+    {
+      macoeff coeff, next = mp->coeff;
+      do
+      {
+        coeff = next;
+        next = coeff->next;
+        omFreeBin(coeff, macoeffBin);
+      }
+      while (next != NULL);
+      if (mp->dest != NULL)
+      {
+        assume(dest_r != NULL);
+        p_Delete(&(mp->dest), dest_r);
+      }
+    }
+  }
+  omFreeBin(mp, mapolyBin);
+}
+
+/*******************************************************************************
+**
+*F  maPoly_InsertMonomial . . . . . . . . .insertion of a monomial into mapoly
+*/
+mapoly maPoly_InsertMonomial(mapoly &into, mapoly what, ring src_r)
+{
+  if (into == NULL)
+  {
+    into = what;
+    return what;
+  }
+
+  mapoly iter = into;
+  mapoly prev = NULL;
+
+  Top:
+  p_LmCmpAction(iter->src, what->src, src_r, goto Equal, goto Greater, goto Smaller);
+
+  Greater:
+  if (iter->next == NULL)
+  {
+    iter->next = what;
+    return what;
+  }
+  prev = iter;
+  iter = iter->next;
+  goto Top;
+
+  Smaller:
+  if (prev == NULL)
+  {
+    into = what;
+    what->next = iter;
+    return what;
+  }
+  prev->next = what;
+  what->next = iter;
+  return what;
+
+  Equal:
+  iter->ref += what->ref;
+  macoeff coeff = what->coeff;
+  if (coeff != NULL)
+  {
+    while (coeff->next != NULL) coeff = coeff->next;
+    coeff->next = iter->coeff;
+    iter->coeff = what->coeff;
+    what->coeff = NULL;
+  }
+  maMonomial_Free(what, src_r);
+  return iter;
+}
+
+mapoly maPoly_InsertMonomial(mapoly &into, poly p, ring src_r, sBucket_pt bucket)
+{
+  return maPoly_InsertMonomial(into, maMonomial_Create(p, src_r, bucket), src_r);
+}
+
+static void maPoly_InsertPoly(mapoly &into, poly what, ring src_r, sBucket_pt bucket)
+{
+  poly next;
+
+  while (what != NULL)
+  {
+    next = what->next;
+    maPoly_InsertMonomial(into, what, src_r, bucket);
+    what = next;
+  }
+}
+
+/*******************************************************************************
+**
+*F  maMap_Create . . . . . . . . . . . . . . . . . . . . create stuff
+*/
+
+void maMap_CreatePolyIdeal(ideal map_id, ring map_r, ring src_r, ring dest_r,
+                           mapoly &mp, maideal &mideal)
+{
+  mideal = (maideal) omAlloc0(sizeof(maideal_s));
+  mideal->n = IDELEMS(map_id);
+  mideal->buckets = (sBucket_pt*) omAlloc0(mideal->n*sizeof(sBucket_pt));
+  int i;
+  mp = NULL;
+
+  for (i=0; i<mideal->n; i++)
+  {
+    if (map_id->m[i] != NULL)
+    {
+      mideal->buckets[i] = sBucketCreate(dest_r);
+      maPoly_InsertPoly(mp,
+#ifdef PDEBUG
+                        prShallowCopyR(map_id->m[i], map_r, src_r),
+#else
+                        prShallowCopyR_NoSort(map_id->m[i], map_r, src_r),
+#endif
+                        src_r,
+                        mideal->buckets[i]);
+    }
+  }
+}
+
+void maMap_CreateRings(ideal map_id, ring map_r,
+                       ideal image_id, ring image_r,
+                       ring &src_r, ring &dest_r, BOOLEAN &simple)
+{
+#if HAVE_SRC_R > 0
+  int* weights = (int*) omAlloc0(map_r->N*sizeof(int));
+  int i;
+  int n = si_min(map_r->N, IDELEMS(image_id));
+
+  for (i=0; i<n; i++)
+  {
+    weights[i] = pLength(image_id->m[i])+1;
+  }
+  src_r = rModifyRing_Wp(map_r, weights);
+#else
+  src_r = map_r;
+#endif
+
+#if HAVE_DEST_R > 0
+  unsigned long maxExp = maGetMaxExp(map_id, map_r, image_id, image_r);
+  if (maxExp <=  1) maxExp = 2;
+  else if (maxExp > (unsigned long) image_r->bitmask)
+    maxExp = (unsigned long) image_r->bitmask;
+  dest_r = rModifyRing_Simple(image_r, TRUE, TRUE, maxExp,  simple);
+#else
+  dest_r = image_r;
+#endif
+}
+
+static void maMap_KillRings(ring map_r, ring image_r, ring src_r, ring dest_r)
+{
+  if (map_r != src_r)
+    rKillModified_Wp_Ring(src_r);
+  if (image_r != dest_r)
+    rKillModifiedRing_Simple(dest_r);
+}
+
+/*******************************************************************************
+**
+*F  misc  . . . . . . . . . . . . . . . . . . . . . . . . . . . .  misc  stuff
+*/
+
+ideal maIdeal_2_Ideal(maideal m_id, ring /*dest_r*/)
+{
+  ideal res = idInit(m_id->n, 1);
+  int l;
+
+  for (int i= 0; i < m_id->n; i++)
+  {
+    if (m_id->buckets[i]!=NULL)
+      sBucketDestroyAdd(m_id->buckets[i], &(res->m[i]), &l);
+  }
+  omFreeSize(m_id->buckets,m_id->n*sizeof(sBucket_pt));
+  omFree(m_id);
+  return res;
+}
+
+void maPoly_GetLength(mapoly mp, int &length)
+{
+  length = 0;
+  while (mp != NULL)
+  {
+    length++;
+    mp = mp->next;
+  }
+}
+
+
+/*******************************************************************************
+**
+*F  fast_map  . . . . . . . . . . . . . . . . . . . . . . . . . .the real thing
+*/
+
+ideal fast_map(ideal map_id, ring map_r, ideal image_id, ring image_r)
+{
+  ring src_r, dest_r;
+  ideal dest_id/*, res_id*/;
+  int length = 0;
+  BOOLEAN no_sort;
+
+  // construct rings we work in:
+  // src_r: Wp with Weights set to length of poly in image_id
+  // dest_r: Simple ring without degree ordering and short exponents
+  maMap_CreateRings(map_id, map_r, image_id, image_r, src_r, dest_r, no_sort);
+
+  // construct dest_id
+  if (dest_r != image_r)
+  {
+    dest_id = idrShallowCopyR(image_id, image_r, dest_r);
+  }
+  else
+    dest_id = image_id;
+
+  // construct mpoly and mideal
+  mapoly mp;
+  maideal mideal;
+  maMap_CreatePolyIdeal(map_id, map_r, src_r, dest_r, mp, mideal);
+
+  if (TEST_OPT_PROT)
+  {
+    maPoly_GetLength(mp, length);
+    Print("map[%ld:%d]{%d:", dest_r->bitmask, dest_r->ExpL_Size, length);
+  }
+
+  // do the optimization step
+#if HAVE_MAP_OPTIMIZE > 0
+  if (mp!=NULL) maPoly_Optimize(mp, src_r);
+#endif
+  if (TEST_OPT_PROT)
+  {
+    maPoly_GetLength(mp, length);
+    Print("%d}", length);
+  }
+
+  // do the actual evaluation
+  maPoly_Eval(mp, src_r, dest_id, dest_r, length);
+  if (TEST_OPT_PROT) Print(".");
+
+  // collect the results back into an ideal
+  ideal res_dest_id = maIdeal_2_Ideal(mideal, dest_r);
+  if (TEST_OPT_PROT) Print(".");
+
+  // convert result back to image_r
+  ideal res_image_id;
+  if (dest_r != image_r)
+  {
+    //if (no_sort) see Old/m134si.tst
+    //  res_image_id = idrShallowCopyR_NoSort(res_dest_id, dest_r, image_r);
+    //else
+      res_image_id = idrShallowCopyR(res_dest_id, dest_r, image_r);
+    id_ShallowDelete(&res_dest_id, dest_r);
+    id_ShallowDelete(&dest_id,dest_r);
+  }
+  else
+    res_image_id = res_dest_id;
+
+  if (TEST_OPT_PROT) Print(".");
+
+  // clean-up the rings
+  maMap_KillRings(map_r, image_r, src_r, dest_r);
+
+  if (TEST_OPT_PROT)
+    Print("\n");
+
+  idTest(res_image_id);
+  return res_image_id;
+}
+
+
+/**********************************************************************
+* Evaluation stuff                                                    *
+**********************************************************************/
+
+// substitute p everywhere the monomial occours,
+// return the number of substitutions
+static int maPoly_Substitute(macoeff c, poly p, ring dest_r)
+{
+  // substitute the monomial: go through macoeff
+  int len;
+  BOOLEAN zero_div= (rField_is_Ring(dest_r) && !rField_is_Domain(dest_r));
+  if (!zero_div) len=pLength(p);
+  int done=0;
+  while (c!=NULL)
+  {
+    done++;
+    poly t=pp_Mult_nn(p,c->n,dest_r);
+    #ifdef HAVE_RINGS
+    if (zero_div) len=pLength(t);
+    #endif
+    sBucket_Add_p(c->bucket, t, len);
+    c=c->next;
+  }
+  return done;
+}
+
+static poly maPoly_EvalMon(poly src, ring src_r, poly* dest_id, ring dest_r)
+{
+  int i;
+  int e;
+  poly p=NULL;
+  poly pp;
+  BOOLEAN is_const=TRUE; // to check for zero-div in p_Mult_q
+  for(i=1;i<=src_r->N;i++)
+  {
+    e=p_GetExp(src,i,src_r);
+    if (e>0)
+    {
+      is_const=FALSE;
+      pp=dest_id[i-1];
+      if (pp==NULL)
+      {
+        p_Delete(&p,dest_r);
+        return NULL;
+      }
+      if (/*(*/ p==NULL /*)*/) /* && (e>0)*/
+      {
+        p=p_Copy(pp /*dest_id[i-1]*/,dest_r);
+        e--;
+      }
+      while (e>0)
+      {
+        p=p_Mult_q(p,p_Copy(pp /*dest_id[i-1]*/,dest_r),dest_r);
+        e--;
+      }
+    }
+  }
+  if (is_const)
+  {
+    assume(p==NULL);
+    p=p_ISet(1,dest_r);
+  }
+  return p;
+}
+
+void maPoly_Eval(mapoly root, ring src_r, ideal dest_id, ring dest_r, int total_cost)
+{
+  // invert the list rooted at root:
+  if ((root!=NULL) && (root->next!=NULL))
+  {
+    mapoly q=root->next;
+    mapoly qn;
+    root->next=NULL;
+    do
+    {
+      qn=q->next;
+      q->next=root;
+      root=q;
+      q=qn;
+    }
+    while (qn !=NULL);
+  }
+
+  total_cost /= 10;
+  int next_print_cost = total_cost;
+
+  // the evaluation -----------------------------------------
+  mapoly p=root;
+  int cost = 0;
+
+  while (p!=NULL)
+  {
+    // look at each mapoly: compute its value in ->dest
+    assume (p->dest==NULL);
+    {
+      if ((p->f1!=NULL)&&(p->f2!=NULL))
+      {
+        poly f1=p->f1->dest;
+        poly f2=p->f2->dest;
+        if (p->f1->ref>0) f1=p_Copy(f1,dest_r);
+        else
+        {
+          // we own p->f1->dest now (in f1)
+          p->f1->dest=NULL;
+        }
+        if (p->f2->ref>0) f2=p_Copy(f2,dest_r);
+        else
+        {
+          // we own p->f2->dest now (in f2)
+          p->f2->dest=NULL;
+        }
+        maMonomial_Free(p->f1,src_r, dest_r);
+        maMonomial_Free(p->f2,src_r, dest_r);
+        p->dest=p_Mult_q(f1,f2,dest_r);
+      } /* factors : 2 */
+      else
+      {
+        assume((p->f1==NULL) && (p->f2==NULL));
+        // no factorization provided, use the classical method:
+        p->dest=maPoly_EvalMon(p->src,src_r,dest_id->m,dest_r);
+      }
+    } /* p->dest==NULL */
+    // substitute the monomial: go through macoeff
+    p->ref -= maPoly_Substitute(p->coeff, p->dest, dest_r);
+    //printf("subst done\n");
+    if (total_cost)
+    {
+      assume(TEST_OPT_PROT);
+      cost++;
+      if (cost > next_print_cost)
+      {
+        Print("-");
+        next_print_cost += total_cost;
+      }
+    }
+
+    mapoly pp=p;
+    p=p->next;
+    //p_wrp(pp->src, src_r);
+    if (pp->ref<=0)
+    {
+      //printf(" (%x) killed\n",pp);
+      maMonomial_Destroy(pp, src_r, dest_r);
+    }
+    //else
+    //  printf(" (%x) not killed, ref=%d\n",pp,pp->ref);
+  }
+}
+
+
+/*******************************************************************************
+**
+*F  maEggt  . . . . . . . . . . . . . . . . . . . . . . . .  returns extended ggt
+*/
+// return NULL if deg(ggt(m1, m2)) < 2
+// else return m = ggT(m1, m2) and q1, q2 such that m1 = q1*m m2 = q2*m
+static poly maEggT(const poly m1, const poly m2, poly &q1, poly &q2,const ring r)
+{
+
+  int i;
+  int dg = 0;
+  poly ggt = p_Init(r);
+  q1 = p_Init(r);
+  q2 = p_Init(r);
+
+  for (i=1;i<=r->N;i++)
+  {
+    unsigned long e1 = p_GetExp(m1, i, r);
+    unsigned long e2 = p_GetExp(m2, i, r);
+    if (e1 > 0 && e2 > 0)
+    {
+      unsigned long em = (e1 > e2 ? e2 : e1);
+      dg += em;
+      p_SetExp(ggt, i, em, r);
+      p_SetExp(q1, i, e1 - em, r);
+      p_SetExp(q2, i, e2 - em, r);
+    }
+    else
+    {
+      p_SetExp(q1, i, e1, r);
+      p_SetExp(q2, i, e2, r);
+    }
+  }
+  if (dg>1)
+  {
+    p_Setm(ggt, r);
+    p_Setm(q1, r);
+    p_Setm(q2, r);
+  }
+  else
+  {
+    p_LmFree(ggt, r);
+    p_LmFree(q1, r);
+    p_LmFree(q2, r);
+    ggt = NULL;
+  }
+  return ggt;
+}
+
+/********************************************************************
+ **                                                                 *
+ * maFindBestggT                                                    *
+ * finds ggT with the highest cost                                  *
+ *******************************************************************/
+
+static mapoly maFindBestggT(mapoly mp, mapoly & choice, mapoly & fp, mapoly & fq,const ring r)
+{
+  int ggt_deg = 0;
+  poly p = mp->src;
+  mapoly iter = choice;
+  poly ggT = NULL;
+  fp = NULL;
+  fq = NULL;
+  poly fp_p=NULL;
+  poly fq_p=NULL;
+  choice=NULL;
+  while ((iter != NULL) && (p_Deg(iter->src, r) > ggt_deg))
+  {
+    //    maMonomial_Out(iter, r, NULL);
+    poly q1, q2, q;
+
+    q = maEggT(p, iter->src, q1, q2,r);
+    if (q != NULL)
+    {
+      int tmp_deg;
+      assume((q1!=NULL)&&(q2!=NULL));
+      if ((tmp_deg=p_Deg(q,r)) > ggt_deg)
+      {
+        choice=iter;
+        if (ggT != NULL)
+        {
+          p_LmFree(ggT, r);
+          p_LmFree(fp_p, r);
+          p_LmFree(fq_p, r);
+        }
+        ggt_deg = tmp_deg ; /*p_Deg(q, r);*/
+        ggT = q;
+        fp_p = q1;
+        fq_p = q2;
+      }
+      else
+      {
+        p_LmFree(q, r);
+        p_LmFree(q1, r);
+        p_LmFree(q2, r);
+      }
+    }
+    iter=iter->next;
+  }
+  if(ggT!=NULL)
+  {
+    int dq =p_Totaldegree(fq_p,r);
+    if (dq!=0)
+    {
+      fq=maPoly_InsertMonomial(mp, fq_p, r, NULL);
+      fp=maPoly_InsertMonomial(mp, fp_p, r, NULL);
+      return maPoly_InsertMonomial(mp, ggT, r, NULL);
+    }
+    else
+    {
+      fq=NULL;
+      p_LmFree(fq_p, r);
+      p_LmFree(ggT, r);
+      fp=maPoly_InsertMonomial(mp, fp_p, r, NULL);
+      choice->ref++;
+      return choice;
+    }
+  }
+  else
+  {
+    return NULL;
+  }
+}
+
+/********************************************************************
+ **                                                                 *
+ * maPoly_Optimize                                                  *
+ * adds and integrates subexpressions                               *
+ *******************************************************************/
+
+void maPoly_Optimize(mapoly mpoly, ring src_r)
+{
+  assume(mpoly!=NULL && mpoly->src!=NULL);
+  mapoly iter = mpoly;
+  mapoly choice;
+  mapoly ggT=NULL;
+  mapoly fp=NULL;
+  mapoly fq=NULL;
+  while (iter->next!=NULL)
+  {
+    choice=iter->next;
+    if ( /*(*/ iter->f1==NULL /*)*/ )
+    {
+      ggT=maFindBestggT(iter, choice, fp, fq,src_r);
+      if (choice!=NULL)
+      {
+        assume(iter->f1==NULL);
+        assume(iter->f2==NULL);
+        iter->f1=fp;
+        iter->f2=ggT;
+        if (fq!=NULL)
+        {
+          ggT->ref++;
+          choice->f1=fq;
+          choice->f2=ggT;
+        }
+      }
+      else assume(ggT==NULL);
+    }
+    iter=iter->next;
+  }
+}
diff --git a/kernel/maps/fast_maps.h b/kernel/maps/fast_maps.h
new file mode 100644
index 0000000..af57fe2
--- /dev/null
+++ b/kernel/maps/fast_maps.h
@@ -0,0 +1,109 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    fast_maps.cc
+ *  Purpose: implementation of fast maps
+ *  Author:  obachman (Olaf Bachmann), hannes (Hannes Schoenemann),
+ *           bricken (Michael Brickenstein)
+ *  Created: 01/02
+ *******************************************************************/
+
+/*******************************************************************************
+**
+*S  mapoly, macoeff . . . . . . . . . . . . definition of structs/classes
+*/
+#ifndef FAST_MAPS_HEADER
+#define FAST_MAPS_HEADER
+class macoeff_s;
+class mapoly_s;
+class maideal_s;
+typedef class mapoly_s*  mapoly;
+typedef class macoeff_s* macoeff;
+typedef class maideal_s* maideal;
+
+class mapoly_s
+{
+public:
+  mapoly    next;
+  poly      src;        // monomial from WeightedRing
+  poly      dest;       // poly in CompRing
+  mapoly    f1, f2;     // if f1 != NULL && f2 != NULL then dest = f1*f2
+  int       ref;        // use to catch last usage to save last copy
+  macoeff   coeff;      // list of coeffs to use
+};
+
+class macoeff_s
+{
+public:
+  macoeff       next;
+  number        n;
+  sBucket_pt    bucket;
+};
+
+class maideal_s
+{
+public:
+  int n;
+  sBucket_pt* buckets;
+};
+
+/*******************************************************************************
+**
+*S  definition of basic routines
+*/
+void maMonomial_Out(mapoly monomial, ring src_r, ring dest_r = NULL);
+void maPoly_Out(mapoly mpoly, ring src_ring, ring dest_r = NULL);
+
+// creates a new maMonomial
+// if bucket != NULL, a coeff with the bucket is created, as well
+mapoly maMonomial_Create(poly p, ring , sBucket_pt bucket = NULL);
+// unconditionally destroys a maMonomial:
+// src: LmFree
+// dest: p_Delete
+// coeffs: delete list
+void maMonomial_Destroy(mapoly monomial, ring src_r, ring dest_r = NULL);
+// decrements ref counter, if 0, calls Destroy
+inline mapoly maMonomial_Free(mapoly monomial, ring src_r, ring dest_r = NULL)
+{
+  monomial->ref--;
+  if (monomial->ref <= 0)
+  { maMonomial_Destroy(monomial, src_r, dest_r); return NULL;}
+  return monomial;
+}
+
+// inserts ("adds") monomial what into poly into
+// returns the maMonomial which was inserted, or, if an equal one was found,
+// the monomial which "swalloed" the monomial
+// It furthermore might reset into
+mapoly maPoly_InsertMonomial(mapoly &into, mapoly what, ring src_r);
+mapoly maPoly_InsertMonomial(mapoly &into, poly p, ring src_r, sBucket_pt bucket = NULL);
+
+// optimizes mpoly for later evaluation
+void maPoly_Optimize(mapoly mpoly, ring src_r);
+
+// evaluates mpoly and destroys it, on the fly
+void maPoly_Eval(mapoly mpoly, ring src_r, ideal dest_id, ring dest_r, int total_cost);
+
+// creates mpoly and  mideal
+void maMap_CreatePolyIdeal(ideal map_id, ring map_r,
+                           ring src_r, ring dest_r,
+                           mapoly &mp, maideal &mideal);
+// creates src_r: rings with weights
+//         dest_r: where we do our computations
+void maMap_CreateRings(ideal map_id, ring map_r,
+                       ideal image_id, ring image_r,
+                       ring &src_r, ring &dest_r, BOOLEAN &no_sort);
+
+// collects tthe results into an ideal and destroys maideal
+ideal maIdeal_2_Ideal(maideal ideal, ring dest_r);
+
+// main routine: map_id: the ideal to map
+//               map_r: the base ring for map_id
+//               image_id: the image of the variables
+//               image_r: the base ring for image_id
+ideal fast_map(ideal map_id, ring map_r, ideal image_id, ring image_r);
+
+#endif
+
+
diff --git a/kernel/maps/test.cc b/kernel/maps/test.cc
new file mode 100644
index 0000000..bb2c248
--- /dev/null
+++ b/kernel/maps/test.cc
@@ -0,0 +1,376 @@
+#include <kernel/mod2.h>
+
+#include <omalloc/omalloc.h>
+
+#include <resources/feFopen.h>
+#include <resources/feResource.h>
+
+
+#include <factory/factory.h> // :(
+
+#include <misc/auxiliary.h>
+#include <misc/intvec.h>
+#include <misc/int64vec.h>
+#include <misc/mylimits.h>
+#include <misc/options.h>
+
+#include <reporter/reporter.h>
+
+#include <coeffs/si_gmp.h>
+#include <coeffs/coeffs.h>
+#include <coeffs/numbers.h>
+
+#ifndef PLURAL_INTERNAL_DECLARATIONS
+#define PLURAL_INTERNAL_DECLARATIONS
+#endif
+
+#ifndef PLURAL_INTERNAL_DECLARATIONS_GB_HACK
+#define PLURAL_INTERNAL_DECLARATIONS_GB_HACK
+#endif
+
+#include <polys/nc/gb_hack.h>
+#include <polys/nc/nc.h>
+#include <polys/nc/ncSACache.h>
+#include <polys/nc/ncSAFormula.h>
+#include <polys/nc/ncSAMult.h>
+#include <polys/nc/sca.h>
+#include <polys/nc/summator.h>
+
+#include <polys/kbuckets.h>
+#include <polys/matpol.h>
+#include <polys/mod_raw.h>
+#include <polys/prCopy.h>
+#include <polys/sbuckets.h>
+#include <polys/simpleideals.h>
+#include <polys/weight.h>
+
+#include <polys/monomials/maps.h>
+#include <polys/monomials/monomials.h>
+#include <polys/monomials/p_polys.h>
+#include <polys/monomials/ring.h>
+
+#include <polys/templates/p_MemAdd.h>
+#include <polys/templates/p_Procs.h>
+
+#include <polys/operations/pShallowCopyDelete.h>
+
+#include <polys/clapsing.h>
+
+
+// // TODO: DUE to the use of HALT in npolygon.cc :(((
+extern "C" {void m2_end(int i){exit(i);}}
+
+// // TODO: DUE to its use in kutil.cc :(((
+// char * showOption(){return NULL;}
+
+
+// #include "structs.h"
+
+
+// HEADERS:
+#include <kernel/ideals.h>
+#include <kernel/digitech.h>
+#include <kernel/fast_mult.h>
+
+// #include <kernel/spectrum/kmatrix.h>
+#include <kernel/preimage.h>
+
+#include <kernel/structs.h>
+
+#include <kernel/polys.h>
+
+void TestGBEngine()
+{
+
+  //  R = MPolynomialRing_polydict(QQ,5,'w,x,y,z,C', order='degrevlex')
+  //  J = (w*w - x*z, w*x - y*z, x*x - w*y, x*y - z*z, y*y - w*z)
+
+  const short w = 1;
+  const short x = 2;
+  const short y = 3;
+  const short z = 4;
+
+  const short N = (z - w + 1);
+
+  char **n=(char**)omalloc(N*sizeof(char*));
+
+
+  n[w-1]=omStrDup("w");
+  n[x-1]=omStrDup("x");
+  n[y-1]=omStrDup("y");
+  n[z-1]=omStrDup("z");
+
+
+  const int D = 3;
+  int *order = (int *) omAlloc0(D* sizeof(int));
+  int *block0 = (int *)omAlloc0(D * sizeof(int));
+  int *block1 = (int *)omAlloc0(D * sizeof(int));
+
+  order[0]  = ringorder_dp;
+  block0[0] = 1;
+  block1[0] = N;
+
+  order[1]  = ringorder_C;
+  block0[1] = 1;
+  block1[1] = N;
+
+  ring R = rDefault(0, N, n, D, order, block0, block1);
+
+//   ring R = rDefault(0, N, n);
+
+  rWrite(R); PrintLn();
+
+#ifdef RDEBUG
+  rDebugPrint(R);
+#endif
+
+  ideal I = idInit(5, 1);
+
+  int gen = 0;
+
+  {
+    // -xz
+    poly p = p_ISet(-1,R);
+
+    p_SetExp(p, x, 1, R);
+    p_SetExp(p, z, 1, R);
+    p_Setm(p, R);
+
+    assume( p_GetExp(p, x, R) == 1 );
+    assume( p_GetExp(p, z, R) == 1 );
+    assume( p_GetExp(p, w, R) == 0 );
+    assume( p_GetExp(p, y, R) == 0 );
+
+    // +w2
+    poly lp = p_ISet(1,R);
+    p_SetExp(lp, w, 2, R);
+    p_Setm(lp, R);
+
+    assume( p_GetExp(lp, w, R) == 2 );
+    assume( p_GetExp(lp, x, R) == 0 );
+    assume( p_GetExp(lp, y, R) == 0 );
+    assume( p_GetExp(lp, z, R) == 0 );
+
+    MATELEM(I, 1, ++gen) = p_Add_q(lp, p, R); // w2 - xz
+  }
+
+  {
+    // -yz
+    poly p = p_ISet(-1,R);
+
+    p_SetExp(p, y, 1, R);
+    p_SetExp(p, z, 1, R);
+    p_Setm(p, R);
+
+    assume( p_GetExp(p, y, R) == 1 );
+    assume( p_GetExp(p, z, R) == 1 );
+    assume( p_GetExp(p, w, R) == 0 );
+    assume( p_GetExp(p, x, R) == 0 );
+
+    // +wx
+    poly lp = p_ISet(1,R);
+    p_SetExp(lp, w, 1, R);
+    p_SetExp(lp, x, 1, R);
+    p_Setm(lp, R);
+
+    assume( p_GetExp(lp, w, R) == 1 );
+    assume( p_GetExp(lp, x, R) == 1 );
+    assume( p_GetExp(lp, y, R) == 0 );
+    assume( p_GetExp(lp, z, R) == 0 );
+
+    MATELEM(I, 1, ++gen) = p_Add_q(lp, p, R); // wx - yz
+  }
+
+
+  {
+    // -wy
+    poly p = p_ISet(-1,R);
+
+    p_SetExp(p, y, 1, R);
+    p_SetExp(p, w, 1, R);
+    p_Setm(p, R);
+
+    assume( p_GetExp(p, y, R) == 1 );
+    assume( p_GetExp(p, w, R) == 1 );
+    assume( p_GetExp(p, z, R) == 0 );
+    assume( p_GetExp(p, x, R) == 0 );
+
+    // +x2
+    poly lp = p_ISet(1,R);
+    p_SetExp(lp, x, 2, R);
+    p_Setm(lp, R);
+
+    assume( p_GetExp(lp, w, R) == 0 );
+    assume( p_GetExp(lp, x, R) == 2 );
+    assume( p_GetExp(lp, y, R) == 0 );
+    assume( p_GetExp(lp, z, R) == 0 );
+
+    MATELEM(I, 1, ++gen) = p_Add_q(lp, p, R); // x2 - wy
+  }
+
+
+  {
+    // -z2
+    poly p = p_ISet(-1,R);
+
+    p_SetExp(p, z, 2, R);
+    p_Setm(p, R);
+
+    assume( p_GetExp(p, y, R) == 0 );
+    assume( p_GetExp(p, w, R) == 0 );
+    assume( p_GetExp(p, z, R) == 2 );
+    assume( p_GetExp(p, x, R) == 0 );
+
+    // +xy
+    poly lp = p_ISet(1,R);
+    p_SetExp(lp, x, 1, R);
+    p_SetExp(lp, y, 1, R);
+    p_Setm(lp, R);
+
+    assume( p_GetExp(lp, w, R) == 0 );
+    assume( p_GetExp(lp, x, R) == 1 );
+    assume( p_GetExp(lp, y, R) == 1 );
+    assume( p_GetExp(lp, z, R) == 0 );
+
+    MATELEM(I, 1, ++gen) = p_Add_q(lp, p, R); // xy - z2
+  }
+
+
+  {
+    // -wz
+    poly p = p_ISet(-1,R);
+
+    p_SetExp(p, w, 1, R);
+    p_SetExp(p, z, 1, R);
+    p_Setm(p, R);
+
+    assume( p_GetExp(p, y, R) == 0 );
+    assume( p_GetExp(p, w, R) == 1 );
+    assume( p_GetExp(p, z, R) == 1 );
+    assume( p_GetExp(p, x, R) == 0 );
+
+    // +y2
+    poly lp = p_ISet(1,R);
+    p_SetExp(lp, y, 2, R);
+    p_Setm(lp, R);
+
+    assume( p_GetExp(lp, w, R) == 0 );
+    assume( p_GetExp(lp, x, R) == 0 );
+    assume( p_GetExp(lp, y, R) == 2 );
+    assume( p_GetExp(lp, z, R) == 0 );
+
+    MATELEM(I, 1, ++gen) = p_Add_q(lp, p, R); // y2 - wz
+  }
+#ifdef PDEBUG
+  PrintS("I: ");
+  idShow(I, R, R, 0);
+#endif
+
+
+//  ideal kStd(ideal F, ideal Q, tHomog h, intvec ** mw,intvec *hilb=NULL,
+//             int syzComp=0,int newIdeal=0, intvec *vw=NULL);
+  // make R the default ring:
+  rChangeCurrRing(R);
+
+ ////
+
+  idDelete( &I, R);
+  rDelete(R); // should cleanup every belonging polynomial, right!?
+
+}
+
+
+
+void TestSimpleRingArithmetcs()
+{
+  // Libpolys tests:
+
+  // construct the ring Z/32003[x,y,z]
+  // the variable names
+  char **n=(char**)omalloc(3*sizeof(char*));
+  n[0]=omStrDup("x");
+  n[1]=omStrDup("y");
+  n[2]=omStrDup("z2");
+
+  ring R = rDefault(32003,3,n); //  ring R = rDefault(0,3,n);
+
+  rWrite(R); PrintLn();
+
+#ifdef RDEBUG
+  rDebugPrint(R);
+#endif
+
+
+  poly p = p_ISet(1,R); p_SetExp(p,1,1, R); p_Setm(p, R);
+
+  assume( p_GetExp(p,1, R) == 1 );
+
+  poly pp = pp_Mult_qq( p, p, R);
+
+  Print("p: "); p_Write0(p, R); Print(", deg(p): %ld", p_Totaldegree(p, R)); assume( 1 == p_Totaldegree(p, R) );
+
+  Print("; p*p : "); p_Write0(pp, R); Print("deg(pp): %ld\n", p_Totaldegree(pp, R)); assume( 2 == p_Totaldegree(pp, R) );
+
+
+  p_Delete(&p, R);
+
+  assume( p_GetExp(pp,1, R) == 2 );
+
+  p_Delete(&pp, R);
+
+
+//  rDelete(R);
+
+  // make R the default ring:
+  rChangeCurrRing(R);
+
+  // create the polynomial 1
+  poly p1=pISet(1);
+
+  // create tthe polynomial 2*x^3*z^2
+  poly p2=p_ISet(2,R);
+  pSetExp(p2,1,3);
+  pSetExp(p2,3,2);
+  pSetm(p2);
+
+  // print p1 + p2
+  Print("p1: "); pWrite0(p1);
+  Print(" + p2: "); pWrite0(p2);
+  Print("  ---- >>>> ");
+
+  // compute p1+p2
+  p1=p_Add_q(p1,p2,R); p2=NULL;
+  pWrite(p1);
+
+  // clean up:
+//  pDelete(&p1);
+
+  rDelete(R); // should cleanup every belonging polynomial, right!?
+}
+
+
+int main( int, char *argv[] )
+{
+  assume( sizeof(long) == SIZEOF_LONG );
+
+  if( sizeof(long) != SIZEOF_LONG )
+  {
+    WerrorS("Bad config.h: wrong size of long!");
+
+    return(1);
+  }
+
+
+  feInitResources(argv[0]);
+
+  StringSetS("ressources in use (as reported by feStringAppendResources(0):\n");
+  feStringAppendResources(0);
+
+  PrintLn();
+  { char* s = StringEndS(); PrintS(s); omFree(s); }
+
+  TestGBEngine();
+  TestSimpleRingArithmetcs();
+
+  return 0;
+}
diff --git a/kernel/mkinstalldirs b/kernel/mkinstalldirs
new file mode 100755
index 0000000..5b6d1ba
--- /dev/null
+++ b/kernel/mkinstalldirs
@@ -0,0 +1,32 @@
+#!/bin/sh
+# mkinstalldirs --- make directory hierarchy
+# Author: Noah Friedman <friedman at prep.ai.mit.edu>
+# Created: 1993-05-16
+# Last modified: 1994-03-25
+# Public domain
+
+errstatus=0
+
+for file in ${1+"$@"} ; do
+   set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
+   shift
+
+   pathcomp=
+   for d in ${1+"$@"} ; do
+     pathcomp="$pathcomp$d"
+     case "$pathcomp" in
+       -* ) pathcomp=./$pathcomp ;;
+     esac
+
+     if test ! -d "$pathcomp"; then
+        echo "mkdir $pathcomp" 1>&2
+        mkdir "$pathcomp" || errstatus=$?
+     fi
+
+     pathcomp="$pathcomp/"
+   done
+done
+
+exit $errstatus
+
+# mkinstalldirs ends here
diff --git a/kernel/mod2.h b/kernel/mod2.h
new file mode 100644
index 0000000..29e1c63
--- /dev/null
+++ b/kernel/mod2.h
@@ -0,0 +1,451 @@
+/* -*-c++-*- */
+/*******************************************************************
+ *  Computer Algebra System SINGULAR
+ *
+ *  mod2.h: Main configuration file for Singular
+ *          DO NOT EDIT!
+ *
+ *******************************************************************/
+#ifndef MOD2_H
+#define MOD2_H
+
+/* please include singularconfig.h exclusively via <kernel/mod2.h> and before any other header */
+# include <singularconfig.h>
+
+# include <misc/auxiliary.h>
+
+#define SINGULAR_MAJOR_VERSION 4
+
+#ifdef SINGULAR_4_1
+#undef VERSION
+#define VERSION "4.1.0"
+#define SINGULAR_MINOR_VERSION 1
+#define SINGULAR_SUB_VERSION 0
+#else
+#define SINGULAR_MINOR_VERSION 0
+#define SINGULAR_SUB_VERSION 1
+#endif
+#define S_ROOT_DIR ""
+
+/*******************************************************************
+ * Defines which are not set by configure
+ ******************************************************************/
+
+/*defines, which should be set by configure */
+#define HAVE_GETTIMEOFDAY 1
+#define TIME_WITH_SYS_TIME 1
+#define HAVE_SYS_TIME_H 1
+/* Default value for timer resolution in ticks per second */
+/* set to 10 for resolution of tenth of a second, etc */
+#define TIMER_RESOLUTION 1
+
+/* Undefine to disable the quote/eval of expressions */
+#define SIQ 1
+
+/* Undefine to disable Gerhard's and Wilfried's fast and dirty std computations */
+#define FAST_AND_DIRTY
+
+/* eigenvalues */
+#define HAVE_EIGENVAL 1
+
+/* Gauss-Manin system */
+#define HAVE_GMS 1
+
+/* include simpleipc/semaphore code, link against librt/libpthread */
+#define HAVE_SIMPLEIPC 1
+
+
+/* linear algebra extensions from pcv.h/pcv.cc */
+#define HAVE_PCV 1
+
+/* procedures to compute groebner bases with the f5 implementation */
+/* still testing */
+#undef HAVE_F5
+
+/* procedures to compute groebner bases with the f5c implementation */
+/* still testing */
+#undef HAVE_F5C
+
+/* procedures to compute with units */
+#define HAVE_UNITS
+
+/* Define to use scanner when loading libraries */
+#define HAVE_LIBPARSER
+
+/*#define PROFILING*/
+#ifdef PROFILING
+#define PROFILER ,0,0
+#else
+#define PROFILER
+#endif
+
+/*******************************************************************
+ * Evaluate the set defines
+ ******************************************************************/
+/* Spectrum needs GMP */
+#define HAVE_SPECTRUM 1
+
+#if SIZEOF_VOIDP == 8
+/* SIZEOF_LONG == SIZEOF_VOIDP is guaranteed by configure */
+#define ALIGN_8
+#endif
+
+#ifdef SINGULAR_4_1
+#define SINGULAR_VERSION 4100
+#else
+#define SINGULAR_PATCHLEVEL 2
+#define SINGULAR_VERSION ((SINGULAR_MAJOR_VERSION*1000 + SINGULAR_MINOR_VERSION*100 + SINGULAR_SUB_VERSION*10)+SINGULAR_PATCHLEVEL)
+#endif
+/*******************************************************************
+ * Miscellanous Defines
+ ******************************************************************/
+#ifndef HAVE_LIBPARSER
+#  undef YYLPDEBUG
+#else
+#  define YYLPDEBUG 1
+#endif
+
+#ifndef FALSE
+#define FALSE       0
+#endif
+
+#ifndef TRUE
+#define TRUE        1
+#endif
+
+#ifndef NULL
+#define NULL        (0)
+#endif
+
+#ifndef SEEK_END
+#define SEEK_END 2
+#endif
+
+#ifndef SEEK_SET
+#define SEEK_SET 0
+#endif
+
+#define HALT() m2_end(2)
+
+/* define OLD_RES for res/sres/mres(i,j,k) */
+#undef OLD_RES
+
+/* the maximal ascii length of an int number + 1 = 11 for 32 bit int */
+/* #define MAX_INT_LEN 11 */
+
+
+#ifdef DO_PROFILE
+/* define to enable explicit profiling of some crucial inline
+ * routines and defines  */
+#undef DO_DEEP_PROFILE
+#endif
+
+/* define to enable assume */
+#ifndef HAVE_ASSUME
+#undef HAVE_ASSUME
+#endif
+
+/* define LINKAGE to "extern C" if compiling for shared libs */
+#ifndef LINKAGE
+#if defined(PIC)
+#define LINKAGE extern "C"
+#else
+#define LINKAGE
+#endif
+#endif
+
+
+/*******************************************************************
+ * DEBUG OPTIONS
+ * -- only significant for for compiling without -DSING_NDEBUG
+ * -- you better know what your are doing, if you touch this
+ ******************************************************************/
+#ifndef SING_NDEBUG
+
+/* undefine to enable inline */
+#define NO_INLINE
+
+/* undefine to disable assume -- should normally be defined for SING_NDEBUG */
+#define HAVE_ASSUME
+
+/* undef PDEBUG to disable checks of polys
+
+ define PDEBUG to
+  0 for enabling pTest
+  1 plus tests in Level 1 poly routines (operations on monomials)
+  2 plus tests in Level 2 poly routines (operations on single exponents)
+ -- see also polys.h for more info
+
+ NOTE: you can set the value of PDEBUG on a per-file basis, before
+       including mod2.h, provided ! PDEBUG is defined in mod2.h E.g.:
+
+       #define PDEBUG 2
+       #include "mod2.h"
+       ...
+
+       makes sure that all poly operations in your file are done with
+       PDEBUG == 2
+ To break after an error occured, set a debugger breakpoint on
+ dErrorBreak.
+*/
+#ifndef PDEBUG
+#define PDEBUG 0
+#endif
+
+/* define MDEBUG to enable memory checks */
+#define MDEBUG 0
+
+#ifdef MDEBUG
+/* If ! defined(OM_NDEBUG) and (defined(OM_TRACK) or defined(OM_CHECK)
+   then omDebug routines are used for memory allocation/free:
+
+   The omDebug routines are controlled by the values of OM_TRACK, OM_CHECK
+   and OM_KEEP.  There meaning is roughly as follows:
+   OM_TRACK: strored with address                              : extra space
+     0     : no additional info is stored                      : 0
+     1     : file:line of location where address was allocated : 1 word
+     2     : plus backtrace of stack where adress was allocated: 6 words
+     3     : plus size/bin info and front-, and back padding   : 9 words
+     4     : plus file:line of location where adress was freed : 10 words
+     5     : plus backtrace of stack where adress was allocated: 15 words
+   OM_CHECK: checks done
+     0     : no checks
+     1     : constant-time checks: i.e. addr checks only
+     2     : plus linear-time checks and constant related bin check
+     3     : plus quadratic-time checks and linear-time related bin checks and
+             constant time all memory checks
+     4     : and so on
+     ==> for OM_CHECK >= 3 it gets rather slow
+   OM_KEEP:  determines whether addresses are really freed  (
+     0     : addresses are really freed
+     1     : addresses are only marked as free and not really freed.
+
+   OM_CHECK, OM_TRACK, and OM_KEEP can be set on a per-file basis
+   (as can OM_NDEBUG),  e.g.:
+     #define OM_CHECK 3
+     #define OM_TRACK 5
+     #define OM_KEEP  1
+     #include "mod2.h"
+     #include <omalloc/omalloc.h>
+   ensures that all memory allocs/free in this file are done with
+   OM_CHECK==3 and OM_TRACK==5, and that all addresses allocated/freed
+   in this file are only marked as free and never really freed.
+
+   To set OM_CHECK, OM_TRACK and OM_KEEP under dynamic scope, set
+   om_Opts.MinCheck, om_Opts.MinTrack to the respectiv values and
+   om_Opts.Keep to the number of addresses which are kept before they are
+   actually freed. E.g.:
+     int check=om_Opts.MinCheck, track=om_Opts.MinTrack, keep= m_OPts.Keep;
+     om_Opts.MinCheck = 3; om_Opts.MinTrack = 5; omOpts.Keep = LONG_MAX;
+     ExternalRoutine();
+     om_Opts.MinCheck = check; omOpts.MinTrack = track; omOpts.Keep = keep;
+   ensures that all calls omDebug routines  occuring during the computation of
+   ExternalRoutine() are done with OM_CHECK==3 and OM_TRACK==5, and
+   calls to omFree only mark addresses as free and not really free them.
+
+   Furthermore, the value of OM_SING_KEEP (resp. om_Opts.Keep) specifies
+   how many addresses are kept before they are actually freed, independently
+   of the value of OM_KEEP.
+
+   Some tips on possible values of OM_TRACK, OM_CHECK, OM_KEEP:
+   + To find out about an address that has been freed twice, first locate the
+     file(s) where the error occured, and then at the beginning of these files:
+       #define OM_CHECK 3
+       #define OM_TRACK 5
+       #define OM_KEEP  1
+       #include "mod2.h"
+       #include <omalloc/omalloc.h>
+     Under dynamic scope, do (e.g., from within the debugger):
+       om_Opts.MinCheck = 3; om_Opts.MinTrack = 5; omOpts.Keep = LONG_MAX;
+   + to find out where "memory corruption" occured, increase value of
+     OM_CHECK - the higher this value is, the more consistency checks are
+     done (However a value > 3 checks the entire memory each time an omalloc
+     routine is used!)
+
+   Some more tips on the usage of omalloc:
+   + omAlloc*, omRealloc*, omFree*, omCheck* omDebug* omTest* rotuines
+     assume that sizes are > 0 and pointers are != NULL
+   + omalloc*, omrealloc*, omfree* omcheck*, omdebug* omtest* routines allow
+     NULL pointers and sizes == 0
+   + You can safely use any free/realloc routine in combination with any alloc
+     routine (including the debug versions): E.g., an address allocated with
+     omAllocBin can be freed with omfree, or an adress allocated with
+     om(Debug)Alloc can be freed with omfree, or omFree, or omFreeSize, etc.
+     However, keep in mind that the efficiency decreases from
+     Bin over Size to General routines (i.e., omFreeBin is more efficient than
+     omFreeSize which is more efficient than omFree, likewise with the alloc
+     routines).
+   + if OM_CHECK is undefined or 0, then all omCheck routines do nothing
+   + if OM_CHECK and OM_TRACK are both undefined (or 0), or if OM_NDEBUG is
+     defined, then the "real" alloc/realloc/free macros are used, and all
+     omTest, omDebug and omCheck routines are undefined
+   + to break after an omError occured within a debugger,
+     set a breakpoint on dErrorBreak
+   + to do checks from within the debugger, or to do checks with explicit
+     check level, use omTest routines.
+*/
+
+/* by default, store alloc info and file/line where addr was freed */
+#ifndef OM_TRACK
+#define OM_TRACK 4
+#endif
+/* only do constant-time memory checks */
+#ifndef OM_CHECK
+#define OM_CHECK 1
+#endif
+/* Do actually free memory:
+   (be careful: if this is set, memory is never really freed,
+    but only marked as free) */
+#ifndef OM_KEEP
+#define OM_KEEP 0
+#endif
+/* but only after you have freed 1000 more addresses
+   (this is actually independent of the value of OM_KEEP and used
+   to initialize om_Opts.Keep) */
+#ifndef OM_SING_KEEP
+#define OM_SING_KEEP 1000
+#endif
+
+#endif /* MDEBUG */
+
+
+/* undef KDEBUG for check of data during std computations
+ *
+ * define KDEBUG to
+ * 0 for basic tests
+ * 1 for tests in kSpoly
+ * NOTE: You can locally enable tests in kspoly by setting the
+ *       define at the beginning of kspoly.cc
+ */
+#define KDEBUG 0
+
+/* define LDEBUG checking numbers, undefine otherwise */
+#define LDEBUG
+/* define RDEBUG checking rings (together with TRACE=9) */
+#define RDEBUG
+/* define TEST for non time critical tests, undefine otherwise */
+#define TEST
+
+/* #define PAGE_TEST */
+
+/* define YYDEBUG 1 for debugging bison texts, 0 otherwise */
+#define YYDEBUG 1
+
+/* define SPECTRUM_DEBUG and SPECTRUM_PRINT for debugging the spectrum code */
+/* define SPECTRUM_IOSTREAM to use C++ iostream for error messages          */
+
+/* #define SPECTRUM_DEBUG */
+/* #define SPECTRUM_PRINT */
+#undef  SPECTRUM_IOSTREAM
+
+#ifdef  SPECTRUM_DEBUG
+#define MULTICNT_DEBUG
+#define GMPRAT_DEBUG
+#define KMATRIX_DEBUG
+#define SPLIST_DEBUG
+#define NPOLYGON_DEBUG
+#define SEMIC_DEBUG
+#endif
+
+#ifdef  SPECTRUM_PRINT
+#define MULTICNT_PRINT
+#define GMPRAT_PRINT
+#define KMATRIX_PRINT
+#define SPLIST_PRINT
+#define NPOLYGON_PRINT
+#define SEMIC_PRINT
+#endif
+
+#ifdef  SPECTRUM_IOSTREAM
+#define MULTICNT_IOSTREAM
+#define GMPRAT_IOSTREAM
+#define KMATRIX_IOSTREAM
+#define SPLIST_IOSTREAM
+#define NPOLYGON_IOSTREAM
+#define SEMIC_IOSTREAM
+#endif
+
+
+#else /* not SING_NDEBUG **************************************************** */
+
+#define NO_PDEBUG
+
+/* define YYDEBUG 1 for debugging bison texts, 0 otherwise */
+#define YYDEBUG 0
+
+#endif /* not SING_NDEBUG */
+
+/*******************************************************************
+ *
+ * assume(x) -- a handy macro for assumptions
+ *
+ ******************************************************************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/* routine which is used to report the error/
+* returns 0 */
+extern int dReportError(const char* fmt, ...);
+/* within a debugger, set a breakpoint on dErrorBreak
+* which is called after the error has been reported */
+extern void dErrorBreak();
+#ifdef __cplusplus
+}
+#endif
+
+#ifndef HAVE_ASSUME
+#define assume(x) do {} while (0)
+#define r_assume(x) do {} while (0)
+#else /* ! HAVE_ASSUME */
+
+#define assume_violation(s,f,l) \
+  dReportError("assume violation at %s:%d condition: %s", f,l,s)
+
+#define assume(x)   _assume(x, __FILE__, __LINE__)
+#define r_assume(x) _r_assume(x, __FILE__, __LINE__)
+
+#define _assume(x, f, l)                        \
+do                                              \
+{                                               \
+  if (! (x))                                    \
+  {                                             \
+    assume_violation(#x, f, l);                 \
+  }                                             \
+}                                               \
+while (0)
+
+#define _r_assume(x, f, l)                      \
+do                                              \
+{                                               \
+  if (! (x))                                    \
+  {                                             \
+    assume_violation(#x, f, l);                 \
+    return 0;                                   \
+  }                                             \
+}                                               \
+while (0)
+#endif /* HAVE_ASSUME */
+
+/* do have RDEBUG, unless we are doing the very real thing */
+#ifdef HAVE_ASSUME
+#ifndef RDEBUG
+#define RDEBUG
+#endif
+#endif
+
+#if SIZEOF_VOIDP == 8
+#ifndef OM_CHECK
+#define OM_CHECK 0
+#endif
+#endif
+
+/* If we're not using GNU C, elide __attribute__ */
+#ifndef __GNUC__
+#  define  __attribute__(x)  /*NOTHING*/
+#endif
+
+#define STRINGIFY(name) #name
+#define EXPANDED_STRINGIFY(name) STRINGIFY(name)
+
+#endif /* MOD2_H  */
diff --git a/kernel/numeric/Makefile.am b/kernel/numeric/Makefile.am
new file mode 100644
index 0000000..ea4d4c0
--- /dev/null
+++ b/kernel/numeric/Makefile.am
@@ -0,0 +1,23 @@
+ACLOCAL_AMFLAGS=-I ../../m4
+AM_CPPFLAGS=-I${top_srcdir} -I${top_builddir} \
+-I${top_srcdir}/libpolys -I${top_builddir}/libpolys \
+${FACTORY_INCLUDES} ${RESOURCES_INCLUDES} ${OMALLOC_INCLUDES} \
+${FLINT_CFLAGS} ${NTL_CFLAGS} ${GMP_CFLAGS}
+
+noinst_LTLIBRARIES=libnumeric.la
+libnumeric_la_SOURCES=mpr_base.cc mpr_inout.cc mpr_numeric.cc
+
+libnumeric_la_includedir=$(includedir)/singular/kernel/numeric
+libnumeric_la_include_HEADERS=mpr_base.h mpr_inout.h mpr_numeric.h
+
+
+
+TESTS_ENVIRONMENT = SINGULARPATH='${abs_top_builddir}/libpolys/polys/.libs:${abs_top_builddir}/factory/gftables'
+TESTS_ENVIRONMENT += SINGULAR_ROOT_DIR='${abs_top_builddir}'
+
+TESTS = test
+check_PROGRAMS = $(TESTS)
+test_SOURCES = test.cc
+test_LDADD   = libnumeric.la ${builddir}/../libkernelCommon.la
+
+CLEANFILES = $(TESTS)
diff --git a/kernel/numeric/Makefile.in b/kernel/numeric/Makefile.in
new file mode 100644
index 0000000..003e64d
--- /dev/null
+++ b/kernel/numeric/Makefile.in
@@ -0,0 +1,1085 @@
+# Makefile.in generated by automake 1.13.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 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@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+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@
+TESTS = test$(EXEEXT)
+check_PROGRAMS = $(am__EXEEXT_1)
+subdir = kernel/numeric
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/build-aux/depcomp \
+	$(libnumeric_la_include_HEADERS) \
+	$(top_srcdir)/build-aux/test-driver
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_append_compile_flags.m4 \
+	$(top_srcdir)/m4/ax_append_flag.m4 \
+	$(top_srcdir)/m4/ax_append_link_flags.m4 \
+	$(top_srcdir)/m4/ax_check_compile_flag.m4 \
+	$(top_srcdir)/m4/ax_check_link_flag.m4 \
+	$(top_srcdir)/m4/ax_compute_relative_paths.m4 \
+	$(top_srcdir)/m4/ax_normalize_path.m4 \
+	$(top_srcdir)/m4/ax_prefix_config_h.m4 \
+	$(top_srcdir)/m4/ax_pthread.m4 \
+	$(top_srcdir)/m4/ax_python_embed.m4 \
+	$(top_srcdir)/m4/ax_python_with_version.m4 \
+	$(top_srcdir)/m4/cpu-check.m4 $(top_srcdir)/m4/dbm-check.m4 \
+	$(top_srcdir)/m4/flags.m4 $(top_srcdir)/m4/flint-check.m4 \
+	$(top_srcdir)/m4/gfanlib-check.m4 \
+	$(top_srcdir)/m4/gmp-check.m4 \
+	$(top_srcdir)/m4/google-perftools.m4 \
+	$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+	$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+	$(top_srcdir)/m4/lt~obsolete.m4 \
+	$(top_srcdir)/m4/mathic-check.m4 $(top_srcdir)/m4/ntl-check.m4 \
+	$(top_srcdir)/m4/options.m4 $(top_srcdir)/m4/p-procs.m4 \
+	$(top_srcdir)/m4/polymake-check.m4 \
+	$(top_srcdir)/m4/readline-check.m4 $(top_srcdir)/configure.ac
+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 =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+libnumeric_la_LIBADD =
+am_libnumeric_la_OBJECTS = mpr_base.lo mpr_inout.lo mpr_numeric.lo
+libnumeric_la_OBJECTS = $(am_libnumeric_la_OBJECTS)
+AM_V_lt = $(am__v_lt_ at AM_V@)
+am__v_lt_ = $(am__v_lt_ at AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 = 
+am__EXEEXT_1 = test$(EXEEXT)
+am_test_OBJECTS = test.$(OBJEXT)
+test_OBJECTS = $(am_test_OBJECTS)
+test_DEPENDENCIES = libnumeric.la ${builddir}/../libkernelCommon.la
+AM_V_P = $(am__v_P_ at AM_V@)
+am__v_P_ = $(am__v_P_ at AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_ at AM_V@)
+am__v_GEN_ = $(am__v_GEN_ at AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_ at AM_V@)
+am__v_at_ = $(am__v_at_ at AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+DEFAULT_INCLUDES = -I. at am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \
+	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+	$(AM_CXXFLAGS) $(CXXFLAGS)
+AM_V_CXX = $(am__v_CXX_ at AM_V@)
+am__v_CXX_ = $(am__v_CXX_ at AM_DEFAULT_V@)
+am__v_CXX_0 = @echo "  CXX     " $@;
+am__v_CXX_1 = 
+CXXLD = $(CXX)
+CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+	$(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CXXLD = $(am__v_CXXLD_ at AM_V@)
+am__v_CXXLD_ = $(am__v_CXXLD_ at AM_DEFAULT_V@)
+am__v_CXXLD_0 = @echo "  CXXLD   " $@;
+am__v_CXXLD_1 = 
+SOURCES = $(libnumeric_la_SOURCES) $(test_SOURCES)
+DIST_SOURCES = $(libnumeric_la_SOURCES) $(test_SOURCES)
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+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__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
+am__installdirs = "$(DESTDIR)$(libnumeric_la_includedir)"
+HEADERS = $(libnumeric_la_include_HEADERS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors_dummy = \
+  mgn= red= grn= lgn= blu= brg= std=; \
+  am__color_tests=no
+am__tty_colors = { \
+  $(am__tty_colors_dummy); \
+  if test "X$(AM_COLOR_TESTS)" = Xno; then \
+    am__color_tests=no; \
+  elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+    am__color_tests=yes; \
+  elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+    am__color_tests=yes; \
+  fi; \
+  if test $$am__color_tests = yes; then \
+    red=''; \
+    grn=''; \
+    lgn=''; \
+    blu=''; \
+    mgn=''; \
+    brg=''; \
+    std=''; \
+  fi; \
+}
+am__recheck_rx = ^[ 	]*:recheck:[ 	]*
+am__global_test_result_rx = ^[ 	]*:global-test-result:[ 	]*
+am__copy_in_global_log_rx = ^[ 	]*:copy-in-global-log:[ 	]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+  recheck = 1; \
+  while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+    { \
+      if (rc < 0) \
+        { \
+          if ((getline line2 < ($$0 ".log")) < 0) \
+	    recheck = 0; \
+          break; \
+        } \
+      else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+        { \
+          recheck = 0; \
+          break; \
+        } \
+      else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+        { \
+          break; \
+        } \
+    }; \
+  if (recheck) \
+    print $$0; \
+  close ($$0 ".trs"); \
+  close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+  print "fatal: making $@: " msg | "cat >&2"; \
+  exit 1; \
+} \
+function rst_section(header) \
+{ \
+  print header; \
+  len = length(header); \
+  for (i = 1; i <= len; i = i + 1) \
+    printf "="; \
+  printf "\n\n"; \
+} \
+{ \
+  copy_in_global_log = 1; \
+  global_test_result = "RUN"; \
+  while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+    { \
+      if (rc < 0) \
+         fatal("failed to read from " $$0 ".trs"); \
+      if (line ~ /$(am__global_test_result_rx)/) \
+        { \
+          sub("$(am__global_test_result_rx)", "", line); \
+          sub("[ 	]*$$", "", line); \
+          global_test_result = line; \
+        } \
+      else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+        copy_in_global_log = 0; \
+    }; \
+  if (copy_in_global_log) \
+    { \
+      rst_section(global_test_result ": " $$0); \
+      while ((rc = (getline line < ($$0 ".log"))) != 0) \
+      { \
+        if (rc < 0) \
+          fatal("failed to read from " $$0 ".log"); \
+        print line; \
+      }; \
+      printf "\n"; \
+    }; \
+  close ($$0 ".trs"); \
+  close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/   &   /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this.  Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+  --color-tests "$$am__color_tests" \
+  --enable-hard-errors "$$am__enable_hard_errors" \
+  --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test.  Creates the
+# directory for the log if needed.  Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log.  Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT.  Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup);					\
+$(am__vpath_adj_setup) $(am__vpath_adj)			\
+$(am__tty_colors);					\
+srcdir=$(srcdir); export srcdir;			\
+case "$@" in						\
+  */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;;	\
+    *) am__odir=.;; 					\
+esac;							\
+test "x$$am__odir" = x"." || test -d "$$am__odir" 	\
+  || $(MKDIR_P) "$$am__odir" || exit $$?;		\
+if test -f "./$$f"; then dir=./;			\
+elif test -f "$$f"; then dir=;				\
+else dir="$(srcdir)/"; fi;				\
+tst=$$dir$$f; log='$@'; 				\
+if test -n '$(DISABLE_HARD_ERRORS)'; then		\
+  am__enable_hard_errors=no; 				\
+else							\
+  am__enable_hard_errors=yes; 				\
+fi; 							\
+case " $(XFAIL_TESTS) " in				\
+  *[\ \	]$$f[\ \	]* | *[\ \	]$$dir$$f[\ \	]*) \
+    am__expect_failure=yes;;				\
+  *)							\
+    am__expect_failure=no;;				\
+esac; 							\
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed).  The result is saved in the shell variable
+# '$bases'.  This honors runtime overriding of TESTS and TEST_LOGS.  Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+  bases='$(TEST_LOGS)'; \
+  bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+  bases=`echo $$bases`
+RECHECK_LOGS = $(TEST_LOGS)
+AM_RECURSIVE_TARGETS = check recheck
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+  case '$@' in \
+    */*) \
+      case '$*' in \
+        */*) b='$*';; \
+          *) b=`echo '$@' | sed 's/\.log$$//'`; \
+       esac;; \
+    *) \
+      b='$*';; \
+  esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT at .log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+	$(TEST_LOG_FLAGS)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BUILTIN_LIBS = @BUILTIN_LIBS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CDDGMPCPPFLAGS = @CDDGMPCPPFLAGS@
+CDDGMPLDFLAGS = @CDDGMPLDFLAGS@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATA_DIR = @DATA_DIR@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DOC_DIR = @DOC_DIR@
+DOXYGEN = @DOXYGEN@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FACTORY_INCLUDES = @FACTORY_INCLUDES@
+FACTORY_LIBS = @FACTORY_LIBS@
+FGREP = @FGREP@
+FLINT_CFLAGS = @FLINT_CFLAGS@
+FLINT_HOME = @FLINT_HOME@
+FLINT_LIBS = @FLINT_LIBS@
+GMP_CFLAGS = @GMP_CFLAGS@
+GMP_HOME = @GMP_HOME@
+GMP_LIBS = @GMP_LIBS@
+GMP_VERSION = @GMP_VERSION@
+GREP = @GREP@
+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@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NTL_CFLAGS = @NTL_CFLAGS@
+NTL_LIBS = @NTL_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OMALLOC_INCLUDES = @OMALLOC_INCLUDES@
+OMALLOC_LIBS = @OMALLOC_LIBS@
+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@
+PKG_REQUIRE = @PKG_REQUIRE@
+PMCONFIG = @PMCONFIG@
+PM_CFLAGS = @PM_CFLAGS@
+PM_INC = @PM_INC@
+PM_LDFLAGS = @PM_LDFLAGS@
+PM_LIBS = @PM_LIBS@
+POLYMAKE_CXXFLAGS = @POLYMAKE_CXXFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LDFLAGS = @PTHREAD_LDFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
+PYTHON = @PYTHON@
+PYTHON_CSPEC = @PYTHON_CSPEC@
+PYTHON_EXECPREFIX = @PYTHON_EXECPREFIX@
+PYTHON_LSPEC = @PYTHON_LSPEC@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+RANLIB = @RANLIB@
+RESOURCES_INCLUDES = @RESOURCES_INCLUDES@
+RESOURCES_LIBS = @RESOURCES_LIBS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SINGULAR_CFLAGS = @SINGULAR_CFLAGS@
+SI_COUNTEDREF_AUTOLOAD = @SI_COUNTEDREF_AUTOLOAD@
+SI_CPU_I386 = @SI_CPU_I386@
+SI_CPU_IA64 = @SI_CPU_IA64@
+SI_CPU_PPC = @SI_CPU_PPC@
+SI_CPU_SPARC = @SI_CPU_SPARC@
+SI_CPU_X86_64 = @SI_CPU_X86_64@
+STRIP = @STRIP@
+USEPPROCSDYNAMICLD = @USEPPROCSDYNAMICLD@
+USEPPROCSDYNAMICLDFLAGS = @USEPPROCSDYNAMICLDFLAGS@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
+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@
+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@
+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@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+ACLOCAL_AMFLAGS = -I ../../m4
+AM_CPPFLAGS = -I${top_srcdir} -I${top_builddir} \
+-I${top_srcdir}/libpolys -I${top_builddir}/libpolys \
+${FACTORY_INCLUDES} ${RESOURCES_INCLUDES} ${OMALLOC_INCLUDES} \
+${FLINT_CFLAGS} ${NTL_CFLAGS} ${GMP_CFLAGS}
+
+noinst_LTLIBRARIES = libnumeric.la
+libnumeric_la_SOURCES = mpr_base.cc mpr_inout.cc mpr_numeric.cc
+libnumeric_la_includedir = $(includedir)/singular/kernel/numeric
+libnumeric_la_include_HEADERS = mpr_base.h mpr_inout.h mpr_numeric.h
+TESTS_ENVIRONMENT = SINGULARPATH='${abs_top_builddir}/libpolys/polys/.libs:${abs_top_builddir}/factory/gftables' \
+	SINGULAR_ROOT_DIR='${abs_top_builddir}'
+test_SOURCES = test.cc
+test_LDADD = libnumeric.la ${builddir}/../libkernelCommon.la
+CLEANFILES = $(TESTS)
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .cc .lo .log .o .obj .test .test$(EXEEXT) .trs
+$(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) --foreign kernel/numeric/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign kernel/numeric/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-noinstLTLIBRARIES:
+	-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+	@list='$(noinst_LTLIBRARIES)'; \
+	locs=`for p in $$list; do echo $$p; done | \
+	      sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+	      sort -u`; \
+	test -z "$$locs" || { \
+	  echo rm -f $${locs}; \
+	  rm -f $${locs}; \
+	}
+
+libnumeric.la: $(libnumeric_la_OBJECTS) $(libnumeric_la_DEPENDENCIES) $(EXTRA_libnumeric_la_DEPENDENCIES) 
+	$(AM_V_CXXLD)$(CXXLINK)  $(libnumeric_la_OBJECTS) $(libnumeric_la_LIBADD) $(LIBS)
+
+clean-checkPROGRAMS:
+	@list='$(check_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
+
+test$(EXEEXT): $(test_OBJECTS) $(test_DEPENDENCIES) $(EXTRA_test_DEPENDENCIES) 
+	@rm -f test$(EXEEXT)
+	$(AM_V_CXXLD)$(CXXLINK) $(test_OBJECTS) $(test_LDADD) $(LIBS)
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/mpr_base.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/mpr_inout.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/mpr_numeric.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/test.Po at am__quote@
+
+.cc.o:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+ at am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXXCOMPILE) -c -o $@ $<
+
+.cc.obj:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+ at am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.cc.lo:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+ at am__fastdepCXX_TRUE@	$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LTCXXCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+install-libnumeric_la_includeHEADERS: $(libnumeric_la_include_HEADERS)
+	@$(NORMAL_INSTALL)
+	@list='$(libnumeric_la_include_HEADERS)'; test -n "$(libnumeric_la_includedir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(libnumeric_la_includedir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(libnumeric_la_includedir)" || exit 1; \
+	fi; \
+	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)$(libnumeric_la_includedir)'"; \
+	  $(INSTALL_HEADER) $$files "$(DESTDIR)$(libnumeric_la_includedir)" || exit $$?; \
+	done
+
+uninstall-libnumeric_la_includeHEADERS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(libnumeric_la_include_HEADERS)'; test -n "$(libnumeric_la_includedir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	dir='$(DESTDIR)$(libnumeric_la_includedir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	$(am__define_uniq_tagged_files); \
+	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-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	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"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'.  Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+	rm -f $< $@
+	$(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+	@:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+	@$(am__set_TESTS_bases); \
+	am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+	redo_bases=`for i in $$bases; do \
+	              am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+	            done`; \
+	if test -n "$$redo_bases"; then \
+	  redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+	  redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+	  if $(am__make_dryrun); then :; else \
+	    rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+	  fi; \
+	fi; \
+	if test -n "$$am__remaking_logs"; then \
+	  echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+	       "recursion detected" >&2; \
+	else \
+	  am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+	fi; \
+	if $(am__make_dryrun); then :; else \
+	  st=0;  \
+	  errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+	  for i in $$redo_bases; do \
+	    test -f $$i.trs && test -r $$i.trs \
+	      || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+	    test -f $$i.log && test -r $$i.log \
+	      || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+	  done; \
+	  test $$st -eq 0 || exit 1; \
+	fi
+	@$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+	ws='[ 	]'; \
+	results=`for b in $$bases; do echo $$b.trs; done`; \
+	test -n "$$results" || results=/dev/null; \
+	all=`  grep "^$$ws*:test-result:"           $$results | wc -l`; \
+	pass=` grep "^$$ws*:test-result:$$ws*PASS"  $$results | wc -l`; \
+	fail=` grep "^$$ws*:test-result:$$ws*FAIL"  $$results | wc -l`; \
+	skip=` grep "^$$ws*:test-result:$$ws*SKIP"  $$results | wc -l`; \
+	xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+	xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+	error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+	if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+	  success=true; \
+	else \
+	  success=false; \
+	fi; \
+	br='==================='; br=$$br$$br$$br$$br; \
+	result_count () \
+	{ \
+	    if test x"$$1" = x"--maybe-color"; then \
+	      maybe_colorize=yes; \
+	    elif test x"$$1" = x"--no-color"; then \
+	      maybe_colorize=no; \
+	    else \
+	      echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+	    fi; \
+	    shift; \
+	    desc=$$1 count=$$2; \
+	    if test $$maybe_colorize = yes && test $$count -gt 0; then \
+	      color_start=$$3 color_end=$$std; \
+	    else \
+	      color_start= color_end=; \
+	    fi; \
+	    echo "$${color_start}# $$desc $$count$${color_end}"; \
+	}; \
+	create_testsuite_report () \
+	{ \
+	  result_count $$1 "TOTAL:" $$all   "$$brg"; \
+	  result_count $$1 "PASS: " $$pass  "$$grn"; \
+	  result_count $$1 "SKIP: " $$skip  "$$blu"; \
+	  result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+	  result_count $$1 "FAIL: " $$fail  "$$red"; \
+	  result_count $$1 "XPASS:" $$xpass "$$red"; \
+	  result_count $$1 "ERROR:" $$error "$$mgn"; \
+	}; \
+	{								\
+	  echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" |	\
+	    $(am__rst_title);						\
+	  create_testsuite_report --no-color;				\
+	  echo;								\
+	  echo ".. contents:: :depth: 2";				\
+	  echo;								\
+	  for b in $$bases; do echo $$b; done				\
+	    | $(am__create_global_log);					\
+	} >$(TEST_SUITE_LOG).tmp || exit 1;				\
+	mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG);			\
+	if $$success; then						\
+	  col="$$grn";							\
+	 else								\
+	  col="$$red";							\
+	  test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG);		\
+	fi;								\
+	echo "$${col}$$br$${std}"; 					\
+	echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}";	\
+	echo "$${col}$$br$${std}"; 					\
+	create_testsuite_report --maybe-color;				\
+	echo "$$col$$br$$std";						\
+	if $$success; then :; else					\
+	  echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}";		\
+	  if test -n "$(PACKAGE_BUGREPORT)"; then			\
+	    echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}";	\
+	  fi;								\
+	  echo "$$col$$br$$std";					\
+	fi;								\
+	$$success || exit 1
+
+check-TESTS:
+	@list='$(RECHECK_LOGS)';           test -z "$$list" || rm -f $$list
+	@list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+	@test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+	@set +e; $(am__set_TESTS_bases); \
+	log_list=`for i in $$bases; do echo $$i.log; done`; \
+	trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+	log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+	$(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+	exit $$?;
+recheck: all $(check_PROGRAMS)
+	@test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+	@set +e; $(am__set_TESTS_bases); \
+	bases=`for i in $$bases; do echo $$i; done \
+	         | $(am__list_recheck_tests)` || exit 1; \
+	log_list=`for i in $$bases; do echo $$i.log; done`; \
+	log_list=`echo $$log_list`; \
+	$(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+	        am__force_recheck=am--force-recheck \
+	        TEST_LOGS="$$log_list"; \
+	exit $$?
+test.log: test$(EXEEXT)
+	@p='test$(EXEEXT)'; \
+	b='test'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+.test.log:
+	@p='$<'; \
+	$(am__set_b); \
+	$(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+ at am__EXEEXT_TRUE@.test$(EXEEXT).log:
+ at am__EXEEXT_TRUE@	@p='$<'; \
+ at am__EXEEXT_TRUE@	$(am__set_b); \
+ at am__EXEEXT_TRUE@	$(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ at am__EXEEXT_TRUE@	--log-file $$b.log --trs-file $$b.trs \
+ at am__EXEEXT_TRUE@	$(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ at am__EXEEXT_TRUE@	"$$tst" $(AM_TESTS_FD_REDIRECT)
+
+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_PROGRAMS)
+	$(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(HEADERS)
+installdirs:
+	for dir in "$(DESTDIR)$(libnumeric_la_includedir)"; 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:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+	-test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+	-test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+	-test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+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-checkPROGRAMS clean-generic clean-libtool \
+	clean-noinstLTLIBRARIES 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-libnumeric_la_includeHEADERS
+
+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: uninstall-libnumeric_la_includeHEADERS
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am clean \
+	clean-checkPROGRAMS clean-generic clean-libtool \
+	clean-noinstLTLIBRARIES cscopelist-am ctags ctags-am 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-libnumeric_la_includeHEADERS 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 \
+	recheck tags tags-am uninstall uninstall-am \
+	uninstall-libnumeric_la_includeHEADERS
+
+
+# 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/kernel/numeric/mpr_base.cc b/kernel/numeric/mpr_base.cc
new file mode 100644
index 0000000..d41fe62
--- /dev/null
+++ b/kernel/numeric/mpr_base.cc
@@ -0,0 +1,3229 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+
+/*
+ * ABSTRACT - multipolynomial resultants - resultant matrices
+ *            ( sparse, dense, u-resultant solver )
+ */
+
+//-> includes
+
+
+
+#include <kernel/mod2.h>
+
+#include <misc/auxiliary.h>
+#include <omalloc/omalloc.h>
+
+#include <misc/mylimits.h>
+#include <misc/options.h>
+#include <misc/intvec.h>
+#include <misc/sirandom.h>
+
+#include <coeffs/numbers.h>
+#include <coeffs/mpr_global.h>
+
+#include <polys/matpol.h>
+#include <polys/sparsmat.h>
+
+#include <polys/clapsing.h>
+
+#include <kernel/polys.h>
+#include <kernel/ideals.h>
+
+#include "mpr_base.h"
+#include "mpr_numeric.h"
+
+#include <math.h>
+//<-
+
+//%s
+//-----------------------------------------------------------------------------
+//-------------- sparse resultant matrix --------------------------------------
+//-----------------------------------------------------------------------------
+
+//-> definitions
+
+//#define mprTEST
+//#define mprMINKSUM
+
+#define MAXPOINTS      10000
+#define MAXINITELEMS   256
+#define LIFT_COOR      50000   // siRand() % LIFT_COOR gives random lift value
+#define SCALEDOWN      100.0  // lift value scale down for linear program
+#define MINVDIST       0.0
+#define RVMULT         0.0001 // multiplicator for random shift vector
+#define MAXRVVAL       50000
+#define MAXVARS        100
+//<-
+
+//-> sparse resultant matrix
+
+/* set of points */
+class pointSet;
+
+
+
+/* sparse resultant matrix class */
+class resMatrixSparse : virtual public resMatrixBase
+{
+public:
+  resMatrixSparse( const ideal _gls, const int special = SNONE );
+  ~resMatrixSparse();
+
+  // public interface according to base class resMatrixBase
+  ideal getMatrix();
+
+  /** Fills in resMat[][] with evpoint[] and gets determinant
+   * uRPos[i][1]: row of matrix
+   * uRPos[i][idelem+1]: col of u(0)
+   *  uRPos[i][2..idelem]: col of u(1) .. u(n)
+   *  i= 1 .. numSet0
+   */
+  number getDetAt( const number* evpoint );
+
+  poly getUDet( const number* evpoint );
+
+private:
+  resMatrixSparse( const resMatrixSparse & );
+
+  void randomVector( const int dim, mprfloat shift[] );
+
+  /** Row Content Function
+   * Finds the largest i such that F[i] is a point, F[i]= a[ij] in A[i] for some j.
+   * Returns -1 iff the point vert does not lie in a cell
+   */
+  int RC( pointSet **pQ, pointSet *E, int vert, mprfloat shift[] );
+
+  /* Remaps a result of LP to the according point set Qi.
+   * Returns false iff remaping was not possible, otherwise true.
+   */
+  bool remapXiToPoint( const int indx, pointSet **pQ, int *set, int *vtx );
+
+  /** create coeff matrix
+   * uRPos[i][1]: row of matrix
+   * uRPos[i][idelem+1]: col of u(0)
+   *  uRPos[i][2..idelem]: col of u(1) .. u(n)
+   *  i= 1 .. numSet0
+   * Returns the dimension of the matrix or -1 in case of an error
+   */
+  int createMatrix( pointSet *E );
+
+  pointSet * minkSumAll( pointSet **pQ, int numq, int dim );
+  pointSet * minkSumTwo( pointSet *Q1, pointSet *Q2, int dim );
+
+private:
+  ideal gls;
+
+  int n, idelem;     // number of variables, polynoms
+  int numSet0;       // number of elements in S0
+  int msize;         // size of matrix
+
+  intvec *uRPos;
+
+  ideal rmat;        // sparse matrix representation
+
+  simplex * LP;      // linear programming stuff
+};
+//<-
+
+//-> typedefs and structs
+poly monomAt( poly p, int i );
+
+typedef unsigned int Coord_t;
+
+struct setID
+{
+  int set;
+  int pnt;
+};
+
+struct onePoint
+{
+  Coord_t * point;             // point[0] is unused, maxial dimension is MAXVARS+1
+  setID rc;                    // filled in by Row Content Function
+  struct onePoint * rcPnt;     // filled in by Row Content Function
+};
+
+typedef struct onePoint * onePointP;
+
+/* sparse matrix entry */
+struct _entry
+{
+  number num;
+  int col;
+  struct _entry * next;
+};
+
+typedef struct _entry * entry;
+//<-
+
+//-> class pointSet
+class pointSet
+{
+private:
+  onePointP *points;     // set of onePoint's, index [1..num], supports of monoms
+  bool lifted;
+
+public:
+  int num;               // number of elements in points
+  int max;               // maximal entries in points, i.e. allocated mem
+  int dim;               // dimension, i.e. valid coord entries in point
+  int index;             // should hold unique identifier of point set
+
+  pointSet( const int _dim, const int _index= 0, const int count= MAXINITELEMS );
+   ~pointSet();
+
+  // pointSet.points[i] equals pointSet[i]
+  inline onePointP operator[] ( const int index );
+
+  /** Adds a point to pointSet, copy vert[0,...,dim] ot point[num+1][0,...,dim].
+   * Returns false, iff additional memory was allocated ( i.e. num >= max )
+   * else returns true
+   */
+  bool addPoint( const onePointP vert );
+
+  /** Adds a point to pointSet, copy vert[0,...,dim] ot point[num+1][0,...,dim].
+   * Returns false, iff additional memory was allocated ( i.e. num >= max )
+   * else returns true
+   */
+  bool addPoint( const int * vert );
+
+  /** Adds a point to pointSet, copy vert[0,...,dim] ot point[num+1][0,...,dim].
+   * Returns false, iff additional memory was allocated ( i.e. num >= max )
+   * else returns true
+   */
+  bool addPoint( const Coord_t * vert );
+
+  /* Removes the point at intex indx */
+  bool removePoint( const int indx );
+
+  /** Adds point to pointSet, iff pointSet \cap point = \emptyset.
+   * Returns true, iff added, else false.
+   */
+  bool mergeWithExp( const onePointP vert );
+
+  /** Adds point to pointSet, iff pointSet \cap point = \emptyset.
+   * Returns true, iff added, else false.
+   */
+  bool mergeWithExp( const int * vert );
+
+  /* Adds support of poly p to pointSet, iff pointSet \cap point = \emptyset. */
+  void mergeWithPoly( const poly p );
+
+  /* Returns the row polynom multiplicator in vert[] */
+  void getRowMP( const int indx, int * vert );
+
+  /* Returns index of supp(LT(p)) in pointSet. */
+  int getExpPos( const poly p );
+
+  /** sort lex
+   */
+  void sort();
+
+  /** Lifts the point set using sufficiently generic linear lifting
+   * homogeneous forms l[1]..l[dim] in Z. Every l[i] is of the form
+   * L1x1+...+Lnxn, for generic L1..Ln in Z.
+   *
+   * Lifting raises dimension by one!
+   */
+  void lift( int *l= NULL );     // !! increments dim by 1
+  void unlift() { dim--; lifted= false; }
+
+private:
+  pointSet( const pointSet & );
+
+  /** points[a] < points[b] ? */
+  inline bool smaller( int, int );
+
+  /** points[a] > points[b] ? */
+  inline bool larger( int, int );
+
+  /** Checks, if more mem is needed ( i.e. num >= max ),
+   * returns false, if more mem was allocated, else true
+   */
+  inline bool checkMem();
+};
+//<-
+
+//-> class convexHull
+/* Compute convex hull of given exponent set */
+class convexHull
+{
+public:
+  convexHull( simplex * _pLP ) : pLP(_pLP) {}
+  ~convexHull() {}
+
+  /** Computes the point sets of the convex hulls of the supports given
+   * by the polynoms in gls.
+   * Returns Q[].
+   */
+  pointSet ** newtonPolytopesP( const ideal gls );
+  ideal newtonPolytopesI( const ideal gls );
+
+private:
+  /** Returns true iff the support of poly pointPoly is inside the
+   * convex hull of all points given by the  support of poly p.
+   */
+  bool inHull(poly p, poly pointPoly, int m, int site);
+
+private:
+  pointSet **Q;
+  int n;
+  simplex * pLP;
+};
+//<-
+
+//-> class mayanPyramidAlg
+/* Compute all lattice points in a given convex hull */
+class mayanPyramidAlg
+{
+public:
+  mayanPyramidAlg( simplex * _pLP ) : n((currRing->N)), pLP(_pLP) {}
+  ~mayanPyramidAlg() {}
+
+  /** Drive Mayan Pyramid Algorithm.
+   * The Alg computes conv(Qi[]+shift[]).
+   */
+  pointSet * getInnerPoints( pointSet **_q_i, mprfloat _shift[] );
+
+private:
+
+  /** Recursive Mayan Pyramid algorithm for directly computing MinkowskiSum
+   * lattice points for (n+1)-fold MinkowskiSum of given point sets Qi[].
+   * Recursively for range of dim: dim in [0..n); acoords[0..var) fixed.
+   * Stores only MinkowskiSum points of udist > 0: done by storeMinkowskiSumPoints.
+   */
+  void runMayanPyramid( int dim );
+
+  /**  Compute v-distance via Linear Programing
+   * Linear Program finds the v-distance of the point in accords[].
+   * The v-distance is the distance along the direction v to boundary of
+   * Minkowski Sum of Qi (here vector v is represented by shift[]).
+   * Returns the v-distance or -1.0 if an error occured.
+   */
+  mprfloat vDistance( Coord_t * acoords, int dim );
+
+  /** LP for finding min/max coord in MinkowskiSum, given previous coors.
+   * Assume MinkowskiSum in non-negative quadrants
+   * coor in [0,n); fixed coords in acoords[0..coor)
+   */
+  void mn_mx_MinkowskiSum( int dim, Coord_t *minR, Coord_t *maxR );
+
+  /**  Stores point in E->points[pt], iff v-distance != 0
+   * Returns true iff point was stored, else flase
+   */
+  bool storeMinkowskiSumPoint();
+
+private:
+  pointSet **Qi;
+  pointSet *E;
+  mprfloat *shift;
+
+  int n,idelem;
+
+  Coord_t acoords[MAXVARS+2];
+
+  simplex * pLP;
+};
+//<-
+
+//-> debug output stuff
+#if defined(mprDEBUG_PROT) || defined(mprDEBUG_ALL)
+void print_mat(mprfloat **a, int maxrow, int maxcol)
+{
+  int i, j;
+
+  for (i = 1; i <= maxrow; i++)
+  {
+    PrintS("[");
+    for (j = 1; j <= maxcol; j++) Print("% 7.2f, ", a[i][j]);
+    PrintS("],\n");
+  }
+}
+void print_bmat(mprfloat **a, int nrows, int ncols, int N, int *iposv)
+{
+  int i, j;
+
+  printf("Output matrix from LinProg");
+  for (i = 1; i <= nrows; i++)
+  {
+    printf("\n[ ");
+    if (i == 1) printf("  ");
+    else if (iposv[i-1] <= N) printf("X%d", iposv[i-1]);
+    else printf("Y%d", iposv[i-1]-N+1);
+    for (j = 1; j <= ncols; j++) printf(" %7.2f ",(double)a[i][j]);
+    printf(" ]");
+  } printf("\n");
+  fflush(stdout);
+}
+
+void print_exp( const onePointP vert, int n )
+{
+  int i;
+  for ( i= 1; i <= n; i++ )
+  {
+    Print(" %d",vert->point[i] );
+#ifdef LONG_OUTPUT
+    if ( i < n ) PrintS(", ");
+#endif
+  }
+}
+void print_matrix( matrix omat )
+{
+  int i,j;
+  int val;
+  Print(" matrix m[%d][%d]=(\n",MATROWS( omat ),MATCOLS( omat ));
+  for ( i= 1; i <= MATROWS( omat ); i++ )
+  {
+    for ( j= 1; j <= MATCOLS( omat ); j++ )
+    {
+      if ( (MATELEM( omat, i, j)!=NULL)
+      && (!nIsZero(pGetCoeff( MATELEM( omat, i, j)))))
+      {
+        val= n_Int(pGetCoeff( MATELEM( omat, i, j) ), currRing->cf);
+        if ( i==MATROWS(omat) && j==MATCOLS(omat) )
+        {
+          Print("%d ",val);
+        }
+        else
+        {
+          Print("%d, ",val);
+        }
+      }
+      else
+      {
+        if ( i==MATROWS(omat) && j==MATCOLS(omat) )
+        {
+          PrintS("  0");
+        }
+        else
+        {
+          PrintS("  0, ");
+        }
+      }
+    }
+    PrintLn();
+  }
+  PrintS(");\n");
+}
+#endif
+//<-
+
+//-> pointSet::*
+pointSet::pointSet( const int _dim, const int _index, const int count )
+  : num(0), max(count), dim(_dim), index(_index)
+{
+  int i;
+  points = (onePointP *)omAlloc( (count+1) * sizeof(onePointP) );
+  for ( i= 0; i <= max; i++ )
+  {
+    points[i]= (onePointP)omAlloc( sizeof(onePoint) );
+    points[i]->point= (Coord_t *)omAlloc0( (dim+2) * sizeof(Coord_t) );
+  }
+  lifted= false;
+}
+
+pointSet::~pointSet()
+{
+  int i;
+  int fdim= lifted ? dim+1 : dim+2;
+  for ( i= 0; i <= max; i++ )
+  {
+    omFreeSize( (void *) points[i]->point, fdim * sizeof(Coord_t) );
+    omFreeSize( (void *) points[i], sizeof(onePoint) );
+  }
+  omFreeSize( (void *) points, (max+1) * sizeof(onePointP) );
+}
+
+inline onePointP pointSet::operator[] ( const int index_i )
+{
+  assume( index_i > 0 && index_i <= num );
+  return points[index_i];
+}
+
+inline bool pointSet::checkMem()
+{
+  if ( num >= max )
+  {
+    int i;
+    int fdim= lifted ? dim+1 : dim+2;
+    points= (onePointP*)omReallocSize( points,
+                                 (max+1) * sizeof(onePointP),
+                                 (2*max + 1) * sizeof(onePointP) );
+    for ( i= max+1; i <= max*2; i++ )
+    {
+      points[i]= (onePointP)omAlloc( sizeof(struct onePoint) );
+      points[i]->point= (Coord_t *)omAlloc0( fdim * sizeof(Coord_t) );
+    }
+    max*= 2;
+    mprSTICKYPROT(ST_SPARSE_MEM);
+    return false;
+  }
+  return true;
+}
+
+bool pointSet::addPoint( const onePointP vert )
+{
+  int i;
+  bool ret;
+  num++;
+  ret= checkMem();
+  points[num]->rcPnt= NULL;
+  for ( i= 1; i <= dim; i++ ) points[num]->point[i]= vert->point[i];
+  return ret;
+}
+
+bool pointSet::addPoint( const int * vert )
+{
+  int i;
+  bool ret;
+  num++;
+  ret= checkMem();
+  points[num]->rcPnt= NULL;
+  for ( i= 1; i <= dim; i++ ) points[num]->point[i]= (Coord_t) vert[i];
+  return ret;
+}
+
+bool pointSet::addPoint( const Coord_t * vert )
+{
+  int i;
+  bool ret;
+  num++;
+  ret= checkMem();
+  points[num]->rcPnt= NULL;
+  for ( i= 0; i < dim; i++ ) points[num]->point[i+1]= vert[i];
+  return ret;
+}
+
+bool pointSet::removePoint( const int indx )
+{
+  assume( indx > 0 && indx <= num );
+  if ( indx != num )
+  {
+    onePointP tmp;
+    tmp= points[indx];
+    points[indx]= points[num];
+    points[num]= tmp;
+  }
+  num--;
+
+  return true;
+}
+
+bool pointSet::mergeWithExp( const onePointP vert )
+{
+  int i,j;
+
+  for ( i= 1; i <= num; i++ )
+  {
+    for ( j= 1; j <= dim; j++ )
+      if ( points[i]->point[j] != vert->point[j] ) break;
+    if ( j > dim ) break;
+  }
+
+  if ( i > num )
+  {
+    addPoint( vert );
+    return true;
+  }
+  return false;
+}
+
+bool pointSet::mergeWithExp( const int * vert )
+{
+  int i,j;
+
+  for ( i= 1; i <= num; i++ )
+  {
+    for ( j= 1; j <= dim; j++ )
+      if ( points[i]->point[j] != (Coord_t) vert[j] ) break;
+    if ( j > dim ) break;
+  }
+
+  if ( i > num )
+  {
+    addPoint( vert );
+    return true;
+  }
+  return false;
+}
+
+void pointSet::mergeWithPoly( const poly p )
+{
+  int i,j;
+  poly piter= p;
+  int * vert;
+  vert= (int *)omAlloc( (dim+1) * sizeof(int) );
+
+  while ( piter )
+  {
+    pGetExpV( piter, vert );
+
+    for ( i= 1; i <= num; i++ )
+    {
+      for ( j= 1; j <= dim; j++ )
+        if ( points[i]->point[j] != (Coord_t) vert[j] ) break;
+      if ( j > dim ) break;
+    }
+
+    if ( i > num )
+    {
+      addPoint( vert );
+    }
+
+    pIter( piter );
+  }
+  omFreeSize( (void *) vert, (dim+1) * sizeof(int) );
+}
+
+int pointSet::getExpPos( const poly p )
+{
+  int * vert;
+  int i,j;
+
+  // hier unschoen...
+  vert= (int *)omAlloc( (dim+1) * sizeof(int) );
+
+  pGetExpV( p, vert );
+  for ( i= 1; i <= num; i++ )
+  {
+    for ( j= 1; j <= dim; j++ )
+      if ( points[i]->point[j] != (Coord_t) vert[j] ) break;
+    if ( j > dim ) break;
+  }
+  omFreeSize( (void *) vert, (dim+1) * sizeof(int) );
+
+  if ( i > num ) return 0;
+  else return i;
+}
+
+void pointSet::getRowMP( const int indx, int * vert )
+{
+  assume( indx > 0 && indx <= num && points[indx]->rcPnt );
+  int i;
+
+  vert[0]= 0;
+  for ( i= 1; i <= dim; i++ )
+    vert[i]= (int)(points[indx]->point[i] - points[indx]->rcPnt->point[i]);
+}
+
+inline bool pointSet::smaller( int a, int b )
+{
+  int i;
+
+  for ( i= 1; i <= dim; i++ )
+  {
+    if ( points[a]->point[i] > points[b]->point[i] )
+    {
+      return false;
+    }
+    if ( points[a]->point[i] < points[b]->point[i] )
+    {
+      return true;
+    }
+  }
+
+ return false; // they are equal
+}
+
+inline bool pointSet::larger( int a, int b )
+{
+  int i;
+
+  for ( i= 1; i <= dim; i++ )
+  {
+    if ( points[a]->point[i] < points[b]->point[i] )
+    {
+      return false;
+    }
+    if ( points[a]->point[i] > points[b]->point[i] )
+    {
+      return true;
+    }
+  }
+
+ return false; // they are equal
+}
+
+void pointSet::sort()
+{
+  int i;
+  bool found= true;
+  onePointP tmp;
+
+  while ( found )
+  {
+    found= false;
+    for ( i= 1; i < num; i++ )
+    {
+      if ( larger( i, i+1 ) )
+      {
+        tmp= points[i];
+        points[i]= points[i+1];
+        points[i+1]= tmp;
+
+        found= true;
+      }
+    }
+  }
+}
+
+void pointSet::lift( int l[] )
+{
+  bool outerL= true;
+  int i, j;
+  int sum;
+
+  dim++;
+
+  if ( l==NULL )
+  {
+    outerL= false;
+    l= (int *)omAlloc( (dim+1) * sizeof(int) ); // [1..dim-1]
+
+    for(i = 1; i < dim; i++)
+    {
+      l[i]= 1 + siRand() % LIFT_COOR;
+    }
+  }
+  for ( j=1; j <= num; j++ )
+  {
+    sum= 0;
+    for ( i=1; i < dim; i++ )
+    {
+      sum += (int)points[j]->point[i] * l[i];
+    }
+    points[j]->point[dim]= sum;
+  }
+
+#ifdef mprDEBUG_ALL
+  PrintS(" lift vector: ");
+  for ( j=1; j < dim; j++ ) Print(" %d ",l[j] );
+  PrintLn();
+#ifdef mprDEBUG_ALL
+  PrintS(" lifted points: \n");
+  for ( j=1; j <= num; j++ )
+  {
+    Print("%d: <",j);print_exp(points[j],dim);PrintS(">\n");
+  }
+  PrintLn();
+#endif
+#endif
+
+  lifted= true;
+
+  if ( !outerL ) omFreeSize( (void *) l, (dim+1) * sizeof(int) );
+}
+//<-
+
+//-> global functions
+// Returns the monom at pos i in poly p
+poly monomAt( poly p, int i )
+{
+  assume( i > 0 );
+  poly iter= p;
+  for ( int j= 1; (j < i) && (iter!=NULL); j++ ) pIter(iter);
+  return iter;
+}
+//<-
+
+//-> convexHull::*
+bool convexHull::inHull(poly p, poly pointPoly, int m, int site)
+{
+  int i, j, col;
+
+  pLP->m = n+1;
+  pLP->n = m;                // this includes col of cts
+
+  pLP->LiPM[1][1] = +0.0;
+  pLP->LiPM[1][2] = +1.0;        // optimize (arbitrary) var
+  pLP->LiPM[2][1] = +1.0;
+  pLP->LiPM[2][2] = -1.0;         // lambda vars sum up to 1
+
+  for ( j=3; j <= pLP->n; j++)
+  {
+    pLP->LiPM[1][j] = +0.0;
+    pLP->LiPM[2][j] = -1.0;
+  }
+
+  for( i= 1; i <= n; i++) {        // each row constraints one coor
+    pLP->LiPM[i+2][1] = (mprfloat)pGetExp(pointPoly,i);
+    col = 2;
+    for( j= 1; j <= m; j++ )
+    {
+      if( j != site )
+      {
+        pLP->LiPM[i+2][col] = -(mprfloat)pGetExp( monomAt(p,j), i );
+        col++;
+      }
+    }
+  }
+
+#ifdef mprDEBUG_ALL
+  PrintS("Matrix of Linear Programming\n");
+  print_mat( pLP->LiPM, pLP->m+1,pLP->n);
+#endif
+
+  pLP->m3= pLP->m;
+
+  pLP->compute();
+
+  return (pLP->icase == 0);
+}
+
+// mprSTICKYPROT:
+// ST_SPARSE_VADD: new vertex of convex hull added
+// ST_SPARSE_VREJ: point rejected (-> inside hull)
+pointSet ** convexHull::newtonPolytopesP( const ideal gls )
+{
+  int i, j, k;
+  int m;  // Anzahl der Exponentvektoren im i-ten Polynom (gls->m)[i] des Ideals gls
+  int idelem= IDELEMS(gls);
+  int * vert;
+
+  n= (currRing->N);
+  vert= (int *)omAlloc( (idelem+1) * sizeof(int) );
+
+  Q = (pointSet **)omAlloc( idelem * sizeof(pointSet*) );        // support hulls
+  for ( i= 0; i < idelem; i++ )
+    Q[i] = new pointSet( (currRing->N), i+1, pLength((gls->m)[i])+1 );
+
+  for( i= 0; i < idelem; i++ )
+  {
+    k=1;
+    m = pLength( (gls->m)[i] );
+
+    poly p= (gls->m)[i];
+    for( j= 1; j <= m; j++) {  // f�r jeden Exponentvektor
+      if( !inHull( (gls->m)[i], p, m, j ) )
+      {
+        pGetExpV( p, vert );
+        Q[i]->addPoint( vert );
+        k++;
+        mprSTICKYPROT(ST_SPARSE_VADD);
+      }
+      else
+      {
+        mprSTICKYPROT(ST_SPARSE_VREJ);
+      }
+      pIter( p );
+    } // j
+    mprSTICKYPROT("\n");
+  } // i
+
+  omFreeSize( (void *) vert, (idelem+1) * sizeof(int) );
+
+#ifdef mprDEBUG_PROT
+  PrintLn();
+  for( i= 0; i < idelem; i++ )
+  {
+    Print(" \\Conv(Qi[%d]): #%d\n", i,Q[i]->num );
+    for ( j=1; j <= Q[i]->num; j++ )
+    {
+      Print("%d: <",j);print_exp( (*Q[i])[j] , (currRing->N) );PrintS(">\n");
+    }
+    PrintLn();
+  }
+#endif
+
+  return Q;
+}
+
+// mprSTICKYPROT:
+// ST_SPARSE_VADD: new vertex of convex hull added
+// ST_SPARSE_VREJ: point rejected (-> inside hull)
+ideal convexHull::newtonPolytopesI( const ideal gls )
+{
+  int i, j;
+  int m;  // Anzahl der Exponentvektoren im i-ten Polynom (gls->m)[i] des Ideals gls
+  int idelem= IDELEMS(gls);
+  ideal id;
+  poly p,pid;
+  int * vert;
+
+  n= (currRing->N);
+  vert= (int *)omAlloc( (idelem+1) * sizeof(int) );
+  id= idInit( idelem, 1 );
+
+  for( i= 0; i < idelem; i++ )
+  {
+    m = pLength( (gls->m)[i] );
+
+    p= (gls->m)[i];
+    for( j= 1; j <= m; j++) {  // f�r jeden Exponentvektor
+      if( !inHull( (gls->m)[i], p, m, j ) )
+      {
+        if ( (id->m)[i] == NULL )
+        {
+          (id->m)[i]= pHead(p);
+          pid=(id->m)[i];
+        }
+        else
+        {
+          pNext(pid)= pHead(p);
+          pIter(pid);
+          pNext(pid)= NULL;
+        }
+        mprSTICKYPROT(ST_SPARSE_VADD);
+      }
+      else
+      {
+        mprSTICKYPROT(ST_SPARSE_VREJ);
+      }
+      pIter( p );
+    } // j
+    mprSTICKYPROT("\n");
+  } // i
+
+  omFreeSize( (void *) vert, (idelem+1) * sizeof(int) );
+
+#ifdef mprDEBUG_PROT
+  PrintLn();
+  for( i= 0; i < idelem; i++ )
+  {
+  }
+#endif
+
+  return id;
+}
+//<-
+
+//-> mayanPyramidAlg::*
+pointSet * mayanPyramidAlg::getInnerPoints( pointSet **_q_i, mprfloat _shift[] )
+{
+  int i;
+
+  Qi= _q_i;
+  shift= _shift;
+
+  E= new pointSet( Qi[0]->dim ); // E has same dim as Qi[...]
+
+  for ( i= 0; i < MAXVARS+2; i++ ) acoords[i]= 0;
+
+  runMayanPyramid(0);
+
+  mprSTICKYPROT("\n");
+
+  return E;
+}
+
+mprfloat mayanPyramidAlg::vDistance( Coord_t * acoords_a, int dim )
+{
+  int i, ii, j, k, col, r;
+  int numverts, cols;
+
+  numverts = 0;
+  for( i=0; i<=n; i++)
+  {
+    numverts += Qi[i]->num;
+  }
+  cols = numverts + 2;
+
+  //if( dim < 1 || dim > n )
+  //  WerrorS("mayanPyramidAlg::vDistance: Known coords dim off range");
+
+  pLP->LiPM[1][1] = 0.0;
+  pLP->LiPM[1][2] = 1.0;        // maximize
+  for( j=3; j<=cols; j++) pLP->LiPM[1][j] = 0.0;
+
+  for( i=0; i <= n; i++ )
+  {
+    pLP->LiPM[i+2][1] = 1.0;
+    pLP->LiPM[i+2][2] = 0.0;
+  }
+  for( i=1; i<=dim; i++)
+  {
+    pLP->LiPM[n+2+i][1] = (mprfloat)(acoords_a[i-1]);
+    pLP->LiPM[n+2+i][2] = -shift[i];
+  }
+
+  ii = -1;
+  col = 2;
+  for ( i= 0; i <= n; i++ )
+  {
+    ii++;
+    for( k= 1; k <= Qi[ii]->num; k++ )
+    {
+      col++;
+      for ( r= 0; r <= n; r++ )
+      {
+        if ( r == i ) pLP->LiPM[r+2][col] = -1.0;
+        else pLP->LiPM[r+2][col] = 0.0;
+      }
+      for( r= 1; r <= dim; r++ )
+        pLP->LiPM[r+n+2][col] = -(mprfloat)((*Qi[ii])[k]->point[r]);
+    }
+  }
+
+  if( col != cols)
+    Werror("mayanPyramidAlg::vDistance:"
+           "setting up matrix for udist: col %d != cols %d",col,cols);
+
+  pLP->m = n+dim+1;
+  pLP->m3= pLP->m;
+  pLP->n=cols-1;
+
+#ifdef mprDEBUG_ALL
+  Print("vDistance LP, known koords dim=%d, constr %d, cols %d, acoords= ",
+        dim,pLP->m,cols);
+  for( i= 0; i < dim; i++ )
+    Print(" %d",acoords_a[i]);
+  PrintLn();
+  print_mat( pLP->LiPM, pLP->m+1, cols);
+#endif
+
+  pLP->compute();
+
+#ifdef mprDEBUG_ALL
+  PrintS("LP returns matrix\n");
+  print_bmat( pLP->LiPM, pLP->m+1, cols+1-pLP->m, cols, pLP->iposv);
+#endif
+
+  if( pLP->icase != 0 )
+  {  // check for errors
+    WerrorS("mayanPyramidAlg::vDistance:");
+    if( pLP->icase == 1 )
+      WerrorS(" Unbounded v-distance: probably 1st v-coor=0");
+    else if( pLP->icase == -1 )
+      WerrorS(" Infeasible v-distance");
+    else
+      WerrorS(" Unknown error");
+    return -1.0;
+  }
+
+  return pLP->LiPM[1][1];
+}
+
+void  mayanPyramidAlg::mn_mx_MinkowskiSum( int dim, Coord_t *minR, Coord_t *maxR )
+{
+  int i, j, k, cols, cons;
+  int la_cons_row;
+
+  cons = n+dim+2;
+
+  // first, compute minimum
+  //
+
+  // common part of the matrix
+  pLP->LiPM[1][1] = 0.0;
+  for( i=2; i<=n+2; i++)
+  {
+    pLP->LiPM[i][1] = 1.0;        // 1st col
+    pLP->LiPM[i][2] = 0.0;        // 2nd col
+  }
+
+  la_cons_row = 1;
+  cols = 2;
+  for( i=0; i<=n; i++)
+  {
+    la_cons_row++;
+    for( j=1; j<= Qi[i]->num; j++)
+    {
+      cols++;
+      pLP->LiPM[1][cols] = 0.0;        // set 1st row 0
+      for( k=2; k<=n+2; k++)
+      {  // lambdas sum up to 1
+        if( k != la_cons_row) pLP->LiPM[k][cols] = 0.0;
+        else pLP->LiPM[k][cols] = -1.0;
+      }
+      for( k=1; k<=n; k++)
+        pLP->LiPM[k+n+2][cols] = -(mprfloat)((*Qi[i])[j]->point[k]);
+    } // j
+  } // i
+
+  for( i= 0; i < dim; i++ )
+  {                // fixed coords
+    pLP->LiPM[i+n+3][1] = acoords[i];
+    pLP->LiPM[i+n+3][2] = 0.0;
+  }
+  pLP->LiPM[dim+n+3][1] = 0.0;
+
+
+  pLP->LiPM[1][2] = -1.0;                        // minimize
+  pLP->LiPM[dim+n+3][2] = 1.0;
+
+#ifdef mprDEBUG_ALL
+  Print("\nThats the matrix for minR, dim= %d, acoords= ",dim);
+  for( i= 0; i < dim; i++ )
+    Print(" %d",acoords[i]);
+  PrintLn();
+  print_mat( pLP->LiPM, cons+1, cols);
+#endif
+
+  // simplx finds MIN for obj.fnc, puts it in [1,1]
+  pLP->m= cons;
+  pLP->n= cols-1;
+  pLP->m3= cons;
+
+  pLP->compute();
+
+  if ( pLP->icase != 0 )
+  { // check for errors
+    if( pLP->icase < 0)
+      WerrorS(" mn_mx_MinkowskiSum: LinearProgram: minR: infeasible");
+    else if( pLP->icase > 0)
+      WerrorS(" mn_mx_MinkowskiSum: LinearProgram: minR: unbounded");
+  }
+
+  *minR = (Coord_t)( -pLP->LiPM[1][1] + 1.0 - SIMPLEX_EPS );
+
+  // now compute maximum
+  //
+
+  // common part of the matrix again
+  pLP->LiPM[1][1] = 0.0;
+  for( i=2; i<=n+2; i++)
+  {
+    pLP->LiPM[i][1] = 1.0;
+    pLP->LiPM[i][2] = 0.0;
+  }
+  la_cons_row = 1;
+  cols = 2;
+  for( i=0; i<=n; i++)
+  {
+    la_cons_row++;
+    for( j=1; j<=Qi[i]->num; j++)
+    {
+      cols++;
+      pLP->LiPM[1][cols] = 0.0;
+      for( k=2; k<=n+2; k++)
+      {
+        if( k != la_cons_row) pLP->LiPM[k][cols] = 0.0;
+        else pLP->LiPM[k][cols] = -1.0;
+      }
+      for( k=1; k<=n; k++)
+        pLP->LiPM[k+n+2][cols] = -(mprfloat)((*Qi[i])[j]->point[k]);
+    } // j
+  }  // i
+
+  for( i= 0; i < dim; i++ )
+  {                // fixed coords
+    pLP->LiPM[i+n+3][1] = acoords[i];
+    pLP->LiPM[i+n+3][2] = 0.0;
+  }
+  pLP->LiPM[dim+n+3][1] = 0.0;
+
+  pLP->LiPM[1][2] = 1.0;                      // maximize
+  pLP->LiPM[dim+n+3][2] = 1.0;                // var = sum of pnt coords
+
+#ifdef mprDEBUG_ALL
+  Print("\nThats the matrix for maxR, dim= %d\n",dim);
+  print_mat( pLP->LiPM, cons+1, cols);
+#endif
+
+  pLP->m= cons;
+  pLP->n= cols-1;
+  pLP->m3= cons;
+
+  // simplx finds MAX for obj.fnc, puts it in [1,1]
+  pLP->compute();
+
+  if ( pLP->icase != 0 )
+  {
+    if( pLP->icase < 0)
+      WerrorS(" mn_mx_MinkowskiSum: LinearProgram: maxR: infeasible");
+    else if( pLP->icase > 0)
+      WerrorS(" mn_mx_MinkowskiSum: LinearProgram: maxR: unbounded");
+  }
+
+  *maxR = (Coord_t)( pLP->LiPM[1][1] + SIMPLEX_EPS );
+
+#ifdef mprDEBUG_ALL
+  Print("  Range for dim=%d: [%d,%d]\n", dim, *minR, *maxR);
+#endif
+}
+
+// mprSTICKYPROT:
+// ST_SPARSE_VREJ: rejected point
+// ST_SPARSE_VADD: added point to set
+bool mayanPyramidAlg::storeMinkowskiSumPoint()
+{
+  mprfloat dist;
+
+  // determine v-distance of point pt
+  dist= vDistance( &(acoords[0]), n );
+
+  // store only points with v-distance > minVdist
+  if( dist <= MINVDIST + SIMPLEX_EPS )
+  {
+    mprSTICKYPROT(ST_SPARSE_VREJ);
+    return false;
+  }
+
+  E->addPoint( &(acoords[0]) );
+  mprSTICKYPROT(ST_SPARSE_VADD);
+
+  return true;
+}
+
+// mprSTICKYPROT:
+// ST_SPARSE_MREC1: recurse
+// ST_SPARSE_MREC2: recurse with extra points
+// ST_SPARSE_MPEND: end
+void mayanPyramidAlg::runMayanPyramid( int dim )
+{
+  Coord_t minR, maxR;
+  mprfloat dist;
+
+  // step 3
+  mn_mx_MinkowskiSum( dim, &minR, &maxR );
+
+#ifdef mprDEBUG_ALL
+  int i;
+  for( i=0; i <= dim; i++) Print("acoords[%d]=%d ",i,(int)acoords[i]);
+  Print(":: [%d,%d]\n", minR, maxR);
+#endif
+
+  // step 5 -> terminate
+  if( dim == n-1 )
+  {
+    int lastKilled = 0;
+    // insert points
+    acoords[dim] = minR;
+    while( acoords[dim] <= maxR )
+    {
+      if( !storeMinkowskiSumPoint() )
+        lastKilled++;
+      acoords[dim]++;
+    }
+    mprSTICKYPROT(ST_SPARSE_MPEND);
+    return;
+  }
+
+  // step 4 -> recurse at step 3
+  acoords[dim] = minR;
+  while ( acoords[dim] <= maxR )
+  {
+    if ( (acoords[dim] > minR) && (acoords[dim] <= maxR) )
+    {     // acoords[dim] >= minR  ??
+      mprSTICKYPROT(ST_SPARSE_MREC1);
+      runMayanPyramid( dim + 1 );         // recurse with higer dimension
+    }
+    else
+    {
+      // get v-distance of pt
+      dist= vDistance( &(acoords[0]), dim + 1 );// dim+1 == known coordinates
+
+      if( dist >= SIMPLEX_EPS )
+      {
+        mprSTICKYPROT(ST_SPARSE_MREC2);
+        runMayanPyramid( dim + 1 );       // recurse with higer dimension
+      }
+    }
+    acoords[dim]++;
+  } // while
+}
+//<-
+
+//-> resMatrixSparse::*
+bool resMatrixSparse::remapXiToPoint( const int indx, pointSet **pQ, int *set, int *pnt )
+{
+  int i,nn= (currRing->N);
+  int loffset= 0;
+  for ( i= 0; i <= nn; i++ )
+  {
+    if ( (loffset < indx) && (indx <= pQ[i]->num + loffset) )
+    {
+      *set= i;
+      *pnt= indx-loffset;
+      return true;
+    }
+    else loffset+= pQ[i]->num;
+  }
+  return false;
+}
+
+// mprSTICKYPROT
+// ST_SPARSE_RC: point added
+int resMatrixSparse::RC( pointSet **pQ, pointSet *E, int vert, mprfloat shift[] )
+{
+  int i, j, k,c ;
+  int size;
+  bool found= true;
+  mprfloat cd;
+  int onum;
+  int bucket[MAXVARS+2];
+  setID *optSum;
+
+  LP->n = 1;
+  LP->m = n + n + 1;   // number of constrains
+
+  // fill in LP matrix
+  for ( i= 0; i <= n; i++ )
+  {
+    size= pQ[i]->num;
+    for ( k= 1; k <= size; k++ )
+    {
+      LP->n++;
+
+      // objective funtion, minimize
+      LP->LiPM[1][LP->n] = - ( (mprfloat) (*pQ[i])[k]->point[pQ[i]->dim] / SCALEDOWN );
+
+      // lambdas sum up to 1
+      for ( j = 0; j <= n; j++ )
+      {
+        if ( i==j )
+          LP->LiPM[j+2][LP->n] = -1.0;
+        else
+          LP->LiPM[j+2][LP->n] = 0.0;
+      }
+
+      // the points
+      for ( j = 1; j <= n; j++ )
+      {
+        LP->LiPM[j+n+2][LP->n] =  - ( (mprfloat) (*pQ[i])[k]->point[j] );
+      }
+    }
+  }
+
+  for ( j = 0; j <= n; j++ ) LP->LiPM[j+2][1] = 1.0;
+  for ( j= 1; j <= n; j++ )
+  {
+    LP->LiPM[j+n+2][1]= (mprfloat)(*E)[vert]->point[j] - shift[j];
+  }
+  LP->n--;
+
+  LP->LiPM[1][1] = 0.0;
+
+#ifdef mprDEBUG_ALL
+  PrintLn();
+  Print(" n= %d, LP->m=M= %d, LP->n=N= %d\n",n,LP->m,LP->n);
+  print_mat(LP->LiPM, LP->m+1, LP->n+1);
+#endif
+
+  LP->m3= LP->m;
+
+  LP->compute();
+
+  if ( LP->icase < 0 )
+  {
+    // infeasibility: the point does not lie in a cell -> remove it
+    return -1;
+  }
+
+  // store result
+  (*E)[vert]->point[E->dim]= (int)(-LP->LiPM[1][1] * SCALEDOWN);
+
+#ifdef mprDEBUG_ALL
+  Print(" simplx returned %d, Objective value = %f\n", LP->icase, LP->LiPM[1][1]);
+  //print_bmat(LP->LiPM, NumCons + 1, LP->n+1-NumCons, LP->n+1, LP->iposv); // ( rows= M+1, cols= N+1-m3 )
+  //print_mat(LP->LiPM, NumCons+1, LP->n);
+#endif
+
+#if 1
+  // sort LP results
+  while (found)
+  {
+    found=false;
+    for ( i= 1; i < LP->m; i++ )
+    {
+      if ( LP->iposv[i] > LP->iposv[i+1] )
+      {
+
+        c= LP->iposv[i];
+        LP->iposv[i]=LP->iposv[i+1];
+        LP->iposv[i+1]=c;
+
+        cd=LP->LiPM[i+1][1];
+        LP->LiPM[i+1][1]=LP->LiPM[i+2][1];
+        LP->LiPM[i+2][1]=cd;
+
+        found= true;
+      }
+    }
+  }
+#endif
+
+#ifdef mprDEBUG_ALL
+  print_bmat(LP->LiPM, LP->m + 1, LP->n+1-LP->m, LP->n+1, LP->iposv);
+  PrintS(" now split into sets\n");
+#endif
+
+
+  // init bucket
+  for ( i= 0; i <= E->dim; i++ ) bucket[i]= 0;
+  // remap results of LP to sets Qi
+  c=0;
+  optSum= (setID*)omAlloc( (LP->m) * sizeof(struct setID) );
+  for ( i= 0; i < LP->m; i++ )
+  {
+    //Print("% .15f\n",LP->LiPM[i+2][1]);
+    if ( LP->LiPM[i+2][1] > 1e-12 )
+    {
+      if ( !remapXiToPoint( LP->iposv[i+1], pQ, &(optSum[c].set), &(optSum[c].pnt) ) )
+      {
+        Werror(" resMatrixSparse::RC: Found bad solution in LP: %d!",LP->iposv[i+1]);
+        WerrorS(" resMatrixSparse::RC: remapXiToPoint faild!");
+        return -1;
+      }
+      bucket[optSum[c].set]++;
+      c++;
+    }
+  }
+
+  onum= c;
+  // find last min in bucket[]: maximum i such that Fi is a point
+  c= 0;
+  for ( i= 1; i < E->dim; i++ )
+  {
+    if ( bucket[c] >= bucket[i] )
+    {
+      c= i;
+    }
+  }
+  // find matching point set
+  for ( i= onum - 1; i >= 0; i-- )
+  {
+    if ( optSum[i].set == c )
+      break;
+  }
+  // store
+  (*E)[vert]->rc.set= c;
+  (*E)[vert]->rc.pnt= optSum[i].pnt;
+  (*E)[vert]->rcPnt= (*pQ[c])[optSum[i].pnt];
+  // count
+  if ( (*E)[vert]->rc.set == linPolyS ) numSet0++;
+
+#ifdef mprDEBUG_PROT
+  Print("\n Point E[%d] was <",vert);print_exp((*E)[vert],E->dim-1);Print(">, bucket={");
+  for ( j= 0; j < E->dim; j++ )
+  {
+    Print(" %d",bucket[j]);
+  }
+  PrintS(" }\n optimal Sum: Qi ");
+  for ( j= 0; j < LP->m; j++ )
+  {
+    Print(" [ %d, %d ]",optSum[j].set,optSum[j].pnt);
+  }
+  Print(" -> i= %d, j = %d\n",(*E)[vert]->rc.set,optSum[i].pnt);
+#endif
+
+  // clean up
+  omFreeSize( (void *) optSum, (LP->m) * sizeof(struct setID) );
+
+  mprSTICKYPROT(ST_SPARSE_RC);
+
+  return (int)(-LP->LiPM[1][1] * SCALEDOWN);
+}
+
+// create coeff matrix
+int resMatrixSparse::createMatrix( pointSet *E )
+{
+  // sparse matrix
+  //    uRPos[i][1]: row of matrix
+  //    uRPos[i][idelem+1]: col of u(0)
+  //    uRPos[i][2..idelem]: col of u(1) .. u(n)
+  //    i= 1 .. numSet0
+  int i,epos;
+  int rp,cp;
+  poly rowp,epp;
+  poly iterp;
+  int *epp_mon, *eexp;
+
+  epp_mon= (int *)omAlloc( (n+2) * sizeof(int) );
+  eexp= (int *)omAlloc0(((currRing->N)+1)*sizeof(int));
+
+  totDeg= numSet0;
+
+  mprSTICKYPROT2(" size of matrix: %d\n", E->num);
+  mprSTICKYPROT2("  resultant deg: %d\n", numSet0);
+
+  uRPos= new intvec( numSet0, pLength((gls->m)[0])+1, 0 );
+
+  // sparse Matrix represented as a module where
+  // each poly is column vector ( pSetComp(p,k) gives the row )
+  rmat= idInit( E->num, E->num );    // cols, rank= number of rows
+  msize= E->num;
+
+  rp= 1;
+  rowp= NULL;
+  epp= pOne();
+  for ( i= 1; i <= E->num; i++ )
+  {       // for every row
+    E->getRowMP( i, epp_mon );           // compute (p-a[ij]), (i,j) = RC(p)
+    pSetExpV( epp, epp_mon );
+
+    //
+    rowp= ppMult_qq( epp, (gls->m)[(*E)[i]->rc.set] );  // x^(p-a[ij]) * f(i)
+
+    cp= 2;
+    // get column for every monomial in rowp and store it
+    iterp= rowp;
+    while ( iterp!=NULL )
+    {
+      epos= E->getExpPos( iterp );
+      if ( epos == 0 )
+      {
+        // this can happen, if the shift vektor or the lift funktions
+        // are not generically choosen.
+        Werror("resMatrixSparse::createMatrix: Found exponent not in E, id %d, set [%d, %d]!",
+               i,(*E)[i]->rc.set,(*E)[i]->rc.pnt);
+        return i;
+      }
+      pSetExpV(iterp,eexp);
+      pSetComp(iterp, epos );
+      pSetm(iterp);
+      if ( (*E)[i]->rc.set == linPolyS )
+      { // store coeff positions
+        IMATELEM(*uRPos,rp,cp)= epos;
+        cp++;
+      }
+      pIter( iterp );
+    } // while
+    if ( (*E)[i]->rc.set == linPolyS )
+    {   // store row
+      IMATELEM(*uRPos,rp,1)= i-1;
+      rp++;
+    }
+    (rmat->m)[i-1]= rowp;
+  } // for
+
+  pDelete( &epp );
+  omFreeSize( (void *) epp_mon, (n+2) * sizeof(int) );
+  omFreeSize( (void *) eexp, ((currRing->N)+1)*sizeof(int));
+
+#ifdef mprDEBUG_ALL
+  if ( E->num <= 40 )
+  {
+    matrix mout= idModule2Matrix( idCopy(rmat) );
+    print_matrix(mout);
+  }
+  for ( i= 1; i <= numSet0; i++ )
+  {
+    Print(" row  %d contains coeffs of f_%d\n",IMATELEM(*uRPos,i,1),linPolyS);
+  }
+  PrintS(" Sparse Matrix done\n");
+#endif
+
+  return E->num;
+}
+
+// find a sufficiently generic and small vector
+void resMatrixSparse::randomVector( const int dim, mprfloat shift[] )
+{
+  int i,j;
+  i= 1;
+
+  while ( i <= dim )
+  {
+    shift[i]= (mprfloat) (RVMULT*(siRand()%MAXRVVAL)/(mprfloat)MAXRVVAL);
+    i++;
+    for ( j= 1; j < i-1; j++ )
+    {
+      if ( (shift[j] < shift[i-1] + SIMPLEX_EPS) && (shift[j] > shift[i-1] - SIMPLEX_EPS) )
+      {
+        i--;
+        break;
+      }
+    }
+  }
+}
+
+pointSet * resMatrixSparse::minkSumTwo( pointSet *Q1, pointSet *Q2, int dim )
+{
+  pointSet *vs;
+  onePoint vert;
+  int j,k,l;
+
+  vert.point=(Coord_t*)omAlloc( ((currRing->N)+2) * sizeof(Coord_t) );
+
+  vs= new pointSet( dim );
+
+  for ( j= 1; j <= Q1->num; j++ )
+  {
+    for ( k= 1; k <= Q2->num; k++ )
+    {
+      for ( l= 1; l <= dim; l++ )
+      {
+        vert.point[l]= (*Q1)[j]->point[l] + (*Q2)[k]->point[l];
+      }
+      vs->mergeWithExp( &vert );
+      //vs->addPoint( &vert );
+    }
+  }
+
+  omFreeSize( (void *) vert.point, ((currRing->N)+2) * sizeof(Coord_t) );
+
+  return vs;
+}
+
+pointSet * resMatrixSparse::minkSumAll( pointSet **pQ, int numq, int dim )
+{
+  pointSet *vs,*vs_old;
+  int j;
+
+  vs= new pointSet( dim );
+
+  for ( j= 1; j <= pQ[0]->num; j++ ) vs->addPoint( (*pQ[0])[j] );
+
+  for ( j= 1; j < numq; j++ )
+  {
+    vs_old= vs;
+    vs= minkSumTwo( vs_old, pQ[j], dim );
+
+    delete vs_old;
+  }
+
+  return vs;
+}
+
+//----------------------------------------------------------------------------------------
+
+resMatrixSparse::resMatrixSparse( const ideal _gls, const int special )
+  : resMatrixBase(), gls( _gls )
+{
+  pointSet **Qi; // vertices sets of Conv(Supp(f_i)), i=0..idelem
+  pointSet *E;   // all integer lattice points of the minkowski sum of Q0...Qn
+  int i,k;
+  int pnt;
+  int totverts;                // total number of exponent vectors in ideal gls
+  mprfloat shift[MAXVARS+2];   // shiftvector delta, index [1..dim]
+
+  if ( (currRing->N) > MAXVARS )
+  {
+    WerrorS("resMatrixSparse::resMatrixSparse: Too many variables!");
+    return;
+  }
+
+  rmat= NULL;
+  numSet0= 0;
+
+  if ( special == SNONE ) linPolyS= 0;
+  else linPolyS= special;
+
+  istate= resMatrixBase::ready;
+
+  n= (currRing->N);
+  idelem= IDELEMS(gls);  // should be n+1
+
+  // prepare matrix LP->LiPM for Linear Programming
+  totverts = 0;
+  for( i=0; i < idelem; i++) totverts += pLength( (gls->m)[i] );
+
+  LP = new simplex( idelem+totverts*2+5, totverts+5 ); // rows, cols
+
+  // get shift vector
+#ifdef mprTEST
+  shift[0]=0.005; shift[1]=0.003; shift[2]=0.008; shift[3]=0.005; shift[4]=0.002;
+  shift[5]=0.1; shift[6]=0.3; shift[7]=0.2; shift[8]=0.4; shift[9]=0.2;
+#else
+  randomVector( idelem, shift );
+#endif
+#ifdef mprDEBUG_PROT
+  PrintS(" shift vector: ");
+  for ( i= 1; i <= idelem; i++ ) Print(" %.12f ",(double)shift[i]);
+  PrintLn();
+#endif
+
+  // evaluate convex hull for supports of gls
+  convexHull chnp( LP );
+  Qi= chnp.newtonPolytopesP( gls );
+
+#ifdef mprMINKSUM
+  E= minkSumAll( Qi, n+1, n);
+#else
+  // get inner points
+  mayanPyramidAlg mpa( LP );
+  E= mpa.getInnerPoints( Qi, shift );
+#endif
+
+#ifdef mprDEBUG_PROT
+#ifdef mprMINKSUM
+  PrintS("(MinkSum)");
+#endif
+  PrintS("\n E = (Q_0 + ... + Q_n) \\cap \\N :\n");
+  for ( pnt= 1; pnt <= E->num; pnt++ )
+  {
+    Print("%d: <",pnt);print_exp( (*E)[pnt], E->dim );PrintS(">\n");
+  }
+  PrintLn();
+#endif
+
+#ifdef mprTEST
+  int lift[5][5];
+  lift[0][1]=3; lift[0][2]=4; lift[0][3]=8;  lift[0][4]=2;
+  lift[1][1]=6; lift[1][2]=1; lift[1][3]=7;  lift[1][4]=4;
+  lift[2][1]=2; lift[2][2]=5; lift[2][3]=9;  lift[2][4]=6;
+  lift[3][1]=2; lift[3][2]=1; lift[3][3]=9;  lift[3][4]=5;
+  lift[4][1]=3; lift[4][2]=7; lift[4][3]=1;  lift[4][4]=5;
+  // now lift everything
+  for ( i= 0; i <= n; i++ ) Qi[i]->lift( lift[i] );
+#else
+  // now lift everything
+  for ( i= 0; i <= n; i++ ) Qi[i]->lift();
+#endif
+  E->dim++;
+
+  // run Row Content Function for every point in E
+  for ( pnt= 1; pnt <= E->num; pnt++ )
+  {
+    RC( Qi, E, pnt, shift );
+  }
+
+  // remove points not in cells
+  k= E->num;
+  for ( pnt= k; pnt > 0; pnt-- )
+  {
+    if ( (*E)[pnt]->rcPnt == NULL )
+    {
+      E->removePoint(pnt);
+      mprSTICKYPROT(ST_SPARSE_RCRJ);
+    }
+  }
+  mprSTICKYPROT("\n");
+
+#ifdef mprDEBUG_PROT
+  PrintS(" points which lie in a cell:\n");
+  for ( pnt= 1; pnt <= E->num; pnt++ )
+  {
+    Print("%d: <",pnt);print_exp( (*E)[pnt], E->dim );PrintS(">\n");
+  }
+  PrintLn();
+#endif
+
+  // unlift to old dimension, sort
+  for ( i= 0; i <= n; i++ ) Qi[i]->unlift();
+  E->unlift();
+  E->sort();
+
+#ifdef mprDEBUG_PROT
+  Print(" points with a[ij] (%d):\n",E->num);
+  for ( pnt= 1; pnt <= E->num; pnt++ )
+  {
+    Print("Punkt p \\in E[%d]: <",pnt);print_exp( (*E)[pnt], E->dim );
+    Print(">, RC(p) = (i:%d, j:%d), a[i,j] = <",(*E)[pnt]->rc.set,(*E)[pnt]->rc.pnt);
+    //print_exp( (Qi[(*E)[pnt]->rc.set])[(*E)[pnt]->rc.pnt], E->dim );PrintS("> = <");
+    print_exp( (*E)[pnt]->rcPnt, E->dim );PrintS(">\n");
+  }
+#endif
+
+  // now create matrix
+  if (E->num <1)
+  {
+    WerrorS("could not handle a degenerate situation: no inner points found");
+    goto theEnd;
+  }
+  if ( createMatrix( E ) != E->num )
+  {
+    // this can happen if the shiftvector shift is to large or not generic
+    istate= resMatrixBase::fatalError;
+    WerrorS("resMatrixSparse::resMatrixSparse: Error in resMatrixSparse::createMatrix!");
+    goto theEnd;
+  }
+
+ theEnd:
+  // clean up
+  for ( i= 0; i < idelem; i++ )
+  {
+    delete Qi[i];
+  }
+  omFreeSize( (void *) Qi, idelem * sizeof(pointSet*) );
+
+  delete E;
+
+  delete LP;
+}
+
+//----------------------------------------------------------------------------------------
+
+resMatrixSparse::~resMatrixSparse()
+{
+  delete uRPos;
+  idDelete( &rmat );
+}
+
+ideal resMatrixSparse::getMatrix()
+{
+  int i,/*j,*/cp;
+  poly pp,phelp,piter,pgls;
+
+  // copy original sparse res matrix
+  ideal rmat_out= idCopy(rmat);
+
+  // now fill in coeffs of f0
+  for ( i= 1; i <= numSet0; i++ )
+  {
+
+    pgls= (gls->m)[0]; // f0
+
+    // get matrix row and delete it
+    pp= (rmat_out->m)[IMATELEM(*uRPos,i,1)];
+    pDelete( &pp );
+    pp= NULL;
+    phelp= pp;
+    piter= NULL;
+
+    // u_1,..,u_k
+    cp=2;
+    while ( pNext(pgls)!=NULL )
+    {
+      phelp= pOne();
+      pSetCoeff( phelp, nCopy(pGetCoeff(pgls)) );
+      pSetComp( phelp, IMATELEM(*uRPos,i,cp) );
+      pSetmComp( phelp );
+      if ( piter!=NULL )
+      {
+        pNext(piter)= phelp;
+        piter= phelp;
+      }
+      else
+      {
+        pp= phelp;
+        piter= phelp;
+      }
+      cp++;
+      pIter( pgls );
+    }
+    // u0, now pgls points to last monom
+    phelp= pOne();
+    pSetCoeff( phelp, nCopy(pGetCoeff(pgls)) );
+    //pSetComp( phelp, IMATELEM(*uRPos,i,idelem+1) );
+    pSetComp( phelp, IMATELEM(*uRPos,i,pLength((gls->m)[0])+1) );
+    pSetmComp( phelp );
+    if (piter!=NULL) pNext(piter)= phelp;
+    else pp= phelp;
+    (rmat_out->m)[IMATELEM(*uRPos,i,1)]= pp;
+  }
+
+  return rmat_out;
+}
+
+// Fills in resMat[][] with evpoint[] and gets determinant
+//    uRPos[i][1]: row of matrix
+//    uRPos[i][idelem+1]: col of u(0)
+//    uRPos[i][2..idelem]: col of u(1) .. u(n)
+//    i= 1 .. numSet0
+number resMatrixSparse::getDetAt( const number* evpoint )
+{
+  int i,cp;
+  poly pp,phelp,piter;
+
+  mprPROTnl("smCallDet");
+
+  for ( i= 1; i <= numSet0; i++ )
+  {
+    pp= (rmat->m)[IMATELEM(*uRPos,i,1)];
+    pDelete( &pp );
+    pp= NULL;
+    phelp= pp;
+    piter= NULL;
+    // u_1,..,u_n
+    for ( cp= 2; cp <= idelem; cp++ )
+    {
+      if ( !nIsZero(evpoint[cp-1]) )
+      {
+        phelp= pOne();
+        pSetCoeff( phelp, nCopy(evpoint[cp-1]) );
+        pSetComp( phelp, IMATELEM(*uRPos,i,cp) );
+        pSetmComp( phelp );
+        if ( piter )
+        {
+          pNext(piter)= phelp;
+          piter= phelp;
+        }
+        else
+        {
+          pp= phelp;
+          piter= phelp;
+        }
+      }
+    }
+    // u0
+    phelp= pOne();
+    pSetCoeff( phelp, nCopy(evpoint[0]) );
+    pSetComp( phelp, IMATELEM(*uRPos,i,idelem+1) );
+    pSetmComp( phelp );
+    pNext(piter)= phelp;
+    (rmat->m)[IMATELEM(*uRPos,i,1)]= pp;
+  }
+
+  mprSTICKYPROT(ST__DET); // 1
+
+  poly pres= sm_CallDet( rmat, currRing );
+  number numres= nCopy( pGetCoeff( pres ) );
+  pDelete( &pres );
+
+  mprSTICKYPROT(ST__DET); // 2
+
+  return ( numres );
+}
+
+// Fills in resMat[][] with evpoint[] and gets determinant
+//    uRPos[i][1]: row of matrix
+//    uRPos[i][idelem+1]: col of u(0)
+//    uRPos[i][2..idelem]: col of u(1) .. u(n)
+//    i= 1 .. numSet0
+poly resMatrixSparse::getUDet( const number* evpoint )
+{
+  int i,cp;
+  poly pp,phelp/*,piter*/;
+
+  mprPROTnl("smCallDet");
+
+  for ( i= 1; i <= numSet0; i++ )
+  {
+    pp= (rmat->m)[IMATELEM(*uRPos,i,1)];
+    pDelete( &pp );
+    phelp= NULL;
+    // piter= NULL;
+    for ( cp= 2; cp <= idelem; cp++ )
+    { // u1 .. un
+      if ( !nIsZero(evpoint[cp-1]) )
+      {
+        phelp= pOne();
+        pSetCoeff( phelp, nCopy(evpoint[cp-1]) );
+        pSetComp( phelp, IMATELEM(*uRPos,i,cp) );
+        //pSetmComp( phelp );
+        pSetm( phelp );
+        //Print("comp %d\n",IMATELEM(*uRPos,i,cp));
+        #if 0
+        if ( piter!=NULL )
+        {
+          pNext(piter)= phelp;
+          piter= phelp;
+        }
+        else
+        {
+          pp= phelp;
+          piter= phelp;
+        }
+        #else
+        pp=pAdd(pp,phelp);
+        #endif
+      }
+    }
+    // u0
+    phelp= pOne();
+    pSetExp(phelp,1,1);
+    pSetComp( phelp, IMATELEM(*uRPos,i,idelem+1) );
+    //    Print("comp %d\n",IMATELEM(*uRPos,i,idelem+1));
+    pSetm( phelp );
+    #if 0
+    pNext(piter)= phelp;
+    #else
+    pp=pAdd(pp,phelp);
+    #endif
+    pTest(pp);
+    (rmat->m)[IMATELEM(*uRPos,i,1)]= pp;
+  }
+
+  mprSTICKYPROT(ST__DET); // 1
+
+  poly pres= sm_CallDet( rmat, currRing );
+
+  mprSTICKYPROT(ST__DET); // 2
+
+  return ( pres );
+}
+//<-
+
+//-----------------------------------------------------------------------------
+//-------------- dense resultant matrix ---------------------------------------
+//-----------------------------------------------------------------------------
+
+//-> dense resultant matrix
+//
+struct resVector;
+
+/* dense resultant matrix */
+class resMatrixDense : virtual public resMatrixBase
+{
+public:
+  /**
+   * _gls: system of multivariate polynoms
+   * special: -1 -> resMatrixDense is a symbolic matrix
+   *    0,1, ... -> resMatrixDense ist eine u-Resultante, wobei special das
+   *                        lineare u-Polynom angibt
+   */
+  resMatrixDense( const ideal _gls, const int special = SNONE );
+  ~resMatrixDense();
+
+  /** column vector of matrix, index von 0 ... numVectors-1 */
+  resVector *getMVector( const int i );
+
+  /** Returns the matrix M in an usable presentation */
+  ideal getMatrix();
+
+  /** Returns the submatrix M' of M in an usable presentation */
+  ideal getSubMatrix();
+
+  /** Evaluate the determinant of the matrix M at the point evpoint
+   * where the ui's are replaced by the components of evpoint.
+   * Uses singclap_det from factory.
+   */
+  number getDetAt( const number* evpoint );
+
+  /** Evaluates the determinant of the submatrix M'.
+   * Since the matrix is numerically, no evaluation point is needed.
+   * Uses singclap_det from factory.
+   */
+  number getSubDet();
+
+private:
+  /** deactivated copy constructor */
+  resMatrixDense( const resMatrixDense & );
+
+  /** Generate the "matrix" M. Each column is presented by a resVector
+   * holding all entries for this column.
+   */
+  void generateBaseData();
+
+  /** Generates needed set of monoms, split them into sets S0, ... Sn and
+   * check if reduced/nonreduced and calculate size of submatrix.
+   */
+  void generateMonomData( int deg, intvec* polyDegs , intvec* iVO );
+
+  /** Recursively generate all homogeneous monoms of
+   * (currRing->N) variables of degree deg.
+   */
+  void generateMonoms( poly m, int var, int deg );
+
+  /** Creates quadratic matrix M of size numVectors for later use.
+   * u0, u1, ...,un are replaced by 0.
+   * Entries equal to 0 are not initialized ( == NULL)
+   */
+  void createMatrix();
+
+private:
+  resVector *resVectorList;
+
+  int veclistmax;
+  int veclistblock;
+  int numVectors;
+  int subSize;
+
+  matrix m;
+};
+//<-
+
+//-> struct resVector
+/* Holds a row vector of the dense resultant matrix */
+struct resVector
+{
+public:
+  void init()
+  {
+    isReduced = FALSE;
+    elementOfS = SFREE;
+    mon = NULL;
+  }
+  void init( const poly m )
+  {
+    isReduced = FALSE;
+    elementOfS = SFREE;
+    mon = m;
+  }
+
+  /** index von 0 ... numVectors-1 */
+  poly getElem( const int i );
+
+  /** index von 0 ... numVectors-1 */
+  number getElemNum( const int i );
+
+  // variables
+  poly mon;
+  poly dividedBy;
+  bool isReduced;
+
+  /** number of the set S mon is element of */
+  int elementOfS;
+
+  /** holds the index of u0, u1, ..., un, if (elementOfS == linPolyS)
+   *  the size is given by (currRing->N)
+   */
+  int *numColParNr;
+
+  /** holds the column vector if (elementOfS != linPolyS) */
+  number *numColVector;
+
+  /** size of numColVector */
+  int numColVectorSize;
+
+  number *numColVecCopy;
+};
+//<-
+
+//-> resVector::*
+poly resVector::getElem( const int i ) // inline ???
+{
+  assume( 0 < i || i > numColVectorSize );
+  poly out= pOne();
+  pSetCoeff( out, numColVector[i] );
+  pTest( out );
+  return( out );
+}
+
+number resVector::getElemNum( const int i ) // inline ??
+{
+  assume( i >= 0 && i < numColVectorSize );
+  return( numColVector[i] );
+}
+//<-
+
+//-> resMatrixDense::*
+resMatrixDense::resMatrixDense( const ideal _gls, const int special )
+  : resMatrixBase()
+{
+  int i;
+
+  sourceRing=currRing;
+  gls= idCopy( _gls );
+  linPolyS= special;
+  m=NULL;
+
+  // init all
+  generateBaseData();
+
+  totDeg= 1;
+  for ( i= 0; i < IDELEMS(gls); i++ )
+  {
+    totDeg*=pTotaldegree( (gls->m)[i] );
+  }
+
+  mprSTICKYPROT2("  resultant deg: %d\n",totDeg);
+
+  istate= resMatrixBase::ready;
+}
+
+resMatrixDense::~resMatrixDense()
+{
+  int i,j;
+  for (i=0; i < numVectors; i++)
+  {
+    pDelete( &resVectorList[i].mon );
+    pDelete( &resVectorList[i].dividedBy );
+    for ( j=0; j < resVectorList[i].numColVectorSize; j++ )
+    {
+        nDelete( resVectorList[i].numColVector+j );
+    }
+    // OB: ????? (solve_s.tst)
+    if (resVectorList[i].numColVector!=NULL)
+      omfreeSize( (void *)resVectorList[i].numColVector,
+                numVectors * sizeof( number ) );
+    if (resVectorList[i].numColParNr!=NULL)
+      omfreeSize( (void *)resVectorList[i].numColParNr,
+                ((currRing->N)+1) * sizeof(int) );
+  }
+
+  omFreeSize( (void *)resVectorList, veclistmax*sizeof( resVector ) );
+
+  // free matrix m
+  if ( m != NULL )
+  {
+    idDelete((ideal *)&m);
+  }
+}
+
+// mprSTICKYPROT:
+// ST_DENSE_FR: found row S0
+// ST_DENSE_NR: normal row
+void resMatrixDense::createMatrix()
+{
+  int k,i,j;
+  resVector *vecp;
+
+  m= mpNew( numVectors, numVectors );
+
+  for ( i= 1; i <= MATROWS( m ); i++ )
+    for ( j= 1; j <= MATCOLS( m ); j++ )
+    {
+      MATELEM(m,i,j)= pInit();
+      pSetCoeff0( MATELEM(m,i,j), nInit(0) );
+    }
+
+
+  for ( k= 0; k <= numVectors - 1; k++ )
+  {
+    if ( linPolyS == getMVector(k)->elementOfS )
+    {
+      mprSTICKYPROT(ST_DENSE_FR);
+      for ( i= 0; i < (currRing->N); i++ )
+      {
+        MATELEM(m,numVectors-k,numVectors-(getMVector(k)->numColParNr)[i])= pInit();
+      }
+    }
+    else
+    {
+      mprSTICKYPROT(ST_DENSE_NR);
+      vecp= getMVector(k);
+      for ( i= 0; i < numVectors; i++)
+      {
+        if ( !nIsZero( vecp->getElemNum(i) ) )
+        {
+          MATELEM(m,numVectors - k,i + 1)= pInit();
+          pSetCoeff0( MATELEM(m,numVectors - k,i + 1), nCopy(vecp->getElemNum(i)) );
+        }
+      }
+    }
+  } // for
+  mprSTICKYPROT("\n");
+
+#ifdef mprDEBUG_ALL
+  for ( k= numVectors - 1; k >= 0; k-- )
+  {
+    if ( linPolyS == getMVector(k)->elementOfS )
+    {
+      for ( i=0; i < (currRing->N); i++ )
+      {
+        Print(" %d ",(getMVector(k)->numColParNr)[i]);
+      }
+      PrintLn();
+    }
+  }
+  for (i=1; i <= numVectors; i++)
+  {
+    for (j=1; j <= numVectors; j++ )
+    {
+      pWrite0(MATELEM(m,i,j));PrintS("  ");
+    }
+    PrintLn();
+  }
+#endif
+}
+
+// mprSTICKYPROT:
+// ST_DENSE_MEM: more mem allocated
+// ST_DENSE_NMON: new monom added
+void resMatrixDense::generateMonoms( poly mm, int var, int deg )
+{
+  if ( deg == 0 )
+  {
+    poly mon = pCopy( mm );
+
+    if ( numVectors == veclistmax )
+    {
+      resVectorList= (resVector * )omReallocSize( resVectorList,
+                                            (veclistmax) * sizeof( resVector ),
+                                            (veclistmax + veclistblock) * sizeof( resVector ) );
+      int k;
+      for ( k= veclistmax; k < (veclistmax + veclistblock); k++ )
+        resVectorList[k].init();
+      veclistmax+= veclistblock;
+      mprSTICKYPROT(ST_DENSE_MEM);
+
+    }
+    resVectorList[numVectors].init( mon );
+    numVectors++;
+    mprSTICKYPROT(ST_DENSE_NMON);
+    return;
+  }
+  else
+  {
+    if ( var == (currRing->N)+1 ) return;
+    poly newm = pCopy( mm );
+    while ( deg >= 0 )
+    {
+      generateMonoms( newm, var+1, deg );
+      pIncrExp( newm, var );
+      pSetm( newm );
+      deg--;
+    }
+    pDelete( & newm );
+  }
+
+  return;
+}
+
+void resMatrixDense::generateMonomData( int deg, intvec* polyDegs , intvec* iVO )
+{
+  int i,j,k;
+
+  // init monomData
+  veclistblock= 512;
+  veclistmax= veclistblock;
+  resVectorList= (resVector *)omAlloc( veclistmax*sizeof( resVector ) );
+
+  // Init resVector()s
+  for ( j= veclistmax - 1; j >= 0; j-- ) resVectorList[j].init();
+  numVectors= 0;
+
+  // Generate all monoms of degree deg
+  poly start= pOne();
+  generateMonoms( start, 1, deg );
+  pDelete( & start );
+
+  mprSTICKYPROT("\n");
+
+  // Check for reduced monoms
+  // First generate polyDegs.rows() monoms
+  //  x(k)^(polyDegs[k]),  0 <= k < polyDegs.rows()
+  ideal pDegDiv= idInit( polyDegs->rows(), 1 );
+  for ( k= 0; k < polyDegs->rows(); k++ )
+  {
+    poly p= pOne();
+    pSetExp( p, k + 1, (*polyDegs)[k] );
+    pSetm( p );
+    (pDegDiv->m)[k]= p;
+  }
+
+  // Now check each monom if it is reduced.
+  // A monom monom is called reduced if there exists
+  // exactly one x(k)^(polyDegs[k]) that divides the monom.
+  int divCount;
+  for ( j= numVectors - 1; j >= 0; j-- )
+  {
+    divCount= 0;
+    for ( k= 0; k < IDELEMS(pDegDiv); k++ )
+      if ( pLmDivisibleByNoComp( (pDegDiv->m)[k], resVectorList[j].mon ) )
+        divCount++;
+    resVectorList[j].isReduced= (divCount == 1);
+  }
+
+  // create the sets S(k)s
+  // a monom x(i)^deg, deg given, is element of the set S(i)
+  // if all x(0)^(polyDegs[0]) ... x(i-1)^(polyDegs[i-1]) DONT divide
+  // x(i)^deg and only x(i)^(polyDegs[i]) divides x(i)^deg
+  bool doInsert;
+  for ( k= 0; k < iVO->rows(); k++)
+  {
+    //mprPROTInl(" ------------ var:",(*iVO)[k]);
+    for ( j= numVectors - 1; j >= 0; j-- )
+    {
+      //mprPROTPnl("testing monom",resVectorList[j].mon);
+      if ( resVectorList[j].elementOfS == SFREE )
+      {
+        //mprPROTnl("\tfree");
+        if ( pLmDivisibleByNoComp( (pDegDiv->m)[ (*iVO)[k] ], resVectorList[j].mon ) )
+        {
+          //mprPROTPnl("\tdivisible by ",(pDegDiv->m)[ (*iVO)[k] ]);
+          doInsert=TRUE;
+          for ( i= 0; i < k; i++ )
+          {
+            //mprPROTPnl("\tchecking db ",(pDegDiv->m)[ (*iVO)[i] ]);
+            if ( pLmDivisibleByNoComp( (pDegDiv->m)[ (*iVO)[i] ], resVectorList[j].mon ) )
+            {
+              //mprPROTPnl("\t and divisible by",(pDegDiv->m)[ (*iVO)[i] ]);
+              doInsert=FALSE;
+              break;
+            }
+          }
+          if ( doInsert )
+          {
+            //mprPROTInl("\t------------------> S ",(*iVO)[k]);
+            resVectorList[j].elementOfS= (*iVO)[k];
+            resVectorList[j].dividedBy= pCopy( (pDegDiv->m)[ (*iVO)[i] ] );
+          }
+        }
+      }
+    }
+  }
+
+  // size of submatrix M', equal to number of nonreduced monoms
+  // (size of matrix M is equal to number of monoms=numVectors)
+  subSize= 0;
+  int sub;
+  for ( i= 0; i < polyDegs->rows(); i++ )
+  {
+    sub= 1;
+    for ( k= 0; k < polyDegs->rows(); k++ )
+      if ( i != k ) sub*= (*polyDegs)[k];
+    subSize+= sub;
+  }
+  subSize= numVectors - subSize;
+
+  // pDegDiv wieder freigeben!
+  idDelete( &pDegDiv );
+
+#ifdef mprDEBUG_ALL
+  // Print a list of monoms and their properties
+  PrintS("// \n");
+  for ( j= numVectors - 1; j >= 0; j-- )
+  {
+    Print("// %s, S(%d),  db ",
+          resVectorList[j].isReduced?"reduced":"nonreduced",
+          resVectorList[j].elementOfS);
+    pWrite0(resVectorList[j].dividedBy);
+    PrintS("  monom ");
+    pWrite(resVectorList[j].mon);
+  }
+  Print("// size: %d, subSize: %d\n",numVectors,subSize);
+#endif
+}
+
+void resMatrixDense::generateBaseData()
+{
+  int k,j,i;
+  number matEntry;
+  poly pmatchPos;
+  poly pi,factor,pmp;
+
+  // holds the degrees of F0, F1, ..., Fn
+  intvec polyDegs( IDELEMS(gls) );
+  for ( k= 0; k < IDELEMS(gls); k++ )
+    polyDegs[k]= pTotaldegree( (gls->m)[k] );
+
+  // the internal Variable Ordering
+  // make sure that the homogenization variable goes last!
+  intvec iVO( (currRing->N) );
+  if ( linPolyS != SNONE )
+  {
+    iVO[(currRing->N) - 1]= linPolyS;
+    int p=0;
+    for ( k= (currRing->N) - 1; k >= 0; k-- )
+    {
+      if ( k != linPolyS )
+      {
+        iVO[p]= k;
+        p++;
+      }
+    }
+  }
+  else
+  {
+    linPolyS= 0;
+    for ( k= 0; k < (currRing->N); k++ )
+      iVO[k]= (currRing->N) - k - 1;
+  }
+
+  // the critical degree d= sum( deg(Fi) ) - n
+  int sumDeg= 0;
+  for ( k= 0; k < polyDegs.rows(); k++ )
+    sumDeg+= polyDegs[k];
+  sumDeg-= polyDegs.rows() - 1;
+
+  // generate the base data
+  generateMonomData( sumDeg, &polyDegs, &iVO );
+
+  // generate "matrix"
+  for ( k= numVectors - 1; k >= 0; k-- )
+  {
+    if ( resVectorList[k].elementOfS != linPolyS )
+    {
+      // column k is a normal column with numerical or symbolic entries
+      // init stuff
+      resVectorList[k].numColParNr= NULL;
+      resVectorList[k].numColVectorSize= numVectors;
+      resVectorList[k].numColVector= (number *)omAlloc( numVectors*sizeof( number ) );
+      for ( i= 0; i < numVectors; i++ ) resVectorList[k].numColVector[i]= nInit(0);
+
+      // compute row poly
+      poly pi= ppMult_qq( (gls->m)[ resVectorList[k].elementOfS ] , resVectorList[k].mon );
+      pi= pDivideM( pCopy( pi ), pCopy( resVectorList[k].dividedBy ) );
+
+      // fill in "matrix"
+      while ( pi != NULL )
+      {
+        matEntry= nCopy(pGetCoeff(pi));
+        pmatchPos= pLmInit( pi );
+        pSetCoeff0( pmatchPos, nInit(1) );
+
+        for ( i= 0; i < numVectors; i++)
+          if ( pLmEqual( pmatchPos, resVectorList[i].mon ) )
+            break;
+
+        resVectorList[k].numColVector[numVectors - i - 1] = nCopy(matEntry);
+
+        pDelete( &pmatchPos );
+        nDelete( &matEntry );
+
+        pIter( pi );
+      }
+      pDelete( &pi );
+    }
+    else
+    {
+      // column is a special column, i.e. is generated by S0 and F0
+      // safe only the positions of the ui's in the column
+      //mprPROTInl(" setup of numColParNr ",k);
+      resVectorList[k].numColVectorSize= 0;
+      resVectorList[k].numColVector= NULL;
+      resVectorList[k].numColParNr= (int *)omAlloc0( ((currRing->N)+1) * sizeof(int) );
+
+      pi= (gls->m)[ resVectorList[k].elementOfS ];
+      factor= pDivideM( pCopy( resVectorList[k].mon ), pCopy( resVectorList[k].dividedBy ) );
+
+      j=0;
+      while ( pi  != NULL )
+      { // fill in "matrix"
+        pmp= pMult( pCopy( factor ), pHead( pi ) );
+        pTest( pmp );
+
+        for ( i= 0; i < numVectors; i++)
+          if ( pLmEqual( pmp, resVectorList[i].mon ) )
+            break;
+
+        resVectorList[k].numColParNr[j]= i;
+        pDelete( &pmp );
+        pIter( pi );
+        j++;
+      }
+      pDelete( &pi );
+      pDelete( &factor );
+    }
+  } // for ( k= numVectors - 1; k >= 0; k-- )
+
+  mprSTICKYPROT2(" size of matrix:    %d\n",numVectors);
+  mprSTICKYPROT2(" size of submatrix: %d\n",subSize);
+
+  // create the matrix M
+  createMatrix();
+
+}
+
+resVector *resMatrixDense::getMVector(const int i)
+{
+  assume( i >= 0 && i < numVectors );
+  return &resVectorList[i];
+}
+
+ideal resMatrixDense::getMatrix()
+{
+  int i,j;
+
+  // copy matrix
+  matrix resmat= mpNew(numVectors,numVectors);
+  poly p;
+  for (i=1; i <= numVectors; i++)
+  {
+    for (j=1; j <= numVectors; j++ )
+    {
+      p=MATELEM(m,i,j);
+      if (( p!=NULL)
+      && (!nIsZero(pGetCoeff(p)))
+      && (pGetCoeff(p)!=NULL)
+      )
+      {
+        MATELEM(resmat,i,j)= pCopy( p );
+      }
+    }
+  }
+  for (i=0; i < numVectors; i++)
+  {
+    if ( resVectorList[i].elementOfS == linPolyS )
+    {
+      for (j=1; j <= (currRing->N); j++ )
+      {
+        if ( MATELEM(resmat,numVectors-i,
+                     numVectors-resVectorList[i].numColParNr[j-1])!=NULL )
+          pDelete( &MATELEM(resmat,numVectors-i,numVectors-resVectorList[i].numColParNr[j-1]) );
+        MATELEM(resmat,numVectors-i,numVectors-resVectorList[i].numColParNr[j-1])= pOne();
+        // FIX ME
+        if ( FALSE )
+        {
+          pSetCoeff( MATELEM(resmat,numVectors-i,numVectors-resVectorList[i].numColParNr[j-1]), n_Param(j,currRing) );
+        }
+        else
+        {
+          pSetExp( MATELEM(resmat,numVectors-i,numVectors-resVectorList[i].numColParNr[j-1]), j, 1 );
+          pSetm(MATELEM(resmat,numVectors-i,numVectors-resVectorList[i].numColParNr[j-1]));
+        }
+      }
+    }
+  }
+
+  // obachman: idMatrix2Module frees resmat !!
+  ideal resmod= id_Matrix2Module(resmat,currRing);
+  return resmod;
+}
+
+ideal resMatrixDense::getSubMatrix()
+{
+  int k,i,j,l;
+  resVector *vecp;
+
+  // generate quadratic matrix resmat of size subSize
+  matrix resmat= mpNew( subSize, subSize );
+
+  j=1;
+  for ( k= numVectors - 1; k >= 0; k-- )
+  {
+    vecp= getMVector(k);
+    if ( vecp->isReduced ) continue;
+    l=1;
+    for ( i= numVectors - 1; i >= 0; i-- )
+    {
+      if ( getMVector(i)->isReduced ) continue;
+      if ( !nIsZero(vecp->getElemNum(numVectors - i - 1)) )
+      {
+        MATELEM(resmat,j,l)= pCopy( vecp->getElem(numVectors-i-1) );
+      }
+      l++;
+    }
+    j++;
+  }
+
+  // obachman: idMatrix2Module frees resmat !!
+  ideal resmod= id_Matrix2Module(resmat,currRing);
+  return resmod;
+}
+
+number resMatrixDense::getDetAt( const number* evpoint )
+{
+  int k,i;
+
+  // copy evaluation point into matrix
+  // p0, p1, ..., pn replace u0, u1, ..., un
+  for ( k= numVectors - 1; k >= 0; k-- )
+  {
+    if ( linPolyS == getMVector(k)->elementOfS )
+    {
+      for ( i= 0; i < (currRing->N); i++ )
+      {
+        pSetCoeff( MATELEM(m,numVectors-k,numVectors-(getMVector(k)->numColParNr)[i]),
+                   nCopy(evpoint[i]) );
+      }
+    }
+  }
+
+  mprSTICKYPROT(ST__DET);
+
+  // evaluate determinant of matrix m using factory singclap_det
+  poly res= singclap_det( m, currRing );
+
+  // avoid errors for det==0
+  number numres;
+  if ( (res!=NULL)  && (!nIsZero(pGetCoeff( res ))) )
+  {
+    numres= nCopy( pGetCoeff( res ) );
+  }
+  else
+  {
+    numres= nInit(0);
+    mprPROT("0");
+  }
+  pDelete( &res );
+
+  mprSTICKYPROT(ST__DET);
+
+  return( numres );
+}
+
+number resMatrixDense::getSubDet()
+{
+  int k,i,j,l;
+  resVector *vecp;
+
+  // generate quadratic matrix mat of size subSize
+  matrix mat= mpNew( subSize, subSize );
+
+  for ( i= 1; i <= MATROWS( mat ); i++ )
+  {
+    for ( j= 1; j <= MATCOLS( mat ); j++ )
+    {
+      MATELEM(mat,i,j)= pInit();
+      pSetCoeff0( MATELEM(mat,i,j), nInit(0) );
+    }
+  }
+  j=1;
+  for ( k= numVectors - 1; k >= 0; k-- )
+  {
+    vecp= getMVector(k);
+    if ( vecp->isReduced ) continue;
+    l=1;
+    for ( i= numVectors - 1; i >= 0; i-- )
+    {
+      if ( getMVector(i)->isReduced ) continue;
+      if ( vecp->getElemNum(numVectors - i - 1) && !nIsZero(vecp->getElemNum(numVectors - i - 1)) )
+      {
+        pSetCoeff(MATELEM(mat, j , l ), nCopy(vecp->getElemNum(numVectors - i - 1)));
+      }
+      /* else
+      {
+           MATELEM(mat, j , l )= pOne();
+           pSetCoeff(MATELEM(mat, j , l ), nInit(0) );
+      }
+      */
+      l++;
+    }
+    j++;
+  }
+
+  poly res= singclap_det( mat, currRing );
+
+  number numres;
+  if ((res != NULL) && (!nIsZero(pGetCoeff( res ))) )
+  {
+    numres= nCopy(pGetCoeff( res ));
+  }
+  else
+  {
+    numres= nInit(0);
+  }
+  pDelete( &res );
+  return numres;
+}
+//<--
+
+//-----------------------------------------------------------------------------
+//-------------- uResultant ---------------------------------------------------
+//-----------------------------------------------------------------------------
+
+#define MAXEVPOINT 1000000 // 0x7fffffff
+//#define MPR_MASI
+
+//-> unsigned long over(unsigned long n,unsigned long d)
+// Calculates (n+d \over d) using gmp functionality
+//
+unsigned long over( const unsigned long n , const unsigned long d )
+{ // (d+n)! / ( d! n! )
+  mpz_t res;
+  mpz_init(res);
+  mpz_t m,md,mn;
+  mpz_init(m);mpz_set_ui(m,1);
+  mpz_init(md);mpz_set_ui(md,1);
+  mpz_init(mn);mpz_set_ui(mn,1);
+
+  mpz_fac_ui(m,n+d);
+  mpz_fac_ui(md,d);
+  mpz_fac_ui(mn,n);
+
+  mpz_mul(res,md,mn);
+  mpz_tdiv_q(res,m,res);
+
+  mpz_clear(m);mpz_clear(md);mpz_clear(mn);
+
+  unsigned long result = mpz_get_ui(res);
+  mpz_clear(res);
+
+  return result;
+}
+//<-
+
+//-> uResultant::*
+uResultant::uResultant( const ideal _gls, const resMatType _rmt, BOOLEAN extIdeal )
+  : rmt( _rmt )
+{
+  if ( extIdeal )
+  {
+    // extend given ideal by linear poly F0=u0x0 + u1x1 +...+ unxn
+    gls= extendIdeal( _gls, linearPoly( rmt ), rmt );
+    n= IDELEMS( gls );
+  }
+  else
+    gls= idCopy( _gls );
+
+  switch ( rmt )
+  {
+  case sparseResMat:
+    resMat= new resMatrixSparse( gls );
+    break;
+  case denseResMat:
+    resMat= new resMatrixDense( gls );
+    break;
+  default:
+    WerrorS("uResultant::uResultant: Unknown resultant matrix type choosen!");
+  }
+}
+
+uResultant::~uResultant( )
+{
+  delete resMat;
+}
+
+ideal uResultant::extendIdeal( const ideal igls, poly linPoly, const resMatType rrmt )
+{
+  ideal newGls= idCopy( igls );
+  newGls->m= (poly *)omReallocSize( newGls->m,
+                              IDELEMS(igls) * sizeof(poly),
+                              (IDELEMS(igls) + 1) * sizeof(poly) );
+  IDELEMS(newGls)++;
+
+  switch ( rrmt )
+  {
+  case sparseResMat:
+  case denseResMat:
+    {
+      int i;
+      for ( i= IDELEMS(newGls)-1; i > 0; i-- )
+      {
+        newGls->m[i]= newGls->m[i-1];
+      }
+      newGls->m[0]= linPoly;
+    }
+    break;
+  default:
+    WerrorS("uResultant::extendIdeal: Unknown resultant matrix type choosen!");
+  }
+
+  return( newGls );
+}
+
+poly uResultant::linearPoly( const resMatType rrmt )
+{
+  int i;
+
+  poly newlp= pOne();
+  poly actlp, rootlp= newlp;
+
+  for ( i= 1; i <= (currRing->N); i++ )
+  {
+    actlp= newlp;
+    pSetExp( actlp, i, 1 );
+    pSetm( actlp );
+    newlp= pOne();
+    actlp->next= newlp;
+  }
+  actlp->next= NULL;
+  pDelete( &newlp );
+
+  if ( rrmt == sparseResMat )
+  {
+    newlp= pOne();
+    actlp->next= newlp;
+    newlp->next= NULL;
+  }
+  return ( rootlp );
+}
+
+poly uResultant::interpolateDense( const number subDetVal )
+{
+  int i,j,p;
+  long tdg;
+
+  // D is a Polynom homogeneous in the coeffs of F0 and of degree tdg = d0*d1*...*dn
+  tdg= resMat->getDetDeg();
+
+  // maximum number of terms in polynom D (homogeneous, of degree tdg)
+  // long mdg= (facul(tdg+n-1) / facul( tdg )) / facul( n - 1 );
+  long mdg= over( n-1, tdg );
+
+  // maximal number of terms in a polynom of degree tdg
+  long l=(long)pow( (double)(tdg+1), n );
+
+#ifdef mprDEBUG_PROT
+  Print("// total deg of D: tdg %ld\n",tdg);
+  Print("// maximum number of terms in D: mdg: %ld\n",mdg);
+  Print("// maximum number of terms in polynom of deg tdg: l %ld\n",l);
+#endif
+
+  // we need mdg results of D(p0,p1,...,pn)
+  number *presults;
+  presults= (number *)omAlloc( mdg * sizeof( number ) );
+  for (i=0; i < mdg; i++) presults[i]= nInit(0);
+
+  number *pevpoint= (number *)omAlloc( n * sizeof( number ) );
+  number *pev= (number *)omAlloc( n * sizeof( number ) );
+  for (i=0; i < n; i++) pev[i]= nInit(0);
+
+  mprPROTnl("// initial evaluation point: ");
+  // initial evaluatoin point
+  p=1;
+  for (i=0; i < n; i++)
+  {
+    // init pevpoint with primes 3,5,7,11, ...
+    p= nextPrime( p );
+    pevpoint[i]=nInit( p );
+    nTest(pevpoint[i]);
+    mprPROTNnl(" ",pevpoint[i]);
+  }
+
+  // evaluate the determinant in the points pev^0, pev^1, ..., pev^mdg
+  mprPROTnl("// evaluating:");
+  for ( i=0; i < mdg; i++ )
+  {
+    for (j=0; j < n; j++)
+    {
+      nDelete( &pev[j] );
+      nPower(pevpoint[j],i,&pev[j]);
+      mprPROTN(" ",pev[j]);
+    }
+    mprPROTnl("");
+
+    nDelete( &presults[i] );
+    presults[i]=resMat->getDetAt( pev );
+
+    mprSTICKYPROT(ST_BASE_EV);
+  }
+  mprSTICKYPROT("\n");
+
+  // now interpolate using vandermode interpolation
+  mprPROTnl("// interpolating:");
+  number *ncpoly;
+  {
+    vandermonde vm( mdg, n, tdg, pevpoint );
+    ncpoly= vm.interpolateDense( presults );
+  }
+
+  if ( subDetVal != NULL )
+  {   // divide by common factor
+    number detdiv;
+    for ( i= 0; i <= mdg; i++ )
+    {
+      detdiv= nDiv( ncpoly[i], subDetVal );
+      nNormalize( detdiv );
+      nDelete( &ncpoly[i] );
+      ncpoly[i]= detdiv;
+    }
+  }
+
+#ifdef mprDEBUG_ALL
+  PrintLn();
+  for ( i=0; i < mdg; i++ )
+  {
+    nPrint(ncpoly[i]); PrintS(" --- ");
+  }
+  PrintLn();
+#endif
+
+  // prepare ncpoly for later use
+  number nn=nInit(0);
+  for ( i=0; i < mdg; i++ )
+  {
+    if ( nEqual(ncpoly[i],nn) )
+    {
+      nDelete( &ncpoly[i] );
+      ncpoly[i]=NULL;
+    }
+  }
+  nDelete( &nn );
+
+  // create poly presenting the determinat of the uResultant
+  intvec exp( n );
+  for ( i= 0; i < n; i++ ) exp[i]=0;
+
+  poly result= NULL;
+
+  long sum=0;
+  long c=0;
+
+  for ( i=0; i < l; i++ )
+  {
+    if ( sum == tdg )
+    {
+      if ( !nIsZero(ncpoly[c]) )
+      {
+        poly p= pOne();
+        if ( rmt == denseResMat )
+        {
+          for ( j= 0; j < n; j++ ) pSetExp( p, j+1, exp[j] );
+        }
+        else if ( rmt == sparseResMat )
+        {
+          for ( j= 1; j < n; j++ ) pSetExp( p, j, exp[j] );
+        }
+        pSetCoeff( p, ncpoly[c] );
+        pSetm( p );
+        if (result!=NULL) result= pAdd( result, p );
+        else result=  p;
+      }
+      c++;
+    }
+    sum=0;
+    exp[0]++;
+    for ( j= 0; j < n - 1; j++ )
+    {
+      if ( exp[j] > tdg )
+      {
+        exp[j]= 0;
+        exp[j + 1]++;
+      }
+      sum+=exp[j];
+    }
+    sum+=exp[n-1];
+  }
+
+  pTest( result );
+
+  return result;
+}
+
+rootContainer ** uResultant::interpolateDenseSP( BOOLEAN matchUp, const number subDetVal )
+{
+  int i,p,uvar;
+  long tdg;
+  int loops= (matchUp?n-2:n-1);
+
+  mprPROTnl("uResultant::interpolateDenseSP");
+
+  tdg= resMat->getDetDeg();
+
+  // evaluate D in tdg+1 distinct points, so
+  // we need tdg+1 results of D(p0,1,0,...,0) =
+  //              c(0)*u0^tdg + c(1)*u0^tdg-1 + ... + c(tdg-1)*u0 + c(tdg)
+  number *presults;
+  presults= (number *)omAlloc( (tdg + 1) * sizeof( number ) );
+  for ( i=0; i <= tdg; i++ ) presults[i]= nInit(0);
+
+  rootContainer ** roots;
+  roots= (rootContainer **) omAlloc( loops * sizeof(rootContainer*) );
+  for ( i=0; i < loops; i++ ) roots[i]= new rootContainer(); // 0..n-2
+
+  number *pevpoint= (number *)omAlloc( n * sizeof( number ) );
+  for (i=0; i < n; i++) pevpoint[i]= nInit(0);
+
+  number *pev= (number *)omAlloc( n * sizeof( number ) );
+  for (i=0; i < n; i++) pev[i]= nInit(0);
+
+  // now we evaluate D(u0,-1,0,...0), D(u0,0,-1,0,...,0), ..., D(u0,0,..,0,-1)
+  // or D(u0,k1,k2,0,...,0), D(u0,k1,k2,k3,0,...,0), ..., D(u0,k1,k2,k3,...,kn)
+  // this gives us n-1 evaluations
+  p=3;
+  for ( uvar= 0; uvar < loops; uvar++ )
+  {
+    // generate initial evaluation point
+    if ( matchUp )
+    {
+      for (i=0; i < n; i++)
+      {
+        // prime(random number) between 1 and MAXEVPOINT
+        nDelete( &pevpoint[i] );
+        if ( i == 0 )
+        {
+          //p= nextPrime( p );
+          pevpoint[i]= nInit( p );
+        }
+        else if ( i <= uvar + 2 )
+        {
+          pevpoint[i]=nInit(1+siRand()%MAXEVPOINT);
+          //pevpoint[i]=nInit(383);
+        }
+        else
+          pevpoint[i]=nInit(0);
+        mprPROTNnl(" ",pevpoint[i]);
+      }
+    }
+    else
+    {
+      for (i=0; i < n; i++)
+      {
+        // init pevpoint with  prime,0,...0,1,0,...,0
+        nDelete( &pevpoint[i] );
+        if ( i == 0 )
+        {
+          //p=nextPrime( p );
+          pevpoint[i]=nInit( p );
+        }
+        else
+        {
+          if ( i == (uvar + 1) ) pevpoint[i]= nInit(-1);
+          else pevpoint[i]= nInit(0);
+        }
+        mprPROTNnl(" ",pevpoint[i]);
+      }
+    }
+
+    // prepare aktual evaluation point
+    for (i=0; i < n; i++)
+    {
+      nDelete( &pev[i] );
+      pev[i]= nCopy( pevpoint[i] );
+    }
+    // evaluate the determinant in the points pev^0, pev^1, ..., pev^tdg
+    for ( i=0; i <= tdg; i++ )
+    {
+      nDelete( &pev[0] );
+      nPower(pevpoint[0],i,&pev[0]);          // new evpoint
+
+      nDelete( &presults[i] );
+      presults[i]=resMat->getDetAt( pev );   // evaluate det at point evpoint
+
+      mprPROTNnl("",presults[i]);
+
+      mprSTICKYPROT(ST_BASE_EV);
+      mprPROTL("",tdg-i);
+    }
+    mprSTICKYPROT("\n");
+
+    // now interpolate
+    vandermonde vm( tdg + 1, 1, tdg, pevpoint, FALSE );
+    number *ncpoly= vm.interpolateDense( presults );
+
+    if ( subDetVal != NULL )
+    {  // divide by common factor
+      number detdiv;
+      for ( i= 0; i <= tdg; i++ )
+      {
+        detdiv= nDiv( ncpoly[i], subDetVal );
+        nNormalize( detdiv );
+        nDelete( &ncpoly[i] );
+        ncpoly[i]= detdiv;
+      }
+    }
+
+#ifdef mprDEBUG_ALL
+    PrintLn();
+    for ( i=0; i <= tdg; i++ )
+    {
+      nPrint(ncpoly[i]); PrintS(" --- ");
+    }
+    PrintLn();
+#endif
+
+    // save results
+    roots[uvar]->fillContainer( ncpoly, pevpoint, uvar+1, tdg,
+                                (matchUp?rootContainer::cspecialmu:rootContainer::cspecial),
+                                loops );
+  }
+
+  // free some stuff: pev, presult
+  for ( i=0; i < n; i++ ) nDelete( pev + i );
+  omFreeSize( (void *)pev, n * sizeof( number ) );
+
+  for ( i=0; i <= tdg; i++ ) nDelete( presults+i );
+  omFreeSize( (void *)presults, (tdg + 1) * sizeof( number ) );
+
+  return roots;
+}
+
+rootContainer ** uResultant::specializeInU( BOOLEAN matchUp, const number subDetVal )
+{
+  int i,/*p,*/uvar;
+  long tdg;
+  poly pures,piter;
+  int loops=(matchUp?n-2:n-1);
+  int nn=n;
+  if (loops==0) { loops=1;nn++;}
+
+  mprPROTnl("uResultant::specializeInU");
+
+  tdg= resMat->getDetDeg();
+
+  rootContainer ** roots;
+  roots= (rootContainer **) omAlloc( loops * sizeof(rootContainer*) );
+  for ( i=0; i < loops; i++ ) roots[i]= new rootContainer(); // 0..n-2
+
+  number *pevpoint= (number *)omAlloc( nn * sizeof( number ) );
+  for (i=0; i < nn; i++) pevpoint[i]= nInit(0);
+
+  // now we evaluate D(u0,-1,0,...0), D(u0,0,-1,0,...,0), ..., D(u0,0,..,0,-1)
+  // or D(u0,k1,k2,0,...,0), D(u0,k1,k2,k3,0,...,0), ..., D(u0,k1,k2,k3,...,kn)
+  // p=3;
+  for ( uvar= 0; uvar < loops; uvar++ )
+  {
+    // generate initial evaluation point
+    if ( matchUp )
+    {
+      for (i=0; i < n; i++)
+      {
+        // prime(random number) between 1 and MAXEVPOINT
+        nDelete( &pevpoint[i] );
+        if ( i <= uvar + 2 )
+        {
+          pevpoint[i]=nInit(1+siRand()%MAXEVPOINT);
+          //pevpoint[i]=nInit(383);
+        }
+        else pevpoint[i]=nInit(0);
+        mprPROTNnl(" ",pevpoint[i]);
+      }
+    }
+    else
+    {
+      for (i=0; i < n; i++)
+      {
+        // init pevpoint with  prime,0,...0,-1,0,...,0
+        nDelete( &(pevpoint[i]) );
+        if ( i == (uvar + 1) ) pevpoint[i]= nInit(-1);
+        else pevpoint[i]= nInit(0);
+        mprPROTNnl(" ",pevpoint[i]);
+      }
+    }
+
+    pures= resMat->getUDet( pevpoint );
+
+    number *ncpoly= (number *)omAlloc( (tdg+1) * sizeof(number) );
+
+#ifdef MPR_MASI
+    BOOLEAN masi=true;
+#endif
+
+    piter= pures;
+    for ( i= tdg; i >= 0; i-- )
+    {
+      //if ( piter ) Print("deg %d, pDeg(piter) %d\n",i,pTotaldegree(piter));
+      if ( piter && pTotaldegree(piter) == i )
+      {
+        ncpoly[i]= nCopy( pGetCoeff( piter ) );
+        pIter( piter );
+#ifdef MPR_MASI
+        masi=false;
+#endif
+      }
+      else
+      {
+        ncpoly[i]= nInit(0);
+      }
+      mprPROTNnl("", ncpoly[i] );
+    }
+#ifdef MPR_MASI
+    if ( masi ) mprSTICKYPROT("MASI");
+#endif
+
+    mprSTICKYPROT(ST_BASE_EV); // .
+
+    if ( subDetVal != NULL )  // divide by common factor
+    {
+      number detdiv;
+      for ( i= 0; i <= tdg; i++ )
+      {
+        detdiv= nDiv( ncpoly[i], subDetVal );
+        nNormalize( detdiv );
+        nDelete( &ncpoly[i] );
+        ncpoly[i]= detdiv;
+      }
+    }
+
+    pDelete( &pures );
+
+    // save results
+    roots[uvar]->fillContainer( ncpoly, pevpoint, uvar+1, tdg,
+                                (matchUp?rootContainer::cspecialmu:rootContainer::cspecial),
+                                loops );
+  }
+
+  mprSTICKYPROT("\n");
+
+  // free some stuff: pev, presult
+  for ( i=0; i < n; i++ ) nDelete( pevpoint + i );
+  omFreeSize( (void *)pevpoint, n * sizeof( number ) );
+
+  return roots;
+}
+
+int uResultant::nextPrime( const int i )
+{
+  int init=i;
+  int ii=i+2;
+  extern int IsPrime(int p); // from Singular/ipshell.{h,cc}
+  int j= IsPrime( ii );
+  while ( j <= init )
+  {
+    ii+=2;
+    j= IsPrime( ii );
+  }
+  return j;
+}
+//<-
+
+//-----------------------------------------------------------------------------
+
+//-> loNewtonPolytope(...)
+ideal loNewtonPolytope( const ideal id )
+{
+  simplex * LP;
+  int i;
+  int /*n,*/totverts,idelem;
+  ideal idr;
+
+  // n= (currRing->N);
+  idelem= IDELEMS(id);  // should be n+1
+
+  totverts = 0;
+  for( i=0; i < idelem; i++) totverts += pLength( (id->m)[i] );
+
+  LP = new simplex( idelem+totverts*2+5, totverts+5 ); // rows, cols
+
+  // evaluate convex hull for supports of id
+  convexHull chnp( LP );
+  idr = chnp.newtonPolytopesI( id );
+
+  delete LP;
+
+  return idr;
+}
+//<-
+
+//%e
+
+//-----------------------------------------------------------------------------
+
+// local Variables: ***
+// folded-file: t ***
+// compile-command-1: "make installg" ***
+// compile-command-2: "make install" ***
+// End: ***
+
+// in folding: C-c x
+// leave fold: C-c y
+//   foldmode: F10
diff --git a/kernel/numeric/mpr_base.h b/kernel/numeric/mpr_base.h
new file mode 100644
index 0000000..73d1365
--- /dev/null
+++ b/kernel/numeric/mpr_base.h
@@ -0,0 +1,123 @@
+#ifndef MPR_BASE_H
+#define MPR_BASE_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+
+/*
+* ABSTRACT - multipolynomial resultants - resultant matrices
+*            ( sparse, dense, u-resultant solver )
+*/
+
+#include <kernel/numeric/mpr_numeric.h>
+
+#define SNONE -1
+#define SFREE -2
+
+//%s
+//-> class resMatrixBase
+/**
+ * Base class for sparse and dense u-Resultant computation
+ */
+class resMatrixBase
+{
+public:
+  /* state of the resultant */
+  enum IStateType { none, ready, notInit, fatalError, sparseError };
+
+  resMatrixBase() : istate(notInit), totDeg(0) {}
+  virtual ~resMatrixBase() {}
+
+  virtual ideal getMatrix() { return NULL; }
+  virtual ideal getSubMatrix() { return NULL; }
+
+  virtual poly getUDet( const number* /*evpoint*/ ) { return NULL; }
+
+  virtual number getDetAt( const number* /*evpoint*/ ) { return NULL; }
+  virtual number getSubDet() { return NULL; }
+
+  virtual long getDetDeg() { return totDeg; }
+
+  virtual IStateType initState() const { return istate; }
+
+protected:
+  IStateType istate;
+
+  ideal gls;
+  int linPolyS;
+  ring sourceRing;
+
+  int totDeg;
+
+private:
+  /* disables the copy constructor */
+  resMatrixBase( const resMatrixBase & );
+};
+//<-
+
+//-> class uResultant
+/**
+ * Base class for solving 0-dim poly systems using u-resultant
+ */
+class uResultant
+{
+public:
+  enum resMatType { none, sparseResMat, denseResMat };
+
+  uResultant( const ideal _gls, const resMatType _rmt= sparseResMat, BOOLEAN extIdeal= true );
+  ~uResultant();
+
+  poly interpolateDense( const number subDetVal= NULL );
+
+  /* Interpolates n+1 determinat polys for coeff specializations. */
+  rootContainer ** interpolateDenseSP( BOOLEAN matchUp= false, const number subDetVal= NULL );
+
+  /* Uses Bareiss */
+  rootContainer ** specializeInU( BOOLEAN matchUp= false, const number subDetVal= NULL );
+
+  resMatrixBase * accessResMat() { return resMat; }
+
+private:
+  /* deactivated copy constructor */
+  uResultant( const uResultant & );
+
+  ideal extendIdeal( const ideal gls, poly linPoly, const resMatType rmt );
+  poly linearPoly( const resMatType rmt );
+  int nextPrime( const int p );
+
+  ideal gls;
+  int n;
+
+  resMatType rmt;        // sparse or dense resultant matrix ?
+  resMatrixBase *resMat; // pointer to base resultant matrix class
+};
+//<-
+uResultant::resMatType determineMType( int imtype );
+enum mprState
+{
+    mprOk,
+    mprWrongRType,
+    mprHasOne,
+    mprInfNumOfVars,
+    mprNotReduced,
+    mprNotZeroDim,
+    mprNotHomog,
+    mprUnSupField
+};
+
+mprState mprIdealCheck( const ideal theIdeal,
+                        const char * name,
+                        uResultant::resMatType mtype,
+                        BOOLEAN rmatrix= false );
+
+ideal loNewtonPolytope( const ideal id );
+
+extern size_t gmp_output_digits;
+//%e
+#endif /*MPR_BASE_H*/
+
+// local Variables: ***
+// folded-file: t ***
+// compile-command-2: "make install" ***
+// compile-command: "make installg" ***
+// End: ***
diff --git a/kernel/numeric/mpr_inout.cc b/kernel/numeric/mpr_inout.cc
new file mode 100644
index 0000000..4f7a881
--- /dev/null
+++ b/kernel/numeric/mpr_inout.cc
@@ -0,0 +1,215 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+
+
+/*
+* ABSTRACT - multipolynomial resultant
+*/
+
+
+#include <kernel/mod2.h>
+#include <misc/auxiliary.h>
+
+//#ifdef HAVE_MPR
+
+//-> includes
+#include <omalloc/omalloc.h>
+
+#include <misc/mylimits.h>
+#include <misc/options.h>
+#include <misc/intvec.h>
+
+#include <coeffs/numbers.h>
+#include <coeffs/mpr_global.h>
+
+#include <polys/matpol.h>
+
+
+#include <kernel/structs.h>
+#include <kernel/polys.h>
+#include <kernel/ideals.h>
+
+
+#include <math.h>
+
+#include "mpr_base.h"
+#include "mpr_numeric.h"
+#include "mpr_inout.h"
+
+// to get detailed timigs, define MPR_TIMING
+#ifdef MPR_TIMING
+#define TIMING
+#endif
+#include <factory/timing.h>
+TIMING_DEFINE_PRINT(mpr_overall)
+TIMING_DEFINE_PRINT(mpr_check)
+TIMING_DEFINE_PRINT(mpr_constr)
+TIMING_DEFINE_PRINT(mpr_ures)
+TIMING_DEFINE_PRINT(mpr_mures)
+TIMING_DEFINE_PRINT(mpr_arrange)
+TIMING_DEFINE_PRINT(mpr_solver)
+
+#define TIMING_EPR(t,msg) TIMING_END_AND_PRINT(t,msg);TIMING_RESET(t);
+
+//<-
+
+//------------------------------------------------------------------------------
+
+//-> void mprPrintError( mprState state )
+void mprPrintError( mprState state, const char * name )
+{
+  switch (state)
+  {
+  case mprWrongRType:
+    WerrorS("Unknown resultant matrix type choosen!");
+    break;
+  case mprHasOne:
+    Werror("One element of the ideal %s is constant!",name);
+    break;
+  case mprInfNumOfVars:
+    Werror("Wrong number of elements in given ideal %s, should be %d resp. %d!",
+           name,(currRing->N)+1,(currRing->N));
+    break;
+  case mprNotZeroDim:
+    Werror("The given ideal %s must be 0-dimensional!",name);
+    break;
+  case mprNotHomog:
+    Werror("The given ideal %s has to be homogeneous in the first ring variable!",
+           name);
+    break;
+  case mprNotReduced:
+    Werror("The given ideal %s has to reduced!",name);
+    break;
+  case mprUnSupField:
+    WerrorS("Ground field not implemented!");
+    break;
+  default:
+    break;
+  }
+}
+//<-
+
+//-> mprState mprIdealCheck()
+mprState mprIdealCheck( const ideal theIdeal,
+                        const char * /*name*/,
+                        uResultant::resMatType mtype,
+                        BOOLEAN rmatrix )
+{
+  mprState state = mprOk;
+  // int power;
+  int k;
+
+  int numOfVars= mtype == uResultant::denseResMat?(currRing->N)-1:(currRing->N);
+  if ( rmatrix ) numOfVars++;
+
+  if ( mtype == uResultant::none )
+    state= mprWrongRType;
+
+  if ( IDELEMS(theIdeal) != numOfVars )
+    state= mprInfNumOfVars;
+
+  for ( k= IDELEMS(theIdeal) - 1; (state == mprOk) && (k >= 0); k-- )
+  {
+    poly p = (theIdeal->m)[k];
+    if ( pIsConstant(p) ) state= mprHasOne;
+    else
+    if ( (mtype == uResultant::denseResMat) && !p_IsHomogeneous(p, currRing) )
+      state=mprNotHomog;
+  }
+
+  if ( !(rField_is_R(currRing)||
+         rField_is_Q(currRing)||
+         rField_is_long_R(currRing)||
+         rField_is_long_C(currRing)||
+         (rmatrix && rField_is_Q_a(currRing))) )
+    state= mprUnSupField;
+
+  if ( state != mprOk ) mprPrintError( state, "" /* name */ );
+
+  return state;
+}
+//<-
+
+//-> uResultant::resMatType determineMType( int imtype )
+uResultant::resMatType determineMType( int imtype )
+{
+  switch ( imtype )
+  {
+  case MPR_DENSE:
+    return uResultant::denseResMat;
+  case 0:
+  case MPR_SPARSE:
+    return uResultant::sparseResMat;
+  default:
+    return uResultant::none;
+  }
+}
+//<-
+
+//-> function u_resultant_det
+poly u_resultant_det( ideal gls, int imtype )
+{
+  uResultant::resMatType mtype= determineMType( imtype );
+  poly resdet;
+  poly emptypoly= pInit();
+  number smv= NULL;
+
+  TIMING_START(mpr_overall);
+
+  // check input ideal ( = polynomial system )
+  if ( mprIdealCheck( gls, "", mtype ) != mprOk )
+  {
+    return emptypoly;
+  }
+
+  uResultant *ures;
+
+  // main task 1: setup of resultant matrix
+  TIMING_START(mpr_constr);
+  ures= new uResultant( gls, mtype );
+  TIMING_EPR(mpr_constr,"construction");
+
+  // if dense resultant, check if minor nonsingular
+  if ( mtype == uResultant::denseResMat )
+  {
+    smv= ures->accessResMat()->getSubDet();
+#ifdef mprDEBUG_PROT
+    PrintS("// Determinant of submatrix: ");nPrint(smv); PrintLn();
+#endif
+    if ( nIsZero(smv) )
+    {
+      WerrorS("Unsuitable input ideal: Minor of resultant matrix is singular!");
+      return emptypoly;
+    }
+  }
+
+  // main task 2: Interpolate resultant polynomial
+  TIMING_START(mpr_ures);
+  resdet= ures->interpolateDense( smv );
+  TIMING_EPR(mpr_ures,"ures");
+
+  // free mem
+  delete ures;
+  nDelete( &smv );
+  pDelete( &emptypoly );
+
+  TIMING_EPR(mpr_overall,"overall");
+
+  return ( resdet );
+}
+//<-
+
+//-----------------------------------------------------------------------------
+
+//#endif // HAVE_MPR
+
+// local Variables: ***
+// folded-file: t ***
+// compile-command-1: "make installg" ***
+// compile-command-2: "make install" ***
+// End: ***
+
+// in folding: C-c x
+// leave fold: C-c y
+//   foldmode: F10
diff --git a/kernel/numeric/mpr_inout.h b/kernel/numeric/mpr_inout.h
new file mode 100644
index 0000000..2035b0e
--- /dev/null
+++ b/kernel/numeric/mpr_inout.h
@@ -0,0 +1,74 @@
+#ifndef MPR_H
+#define MPR_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+
+
+/*
+* ABSTRACT - multipolynomial resultants - interface to Singular
+*
+*/
+
+#define DEFAULT_DIGITS 30
+
+#define MPR_DENSE  1
+#define MPR_SPARSE 2
+
+/** solve a multipolynomial system using the u-resultant
+ * Input ideal must be 0-dimensional and (currRing->N) == IDELEMS(ideal).
+ * Resultant method can be MPR_DENSE, which uses Macaulay Resultant (good for
+ * dense homogeneous polynoms) or MPR_SPARSE, which uses Sparse Resultant
+ * (Gelfand, Kapranov, Zelevinsky).
+ * Arguments 4: ideal i, int k, int l, int m
+ *   k=0: use sparse resultant matrix of Gelfand, Kapranov and Zelevinsky
+ *   k=1: use resultant matrix of Macaulay (k=0 is default)
+ *   l>0: defines precision of fractional part if ground field is Q
+ *   m=0,1,2: number of iterations for approximation of roots (default=2)
+ * Returns a list containing the roots of the system.
+ */
+BOOLEAN nuUResSolve( leftv res, leftv args );
+
+/** returns module representing the multipolynomial resultant matrix
+ * Arguments 2: ideal i, int k
+ *   k=0: use sparse resultant matrix of Gelfand, Kapranov and Zelevinsky
+ *   k=1: use resultant matrix of Macaulay (k=0 is default)
+ */
+BOOLEAN nuMPResMat( leftv res, leftv arg1, leftv arg2 );
+
+/** find the (complex) roots an univariate polynomial
+ * Determines the roots of an univariate polynomial using Laguerres'
+ * root-solver. Good for polynomials with low and middle degree (<40).
+ * Arguments 3: poly arg1 , int arg2 , int arg3
+ *  arg2>0: defines precision of fractional part if ground field is Q
+ *  arg3: number of iterations for approximation of roots (default=2)
+ * Returns a list of all (complex) roots of the polynomial arg1
+ */
+BOOLEAN nuLagSolve( leftv res, leftv arg1, leftv arg2, leftv arg3 );
+
+/**
+ * COMPUTE: polynomial p with values given by v at points p1,..,pN derived
+ * from p; more precisely: consider p as point in K^n and v as N elements in K,
+ * let p1,..,pN be the points in K^n obtained by evaluating all monomials
+ * of degree 0,1,...,N at p in lexicographical order, then the procedure
+ * computes the polynomial f satisfying f(pi) = v[i]
+ * RETURN:  polynomial f of degree d
+ */
+BOOLEAN nuVanderSys( leftv res, leftv arg1, leftv arg2, leftv arg3 );
+
+/** compute Newton Polytopes of input polynomials
+ */
+BOOLEAN loNewtonP( leftv res, leftv arg1 );
+
+/** Implementation of the Simplex Algorithm.
+ * For args, see class simplex.
+ */
+BOOLEAN loSimplex( leftv res, leftv args );
+
+#endif
+
+// local Variables: ***
+// folded-file: t ***
+// compile-command-1: "make installg" ***
+// compile-command-2: "make install" ***
+// End: ***
diff --git a/kernel/numeric/mpr_numeric.cc b/kernel/numeric/mpr_numeric.cc
new file mode 100644
index 0000000..cc05831
--- /dev/null
+++ b/kernel/numeric/mpr_numeric.cc
@@ -0,0 +1,1381 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+
+
+/*
+* ABSTRACT - multipolynomial resultants - numeric stuff
+*            ( root finder, vandermonde system solver, simplex )
+*/
+
+#include <kernel/mod2.h>
+
+#include <misc/auxiliary.h>
+#include <omalloc/omalloc.h>
+
+//#ifdef HAVE_MPR
+
+//#define mprDEBUG_ALL
+
+//-> includes
+#include <misc/mylimits.h>
+#include <misc/options.h>
+#include <misc/intvec.h>
+
+#include <coeffs/numbers.h>
+#include <coeffs/mpr_global.h>
+
+#include <polys/matpol.h>
+
+#include <kernel/polys.h>
+#include <kernel/ideals.h>
+
+#include <kernel/polys.h>
+#include <kernel/ideals.h>
+
+//#include "longrat.h"
+
+#include "mpr_base.h"
+#include "mpr_numeric.h"
+
+#include <math.h>
+//<-
+
+//-----------------------------------------------------------------------------
+//-------------- vandermonde system solver ------------------------------------
+//-----------------------------------------------------------------------------
+
+//-> vandermonde::*
+vandermonde::vandermonde( const long _cn, const long _n, const long _maxdeg,
+                          number *_p, const bool _homog )
+  : n(_n), cn(_cn), maxdeg(_maxdeg), p(_p), homog(_homog)
+{
+  long j;
+  l= (long)pow((double)maxdeg+1,(int)n);
+  x= (number *)omAlloc( cn * sizeof(number) );
+  for ( j= 0; j < cn; j++ ) x[j]= nInit(1);
+  init();
+}
+
+vandermonde::~vandermonde()
+{
+  int j;
+  for ( j= 0; j < cn; j++ ) nDelete( x+j );
+  omFreeSize( (void *)x, cn * sizeof( number ) );
+}
+
+void vandermonde::init()
+{
+  int j;
+  long i,c,sum;
+  number tmp,tmp1;
+
+  c=0;
+  sum=0;
+
+  intvec exp( n );
+  for ( j= 0; j < n; j++ ) exp[j]=0;
+
+  for ( i= 0; i < l; i++ )
+  {
+    if ( !homog || (sum == maxdeg) )
+    {
+      for ( j= 0; j < n; j++ )
+      {
+        nPower( p[j], exp[j], &tmp );
+        tmp1 = nMult( tmp, x[c] );
+        x[c]= tmp1;
+        nDelete( &tmp );
+      }
+      c++;
+    }
+    exp[0]++;
+    sum=0;
+    for ( j= 0; j < n - 1; j++ )
+    {
+      if ( exp[j] > maxdeg )
+      {
+        exp[j]= 0;
+        exp[j + 1]++;
+        }
+      sum+= exp[j];
+    }
+    sum+= exp[n - 1];
+  }
+}
+
+poly vandermonde::numvec2poly( const number * q )
+{
+  int j;
+  long i,/*c,*/sum;
+
+  poly pnew,pit=NULL;
+
+  // c=0;
+  sum=0;
+
+  int *exp= (int *) omAlloc( (n+1) * sizeof(int) );
+
+  for ( j= 0; j < n+1; j++ ) exp[j]=0;
+
+  for ( i= 0; i < l; i++ )
+  {
+    if ( (!homog || (sum == maxdeg)) && q[i] && !nIsZero(q[i]) )
+    {
+      pnew= pOne();
+      pSetCoeff(pnew,q[i]);
+      pSetExpV(pnew,exp);
+      if ( pit )
+      {
+        pNext(pnew)= pit;
+        pit= pnew;
+      }
+      else
+      {
+        pit= pnew;
+        pNext(pnew)= NULL;
+      }
+      pSetm(pit);
+    }
+    exp[1]++;
+    sum=0;
+    for ( j= 1; j < n; j++ )
+    {
+      if ( exp[j] > maxdeg )
+      {
+        exp[j]= 0;
+        exp[j + 1]++;
+        }
+      sum+= exp[j];
+    }
+    sum+= exp[n];
+  }
+
+  omFreeSize( (void *) exp, (n+1) * sizeof(int) );
+
+  pSortAdd(pit);
+  return pit;
+}
+
+number * vandermonde::interpolateDense( const number * q )
+{
+  int i,j,k;
+  number newnum,tmp1;
+  number b,t,xx,s;
+  number *c;
+  number *w;
+
+  b=t=xx=s=tmp1=NULL;
+
+  w= (number *)omAlloc( cn * sizeof(number) );
+  c= (number *)omAlloc( cn * sizeof(number) );
+  for ( j= 0; j < cn; j++ )
+  {
+    w[j]= nInit(0);
+    c[j]= nInit(0);
+  }
+
+  if ( cn == 1 )
+  {
+    nDelete( &w[0] );
+    w[0]= nCopy(q[0]);
+  }
+  else
+  {
+    nDelete( &c[cn-1] );
+    c[cn-1]= nCopy(x[0]);
+    c[cn-1]= nInpNeg(c[cn-1]);              // c[cn]= -x[1]
+
+    for ( i= 1; i < cn; i++ ) {              // i=2; i <= cn
+      nDelete( &xx );
+      xx= nCopy(x[i]);
+      xx= nInpNeg(xx);               // xx= -x[i]
+
+      for ( j= (cn-i-1); j <= (cn-2); j++) { // j=(cn+1-i); j <= (cn-1)
+        nDelete( &tmp1 );
+        tmp1= nMult( xx, c[j+1] );           // c[j]= c[j] + (xx * c[j+1])
+        newnum= nAdd( c[j], tmp1 );
+        nDelete( &c[j] );
+        c[j]= newnum;
+      }
+
+      newnum= nAdd( xx, c[cn-1] );           // c[cn-1]= c[cn-1] + xx
+      nDelete( &c[cn-1] );
+      c[cn-1]= newnum;
+    }
+
+    for ( i= 0; i < cn; i++ ) {              // i=1; i <= cn
+      nDelete( &xx );
+      xx= nCopy(x[i]);                     // xx= x[i]
+
+      nDelete( &t );
+      t= nInit( 1 );                         // t= b= 1
+      nDelete( &b );
+      b= nInit( 1 );
+      nDelete( &s );                         // s= q[cn-1]
+      s= nCopy( q[cn-1] );
+
+      for ( k= cn-1; k >= 1; k-- ) {         // k=cn; k >= 2
+        nDelete( &tmp1 );
+        tmp1= nMult( xx, b );                // b= c[k] + (xx * b)
+        nDelete( &b );
+        b= nAdd( c[k], tmp1 );
+
+        nDelete( &tmp1 );
+        tmp1= nMult( q[k-1], b );            // s= s + (q[k-1] * b)
+        newnum= nAdd( s, tmp1 );
+        nDelete( &s );
+        s= newnum;
+
+        nDelete( &tmp1 );
+        tmp1= nMult( xx, t );                // t= (t * xx) + b
+        newnum= nAdd( tmp1, b );
+        nDelete( &t );
+        t= newnum;
+      }
+
+      if (!nIsZero(t))
+      {
+        nDelete( &w[i] );                      // w[i]= s/t
+        w[i]= nDiv( s, t );
+        nNormalize( w[i] );
+      }
+
+      mprSTICKYPROT(ST_VANDER_STEP);
+    }
+  }
+  mprSTICKYPROT("\n");
+
+  // free mem
+  for ( j= 0; j < cn; j++ ) nDelete( c+j );
+  omFreeSize( (void *)c, cn * sizeof( number ) );
+
+  nDelete( &tmp1 );
+  nDelete( &s );
+  nDelete( &t );
+  nDelete( &b );
+  nDelete( &xx );
+
+  // makes quotiens smaller
+  for ( j= 0; j < cn; j++ ) nNormalize( w[j] );
+
+  return w;
+}
+//<-
+
+//-----------------------------------------------------------------------------
+//-------------- rootContainer ------------------------------------------------
+//-----------------------------------------------------------------------------
+
+//-> definitions
+#define MR       8        // never change this value
+#define MT      5
+#define MMOD    (MT*MR)
+#define MAXIT   (5*MMOD)   // max number of iterations in laguer root finder
+
+
+//-> rootContainer::rootContainer()
+rootContainer::rootContainer()
+{
+  rt=none;
+
+  coeffs= NULL;
+  ievpoint= NULL;
+  theroots= NULL;
+
+  found_roots= false;
+}
+//<-
+
+//-> rootContainer::~rootContainer()
+rootContainer::~rootContainer()
+{
+  int i;
+  // free coeffs, ievpoint
+  if ( ievpoint != NULL )
+  {
+    for ( i=0; i < anz+2; i++ ) nDelete( ievpoint + i );
+    omFreeSize( (void *)ievpoint, (anz+2) * sizeof( number ) );
+  }
+
+  for ( i=0; i <= tdg; i++ ) nDelete( coeffs + i );
+  omFreeSize( (void *)coeffs, (tdg+1) * sizeof( number ) );
+
+  // theroots l�schen
+  for ( i=0; i < tdg; i++ ) delete theroots[i];
+  omFreeSize( (void *) theroots, (tdg)*sizeof(gmp_complex*) );
+
+  //mprPROTnl("~rootContainer()");
+}
+//<-
+
+//-> void rootContainer::fillContainer( ... )
+void rootContainer::fillContainer( number *_coeffs, number *_ievpoint,
+                                   const int _var, const int _tdg,
+                                   const rootType  _rt, const int _anz )
+{
+  int i;
+  number nn= nInit(0);
+  var=_var;
+  tdg=_tdg;
+  coeffs=_coeffs;
+  rt=_rt;
+  anz=_anz;
+
+  for ( i=0; i <= tdg; i++ )
+  {
+    if ( nEqual(coeffs[i],nn) )
+    {
+      nDelete( &coeffs[i] );
+      coeffs[i]=NULL;
+    }
+  }
+  nDelete( &nn );
+
+  if ( rt == cspecialmu && _ievpoint )  // copy ievpoint
+  {
+    ievpoint= (number *)omAlloc( (anz+2) * sizeof( number ) );
+    for (i=0; i < anz+2; i++) ievpoint[i]= nCopy( _ievpoint[i] );
+  }
+
+  theroots= NULL;
+  found_roots= false;
+}
+//<-
+
+//-> poly rootContainer::getPoly()
+poly rootContainer::getPoly()
+{
+  int i;
+
+  poly result= NULL;
+  poly ppos;
+
+  if ( (rt == cspecial) || ( rt == cspecialmu ) )
+  {
+    for ( i= tdg; i >= 0; i-- )
+    {
+      if ( coeffs[i] )
+      {
+        poly p= pOne();
+        //pSetExp( p, var+1, i);
+        pSetExp( p, 1, i);
+        pSetCoeff( p, nCopy( coeffs[i] ) );
+        pSetm( p );
+        if (result)
+        {
+          ppos->next=p;
+          ppos=ppos->next;
+        }
+        else
+        {
+          result=p;
+          ppos=p;
+        }
+
+      }
+    }
+    if (result!=NULL) pSetm( result );
+  }
+
+  return result;
+}
+//<-
+
+//-> const gmp_complex & rootContainer::opterator[] ( const int i )
+// this is now inline!
+//  gmp_complex & rootContainer::operator[] ( const int i )
+//  {
+//    if ( found_roots && ( i >= 0) && ( i < tdg ) )
+//    {
+//      return *theroots[i];
+//    }
+//    // warning
+//    Warn("rootContainer::getRoot: Wrong index %d, found_roots %s",i,found_roots?"true":"false");
+//    gmp_complex *tmp= new gmp_complex();
+//    return *tmp;
+//  }
+//<-
+
+//-> gmp_complex & rootContainer::evPointCoord( int i )
+gmp_complex & rootContainer::evPointCoord( const int i )
+{
+  if (! ((i >= 0) && (i < anz+2) ) )
+    WarnS("rootContainer::evPointCoord: index out of range");
+  if (ievpoint == NULL)
+    WarnS("rootContainer::evPointCoord: ievpoint == NULL");
+
+  if ( (rt == cspecialmu) && found_roots ) // FIX ME
+  {
+    if ( ievpoint[i] != NULL )
+    {
+      gmp_complex *tmp= new gmp_complex();
+      *tmp= numberToComplex(ievpoint[i], currRing->cf);
+      return *tmp;
+    }
+    else
+    {
+      Warn("rootContainer::evPointCoord: NULL index %d",i);
+    }
+  }
+
+  // warning
+  Warn("rootContainer::evPointCoord: Wrong index %d, found_roots %s",i,found_roots?"true":"false");
+  gmp_complex *tmp= new gmp_complex();
+  return *tmp;
+}
+//<-
+
+//-> bool rootContainer::changeRoots( int from, int to )
+bool rootContainer::swapRoots( const int from, const int to )
+{
+  if ( found_roots && ( from >= 0) && ( from < tdg ) && ( to >= 0) && ( to < tdg ) )
+  {
+    if ( to != from )
+    {
+      gmp_complex tmp( *theroots[from] );
+      *theroots[from]= *theroots[to];
+      *theroots[to]= tmp;
+    }
+    return true;
+  }
+
+  // warning
+  Warn(" rootContainer::changeRoots: Wrong index %d, %d",from,to);
+  return false;
+}
+//<-
+
+//-> void rootContainer::solver()
+bool rootContainer::solver( const int polishmode )
+{
+  int i;
+
+  // there are maximal tdg roots, so *roots ranges form 0 to tdg-1.
+  theroots= (gmp_complex**)omAlloc( tdg*sizeof(gmp_complex*) );
+  for ( i=0; i < tdg; i++ ) theroots[i]= new gmp_complex();
+
+  // copy the coefficients of type number to type gmp_complex
+  gmp_complex **ad= (gmp_complex**)omAlloc( (tdg+1)*sizeof(gmp_complex*) );
+  for ( i=0; i <= tdg; i++ )
+  {
+    ad[i]= new gmp_complex();
+    if ( coeffs[i] ) *ad[i] = numberToComplex( coeffs[i], currRing->cf );
+  }
+
+  // now solve
+  found_roots= laguer_driver( ad, theroots, polishmode != 0 );
+  if (!found_roots)
+    WarnS("rootContainer::solver: No roots found!");
+
+  // free memory
+  for ( i=0; i <= tdg; i++ ) delete ad[i];
+  omFreeSize( (void *) ad, (tdg+1)*sizeof(gmp_complex*) );
+
+  return found_roots;
+}
+//<-
+
+//-> gmp_complex* rootContainer::laguer_driver( bool polish )
+bool rootContainer::laguer_driver(gmp_complex ** a, gmp_complex ** roots, bool polish )
+{
+  int i,j,k,its;
+  gmp_float zero(0.0);
+  gmp_complex x(0.0),o(1.0);
+  bool ret= true, isf=isfloat(a), type=true;
+
+  gmp_complex ** ad= (gmp_complex**)omAlloc( (tdg+1)*sizeof(gmp_complex*) );
+  for ( i=0; i <= tdg; i++ ) ad[i]= new gmp_complex( *a[i] );
+
+  k = 0;
+  i = tdg;
+  j = i-1;
+  while (i>2)
+  {
+    // run laguer alg
+    x = zero;
+    laguer(ad, i, &x, &its, type);
+    if ( its > MAXIT )
+    {
+      type = !type;
+      x = zero;
+      laguer(ad, i, &x, &its, type);
+    }
+
+    mprSTICKYPROT(ST_ROOTS_LGSTEP);
+    if ( its > MAXIT )
+    {  // error
+      WarnS("Laguerre solver: Too many iterations!");
+      ret= false;
+      goto theend;
+    }
+    if ( polish )
+    {
+      laguer( a, tdg, &x, &its , type);
+      if ( its > MAXIT )
+      {  // error
+        WarnS("Laguerre solver: Too many iterations in polish!");
+        ret= false;
+        goto theend;
+      }
+    }
+    if ((!type)&&(!((x.real()==zero)&&(x.imag()==zero)))) x = o/x;
+    if (x.imag() == zero)
+    {
+      *roots[k] = x;
+      k++;
+      divlin(ad,x,i);
+      i--;
+    }
+    else
+    {
+      if(isf)
+      {
+        *roots[j] = x;
+        *roots[j-1]= gmp_complex(x.real(),-x.imag());
+        j -= 2;
+        divquad(ad,x,i);
+        i -= 2;
+      }
+      else
+      {
+        *roots[j] = x;
+        j--;
+        divlin(ad,x,i);
+        i--;
+      }
+    }
+    type = !type;
+  }
+  solvequad(ad,roots,k,j);
+  sortroots(roots,k,j,isf);
+
+theend:
+  mprSTICKYPROT("\n");
+  for ( i=0; i <= tdg; i++ ) delete ad[i];
+  omFreeSize( (void *) ad, (tdg+1)*sizeof( gmp_complex* ));
+
+  return ret;
+}
+//<-
+
+//-> void rootContainer::laguer(...)
+void rootContainer::laguer(gmp_complex ** a, int m, gmp_complex *x, int *its, bool type)
+{
+  int iter,j;
+  gmp_float zero(0.0),one(1.0),deg(m);
+  gmp_float abx_g, err_g, fabs;
+  gmp_complex dx, x1, b, d, f, g, h, sq, gp, gm, g2;
+  gmp_float frac_g[MR+1] = { 0.0, 0.5, 0.25, 0.75, 0.125, 0.375, 0.625, 0.875, 1.0 };
+
+  gmp_float epss(0.1);
+  mpf_pow_ui(*epss._mpfp(),*epss.mpfp(),gmp_output_digits);
+
+  for ( iter= 1; iter <= MAXIT; iter++ )
+  {
+    mprSTICKYPROT(ST_ROOTS_LG);
+    *its=iter;
+    if (type)
+      computefx(a,*x,m,b,d,f,abx_g,err_g);
+    else
+      computegx(a,*x,m,b,d,f,abx_g,err_g);
+    err_g *= epss; // EPSS;
+
+    fabs = abs(b);
+    if (fabs <= err_g)
+    {
+      if ((fabs==zero) || (abs(d)==zero)) return;
+      *x -= (b/d); // a last newton-step
+      goto ende;
+    }
+
+    g= d / b;
+    g2 = g * g;
+    h= g2 - (((f+f) / b ));
+    sq= sqrt(( ( h * deg ) - g2 ) * (deg - one));
+    gp= g + sq;
+    gm= g - sq;
+    if (abs(gp)<abs(gm))
+    {
+      dx = deg/gm;
+    }
+    else
+    {
+      if((gp.real()==zero)&&(gp.imag()==zero))
+      {
+        dx.real(cos((mprfloat)iter));
+        dx.imag(sin((mprfloat)iter));
+        dx = dx*(one+abx_g);
+      }
+      else
+      {
+        dx = deg/gp;
+      }
+    }
+    x1= *x - dx;
+
+    if (*x == x1) goto ende;
+
+    j = iter%MMOD;
+    if (j==0) j=MT;
+    if ( j % MT ) *x= x1;
+    else *x -= ( dx * frac_g[ j / MT ] );
+  }
+
+  *its= MAXIT+1;
+ende:
+  checkimag(x,epss);
+}
+
+void rootContainer::checkimag(gmp_complex *x, gmp_float &e)
+{
+  if(abs(x->imag())<abs(x->real())*e)
+  {
+    x->imag(0.0);
+  }
+}
+
+bool rootContainer::isfloat(gmp_complex **a)
+{
+  gmp_float z(0.0);
+  gmp_complex *b;
+  for (int i=tdg; i >= 0; i-- )
+  {
+    b = &(*a[i]);
+    if (!(b->imag()==z))
+      return false;
+  }
+  return true;
+}
+
+void rootContainer::divlin(gmp_complex **a, gmp_complex x, int j)
+{
+  int i;
+  gmp_float o(1.0);
+
+  if (abs(x)<o)
+  {
+    for (i= j-1; i > 0; i-- )
+      *a[i] += (*a[i+1]*x);
+    for (i= 0; i < j; i++ )
+      *a[i] = *a[i+1];
+  }
+  else
+  {
+    gmp_complex y(o/x);
+    for (i= 1; i < j; i++)
+      *a[i] += (*a[i-1]*y);
+  }
+}
+
+void rootContainer::divquad(gmp_complex **a, gmp_complex x, int j)
+{
+  int i;
+  gmp_float o(1.0),p(x.real()+x.real()),
+            q((x.real()*x.real())+(x.imag()*x.imag()));
+
+  if (abs(x)<o)
+  {
+    *a[j-1] += (*a[j]*p);
+    for (i= j-2; i > 1; i-- )
+      *a[i] += ((*a[i+1]*p)-(*a[i+2]*q));
+    for (i= 0; i < j-1; i++ )
+      *a[i] = *a[i+2];
+  }
+  else
+  {
+    p = p/q;
+    q = o/q;
+    *a[1] += (*a[0]*p);
+    for (i= 2; i < j-1; i++)
+      *a[i] += ((*a[i-1]*p)-(*a[i-2]*q));
+  }
+}
+
+void rootContainer::solvequad(gmp_complex **a, gmp_complex **r, int &k, int &j)
+{
+  gmp_float zero(0.0);
+
+  if ((j>k)
+  &&((!(*a[2]).real().isZero())||(!(*a[2]).imag().isZero())))
+  {
+    gmp_complex sq(zero);
+    gmp_complex h1(*a[1]/(*a[2] + *a[2])), h2(*a[0] / *a[2]);
+    gmp_complex disk((h1 * h1) - h2);
+    if (disk.imag().isZero())
+    {
+      if (disk.real()<zero)
+      {
+        sq.real(zero);
+        sq.imag(sqrt(-disk.real()));
+      }
+      else
+        sq = (gmp_complex)sqrt(disk.real());
+    }
+    else
+      sq = sqrt(disk);
+    *r[k+1] = sq - h1;
+    sq += h1;
+    *r[k] = (gmp_complex)0.0-sq;
+    if(sq.imag().isZero())
+    {
+      k = j;
+      j++;
+    }
+    else
+    {
+      j = k;
+      k--;
+    }
+  }
+  else
+  {
+    if (((*a[1]).real().isZero()) && ((*a[1]).imag().isZero()))
+    {
+      WerrorS("precision lost, try again with higher precision");
+    }
+    else
+    {
+      *r[k]= (gmp_complex)0.0-(*a[0] / *a[1]);
+      if(r[k]->imag().isZero())
+        j++;
+      else
+        k--;
+    }
+  }
+}
+
+void rootContainer::sortroots(gmp_complex **ro, int r, int c, bool isf)
+{
+  int j;
+
+  for (j=0; j<r; j++) // the real roots
+    sortre(ro, j, r, 1);
+  if (c>=tdg) return;
+  if (isf)
+  {
+    for (j=c; j+2<tdg; j+=2) // the complex roots for a real poly
+      sortre(ro, j, tdg-1, 2);
+  }
+  else
+  {
+    for (j=c; j+1<tdg; j++) // the complex roots for a general poly
+      sortre(ro, j, tdg-1, 1);
+  }
+}
+
+void rootContainer::sortre(gmp_complex **r, int l, int u, int inc)
+{
+  int pos,i;
+  gmp_complex *x,*y;
+
+  pos = l;
+  x = r[pos];
+  for (i=l+inc; i<=u; i+=inc)
+  {
+    if (r[i]->real()<x->real())
+    {
+      pos = i;
+      x = r[pos];
+    }
+  }
+  if (pos>l)
+  {
+    if (inc==1)
+    {
+      for (i=pos; i>l; i--)
+        r[i] = r[i-1];
+      r[l] = x;
+    }
+    else
+    {
+      y = r[pos+1];
+      for (i=pos+1; i+1>l; i--)
+        r[i] = r[i-2];
+      if (x->imag()>y->imag())
+      {
+        r[l] = x;
+        r[l+1] = y;
+      }
+      else
+      {
+        r[l] = y;
+        r[l+1] = x;
+      }
+    }
+  }
+  else if ((inc==2)&&(x->imag()<r[l+1]->imag()))
+  {
+    r[l] = r[l+1];
+    r[l+1] = x;
+  }
+}
+
+void rootContainer::computefx(gmp_complex **a, gmp_complex x, int m,
+                  gmp_complex &f0, gmp_complex &f1, gmp_complex &f2,
+                  gmp_float &ex, gmp_float &ef)
+{
+  int k;
+
+  f0= *a[m];
+  ef= abs(f0);
+  f1= gmp_complex(0.0);
+  f2= f1;
+  ex= abs(x);
+
+  for ( k= m-1; k >= 0; k-- )
+  {
+    f2 = ( x * f2 ) + f1;
+    f1 = ( x * f1 ) + f0;
+    f0 = ( x * f0 ) + *a[k];
+    ef = abs( f0 ) + ( ex * ef );
+  }
+}
+
+void rootContainer::computegx(gmp_complex **a, gmp_complex x, int m,
+                  gmp_complex &f0, gmp_complex &f1, gmp_complex &f2,
+                  gmp_float &ex, gmp_float &ef)
+{
+  int k;
+
+  f0= *a[0];
+  ef= abs(f0);
+  f1= gmp_complex(0.0);
+  f2= f1;
+  ex= abs(x);
+
+  for ( k= 1; k <= m; k++ )
+  {
+    f2 = ( x * f2 ) + f1;
+    f1 = ( x * f1 ) + f0;
+    f0 = ( x * f0 ) + *a[k];
+    ef = abs( f0 ) + ( ex * ef );
+  }
+}
+
+//-----------------------------------------------------------------------------
+//-------------- rootArranger -------------------------------------------------
+//-----------------------------------------------------------------------------
+
+//-> rootArranger::rootArranger(...)
+rootArranger::rootArranger( rootContainer ** _roots,
+                            rootContainer ** _mu,
+                            const int _howclean )
+  : roots(_roots), mu(_mu), howclean(_howclean)
+{
+  found_roots=false;
+}
+//<-
+
+//-> void rootArranger::solve_all()
+void rootArranger::solve_all()
+{
+  int i;
+  found_roots= true;
+
+  // find roots of polys given by coeffs in roots
+  rc= roots[0]->getAnzElems();
+  for ( i= 0; i < rc; i++ )
+    if ( !roots[i]->solver( howclean ) )
+    {
+      found_roots= false;
+      return;
+    }
+  // find roots of polys given by coeffs in mu
+  mc= mu[0]->getAnzElems();
+  for ( i= 0; i < mc; i++ )
+    if ( ! mu[i]->solver( howclean ) )
+    {
+      found_roots= false;
+      return;
+    }
+}
+//<-
+
+//-> void rootArranger::arrange()
+void rootArranger::arrange()
+{
+  gmp_complex tmp,zwerg;
+  int anzm= mu[0]->getAnzElems();
+  int anzr= roots[0]->getAnzRoots();
+  int xkoord, r, rtest, xk, mtest;
+  bool found;
+  //gmp_complex mprec(1.0/pow(10,gmp_output_digits-5),1.0/pow(10,gmp_output_digits-5));
+
+  for ( xkoord= 0; xkoord < anzm; xkoord++ ) {    // f�r x1,x2, x1,x2,x3, x1,x2,...,xn
+    gmp_float mprec(1.0/pow(10.0,(int)(gmp_output_digits/3)));
+    for ( r= 0; r < anzr; r++ ) {                 // f�r jede Nullstelle
+      // (x1-koordinate) * evp[1] + (x2-koordinate) * evp[2] +
+      //                                  ... + (xkoord-koordinate) * evp[xkoord]
+      tmp= gmp_complex();
+      for ( xk =0; xk <= xkoord; xk++ )
+      {
+        tmp -= (*roots[xk])[r] * mu[xkoord]->evPointCoord(xk+1); //xk+1
+      }
+      found= false;
+      do { // while not found
+        for ( rtest= r; rtest < anzr; rtest++ ) {   // f�r jede Nullstelle
+           zwerg = tmp - (*roots[xk])[rtest] * mu[xkoord]->evPointCoord(xk+1); // xk+1, xkoord+2
+          for ( mtest= 0; mtest < anzr; mtest++ )
+          {
+            //          if ( tmp == (*mu[xkoord])[mtest] )
+            //          {
+            if ( ((zwerg.real() <= (*mu[xkoord])[mtest].real() + mprec) &&
+                  (zwerg.real() >= (*mu[xkoord])[mtest].real() - mprec)) &&
+                 ((zwerg.imag() <= (*mu[xkoord])[mtest].imag() + mprec) &&
+                  (zwerg.imag() >= (*mu[xkoord])[mtest].imag() - mprec)) )
+            {
+              roots[xk]->swapRoots( r, rtest );
+              found= true;
+              break;
+            }
+          }
+        } // rtest
+        if (!found)
+        {
+          WarnS("rootArranger::arrange: precision lost");
+          mprec*=10;
+	}
+      } while(!found);
+#if 0
+      if ( !found )
+      {
+        Warn("rootArranger::arrange: No match? coord %d, root %d.",xkoord,r);
+//#ifdef mprDEBUG_PROT
+        WarnS("One of these ...");
+        for ( rtest= r; rtest < anzr; rtest++ )
+        {
+          tmp= gmp_complex();
+          for ( xk =0; xk <= xkoord; xk++ )
+          {
+            tmp-= (*roots[xk])[r] * mu[xkoord]->evPointCoord(xk+1);
+          }
+          tmp-= (*roots[xk])[rtest] * mu[xkoord]->evPointCoord(xk+1); // xkoord+2
+          Warn("  %s",complexToStr(tmp,gmp_output_digits+1),rtest);
+        }
+        WarnS(" ... must match to one of these:");
+        for ( mtest= 0; mtest < anzr; mtest++ )
+        {
+          Warn("                  %s",complexToStr((*mu[xkoord])[mtest],gmp_output_digits+1));
+        }
+//#endif
+      }
+#endif
+    } // r
+  } // xkoord
+}
+//<-
+
+//-----------------------------------------------------------------------------
+//-------------- simplex ----- ------------------------------------------------
+//-----------------------------------------------------------------------------
+
+//  #ifdef mprDEBUG_PROT
+//  #define error(a) a
+//  #else
+//  #define error(a)
+//  #endif
+
+#define error(a) a
+
+#define MAXPOINTS      1000
+
+//-> simplex::*
+//
+simplex::simplex( int rows, int cols )
+   : LiPM_cols(cols), LiPM_rows(rows)
+{
+  int i;
+
+  LiPM_rows=LiPM_rows+3;
+  LiPM_cols=LiPM_cols+2;
+
+  LiPM = (mprfloat **)omAlloc( LiPM_rows * sizeof(mprfloat *) );  // LP matrix
+  for( i= 0; i < LiPM_rows; i++ )
+  {
+    // Mem must be allocated aligned, also for type double!
+    LiPM[i] = (mprfloat *)omAlloc0Aligned( LiPM_cols * sizeof(mprfloat) );
+  }
+
+  iposv = (int *)omAlloc0( 2*LiPM_rows*sizeof(int) );
+  izrov = (int *)omAlloc0( 2*LiPM_rows*sizeof(int) );
+
+  m=n=m1=m2=m3=icase=0;
+
+#ifdef mprDEBUG_ALL
+  Print("LiPM size: %d, %d\n",LiPM_rows,LiPM_cols);
+#endif
+}
+
+simplex::~simplex()
+{
+  // clean up
+  int i;
+  for( i= 0; i < LiPM_rows; i++ )
+  {
+    omFreeSize( (void *) LiPM[i], LiPM_cols * sizeof(mprfloat) );
+  }
+  omFreeSize( (void *) LiPM, LiPM_rows * sizeof(mprfloat *) );
+
+  omFreeSize( (void *) iposv, 2*LiPM_rows*sizeof(int) );
+  omFreeSize( (void *) izrov, 2*LiPM_rows*sizeof(int) );
+}
+
+BOOLEAN simplex::mapFromMatrix( matrix mm )
+{
+  int i,j;
+//    if ( MATROWS( m ) > LiPM_rows ||  MATCOLS( m ) > LiPM_cols ) {
+//      WarnS("");
+//      return FALSE;
+//    }
+
+  number coef;
+  for ( i= 1; i <= MATROWS( mm ); i++ )
+  {
+     for ( j= 1; j <= MATCOLS( mm ); j++ )
+     {
+        if ( MATELEM(mm,i,j) != NULL )
+        {
+           coef= pGetCoeff( MATELEM(mm,i,j) );
+           if ( coef != NULL && !nIsZero(coef) )
+              LiPM[i][j]= (double)(*(gmp_float*)coef);
+           //#ifdef mpr_DEBUG_PROT
+           //Print("%f ",LiPM[i][j]);
+           //#endif
+        }
+     }
+     //     PrintLn();
+  }
+
+  return TRUE;
+}
+
+matrix simplex::mapToMatrix( matrix mm )
+{
+  int i,j;
+//    if ( MATROWS( mm ) < LiPM_rows-3 ||  MATCOLS( m ) < LiPM_cols-2 ) {
+//      WarnS("");
+//      return NULL;
+//    }
+
+//Print(" %d x %d\n",MATROWS( mm ),MATCOLS( mm ));
+
+  number coef;
+  gmp_float * bla;
+  for ( i= 1; i <= MATROWS( mm ); i++ )
+  {
+    for ( j= 1; j <= MATCOLS( mm ); j++ )
+    {
+       pDelete( &(MATELEM(mm,i,j)) );
+       MATELEM(mm,i,j)= NULL;
+//Print(" %3.0f ",LiPM[i][j]);
+       if ( LiPM[i][j] != 0.0 )
+       {
+          bla= new gmp_float(LiPM[i][j]);
+          coef= (number)bla;
+          MATELEM(mm,i,j)= pOne();
+          pSetCoeff( MATELEM(mm,i,j), coef );
+       }
+    }
+//PrintLn();
+  }
+
+  return mm;
+}
+
+intvec * simplex::posvToIV()
+{
+   int i;
+   intvec * iv = new intvec( m );
+   for ( i= 1; i <= m; i++ )
+   {
+      IMATELEM(*iv,i,1)= iposv[i];
+   }
+   return iv;
+}
+
+intvec * simplex::zrovToIV()
+{
+   int i;
+   intvec * iv = new intvec( n );
+   for ( i= 1; i <= n; i++ )
+   {
+      IMATELEM(*iv,i,1)= izrov[i];
+   }
+   return iv;
+}
+
+void simplex::compute()
+{
+  int i,ip,ir,is,k,kh,kp,m12,nl1,nl2;
+  int *l1,*l2,*l3;
+  mprfloat q1, bmax;
+
+  if ( m != (m1+m2+m3) )
+  {
+    // error: bad input
+    error(WarnS("simplex::compute: Bad input constraint counts!");)
+    icase=-2;
+    return;
+  }
+
+  l1= (int *) omAlloc0( (n+1) * sizeof(int) );
+  l2= (int *) omAlloc0( (m+1) * sizeof(int) );
+  l3= (int *) omAlloc0( (m+1) * sizeof(int) );
+
+  nl1= n;
+  for ( k=1; k<=n; k++ ) l1[k]=izrov[k]=k;
+  nl2=m;
+  for ( i=1; i<=m; i++ )
+  {
+    if ( LiPM[i+1][1] < 0.0 )
+    {
+      // error: bad input
+      error(WarnS("simplex::compute: Bad input tableau!");)
+      error(Warn("simplex::compute: in input Matrix row %d, column 1, value %f",i+1,LiPM[i+1][1]);)
+      icase=-2;
+      // free mem l1,l2,l3;
+      omFreeSize( (void *) l3, (m+1) * sizeof(int) );
+      omFreeSize( (void *) l2, (m+1) * sizeof(int) );
+      omFreeSize( (void *) l1, (n+1) * sizeof(int) );
+      return;
+    }
+    l2[i]= i;
+    iposv[i]= n+i;
+  }
+  for ( i=1; i<=m2; i++) l3[i]= 1;
+  ir= 0;
+  if (m2+m3)
+  {
+    ir=1;
+    for ( k=1; k <= (n+1); k++ )
+    {
+      q1=0.0;
+      for ( i=m1+1; i <= m; i++ ) q1+= LiPM[i+1][k];
+      LiPM[m+2][k]= -q1;
+    }
+
+    do
+    {
+      simp1(LiPM,m+1,l1,nl1,0,&kp,&bmax);
+      if ( bmax <= SIMPLEX_EPS && LiPM[m+2][1] < -SIMPLEX_EPS )
+      {
+        icase= -1; // no solution found
+        // free mem l1,l2,l3;
+        omFreeSize( (void *) l3, (m+1) * sizeof(int) );
+        omFreeSize( (void *) l2, (m+1) * sizeof(int) );
+        omFreeSize( (void *) l1, (n+1) * sizeof(int) );
+        return;
+      }
+      else if ( bmax <= SIMPLEX_EPS && LiPM[m+2][1] <= SIMPLEX_EPS )
+      {
+        m12= m1+m2+1;
+        if ( m12 <= m )
+        {
+          for ( ip= m12; ip <= m; ip++ )
+          {
+            if ( iposv[ip] == (ip+n) )
+            {
+              simp1(LiPM,ip,l1,nl1,1,&kp,&bmax);
+              if ( fabs(bmax) >= SIMPLEX_EPS)
+                goto one;
+            }
+          }
+        }
+        ir= 0;
+        --m12;
+        if ( m1+1 <= m12 )
+          for ( i=m1+1; i <= m12; i++ )
+            if ( l3[i-m1] == 1 )
+              for ( k=1; k <= n+1; k++ )
+                LiPM[i+1][k] = -(LiPM[i+1][k]);
+        break;
+      }
+      //#if DEBUG
+      //print_bmat( a, m+2, n+3);
+      //#endif
+      simp2(LiPM,n,l2,nl2,&ip,kp,&q1);
+      if ( ip == 0 )
+      {
+        icase = -1; // no solution found
+        // free mem l1,l2,l3;
+        omFreeSize( (void *) l3, (m+1) * sizeof(int) );
+        omFreeSize( (void *) l2, (m+1) * sizeof(int) );
+        omFreeSize( (void *) l1, (n+1) * sizeof(int) );
+        return;
+      }
+    one: simp3(LiPM,m+1,n,ip,kp);
+      // #if DEBUG
+      // print_bmat(a,m+2,n+3);
+      // #endif
+      if ( iposv[ip] >= (n+m1+m2+1))
+      {
+        for ( k= 1; k <= nl1; k++ )
+          if ( l1[k] == kp ) break;
+        --nl1;
+        for ( is=k; is <= nl1; is++ ) l1[is]= l1[is+1];
+        ++(LiPM[m+2][kp+1]);
+        for ( i= 1; i <= m+2; i++ ) LiPM[i][kp+1] = -(LiPM[i][kp+1]);
+      }
+      else
+      {
+        if ( iposv[ip] >= (n+m1+1) )
+        {
+          kh= iposv[ip]-m1-n;
+          if ( l3[kh] )
+          {
+            l3[kh]= 0;
+            ++(LiPM[m+2][kp+1]);
+            for ( i=1; i<= m+2; i++ )
+              LiPM[i][kp+1] = -(LiPM[i][kp+1]);
+          }
+        }
+      }
+      is= izrov[kp];
+      izrov[kp]= iposv[ip];
+      iposv[ip]= is;
+    } while (ir);
+  }
+  /* end of phase 1, have feasible sol, now optimize it */
+  loop
+  {
+    // #if DEBUG
+    // print_bmat( a, m+1, n+5);
+    // #endif
+    simp1(LiPM,0,l1,nl1,0,&kp,&bmax);
+    if (bmax <= /*SIMPLEX_EPS*/0.0)
+    {
+      icase=0; // finite solution found
+      // free mem l1,l2,l3
+      omFreeSize( (void *) l3, (m+1) * sizeof(int) );
+      omFreeSize( (void *) l2, (m+1) * sizeof(int) );
+      omFreeSize( (void *) l1, (n+1) * sizeof(int) );
+      return;
+    }
+    simp2(LiPM,n,l2,nl2,&ip,kp,&q1);
+    if (ip == 0)
+    {
+      //printf("Unbounded:");
+      // #if DEBUG
+      //       print_bmat( a, m+1, n+1);
+      // #endif
+      icase=1;                /* unbounded */
+      // free mem
+      omFreeSize( (void *) l3, (m+1) * sizeof(int) );
+      omFreeSize( (void *) l2, (m+1) * sizeof(int) );
+      omFreeSize( (void *) l1, (n+1) * sizeof(int) );
+      return;
+    }
+    simp3(LiPM,m,n,ip,kp);
+    is= izrov[kp];
+    izrov[kp]= iposv[ip];
+    iposv[ip]= is;
+  }/*for ;;*/
+}
+
+void simplex::simp1( mprfloat **a, int mm, int ll[], int nll, int iabf, int *kp, mprfloat *bmax )
+{
+  int k;
+  mprfloat test;
+
+  if( nll <= 0)
+  {                        /* init'tion: fixed */
+    *bmax = 0.0;
+    return;
+  }
+  *kp=ll[1];
+  *bmax=a[mm+1][*kp+1];
+  for (k=2;k<=nll;k++)
+  {
+    if (iabf == 0)
+    {
+      test=a[mm+1][ll[k]+1]-(*bmax);
+      if (test > 0.0)
+      {
+        *bmax=a[mm+1][ll[k]+1];
+        *kp=ll[k];
+      }
+    }
+    else
+    {                        /* abs values: have fixed it */
+      test=fabs(a[mm+1][ll[k]+1])-fabs(*bmax);
+      if (test > 0.0)
+      {
+        *bmax=a[mm+1][ll[k]+1];
+        *kp=ll[k];
+      }
+    }
+  }
+}
+
+void simplex::simp2( mprfloat **a, int nn, int l2[], int nl2, int *ip, int kp, mprfloat *q1 )
+{
+  int k,ii,i;
+  mprfloat qp,q0,q;
+
+  *ip= 0;
+  for ( i=1; i <= nl2; i++ )
+  {
+    if ( a[l2[i]+1][kp+1] < -SIMPLEX_EPS )
+    {
+      *q1= -a[l2[i]+1][1] / a[l2[i]+1][kp+1];
+      *ip= l2[i];
+      for ( i= i+1; i <= nl2; i++ )
+      {
+        ii= l2[i];
+        if (a[ii+1][kp+1] < -SIMPLEX_EPS)
+        {
+          q= -a[ii+1][1] / a[ii+1][kp+1];
+          if (q - *q1 < -SIMPLEX_EPS)
+          {
+            *ip=ii;
+            *q1=q;
+          }
+          else if (q - *q1 < SIMPLEX_EPS)
+          {
+            for ( k=1; k<= nn; k++ )
+            {
+              qp= -a[*ip+1][k+1]/a[*ip+1][kp+1];
+              q0= -a[ii+1][k+1]/a[ii+1][kp+1];
+              if ( q0 != qp ) break;
+            }
+            if ( q0 < qp ) *ip= ii;
+          }
+        }
+      }
+    }
+  }
+}
+
+void simplex::simp3( mprfloat **a, int i1, int k1, int ip, int kp )
+{
+  int kk,ii;
+  mprfloat piv;
+
+  piv= 1.0 / a[ip+1][kp+1];
+  for ( ii=1; ii <= i1+1; ii++ )
+  {
+    if ( ii -1 != ip )
+    {
+      a[ii][kp+1] *= piv;
+      for ( kk=1; kk <= k1+1; kk++ )
+        if ( kk-1 != kp )
+          a[ii][kk] -= a[ip+1][kk] * a[ii][kp+1];
+    }
+  }
+  for ( kk=1; kk<= k1+1; kk++ )
+    if ( kk-1 != kp ) a[ip+1][kk] *= -piv;
+  a[ip+1][kp+1]= piv;
+}
+//<-
+
+//-----------------------------------------------------------------------------
+
+//#endif // HAVE_MPR
+
+// local Variables: ***
+// folded-file: t ***
+// compile-command-1: "make installg" ***
+// compile-command-2: "make install" ***
+// End: ***
+
diff --git a/kernel/numeric/mpr_numeric.h b/kernel/numeric/mpr_numeric.h
new file mode 100644
index 0000000..36a4984
--- /dev/null
+++ b/kernel/numeric/mpr_numeric.h
@@ -0,0 +1,236 @@
+#ifndef MPR_NUMERIC_H
+#define MPR_NUMERIC_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+
+
+/*
+* ABSTRACT - multipolynomial resultants - numeric stuff
+*            ( root finder, vandermonde system solver, simplex )
+*/
+
+//-> include & define stuff
+#include <coeffs/numbers.h>
+#include <coeffs/mpr_global.h>
+#include <coeffs/mpr_complex.h>
+
+// define polish mode when finding roots
+#define PM_NONE    0
+#define PM_POLISH  1
+#define PM_CORRUPT 2
+//<-
+
+//-> vandermonde system solver
+/**
+ * vandermonde system solver for interpolating polynomials from their values
+ */
+class vandermonde
+{
+public:
+  vandermonde( const long _cn, const long _n,
+	       const long _maxdeg, number *_p, const bool _homog = true );
+  ~vandermonde();
+
+  /** Solves the Vandermode linear system
+   *    \sum_{i=1}^{n} x_i^k-1 w_i = q_k, k=1,..,n.
+     * Any computations are done using type number to get high pecision results.
+   * @param  q n-tuple of results (right hand of equations)
+   * @return w n-tuple of coefficients of resulting polynomial, lowest deg first
+   */
+  number * interpolateDense( const number * q );
+
+  poly numvec2poly(const number * q );
+
+private:
+  void init();
+
+private:
+  long n;       // number of variables
+  long cn;      // real number of coefficients of poly to interpolate
+  long maxdeg;  // degree of the polynomial to interpolate
+  long l;       // max number of coefficients in poly of deg maxdeg = (maxdeg+1)^n
+
+  number *p;    // evaluation point
+  number *x;    // coefficients, determinend by init() from *p
+
+  bool homog;
+};
+//<-
+
+//-> rootContainer
+/**
+ * complex root finder for univariate polynomials based on laguers algorithm
+ */
+class rootContainer
+{
+public:
+  enum rootType { none, cspecial, cspecialmu, det, onepoly };
+
+  rootContainer();
+  ~rootContainer();
+
+  void fillContainer( number *_coeffs, number *_ievpoint,
+		      const int _var, const int _tdg,
+		      const rootType _rt, const int _anz );
+
+  bool solver( const int polishmode= PM_NONE );
+
+  poly getPoly();
+
+  //gmp_complex & operator[] ( const int i );
+  inline gmp_complex & operator[] ( const int i )
+  {
+    return *theroots[i];
+  }
+  gmp_complex & evPointCoord( const int i );
+
+  inline gmp_complex * getRoot( const int i )
+  {
+    return theroots[i];
+  }
+
+  bool swapRoots( const int from, const int to );
+
+  int getAnzElems() { return anz; }
+  int getLDim() { return anz; }
+  int getAnzRoots() { return tdg; }
+
+private:
+  rootContainer( const rootContainer & v );
+
+  /** Given the degree tdg and the tdg+1 complex coefficients ad[0..tdg]
+   * (generated from the number coefficients coeffs[0..tdg]) of the polynomial
+   * this routine successively calls "laguer" and finds all m complex roots in
+   * roots[0..tdg]. The bool var "polish" should be input as "true" if polishing
+   * (also by "laguer") is desired, "false" if the roots will be subsequently
+   * polished by other means.
+   */
+  bool laguer_driver( gmp_complex ** a, gmp_complex ** roots, bool polish = true );
+  bool isfloat(gmp_complex **a);
+  void divlin(gmp_complex **a, gmp_complex x, int j);
+  void divquad(gmp_complex **a, gmp_complex x, int j);
+  void solvequad(gmp_complex **a, gmp_complex **r, int &k, int &j);
+  void sortroots(gmp_complex **roots, int r, int c, bool isf);
+  void sortre(gmp_complex **r, int l, int u, int inc);
+
+  /** Given the degree m and the m+1 complex coefficients a[0..m] of the
+   * polynomial, and given the complex value x, this routine improves x by
+   * Laguerre's method until it converges, within the achievable roundoff limit,
+   * to a root of the given polynomial. The number of iterations taken is
+   * returned at its.
+   */
+  void laguer(gmp_complex ** a, int m, gmp_complex * x, int * its, bool type);
+  void computefx(gmp_complex **a, gmp_complex x, int m,
+                gmp_complex &f0, gmp_complex &f1, gmp_complex &f2,
+                gmp_float &ex, gmp_float &ef);
+  void computegx(gmp_complex **a, gmp_complex x, int m,
+                gmp_complex &f0, gmp_complex &f1, gmp_complex &f2,
+                gmp_float &ex, gmp_float &ef);
+  void checkimag(gmp_complex *x, gmp_float &e);
+
+  int var;
+  int tdg;
+
+  number * coeffs;
+  number * ievpoint;
+  rootType rt;
+
+  gmp_complex ** theroots;
+
+  int anz;
+  bool found_roots;
+};
+//<-
+
+class slists; typedef slists * lists;
+
+//-> class rootArranger
+class rootArranger
+{
+public:
+  friend lists listOfRoots( rootArranger*, const unsigned int oprec );
+
+  rootArranger( rootContainer ** _roots,
+		rootContainer ** _mu,
+		const int _howclean = PM_CORRUPT );
+  ~rootArranger() {}
+
+  void solve_all();
+  void arrange();
+
+  bool success() { return found_roots; }
+
+private:
+  rootArranger( const rootArranger & );
+
+  rootContainer ** roots;
+  rootContainer ** mu;
+
+  int howclean;
+  int rc,mc;
+  bool found_roots;
+};
+
+
+
+//<-
+
+//-> simplex computation
+//   (used by sparse matrix construction)
+#define SIMPLEX_EPS 1.0e-12
+
+/** Linear Programming / Linear Optimization using Simplex - Algorithm
+ *
+ * On output, the tableau LiPM is indexed by two arrays of integers.
+ * ipsov[j] contains, for j=1..m, the number i whose original variable
+ * is now represented by row j+1 of LiPM. (left-handed vars in solution)
+ * (first row is the one with the objective function)
+ * izrov[j] contains, for j=1..n, the number i whose original variable
+ * x_i is now a right-handed variable, rep. by column j+1 of LiPM.
+ * These vars are all zero in the solution. The meaning of n<i<n+m1+m2
+ * is the same as above.
+ */
+class simplex
+{
+public:
+
+  int m;         // number of constraints, make sure m == m1 + m2 + m3 !!
+  int n;         // # of independent variables
+  int m1,m2,m3;  // constraints <=, >= and ==
+  int icase;     // == 0: finite solution found;
+                 // == +1 objective funtion unbound; == -1: no solution
+  int *izrov,*iposv;
+
+  mprfloat **LiPM; // the matrix (of size [m+2, n+1])
+
+  /** #rows should be >= m+2, #cols >= n+1
+   */
+  simplex( int rows, int cols );
+  ~simplex();
+
+  BOOLEAN mapFromMatrix( matrix m );
+  matrix mapToMatrix( matrix m );
+  intvec * posvToIV();
+  intvec * zrovToIV();
+
+  void compute();
+
+private:
+  simplex( const simplex & );
+  void simp1( mprfloat **a, int mm, int ll[], int nll, int iabf, int *kp, mprfloat *bmax );
+  void simp2( mprfloat **a, int n, int l2[], int nl2, int *ip, int kp, mprfloat *q1 );
+  void simp3( mprfloat **a, int i1, int k1, int ip, int kp );
+
+  int LiPM_cols,LiPM_rows;
+};
+
+//<-
+
+#endif /*MPR_NUMERIC_H*/
+
+// local Variables: ***
+// folded-file: t ***
+// compile-command-1: "make installg" ***
+// compile-command-2: "make install" ***
+// End: ***
diff --git a/kernel/numeric/test.cc b/kernel/numeric/test.cc
new file mode 100644
index 0000000..bb2c248
--- /dev/null
+++ b/kernel/numeric/test.cc
@@ -0,0 +1,376 @@
+#include <kernel/mod2.h>
+
+#include <omalloc/omalloc.h>
+
+#include <resources/feFopen.h>
+#include <resources/feResource.h>
+
+
+#include <factory/factory.h> // :(
+
+#include <misc/auxiliary.h>
+#include <misc/intvec.h>
+#include <misc/int64vec.h>
+#include <misc/mylimits.h>
+#include <misc/options.h>
+
+#include <reporter/reporter.h>
+
+#include <coeffs/si_gmp.h>
+#include <coeffs/coeffs.h>
+#include <coeffs/numbers.h>
+
+#ifndef PLURAL_INTERNAL_DECLARATIONS
+#define PLURAL_INTERNAL_DECLARATIONS
+#endif
+
+#ifndef PLURAL_INTERNAL_DECLARATIONS_GB_HACK
+#define PLURAL_INTERNAL_DECLARATIONS_GB_HACK
+#endif
+
+#include <polys/nc/gb_hack.h>
+#include <polys/nc/nc.h>
+#include <polys/nc/ncSACache.h>
+#include <polys/nc/ncSAFormula.h>
+#include <polys/nc/ncSAMult.h>
+#include <polys/nc/sca.h>
+#include <polys/nc/summator.h>
+
+#include <polys/kbuckets.h>
+#include <polys/matpol.h>
+#include <polys/mod_raw.h>
+#include <polys/prCopy.h>
+#include <polys/sbuckets.h>
+#include <polys/simpleideals.h>
+#include <polys/weight.h>
+
+#include <polys/monomials/maps.h>
+#include <polys/monomials/monomials.h>
+#include <polys/monomials/p_polys.h>
+#include <polys/monomials/ring.h>
+
+#include <polys/templates/p_MemAdd.h>
+#include <polys/templates/p_Procs.h>
+
+#include <polys/operations/pShallowCopyDelete.h>
+
+#include <polys/clapsing.h>
+
+
+// // TODO: DUE to the use of HALT in npolygon.cc :(((
+extern "C" {void m2_end(int i){exit(i);}}
+
+// // TODO: DUE to its use in kutil.cc :(((
+// char * showOption(){return NULL;}
+
+
+// #include "structs.h"
+
+
+// HEADERS:
+#include <kernel/ideals.h>
+#include <kernel/digitech.h>
+#include <kernel/fast_mult.h>
+
+// #include <kernel/spectrum/kmatrix.h>
+#include <kernel/preimage.h>
+
+#include <kernel/structs.h>
+
+#include <kernel/polys.h>
+
+void TestGBEngine()
+{
+
+  //  R = MPolynomialRing_polydict(QQ,5,'w,x,y,z,C', order='degrevlex')
+  //  J = (w*w - x*z, w*x - y*z, x*x - w*y, x*y - z*z, y*y - w*z)
+
+  const short w = 1;
+  const short x = 2;
+  const short y = 3;
+  const short z = 4;
+
+  const short N = (z - w + 1);
+
+  char **n=(char**)omalloc(N*sizeof(char*));
+
+
+  n[w-1]=omStrDup("w");
+  n[x-1]=omStrDup("x");
+  n[y-1]=omStrDup("y");
+  n[z-1]=omStrDup("z");
+
+
+  const int D = 3;
+  int *order = (int *) omAlloc0(D* sizeof(int));
+  int *block0 = (int *)omAlloc0(D * sizeof(int));
+  int *block1 = (int *)omAlloc0(D * sizeof(int));
+
+  order[0]  = ringorder_dp;
+  block0[0] = 1;
+  block1[0] = N;
+
+  order[1]  = ringorder_C;
+  block0[1] = 1;
+  block1[1] = N;
+
+  ring R = rDefault(0, N, n, D, order, block0, block1);
+
+//   ring R = rDefault(0, N, n);
+
+  rWrite(R); PrintLn();
+
+#ifdef RDEBUG
+  rDebugPrint(R);
+#endif
+
+  ideal I = idInit(5, 1);
+
+  int gen = 0;
+
+  {
+    // -xz
+    poly p = p_ISet(-1,R);
+
+    p_SetExp(p, x, 1, R);
+    p_SetExp(p, z, 1, R);
+    p_Setm(p, R);
+
+    assume( p_GetExp(p, x, R) == 1 );
+    assume( p_GetExp(p, z, R) == 1 );
+    assume( p_GetExp(p, w, R) == 0 );
+    assume( p_GetExp(p, y, R) == 0 );
+
+    // +w2
+    poly lp = p_ISet(1,R);
+    p_SetExp(lp, w, 2, R);
+    p_Setm(lp, R);
+
+    assume( p_GetExp(lp, w, R) == 2 );
+    assume( p_GetExp(lp, x, R) == 0 );
+    assume( p_GetExp(lp, y, R) == 0 );
+    assume( p_GetExp(lp, z, R) == 0 );
+
+    MATELEM(I, 1, ++gen) = p_Add_q(lp, p, R); // w2 - xz
+  }
+
+  {
+    // -yz
+    poly p = p_ISet(-1,R);
+
+    p_SetExp(p, y, 1, R);
+    p_SetExp(p, z, 1, R);
+    p_Setm(p, R);
+
+    assume( p_GetExp(p, y, R) == 1 );
+    assume( p_GetExp(p, z, R) == 1 );
+    assume( p_GetExp(p, w, R) == 0 );
+    assume( p_GetExp(p, x, R) == 0 );
+
+    // +wx
+    poly lp = p_ISet(1,R);
+    p_SetExp(lp, w, 1, R);
+    p_SetExp(lp, x, 1, R);
+    p_Setm(lp, R);
+
+    assume( p_GetExp(lp, w, R) == 1 );
+    assume( p_GetExp(lp, x, R) == 1 );
+    assume( p_GetExp(lp, y, R) == 0 );
+    assume( p_GetExp(lp, z, R) == 0 );
+
+    MATELEM(I, 1, ++gen) = p_Add_q(lp, p, R); // wx - yz
+  }
+
+
+  {
+    // -wy
+    poly p = p_ISet(-1,R);
+
+    p_SetExp(p, y, 1, R);
+    p_SetExp(p, w, 1, R);
+    p_Setm(p, R);
+
+    assume( p_GetExp(p, y, R) == 1 );
+    assume( p_GetExp(p, w, R) == 1 );
+    assume( p_GetExp(p, z, R) == 0 );
+    assume( p_GetExp(p, x, R) == 0 );
+
+    // +x2
+    poly lp = p_ISet(1,R);
+    p_SetExp(lp, x, 2, R);
+    p_Setm(lp, R);
+
+    assume( p_GetExp(lp, w, R) == 0 );
+    assume( p_GetExp(lp, x, R) == 2 );
+    assume( p_GetExp(lp, y, R) == 0 );
+    assume( p_GetExp(lp, z, R) == 0 );
+
+    MATELEM(I, 1, ++gen) = p_Add_q(lp, p, R); // x2 - wy
+  }
+
+
+  {
+    // -z2
+    poly p = p_ISet(-1,R);
+
+    p_SetExp(p, z, 2, R);
+    p_Setm(p, R);
+
+    assume( p_GetExp(p, y, R) == 0 );
+    assume( p_GetExp(p, w, R) == 0 );
+    assume( p_GetExp(p, z, R) == 2 );
+    assume( p_GetExp(p, x, R) == 0 );
+
+    // +xy
+    poly lp = p_ISet(1,R);
+    p_SetExp(lp, x, 1, R);
+    p_SetExp(lp, y, 1, R);
+    p_Setm(lp, R);
+
+    assume( p_GetExp(lp, w, R) == 0 );
+    assume( p_GetExp(lp, x, R) == 1 );
+    assume( p_GetExp(lp, y, R) == 1 );
+    assume( p_GetExp(lp, z, R) == 0 );
+
+    MATELEM(I, 1, ++gen) = p_Add_q(lp, p, R); // xy - z2
+  }
+
+
+  {
+    // -wz
+    poly p = p_ISet(-1,R);
+
+    p_SetExp(p, w, 1, R);
+    p_SetExp(p, z, 1, R);
+    p_Setm(p, R);
+
+    assume( p_GetExp(p, y, R) == 0 );
+    assume( p_GetExp(p, w, R) == 1 );
+    assume( p_GetExp(p, z, R) == 1 );
+    assume( p_GetExp(p, x, R) == 0 );
+
+    // +y2
+    poly lp = p_ISet(1,R);
+    p_SetExp(lp, y, 2, R);
+    p_Setm(lp, R);
+
+    assume( p_GetExp(lp, w, R) == 0 );
+    assume( p_GetExp(lp, x, R) == 0 );
+    assume( p_GetExp(lp, y, R) == 2 );
+    assume( p_GetExp(lp, z, R) == 0 );
+
+    MATELEM(I, 1, ++gen) = p_Add_q(lp, p, R); // y2 - wz
+  }
+#ifdef PDEBUG
+  PrintS("I: ");
+  idShow(I, R, R, 0);
+#endif
+
+
+//  ideal kStd(ideal F, ideal Q, tHomog h, intvec ** mw,intvec *hilb=NULL,
+//             int syzComp=0,int newIdeal=0, intvec *vw=NULL);
+  // make R the default ring:
+  rChangeCurrRing(R);
+
+ ////
+
+  idDelete( &I, R);
+  rDelete(R); // should cleanup every belonging polynomial, right!?
+
+}
+
+
+
+void TestSimpleRingArithmetcs()
+{
+  // Libpolys tests:
+
+  // construct the ring Z/32003[x,y,z]
+  // the variable names
+  char **n=(char**)omalloc(3*sizeof(char*));
+  n[0]=omStrDup("x");
+  n[1]=omStrDup("y");
+  n[2]=omStrDup("z2");
+
+  ring R = rDefault(32003,3,n); //  ring R = rDefault(0,3,n);
+
+  rWrite(R); PrintLn();
+
+#ifdef RDEBUG
+  rDebugPrint(R);
+#endif
+
+
+  poly p = p_ISet(1,R); p_SetExp(p,1,1, R); p_Setm(p, R);
+
+  assume( p_GetExp(p,1, R) == 1 );
+
+  poly pp = pp_Mult_qq( p, p, R);
+
+  Print("p: "); p_Write0(p, R); Print(", deg(p): %ld", p_Totaldegree(p, R)); assume( 1 == p_Totaldegree(p, R) );
+
+  Print("; p*p : "); p_Write0(pp, R); Print("deg(pp): %ld\n", p_Totaldegree(pp, R)); assume( 2 == p_Totaldegree(pp, R) );
+
+
+  p_Delete(&p, R);
+
+  assume( p_GetExp(pp,1, R) == 2 );
+
+  p_Delete(&pp, R);
+
+
+//  rDelete(R);
+
+  // make R the default ring:
+  rChangeCurrRing(R);
+
+  // create the polynomial 1
+  poly p1=pISet(1);
+
+  // create tthe polynomial 2*x^3*z^2
+  poly p2=p_ISet(2,R);
+  pSetExp(p2,1,3);
+  pSetExp(p2,3,2);
+  pSetm(p2);
+
+  // print p1 + p2
+  Print("p1: "); pWrite0(p1);
+  Print(" + p2: "); pWrite0(p2);
+  Print("  ---- >>>> ");
+
+  // compute p1+p2
+  p1=p_Add_q(p1,p2,R); p2=NULL;
+  pWrite(p1);
+
+  // clean up:
+//  pDelete(&p1);
+
+  rDelete(R); // should cleanup every belonging polynomial, right!?
+}
+
+
+int main( int, char *argv[] )
+{
+  assume( sizeof(long) == SIZEOF_LONG );
+
+  if( sizeof(long) != SIZEOF_LONG )
+  {
+    WerrorS("Bad config.h: wrong size of long!");
+
+    return(1);
+  }
+
+
+  feInitResources(argv[0]);
+
+  StringSetS("ressources in use (as reported by feStringAppendResources(0):\n");
+  feStringAppendResources(0);
+
+  PrintLn();
+  { char* s = StringEndS(); PrintS(s); omFree(s); }
+
+  TestGBEngine();
+  TestSimpleRingArithmetcs();
+
+  return 0;
+}
diff --git a/kernel/oswrapper/Makefile.am b/kernel/oswrapper/Makefile.am
new file mode 100644
index 0000000..182f615
--- /dev/null
+++ b/kernel/oswrapper/Makefile.am
@@ -0,0 +1,22 @@
+ACLOCAL_AMFLAGS=-I ../../m4
+AM_CPPFLAGS=-I${top_srcdir} -I${top_builddir} -I${top_srcdir}/libpolys -I${top_builddir}/libpolys \
+${FACTORY_INCLUDES} $(OMALLOC_INCLUDES) $(RESOURCES_INCLUDES) \
+${NTL_CFLAGS} $(FLINT_CFLAGS) ${GMP_CFLAGS}
+
+noinst_LTLIBRARIES=liboswrapper.la
+liboswrapper_la_SOURCES=feread.cc fereadl.c timer.cc rlimit.c
+
+liboswrapper_la_includedir=$(includedir)/singular/kernel/oswrapper
+liboswrapper_la_include_HEADERS=feread.h timer.h rlimit.h
+
+
+
+TESTS_ENVIRONMENT = SINGULARPATH='${abs_top_builddir}/libpolys/polys/.libs:${abs_top_builddir}/factory/gftables'
+TESTS_ENVIRONMENT += SINGULAR_ROOT_DIR='${abs_top_builddir}'
+
+TESTS = test
+check_PROGRAMS = $(TESTS)
+test_SOURCES = test.cc
+test_LDADD   = liboswrapper.la ${builddir}/../libkernelCommon.la
+
+CLEANFILES = $(TESTS)
diff --git a/kernel/oswrapper/Makefile.in b/kernel/oswrapper/Makefile.in
new file mode 100644
index 0000000..bda2040
--- /dev/null
+++ b/kernel/oswrapper/Makefile.in
@@ -0,0 +1,1127 @@
+# Makefile.in generated by automake 1.13.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 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@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+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@
+TESTS = test$(EXEEXT)
+check_PROGRAMS = $(am__EXEEXT_1)
+subdir = kernel/oswrapper
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/build-aux/depcomp \
+	$(liboswrapper_la_include_HEADERS) \
+	$(top_srcdir)/build-aux/test-driver
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_append_compile_flags.m4 \
+	$(top_srcdir)/m4/ax_append_flag.m4 \
+	$(top_srcdir)/m4/ax_append_link_flags.m4 \
+	$(top_srcdir)/m4/ax_check_compile_flag.m4 \
+	$(top_srcdir)/m4/ax_check_link_flag.m4 \
+	$(top_srcdir)/m4/ax_compute_relative_paths.m4 \
+	$(top_srcdir)/m4/ax_normalize_path.m4 \
+	$(top_srcdir)/m4/ax_prefix_config_h.m4 \
+	$(top_srcdir)/m4/ax_pthread.m4 \
+	$(top_srcdir)/m4/ax_python_embed.m4 \
+	$(top_srcdir)/m4/ax_python_with_version.m4 \
+	$(top_srcdir)/m4/cpu-check.m4 $(top_srcdir)/m4/dbm-check.m4 \
+	$(top_srcdir)/m4/flags.m4 $(top_srcdir)/m4/flint-check.m4 \
+	$(top_srcdir)/m4/gfanlib-check.m4 \
+	$(top_srcdir)/m4/gmp-check.m4 \
+	$(top_srcdir)/m4/google-perftools.m4 \
+	$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+	$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+	$(top_srcdir)/m4/lt~obsolete.m4 \
+	$(top_srcdir)/m4/mathic-check.m4 $(top_srcdir)/m4/ntl-check.m4 \
+	$(top_srcdir)/m4/options.m4 $(top_srcdir)/m4/p-procs.m4 \
+	$(top_srcdir)/m4/polymake-check.m4 \
+	$(top_srcdir)/m4/readline-check.m4 $(top_srcdir)/configure.ac
+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 =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+liboswrapper_la_LIBADD =
+am_liboswrapper_la_OBJECTS = feread.lo fereadl.lo timer.lo rlimit.lo
+liboswrapper_la_OBJECTS = $(am_liboswrapper_la_OBJECTS)
+AM_V_lt = $(am__v_lt_ at AM_V@)
+am__v_lt_ = $(am__v_lt_ at AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 = 
+am__EXEEXT_1 = test$(EXEEXT)
+am_test_OBJECTS = test.$(OBJEXT)
+test_OBJECTS = $(am_test_OBJECTS)
+test_DEPENDENCIES = liboswrapper.la ${builddir}/../libkernelCommon.la
+AM_V_P = $(am__v_P_ at AM_V@)
+am__v_P_ = $(am__v_P_ at AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_ at AM_V@)
+am__v_GEN_ = $(am__v_GEN_ at AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_ at AM_V@)
+am__v_at_ = $(am__v_at_ at AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+DEFAULT_INCLUDES = -I. at am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+	$(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_ at AM_V@)
+am__v_CC_ = $(am__v_CC_ at AM_DEFAULT_V@)
+am__v_CC_0 = @echo "  CC      " $@;
+am__v_CC_1 = 
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+	$(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_ at AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_ at AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo "  CCLD    " $@;
+am__v_CCLD_1 = 
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \
+	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+	$(AM_CXXFLAGS) $(CXXFLAGS)
+AM_V_CXX = $(am__v_CXX_ at AM_V@)
+am__v_CXX_ = $(am__v_CXX_ at AM_DEFAULT_V@)
+am__v_CXX_0 = @echo "  CXX     " $@;
+am__v_CXX_1 = 
+CXXLD = $(CXX)
+CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+	$(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CXXLD = $(am__v_CXXLD_ at AM_V@)
+am__v_CXXLD_ = $(am__v_CXXLD_ at AM_DEFAULT_V@)
+am__v_CXXLD_0 = @echo "  CXXLD   " $@;
+am__v_CXXLD_1 = 
+SOURCES = $(liboswrapper_la_SOURCES) $(test_SOURCES)
+DIST_SOURCES = $(liboswrapper_la_SOURCES) $(test_SOURCES)
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+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__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
+am__installdirs = "$(DESTDIR)$(liboswrapper_la_includedir)"
+HEADERS = $(liboswrapper_la_include_HEADERS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors_dummy = \
+  mgn= red= grn= lgn= blu= brg= std=; \
+  am__color_tests=no
+am__tty_colors = { \
+  $(am__tty_colors_dummy); \
+  if test "X$(AM_COLOR_TESTS)" = Xno; then \
+    am__color_tests=no; \
+  elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+    am__color_tests=yes; \
+  elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+    am__color_tests=yes; \
+  fi; \
+  if test $$am__color_tests = yes; then \
+    red=''; \
+    grn=''; \
+    lgn=''; \
+    blu=''; \
+    mgn=''; \
+    brg=''; \
+    std=''; \
+  fi; \
+}
+am__recheck_rx = ^[ 	]*:recheck:[ 	]*
+am__global_test_result_rx = ^[ 	]*:global-test-result:[ 	]*
+am__copy_in_global_log_rx = ^[ 	]*:copy-in-global-log:[ 	]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+  recheck = 1; \
+  while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+    { \
+      if (rc < 0) \
+        { \
+          if ((getline line2 < ($$0 ".log")) < 0) \
+	    recheck = 0; \
+          break; \
+        } \
+      else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+        { \
+          recheck = 0; \
+          break; \
+        } \
+      else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+        { \
+          break; \
+        } \
+    }; \
+  if (recheck) \
+    print $$0; \
+  close ($$0 ".trs"); \
+  close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+  print "fatal: making $@: " msg | "cat >&2"; \
+  exit 1; \
+} \
+function rst_section(header) \
+{ \
+  print header; \
+  len = length(header); \
+  for (i = 1; i <= len; i = i + 1) \
+    printf "="; \
+  printf "\n\n"; \
+} \
+{ \
+  copy_in_global_log = 1; \
+  global_test_result = "RUN"; \
+  while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+    { \
+      if (rc < 0) \
+         fatal("failed to read from " $$0 ".trs"); \
+      if (line ~ /$(am__global_test_result_rx)/) \
+        { \
+          sub("$(am__global_test_result_rx)", "", line); \
+          sub("[ 	]*$$", "", line); \
+          global_test_result = line; \
+        } \
+      else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+        copy_in_global_log = 0; \
+    }; \
+  if (copy_in_global_log) \
+    { \
+      rst_section(global_test_result ": " $$0); \
+      while ((rc = (getline line < ($$0 ".log"))) != 0) \
+      { \
+        if (rc < 0) \
+          fatal("failed to read from " $$0 ".log"); \
+        print line; \
+      }; \
+      printf "\n"; \
+    }; \
+  close ($$0 ".trs"); \
+  close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/   &   /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this.  Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+  --color-tests "$$am__color_tests" \
+  --enable-hard-errors "$$am__enable_hard_errors" \
+  --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test.  Creates the
+# directory for the log if needed.  Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log.  Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT.  Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup);					\
+$(am__vpath_adj_setup) $(am__vpath_adj)			\
+$(am__tty_colors);					\
+srcdir=$(srcdir); export srcdir;			\
+case "$@" in						\
+  */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;;	\
+    *) am__odir=.;; 					\
+esac;							\
+test "x$$am__odir" = x"." || test -d "$$am__odir" 	\
+  || $(MKDIR_P) "$$am__odir" || exit $$?;		\
+if test -f "./$$f"; then dir=./;			\
+elif test -f "$$f"; then dir=;				\
+else dir="$(srcdir)/"; fi;				\
+tst=$$dir$$f; log='$@'; 				\
+if test -n '$(DISABLE_HARD_ERRORS)'; then		\
+  am__enable_hard_errors=no; 				\
+else							\
+  am__enable_hard_errors=yes; 				\
+fi; 							\
+case " $(XFAIL_TESTS) " in				\
+  *[\ \	]$$f[\ \	]* | *[\ \	]$$dir$$f[\ \	]*) \
+    am__expect_failure=yes;;				\
+  *)							\
+    am__expect_failure=no;;				\
+esac; 							\
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed).  The result is saved in the shell variable
+# '$bases'.  This honors runtime overriding of TESTS and TEST_LOGS.  Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+  bases='$(TEST_LOGS)'; \
+  bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+  bases=`echo $$bases`
+RECHECK_LOGS = $(TEST_LOGS)
+AM_RECURSIVE_TARGETS = check recheck
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+  case '$@' in \
+    */*) \
+      case '$*' in \
+        */*) b='$*';; \
+          *) b=`echo '$@' | sed 's/\.log$$//'`; \
+       esac;; \
+    *) \
+      b='$*';; \
+  esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT at .log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+	$(TEST_LOG_FLAGS)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BUILTIN_LIBS = @BUILTIN_LIBS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CDDGMPCPPFLAGS = @CDDGMPCPPFLAGS@
+CDDGMPLDFLAGS = @CDDGMPLDFLAGS@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATA_DIR = @DATA_DIR@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DOC_DIR = @DOC_DIR@
+DOXYGEN = @DOXYGEN@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FACTORY_INCLUDES = @FACTORY_INCLUDES@
+FACTORY_LIBS = @FACTORY_LIBS@
+FGREP = @FGREP@
+FLINT_CFLAGS = @FLINT_CFLAGS@
+FLINT_HOME = @FLINT_HOME@
+FLINT_LIBS = @FLINT_LIBS@
+GMP_CFLAGS = @GMP_CFLAGS@
+GMP_HOME = @GMP_HOME@
+GMP_LIBS = @GMP_LIBS@
+GMP_VERSION = @GMP_VERSION@
+GREP = @GREP@
+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@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NTL_CFLAGS = @NTL_CFLAGS@
+NTL_LIBS = @NTL_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OMALLOC_INCLUDES = @OMALLOC_INCLUDES@
+OMALLOC_LIBS = @OMALLOC_LIBS@
+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@
+PKG_REQUIRE = @PKG_REQUIRE@
+PMCONFIG = @PMCONFIG@
+PM_CFLAGS = @PM_CFLAGS@
+PM_INC = @PM_INC@
+PM_LDFLAGS = @PM_LDFLAGS@
+PM_LIBS = @PM_LIBS@
+POLYMAKE_CXXFLAGS = @POLYMAKE_CXXFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LDFLAGS = @PTHREAD_LDFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
+PYTHON = @PYTHON@
+PYTHON_CSPEC = @PYTHON_CSPEC@
+PYTHON_EXECPREFIX = @PYTHON_EXECPREFIX@
+PYTHON_LSPEC = @PYTHON_LSPEC@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+RANLIB = @RANLIB@
+RESOURCES_INCLUDES = @RESOURCES_INCLUDES@
+RESOURCES_LIBS = @RESOURCES_LIBS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SINGULAR_CFLAGS = @SINGULAR_CFLAGS@
+SI_COUNTEDREF_AUTOLOAD = @SI_COUNTEDREF_AUTOLOAD@
+SI_CPU_I386 = @SI_CPU_I386@
+SI_CPU_IA64 = @SI_CPU_IA64@
+SI_CPU_PPC = @SI_CPU_PPC@
+SI_CPU_SPARC = @SI_CPU_SPARC@
+SI_CPU_X86_64 = @SI_CPU_X86_64@
+STRIP = @STRIP@
+USEPPROCSDYNAMICLD = @USEPPROCSDYNAMICLD@
+USEPPROCSDYNAMICLDFLAGS = @USEPPROCSDYNAMICLDFLAGS@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
+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@
+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@
+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@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+ACLOCAL_AMFLAGS = -I ../../m4
+AM_CPPFLAGS = -I${top_srcdir} -I${top_builddir} -I${top_srcdir}/libpolys -I${top_builddir}/libpolys \
+${FACTORY_INCLUDES} $(OMALLOC_INCLUDES) $(RESOURCES_INCLUDES) \
+${NTL_CFLAGS} $(FLINT_CFLAGS) ${GMP_CFLAGS}
+
+noinst_LTLIBRARIES = liboswrapper.la
+liboswrapper_la_SOURCES = feread.cc fereadl.c timer.cc rlimit.c
+liboswrapper_la_includedir = $(includedir)/singular/kernel/oswrapper
+liboswrapper_la_include_HEADERS = feread.h timer.h rlimit.h
+TESTS_ENVIRONMENT = SINGULARPATH='${abs_top_builddir}/libpolys/polys/.libs:${abs_top_builddir}/factory/gftables' \
+	SINGULAR_ROOT_DIR='${abs_top_builddir}'
+test_SOURCES = test.cc
+test_LDADD = liboswrapper.la ${builddir}/../libkernelCommon.la
+CLEANFILES = $(TESTS)
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .cc .lo .log .o .obj .test .test$(EXEEXT) .trs
+$(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) --foreign kernel/oswrapper/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign kernel/oswrapper/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-noinstLTLIBRARIES:
+	-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+	@list='$(noinst_LTLIBRARIES)'; \
+	locs=`for p in $$list; do echo $$p; done | \
+	      sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+	      sort -u`; \
+	test -z "$$locs" || { \
+	  echo rm -f $${locs}; \
+	  rm -f $${locs}; \
+	}
+
+liboswrapper.la: $(liboswrapper_la_OBJECTS) $(liboswrapper_la_DEPENDENCIES) $(EXTRA_liboswrapper_la_DEPENDENCIES) 
+	$(AM_V_CXXLD)$(CXXLINK)  $(liboswrapper_la_OBJECTS) $(liboswrapper_la_LIBADD) $(LIBS)
+
+clean-checkPROGRAMS:
+	@list='$(check_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
+
+test$(EXEEXT): $(test_OBJECTS) $(test_DEPENDENCIES) $(EXTRA_test_DEPENDENCIES) 
+	@rm -f test$(EXEEXT)
+	$(AM_V_CXXLD)$(CXXLINK) $(test_OBJECTS) $(test_LDADD) $(LIBS)
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/feread.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/fereadl.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/rlimit.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/test.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/timer.Plo at am__quote@
+
+.c.o:
+ at am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+ at am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+ at am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+ at am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+ at am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+ at am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+ at am__fastdepCC_TRUE@	$(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+.cc.o:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+ at am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXXCOMPILE) -c -o $@ $<
+
+.cc.obj:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+ at am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.cc.lo:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+ at am__fastdepCXX_TRUE@	$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LTCXXCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+install-liboswrapper_la_includeHEADERS: $(liboswrapper_la_include_HEADERS)
+	@$(NORMAL_INSTALL)
+	@list='$(liboswrapper_la_include_HEADERS)'; test -n "$(liboswrapper_la_includedir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(liboswrapper_la_includedir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(liboswrapper_la_includedir)" || exit 1; \
+	fi; \
+	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)$(liboswrapper_la_includedir)'"; \
+	  $(INSTALL_HEADER) $$files "$(DESTDIR)$(liboswrapper_la_includedir)" || exit $$?; \
+	done
+
+uninstall-liboswrapper_la_includeHEADERS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(liboswrapper_la_include_HEADERS)'; test -n "$(liboswrapper_la_includedir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	dir='$(DESTDIR)$(liboswrapper_la_includedir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	$(am__define_uniq_tagged_files); \
+	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-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	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"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'.  Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+	rm -f $< $@
+	$(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+	@:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+	@$(am__set_TESTS_bases); \
+	am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+	redo_bases=`for i in $$bases; do \
+	              am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+	            done`; \
+	if test -n "$$redo_bases"; then \
+	  redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+	  redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+	  if $(am__make_dryrun); then :; else \
+	    rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+	  fi; \
+	fi; \
+	if test -n "$$am__remaking_logs"; then \
+	  echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+	       "recursion detected" >&2; \
+	else \
+	  am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+	fi; \
+	if $(am__make_dryrun); then :; else \
+	  st=0;  \
+	  errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+	  for i in $$redo_bases; do \
+	    test -f $$i.trs && test -r $$i.trs \
+	      || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+	    test -f $$i.log && test -r $$i.log \
+	      || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+	  done; \
+	  test $$st -eq 0 || exit 1; \
+	fi
+	@$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+	ws='[ 	]'; \
+	results=`for b in $$bases; do echo $$b.trs; done`; \
+	test -n "$$results" || results=/dev/null; \
+	all=`  grep "^$$ws*:test-result:"           $$results | wc -l`; \
+	pass=` grep "^$$ws*:test-result:$$ws*PASS"  $$results | wc -l`; \
+	fail=` grep "^$$ws*:test-result:$$ws*FAIL"  $$results | wc -l`; \
+	skip=` grep "^$$ws*:test-result:$$ws*SKIP"  $$results | wc -l`; \
+	xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+	xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+	error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+	if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+	  success=true; \
+	else \
+	  success=false; \
+	fi; \
+	br='==================='; br=$$br$$br$$br$$br; \
+	result_count () \
+	{ \
+	    if test x"$$1" = x"--maybe-color"; then \
+	      maybe_colorize=yes; \
+	    elif test x"$$1" = x"--no-color"; then \
+	      maybe_colorize=no; \
+	    else \
+	      echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+	    fi; \
+	    shift; \
+	    desc=$$1 count=$$2; \
+	    if test $$maybe_colorize = yes && test $$count -gt 0; then \
+	      color_start=$$3 color_end=$$std; \
+	    else \
+	      color_start= color_end=; \
+	    fi; \
+	    echo "$${color_start}# $$desc $$count$${color_end}"; \
+	}; \
+	create_testsuite_report () \
+	{ \
+	  result_count $$1 "TOTAL:" $$all   "$$brg"; \
+	  result_count $$1 "PASS: " $$pass  "$$grn"; \
+	  result_count $$1 "SKIP: " $$skip  "$$blu"; \
+	  result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+	  result_count $$1 "FAIL: " $$fail  "$$red"; \
+	  result_count $$1 "XPASS:" $$xpass "$$red"; \
+	  result_count $$1 "ERROR:" $$error "$$mgn"; \
+	}; \
+	{								\
+	  echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" |	\
+	    $(am__rst_title);						\
+	  create_testsuite_report --no-color;				\
+	  echo;								\
+	  echo ".. contents:: :depth: 2";				\
+	  echo;								\
+	  for b in $$bases; do echo $$b; done				\
+	    | $(am__create_global_log);					\
+	} >$(TEST_SUITE_LOG).tmp || exit 1;				\
+	mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG);			\
+	if $$success; then						\
+	  col="$$grn";							\
+	 else								\
+	  col="$$red";							\
+	  test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG);		\
+	fi;								\
+	echo "$${col}$$br$${std}"; 					\
+	echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}";	\
+	echo "$${col}$$br$${std}"; 					\
+	create_testsuite_report --maybe-color;				\
+	echo "$$col$$br$$std";						\
+	if $$success; then :; else					\
+	  echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}";		\
+	  if test -n "$(PACKAGE_BUGREPORT)"; then			\
+	    echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}";	\
+	  fi;								\
+	  echo "$$col$$br$$std";					\
+	fi;								\
+	$$success || exit 1
+
+check-TESTS:
+	@list='$(RECHECK_LOGS)';           test -z "$$list" || rm -f $$list
+	@list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+	@test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+	@set +e; $(am__set_TESTS_bases); \
+	log_list=`for i in $$bases; do echo $$i.log; done`; \
+	trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+	log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+	$(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+	exit $$?;
+recheck: all $(check_PROGRAMS)
+	@test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+	@set +e; $(am__set_TESTS_bases); \
+	bases=`for i in $$bases; do echo $$i; done \
+	         | $(am__list_recheck_tests)` || exit 1; \
+	log_list=`for i in $$bases; do echo $$i.log; done`; \
+	log_list=`echo $$log_list`; \
+	$(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+	        am__force_recheck=am--force-recheck \
+	        TEST_LOGS="$$log_list"; \
+	exit $$?
+test.log: test$(EXEEXT)
+	@p='test$(EXEEXT)'; \
+	b='test'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+.test.log:
+	@p='$<'; \
+	$(am__set_b); \
+	$(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+ at am__EXEEXT_TRUE@.test$(EXEEXT).log:
+ at am__EXEEXT_TRUE@	@p='$<'; \
+ at am__EXEEXT_TRUE@	$(am__set_b); \
+ at am__EXEEXT_TRUE@	$(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ at am__EXEEXT_TRUE@	--log-file $$b.log --trs-file $$b.trs \
+ at am__EXEEXT_TRUE@	$(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ at am__EXEEXT_TRUE@	"$$tst" $(AM_TESTS_FD_REDIRECT)
+
+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_PROGRAMS)
+	$(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(HEADERS)
+installdirs:
+	for dir in "$(DESTDIR)$(liboswrapper_la_includedir)"; 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:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+	-test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+	-test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+	-test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+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-checkPROGRAMS clean-generic clean-libtool \
+	clean-noinstLTLIBRARIES 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-liboswrapper_la_includeHEADERS
+
+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: uninstall-liboswrapper_la_includeHEADERS
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am clean \
+	clean-checkPROGRAMS clean-generic clean-libtool \
+	clean-noinstLTLIBRARIES cscopelist-am ctags ctags-am 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-liboswrapper_la_includeHEADERS 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 \
+	recheck tags tags-am uninstall uninstall-am \
+	uninstall-liboswrapper_la_includeHEADERS
+
+
+# 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/kernel/oswrapper/feread.cc b/kernel/oswrapper/feread.cc
new file mode 100644
index 0000000..edb555f
--- /dev/null
+++ b/kernel/oswrapper/feread.cc
@@ -0,0 +1,422 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: input from ttys, simulating fgets
+*/
+
+#include <kernel/mod2.h>
+
+// ----------------------------------------
+// system settings:
+
+#undef USE_READLINE4
+
+//----------------------------------------
+#ifdef __CYGWIN__
+#define READLINE_STATIC
+#endif
+#include <omalloc/omalloc.h>
+#include <misc/options.h>
+
+#include <kernel/oswrapper/feread.h>
+
+#ifdef HAVE_STATIC
+#undef HAVE_DYN_RL
+#endif
+
+#if defined(HAVE_DYN_RL)
+#include <unistd.h>
+#endif
+
+static char * fe_fgets_stdin_init(const char *pr,char *s, int size);
+char * (*fe_fgets_stdin)(const char *pr,char *s, int size)
+ = fe_fgets_stdin_init;
+
+extern char *iiArithGetCmd(int);
+
+/* ===================================================================*/
+/* =                   static/dymanic readline                      = */
+/* ===================================================================*/
+#if defined(HAVE_READLINE) || defined(HAVE_DYN_RL) || defined(HAVE_LIBREADLINE)
+
+#ifndef STDOUT_FILENO
+#define STDOUT_FILENO 1
+#endif
+
+/* Generator function for command completion.  STATE lets us know whether
+*   to start from scratch; without any state (i.e. STATE == 0), then we
+*   start at the top of the list.
+*/
+#include <Singular/ipid.h>
+extern "C"
+char *command_generator (char *text, int state)
+{
+  static int list_index, len;
+  static idhdl h;
+  const char *name;
+
+  /* If this is a new word to complete, initialize now.  This includes
+     saving the length of TEXT for efficiency, and initializing the index
+     variable to 0. */
+  if (state==0)
+  {
+    list_index = 1;
+    len = strlen (text);
+    h=basePack->idroot;
+  }
+
+  /* Return the next name which partially matches from the command list. */
+  while ((name = iiArithGetCmd(list_index))!=NULL)
+  {
+    list_index++;
+
+    if (strncmp (name, text, len) == 0)
+      return (strdup(name));
+  }
+  if (len>1)
+  {
+    while (h!=NULL)
+    {
+      name=h->id;
+      h=h->next;
+      if (strncmp (name, text, len) == 0)
+        return (strdup(name));
+    }
+  }
+  /* If no names matched, then return NULL. */
+  return ((char *)NULL);
+}
+#endif
+
+/* ===================================================================*/
+/* =                      static readline                           = */
+/* ===================================================================*/
+/* some procedure are shared with "dynamic readline" */
+#if (defined(HAVE_READLINE) || defined(HAVE_LIBREADLINE) || defined(HAVE_DYN_RL))
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/file.h>
+#include <sys/stat.h>
+#include <sys/errno.h>
+
+// #undef READLINE_READLINE_H_OK
+
+extern "C" {
+  typedef char * (*RL_PROC)(const char*,int);
+  #ifdef READLINE_READLINE_H_OK
+    #include <readline/readline.h>
+    #ifdef HAVE_READLINE_HISTORY_H
+      #include <readline/history.h>
+    #endif
+  #endif
+
+  #ifdef RL_VERSION_MAJOR
+    #if (RL_VERSION_MAJOR >= 4)
+      #define USE_READLINE4
+    #endif
+  #endif
+
+  #ifndef USE_READLINE4
+    #define rl_filename_completion_function filename_completion_function
+    #define rl_completion_matches           completion_matches
+  #endif
+  #ifndef READLINE_READLINE_H_OK
+    /* declare everything we need explicitely and do not rely on includes */
+    extern char * rl_readline_name;
+    extern char *rl_line_buffer;
+    char *rl_filename_completion_function(const char*, int);
+    typedef char **CPPFunction ();
+
+    extern char ** rl_completion_matches (const char*, RL_PROC);
+    extern CPPFunction * rl_attempted_completion_function;
+    extern FILE * rl_outstream;
+    extern char * readline (const char *);
+    extern void add_history (char *);
+    extern int write_history ();
+    extern void using_history();
+    extern int read_history(char *);
+    extern int history_total_bytes();
+  #endif /* READLINE_READLINE_H_OK */
+
+  typedef char * (*PROC)();
+
+  typedef char **RL_CPPFunction (const char*, int,int);
+}
+
+
+char * fe_fgets_stdin_rl(const char *pr,char *s, int size);
+
+/* Tell the GNU Readline library how to complete.  We want to try to complete
+   on command names  or on filenames if it is preceded by " */
+
+/* Attempt to complete on the contents of TEXT.  START and END show the
+*   region of TEXT that contains the word to complete.  We can use the
+*   entire line in case we want to do some simple parsing.  Return the
+*   array of matches, or NULL if there aren't any.
+*/
+#if defined(HAVE_DYN_RL)
+extern "C"
+{
+  int fe_init_dyn_rl();
+  char *(*fe_filename_completion_function)(); /* 3 */
+  char *(* fe_readline) (char *);             /* 4 */
+  void (*fe_add_history) (char *);            /* 5 */
+  char ** fe_rl_readline_name;                /* 6 */
+  char **fe_rl_line_buffer;                   /* 7 */
+  char **(*fe_completion_matches)(...);          /* 8 */
+  CPPFunction **fe_rl_attempted_completion_function; /* 9 */
+  FILE ** fe_rl_outstream;                    /* 10 */
+  int (*fe_write_history) ();                 /* 11 */
+  int (*fe_history_total_bytes) ();           /* 12 */
+  void (*fe_using_history) ();                /* 13 */
+  int (*fe_read_history) (char *);            /* 14 */
+
+}
+#endif
+char ** singular_completion (char *text, int start, int end)
+{
+  /* If this word is not in a string, then it may be a command
+     to complete.  Otherwise it may be the name of a file in the current
+     directory. */
+#ifdef HAVE_DYN_RL
+  #define x_rl_line_buffer (*fe_rl_line_buffer)
+  #define x_rl_completion_matches (*fe_completion_matches)
+  #define x_rl_filename_completion_function (*fe_filename_completion_function)
+#else
+  #define x_rl_line_buffer rl_line_buffer
+  #define x_rl_completion_matches rl_completion_matches
+  #define x_rl_filename_completion_function rl_filename_completion_function
+#endif
+  if ((start>0) && (x_rl_line_buffer[start-1]=='"'))
+    return x_rl_completion_matches (text, (RL_PROC)x_rl_filename_completion_function);
+  char **m=x_rl_completion_matches (text, (RL_PROC)command_generator);
+#undef x_rl_line_buffer
+#undef x_rl_completion_matches
+  if (m==NULL)
+  {
+    m=(char **)malloc(2*sizeof(char*));
+    m[0]=(char *)malloc(end-start+2);
+    strncpy(m[0],text,end-start+1);
+    m[1]=NULL;
+  }
+  return m;
+}
+
+#ifndef HAVE_DYN_RL
+char * fe_fgets_stdin_rl(const char *pr,char *s, int size)
+{
+  if (!BVERBOSE(V_PROMPT))
+  {
+    pr="";
+  }
+  mflush();
+
+  char *line;
+  line = readline (pr);
+
+  if (line==NULL)
+    return NULL;
+
+  int l=strlen(line);
+  for (int i=l-1;i>=0;i--) line[i]=line[i]&127;
+
+  if (*line!='\0')
+  {
+    add_history (line);
+  }
+  if (l>=size-1)
+  {
+    strncpy(s,line,size);
+  }
+  else
+  {
+    strncpy(s,line,l);
+    s[l]='\n';
+    s[l+1]='\0';
+  }
+  free (line);
+
+  return s;
+}
+#endif
+#endif
+
+/* ===================================================================*/
+/* =                    emulated readline                           = */
+/* ===================================================================*/
+#if !defined(HAVE_READLINE) && defined(HAVE_FEREAD)
+extern "C" {
+char * fe_fgets_stdin_fe(const char *pr,char *s, int size);
+}
+char * fe_fgets_stdin_emu(const char *pr,char *s, int size)
+{
+  if (!BVERBOSE(V_PROMPT))
+  {
+    pr="";
+  }
+  mflush();
+  return fe_fgets_stdin_fe(pr,s,size);
+}
+#endif
+
+/* ===================================================================*/
+/* =                     dynamic readline                           = */
+/* ===================================================================*/
+/* some procedure are shared with "static readline" */
+#if defined(HAVE_DYN_RL)
+char * fe_fgets_stdin_drl(const char *pr,char *s, int size)
+{
+  if (!BVERBOSE(V_PROMPT))
+  {
+    pr="";
+  }
+  mflush();
+
+  char *line;
+  line = (*fe_readline) ((char*)pr);
+
+  if (line==NULL)
+    return NULL;
+
+  int l=strlen(line);
+  for (int i=l-1;i>=0;i--) line[i]=line[i]&127;
+
+  if (*line!='\0')
+  {
+    (*fe_add_history) (line);
+  }
+  if (l>=size-1)
+  {
+    strncpy(s,line,size);
+  }
+  else
+  {
+    strncpy(s,line,l);
+    s[l]='\n';
+    s[l+1]='\0';
+  }
+  free (line);
+
+  return s;
+}
+#endif
+
+/* ===================================================================*/
+/* =                        fgets                                   = */
+/* ===================================================================*/
+char * fe_fgets(const char *pr,char *s, int size)
+{
+  if (BVERBOSE(V_PROMPT))
+  {
+    fprintf(stdout,"%s",pr);
+  }
+  mflush();
+  char *line=fgets(s,size,stdin);
+  if (line!=NULL)
+    for (int i=strlen(line)-1;i>=0;i--) line[i]=line[i]&127;
+  return line;
+}
+
+/* ===================================================================*/
+/* =       init for static rl, dyn. rl, emu. rl                     = */
+/* ===================================================================*/
+static char * fe_fgets_stdin_init(const char *pr,char *s, int size)
+{
+#if (defined(HAVE_READLINE) || defined(HAVE_LIBREADLINE)) && !defined(HAVE_DYN_RL) && !defined(HAVE_FEREAD)
+  /* Allow conditional parsing of the ~/.inputrc file. */
+  rl_readline_name = "Singular";
+  /* Tell the completer that we want a crack first. */
+#ifdef USE_READLINE4
+  rl_attempted_completion_function = (rl_completion_func_t *)singular_completion;
+#else
+  rl_attempted_completion_function = (CPPFunction *)singular_completion;
+#endif
+
+  /* set the output stream */
+  if(!isatty(STDOUT_FILENO))
+  {
+    #ifdef atarist
+      rl_outstream = fopen( "/dev/tty", "w" );
+    #else
+      rl_outstream = fopen( ttyname(fileno(stdin)), "w" );
+    #endif
+  }
+
+  /* try to read a history */
+  using_history();
+  char *p = getenv("SINGULARHIST");
+  if (p != NULL)
+  {
+    read_history (p);
+  }
+  fe_fgets_stdin=fe_fgets_stdin_rl;
+  return(fe_fgets_stdin_rl(pr,s,size));
+#endif
+#ifdef HAVE_DYN_RL
+  /* do dynamic loading */
+  int res=fe_init_dyn_rl();
+  if (res!=0)
+  {
+    //if (res==1)
+    //  WarnS("dynamic loading of libreadline failed");
+    //else
+    //  Warn("dynamic loading failed: %d\n",res);
+    if (res!=1)
+      Warn("dynamic loading failed: %d\n",res);
+    #ifdef HAVE_FEREAD
+    fe_fgets_stdin=fe_fgets_stdin_emu;
+    #else
+    fe_fgets_stdin=fe_fgets;
+    #endif
+    return fe_fgets_stdin(pr,s,size);
+  }
+  else /* could load libreadline: */
+  {
+    /* Allow conditional parsing of the ~/.inputrc file. */
+    *fe_rl_readline_name = "Singular";
+    /* Tell the completer that we want a crack first. */
+    *fe_rl_attempted_completion_function = (CPPFunction *)singular_completion;
+    /* try to read a history */
+    (*fe_using_history)();
+    char *p = getenv("SINGULARHIST");
+    if (p != NULL)
+    {
+      (*fe_read_history) (p);
+    }
+  }
+
+  /* set the output stream */
+  if(!isatty(STDOUT_FILENO))
+  {
+    #ifdef atarist
+      *fe_rl_outstream = fopen( "/dev/tty", "w" );
+    #else
+      *fe_rl_outstream = fopen( ttyname(fileno(stdin)), "w" );
+    #endif
+  }
+
+  fe_fgets_stdin=fe_fgets_stdin_drl;
+  return fe_fgets_stdin_drl(pr,s,size);
+#else
+  #if !defined(HAVE_READLINE) && defined(HAVE_FEREAD)
+    fe_fgets_stdin=fe_fgets_stdin_emu;
+    return(fe_fgets_stdin_emu(pr,s,size));
+  #else
+    fe_fgets_stdin=fe_fgets;
+    return(fe_fgets(pr,s,size));
+  #endif
+#endif
+}
+
+/* ===================================================================*/
+/* =                      batch mode                                = */
+/* ===================================================================*/
+/* dummy (for batch mode): */
+char * fe_fgets_dummy(const char */*pr*/,char */*s*/, int /*size*/)
+{
+  return NULL;
+}
+
diff --git a/kernel/oswrapper/feread.h b/kernel/oswrapper/feread.h
new file mode 100644
index 0000000..cc0ce95
--- /dev/null
+++ b/kernel/oswrapper/feread.h
@@ -0,0 +1,53 @@
+#ifndef FEREAD_H
+#define FEREAD_H
+/****************************************
+ * *  Computer Algebra System SINGULAR     *
+ * ****************************************/
+/*
+ * ABSTRACT: terminal input
+ */
+
+#include <kernel/structs.h>
+
+extern char    prompt_char; /*1 either '>' or '.'*/
+
+#ifdef __cplusplus
+
+/* the interface for reading: */
+extern "C"  char * (*fe_fgets_stdin)(const char *pr,char *s, int size);
+
+#ifdef HAVE_DYN_RL
+char * fe_fgets_stdin_drl(const char *pr,char *s, int size);
+#endif
+
+extern "C" void fe_reset_input_mode();
+
+extern "C" {
+#ifndef HAVE_ATEXIT
+void fe_reset_fe (int i, void *v);
+#else
+void fe_reset_fe (void);
+#endif
+}
+
+/* possible implementations: */
+extern "C"
+{
+  /* readline, linked in: */
+  char * fe_fgets_stdin_rl(const char *pr,char *s, int size);
+
+  /* emulated readline: */
+  char * fe_fgets_stdin_emu(const char *pr,char *s, int size);
+
+  /* fgets: */
+  char * fe_fgets(const char *pr,char *s, int size);
+
+  /* dummy (for batch mode): */
+  char * fe_fgets_dummy(const char *pr,char *s, int size);
+
+}
+const char *  eati(const char *s, int *i);
+
+#endif
+#endif
+
diff --git a/kernel/oswrapper/fereadl.c b/kernel/oswrapper/fereadl.c
new file mode 100644
index 0000000..bfc4d32
--- /dev/null
+++ b/kernel/oswrapper/fereadl.c
@@ -0,0 +1,852 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: input from ttys, simulating fgets
+*/
+
+
+
+
+
+#include <kernel/mod2.h>
+#include <omalloc/omalloc.h>
+
+// #include <kernel/structs.h>
+
+
+#ifdef HAVE_FEREAD
+  #include <unistd.h>
+  #include <stdio.h>
+  #include <stdlib.h>
+  #include <sys/time.h>
+  #include <sys/types.h>
+  #include <string.h>
+
+  #if 0
+    #include <pc.h>
+  #else
+    #ifdef SunOS_5
+      /* solaris special, found with v 5.7 */
+      #define _XOPEN_SOURCE_EXTENDED
+      #include "/usr/xpg4/include/term.h"
+    #endif
+    #if 0
+      #ifndef SunOS_5
+        #include <term.h>
+      #endif
+    #elif HAVE_TERMCAP_H
+      #ifndef SunOS_5
+      #include <termcap.h>
+      #endif
+    #endif
+    #if defined(HAVE_TERMIOS_H) && ! defined(TCSANOW)
+      #include <termios.h>
+    #endif
+    #if defined(HAVE_TERM_H) && ! defined(TCSANOW)
+      #include <term.h>
+    #endif
+
+  #endif
+
+
+#ifndef STDIN_FILENO
+  #define STDIN_FILENO 0
+#endif
+#ifndef STDOUT_FILENO
+  #define STDOUT_FILENO 1
+#endif
+
+#define feCTRL(C) ((C) & 0x1F)    /* <ctrl> character  */
+
+struct termios fe_saved_attributes;
+
+static BOOLEAN fe_stdout_is_tty;
+static BOOLEAN fe_stdin_is_tty;
+BOOLEAN fe_use_fgets=FALSE;
+static BOOLEAN fe_is_initialized=FALSE;
+static int     pagelength = 24;
+
+FILE *  fe_echo; /*the output file for echoed characters*/
+
+#define fe_hist_max 32
+char ** fe_hist=NULL;
+short   fe_hist_pos;
+BOOLEAN fe_is_raw_tty=0;
+int     fe_cursor_pos; /* 0..colmax-1*/
+int     fe_cursor_line; /* 0..pagelength-1*/
+
+#ifndef HAVE_ATEXIT
+  int on_exit(void (*f)(int, void *), void *arg);
+  #ifdef HAVE_FEREAD
+    void fe_reset_fe (int i, void *v)
+  #endif
+#else
+  #ifdef HAVE_FEREAD
+    void fe_reset_fe (void)
+  #endif
+#endif
+{
+  if (fe_stdin_is_tty)
+  {
+    int i;
+    if (fe_is_raw_tty)
+    {
+      tcsetattr (STDIN_FILENO, TCSANOW, &fe_saved_attributes);
+      fe_is_raw_tty=0;
+    }
+    if (fe_hist!=NULL)
+    {
+      for(i=fe_hist_max-1;i>=0;i--)
+      {
+        if (fe_hist[i] != NULL) omFree((ADDRESS)fe_hist[i]);
+      }
+      omFreeSize((ADDRESS)fe_hist,fe_hist_max*sizeof(char *));
+      fe_hist=NULL;
+    }
+    if (!fe_stdout_is_tty)
+    {
+      fclose(fe_echo);
+    }
+  }
+}
+void fe_temp_reset (void)
+{
+  if (fe_is_raw_tty)
+  {
+    tcsetattr (STDIN_FILENO, TCSANOW, &fe_saved_attributes);
+    fe_is_raw_tty=0;
+  }
+}
+void fe_temp_set (void)
+{
+  if(fe_is_raw_tty==0)
+  {
+    struct termios tattr;
+
+    /* Set the funny terminal modes. */
+    tcgetattr (STDIN_FILENO, &tattr);
+    tattr.c_lflag &= ~(ICANON|ECHO); /* Clear ICANON and ECHO. */
+    tattr.c_cc[VMIN] = 1;
+    tattr.c_cc[VTIME] = 0;
+    tcsetattr (STDIN_FILENO, TCSAFLUSH, &tattr);
+    fe_is_raw_tty=1;
+  }
+}
+
+static char termcap_buff[2048];
+static int fe_out_char(int c)
+{
+  fputc(c,fe_echo);
+  return c;
+}
+void fe_init (void)
+{
+  fe_is_initialized=TRUE;
+  if ((!fe_use_fgets) && (isatty (STDIN_FILENO)))
+  {
+    /* Make sure stdin is a terminal. */
+    char *term=getenv("TERM");
+
+    /*setup echo*/
+    if(isatty(STDOUT_FILENO))
+    {
+      fe_stdout_is_tty=1;
+      fe_echo=stdout;
+    }
+    else
+    {
+      fe_stdout_is_tty=0;
+      fe_echo = fopen( ttyname(fileno(stdin)), "w" );
+    }
+    /* Save the terminal attributes so we can restore them later. */
+    {
+      struct termios tattr;
+      tcgetattr (STDIN_FILENO, &fe_saved_attributes);
+      #ifdef HAVE_FEREAD
+        #ifdef HAVE_ATEXIT
+          atexit(fe_reset_fe);
+        #else
+          on_exit(fe_reset_fe,NULL);
+        #endif
+      #endif
+
+      /* Set the funny terminal modes. */
+      tcgetattr (STDIN_FILENO, &tattr);
+      tattr.c_lflag &= ~(ICANON|ECHO); /* Clear ICANON and ECHO. */
+      tattr.c_cc[VMIN] = 1;
+      tattr.c_cc[VTIME] = 0;
+      tcsetattr (STDIN_FILENO, TCSAFLUSH, &tattr);
+      /*ospeed=cfgetospeed(&tattr);*/
+    }
+    if(term==NULL)
+    {
+      printf("need TERM\n");
+    }
+    else if(tgetent(termcap_buff,term)<=0)
+    {
+      printf("could not access termcap data base\n");
+    }
+    else
+    {
+      #ifndef __CYGWIN__
+      extern char *BC;
+      extern char *UP;
+      extern char PC;
+      #endif
+      /* OB: why this ? HS: char t_buf[128] does not work with glibc2 systems */
+      char *t_buf=(char *)omAlloc(128);
+      /*char t_buf[128];*/
+      char *temp;
+      char** t_buf_ptr= &t_buf;
+      /* Extract information that termcap functions use.  */
+      temp = tgetstr ("pc", t_buf_ptr);
+      PC = (temp!=NULL) ? *temp : '\0';
+      BC=tgetstr("le",t_buf_ptr);
+      UP=tgetstr("up",t_buf_ptr);
+
+      /* Extract information we will use */
+      colmax=tgetnum("co");
+      pagelength=tgetnum("li");
+      fe_cursor_line=pagelength-1;
+
+      /* init screen */
+      temp = tgetstr ("ti", t_buf_ptr);
+      #if 0
+      if (temp!=NULL) tputs(temp,1,fe_out_char);
+      #endif
+
+      /* printf("TERM=%s, co=%d, li=%d\n",term,colmax,pagelength);*/
+    }
+
+    fe_stdin_is_tty=1;
+    fe_is_raw_tty=1;
+
+    /* setup history */
+    fe_hist=(char **)omAlloc0(fe_hist_max*sizeof(char *));
+    omMarkAsStaticAddr(fe_hist);
+    fe_hist_pos=0;
+  }
+  else
+  {
+    fe_stdin_is_tty=0;
+    fe_echo=stdout;
+  }
+}
+
+/* delete to end of line */
+static void fe_ctrl_k(char *s,int i)
+{
+  int j=i;
+  while(s[j]!='\0')
+  {
+    fputc(' ',fe_echo);
+    j++;
+  }
+  while(j>i)
+  {
+    fputc('\b',fe_echo);
+    j--;
+  }
+}
+
+/* delete the line */
+static void fe_ctrl_u(char *s,int *i)
+{
+  fe_ctrl_k(s,*i);
+  while((*i)>0)
+  {
+    (*i)--;
+    fputc('\b',fe_echo);
+    fputc(' ',fe_echo);
+    fputc('\b',fe_echo);
+  }
+}
+
+/*2
+* add s to the history
+* if s is no the previous one, duplicate it
+*/
+static void fe_add_hist(char *s)
+{
+  if (s[0]!='\0') /* skip empty lines */
+  {
+    /* compare this line*/
+    if (fe_hist_pos!=0)
+    {
+      if ((fe_hist[fe_hist_pos-1]!=NULL)
+      && (strcmp(fe_hist[fe_hist_pos-1],s)==0))
+        return;
+    }
+    else
+    {
+      if ((fe_hist[fe_hist_max-1]!=NULL)
+      && (strcmp(fe_hist[fe_hist_max-1],s)==0))
+        return;
+    }
+    /* normal case: enter a new line */
+    /* first free the slot at position fe_hist_pos */
+    if (fe_hist[fe_hist_pos]!=NULL)
+    {
+      omFree((ADDRESS)fe_hist[fe_hist_pos]);
+    }
+    /* and store a duplicate */
+    fe_hist[fe_hist_pos]=omStrDup(s);
+    omMarkAsStaticAddr(fe_hist[fe_hist_pos]);
+    /* increment fe_hist_pos in a circular manner */
+    fe_hist_pos++;
+    if (fe_hist_pos==fe_hist_max) fe_hist_pos=0;
+  }
+}
+
+static void fe_get_hist(char *s, int size, int *pos,int change, int incr)
+{
+  if (change)
+    fe_add_hist(s);
+  do
+  {
+    (*pos)+=incr;
+    if((*pos)>=fe_hist_max) (*pos)-=fe_hist_max;
+    else if((*pos)<0)       (*pos)+=fe_hist_max;
+  }
+  while (((*pos)!=0)&&(fe_hist[(*pos)]==NULL));
+  memset(s,0,size);
+  if (fe_hist[(*pos)]!=NULL)
+  {
+    strncpy(s,fe_hist[(*pos)],size-2);
+  }
+}
+
+static int fe_getchar()
+{
+  char c='\0';
+  while (1!=read (STDIN_FILENO, &c, 1));
+  if (c == 033)
+  {
+    /* check for CSI */
+    c='\0';
+    while((-1 == read (STDIN_FILENO, &c, 1)) && (errno == EINTR));
+    if (c == '[')
+    {
+      /* get command character */
+      c='\0';
+      while((-1 == read (STDIN_FILENO, &c, 1)) && (errno == EINTR));
+      switch (c)
+      {
+        case 'D': /* left arrow key */
+          c = feCTRL('B')/*002*/;
+          break;
+        case 'C': /* right arrow key */
+          c = feCTRL('F')/*006*/;
+          break;
+        case 'A': /* up arrow key */
+          c = feCTRL('P')/*020*/;
+          break;
+        case 'B': /* down arrow key */
+          c = feCTRL('N')/*016*/;
+          break;
+      }
+    }
+  }
+  return c;
+}
+
+static void fe_set_cursor(char *s,int i)
+{
+  char tgoto_buf[40];
+  if (0)/*(fe_cursor_pos>1) && (i>0))*/
+  {
+    /*fputs(tgoto(tgetstr("cm",&tgoto_buf),fe_cursor_pos-1,fe_cursor_line),fe_echo);*/
+    tputs(
+      tgoto(tgetstr("cm",(char **)&tgoto_buf),fe_cursor_pos-1,fe_cursor_line),
+      pagelength,fe_out_char);
+    fputc(s[i-1],fe_echo);
+  }
+  else
+  {
+    /*fputs(
+      tgoto(tgetstr("cm",&tgoto_buf),fe_cursor_pos,fe_cursor_line),fe_echo);*/
+    tputs(tgoto(tgetstr("cm",(char **)&tgoto_buf),fe_cursor_pos,fe_cursor_line),
+      pagelength,fe_out_char);
+  }
+  fflush(fe_echo);
+}
+
+char * fe_fgets_stdin_fe(char *pr,char *s, int size)
+{
+  if(!fe_is_initialized)
+    fe_init();
+  if (fe_stdin_is_tty)
+  {
+    int h=fe_hist_pos;
+    int change=0;
+    char c;
+    int i=0;
+
+    if (fe_is_raw_tty==0)
+    {
+      fe_temp_set();
+    }
+
+    fputs(pr,fe_echo); fflush(fe_echo);
+    fe_cursor_pos=strlen(pr); /* prompt */
+
+    memset(s,0,size);
+
+    loop
+    {
+      c=fe_getchar();
+      switch(c)
+      {
+        case feCTRL('M'):
+        case feCTRL('J'):
+        {
+          fd_set fdset;
+          struct timeval tv;
+          int sel;
+
+          fe_add_hist(s);
+          i=strlen(s);
+          if (i<size-1) s[i]='\n';
+          fputc('\n',fe_echo);
+          fflush(fe_echo);
+
+          FD_ZERO (&fdset);
+          FD_SET(STDIN_FILENO, &fdset);
+          tv.tv_sec = 0;
+          tv.tv_usec = 0;
+          do
+          {
+            sel = select (STDIN_FILENO+1,
+#ifdef hpux
+                          (int *)fdset.fds_bits,
+#else
+                          &fdset,
+#endif
+                          NULL, NULL, &tv);
+          } while( (sel == -1) && (errno == EINTR) );
+          if (sel==0)
+            fe_temp_reset();
+          return s;
+        }
+        case feCTRL('H'):
+        case 127:       /*delete the character left of the cursor*/
+        {
+          if (i==0) break;
+          i--;
+          fe_cursor_pos--;
+          if(fe_cursor_pos<0)
+          {
+            fe_cursor_line--;
+            fe_cursor_pos=colmax-1;
+            fe_set_cursor(s,i);
+          }
+          else
+          {
+            fputc('\b',fe_echo);
+          }
+          /* NO BREAK : next: feCTRL('D') */
+        }
+        case feCTRL('D'):  /*delete the character under the cursor or eof*/
+        {
+          int j;
+          if ((i==0) &&(s[0]=='\0')) return NULL; /*eof*/
+          if (s[i]!='\0')
+          {
+            j=i;
+            while(s[j]!='\0')
+            {
+              s[j]=s[j+1];
+              fputc(s[j],fe_echo);
+              j++;
+            }
+            fputc(' ',fe_echo);
+            if (fe_cursor_pos+(j-i)>=colmax)
+            {
+              fe_set_cursor(s,i);
+            }
+            else
+            {
+              while(j>i)
+              {
+                fputc('\b',fe_echo);
+                j--;
+              }
+            }
+          }
+          change=1;
+          fflush(fe_echo);
+          break;
+        }
+        case feCTRL('A'):  /* move the cursor to the beginning of the line */
+        {
+          if (i>=colmax-strlen(pr))
+          {
+            while (i>=colmax-strlen(pr))
+            {
+              i-=colmax;
+              fe_cursor_line--;
+            }
+            i=0;
+            fe_cursor_pos=strlen(pr);
+            fe_set_cursor(s,i);
+          }
+          else
+          {
+            while(i>0)
+            {
+              i--;
+              fputc('\b',fe_echo);
+            }
+            fe_cursor_pos=strlen(pr);
+          }
+          break;
+        }
+        case feCTRL('E'): /* move the cursor to the end of the line */
+        {
+          while(s[i]!='\0')
+          {
+            fputc(s[i],fe_echo);
+            i++;
+            fe_cursor_pos++;
+            if(fe_cursor_pos>=colmax)
+            {
+              fe_cursor_pos=0;
+              if(fe_cursor_line!=(pagelength-1))
+                fe_cursor_line++;
+            }
+          }
+          break;
+        }
+        case feCTRL('B'): /* move the cursor backward one character */
+        {
+          if (i>0)
+          {
+            i--;
+            fputc('\b',fe_echo);
+            fe_cursor_pos--;
+            if(fe_cursor_pos<0)
+            {
+              fe_cursor_pos=colmax-1;
+              fe_cursor_line--;
+            }
+          }
+          break;
+        }
+        case feCTRL('F'): /* move the cursor forward  one character */
+        {
+          if(s[i]!='\0')
+          {
+            fputc(s[i],fe_echo);
+            i++;
+            fe_cursor_pos++;
+            if(fe_cursor_pos>=colmax)
+            {
+              fe_cursor_pos=0;
+              if(fe_cursor_line!=(pagelength-1))
+                fe_cursor_line++;
+            }
+          }
+          break;
+        }
+        case feCTRL('U'): /* delete entire input line */
+        {
+          fe_ctrl_u(s,&i);
+          fe_cursor_pos=strlen(pr);
+          memset(s,0,size);
+          change=1;
+          break;
+        }
+        #if 0
+        case feCTRL('W'): /* test hist. */
+        {
+          int i;
+          PrintS("\nstart hist\n");
+          for(i=0;i<fe_hist_max;i++)
+          {
+            if(fe_hist[i]!=NULL)
+            {
+              Print("%2d ",i);
+              if(i==fe_hist_pos) PrintS("-"); else PrintS(" ");
+              if(i==h) PrintS(">"); else PrintS(" ");
+              PrintS(fe_hist[i]);
+              PrintLn();
+            }
+          }
+          Print("end hist, next_pos=%d\n",fe_hist_pos);
+          break;
+        }
+        #endif
+        case feCTRL('K'): /* delete up to the end of the line */
+        {
+          fe_ctrl_k(s,i);
+          memset(&(s[i]),'\0',size-i);
+          /* s[i]='\0';*/
+          change=1;
+          break;
+        }
+        case feCTRL('L'): /* redraw screen */
+        {
+          char t_buf[40];
+          char *t=t_buf;
+          fe_cursor_line=i/colmax;
+          /*fputs(tgetstr("cl",&t),fe_echo);*/
+          tputs(tgetstr("cl",&t),pagelength,fe_out_char);
+          fflush(fe_echo);
+          fputs(pr,fe_echo);
+          fputs(s,fe_echo);
+          fe_set_cursor(s,i);
+          break;
+        }
+        case feCTRL('P'): /* previous line */
+        {
+          fe_ctrl_u(s,&i);
+          fe_get_hist(s,size,&h,change,-1);
+          while(s[i]!='\0')
+          {
+            fputc(s[i],fe_echo);
+            i++;
+          }
+          fe_cursor_pos=strlen(pr)+i/*strlen(s)*/;
+          change=0;
+          break;
+        }
+        case feCTRL('N'): /* next line */
+        {
+          fe_ctrl_u(s,&i);
+          fe_get_hist(s,size,&h,change,1);
+          while(s[i]!='\0')
+          {
+            fputc(s[i],fe_echo);
+            i++;
+          }
+          fe_cursor_pos=strlen(pr)+i/*strlen(s)*/;
+          change=0;
+          break;
+        }
+        default:
+        {
+          if ((c>=' ')&&(c<=126))
+          {
+            fputc (c,fe_echo);
+            fe_cursor_pos++;
+            if(fe_cursor_pos>=colmax)
+            {
+              fe_cursor_pos=0;
+              if(fe_cursor_line!=(pagelength-1))
+                fe_cursor_line++;
+            }
+            if (s[i]!='\0')
+            {
+              /* shift by 1 to the right */
+              int j=i;
+              int l;
+              while ((s[j]!='\0')&&(j<size-2)) j++;
+              l=j-i;
+              while (j>i) { s[j]=s[j-1]; j--; }
+              /* display */
+              fwrite(s+i+1,l,1,fe_echo);
+              fflush(fe_echo);
+              /* set cursor */
+              if(fe_cursor_pos+l>=colmax)
+              {
+                while(fe_cursor_pos+l>=colmax)
+                {
+                  fe_cursor_line--;
+                  l-=colmax;
+                }
+                fe_set_cursor(s,i);
+              }
+              else
+              {
+                while(l>0)
+                {
+                  l--;
+                  fputc('\b',fe_echo);
+                }
+              }
+              fflush(fe_echo);
+            }
+            if (i<size-1) s[i]=c;
+            i++;
+            change=1;
+          }
+        }
+      } /* switch */
+      fflush(fe_echo);
+    } /* loop */
+  }
+  /*else*/
+    return fgets(s,size,stdin);
+}
+
+//int main (void)
+//{
+//  char b[200];
+//  char * m_eof;
+//
+//  fe_init();
+//  while(1)
+//  {
+//    m_eof=fe_fgets_stdin_fe("> ",b,200);
+//    if (!m_eof) break;
+//    printf(">>%s<<\n",b);
+//  }
+//
+//  return 0;
+//}
+#endif
+
+/* ================================================================ */
+#if defined(HAVE_DYN_RL)
+#include <unistd.h>
+//#include <stdio.h>
+//#include <stdlib.h>
+//#include <sys/types.h>
+//#include <sys/file.h>
+//#include <sys/stat.h>
+//#include <sys/errno.h>
+//#include <dlfcn.h>
+#include <kernel/mod_raw.h>
+
+  typedef char **CPPFunction ();
+
+  char *(*fe_filename_completion_function)(); /* 3 */
+  char *(* fe_readline) ();                   /* 4 */
+  void (*fe_add_history) ();                  /* 5 */
+  char ** fe_rl_readline_name;                /* 6 */
+  char **fe_rl_line_buffer;                   /* 7 */
+  char **(*fe_completion_matches)();          /* 8 */
+  CPPFunction **fe_rl_attempted_completion_function; /* 9 */
+  FILE ** fe_rl_outstream;                    /* 10 */
+  int (*fe_write_history) ();                 /* 11 */
+  int (*fe_history_total_bytes) ();           /* 12 */
+  void (*fe_using_history) ();                /* 13 */
+  int (*fe_read_history) ();                  /* 14 */
+
+void * fe_rl_hdl=NULL;
+
+char *command_generator (char *text, int state);
+
+/* Attempt to complete on the contents of TEXT.  START and END show the
+*   region of TEXT that contains the word to complete.  We can use the
+*   entire line in case we want to do some simple parsing.  Return the
+*   array of matches, or NULL if there aren't any.
+*/
+char ** singular_completion (char *text, int start, int end)
+{
+  /* If this word is not in a string, then it may be a command
+     to complete.  Otherwise it may be the name of a file in the current
+     directory. */
+  char **m;
+  if ((*fe_rl_line_buffer)[start-1]=='"')
+    return (*fe_completion_matches) (text, *fe_filename_completion_function);
+  m=(*fe_completion_matches) (text, command_generator);
+  if (m==NULL)
+  {
+    m=(char **)malloc(2*sizeof(char*));
+    m[0]=(char *)malloc(end-start+2);
+    strncpy(m[0],text,end-start+1);
+    m[1]=NULL;
+  }
+  return m;
+}
+
+
+int fe_init_dyn_rl()
+{
+  int res=0;
+  loop
+  {
+    fe_rl_hdl=dynl_open("libreadline.so");
+    if (fe_rl_hdl==NULL) fe_rl_hdl=dynl_open("libreadline.so.2");
+    if (fe_rl_hdl==NULL) fe_rl_hdl=dynl_open("libreadline.so.3");
+    if (fe_rl_hdl==NULL) fe_rl_hdl=dynl_open("libreadline.so.4");
+    if (fe_rl_hdl==NULL) fe_rl_hdl=dynl_open("libreadline.so.5");
+    if (fe_rl_hdl==NULL) fe_rl_hdl=dynl_open("libreadline.so.6");
+    if (fe_rl_hdl==NULL) fe_rl_hdl=dynl_open("libreadline.so.7");
+    if (fe_rl_hdl==NULL) { return 1;}
+
+    fe_filename_completion_function=
+      dynl_sym(fe_rl_hdl, "filename_completion_function");
+    if (fe_filename_completion_function==NULL) { res=3; break; }
+    fe_readline=dynl_sym(fe_rl_hdl,"readline");
+    if (fe_readline==NULL) { res=4; break; }
+    fe_add_history=dynl_sym(fe_rl_hdl,"add_history");
+    if (fe_add_history==NULL) { res=5; break; }
+    fe_rl_readline_name=(char**)dynl_sym(fe_rl_hdl,"rl_readline_name");
+    if (fe_rl_readline_name==NULL) { res=6; break; }
+    fe_rl_line_buffer=(char**)dynl_sym(fe_rl_hdl,"rl_line_buffer");
+    if (fe_rl_line_buffer==NULL) { res=7; break; }
+    fe_completion_matches=dynl_sym(fe_rl_hdl,"completion_matches");
+    if (fe_completion_matches==NULL) { res=8; break; }
+    fe_rl_attempted_completion_function=
+      dynl_sym(fe_rl_hdl,"rl_attempted_completion_function");
+    if (fe_rl_attempted_completion_function==NULL) { res=9; break; }
+    fe_rl_outstream=(FILE**)dynl_sym(fe_rl_hdl,"rl_outstream");
+    if (fe_rl_outstream==NULL) { res=10; break; }
+    fe_write_history=dynl_sym(fe_rl_hdl,"write_history");
+    if (fe_write_history==NULL) { res=11; break; }
+    fe_history_total_bytes=dynl_sym(fe_rl_hdl,"history_total_bytes");
+    if (fe_history_total_bytes==NULL) { res=12; break; }
+    fe_using_history=dynl_sym(fe_rl_hdl,"using_history");
+    if (fe_using_history==NULL) { res=13; break; }
+    fe_read_history=dynl_sym(fe_rl_hdl,"read_history");
+    if (fe_read_history==NULL) { res=14; break; }
+    return 0;
+  }
+  dynl_close(fe_rl_hdl);
+  if (res==0)
+  {
+    char *p;
+    /* more init stuff: */
+    /* Allow conditional parsing of the ~/.inputrc file. */
+    (*fe_rl_readline_name) = "Singular";
+    /* Tell the completer that we want a crack first. */
+    (*fe_rl_attempted_completion_function) = (CPPFunction *)singular_completion;
+    /* try to read a history */
+    (*fe_using_history)();
+    p = getenv("SINGULARHIST");
+    if (p != NULL)
+    {
+      (*fe_read_history) (p);
+    }
+  }
+  return res;
+}
+#endif
+
+/* ===================================================================*/
+/* =          fe_reset_input_mode (all possibilities)               = */
+/* ===================================================================*/
+#if defined(HAVE_READLINE) && !defined(HAVE_FEREAD) && !defined(HAVE_DYN_RL)
+extern int history_total_bytes();
+extern int write_history (const char *);
+#endif
+void fe_reset_input_mode ()
+{
+#if defined(HAVE_DYN_RL)
+  char *p = getenv("SINGULARHIST");
+  if ((p != NULL) && (fe_history_total_bytes != NULL))
+  {
+    if((*fe_history_total_bytes)()!=0)
+      (*fe_write_history) (p);
+  }
+#endif
+#if defined(HAVE_READLINE) && !defined(HAVE_FEREAD) && !defined(HAVE_DYN_RL)
+  char *p = getenv("SINGULARHIST");
+  if (p != NULL)
+  {
+    if(history_total_bytes()!=0)
+      write_history (p);
+  }
+#endif
+#if defined(HAVE_FEREAD)
+  #ifndef HAVE_ATEXIT
+  fe_reset_fe(NULL,NULL);
+  #else
+  fe_reset_fe();
+  #endif
+#endif
+}
+
diff --git a/kernel/oswrapper/rlimit.c b/kernel/oswrapper/rlimit.c
new file mode 100644
index 0000000..53bbc7c
--- /dev/null
+++ b/kernel/oswrapper/rlimit.c
@@ -0,0 +1,46 @@
+/****************************************
+ * Computer Algebra System SINGULAR     *
+ ****************************************/
+/***************************************************************
+ * File:    rlimit.c
+ * Purpose: set resource limits
+ ***************************************************************/
+
+#include "rlimit.h"
+
+#include <stdint.h>
+#include <sys/resource.h>
+
+/* raise the maximum number of processes (or threads),
+ * return  0 on success,
+ *        -1 on error
+ */
+int raise_rlimit_nproc()
+{
+#ifdef RLIMIT_NPROC
+  struct rlimit nproc;
+  getrlimit(RLIMIT_NPROC, &nproc);
+  if (nproc.rlim_cur == RLIM_INFINITY
+      || (nproc.rlim_max != RLIM_INFINITY && nproc.rlim_cur >= nproc.rlim_max))
+  {
+    return(-1);
+  }
+  if (nproc.rlim_cur < 512)
+  {
+    nproc.rlim_cur = 512;
+  }
+  if ((nproc.rlim_max == RLIM_INFINITY || 2*nproc.rlim_cur <= nproc.rlim_max)
+      && nproc.rlim_cur < 65536)
+  {
+    nproc.rlim_cur = 2*nproc.rlim_cur;
+  }
+  else
+  {
+    nproc.rlim_cur = nproc.rlim_max;
+  }
+  int res = setrlimit(RLIMIT_NPROC, &nproc);
+  return(res);
+#else
+  return(-1);
+#endif
+}
diff --git a/kernel/oswrapper/rlimit.h b/kernel/oswrapper/rlimit.h
new file mode 100644
index 0000000..8e37d7a
--- /dev/null
+++ b/kernel/oswrapper/rlimit.h
@@ -0,0 +1,23 @@
+/****************************************
+ * Computer Algebra System SINGULAR     *
+ ****************************************/
+/***************************************************************
+ * File:    rlimit.h
+ * Purpose: set resource limits
+ ***************************************************************/
+
+#ifndef RLIMIT_H
+#define RLIMIT_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+int raise_rlimit_nproc();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/kernel/oswrapper/test.cc b/kernel/oswrapper/test.cc
new file mode 100644
index 0000000..bb2c248
--- /dev/null
+++ b/kernel/oswrapper/test.cc
@@ -0,0 +1,376 @@
+#include <kernel/mod2.h>
+
+#include <omalloc/omalloc.h>
+
+#include <resources/feFopen.h>
+#include <resources/feResource.h>
+
+
+#include <factory/factory.h> // :(
+
+#include <misc/auxiliary.h>
+#include <misc/intvec.h>
+#include <misc/int64vec.h>
+#include <misc/mylimits.h>
+#include <misc/options.h>
+
+#include <reporter/reporter.h>
+
+#include <coeffs/si_gmp.h>
+#include <coeffs/coeffs.h>
+#include <coeffs/numbers.h>
+
+#ifndef PLURAL_INTERNAL_DECLARATIONS
+#define PLURAL_INTERNAL_DECLARATIONS
+#endif
+
+#ifndef PLURAL_INTERNAL_DECLARATIONS_GB_HACK
+#define PLURAL_INTERNAL_DECLARATIONS_GB_HACK
+#endif
+
+#include <polys/nc/gb_hack.h>
+#include <polys/nc/nc.h>
+#include <polys/nc/ncSACache.h>
+#include <polys/nc/ncSAFormula.h>
+#include <polys/nc/ncSAMult.h>
+#include <polys/nc/sca.h>
+#include <polys/nc/summator.h>
+
+#include <polys/kbuckets.h>
+#include <polys/matpol.h>
+#include <polys/mod_raw.h>
+#include <polys/prCopy.h>
+#include <polys/sbuckets.h>
+#include <polys/simpleideals.h>
+#include <polys/weight.h>
+
+#include <polys/monomials/maps.h>
+#include <polys/monomials/monomials.h>
+#include <polys/monomials/p_polys.h>
+#include <polys/monomials/ring.h>
+
+#include <polys/templates/p_MemAdd.h>
+#include <polys/templates/p_Procs.h>
+
+#include <polys/operations/pShallowCopyDelete.h>
+
+#include <polys/clapsing.h>
+
+
+// // TODO: DUE to the use of HALT in npolygon.cc :(((
+extern "C" {void m2_end(int i){exit(i);}}
+
+// // TODO: DUE to its use in kutil.cc :(((
+// char * showOption(){return NULL;}
+
+
+// #include "structs.h"
+
+
+// HEADERS:
+#include <kernel/ideals.h>
+#include <kernel/digitech.h>
+#include <kernel/fast_mult.h>
+
+// #include <kernel/spectrum/kmatrix.h>
+#include <kernel/preimage.h>
+
+#include <kernel/structs.h>
+
+#include <kernel/polys.h>
+
+void TestGBEngine()
+{
+
+  //  R = MPolynomialRing_polydict(QQ,5,'w,x,y,z,C', order='degrevlex')
+  //  J = (w*w - x*z, w*x - y*z, x*x - w*y, x*y - z*z, y*y - w*z)
+
+  const short w = 1;
+  const short x = 2;
+  const short y = 3;
+  const short z = 4;
+
+  const short N = (z - w + 1);
+
+  char **n=(char**)omalloc(N*sizeof(char*));
+
+
+  n[w-1]=omStrDup("w");
+  n[x-1]=omStrDup("x");
+  n[y-1]=omStrDup("y");
+  n[z-1]=omStrDup("z");
+
+
+  const int D = 3;
+  int *order = (int *) omAlloc0(D* sizeof(int));
+  int *block0 = (int *)omAlloc0(D * sizeof(int));
+  int *block1 = (int *)omAlloc0(D * sizeof(int));
+
+  order[0]  = ringorder_dp;
+  block0[0] = 1;
+  block1[0] = N;
+
+  order[1]  = ringorder_C;
+  block0[1] = 1;
+  block1[1] = N;
+
+  ring R = rDefault(0, N, n, D, order, block0, block1);
+
+//   ring R = rDefault(0, N, n);
+
+  rWrite(R); PrintLn();
+
+#ifdef RDEBUG
+  rDebugPrint(R);
+#endif
+
+  ideal I = idInit(5, 1);
+
+  int gen = 0;
+
+  {
+    // -xz
+    poly p = p_ISet(-1,R);
+
+    p_SetExp(p, x, 1, R);
+    p_SetExp(p, z, 1, R);
+    p_Setm(p, R);
+
+    assume( p_GetExp(p, x, R) == 1 );
+    assume( p_GetExp(p, z, R) == 1 );
+    assume( p_GetExp(p, w, R) == 0 );
+    assume( p_GetExp(p, y, R) == 0 );
+
+    // +w2
+    poly lp = p_ISet(1,R);
+    p_SetExp(lp, w, 2, R);
+    p_Setm(lp, R);
+
+    assume( p_GetExp(lp, w, R) == 2 );
+    assume( p_GetExp(lp, x, R) == 0 );
+    assume( p_GetExp(lp, y, R) == 0 );
+    assume( p_GetExp(lp, z, R) == 0 );
+
+    MATELEM(I, 1, ++gen) = p_Add_q(lp, p, R); // w2 - xz
+  }
+
+  {
+    // -yz
+    poly p = p_ISet(-1,R);
+
+    p_SetExp(p, y, 1, R);
+    p_SetExp(p, z, 1, R);
+    p_Setm(p, R);
+
+    assume( p_GetExp(p, y, R) == 1 );
+    assume( p_GetExp(p, z, R) == 1 );
+    assume( p_GetExp(p, w, R) == 0 );
+    assume( p_GetExp(p, x, R) == 0 );
+
+    // +wx
+    poly lp = p_ISet(1,R);
+    p_SetExp(lp, w, 1, R);
+    p_SetExp(lp, x, 1, R);
+    p_Setm(lp, R);
+
+    assume( p_GetExp(lp, w, R) == 1 );
+    assume( p_GetExp(lp, x, R) == 1 );
+    assume( p_GetExp(lp, y, R) == 0 );
+    assume( p_GetExp(lp, z, R) == 0 );
+
+    MATELEM(I, 1, ++gen) = p_Add_q(lp, p, R); // wx - yz
+  }
+
+
+  {
+    // -wy
+    poly p = p_ISet(-1,R);
+
+    p_SetExp(p, y, 1, R);
+    p_SetExp(p, w, 1, R);
+    p_Setm(p, R);
+
+    assume( p_GetExp(p, y, R) == 1 );
+    assume( p_GetExp(p, w, R) == 1 );
+    assume( p_GetExp(p, z, R) == 0 );
+    assume( p_GetExp(p, x, R) == 0 );
+
+    // +x2
+    poly lp = p_ISet(1,R);
+    p_SetExp(lp, x, 2, R);
+    p_Setm(lp, R);
+
+    assume( p_GetExp(lp, w, R) == 0 );
+    assume( p_GetExp(lp, x, R) == 2 );
+    assume( p_GetExp(lp, y, R) == 0 );
+    assume( p_GetExp(lp, z, R) == 0 );
+
+    MATELEM(I, 1, ++gen) = p_Add_q(lp, p, R); // x2 - wy
+  }
+
+
+  {
+    // -z2
+    poly p = p_ISet(-1,R);
+
+    p_SetExp(p, z, 2, R);
+    p_Setm(p, R);
+
+    assume( p_GetExp(p, y, R) == 0 );
+    assume( p_GetExp(p, w, R) == 0 );
+    assume( p_GetExp(p, z, R) == 2 );
+    assume( p_GetExp(p, x, R) == 0 );
+
+    // +xy
+    poly lp = p_ISet(1,R);
+    p_SetExp(lp, x, 1, R);
+    p_SetExp(lp, y, 1, R);
+    p_Setm(lp, R);
+
+    assume( p_GetExp(lp, w, R) == 0 );
+    assume( p_GetExp(lp, x, R) == 1 );
+    assume( p_GetExp(lp, y, R) == 1 );
+    assume( p_GetExp(lp, z, R) == 0 );
+
+    MATELEM(I, 1, ++gen) = p_Add_q(lp, p, R); // xy - z2
+  }
+
+
+  {
+    // -wz
+    poly p = p_ISet(-1,R);
+
+    p_SetExp(p, w, 1, R);
+    p_SetExp(p, z, 1, R);
+    p_Setm(p, R);
+
+    assume( p_GetExp(p, y, R) == 0 );
+    assume( p_GetExp(p, w, R) == 1 );
+    assume( p_GetExp(p, z, R) == 1 );
+    assume( p_GetExp(p, x, R) == 0 );
+
+    // +y2
+    poly lp = p_ISet(1,R);
+    p_SetExp(lp, y, 2, R);
+    p_Setm(lp, R);
+
+    assume( p_GetExp(lp, w, R) == 0 );
+    assume( p_GetExp(lp, x, R) == 0 );
+    assume( p_GetExp(lp, y, R) == 2 );
+    assume( p_GetExp(lp, z, R) == 0 );
+
+    MATELEM(I, 1, ++gen) = p_Add_q(lp, p, R); // y2 - wz
+  }
+#ifdef PDEBUG
+  PrintS("I: ");
+  idShow(I, R, R, 0);
+#endif
+
+
+//  ideal kStd(ideal F, ideal Q, tHomog h, intvec ** mw,intvec *hilb=NULL,
+//             int syzComp=0,int newIdeal=0, intvec *vw=NULL);
+  // make R the default ring:
+  rChangeCurrRing(R);
+
+ ////
+
+  idDelete( &I, R);
+  rDelete(R); // should cleanup every belonging polynomial, right!?
+
+}
+
+
+
+void TestSimpleRingArithmetcs()
+{
+  // Libpolys tests:
+
+  // construct the ring Z/32003[x,y,z]
+  // the variable names
+  char **n=(char**)omalloc(3*sizeof(char*));
+  n[0]=omStrDup("x");
+  n[1]=omStrDup("y");
+  n[2]=omStrDup("z2");
+
+  ring R = rDefault(32003,3,n); //  ring R = rDefault(0,3,n);
+
+  rWrite(R); PrintLn();
+
+#ifdef RDEBUG
+  rDebugPrint(R);
+#endif
+
+
+  poly p = p_ISet(1,R); p_SetExp(p,1,1, R); p_Setm(p, R);
+
+  assume( p_GetExp(p,1, R) == 1 );
+
+  poly pp = pp_Mult_qq( p, p, R);
+
+  Print("p: "); p_Write0(p, R); Print(", deg(p): %ld", p_Totaldegree(p, R)); assume( 1 == p_Totaldegree(p, R) );
+
+  Print("; p*p : "); p_Write0(pp, R); Print("deg(pp): %ld\n", p_Totaldegree(pp, R)); assume( 2 == p_Totaldegree(pp, R) );
+
+
+  p_Delete(&p, R);
+
+  assume( p_GetExp(pp,1, R) == 2 );
+
+  p_Delete(&pp, R);
+
+
+//  rDelete(R);
+
+  // make R the default ring:
+  rChangeCurrRing(R);
+
+  // create the polynomial 1
+  poly p1=pISet(1);
+
+  // create tthe polynomial 2*x^3*z^2
+  poly p2=p_ISet(2,R);
+  pSetExp(p2,1,3);
+  pSetExp(p2,3,2);
+  pSetm(p2);
+
+  // print p1 + p2
+  Print("p1: "); pWrite0(p1);
+  Print(" + p2: "); pWrite0(p2);
+  Print("  ---- >>>> ");
+
+  // compute p1+p2
+  p1=p_Add_q(p1,p2,R); p2=NULL;
+  pWrite(p1);
+
+  // clean up:
+//  pDelete(&p1);
+
+  rDelete(R); // should cleanup every belonging polynomial, right!?
+}
+
+
+int main( int, char *argv[] )
+{
+  assume( sizeof(long) == SIZEOF_LONG );
+
+  if( sizeof(long) != SIZEOF_LONG )
+  {
+    WerrorS("Bad config.h: wrong size of long!");
+
+    return(1);
+  }
+
+
+  feInitResources(argv[0]);
+
+  StringSetS("ressources in use (as reported by feStringAppendResources(0):\n");
+  feStringAppendResources(0);
+
+  PrintLn();
+  { char* s = StringEndS(); PrintS(s); omFree(s); }
+
+  TestGBEngine();
+  TestSimpleRingArithmetcs();
+
+  return 0;
+}
diff --git a/kernel/oswrapper/timer.cc b/kernel/oswrapper/timer.cc
new file mode 100644
index 0000000..d2725a7
--- /dev/null
+++ b/kernel/oswrapper/timer.cc
@@ -0,0 +1,213 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+
+/*
+*  ABSTRACT - get the computing time
+*/
+
+
+
+
+#include <kernel/mod2.h>
+
+#include <sys/resource.h>
+#include <time.h>
+#include <sys/time.h>
+#include <unistd.h>
+
+int        timerv = 0;
+static double timer_resolution = TIMER_RESOLUTION;
+
+static double mintime = 0.5;
+
+void SetTimerResolution(int res)
+{
+  timer_resolution = (double) res;
+}
+
+void SetMinDisplayTime(double mtime)
+{
+  mintime = mtime;
+}
+
+#include <stdio.h>
+
+#ifdef TIME_WITH_SYS_TIME
+# include <time.h>
+# ifdef HAVE_SYS_TIME_H
+#   include <sys/time.h>
+# endif
+#else
+# ifdef HAVE_SYS_TIME_H
+#   include <sys/time.h>
+# else
+#   include <time.h>
+# endif
+#endif
+
+#ifdef HAVE_SYS_TIMES_H
+#include <sys/times.h>
+#endif
+
+
+#include <reporter/reporter.h>
+#include <kernel/oswrapper/timer.h>
+
+/*3
+* the start time of the timer
+*/
+static int64 siStartTime;
+static int64 startl;
+
+/*3
+* temp structure to get the time
+*/
+static struct rusage t_rec;
+/*0 implementation*/
+
+int initTimer()
+{
+  getrusage(RUSAGE_SELF,&t_rec);
+  siStartTime = (t_rec.ru_utime.tv_sec*1000000+t_rec.ru_utime.tv_usec
+               +t_rec.ru_stime.tv_sec*1000000+t_rec.ru_stime.tv_usec
+               +5000)/10000; // unit is 1/100 sec
+  getrusage(RUSAGE_CHILDREN,&t_rec);
+  siStartTime += (t_rec.ru_utime.tv_sec*1000000+t_rec.ru_utime.tv_usec
+               +t_rec.ru_stime.tv_sec*1000000+t_rec.ru_stime.tv_usec
+               +5000)/10000; // unit is 1/100 sec
+  return (int)time(NULL);
+}
+
+void startTimer()
+{
+  getrusage(RUSAGE_SELF,&t_rec);
+  startl = ((int64)t_rec.ru_utime.tv_sec*1000000+(int64)t_rec.ru_utime.tv_usec
+               +(int64)t_rec.ru_stime.tv_sec*1000000+t_rec.ru_stime.tv_usec
+               +(int64)5000)/(int64)10000; // unit is 1/100 sec
+  getrusage(RUSAGE_CHILDREN,&t_rec);
+  startl += ((int64)t_rec.ru_utime.tv_sec*1000000+(int64)t_rec.ru_utime.tv_usec
+               +(int64)t_rec.ru_stime.tv_sec*1000000+t_rec.ru_stime.tv_usec
+               +(int64)5000)/(int64)10000; // unit is 1/100 sec
+}
+
+/*2
+* returns the time since a fixed point in seconds
+*/
+int getTimer()
+{
+  int64 curr;
+  getrusage(RUSAGE_SELF,&t_rec);
+  curr = ((int64)t_rec.ru_utime.tv_sec*1000000+(int64)t_rec.ru_utime.tv_usec
+         +(int64)t_rec.ru_stime.tv_sec*1000000+(int64)t_rec.ru_stime.tv_usec
+         +(int64)5000)/(int64)10000; // unit is 1/100 sec
+  getrusage(RUSAGE_CHILDREN,&t_rec);
+  curr += ((int64)t_rec.ru_utime.tv_sec*1000000+(int64)t_rec.ru_utime.tv_usec
+         +(int64)t_rec.ru_stime.tv_sec*1000000+(int64)t_rec.ru_stime.tv_usec
+         +(int64)5000)/(int64)10000; // unit is 1/100 sec
+  curr -= siStartTime;
+  double f =  ((double)curr) * timer_resolution / (double)100;
+  return (int)(f+0.5);
+}
+
+/*2
+* stops timer, writes string s and the time since last call of startTimer
+* if this time is > mintime sec
+*/
+#ifdef EXTEND_TIMER_D
+extern int iiOp;
+#endif
+
+void writeTime(const char* v)
+{
+  int64 curr;
+  getrusage(RUSAGE_SELF,&t_rec);
+  curr = ((int64)t_rec.ru_utime.tv_sec*1000000+(int64)t_rec.ru_utime.tv_usec
+               +(int64)t_rec.ru_stime.tv_sec*1000000+(int64)t_rec.ru_stime.tv_usec
+               +(int64)5000)/(int64)10000; // unit is 1/100 sec
+  getrusage(RUSAGE_CHILDREN,&t_rec);
+  curr += ((int64)t_rec.ru_utime.tv_sec*1000000+(int64)t_rec.ru_utime.tv_usec
+               +(int64)t_rec.ru_stime.tv_sec*1000000+(int64)t_rec.ru_stime.tv_usec
+               +(int64)5000)/(int64)10000; // unit is 1/100 sec
+  curr -= startl;
+  double f =  ((double)curr) * timer_resolution / (double)100;
+  if (f/timer_resolution > mintime)
+  {
+#ifdef EXTEND_TIMER_D
+    Print("//%s %.2f/%d sec (%d) >>%s<<\n" ,v ,f,(int)timer_resolution,iiOp,my_yylinebuf);
+#else
+    if (timer_resolution==(double)1.0)
+      Print("//%s %.2f sec\n" ,v ,f);
+    else
+      Print("//%s %.2f/%d sec\n" ,v ,f,(int)timer_resolution);
+#endif
+  }
+}
+
+/*0 Real timer implementation*/
+int rtimerv = 0;
+static struct timeval  startRl;
+static struct timeval  siStartRTime;
+static struct timezone tzp;
+
+void startRTimer()
+{
+  gettimeofday(&siStartRTime, &tzp);
+}
+
+void initRTimer()
+{
+#ifdef HAVE_GETTIMEOFDAY
+  gettimeofday(&startRl, &tzp);
+  gettimeofday(&siStartRTime, &tzp);
+#else
+  memset(&startRl,0,sizeof(startRl));
+  memset(&siStartRTime,0,sizeof(siStartRTime));
+#endif
+}
+
+/*2
+* returns the time since a fixed point in resolutions
+*/
+int getRTimer()
+{
+  struct timeval now;
+
+  gettimeofday(&now, &tzp);
+
+  if (startRl.tv_usec > now.tv_usec)
+  {
+    now.tv_usec += 1000000;
+    now.tv_sec --;
+  }
+
+  double f =((double)  (now.tv_sec - startRl.tv_sec))*timer_resolution +
+    ((double) (now.tv_usec - startRl.tv_usec))*timer_resolution /
+    (double) 1000000;
+
+  return (int)(f+0.5);
+}
+
+/*2
+* stops timer, writes string s and the time since last call of startTimer
+* if this time is > mintime
+*/
+void writeRTime(const char* v)
+{
+  struct timeval now;
+
+  gettimeofday(&now, &tzp);
+
+  if (siStartRTime.tv_usec > now.tv_usec)
+  {
+    now.tv_usec += 1000000;
+    now.tv_sec --;
+  }
+
+  double f =((double)  (now.tv_sec - siStartRTime.tv_sec)) +
+    ((double) (now.tv_usec - siStartRTime.tv_usec)) /
+    (double) 1000000;
+
+  if (f > mintime)
+   Print("//%s %.2f sec \n" ,v ,f);
+}
diff --git a/kernel/oswrapper/timer.h b/kernel/oswrapper/timer.h
new file mode 100644
index 0000000..ab444a4
--- /dev/null
+++ b/kernel/oswrapper/timer.h
@@ -0,0 +1,28 @@
+#ifndef TIMER_H
+#define TIMER_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+*  ABSTRACT - get the computing time
+*/
+
+extern int timerv;
+void startTimer(void);
+void writeTime(const char* s);
+
+int initTimer();
+int  getTimer();
+
+extern int rtimerv;
+void startRTimer(void);
+void writeRTime(const char* s);
+
+void initRTimer();
+int  getRTimer();
+
+void SetTimerResolution(int res);
+void SetMinDisplayTime(double mtime);
+
+#endif
+
diff --git a/kernel/polys.cc b/kernel/polys.cc
new file mode 100644
index 0000000..e37824b
--- /dev/null
+++ b/kernel/polys.cc
@@ -0,0 +1,65 @@
+
+#include <kernel/mod2.h>
+
+#include <omalloc/omalloc.h>
+#include <misc/auxiliary.h>
+#include <misc/options.h>
+
+#include "polys.h"
+
+/// Widely used global variable which specifies the current polynomial ring for Singular interpreter and legacy implementatins.
+/// @Note: one should avoid using it in newer designs, for example due to possible problems in parallelization with threads.
+ring  currRing = NULL;
+
+void rChangeCurrRing(ring r)
+{
+  #if 0
+  if ((currRing!=NULL)&&(currRing!=r))
+  {
+    currRing->options=si_opt_1 & TEST_RINGDEP_OPTS;
+  }
+  #endif
+  if( r != NULL )
+  {
+    rTest(r);
+
+    //------------ set global ring vars --------------------------------
+    currRing = r;
+    //------------ global variables related to coefficients ------------
+    assume( r->cf!= NULL );
+    nSetChar(r->cf);
+    //------------ global variables related to polys
+    p_SetGlobals(r);
+    //------------ global variables related to factory -----------------
+  }
+  else
+  {
+    currRing = NULL;
+  }
+}
+/*
+/// internally changes the gloabl ring and resets the relevant
+/// global variables:
+/// SHOULD BE DEPRECATED NOW...?
+void rChangeCurrRing(ring r)
+{
+ // if (!rMinpolyIsNULL(currRing))
+ // {
+ //   omCheckAddr(currRing->cf->minpoly);
+ // }
+  //------------ set global ring vars --------------------------------
+  //currRing = r;
+  if (r != NULL)
+  {
+    rTest(r);
+    //------------ set global ring vars --------------------------------
+
+    //------------ global variables related to coefficients ------------
+    nSetChar(r->cf);
+
+    //------------ global variables related to polys -------------------
+    p_SetGlobals(r);
+    //------------ global variables related to factory -----------------
+  }
+}
+*/
diff --git a/kernel/polys.h b/kernel/polys.h
new file mode 100644
index 0000000..4c6d6a9
--- /dev/null
+++ b/kernel/polys.h
@@ -0,0 +1,396 @@
+/*! \file kernel/polys.h Compatiblity layer for legacy polynomial operations (over @ref currRing)
+
+ Macro defines for legacy polynomial operations used in @ref kernel_page and @ref singular_page.
+ They take no ring argument since they work with @ref currRing by default.
+ Notice that they have different prefix: `p` instead of `p_`.
+
+ See also related global ring variable and the correct ring changeing routine:
+ - \ref currRing
+ - \ref rChangeCurrRing
+*/
+
+#ifndef POLYS_H
+#define POLYS_H
+
+#include <polys/monomials/ring.h>
+#include <polys/monomials/p_polys.h>
+
+extern ring currRing;
+void rChangeCurrRing(ring r);
+
+#include <coeffs/numbers.h>
+
+/***************************************************************
+ *
+ * Primitives for accessing and setting fields of a poly
+ * poly must be != NULL
+ *
+ ***************************************************************/
+
+/// deletes old coeff before setting the new one
+#define pSetCoeff(p,n)      p_SetCoeff(p,n,currRing)
+
+/// Order
+#define pGetOrder(p)        p_GetOrder(p, currRing)
+
+/// Component
+#define pGetComp(p)         __p_GetComp(p, currRing)
+#define pSetComp(p,v)       p_SetComp(p,v, currRing)
+
+/// Exponent
+#define pGetExp(p,i)        p_GetExp(p, i, currRing)
+#define pSetExp(p,i,v)      p_SetExp(p, i, v, currRing)
+#define pIncrExp(p,i)       p_IncrExp(p,i, currRing)
+#define pDecrExp(p,i)       p_DecrExp(p,i, currRing)
+#define pAddExp(p,i,v)      p_AddExp(p,i,v, currRing)
+#define pSubExp(p,i,v)      p_SubExp(p,i,v, currRing)
+#define pMultExp(p,i,v)     p_MultExp(p,i,v, currRing)
+#define pGetExpSum(p1, p2, i)    p_GetExpSum(p1, p2, i, currRing)
+#define pGetExpDiff(p1, p2, i)   p_GetExpDiff(p1, p2, i, currRing)
+
+
+/***************************************************************
+ *
+ * Allocation/Initalization/Deletion
+ * except for pHead, all polys must be != NULL
+ *
+ ***************************************************************/
+/// allocates the space for a new monomial -- no initialization !!!
+#define pNew()          p_New(currRing)
+/// allocates a new monomial and initializes everything to 0
+#define pInit()         p_Init(currRing)
+/// like pInit, except that expvector is initialized to that of p,
+/// p must be != NULL
+#define pLmInit(p)  p_LmInit(p, currRing)
+/// returns newly allocated copy of Lm(p), coef is copied, next=NULL,
+/// p might be NULL
+#define pHead(p)        p_Head(p, currRing)
+/// frees the space of the monomial m, assumes m != NULL
+/// coef is not freed, m is not advanced
+static inline void pLmFree(poly p)    {p_LmFree(p, currRing);}
+/// like pLmFree, but advances p
+static inline void pLmFree(poly *p)   {p_LmFree(p, currRing);}
+/// assumes p != NULL, deletes p, returns pNext(p)
+#define pLmFreeAndNext(p) p_LmFreeAndNext(p, currRing)
+/// assume p != NULL, deletes Lm(p)->coef and Lm(p)
+#define pLmDelete(p)    p_LmDelete(p, currRing)
+/// like pLmDelete, returns pNext(p)
+#define pLmDeleteAndNext(p) p_LmDeleteAndNext(p, currRing)
+
+/***************************************************************
+ *
+ * Operation on ExpVectors: assumes polys != NULL
+ *
+ ***************************************************************/
+
+#define pExpVectorCopy(d_p, s_p)      p_ExpVectorCopy(d_p, s_p, currRing)
+#define pExpVectorAdd(p1, p2)         p_ExpVectorAdd(p1, p2, currRing)
+#define pExpVectorSub(p1, p2)         p_ExpVectorSub(p1, p2, currRing)
+#define pExpVectorAddSub(p1, p2, p3)  p_ExpVectorAddSub(p1, p2, p3, currRing)
+#define pExpVectorSum(pr, p1, p2)     p_ExpVectorSum(pr, p1, p2, currRing)
+#define pExpVectorDiff(pr, p1, p2)    p_ExpVectorDiff(pr, p1, p2, currRing)
+
+/// Gets a copy of (resp. set) the exponent vector, where e is assumed
+/// to point to (r->N +1)*sizeof(long) memory. Exponents are
+/// filled in as follows: comp, e_1, .., e_n
+#define pGetExpV(p, e)      p_GetExpV(p, e, currRing)
+#define pSetExpV(p, e)      p_SetExpV(p, e, currRing)
+
+/***************************************************************
+ *
+ * Comparisons: they are all done without regarding coeffs
+ *
+ ***************************************************************/
+/// returns 0|1|-1 if p=q|p>q|p<q w.r.t monomial ordering
+#define pLmCmp(p,q)         p_LmCmp(p,q,currRing)
+/// executes axtionE|actionG|actionS if p=q|p>q|p<q w.r.t monomial ordering
+/// action should be a "goto ..."
+#define pLmCmpAction(p,q, actionE, actionG, actionS)  \
+  _p_LmCmpAction(p,q,currRing, actionE, actionG,actionS)
+
+#define pLmEqual(p1, p2)     p_ExpVectorEqual(p1, p2, currRing)
+
+/// pCmp: args may be NULL
+/// returns: (p2==NULL ? 1 : (p1 == NULL ? -1 : p_LmCmp(p1, p2)))
+#define pCmp(p1, p2)    p_Cmp(p1, p2, currRing)
+
+
+/***************************************************************
+ *
+ * Divisiblity tests, args must be != NULL, except for
+ * pDivisbleBy
+ *
+ ***************************************************************/
+/// returns TRUE, if leading monom of a divides leading monom of b
+/// i.e., if there exists a expvector c > 0, s.t. b = a + c;
+#define pDivisibleBy(a, b)  p_DivisibleBy(a,b,currRing)
+/// like pDivisibleBy, except that it is assumed that a!=NULL, b!=NULL
+#define pLmDivisibleBy(a,b)  p_LmDivisibleBy(a,b,currRing)
+/// like pLmDivisibleBy, does not check components
+#define pLmDivisibleByNoComp(a, b) p_LmDivisibleByNoComp(a,b,currRing)
+/// Divisibility tests based on Short Exponent vectors
+/// sev_a     == pGetShortExpVector(a)
+/// not_sev_b == ~ pGetShortExpVector(b)
+#define pLmShortDivisibleBy(a, sev_a, b, not_sev_b) \
+  p_LmShortDivisibleBy(a, sev_a, b, not_sev_b, currRing)
+#define pLmRingShortDivisibleBy(a, sev_a, b, not_sev_b) \
+  p_LmRingShortDivisibleBy(a, sev_a, b, not_sev_b, currRing)
+/// returns the "Short Exponent Vector" -- used to speed up divisibility
+/// tests (see polys-impl.cc )
+#define pGetShortExpVector(a)   p_GetShortExpVector(a, currRing)
+
+#ifdef HAVE_RINGS
+/// divisibility check over ground ring (which may contain zero divisors);
+/// TRUE iff LT(f) divides LT(g), i.e., LT(f)*c*m = LT(g), for some
+/// coefficient c and some monomial m;
+/// does not take components into account */
+#define  pDivisibleByRingCase(f,g) p_DivisibleByRingCase(f,g,currRing)
+#endif
+
+/***************************************************************
+ *
+ * Copying/Deleteion of polys: args may be NULL
+ *
+ ***************************************************************/
+/// return a copy of the poly
+#define pCopy(p) p_Copy(p, currRing)
+#define pDelete(p_ptr)  p_Delete(p_ptr, currRing)
+
+/***************************************************************
+ *
+ * Copying/Deletion of polys: args may be NULL
+ *  - p/q as arg mean a poly
+ *  - m a monomial
+ *  - n a number
+ *  - pp (resp. qq, mm, nn) means arg is constant
+ *  - p (resp, q, m, n)     means arg is destroyed
+ *
+ ***************************************************************/
+#define pNeg(p)                     p_Neg(p, currRing)
+#define ppMult_nn(p, n)             pp_Mult_nn(p, n, currRing)
+#define pMult_nn(p, n)              p_Mult_nn(p, n, currRing)
+#define ppMult_mm(p, m)             pp_Mult_mm(p, m, currRing)
+#define pMult_mm(p, m)              p_Mult_mm(p, m, currRing)
+#define pAdd(p, q)                  p_Add_q(p, q, currRing)
+#define pPower(p, q)                p_Power(p, q, currRing)
+#define pMinus_mm_Mult_qq(p, m, q)  p_Minus_mm_Mult_qq(p, m, q, currRing)
+#define pPlus_mm_Mult_qq(p, m, q)   p_Plus_mm_Mult_qq(p, m, q, currRing)
+#define pMult(p, q)                 p_Mult_q(p, q, currRing)
+#define ppMult_qq(p, q)             pp_Mult_qq(p, q, currRing)
+// p*Coeff(m) for such monomials pm of p, for which m is divisble by pm
+#define ppMult_Coeff_mm_DivSelect(p, m)   pp_Mult_Coeff_mm_DivSelect(p, m, currRing)
+/*************************************************************************
+ *
+ * Sort routines
+ *
+ *************************************************************************/
+/// sorts p, assumes all monomials in p are different
+#define pSortMerger(p)          p_SortMerge(p, currRing)
+#define pSort(p)                p_SortMerge(p, currRing)
+
+/// sorts p, p may have equal monomials
+#define pSortAdd(p)             p_SortAdd(p, currRing)
+
+
+/// Assume: If considerd only as poly in any component of p
+/// (say, monomials of other components of p are set to 0),
+/// then p is already sorted correctly
+#define pSortCompCorrect(p) pSort(p)
+
+/***************************************************************
+ *
+ * Predicates on polys/Lm's
+ *
+ ***************************************************************/
+/// return true if all p is eihter NULL, or if all exponents
+/// of p are 0 and Comp of p is zero
+#define   pIsConstantComp(p)        p_IsConstantComp(p, currRing)
+/// like above, except that Comp might be != 0
+#define   pIsConstant(p)            p_IsConstant(p,currRing)
+/// return true if the Lm is a constant <>0
+#define   pIsUnit(p)            p_IsUnit(p,currRing)
+/// like above, except that p must be != NULL
+#define   pLmIsConstantComp(p)      p_LmIsConstantComp(p, currRing)
+#define   pLmIsConstant(p)          p_LmIsConstant(p,currRing)
+
+/// return TRUE if all monomials of p are constant
+#define   pIsConstantPoly(p)        p_IsConstantPoly(p, currRing)
+
+#define   pIsPurePower(p)   p_IsPurePower(p, currRing)
+#define   pIsUnivariate(p)  p_IsUnivariate(p, currRing)
+#define   pIsVector(p)      (pGetComp(p)>0)
+#define   pGetVariables(p,e)  p_GetVariables(p, e, currRing)
+
+/***************************************************************
+ *
+ * Old stuff
+ *
+ ***************************************************************/
+
+typedef poly*   polyset;
+
+/*-------------predicate on polys ----------------------*/
+#define  pHasNotCF(p1,p2)   p_HasNotCF(p1,p2,currRing)
+                                /*has no common factor ?*/
+#define  pSplit(p,r)        p_Split(p,r)
+                                /*p => IN(p), r => REST(p) */
+
+
+
+/*-----------the ordering of monomials:-------------*/
+#define pSetm(p)    p_Setm(p, currRing)
+/// TODO:
+#define pSetmComp(p)   p_Setm(p, currRing)
+
+/***************************************************************
+ *
+ * Degree stuff -- see p_polys.cc for explainations
+ *
+ ***************************************************************/
+inline int pWeight(int i, const ring R = currRing){ return p_Weight(i, R); }
+
+
+static inline long pTotaldegree(poly p) { return p_Totaldegree(p,currRing); }
+#define pWTotaldegree(p) p_WTotaldegree(p,currRing)
+#define pWDegree(p) p_WDegree(p,currRing)
+
+/*-------------operations on polynomials:------------*/
+#define   pSub(a,b) p_Sub(a,b,currRing)
+
+#define pmInit(a,b) p_mInit(a,b,currRing)
+
+/* ----------------- define to enable new p_procs -----*/
+
+#define pDivide(a,b) p_Divide(a,b,currRing)
+#define pDivideM(a,b) p_DivideM(a,b,currRing)
+#define pLcm(a,b,m) p_Lcm(a,b,m,currRing)
+#define pDiff(a,b)  p_Diff(a,b,currRing)
+#define pDiffOp(a,b,m) p_DiffOp(a,b,m,currRing)
+
+#define   pMaxComp(p)   p_MaxComp(p, currRing)
+#define   pMinComp(p)   p_MinComp(p, currRing)
+
+#define   pOneComp(p)       p_OneComp(p, currRing)
+#define   pSetCompP(a,i)    p_SetCompP(a, i, currRing)
+
+// let's inline those, so that we can call them from the debugger
+inline char*   pString(poly p)    {return p_String(p, currRing, currRing);}
+inline void    pString0(poly p)   {p_String0(p, currRing, currRing);}
+inline void    pWrite(poly p)     {p_Write(p, currRing, currRing);}
+inline void    pWrite0(poly p)    {p_Write0(p, currRing, currRing);}
+inline void    wrp(poly p)        {p_wrp(p, currRing, currRing);}
+
+#define   pISet(i) p_ISet(i,currRing)
+#define   pNSet(n) p_NSet(n,currRing)
+
+#define   pOne()   p_One(currRing)
+
+#define   pNormalize(p) p_Normalize(p,currRing)
+#define   pSize(p)      p_Size(p,currRing)
+
+
+/// homogenizes p by multiplying certain powers of the varnum-th variable
+#define  pHomogen(p,varnum) p_Homogen(p,varnum,currRing)
+
+BOOLEAN   pIsHomogeneous (poly p);
+// // replaces the maximal powers of the leading monomial of p2 in p1 by
+// // the same powers of n, utility for dehomogenization
+// #define   pDehomogen(p1,p2,n) p_Dehomgen(p1,p2,n,currRing)
+// #define   pIsHomogen(p)       p_IsHomggen(p,currRing)
+#define   pIsHomogen(p)       p_IsHomogen(p,currRing)
+
+/*BOOLEAN   pVectorHasUnitM(poly p, int * k);*/
+#define   pVectorHasUnitB(p,k) p_VectorHasUnitB(p,k,currRing)
+#define   pVectorHasUnit(p,k,l) p_VectorHasUnit(p,k,l,currRing)
+#define   pTakeOutComp1(p,k)    p_TakeOutComp1(p,k,currRing)
+
+/// Splits *p into two polys: *q which consists of all monoms with
+/// component == comp and *p of all other monoms *lq == pLength(*q)
+/// On return all components pf *q == 0
+inline void pTakeOutComp(poly *p, long comp, poly *q, int *lq, const ring R = currRing)
+{
+  return p_TakeOutComp(p, comp, q, lq, R);
+}
+
+
+/// This is something weird -- Don't use it, unless you know what you are doing
+inline poly      pTakeOutComp(poly * p, int k, const ring R = currRing)
+{
+  return p_TakeOutComp(p, k, R);
+}
+
+/* old spielwiese
+#define   pTakeOutComp(p,k,q,lq)    p_TakeOutComp(p,k,q,lq,currRing)
+
+// Similar to pTakeOutComp, except that only those components are
+// taken out whose Order == order
+// ASSUME: monomial ordering is Order compatible, i.e., if m1, m2 Monoms then
+//         m1 >= m2 ==> pGetOrder(m1) >= pGetOrder(m2)
+#define   pDecrOrdTakeOutComp(p,c,o,q,lq) p_DecrOrdTakeOutComp(p,c,o,q,lq,currRing)
+*/
+void      pSetPolyComp(poly p, int comp);
+#define   pDeleteComp(p,k) p_DeleteComp(p,k,currRing)
+
+inline void pNorm(poly p, const ring R = currRing){ p_Norm(p, R); }
+
+
+#define   pSubst(p,n,e) p_Subst(p,n,e,currRing)
+#define   ppJet(p,m) pp_Jet(p,m,currRing)
+#define   pJet(p,m)  p_Jet(p,m,currRing)
+#define   ppJetW(p,m,iv) pp_JetW(p,m,iv,currRing)
+#define   pJetW(p,m,iv) p_JetW(p,m,iv,currRing)
+#define   pMinDeg(p,w) p_MinDeg(p,w,currRing)
+#define   pSeries(n,p,u,w) p_Series(n,p,u,w,currRing)
+#define   pInvers(n,p,w) p_Invers(n,p,w,currRing)
+// maximum weigthed degree of all monomials of p, w is indexed from
+// 1..pVariables
+
+/// Deprecated: only for compatibility with older code!
+#define    pDegW(p,w) p_DegW(p,w,currRing)
+
+/*-----------type conversions ----------------------------*/
+// void  pVec2Polys(poly v, polyset *p, int *len);
+#define   pVar(m) p_Var(m,currRing)
+
+/*-----------specials for spoly-computations--------------*/
+
+/// Returns TRUE if
+///      * LM(p) | LM(lcm)
+///      * LC(p) | LC(lcm) only if ring
+///      * Exists i, j:
+///          * LE(p, i)  != LE(lcm, i)
+///          * LE(p1, i) != LE(lcm, i)   ==> LCM(p1, p) != lcm
+///          * LE(p, j)  != LE(lcm, j)
+///          * LE(p2, j) != LE(lcm, j)   ==> LCM(p2, p) != lcm
+BOOLEAN pCompareChain (poly p, poly p1, poly p2, poly lcm, const ring R = currRing);
+
+#ifdef HAVE_RATGRING
+BOOLEAN pCompareChainPart (poly p, poly p1, poly p2, poly lcm, const ring R = currRing);
+#endif
+
+
+#define  pEqualPolys(p1,p2) p_EqualPolys(p1,p2,currRing)
+
+
+
+/// returns the length of a polynomial (numbers of monomials)
+/// respect syzComp
+static inline poly pLast(poly a, int &length) { return p_Last (a, length, currRing); }
+static inline poly pLast(poly a) { int l; return pLast(a, l); }
+
+/***************************************************************
+ *
+ * PDEBUG stuff
+ *
+ ***************************************************************/
+#ifdef PDEBUG
+#define pTest(p)        _p_Test(p, currRing, PDEBUG)
+#define pLmTest(p)      _p_LmTest(p, currRing, PDEBUG)
+
+#else // ! PDEBUG
+
+#define pTest(p)        do {} while (0)
+#define pLmTest(p)      do {} while (0)
+#endif
+
+#endif // POLYS_H
diff --git a/kernel/preimage.cc b/kernel/preimage.cc
new file mode 100644
index 0000000..c5be105
--- /dev/null
+++ b/kernel/preimage.cc
@@ -0,0 +1,181 @@
+
+#include <kernel/mod2.h>
+
+#include <omalloc/omalloc.h>
+#include <misc/auxiliary.h>
+#include <misc/options.h>
+#include <misc/intvec.h>
+
+#include <kernel/polys.h>
+#include <polys/monomials/ring.h>
+
+
+#include <kernel/ideals.h>
+#include <kernel/GBEngine/kstd1.h>
+#include <kernel/GBEngine/khstd.h>
+
+#include <kernel/GBEngine/kutil.h>
+
+
+#ifdef HAVE_PLURAL
+#include <polys/nc/nc.h>
+#endif
+
+/*2
+*shifts the variables between minvar and maxvar of p  \in p_ring to the
+*first maxvar-minvar+1 variables in the actual ring
+*be carefull: there is no range check for the variables of p
+*/
+static poly pChangeSizeOfPoly(ring p_ring, poly p,int minvar,int maxvar, const ring dst_r)
+{
+  int i;
+  poly result = NULL,resultWorkP;
+  number n;
+
+  if (p==NULL) return result;
+  else result = p_Init(dst_r);
+  resultWorkP = result;
+  while (p!=NULL)
+  {
+    for (i=minvar;i<=maxvar;i++)
+      p_SetExp(resultWorkP,i-minvar+1,p_GetExp(p,i,p_ring),dst_r);
+    p_SetComp(resultWorkP,p_GetComp(p,p_ring),dst_r);
+    n=n_Copy(pGetCoeff(p),dst_r->cf);
+    p_SetCoeff(resultWorkP,n,dst_r);
+    p_Setm(resultWorkP,dst_r);
+    pIter(p);
+    if (p!=NULL)
+    {
+      pNext(resultWorkP) = p_Init(dst_r);
+      pIter(resultWorkP);
+    }
+  }
+  return result;
+}
+
+
+
+/*2
+*returns the preimage of id under theMap,
+*if id is empty or zero the kernel is computed
+* (assumes) that both ring have the same coeff.field
+*/
+ideal maGetPreimage(ring theImageRing, map theMap, ideal id, const ring dst_r)
+{
+  ring sourcering = dst_r;
+
+#ifdef HAVE_PLURAL
+  if (rIsPluralRing(theImageRing))
+  {
+    if ((rIsPluralRing(sourcering)) && (ncRingType(sourcering)!=nc_comm))
+    {
+      Werror("Sorry, not yet implemented for noncomm. rings");
+      return NULL;
+    }
+  }
+#endif
+
+  int i,j;
+  poly p,/*pp,*/q;
+  ideal temp1;
+  ideal temp2;
+
+  int imagepvariables = rVar(theImageRing);
+  int N = rVar(dst_r)+imagepvariables;
+
+  ring tmpR;
+  if (rSumInternal(theImageRing,sourcering,tmpR,FALSE,TRUE)!=1)
+  {
+     WerrorS("error in rSumInternal");
+     return NULL;
+  }
+
+  assume(n_SetMap(theImageRing->cf, dst_r->cf) == ndCopyMap);
+
+  if (theImageRing->cf != dst_r->cf)
+  {
+    /// TODO: there might be extreme cases where this doesn't hold...
+    Werror("Coefficient fields/rings must be equal");
+    return NULL;
+  }
+
+  const ring save_ring = currRing; if (currRing!=tmpR) rChangeCurrRing(tmpR); // due to kStd
+
+  if (id==NULL)
+    j = 0;
+  else
+    j = IDELEMS(id);
+  int j0=j;
+  if (theImageRing->qideal!=NULL) j+=IDELEMS(theImageRing->qideal);
+  temp1 = idInit(sourcering->N+j,1);
+  for (i=0;i<sourcering->N;i++)
+  {
+    q = p_ISet(-1,tmpR);
+    p_SetExp(q,i+1+imagepvariables,1,tmpR);
+    p_Setm(q,tmpR);
+    if ((i<IDELEMS(theMap)) && (theMap->m[i]!=NULL))
+    {
+      p = p_SortMerge(
+                      pChangeSizeOfPoly(theImageRing, theMap->m[i], 1, imagepvariables, tmpR),
+                      tmpR);
+      p=p_Add_q(p,q,tmpR);
+    }
+    else
+    {
+      p = q;
+    }
+    temp1->m[i] = p;
+  }
+  id_Test(temp1, tmpR);
+  for (i=sourcering->N;i<sourcering->N+j0;i++)
+  {
+    temp1->m[i] = p_SortMerge(
+                              pChangeSizeOfPoly(theImageRing, id->m[i-sourcering->N], 1, imagepvariables, tmpR),
+                              tmpR);
+  }
+  for (i=sourcering->N+j0;i<sourcering->N+j;i++)
+  {
+    temp1->m[i] = p_SortMerge(
+                              pChangeSizeOfPoly(theImageRing, theImageRing->qideal->m[i-sourcering->N-j0], 1, imagepvariables, tmpR),
+                              tmpR);
+  }
+  // we ignore here homogenity - may be changed later:
+
+  temp2 = kStd(temp1,NULL,isNotHomog,NULL);
+
+  id_Delete(&temp1,tmpR);
+  for (i=0;i<IDELEMS(temp2);i++)
+  {
+    if (p_LowVar(temp2->m[i], currRing)<imagepvariables) p_Delete(&(temp2->m[i]),tmpR);
+  }
+
+  // let's get back to the original ring
+  //rChangeCurrRing(sourcering);
+  temp1 = idInit(5,1);
+  j = 0;
+  for (i=0;i<IDELEMS(temp2);i++)
+  {
+    p = temp2->m[i];
+    if (p!=NULL)
+    {
+      q = p_SortMerge(
+                      pChangeSizeOfPoly(tmpR, p, imagepvariables+1, N, sourcering),
+                      sourcering);
+      if (j>=IDELEMS(temp1))
+      {
+        pEnlargeSet(&(temp1->m),IDELEMS(temp1),5);
+        IDELEMS(temp1)+=5;
+      }
+      temp1->m[j] = q;
+      j++;
+    }
+  }
+  id_Delete(&temp2, tmpR);
+  idSkipZeroes(temp1);
+
+  if (currRing!=save_ring) rChangeCurrRing(save_ring);
+
+  rDelete(tmpR);
+  return temp1;
+}
+
diff --git a/kernel/preimage.h b/kernel/preimage.h
new file mode 100644
index 0000000..6d319ef
--- /dev/null
+++ b/kernel/preimage.h
@@ -0,0 +1,10 @@
+#ifndef KERNEL_PREIMAGE_H
+#define KERNEL_PREIMAGE_H
+
+struct ip_sring; typedef struct ip_sring * ring;
+struct sip_sideal; typedef struct sip_sideal * ideal;
+struct sip_smap; typedef struct sip_smap *          map;
+
+ideal maGetPreimage(ring theImageRing, map theMap, ideal id, const ring dst_r);
+
+#endif // KERNEL_PREIMAGE_H
diff --git a/kernel/spectrum/GMPrat.cc b/kernel/spectrum/GMPrat.cc
new file mode 100644
index 0000000..edb7d89
--- /dev/null
+++ b/kernel/spectrum/GMPrat.cc
@@ -0,0 +1,548 @@
+// ----------------------------------------------------------------------------
+//  GMPrat.cc
+//  begin of file
+//  originally written by Gerd Sussner, sussner at mi.uni-erlangen.de
+//  copied by Stephan Endrass, endrass at mathematik.uni-mainz.de
+//  23.7.99
+// ----------------------------------------------------------------------------
+
+#define  GMPRAT_CC
+
+
+
+
+#include <kernel/mod2.h>
+
+#ifdef HAVE_SPECTRUM
+
+#ifdef   GMPRAT_PRINT
+#include <iostream.h>
+#ifndef  GMPRAT_IOSTREAM
+#include <stdio.h>
+#endif
+#endif
+
+#include <stdlib.h>
+#include <math.h>
+#include <ctype.h>
+#include <string.h>
+
+#include <kernel/spectrum/GMPrat.h>
+
+// ----------------------------------------------------------------------------
+//  disconnect a rational from its reference
+// ----------------------------------------------------------------------------
+
+void    Rational::disconnect()
+{
+    if( p->n>1)
+    {
+        rep *old_p = p;
+        p->n--;
+        p = new rep;
+        mpq_init(p->rat);
+        mpq_set(p->rat, old_p->rat);
+    }
+}
+
+// ----------------------------------------------------------------------------
+//  Constructors
+// ----------------------------------------------------------------------------
+
+Rational::Rational( )
+{
+    p = new rep;
+    mpq_init( p->rat );
+}
+
+Rational::Rational( int a )
+{
+    p = new rep;
+    mpq_init( p->rat );
+    mpq_set_si( p->rat,(long)a,1 );
+}
+
+Rational::Rational( const Rational& a )
+{
+    a.p->n++;
+    p=a.p;
+}
+
+// ----------------------------------------------------------------------------
+//  Constructors with two arguments: numerator and denominator
+// ----------------------------------------------------------------------------
+
+Rational::Rational(const Rational& a, const Rational& b)
+{
+    p=new rep;
+    mpq_init(p->rat);
+    mpq_div(p->rat, a.p->rat, b.p->rat);
+}
+
+Rational::Rational(int a, int b)
+{
+    if (b<0) a=-a;
+    p=new rep;
+    mpq_init(p->rat);
+    mpq_set_si(p->rat,(long) a,(unsigned long) abs(b));
+    mpq_canonicalize(p->rat);
+}
+
+// ----------------------------------------------------------------------------
+//  Destructor
+// ----------------------------------------------------------------------------
+
+Rational::~Rational()
+{
+  if (--(p->n)==0)
+  {
+    mpq_clear(p->rat);
+    delete p;
+  }
+}
+
+// ----------------------------------------------------------------------------
+//  Assignment operators
+// ----------------------------------------------------------------------------
+
+Rational& Rational::operator=(int a)
+{
+  if( p->n>1)
+  {
+    p->n--;
+    p = new rep;
+    mpq_init(p->rat);
+  }
+  mpq_set_si(p->rat,(long) a,1);
+  return *this;
+}
+
+Rational& Rational::operator=(const Rational& a)
+{
+  a.p->n++;
+  if (--(p->n)==0)
+  {
+    mpq_clear(p->rat);
+    delete p;
+  }
+  p=a.p;
+  return *this;
+}
+
+// ----------------------------------------------------------------------------
+//  Numerator and denominator
+// ----------------------------------------------------------------------------
+
+Rational Rational::get_num( )
+{
+    Rational erg;
+
+    mpq_set_num( erg.p->rat,mpq_numref( p->rat ) );
+
+    return  erg;
+}
+
+int Rational::get_num_si( )
+{
+    return  mpz_get_si( mpq_numref( p->rat ) );
+}
+
+Rational Rational::get_den( )
+{
+    Rational erg;
+
+    mpq_set_num( erg.p->rat,mpq_denref( p->rat ) );
+
+    return  erg;
+}
+
+int Rational::get_den_si( )
+{
+    return  mpz_get_si( mpq_denref( p->rat ) );
+}
+
+// ----------------------------------------------------------------------------
+//  Casting
+// ----------------------------------------------------------------------------
+
+Rational::operator int()
+{
+  mpz_t h;
+  long ret_val;
+
+  mpz_init(h);
+  mpz_tdiv_q(h,mpq_numref(p->rat),mpq_denref(p->rat));
+  ret_val=mpz_get_si(h);
+  mpz_clear(h);
+
+  return ret_val;
+}
+
+// ----------------------------------------------------------------------------
+//  Unary minus
+// ----------------------------------------------------------------------------
+
+Rational
+Rational::operator-()
+{
+  Rational erg;
+
+  mpq_neg(erg.p->rat,p->rat);
+  return erg;
+}
+
+Rational operator - ( const Rational &r )
+{
+  Rational erg;
+
+  mpq_neg(erg.p->rat,r.p->rat);
+  return erg;
+}
+
+// ----------------------------------------------------------------------------
+//  Inverse
+// ----------------------------------------------------------------------------
+
+Rational
+Rational::operator~()
+{
+  Rational erg;
+
+  mpq_inv(erg.p->rat,p->rat);
+  return erg;
+}
+
+// ----------------------------------------------------------------------------
+//  +=, -= ...
+// ----------------------------------------------------------------------------
+
+Rational&
+Rational::operator+=(const Rational &a)
+{
+  disconnect();
+  mpq_add(p->rat,p->rat,a.p->rat);
+  return *this;
+}
+
+Rational&
+Rational::operator-=(const Rational &a)
+{
+  disconnect();
+  mpq_sub(p->rat,p->rat,a.p->rat);
+  return *this;
+}
+
+Rational&
+Rational::operator*=(const Rational &a)
+{
+  disconnect();
+  mpq_mul(p->rat,p->rat,a.p->rat);
+  return *this;
+}
+
+Rational&
+Rational::operator/=(const Rational &a)
+{
+  disconnect();
+  mpq_div(p->rat,p->rat,a.p->rat);
+  return *this;
+}
+
+// ----------------------------------------------------------------------------
+//  Increment and decrement
+// ----------------------------------------------------------------------------
+
+Rational&
+Rational::operator++()
+{
+  disconnect();
+  mpz_add(mpq_numref(p->rat), mpq_numref(p->rat), mpq_denref(p->rat));
+  return *this;
+}
+
+Rational
+Rational::operator++(int)
+{
+  Rational erg(*this);
+
+  disconnect();
+  mpz_add(mpq_numref(p->rat), mpq_numref(p->rat), mpq_denref(p->rat));
+  return erg;
+}
+
+Rational&
+Rational::operator--()
+{
+  disconnect();
+  mpz_sub(mpq_numref(p->rat), mpq_numref(p->rat), mpq_denref(p->rat));
+  return *this;
+}
+
+Rational
+Rational::operator--(int)
+{
+  Rational erg(*this);
+
+  disconnect();
+  mpz_sub(mpq_numref(p->rat), mpq_numref(p->rat), mpq_denref(p->rat));
+  return erg;
+}
+
+// ----------------------------------------------------------------------------
+//  Relational operators
+// ----------------------------------------------------------------------------
+
+bool operator<(const Rational& a,const Rational& b)
+{
+  if (mpq_cmp(a.p->rat,b.p->rat)<0) return true;
+  return false;
+}
+
+bool operator<=(const Rational& a,const Rational& b)
+{
+  if (mpq_cmp(a.p->rat,b.p->rat)>0) return false;
+  return true;
+}
+
+bool operator>(const Rational& a,const Rational& b)
+{
+  if (mpq_cmp(a.p->rat,b.p->rat)>0) return true;
+  return false;
+}
+
+bool operator>=(const Rational& a,const Rational& b)
+{
+  if (mpq_cmp(a.p->rat,b.p->rat)<0) return false;
+  return true;
+}
+
+bool operator==(const Rational& a,const Rational& b)
+{
+  if (mpq_equal(a.p->rat,b.p->rat)) return true;
+  return false;
+}
+
+bool operator!=(const Rational& a,const Rational& b)
+{
+  if (mpq_equal(a.p->rat,b.p->rat)) return false;
+  return true;
+}
+
+// ----------------------------------------------------------------------------
+//  Ostream
+// ----------------------------------------------------------------------------
+
+#ifdef GMPRAT_PRINT
+ostream& operator<< (ostream& s,const Rational& a)
+{
+    char *snum,*sdenom;
+
+    snum   = mpz_get_str( NULL,10,mpq_numref(a.p->rat) );
+    sdenom = mpz_get_str( NULL,10,mpq_denref(a.p->rat) );
+
+    if( sdenom[0] == '1' && sdenom[1] == '\0' )
+    {
+        #ifdef GMPRAT_IOSTREAM
+            s << snum;
+        #else
+            fprintf( stdout,snum );
+        #endif
+    }
+    else
+    {
+        #ifdef GMPRAT_IOSTREAM
+            s << snum << "/" << sdenom;
+        #else
+            fprintf( stdout,snum );
+            fprintf( stdout,"/" );
+            fprintf( stdout,sdenom );
+        #endif
+    }
+
+    //free( snum );
+    //free( sdenom );
+
+    return s;
+}
+#endif
+
+unsigned int Rational::length( ) const
+{
+    char *snum = (char*)NULL;
+    char *sden = (char*)NULL;
+
+    snum = mpz_get_str( snum,10,mpq_numref( p->rat ) );
+    sden = mpz_get_str( sden,10,mpq_denref( p->rat ) );
+
+    int length = strlen( snum );
+
+    if( sden[0] != '1' || sden[1] != '\0' ) length += strlen( sden ) + 1;
+
+    free( snum );
+    free( sden );
+
+    return  length;
+}
+
+// ----------------------------------------------------------------------------
+//  Operators
+// ----------------------------------------------------------------------------
+
+Rational
+operator+(const Rational& a,const Rational &b)
+{
+  Rational
+    erg(a);
+
+  return erg+=b;
+}
+
+Rational
+operator-(const Rational& a,const Rational &b)
+{
+  Rational
+    erg(a);
+
+  return erg-=b;
+}
+
+Rational
+operator*(const Rational& a,const Rational &b)
+{
+  Rational
+    erg(a);
+
+  return erg*=b;
+}
+
+Rational pow( const Rational& a,int e )
+{
+    Rational erg(1);
+
+    for( int i=0; i<e; i++ )
+    {
+        erg *= a;
+    }
+    return erg;
+}
+
+Rational operator/(const Rational& a,const Rational &b)
+{
+  Rational
+    erg(a);
+
+  return erg/=b;
+}
+
+int sgn(const Rational& a)
+{
+  return mpq_sgn(a.p->rat);
+}
+
+Rational
+abs(const Rational& a)
+{
+  Rational
+    erg;
+
+  if (mpq_sgn(a.p->rat)<0)
+    mpq_neg(erg.p->rat,a.p->rat);
+  else
+    mpq_set(erg.p->rat,a.p->rat);
+  return erg;
+}
+
+Rational gcd( const Rational &a,const Rational &b )
+{
+    if( a == 0 )
+    {
+        if( b == 0 )
+        {
+            return  (Rational)1;
+        }
+        else
+        {
+            return  abs( b );
+        }
+    }
+    else if( b == 0 )
+    {
+        return  abs( a );
+    }
+
+    Rational erg;
+
+    mpz_gcd( mpq_numref( erg.p->rat ),
+            mpq_numref( a.p->rat ),mpq_numref( b.p->rat ) );
+    mpz_gcd( mpq_denref( erg.p->rat ),
+            mpq_denref( a.p->rat ),mpq_denref( b.p->rat ) );
+
+    //mpq_canonicalize( erg.p->rat );
+
+    return  abs( erg );
+}
+
+Rational gcd( Rational *a,int n )
+{
+    if( n == 1 )
+    {
+        return  a[0];
+    }
+
+    Rational g = gcd( a[0],a[1] );
+
+    for( int i=2; i<n; i++ )
+    {
+        g = gcd( g,a[i] );
+    }
+
+    return  g;
+}
+
+Rational lcm( const Rational &a,const Rational &b )
+{
+    if( a == 0 )
+    {
+        return b;
+    }
+    else if( b == 0 )
+    {
+        return a;
+    }
+
+    return a*b/gcd(a,b);
+}
+
+Rational lcm( Rational *a,int n )
+{
+    if( n == 1 )
+    {
+        return  a[0];
+    }
+
+    Rational g = lcm( a[0],a[1] );
+
+    for( int i=2; i<n; i++ )
+    {
+        g = lcm( g,a[i] );
+    }
+
+    return  g;
+}
+
+double  Rational::complexity( ) const
+{
+    double num = mpz_get_d( mpq_numref( p->rat ) );
+    double den = mpz_get_d( mpq_denref( p->rat ) );
+
+    if( num < 0 ) num = -num;
+    if( den < 0 ) den = -den;
+
+    return  ( num > den ? num : den );
+}
+
+#endif /* HAVE_SPECTRUM */
+// ----------------------------------------------------------------------------
+//  GMPrat.cc
+//  end of file
+// ----------------------------------------------------------------------------
diff --git a/kernel/spectrum/GMPrat.h b/kernel/spectrum/GMPrat.h
new file mode 100644
index 0000000..8701d7c
--- /dev/null
+++ b/kernel/spectrum/GMPrat.h
@@ -0,0 +1,94 @@
+// ----------------------------------------------------------------------------
+//  GMPrat.h
+//  begin of file
+//  originally written by Gerd Sussner, sussner at mi.uni-erlangen.de
+//  copied by Stephan Endrass, endrass at mathematik.uni-mainz.de
+//  23.7.99
+// ----------------------------------------------------------------------------
+
+#ifndef  GMPRAT_H
+#define  GMPRAT_H
+
+#include <coeffs/si_gmp.h>
+
+class Rational
+{
+    struct rep
+    {
+        mpq_t rat;
+        int   n;
+        rep() { n=1; }
+    };
+
+    rep             *p;
+
+    void disconnect();
+
+    public:
+
+    Rational( );
+    Rational( int );
+    Rational( const Rational& );
+    Rational( const Rational&,const Rational& );
+    Rational( int,int );
+    ~Rational( );
+
+    Rational& operator = ( int );
+    Rational& operator = ( char *s );
+    Rational& operator = ( const Rational& );
+
+    unsigned int length( ) const;
+    Rational get_num( );
+    Rational get_den( );
+    int      get_num_si( );
+    int      get_den_si( );
+    operator int( );
+
+    Rational  operator - ( );
+    Rational  operator ~ ( );
+    Rational& operator += ( const Rational& );
+    Rational& operator -= ( const Rational& );
+    Rational& operator *= ( const Rational& );
+    Rational& operator /= ( const Rational& );
+    Rational& operator ++ ( );
+    Rational  operator ++ ( int );
+    Rational& operator -- ( );
+    Rational  operator -- ( int );
+
+    friend Rational operator - ( const Rational& );
+
+    friend bool operator <  ( const Rational&,const Rational& );
+    friend bool operator <= ( const Rational&,const Rational& );
+    friend bool operator >  ( const Rational&,const Rational& );
+    friend bool operator >= ( const Rational&,const Rational& );
+    friend bool operator == ( const Rational&,const Rational& );
+    friend bool operator != ( const Rational&,const Rational& );
+
+    #ifdef GMPRAT_PRINT
+    friend ostream& operator<<( ostream&,const Rational& );
+    #endif
+
+    friend int      sgn ( const Rational& );
+    friend Rational abs ( const Rational& );
+    friend Rational pow ( const Rational&,int );
+
+    double   complexity( ) const;
+
+    friend Rational gcd ( const Rational&, const Rational& );
+    friend Rational lcm ( const Rational&, const Rational& );
+    friend Rational gcd ( Rational*, int );
+    friend Rational lcm ( Rational*, int );
+};
+
+Rational operator + ( const Rational&, const Rational& );
+Rational operator - ( const Rational&, const Rational& );
+Rational operator * ( const Rational&, const Rational& );
+Rational operator / ( const Rational&, const Rational& );
+
+#endif /* GMPRAT_H */
+
+// ----------------------------------------------------------------------------
+//  GMPrat.h
+//  end of file
+// ----------------------------------------------------------------------------
+
diff --git a/kernel/spectrum/Makefile.am b/kernel/spectrum/Makefile.am
new file mode 100644
index 0000000..69094fd
--- /dev/null
+++ b/kernel/spectrum/Makefile.am
@@ -0,0 +1,22 @@
+ACLOCAL_AMFLAGS=-I ../../m4
+AM_CPPFLAGS=-I${top_srcdir} -I${top_builddir} -I${top_srcdir}/libpolys -I${top_builddir}/libpolys \
+${FACTORY_INCLUDES} $(OMALLOC_INCLUDES) $(RESOURCES_INCLUDES) \
+${NTL_CFLAGS} $(FLINT_CFLAGS) ${GMP_CFLAGS}
+
+noinst_LTLIBRARIES=libspectrum.la
+libspectrum_la_SOURCES=GMPrat.cc multicnt.cc npolygon.cc semic.cc spectrum.cc splist.cc
+
+libspectrum_la_includedir=$(includedir)/singular/kernel/spectrum
+libspectrum_la_include_HEADERS=GMPrat.h multicnt.h npolygon.h semic.h spectrum.h splist.h kmatrix.h
+
+
+
+TESTS_ENVIRONMENT = SINGULARPATH='${abs_top_builddir}/libpolys/polys/.libs:${abs_top_builddir}/factory/gftables'
+TESTS_ENVIRONMENT += SINGULAR_ROOT_DIR='${abs_top_builddir}'
+
+TESTS = test
+check_PROGRAMS = $(TESTS)
+test_SOURCES = test.cc
+test_LDADD   = libspectrum.la ${builddir}/../libkernelCommon.la
+
+CLEANFILES = $(TESTS)
diff --git a/kernel/spectrum/Makefile.in b/kernel/spectrum/Makefile.in
new file mode 100644
index 0000000..36c32d4
--- /dev/null
+++ b/kernel/spectrum/Makefile.in
@@ -0,0 +1,1088 @@
+# Makefile.in generated by automake 1.13.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 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@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+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@
+TESTS = test$(EXEEXT)
+check_PROGRAMS = $(am__EXEEXT_1)
+subdir = kernel/spectrum
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/build-aux/depcomp \
+	$(libspectrum_la_include_HEADERS) \
+	$(top_srcdir)/build-aux/test-driver
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_append_compile_flags.m4 \
+	$(top_srcdir)/m4/ax_append_flag.m4 \
+	$(top_srcdir)/m4/ax_append_link_flags.m4 \
+	$(top_srcdir)/m4/ax_check_compile_flag.m4 \
+	$(top_srcdir)/m4/ax_check_link_flag.m4 \
+	$(top_srcdir)/m4/ax_compute_relative_paths.m4 \
+	$(top_srcdir)/m4/ax_normalize_path.m4 \
+	$(top_srcdir)/m4/ax_prefix_config_h.m4 \
+	$(top_srcdir)/m4/ax_pthread.m4 \
+	$(top_srcdir)/m4/ax_python_embed.m4 \
+	$(top_srcdir)/m4/ax_python_with_version.m4 \
+	$(top_srcdir)/m4/cpu-check.m4 $(top_srcdir)/m4/dbm-check.m4 \
+	$(top_srcdir)/m4/flags.m4 $(top_srcdir)/m4/flint-check.m4 \
+	$(top_srcdir)/m4/gfanlib-check.m4 \
+	$(top_srcdir)/m4/gmp-check.m4 \
+	$(top_srcdir)/m4/google-perftools.m4 \
+	$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+	$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+	$(top_srcdir)/m4/lt~obsolete.m4 \
+	$(top_srcdir)/m4/mathic-check.m4 $(top_srcdir)/m4/ntl-check.m4 \
+	$(top_srcdir)/m4/options.m4 $(top_srcdir)/m4/p-procs.m4 \
+	$(top_srcdir)/m4/polymake-check.m4 \
+	$(top_srcdir)/m4/readline-check.m4 $(top_srcdir)/configure.ac
+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 =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+libspectrum_la_LIBADD =
+am_libspectrum_la_OBJECTS = GMPrat.lo multicnt.lo npolygon.lo semic.lo \
+	spectrum.lo splist.lo
+libspectrum_la_OBJECTS = $(am_libspectrum_la_OBJECTS)
+AM_V_lt = $(am__v_lt_ at AM_V@)
+am__v_lt_ = $(am__v_lt_ at AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 = 
+am__EXEEXT_1 = test$(EXEEXT)
+am_test_OBJECTS = test.$(OBJEXT)
+test_OBJECTS = $(am_test_OBJECTS)
+test_DEPENDENCIES = libspectrum.la ${builddir}/../libkernelCommon.la
+AM_V_P = $(am__v_P_ at AM_V@)
+am__v_P_ = $(am__v_P_ at AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_ at AM_V@)
+am__v_GEN_ = $(am__v_GEN_ at AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_ at AM_V@)
+am__v_at_ = $(am__v_at_ at AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+DEFAULT_INCLUDES = -I. at am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \
+	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+	$(AM_CXXFLAGS) $(CXXFLAGS)
+AM_V_CXX = $(am__v_CXX_ at AM_V@)
+am__v_CXX_ = $(am__v_CXX_ at AM_DEFAULT_V@)
+am__v_CXX_0 = @echo "  CXX     " $@;
+am__v_CXX_1 = 
+CXXLD = $(CXX)
+CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+	$(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CXXLD = $(am__v_CXXLD_ at AM_V@)
+am__v_CXXLD_ = $(am__v_CXXLD_ at AM_DEFAULT_V@)
+am__v_CXXLD_0 = @echo "  CXXLD   " $@;
+am__v_CXXLD_1 = 
+SOURCES = $(libspectrum_la_SOURCES) $(test_SOURCES)
+DIST_SOURCES = $(libspectrum_la_SOURCES) $(test_SOURCES)
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+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__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
+am__installdirs = "$(DESTDIR)$(libspectrum_la_includedir)"
+HEADERS = $(libspectrum_la_include_HEADERS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors_dummy = \
+  mgn= red= grn= lgn= blu= brg= std=; \
+  am__color_tests=no
+am__tty_colors = { \
+  $(am__tty_colors_dummy); \
+  if test "X$(AM_COLOR_TESTS)" = Xno; then \
+    am__color_tests=no; \
+  elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+    am__color_tests=yes; \
+  elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+    am__color_tests=yes; \
+  fi; \
+  if test $$am__color_tests = yes; then \
+    red=''; \
+    grn=''; \
+    lgn=''; \
+    blu=''; \
+    mgn=''; \
+    brg=''; \
+    std=''; \
+  fi; \
+}
+am__recheck_rx = ^[ 	]*:recheck:[ 	]*
+am__global_test_result_rx = ^[ 	]*:global-test-result:[ 	]*
+am__copy_in_global_log_rx = ^[ 	]*:copy-in-global-log:[ 	]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+  recheck = 1; \
+  while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+    { \
+      if (rc < 0) \
+        { \
+          if ((getline line2 < ($$0 ".log")) < 0) \
+	    recheck = 0; \
+          break; \
+        } \
+      else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+        { \
+          recheck = 0; \
+          break; \
+        } \
+      else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+        { \
+          break; \
+        } \
+    }; \
+  if (recheck) \
+    print $$0; \
+  close ($$0 ".trs"); \
+  close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+  print "fatal: making $@: " msg | "cat >&2"; \
+  exit 1; \
+} \
+function rst_section(header) \
+{ \
+  print header; \
+  len = length(header); \
+  for (i = 1; i <= len; i = i + 1) \
+    printf "="; \
+  printf "\n\n"; \
+} \
+{ \
+  copy_in_global_log = 1; \
+  global_test_result = "RUN"; \
+  while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+    { \
+      if (rc < 0) \
+         fatal("failed to read from " $$0 ".trs"); \
+      if (line ~ /$(am__global_test_result_rx)/) \
+        { \
+          sub("$(am__global_test_result_rx)", "", line); \
+          sub("[ 	]*$$", "", line); \
+          global_test_result = line; \
+        } \
+      else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+        copy_in_global_log = 0; \
+    }; \
+  if (copy_in_global_log) \
+    { \
+      rst_section(global_test_result ": " $$0); \
+      while ((rc = (getline line < ($$0 ".log"))) != 0) \
+      { \
+        if (rc < 0) \
+          fatal("failed to read from " $$0 ".log"); \
+        print line; \
+      }; \
+      printf "\n"; \
+    }; \
+  close ($$0 ".trs"); \
+  close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/   &   /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this.  Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+  --color-tests "$$am__color_tests" \
+  --enable-hard-errors "$$am__enable_hard_errors" \
+  --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test.  Creates the
+# directory for the log if needed.  Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log.  Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT.  Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup);					\
+$(am__vpath_adj_setup) $(am__vpath_adj)			\
+$(am__tty_colors);					\
+srcdir=$(srcdir); export srcdir;			\
+case "$@" in						\
+  */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;;	\
+    *) am__odir=.;; 					\
+esac;							\
+test "x$$am__odir" = x"." || test -d "$$am__odir" 	\
+  || $(MKDIR_P) "$$am__odir" || exit $$?;		\
+if test -f "./$$f"; then dir=./;			\
+elif test -f "$$f"; then dir=;				\
+else dir="$(srcdir)/"; fi;				\
+tst=$$dir$$f; log='$@'; 				\
+if test -n '$(DISABLE_HARD_ERRORS)'; then		\
+  am__enable_hard_errors=no; 				\
+else							\
+  am__enable_hard_errors=yes; 				\
+fi; 							\
+case " $(XFAIL_TESTS) " in				\
+  *[\ \	]$$f[\ \	]* | *[\ \	]$$dir$$f[\ \	]*) \
+    am__expect_failure=yes;;				\
+  *)							\
+    am__expect_failure=no;;				\
+esac; 							\
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed).  The result is saved in the shell variable
+# '$bases'.  This honors runtime overriding of TESTS and TEST_LOGS.  Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+  bases='$(TEST_LOGS)'; \
+  bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+  bases=`echo $$bases`
+RECHECK_LOGS = $(TEST_LOGS)
+AM_RECURSIVE_TARGETS = check recheck
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+  case '$@' in \
+    */*) \
+      case '$*' in \
+        */*) b='$*';; \
+          *) b=`echo '$@' | sed 's/\.log$$//'`; \
+       esac;; \
+    *) \
+      b='$*';; \
+  esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT at .log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+	$(TEST_LOG_FLAGS)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BUILTIN_LIBS = @BUILTIN_LIBS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CDDGMPCPPFLAGS = @CDDGMPCPPFLAGS@
+CDDGMPLDFLAGS = @CDDGMPLDFLAGS@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATA_DIR = @DATA_DIR@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DOC_DIR = @DOC_DIR@
+DOXYGEN = @DOXYGEN@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FACTORY_INCLUDES = @FACTORY_INCLUDES@
+FACTORY_LIBS = @FACTORY_LIBS@
+FGREP = @FGREP@
+FLINT_CFLAGS = @FLINT_CFLAGS@
+FLINT_HOME = @FLINT_HOME@
+FLINT_LIBS = @FLINT_LIBS@
+GMP_CFLAGS = @GMP_CFLAGS@
+GMP_HOME = @GMP_HOME@
+GMP_LIBS = @GMP_LIBS@
+GMP_VERSION = @GMP_VERSION@
+GREP = @GREP@
+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@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NTL_CFLAGS = @NTL_CFLAGS@
+NTL_LIBS = @NTL_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OMALLOC_INCLUDES = @OMALLOC_INCLUDES@
+OMALLOC_LIBS = @OMALLOC_LIBS@
+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@
+PKG_REQUIRE = @PKG_REQUIRE@
+PMCONFIG = @PMCONFIG@
+PM_CFLAGS = @PM_CFLAGS@
+PM_INC = @PM_INC@
+PM_LDFLAGS = @PM_LDFLAGS@
+PM_LIBS = @PM_LIBS@
+POLYMAKE_CXXFLAGS = @POLYMAKE_CXXFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LDFLAGS = @PTHREAD_LDFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
+PYTHON = @PYTHON@
+PYTHON_CSPEC = @PYTHON_CSPEC@
+PYTHON_EXECPREFIX = @PYTHON_EXECPREFIX@
+PYTHON_LSPEC = @PYTHON_LSPEC@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+RANLIB = @RANLIB@
+RESOURCES_INCLUDES = @RESOURCES_INCLUDES@
+RESOURCES_LIBS = @RESOURCES_LIBS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SINGULAR_CFLAGS = @SINGULAR_CFLAGS@
+SI_COUNTEDREF_AUTOLOAD = @SI_COUNTEDREF_AUTOLOAD@
+SI_CPU_I386 = @SI_CPU_I386@
+SI_CPU_IA64 = @SI_CPU_IA64@
+SI_CPU_PPC = @SI_CPU_PPC@
+SI_CPU_SPARC = @SI_CPU_SPARC@
+SI_CPU_X86_64 = @SI_CPU_X86_64@
+STRIP = @STRIP@
+USEPPROCSDYNAMICLD = @USEPPROCSDYNAMICLD@
+USEPPROCSDYNAMICLDFLAGS = @USEPPROCSDYNAMICLDFLAGS@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
+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@
+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@
+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@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+ACLOCAL_AMFLAGS = -I ../../m4
+AM_CPPFLAGS = -I${top_srcdir} -I${top_builddir} -I${top_srcdir}/libpolys -I${top_builddir}/libpolys \
+${FACTORY_INCLUDES} $(OMALLOC_INCLUDES) $(RESOURCES_INCLUDES) \
+${NTL_CFLAGS} $(FLINT_CFLAGS) ${GMP_CFLAGS}
+
+noinst_LTLIBRARIES = libspectrum.la
+libspectrum_la_SOURCES = GMPrat.cc multicnt.cc npolygon.cc semic.cc spectrum.cc splist.cc
+libspectrum_la_includedir = $(includedir)/singular/kernel/spectrum
+libspectrum_la_include_HEADERS = GMPrat.h multicnt.h npolygon.h semic.h spectrum.h splist.h kmatrix.h
+TESTS_ENVIRONMENT = SINGULARPATH='${abs_top_builddir}/libpolys/polys/.libs:${abs_top_builddir}/factory/gftables' \
+	SINGULAR_ROOT_DIR='${abs_top_builddir}'
+test_SOURCES = test.cc
+test_LDADD = libspectrum.la ${builddir}/../libkernelCommon.la
+CLEANFILES = $(TESTS)
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .cc .lo .log .o .obj .test .test$(EXEEXT) .trs
+$(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) --foreign kernel/spectrum/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign kernel/spectrum/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-noinstLTLIBRARIES:
+	-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+	@list='$(noinst_LTLIBRARIES)'; \
+	locs=`for p in $$list; do echo $$p; done | \
+	      sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+	      sort -u`; \
+	test -z "$$locs" || { \
+	  echo rm -f $${locs}; \
+	  rm -f $${locs}; \
+	}
+
+libspectrum.la: $(libspectrum_la_OBJECTS) $(libspectrum_la_DEPENDENCIES) $(EXTRA_libspectrum_la_DEPENDENCIES) 
+	$(AM_V_CXXLD)$(CXXLINK)  $(libspectrum_la_OBJECTS) $(libspectrum_la_LIBADD) $(LIBS)
+
+clean-checkPROGRAMS:
+	@list='$(check_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
+
+test$(EXEEXT): $(test_OBJECTS) $(test_DEPENDENCIES) $(EXTRA_test_DEPENDENCIES) 
+	@rm -f test$(EXEEXT)
+	$(AM_V_CXXLD)$(CXXLINK) $(test_OBJECTS) $(test_LDADD) $(LIBS)
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/GMPrat.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/multicnt.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/npolygon.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/semic.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/spectrum.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/splist.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/test.Po at am__quote@
+
+.cc.o:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+ at am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXXCOMPILE) -c -o $@ $<
+
+.cc.obj:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+ at am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.cc.lo:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+ at am__fastdepCXX_TRUE@	$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LTCXXCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+install-libspectrum_la_includeHEADERS: $(libspectrum_la_include_HEADERS)
+	@$(NORMAL_INSTALL)
+	@list='$(libspectrum_la_include_HEADERS)'; test -n "$(libspectrum_la_includedir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(libspectrum_la_includedir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(libspectrum_la_includedir)" || exit 1; \
+	fi; \
+	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)$(libspectrum_la_includedir)'"; \
+	  $(INSTALL_HEADER) $$files "$(DESTDIR)$(libspectrum_la_includedir)" || exit $$?; \
+	done
+
+uninstall-libspectrum_la_includeHEADERS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(libspectrum_la_include_HEADERS)'; test -n "$(libspectrum_la_includedir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	dir='$(DESTDIR)$(libspectrum_la_includedir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	$(am__define_uniq_tagged_files); \
+	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-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	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"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'.  Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+	rm -f $< $@
+	$(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+	@:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+	@$(am__set_TESTS_bases); \
+	am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+	redo_bases=`for i in $$bases; do \
+	              am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+	            done`; \
+	if test -n "$$redo_bases"; then \
+	  redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+	  redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+	  if $(am__make_dryrun); then :; else \
+	    rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+	  fi; \
+	fi; \
+	if test -n "$$am__remaking_logs"; then \
+	  echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+	       "recursion detected" >&2; \
+	else \
+	  am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+	fi; \
+	if $(am__make_dryrun); then :; else \
+	  st=0;  \
+	  errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+	  for i in $$redo_bases; do \
+	    test -f $$i.trs && test -r $$i.trs \
+	      || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+	    test -f $$i.log && test -r $$i.log \
+	      || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+	  done; \
+	  test $$st -eq 0 || exit 1; \
+	fi
+	@$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+	ws='[ 	]'; \
+	results=`for b in $$bases; do echo $$b.trs; done`; \
+	test -n "$$results" || results=/dev/null; \
+	all=`  grep "^$$ws*:test-result:"           $$results | wc -l`; \
+	pass=` grep "^$$ws*:test-result:$$ws*PASS"  $$results | wc -l`; \
+	fail=` grep "^$$ws*:test-result:$$ws*FAIL"  $$results | wc -l`; \
+	skip=` grep "^$$ws*:test-result:$$ws*SKIP"  $$results | wc -l`; \
+	xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+	xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+	error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+	if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+	  success=true; \
+	else \
+	  success=false; \
+	fi; \
+	br='==================='; br=$$br$$br$$br$$br; \
+	result_count () \
+	{ \
+	    if test x"$$1" = x"--maybe-color"; then \
+	      maybe_colorize=yes; \
+	    elif test x"$$1" = x"--no-color"; then \
+	      maybe_colorize=no; \
+	    else \
+	      echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+	    fi; \
+	    shift; \
+	    desc=$$1 count=$$2; \
+	    if test $$maybe_colorize = yes && test $$count -gt 0; then \
+	      color_start=$$3 color_end=$$std; \
+	    else \
+	      color_start= color_end=; \
+	    fi; \
+	    echo "$${color_start}# $$desc $$count$${color_end}"; \
+	}; \
+	create_testsuite_report () \
+	{ \
+	  result_count $$1 "TOTAL:" $$all   "$$brg"; \
+	  result_count $$1 "PASS: " $$pass  "$$grn"; \
+	  result_count $$1 "SKIP: " $$skip  "$$blu"; \
+	  result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+	  result_count $$1 "FAIL: " $$fail  "$$red"; \
+	  result_count $$1 "XPASS:" $$xpass "$$red"; \
+	  result_count $$1 "ERROR:" $$error "$$mgn"; \
+	}; \
+	{								\
+	  echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" |	\
+	    $(am__rst_title);						\
+	  create_testsuite_report --no-color;				\
+	  echo;								\
+	  echo ".. contents:: :depth: 2";				\
+	  echo;								\
+	  for b in $$bases; do echo $$b; done				\
+	    | $(am__create_global_log);					\
+	} >$(TEST_SUITE_LOG).tmp || exit 1;				\
+	mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG);			\
+	if $$success; then						\
+	  col="$$grn";							\
+	 else								\
+	  col="$$red";							\
+	  test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG);		\
+	fi;								\
+	echo "$${col}$$br$${std}"; 					\
+	echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}";	\
+	echo "$${col}$$br$${std}"; 					\
+	create_testsuite_report --maybe-color;				\
+	echo "$$col$$br$$std";						\
+	if $$success; then :; else					\
+	  echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}";		\
+	  if test -n "$(PACKAGE_BUGREPORT)"; then			\
+	    echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}";	\
+	  fi;								\
+	  echo "$$col$$br$$std";					\
+	fi;								\
+	$$success || exit 1
+
+check-TESTS:
+	@list='$(RECHECK_LOGS)';           test -z "$$list" || rm -f $$list
+	@list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+	@test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+	@set +e; $(am__set_TESTS_bases); \
+	log_list=`for i in $$bases; do echo $$i.log; done`; \
+	trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+	log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+	$(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+	exit $$?;
+recheck: all $(check_PROGRAMS)
+	@test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+	@set +e; $(am__set_TESTS_bases); \
+	bases=`for i in $$bases; do echo $$i; done \
+	         | $(am__list_recheck_tests)` || exit 1; \
+	log_list=`for i in $$bases; do echo $$i.log; done`; \
+	log_list=`echo $$log_list`; \
+	$(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+	        am__force_recheck=am--force-recheck \
+	        TEST_LOGS="$$log_list"; \
+	exit $$?
+test.log: test$(EXEEXT)
+	@p='test$(EXEEXT)'; \
+	b='test'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+.test.log:
+	@p='$<'; \
+	$(am__set_b); \
+	$(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+ at am__EXEEXT_TRUE@.test$(EXEEXT).log:
+ at am__EXEEXT_TRUE@	@p='$<'; \
+ at am__EXEEXT_TRUE@	$(am__set_b); \
+ at am__EXEEXT_TRUE@	$(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ at am__EXEEXT_TRUE@	--log-file $$b.log --trs-file $$b.trs \
+ at am__EXEEXT_TRUE@	$(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ at am__EXEEXT_TRUE@	"$$tst" $(AM_TESTS_FD_REDIRECT)
+
+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_PROGRAMS)
+	$(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(HEADERS)
+installdirs:
+	for dir in "$(DESTDIR)$(libspectrum_la_includedir)"; 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:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+	-test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+	-test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+	-test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+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-checkPROGRAMS clean-generic clean-libtool \
+	clean-noinstLTLIBRARIES 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-libspectrum_la_includeHEADERS
+
+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: uninstall-libspectrum_la_includeHEADERS
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am clean \
+	clean-checkPROGRAMS clean-generic clean-libtool \
+	clean-noinstLTLIBRARIES cscopelist-am ctags ctags-am 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-libspectrum_la_includeHEADERS 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 \
+	recheck tags tags-am uninstall uninstall-am \
+	uninstall-libspectrum_la_includeHEADERS
+
+
+# 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/kernel/spectrum/kmatrix.h b/kernel/spectrum/kmatrix.h
new file mode 100644
index 0000000..81acfcc
--- /dev/null
+++ b/kernel/spectrum/kmatrix.h
@@ -0,0 +1,933 @@
+// ----------------------------------------------------------------------------
+//  kmatrix.h
+//  begin of file
+//  Stephan Endrass, endrass at mathematik.uni-mainz.de
+//  23.7.99
+// ----------------------------------------------------------------------------
+
+#ifndef KMATRIX_H
+#define KMATRIX_H
+#include <stdlib.h>
+
+// ----------------------------------------------------------------------------
+//  template class for matrices with coefficients in the field  K
+//  K is a class representing elements of a field
+//  The implementation of  K  is expected to have overloaded
+//  the operators +, -, *, /, +=, -=, *= and /=.
+//  The expressions  (K)0  and (K)1  should cast to the  0  and  1  of  K.
+//  Additionally we use the following functions in class K:
+//
+//    member functions:
+//
+//      double  complexity( void );
+//
+//    friend functions:
+//
+//      friend  K   gcd( const K &a,const K &b );  // gcd(a,b)
+//      friend  K   gcd( K* a,int k );             // gcd(a[0],...,a[k-1])
+//
+//  The complexity function should return a measure indicating
+//  how complicated this number is in terms of memory usage
+//  and arithmetic operations. For a rational p/q, one could
+//  return max(|p|,|q|). This fuction is used for pivoting.
+//
+//  The gcd of two numbers a,b should be a number g such that
+//  the complexities of a/g and b/g are less or equal than those
+//  of a and b. For rationals p1/q1, p2/q2 one could return the
+//  quotient of integer gcd's gcd(p1,p2)/gcd(q1,q2).
+//
+// ----------------------------------------------------------------------------
+
+template<class K> class KMatrix
+{
+
+private:
+
+    K    *a;                                // the entries ot the matrix
+    int rows;                               // number of rows
+    int cols;                               // number of columns
+
+public:
+
+    KMatrix( );                             // init zero
+    KMatrix( const KMatrix& );              // copy constructor
+    KMatrix( int,int );                     // preallocate rows & columns
+
+    ~KMatrix( );                            // destructor
+
+    void    copy_delete ( void );           // delete associated memory
+    void    copy_new    ( int  );           // allocate associated memory
+    void    copy_zero   ( void );           // init zero
+    void    copy_unit   ( int );            // init as unit matrix
+    void    copy_shallow( KMatrix& );       // shallow copy
+    void    copy_deep   ( const KMatrix& ); // deep copy
+
+    K       get( int,int ) const;           // get an element
+    void    set( int,int,const K& );        // set an element
+
+    int     row_is_zero( int ) const;       // test if row is zero
+    int     column_is_zero( int ) const;    // test if column is zero
+
+    int     column_pivot( int,int ) const;
+
+    int     gausseliminate( void );         // Gauss elimination
+    int     rank( void ) const;             // compute the rank
+    int     solve( K**,int* );              // solve Ax=b from (A|b)
+
+    // elementary transformations
+
+    K       multiply_row( int,const K& );
+    K       add_rows( int,int,const K&,const K& );
+    int     swap_rows( int,int );
+    K       set_row_primitive( int );
+
+    int     is_quadratic( void ) const;
+    int     is_symmetric( void ) const;
+
+    K       determinant( void ) const;
+
+    #ifdef KMATRIX_DEBUG
+        void    test_row( int ) const;
+        void    test_col( int ) const;
+    #endif
+
+    #ifdef KMATRIX_PRINT
+        friend  ostream & operator << ( ostream&,const KMatrix& );
+    #endif
+};
+
+// ------------------------------------
+//  inline functions for class KMatrix
+// ------------------------------------
+
+// ----------------------------------------------------------------------------
+//  Delete memory associated to a  KMatrix
+// ----------------------------------------------------------------------------
+
+template<class K>
+    inline  void    KMatrix<K>::copy_delete( void )
+{
+    if( a != (K*)NULL && rows > 0 && cols > 0 ) delete [] a;
+    copy_zero( );
+}
+
+// ----------------------------------------------------------------------------
+//  Allocate memory associated to a  KMatrix
+// ----------------------------------------------------------------------------
+
+template<class K>
+    inline  void    KMatrix<K>::copy_new( int k )
+{
+    if( k > 0 )
+    {
+        a = new K[k];
+
+        #ifndef SING_NDEBUG
+        if( a == (K*)NULL )
+        {
+            #ifdef KMATRIX_PRINT
+            #ifdef KMATRIX_IOSTREAM
+                cerr << "void KMatrix::copy_new( int k )";
+                cerr << ": no memory left ..." << endl;
+            #else
+                fprintf( stderr,"void KMatrix::copy_new( int k )" );
+                fprintf( stderr,": no memory left ...\n" );
+            #endif
+            #endif
+
+            exit( 1 );
+        }
+        #endif
+    }
+    else if( k == 0 )
+    {
+        a = (K*)NULL;
+    }
+    else
+    {
+        #ifdef KMATRIX_PRINT
+        #ifdef KMATRIX_IOSTREAM
+            cerr << "void KMatrix::copy_new( int k )";
+            cerr << ": k < 0 ..." << endl;
+        #else
+            fprintf( stderr,"void KMatrix::copy_new( int k )" );
+            fprintf( stderr,": k < 0 ...\n" );
+        #endif
+        #endif
+
+        exit( 1 );
+    }
+}
+
+// ----------------------------------------------------------------------------
+//  Initialize a  KMatrix  with  0
+// ----------------------------------------------------------------------------
+
+template<class K>
+    inline  void    KMatrix<K>::copy_zero( void )
+{
+    a = (K*)NULL;
+    rows = cols = 0;
+}
+
+// ----------------------------------------------------------------------------
+//  Initialize a  KMatrix  with the unit matrix
+// ----------------------------------------------------------------------------
+
+template<class K>
+    inline  void    KMatrix<K>::copy_unit( int rank )
+{
+    int r,n=rank*rank;
+    copy_new( n );
+    rows = cols = rank;
+
+    for( r=0; r<n; a[r++]=(K)0 );
+
+    for( r=0; r<rows; r++ )
+    {
+        a[r*cols+r] = (K)1;
+    }
+}
+
+// ----------------------------------------------------------------------------
+//  Shallow copy
+// ----------------------------------------------------------------------------
+
+template<class K>
+    inline  void    KMatrix<K>::copy_shallow( KMatrix &m )
+{
+    a = m.a;
+    rows = m.rows;
+    cols = m.cols;
+}
+
+// ----------------------------------------------------------------------------
+//  Deep copy
+// ----------------------------------------------------------------------------
+
+template<class K>
+    inline  void    KMatrix<K>::copy_deep( const KMatrix &m )
+{
+    if( m.a == (K*)NULL )
+    {
+        copy_zero( );
+    }
+    else
+    {
+        int n=m.rows*m.cols;
+        copy_new( n );
+        rows = m.rows;
+        cols = m.cols;
+
+        for( int i=0; i<n; i++ )
+        {
+            a[i] = m.a[i];
+        }
+    }
+}
+
+// ----------------------------------------------------------------------------
+//  Zero constructor
+// ----------------------------------------------------------------------------
+
+template<class K>
+    inline  KMatrix<K>::KMatrix( )
+{
+    copy_zero( );
+}
+
+// ----------------------------------------------------------------------------
+//  Copy constructor
+// ----------------------------------------------------------------------------
+
+template<class K>
+    inline  KMatrix<K>::KMatrix( const KMatrix &m )
+{
+    copy_deep( m );
+}
+
+// ----------------------------------------------------------------------------
+//  Zero r by c matrix constructor
+// ----------------------------------------------------------------------------
+
+template<class K>
+    KMatrix<K>::KMatrix( int r,int c )
+{
+    int n = r*c;
+
+    copy_new( n );
+
+    rows = r;
+    cols = c;
+
+    for( int i=0; i<n; i++ )
+    {
+        a[i]=(K)0;
+    }
+}
+
+// ----------------------------------------------------------------------------
+//  Destructor
+// ----------------------------------------------------------------------------
+
+template<class K>
+    KMatrix<K>::~KMatrix( )
+{
+    copy_delete( );
+}
+
+// -------------------------------------------------
+//  non-inline template functions for class KMatrix
+// -------------------------------------------------
+
+// ----------------------------------------------------------------------------
+//  Debugging functions
+// ----------------------------------------------------------------------------
+
+#ifdef KMATRIX_DEBUG
+
+template<class K>
+    void    KMatrix<K>::test_row( int r ) const
+{
+    if( r<0 || r>=rows )
+    {
+        #ifdef KMATRIX_PRINT
+        #ifdef KMATRIX_IOSTREAM
+            cerr << "KMatrix<K>::test_row( " << r << " )" << endl;
+            cerr << "    rows = " << rows << endl;
+            cerr << "    exiting...." << endl;
+        #else
+            fprintf( stderr,"KMatrix<K>::test_row( %d )\n",r );
+            fprintf( stderr,"    rows = %d\n",rows );
+            fprintf( stderr,"    exiting....\n" );
+        #endif
+        #endif
+
+        exit( 1 );
+    }
+}
+
+template<class K>
+    void    KMatrix<K>::test_col( int c ) const
+{
+    if( c<0 || c>=cols )
+    {
+        #ifdef KMATRIX_PRINT
+        #ifdef KMATRIX_IOSTREAM
+            cerr << "KMatrix<K>::test_col( " << c << " )" << endl;
+            cerr << "    cols = " << cols << endl;
+            cerr << "    exiting...." << endl;
+        #else
+            fprintf( stderr,"KMatrix<K>::test_col( %d )\n",c );
+            fprintf( stderr,"    cols = %d\n",cols );
+            fprintf( stderr,"    exiting....\n" );
+        #endif
+        #endif
+
+        exit( 1 );
+    }
+}
+
+#endif
+
+// ----------------------------------------------------------------------------
+//  get coefficient at row  r  and column  c
+//  return value: the coefficient
+// ----------------------------------------------------------------------------
+
+template<class K>
+    K    KMatrix<K>::get( int r,int c ) const
+{
+    #ifdef KMATRIX_DEBUG
+        test_row( r );
+        test_col( c );
+    #endif
+
+    return a[r*cols+c];
+}
+
+// ----------------------------------------------------------------------------
+//  sets coefficient at row  r  and column  c  to  value
+// ----------------------------------------------------------------------------
+
+template<class K>
+    void    KMatrix<K>::set( int r,int c,const K &value )
+{
+    #ifdef KMATRIX_DEBUG
+        test_row( r );
+        test_col( c );
+    #endif
+
+    a[r*cols+c] = value;
+}
+
+// ----------------------------------------------------------------------------
+//  interchanges the rows  r1  and  r2
+//  return value:  1 if r1==r2
+//  return value: -1 if r1!=r2
+//  caution: the determinant changes its sign by the return value
+// ----------------------------------------------------------------------------
+
+template<class K>
+    int     KMatrix<K>::swap_rows( int r1,int r2 )
+{
+    #ifdef KMATRIX_DEBUG
+        test_row( r1 );
+        test_row( r2 );
+    #endif
+
+    if( r1 == r2 ) return 1;
+
+    K   tmp;
+
+    for( int c=0; c<cols; c++ )
+    {
+        tmp          = a[r1*cols+c];
+        a[r1*cols+c] = a[r2*cols+c];
+        a[r2*cols+c] = tmp;
+    }
+
+    return -1;
+}
+
+// ----------------------------------------------------------------------------
+//  replaces row  r  by its multiple (row r)*factor
+//  return value: factor
+//  caution: the determinant changes by the return value
+// ----------------------------------------------------------------------------
+
+template<class K>
+    K    KMatrix<K>::multiply_row( int r,const K &factor )
+{
+    #ifdef KMATRIX_DEBUG
+        test_row( r );
+    #endif
+
+    int i_src = r*cols;
+
+    for( int i=0; i<cols; i++,i_src++ )
+    {
+        a[i_src] *= factor;
+    }
+    return  factor;
+}
+
+// ----------------------------------------------------------------------------
+//  replaces row  dest  by the linear combination
+//      (row src)*factor_src + (row dest)*factor_dest
+//  return value: factor_dest
+//  caution: the determinant changes by the return value
+// ----------------------------------------------------------------------------
+
+template<class K>
+    K   KMatrix<K>::add_rows(
+        int src,int dest,const K &factor_src,const K &factor_dest )
+{
+    #ifdef KMATRIX_DEBUG
+        test_row( src  );
+        test_row( dest );
+    #endif
+
+    int i;
+    int i_src  = src*cols;
+    int i_dest = dest*cols;
+
+    for( i=0; i<cols; i++,i_src++,i_dest++ )
+    {
+        a[i_dest] = a[i_src]*factor_src + a[i_dest]*factor_dest;
+    }
+
+    return factor_dest;
+}
+
+// ----------------------------------------------------------------------------
+//  test if row  r  is zero
+//  return value: TRUE  if zero
+//                FALSE if not zero
+// ----------------------------------------------------------------------------
+
+template<class K>
+    int     KMatrix<K>::row_is_zero( int r ) const
+{
+    #ifdef KMATRIX_DEBUG
+        test_row( r );
+    #endif
+
+    for( int c=0; c<cols; c++ )
+    {
+        if( a[r*cols+c] != (K)0 ) return FALSE;
+    }
+    return TRUE;
+}
+
+// ----------------------------------------------------------------------------
+//  test if column  c  is zero
+//  return value: TRUE  if zero
+//                FALSE if not zero
+// ----------------------------------------------------------------------------
+
+template<class K>
+    int     KMatrix<K>::column_is_zero( int c ) const
+{
+    #ifdef KMATRIX_DEBUG
+        test_col( c );
+    #endif
+
+    for( int r=0; r<rows; r++ )
+    {
+        if( a[r*cols+c] != (K)0 ) return FALSE;
+    }
+    return TRUE;
+}
+
+// ----------------------------------------------------------------------------
+//  find the element of column  c  if smallest nonzero absolute value
+//  consider only elements in row  r0  or below
+//  return value: the row of the element
+// ----------------------------------------------------------------------------
+
+template<class K>
+    int     KMatrix<K>::column_pivot( int r0,int c ) const
+{
+    #ifdef KMATRIX_DEBUG
+        test_row( r0 );
+        test_col( c  );
+    #endif
+
+    int r;
+    //  find first nonzero entry in column  c
+
+    for( r=r0; r<rows && a[r*cols+c]==(K)0; r++ );
+
+    if( r == rows )
+    {
+        //  column is zero
+
+        return -1;
+    }
+    else
+    {
+        double val     = a[r*cols+c].complexity( );
+        double val_new = 0.0;
+        int pivot   = r;
+
+        for( ; r<rows; r++ )
+        {
+            if( a[r*cols+c] != (K)0 &&
+                ( val_new = a[r*cols+c].complexity( ) ) < val )
+            {
+                val = val_new;
+                pivot = r;
+            }
+        }
+        return pivot;
+    }
+}
+
+// ----------------------------------------------------------------------------
+//  divide row  r  by the gcd of all elements
+// ----------------------------------------------------------------------------
+
+template<class K>
+    K    KMatrix<K>::set_row_primitive( int r )
+{
+    #ifdef KMATRIX_DEBUG
+        test_row( r );
+    #endif
+
+    K   g = gcd( &(a[r*cols]),cols );
+
+    for( int c=0; c<cols; c++ )
+    {
+        a[r*cols+c] /= g;
+    }
+    return  g;
+}
+
+// ----------------------------------------------------------------------------
+//  convert the matrix to upper triangular form
+//  return value: rank of the matrix
+// ----------------------------------------------------------------------------
+
+template<class K>
+    int     KMatrix<K>::gausseliminate( void )
+{
+    int r,c,rank = 0;
+    K g;
+
+    //  make sure that the elements of each row have gcd=1
+    //  this is useful for pivoting
+
+    for( r=0; r<rows; r++ )
+    {
+        set_row_primitive( r );
+    }
+
+    //  search a pivoting element in each column
+    //  perform Gauss elimination
+
+    for( c=0; c<cols && rank<rows; c++ )
+    {
+        if( ( r = column_pivot( rank,c )) >= 0 )
+        {
+            swap_rows( rank,r );
+
+            for( r=rank+1; r<rows; r++ )
+            {
+                if( a[r*cols+c] != (K)0 )
+                {
+                    g = gcd( a[r*cols+c],a[rank*cols+c] );
+                    add_rows( rank,r,-a[r*cols+c]/g,a[rank*cols+c]/g );
+                    set_row_primitive( r );
+                }
+            }
+            rank++;
+        }
+    }
+    return rank;
+}
+
+// ----------------------------------------------------------------------------
+//  solve the linear system of equations given by
+//    (x1,...,xn,-1)*(*this) = 0
+//  return value: rank of the matrix
+//  k is set to the number of variables
+//  rat[0],...,rat[k-1] are set to the solutions
+// ----------------------------------------------------------------------------
+
+template<class K>
+    int     KMatrix<K>::solve( K **solution,int *k )
+{
+    int r,c,rank = 0;
+    K g;
+
+    // ----------------------------------------------------
+    //  make sure that the elements of each row have gcd=1
+    //  this is useful for pivoting
+    // ----------------------------------------------------
+
+    for( r=0; r<rows; r++ )
+    {
+        set_row_primitive( r );
+    }
+
+    // ------------------------------------------
+    //  search a pivoting element in each column
+    //  perform Gauss elimination
+    // ------------------------------------------
+
+    for( c=0; c<cols && rank < rows; c++ )
+    {
+        if( ( r = column_pivot( rank,c )) >= 0 )
+        {
+            swap_rows( rank,r );
+
+            for( r=0; r<rank; r++ )
+            {
+                if( a[r*cols+c] != (K)0 )
+                {
+                    g = gcd( a[r*cols+c],a[rank*cols+c] );
+                    add_rows( rank,r,-a[r*cols+c]/g,a[rank*cols+c]/g );
+                    set_row_primitive( r );
+                }
+            }
+
+            for( r=rank+1; r<rows; r++ )
+            {
+                if( a[r*cols+c] != (K)0 )
+                {
+                    g = gcd( a[r*cols+c],a[rank*cols+c] );
+                    add_rows( rank,r,-a[r*cols+c]/g,a[rank*cols+c]/g );
+                    set_row_primitive( r );
+                }
+            }
+
+            rank++;
+        }
+    }
+
+    if( rank < cols )
+    {
+        // ----------------------
+        //  equation is solvable
+        //  copy solutions
+        // ----------------------
+
+        *solution = new K[cols-1];
+        *k        = cols - 1;
+
+        for( c=0; c<cols-1; c++ )
+        {
+            (*solution)[c] = (K)0;
+        }
+
+        for( r=0; r<rows; r++ )
+        {
+            for( c=0; c<cols && a[r*cols+c] == (K)0; c++ );
+
+            if( c < cols-1 )
+            {
+                (*solution)[c] = ((K)a[(r+1)*cols-1])/a[r*cols+c];
+            }
+        }
+    }
+    else
+    {
+        // --------------------------
+        //  equation is not solvable
+        // --------------------------
+
+        *solution = (K*)NULL;
+        *k   = 0;
+    }
+
+    return rank;
+}
+
+// ----------------------------------------------------------------------------
+//  compute the rank of the matrix
+//  return value: rank of the matrix
+// ----------------------------------------------------------------------------
+
+template<class K>
+    int     KMatrix<K>::rank( void ) const
+{
+    KMatrix<K> dummy( *this );
+
+    return dummy.gausseliminate( );
+}
+
+// ----------------------------------------------------------------------------
+//  print the matrix
+//  return value: the output stream used
+// ----------------------------------------------------------------------------
+
+#ifdef KMATRIX_PRINT
+
+template<class K>
+    static
+        void    print_rational( ostream &s,int digits,const K &n )
+{
+    unsigned int num = digits - n.length( );
+
+    for( unsigned int i=0; i < num; i++ )
+    {
+        #ifdef KMATRIX_IOSTREAM
+            s << " ";
+        #else
+            fprintf( stdout," " );
+        #endif
+    }
+
+    s << n;
+}
+
+template<class K>
+    ostream &    operator << ( ostream &s,const KMatrix<K> &m )
+{
+    int i,r,c,digits=0,tmp;
+
+    for( i=0; i<m.rows*m.cols; i++ )
+    {
+        tmp = m.a[i].length( );
+
+        if( tmp > digits ) digits = tmp;
+    }
+
+    for( r=0; r<m.rows; r++ )
+    {
+        if( m.rows == 1 )
+        {
+            #ifdef KMATRIX_IOSTREAM
+                s << "<";
+            #else
+                fprintf( stdout,"<" );
+            #endif
+        }
+        else if( r == 0 )
+        {
+            #ifdef KMATRIX_IOSTREAM
+                s << "/";
+            #else
+                fprintf( stdout,"/" );
+            #endif
+        }
+        else if( r == m.rows - 1 )
+        {
+            #ifdef KMATRIX_IOSTREAM
+                s << "\\";
+            #else
+                fprintf( stdout,"\\" );
+            #endif
+        }
+        else
+        {
+            #ifdef KMATRIX_IOSTREAM
+                s << "|";
+            #else
+                fprintf( stdout,"|" );
+            #endif
+        }
+
+        for( c=0; c<m.cols; c++ )
+        {
+            #ifdef KMATRIX_IOSTREAM
+                s << " ";
+            #else
+                fprintf( stdout," " );
+            #endif
+
+            print_rational( s,digits,m.a[r*m.cols+c] );
+        }
+
+        if( m.rows == 1 )
+        {
+            #ifdef KMATRIX_IOSTREAM
+                s << " >";
+            #else
+                fprintf( stdout," >" );
+            #endif
+        }
+        else if( r == 0 )
+        {
+            #ifdef KMATRIX_IOSTREAM
+                s << " \\" << endl;
+            #else
+                fprintf( stdout," \\\n" );
+            #endif
+        }
+        else if( r == m.rows - 1 )
+        {
+            #ifdef KMATRIX_IOSTREAM
+                s << " /";
+            #else
+                fprintf( stdout," /" );
+            #endif
+        }
+        else
+        {
+            #ifdef KMATRIX_IOSTREAM
+                s << " |" << endl;
+            #else
+                fprintf( stdout," |\n" );
+            #endif
+        }
+    }
+    return s;
+}
+
+#endif
+
+// ----------------------------------------------------------------------------
+//  test if the matrix is quadratic
+//  return value: TRUE or FALSE
+// ----------------------------------------------------------------------------
+
+template<class K>
+    int     KMatrix<K>::is_quadratic( void ) const
+{
+    return ( rows == cols ? TRUE : FALSE );
+}
+
+// ----------------------------------------------------------------------------
+//  test if the matrix is symmetric
+//  return value: TRUE or FALSE
+// ----------------------------------------------------------------------------
+
+template<class K>
+     int     KMatrix<K>::is_symmetric( void ) const
+{
+    if( is_quadratic( ) )
+    {
+        int r,c;
+
+        for( r=1; r<rows; r++ )
+        {
+            for( c=0; c<r; c++ )
+            {
+                if( a[r*cols+c] != a[c*cols+r] )
+                {
+                    return  FALSE;
+                }
+            }
+        }
+        return  TRUE;
+    }
+    else
+    {
+        return  FALSE;
+    }
+}
+
+// ----------------------------------------------------------------------------
+//  compute the determinant
+//  return value: the determinant
+// ----------------------------------------------------------------------------
+
+template<class K> K KMatrix<K>::determinant( void ) const
+{
+    if( !is_quadratic( ) )
+    {
+        return 0;
+    }
+
+    KMatrix<K> dummy( *this );
+
+    int r,c,rank = 0;
+    K g;
+    K frank,fr;
+    K det = 1;
+
+    //  make sure that the elements of each row have gcd=1
+    //  this is useful for pivoting
+
+    for( r=0; r<dummy.rows; r++ )
+    {
+        det *= dummy.set_row_primitive( r );
+    }
+
+    //  search a pivoting element in each column
+    //  perform Gauss elimination
+
+    for( c=0; c<cols && rank<dummy.rows; c++ )
+    {
+        if( ( r = dummy.column_pivot( rank,c )) >= 0 )
+        {
+            det *= dummy.swap_rows( rank,r );
+
+            for( r=rank+1; r<dummy.rows; r++ )
+            {
+                if( dummy.a[r*cols+c] != (K)0 )
+                {
+                    g = gcd( dummy.a[r*cols+c],dummy.a[rank*cols+c] );
+
+                    frank = -dummy.a[r*cols+c]/g;
+                    fr    = dummy.a[rank*cols+c]/g;
+
+                    det /= dummy.add_rows( rank,r,frank,fr );
+                    det *= dummy.set_row_primitive( r );
+                }
+            }
+            rank++;
+        }
+    }
+
+    if( rank != dummy.rows )
+    {
+        return 0;
+    }
+
+    for( r=0; r<dummy.rows; r++ )
+    {
+        det *= dummy.a[r*cols+r];
+    }
+
+    return  det;
+}
+
+#endif /* KMATRIX_H */
+
+// ----------------------------------------------------------------------------
+//  kmatrix.h
+//  end of file
+// ----------------------------------------------------------------------------
diff --git a/kernel/spectrum/multicnt.cc b/kernel/spectrum/multicnt.cc
new file mode 100644
index 0000000..ce041fe
--- /dev/null
+++ b/kernel/spectrum/multicnt.cc
@@ -0,0 +1,248 @@
+// ----------------------------------------------------------------------------
+//  multicnt.cc
+//  begin of file
+//  Stephan Endrass, endrass at mathematik.uni-mainz.de
+//  23.7.99
+// ----------------------------------------------------------------------------
+
+#define MULTICNT_CC
+
+
+
+
+#include <kernel/mod2.h>
+
+#ifdef HAVE_SPECTRUM
+
+#include <stdlib.h>
+
+#ifdef  MULTICNT_PRINT
+#include <iostream.h>
+#ifndef  MULTICNT_IOSTREAM
+#include <stdio.h>
+#endif
+#endif
+
+#include <kernel/spectrum/multicnt.h>
+
+// ----------------------------------------------------------------------------
+//  allocate counter memory
+// ----------------------------------------------------------------------------
+
+void    multiCnt::copy_new( int n )
+{
+    if( n > 0 )
+    {
+        cnt = new int[n];
+
+        #ifndef SING_NDEBUG
+        if( cnt == (int*)NULL )
+        {
+            #ifdef MULTICNT_PRINT
+            #ifdef MULTICNT_IOSTREAM
+                cerr << "multiCnt::copy_new(" << n << ")" << endl;
+                cerr << "    returned ZERO!!!" << endl;
+                cerr << "    exit..." << endl;
+            #else
+                fprintf( stderr,"multiCnt::copy_new( %d )\n",n );
+                fprintf( stderr,"    returned ZERO!!!\n" );
+                fprintf( stderr,"    exit...\n" );
+            #endif
+            #endif
+
+            exit( 1 );
+        }
+        #endif
+    }
+    else if( n == 0 )
+    {
+        cnt = (int*)NULL;
+    }
+    else
+    {
+        #ifdef MULTICNT_PRINT
+        #ifdef MULTICNT_IOSTREAM
+            cerr << "multiCnt::copy_new(" << n << ")" << endl;
+            cerr << "    exit..." << endl;
+        #else
+            fprintf( stderr,"multiCnt::copy_new( %d )\n",n );
+            fprintf( stderr,"    exit...\n" );
+        #endif
+        #endif
+
+        exit( 1 );
+    }
+}
+
+// ----------------------------------------------------------------------------
+//  delete counter memory
+// ----------------------------------------------------------------------------
+
+void    multiCnt::copy_delete( void )
+{
+    if( N>0 && cnt!=(int*)NULL ) delete [] cnt;
+    copy_zero( );
+}
+
+// ----------------------------------------------------------------------------
+//  copy a counter
+// ----------------------------------------------------------------------------
+
+void multiCnt::copy_deep( const multiCnt &C )
+{
+    copy_new( C.N );
+
+    last_inc = C.last_inc;
+    N        = C.N;
+
+    for( int i=0; i<N; i++ )
+    {
+        cnt[i] = C.cnt[i];
+    }
+}
+
+// ----------------------------------------------------------------------------
+//  set all counter entries to c
+// ----------------------------------------------------------------------------
+
+void multiCnt::set( int c )
+{
+    for( int i=0; i<N; i++ ) cnt[i]=c;
+}
+
+
+// ----------------------------------------------------------------------------
+//  n entries zero init constructor
+// ----------------------------------------------------------------------------
+
+multiCnt::multiCnt( int n ) :
+    last_inc( 0 )
+{
+    copy_new( n );
+    N = n;
+    set( 0 );
+}
+
+// ----------------------------------------------------------------------------
+//  n entries c init constructor
+// ----------------------------------------------------------------------------
+
+multiCnt::multiCnt( int n,int c ) :
+    last_inc( 0 )
+{
+    copy_new( n );
+    N = n;
+    set( c );
+}
+
+// ----------------------------------------------------------------------------
+//  n entries c* init constructor
+// ----------------------------------------------------------------------------
+
+multiCnt::multiCnt( int n,int *c ) :
+    last_inc( 0 )
+{
+    copy_new( n );
+    N = n;
+    for( int i=0; i<N; i++ ) cnt[i] = c[i];
+}
+
+// ----------------------------------------------------------------------------
+//  increment the counter
+// ----------------------------------------------------------------------------
+
+void multiCnt::inc( void )
+{
+    cnt[0]++;
+    last_inc=0;
+}
+
+// ----------------------------------------------------------------------------
+//  decrement the counter
+// ----------------------------------------------------------------------------
+
+/*
+void multiCnt::dec( void )
+{
+    cnt[0]--;
+    last_inc=0;
+}
+*/
+
+// ----------------------------------------------------------------------------
+//  increment the counter and carry over
+// ----------------------------------------------------------------------------
+
+void multiCnt::inc_carry( void )
+{
+    for( int i=0; i<=last_inc; i++ ) cnt[i] = 0;
+    last_inc++;
+    cnt[last_inc]++;
+}
+
+// ----------------------------------------------------------------------------
+//  decrement the counter and carry over
+// ----------------------------------------------------------------------------
+
+/*
+void multiCnt::dec_carry( void )
+{
+    for( int i=0; i<=last_inc; i++ ) cnt[i] = 0;
+    last_inc++;
+    cnt[last_inc]--;
+}
+*/
+
+// ----------------------------------------------------------------------------
+//  increment the counter and carry over automatic
+// ----------------------------------------------------------------------------
+
+int  multiCnt::inc( int carry )
+{
+    if( carry==FALSE )
+    {
+        inc( );
+    }
+    else
+    {
+        if( last_inc==N-1 )
+        {
+            return  FALSE;
+        }
+
+        inc_carry( );
+    }
+
+    return  TRUE;
+}
+
+// ----------------------------------------------------------------------------
+//  decrement the counter and carry over automatic
+// ----------------------------------------------------------------------------
+
+/*
+int  multiCnt::dec( int carry )
+{
+    if( carry==FALSE )
+    {
+        dec( );
+    }
+    else
+    {
+        if( last_inc==N-1 )
+        {
+            return  FALSE;
+        }
+
+        dec_carry( );
+    }
+
+    return  TRUE;
+}
+*/
+
+#endif /* HAVE_SPECTRUM */
+// ----------------------------------------------------------------------------
+//  multicnt.cc
+//  end of file
+// ----------------------------------------------------------------------------
diff --git a/kernel/spectrum/multicnt.h b/kernel/spectrum/multicnt.h
new file mode 100644
index 0000000..75df7e3
--- /dev/null
+++ b/kernel/spectrum/multicnt.h
@@ -0,0 +1,83 @@
+// ----------------------------------------------------------------------------
+//  multicnt.h
+//  begin of file
+//  Stephan Endrass, endrass at mathematik.uni-mainz.de
+//  23.7.99
+// ----------------------------------------------------------------------------
+
+// ----------------------------------------------------------------------------
+//  Description: the class multiCnt is a general multi purpose counter.
+//  The counter holds an array  cnt  of  N  integers.
+//  The integer  last_inc  holds the index of the last incremented entry.
+// ----------------------------------------------------------------------------
+
+#ifndef MULTICNT_H
+#define MULTICNT_H
+
+class multiCnt
+{
+public:
+
+    int *cnt;
+    int N;
+    int last_inc;
+
+    multiCnt( );
+    multiCnt( int );
+    multiCnt( int,int );
+    multiCnt( int,int* );
+    multiCnt( const multiCnt& );
+
+    void    copy_zero   ( void );
+    void    copy_new    ( int );
+    void    copy_delete ( void );
+    void    copy_shallow( multiCnt& );
+    void    copy_deep   ( const multiCnt& );
+
+    void    set( int );
+
+    void    inc      ( void );
+    void    inc_carry( void );
+    int     inc      ( int );
+    //void    dec      ( void );
+    //void    dec_carry( void );
+    //int     dec      ( int );
+};
+
+// ----------------------------------------------------------------------------
+//  zero init
+// ----------------------------------------------------------------------------
+
+inline  void    multiCnt::copy_zero( void )
+{
+    cnt      = (int*)NULL;
+    N        = 0;
+    last_inc = 0;
+}
+
+// ----------------------------------------------------------------------------
+//  copy a counter by reference
+// ----------------------------------------------------------------------------
+
+inline  void multiCnt::copy_shallow( multiCnt &C )
+{
+    cnt      = C.cnt;
+    N        = C.N;
+    last_inc = C.last_inc;
+}
+
+// ----------------------------------------------------------------------------
+//  zero constructor
+// ----------------------------------------------------------------------------
+
+inline multiCnt::multiCnt( )
+{
+    copy_zero( );
+}
+
+#endif /* MULTICNT_H */
+
+// ----------------------------------------------------------------------------
+//  multicnt.h
+//  end of file
+// ----------------------------------------------------------------------------
diff --git a/kernel/spectrum/npolygon.cc b/kernel/spectrum/npolygon.cc
new file mode 100644
index 0000000..e246ef5
--- /dev/null
+++ b/kernel/spectrum/npolygon.cc
@@ -0,0 +1,678 @@
+// ----------------------------------------------------------------------------
+//  npolygon.cc
+//  begin of file
+//  Stephan Endrass, endrass at mathematik.uni-mainz.de
+//  23.7.99
+// ----------------------------------------------------------------------------
+
+#define  NPOLYGON_CC
+
+
+
+
+#include <kernel/mod2.h>
+
+#ifdef HAVE_SPECTRUM
+
+#ifdef   NPOLYGON_PRINT
+#include <iostream.h>
+#ifndef   NPOLYGON_IOSTREAM
+#include <stdio.h>
+#endif
+#endif
+
+//#include <kernel/polys.h>
+#include <polys/monomials/p_polys.h>
+#include <polys/monomials/ring.h>
+
+#include <kernel/spectrum/GMPrat.h>
+#include <kernel/spectrum/kmatrix.h>
+#include <kernel/spectrum/npolygon.h>
+#include <kernel/structs.h>
+
+// ----------------------------------------------------------------------------
+//  Allocate memory for a linear form of  k  terms
+// ----------------------------------------------------------------------------
+
+void    linearForm::copy_new( int k )
+{
+  if( k > 0 )
+  {
+    c = new Rational[k];
+
+    #ifndef NBDEBUG
+    if( c == (Rational*)NULL )
+    {
+      #ifdef  NPOLYGON_PRINT
+      #ifdef  NPOLYGON_IOSTREAM
+        cerr <<
+        "void linearForm::copy_new( int k ): no memory left ...\n" ;
+      #else
+        fprintf( stderr,
+        "void linearForm::copy_new( int k ): no memory left ...\n");
+      #endif
+      #endif
+      HALT();
+    }
+    #endif
+  }
+  else if( k == 0 )
+  {
+    c = (Rational*)NULL;
+  }
+  else if( k < 0 )
+  {
+    #ifdef  NPOLYGON_PRINT
+    #ifdef  NPOLYGON_IOSTREAM
+      cerr <<
+      "void linearForm::copy_new( int k ): k < 0 ...\n";
+    #else
+      fprintf( stderr,
+      "void linearForm::copy_new( int k ): k < 0 ...\n" );
+    #endif
+    #endif
+
+    HALT();
+  }
+}
+
+// ----------------------------------------------------------------------------
+//  Delete the memory of a linear form
+// ----------------------------------------------------------------------------
+
+void    linearForm::copy_delete( void )
+{
+  if( c != (Rational*)NULL && N > 0 )
+    delete [] c;
+  copy_zero( );
+}
+
+// ----------------------------------------------------------------------------
+//  Initialize deep from another linear form
+// ----------------------------------------------------------------------------
+
+void    linearForm::copy_deep( const linearForm &l )
+{
+  copy_new( l.N );
+  for( int i=l.N-1; i>=0; i-- )
+  {
+    c[i] = l.c[i];
+  }
+  N = l.N;
+}
+
+// ----------------------------------------------------------------------------
+//  Copy constructor
+// ----------------------------------------------------------------------------
+
+linearForm::linearForm( const linearForm &l )
+{
+  copy_deep( l );
+}
+
+// ----------------------------------------------------------------------------
+//  Destructor
+// ----------------------------------------------------------------------------
+
+linearForm::~linearForm( )
+{
+  copy_delete( );
+}
+
+// ----------------------------------------------------------------------------
+//  Define `=` to be a deep copy
+// ----------------------------------------------------------------------------
+
+linearForm & linearForm::operator = ( const linearForm &l )
+{
+  copy_delete( );
+  copy_deep( l );
+
+  return *this;
+}
+
+// ----------------------------------------------------------------------------
+//  ostream for linear form
+// ----------------------------------------------------------------------------
+
+#ifdef  NPOLYGON_PRINT
+
+ostream & operator << ( ostream &s,const linearForm &l )
+{
+  for( int i=0; i<l.N; i++ )
+  {
+    if( l.c[i] != (Rational)0 )
+    {
+      if( i > 0 && l.c[i] >= (Rational)0 )
+      {
+        #ifdef NPOLYGON_IOSTREAM
+          s << "+";
+        #else
+          fprintf( stdout,"+" );
+        #endif
+      }
+
+      s << l.c[i];
+
+      #ifdef NPOLYGON_IOSTREAM
+        s << "*x" << i+1;
+      #else
+        fprintf( stdout,"*x%d",i+1 );
+      #endif
+    }
+  }
+  return s;
+}
+
+#endif
+
+// ----------------------------------------------------------------------------
+//  Equality of linear forms
+// ----------------------------------------------------------------------------
+
+int     operator == ( const linearForm &l1,const linearForm &l2 )
+{
+  if( l1.N!=l2.N )
+    return  FALSE;
+  for( int i=l1.N-1; i >=0 ; i-- )
+  {
+    if( l1.c[i]!=l2.c[i] )
+      return  FALSE;
+  }
+  return  TRUE;
+}
+
+
+// ----------------------------------------------------------------------------
+//  Newton weight of a monomial
+// ----------------------------------------------------------------------------
+
+Rational linearForm::weight( poly m, const ring r ) const
+{
+  Rational ret=(Rational)0;
+
+  for( int i=0,j=1; i<N; i++,j++ )
+  {
+    ret += c[i]*(Rational)p_GetExp( m,j,r );
+  }
+
+  return ret;
+}
+
+// ----------------------------------------------------------------------------
+//  Newton weight of a polynomial
+// ----------------------------------------------------------------------------
+
+Rational linearForm::pweight( poly m, const ring r ) const
+{
+  if( m==(poly)NULL )
+    return  (Rational)0;
+
+  Rational    ret = weight( m, r );
+  Rational    tmp;
+
+  for( m=pNext(m); m!=(poly)NULL; pIter(m) )
+  {
+    tmp = weight( m, r );
+    if( tmp<ret )
+    {
+      ret = tmp;
+    }
+  }
+
+  return ret;
+}
+
+// ----------------------------------------------------------------------------
+//  Newton weight of a monomial shifted by the product of the variables
+// ----------------------------------------------------------------------------
+
+Rational linearForm::weight_shift( poly m, const ring r ) const
+{
+  Rational ret=(Rational)0;
+
+  for( int i=0,j=1; i<N; i++,j++ )
+  {
+    ret += c[i]*(Rational)( p_GetExp( m,j,r ) + 1 );
+  }
+
+  return ret;
+}
+
+// ----------------------------------------------------------------------------
+//  Newton weight of a monomial (forgetting the first variable)
+// ----------------------------------------------------------------------------
+
+Rational linearForm::weight1( poly m, const ring r ) const
+{
+  Rational ret=(Rational)0;
+
+  for( int i=0,j=2; i<N; i++,j++ )
+  {
+    ret += c[i]*(Rational)p_GetExp( m,j,r );
+  }
+
+  return ret;
+}
+
+// ----------------------------------------------------------------------------
+//  Newton weight of a monomial shifted by the product of the variables
+//  (forgetting the first variable)
+// ----------------------------------------------------------------------------
+
+Rational linearForm::weight_shift1( poly m, const ring r ) const
+{
+  Rational ret=(Rational)0;
+
+  for( int i=0,j=2; i<N; i++,j++ )
+  {
+    ret += c[i]*(Rational)( p_GetExp( m,j,r ) + 1 );
+  }
+
+  return ret;
+}
+
+
+// ----------------------------------------------------------------------------
+//  Test if all coefficients of a linear form are positive
+// ----------------------------------------------------------------------------
+
+int linearForm::positive( void )
+{
+  for( int i=0; i<N; i++ )
+  {
+    if( c[i] <= (Rational)0 )
+    {
+      return FALSE;
+    }
+  }
+  return  TRUE;
+}
+
+
+// ----------------------------------------------------------------------------
+//  Allocate memory for a newton polygon of  k  linear forms
+// ----------------------------------------------------------------------------
+
+void    newtonPolygon::copy_new( int k )
+{
+  if( k > 0 )
+  {
+    l = new linearForm[k];
+
+    #ifndef SING_NDEBUG
+      if( l == (linearForm*)NULL )
+      {
+        #ifdef  NPOLYGON_PRINT
+          #ifdef  NPOLYGON_IOSTREAM
+            cerr <<
+            "void newtonPolygon::copy_new( int k ): no memory left ...\n";
+          #else
+            fprintf( stderr,
+            "void newtonPolygon::copy_new( int k ): no memory left ...\n" );
+          #endif
+        #endif
+
+        HALT();
+      }
+    #endif
+  }
+  else if( k == 0 )
+  {
+    l = (linearForm*)NULL;
+  }
+  else if( k < 0 )
+  {
+    #ifdef  NPOLYGON_PRINT
+      #ifdef  NPOLYGON_IOSTREAM
+        cerr << "void newtonPolygon::copy_new( int k ): k < 0 ...\n";
+      #else
+        fprintf( stderr,
+        "void newtonPolygon::copy_new( int k ): k < 0 ...\n" );
+      #endif
+    #endif
+
+    HALT();
+  }
+}
+
+// ----------------------------------------------------------------------------
+//  Delete the memory of a Newton polygon
+// ----------------------------------------------------------------------------
+
+void    newtonPolygon::copy_delete( void )
+{
+  if( l != (linearForm*)NULL && N > 0 )
+    delete [] l;
+  copy_zero( );
+}
+
+// ----------------------------------------------------------------------------
+//  Initialize deep from another Newton polygon
+// ----------------------------------------------------------------------------
+
+void    newtonPolygon::copy_deep( const newtonPolygon &np )
+{
+  copy_new( np.N );
+  for( int i=0; i<np.N; i++ )
+  {
+    l[i] = np.l[i];
+  }
+  N = np.N;
+}
+
+// ----------------------------------------------------------------------------
+//  Copy constructor
+// ----------------------------------------------------------------------------
+
+newtonPolygon::newtonPolygon( const newtonPolygon &np )
+{
+  copy_deep( np );
+}
+
+// ----------------------------------------------------------------------------
+//  Destructor
+// ----------------------------------------------------------------------------
+
+newtonPolygon::~newtonPolygon( )
+{
+  copy_delete( );
+}
+
+// ----------------------------------------------------------------------------
+//  We define `=` to be a deep copy
+// ----------------------------------------------------------------------------
+
+newtonPolygon & newtonPolygon::operator = ( const newtonPolygon &np )
+{
+  copy_delete( );
+  copy_deep( np );
+
+  return *this;
+}
+
+// ----------------------------------------------------------------------------
+//  Initialize a Newton polygon from a polynomial
+// ----------------------------------------------------------------------------
+
+newtonPolygon::newtonPolygon( poly f, const ring s )
+{
+  copy_zero( );
+
+  int *r=new int[s->N];
+  poly *m=new poly[s->N];
+
+
+  KMatrix<Rational> mat(s->N,s->N+1 );
+
+  int i,j,stop=FALSE;
+  linearForm sol;
+
+  // ---------------
+  //  init counters
+  // ---------------
+
+  for( i=0; i<s->N; i++ )
+  {
+    r[i] = i;
+  }
+
+  m[0] = f;
+
+  for( i=1; i<s->N; i++ )
+  {
+    m[i] = pNext(m[i-1]);
+  }
+
+  // -----------------------------
+  //  find faces (= linear forms)
+  // -----------------------------
+
+  do
+  {
+    // ---------------------------------------------------
+    //  test if monomials p.m[r[0]]m,...,p.m[r[p.vars-1]]
+    //  are linearely independent
+    // ---------------------------------------------------
+
+    for( i=0; i<s->N; i++ )
+    {
+      for( j=0; j<s->N; j++ )
+      {
+        //    mat.set( i,j,pGetExp( m[r[i]],j+1 ) );
+        mat.set( i,j,p_GetExp( m[i],j+1,s ) );
+      }
+      mat.set( i,j,1 );
+    }
+
+    if( mat.solve( &(sol.c),&(sol.N) ) == s->N )
+    {
+      // ---------------------------------
+      //  check if linearForm is positive
+      //  check if linearForm is extremal
+      // ---------------------------------
+
+      if( sol.positive( ) && sol.pweight( f,s ) >= (Rational)1 )
+      {
+        // ----------------------------------
+        //  this is a face or the polyhedron
+        // ----------------------------------
+
+        add_linearForm( sol );
+        sol.c = (Rational*)NULL;
+        sol.N = 0;
+      }
+    }
+
+    // --------------------
+    //  increment counters
+    // --------------------
+
+    for( i=1; r[i-1] + 1 == r[i] && i < s->N; i++ );
+
+    for( j=0; j<i-1; j++ )
+    {
+      r[j]=j;
+    }
+
+    if( i>1 )
+    {
+      m[0]=f;
+      for( j=1; j<i-1; j++ )
+      {
+        m[j]=pNext(m[j-1]);
+      }
+    }
+    r[i-1]++;
+    m[i-1]=pNext(m[i-1]);
+
+    if( m[s->N-1] == (poly)NULL )
+    {
+      stop = TRUE;
+    }
+  } while( stop == FALSE );
+}
+
+#ifdef  NPOLYGON_PRINT
+
+ostream & operator << ( ostream &s,const newtonPolygon &a )
+{
+  #ifdef NPOLYGON_IOSTREAM
+    s << "Newton polygon:" << endl;
+  #else
+    fprintf( stdout,"Newton polygon:\n" );
+  #endif
+
+  for( int i=0; i<a.N; i++ )
+  {
+    s << a.l[i];
+
+    #ifdef NPOLYGON_IOSTREAM
+      s << endl;
+    #else
+      fprintf( stdout,"\n" );
+    #endif
+  }
+
+  return s;
+}
+
+#endif
+
+// ----------------------------------------------------------------------------
+//  Add a face to the newton polygon
+// ----------------------------------------------------------------------------
+
+void    newtonPolygon::add_linearForm( const linearForm &l0 )
+{
+  int           i;
+  newtonPolygon np;
+
+  // -------------------------------------
+  //  test if linear form is already here
+  // -------------------------------------
+
+  for( i=0; i<N; i++ )
+  {
+    if( l0==l[i] )
+    {
+      return;
+    }
+  }
+
+  np.copy_new( N+1 );
+  np.N = N+1;
+
+  for( i=0; i<N; i++ )
+  {
+    np.l[i].copy_shallow( l[i] );
+    l[i].copy_zero( );
+  }
+
+  np.l[N] = l0;
+
+  copy_delete( );
+  copy_shallow( np );
+  np.copy_zero( );
+
+  return;
+}
+
+// ----------------------------------------------------------------------------
+//  Newton weight of a monomial
+// ----------------------------------------------------------------------------
+
+Rational  newtonPolygon::weight( poly m, const ring r ) const
+{
+  Rational ret = l[0].weight( m,r );
+  Rational tmp;
+
+  for( int i=1; i<N; i++ )
+  {
+    tmp = l[i].weight( m,r );
+
+    if( tmp < ret )
+    {
+      ret = tmp;
+    }
+  }
+  return ret;
+}
+
+// ----------------------------------------------------------------------------
+//  Newton weight of a monomial shifted by the product of the variables
+// ----------------------------------------------------------------------------
+
+Rational  newtonPolygon::weight_shift( poly m, const ring r ) const
+{
+  Rational ret = l[0].weight_shift( m, r );
+  Rational tmp;
+
+  for( int i=1; i<N; i++ )
+  {
+    tmp = l[i].weight_shift( m, r );
+
+    if( tmp < ret )
+    {
+      ret = tmp;
+    }
+  }
+  return ret;
+}
+
+// ----------------------------------------------------------------------------
+//  Newton weight of a monomial (forgetting the first variable)
+// ----------------------------------------------------------------------------
+
+Rational  newtonPolygon::weight1( poly m, const ring r ) const
+{
+  Rational ret = l[0].weight1( m, r );
+  Rational tmp;
+
+  for( int i=1; i<N; i++ )
+  {
+    tmp = l[i].weight1( m, r );
+
+    if( tmp < ret )
+    {
+      ret = tmp;
+    }
+  }
+  return ret;
+}
+
+// ----------------------------------------------------------------------------
+//  Newton weight of a monomial shifted by the product of the variables
+//  (forgetting the first variable)
+// ----------------------------------------------------------------------------
+
+Rational  newtonPolygon::weight_shift1( poly m, const ring r ) const
+{
+  Rational ret = l[0].weight_shift1( m, r );
+  Rational tmp;
+
+  for( int i=1; i<N; i++ )
+  {
+    tmp = l[i].weight_shift1( m, r );
+
+    if( tmp < ret )
+    {
+      ret = tmp;
+    }
+  }
+  return ret;
+}
+
+/*
+// ----------------------------------------------------------------------------
+//  Chcek if the polynomial belonging to the Newton polygon
+//  is semiquasihomogeneous (sqh)
+// ----------------------------------------------------------------------------
+
+int     newtonPolygon::is_sqh( void ) const
+{
+  return ( N==1 ? TRUE : FALSE );
+}
+
+// ----------------------------------------------------------------------------
+//  If the polynomial belonging to the Newton polygon is sqh,
+//  return its weights vector
+// ----------------------------------------------------------------------------
+
+Rational*   newtonPolygon::sqh_weights( void ) const
+{
+  return ( N==1 ? l[0].c : (Rational*)NULL );
+}
+
+int    newtonPolygon::sqh_N( void ) const
+{
+  return ( N==1 ? l[0].N : 0 );
+}
+*/
+
+#endif /* HAVE_SPECTRUM */
+// ----------------------------------------------------------------------------
+//  npolygon.cc
+//  end of file
+// ----------------------------------------------------------------------------
+
diff --git a/kernel/spectrum/npolygon.h b/kernel/spectrum/npolygon.h
new file mode 100644
index 0000000..9fa430f
--- /dev/null
+++ b/kernel/spectrum/npolygon.h
@@ -0,0 +1,175 @@
+// ----------------------------------------------------------------------------
+//  npolygon.h
+//  begin of file
+//  Stephan Endrass, endrass at mathematik.uni-mainz.de
+//  23.7.99
+// ----------------------------------------------------------------------------
+
+#ifndef NPOLYGON_H
+#define NPOLYGON_H
+
+#include <kernel/spectrum/GMPrat.h>
+
+// ----------------------------------------------------------------------------
+//  Class representing a linear form QQ^N-->QQ
+// ----------------------------------------------------------------------------
+
+class linearForm
+{
+
+private:
+
+    Rational    *c;                   // the coefficients
+    int         N;                    // number of coefficients
+
+public:
+
+    linearForm( );
+    linearForm( const linearForm& );
+    ~linearForm( );
+
+    linearForm & operator = ( const linearForm& );
+
+    friend  int     operator == ( const linearForm&,const linearForm& );
+
+    void        copy_new     ( int );
+    void        copy_delete  ( void );
+    void        copy_zero    ( void );
+    void        copy_shallow ( linearForm& );
+    void        copy_deep    ( const linearForm& );
+
+    Rational    weight       ( poly, const ring r ) const;
+    Rational    weight_shift ( poly, const ring r ) const;
+    Rational    weight1      ( poly, const ring r ) const;
+    Rational    weight_shift1( poly, const ring r ) const;
+
+    Rational    pweight      ( poly, const ring r ) const;
+
+    int         positive     ( void );
+
+    #ifdef  NPOLYGON_PRINT
+        friend ostream & operator << ( ostream&,const linearForm& );
+    #endif
+
+    friend class newtonPolygon;
+};
+
+// ----------------------------------------------------------------------------
+//  Class representing a Newton polygon
+// ----------------------------------------------------------------------------
+
+class newtonPolygon
+{
+
+private:
+
+    linearForm  *l;                   // the linear forms
+    int         N;                    // number of linear forms
+
+public:
+
+    newtonPolygon( );
+    newtonPolygon( const newtonPolygon& );
+    newtonPolygon( poly, const ring r );
+    ~newtonPolygon( );
+
+    newtonPolygon & operator = ( const newtonPolygon& );
+
+
+    void        copy_new    ( int );
+    void        copy_delete ( void );
+    void        copy_zero   ( void );
+    void        copy_shallow( newtonPolygon& );
+    void        copy_deep   ( const newtonPolygon& );
+
+    void        add_linearForm( const linearForm& );
+
+    Rational    weight       ( poly, const ring r ) const;
+    Rational    weight_shift ( poly, const ring r ) const;
+    Rational    weight1      ( poly, const ring r ) const;
+    Rational    weight_shift1( poly, const ring r ) const;
+
+    //int         is_sqh     ( void ) const;
+    //Rational*   sqh_weights( void ) const;
+    //int         sqh_N      ( void ) const;
+
+    #ifdef  NPOLYGON_PRINT
+        friend ostream & operator << ( ostream&,const newtonPolygon&  );
+    #endif
+};
+
+// ---------------------------------------
+//  inline functions for class linearForm
+// ---------------------------------------
+
+// ----------------------------------------------------------------------------
+//  Initialize with zero
+// ----------------------------------------------------------------------------
+
+inline  void    linearForm::copy_zero( void )
+{
+    c = (Rational*)NULL;
+    N = 0;
+}
+
+// ----------------------------------------------------------------------------
+//  Initialize shallow from another linear form
+// ----------------------------------------------------------------------------
+
+inline  void    linearForm::copy_shallow( linearForm &l )
+{
+    c = l.c;
+    N = l.N;
+}
+
+
+// ----------------------------------------------------------------------------
+//  Zero constructor
+// ----------------------------------------------------------------------------
+
+inline  linearForm::linearForm( )
+{
+    copy_zero( );
+}
+
+
+// ------------------------------------------
+//  inline functions for class newtonPolygon
+// ------------------------------------------
+
+// ----------------------------------------------------------------------------
+//  Initialize with zero
+// ----------------------------------------------------------------------------
+
+inline  void    newtonPolygon::copy_zero( void )
+{
+    l = (linearForm*)NULL;
+    N = 0;
+}
+
+// ----------------------------------------------------------------------------
+//  Initialize shallow from another Newton polygon
+// ----------------------------------------------------------------------------
+
+inline  void    newtonPolygon::copy_shallow( newtonPolygon &np )
+{
+    l = np.l;
+    N = np.N;
+}
+
+
+// ----------------------------------------------------------------------------
+//  Zero constructor
+// ----------------------------------------------------------------------------
+
+inline newtonPolygon::newtonPolygon( )
+{
+    copy_zero( );
+}
+
+#endif /* NPOLYGON_H */
+
+// ----------------------------------------------------------------------------
+//  npolygon.h
+//  end of file
+// ----------------------------------------------------------------------------
diff --git a/kernel/spectrum/semic.cc b/kernel/spectrum/semic.cc
new file mode 100644
index 0000000..d20308d
--- /dev/null
+++ b/kernel/spectrum/semic.cc
@@ -0,0 +1,493 @@
+// ----------------------------------------------------------------------------
+//  semic.cc
+//  begin of file
+//  Stephan Endrass, endrass at mathematik.uni-mainz.de
+//  23.7.99
+// ----------------------------------------------------------------------------
+
+#define SEMIC_CC
+
+
+
+
+#include <kernel/mod2.h>
+
+#ifdef HAVE_SPECTRUM
+
+#ifdef  SEMIC_PRINT
+#ifndef SEMIC_IOSTREAM
+#include <stdio.h>
+#else
+#include <iostream.h>
+#endif
+#endif
+
+#include <string.h>
+
+#include <misc/intvec.h>
+#include <misc/mylimits.h>
+#include <kernel/spectrum/GMPrat.h>
+#include <kernel/spectrum/semic.h>
+
+// ----------------------------------------------------------------------------
+//  Copy constructor for  spectrum
+// ----------------------------------------------------------------------------
+
+spectrum::spectrum( const spectrum &spec )
+{
+    copy_deep( spec );
+}
+
+// ----------------------------------------------------------------------------
+//  Destructor for  spectrum
+// ----------------------------------------------------------------------------
+
+spectrum::~spectrum( )
+{
+    copy_delete( );
+}
+
+// ----------------------------------------------------------------------------
+//  Allocate memory for a spectrum of  k  numbers
+// ----------------------------------------------------------------------------
+
+void spectrum::copy_new( int k )
+{
+    if( k > 0 )
+    {
+        s = new Rational[k];
+        w = new int[k];
+
+        #ifndef SING_NDEBUG
+        if( s == (Rational*)NULL || w == (int*)NULL )
+        {
+            #ifdef SEMIC_PRINT
+            #ifdef SEMIC_IOSTREAM
+                cerr << "spectrum::copy_new(" << k << ")" << endl;
+                cerr << "    returned ZERO!!!" << endl;
+                cerr << "    exit..." << endl;
+            #else
+                fprintf( stderr,"spectrum::copy_new( %d )\n",k );
+                fprintf( stderr,"    returned ZERO!!!\n" );
+                fprintf( stderr,"    exit...\n" );
+            #endif
+            #endif
+        }
+        #endif
+    }
+    else if( k == 0 )
+    {
+        s = (Rational*)NULL;
+        w = (int*)NULL;
+    }
+    else if( k < 0 )
+    {
+        #ifdef SEMIC_PRINT
+        #ifdef SEMIC_IOSTREAM
+                cerr << "spectrum::copy_new(" << k << ")";
+                cerr << ": k < 0 ..." << endl;
+        #else
+                fprintf( stderr,"spectrum::copy_new( %d )",k );
+                fprintf( stderr,": k < 0 ...\n" );
+        #endif
+        #endif
+
+        exit( 1 );
+    }
+}
+
+// ----------------------------------------------------------------------------
+//  Initialize a  spectrum  deep from another  spectrum
+// ----------------------------------------------------------------------------
+
+void spectrum::copy_deep( const spectrum &spec )
+{
+    mu = spec.mu;
+    pg = spec.pg;
+    n  = spec.n;
+
+    copy_new( n );
+
+    for( int i=0; i<n; i++ )
+    {
+        s[i] = spec.s[i];
+        w[i] = spec.w[i];
+    }
+}
+
+// ----------------------------------------------------------------------------
+//  operator  =  for  spectrum
+// ----------------------------------------------------------------------------
+
+spectrum spectrum::operator = ( const spectrum &spec )
+{
+    copy_delete( );
+    copy_deep( spec );
+
+    return *this;
+}
+
+// ----------------------------------------------------------------------------
+//  add the two spectra  s1  and  s2  and return their sum
+// ----------------------------------------------------------------------------
+
+spectrum  operator + ( const spectrum &s1,const spectrum &s2 )
+{
+    int i1=0, i2=0, i3=0;
+
+    spectrum result;
+
+    do
+    {
+        if( i1 >= s1.n )
+        {
+            i2++;
+        }
+        else if( i2 >= s2.n )
+        {
+            i1++;
+        }
+        else if( s1.s[i1] < s2.s[i2] )
+        {
+            i1++;
+        }
+        else if( s1.s[i1] == s2.s[i2] )
+        {
+            i1++;
+            i2++;
+        }
+        else
+        {
+            i2++;
+        }
+        i3++;
+    }
+    while( i1 < s1.n || i2 < s2.n );
+
+    result.copy_new( i3 );
+    result.n = i3;
+
+    i1 = i2 = i3 = 0;
+
+    do
+    {
+        if( i1 >= s1.n )
+        {
+            result.s[i3] = s2.s[i2];
+            result.w[i3] = s2.w[i2];
+            i2++;
+        }
+        else if( i2 >= s2.n )
+        {
+            result.s[i3] = s1.s[i1];
+            result.w[i3] = s1.w[i1];
+            i1++;
+        }
+        else if( s1.s[i1] < s2.s[i2] )
+        {
+            result.s[i3] = s1.s[i1];
+            result.w[i3] = s1.w[i1];
+            i1++;
+          }
+        else if( s1.s[i1] == s2.s[i2] )
+        {
+            result.s[i3] = s1.s[i1];
+            result.w[i3] = s1.w[i1] + s2.w[i2];
+            i1++;
+            i2++;
+        }
+        else
+        {
+            result.s[i3] = s2.s[i2];
+            result.w[i3] = s2.w[i2];
+            i2++;
+        }
+        i3++;
+    }
+    while( i1 < s1.n || i2 < s2.n );
+
+    result.mu = s1.mu + s2.mu;
+    result.pg = s1.pg + s2.pg;
+
+    return  result;
+}
+
+// ----------------------------------------------------------------------------
+//  multiply the multiplicities of the spectrum numbers of  a  with  m
+// ----------------------------------------------------------------------------
+
+spectrum operator * ( int k,const spectrum &spec )
+{
+    if( k == 0 )
+    {
+        spectrum result;
+
+        return  result;
+    }
+    else
+    {
+        spectrum result( spec );
+
+        result.mu *= k;
+        result.pg *= k;
+
+        for( int i=0; i<result.n; i++ )
+        {
+            result.w[i] *= k;
+        }
+
+        return  result;
+    }
+}
+
+// ----------------------------------------------------------------------------
+//  Print a  spectrum
+// ----------------------------------------------------------------------------
+
+#ifdef SEMIC_PRINT
+
+ostream & operator << ( ostream &s,const spectrum &spec )
+{
+    for( int i=0; i<spec.n; i++ )
+    {
+        if( i>0 )
+        {
+            #ifdef SEMIC_STDOUT
+                s << "+";
+            #else
+                fprintf( stdout,"+" );
+            #endif
+        }
+
+        #ifdef SEMIC_STDOUT
+            s << spec.w[i] << "*t^";
+        #else
+            fprintf( stdout,"%d*t^",spec.w[i] );
+        #endif
+
+        s << spec.s[i];
+    }
+
+    return s;
+}
+#endif
+
+// ----------------------------------------------------------------------------
+//  Add a subspectrum with multiplicity  k  (faster than '+')
+// ----------------------------------------------------------------------------
+
+int    spectrum::add_subspectrum( spectrum &a,int k )
+{
+    int i,j;
+    for( i=0, j=0; i<n; i++ )
+    {
+        if( s[i] == a.s[j] )
+        {
+            w[i] += k*a.w[j];
+            j++;
+        }
+    }
+
+    return ( j == a.n ? TRUE : FALSE );
+}
+
+// ----------------------------------------------------------------------------
+//  set  *alpha  to the next spectrum number strictly bigger than  *alpha
+//  returns: TRUE, if such a spectrum number exists
+//           FALSE otherwise
+// ----------------------------------------------------------------------------
+
+int    spectrum::next_number( Rational *alpha )
+{
+    int i=0;
+
+    while( i < n && *alpha >= s[i]  )
+    {
+        i++;
+    }
+
+    if( i < n )
+    {
+        *alpha = s[i];
+        return TRUE;
+    }
+    else
+    {
+        return FALSE;
+    }
+}
+
+// ----------------------------------------------------------------------------
+//  find the next interval on the real line of same length as
+//  [*alpha1,*alpha2]  having a spectrum number as interval border
+// ----------------------------------------------------------------------------
+
+int     spectrum::next_interval( Rational *alpha1,Rational *alpha2 )
+{
+    Rational zero( 0,1 );
+    Rational a1 = *alpha1;
+    Rational a2 = *alpha2;
+    Rational d  = *alpha2 - *alpha1;
+
+    int    e1 = this->next_number( &a1 );
+    int    e2 = this->next_number( &a2 );
+
+    if( e1 || e2 )
+    {
+        Rational d1 = a1 - *alpha1;
+        Rational d2 = a2 - *alpha2;
+
+        if( d1 < d2 || d2 == zero )
+        {
+            *alpha1 = a1;
+            *alpha2 = a1 + d;
+        }
+        else
+        {
+            *alpha1 = a2 - d;
+            *alpha2 = a2;
+        }
+        return  TRUE;
+    }
+    else
+    {
+        return  FALSE;
+    }
+}
+
+// ----------------------------------------------------------------------------
+//  compute the numver of spectrum numbers in the inverval  [*alpha1,*alpha2]
+// ----------------------------------------------------------------------------
+
+int     spectrum::numbers_in_interval( Rational &alpha1,
+                Rational &alpha2,interval_status status )
+{
+    int count = 0;
+
+    for( int i=0; i<n; i++ )
+    {
+        if( ( ( status == OPEN   || status == LEFTOPEN  ) &&
+              s[i] >  alpha1 ) ||
+            ( ( status == CLOSED || status == RIGHTOPEN ) &&
+              s[i] >= alpha1 ) )
+        {
+              if( ( ( status == OPEN   || status == RIGHTOPEN  ) &&
+                  s[i] <  alpha2 ) ||
+                ( ( status == CLOSED || status == LEFTOPEN ) &&
+                  s[i] <= alpha2 ) )
+            {
+                count += w[i];
+            }
+            else
+            {
+                break;
+            }
+        }
+    }
+
+    return count;
+}
+
+// ----------------------------------------------------------------------------
+//  find the maximal integer  k  such that  k*t is semicontinous
+//  for the spectrum
+// ----------------------------------------------------------------------------
+
+int     spectrum::mult_spectrum( spectrum &t )
+{
+    spectrum u = *this + t;
+
+    Rational alpha1 = -2;
+    Rational alpha2 = -1;
+
+    int      mult=MAX_INT_VAL,nthis,nt;
+
+    while( u.next_interval( &alpha1,&alpha2 ) )
+    {
+        nt    = t.numbers_in_interval( alpha1,alpha2,LEFTOPEN );
+        nthis = this->numbers_in_interval( alpha1,alpha2,LEFTOPEN );
+
+        if( nt != 0 )
+        {
+            mult = (nthis/nt < mult ? nthis/nt: mult );
+        }
+
+    }
+
+    return  mult;
+}
+
+// ----------------------------------------------------------------------------
+//  find the maximal integer  k  such that  k*t is semicontinous
+//  for the spectrum (in the homogeneous sense)
+// ----------------------------------------------------------------------------
+
+int     spectrum::mult_spectrumh( spectrum &t )
+{
+    spectrum u = *this + t;
+
+    Rational alpha1 = -2;
+    Rational alpha2 = -1;
+
+    int      mult=MAX_INT_VAL,nthis,nt;
+
+    while( u.next_interval( &alpha1,&alpha2 ) )
+    {
+        nt    = t.numbers_in_interval( alpha1,alpha2,LEFTOPEN );
+        nthis = this->numbers_in_interval( alpha1,alpha2,LEFTOPEN );
+
+        if( nt != 0 )
+        {
+            mult = (nthis/nt < mult ? nthis/nt: mult );
+        }
+
+        nt    = t.numbers_in_interval( alpha1,alpha2,OPEN );
+        nthis = this->numbers_in_interval( alpha1,alpha2,OPEN );
+
+        if( nt != 0 )
+        {
+            mult = (nthis/nt < mult ? nthis/nt: mult );
+        }
+    }
+
+    return  mult;
+}
+
+// ----------------------------------------------------------------------------
+//  Set the Milnor number
+// ----------------------------------------------------------------------------
+
+/*
+int spectrum::set_milnor( void )
+{
+   mu = 0;
+
+   for( int i=0; i<n; i++ )
+   {
+      mu += w[i];
+   }
+
+   return  mu;
+}
+
+// ----------------------------------------------------------------------------
+//  Set the geometrical genus
+// ----------------------------------------------------------------------------
+
+int spectrum::set_geometric_genus( void )
+{
+   pg = 0;
+
+   for( int i=0; i<n && s[i]<=1; i++ )
+   {
+      pg += w[i];
+   }
+   return  pg;
+}
+*/
+
+#endif /* HAVE_SPECTRUM */
+// ----------------------------------------------------------------------------
+//  semic.cc
+//  end of file
+// ----------------------------------------------------------------------------
diff --git a/kernel/spectrum/semic.h b/kernel/spectrum/semic.h
new file mode 100644
index 0000000..814132b
--- /dev/null
+++ b/kernel/spectrum/semic.h
@@ -0,0 +1,148 @@
+// ----------------------------------------------------------------------------
+//  semic.h
+//  begin of file
+//  Stephan Endrass, endrass at mathematik.uni-mainz.de
+//  23.7.99
+// ----------------------------------------------------------------------------
+
+// ----------------------------------------------------------------------------
+//  here we define a class  spectrum  to test semicontinuity
+// ----------------------------------------------------------------------------
+
+#ifndef SEMIC_H
+#define SEMIC_H
+
+#ifdef HAVE_SPECTRUM
+
+
+#include <kernel/spectrum/GMPrat.h>
+
+typedef enum
+{
+    OPEN,
+    LEFTOPEN,
+    RIGHTOPEN,
+    CLOSED
+
+} interval_status;
+
+/*typedef enum
+{
+    semicOK,
+    semicMulNegative,
+
+    semicListTooShort,
+    semicListTooLong,
+
+    semicListFirstElementWrongType,
+    semicListSecondElementWrongType,
+    semicListThirdElementWrongType,
+    semicListFourthElementWrongType,
+    semicListFifthElementWrongType,
+    semicListSixthElementWrongType,
+
+    semicListNNegative,
+    semicListWrongNumberOfNumerators,
+    semicListWrongNumberOfDenominators,
+    semicListWrongNumberOfMultiplicities,
+
+    semicListMuNegative,
+    semicListPgNegative,
+    semicListNumNegative,
+    semicListDenNegative,
+    semicListMulNegative,
+
+    semicListNotSymmetric,
+    semicListNotMonotonous,
+
+    semicListMilnorWrong,
+    semicListPGWrong
+
+} semicState; */ //TODO move to Singular
+
+class spectrum
+{
+public:
+
+    int         mu;      // milnor number
+    int         pg;      // geometrical genus
+    int         n;       // # of spectrum numbers
+    Rational    *s;      // spectrum numbers
+    int         *w;      // multiplicities
+
+//    spectrum( );
+//    spectrum( lists );
+
+    ///  Zero constructor
+    spectrum( )
+    {
+       copy_zero( );
+    }
+
+    spectrum( const spectrum& );
+
+    ~spectrum( );
+
+    spectrum operator = ( const spectrum& );
+//    spectrum operator = ( lists );
+
+    friend spectrum   operator + ( const spectrum&,const spectrum& );
+    friend spectrum   operator * ( int,const spectrum& );
+
+    #ifdef SEMIC_PRINT
+    friend ostream &  operator << ( ostream&,const spectrum& );
+    #endif /*SEMIC_PRINT*/
+
+    void    copy_new    ( int );
+//    void    copy_delete ( void );
+
+///  Delete the memory of a spectrum
+inline void copy_delete( void )
+{
+    if( s != (Rational*)NULL && n > 0 ) delete [] s;
+    if( w != (int*)NULL      && n > 0 ) delete [] w;
+    copy_zero( );
+}
+
+///  Initialize with zero
+inline void copy_zero( void )
+{
+    mu = 0;
+    pg = 0;
+    n  = 0;
+    s  = (Rational*)NULL;
+    w  = (int*)NULL;
+}
+
+///  Initialize shallow from another spectrum
+inline void copy_shallow( spectrum &spec )
+{
+    mu = spec.mu;
+    pg = spec.pg;
+    n  = spec.n;
+    s  = spec.s;
+    w  = spec.w;
+}
+
+    void    copy_deep   ( const spectrum& );
+//    void    copy_deep   ( lists );
+
+//    lists   thelist     ( void );
+
+    int     add_subspectrum    ( spectrum&,int );
+    int     next_number        ( Rational* );
+    int     next_interval      ( Rational*,Rational* );
+    int     numbers_in_interval( Rational&,Rational&,interval_status );
+    int     mult_spectrum      ( spectrum& );
+    int     mult_spectrumh     ( spectrum& );
+
+    //    int     set_milnor         ( void );
+    //   int     set_geometric_genus( void );
+};
+
+#endif /*HAVE_SPECTRUM*/
+// ----------------------------------------------------------------------------
+//  semic.h
+//  end of file
+// ----------------------------------------------------------------------------
+#endif
diff --git a/kernel/spectrum/spectrum.cc b/kernel/spectrum/spectrum.cc
new file mode 100644
index 0000000..bd9476f
--- /dev/null
+++ b/kernel/spectrum/spectrum.cc
@@ -0,0 +1,523 @@
+// ----------------------------------------------------------------------------
+//  spectrum.cc
+//  begin of file
+//  Stephan Endrass, endrass at mathematik.uni-mainz.de
+//  23.7.99
+// ----------------------------------------------------------------------------
+
+#define SPECTRUM_CC
+
+
+
+
+#include <kernel/mod2.h>
+
+#ifdef HAVE_SPECTRUM
+
+#ifdef  SPECTRUM_PRINT
+#include <iostream.h>
+#ifndef  SPECTRUM_IOSTREAM
+#include <stdio.h>
+#endif
+#endif
+
+#include <misc/mylimits.h>
+
+#include <coeffs/numbers.h>
+#include <polys/monomials/p_polys.h>
+#include <polys/simpleideals.h>
+#include <misc/intvec.h>
+#include <polys/monomials/ring.h>
+//extern ring currRing;
+
+#include <kernel/GBEngine/kstd1.h>
+#include <kernel/combinatorics/stairc.h>
+#include <kernel/spectrum/multicnt.h>
+#include <kernel/spectrum/GMPrat.h>
+#include <kernel/spectrum/kmatrix.h>
+#include <kernel/spectrum/npolygon.h>
+#include <kernel/spectrum/splist.h>
+#include <kernel/spectrum/semic.h>
+
+// ----------------------------------------------------------------------------
+//  test if the polynomial  h  has a term of total degree d
+// ----------------------------------------------------------------------------
+
+BOOLEAN hasTermOfDegree( poly h, int d, const ring r )
+{
+  do
+  {
+    if( p_Totaldegree( h,r )== d )
+      return  TRUE;
+    pIter(h);
+  }
+  while( h!=NULL );
+
+  return  FALSE;
+}
+
+// ----------------------------------------------------------------------------
+//  test if the polynomial  h  has a constant term
+// ----------------------------------------------------------------------------
+
+static BOOLEAN inline hasConstTerm( poly h, const ring r )
+{
+  return  hasTermOfDegree(h,0,r);
+}
+
+// ----------------------------------------------------------------------------
+//  test if the polynomial  h  has a linear term
+// ----------------------------------------------------------------------------
+
+static BOOLEAN inline hasLinearTerm( poly h, const ring r )
+{
+  return  hasTermOfDegree(h,1,r);
+}
+
+// ----------------------------------------------------------------------------
+//  test if the ideal  J  has a lead monomial on the axis number  k
+// ----------------------------------------------------------------------------
+
+BOOLEAN hasAxis( ideal J,int k, const ring r )
+{
+  int i;
+
+  for( i=0; i<IDELEMS(J); i++ )
+  {
+    if (p_IsPurePower( J->m[i],r ) == k) return TRUE;
+  }
+  return  FALSE;
+}
+
+// ----------------------------------------------------------------------------
+//  test if the ideal  J  has  1  as a lead monomial
+// ----------------------------------------------------------------------------
+
+int     hasOne( ideal J, const ring r )
+{
+  int i;
+
+  for( i=0; i<IDELEMS(J); i++ )
+  {
+    if (p_IsConstant(J->m[i],r)) return TRUE;
+  }
+  return  FALSE;
+}
+// ----------------------------------------------------------------------------
+//  test if  m  is a multiple of one of the monomials of  f
+// ----------------------------------------------------------------------------
+
+int     isMultiple( poly f,poly m, const ring r )
+{
+  while( f!=NULL )
+  {
+    // ---------------------------------------------------
+    //  for a local order  f|m  is only possible if  f>=m
+    // ---------------------------------------------------
+
+    if( p_LmCmp( f,m,r )>=0 )
+    {
+      if( p_LmDivisibleByNoComp( f,m,r ) )
+      {
+        return  TRUE;
+      }
+      else
+      {
+        pIter( f );
+      }
+    }
+    else
+    {
+      return FALSE;
+    }
+  }
+
+  return  FALSE;
+}
+
+// ----------------------------------------------------------------------------
+//  compute the minimal monomial of minimmal  weight>=max_weight
+// ----------------------------------------------------------------------------
+
+poly    computeWC( const newtonPolygon &np,Rational max_weight, const ring r )
+{
+  poly m  = p_One(r);
+  poly wc = NULL;
+  int  mdegree;
+
+  for( int i=1; i<=r->N; i++ )
+  {
+    mdegree = 1;
+    p_SetExp( m,i,mdegree,r );
+    // pSetm( m );
+    // np.weight_shift does not need pSetm( m ), postpone it
+
+    while(  np.weight_shift( m,r )<max_weight )
+    {
+      mdegree++;
+      p_SetExp( m,i,mdegree,r );
+      // pSetm( m );
+      // np.weight_shift does not need pSetm( m ), postpone it
+    }
+    p_Setm( m,r );
+
+    if( i==1 || p_Cmp( m,wc,r )<0 )
+    {
+      p_Delete( &wc,r );
+      wc = p_Head( m,r );
+    }
+
+    p_SetExp( m,i,0,r );
+  }
+
+  p_Delete( &m,r );
+
+  return  wc;
+}
+
+// ----------------------------------------------------------------------------
+//  deletes all monomials of  f  which are less than  hc
+// ----------------------------------------------------------------------------
+
+static inline  poly    normalFormHC( poly f,poly hc, const ring r )
+{
+  poly    *ptr = &f;
+
+  while( (*ptr)!=NULL )
+  {
+    if( p_LmCmp( *ptr,hc,r )>=0 )
+    {
+      ptr = &(pNext( *ptr ));
+    }
+    else
+    {
+      p_Delete( ptr,r );
+      return  f;
+    }
+  }
+
+  return f;
+}
+
+// ----------------------------------------------------------------------------
+//  deletes all monomials of  f  which are multiples of monomials of  Z
+// ----------------------------------------------------------------------------
+
+static inline  poly    normalFormZ( poly f,poly Z, const ring r )
+{
+  poly    *ptr = &f;
+
+  while( (*ptr)!=NULL )
+  {
+    if( !isMultiple( Z,*ptr,r ) )
+    {
+      ptr = &(pNext( *ptr ));
+    }
+    else
+    {
+      p_LmDelete(ptr,r);
+    }
+  }
+
+  return f;
+}
+
+// ?? HS:
+// Looks for the shortest polynomial f in stdJ which is divisible
+// by the monimial m, return its index in stdJ
+// ----------------------------------------------------------------------------
+//  Looks for the first polynomial f in stdJ which satisfies m=LT(f)*eta
+//  for a monomial eta. The return eta*f-m and cancel all monomials
+//  which are smaller than the highest corner hc
+// ----------------------------------------------------------------------------
+
+static inline  int     isLeadMonomial( poly m,ideal stdJ, const ring r )
+{
+  int     length = MAX_INT_VAL;
+  int     result = -1;
+
+  for( int i=0; i<IDELEMS(stdJ); i++ )
+  {
+    if( p_Cmp( stdJ->m[i],m,r )>=0 && p_DivisibleBy( stdJ->m[i],m,r ) )
+    {
+      int     tmp = pLength( stdJ->m[i] );
+
+      if( tmp < length )
+      {
+        length = tmp;
+        result = i;
+      }
+    }
+  }
+
+  return  result;
+}
+
+// ----------------------------------------------------------------------------
+//  set the exponent of a monomial t an integer array
+// ----------------------------------------------------------------------------
+
+static void    setExp( poly m,int *r, const ring s )
+{
+  for( int i=s->N; i>0; i-- )
+  {
+    p_SetExp( m,i,r[i-1],s );
+  }
+  p_Setm( m,s );
+}
+
+// ----------------------------------------------------------------------------
+//  check if the ordering is a reverse wellordering, i.e. every monomial
+//  is smaller than only finitely monomials
+// ----------------------------------------------------------------------------
+
+static BOOLEAN isWell( const ring r )
+{
+  int b = rBlocks( r );
+
+  if( b==3 &&
+      ( r->order[0] == ringorder_ds ||
+        r->order[0] == ringorder_Ds ||
+        r->order[0] == ringorder_ws ||
+        r->order[0] == ringorder_Ws ) )
+  {
+    return  TRUE;
+  }
+  else if( b>=3
+  && (( r->order[0] ==ringorder_a
+        && r->block1[0]==r->N )
+    || (r->order[0]==ringorder_M
+        && r->block1[0]==r->N*r->N )))
+  {
+    for( int i=r->N-1; i>=0; i-- )
+    {
+      if( r->wvhdl[0][i]>=0 )
+      {
+        return  FALSE;
+      }
+    }
+    return  TRUE;
+  }
+
+  return  FALSE;
+}
+
+// ----------------------------------------------------------------------------
+//  compute all monomials not in  stdJ  and their normal forms
+// ----------------------------------------------------------------------------
+
+void    computeNF( ideal stdJ,poly hc,poly wc,spectrumPolyList *NF, const ring r )
+{
+  int         carry,k;
+  multiCnt    C( r->N,0 );
+  poly        Z = NULL;
+
+  int         well = isWell(r);
+
+  do
+  {
+    poly    m = p_One(r);
+    setExp( m,C.cnt,r );
+
+    carry = FALSE;
+
+    k = isLeadMonomial( m,stdJ,r );
+
+    if( k < 0 )
+    {
+      // ---------------------------
+      //  m  is not a lead monomial
+      // ---------------------------
+
+      NF->insert_node( m,NULL,r );
+    }
+    else if( isMultiple( Z,m,r ) )
+    {
+      // ------------------------------------
+      //  m  is trivially in the ideal  stdJ
+      // ------------------------------------
+
+      p_Delete( &m,r );
+      carry = TRUE;
+    }
+    else if( p_Cmp( m,hc,r ) < 0 || p_Cmp( m,wc,r ) < 0 )
+    {
+      // -------------------
+      //  we do not need  m
+      // -------------------
+
+      p_Delete( &m,r );
+      carry = TRUE;
+    }
+    else
+    {
+      // --------------------------
+      //  compute lazy normal form
+      // --------------------------
+
+      poly    multiplicant = p_Divide( m,stdJ->m[k],r );
+      pGetCoeff( multiplicant ) = n_Init(1,r->cf);
+
+      poly    nf = p_Mult_mm( p_Copy( stdJ->m[k],r ), multiplicant,r );
+
+      p_Delete( &multiplicant,r );
+
+      nf = normalFormHC( nf,hc,r );
+
+      if( pNext( nf )==NULL )
+      {
+        // ----------------------------------
+        //  normal form of  m  is  m  itself
+        // ----------------------------------
+
+        p_Delete( &nf,r );
+        NF->delete_monomial( m,r );
+        Z = p_Add_q( Z,m,r );
+        carry = TRUE;
+      }
+      else
+      {
+        nf = normalFormZ( nf,Z,r );
+
+        if( pNext( nf )==NULL )
+        {
+          // ----------------------------------
+          //  normal form of  m  is  m  itself
+          // ----------------------------------
+
+          p_Delete( &nf,r );
+          NF->delete_monomial( m,r );
+          Z = p_Add_q( Z,m,r );
+          carry = TRUE;
+        }
+        else
+        {
+          // ------------------------------------
+          //  normal form of  m  is a polynomial
+          // ------------------------------------
+
+          p_Norm( nf,r );
+          if( well==TRUE )
+          {
+            NF->insert_node( m,nf,r );
+          }
+          else
+          {
+            poly    nfhard = kNF( stdJ,(ideal)NULL,pNext( nf ),0,0 );
+            nfhard = normalFormHC( nfhard,hc,r );
+            nfhard = normalFormZ ( nfhard,Z,r );
+
+            if( nfhard==NULL )
+            {
+              NF->delete_monomial( m,r );
+              Z = p_Add_q( Z,m,r );
+              carry = TRUE;
+            }
+            else
+            {
+              p_Delete( &pNext( nf ),r );
+              pNext( nf ) = nfhard;
+              NF->insert_node( m,nf,r );
+            }
+          }
+        }
+      }
+    }
+  }
+  while( C.inc( carry ) );
+
+  // delete single monomials
+
+  BOOLEAN  not_finished;
+
+  do
+  {
+    not_finished = FALSE;
+
+    spectrumPolyNode  *node = NF->root;
+
+    while( node!=(spectrumPolyNode*)NULL )
+    {
+      if( node->nf!=NULL && pNext( node->nf )==NULL )
+      {
+        NF->delete_monomial( node->nf,r );
+        not_finished = TRUE;
+        node = (spectrumPolyNode*)NULL;
+      }
+      else
+      {
+        node = node->next;
+      }
+    }
+  } while( not_finished );
+
+  p_Delete( &Z,r );
+}
+
+// ----------------------------------------------------------------------------
+//  check if  currRing is local
+// ----------------------------------------------------------------------------
+
+BOOLEAN ringIsLocal( const ring r )
+{
+  poly    m   = p_One(r);
+  poly    one = p_One(r);
+  BOOLEAN res=TRUE;
+
+  for( int i=r->N; i>0; i-- )
+  {
+    p_SetExp( m,i,1,r );
+    p_Setm( m,r );
+
+    if( p_Cmp( m,one,r )>0 )
+    {
+      res=FALSE;
+      break;
+    }
+    p_SetExp( m,i,0,r );
+  }
+
+  p_Delete( &m,r );
+  p_Delete( &one,r );
+
+  return  res;
+}
+
+// ----------------------------------------------------------------------------
+// print error message corresponding to spectrumState state:
+// ----------------------------------------------------------------------------
+/*void spectrumPrintError(spectrumState state)
+{
+  switch( state )
+  {
+    case spectrumZero:
+      WerrorS( "polynomial is zero" );
+      break;
+    case spectrumBadPoly:
+      WerrorS( "polynomial has constant term" );
+      break;
+    case spectrumNoSingularity:
+      WerrorS( "not a singularity" );
+      break;
+    case spectrumNotIsolated:
+      WerrorS( "the singularity is not isolated" );
+      break;
+    case spectrumNoHC:
+      WerrorS( "highest corner cannot be computed" );
+      break;
+    case spectrumDegenerate:
+      WerrorS( "principal part is degenerate" );
+      break;
+    case spectrumOK:
+      break;
+
+    default:
+      WerrorS( "unknown error occurred" );
+      break;
+  }
+}*/
+#endif /* HAVE_SPECTRUM */
+// ----------------------------------------------------------------------------
+//  spectrum.cc
+//  end of file
+// ----------------------------------------------------------------------------
diff --git a/kernel/spectrum/spectrum.h b/kernel/spectrum/spectrum.h
new file mode 100644
index 0000000..ab3e666
--- /dev/null
+++ b/kernel/spectrum/spectrum.h
@@ -0,0 +1,39 @@
+// ----------------------------------------------------------------------------
+//  spectrum.h
+//  begin of file
+//  Stephan Endrass, endrass at mathematik.uni-mainz.de
+//  23.7.99
+// ----------------------------------------------------------------------------
+
+#ifndef SPECTRUM_H
+#define SPECTRUM_H
+#include <kernel/spectrum/npolygon.h>
+#include <kernel/spectrum/splist.h>
+
+/*BOOLEAN    spectrumProc ( leftv,leftv );
+BOOLEAN    spectrumfProc( leftv,leftv );
+BOOLEAN    spaddProc    ( leftv,leftv,leftv );
+BOOLEAN    spmulProc    ( leftv,leftv,leftv );
+BOOLEAN    semicProc   ( leftv,leftv,leftv );
+BOOLEAN    semicProc3   ( leftv,leftv,leftv,leftv );*/ //TODO move to kernel
+
+BOOLEAN    hasTermOfDegree( poly h, int d, const ring r );
+int        hasOne( ideal J, const ring r );
+BOOLEAN    hasAxis( ideal J,int k, const ring r );
+poly       computeWC( const newtonPolygon &np,Rational max_weight, const ring r );
+void       computeNF( ideal stdJ,poly hc,poly wc,spectrumPolyList *NF, const ring r );
+//void       spectrumPrintError(spectrumState state);
+BOOLEAN    ringIsLocal( const ring r);
+
+BOOLEAN inline hasConstTerm( poly h, const ring r )
+{ return  hasTermOfDegree(h,0,r); }
+BOOLEAN inline hasLinearTerm( poly h, const ring r )
+{ return  hasTermOfDegree(h,1,r); }
+
+
+#endif
+
+// ----------------------------------------------------------------------------
+//  spectrum.h
+//  end of file
+// ----------------------------------------------------------------------------
diff --git a/kernel/spectrum/splist.cc b/kernel/spectrum/splist.cc
new file mode 100644
index 0000000..84fdc98
--- /dev/null
+++ b/kernel/spectrum/splist.cc
@@ -0,0 +1,386 @@
+// ----------------------------------------------------------------------------
+//  splist.cc
+//  begin of file
+//  Stephan Endrass, endrass at mathematik.uni-mainz.de
+//  23.7.99
+// ----------------------------------------------------------------------------
+
+#define SPLIST_CC
+
+
+
+
+#include <kernel/mod2.h>
+
+#ifdef HAVE_SPECTRUM
+
+#ifdef  SPLIST_PRINT
+#include <iostream.h>
+#ifndef SPLIST_IOSTREAM
+#include <stdio.h>
+#endif
+#endif
+
+#include <kernel/structs.h>
+#include <kernel/spectrum/GMPrat.h>
+#include <coeffs/numbers.h>
+#include <polys/monomials/p_polys.h>
+#include <kernel/spectrum/npolygon.h>
+#include <kernel/spectrum/splist.h>
+#include <misc/intvec.h>
+
+// ------------------------
+//  class spectrumPolyNode
+// ------------------------
+
+// ----------------------------------------------------------------------------
+//  Initialize a  spectrumPolyNode  with zero
+// ----------------------------------------------------------------------------
+
+void    spectrumPolyNode::copy_zero( void )
+{
+    next   = (spectrumPolyNode*)NULL;
+    mon    = NULL;
+    weight = (Rational)0;
+    nf     = NULL;
+    r      = NULL;
+}
+
+// ----------------------------------------------------------------------------
+//  Inizialize a  spectrumPolyNode  shallow from data
+// ----------------------------------------------------------------------------
+
+void    spectrumPolyNode::copy_shallow(
+         spectrumPolyNode *pnode,poly m,const Rational &w,poly f, const ring R )
+{
+    next   = pnode;
+    mon    = m;
+    weight = w;
+    nf     = f;
+    r      = R;
+}
+
+// ----------------------------------------------------------------------------
+//  Inizialize a  spectrumPolyNode  shallow from another  spectrumPolyNode
+// ----------------------------------------------------------------------------
+
+void    spectrumPolyNode::copy_shallow( spectrumPolyNode &node )
+{
+    next   = node.next;
+    mon    = node.mon;
+    weight = node.weight;
+    nf     = node.nf;
+    r      = node.r;
+}
+
+// ----------------------------------------------------------------------------
+//  Zero constructor for  spectrumPolyNode
+// ----------------------------------------------------------------------------
+
+spectrumPolyNode::spectrumPolyNode( )
+{
+    copy_zero( );
+}
+
+// ----------------------------------------------------------------------------
+//  Data constructor for  spectrumPolyNode  is shallow
+// ----------------------------------------------------------------------------
+
+spectrumPolyNode::spectrumPolyNode(
+        spectrumPolyNode *pnode,poly m,const Rational &w,poly f, const ring R )
+{
+    copy_shallow( pnode,m,w,f,R );
+}
+
+// ----------------------------------------------------------------------------
+//  Destructor is empty since we construct our objects shallow
+// ----------------------------------------------------------------------------
+
+spectrumPolyNode::~spectrumPolyNode()
+{
+    if( mon!=NULL ) p_Delete( &mon, r );
+    if( nf !=NULL ) p_Delete( &nf,r );
+    copy_zero( );
+}
+
+// ------------------------
+//  class spectrumPolyList
+// ------------------------
+
+// ----------------------------------------------------------------------------
+//  Initialize a  spectrumPolyList  with zero
+// ----------------------------------------------------------------------------
+
+void    spectrumPolyList::copy_zero( void )
+{
+    root = (spectrumPolyNode*)NULL;
+    N    = 0;
+    np   = (newtonPolygon*)NULL;
+}
+
+// ----------------------------------------------------------------------------
+//  Inizialize a  spectrumPolyList  shallow from data
+// ----------------------------------------------------------------------------
+
+void    spectrumPolyList::copy_shallow(
+                spectrumPolyNode *node,int k,newtonPolygon *npolygon )
+{
+    root = node;
+    N    = k;
+    np   = npolygon;
+}
+
+// ----------------------------------------------------------------------------
+//  Inizialize a  spectrumPolyList  shallow from another  spectrumPolyList
+// ----------------------------------------------------------------------------
+
+void    spectrumPolyList::copy_shallow( spectrumPolyList &splist )
+{
+    copy_shallow( splist.root,splist.N,splist.np );
+}
+
+// ----------------------------------------------------------------------------
+//  Zero constructor for  spectrumPolyList
+// ----------------------------------------------------------------------------
+
+spectrumPolyList::spectrumPolyList( )
+{
+    copy_zero( );
+}
+
+// ----------------------------------------------------------------------------
+//  Data constructor for  spectrumPolyList
+// ----------------------------------------------------------------------------
+
+spectrumPolyList::spectrumPolyList( newtonPolygon *npolygon )
+{
+    copy_shallow( (spectrumPolyNode*)NULL,0,npolygon );
+}
+
+// ----------------------------------------------------------------------------
+//  Destuctor for  spectrumPolyList
+// ----------------------------------------------------------------------------
+
+spectrumPolyList::~spectrumPolyList( )
+{
+    spectrumPolyNode *node;
+
+    while( root!=(spectrumPolyNode*)NULL )
+    {
+        node = root->next;
+        delete root;
+        root = node;
+    }
+
+    copy_zero( );
+}
+
+// ----------------------------------------------------------------------------
+//  Insert a new node into a  spectrumPolyList  at position k
+//      If the list is sorted, then
+//      the new node ist inserted such that the list remains sorted.
+// ----------------------------------------------------------------------------
+
+void    spectrumPolyList::insert_node( poly m,poly f, const ring R )
+{
+    #ifdef SPLIST_DEBUG
+        if( np==(newtonPolygon*)NULL )
+        {
+            #ifdef SPLIST_PRINT
+            #ifdef SPLIST_IOSTREAM
+                cerr << "void    spectrumPolyList::insert_node( poly f )" << endl;
+                cerr << "    no Newton polygon" << endl;
+                cerr << "    exiting..." << endl;
+            #else
+                fprintf( stderr,"void    spectrumPolyList::insert_node( poly f )\n" );
+                fprintf( stderr,"    no Newton polygon\n" );
+                fprintf( stderr,"    exiting...\n" );
+            #endif
+            #endif
+
+            exit( 1 );
+        }
+    #endif
+
+    spectrumPolyNode    *newnode = new spectrumPolyNode(
+        (spectrumPolyNode*)NULL,m,np->weight_shift( m,R ),f, R );
+
+    if( N==0 ||
+              root->weight>newnode->weight ||
+            ( root->weight==newnode->weight &&
+              p_Cmp( root->mon,newnode->mon,R )<0 ) )
+    {
+        // ----------------------
+        //  insert at position 0
+        // ----------------------
+
+        newnode->next = root;
+        root          = newnode;
+    }
+    else if( N==1 )
+    {
+        // ---------------
+        //  insert at end
+        // ---------------
+
+        root->next    = newnode;
+    }
+    else
+    {
+        // ----------------------------
+        //  insert according to weight
+        // ----------------------------
+
+        spectrumPolyNode *actual = root;
+        spectrumPolyNode *next   = root->next;
+
+        while( next!=(spectrumPolyNode*)NULL &&
+               ( newnode->weight>next->weight ||
+               ( newnode->weight==next->weight &&
+                 p_Cmp( newnode->mon,next->mon, R )<0 ) ) )
+        {
+            actual = next;
+            next   = next->next;
+        }
+
+        actual->next = newnode;
+        newnode->next = next;
+    }
+    N++;
+}
+
+// ----------------------------------------------------------------------------
+//  Delete a node from a  spectrumPolyList
+// ----------------------------------------------------------------------------
+
+void    spectrumPolyList::delete_node( spectrumPolyNode **node )
+{
+    spectrumPolyNode *foo = *node;
+    *node = (*node)->next;
+    delete foo;
+    N--;
+}
+
+// ----------------------------------------------------------------------------
+//  Delete all nodes where   node->mon  is a multiple of  m
+//  In every node delete all instances of  m  in  node->nf
+// ----------------------------------------------------------------------------
+
+void    spectrumPolyList::delete_monomial( poly m, const ring R )
+{
+    spectrumPolyNode **node = &root;
+    poly              *f;
+
+    m = p_Copy( m,R );
+
+    while( *node!=(spectrumPolyNode*)NULL )
+    {
+        if( p_Cmp( m,(*node)->mon,R )>=0 && p_LmDivisibleByNoComp( m,(*node)->mon, R ))
+        {
+            delete_node( node );
+        }
+        else if( (*node)->nf!=NULL )
+        {
+            f = &((*node)->nf);
+
+            while( *f!=NULL )
+            {
+                if( p_Cmp( m,*f,R )>=0 && p_LmDivisibleByNoComp( m,*f,R ) )
+                {
+                    p_LmDelete(f,R);
+                }
+                else
+                {
+                    f = &(pNext( *f ));
+                }
+            }
+
+            if( (*node)->nf==NULL )
+            {
+                delete_node( node );
+            }
+            else
+            {
+                node = &((*node)->next);
+            }
+        }
+        else
+        {
+            node = &((*node)->next);
+        }
+    }
+    p_Delete( &m,R );
+}
+
+// ----------------------------------------------------------------------------
+//  Print a  spectrumPolyList
+// ----------------------------------------------------------------------------
+
+#ifdef SPLIST_PRINT
+ostream & operator << ( ostream &s,const spectrumPolyList &l )
+{
+    #ifdef SPLIST_IOSTREAM
+        s << "elements: " << l.N << endl;
+        s << "{";
+    #else
+        fprintf( stdout,"elements: %d\n",l.N );
+        fprintf( stdout,"{" );
+    #endif
+
+    if( l.root!=(spectrumPolyNode*)NULL )
+    {
+        #ifdef SPLIST_IOSTREAM
+            s << "(";
+            pWrite0( l.root->mon );
+            s << "=>";
+            pWrite0( l.root->nf );
+            cout << "," << l.root->weight << ")" << endl;
+        #else
+            fprintf( stdout,"(" );
+            pWrite0( l.root->mon );
+            fprintf( stdout,"=>" );
+            pWrite0( l.root->nf );
+            fprintf( stdout,"," );
+            cout << l.root->weight;
+            fprintf( stdout,")\n" );
+        #endif
+
+        spectrumPolyNode *node = l.root->next;
+
+        while( node!=(spectrumPolyNode*)NULL )
+        {
+            #ifdef SPLIST_IOSTREAM
+                s << ",(";
+                pWrite0( node->mon );
+                s << "=>";
+                pWrite0( node->nf );
+                cout << "," << node->weight << ")" << endl;
+            #else
+                fprintf( stdout,",(" );
+                pWrite0( node->mon );
+                fprintf( stdout,"=>" );
+                pWrite0( node->nf );
+                fprintf( stdout,"," );
+                cout << node->weight;
+                fprintf( stdout,")\n" );
+            #endif
+
+            node = node->next;
+        }
+    }
+    #ifdef SPLIST_IOSTREAM
+        s << "}";
+    #else
+        fprintf( stdout,"}" );
+    #endif
+
+    return  s;
+}
+#endif
+
+#endif /* HAVE_SPECTRUM */
+// ----------------------------------------------------------------------------
+//  splist.cc
+//  end of file
+// ----------------------------------------------------------------------------
+
diff --git a/kernel/spectrum/splist.h b/kernel/spectrum/splist.h
new file mode 100644
index 0000000..75fdbc7
--- /dev/null
+++ b/kernel/spectrum/splist.h
@@ -0,0 +1,89 @@
+// ----------------------------------------------------------------------------
+//  splist.h
+//  begin of file
+//  Stephan Endrass, endrass at mathematik.uni-mainz.de
+//  23.7.99
+// ----------------------------------------------------------------------------
+
+// ----------------------------------------------------------------------------
+//  Description: the class  spectrumPolyList  is to hold monomials
+//  and their normal forms with respect to a given standard basis
+//  and a given ordering. On this list we run a standard basis
+//  conversion algorithm to compute  the spectrum
+// ----------------------------------------------------------------------------
+
+#ifndef SPLIST_H
+#define SPLIST_H
+
+#include <kernel/spectrum/npolygon.h>
+
+/*enum    spectrumState
+{
+    spectrumOK,
+    spectrumZero,
+    spectrumBadPoly,
+    spectrumNoSingularity,
+    spectrumNotIsolated,
+    spectrumDegenerate,
+    spectrumWrongRing,
+    spectrumNoHC,
+    spectrumUnspecErr
+};*/ //TODO move to Singular
+
+// ----------------------------------------------------------------------------
+
+class spectrumPolyNode
+{
+public:
+
+    spectrumPolyNode    *next;
+    poly                mon;
+    Rational            weight;
+    poly                nf;
+    ring                r;
+
+    spectrumPolyNode( );
+    spectrumPolyNode( spectrumPolyNode*,poly,const Rational&,poly, const ring);
+    ~spectrumPolyNode( );
+
+    void    copy_zero   ( void );
+    void    copy_shallow( spectrumPolyNode*,poly,const Rational&,poly, const ring);
+    void    copy_shallow( spectrumPolyNode& );
+};
+
+// ----------------------------------------------------------------------------
+
+class spectrumPolyList
+{
+public:
+
+    spectrumPolyNode       *root;
+    int             N;
+    newtonPolygon   *np;
+
+    spectrumPolyList( );
+    spectrumPolyList( newtonPolygon* );
+    ~spectrumPolyList( );
+
+    void    copy_zero   ( void );
+    void    copy_shallow( spectrumPolyNode*,int,newtonPolygon* );
+    void    copy_shallow( spectrumPolyList& );
+
+    void    insert_node( poly,poly, const ring );
+    void    delete_node( spectrumPolyNode** );
+
+    void    delete_monomial( poly, const ring );
+
+    //spectrumState  spectrum( lists*,int );
+
+    #ifdef SPLIST_PRINT
+        friend ostream & operator << ( ostream&,const spectrumPolyList& );
+    #endif
+};
+
+#endif /* SPLIST_H */
+
+// ----------------------------------------------------------------------------
+//  splist.h
+//  end of file
+// ----------------------------------------------------------------------------
diff --git a/kernel/spectrum/test.cc b/kernel/spectrum/test.cc
new file mode 100644
index 0000000..bb2c248
--- /dev/null
+++ b/kernel/spectrum/test.cc
@@ -0,0 +1,376 @@
+#include <kernel/mod2.h>
+
+#include <omalloc/omalloc.h>
+
+#include <resources/feFopen.h>
+#include <resources/feResource.h>
+
+
+#include <factory/factory.h> // :(
+
+#include <misc/auxiliary.h>
+#include <misc/intvec.h>
+#include <misc/int64vec.h>
+#include <misc/mylimits.h>
+#include <misc/options.h>
+
+#include <reporter/reporter.h>
+
+#include <coeffs/si_gmp.h>
+#include <coeffs/coeffs.h>
+#include <coeffs/numbers.h>
+
+#ifndef PLURAL_INTERNAL_DECLARATIONS
+#define PLURAL_INTERNAL_DECLARATIONS
+#endif
+
+#ifndef PLURAL_INTERNAL_DECLARATIONS_GB_HACK
+#define PLURAL_INTERNAL_DECLARATIONS_GB_HACK
+#endif
+
+#include <polys/nc/gb_hack.h>
+#include <polys/nc/nc.h>
+#include <polys/nc/ncSACache.h>
+#include <polys/nc/ncSAFormula.h>
+#include <polys/nc/ncSAMult.h>
+#include <polys/nc/sca.h>
+#include <polys/nc/summator.h>
+
+#include <polys/kbuckets.h>
+#include <polys/matpol.h>
+#include <polys/mod_raw.h>
+#include <polys/prCopy.h>
+#include <polys/sbuckets.h>
+#include <polys/simpleideals.h>
+#include <polys/weight.h>
+
+#include <polys/monomials/maps.h>
+#include <polys/monomials/monomials.h>
+#include <polys/monomials/p_polys.h>
+#include <polys/monomials/ring.h>
+
+#include <polys/templates/p_MemAdd.h>
+#include <polys/templates/p_Procs.h>
+
+#include <polys/operations/pShallowCopyDelete.h>
+
+#include <polys/clapsing.h>
+
+
+// // TODO: DUE to the use of HALT in npolygon.cc :(((
+extern "C" {void m2_end(int i){exit(i);}}
+
+// // TODO: DUE to its use in kutil.cc :(((
+// char * showOption(){return NULL;}
+
+
+// #include "structs.h"
+
+
+// HEADERS:
+#include <kernel/ideals.h>
+#include <kernel/digitech.h>
+#include <kernel/fast_mult.h>
+
+// #include <kernel/spectrum/kmatrix.h>
+#include <kernel/preimage.h>
+
+#include <kernel/structs.h>
+
+#include <kernel/polys.h>
+
+void TestGBEngine()
+{
+
+  //  R = MPolynomialRing_polydict(QQ,5,'w,x,y,z,C', order='degrevlex')
+  //  J = (w*w - x*z, w*x - y*z, x*x - w*y, x*y - z*z, y*y - w*z)
+
+  const short w = 1;
+  const short x = 2;
+  const short y = 3;
+  const short z = 4;
+
+  const short N = (z - w + 1);
+
+  char **n=(char**)omalloc(N*sizeof(char*));
+
+
+  n[w-1]=omStrDup("w");
+  n[x-1]=omStrDup("x");
+  n[y-1]=omStrDup("y");
+  n[z-1]=omStrDup("z");
+
+
+  const int D = 3;
+  int *order = (int *) omAlloc0(D* sizeof(int));
+  int *block0 = (int *)omAlloc0(D * sizeof(int));
+  int *block1 = (int *)omAlloc0(D * sizeof(int));
+
+  order[0]  = ringorder_dp;
+  block0[0] = 1;
+  block1[0] = N;
+
+  order[1]  = ringorder_C;
+  block0[1] = 1;
+  block1[1] = N;
+
+  ring R = rDefault(0, N, n, D, order, block0, block1);
+
+//   ring R = rDefault(0, N, n);
+
+  rWrite(R); PrintLn();
+
+#ifdef RDEBUG
+  rDebugPrint(R);
+#endif
+
+  ideal I = idInit(5, 1);
+
+  int gen = 0;
+
+  {
+    // -xz
+    poly p = p_ISet(-1,R);
+
+    p_SetExp(p, x, 1, R);
+    p_SetExp(p, z, 1, R);
+    p_Setm(p, R);
+
+    assume( p_GetExp(p, x, R) == 1 );
+    assume( p_GetExp(p, z, R) == 1 );
+    assume( p_GetExp(p, w, R) == 0 );
+    assume( p_GetExp(p, y, R) == 0 );
+
+    // +w2
+    poly lp = p_ISet(1,R);
+    p_SetExp(lp, w, 2, R);
+    p_Setm(lp, R);
+
+    assume( p_GetExp(lp, w, R) == 2 );
+    assume( p_GetExp(lp, x, R) == 0 );
+    assume( p_GetExp(lp, y, R) == 0 );
+    assume( p_GetExp(lp, z, R) == 0 );
+
+    MATELEM(I, 1, ++gen) = p_Add_q(lp, p, R); // w2 - xz
+  }
+
+  {
+    // -yz
+    poly p = p_ISet(-1,R);
+
+    p_SetExp(p, y, 1, R);
+    p_SetExp(p, z, 1, R);
+    p_Setm(p, R);
+
+    assume( p_GetExp(p, y, R) == 1 );
+    assume( p_GetExp(p, z, R) == 1 );
+    assume( p_GetExp(p, w, R) == 0 );
+    assume( p_GetExp(p, x, R) == 0 );
+
+    // +wx
+    poly lp = p_ISet(1,R);
+    p_SetExp(lp, w, 1, R);
+    p_SetExp(lp, x, 1, R);
+    p_Setm(lp, R);
+
+    assume( p_GetExp(lp, w, R) == 1 );
+    assume( p_GetExp(lp, x, R) == 1 );
+    assume( p_GetExp(lp, y, R) == 0 );
+    assume( p_GetExp(lp, z, R) == 0 );
+
+    MATELEM(I, 1, ++gen) = p_Add_q(lp, p, R); // wx - yz
+  }
+
+
+  {
+    // -wy
+    poly p = p_ISet(-1,R);
+
+    p_SetExp(p, y, 1, R);
+    p_SetExp(p, w, 1, R);
+    p_Setm(p, R);
+
+    assume( p_GetExp(p, y, R) == 1 );
+    assume( p_GetExp(p, w, R) == 1 );
+    assume( p_GetExp(p, z, R) == 0 );
+    assume( p_GetExp(p, x, R) == 0 );
+
+    // +x2
+    poly lp = p_ISet(1,R);
+    p_SetExp(lp, x, 2, R);
+    p_Setm(lp, R);
+
+    assume( p_GetExp(lp, w, R) == 0 );
+    assume( p_GetExp(lp, x, R) == 2 );
+    assume( p_GetExp(lp, y, R) == 0 );
+    assume( p_GetExp(lp, z, R) == 0 );
+
+    MATELEM(I, 1, ++gen) = p_Add_q(lp, p, R); // x2 - wy
+  }
+
+
+  {
+    // -z2
+    poly p = p_ISet(-1,R);
+
+    p_SetExp(p, z, 2, R);
+    p_Setm(p, R);
+
+    assume( p_GetExp(p, y, R) == 0 );
+    assume( p_GetExp(p, w, R) == 0 );
+    assume( p_GetExp(p, z, R) == 2 );
+    assume( p_GetExp(p, x, R) == 0 );
+
+    // +xy
+    poly lp = p_ISet(1,R);
+    p_SetExp(lp, x, 1, R);
+    p_SetExp(lp, y, 1, R);
+    p_Setm(lp, R);
+
+    assume( p_GetExp(lp, w, R) == 0 );
+    assume( p_GetExp(lp, x, R) == 1 );
+    assume( p_GetExp(lp, y, R) == 1 );
+    assume( p_GetExp(lp, z, R) == 0 );
+
+    MATELEM(I, 1, ++gen) = p_Add_q(lp, p, R); // xy - z2
+  }
+
+
+  {
+    // -wz
+    poly p = p_ISet(-1,R);
+
+    p_SetExp(p, w, 1, R);
+    p_SetExp(p, z, 1, R);
+    p_Setm(p, R);
+
+    assume( p_GetExp(p, y, R) == 0 );
+    assume( p_GetExp(p, w, R) == 1 );
+    assume( p_GetExp(p, z, R) == 1 );
+    assume( p_GetExp(p, x, R) == 0 );
+
+    // +y2
+    poly lp = p_ISet(1,R);
+    p_SetExp(lp, y, 2, R);
+    p_Setm(lp, R);
+
+    assume( p_GetExp(lp, w, R) == 0 );
+    assume( p_GetExp(lp, x, R) == 0 );
+    assume( p_GetExp(lp, y, R) == 2 );
+    assume( p_GetExp(lp, z, R) == 0 );
+
+    MATELEM(I, 1, ++gen) = p_Add_q(lp, p, R); // y2 - wz
+  }
+#ifdef PDEBUG
+  PrintS("I: ");
+  idShow(I, R, R, 0);
+#endif
+
+
+//  ideal kStd(ideal F, ideal Q, tHomog h, intvec ** mw,intvec *hilb=NULL,
+//             int syzComp=0,int newIdeal=0, intvec *vw=NULL);
+  // make R the default ring:
+  rChangeCurrRing(R);
+
+ ////
+
+  idDelete( &I, R);
+  rDelete(R); // should cleanup every belonging polynomial, right!?
+
+}
+
+
+
+void TestSimpleRingArithmetcs()
+{
+  // Libpolys tests:
+
+  // construct the ring Z/32003[x,y,z]
+  // the variable names
+  char **n=(char**)omalloc(3*sizeof(char*));
+  n[0]=omStrDup("x");
+  n[1]=omStrDup("y");
+  n[2]=omStrDup("z2");
+
+  ring R = rDefault(32003,3,n); //  ring R = rDefault(0,3,n);
+
+  rWrite(R); PrintLn();
+
+#ifdef RDEBUG
+  rDebugPrint(R);
+#endif
+
+
+  poly p = p_ISet(1,R); p_SetExp(p,1,1, R); p_Setm(p, R);
+
+  assume( p_GetExp(p,1, R) == 1 );
+
+  poly pp = pp_Mult_qq( p, p, R);
+
+  Print("p: "); p_Write0(p, R); Print(", deg(p): %ld", p_Totaldegree(p, R)); assume( 1 == p_Totaldegree(p, R) );
+
+  Print("; p*p : "); p_Write0(pp, R); Print("deg(pp): %ld\n", p_Totaldegree(pp, R)); assume( 2 == p_Totaldegree(pp, R) );
+
+
+  p_Delete(&p, R);
+
+  assume( p_GetExp(pp,1, R) == 2 );
+
+  p_Delete(&pp, R);
+
+
+//  rDelete(R);
+
+  // make R the default ring:
+  rChangeCurrRing(R);
+
+  // create the polynomial 1
+  poly p1=pISet(1);
+
+  // create tthe polynomial 2*x^3*z^2
+  poly p2=p_ISet(2,R);
+  pSetExp(p2,1,3);
+  pSetExp(p2,3,2);
+  pSetm(p2);
+
+  // print p1 + p2
+  Print("p1: "); pWrite0(p1);
+  Print(" + p2: "); pWrite0(p2);
+  Print("  ---- >>>> ");
+
+  // compute p1+p2
+  p1=p_Add_q(p1,p2,R); p2=NULL;
+  pWrite(p1);
+
+  // clean up:
+//  pDelete(&p1);
+
+  rDelete(R); // should cleanup every belonging polynomial, right!?
+}
+
+
+int main( int, char *argv[] )
+{
+  assume( sizeof(long) == SIZEOF_LONG );
+
+  if( sizeof(long) != SIZEOF_LONG )
+  {
+    WerrorS("Bad config.h: wrong size of long!");
+
+    return(1);
+  }
+
+
+  feInitResources(argv[0]);
+
+  StringSetS("ressources in use (as reported by feStringAppendResources(0):\n");
+  feStringAppendResources(0);
+
+  PrintLn();
+  { char* s = StringEndS(); PrintS(s); omFree(s); }
+
+  TestGBEngine();
+  TestSimpleRingArithmetcs();
+
+  return 0;
+}
diff --git a/kernel/structs.h b/kernel/structs.h
new file mode 100644
index 0000000..79b6543
--- /dev/null
+++ b/kernel/structs.h
@@ -0,0 +1,95 @@
+#ifndef STRUCTS_H
+#define STRUCTS_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT
+*/
+
+/* for omBin */
+#include <omalloc/omalloc.h>
+#ifdef HAVE_RINGS
+#include <coeffs/si_gmp.h>
+#endif
+
+/* standard types */
+#define BITSET  unsigned int
+
+
+/* C++-part */
+#ifdef __cplusplus
+#include <misc/auxiliary.h>
+#include <kernel/polys.h>
+#include <polys/coeffrings.h>
+
+class Voice;
+class sleftv;
+class procinfo;
+class skStrategy;
+class ssyStrategy;
+class CPolynomialSummator;
+class CGlobalMultiplier;
+class CFormulaPowerMultiplier;
+#endif
+
+
+enum tHomog
+{
+  isNotHomog = FALSE,
+  isHomog    = TRUE,
+  testHomog
+};
+
+struct sip_package;
+typedef struct sip_package ip_package;
+typedef ip_package *       package;
+
+typedef struct  n_Procs_s  n_Procs_s;
+
+struct nc_struct;
+typedef struct nc_struct   nc_struct;
+
+typedef struct sip_link    ip_link;
+
+/* the pointer types */
+typedef char *             char_ptr;
+typedef int  *             int_ptr;
+
+#ifdef __cplusplus
+typedef sleftv *           leftv;
+typedef skStrategy *       kStrategy;
+typedef ssyStrategy *      syStrategy;
+typedef procinfo *         procinfov;
+
+/* the function pointer types */
+
+#endif /* __cplusplus */
+
+
+
+/*
+**  7. runtime procedures/global data
+*/
+
+/* 7.1 C-routines : */
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+void  m2_end(int i);
+#ifdef __cplusplus
+}
+#endif
+
+#define loop for(;;)
+
+#ifndef ABS
+#define ABS(x) ((x)<0?(-(x)):(x))
+#endif
+
+extern omBin char_ptr_bin;
+
+#endif
+
diff --git a/kernel/test.cc b/kernel/test.cc
new file mode 100644
index 0000000..ea60227
--- /dev/null
+++ b/kernel/test.cc
@@ -0,0 +1,619 @@
+#include <kernel/mod2.h>
+
+#include <omalloc/omalloc.h>
+#include <misc/auxiliary.h>
+#include <factory/factory.h> // :(
+
+#include <misc/intvec.h>
+#include <misc/int64vec.h>
+#include <misc/mylimits.h>
+#include <misc/options.h>
+
+#include <reporter/reporter.h>
+
+#include <resources/feFopen.h>
+#include <resources/feResource.h>
+
+#include <coeffs/coeffs.h>
+
+#include <coeffs/si_gmp.h>
+
+#include <polys/kbuckets.h>
+#include <polys/matpol.h>
+#include <polys/mod_raw.h>
+#include <polys/prCopy.h>
+#include <polys/sbuckets.h>
+#include <polys/simpleideals.h>
+#include <polys/weight.h>
+
+#include <polys/monomials/maps.h>
+#include <polys/monomials/monomials.h>
+#include <polys/monomials/p_polys.h>
+#include <polys/monomials/ring.h>
+
+#include <polys/nc/nc.h>
+#include <polys/nc/ncSACache.h>
+#include <polys/nc/ncSAFormula.h>
+#include <polys/nc/ncSAMult.h>
+#include <polys/nc/sca.h>
+#include <polys/nc/summator.h>
+
+
+#include <polys/templates/p_MemAdd.h>
+#include <polys/templates/p_Procs.h>
+
+#include <polys/operations/pShallowCopyDelete.h>
+
+#include <polys/clapsing.h>
+
+
+// // TODO: DUE to the use of HALT in npolygon.cc :(((
+extern "C" {void m2_end(int i){exit(i);}}
+
+// // TODO: DUE to its use in kutil.cc :(((
+char * showOption(){return NULL;}
+
+// // TODO: DUE to its use in feread.cc :(((
+char *iiArithGetCmd(int nPos){return NULL; }
+
+
+#include <coeffs/numbers.h>
+
+#include "structs.h"
+
+
+// HEADERS:
+#include <kernel/combinatorics/hutil.h>
+#include <kernel/combinatorics/stairc.h>
+#include <kernel/ideals.h>
+#include <kernel/GBEngine/syz.h>
+#include <kernel/maps/fast_maps.h>
+#include <kernel/groebner_walk/walkProc.h>
+#include <kernel/groebner_walk/walkMain.h>
+#include <kernel/groebner_walk/walkSupport.h>
+#include <kernel/GBEngine/khstd.h>
+/// #include <kernel/sparsmat.h> // TODO: install polys/this!
+//+
+
+#include <kernel/fglm/fglm.h>
+#include <kernel/GBEngine/kstd1.h>
+#include <kernel/fglm/fglmgauss.h>
+#include <kernel/fglm/fglmvec.h>
+#include <kernel/GBEngine/kstdfac.h>
+#include <kernel/spectrum/kmatrix.h>
+#include <kernel/spectrum/GMPrat.h>
+#include <kernel/spectrum/multicnt.h>
+#include <kernel/spectrum/npolygon.h>
+#include <kernel/spectrum/semic.h>
+#include <kernel/spectrum/spectrum.h>
+#include <kernel/spectrum/splist.h>
+#include <kernel/spectrum/multicnt.h>
+#include <kernel/linear_algebra/eigenval.h>
+#include <kernel/GBEngine/units.h>
+#include <kernel/GBEngine/ratgring.h>
+#include <kernel/GBEngine/shiftgb.h>
+
+
+#include <kernel/GBEngine/kutil.h>
+
+// #include "CCRing.h" // Too old!
+#include <kernel/digitech.h>
+#include <kernel/linear_algebra/eigenval.h>
+#include <kernel/maps/fast_maps.h>
+#include <kernel/fast_mult.h>
+
+#include <kernel/fglm/fglmgauss.h>
+#include <kernel/fglm/fglm.h>
+#include <kernel/fglm/fglmvec.h>
+
+////////#include <kernel/F5cData.h>
+#include <kernel/GBEngine/f5c.h>
+#include <kernel/GBEngine/f5data.h>
+#include <kernel/GBEngine/f5gb.h>
+#include <kernel/GBEngine/f5lists.h>
+////////#include <kernel/F5cLists.h>
+
+
+// #include "Ideal.h" // Too old?
+
+
+#include <kernel/ideals.h>
+
+#include <kernel/spectrum/kmatrix.h>
+#include <kernel/GBEngine/kstd1.h>
+#include <kernel/GBEngine/kstdfac.h>
+#include <kernel/GBEngine/khstd.h>
+
+#include <kernel/linear_algebra/linearAlgebra.h>
+
+
+
+// #include <kernel/lplist.h> // Too old!
+#include <kernel/spectrum/multicnt.h>
+#include <kernel/spectrum/npolygon.h>
+// #include "Number.h" // Too old?
+// #include "Poly.h" // Too old?
+// #include "PowerSeries.h" // Too old?
+
+#include <kernel/preimage.h>
+
+#include <kernel/GBEngine/nc.h>
+
+#include <kernel/GBEngine/ratgring.h>
+#include <kernel/GBEngine/ringgb.h>
+#include <kernel/spectrum/semic.h>
+#include <kernel/GBEngine/shiftgb.h>
+#include <kernel/spectrum/spectrum.h>
+#include <kernel/spectrum/splist.h>
+#include <kernel/structs.h>
+#include <kernel/GBEngine/syz.h>
+// #include <kernel/testpoly.h> // Too old?
+
+#include <kernel/GBEngine/tgbgauss.h>
+#include <kernel/GBEngine/tgb.h>
+
+
+#include <kernel/GBEngine/units.h>
+#include <kernel/groebner_walk/walkMain.h>
+#include <kernel/groebner_walk/walkProc.h>
+#include <kernel/groebner_walk/walkSupport.h>
+
+#include <kernel/GBEngine/janet.h>
+#include <kernel/linear_algebra/interpolation.h>
+#include <kernel/linear_algebra/minpoly.h>
+
+#include <kernel/linear_algebra/Minor.h>
+#include <kernel/linear_algebra/MinorInterface.h>
+#include <kernel/linear_algebra/MinorProcessor.h>
+#include <kernel/linear_algebra/Cache.h>
+#include <kernel/linear_algebra/CacheImplementation.h>
+
+// #include <polys/clapconv.h> // due to factory? :(
+// #include <kernel/tgb_internal.h> // :(
+// #include <kernel/F4.h> // uses tgb_internal // :(
+
+
+
+
+// #include <kernel/fglm/fglmzero.cc> // looks like <factory/templates/ftmpl_list.h> must be installed!
+// TODO: looks like <coeffs/mpr_complex.h> must be installed!
+
+
+
+#include <kernel/polys.h>
+
+void TestGBEngine()
+{
+
+  //  R = MPolynomialRing_polydict(QQ,5,'w,x,y,z,C', order='degrevlex')
+  //  J = (w*w - x*z, w*x - y*z, x*x - w*y, x*y - z*z, y*y - w*z)
+
+  const short w = 1;
+  const short x = 2;
+  const short y = 3;
+  const short z = 4;
+
+  const short N = (z - w + 1);
+
+  char **n=(char**)omalloc(N*sizeof(char*));
+
+
+  n[w-1]=omStrDup("w");
+  n[x-1]=omStrDup("x");
+  n[y-1]=omStrDup("y");
+  n[z-1]=omStrDup("z");
+
+
+  const int D = 3;
+  int *order = (int *) omAlloc0(D* sizeof(int));
+  int *block0 = (int *)omAlloc0(D * sizeof(int));
+  int *block1 = (int *)omAlloc0(D * sizeof(int));
+
+  order[0]  = ringorder_dp;
+  block0[0] = 1;
+  block1[0] = N;
+
+  order[1]  = ringorder_C;
+  block0[1] = 1;
+  block1[1] = N;
+
+  ring R = rDefault(0, N, n, D, order, block0, block1);
+
+//   ring R = rDefault(0, N, n);
+
+  rWrite(R); PrintLn();
+
+#ifdef RDEBUG
+  rDebugPrint(R);
+#endif
+
+  ideal I = idInit(5, 1);
+
+  int gen = 0;
+
+  {
+    // -xz
+    poly p = p_ISet(-1,R);
+
+    p_SetExp(p, x, 1, R);
+    p_SetExp(p, z, 1, R);
+    p_Setm(p, R);
+
+    assume( p_GetExp(p, x, R) == 1 );
+    assume( p_GetExp(p, z, R) == 1 );
+    assume( p_GetExp(p, w, R) == 0 );
+    assume( p_GetExp(p, y, R) == 0 );
+
+    // +w2
+    poly lp = p_ISet(1,R);
+    p_SetExp(lp, w, 2, R);
+    p_Setm(lp, R);
+
+    assume( p_GetExp(lp, w, R) == 2 );
+    assume( p_GetExp(lp, x, R) == 0 );
+    assume( p_GetExp(lp, y, R) == 0 );
+    assume( p_GetExp(lp, z, R) == 0 );
+
+    MATELEM(I, 1, ++gen) = p_Add_q(lp, p, R); // w2 - xz
+  }
+
+  {
+    // -yz
+    poly p = p_ISet(-1,R);
+
+    p_SetExp(p, y, 1, R);
+    p_SetExp(p, z, 1, R);
+    p_Setm(p, R);
+
+    assume( p_GetExp(p, y, R) == 1 );
+    assume( p_GetExp(p, z, R) == 1 );
+    assume( p_GetExp(p, w, R) == 0 );
+    assume( p_GetExp(p, x, R) == 0 );
+
+    // +wx
+    poly lp = p_ISet(1,R);
+    p_SetExp(lp, w, 1, R);
+    p_SetExp(lp, x, 1, R);
+    p_Setm(lp, R);
+
+    assume( p_GetExp(lp, w, R) == 1 );
+    assume( p_GetExp(lp, x, R) == 1 );
+    assume( p_GetExp(lp, y, R) == 0 );
+    assume( p_GetExp(lp, z, R) == 0 );
+
+    MATELEM(I, 1, ++gen) = p_Add_q(lp, p, R); // wx - yz
+  }
+
+
+  {
+    // -wy
+    poly p = p_ISet(-1,R);
+
+    p_SetExp(p, y, 1, R);
+    p_SetExp(p, w, 1, R);
+    p_Setm(p, R);
+
+    assume( p_GetExp(p, y, R) == 1 );
+    assume( p_GetExp(p, w, R) == 1 );
+    assume( p_GetExp(p, z, R) == 0 );
+    assume( p_GetExp(p, x, R) == 0 );
+
+    // +x2
+    poly lp = p_ISet(1,R);
+    p_SetExp(lp, x, 2, R);
+    p_Setm(lp, R);
+
+    assume( p_GetExp(lp, w, R) == 0 );
+    assume( p_GetExp(lp, x, R) == 2 );
+    assume( p_GetExp(lp, y, R) == 0 );
+    assume( p_GetExp(lp, z, R) == 0 );
+
+    MATELEM(I, 1, ++gen) = p_Add_q(lp, p, R); // x2 - wy
+  }
+
+
+  {
+    // -z2
+    poly p = p_ISet(-1,R);
+
+    p_SetExp(p, z, 2, R);
+    p_Setm(p, R);
+
+    assume( p_GetExp(p, y, R) == 0 );
+    assume( p_GetExp(p, w, R) == 0 );
+    assume( p_GetExp(p, z, R) == 2 );
+    assume( p_GetExp(p, x, R) == 0 );
+
+    // +xy
+    poly lp = p_ISet(1,R);
+    p_SetExp(lp, x, 1, R);
+    p_SetExp(lp, y, 1, R);
+    p_Setm(lp, R);
+
+    assume( p_GetExp(lp, w, R) == 0 );
+    assume( p_GetExp(lp, x, R) == 1 );
+    assume( p_GetExp(lp, y, R) == 1 );
+    assume( p_GetExp(lp, z, R) == 0 );
+
+    MATELEM(I, 1, ++gen) = p_Add_q(lp, p, R); // xy - z2
+  }
+
+
+  {
+    // -wz
+    poly p = p_ISet(-1,R);
+
+    p_SetExp(p, w, 1, R);
+    p_SetExp(p, z, 1, R);
+    p_Setm(p, R);
+
+    assume( p_GetExp(p, y, R) == 0 );
+    assume( p_GetExp(p, w, R) == 1 );
+    assume( p_GetExp(p, z, R) == 1 );
+    assume( p_GetExp(p, x, R) == 0 );
+
+    // +y2
+    poly lp = p_ISet(1,R);
+    p_SetExp(lp, y, 2, R);
+    p_Setm(lp, R);
+
+    assume( p_GetExp(lp, w, R) == 0 );
+    assume( p_GetExp(lp, x, R) == 0 );
+    assume( p_GetExp(lp, y, R) == 2 );
+    assume( p_GetExp(lp, z, R) == 0 );
+
+    MATELEM(I, 1, ++gen) = p_Add_q(lp, p, R); // y2 - wz
+  }
+#ifdef PDEBUG
+  PrintS("I: ");
+  idShow(I, R, R, 0);
+#endif
+
+
+//  ideal kStd(ideal F, ideal Q, tHomog h, intvec ** mw,intvec *hilb=NULL,
+//             int syzComp=0,int newIdeal=0, intvec *vw=NULL);
+  // make R the default ring:
+  rChangeCurrRing(R);
+
+  {
+    ideal G = kStd(I, currRing->qideal, testHomog, NULL);
+
+#ifdef PDEBUG
+    PrintS("GB: ");
+    idShow(G, R, R, 0);
+#endif
+
+    idDelete( &G, R);
+  }
+
+  {
+    intvec *weights = NULL;
+    ideal SYZ = idSyzygies(I, testHomog, &weights);
+
+#ifdef PDEBUG
+    PrintS("SYZ: ");
+    idShow(SYZ, R, R, 0);
+#endif
+
+    idDelete(&SYZ, R);
+    if (weights!=NULL) { PrintS("weights: "); weights->show(); delete weights; }
+  }
+
+
+  {
+    PrintS("\n**********************************\n");
+    PrintS("lres: \n");
+    int dummy;
+    syStrategy r = syLaScala3(I,&dummy);
+
+    intvec *b = syBettiOfComputation(r, FALSE);
+    PrintS("non-min. betti: \n");    b->show();    PrintLn();
+    delete b;
+
+    Print("length: %d\n", sySize(r));
+
+    syPrint(r, "R");
+
+    r =  syMinimize(r); // syzstr->references ++ ==> memory leak :(((
+
+    b = syBettiOfComputation(r, TRUE);
+    PrintS("min. betti: \n");    b->show();    PrintLn();
+    delete b;
+
+    Print("length: %d\n", sySize(r));
+
+    syPrint(r, "R");
+
+    syKillComputation(r, R);
+  }
+
+  {
+    PrintS("\n**********************************\n");
+    PrintS("sres: \n");
+    const int maxl = rVar(R)-1; // +2*(1);
+
+    syStrategy r = sySchreyer(I, rVar(R));
+
+    intvec *b = syBettiOfComputation(r, FALSE);
+    PrintS("non-min. betti: \n");    b->show();    PrintLn();
+    delete b;
+
+    Print("length: %d\n", sySize(r));
+
+    syPrint(r, "R");
+
+    r =  syMinimize(r); // syzstr->references ++ ==> memory leak :(((
+
+    b = syBettiOfComputation(r, TRUE);
+    PrintS("min. betti: \n");    b->show();    PrintLn();
+    delete b;
+
+    Print("length: %d\n", sySize(r));
+
+    syPrint(r, "R");
+
+    syKillComputation(r, R);
+  }
+
+
+
+  {
+    PrintS("\n**********************************\n");
+    PrintS("nres: \n");
+    intvec *weights=NULL;
+//    const int maxl = rVar(R)-1 + 2*(1);
+    syStrategy r = syResolution(I, rVar(R)-1, weights, FALSE/*iiOp==MRES_CMD*/);
+
+    intvec *b = syBettiOfComputation(r, FALSE);
+    PrintS("non-min. betti: \n");    b->show();    PrintLn();
+    delete b;
+
+    Print("length: %d\n", sySize(r));
+
+    syPrint(r, "R");
+
+    r =  syMinimize(r); // syzstr->references ++ ==> memory leak :(((
+
+    b = syBettiOfComputation(r, TRUE);
+    PrintS("min. betti: \n");    b->show();    PrintLn();
+    delete b;
+
+    Print("length: %d\n", sySize(r));
+
+    syPrint(r, "R");
+
+    syKillComputation(r, R);
+  }
+
+
+  {
+    PrintS("\n**********************************\n");
+    PrintS("mres: \n");
+    intvec *weights=NULL;
+//    const int maxl = rVar(R)-1 + 2*(1);
+    syStrategy r = syResolution(I, rVar(R)+1, weights, TRUE/*iiOp==MRES_CMD*/);
+
+    intvec *b = syBettiOfComputation(r, FALSE);
+    PrintS("non-min. betti: \n");    b->show();    PrintLn();
+    delete b;
+
+    Print("length: %d\n", sySize(r));
+
+    syPrint(r, "R");
+
+    r =  syMinimize(r); // syzstr->references ++ ==> memory leak :(((
+
+    b = syBettiOfComputation(r, TRUE);
+    PrintS("min. betti: \n");    b->show();    PrintLn();
+    delete b;
+
+    Print("length: %d\n", sySize(r));
+
+    syPrint(r, "R");
+
+    syKillComputation(r, R);
+  }
+
+
+
+
+  idDelete( &I, R);
+  rDelete(R); // should cleanup every belonging polynomial, right!?
+
+}
+
+
+
+void TestSimpleRingArithmetcs()
+{
+  // Libpolys tests:
+
+  // construct the ring Z/32003[x,y,z]
+  // the variable names
+  char **n=(char**)omalloc(3*sizeof(char*));
+  n[0]=omStrDup("x");
+  n[1]=omStrDup("y");
+  n[2]=omStrDup("z2");
+
+  ring R = rDefault(32003,3,n); //  ring R = rDefault(0,3,n);
+
+  rWrite(R); PrintLn();
+
+#ifdef RDEBUG
+  rDebugPrint(R);
+#endif
+
+
+  poly p = p_ISet(1,R); p_SetExp(p,1,1, R); p_Setm(p, R);
+
+  assume( p_GetExp(p,1, R) == 1 );
+
+  poly pp = pp_Mult_qq( p, p, R);
+
+  Print("p: "); p_Write0(p, R); Print(", deg(p): %ld", p_Totaldegree(p, R)); assume( 1 == p_Totaldegree(p, R) );
+
+  Print("; p*p : "); p_Write0(pp, R); Print("deg(pp): %ld\n", p_Totaldegree(pp, R)); assume( 2 == p_Totaldegree(pp, R) );
+
+
+  p_Delete(&p, R);
+
+  assume( p_GetExp(pp,1, R) == 2 );
+
+  p_Delete(&pp, R);
+
+
+//  rDelete(R);
+
+  // make R the default ring:
+  rChangeCurrRing(R);
+
+  // create the polynomial 1
+  poly p1=pISet(1);
+
+  // create tthe polynomial 2*x^3*z^2
+  poly p2=p_ISet(2,R);
+  pSetExp(p2,1,3);
+  pSetExp(p2,3,2);
+  pSetm(p2);
+
+  // print p1 + p2
+  Print("p1: "); pWrite0(p1);
+  Print(" + p2: "); pWrite0(p2);
+  Print("  ---- >>>> ");
+
+  // compute p1+p2
+  p1=p_Add_q(p1,p2,R); p2=NULL;
+  pWrite(p1);
+
+  // clean up:
+//  pDelete(&p1);
+
+  rDelete(R); // should cleanup every belonging polynomial, right!?
+}
+
+
+int main( int, char *argv[] )
+{
+  assume( sizeof(long) == SIZEOF_LONG );
+
+  if( sizeof(long) != SIZEOF_LONG )
+  {
+    WerrorS("Bad config.h: wrong size of long!");
+
+    return(1);
+  }
+
+
+  feInitResources(argv[0]);
+
+  StringSetS("ressources in use (as reported by feStringAppendResources(0):\n");
+  feStringAppendResources(0);
+
+  PrintLn();
+  { char* s = StringEndS(); PrintS(s); omFree(s); }
+
+  TestGBEngine();
+  TestSimpleRingArithmetcs();
+
+  return 0;
+}
diff --git a/libpolys/AUTHORS b/libpolys/AUTHORS
new file mode 100644
index 0000000..e69de29
diff --git a/libpolys/COPYING b/libpolys/COPYING
new file mode 100644
index 0000000..ec699b9
--- /dev/null
+++ b/libpolys/COPYING
@@ -0,0 +1,103 @@
+                        SINGULAR version 4-0
+
+                     University of Kaiserslautern
+
+      Department of Mathematics and  Centre for Computer Algebra
+
+           Authors: G.-M. Greuel, G. Pfister, H. Schoenemann
+
+                        Copyright (C) 1986-2014
+
+
+
+                               *NOTICE*
+
+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 ( version 2 or version 3 of the License ).
+
+Some single files have a copyright given within the file:
+Singular/ndbm.* (BSD)
+
+The following software used with SINGULAR have their own copyright: the
+omalloc library, the readline library, the Gnu Multiple Precision
+Library (GMP), NTL: A Library for doing Number Theory (NTL), the Multi
+Protocol library (MP), the Singular-Factory library, the
+Singular-libfac library, surfex, and, for the Windows distributions the
+Cygwin DLL and the Cygwin tools (Cygwin), and the XEmacs editor
+(XEmacs).
+
+Their copyrights and licenses can be found in the accompanying files
+COPYING which are distributed along with these packages.  (Since
+version 3-0-3 of SINGULAR, all parts have GPL or LGPL as (one of) their
+licences.)
+
+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 (see GPL)
+
+Please send any comments or bug reports to
+<singular at mathematik.uni-kl.de>.
+
+If you want to be informed of new releases,  please register yourself
+as a SINGULAR user by using the registration form on the SINGULAR
+homepage               `http://www.singular.uni-kl.de'.  If for some
+reason you cannot access the registration form, you can also register
+by sending an email to               <singular at mathematik.uni-kl.de>
+with subject line `register' and body containing the following data:
+ your name, email address, organisation, country and platform(s).
+
+For the citation of SINGULAR see
+`http://www.singular.uni-kl.de/how_to_cite.html', for information on
+how to cite Singular.
+
+You can also support SINGULAR by informing us about your result
+obtained by using SINGULAR.
+
+Availability
+============
+
+The latest information about SINGULAR is always available from
+`http://www.singular.uni-kl.de'.
+
+Acknowledgements
+================
+
+The development of SINGULAR is directed and coordinated by Gert-Martin
+Greuel, Gerhard Pfister, and Hans Scho"nemann.
+
+Currently, the SINGULAR team has the following members: Michael
+Brickenstein, Wolfram Decker, Alexander Dreyer, Anne Fru"hbis-Kru"ger,
+Kai Kru"ger, Viktor Levandovskyy, Oleksandr Motsak, Mathias Schulze, and
+Oliver Wienand.
+
+Former members of the SINGULAR team are: Olaf Bachmann, Christoph
+Lossen, Wolfgang Neumann, Wilfred Pohl, Jens Schmidt, Thomas Siebert,
+Ru"diger Stobbe, Eric Westenberger and Tim Wichmann.
+
+Further contributions to SINGULAR were made by: Daniel Andres, Thomas
+Bayer, Isabelle Bermejo, Markus Becker, Stas Bulygin, Nadine Cremer,
+Kai Dehmann, Marcin Dumnicki, Stephan Endrass, Jose Ignacio Farran, I.
+Garcia-Marco, Vladimir Gerdt, Philippe Gimenez, Christian Gorzel,
+Hubert Grassmann, Amir Hashemi, Fernando Hernando, Agnes Heydtmann,
+Dietmar Hillebrand, Tobias Hirsch, Markus Hochstetter, Manuel Kauers,
+Simon King, Anen Lakhal, Martin Lamm, Santiago Laplagne, Gregoire
+Lecerf, Francisco Javier Lobillo, Christoph Mang, Thomas Markwig, Bernd
+Martin, Michael Messollen, Andrea Mindnich, Jorge Martin Morales,
+Thomas Nu"ssler, Tetyana Povalyaeva, Carlos Rabelo, J.-J.
+Salazar-Gonzalez, Alfredo Sanchez-Navarro, Ivor Saynisch, Kristina
+Schindelar, Silke Spang, Stefan Steidel, Henrik Strohmayer, Christian
+Stussak, Imade Sulandra, Akira Suzuki, Christine Theis, Enrique Tobis,
+Maryna Viazovska, Alberto Vigneron-Tenorio, Moritz Wenk, Denis Yanovich,
+Oleksandr Iena.
+
+We should like to acknowledge the financial support given by the
+Volkswagen-Stiftung, the Deutsche Forschungsgemeinschaft and the
+Stiftung fu"r Innovation des Landes Rheinland-Pfalz to the SINGULAR
+project.
+
diff --git a/libpolys/ChangeLog b/libpolys/ChangeLog
new file mode 100644
index 0000000..e69de29
diff --git a/libpolys/Makefile.am b/libpolys/Makefile.am
new file mode 100644
index 0000000..a8c32d4
--- /dev/null
+++ b/libpolys/Makefile.am
@@ -0,0 +1,12 @@
+ACLOCAL_AMFLAGS = -I ../m4
+
+bin_SCRIPTS = libpolys-config
+
+SUBDIRS=misc reporter coeffs polys tests
+
+configheaderdir = ${includedir}/singular
+nodist_configheader_HEADERS = libpolysconfig.h
+DISTCLEANFILES = $(nodist_configheader_HEADERS)
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = libpolys.pc
diff --git a/libpolys/Makefile.in b/libpolys/Makefile.in
new file mode 100644
index 0000000..f1dc11a
--- /dev/null
+++ b/libpolys/Makefile.in
@@ -0,0 +1,976 @@
+# Makefile.in generated by automake 1.13.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 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@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+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 = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/configure $(am__configure_deps) \
+	$(srcdir)/_config.h.in $(srcdir)/libpolys-config.in \
+	$(srcdir)/libpolys.pc.in AUTHORS COPYING ChangeLog NEWS README \
+	../build-aux/ar-lib ../build-aux/compile \
+	../build-aux/config.guess ../build-aux/config.sub \
+	../build-aux/depcomp ../build-aux/install-sh \
+	../build-aux/missing ../build-aux/ylwrap \
+	../build-aux/ltmain.sh $(top_srcdir)/../build-aux/ar-lib \
+	$(top_srcdir)/../build-aux/compile \
+	$(top_srcdir)/../build-aux/config.guess \
+	$(top_srcdir)/../build-aux/config.sub \
+	$(top_srcdir)/../build-aux/install-sh \
+	$(top_srcdir)/../build-aux/ltmain.sh \
+	$(top_srcdir)/../build-aux/missing
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/../m4/ax_append_compile_flags.m4 \
+	$(top_srcdir)/../m4/ax_append_flag.m4 \
+	$(top_srcdir)/../m4/ax_append_link_flags.m4 \
+	$(top_srcdir)/../m4/ax_check_compile_flag.m4 \
+	$(top_srcdir)/../m4/ax_check_link_flag.m4 \
+	$(top_srcdir)/../m4/ax_cxx_gcc_abi_demangle.m4 \
+	$(top_srcdir)/../m4/ax_prefix_config_h.m4 \
+	$(top_srcdir)/../m4/cpu-check.m4 $(top_srcdir)/../m4/flags.m4 \
+	$(top_srcdir)/../m4/flint-check.m4 \
+	$(top_srcdir)/../m4/gmp-check.m4 \
+	$(top_srcdir)/../m4/libtool.m4 \
+	$(top_srcdir)/../m4/ltoptions.m4 \
+	$(top_srcdir)/../m4/ltsugar.m4 \
+	$(top_srcdir)/../m4/ltversion.m4 \
+	$(top_srcdir)/../m4/lt~obsolete.m4 \
+	$(top_srcdir)/../m4/ntl-check.m4 \
+	$(top_srcdir)/../m4/options.m4 $(top_srcdir)/../m4/p-procs.m4 \
+	$(top_srcdir)/configure.ac
+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 = libpolys-config libpolys.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__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
+am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pkgconfigdir)" \
+	"$(DESTDIR)$(configheaderdir)"
+SCRIPTS = $(bin_SCRIPTS)
+AM_V_P = $(am__v_P_ at AM_V@)
+am__v_P_ = $(am__v_P_ at AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_ at AM_V@)
+am__v_GEN_ = $(am__v_GEN_ at AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_ at AM_V@)
+am__v_at_ = $(am__v_at_ at AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+SOURCES =
+DIST_SOURCES =
+RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
+	ctags-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 \
+	tags-recursive uninstall-recursive
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+DATA = $(pkgconfig_DATA)
+HEADERS = $(nodist_configheader_HEADERS)
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive	\
+  distclean-recursive maintainer-clean-recursive
+am__recursive_targets = \
+  $(RECURSIVE_TARGETS) \
+  $(RECURSIVE_CLEAN_TARGETS) \
+  $(am__extra_recursive_targets)
+AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
+	cscope distdir dist dist-all distcheck
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \
+	$(LISP)_config.h.in
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+CSCOPE = cscope
+DIST_SUBDIRS = $(SUBDIRS)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+distdir = $(PACKAGE)-$(VERSION)
+top_distdir = $(distdir)
+am__remove_distdir = \
+  if test -d "$(distdir)"; then \
+    find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \
+      && rm -rf "$(distdir)" \
+      || { sleep 5 && rm -rf "$(distdir)"; }; \
+  else :; fi
+am__post_remove_distdir = $(am__remove_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
+DIST_TARGETS = dist-gzip
+distuninstallcheck_listfiles = find . -type f -print
+am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \
+  | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$'
+distcleancheck_listfiles = find . -type f -print
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+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@
+FACTORY_INCLUDES = @FACTORY_INCLUDES@
+FACTORY_LIBS = @FACTORY_LIBS@
+FGREP = @FGREP@
+FLINT_CFLAGS = @FLINT_CFLAGS@
+FLINT_HOME = @FLINT_HOME@
+FLINT_LIBS = @FLINT_LIBS@
+GMP_CFLAGS = @GMP_CFLAGS@
+GMP_HOME = @GMP_HOME@
+GMP_LIBS = @GMP_LIBS@
+GMP_VERSION = @GMP_VERSION@
+GREP = @GREP@
+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@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NTL_CFLAGS = @NTL_CFLAGS@
+NTL_LIBS = @NTL_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OMALLOC_INCLUDES = @OMALLOC_INCLUDES@
+OMALLOC_LIBS = @OMALLOC_LIBS@
+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@
+PKG_REQUIRE = @PKG_REQUIRE@
+POLYMAKE_CXXFLAGS = @POLYMAKE_CXXFLAGS@
+RANLIB = @RANLIB@
+RESOURCES_INCLUDES = @RESOURCES_INCLUDES@
+RESOURCES_LIBS = @RESOURCES_LIBS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SINGULAR_CFLAGS = @SINGULAR_CFLAGS@
+SI_CPU_I386 = @SI_CPU_I386@
+SI_CPU_IA64 = @SI_CPU_IA64@
+SI_CPU_PPC = @SI_CPU_PPC@
+SI_CPU_SPARC = @SI_CPU_SPARC@
+SI_CPU_X86_64 = @SI_CPU_X86_64@
+STRIP = @STRIP@
+USEPPROCSDYNAMICLD = @USEPPROCSDYNAMICLD@
+USEPPROCSDYNAMICLDFLAGS = @USEPPROCSDYNAMICLDFLAGS@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+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@
+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@
+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@
+ACLOCAL_AMFLAGS = -I ../m4
+bin_SCRIPTS = libpolys-config
+SUBDIRS = misc reporter coeffs polys tests
+configheaderdir = ${includedir}/singular
+nodist_configheader_HEADERS = libpolysconfig.h
+DISTCLEANFILES = $(nodist_configheader_HEADERS)
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = libpolys.pc
+all: _config.h
+	$(MAKE) $(AM_MAKEFLAGS) all-recursive
+
+.SUFFIXES:
+am--refresh: Makefile
+	@:
+$(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) --foreign'; \
+	      $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \
+		&& exit 0; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign 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; else :; fi
+	@if test ! -f $@; then $(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
+libpolys-config: $(top_builddir)/config.status $(srcdir)/libpolys-config.in
+	cd $(top_builddir) && $(SHELL) ./config.status $@
+libpolys.pc: $(top_builddir)/config.status $(srcdir)/libpolys.pc.in
+	cd $(top_builddir) && $(SHELL) ./config.status $@
+install-binSCRIPTS: $(bin_SCRIPTS)
+	@$(NORMAL_INSTALL)
+	@list='$(bin_SCRIPTS)'; test -n "$(bindir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \
+	fi; \
+	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)'`; \
+	dir='$(DESTDIR)$(bindir)'; $(am__uninstall_files_from_dir)
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+
+distclean-libtool:
+	-rm -f libtool config.lt
+install-pkgconfigDATA: $(pkgconfig_DATA)
+	@$(NORMAL_INSTALL)
+	@list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(pkgconfigdir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" || exit 1; \
+	fi; \
+	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|^.*/||'`; \
+	dir='$(DESTDIR)$(pkgconfigdir)'; $(am__uninstall_files_from_dir)
+install-nodist_configheaderHEADERS: $(nodist_configheader_HEADERS)
+	@$(NORMAL_INSTALL)
+	@list='$(nodist_configheader_HEADERS)'; test -n "$(configheaderdir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(configheaderdir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(configheaderdir)" || exit 1; \
+	fi; \
+	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)$(configheaderdir)'"; \
+	  $(INSTALL_HEADER) $$files "$(DESTDIR)$(configheaderdir)" || exit $$?; \
+	done
+
+uninstall-nodist_configheaderHEADERS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(nodist_configheader_HEADERS)'; test -n "$(configheaderdir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	dir='$(DESTDIR)$(configheaderdir)'; $(am__uninstall_files_from_dir)
+
+# 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.
+$(am__recursive_targets):
+	@fail=; \
+	if $(am__make_keepgoing); then \
+	  failcom='fail=yes'; \
+	else \
+	  failcom='exit 1'; \
+	fi; \
+	dot_seen=no; \
+	target=`echo $@ | sed s/-recursive//`; \
+	case "$@" in \
+	  distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+	  *) list='$(SUBDIRS)' ;; \
+	esac; \
+	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"
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-recursive
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	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; \
+	$(am__define_uniq_tagged_files); \
+	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-recursive
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	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"
+cscope: cscope.files
+	test ! -s cscope.files \
+	  || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS)
+clean-cscope:
+	-rm -f cscope.files
+cscope.files: clean-cscope cscopelist
+cscopelist: cscopelist-recursive
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+	-rm -f cscope.out cscope.in.out cscope.po.out cscope.files
+
+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 \
+	    $(am__make_dryrun) \
+	      || test -d "$(distdir)/$$subdir" \
+	      || $(MKDIR_P) "$(distdir)/$$subdir" \
+	      || exit 1; \
+	    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 -755 \
+		-exec chmod u+rwx,go+rx {} \; -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__post_remove_distdir)
+
+dist-bzip2: distdir
+	tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2
+	$(am__post_remove_distdir)
+
+dist-lzip: distdir
+	tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz
+	$(am__post_remove_distdir)
+
+dist-xz: distdir
+	tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz
+	$(am__post_remove_distdir)
+
+dist-tarZ: distdir
+	tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
+	$(am__post_remove_distdir)
+
+dist-shar: distdir
+	shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
+	$(am__post_remove_distdir)
+
+dist-zip: distdir
+	-rm -f $(distdir).zip
+	zip -rq $(distdir).zip $(distdir)
+	$(am__post_remove_distdir)
+
+dist dist-all:
+	$(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:'
+	$(am__post_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) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\
+	*.tar.bz2*) \
+	  bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
+	*.tar.lz*) \
+	  lzip -dc $(distdir).tar.lz | $(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) gzip -dc $(distdir).shar.gz | unshar ;;\
+	*.zip*) \
+	  unzip $(distdir).zip ;;\
+	esac
+	chmod -R a-w $(distdir)
+	chmod u+w $(distdir)
+	mkdir $(distdir)/_build $(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" \
+	    $(AM_DISTCHECK_CONFIGURE_FLAGS) \
+	    $(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__post_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:
+	@test -n '$(distuninstallcheck_dir)' || { \
+	  echo 'ERROR: trying to run $@ with an empty' \
+	       '$$(distuninstallcheck_dir)' >&2; \
+	  exit 1; \
+	}; \
+	$(am__cd) '$(distuninstallcheck_dir)' || { \
+	  echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \
+	  exit 1; \
+	}; \
+	test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \
+	   || { 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 $(SCRIPTS) $(DATA) $(HEADERS) _config.h
+installdirs: installdirs-recursive
+installdirs-am:
+	for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(configheaderdir)"; do \
+	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+	done
+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:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+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)
+	-test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
+
+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-nodist_configheaderHEADERS \
+	install-pkgconfigDATA
+
+install-dvi: install-dvi-recursive
+
+install-dvi-am:
+
+install-exec-am: install-binSCRIPTS
+
+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: uninstall-binSCRIPTS \
+	uninstall-nodist_configheaderHEADERS uninstall-pkgconfigDATA
+
+.MAKE: $(am__recursive_targets) all install-am install-strip
+
+.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \
+	am--refresh check check-am clean clean-cscope clean-generic \
+	clean-libtool cscope cscopelist-am ctags ctags-am dist \
+	dist-all dist-bzip2 dist-gzip dist-lzip 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-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-nodist_configheaderHEADERS \
+	install-pdf install-pdf-am install-pkgconfigDATA 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-am uninstall \
+	uninstall-am uninstall-binSCRIPTS \
+	uninstall-nodist_configheaderHEADERS uninstall-pkgconfigDATA
+
+
+# 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/libpolys/NEWS b/libpolys/NEWS
new file mode 100644
index 0000000..e69de29
diff --git a/libpolys/README b/libpolys/README
new file mode 100644
index 0000000..80cf52d
--- /dev/null
+++ b/libpolys/README
@@ -0,0 +1,9 @@
+This directory contains the data structures and basic algorithms for polynomials
+in Singular
+
+Subdirectories:
+ coeffs: interface to coefficients (cring elemeents) ans basic representants
+ polys: polynomial ring and (basic) polynomial operations
+ misc: misc. stuff: randaom generation, global options, 64bit intvec
+ reporter: error reporting, basic output routines, input buffering
+
diff --git a/libpolys/_config.h.in b/libpolys/_config.h.in
new file mode 100644
index 0000000..692c963
--- /dev/null
+++ b/libpolys/_config.h.in
@@ -0,0 +1,242 @@
+/* _config.h.in.  Generated from configure.ac by autoheader.  */
+
+/* DISABLE_GMP_CPP */
+#undef DISABLE_GMP_CPP
+
+/* GMP_CFLAGS */
+#undef GMP_CFLAGS
+
+/* GMP_LIBS */
+#undef GMP_LIBS
+
+/* Define if GMP is version 3.xxx */
+#undef GMP_VERSION_3
+
+/* division using extend euclidian algorithm otherwise using tables of
+   logartihms */
+#undef HAVE_DIV_MOD
+
+/* enable dynamic modules */
+#undef HAVE_DL
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
+
+/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */
+#undef HAVE_DOPRNT
+
+/* enable dynamic modules */
+#undef HAVE_DYNAMIC_LOADING
+
+/* Define to 1 if you have the <execinfo.h> header file. */
+#undef HAVE_EXECINFO_H
+
+/* Enable factory */
+#undef HAVE_FACTORY
+
+/* Define to 1 if you have the <factory/factory.h> header file. */
+#undef HAVE_FACTORY_FACTORY_H
+
+/* Define if FLINT is installed */
+#undef HAVE_FLINT
+
+/* Define to 1 if you have the <float.h> header file. */
+#undef HAVE_FLOAT_H
+
+/* define if the compiler supports GCC C++ ABI name demangling */
+#undef HAVE_GCC_ABI_DEMANGLE
+
+/* use branch for addition in Z/p otherwise it uses a generic add */
+#undef HAVE_GENERIC_ADD
+
+/* Define if GMP is installed */
+#undef HAVE_GMP
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the <limits.h> header file. */
+#undef HAVE_LIMITS_H
+
+/* Define to 1 if your system has a GNU libc compatible `malloc' function, and
+   to 0 otherwise. */
+#undef HAVE_MALLOC
+
+/* Define to 1 if you have the `memmove' function. */
+#undef HAVE_MEMMOVE
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the `memset' function. */
+#undef HAVE_MEMSET
+
+/* multiplication is fast on the cpu: a*b is with mod otherwise using tables
+   of logartihms */
+#undef HAVE_MULT_MOD
+
+/* Define if NTL is installed */
+#undef HAVE_NTL
+
+/* define if build with OMALLOC */
+#undef HAVE_OMALLOC
+
+/* Define to 1 if you have the <omalloc/omalloc.h> header file. */
+#undef HAVE_OMALLOC_OMALLOC_H
+
+/* Enable non-commutative subsystem */
+#undef HAVE_PLURAL
+
+/* Define to 1 if you have the `pow' function. */
+#undef HAVE_POW
+
+/* Define to 1 if you have the `putenv' function. */
+#undef HAVE_PUTENV
+
+/* Define to 1 if you have the <pwd.h> header file. */
+#undef HAVE_PWD_H
+
+/* Enable RatGB support */
+#undef HAVE_RATGRING
+
+/* Enable arithmetical rings */
+#undef HAVE_RINGS
+
+/* Define to 1 if you have the `setenv' function. */
+#undef HAVE_SETENV
+
+/* Enable letterplace */
+#undef HAVE_SHIFTBBA
+
+/* Define to 1 if you have the `sqrt' function. */
+#undef HAVE_SQRT
+
+/* Define to 1 if stdbool.h conforms to C99. */
+#undef HAVE_STDBOOL_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 `strchr' function. */
+#undef HAVE_STRCHR
+
+/* 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/param.h> header file. */
+#undef HAVE_SYS_PARAM_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 1 if you have the `vprintf' function. */
+#undef HAVE_VPRINTF
+
+/* Define if vsnprintf exists. */
+#undef HAVE_VSNPRINTF
+
+/* Define to 1 if the system has the type `_Bool'. */
+#undef HAVE__BOOL
+
+/* Define to the sub-directory in which libtool stores uninstalled libraries.
+   */
+#undef LT_OBJDIR
+
+/* DISABLE_GMP_CPP */
+#undef NOSTREAMIO
+
+/* Define to 1 if your C compiler doesn't accept -c and -o together. */
+#undef NO_MINUS_C_MINUS_O
+
+/* NTL_CFLAGS */
+#undef NTL_CFLAGS
+
+/* NTL_LIBS */
+#undef NTL_LIBS
+
+/* "Disable OM Debug" */
+#undef OM_NDEBUG
+
+/* Name of package */
+#undef PACKAGE
+
+/* 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
+
+/* SINGULAR */
+#undef SINGULAR
+
+/* SINGULAR_CFLAGS */
+#undef SINGULAR_CFLAGS
+
+/* "Disable Singular Debug" */
+#undef SING_NDEBUG
+
+/* The size of `long', as computed by sizeof. */
+#undef SIZEOF_LONG
+
+/* "i686" */
+#undef SI_CPU_I386
+
+/* "ia64" */
+#undef SI_CPU_IA64
+
+/* "PPC" */
+#undef SI_CPU_PPC
+
+/* "SPARC" */
+#undef SI_CPU_SPARC
+
+/* "x86-64" */
+#undef SI_CPU_X86_64
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Singular\'s own uname\ */
+#undef S_UNAME
+
+/* Version number of package */
+#undef VERSION
+
+/* Define to empty if `const' does not conform to ANSI C. */
+#undef const
+
+/* Define to `__inline__' or `__inline' if that's what the C compiler
+   calls it, or to nothing if 'inline' is not supported under any name.  */
+#ifndef __cplusplus
+#undef inline
+#endif
+
+/* Define to rpl_malloc if the replacement function should be used. */
+#undef malloc
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+#undef size_t
diff --git a/libpolys/aclocal.m4 b/libpolys/aclocal.m4
new file mode 100644
index 0000000..1b9da6e
--- /dev/null
+++ b/libpolys/aclocal.m4
@@ -0,0 +1,1185 @@
+# generated automatically by aclocal 1.13.4 -*- Autoconf -*-
+
+# Copyright (C) 1996-2013 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_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])
+m4_ifndef([AC_AUTOCONF_VERSION],
+  [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],,
+[m4_warning([this file was generated for autoconf 2.69.
+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'.])])
+
+# Copyright (C) 2002-2013 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.13'
+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.13.4], [],
+      [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.13.4])dnl
+m4_ifndef([AC_AUTOCONF_VERSION],
+  [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
+
+# Copyright (C) 2011-2013 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_AR([ACT-IF-FAIL])
+# -------------------------
+# Try to determine the archiver interface, and trigger the ar-lib wrapper
+# if it is needed.  If the detection of archiver interface fails, run
+# ACT-IF-FAIL (default is to abort configure with a proper error message).
+AC_DEFUN([AM_PROG_AR],
+[AC_BEFORE([$0], [LT_INIT])dnl
+AC_BEFORE([$0], [AC_PROG_LIBTOOL])dnl
+AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([ar-lib])dnl
+AC_CHECK_TOOLS([AR], [ar lib "link -lib"], [false])
+: ${AR=ar}
+
+AC_CACHE_CHECK([the archiver ($AR) interface], [am_cv_ar_interface],
+  [am_cv_ar_interface=ar
+   AC_COMPILE_IFELSE([AC_LANG_SOURCE([[int some_variable = 0;]])],
+     [am_ar_try='$AR cru libconftest.a conftest.$ac_objext >&AS_MESSAGE_LOG_FD'
+      AC_TRY_EVAL([am_ar_try])
+      if test "$ac_status" -eq 0; then
+        am_cv_ar_interface=ar
+      else
+        am_ar_try='$AR -NOLOGO -OUT:conftest.lib conftest.$ac_objext >&AS_MESSAGE_LOG_FD'
+        AC_TRY_EVAL([am_ar_try])
+        if test "$ac_status" -eq 0; then
+          am_cv_ar_interface=lib
+        else
+          am_cv_ar_interface=unknown
+        fi
+      fi
+      rm -f conftest.lib libconftest.a
+     ])
+   ])
+
+case $am_cv_ar_interface in
+ar)
+  ;;
+lib)
+  # Microsoft lib, so override with the ar-lib wrapper script.
+  # FIXME: It is wrong to rewrite AR.
+  # But if we don't then we get into trouble of one sort or another.
+  # A longer-term fix would be to have automake use am__AR in this case,
+  # and then we could set am__AR="$am_aux_dir/ar-lib \$(AR)" or something
+  # similar.
+  AR="$am_aux_dir/ar-lib $AR"
+  ;;
+unknown)
+  m4_default([$1],
+             [AC_MSG_ERROR([could not determine $AR interface])])
+  ;;
+esac
+AC_SUBST([AR])dnl
+])
+
+# AM_AUX_DIR_EXPAND                                         -*- Autoconf -*-
+
+# Copyright (C) 2001-2013 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-2013 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_CONDITIONAL(NAME, SHELL-CONDITION)
+# -------------------------------------
+# Define a conditional.
+AC_DEFUN([AM_CONDITIONAL],
+[AC_PREREQ([2.52])dnl
+ m4_if([$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-2013 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.
+
+
+# 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", "OBJC", "OBJCXX", "UPC", or "GJC".
+# 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
+
+m4_if([$1], [CC],   [depcc="$CC"   am_compiler_list=],
+      [$1], [CXX],  [depcc="$CXX"  am_compiler_list=],
+      [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
+      [$1], [OBJCXX], [depcc="$OBJCXX" 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".
+  rm -rf conftest.dir
+  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 10 /bin/sh.
+      echo '/* dummy */' > 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
+      ;;
+    msvc7 | msvc7msys | 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], [dnl
+AS_HELP_STRING(
+  [--enable-dependency-tracking],
+  [do not reject slow dependency extractors])
+AS_HELP_STRING(
+  [--disable-dependency-tracking],
+  [speeds up one-time build])])
+if test "x$enable_dependency_tracking" != xno; then
+  am_depcomp="$ac_aux_dir/depcomp"
+  AMDEPBACKSLASH='\'
+  am__nodep='_no'
+fi
+AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
+AC_SUBST([AMDEPBACKSLASH])dnl
+_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl
+AC_SUBST([am__nodep])dnl
+_AM_SUBST_NOTMAKE([am__nodep])dnl
+])
+
+# Generate code to set up dependency tracking.              -*- Autoconf -*-
+
+# Copyright (C) 1999-2013 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_OUTPUT_DEPENDENCY_COMMANDS
+# ------------------------------
+AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
+[{
+  # Older Autoconf 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"`
+    # 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'`; 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"])
+])
+
+# Do all the work for Automake.                             -*- Autoconf -*-
+
+# Copyright (C) 1996-2013 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 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.65])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],
+[AC_DIAGNOSE([obsolete],
+             [$0: two- and three-arguments forms are deprecated.])
+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], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]),
+  [ok:ok],,
+  [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([AC_PROG_MKDIR_P])dnl
+# For better backward compatibility.  To be removed once Automake 1.9.x
+# dies out for good.  For more background, see:
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
+AC_SUBST([mkdir_p], ['$(MKDIR_P)'])
+# 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])],
+		  [m4_define([AC_PROG_CC],
+			     m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_CXX],
+		  [_AM_DEPENDENCIES([CXX])],
+		  [m4_define([AC_PROG_CXX],
+			     m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_OBJC],
+		  [_AM_DEPENDENCIES([OBJC])],
+		  [m4_define([AC_PROG_OBJC],
+			     m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_OBJCXX],
+		  [_AM_DEPENDENCIES([OBJCXX])],
+		  [m4_define([AC_PROG_OBJCXX],
+			     m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl
+])
+AC_REQUIRE([AM_SILENT_RULES])dnl
+dnl The testsuite driver may need to know about EXEEXT, so add the
+dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen.  This
+dnl macro 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-2013 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-2013 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.
+
+# 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-2013 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_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 enable maintainer-specific portions of Makefiles])
+  dnl maintainer-mode's default is 'disable' unless 'enable' is passed
+  AC_ARG_ENABLE([maintainer-mode],
+    [AS_HELP_STRING([--]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
+]
+)
+
+# Check to see how 'make' treats includes.	            -*- Autoconf -*-
+
+# Copyright (C) 2001-2013 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_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
+])
+
+# Copyright (C) 1999-2013 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_CC_C_O
+# --------------
+# Like AC_PROG_CC_C_O, but changed for automake.
+AC_DEFUN([AM_PROG_CC_C_O],
+[AC_REQUIRE([AC_PROG_CC_C_O])dnl
+AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([compile])dnl
+# FIXME: we rely on the cache variable name because
+# there is no other way.
+set dummy $CC
+am_cc=`echo $[2] | sed ['s/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/']`
+eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o
+if test "$am_t" != yes; then
+   # Losing compiler, so override with the script.
+   # FIXME: It is wrong to rewrite CC.
+   # But if we don't then we get into trouble of one sort or another.
+   # A longer-term fix would be to have automake use am__CC in this case,
+   # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
+   CC="$am_aux_dir/compile $CC"
+fi
+dnl Make sure AC_PROG_CC is never called again, or it will override our
+dnl setting of CC.
+m4_define([AC_PROG_CC],
+          [m4_fatal([AC_PROG_CC cannot be called after AM_PROG_CC_C_O])])
+])
+
+# Fake the existence of programs that GNU maintainers use.  -*- Autoconf -*-
+
+# Copyright (C) 1997-2013 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_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 is modern enough.
+# If it is, 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 --is-lightweight"; then
+  am_missing_run="$MISSING "
+else
+  am_missing_run=
+  AC_MSG_WARN(['missing' script is too old or missing])
+fi
+])
+
+# Helper functions for option handling.                     -*- Autoconf -*-
+
+# Copyright (C) 2001-2013 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_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-2013 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_SANITY_CHECK
+# ---------------
+AC_DEFUN([AM_SANITY_CHECK],
+[AC_MSG_CHECKING([whether build environment is sane])
+# 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 (
+   am_has_slept=no
+   for am_try in 1 2; do
+     echo "timestamp, slept: $am_has_slept" > conftest.file
+     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
+     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
+     if test "$[2]" = conftest.file || test $am_try -eq 2; then
+       break
+     fi
+     # Just in case.
+     sleep 1
+     am_has_slept=yes
+   done
+   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])
+# If we didn't sleep, we still need to ensure time stamps of config.status and
+# generated files are strictly newer.
+am_sleep_pid=
+if grep 'slept: no' conftest.file >/dev/null 2>&1; then
+  ( sleep 1 ) &
+  am_sleep_pid=$!
+fi
+AC_CONFIG_COMMANDS_PRE(
+  [AC_MSG_CHECKING([that generated files are newer than configure])
+   if test -n "$am_sleep_pid"; then
+     # Hide warnings about reused PIDs.
+     wait $am_sleep_pid 2>/dev/null
+   fi
+   AC_MSG_RESULT([done])])
+rm -f conftest.file
+])
+
+# Copyright (C) 2009-2013 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_SILENT_RULES([DEFAULT])
+# --------------------------
+# Enable less verbose build rules; with the default set to DEFAULT
+# ("yes" being less verbose, "no" or empty being verbose).
+AC_DEFUN([AM_SILENT_RULES],
+[AC_ARG_ENABLE([silent-rules], [dnl
+AS_HELP_STRING(
+  [--enable-silent-rules],
+  [less verbose build output (undo: "make V=1")])
+AS_HELP_STRING(
+  [--disable-silent-rules],
+  [verbose build output (undo: "make V=0")])dnl
+])
+case $enable_silent_rules in @%:@ (((
+  yes) AM_DEFAULT_VERBOSITY=0;;
+   no) AM_DEFAULT_VERBOSITY=1;;
+    *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);;
+esac
+dnl
+dnl A few 'make' implementations (e.g., NonStop OS and NextStep)
+dnl do not support nested variable expansions.
+dnl See automake bug#9928 and bug#10237.
+am_make=${MAKE-make}
+AC_CACHE_CHECK([whether $am_make supports nested variables],
+   [am_cv_make_support_nested_variables],
+   [if AS_ECHO([['TRUE=$(BAR$(V))
+BAR0=false
+BAR1=true
+V=1
+am__doit:
+	@$(TRUE)
+.PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then
+  am_cv_make_support_nested_variables=yes
+else
+  am_cv_make_support_nested_variables=no
+fi])
+if test $am_cv_make_support_nested_variables = yes; then
+  dnl Using '$V' instead of '$(V)' breaks IRIX make.
+  AM_V='$(V)'
+  AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
+else
+  AM_V=$AM_DEFAULT_VERBOSITY
+  AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY
+fi
+AC_SUBST([AM_V])dnl
+AM_SUBST_NOTMAKE([AM_V])dnl
+AC_SUBST([AM_DEFAULT_V])dnl
+AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl
+AC_SUBST([AM_DEFAULT_VERBOSITY])dnl
+AM_BACKSLASH='\'
+AC_SUBST([AM_BACKSLASH])dnl
+_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl
+])
+
+# Copyright (C) 2001-2013 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-2013 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_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-2013 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_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.  Yes, it's still used
+# in the wild :-(  We should find a proper way to deprecate it ...
+AC_SUBST([AMTAR], ['$${TAR-tar}'])
+
+# We'll loop over all known methods to create a tar archive until one works.
+_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
+
+m4_if([$1], [v7],
+  [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'],
+
+  [m4_case([$1],
+    [ustar],
+     [# The POSIX 1988 'ustar' format is defined with fixed-size fields.
+      # There is notably a 21 bits limit for the UID and the GID.  In fact,
+      # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343
+      # and bug#13588).
+      am_max_uid=2097151 # 2^21 - 1
+      am_max_gid=$am_max_uid
+      # The $UID and $GID variables are not portable, so we need to resort
+      # to the POSIX-mandated id(1) utility.  Errors in the 'id' calls
+      # below are definitely unexpected, so allow the users to see them
+      # (that is, avoid stderr redirection).
+      am_uid=`id -u || echo unknown`
+      am_gid=`id -g || echo unknown`
+      AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format])
+      if test $am_uid -le $am_max_uid; then
+         AC_MSG_RESULT([yes])
+      else
+         AC_MSG_RESULT([no])
+         _am_tools=none
+      fi
+      AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format])
+      if test $am_gid -le $am_max_gid; then
+         AC_MSG_RESULT([yes])
+      else
+        AC_MSG_RESULT([no])
+        _am_tools=none
+      fi],
+
+  [pax],
+    [],
+
+  [m4_fatal([Unknown tar format])])
+
+  AC_MSG_CHECKING([how to create a $1 tar archive])
+
+  # Go ahead even if we have the value already cached.  We do so because we
+  # need to set the values for the 'am__tar' and 'am__untar' variables.
+  _am_tools=${am_cv_prog_tar_$1-$_am_tools}
+
+  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])
+      AM_RUN_LOG([cat conftest.dir/file])
+      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([../m4/ax_append_compile_flags.m4])
+m4_include([../m4/ax_append_flag.m4])
+m4_include([../m4/ax_append_link_flags.m4])
+m4_include([../m4/ax_check_compile_flag.m4])
+m4_include([../m4/ax_check_link_flag.m4])
+m4_include([../m4/ax_cxx_gcc_abi_demangle.m4])
+m4_include([../m4/ax_prefix_config_h.m4])
+m4_include([../m4/cpu-check.m4])
+m4_include([../m4/flags.m4])
+m4_include([../m4/flint-check.m4])
+m4_include([../m4/gmp-check.m4])
+m4_include([../m4/libtool.m4])
+m4_include([../m4/ltoptions.m4])
+m4_include([../m4/ltsugar.m4])
+m4_include([../m4/ltversion.m4])
+m4_include([../m4/lt~obsolete.m4])
+m4_include([../m4/ntl-check.m4])
+m4_include([../m4/options.m4])
+m4_include([../m4/p-procs.m4])
diff --git a/libpolys/coeffs/AE.cc b/libpolys/coeffs/AE.cc
new file mode 100644
index 0000000..d62422e
--- /dev/null
+++ b/libpolys/coeffs/AE.cc
@@ -0,0 +1,1281 @@
+#include <misc/auxiliary.h>
+#include <omalloc/omalloc.h>
+
+#include "AE.h"
+
+#include <math.h>
+
+#ifdef SINGULAR_4_1
+
+using namespace std;
+
+//Konstruktoren
+
+int_poly::int_poly()
+{
+    //coef = reinterpret_cast<mpz_t*> (omAlloc(100*sizeof(mpz_t)));
+    deg=-1;
+    mpz_init_set_ui(coef[0],0);
+}
+
+
+
+int_poly::int_poly(int n, mpz_t *a)
+{
+    //coef = reinterpret_cast<mpz_t*> (omAlloc(100*sizeof(mpz_t)));
+    deg=n;
+
+    for ( int i=0;i<=n;i++)
+    {
+        mpz_init_set(coef[i], a[i]);
+    }
+
+}
+
+/*
+//Destruktor
+
+int_poly::~int_poly()
+{
+        delete[] coef;
+}
+
+*/
+
+
+
+
+// Arithmetik
+
+
+//Additionen
+
+//Standard - Addition
+void int_poly::poly_add(const int_poly a, const int_poly b)
+{
+    if (a.deg >=b.deg)
+    {
+
+        deg=a.deg;
+
+        for ( int i=0;i<=b.deg;i++)
+        {
+            mpz_add(coef[i],a.coef[i],b.coef[i]);
+        }
+
+        for ( int i=b.deg+1;i<=a.deg;i++)
+        {
+            mpz_init_set(coef[i],a.coef[i]);
+        }
+        //Hier nötige Grad Korrektur
+        int i;
+        i=deg;
+        while(mpz_sgn(coef[i])==0 && i>=0)
+        {deg--;i--;}
+    }
+
+    else {poly_add(b,a);  }
+
+}
+
+//Überschreibende Addition
+
+void int_poly::poly_add_to(const int_poly g)
+{
+    this->poly_add(*this,g);
+}
+
+//Addition einer Konstanten
+void int_poly::poly_add_const(int_poly f,const mpz_t a)
+{
+    if (f.is_zero()==1)
+        poly_set(a);
+    else
+    {
+        poly_set(f);
+        mpz_add(coef[0],coef[0],a);
+        // Grad Korrektur
+        if (deg==0 && mpz_sgn(coef[0])==0)
+            poly_set_zero();
+    }
+
+}
+
+
+//To Variante Addition einer Konstanten
+
+void int_poly::poly_add_const_to(const mpz_t a)
+{
+    this->poly_add_const(*this,a);
+}
+
+//Monom Addition
+void int_poly::poly_add_mon(int_poly f, mpz_t a, int i)
+{
+    poly_set(f);
+
+    if (i<=deg  && is_zero()==0)
+    {
+        mpz_add(coef[i],coef[i],a);
+        // Grad Korrektur
+        if (deg==i && mpz_sgn(coef[i])==0)
+            deg--;
+    }
+    else if (is_zero()==1)
+    {
+        deg=i;
+        for(int j=0;j<=i;j++)
+        {
+            mpz_init_set_ui(coef[j],0);
+        }
+        mpz_add(coef[i],coef[i],a);
+
+    }
+    else if (i>deg)
+    {
+        for(int j=i;j>deg;j--)
+        {
+            mpz_init_set_ui(coef[j],0);
+        }
+        mpz_add(coef[i],coef[i],a);
+        deg=i;
+    }
+}
+
+//To Variante Monomaddition
+void int_poly::poly_add_mon_to(mpz_t a, int i)
+{
+    if (i<=deg  && is_zero()==0)
+    {
+        mpz_add(coef[i],coef[i],a);
+    }
+    else if (is_zero()==1)
+    {
+        deg=i;
+        for(int j=0;j<=i;j++)
+        {
+            mpz_init_set_ui(coef[j],0);
+        }
+        mpz_add(coef[i],coef[i],a);
+
+    }
+    else if (i>deg)
+    {
+        for(int j=i;j>deg;j--)
+        {
+            mpz_init_set_ui(coef[j],0);
+        }
+        mpz_add(coef[i],coef[i],a);
+        deg=i;
+    }
+    //Hier nötige Grad Korrektur
+    int k=deg;
+    while(mpz_sgn(coef[k])==0 && k>=0)
+    {deg--;k--;}
+
+}
+
+//Subtraktionen
+
+void int_poly::poly_sub(const int_poly a, const int_poly b)
+{
+    int_poly temp;
+    temp.poly_set(b);
+    temp.poly_neg();
+    poly_add(a,temp);
+
+    // Grad Korrektur
+    int i;
+    i=deg;
+    while(mpz_sgn(coef[i])==0 && i>=0)
+    {deg--;i--;}
+
+}
+
+
+//Überschreibende Subtraktion
+
+void int_poly::poly_sub_to(const int_poly b)
+{
+    this->poly_sub(*this,b);
+}
+
+//Subtraktion einer Konstanten
+void int_poly::poly_sub_const(int_poly f,const mpz_t a)
+{
+    if (f.is_zero()==1)
+    {
+        poly_set(a);
+        poly_neg();
+    }
+    else
+    {
+        poly_set(f);
+        mpz_sub(coef[0],coef[0],a);
+
+    }
+    //Hier nötige Grad Korrektur
+    int i=deg;
+    while(mpz_sgn(coef[i])==0 && i>=0)
+    {deg--;i--;}
+
+}
+
+
+//To Variante Subtraktion einer Konstanten
+
+void int_poly::poly_sub_const_to(const mpz_t a)
+{
+    this->poly_sub_const(*this,a);
+}
+
+
+//Monom Subtraktion
+void int_poly::poly_sub_mon(const int_poly f , mpz_t a, int i)
+{
+    poly_set(f);
+
+    if (i<=deg && is_zero()!=1)
+    {
+        mpz_sub(coef[i],coef[i],a);
+        // Grad Korrektur
+        if (deg==i && mpz_sgn(coef[i])==0)
+            deg--;
+    }
+    else if (is_zero()==1)
+    {
+        for(int j=0;j<=i;j++)
+        {
+            mpz_init_set_ui(coef[j],0);
+        }
+        mpz_sub(coef[i],coef[i],a);
+        deg=i;
+    }
+    else
+    {
+        for(int j=i;j>deg;j--)
+        {
+            mpz_init_set_ui(coef[j],0);
+        }
+        mpz_sub(coef[i],coef[i],a);
+        deg=i;
+    }
+}
+
+//To Variante Monomaddition
+void int_poly::poly_sub_mon_to(mpz_t a, int i)
+{
+
+    if (i<=deg && is_zero()!=1)
+    {
+        mpz_sub(coef[i],coef[i],a);
+        // Grad Korrektur
+        if (deg==i && mpz_sgn(coef[i])==0)
+            deg--;
+    }
+    else if (is_zero()==1)
+    {
+        for(int j=0;j<=i;j++)
+        {
+            mpz_init_set_ui(coef[j],0);
+        }
+        mpz_sub(coef[i],coef[i],a);
+        deg=i;
+    }
+    else
+    {
+        for(int j=i;j>deg;j--)
+        {
+            mpz_init_set_ui(coef[j],0);
+        }
+        mpz_sub(coef[i],coef[i],a);
+        deg=i;
+    }
+}
+
+
+//Multiplikationen
+
+//Multiplikation mit Monom
+void int_poly::poly_mon_mult(const int_poly f, int n)
+{
+    if (f.is_zero()==1)
+    {
+        poly_set_zero();
+    }
+    else
+    {
+        deg=f.deg+n;
+        for (int i=deg;i>=n;i--)
+        {
+            mpz_init_set(coef[i],f.coef[i-n]);
+        }
+        for (int i=n-1;i>=0;i--)
+        {
+            mpz_init_set_ui(coef[i],0);
+        }
+    }
+}
+
+void int_poly::poly_mon_mult_to(const int n)
+{
+    this->poly_mon_mult(*this,n);
+}
+
+
+//Multiplikation mit Skalar
+
+void int_poly::poly_scalar_mult(const int_poly g, const mpz_t n)
+{
+    if (mpz_sgn(n)==0)
+        poly_set_zero();
+    else
+    {
+        deg=g.deg;
+        mpz_t temp;
+        mpz_init_set_ui(temp,0);
+        for(int i=0;i<=deg;i++)
+        {
+            mpz_mul(temp,n,g.coef[i]);
+            mpz_init_set(coef[i],temp);
+        }
+    }
+}
+
+
+
+void int_poly::poly_scalar_mult(const mpz_t n, const int_poly g)
+{
+    if (mpz_sgn(n)==0)
+        poly_set_zero();
+    else
+    {
+        deg=g.deg;
+        mpz_t temp;
+        mpz_init_set_ui(temp,0);
+        for(int i=0;i<=deg;i++)
+        {
+            mpz_mul(temp,n,g.coef[i]);
+            mpz_init_set(coef[i],temp);
+        }
+    }
+}
+
+
+void int_poly::poly_scalar_mult_to(const mpz_t n)
+{
+    this->poly_scalar_mult(*this,n);
+}
+
+
+
+// Negation
+
+void int_poly::poly_neg()
+{
+    for (int i=0;i<=deg;i++)
+    {
+        mpz_neg(coef[i],coef[i]);
+    }
+}
+
+// Naive Multiplikation
+void int_poly::poly_mult_n(int_poly a,int_poly b)
+{
+
+    if (a.is_zero()==1 || b.is_zero()==1)
+    {
+        poly_set_zero();
+    }
+    else
+    {
+        mpz_t temp;
+        mpz_init_set_ui(temp,0);
+        deg = a.deg + b.deg;
+
+        // Kopien atemp und btemp von a bzw. b, mit Nullen aufgefüllt
+        int_poly atemp, btemp;
+        atemp.poly_set(a);
+        btemp.poly_set(b);
+        for(int i=a.deg+1;i<=deg;i++)
+        {
+            mpz_init_set_ui(atemp.coef[i],0);
+        }
+        for(int i=b.deg+1;i<=deg;i++)
+        {
+            mpz_init_set_ui(btemp.coef[i],0);
+        }
+        atemp.deg = deg;
+        btemp.deg = deg;
+
+        // Multiplikationsalgorithmus
+        for (int k=0; k<=deg; k++)
+        {
+            mpz_init_set_ui(coef[k],0);        // k-ter Koeffizient zunächst 0
+            for (int i=0; i<=k; i++)        // dann schrittweise Summe der a[i]*b[k-i]/
+            {
+                mpz_mul(temp,atemp.coef[i],btemp.coef[k-i]);
+                mpz_add(coef[k],coef[k],temp);
+            }
+        }
+
+    }
+}
+
+//Überschreibende Multiplikation
+
+void int_poly::poly_mult_n_to(const int_poly g)
+{
+    this->poly_mult_n(*this,g);
+
+}
+
+// Karatsuba-Multiplikation (Weimerskirch/Paar Alg. 1), ACHTUNG VORLÄUFIGE VERSION, macht noch Fehler beim Grad und ist unelegant !!!
+void int_poly::poly_mult_ka( int_poly A,  int_poly B)
+{
+
+    if (A.is_zero()==1 || B.is_zero()==1)
+    {
+        poly_set_zero();
+    }
+    else
+    {
+        // Größeren Grad feststellen
+        int n;
+        if(A.deg>=B.deg){n=A.deg+1;}
+        else{n=B.deg+1;}
+        // n auf nächste 2er-Potenz setzen (VORLÄUFIG!)
+        n = static_cast<int>(ceil(log(n)/log(2)));
+        n = static_cast<int>(pow(2,n));
+
+        if (n==1)
+        {
+            mpz_t AB;
+            mpz_mul(AB,A.coef[0],B.coef[0]);
+            poly_set(AB);
+        }
+        else
+        {
+            // int_polynome A und B aufspalten
+            int_poly Au, Al, Bu, Bl;
+            Au.poly_mon_div(A,n/2);
+            Al.poly_mon_div_rem(A,n/2);
+            Bu.poly_mon_div(B,n/2);
+            Bl.poly_mon_div_rem(B,n/2);
+            int_poly Alu,Blu;
+            Alu.poly_add(Al,Au);
+            Blu.poly_add(Bl,Bu);
+
+            // Teile rekursiv multiplizieren
+            int_poly D0, D1, D01;
+            D0.poly_mult_ka(Al,Bl);
+            D1.poly_mult_ka(Au,Bu);
+            D01.poly_mult_ka(Alu,Blu);
+
+            // Ergebnis zusammensetzen
+            int_poly temp;
+            D01.poly_sub_to(D0);
+            D01.poly_sub_to(D1);
+            D01.poly_mon_mult_to(n/2);
+            D1.poly_mon_mult_to(n);
+            D1.poly_add_to(D01);
+            D1.poly_add_to(D0);
+            poly_set(D1);
+        }
+    }
+}
+
+
+
+//Skalare Divisionen
+
+void int_poly::poly_scalar_div( const int_poly g, const mpz_t n)
+{
+    deg=g.deg;
+    mpz_t temp;
+    mpz_init_set_ui(temp,0);
+    for(int i=0;i<=deg;i++)
+    {
+        mpz_divexact(temp,g.coef[i],n);
+        mpz_init_set(coef[i],temp);
+    }
+}
+
+
+void int_poly::poly_scalar_div_to(const mpz_t n)
+{
+    this->poly_scalar_div(*this,n);
+}
+
+// Division durch Monom -  results in Quotient without remainder
+void int_poly::poly_mon_div(const int_poly f, const int n)
+{
+    if (f.deg<n)
+    {
+        poly_set_zero();
+    }
+    else
+    {
+        deg=f.deg-n;
+        for (int i=0;i<=f.deg-n;i++)
+        {
+            mpz_init_set(coef[i],f.coef[n+i]);
+        }
+    }
+}
+
+// Division durch Monom - Rest
+void int_poly::poly_mon_div_rem(const int_poly f, const int n)
+{
+    if (f.deg<n)
+    {
+        poly_set(f);
+    }
+    else
+    {
+        deg=n-1;
+        for (int i=0;i<=n-1;i++)
+        {
+            mpz_init_set(coef[i],f.coef[i]);
+        }
+    }
+}
+
+
+
+
+//Exakte Division nach Cohen 3.1.1 (works only if B!=0)
+void int_poly::poly_div(int_poly &Q,int_poly &R, int_poly A,  int_poly B)
+{
+    if (B.is_zero()==0)
+    {
+        //Initialisierungen
+        int_poly temp;
+        R.poly_set(A);
+        Q.poly_set_zero();
+        mpz_t a;
+        mpz_init_set_ui(a,0);
+        int i;
+
+        //Algorithmus TO DO: evtl hier mit auch den Rest ausgeben
+        while (R.deg>=B.deg)
+        {
+            mpz_divexact(a,R.coef[R.deg],B.coef[B.deg]);
+            i=R.deg-B.deg;
+
+            temp.poly_mon_mult(B,i);
+            temp.poly_scalar_mult_to(a);
+
+            R.poly_sub_to(temp);
+            Q.poly_add_mon_to(a,i);
+        }
+        poly_set(Q);
+    }
+}
+
+
+//To Varainte der exakten Division
+
+void int_poly::poly_div_to(int_poly &Q,int_poly &R,const int_poly B)
+{
+    this->poly_div( Q, R,*this,B);
+}
+
+// pseudo Division nach Cohen 3.1.2 (geht eleganter)
+
+void int_poly::poly_pseudodiv_rem( int_poly A,  int_poly B)
+{
+
+    if (B.is_zero()==0)
+    {
+        int_poly temp;
+        int_poly R;
+        R.poly_set(A);
+        int e=A.deg-B.deg+1;
+        while (R.deg>=B.deg)
+        {
+
+            temp.poly_mon_mult(B,R.deg-B.deg);
+            temp.poly_scalar_mult_to(R.coef[R.deg]);
+            R.poly_scalar_mult_to(B.coef[B.deg]);
+            R.poly_sub_to(temp);
+            e--;
+
+        }
+        mpz_t q;
+        mpz_init_set(q,B.coef[B.deg]);
+        mpz_pow_ui(q,q,e);
+        R.poly_scalar_mult_to(q);
+        poly_set(R);
+    }
+}
+
+//To Variante Algo 3.1.2 nach Cohen
+
+void int_poly::poly_pseudodiv_rem_to(const int_poly B)
+{
+    this->poly_pseudodiv_rem(*this,B);
+}
+
+
+//Pseudodivision nach Kaplan, M. Computeralgebra 4.6 welche q^e*A=Q*B+R
+//berechnet und entsprechendes in Q und R hineinschreibt
+
+void int_poly::poly_pseudodiv(int_poly &Q, int_poly &R, int_poly A,  int_poly B)
+{
+
+    if (B.is_zero()==0)
+    {
+        // Initialisierungen: Vergiss zunächst die Hauptnenner von A und B (--> R bzw. Bint)
+        int_poly temp;
+        R.poly_set(A);
+
+
+        int k = A.deg - B.deg;
+
+        //Initialisiere Q mit 0en
+        Q.deg=k;
+        for (int i=0;i<=k;i++)
+        {
+            mpz_init_set_ui(Q.coef[i],0);
+        }
+
+
+        // Algorithmus
+        while (k>=0)
+        {
+
+            mpz_set(Q.coef[k],R.coef[R.deg]);
+
+            temp.poly_mon_mult(B,k);
+            temp.poly_scalar_mult_to(R.coef[R.deg]);
+
+            R.poly_scalar_mult_to(B.coef[B.deg]);
+            R.poly_sub_to(temp);
+
+            k=R.deg-B.deg;
+        }
+
+        int delta;
+        delta=0;
+        mpz_t dummy;
+        mpz_init_set_ui(dummy,0);
+
+        for (int i=0;i<=A.deg-B.deg;i++)
+        {
+            if (mpz_cmp_ui(Q.coef[i],0)!=0)
+            {
+                mpz_pow_ui(dummy,B.coef[B.deg],delta);
+                mpz_mul(Q.coef[i],Q.coef[i],dummy);
+                delta++;
+            }
+
+        }
+
+    }
+
+
+}
+
+
+//To Variante Algo 3.1.2 nach Cohen
+
+void int_poly::poly_pseudodiv_to(int_poly &Q, int_poly &R, int_poly B)
+{
+    this->poly_pseudodiv(Q, R,*this,B);
+}
+
+// Kombinationen
+
+// a := a*b + c
+void int_poly::poly_multadd_to(const int_poly b, const int_poly c)
+{
+    poly_mult_n_to(b);
+    poly_add_to(c);
+}
+
+//a=a*b-c
+void int_poly::poly_multsub_to(const int_poly b, const int_poly c)
+{
+    poly_mult_n_to(b);
+    poly_sub_to(c);
+}
+
+
+
+/*
+// a := (a+b)* c
+void int_poly::poly_addmult_to(const int_poly b, const int_poly c)
+{
+        int_poly a(deg,coef);
+        a.poly_add_to(b);
+        a.poly_mult_n_to(c);
+        poly_set(a);
+}
+*/
+
+// Eigenschaften
+
+// Content (Cohen 3.2.7), schreibt Ergebnis ins Argument cont
+void int_poly::poly_cont(mpz_t& cont)
+{
+    if (is_zero()==1)
+    {
+        mpz_init_set_ui(cont,0);
+    }
+    else
+    {
+        mpz_t temp;
+        int i=1;
+        mpz_init_set(temp,coef[0]);
+        while (mpz_cmp_ui(temp,1)!=0 && i<=deg)
+        {
+            mpz_gcd(temp,temp,coef[i]);
+            i++;
+        }
+        mpz_init_set(cont,temp);
+    }
+}
+
+
+// Primitive Part (Cohen 3.2.7) unter Verwendung von mpz_divexact
+// da wir wissen,dass der Inhalt alle Elemente teilt
+//ÜBERSCHREIBT DAS int_polyNOM WELCHES DEN BEFEHL AUFRUFT!!!!
+
+
+void int_poly::poly_pp(int_poly f)
+{
+    mpz_t cont;
+    f.poly_cont(cont); // cont ist auf den Inhalt von f gesetzt.
+
+    if (mpz_cmp_ui(cont,1)==0)
+        poly_set(f);
+    else
+    {
+        deg=f.deg;
+        for (int i=0;i<=deg;i++)
+        {
+            mpz_init_set_ui(coef[i],0);
+            mpz_divexact(coef[i],f.coef[i],cont);
+        }
+
+    }
+}
+
+
+
+//Sonstiges
+void int_poly::poly_horner(mpz_t erg, const mpz_t u)
+{
+    mpz_init_set(erg,coef[deg]);
+    for (int i=deg;i>=1;i--)
+    {
+        mpz_mul(erg,erg,u);
+        mpz_add(erg,erg,coef[i-1]);
+    }
+}
+
+// int_polynom in int_polynom einsetzen(Horner-Schema) KRITISCHE EINGABE x^2, x^2  ....
+
+void int_poly::poly_horner_int_poly(const int_poly A,const int_poly B)
+{
+    poly_set(A.coef[A.deg]);
+    for (int i=A.deg;i>=1;i--)
+    {
+        poly_mult_n_to(B);
+        poly_add_const_to(A.coef[i-1]);
+    }
+}
+
+
+
+//Hilfsfunktionen
+
+
+//setze int_polynom auf int_polynom b
+void int_poly::poly_set(const int_poly b)
+{
+    deg=b.deg;
+    for(int i=0;i<=deg;i++)
+    {
+        mpz_init_set(coef[i],b.coef[i]); // Hier wird init set dringendst benötigt
+    }
+
+}
+
+// setze int_polynom auf konstantes int_polynom b
+void int_poly::poly_set(const mpz_t b)
+{
+    deg=0;
+    mpz_init_set(coef[0],b);
+}
+
+
+//setze int_polynom auf Nullint_polynom
+void int_poly::poly_set_zero()
+{
+    deg = -1;
+}
+
+
+//Vergleiche ob 2 int_polynome gleich return 1 falls ja sont 0
+
+int int_poly::is_equal(const int_poly g) const
+{
+    if (deg!=g.deg)
+        return 0;
+    else
+
+        for (int i=deg;i>=0; i--)
+        {
+        if (mpz_cmp(coef[i],g.coef[i])!=0)
+        {return 0;}
+    }
+    return 1;
+}
+
+//Überprüft ob das int_polynom 0 ist
+
+int int_poly::is_zero() const
+{
+    if (deg<0)
+        return 1;
+    else
+        return 0;
+
+}
+
+int int_poly::is_one() const
+{
+    if (deg==0)
+    {
+        if (mpz_cmpabs_ui(coef[0],1)==0) { return 1; }
+        else { return 0; }
+    }
+    else { return 0; }
+}
+
+int int_poly::is_monic() const
+{
+    if (mpz_cmpabs_ui(coef[deg],1)==0)
+        return 1;
+    else
+        return 0;
+}
+
+// klassischer GGT nach Cohen 3.2.1
+
+void int_poly::poly_gcd( int_poly A,  int_poly B)
+{
+    if (A.deg<B.deg)
+        poly_gcd(B,A);
+    else if (B.is_zero()==1)
+        poly_set(A);
+    else if (B.is_monic()==0)
+    {
+        //cout << "Subresultanten GGT wird benutzt"<<endl;
+        poly_subgcd(A,B);
+    }
+    else
+    {
+        int_poly Q;
+        int_poly App;
+        int_poly Bpp;
+        int_poly R;
+        App.poly_set(A);
+        Bpp.poly_set(B);
+
+        while (Bpp.is_zero()==0)
+        {
+            R.poly_div(Q,R,App,Bpp);
+            App.poly_set(Bpp);
+            Bpp.poly_set(R);
+        }
+        poly_set(App);
+    }
+
+}
+
+// GGT nach Cohen, Algorithmus 3.2.10 (Primitive int_polynomial GCD) TO DO: Optimierung bzgl. Mehrfachberechnung)
+// Bpp ist das B in den Schritten ab 2
+
+
+void int_poly::poly_ppgcd(int_poly A,int_poly B)
+{
+    if(A.deg<B.deg)
+    {
+        poly_ppgcd(B,A);
+
+    }
+    else if(B.is_zero()==1)
+    {
+        poly_set(A);
+
+    }
+    else
+    {
+        //Initialisierung und Reduktionen
+        mpz_t a;
+        mpz_init_set_ui(a,0);
+        mpz_t b;
+        mpz_init_set_ui(b,0);
+        mpz_t d;
+        mpz_init_set_ui(d,0);
+        A.poly_cont(a);
+        B.poly_cont(b);
+        mpz_gcd(d,a,b);
+
+        int_poly App;
+        int_poly Bpp;
+        int_poly R;
+
+        //Erster Schritt im Algo
+        App.poly_pp(A);
+        Bpp.poly_pp(B);
+        R.poly_pseudodiv_rem(App,Bpp);
+
+        //Algo
+
+        while (R.deg>0)
+        {
+            App.poly_set(Bpp);
+            Bpp.poly_pp(R);
+            R.poly_pseudodiv_rem(App,Bpp);
+        }
+
+        if (R.is_zero()==0)
+        {
+            deg=0;
+            mpz_init_set(coef[0],d);
+        }
+        else
+        {
+            poly_set(Bpp);
+            poly_scalar_mult_to(d);
+        }
+    }
+}
+// To Variante ppgcd
+
+
+void int_poly::poly_ppgcd_to(int_poly B)
+{
+    this->poly_ppgcd(*this,B);
+}
+
+
+
+// GGT nach Cohen, Algorithmus 3.3.1 (Subresultant int_polynomial GCD) TO DO: Optimierung bzgl. Mehrfachberechnung)
+// Bpp ist das B in den Schritten ab 2
+void int_poly::poly_subgcd(int_poly A, int_poly B)
+{
+    //Initialisierung und Reduktionen
+    if(A.deg<B.deg)
+    {
+        poly_subgcd(B,A);
+
+    }
+    else if(B.is_zero()==1)
+    {
+        poly_set(A);
+
+    }
+    else
+    {
+        mpz_t a;
+        mpz_init_set_ui(a,0);
+        mpz_t b;
+        mpz_init_set_ui(b,0);
+        mpz_t d;
+        mpz_init_set_ui(d,0);
+        mpz_t h;
+        mpz_init_set_ui(h,1);
+        mpz_t g;
+        mpz_init_set_ui(g,1);
+        mpz_t temp1;
+        mpz_init_set_ui(temp1,0);
+        mpz_t temp2;
+        mpz_init_set_ui(temp2,0);
+
+        A.poly_cont(a);
+        B.poly_cont(b);
+        mpz_gcd(d,a,b);
+
+        int_poly App;
+        int_poly Bpp;
+        int_poly R;
+
+        //Erster Schritt im Algo
+        int delta;
+        App.poly_pp(A);
+        Bpp.poly_pp(B);
+        R.poly_pseudodiv_rem(App,Bpp);
+
+        //Algo
+
+        while (R.deg>0)
+        {
+            delta =App.deg-Bpp.deg;
+
+            mpz_pow_ui(temp1,h,delta);
+            mpz_mul(temp2,temp1,g);
+            App.poly_set(Bpp);
+            Bpp.poly_pp(R);
+            Bpp.poly_scalar_div_to(temp2);
+
+            mpz_set(g,App.coef[App.deg]);
+            mpz_pow_ui(temp1,h,1-delta);
+            mpz_pow_ui(temp2,g,delta);
+            mpz_mul(h,temp1,temp2);
+
+
+            App.poly_set(Bpp);
+            Bpp.poly_pp(R);
+            R.poly_pseudodiv_rem(App,Bpp);
+
+        }
+
+        if (R.is_zero()==0)
+        {
+            deg=0;
+            mpz_init_set(coef[0],d);
+        }
+        else
+        {
+            poly_set(Bpp);
+            poly_cont(temp1);
+            poly_scalar_mult_to(d);
+            poly_scalar_div_to(temp1);
+        }
+    }
+}
+
+// To Varianta Subresultanten
+
+void int_poly::poly_subgcd_to(int_poly B)
+{
+    this->poly_subgcd(*this,B);
+}
+
+
+//Extended Subresultant GCD; see Kaplan, M. Computeralgebra, chapter 4.6
+//returns g=r*A+t*B IT WORKS DONT TOUCH IT!!!!!!!!
+void int_poly::poly_extsubgcd(int_poly& r, int_poly& t,int_poly &g,int_poly A,int_poly B)
+{
+    if (A.deg<B.deg)
+        poly_extsubgcd(t,r,g,B,A);
+    else if (B.is_zero()==1)
+    {
+        g.poly_set(A);
+        t.poly_set_zero();
+
+        mpz_t temp;
+        mpz_init_set_ui(temp,1);
+        r.poly_set(temp);
+    }
+
+    else
+    {
+        //Initialization (temp will be -1 in the algorithm)
+        mpz_t temp;
+        mpz_t temp2;
+        mpz_t psi;
+        int alpha;
+        int delta;
+        int delta2;
+        mpz_t base; //will be always (-1)^ ...
+        mpz_t base2; //will be always (-1)^ .../LK ...
+        mpz_t base3;
+        mpz_init_set_ui(temp,1);
+        mpz_init_set_ui(base,1);
+        mpz_init_set_ui(base2,1);
+        mpz_init_set_ui(base3,1);
+        mpz_init_set_ui(psi,1);
+        delta=A.deg-B.deg;
+        delta2=delta;
+        alpha=delta2+1;
+
+        int_poly dummy; // is needed in the main algorithm for -q*r_i resp. -q*t_i
+        dummy.poly_set_zero();
+
+        int_poly dummy2; // is needed in the main algorithm for LK * r_i resp LK* t_i
+        dummy2.poly_set_zero();
+
+        int_poly f1;
+        int_poly f2;
+        int_poly f3;
+        int_poly f;
+
+        int_poly q;
+
+        int_poly r1;
+        int_poly r2;
+        int_poly r3;
+
+        int_poly t1;
+        int_poly t2;
+        int_poly t3;
+
+        f1.poly_set(A);
+        f2.poly_set(B);
+        f.poly_set_zero();
+
+        r1.poly_set(temp);
+        r2.poly_set_zero();
+
+        t1.poly_set_zero();
+        t2.poly_set(temp);
+
+        mpz_set_si(temp,-1);
+
+        //Calculating first step
+        mpz_init_set_ui(temp2,0);
+        mpz_pow_ui(temp2,f2.coef[f2.deg],alpha);
+        f.poly_scalar_mult(f1,temp2);
+
+
+        A.poly_div(q,f3,f,f2);
+        mpz_pow_ui(base,temp,alpha);
+        f3.poly_scalar_mult_to(base);
+
+
+        r3.poly_set(base);
+        mpz_pow_ui(base2,f2.coef[f2.deg],alpha);
+        r3.poly_scalar_mult_to(base2);
+
+
+        mpz_pow_ui(base,temp,delta);
+        t3.poly_set(base);
+        t3.poly_mult_n_to(q);
+
+
+
+        //Correcting the polynomials and constants
+
+        f1.poly_set(f2);
+        f2.poly_set(f3);
+
+        r1.poly_set(r2);
+        r2.poly_set(r3);
+
+        t1.poly_set(t2);
+        t2.poly_set(t3);
+
+        delta=delta2;
+        delta2=f1.deg-f2.deg;
+        alpha=delta2+1;
+
+        //Main Algorithm
+        while (f2.is_zero()==0)
+        {
+
+
+            //Step 1.1+1.2: base and base 2 will be psi^ ... and LK^...
+
+            mpz_pow_ui(temp2,f2.coef[f2.deg],alpha);
+            f.poly_scalar_mult(f1,temp2);
+            A.poly_div(q,f3,f,f2);
+
+
+            mpz_pow_ui(base,psi,delta);
+            mpz_pow_ui(base2,f1.coef[f1.deg],delta);
+
+
+            mpz_mul(base2,base2,psi);
+            mpz_divexact(psi,base2,base);
+
+            //Step 1.3
+
+            mpz_pow_ui(base,temp,alpha);
+            mpz_pow_ui(base2,psi,delta2);
+            mpz_mul(base2,base2,f1.coef[f1.deg]);
+            f3.poly_scalar_div_to(base2);
+            f3.poly_scalar_mult_to(base);
+
+
+            //Step 1.4
+
+            mpz_pow_ui(base3,f2.coef[f2.deg],alpha);
+
+            //computing r_i
+            dummy.poly_mult_n(q,r2);
+            dummy2.poly_scalar_mult(r1,base3);
+            r3.poly_sub(dummy2,dummy);
+            r3.poly_scalar_mult_to(base);
+            r3.poly_scalar_div_to(base2);
+
+            //computing t_i
+            dummy.poly_mult_n(q,t2);
+            dummy2.poly_scalar_mult(t1,base3);
+            t3.poly_sub(dummy2,dummy);
+            t3.poly_scalar_mult_to(base);
+            t3.poly_scalar_div_to(base2);
+
+            //Correcting the polynomials and constants
+
+            f1.poly_set(f2);
+            f2.poly_set(f3);
+
+            r1.poly_set(r2);
+            r2.poly_set(r3);
+
+            t1.poly_set(t2);
+            t2.poly_set(t3);
+
+            delta=delta2;
+            delta2=f1.deg-f2.deg;
+            alpha=delta2+1;
+
+        }
+
+        //Computing result
+        g.poly_set(f1);
+        r.poly_set(r1);
+        t.poly_set(t1);
+
+    }
+
+
+}
+
+//Ein & Ausgabe
+
+//Eingabe
+
+void int_poly::poly_insert()
+{
+#if 0
+    cout << "Bitte geben Sie ein int_polynom ein! Zunächst den Grad: " << endl;
+    cin >> deg;
+
+
+    for ( int i=0; i<=deg;i++)
+    {
+        mpz_init_set_ui(coef[i],0);
+        printf("Geben Sie nun f[%i] ein:",i);
+        mpz_inp_str(coef[i],stdin, 10);
+    }
+#endif
+}
+
+
+//Ausgabe
+void int_poly::poly_print()
+{
+#if 0
+    if (is_zero()==1)
+        cout << "0" << "\n" <<endl;
+    else
+    {
+        for (int i=deg;i>=1;i--)
+        {
+            mpz_out_str(stdout,10, coef[i]);
+            printf("X%i+",i);
+        }
+        mpz_out_str(stdout,10, coef[0]);
+        printf("\n");
+    }
+#endif
+}
+
+#endif
diff --git a/libpolys/coeffs/AE.h b/libpolys/coeffs/AE.h
new file mode 100644
index 0000000..bae20ea
--- /dev/null
+++ b/libpolys/coeffs/AE.h
@@ -0,0 +1,112 @@
+#ifndef AE_H
+#define AE_H
+
+#include <misc/auxiliary.h>
+#include "si_gmp.h"
+
+#ifdef SINGULAR_4_1
+
+class int_poly // Klasse von int_polynomen mit Typ (Grad, Koeffizienten ganzzahlig)
+{
+
+public:
+    // Charakteristika der int_polynome (TO DO??: Dynamisches Array)
+
+    int deg;                // Grad des int_polynoms
+    mpz_t coef[100];        // Feld der Koeffizienten
+    //mpz_t coef = reinterpret_cast<mpz_t*> (omAlloc(100*sizeof(mpz_t)));
+
+
+    // Konstruktoren und Destruktoren
+    int_poly();
+    int_poly( int , mpz_t*);
+    //~int_poly();
+
+
+
+    // Arithmetische Operationen
+
+
+    // Additionen
+
+    void poly_add(const int_poly , const int_poly );
+    void poly_add_to(const int_poly);
+    void poly_add_mon(const int_poly,mpz_t, int); //addiert Monome zu int_polynom
+    void poly_add_mon_to(mpz_t,int);
+    void poly_add_const( int_poly, const mpz_t);
+    void poly_add_const_to(const mpz_t);
+
+    // Subtraktion
+
+    void poly_sub(const int_poly , const int_poly );
+    void poly_sub_to(const int_poly);
+    void poly_sub_mon(const int_poly,mpz_t,int);
+    void poly_sub_mon_to(mpz_t,int);
+    void poly_sub_const( int_poly, const mpz_t);
+    void poly_sub_const_to(const mpz_t);
+
+    //Multiplikationen
+
+    void poly_mult_n(int_poly,int_poly);
+    void poly_mult_n_to(const int_poly);
+    void poly_mult_ka( int_poly,  int_poly);
+    void poly_scalar_mult(const mpz_t ,const int_poly);
+    void poly_scalar_mult(const int_poly, const mpz_t);
+    void poly_scalar_mult_to(const mpz_t);
+    void poly_neg();
+    void poly_mon_mult(const int_poly, const int);
+    void poly_mon_mult_to(const int);
+
+    //Divisionen
+    void poly_div(int_poly &,int_poly &, int_poly,  int_poly); // exakte Division
+    void poly_div_to(int_poly &,int_poly &,const int_poly);       // To Variante exakte Division
+    void poly_pseudodiv(int_poly &, int_poly &, int_poly ,  int_poly );
+    void poly_pseudodiv_to(int_poly &, int_poly &, int_poly );
+    void poly_pseudodiv_rem( int_poly , int_poly);
+    void poly_pseudodiv_rem_to(const int_poly);
+    void poly_scalar_div(const int_poly, const mpz_t);
+    void poly_scalar_div_to(const mpz_t);
+    void poly_mon_div(const int_poly, const int);
+    void poly_mon_div_rem(const int_poly, const int);
+
+    //Kombinationen
+
+    void poly_multadd_to(const int_poly, const int_poly); //a=a*b+c
+    void poly_multsub_to(const int_poly,const int_poly);  //a=a*b-c
+    //int_poly poly_addmult_to(const int_poly, const int_poly);
+
+    // Eigenschaften von int_polynomen
+
+    // Content & Primitive Part
+    void poly_cont(mpz_t&);
+    void poly_pp(int_poly);
+
+
+    // Sonstige Operationen
+    void poly_set(const int_poly);
+    void poly_set(const mpz_t);                // Setzt int_polynom auf Konstante
+    void poly_set_zero();                        // Setzt int_polynom auf 0
+    void poly_horner(mpz_t, const mpz_t);        // Wertet int_polynom mittels Horner-Schema an einer Stelle aus
+    void poly_horner_int_poly(int_poly, const int_poly);        //Setzt int_polynom in int_polynom mittels Horner Schema ein
+    void poly_gcd(int_poly,int_poly);                //Standard GGT
+    void poly_extgcd(int_poly,int_poly,int_poly,int_poly);        //Erweiterter Standard GGT
+    void poly_ppgcd( int_poly, int_poly);                // Primitive int_polynomial GCD
+    void poly_ppgcd_to(int_poly);
+    void poly_subgcd( int_poly, int_poly);                // Subresulatant GCD
+    void poly_subgcd_to(int_poly);
+    void poly_extsubgcd(int_poly&, int_poly&,int_poly &,int_poly,int_poly);
+    int is_equal(const int_poly) const;                // Test auf Gleichheit
+    int is_zero() const;                                // Test auf Gleichheit mit 0
+    int is_one() const;                                // Test auf Gleichheit mit 1
+    int is_monic() const;                                // testet, ob das int_polynom normiert ist
+
+
+    // Ein und Ausgabe
+    void poly_insert();                        // Eingabe von int_polynom
+    void poly_print();                        //Ausgabe von int_polynom
+};
+
+#endif
+#endif
+
+
diff --git a/libpolys/coeffs/AEQ.cc b/libpolys/coeffs/AEQ.cc
new file mode 100644
index 0000000..b1b4e45
--- /dev/null
+++ b/libpolys/coeffs/AEQ.cc
@@ -0,0 +1,921 @@
+#include <misc/auxiliary.h>
+#include <omalloc/omalloc.h>
+
+#include "AEQ.h"
+
+#include <stdio.h>
+#include <math.h>
+#ifdef SINGULAR_4_1
+
+using namespace std;
+
+//Konstruktoren
+
+Q_poly::Q_poly()
+{
+    deg=-1;
+    mpz_init_set_ui(denom,1);
+    mpz_init_set_ui(coef[0],0);
+}
+
+
+
+Q_poly::Q_poly(int n,mpz_t d, mpz_t *a)
+{
+    deg=n;
+
+    mpz_init_set(denom,d);
+
+    for ( int i=0;i<=n;i++)
+    {
+        mpz_init_set(coef[i], a[i]);
+    }
+}
+
+/*
+//Destruktor
+
+Q_poly::~Q_poly()
+{
+        delete[] coef;
+}
+
+*/
+
+// Kürzen  --  MACHT NOCH MIST!
+void Q_poly::Q_poly_reduce()
+{
+    if (is_zero()==1)
+    {
+        mpz_init_set_ui(denom,1);
+    }
+    else
+    {
+        mpz_t d;
+        mpz_init_set(d,denom);
+        int i=0;
+        while (mpz_cmp_ui(d,1)!=0 && i<=deg)
+        {
+            mpz_gcd(d,d,coef[i]);
+            i++;
+        }
+        if (mpz_sgn(denom)==-1)
+        {
+            mpz_neg(d,d);
+        }
+        if (mpz_cmp_ui(d,1)!=0)
+        {
+            mpz_div(denom,denom,d);
+            for (int j=0;j<=deg;j++)
+            {
+                mpz_div(coef[j],coef[j],d);
+            }
+        }
+    }
+    // Grad-Korrektur
+    int j;
+    j=deg;
+    while(mpz_sgn(coef[j])==0 && j>=0)
+    {deg--;j--;}
+}
+
+// Koeffizienten mit b erweitern
+void Q_poly::Q_poly_extend(mpz_t b)
+{
+        mpz_mul(denom,denom,b);
+        for (int i=0;i<=deg;i++)
+        {
+                mpz_mul(coef[i],coef[i],b);
+        }
+}
+
+
+// Arithmetik
+
+
+//Additionen
+
+//Standard - Addition
+void Q_poly::Q_poly_add(const Q_poly a, const Q_poly b)
+{
+    if (a.deg >= b.deg)
+    {
+        deg=a.deg;
+        mpz_t atemp, btemp;
+        mpz_init_set_ui(atemp,0);
+        mpz_init_set_ui(btemp,0);
+
+        for (int i=0;i<=b.deg;i++)
+        {
+                mpz_mul(atemp,a.coef[i],b.denom);
+                mpz_mul(btemp,b.coef[i],a.denom);
+                mpz_add(coef[i],atemp,btemp);
+        }
+
+        for ( int i=b.deg+1;i<=a.deg;i++)
+        {
+            mpz_mul(coef[i],a.coef[i],b.denom);
+        }
+        mpz_mul(denom,a.denom,b.denom);
+
+        // Grad-Korrektur
+        int i=deg;
+        while(mpz_sgn(coef[i])==0 && i>=0)
+        {deg--;i--;}
+    }
+
+    else {Q_poly_add(b,a);}
+
+}
+
+//Überschreibende Addition
+
+void Q_poly::Q_poly_add_to(const Q_poly g)
+{
+    this->Q_poly_add(*this,g);
+}
+
+//Addition einer Konstanten
+void Q_poly::Q_poly_add_const(Q_poly f, const mpz_t a)
+{
+    if (f.is_zero()==1)
+    {
+        Q_poly_set(a,f.denom);
+    }
+    else
+    {
+        Q_poly_set(f);
+        mpz_t atemp;
+        mpz_mul(atemp,a,f.denom);
+        mpz_add(coef[0],coef[0],atemp);
+        // Grad Korrektur
+        if (deg==0 && mpz_sgn(coef[0])==0)
+            Q_poly_set_zero();
+    }
+}
+
+
+//To Variante Addition einer Konstanten
+
+void Q_poly::Q_poly_add_const_to(const mpz_t a)
+{
+    this->Q_poly_add_const(*this,a);
+}
+
+//Monom Addition
+void Q_poly::Q_poly_add_mon(const Q_poly f, mpz_t a, int i)
+{
+    Q_poly_set(f);
+    if (i<=deg  && is_zero()==0)
+    {
+        mpz_t atemp;
+        mpz_init_set_ui(atemp,0);
+        mpz_mul(atemp,a,f.denom);
+        mpz_add(coef[i],coef[i],atemp);
+
+        // Grad Korrektur
+
+        if (deg==i && mpz_sgn(coef[i])==0)
+        {deg--;}
+    }
+    else if (is_zero()==1)
+    {
+        deg=i;
+        for(int j=0;j<i;j++)
+        {
+            mpz_init_set_ui(coef[j],0);
+        }
+        mpz_init_set(coef[i],a);
+        mpz_init_set_ui(denom,1);
+    }
+    else if(i>deg)
+    {
+        deg=i;
+        for(int j=i-1;j>deg;j--)
+        {
+            mpz_init_set_ui(coef[j],0);
+        }
+        mpz_t atemp;
+        mpz_mul(atemp,a,f.denom);
+        mpz_init_set(coef[i],atemp);
+    }
+}
+
+//To Variante Monomaddition
+void Q_poly::Q_poly_add_mon_to(mpz_t a, int i)
+{
+    this->Q_poly_add_mon(*this,a,i);
+}
+
+//Subtraktionen
+
+void Q_poly::Q_poly_sub(const Q_poly a, const Q_poly b)
+{
+    Q_poly temp;
+    temp.Q_poly_set(b);
+    temp.Q_poly_neg();
+    Q_poly_add(a,temp);
+}
+
+
+//Überschreibende Subtraktion
+
+void Q_poly::Q_poly_sub_to(const Q_poly b)
+{
+    this->Q_poly_sub(*this,b);
+}
+
+//Subtraktion einer Konstanten
+void Q_poly::Q_poly_sub_const(Q_poly f,const mpz_t a)
+{
+    if (f.is_zero()==1)
+    {
+        Q_poly_set(a);
+        Q_poly_neg();
+    }
+    else
+    {
+        Q_poly_set(f);
+        mpz_t atemp;
+        mpz_init_set_ui(atemp,1);
+        mpz_mul(atemp,a,f.denom);
+        mpz_sub(coef[0],coef[0],atemp);
+    }
+}
+
+
+//To Variante Subtraktion einer Konstanten
+
+void Q_poly::Q_poly_sub_const_to(const mpz_t a)
+{
+    this->Q_poly_sub_const(*this,a);
+}
+
+
+//Monom Subtraktion
+void Q_poly::Q_poly_sub_mon(const Q_poly f , mpz_t a, int i)
+{
+    mpz_t temp;
+    mpz_init_set_ui(temp,0);
+    mpz_neg(temp,a);
+    Q_poly_add_mon(f,temp,i);
+}
+
+//To Variante Monomsubtraktion
+void Q_poly::Q_poly_sub_mon_to(mpz_t a, int i)
+{
+    this->Q_poly_sub_mon(*this,a,i);
+}
+
+
+//Multiplikationen
+
+//Multiplikation mit Monom
+void Q_poly::Q_poly_mon_mult(const Q_poly f, int n)
+{
+    deg=f.deg+n;
+    mpz_init_set(denom,f.denom);
+    for (int i=deg;i>=n;i--)
+    {
+        mpz_init_set(coef[i],f.coef[i-n]);
+    }
+    for (int i=n-1;i>=0;i--)
+    {
+        mpz_init_set_ui(coef[i],0);
+    }
+}
+
+void Q_poly::Q_poly_mon_mult_to(const int n)
+{
+    this->Q_poly_mon_mult(*this,n);
+}
+
+
+//Multiplikation mit Skalar
+
+void Q_poly::Q_poly_scalar_mult(const Q_poly g, const mpz_t n)
+{
+    deg=g.deg;
+    mpz_init_set(denom,g.denom);
+
+    mpz_t temp;
+    mpz_init_set_ui(temp,0);
+    for(int i=0;i<=deg;i++)
+    {
+        mpz_mul(temp,n,g.coef[i]);
+        mpz_init_set(coef[i],temp);
+    }
+}
+
+
+
+void Q_poly::Q_poly_scalar_mult(const mpz_t n, const Q_poly g)
+{
+    deg=g.deg;
+    mpz_init_set(denom,g.denom);
+
+    mpz_t temp;
+    mpz_init_set_ui(temp,0);
+    for(int i=0;i<=deg;i++)
+    {
+        mpz_mul(temp,n,g.coef[i]);
+        mpz_init_set(coef[i],temp);
+    }
+}
+
+
+void Q_poly::Q_poly_scalar_mult_to(const mpz_t n)
+{
+    this->Q_poly_scalar_mult(*this,n);
+}
+
+
+
+// Negation
+
+void Q_poly::Q_poly_neg()
+{
+    mpz_neg(denom,denom);
+}
+
+// Naive Multiplikation
+void Q_poly::Q_poly_mult_n(Q_poly a,Q_poly b)
+{
+
+    if (a.is_zero()==1 || b.is_zero()==1)
+        Q_poly_set_zero();
+    else
+    {
+        mpz_t temp;
+        mpz_init_set_ui(temp,0);
+        deg = a.deg + b.deg;
+
+        // Kopien atemp und btemp von a bzw. b, mit Nullen aufgefüllt
+        Q_poly atemp, btemp;
+        atemp.Q_poly_set(a);
+        btemp.Q_poly_set(b);
+        for(int i=a.deg+1;i<=deg;i++)
+        {
+            mpz_init_set_ui(atemp.coef[i],0);
+        }
+        for(int i=b.deg+1;i<=deg;i++)
+        {
+            mpz_init_set_ui(btemp.coef[i],0);
+        }
+        atemp.deg = deg;
+        btemp.deg = deg;
+
+        // Multiplikationsalgorithmus
+        for (int k=0; k<=deg; k++)
+        {
+            mpz_init_set_ui(coef[k],0);        // k-ter Koeffizient zunächst 0
+            for (int i=0; i<=k; i++)        // dann schrittweise Summe der a[i]*b[k-i]/
+            {
+                mpz_mul(temp,atemp.coef[i],btemp.coef[k-i]);
+                mpz_add(coef[k],coef[k],temp);
+            }
+        }
+        mpz_mul(denom,a.denom,b.denom);
+    }
+}
+
+//Überschreibende Multiplikation
+
+void Q_poly::Q_poly_mult_n_to(const Q_poly g)
+{
+    this->Q_poly_mult_n(*this,g);
+}
+
+// Karatsuba-Multiplikation (Weimerskirch/Paar Alg. 1), ACHTUNG VORLÄUFIGE VERSION, macht noch Fehler beim Grad und ist unelegant !!!
+void Q_poly::Q_poly_mult_ka(const Q_poly A, const Q_poly B)
+{
+    // Größeren Grad feststellen
+    int n;
+    if(A.deg>=B.deg){n=A.deg+1;}
+    else{n=B.deg+1;}
+    // n auf nächste 2er-Potenz setzen (VORLÄUFIG!)
+    n = static_cast<int>(ceil(log(n)/log(2)));
+    n = static_cast<int>(pow(2,n));
+
+    if (n==1)
+    {
+        mpz_t AB;
+        mpz_mul(AB,A.coef[0],B.coef[0]);
+        Q_poly_set(AB,A.denom);
+    }
+    else
+    {
+        // Q_polynome A und B aufspalten
+        Q_poly Au, Al, Bu, Bl;
+        Au.Q_poly_mon_div(A,n/2);
+        Al.Q_poly_mon_div_rem(A,n/2);
+        Bu.Q_poly_mon_div(B,n/2);
+        Bl.Q_poly_mon_div_rem(B,n/2);
+        Q_poly Alu,Blu;
+        Alu.Q_poly_add(Al,Au);
+        Blu.Q_poly_add(Bl,Bu);
+
+        // Teile rekursiv multiplizieren
+        Q_poly D0, D1, D01;
+        D0.Q_poly_mult_ka(Al,Bl);
+        D1.Q_poly_mult_ka(Au,Bu);
+        D01.Q_poly_mult_ka(Alu,Blu);
+
+        // Ergebnis zusammensetzen
+        Q_poly temp;
+        D01.Q_poly_sub_to(D0);
+        D01.Q_poly_sub_to(D1);
+        D01.Q_poly_mon_mult_to(n/2);
+        D1.Q_poly_mon_mult_to(n);
+        D1.Q_poly_add_to(D01);
+        D1.Q_poly_add_to(D0);
+        Q_poly_set(D1);
+    }
+}
+
+
+
+//Skalare Divisionen
+
+void Q_poly::Q_poly_scalar_div(const Q_poly g, const mpz_t n)
+{
+    if (mpz_sgn(n)!=0) // überprüft Teilung durch 0
+    {
+        Q_poly_set(g);
+        mpz_mul(denom,g.denom,n);
+    }
+}
+
+
+void Q_poly::Q_poly_scalar_div_to(const mpz_t n)
+{
+    this->Q_poly_scalar_div(*this,n);
+}
+
+// Division durch Monom - Quotient
+void Q_poly::Q_poly_mon_div(const Q_poly f, const int n)
+{
+    if (f.deg<n)
+    {
+        Q_poly_set_zero();
+    }
+    else
+    {
+        deg=f.deg-n;
+        mpz_init_set(denom,f.denom);
+
+        for (int i=0;i<=f.deg-n;i++)
+        {
+            mpz_init_set(coef[i],f.coef[n+i]);
+        }
+    }
+}
+
+// Division durch Monom - Rest
+void Q_poly::Q_poly_mon_div_rem(const Q_poly f, const int n)
+{
+    if (f.deg<n)
+    {
+        Q_poly_set(f);
+    }
+    else
+    {
+        // Grad-Korrektur ist inklusive
+        deg=n-1;
+        int j=deg;
+        while(mpz_sgn(f.coef[j])==0 && j>=0)
+        {
+            deg--;
+            j--;
+            mpz_init_set_ui(coef[j],0);
+        }
+        for (int i=j;i>=0;i--)
+        {
+            mpz_init_set(coef[i],f.coef[i]);
+        }
+        mpz_init_set(denom,f.denom);
+    }
+}
+
+
+
+
+// Euklidische Division nach Cohen Algo 3.1.1 (degA muss größer gleich deg B sein)!!
+
+void Q_poly::Q_poly_div_rem(const Q_poly A, const Q_poly B)
+{
+
+    // Initialisierungen: Vergiss zunächst die Hauptnenner von A und B (--> R bzw. Bint)
+    Q_poly temp, Bint;
+    Q_poly_set(A);
+    mpz_init_set_ui(denom,1);
+    Bint.Q_poly_set(B);
+    mpz_init_set_ui(Bint.denom,1);
+    int e = A.deg - B.deg + 1;
+
+    // Algorithmus
+    while (deg>=B.deg)
+    {
+        temp.Q_poly_mon_mult(Bint,deg-B.deg);
+        temp.Q_poly_scalar_mult_to(coef[deg]);
+
+        Q_poly_scalar_mult_to(B.coef[B.deg]);
+        Q_poly_sub_to(temp);
+
+        e--;
+    }
+
+    // Terminierung
+    mpz_t d,q;
+    mpz_init_set(d,B.coef[B.deg]);
+    if (e>0)
+    {
+        mpz_pow_ui(q,d,e);
+        Q_poly_scalar_mult_to(q);
+    }
+    else if (e<0)
+    {
+        mpz_pow_ui(q,d,-e);
+        Q_poly_scalar_div_to(q);
+    }
+
+    mpz_pow_ui(d,d,A.deg-B.deg+1);
+    mpz_mul(denom,denom,d);
+
+    // Hauptnenner von A und B berücksichtigen
+    mpz_mul(denom,denom,A.denom);
+    Q_poly_scalar_mult_to(B.denom);
+}
+
+
+//To Variante von Algo 3.1.1 im Cohen
+
+void Q_poly::Q_poly_div_rem_to(const Q_poly B)
+{
+    this->Q_poly_div_rem(*this,B);
+}
+
+
+// Division nach Cohen 3.1.2 (gibt R und Q aus) --> Führt Pseudo-Division durch, korrigiert den Faktor aber im Nenner
+void Q_poly::Q_poly_div(Q_poly &Q, Q_poly &R, const Q_poly A, const Q_poly B)
+{
+
+    // Initialisierungen: Vergiss zunächst die Hauptnenner von A und B (--> R bzw. Bint)
+    Q_poly temp, Bint;
+    R.Q_poly_set(A);
+    mpz_init_set_ui(R.denom,1);
+    Q.Q_poly_set_zero();
+    Bint.Q_poly_set(B);
+    mpz_init_set_ui(Bint.denom,1);
+    int e = A.deg - B.deg + 1;
+
+    // Algorithmus
+    while (R.deg>=B.deg)
+    {
+        temp.Q_poly_mon_mult(Bint,R.deg-B.deg);
+        temp.Q_poly_scalar_mult_to(R.coef[R.deg]);
+
+        Q.Q_poly_scalar_mult_to(B.coef[B.deg]);
+        Q.Q_poly_add_mon_to(R.coef[R.deg],R.deg-B.deg);
+
+        R.Q_poly_scalar_mult_to(B.coef[B.deg]);
+        R.Q_poly_sub_to(temp);
+
+        e--;
+    }
+
+    // Terminierung
+    mpz_t d,q;
+    mpz_init_set(d,B.coef[B.deg]);
+    if (e>0)
+    {
+        mpz_pow_ui(q,d,e);
+        R.Q_poly_scalar_mult_to(q);
+        Q.Q_poly_scalar_mult_to(q);
+    }
+    else if (e<0)
+    {
+        mpz_pow_ui(q,d,-e);
+        R.Q_poly_scalar_div_to(q);
+        Q.Q_poly_scalar_div_to(q);
+    }
+
+    mpz_pow_ui(d,d,A.deg-B.deg+1);
+    mpz_mul(R.denom,R.denom,d);
+    mpz_mul(Q.denom,Q.denom,d);
+
+    // Hauptnenner von A und B berücksichtigen
+    mpz_mul(R.denom,R.denom,A.denom);
+    mpz_mul(Q.denom,Q.denom,A.denom);
+    R.Q_poly_scalar_mult_to(B.denom);
+    Q.Q_poly_scalar_mult_to(B.denom);
+}
+
+
+//To Variante der exakten Division
+
+void Q_poly::Q_poly_div_to(Q_poly &Q,Q_poly &R,const Q_poly B)
+{
+    this->Q_poly_div(Q,R,*this,B);
+}
+
+
+// Kombinationen
+
+// a := a*b + c
+void Q_poly::Q_poly_multadd_to(const Q_poly b, const Q_poly c)
+{
+    Q_poly_mult_n_to(b);
+    Q_poly_add_to(c);
+}
+
+//a=a*b-c
+void Q_poly::Q_poly_multsub_to(const Q_poly b, const Q_poly c)
+{
+    Q_poly_mult_n_to(b);
+    Q_poly_sub_to(c);
+}
+
+
+
+/*
+// a := (a+b)* c
+void Q_poly::poly_addmult_to(const Q_poly b, const Q_poly c)
+{
+        Q_poly a(deg,coef);
+        a.poly_add_to(b);
+        a.poly_mult_n_to(c);
+        poly_set(a);
+}
+*/
+
+
+
+//Sonstiges
+void Q_poly::Q_poly_horner(mpz_t erg, const mpz_t u)
+{
+    mpz_init_set(erg,coef[deg]);
+    for (int i=deg;i>=1;i--)
+    {
+        mpz_mul(erg,erg,u);
+        mpz_add(erg,erg,coef[i-1]);
+    }
+
+// erg noch durch denom dividieren
+
+}
+
+// Q_polynom in Q_polynom einsetzen(Horner-Schema) KRITISCHE EINGABE x^2, x^2  ....
+
+void Q_poly::Q_poly_horner_Q_poly(const Q_poly A,const Q_poly B)
+{
+    Q_poly_set(A.coef[A.deg],A.denom);
+    for (int i=A.deg;i>=1;i--)
+    {
+        Q_poly_mult_n_to(B);
+        Q_poly_add_const_to(A.coef[i-1]);
+    }
+
+  // Nenner anpassen
+
+}
+
+
+
+//Hilfsfunktionen
+
+
+//setze Q_polynom auf Q_polynom b
+void Q_poly::Q_poly_set(const Q_poly b)
+{
+    deg=b.deg;
+    mpz_init_set(denom,b.denom);
+
+    for(int i=0;i<=deg;i++)
+    {
+        mpz_init_set(coef[i],b.coef[i]); // Hier wird init set dringendst benötigt
+    }
+}
+
+
+// setze Q_polynom auf konstantes Q_polynom b/d
+void Q_poly::Q_poly_set(const mpz_t b, const mpz_t d)
+{
+    deg=0;
+    mpz_init_set(denom,d);
+    mpz_init_set(coef[0],b);
+}
+
+// setze Q_polynom auf konstantes Z_polynom b
+void Q_poly::Q_poly_set(const mpz_t b)
+{
+    deg=0;
+    mpz_init_set_ui(denom,1);
+    mpz_init_set(coef[0],b);
+}
+
+
+//setze Q_polynom auf Nullpolynom
+void Q_poly::Q_poly_set_zero()
+{
+    deg = -1;
+}
+
+
+// Vergleiche ob zwei Q_polynome gleich --> return 1 falls ja sont 0
+
+int Q_poly::is_equal(Q_poly &g)
+{
+    if (deg!=g.deg)
+    {
+      return 0;
+    }
+    else
+    {
+      g.Q_poly_reduce();
+      Q_poly_reduce();
+      for (int i=deg;i>=0; i--)
+      {
+        if (mpz_cmp(coef[i],g.coef[i])!=0)
+          {return 0;}
+      }
+      return 1;
+    }
+}
+
+//Überprüft ob das Q_polynom 0 ist
+int Q_poly::is_zero() const
+{
+    if (deg<0)
+        return 1;
+    else
+        return 0;
+
+}
+
+
+//Überprüft ob das Q_polynom 1 ist
+int Q_poly::is_one() const
+{
+    if (deg==0)
+    {
+        if (mpz_cmp(coef[0],denom)==0) { return 1; }
+        else { return 0; }
+    }
+    else { return 0; }
+}
+
+int Q_poly::is_monic() const
+{
+    if (mpz_cmp(coef[deg],denom)==0)
+        return 1;
+    else
+        return 0;
+}
+
+// klassischer GGT nach Cohen 3.2.1
+
+void Q_poly::Q_poly_gcd(Q_poly A, Q_poly B)
+{
+
+    if (A.deg<B.deg)
+        Q_poly_gcd(B,A);
+    else if (B.is_zero()==1)
+        Q_poly_set(A);
+    else
+    {
+        Q_poly App;
+        Q_poly Bpp;
+        Q_poly R;
+        App.Q_poly_set(A);
+        Bpp.Q_poly_set(B);
+        mpz_init_set_ui(App.denom,1);
+        mpz_init_set_ui(Bpp.denom,1);
+
+        while (Bpp.is_zero()==0)
+        {
+            R.Q_poly_div_rem(App,Bpp);
+            App.Q_poly_set(Bpp);
+            Bpp.Q_poly_set(R);
+        }
+        mpz_init_set(App.denom,App.coef[App.deg]);
+        Q_poly_set(App);
+    }
+}
+
+
+// Nach nach Fieker 2.12 Symbolisches Rechnen (2012) MACHT PROBLEME
+// gibt g=s*A+t*B aus
+void Q_poly::Q_poly_extgcd(Q_poly &s,Q_poly &t,Q_poly &g, Q_poly A, Q_poly B)
+{
+    if (A.deg<B.deg)
+        Q_poly_extgcd(t,s,g,B,A);
+    else if (B.is_zero()==1)
+    {
+        g.Q_poly_set(A);
+        t.Q_poly_set_zero();
+
+        mpz_t temp;
+        mpz_init_set_ui(temp,1);
+        s.Q_poly_set(temp,A.denom);
+    }
+
+    else
+    {
+        mpz_t temp;
+        mpz_init_set_ui(temp,1);
+
+        Q_poly R1;
+        R1.Q_poly_set(A);
+        Q_poly R2;
+        R2.Q_poly_set(B);
+        Q_poly R3;
+
+        Q_poly S1;
+        S1.Q_poly_set(temp,A.denom);
+        Q_poly S2;
+        S2.Q_poly_set_zero();
+        Q_poly S3;
+
+        Q_poly T1;
+        T1.Q_poly_set_zero();
+        Q_poly T2;
+        T2.Q_poly_set(temp,A.denom);
+        Q_poly T3;
+
+        Q_poly Q;
+
+        while (R2.is_zero()!=1)
+        {
+            Q_poly_div(Q,R3,R1,R2);
+
+            S3.Q_poly_mult_n(Q,S2);
+            S3.Q_poly_neg();
+            S3.Q_poly_add_to(S1);
+
+            T3.Q_poly_mult_n(Q,T2);
+            T3.Q_poly_neg();
+            T3.Q_poly_add_to(T1);
+
+            R1.Q_poly_set(R2);
+            R2.Q_poly_set(R3);
+
+            S1.Q_poly_set(S2);
+            S2.Q_poly_set(S3);
+
+            T1.Q_poly_set(T2);
+            T2.Q_poly_set(T3);
+        }
+        t.Q_poly_set(T1);
+        s.Q_poly_set(S1);
+        g.Q_poly_set(R1);
+    }
+}
+
+
+//Ein & Ausgabe
+
+//Eingabe
+
+void Q_poly::Q_poly_insert()
+{
+#if 0
+    cout << "Bitte geben Sie ein Q_polynom ein! Zunächst den Grad: " << endl;
+    cin >> deg;
+    mpz_init_set_ui(denom,1);
+    cout << "Jetzt den Hauptnenner: " << endl;
+    mpz_inp_str(denom,stdin, 10);
+
+    for ( int i=0; i<=deg;i++)
+    {
+        mpz_init_set_ui(coef[i],0);
+        printf("Geben Sie nun f[%i] ein:",i);
+        mpz_inp_str(coef[i],stdin, 10);
+    }
+#endif
+}
+
+
+//Ausgabe
+void Q_poly::Q_poly_print()
+{
+#if 0
+    if (is_zero()==1)
+        cout << "0" << "\n" <<endl;
+    else
+    {
+        printf("(");
+        for (int i=deg;i>=1;i--)
+        {
+            mpz_out_str(stdout,10,coef[i]);
+            printf("X%i+",i);
+        }
+        mpz_out_str(stdout,10,coef[0]);
+        printf(")/");
+        mpz_out_str(stdout,10,denom);
+        printf("\n");
+    }
+#endif
+}
+
+#endif
diff --git a/libpolys/coeffs/AEQ.h b/libpolys/coeffs/AEQ.h
new file mode 100644
index 0000000..3dab062
--- /dev/null
+++ b/libpolys/coeffs/AEQ.h
@@ -0,0 +1,107 @@
+#ifndef QPOLY
+#define QPOLY
+
+#include <misc/auxiliary.h>
+#include "si_gmp.h"
+
+#ifdef SINGULAR_4_1
+
+class Q_poly // Klasse von Q_polynomen mit Typ (Grad, Koeffizienten ganzzahlig)
+{
+
+public:
+    // Charakteristika der Q_polynome (TO DO??: Dynamisches Array)
+
+    int deg;                // Grad des Q_polynoms
+    mpz_t denom;        // Hauptnenner der Koeffizienten
+    mpz_t coef[100];        // Feld der Koeffizienten
+    //mpz_t coef = reinterpret_cast<mpz_t*> (omAlloc(100*sizeof(mpz_t)));
+
+
+    // Konstruktoren und Destruktoren
+    Q_poly();
+    Q_poly( int ,mpz_t, mpz_t*);
+    //Q_poly(int_poly,int);
+    //~Q_poly();
+
+    //Reduktion modulo p
+    void Q_poly_reduce();
+    void Q_poly_extend(mpz_t);
+
+    // Arithmetische Operationen
+
+
+    // Additionen
+
+    void Q_poly_add(const Q_poly , const Q_poly );
+    void Q_poly_add_to(const Q_poly);
+    void Q_poly_add_mon(const Q_poly,mpz_t, int); //addiert Monome zu Q_polynom
+    void Q_poly_add_mon_to(mpz_t,int);
+    void Q_poly_add_const( Q_poly, const mpz_t);
+    void Q_poly_add_const_to(const mpz_t);
+
+    // Subtraktion
+
+    void Q_poly_sub(const Q_poly , const Q_poly );
+    void Q_poly_sub_to(const Q_poly);
+    void Q_poly_sub_mon(const Q_poly,mpz_t,int);
+    void Q_poly_sub_mon_to(mpz_t,int);
+    void Q_poly_sub_const( Q_poly, const mpz_t);
+    void Q_poly_sub_const_to(const mpz_t);
+
+    //Multiplikationen
+
+    void Q_poly_mult_n(Q_poly,Q_poly);
+    void Q_poly_mult_n_to(const Q_poly);
+    void Q_poly_mult_ka(const Q_poly, const Q_poly);
+    void Q_poly_scalar_mult(const mpz_t ,const Q_poly);
+    void Q_poly_scalar_mult(const Q_poly, const mpz_t);
+    void Q_poly_scalar_mult_to(const mpz_t);
+    void Q_poly_neg();
+    void Q_poly_mon_mult(const Q_poly, const int);
+    void Q_poly_mon_mult_to(const int);
+
+    //Divisionen
+    void Q_poly_div(Q_poly&, Q_poly&,const Q_poly, const Q_poly);        // exakte Division
+    void Q_poly_div_to(Q_poly&, Q_poly&,const Q_poly);                       // To Variante exakte Division
+    void Q_poly_scalar_div(const Q_poly, const mpz_t); // Dividiert Polynom durch ganze Zahl
+    void Q_poly_scalar_div_to(const mpz_t);
+    void Q_poly_div_rem(const Q_poly, const Q_poly);        //Division mit Rest
+    void Q_poly_div_rem_to(const Q_poly);
+    void Q_poly_mon_div(const Q_poly, const int);        //Division durch Monom
+    void Q_poly_mon_div_rem(const Q_poly, const int);
+
+    //Kombinationen
+
+    void Q_poly_multadd_to(const Q_poly, const Q_poly); //a=a*b+c
+    void Q_poly_multsub_to(const Q_poly,const Q_poly);  //a=a*b-c
+    //Q_poly Q_poly_addmult_to(const Q_poly, const Q_poly);
+
+
+
+
+    // Sonstige Operationen
+    void Q_poly_set(const Q_poly);
+    void Q_poly_set(const mpz_t);                        // Setzt Q_polynom auf Konstante aus Z
+    void Q_poly_set(const mpz_t, const mpz_t);        // Setzt Q_polynom auf Konstante aus Q
+    void Q_poly_set_zero();                                // Setzt Q_polynom auf 0
+    void Q_poly_horner(mpz_t, const mpz_t);                // Wertet Q_polynom mittels Horner-Schema an einer Stelle aus
+    void Q_poly_horner_Q_poly(Q_poly, const Q_poly);        //Setzt Q_polynom in Q_polynom mittels Horner Schema ein
+    void Q_poly_gcd(Q_poly,Q_poly);                //Standard GGT
+    void Q_poly_extgcd(Q_poly &,Q_poly &,Q_poly &, Q_poly, Q_poly);        //Erweiterter Standard GGT
+    int is_equal(Q_poly &);                        // Test auf Gleichheit
+    int is_zero() const;                                // Test auf Gleichheit mit 0
+    int is_one() const;                                // Test auf Gleichheit mit 1
+    int is_monic() const;                                // testet, ob das Q_polynom normiert ist
+
+    // Ein und Ausgabe
+    void Q_poly_insert();                        // Eingabe von Q_polynom
+    void Q_poly_print();                        //Ausgabe von Q_polynom
+
+
+};
+
+#endif
+#endif
+
+
diff --git a/libpolys/coeffs/AEp.cc b/libpolys/coeffs/AEp.cc
new file mode 100644
index 0000000..696b649
--- /dev/null
+++ b/libpolys/coeffs/AEp.cc
@@ -0,0 +1,1048 @@
+#include <misc/auxiliary.h>
+#include <omalloc/omalloc.h>
+
+#include "AEp.h"
+
+#include <stdio.h>
+#include <math.h>
+#ifdef SINGULAR_4_1
+
+
+using namespace std;
+
+//Konstruktoren
+
+p_poly::p_poly()
+{
+    //coef = reinterpret_cast<mpz_t*> (omAlloc(100*sizeof(mpz_t)));
+    deg=-1;
+    mod=2;
+    mpz_init_set_ui(coef[0],0);
+}
+
+
+
+p_poly::p_poly(int n,int p, mpz_t *a)
+{
+
+    deg=n;
+    mod=p;
+
+    for ( int i=0;i<=n;i++)
+    {
+        mpz_mod_ui(a[i],a[i],mod);
+        mpz_init_set(coef[i], a[i]);
+    }
+
+}
+
+/*
+//Destruktor
+
+p_poly::~p_poly()
+{
+        delete[] coef;
+}
+
+*/
+
+//Reduktion modulo p
+
+void p_poly::p_poly_reduce(p_poly f,int p)
+{
+    if (f.is_zero()==0)
+    {
+
+        for (int i=f.deg;i>=0;i--)
+        {
+            mpz_mod_ui(coef[i],f.coef[i],p);
+        }
+    }
+    //Hier nötige Grad Korrektur
+    int k=deg;
+    while(mpz_sgn(coef[k])==0 && k>=0)
+    {deg--;k--;}
+}
+
+
+// Arithmetik
+
+
+//Additionen
+
+//Standard - Addition
+void p_poly::p_poly_add(const p_poly a, const p_poly b)
+{
+    if (a.deg >=b.deg)
+    {
+
+        deg=a.deg;
+        mod=a.mod;
+
+        for ( int i=0;i<=b.deg;i++)
+        {
+            mpz_add(coef[i],a.coef[i],b.coef[i]);
+        }
+
+        for ( int i=b.deg+1;i<=a.deg;i++)
+        {
+            mpz_init_set(coef[i],a.coef[i]);
+        }
+
+        //Hier nötige Grad Korrektur
+        int k=deg;
+        while(mpz_divisible_ui_p(coef[k],mod)!=0 && k>=0)
+        {deg--;k--;}
+
+
+    }
+
+    else {p_poly_add(b,a);  }
+
+}
+
+//Überschreibende Addition
+
+void p_poly::p_poly_add_to(const p_poly g)
+{
+    this->p_poly_add(*this,g);
+}
+
+//Addition einer Konstanten
+void p_poly::p_poly_add_const(p_poly f,const mpz_t a)
+{
+    if (f.is_zero()==1 && mpz_divisible_ui_p(a,f.mod)==0)
+        p_poly_set(a,f.mod);
+
+    else if (mpz_divisible_ui_p(a,f.mod)==0)
+    {
+        p_poly_set(f);
+        mpz_add(coef[0],coef[0],a);
+        /*/Hier nötige Grad Korrektur
+        int k=deg;
+        while(mpz_divisible_ui_p(coef[k],mod)!=0 && k>=0)
+        {deg--;k--;}
+        */
+    }
+
+}
+
+
+//To Variante Addition einer Konstanten
+
+void p_poly::p_poly_add_const_to(const mpz_t a)
+{
+    this->p_poly_add_const(*this,a);
+}
+
+//Monom Addition
+void p_poly::p_poly_add_mon(const p_poly f, mpz_t a, int i)
+{
+    p_poly_set(f);
+    if (i<=deg  && is_zero()==0)
+    {
+        mpz_add(coef[i],coef[i],a);
+    }
+    else if (is_zero()==1 && mpz_divisible_ui_p(a,f.mod)==0)
+    {
+        deg=i;
+        for(int j=0;j<=i;j++)
+        {
+            mpz_init_set_ui(coef[j],0);
+        }
+        mpz_t temp;
+        mpz_init_set_ui(temp,0);
+        mpz_mod_ui(temp,a,mod);
+        mpz_add(coef[i],coef[i],temp);
+
+    }
+    else if(i>deg && mpz_divisible_ui_p(a,f.mod)==0)
+    {
+        deg=i;
+        for(int j=i;j>deg;j--)
+        {
+            mpz_init_set_ui(coef[j],0);
+        }
+        mpz_t temp;
+        mpz_init_set_ui(temp,0);
+        mpz_mod_ui(temp,a,mod);
+        mpz_add(coef[i],coef[i],temp);
+
+    }
+    /*/Hier nötige Grad Korrektur
+    int k=deg;
+    while(mpz_divisible_ui_p(coef[k],mod)!=0 && k>=0)
+    {deg--;k--;}
+    */
+
+}
+
+//To Variante Monomaddition
+void p_poly::p_poly_add_mon_to(mpz_t a, int i)
+{
+
+    if (i<=deg  && is_zero()==0)
+    {
+        mpz_add(coef[i],coef[i],a);
+    }
+    else if (is_zero()==1 && mpz_divisible_ui_p(a,mod)==0)
+    {
+        deg=i;
+        for(int j=0;j<=i;j++)
+        {
+            mpz_init_set_ui(coef[j],0);
+        }
+        mpz_t temp;
+        mpz_init_set_ui(temp,0);
+        mpz_mod_ui(temp,a,mod);
+        mpz_add(coef[i],coef[i],temp);
+
+    }
+    else if(i>deg && mpz_divisible_ui_p(a,mod)==0)
+    {
+        deg=i;
+        for(int j=i;j>deg;j--)
+        {
+            mpz_init_set_ui(coef[j],0);
+        }
+        mpz_t temp;
+        mpz_init_set_ui(temp,0);
+        mpz_mod_ui(temp,a,mod);
+        mpz_add(coef[i],coef[i],temp);
+
+    }
+    /*Hier nötige Grad Korrektur
+    int k=deg;
+    while(mpz_divisible_ui_p(coef[k],mod)!=0 && k>=0)
+    {deg--;k--;} */
+}
+
+//Subtraktionen
+
+void p_poly::p_poly_sub(const p_poly a, const p_poly b)
+{
+    if (a.deg >=b.deg)
+    {
+
+        deg=a.deg;
+        mod=a.mod;
+
+        for ( int i=0;i<=b.deg;i++)
+        {
+            mpz_sub(coef[i],a.coef[i],b.coef[i]);
+        }
+
+        for ( int i=b.deg+1;i<=a.deg;i++)
+        {
+            mpz_init_set(coef[i],a.coef[i]);
+        }
+
+        //Hier nötige Grad Korrektur
+        int k=deg;
+        while(mpz_divisible_ui_p(coef[k],mod)!=0 && k>=0)
+        {deg--;k--;}
+
+    }
+
+    else {p_poly_sub(b,a);p_poly_neg();  }
+
+}
+
+
+//Überschreibende Subtraktion
+
+void p_poly::p_poly_sub_to(const p_poly b)
+{
+    this->p_poly_sub(*this,b);
+}
+
+//Subtraktion einer Konstanten
+void p_poly::p_poly_sub_const(p_poly f,const mpz_t a)
+{
+    if (f.is_zero()==1)
+    {
+        p_poly_set(a,f.mod);
+        p_poly_neg();
+    }
+    else
+    {
+        p_poly_set(f);
+        mpz_sub(coef[0],coef[0],a);
+    }
+    /*/*Hier nötige Grad Korrektur
+    int k=deg;
+    while(mpz_divisible_ui_p(coef[k],mod)!=0 && k>=0)
+    {deg--;k--;} */
+
+}
+
+
+//To Variante Subtraktion einer Konstanten
+
+void p_poly::p_poly_sub_const_to(const mpz_t a)
+{
+    this->p_poly_sub_const(*this,a);
+}
+
+
+//Monom Subtraktion
+void p_poly::p_poly_sub_mon(const p_poly f , mpz_t a, int i)
+{
+    mpz_t temp;
+    mpz_neg(temp,a);
+    p_poly_add_mon(f,temp,i);
+}
+
+//To Variante Monomaddition
+void p_poly::p_poly_sub_mon_to(mpz_t a, int i)
+{
+    mpz_t temp;
+    mpz_neg(temp,a);
+    p_poly_add_mon_to(temp,i);
+}
+
+
+//Multiplikationen
+
+//Multiplikation mit Monom
+void p_poly::p_poly_mon_mult( p_poly f, int n)
+{
+    if (f.is_zero()==1)
+    {p_poly_set_zero();}
+    else
+    {
+        deg=f.deg+n;
+        mod=f.mod;
+        for (int i=deg;i>=n;i--)
+        {
+            mpz_init_set(coef[i],f.coef[i-n]);
+        }
+        for (int i=n-1;i>=0;i--)
+        {
+            mpz_init_set_ui(coef[i],0);
+        }
+
+        /*/Hier nötige Grad Korrektur
+    int k=deg;
+    while(mpz_divisible_ui_p(coef[k],mod)!=0 && k>=0)
+    {deg--;k--;} */
+    }
+}
+
+void p_poly::p_poly_mon_mult_to(const int n)
+{
+    this->p_poly_mon_mult(*this,n);
+}
+
+
+//Multiplikation mit Skalar
+
+void p_poly::p_poly_scalar_mult(const p_poly g, const mpz_t n)
+{
+    if (mpz_divisible_ui_p(n,g.mod)!=0)
+        p_poly_set_zero();
+    else
+    {
+        deg=g.deg;
+        mod=g.mod;
+
+        mpz_t temp;
+        mpz_init_set_ui(temp,0);
+        for(int i=0;i<=deg;i++)
+        {
+            mpz_mul(temp,n,g.coef[i]);
+            mpz_init_set(coef[i],temp);
+        }
+    }
+}
+
+
+
+void p_poly::p_poly_scalar_mult(const mpz_t n, const p_poly g)
+{
+    if (mpz_divisible_ui_p(n,g.mod)!=0)
+        p_poly_set_zero();
+    else
+    {
+        deg=g.deg;
+        mod=g.mod;
+
+
+        mpz_t temp;
+        mpz_init_set_ui(temp,0);
+        for(int i=0;i<=deg;i++)
+        {
+            mpz_mul(temp,n,g.coef[i]);
+            mpz_init_set(coef[i],temp);
+        }
+        /*/Hier nötige Grad Korrektur
+        int k=deg;
+        while(mpz_divisible_ui_p(coef[k],mod)!=0 && k>=0)
+        {deg--;k--;} */
+    }
+}
+
+
+void p_poly::p_poly_scalar_mult_to(const mpz_t n)
+{
+    this->p_poly_scalar_mult(*this,n);
+}
+
+
+
+// Negation
+
+void p_poly::p_poly_neg()
+{
+    for (int i=0;i<=deg;i++)
+    {
+        mpz_neg(coef[i],coef[i]);
+    }
+}
+
+// Naive Multiplikation
+void p_poly::p_poly_mult_n(p_poly a,p_poly b)
+{
+    //Reduktion mod p
+    a.p_poly_reduce(a,a.mod);
+    b.p_poly_reduce(b,b.mod);
+
+    if (a.is_zero()==1 || b.is_zero()==1)
+        p_poly_set_zero();
+    else
+    {
+        mpz_t temp;
+        mpz_init_set_ui(temp,0);
+        deg = a.deg + b.deg;
+
+        // Kopien atemp und btemp von a bzw. b, mit Nullen aufgefüllt
+        p_poly atemp, btemp;
+        atemp.p_poly_set(a);
+        btemp.p_poly_set(b);
+        for(int i=a.deg+1;i<=deg;i++)
+        {
+            mpz_init_set_ui(atemp.coef[i],0);
+        }
+        for(int i=b.deg+1;i<=deg;i++)
+        {
+            mpz_init_set_ui(btemp.coef[i],0);
+        }
+        atemp.deg = deg;
+        btemp.deg = deg;
+
+        // Multiplikationsalgorithmus
+        for (int k=0; k<=deg; k++)
+        {
+            mpz_init_set_ui(coef[k],0);        // k-ter Koeffizient zunächst 0
+            for (int i=0; i<=k; i++)        // dann schrittweise Summe der a[i]*b[k-i]/
+            {
+                mpz_mul(temp,atemp.coef[i],btemp.coef[k-i]);
+                mpz_add(coef[k],coef[k],temp);
+            }
+        }
+
+        /*/Hier nötige Grad Korrektur
+        int k=deg;
+        while(mpz_divisible_ui_p(coef[k],mod)!=0 && k>=0)
+        {deg--;k--;} */
+
+
+    }
+}
+
+
+//Überschreibende Multiplikation
+
+void p_poly::p_poly_mult_n_to(const p_poly g)
+{
+    this->p_poly_mult_n(*this,g);
+
+}
+
+// Karatsuba-Multiplikation (Weimerskirch/Paar Alg. 1), ACHTUNG VORLÄUFIGE VERSION, macht noch Fehler beim Grad und ist unelegant !!!
+void p_poly::p_poly_mult_ka( p_poly A,  p_poly B)
+{
+
+    if (A.is_zero()==1 || B.is_zero()==1)
+    {
+        p_poly_set_zero();
+    }
+    else
+    {
+        //Reduktion mod p
+        A.p_poly_reduce(A,A.mod);
+        B.p_poly_reduce(B,B.mod);
+
+        // Größeren Grad feststellen
+        int n;
+        if(A.deg>=B.deg){n=A.deg+1;}
+        else{n=B.deg+1;}
+        // n auf nächste 2er-Potenz setzen (VORLÄUFIG!)
+        n = static_cast<int>(ceil(log(n)/log(2)));
+        n = static_cast<int>(pow(2,n));
+
+        if (n==1)
+        {
+            mpz_t AB;
+            mpz_mul(AB,A.coef[0],B.coef[0]);
+            p_poly_set(AB,A.mod);
+            this->p_poly_reduce(*this,A.mod);
+        }
+        else
+        {
+            // p_polynome A und B aufspalten
+            p_poly Au, Al, Bu, Bl;
+            Au.p_poly_mon_div(A,n/2);
+            Al.p_poly_mon_div_rem(A,n/2);
+            Bu.p_poly_mon_div(B,n/2);
+            Bl.p_poly_mon_div_rem(B,n/2);
+            p_poly Alu,Blu;
+            Alu.p_poly_add(Al,Au);
+            Blu.p_poly_add(Bl,Bu);
+
+            // Teile rekursiv multiplizieren
+            p_poly D0, D1, D01;
+            D0.p_poly_mult_ka(Al,Bl);
+            D1.p_poly_mult_ka(Au,Bu);
+            D01.p_poly_mult_ka(Alu,Blu);
+
+            // Ergebnis zusammensetzen
+            p_poly temp;
+            D01.p_poly_sub_to(D0);
+            D01.p_poly_sub_to(D1);
+            D01.p_poly_mon_mult_to(n/2);
+            D1.p_poly_mon_mult_to(n);
+            D1.p_poly_add_to(D01);
+            D1.p_poly_add_to(D0);
+            p_poly_set(D1);
+
+        }
+
+        //Hier nötige Grad Korrektur
+        int k=deg;
+        while(mpz_divisible_ui_p(coef[k],mod)!=0 && k>=0)
+        {deg--;k--;}
+    }
+}
+
+
+
+//Skalare Divisionen
+
+void p_poly::p_poly_scalar_div( const p_poly g, const mpz_t n)
+{
+
+    if (mpz_divisible_ui_p(n,g.mod)==0) // überprüft invertierbarkeit
+    {
+        deg=g.deg;
+        mod=g.mod;
+
+
+        mpz_t temp;
+        mpz_t p;
+        mpz_init_set_ui(temp,0);
+        mpz_init_set_ui(p,mod);
+        for(int i=0;i<=deg;i++)
+        {
+            mpz_invert(temp,n,p);
+            mpz_mul(temp,g.coef[i],temp);
+            mpz_init_set(coef[i],temp);
+        }
+
+        /*/Hier nötige Grad Korrektur
+        int k=deg;
+        while(mpz_divisible_ui_p(coef[k],mod)!=0 && k>=0)
+        {deg--;k--;} */
+    }
+}
+
+
+void p_poly::p_poly_scalar_div_to(const mpz_t n)
+{
+    this->p_poly_scalar_div(*this,n);
+}
+
+// Division durch Monom - Quotient
+void p_poly::p_poly_mon_div(const p_poly f, const int n)
+{
+    if (f.deg<n)
+    {
+        p_poly_set_zero();
+    }
+    else
+    {
+        deg=f.deg-n;
+        mod=f.mod;
+
+        for (int i=0;i<=f.deg-n;i++)
+        {
+            mpz_init_set(coef[i],f.coef[n+i]);
+        }
+    }
+}
+
+// Division durch Monom - Rest
+void p_poly::p_poly_mon_div_rem(const p_poly f, const int n)
+{
+    if (f.deg<n)
+    {
+        p_poly_set(f);
+    }
+    else
+    {
+        deg=n-1;
+        mod=f.mod;
+
+
+        for (int i=0;i<=n-1;i++)
+        {
+            mpz_init_set(coef[i],f.coef[i]);
+        }
+    }
+}
+
+
+
+
+//Euklidische Division nach Cohen Algo 3.1.1 (degA muss größer gleich deg B sein)!!
+
+void p_poly::p_poly_div_rem( p_poly A,  p_poly B)
+{
+
+    if (B.is_zero()==0)
+    {
+        //Reduktion mod p
+        A.p_poly_reduce(A,A.mod);
+        B.p_poly_reduce(B,B.mod);
+
+        p_poly R;
+        p_poly temp;
+        R.p_poly_set(A);
+        mpz_t a;
+        mpz_t u;
+        mpz_t p;
+        mpz_init_set_ui(p,A.mod);
+        mpz_init_set_ui(a,0);
+        mpz_init_set_ui(u,0);
+        int i;
+
+        mpz_invert(u,B.coef[B.deg],p); // Inverse von lc(B)
+
+
+        while (R.deg>=B.deg)
+        {
+
+            mpz_mul(a,R.coef[R.deg],u);
+            i=R.deg-B.deg;
+
+            temp.p_poly_mon_mult(B,i);
+            temp.p_poly_scalar_mult_to(a);
+
+            R.p_poly_sub_to(temp);
+
+        }
+        p_poly_set(R);
+
+        /*/Hier nötige Grad Korrektur
+    int k=deg;
+    while(mpz_divisible_ui_p(coef[k],mod)!=0 && k>=0)
+    {deg--;k--;}*/
+    }
+}
+//To Variante von Algo 3.1.1 im Cohen
+
+void p_poly::p_poly_div_rem_to(const p_poly B)
+{
+    this->p_poly_div_rem(*this,B);
+
+
+}
+
+
+
+//Exakte Division nach Cohen 3.1.1
+void p_poly::p_poly_div(p_poly &Q, p_poly &R, p_poly A,  p_poly B)
+{
+    if (B.is_zero()==0)
+    {
+        //Reduktion mod p
+        A.p_poly_reduce(A,A.mod);
+        B.p_poly_reduce(B,B.mod);
+
+        //Initialisierungen
+        p_poly temp;
+        R.p_poly_set(A);
+        Q.p_poly_set_zero();
+        Q.mod=A.mod;
+
+        mpz_t a;
+        mpz_t b;
+        mpz_t p;
+        mpz_init_set_ui(p,A.mod);
+        mpz_init_set_ui(a,0);
+        mpz_init_set_ui(b,0);
+        int i;
+        mpz_invert(b,B.coef[B.deg],p);
+
+        //Algorithmus TO DO: evtl hier mit auch den Rest ausgeben
+        while (R.deg>=B.deg)
+        {
+
+            mpz_mul(a,R.coef[R.deg],b);
+            i=R.deg-B.deg;
+
+            temp.p_poly_mon_mult(B,i);
+            temp.p_poly_scalar_mult_to(a);
+
+            R.p_poly_sub_to(temp);
+
+            Q.p_poly_add_mon_to(a,i);
+
+            R.p_poly_reduce(R,R.mod);
+            Q.p_poly_reduce(Q,Q.mod);
+        }
+
+        /*/Hier nötige Grad Korrektur Q
+    int k=Q.deg;
+    while(mpz_divisible_ui_p(Q.coef[k],Q.mod)!=0 && k>=0)
+    {Q.deg--;k--;}*/
+
+        /*/Hier nötige Grad Korrektur R
+    k=R.deg;
+    while(mpz_divisible_ui_p(R.coef[k],R.mod)!=0 && k>=0)
+    {R.deg--;k--;} */
+    }
+}
+
+
+//To Varainte der exakten Division
+
+void p_poly::p_poly_div_to(p_poly &Q,p_poly &R, p_poly B)
+{
+    this->p_poly_div(Q ,R,*this,B);
+}
+
+
+// Kombinationen
+
+// a := a*b + c
+void p_poly::p_poly_multadd_to(const p_poly b, const p_poly c)
+{
+    p_poly_mult_n_to(b);
+    p_poly_add_to(c);
+}
+
+//a=a*b-c
+void p_poly::p_poly_multsub_to(const p_poly b, const p_poly c)
+{
+    p_poly_mult_n_to(b);
+    p_poly_sub_to(c);
+}
+
+
+
+/*
+// a := (a+b)* c
+void p_poly::poly_addmult_to(const p_poly b, const p_poly c)
+{
+        p_poly a(deg,coef);
+        a.poly_add_to(b);
+        a.poly_mult_n_to(c);
+        poly_set(a);
+}
+*/
+
+
+
+//Sonstiges
+void p_poly::p_poly_horner(mpz_t erg, const mpz_t u)
+{
+    if (is_zero()==0)
+    {
+        mpz_init_set(erg,coef[deg]);
+        for (int i=deg;i>=1;i--)
+        {
+            mpz_mul(erg,erg,u);
+            mpz_add(erg,erg,coef[i-1]);
+        }
+
+        //Reduktion
+        mpz_mod_ui(erg,erg,mod);
+    }
+    else
+    {
+        mpz_set_ui(erg,0);
+    }
+}
+
+// p_polynom in p_polynom einsetzen(Horner-Schema) KRITISCHE EINGABE x^2, x^2  ....
+
+void p_poly::p_poly_horner_p_poly( p_poly A, p_poly B)
+{
+    //Reduktion mod p
+    A.p_poly_reduce(A,A.mod);
+    B.p_poly_reduce(B,B.mod);
+
+    p_poly_set(A.coef[A.deg],A.mod);
+    for (int i=A.deg;i>=1;i--)
+    {
+        p_poly_mult_n_to(B);
+        p_poly_add_const_to(A.coef[i-1]);
+    }
+    /*/Hier nötige Grad Korrektur
+    int i=deg;
+    while(mpz_divisible_ui_p(coef[i],mod)!=0 && i>=0)
+    {deg--;i--;} */
+}
+
+
+
+//Hilfsfunktionen
+
+
+//setze p_polynom auf p_polynom b
+void p_poly::p_poly_set(const p_poly b)
+{
+    deg=b.deg;
+    mod=b.mod;
+
+
+    for(int i=0;i<=deg;i++)
+    {
+        mpz_init_set(coef[i],b.coef[i]); // Hier wird init set dringendst benötigt
+    }
+
+}
+
+// setze p_polynom auf konstantes p_polynom b
+void p_poly::p_poly_set(const mpz_t b,int p)
+{
+    deg=0;
+    mod=p;
+
+    if (mpz_divisible_ui_p(b,mod)!=0)
+        p_poly_set_zero();
+    else
+    {
+        mpz_t temp;
+        mpz_init_set(temp,b);
+        mpz_mod_ui(temp,temp,p);
+        mpz_init_set(coef[0],b);
+    }
+}
+
+
+//setze p_polynom auf Nullpolynom
+void p_poly::p_poly_set_zero()
+{
+    deg = -1;
+}
+
+
+//Vergleiche ob 2 p_polynome gleich return 1 falls ja sont 0
+
+int p_poly::is_equal(const p_poly g) const
+{
+    if (deg!=g.deg)
+        return 0;
+    else
+
+        for (int i=deg;i>=0; i--)
+        {
+        if (mpz_cmp(coef[i],g.coef[i])!=0)
+        {return 0;}
+    }
+    return 1;
+}
+
+//Überprüft ob das p_polynom 0 ist
+
+int p_poly::is_zero() const
+{
+    if (deg<0)
+        return 1;
+    else
+        return 0;
+
+}
+
+int p_poly::is_one() const
+{
+    if (deg==0)
+    {
+        if (mpz_cmp_ui(coef[0],1)==0) { return 1; }
+        else { return 0; }
+    }
+    else { return 0; }
+}
+
+int p_poly::is_monic() const
+{
+    if (mpz_cmpabs_ui(coef[deg],1)==0)
+        return 1;
+    else
+        return 0;
+}
+
+// klassischer GGT nach Cohen 3.2.1
+
+void p_poly::p_poly_gcd( p_poly A,  p_poly B)
+{
+
+    //Reduktion mod p
+    A.p_poly_reduce(A,A.mod);
+    B.p_poly_reduce(B,B.mod);
+
+    if (A.deg<B.deg)
+        p_poly_gcd(B,A);
+    else if (B.is_zero()==1)
+        p_poly_set(A);
+    else
+    {
+        p_poly App;
+        p_poly Bpp;
+        p_poly R;
+        App.p_poly_set(A);
+        Bpp.p_poly_set(B);
+
+        while (Bpp.is_zero()==0)
+        {
+            R.p_poly_div_rem(App,Bpp);
+            App.p_poly_set(Bpp);
+            Bpp.p_poly_set(R);
+        }
+        p_poly_set(App);
+    }
+
+}
+
+//Nach nach Fieker 2.12 Symbolisches Rechnen (2012)
+// gibt g=s*A+t*B aus
+void p_poly::p_poly_extgcd(p_poly &s,p_poly &t,p_poly &g, p_poly A, p_poly B)
+{
+
+    //Reduktion mod p
+    A.p_poly_reduce(A,A.mod);
+    B.p_poly_reduce(B,B.mod);
+
+
+    if (A.deg<B.deg)
+        p_poly_extgcd(t,s,g,B,A);
+    else if (B.is_zero()==1)
+    {
+        g.p_poly_set(A);
+        t.p_poly_set_zero();
+
+        mpz_t temp;
+        mpz_init_set_ui(temp,1);
+        s.p_poly_set(temp,A.mod);
+    }
+
+    else
+    {
+        mpz_t temp;
+        mpz_init_set_ui(temp,1);
+
+        p_poly R1;
+        R1.p_poly_set(A);
+        p_poly R2;
+        R2.p_poly_set(B);
+        p_poly R3;
+        R3.mod=A.mod;
+
+
+        p_poly S1;
+        S1.p_poly_set(temp,A.mod);
+        p_poly S2;
+        S2.p_poly_set_zero();
+        S2.mod=A.mod;
+        p_poly S3;
+        S3.mod=A.mod;
+
+        p_poly T1;
+        T1.p_poly_set_zero();
+        T1.mod=A.mod;
+        p_poly T2;
+        T2.p_poly_set(temp,A.mod);
+        p_poly T3;
+        T3.mod=A.mod;
+
+        p_poly Q;
+
+        while (R2.is_zero()!=1)
+        {
+            p_poly_div(Q,R3,R1,R2);
+
+            S3.p_poly_mult_n(Q,S2);
+            S3.p_poly_neg();
+            S3.p_poly_add_to(S1);
+
+            T3.p_poly_mult_n(Q,T2);
+            T3.p_poly_neg();
+            T3.p_poly_add_to(T1);
+
+            R1.p_poly_set(R2);
+            R2.p_poly_set(R3);
+
+            S1.p_poly_set(S2);
+            S2.p_poly_set(S3);
+
+            T1.p_poly_set(T2);
+            T2.p_poly_set(T3);
+        }
+        t.p_poly_set(T1);
+        s.p_poly_set(S1);
+        g.p_poly_set(R1);
+    }
+}
+
+
+//Ein & Ausgabe
+
+//Eingabe
+
+void p_poly::p_poly_insert()
+{
+#if 0
+    cout << "Bitte geben Sie ein p_polynom ein! Zunächst den Grad: " << endl;
+    cin >> deg;
+    cout << "Jetzt den modul: " << endl;
+    cin >> mod;
+
+    for ( int i=0; i<=deg;i++)
+    {
+        mpz_init_set_ui(coef[i],0);
+        printf("Geben Sie nun f[%i] ein:",i);
+        mpz_inp_str(coef[i],stdin, 10);
+    }
+    //Reduktion
+    this->p_poly_reduce(*this,mod);
+#endif
+}
+
+
+//Ausgabe
+void p_poly::p_poly_print()
+{
+#if 0
+
+    //Reduktion
+    this->p_poly_reduce(*this,mod);
+
+
+    if (is_zero()==1)
+        cout << "0" << "\n" <<endl;
+    else
+    {
+        for (int i=deg;i>=1;i--)
+        {
+            mpz_out_str(stdout,10, coef[i]);
+            printf("X%i+",i);
+        }
+        mpz_out_str(stdout,10, coef[0]);
+        printf("\n");
+    }
+#endif
+}
+
+#endif
diff --git a/libpolys/coeffs/AEp.h b/libpolys/coeffs/AEp.h
new file mode 100644
index 0000000..d317b96
--- /dev/null
+++ b/libpolys/coeffs/AEp.h
@@ -0,0 +1,103 @@
+#ifndef AEP_H
+#define AEP_H
+
+#include <misc/auxiliary.h>
+#include "si_gmp.h"
+
+#ifdef SINGULAR_4_1
+
+class p_poly // Klasse von p_polynomen mit Typ (Grad, Koeffizienten ganzzahlig)
+{
+
+public:
+    // Charakteristika der p_polynome (TO DO??: Dynamisches Array)
+
+    int deg;                // Grad des p_polynoms
+    int mod;                // Primzahl (Modul??)
+    mpz_t coef[100];        // Feld der Koeffizienten
+    //mpz_t coef = reinterpret_cast<mpz_t*> (omAlloc(100*sizeof(mpz_t)));
+
+
+    // Konstruktoren und Destruktoren
+    p_poly();
+    p_poly( int ,int, mpz_t*);
+    //p_poly(int_poly,int);
+    //~p_poly();
+
+    //Reduktion modulo p
+    void p_poly_reduce(p_poly, int);
+
+    // Arithmetische Operationen
+
+
+    // Additionen
+
+    void p_poly_add(const p_poly , const p_poly );
+    void p_poly_add_to(const p_poly);
+    void p_poly_add_mon(const p_poly,mpz_t, int); //addiert Monome zu p_polynom
+    void p_poly_add_mon_to(mpz_t,int);
+    void p_poly_add_const( p_poly, const mpz_t);
+    void p_poly_add_const_to(const mpz_t);
+
+    // Subtraktion
+
+    void p_poly_sub(const p_poly , const p_poly );
+    void p_poly_sub_to(const p_poly);
+    void p_poly_sub_mon(const p_poly,mpz_t,int);
+    void p_poly_sub_mon_to(mpz_t,int);
+    void p_poly_sub_const( p_poly, const mpz_t);
+    void p_poly_sub_const_to(const mpz_t);
+
+    //Multiplikationen
+
+    void p_poly_mult_n(p_poly,p_poly);
+    void p_poly_mult_n_to(const p_poly);
+    void p_poly_mult_ka( p_poly, p_poly);
+    void p_poly_scalar_mult(const mpz_t ,const p_poly);
+    void p_poly_scalar_mult(const p_poly, const mpz_t);
+    void p_poly_scalar_mult_to(const mpz_t);
+    void p_poly_neg();
+    void p_poly_mon_mult( p_poly, const int);
+    void p_poly_mon_mult_to(const int);
+
+    //Divisionen
+    void p_poly_div(p_poly&, p_poly&, p_poly,  p_poly); // exakte Division
+    void p_poly_div_to(p_poly&, p_poly&, p_poly);       // To Variante exakte Division
+    void p_poly_scalar_div(const p_poly, const mpz_t n); // Multipliziert konstante an Polynom
+    void p_poly_scalar_div_to(const mpz_t n);
+    void p_poly_div_rem( p_poly, p_poly);//Division mit Rest
+    void p_poly_div_rem_to( p_poly);
+    void p_poly_mon_div(const p_poly, const int); //Division durch MOnom
+    void p_poly_mon_div_rem(const p_poly, const int);
+
+    //Kombinationen
+
+    void p_poly_multadd_to(const p_poly, const p_poly); //a=a*b+c
+    void p_poly_multsub_to(const p_poly,const p_poly);  //a=a*b-c
+    //p_poly p_poly_addmult_to(const p_poly, const p_poly);
+
+
+
+
+    // Sonstige Operationen
+    void p_poly_set(const p_poly);
+    void p_poly_set(const mpz_t,int);                // Setzt p_polynom auf Konstante
+    void p_poly_set_zero();                        // Setzt p_polynom auf 0
+    void p_poly_horner(mpz_t, const mpz_t);        // Wertet p_polynom mittels Horner-Schema an einer Stelle aus
+    void p_poly_horner_p_poly(p_poly, p_poly);        //Setzt p_polynom in p_polynom mittels Horner Schema ein
+    void p_poly_gcd(p_poly,p_poly);                //Standard GGT
+    void p_poly_extgcd(p_poly &,p_poly &,p_poly &, p_poly, p_poly);        //Erweiterter Standard GGT
+    int is_equal(const p_poly) const;                // Test auf Gleichheit
+    int is_zero() const;                                // Test auf Gleichheit mit 0
+    int is_one() const;                                // Test auf Gleichheit mit 1
+    int is_monic() const;                                // testet, ob das p_polynom normiert ist
+
+    // Ein und Ausgabe
+    void p_poly_insert();                        // Eingabe von p_polynom
+    void p_poly_print();                        //Ausgabe von p_polynom
+};
+
+#endif
+#endif
+
+
diff --git a/libpolys/coeffs/Enumerator.h b/libpolys/coeffs/Enumerator.h
new file mode 100644
index 0000000..97a4f5d
--- /dev/null
+++ b/libpolys/coeffs/Enumerator.h
@@ -0,0 +1,230 @@
+// -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+/*****************************************************************************\
+ * Computer Algebra System SINGULAR
+\*****************************************************************************/
+/** @file Enumerator.h
+ *
+ * Abstract API for enumerators.
+ *
+ * ABSTRACT: Abstract interface for forward iteratable containers (enumerators)
+ * of standalone objects (e.g. polynomials as sets of numbers), without any
+ * knowledge of their internals.
+ *
+ * @author Oleksandr Motsak
+ *
+ *
+ **/
+/*****************************************************************************/
+
+#ifndef ENUMERATOR_H
+#define ENUMERATOR_H
+
+/** @class IBaseEnumerator
+ *
+ * Base enumerator interface for simple iteration over a generic collection.
+ *
+ * Abstract API of enumerators for enumerable collections of standalone objects.
+ * Just like IEnumerator from C#. Usage pattern can be as follows:
+ *
+ * @code
+ *   IBaseEnumerator& itr = ...;
+ *   itr.Reset(); // goes to the "-1" element
+ *   // NOTE: itr is not useable here!
+ *   while( itr.MoveNext() )
+ *   {
+ *      do something custom with itr...
+ *   }
+ * @endcode
+ *
+ * Note that the Reset()
+ *
+ * @sa IEnumerator
+ */
+class IBaseEnumerator // IDisposable
+{
+  public:
+    /// Advances the enumerator to the next element of the collection.
+    /// returns true if the enumerator was successfully advanced to the
+    /// next element;
+    /// false if the enumerator has passed the end of the collection.
+    virtual bool MoveNext() = 0;
+
+    /// Sets the enumerator to its initial position: -1,
+    /// which is before the first element in the collection.
+    virtual void Reset() = 0;
+
+    /// Current position is inside the collection (not -1 or past the end)
+    virtual bool IsValid() const = 0;
+
+  private:
+    /// disable copy constructor and assigment operator
+    IBaseEnumerator(const IBaseEnumerator&);
+    void operator=(const IBaseEnumerator&);
+
+  protected:
+    IBaseEnumerator(){}
+    ~IBaseEnumerator() {} // TODO: needed?
+
+
+};
+
+
+/** @class IAccessor
+ *
+ * Templated accessor interface for accessing individual data (for instance, of an enumerator).
+ *
+ * T is the type of objects to access, available via the Current() method.
+ *
+ * @sa IBaseEnumerator
+ */
+template <typename T>
+class IAccessor // IDisposable
+{
+  public:
+    typedef T value_type;
+    typedef value_type& reference;
+    typedef const value_type& const_reference;
+
+    /// Gets the current element in the collection (read and write).
+    virtual reference Current() = 0;
+
+    /// Gets the current element in the collection (read only).
+    virtual const_reference Current() const = 0;
+
+ protected:
+    IAccessor(){}
+    ~IAccessor() {} // TODO: needed?
+
+};
+
+/** @class IEnumerator
+ *
+ * Templated enumerator interface for simple iteration over a generic collection of T's.
+ *
+ * Abstract API of enumerators for generic enumerable collections of standalone
+ * objects of type T. Inspired by IEnumerator from C#. Usage parrten can be as
+ * follows:
+ *
+ * @code
+ *   IEnumerator<T>& itr = ...;
+ *
+ *   itr.Reset(); // goes before the first element, thus no itr.Current() is available here!
+ *
+ *   while( itr.MoveNext() )
+ *   {
+ *      use/change itr.Current()...
+ *   }
+ * @endcode
+ *
+ * T is the type of objects to enumerate, available via Current() method
+ *
+ * @sa IBaseEnumerator
+ */
+template <typename T>
+class IEnumerator: public virtual IBaseEnumerator, public virtual IAccessor<T>
+{
+  public:
+};
+
+#if 0
+// the following is not used for now //
+// the following is not used for now //
+// the following is not used for now //
+// the following is not used for now //
+// the following is not used for now //
+
+// include basic definitions
+//??// #include <iterator>
+
+/** @class IBaseIterator
+ *
+ * A base abstract iterator API with virtualized standard iterator operators
+ *
+ * Abstract API for iterators that should work with STL and BOOST.
+ *
+ * @sa STL iterators
+ */
+template <class A>
+class IBaseIterator //??// : public std::iterator<std::forward_iterator_tag, A>
+{
+  public:
+    typedef IBaseIterator<A> self;
+    typedef self& self_reference;
+    typedef const self_reference const_self_reference;
+
+    virtual bool operator==(const_self_reference rhs) = 0;
+
+    /// ++itr, goes to the next state, returns the new state
+    virtual self_reference operator++() = 0;
+
+    /// itr++, goes to the next state, returns the previous state
+    virtual self_reference operator++(int) = 0;
+
+    virtual A& operator*() = 0;
+    virtual A* operator->() = 0;
+
+    inline bool operator!=(const_self_reference rhs){ return !((*this) == rhs); }
+};
+
+/** @class AIterator
+ *
+ * An abstract iterator with virtualized assigment operator and
+ * constructors.
+ *
+ * Abstract API for iterators that should work with STL and BOOST.
+ *
+ * @sa STL iterators
+ */
+template <class A>
+class IIterator: public IBaseIterator<A>
+{
+  public:
+    typedef IIterator<A> self;
+    typedef self& self_reference;
+    typedef const self_reference const_self_reference;
+
+    IIterator(){ void_constructor(); }
+
+    IIterator(const_self_reference itr) { copy_constructor(itr); }
+
+    virtual self_reference operator=(const_self_reference other) = 0;
+
+  private:
+    virtual void void_constructor() = 0;
+    virtual void copy_constructor(const_self_reference itr) = 0;
+};
+
+/** @class IContainer
+ *
+ * Container of standalone objects
+ *
+ * Abstract API for containers of objects and their iterators
+ *
+ * @sa STL containers and iterators
+ */
+template <class T>
+class IContainer
+{
+  public:
+    typedef T value_type;
+    typedef value_type& reference;
+    typedef const value_type& const_reference;
+//??//    typedef std::size_t size_type;
+//??//    virtual size_type size() const = 0;
+    virtual bool empty() const = 0;
+
+    typedef IIterator<reference> iterator;
+    virtual iterator begin() = 0;
+    virtual iterator end() = 0;
+
+    typedef IIterator<const_reference> const_iterator;
+    virtual const_iterator begin() const = 0;
+    virtual const_iterator end() const = 0;
+};
+#endif
+
+
+#endif
+/* #ifndef ENUMERATOR_H */
+
+// Vi-modeline: vim: filetype=c:syntax:shiftwidth=2:tabstop=8:textwidth=0:expandtab
diff --git a/libpolys/coeffs/Makefile.am b/libpolys/coeffs/Makefile.am
new file mode 100644
index 0000000..c9ef25f
--- /dev/null
+++ b/libpolys/coeffs/Makefile.am
@@ -0,0 +1,40 @@
+ACLOCAL_AMFLAGS = -I ../../m4
+
+AM_CPPFLAGS = -I${top_srcdir} -I${top_builddir} \
+$(FACTORY_INCLUDES) $(OMALLOC_INCLUDES) $(RESOURCES_INCLUDES) \
+${NTL_CFLAGS} $(FLINT_CFLAGS) ${GMP_CFLAGS}
+
+# noinst???
+noinst_LTLIBRARIES = libcoeffs.la
+###### libcoeffsdir = $(libdir)/singular
+# noinst_HEADERS= \
+#	gnumpc.h gnumpfl.h longrat.h modulop.h ffields.h \
+#	rintegers.h rmodulo2m.h rmodulon.h shortfl.h \
+#	mpr_complex.h mpr_global.h
+
+SOURCES = \
+  numbers.cc rintegers.cc rmodulo2m.cc rmodulon.cc shortfl.cc \
+  gnumpc.cc gnumpfl.cc longrat.cc longrat0.cc ffields.cc \
+  modulop.cc mpr_complex.cc \
+  bigintmat.cc  AE.cc OPAE.cc AEp.cc OPAEp.cc AEQ.cc OPAEQ.cc
+
+libcoeffs_la_SOURCES   = $(SOURCES)
+
+libcoeffs_la_includedir  =$(includedir)/singular/coeffs
+libcoeffs_la_include_HEADERS = \
+  coeffs.h numbers.h si_gmp.h gnumpc.h gnumpfl.h longrat.h modulop.h ffields.h rintegers.h rmodulo2m.h rmodulon.h \
+  shortfl.h mpr_complex.h mpr_global.h numstats.h \
+  bigintmat.h Enumerator.h AE.h OPAE.h AEp.h OPAEp.h AEQ.h OPAEQ.h
+
+libcoeffs_la_LIBADD = ${top_builddir}/reporter/libreporter.la ${top_builddir}/misc/libmisc.la \
+$(FACTORY_LIBS) $(RESOURCES_LIBS) $(OMALLOC_LIBS) \
+$(FLINT_LIBS) $(GMP_LIBS) $(NTL_LIBS)
+
+TESTS_ENVIRONMENT = SINGULARPATH='${top_srcdir}/../factory:${top_builddir}/../factory'
+TESTS_ENVIRONMENT += SINGULAR_ROOT_DIR='$(top_builddir)'
+
+TESTS = test
+check_PROGRAMS = $(TESTS)
+
+test_SOURCES = test.cc
+test_LDADD   = libcoeffs.la $(libcoeffs_la_LIBADD)
diff --git a/libpolys/coeffs/Makefile.in b/libpolys/coeffs/Makefile.in
new file mode 100644
index 0000000..c0ad91e
--- /dev/null
+++ b/libpolys/coeffs/Makefile.in
@@ -0,0 +1,1104 @@
+# Makefile.in generated by automake 1.13.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 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@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+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@
+TESTS = test$(EXEEXT)
+check_PROGRAMS = $(am__EXEEXT_1)
+subdir = coeffs
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/../build-aux/depcomp \
+	$(libcoeffs_la_include_HEADERS) \
+	$(top_srcdir)/../build-aux/test-driver
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/../m4/ax_append_compile_flags.m4 \
+	$(top_srcdir)/../m4/ax_append_flag.m4 \
+	$(top_srcdir)/../m4/ax_append_link_flags.m4 \
+	$(top_srcdir)/../m4/ax_check_compile_flag.m4 \
+	$(top_srcdir)/../m4/ax_check_link_flag.m4 \
+	$(top_srcdir)/../m4/ax_cxx_gcc_abi_demangle.m4 \
+	$(top_srcdir)/../m4/ax_prefix_config_h.m4 \
+	$(top_srcdir)/../m4/cpu-check.m4 $(top_srcdir)/../m4/flags.m4 \
+	$(top_srcdir)/../m4/flint-check.m4 \
+	$(top_srcdir)/../m4/gmp-check.m4 \
+	$(top_srcdir)/../m4/libtool.m4 \
+	$(top_srcdir)/../m4/ltoptions.m4 \
+	$(top_srcdir)/../m4/ltsugar.m4 \
+	$(top_srcdir)/../m4/ltversion.m4 \
+	$(top_srcdir)/../m4/lt~obsolete.m4 \
+	$(top_srcdir)/../m4/ntl-check.m4 \
+	$(top_srcdir)/../m4/options.m4 $(top_srcdir)/../m4/p-procs.m4 \
+	$(top_srcdir)/configure.ac
+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 =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+am__DEPENDENCIES_1 =
+libcoeffs_la_DEPENDENCIES = ${top_builddir}/reporter/libreporter.la \
+	${top_builddir}/misc/libmisc.la $(am__DEPENDENCIES_1) \
+	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+	$(am__DEPENDENCIES_1)
+am__objects_1 = numbers.lo rintegers.lo rmodulo2m.lo rmodulon.lo \
+	shortfl.lo gnumpc.lo gnumpfl.lo longrat.lo longrat0.lo \
+	ffields.lo modulop.lo mpr_complex.lo bigintmat.lo AE.lo \
+	OPAE.lo AEp.lo OPAEp.lo AEQ.lo OPAEQ.lo
+am_libcoeffs_la_OBJECTS = $(am__objects_1)
+libcoeffs_la_OBJECTS = $(am_libcoeffs_la_OBJECTS)
+AM_V_lt = $(am__v_lt_ at AM_V@)
+am__v_lt_ = $(am__v_lt_ at AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 = 
+am__EXEEXT_1 = test$(EXEEXT)
+am_test_OBJECTS = test.$(OBJEXT)
+test_OBJECTS = $(am_test_OBJECTS)
+am__DEPENDENCIES_2 = ${top_builddir}/reporter/libreporter.la \
+	${top_builddir}/misc/libmisc.la $(am__DEPENDENCIES_1) \
+	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+	$(am__DEPENDENCIES_1)
+test_DEPENDENCIES = libcoeffs.la $(am__DEPENDENCIES_2)
+AM_V_P = $(am__v_P_ at AM_V@)
+am__v_P_ = $(am__v_P_ at AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_ at AM_V@)
+am__v_GEN_ = $(am__v_GEN_ at AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_ at AM_V@)
+am__v_at_ = $(am__v_at_ at AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+DEFAULT_INCLUDES = -I. at am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/../build-aux/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \
+	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+	$(AM_CXXFLAGS) $(CXXFLAGS)
+AM_V_CXX = $(am__v_CXX_ at AM_V@)
+am__v_CXX_ = $(am__v_CXX_ at AM_DEFAULT_V@)
+am__v_CXX_0 = @echo "  CXX     " $@;
+am__v_CXX_1 = 
+CXXLD = $(CXX)
+CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+	$(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CXXLD = $(am__v_CXXLD_ at AM_V@)
+am__v_CXXLD_ = $(am__v_CXXLD_ at AM_DEFAULT_V@)
+am__v_CXXLD_0 = @echo "  CXXLD   " $@;
+am__v_CXXLD_1 = 
+DIST_SOURCES = $(libcoeffs_la_SOURCES) $(test_SOURCES)
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+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__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
+am__installdirs = "$(DESTDIR)$(libcoeffs_la_includedir)"
+HEADERS = $(libcoeffs_la_include_HEADERS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors_dummy = \
+  mgn= red= grn= lgn= blu= brg= std=; \
+  am__color_tests=no
+am__tty_colors = { \
+  $(am__tty_colors_dummy); \
+  if test "X$(AM_COLOR_TESTS)" = Xno; then \
+    am__color_tests=no; \
+  elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+    am__color_tests=yes; \
+  elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+    am__color_tests=yes; \
+  fi; \
+  if test $$am__color_tests = yes; then \
+    red=''; \
+    grn=''; \
+    lgn=''; \
+    blu=''; \
+    mgn=''; \
+    brg=''; \
+    std=''; \
+  fi; \
+}
+am__recheck_rx = ^[ 	]*:recheck:[ 	]*
+am__global_test_result_rx = ^[ 	]*:global-test-result:[ 	]*
+am__copy_in_global_log_rx = ^[ 	]*:copy-in-global-log:[ 	]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+  recheck = 1; \
+  while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+    { \
+      if (rc < 0) \
+        { \
+          if ((getline line2 < ($$0 ".log")) < 0) \
+	    recheck = 0; \
+          break; \
+        } \
+      else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+        { \
+          recheck = 0; \
+          break; \
+        } \
+      else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+        { \
+          break; \
+        } \
+    }; \
+  if (recheck) \
+    print $$0; \
+  close ($$0 ".trs"); \
+  close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+  print "fatal: making $@: " msg | "cat >&2"; \
+  exit 1; \
+} \
+function rst_section(header) \
+{ \
+  print header; \
+  len = length(header); \
+  for (i = 1; i <= len; i = i + 1) \
+    printf "="; \
+  printf "\n\n"; \
+} \
+{ \
+  copy_in_global_log = 1; \
+  global_test_result = "RUN"; \
+  while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+    { \
+      if (rc < 0) \
+         fatal("failed to read from " $$0 ".trs"); \
+      if (line ~ /$(am__global_test_result_rx)/) \
+        { \
+          sub("$(am__global_test_result_rx)", "", line); \
+          sub("[ 	]*$$", "", line); \
+          global_test_result = line; \
+        } \
+      else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+        copy_in_global_log = 0; \
+    }; \
+  if (copy_in_global_log) \
+    { \
+      rst_section(global_test_result ": " $$0); \
+      while ((rc = (getline line < ($$0 ".log"))) != 0) \
+      { \
+        if (rc < 0) \
+          fatal("failed to read from " $$0 ".log"); \
+        print line; \
+      }; \
+      printf "\n"; \
+    }; \
+  close ($$0 ".trs"); \
+  close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/   &   /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this.  Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+  --color-tests "$$am__color_tests" \
+  --enable-hard-errors "$$am__enable_hard_errors" \
+  --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test.  Creates the
+# directory for the log if needed.  Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log.  Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT.  Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup);					\
+$(am__vpath_adj_setup) $(am__vpath_adj)			\
+$(am__tty_colors);					\
+srcdir=$(srcdir); export srcdir;			\
+case "$@" in						\
+  */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;;	\
+    *) am__odir=.;; 					\
+esac;							\
+test "x$$am__odir" = x"." || test -d "$$am__odir" 	\
+  || $(MKDIR_P) "$$am__odir" || exit $$?;		\
+if test -f "./$$f"; then dir=./;			\
+elif test -f "$$f"; then dir=;				\
+else dir="$(srcdir)/"; fi;				\
+tst=$$dir$$f; log='$@'; 				\
+if test -n '$(DISABLE_HARD_ERRORS)'; then		\
+  am__enable_hard_errors=no; 				\
+else							\
+  am__enable_hard_errors=yes; 				\
+fi; 							\
+case " $(XFAIL_TESTS) " in				\
+  *[\ \	]$$f[\ \	]* | *[\ \	]$$dir$$f[\ \	]*) \
+    am__expect_failure=yes;;				\
+  *)							\
+    am__expect_failure=no;;				\
+esac; 							\
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed).  The result is saved in the shell variable
+# '$bases'.  This honors runtime overriding of TESTS and TEST_LOGS.  Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+  bases='$(TEST_LOGS)'; \
+  bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+  bases=`echo $$bases`
+RECHECK_LOGS = $(TEST_LOGS)
+AM_RECURSIVE_TARGETS = check recheck
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_DRIVER = $(SHELL) $(top_srcdir)/../build-aux/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+  case '$@' in \
+    */*) \
+      case '$*' in \
+        */*) b='$*';; \
+          *) b=`echo '$@' | sed 's/\.log$$//'`; \
+       esac;; \
+    *) \
+      b='$*';; \
+  esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT at .log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/../build-aux/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+	$(TEST_LOG_FLAGS)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+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@
+FACTORY_INCLUDES = @FACTORY_INCLUDES@
+FACTORY_LIBS = @FACTORY_LIBS@
+FGREP = @FGREP@
+FLINT_CFLAGS = @FLINT_CFLAGS@
+FLINT_HOME = @FLINT_HOME@
+FLINT_LIBS = @FLINT_LIBS@
+GMP_CFLAGS = @GMP_CFLAGS@
+GMP_HOME = @GMP_HOME@
+GMP_LIBS = @GMP_LIBS@
+GMP_VERSION = @GMP_VERSION@
+GREP = @GREP@
+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@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NTL_CFLAGS = @NTL_CFLAGS@
+NTL_LIBS = @NTL_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OMALLOC_INCLUDES = @OMALLOC_INCLUDES@
+OMALLOC_LIBS = @OMALLOC_LIBS@
+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@
+PKG_REQUIRE = @PKG_REQUIRE@
+POLYMAKE_CXXFLAGS = @POLYMAKE_CXXFLAGS@
+RANLIB = @RANLIB@
+RESOURCES_INCLUDES = @RESOURCES_INCLUDES@
+RESOURCES_LIBS = @RESOURCES_LIBS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SINGULAR_CFLAGS = @SINGULAR_CFLAGS@
+SI_CPU_I386 = @SI_CPU_I386@
+SI_CPU_IA64 = @SI_CPU_IA64@
+SI_CPU_PPC = @SI_CPU_PPC@
+SI_CPU_SPARC = @SI_CPU_SPARC@
+SI_CPU_X86_64 = @SI_CPU_X86_64@
+STRIP = @STRIP@
+USEPPROCSDYNAMICLD = @USEPPROCSDYNAMICLD@
+USEPPROCSDYNAMICLDFLAGS = @USEPPROCSDYNAMICLDFLAGS@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+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@
+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@
+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@
+ACLOCAL_AMFLAGS = -I ../../m4
+AM_CPPFLAGS = -I${top_srcdir} -I${top_builddir} \
+$(FACTORY_INCLUDES) $(OMALLOC_INCLUDES) $(RESOURCES_INCLUDES) \
+${NTL_CFLAGS} $(FLINT_CFLAGS) ${GMP_CFLAGS}
+
+
+# noinst???
+noinst_LTLIBRARIES = libcoeffs.la
+###### libcoeffsdir = $(libdir)/singular
+# noinst_HEADERS= \
+#	gnumpc.h gnumpfl.h longrat.h modulop.h ffields.h \
+#	rintegers.h rmodulo2m.h rmodulon.h shortfl.h \
+#	mpr_complex.h mpr_global.h
+SOURCES = \
+  numbers.cc rintegers.cc rmodulo2m.cc rmodulon.cc shortfl.cc \
+  gnumpc.cc gnumpfl.cc longrat.cc longrat0.cc ffields.cc \
+  modulop.cc mpr_complex.cc \
+  bigintmat.cc  AE.cc OPAE.cc AEp.cc OPAEp.cc AEQ.cc OPAEQ.cc
+
+libcoeffs_la_SOURCES = $(SOURCES)
+libcoeffs_la_includedir = $(includedir)/singular/coeffs
+libcoeffs_la_include_HEADERS = \
+  coeffs.h numbers.h si_gmp.h gnumpc.h gnumpfl.h longrat.h modulop.h ffields.h rintegers.h rmodulo2m.h rmodulon.h \
+  shortfl.h mpr_complex.h mpr_global.h numstats.h \
+  bigintmat.h Enumerator.h AE.h OPAE.h AEp.h OPAEp.h AEQ.h OPAEQ.h
+
+libcoeffs_la_LIBADD = ${top_builddir}/reporter/libreporter.la ${top_builddir}/misc/libmisc.la \
+$(FACTORY_LIBS) $(RESOURCES_LIBS) $(OMALLOC_LIBS) \
+$(FLINT_LIBS) $(GMP_LIBS) $(NTL_LIBS)
+
+TESTS_ENVIRONMENT = SINGULARPATH='${top_srcdir}/../factory:${top_builddir}/../factory' \
+	SINGULAR_ROOT_DIR='$(top_builddir)'
+test_SOURCES = test.cc
+test_LDADD = libcoeffs.la $(libcoeffs_la_LIBADD)
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .cc .lo .log .o .obj .test .test$(EXEEXT) .trs
+$(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) --foreign coeffs/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign coeffs/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-noinstLTLIBRARIES:
+	-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+	@list='$(noinst_LTLIBRARIES)'; \
+	locs=`for p in $$list; do echo $$p; done | \
+	      sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+	      sort -u`; \
+	test -z "$$locs" || { \
+	  echo rm -f $${locs}; \
+	  rm -f $${locs}; \
+	}
+
+libcoeffs.la: $(libcoeffs_la_OBJECTS) $(libcoeffs_la_DEPENDENCIES) $(EXTRA_libcoeffs_la_DEPENDENCIES) 
+	$(AM_V_CXXLD)$(CXXLINK)  $(libcoeffs_la_OBJECTS) $(libcoeffs_la_LIBADD) $(LIBS)
+
+clean-checkPROGRAMS:
+	@list='$(check_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
+
+test$(EXEEXT): $(test_OBJECTS) $(test_DEPENDENCIES) $(EXTRA_test_DEPENDENCIES) 
+	@rm -f test$(EXEEXT)
+	$(AM_V_CXXLD)$(CXXLINK) $(test_OBJECTS) $(test_LDADD) $(LIBS)
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/AE.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/AEQ.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/AEp.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/OPAE.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/OPAEQ.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/OPAEp.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/bigintmat.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ffields.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/gnumpc.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/gnumpfl.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/longrat.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/longrat0.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/modulop.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/mpr_complex.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/numbers.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/rintegers.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/rmodulo2m.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/rmodulon.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/shortfl.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/test.Po at am__quote@
+
+.cc.o:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+ at am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXXCOMPILE) -c -o $@ $<
+
+.cc.obj:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+ at am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.cc.lo:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+ at am__fastdepCXX_TRUE@	$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LTCXXCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+install-libcoeffs_la_includeHEADERS: $(libcoeffs_la_include_HEADERS)
+	@$(NORMAL_INSTALL)
+	@list='$(libcoeffs_la_include_HEADERS)'; test -n "$(libcoeffs_la_includedir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(libcoeffs_la_includedir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(libcoeffs_la_includedir)" || exit 1; \
+	fi; \
+	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)$(libcoeffs_la_includedir)'"; \
+	  $(INSTALL_HEADER) $$files "$(DESTDIR)$(libcoeffs_la_includedir)" || exit $$?; \
+	done
+
+uninstall-libcoeffs_la_includeHEADERS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(libcoeffs_la_include_HEADERS)'; test -n "$(libcoeffs_la_includedir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	dir='$(DESTDIR)$(libcoeffs_la_includedir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	$(am__define_uniq_tagged_files); \
+	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-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	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"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'.  Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+	rm -f $< $@
+	$(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+	@:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+	@$(am__set_TESTS_bases); \
+	am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+	redo_bases=`for i in $$bases; do \
+	              am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+	            done`; \
+	if test -n "$$redo_bases"; then \
+	  redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+	  redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+	  if $(am__make_dryrun); then :; else \
+	    rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+	  fi; \
+	fi; \
+	if test -n "$$am__remaking_logs"; then \
+	  echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+	       "recursion detected" >&2; \
+	else \
+	  am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+	fi; \
+	if $(am__make_dryrun); then :; else \
+	  st=0;  \
+	  errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+	  for i in $$redo_bases; do \
+	    test -f $$i.trs && test -r $$i.trs \
+	      || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+	    test -f $$i.log && test -r $$i.log \
+	      || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+	  done; \
+	  test $$st -eq 0 || exit 1; \
+	fi
+	@$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+	ws='[ 	]'; \
+	results=`for b in $$bases; do echo $$b.trs; done`; \
+	test -n "$$results" || results=/dev/null; \
+	all=`  grep "^$$ws*:test-result:"           $$results | wc -l`; \
+	pass=` grep "^$$ws*:test-result:$$ws*PASS"  $$results | wc -l`; \
+	fail=` grep "^$$ws*:test-result:$$ws*FAIL"  $$results | wc -l`; \
+	skip=` grep "^$$ws*:test-result:$$ws*SKIP"  $$results | wc -l`; \
+	xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+	xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+	error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+	if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+	  success=true; \
+	else \
+	  success=false; \
+	fi; \
+	br='==================='; br=$$br$$br$$br$$br; \
+	result_count () \
+	{ \
+	    if test x"$$1" = x"--maybe-color"; then \
+	      maybe_colorize=yes; \
+	    elif test x"$$1" = x"--no-color"; then \
+	      maybe_colorize=no; \
+	    else \
+	      echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+	    fi; \
+	    shift; \
+	    desc=$$1 count=$$2; \
+	    if test $$maybe_colorize = yes && test $$count -gt 0; then \
+	      color_start=$$3 color_end=$$std; \
+	    else \
+	      color_start= color_end=; \
+	    fi; \
+	    echo "$${color_start}# $$desc $$count$${color_end}"; \
+	}; \
+	create_testsuite_report () \
+	{ \
+	  result_count $$1 "TOTAL:" $$all   "$$brg"; \
+	  result_count $$1 "PASS: " $$pass  "$$grn"; \
+	  result_count $$1 "SKIP: " $$skip  "$$blu"; \
+	  result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+	  result_count $$1 "FAIL: " $$fail  "$$red"; \
+	  result_count $$1 "XPASS:" $$xpass "$$red"; \
+	  result_count $$1 "ERROR:" $$error "$$mgn"; \
+	}; \
+	{								\
+	  echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" |	\
+	    $(am__rst_title);						\
+	  create_testsuite_report --no-color;				\
+	  echo;								\
+	  echo ".. contents:: :depth: 2";				\
+	  echo;								\
+	  for b in $$bases; do echo $$b; done				\
+	    | $(am__create_global_log);					\
+	} >$(TEST_SUITE_LOG).tmp || exit 1;				\
+	mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG);			\
+	if $$success; then						\
+	  col="$$grn";							\
+	 else								\
+	  col="$$red";							\
+	  test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG);		\
+	fi;								\
+	echo "$${col}$$br$${std}"; 					\
+	echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}";	\
+	echo "$${col}$$br$${std}"; 					\
+	create_testsuite_report --maybe-color;				\
+	echo "$$col$$br$$std";						\
+	if $$success; then :; else					\
+	  echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}";		\
+	  if test -n "$(PACKAGE_BUGREPORT)"; then			\
+	    echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}";	\
+	  fi;								\
+	  echo "$$col$$br$$std";					\
+	fi;								\
+	$$success || exit 1
+
+check-TESTS:
+	@list='$(RECHECK_LOGS)';           test -z "$$list" || rm -f $$list
+	@list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+	@test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+	@set +e; $(am__set_TESTS_bases); \
+	log_list=`for i in $$bases; do echo $$i.log; done`; \
+	trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+	log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+	$(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+	exit $$?;
+recheck: all $(check_PROGRAMS)
+	@test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+	@set +e; $(am__set_TESTS_bases); \
+	bases=`for i in $$bases; do echo $$i; done \
+	         | $(am__list_recheck_tests)` || exit 1; \
+	log_list=`for i in $$bases; do echo $$i.log; done`; \
+	log_list=`echo $$log_list`; \
+	$(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+	        am__force_recheck=am--force-recheck \
+	        TEST_LOGS="$$log_list"; \
+	exit $$?
+test.log: test$(EXEEXT)
+	@p='test$(EXEEXT)'; \
+	b='test'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+.test.log:
+	@p='$<'; \
+	$(am__set_b); \
+	$(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+ at am__EXEEXT_TRUE@.test$(EXEEXT).log:
+ at am__EXEEXT_TRUE@	@p='$<'; \
+ at am__EXEEXT_TRUE@	$(am__set_b); \
+ at am__EXEEXT_TRUE@	$(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ at am__EXEEXT_TRUE@	--log-file $$b.log --trs-file $$b.trs \
+ at am__EXEEXT_TRUE@	$(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ at am__EXEEXT_TRUE@	"$$tst" $(AM_TESTS_FD_REDIRECT)
+
+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_PROGRAMS)
+	$(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(HEADERS)
+installdirs:
+	for dir in "$(DESTDIR)$(libcoeffs_la_includedir)"; 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:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+	-test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+	-test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+	-test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+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-checkPROGRAMS clean-generic clean-libtool \
+	clean-noinstLTLIBRARIES 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-libcoeffs_la_includeHEADERS
+
+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: uninstall-libcoeffs_la_includeHEADERS
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am clean \
+	clean-checkPROGRAMS clean-generic clean-libtool \
+	clean-noinstLTLIBRARIES cscopelist-am ctags ctags-am 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-libcoeffs_la_includeHEADERS 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 \
+	recheck tags tags-am uninstall uninstall-am \
+	uninstall-libcoeffs_la_includeHEADERS
+
+
+# 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/libpolys/coeffs/OPAE.cc b/libpolys/coeffs/OPAE.cc
new file mode 100644
index 0000000..9097bce
--- /dev/null
+++ b/libpolys/coeffs/OPAE.cc
@@ -0,0 +1,397 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+*Dense Integer Polynomials
+*/
+//Schauen was hier überhaupt sinn macht
+
+#include <misc/auxiliary.h>
+#include <omalloc/omalloc.h>
+#include <factory/factory.h>
+#include <misc/mylimits.h>
+#include <reporter/reporter.h>
+
+#include "coeffs.h"
+#include "numbers.h"
+#include "mpr_complex.h"
+
+#include "OPAE.h"
+#include "AE.h"
+
+#include <string.h>
+
+#ifdef SINGULAR_4_1
+
+BOOLEAN nAECoeffIsEqual     (number a, number b, const coeffs r);
+number  nAEMult        (number a, number b, const coeffs r);
+number  nAESub         (number a, number b, const coeffs r);
+number  nAEAdd         (number a, number b, const coeffs r);
+number  nAEDiv         (number a, number b, const coeffs r);
+number  nAEIntMod      (number a, number b, const coeffs r);// Hir wollte wir was gucken
+number  nAEExactDiv    (number a, number b, const coeffs r);
+number  nAEInit        (long i, const coeffs r);
+number  nAEInitMPZ     (mpz_t m, const coeffs r); //nachgucken/fragen
+int     nAESize        (number a, const coeffs r);///
+int     nAEInt         (number &a, const coeffs r);
+number  nAEMPZ         (number a, const coeffs r); //nachgucken/fragen
+number  nAENeg         (number c, const coeffs r);
+number  nAECopy        (number a, number b, const coeffs r); // nachgicken
+number  nAERePart      (number a, number b, const coeffs r); // nachgicken
+number  nAEImPart      (number a, number b, const coeffs r); // nachgicken
+
+void    nAEWriteLong   (number &a, const coeffs r);//
+void    nAEWriteShort  (number &a, const coeffs r);//
+
+
+const char *  nAERead  (const char *s, number *a, const coeffs r);
+number nAENormalize    (number a, number b, const coeffs r);//
+BOOLEAN nAEGreater     (number a, number b, const coeffs r);//
+BOOLEAN nAEEqual       (number a, number b, const coeffs r);
+BOOLEAN nAEIsZero      (number a, const coeffs r);
+BOOLEAN nAEIsOne       (number a, const coeffs r);
+BOOLEAN nAEIsMOne      (number a, const coeffs r);
+BOOLEAN nAEGreaterZero (number a, number b, const coeffs r);
+void    nAEPower       (number a, int i, number * result, const coeffs r);
+number nAEGetDenom     (number &a, const coeffs r);//
+number nAEGetNumerator (number &a, const coeffs r);//
+number nAEGcd          (number a, number b, const coeffs r);
+number nAELcm          (number a, number b, const coeffs r);
+
+void    nAEDelete       (number *a, const coeffs r);//
+number    nAESetMap      (number a, const coeffs r);//
+void    nAEInpMult      (number &a ,number b, const coeffs r);//
+void    nAECoeffWrite   (const coeffs r, BOOLEAN details);//
+
+BOOLEAN nAEClearContent  (number a, const coeffs r);//
+BOOLEAN nAEClearDenominators  (number a, const coeffs r);//
+
+
+
+
+// DEFINITION DER FUNKTIONEN
+
+number  nAEAdd(number a, number b, const coeffs)
+{
+    int_poly* f=reinterpret_cast<int_poly*> (a);
+    int_poly* g=reinterpret_cast<int_poly*> (b);
+    int_poly *res=new int_poly;
+    res->poly_set(*f);
+    res->poly_add_to(*g);
+    return (number) res;
+}
+
+number  nAEMult(number a, number b, const coeffs)
+{
+    int_poly* f=reinterpret_cast<int_poly*> (a);
+    int_poly* g=reinterpret_cast<int_poly*> (b);
+    int_poly *res=new int_poly;
+    res->poly_set(*f);
+    res->poly_mult_n_to(*g);
+    return (number) res;
+}
+
+number  nAESub(number a, number b, const coeffs)
+{
+    int_poly* f=reinterpret_cast<int_poly*> (a);
+    int_poly* g=reinterpret_cast<int_poly*> (b);
+    int_poly *res=new int_poly;
+    res->poly_set(*f);
+    res->poly_sub_to(*g);
+    return (number) res;
+}
+
+
+number  nAEDiv(number a, number b, const coeffs)
+{
+    int_poly* f=reinterpret_cast<int_poly*> (a);
+    int_poly* g=reinterpret_cast<int_poly*> (b);
+    int_poly *res=new int_poly;
+    res->poly_set(*f);
+    res->poly_div_to(*res,*f,*g);
+    return (number) res;
+}
+
+
+number  nAEIntMod(number a, number, const coeffs)
+{
+    return a;
+}
+
+number  nAEExactDiv(number a, number b, const coeffs)
+{
+    int_poly* f=reinterpret_cast<int_poly*> (a);
+    int_poly* g=reinterpret_cast<int_poly*> (b);
+    int_poly *res=new int_poly;
+    res->poly_set(*f);
+    res->poly_div_to(*res,*f,*g);
+    return (number) res;
+}
+
+
+
+number nAEInit(long i, const coeffs)
+{
+    mpz_t m;
+    mpz_init_set_ui(m, i);
+    int_poly* res=new int_poly;
+    res->poly_set(m);
+    number res1=reinterpret_cast<number>(res);
+    return  res1;
+}
+
+number nAEInitMPZ(mpz_t m, const coeffs)
+{
+    int_poly* res=new int_poly;
+    res->poly_set(m);
+    number res1=reinterpret_cast<number>(res);
+    return  res1;
+}
+
+
+int nAESize (number a, const coeffs)
+{
+    int_poly* f=reinterpret_cast<int_poly*> (a);
+    return f->deg;
+}
+
+int nAEInt(number &, const coeffs)
+{
+    return 1;
+}
+
+
+number nAEMPZ(number a, const coeffs)
+{
+    return a;
+}
+
+
+number nAENeg(number c, const coeffs)
+{
+    int_poly* f=reinterpret_cast<int_poly*> (c);
+    int_poly *res=new int_poly;
+    res->poly_set(*f);
+    res->poly_neg();
+    return (number) res;
+}
+
+number nAECopy(number c, const coeffs)
+{
+    return (number) c;
+}
+
+number nAERePart(number c, const coeffs)
+{
+    return (number) c;
+}
+
+number nAEImPart(number c, const coeffs)
+{
+    return (number) c;
+}
+
+void    nAEWriteLong   (number &a, const coeffs)
+{
+    int_poly* f=reinterpret_cast <int_poly*>(a);
+    f->poly_print();
+    return ;
+}
+
+void    nAEWriteShort  (number &a, const coeffs)
+{
+    int_poly* f=reinterpret_cast <int_poly*>(a);
+    f->poly_print();
+    return ;
+}
+
+
+const char *  nAERead  (const char *, number *, const coeffs)
+{
+    char* c=new char;
+    *c='c';
+    return c;
+}
+
+number nAENormalize    (number a, number, const coeffs) // ?
+{
+        return a;
+}
+
+BOOLEAN nAEGreater     (number a, number b, const coeffs)
+{
+        int_poly* f=reinterpret_cast<int_poly*> (a);
+        int_poly* g=reinterpret_cast<int_poly*> (b);
+        if (f->deg > g->deg) {return FALSE;}
+        else {return TRUE;}
+}
+
+BOOLEAN nAEEqual     (number a, number b, const coeffs)
+{
+        int_poly* f=reinterpret_cast<int_poly*> (a);
+        int_poly* g=reinterpret_cast<int_poly*> (b);
+        if (f->is_equal(*g) == 1) {return FALSE;}
+        else {return TRUE;}
+}
+
+BOOLEAN nAEIsZero      (number a, const coeffs)
+{
+        int_poly* f=reinterpret_cast<int_poly*> (a);
+        if (f->is_zero() == 1) {return FALSE;}
+        else {return TRUE;}
+}
+
+BOOLEAN nAEIsOne      (number a, const coeffs)
+{
+        int_poly* f=reinterpret_cast<int_poly*> (a);
+        if (f->is_one() == 1) {return FALSE;}
+        else {return TRUE;}
+}
+
+BOOLEAN nAEIsMOne      (number a, const coeffs)
+{
+        int_poly* f=reinterpret_cast<int_poly*> (a);
+        if (f->is_one() == 1) {return FALSE;}
+        else {return TRUE;}
+}
+
+BOOLEAN nAEGreaterZero     (number a, const coeffs r)
+{
+        if (nAEIsZero(a, r) == FALSE) { return TRUE; }
+        else { return FALSE; }
+}
+
+void    nAEPower       (number, int, number *, const coeffs)
+{
+        return;
+}
+
+number nAEGetDenom      (number &, const coeffs)
+{
+        return (number) 1;
+}
+
+number nAEGetNumerator      (number &a, const coeffs)
+{
+        return a;
+}
+
+number nAEGcd           (number a, number b, const coeffs)
+{
+        int_poly* f=reinterpret_cast<int_poly*> (a);
+        int_poly* g=reinterpret_cast<int_poly*> (b);
+        int_poly *res=new int_poly;
+        res->poly_gcd(*f,*g);
+        return (number) res;
+}
+
+number nAELcm          (number a, number b, const coeffs)
+{
+        int_poly* f=reinterpret_cast<int_poly*> (a);
+        int_poly* g=reinterpret_cast<int_poly*> (b);
+        int_poly *gcd=new int_poly;
+        int_poly *res=new int_poly;
+        gcd->poly_gcd(*f,*g);
+        res->poly_mult_n(*f,*g);
+        res->poly_div_to(*res,*f,*gcd);
+        return (number) res;
+}
+
+void    nAEDelete       (number *, const coeffs)
+{
+        return;
+}
+
+nMapFunc  nAESetMap (const coeffs src, const coeffs dst)
+{
+  if (src==dst) return ndCopyMap; // UNDEFINED: nAECopyMap; // BUG :(
+  else return NULL;
+}
+
+void    nAEInpMult       (number &, number, const coeffs)
+{
+        return ;
+}
+
+void    nAECoeffWrite   (const coeffs, BOOLEAN)
+{
+        return;
+}
+
+BOOLEAN nAEClearContent  (number, const coeffs)
+{
+        return FALSE;
+}
+
+BOOLEAN nAEClearDenominators  (number, const coeffs)
+{
+        return FALSE;
+}
+
+static char * n_AECoeffName(const coeffs r)
+{
+  return (char *)"AE";
+}
+
+//INITIALISIERUNG FÜR SINGULAR
+
+
+BOOLEAN n_AEInitChar(coeffs r, void *)
+{
+    // r->is_field, r->is_domain?
+    r->ch = 0;
+    //r->cfKillChar = ndKillChar; /* dummy */
+    //r->nCoeffIsEqual=ndCoeffIsEqual;
+    r->cfMult  = nAEMult;
+    r->cfSub   = nAESub;
+    r->cfAdd   = nAEAdd;
+    r->cfDiv   = nAEDiv;
+    r->cfIntMod= nAEIntMod;
+    r->cfExactDiv= nAEExactDiv;
+    r->cfInit = nAEInit;
+    r->cfSize  = nAESize;
+    r->cfInt  = nAEInt;
+    r->cfCoeffName = n_AECoeffName;
+#ifdef HAVE_RINGS
+    //r->cfDivComp = NULL; // only for ring stuff
+    //r->cfIsUnit = NULL; // only for ring stuff
+    //r->cfGetUnit = NULL; // only for ring stuff
+    //r->cfExtGcd = NULL; // only for ring stuff
+    // r->cfDivBy = NULL; // only for ring stuff
+#endif
+    r->cfInpNeg   = nAENeg;
+    r->cfInvers= NULL;
+    //r->cfCopy  = ndCopy;
+    //r->cfRePart = ndCopy;
+    //r->cfImPart = ndReturn0;
+    r->cfWriteLong = nAEWriteLong;
+    r->cfRead = nAERead;
+    //r->cfNormalize=ndNormalize;
+    r->cfGreater = nAEGreater;
+    r->cfEqual = nAEEqual;
+    r->cfIsZero = nAEIsZero;
+    r->cfIsOne = nAEIsOne;
+    r->cfIsMOne = nAEIsOne;
+    r->cfGreaterZero = nAEGreaterZero;
+    r->cfPower = nAEPower; // ZU BEARBEITEN
+    r->cfGetDenom = nAEGetDenom;
+    r->cfGetNumerator = nAEGetNumerator;
+    r->cfGcd  = nAEGcd;
+    r->cfLcm  = nAELcm; // ZU BEARBEITEN
+    r->cfDelete= nAEDelete;
+
+    r->cfSetMap = nAESetMap;
+
+    r->cfInpMult=nAEInpMult; //????
+    r->cfCoeffWrite=nAECoeffWrite; //????
+
+
+    // the variables:
+    r->nNULL = (number) 0;
+    //r->type = n_AE;
+    r->ch = 0;
+    r->has_simple_Alloc=TRUE;
+    r->has_simple_Inverse=TRUE;
+    return FALSE;
+}
+#endif
diff --git a/libpolys/coeffs/OPAE.h b/libpolys/coeffs/OPAE.h
new file mode 100644
index 0000000..e0b1f6f
--- /dev/null
+++ b/libpolys/coeffs/OPAE.h
@@ -0,0 +1,16 @@
+#ifndef OPAE_H
+#define OPAE_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+
+#include <misc/auxiliary.h>
+
+struct n_Procs_s; typedef struct  n_Procs_s  *coeffs;
+struct snumber; typedef struct snumber *   number;
+
+#ifdef SINGULAR_4_1
+BOOLEAN n_AEInitChar(coeffs , void *);
+#endif
+
+#endif
diff --git a/libpolys/coeffs/OPAEQ.cc b/libpolys/coeffs/OPAEQ.cc
new file mode 100644
index 0000000..8ae7c54
--- /dev/null
+++ b/libpolys/coeffs/OPAEQ.cc
@@ -0,0 +1,388 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+*Dense Integer Polynomials
+*/
+//Schauen was hier überhaupt sinn macht
+
+#include <misc/auxiliary.h>
+
+#ifdef SINGULAR_4_1
+
+#include <omalloc/omalloc.h>
+#include <factory/factory.h>
+#include <misc/mylimits.h>
+#include <reporter/reporter.h>
+
+#include "coeffs.h"
+#include "numbers.h"
+#include "mpr_complex.h"
+#include "AEQ.h"
+#include "modulop.h"
+
+#include <string.h>
+
+BOOLEAN nAEQCoeffIsEqual     (number a, number b, const coeffs r);
+number  nAEQMult        (number a, number b, const coeffs r);
+number  nAEQSub         (number a, number b, const coeffs r);
+number  nAEQAdd         (number a, number b, const coeffs r);
+number  nAEQDiv         (number a, number b, const coeffs r);
+number  nAEQIntMod      (number a, number b, const coeffs r);// Hir wollte wir was gucken
+number  nAEQExactDiv    (number a, number b, const coeffs r);
+number  nAEQInit        (long i, const coeffs r);
+number  nAEQInitMPZ     (mpz_t m, const coeffs r); //nachgucken/fragen
+int     nAEQSize        (number a, const coeffs r);///
+int     nAEQInt         (number &a, const coeffs r);
+number  nAEQMPZ         (number a, const coeffs r); //nachgucken/fragen
+number  nAEQNeg         (number c, const coeffs r);
+number  nAEQCopy        (number a, number b, const coeffs r); // nachgicken
+number  nAEQRePart      (number a, number b, const coeffs r); // nachgicken
+number  nAEQImPart      (number a, number b, const coeffs r); // nachgicken
+
+void    nAEQWriteLong   (number &a, const coeffs r);//
+void    nAEQWriteShort  (number &a, const coeffs r);//
+
+
+const char *  nAEQRead  (const char *s, number *a, const coeffs r);
+number nAEQNormalize    (number a, number b, const coeffs r);//
+BOOLEAN nAEQGreater     (number a, number b, const coeffs r);//
+BOOLEAN nAEQEqual       (number a, number b, const coeffs r);
+BOOLEAN nAEQIsZero      (number a, const coeffs r);
+BOOLEAN nAEQIsOne       (number a, const coeffs r);
+BOOLEAN nAEQIsMOne      (number a, const coeffs r);
+BOOLEAN nAEQGreaterZero (number a, number b, const coeffs r);
+void    nAEQPower       (number a, int i, number * result, const coeffs r);
+number nAEQGetDenom     (number &a, const coeffs r);//
+number nAEQGetNumerator (number &a, const coeffs r);//
+number nAEQGcd          (number a, number b, const coeffs r);
+number nAEQLcm          (number a, number b, const coeffs r);
+
+void    nAEQDelete       (number *a, const coeffs r);//
+number    nAEQSetMap      (number a, const coeffs r);//
+void    nAEQInpMult      (number &a ,number b, const coeffs r);//
+void    nAEQCoeffWrite   (const coeffs r, BOOLEAN details);//
+
+BOOLEAN nAEQClearContent  (number a, const coeffs r);//
+BOOLEAN nAEQClearDenominators  (number a, const coeffs r);//
+
+
+
+
+// DEFINITION DER FUNKTIONEN
+
+number  nAEQAdd(number a, number b, const coeffs)
+{
+    Q_poly* f=reinterpret_cast<Q_poly*> (a);
+    Q_poly* g=reinterpret_cast<Q_poly*> (b);
+    Q_poly *res=new Q_poly;
+    res->Q_poly_set(*f);
+    res->Q_poly_add_to(*g);
+    return (number) res;
+}
+
+number  nAEQMult(number a, number b, const coeffs)
+{
+    Q_poly* f=reinterpret_cast<Q_poly*> (a);
+    Q_poly* g=reinterpret_cast<Q_poly*> (b);
+    Q_poly *res=new Q_poly;
+    res->Q_poly_set(*f);
+    res->Q_poly_mult_n_to(*g);
+    return (number) res;
+}
+
+number  nAEQSub(number a, number b, const coeffs)
+{
+    Q_poly* f=reinterpret_cast<Q_poly*> (a);
+    Q_poly* g=reinterpret_cast<Q_poly*> (b);
+    Q_poly *res=new Q_poly;
+    res->Q_poly_set(*f);
+    res->Q_poly_sub_to(*g);
+    return (number) res;
+}
+
+
+number  nAEQDiv(number a, number b, const coeffs)
+{
+    Q_poly* f=reinterpret_cast<Q_poly*> (a);
+    Q_poly* g=reinterpret_cast<Q_poly*> (b);
+    Q_poly *res=new Q_poly;
+    Q_poly *s=new Q_poly;
+    res->Q_poly_set(*f);
+    res->Q_poly_div_to(*res,*s,*g);
+    return (number) res;
+}
+
+
+number  nAEQIntMod(number a, number, const coeffs)
+{
+    return a;
+}
+
+number  nAEQExactDiv(number a, number b, const coeffs)
+{
+    Q_poly* f=reinterpret_cast<Q_poly*> (a);
+    Q_poly* g=reinterpret_cast<Q_poly*> (b);
+    Q_poly *res=new Q_poly;
+    Q_poly *s=new Q_poly;
+    res->Q_poly_set(*f);
+    res->Q_poly_div_to(*res,*s,*g);
+    return (number) res;
+}
+
+
+
+number nAEQInit(long i, const coeffs)
+{
+    number res = (number) i;
+    return res;
+}
+
+number nAEQInitMPZ(mpz_t m, const coeffs)
+{
+    number res= (number) m;
+    return res;
+}
+
+int nAEQSize (number a, const coeffs)
+{
+    Q_poly* f=reinterpret_cast<Q_poly*> (a);
+    return f->deg;
+}
+
+int nAEQInt(number &, const coeffs)
+{
+    return 1;
+}
+
+
+number nAEQMPZ(number a, const coeffs)
+{
+    return a;
+}
+
+
+number nAEQNeg(number c, const coeffs)
+{
+    Q_poly* f=reinterpret_cast<Q_poly*> (c);
+    Q_poly *res=new Q_poly;
+    res->Q_poly_set(*f);
+    res->Q_poly_neg();
+    return (number) res;
+}
+
+number nAEQCopy(number c, const coeffs)
+{
+    return (number) c;
+}
+
+number nAEQRePart(number c, const coeffs)
+{
+    return (number) c;
+}
+
+number nAEQImPart(number c, const coeffs)
+{
+    return (number) c;
+}
+
+void    nAEQWriteLong   (number &, const coeffs)
+{
+    return;
+}
+
+void    nAEQWriteShort  (number &, const coeffs)
+{
+    return ;
+}
+
+
+const char *  nAEQRead  (const char *, number *, const coeffs)
+{
+    return "";
+}
+
+number nAEQNormalize    (number a, number , const coeffs) // ?
+{
+    return a;
+}
+
+BOOLEAN nAEQGreater     (number a, number b, const coeffs)
+{
+    Q_poly* f=reinterpret_cast<Q_poly*> (a);
+    Q_poly* g=reinterpret_cast<Q_poly*> (b);
+    if (f->deg > g->deg) {return FALSE;}
+    else {return TRUE;}
+}
+
+BOOLEAN nAEQEqual     (number a, number b, const coeffs)
+{
+    Q_poly* f=reinterpret_cast<Q_poly*> (a);
+    Q_poly* g=reinterpret_cast<Q_poly*> (b);
+    if (f->is_equal(*g) == 1) {return FALSE;}
+    else {return TRUE;}
+}
+
+BOOLEAN nAEQIsZero      (number a, const coeffs)
+{
+    Q_poly* f=reinterpret_cast<Q_poly*> (a);
+    if (f->is_zero() == 1) {return FALSE;}
+    else {return TRUE;}
+}
+
+BOOLEAN nAEQIsOne      (number a, const coeffs)
+{
+    Q_poly* f=reinterpret_cast<Q_poly*> (a);
+    if (f->is_one() == 1) {return FALSE;}
+    else {return TRUE;}
+}
+
+BOOLEAN nAEQIsMOne      (number a, const coeffs)
+{
+    Q_poly* f=reinterpret_cast<Q_poly*> (a);
+    if (f->is_one() == 1) {return FALSE;}
+    else {return TRUE;}
+}
+
+BOOLEAN nAEQGreaterZero     (number a, const coeffs r)
+{
+    if (nAEQIsZero(a, r) == FALSE) { return TRUE; }
+    else { return FALSE; }
+}
+
+void    nAEQPower       (number, int, number *, const coeffs)
+{
+    return;
+}
+
+number nAEQGetDenom      (number &, const coeffs)
+{
+    return (number) 1;
+}
+
+number nAEQGetNumerator      (number &a, const coeffs)
+{
+    return a;
+}
+
+number nAEQGcd           (number a, number b, const coeffs)
+{
+    Q_poly* f=reinterpret_cast<Q_poly*> (a);
+    Q_poly* g=reinterpret_cast<Q_poly*> (b);
+    Q_poly *res=new Q_poly;
+    res->Q_poly_gcd(*f,*g);
+    return (number) res;
+}
+
+number nAEQLcm          (number a, number b, const coeffs)
+{
+    Q_poly* f=reinterpret_cast<Q_poly*> (a);
+    Q_poly* g=reinterpret_cast<Q_poly*> (b);
+    Q_poly *gcd=new Q_poly;
+    Q_poly *res=new Q_poly;
+    Q_poly *s=new Q_poly;
+    gcd->Q_poly_gcd(*f,*g);
+    res->Q_poly_mult_n(*f,*g);
+    res->Q_poly_div_to(*res,*s,*gcd);
+    return (number) res;
+}
+
+void    nAEQDelete       (number *, const coeffs)
+{
+    return;
+}
+
+/*
+number    nAEQSetMap        (number a, const coeffs)
+{
+        return a;
+}
+*/
+
+void    nAEQInpMult       (number &, number, const coeffs)
+{
+    return ;
+}
+
+void    nAEQCoeffWrite   (const coeffs, BOOLEAN)
+{
+    return;
+}
+
+BOOLEAN nAEQClearContent  (number, const coeffs)
+{
+    return FALSE;
+}
+
+BOOLEAN nAEQClearDenominators  (number, const coeffs)
+{
+    return FALSE;
+}
+
+static char * n_QAECoeffName(const coeffs r)
+{
+  return (char *)"QAE";
+}
+
+
+//INITIALISIERUNG FÜR SINGULAR
+
+
+BOOLEAN n_QAEInitChar(coeffs r, void *)
+{
+    // r->is_field,is_domain?
+    r->ch=0;
+    //r->cfKillChar=ndKillChar;
+    //r->nCoeffIsEqual=ndCoeffIsEqual;
+    r->cfMult  = nAEQMult;
+    r->cfSub   = nAEQSub;
+    r->cfAdd   = nAEQAdd;
+    r->cfDiv   = nAEQDiv;
+    r->cfIntMod= nAEQIntMod;
+    r->cfExactDiv= nAEQExactDiv;
+    r->cfInit = nAEQInit;
+    r->cfSize  = nAEQSize;
+    r->cfInt  = nAEQInt;
+    r->cfCoeffName = n_QAECoeffName;
+#ifdef HAVE_RINGS
+    //r->cfDivComp = NULL; // only for ring stuff
+    //r->cfIsUnit = NULL; // only for ring stuff
+    //r->cfGetUnit = NULL; // only for ring stuff
+    //r->cfExtGcd = NULL; // only for ring stuff
+    // r->cfDivBy = NULL; // only for ring stuff
+#endif
+    r->cfInpNeg   = nAEQNeg;
+    r->cfInvers= NULL;
+    //r->cfCopy  = ndCopy;
+    //r->cfRePart = ndCopy;
+    //r->cfImPart = ndReturn0;
+    r->cfWriteLong = nAEQWriteLong;
+    r->cfRead = nAEQRead;
+    //r->cfNormalize=ndNormalize;
+    r->cfGreater = nAEQGreater;
+    r->cfEqual = nAEQEqual;
+    r->cfIsZero = nAEQIsZero;
+    r->cfIsOne = nAEQIsOne;
+    r->cfIsMOne = nAEQIsOne;
+    r->cfGreaterZero = nAEQGreaterZero;
+    r->cfPower = nAEQPower; // ZU BEARBEITEN
+    r->cfGetDenom = nAEQGetDenom;
+    r->cfGetNumerator = nAEQGetNumerator;
+    r->cfGcd  = nAEQGcd;
+    r->cfLcm  = nAEQLcm; // ZU BEARBEITEN
+    r->cfDelete= nAEQDelete;
+
+    r->cfSetMap = npSetMap; // extern nMapFunc npSetMap(const coeffs src, const coeffs dst); // FIXME: WHY??? // TODO: this seems to be a bug!
+
+    r->cfInpMult=nAEQInpMult; //????
+    r->cfCoeffWrite=nAEQCoeffWrite; //????
+
+
+    // the variables:
+    r->nNULL = (number) 0;
+    //r->type = n_AE;
+    r->has_simple_Alloc=TRUE;
+    r->has_simple_Inverse=TRUE;
+    return FALSE;
+}
+#endif
diff --git a/libpolys/coeffs/OPAEQ.h b/libpolys/coeffs/OPAEQ.h
new file mode 100644
index 0000000..212fe32
--- /dev/null
+++ b/libpolys/coeffs/OPAEQ.h
@@ -0,0 +1,15 @@
+#ifndef OPAEQ_H
+#define OPAEQ_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+#include <misc/auxiliary.h>
+
+struct n_Procs_s; typedef struct  n_Procs_s  *coeffs;
+struct snumber; typedef struct snumber *   number;
+
+#ifdef SINGULAR_4_1
+BOOLEAN n_QAEInitChar(coeffs , void *);
+#endif
+
+#endif
diff --git a/libpolys/coeffs/OPAEp.cc b/libpolys/coeffs/OPAEp.cc
new file mode 100644
index 0000000..ef32fc6
--- /dev/null
+++ b/libpolys/coeffs/OPAEp.cc
@@ -0,0 +1,412 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* Dense Polynomials modulo p
+*/
+//Schauen was hier überhaupt sinn macht
+
+#include <misc/auxiliary.h>
+
+#ifdef SINGULAR_4_1
+
+#include <omalloc/omalloc.h>
+#include <factory/factory.h>
+#include <misc/mylimits.h>
+#include <reporter/reporter.h>
+
+#include "coeffs.h"
+#include "numbers.h"
+#include "mpr_complex.h"
+#include "OPAEp.h"
+#include "AEp.h"
+#include "modulop.h"
+
+#include <string.h>
+
+BOOLEAN nAEpCoeffIsEqual     (number a, number b, const coeffs r);
+number  nAEpMult        (number a, number b, const coeffs r);
+number  nAEpSub         (number a, number b, const coeffs r);
+number  nAEpAdd         (number a, number b, const coeffs r);
+number  nAEpDiv         (number a, number b, const coeffs r);
+number  nAEpIntMod      (number a, number b, const coeffs r);// Hir wollte wir was gucken
+number  nAEpExactDiv    (number a, number b, const coeffs r);
+number  nAEpInit        (long i, const coeffs r);
+number  nAEpInitMPZ     (mpz_t m, const coeffs r); //nachgucken/fragen
+int     nAEpSize        (number a, const coeffs r);///
+int     nAEpInt         (number &a, const coeffs r);
+number  nAEpMPZ         (number a, const coeffs r); //nachgucken/fragen
+number  nAEpNeg         (number c, const coeffs r);
+number  nAEpCopy        (number a, number b, const coeffs r); // nachgicken
+number  nAEpRePart      (number a, number b, const coeffs r); // nachgicken
+number  nAEpImPart      (number a, number b, const coeffs r); // nachgicken
+
+void    nAEpWriteLong   (number &a, const coeffs r);//
+void    nAEpWriteShort  (number &a, const coeffs r);//
+
+
+const char *  nAEpRead  (const char *s, number *a, const coeffs r);
+number nAEpNormalize    (number a, number b, const coeffs r);//
+BOOLEAN nAEpGreater     (number a, number b, const coeffs r);//
+BOOLEAN nAEpEqual       (number a, number b, const coeffs r);
+BOOLEAN nAEpIsZero      (number a, const coeffs r);
+BOOLEAN nAEpIsOne       (number a, const coeffs r);
+BOOLEAN nAEpIsMOne      (number a, const coeffs r);
+BOOLEAN nAEpGreaterZero (number a, number b, const coeffs r);
+void    nAEpPower       (number a, int i, number * result, const coeffs r);
+number nAEpGetDenom     (number &a, const coeffs r);//
+number nAEpGetNumerator (number &a, const coeffs r);//
+number nAEpGcd          (number a, number b, const coeffs r);
+number nAEpLcm          (number a, number b, const coeffs r);
+
+void    nAEpDelete       (number *a, const coeffs r);//
+number    nAEpSetMap      (number a, const coeffs r);//
+void    nAEpInpMult      (number &a ,number b, const coeffs r);//
+void    nAEpCoeffWrite   (const coeffs r, BOOLEAN details);//
+
+BOOLEAN nAEpClearContent  (number a, const coeffs r);//
+BOOLEAN nAEpClearDenominators  (number a, const coeffs r);//
+
+
+// DEFINITION DER FUNKTIONEN
+
+number  nAEpAdd(number a, number b, const coeffs)
+{
+    p_poly* f=reinterpret_cast<p_poly*> (a);
+    p_poly* g=reinterpret_cast<p_poly*> (b);
+    p_poly *res=new p_poly;
+    res->p_poly_set(*f);
+    res->p_poly_add_to(*g);
+    return (number) res;
+}
+
+number  nAEpMult(number a, number b, const coeffs)
+{
+    p_poly* f=reinterpret_cast<p_poly*> (a);
+    p_poly* g=reinterpret_cast<p_poly*> (b);
+    p_poly *res=new p_poly;
+    res->p_poly_set(*f);
+    res->p_poly_mult_n_to(*g);
+    return (number) res;
+}
+
+number  nAEpSub(number a, number b, const coeffs)
+{
+    p_poly* f=reinterpret_cast<p_poly*> (a);
+    p_poly* g=reinterpret_cast<p_poly*> (b);
+    p_poly *res=new p_poly;
+    res->p_poly_set(*f);
+    res->p_poly_sub_to(*g);
+    return (number) res;
+}
+
+
+number  nAEpDiv(number a, number b, const coeffs)
+{
+    p_poly* f=reinterpret_cast<p_poly*> (a);
+    p_poly* g=reinterpret_cast<p_poly*> (b);
+    p_poly *res=new p_poly;
+    p_poly *s=new p_poly;
+    res->p_poly_set(*f);
+    res->p_poly_div_to(*res,*s,*g);
+    return (number) res;
+}
+
+
+number  nAEpIntMod(number a, number, const coeffs)
+{
+    return a;
+}
+
+number  nAEpExactDiv(number a, number b, const coeffs)
+{
+    p_poly* f=reinterpret_cast<p_poly*> (a);
+    p_poly* g=reinterpret_cast<p_poly*> (b);
+    p_poly *res=new p_poly;
+    p_poly *s=new p_poly;
+    res->p_poly_set(*f);
+    res->p_poly_div_to(*res,*s,*g);
+    return (number) res;
+}
+
+
+
+number nAEpInit(long i, const coeffs)
+{
+    int j=7;
+    mpz_t m;
+    mpz_init_set_ui(m, i);
+    p_poly* res=new p_poly;
+    res->p_poly_set(m, j);
+    number res1=reinterpret_cast<number>(res);
+    return  res1;
+}
+
+number nAEpInitMPZ(mpz_t m, const coeffs)
+{
+    int j=7;
+    p_poly* res=new p_poly;
+    res->p_poly_set(m, j);
+    number res1=reinterpret_cast<number>(res);
+    return  res1;
+
+}
+
+int nAEpSize (number a, const coeffs)
+{
+    p_poly* f=reinterpret_cast<p_poly*> (a);
+    return f->deg;
+}
+
+int nAEpInt(number &, const coeffs)
+{
+    return 1;
+}
+
+
+number nAEpMPZ(number a, const coeffs)
+{
+    return a;
+}
+
+
+number nAEpNeg(number c, const coeffs)
+{
+    p_poly* f=reinterpret_cast<p_poly*> (c);
+    p_poly *res=new p_poly;
+    res->p_poly_set(*f);
+    res->p_poly_neg();
+    return (number) res;
+}
+
+number nAEpCopy(number c, const coeffs)
+{
+    return c;
+}
+
+number nAEpRePart(number c, const coeffs)
+{
+    return c;
+}
+
+number nAEpImPart(number c, const coeffs)
+{
+    return  c;
+}
+
+void    nAEpWriteLong   (number &a, const coeffs)
+{
+    p_poly* f=reinterpret_cast <p_poly*>(a);
+    f->p_poly_print();
+
+    return;
+}
+
+void    nAEpWriteShort  (number &a, const coeffs)
+{
+    p_poly* f=reinterpret_cast <p_poly*>(a);
+    f->p_poly_print();
+    return ;
+}
+
+
+const char *  nAEpRead  (const char *, number *a, const coeffs)
+{
+    p_poly& f=reinterpret_cast <p_poly&>(a);
+    f.p_poly_insert();
+    f.p_poly_print();
+    *a=reinterpret_cast <number>(&f);
+    char* c=new char;
+    *c='c';
+    return c;
+}
+
+number nAEpNormalize    (number a, number, const coeffs) // ?
+{
+    return a;
+}
+
+BOOLEAN nAEpGreater     (number a, number b, const coeffs)
+{
+    p_poly* f=reinterpret_cast<p_poly*> (a);
+    p_poly* g=reinterpret_cast<p_poly*> (b);
+    if (f->deg > g->deg) {return FALSE;}
+    else {return TRUE;}
+}
+
+BOOLEAN nAEpEqual     (number a, number b, const coeffs)
+{
+    p_poly* f=reinterpret_cast<p_poly*> (a);
+    p_poly* g=reinterpret_cast<p_poly*> (b);
+    if (f->is_equal(*g) == 1) {return FALSE;}
+    else {return TRUE;}
+}
+
+BOOLEAN nAEpIsZero      (number a, const coeffs)
+{
+    p_poly* f=reinterpret_cast<p_poly*> (a);
+    if (f->is_zero() == 1) {return FALSE;}
+    else {return TRUE;}
+}
+
+BOOLEAN nAEpIsOne      (number a, const coeffs)
+{
+    p_poly* f=reinterpret_cast<p_poly*> (a);
+    if (f->is_one() == 1) {return FALSE;}
+    else {return TRUE;}
+}
+
+BOOLEAN nAEpIsMOne      (number a, const coeffs r)
+{
+    number b=nAEpNeg(a, r);
+    p_poly* f=reinterpret_cast<p_poly*> (b);
+    if (f->is_one() == 1) {return FALSE;}
+    else {return TRUE;}
+}
+
+BOOLEAN nAEpGreaterZero     (number a, const coeffs r)
+{
+    if (nAEpIsZero(a, r) == FALSE) { return TRUE; }
+    else { return FALSE; }
+}
+
+void    nAEpPower       (number, int, number *, const coeffs)
+{
+    return;
+}
+
+number nAEpGetDenom      (number &, const coeffs)
+{
+    return (number) 1;
+}
+
+number nAEpGetNumerator      (number &a, const coeffs)
+{
+    return a;
+}
+
+number nAEpGcd           (number a, number b, const coeffs)
+{
+    p_poly* f=reinterpret_cast<p_poly*> (a);
+    p_poly* g=reinterpret_cast<p_poly*> (b);
+    p_poly *res=new p_poly;
+    res->p_poly_gcd(*f,*g);
+    return (number) res;
+}
+
+number nAEpLcm          (number a, number b, const coeffs)
+{
+    p_poly* f=reinterpret_cast<p_poly*> (a);
+    p_poly* g=reinterpret_cast<p_poly*> (b);
+    p_poly *gcd=new p_poly;
+    p_poly *res=new p_poly;
+    p_poly *s=new p_poly;
+    gcd->p_poly_gcd(*f,*g);
+    res->p_poly_mult_n(*f,*g);
+    res->p_poly_div_to(*res,*s,*gcd);
+    return (number) res;
+}
+
+void    nAEpDelete       (number *, const coeffs)
+{
+    return;
+}
+
+/*
+number    nAEpSetMap        (number a, const coeffs)
+{
+        return a;
+}
+*/
+
+void    nAEpInpMult       (number &a, number b, const coeffs)
+{
+    p_poly* f=reinterpret_cast<p_poly*> (a);
+    p_poly* g=reinterpret_cast<p_poly*> (b);
+    f->p_poly_mult_n_to(*g);
+    a=(number) f;
+    return ;
+}
+
+void    nAEpCoeffWrite   (const coeffs, BOOLEAN)
+{
+    return;
+}
+
+BOOLEAN nAEpClearContent  (number, const coeffs)
+{
+    return FALSE;
+}
+
+BOOLEAN nAEpClearDenominators  (number, const coeffs)
+{
+    return FALSE;
+}
+
+
+
+//INITIALISIERUNG FÜR SINGULAR
+
+
+BOOLEAN n_pAEInitChar(coeffs r, void *p)
+{
+    // r->is_field, is_domain
+    //Charakteristik abgreifen!
+    const int c = (int) (long) p;
+
+
+    r->ch=c;
+    r->cfKillChar=NULL;
+    //r->nCoeffIsEqual=ndCoeffIsEqual;
+    r->cfMult  = nAEpMult;
+    r->cfSub   = nAEpSub;
+    r->cfAdd   = nAEpAdd;
+    r->cfDiv   = nAEpDiv;
+    r->cfIntMod= nAEpIntMod;
+    r->cfExactDiv= nAEpExactDiv;
+    r->cfInit = nAEpInit;
+    r->cfSize  = nAEpSize;
+    r->cfInt  = nAEpInt;
+#ifdef HAVE_RINGS
+    //r->cfDivComp = NULL; // only for ring stuff
+    //r->cfIsUnit = NULL; // only for ring stuff
+    //r->cfGetUnit = NULL; // only for ring stuff
+    //r->cfExtGcd = NULL; // only for ring stuff
+    // r->cfDivBy = NULL; // only for ring stuff
+#endif
+    r->cfInpNeg   = nAEpNeg;
+    r->cfInvers= NULL;
+    //r->cfCopy  = ndCopy;
+    //r->cfRePart = ndCopy;
+    //r->cfImPart = ndReturn0;
+    r->cfWriteLong = nAEpWriteLong;
+    r->cfRead = nAEpRead;
+    //r->cfNormalize=ndNormalize;
+    r->cfGreater = nAEpGreater;
+    r->cfEqual = nAEpEqual;
+    r->cfIsZero = nAEpIsZero;
+    r->cfIsOne = nAEpIsOne;
+    r->cfIsMOne = nAEpIsOne;
+    r->cfGreaterZero = nAEpGreaterZero;
+    r->cfPower = nAEpPower; // ZU BEARBEITEN
+    r->cfGetDenom = nAEpGetDenom;
+    r->cfGetNumerator = nAEpGetNumerator;
+    r->cfGcd  = nAEpGcd;
+    r->cfLcm  = nAEpLcm; // ZU BEARBEITEN
+    r->cfDelete= nAEpDelete;
+
+    r->cfSetMap = npSetMap; // extern nMapFunc npSetMap(const coeffs src, const coeffs dst); // FIXME: WHY??? // TODO: this seems to be a bug!
+
+    r->cfInpMult=nAEpInpMult; //????
+    r->cfCoeffWrite=nAEpCoeffWrite; //????
+
+
+    // the variables:
+    r->nNULL = (number) 0;
+    //r->type = n_AE;
+    r->ch = c;
+    r->has_simple_Alloc=TRUE;
+    r->has_simple_Inverse=TRUE;
+    return FALSE;
+}
+#endif
diff --git a/libpolys/coeffs/OPAEp.h b/libpolys/coeffs/OPAEp.h
new file mode 100644
index 0000000..3c53ee3
--- /dev/null
+++ b/libpolys/coeffs/OPAEp.h
@@ -0,0 +1,16 @@
+#ifndef OPAEP_H
+#define OPAEP_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+
+#include <misc/auxiliary.h>
+
+struct n_Procs_s; typedef struct  n_Procs_s  *coeffs;
+struct snumber; typedef struct snumber *   number;
+
+#ifdef SINGULAR_4_1
+BOOLEAN n_pAEInitChar(coeffs , void *);
+#endif
+
+#endif
diff --git a/libpolys/coeffs/bigintmat.cc b/libpolys/coeffs/bigintmat.cc
new file mode 100644
index 0000000..e61a95d
--- /dev/null
+++ b/libpolys/coeffs/bigintmat.cc
@@ -0,0 +1,2499 @@
+/*****************************************
+ *  Computer Algebra System SINGULAR      *
+ *****************************************/
+/*
+ *  * ABSTRACT: class bigintmat: matrices of numbers.
+ *   * a few functinos might be limited to bigint or euclidean rings.
+ *    */
+
+
+#include <misc/auxiliary.h>
+
+#include "bigintmat.h"
+#include <misc/intvec.h>
+
+#include "rmodulon.h"
+
+#include <math.h>
+#include <string.h>
+
+///create Z/nA of type n_Zn
+static coeffs numbercoeffs(number n, coeffs c) // TODO: FIXME: replace with n_CoeffRingQuot1
+{
+  mpz_t p;
+  number2mpz(n, c, p);
+  ZnmInfo *pp = new ZnmInfo;
+  pp->base = p;
+  pp->exp = 1;
+  coeffs nc = nInitChar(n_Zn, (void*)pp);
+  mpz_clear(p);
+  delete pp;
+  return nc;
+}
+
+//#define BIMATELEM(M,I,J) (M)[ (M).index(I,J) ]
+
+bigintmat * bigintmat::transpose()
+{
+  bigintmat * t = new bigintmat(col, row, basecoeffs());
+  for (int i=1; i<=row; i++)
+  {
+    for (int j=1; j<=col; j++)
+    {
+      t->set(j, i, BIMATELEM(*this,i,j));
+    }
+  }
+  return t;
+}
+
+void bigintmat::inpTranspose()
+{
+  int n = row,
+      m = col,
+      nm = n<m?n : m; // the min, describing the square part of the matrix
+  //CF: this is not optimal, but so far, it seems to work
+
+#define swap(_i, _j)        \
+  int __i = (_i), __j=(_j); \
+  number c = v[__i];        \
+  v[__i] = v[__j];          \
+  v[__j] = c                \
+
+  for (int i=0; i< nm; i++)
+    for (int j=i+1; j< nm; j++) {
+      swap(i*m+j, j*n+i);
+    }
+  if (n<m)
+    for (int i=nm; i<m; i++)
+      for(int j=0; j<n; j++) {
+        swap(j*n+i, i*m+j);
+      }
+  if (n>m)
+    for (int i=nm; i<n; i++)
+      for(int j=0; j<m; j++) {
+        swap(i*m+j, j*n+i);
+      }
+#undef swap
+  row = m;
+  col = n;
+}
+
+
+// Beginnt bei [0]
+void bigintmat::set(int i, number n, const coeffs C)
+{
+  assume (C == NULL || C == basecoeffs());
+
+  rawset(i, n_Copy(n, basecoeffs()), basecoeffs());
+}
+
+// Beginnt bei [1,1]
+void bigintmat::set(int i, int j, number n, const coeffs C)
+{
+  assume (C == NULL || C == basecoeffs());
+  assume (i > 0 && j > 0);
+  assume (i <= rows() && j <= cols());
+  set(index(i, j), n, C);
+}
+
+number bigintmat::get(int i) const
+{
+  assume (i >= 0);
+  assume (i<rows()*cols());
+
+  return n_Copy(v[i], basecoeffs());
+}
+
+number bigintmat::view(int i) const
+{
+  assume (i >= 0);
+  assume (i<rows()*cols());
+
+  return v[i];
+}
+
+number bigintmat::get(int i, int j) const
+{
+  assume (i > 0 && j > 0);
+  assume (i <= rows() && j <= cols());
+
+  return get(index(i, j));
+}
+
+number bigintmat::view(int i, int j) const
+{
+  assume (i >= 0 && j >= 0);
+  assume (i <= rows() && j <= cols());
+
+  return view(index(i, j));
+}
+// Ueberladener *=-Operator (für int und bigint)
+// Frage hier: *= verwenden oder lieber = und * einzeln?
+void bigintmat::operator*=(int intop)
+{
+  number iop = n_Init(intop, basecoeffs());
+
+  inpMult(iop, basecoeffs());
+
+  n_Delete(&iop, basecoeffs());
+}
+
+void bigintmat::inpMult(number bintop, const coeffs C)
+{
+  assume (C == NULL || C == basecoeffs());
+
+  const int l = rows() * cols();
+
+  for (int i=0; i < l; i++)
+    n_InpMult(v[i], bintop, basecoeffs());
+}
+
+// Stimmen Parameter?
+// Welche der beiden Methoden?
+// Oder lieber eine comp-Funktion?
+
+bool operator==(const bigintmat & lhr, const bigintmat & rhr)
+{
+  if (&lhr == &rhr) { return true; }
+  if (lhr.cols() != rhr.cols()) { return false; }
+  if (lhr.rows() != rhr.rows()) { return false; }
+  if (lhr.basecoeffs() != rhr.basecoeffs()) { return false; }
+
+  const int l = (lhr.rows())*(lhr.cols());
+
+  for (int i=0; i < l; i++)
+  {
+    if (!n_Equal(lhr[i], rhr[i], lhr.basecoeffs())) { return false; }
+  }
+
+  return true;
+}
+
+bool operator!=(const bigintmat & lhr, const bigintmat & rhr)
+{
+  return !(lhr==rhr);
+}
+
+// Matrix-Add/-Sub/-Mult so oder mit operator+/-/* ?
+bigintmat * bimAdd(bigintmat * a, bigintmat * b)
+{
+  if (a->cols() != b->cols()) return NULL;
+  if (a->rows() != b->rows()) return NULL;
+  if (a->basecoeffs() != b->basecoeffs()) { return NULL; }
+
+  const coeffs basecoeffs = a->basecoeffs();
+
+  int i;
+
+  bigintmat * bim = new bigintmat(a->rows(), a->cols(), basecoeffs);
+
+  for (i=a->rows()*a->cols()-1;i>=0; i--)
+    bim->rawset(i, n_Add((*a)[i], (*b)[i], basecoeffs), basecoeffs);
+
+  return bim;
+}
+bigintmat * bimAdd(bigintmat * a, int b)
+{
+
+  const int mn = a->rows()*a->cols();
+
+  const coeffs basecoeffs = a->basecoeffs();
+  number bb=n_Init(b,basecoeffs);
+
+  int i;
+
+  bigintmat * bim = new bigintmat(a->rows(),a->cols() , basecoeffs);
+
+  for (i=0; i<mn; i++)
+    bim->rawset(i, n_Add((*a)[i], bb, basecoeffs), basecoeffs);
+
+  n_Delete(&bb,basecoeffs);
+  return bim;
+}
+
+bigintmat * bimSub(bigintmat * a, bigintmat * b)
+{
+  if (a->cols() != b->cols()) return NULL;
+  if (a->rows() != b->rows()) return NULL;
+  if (a->basecoeffs() != b->basecoeffs()) { return NULL; }
+
+  const coeffs basecoeffs = a->basecoeffs();
+
+  int i;
+
+  bigintmat * bim = new bigintmat(a->rows(), a->cols(), basecoeffs);
+
+  for (i=a->rows()*a->cols()-1;i>=0; i--)
+    bim->rawset(i, n_Sub((*a)[i], (*b)[i], basecoeffs), basecoeffs);
+
+  return bim;
+}
+
+bigintmat * bimSub(bigintmat * a, int b)
+{
+  const int mn = a->rows()*a->cols();
+
+  const coeffs basecoeffs = a->basecoeffs();
+  number bb=n_Init(b,basecoeffs);
+
+  int i;
+
+  bigintmat * bim = new bigintmat(a->rows(),a->cols() , basecoeffs);
+
+  for (i=0; i<mn; i++)
+    bim->rawset(i, n_Sub((*a)[i], bb, basecoeffs), basecoeffs);
+
+  n_Delete(&bb,basecoeffs);
+  return bim;
+}
+
+//TODO: make special versions for certain rings!
+bigintmat * bimMult(bigintmat * a, bigintmat * b)
+{
+  const int ca = a->cols();
+  const int cb = b->cols();
+
+  const int ra = a->rows();
+  const int rb = b->rows();
+
+  if (ca != rb)
+  {
+#ifndef SING_NDEBUG
+    Werror("wrong bigintmat sizes at multiplication a * b: acols: %d != brows: %d\n", ca, rb);
+#endif
+    return NULL;
+  }
+
+  assume (ca == rb);
+
+  if (a->basecoeffs() != b->basecoeffs()) { return NULL; }
+
+  const coeffs basecoeffs = a->basecoeffs();
+
+  int i, j, k;
+
+  number sum;
+
+  bigintmat * bim = new bigintmat(ra, cb, basecoeffs);
+
+  for (i=1; i<=ra; i++)
+    for (j=1; j<=cb; j++)
+    {
+      sum = n_Init(0, basecoeffs);
+
+      for (k=1; k<=ca; k++)
+      {
+        number prod = n_Mult( BIMATELEM(*a, i, k), BIMATELEM(*b, k, j), basecoeffs);
+
+        number sum2 = n_Add(sum, prod, basecoeffs); // no inplace add :(
+
+        n_Delete(&sum, basecoeffs); n_Delete(&prod, basecoeffs);
+
+        sum = sum2;
+      }
+      bim->rawset(i, j, sum, basecoeffs);
+    }
+  return bim;
+}
+
+bigintmat * bimMult(bigintmat * a, int b)
+{
+
+  const int mn = a->rows()*a->cols();
+
+  const coeffs basecoeffs = a->basecoeffs();
+  number bb=n_Init(b,basecoeffs);
+
+  int i;
+
+  bigintmat * bim = new bigintmat(a->rows(),a->cols() , basecoeffs);
+
+  for (i=0; i<mn; i++)
+    bim->rawset(i, n_Mult((*a)[i], bb, basecoeffs), basecoeffs);
+
+  n_Delete(&bb,basecoeffs);
+  return bim;
+}
+
+bigintmat * bimMult(bigintmat * a, number b, const coeffs cf)
+{
+  if (cf!=a->basecoeffs()) return NULL;
+
+  const int mn = a->rows()*a->cols();
+
+  const coeffs basecoeffs = a->basecoeffs();
+
+  int i;
+
+  bigintmat * bim = new bigintmat(a->rows(),a->cols() , basecoeffs);
+
+  for (i=0; i<mn; i++)
+    bim->rawset(i, n_Mult((*a)[i], b, basecoeffs), basecoeffs);
+
+  return bim;
+}
+
+// ----------------------------------------------------------------- //
+// Korrekt?
+
+intvec * bim2iv(bigintmat * b)
+{
+  intvec * iv = new intvec(b->rows(), b->cols(), 0);
+  for (int i=0; i<(b->rows())*(b->cols()); i++)
+    (*iv)[i] = n_Int((*b)[i], b->basecoeffs()); // Geht das so?
+  return iv;
+}
+
+bigintmat * iv2bim(intvec * b, const coeffs C)
+{
+  const int l = (b->rows())*(b->cols());
+  bigintmat * bim = new bigintmat(b->rows(), b->cols(), C);
+
+  for (int i=0; i < l; i++)
+    bim->rawset(i, n_Init((*b)[i], C), C);
+
+  return bim;
+}
+
+// ----------------------------------------------------------------- //
+
+int bigintmat::compare(const bigintmat* op) const
+{
+  assume (basecoeffs() == op->basecoeffs() );
+
+#ifndef SING_NDEBUG
+  if (basecoeffs() != op->basecoeffs() )
+    WerrorS("wrong bigintmat comparison: different basecoeffs!\n");
+#endif
+
+  if ((col!=1) ||(op->cols()!=1))
+  {
+    if((col!=op->cols())
+       || (row!=op->rows()))
+      return -2;
+  }
+
+  int i;
+  for (i=0; i<si_min(row*col,op->rows()*op->cols()); i++)
+  {
+    if ( n_Greater(v[i], (*op)[i], basecoeffs()) )
+      return 1;
+    else if (! n_Equal(v[i], (*op)[i], basecoeffs()))
+      return -1;
+  }
+
+  for (; i<row; i++)
+  {
+    if ( n_GreaterZero(v[i], basecoeffs()) )
+      return 1;
+    else if (! n_IsZero(v[i], basecoeffs()) )
+      return -1;
+  }
+  for (; i<op->rows(); i++)
+  {
+    if ( n_GreaterZero((*op)[i], basecoeffs()) )
+      return -1;
+    else if (! n_IsZero((*op)[i], basecoeffs()) )
+      return 1;
+  }
+  return 0;
+}
+
+
+bigintmat * bimCopy(const bigintmat * b)
+{
+  if (b == NULL)
+    return NULL;
+
+  return new bigintmat(b);
+}
+
+void bigintmat::Write()
+{
+  int n = cols(), m=rows();
+
+  StringAppendS("[ ");
+  for(int i=1; i<= m; i++) {
+    StringAppendS("[ ");
+    for(int j=1; j< n; j++) {
+      n_Write(v[(i-1)*n+j-1], basecoeffs());
+      StringAppendS(", ");
+    }
+    if (n) n_Write(v[i*n-1], basecoeffs());
+    StringAppendS(" ]");
+    if (i<m) {
+      StringAppendS(", ");
+    }
+  }
+  StringAppendS(" ] ");
+}
+
+char* bigintmat::String()
+{
+  StringSetS("");
+  Write();
+  return StringEndS();
+}
+
+void bigintmat::Print()
+{
+  char * s = String();
+  PrintS(s);
+  omFree(s);
+}
+
+
+char* bigintmat::StringAsPrinted()
+{
+  if ((col==0) || (row==0))
+    return NULL;
+  else
+  {
+    int * colwid = getwid(80);
+    if (colwid == NULL)
+    {
+      WerrorS("not enough space to print bigintmat");
+      WerrorS("try string(...) for a unformatted output");
+      return NULL;
+    }
+    char * ps;
+    int slength = 0;
+    for (int j=0; j<col; j++)
+      slength += colwid[j]*row;
+    slength += col*row+row;
+    ps = (char*) omAlloc0(sizeof(char)*(slength));
+    int pos = 0;
+    for (int i=0; i<col*row; i++)
+    {
+      StringSetS("");
+      n_Write(v[i], basecoeffs());
+      char * ts = StringEndS();
+      const int _nl = strlen(ts);
+      int cj = i%col;
+      if (_nl > colwid[cj])
+      {
+        StringSetS("");
+        int ci = i/col;
+        StringAppend("[%d,%d]", ci+1, cj+1);
+        char * ph = StringEndS();
+        int phl = strlen(ph);
+        if (phl > colwid[cj])
+        {
+          for (int j=0; j<colwid[cj]-1; j++)
+            ps[pos+j] = ' ';
+          ps[pos+colwid[cj]-1] = '*';
+        }
+        else
+        {
+          for (int j=0; j<colwid[cj]-phl; j++)
+            ps[pos+j] = ' ';
+          for (int j=0; j<phl; j++)
+            ps[pos+colwid[cj]-phl+j] = ph[j];
+        }
+        omFree(ph);
+    }
+    else  // Mit Leerzeichen auffüllen und zahl reinschreiben
+    {
+      for (int j=0; j<(colwid[cj]-_nl); j++)
+        ps[pos+j] = ' ';
+      for (int j=0; j<_nl; j++)
+        ps[pos+colwid[cj]-_nl+j] = ts[j];
+    }
+    // ", " und (evtl) "\n" einfügen
+    if ((i+1)%col == 0)
+    {
+      if (i != col*row-1)
+      {
+        ps[pos+colwid[cj]] = ',';
+        ps[pos+colwid[cj]+1] = '\n';
+        pos += colwid[cj]+2;
+      }
+    }
+    else
+    {
+      ps[pos+colwid[cj]] = ',';
+      pos += colwid[cj]+1;
+    }
+
+      omFree(ts);  // Hier ts zerstören
+  }
+  return(ps);
+  // omFree(ps);
+}
+}
+
+static int intArrSum(int * a, int length)
+{
+  int sum = 0;
+  for (int i=0; i<length; i++)
+    sum += a[i];
+  return sum;
+}
+
+static int findLongest(int * a, int length)
+{
+  int l = 0;
+  int index;
+  for (int i=0; i<length; i++)
+  {
+    if (a[i] > l)
+    {
+      l = a[i];
+      index = i;
+    }
+  }
+  return index;
+}
+
+static int getShorter (int * a, int l, int j, int cols, int rows)
+{
+  int sndlong = 0;
+  int min;
+  for (int i=0; i<rows; i++)
+  {
+    int index = cols*i+j;
+    if ((a[index] > sndlong) && (a[index] < l))
+    {
+      min = floor(log10((double)cols))+floor(log10((double)rows))+5;
+      if ((a[index] < min) && (min < l))
+        sndlong = min;
+      else
+        sndlong = a[index];
+    }
+  }
+  if (sndlong == 0)
+  {
+    min = floor(log10((double)cols))+floor(log10((double)rows))+5;
+    if (min < l)
+      sndlong = min;
+    else
+      sndlong = 1;
+  }
+  return sndlong;
+}
+
+
+int * bigintmat::getwid(int maxwid)
+{
+  int const c = /*2**/(col-1)+1;
+  if (col + c > maxwid-1) return NULL;
+  int * wv = (int*)omAlloc(sizeof(int)*col*row);
+  int * cwv = (int*)omAlloc(sizeof(int)*col);
+  for (int j=0; j<col; j++)
+  {
+    cwv[j] = 0;
+    for (int i=0; i<row; i++)
+    {
+      StringSetS("");
+      n_Write(v[col*i+j], basecoeffs());
+      char * tmp = StringEndS();
+      const int _nl = strlen(tmp);
+      wv[col*i+j] = _nl;
+      if (_nl > cwv[j])
+        cwv[j]=_nl;
+        omFree(tmp);
+    }
+  }
+
+  // Groesse verkleinern, bis < maxwid
+  while (intArrSum(cwv, col)+c > maxwid)
+  {
+    int j = findLongest(cwv, col);
+    cwv[j] = getShorter(wv, cwv[j], j, col, row);
+  }
+  omFree(wv);
+return cwv;
+}
+
+void bigintmat::pprint(int maxwid)
+{
+  if ((col==0) || (row==0))
+    PrintS("");
+  else
+  {
+    int * colwid = getwid(maxwid);
+    if (colwid == NULL)
+    {
+      WerrorS("not enough space to print bigintmat");
+      return;
+    }
+    char * ps;
+    int slength = 0;
+    for (int j=0; j<col; j++)
+      slength += colwid[j]*row;
+    slength += col*row+row;
+    ps = (char*) omAlloc0(sizeof(char)*(slength));
+    int pos = 0;
+    for (int i=0; i<col*row; i++)
+    {
+      StringSetS("");
+      n_Write(v[i], basecoeffs());
+      char * ts = StringEndS();
+      const int _nl = strlen(ts);
+      int cj = i%col;
+      if (_nl > colwid[cj])
+      {
+        StringSetS("");
+        int ci = i/col;
+        StringAppend("[%d,%d]", ci+1, cj+1);
+        char * ph = StringEndS();
+        int phl = strlen(ph);
+        if (phl > colwid[cj])
+        {
+          for (int j=0; j<colwid[cj]-1; j++)
+            ps[pos+j] = ' ';
+          ps[pos+colwid[cj]-1] = '*';
+        }
+        else
+        {
+          for (int j=0; j<colwid[cj]-phl; j++)
+            ps[pos+j] = ' ';
+          for (int j=0; j<phl; j++)
+            ps[pos+colwid[cj]-phl+j] = ph[j];
+        }
+          omFree(ph);
+      }
+      else  // Mit Leerzeichen auffüllen und zahl reinschreiben
+      {
+        for (int j=0; j<colwid[cj]-_nl; j++)
+          ps[pos+j] = ' ';
+        for (int j=0; j<_nl; j++)
+          ps[pos+colwid[cj]-_nl+j] = ts[j];
+      }
+      // ", " und (evtl) "\n" einfügen
+      if ((i+1)%col == 0)
+      {
+        if (i != col*row-1)
+        {
+          ps[pos+colwid[cj]] = ',';
+          ps[pos+colwid[cj]+1] = '\n';
+          pos += colwid[cj]+2;
+        }
+      }
+      else
+      {
+        ps[pos+colwid[cj]] = ',';
+        pos += colwid[cj]+1;
+      }
+
+      omFree(ts);  // Hier ts zerstören
+    }
+    PrintS(ps);
+    omFree(ps);
+  }
+}
+
+
+//swaps columns i and j
+void bigintmat::swap(int i, int j) {
+  if ((i <= col) && (j <= col) && (i>0) && (j>0)) {
+    number tmp;
+    number t;
+    for (int k=1; k<=row; k++) {
+      tmp = get(k, i);
+      t = view(k, j);
+      set(k, i, t);
+      set(k, j, tmp);
+      n_Delete(&tmp, basecoeffs());
+    }
+  } else
+    Werror("Error in swap");
+}
+
+void bigintmat::swaprow(int i, int j) {
+  if ((i <= row) && (j <= row) && (i>0) && (j>0)) {
+    number tmp;
+    number t;
+    for (int k=1; k<=col; k++) {
+      tmp = get(i, k);
+      t = view(j, k);
+      set(i, k, t);
+      set(j, k, tmp);
+      n_Delete(&tmp, basecoeffs());
+    }
+  }
+  else
+    Werror("Error in swaprow");
+}
+
+int bigintmat::findnonzero(int i)
+{
+  for (int j=1; j<=col; j++) {
+    if (!n_IsZero(view(i,j), basecoeffs()))
+    {
+      return j;
+    }
+  }
+  return 0;
+}
+
+int bigintmat::findcolnonzero(int j)
+{
+  for (int i=row; i>=1; i--) {
+    if (!n_IsZero(view(i,j), basecoeffs()))
+    {
+      return i;
+    }
+  }
+  return 0;
+}
+
+void bigintmat::getcol(int j, bigintmat *a)
+{
+  assume((j<=col) && (j>=1));
+  if (((a->rows() != row) || (a->cols() != 1)) && ((a->rows() != 1) || (a->cols() != row))) {
+    assume(0);
+    Werror("Error in getcol. Dimensions must agree!");
+    return;
+  }
+  if (!nCoeffs_are_equal(basecoeffs(), a->basecoeffs())) {
+    nMapFunc f = n_SetMap(basecoeffs(), a->basecoeffs());
+    number t1, t2;
+    for (int i=1; i<=row;i++) {
+    t1 = get(i,j);
+    t2 = f(t1, basecoeffs(), a->basecoeffs());
+    a->set(i-1,t1);
+    n_Delete(&t1, basecoeffs());
+    n_Delete(&t2, a->basecoeffs());
+  }
+    return;
+  }
+  number t1;
+  for (int i=1; i<=row;i++) {
+    t1 = view(i,j);
+    a->set(i-1,t1);
+  }
+}
+
+void bigintmat::getColRange(int j, int no, bigintmat *a)
+{
+  number t1;
+  for(int ii=0; ii< no; ii++) {
+    for (int i=1; i<=row;i++) {
+      t1 = view(i, ii+j);
+      a->set(i, ii+1, t1);
+    }
+  }
+}
+
+void bigintmat::getrow(int i, bigintmat *a)
+{
+  if ((i>row) || (i<1)) {
+    Werror("Error in getrow: Index out of range!");
+    return;
+  }
+  if (((a->rows() != 1) || (a->cols() != col)) && ((a->rows() != col) || (a->cols() != 1))) {
+    Werror("Error in getrow. Dimensions must agree!");
+    return;
+  }
+  if (!nCoeffs_are_equal(basecoeffs(), a->basecoeffs())) {
+    nMapFunc f = n_SetMap(basecoeffs(), a->basecoeffs());
+    number t1, t2;
+    for (int j=1; j<=col;j++) {
+      t1 = get(i,j);
+      t2 = f(t1, basecoeffs(), a->basecoeffs());
+      a->set(j-1,t2);
+      n_Delete(&t1, basecoeffs());
+      n_Delete(&t2, a->basecoeffs());
+    }
+    return;
+  }
+  number t1;
+  for (int j=1; j<=col;j++) {
+    t1 = get(i,j);
+    a->set(j-1,t1);
+    n_Delete(&t1, basecoeffs());
+  }
+}
+
+
+void bigintmat::setcol(int j, bigintmat *m)
+{
+   if ((j>col) || (j<1)) {
+    Werror("Error in setcol: Index out of range!");
+    return;
+  }
+  if (((m->rows() != row) || (m->cols() != 1)) && ((m->rows() != 1) || (m->cols() != row))) {
+    Werror("Error in setcol. Dimensions must agree!");
+    return;
+  }
+  if (!nCoeffs_are_equal(basecoeffs(), m->basecoeffs())) {
+    nMapFunc f = n_SetMap(m->basecoeffs(), basecoeffs());
+    number t1,t2;
+    for (int i=1; i<=row; i++) {
+      t1 = m->get(i-1);
+      t2 = f(t1, m->basecoeffs(),basecoeffs());
+      set(i, j, t2);
+      n_Delete(&t2, basecoeffs());
+      n_Delete(&t1, m->basecoeffs());
+    }
+    return;
+  }
+  number t1;
+  for (int i=1; i<=row; i++) {
+      t1 = m->view(i-1);
+      set(i, j, t1);
+  }
+}
+
+void bigintmat::setrow(int j, bigintmat *m) {
+  if ((j>row) || (j<1)) {
+    Werror("Error in setrow: Index out of range!");
+    return;
+  }
+  if (((m->rows() != 1) || (m->cols() != col)) && ((m->rows() != col) || (m->cols() != 1))) {
+    Werror("Error in setrow. Dimensions must agree!");
+    return;
+  }
+  if (!nCoeffs_are_equal(basecoeffs(), m->basecoeffs())) {
+    nMapFunc f = n_SetMap(m->basecoeffs(), basecoeffs());
+    number tmp1,tmp2;
+  for (int i=1; i<=col; i++) {
+      tmp1 = m->get(i-1);
+      tmp2 = f(tmp1, m->basecoeffs(),basecoeffs());
+      set(j, i, tmp2);
+      n_Delete(&tmp2, basecoeffs());
+      n_Delete(&tmp1, m->basecoeffs());
+  }
+    return;
+  }
+  number tmp;
+  for (int i=1; i<=col; i++) {
+      tmp = m->view(i-1);
+      set(j, i, tmp);
+  }
+
+}
+
+bool bigintmat::add(bigintmat *b)
+{
+  if ((b->rows() != row) || (b->cols() != col)) {
+    Werror("Error in bigintmat::add. Dimensions do not agree!");
+    return false;
+  }
+  if (!nCoeffs_are_equal(basecoeffs(), b->basecoeffs())) {
+    Werror("Error in bigintmat::add. coeffs do not agree!");
+    return false;
+  }
+  for (int i=1; i<=row; i++) {
+    for (int j=1; j<=col; j++) {
+      rawset(i, j, n_Add(b->view(i,j), view(i,j), basecoeffs()));
+    }
+  }
+  return true;
+}
+
+bool bigintmat::sub(bigintmat *b)
+{
+ if ((b->rows() != row) || (b->cols() != col)) {
+    Werror("Error in bigintmat::sub. Dimensions do not agree!");
+    return false;
+  }
+  if (!nCoeffs_are_equal(basecoeffs(), b->basecoeffs())) {
+    Werror("Error in bigintmat::sub. coeffs do not agree!");
+    return false;
+  }
+  for (int i=1; i<=row; i++) {
+    for (int j=1; j<=col; j++) {
+      rawset(i, j, n_Sub(view(i,j), b->view(i,j), basecoeffs()));
+    }
+  }
+  return true;
+}
+
+bool bigintmat::skalmult(number b, coeffs c)
+{
+  if (!nCoeffs_are_equal(c, basecoeffs()))
+  {
+    Werror("Wrong coeffs\n");
+    return false;
+  }
+  number t1, t2;
+  if ( n_IsOne(b,c)) return true;
+  for (int i=1; i<=row; i++)
+  {
+    for (int j=1; j<=col; j++)
+    {
+      t1 = view(i, j);
+      t2 = n_Mult(t1, b, basecoeffs());
+      rawset(i, j, t2);
+    }
+  }
+  return true;
+}
+
+bool bigintmat::addcol(int i, int j, number a, coeffs c)
+{
+  if ((i>col) || (j>col) || (i<1) || (j<1)) {
+    Werror("Error in addcol: Index out of range!");
+    return false;
+  }
+  if (!nCoeffs_are_equal(c, basecoeffs())) {
+    Werror("Error in addcol: coeffs do not agree!");
+    return false;
+  }
+  number t1, t2, t3, t4;
+  for (int k=1; k<=row; k++)
+  {
+    t1 = view(k, j);
+    t2 = view(k, i);
+    t3 = n_Mult(t1, a, basecoeffs());
+    t4 = n_Add(t3, t2, basecoeffs());
+    rawset(k, i, t4);
+    n_Delete(&t3, basecoeffs());
+  }
+  return true;
+}
+
+bool bigintmat::addrow(int i, int j, number a, coeffs c)
+{
+  if ((i>row) || (j>row) || (i<1) || (j<1)) {
+    Werror("Error in addrow: Index out of range!");
+    return false;
+  }
+  if (!nCoeffs_are_equal(c, basecoeffs())) {
+    Werror("Error in addrow: coeffs do not agree!");
+    return false;
+  }
+  number t1, t2, t3, t4;
+  for (int k=1; k<=col; k++)
+  {
+    t1 = view(j, k);
+    t2 = view(i, k);
+    t3 = n_Mult(t1, a, basecoeffs());
+    t4 = n_Add(t3, t2, basecoeffs());
+    rawset(i, k, t4);
+    n_Delete(&t3, basecoeffs());
+  }
+  return true;
+}
+
+void bigintmat::colskalmult(int i, number a, coeffs c) {
+  if ((i>=1) && (i<=col) && (nCoeffs_are_equal(c, basecoeffs()))) {
+    number t, tmult;
+    for (int j=1; j<=row; j++) {
+      t = view(j, i);
+      tmult = n_Mult(a, t, basecoeffs());
+      rawset(j, i, tmult);
+    }
+  }
+  else
+    Werror("Error in colskalmult");
+}
+
+void bigintmat::rowskalmult(int i, number a, coeffs c) {
+  if ((i>=1) && (i<=row) && (nCoeffs_are_equal(c, basecoeffs()))) {
+    number t, tmult;
+    for (int j=1; j<=col; j++) {
+      t = view(i, j);
+      tmult = n_Mult(a, t, basecoeffs());
+      rawset(i, j, tmult);
+    }
+  }
+  else
+    Werror("Error in rowskalmult");
+}
+
+void bigintmat::concatrow(bigintmat *a, bigintmat *b) {
+  int ay = a->cols();
+  int ax = a->rows();
+  int by = b->cols();
+  int bx = b->rows();
+  number tmp;
+  if (!((col == ay) && (col == by) && (ax+bx == row))) {
+    Werror("Error in concatrow. Dimensions must agree!");
+    return;
+  }
+  if (!(nCoeffs_are_equal(a->basecoeffs(), basecoeffs()) && nCoeffs_are_equal(b->basecoeffs(), basecoeffs()))) {
+    Werror("Error in concatrow. coeffs do not agree!");
+    return;
+  }
+  for (int i=1; i<=ax; i++) {
+    for (int j=1; j<=ay; j++) {
+      tmp = a->get(i,j);
+      set(i, j, tmp);
+      n_Delete(&tmp, basecoeffs());
+    }
+  }
+  for (int i=1; i<=bx; i++) {
+    for (int j=1; j<=by; j++) {
+      tmp = b->get(i,j);
+      set(i+ax, j, tmp);
+      n_Delete(&tmp, basecoeffs());
+    }
+  }
+}
+
+void bigintmat::extendCols(int i) {
+  bigintmat * tmp = new bigintmat(rows(), i, basecoeffs());
+  appendCol(tmp);
+  delete tmp;
+}
+void bigintmat::appendCol (bigintmat *a) {
+  coeffs R = basecoeffs();
+  int ay = a->cols();
+  int ax = a->rows();
+  assume(row == ax);
+
+  assume(nCoeffs_are_equal(a->basecoeffs(), R));
+
+  bigintmat * tmp = new bigintmat(rows(), cols() + ay, R);
+  tmp->concatcol(this, a);
+  this->swapMatrix(tmp);
+  delete tmp;
+}
+
+
+void bigintmat::concatcol (bigintmat *a, bigintmat *b) {
+  int ay = a->cols();
+  int ax = a->rows();
+  int by = b->cols();
+  int bx = b->rows();
+  number tmp;
+
+  assume(row==ax && row == bx && ay+by ==col);
+
+  assume(nCoeffs_are_equal(a->basecoeffs(), basecoeffs()) && nCoeffs_are_equal(b->basecoeffs(), basecoeffs()));
+
+  for (int i=1; i<=ax; i++) {
+    for (int j=1; j<=ay; j++) {
+      tmp = a->view(i,j);
+      set(i, j, tmp);
+    }
+  }
+  for (int i=1; i<=bx; i++) {
+    for (int j=1; j<=by; j++) {
+      tmp = b->view(i,j);
+      set(i, j+ay, tmp);
+    }
+  }
+}
+
+void bigintmat::splitrow(bigintmat *a, bigintmat *b) {
+  int ay = a->cols();
+  int ax = a->rows();
+  int by = b->cols();
+  int bx = b->rows();
+  number tmp;
+  if (!(ax + bx == row)) {
+    Werror("Error in splitrow. Dimensions must agree!");
+  }
+  else if (!((col == ay) && (col == by))) {
+    Werror("Error in splitrow. Dimensions must agree!");
+  }
+  else if (!(nCoeffs_are_equal(a->basecoeffs(), basecoeffs()) && nCoeffs_are_equal(b->basecoeffs(), basecoeffs()))) {
+    Werror("Error in splitrow. coeffs do not agree!");
+  }
+  else {
+    for(int i = 1; i<=ax; i++) {
+      for(int j = 1; j<=ay;j++) {
+        tmp = get(i,j);
+        a->set(i,j,tmp);
+        n_Delete(&tmp, basecoeffs());
+      }
+    }
+    for (int i =1; i<=bx; i++) {
+      for (int j=1;j<=col;j++) {
+        tmp = get(i+ax, j);
+        b->set(i,j,tmp);
+        n_Delete(&tmp, basecoeffs());
+      }
+    }
+  }
+}
+
+void bigintmat::splitcol(bigintmat *a, bigintmat *b) {
+  int ay = a->cols();
+  int ax = a->rows();
+  int by = b->cols();
+  int bx = b->rows();
+  number tmp;
+  if (!((row == ax) && (row == bx))) {
+    Werror("Error in splitcol. Dimensions must agree!");
+  }
+  else if (!(ay+by == col)) {
+    Werror("Error in splitcol. Dimensions must agree!");
+  }
+  else if (!(nCoeffs_are_equal(a->basecoeffs(), basecoeffs()) && nCoeffs_are_equal(b->basecoeffs(), basecoeffs()))) {
+    Werror("Error in splitcol. coeffs do not agree!");
+  }
+  else {
+    for (int i=1; i<=ax; i++) {
+      for (int j=1; j<=ay; j++) {
+        tmp = view(i,j);
+        a->set(i,j,tmp);
+      }
+    }
+    for (int i=1; i<=bx; i++) {
+      for (int j=1; j<=by; j++) {
+        tmp = view(i,j+ay);
+        b->set(i,j,tmp);
+      }
+    }
+  }
+}
+
+void bigintmat::splitcol(bigintmat *a, int i) {
+  number tmp;
+  if ((a->rows() != row) || (a->cols()+i-1 > col) || (i<1)) {
+    Werror("Error in splitcol. Dimensions must agree!");
+    return;
+  }
+  if (!(nCoeffs_are_equal(a->basecoeffs(), basecoeffs()))) {
+    Werror("Error in splitcol. coeffs do not agree!");
+    return;
+  }
+  int width = a->cols();
+  for (int j=1; j<=width; j++) {
+    for (int k=1; k<=row; k++) {
+      tmp = get(k, j+i-1);
+      a->set(k, j, tmp);
+      n_Delete(&tmp, basecoeffs());
+    }
+  }
+}
+
+void bigintmat::splitrow(bigintmat *a, int i) {
+  number tmp;
+  if ((a->cols() != col) || (a->rows()+i-1 > row) || (i<1)) {
+    Werror("Error in Marco-splitrow");
+    return;
+  }
+
+  if (!(nCoeffs_are_equal(a->basecoeffs(), basecoeffs()))) {
+    Werror("Error in splitrow. coeffs do not agree!");
+    return;
+  }
+  int height = a->rows();
+  for (int j=1; j<=height; j++) {
+    for (int k=1; k<=col; k++) {
+      tmp = view(j+i-1, k);
+      a->set(j, k, tmp);
+    }
+  }
+}
+
+bool bigintmat::copy(bigintmat *b)
+{
+  if ((b->rows() != row) || (b->cols() != col)) {
+    Werror("Error in bigintmat::copy. Dimensions do not agree!");
+    return false;
+  }
+  if (!nCoeffs_are_equal(basecoeffs(), b->basecoeffs())) {
+    Werror("Error in bigintmat::copy. coeffs do not agree!");
+    return false;
+  }
+  number t1;
+  for (int i=1; i<=row; i++)
+  {
+    for (int j=1; j<=col; j++)
+    {
+      t1 = b->view(i, j);
+      set(i, j, t1);
+    }
+  }
+  return true;
+}
+
+/// copy the submatrix of b, staring at (a,b) having n rows, m cols into
+/// the given matrix at pos. (c,d)
+/// needs c+n, d+m <= rows, cols
+///       a+n, b+m <= b.rows(), b.cols()
+void bigintmat::copySubmatInto(bigintmat *B, int a, int b, int n, int m, int c, int d)
+{
+  number t1;
+  for (int i=1; i<=n; i++)
+  {
+    for (int j=1; j<=m; j++)
+    {
+      t1 = B->view(a+i-1, b+j-1);
+      set(c+i-1, d+j-1, t1);
+    }
+  }
+}
+
+
+int bigintmat::isOne() {
+  coeffs r = basecoeffs();
+  if (row==col) {
+    for (int i=1; i<=row; i++) {
+      for (int j=1; j<=col; j++) {
+        if (i==j) {
+          if (!n_IsOne(view(i, j), r))
+            return 0;
+        }
+        else {
+          if (!n_IsZero(view(i,j), r))
+            return 0;
+        }
+      }
+    }
+  }
+  return 1;
+}
+
+
+void bigintmat::one() {
+  if (row==col) {
+    number one = n_Init(1, basecoeffs()),
+           zero = n_Init(0, basecoeffs());
+    for (int i=1; i<=row; i++) {
+      for (int j=1; j<=col; j++) {
+        if (i==j) {
+          set(i, j, one);
+        } else {
+          set(i, j, zero);
+        }
+      }
+    }
+    n_Delete(&one, basecoeffs());
+    n_Delete(&zero, basecoeffs());
+  }
+}
+
+void bigintmat::zero() {
+  number tmp = n_Init(0, basecoeffs());
+  for (int i=1; i<=row; i++) {
+    for (int j=1; j<=col; j++) {
+      set(i, j, tmp);
+    }
+  }
+  n_Delete(&tmp,basecoeffs());
+}
+
+int bigintmat::isZero() {
+  for (int i=1; i<=row; i++) {
+    for (int j=1; j<=col; j++) {
+      if (!n_IsZero(view(i,j), basecoeffs()))
+        return FALSE;
+    }
+  }
+  return TRUE;
+}
+//****************************************************************************
+//
+//****************************************************************************
+
+//used in the det function. No idea what it does.
+//looks like it return the submatrix where the i-th row
+//and j-th column has been removed in the LaPlace generic
+//determinant algorithm
+bigintmat *bigintmat::elim(int i, int j)
+{
+  if ((i<=0) || (i>row) || (j<=0) || (j>col))
+    return NULL;
+  int cx, cy;
+  cx=1;
+  cy=1;
+  number t;
+  bigintmat *b = new bigintmat(row-1, col-1, basecoeffs());
+  for (int k=1; k<=row; k++) {
+    if (k!=i)
+    {
+      cy=1;
+      for (int l=1; l<=col; l++)
+      {
+        if (l!=j)
+        {
+          t = get(k, l);
+          b->set(cx, cy, t);
+          n_Delete(&t, basecoeffs());
+          cy++;
+        }
+      }
+      cx++;
+    }
+  }
+  return b;
+}
+
+
+//returns d such that a/d is the inverse of the input
+//TODO: make work for p not prime using the euc stuff.
+//long term: rewrite for Z using p-adic lifting
+//and Dixon. Possibly even the sparse recent Storjohann stuff
+number bigintmat::pseudoinv(bigintmat *a) {
+
+  // Falls Matrix über reellen Zahlen nicht invertierbar, breche ab
+ assume((a->rows() == row) && (a->rows() == a->cols()) && (row == col));
+
+ number det = this->det(); //computes the HNF, so should e reused.
+ if ((n_IsZero(det, basecoeffs())))
+    return det;
+
+ // Hänge Einheitsmatrix über Matrix und wendet HNF an. An Stelle der Einheitsmatrix steht im Ergebnis die Transformationsmatrix dazu
+  a->one();
+  bigintmat *m = new bigintmat(2*row, col, basecoeffs());
+  m->concatrow(a,this);
+  m->hnf();
+  // Arbeite weiterhin mit der zusammengehängten Matrix
+  // Laufe durch die Diagonalelemente, und multipliziere jede Spalte rechts davon damit, speichere aber den alten Eintrag der Spalte, temp, der in der Zeile des Diagonalelements liegt, zwischen. Dann addiere das -temp-Fache der Diagonalspalte zur entsprechenenden Spalte rechts davon. Dadurch entsteht überall rechts der Diagonalen eine 0
+  number diag;
+  number temp, ttemp;
+  for (int i=1; i<=col; i++) {
+    diag = m->get(row+i, i);
+    for (int j=i+1; j<=col; j++) {
+      temp = m->get(row+i, j);
+      m->colskalmult(j, diag, basecoeffs());
+      temp = n_InpNeg(temp, basecoeffs());
+      m->addcol(j, i, temp, basecoeffs());
+      n_Delete(&temp, basecoeffs());
+    }
+    n_Delete(&diag, basecoeffs());
+  }
+  // Falls wir nicht modulo n arbeiten, können wir die Spalten durch den ggT teilen, um die Einträge kleiner zu bekommen
+  // Bei Z/n sparen wir uns das, da es hier sinnlos ist
+  number g;
+  number gcd;
+  for (int j=1; j<=col; j++) {
+    g = n_Init(0, basecoeffs());
+    for (int i=1; i<=2*row; i++) {
+      temp = m->get(i,j);
+      gcd = n_Gcd(g, temp, basecoeffs());
+      n_Delete(&g, basecoeffs());
+      n_Delete(&temp, basecoeffs());
+      g = n_Copy(gcd, basecoeffs());
+      n_Delete(&gcd, basecoeffs());
+    }
+    if (!(n_IsOne(g, basecoeffs())))
+      m->colskaldiv(j, g);
+    n_Delete(&g, basecoeffs());
+  }
+
+  // Nun müssen die Diagonalelemente durch Spaltenmultiplikation gleich gesett werden. Bei Z können wir mit dem kgV arbeiten, bei Z/n bringen wir jedes Diagonalelement auf 1 (wir arbeiten immer mit n = Primzahl. Für n != Primzahl muss noch an anderen Stellen etwas geändert werden)
+
+  g = n_Init(0, basecoeffs());
+  number prod = n_Init(1, basecoeffs());
+  for (int i=1; i<=col; i++) {
+    gcd = n_Gcd(g, m->get(row+i, i), basecoeffs());
+    n_Delete(&g, basecoeffs());
+    g = n_Copy(gcd, basecoeffs());
+    n_Delete(&gcd, basecoeffs());
+    ttemp = n_Copy(prod, basecoeffs());
+    temp = m->get(row+i, i);
+    n_Delete(&prod, basecoeffs());
+    prod = n_Mult(ttemp, temp, basecoeffs());
+    n_Delete(&ttemp, basecoeffs());
+    n_Delete(&temp, basecoeffs());
+  }
+  number lcm;
+  lcm = n_Div(prod, g, basecoeffs());
+  for (int j=1; j<=col; j++) {
+    ttemp = m->get(row+j,j);
+    temp = n_QuotRem(lcm, ttemp, NULL, basecoeffs());
+    m->colskalmult(j, temp, basecoeffs());
+    n_Delete(&ttemp, basecoeffs());
+    n_Delete(&temp, basecoeffs());
+  }
+  n_Delete(&lcm, basecoeffs());
+  n_Delete(&prod, basecoeffs());
+
+  number divisor = m->get(row+1, 1);
+  m->splitrow(a, 1);
+  delete m;
+  n_Delete(&det, basecoeffs());
+  return divisor;
+}
+
+number bigintmat::trace()
+{
+  assume (col == row);
+  number t = get(1,1),
+         h;
+  coeffs r = basecoeffs();
+  for(int i=2; i<= col; i++) {
+    h = n_Add(t, view(i,i), r);
+    n_Delete(&t, r);
+    t = h;
+  }
+  return t;
+}
+
+number bigintmat::det()
+{
+  assume (row==col);
+
+  if (col == 1)
+    return get(1, 1);
+  // should work as well in Z/pZ of type n_Zp?
+  // relies on XExtGcd and the other euc. functinos.
+  if ( getCoeffType(basecoeffs())== n_Z || getCoeffType(basecoeffs() )== n_Zn) {
+    return hnfdet();
+  }
+  number sum = n_Init(0, basecoeffs());
+  number t1, t2, t3, t4;
+  bigintmat *b;
+  for (int i=1; i<=row; i++) {
+    b = elim(i, 1);
+    t1 = get(i, 1);
+    t2 = b->det();
+    t3 = n_Mult(t1, t2, basecoeffs());
+    t4 = n_Copy(sum, basecoeffs());
+    n_Delete(&sum, basecoeffs());
+    if ((i+1)>>1<<1==(i+1))
+      sum = n_Add(t4, t3, basecoeffs());
+    else
+      sum = n_Sub(t4, t3, basecoeffs());
+    n_Delete(&t1, basecoeffs());
+    n_Delete(&t2, basecoeffs());
+    n_Delete(&t3, basecoeffs());
+    n_Delete(&t4, basecoeffs());
+  }
+  return sum;
+}
+
+number bigintmat::hnfdet()
+{
+  assume (col == row);
+
+  if (col == 1)
+    return get(1, 1);
+  bigintmat *m = new bigintmat(this);
+  m->hnf();
+  number prod = n_Init(1, basecoeffs());
+  number temp, temp2;
+  for (int i=1; i<=col; i++) {
+    temp = m->get(i, i);
+    temp2 = n_Mult(temp, prod, basecoeffs());
+    n_Delete(&prod, basecoeffs());
+    prod = temp2;
+    n_Delete(&temp, basecoeffs());
+  }
+  delete m;
+  return prod;
+}
+
+void bigintmat::swapMatrix(bigintmat *a)
+{
+  int n = rows(), m = cols();
+  row = a->rows();
+  col = a->cols();
+  number * V = v;
+  v = a->v;
+  a->v = V;
+  a->row = n;
+  a->col = m;
+}
+int bigintmat::colIsZero(int j)
+{
+  coeffs R = basecoeffs();
+  for(int i=1; i<=rows(); i++)
+    if (!n_IsZero(view(i, j), R)) return FALSE;
+  return TRUE;
+}
+
+void bigintmat::howell()
+{
+  coeffs R = basecoeffs();
+  hnf(); // as a starting point...
+  if (getCoeffType(R)== n_Z) return; //wrong, need to prune!
+
+  int n = cols(), m = rows(), i, j, k;
+
+  //make sure, the matrix has enough space. We need no rows+1 columns.
+  //The resulting Howell form will be pruned to be at most square.
+  bigintmat * t = new bigintmat(m, m+1, R);
+  t->copySubmatInto(this, 1, n>m ? n-m+1 : 1, m, n>m ? m : n, 1, n>m ? 2 : m+2-n  );
+  swapMatrix(t);
+  delete t;
+  for(i=1; i<= cols(); i++) {
+    if (!colIsZero(i)) break;
+  }
+  assume (i>1);
+  if (i>cols()) {
+    t = new bigintmat(rows(), 0, R);
+    swapMatrix(t);
+    delete t;
+    return; // zero matrix found, clearly normal.
+  }
+
+  int last_zero_col = i-1;
+  for (int c = cols(); c>0; c--) {
+    for(i=rows(); i>0; i--) {
+      if (!n_IsZero(view(i, c), R)) break;
+    }
+    if (i==0) break; // matrix SHOULD be zero from here on
+    number a = n_Ann(view(i, c), R);
+    addcol(last_zero_col, c, a, R);
+    n_Delete(&a, R);
+    for(j = c-1; j>last_zero_col; j--) {
+      for(k=rows(); k>0; k--) {
+        if (!n_IsZero(view(k, j), R)) break;
+        if (!n_IsZero(view(k, last_zero_col), R)) break;
+      }
+      if (k==0) break;
+      if (!n_IsZero(view(k, last_zero_col), R)) {
+        number gcd, co1, co2, co3, co4;
+        gcd = n_XExtGcd(view(k, last_zero_col), view(k, j), &co1, &co2, &co3, &co4, R);
+        if (n_Equal(gcd, view(k, j), R)) {
+          number q = n_Div(view(k, last_zero_col), gcd, R);
+          q = n_InpNeg(q, R);
+          addcol(last_zero_col, j, q, R);
+          n_Delete(&q, R);
+        } else if (n_Equal(gcd, view(k, last_zero_col), R)) {
+          swap(last_zero_col, k);
+          number q = n_Div(view(k, last_zero_col), gcd, R);
+          q = n_InpNeg(q, R);
+          addcol(last_zero_col, j, q, R);
+          n_Delete(&q, R);
+        } else {
+          coltransform(last_zero_col, j, co3, co4, co1, co2);
+        }
+        n_Delete(&gcd, R);
+        n_Delete(&co1, R);
+        n_Delete(&co2, R);
+        n_Delete(&co3, R);
+        n_Delete(&co4, R);
+      }
+    }
+    for(k=rows(); k>0; k--) {
+      if (!n_IsZero(view(k, last_zero_col), R)) break;
+    }
+    if (k) last_zero_col--;
+  }
+  t = new bigintmat(rows(), cols()-last_zero_col, R);
+  t->copySubmatInto(this, 1, last_zero_col+1, rows(), cols()-last_zero_col, 1, 1);
+  swapMatrix(t);
+  delete t;
+}
+
+void bigintmat::hnf()
+{
+  // Laufen von unten nach oben und von links nach rechts
+  // CF: TODO: for n_Z: write a recursive version. This one will
+  //     have exponential blow-up. Look at Michianchio
+  //     Alternatively, do p-adic det and modular method
+
+#if 0
+    char * s;
+    ::Print("mat over Z is \n");
+    ::Print("%s\n", s = nCoeffString(basecoeffs()));
+    omFree(s);
+    Print();
+    ::Print("\n(%d x %d)\n", rows(), cols());
+#endif
+
+  int i = rows();
+  int j = cols();
+  number q = n_Init(0, basecoeffs());
+  number one = n_Init(1, basecoeffs());
+  number minusone = n_Init(-1, basecoeffs());
+  number tmp1 = n_Init(0, basecoeffs());
+  number tmp2 = n_Init(0, basecoeffs());
+  number co1, co2, co3, co4;
+  number ggt = n_Init(0, basecoeffs());
+
+  while ((i>0) && (j>0)) {
+    // Falls erstes Nicht-Null-Element in Zeile i nicht existiert, oder hinter Spalte j vorkommt, gehe in nächste Zeile
+    if ((findnonzero(i)==0) || (findnonzero(i)>j)) {
+      i--;
+    } else {
+      // Laufe von links nach rechts durch die Zeile:
+      for (int l=1; l<=j-1; l++) {
+        n_Delete(&tmp1, basecoeffs());
+        tmp1 = get(i, l);
+        // Falls Eintrag (im folgenden x genannt) gleich 0, gehe eine Spalte weiter. Ansonsten...
+        if (!n_IsZero(tmp1, basecoeffs())) {
+          n_Delete(&tmp2, basecoeffs());
+          tmp2 = get(i, l+1);
+          // Falls Eintrag (i.f. y g.) rechts daneben gleich 0, tausche beide Spalten, sonst...
+          if (!n_IsZero(tmp2, basecoeffs())) {
+            n_Delete(&ggt, basecoeffs());
+            ggt = n_XExtGcd(tmp1, tmp2, &co1, &co2, &co3, &co4, basecoeffs());
+            // Falls x=ggT(x, y), tausche die beiden Spalten und ziehe die (neue) rechte Spalte so häufig von der linken ab, dass an der ehemaligen Stelle von x nun eine 0 steht. Dazu:
+            if (n_Equal(tmp1, ggt, basecoeffs())) {
+              swap(l, l+1);
+              n_Delete(&q, basecoeffs());
+              q = n_Div(tmp2, ggt, basecoeffs());
+              q = n_InpNeg(q, basecoeffs());
+              // Dann addiere das -q-fache der (neuen) rechten Spalte zur linken dazu. Damit erhalten wir die gewünschte 0
+
+              addcol(l, l+1, q, basecoeffs());
+              n_Delete(&q, basecoeffs());
+            }
+            else if (n_Equal(tmp1, minusone, basecoeffs())) {
+              // Falls x=-1, so ist x=-ggt(x, y). Dann gehe wie oben vor, multipliziere aber zuerst die neue rechte Spalte (die mit x) mit -1
+              // Die Berechnung von q (=y/ggt) entfällt, da ggt=1
+              swap(l, l+1);
+              colskalmult(l+1, minusone, basecoeffs());
+              tmp2 = n_InpNeg(tmp2, basecoeffs());
+              addcol(l, l+1, tmp2, basecoeffs());
+            }
+            else {
+              // CF: use the 2x2 matrix (co1, co2)(co3, co4) to
+              // get the gcd in position and the 0 in the other:
+#ifdef CF_DEB
+              ::Print("applying trafo\n");
+              StringSetS("");
+              n_Write(co1, basecoeffs()); StringAppendS("\t");
+              n_Write(co2, basecoeffs()); StringAppendS("\t");
+              n_Write(co3, basecoeffs()); StringAppendS("\t");
+              n_Write(co4, basecoeffs()); StringAppendS("\t");
+              ::Print("%s\nfor l=%d\n", StringEndS(), l);
+              {char * s = String();
+              ::Print("to %s\n", s);omFree(s);};
+#endif
+              coltransform(l, l+1, co3, co4, co1, co2);
+#ifdef CF_DEB
+              {char * s = String();
+              ::Print("gives %s\n", s);}
+#endif
+            }
+            n_Delete(&co1, basecoeffs());
+            n_Delete(&co2, basecoeffs());
+            n_Delete(&co3, basecoeffs());
+            n_Delete(&co4, basecoeffs());
+          }
+          else {
+            swap(l, l+1);
+          }
+          // Dann betrachte die vormals rechte Spalte als neue linke, und die rechts daneben als neue rechte.
+        }
+      }
+
+      // normalize by units:
+      if (!n_IsZero(view(i, j), basecoeffs())) {
+        number u = n_GetUnit(view(i, j), basecoeffs());
+        if (!n_IsOne(u, basecoeffs())) {
+          colskaldiv(j, u);
+        }
+        n_Delete(&u, basecoeffs());
+      }
+      // Zum Schluss mache alle Einträge rechts vom Diagonalelement betragsmäßig kleiner als dieses
+      for (int l=j+1; l<=col; l++) {
+        n_Delete(&q, basecoeffs());
+        q = n_QuotRem(view(i, l), view(i, j), NULL, basecoeffs());
+        q = n_InpNeg(q, basecoeffs());
+        addcol(l, j, q, basecoeffs());
+      }
+      i--;
+      j--;
+      // Dann betrachte die Zeile darüber und gehe dort wie vorher vor
+    }
+  }
+  n_Delete(&q, basecoeffs());
+  n_Delete(&tmp1, basecoeffs());
+  n_Delete(&tmp2, basecoeffs());
+  n_Delete(&ggt, basecoeffs());
+  n_Delete(&one, basecoeffs());
+  n_Delete(&minusone, basecoeffs());
+
+#if 0
+    ::Print("hnf over Z is \n");
+    Print();
+    ::Print("\n(%d x %d)\n", rows(), cols());
+#endif
+}
+
+bigintmat * bimChangeCoeff(bigintmat *a, coeffs cnew)
+{
+  coeffs cold = a->basecoeffs();
+  bigintmat *b = new bigintmat(a->rows(), a->cols(), cnew);
+  // Erzeugt Karte von alten coeffs nach neuen
+  nMapFunc f = n_SetMap(cold, cnew);
+  number t1;
+  number t2;
+  // apply map to all entries.
+  for (int i=1; i<=a->rows(); i++)
+  {
+    for (int j=1; j<=a->cols(); j++)
+    {
+      t1 = a->get(i, j);
+      t2 = f(t1, cold, cnew);
+      b->set(i, j, t2);
+      n_Delete(&t1, cold);
+      n_Delete(&t2, cnew);
+    }
+  }
+  return b;
+}
+
+//OK: a HNF of (this | p*I)
+//so the result will always have FULL rank!!!!
+//(This is different form a lift of the HNF mod p: consider the matrix (p)
+//to see the difference. It CAN be computed as HNF mod p^2 usually..)
+bigintmat * bigintmat::modhnf(number p, coeffs R)
+{
+  coeffs Rp = numbercoeffs(p, R); // R/pR
+  bigintmat *m = bimChangeCoeff(this, Rp);
+  m->howell();
+  bigintmat *a = bimChangeCoeff(m, R);
+  delete m;
+  bigintmat *C = new bigintmat(rows(), rows(), R);
+  int piv = rows(), i = a->cols();
+  while (piv) {
+    if (!i || n_IsZero(a->view(piv, i), R)) {
+      C->set(piv, piv, p, R);
+    } else {
+      C->copySubmatInto(a, 1, i, rows(), 1, 1, piv);
+      i--;
+    }
+    piv--;
+  }
+  delete a;
+  return C;
+}
+
+
+//exactly divide matrix by b
+void bigintmat::skaldiv(number b)
+{
+  number tmp1, tmp2;
+  for (int i=1; i<=row; i++)
+  {
+    for (int j=1; j<=col; j++)
+    {
+      tmp1 = view(i, j);
+      tmp2 = n_Div(tmp1, b, basecoeffs());
+      rawset(i, j, tmp2);
+    }
+  }
+}
+
+//exactly divide col j by b
+void bigintmat::colskaldiv(int j, number b)
+{
+  number tmp1, tmp2;
+  for (int i=1; i<=row; i++)
+  {
+    tmp1 = view(i, j);
+    tmp2 = n_Div(tmp1, b, basecoeffs());
+    rawset(i, j, tmp2);
+  }
+}
+
+// col(j, k) <- col(j,k)*matrix((a, c)(b, d))
+// mostly used internally in the hnf and Howell stuff
+void bigintmat::coltransform(int j, int k, number a, number b, number c, number d)
+{
+  number tmp1, tmp2, tmp3, tmp4;
+  for (int i=1; i<=row; i++)
+  {
+    tmp1 = get(i, j);
+    tmp2 = get(i, k);
+    tmp3 = n_Mult(tmp1, a, basecoeffs());
+    tmp4 = n_Mult(tmp2, b, basecoeffs());
+    n_InpAdd(tmp3, tmp4, basecoeffs());
+    n_Delete(&tmp4, basecoeffs());
+
+    n_InpMult(tmp1, c, basecoeffs());
+    n_InpMult(tmp2, d, basecoeffs());
+    n_InpAdd(tmp1, tmp2, basecoeffs());
+    n_Delete(&tmp2, basecoeffs());
+
+    set(i, j, tmp3);
+    set(i, k, tmp1);
+    n_Delete(&tmp1, basecoeffs());
+    n_Delete(&tmp3, basecoeffs());
+  }
+}
+
+
+
+//reduce all entries mod p. Does NOT change the coeffs type
+void bigintmat::mod(number p, coeffs c)
+{
+  // produce the matrix in Z/pZ
+  // CF: TODO rewrite using QuotRem and not the map
+  coeffs coe = numbercoeffs(p, c);
+  nMapFunc f1 = n_SetMap(basecoeffs(), coe);
+  nMapFunc f2 = n_SetMap(coe, basecoeffs());
+  number tmp1, tmp2;
+  for (int i=1; i<=row; i++)
+  {
+    for (int j=1; j<=col; j++)
+    {
+      tmp1 = get(i, j);
+      tmp2 = f1(tmp1, basecoeffs(), coe);
+      n_Delete(&tmp1, basecoeffs());
+      tmp1 = f2(tmp2, coe, basecoeffs());
+      set(i, j, tmp1);
+      n_Delete(&tmp1, basecoeffs());
+      n_Delete(&tmp2, coe);
+    }
+  }
+  nKillChar(coe);
+}
+
+void bimMult(bigintmat *a, bigintmat *b, bigintmat *c)
+{
+  if (!nCoeffs_are_equal(a->basecoeffs(), b->basecoeffs())) {
+    Werror("Error in bimMult. Coeffs do not agree!");
+    return;
+  }
+  if ((a->rows() != c->rows()) || (b->cols() != c->cols()) || (a->cols() != b->rows())) {
+    Werror("Error in bimMult. Dimensions do not agree!");
+    return;
+  }
+  bigintmat *tmp = bimMult(a, b);
+  c->copy(tmp);
+
+  delete tmp;
+}
+
+static void reduce_mod_howell(bigintmat *A, bigintmat *b, bigintmat * eps, bigintmat *x) {
+  //write b = Ax + eps where eps is "small" in the sense of bounded by the
+  //pivot entries in H. H does not need to be Howell (or HNF) but need
+  //to be triagonal in the same direction.
+  //b can have multiple columns.
+#if 0
+  Print("reduce_mod_howell: A:\n");
+  A->Print();
+  Print("\nb:\n");
+  b->Print();
+#endif
+
+  coeffs R = A->basecoeffs();
+  assume(x->basecoeffs() == R);
+  assume(b->basecoeffs() == R);
+  assume(eps->basecoeffs() == R);
+  if (!A->cols()) {
+    x->zero();
+    eps->copy(b);
+
+#if 0
+    Print("\nx:\n");
+    x->Print();
+    Print("\neps:\n");
+    eps->Print();
+    Print("\n****************************************\n");
+#endif
+    return;
+  }
+
+  bigintmat * B = new bigintmat(b->rows(), 1, R);
+  for(int i=1; i<= b->cols(); i++) {
+    int A_col = A->cols();
+    b->getcol(i, B);
+    for(int j = B->rows(); j>0; j--) {
+      number Ai = A->view(A->rows() - B->rows() + j, A_col);
+      if (n_IsZero(Ai, R) &&
+          n_IsZero(B->view(j, 1), R)) {
+        continue; //all is fine: 0*x = 0
+      } else if (n_IsZero(B->view(j, 1), R)) {
+        x->rawset(x->rows() - B->rows() + j, i, n_Init(0, R));
+        A_col--;
+      } else if (n_IsZero(Ai, R)) {
+        A_col--;
+      } else {
+        // "solve" ax=b, possibly enlarging d
+        number Bj = B->view(j, 1);
+        number q = n_Div(Bj, Ai, R);
+        x->rawset(x->rows() - B->rows() + j, i, q);
+        for(int k=j; k>B->rows() - A->rows(); k--) {
+          //B[k] = B[k] - x[k]A[k][j]
+          number s = n_Mult(q, A->view(A->rows() - B->rows() + k, A_col), R);
+          B->rawset(k, 1, n_Sub(B->view(k, 1), s, R));
+          n_Delete(&s, R);
+        }
+        A_col--;
+      }
+      if (!A_col) {
+        break;
+      }
+    }
+    eps->setcol(i, B);
+  }
+  delete B;
+#if 0
+  Print("\nx:\n");
+  x->Print();
+  Print("\neps:\n");
+  eps->Print();
+  Print("\n****************************************\n");
+#endif
+}
+
+static bigintmat * prependIdentity(bigintmat *A)
+{
+  coeffs R = A->basecoeffs();
+  bigintmat *m = new bigintmat(A->rows()+A->cols(), A->cols(), R);
+  m->copySubmatInto(A, 1, 1, A->rows(), A->cols(), A->cols()+1, 1);
+  number one = n_Init(1, R);
+  for(int i=1; i<= A->cols(); i++)
+    m->set(i,i,one);
+  n_Delete(&one, R);
+  return m;
+}
+
+static number bimFarey(bigintmat *A, number N, bigintmat *L) {
+  coeffs Z = A->basecoeffs(),
+         Q = nInitChar(n_Q, 0);
+  number den = n_Init(1, Z);
+  nMapFunc f = n_SetMap(Q, Z);
+
+  for(int i=1; i<= A->rows(); i++) {
+    for(int j=1; j<= A->cols(); j++) {
+      number ad = n_Mult(den, A->view(i, j), Z);
+      number re = n_IntMod(ad, N, Z);
+      n_Delete(&ad, Z);
+      number q = n_Farey(re, N, Z);
+      n_Delete(&re, Z);
+      if (!q) {
+        n_Delete(&ad, Z);
+        n_Delete(&den, Z);
+        return NULL;
+      }
+
+      number d = n_GetDenom(q, Q),
+             n = n_GetNumerator(q, Q);
+
+      n_Delete(&q, Q);
+      n_Delete(&ad, Z);
+      number dz = f(d, Q, Z),
+             nz = f(n, Q, Z);
+      n_Delete(&d, Q);
+      n_Delete(&n, Q);
+
+      if (!n_IsOne(dz, Z)) {
+        L->skalmult(dz, Z);
+        n_InpMult(den, dz, Z);
+#if 0
+        Print("den increasing to ");
+        n_Print(den, Z);
+        Print("\n");
+#endif
+      }
+      n_Delete(&dz, Z);
+      L->rawset(i, j, nz);
+    }
+  }
+
+  nKillChar(Q);
+  Print("bimFarey worked\n");
+#if 0
+  L->Print();
+  Print("\n * 1/");
+  n_Print(den, Z);
+  Print("\n");
+#endif
+  return den;
+}
+
+static number solveAx_dixon(bigintmat *A, bigintmat *B, bigintmat *x, bigintmat *kern) {
+  coeffs R = A->basecoeffs();
+
+  assume(getCoeffType(R) == n_Z);
+
+  number p = n_Init(536870909, R); // PreviousPrime(2^29); not clever
+  coeffs Rp = numbercoeffs(p, R); // R/pR
+  bigintmat *Ap = bimChangeCoeff(A, Rp),
+            *m = prependIdentity(Ap),
+            *Tp, *Hp;
+  delete Ap;
+
+  m->howell();
+  Hp = new bigintmat(A->rows(), A->cols(), Rp);
+  Hp->copySubmatInto(m, A->cols()+1, 1, A->rows(), A->cols(), 1, 1);
+  Tp = new bigintmat(A->cols(), A->cols(), Rp);
+  Tp->copySubmatInto(m, 1, 1, A->cols(), A->cols(), 1, 1);
+
+  int i, j;
+
+  for(i=1; i<= A->cols(); i++) {
+    for(j=m->rows(); j>A->cols(); j--) {
+      if (!n_IsZero(m->view(j, i), Rp)) break;
+    }
+    if (j>A->cols()) break;
+  }
+//  Print("Found nullity (kern dim) of %d\n", i-1);
+  bigintmat * kp = new bigintmat(A->cols(), i-1, Rp);
+  kp->copySubmatInto(Tp, 1, 1, A->cols(), i-1, 1, 1);
+  kp->howell();
+
+  delete m;
+
+  //Hp is the mod-p howell form
+  //Tp the transformation, mod p
+  //kp a basis for the kernel, in howell form, mod p
+
+  bigintmat * eps_p = new bigintmat(B->rows(), B->cols(), Rp),
+            * x_p   = new bigintmat(A->cols(), B->cols(), Rp),
+            * fps_p = new bigintmat(kp->cols(), B->cols(), Rp);
+
+  //initial solution
+
+  number zero = n_Init(0, R);
+  x->skalmult(zero, R);
+  n_Delete(&zero, R);
+
+  bigintmat * b = new bigintmat(B);
+  number pp = n_Init(1, R);
+  i = 1;
+  do {
+    bigintmat * b_p = bimChangeCoeff(b, Rp), * s;
+    bigintmat * t1, *t2;
+    reduce_mod_howell(Hp, b_p, eps_p, x_p);
+    delete b_p;
+    if (!eps_p->isZero()) {
+      Print("no solution, since no modular solution\n");
+
+      delete eps_p;
+      delete x_p;
+      delete Hp;
+      delete kp;
+      delete Tp;
+      delete b;
+      n_Delete(&pp, R);
+      n_Delete(&p, R);
+      nKillChar(Rp);
+
+      return NULL;
+    }
+    t1 = bimMult(Tp, x_p);
+    delete x_p;
+    x_p = t1;
+    reduce_mod_howell(kp, x_p, x_p, fps_p);  //we're not all interested in fps_p
+    s = bimChangeCoeff(x_p, R);
+    t1 = bimMult(A, s);
+    t2 = bimSub(b, t1);
+    t2->skaldiv(p);
+    delete b;
+    delete t1;
+    b = t2;
+    s->skalmult(pp, R);
+    t1 = bimAdd(x, s);
+    delete s;
+    x->swapMatrix(t1);
+    delete t1;
+
+    if(kern && i==1) {
+      bigintmat * ker = bimChangeCoeff(kp, R);
+      t1 = bimMult(A, ker);
+      t1->skaldiv(p);
+      t1->skalmult(n_Init(-1, R), R);
+      b->appendCol(t1);
+      delete t1;
+      x->appendCol(ker);
+      delete ker;
+      x_p->extendCols(kp->cols());
+      eps_p->extendCols(kp->cols());
+      fps_p->extendCols(kp->cols());
+    }
+
+    n_InpMult(pp, p, R);
+
+    if (b->isZero()) {
+      //exact solution found, stop
+      delete eps_p;
+      delete fps_p;
+      delete x_p;
+      delete Hp;
+      delete kp;
+      delete Tp;
+      delete b;
+      n_Delete(&pp, R);
+      n_Delete(&p, R);
+      nKillChar(Rp);
+
+      return n_Init(1, R);
+    } else {
+      bigintmat *y = new bigintmat(x->rows(), x->cols(), R);
+      number d = bimFarey(x, pp, y);
+      if (d) {
+        bigintmat *c = bimMult(A, y);
+        bigintmat *bd = new bigintmat(B);
+        bd->skalmult(d, R);
+        if (kern) {
+          bd->extendCols(kp->cols());
+        }
+        if (*c == *bd) {
+          x->swapMatrix(y);
+          delete y;
+          delete c;
+          if (kern) {
+            y = new bigintmat(x->rows(), B->cols(), R);
+            c = new bigintmat(x->rows(), kp->cols(), R);
+            x->splitcol(y, c);
+            x->swapMatrix(y);
+            delete y;
+            kern->swapMatrix(c);
+            delete c;
+          }
+
+          delete bd;
+
+          delete eps_p;
+          delete fps_p;
+          delete x_p;
+          delete Hp;
+          delete kp;
+          delete Tp;
+          delete b;
+          n_Delete(&pp, R);
+          n_Delete(&p, R);
+          nKillChar(Rp);
+
+          return d;
+        }
+        delete c;
+        delete bd;
+        n_Delete(&d, R);
+      }
+      delete y;
+    }
+    i++;
+  } while (1);
+  delete eps_p;
+  delete fps_p;
+  delete x_p;
+  delete Hp;
+  delete kp;
+  delete Tp;
+  n_Delete(&pp, R);
+  n_Delete(&p, R);
+  nKillChar(Rp);
+  return NULL;
+}
+
+//TODO: re-write using reduce_mod_howell
+static number solveAx_howell(bigintmat *A, bigintmat *b, bigintmat *x, bigintmat *kern) {
+  // try to solve Ax=b, more precisely, find
+  //   number    d
+  //   bigintmat x
+  // sth. Ax=db
+  // where d is small-ish (divides the determinant of A if this makes sense)
+  // return 0 if there is no solution.
+  //
+  // if kern is non-NULL, return a basis for the kernel
+
+  //Algo: we do row-howell (triangular matrix). The idea is
+  //  Ax = b <=>  AT T^-1x = b
+  //  y := T^-1 x, solve AT y = b
+  //  and return Ty.
+  //Howell does not compute the trafo, hence we need to cheat:
+  //B := (I_n | A^t)^t, then the top part of the Howell form of
+  //B will give a useful trafo
+  //Then we can find x by back-substitution and lcm/gcd to find the denominator
+  //The defining property of Howell makes this work.
+
+  coeffs R = A->basecoeffs();
+  bigintmat *m = prependIdentity(A);
+  m->howell(); // since m contains the identity, we'll have A->cols()
+               // many cols.
+  number den = n_Init(1, R);
+
+  bigintmat * B = new bigintmat(A->rows(), 1, R);
+  for(int i=1; i<= b->cols(); i++) {
+    int A_col = A->cols();
+    b->getcol(i, B);
+    B->skalmult(den, R);
+    for(int j = B->rows(); j>0; j--) {
+      number Ai = m->view(m->rows()-B->rows() + j, A_col);
+      if (n_IsZero(Ai, R) &&
+          n_IsZero(B->view(j, 1), R)) {
+        continue; //all is fine: 0*x = 0
+      } else if (n_IsZero(B->view(j, 1), R)) {
+        x->rawset(x->rows() - B->rows() + j, i, n_Init(0, R));
+        A_col--;
+      } else if (n_IsZero(Ai, R)) {
+        delete m;
+        delete B;
+        n_Delete(&den, R);
+        return 0;
+      } else {
+        // solve ax=db, possibly enlarging d
+        // so x = db/a
+        number Bj = B->view(j, 1);
+        number g = n_Gcd(Bj, Ai, R);
+        number xi;
+        if (n_Equal(Ai, g, R)) { //good: den stable!
+          xi = n_Div(Bj, Ai, R);
+        } else { //den <- den * (a/g), so old sol. needs to be adjusted
+          number inc_d = n_Div(Ai, g, R);
+          n_InpMult(den, inc_d, R);
+          x->skalmult(inc_d, R);
+          B->skalmult(inc_d, R);
+          xi = n_Div(Bj, g, R);
+          n_Delete(&inc_d, R);
+        } //now for the back-substitution:
+        x->rawset(x->rows() - B->rows() + j, i, xi);
+        for(int k=j; k>0; k--) {
+          //B[k] = B[k] - x[k]A[k][j]
+          number s = n_Mult(xi, m->view(m->rows()-B->rows() + k, A_col), R);
+          B->rawset(k, 1, n_Sub(B->view(k, 1), s, R));
+          n_Delete(&s, R);
+        }
+        n_Delete(&g, R);
+        A_col--;
+      }
+      if (!A_col) {
+        if (B->isZero()) break;
+        else {
+          delete m;
+          delete B;
+          n_Delete(&den, R);
+          return 0;
+        }
+      }
+    }
+  }
+  delete B;
+  bigintmat *T = new bigintmat(A->cols(), A->cols(), R);
+  T->copySubmatInto(m, 1, 1, A->cols(), A->cols(), 1, 1);
+  if (kern) {
+    int i, j;
+    for(i=1; i<= A->cols(); i++) {
+      for(j=m->rows(); j>A->cols(); j--) {
+        if (!n_IsZero(m->view(j, i), R)) break;
+      }
+      if (j>A->cols()) break;
+    }
+    Print("Found nullity (kern dim) of %d\n", i-1);
+    bigintmat * ker = new bigintmat(A->rows(), i-1, R);
+    ker->copySubmatInto(T, 1, 1, A->rows(), i-1, 1, 1);
+    kern->swapMatrix(ker);
+    delete ker;
+  }
+  delete m;
+  bigintmat * y = bimMult(T, x);
+  x->swapMatrix(y);
+  delete y;
+  x->simplifyContentDen(&den);
+#if 0
+  Print("sol = 1/");
+  n_Print(den, R);
+  Print(" *\n");
+  x->Print();
+  Print("\n");
+#endif
+  return den;
+}
+
+number solveAx(bigintmat *A, bigintmat *b, bigintmat *x) {
+#if 0
+  Print("Solve Ax=b for A=\n");
+  A->Print();
+  Print("\nb = \n");
+  b->Print();
+  Print("\nx = \n");
+  x->Print();
+  Print("\n");
+#endif
+
+  coeffs R = A->basecoeffs();
+  assume (R == b->basecoeffs());
+  assume (R == x->basecoeffs());
+  assume ((x->cols() == b->cols()) && (x->rows() == A->cols()) && (A->rows() == b->rows()));
+
+  switch (getCoeffType(R)) {
+    case n_Z:
+      return solveAx_dixon(A, b, x, NULL);
+    case n_Zn:
+    case n_Znm:
+    case n_Z2m:
+      return solveAx_howell(A, b, x, NULL);
+    case n_Zp:
+    case n_Q:
+    case n_GF:
+    case n_algExt:
+    case n_transExt:
+      Warn("have field, should use Gauss or better");
+    default:
+      if (R->cfXExtGcd && R->cfAnn) { //assume it's Euclidean
+        return solveAx_howell(A, b, x, NULL);
+      }
+      Werror("have no solve algorithm");
+  }
+  return NULL;
+}
+
+void diagonalForm(bigintmat *A, bigintmat ** S, bigintmat ** T)
+{
+  bigintmat * t, *s, *a=A;
+  coeffs R = a->basecoeffs();
+  if (T) {
+    *T = new bigintmat(a->cols(), a->cols(), R),
+    (*T)->one();
+    t = new bigintmat(*T);
+  } else {
+    t = *T;
+  }
+
+  if (S) {
+    *S = new bigintmat(a->rows(), a->rows(), R);
+    (*S)->one();
+    s = new bigintmat(*S);
+  } else {
+    s = *S;
+  }
+
+  int flip=0;
+  do {
+    bigintmat * x, *X;
+    if (flip) {
+      x = s;
+      X = *S;
+    } else {
+      x = t;
+      X = *T;
+    }
+
+    if (x) {
+      x->one();
+      bigintmat * r = new bigintmat(a->rows()+a->cols(), a->cols(), R);
+      bigintmat * rw = new bigintmat(1, a->cols(), R);
+      for(int i=0; i<a->cols(); i++) {
+        x->getrow(i+1, rw);
+        r->setrow(i+1, rw);
+      }
+      for (int i=0; i<a->rows(); i++) {
+        a->getrow(i+1, rw);
+        r->setrow(i+a->cols()+1, rw);
+      }
+      r->hnf();
+      for(int i=0; i<a->cols(); i++) {
+        r->getrow(i+1, rw);
+        x->setrow(i+1, rw);
+      }
+      for(int i=0; i<a->rows(); i++) {
+        r->getrow(i+a->cols()+1, rw);
+        a->setrow(i+1, rw);
+      }
+      delete rw;
+      delete r;
+
+#if 0
+      Print("X: %ld\n", X);
+      X->Print();
+      Print("\nx: %ld\n", x);
+      x->Print();
+#endif
+      bimMult(X, x, X);
+#if 0
+      Print("\n2:X: %ld %ld %ld\n", X, *S, *T);
+      X->Print();
+      Print("\n2:x: %ld\n", x);
+      x->Print();
+      Print("\n");
+#endif
+    } else {
+      a->hnf();
+    }
+
+    int diag = 1;
+    for(int i=a->rows(); diag && i>0; i--) {
+      for(int j=a->cols(); j>0; j--) {
+        if ((a->rows()-i)!=(a->cols()-j) && !n_IsZero(a->view(i, j), R)) {
+          diag = 0;
+          break;
+        }
+      }
+    }
+#if 0
+    Print("Diag ? %d\n", diag);
+    a->Print();
+    Print("\n");
+#endif
+    if (diag) break;
+
+    a = a->transpose(); // leaks - I need to write inpTranspose
+    flip = 1-flip;
+  } while (1);
+  if (flip)
+    a = a->transpose();
+
+  if (S) *S = (*S)->transpose();
+  if (s) delete s;
+  if (t) delete t;
+  A->copy(a);
+}
+
+//a "q-base" for the kernel of a.
+//Should be re-done to use Howell rather than smith.
+//can be done using solveAx now.
+int kernbase (bigintmat *a, bigintmat *c, number p, coeffs q) {
+#if 0
+  Print("Kernel of ");
+  a->Print();
+  Print(" modulo ");
+  n_Print(p, q);
+  Print("\n");
+#endif
+
+  coeffs coe = numbercoeffs(p, q);
+  bigintmat *m = bimChangeCoeff(a, coe), *U, *V;
+  diagonalForm(m, &U, &V);
+#if 0
+  Print("\ndiag form: ");
+  m->Print();
+  Print("\nU:\n");
+  U->Print();
+  Print("\nV:\n");
+  V->Print();
+  Print("\n");
+#endif
+
+  int rg = 0;
+#undef MIN
+#define MIN(a,b) (a < b ? a : b)
+  for(rg=0; rg<MIN(m->rows(), m->cols()) && !n_IsZero(m->view(m->rows()-rg,m->cols()-rg), coe); rg++);
+
+#undef MAX
+#define MAX(a,b) (a > b ? a : b)
+  bigintmat * k = new bigintmat(m->cols(), m->rows(), coe);
+  for(int i=0; i<rg; i++) {
+    number A = n_Ann(m->view(m->rows()-i, m->cols()-i), coe);
+    k->set(m->cols()-i, i+1, A);
+    n_Delete(&A, coe);
+  }
+  for(int i=rg; i<m->cols(); i++) {
+    k->set(m->cols()-i, i+1-rg, n_Init(1, coe));
+  }
+  bimMult(V, k, k);
+  c->copy(bimChangeCoeff(k, q));
+  return c->cols();
+}
+
+
+bool nCoeffs_are_equal(coeffs r, coeffs s) {
+  if ((r == NULL) || (s == NULL))
+    return false;
+  if ((getCoeffType(r)==n_Z) && (getCoeffType(s)==n_Z))
+    return true;
+  if ((getCoeffType(r)==n_Zp) && (getCoeffType(s)==n_Zp)) {
+    if (r->ch == s->ch)
+      return true;
+    else
+      return false;
+  }
+  // n_Zn stimmt wahrscheinlich noch nicht
+  if ((getCoeffType(r)==n_Zn) && (getCoeffType(s)==n_Zn)) {
+    if (r->ch == s->ch)
+      return true;
+    else
+      return false;
+  }
+  if ((getCoeffType(r)==n_Q) && (getCoeffType(s)==n_Q))
+    return true;
+  // FALL n_Zn FEHLT NOCH!
+    //if ((getCoeffType(r)==n_Zn) && (getCoeffType(s)==n_Zn))
+  return false;
+}
+
+number bigintmat::content()
+{
+  coeffs r = basecoeffs();
+  number g = get(1,1), h;
+  int n=rows()*cols();
+  for(int i=1; i<n && !n_IsOne(g, r); i++) {
+    h = n_Gcd(g, view(i), r);
+    n_Delete(&g, r);
+    g=h;
+  }
+  return g;
+}
+void bigintmat::simplifyContentDen(number *d)
+{
+  coeffs r = basecoeffs();
+  number g = n_Copy(*d, r), h;
+  int n=rows()*cols();
+  for(int i=0; i<n && !n_IsOne(g, r); i++) {
+    h = n_Gcd(g, view(i), r);
+    n_Delete(&g, r);
+    g=h;
+  }
+  *d = n_Div(*d, g, r);
+  if (!n_IsOne(g, r))
+  skaldiv(g);
+}
diff --git a/libpolys/coeffs/bigintmat.h b/libpolys/coeffs/bigintmat.h
new file mode 100644
index 0000000..951cf23
--- /dev/null
+++ b/libpolys/coeffs/bigintmat.h
@@ -0,0 +1,333 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+#ifndef BIGINTMAT_H
+#define BIGINTMAT_H
+
+#include <omalloc/omalloc.h>
+#include <coeffs/coeffs.h>
+
+/**
+ * @class bigintmat bigintmat.h <coeffs/bigintmat.h>
+ *
+ * Matrices of numbers
+ *
+ * Matrices are stored as 1-dim c-arrays but interpreted 2-dim as matrices.
+ * Both modes of addressing are supported, note however, that the 1-dim
+ * adressing starts at 0, the 2-dim at 1.
+ *
+ * Matrices are meant to represent column modules, thus the default
+ * operations are always by column.
+ *
+ * While basic operations are supported over any ring (coeff), some more
+ * advanced ones require more special rings: eg. echelon forms, solving
+ * of linear equations is only effective over principal ideal or even
+ * Euclidean rings.
+ *
+ * Be careful with the get/set/view/rawset functions to understand which
+ * arguments are copied/ deleted or only assigned.
+ *
+ * @Note: no reference counting here!
+ */
+class bigintmat
+{
+  private:
+    coeffs m_coeffs;
+    number *v;
+    int row;
+    int col;
+  public:
+
+    bigintmat(): m_coeffs(NULL), v(NULL), row(1), col(0){}
+
+    bigintmat * transpose();
+
+    /// transpose in place
+    void inpTranspose();
+
+
+    /// constructor: the r times c zero-matrix. Beware that the creation
+    /// of a large zero matrix is expensive in terms of time and memory.
+    bigintmat(int r, int c, const coeffs n): m_coeffs(n), v(NULL), row(r), col(c)
+    {
+      assume (rows() >= 0);
+      assume (cols() >= 0);
+
+      const int l = r*c;
+
+      if (l>0) /*(r>0) && (c>0) */
+      {
+        v = (number *)omAlloc(sizeof(number)*l);
+
+        assume (basecoeffs() != NULL);
+        for (int i = l - 1; i>=0; i--)
+        {
+          v[i] = n_Init(0, basecoeffs());
+        }
+      }
+    }
+
+    /// copy constructor
+    bigintmat(const bigintmat *m): m_coeffs(m->basecoeffs()), v(NULL), row(m->rows()), col(m->cols())
+    {
+      const int l = row*col;
+
+      if (l > 0)
+      {
+        assume (rows() > 0);
+        assume (cols() > 0);
+
+        assume (m->v != NULL);
+
+        v = (number *)omAlloc(sizeof(number)*row*col);
+
+        assume (basecoeffs() != NULL);
+
+        for (int i = l-1; i>=0; i--)
+        {
+          v[i] = n_Copy((*m)[i], basecoeffs());
+        }
+      }
+    }
+    /// dubious: 1-dim access to 2-dim array. Entries are read row by row.
+    inline number& operator[](int i)
+    {
+#ifndef SING_NDEBUG
+      if((i<0)||(i>=row*col))
+      {
+        Werror("wrong bigintmat index:%d\n",i);
+      }
+#endif
+      assume ( !((i<0)||(i>=row*col)) );
+
+      return v[i];  // Hier sollte imho kein nlCopy rein...
+    }
+    inline const number& operator[](int i) const
+    {
+#ifndef SING_NDEBUG
+      if((i<0)||(i>=row*col))
+      {
+        Werror("wrong bigintmat index:%d\n",i);
+      }
+#endif
+      assume ( !((i<0)||(i>=row*col)) );
+
+      return v[i];
+    }
+#define BIMATELEM(M,I,J) (M)[(I-1)*(M).cols()+J-1]
+
+    /// UEberladener *=-Operator (fuer int und bigint)
+    /// Frage hier: *= verwenden oder lieber = und * einzeln?
+    /// problem: what about non-commuting rings. Is this from left or right?
+    void operator*=(int intop);
+
+    /// inplace versio of skalar mult. CHANGES input.
+    void inpMult(number bintop, const coeffs C = NULL);
+
+    inline int length() { return col*row; }
+    inline int  cols() const { return col; }
+    inline int  rows() const { return row; }
+    inline coeffs basecoeffs() const { return m_coeffs; }
+
+    /// canonical destructor.
+    ~bigintmat()
+    {
+      if (v!=NULL)
+      {
+        for (int i=0; i<row*col; i++) { n_Delete(&(v[i]), basecoeffs()); }
+        omFreeSize((ADDRESS)v, sizeof(number)*row*col);
+        v=NULL;
+      }
+    }
+
+    /// helper function to map from 2-dim coordinates, starting by 1 to
+    /// 1-dim coordinate, starting by 0
+    int index(int r, int c) const
+    {
+      assume (rows() >= 0 && cols() >= 0);
+
+      assume (r > 0 && c > 0);
+      assume (r <= rows() && c <= cols());
+
+      const int index = ((r-1)*cols() + (c-1));
+
+      assume (index >= 0 && index < rows() * cols());
+      return index;
+    }
+
+    /// get a copy of an entry. NOTE: starts at [1,1]
+    number get(int i, int j) const;
+    /// view an entry an entry. NOTE: starts at [1,1]
+    //do NOT delete.
+    number view(int i, int j) const;
+
+    /// get a copy of an entry. NOTE: starts at [0]
+    number get(int i) const;
+    /// view an entry. NOTE: starts at [0]
+    number view(int i) const;
+
+    /// replace an entry with a copy (delete old + copy new!).
+    /// NOTE: starts at [1,1]
+    void set(int i, int j, number n, const coeffs C = NULL);
+
+    /// replace an entry with a copy (delete old + copy new!).
+    /// NOTE: starts at [0]
+    void set(int i, number n, const coeffs C = NULL);
+
+
+    /// replace an entry with the given number n (only delete old).
+    /// NOTE: starts at [0]. Should be named set_transfer
+    inline void rawset(int i, number n, const coeffs C = NULL)
+    {
+      assume (C == NULL || C == basecoeffs());
+      assume (i >= 0);
+      const int l = rows() * cols();
+      assume (i<l);
+
+      if (i < l)
+      {
+        n_Delete(&(v[i]), basecoeffs()); v[i] = n;
+      }
+#ifndef SING_NDEBUG
+      else
+      {
+        Werror("wrong bigintmat index:%d\n",i);
+      }
+#endif
+    }
+
+    /// as above, but the 2-dim version
+    inline void rawset(int i, int j, number n, const coeffs C = NULL)
+    {
+      rawset( index(i,j), n, C);
+    }
+
+    ///IO: String returns a singular string containing the matrix, needs
+    /// freeing afterwards
+    char * String();
+    ///IO: writes the matrix into the current internal string buffer which
+    /// must be started/ allocated before (e.g. @ref StringSetS)
+    void Write();
+    ///IO: simply prints the matrix to the current output (screen?)
+    void Print();
+
+   /**
+    * Returns a string as it would have been printed in the interpreter.
+    * Used e.g. in print functions of various blackbox types.
+    */
+    char * StringAsPrinted();
+    void pprint(int maxwid);
+    int compare(const bigintmat* op) const;
+    int * getwid(int maxwid);
+
+
+    // Funktionen von Kira, Jan, Marco
+    // !WICHTIG: Überall, wo eine number übergeben wird, und damit gearbeitet wird, die coeffs mitübergeben und erst
+    // überprüfen, ob diese mit basecoeffs übereinstimmen. Falls nein: Breche ab!
+
+    /// swap columns i and j
+    void swap(int i, int j);
+
+    /// swap rows i and j
+    void swaprow(int i, int j);
+
+    ///find index of 1st non-zero entry in row i
+    int findnonzero(int i);
+
+    ///find index of 1st non-zero entry in column j
+    int findcolnonzero(int j);
+
+    ///copies the j-th column into the matrix a - which needs to be pre-allocated with the correct size.
+    void getcol(int j, bigintmat *a);
+
+    ///copies the no-columns staring by j (so j...j+no-1) into the pre-allocated a
+    void getColRange(int j, int no, bigintmat *a);
+
+    void getrow(int i, bigintmat *a); ///< Schreibt i-te Zeile in Vektor (Matrix) a
+    void setcol(int j, bigintmat *m); ///< Setzt j-te Spalte gleich übergebenem Vektor (Matrix) m
+    void setrow(int i, bigintmat *m); ///< Setzt i-te Zeile gleich übergebenem Vektor (Matrix) m
+
+    ///horizontally join the matrices, m <- m|a
+    void appendCol (bigintmat *a);
+
+    ///append i zero-columns to the matrix
+    void extendCols (int i);
+
+    bool add(bigintmat *b); ///< Addiert zur Matrix die Matrix b dazu. Return false => an error occured
+    bool sub(bigintmat *b); ///< Subtrahiert ...
+    bool skalmult(number b, coeffs c); ///< Multipliziert zur Matrix den Skalar b hinzu
+    bool addcol(int i, int j, number a, coeffs c); ///< addiert a-faches der j-ten Spalte zur i-ten dazu
+    bool addrow(int i, int j, number a, coeffs c); ///< ... Zeile ...
+    void colskalmult(int i, number a, coeffs c); ///< Multipliziert zur i-ten Spalte den Skalar a hinzu
+    void rowskalmult(int i, number a, coeffs c); ///< ... Zeile ...
+    void coltransform(int i, int j, number a, number b, number c, number d); ///<  transforms cols (i,j) using the 2x2 matrix ((a,b)(c,d)) (hopefully)
+    void concatrow(bigintmat *a, bigintmat *b); ///< Fügt zwei Matrixen untereinander/nebeneinander in gegebene Matrix ein, bzw spaltet gegebenen Matrix auf
+    void concatcol(bigintmat *a, bigintmat *b);
+    void splitrow(bigintmat *a, bigintmat *b); ///< Speichert in Matrix a den oberen, in b den unteren Teil der Matrix, vorausgesetzt die Dimensionen stimmen überein
+    void splitcol(bigintmat *a, bigintmat *b); ///< ... linken ... rechten ...
+    void splitcol(bigintmat *a, int i); ///< Speichert die ersten i Spalten als Teilmatrix in a
+    void splitrow(bigintmat *a, int i); ///< ... Zeilen ...
+    bool copy(bigintmat *b); ///< Kopiert Einträge von b auf Bigintmat
+    void copySubmatInto(bigintmat *, int sr, int sc, int nr, int nc, int tr, int tc);
+    void one(); ///< Macht Matrix (Falls quadratisch) zu Einheitsmatrix
+    int isOne(); ///< is matrix is identity
+    void zero(); ///< Setzt alle Einträge auf 0
+    int isZero();
+    int colIsZero(int i);
+    bigintmat *elim(int i, int j); ///< Liefert Streichungsmatrix (i-te Zeile und j-te Spalte gestrichen) zurück
+    number pseudoinv(bigintmat *a); ///< Speichert in Matrix a die Pseudoinverse, liefert den Nenner zurück
+    number trace(); ///< the trace ....
+    number det(); ///< det (via LaPlace in general, hnf for euc. rings)
+    number hnfdet(); ///< det via HNF
+    /// Primzahlen als long long int, müssen noch in number umgewandelt werden?
+    void hnf(); ///< transforms INPLACE to HNF
+    void howell(); ///<dito, but Howell form (only different for zero-divsors)
+    void swapMatrix(bigintmat * a);
+    bigintmat * modhnf(number p, coeffs c); ///< computes HNF(this | p*I)
+    bigintmat * modgauss(number p, coeffs c);
+    void skaldiv(number b); ///< Macht Ganzzahldivision aller Matrixeinträge mit b
+    void colskaldiv(int j, number b); ///< Macht Ganzzahldivision aller j-ten Spalteneinträge mit b
+    void mod(number p, coeffs c); ///< Reduziert komplette Matrix modulo p
+    bigintmat* inpmod(number p, coeffs c); ///< Liefert Kopie der Matrix zurück, allerdings im Ring Z modulo p
+    number content(); ///<the content, the gcd of all entries. Only makes sense for Euclidean rings (or possibly constructive PIR)
+    void simplifyContentDen(number *den); ///< ensures that Gcd(den, content)=1
+    ///< enden hier wieder
+};
+
+bool operator==(const bigintmat & lhr, const bigintmat & rhr);
+bool operator!=(const bigintmat & lhr, const bigintmat & rhr);
+
+/// Matrix-Add/-Sub/-Mult so oder mit operator+/-/* ?
+/// @Note: NULL as a result means an error (non-compatible matrices?)
+bigintmat * bimAdd(bigintmat * a, bigintmat * b);
+bigintmat * bimAdd(bigintmat * a, int b);
+bigintmat * bimSub(bigintmat * a, bigintmat * b);
+bigintmat * bimSub(bigintmat * a, int b);
+bigintmat * bimMult(bigintmat * a, bigintmat * b);
+bigintmat * bimMult(bigintmat * a, int b);
+bigintmat * bimMult(bigintmat * a, number b, const coeffs cf);
+
+///same as copy constructor - apart from it being able to accept NULL as input
+bigintmat * bimCopy(const bigintmat * b);
+
+class intvec;
+intvec * bim2iv(bigintmat * b);
+bigintmat * iv2bim(intvec * b, const coeffs C);
+
+// Wieder von Kira, Jan, Marco
+bigintmat * bimChangeCoeff(bigintmat *a, coeffs cnew); ///< Liefert Kopier von Matrix a zurück, mit coeffs cnew statt den ursprünglichen
+void bimMult(bigintmat *a, bigintmat *b, bigintmat *c); ///< Multipliziert Matrix a und b und speichert Ergebnis in c
+
+///solve Ax=b*d. x needs to be pre-allocated to the same number of columns as b.
+/// the minimal denominator d is returned. Currently available for Z, Q and Z/nZ (and possibly for all fields: d=1 there)
+///Beware that the internal functions can find the kernel as well - but the interface is lacking.
+number solveAx(bigintmat *A, bigintmat *b, bigintmat *x); // solves Ax=b*d for a minimal denominator d. if x needs to have as many cols as b
+
+///a basis for the nullspace of a mod p: only used internally in Round2.
+/// Don't use it.
+int kernbase (bigintmat *a, bigintmat *c, number p, coeffs q);
+bool nCoeffs_are_equal(coeffs r, coeffs s);
+// enden wieder
+void diagonalForm(bigintmat *a, bigintmat **b, bigintmat **c);
+
+#endif /* #ifndef BIGINTMAT_H */
diff --git a/libpolys/coeffs/coeffs.h b/libpolys/coeffs/coeffs.h
new file mode 100644
index 0000000..72d2fc5
--- /dev/null
+++ b/libpolys/coeffs/coeffs.h
@@ -0,0 +1,989 @@
+/*! \file coeffs/coeffs.h Coefficient rings, fields and other domains suitable for Singular polynomials
+
+  The main interface for Singular coefficients: \ref coeffs is the main handler for Singular numbers
+*/
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+
+#ifndef COEFFS_H
+#define COEFFS_H
+
+#include <misc/auxiliary.h>
+#include <omalloc/omalloc.h>
+
+#include <misc/sirandom.h>
+/* for assume: */
+#include <reporter/reporter.h>
+#include <reporter/s_buff.h>
+
+#include <coeffs/si_gmp.h>
+#include <coeffs/Enumerator.h>
+#include <coeffs/numstats.h> // for STATISTIC(F) counting macro
+
+class CanonicalForm;
+
+enum n_coeffType
+{
+  n_unknown=0,
+  n_Zp, /**< \F{p < 2^31} */
+  n_Q,  /**< rational (GMP) numbers */
+  n_R,  /**< single prescision (6,6) real numbers */
+  n_GF, /**< \GF{p^n < 2^16} */
+  n_long_R, /**< real floating point (GMP) numbers */
+  n_algExt,  /**< used for all algebraic extensions, i.e.,
+                the top-most extension in an extension tower
+                is algebraic */
+  n_transExt,  /**< used for all transcendental extensions, i.e.,
+                  the top-most extension in an extension tower
+                  is transcendental */
+  n_long_C, /**< complex floating point (GMP) numbers */
+  n_Z, /**< only used if HAVE_RINGS is defined: ? */
+  n_Zn, /**< only used if HAVE_RINGS is defined: ? */
+  n_Znm, /**< only used if HAVE_RINGS is defined: ? */
+  n_Z2m, /**< only used if HAVE_RINGS is defined: ? */
+  n_CF /**< ? */
+};
+
+extern unsigned short fftable[];
+
+struct snumber;
+typedef struct snumber *   number;
+
+/* standard types */
+struct ip_sring;
+typedef struct ip_sring *         ring;
+typedef struct ip_sring const *   const_ring;
+
+/// @class coeffs coeffs.h coeffs/coeffs.h
+///
+/// The main handler for Singular numbers which are suitable for Singular polynomials.
+///
+/// With it one may implement a ring, a field, a domain etc.
+///
+struct n_Procs_s;
+typedef struct  n_Procs_s  *coeffs;
+typedef struct  n_Procs_s  const * const_coeffs;
+
+typedef number (*numberfunc)(number a, number b, const coeffs r);
+
+/// maps "a", which lives in src, into dst
+typedef number (*nMapFunc)(number a, const coeffs src, const coeffs dst);
+
+
+/// Abstract interface for an enumerator of number coefficients for an
+/// object, e.g. a polynomial
+typedef IEnumerator<number> ICoeffsEnumerator;
+
+/// goes over coeffs given by the ICoeffsEnumerator and changes them.
+/// Additionally returns a number;
+typedef void (*nCoeffsEnumeratorFunc)(ICoeffsEnumerator& numberCollectionEnumerator, number& output, const coeffs r);
+
+extern omBin rnumber_bin;
+
+#define FREE_RNUMBER(x) omFreeBin((void *)x, rnumber_bin)
+#define ALLOC_RNUMBER() (number)omAllocBin(rnumber_bin)
+#define ALLOC0_RNUMBER() (number)omAlloc0Bin(rnumber_bin)
+
+
+/// Creation data needed for finite fields
+typedef struct
+{
+  int GFChar;
+  int GFDegree;
+  const char* GFPar_name;
+} GFInfo;
+
+typedef struct
+{
+  short      float_len; /**< additional char-flags, rInit */
+  short      float_len2; /**< additional char-flags, rInit */
+  const char* par_name; /**< parameter name */
+} LongComplexInfo;
+
+
+enum n_coeffRep
+{
+  n_rep_unknown=0,
+  n_rep_int,      /**< (int), see modulop.h */
+  n_rep_gap_rat,  /**< (number), see longrat.h */
+  n_rep_gap_gmp,  /**< (), see rinteger.h, new impl. */
+  n_rep_poly,     /**< (poly), see algext.h */
+  n_rep_rat_fct,  /**< (fraction), see transext.h */
+  n_rep_gmp,      /**< (mpz_ptr), see rmodulon,h */
+  n_rep_float,    /**< (float), see shortfl.h */
+  n_rep_gmp_float,  /**< (gmp_float), see  */
+  n_rep_gmp_complex,/**< (gmp_complex), see gnumpc.h */
+  n_rep_gf        /**< (int), see ffields.h */
+};
+
+struct n_Procs_s
+{
+   // administration of coeffs:
+   coeffs next;
+   int     ref;
+   n_coeffRep rep;
+   n_coeffType type;
+   /// how many variables of factory are already used by this coeff
+   int     factoryVarOffset;
+
+   // general properties:
+   /// TRUE, if nNew/nDelete/nCopy are dummies
+   BOOLEAN has_simple_Alloc;
+   /// TRUE, if std should make polynomials monic (if nInvers is cheap)
+   /// if false, then a gcd routine is used for a content computation
+   BOOLEAN has_simple_Inverse;
+
+   /// TRUE, if cf is a field
+   BOOLEAN is_field;
+   /// TRUE, if cf is a domain
+   BOOLEAN is_domain;
+
+   // tests for numbers.cc:
+   BOOLEAN (*nCoeffIsEqual)(const coeffs r, n_coeffType n, void * parameter);
+
+   /// output of coeff description via Print
+   void (*cfCoeffWrite)(const coeffs r, BOOLEAN details);
+
+   /// string output of coeff description
+   char* (*cfCoeffString)(const coeffs r);
+
+   /// default name of cf, should substitue cfCoeffWrite, cfCoeffString
+   char* (*cfCoeffName)(const coeffs r);
+
+   // ?
+   // initialisation:
+   //void (*cfInitChar)(coeffs r, int parameter); // do one-time initialisations
+   void (*cfKillChar)(coeffs r); //  undo all initialisations
+                                // or NULL
+   void (*cfSetChar)(const coeffs r); // initialisations after each ring change
+                                // or NULL
+   // general stuff
+   //   if the ring has a meaningful Euclidean structure, hopefully
+   //   supported by cfQuotRem, then
+   //     IntMod, Div should give the same result
+   //     Div(a,b) = QuotRem(a,b, &IntMod(a,b))
+   //   if the ring is not Euclidean or a field, then IntMod should return 0
+   //   and Div the exact quotient. It is assumed that the function is
+   //   ONLY called on Euclidean rings or in the case of an exact division.
+   //
+   //   cfDiv does an exact division, but has to handle illegal input
+   //   cfExactDiv does an exact division, but no error checking
+   //   (I'm not sure I understant and even less that this makes sense)
+   numberfunc cfMult, cfSub ,cfAdd ,cfDiv, cfIntMod, cfExactDiv;
+
+   /// init with an integer
+   number  (*cfInit)(long i,const coeffs r);
+
+   /// init with a GMP integer
+   number  (*cfInitMPZ)(mpz_t i, const coeffs r);
+
+   /// how complicated, (0) => 0, or positive
+   int     (*cfSize)(number n, const coeffs r);
+
+   /// convertion to int, 0 if impossible
+   int     (*cfInt)(number &n, const coeffs r);
+
+   /// Converts a non-negative number n into a GMP number, 0 if impossible
+   void     (*cfMPZ)(mpz_t result, number &n, const coeffs r);
+
+   /// changes argument  inline: a:= -a
+   /// return -a! (no copy is returned)
+   /// the result should be assigned to the original argument: e.g. a = n_InpNeg(a,r)
+   number  (*cfInpNeg)(number a, const coeffs r);
+   /// return 1/a
+   number  (*cfInvers)(number a, const coeffs r);
+   /// return a copy of a
+   number  (*cfCopy)(number a, const coeffs r);
+   number  (*cfRePart)(number a, const coeffs r);
+   number  (*cfImPart)(number a, const coeffs r);
+
+   /// print a given number (long format)
+   void    (*cfWriteLong)(number &a, const coeffs r);
+
+   /// print a given number in a shorter way, if possible
+   /// e.g. in K(a): a2 instead of a^2
+   void    (*cfWriteShort)(number &a, const coeffs r);
+
+   // it is legal, but not always useful to have cfRead(s, a, r)
+   //   just return s again.
+   // Useful application (read constants which are not an projection
+   // from int/bigint:
+   // Let ring r = R,x,dp;
+   // where R is a coeffs having "special" "named" elements (ie.
+   // the primitive element in some algebraic extension).
+   // If there is no interpreter variable of the same name, it is
+   // difficult to create non-trivial elements in R.
+   // Hence one can use the string to allow creation of R-elts using the
+   // unbound name of the special element.
+   const char *  (*cfRead)(const char * s, number * a, const coeffs r);
+
+   void    (*cfNormalize)(number &a, const coeffs r);
+
+   BOOLEAN (*cfGreater)(number a,number b, const coeffs r),
+            /// tests
+           (*cfEqual)(number a,number b, const coeffs r),
+           (*cfIsZero)(number a, const coeffs r),
+           (*cfIsOne)(number a, const coeffs r),
+           (*cfIsMOne)(number a, const coeffs r),
+       //GreaterZero is used for printing of polynomials:
+       //  a "+" is only printed in front of a coefficient
+       //  if the element is >0. It is assumed that any element
+       //  failing this will start printing with a leading "-"
+           (*cfGreaterZero)(number a, const coeffs r);
+
+   void    (*cfPower)(number a, int i, number * result, const coeffs r);
+   number  (*cfGetDenom)(number &n, const coeffs r);
+   number  (*cfGetNumerator)(number &n, const coeffs r);
+   //CF: a Euclidean ring is a commutative, unitary ring with an Euclidean
+   //  function f s.th. for all a,b in R, b ne 0, we can find q, r s.th.
+   //  a = qb+r and either r=0 or f(r) < f(b)
+   //  Note that neither q nor r nor f(r) are unique.
+   number  (*cfGcd)(number a, number b, const coeffs r);
+   number  (*cfSubringGcd)(number a, number b, const coeffs r);
+   number  (*cfExtGcd)(number a, number b, number *s, number *t,const coeffs r);
+   //given a and b in a Euclidean setting, return s,t,u,v sth.
+   //  sa + tb = gcd
+   //  ua + vb = 0
+   //  sv + tu = 1
+   //  ie. the 2x2 matrix (s t | u v) is unimodular and maps (a,b) to (g, 0)
+   //CF: note, in general, this cannot be derived from ExtGcd due to
+   //    zero divisors
+   number  (*cfXExtGcd)(number a, number b, number *s, number *t, number *u, number *v, const coeffs r);
+   //in a Euclidean ring, return the Euclidean norm as a bigint (of type number)
+   number  (*cfEucNorm)(number a, const coeffs r);
+   //in a principal ideal ring (with zero divisors): the annihilator
+   // NULL otherwise
+   number  (*cfAnn)(number a, const coeffs r);
+   //find a "canonical representative of a modulo the units of r
+   //return NULL if a is already normalized
+   //otherwise, the factor.
+   //(for Z: make positive, for z/nZ make the gcd with n
+   //aparently it is GetUnit!
+   //in a Euclidean ring, return the quotient and compute the remainder
+   //rem can be NULL
+   number  (*cfQuotRem)(number a, number b, number *rem, const coeffs r);
+   number  (*cfLcm)(number a, number b, const coeffs r);
+   number  (*cfNormalizeHelper)(number a, number b, const coeffs r);
+   void    (*cfDelete)(number * a, const coeffs r);
+
+   //CF: tries to find a canonical map from src -> dst
+   nMapFunc (*cfSetMap)(const coeffs src, const coeffs dst);
+
+   void    (*cfWriteFd)(number a, FILE *f, const coeffs r);
+   number  (*cfReadFd)( s_buff f, const coeffs r);
+
+   /// Inplace: a *= b
+   void    (*cfInpMult)(number &a, number b, const coeffs r);
+
+   /// Inplace: a += b
+   void    (*cfInpAdd)(number &a, number b, const coeffs r);
+
+   /// rational reconstruction: "best" rational a/b with a/b = p mod n
+   //  or a = bp mod n
+   //  CF: no idea what this would be in general
+   //     it seems to be extended to operate coefficient wise in extensions.
+   //     I presume then n in coeffs_BIGINT while p in coeffs
+   number  (*cfFarey)(number p, number n, const coeffs);
+
+   /// chinese remainder
+   /// returns X with X mod q[i]=x[i], i=0..rl-1
+   //CF: by the looks of it: q[i] in Z (coeffs_BIGINT)
+   //    strange things happen in naChineseRemainder for example.
+   number  (*cfChineseRemainder)(number *x, number *q,int rl, BOOLEAN sym,const coeffs);
+
+   /// degree for coeffcients: -1 for 0, 0 for "constants", ...
+   int (*cfParDeg)(number x,const coeffs r);
+
+   /// create i^th parameter or NULL if not possible
+   number  (*cfParameter)(const int i, const coeffs r);
+
+   /// a function returning random elements
+   number (*cfRandom)(siRandProc p, number p1, number p2, const coeffs cf);
+
+   /// function pointer behind n_ClearContent
+   nCoeffsEnumeratorFunc cfClearContent;
+
+   /// function pointer behind n_ClearDenominators
+   nCoeffsEnumeratorFunc cfClearDenominators;
+
+   /// conversion to CanonicalForm(factory) to number
+   number (*convFactoryNSingN)( const CanonicalForm n, const coeffs r);
+   CanonicalForm (*convSingNFactoryN)( number n, BOOLEAN setChar, const coeffs r );
+
+
+   /// the 0 as constant, NULL by default
+   number nNULL;
+
+   /// Number of Parameters in the coeffs (default 0)
+   int iNumberOfParameters;
+
+   /// array containing the names of Parameters (default NULL)
+   char const **  pParameterNames;
+   // NOTE that it replaces the following:
+// char* complex_parameter; //< the name of sqrt(-1) in n_long_C , i.e. 'i' or 'j' etc...?
+// char * m_nfParameter; //< the name of parameter in n_GF
+
+   /////////////////////////////////////////////
+   // the union stuff
+
+   //-------------------------------------------
+
+  /* for extension fields we need to be able to represent polynomials,
+     so here is the polynomial ring: */
+  ring          extRing;
+
+  //number     minpoly;  //< no longer needed: replaced by
+  //                     //< extRing->qideal->[0]
+
+
+  int        ch;  /* characteristic, set by the local *InitChar methods;
+                     In field extensions or extensions towers, the
+                     characteristic can be accessed from any of the
+                     intermediate extension fields, i.e., in this case
+                     it is redundant along the chain of field extensions;
+                     CONTRARY to SINGULAR as it was, we do NO LONGER use
+                     negative values for ch;
+                     for rings, ch will also be set and is - per def -
+                     the smallest number of 1's that sum up to zero;
+                     however, in this case ch may not fit in an int,
+                     thus ch may contain a faulty value */
+
+  short      float_len; /* additional char-flags, rInit */
+  short      float_len2; /* additional char-flags, rInit */
+
+//  BOOLEAN   CanShortOut; //< if the elements can be printed in short format
+//                       // this is set to FALSE if a parameter name has >2 chars
+//  BOOLEAN   ShortOut; //< if the elements should print in short format
+
+// ---------------------------------------------------
+  // for n_GF
+
+  int m_nfCharQ;  ///< the number of elements: q
+  int m_nfM1;       ///< representation of -1
+  int m_nfCharP;  ///< the characteristic: p
+  int m_nfCharQ1; ///< q-1
+  unsigned short *m_nfPlus1Table;
+  int *m_nfMinPoly;
+
+// ---------------------------------------------------
+// for Zp:
+  unsigned short *npInvTable;
+  unsigned short *npExpTable;
+  unsigned short *npLogTable;
+   //   int npPrimeM; // NOTE: npPrimeM is deprecated, please use ch instead!
+  int npPminus1M; ///< characteristic - 1
+//-------------------------------------------
+   int     (*cfDivComp)(number a,number b,const coeffs r);
+   BOOLEAN (*cfIsUnit)(number a,const coeffs r);
+   number  (*cfGetUnit)(number a,const coeffs r);
+   //CF: test if b divides a
+   BOOLEAN (*cfDivBy)(number a, number b, const coeffs r);
+  /* The following members are for representing the ring Z/n,
+     where n is not a prime. We distinguish four cases:
+     1.) n has at least two distinct prime factors. Then
+         modBase stores n, modExponent stores 1, modNumber
+         stores n, and mod2mMask is not used;
+     2.) n = p^k for some odd prime p and k > 1. Then
+         modBase stores p, modExponent stores k, modNumber
+         stores n, and mod2mMask is not used;
+     3.) n = 2^k for some k > 1; moreover, 2^k - 1 fits in
+         an unsigned long. Then modBase stores 2, modExponent
+         stores k, modNumber is not used, and mod2mMask stores
+         2^k - 1, i.e., the bit mask '111..1' of length k.
+     4.) n = 2^k for some k > 1; but 2^k - 1 does not fit in
+         an unsigned long. Then modBase stores 2, modExponent
+         stores k, modNumber stores n, and mod2mMask is not
+         used;
+     Cases 1.), 2.), and 4.) are covered by the implementation
+     in the files rmodulon.h and rmodulon.cc, whereas case 3.)
+     is implemented in the files rmodulo2m.h and rmodulo2m.cc. */
+  mpz_ptr    modBase;
+  unsigned long modExponent;
+  mpz_ptr    modNumber;
+  unsigned long mod2mMask;
+  //returns coeffs with updated ch, modNumber and modExp
+  coeffs (*cfQuot1)(number c, const coeffs r);
+
+  /*CF: for blackbox rings, contains data needed to define the ring.
+   * contents depends on the actual example.*/
+  void * data;
+#ifdef LDEBUG
+   // must be last entry:
+   /// Test: is "a" a correct number?
+   // DB as in debug, not data base.
+   BOOLEAN (*cfDBTest)(number a, const char *f, const int l, const coeffs r);
+#endif
+};
+
+// test properties and type
+/// Returns the type of coeffs domain
+static FORCE_INLINE n_coeffType getCoeffType(const coeffs r)
+{ assume(r != NULL); return r->type; }
+
+/// one-time initialisations for new coeffs
+/// in case of an error return NULL
+coeffs nInitChar(n_coeffType t, void * parameter);
+
+/// "copy" coeffs, i.e. increment ref
+static FORCE_INLINE coeffs nCopyCoeff(const coeffs r)
+{ assume(r!=NULL); r->ref++; return r;}
+
+/// undo all initialisations
+void nKillChar(coeffs r);
+
+/// initialisations after each ring change
+static FORCE_INLINE void nSetChar(const coeffs r)
+{ STATISTIC(nSetChar);  assume(r!=NULL); assume(r->cfSetChar != NULL); r->cfSetChar(r); }
+
+void           nNew(number * a);
+#define n_New(n, r)           nNew(n)
+
+
+/// Return the characteristic of the coeff. domain.
+static FORCE_INLINE int n_GetChar(const coeffs r)
+{ STATISTIC(n_GetChar); assume(r != NULL); return r->ch; }
+
+
+// the access methods (part 2):
+
+/// return a copy of 'n'
+static FORCE_INLINE number n_Copy(number n,    const coeffs r)
+{ STATISTIC(n_Copy);   assume(r != NULL); assume(r->cfCopy!=NULL); return r->cfCopy(n, r); }
+
+/// delete 'p'
+static FORCE_INLINE void   n_Delete(number* p, const coeffs r)
+{ STATISTIC(n_Delete);   assume(r != NULL); assume(r->cfDelete!= NULL); r->cfDelete(p, r); }
+
+/// TRUE iff 'a' and 'b' represent the same number;
+/// they may have different representations
+static FORCE_INLINE BOOLEAN n_Equal(number a, number b, const coeffs r)
+{ STATISTIC(n_Equal); assume(r != NULL); assume(r->cfEqual!=NULL); return r->cfEqual(a, b, r); }
+
+/// TRUE iff 'n' represents the zero element
+static FORCE_INLINE BOOLEAN n_IsZero(number n, const coeffs r)
+{ STATISTIC(n_IsZero); assume(r != NULL); assume(r->cfIsZero!=NULL); return r->cfIsZero(n,r); }
+
+/// TRUE iff 'n' represents the one element
+static FORCE_INLINE BOOLEAN n_IsOne(number n,  const coeffs r)
+{ STATISTIC(n_IsOne); assume(r != NULL); assume(r->cfIsOne!=NULL); return r->cfIsOne(n,r); }
+
+/// TRUE iff 'n' represents the additive inverse of the one element, i.e. -1
+static FORCE_INLINE BOOLEAN n_IsMOne(number n, const coeffs r)
+{ STATISTIC(n_IsMOne); assume(r != NULL); assume(r->cfIsMOne!=NULL); return r->cfIsMOne(n,r); }
+
+/// ordered fields: TRUE iff 'n' is positive;
+/// in Z/pZ: TRUE iff 0 < m <= roundedBelow(p/2), where m is the long
+///          representing n
+/// in C:    TRUE iff (Im(n) != 0 and Im(n) >= 0) or
+///                   (Im(n) == 0 and Re(n) >= 0)
+/// in K(a)/<p(a)>: TRUE iff (n != 0 and (LC(n) > 0 or deg(n) > 0))
+/// in K(t_1, ..., t_n): TRUE iff (LC(numerator(n) is a constant and > 0)
+///                            or (LC(numerator(n) is not a constant)
+/// in Z/2^kZ: TRUE iff 0 < n <= 2^(k-1)
+/// in Z/mZ: TRUE iff the internal mpz is greater than zero
+/// in Z: TRUE iff n > 0
+///
+/// !!! Recommendation: remove implementations for unordered fields
+/// !!!                 and raise errors instead, in these cases
+/// !!! Do not follow this recommendation: while writing polys,
+/// !!! between 2 monomials will be an additional + iff !n_GreaterZero(next coeff)
+///     Then change definition to include n_GreaterZero => printing does NOT
+///     start with -
+///
+static FORCE_INLINE BOOLEAN n_GreaterZero(number n, const coeffs r)
+{ STATISTIC(n_GreaterZero); assume(r != NULL); assume(r->cfGreaterZero!=NULL); return r->cfGreaterZero(n,r); }
+
+/// ordered fields: TRUE iff 'a' is larger than 'b';
+/// in Z/pZ: TRUE iff la > lb, where la and lb are the long's representing
+//                             a and b, respectively
+/// in C:    TRUE iff (Im(a) > Im(b))
+/// in K(a)/<p(a)>: TRUE iff (a != 0 and (b == 0 or deg(a) > deg(b))
+/// in K(t_1, ..., t_n): TRUE only if one or both numerator polynomials are
+///                      zero or if their degrees are equal. In this case,
+///                      TRUE if LC(numerator(a)) > LC(numerator(b))
+/// in Z/2^kZ: TRUE if n_DivBy(a, b)
+/// in Z/mZ: TRUE iff the internal mpz's fulfill the relation '>'
+/// in Z: TRUE iff a > b
+///
+/// !!! Recommendation: remove implementations for unordered fields
+/// !!!                 and raise errors instead, in these cases
+static FORCE_INLINE BOOLEAN n_Greater(number a, number b, const coeffs r)
+{ STATISTIC(n_Greater); assume(r != NULL); assume(r->cfGreater!=NULL); return r->cfGreater(a,b,r); }
+
+#ifdef HAVE_RINGS
+static FORCE_INLINE int n_DivComp(number a, number b, const coeffs r)
+{ STATISTIC(n_DivComp); assume(r != NULL); assume(r->cfDivComp!=NULL); return r->cfDivComp (a,b,r); }
+
+/// TRUE iff n has a multiplicative inverse in the given coeff field/ring r
+static FORCE_INLINE BOOLEAN n_IsUnit(number n, const coeffs r)
+{ STATISTIC(n_IsUnit); assume(r != NULL); assume(r->cfIsUnit!=NULL); return r->cfIsUnit(n,r); }
+
+/// in Z: 1
+/// in Z/kZ (where k is not a prime): largest divisor of n (taken in Z) that
+///                                   is co-prime with k
+/// in Z/2^kZ: largest odd divisor of n (taken in Z)
+/// other cases: not implemented
+// CF: shold imply that n/GetUnit(n) is normalized in Z/kZ
+//   it would make more sense to return the inverse...
+static FORCE_INLINE number n_GetUnit(number n, const coeffs r)
+{ STATISTIC(n_GetUnit); assume(r != NULL); assume(r->cfGetUnit!=NULL); return r->cfGetUnit(n,r); }
+
+static FORCE_INLINE coeffs n_CoeffRingQuot1(number c, const coeffs r)
+{ STATISTIC(n_CoeffRingQuot1); assume(r != NULL); assume(r->cfQuot1 != NULL); return r->cfQuot1(c, r); }
+#endif
+
+/// a number representing i in the given coeff field/ring r
+static FORCE_INLINE number n_Init(long i,       const coeffs r)
+{ STATISTIC(n_Init); assume(r != NULL); assume(r->cfInit!=NULL); return r->cfInit(i,r); }
+
+/// conversion of a GMP integer to number
+static FORCE_INLINE number n_InitMPZ(mpz_t n,     const coeffs r)
+{ STATISTIC(n_InitMPZ); assume(r != NULL); assume(r->cfInitMPZ != NULL); return r->cfInitMPZ(n,r); }
+
+/// conversion of n to an int; 0 if not possible
+/// in Z/pZ: the representing int lying in (-p/2 .. p/2]
+static FORCE_INLINE int n_Int(number &n,       const coeffs r)
+{ STATISTIC(n_Int); assume(r != NULL); assume(r->cfInt!=NULL); return r->cfInt(n,r); }
+
+/// conversion of n to a GMP integer; 0 if not possible
+static FORCE_INLINE void n_MPZ(mpz_t result, number &n,       const coeffs r)
+{ STATISTIC(n_MPZ); assume(r != NULL); assume(r->cfMPZ!=NULL); r->cfMPZ(result, n, r); }
+
+
+/// in-place negation of n
+/// MUST BE USED: n = n_InpNeg(n) (no copy is returned)
+static FORCE_INLINE number n_InpNeg(number n,     const coeffs r)
+{ STATISTIC(n_InpNeg); assume(r != NULL); assume(r->cfInpNeg!=NULL); return r->cfInpNeg(n,r); }
+
+/// return the multiplicative inverse of 'a';
+/// raise an error if 'a' is not invertible
+///
+/// !!! Recommendation: rename to 'n_Inverse'
+static FORCE_INLINE number n_Invers(number a,  const coeffs r)
+{ STATISTIC(n_Invers); assume(r != NULL); assume(r->cfInvers!=NULL); return r->cfInvers(a,r); }
+
+/// return a non-negative measure for the complexity of n;
+/// return 0 only when n represents zero;
+/// (used for pivot strategies in matrix computations with entries from r)
+static FORCE_INLINE int    n_Size(number n,    const coeffs r)
+{ STATISTIC(n_Size); assume(r != NULL); assume(r->cfSize!=NULL); return r->cfSize(n,r); }
+
+/// inplace-normalization of n;
+/// produces some canonical representation of n;
+///
+/// !!! Recommendation: remove this method from the user-interface, i.e.,
+/// !!!                 this should be hidden
+static FORCE_INLINE void   n_Normalize(number& n, const coeffs r)
+{ STATISTIC(n_Normalize); assume(r != NULL); assume(r->cfNormalize!=NULL); r->cfNormalize(n,r); }
+
+/// write to the output buffer of the currently used reporter
+//CF: the "&" should be removed, as one wants to write constants as well
+static FORCE_INLINE void   n_WriteLong(number& n,  const coeffs r)
+{ STATISTIC(n_WriteLong); assume(r != NULL); assume(r->cfWriteLong!=NULL); r->cfWriteLong(n,r); }
+
+/// write to the output buffer of the currently used reporter
+/// in a shortest possible way, e.g. in K(a): a2 instead of a^2
+static FORCE_INLINE void   n_WriteShort(number& n,  const coeffs r)
+{ STATISTIC(n_WriteShort); assume(r != NULL); assume(r->cfWriteShort!=NULL); r->cfWriteShort(n,r); }
+
+static FORCE_INLINE void   n_Write(number& n,  const coeffs r, const BOOLEAN bShortOut = TRUE)
+{ STATISTIC(n_Write); if (bShortOut) n_WriteShort(n, r); else n_WriteLong(n, r); }
+
+
+/// !!! Recommendation: This method is too cryptic to be part of the user-
+/// !!!                 interface. As defined here, it is merely a helper
+/// !!!                 method for parsing number input strings.
+static FORCE_INLINE const char *n_Read(const char * s, number * a, const coeffs r)
+{ STATISTIC(n_Read); assume(r != NULL); assume(r->cfRead!=NULL); return r->cfRead(s, a, r); }
+
+/// return the denominator of n
+/// (if elements of r are by nature not fractional, result is 1)
+static FORCE_INLINE number n_GetDenom(number& n, const coeffs r)
+{ STATISTIC(n_GetDenom); assume(r != NULL); assume(r->cfGetDenom!=NULL); return r->cfGetDenom(n, r); }
+
+/// return the numerator of n
+/// (if elements of r are by nature not fractional, result is n)
+static FORCE_INLINE number n_GetNumerator(number& n, const coeffs r)
+{ STATISTIC(n_GetNumerator); assume(r != NULL); assume(r->cfGetNumerator!=NULL); return r->cfGetNumerator(n, r); }
+
+/// return the quotient of 'a' and 'b', i.e., a/b;
+/// raise an error if 'b' is not invertible in r
+static FORCE_INLINE number n_Div(number a, number b, const coeffs r)
+{ STATISTIC(n_Div); assume(r != NULL); assume(r->cfDiv!=NULL); return r->cfDiv(a,b,r); }
+
+/// assume that there is a canonical subring in cf and we know
+/// that division is possible for these a and b in the subring,
+/// n_ExactDiv performs it, may skip additional tests.
+/// Can always be substituted by n_Div at the cost of larger  computing time.
+static FORCE_INLINE number n_ExactDiv(number a, number b, const coeffs r)
+{ STATISTIC(n_ExactDiv); assume(r != NULL); assume(r->cfExactDiv!=NULL); return r->cfExactDiv(a,b,r); }
+
+/// for r a field, return n_Init(0,r)
+/// otherwise: n_Div(a,b,r)*b+n_IntMod(a,b,r)==a
+static FORCE_INLINE number n_IntMod(number a, number b, const coeffs r)
+{ STATISTIC(n_IntMod); assume(r != NULL); return r->cfIntMod(a,b,r); }
+
+/// fill res with the power a^b
+static FORCE_INLINE void   n_Power(number a, int b, number *res, const coeffs r)
+{ STATISTIC(n_Power); assume(r != NULL); assume(r->cfPower!=NULL); r->cfPower(a,b,res,r); }
+
+/// return the product of 'a' and 'b', i.e., a*b
+static FORCE_INLINE number n_Mult(number a, number b, const coeffs r)
+{ STATISTIC(n_Mult); assume(r != NULL); assume(r->cfMult!=NULL); return r->cfMult(a, b, r); }
+
+/// multiplication of 'a' and 'b';
+/// replacement of 'a' by the product a*b
+static FORCE_INLINE void n_InpMult(number &a, number b, const coeffs r)
+{ STATISTIC(n_InpMult); assume(r != NULL); assume(r->cfInpMult!=NULL); r->cfInpMult(a,b,r); }
+
+/// addition of 'a' and 'b';
+/// replacement of 'a' by the sum a+b
+static FORCE_INLINE void n_InpAdd(number &a, number b, const coeffs r)
+{ STATISTIC(n_InpAdd); assume(r != NULL); assume(r->cfInpAdd!=NULL); r->cfInpAdd(a,b,r);
+
+#ifdef HAVE_NUMSTATS
+  // avoid double counting
+  if( r->cfIsZero(a,r) ) STATISTIC(n_CancelOut);
+#endif
+}
+
+/// return the sum of 'a' and 'b', i.e., a+b
+static FORCE_INLINE number n_Add(number a, number b, const coeffs r)
+{ STATISTIC(n_Add); assume(r != NULL); assume(r->cfAdd!=NULL); const number sum = r->cfAdd(a, b, r);
+
+#ifdef HAVE_NUMSTATS
+  // avoid double counting
+  if( r->cfIsZero(sum,r) ) STATISTIC(n_CancelOut);
+#endif
+
+ return sum;
+}
+
+
+/// return the difference of 'a' and 'b', i.e., a-b
+static FORCE_INLINE number n_Sub(number a, number b, const coeffs r)
+{ STATISTIC(n_Sub); assume(r != NULL); assume(r->cfSub!=NULL); const number d = r->cfSub(a, b, r);
+
+#ifdef HAVE_NUMSTATS
+  // avoid double counting
+  if( r->cfIsZero(d,r) ) STATISTIC(n_CancelOut);
+#endif
+
+  return d;
+}
+
+/// in Z: return the gcd of 'a' and 'b'
+/// in Z/nZ, Z/2^kZ: computed as in the case Z
+/// in Z/pZ, C, R: not implemented
+/// in Q: return the gcd of the numerators of 'a' and 'b'
+/// in K(a)/<p(a)>: not implemented
+/// in K(t_1, ..., t_n): not implemented
+static FORCE_INLINE number n_Gcd(number a, number b, const coeffs r)
+{ STATISTIC(n_Gcd); assume(r != NULL); assume(r->cfGcd!=NULL); return r->cfGcd(a,b,r); }
+static FORCE_INLINE number n_SubringGcd(number a, number b, const coeffs r)
+{ STATISTIC(n_SubringGcd); assume(r != NULL); assume(r->cfSubringGcd!=NULL); return r->cfSubringGcd(a,b,r); }
+
+/// beware that ExtGCD is only relevant for a few chosen coeff. domains
+/// and may perform something unexpected in some cases...
+static FORCE_INLINE number n_ExtGcd(number a, number b, number *s, number *t, const coeffs r)
+{ STATISTIC(n_ExtGcd); assume(r != NULL); assume(r->cfExtGcd!=NULL); return r->cfExtGcd (a,b,s,t,r); }
+static FORCE_INLINE number n_XExtGcd(number a, number b, number *s, number *t, number *u, number *v, const coeffs r)
+{ STATISTIC(n_XExtGcd); assume(r != NULL); assume(r->cfXExtGcd!=NULL); return r->cfXExtGcd (a,b,s,t,u,v,r); }
+static FORCE_INLINE number  n_EucNorm(number a, const coeffs r)
+{ STATISTIC(n_EucNorm); assume(r != NULL); assume(r->cfEucNorm!=NULL); return r->cfEucNorm (a,r); }
+/// if r is a ring with zero divisors, return an annihilator!=0 of b
+/// otherwise return NULL
+static FORCE_INLINE number  n_Ann(number a, const coeffs r)
+{ STATISTIC(n_Ann); assume(r != NULL); return r->cfAnn (a,r); }
+static FORCE_INLINE number  n_QuotRem(number a, number b, number *q, const coeffs r)
+{ STATISTIC(n_QuotRem); assume(r != NULL); assume(r->cfQuotRem!=NULL); return r->cfQuotRem (a,b,q,r); }
+
+
+/// in Z: return the lcm of 'a' and 'b'
+/// in Z/nZ, Z/2^kZ: computed as in the case Z
+/// in Z/pZ, C, R: not implemented
+/// in K(a)/<p(a)>: not implemented
+/// in K(t_1, ..., t_n): not implemented
+static FORCE_INLINE number n_Lcm(number a, number b, const coeffs r)
+{ STATISTIC(n_Lcm); assume(r != NULL); assume(r->cfLcm!=NULL); return r->cfLcm(a,b,r); }
+
+/// assume that r is a quotient field (otherwise, return 1)
+/// for arguments (a1/a2,b1/b2) return (lcm(a1,b2)/1)
+static FORCE_INLINE number n_NormalizeHelper(number a, number b, const coeffs r)
+{ STATISTIC(n_NormalizeHelper); assume(r != NULL); assume(r->cfNormalizeHelper!=NULL); return r->cfNormalizeHelper(a,b,r); }
+
+/// set the mapping function pointers for translating numbers from src to dst
+static FORCE_INLINE nMapFunc n_SetMap(const coeffs src, const coeffs dst)
+{ STATISTIC(n_SetMap); assume(src != NULL && dst != NULL); assume(dst->cfSetMap!=NULL); return dst->cfSetMap(src,dst); }
+
+#ifdef LDEBUG
+/// test whether n is a correct number;
+/// only used if LDEBUG is defined
+static FORCE_INLINE BOOLEAN n_DBTest(number n, const char *filename, const int linenumber, const coeffs r)
+{ STATISTIC(n_Test); assume(r != NULL); assume(r->cfDBTest != NULL); return r->cfDBTest(n, filename, linenumber, r); }
+#else
+// is it really necessary to define this function in any case?
+/// test whether n is a correct number;
+/// only used if LDEBUG is defined
+static FORCE_INLINE BOOLEAN n_DBTest(number, const char*, const int, const coeffs)
+{ STATISTIC(n_Test);  return TRUE; }
+#endif
+
+/// output the coeff description
+static FORCE_INLINE void   n_CoeffWrite(const coeffs r, BOOLEAN details = TRUE)
+{ STATISTIC(n_CoeffWrite); assume(r != NULL); assume(r->cfCoeffWrite != NULL); r->cfCoeffWrite(r, details); }
+
+// Tests:
+static FORCE_INLINE BOOLEAN nCoeff_is_Ring_2toM(const coeffs r)
+{ assume(r != NULL); return (getCoeffType(r)==n_Z2m); }
+
+static FORCE_INLINE BOOLEAN nCoeff_is_Ring_ModN(const coeffs r)
+{ assume(r != NULL); return (getCoeffType(r)==n_Zn); }
+
+static FORCE_INLINE BOOLEAN nCoeff_is_Ring_PtoM(const coeffs r)
+{ assume(r != NULL); return (getCoeffType(r)==n_Znm); }
+
+static FORCE_INLINE BOOLEAN nCoeff_is_Ring_Z(const coeffs r)
+{ assume(r != NULL); return (getCoeffType(r)==n_Z); }
+
+static FORCE_INLINE BOOLEAN nCoeff_is_Ring(const coeffs r)
+{ assume(r != NULL); return (r->is_field==0); }
+
+/// returns TRUE, if r is a field or r has no zero divisors (i.e is a domain)
+static FORCE_INLINE BOOLEAN nCoeff_is_Domain(const coeffs r)
+{
+  assume(r != NULL);
+  return (r->is_domain);
+}
+
+/// test whether 'a' is divisible 'b';
+/// for r encoding a field: TRUE iff 'b' does not represent zero
+/// in Z: TRUE iff 'b' divides 'a' (with remainder = zero)
+/// in Z/nZ: TRUE iff (a = 0 and b divides n in Z) or
+///                   (a != 0 and b/gcd(a, b) is co-prime with n, i.e.
+///                                              a unit in Z/nZ)
+/// in Z/2^kZ: TRUE iff ((a = 0 mod 2^k) and (b = 0 or b is a power of 2))
+///                  or ((a, b <> 0) and (b/gcd(a, b) is odd))
+static FORCE_INLINE BOOLEAN n_DivBy(number a, number b, const coeffs r)
+{ STATISTIC(n_DivBy); assume(r != NULL);
+#ifdef HAVE_RINGS
+  if( nCoeff_is_Ring(r) )
+  {
+    assume(r->cfDivBy!=NULL); return r->cfDivBy(a,b,r);
+  }
+#endif
+  return !n_IsZero(b, r);
+}
+
+static FORCE_INLINE number n_ChineseRemainderSym(number *a, number *b, int rl, BOOLEAN sym,const coeffs r)
+{ STATISTIC(n_ChineseRemainderSym); assume(r != NULL); assume(r->cfChineseRemainder != NULL); return r->cfChineseRemainder(a,b,rl,sym,r); }
+
+static FORCE_INLINE number n_Farey(number a, number b, const coeffs r)
+{ STATISTIC(n_Farey); assume(r != NULL); assume(r->cfFarey != NULL); return r->cfFarey(a,b,r); }
+
+static FORCE_INLINE int n_ParDeg(number n, const coeffs r)
+{ STATISTIC(n_ParDeg); assume(r != NULL); assume(r->cfParDeg != NULL); return r->cfParDeg(n,r); }
+
+/// Returns the number of parameters
+static FORCE_INLINE int n_NumberOfParameters(const coeffs r)
+{ STATISTIC(n_NumberOfParameters); assume(r != NULL); return r->iNumberOfParameters; }
+
+/// Returns a (const!) pointer to (const char*) names of parameters
+static FORCE_INLINE char const * * n_ParameterNames(const coeffs r)
+{ STATISTIC(n_ParameterNames); assume(r != NULL); return r->pParameterNames; }
+
+/// return the (iParameter^th) parameter as a NEW number
+/// NOTE: parameter numbering: 1..n_NumberOfParameters(...)
+static FORCE_INLINE number n_Param(const int iParameter, const coeffs r)
+{ assume(r != NULL);
+  assume((iParameter >= 1) || (iParameter <= n_NumberOfParameters(r)));
+  assume(r->cfParameter != NULL);
+  STATISTIC(n_Param); return r->cfParameter(iParameter, r);
+}
+
+static FORCE_INLINE number  n_RePart(number i, const coeffs cf)
+{ STATISTIC(n_RePart); assume(cf != NULL); assume(cf->cfRePart!=NULL); return cf->cfRePart(i,cf); }
+
+static FORCE_INLINE number  n_ImPart(number i, const coeffs cf)
+{ STATISTIC(n_ImPart); assume(cf != NULL); assume(cf->cfImPart!=NULL); return cf->cfImPart(i,cf); }
+
+/// returns TRUE, if r is not a field and r has non-trivial units
+static FORCE_INLINE BOOLEAN nCoeff_has_Units(const coeffs r)
+{ assume(r != NULL); return ((getCoeffType(r)==n_Zn) || (getCoeffType(r)==n_Z2m) || (getCoeffType(r)==n_Znm)); }
+
+static FORCE_INLINE BOOLEAN nCoeff_is_Zp(const coeffs r)
+{ assume(r != NULL); return getCoeffType(r)==n_Zp; }
+
+static FORCE_INLINE BOOLEAN nCoeff_is_Zp(const coeffs r, int p)
+{ assume(r != NULL); return ((getCoeffType(r)==n_Zp) && (r->ch == p)); }
+
+static FORCE_INLINE BOOLEAN nCoeff_is_Q(const coeffs r)
+{ assume(r != NULL); return getCoeffType(r)==n_Q && (r->is_field); }
+
+static FORCE_INLINE BOOLEAN nCoeff_is_numeric(const coeffs r) /* R, long R, long C */
+{ assume(r != NULL);  return (getCoeffType(r)==n_R) || (getCoeffType(r)==n_long_R) || (getCoeffType(r)==n_long_C); }
+// (r->ringtype == 0) && (r->ch ==  -1); ??
+
+static FORCE_INLINE BOOLEAN nCoeff_is_R(const coeffs r)
+{ assume(r != NULL); return getCoeffType(r)==n_R; }
+
+static FORCE_INLINE BOOLEAN nCoeff_is_GF(const coeffs r)
+{ assume(r != NULL); return getCoeffType(r)==n_GF; }
+
+static FORCE_INLINE BOOLEAN nCoeff_is_GF(const coeffs r, int q)
+{ assume(r != NULL); return (getCoeffType(r)==n_GF) && (r->ch == q); }
+
+/* TRUE iff r represents an algebraic or transcendental extension field */
+static FORCE_INLINE BOOLEAN nCoeff_is_Extension(const coeffs r)
+{
+  assume(r != NULL);
+  return (getCoeffType(r)==n_algExt) || (getCoeffType(r)==n_transExt);
+}
+
+/* DO NOT USE (only kept for compatibility reasons towards the SINGULAR
+   svn trunk);
+   intension: should be TRUE iff the given r is an extension field above
+   some Z/pZ;
+   actually: TRUE iff the given r is an extension tower of arbitrary
+   height above some field of characteristic p (may be Z/pZ or some
+   Galois field of characteristic p) */
+static FORCE_INLINE BOOLEAN nCoeff_is_Zp_a(const coeffs r)
+{
+  assume(r != NULL);
+  return ((!nCoeff_is_Ring(r)) && (n_GetChar(r) != 0) && nCoeff_is_Extension(r));
+}
+
+/* DO NOT USE (only kept for compatibility reasons towards the SINGULAR
+   svn trunk);
+   intension: should be TRUE iff the given r is an extension field above
+   Z/pZ (with p as provided);
+   actually: TRUE iff the given r is an extension tower of arbitrary
+   height above some field of characteristic p (may be Z/pZ or some
+   Galois field of characteristic p) */
+static FORCE_INLINE BOOLEAN nCoeff_is_Zp_a(const coeffs r, int p)
+{
+  assume(r != NULL);
+  assume(p != 0);
+  return ((!nCoeff_is_Ring(r)) && (n_GetChar(r) == p) && nCoeff_is_Extension(r));
+}
+
+/* DO NOT USE (only kept for compatibility reasons towards the SINGULAR
+   svn trunk);
+   intension: should be TRUE iff the given r is an extension field
+   above Q;
+   actually: TRUE iff the given r is an extension tower of arbitrary
+   height above some field of characteristic 0 (may be Q, R, or C) */
+static FORCE_INLINE BOOLEAN nCoeff_is_Q_a(const coeffs r)
+{
+  assume(r != NULL);
+  return ((n_GetChar(r) == 0) && nCoeff_is_Extension(r));
+}
+
+
+
+
+static FORCE_INLINE BOOLEAN nCoeff_is_long_R(const coeffs r)
+{ assume(r != NULL); return getCoeffType(r)==n_long_R; }
+
+static FORCE_INLINE BOOLEAN nCoeff_is_long_C(const coeffs r)
+{ assume(r != NULL); return getCoeffType(r)==n_long_C; }
+
+static FORCE_INLINE BOOLEAN nCoeff_is_CF(const coeffs r)
+{ assume(r != NULL); return getCoeffType(r)==n_CF; }
+
+/// TRUE, if the computation of the inverse is fast,
+/// i.e. prefer leading coeff. 1 over content
+static FORCE_INLINE BOOLEAN nCoeff_has_simple_inverse(const coeffs r)
+{ assume(r != NULL); return r->has_simple_Inverse; }
+
+/// TRUE if n_Delete/n_New are empty operations
+static FORCE_INLINE BOOLEAN nCoeff_has_simple_Alloc(const coeffs r)
+{ assume(r != NULL); return r->has_simple_Alloc; }
+
+/// TRUE iff r represents an algebraic extension field
+static FORCE_INLINE BOOLEAN nCoeff_is_algExt(const coeffs r)
+{ assume(r != NULL); return (getCoeffType(r)==n_algExt); }
+
+/// is it an alg. ext. of Q?
+static FORCE_INLINE BOOLEAN nCoeff_is_Q_algext(const coeffs r)
+{ assume(r != NULL); return ((n_GetChar(r) == 0) && nCoeff_is_algExt(r)); }
+
+/// TRUE iff r represents a transcendental extension field
+static FORCE_INLINE BOOLEAN nCoeff_is_transExt(const coeffs r)
+{ assume(r != NULL); return (getCoeffType(r)==n_transExt); }
+
+/// BOOLEAN n_Test(number a, const coeffs r)
+#define n_Test(a,r)  n_DBTest(a, __FILE__, __LINE__, r)
+
+/// Computes the content and (inplace) divides it out on a collection
+/// of numbers
+/// number @em c is the content (i.e. the GCD of all the coeffs, which
+/// we divide out inplace)
+/// NOTE: it assumes all coefficient numbers to be integer!!!
+/// NOTE/TODO: see also the description by Hans
+/// TODO: rename into n_ClearIntegerContent
+static FORCE_INLINE void n_ClearContent(ICoeffsEnumerator& numberCollectionEnumerator, number& c, const coeffs r)
+{ STATISTIC(n_ClearContent); assume(r != NULL); r->cfClearContent(numberCollectionEnumerator, c, r); }
+
+/// (inplace) Clears denominators on a collection of numbers
+/// number @em d is the LCM of all the coefficient denominators (i.e. the number
+/// with which all the number coeffs. were multiplied)
+/// NOTE/TODO: see also the description by Hans
+static FORCE_INLINE void n_ClearDenominators(ICoeffsEnumerator& numberCollectionEnumerator, number& d, const coeffs r)
+{ STATISTIC(n_ClearDenominators); assume(r != NULL); r->cfClearDenominators(numberCollectionEnumerator, d, r); }
+
+// convenience helpers (no number returned - but the input enumeration
+// is to be changed
+// TODO: do we need separate hooks for these as our existing code does
+// *different things* there: compare p_Cleardenom (which calls
+// *p_Content) and p_Cleardenom_n (which doesn't)!!!
+
+static FORCE_INLINE void n_ClearContent(ICoeffsEnumerator& numberCollectionEnumerator, const coeffs r)
+{ STATISTIC(n_ClearContent); number c; n_ClearContent(numberCollectionEnumerator, c, r); n_Delete(&c, r); }
+
+static FORCE_INLINE void n_ClearDenominators(ICoeffsEnumerator& numberCollectionEnumerator, const coeffs r)
+{ STATISTIC(n_ClearDenominators); assume(r != NULL); number d; n_ClearDenominators(numberCollectionEnumerator, d, r); n_Delete(&d, r); }
+
+
+/// print a number (BEWARE of string buffers!)
+/// mostly for debugging
+void   n_Print(number& a,  const coeffs r);
+
+
+
+/// TODO: make it a virtual method of coeffs, together with:
+/// Decompose & Compose, rParameter & rPar
+static FORCE_INLINE char * nCoeffString(const coeffs cf)
+{ STATISTIC(nCoeffString); assume( cf != NULL ); return cf->cfCoeffString(cf); }
+
+
+static FORCE_INLINE char * nCoeffName (const coeffs cf)
+{ STATISTIC(nCoeffName); assume( cf != NULL ); return cf->cfCoeffName(cf); }
+
+static FORCE_INLINE number n_Random(siRandProc p, number p1, number p2, const coeffs cf)
+{ STATISTIC(n_Random); assume( cf != NULL ); assume( cf->cfRandom != NULL );  return cf->cfRandom(p, p1, p2, cf); }
+
+/// io via ssi:
+static FORCE_INLINE void n_WriteFd(number a, FILE *f, const coeffs r)
+{ STATISTIC(n_WriteFd); assume(r != NULL); assume(r->cfWriteFd != NULL); return r->cfWriteFd(a, f, r); }
+
+/// io via ssi:
+static FORCE_INLINE number n_ReadFd( s_buff f, const coeffs r)
+{ STATISTIC(n_ReadFd); assume(r != NULL); assume(r->cfReadFd != NULL); return r->cfReadFd(f, r); }
+
+
+// the following wrappers went to numbers.cc since they needed factory
+// knowledge!
+number n_convFactoryNSingN( const CanonicalForm n, const coeffs r);
+
+CanonicalForm n_convSingNFactoryN( number n, BOOLEAN setChar, const coeffs r );
+
+
+// TODO: remove the following functions...
+// the following 2 inline functions are just convenience shortcuts for Frank's code:
+static FORCE_INLINE void number2mpz(number n, coeffs c, mpz_t m){ n_MPZ(m, n, c); }
+static FORCE_INLINE number mpz2number(mpz_t m, coeffs c){ return n_InitMPZ(m, c); }
+
+#endif
+
diff --git a/libpolys/coeffs/ffields.cc b/libpolys/coeffs/ffields.cc
new file mode 100644
index 0000000..174ade1
--- /dev/null
+++ b/libpolys/coeffs/ffields.cc
@@ -0,0 +1,996 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: finite fields with a none-prime number of elements (via tables)
+*/
+#include <misc/auxiliary.h>
+#include <omalloc/omalloc.h>
+
+#include <misc/mylimits.h>
+#include <misc/sirandom.h>
+
+#include <reporter/reporter.h>
+
+#include "coeffs.h"
+#include "numbers.h"
+#include "longrat.h"
+
+#include <string.h>
+#include <math.h>
+#include <errno.h>
+
+BOOLEAN nfGreaterZero (number k, const coeffs r);
+number  nfMult        (number a, number b, const coeffs r);
+number  nfInit        (long i, const coeffs r);
+number  nfParameter   (int i, const coeffs r);
+int     nfInt         (number &n, const coeffs r);
+number  nfAdd         (number a, number b, const coeffs r);
+number  nfSub         (number a, number b, const coeffs r);
+void    nfPower       (number a, int i, number * result, const coeffs r);
+BOOLEAN nfIsZero      (number a, const coeffs r);
+BOOLEAN nfIsOne       (number a, const coeffs r);
+BOOLEAN nfIsMOne      (number a, const coeffs r);
+number  nfDiv         (number a, number b, const coeffs r);
+number  nfNeg         (number c, const coeffs r);
+number  nfInvers      (number c, const coeffs r);
+BOOLEAN nfGreater     (number a, number b, const coeffs r);
+BOOLEAN nfEqual       (number a, number b, const coeffs r);
+const char *  nfRead  (const char *s, number *a, const coeffs r);
+#ifdef LDEBUG
+BOOLEAN nfDBTest      (number a, const char *f, const int l, const coeffs r);
+#endif
+//void    nfSetChar     (const coeffs r);
+
+nMapFunc nfSetMap     (const coeffs src, const coeffs dst);
+char *  nfName        (number n, const coeffs r);
+void    nfReadTable   (const int c, const coeffs r);
+
+void    nfCoeffWrite(const coeffs r, BOOLEAN details);
+void    nfShowMipo(const coeffs r);
+
+
+
+/// Our Type!
+static const n_coeffType ID = n_GF;
+
+//unsigned short *nfPlus1Table=NULL; /* the table i=log(z^i) -> log(z^i+1) */
+
+const double sixteenlog2= 11.09035489;
+/* the q's from the table 'fftable' */
+unsigned short fftable[]={
+    4,  8, 16, 32, 64, 128, 256, 512,1024,2048,4096,8192,16384, 32768,
+/*2^2 2^3 2^4 2^5 2^6  2^7  2^8  2^9 2^10 2^11 2^12 2^13  2^14  2^15*/
+    9, 27, 81,243,729,2187, 6561,19683,59049,
+/*3^2 3^3 3^4 3^5 3^6  3^7  3^8   3^9  3^10*/
+   25,125,625,3125,15625,
+/*5^2 5^3 5^4 5^5  5^6*/
+   49,343,2401,16807,
+/*7^2 7^3  7^4 7^5*/
+   121,1331, 14641,
+/*11^2 11^3  11^4*/
+  169, 2197, 28561,
+/*13^2 13^3  13^4*/
+  289, 4913,
+/*17^2 17^3*/
+  361, 6859,
+/*19^2 19^3*/
+  529, 12167,
+/*23^2 23^3*/
+  841, 24389,
+/*29^2 29^3*/
+  961, 29791,
+/*31^2 31^3*/
+  1369, 50653,
+/*37^2  37^3*/
+  1681, /*41^2*/
+  1849, /*43^2*/
+  2209, /*47^2*/
+  2809, /*53^2*/
+  3481, /*59^2*/
+  3721, /*61^2*/
+  4489, /*67^2*/
+  5041, /*71^2*/
+  5329, /*73^2*/
+  6241, /*79^2*/
+  6889, /*83^2*/
+  7921, /*89^2*/
+  9409, /*97^2*/
+  10201, /*101^2*/
+  10609, /*103^2*/
+  11449, /*107^2*/
+  11881, /*109^2*/
+  12769, /*113^2*/
+  16129, /*127^2*/
+  17161, /*131^2*/
+  18769, /*137^2*/
+  19321, /*139^2*/
+  22201, /*149^2*/
+  22801, /*151^2*/
+  24649, /*157^2*/
+  26569, /*163^2*/
+  27889, /*167^2*/
+  29929, /*173^2*/
+  32041, /*179^2*/
+  32761, /*181^2*/
+  36481, /*191^2*/
+  37249, /*193^2*/
+  38809, /*197^2*/
+  39601, /*199^2*/
+  49729, /*223^2*/
+  44521, /*211^2*/
+  51529, /*227^2*/
+  52441, /*229^2*/
+  54289, /*233^2*/
+  57121, /*239^2*/
+  58081, /*241^2*/
+  63001, /*251^2*/
+  0 };
+
+/*1
+* numbers in GF(p^n):
+* let nfCharQ=q=nfCharP^n=p^n
+* GF(q)\{0} will be generated by powers of an element Z
+* Z^i will be represented by the int i, 1 by the int 0, 0 by the int q=nfChar
+*/
+
+#ifdef LDEBUG
+/*2
+* debugging: is a a valid representation of a number ?
+*/
+BOOLEAN nfDBTest (number a, const char *f, const int l, const coeffs r)
+{
+  assume( r->m_nfPlus1Table != NULL );
+  if (((long)a<0L) || ((long)a>(long)r->m_nfCharQ))
+  {
+    Print("wrong %d in %s:%d\n",(int)((long)a),f,l);
+    return FALSE;
+  }
+  int i=0;
+  do
+  {
+    if (r->m_nfPlus1Table[i]>r->m_nfCharQ)
+    {
+      Print("wrong table %d=%d in %s:%d\n",i,r->m_nfPlus1Table[i],f,l);
+      return FALSE;
+    }
+    i++;
+  } while (i<r->m_nfCharQ);
+  return TRUE;
+}
+#define nfTest(N, R) nfDBTest(N,__FILE__,__LINE__, R)
+#endif
+
+/*2
+* k >= 0 ?
+*/
+BOOLEAN nfGreaterZero (number k, const coeffs r)
+{
+#ifdef LDEBUG
+  nfTest(k, r);
+#endif
+  return !nfIsZero(k, r) && !nfIsMOne(k, r);
+}
+
+/*2
+* a*b
+*/
+number nfMult (number a,number b, const coeffs r)
+{
+#ifdef LDEBUG
+  nfTest(a, r);
+  nfTest(b, r);
+#endif
+  if (((long)a == (long)r->m_nfCharQ) || ((long)b == (long)r->m_nfCharQ))
+    return (number)(long)r->m_nfCharQ;
+  /*else*/
+  int i=(int)((long)a+(long)b);
+  if (i>=r->m_nfCharQ1) i-=r->m_nfCharQ1;
+#ifdef LDEBUG
+  nfTest((number)(long)i, r);
+#endif
+  return (number)(long)i;
+}
+
+/*2
+* int -> number
+*/
+number nfInit (long i, const coeffs r)
+{
+  assume( r->m_nfPlus1Table != NULL );
+  // Hmm .. this is just to prevent initialization
+  // from nfInitChar to go into an infinite loop
+  if (i==0) return (number)(long)r->m_nfCharQ;
+  while (i <  0)    i += r->m_nfCharP;
+  while (i >= r->m_nfCharP) i -= r->m_nfCharP;
+  if (i==0) return (number)(long)r->m_nfCharQ;
+  unsigned short c=0;
+  while (i>1)
+  {
+    c=r->m_nfPlus1Table[c];
+    i--;
+  }
+#ifdef LDEBUG
+  nfTest((number)(long)c, r);
+#endif
+  return (number)(long)c;
+}
+
+/*
+* the generating element `z`
+*/
+number nfParameter (int i, const coeffs)
+{
+  assume(i==1);
+
+  if( i == 1 )
+    return (number)1;
+
+  return NULL;
+}
+
+/*2
+* the degree of the "alg. number"
+*/
+static int nfParDeg(number n, const coeffs r)
+{
+#ifdef LDEBUG
+  nfTest(n, r);
+#endif
+  if((long)r->m_nfCharQ == (long)n) return -1;
+  return (int)((long)n);
+}
+
+/*2
+* number -> int
+*/
+int nfInt (number &, const coeffs )
+{
+  return 0;
+}
+
+/*2
+* a + b
+*/
+number nfAdd (number a, number b, const coeffs R)
+{
+/*4 z^a+z^b=z^b*(z^(a-b)+1), if a>=b; *
+*          =z^a*(z^(b-a)+1)  if a<b  */
+#ifdef LDEBUG
+  nfTest(a, R);
+  nfTest(b, R);
+#endif
+  if ((long)R->m_nfCharQ == (long)a) return b;
+  if ((long)R->m_nfCharQ == (long)b) return a;
+  long zb,zab,r;
+  if ((long)a >= (long)b)
+  {
+    zb = (long)b;
+    zab = (long)a-(long)b;
+  }
+  else
+  {
+    zb = (long)a;
+    zab = (long)b-(long)a;
+  }
+#ifdef LDEBUG
+  nfTest((number)zab, R);
+#endif
+  if (R->m_nfPlus1Table[zab]==R->m_nfCharQ) r=(long)R->m_nfCharQ; /*if z^(a-b)+1 =0*/
+  else
+  {
+    r= zb+(long)R->m_nfPlus1Table[zab];
+    if(r>=(long)R->m_nfCharQ1) r-=(long)R->m_nfCharQ1;
+  }
+#ifdef LDEBUG
+  nfTest((number)r, R);
+#endif
+  return (number)r;
+}
+
+/*2
+* a - b
+*/
+number nfSub (number a, number b, const coeffs r)
+{
+  number mb = nfNeg(b, r);
+  return nfAdd(a,mb,r);
+}
+
+/*2
+* a == 0 ?
+*/
+BOOLEAN nfIsZero (number  a, const coeffs r)
+{
+#ifdef LDEBUG
+  nfTest(a, r);
+#endif
+  return (long)r->m_nfCharQ == (long)a;
+}
+
+/*2
+* a == 1 ?
+*/
+BOOLEAN nfIsOne (number a, const coeffs r)
+{
+#ifdef LDEBUG
+  nfTest(a, r);
+#endif
+  return 0L == (long)a;
+}
+
+/*2
+* a == -1 ?
+*/
+BOOLEAN nfIsMOne (number a, const coeffs r)
+{
+#ifdef LDEBUG
+  nfTest(a, r);
+#endif
+  if (0L == (long)a) return FALSE; /* special handling of char 2*/
+  return (long)r->m_nfM1 == (long)a;
+}
+
+/*2
+* a / b
+*/
+number nfDiv (number a,number b, const coeffs r)
+{
+#ifdef LDEBUG
+  nfTest(b, r);
+#endif
+  if ((long)b==(long)r->m_nfCharQ)
+  {
+    WerrorS(nDivBy0);
+    return (number)((long)r->m_nfCharQ);
+  }
+#ifdef LDEBUG
+  nfTest(a, r);
+#endif
+  if ((long)a==(long)r->m_nfCharQ)
+    return (number)((long)r->m_nfCharQ);
+  /*else*/
+  long s = (long)a - (long)b;
+  if (s < 0L)
+    s += (long)r->m_nfCharQ1;
+#ifdef LDEBUG
+  nfTest((number)s, r);
+#endif
+  return (number)s;
+}
+
+/*2
+* 1 / c
+*/
+number  nfInvers (number c, const coeffs r)
+{
+#ifdef LDEBUG
+  nfTest(c, r);
+#endif
+  if ((long)c==(long)r->m_nfCharQ)
+  {
+    WerrorS(nDivBy0);
+    return (number)((long)r->m_nfCharQ);
+  }
+#ifdef LDEBUG
+  nfTest(((number)((long)r->m_nfCharQ1-(long)c)), r);
+#endif
+  return (number)((long)r->m_nfCharQ1-(long)c);
+}
+
+/*2
+* -c
+*/
+number nfNeg (number c, const coeffs r)
+{
+/*4 -z^c=z^c*(-1)=z^c*nfM1*/
+#ifdef LDEBUG
+  nfTest(c, r);
+#endif
+  if ((long)r->m_nfCharQ == (long)c) return c;
+  long i=(long)c+(long)r->m_nfM1;
+  if (i>=(long)r->m_nfCharQ1) i-=(long)r->m_nfCharQ1;
+#ifdef LDEBUG
+  nfTest((number)i, r);
+#endif
+  return (number)i;
+}
+
+/*2
+* a > b ?
+*/
+BOOLEAN nfGreater (number a,number b, const coeffs r)
+{
+#ifdef LDEBUG
+  nfTest(a, r);
+  nfTest(b, r);
+#endif
+  return (long)a != (long)b;
+}
+
+/*2
+* a == b ?
+*/
+BOOLEAN nfEqual (number a,number b, const coeffs r)
+{
+#ifdef LDEBUG
+  nfTest(a, r);
+  nfTest(b, r);
+#endif
+  return (long)a == (long)b;
+}
+
+/*2
+* write via StringAppend
+*/
+static void nfWriteLong (number &a, const coeffs r)
+{
+#ifdef LDEBUG
+  nfTest(a, r);
+#endif
+  if ((long)a==(long)r->m_nfCharQ)  StringAppendS("0");
+  else if ((long)a==0L)   StringAppendS("1");
+  else if (nfIsMOne(a, r))   StringAppendS("-1");
+  else
+  {
+    StringAppendS(n_ParameterNames(r)[0]);
+    if ((long)a!=1L)
+    {
+      StringAppend("^%d",(int)((long)a)); // long output!
+    }
+  }
+}
+
+
+/*2
+* write (shortert output) via StringAppend
+*/
+static void nfWriteShort (number &a, const coeffs r)
+{
+#ifdef LDEBUG
+  nfTest(a, r);
+#endif
+  if ((long)a==(long)r->m_nfCharQ)  StringAppendS("0");
+  else if ((long)a==0L)   StringAppendS("1");
+  else if (nfIsMOne(a, r))   StringAppendS("-1");
+  else
+  {
+    StringAppendS(n_ParameterNames(r)[0]);
+    if ((long)a!=1L)
+    {
+      StringAppend("%d",(int)((long)a));
+    }
+  }
+}
+
+/*2
+*
+*/
+char * nfName(number a, const coeffs r)
+{
+#ifdef LDEBUG
+  nfTest(a, r);
+#endif
+  char *s;
+  const char * const nf_Parameter=n_ParameterNames(r)[0];
+  if (((long)a==(long)r->m_nfCharQ) || ((long)a==0L)) return NULL;
+  else if ((long)a==1L)
+  {
+    return omStrDup(nf_Parameter);
+  }
+  else
+  {
+    s=(char *)omAlloc(4+strlen(nf_Parameter));
+    sprintf(s,"%s%d",nf_Parameter,(int)((long)a));
+  }
+  return s;
+}
+/*2
+* c ^ i with i>=0
+*/
+void nfPower (number a, int i, number * result, const coeffs r)
+{
+#ifdef LDEBUG
+  nfTest(a, r);
+#endif
+  if (i==0)
+  {
+    *result = (number)0L;
+  }
+  else if (i==1)
+  {
+    *result = a;
+  }
+  else
+  {
+    long rl;
+    if ((long)a == (long)r->m_nfCharQ) rl=(long)r->m_nfCharQ;
+    else rl=((long)a*(long)i) % (long)r->m_nfCharQ1;
+    *result = (number)rl;
+  }
+#ifdef LDEBUG
+  nfTest(*result, r);
+#endif
+}
+
+/*4
+* read an integer (with reduction mod p)
+*/
+static const char* nfEati(const char *s, int *i, const coeffs r)
+{
+  if (*s >= '0' && *s <= '9')
+  {
+    *i = 0;
+    do
+    {
+      *i *= 10;
+      *i += *s++ - '0';
+      if (*i > (MAX_INT_VAL / 10)) *i = *i % r->m_nfCharP;
+    }
+    while (*s >= '0' && *s <= '9');
+    if (*i >= r->m_nfCharP) *i = *i % r->m_nfCharP;
+  }
+  else *i = 1;
+  return s;
+}
+
+/*2
+* read a number
+*/
+const char * nfRead (const char *s, number *a, const coeffs r)
+{
+  int i;
+  number z;
+  number n;
+
+  s = nfEati(s, &i, r);
+  z=nfInit(i, r);
+  *a=z;
+  if (*s == '/')
+  {
+    s++;
+    s = nfEati(s, &i, r);
+    n=nfInit(i, r);
+    *a = nfDiv(z,n,r);
+  }
+  const char * const nf_Parameter = n_ParameterNames(r)[0];
+  const int N = strlen(nf_Parameter);
+  if (strncmp(s,nf_Parameter, N)==0)
+  {
+    s += N;
+    if ((*s >= '0') && (*s <= '9'))
+    {
+      s=eati(s,&i);
+      while (i>=r->m_nfCharQ1) i-=r->m_nfCharQ1;
+    }
+    else
+      i=1;
+    z=(number)(long)i;
+    *a=nfMult(*a,z,r);
+  }
+#ifdef LDEBUG
+  nfTest(*a, r);
+#endif
+  return s;
+}
+
+int gf_tab_numdigits62 ( int q );
+int convertback62 ( char * p, int n );
+
+int nfMinPoly[16];
+
+void nfShowMipo(const coeffs r)
+{
+  int i=nfMinPoly[0];
+  int j=0;
+  loop
+  {
+    j++;
+    if (nfMinPoly[j]!=0)
+      StringAppend("%d*%s^%d",nfMinPoly[j],n_ParameterNames(r)[0],i);
+    i--;
+    if(i<0) break;
+    if (nfMinPoly[j]!=0)
+      StringAppendS("+");
+  }
+}
+
+static void nfReadMipo(char *s)
+{
+  const char *l=strchr(s,';')+1;
+  char *n;
+  int i=strtol(l,&n,10);
+  l=n;
+  int j=1;
+  nfMinPoly[0]=i;
+  while(i>=0)
+  {
+    nfMinPoly[j]=strtol(l,&n,10);
+    if (l==n) break;
+    l=n;
+    j++;
+    i--;
+  }
+  if (i>=0)
+  {
+    WerrorS("error in reading minpoly from gftables");
+  }
+}
+
+/*2
+* init global variables from files 'gftables/%d'
+*/
+void nfReadTable(const int c, const coeffs r)
+{
+  //Print("GF(%d)\n",c);
+  if ((c==r->m_nfCharQ)||(c==-r->m_nfCharQ))
+    /*this field is already set*/  return;
+  int i=0;
+
+  while ((fftable[i]!=c) && (fftable[i]!=0))
+    i++;
+
+  if (fftable[i]==0)
+  {
+#ifndef SING_NDEBUG
+    Warn("illegal GF-table size: %d", c);
+#endif
+    return;
+  }
+
+  if (r->m_nfCharQ > 1)
+  {
+    omFreeSize( (ADDRESS)r->m_nfPlus1Table,r->m_nfCharQ*sizeof(unsigned short) );
+    r->m_nfPlus1Table=NULL;
+  }
+  if ((c>1) || (c<0))
+  {
+    if (c>1) r->m_nfCharQ = c;
+    else     r->m_nfCharQ = -c;
+    char buf[100];
+    sprintf(buf,"gftables/%d",r->m_nfCharQ);
+    FILE * fp = feFopen(buf,"r",NULL,TRUE);
+    if (fp==NULL)
+    {
+      return;
+    }
+    if(!fgets( buf, sizeof(buf), fp)) return;
+    if(strcmp(buf,"@@ factory GF(q) table @@\n")!=0)
+    {
+      goto err;
+    }
+    if(!fgets( buf, sizeof(buf), fp))
+    {
+      goto err;
+    }
+    int q;
+    int res = -1;
+    do
+    {
+      res = sscanf(buf,"%d %d",&r->m_nfCharP,&q);
+    }
+    while((res < 0) and (errno == EINTR));
+
+    nfReadMipo(buf);
+    r->m_nfCharQ1=r->m_nfCharQ-1;
+    //Print("nfCharQ=%d,nfCharQ1=%d,mipo=>>%s<<\n",nfCharQ,nfCharQ1,buf);
+    r->m_nfPlus1Table= (unsigned short *)omAlloc( (r->m_nfCharQ)*sizeof(unsigned short) );
+    int digs = gf_tab_numdigits62( r->m_nfCharQ );
+    char * bufptr;
+    int i = 1;
+    int k;
+    while ( i < r->m_nfCharQ )
+    {
+      (void)fgets( buf, sizeof(buf), fp);
+      //( strlen( buffer ) == (size_t)digs * 30, "illegal table" );
+      bufptr = buf;
+      k = 0;
+      while ( (i < r->m_nfCharQ) && (k < 30) )
+      {
+        r->m_nfPlus1Table[i] = convertback62( bufptr, digs );
+        if(r->m_nfPlus1Table[i]>r->m_nfCharQ)
+        {
+          Print("wrong entry %d: %d(%c%c%c)\n",i,r->m_nfPlus1Table[i],bufptr[0],bufptr[1],bufptr[2]);
+        }
+        bufptr += digs;
+        if (r->m_nfPlus1Table[i]==r->m_nfCharQ)
+        {
+          if(i==r->m_nfCharQ1)
+          {
+            r->m_nfM1=0;
+          }
+          else
+          {
+            r->m_nfM1=i;
+          }
+        }
+        i++; k++;
+      }
+    }
+    r->m_nfPlus1Table[0]=r->m_nfPlus1Table[r->m_nfCharQ1];
+  }
+  else
+    r->m_nfCharQ=0;
+#ifdef LDEBUG
+  nfTest((number)0, r);
+#endif
+  return;
+err:
+  Werror("illegal GF-table %d",r->m_nfCharQ);
+}
+
+/*2
+* map Z/p -> GF(p,n)
+*/
+number nfMapP(number c, const coeffs, const coeffs dst)
+{
+  return nfInit((int)((long)c), dst);
+}
+
+/*2
+* map GF(p,n1) -> GF(p,n2), n1 < n2, n1 | n2
+*/
+int nfMapGG_factor;
+number nfMapGG(number c, const coeffs src, const coeffs)
+{
+  int i=(long)c;
+  i*= nfMapGG_factor;
+  while (i >src->m_nfCharQ1) i-=src->m_nfCharQ1;
+  return (number)((long)i);
+}
+/*2
+* map GF(p,n1) -> GF(p,n2), n1 > n2, n2 | n1
+*/
+number nfMapGGrev(number c, const coeffs src, const coeffs)
+{
+  int ex=(int)((long)c);
+  if ((ex % nfMapGG_factor)==0)
+    return (number)(((long)ex) / ((long)nfMapGG_factor));
+  else
+    return (number)(long)src->m_nfCharQ; /* 0 */
+}
+
+/*2
+* set map function nMap ... -> GF(p,n)
+*/
+nMapFunc nfSetMap(const coeffs src, const coeffs dst)
+{
+  if (nCoeff_is_GF(src,src->m_nfCharQ))
+  {
+    return ndCopyMap;   /* GF(p,n) -> GF(p,n) */
+  }
+  if (nCoeff_is_GF(src))
+  {
+    const coeffs r = dst;
+    int q=src->ch;
+    if ((src->m_nfCharQ % q)==0) /* GF(p,n1) -> GF(p,n2), n2 > n1 */
+    {
+      // check if n2 is a multiple of n1
+      int n1=1;
+      int qq=r->m_nfCharP;
+      while(qq!=q) { qq *= r->m_nfCharP; n1++; }
+      int n2=1;
+      qq=r->m_nfCharP;
+      while(qq!=src->m_nfCharQ) { qq *= r->m_nfCharP; n2++; }
+      //Print("map %d^%d -> %d^%d\n",r->m_nfCharP,n1,r->m_nfCharP,n2);
+      if ((n2 % n1)==0)
+      {
+        int save_ch=r->m_nfCharQ;
+        nfReadTable(src->m_nfCharQ, r);
+        int nn=r->m_nfPlus1Table[0];
+        nfReadTable(save_ch, r);
+        nfMapGG_factor= r->m_nfPlus1Table[0] / nn;
+        //Print("nfMapGG_factor=%d (%d / %d)\n",nfMapGG_factor, r->m_nfPlus1Table[0], nn);
+        return nfMapGG;
+      }
+      else if ((n1 % n2)==0)
+      {
+        nfMapGG_factor= (n1/n2);
+        return nfMapGGrev;
+      }
+      else
+        return NULL;
+    }
+  }
+  if ((src->rep==n_rep_int) && nCoeff_is_Zp(src,dst->m_nfCharP))
+  {
+    return nfMapP;    /* Z/p -> GF(p,n) */
+  }
+
+  if (src->rep==n_rep_gap_rat) /*Q, Z */
+  {
+    return nlModP; // FIXME? TODO? // extern number nlModP(number q, const coeffs Q, const coeffs Zp); // Map q \in QQ \to Zp // FIXME!
+  }
+
+  return NULL;     /* default */
+}
+
+static BOOLEAN nfCoeffIsEqual(const coeffs, n_coeffType, void*);
+
+static void nfKillChar(coeffs r)
+{
+  char** p = (char**)n_ParameterNames(r);
+
+  const int P = n_NumberOfParameters(r);
+
+  for( int i = 1; i <= P; i++ )
+    if (p[i-1] != NULL)
+      omFree( (ADDRESS)p[i-1] );
+
+  omFreeSize((ADDRESS)p, P * sizeof(char*));
+}
+
+static char* nfCoeffString(const coeffs r)
+{
+  const char *p=n_ParameterNames(r)[0];
+  char *s=(char*)omAlloc(11+1+strlen(p));
+  sprintf(s,"%d,%s",r->m_nfCharQ,p);
+  return s;
+}
+
+static number nfRandom(siRandProc p,number ,number, const coeffs cf)
+{
+  return (number)(long)(p() %(cf->m_nfCharQ+1));
+}
+
+BOOLEAN nfInitChar(coeffs r,  void * parameter)
+{
+  r->is_field=TRUE;
+  r->is_domain=TRUE;
+  r->rep=n_rep_gf;
+  //r->cfInitChar=npInitChar;
+  r->cfKillChar=nfKillChar;
+  r->nCoeffIsEqual=nfCoeffIsEqual;
+  r->cfCoeffString=nfCoeffString;
+
+  r->cfMult  = nfMult;
+  r->cfSub   = nfSub;
+  r->cfAdd   = nfAdd;
+  r->cfDiv   = nfDiv;
+  //r->cfIntMod= ndIntMod;
+  r->cfExactDiv= nfDiv;
+  r->cfInit = nfInit;
+  //r->cfSize  = ndSize;
+  r->cfInt  = nfInt;
+  #ifdef HAVE_RINGS
+  //r->cfDivComp = NULL; // only for ring stuff
+  //r->cfIsUnit = NULL; // only for ring stuff
+  //r->cfGetUnit = NULL; // only for ring stuff
+  //r->cfExtGcd = NULL; // only for ring stuff
+  // r->cfDivBy = NULL; // only for ring stuff
+  #endif
+  r->cfInpNeg   = nfNeg;
+  r->cfInvers= nfInvers;
+  //r->cfCopy  = ndCopy;
+  //r->cfRePart = ndCopy;
+  //r->cfImPart = ndReturn0;
+
+  r->cfWriteLong = nfWriteLong;
+  r->cfRead = nfRead;
+  //r->cfNormalize=ndNormalize;
+  r->cfGreater = nfGreater;
+  r->cfEqual = nfEqual;
+  r->cfIsZero = nfIsZero;
+  r->cfIsOne = nfIsOne;
+  r->cfIsMOne = nfIsMOne;
+  r->cfGreaterZero = nfGreaterZero;
+  r->cfPower = nfPower;
+  //r->cfGcd  = ndGcd;
+  //r->cfLcm  = ndGcd;
+  //r->cfDelete= ndDelete;
+  r->cfSetMap = nfSetMap;
+  //r->cfName = ndName;
+  // debug stuff
+  r->cfCoeffWrite=nfCoeffWrite;
+
+  r->cfParDeg = nfParDeg;
+
+  r->cfRandom = nfRandom;
+
+#ifdef LDEBUG
+  r->cfDBTest=nfDBTest;
+#endif
+
+  // the variables:
+  r->nNULL = (number)0;
+  assume( getCoeffType(r) == n_GF );
+
+  GFInfo* p = (GFInfo *)(parameter);
+  assume (p->GFChar > 0);
+  assume (p->GFDegree > 0);
+
+  const char * name = p->GFPar_name;
+
+  r->m_nfCharQ = 0;
+  r->m_nfCharP = p->GFChar;
+  r->m_nfCharQ1 = 0;
+
+  r->iNumberOfParameters = 1;
+  r->cfParameter = nfParameter;
+
+  char ** pParameterNames = (char **) omAlloc0(sizeof(char *));
+  pParameterNames[0] = omStrDup(name); //TODO use omAlloc for allocating memory and use strcpy?
+
+  assume( pParameterNames != NULL );
+  assume( pParameterNames[0] != NULL );
+
+  r->pParameterNames = (const char**)pParameterNames;
+  // NOTE: r->m_nfParameter was replaced by n_ParameterNames(r)[0]
+
+  // TODO: nfKillChar MUST destroy r->pParameterNames[0] (0-term. string) && r->pParameterNames (array of size 1)
+
+  r->m_nfPlus1Table= NULL;
+
+  if (strlen(name) > 1)
+    r->cfWriteShort = nfWriteLong;
+  else
+    r->cfWriteShort = nfWriteShort;
+
+  r->has_simple_Alloc=TRUE;
+  r->has_simple_Inverse=TRUE;
+
+  if(p->GFChar > (2<<15))
+  {
+#ifndef SING_NDEBUG
+    Warn("illegal characteristic");
+#endif
+    return TRUE;
+  }
+
+  const double check= log ((double) (p->GFChar));
+
+  if( (p->GFDegree * check) > sixteenlog2 )
+  {
+#ifndef SING_NDEBUG
+    Warn("Sorry: illegal size: %u ^ %u", p->GFChar, p->GFDegree );
+#endif
+    return TRUE;
+  }
+
+  int c = pow (p->GFChar, p->GFDegree);
+
+  nfReadTable(c, r);
+
+  if( r->m_nfPlus1Table == NULL )
+  {
+#ifndef SING_NDEBUG
+    Warn("Sorry: cannot init lookup table!");
+#endif
+    return TRUE;
+  }
+
+
+  assume (r -> m_nfCharQ > 0);
+
+  r->ch = r->m_nfCharP;
+  assume( r->m_nfPlus1Table != NULL );
+
+  return FALSE;
+
+}
+
+void    nfCoeffWrite  (const coeffs r, BOOLEAN details)
+{
+  // m_nfCharQ = p^k where p is the characteristic (r->CharP) and k is GFDegree
+  Print("//   # ground field : %d\n",r->m_nfCharQ);
+  Print("//   primitive element : %s\n", n_ParameterNames(r)[0]);
+  if ( details )
+  {
+    StringSetS("//   minpoly        : ");
+    nfShowMipo(r);
+    StringAppendS("\n");
+    char *s=StringEndS(); PrintS(s); omFree(s);
+  }
+  else PrintS("//   minpoly        : ...\n");
+}
+
+static BOOLEAN nfCoeffIsEqual (const coeffs r, n_coeffType n, void * parameter)
+{
+  if (n==n_GF) {
+    GFInfo* p = (GFInfo *)(parameter);
+    int c = pow (p->GFChar, p->GFDegree);
+    if ((c == r->m_nfCharQ) && (strcmp(n_ParameterNames(r)[0], p->GFPar_name) == 0))
+      return TRUE;
+  }
+  return FALSE;
+}
diff --git a/libpolys/coeffs/ffields.h b/libpolys/coeffs/ffields.h
new file mode 100644
index 0000000..2a02f01
--- /dev/null
+++ b/libpolys/coeffs/ffields.h
@@ -0,0 +1,21 @@
+#ifndef FFIELDS_H
+#define FFIELDS_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: finite fields with a none-prime number of elements (via tables)
+*/
+#include <misc/auxiliary.h>
+
+struct n_Procs_s; typedef struct  n_Procs_s  *coeffs;
+
+//// Initialize r (n_GF)
+BOOLEAN nfInitChar(coeffs r, void*);
+
+/// Show the mininimal polynom....
+/// NOTE: this is used by char *  sleftv::String(void *d, BOOLEAN typed, int dim) (from Singular/subexpr.cc)
+/// for printing minpoly
+void    nfShowMipo(const coeffs r);
+
+#endif
diff --git a/libpolys/coeffs/gnumpc.cc b/libpolys/coeffs/gnumpc.cc
new file mode 100644
index 0000000..90a6f3a
--- /dev/null
+++ b/libpolys/coeffs/gnumpc.cc
@@ -0,0 +1,738 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: computations with GMP complex floating-point numbers
+*
+* ngc == number gnu complex
+*/
+#include <misc/auxiliary.h>
+#include <omalloc/omalloc.h>
+
+#include <misc/mylimits.h>
+#include <reporter/reporter.h>
+
+#include "coeffs.h"
+#include "numbers.h"
+
+#include "mpr_complex.h"
+
+#include "gnumpc.h"
+#include "longrat.h"
+#include "gnumpfl.h"
+#include "modulop.h"
+#include "shortfl.h"
+
+/// Get a mapping function from src into the domain of this type: long_C!
+nMapFunc  ngcSetMap(const coeffs src, const coeffs dst);
+
+number ngcMapQ(number from, const coeffs r, const coeffs aRing);
+
+void ngcSetChar(const coeffs r);
+
+// Private interface should be hidden!!!
+
+/// Note: MAY NOT WORK AS EXPECTED!
+BOOLEAN  ngcGreaterZero(number za, const coeffs r);
+BOOLEAN  ngcGreater(number a, number b, const coeffs r);
+BOOLEAN  ngcEqual(number a, number b, const coeffs r);
+BOOLEAN  ngcIsOne(number a, const coeffs r);
+BOOLEAN  ngcIsMOne(number a, const coeffs r);
+BOOLEAN  ngcIsZero(number za, const coeffs r);
+number   ngcInit(long i, const coeffs r);
+int      ngcInt(number &n, const coeffs r);
+number   ngcNeg(number za, const coeffs r);
+number   ngcInvers(number a, const coeffs r);
+number   ngcParameter(int i, const coeffs r);
+number   ngcAdd(number la, number li, const coeffs r);
+number   ngcSub(number la, number li, const coeffs r);
+number   ngcMult(number a, number b, const coeffs r);
+number   ngcDiv(number a, number b, const coeffs r);
+void     ngcPower(number x, int exp, number *lu, const coeffs r);
+number   ngcCopy(number a, const coeffs r);
+number   ngc_Copy(number a, coeffs r);
+const char * ngcRead (const char *s, number *a, const coeffs r);
+void     ngcWrite(number &a, const coeffs r);
+number   ngcRePart(number a, const coeffs r);
+number   ngcImPart(number a, const coeffs r);
+
+void     ngcDelete(number *a, const coeffs r);
+void     ngcCoeffWrite(const coeffs r, BOOLEAN details);
+
+#ifdef LDEBUG
+BOOLEAN  ngcDBTest(number a, const char *f, const int l, const coeffs r);
+#endif
+
+
+// Why is this here? who needs it?
+// number ngcMapQ(number from, const coeffs r, const coeffs aRing);
+
+/// Our Type!
+static const n_coeffType ID = n_long_C;
+
+
+#ifdef LDEBUG
+// not yet implemented
+BOOLEAN ngcDBTest(number, const char *, const int, const coeffs r)
+{
+  assume( getCoeffType(r) == ID );
+
+  return TRUE;
+}
+#endif
+
+number   ngcParameter(int i, const coeffs r)
+{
+  assume( getCoeffType(r) == ID );
+  assume(i==1);
+
+  if( i == 1 )
+    return (number)(new gmp_complex( (long)0, (long)1 ));
+
+  return NULL; // new gmp_complex( )  // 0?
+}
+
+/*2
+* n := i
+*/
+number ngcInit (long i, const coeffs r)
+{
+  assume( getCoeffType(r) == ID );
+
+  gmp_complex* n= new gmp_complex( (long)i, (long)0 );
+
+  return (number)n;
+}
+
+/*2
+* convert number to int
+*/
+int ngcInt(number &i, const coeffs r)
+{
+  assume( getCoeffType(r) == ID );
+
+  return (int)((gmp_complex*)i)->real();
+}
+
+int ngcSize(number n, const coeffs R)
+{
+  int r = (int)((gmp_complex*)n)->real();
+  if (r < 0) r = -r;
+  int i = (int)((gmp_complex*)n)->imag();
+  if (i < 0) i = -i;
+  int oneNorm = r + i;
+  /* basically return the 1-norm of n;
+     only if this happens to be zero although n != 0,
+     return 1;
+     (this code ensures that zero has the size zero) */
+  if ((oneNorm == 0.0) & (ngcIsZero(n,R) == FALSE)) oneNorm = 1;
+  return oneNorm;
+}
+
+/*2
+* delete a
+*/
+void ngcDelete (number * a, const coeffs r)
+{
+  assume( getCoeffType(r) == ID );
+
+  if ( *a != NULL )
+  {
+    delete *(gmp_complex**)a;
+    *a=NULL;
+  }
+}
+
+/*2
+ * copy a to b
+*/
+number ngcCopy(number a, const coeffs r)
+{
+  assume( getCoeffType(r) == ID );
+
+  gmp_complex* b= new gmp_complex( *(gmp_complex*)a );
+  return (number)b;
+}
+
+
+/*2
+* za:= - za
+*/
+number ngcNeg (number a, const coeffs R)
+{
+  assume( getCoeffType(R) == ID );
+
+  gmp_complex* r=(gmp_complex*)a;
+  (*r).neg();
+  return (number)a;
+}
+
+/*
+* 1/a
+*/
+number ngcInvers(number a, const coeffs R)
+{
+  assume( getCoeffType(R) == ID );
+
+  gmp_complex* r = NULL;
+  if (((gmp_complex*)a)->isZero())
+  {
+    WerrorS(nDivBy0);
+  }
+  else
+  {
+    r = new gmp_complex( (gmp_complex)1 / (*(gmp_complex*)a) );
+  }
+  return (number)r;
+}
+
+/*2
+* u:= a + b
+*/
+number ngcAdd (number a, number b, const coeffs R)
+{
+  assume( getCoeffType(R) == ID );
+
+  gmp_complex* r= new gmp_complex( (*(gmp_complex*)a) + (*(gmp_complex*)b) );
+  return (number)r;
+}
+
+/*2
+* u:= a - b
+*/
+number ngcSub (number a, number b, const coeffs R)
+{
+  assume( getCoeffType(R) == ID );
+
+  gmp_complex* r= new gmp_complex( (*(gmp_complex*)a) - (*(gmp_complex*)b) );
+  return (number)r;
+}
+
+/*2
+* u := a * b
+*/
+number ngcMult (number a, number b, const coeffs R)
+{
+  assume( getCoeffType(R) == ID );
+
+  gmp_complex* r= new gmp_complex( (*(gmp_complex*)a) * (*(gmp_complex*)b) );
+  return (number)r;
+}
+
+/*2
+* u := a / b
+*/
+number ngcDiv (number a, number b, const coeffs r)
+{
+  assume( getCoeffType(r) == ID );
+
+  if (((gmp_complex*)b)->isZero())
+  {
+    // a/0 = error
+    WerrorS(nDivBy0);
+    return NULL;
+  }
+  gmp_complex* res = new gmp_complex( (*(gmp_complex*)a) / (*(gmp_complex*)b) );
+  return (number)res;
+}
+
+/*2
+* u:= x ^ exp
+*/
+void ngcPower ( number x, int exp, number * u, const coeffs r)
+{
+  assume( getCoeffType(r) == ID );
+
+  if ( exp == 0 )
+  {
+    gmp_complex* n = new gmp_complex(1);
+    *u=(number)n;
+    return;
+  }
+  else if ( exp == 1 )
+  {
+    n_New(u, r);
+    gmp_complex* n = new gmp_complex();
+    *n= *(gmp_complex*)x;
+    *u=(number)n;
+    return;
+  }
+  else if (exp == 2)
+  {
+    n_New(u, r);
+    gmp_complex* n = new gmp_complex();
+    *n= *(gmp_complex*)x;
+    *u=(number)n;
+    *(gmp_complex*)(*u) *= *(gmp_complex*)n;
+    return;
+  }
+  if ( (exp & 1) == 1 )
+  {
+    ngcPower(x,exp-1,u, r);
+    gmp_complex *n = new gmp_complex();
+    *n=*(gmp_complex*)x;
+    *(gmp_complex*)(*u) *= *(gmp_complex*)n;
+    delete n;
+  }
+  else
+  {
+    number w;
+    n_New(&w, r);
+    ngcPower(x,exp/2,&w, r);
+    ngcPower(w,2,u, r);
+    n_Delete(&w, r);
+  }
+}
+
+BOOLEAN ngcIsZero (number a, const coeffs r)
+{
+  assume( getCoeffType(r) == ID );
+
+  return ( ((gmp_complex*)a)->real().isZero() && ((gmp_complex*)a)->imag().isZero());
+}
+
+number ngcRePart(number a, const coeffs r)
+{
+  assume( getCoeffType(r) == ID );
+
+  gmp_complex* n = new gmp_complex(((gmp_complex*)a)->real());
+  return (number)n;
+}
+
+number ngcImPart(number a, const coeffs r)
+{
+  assume( getCoeffType(r) == ID );
+
+  gmp_complex* n = new gmp_complex(((gmp_complex*)a)->imag());
+  return (number)n;
+}
+
+/*2
+* za >= 0 ?
+*/
+BOOLEAN ngcGreaterZero (number a, const coeffs r)
+{
+  assume( getCoeffType(r) == ID );
+
+  if ( ! ((gmp_complex*)a)->imag().isZero() )
+    return ( abs( *(gmp_complex*)a).sign() >= 0 );
+  else
+    return ( ((gmp_complex*)a)->real().sign() >= 0 );
+}
+
+/*2
+* a > b ?
+*/
+BOOLEAN ngcGreater (number a, number b, const coeffs r)
+{
+  assume( getCoeffType(r) == ID );
+
+  gmp_complex *aa=(gmp_complex*)a;
+  gmp_complex *bb=(gmp_complex*)b;
+  return (*aa) > (*bb);
+}
+
+/*2
+* a = b ?
+*/
+BOOLEAN ngcEqual (number a, number b, const coeffs r)
+{
+  assume( getCoeffType(r) == ID );
+
+  gmp_complex *aa=(gmp_complex*)a;
+  gmp_complex *bb=(gmp_complex*)b;
+  return (*aa) == (*bb);
+}
+
+/*2
+* a == 1 ?
+*/
+BOOLEAN ngcIsOne (number a, const coeffs r)
+{
+  assume( getCoeffType(r) == ID );
+
+  return (((gmp_complex*)a)->real().isOne() && ((gmp_complex*)a)->imag().isZero());
+  //return (((gmp_complex*)a)->real().isOne());
+}
+
+/*2
+* a == -1 ?
+*/
+BOOLEAN ngcIsMOne (number a, const coeffs r)
+{
+  assume( getCoeffType(r) == ID );
+
+  return (((gmp_complex*)a)->real().isMOne() && ((gmp_complex*)a)->imag().isZero());
+  //return (((gmp_complex*)a)->real().isMOne());
+}
+
+/*2
+* extracts the number a from s, returns the rest
+*/
+const char * ngcRead (const char * s, number * a, const coeffs r)
+{
+  assume( getCoeffType(r) == ID );
+  const char * const complex_parameter = n_ParameterNames(r)[0];
+  assume( complex_parameter != NULL );
+  const int N = strlen(complex_parameter);
+
+  if ((*s >= '0') && (*s <= '9'))
+  {
+    gmp_float *re=NULL;
+    s=ngfRead(s,(number *)&re, r); // FIXME? TODO? // extern const char *   ngfRead (const char *s, number *a, const coeffs r);
+    gmp_complex *aa=new gmp_complex(*re);
+    *a=(number)aa;
+    delete re;
+  }
+  else if (strncmp(s, complex_parameter, N)==0)
+  {
+    s += N;
+    gmp_complex *aa=new gmp_complex((long)0,(long)1);
+    *a=(number)aa;
+  }
+  else
+  {
+    *a=(number) new gmp_complex((long)1);
+  }
+  return s;
+}
+
+
+
+/*2
+* write a floating point number
+*/
+void ngcWrite (number &a, const coeffs r)
+{
+  assume( getCoeffType(r) == ID );
+
+  if (a==NULL)
+    StringAppendS("0");
+  else
+  {
+    char *out;
+    out= complexToStr(*(gmp_complex*)a, r->float_len, r);
+    StringAppendS(out);
+    //    omFreeSize((void *)out, (strlen(out)+1)* sizeof(char) );
+    omFree( (void *)out );
+  }
+}
+
+BOOLEAN ngcCoeffIsEqual (const coeffs r, n_coeffType n, void * parameter)
+{
+  if (n==ID)
+  {
+    LongComplexInfo* p = (LongComplexInfo *)(parameter);
+
+    if ((p==NULL)
+      && (6==r->float_len)
+      && (6==r->float_len2)
+      && (strcmp("i",n_ParameterNames(r)[0]) == 0)
+      )
+        return TRUE;
+    if ((p!=NULL) &&
+        (p->float_len == r->float_len) &&
+        (p->float_len2 == r->float_len2)
+       )
+      if (strcmp(p->par_name, n_ParameterNames(r)[0]) == 0)
+        return (TRUE);
+  }
+  return (FALSE);
+}
+
+static void ngcKillChar(coeffs r)
+{
+  char** p = (char**)n_ParameterNames(r);
+
+  const int P = n_NumberOfParameters(r);
+
+  for( int i = 1; i <= P; i++ )
+    if (p[i-1] != NULL)
+      omFree( (ADDRESS)p[i-1] );
+
+  omFreeSize((ADDRESS)p, P * sizeof(char*));
+}
+
+static char* ngcCoeffString(const coeffs r)
+{
+  const char *p=n_ParameterNames(r)[0];
+  char *s=(char*)omAlloc(31+strlen(p));
+  sprintf(s,"complex,%d,%d,%s",r->float_len,r->float_len2,p);
+  return s;
+}
+
+BOOLEAN ngcInitChar(coeffs n, void* parameter)
+{
+  assume( getCoeffType(n) == ID );
+  n->is_field=TRUE;
+  n->is_domain=TRUE;
+  n->rep=n_rep_gmp_complex;
+
+  n->cfKillChar = ngcKillChar;
+  n->ch = 0;
+  n->cfCoeffString=ngcCoeffString;
+
+  n->cfDelete  = ngcDelete;
+  //n->cfNormalize=ndNormalize;
+  n->cfInit   = ngcInit;
+  n->cfInt    = ngcInt;
+  n->cfAdd     = ngcAdd;
+  n->cfSub     = ngcSub;
+  n->cfMult    = ngcMult;
+  n->cfDiv     = ngcDiv;
+  n->cfExactDiv= ngcDiv;
+  n->cfInpNeg     = ngcNeg;
+  n->cfInvers  = ngcInvers;
+  n->cfCopy   = ngcCopy;
+  n->cfGreater = ngcGreater;
+  n->cfEqual   = ngcEqual;
+  n->cfIsZero  = ngcIsZero;
+  n->cfIsOne   = ngcIsOne;
+  n->cfIsMOne  = ngcIsMOne;
+  n->cfGreaterZero = ngcGreaterZero;
+
+  n->cfWriteLong  = ngcWrite;
+  n->cfWriteShort = ngcWrite;
+
+  n->cfRead    = ngcRead;
+  n->cfPower   = ngcPower;
+  n->cfSetMap = ngcSetMap;
+  n->cfRePart  = ngcRePart;
+  n->cfImPart  = ngcImPart;
+  n->cfCoeffWrite = ngcCoeffWrite;
+    // cfSize  = ndSize;
+#ifdef LDEBUG
+  //n->cfDBTest  = ndDBTest; // not yet implemented: ngcDBTest
+#endif
+
+  n->nCoeffIsEqual = ngcCoeffIsEqual;
+
+  n->cfSetChar=ngcSetChar;
+
+// we need to initialize n->nNULL at least for minpoly printing
+  n->nNULL  = n->cfInit(0,n);
+
+/*
+  //r->cfInitChar=nlInitChar;
+  r->cfKillChar=NULL;
+
+  r->cfMult  = nlMult;
+  r->cfSub   = nlSub;
+  r->cfAdd   = nlAdd;
+  r->cfDiv   = nlDiv;
+  r->cfIntMod= nlIntMod;
+  r->cfExactDiv= nlExactDiv;
+  r->cfInit = nlInit;
+  r->cfSize  = nlSize;
+  r->cfInt  = nlInt;
+#ifdef HAVE_RINGS
+  r->cfDivComp = NULL; // only for ring stuff
+  r->cfIsUnit = NULL; // only for ring stuff
+  r->cfGetUnit = NULL; // only for ring stuff
+  r->cfExtGcd = NULL; // only for ring stuff
+#endif
+  r->cfInpNeg   = nlNeg;
+  r->cfInvers= nlInvers;
+  r->cfCopy  = nl_Copy;
+  r->cfRePart = nl_Copy;
+  r->cfImPart = ndReturn0;
+  r->cfWriteLong = nlWrite;
+  r->cfRead = nlRead;
+  r->cfNormalize=nlNormalize;
+  r->cfGreater = nlGreater;
+#ifdef HAVE_RINGS
+  r->cfDivBy = NULL; // only for ring stuff
+#endif
+  r->cfEqual = nlEqual;
+  r->cfIsZero = nlIsZero;
+  r->cfIsOne = nlIsOne;
+  r->cfIsMOne = nlIsMOne;
+  r->cfGreaterZero = nlGreaterZero;
+  r->cfPower = nlPower;
+  r->cfGetDenom = nlGetDenom;
+  r->cfGetNumerator = nlGetNumerator;
+  r->cfGcd  = nlGcd;
+  r->cfLcm  = nlLcm;
+  r->cfDelete= nlDelete;
+  r->cfSetMap = nlSetMap;
+  r->cfName = ndName;
+  r->cfInpMult=nlInpMult;
+  r->cfInit_bigint=nlCopyMap;
+#ifdef LDEBUG
+  // debug stuff
+  r->cfDBTest=nlDBTest;
+#endif
+
+  // the variables:
+  r->nNULL = INT_TO_SR(0);
+  r->type = n_Q;
+  r->ch = 0;
+  r->has_simple_Alloc=FALSE;
+  r->has_simple_Inverse=FALSE;
+*/
+
+  n->iNumberOfParameters = 1;
+  n->cfParameter = ngcParameter;
+
+  char ** pParameterNames = (char **) omAlloc0(sizeof(char *));
+
+  if( parameter != NULL)
+  {
+    LongComplexInfo* p = (LongComplexInfo*)parameter;
+    pParameterNames[0] = omStrDup(p->par_name);
+    // fix wrong parameters:
+    if (p->float_len<SHORT_REAL_LENGTH) p->float_len=SHORT_REAL_LENGTH;
+    n->float_len = p->float_len;
+    n->float_len2 = p->float_len2;
+
+  } else // default values, just for testing!
+  {
+    pParameterNames[0] = omStrDup("i");
+    n->float_len = SHORT_REAL_LENGTH;
+    n->float_len2 = SHORT_REAL_LENGTH;
+  }
+
+  assume( pParameterNames != NULL );
+  assume( pParameterNames[0] != NULL );
+
+  n->pParameterNames = (const char**)pParameterNames;
+
+  // NOTE: n->complex_parameter was replaced by n_ParameterNames(n)[0]
+  // TODO: nfKillChar MUST destroy n->pParameterNames[0] (0-term. string) && n->pParameterNames (array of size 1)
+
+  return FALSE;
+}
+
+void ngcSetChar(const coeffs r)
+{
+  setGMPFloatDigits(r->float_len, r->float_len2);
+}
+
+
+
+number ngcMapQ(number from, const coeffs aRing, const coeffs r)
+{
+  assume( getCoeffType(r) == ID );
+  assume( aRing->rep == n_rep_gap_rat);
+
+  if ( from != NULL )
+  {
+    gmp_complex *res=new gmp_complex(numberFieldToFloat(from,QTOF,aRing));
+    return (number)res;
+  }
+  else
+    return NULL;
+}
+
+number ngcMapZ(number from, const coeffs aRing, const coeffs r)
+{
+  assume( getCoeffType(r) == ID );
+  assume( aRing->rep == n_rep_gap_gmp);
+
+  if ( from != NULL )
+  {
+    if (SR_HDL(from) & SR_INT)
+    {
+      gmp_float f_i= gmp_float(SR_TO_INT(from));
+      gmp_complex *res=new gmp_complex(f_i);
+      return (number)res;
+    }
+    gmp_float f_i=(mpz_ptr)from;
+    gmp_complex *res=new gmp_complex(f_i);
+    return (number)res;
+  }
+  else
+    return NULL;
+}
+
+static number ngcMapLongR(number from, const coeffs aRing, const coeffs r)
+{
+  assume( getCoeffType(r) == ID );
+  assume( getCoeffType(aRing) == n_long_R );
+
+  if ( from != NULL )
+  {
+    gmp_complex *res=new gmp_complex(*((gmp_float *)from));
+    return (number)res;
+  }
+  else
+    return NULL;
+}
+
+static number ngcMapR(number from, const coeffs aRing, const coeffs r)
+{
+  assume( getCoeffType(r) == ID );
+  assume( getCoeffType(aRing) == n_R );
+
+  if ( from != NULL )
+  {
+    gmp_complex *res=new gmp_complex((double)nrFloat(from)); // FIXME? TODO? // extern float   nrFloat(number n);
+    return (number)res;
+  }
+  else
+    return NULL;
+}
+
+static number ngcMapP(number from, const coeffs aRing, const coeffs r)
+{
+  assume( getCoeffType(r) == ID );
+  assume( getCoeffType(aRing) ==  n_Zp );
+
+  if ( from != NULL )
+    return ngcInit(npInt(from, aRing), r); // FIXME? TODO? // extern int     npInt         (number &n, const coeffs r);
+  else
+    return NULL;
+}
+
+static number ngcCopyMap(number from, const coeffs aRing, const coeffs r)
+{
+  assume( getCoeffType(r) == ID );
+  assume( getCoeffType(aRing) ==  ID );
+
+  gmp_complex* b = NULL;
+
+  if ( from !=  NULL )
+  {
+    b = new gmp_complex( *(gmp_complex*)from );
+  }
+  return (number)b;
+}
+
+nMapFunc ngcSetMap(const coeffs src, const coeffs dst)
+{
+  assume( getCoeffType(dst) == ID );
+
+  if (src->rep==n_rep_gap_rat) /* Q, Z*/
+  {
+    return ngcMapQ;
+  }
+  if (src->rep==n_rep_gap_gmp) /* Z */
+  {
+    return ngcMapZ;
+  }
+  if ((src->rep==n_rep_gmp_float) && nCoeff_is_long_R(src))
+  {
+    return ngcMapLongR;
+  }
+  if ((src->rep==n_rep_gmp_complex) && nCoeff_is_long_C(src))
+  {
+    return ngcCopyMap;
+  }
+  if ((src->rep==n_rep_float) && nCoeff_is_R(src))
+  {
+    return ngcMapR;
+  }
+  if ((src->rep==n_rep_int) && nCoeff_is_Zp(src))
+  {
+    return ngcMapP;
+  }
+  return NULL;
+}
+
+void    ngcCoeffWrite  (const coeffs r, BOOLEAN /*details*/)
+{
+  Print("//   characteristic : 0 (complex:%d digits, additional %d digits)\n",
+        r->float_len, r->float_len2);  /* long C */
+  Print("//   1 parameter    : %s \n", n_ParameterNames(r)[0]); // this trailing space is for compatibility with the legacy Singular
+  Print("//   minpoly        : (%s^2+1)\n", n_ParameterNames(r)[0]);
+}
diff --git a/libpolys/coeffs/gnumpc.h b/libpolys/coeffs/gnumpc.h
new file mode 100644
index 0000000..5d3cde5
--- /dev/null
+++ b/libpolys/coeffs/gnumpc.h
@@ -0,0 +1,17 @@
+#ifndef GMPCOMPLEX_H
+#define GMPCOMPLEX_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: computations with GMP floating-point numbers
+*/
+#include <misc/auxiliary.h>
+
+struct n_Procs_s; typedef struct  n_Procs_s  *coeffs;
+
+/// Initialize r (n_long_C)
+BOOLEAN ngcInitChar(coeffs r, void*);
+
+#endif
+/* GMPCOMPLEX_H */
diff --git a/libpolys/coeffs/gnumpfl.cc b/libpolys/coeffs/gnumpfl.cc
new file mode 100644
index 0000000..d30530d
--- /dev/null
+++ b/libpolys/coeffs/gnumpfl.cc
@@ -0,0 +1,597 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: computations with GMP floating-point numbers
+*
+* ngf == number gnu floats
+*/
+
+#include <misc/auxiliary.h>
+#include <omalloc/omalloc.h>
+
+#include <reporter/reporter.h>
+
+#include "coeffs.h"
+#include "numbers.h"
+#include "mpr_complex.h"
+
+#include "longrat.h"
+#include "shortfl.h"
+#include "gnumpfl.h"
+#include "modulop.h"
+
+//ring ngfMapRing; // to be used also in gnumpc.cc
+
+/// Our Type!
+static const n_coeffType ID = n_long_R;
+
+/// Get a mapping function from src into the domain of this type:
+nMapFunc  ngfSetMap(const coeffs src, const coeffs dst);
+
+const char *   ngfRead (const char *s, number *a, const coeffs r);
+
+ // Private interface should be hidden!!!
+/// Note: MAY NOT WORK AS EXPECTED!
+BOOLEAN  ngfGreaterZero(number za, const coeffs r);
+BOOLEAN  ngfGreater(number a, number b, const coeffs r);
+BOOLEAN  ngfEqual(number a, number b, const coeffs r);
+BOOLEAN  ngfIsOne(number a, const coeffs r);
+BOOLEAN  ngfIsMOne(number a, const coeffs r);
+BOOLEAN  ngfIsZero(number za, const coeffs r);
+number   ngfInit(long i, const coeffs r);
+int      ngfInt(number &n, const coeffs r);
+number   ngfNeg(number za, const coeffs r);
+number   ngfInvers(number a, const coeffs r);
+number   ngfAdd(number la, number li, const coeffs r);
+number   ngfSub(number la, number li, const coeffs r);
+number   ngfMult(number a, number b, const coeffs r);
+number   ngfDiv(number a, number b, const coeffs r);
+void     ngfPower(number x, int exp, number *lu, const coeffs r);
+number   ngfCopy(number a, const coeffs r);
+number   ngf_Copy(number a, coeffs r);
+void     ngfWrite(number &a, const coeffs r);
+void     ngfCoeffWrite(const coeffs r, BOOLEAN details);
+
+void     ngfDelete(number *a, const coeffs r);
+
+number ngfMapQ(number from, const coeffs src, const coeffs r);
+
+union nf
+{
+  float _f;
+  number _n;
+  nf(float f) {_f = f;}
+  nf(number n) {_n = n;}
+  float F() const {return _f;}
+  number N() const {return _n;}
+};
+
+/*2
+* n := i
+*/
+number ngfInit (long i, const coeffs r)
+{
+  assume( getCoeffType(r) == ID );
+
+  gmp_float* n= new gmp_float( (double)i );
+  return (number)n;
+}
+
+/*2
+* convert number to int
+*/
+int ngfInt(number &i, const coeffs r)
+{
+  assume( getCoeffType(r) == ID );
+
+  double d=(double)*(gmp_float*)i;
+  if (d<0.0)
+    return (int)(d-0.5);
+  else
+    return (int)(d+0.5);
+}
+
+int ngfSize(number n, const coeffs r)
+{
+  int i = ngfInt(n, r);
+  /* basically return the largest integer in n;
+     only if this happens to be zero although n != 0,
+     return 1;
+     (this code ensures that zero has the size zero) */
+  if ((i == 0) && (ngfIsZero(n,r) == FALSE)) i = 1;
+  return i;
+}
+
+/*2
+* delete a
+*/
+void ngfDelete (number * a, const coeffs r)
+{
+  assume( getCoeffType(r) == ID );
+
+  if ( *a != NULL )
+  {
+    delete *(gmp_float**)a;
+    *a=NULL;
+  }
+}
+
+/*2
+* copy a to b
+*/
+number ngfCopy(number a, const coeffs r)
+{
+  assume( getCoeffType(r) == ID );
+
+  gmp_float* b= new gmp_float( *(gmp_float*)a );
+  return (number)b;
+}
+
+#if 0
+static number ngfCopyMap(number a, const coeffs r1, const coeffs r2)
+{
+  assume( getCoeffType(r1) == ID );
+  assume( getCoeffType(r2) == ID );
+
+  gmp_float* b= NULL;
+  if ( a !=  NULL )
+  {
+    b= new gmp_float( *(gmp_float*)a );
+  }
+  return (number)b;
+}
+#endif
+
+/*2
+* za:= - za
+*/
+number ngfNeg (number a, const coeffs r)
+{
+  assume( getCoeffType(r) == ID );
+
+  *(gmp_float*)a= -(*(gmp_float*)a);
+  return (number)a;
+}
+
+/*
+* 1/a
+*/
+number ngfInvers(number a, const coeffs r)
+{
+  assume( getCoeffType(r) == ID );
+
+  gmp_float* f= NULL;
+  if (((gmp_float*)a)->isZero() )
+  {
+    WerrorS(nDivBy0);
+  }
+  else
+  {
+    f= new gmp_float( gmp_float(1) / (*(gmp_float*)a) );
+  }
+  return (number)f;
+}
+
+/*2
+* u:= a + b
+*/
+number ngfAdd (number a, number b, const coeffs R)
+{
+  assume( getCoeffType(R) == ID );
+
+  gmp_float* r= new gmp_float( (*(gmp_float*)a) + (*(gmp_float*)b) );
+  return (number)r;
+}
+
+/*2
+* u:= a - b
+*/
+number ngfSub (number a, number b, const coeffs R)
+{
+  assume( getCoeffType(R) == ID );
+
+  gmp_float* r= new gmp_float( (*(gmp_float*)a) - (*(gmp_float*)b) );
+  return (number)r;
+}
+
+/*2
+* u := a * b
+*/
+number ngfMult (number a, number b, const coeffs R)
+{
+  assume( getCoeffType(R) == ID );
+
+  gmp_float* r= new gmp_float( (*(gmp_float*)a) * (*(gmp_float*)b) );
+  return (number)r;
+}
+
+/*2
+* u := a / b
+*/
+number ngfDiv (number a, number b, const coeffs r)
+{
+  assume( getCoeffType(r) == ID );
+
+  if ( ((gmp_float*)b)->isZero() )
+  {
+    // a/0 = error
+    WerrorS(nDivBy0);
+    return NULL;
+  }
+  gmp_float* f= new gmp_float( (*(gmp_float*)a) / (*(gmp_float*)b) );
+  return (number)f;
+}
+
+/*2
+* u:= x ^ exp
+*/
+number ngfPower (number x, int exp, const coeffs r)
+{
+  assume( getCoeffType(r) == ID );
+
+  if ( exp == 0 )
+  {
+    gmp_float* n = new gmp_float(1);
+    return (number)n;
+  }
+  else if ( ngfIsZero(x, r) ) // 0^e, e>0
+  {
+    return ngfInit(0, r);
+  }
+  else if ( exp == 1 )
+  {
+    return ngfCopy(x,r);
+  }
+  return (number) ( new gmp_float( (*(gmp_float*)x)^exp ) );
+}
+
+/* kept for compatibility reasons, to be deleted */
+void ngfPower ( number x, int exp, number * u, const coeffs r )
+{
+  *u = ngfPower(x, exp, r);
+}
+
+BOOLEAN ngfIsZero (number a, const coeffs r)
+{
+  assume( getCoeffType(r) == ID );
+
+  return ( ((gmp_float*)a)->isZero() );
+}
+
+/*2
+* za > 0 ?
+*/
+BOOLEAN ngfGreaterZero (number a, const coeffs r)
+{
+  assume( getCoeffType(r) == ID );
+
+  return (((gmp_float*)a)->sign() > 0);
+}
+
+/*2
+* a > b ?
+*/
+BOOLEAN ngfGreater (number a, number b, const coeffs r)
+{
+  assume( getCoeffType(r) == ID );
+
+  return ( (*(gmp_float*)a) > (*(gmp_float*)b) );
+}
+
+/*2
+* a = b ?
+*/
+BOOLEAN ngfEqual (number a, number b, const coeffs r)
+{
+  assume( getCoeffType(r) == ID );
+
+  return ( (*(gmp_float*)a) == (*(gmp_float*)b) );
+}
+
+/*2
+* a == 1 ?
+*/
+BOOLEAN ngfIsOne (number a, const coeffs r)
+{
+  assume( getCoeffType(r) == ID );
+
+  return ((gmp_float*)a)->isOne();
+}
+
+/*2
+* a == -1 ?
+*/
+BOOLEAN ngfIsMOne (number a, const coeffs r)
+{
+  assume( getCoeffType(r) == ID );
+
+  return ((gmp_float*)a)->isMOne();
+}
+
+static char * ngfEatFloatNExp(char * s )
+{
+  char *start= s;
+
+  // eat floats (mantissa) like:
+  //   0.394394993, 102.203003008,  .300303032, pssibly starting with -
+  if (*s == '-') s++;
+  while ((*s >= '0' && *s <= '9')||(*s == '.')) s++;
+
+  // eat the exponent, starts with 'e' followed by '+', '-'
+  // and digits, like:
+  //   e-202, e+393, accept also E7
+  if ( (s != start) && ((*s == 'e')||(*s=='E')))
+  {
+    if (*s=='E') *s='e';
+    s++; // skip 'e'/'E'
+    if ((*s == '+') || (*s == '-')) s++;
+    while ((*s >= '0' && *s <= '9')) s++;
+  }
+
+  return s;
+}
+
+/*2
+* extracts the number a from s, returns the rest
+*
+* This is also called to print components of complex coefficients.
+* Handle with care!
+*/
+const char * ngfRead (const char * start, number * a, const coeffs r)
+{
+  assume( getCoeffType(r) == ID or getCoeffType(r) == n_long_C);
+
+  char *s= (char *)start;
+
+  //Print("%s\n",s);
+
+  s= ngfEatFloatNExp( s );
+
+  if (*s=='\0')  // 0
+  {
+    if ( *(gmp_float**)a == NULL ) (*(gmp_float**)a)= new gmp_float();
+    (*(gmp_float**)a)->setFromStr(start);
+  }
+  else if (s==start)  // 1
+  {
+    if ( *(gmp_float**)a != NULL )  delete (*(gmp_float**)a);
+    (*(gmp_float**)a)= new gmp_float(1);
+  }
+  else
+  {
+    gmp_float divisor(1.0);
+    char *start2=s;
+    if ( *s == '/' )
+    {
+      s++;
+      s= ngfEatFloatNExp( (char *)s );
+      if (s!= start2+1)
+      {
+        char tmp_c=*s;
+        *s='\0';
+        divisor.setFromStr(start2+1);
+        *s=tmp_c;
+      }
+      else
+      {
+        Werror("wrong long real format: %s",start2);
+      }
+    }
+    char c=*start2;
+    *start2='\0';
+    if ( *(gmp_float**)a == NULL ) (*(gmp_float**)a)= new gmp_float();
+    (*(gmp_float**)a)->setFromStr(start);
+    *start2=c;
+    if (divisor.isZero())
+    {
+      WerrorS(nDivBy0);
+    }
+    else
+      (**(gmp_float**)a) /= divisor;
+  }
+
+  return s;
+}
+
+/*2
+* write a floating point number
+*/
+void ngfWrite (number &a, const coeffs r)
+{
+  assume( getCoeffType(r) == ID );
+
+  char *out;
+  if ( a != NULL )
+  {
+    out= floatToStr(*(gmp_float*)a, r->float_len);
+    StringAppendS(out);
+    //omFreeSize((void *)out, (strlen(out)+1)* sizeof(char) );
+    omFree( (void *)out );
+  }
+  else
+  {
+    StringAppendS("0");
+  }
+}
+
+BOOLEAN ngfCoeffIsEqual (const coeffs r, n_coeffType n, void * parameter)
+{
+  if (n==ID)
+  {
+    LongComplexInfo* p = (LongComplexInfo *)(parameter);
+    if ((p!=NULL)
+    && (p->float_len == r->float_len)
+    && (p->float_len2 == r->float_len2))
+      return TRUE;
+  }
+  return FALSE;
+}
+
+void ngfSetChar(const coeffs r)
+{
+  setGMPFloatDigits(r->float_len, r->float_len2);
+}
+
+static char* ngfCoeffString(const coeffs r)
+{
+  char *s=(char*)omAlloc(27);
+  snprintf(s,27,"real,%d,%d",r->float_len,r->float_len2);
+  return s;
+}
+
+BOOLEAN ngfInitChar(coeffs n, void *parameter)
+{
+  assume( getCoeffType(n) == ID );
+
+  n->is_field=TRUE;
+  n->is_domain=TRUE;
+  n->rep=n_rep_gmp_float;
+
+  //n->cfKillChar = ndKillChar; /* dummy */
+
+  n->cfSetChar = ngfSetChar;
+  n->ch = 0;
+  n->cfCoeffString=ngfCoeffString;
+
+  n->cfDelete  = ngfDelete;
+  //n->cfNormalize=ndNormalize;
+  n->cfInit   = ngfInit;
+  n->cfInt    = ngfInt;
+  n->cfAdd     = ngfAdd;
+  n->cfSub     = ngfSub;
+  n->cfMult    = ngfMult;
+  n->cfDiv     = ngfDiv;
+  n->cfExactDiv= ngfDiv;
+  n->cfInpNeg     = ngfNeg;
+  n->cfInvers  = ngfInvers;
+  n->cfCopy   = ngfCopy;
+  n->cfGreater = ngfGreater;
+  n->cfEqual   = ngfEqual;
+  n->cfIsZero  = ngfIsZero;
+  n->cfIsOne   = ngfIsOne;
+  n->cfIsMOne  = ngfIsMOne;
+  n->cfGreaterZero = ngfGreaterZero;
+  n->cfWriteLong  = ngfWrite;
+  n->cfRead    = ngfRead;
+  n->cfPower   = ngfPower;
+  n->cfSetMap = ngfSetMap;
+  n->cfCoeffWrite = ngfCoeffWrite;
+#ifdef LDEBUG
+  //n->cfDBTest  = ndDBTest; // not yet implemented: ngfDBTest
+#endif
+
+  n->nCoeffIsEqual = ngfCoeffIsEqual;
+
+  if( parameter != NULL)
+  {
+    LongComplexInfo* p = (LongComplexInfo*)parameter;
+
+    n->float_len = p->float_len;
+    n->float_len2 = p->float_len2;
+  } else // default values, just for testing!
+  {
+    n->float_len = SHORT_REAL_LENGTH;
+    n->float_len2 = SHORT_REAL_LENGTH;
+  }
+
+  assume( n->float_len2 >= SHORT_REAL_LENGTH );
+
+  assume( n_NumberOfParameters(n) == 0 );
+  assume( n_ParameterNames(n) == NULL );
+
+  return FALSE;
+}
+
+number ngfMapQ(number from, const coeffs src, const coeffs dst)
+{
+  assume( getCoeffType(dst) == ID );
+  assume( src->rep == n_rep_gap_rat );
+
+  gmp_float *res=new gmp_float(numberFieldToFloat(from,QTOF,dst));
+  return (number)res;
+}
+number ngfMapZ(number from, const coeffs aRing, const coeffs r)
+{
+  assume( getCoeffType(r) == ID );
+  assume( aRing->rep == n_rep_gap_gmp);
+
+  if ( from != NULL )
+  {
+    if (SR_HDL(from) & SR_INT)
+    {
+      gmp_float f_i= gmp_float(SR_TO_INT(from));
+      gmp_float *res=new gmp_float(f_i);
+      return (number)res;
+    }
+    gmp_float f_i=(mpz_ptr)from;
+    gmp_float *res=new gmp_float(f_i);
+    return (number)res;
+  }
+  else
+    return NULL;
+}
+
+
+static number ngfMapR(number from, const coeffs src, const coeffs dst)
+{
+  assume( getCoeffType(dst) == ID );
+  assume( getCoeffType(src) == n_R );
+
+  gmp_float *res=new gmp_float((double)nf(from).F());
+  return (number)res;
+}
+
+static number ngfMapP(number from, const coeffs src, const coeffs dst)
+{
+  assume( getCoeffType(dst) == ID );
+  assume( getCoeffType(src) ==  n_Zp );
+
+  return ngfInit(npInt(from,src), dst); // FIXME? TODO? // extern int     npInt         (number &n, const coeffs r);
+}
+
+static number ngfMapC(number from, const coeffs src, const coeffs dst)
+{
+  assume( getCoeffType(dst) == ID );
+  assume( getCoeffType(src) ==  n_long_C );
+
+  gmp_float *res=new gmp_float(((gmp_complex*)from)->real());
+  return (number)res;
+}
+
+nMapFunc ngfSetMap(const coeffs src, const coeffs dst)
+{
+  assume( getCoeffType(dst) == ID );
+
+  if (src->rep==n_rep_gap_rat) /*Q, Z*/
+  {
+    return ngfMapQ;
+  }
+  if (src->rep==n_rep_gap_gmp) /*Q, Z*/
+  {
+    return ngfMapZ;
+  }
+  if ((src->rep==n_rep_gmp_float) && nCoeff_is_long_R(src))
+  {
+    return ndCopyMap; //ngfCopyMap;
+  }
+  if ((src->rep==n_rep_float) && nCoeff_is_R(src))
+  {
+    return ngfMapR;
+  }
+  if ((src->rep==n_rep_gmp_complex) && nCoeff_is_long_C(src))
+  {
+    return ngfMapC;
+  }
+  if ((src->rep==n_rep_int) && nCoeff_is_Zp(src))
+  {
+    return ngfMapP;
+  }
+  return NULL;
+}
+
+void    ngfCoeffWrite  (const coeffs r, BOOLEAN /*details*/)
+{
+  Print("//   characteristic : 0 (real:%d digits, additional %d digits)\n",
+               r->float_len,r->float_len2);  /* long R */
+}
diff --git a/libpolys/coeffs/gnumpfl.h b/libpolys/coeffs/gnumpfl.h
new file mode 100644
index 0000000..f9fb1ac
--- /dev/null
+++ b/libpolys/coeffs/gnumpfl.h
@@ -0,0 +1,21 @@
+#ifndef GMPFLOAT_H
+#define GMPFLOAT_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: computations with GMP floating-point numbers
+*/
+
+#include <misc/auxiliary.h>
+
+struct n_Procs_s; typedef struct  n_Procs_s  *coeffs;
+struct snumber; typedef struct snumber *   number;
+
+/// Initialize r
+BOOLEAN ngfInitChar(coeffs r, void *);
+
+// will be reused by gnumpc.cc
+const char *   ngfRead (const char *s, number *a, const coeffs r);
+
+#endif
diff --git a/libpolys/coeffs/longrat.cc b/libpolys/coeffs/longrat.cc
new file mode 100644
index 0000000..9482ff4
--- /dev/null
+++ b/libpolys/coeffs/longrat.cc
@@ -0,0 +1,3277 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: computation with long rational numbers (Hubert Grassmann)
+*/
+
+#include <misc/auxiliary.h>
+#include <omalloc/omalloc.h>
+
+#include <factory/factory.h>
+
+#include <misc/sirandom.h>
+#include <reporter/reporter.h>
+
+#include "rmodulon.h" // ZnmInfo
+#include "longrat.h"
+#include "shortfl.h"
+#include "modulop.h"
+
+// allow inlining only from p_Numbers.h and if ! LDEBUG
+#if defined(DO_LINLINE) && defined(P_NUMBERS_H) && !defined(LDEBUG)
+#define LINLINE static FORCE_INLINE
+#else
+#define LINLINE
+#undef DO_LINLINE
+#endif // DO_LINLINE
+
+LINLINE BOOLEAN  nlEqual(number a, number b, const coeffs r);
+LINLINE number   nlInit(long i, const coeffs r);
+LINLINE BOOLEAN  nlIsOne(number a, const coeffs r);
+LINLINE BOOLEAN  nlIsZero(number za, const coeffs r);
+LINLINE number   nlCopy(number a, const coeffs r);
+LINLINE number   nl_Copy(number a, const coeffs r);
+LINLINE void     nlDelete(number *a, const coeffs r);
+LINLINE number   nlNeg(number za, const coeffs r);
+LINLINE number   nlAdd(number la, number li, const coeffs r);
+LINLINE number   nlSub(number la, number li, const coeffs r);
+LINLINE number   nlMult(number a, number b, const coeffs r);
+LINLINE void nlInpAdd(number &a, number b, const coeffs r);
+LINLINE void nlInpMult(number &a, number b, const coeffs r);
+
+number nlRInit (long i);
+
+
+// number nlInitMPZ(mpz_t m, const coeffs r);
+// void nlMPZ(mpz_t m, number &n, const coeffs r);
+
+void     nlNormalize(number &x, const coeffs r);
+
+number   nlGcd(number a, number b, const coeffs r);
+number nlExtGcd(number a, number b, number *s, number *t, const coeffs);
+number   nlNormalizeHelper(number a, number b, const coeffs r);   /*special routine !*/
+BOOLEAN  nlGreater(number a, number b, const coeffs r);
+BOOLEAN  nlIsMOne(number a, const coeffs r);
+int      nlInt(number &n, const coeffs r);
+number   nlBigInt(number &n);
+
+#ifdef HAVE_RINGS
+number nlMapGMP(number from, const coeffs src, const coeffs dst);
+#endif
+
+BOOLEAN  nlGreaterZero(number za, const coeffs r);
+number   nlInvers(number a, const coeffs r);
+number   nlDiv(number a, number b, const coeffs r);
+number   nlExactDiv(number a, number b, const coeffs r);
+number   nlIntDiv(number a, number b, const coeffs r);
+number   nlIntMod(number a, number b, const coeffs r);
+void     nlPower(number x, int exp, number *lu, const coeffs r);
+const char *   nlRead (const char *s, number *a, const coeffs r);
+void     nlWrite(number &a, const coeffs r);
+
+number   nlGetDenom(number &n, const coeffs r);
+number   nlGetNumerator(number &n, const coeffs r);
+void     nlCoeffWrite(const coeffs r, BOOLEAN details);
+number   nlChineseRemainder(number *x, number *q,int rl, const coeffs C);
+number   nlFarey(number nN, number nP, const coeffs CF);
+
+#ifdef LDEBUG
+BOOLEAN  nlDBTest(number a, const char *f, const int l);
+#endif
+
+extern number nlOne; // FIXME? TODO? //  move into coeffs?
+
+nMapFunc nlSetMap(const coeffs src, const coeffs dst);
+
+// in-place operations
+void nlInpIntDiv(number &a, number b, const coeffs r);
+
+#ifdef LDEBUG
+#define nlTest(a, r) nlDBTest(a,__FILE__,__LINE__, r)
+BOOLEAN nlDBTest(number a, char *f,int l, const coeffs r);
+#else
+#define nlTest(a, r) do {} while (0)
+#endif
+
+
+// 64 bit version:
+//#if SIZEOF_LONG == 8
+#if 0
+#define MAX_NUM_SIZE 60
+#define POW_2_28 (1L<<60)
+#define POW_2_28_32 (1L<<28)
+#define LONG long
+#else
+#define MAX_NUM_SIZE 28
+#define POW_2_28 (1L<<28)
+#define POW_2_28_32 (1L<<28)
+#define LONG int
+#endif
+
+static inline number nlShort3(number x) // assume x->s==3
+{
+  assume(x->s==3);
+  if (mpz_cmp_ui(x->z,(long)0)==0)
+  {
+    mpz_clear(x->z);
+    FREE_RNUMBER(x);
+    return INT_TO_SR(0);
+  }
+  if (mpz_size1(x->z)<=MP_SMALL)
+  {
+    LONG ui=mpz_get_si(x->z);
+    if ((((ui<<3)>>3)==ui)
+    && (mpz_cmp_si(x->z,(long)ui)==0))
+    {
+      mpz_clear(x->z);
+      FREE_RNUMBER(x);
+      return INT_TO_SR(ui);
+    }
+  }
+  return x;
+}
+
+#ifndef LONGRAT_CC
+#define LONGRAT_CC
+
+#include <string.h>
+#include <float.h>
+
+#include <coeffs/coeffs.h>
+#include <reporter/reporter.h>
+#include <omalloc/omalloc.h>
+
+#include <coeffs/numbers.h>
+#include <coeffs/mpr_complex.h>
+
+#ifndef BYTES_PER_MP_LIMB
+#define BYTES_PER_MP_LIMB sizeof(mp_limb_t)
+#endif
+
+//#define SR_HDL(A) ((long)(A))
+/*#define SR_INT    1L*/
+/*#define INT_TO_SR(INT)  ((number) (((long)INT << 2) + SR_INT))*/
+// #define SR_TO_INT(SR)   (((long)SR) >> 2)
+
+#define MP_SMALL 1
+//#define mpz_isNeg(A) (mpz_cmp_si(A,(long)0)<0)
+#define mpz_isNeg(A) ((A)->_mp_size<0)
+#define mpz_limb_size(A) ((A)->_mp_size)
+#define mpz_limb_d(A) ((A)->_mp_d)
+#define MPZ_DIV(A,B,C) mpz_tdiv_q((A),(B),(C))
+#define MPZ_EXACTDIV(A,B,C) mpz_divexact((A),(B),(C))
+
+void    _nlDelete_NoImm(number *a);
+
+/***************************************************************
+ *
+ * Routines which are never inlined by p_Numbers.h
+ *
+ *******************************************************************/
+#ifndef P_NUMBERS_H
+
+number nlShort3_noinline(number x) // assume x->s==3
+{
+  return nlShort3(x);
+}
+
+
+number nlOne=INT_TO_SR(1);
+
+#if (__GNU_MP_VERSION*10+__GNU_MP_VERSION_MINOR < 31)
+void mpz_mul_si (mpz_ptr r, mpz_srcptr s, long int si)
+{
+  if (si>=0)
+    mpz_mul_ui(r,s,si);
+  else
+  {
+    mpz_mul_ui(r,s,-si);
+    mpz_neg(r,r);
+  }
+}
+#endif
+
+static number nlMapP(number from, const coeffs src, const coeffs dst)
+{
+  assume( getCoeffType(src) == n_Zp );
+
+  number to = nlInit(npInt(from,src), dst); // FIXME? TODO? // extern int     npInt         (number &n, const coeffs r);
+
+  return to;
+}
+
+static number nlMapLongR(number from, const coeffs src, const coeffs dst);
+static number nlMapR(number from, const coeffs src, const coeffs dst);
+
+
+#ifdef HAVE_RINGS
+/*2
+* convert from a GMP integer
+*/
+number nlMapGMP(number from, const coeffs /*src*/, const coeffs /*dst*/)
+{
+  number z=ALLOC_RNUMBER();
+#if defined(LDEBUG)
+  z->debug=123456;
+#endif
+  mpz_init_set(z->z,(mpz_ptr) from);
+  //mpz_init_set_ui(&z->n,1);
+  z->s = 3;
+  z=nlShort3(z);
+  return z;
+}
+
+number nlMapZ(number from, const coeffs src, const coeffs dst)
+{
+  if (SR_HDL(from) & SR_INT)
+  {
+    return from;
+  }
+  return nlMapGMP(from,src,dst);
+}
+
+/*2
+* convert from an machine long
+*/
+number nlMapMachineInt(number from, const coeffs /*src*/, const coeffs /*dst*/)
+{
+  number z=ALLOC_RNUMBER();
+#if defined(LDEBUG)
+  z->debug=123456;
+#endif
+  mpz_init_set_ui(z->z,(unsigned long) from);
+  z->s = 3;
+  z=nlShort3(z);
+  return z;
+}
+#endif
+
+
+#ifdef LDEBUG
+BOOLEAN nlDBTest(number a, const char *f,const int l, const coeffs /*r*/)
+{
+  if (a==NULL)
+  {
+    Print("!!longrat: NULL in %s:%d\n",f,l);
+    return FALSE;
+  }
+  //if ((int)a==1) Print("!! 0x1 as number ? %s %d\n",f,l);
+  if ((((long)a)&3L)==3L)
+  {
+    Print(" !!longrat:ptr(3) in %s:%d\n",f,l);
+    return FALSE;
+  }
+  if ((((long)a)&3L)==1L)
+  {
+    if (((((LONG)(long)a)<<1)>>1)!=((LONG)(long)a))
+    {
+      Print(" !!longrat:arith:%lx in %s:%d\n",(long)a, f,l);
+      return FALSE;
+    }
+    return TRUE;
+  }
+  /* TODO: If next line is active, then computations in algebraic field
+           extensions over Q will throw a lot of assume violations although
+           everything is computed correctly and no seg fault appears.
+           Maybe the test is not appropriate in this case. */
+  omCheckIf(omCheckAddrSize(a,sizeof(*a)), return FALSE);
+  if (a->debug!=123456)
+  {
+    Print("!!longrat:debug:%d in %s:%d\n",a->debug,f,l);
+    a->debug=123456;
+    return FALSE;
+  }
+  if ((a->s<0)||(a->s>4))
+  {
+    Print("!!longrat:s=%d in %s:%d\n",a->s,f,l);
+    return FALSE;
+  }
+  /* TODO: If next line is active, then computations in algebraic field
+           extensions over Q will throw a lot of assume violations although
+           everything is computed correctly and no seg fault appears.
+           Maybe the test is not appropriate in this case. */
+  //omCheckAddrSize(a->z[0]._mp_d,a->z[0]._mp_alloc*BYTES_PER_MP_LIMB);
+  if (a->z[0]._mp_alloc==0)
+    Print("!!longrat:z->alloc=0 in %s:%d\n",f,l);
+
+  if (a->s<2)
+  {
+    if ((a->n[0]._mp_d[0]==0)&&(a->n[0]._mp_alloc<=1))
+    {
+      Print("!!longrat: n==0 in %s:%d\n",f,l);
+      return FALSE;
+    }
+    /* TODO: If next line is active, then computations in algebraic field
+             extensions over Q will throw a lot of assume violations although
+             everything is computed correctly and no seg fault appears.
+             Maybe the test is not appropriate in this case. */
+    //omCheckIf(omCheckAddrSize(a->n[0]._mp_d,a->n[0]._mp_alloc*BYTES_PER_MP_LIMB), return FALSE);
+    if (a->z[0]._mp_alloc==0)
+      Print("!!longrat:n->alloc=0 in %s:%d\n",f,l);
+    if ((mpz_size1(a->n) ==1) && (mpz_cmp_si(a->n,(long)1)==0))
+    {
+      Print("!!longrat:integer as rational in %s:%d\n",f,l);
+      mpz_clear(a->n); a->s=3;
+      return FALSE;
+    }
+    else if (mpz_isNeg(a->n))
+    {
+      Print("!!longrat:div. by negative in %s:%d\n",f,l);
+      mpz_neg(a->z,a->z);
+      mpz_neg(a->n,a->n);
+      return FALSE;
+    }
+    return TRUE;
+  }
+  //if (a->s==2)
+  //{
+  //  Print("!!longrat:s=2 in %s:%d\n",f,l);
+  //  return FALSE;
+  //}
+  if (mpz_size1(a->z)>MP_SMALL) return TRUE;
+  LONG ui=(int)mpz_get_si(a->z);
+  if ((((ui<<3)>>3)==ui)
+  && (mpz_cmp_si(a->z,(long)ui)==0))
+  {
+    Print("!!longrat:im int %d in %s:%d\n",ui,f,l);
+    f=NULL;
+    return FALSE;
+  }
+  return TRUE;
+}
+#endif
+
+static CanonicalForm nlConvSingNFactoryN( number n, const BOOLEAN setChar, const coeffs /*r*/ )
+{
+  if (setChar) setCharacteristic( 0 );
+
+  CanonicalForm term;
+  if ( SR_HDL(n) & SR_INT )
+  {
+    int nn=SR_TO_INT(n);
+    if ((long)nn==SR_TO_INT(n))
+       term = nn;
+    else
+    {
+        mpz_t dummy;
+        mpz_init_set_si(dummy, SR_TO_INT(n));
+        term = make_cf(dummy);
+    }
+  }
+  else
+  {
+    if ( n->s == 3 )
+    {
+      mpz_t dummy;
+      long lz=mpz_get_si(n->z);
+      if (mpz_cmp_si(n->z,lz)==0) term=lz;
+      else
+      {
+        mpz_init_set( dummy,n->z );
+        term = make_cf( dummy );
+      }
+    }
+    else
+    {
+      // assume s==0 or s==1
+      mpz_t num, den;
+      On(SW_RATIONAL);
+      mpz_init_set( num, n->z );
+      mpz_init_set( den, n->n );
+      term = make_cf( num, den, ( n->s != 1 ));
+    }
+  }
+  return term;
+}
+
+number nlRInit (long i);
+
+static number nlConvFactoryNSingN( const CanonicalForm f, const coeffs r)
+{
+  if (f.isImm())
+  {
+    const long lz=f.intval();
+    const int iz=(int)lz;
+    if ((long)iz==lz)
+      return nlInit(f.intval(),r);
+    else
+      return nlRInit(lz);
+//    return nlInit(f.intval(),r);
+  }
+  else
+  {
+    number z = ALLOC_RNUMBER(); //Q!? // (number)omAllocBin(rnumber_bin);
+#if defined(LDEBUG)
+    z->debug=123456;
+#endif
+    gmp_numerator( f, z->z );
+    if ( f.den().isOne() )
+      z->s = 3;
+    else
+    {
+      gmp_denominator( f, z->n );
+      z->s = 0;
+    }
+    nlNormalize(z,r);
+    return z;
+  }
+}
+
+static number nlMapR(number from, const coeffs src, const coeffs dst)
+{
+  assume( getCoeffType(src) == n_R );
+
+  double f=nrFloat(from); // FIXME? TODO? // extern float   nrFloat(number n);
+  if (f==0.0) return INT_TO_SR(0);
+  int f_sign=1;
+  if (f<0.0)
+  {
+    f_sign=-1;
+    f=-f;
+  }
+  int i=0;
+  mpz_t h1;
+  mpz_init_set_ui(h1,1);
+  while((FLT_RADIX*f) < DBL_MAX && i<DBL_MANT_DIG)
+  {
+    f*=FLT_RADIX;
+    mpz_mul_ui(h1,h1,FLT_RADIX);
+    i++;
+  }
+  number re=nlRInit(1);
+  mpz_set_d(re->z,f);
+  memcpy(&(re->n),&h1,sizeof(h1));
+  re->s=0; /* not normalized */
+  if(f_sign==-1) re=nlNeg(re,dst);
+  nlNormalize(re,dst);
+  return re;
+}
+
+static number nlMapLongR(number from, const coeffs src, const coeffs dst)
+{
+  assume( getCoeffType(src) == n_long_R );
+
+  gmp_float *ff=(gmp_float*)from;
+  mpf_t *f=ff->_mpfp();
+  number res;
+  mpz_ptr dest,ndest;
+  int size, i,negative;
+  int e,al,bl;
+  mp_ptr qp,dd,nn;
+
+  size = (*f)[0]._mp_size;
+  if (size == 0)
+    return INT_TO_SR(0);
+  if(size<0)
+  {
+    negative = 1;
+    size = -size;
+  }
+  else
+    negative = 0;
+
+  qp = (*f)[0]._mp_d;
+  while(qp[0]==0)
+  {
+    qp++;
+    size--;
+  }
+
+  e=(*f)[0]._mp_exp-size;
+  res = ALLOC_RNUMBER();
+#if defined(LDEBUG)
+  res->debug=123456;
+#endif
+  dest = res->z;
+
+  if (e<0)
+  {
+    al = dest->_mp_size = size;
+    if (al<2) al = 2;
+    dd = (mp_ptr)omAlloc(sizeof(mp_limb_t)*al);
+    for (i=0;i<size;i++) dd[i] = qp[i];
+    bl = 1-e;
+    nn = (mp_ptr)omAlloc(sizeof(mp_limb_t)*bl);
+    nn[bl-1] = 1;
+    for (i=bl-2;i>=0;i--) nn[i] = 0;
+    ndest = res->n;
+    ndest->_mp_d = nn;
+    ndest->_mp_alloc = ndest->_mp_size = bl;
+    res->s = 0;
+  }
+  else
+  {
+    al = dest->_mp_size = size+e;
+    if (al<2) al = 2;
+    dd = (mp_ptr)omAlloc(sizeof(mp_limb_t)*al);
+    for (i=0;i<size;i++) dd[i+e] = qp[i];
+    for (i=0;i<e;i++) dd[i] = 0;
+    res->s = 3;
+  }
+
+  dest->_mp_d = dd;
+  dest->_mp_alloc = al;
+  if (negative) dest->_mp_size = -dest->_mp_size;
+
+  if (res->s==0)
+    nlNormalize(res,dst);
+  else if (mpz_size1(res->z)<=MP_SMALL)
+  {
+    // res is new, res->ref is 1
+    res=nlShort3(res);
+  }
+  nlTest(res, dst);
+  return res;
+}
+
+//static number nlMapLongR(number from)
+//{
+//  gmp_float *ff=(gmp_float*)from;
+//  const mpf_t *f=ff->mpfp();
+//  int f_size=ABS((*f)[0]._mp_size);
+//  if (f_size==0)
+//    return nlInit(0);
+//  int f_sign=1;
+//  number work=ngcCopy(from);
+//  if (!ngcGreaterZero(work))
+//  {
+//    f_sign=-1;
+//    work=ngcNeg(work);
+//  }
+//  int i=0;
+//  mpz_t h1;
+//  mpz_init_set_ui(h1,1);
+//  while((FLT_RADIX*f) < DBL_MAX && i<DBL_MANT_DIG)
+//  {
+//    f*=FLT_RADIX;
+//    mpz_mul_ui(h1,h1,FLT_RADIX);
+//    i++;
+//  }
+//  number r=nlRInit(1);
+//  mpz_set_d(&(r->z),f);
+//  memcpy(&(r->n),&h1,sizeof(h1));
+//  r->s=0; /* not normalized */
+//  nlNormalize(r);
+//  return r;
+//
+//
+//  number r=nlRInit(1);
+//  int f_shift=f_size+(*f)[0]._mp_exp;
+//  if ( f_shift > 0)
+//  {
+//    r->s=0;
+//    mpz_init(&r->n);
+//    mpz_setbit(&r->n,f_shift*BYTES_PER_MP_LIMB*8);
+//    mpz_setbit(&r->z,f_size*BYTES_PER_MP_LIMB*8-1);
+//    // now r->z has enough space
+//    memcpy(mpz_limb_d(&r->z),((*f)[0]._mp_d),f_size*BYTES_PER_MP_LIMB);
+//    nlNormalize(r);
+//  }
+//  else
+//  {
+//    r->s=3;
+//    if (f_shift==0)
+//    {
+//      mpz_setbit(&r->z,f_size*BYTES_PER_MP_LIMB*8-1);
+//      // now r->z has enough space
+//      memcpy(mpz_limb_d(&r->z),((*f)[0]._mp_d),f_size*BYTES_PER_MP_LIMB);
+//    }
+//    else /* f_shift < 0 */
+//    {
+//      mpz_setbit(&r->z,(f_size-f_shift)*BYTES_PER_MP_LIMB*8-1);
+//      // now r->z has enough space
+//      memcpy(mpz_limb_d(&r->z)-f_shift,((*f)[0]._mp_d),
+//        f_size*BYTES_PER_MP_LIMB);
+//    }
+//  }
+//  if ((*f)[0]._mp_size<0);
+//    r=nlNeg(r);
+//  return r;
+//}
+
+int nlSize(number a, const coeffs)
+{
+  if (a==INT_TO_SR(0))
+     return 0; /* rational 0*/
+  if (SR_HDL(a) & SR_INT)
+     return 1; /* immidiate int */
+  int s=a->z[0]._mp_alloc;
+//  while ((s>0) &&(a->z._mp_d[s]==0L)) s--;
+//#if SIZEOF_LONG == 8
+//  if (a->z._mp_d[s] < (unsigned long)0x100000000L) s=s*2-1;
+//  else s *=2;
+//#endif
+//  s++;
+  if (a->s<2)
+  {
+    int d=a->n[0]._mp_alloc;
+//    while ((d>0) && (a->n._mp_d[d]==0L)) d--;
+//#if SIZEOF_LONG == 8
+//    if (a->n._mp_d[d] < (unsigned long)0x100000000L) d=d*2-1;
+//    else d *=2;
+//#endif
+    s+=d;
+  }
+  return s;
+}
+
+/*2
+* convert number to int
+*/
+int nlInt(number &i, const coeffs r)
+{
+  nlTest(i, r);
+  nlNormalize(i,r);
+  if (SR_HDL(i) & SR_INT)
+  {
+    int dummy = SR_TO_INT(i);
+    if((long)dummy == SR_TO_INT(i))
+        return SR_TO_INT(i);
+    else
+        return 0;
+  }
+  if (i->s==3)
+  {
+    if(mpz_size1(i->z)>MP_SMALL) return 0;
+    int ul=(int)mpz_get_si(i->z);
+    if (mpz_cmp_si(i->z,(long)ul)!=0) return 0;
+    return ul;
+  }
+  mpz_t tmp;
+  int ul;
+  mpz_init(tmp);
+  MPZ_DIV(tmp,i->z,i->n);
+  if(mpz_size1(tmp)>MP_SMALL) ul=0;
+  else
+  {
+    ul=(int)mpz_get_si(tmp);
+    if (mpz_cmp_si(tmp,(long)ul)!=0) ul=0;
+  }
+  mpz_clear(tmp);
+  return ul;
+}
+
+/*2
+* convert number to bigint
+*/
+number nlBigInt(number &i, const coeffs r)
+{
+  nlTest(i, r);
+  nlNormalize(i,r);
+  if (SR_HDL(i) & SR_INT) return (i);
+  if (i->s==3)
+  {
+    return nlCopy(i,r);
+  }
+  number tmp=nlRInit(1);
+  MPZ_DIV(tmp->z,i->z,i->n);
+  tmp=nlShort3(tmp);
+  return tmp;
+}
+
+/*
+* 1/a
+*/
+number nlInvers(number a, const coeffs r)
+{
+  nlTest(a, r);
+  number n;
+  if (SR_HDL(a) & SR_INT)
+  {
+    if ((a==INT_TO_SR(1L)) || (a==INT_TO_SR(-1L)))
+    {
+      return a;
+    }
+    if (nlIsZero(a,r))
+    {
+      WerrorS(nDivBy0);
+      return INT_TO_SR(0);
+    }
+    n=ALLOC_RNUMBER();
+#if defined(LDEBUG)
+    n->debug=123456;
+#endif
+    n->s=1;
+    if ((long)a>0L)
+    {
+      mpz_init_set_si(n->z,(long)1);
+      mpz_init_set_si(n->n,(long)SR_TO_INT(a));
+    }
+    else
+    {
+      mpz_init_set_si(n->z,(long)-1);
+      mpz_init_set_si(n->n,(long)-SR_TO_INT(a));
+    }
+    nlTest(n, r);
+    return n;
+  }
+  n=ALLOC_RNUMBER();
+#if defined(LDEBUG)
+  n->debug=123456;
+#endif
+  {
+    n->s=a->s;
+    mpz_init_set(n->n,a->z);
+    switch (a->s)
+    {
+      case 0:
+      case 1:
+              mpz_init_set(n->z,a->n);
+              if (mpz_isNeg(n->n)) /* && n->s<2*/
+              {
+                mpz_neg(n->z,n->z);
+                mpz_neg(n->n,n->n);
+              }
+              if (mpz_cmp_si(n->n,(long)1)==0)
+              {
+                mpz_clear(n->n);
+                n->s=3;
+                n=nlShort3(n);
+              }
+              break;
+      case 3:
+              n->s=1;
+              if (mpz_isNeg(n->n)) /* && n->s<2*/
+              {
+                mpz_neg(n->n,n->n);
+                mpz_init_set_si(n->z,(long)-1);
+              }
+              else
+              {
+                mpz_init_set_si(n->z,(long)1);
+              }
+              break;
+    }
+  }
+  nlTest(n, r);
+  return n;
+}
+
+
+/*2
+* u := a / b in Z, if b | a (else undefined)
+*/
+number   nlExactDiv(number a, number b, const coeffs r)
+{
+  if (b==INT_TO_SR(0))
+  {
+    WerrorS(nDivBy0);
+    return INT_TO_SR(0);
+  }
+  if (a==INT_TO_SR(0))
+    return INT_TO_SR(0);
+  number u;
+  if (SR_HDL(a) & SR_HDL(b) & SR_INT)
+  {
+    /* the small int -(1<<28) divided by -1 is the large int (1<<28)   */
+    if ((a==INT_TO_SR(-(POW_2_28)))&&(b==INT_TO_SR(-1L)))
+    {
+      return nlRInit(POW_2_28);
+    }
+    long aa=SR_TO_INT(a);
+    long bb=SR_TO_INT(b);
+    return INT_TO_SR(aa/bb);
+  }
+  number bb=NULL;
+  if (SR_HDL(b) & SR_INT)
+  {
+    bb=nlRInit(SR_TO_INT(b));
+    b=bb;
+  }
+  u=ALLOC_RNUMBER();
+#if defined(LDEBUG)
+  u->debug=123456;
+#endif
+  mpz_init(u->z);
+  /* u=a/b */
+  u->s = 3;
+  MPZ_EXACTDIV(u->z,a->z,b->z);
+  if (bb!=NULL)
+  {
+    mpz_clear(bb->z);
+#if defined(LDEBUG)
+    bb->debug=654324;
+#endif
+    FREE_RNUMBER(bb); // omFreeBin((void *)bb, rnumber_bin);
+  }
+  u=nlShort3(u);
+  nlTest(u, r);
+  return u;
+}
+
+/*2
+* u := a / b in Z
+*/
+number nlIntDiv (number a, number b, const coeffs r)
+{
+  if (b==INT_TO_SR(0))
+  {
+    WerrorS(nDivBy0);
+    return INT_TO_SR(0);
+  }
+  if (a==INT_TO_SR(0))
+    return INT_TO_SR(0);
+  number u;
+  if (SR_HDL(a) & SR_HDL(b) & SR_INT)
+  {
+    /* the small int -(1<<28) divided by -1 is the large int (1<<28)   */
+    if ((a==INT_TO_SR(-(POW_2_28)))&&(b==INT_TO_SR(-1L)))
+    {
+      return nlRInit(POW_2_28);
+    }
+    long aa=SR_TO_INT(a);
+    long bb=SR_TO_INT(b);
+    return INT_TO_SR(aa/bb);
+  }
+  if (SR_HDL(a) & SR_INT)
+  {
+    /* the small int -(1<<28) divided by 2^28 is 1   */
+    if (a==INT_TO_SR(-(POW_2_28)))
+    {
+      if(mpz_cmp_si(b->z,(POW_2_28))==0)
+      {
+        return INT_TO_SR(-1);
+      }
+    }
+    /* a is a small and b is a large int: -> 0 */
+    return INT_TO_SR(0);
+  }
+  number bb=NULL;
+  if (SR_HDL(b) & SR_INT)
+  {
+    bb=nlRInit(SR_TO_INT(b));
+    b=bb;
+  }
+  u=ALLOC_RNUMBER();
+#if defined(LDEBUG)
+  u->debug=123456;
+#endif
+  assume(a->s==3);
+  assume(b->s==3);
+  mpz_init_set(u->z,a->z);
+  /* u=u/b */
+  u->s = 3;
+  MPZ_DIV(u->z,u->z,b->z);
+  if (bb!=NULL)
+  {
+    mpz_clear(bb->z);
+#if defined(LDEBUG)
+    bb->debug=654324;
+#endif
+    FREE_RNUMBER(bb);
+  }
+  u=nlShort3(u);
+  nlTest(u,r);
+  return u;
+}
+
+/*2
+* u := a mod b in Z, u>=0
+*/
+number nlIntMod (number a, number b, const coeffs r)
+{
+  if (b==INT_TO_SR(0))
+  {
+    WerrorS(nDivBy0);
+    return INT_TO_SR(0);
+  }
+  if (a==INT_TO_SR(0))
+    return INT_TO_SR(0);
+  number u;
+  if (SR_HDL(a) & SR_HDL(b) & SR_INT)
+  {
+    LONG bb=SR_TO_INT(b);
+    LONG c=SR_TO_INT(a) % bb;
+    return INT_TO_SR(c);
+  }
+  if (SR_HDL(a) & SR_INT)
+  {
+    mpz_t aa;
+    mpz_init(aa);
+    mpz_set_si(aa, SR_TO_INT(a));
+    u=ALLOC_RNUMBER();
+#if defined(LDEBUG)
+    u->debug=123456;
+#endif
+    u->s = 3;
+    mpz_init(u->z);
+    mpz_mod(u->z,aa,b->z);
+    mpz_clear(aa);
+    u=nlShort3(u);
+    nlTest(u,r);
+    return u;
+  }
+  number bb=NULL;
+  if (SR_HDL(b) & SR_INT)
+  {
+    bb=nlRInit(SR_TO_INT(b));
+    b=bb;
+  }
+  u=ALLOC_RNUMBER();
+#if defined(LDEBUG)
+  u->debug=123456;
+#endif
+  mpz_init(u->z);
+  u->s = 3;
+  mpz_mod(u->z,a->z,b->z);
+  if (bb!=NULL)
+  {
+    mpz_clear(bb->z);
+#if defined(LDEBUG)
+    bb->debug=654324;
+#endif
+    FREE_RNUMBER(bb);
+  }
+  u=nlShort3(u);
+  nlTest(u,r);
+  return u;
+}
+
+BOOLEAN nlDivBy (number a,number b, const coeffs)
+{
+  if (SR_HDL(a) & SR_HDL(b) & SR_INT)
+  {
+    return ((SR_TO_INT(a) % SR_TO_INT(b))==0);
+  }
+  if (SR_HDL(b) & SR_INT)
+  {
+    return (mpz_divisible_ui_p(a->z,SR_TO_INT(b))!=0);
+  }
+  if (SR_HDL(a) & SR_INT) return FALSE;
+  return mpz_divisible_p(a->z, b->z) != 0;
+}
+
+int nlDivComp(number a, number b, const coeffs r)
+{
+  if (nlDivBy(a, b, r))
+  {
+    if (nlDivBy(b, a, r)) return 2;
+    return -1;
+  }
+  if (nlDivBy(b, a, r)) return 1;
+  return 0;
+}
+
+number  nlGetUnit (number n, const coeffs r)
+{
+  if (nlGreaterZero(n, r))
+    return INT_TO_SR(1);
+  else
+    return INT_TO_SR(-1);
+}
+
+coeffs nlQuot1(number c, const coeffs r)
+{
+  int ch = r->cfInt(c, r);
+  mpz_ptr dummy;
+  dummy = (mpz_ptr) omAlloc(sizeof(mpz_t));
+  mpz_init_set_ui(dummy, ch);
+  ZnmInfo info;
+  info.base = dummy;
+  info.exp = (unsigned long) 1;
+  coeffs rr = nInitChar(n_Zn, (void*)&info);
+  return(rr);
+}
+
+
+BOOLEAN nlIsUnit (number a, const coeffs)
+{
+  return ((SR_HDL(a) & SR_INT) && (ABS(SR_TO_INT(a))==1));
+}
+
+
+/*2
+* u := a / b
+*/
+number nlDiv (number a, number b, const coeffs r)
+{
+  if (nlIsZero(b,r))
+  {
+    WerrorS(nDivBy0);
+    return INT_TO_SR(0);
+  }
+  number u;
+// ---------- short / short ------------------------------------
+  if (SR_HDL(a) & SR_HDL(b) & SR_INT)
+  {
+    LONG i=SR_TO_INT(a);
+    LONG j=SR_TO_INT(b);
+    if (j==1L) return a;
+    if ((i==-POW_2_28) && (j== -1L))
+    {
+      return nlRInit(POW_2_28);
+    }
+    LONG r=i%j;
+    if (r==0)
+    {
+      return INT_TO_SR(i/j);
+    }
+    u=ALLOC_RNUMBER();
+    u->s=0;
+    #if defined(LDEBUG)
+    u->debug=123456;
+    #endif
+    mpz_init_set_si(u->z,(long)i);
+    mpz_init_set_si(u->n,(long)j);
+  }
+  else
+  {
+    u=ALLOC_RNUMBER();
+    u->s=0;
+    #if defined(LDEBUG)
+    u->debug=123456;
+    #endif
+    mpz_init(u->z);
+// ---------- short / long ------------------------------------
+    if (SR_HDL(a) & SR_INT)
+    {
+      // short a / (z/n) -> (a*n)/z
+      if (b->s<2)
+      {
+        mpz_mul_si(u->z,b->n,SR_TO_INT(a));
+      }
+      else
+      // short a / long z -> a/z
+      {
+        mpz_set_si(u->z,SR_TO_INT(a));
+      }
+      if (mpz_cmp(u->z,b->z)==0)
+      {
+        mpz_clear(u->z);
+        FREE_RNUMBER(u);
+        return INT_TO_SR(1);
+      }
+      mpz_init_set(u->n,b->z);
+    }
+// ---------- long / short ------------------------------------
+    else if (SR_HDL(b) & SR_INT)
+    {
+      mpz_set(u->z,a->z);
+      // (z/n) / b -> z/(n*b)
+      if (a->s<2)
+      {
+        mpz_init_set(u->n,a->n);
+        if ((long)b>0L)
+          mpz_mul_ui(u->n,u->n,SR_TO_INT(b));
+        else
+        {
+          mpz_mul_ui(u->n,u->n,-SR_TO_INT(b));
+          mpz_neg(u->z,u->z);
+        }
+      }
+      else
+      // long z / short b -> z/b
+      {
+        //mpz_set(u->z,a->z);
+        mpz_init_set_si(u->n,SR_TO_INT(b));
+      }
+    }
+// ---------- long / long ------------------------------------
+    else
+    {
+      mpz_set(u->z,a->z);
+      mpz_init_set(u->n,b->z);
+      if (a->s<2) mpz_mul(u->n,u->n,a->n);
+      if (b->s<2) mpz_mul(u->z,u->z,b->n);
+    }
+  }
+  if (mpz_isNeg(u->n))
+  {
+    mpz_neg(u->z,u->z);
+    mpz_neg(u->n,u->n);
+  }
+  if (mpz_cmp_si(u->n,(long)1)==0)
+  {
+    mpz_clear(u->n);
+    u->s=3;
+    u=nlShort3(u);
+  }
+  nlTest(u, r);
+  return u;
+}
+
+/*2
+* u:= x ^ exp
+*/
+void nlPower (number x,int exp,number * u, const coeffs r)
+{
+  *u = INT_TO_SR(0); // 0^e, e!=0
+  if (exp==0)
+    *u= INT_TO_SR(1);
+  else if (!nlIsZero(x,r))
+  {
+    nlTest(x, r);
+    number aa=NULL;
+    if (SR_HDL(x) & SR_INT)
+    {
+      aa=nlRInit(SR_TO_INT(x));
+      x=aa;
+    }
+    else if (x->s==0)
+      nlNormalize(x,r);
+    *u=ALLOC_RNUMBER();
+#if defined(LDEBUG)
+    (*u)->debug=123456;
+#endif
+    mpz_init((*u)->z);
+    mpz_pow_ui((*u)->z,x->z,(unsigned long)exp);
+    if (x->s<2)
+    {
+      if (mpz_cmp_si(x->n,(long)1)==0)
+      {
+        x->s=3;
+        mpz_clear(x->n);
+      }
+      else
+      {
+        mpz_init((*u)->n);
+        mpz_pow_ui((*u)->n,x->n,(unsigned long)exp);
+      }
+    }
+    (*u)->s = x->s;
+    if ((*u)->s==3) *u=nlShort3(*u);
+    if (aa!=NULL)
+    {
+      mpz_clear(aa->z);
+      FREE_RNUMBER(aa);
+    }
+  }
+#ifdef LDEBUG
+  if (exp<0) Print("nlPower: neg. exp. %d\n",exp);
+  nlTest(*u, r);
+#endif
+}
+
+
+/*2
+* za >= 0 ?
+*/
+BOOLEAN nlGreaterZero (number a, const coeffs r)
+{
+  nlTest(a, r);
+  if (SR_HDL(a) & SR_INT) return SR_HDL(a)>1L /* represents number(0) */;
+  return (!mpz_isNeg(a->z));
+}
+
+/*2
+* a > b ?
+*/
+BOOLEAN nlGreater (number a, number b, const coeffs r)
+{
+  nlTest(a, r);
+  nlTest(b, r);
+  number re;
+  BOOLEAN rr;
+  re=nlSub(a,b,r);
+  rr=(!nlIsZero(re,r)) && (nlGreaterZero(re,r));
+  nlDelete(&re,r);
+  return rr;
+}
+
+/*2
+* a == -1 ?
+*/
+BOOLEAN nlIsMOne (number a, const coeffs r)
+{
+#ifdef LDEBUG
+  if (a==NULL) return FALSE;
+  nlTest(a, r);
+#endif
+  return  (a==INT_TO_SR(-1L));
+}
+
+/*2
+* result =gcd(a,b)
+*/
+number nlGcd(number a, number b, const coeffs r)
+{
+  number result;
+  nlTest(a, r);
+  nlTest(b, r);
+  //nlNormalize(a);
+  //nlNormalize(b);
+  if ((a==INT_TO_SR(1L))||(a==INT_TO_SR(-1L))
+  ||  (b==INT_TO_SR(1L))||(b==INT_TO_SR(-1L)))
+    return INT_TO_SR(1L);
+  if (a==INT_TO_SR(0)) /* gcd(0,b) ->b */
+    return nlCopy(b,r);
+  if (b==INT_TO_SR(0)) /* gcd(a,0) -> a */
+    return nlCopy(a,r);
+  if (SR_HDL(a) & SR_HDL(b) & SR_INT)
+  {
+    long i=SR_TO_INT(a);
+    long j=SR_TO_INT(b);
+    if((i==0L)||(j==0L))
+      return INT_TO_SR(1);
+    long l;
+    i=ABS(i);
+    j=ABS(j);
+    do
+    {
+      l=i%j;
+      i=j;
+      j=l;
+    } while (l!=0L);
+    if (i==POW_2_28)
+      result=nlRInit(POW_2_28);
+    else
+     result=INT_TO_SR(i);
+    nlTest(result,r);
+    return result;
+  }
+  if (((!(SR_HDL(a) & SR_INT))&&(a->s<2))
+  ||  ((!(SR_HDL(b) & SR_INT))&&(b->s<2))) return INT_TO_SR(1);
+  if (SR_HDL(a) & SR_INT)
+  {
+    LONG aa=ABS(SR_TO_INT(a));
+    unsigned long t=mpz_gcd_ui(NULL,b->z,(long)aa);
+    if (t==POW_2_28)
+      result=nlRInit(POW_2_28);
+    else
+     result=INT_TO_SR(t);
+  }
+  else
+  if (SR_HDL(b) & SR_INT)
+  {
+    LONG bb=ABS(SR_TO_INT(b));
+    unsigned long t=mpz_gcd_ui(NULL,a->z,(long)bb);
+    if (t==POW_2_28)
+      result=nlRInit(POW_2_28);
+    else
+     result=INT_TO_SR(t);
+  }
+  else
+  {
+    result=ALLOC0_RNUMBER();
+    mpz_init(result->z);
+    mpz_gcd(result->z,a->z,b->z);
+    result->s = 3;
+  #ifdef LDEBUG
+    result->debug=123456;
+  #endif
+    result=nlShort3(result);
+  }
+  nlTest(result, r);
+  return result;
+}
+//number nlGcd_dummy(number a, number b, const coeffs r)
+//{
+//  extern char my_yylinebuf[80];
+//  Print("nlGcd in >>%s<<\n",my_yylinebuf);
+//  return nlGcd(a,b,r);;
+//}
+
+number nlShort1(number x) // assume x->s==0/1
+{
+  assume(x->s<2);
+  if (mpz_cmp_ui(x->z,(long)0)==0)
+  {
+    _nlDelete_NoImm(&x);
+    return INT_TO_SR(0);
+  }
+  if (x->s<2)
+  {
+    if (mpz_cmp(x->z,x->n)==0)
+    {
+      _nlDelete_NoImm(&x);
+      return INT_TO_SR(1);
+    }
+  }
+  return x;
+}
+/*2
+* simplify x
+*/
+void nlNormalize (number &x, const coeffs r)
+{
+  if ((SR_HDL(x) & SR_INT) ||(x==NULL))
+    return;
+  if (x->s==3)
+  {
+    x=nlShort3_noinline(x);
+    nlTest(x,r);
+    return;
+  }
+  else if (x->s==0)
+  {
+    if (mpz_cmp_si(x->n,(long)1)==0)
+    {
+      mpz_clear(x->n);
+      x->s=3;
+      x=nlShort3(x);
+    }
+    else
+    {
+      mpz_t gcd;
+      mpz_init(gcd);
+      mpz_gcd(gcd,x->z,x->n);
+      x->s=1;
+      if (mpz_cmp_si(gcd,(long)1)!=0)
+      {
+        MPZ_EXACTDIV(x->z,x->z,gcd);
+        MPZ_EXACTDIV(x->n,x->n,gcd);
+        if (mpz_cmp_si(x->n,(long)1)==0)
+        {
+          mpz_clear(x->n);
+          x->s=3;
+          x=nlShort3_noinline(x);
+        }
+      }
+      mpz_clear(gcd);
+    }
+  }
+  nlTest(x, r);
+}
+
+/*2
+* returns in result->z the lcm(a->z,b->n)
+*/
+number nlNormalizeHelper(number a, number b, const coeffs r)
+{
+  number result;
+  nlTest(a, r);
+  nlTest(b, r);
+  if ((SR_HDL(b) & SR_INT)
+  || (b->s==3))
+  {
+    // b is 1/(b->n) => b->n is 1 => result is a
+    return nlCopy(a,r);
+  }
+  result=ALLOC_RNUMBER();
+#if defined(LDEBUG)
+  result->debug=123456;
+#endif
+  result->s=3;
+  mpz_t gcd;
+  mpz_init(gcd);
+  mpz_init(result->z);
+  if (SR_HDL(a) & SR_INT)
+    mpz_gcd_ui(gcd,b->n,ABS(SR_TO_INT(a)));
+  else
+    mpz_gcd(gcd,a->z,b->n);
+  if (mpz_cmp_si(gcd,(long)1)!=0)
+  {
+    mpz_t bt;
+    mpz_init_set(bt,b->n);
+    MPZ_EXACTDIV(bt,bt,gcd);
+    if (SR_HDL(a) & SR_INT)
+      mpz_mul_si(result->z,bt,SR_TO_INT(a));
+    else
+      mpz_mul(result->z,bt,a->z);
+    mpz_clear(bt);
+  }
+  else
+    if (SR_HDL(a) & SR_INT)
+      mpz_mul_si(result->z,b->n,SR_TO_INT(a));
+    else
+      mpz_mul(result->z,b->n,a->z);
+  mpz_clear(gcd);
+  result=nlShort3(result);
+  nlTest(result, r);
+  return result;
+}
+
+// Map q \in QQ or ZZ \to Zp or an extension of it
+// src = Q or Z, dst = Zp (or an extension of Zp)
+number nlModP(number q, const coeffs Q, const coeffs Zp)
+{
+  const int p = n_GetChar(Zp);
+  assume( p > 0 );
+
+  const long P = p;
+  assume( P > 0 );
+
+  // embedded long within q => only long numerator has to be converted
+  // to int (modulo char.)
+  if (SR_HDL(q) & SR_INT)
+  {
+    long i = SR_TO_INT(q);
+    return n_Init( i, Zp );
+  }
+
+  const unsigned long PP = p;
+
+  // numerator modulo char. should fit into int
+  number z = n_Init( static_cast<long>(mpz_fdiv_ui(q->z, PP)), Zp );
+
+  // denominator != 1?
+  if (q->s!=3)
+  {
+    // denominator modulo char. should fit into int
+    number n = n_Init( static_cast<long>(mpz_fdiv_ui(q->n, PP)), Zp );
+
+    number res = n_Div( z, n, Zp );
+
+    n_Delete(&z, Zp);
+    n_Delete(&n, Zp);
+
+    return res;
+  }
+
+  return z;
+}
+
+#ifdef HAVE_RINGS
+/*2
+* convert number i (from Q) to GMP and warn if denom != 1
+*/
+void nlGMP(number &i, number n, const coeffs r)
+{
+  // Hier brauche ich einfach die GMP Zahl
+  nlTest(i, r);
+  nlNormalize(i, r);
+  if (SR_HDL(i) & SR_INT)
+  {
+    mpz_set_si((mpz_ptr) n, SR_TO_INT(i));
+    return;
+  }
+  if (i->s!=3)
+  {
+     WarnS("Omitted denominator during coefficient mapping !");
+  }
+  mpz_set((mpz_ptr) n, i->z);
+}
+#endif
+
+/*2
+* acces to denominator, other 1 for integers
+*/
+number   nlGetDenom(number &n, const coeffs r)
+{
+  if (!(SR_HDL(n) & SR_INT))
+  {
+    if (n->s==0)
+    {
+      nlNormalize(n,r);
+    }
+    if (!(SR_HDL(n) & SR_INT))
+    {
+      if (n->s!=3)
+      {
+        number u=ALLOC_RNUMBER();
+        u->s=3;
+#if defined(LDEBUG)
+        u->debug=123456;
+#endif
+        mpz_init_set(u->z,n->n);
+        u=nlShort3_noinline(u);
+        return u;
+      }
+    }
+  }
+  return INT_TO_SR(1);
+}
+
+/*2
+* acces to Nominator, nlCopy(n) for integers
+*/
+number   nlGetNumerator(number &n, const coeffs r)
+{
+  if (!(SR_HDL(n) & SR_INT))
+  {
+    if (n->s==0)
+    {
+      nlNormalize(n,r);
+    }
+    if (!(SR_HDL(n) & SR_INT))
+    {
+      number u=ALLOC_RNUMBER();
+#if defined(LDEBUG)
+      u->debug=123456;
+#endif
+      u->s=3;
+      mpz_init_set(u->z,n->z);
+      if (n->s!=3)
+      {
+        u=nlShort3_noinline(u);
+      }
+      return u;
+    }
+  }
+  return n; // imm. int
+}
+
+/***************************************************************
+ *
+ * routines which are needed by Inline(d) routines
+ *
+ *******************************************************************/
+BOOLEAN _nlEqual_aNoImm_OR_bNoImm(number a, number b)
+{
+  assume(! (SR_HDL(a) & SR_HDL(b) & SR_INT));
+//  long - short
+  BOOLEAN bo;
+  if (SR_HDL(b) & SR_INT)
+  {
+    if (a->s!=0) return FALSE;
+    number n=b; b=a; a=n;
+  }
+//  short - long
+  if (SR_HDL(a) & SR_INT)
+  {
+    if (b->s!=0)
+      return FALSE;
+    if (((long)a > 0L) && (mpz_isNeg(b->z)))
+      return FALSE;
+    if (((long)a < 0L) && (!mpz_isNeg(b->z)))
+      return FALSE;
+    mpz_t  bb;
+    mpz_init_set(bb,b->n);
+    mpz_mul_si(bb,bb,(long)SR_TO_INT(a));
+    bo=(mpz_cmp(bb,b->z)==0);
+    mpz_clear(bb);
+    return bo;
+  }
+// long - long
+  if (((a->s==1) && (b->s==3))
+  ||  ((b->s==1) && (a->s==3)))
+    return FALSE;
+  if (mpz_isNeg(a->z)&&(!mpz_isNeg(b->z)))
+    return FALSE;
+  if (mpz_isNeg(b->z)&&(!mpz_isNeg(a->z)))
+    return FALSE;
+  mpz_t  aa;
+  mpz_t  bb;
+  mpz_init_set(aa,a->z);
+  mpz_init_set(bb,b->z);
+  if (a->s<2) mpz_mul(bb,bb,a->n);
+  if (b->s<2) mpz_mul(aa,aa,b->n);
+  bo=(mpz_cmp(aa,bb)==0);
+  mpz_clear(aa);
+  mpz_clear(bb);
+  return bo;
+}
+
+// copy not immediate number a
+number _nlCopy_NoImm(number a)
+{
+  assume(!((SR_HDL(a) & SR_INT)||(a==NULL)));
+  //nlTest(a, r);
+  number b=ALLOC_RNUMBER();
+#if defined(LDEBUG)
+  b->debug=123456;
+#endif
+  switch (a->s)
+  {
+    case 0:
+    case 1:
+            mpz_init_set(b->n,a->n);
+    case 3:
+            mpz_init_set(b->z,a->z);
+            break;
+  }
+  b->s = a->s;
+  return b;
+}
+
+void _nlDelete_NoImm(number *a)
+{
+  {
+    switch ((*a)->s)
+    {
+      case 0:
+      case 1:
+        mpz_clear((*a)->n);
+      case 3:
+        mpz_clear((*a)->z);
+#ifdef LDEBUG
+        (*a)->s=2;
+#endif
+    }
+    FREE_RNUMBER(*a); // omFreeBin((void *) *a, rnumber_bin);
+  }
+}
+
+number _nlNeg_NoImm(number a)
+{
+  {
+    mpz_neg(a->z,a->z);
+    if (a->s==3)
+    {
+      a=nlShort3(a);
+    }
+  }
+  return a;
+}
+
+number _nlAdd_aNoImm_OR_bNoImm(number a, number b)
+{
+  number u=ALLOC_RNUMBER();
+#if defined(LDEBUG)
+  u->debug=123456;
+#endif
+  mpz_init(u->z);
+  if (SR_HDL(b) & SR_INT)
+  {
+    number x=a;
+    a=b;
+    b=x;
+  }
+  if (SR_HDL(a) & SR_INT)
+  {
+    switch (b->s)
+    {
+      case 0:
+      case 1:/* a:short, b:1 */
+      {
+        mpz_t x;
+        mpz_init(x);
+        mpz_mul_si(x,b->n,SR_TO_INT(a));
+        mpz_add(u->z,b->z,x);
+        mpz_clear(x);
+        if (mpz_cmp_ui(u->z,(long)0)==0)
+        {
+          mpz_clear(u->z);
+          FREE_RNUMBER(u);
+          return INT_TO_SR(0);
+        }
+        if (mpz_cmp(u->z,b->n)==0)
+        {
+          mpz_clear(u->z);
+          FREE_RNUMBER(u);
+          return INT_TO_SR(1);
+        }
+        mpz_init_set(u->n,b->n);
+        u->s = 0;
+        break;
+      }
+      case 3:
+      {
+        if ((long)a>0L)
+          mpz_add_ui(u->z,b->z,SR_TO_INT(a));
+        else
+          mpz_sub_ui(u->z,b->z,-SR_TO_INT(a));
+        if (mpz_cmp_ui(u->z,(long)0)==0)
+        {
+          mpz_clear(u->z);
+          FREE_RNUMBER(u);
+          return INT_TO_SR(0);
+        }
+        u->s = 3;
+        u=nlShort3(u);
+        break;
+      }
+    }
+  }
+  else
+  {
+    switch (a->s)
+    {
+      case 0:
+      case 1:
+      {
+        switch(b->s)
+        {
+          case 0:
+          case 1:
+          {
+            mpz_t x;
+            mpz_init(x);
+
+            mpz_mul(x,b->z,a->n);
+            mpz_mul(u->z,a->z,b->n);
+            mpz_add(u->z,u->z,x);
+            mpz_clear(x);
+
+            if (mpz_cmp_ui(u->z,(long)0)==0)
+            {
+              mpz_clear(u->z);
+              FREE_RNUMBER(u);
+              return INT_TO_SR(0);
+            }
+            mpz_init(u->n);
+            mpz_mul(u->n,a->n,b->n);
+            if (mpz_cmp(u->z,u->n)==0)
+            {
+               mpz_clear(u->z);
+               mpz_clear(u->n);
+               FREE_RNUMBER(u);
+               return INT_TO_SR(1);
+            }
+            u->s = 0;
+            break;
+          }
+          case 3: /* a:1 b:3 */
+          {
+            mpz_mul(u->z,b->z,a->n);
+            mpz_add(u->z,u->z,a->z);
+            if (mpz_cmp_ui(u->z,(long)0)==0)
+            {
+              mpz_clear(u->z);
+              FREE_RNUMBER(u);
+              return INT_TO_SR(0);
+            }
+            if (mpz_cmp(u->z,a->n)==0)
+            {
+              mpz_clear(u->z);
+              FREE_RNUMBER(u);
+              return INT_TO_SR(1);
+            }
+            mpz_init_set(u->n,a->n);
+            u->s = 0;
+            break;
+          }
+        } /*switch (b->s) */
+        break;
+      }
+      case 3:
+      {
+        switch(b->s)
+        {
+          case 0:
+          case 1:/* a:3, b:1 */
+          {
+            mpz_mul(u->z,a->z,b->n);
+            mpz_add(u->z,u->z,b->z);
+            if (mpz_cmp_ui(u->z,(long)0)==0)
+            {
+              mpz_clear(u->z);
+              FREE_RNUMBER(u);
+              return INT_TO_SR(0);
+            }
+            if (mpz_cmp(u->z,b->n)==0)
+            {
+              mpz_clear(u->z);
+              FREE_RNUMBER(u);
+              return INT_TO_SR(1);
+            }
+            mpz_init_set(u->n,b->n);
+            u->s = 0;
+            break;
+          }
+          case 3:
+          {
+            mpz_add(u->z,a->z,b->z);
+            if (mpz_cmp_ui(u->z,(long)0)==0)
+            {
+              mpz_clear(u->z);
+              FREE_RNUMBER(u);
+              return INT_TO_SR(0);
+            }
+            u->s = 3;
+            u=nlShort3(u);
+            break;
+          }
+        }
+        break;
+      }
+    }
+  }
+  return u;
+}
+
+void _nlInpAdd_aNoImm_OR_bNoImm(number &a, number b)
+{
+  if (SR_HDL(b) & SR_INT)
+  {
+    switch (a->s)
+    {
+      case 0:
+      case 1:/* b:short, a:1 */
+      {
+        mpz_t x;
+        mpz_init(x);
+        mpz_mul_si(x,a->n,SR_TO_INT(b));
+        mpz_add(a->z,a->z,x);
+        mpz_clear(x);
+        a->s = 0;
+        a=nlShort1(a);
+        break;
+      }
+      case 3:
+      {
+        if ((long)b>0L)
+          mpz_add_ui(a->z,a->z,SR_TO_INT(b));
+        else
+          mpz_sub_ui(a->z,a->z,-SR_TO_INT(b));
+        a->s = 3;
+        a=nlShort3_noinline(a);
+        break;
+      }
+    }
+    return;
+  }
+  else if (SR_HDL(a) & SR_INT)
+  {
+    number u=ALLOC_RNUMBER();
+    #if defined(LDEBUG)
+    u->debug=123456;
+    #endif
+    mpz_init(u->z);
+    switch (b->s)
+    {
+      case 0:
+      case 1:/* a:short, b:1 */
+      {
+        mpz_t x;
+        mpz_init(x);
+
+        mpz_mul_si(x,b->n,SR_TO_INT(a));
+        mpz_add(u->z,b->z,x);
+        mpz_clear(x);
+        // result cannot be 0, if coeffs are normalized
+        mpz_init_set(u->n,b->n);
+        u->s = 0;
+        u=nlShort1(u);
+        break;
+      }
+      case 3:
+      {
+        if ((long)a>0L)
+          mpz_add_ui(u->z,b->z,SR_TO_INT(a));
+        else
+          mpz_sub_ui(u->z,b->z,-SR_TO_INT(a));
+        // result cannot be 0, if coeffs are normalized
+        u->s = 3;
+        u=nlShort3_noinline(u);
+        break;
+      }
+    }
+    a=u;
+  }
+  else
+  {
+    switch (a->s)
+    {
+      case 0:
+      case 1:
+      {
+        switch(b->s)
+        {
+          case 0:
+          case 1: /* a:1 b:1 */
+          {
+            mpz_t x;
+            mpz_t y;
+            mpz_init(x);
+            mpz_init(y);
+            mpz_mul(x,b->z,a->n);
+            mpz_mul(y,a->z,b->n);
+            mpz_add(a->z,x,y);
+            mpz_clear(x);
+            mpz_clear(y);
+            mpz_mul(a->n,a->n,b->n);
+            a->s = 0;
+            break;
+          }
+          case 3: /* a:1 b:3 */
+          {
+            mpz_t x;
+            mpz_init(x);
+            mpz_mul(x,b->z,a->n);
+            mpz_add(a->z,a->z,x);
+            mpz_clear(x);
+            a->s = 0;
+            break;
+          }
+        } /*switch (b->s) */
+        a=nlShort1(a);
+        break;
+      }
+      case 3:
+      {
+        switch(b->s)
+        {
+          case 0:
+          case 1:/* a:3, b:1 */
+          {
+            mpz_t x;
+            mpz_init(x);
+            mpz_mul(x,a->z,b->n);
+            mpz_add(a->z,b->z,x);
+            mpz_clear(x);
+            mpz_init_set(a->n,b->n);
+            a->s = 0;
+            a=nlShort1(a);
+            break;
+          }
+          case 3:
+          {
+            mpz_add(a->z,a->z,b->z);
+            a->s = 3;
+            a=nlShort3_noinline(a);
+            break;
+          }
+        }
+        break;
+      }
+    }
+  }
+}
+
+number _nlSub_aNoImm_OR_bNoImm(number a, number b)
+{
+  number u=ALLOC_RNUMBER();
+#if defined(LDEBUG)
+  u->debug=123456;
+#endif
+  mpz_init(u->z);
+  if (SR_HDL(a) & SR_INT)
+  {
+    switch (b->s)
+    {
+      case 0:
+      case 1:/* a:short, b:1 */
+      {
+        mpz_t x;
+        mpz_init(x);
+        mpz_mul_si(x,b->n,SR_TO_INT(a));
+        mpz_sub(u->z,x,b->z);
+        mpz_clear(x);
+        if (mpz_cmp_ui(u->z,(long)0)==0)
+        {
+          mpz_clear(u->z);
+          FREE_RNUMBER(u);
+          return INT_TO_SR(0);
+        }
+        if (mpz_cmp(u->z,b->n)==0)
+        {
+          mpz_clear(u->z);
+          FREE_RNUMBER(u);
+          return INT_TO_SR(1);
+        }
+        mpz_init_set(u->n,b->n);
+        u->s = 0;
+        break;
+      }
+      case 3:
+      {
+        if ((long)a>0L)
+        {
+          mpz_sub_ui(u->z,b->z,SR_TO_INT(a));
+          mpz_neg(u->z,u->z);
+        }
+        else
+        {
+          mpz_add_ui(u->z,b->z,-SR_TO_INT(a));
+          mpz_neg(u->z,u->z);
+        }
+        if (mpz_cmp_ui(u->z,(long)0)==0)
+        {
+          mpz_clear(u->z);
+          FREE_RNUMBER(u);
+          return INT_TO_SR(0);
+        }
+        u->s = 3;
+        u=nlShort3(u);
+        break;
+      }
+    }
+  }
+  else if (SR_HDL(b) & SR_INT)
+  {
+    switch (a->s)
+    {
+      case 0:
+      case 1:/* b:short, a:1 */
+      {
+        mpz_t x;
+        mpz_init(x);
+        mpz_mul_si(x,a->n,SR_TO_INT(b));
+        mpz_sub(u->z,a->z,x);
+        mpz_clear(x);
+        if (mpz_cmp_ui(u->z,(long)0)==0)
+        {
+          mpz_clear(u->z);
+          FREE_RNUMBER(u);
+          return INT_TO_SR(0);
+        }
+        if (mpz_cmp(u->z,a->n)==0)
+        {
+          mpz_clear(u->z);
+          FREE_RNUMBER(u);
+          return INT_TO_SR(1);
+        }
+        mpz_init_set(u->n,a->n);
+        u->s = 0;
+        break;
+      }
+      case 3:
+      {
+        if ((long)b>0L)
+        {
+          mpz_sub_ui(u->z,a->z,SR_TO_INT(b));
+        }
+        else
+        {
+          mpz_add_ui(u->z,a->z,-SR_TO_INT(b));
+        }
+        if (mpz_cmp_ui(u->z,(long)0)==0)
+        {
+          mpz_clear(u->z);
+          FREE_RNUMBER(u);
+          return INT_TO_SR(0);
+        }
+        u->s = 3;
+        u=nlShort3(u);
+        break;
+      }
+    }
+  }
+  else
+  {
+    switch (a->s)
+    {
+      case 0:
+      case 1:
+      {
+        switch(b->s)
+        {
+          case 0:
+          case 1:
+          {
+            mpz_t x;
+            mpz_t y;
+            mpz_init(x);
+            mpz_init(y);
+            mpz_mul(x,b->z,a->n);
+            mpz_mul(y,a->z,b->n);
+            mpz_sub(u->z,y,x);
+            mpz_clear(x);
+            mpz_clear(y);
+            if (mpz_cmp_ui(u->z,(long)0)==0)
+            {
+              mpz_clear(u->z);
+              FREE_RNUMBER(u);
+              return INT_TO_SR(0);
+            }
+            mpz_init(u->n);
+            mpz_mul(u->n,a->n,b->n);
+            if (mpz_cmp(u->z,u->n)==0)
+            {
+              mpz_clear(u->z);
+              mpz_clear(u->n);
+              FREE_RNUMBER(u);
+              return INT_TO_SR(1);
+            }
+            u->s = 0;
+            break;
+          }
+          case 3: /* a:1, b:3 */
+          {
+            mpz_t x;
+            mpz_init(x);
+            mpz_mul(x,b->z,a->n);
+            mpz_sub(u->z,a->z,x);
+            mpz_clear(x);
+            if (mpz_cmp_ui(u->z,(long)0)==0)
+            {
+              mpz_clear(u->z);
+              FREE_RNUMBER(u);
+              return INT_TO_SR(0);
+            }
+            if (mpz_cmp(u->z,a->n)==0)
+            {
+              mpz_clear(u->z);
+              FREE_RNUMBER(u);
+              return INT_TO_SR(1);
+            }
+            mpz_init_set(u->n,a->n);
+            u->s = 0;
+            break;
+          }
+        }
+        break;
+      }
+      case 3:
+      {
+        switch(b->s)
+        {
+          case 0:
+          case 1: /* a:3, b:1 */
+          {
+            mpz_t x;
+            mpz_init(x);
+            mpz_mul(x,a->z,b->n);
+            mpz_sub(u->z,x,b->z);
+            mpz_clear(x);
+            if (mpz_cmp_ui(u->z,(long)0)==0)
+            {
+              mpz_clear(u->z);
+              FREE_RNUMBER(u);
+              return INT_TO_SR(0);
+            }
+            if (mpz_cmp(u->z,b->n)==0)
+            {
+              mpz_clear(u->z);
+              FREE_RNUMBER(u);
+              return INT_TO_SR(1);
+            }
+            mpz_init_set(u->n,b->n);
+            u->s = 0;
+            break;
+          }
+          case 3: /* a:3 , b:3 */
+          {
+            mpz_sub(u->z,a->z,b->z);
+            if (mpz_cmp_ui(u->z,(long)0)==0)
+            {
+              mpz_clear(u->z);
+              FREE_RNUMBER(u);
+              return INT_TO_SR(0);
+            }
+            u->s = 3;
+            u=nlShort3(u);
+            break;
+          }
+        }
+        break;
+      }
+    }
+  }
+  return u;
+}
+
+// a and b are intermediate, but a*b not
+number _nlMult_aImm_bImm_rNoImm(number a, number b)
+{
+  number u=ALLOC_RNUMBER();
+#if defined(LDEBUG)
+  u->debug=123456;
+#endif
+  u->s=3;
+  mpz_init_set_si(u->z,SR_TO_INT(a));
+  mpz_mul_si(u->z,u->z,SR_TO_INT(b));
+  return u;
+}
+
+// a or b are not immediate
+number _nlMult_aNoImm_OR_bNoImm(number a, number b)
+{
+  assume(! (SR_HDL(a) & SR_HDL(b) & SR_INT));
+  number u=ALLOC_RNUMBER();
+#if defined(LDEBUG)
+  u->debug=123456;
+#endif
+  mpz_init(u->z);
+  if (SR_HDL(b) & SR_INT)
+  {
+    number x=a;
+    a=b;
+    b=x;
+  }
+  if (SR_HDL(a) & SR_INT)
+  {
+    u->s=b->s;
+    if (u->s==1) u->s=0;
+    if ((long)a>0L)
+    {
+      mpz_mul_ui(u->z,b->z,(unsigned long)SR_TO_INT(a));
+    }
+    else
+    {
+      if (a==INT_TO_SR(-1))
+      {
+        mpz_set(u->z,b->z);
+        mpz_neg(u->z,u->z);
+        u->s=b->s;
+      }
+      else
+      {
+        mpz_mul_ui(u->z,b->z,(unsigned long)-SR_TO_INT(a));
+        mpz_neg(u->z,u->z);
+      }
+    }
+    if (u->s<2)
+    {
+      if (mpz_cmp(u->z,b->n)==0)
+      {
+        mpz_clear(u->z);
+        FREE_RNUMBER(u);
+        return INT_TO_SR(1);
+      }
+      mpz_init_set(u->n,b->n);
+    }
+    else //u->s==3
+    {
+      u=nlShort3(u);
+    }
+  }
+  else
+  {
+    mpz_mul(u->z,a->z,b->z);
+    u->s = 0;
+    if(a->s==3)
+    {
+      if(b->s==3)
+      {
+        u->s = 3;
+      }
+      else
+      {
+        if (mpz_cmp(u->z,b->n)==0)
+        {
+          mpz_clear(u->z);
+          FREE_RNUMBER(u);
+          return INT_TO_SR(1);
+        }
+        mpz_init_set(u->n,b->n);
+      }
+    }
+    else
+    {
+      if(b->s==3)
+      {
+        if (mpz_cmp(u->z,a->n)==0)
+        {
+          mpz_clear(u->z);
+          FREE_RNUMBER(u);
+          return INT_TO_SR(1);
+        }
+        mpz_init_set(u->n,a->n);
+      }
+      else
+      {
+        mpz_init(u->n);
+        mpz_mul(u->n,a->n,b->n);
+        if (mpz_cmp(u->z,u->n)==0)
+        {
+          mpz_clear(u->z);
+          mpz_clear(u->n);
+          FREE_RNUMBER(u);
+          return INT_TO_SR(1);
+        }
+      }
+    }
+  }
+  return u;
+}
+
+/*2
+* copy a to b for mapping
+*/
+number nlCopyMap(number a, const coeffs src, const coeffs dst)
+{
+  if ((SR_HDL(a) & SR_INT)||(a==NULL))
+  {
+    return a;
+  }
+  return _nlCopy_NoImm(a);
+}
+
+nMapFunc nlSetMap(const coeffs src, const coeffs dst)
+{
+  if (src->rep==n_rep_gap_rat)  /*Q, coeffs_BIGINT */
+  {
+    return ndCopyMap;
+  }
+  if ((src->rep==n_rep_int) && nCoeff_is_Zp(src))
+  {
+    return nlMapP;
+  }
+  if ((src->rep==n_rep_float) && nCoeff_is_R(src))
+  {
+    return nlMapR;
+  }
+  if ((src->rep==n_rep_gmp_float) && nCoeff_is_long_R(src))
+  {
+    return nlMapLongR; /* long R -> Q */
+  }
+#ifdef HAVE_RINGS
+  if (src->rep==n_rep_gmp) // nCoeff_is_Ring_Z(src) || nCoeff_is_Ring_PtoM(src) || nCoeff_is_Ring_ModN(src))
+  {
+    return nlMapGMP;
+  }
+  if (src->rep==n_rep_gap_gmp)
+  {
+    return nlMapZ;
+  }
+  if ((src->rep==n_rep_int) && nCoeff_is_Ring_2toM(src))
+  {
+    return nlMapMachineInt;
+  }
+#endif
+  return NULL;
+}
+/*2
+* z := i
+*/
+number nlRInit (long i)
+{
+  number z=ALLOC_RNUMBER();
+#if defined(LDEBUG)
+  z->debug=123456;
+#endif
+  mpz_init_set_si(z->z,i);
+  z->s = 3;
+  return z;
+}
+
+/*2
+* z := i/j
+*/
+number nlInit2 (int i, int j, const coeffs r)
+{
+  number z=ALLOC_RNUMBER();
+#if defined(LDEBUG)
+  z->debug=123456;
+#endif
+  mpz_init_set_si(z->z,(long)i);
+  mpz_init_set_si(z->n,(long)j);
+  z->s = 0;
+  nlNormalize(z,r);
+  return z;
+}
+
+number nlInit2gmp (mpz_t i, mpz_t j, const coeffs r)
+{
+  number z=ALLOC_RNUMBER();
+#if defined(LDEBUG)
+  z->debug=123456;
+#endif
+  mpz_init_set(z->z,i);
+  mpz_init_set(z->n,j);
+  z->s = 0;
+  nlNormalize(z,r);
+  return z;
+}
+
+#else // DO_LINLINE
+
+// declare immedate routines
+number nlRInit (long i);
+BOOLEAN _nlEqual_aNoImm_OR_bNoImm(number a, number b);
+number  _nlCopy_NoImm(number a);
+number  _nlNeg_NoImm(number a);
+number  _nlAdd_aNoImm_OR_bNoImm(number a, number b);
+void    _nlInpAdd_aNoImm_OR_bNoImm(number &a, number b);
+number  _nlSub_aNoImm_OR_bNoImm(number a, number b);
+number  _nlMult_aNoImm_OR_bNoImm(number a, number b);
+number  _nlMult_aImm_bImm_rNoImm(number a, number b);
+
+#endif
+
+/***************************************************************
+ *
+ * Routines which might be inlined by p_Numbers.h
+ *
+ *******************************************************************/
+#if defined(DO_LINLINE) || !defined(P_NUMBERS_H)
+
+// routines which are always inlined/static
+
+/*2
+* a = b ?
+*/
+LINLINE BOOLEAN nlEqual (number a, number b, const coeffs r)
+{
+  nlTest(a, r);
+  nlTest(b, r);
+// short - short
+  if (SR_HDL(a) & SR_HDL(b) & SR_INT) return a==b;
+  return _nlEqual_aNoImm_OR_bNoImm(a, b);
+}
+
+LINLINE number nlInit (long i, const coeffs r)
+{
+  number n;
+  LONG ii=(LONG)i;
+  if ( ((ii << 3) >> 3) == ii ) n=INT_TO_SR(ii);
+  else                          n=nlRInit(ii);
+  nlTest(n, r);
+  return n;
+}
+
+/*2
+* a == 1 ?
+*/
+LINLINE BOOLEAN nlIsOne (number a, const coeffs r)
+{
+#ifdef LDEBUG
+  if (a==NULL) return FALSE;
+  nlTest(a, r);
+#endif
+  return (a==INT_TO_SR(1));
+}
+
+LINLINE BOOLEAN nlIsZero (number a, const coeffs)
+{
+  #if 0
+  if (a==INT_TO_SR(0)) return TRUE;
+  if ((SR_HDL(a) & SR_INT)||(a==NULL)) return FALSE;
+  if (mpz_cmp_si(a->z,(long)0)==0)
+  {
+    printf("gmp-0 in nlIsZero\n");
+    dErrorBreak();
+    return TRUE;
+  }
+  return FALSE;
+  #else
+  return (a==INT_TO_SR(0));
+  #endif
+}
+
+/*2
+* copy a to b
+*/
+LINLINE number nlCopy(number a, const coeffs)
+{
+  if ((SR_HDL(a) & SR_INT)||(a==NULL))
+  {
+    return a;
+  }
+  return _nlCopy_NoImm(a);
+}
+
+
+/*2
+* delete a
+*/
+LINLINE void nlDelete (number * a, const coeffs r)
+{
+  if (*a!=NULL)
+  {
+    nlTest(*a, r);
+    if ((SR_HDL(*a) & SR_INT)==0)
+    {
+      _nlDelete_NoImm(a);
+    }
+    *a=NULL;
+  }
+}
+
+/*2
+* za:= - za
+*/
+LINLINE number nlNeg (number a, const coeffs R)
+{
+  nlTest(a, R);
+  if(SR_HDL(a) &SR_INT)
+  {
+    LONG r=SR_TO_INT(a);
+    if (r==(-(POW_2_28))) a=nlRInit(POW_2_28);
+    else               a=INT_TO_SR(-r);
+    return a;
+  }
+  a = _nlNeg_NoImm(a);
+  nlTest(a, R);
+  return a;
+
+}
+
+/*2
+* u:= a + b
+*/
+LINLINE number nlAdd (number a, number b, const coeffs R)
+{
+  if (SR_HDL(a) & SR_HDL(b) & SR_INT)
+  {
+    LONG r=SR_HDL(a)+SR_HDL(b)-1L;
+    if ( ((r << 1) >> 1) == r )
+      return (number)(long)r;
+    else
+      return nlRInit(SR_TO_INT(r));
+  }
+  number u =  _nlAdd_aNoImm_OR_bNoImm(a, b);
+  nlTest(u, R);
+  return u;
+}
+
+number nlShort1(number a);
+number nlShort3_noinline(number x);
+
+LINLINE void nlInpAdd(number &a, number b, const coeffs r)
+{
+  // a=a+b
+  if (SR_HDL(a) & SR_HDL(b) & SR_INT)
+  {
+    LONG r=SR_HDL(a)+SR_HDL(b)-1L;
+    if ( ((r << 1) >> 1) == r )
+      a=(number)(long)r;
+    else
+      a=nlRInit(SR_TO_INT(r));
+  }
+  else
+  {
+    _nlInpAdd_aNoImm_OR_bNoImm(a,b);
+    nlTest(a,r);
+  }
+}
+
+LINLINE number nlMult (number a, number b, const coeffs R)
+{
+  nlTest(a, R);
+  nlTest(b, R);
+  if (a==INT_TO_SR(0)) return INT_TO_SR(0);
+  if (b==INT_TO_SR(0)) return INT_TO_SR(0);
+  if (SR_HDL(a) & SR_HDL(b) & SR_INT)
+  {
+    LONG r=(LONG)((unsigned LONG)(SR_HDL(a)-1L))*((unsigned LONG)(SR_HDL(b)>>1));
+    if ((r/(SR_HDL(b)>>1))==(SR_HDL(a)-1L))
+    {
+      number u=((number) ((r>>1)+SR_INT));
+      if (((((LONG)SR_HDL(u))<<1)>>1)==SR_HDL(u)) return (u);
+      return nlRInit(SR_HDL(u)>>2);
+    }
+    number u = _nlMult_aImm_bImm_rNoImm(a, b);
+    nlTest(u, R);
+    return u;
+
+  }
+  number u = _nlMult_aNoImm_OR_bNoImm(a, b);
+  nlTest(u, R);
+  return u;
+
+}
+
+
+/*2
+* u:= a - b
+*/
+LINLINE number nlSub (number a, number b, const coeffs r)
+{
+  if (SR_HDL(a) & SR_HDL(b) & SR_INT)
+  {
+    LONG r=SR_HDL(a)-SR_HDL(b)+1;
+    if ( ((r << 1) >> 1) == r )
+    {
+      return (number)(long)r;
+    }
+    else
+      return nlRInit(SR_TO_INT(r));
+  }
+  number u = _nlSub_aNoImm_OR_bNoImm(a, b);
+  nlTest(u, r);
+  return u;
+
+}
+
+LINLINE void nlInpMult(number &a, number b, const coeffs r)
+{
+  number aa=a;
+  if (((SR_HDL(b)|SR_HDL(aa))&SR_INT))
+  {
+    number n=nlMult(aa,b,r);
+    nlDelete(&a,r);
+    a=n;
+  }
+  else
+  {
+    mpz_mul(aa->z,a->z,b->z);
+    if (aa->s==3)
+    {
+      if(b->s!=3)
+      {
+        mpz_init_set(a->n,b->n);
+        a->s=0;
+      }
+    }
+    else
+    {
+      if(b->s!=3)
+      {
+        mpz_mul(a->n,a->n,b->n);
+      }
+      a->s=0;
+    }
+  }
+}
+#endif // DO_LINLINE
+
+#ifndef P_NUMBERS_H
+
+static void nlMPZ(mpz_t m, number &n, const coeffs r)
+{
+  nlTest(n, r);
+  nlNormalize(n, r);
+  if (SR_HDL(n) & SR_INT) mpz_init_set_si(m, SR_TO_INT(n));     /* n fits in an int */
+  else             mpz_init_set(m, (mpz_ptr)n->z);
+}
+
+
+static number nlInitMPZ(mpz_t m, const coeffs)
+{
+  number z = ALLOC_RNUMBER();
+  mpz_init_set(z->z, m);
+  mpz_init_set_ui(z->n, 1);
+  z->s = 3;
+  return z;
+}
+
+
+void nlInpGcd(number &a, number b, const coeffs r)
+{
+  if ((SR_HDL(b)|SR_HDL(a))&SR_INT)
+  {
+    number n=nlGcd(a,b,r);
+    nlDelete(&a,r);
+    a=n;
+  }
+  else
+  {
+    mpz_gcd(a->z,a->z,b->z);
+    a=nlShort3_noinline(a);
+  }
+}
+
+void nlInpIntDiv(number &a, number b, const coeffs r)
+{
+  if ((SR_HDL(b)|SR_HDL(a))&SR_INT)
+  {
+    number n=nlIntDiv(a,b, r);
+    nlDelete(&a,r);
+    a=n;
+  }
+  else
+  {
+    if (mpz_isNeg(a->z))
+    {
+      if (mpz_isNeg(b->z))
+      {
+        mpz_add(a->z,a->z,b->z);
+      }
+      else
+      {
+        mpz_sub(a->z,a->z,b->z);
+      }
+      mpz_add_ui(a->z,a->z,1);
+    }
+    else
+    {
+      if (mpz_isNeg(b->z))
+      {
+        mpz_sub(a->z,a->z,b->z);
+      }
+      else
+      {
+        mpz_add(a->z,a->z,b->z);
+      }
+      mpz_sub_ui(a->z,a->z,1);
+    }
+    MPZ_DIV(a->z,a->z,b->z);
+    a=nlShort3_noinline(a);
+  }
+}
+
+number nlFarey(number nN, number nP, const coeffs r)
+{
+  mpz_t tmp; mpz_init(tmp);
+  mpz_t A,B,C,D,E,N,P;
+  if (SR_HDL(nN) & SR_INT) mpz_init_set_si(N,SR_TO_INT(nN));
+  else                     mpz_init_set(N,nN->z);
+  if (SR_HDL(nP) & SR_INT) mpz_init_set_si(P,SR_TO_INT(nP));
+  else                     mpz_init_set(P,nP->z);
+  assume(!mpz_isNeg(P));
+  if (mpz_isNeg(N))  mpz_add(N,N,P);
+  mpz_init_set_si(A,(long)0);
+  mpz_init_set_ui(B,(unsigned long)1);
+  mpz_init_set_si(C,(long)0);
+  mpz_init(D);
+  mpz_init_set(E,P);
+  number z=INT_TO_SR(0);
+  while(mpz_cmp_si(N,(long)0)!=0)
+  {
+    mpz_mul(tmp,N,N);
+    mpz_add(tmp,tmp,tmp);
+    if (mpz_cmp(tmp,P)<0)
+    {
+       if (mpz_isNeg(B))
+       {
+         mpz_neg(B,B);
+         mpz_neg(N,N);
+       }
+       // check for gcd(N,B)==1
+       mpz_gcd(tmp,N,B);
+       if (mpz_cmp_ui(tmp,1)==0)
+       {
+         // return N/B
+         z=ALLOC_RNUMBER();
+         #ifdef LDEBUG
+         z->debug=123456;
+         #endif
+         mpz_init_set(z->z,N);
+         mpz_init_set(z->n,B);
+         z->s = 0;
+         nlNormalize(z,r);
+       }
+       else
+       {
+         // return nN (the input) instead of "fail"
+         z=nlCopy(nN,r);
+       }
+       break;
+    }
+    //mpz_mod(D,E,N);
+    //mpz_div(tmp,E,N);
+    mpz_divmod(tmp,D,E,N);
+    mpz_mul(tmp,tmp,B);
+    mpz_sub(C,A,tmp);
+    mpz_set(E,N);
+    mpz_set(N,D);
+    mpz_set(A,B);
+    mpz_set(B,C);
+  }
+  mpz_clear(tmp);
+  mpz_clear(A);
+  mpz_clear(B);
+  mpz_clear(C);
+  mpz_clear(D);
+  mpz_clear(E);
+  mpz_clear(N);
+  mpz_clear(P);
+  return z;
+}
+
+number nlExtGcd(number a, number b, number *s, number *t, const coeffs)
+{
+  mpz_t aa,bb;
+  *s=ALLOC_RNUMBER();
+  mpz_init((*s)->z); (*s)->s=3;
+  (*t)=ALLOC_RNUMBER();
+  mpz_init((*t)->z); (*t)->s=3;
+  number g=ALLOC_RNUMBER();
+  mpz_init(g->z); g->s=3;
+  if (SR_HDL(a) & SR_INT)
+  {
+    mpz_init_set_si(aa,SR_TO_INT(a));
+  }
+  else
+  {
+    mpz_init_set(aa,a->z);
+  }
+  if (SR_HDL(b) & SR_INT)
+  {
+    mpz_init_set_si(bb,SR_TO_INT(b));
+  }
+  else
+  {
+    mpz_init_set(bb,b->z);
+  }
+  mpz_gcdext(g->z,(*s)->z,(*t)->z,aa,bb);
+  mpz_clear(aa);
+  mpz_clear(bb);
+  (*s)=nlShort3((*s));
+  (*t)=nlShort3((*t));
+  g=nlShort3(g);
+  return g;
+}
+
+void    nlCoeffWrite  (const coeffs r, BOOLEAN /*details*/)
+{
+  if (r->is_field)
+  PrintS("//   characteristic : 0\n");
+  else
+  PrintS("//   coeff. ring is : Integers\n");
+}
+
+number   nlChineseRemainderSym(number *x, number *q,int rl, BOOLEAN sym, const coeffs CF)
+// elemenst in the array are x[0..(rl-1)], q[0..(rl-1)]
+{
+  setCharacteristic( 0 ); // only in char 0
+  Off(SW_RATIONAL);
+  CFArray X(rl), Q(rl);
+  int i;
+  for(i=rl-1;i>=0;i--)
+  {
+    X[i]=CF->convSingNFactoryN(x[i],FALSE,CF); // may be larger MAX_INT
+    Q[i]=CF->convSingNFactoryN(q[i],FALSE,CF); // may be larger MAX_INT
+  }
+  CanonicalForm xnew,qnew;
+  chineseRemainder(X,Q,xnew,qnew);
+  number n=CF->convFactoryNSingN(xnew,CF);
+  if (sym)
+  {
+    number p=CF->convFactoryNSingN(qnew,CF);
+    number p2=nlIntDiv(p,nlInit(2, CF),CF);
+    if (nlGreater(n,p2,CF))
+    {
+       number n2=nlSub(n,p,CF);
+       nlDelete(&n,CF);
+       n=n2;
+    }
+    nlDelete(&p2,CF);
+    nlDelete(&p,CF);
+  }
+  nlNormalize(n,CF);
+  return n;
+}
+number   nlChineseRemainder(number *x, number *q,int rl, const coeffs C)
+{
+  return nlChineseRemainderSym(x,q,rl,TRUE,C);
+}
+
+static void nlClearContent(ICoeffsEnumerator& numberCollectionEnumerator, number& c, const coeffs cf)
+{
+  assume(cf != NULL);
+
+  numberCollectionEnumerator.Reset();
+
+  if( !numberCollectionEnumerator.MoveNext() ) // empty zero polynomial?
+  {
+    c = nlInit(1, cf);
+    return;
+  }
+
+  // all coeffs are given by integers!!!
+
+  // part 1, find a small candidate for gcd
+  number cand1,cand;
+  int s1,s;
+  s=2147483647; // max. int
+
+  const BOOLEAN lc_is_pos=nlGreaterZero(numberCollectionEnumerator.Current(),cf);
+
+  int normalcount = 0;
+  do
+  {
+    number& n = numberCollectionEnumerator.Current();
+    nlNormalize(n, cf); ++normalcount;
+    cand1 = n;
+
+    if (SR_HDL(cand1)&SR_INT) { cand=cand1; break; }
+    assume(cand1->s==3); // all coeffs should be integers // ==0?!! after printing
+    s1=mpz_size1(cand1->z);
+    if (s>s1)
+    {
+      cand=cand1;
+      s=s1;
+    }
+  } while (numberCollectionEnumerator.MoveNext() );
+
+//  assume( nlGreaterZero(cand,cf) ); // cand may be a negative integer!
+
+  cand=nlCopy(cand,cf);
+  // part 2: compute gcd(cand,all coeffs)
+
+  numberCollectionEnumerator.Reset();
+
+  while (numberCollectionEnumerator.MoveNext() )
+  {
+    number& n = numberCollectionEnumerator.Current();
+
+    if( (--normalcount) <= 0)
+      nlNormalize(n, cf);
+
+    nlInpGcd(cand, n, cf);
+    assume( nlGreaterZero(cand,cf) );
+
+    if(nlIsOne(cand,cf))
+    {
+      c = cand;
+
+      if(!lc_is_pos)
+      {
+        // make the leading coeff positive
+        c = nlNeg(c, cf);
+        numberCollectionEnumerator.Reset();
+
+        while (numberCollectionEnumerator.MoveNext() )
+        {
+          number& nn = numberCollectionEnumerator.Current();
+          nn = nlNeg(nn, cf);
+        }
+      }
+      return;
+    }
+  }
+
+  // part3: all coeffs = all coeffs / cand
+  if (!lc_is_pos)
+    cand = nlNeg(cand,cf);
+
+  c = cand;
+  numberCollectionEnumerator.Reset();
+
+  while (numberCollectionEnumerator.MoveNext() )
+  {
+    number& n = numberCollectionEnumerator.Current();
+    number t=nlIntDiv(n, cand, cf); // simple integer exact division, no ratios to remain
+    nlDelete(&n, cf);
+    n = t;
+  }
+}
+
+static void nlClearDenominators(ICoeffsEnumerator& numberCollectionEnumerator, number& c, const coeffs cf)
+{
+  assume(cf != NULL);
+
+  numberCollectionEnumerator.Reset();
+
+  if( !numberCollectionEnumerator.MoveNext() ) // empty zero polynomial?
+  {
+    c = nlInit(1, cf);
+//    assume( n_GreaterZero(c, cf) );
+    return;
+  }
+
+  // all coeffs are given by integers after returning from this routine
+
+  // part 1, collect product of all denominators /gcds
+  number cand;
+  cand=ALLOC_RNUMBER();
+#if defined(LDEBUG)
+  cand->debug=123456;
+#endif
+  cand->s=3;
+
+  int s=0;
+
+  const BOOLEAN lc_is_pos=nlGreaterZero(numberCollectionEnumerator.Current(),cf);
+
+  do
+  {
+    number& cand1 = numberCollectionEnumerator.Current();
+
+    if (!(SR_HDL(cand1)&SR_INT))
+    {
+      nlNormalize(cand1, cf);
+      if ((!(SR_HDL(cand1)&SR_INT)) // not a short int
+      && (cand1->s==1))             // and is a normalised rational
+      {
+        if (s==0) // first denom, we meet
+        {
+          mpz_init_set(cand->z, cand1->n); // cand->z = cand1->n
+          s=1;
+        }
+        else // we have already something
+        {
+          mpz_lcm(cand->z, cand->z, cand1->n);
+        }
+      }
+    }
+  }
+  while (numberCollectionEnumerator.MoveNext() );
+
+
+  if (s==0) // nothing to do, all coeffs are already integers
+  {
+//    mpz_clear(tmp);
+    FREE_RNUMBER(cand);
+    if (lc_is_pos)
+      c=nlInit(1,cf);
+    else
+    {
+      // make the leading coeff positive
+      c=nlInit(-1,cf);
+
+      // TODO: incorporate the following into the loop below?
+      numberCollectionEnumerator.Reset();
+      while (numberCollectionEnumerator.MoveNext() )
+      {
+        number& n = numberCollectionEnumerator.Current();
+        n = nlNeg(n, cf);
+      }
+    }
+//    assume( n_GreaterZero(c, cf) );
+    return;
+  }
+
+  cand = nlShort3(cand);
+
+  // part2: all coeffs = all coeffs * cand
+  // make the lead coeff positive
+  numberCollectionEnumerator.Reset();
+
+  if (!lc_is_pos)
+    cand = nlNeg(cand, cf);
+
+  c = cand;
+
+  while (numberCollectionEnumerator.MoveNext() )
+  {
+    number &n = numberCollectionEnumerator.Current();
+    nlInpMult(n, cand, cf);
+  }
+
+}
+
+char * nlCoeffName(const coeffs r)
+{
+  if (r->cfDiv==nlDiv) return (char*)"QQ";
+  else                 return (char*)"ZZ";
+}
+
+static char* nlCoeffString(const coeffs r)
+{
+  //return omStrDup(nlCoeffName(r));
+  if (r->cfDiv==nlDiv) return omStrDup("0");
+  else                 return omStrDup("integer");
+}
+
+#define SSI_BASE 16
+
+static void nlWriteFd(number n,FILE* f, const coeffs)
+{
+  if(SR_HDL(n) & SR_INT)
+  {
+    #if SIZEOF_LONG == 4
+    fprintf(f,"4 %ld ",SR_TO_INT(n));
+    #else
+    long nn=SR_TO_INT(n);
+    if ((nn<POW_2_28_32)&&(nn>= -POW_2_28_32))
+    {
+      int nnn=(int)nn;
+      fprintf(f,"4 %d ",nnn);
+    }
+    else
+    {
+      mpz_t tmp;
+      mpz_init_set_si(tmp,nn);
+      fputs("8 ",f);
+      mpz_out_str (f,SSI_BASE, tmp);
+      fputc(' ',f);
+      mpz_clear(tmp);
+    }
+    #endif
+  }
+  else if (n->s<2)
+  {
+    //gmp_fprintf(f,"%d %Zd %Zd ",n->s,n->z,n->n);
+    fprintf(f,"%d ",n->s+5);
+    mpz_out_str (f,SSI_BASE, n->z);
+    fputc(' ',f);
+    mpz_out_str (f,SSI_BASE, n->n);
+    fputc(' ',f);
+
+    //if (d->f_debug!=NULL) gmp_fprintf(d->f_debug,"number: s=%d gmp/gmp \"%Zd %Zd\" ",n->s,n->z,n->n);
+  }
+  else /*n->s==3*/
+  {
+    //gmp_fprintf(d->f_write,"3 %Zd ",n->z);
+    fputs("8 ",f);
+    mpz_out_str (f,SSI_BASE, n->z);
+    fputc(' ',f);
+
+    //if (d->f_debug!=NULL) gmp_fprintf(d->f_debug,"number: gmp \"%Zd\" ",n->z);
+  }
+}
+
+static number nlReadFd(s_buff f, const coeffs)
+{
+  int sub_type=-1;
+  sub_type=s_readint(f);
+  switch(sub_type)
+  {
+     case 0:
+     case 1:
+       {// read mpz_t, mpz_t
+         number n=nlRInit(0);
+         mpz_init(n->n);
+         s_readmpz(f,n->z);
+         s_readmpz(f,n->n);
+         n->s=sub_type;
+         return n;
+       }
+
+     case 3:
+       {// read mpz_t
+         number n=nlRInit(0);
+         s_readmpz(f,n->z);
+         n->s=3; /*sub_type*/
+         #if SIZEOF_LONG == 8
+         n=nlShort3(n);
+         #endif
+         return n;
+       }
+     case 4:
+       {
+         LONG dd=s_readlong(f);
+         //#if SIZEOF_LONG == 8
+         return INT_TO_SR(dd);
+         //#else
+         //return nlInit(dd,NULL);
+         //#endif
+       }
+     case 5:
+     case 6:
+       {// read raw mpz_t, mpz_t
+         number n=nlRInit(0);
+         mpz_init(n->n);
+         s_readmpz_base (f,n->z, SSI_BASE);
+         s_readmpz_base (f,n->n, SSI_BASE);
+         n->s=sub_type-5;
+         return n;
+       }
+     case 8:
+       {// read raw mpz_t
+         number n=nlRInit(0);
+         s_readmpz_base (f,n->z, SSI_BASE);
+         n->s=sub_type=3; /*subtype-5*/
+         #if SIZEOF_LONG == 8
+         n=nlShort3(n);
+         #endif
+         return n;
+       }
+
+     default: Werror("error in reading number: invalid subtype %d",sub_type);
+              return NULL;
+  }
+  return NULL;
+}
+BOOLEAN nlCoeffIsEqual(const coeffs r, n_coeffType n, void *p)
+{
+  /* test, if r is an instance of nInitCoeffs(n,parameter) */
+  /* if paramater is not needed */
+  if (n==r->type)
+  {
+    if ((p==NULL)&&(r->cfDiv==nlDiv)) return TRUE;
+    if ((p!=NULL)&&(r->cfDiv!=nlDiv)) return TRUE;
+  }
+  return FALSE;
+}
+
+static number nlLcm(number a,number b,const coeffs r)
+{
+  number g=nlGcd(a,b,r);
+  number n1=nlMult(a,b,r);
+  number n2=nlDiv(n1,g,r);
+  nlDelete(&g,r);
+  nlDelete(&n1,r);
+  return n2;
+}
+
+static number nlRandom(siRandProc p, number v2, number, const coeffs cf)
+{
+  number a=nlInit(p(),cf);
+  if (v2!=NULL)
+  {
+    number b=nlInit(p(),cf);
+    number c=nlDiv(a,b,cf);
+    nlDelete(&b,cf);
+    nlDelete(&a,cf);
+    a=c;
+  }
+  return a;
+}
+
+BOOLEAN nlInitChar(coeffs r, void*p)
+{
+  r->is_domain=TRUE;
+  r->rep=n_rep_gap_rat;
+
+  //const int ch = (int)(long)(p);
+
+  r->nCoeffIsEqual=nlCoeffIsEqual;
+  //r->cfKillChar = ndKillChar; /* dummy */
+  r->cfCoeffString=nlCoeffString;
+  r->cfCoeffName=nlCoeffName;
+
+  r->cfInitMPZ = nlInitMPZ;
+  r->cfMPZ  = nlMPZ;
+
+  r->cfMult  = nlMult;
+  r->cfSub   = nlSub;
+  r->cfAdd   = nlAdd;
+  if (p==NULL) /* Q */
+  {
+    r->is_field=TRUE;
+    r->cfDiv   = nlDiv;
+    //r->cfGcd  = ndGcd_dummy;
+    r->cfSubringGcd  = nlGcd;
+  }
+  else /* Z: coeffs_BIGINT */
+  {
+    r->is_field=FALSE;
+    r->cfDiv   = nlIntDiv;
+    r->cfIntMod= nlIntMod;
+    r->cfGcd  = nlGcd;
+    r->cfDivBy=nlDivBy;
+    r->cfDivComp = nlDivComp;
+    r->cfIsUnit = nlIsUnit;
+    r->cfGetUnit = nlGetUnit;
+    r->cfQuot1 = nlQuot1;
+    r->cfLcm = nlLcm;
+  }
+  r->cfExactDiv= nlExactDiv;
+  r->cfInit = nlInit;
+  r->cfSize  = nlSize;
+  r->cfInt  = nlInt;
+
+  r->cfChineseRemainder=nlChineseRemainderSym;
+  r->cfFarey=nlFarey;
+  r->cfInpNeg   = nlNeg;
+  r->cfInvers= nlInvers;
+  r->cfCopy  = nlCopy;
+  r->cfRePart = nlCopy;
+  //r->cfImPart = ndReturn0;
+  r->cfWriteLong = nlWrite;
+  r->cfRead = nlRead;
+  r->cfNormalize=nlNormalize;
+  r->cfGreater = nlGreater;
+  r->cfEqual = nlEqual;
+  r->cfIsZero = nlIsZero;
+  r->cfIsOne = nlIsOne;
+  r->cfIsMOne = nlIsMOne;
+  r->cfGreaterZero = nlGreaterZero;
+  r->cfPower = nlPower;
+  r->cfGetDenom = nlGetDenom;
+  r->cfGetNumerator = nlGetNumerator;
+  r->cfExtGcd = nlExtGcd; // only for ring stuff and Z
+  r->cfNormalizeHelper  = nlNormalizeHelper;
+  r->cfDelete= nlDelete;
+  r->cfSetMap = nlSetMap;
+  //r->cfName = ndName;
+  r->cfInpMult=nlInpMult;
+  r->cfInpAdd=nlInpAdd;
+  r->cfCoeffWrite=nlCoeffWrite;
+
+  r->cfClearContent = nlClearContent;
+  r->cfClearDenominators = nlClearDenominators;
+
+#ifdef LDEBUG
+  // debug stuff
+  r->cfDBTest=nlDBTest;
+#endif
+  r->convSingNFactoryN=nlConvSingNFactoryN;
+  r->convFactoryNSingN=nlConvFactoryNSingN;
+
+  r->cfRandom=nlRandom;
+
+  // io via ssi
+  r->cfWriteFd=nlWriteFd;
+  r->cfReadFd=nlReadFd;
+
+  // the variables: general stuff (required)
+  r->nNULL = INT_TO_SR(0);
+  //r->type = n_Q;
+  r->ch = 0;
+  r->has_simple_Alloc=FALSE;
+  r->has_simple_Inverse=FALSE;
+
+  // variables for this type of coeffs:
+  // (none)
+  return FALSE;
+}
+#if 0
+number nlMod(number a, number b)
+{
+  if (((SR_HDL(b)&SR_HDL(a))&SR_INT)
+  {
+    int bi=SR_TO_INT(b);
+    int ai=SR_TO_INT(a);
+    int bb=ABS(bi);
+    int c=ai%bb;
+    if (c<0)  c+=bb;
+    return (INT_TO_SR(c));
+  }
+  number al;
+  number bl;
+  if (SR_HDL(a))&SR_INT)
+    al=nlRInit(SR_TO_INT(a));
+  else
+    al=nlCopy(a);
+  if (SR_HDL(b))&SR_INT)
+    bl=nlRInit(SR_TO_INT(b));
+  else
+    bl=nlCopy(b);
+  number r=nlRInit(0);
+  mpz_mod(r->z,al->z,bl->z);
+  nlDelete(&al);
+  nlDelete(&bl);
+  if (mpz_size1(&r->z)<=MP_SMALL)
+  {
+    LONG ui=(int)mpz_get_si(&r->z);
+    if ((((ui<<3)>>3)==ui)
+    && (mpz_cmp_si(x->z,(long)ui)==0))
+    {
+      mpz_clear(&r->z);
+      FREE_RNUMBER(r); //  omFreeBin((void *)r, rnumber_bin);
+      r=INT_TO_SR(ui);
+    }
+  }
+  return r;
+}
+#endif
+#endif // not P_NUMBERS_H
+#endif // LONGRAT_CC
diff --git a/libpolys/coeffs/longrat.h b/libpolys/coeffs/longrat.h
new file mode 100644
index 0000000..9d2f538
--- /dev/null
+++ b/libpolys/coeffs/longrat.h
@@ -0,0 +1,121 @@
+#ifndef LONGRAT_H
+#define LONGRAT_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: computation with long rational numbers
+*/
+#include <misc/auxiliary.h>
+
+#include <coeffs/si_gmp.h>
+#include <coeffs/coeffs.h>
+
+struct snumber; typedef struct snumber  *number;
+
+/*-----------------------------------------------------------------*/
+/**
+**  'SR_INT' is the type of those integers small enough to fit into  29  bits.
+**  Therefor the value range of this small integers is: $-2^{28}...2^{28}-1$.
+**
+**  Small integers are represented by an immediate integer handle, containing
+**  the value instead of pointing  to  it,  which  has  the  following  form:
+**
+**      +-------+-------+-------+-------+- - - -+-------+-------+-------+
+**      | guard | sign  | bit   | bit   |       | bit   | tag   | tag   |
+**      | bit   | bit   | 27    | 26    |       | 0     | 0     | 1     |
+**      +-------+-------+-------+-------+- - - -+-------+-------+-------+
+**
+**  Immediate integers handles carry the tag 'SR_INT', i.e. the last bit is 1.
+**  This distuingishes immediate integers from other handles which  point  to
+**  structures aligned on 4 byte boundaries and therefor have last bit  zero.
+**  (The second bit is reserved as tag to allow extensions of  this  scheme.)
+**  Using immediates as pointers and dereferencing them gives address errors.
+**
+**  To aid overflow check the most significant two bits must always be equal,
+**  that is to say that the sign bit of immediate integers has a  guard  bit.
+**
+**  The macros 'INT_TO_SR' and 'SR_TO_INT' should be used to convert  between
+**  a small integer value and its representation as immediate integer handle.
+**
+**  Large integers and rationals are represented by z and n
+**  where n may be undefined (if s==3)
+**  NULL represents only deleted values
+*/
+
+struct snumber
+{
+  mpz_t z; //< Zaehler
+  mpz_t n; //< Nenner
+#if defined(LDEBUG)
+  int debug;
+#endif
+
+  /**
+   * parameter s in number:
+   * 0 (or FALSE): not normalised rational
+   * 1 (or TRUE):  normalised rational
+   * 3          :  integer with n==NULL
+   **/
+  BOOLEAN s; //< integer parameter
+};
+
+#define SR_HDL(A) ((long)(A))
+
+#define SR_INT    1L
+#define INT_TO_SR(INT)  ((number) (((long)INT << 2) + SR_INT))
+#define SR_TO_INT(SR)   (((long)SR) >> 2)
+
+#define MP_SMALL 1
+
+BOOLEAN nlInitChar(coeffs, void*);
+
+/// only used by slimgb (tgb.cc)
+static inline int nlQlogSize (number n, const coeffs r)
+{
+  assume( nCoeff_is_Q (r) );
+
+  long nl=n_Size(n,r);
+  if (nl==0L) return 0;
+  if (nl==1L)
+  {
+    long i = SR_TO_INT (n);
+    unsigned long v;
+    v = (i >= 0) ? i : -i;
+    int r = 0;
+
+    while(v >>= 1)
+    {
+      r++;
+    }
+    return r + 1;
+  }
+  //assume denominator is 0
+  number nn=(number) n;
+  return mpz_sizeinbase (nn->z, 2);
+}
+
+
+number nlModP(number q, const coeffs Q, const coeffs Zp);
+void   nlNormalize(number &x, const coeffs r);
+void   nlInpGcd(number &a, number b, const coeffs r);
+void   nlDelete(number *a, const coeffs r);
+
+
+/// create a rational i/j (implicitly) over Q
+/// NOTE: make sure to use correct Q in debug mode
+number   nlInit2 (int i, int j, const coeffs r);
+
+/// create a rational i/j (implicitly) over Q
+/// NOTE: make sure to use correct Q in debug mode
+number   nlInit2gmp (mpz_t i, mpz_t j, const coeffs r);
+
+// FIXME: TODO:  why only if HAVE_RINGS? bug?
+#  ifdef HAVE_RINGS
+void   nlGMP(number &i, number n, const coeffs r); // to be replaced with n_MPZ(number n, number &i,const coeffs r)???
+number nlMapGMP(number from, const coeffs src, const coeffs dst);
+#  endif
+
+#endif
+
+
diff --git a/libpolys/coeffs/longrat0.cc b/libpolys/coeffs/longrat0.cc
new file mode 100644
index 0000000..b7c6f94
--- /dev/null
+++ b/libpolys/coeffs/longrat0.cc
@@ -0,0 +1,152 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT -
+* IO for long rational numbers (Hubert Grassmann)
+*/
+
+#include <stdio.h>
+#include <string.h>
+
+#include <misc/auxiliary.h>
+#include <omalloc/omalloc.h>
+#include <reporter/reporter.h>
+
+#include "coeffs.h"
+#include "numbers.h"
+#include "longrat.h"
+
+/// Our Type!
+static const n_coeffType ID = n_Q;
+
+omBin rnumber_bin = omGetSpecBin(sizeof(snumber)); // TODO: move this into coeffs-struct (for Q)?!
+
+
+#define SR_HDL(A) ((long)(A))
+//#define SR_INT    1 // already in longrat.h
+//#define INT_TO_SR(INT)  ((number) (((long)INT << 2) + SR_INT))
+#define SR_TO_INT(SR)   (((long)SR) >> 2)
+
+
+/*2
+* extracts a long integer from s, returns the rest
+*/
+static const char * nlEatLong(char *s, mpz_ptr i)
+{
+  const char * start=s;
+
+  while (*s >= '0' && *s <= '9') s++;
+  if (*s=='\0')
+  {
+    mpz_set_str(i,start,10);
+  }
+  else
+  {
+    char c=*s;
+    *s='\0';
+    mpz_set_str(i,start,10);
+    *s=c;
+  }
+  return s;
+}
+
+/*2
+* extracts the number a from s, returns the rest
+*/
+const char * nlRead (const char *s, number *a, const coeffs r)
+{
+  if (*s<'0' || *s>'9')
+  {
+    *a = INT_TO_SR(1); /* nlInit(1) */
+    return s;
+  }
+  *a=(number)ALLOC_RNUMBER();
+  {
+    (*a)->s = 3;
+#if defined(LDEBUG)
+    (*a)->debug=123456;
+#endif
+    mpz_ptr z=(*a)->z;
+    mpz_ptr n=(*a)->n;
+    mpz_init(z);
+    s = nlEatLong((char *)s, z);
+    if (*s == '/')
+    {
+      mpz_init(n);
+      (*a)->s = 0;
+      s++;
+      s = nlEatLong((char *)s, n);
+      if (mpz_cmp_si(n,(long)0)==0)
+      {
+        WerrorS(nDivBy0);
+        mpz_clear(n);
+        (*a)->s = 3;
+      }
+      else if (mpz_cmp_si(n,(long)1)==0)
+      {
+        mpz_clear(n);
+        (*a)->s=3;
+      }
+    }
+    if (mpz_cmp_si(z,(long)0)==0)
+    {
+      mpz_clear(z);
+      FREE_RNUMBER(*a);
+      *a=INT_TO_SR(0);
+    }
+    else
+    if ((*a)->s==3)
+    {
+      number nlShort3_noinline(number x);
+      *a=nlShort3_noinline(*a);
+    }
+    else
+    {
+      number aa=*a;
+      nlNormalize(aa,r); // FIXME? TODO? // extern void     nlNormalize(number &x, const coeffs r);
+      *a=aa;
+    }
+  }
+  return s;
+}
+
+/*2
+* write a rational number
+*/
+void nlWrite (number &a, const coeffs r)
+{
+  char *s,*z;
+  if (SR_HDL(a) & SR_INT)
+  {
+    StringAppend("%ld",SR_TO_INT(a));
+  }
+  else if (a==NULL)
+  {
+    StringAppendS("o");
+  }
+  else
+  {
+    if (a->s==0)
+    {
+      nlNormalize(a,r); // FIXME? TODO? // extern void     nlNormalize(number &x, const coeffs r);
+      nlWrite(a,r);
+      return;
+    }
+    int l=mpz_sizeinbase(a->z,10);
+    if (a->s<2) l=si_max(l,(int)mpz_sizeinbase(a->n,10));
+    l+=2;
+    s=(char*)omAlloc(l);
+    z=mpz_get_str(s,10,a->z);
+    StringAppendS(z);
+    if (a->s!=3)
+    {
+      StringAppendS("/");
+      z=mpz_get_str(s,10,a->n);
+      StringAppendS(z);
+    }
+    omFreeSize((void *)s,l);
+  }
+}
+
+
diff --git a/libpolys/coeffs/modulop.cc b/libpolys/coeffs/modulop.cc
new file mode 100644
index 0000000..a3efe15
--- /dev/null
+++ b/libpolys/coeffs/modulop.cc
@@ -0,0 +1,930 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: numbers modulo p (<=32003)
+*/
+
+#include <misc/auxiliary.h>
+#include <omalloc/omalloc.h>
+
+#include <factory/factory.h>
+
+#include <misc/mylimits.h>
+#include <misc/sirandom.h>
+
+#include <reporter/reporter.h>
+
+#include <coeffs/coeffs.h>
+#include <coeffs/numbers.h>
+#include <coeffs/mpr_complex.h>
+
+#include "longrat.h"
+#include "modulop.h"
+
+#include <string.h>
+
+/// Our Type!
+static const n_coeffType ID = n_Zp;
+
+BOOLEAN npGreaterZero (number k, const coeffs r);
+number  npMult        (number a, number b, const coeffs r);
+number  npInit        (long i, const coeffs r);
+int     npInt         (number &n, const coeffs r);
+number  npAdd         (number a, number b,const coeffs r);
+number  npSub         (number a, number b,const coeffs r);
+void    npPower       (number a, int i, number * result,const coeffs r);
+BOOLEAN npIsZero      (number a,const coeffs r);
+BOOLEAN npIsOne       (number a,const coeffs r);
+BOOLEAN npIsMOne       (number a,const coeffs r);
+number  npDiv         (number a, number b,const coeffs r);
+number  npNeg         (number c,const coeffs r);
+number  npInvers      (number c,const coeffs r);
+BOOLEAN npGreater     (number a, number b,const coeffs r);
+BOOLEAN npEqual       (number a, number b,const coeffs r);
+void    npWrite       (number &a, const coeffs r);
+void    npCoeffWrite  (const coeffs r, BOOLEAN details);
+const char *  npRead  (const char *s, number *a,const coeffs r);
+#ifdef LDEBUG
+BOOLEAN npDBTest      (number a, const char *f, const int l, const coeffs r);
+#define npTest(A,r)     npDBTest(A,__FILE__,__LINE__, r)
+#else
+#define npTest(A,r)     (0)
+#endif
+
+//int     npGetChar();
+
+nMapFunc npSetMap(const coeffs src, const coeffs dst);
+number  npMapP(number from, const coeffs src, const coeffs r);
+
+// extern int npGen; // obsolete
+
+// int npGen=0;
+
+/*-------specials for spolys, do NOT use otherwise--------------------------*/
+/* for npMultM, npSubM, npNegM, npEqualM : */
+#ifdef HAVE_DIV_MOD
+extern unsigned short *npInvTable;
+#else
+#ifndef HAVE_MULT_MOD
+extern long npPminus1M;
+extern unsigned short *npExpTable;
+extern unsigned short *npLogTable;
+#endif
+#endif
+
+#ifdef NV_OPS
+#pragma GCC diagnostic ignored "-Wlong-long"
+static inline number nvMultM(number a, number b, const coeffs r)
+{
+  assume( getCoeffType(r) == ID );
+
+#if SIZEOF_LONG == 4
+#define ULONG64 (unsigned long long)(unsigned long)
+#else
+#define ULONG64 (unsigned long)
+#endif
+  return (number)
+      (unsigned long)((ULONG64 a)*(ULONG64 b) % (ULONG64 r->ch));
+}
+number  nvMult        (number a, number b, const coeffs r);
+number  nvDiv         (number a, number b, const coeffs r);
+number  nvInvers      (number c, const coeffs r);
+//void    nvPower       (number a, int i, number * result, const coeffs r);
+#endif
+
+
+
+
+BOOLEAN npGreaterZero (number k, const coeffs r)
+{
+  n_Test(k, r);
+
+  int h = (int)((long) k);
+  return ((int)h !=0) && (h <= (r->ch>>1));
+}
+
+//unsigned long npMultMod(unsigned long a, unsigned long b, int npPrimeM)
+//{
+//  unsigned long c = a*b;
+//  c = c % npPrimeM;
+//  assume(c == (unsigned long) npMultM((number) a, (number) b, npPrimeM));
+//  return c;
+//}
+
+number npMult (number a,number b, const coeffs r)
+{
+  n_Test(a, r);
+  n_Test(b, r);
+
+  if (((long)a == 0) || ((long)b == 0))
+    return (number)0;
+  number c = npMultM(a,b, r);
+  n_Test(c, r);
+  return c;
+}
+
+/*2
+* create a number from int
+*/
+number npInit (long i, const coeffs r)
+{
+  long ii=i % (long)r->ch;
+  if (ii <  0L)                         ii += (long)r->ch;
+
+  number c = (number)ii;
+  n_Test(c, r);
+  return c;
+
+}
+
+
+/*2
+ * convert a number to an int in (-p/2 .. p/2]
+ */
+int npInt(number &n, const coeffs r)
+{
+  n_Test(n, r);
+
+  if ((long)n > (((long)r->ch) >>1)) return (int)((long)n -((long)r->ch));
+  else                               return (int)((long)n);
+}
+
+number npAdd (number a, number b, const coeffs r)
+{
+  n_Test(a, r);
+  n_Test(b, r);
+
+  number c = npAddM(a,b, r);
+
+  n_Test(c, r);
+
+  return c;
+}
+
+number npSub (number a, number b, const coeffs r)
+{
+  n_Test(a, r);
+  n_Test(b, r);
+
+  number c = npSubM(a,b,r);
+
+  n_Test(c, r);
+
+  return c;
+}
+
+BOOLEAN npIsZero (number  a, const coeffs r)
+{
+  n_Test(a, r);
+
+  return 0 == (long)a;
+}
+
+BOOLEAN npIsOne (number a, const coeffs r)
+{
+  n_Test(a, r);
+
+  return 1 == (long)a;
+}
+
+BOOLEAN npIsMOne (number a, const coeffs r)
+{
+  n_Test(a, r);
+
+  return ((r->npPminus1M == (long)a)&&((long)1!=(long)a));
+}
+
+#ifdef HAVE_DIV_MOD
+
+#ifdef USE_NTL_XGCD
+
+//ifdef HAVE_NTL // in ntl.a
+//extern void XGCD(long& d, long& s, long& t, long a, long b);
+#include <NTL/ZZ.h>
+#ifdef NTL_CLIENT
+NTL_CLIENT
+#endif
+
+#endif
+
+long InvMod(long a, const coeffs R)
+{
+   long d, s, t;
+
+#ifdef USE_NTL_XGCD
+   XGCD(d, s, t, a, R->ch);
+   assume (d == 1);
+#else
+   long  u, v, u0, v0, u1, v1, u2, v2, q, r;
+
+   assume(a>0);
+   u1=1; u2=0;
+   u = a; v = R->ch;
+
+   while (v != 0)
+   {
+      q = u / v;
+      r = u % v;
+      u = v;
+      v = r;
+      u0 = u2;
+      u2 = u1 - q*u2;
+      u1 = u0;
+   }
+
+   assume(u==1);
+   s = u1;
+#endif
+   if (s < 0)
+      return s + R->ch;
+   else
+      return s;
+}
+#endif
+
+inline number npInversM (number c, const coeffs r)
+{
+  n_Test(c, r);
+#ifndef HAVE_DIV_MOD
+  number d = (number)(long)r->npExpTable[r->npPminus1M - r->npLogTable[(long)c]];
+#else
+  long inv=(long)r->npInvTable[(long)c];
+  if (inv==0)
+  {
+    inv=InvMod((long)c,r);
+    r->npInvTable[(long)c]=inv;
+  }
+  number d = (number)inv;
+#endif
+  n_Test(d, r);
+  return d;
+
+}
+
+number npDiv (number a,number b, const coeffs r)
+{
+  n_Test(a, r);
+  n_Test(b, r);
+
+//#ifdef NV_OPS
+//  if (r->ch>NV_MAX_PRIME)
+//    return nvDiv(a,b);
+//#endif
+  if ((long)a==0)
+    return (number)0;
+  number d;
+
+#ifndef HAVE_DIV_MOD
+  if ((long)b==0)
+  {
+    WerrorS(nDivBy0);
+    return (number)0;
+  }
+
+  int s = r->npLogTable[(long)a] - r->npLogTable[(long)b];
+  if (s < 0)
+    s += r->npPminus1M;
+  d = (number)(long)r->npExpTable[s];
+#else
+  number inv=npInversM(b,r);
+  d = npMultM(a,inv,r);
+#endif
+
+  n_Test(d, r);
+  return d;
+
+}
+number  npInvers (number c, const coeffs r)
+{
+  n_Test(c, r);
+
+  if ((long)c==0)
+  {
+    WerrorS("1/0");
+    return (number)0;
+  }
+  number d = npInversM(c,r);
+
+  n_Test(d, r);
+  return d;
+
+}
+
+number npNeg (number c, const coeffs r)
+{
+  n_Test(c, r);
+
+  if ((long)c==0) return c;
+
+#if 0
+  number d = npNegM(c,r);
+  n_Test(d, r);
+  return d;
+#else
+  c = npNegM(c,r);
+  n_Test(c, r);
+  return c;
+#endif
+}
+
+BOOLEAN npGreater (number a,number b, const coeffs r)
+{
+  n_Test(a, r);
+  n_Test(b, r);
+
+  //return (long)a != (long)b;
+  return (long)a > (long)b;
+}
+
+BOOLEAN npEqual (number a,number b, const coeffs r)
+{
+  n_Test(a, r);
+  n_Test(b, r);
+
+//  return (long)a == (long)b;
+
+  return npEqualM(a,b,r);
+}
+
+void npWrite (number &a, const coeffs r)
+{
+  n_Test(a, r);
+
+  if ((long)a>(((long)r->ch) >>1)) StringAppend("-%d",(int)(((long)r->ch)-((long)a)));
+  else                             StringAppend("%d",(int)((long)a));
+}
+
+#if 0
+void npPower (number a, int i, number * result, const coeffs r)
+{
+  n_Test(a, r);
+
+  if (i==0)
+  {
+    //npInit(1,result);
+    *(long *)result = 1;
+  }
+  else if (i==1)
+  {
+    *result = a;
+  }
+  else
+  {
+    npPower(a,i-1,result,r);
+    *result = npMultM(a,*result,r);
+  }
+}
+#endif
+
+static const char* npEati(const char *s, int *i, const coeffs r)
+{
+
+  if (((*s) >= '0') && ((*s) <= '9'))
+  {
+    unsigned long ii=0L;
+    do
+    {
+      ii *= 10;
+      ii += *s++ - '0';
+      if (ii >= (MAX_INT_VAL / 10)) ii = ii % r->ch;
+    }
+    while (((*s) >= '0') && ((*s) <= '9'));
+    if (ii >= (unsigned long)r->ch) ii = ii % r->ch;
+    *i=(int)ii;
+  }
+  else (*i) = 1;
+  return s;
+}
+
+const char * npRead (const char *s, number *a, const coeffs r)
+{
+  int z;
+  int n=1;
+
+  s = npEati(s, &z, r);
+  if ((*s) == '/')
+  {
+    s++;
+    s = npEati(s, &n, r);
+  }
+  if (n == 1)
+    *a = (number)(long)z;
+  else
+  {
+    if ((z==0)&&(n==0)) WerrorS(nDivBy0);
+    else
+    {
+#ifdef NV_OPS
+      if (r->ch>NV_MAX_PRIME)
+        *a = nvDiv((number)(long)z,(number)(long)n,r);
+      else
+#endif
+        *a = npDiv((number)(long)z,(number)(long)n,r);
+    }
+  }
+  n_Test(*a, r);
+  return s;
+}
+
+/*2
+* set the charcteristic (allocate and init tables)
+*/
+
+void npKillChar(coeffs r)
+{
+  #ifdef HAVE_DIV_MOD
+  if (r->npInvTable!=NULL)
+  omFreeSize( (void *)r->npInvTable, r->ch*sizeof(unsigned short) );
+  r->npInvTable=NULL;
+  #else
+  if (r->npExpTable!=NULL)
+  {
+    omFreeSize( (void *)r->npExpTable, r->ch*sizeof(unsigned short) );
+    omFreeSize( (void *)r->npLogTable, r->ch*sizeof(unsigned short) );
+    r->npExpTable=NULL; r->npLogTable=NULL;
+  }
+  #endif
+}
+
+static BOOLEAN npCoeffsEqual(const coeffs r, n_coeffType n, void * parameter)
+{
+  /* test, if r is an instance of nInitCoeffs(n,parameter) */
+  return (n==n_Zp) && (r->ch==(int)(long)parameter);
+}
+CanonicalForm npConvSingNFactoryN( number n, BOOLEAN setChar, const coeffs r )
+{
+  if (setChar) setCharacteristic( r->ch );
+  CanonicalForm term(npInt( n,r ));
+  return term;
+}
+
+number npConvFactoryNSingN( const CanonicalForm n, const coeffs r)
+{
+  if (n.isImm())
+  {
+    return npInit(n.intval(),r);
+  }
+  else
+  {
+    assume(0);
+    return NULL;
+  }
+}
+
+static char* npCoeffString(const coeffs r)
+{
+  char *s=(char*)omAlloc(11);
+  snprintf(s,11,"%d",r->ch);
+  return s;
+}
+
+static void npWriteFd(number n, FILE* f, const coeffs r)
+{
+  fprintf(f,"%d ",(int)(long)n);
+}
+
+static number npReadFd(s_buff f, const coeffs r)
+{
+  // read int
+  int dd;
+  dd=s_readint(f);
+  return (number)(long)dd;
+}
+
+static number npRandom(siRandProc p, number, number, const coeffs cf)
+{
+  return npInit(p(),cf);
+}
+
+BOOLEAN npInitChar(coeffs r, void* p)
+{
+  assume( getCoeffType(r) == ID );
+  const int c = (int) (long) p;
+
+  assume( c > 0 );
+
+  int i, w;
+
+  r->is_field=TRUE;
+  r->is_domain=TRUE;
+  r->rep=n_rep_int;
+
+  r->ch = c;
+  r->npPminus1M = c /*r->ch*/ - 1;
+
+  //r->cfInitChar=npInitChar;
+  r->cfKillChar=npKillChar;
+  r->nCoeffIsEqual=npCoeffsEqual;
+  r->cfCoeffString=npCoeffString;
+
+  r->cfMult  = npMult;
+  r->cfSub   = npSub;
+  r->cfAdd   = npAdd;
+  r->cfDiv   = npDiv;
+  r->cfInit = npInit;
+  //r->cfSize  = ndSize;
+  r->cfInt  = npInt;
+  #ifdef HAVE_RINGS
+  //r->cfDivComp = NULL; // only for ring stuff
+  //r->cfIsUnit = NULL; // only for ring stuff
+  //r->cfGetUnit = NULL; // only for ring stuff
+  //r->cfExtGcd = NULL; // only for ring stuff
+  // r->cfDivBy = NULL; // only for ring stuff
+  #endif
+  r->cfInpNeg   = npNeg;
+  r->cfInvers= npInvers;
+  //r->cfCopy  = ndCopy;
+  //r->cfRePart = ndCopy;
+  //r->cfImPart = ndReturn0;
+  r->cfWriteLong = npWrite;
+  r->cfRead = npRead;
+  //r->cfNormalize=ndNormalize;
+  r->cfGreater = npGreater;
+  r->cfEqual = npEqual;
+  r->cfIsZero = npIsZero;
+  r->cfIsOne = npIsOne;
+  r->cfIsMOne = npIsMOne;
+  r->cfGreaterZero = npGreaterZero;
+  //r->cfPower = npPower;
+  //r->cfGetDenom = ndGetDenom;
+  //r->cfGetNumerator = ndGetNumerator;
+  //r->cfGcd  = ndGcd;
+  //r->cfLcm  = ndGcd;
+  //r->cfDelete= ndDelete;
+  r->cfSetMap = npSetMap;
+  //r->cfName = ndName;
+  //r->cfInpMult=ndInpMult;
+#ifdef NV_OPS
+  if (c>NV_MAX_PRIME)
+  {
+    r->cfMult  = nvMult;
+    r->cfDiv   = nvDiv;
+    r->cfExactDiv= nvDiv;
+    r->cfInvers= nvInvers;
+    //r->cfPower= nvPower;
+  }
+#endif
+  r->cfCoeffWrite=npCoeffWrite;
+#ifdef LDEBUG
+  // debug stuff
+  r->cfDBTest=npDBTest;
+#endif
+
+  r->convSingNFactoryN=npConvSingNFactoryN;
+  r->convFactoryNSingN=npConvFactoryNSingN;
+
+  r->cfRandom=npRandom;
+
+  // io via ssi
+  r->cfWriteFd=npWriteFd;
+  r->cfReadFd=npReadFd;
+
+  // the variables:
+  r->nNULL = (number)0;
+  r->type = n_Zp;
+  r->ch = c;
+  r->has_simple_Alloc=TRUE;
+  r->has_simple_Inverse=TRUE;
+
+  // the tables
+#ifdef NV_OPS
+  if (r->ch <=NV_MAX_PRIME)
+#endif
+  {
+#if !defined(HAVE_DIV_MOD) || !defined(HAVE_MULT_MOD)
+    r->npExpTable=(unsigned short *)omAlloc( r->ch*sizeof(unsigned short) );
+    r->npLogTable=(unsigned short *)omAlloc( r->ch*sizeof(unsigned short) );
+    r->npExpTable[0] = 1;
+    r->npLogTable[0] = 0;
+    if (r->ch > 2)
+    {
+      w = 1;
+      loop
+      {
+        r->npLogTable[1] = 0;
+        w++;
+        i = 0;
+        loop
+        {
+          i++;
+          r->npExpTable[i] =(int)(((long)w * (long)r->npExpTable[i-1]) % r->ch);
+          r->npLogTable[r->npExpTable[i]] = i;
+          if /*(i == r->ch - 1 ) ||*/ (/*(*/ r->npExpTable[i] == 1 /*)*/)
+            break;
+        }
+        if (i == r->ch - 1)
+          break;
+      }
+    }
+    else
+    {
+      r->npExpTable[1] = 1;
+      r->npLogTable[1] = 0;
+    }
+#endif
+#ifdef HAVE_DIV_MOD
+    r->npInvTable=(unsigned short*)omAlloc0( r->ch*sizeof(unsigned short) );
+#endif
+  }
+  return FALSE;
+}
+
+#ifdef LDEBUG
+BOOLEAN npDBTest (number a, const char *f, const int l, const coeffs r)
+{
+  if (((long)a<0) || ((long)a>r->ch))
+  {
+    Print("wrong mod p number %ld at %s,%d\n",(long)a,f,l);
+    return FALSE;
+  }
+  return TRUE;
+}
+#endif
+
+number npMapP(number from, const coeffs src, const coeffs dst_r)
+{
+  long i = (long)from;
+  if (i>src->ch/2)
+  {
+    i-=src->ch;
+    while (i < 0) i+=dst_r->ch;
+  }
+  i%=dst_r->ch;
+  return (number)i;
+}
+
+static number npMapLongR(number from, const coeffs /*src*/, const coeffs dst_r)
+{
+  gmp_float *ff=(gmp_float*)from;
+  mpf_t *f=ff->_mpfp();
+  number res;
+  mpz_ptr dest,ndest;
+  int size,i;
+  int e,al,bl;
+  long iz;
+  mp_ptr qp,dd,nn;
+
+  size = (*f)[0]._mp_size;
+  if (size == 0)
+    return npInit(0,dst_r);
+  if(size<0)
+    size = -size;
+
+  qp = (*f)[0]._mp_d;
+  while(qp[0]==0)
+  {
+    qp++;
+    size--;
+  }
+
+  if(dst_r->ch>2)
+    e=(*f)[0]._mp_exp-size;
+  else
+    e=0;
+  res = ALLOC_RNUMBER();
+#if defined(LDEBUG)
+  res->debug=123456;
+#endif
+  dest = res->z;
+
+  long in=0;
+  if (e<0)
+  {
+    al = dest->_mp_size = size;
+    if (al<2) al = 2;
+    dd = (mp_ptr)omAlloc(sizeof(mp_limb_t)*al);
+    for (i=0;i<size;i++) dd[i] = qp[i];
+    bl = 1-e;
+    nn = (mp_ptr)omAlloc(sizeof(mp_limb_t)*bl);
+    nn[bl-1] = 1;
+    for (i=bl-2;i>=0;i--) nn[i] = 0;
+    ndest = res->n;
+    ndest->_mp_d = nn;
+    ndest->_mp_alloc = ndest->_mp_size = bl;
+    res->s = 0;
+    in=mpz_fdiv_ui(ndest,dst_r->ch);
+    mpz_clear(ndest);
+  }
+  else
+  {
+    al = dest->_mp_size = size+e;
+    if (al<2) al = 2;
+    dd = (mp_ptr)omAlloc(sizeof(mp_limb_t)*al);
+    for (i=0;i<size;i++) dd[i+e] = qp[i];
+    for (i=0;i<e;i++) dd[i] = 0;
+    res->s = 3;
+  }
+
+  dest->_mp_d = dd;
+  dest->_mp_alloc = al;
+  iz=mpz_fdiv_ui(dest,dst_r->ch);
+  mpz_clear(dest);
+  if(res->s==0)
+    iz=(long)npDiv((number)iz,(number)in,dst_r);
+  FREE_RNUMBER(res); // Q!?
+  return (number)iz;
+}
+
+#ifdef HAVE_RINGS
+/*2
+* convert from a GMP integer
+*/
+number npMapGMP(number from, const coeffs /*src*/, const coeffs dst)
+{
+  mpz_ptr erg = (mpz_ptr) omAlloc(sizeof(mpz_t)); // evtl. spaeter mit bin
+  mpz_init(erg);
+
+  mpz_mod_ui(erg, (mpz_ptr) from, dst->ch);
+  number r = (number) mpz_get_si(erg);
+
+  mpz_clear(erg);
+  omFree((void *) erg);
+  return (number) r;
+}
+
+number npMapZ(number from, const coeffs src, const coeffs dst)
+{
+  if (SR_HDL(from) & SR_INT)
+  {
+    long f_i=SR_TO_INT(from);
+    return npInit(f_i,dst);
+  }
+  return npMapGMP(from,src,dst);
+}
+
+/*2
+* convert from an machine long
+*/
+number npMapMachineInt(number from, const coeffs /*src*/,const coeffs dst)
+{
+  long i = (long) (((unsigned long) from) % dst->ch);
+  return (number) i;
+}
+#endif
+
+number npMapCanonicalForm (number a, const coeffs /*src*/, const coeffs dst)
+{
+  setCharacteristic (dst ->ch);
+  CanonicalForm f= CanonicalForm ((InternalCF*)(a));
+  return (number) (f.intval());
+}
+
+nMapFunc npSetMap(const coeffs src, const coeffs dst)
+{
+#ifdef HAVE_RINGS
+  if ((src->rep==n_rep_int) && nCoeff_is_Ring_2toM(src))
+  {
+    return npMapMachineInt;
+  }
+  if (src->rep==n_rep_gmp) //nCoeff_is_Ring_Z(src) || nCoeff_is_Ring_PtoM(src) || nCoeff_is_Ring_ModN(src))
+  {
+    return npMapGMP;
+  }
+  if (src->rep==n_rep_gap_gmp) //nCoeff_is_Ring_Z(src)
+  {
+    return npMapZ;
+  }
+#endif
+  if (src->rep==n_rep_gap_rat)  /* Q, Z */
+  {
+    return nlModP; // npMap0; // FIXME? TODO? // extern number nlModP(number q, const coeffs Q, const coeffs Zp); // Map q \in QQ \to Zp // FIXME!
+  }
+  if ((src->rep==n_rep_int) &&  nCoeff_is_Zp(src) )
+  {
+    if (n_GetChar(src) == n_GetChar(dst))
+    {
+      return ndCopyMap;
+    }
+    else
+    {
+      return npMapP;
+    }
+  }
+  if ((src->rep==n_rep_gmp_float) && nCoeff_is_long_R(src))
+  {
+    return npMapLongR;
+  }
+  if (nCoeff_is_CF (src))
+  {
+    return npMapCanonicalForm;
+  }
+  return NULL;      /* default */
+}
+
+// -----------------------------------------------------------
+//  operation for very large primes (32003< p < 2^31-1)
+// ----------------------------------------------------------
+#ifdef NV_OPS
+
+number nvMult (number a,number b, const coeffs r)
+{
+  //if (((long)a == 0) || ((long)b == 0))
+  //  return (number)0;
+  //else
+    return nvMultM(a,b,r);
+}
+
+void   nvInpMult(number &a, number b, const coeffs r)
+{
+  number n=nvMultM(a,b,r);
+  a=n;
+}
+
+
+inline long nvInvMod(long a, const coeffs R)
+{
+#ifdef HAVE_DIV_MOD
+  return InvMod(a, R);
+#else
+/// TODO: use "long InvMod(long a, const coeffs R)"?!
+
+   long  s;
+
+   long  u, u0, u1, u2, q, r; // v0, v1, v2,
+
+   u1=1; // v1=0;
+   u2=0; // v2=1;
+   u = a;
+
+   long v = R->ch;
+
+   while (v != 0)
+   {
+      q = u / v;
+      r = u % v;
+      u = v;
+      v = r;
+      u0 = u2;
+//      v0 = v2;
+      u2 = u1 - q*u2;
+//      v2 = v1 - q*v2;
+      u1 = u0;
+//      v1 = v0;
+   }
+
+   s = u1;
+   //t = v1;
+   if (s < 0)
+      return s + R->ch;
+   else
+     return s;
+#endif
+}
+
+inline number nvInversM (number c, const coeffs r)
+{
+  long inv=nvInvMod((long)c,r);
+  return (number)inv;
+}
+
+number nvDiv (number a,number b, const coeffs r)
+{
+  if ((long)a==0)
+    return (number)0;
+  else if ((long)b==0)
+  {
+    WerrorS(nDivBy0);
+    return (number)0;
+  }
+  else
+  {
+    number inv=nvInversM(b,r);
+    return nvMultM(a,inv,r);
+  }
+}
+number  nvInvers (number c, const coeffs r)
+{
+  if ((long)c==0)
+  {
+    WerrorS(nDivBy0);
+    return (number)0;
+  }
+  return nvInversM(c,r);
+}
+#if 0
+void nvPower (number a, int i, number * result, const coeffs r)
+{
+  if (i==0)
+  {
+    //npInit(1,result);
+    *(long *)result = 1;
+  }
+  else if (i==1)
+  {
+    *result = a;
+  }
+  else
+  {
+    nvPower(a,i-1,result,r);
+    *result = nvMultM(a,*result,r);
+  }
+}
+#endif
+#endif
+
+void    npCoeffWrite  (const coeffs r, BOOLEAN /*details*/)
+{
+  Print("//   characteristic : %d\n",r->ch);
+}
+
diff --git a/libpolys/coeffs/modulop.h b/libpolys/coeffs/modulop.h
new file mode 100644
index 0000000..ced5275
--- /dev/null
+++ b/libpolys/coeffs/modulop.h
@@ -0,0 +1,135 @@
+#ifndef MODULOP_H
+#define MODULOP_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: numbers modulo p (<=32003)
+*/
+#include <misc/auxiliary.h>
+
+// defines are in struct.h
+// define if a*b is with mod instead of tables
+//#define HAVE_MULT_MOD
+// define if a/b is with mod instead of tables
+//#define HAVE_DIV_MOD
+// define if an if should be used
+//#define HAVE_GENERIC_ADD
+
+// enable large primes (32003 < p < 2^31-)
+#define NV_OPS
+#define NV_MAX_PRIME 32003
+
+struct n_Procs_s; typedef struct  n_Procs_s  *coeffs;
+struct snumber; typedef struct snumber *   number;
+
+BOOLEAN npInitChar(coeffs r, void* p);
+
+// inline number npMultM(number a, number b, int npPrimeM)
+// // return (a*b)%n
+// {
+//    double ab;
+//    long q, res;
+//
+//    ab = ((double) ((int)a)) * ((double) ((int)b));
+//    q  = (long) (ab/((double) npPrimeM));  // q could be off by (+/-) 1
+//    res = (long) (ab - ((double) q)*((double) npPrimeM));
+//    res += (res >> 31) & npPrimeM;
+//    res -= npPrimeM;
+//    res += (res >> 31) & npPrimeM;
+//    return (number)res;
+// }
+#ifdef HAVE_MULT_MOD
+static inline number npMultM(number a, number b, const coeffs r)
+{
+  return (number)
+    ((((unsigned long) a)*((unsigned long) b)) % ((unsigned long) r->ch));
+}
+#else
+static inline number npMultM(number a, number b, const coeffs r)
+{
+  long x = (long)r->npLogTable[(long)a]+ r->npLogTable[(long)b];
+  return (number)(long)r->npExpTable[x<r->npPminus1M ? x : x- r->npPminus1M];
+}
+#endif
+
+#if 0
+inline number npAddAsm(number a, number b, int m)
+{
+  number r;
+    asm ("addl %2, %1; cmpl %3, %1; jb 0f; subl %3, %1; 0:"
+         : "=&r" (r)
+         : "%0" (a), "g" (b), "g" (m)
+         : "cc");
+  return r;
+}
+inline number npSubAsm(number a, number b, int m)
+{
+  number r;
+  asm ("subl %2, %1; jnc 0f; addl %3, %1; 0:"
+        : "=&r" (r)
+        : "%0" (a), "g" (b), "g" (m)
+        : "cc");
+  return r;
+}
+#endif
+#ifdef HAVE_GENERIC_ADD
+static inline number npAddM(number a, number b, const coeffs r)
+{
+  unsigned long R = (unsigned long)a + (unsigned long)b;
+  return (number)(R >= r->ch ? R - r->ch : R);
+}
+static inline number npSubM(number a, number b, const coeffs r)
+{
+  return (number)((long)a<(long)b ?
+                       r->ch-(long)b+(long)a : (long)a-(long)b);
+}
+#else
+static inline number npAddM(number a, number b, const coeffs r)
+{
+   unsigned long res = (long)((unsigned long)a + (unsigned long)b);
+   res -= r->ch;
+#if SIZEOF_LONG == 8
+   res += ((long)res >> 63) & r->ch;
+#else
+   res += ((long)res >> 31) & r->ch;
+#endif
+   return (number)res;
+}
+static inline number npSubM(number a, number b, const coeffs r)
+{
+   long res = ((long)a - (long)b);
+#if SIZEOF_LONG == 8
+   res += (res >> 63) & r->ch;
+#else
+   res += (res >> 31) & r->ch;
+#endif
+   return (number)res;
+}
+#endif
+
+static inline number npNegM(number a, const coeffs r)
+{
+  return (number)((long)(r->ch)-(long)(a));
+}
+
+static inline BOOLEAN npIsZeroM (number  a, const coeffs)
+{
+  return 0 == (long)a;
+}
+
+// inline number npMultM(number a, number b, int npPrimeM)
+// {
+//   return (number)(((long)a*(long)b) % npPrimeM);
+// }
+
+// The folloing is reused inside gnumpc.cc, gnumpfl.cc and longrat.cc
+int     npInt         (number &n, const coeffs r);
+
+// The following is currently used in OPAE.cc, OPAEQ.cc and OPAEp.cc for setting their SetMap...
+nMapFunc npSetMap(const coeffs src, const coeffs dst); // FIXME! BUG?
+
+#define npEqualM(A,B,r)  ((A)==(B))
+
+
+#endif
diff --git a/libpolys/coeffs/mpr_complex.cc b/libpolys/coeffs/mpr_complex.cc
new file mode 100644
index 0000000..12b5863
--- /dev/null
+++ b/libpolys/coeffs/mpr_complex.cc
@@ -0,0 +1,826 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+
+/*
+* ABSTRACT - multipolynomial resultants - real floating-point numbers using gmp
+*            and complex numbers based on pairs of real floating-point numbers
+*
+*/
+
+// WARNING! ALWAYS use omAlloc and FreeL when alloc. memory for some char* !!
+
+
+#include <misc/auxiliary.h>
+#include <omalloc/omalloc.h>
+
+#include <reporter/reporter.h>
+
+//#ifdef HAVE_MPR
+#include <coeffs/coeffs.h>
+#include <coeffs/numbers.h>
+
+#include <coeffs/mpr_complex.h>
+
+#include "longrat.h"
+
+#include <math.h>
+
+
+//%s
+// this was copied form longrat0.cc
+// and will be used in numberToFloat.
+// Make sure that it is up to date!!
+#define SR_HDL(A) ((long)(A))
+#define SR_TO_INT(SR) (((long)SR) >> 2)
+
+#define SIGN_PLUS  1
+#define SIGN_SPACE 2
+#define SIGN_EMPTY 4
+
+#define EXTRABYTES 4
+
+#define DEFPREC        20         // minimum number of digits (output operations)
+size_t gmp_output_digits= DEFPREC;
+
+static gmp_float *gmpRel=NULL;
+static gmp_float *diff=NULL;
+
+
+/** Set size of mantissa
+ *  digits - the number of output digits (basis 10)
+ *  the size of mantissa consists of two parts:
+ *    the "output" part a and the "rest" part b.
+ *  According to the GMP-precision digits is
+ *  recomputed to bits (basis 2).
+ *  Two numbers a, b are equal if
+ *    | a - b | < | a | * 0.1^digits .
+ *  In this case we have a - b = 0 .
+ *  The epsilon e is e=0.1^(digits+rest) with
+ *  1+e != 1, but 1+0.1*e = 1.
+ */
+void setGMPFloatDigits( size_t digits, size_t rest )
+{
+  size_t bits = 1 + (size_t) ((float)digits * 3.5);
+  size_t rb = 1 + (size_t) ((float)rest * 3.5);
+  size_t db = bits+rb;
+  gmp_output_digits= digits;
+  mpf_set_default_prec( db );
+  if (diff!=NULL) delete diff;
+  diff=new gmp_float(0.0);
+  mpf_set_prec(*diff->_mpfp(),32);
+  if (gmpRel!=NULL) delete gmpRel;
+  gmpRel=new gmp_float(0.0);
+  mpf_set_prec(*gmpRel->_mpfp(),32);
+  mpf_set_d(*gmpRel->_mpfp(),0.1);
+  mpf_pow_ui(*gmpRel->_mpfp(),*gmpRel->_mpfp(),digits);
+}
+
+#if 1
+void gmp_float::setFromStr(const char * in )
+{
+  BOOLEAN neg=false;
+  if (*in == '-') { in++; neg=TRUE; }
+  char *s;
+  if ((s=strchr((char *)in,'E')) !=NULL)
+  {
+    *s='e';
+  }
+
+  // gmp doesn't understand number which begin with "." -- it needs 0.
+  // so, insert the zero
+  if (*in == '.')
+  {
+    int len = strlen(in)+2;
+    char* c_in = (char*) omAlloc(len);
+    *c_in = '0';
+    strcpy(&(c_in[1]), in);
+
+    if(mpf_set_str( t, c_in, 10 )!=0) WerrorS("syntax error in GMP float");
+    omFreeSize((void*)c_in, len);
+  }
+  else
+  {
+    if(mpf_set_str( t, in, 10 )!=0) WerrorS("syntax error in GMP float");
+  }
+  if (neg)  mpf_neg( t, t );
+}
+#else
+// problemns with solve_s.tst
+void gmp_float::setFromStr(const char * in )
+{
+  BOOLEAN neg=false;
+  BOOLEAN E_found=FALSE;
+  if (*in == '-') { in++; neg=TRUE; }
+  char *s;
+  if ((s=strchr(in,'E')) !=NULL)
+  {
+    *s='e';
+    E_found=TRUE;
+  }
+  // gmp doesn't understand number like 1e1, it need 1e+1
+  // so, insert the +
+  if (E_found ||((s=strchr(in,'e')) !=NULL))
+  {
+    if ((*(s+1)!='+') && (*(s+1)!='-'))
+    {
+      int len = strlen(in)+3;
+      char* c_in = (char*) omAlloc(len);
+      if (*in == '.')
+      {
+        *c_in = '0';
+        strcpy(&(c_in[1]), in);
+      }
+      else
+      {
+        strcpy(c_in, in);
+      }
+      char * ss=strchr(c_in,'e');
+      memmove(ss+2,s+1,strlen(s+1));
+      *(ss+1)+'+';
+
+      mpf_set_str( t, c_in, 10 );
+      omFreeSize((void*)c_in, len);
+    }
+  }
+
+  // gmp doesn't understand number which begin with "." -- it needs 0.
+  // so, insert the zero
+  else if (*in == '.')
+  {
+    int len = strlen(in)+2;
+    char* c_in = (char*) omAlloc(len);
+    *c_in = '0';
+    strcpy(&(c_in[1]), in);
+
+    mpf_set_str( t, c_in, 10 );
+    omFreeSize((void*)c_in, len);
+  }
+  else
+  {
+    mpf_set_str( t, in, 10 );
+  }
+  if (neg)  mpf_neg( t, t );
+}
+#endif
+
+
+// <gmp_float> = <gmp_float> operator <gmp_float>
+gmp_float operator + ( const gmp_float & a, const gmp_float & b )
+{
+  gmp_float tmp( a );
+  tmp += b;
+  return tmp;
+}
+gmp_float operator - ( const gmp_float & a, const gmp_float & b )
+{
+  gmp_float tmp( a );
+  tmp -= b;
+  return tmp;
+}
+gmp_float operator * ( const gmp_float & a, const gmp_float & b )
+{
+  gmp_float tmp( a );
+  tmp *= b;
+  return tmp;
+}
+gmp_float operator / ( const gmp_float & a, const gmp_float & b )
+{
+  gmp_float tmp( a );
+  tmp /= b;
+  return tmp;
+}
+
+// <gmp_float> operator <gmp_float>
+gmp_float & gmp_float::operator += ( const gmp_float & a )
+{
+  if (mpf_sgn(t) != -(mpf_sgn(a.t)))
+  {
+    mpf_add( t, t, a.t);
+    return *this;
+  }
+  if((mpf_sgn(a.t)==0) && (mpf_sgn(t)==0))
+  {
+    mpf_set_d( t, 0.0);
+    return *this;
+  }
+  mpf_add( t, t, a.t );
+  mpf_set(diff->t, t);
+  mpf_set_prec(diff->t, 32);
+  mpf_div(diff->t, diff->t, a.t);
+  mpf_abs(diff->t, diff->t);
+  if(mpf_cmp(diff->t, gmpRel->t) < 0)
+    mpf_set_d( t, 0.0);
+  return *this;
+}
+gmp_float & gmp_float::operator -= ( const gmp_float & a )
+{
+  if (mpf_sgn(t) != mpf_sgn(a.t))
+  {
+    mpf_sub( t, t, a.t);
+    return *this;
+  }
+  if((mpf_sgn(a.t)==0) && (mpf_sgn(t)==0))
+  {
+    mpf_set_d( t, 0.0);
+    return *this;
+  }
+  mpf_sub( t, t, a.t );
+  mpf_set(diff->t, t);
+  mpf_set_prec(diff->t, 32);
+  mpf_div(diff->t, diff->t, a.t);
+  mpf_abs(diff->t, diff->t);
+  if(mpf_cmp(diff->t, gmpRel->t) < 0)
+    mpf_set_d( t, 0.0);
+  return *this;
+}
+
+// <gmp_float> == <gmp_float> ??
+bool operator == ( const gmp_float & a, const gmp_float & b )
+{
+  if(mpf_sgn(a.t) != mpf_sgn(b.t))
+    return false;
+  if((mpf_sgn(a.t)==0) && (mpf_sgn(b.t)==0))
+    return true;
+  mpf_sub(diff->t, a.t, b.t);
+  mpf_div(diff->t, diff->t, a.t);
+  mpf_abs(diff->t, diff->t);
+  if(mpf_cmp(diff->t, gmpRel->t) < 0)
+    return true;
+  else
+    return false;
+}
+// t == 0 ?
+bool gmp_float::isZero() const
+{
+  return (mpf_sgn( t ) == 0);
+}
+// t == 1 ?
+bool gmp_float::isOne() const
+{
+#ifdef  VARIANTE_1
+  return (mpf_cmp_ui( t , 1 ) == 0);
+#else
+  if (mpf_sgn(t) <= 0)
+    return false;
+  mpf_sub_ui(diff->t, t, 1);
+  mpf_abs(diff->t, diff->t);
+  if(mpf_cmp(diff->t, gmpRel->t) < 0)
+    return true;
+  else
+    return false;
+#endif
+}
+// t == -1 ?
+bool gmp_float::isMOne() const
+{
+#ifdef VARIANTE_1
+  return (mpf_cmp_si( t , -1 ) == 0);
+#else
+  if (mpf_sgn(t) >= 0)
+    return false;
+  mpf_add_ui(diff->t, t, 1);
+  mpf_abs(diff->t, diff->t);
+  if(mpf_cmp(diff->t, gmpRel->t) < 0)
+    return true;
+  else
+    return false;
+#endif
+}
+bool operator > ( const gmp_float & a, const gmp_float & b )
+{
+  if (a.t == b.t)
+    return false;
+  return mpf_cmp( a.t, b.t ) > 0;
+}
+bool operator < ( const gmp_float & a, const gmp_float & b )
+{
+  if (a.t == b.t)
+    return false;
+  return mpf_cmp( a.t, b.t ) < 0;
+}
+bool operator >= ( const gmp_float & a, const gmp_float & b )
+{
+  if (a.t == b.t)
+    return true;
+  return mpf_cmp( a.t, b.t ) >= 0;
+}
+bool operator <= ( const gmp_float & a, const gmp_float & b )
+{
+  if (a.t == b.t)
+    return true;
+  return mpf_cmp( a.t, b.t ) <= 0;
+}
+
+// unary -
+gmp_float operator - ( const gmp_float & a )
+{
+  gmp_float tmp;
+  mpf_neg( *(tmp._mpfp()), *(a.mpfp()) );
+  return tmp;
+}
+
+gmp_float abs( const gmp_float & a )
+{
+  gmp_float tmp;
+  mpf_abs( *(tmp._mpfp()), *a.mpfp() );
+  return tmp;
+}
+gmp_float sqrt( const gmp_float & a )
+{
+  gmp_float tmp;
+  mpf_sqrt( *(tmp._mpfp()), *a.mpfp() );
+  return tmp;
+}
+gmp_float sin( const gmp_float & a )
+{
+  gmp_float tmp( sin((double)a) );
+  return tmp;
+}
+gmp_float cos( const gmp_float & a )
+{
+  gmp_float tmp( cos((double)a) );
+  return tmp;
+}
+gmp_float log( const gmp_float & a )
+{
+  gmp_float tmp( log((double)a) );
+  return tmp;
+}
+gmp_float hypot( const gmp_float & a, const gmp_float & b )
+{
+#if 1
+  return ( sqrt( (a*a) + (b*b) ) );
+#else
+  gmp_float tmp( hypot( (double)a, (double)b ) );
+  return tmp;
+#endif
+}
+gmp_float exp( const gmp_float & a )
+{
+  gmp_float tmp( exp((double)a) );
+  return tmp;
+}
+gmp_float max( const gmp_float & a, const gmp_float & b )
+{
+  gmp_float tmp;
+  a > b ? tmp= a : tmp= b;
+  return tmp;
+}
+//
+// number to float, number = Q, R, C
+// makes a COPY of num! (Ist das gut?)
+//
+gmp_float numberToFloat( number num, const coeffs src)
+{
+  gmp_float r;
+
+  if ( nCoeff_is_Q(src) )
+  {
+    if ( num != NULL )
+    {
+      if (SR_HDL(num) & SR_INT)
+      {
+        //n_Print(num, src);printf("\n");
+        int nn = SR_TO_INT(num);
+        if((long)nn == SR_TO_INT(num))
+            r = SR_TO_INT(num);
+        else
+            r = gmp_float(SR_TO_INT(num));
+        //int dd = 20;
+        //gmp_printf("\nr = %.*Ff\n",dd,*r.mpfp());
+        //getchar();
+      }
+      else
+      {
+        if ( num->s == 0 )
+        {
+          nlNormalize( num, src ); // FIXME? TODO? // extern void     nlNormalize(number &x, const coeffs r); // FIXME
+        }
+        if (SR_HDL(num) & SR_INT)
+        {
+          r= SR_TO_INT(num);
+        }
+        else
+        {
+          if ( num->s != 3 )
+          {
+            r= num->z;
+            r/= (gmp_float)num->n;
+          }
+          else
+          {
+            r= num->z;
+          }
+        }
+      }
+    }
+    else
+    {
+      r= 0.0;
+    }
+  }
+  else if (nCoeff_is_long_R(src) || nCoeff_is_long_C(src))
+  {
+    r= *(gmp_float*)num;
+  }
+  else if ( nCoeff_is_R(src) )
+  {
+    // Add some code here :-)
+    WerrorS("Ground field not implemented!");
+  }
+  else
+  {
+    WerrorS("Ground field not implemented!");
+  }
+
+  return r;
+}
+
+gmp_float numberFieldToFloat( number num, int k, const coeffs src)
+{
+  gmp_float r;
+
+  switch (k)
+  {
+  case QTOF:
+    if ( num != NULL )
+    {
+      if (SR_HDL(num) & SR_INT)
+      {
+        r = gmp_float(SR_TO_INT(num));
+      }
+      else
+      {
+        if ( num->s == 0 )
+        {
+          nlNormalize( num, src ); // FIXME? TODO? // extern void     nlNormalize(number &x, const coeffs r); // FIXME
+        }
+        if (SR_HDL(num) & SR_INT)
+        {
+          r = gmp_float(SR_TO_INT(num));
+        }
+        else
+        {
+          if ( num->s != 3 )
+          {
+            r= num->z;
+            r/= (gmp_float)num->n;
+          }
+          else
+          {
+            r= num->z;
+          }
+        }
+      }
+    }
+    else
+    {
+      r= 0.0;
+    }
+    break;
+  case RTOF:
+    r= *(gmp_float*)num;
+    break;
+  case CTOF:
+    WerrorS("Can not map from field C to field R!");
+    break;
+  case ZTOF:
+  default:
+    WerrorS("Ground field not implemented!");
+  } // switch
+
+  return r;
+}
+
+// Do some strange things with the mantissa string and the exponent
+// to get some nice output string.
+char *nicifyFloatStr( char * in, mp_exp_t exponent, size_t oprec, int *size, int thesign )
+{
+  char *out;
+
+  int sign= (in[0] == '-') ? 1 : 0;
+  char csign[2];
+
+  switch (thesign)
+  {
+    case SIGN_PLUS:
+      sign ? strcpy(csign,"-") : strcpy(csign,"+");  //+123, -123
+      break;
+    case SIGN_SPACE:
+      sign ? strcpy(csign,"-") : strcpy(csign," ");  // 123, -123
+      break;
+    case SIGN_EMPTY:
+    default:
+      sign ? strcpy(csign,"-") : strcpy(csign,"");   //123, -123
+      break;
+  }
+
+  if ( strlen(in) == 0 )
+  {
+    *size= 2*sizeof(char);
+    return omStrDup("0");
+  }
+
+  if ( ((unsigned int)ABS(exponent) <= oprec)
+       /*|| (exponent+sign >= (int)strlen(in))*/ )
+  {
+    if ( exponent+sign < (int)strlen(in) )
+    {
+      int eexponent= (exponent >= 0) ? 0 : -exponent;
+      int eeexponent= (exponent >= 0) ? exponent : 0;
+      *size= (strlen(in)+15+eexponent) * sizeof(char);
+      out= (char*)omAlloc(*size);
+      memset(out,0,*size);
+
+      strcpy(out,csign);
+      strncat(out,in+sign,eeexponent);
+
+      if (exponent == 0)
+        strcat(out,"0.");
+      else if ( exponent > 0 )
+        strcat(out,".");
+      else
+      {
+        strcat(out,"0.");
+        memset(out+strlen(out),'0',eexponent);
+      }
+      strcat(out,in+sign+eeexponent);
+    }
+    else if ( exponent+sign > (int)strlen(in) )
+    {
+      *size= (strlen(in)+exponent+12)*sizeof(char);
+      out= (char*)omAlloc(*size);
+      memset(out,0,*size);
+      sprintf(out,"%s%s",csign,in+sign);
+      memset(out+strlen(out),'0',exponent-strlen(in)+sign);
+    }
+    else
+    {
+      *size= (strlen(in)+2) * sizeof(char) + 10;
+      out= (char*)omAlloc(*size);
+      memset(out,0,*size);
+      sprintf(out,"%s%s",csign,in+sign);
+    }
+  }
+  else
+  {
+//      if ( exponent > 0 )
+//      {
+      int c=1,d=10;
+      while ( exponent / d > 0 )
+      { // count digits
+        d*=10;
+        c++;
+      }
+      *size= (strlen(in)+12+c) * sizeof(char) + 10;
+      out= (char*)omAlloc(*size);
+      memset(out,0,*size);
+      sprintf(out,"%s0.%se%s%d",csign,in+sign,exponent>=0?"+":"",(int)exponent);
+//      }
+//      else
+//      {
+//        *size=2;
+//        out= (char*)omAlloc(*size);
+//        strcpy(out,"0");
+//      }
+  }
+  return out;
+}
+
+char *floatToStr( const gmp_float & r, const unsigned int oprec )
+{
+#if 1
+  mp_exp_t exponent;
+  int size,insize;
+  char *nout,*out,*in;
+
+  insize= (oprec+2) * sizeof(char) + 10;
+  in= (char*)omAlloc( insize );
+
+  mpf_get_str(in,&exponent,10,oprec,*(r.mpfp()));
+
+  if ( (exponent > 0)
+  && (exponent < (int)oprec)
+  && (strlen(in)-(in[0]=='-'?1:0) == oprec) )
+  {
+    omFree( (void *) in );
+    insize= (exponent+oprec+2) * sizeof(char) + 10;
+    in= (char*)omAlloc( insize );
+    int newprec= exponent+oprec;
+    mpf_get_str(in,&exponent,10,newprec,*(r.mpfp()));
+  }
+  nout= nicifyFloatStr( in, exponent, oprec, &size, SIGN_EMPTY );
+  omFree( (void *) in );
+  out= (char*)omAlloc( (strlen(nout)+1) * sizeof(char) );
+  strcpy( out, nout );
+  omFree( (void *) nout );
+
+  return out;
+#else
+  // for testing purpose...
+  char *out= (char*)omAlloc( (1024) * sizeof(char) );
+  sprintf(out,"% .10f",(double)r);
+  return out;
+#endif
+}
+//<-
+
+//-> gmp_complex::*
+// <gmp_complex> = <gmp_complex> operator <gmp_complex>
+//
+gmp_complex operator + ( const gmp_complex & a, const gmp_complex & b )
+{
+  return gmp_complex( a.r + b.r, a.i + b.i );
+}
+gmp_complex operator - ( const gmp_complex & a, const gmp_complex & b )
+{
+  return gmp_complex( a.r - b.r, a.i - b.i );
+}
+gmp_complex operator * ( const gmp_complex & a, const gmp_complex & b )
+{
+  return gmp_complex( a.r * b.r - a.i * b.i,
+                  a.r * b.i + a.i * b.r);
+}
+gmp_complex operator / ( const gmp_complex & a, const gmp_complex & b )
+{
+  gmp_float d = b.r*b.r + b.i*b.i;
+  return gmp_complex( (a.r * b.r + a.i * b.i) / d,
+                (a.i * b.r - a.r * b.i) / d);
+}
+
+// <gmp_complex> operator <gmp_complex>
+//
+gmp_complex & gmp_complex::operator += ( const gmp_complex & b )
+{
+  r+=b.r;
+  i+=b.i;
+  return *this;
+}
+gmp_complex & gmp_complex::operator -= ( const gmp_complex & b )
+{
+  r-=b.r;
+  i-=b.i;
+  return *this;
+}
+gmp_complex & gmp_complex::operator *= ( const gmp_complex & b )
+{
+  gmp_float f = r * b.r - i * b.i;
+  i = r * b.i + i * b.r;
+  r = f;
+  return *this;
+}
+gmp_complex & gmp_complex::neg ( )
+{
+  i.neg();
+  r.neg();
+  return *this;
+}
+gmp_complex & gmp_complex::operator /= ( const gmp_complex & b )
+{
+  gmp_float d = b.r*b.r + b.i*b.i;
+  r = (r * b.r + i * b.i) / d;
+  i = (i * b.r - r * b.i) / d;
+  return *this;
+}
+
+// Returns square root of gmp_complex number
+//
+gmp_complex sqrt( const gmp_complex & x )
+{
+  gmp_float r = abs(x);
+  gmp_float nr, ni;
+  if (r == (gmp_float) 0.0)
+  {
+    nr = ni = r;
+  }
+  else if ( x.real() > (gmp_float)0)
+  {
+    nr = sqrt((gmp_float)0.5 * (r + x.real()));
+    ni = x.imag() / nr / (gmp_float)2;
+  }
+  else
+  {
+    ni = sqrt((gmp_float)0.5 * (r - x.real()));
+    if (x.imag() < (gmp_float)0)
+    {
+      ni = - ni;
+    }
+    nr = x.imag() / ni / (gmp_float)2;
+  }
+  gmp_complex tmp(nr, ni);
+  return tmp;
+}
+
+// converts a gmp_complex to a string ( <real part> + I * <imaginary part> )
+//
+char *complexToStr( gmp_complex & c, const unsigned int oprec, const coeffs src )
+{
+  const char * complex_parameter = "I";
+  int N = 1; // strlen(complex_parameter);
+
+  if (nCoeff_is_long_C(src))
+  {
+    complex_parameter = n_ParameterNames(src)[0];
+    N = strlen(complex_parameter);
+  }
+
+  assume( complex_parameter != NULL && N > 0);
+
+  char *out,*in_imag,*in_real;
+
+  c.SmallToZero();
+  if ( !c.imag().isZero() )
+  {
+
+    in_real=floatToStr( c.real(), oprec );         // get real part
+    in_imag=floatToStr( abs(c.imag()), oprec );    // get imaginary part
+
+    if (nCoeff_is_long_C(src))
+    {
+      int len=(strlen(in_real)+strlen(in_imag)+7+N)*sizeof(char);
+      out=(char*)omAlloc(len);
+      memset(out,0,len);
+      if (  !c.real().isZero() )  // (-23-i*5.43) or (15.1+i*5.3)
+        sprintf(out,"(%s%s%s*%s)",in_real,c.imag().sign()>=0?"+":"-",complex_parameter,in_imag);
+      else // (-i*43) or (i*34)
+      {
+        if (c.imag().isOne())
+          sprintf(out,"%s", complex_parameter);
+        else if (c.imag().isMOne())
+          sprintf(out,"-%s", complex_parameter);
+        else
+          sprintf(out,"(%s%s*%s)",c.imag().sign()>=0?"":"-", complex_parameter,in_imag);
+      }
+    }
+    else
+    {
+      int len=(strlen(in_real)+strlen(in_imag)+9) * sizeof(char);
+      out=(char*)omAlloc( len );
+      memset(out,0,len);
+      if ( !c.real().isZero() )
+        sprintf(out,"(%s%s%s)",in_real,c.imag().sign()>=0?"+I*":"-I*",in_imag);
+      else
+        sprintf(out,"(%s%s)",c.imag().sign()>=0?"I*":"-I*",in_imag);
+    }
+    omFree( (void *) in_real );
+    omFree( (void *) in_imag );
+  }
+  else
+  {
+    out= floatToStr( c.real(), oprec );
+  }
+
+  return out;
+}
+//<-
+
+bool complexNearZero( gmp_complex * c, int digits )
+{
+  gmp_float eps,epsm;
+
+  if ( digits < 1 ) return true;
+
+  eps=pow(10.0,(int)digits);
+  //Print("eps: %s\n",floatToStr(eps,gmp_output_digits));
+  eps=(gmp_float)1.0/eps;
+  epsm=-eps;
+
+  //Print("eps: %s\n",floatToStr(eps,gmp_output_digits));
+
+  if ( c->real().sign() > 0 ) // +
+    return (c->real() < eps && (c->imag() < eps && c->imag() > epsm));
+  else // -
+    return (c->real() > epsm && (c->imag() < eps && c->imag() > epsm));
+}
+
+void gmp_complex::SmallToZero()
+{
+  gmp_float ar=this->real();
+  gmp_float ai=this->imag();
+  if (ar.isZero() || ai.isZero()) return;
+  mpf_abs(*ar._mpfp(), *ar._mpfp());
+  mpf_abs(*ai._mpfp(), *ai._mpfp());
+  mpf_set_prec(*ar._mpfp(), 32);
+  mpf_set_prec(*ai._mpfp(), 32);
+  if (ar > ai)
+  {
+    mpf_div(*ai._mpfp(), *ai._mpfp(), *ar._mpfp());
+    if (ai < *gmpRel) this->imag(0.0);
+  }
+  else
+  {
+    mpf_div(*ar._mpfp(), *ar._mpfp(), *ai._mpfp());
+    if (ar < *gmpRel) this->real(0.0);
+  }
+}
+
+//%e
+
+//#endif // HAVE_MPR
+
+// local Variables: ***
+// folded-file: t ***
+// compile-command-1: "make installg" ***
+// compile-command-2: "make install" ***
+// End: ***
diff --git a/libpolys/coeffs/mpr_complex.h b/libpolys/coeffs/mpr_complex.h
new file mode 100644
index 0000000..f79af56
--- /dev/null
+++ b/libpolys/coeffs/mpr_complex.h
@@ -0,0 +1,335 @@
+#ifndef MPR_COMPLEX_H
+#define MPR_COMPLEX_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+
+/*
+* ABSTRACT - multipolynomial resultants - real floating-point numbers using gmp
+*            and complex numbers based on pairs of real floating-point numbers
+*
+*/
+
+//-> include & define stuff
+// must have gmp version >= 2
+#include <coeffs/si_gmp.h>
+#include <coeffs/mpr_global.h>
+
+#define ZTOF 1
+#define QTOF 2
+#define RTOF 3
+#define CTOF 4
+
+void setGMPFloatDigits( size_t digits, size_t rest );
+
+//-> class gmp_float
+/**
+ * @short wrapper class for GNU Multi Precision Floats
+ */
+class gmp_float;
+char *floatToStr( const gmp_float & r, const unsigned int oprec );
+class gmp_float
+{
+public:
+  gmp_float( const int v = 0 )
+  {
+    mpf_init_set_si( t, (long)v );
+  }
+  gmp_float( const long v )
+  {
+    mpf_init_set_si( t, v );
+  }
+  gmp_float( const mprfloat v ) // double
+  {
+    mpf_init_set_d( t, v );
+  }
+  gmp_float( const mpf_t v )
+  {
+    mpf_init_set( t, v );
+  }
+  gmp_float( const mpz_t v ) // gnu mp Z
+  {
+    mpf_init( t );
+    mpf_set_z( t, v );
+  }
+  gmp_float( const gmp_float & v ) // copy constructor
+  {
+    mpf_init_set( t, v.t );
+  }
+
+  ~gmp_float()
+  {
+    mpf_clear( t );
+  }
+
+  inline gmp_float & operator = ( const gmp_float & a )
+  {
+    mpf_set( t, a.t );
+    return *this;
+  };
+  inline gmp_float & operator = ( const mpz_t & a )
+  {
+    mpf_set_z( t, a );
+    return *this;
+  };
+  inline gmp_float & operator = ( const mprfloat a )
+  {
+    mpf_set_d( t, (double) a );
+    return *this;
+  };
+  inline gmp_float & operator = ( const long a )
+  {
+    mpf_set_d( t, (double) a );
+    return *this;
+  };
+
+  gmp_float & operator += ( const gmp_float & a );
+  gmp_float & operator -= ( const gmp_float & a );
+  inline gmp_float & operator *= ( const gmp_float & a )
+  {
+    mpf_mul( t, t, a.t );
+    return *this;
+  };
+
+  inline gmp_float & operator /= ( const gmp_float & a )
+  {
+    mpf_div( t, t, a.t );
+    return *this;
+  };
+
+  inline gmp_float & neg ( ) { mpf_neg(t,t); return *this; };
+
+  friend gmp_float operator + ( const gmp_float & a, const gmp_float & b );
+  friend gmp_float operator - ( const gmp_float & a, const gmp_float & b );
+  friend gmp_float operator * ( const gmp_float & a, const gmp_float & b );
+  friend gmp_float operator / ( const gmp_float & a, const gmp_float & b );
+
+  inline gmp_float operator ^ ( const int exp ) const
+  {
+    mpf_t b;
+    mpf_init(b);
+    mpf_pow_ui( b, this->t, (unsigned long)exp );
+    return gmp_float(b);
+  };
+
+  friend bool operator == ( const gmp_float & a, const gmp_float & b );
+  friend bool operator  > ( const gmp_float & a, const gmp_float & b );
+  friend bool operator  < ( const gmp_float & a, const gmp_float & b );
+  friend bool operator >= ( const gmp_float & a, const gmp_float & b );
+  friend bool operator <= ( const gmp_float & a, const gmp_float & b );
+
+  friend gmp_float operator - ( const gmp_float & a );
+
+  inline int sign()    // t>0:+1, t==0:0, t<0:-1
+  { return mpf_sgn( t ); };
+
+  bool isZero() const;  // t == 0 ?
+  bool isOne() const;   // t == 1 ?
+  bool isMOne() const;  // t == -1 ?
+
+  void setFromStr(const char * in );
+
+  // access
+  inline const mpf_t *mpfp() const { return &t; };
+  inline mpf_t *_mpfp() { return &t; };
+
+  inline operator double() { return mpf_get_d( t ); };
+  inline operator double() const { return mpf_get_d( t ); };
+
+#if 0
+  inline operator int() { return (int)mpf_get_d( t ); };
+  inline operator int() const { return (int)mpf_get_d( t ); };
+//#else
+  inline operator int() const
+  { if (mpf_fits_sint_p(t))
+    { return (int)mpf_get_si( t ); }
+    return 0;
+  };
+#endif
+
+private:
+  mpf_t t;
+};
+
+
+// built-in functions of GMP
+gmp_float abs( const gmp_float & );
+gmp_float sqrt( const gmp_float & );
+gmp_float hypot( const gmp_float &, const gmp_float & );
+//gmp_float pow( const gmp_float &, int & );
+
+// simulated functions using double functions
+gmp_float sin( const gmp_float & );
+gmp_float cos( const gmp_float & );
+gmp_float log( const gmp_float & );
+gmp_float exp( const gmp_float & );
+
+gmp_float max( const gmp_float &, const gmp_float & );
+
+gmp_float numberToFloat( number num, const coeffs src );
+gmp_float numberFieldToFloat( number num, int k, const coeffs src );
+//char *floatToStr( const gmp_float & r, const unsigned int oprec );
+//<-
+
+//-> class gmp_complex
+/**
+ * @short gmp_complex numbers based on
+ */
+class gmp_complex
+{
+private:
+  gmp_float r, i;
+
+public:
+  gmp_complex( const gmp_float re= 0.0, const gmp_float im= 0.0 )
+  {
+    r= re;
+    i= im;
+  }
+  gmp_complex( const mprfloat re, const mprfloat im = 0.0 )
+  {
+    r= re;
+    i= im;
+  }
+  gmp_complex( const long re, const long im )
+  {
+    r= re;
+    i= im;
+  }
+  gmp_complex( const gmp_complex & v )
+  {
+    r= v.r;
+    i= v.i;
+  }
+  ~gmp_complex() {}
+
+  gmp_complex & neg ( );
+
+  friend gmp_complex operator + ( const gmp_complex & a, const gmp_complex & b );
+  friend gmp_complex operator - ( const gmp_complex & a, const gmp_complex & b );
+  friend gmp_complex operator * ( const gmp_complex & a, const gmp_complex & b );
+  friend gmp_complex operator / ( const gmp_complex & a, const gmp_complex & b );
+
+  // gmp_complex <operator> real
+  inline friend gmp_complex operator + ( const gmp_complex & a, const gmp_float b_d );
+  inline friend gmp_complex operator - ( const gmp_complex & a, const gmp_float b_d );
+  inline friend gmp_complex operator * ( const gmp_complex & a, const gmp_float b_d );
+  inline friend gmp_complex operator / ( const gmp_complex & a, const gmp_float b_d );
+
+  gmp_complex & operator += ( const gmp_complex & a );
+  gmp_complex & operator -= ( const gmp_complex & a );
+  gmp_complex & operator *= ( const gmp_complex & a );
+  gmp_complex & operator /= ( const gmp_complex & a );
+
+  inline friend bool operator == ( const gmp_complex & a, const gmp_complex & b );
+  inline friend bool operator  > ( const gmp_complex & a, const gmp_complex & b );
+  inline friend bool operator  < ( const gmp_complex & a, const gmp_complex & b );
+  inline friend bool operator >= ( const gmp_complex & a, const gmp_complex & b );
+  inline friend bool operator <= ( const gmp_complex & a, const gmp_complex & b );
+
+  inline gmp_complex & operator = ( const gmp_complex & a );
+  inline gmp_complex & operator = ( const gmp_float & f );
+
+  // access to real and imaginary part
+  inline gmp_float real() const { return r; }
+  inline gmp_float imag() const { return i; }
+
+  inline void real( gmp_float val ) { r = val; }
+  inline void imag( gmp_float val ) { i = val; }
+
+
+  inline bool isZero() { return (r.isZero() && i.isZero()); }
+  void SmallToZero();
+};
+
+// <gmp_complex> = <gmp_complex> operator <gmp_float>
+//
+inline gmp_complex operator + ( const gmp_complex & a, const gmp_float b_d )
+{
+  return gmp_complex( a.r + b_d, a.i );
+}
+inline gmp_complex operator - ( const gmp_complex & a, const gmp_float b_d )
+{
+  return gmp_complex( a.r - b_d, a.i );
+}
+inline gmp_complex operator * ( const gmp_complex & a, const gmp_float b_d )
+{
+  return gmp_complex( a.r * b_d, a.i * b_d );
+}
+inline gmp_complex operator / ( const gmp_complex & a, const gmp_float b_d )
+{
+  return gmp_complex( a.r / b_d, a.i / b_d );
+}
+
+// <gmp_complex> == <gmp_complex> ?
+inline bool operator == ( const gmp_complex & a, const gmp_complex & b )
+{
+  return ( b.real() == a.real() ) && ( b.imag() == a.imag() );
+}
+inline bool operator  > ( const gmp_complex & a, const gmp_complex & b )
+{
+  return ( a.real() > b.real() );
+}
+inline bool operator  < ( const gmp_complex & a, const gmp_complex & b )
+{
+  return ( a.real() < b.real() );
+}
+inline bool operator >= ( const gmp_complex & a, const gmp_complex & b )
+{
+  return ( a.real() >= b.real() );
+}
+inline bool operator <= ( const gmp_complex & a, const gmp_complex & b )
+{
+  return ( a.real() <= b.real() );
+}
+
+
+// <gmp_complex> = <gmp_complex>
+inline gmp_complex & gmp_complex::operator = ( const gmp_complex & a )
+{
+  r= a.r;
+  i= a.i;
+  return *this;
+}
+
+// <gmp_complex> = <gmp_complex>
+inline gmp_complex & gmp_complex::operator = ( const gmp_float & f )
+{
+  r= f;
+  i= (long int)0;
+  return *this;
+}
+
+// Returns absolute value of a gmp_complex number
+//
+inline gmp_float abs( const gmp_complex & c )
+{
+  return hypot(c.real(),c.imag());
+}
+
+gmp_complex sqrt( const gmp_complex & x );
+
+inline gmp_complex numberToComplex( number num, const coeffs r )
+{
+  if (nCoeff_is_long_C(r))
+  {
+    return *(gmp_complex*)num;
+  }
+  else
+  {
+    return gmp_complex( numberToFloat(num, r) );
+  }
+}
+
+char *complexToStr( gmp_complex & c, const  unsigned int oprec, const coeffs src );
+//<-
+
+bool complexNearZero( gmp_complex * c, int digits );
+
+#endif /* MPR_COMPLEX_H */
+
+// local Variables: ***
+// folded-file: t ***
+// compile-command-1: "make installg" ***
+// compile-command-2: "make install" ***
+// End: ***
diff --git a/libpolys/coeffs/mpr_global.h b/libpolys/coeffs/mpr_global.h
new file mode 100644
index 0000000..afa0854
--- /dev/null
+++ b/libpolys/coeffs/mpr_global.h
@@ -0,0 +1,92 @@
+#ifndef MPR_GLOBAL_H
+#define MPR_GLOBAL_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+
+/*
+* ABSTRACT - multipolynomial resultants -
+*                                global definitions and debugging stuff
+*/
+
+// to get detailed timigs, define MPR_TIMING
+//#define MPR_TIMING
+
+// Set to double or long double. double is recomended.
+// Sets the global floating point type used in mpr_numeric.cc.
+typedef double mprfloat;
+
+// --------------------------- debugging stuff ----------------------------
+#if !defined(SING_NDEBUG)
+//#define mprDEBUG_ALL
+#endif
+
+#if !defined(SING_NDEBUG) || defined(mprDEBUG_ALL)
+//#define mprDEBUG_PROT
+#endif
+
+#define mprDEBUG_STICKY
+
+#ifdef mprDEBUG_PROT
+#define mprPROT(msg) PrintS(msg)
+#define mprPROTnl(msg) Print("%s\n",msg)
+#define mprPROTP(msg,poly) PrintS(msg);pWrite0(poly)
+#define mprPROTPnl(msg,poly) PrintS(msg);pWrite(poly)
+#define mprPROTI(msg,intval) Print("%s%d",msg,intval)
+#define mprPROTL(msg,intval) Print("%s%ld",msg,intval)
+#define mprPROTInl(msg,intval) Print("%s%d\n",msg,intval)
+#define mprPROTN(msg,nval) PrintS(msg);nPrint(nval);
+#define mprPROTNnl(msg,nval) PrintS(msg);nPrint(nval);PrintLn();
+#else
+#define mprPROT(msg)
+#define mprPROTnl(msg)
+#define mprPROTP(msg,poly)
+#define mprPROTPnl(msg,poly)
+#define mprPROTI(msg,intval)
+#define mprPROTL(msg,intval)
+#define mprPROTInl(msg,intval)
+#define mprPROTN(msg,nval)
+#define mprPROTNnl(msg,nval)
+#endif
+
+#if defined(mprDEBUG_STICKY)
+// call 'option(prot);' to get status informations
+#define mprSTICKYPROT(msg) if (BTEST1(OPT_PROT)) Print(msg)
+#define mprSTICKYPROT2(msg,arg) if (BTEST1(OPT_PROT)) Print(msg,arg)
+#else
+#define mprSTICKYPROT(msg)
+#define mprSTICKYPROT2(msg,arg)
+#endif
+
+// output by mprSTICKYPROT
+#define ST_BASE_EV "."
+
+#define ST_DENSE_FR ":"
+#define ST_DENSE_NR "."
+#define ST_DENSE_MEM "+"
+#define ST_DENSE_NMON "-"
+
+#define ST_SPARSE_MEM "+"
+#define ST_SPARSE_VADD "+"
+#define ST_SPARSE_VREJ "-"
+#define ST_SPARSE_MPEND "e"
+#define ST_SPARSE_MREC1 "r"
+#define ST_SPARSE_MREC2 "R"
+#define ST_SPARSE_RC "+"
+#define ST_SPARSE_RCRJ "-"
+
+#define ST__DET "|"
+
+#define ST_ROOTS_LGSTEP "|"
+#define ST_ROOTS_LGPOLISH "#"
+#define ST_ROOTS_LG "-"
+
+#define ST_VANDER_STEP "."
+
+#endif
+
+// local Variables: ***
+// folded-file: t ***
+// compile-command-1: "make installg" ***
+// compile-command-2: "make install" ***
+// End: ***
diff --git a/libpolys/coeffs/numbers.cc b/libpolys/coeffs/numbers.cc
new file mode 100644
index 0000000..dbb39a8
--- /dev/null
+++ b/libpolys/coeffs/numbers.cc
@@ -0,0 +1,556 @@
+/*****************************************
+*  Computer Algebra System SINGULAR      *
+*****************************************/
+
+/*
+* ABSTRACT: interface to coefficient aritmetics
+*/
+
+#include <string.h>
+#include <stdlib.h>
+
+#include <misc/auxiliary.h>
+#include <omalloc/omalloc.h>
+#include <factory/factory.h>
+
+#include <reporter/reporter.h>
+
+#include <coeffs/coeffs.h>
+#include <coeffs/numbers.h>
+
+#include <coeffs/longrat.h>
+#include <coeffs/modulop.h>
+#include <coeffs/gnumpfl.h>
+#include <coeffs/gnumpc.h>
+#include <coeffs/ffields.h>
+#include <coeffs/shortfl.h>
+
+#ifdef HAVE_RINGS
+# include <coeffs/rmodulo2m.h>
+# include <coeffs/rmodulon.h>
+# include <coeffs/rintegers.h>
+#endif
+
+#ifdef HAVE_POLYEXTENSIONS
+#include <polys/ext_fields/algext.h>
+#include <polys/ext_fields/transext.h>
+#endif
+
+
+#ifdef HAVE_NUMSTATS
+struct SNumberStatistic number_stats;
+#endif /* HAVE_NUMSTATS */
+
+//static int characteristic = 0;
+//extern int IsPrime(int p);
+
+n_Procs_s *cf_root=NULL;
+
+void   nNew(number* d) { *d=NULL; }
+
+
+static void   ndDelete(number* d, const coeffs) { *d=NULL; }
+static number ndAnn(number, const coeffs) { return NULL;}
+static char* ndCoeffString(const coeffs r)
+{
+  char *s=(char *)omAlloc(11);snprintf(s,11,"Coeffs(%d)",r->type);
+  return s;
+}
+static void   ndInpMult(number &a, number b, const coeffs r)
+{
+  number n=r->cfMult(a,b,r);
+  r->cfDelete(&a,r);
+  a=n;
+}
+static void ndInpAdd(number &a, number b, const coeffs r)
+{
+  number n=r->cfAdd(a,b,r);
+  r->cfDelete(&a,r);
+  a=n;
+}
+
+static void ndPower(number a, int i, number * res, const coeffs r)
+{
+  if (i==0) {
+    *res = r->cfInit(1, r);
+  } else if (i==1) {
+    *res = r->cfCopy(a, r);
+  } else if (i==2) {
+    *res = r->cfMult(a, a, r);
+  } else if (i<0) {
+    number b = r->cfInvers(a, r);
+    ndPower(b, -i, res, r);
+    r->cfDelete(&b, r);
+  } else {
+    ndPower(a, i/2, res, r);
+    r->cfInpMult(*res, *res, r);
+    if (i&1) {
+      r->cfInpMult(*res, a, r);
+    }
+  }
+}
+
+#ifdef LDEBUG
+// static void   nDBDummy1(number* d,char *, int) { *d=NULL; }
+static BOOLEAN ndDBTest(number, const char *, const int, const coeffs){ return TRUE; }
+#endif
+
+static number ndFarey(number,number,const coeffs r)
+{
+  Werror("farey not implemented for %s (c=%d)",r->cfCoeffString(r),getCoeffType(r));
+  return NULL;
+}
+static number ndChineseRemainder(number *,number *,int,BOOLEAN,const coeffs r)
+{
+  Werror("ChineseRemainder not implemented for %s (c=%d)",r->cfCoeffString(r),getCoeffType(r));
+  return r->cfInit(0,r);
+}
+
+static int ndParDeg(number n, const coeffs r)
+{
+  return (-r->cfIsZero(n,r));
+}
+
+static number ndParameter(const int, const coeffs r)
+{
+  Werror("ndParameter: n_Parameter is not implemented/relevant for (coeff_type = %d)",getCoeffType(r));
+  return NULL;
+}
+
+BOOLEAN n_IsZeroDivisor( number a, const coeffs r)
+{
+  int c = n_GetChar(r);
+  BOOLEAN ret = n_IsZero(a, r);
+  if( (c != 0) && !ret )
+  {
+    number ch = n_Init( c, r );
+    number g = n_Gcd( ch, a, r );
+    ret = !n_IsOne (g, r);
+    n_Delete(&ch, r);
+    n_Delete(&g, r);
+  }
+  return ret;
+}
+
+static void   ndNormalize(number&, const coeffs) { }
+static number ndReturn0(number, const coeffs r)        { return r->cfInit(0,r); }
+static number ndGcd(number, number, const coeffs r)    { return r->cfInit(1,r); }
+static number ndIntMod(number, number, const coeffs r) { return r->cfInit(0,r); }
+static number ndGetDenom(number &, const coeffs r)     { return r->cfInit(1,r); }
+static number ndGetNumerator(number &a,const coeffs r) { return r->cfCopy(a,r); }
+static int    ndSize(number a, const coeffs r)         { return (int)r->cfIsZero(a,r)==FALSE; }
+static char * ndCoeffName(const coeffs r)              { return r->cfCoeffString(r); }
+
+static void ndClearContent(ICoeffsEnumerator& numberCollectionEnumerator, number& c, const coeffs r)
+{
+  assume(r != NULL);
+
+  // no fractions
+  assume(!(  nCoeff_is_Q(r) ));
+  // all coeffs are given by integers!!!
+
+  numberCollectionEnumerator.Reset();
+
+  if( !numberCollectionEnumerator.MoveNext() ) // empty zero polynomial?
+  {
+    c = n_Init(1, r);
+    return;
+  }
+
+  number &curr = numberCollectionEnumerator.Current();
+
+#ifdef HAVE_RINGS
+  /// TODO: move to a separate implementation
+  if (nCoeff_is_Ring(r))
+  {
+    if (nCoeff_has_Units(r))
+    {
+      c = n_GetUnit(curr, r);
+
+      if (!n_IsOne(c, r))
+      {
+        number inv = n_Invers(c, r);
+
+        n_InpMult(curr, inv, r);
+
+        while( numberCollectionEnumerator.MoveNext() )
+        {
+          number &n = numberCollectionEnumerator.Current();
+          n_Normalize(n, r); // ?
+          n_InpMult(n, inv, r); // TODO: either this or directly divide!!!?
+        }
+
+        n_Delete(&inv, r);
+      }
+    } else c = n_Init(1, r);
+
+    return;
+  }
+#endif
+
+  assume(!nCoeff_is_Ring(r));
+  assume(nCoeff_is_Zp(r) || nCoeff_is_numeric(r) || nCoeff_is_GF(r) || nCoeff_is_Zp_a(r) || nCoeff_is_Q_algext(r));
+
+  n_Normalize(curr, r); // Q: good/bad/ugly??
+
+  if (!n_IsOne(curr, r))
+  {
+    number t = curr; // takes over the curr! note: not a reference!!!
+
+    curr = n_Init(1, r); // ???
+
+    number inv = n_Invers(t, r);
+
+    while( numberCollectionEnumerator.MoveNext() )
+    {
+      number &n = numberCollectionEnumerator.Current();
+      n_InpMult(n, inv, r); // TODO: either this or directly divide!!!?
+//      n_Normalize(n, r); // ?
+    }
+
+    n_Delete(&inv, r);
+
+    c = t;
+  } else
+    c = n_Copy(curr, r); // c == 1 and nothing else to do...
+}
+
+static void ndClearDenominators(ICoeffsEnumerator& /*numberCollectionEnumerator*/, number& d, const coeffs r)
+{
+  assume( r != NULL );
+  assume( !(nCoeff_is_Q(r) || nCoeff_is_transExt(r) || nCoeff_is_algExt(r)) );
+  assume( nCoeff_is_Ring(r) || nCoeff_is_Zp(r) || nCoeff_is_numeric(r) || nCoeff_is_GF(r) );
+
+  d = n_Init(1, r);
+}
+
+static number ndCopy(number a, const coeffs) { return a; }
+number ndCopyMap(number a, const coeffs aRing, const coeffs r)
+{
+  assume( getCoeffType(r) == getCoeffType(aRing) );
+  if ( nCoeff_has_simple_Alloc(r) && nCoeff_has_simple_Alloc(aRing) )
+    return a;
+  else
+    return r->cfCopy(a, r);
+}
+
+static void ndKillChar(coeffs) {}
+static void ndSetChar(const coeffs) {}
+
+number nd_Copy(number a, const coeffs r) { return r->cfCopy(a, r); }
+
+#ifdef HAVE_RINGS
+static BOOLEAN ndDivBy(number, number, const coeffs) { return TRUE; } // assume a,b !=0
+static int ndDivComp(number, number, const coeffs) { return 2; }
+static BOOLEAN ndIsUnit(number a, const coeffs r) { return !r->cfIsZero(a,r); }
+static number  ndExtGcd (number, number, number *, number *, const coeffs r) { return r->cfInit(1,r); }
+#endif
+
+static CanonicalForm ndConvSingNFactoryN( number, BOOLEAN /*setChar*/, const coeffs)
+{
+  CanonicalForm term(0);
+  Werror("no conversion to factory");
+  return term;
+}
+
+static number ndConvFactoryNSingN( const CanonicalForm, const coeffs)
+{
+  Werror("no conversion from factory");
+  return NULL;
+}
+
+/**< [in, out] a bigint number >= 0  */
+/**< [out] the GMP equivalent    */
+/// Converts a non-negative bigint number into a GMP number.
+static void ndMPZ(mpz_t result, number &n, const coeffs r)
+{
+  mpz_init_set_si( result, r->cfInt(n, r) );
+}
+
+static number ndInitMPZ(mpz_t m, const coeffs r)
+{
+  return r->cfInit( mpz_get_si(m), r);
+}
+
+
+static BOOLEAN ndCoeffIsEqual(const coeffs r, n_coeffType n, void *)
+{
+  /* test, if r is an instance of nInitCoeffs(n,parameter) */
+  /* if paramater is not needed */
+  return (n==r->type);
+}
+
+static n_coeffType nLastCoeffs=n_CF;
+cfInitCharProc nInitCharTableDefault[]=
+{ NULL,        /*n_unknown */
+ npInitChar,   /* n_Zp */
+ nlInitChar,   /* n_Q */
+ nrInitChar,   /* n_R */
+ nfInitChar,   /* n_GF */
+ ngfInitChar,  /* n_long_R */
+ #ifdef HAVE_POLYEXTENSIONS
+ naInitChar,  /* n_algExt */
+ ntInitChar,  /* n_transExt */
+ #else
+ NULL,        /* n_algExt */
+ NULL,        /* n_transExt */
+ #endif
+ ngcInitChar,  /* n_long_C */
+ #ifdef HAVE_RINGS
+ nrzInitChar,  /* n_Z */
+ nrnInitChar,  /* n_Zn */
+ nrnInitChar,  /* n_Znm */
+ nr2mInitChar, /* n_Z2m */
+ #else
+ NULL,         /* n_Z */
+ NULL,         /* n_Zn */
+ NULL,         /* n_Znm */
+ NULL,         /* n_Z2m */
+ #endif
+ NULL         /* n_CF */
+};
+
+static cfInitCharProc *nInitCharTable=nInitCharTableDefault;
+/*2
+* init operations for coeffs r
+*/
+coeffs nInitChar(n_coeffType t, void * parameter)
+{
+  n_Procs_s *n=cf_root;
+
+  while((n!=NULL) && (n->nCoeffIsEqual!=NULL) && (!n->nCoeffIsEqual(n,t,parameter)))
+      n=n->next;
+
+  if (n==NULL)
+  {
+    n=(n_Procs_s*)omAlloc0(sizeof(n_Procs_s));
+    n->next=cf_root;
+    n->ref=1;
+    n->type=t;
+
+    // default entries (different from NULL) for some routines:
+    n->nCoeffIsEqual = ndCoeffIsEqual;
+    n->cfSize = ndSize;
+    n->cfGetDenom= ndGetDenom;
+    n->cfGetNumerator= ndGetNumerator;
+    n->cfImPart=ndReturn0;
+    n->cfDelete= ndDelete;
+    n->cfAnn = ndAnn;
+    n->cfCoeffString = ndCoeffString; // should alway be changed!
+    n->cfInpMult=ndInpMult;
+    n->cfInpAdd=ndInpAdd;
+    n->cfCopy = ndCopy;
+    n->cfIntMod=ndIntMod; /* dummy !! */
+    n->cfNormalize=ndNormalize;
+    n->cfGcd  = ndGcd;
+    n->cfNormalizeHelper  = ndGcd; /* tricky, isn't it ?*/
+    n->cfLcm  = ndGcd; /* tricky, isn't it ?*/
+    n->cfInitMPZ = ndInitMPZ;
+    n->cfMPZ = ndMPZ;
+    n->cfPower = ndPower;
+    n->cfCoeffName = ndCoeffName;
+
+    n->cfKillChar = ndKillChar; /* dummy */
+    n->cfSetChar = ndSetChar; /* dummy */
+    // temp. removed to catch all the coeffs which miss to implement this!
+
+    n->cfChineseRemainder = ndChineseRemainder;
+    n->cfFarey = ndFarey;
+    n->cfParDeg = ndParDeg;
+
+    n->cfParameter = ndParameter;
+
+    n->cfClearContent = ndClearContent;
+    n->cfClearDenominators = ndClearDenominators;
+
+#ifdef HAVE_RINGS
+    n->cfDivComp = ndDivComp;
+    n->cfDivBy = ndDivBy;
+    n->cfIsUnit = ndIsUnit;
+    n->cfExtGcd = ndExtGcd;
+    //n->cfGetUnit = (nMapFunc)NULL;
+#endif
+
+#ifdef LDEBUG
+    n->cfDBTest=ndDBTest;
+#endif
+
+    n->convSingNFactoryN=ndConvSingNFactoryN;
+    n->convFactoryNSingN=ndConvFactoryNSingN;
+
+    BOOLEAN nOK=TRUE;
+    // init
+    if ((t<=nLastCoeffs) && (nInitCharTable[t]!=NULL))
+      nOK = (nInitCharTable[t])(n,parameter);
+    else
+       Werror("Sorry: the coeff type [%d] was not registered: it is missing in nInitCharTable", (int)t);
+    if (nOK)
+    {
+      omFreeSize(n,sizeof(*n));
+      return NULL;
+    }
+    cf_root=n;
+    // post init settings:
+    if (n->cfRePart==NULL) n->cfRePart=n->cfCopy;
+    if (n->cfExactDiv==NULL) n->cfExactDiv=n->cfDiv;
+    if (n->cfSubringGcd==NULL) n->cfSubringGcd=n->cfGcd;
+
+#ifdef HAVE_RINGS
+    if (n->cfGetUnit==NULL) n->cfGetUnit=n->cfCopy;
+#endif
+
+    if(n->cfWriteShort==NULL)
+      n->cfWriteShort = n->cfWriteLong;
+
+    assume(n->nCoeffIsEqual!=NULL);
+    assume(n->cfSetChar!=NULL);
+    assume(n->cfCoeffString!=ndCoeffString);
+    assume(n->cfMult!=NULL);
+    assume(n->cfSub!=NULL);
+    assume(n->cfAdd!=NULL);
+    assume(n->cfDiv!=NULL);
+    assume(n->cfIntMod!=NULL);
+    assume(n->cfExactDiv!=NULL);
+    assume(n->cfInit!=NULL);
+    assume(n->cfInitMPZ!=NULL);
+    assume(n->cfSize!=NULL);
+    assume(n->cfInt!=NULL);
+    assume(n->cfMPZ!=NULL);
+    //assume(n->n->cfDivComp!=NULL);
+    //assume(n->cfIsUnit!=NULL);
+    //assume(n->cfGetUnit!=NULL);
+    //assume(n->cfExtGcd!=NULL);
+    assume(n->cfInpNeg!=NULL);
+    assume(n->cfCopy!=NULL);
+
+    assume(n->cfWriteLong!=NULL);
+    assume(n->cfWriteShort!=NULL);
+
+    assume(n->iNumberOfParameters>= 0);
+
+    assume( (n->iNumberOfParameters == 0 && n->pParameterNames == NULL) ||
+            (n->iNumberOfParameters >  0 && n->pParameterNames != NULL) );
+
+    assume(n->cfParameter!=NULL);
+    assume(n->cfParDeg!=NULL);
+
+    assume(n->cfRead!=NULL);
+    assume(n->cfNormalize!=NULL);
+    assume(n->cfGreater!=NULL);
+    //assume(n->cfDivBy!=NULL);
+    assume(n->cfEqual!=NULL);
+    assume(n->cfIsZero!=NULL);
+    assume(n->cfIsOne!=NULL);
+    assume(n->cfIsMOne!=NULL);
+    assume(n->cfGreaterZero!=NULL);
+    assume(n->cfGetDenom!=NULL);
+    assume(n->cfGetNumerator!=NULL);
+    assume(n->cfGcd!=NULL);
+    assume(n->cfNormalizeHelper!=NULL);
+    assume(n->cfDelete!=NULL);
+    assume(n->cfSetMap!=NULL);
+    assume(n->cfInpMult!=NULL);
+//    assume(n->cfInit_bigint!=NULL);
+    assume(n->cfCoeffWrite != NULL);
+
+    assume(n->cfClearContent != NULL);
+    assume(n->cfClearDenominators != NULL);
+
+    assume(n->type==t);
+
+#ifndef SING_NDEBUG
+    if(n->cfKillChar==NULL) Warn("cfKillChar is NULL for coeff %d",t);
+    if(n->cfWriteLong==NULL) Warn("cfWrite is NULL for coeff %d",t);
+    if(n->cfWriteShort==NULL) Warn("cfWriteShort is NULL for coeff %d",t);
+    if(n->cfCoeffString==ndCoeffString) Warn("cfCoeffString is undefined for coeff %d",t);
+#endif
+
+   if( n->nNULL == NULL )
+     n->nNULL = n->cfInit(0, n); // may still remain NULL
+  }
+  else
+  {
+    n->ref++;
+  }
+  return n;
+}
+
+void nKillChar(coeffs r)
+{
+  STATISTIC(nKillChar);
+  if (r!=NULL)
+  {
+    r->ref--;
+    if (r->ref<=0)
+    {
+      n_Procs_s tmp;
+      n_Procs_s* n=&tmp;
+      tmp.next=cf_root;
+      while((n->next!=NULL) && (n->next!=r)) n=n->next;
+      if (n->next==r)
+      {
+        n->next=n->next->next;
+        if (cf_root==r) cf_root=n->next;
+        n_Delete(&(r->nNULL),r);
+        assume (r->cfKillChar!=NULL); r->cfKillChar(r); // STATISTIC(nKillChar);
+        omFreeSize((void *)r, sizeof(n_Procs_s));
+        r=NULL;
+      }
+      else
+      {
+        WarnS("cf_root list destroyed");
+      }
+    }
+  }
+}
+
+
+n_coeffType nRegister(n_coeffType n, cfInitCharProc p)
+{
+  if (n==n_unknown)
+  {
+    nLastCoeffs=(n_coeffType)(int(nLastCoeffs)+1);
+    if (nInitCharTable==nInitCharTableDefault)
+    {
+      nInitCharTable=(cfInitCharProc*)omAlloc0(
+                                          ((int)nLastCoeffs+1)*sizeof(cfInitCharProc));
+      memcpy(nInitCharTable,nInitCharTableDefault,
+              ((int)nLastCoeffs)*sizeof(cfInitCharProc));
+    }
+    else
+    {
+      nInitCharTable=(cfInitCharProc*)omReallocSize(nInitCharTable,
+                                          ((int)nLastCoeffs)*sizeof(cfInitCharProc),
+                                          (((int)nLastCoeffs)+1)*sizeof(cfInitCharProc));
+    }
+
+    nInitCharTable[nLastCoeffs]=p;
+    return nLastCoeffs;
+  }
+  else
+  {
+    if (nInitCharTable[n]!=NULL) Print("coeff %d already initialized\n",n);
+    nInitCharTable[n]=p;
+    return n;
+  }
+}
+
+
+void n_Print(number& a,  const coeffs r)
+{
+   assume(r != NULL);
+   n_Test(a,r);
+
+   StringSetS("");
+   n_Write(a, r);
+   { char* s = StringEndS(); Print("%s", s); omFree(s); }
+}
+
+
+number n_convFactoryNSingN( const CanonicalForm n, const coeffs r)
+{ STATISTIC(n_convFactoryNSingN); assume(r != NULL); assume(r->convFactoryNSingN != NULL); return r->convFactoryNSingN(n, r); }
+
+
+
+CanonicalForm n_convSingNFactoryN( number n, BOOLEAN setChar, const coeffs r )
+{ STATISTIC(n_convSingNFactoryN); assume(r != NULL); assume(r->convSingNFactoryN != NULL); return r->convSingNFactoryN(n, setChar, r); }
diff --git a/libpolys/coeffs/numbers.h b/libpolys/coeffs/numbers.h
new file mode 100644
index 0000000..a8f5d90
--- /dev/null
+++ b/libpolys/coeffs/numbers.h
@@ -0,0 +1,98 @@
+#ifndef NUMBERS_H
+#define NUMBERS_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: compatility interface to coeffs
+*/
+#include <coeffs/coeffs.h>
+
+// the access methods
+//
+// the routines w.r.t. currRing:
+// (should only be used in the context of currRing, i.e. in t
+#define nCopy(n)          n_Copy(n, currRing->cf)
+#define nDelete(n)        n_Delete(n, currRing->cf)
+#define nMult(n1, n2)     n_Mult(n1, n2, currRing->cf)
+#define nAdd(n1, n2)      n_Add(n1, n2, currRing->cf)
+#define nIsZero(n)        n_IsZero(n, currRing->cf)
+#define nEqual(n1, n2)    n_Equal(n1, n2, currRing->cf)
+#define nInpNeg(n)        n_InpNeg(n, currRing->cf)
+#define nSub(n1, n2)      n_Sub(n1, n2, currRing->cf)
+#define nGetChar()        n_GetChar(currRing->cf)
+#define nInit(i)          n_Init(i, currRing->cf)
+#define nIsOne(n)         n_IsOne(n, currRing->cf)
+#define nIsMOne(n)        n_IsMOne(n, currRing->cf)
+#define nGreaterZero(n)   n_GreaterZero(n, currRing->cf)
+#define nGreater(a, b)    n_Greater (a,b,currRing->cf)
+#define nWrite(n)         n_Write(n, currRing->cf, rShortOut(currRing))
+#define nNormalize(n)     n_Normalize(n,currRing->cf)
+#define nGcd(a,b)         n_Gcd(a,b,currRing->cf)
+#define nDiv(a, b)        n_Div(a,b,currRing->cf)
+#define nInvers(a)        n_Invers(a,currRing->cf)
+#define nExactDiv(a, b)   n_ExactDiv(a,b,currRing->cf)
+#define nTest(a)          n_Test(a,currRing->cf)
+
+#define nInpMult(a, b)    n_InpMult(a,b,currRing->cf)
+#define nPower(a, b, res) n_Power(a,b,res,currRing->cf)
+#define nSize(n)          n_Size(n,currRing->cf)
+#define nGetDenom(N)      n_GetDenom((N),currRing->cf)
+#define nGetNumerator(N)  n_GetNumerator((N),currRing->cf)
+
+#define nSetMap(R)        n_SetMap(R,currRing->cf)
+
+/// only for debug, over any initalized currRing
+#define nPrint(a)         n_Print(a,currRing->cf)
+
+
+
+
+// --------------------------------------------------------------
+// internal to coeffs, but public for all realizations
+
+#define SHORT_REAL_LENGTH 6 // use short reals for real <= 6 digits
+
+/* the dummy routines: */
+// void nDummy1(number* d);
+// void ndDelete(number* d, const coeffs r);
+// number ndGcd(number a, number b, const coeffs);
+// number ndCopy(number a, const coeffs r);
+number ndCopyMap(number a, const coeffs src, const coeffs dst);
+// int ndSize(number a, const coeffs r);
+// number ndGetDenom(number &n, const coeffs r);
+// number ndGetNumerator(number &a,const coeffs r);
+// number ndReturn0(number n, const coeffs r);
+// number ndIntMod(number a, number b, const coeffs r);
+
+// void   ndInpMult(number &a, number b, const coeffs r);
+// void   ndInpAdd(number &a, number b, const coeffs r);
+
+// void ndKillChar(coeffs);
+
+// number  ndInit_bigint(number i, const coeffs dummy, const coeffs dst);
+
+// BOOLEAN ndCoeffIsEqual(const coeffs r, n_coeffType n, void * parameter);
+
+/// Test whether a is a zero divisor in r
+/// i.e. not coprime with char. of r
+/// very inefficient implementation:
+/// should ONLY be used for debug stuff /tests
+BOOLEAN n_IsZeroDivisor( number a, const coeffs r);
+
+const char* const nDivBy0 = "div by 0";
+
+// dummy routines
+// void   ndNormalize(number& d, const coeffs); // nNormalize...
+
+/// initialize an object of type coeff, return FALSE in case of success
+typedef BOOLEAN (*cfInitCharProc)(coeffs, void *);
+n_coeffType nRegister(n_coeffType n, cfInitCharProc p);
+
+/// divide by the first (leading) number and return it, i.e. make monic
+// void ndClearContent(ICoeffsEnumerator& numberCollectionEnumerator, number& c, const coeffs r);
+
+/// does nothing (just returns a dummy one number)
+// void ndClearDenominators(ICoeffsEnumerator& numberCollectionEnumerator, number& d, const coeffs r);
+
+#endif
diff --git a/libpolys/coeffs/numstats.h b/libpolys/coeffs/numstats.h
new file mode 100644
index 0000000..73e1843
--- /dev/null
+++ b/libpolys/coeffs/numstats.h
@@ -0,0 +1,148 @@
+/*! \file coeffs/numstats.h Count number operarions over coefficient rings, fields and other domains suitable for Singular polynomials
+
+  Optional addition for the main interface for Singular coefficients,
+  i.e. to n_[A-Z].* (..., const coeffs) functions
+*/
+#ifndef NUMSTATS_H
+#define NUMSTATS_H
+
+#include <misc/auxiliary.h>
+#include <reporter/reporter.h>
+
+#ifndef HAVE_NUMSTATS
+
+// Nothing will happen if HAVE_NUMSTATS was not defined
+#define ALL_STATISTIC(FUN)
+#define STATISTIC(f) do{}while(0)
+#else
+
+// Otherwise we will treat the following wrappers:
+
+#define ALL_STATISTIC(FUN) \
+    FUN(n_Test); \
+    FUN(n_Size); \
+    FUN(n_Normalize); \
+    FUN(n_NormalizeHelper); \
+    FUN(n_GetChar);  \
+    FUN(n_SetMap); \
+    FUN(n_Delete); \
+    FUN(n_Copy);  \
+    FUN(n_Init); \
+    FUN(n_InitMPZ); \
+    FUN(n_Int); \
+    FUN(n_MPZ); \
+    FUN(n_Invers); \
+    FUN(n_Div); \
+    FUN(n_DivBy); \
+    FUN(n_ExactDiv); \
+    FUN(n_IntMod); \
+    FUN(n_Mult); \
+    FUN(n_InpMult); \
+    FUN(n_Power); \
+    FUN(n_Add); \
+    FUN(n_InpAdd); \
+    FUN(n_Sub); \
+    FUN(n_InpNeg); \
+    FUN(n_Equal); \
+    FUN(n_IsZero); \
+    FUN(n_IsOne); \
+    FUN(n_IsMOne); \
+    FUN(n_GreaterZero); \
+    FUN(n_Greater); \
+    FUN(n_DivComp); \
+    FUN(n_IsUnit); \
+    FUN(n_GetUnit); \
+    FUN(n_CoeffRingQuot1); \
+    FUN(n_Lcm); \
+    FUN(n_Gcd); \
+    FUN(n_ExtGcd); \
+    FUN(n_XExtGcd); \
+    FUN(n_SubringGcd); \
+    FUN(n_EucNorm); \
+    FUN(n_Ann); \
+    FUN(n_QuotRem); \
+    FUN(n_Farey); \
+    FUN(n_ChineseRemainderSym); \
+    FUN(n_RePart); \
+    FUN(n_ImPart); \
+    FUN(n_ParDeg); \
+    FUN(n_Param); \
+    FUN(n_NumberOfParameters); \
+    FUN(n_ParameterNames); \
+    FUN(n_GetDenom); \
+    FUN(n_GetNumerator); \
+    FUN(n_ClearContent); \
+    FUN(n_ClearDenominators); \
+    FUN(n_Read); \
+    FUN(n_Write); \
+    FUN(n_ReadFd); \
+    FUN(n_WriteFd); \
+    FUN(n_WriteLong); \
+    FUN(n_WriteShort); \
+    FUN(nCoeffString); \
+    FUN(nCoeffName); \
+    FUN(nSetChar); \
+    FUN(nKillChar); \
+    FUN(n_convFactoryNSingN); \
+    FUN(n_convSingNFactoryN); \
+    FUN(n_Random); \
+    FUN(n_CoeffWrite)
+
+
+
+struct SNumberStatistic
+{
+  public:
+    SNumberStatistic(){ Init(); }
+
+    inline void Init(const unsigned long defaultvalue = 0)
+    {
+#define _Z(F) this->F = defaultvalue
+      ALL_STATISTIC(_Z);
+      _Z(n_CancelOut);
+#undef _Z
+    }
+
+    inline void Print() const
+    {
+#define _P(F) if(this->F > 0) ::Print("%21s: %13lu\n", # F, this->F)
+      ALL_STATISTIC(_P);
+      _P(n_CancelOut);
+#undef _P
+    }
+
+#define _UL(F) unsigned long F
+    ALL_STATISTIC(_UL);
+    _UL(n_CancelOut);
+#undef _UL
+};
+
+#define STATISTIC(F) {extern struct SNumberStatistic number_stats; number_stats.F += 1;}
+#endif
+
+/// set all counters to zero
+static inline void number_stats_Init(const unsigned long defaultvalue = 0)
+{
+#ifndef HAVE_NUMSTATS
+  WarnS("Please enable NUMSTATS first!");
+  (void)(defaultvalue);
+#else
+  extern struct SNumberStatistic number_stats;
+  number_stats.Init(defaultvalue);
+#endif
+}
+
+/// print out all counters
+static inline void number_stats_Print(const char * const msg = NULL)
+{
+   ::Print("%s:\n", (msg == NULL) ? "Statistic about number operations" : msg);
+#ifndef HAVE_NUMSTATS
+  WarnS("Please enable NUMSTATS first!");
+#else
+  extern struct SNumberStatistic number_stats;
+  number_stats.Print();
+#endif
+  ::PrintLn();
+}
+#endif /* NUMSTAT */
+
diff --git a/libpolys/coeffs/rintegers.cc b/libpolys/coeffs/rintegers.cc
new file mode 100644
index 0000000..00f6cf1
--- /dev/null
+++ b/libpolys/coeffs/rintegers.cc
@@ -0,0 +1,1782 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: numbers (integers)
+*/
+
+#include <misc/auxiliary.h>
+#include <omalloc/omalloc.h>
+
+#include <factory/factory.h>
+
+#include <misc/mylimits.h>
+#include <reporter/reporter.h>
+
+#include "coeffs.h"
+#include "numbers.h"
+
+#include "si_gmp.h"
+
+#include "mpr_complex.h"
+#include "rintegers.h"
+#include "rmodulon.h"
+#include "longrat.h"
+
+#include <string.h>
+
+#ifdef HAVE_RINGS
+
+
+/// Our Type!
+static const n_coeffType ID = n_Z;
+
+number  nrzCopy        (number a, const coeffs r);
+int     nrzSize        (number a, const coeffs r);
+void    nrzDelete      (number *a, const coeffs r);
+BOOLEAN nrzGreaterZero (number k, const coeffs r);
+number  nrzMult        (number a, number b, const coeffs r);
+number  nrzInit        (long i, const coeffs r);
+int     nrzInt         (number &n, const coeffs r);
+number  nrzAdd         (number a, number b, const coeffs r);
+number  nrzSub         (number a, number b, const coeffs r);
+void    nrzPower       (number a, int i, number * result, const coeffs r);
+BOOLEAN nrzIsZero      (number a, const coeffs r);
+BOOLEAN nrzIsOne       (number a, const coeffs r);
+BOOLEAN nrzIsMOne      (number a, const coeffs r);
+BOOLEAN nrzIsUnit      (number a, const coeffs r);
+number  nrzGetUnit     (number a, const coeffs r);
+number  nrzDiv         (number a, number b, const coeffs r);
+number  nrzExactDiv    (number a, number b, const coeffs r);
+number  nrzIntMod      (number a, number b, const coeffs r);
+number  nrzNeg         (number c, const coeffs r);
+number  nrzInvers      (number c, const coeffs r);
+BOOLEAN nrzGreater     (number a, number b, const coeffs r);
+BOOLEAN nrzDivBy       (number a, number b, const coeffs r);
+int     nrzDivComp     (number a, number b, const coeffs r);
+BOOLEAN nrzEqual       (number a, number b, const coeffs r);
+number  nrzLcm         (number a,number b, const coeffs r);
+number  nrzGcd         (number a,number b, const coeffs r);
+number  nrzExtGcd      (number a, number b, number *s, number *t, const coeffs r);
+nMapFunc nrzSetMap     (const coeffs src, const coeffs dst);
+void    nrzWrite       (number &a, const coeffs r);
+const char *  nrzRead  (const char *s, number *a, const coeffs r);
+char *  nrzName        (number n, const coeffs r);
+void    nrzCoeffWrite  (const coeffs r, BOOLEAN details);
+#ifdef LDEBUG
+BOOLEAN nrzDBTest      (number a, const char *f, const int l, const coeffs r);
+#endif
+void    nrzSetExp(int c, coeffs r);
+void    nrzInitExp(int c, coeffs r);
+void    nrzDelete(number *a, const coeffs r);
+coeffs  nrzQuot1(number c, const coeffs r);
+
+//CanonicalForm nrzConvSingNFactoryN(number n, BOOLEAN setChar, const coeffs /*r*/);
+//number nrzConvFactoryNSingN(const CanonicalForm n, const coeffs r);
+
+number nrzMapQ(number from, const coeffs src, const coeffs dst);
+
+
+omBin gmp_nrz_bin = omGetSpecBin(sizeof(mpz_t));
+
+#if SI_INTEGER_VARIANT == 2
+/*
+ * Multiply two numbers
+ */
+number nrzMult (number a, number b, const coeffs)
+{
+  mpz_ptr erg = (mpz_ptr) omAllocBin(gmp_nrz_bin);
+  mpz_init(erg);
+  mpz_mul(erg, (mpz_ptr) a, (mpz_ptr) b);
+  return (number) erg;
+}
+
+/*
+ * Give the smallest non unit k, such that a * x = k = b * y has a solution
+ */
+number nrzLcm (number a,number b,const coeffs)
+{
+  mpz_ptr erg = (mpz_ptr) omAllocBin(gmp_nrz_bin);
+  mpz_init(erg);
+  mpz_lcm(erg, (mpz_ptr) a, (mpz_ptr) b);
+  return (number) erg;
+}
+
+/*
+ * Give the largest non unit k, such that a = x * k, b = y * k has
+ * a solution.
+ */
+number nrzGcd (number a,number b,const coeffs)
+{
+  mpz_ptr erg = (mpz_ptr) omAllocBin(gmp_nrz_bin);
+  mpz_init(erg);
+  mpz_gcd(erg, (mpz_ptr) a, (mpz_ptr) b);
+  return (number) erg;
+}
+
+/*
+ * Give the largest non unit k, such that a = x * k, b = y * k has
+ * a solution and r, s, s.t. k = s*a + t*b
+ */
+number  nrzExtGcd (number a, number b, number *s, number *t, const coeffs)
+{
+  mpz_ptr erg = (mpz_ptr) omAllocBin(gmp_nrz_bin);
+  mpz_ptr bs = (mpz_ptr) omAllocBin(gmp_nrz_bin);
+  mpz_ptr bt = (mpz_ptr) omAllocBin(gmp_nrz_bin);
+  mpz_init(erg);
+  mpz_init(bs);
+  mpz_init(bt);
+  mpz_gcdext(erg, bs, bt, (mpz_ptr) a, (mpz_ptr) b);
+  *s = (number) bs;
+  *t = (number) bt;
+  return (number) erg;
+}
+
+void nrzPower (number a, int i, number * result, const coeffs)
+{
+  mpz_ptr erg = (mpz_ptr) omAllocBin(gmp_nrz_bin);
+  mpz_init(erg);
+  mpz_pow_ui(erg, (mpz_ptr) a, i);
+  *result = (number) erg;
+}
+
+/*
+ * create a number from int
+ */
+number nrzInit (long i, const coeffs)
+{
+  mpz_ptr erg = (mpz_ptr) omAllocBin(gmp_nrz_bin);
+  mpz_init_set_si(erg, i);
+  return (number) erg;
+}
+
+void nrzDelete(number *a, const coeffs)
+{
+  if (*a == NULL) return;
+  mpz_clear((mpz_ptr) *a);
+  omFreeBin((ADDRESS) *a, gmp_nrz_bin);
+  *a = NULL;
+}
+
+number nrzCopy(number a, const coeffs)
+{
+  mpz_ptr erg = (mpz_ptr) omAllocBin(gmp_nrz_bin);
+  mpz_init_set(erg, (mpz_ptr) a);
+  return (number) erg;
+}
+
+#if 0
+number nrzCopyMap(number a, const coeffs /*src*/, const coeffs dst)
+{
+  return nrzCopy(a,dst);
+}
+#endif
+
+int nrzSize(number a, const coeffs)
+{
+  if (a == NULL) return 0;
+  return ((mpz_ptr)a)->_mp_alloc;
+}
+
+/*
+ * convert a number to int
+ */
+int nrzInt(number &n, const coeffs)
+{
+  return (int) mpz_get_si( (mpz_ptr)n);
+}
+
+number nrzAdd (number a, number b, const coeffs)
+{
+  mpz_ptr erg = (mpz_ptr) omAllocBin(gmp_nrz_bin);
+  mpz_init(erg);
+  mpz_add(erg, (mpz_ptr) a, (mpz_ptr) b);
+  return (number) erg;
+}
+
+number nrzSub (number a, number b, const coeffs)
+{
+  mpz_ptr erg = (mpz_ptr) omAllocBin(gmp_nrz_bin);
+  mpz_init(erg);
+  mpz_sub(erg, (mpz_ptr) a, (mpz_ptr) b);
+  return (number) erg;
+}
+
+number  nrzGetUnit (number, const coeffs r)
+{
+  return nrzInit(1, r);
+}
+
+BOOLEAN nrzIsUnit (number a, const coeffs)
+{
+  return 0 == mpz_cmpabs_ui((mpz_ptr) a, 1);
+}
+
+BOOLEAN nrzIsZero (number  a, const coeffs)
+{
+  return 0 == mpz_cmpabs_ui((mpz_ptr) a, 0);
+}
+
+BOOLEAN nrzIsOne (number a, const coeffs)
+{
+  return (a!=NULL) && (0 == mpz_cmp_si((mpz_ptr) a, 1));
+}
+
+BOOLEAN nrzIsMOne (number a, const coeffs)
+{
+  return (a!=NULL) && (0 == mpz_cmp_si((mpz_ptr) a, -1));
+}
+
+BOOLEAN nrzEqual (number a,number b, const coeffs)
+{
+  return 0 == mpz_cmp((mpz_ptr) a, (mpz_ptr) b);
+}
+
+BOOLEAN nrzGreater (number a,number b, const coeffs)
+{
+  return 0 < mpz_cmp((mpz_ptr) a, (mpz_ptr) b);
+}
+
+BOOLEAN nrzGreaterZero (number k, const coeffs)
+{
+  return 0 < mpz_cmp_si((mpz_ptr) k, 0);
+}
+
+int nrzDivComp(number a, number b, const coeffs r)
+{
+  if (nrzDivBy(a, b, r))
+  {
+    if (nrzDivBy(b, a, r)) return 2;
+    return -1;
+  }
+  if (nrzDivBy(b, a, r)) return 1;
+  return 0;
+}
+
+BOOLEAN nrzDivBy (number a,number b, const coeffs)
+{
+  return mpz_divisible_p((mpz_ptr) a, (mpz_ptr) b) != 0;
+}
+
+number nrzDiv (number a,number b, const coeffs R)
+{
+  mpz_ptr erg = (mpz_ptr) omAllocBin(gmp_nrz_bin);
+  mpz_init(erg);
+  mpz_ptr r = (mpz_ptr) omAllocBin(gmp_nrz_bin);
+  mpz_init(r);
+  mpz_tdiv_qr(erg, r, (mpz_ptr) a, (mpz_ptr) b);
+  //if (!nrzIsZero((number) r, R))
+  //{
+  //  WerrorS("Division by non divisible element.");
+  //  WerrorS("Result is without remainder.");
+  //}
+  mpz_clear(r);
+  omFreeBin(r, gmp_nrz_bin);
+  return (number) erg;
+}
+
+number nrzExactDiv (number a,number b, const coeffs)
+{
+  mpz_ptr erg = (mpz_ptr) omAllocBin(gmp_nrz_bin);
+  mpz_init(erg);
+  mpz_tdiv_q(erg, (mpz_ptr) a, (mpz_ptr) b);
+  return (number) erg;
+}
+
+number nrzIntMod (number a,number b, const coeffs)
+{
+  mpz_ptr erg = (mpz_ptr) omAllocBin(gmp_nrz_bin);
+  mpz_init(erg);
+  mpz_ptr r = (mpz_ptr) omAllocBin(gmp_nrz_bin);
+  mpz_init(r);
+  mpz_tdiv_qr(erg, r, (mpz_ptr) a, (mpz_ptr) b);
+  mpz_clear(erg);
+  omFreeBin(erg, gmp_nrz_bin);
+  return (number) r;
+}
+
+number  nrzInvers (number c, const coeffs r)
+{
+  if (!nrzIsUnit((number) c, r))
+  {
+    WerrorS("Non invertible element.");
+    return (number)0; //TODO
+  }
+  return nrzCopy(c,r);
+}
+
+number nrzNeg (number c, const coeffs)
+{
+// nNeg inplace !!!
+  mpz_mul_si((mpz_ptr) c, (mpz_ptr) c, -1);
+  return c;
+}
+
+number nrzMapMachineInt(number from, const coeffs /*src*/, const coeffs /*dst*/)
+{
+  mpz_ptr erg = (mpz_ptr) omAllocBin(gmp_nrz_bin);
+  mpz_init_set_ui(erg, (unsigned long) from);
+  return (number) erg;
+}
+
+number nrzMapZp(number from, const coeffs /*src*/, const coeffs /*dst*/)
+{
+  mpz_ptr erg = (mpz_ptr) omAllocBin(gmp_nrz_bin);
+  mpz_init_set_si(erg, (long) from);
+  return (number) erg;
+}
+
+number nrzMapQ(number from, const coeffs src, const coeffs /*dst*/)
+{
+  mpz_ptr erg = (mpz_ptr) omAllocBin(gmp_nrz_bin);
+  mpz_init(erg);
+  nlGMP(from, (number) erg, src); // FIXME? TODO? // extern void   nlGMP(number &i, number n, const coeffs r); // to be replaced with n_MPZ(erg, from, src); // ?
+  return (number) erg;
+}
+
+nMapFunc nrzSetMap(const coeffs src, const coeffs /*dst*/)
+{
+  /* dst = currRing */
+  if (nCoeff_is_Ring_Z(src) || nCoeff_is_Ring_ModN(src) || nCoeff_is_Ring_PtoM(src))
+  {
+    return ndCopyMap; //nrzCopyMap;
+  }
+  if (nCoeff_is_Ring_2toM(src))
+  {
+    return nrzMapMachineInt;
+  }
+  if (nCoeff_is_Zp(src))
+  {
+    return nrzMapZp;
+  }
+  if (getCoeffType(src)==n_Q /*nCoeff_is_Q(src) or coeffs_BIGINT*/)
+  {
+    return nrzMapQ;
+  }
+  return NULL;      // default
+}
+
+
+/*
+ * set the exponent (allocate and init tables) (TODO)
+ */
+
+void nrzSetExp(int, coeffs)
+{
+}
+
+void nrzInitExp(int, coeffs)
+{
+}
+
+#ifdef LDEBUG
+BOOLEAN nrzDBTest (number, const char *, const int, const coeffs)
+{
+  return TRUE;//TODO
+}
+#endif
+
+void nrzWrite (number &a, const coeffs)
+{
+  char *s,*z;
+  if (a==NULL)
+  {
+    StringAppendS("o");
+  }
+  else
+  {
+    int l=mpz_sizeinbase((mpz_ptr) a, 10) + 2;
+    s=(char*)omAlloc(l);
+    z=mpz_get_str(s,10,(mpz_ptr) a);
+    StringAppendS(z);
+    omFreeSize((ADDRESS)s,l);
+  }
+}
+
+/*2
+* extracts a long integer from s, returns the rest    (COPY FROM longrat0.cc)
+*/
+static const char * nlEatLongC(char *s, mpz_ptr i)
+{
+  const char * start=s;
+
+  if (*s<'0' || *s>'9')
+  {
+    mpz_set_si(i,1);
+    return s;
+  }
+  while (*s >= '0' && *s <= '9') s++;
+  if (*s=='\0')
+  {
+    mpz_set_str(i,start,10);
+  }
+  else
+  {
+    char c=*s;
+    *s='\0';
+    mpz_set_str(i,start,10);
+    *s=c;
+  }
+  return s;
+}
+
+
+static CanonicalForm nrzConvSingNFactoryN(number n, BOOLEAN setChar, const coeffs /*r*/)
+{
+  if (setChar) setCharacteristic( 0 );
+
+  CanonicalForm term;
+  mpz_t num;
+  mpz_init_set(num, *((mpz_t*)n));
+  term = make_cf(num);
+  return term;
+}
+
+static number nrzConvFactoryNSingN(const CanonicalForm n, const coeffs r)
+{
+  if (n.isImm())
+    return nrzInit(n.intval(),r);
+  else
+  {
+    mpz_ptr m = (mpz_ptr) omAllocBin(gmp_nrz_bin);
+    gmp_numerator(n,m);
+    return (number) m;
+  }
+}
+
+const char * nrzRead (const char *s, number *a, const coeffs)
+{
+  mpz_ptr z = (mpz_ptr) omAllocBin(gmp_nrz_bin);
+  {
+    mpz_init(z);
+    s = nlEatLongC((char *) s, z);
+  }
+  *a = (number) z;
+  return s;
+}
+
+void    nrzCoeffWrite  (const coeffs, BOOLEAN /*details*/)
+{
+  PrintS("//   coeff. ring is : Integers\n");
+}
+
+static char* nrzCoeffString(const coeffs)
+{
+  return omStrDup("integer");
+}
+
+coeffs nrzQuot1(number c, const coeffs r)
+{
+    int ch = r->cfInt(c, r);
+    mpz_ptr dummy;
+    dummy = (mpz_ptr) omAlloc(sizeof(mpz_t));
+    mpz_init_set_ui(dummy, ch);
+    ZnmInfo info;
+    info.base = dummy;
+    info.exp = (unsigned long) 1;
+    coeffs rr = nInitChar(n_Zn, (void*)&info);
+    return(rr);
+}
+
+BOOLEAN nrzInitChar(coeffs r,  void *)
+{
+  assume( getCoeffType(r) == ID );
+
+  r->is_field=FALSE;
+  r->is_domain=TRUE;
+  r->rep=n_rep_gmp;
+
+  //r->nCoeffIsEqual = ndCoeffIsEqual;
+  r->cfCoeffString = nrzCoeffString;
+  //r->cfKillChar = ndKillChar;
+  r->cfMult  = nrzMult;
+  r->cfSub   = nrzSub;
+  r->cfAdd   = nrzAdd;
+  r->cfDiv   = nrzDiv;
+  r->cfIntMod= nrzIntMod;
+  r->cfExactDiv= nrzExactDiv;
+  r->cfInit = nrzInit;
+  r->cfSize  = nrzSize;
+  r->cfInt  = nrzInt;
+  //#ifdef HAVE_RINGS
+  r->cfDivComp = nrzDivComp; // only for ring stuff
+  r->cfIsUnit = nrzIsUnit; // only for ring stuff
+  r->cfGetUnit = nrzGetUnit; // only for ring stuff
+  r->cfExtGcd = nrzExtGcd; // only for ring stuff
+  r->cfDivBy = nrzDivBy; // only for ring stuff
+  //#endif
+  r->cfInpNeg   = nrzNeg;
+  r->cfInvers= nrzInvers;
+  r->cfCopy  = nrzCopy;
+  r->cfWriteLong = nrzWrite;
+  r->cfRead = nrzRead;
+  r->cfGreater = nrzGreater;
+  r->cfEqual = nrzEqual;
+  r->cfIsZero = nrzIsZero;
+  r->cfIsOne = nrzIsOne;
+  r->cfIsMOne = nrzIsMOne;
+  r->cfGreaterZero = nrzGreaterZero;
+  r->cfPower = nrzPower;
+  r->cfGcd  = nrzGcd;
+  r->cfLcm  = nrzLcm;
+  r->cfDelete= nrzDelete;
+  r->cfSetMap = nrzSetMap;
+  r->cfCoeffWrite = nrzCoeffWrite;
+  r->cfQuot1 = nrzQuot1;
+  r->convSingNFactoryN=nrzConvSingNFactoryN;
+  r->convFactoryNSingN=nrzConvFactoryNSingN;
+  // debug stuff
+
+#ifdef LDEBUG
+  r->cfDBTest=nrzDBTest;
+#endif
+
+  r->nNULL = 0;
+  r->ch = 0;
+  r->has_simple_Alloc=FALSE;
+  r->has_simple_Inverse=FALSE;
+  return FALSE;
+}
+
+#elif SI_INTEGER_VARIANT == 3
+
+//make sure that a small number is an immediate integer
+//bascially coped from longrat.cc nlShort3
+//TODO: is there any point in checking 0 first???
+//TODO: it is not clear that this works in 32/64 bit everywhere.
+//      too many hacks.
+#ifdef LDEBUG
+#define nrzTest(A) nrzDBTest(A,__FILE__,__LINE__,NULL)
+BOOLEAN nrzDBTest (number x, const char *f, const int l, const coeffs);
+#else
+#define nrzTest(A)
+#endif
+
+#define CF_DEBUG 0
+static inline number nrz_short(number x)
+{
+#if CF_DEBUG
+  StringAppendS("short(");
+  nrzWrite(x, NULL);
+#endif
+  if (mpz_cmp_ui((mpz_ptr) x,(long)0)==0)
+  {
+    mpz_clear((mpz_ptr)x);
+    omFreeBin(x, gmp_nrz_bin);
+#if CF_DEBUG
+    StringAppendS(")=0");
+#endif
+    return INT_TO_SR(0);
+  }
+  if (mpz_size1((mpz_ptr)x)<=MP_SMALL)
+  {
+    int ui=mpz_get_si((mpz_ptr)x);
+    if ((((ui<<3)>>3)==ui)
+    && (mpz_cmp_si((mpz_ptr)x,(long)ui)==0))
+    {
+      mpz_clear((mpz_ptr)x);
+      omFreeBin(x, gmp_nrz_bin);
+#if CF_DEBUG
+    StringAppendS(")=imm");
+#endif
+      return INT_TO_SR(ui);
+    }
+  }
+#if CF_DEBUG
+  StringAppendS(")");
+#endif
+  return x;
+}
+
+
+int nrzSize(number a, const coeffs)
+{
+  if (a == NULL) return 0;
+  if (n_Z_IS_SMALL(a)) return 1;
+  return ((mpz_ptr)a)->_mp_alloc;
+}
+
+
+/*
+ * Multiply two numbers
+ * check for 0, 1, -1 maybe
+ */
+#if CF_DEBUG
+number _nrzMult(number, number, const coeffs);
+number nrzMult(number a, number b, const coeffs R)
+{
+  StringSetS("Mult: ");
+  nrzWrite(a, R);
+  StringAppendS(" by ");
+  nrzWrite(b, R);
+  number c = _nrzMult(a, b, R);
+  StringAppendS(" is ");
+  nrzWrite(c, R);
+  char * s = StringEndS();
+  Print("%s\n", s);
+  omFree(s);
+  return c;
+}
+number _nrzMult (number a, number b, const coeffs R)
+#else
+number nrzMult (number a, number b, const coeffs R)
+#endif
+{
+  if (n_Z_IS_SMALL(a) && n_Z_IS_SMALL(b)) {
+  //from longrat.cc
+    if (SR_TO_INT(a)==0)
+      return a;
+    if (SR_TO_INT(b)==0)
+      return b;
+    long r=(long)((unsigned long)(SR_HDL(a)-1L))*((unsigned long)(SR_HDL(b)>>1));
+    if ((r/(SR_HDL(b)>>1))==(SR_HDL(a)-1L))
+    {
+      number u=((number) ((r>>1)+SR_INT));
+    //  if (((((long)SR_HDL(u))<<1)>>1)==SR_HDL(u)) return (u);
+      return nrzInit(SR_HDL(u)>>2, R);
+    }
+    mpz_ptr erg = (mpz_ptr) omAllocBin(gmp_nrz_bin);
+    mpz_init(erg);
+    mpz_set_si(erg, SR_TO_INT(a));
+    mpz_mul_si(erg, erg, SR_TO_INT(b));
+    nrzTest((number)erg);
+    return (number) erg;
+  }
+  else if (n_Z_IS_SMALL(a))
+  {
+    if (SR_TO_INT(a)==0)
+      return a;
+    mpz_ptr erg = (mpz_ptr) omAllocBin(gmp_nrz_bin);
+    mpz_init_set(erg, (mpz_ptr) b);
+    mpz_mul_si(erg, erg, SR_TO_INT(a));
+    nrzTest((number)erg);
+    return (number) erg;
+  }
+  else if (n_Z_IS_SMALL(b))
+  {
+    if (SR_TO_INT(b)==0)
+      return b;
+    mpz_ptr erg = (mpz_ptr) omAllocBin(gmp_nrz_bin);
+    mpz_init_set(erg, (mpz_ptr) a);
+    mpz_mul_si(erg, erg, SR_TO_INT(b));
+    nrzTest((number)erg);
+    return (number) erg;
+  }
+  else
+  {
+    mpz_ptr erg = (mpz_ptr) omAllocBin(gmp_nrz_bin);
+    mpz_init(erg);
+    mpz_mul(erg, (mpz_ptr) a, (mpz_ptr) b);
+    nrzTest((number)erg);
+    return (number) erg;
+  }
+}
+
+
+static int int_gcd(int a, int b)
+{
+  int r;
+  a = ABS(a);
+  b = ABS(b);
+  if (!a) return b;
+  if (!b) return a;
+  do
+  {
+    r = a % b;
+    a = b;
+    b = r;
+  } while (b);
+  return ABS(a); // % in c doeas not imply a signn
+                 // it would be unlikely to see a negative here
+                 // but who knows
+}
+
+/*
+ * Give the smallest non unit k, such that a * x = k = b * y has a solution
+ */
+number nrzLcm (number a, number b, const coeffs R)
+{
+  PrintS("nrzLcm\n");
+  mpz_ptr erg;
+  if (n_Z_IS_SMALL(a) && n_Z_IS_SMALL(b))
+  {
+    int g = int_gcd(SR_TO_INT(a), SR_TO_INT(b));
+    return nrzMult(a, INT_TO_SR(SR_TO_INT(b)/g), R);
+  }
+  else
+  {
+    erg = (mpz_ptr) omAllocBin(gmp_nrz_bin);
+    if (n_Z_IS_SMALL(a))
+    {
+      mpz_init_set(erg, (mpz_ptr) b);
+      unsigned long g = mpz_gcd_ui(NULL, erg, (unsigned long) ABS(SR_TO_INT(a)));
+      mpz_mul_si(erg, erg, SR_TO_INT(a)/g);
+    }
+    else if (n_Z_IS_SMALL(b))
+    {
+      mpz_init_set(erg, (mpz_ptr) a);
+      unsigned long g = mpz_gcd_ui(NULL, erg, (unsigned long) ABS(SR_TO_INT(b)));
+      mpz_mul_si(erg, erg, SR_TO_INT(b)/g);
+    }
+    else
+    {
+      mpz_init(erg);
+      mpz_lcm(erg, (mpz_ptr) a, (mpz_ptr) b);
+    }
+  }
+  return (number) erg;
+}
+
+/*
+ * Give the largest non unit k, such that a = x * k, b = y * k has
+ * a solution.
+ */
+number nrzGcd (number a,number b,const coeffs R)
+{
+  if (n_Z_IS_SMALL(a) && n_Z_IS_SMALL(b))
+  {
+    int g = int_gcd(SR_TO_INT(a), SR_TO_INT(b));
+    return INT_TO_SR(g);
+  }
+  else if (n_Z_IS_SMALL(a))
+  {
+    if (a==INT_TO_SR(0))
+      return nrzCopy(b, R);
+    unsigned long g = mpz_gcd_ui(NULL, (mpz_ptr)b, (unsigned long) ABS(SR_TO_INT(a)));
+    return INT_TO_SR( g);
+  }
+  else if (n_Z_IS_SMALL(b))
+  {
+    if (b==INT_TO_SR(0))
+      return nrzCopy(a, R);
+    unsigned long g = mpz_gcd_ui(NULL, (mpz_ptr)a, (unsigned long) ABS(SR_TO_INT(b)));
+    return INT_TO_SR(g);
+  }
+  else
+  {
+    mpz_ptr erg = (mpz_ptr) omAllocBin(gmp_nrz_bin);
+    mpz_init(erg);
+    mpz_gcd(erg, (mpz_ptr) a, (mpz_ptr) b);
+    return (number) erg;
+  }
+}
+
+/*
+ * Give the largest non unit k, such that a = x * k, b = y * k has
+ * a solution and r, s, s.t. k = s*a + t*b
+ */
+static int int_extgcd(int a, int b, int * u, int* x, int * v, int* y)
+{
+  int q, r;
+  if (!a)
+  {
+    *u = 0;
+    *v = 1;
+    *x = -1;
+    *y = 0;
+    return b;
+  }
+  if (!b)
+  {
+    *u = 1;
+    *v = 0;
+    *x = 0;
+    *y = 1;
+    return a;
+  }
+  *u=1;
+  *v=0;
+  *x=0;
+  *y=1;
+  do
+  {
+    q = a/b;
+    r = a%b;
+    assume (q*b+r == a);
+    a = b;
+    b = r;
+
+    r = -(*v)*q+(*u);
+    (*u) =(*v);
+    (*v) = r;
+
+    r = -(*y)*q+(*x);
+    (*x) = (*y);
+    (*y) = r;
+  } while (b);
+
+  return a;
+}
+
+number  nrzExtGcd (number a, number b, number *s, number *t, const coeffs)
+{
+  if (n_Z_IS_SMALL(a) && n_Z_IS_SMALL(b))
+  {
+    int u, v, x, y;
+    int g = int_extgcd(SR_TO_INT(a), SR_TO_INT(b), &u, &v, &x, &y);
+    *s = INT_TO_SR(u);
+    *t = INT_TO_SR(v);
+    return INT_TO_SR(g);
+  }
+  else
+  {
+    mpz_t aa, bb;
+    if (n_Z_IS_SMALL(a))
+    {
+      mpz_init_set_si(aa, SR_TO_INT(a));
+    }
+    else
+    {
+      mpz_init_set(aa, (mpz_ptr) a);
+    }
+    if (n_Z_IS_SMALL(b))
+    {
+      mpz_init_set_si(bb, SR_TO_INT(b));
+    }
+    else
+    {
+      mpz_init_set(bb, (mpz_ptr) b);
+    }
+    mpz_ptr erg = (mpz_ptr) omAllocBin(gmp_nrz_bin);
+    mpz_ptr bs = (mpz_ptr) omAllocBin(gmp_nrz_bin);
+    mpz_ptr bt = (mpz_ptr) omAllocBin(gmp_nrz_bin);
+    mpz_init(erg);
+    mpz_init(bs);
+    mpz_init(bt);
+    mpz_gcdext(erg, bs, bt, aa, bb);
+    *s = nrz_short((number) bs);
+    *t = nrz_short((number) bt);
+    mpz_clear(aa);
+    mpz_clear(bb);
+    return nrz_short((number) erg);
+  }
+}
+#if CF_DEBUG
+number _nrzXExtGcd(number, number, number *, number *, number *, number *, const coeffs);
+number nrzXExtGcd(number a, number b, number *x, number * y, number * u, number * v, const coeffs R)
+{
+  char * s;
+  StringSetS("XExtGcd: ");
+  nrzWrite(a, R);
+  StringAppendS(" by ");
+  nrzWrite(b, R);
+  number c = _nrzXExtGcd(a, b, x, y, u, v, R);
+  StringAppendS(" is ");
+  nrzWrite(c, R);
+  StringAppendS("[[");
+  nrzWrite(*x, R);
+  StringAppendS(", ");
+  nrzWrite(*y, R);
+  StringAppendS("], ");
+  nrzWrite(*u, R);
+  StringAppendS(", ");
+  nrzWrite(*v, R);
+  s=StringEndS();
+  Print("%s]]\n", s);
+  omFree(s);
+  return c;
+}
+number  _nrzXExtGcd (number a, number b, number *s, number *t, number *u, number *v, const coeffs )
+#else
+number  nrzXExtGcd (number a, number b, number *s, number *t, number *u, number *v, const coeffs )
+#endif
+{
+  if (n_Z_IS_SMALL(a) && n_Z_IS_SMALL(b))
+  {
+    int uu, vv, x, y;
+    int g = int_extgcd(SR_TO_INT(a), SR_TO_INT(b), &uu, &vv, &x, &y);
+    *s = INT_TO_SR(uu);
+    *t = INT_TO_SR(vv);
+    *u = INT_TO_SR(x);
+    *v = INT_TO_SR(y);
+    return INT_TO_SR(g);
+  }
+  else
+  {
+    mpz_t aa, bb;
+    if (n_Z_IS_SMALL(a))
+    {
+      mpz_init_set_si(aa, SR_TO_INT(a));
+    }
+    else
+    {
+      mpz_init_set(aa, (mpz_ptr) a);
+    }
+    if (n_Z_IS_SMALL(b))
+    {
+      mpz_init_set_si(bb, SR_TO_INT(b));
+    }
+    else
+    {
+      mpz_init_set(bb, (mpz_ptr) b);
+    }
+    mpz_ptr erg = (mpz_ptr) omAllocBin(gmp_nrz_bin);
+    mpz_ptr bs = (mpz_ptr) omAllocBin(gmp_nrz_bin);
+    mpz_ptr bt = (mpz_ptr) omAllocBin(gmp_nrz_bin);
+    mpz_init(erg);
+    mpz_init(bs);
+    mpz_init(bt);
+
+    mpz_gcdext(erg, bs, bt, aa, bb);
+
+    mpz_ptr bu = (mpz_ptr) omAllocBin(gmp_nrz_bin);
+    mpz_ptr bv = (mpz_ptr) omAllocBin(gmp_nrz_bin);
+
+    mpz_init_set(bu, (mpz_ptr) bb);
+    mpz_init_set(bv, (mpz_ptr) aa);
+
+    mpz_clear(aa);
+    mpz_clear(bb);
+    assume(mpz_cmp_si(erg, 0));
+
+    mpz_div(bu, bu, erg);
+    mpz_div(bv, bv, erg);
+
+    mpz_mul_si(bu, bu, -1);
+    *u = nrz_short((number) bu);
+    *v = nrz_short((number) bv);
+
+    *s = nrz_short((number) bs);
+    *t = nrz_short((number) bt);
+    return nrz_short((number) erg);
+  }
+}
+#if CF_DEBUG
+number _nrzQuotRem(number, number, number *, const coeffs);
+number nrzQuotRem(number a, number b, number * r, const coeffs R)
+{
+  StringSetS("QuotRem: ");
+  nrzWrite(a, R);
+  StringAppendS(" by ");
+  nrzWrite(b, R);
+  number c = _nrzQuotRem(a, b, r, R);
+  StringAppendS(" is ");
+  nrzWrite(c, R);
+  if (r) {
+    StringAppendS("+R(");
+    nrzWrite(*r, R);
+    StringAppendS(")");
+  }
+  char * s = StringEndS();
+  Print("%s\n", s);
+  omFree(s);
+  return c;
+}
+number _nrzQuotRem (number a, number b, number * r, const coeffs )
+#else
+number nrzQuotRem (number a, number b, number * r, const coeffs )
+#endif
+{
+  assume(SR_TO_INT(b));
+  if (n_Z_IS_SMALL(a) && n_Z_IS_SMALL(b))
+  {
+    if (r)
+      *r = INT_TO_SR(SR_TO_INT(a) % SR_TO_INT(b));
+    return INT_TO_SR(SR_TO_INT(a)/SR_TO_INT(b));
+  }
+  else if (n_Z_IS_SMALL(a))
+  {
+    //a is small, b is not, so q=0, r=a
+    if (r)
+      *r = a;
+    return INT_TO_SR(0);
+  }
+  else if (n_Z_IS_SMALL(b))
+  {
+    unsigned long rr;
+    mpz_ptr qq = (mpz_ptr) omAllocBin(gmp_nrz_bin);
+    mpz_init(qq);
+    mpz_t rrr;
+    mpz_init(rrr);
+    rr = mpz_divmod_ui(qq, rrr, (mpz_ptr) a, (unsigned long)ABS(SR_TO_INT(b)));
+    mpz_clear(rrr);
+
+    if (r)
+      *r = INT_TO_SR(rr);
+    if (SR_TO_INT(b)<0)
+    {
+      mpz_mul_si(qq, qq, -1);
+    }
+    return nrz_short((number)qq);
+  }
+  mpz_ptr qq = (mpz_ptr) omAllocBin(gmp_nrz_bin),
+             rr = (mpz_ptr) omAllocBin(gmp_nrz_bin);
+  mpz_init(qq);
+  mpz_init(rr);
+  mpz_divmod(qq, rr, (mpz_ptr)a, (mpz_ptr)b);
+  if (r)
+    *r = (number) rr;
+  else
+  {
+    mpz_clear(rr);
+  }
+  nrzTest((number)qq);
+  return (number) qq;
+}
+
+
+void nrzPower (number a, int i, number * result, const coeffs)
+{
+  mpz_ptr erg = (mpz_ptr) omAllocBin(gmp_nrz_bin);
+  mpz_init(erg);
+  mpz_t aa;
+  if (n_Z_IS_SMALL(a))
+    mpz_init_set_si(aa, SR_TO_INT(a));
+  else
+    mpz_init_set(aa, (mpz_ptr) a);
+  mpz_pow_ui(erg, aa, i);
+  *result = nrz_short((number) erg);
+}
+
+/*
+ * create a number from int
+ * TODO: do not create an mpz if not necessary
+ */
+number nrzInit (long i, const coeffs)
+{
+  mpz_ptr erg = (mpz_ptr) omAllocBin(gmp_nrz_bin);
+  mpz_init_set_si(erg, i);
+  return nrz_short((number) erg);
+}
+
+void nrzDelete(number *a, const coeffs)
+{
+  if (*a == NULL) return;
+  if (n_Z_IS_SMALL(*a)==0)
+  {
+    mpz_clear((mpz_ptr) *a);
+    omFreeBin((ADDRESS) *a, gmp_nrz_bin);
+  }
+  *a = NULL;
+}
+
+number nrzCopy(number a, const coeffs)
+{
+  if (n_Z_IS_SMALL(a)) return a;
+  mpz_ptr erg = (mpz_ptr) omAllocBin(gmp_nrz_bin);
+  mpz_init_set(erg, (mpz_ptr) a);
+  return (number) erg;
+}
+
+int nrzSize(number a, const coeffs)
+{
+  if (a == NULL) return 0;
+  if (n_Z_IS_SMALL(a)) return 1;
+  return mpz_size1((mpz_ptr)a)+1;
+}
+
+/*
+ * convert a number to int
+ */
+int nrzInt(number &n, const coeffs)
+{
+  if (n_Z_IS_SMALL(n)) return SR_TO_INT(n);
+  return (int) mpz_get_si( (mpz_ptr)n);
+}
+#if CF_DEBUG
+number _nrzAdd(number, number, const coeffs);
+number nrzAdd(number a, number b, const coeffs R)
+{
+  StringSetS("Add: ");
+  nrzWrite(a, R);
+  StringAppendS(" to ");
+  nrzWrite(b, R);
+  number c = _nrzAdd(a, b, R);
+  StringAppendS(" is ");
+  nrzWrite(c, R);
+  char * s = StringEndS();
+  Print("%s\n", s);
+  omFree(s);
+  return c;
+}
+number _nrzAdd (number a, number b, const coeffs )
+#else
+number nrzAdd (number a, number b, const coeffs )
+#endif
+{
+  if (n_Z_IS_SMALL(a) && n_Z_IS_SMALL(b))
+  {
+    int c = SR_TO_INT(a) + SR_TO_INT(b);
+    if (INT_IS_SMALL(c))
+      return INT_TO_SR(c);
+    mpz_ptr erg = (mpz_ptr) omAllocBin(gmp_nrz_bin);
+    mpz_init_set_si(erg, c);
+
+    nrzTest((number)erg);
+    return (number) erg;
+  }
+  else if (n_Z_IS_SMALL(a))
+  {
+    mpz_ptr erg = (mpz_ptr) omAllocBin(gmp_nrz_bin);
+    mpz_init(erg);
+    if (SR_TO_INT(a)>0)
+      mpz_add_ui(erg, (mpz_ptr) b, (unsigned long)SR_TO_INT(a));
+    else
+      mpz_sub_ui(erg, (mpz_ptr) b, (unsigned long)-(SR_TO_INT(a)));
+    return nrz_short((number) erg);
+  }
+  else if (n_Z_IS_SMALL(b))
+  {
+    mpz_ptr erg = (mpz_ptr) omAllocBin(gmp_nrz_bin);
+    mpz_init(erg);
+    if (SR_TO_INT(b)>0)
+      mpz_add_ui(erg, (mpz_ptr) a, (unsigned long)SR_TO_INT(b));
+    else
+      mpz_sub_ui(erg, (mpz_ptr) a, (unsigned long)-(SR_TO_INT(b)));
+    return nrz_short((number) erg);
+  }
+  else
+  {
+    mpz_ptr erg = (mpz_ptr) omAllocBin(gmp_nrz_bin);
+    mpz_init(erg);
+    mpz_add(erg, (mpz_ptr) a, (mpz_ptr) b);
+    return nrz_short((number) erg);
+  }
+}
+
+number nrzSub (number a, number b,  const coeffs )
+{
+  if (n_Z_IS_SMALL(a) && n_Z_IS_SMALL(b))
+  {
+    int c = SR_TO_INT(a) - SR_TO_INT(b);
+    if (INT_IS_SMALL(c))
+      return INT_TO_SR(c);
+    mpz_ptr erg = (mpz_ptr) omAllocBin(gmp_nrz_bin);
+    mpz_init_set_si(erg, c);
+    nrzTest((number)erg);
+    return (number) erg;
+  }
+  else if (n_Z_IS_SMALL(a))
+  {
+    mpz_ptr erg = (mpz_ptr) omAllocBin(gmp_nrz_bin);
+    mpz_init(erg);
+
+    if (SR_TO_INT(a)>0)
+      mpz_ui_sub(erg, (unsigned long)SR_TO_INT(a), (mpz_ptr) b);
+    else
+    {
+      mpz_add_ui(erg, (mpz_ptr) b, (unsigned long)-SR_TO_INT(a));
+      mpz_neg(erg, erg);
+    }
+    return nrz_short((number) erg);
+  }
+  else if (n_Z_IS_SMALL(b))
+  {
+    mpz_ptr erg = (mpz_ptr) omAllocBin(gmp_nrz_bin);
+    mpz_init(erg);
+    if (SR_TO_INT(b)>0)
+      mpz_sub_ui(erg, (mpz_ptr) a, (unsigned long)SR_TO_INT(b));
+    else
+      mpz_add_ui(erg, (mpz_ptr) a, (unsigned long)-SR_TO_INT(b));
+    return nrz_short((number) erg);
+  }
+  else
+  {
+    mpz_ptr erg = (mpz_ptr) omAllocBin(gmp_nrz_bin);
+    mpz_init(erg);
+    mpz_sub(erg, (mpz_ptr) a, (mpz_ptr) b);
+    return nrz_short((number) erg);
+  }
+}
+
+number  nrzGetUnit (number n, const coeffs r)
+{
+  if (nrzGreaterZero(n, r))
+    return INT_TO_SR(1);
+  else
+    return INT_TO_SR(-1);
+}
+
+number nrzAnn(number n, const coeffs)
+{
+  if (SR_TO_INT(n))  // in Z: the annihilator of !=0 is 0
+    return INT_TO_SR(0);
+  else
+    return INT_TO_SR(1);
+}
+
+BOOLEAN nrzIsUnit (number a, const coeffs)
+{
+  return ABS(SR_TO_INT(a))==1;
+}
+
+BOOLEAN nrzIsZero (number  a, const coeffs)
+{
+  return a==INT_TO_SR(0);
+}
+
+BOOLEAN nrzIsOne (number a, const coeffs)
+{
+  return a==INT_TO_SR(1);
+}
+
+BOOLEAN nrzIsMOne (number a, const coeffs)
+{
+  return a==INT_TO_SR(-1);
+}
+
+BOOLEAN nrzEqual (number a,number b, const coeffs)
+{
+  if (n_Z_IS_SMALL(a) && n_Z_IS_SMALL(b))
+    return a==b;
+  else if (n_Z_IS_SMALL(a) || n_Z_IS_SMALL(b))
+    return FALSE;
+  else
+    return 0 == mpz_cmp((mpz_ptr) a, (mpz_ptr) b);
+}
+
+BOOLEAN nrzGreater (number a,number b, const coeffs)
+{
+  if (n_Z_IS_SMALL(a) && n_Z_IS_SMALL(b))
+    return ((long)a)>((long)b);
+  else if (n_Z_IS_SMALL(a))
+    return 0 > mpz_cmp_si((mpz_ptr)b,SR_TO_INT(a));
+  else if (n_Z_IS_SMALL(b))
+    return 0 < mpz_cmp_si((mpz_ptr)a,SR_TO_INT(b));
+  return 0 < mpz_cmp((mpz_ptr) a, (mpz_ptr) b);
+}
+
+BOOLEAN nrzGreaterZero (number k, const coeffs C)
+{
+  return nrzGreater(k, INT_TO_SR(0), C);
+}
+
+int nrzDivComp(number a, number b, const coeffs r)
+{
+  if (nrzDivBy(a, b, r))
+  {
+    if (nrzDivBy(b, a, r)) return 2;
+    return -1;
+  }
+  if (nrzDivBy(b, a, r)) return 1;
+  return 0;
+}
+
+BOOLEAN nrzDivBy (number a,number b, const coeffs)
+{
+  if (n_Z_IS_SMALL(a) && n_Z_IS_SMALL(b))
+  {
+    return SR_TO_INT(a) %SR_TO_INT(b) ==0;
+  }
+  else if (n_Z_IS_SMALL(a))
+  {
+    return a==INT_TO_SR(0);
+  }
+  else if (n_Z_IS_SMALL(b))
+  {
+    return mpz_divisible_ui_p((mpz_ptr)a, (unsigned long)ABS(SR_TO_INT(b))) != 0;
+  }
+  else
+    return mpz_divisible_p((mpz_ptr) a, (mpz_ptr) b) != 0;
+}
+
+number nrzDiv (number a,number b, const coeffs)
+{
+  assume(SR_TO_INT(b));
+  if (n_Z_IS_SMALL(a) && n_Z_IS_SMALL(b))
+  {
+    //if (SR_TO_INT(a) % SR_TO_INT(b))
+    //{
+    //  WerrorS("1:Division by non divisible element.");
+    //  WerrorS("Result is without remainder.");
+    //}
+    return INT_TO_SR(SR_TO_INT(a)/SR_TO_INT(b));
+  }
+  else if (n_Z_IS_SMALL(a))
+  {
+    //if (SR_TO_INT(a))
+    //{
+    //  WerrorS("2:Division by non divisible element.");
+    //  WerrorS("Result is without remainder.");
+    //}
+    return INT_TO_SR(0);
+  }
+  else if (n_Z_IS_SMALL(b))
+  {
+    mpz_ptr erg = (mpz_ptr) omAllocBin(gmp_nrz_bin);
+    mpz_t r;
+    mpz_init(r);
+    mpz_init(erg);
+    if (mpz_divmod_ui(erg, r, (mpz_ptr) a, (unsigned long)ABS(SR_TO_INT(b)))) {
+    //  WerrorS("3:Division by non divisible element.");
+    //  WerrorS("Result is without remainder.");
+    }
+    mpz_clear(r);
+    if (SR_TO_INT(b)<0)
+      mpz_neg(erg, erg);
+    return nrz_short((number) erg);
+  }
+  mpz_ptr erg = (mpz_ptr) omAllocBin(gmp_nrz_bin);
+  mpz_init(erg);
+  mpz_t r;
+  mpz_init(r);
+  mpz_tdiv_qr(erg, r, (mpz_ptr) a, (mpz_ptr) b);
+#if CF_DEBUG
+  StringSetS("division of");
+  nrzWrite(a, R);
+  StringAppendS(" by ");
+  nrzWrite(b, R);
+  StringAppendS(" is ");
+  number du;
+  nrzWrite(du = (number)erg, R);
+  StringAppendS(" rest ");
+  nrzWrite(du = (number)r, R);
+  char * s = StringEndS();
+  Print("%s\n", s);
+  omFree(s);
+#endif
+
+  if (mpz_cmp_si(r, 0)!=0)
+  {
+    //WerrorS("4:Division by non divisible element.");
+    //WerrorS("Result is without remainder.");
+  }
+  mpz_clear(r);
+  return nrz_short((number) erg);
+}
+
+number nrzExactDiv (number a,number b, const coeffs)
+{
+  assume(SR_TO_INT(b));
+  mpz_t aa, bb;
+  if (n_Z_IS_SMALL(a))
+    mpz_init_set_si(aa, SR_TO_INT(a));
+  else
+    mpz_init_set(aa, (mpz_ptr) a);
+  if (n_Z_IS_SMALL(b))
+    mpz_init_set_si(bb, SR_TO_INT(b));
+  else
+    mpz_init_set(bb, (mpz_ptr) b);
+  mpz_ptr erg = (mpz_ptr) omAllocBin(gmp_nrz_bin);
+  mpz_init(erg);
+  mpz_tdiv_q(erg, (mpz_ptr) aa, (mpz_ptr) bb);
+  mpz_clear(aa);
+  mpz_clear(bb);
+  nrzTest((number)erg);
+  return (number) erg;
+}
+
+number nrzIntMod (number a,number b, const coeffs)
+{
+  mpz_t aa, bb;
+  assume(SR_TO_INT(b));
+  if (n_Z_IS_SMALL(a))
+    mpz_init_set_si(aa, SR_TO_INT(a));
+  else
+    mpz_init_set(aa, (mpz_ptr) a);
+  if (n_Z_IS_SMALL(b))
+    mpz_init_set_si(bb, SR_TO_INT(b));
+  else
+    mpz_init_set(bb, (mpz_ptr) b);
+
+  mpz_t erg;
+  mpz_init(erg);
+  mpz_ptr r = (mpz_ptr) omAllocBin(gmp_nrz_bin);
+  mpz_init(r);
+  mpz_tdiv_qr(erg, r, (mpz_ptr) aa, (mpz_ptr) bb);
+  mpz_clear(erg);
+  mpz_clear(aa);
+  mpz_clear(bb);
+
+  return nrz_short((number) r);
+}
+
+number  nrzInvers (number c, const coeffs r)
+{
+  if (!nrzIsUnit((number) c, r))
+  {
+    WerrorS("Non invertible element.");
+    return (number)0; //TODO
+  }
+  return c; // has to be 1 or -1....
+}
+
+number nrzNeg (number c, const coeffs)
+{
+// nNeg inplace !!!
+  if (n_Z_IS_SMALL(c))
+    return INT_TO_SR(-SR_TO_INT(c));
+  mpz_mul_si((mpz_ptr) c, (mpz_ptr) c, -1);
+  return c;
+}
+
+static number nrzFarey(number r, number N, const coeffs R)
+{
+  number a0 = nrzCopy(N, R);
+  number b0 = nrzInit(0, R);
+  number a1 = nrzCopy(r, R);
+  number b1 = nrzInit(1, R);
+  number two = nrzInit(2, R);
+#if 0
+  Print("Farey start with ");
+  n_Print(r, R);
+  Print(" mod ");
+  n_Print(N, R);
+  Print("\n");
+#endif
+  while (1)
+  {
+    number as = nrzMult(a1, a1, R);
+    n_InpMult(as, two, R);
+    if (nrzGreater(N, as, R))
+    {
+      nrzDelete(&as, R);
+      break;
+    }
+    nrzDelete(&as, R);
+    number q = nrzDiv(a0, a1, R);
+    number t = nrzMult(a1, q, R),
+           s = nrzSub(a0, t, R);
+    nrzDelete(&a0, R);
+    a0 = a1;
+    a1 = s;
+    nrzDelete(&t, R);
+
+    t = nrzMult(b1, q, R);
+    s = nrzSub(b0, t, R);
+    nrzDelete(&b0, R);
+    b0 = b1;
+    b1 = s;
+    nrzDelete(&t, R);
+    nrzDelete(&q, R);
+  }
+  number as = nrzMult(b1, b1, R);
+  n_InpMult(as, two, R);
+  nrzDelete(&two, R);
+  if (nrzGreater(as, N, R))
+  {
+    nrzDelete(&a0, R);
+    nrzDelete(&a1, R);
+    nrzDelete(&b0, R);
+    nrzDelete(&b1, R);
+    nrzDelete(&as, R);
+    return NULL;
+  }
+  nrzDelete(&as, R);
+  nrzDelete(&a0, R);
+  nrzDelete(&b0, R);
+
+  number a, b, ab;
+  coeffs Q = nInitChar(n_Q, 0);
+  nMapFunc f = n_SetMap(R, Q);
+  a = f(a1, R, Q);
+  b = f(b1, R, Q);
+  ab = n_Div(a, b, Q);
+  n_Delete(&a, Q);
+  n_Delete(&b, Q);
+  nKillChar(Q);
+
+  nrzDelete(&a1, R);
+  nrzDelete(&b1, R);
+  return ab;
+}
+
+number nrzMapMachineInt(number from, const coeffs /*src*/, const coeffs /*dst*/)
+{
+  mpz_ptr erg = (mpz_ptr) omAllocBin(gmp_nrz_bin);
+  mpz_init_set_ui(erg, (unsigned long) from);
+  return nrz_short((number) erg);
+}
+
+number nrzMapZp(number from, const coeffs /*src*/, const coeffs /*dst*/)
+{
+  mpz_ptr erg = (mpz_ptr) omAllocBin(gmp_nrz_bin);
+  mpz_init_set_si(erg, (long) from);
+  return nrz_short((number) erg);
+}
+
+number nrzModNMap(number from, const coeffs /* src */, const coeffs /*dst*/)
+{
+  mpz_ptr erg = (mpz_ptr) omAllocBin(gmp_nrz_bin);
+  mpz_init_set(erg, (mpz_ptr) from);
+  return nrz_short((number) erg);
+}
+
+number nrzMapQ(number from, const coeffs /* src */, const coeffs dst)
+{
+  if (SR_HDL(from) & SR_INT)
+    return nrzInit(SR_TO_INT(from),dst);
+  if (from->s!=3)
+  {
+    WerrorS("rational in map to integer");
+    return NULL;
+  }
+  mpz_ptr erg = (mpz_ptr) omAllocBin(gmp_nrz_bin);
+  mpz_init_set(erg, from->z);
+  return nrz_short((number) erg);
+}
+
+nMapFunc nrzSetMap(const coeffs src, const coeffs /*dst*/)
+{
+  /* dst = rintegers */
+  if (src->rep==n_rep_gmp) //nCoeff_is_Ring_ModN(src) || nCoeff_is_Ring_PtoM(src))
+    return nrzModNMap;
+
+  if ((src->rep==n_rep_gap_gmp) && nCoeff_is_Ring_Z(src))
+  {
+    return ndCopyMap; //nrzCopyMap;
+  }
+  if (src->rep==n_rep_gap_rat) /*&& nCoeff_is_Ring_Z(src)) Q, bigint*/
+  {
+    return nrzMapQ;
+  }
+  if ((src->rep==n_rep_int) && nCoeff_is_Ring_2toM(src))
+  {
+    return nrzMapMachineInt;
+  }
+  if ((src->rep==n_rep_int) && nCoeff_is_Zp(src))
+  {
+    return nrzMapZp;
+  }
+  return NULL;      // default
+}
+
+
+/*
+ * set the exponent (allocate and init tables) (TODO)
+ */
+
+void nrzSetExp(int, coeffs)
+{
+}
+
+void nrzInitExp(int, coeffs)
+{
+}
+
+#ifdef LDEBUG
+BOOLEAN nrzDBTest (number x, const char *f, const int l, const coeffs)
+{
+  if (SR_HDL(x) & SR_INT) return TRUE;
+  if (mpz_cmp_ui((mpz_ptr) x,(long)0)==0)
+  {
+    Print("gmp-0 %s:%d\n",f,l);
+    return FALSE;
+  }
+  if (mpz_size1((mpz_ptr)x)<=MP_SMALL)
+  {
+    int ui=mpz_get_si((mpz_ptr)x);
+    if ((((ui<<3)>>3)==ui)
+    && (mpz_cmp_si((mpz_ptr)x,(long)ui)==0))
+    {
+      Print("gmp-small %s:%d\n",f,l);
+      return FALSE;
+    }
+  }
+  return TRUE;
+}
+#endif
+
+void nrzWrite (number &a, const coeffs)
+{
+  char *s,*z;
+  if (a==NULL)
+  {
+    StringAppendS("o");
+  }
+  else
+  {
+    if (n_Z_IS_SMALL(a))
+    {
+      StringAppend("%d", SR_TO_INT(a));
+    }
+    else
+    {
+      int l=mpz_sizeinbase((mpz_ptr) a, 10) + 2;
+      s=(char*)omAlloc(l);
+      z=mpz_get_str(s,10,(mpz_ptr) a);
+      StringAppendS(z);
+      omFreeSize((ADDRESS)s,l);
+    }
+  }
+}
+
+/*2
+* extracts a long integer from s, returns the rest    (COPY FROM longrat0.cc)
+*/
+static const char * nlEatLongC(char *s, mpz_ptr i)
+{
+  const char * start=s;
+
+  if (*s<'0' || *s>'9')
+  {
+    mpz_set_si(i,1);
+    return s;
+  }
+  while (*s >= '0' && *s <= '9') s++;
+  if (*s=='\0')
+  {
+    mpz_set_str(i,start,10);
+  }
+  else
+  {
+    char c=*s;
+    *s='\0';
+    mpz_set_str(i,start,10);
+    *s=c;
+  }
+  return s;
+}
+
+const char * nrzRead (const char *s, number *a, const coeffs)
+{
+  mpz_ptr z = (mpz_ptr) omAllocBin(gmp_nrz_bin);
+  {
+    mpz_init(z);
+    s = nlEatLongC((char *) s, z);
+  }
+  *a = nrz_short((number) z);
+  return s;
+}
+
+void    nrzCoeffWrite  (const coeffs, BOOLEAN /*details*/)
+{
+  //PrintS("// ZZ\n");
+  PrintS("//   coeff. ring is : Integers\n");
+}
+
+static char* nrzCoeffString(const coeffs)
+{
+  return omStrDup("integer");
+}
+
+static CanonicalForm nrzConvSingNFactoryN( number n, BOOLEAN setChar, const coeffs /*r*/ )
+{
+  if (setChar) setCharacteristic( 0 );
+
+  CanonicalForm term;
+  if ( n_Z_IS_SMALL(n))
+  {
+    term = SR_TO_INT(n);
+  }
+  else
+  {
+    mpz_t dummy;
+    mpz_init_set( dummy,n->z );
+    term = make_cf( dummy );
+  }
+  return term;
+}
+
+static number nrzConvFactoryNSingN( const CanonicalForm n, const coeffs r)
+{
+  if (n.isImm())
+  {
+    return nrzInit(n.intval(),r);
+  }
+  else
+  {
+    if ( !n.den().isOne() )
+    {
+     WerrorS("rational in conversion to integer");
+     return NULL;
+    }
+    mpz_ptr z = (mpz_ptr) omAlloc0Bin(gmp_nrz_bin);
+    gmp_numerator( n,z);
+    return nrz_short((number)z);
+  }
+}
+
+static void nrzMPZ(mpz_t res, number &a, const coeffs)
+{
+  if (n_Z_IS_SMALL(a))
+    mpz_init_set_si(res, SR_TO_INT(a));
+  else
+    mpz_init_set(res, (mpz_ptr) a);
+}
+
+coeffs nrzQuot1(number c, const coeffs r)
+{
+    mpz_ptr dummy;
+    dummy = (mpz_ptr) omAlloc(sizeof(mpz_t));
+    if(n_Z_IS_SMALL(c))
+    {
+      int ch = r->cfInt(c, r);
+      mpz_init_set_ui(dummy, ch);
+    }
+    else
+    {
+      mpz_init_set(dummy, (mpz_ptr)c);
+    }
+    ZnmInfo info;
+    info.base = dummy;
+    info.exp = (unsigned long) 1;
+    coeffs rr = nInitChar(n_Zn, (void*)&info);
+    return(rr);
+}
+
+BOOLEAN nrzInitChar(coeffs r,  void *)
+{
+  assume( getCoeffType(r) == ID );
+
+  r->is_field=FALSE;
+  r->is_domain=TRUE;
+  r->rep=n_rep_gap_gmp;
+
+  //r->nCoeffIsEqual = ndCoeffIsEqual;
+  r->cfCoeffString = nrzCoeffString;
+  //r->cfKillChar = ndKillChar;
+  r->cfMult  = nrzMult;
+  r->cfSub   = nrzSub;
+  r->cfAdd   = nrzAdd;
+  r->cfDiv   = nrzDiv;
+  r->cfIntMod= nrzIntMod;
+  r->cfExactDiv= nrzExactDiv;
+  r->cfInit = nrzInit;
+  r->cfSize  = nrzSize;
+  r->cfInt  = nrzInt;
+  //#ifdef HAVE_RINGS
+  r->cfDivComp = nrzDivComp; // only for ring stuff
+  r->cfIsUnit = nrzIsUnit; // only for ring stuff
+  r->cfGetUnit = nrzGetUnit; // only for ring stuff
+  r->cfAnn = nrzAnn;
+  r->cfExtGcd = nrzExtGcd; // only for ring stuff
+  r->cfXExtGcd = nrzXExtGcd; // only for ring stuff
+  r->cfQuotRem = nrzQuotRem;
+  r->cfDivBy = nrzDivBy; // only for ring stuff
+  //#endif
+  r->cfInpNeg   = nrzNeg;
+  r->cfInvers= nrzInvers;
+  r->cfCopy  = nrzCopy;
+  r->cfWriteLong = nrzWrite;
+  r->cfRead = nrzRead;
+  r->cfGreater = nrzGreater;
+  r->cfEqual = nrzEqual;
+  r->cfIsZero = nrzIsZero;
+  r->cfIsOne = nrzIsOne;
+  r->cfIsMOne = nrzIsMOne;
+  r->cfGreaterZero = nrzGreaterZero;
+  r->cfPower = nrzPower;
+  r->cfGcd  = nrzGcd;
+  r->cfLcm  = nrzLcm;
+  r->cfDelete= nrzDelete;
+  r->cfSetMap = nrzSetMap;
+  r->cfCoeffWrite = nrzCoeffWrite;
+  r->convSingNFactoryN = nrzConvSingNFactoryN;
+  r->convFactoryNSingN = nrzConvFactoryNSingN;
+  r->cfMPZ = nrzMPZ;
+  r->cfFarey = nrzFarey;
+
+  r->cfQuot1 = nrzQuot1;
+  // debug stuff
+
+#ifdef LDEBUG
+  r->cfDBTest=nrzDBTest;
+#endif
+
+  r->nNULL = 0;
+  r->ch = 0;
+  r->has_simple_Alloc=FALSE;
+  r->has_simple_Inverse=FALSE;
+  return FALSE;
+}
+
+#elif SI_INTEGER_VARIANT == 1
+BOOLEAN nrzInitChar(coeffs r,  void *)
+{
+  return nlInitChar(r,(void*)1);
+}
+#else
+#error set SI_INTEGER_VARIANT
+#endif
+#endif
diff --git a/libpolys/coeffs/rintegers.h b/libpolys/coeffs/rintegers.h
new file mode 100644
index 0000000..bab7c17
--- /dev/null
+++ b/libpolys/coeffs/rintegers.h
@@ -0,0 +1,33 @@
+#ifndef RINTEGERS_H
+#define RINTEGERS_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: numbers modulo n
+*/
+#include <misc/auxiliary.h>
+#include <coeffs/coeffs.h>
+
+#ifdef HAVE_RINGS
+
+#if SI_INTEGER_VARIANT == 3
+#define SR_HDL(A) ((long)(A))
+#define SR_INT    1L
+#define INT_TO_SR(INT)  ((number) (((long)INT << 2) + SR_INT))
+#define SR_TO_INT(SR)   (((long)SR) >> 2)
+#define n_Z_IS_SMALL(A)     (SR_HDL(A) & SR_INT)
+#define INT_IS_SMALL(A) ( ((A << 1) >> 1) == A )
+#endif
+
+//extern int nrzExp;
+//extern unsigned long nrzModul;
+
+BOOLEAN nrzInitChar    (coeffs r,  void * parameter);
+
+// will be reused by rmodulon.cc
+void    nrzWrite       (number &a, const coeffs r);
+
+#endif
+
+#endif
diff --git a/libpolys/coeffs/rmodulo2m.cc b/libpolys/coeffs/rmodulo2m.cc
new file mode 100644
index 0000000..23238e2
--- /dev/null
+++ b/libpolys/coeffs/rmodulo2m.cc
@@ -0,0 +1,877 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: numbers modulo 2^m
+*/
+#include <misc/auxiliary.h>
+
+#include <omalloc/omalloc.h>
+
+#include <misc/mylimits.h>
+#include <reporter/reporter.h>
+
+#include "si_gmp.h"
+#include "coeffs.h"
+#include "numbers.h"
+#include "longrat.h"
+#include "mpr_complex.h"
+
+#include "rmodulo2m.h"
+#include "rmodulon.h"
+
+#include <string.h>
+
+#ifdef HAVE_RINGS
+
+/// Our Type!
+static const n_coeffType ID = n_Z2m;
+
+number  nr2mCopy        (number a, const coeffs r);
+BOOLEAN nr2mGreaterZero (number k, const coeffs r);
+number  nr2mMult        (number a, number b, const coeffs r);
+number  nr2mInit        (long i, const coeffs r);
+int     nr2mInt         (number &n, const coeffs r);
+number  nr2mAdd         (number a, number b, const coeffs r);
+number  nr2mSub         (number a, number b, const coeffs r);
+void    nr2mPower       (number a, int i, number * result, const coeffs r);
+BOOLEAN nr2mIsZero      (number a, const coeffs r);
+BOOLEAN nr2mIsOne       (number a, const coeffs r);
+BOOLEAN nr2mIsMOne      (number a, const coeffs r);
+BOOLEAN nr2mIsUnit      (number a, const coeffs r);
+number  nr2mGetUnit     (number a, const coeffs r);
+number  nr2mDiv         (number a, number b, const coeffs r);
+number  nr2mIntDiv      (number a,number b, const coeffs r);
+number  nr2mMod         (number a,number b, const coeffs r);
+number  nr2mNeg         (number c, const coeffs r);
+number  nr2mInvers      (number c, const coeffs r);
+BOOLEAN nr2mGreater     (number a, number b, const coeffs r);
+BOOLEAN nr2mDivBy       (number a, number b, const coeffs r);
+int     nr2mDivComp     (number a, number b, const coeffs r);
+BOOLEAN nr2mEqual       (number a, number b, const coeffs r);
+number  nr2mLcm         (number a, number b, const coeffs r);
+number  nr2mGcd         (number a, number b, const coeffs r);
+number  nr2mExtGcd      (number a, number b, number *s, number *t, const coeffs r);
+nMapFunc nr2mSetMap     (const coeffs src, const coeffs dst);
+void    nr2mWrite       (number &a, const coeffs r);
+const char *  nr2mRead  (const char *s, number *a, const coeffs r);
+char *  nr2mName        (number n, const coeffs r);
+void    nr2mCoeffWrite  (const coeffs r, BOOLEAN details);
+coeffs  nr2mQuot1(number c, const coeffs r);
+#ifdef LDEBUG
+BOOLEAN nr2mDBTest      (number a, const char *f, const int l, const coeffs r);
+#endif
+void    nr2mSetExp(int c, const coeffs r);
+void    nr2mInitExp(int c, const coeffs r);
+
+number nr2mMapQ(number from, const coeffs src, const coeffs dst);
+
+static inline number nr2mMultM(number a, number b, const coeffs r)
+{
+  return (number)
+    ((((unsigned long) a) * ((unsigned long) b)) & ((unsigned long)r->mod2mMask));
+}
+
+static inline number nr2mAddM(number a, number b, const coeffs r)
+{
+  return (number)
+    ((((unsigned long) a) + ((unsigned long) b)) & ((unsigned long)r->mod2mMask));
+}
+
+static inline number nr2mSubM(number a, number b, const coeffs r)
+{
+  return (number)((unsigned long)a < (unsigned long)b ?
+                       r->mod2mMask - (unsigned long)b + (unsigned long)a + 1:
+                       (unsigned long)a - (unsigned long)b);
+}
+
+#define nr2mNegM(A,r) (number)((r->mod2mMask - (unsigned long)(A) + 1) & r->mod2mMask)
+#define nr2mEqualM(A,B)  ((A)==(B))
+
+extern omBin gmp_nrz_bin; /* init in rintegers*/
+
+void    nr2mCoeffWrite  (const coeffs r, BOOLEAN /*details*/)
+{
+  PrintS("//   coeff. ring is : ");
+  Print("Z/2^%lu\n", r->modExponent);
+}
+
+BOOLEAN nr2mCoeffIsEqual(const coeffs r, n_coeffType n, void * p)
+{
+  if (n==n_Z2m)
+  {
+    int m=(int)(long)(p);
+    unsigned long mm=r->mod2mMask;
+    if (((mm+1)>>m)==1L) return TRUE;
+  }
+  return FALSE;
+}
+
+static char* nr2mCoeffString(const coeffs r)
+{
+  char* s = (char*) omAlloc(11+11);
+  sprintf(s,"integer,2,%lu",r->modExponent);
+  return s;
+}
+
+coeffs nr2mQuot1(number c, const coeffs r)
+{
+    coeffs rr;
+    int ch = r->cfInt(c, r);
+    mpz_t a,b;
+    mpz_init_set(a, r->modNumber);
+    mpz_init_set_ui(b, ch);
+    mpz_ptr gcd;
+    gcd = (mpz_ptr) omAlloc(sizeof(mpz_t));
+    mpz_init(gcd);
+    mpz_gcd(gcd, a,b);
+    if(mpz_cmp_ui(gcd, 1) == 0)
+        {
+            WerrorS("constant in q-ideal is coprime to modulus in ground ring");
+            WerrorS("Unable to create qring!");
+            return NULL;
+        }
+    if(mpz_cmp_ui(gcd, 2) == 0)
+    {
+        rr = nInitChar(n_Zp, (void*)2);
+    }
+    else
+    {
+        ZnmInfo info;
+        info.base = r->modBase;
+        int kNew = 1;
+        mpz_t baseTokNew;
+        mpz_init(baseTokNew);
+        mpz_set(baseTokNew, r->modBase);
+        while(mpz_cmp(gcd, baseTokNew) > 0)
+        {
+          kNew++;
+          mpz_mul(baseTokNew, baseTokNew, r->modBase);
+        }
+        info.exp = kNew;
+        mpz_clear(baseTokNew);
+        rr = nInitChar(n_Z2m, (void*)(long)kNew);
+    }
+    return(rr);
+}
+
+static number nr2mAnn(number b, const coeffs r);
+/* for initializing function pointers */
+BOOLEAN nr2mInitChar (coeffs r, void* p)
+{
+  assume( getCoeffType(r) == ID );
+  nr2mInitExp((int)(long)(p), r);
+
+  r->is_field=FALSE;
+  r->is_domain=FALSE;
+  r->rep=n_rep_int;
+
+  //r->cfKillChar    = ndKillChar; /* dummy*/
+  r->nCoeffIsEqual = nr2mCoeffIsEqual;
+  r->cfCoeffString = nr2mCoeffString;
+
+  r->modBase = (mpz_ptr) omAllocBin (gmp_nrz_bin);
+  mpz_init_set_si (r->modBase, 2L);
+  r->modNumber= (mpz_ptr) omAllocBin (gmp_nrz_bin);
+  mpz_init (r->modNumber);
+  mpz_pow_ui (r->modNumber, r->modBase, r->modExponent);
+
+  /* next cast may yield an overflow as mod2mMask is an unsigned long */
+  r->ch = (int)r->mod2mMask + 1;
+
+  r->cfInit        = nr2mInit;
+  //r->cfCopy        = ndCopy;
+  r->cfInt         = nr2mInt;
+  r->cfAdd         = nr2mAdd;
+  r->cfSub         = nr2mSub;
+  r->cfMult        = nr2mMult;
+  r->cfDiv         = nr2mDiv;
+  r->cfAnn         = nr2mAnn;
+  r->cfIntMod      = nr2mMod;
+  r->cfExactDiv    = nr2mDiv;
+  r->cfInpNeg         = nr2mNeg;
+  r->cfInvers      = nr2mInvers;
+  r->cfDivBy       = nr2mDivBy;
+  r->cfDivComp     = nr2mDivComp;
+  r->cfGreater     = nr2mGreater;
+  r->cfEqual       = nr2mEqual;
+  r->cfIsZero      = nr2mIsZero;
+  r->cfIsOne       = nr2mIsOne;
+  r->cfIsMOne      = nr2mIsMOne;
+  r->cfGreaterZero = nr2mGreaterZero;
+  r->cfWriteLong       = nr2mWrite;
+  r->cfRead        = nr2mRead;
+  r->cfPower       = nr2mPower;
+  r->cfSetMap      = nr2mSetMap;
+//  r->cfNormalize   = ndNormalize; // default
+  r->cfLcm         = nr2mLcm;
+  r->cfGcd         = nr2mGcd;
+  r->cfIsUnit      = nr2mIsUnit;
+  r->cfGetUnit     = nr2mGetUnit;
+  r->cfExtGcd      = nr2mExtGcd;
+  r->cfCoeffWrite  = nr2mCoeffWrite;
+  r->cfQuot1       = nr2mQuot1;
+#ifdef LDEBUG
+  r->cfDBTest      = nr2mDBTest;
+#endif
+  r->has_simple_Alloc=TRUE;
+  return FALSE;
+}
+
+/*
+ * Multiply two numbers
+ */
+number nr2mMult(number a, number b, const coeffs r)
+{
+  if (((unsigned long)a == 0) || ((unsigned long)b == 0))
+    return (number)0;
+  else
+    return nr2mMultM(a, b, r);
+}
+
+/*
+ * Give the smallest k, such that a * x = k = b * y has a solution
+ */
+number nr2mLcm(number a, number b, const coeffs)
+{
+  unsigned long res = 0;
+  if ((unsigned long)a == 0) a = (number) 1;
+  if ((unsigned long)b == 0) b = (number) 1;
+  while ((unsigned long)a % 2 == 0)
+  {
+    a = (number)((unsigned long)a / 2);
+    if ((unsigned long)b % 2 == 0) b = (number)((unsigned long)b / 2);
+    res++;
+  }
+  while ((unsigned long)b % 2 == 0)
+  {
+    b = (number)((unsigned long)b / 2);
+    res++;
+  }
+  return (number)(1L << res);  // (2**res)
+}
+
+/*
+ * Give the largest k, such that a = x * k, b = y * k has
+ * a solution.
+ */
+number nr2mGcd(number a, number b, const coeffs)
+{
+  unsigned long res = 0;
+  if ((unsigned long)a == 0 && (unsigned long)b == 0) return (number)1;
+  while ((unsigned long)a % 2 == 0 && (unsigned long)b % 2 == 0)
+  {
+    a = (number)((unsigned long)a / 2);
+    b = (number)((unsigned long)b / 2);
+    res++;
+  }
+//  if ((unsigned long)b % 2 == 0)
+//  {
+//    return (number)((1L << res)); // * (unsigned long) a);  // (2**res)*a    a is a unit
+//  }
+//  else
+//  {
+    return (number)((1L << res)); // * (unsigned long) b);  // (2**res)*b    b is a unit
+//  }
+}
+
+/*
+ * Give the largest k, such that a = x * k, b = y * k has
+ * a solution.
+ */
+number nr2mExtGcd(number a, number b, number *s, number *t, const coeffs r)
+{
+  unsigned long res = 0;
+  if ((unsigned long)a == 0 && (unsigned long)b == 0) return (number)1;
+  while ((unsigned long)a % 2 == 0 && (unsigned long)b % 2 == 0)
+  {
+    a = (number)((unsigned long)a / 2);
+    b = (number)((unsigned long)b / 2);
+    res++;
+  }
+  if ((unsigned long)b % 2 == 0)
+  {
+    *t = NULL;
+    *s = nr2mInvers(a,r);
+    return (number)((1L << res)); // * (unsigned long) a);  // (2**res)*a    a is a unit
+  }
+  else
+  {
+    *s = NULL;
+    *t = nr2mInvers(b,r);
+    return (number)((1L << res)); // * (unsigned long) b);  // (2**res)*b    b is a unit
+  }
+}
+
+void nr2mPower(number a, int i, number * result, const coeffs r)
+{
+  if (i == 0)
+  {
+    *(unsigned long *)result = 1;
+  }
+  else if (i == 1)
+  {
+    *result = a;
+  }
+  else
+  {
+    nr2mPower(a, i-1, result, r);
+    *result = nr2mMultM(a, *result, r);
+  }
+}
+
+/*
+ * create a number from int
+ */
+number nr2mInit(long i, const coeffs r)
+{
+  if (i == 0) return (number)(unsigned long)i;
+
+  long ii = i;
+  unsigned long j = (unsigned long)1;
+  if (ii < 0) { j = r->mod2mMask; ii = -ii; }
+  unsigned long k = (unsigned long)ii;
+  k = k & r->mod2mMask;
+  /* now we have: i = j * k mod 2^m */
+  return (number)nr2mMult((number)j, (number)k, r);
+}
+
+/*
+ * convert a number to an int in ]-k/2 .. k/2],
+ * where k = 2^m; i.e., an int in ]-2^(m-1) .. 2^(m-1)];
+ * note that the code computes a long which will then
+ * automatically casted to int
+ */
+static long nr2mLong(number &n, const coeffs r)
+{
+  unsigned long nn = (unsigned long)(unsigned long)n & r->mod2mMask;
+  unsigned long l = r->mod2mMask >> 1; l++; /* now: l = 2^(m-1) */
+  if ((unsigned long)nn > l)
+    return (long)((unsigned long)nn - r->mod2mMask - 1);
+  else
+    return (long)((unsigned long)nn);
+}
+int nr2mInt(number &n, const coeffs r)
+{
+  return (int)nr2mLong(n,r);
+}
+
+number nr2mAdd(number a, number b, const coeffs r)
+{
+  return nr2mAddM(a, b, r);
+}
+
+number nr2mSub(number a, number b, const coeffs r)
+{
+  return nr2mSubM(a, b, r);
+}
+
+BOOLEAN nr2mIsUnit(number a, const coeffs)
+{
+  return ((unsigned long)a % 2 == 1);
+}
+
+number nr2mGetUnit(number k, const coeffs)
+{
+  if (k == NULL) return (number)1;
+  unsigned long erg = (unsigned long)k;
+  while (erg % 2 == 0) erg = erg / 2;
+  return (number)erg;
+}
+
+BOOLEAN nr2mIsZero(number a, const coeffs)
+{
+  return 0 == (unsigned long)a;
+}
+
+BOOLEAN nr2mIsOne(number a, const coeffs)
+{
+  return 1 == (unsigned long)a;
+}
+
+BOOLEAN nr2mIsMOne(number a, const coeffs r)
+{
+  return (r->mod2mMask  == (unsigned long)a);
+}
+
+BOOLEAN nr2mEqual(number a, number b, const coeffs)
+{
+  return (a == b);
+}
+
+BOOLEAN nr2mGreater(number a, number b, const coeffs r)
+{
+  return nr2mDivBy(a, b,r);
+}
+
+/* Is 'a' divisible by 'b'? There are two cases:
+   1) a = 0 mod 2^m; then TRUE iff b = 0 or b is a power of 2
+   2) a, b <> 0; then TRUE iff b/gcd(a, b) is a unit mod 2^m */
+BOOLEAN nr2mDivBy (number a, number b, const coeffs r)
+{
+  if (a == NULL)
+  {
+    unsigned long c = r->mod2mMask + 1;
+    if (c != 0) /* i.e., if no overflow */
+      return (c % (unsigned long)b) == 0;
+    else
+    {
+      /* overflow: we need to check whether b
+         is zero or a power of 2: */
+      c = (unsigned long)b;
+      while (c != 0)
+      {
+        if ((c % 2) != 0) return FALSE;
+        c = c >> 1;
+      }
+      return TRUE;
+    }
+  }
+  else
+  {
+    number n = nr2mGcd(a, b, r);
+    n = nr2mDiv(b, n, r);
+    return nr2mIsUnit(n, r);
+  }
+}
+
+int nr2mDivComp(number as, number bs, const coeffs)
+{
+  unsigned long a = (unsigned long)as;
+  unsigned long b = (unsigned long)bs;
+  assume(a != 0 && b != 0);
+  while (a % 2 == 0 && b % 2 == 0)
+  {
+    a = a / 2;
+    b = b / 2;
+  }
+  if (a % 2 == 0)
+  {
+    return -1;
+  }
+  else
+  {
+    if (b % 2 == 1)
+    {
+      return 2;
+    }
+    else
+    {
+      return 1;
+    }
+  }
+}
+
+/* TRUE iff 0 < k <= 2^m / 2 */
+BOOLEAN nr2mGreaterZero(number k, const coeffs r)
+{
+  if ((unsigned long)k == 0) return FALSE;
+  if ((unsigned long)k > ((r->mod2mMask >> 1) + 1)) return FALSE;
+  return TRUE;
+}
+
+/* assumes that 'a' is odd, i.e., a unit in Z/2^m, and computes
+   the extended gcd of 'a' and 2^m, in order to find some 's'
+   and 't' such that a * s + 2^m * t = gcd(a, 2^m) = 1;
+   this code will always find a positive 's' */
+void specialXGCD(unsigned long& s, unsigned long a, const coeffs r)
+{
+  mpz_ptr u = (mpz_ptr)omAlloc(sizeof(mpz_t));
+  mpz_init_set_ui(u, a);
+  mpz_ptr u0 = (mpz_ptr)omAlloc(sizeof(mpz_t));
+  mpz_init(u0);
+  mpz_ptr u1 = (mpz_ptr)omAlloc(sizeof(mpz_t));
+  mpz_init_set_ui(u1, 1);
+  mpz_ptr u2 = (mpz_ptr)omAlloc(sizeof(mpz_t));
+  mpz_init(u2);
+  mpz_ptr v = (mpz_ptr)omAlloc(sizeof(mpz_t));
+  mpz_init_set_ui(v, r->mod2mMask);
+  mpz_add_ui(v, v, 1); /* now: v = 2^m */
+  mpz_ptr v0 = (mpz_ptr)omAlloc(sizeof(mpz_t));
+  mpz_init(v0);
+  mpz_ptr v1 = (mpz_ptr)omAlloc(sizeof(mpz_t));
+  mpz_init(v1);
+  mpz_ptr v2 = (mpz_ptr)omAlloc(sizeof(mpz_t));
+  mpz_init_set_ui(v2, 1);
+  mpz_ptr q = (mpz_ptr)omAlloc(sizeof(mpz_t));
+  mpz_init(q);
+  mpz_ptr rr = (mpz_ptr)omAlloc(sizeof(mpz_t));
+  mpz_init(rr);
+
+  while (mpz_cmp_ui(v, 0) != 0) /* i.e., while v != 0 */
+  {
+    mpz_div(q, u, v);
+    mpz_mod(rr, u, v);
+    mpz_set(u, v);
+    mpz_set(v, rr);
+    mpz_set(u0, u2);
+    mpz_set(v0, v2);
+    mpz_mul(u2, u2, q); mpz_sub(u2, u1, u2); /* u2 = u1 - q * u2 */
+    mpz_mul(v2, v2, q); mpz_sub(v2, v1, v2); /* v2 = v1 - q * v2 */
+    mpz_set(u1, u0);
+    mpz_set(v1, v0);
+  }
+
+  while (mpz_cmp_ui(u1, 0) < 0) /* i.e., while u1 < 0 */
+  {
+    /* we add 2^m = (2^m - 1) + 1 to u1: */
+    mpz_add_ui(u1, u1, r->mod2mMask);
+    mpz_add_ui(u1, u1, 1);
+  }
+  s = mpz_get_ui(u1); /* now: 0 <= s <= 2^m - 1 */
+
+  mpz_clear(u);  omFree((ADDRESS)u);
+  mpz_clear(u0); omFree((ADDRESS)u0);
+  mpz_clear(u1); omFree((ADDRESS)u1);
+  mpz_clear(u2); omFree((ADDRESS)u2);
+  mpz_clear(v);  omFree((ADDRESS)v);
+  mpz_clear(v0); omFree((ADDRESS)v0);
+  mpz_clear(v1); omFree((ADDRESS)v1);
+  mpz_clear(v2); omFree((ADDRESS)v2);
+  mpz_clear(q); omFree((ADDRESS)q);
+  mpz_clear(rr); omFree((ADDRESS)rr);
+}
+
+unsigned long InvMod(unsigned long a, const coeffs r)
+{
+  assume((unsigned long)a % 2 != 0);
+  unsigned long s;
+  specialXGCD(s, a, r);
+  return s;
+}
+//#endif
+
+inline number nr2mInversM(number c, const coeffs r)
+{
+  assume((unsigned long)c % 2 != 0);
+  // Table !!!
+  unsigned long inv;
+  inv = InvMod((unsigned long)c,r);
+  return (number)inv;
+}
+
+number nr2mDiv(number a, number b, const coeffs r)
+{
+  if ((unsigned long)a == 0) return (number)0;
+  else if ((unsigned long)b % 2 == 0)
+  {
+    if ((unsigned long)b != 0)
+    {
+      while (((unsigned long)b % 2 == 0) && ((unsigned long)a % 2 == 0))
+      {
+        a = (number)((unsigned long)a / 2);
+        b = (number)((unsigned long)b / 2);
+      }
+    }
+    if ((unsigned long)b % 2 == 0)
+    {
+      WerrorS("Division not possible, even by cancelling zero divisors.");
+      WerrorS("Result is integer division without remainder.");
+      return (number) ((unsigned long) a / (unsigned long) b);
+    }
+  }
+  return (number)nr2mMult(a, nr2mInversM(b,r),r);
+}
+
+number nr2mMod(number a, number b, const coeffs r)
+{
+  /*
+    We need to return the number rr which is uniquely determined by the
+    following two properties:
+      (1) 0 <= rr < |b| (with respect to '<' and '<=' performed in Z x Z)
+      (2) There exists some k in the integers Z such that a = k * b + rr.
+    Consider g := gcd(2^m, |b|). Note that then |b|/g is a unit in Z/2^m.
+    Now, there are three cases:
+      (a) g = 1
+          Then |b| is a unit in Z/2^m, i.e. |b| (and also b) divides a.
+          Thus rr = 0.
+      (b) g <> 1 and g divides a
+          Then a = (a/g) * (|b|/g)^(-1) * b (up to sign), i.e. again rr = 0.
+      (c) g <> 1 and g does not divide a
+          Let's denote the division with remainder of a by g as follows:
+          a = s * g + t. Then t = a - s * g = a - s * (|b|/g)^(-1) * |b|
+          fulfills (1) and (2), i.e. rr := t is the correct result. Hence
+          in this third case, rr is the remainder of division of a by g in Z.
+    This algorithm is the same as for the case Z/n, except that we may
+    compute the gcd of |b| and 2^m "by hand": We just extract the highest
+    power of 2 (<= 2^m) that is contained in b.
+  */
+  assume((unsigned long) b != 0);
+  unsigned long g = 1;
+  unsigned long b_div = (unsigned long) b;
+
+  /*
+   * b_div is unsigned, so that (b_div < 0) evaluates false at compile-time
+   *
+  if (b_div < 0) b_div = -b_div; // b_div now represents |b|, BUT b_div is unsigned!
+  */
+
+  unsigned long rr = 0;
+  while ((g < r->mod2mMask ) && (b_div > 0) && (b_div % 2 == 0))
+  {
+    b_div = b_div >> 1;
+    g = g << 1;
+  } // g is now the gcd of 2^m and |b|
+
+  if (g != 1) rr = (unsigned long)a % g;
+  return (number)rr;
+}
+
+number nr2mIntDiv(number a, number b, const coeffs r)
+{
+  if ((unsigned long)a == 0)
+  {
+    if ((unsigned long)b == 0)
+      return (number)1;
+    if ((unsigned long)b == 1)
+      return (number)0;
+    unsigned long c = r->mod2mMask + 1;
+    if (c != 0) /* i.e., if no overflow */
+      return (number)(c / (unsigned long)b);
+    else
+    {
+      /* overflow: c = 2^32 resp. 2^64, depending on platform */
+      mpz_ptr cc = (mpz_ptr)omAlloc(sizeof(mpz_t));
+      mpz_init_set_ui(cc, r->mod2mMask); mpz_add_ui(cc, cc, 1);
+      mpz_div_ui(cc, cc, (unsigned long)(unsigned long)b);
+      unsigned long s = mpz_get_ui(cc);
+      mpz_clear(cc); omFree((ADDRESS)cc);
+      return (number)(unsigned long)s;
+    }
+  }
+  else
+  {
+    if ((unsigned long)b == 0)
+      return (number)0;
+    return (number)((unsigned long) a / (unsigned long) b);
+  }
+}
+
+static number nr2mAnn(number b, const coeffs r)
+{
+  if ((unsigned long)b == 0)
+    return NULL;
+  if ((unsigned long)b == 1)
+    return NULL;
+  unsigned long c = r->mod2mMask + 1;
+  if (c != 0) /* i.e., if no overflow */
+    return (number)(c / (unsigned long)b);
+  else
+  {
+    /* overflow: c = 2^32 resp. 2^64, depending on platform */
+    mpz_ptr cc = (mpz_ptr)omAlloc(sizeof(mpz_t));
+    mpz_init_set_ui(cc, r->mod2mMask); mpz_add_ui(cc, cc, 1);
+    mpz_div_ui(cc, cc, (unsigned long)(unsigned long)b);
+    unsigned long s = mpz_get_ui(cc);
+    mpz_clear(cc); omFree((ADDRESS)cc);
+    return (number)(unsigned long)s;
+  }
+}
+
+number nr2mInvers(number c, const coeffs r)
+{
+  if ((unsigned long)c % 2 == 0)
+  {
+    WerrorS("division by zero divisor");
+    return (number)0;
+  }
+  return nr2mInversM(c, r);
+}
+
+number nr2mNeg(number c, const coeffs r)
+{
+  if ((unsigned long)c == 0) return c;
+  return nr2mNegM(c, r);
+}
+
+number nr2mMapMachineInt(number from, const coeffs /*src*/, const coeffs dst)
+{
+  unsigned long i = ((unsigned long)from) % dst->mod2mMask ;
+  return (number)i;
+}
+
+number nr2mMapProject(number from, const coeffs /*src*/, const coeffs dst)
+{
+  unsigned long i = ((unsigned long)from) % (dst->mod2mMask + 1);
+  return (number)i;
+}
+
+number nr2mMapZp(number from, const coeffs /*src*/, const coeffs dst)
+{
+  unsigned long j = (unsigned long)1;
+  long ii = (long)from;
+  if (ii < 0) { j = dst->mod2mMask; ii = -ii; }
+  unsigned long i = (unsigned long)ii;
+  i = i & dst->mod2mMask;
+  /* now we have: from = j * i mod 2^m */
+  return (number)nr2mMult((number)i, (number)j, dst);
+}
+
+number nr2mMapQ(number from, const coeffs src, const coeffs dst)
+{
+  mpz_ptr erg = (mpz_ptr)omAllocBin(gmp_nrz_bin);
+  mpz_init(erg);
+  mpz_ptr k = (mpz_ptr)omAlloc(sizeof(mpz_t));
+  mpz_init_set_ui(k, dst->mod2mMask);
+
+  nlGMP(from, (number)erg, src); // FIXME? TODO? // extern void   nlGMP(number &i, number n, const coeffs r); // to be replaced with n_MPZ(erg, from, src); // ?
+  mpz_and(erg, erg, k);
+  number res = (number)mpz_get_ui(erg);
+
+  mpz_clear(erg); omFree((ADDRESS)erg);
+  mpz_clear(k);   omFree((ADDRESS)k);
+
+  return (number)res;
+}
+
+number nr2mMapGMP(number from, const coeffs /*src*/, const coeffs dst)
+{
+  mpz_ptr erg = (mpz_ptr)omAllocBin(gmp_nrz_bin);
+  mpz_init(erg);
+  mpz_ptr k = (mpz_ptr)omAlloc(sizeof(mpz_t));
+  mpz_init_set_ui(k, dst->mod2mMask);
+
+  mpz_and(erg, (mpz_ptr)from, k);
+  number res = (number) mpz_get_ui(erg);
+
+  mpz_clear(erg); omFree((ADDRESS)erg);
+  mpz_clear(k);   omFree((ADDRESS)k);
+
+  return (number)res;
+}
+
+number nr2mMapZ(number from, const coeffs src, const coeffs dst)
+{
+  if (SR_HDL(from) & SR_INT)
+  {
+    long f_i=SR_TO_INT(from);
+    return nr2mInit(f_i,dst);
+  }
+  return nr2mMapGMP(from,src,dst);
+}
+
+nMapFunc nr2mSetMap(const coeffs src, const coeffs dst)
+{
+  if ((src->rep==n_rep_int) && nCoeff_is_Ring_2toM(src)
+     && (src->mod2mMask == dst->mod2mMask))
+  {
+    return ndCopyMap;
+  }
+  if ((src->rep==n_rep_int) && nCoeff_is_Ring_2toM(src)
+     && (src->mod2mMask < dst->mod2mMask))
+  { /* i.e. map an integer mod 2^s into Z mod 2^t, where t < s */
+    return nr2mMapMachineInt;
+  }
+  if ((src->rep==n_rep_int) && nCoeff_is_Ring_2toM(src)
+     && (src->mod2mMask > dst->mod2mMask))
+  { /* i.e. map an integer mod 2^s into Z mod 2^t, where t > s */
+    // to be done
+    return nr2mMapProject;
+  }
+  if ((src->rep==n_rep_gmp) && nCoeff_is_Ring_Z(src))
+  {
+    return nr2mMapGMP;
+  }
+  if ((src->rep==n_rep_gap_gmp) /*&& nCoeff_is_Ring_Z(src)*/)
+  {
+    return nr2mMapZ;
+  }
+  if ((src->rep==n_rep_gap_rat) && nCoeff_is_Q(src))
+  {
+    return nr2mMapQ;
+  }
+  if ((src->rep==n_rep_int) && nCoeff_is_Zp(src) && (src->ch == 2))
+  {
+    return nr2mMapZp;
+  }
+  if ((src->rep==n_rep_gmp) &&
+  (nCoeff_is_Ring_PtoM(src) || nCoeff_is_Ring_ModN(src)))
+  {
+    if (mpz_divisible_2exp_p(src->modNumber,dst->modExponent))
+      return nr2mMapGMP;
+  }
+  return NULL;      // default
+}
+
+/*
+ * set the exponent
+ */
+
+void nr2mSetExp(int m, coeffs r)
+{
+  if (m > 1)
+  {
+    /* we want mod2mMask to be the bit pattern
+       '111..1' consisting of m one's: */
+    r->modExponent= m;
+    r->mod2mMask = 1;
+    for (int i = 1; i < m; i++) r->mod2mMask = (r->mod2mMask << 1) + 1;
+  }
+  else
+  {
+    r->modExponent= 2;
+    /* code unexpectedly called with m = 1; we continue with m = 2: */
+    r->mod2mMask = 3; /* i.e., '11' in binary representation */
+  }
+}
+
+void nr2mInitExp(int m, coeffs r)
+{
+  nr2mSetExp(m, r);
+  if (m < 2)
+    WarnS("nr2mInitExp unexpectedly called with m = 1 (we continue with Z/2^2");
+}
+
+#ifdef LDEBUG
+BOOLEAN nr2mDBTest (number a, const char *, const int, const coeffs r)
+{
+  //if ((unsigned long)a < 0) return FALSE; // is unsigned!
+  if (((unsigned long)a & r->mod2mMask) != (unsigned long)a) return FALSE;
+  return TRUE;
+}
+#endif
+
+void nr2mWrite (number &a, const coeffs r)
+{
+  long i = nr2mLong(a, r);
+  StringAppend("%ld", i);
+}
+
+static const char* nr2mEati(const char *s, int *i, const coeffs r)
+{
+
+  if (((*s) >= '0') && ((*s) <= '9'))
+  {
+    (*i) = 0;
+    do
+    {
+      (*i) *= 10;
+      (*i) += *s++ - '0';
+      if ((*i) >= (MAX_INT_VAL / 10)) (*i) = (*i) & r->mod2mMask;
+    }
+    while (((*s) >= '0') && ((*s) <= '9'));
+    (*i) = (*i) & r->mod2mMask;
+  }
+  else (*i) = 1;
+  return s;
+}
+
+const char * nr2mRead (const char *s, number *a, const coeffs r)
+{
+  int z;
+  int n=1;
+
+  s = nr2mEati(s, &z,r);
+  if ((*s) == '/')
+  {
+    s++;
+    s = nr2mEati(s, &n,r);
+  }
+  if (n == 1)
+    *a = (number)(long)z;
+  else
+      *a = nr2mDiv((number)(long)z,(number)(long)n,r);
+  return s;
+}
+#endif
+/* #ifdef HAVE_RINGS */
diff --git a/libpolys/coeffs/rmodulo2m.h b/libpolys/coeffs/rmodulo2m.h
new file mode 100644
index 0000000..54eb9e3
--- /dev/null
+++ b/libpolys/coeffs/rmodulo2m.h
@@ -0,0 +1,21 @@
+#ifndef RMODULO2M_H
+#define RMODULO2M_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: numbers modulo 2^m such that 2^m - 1
+*           fits in an unsigned long
+*/
+
+#include <misc/auxiliary.h>
+
+struct n_Procs_s; typedef struct  n_Procs_s  *coeffs;
+struct snumber; typedef struct snumber *   number;
+
+#ifdef HAVE_RINGS
+
+BOOLEAN nr2mInitChar    (coeffs r, void*);
+
+#endif
+#endif
diff --git a/libpolys/coeffs/rmodulon.cc b/libpolys/coeffs/rmodulon.cc
new file mode 100644
index 0000000..1f9b38c
--- /dev/null
+++ b/libpolys/coeffs/rmodulon.cc
@@ -0,0 +1,983 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: numbers modulo n
+*/
+#include <misc/auxiliary.h>
+#include <omalloc/omalloc.h>
+
+#include <misc/mylimits.h>
+#include <reporter/reporter.h>
+
+#include "si_gmp.h"
+#include "coeffs.h"
+#include "numbers.h"
+
+#include "mpr_complex.h"
+
+#include "longrat.h"
+#include "rmodulon.h"
+
+#include <string.h>
+
+#ifdef HAVE_RINGS
+
+/// Our Type!
+static const n_coeffType ID = n_Zn;
+static const n_coeffType ID2 = n_Znm;
+
+number  nrnCopy        (number a, const coeffs r);
+int     nrnSize        (number a, const coeffs r);
+void    nrnDelete      (number *a, const coeffs r);
+BOOLEAN nrnGreaterZero (number k, const coeffs r);
+number  nrnMult        (number a, number b, const coeffs r);
+number  nrnInit        (long i, const coeffs r);
+int     nrnInt         (number &n, const coeffs r);
+number  nrnAdd         (number a, number b, const coeffs r);
+number  nrnSub         (number a, number b, const coeffs r);
+void    nrnPower       (number a, int i, number * result, const coeffs r);
+BOOLEAN nrnIsZero      (number a, const coeffs r);
+BOOLEAN nrnIsOne       (number a, const coeffs r);
+BOOLEAN nrnIsMOne      (number a, const coeffs r);
+BOOLEAN nrnIsUnit      (number a, const coeffs r);
+number  nrnGetUnit     (number a, const coeffs r);
+number  nrnAnn         (number a, const coeffs r);
+number  nrnDiv         (number a, number b, const coeffs r);
+number  nrnMod         (number a,number b, const coeffs r);
+number  nrnIntDiv      (number a,number b, const coeffs r);
+number  nrnNeg         (number c, const coeffs r);
+number  nrnInvers      (number c, const coeffs r);
+BOOLEAN nrnGreater     (number a, number b, const coeffs r);
+BOOLEAN nrnDivBy       (number a, number b, const coeffs r);
+int     nrnDivComp     (number a, number b, const coeffs r);
+BOOLEAN nrnEqual       (number a, number b, const coeffs r);
+number  nrnLcm         (number a,number b, const coeffs r);
+number  nrnGcd         (number a,number b, const coeffs r);
+number  nrnExtGcd      (number a, number b, number *s, number *t, const coeffs r);
+number  nrnXExtGcd      (number a, number b, number *s, number *t, number *u, number *v, const coeffs r);
+number  nrnQuotRem      (number a, number b, number *s, const coeffs r);
+nMapFunc nrnSetMap     (const coeffs src, const coeffs dst);
+#if SI_INTEGER_VARIANT==2
+// FIXME? TODO? // extern void    nrzWrite       (number &a, const coeffs r); // FIXME
+# define  nrnWrite      nrzWrite
+#else
+void nrnWrite (number &a, const coeffs);
+#endif
+const char *  nrnRead  (const char *s, number *a, const coeffs r);
+void     nrnCoeffWrite (const coeffs r, BOOLEAN details);
+#ifdef LDEBUG
+BOOLEAN nrnDBTest      (number a, const char *f, const int l, const coeffs r);
+#endif
+void    nrnSetExp(unsigned long c, const coeffs r);
+void    nrnInitExp(unsigned long c, const coeffs r);
+coeffs  nrnQuot1(number c, const coeffs r);
+
+number nrnMapQ(number from, const coeffs src, const coeffs dst);
+
+
+extern omBin gmp_nrz_bin;
+
+void    nrnCoeffWrite  (const coeffs r, BOOLEAN /*details*/)
+{
+  long l = (long)mpz_sizeinbase(r->modBase, 10) + 2;
+  char* s = (char*) omAlloc(l);
+  s= mpz_get_str (s, 10, r->modBase);
+  if (nCoeff_is_Ring_ModN(r)) Print("//   coeff. ring is : Z/%s\n", s);
+  else if (nCoeff_is_Ring_PtoM(r)) Print("//   coeff. ring is : Z/%s^%lu\n", s, r->modExponent);
+  omFreeSize((ADDRESS)s, l);
+}
+
+static BOOLEAN nrnCoeffsEqual(const coeffs r, n_coeffType n, void * parameter)
+{
+  /* test, if r is an instance of nInitCoeffs(n,parameter) */
+  return (n==n_Zn) && (mpz_cmp_ui(r->modNumber,(long)parameter)==0);
+}
+
+static char* nrnCoeffString(const coeffs r)
+{
+  long l = (long)mpz_sizeinbase(r->modBase, 10) +2;
+  char* b = (char*) omAlloc(l);
+  b= mpz_get_str (b, 10, r->modBase);
+  char* s = (char*) omAlloc(7+2+10+l);
+  if (nCoeff_is_Ring_ModN(r)) sprintf(s,"integer,%s",b);
+  else /*if (nCoeff_is_Ring_PtoM(r))*/ sprintf(s,"integer,%s^%lu",b,r->modExponent);
+  omFreeSize(b,l);
+  return s;
+}
+
+static void nrnKillChar(coeffs r)
+{
+  mpz_clear(r->modNumber);
+  mpz_clear(r->modBase);
+  omFreeBin((void *) r->modBase, gmp_nrz_bin);
+  omFreeBin((void *) r->modNumber, gmp_nrz_bin);
+}
+
+coeffs nrnQuot1(number c, const coeffs r)
+{
+    coeffs rr;
+    int ch = r->cfInt(c, r);
+    mpz_t a,b;
+    mpz_init_set(a, r->modNumber);
+    mpz_init_set_ui(b, ch);
+    mpz_ptr gcd;
+    gcd = (mpz_ptr) omAlloc(sizeof(mpz_t));
+    mpz_init(gcd);
+    mpz_gcd(gcd, a,b);
+    if(mpz_cmp_ui(gcd, 1) == 0)
+        {
+            WerrorS("constant in q-ideal is coprime to modulus in ground ring");
+            WerrorS("Unable to create qring!");
+            return NULL;
+        }
+    if(r->modExponent == 1)
+    {
+        ZnmInfo info;
+        info.base = gcd;
+        info.exp = (unsigned long) 1;
+        rr = nInitChar(n_Zn, (void*)&info);
+    }
+    else
+    {
+        ZnmInfo info;
+        info.base = r->modBase;
+        int kNew = 1;
+        mpz_t baseTokNew;
+        mpz_init(baseTokNew);
+        mpz_set(baseTokNew, r->modBase);
+        while(mpz_cmp(gcd, baseTokNew) > 0)
+        {
+          kNew++;
+          mpz_mul(baseTokNew, baseTokNew, r->modBase);
+        }
+        //printf("\nkNew = %i\n",kNew);
+        info.exp = kNew;
+        mpz_clear(baseTokNew);
+        rr = nInitChar(n_Znm, (void*)&info);
+    }
+    return(rr);
+}
+
+/* for initializing function pointers */
+BOOLEAN nrnInitChar (coeffs r, void* p)
+{
+  assume( (getCoeffType(r) == ID) || (getCoeffType (r) == ID2) );
+  ZnmInfo * info= (ZnmInfo *) p;
+  r->modBase= (mpz_ptr)nrnCopy((number)info->base, r); //this circumvents the problem
+  //in bigintmat.cc where we cannot create a "legal" nrn that can be freed.
+  //If we take a copy, we can do whatever we want.
+
+  nrnInitExp (info->exp, r);
+
+  /* next computation may yield wrong characteristic as r->modNumber
+     is a GMP number */
+  r->ch = mpz_get_ui(r->modNumber);
+
+  r->is_field=FALSE;
+  r->is_domain=FALSE;
+  r->rep=n_rep_gmp;
+
+
+  r->cfCoeffString = nrnCoeffString;
+
+  r->cfInit        = nrnInit;
+  r->cfDelete      = nrnDelete;
+  r->cfCopy        = nrnCopy;
+  r->cfSize        = nrnSize;
+  r->cfInt         = nrnInt;
+  r->cfAdd         = nrnAdd;
+  r->cfSub         = nrnSub;
+  r->cfMult        = nrnMult;
+  r->cfDiv         = nrnDiv;
+  r->cfAnn         = nrnAnn;
+  r->cfIntMod      = nrnMod;
+  r->cfExactDiv    = nrnDiv;
+  r->cfInpNeg         = nrnNeg;
+  r->cfInvers      = nrnInvers;
+  r->cfDivBy       = nrnDivBy;
+  r->cfDivComp     = nrnDivComp;
+  r->cfGreater     = nrnGreater;
+  r->cfEqual       = nrnEqual;
+  r->cfIsZero      = nrnIsZero;
+  r->cfIsOne       = nrnIsOne;
+  r->cfIsMOne      = nrnIsMOne;
+  r->cfGreaterZero = nrnGreaterZero;
+  r->cfWriteLong   = nrnWrite;
+  r->cfRead        = nrnRead;
+  r->cfPower       = nrnPower;
+  r->cfSetMap      = nrnSetMap;
+  //r->cfNormalize   = ndNormalize;
+  r->cfLcm         = nrnLcm;
+  r->cfGcd         = nrnGcd;
+  r->cfIsUnit      = nrnIsUnit;
+  r->cfGetUnit     = nrnGetUnit;
+  r->cfExtGcd      = nrnExtGcd;
+  r->cfXExtGcd     = nrnXExtGcd;
+  r->cfQuotRem     = nrnQuotRem;
+  r->cfCoeffWrite  = nrnCoeffWrite;
+  r->nCoeffIsEqual = nrnCoeffsEqual;
+  r->cfKillChar    = nrnKillChar;
+  r->cfQuot1       = nrnQuot1;
+#ifdef LDEBUG
+  r->cfDBTest      = nrnDBTest;
+#endif
+  return FALSE;
+}
+
+/*
+ * create a number from int
+ */
+number nrnInit(long i, const coeffs r)
+{
+  mpz_ptr erg = (mpz_ptr) omAllocBin(gmp_nrz_bin);
+  mpz_init_set_si(erg, i);
+  mpz_mod(erg, erg, r->modNumber);
+  return (number) erg;
+}
+
+void nrnDelete(number *a, const coeffs)
+{
+  if (*a == NULL) return;
+  mpz_clear((mpz_ptr) *a);
+  omFreeBin((void *) *a, gmp_nrz_bin);
+  *a = NULL;
+}
+
+number nrnCopy(number a, const coeffs)
+{
+  mpz_ptr erg = (mpz_ptr) omAllocBin(gmp_nrz_bin);
+  mpz_init_set(erg, (mpz_ptr) a);
+  return (number) erg;
+}
+
+int nrnSize(number a, const coeffs)
+{
+  if (a == NULL) return 0;
+  return sizeof(mpz_t);
+}
+
+/*
+ * convert a number to int
+ */
+int nrnInt(number &n, const coeffs)
+{
+  return (int)mpz_get_si((mpz_ptr) n);
+}
+
+/*
+ * Multiply two numbers
+ */
+number nrnMult(number a, number b, const coeffs r)
+{
+  mpz_ptr erg = (mpz_ptr)omAllocBin(gmp_nrz_bin);
+  mpz_init(erg);
+  mpz_mul(erg, (mpz_ptr)a, (mpz_ptr) b);
+  mpz_mod(erg, erg, r->modNumber);
+  return (number) erg;
+}
+
+void nrnPower(number a, int i, number * result, const coeffs r)
+{
+  mpz_ptr erg = (mpz_ptr)omAllocBin(gmp_nrz_bin);
+  mpz_init(erg);
+  mpz_powm_ui(erg, (mpz_ptr)a, i, r->modNumber);
+  *result = (number) erg;
+}
+
+number nrnAdd(number a, number b, const coeffs r)
+{
+  mpz_ptr erg = (mpz_ptr)omAllocBin(gmp_nrz_bin);
+  mpz_init(erg);
+  mpz_add(erg, (mpz_ptr)a, (mpz_ptr) b);
+  mpz_mod(erg, erg, r->modNumber);
+  return (number) erg;
+}
+
+number nrnSub(number a, number b, const coeffs r)
+{
+  mpz_ptr erg = (mpz_ptr)omAllocBin(gmp_nrz_bin);
+  mpz_init(erg);
+  mpz_sub(erg, (mpz_ptr)a, (mpz_ptr) b);
+  mpz_mod(erg, erg, r->modNumber);
+  return (number) erg;
+}
+
+number nrnNeg(number c, const coeffs r)
+{
+  if( !nrnIsZero(c, r) )
+    // Attention: This method operates in-place.
+    mpz_sub((mpz_ptr)c, r->modNumber, (mpz_ptr)c);
+  return c;
+}
+
+number nrnInvers(number c, const coeffs r)
+{
+  mpz_ptr erg = (mpz_ptr)omAllocBin(gmp_nrz_bin);
+  mpz_init(erg);
+  mpz_invert(erg, (mpz_ptr)c, r->modNumber);
+  return (number) erg;
+}
+
+/*
+ * Give the smallest k, such that a * x = k = b * y has a solution
+ * TODO: lcm(gcd,gcd) better than gcd(lcm) ?
+ */
+number nrnLcm(number a, number b, const coeffs r)
+{
+  number erg = nrnGcd(NULL, a, r);
+  number tmp = nrnGcd(NULL, b, r);
+  mpz_lcm((mpz_ptr)erg, (mpz_ptr)erg, (mpz_ptr)tmp);
+  nrnDelete(&tmp, r);
+  return (number)erg;
+}
+
+/*
+ * Give the largest k, such that a = x * k, b = y * k has
+ * a solution.
+ */
+number nrnGcd(number a, number b, const coeffs r)
+{
+  if ((a == NULL) && (b == NULL)) return nrnInit(0,r);
+  mpz_ptr erg = (mpz_ptr)omAllocBin(gmp_nrz_bin);
+  mpz_init_set(erg, r->modNumber);
+  if (a != NULL) mpz_gcd(erg, erg, (mpz_ptr)a);
+  if (b != NULL) mpz_gcd(erg, erg, (mpz_ptr)b);
+  return (number)erg;
+}
+
+/* Not needed any more, but may have room for improvement
+   number nrnGcd3(number a,number b, number c,ring r)
+{
+  mpz_ptr erg = (mpz_ptr) omAllocBin(gmp_nrz_bin);
+  mpz_init(erg);
+  if (a == NULL) a = (number)r->modNumber;
+  if (b == NULL) b = (number)r->modNumber;
+  if (c == NULL) c = (number)r->modNumber;
+  mpz_gcd(erg, (mpz_ptr)a, (mpz_ptr)b);
+  mpz_gcd(erg, erg, (mpz_ptr)c);
+  mpz_gcd(erg, erg, r->modNumber);
+  return (number)erg;
+}
+*/
+
+/*
+ * Give the largest k, such that a = x * k, b = y * k has
+ * a solution and r, s, s.t. k = s*a + t*b
+ * CF: careful: ExtGcd is wrong as implemented (or at least may not
+ * give you what you want:
+ * ExtGcd(5, 10 modulo 12):
+ * the gcdext will return 5 = 1*5 + 0*10
+ * however, mod 12, the gcd should be 1
+ */
+number nrnExtGcd(number a, number b, number *s, number *t, const coeffs r)
+{
+  mpz_ptr erg = (mpz_ptr)omAllocBin(gmp_nrz_bin);
+  mpz_ptr bs  = (mpz_ptr)omAllocBin(gmp_nrz_bin);
+  mpz_ptr bt  = (mpz_ptr)omAllocBin(gmp_nrz_bin);
+  mpz_init(erg);
+  mpz_init(bs);
+  mpz_init(bt);
+  mpz_gcdext(erg, bs, bt, (mpz_ptr)a, (mpz_ptr)b);
+  mpz_mod(bs, bs, r->modNumber);
+  mpz_mod(bt, bt, r->modNumber);
+  *s = (number)bs;
+  *t = (number)bt;
+  return (number)erg;
+}
+/* XExtGcd  returns a unimodular matrix ((s,t)(u,v)) sth.
+ * (a,b)^t ((st)(uv)) = (g,0)^t
+ * Beware, the ExtGcd will not necessaairly do this.
+ * Problem: if g = as+bt then (in Z/nZ) it follows NOT that
+ *             1 = (a/g)s + (b/g) t
+ * due to the zero divisors.
+ */
+
+//#define CF_DEB;
+number nrnXExtGcd(number a, number b, number *s, number *t, number *u, number *v, const coeffs r)
+{
+  number xx;
+#ifdef CF_DEB
+  StringSetS("XExtGcd of ");
+  nrnWrite(a, r);
+  StringAppendS("\t");
+  nrnWrite(b, r);
+  StringAppendS(" modulo ");
+  nrnWrite(xx = (number)r->modNumber, r);
+  Print("%s\n", StringEndS());
+#endif
+
+  mpz_ptr one = (mpz_ptr)omAllocBin(gmp_nrz_bin);
+  mpz_ptr erg = (mpz_ptr)omAllocBin(gmp_nrz_bin);
+  mpz_ptr bs  = (mpz_ptr)omAllocBin(gmp_nrz_bin);
+  mpz_ptr bt  = (mpz_ptr)omAllocBin(gmp_nrz_bin);
+  mpz_ptr bu  = (mpz_ptr)omAllocBin(gmp_nrz_bin);
+  mpz_ptr bv  = (mpz_ptr)omAllocBin(gmp_nrz_bin);
+  mpz_init(erg);
+  mpz_init(one);
+  mpz_init_set(bs, (mpz_ptr) a);
+  mpz_init_set(bt, (mpz_ptr) b);
+  mpz_init(bu);
+  mpz_init(bv);
+  mpz_gcd(erg, bs, bt);
+
+#ifdef CF_DEB
+  StringSetS("1st gcd:");
+  nrnWrite(xx= (number)erg, r);
+#endif
+
+  mpz_gcd(erg, erg, r->modNumber);
+
+  mpz_div(bs, bs, erg);
+  mpz_div(bt, bt, erg);
+
+#ifdef CF_DEB
+  Print("%s\n", StringEndS());
+  StringSetS("xgcd: ");
+#endif
+
+  mpz_gcdext(one, bu, bv, bs, bt);
+  number ui = nrnGetUnit(xx = (number) one, r);
+#ifdef CF_DEB
+  n_Write(xx, r);
+  StringAppendS("\t");
+  n_Write(ui, r);
+  Print("%s\n", StringEndS());
+#endif
+  nrnDelete(&xx, r);
+  if (!nrnIsOne(ui, r)) {
+#ifdef CF_DEB
+    Print("Scaling\n");
+#endif
+    number uii = nrnInvers(ui, r);
+    nrnDelete(&ui, r);
+    ui = uii;
+    mpz_ptr uu = (mpz_ptr)omAllocBin(gmp_nrz_bin);
+    mpz_init_set(uu, (mpz_ptr)ui);
+    mpz_mul(bu, bu, uu);
+    mpz_mul(bv, bv, uu);
+    mpz_clear(uu);
+    omFreeBin(uu, gmp_nrz_bin);
+  }
+  nrnDelete(&ui, r);
+#ifdef CF_DEB
+  StringSetS("xgcd");
+  nrnWrite(xx= (number)bs, r);
+  StringAppendS("*");
+  nrnWrite(xx= (number)bu, r);
+  StringAppendS(" + ");
+  nrnWrite(xx= (number)bt, r);
+  StringAppendS("*");
+  nrnWrite(xx= (number)bv, r);
+  Print("%s\n", StringEndS());
+#endif
+
+  mpz_mod(bs, bs, r->modNumber);
+  mpz_mod(bt, bt, r->modNumber);
+  mpz_mod(bu, bu, r->modNumber);
+  mpz_mod(bv, bv, r->modNumber);
+  *s = (number)bu;
+  *t = (number)bv;
+  *u = (number)bt;
+  *u = nrnNeg(*u, r);
+  *v = (number)bs;
+  return (number)erg;
+}
+
+
+BOOLEAN nrnIsZero(number a, const coeffs)
+{
+#ifdef LDEBUG
+  if (a == NULL) return FALSE;
+#endif
+  return 0 == mpz_cmpabs_ui((mpz_ptr)a, 0);
+}
+
+BOOLEAN nrnIsOne(number a, const coeffs)
+{
+#ifdef LDEBUG
+  if (a == NULL) return FALSE;
+#endif
+  return 0 == mpz_cmp_si((mpz_ptr)a, 1);
+}
+
+BOOLEAN nrnIsMOne(number a, const coeffs r)
+{
+#ifdef LDEBUG
+  if (a == NULL) return FALSE;
+#endif
+  mpz_t t; mpz_init_set(t, (mpz_ptr)a);
+  mpz_add_ui(t, t, 1);
+  bool erg = (0 == mpz_cmp(t, r->modNumber));
+  mpz_clear(t);
+  return erg;
+}
+
+BOOLEAN nrnEqual(number a, number b, const coeffs)
+{
+  return 0 == mpz_cmp((mpz_ptr)a, (mpz_ptr)b);
+}
+
+BOOLEAN nrnGreater(number a, number b, const coeffs)
+{
+  return 0 < mpz_cmp((mpz_ptr)a, (mpz_ptr)b);
+}
+
+BOOLEAN nrnGreaterZero(number k, const coeffs)
+{
+  return 0 < mpz_cmp_si((mpz_ptr)k, 0);
+}
+
+BOOLEAN nrnIsUnit(number a, const coeffs r)
+{
+  number tmp = nrnGcd(a, (number)r->modNumber, r);
+  bool res = nrnIsOne(tmp, r);
+  nrnDelete(&tmp, NULL);
+  return res;
+}
+
+number nrnGetUnit(number k, const coeffs r)
+{
+  if (mpz_divisible_p(r->modNumber, (mpz_ptr)k)) return nrnInit(1,r);
+
+  mpz_ptr unit = (mpz_ptr)nrnGcd(k, 0, r);
+  mpz_tdiv_q(unit, (mpz_ptr)k, unit);
+  mpz_ptr gcd = (mpz_ptr)nrnGcd((number)unit, 0, r);
+  if (!nrnIsOne((number)gcd,r))
+  {
+    mpz_ptr ctmp;
+    // tmp := unit^2
+    mpz_ptr tmp = (mpz_ptr) nrnMult((number) unit,(number) unit,r);
+    // gcd_new := gcd(tmp, 0)
+    mpz_ptr gcd_new = (mpz_ptr) nrnGcd((number) tmp, 0, r);
+    while (!nrnEqual((number) gcd_new,(number) gcd,r))
+    {
+      // gcd := gcd_new
+      ctmp = gcd;
+      gcd = gcd_new;
+      gcd_new = ctmp;
+      // tmp := tmp * unit
+      mpz_mul(tmp, tmp, unit);
+      mpz_mod(tmp, tmp, r->modNumber);
+      // gcd_new := gcd(tmp, 0)
+      mpz_gcd(gcd_new, tmp, r->modNumber);
+    }
+    // unit := unit + modNumber / gcd_new
+    mpz_tdiv_q(tmp, r->modNumber, gcd_new);
+    mpz_add(unit, unit, tmp);
+    mpz_mod(unit, unit, r->modNumber);
+    nrnDelete((number*) &gcd_new, NULL);
+    nrnDelete((number*) &tmp, NULL);
+  }
+  nrnDelete((number*) &gcd, NULL);
+  return (number)unit;
+}
+
+number nrnAnn(number k, const coeffs r)
+{
+  mpz_ptr tmp = (mpz_ptr) omAllocBin(gmp_nrz_bin);
+  mpz_init(tmp);
+  mpz_gcd(tmp, (mpz_ptr) k, r->modNumber);
+  if (mpz_cmp_si(tmp, 1)==0) {
+    mpz_set_si(tmp, 0);
+    return (number) tmp;
+  }
+  mpz_divexact(tmp, r->modNumber, tmp);
+  return (number) tmp;
+}
+
+BOOLEAN nrnDivBy(number a, number b, const coeffs r)
+{
+  if (a == NULL)
+    return mpz_divisible_p(r->modNumber, (mpz_ptr)b);
+  else
+  { /* b divides a iff b/gcd(a, b) is a unit in the given ring: */
+    number n = nrnGcd(a, b, r);
+    mpz_tdiv_q((mpz_ptr)n, (mpz_ptr)b, (mpz_ptr)n);
+    bool result = nrnIsUnit(n, r);
+    nrnDelete(&n, NULL);
+    return result;
+  }
+}
+
+int nrnDivComp(number a, number b, const coeffs r)
+{
+  if (nrnEqual(a, b,r)) return 2;
+  if (mpz_divisible_p((mpz_ptr) a, (mpz_ptr) b)) return -1;
+  if (mpz_divisible_p((mpz_ptr) b, (mpz_ptr) a)) return 1;
+  return 0;
+}
+
+number nrnDiv(number a, number b, const coeffs r)
+{
+  if (a == NULL) a = (number)r->modNumber;
+  mpz_ptr erg = (mpz_ptr)omAllocBin(gmp_nrz_bin);
+  mpz_init(erg);
+  if (mpz_divisible_p((mpz_ptr)a, (mpz_ptr)b))
+  {
+    mpz_divexact(erg, (mpz_ptr)a, (mpz_ptr)b);
+    return (number)erg;
+  }
+  else
+  {
+    mpz_ptr gcd = (mpz_ptr)nrnGcd(a, b, r);
+    mpz_divexact(erg, (mpz_ptr)b, gcd);
+    if (!nrnIsUnit((number)erg, r))
+    {
+      WerrorS("Division not possible, even by cancelling zero divisors.");
+      WerrorS("Result is integer division without remainder.");
+      mpz_tdiv_q(erg, (mpz_ptr) a, (mpz_ptr) b);
+      nrnDelete((number*) &gcd, NULL);
+      return (number)erg;
+    }
+    // a / gcd(a,b) * [b / gcd (a,b)]^(-1)
+    mpz_ptr tmp = (mpz_ptr)nrnInvers((number) erg,r);
+    mpz_divexact(erg, (mpz_ptr)a, gcd);
+    mpz_mul(erg, erg, tmp);
+    nrnDelete((number*) &gcd, NULL);
+    nrnDelete((number*) &tmp, NULL);
+    mpz_mod(erg, erg, r->modNumber);
+    return (number)erg;
+  }
+}
+
+number nrnMod(number a, number b, const coeffs r)
+{
+  /*
+    We need to return the number rr which is uniquely determined by the
+    following two properties:
+      (1) 0 <= rr < |b| (with respect to '<' and '<=' performed in Z x Z)
+      (2) There exists some k in the integers Z such that a = k * b + rr.
+    Consider g := gcd(n, |b|). Note that then |b|/g is a unit in Z/n.
+    Now, there are three cases:
+      (a) g = 1
+          Then |b| is a unit in Z/n, i.e. |b| (and also b) divides a.
+          Thus rr = 0.
+      (b) g <> 1 and g divides a
+          Then a = (a/g) * (|b|/g)^(-1) * b (up to sign), i.e. again rr = 0.
+      (c) g <> 1 and g does not divide a
+          Then denote the division with remainder of a by g as this:
+          a = s * g + t. Then t = a - s * g = a - s * (|b|/g)^(-1) * |b|
+          fulfills (1) and (2), i.e. rr := t is the correct result. Hence
+          in this third case, rr is the remainder of division of a by g in Z.
+     Remark: according to mpz_mod: a,b are always non-negative
+  */
+  mpz_ptr g = (mpz_ptr)omAllocBin(gmp_nrz_bin);
+  mpz_ptr rr = (mpz_ptr)omAllocBin(gmp_nrz_bin);
+  mpz_init(g);
+  mpz_init_set_si(rr, 0);
+  mpz_gcd(g, (mpz_ptr)r->modNumber, (mpz_ptr)b); // g is now as above
+  if (mpz_cmp_si(g, (long)1) != 0) mpz_mod(rr, (mpz_ptr)a, g); // the case g <> 1
+  mpz_clear(g);
+  omFreeBin(g, gmp_nrz_bin);
+  return (number)rr;
+}
+
+number nrnIntDiv(number a, number b, const coeffs r)
+{
+  mpz_ptr erg = (mpz_ptr)omAllocBin(gmp_nrz_bin);
+  mpz_init(erg);
+  if (a == NULL) a = (number)r->modNumber;
+  mpz_tdiv_q(erg, (mpz_ptr)a, (mpz_ptr)b);
+  return (number)erg;
+}
+
+/* CF: note that Z/nZ has (at least) two distinct euclidean structures
+ * 1st phi(a) := (a mod n) which is just the structure directly
+ *     inherited from Z
+ * 2nd phi(a) := gcd(a, n)
+ * The 1st version is probably faster as everything just comes from Z,
+ * but the 2nd version behaves nicely wrt. to quotient operations
+ * and HNF and such. In agreement with nrnMod we imlement the 2nd here
+ *
+ * For quotrem note that if b exactly divides a, then
+ *   min(v_p(a), v_p(n))  >= min(v_p(b), v_p(n))
+ * so if we divide  a and b by g:= gcd(a,b,n), then   b becomes a
+ * unit mod n/g.
+ * Thus we 1st compute the remainder (similar to nrnMod) and then
+ * the exact quotient.
+ */
+number nrnQuotRem(number a, number b, number  * rem, const coeffs r)
+{
+  mpz_t g, aa, bb;
+  mpz_ptr qq = (mpz_ptr)omAllocBin(gmp_nrz_bin);
+  mpz_ptr rr = (mpz_ptr)omAllocBin(gmp_nrz_bin);
+  mpz_init(qq);
+  mpz_init(rr);
+  mpz_init(g);
+  mpz_init_set(aa, (mpz_ptr)a);
+  mpz_init_set(bb, (mpz_ptr)b);
+
+  mpz_gcd(g, bb, r->modNumber);
+  mpz_mod(rr, aa, g);
+  mpz_sub(aa, aa, rr);
+  mpz_gcd(g, aa, g);
+  mpz_div(aa, aa, g);
+  mpz_div(bb, bb, g);
+  mpz_div(g, r->modNumber, g);
+  mpz_invert(g, bb, g);
+  mpz_mul(qq, aa, g);
+  if (rem)
+    *rem = (number)rr;
+  else {
+    mpz_clear(rr);
+    omFreeBin(rr, gmp_nrz_bin);
+  }
+  mpz_clear(g);
+  mpz_clear(aa);
+  mpz_clear(bb);
+  return (number) qq;
+}
+
+/*
+ * Helper function for computing the module
+ */
+
+mpz_ptr nrnMapCoef = NULL;
+
+number nrnMapModN(number from, const coeffs /*src*/, const coeffs dst)
+{
+  return nrnMult(from, (number) nrnMapCoef, dst);
+}
+
+number nrnMap2toM(number from, const coeffs /*src*/, const coeffs dst)
+{
+  mpz_ptr erg = (mpz_ptr)omAllocBin(gmp_nrz_bin);
+  mpz_init(erg);
+  mpz_mul_ui(erg, nrnMapCoef, (unsigned long)from);
+  mpz_mod(erg, erg, dst->modNumber);
+  return (number)erg;
+}
+
+number nrnMapZp(number from, const coeffs /*src*/, const coeffs dst)
+{
+  mpz_ptr erg = (mpz_ptr)omAllocBin(gmp_nrz_bin);
+  mpz_init(erg);
+  // TODO: use npInt(...)
+  mpz_mul_si(erg, nrnMapCoef, (unsigned long)from);
+  mpz_mod(erg, erg, dst->modNumber);
+  return (number)erg;
+}
+
+number nrnMapGMP(number from, const coeffs /*src*/, const coeffs dst)
+{
+  mpz_ptr erg = (mpz_ptr)omAllocBin(gmp_nrz_bin);
+  mpz_init(erg);
+  mpz_mod(erg, (mpz_ptr)from, dst->modNumber);
+  return (number)erg;
+}
+
+#if SI_INTEGER_VARIANT==3
+number nrnMapZ(number from, const coeffs /*src*/, const coeffs dst)
+{
+  mpz_ptr erg = (mpz_ptr)omAllocBin(gmp_nrz_bin);
+  if (n_Z_IS_SMALL(from))
+    mpz_init_set_si(erg, SR_TO_INT(from));
+  else
+    mpz_init_set(erg, (mpz_ptr) from);
+  mpz_mod(erg, erg, dst->modNumber);
+  return (number)erg;
+}
+#elif SI_INTEGER_VARIANT==2
+
+number nrnMapZ(number from, const coeffs src, const coeffs dst)
+{
+  if (SR_HDL(from) & SR_INT)
+  {
+    long f_i=SR_TO_INT(from);
+    return nrnInit(f_i,dst);
+  }
+  return nrnMapGMP(from,src,dst);
+}
+#elif SI_INTEGER_VARIANT==1
+number nrnMapZ(number from, const coeffs src, const coeffs dst)
+{
+  return nrnMapQ(from,src,dst);
+}
+#endif
+#if SI_INTEGER_VARIANT!=2
+void nrnWrite (number &a, const coeffs)
+{
+  char *s,*z;
+  if (a==NULL)
+  {
+    StringAppendS("o");
+  }
+  else
+  {
+    int l=mpz_sizeinbase((mpz_ptr) a, 10) + 2;
+    s=(char*)omAlloc(l);
+    z=mpz_get_str(s,10,(mpz_ptr) a);
+    StringAppendS(z);
+    omFreeSize((ADDRESS)s,l);
+  }
+}
+#endif
+
+number nrnMapQ(number from, const coeffs src, const coeffs dst)
+{
+  mpz_ptr erg = (mpz_ptr)omAllocBin(gmp_nrz_bin);
+  mpz_init(erg);
+  nlGMP(from, (number)erg, src); // FIXME? TODO? // extern void   nlGMP(number &i, number n, const coeffs r); // to be replaced with n_MPZ(erg, from, src); // ?
+  mpz_mod(erg, erg, dst->modNumber);
+  return (number)erg;
+}
+
+nMapFunc nrnSetMap(const coeffs src, const coeffs dst)
+{
+  /* dst = nrn */
+  if ((src->rep==n_rep_gmp) && nCoeff_is_Ring_Z(src))
+  {
+    return nrnMapZ;
+  }
+  if ((src->rep==n_rep_gap_gmp) /*&& nCoeff_is_Ring_Z(src)*/)
+  {
+    return nrnMapZ;
+  }
+  if (src->rep==n_rep_gap_rat) /*&& nCoeff_is_Q(src)) or Z*/
+  {
+    return nrnMapQ;
+  }
+  // Some type of Z/n ring / field
+  if (nCoeff_is_Ring_ModN(src) || nCoeff_is_Ring_PtoM(src) ||
+      nCoeff_is_Ring_2toM(src) || nCoeff_is_Zp(src))
+  {
+    if (   (!nCoeff_is_Zp(src))
+        && (mpz_cmp(src->modBase, dst->modBase) == 0)
+        && (src->modExponent == dst->modExponent)) return nrnMapGMP;
+    else
+    {
+      mpz_ptr nrnMapModul = (mpz_ptr) omAllocBin(gmp_nrz_bin);
+      // Computing the n of Z/n
+      if (nCoeff_is_Zp(src))
+      {
+        mpz_init_set_si(nrnMapModul, src->ch);
+      }
+      else
+      {
+        mpz_init(nrnMapModul);
+        mpz_set(nrnMapModul, src->modNumber);
+      }
+      // nrnMapCoef = 1 in dst       if dst is a subring of src
+      // nrnMapCoef = 0 in dst / src if src is a subring of dst
+      if (nrnMapCoef == NULL)
+      {
+        nrnMapCoef = (mpz_ptr) omAllocBin(gmp_nrz_bin);
+        mpz_init(nrnMapCoef);
+      }
+      if (mpz_divisible_p(nrnMapModul, dst->modNumber))
+      {
+        mpz_set_si(nrnMapCoef, 1);
+      }
+      else
+      if (nrnDivBy(NULL, (number) nrnMapModul,dst))
+      {
+        mpz_divexact(nrnMapCoef, dst->modNumber, nrnMapModul);
+        mpz_ptr tmp = dst->modNumber;
+        dst->modNumber = nrnMapModul;
+        if (!nrnIsUnit((number) nrnMapCoef,dst))
+        {
+          dst->modNumber = tmp;
+          nrnDelete((number*) &nrnMapModul, dst);
+          return NULL;
+        }
+        mpz_ptr inv = (mpz_ptr) nrnInvers((number) nrnMapCoef,dst);
+        dst->modNumber = tmp;
+        mpz_mul(nrnMapCoef, nrnMapCoef, inv);
+        mpz_mod(nrnMapCoef, nrnMapCoef, dst->modNumber);
+        nrnDelete((number*) &inv, dst);
+      }
+      else
+      {
+        nrnDelete((number*) &nrnMapModul, dst);
+        return NULL;
+      }
+      nrnDelete((number*) &nrnMapModul, dst);
+      if (nCoeff_is_Ring_2toM(src))
+        return nrnMap2toM;
+      else if (nCoeff_is_Zp(src))
+        return nrnMapZp;
+      else
+        return nrnMapModN;
+    }
+  }
+  return NULL;      // default
+}
+
+/*
+ * set the exponent (allocate and init tables) (TODO)
+ */
+
+void nrnSetExp(unsigned long m, coeffs r)
+{
+  /* clean up former stuff */
+  if (r->modNumber != NULL) mpz_clear(r->modNumber);
+
+  r->modExponent= m;
+  r->modNumber = (mpz_ptr)omAllocBin(gmp_nrz_bin);
+  mpz_init_set (r->modNumber, r->modBase);
+  mpz_pow_ui (r->modNumber, r->modNumber, m);
+}
+
+/* We expect this ring to be Z/n^m for some m > 0 and for some n > 2 which is not a prime. */
+void nrnInitExp(unsigned long m, coeffs r)
+{
+  nrnSetExp(m, r);
+  assume (r->modNumber != NULL);
+//CF: in geenral, the modulus is computed somewhere. I don't want to
+//  check it's size before I construct the best ring.
+//  if (mpz_cmp_ui(r->modNumber,2) <= 0)
+//    WarnS("nrnInitExp failed (m in Z/m too small)");
+}
+
+#ifdef LDEBUG
+BOOLEAN nrnDBTest (number a, const char *, const int, const coeffs r)
+{
+  if (a==NULL) return TRUE;
+  if ( (mpz_cmp_si((mpz_ptr) a, 0) < 0) || (mpz_cmp((mpz_ptr) a, r->modNumber) > 0) )
+  {
+    return FALSE;
+  }
+  return TRUE;
+}
+#endif
+
+/*2
+* extracts a long integer from s, returns the rest    (COPY FROM longrat0.cc)
+*/
+static const char * nlCPEatLongC(char *s, mpz_ptr i)
+{
+  const char * start=s;
+  if (!(*s >= '0' && *s <= '9'))
+  {
+    mpz_init_set_si(i, 1);
+    return s;
+  }
+  mpz_init(i);
+  while (*s >= '0' && *s <= '9') s++;
+  if (*s=='\0')
+  {
+    mpz_set_str(i,start,10);
+  }
+  else
+  {
+    char c=*s;
+    *s='\0';
+    mpz_set_str(i,start,10);
+    *s=c;
+  }
+  return s;
+}
+
+const char * nrnRead (const char *s, number *a, const coeffs r)
+{
+  mpz_ptr z = (mpz_ptr) omAllocBin(gmp_nrz_bin);
+  {
+    s = nlCPEatLongC((char *)s, z);
+  }
+  mpz_mod(z, z, r->modNumber);
+  *a = (number) z;
+  return s;
+}
+#endif
+/* #ifdef HAVE_RINGS */
diff --git a/libpolys/coeffs/rmodulon.h b/libpolys/coeffs/rmodulon.h
new file mode 100644
index 0000000..6ce48f3
--- /dev/null
+++ b/libpolys/coeffs/rmodulon.h
@@ -0,0 +1,24 @@
+#ifndef RMODULON_H
+#define RMODULON_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: numbers modulo n
+*/
+#include <misc/auxiliary.h>
+
+struct n_Procs_s; typedef struct  n_Procs_s  *coeffs;
+struct snumber; typedef struct snumber *   number;
+
+#include <coeffs/rintegers.h>
+
+#ifdef HAVE_RINGS
+
+typedef struct { mpz_ptr base;  unsigned long exp; } ZnmInfo;
+
+BOOLEAN nrnInitChar    (coeffs r, void*);
+
+#endif
+
+#endif
diff --git a/libpolys/coeffs/shortfl.cc b/libpolys/coeffs/shortfl.cc
new file mode 100644
index 0000000..c25cee0
--- /dev/null
+++ b/libpolys/coeffs/shortfl.cc
@@ -0,0 +1,782 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+
+/*
+* ABSTRACT:
+*/
+
+
+
+#include <misc/auxiliary.h>
+#include <misc/mylimits.h>
+
+#include <reporter/reporter.h>
+
+#include "numbers.h"
+#include "coeffs.h"
+#include "mpr_complex.h"
+
+#include "shortfl.h"
+#include "longrat.h"
+
+#include <string.h>
+#include <math.h>
+
+/// Our Type!
+static const n_coeffType ID = n_R;
+
+// Private interface should be hidden!!!
+
+BOOLEAN nrGreaterZero (number k, const coeffs r);
+number  nrMult        (number a, number b, const coeffs r);
+number  nrInit        (long i, const coeffs r);
+int     nrInt         (number &n, const coeffs r);
+number  nrAdd         (number a, number b, const coeffs r);
+number  nrSub         (number a, number b, const coeffs r);
+void    nrPower       (number a, int i, number * result, const coeffs r);
+BOOLEAN nrIsZero      (number a, const coeffs r);
+BOOLEAN nrIsOne       (number a, const coeffs r);
+BOOLEAN nrIsMOne      (number a, const coeffs r);
+number  nrDiv         (number a, number b, const coeffs r);
+number  nrNeg         (number c, const coeffs r);
+number  nrInvers      (number c, const coeffs r);
+BOOLEAN nrGreater     (number a, number b, const coeffs r);
+BOOLEAN nrEqual       (number a, number b, const coeffs r);
+void    nrWrite       (number &a, const coeffs r);
+const char *  nrRead  (const char *s, number *a, const coeffs r);
+
+#ifdef LDEBUG
+BOOLEAN nrDBTest(number a, const coeffs r, const char *f, const int l);
+#endif
+
+/// Get a mapping function from src into the domain of this type: n_R
+nMapFunc nrSetMap(const coeffs src, const coeffs dst);
+
+// Where are the following used?
+// int     nrGetChar();
+number nrMapQ(number from, const coeffs r, const coeffs aRing);
+
+static const float nrEps = 1.0e-3;
+
+union nf
+{
+  float _f;
+  number _n;
+
+  nf(float f): _f(f){};
+
+  nf(number n): _n(n){};
+
+  inline float F() const {return _f;}
+  inline number N() const {return _n;}
+};
+
+
+
+
+float nrFloat(number n)
+{
+  return nf(n).F();
+}
+
+
+void    nrCoeffWrite  (const coeffs r, BOOLEAN /*details*/)
+{
+  assume( getCoeffType(r) == ID );
+  PrintS("//   characteristic : 0 (real)\n");  /* R */
+}
+
+
+BOOLEAN nrGreaterZero (number k, const coeffs r)
+{
+  assume( getCoeffType(r) == ID );
+
+  return nf(k).F() >= 0.0;
+}
+
+number nrMult (number a,number b, const coeffs r)
+{
+  assume( getCoeffType(r) == ID );
+
+  return nf(nf(a).F() * nf(b).F()).N();
+}
+
+/*2
+* create a number from int
+*/
+number nrInit (long i, const coeffs r)
+{
+  assume( getCoeffType(r) == ID );
+
+  float f = (float)i;
+  return nf(nf(f).F()).N();
+}
+
+/*2
+* convert a number to int
+*/
+int nrInt(number &n, const coeffs r)
+{
+  assume( getCoeffType(r) == ID );
+
+  int i;
+  float f = nf(n).F();
+  if (((float)(-MAX_INT_VAL-1) <= f) || ((float)MAX_INT_VAL >= f))
+    i = (int)f;
+  else
+    i = 0;
+  return i;
+}
+
+int nrSize(number n, const coeffs)
+{
+  float f = nf(n).F();
+  int i = (int)f;
+  /* basically return the largest integer in n;
+     only if this happens to be zero although n != 0,
+     return 1;
+     (this code ensures that zero has the size zero) */
+  if ((f != 0.0) & (i == 0)) i = 1;
+  return i;
+}
+
+number nrAdd (number a, number b, const coeffs r)
+{
+  assume( getCoeffType(r) == ID );
+
+  float x = nf(a).F();
+  float y = nf(b).F();
+  float f = x + y;
+  if (x > 0.0)
+  {
+    if (y < 0.0)
+    {
+      x = f / (x - y);
+      if (x < 0.0)
+        x = -x;
+      if (x < nrEps)
+        f = 0.0;
+    }
+  }
+  else
+  {
+    if (y > 0.0)
+    {
+      x = f / (y - x);
+      if (x < 0.0)
+        x = -x;
+      if (x < nrEps)
+        f = 0.0;
+    }
+  }
+  return nf(f).N();
+}
+
+number nrSub (number a, number b, const coeffs r)
+{
+  assume( getCoeffType(r) == ID );
+
+  float x = nf(a).F();
+  float y = nf(b).F();
+  float f = x - y;
+  if (x > 0.0)
+  {
+    if (y > 0.0)
+    {
+      x = f / (x + y);
+      if (x < 0.0)
+        x = -x;
+      if (x < nrEps)
+        f = 0.0;
+    }
+  }
+  else
+  {
+    if (y < 0.0)
+    {
+      x = f / (x + y);
+      if (x < 0.0)
+        x = -x;
+      if (x < nrEps)
+        f = 0.0;
+    }
+  }
+  return nf(f).N();
+}
+
+BOOLEAN nrIsZero (number  a, const coeffs r)
+{
+  assume( getCoeffType(r) == ID );
+
+  return (0.0 == nf(a).F());
+}
+
+BOOLEAN nrIsOne (number a, const coeffs r)
+{
+  assume( getCoeffType(r) == ID );
+
+  float aa=nf(a).F()-1.0;
+  if (aa<0.0) aa=-aa;
+  return (aa<nrEps);
+}
+
+BOOLEAN nrIsMOne (number a, const coeffs r)
+{
+  assume( getCoeffType(r) == ID );
+
+  float aa=nf(a).F()+1.0;
+  if (aa<0.0) aa=-aa;
+  return (aa<nrEps);
+}
+
+number nrDiv (number a,number b, const coeffs r)
+{
+  assume( getCoeffType(r) == ID );
+
+  float n = nf(b).F();
+  if (n == 0.0)
+  {
+    WerrorS(nDivBy0);
+    return nf((float)0.0).N();
+  }
+  else
+    return nf(nf(a).F() / n).N();
+}
+
+number  nrInvers (number c, const coeffs r)
+{
+  assume( getCoeffType(r) == ID );
+
+  float n = nf(c).F();
+  if (n == 0.0)
+  {
+    WerrorS(nDivBy0);
+    return nf((float)0.0).N();
+  }
+  return nf(1.0 / n).N();
+}
+
+number nrNeg (number c, const coeffs r)
+{
+  assume( getCoeffType(r) == ID );
+
+  return nf(-nf(c).F()).N();
+}
+
+BOOLEAN nrGreater (number a,number b, const coeffs r)
+{
+  assume( getCoeffType(r) == ID );
+
+  return nf(a).F() > nf(b).F();
+}
+
+BOOLEAN nrEqual (number a,number b, const coeffs r)
+{
+  assume( getCoeffType(r) == ID );
+
+  number x = nrSub(a,b,r);
+  return nf(x).F() == nf((float)0.0).F();
+}
+
+void nrWrite (number &a, const coeffs r)
+{
+  assume( getCoeffType(r) == ID );
+
+  char ch[11];
+  int n = sprintf(ch,"%9.3e", nf(a).F());
+  if (ch[0] == '-')
+  {
+    char* chbr = new char[n+3];
+    memcpy(&chbr[2],&ch[1],n-1);
+    chbr[0] = '-';
+    chbr[1] = '(';
+    chbr[n+1] = ')';
+    chbr[n+2] = '\0';
+    StringAppendS(chbr);
+    delete chbr;
+  }
+  else
+    StringAppend("(%s)",ch);
+}
+
+#if 0
+void nrPower (number a, int i, number * result, const coeffs r)
+{
+  assume( getCoeffType(r) == ID );
+
+  if (i==0)
+  {
+    *result = nf(nf(1.0).F()).N();
+    return;
+  }
+  if (i==1)
+  {
+    *result = nf(nf(a).F()).N();
+    return;
+  }
+  nrPower(a,i-1,result,r);
+  *result = nf(nf(a).F() * nf(*result).F()).N();
+}
+#endif
+
+namespace {
+  static const char* nrEatr(const char *s, float *r)
+  {
+    int i;
+
+    if    (*s >= '0' && *s <= '9')
+    {
+      *r = 0.0;
+      do
+      {
+        *r *= 10.0;
+        i = *s++ - '0';
+        *r += (float)i;
+      }
+      while (*s >= '0' && *s <= '9');
+    }
+    else *r = 1.0;
+    return s;
+  }
+}
+
+const char * nrRead (const char *s, number *a, const coeffs r)
+{
+
+  assume( getCoeffType(r) == ID );
+
+  static const char *nIllegalChar="illegal character in number";
+
+  const char *t;
+  const char *start=s;
+  float z1,z2;
+  float n=1.0;
+
+  s = nrEatr(s, &z1);
+  if (*s == '/')
+  {
+    if (s==start) { WerrorS(nIllegalChar);return s; }
+    s++;
+    s = nrEatr(s, &z2);
+    if (z2==0.0)
+      WerrorS(nDivBy0);
+    else
+      z1 /= z2;
+  }
+  else if (*s =='.')
+  {
+    if (s==start) { WerrorS(nIllegalChar);return s; }
+    s++;
+    t = s;
+    while (*t >= '0' && *t <= '9')
+    {
+      t++;
+      n *= 10.0;
+    }
+    s = nrEatr(s, &z2);
+    z1 = (z1*n + z2) / n;
+    if (*s=='e')
+    {
+      int e=0; /* exponent */
+      int si=1;/* sign of exponent */
+      s++;
+      if (*s=='+') s++;
+      else if (*s=='-') {s++; si=-1; }
+      while (*s >= '0' && *s <= '9')
+      {
+        e=e*10+(*s)-'0';
+        s++;
+      }
+      if (si==1)
+      {
+        while (e>0) {z1*=10.0; e--; }
+      }
+      else
+      {
+        while (e>0) {z1/=10.0; e--; }
+      }
+    }
+  }
+  *a = nf(z1).N();
+  return s;
+}
+
+
+// the last used charcteristic
+// int nrGetChar(){ return 0; }
+
+
+#ifdef LDEBUG
+/*2
+* test valid numbers: not implemented yet
+*/
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+BOOLEAN  nrDBTest(number a, const char *f, const int l, const coeffs r)
+{
+  assume( getCoeffType(r) == ID );
+
+  return TRUE;
+}
+#endif
+
+static number nrMapP(number from, const coeffs aRing, const coeffs r)
+{
+  assume( getCoeffType(r) == ID );
+  assume( getCoeffType(aRing) ==  n_Zp );
+
+  int i = (int)((long)from);
+  float f = (float)i;
+  return nf(f).N();
+}
+
+static number nrMapLongR(number from, const coeffs aRing, const coeffs r)
+{
+  assume( getCoeffType(r) == ID );
+  assume( getCoeffType(aRing) == n_long_R );
+
+  float t =(float)mpf_get_d((mpf_srcptr)from);
+  return nf(t).N();
+}
+
+static number nrMapC(number from, const coeffs aRing, const coeffs r)
+{
+  assume( getCoeffType(r) == ID );
+  assume( getCoeffType(aRing) == n_long_C );
+
+  gmp_float h = ((gmp_complex*)from)->real();
+  float t =(float)mpf_get_d((mpf_srcptr)&h);
+  return nf(t).N();
+}
+
+
+number nrMapQ(number from, const coeffs aRing, const coeffs r)
+{
+/* in longrat.h
+#define SR_INT    1
+#define mpz_size1(A) (ABS((A)->_mp_size))
+*/
+#define SR_HDL(A) ((long)(A))
+#define IS_INT(A) ((A)->s==3)
+#define IS_IMM(A) (SR_HDL(A) & SR_INT)
+#define GET_NOM(A) ((A)->z)
+#define GET_DENOM(A) ((A)->n)
+
+  assume( getCoeffType(r) == ID );
+  assume( aRing->rep == n_rep_gap_rat );
+
+  mpz_ptr z;
+  mpz_ptr zz=NULL;
+  if (IS_IMM(from))
+  {
+     zz=(mpz_ptr)omAlloc(sizeof(mpz_t));
+     mpz_init_set_si(zz,SR_TO_INT(from));
+     z=zz;
+  }
+  else
+  {
+    /* read out the enumerator */
+    z=GET_NOM(from);
+  }
+
+  int i = mpz_size1(z);
+  mpf_t e;
+  mpf_init(e);
+  mpf_set_z(e,z);
+  int sign= mpf_sgn(e);
+  mpf_abs (e, e);
+
+  if (zz!=NULL)
+  {
+    mpz_clear(zz);
+    omFreeSize(zz,sizeof(mpz_t));
+  }
+  /* if number was an integer, we are done*/
+  if(IS_IMM(from)|| IS_INT(from))
+  {
+    if(i>4)
+    {
+      WerrorS("float overflow");
+      return nf(0.0).N();
+    }
+    double basis;
+    signed long int exp;
+    basis = mpf_get_d_2exp(&exp, e);
+    float f= sign*ldexp(basis,exp);
+    mpf_clear(e);
+    return nf(f).N();
+  }
+
+  /* else read out the denominator */
+  mpz_ptr n = GET_DENOM(from);
+  int j = mpz_size1(n);
+  if(j-i>4)
+  {
+    WerrorS("float overflow");
+    mpf_clear(e);
+    return nf(0.0).N();
+  }
+  mpf_t d;
+  mpf_init(d);
+  mpf_set_z(d,n);
+
+  /* and compute the quotient */
+  mpf_t q;
+  mpf_init(q);
+  mpf_div(q,e,d);
+
+  double basis;
+  signed long int exp;
+  basis = mpf_get_d_2exp(&exp, q);
+  float f = sign*ldexp(basis,exp);
+  mpf_clear(e);
+  mpf_clear(d);
+  mpf_clear(q);
+  return nf(f).N();
+}
+
+number nrMapZ(number from, const coeffs aRing, const coeffs r)
+{
+  assume( getCoeffType(r) == ID );
+  assume( aRing->rep == n_rep_gap_gmp );
+
+  mpz_ptr z;
+  mpz_ptr zz=NULL;
+  if (IS_IMM(from))
+  {
+     zz=(mpz_ptr)omAlloc(sizeof(mpz_t));
+     mpz_init_set_si(zz,SR_TO_INT(from));
+     z=zz;
+  }
+  else
+  {
+    /* read out the enumerator */
+    z=(mpz_ptr)from;
+  }
+
+  int i = mpz_size1(z);
+  mpf_t e;
+  mpf_init(e);
+  mpf_set_z(e,z);
+  int sign= mpf_sgn(e);
+  mpf_abs (e, e);
+
+  if (zz!=NULL)
+  {
+    mpz_clear(zz);
+    omFreeSize(zz,sizeof(mpz_t));
+  }
+  if(i>4)
+  {
+    WerrorS("float overflow");
+    return nf(0.0).N();
+  }
+  double basis;
+  signed long int exp;
+  basis = mpf_get_d_2exp(&exp, e);
+  float f= sign*ldexp(basis,exp);
+  mpf_clear(e);
+  return nf(f).N();
+}
+
+// old version:
+// number nrMapQ(number from, const coeffs aRing, const coeffs r)
+// {
+// /* in longrat.h
+// #define SR_INT    1
+// #define mpz_size1(A) (ABS((A)->_mp_size))
+// */
+// #define SR_HDL(A) ((long)(A))
+// #define mpz_isNeg(A) ((A)->_mp_size<0)
+// #define mpz_limb_size(A) ((A)->_mp_size)
+// #define mpz_limb_d(A) ((A)->_mp_d)
+// #define MPZ_DIV(A,B,C) mpz_tdiv_q((A),(B),(C))
+// #define IS_INT(A) ((A)->s==3)
+// #define IS_IMM(A) (SR_HDL(A)&SR_INT)
+// #define GET_NOM(A) ((A)->z)
+// #define GET_DENOM(A) ((A)->n)
+// #define MPZ_INIT mpz_init
+// #define MPZ_CLEAR mpz_clear
+
+//   assume( getCoeffType(r) == ID );
+//   assume( getCoeffType(aRing) == n_Q );
+
+//   mpz_t h;
+//   mpz_ptr g,z,n;
+//   int i,j,t,s;
+//   float ba,rr,rn,y;
+
+//   if (IS_IMM(from))
+//     return nf((float)nlInt(from,NULL /* dummy for nlInt*/)).N();
+//   z=GET_NOM(from);
+//   s=0X10000;
+//   ba=(float)s;
+//   ba*=ba;
+//   rr=0.0;
+//   i=mpz_size1(z);
+//   if(IS_INT(from))
+//   {
+//     if(i>4)
+//     {
+//       WerrorS("float overflow");
+//       return nf(rr).N();
+//     }
+//     i--;
+//     rr=(float)mpz_limb_d(z)[i];
+//     while(i>0)
+//     {
+//       i--;
+//       y=(float)mpz_limb_d(z)[i];
+//       rr=rr*ba+y;
+//     }
+//     if(mpz_isNeg(z))
+//       rr=-rr;
+//     return nf(rr).N();
+//   }
+//   n=GET_DENOM(from);
+//   j=s=mpz_limb_size(n);
+//   if(j>i)
+//   {
+//     g=n; n=z; z=g;
+//     t=j; j=i; i=t;
+//   }
+//   t=i-j;
+//   if(t>4)
+//   {
+//     if(j==s)
+//       WerrorS("float overflow");
+//     return nf(rr).N();
+//   }
+//   if(t>1)
+//   {
+//     g=h;
+//     MPZ_INIT(g);
+//     MPZ_DIV(g,z,n);
+//     t=mpz_size1(g);
+//     if(t>4)
+//     {
+//       MPZ_CLEAR(g);
+//       if(j==s)
+//         WerrorS("float overflow");
+//       return nf(rr).N();
+//     }
+//     t--;
+//     rr=(float)mpz_limb_d(g)[t];
+//     while(t)
+//     {
+//       t--;
+//       y=(float)mpz_limb_d(g)[t];
+//       rr=rr*ba+y;
+//     }
+//     MPZ_CLEAR(g);
+//     if(j!=s)
+//       rr=1.0/rr;
+//     if(mpz_isNeg(z))
+//       rr=-rr;
+//     return nf(rr).N();
+//   }
+//   rn=(float)mpz_limb_d(n)[j-1];
+//   rr=(float)mpz_limb_d(z)[i-1];
+//   if(j>1)
+//   {
+//     rn=rn*ba+(float)mpz_limb_d(n)[j-2];
+//     rr=rr*ba+(float)mpz_limb_d(z)[i-2];
+//     i--;
+//   }
+//   if(t!=0)
+//     rr=rr*ba+(float)mpz_limb_d(z)[i-2];
+//   if(j==s)
+//     rr=rr/rn;
+//   else
+//     rr=rn/rr;
+//   if(mpz_isNeg(z))
+//     rr=-rr;
+//   return nf(rr).N();
+// }
+
+nMapFunc nrSetMap(const coeffs src, const coeffs dst)
+{
+  assume( getCoeffType(dst) == ID );
+
+  if (src->rep==n_rep_gap_rat) /*Q, Z */
+  {
+    return nrMapQ;
+  }
+  if (src->rep==n_rep_gap_gmp) /*Q, Z */
+  {
+    return nrMapZ;
+  }
+  if ((src->rep==n_rep_gmp_float) && nCoeff_is_long_R(src))
+  {
+    return nrMapLongR;
+  }
+  if ((src->rep==n_rep_float) && nCoeff_is_R(src))
+  {
+    return ndCopyMap;
+  }
+  if ((src->rep==n_rep_int) && nCoeff_is_Zp(src))
+  {
+    return nrMapP;
+  }
+  if ((src->rep==n_rep_gmp_complex) && nCoeff_is_long_C(src))
+  {
+    return nrMapC;
+  }
+  return NULL;
+}
+
+static char* nrCoeffString(const coeffs r)
+{
+  return omStrDup("real");
+}
+
+BOOLEAN nrInitChar(coeffs n, void* p)
+{
+  assume( getCoeffType(n) == ID );
+
+  assume( p == NULL );
+
+  n->is_field=TRUE;
+  n->is_domain=TRUE;
+  n->rep=n_rep_float;
+
+  //n->cfKillChar = ndKillChar; /* dummy */
+  n->ch = 0;
+  n->cfCoeffString = nrCoeffString;
+
+  n->cfInit = nrInit;
+  n->cfInt  = nrInt;
+  n->cfAdd   = nrAdd;
+  n->cfSub   = nrSub;
+  n->cfMult  = nrMult;
+  n->cfDiv   = nrDiv;
+  n->cfExactDiv= nrDiv;
+  n->cfInpNeg   = nrNeg;
+  n->cfInvers= nrInvers;
+  //n->cfCopy  = ndCopy;
+  n->cfGreater = nrGreater;
+  n->cfEqual = nrEqual;
+  n->cfIsZero = nrIsZero;
+  n->cfIsOne = nrIsOne;
+  n->cfIsMOne = nrIsMOne;
+  n->cfGreaterZero = nrGreaterZero;
+  n->cfWriteLong = nrWrite;
+  n->cfRead = nrRead;
+  //n->cfPower = nrPower;
+  n->cfSetMap = nrSetMap;
+  n->cfCoeffWrite  = nrCoeffWrite;
+
+    /* nName= ndName; */
+    /*nSize  = ndSize;*/
+#ifdef LDEBUG
+  //n->cfDBTest=ndDBTest; // not yet implemented: nrDBTest;
+#endif
+
+  //n->nCoeffIsEqual = ndCoeffIsEqual;
+
+  n->float_len = SHORT_REAL_LENGTH;
+  n->float_len2 = SHORT_REAL_LENGTH;
+
+  // TODO: Any variables?
+  return FALSE;
+}
diff --git a/libpolys/coeffs/shortfl.h b/libpolys/coeffs/shortfl.h
new file mode 100644
index 0000000..8917261
--- /dev/null
+++ b/libpolys/coeffs/shortfl.h
@@ -0,0 +1,22 @@
+#ifndef SHORTFL_H
+#define SHORTFL_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT
+*/
+#include <misc/auxiliary.h>
+
+struct n_Procs_s; typedef struct  n_Procs_s  *coeffs;
+struct snumber; typedef struct snumber *   number;
+
+/// Initialize r
+BOOLEAN nrInitChar(coeffs r, void*);
+
+// will be reused by gnumpc.cc and longrat.cc
+/// Converts a n_R number into a float. Needed by Maps
+float   nrFloat(number n);
+
+#endif
+
diff --git a/libpolys/coeffs/si_gmp.h b/libpolys/coeffs/si_gmp.h
new file mode 100644
index 0000000..ca72779
--- /dev/null
+++ b/libpolys/coeffs/si_gmp.h
@@ -0,0 +1,17 @@
+#ifndef COEFFS_SI_GMP_H
+#define COEFFS_SI_GMP_H
+
+#include <stddef.h>
+
+// just assume that factory have been built (cplusplus.h!)
+// instead of duplicating cf_gmp.h here for now...
+#include <factory/cf_gmp.h>
+
+#ifndef mpz_size1
+// This is taken from longrat.h: it seems to be generally GMP-related
+#define mpz_size1(A) (ABS((A)->_mp_size))
+//#define mpz_size1(A) mpz_size(A)
+#endif // mpz_size1
+
+
+#endif /* ! COEFFS_SI_GMP_H */
diff --git a/libpolys/coeffs/test.cc b/libpolys/coeffs/test.cc
new file mode 100644
index 0000000..2e5f3f8
--- /dev/null
+++ b/libpolys/coeffs/test.cc
@@ -0,0 +1,319 @@
+#include <misc/auxiliary.h>
+
+#include <factory/factory.h>
+
+#include <omalloc/omalloc.h>
+
+#include <reporter/reporter.h>
+#include <resources/feResource.h>
+
+#include "coeffs.h"
+#include "numbers.h"
+
+#include "longrat.h"
+#include "gnumpfl.h"
+#include "gnumpc.h"
+#include "shortfl.h"
+#include "ffields.h"
+#include "modulop.h"
+#include "rmodulon.h"
+#include "rmodulo2m.h"
+#include "rintegers.h"
+
+
+#include <iostream>
+
+using namespace std;
+
+#pragma GCC diagnostic ignored "-Wwrite-strings"
+
+void Print(/*const*/ number a, const coeffs r, BOOLEAN eoln = TRUE)
+{
+  n_Test(a,r);
+
+  StringSetS("");
+  n_Write(a, r);
+
+
+  if( eoln )
+    PrintLn();
+
+  { char* s = StringEndS(); PrintS(s); omFree(s); }
+}
+
+
+void PrintSized(/*const*/ number a, const coeffs r, BOOLEAN eoln = TRUE)
+{
+  Print(a, r, FALSE);
+  Print(", of size: %d", n_Size(a, r));
+
+  if( eoln )
+    PrintLn();
+}
+
+
+
+bool TestArith(const coeffs r)
+{
+  number a = n_Init(66666, r);
+
+  PrintS("a: "); PrintSized(a, r);
+
+  number two = n_Init(2, r);
+
+  PrintS("two: "); PrintSized(two, r);
+
+  if (n_NumberOfParameters(r) > 0)
+  {
+    number z = n_Param(1, r); // also any integer instead of 0//?
+
+    PrintS("Parameter: "); PrintSized(z, r);
+
+    n_Delete(&z, r);
+  }
+
+  number aa = n_Add(a, a, r);
+
+  PrintS("aa = a + a: "); PrintSized(aa, r);
+
+  number aa2 = n_Mult(a, two, r);
+
+  PrintS("aa2 = a * 2: "); PrintSized(aa2, r);
+
+  number aa1 = n_Mult(two, a, r);
+
+  PrintS("aa1 = 2 * a: "); PrintSized(aa1, r);
+
+  n_Delete(&a, r);
+  n_Delete(&two, r);
+
+
+  a = n_Sub( aa, aa1, r );
+
+  PrintS("a = aa - aa1: "); PrintSized(a, r);
+
+  if( !n_IsZero(a, r) )
+    WarnS("TestArith: ERROR: a != 0 !!!\n");
+
+  n_Delete(&a, r);
+
+  a = n_Sub( aa, aa2, r );
+
+  PrintS("a = aa - aa2: "); PrintSized(a, r);
+
+  if( !n_IsZero(a, r) )
+    WarnS("TestArith: ERROR: a != 0 !!!\n");
+
+  n_Delete(&a, r);
+
+
+  a = n_Sub( aa1, aa2, r );
+
+  PrintS("a = aa1 - aa2: "); PrintSized(a, r);
+
+  if( !n_IsZero(a, r) )
+    WarnS("TestArith: ERROR: a != 0 !!!\n");
+
+  n_Delete(&a, r);
+
+
+
+  if( !n_Equal(aa, aa1, r) )
+    WarnS("TestArith: ERROR: aa != aa1  !!!\n");
+
+  if( !n_Equal(aa, aa2, r) )
+    WarnS("TestArith: ERROR: aa != aa2  !!!\n");
+
+  if( !n_Equal(aa1, aa2, r) )
+    WarnS("TestArith: ERROR: aa1 != aa2  !!!\n");
+
+
+
+
+  n_Delete(&aa, r);
+  n_Delete(&aa1, r);
+  n_Delete(&aa2, r);
+
+  return false;
+}
+
+
+
+namespace
+{
+  static inline ostream& operator<< (ostream& o, const n_coeffType& type)
+  {
+#define CASE(A) case A: return o << (" " # A) << " ";
+    switch( type )
+    {
+      CASE(n_unknown);
+      CASE(n_Zp);
+      CASE(n_Q);
+      CASE(n_R);
+      CASE(n_GF);
+      CASE(n_long_R);
+      CASE(n_algExt);
+      CASE(n_transExt);
+      CASE(n_long_C);
+      CASE(n_Z);
+      CASE(n_Zn);
+      CASE(n_Znm);
+      CASE(n_Z2m);
+      CASE(n_CF);
+      default: return o << "Unknown type: [" << (const unsigned long) type << "]";
+    }
+#undef CASE
+    return o;
+  }
+}
+
+
+bool Test(const n_coeffType type, void* p = NULL)
+{
+  cout  << endl << "----------------------- Testing coeffs: [" << type << ", " << p <<
+                "]: -----------------------" << endl;
+
+  const coeffs r = nInitChar( type, p );
+
+  if( r == NULL ) { cout << "Test: could not get the specified coeff. domain for type: " << type << " and the parameter: " << p << endl; return false; };
+
+  assume( r != NULL );
+  nSetChar( r );
+  assume( getCoeffType(r) == type );
+
+  assume( r->cfInit != NULL );
+  assume( r->cfWriteLong != NULL );
+  assume( r->cfAdd != NULL );
+  assume( r->cfDelete != NULL );
+  assume( r->cfKillChar != NULL );
+
+  bool ret = TestArith( r );
+
+  nKillChar( r );
+
+  return ret;
+}
+
+
+int main( int, char *argv[] )
+{
+  assume( sizeof(long) == SIZEOF_LONG );
+
+  if( sizeof(long) != SIZEOF_LONG )
+  {
+    WerrorS("Bad config.h: wrong size of long!");
+
+    return(1);
+  }
+
+
+  feInitResources(argv[0]);
+
+  StringSetS("ressources in use (as reported by feStringAppendResources(0):\n");
+  feStringAppendResources(0);
+  PrintLn();
+
+  { char* s = StringEndS(); PrintS(s); omFree(s); }
+
+  int c = 0;
+
+  n_coeffType type;
+
+
+#ifdef HAVE_RINGS
+//  TODO(Frank, Segmentation fault! (if used wihout omalloc???). Please_ investigate!);
+  type =  n_Z2m;
+  if( Test(type, (void*) 4) )
+    c ++;
+#endif
+
+  type =  n_Zp;
+  if( Test(type, (void*) 101) )
+    c ++;
+
+#ifdef HAVE_RINGS
+//  TODO(Frank, memmory corruption_ if used wihout omalloc??? Please_ investigate!);
+
+  type = n_Z2m;
+  if( Test(type, (void*) 8) )
+    c ++;
+
+#endif
+
+
+  type =  n_Q;
+  if( Test(type) )
+    c ++;
+
+  type = n_R;
+  if( Test(type) )
+    c ++;
+
+#ifdef HAVE_RINGS
+  type = n_Z;
+  if( Test(type) )
+    c ++;
+#endif
+   type = n_GF;
+
+
+   GFInfo* param = new GFInfo();
+
+   param->GFChar= 5;
+   param->GFDegree= 12;
+   param->GFPar_name= (const char*)"q";
+
+   if( Test(type, (void*) param) )
+     c ++;
+
+   // it should not be used by numbers... right?
+   // TODO: what is our policy wrt param-pointer-ownership?
+   delete param;
+   // Q: no way to deRegister a type?
+
+   param = new GFInfo();
+
+   param->GFChar= 5;
+   param->GFDegree= 2;
+   param->GFPar_name= (const char*)"Q";
+
+   if( Test(type, (void*) param) )
+     c ++;
+
+   delete param;
+
+
+
+
+#ifdef HAVE_RINGS
+  type = n_Zn;
+
+  ZnmInfo Znmparam;
+  Znmparam.base= (mpz_ptr) omAlloc (sizeof (mpz_t));
+  mpz_init_set_ui (Znmparam.base, 3);
+  Znmparam.exp= 1;
+
+  if( Test(type, (void*) &Znmparam) )
+    c ++;
+
+#endif
+
+  type = n_long_C;
+  if( Test(type) )
+    c ++;
+
+  type = n_long_R;
+  if( Test(type) )
+    c ++;
+
+#ifdef HAVE_RINGS
+  type = n_Z2m;
+  if( Test(type, (void*) 2) )
+    c ++;
+#endif
+
+  // polynomial rings needed for: n_algExt, n_transExt !
+
+  return c;
+
+}
diff --git a/libpolys/configure b/libpolys/configure
new file mode 100755
index 0000000..3f707a8
--- /dev/null
+++ b/libpolys/configure
@@ -0,0 +1,24151 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.69 for libpolys 4.0.1.
+#
+#
+# Copyright (C) 1992-1996, 1998-2012 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.
+as_myself=
+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
+
+# Use a proper internal environment variable to ensure we don't fall
+  # into an infinite loop, continuously re-executing ourselves.
+  if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then
+    _as_can_reexec=no; export _as_can_reexec;
+    # 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.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+  *v*x* | *x*v* ) as_opts=-vx ;;
+  *v* ) as_opts=-v ;;
+  *x* ) as_opts=-x ;;
+  * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+as_fn_exit 255
+  fi
+  # We don't want this to propagate to other subprocesses.
+          { _as_can_reexec=; unset _as_can_reexec;}
+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
+test -x / || 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 -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || (
+    ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+    ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO
+    ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO
+    PATH=/empty FPATH=/empty; export PATH FPATH
+    test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\
+      || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || 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 :
+  export CONFIG_SHELL
+             # 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.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+  *v*x* | *x*v* ) as_opts=-vx ;;
+  *v* ) as_opts=-v ;;
+  *x* ) as_opts=-x ;;
+  * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+exit 255
+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_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+  test -f "$1" && test -x "$1"
+} # as_fn_executable_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 STATUS 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=$1; test $as_status -eq 0 && as_status=1
+  if test "$4"; then
+    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+  fi
+  $as_echo "$as_me: error: $2" >&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; }
+
+  # If we had to re-execute with $CONFIG_SHELL, we're ensured to have
+  # already done that, so ensure we don't try to do so again and fall
+  # in an infinite loop.  This has already happened in practice.
+  _as_can_reexec=no; export _as_can_reexec
+  # 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 -pR'.
+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+      as_ln_s='cp -pR'
+  elif ln conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s=ln
+  else
+    as_ln_s='cp -pR'
+  fi
+else
+  as_ln_s='cp -pR'
+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
+
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
+
+# 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'"
+
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+
+test -n "$DJDIR" || exec 7<&0 </dev/null
+exec 6>&1
+
+# Name of the host.
+# hostname on some systems (SVR3.2, old GNU/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='libpolys'
+PACKAGE_TARNAME='libpolys'
+PACKAGE_VERSION='4.0.1'
+PACKAGE_STRING='libpolys 4.0.1'
+PACKAGE_BUGREPORT=''
+PACKAGE_URL=''
+
+ac_unique_file="reporter/reporter.h"
+# 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
+ENABLE_PLURAL_FALSE
+ENABLE_PLURAL_TRUE
+ENABLE_RINGS_FALSE
+ENABLE_RINGS_TRUE
+ENABLE_P_PROCS_STATIC_FALSE
+ENABLE_P_PROCS_STATIC_TRUE
+ENABLE_P_PROCS_DYNAMIC_FALSE
+ENABLE_P_PROCS_DYNAMIC_TRUE
+USEPPROCSDYNAMICLD
+USEPPROCSDYNAMICLDFLAGS
+ENABLE_FACTORY_FALSE
+ENABLE_FACTORY_TRUE
+FACTORY_LIBS
+FACTORY_INCLUDES
+ENABLE_RESOURCES_FALSE
+ENABLE_RESOURCES_TRUE
+RESOURCES_LIBS
+RESOURCES_INCLUDES
+ENABLE_OMALLOC_FALSE
+ENABLE_OMALLOC_TRUE
+PKG_REQUIRE
+OMALLOC_LIBS
+OMALLOC_INCLUDES
+SI_CPU_PPC
+SI_CPU_SPARC
+SI_CPU_IA64
+SI_CPU_X86_64
+SI_CPU_I386
+LIBOBJS
+SING_HAVE_FLINT_FALSE
+SING_HAVE_FLINT_TRUE
+FLINT_HOME
+FLINT_LIBS
+FLINT_CFLAGS
+SING_HAVE_NTL_FALSE
+SING_HAVE_NTL_TRUE
+NTL_LIBS
+NTL_CFLAGS
+SING_HAVE_GMP_FALSE
+SING_HAVE_GMP_TRUE
+GMP_VERSION
+GMP_HOME
+GMP_LIBS
+GMP_CFLAGS
+CXXCPP
+CPP
+OTOOL64
+OTOOL
+LIPO
+NMEDIT
+DSYMUTIL
+MANIFEST_TOOL
+RANLIB
+DLLTOOL
+OBJDUMP
+NM
+ac_ct_DUMPBIN
+DUMPBIN
+LD
+FGREP
+EGREP
+GREP
+SED
+host_os
+host_vendor
+host_cpu
+host
+build_os
+build_vendor
+build_cpu
+build
+LIBTOOL
+LN_S
+POLYMAKE_CXXFLAGS
+am__fastdepCXX_FALSE
+am__fastdepCXX_TRUE
+CXXDEPMODE
+ac_ct_CXX
+CXXFLAGS
+CXX
+SINGULAR_CFLAGS
+WANT_OPTIMIZATIONFLAGS_FALSE
+WANT_OPTIMIZATIONFLAGS_TRUE
+WANT_DEBUG_FALSE
+WANT_DEBUG_TRUE
+am__fastdepCC_FALSE
+am__fastdepCC_TRUE
+CCDEPMODE
+am__nodep
+AMDEPBACKSLASH
+AMDEP_FALSE
+AMDEP_TRUE
+am__quote
+am__include
+DEPDIR
+OBJEXT
+EXEEXT
+ac_ct_CC
+CPPFLAGS
+LDFLAGS
+CFLAGS
+CC
+ac_ct_AR
+AR
+AM_BACKSLASH
+AM_DEFAULT_VERBOSITY
+AM_DEFAULT_V
+AM_V
+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
+MAINT
+MAINTAINER_MODE_FALSE
+MAINTAINER_MODE_TRUE
+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
+enable_silent_rules
+enable_dependency_tracking
+enable_debug
+enable_optimizationflags
+enable_shared
+enable_static
+with_pic
+enable_fast_install
+with_gnu_ld
+with_sysroot
+enable_libtool_lock
+with_gmp
+with_ntl
+with_flint
+enable_omalloc
+enable_factory
+enable_p_procs_static
+enable_p_procs_dynamic
+enable_arith_rings
+enable_plural
+with_RatGB
+'
+      ac_precious_vars='build_alias
+host_alias
+target_alias
+CC
+CFLAGS
+LDFLAGS
+LIBS
+CPPFLAGS
+CXX
+CXXFLAGS
+CCC
+CPP
+CXXCPP
+OMALLOC_INCLUDES
+OMALLOC_LIBS
+RESOURCES_INCLUDES
+RESOURCES_LIBS
+FACTORY_INCLUDES
+FACTORY_LIBS'
+
+
+# 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_TARNAME}'
+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= ;;
+  *)    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
+  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 libpolys 4.0.1 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/libpolys]
+  --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
+  case $ac_init_help in
+     short | recursive ) echo "Configuration of libpolys 4.0.1:";;
+   esac
+  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]
+  --disable-maintainer-mode
+                          disable make rules and dependencies not useful (and
+                          sometimes confusing) to the casual installer
+  --enable-silent-rules   less verbose build output (undo: "make V=1")
+  --disable-silent-rules  verbose build output (undo: "make V=0")
+  --enable-dependency-tracking
+                          do not reject slow dependency extractors
+  --disable-dependency-tracking
+                          speeds up one-time build
+  --enable-debug          build the debugging version of the libraries
+  --disable-optimizationflags
+                          build the without default optimization flags
+  --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-omalloc        build for use with omalloc
+  --disable-factory       Disable factory
+  --enable-p-procs-static Enable statically compiled p_Procs-modules
+
+  --enable-p-procs-dynamic Enable dynamically compiled p_Procs-modules
+
+  --disable-arith-rings   Disable arithmetical rings
+  --disable-plural        Disable non-commutative subsystem
+
+Optional Packages:
+  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
+  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
+  --with-pic[=PKGS]       try to use only PIC/non-PIC objects [default=use
+                          both]
+  --with-gnu-ld           assume the C compiler uses GNU ld [default=no]
+  --with-sysroot=DIR Search for dependent libraries within DIR
+                        (or the compiler's sysroot if not specified).
+  --with-gmp= <path>|yes Use GMP library. This library is mandatory for Singular
+	                 compilation. If argument is yes or <empty> that means
+   	       		 the library is reachable with the standard search path
+			 "/usr" or "/usr/local" (set as default). Otherwise you
+			 give the <path> to the directory which contain the
+			 library.
+
+  --with-ntl=<path>|yes|no  Use NTL library. If argument is no, you do not have
+                            the library installed on your machine (set as
+			    default). If argument is yes or <empty> that means
+			    the library is reachable with the standard search
+			    path (/usr or /usr/local). Otherwise you give the
+			    <path> to the directory which contain the library.
+
+  --with-flint=<path>|yes|no  Use FLINT library. If argument is no, you do not have
+                            the library installed on your machine (set as
+			    default). If argument is yes or <empty> that means
+			    the library is reachable with the standard search
+			    path (/usr or /usr/local). Otherwise you give the
+			    <path> to the directory which contain the library.
+
+  --with-ratGB            do compile with ratGB support (experimental)
+
+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    (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
+              you have headers in a nonstandard directory <include dir>
+  CXX         C++ compiler command
+  CXXFLAGS    C++ compiler flags
+  CPP         C preprocessor
+  CXXCPP      C++ preprocessor
+  OMALLOC_INCLUDES
+              INCLUDES for libomalloc
+  OMALLOC_LIBS
+              LIBS for libomalloc
+  RESOURCES_INCLUDES
+              INCLUDES for libresources
+  RESOURCES_LIBS
+              LIBS for libresources
+  FACTORY_INCLUDES
+              INCLUDES for FACTORY
+  FACTORY_LIBS
+              LIBS for FACTORY
+
+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
+libpolys configure 4.0.1
+generated by GNU Autoconf 2.69
+
+Copyright (C) 2012 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; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_compile
+
+# ac_fn_cxx_try_compile LINENO
+# ----------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_cxx_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_cxx_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; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_cxx_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 ||
+	 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; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $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 eval \${$3+:} false; 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; ${as_lineno_stack:+:} 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; } > conftest.i && {
+	 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; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $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; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $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 eval \${$3+:} false; 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; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_func
+
+# ac_fn_cxx_try_cpp LINENO
+# ------------------------
+# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
+ac_fn_cxx_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; } > conftest.i && {
+	 test -z "$ac_cxx_preproc_warn_flag$ac_cxx_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; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_cxx_try_cpp
+
+# ac_fn_cxx_try_link LINENO
+# -------------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded.
+ac_fn_cxx_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_cxx_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext && {
+	 test "$cross_compiling" = yes ||
+	 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; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_cxx_try_link
+
+# ac_fn_cxx_try_run LINENO
+# ------------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes
+# that executables *can* be run.
+ac_fn_cxx_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; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_cxx_try_run
+
+# 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 eval \${$3+:} false; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; 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.i 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 eval \${$3+:} false; 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; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_header_mongrel
+
+# ac_fn_c_check_type LINENO TYPE VAR INCLUDES
+# -------------------------------------------
+# Tests whether TYPE exists after having included INCLUDES, setting cache
+# variable VAR accordingly.
+ac_fn_c_check_type ()
+{
+  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 eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  eval "$3=no"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+if (sizeof ($2))
+	 return 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+if (sizeof (($2)))
+	    return 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+  eval "$3=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
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_type
+
+# ac_fn_c_compute_int LINENO EXPR VAR INCLUDES
+# --------------------------------------------
+# Tries to find the compile-time value of EXPR in a program that includes
+# INCLUDES, setting VAR accordingly. Returns whether the value could be
+# computed
+ac_fn_c_compute_int ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if test "$cross_compiling" = yes; then
+    # Depending upon the size, compute the lo and hi bounds.
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) >= 0)];
+test_array [0] = 0;
+return test_array [0];
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_lo=0 ac_mid=0
+  while :; do
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) <= $ac_mid)];
+test_array [0] = 0;
+return test_array [0];
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_hi=$ac_mid; break
+else
+  as_fn_arith $ac_mid + 1 && ac_lo=$as_val
+			if test $ac_lo -le $ac_mid; then
+			  ac_lo= ac_hi=
+			  break
+			fi
+			as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) < 0)];
+test_array [0] = 0;
+return test_array [0];
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_hi=-1 ac_mid=-1
+  while :; do
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) >= $ac_mid)];
+test_array [0] = 0;
+return test_array [0];
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_lo=$ac_mid; break
+else
+  as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val
+			if test $ac_mid -le $ac_hi; then
+			  ac_lo= ac_hi=
+			  break
+			fi
+			as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
+else
+  ac_lo= ac_hi=
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+# Binary search between lo and hi bounds.
+while test "x$ac_lo" != "x$ac_hi"; do
+  as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) <= $ac_mid)];
+test_array [0] = 0;
+return test_array [0];
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_hi=$ac_mid
+else
+  as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+case $ac_lo in #((
+?*) eval "$3=\$ac_lo"; ac_retval=0 ;;
+'') ac_retval=1 ;;
+esac
+  else
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+static long int longval () { return $2; }
+static unsigned long int ulongval () { return $2; }
+#include <stdio.h>
+#include <stdlib.h>
+int
+main ()
+{
+
+  FILE *f = fopen ("conftest.val", "w");
+  if (! f)
+    return 1;
+  if (($2) < 0)
+    {
+      long int i = longval ();
+      if (i != ($2))
+	return 1;
+      fprintf (f, "%ld", i);
+    }
+  else
+    {
+      unsigned long int i = ulongval ();
+      if (i != ($2))
+	return 1;
+      fprintf (f, "%lu", i);
+    }
+  /* Do not output a trailing newline, as this causes \r\n confusion
+     on some platforms.  */
+  return ferror (f) || fclose (f) != 0;
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  echo >>conftest.val; read $3 <conftest.val; ac_retval=0
+else
+  ac_retval=1
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+rm -f conftest.val
+
+  fi
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_compute_int
+
+# ac_fn_cxx_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_cxx_check_header_mongrel ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if eval \${$3+:} false; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; 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_cxx_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_cxx_try_cpp "$LINENO"; then :
+  ac_header_preproc=yes
+else
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.i 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_cxx_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 eval \${$3+:} false; 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; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_cxx_check_header_mongrel
+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 libpolys $as_me 4.0.1, which was
+generated by GNU Autoconf 2.69.  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
+
+    $as_echo "## ---------------- ##
+## Cache variables. ##
+## ---------------- ##"
+    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
+
+    $as_echo "## ----------------- ##
+## Output variables. ##
+## ----------------- ##"
+    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
+      $as_echo "## ------------------- ##
+## File substitutions. ##
+## ------------------- ##"
+      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
+      $as_echo "## ----------- ##
+## confdefs.h. ##
+## ----------- ##"
+      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
+  # We do not want a PATH search for config.site.
+  case $CONFIG_SITE in #((
+    -*)  ac_site_file1=./$CONFIG_SITE;;
+    */*) ac_site_file1=$CONFIG_SITE;;
+    *)   ac_site_file1=./$CONFIG_SITE;;
+  esac
+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 /dev/null != "$ac_site_file" && 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" \
+      || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "failed to load site script $ac_site_file
+See \`config.log' for more details" "$LINENO" 5; }
+  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.  DJGPP emulates it as a regular file.
+  if test /dev/null != "$cache_file" && 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_aux_dir=
+for ac_dir in ../build-aux "$srcdir"/../build-aux; do
+  if test -f "$ac_dir/install-sh"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install-sh -c"
+    break
+  elif test -f "$ac_dir/install.sh"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install.sh -c"
+    break
+  elif test -f "$ac_dir/shtool"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/shtool install -c"
+    break
+  fi
+done
+if test -z "$ac_aux_dir"; then
+  as_fn_error $? "cannot find install-sh, install.sh, or shtool in ../build-aux \"$srcdir\"/../build-aux" "$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.
+
+
+
+ac_config_headers="$ac_config_headers _config.h"
+
+
+
+{ $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=yes
+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
+
+
+
+am__api_version='1.13'
+
+# 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 ${ac_cv_path_install+:} false; 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 as_fn_executable_p "$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; }
+# 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 (
+   am_has_slept=no
+   for am_try in 1 2; do
+     echo "timestamp, slept: $am_has_slept" > conftest.file
+     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
+     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
+     if test "$2" = conftest.file || test $am_try -eq 2; then
+       break
+     fi
+     # Just in case.
+     sleep 1
+     am_has_slept=yes
+   done
+   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; }
+# If we didn't sleep, we still need to ensure time stamps of config.status and
+# generated files are strictly newer.
+am_sleep_pid=
+if grep 'slept: no' conftest.file >/dev/null 2>&1; then
+  ( sleep 1 ) &
+  am_sleep_pid=$!
+fi
+
+rm -f conftest.file
+
+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 --is-lightweight"; then
+  am_missing_run="$MISSING "
+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 ${ac_cv_prog_STRIP+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_STRIP+:} false; 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 as_fn_executable_p "$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 ${ac_cv_path_mkdir+:} false; 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
+	   as_fn_executable_p "$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
+
+  test -d ./--version && rmdir ./--version
+  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.
+    MKDIR_P="$ac_install_sh -d"
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5
+$as_echo "$MKDIR_P" >&6; }
+
+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 ${ac_cv_prog_AWK+:} false; 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 as_fn_executable_p "$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 eval \${ac_cv_prog_make_${ac_make}_set+:} false; 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
+
+# Check whether --enable-silent-rules was given.
+if test "${enable_silent_rules+set}" = set; then :
+  enableval=$enable_silent_rules;
+fi
+
+case $enable_silent_rules in # (((
+  yes) AM_DEFAULT_VERBOSITY=0;;
+   no) AM_DEFAULT_VERBOSITY=1;;
+    *) AM_DEFAULT_VERBOSITY=1;;
+esac
+am_make=${MAKE-make}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5
+$as_echo_n "checking whether $am_make supports nested variables... " >&6; }
+if ${am_cv_make_support_nested_variables+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if $as_echo 'TRUE=$(BAR$(V))
+BAR0=false
+BAR1=true
+V=1
+am__doit:
+	@$(TRUE)
+.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then
+  am_cv_make_support_nested_variables=yes
+else
+  am_cv_make_support_nested_variables=no
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5
+$as_echo "$am_cv_make_support_nested_variables" >&6; }
+if test $am_cv_make_support_nested_variables = yes; then
+    AM_V='$(V)'
+  AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
+else
+  AM_V=$AM_DEFAULT_VERBOSITY
+  AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY
+fi
+AM_BACKSLASH='\'
+
+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='libpolys'
+ VERSION='4.0.1'
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE "$PACKAGE"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define VERSION "$VERSION"
+_ACEOF
+
+# 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"}
+
+# For better backward compatibility.  To be removed once Automake 1.9.x
+# dies out for good.  For more background, see:
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
+mkdir_p='$(MKDIR_P)'
+
+# We need awk for the "check" target.  The system "awk" is bad on
+# some platforms.
+# Always define AMTAR for backward compatibility.  Yes, it's still used
+# in the wild :-(  We should find a proper way to deprecate it ...
+AMTAR='$${TAR-tar}'
+
+
+# We'll loop over all known methods to create a tar archive until one works.
+_am_tools='gnutar  pax cpio none'
+
+am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'
+
+
+
+
+
+ # -Wno-extra-portability -Werror silent-rules
+# Check whether --enable-silent-rules was given.
+if test "${enable_silent_rules+set}" = set; then :
+  enableval=$enable_silent_rules;
+fi
+
+case $enable_silent_rules in # (((
+  yes) AM_DEFAULT_VERBOSITY=0;;
+   no) AM_DEFAULT_VERBOSITY=1;;
+    *) AM_DEFAULT_VERBOSITY=0;;
+esac
+am_make=${MAKE-make}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5
+$as_echo_n "checking whether $am_make supports nested variables... " >&6; }
+if ${am_cv_make_support_nested_variables+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if $as_echo 'TRUE=$(BAR$(V))
+BAR0=false
+BAR1=true
+V=1
+am__doit:
+	@$(TRUE)
+.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then
+  am_cv_make_support_nested_variables=yes
+else
+  am_cv_make_support_nested_variables=no
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5
+$as_echo "$am_cv_make_support_nested_variables" >&6; }
+if test $am_cv_make_support_nested_variables = yes; then
+    AM_V='$(V)'
+  AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
+else
+  AM_V=$AM_DEFAULT_VERBOSITY
+  AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY
+fi
+AM_BACKSLASH='\'
+
+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='\'
+  am__nodep='_no'
+fi
+ if test "x$enable_dependency_tracking" != xno; then
+  AMDEP_TRUE=
+  AMDEP_FALSE='#'
+else
+  AMDEP_TRUE='#'
+  AMDEP_FALSE=
+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 ${ac_cv_prog_CC+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_CC+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_CC+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_CC+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_CC+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_CC+:} false; 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 as_fn_executable_p "$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
+  fi
+  rm -f conftest.er1 conftest.err
+  $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.  */
+
+int
+main ()
+{
+
+  ;
+  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"
+# 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 whether the C compiler works" >&5
+$as_echo_n "checking whether the C compiler works... " >&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
+if test -z "$ac_file"; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+$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 77 "C compiler cannot create executables
+See \`config.log' for more details" "$LINENO" 5; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+fi
+{ $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; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
+$as_echo "$ac_file" >&6; }
+ac_exeext=$ac_cv_exeext
+
+rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+{ $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 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
+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="$ac_clean_files conftest.out"
+# 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; }
+if test "$cross_compiling" != yes; then
+  { { 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; }
+  if { ac_try='./conftest$ac_cv_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
+    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: $cross_compiling" >&5
+$as_echo "$cross_compiling" >&6; }
+
+rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out
+ac_clean_files=$ac_clean_files_save
+{ $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 ${ac_cv_objext+:} false; 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 ${ac_cv_c_compiler_gnu+:} false; 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 ${ac_cv_prog_cc_g+:} false; 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 ${ac_cv_prog_cc_c89+:} false; 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>
+struct stat;
+/* 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
+
+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 ${am_cv_CC_dependencies_compiler_type+:} false; 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".
+  rm -rf conftest.dir
+  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 10 /bin/sh.
+      echo '/* dummy */' > 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
+      ;;
+    msvc7 | msvc7msys | 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 -n "$ac_tool_prefix"; then
+  for ac_prog in ar lib "link -lib"
+  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 ${ac_cv_prog_AR+:} false; 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_AR="$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
+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
+
+
+    test -n "$AR" && break
+  done
+fi
+if test -z "$AR"; then
+  ac_ct_AR=$AR
+  for ac_prog in ar lib "link -lib"
+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 ${ac_cv_prog_ac_ct_AR+:} false; 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_AR="$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_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
+
+
+  test -n "$ac_ct_AR" && break
+done
+
+  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
+fi
+
+: ${AR=ar}
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the archiver ($AR) interface" >&5
+$as_echo_n "checking the archiver ($AR) interface... " >&6; }
+if ${am_cv_ar_interface+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  am_cv_ar_interface=ar
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+int some_variable = 0;
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  am_ar_try='$AR cru libconftest.a conftest.$ac_objext >&5'
+      { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$am_ar_try\""; } >&5
+  (eval $am_ar_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      if test "$ac_status" -eq 0; then
+        am_cv_ar_interface=ar
+      else
+        am_ar_try='$AR -NOLOGO -OUT:conftest.lib conftest.$ac_objext >&5'
+        { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$am_ar_try\""; } >&5
+  (eval $am_ar_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+        if test "$ac_status" -eq 0; then
+          am_cv_ar_interface=lib
+        else
+          am_cv_ar_interface=unknown
+        fi
+      fi
+      rm -f conftest.lib libconftest.a
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_ar_interface" >&5
+$as_echo "$am_cv_ar_interface" >&6; }
+
+case $am_cv_ar_interface in
+ar)
+  ;;
+lib)
+  # Microsoft lib, so override with the ar-lib wrapper script.
+  # FIXME: It is wrong to rewrite AR.
+  # But if we don't then we get into trouble of one sort or another.
+  # A longer-term fix would be to have automake use am__AR in this case,
+  # and then we could set am__AR="$am_aux_dir/ar-lib \$(AR)" or something
+  # similar.
+  AR="$am_aux_dir/ar-lib $AR"
+  ;;
+unknown)
+  as_fn_error $? "could not determine $AR interface" "$LINENO" 5
+  ;;
+esac
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5
+$as_echo_n "checking whether build environment is sane... " >&6; }
+# 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 (
+   am_has_slept=no
+   for am_try in 1 2; do
+     echo "timestamp, slept: $am_has_slept" > conftest.file
+     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
+     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
+     if test "$2" = conftest.file || test $am_try -eq 2; then
+       break
+     fi
+     # Just in case.
+     sleep 1
+     am_has_slept=yes
+   done
+   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; }
+# If we didn't sleep, we still need to ensure time stamps of config.status and
+# generated files are strictly newer.
+am_sleep_pid=
+if grep 'slept: no' conftest.file >/dev/null 2>&1; then
+  ( sleep 1 ) &
+  am_sleep_pid=$!
+fi
+
+rm -f conftest.file
+
+
+# Add pre'prefixed config
+
+ac_config_commands="$ac_config_commands libpolysconfig.h"
+
+
+# - Check for CC and CXX but be careful about CFLAGS.
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Please note that we set empty defaults for \`CFLAGS' and \`CXXFLAGS' (instead of \`-g -O')" >&5
+$as_echo "$as_me: WARNING: Please note that we set empty defaults for \`CFLAGS' and \`CXXFLAGS' (instead of \`-g -O')" >&2;}
+ : ${CFLAGS:=""}
+ : ${CXXFLAGS:=""}
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts " >&5
+$as_echo_n "checking whether C compiler accepts ... " >&6; }
+if ${ax_cv_check_cflags__+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$CFLAGS
+  CFLAGS="$CFLAGS   -Werror"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ax_cv_check_cflags__=yes
+else
+  ax_cv_check_cflags__=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  CFLAGS=$ax_check_save_flags
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags__" >&5
+$as_echo "$ax_cv_check_cflags__" >&6; }
+if test x"$ax_cv_check_cflags__" = xyes; then :
+  :
+else
+  :
+fi
+
+if ${CFLAGS+:} false; then :
+  case " $CFLAGS " in
+    *"  "*)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS already contains "; } >&5
+  (: CFLAGS already contains ) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      ;;
+    *)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS=\"\$CFLAGS \""; } >&5
+  (: CFLAGS="$CFLAGS ") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      CFLAGS="$CFLAGS "
+      ;;
+   esac
+else
+  CFLAGS=""
+fi
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+if test -z "$CXX"; then
+  if test -n "$CCC"; then
+    CXX=$CCC
+  else
+    if test -n "$ac_tool_prefix"; then
+  for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+  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 ${ac_cv_prog_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CXX"; then
+  ac_cv_prog_CXX="$CXX" # 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CXX="$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
+CXX=$ac_cv_prog_CXX
+if test -n "$CXX"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5
+$as_echo "$CXX" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+    test -n "$CXX" && break
+  done
+fi
+if test -z "$CXX"; then
+  ac_ct_CXX=$CXX
+  for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+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 ${ac_cv_prog_ac_ct_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_CXX"; then
+  ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CXX="$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_CXX=$ac_cv_prog_ac_ct_CXX
+if test -n "$ac_ct_CXX"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5
+$as_echo "$ac_ct_CXX" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$ac_ct_CXX" && break
+done
+
+  if test "x$ac_ct_CXX" = x; then
+    CXX="g++"
+  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
+    CXX=$ac_ct_CXX
+  fi
+fi
+
+  fi
+fi
+# 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
+  fi
+  rm -f conftest.er1 conftest.err
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+done
+
+{ $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 ${ac_cv_cxx_compiler_gnu+:} false; 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_cxx_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_cxx_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5
+$as_echo "$ac_cv_cxx_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+  GXX=yes
+else
+  GXX=
+fi
+ac_test_CXXFLAGS=${CXXFLAGS+set}
+ac_save_CXXFLAGS=$CXXFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5
+$as_echo_n "checking whether $CXX accepts -g... " >&6; }
+if ${ac_cv_prog_cxx_g+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_save_cxx_werror_flag=$ac_cxx_werror_flag
+   ac_cxx_werror_flag=yes
+   ac_cv_prog_cxx_g=no
+   CXXFLAGS="-g"
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ac_cv_prog_cxx_g=yes
+else
+  CXXFLAGS=""
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+
+else
+  ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+	 CXXFLAGS="-g"
+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ac_cv_prog_cxx_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_cxx_werror_flag=$ac_save_cxx_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5
+$as_echo "$ac_cv_prog_cxx_g" >&6; }
+if test "$ac_test_CXXFLAGS" = set; then
+  CXXFLAGS=$ac_save_CXXFLAGS
+elif test $ac_cv_prog_cxx_g = yes; then
+  if test "$GXX" = yes; then
+    CXXFLAGS="-g -O2"
+  else
+    CXXFLAGS="-g"
+  fi
+else
+  if test "$GXX" = yes; then
+    CXXFLAGS="-O2"
+  else
+    CXXFLAGS=
+  fi
+fi
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+depcc="$CXX"  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 ${am_cv_CXX_dependencies_compiler_type+:} false; 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".
+  rm -rf conftest.dir
+  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_CXX_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 10 /bin/sh.
+      echo '/* dummy */' > 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
+      ;;
+    msvc7 | msvc7msys | 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_CXX_dependencies_compiler_type=$depmode
+        break
+      fi
+    fi
+  done
+
+  cd ..
+  rm -rf conftest.dir
+else
+  am_cv_CXX_dependencies_compiler_type=none
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5
+$as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; }
+CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type
+
+ if
+  test "x$enable_dependency_tracking" != xno \
+  && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then
+  am__fastdepCXX_TRUE=
+  am__fastdepCXX_FALSE='#'
+else
+  am__fastdepCXX_TRUE='#'
+  am__fastdepCXX_FALSE=
+fi
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the linker accepts " >&5
+$as_echo_n "checking whether the linker accepts ... " >&6; }
+if ${ax_cv_check_ldflags__+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$LDFLAGS
+  LDFLAGS="$LDFLAGS  "
+  _save_cflags="$CFLAGS"
+  CFLAGS="$CFLAGS -Werror"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ax_cv_check_ldflags__=yes
+else
+  ax_cv_check_ldflags__=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+  CFLAGS="$_save_cflags"
+  LDFLAGS=$ax_check_save_flags
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_ldflags__" >&5
+$as_echo "$ax_cv_check_ldflags__" >&6; }
+if test x"$ax_cv_check_ldflags__" = xyes; then :
+  :
+else
+  :
+fi
+
+
+#  SING_SHOW_FLAGS([Initial state?...])dnl
+
+ # Check whether --enable-debug was given.
+if test "${enable_debug+set}" = set; then :
+  enableval=$enable_debug; ENABLE_DEBUG="$enableval"
+else
+  ENABLE_DEBUG=""
+fi
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking debugging checks should be embedded" >&5
+$as_echo_n "checking debugging checks should be embedded... " >&6; }
+ if test "x${ENABLE_DEBUG}" != xyes; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ fi
+
+ # Check whether --enable-optimizationflags was given.
+if test "${enable_optimizationflags+set}" = set; then :
+  enableval=$enable_optimizationflags; ENABLE_OPTIMIZATION="$enableval"
+else
+  ENABLE_OPTIMIZATION="yeah"
+fi
+
+
+ if test "x${ENABLE_DEBUG}" = xyes; then
+  SINGULAR_CFLAGS=""
+  if test "x${ENABLE_OPTIMIZATION}" = xyeah; then
+   ENABLE_OPTIMIZATION="no"
+   { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Please note that we disable implicit (default) optimization flags since you have enabled the debug flags... " >&5
+$as_echo "$as_me: WARNING: Please note that we disable implicit (default) optimization flags since you have enabled the debug flags... " >&2;}
+  fi
+ else
+  SINGULAR_CFLAGS="-DSING_NDEBUG -DOM_NDEBUG"
+  # for now let '-DSING_NDEBUG -DOM_NDEBUG' be here...
+
+$as_echo "#define OM_NDEBUG 1" >>confdefs.h
+
+
+$as_echo "#define SING_NDEBUG 1" >>confdefs.h
+
+ fi
+
+ if test "x${ENABLE_OPTIMIZATION}" = xyeah; then
+   ENABLE_OPTIMIZATION="yes"
+ fi
+
+ if test "x${ENABLE_OPTIMIZATION}" = xyes; then
+  if test "x${ENABLE_DEBUG}" = xyes; then
+   { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Please note that you will be using our optimization flags together with debug flags... " >&5
+$as_echo "$as_me: WARNING: Please note that you will be using our optimization flags together with debug flags... " >&2;}
+  fi
+ fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether optimization flags should be used" >&5
+$as_echo_n "checking whether optimization flags should be used... " >&6; }
+ if test "x${ENABLE_OPTIMIZATION}" = xyes; 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; }
+ fi
+
+
+  if test x"${ENABLE_DEBUG}" = xyes; then
+  WANT_DEBUG_TRUE=
+  WANT_DEBUG_FALSE='#'
+else
+  WANT_DEBUG_TRUE='#'
+  WANT_DEBUG_FALSE=
+fi
+
+  if test x"${ENABLE_OPTIMIZATION}" = xyes; then
+  WANT_OPTIMIZATIONFLAGS_TRUE=
+  WANT_OPTIMIZATIONFLAGS_FALSE='#'
+else
+  WANT_OPTIMIZATIONFLAGS_TRUE='#'
+  WANT_OPTIMIZATIONFLAGS_FALSE=
+fi
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SINGULAR_CFLAGS "$SINGULAR_CFLAGS"
+_ACEOF
+
+
+
+# SING_SHOW_FLAGS([checking flags....])
+
+ FLAGS="-pipe -fno-common"
+ 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
+
+
+
+for flag in ${FLAGS}; do
+  as_CACHEVAR=`$as_echo "ax_cv_check_cflags__$flag" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts $flag" >&5
+$as_echo_n "checking whether C compiler accepts $flag... " >&6; }
+if eval \${$as_CACHEVAR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$CFLAGS
+  CFLAGS="$CFLAGS  $flag -Werror"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  eval "$as_CACHEVAR=yes"
+else
+  eval "$as_CACHEVAR=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  CFLAGS=$ax_check_save_flags
+fi
+eval ac_res=\$$as_CACHEVAR
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if test x"`eval 'as_val=${'$as_CACHEVAR'};$as_echo "$as_val"'`" = xyes; then :
+  if ${CFLAGS+:} false; then :
+  case " $CFLAGS " in
+    *" $flag "*)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS already contains \$flag"; } >&5
+  (: CFLAGS already contains $flag) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      ;;
+    *)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS=\"\$CFLAGS \$flag\""; } >&5
+  (: CFLAGS="$CFLAGS $flag") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      CFLAGS="$CFLAGS $flag"
+      ;;
+   esac
+else
+  CFLAGS="$flag"
+fi
+
+else
+  :
+fi
+
+done
+
+ 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=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+
+for flag in ${FLAGS}; do
+  as_CACHEVAR=`$as_echo "ax_cv_check_cxxflags__$flag" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C++ compiler accepts $flag" >&5
+$as_echo_n "checking whether C++ compiler accepts $flag... " >&6; }
+if eval \${$as_CACHEVAR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$CXXFLAGS
+  CXXFLAGS="$CXXFLAGS  $flag -Werror"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  eval "$as_CACHEVAR=yes"
+else
+  eval "$as_CACHEVAR=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  CXXFLAGS=$ax_check_save_flags
+fi
+eval ac_res=\$$as_CACHEVAR
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if test x"`eval 'as_val=${'$as_CACHEVAR'};$as_echo "$as_val"'`" = xyes; then :
+  if ${CXXFLAGS+:} false; then :
+  case " $CXXFLAGS " in
+    *" $flag "*)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CXXFLAGS already contains \$flag"; } >&5
+  (: CXXFLAGS already contains $flag) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      ;;
+    *)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CXXFLAGS=\"\$CXXFLAGS \$flag\""; } >&5
+  (: CXXFLAGS="$CXXFLAGS $flag") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      CXXFLAGS="$CXXFLAGS $flag"
+      ;;
+   esac
+else
+  CXXFLAGS="$flag"
+fi
+
+else
+  :
+fi
+
+done
+
+
+
+for flag in -fexceptions -frtti; do
+  as_CACHEVAR=`$as_echo "ax_cv_check_cxxflags__$flag" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C++ compiler accepts $flag" >&5
+$as_echo_n "checking whether C++ compiler accepts $flag... " >&6; }
+if eval \${$as_CACHEVAR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$CXXFLAGS
+  CXXFLAGS="$CXXFLAGS  $flag -Werror"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  eval "$as_CACHEVAR=yes"
+else
+  eval "$as_CACHEVAR=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  CXXFLAGS=$ax_check_save_flags
+fi
+eval ac_res=\$$as_CACHEVAR
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if test x"`eval 'as_val=${'$as_CACHEVAR'};$as_echo "$as_val"'`" = xyes; then :
+  if ${POLYMAKE_CXXFLAGS+:} false; then :
+  case " $POLYMAKE_CXXFLAGS " in
+    *" $flag "*)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : POLYMAKE_CXXFLAGS already contains \$flag"; } >&5
+  (: POLYMAKE_CXXFLAGS already contains $flag) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      ;;
+    *)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : POLYMAKE_CXXFLAGS=\"\$POLYMAKE_CXXFLAGS \$flag\""; } >&5
+  (: POLYMAKE_CXXFLAGS="$POLYMAKE_CXXFLAGS $flag") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      POLYMAKE_CXXFLAGS="$POLYMAKE_CXXFLAGS $flag"
+      ;;
+   esac
+else
+  POLYMAKE_CXXFLAGS="$flag"
+fi
+
+else
+  :
+fi
+
+done
+
+ 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
+
+
+
+
+for flag in ${FLAGS}; do
+  as_CACHEVAR=`$as_echo "ax_cv_check_ldflags__$flag" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the linker accepts $flag" >&5
+$as_echo_n "checking whether the linker accepts $flag... " >&6; }
+if eval \${$as_CACHEVAR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$LDFLAGS
+  LDFLAGS="$LDFLAGS  $flag"
+  _save_cflags="$CFLAGS"
+  CFLAGS="$CFLAGS -Werror"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "$as_CACHEVAR=yes"
+else
+  eval "$as_CACHEVAR=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+  CFLAGS="$_save_cflags"
+  LDFLAGS=$ax_check_save_flags
+fi
+eval ac_res=\$$as_CACHEVAR
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if test x"`eval 'as_val=${'$as_CACHEVAR'};$as_echo "$as_val"'`" = xyes; then :
+  if ${LDFLAGS+:} false; then :
+  case " $LDFLAGS " in
+    *" $flag "*)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : LDFLAGS already contains \$flag"; } >&5
+  (: LDFLAGS already contains $flag) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      ;;
+    *)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : LDFLAGS=\"\$LDFLAGS \$flag\""; } >&5
+  (: LDFLAGS="$LDFLAGS $flag") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      LDFLAGS="$LDFLAGS $flag"
+      ;;
+   esac
+else
+  LDFLAGS="$flag"
+fi
+
+else
+  :
+fi
+
+done
+
+
+
+
+ if test "x${ENABLE_DEBUG}" = xyes; then
+  DBGFLAGS="-g -ftrapv -fdiagnostics-show-option -Wall -Wextra"
+  #  -pedantic too strict ??? -Wvla -Wno-long-long ???
+  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
+
+
+
+for flag in ${DBGFLAGS}; do
+  as_CACHEVAR=`$as_echo "ax_cv_check_cflags__$flag" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts $flag" >&5
+$as_echo_n "checking whether C compiler accepts $flag... " >&6; }
+if eval \${$as_CACHEVAR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$CFLAGS
+  CFLAGS="$CFLAGS  $flag -Werror"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  eval "$as_CACHEVAR=yes"
+else
+  eval "$as_CACHEVAR=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  CFLAGS=$ax_check_save_flags
+fi
+eval ac_res=\$$as_CACHEVAR
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if test x"`eval 'as_val=${'$as_CACHEVAR'};$as_echo "$as_val"'`" = xyes; then :
+  if ${CFLAGS+:} false; then :
+  case " $CFLAGS " in
+    *" $flag "*)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS already contains \$flag"; } >&5
+  (: CFLAGS already contains $flag) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      ;;
+    *)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS=\"\$CFLAGS \$flag\""; } >&5
+  (: CFLAGS="$CFLAGS $flag") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      CFLAGS="$CFLAGS $flag"
+      ;;
+   esac
+else
+  CFLAGS="$flag"
+fi
+
+else
+  :
+fi
+
+done
+
+  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=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+
+for flag in ${DBGFLAGS}; do
+  as_CACHEVAR=`$as_echo "ax_cv_check_cxxflags__$flag" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C++ compiler accepts $flag" >&5
+$as_echo_n "checking whether C++ compiler accepts $flag... " >&6; }
+if eval \${$as_CACHEVAR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$CXXFLAGS
+  CXXFLAGS="$CXXFLAGS  $flag -Werror"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  eval "$as_CACHEVAR=yes"
+else
+  eval "$as_CACHEVAR=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  CXXFLAGS=$ax_check_save_flags
+fi
+eval ac_res=\$$as_CACHEVAR
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if test x"`eval 'as_val=${'$as_CACHEVAR'};$as_echo "$as_val"'`" = xyes; then :
+  if ${CXXFLAGS+:} false; then :
+  case " $CXXFLAGS " in
+    *" $flag "*)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CXXFLAGS already contains \$flag"; } >&5
+  (: CXXFLAGS already contains $flag) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      ;;
+    *)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CXXFLAGS=\"\$CXXFLAGS \$flag\""; } >&5
+  (: CXXFLAGS="$CXXFLAGS $flag") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      CXXFLAGS="$CXXFLAGS $flag"
+      ;;
+   esac
+else
+  CXXFLAGS="$flag"
+fi
+
+else
+  :
+fi
+
+done
+
+  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
+
+
+
+for flag in ${DBGFLAGS}; do
+  as_CACHEVAR=`$as_echo "ax_cv_check_ldflags__$flag" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the linker accepts $flag" >&5
+$as_echo_n "checking whether the linker accepts $flag... " >&6; }
+if eval \${$as_CACHEVAR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$LDFLAGS
+  LDFLAGS="$LDFLAGS  $flag"
+  _save_cflags="$CFLAGS"
+  CFLAGS="$CFLAGS -Werror"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "$as_CACHEVAR=yes"
+else
+  eval "$as_CACHEVAR=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+  CFLAGS="$_save_cflags"
+  LDFLAGS=$ax_check_save_flags
+fi
+eval ac_res=\$$as_CACHEVAR
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if test x"`eval 'as_val=${'$as_CACHEVAR'};$as_echo "$as_val"'`" = xyes; then :
+  if ${LDFLAGS+:} false; then :
+  case " $LDFLAGS " in
+    *" $flag "*)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : LDFLAGS already contains \$flag"; } >&5
+  (: LDFLAGS already contains $flag) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      ;;
+    *)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : LDFLAGS=\"\$LDFLAGS \$flag\""; } >&5
+  (: LDFLAGS="$LDFLAGS $flag") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      LDFLAGS="$LDFLAGS $flag"
+      ;;
+   esac
+else
+  LDFLAGS="$flag"
+fi
+
+else
+  :
+fi
+
+done
+
+ fi
+
+ ## for clang: -Wunneeded-internal-declaration
+
+ if test "x${ENABLE_OPTIMIZATION}" != xno; then
+  OPTFLAGS="-O3 -Wno-unused-function -Wno-trigraphs -Wno-unused-parameter -Wunknown-pragmas -Wno-unused-variable -fomit-frame-pointer -fwrapv -fvisibility=default -finline-functions -fno-exceptions -fno-rtti -fno-threadsafe-statics -fno-enforce-eh-specs -fconserve-space -funroll-loops"
+  #  -O3 - crashes gcc???!!!
+  # -fpermissive
+  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
+
+
+
+for flag in ${OPTFLAGS}; do
+  as_CACHEVAR=`$as_echo "ax_cv_check_cflags__$flag" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts $flag" >&5
+$as_echo_n "checking whether C compiler accepts $flag... " >&6; }
+if eval \${$as_CACHEVAR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$CFLAGS
+  CFLAGS="$CFLAGS  $flag -Werror"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  eval "$as_CACHEVAR=yes"
+else
+  eval "$as_CACHEVAR=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  CFLAGS=$ax_check_save_flags
+fi
+eval ac_res=\$$as_CACHEVAR
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if test x"`eval 'as_val=${'$as_CACHEVAR'};$as_echo "$as_val"'`" = xyes; then :
+  if ${CFLAGS+:} false; then :
+  case " $CFLAGS " in
+    *" $flag "*)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS already contains \$flag"; } >&5
+  (: CFLAGS already contains $flag) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      ;;
+    *)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS=\"\$CFLAGS \$flag\""; } >&5
+  (: CFLAGS="$CFLAGS $flag") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      CFLAGS="$CFLAGS $flag"
+      ;;
+   esac
+else
+  CFLAGS="$flag"
+fi
+
+else
+  :
+fi
+
+done
+
+  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=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+
+for flag in ${OPTFLAGS}; do
+  as_CACHEVAR=`$as_echo "ax_cv_check_cxxflags__$flag" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C++ compiler accepts $flag" >&5
+$as_echo_n "checking whether C++ compiler accepts $flag... " >&6; }
+if eval \${$as_CACHEVAR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$CXXFLAGS
+  CXXFLAGS="$CXXFLAGS  $flag -Werror"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  eval "$as_CACHEVAR=yes"
+else
+  eval "$as_CACHEVAR=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  CXXFLAGS=$ax_check_save_flags
+fi
+eval ac_res=\$$as_CACHEVAR
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if test x"`eval 'as_val=${'$as_CACHEVAR'};$as_echo "$as_val"'`" = xyes; then :
+  if ${CXXFLAGS+:} false; then :
+  case " $CXXFLAGS " in
+    *" $flag "*)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CXXFLAGS already contains \$flag"; } >&5
+  (: CXXFLAGS already contains $flag) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      ;;
+    *)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CXXFLAGS=\"\$CXXFLAGS \$flag\""; } >&5
+  (: CXXFLAGS="$CXXFLAGS $flag") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      CXXFLAGS="$CXXFLAGS $flag"
+      ;;
+   esac
+else
+  CXXFLAGS="$flag"
+fi
+
+else
+  :
+fi
+
+done
+
+#   AX_APPEND_COMPILE_FLAGS([-fno-threadsafe-statics -fno-enforce-eh-specs -fconserve-space], [CXXFLAGS])
+###  AX_APPEND_COMPILE_FLAGS([-fno-implicit-templates], [CXXFLAGS]) # problems due to STL
+  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
+
+
+
+for flag in ${OPTFLAGS}; do
+  as_CACHEVAR=`$as_echo "ax_cv_check_ldflags__$flag" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the linker accepts $flag" >&5
+$as_echo_n "checking whether the linker accepts $flag... " >&6; }
+if eval \${$as_CACHEVAR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$LDFLAGS
+  LDFLAGS="$LDFLAGS  $flag"
+  _save_cflags="$CFLAGS"
+  CFLAGS="$CFLAGS -Werror"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "$as_CACHEVAR=yes"
+else
+  eval "$as_CACHEVAR=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+  CFLAGS="$_save_cflags"
+  LDFLAGS=$ax_check_save_flags
+fi
+eval ac_res=\$$as_CACHEVAR
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if test x"`eval 'as_val=${'$as_CACHEVAR'};$as_echo "$as_val"'`" = xyes; then :
+  if ${LDFLAGS+:} false; then :
+  case " $LDFLAGS " in
+    *" $flag "*)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : LDFLAGS already contains \$flag"; } >&5
+  (: LDFLAGS already contains $flag) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      ;;
+    *)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : LDFLAGS=\"\$LDFLAGS \$flag\""; } >&5
+  (: LDFLAGS="$LDFLAGS $flag") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      LDFLAGS="$LDFLAGS $flag"
+      ;;
+   esac
+else
+  LDFLAGS="$flag"
+fi
+
+else
+  :
+fi
+
+done
+
+#  AX_APPEND_LINK_FLAGS([-fno-threadsafe-statics -fno-enforce-eh-specs -fconserve-space])
+###  AX_APPEND_LINK_FLAGS([-fno-implicit-templates]) # see above :(
+#  AX_APPEND_LINK_FLAGS([ ])
+ fi
+
+ FLAGS2="-Qunused-arguments"
+ 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
+
+
+
+for flag in ${FLAGS2}; do
+  as_CACHEVAR=`$as_echo "ax_cv_check_cflags__$flag" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts $flag" >&5
+$as_echo_n "checking whether C compiler accepts $flag... " >&6; }
+if eval \${$as_CACHEVAR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$CFLAGS
+  CFLAGS="$CFLAGS  $flag -Werror"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  eval "$as_CACHEVAR=yes"
+else
+  eval "$as_CACHEVAR=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  CFLAGS=$ax_check_save_flags
+fi
+eval ac_res=\$$as_CACHEVAR
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if test x"`eval 'as_val=${'$as_CACHEVAR'};$as_echo "$as_val"'`" = xyes; then :
+  if ${CFLAGS+:} false; then :
+  case " $CFLAGS " in
+    *" $flag "*)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS already contains \$flag"; } >&5
+  (: CFLAGS already contains $flag) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      ;;
+    *)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS=\"\$CFLAGS \$flag\""; } >&5
+  (: CFLAGS="$CFLAGS $flag") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      CFLAGS="$CFLAGS $flag"
+      ;;
+   esac
+else
+  CFLAGS="$flag"
+fi
+
+else
+  :
+fi
+
+done
+
+ 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=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+
+for flag in ${FLAGS2}; do
+  as_CACHEVAR=`$as_echo "ax_cv_check_cxxflags__$flag" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C++ compiler accepts $flag" >&5
+$as_echo_n "checking whether C++ compiler accepts $flag... " >&6; }
+if eval \${$as_CACHEVAR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$CXXFLAGS
+  CXXFLAGS="$CXXFLAGS  $flag -Werror"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  eval "$as_CACHEVAR=yes"
+else
+  eval "$as_CACHEVAR=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  CXXFLAGS=$ax_check_save_flags
+fi
+eval ac_res=\$$as_CACHEVAR
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if test x"`eval 'as_val=${'$as_CACHEVAR'};$as_echo "$as_val"'`" = xyes; then :
+  if ${CXXFLAGS+:} false; then :
+  case " $CXXFLAGS " in
+    *" $flag "*)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CXXFLAGS already contains \$flag"; } >&5
+  (: CXXFLAGS already contains $flag) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      ;;
+    *)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CXXFLAGS=\"\$CXXFLAGS \$flag\""; } >&5
+  (: CXXFLAGS="$CXXFLAGS $flag") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      CXXFLAGS="$CXXFLAGS $flag"
+      ;;
+   esac
+else
+  CXXFLAGS="$flag"
+fi
+
+else
+  :
+fi
+
+done
+
+ 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
+
+
+
+
+for flag in ${FLAGS2}; do
+  as_CACHEVAR=`$as_echo "ax_cv_check_ldflags__$flag" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the linker accepts $flag" >&5
+$as_echo_n "checking whether the linker accepts $flag... " >&6; }
+if eval \${$as_CACHEVAR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$LDFLAGS
+  LDFLAGS="$LDFLAGS  $flag"
+  _save_cflags="$CFLAGS"
+  CFLAGS="$CFLAGS -Werror"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "$as_CACHEVAR=yes"
+else
+  eval "$as_CACHEVAR=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+  CFLAGS="$_save_cflags"
+  LDFLAGS=$ax_check_save_flags
+fi
+eval ac_res=\$$as_CACHEVAR
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if test x"`eval 'as_val=${'$as_CACHEVAR'};$as_echo "$as_val"'`" = xyes; then :
+  if ${LDFLAGS+:} false; then :
+  case " $LDFLAGS " in
+    *" $flag "*)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : LDFLAGS already contains \$flag"; } >&5
+  (: LDFLAGS already contains $flag) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      ;;
+    *)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : LDFLAGS=\"\$LDFLAGS \$flag\""; } >&5
+  (: LDFLAGS="$LDFLAGS $flag") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      LDFLAGS="$LDFLAGS $flag"
+      ;;
+   esac
+else
+  LDFLAGS="$flag"
+fi
+
+else
+  :
+fi
+
+done
+
+
+# SING_SHOW_FLAGS([before PROG_C_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
+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 ${ac_cv_prog_CC+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_CC+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_CC+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_CC+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_CC+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_CC+:} false; 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 as_fn_executable_p "$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
+  fi
+  rm -f conftest.er1 conftest.err
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+done
+
+{ $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 ${ac_cv_c_compiler_gnu+:} false; 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 ${ac_cv_prog_cc_g+:} false; 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 ${ac_cv_prog_cc_c89+:} false; 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>
+struct stat;
+/* 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
+
+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 ${am_cv_CC_dependencies_compiler_type+:} false; 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".
+  rm -rf conftest.dir
+  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 10 /bin/sh.
+      echo '/* dummy */' > 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
+      ;;
+    msvc7 | msvc7msys | 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
+
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+if test -z "$CXX"; then
+  if test -n "$CCC"; then
+    CXX=$CCC
+  else
+    if test -n "$ac_tool_prefix"; then
+  for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+  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 ${ac_cv_prog_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CXX"; then
+  ac_cv_prog_CXX="$CXX" # 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CXX="$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
+CXX=$ac_cv_prog_CXX
+if test -n "$CXX"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5
+$as_echo "$CXX" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+    test -n "$CXX" && break
+  done
+fi
+if test -z "$CXX"; then
+  ac_ct_CXX=$CXX
+  for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+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 ${ac_cv_prog_ac_ct_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_CXX"; then
+  ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CXX="$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_CXX=$ac_cv_prog_ac_ct_CXX
+if test -n "$ac_ct_CXX"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5
+$as_echo "$ac_ct_CXX" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$ac_ct_CXX" && break
+done
+
+  if test "x$ac_ct_CXX" = x; then
+    CXX="g++"
+  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
+    CXX=$ac_ct_CXX
+  fi
+fi
+
+  fi
+fi
+# 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
+  fi
+  rm -f conftest.er1 conftest.err
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+done
+
+{ $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 ${ac_cv_cxx_compiler_gnu+:} false; 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_cxx_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_cxx_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5
+$as_echo "$ac_cv_cxx_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+  GXX=yes
+else
+  GXX=
+fi
+ac_test_CXXFLAGS=${CXXFLAGS+set}
+ac_save_CXXFLAGS=$CXXFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5
+$as_echo_n "checking whether $CXX accepts -g... " >&6; }
+if ${ac_cv_prog_cxx_g+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_save_cxx_werror_flag=$ac_cxx_werror_flag
+   ac_cxx_werror_flag=yes
+   ac_cv_prog_cxx_g=no
+   CXXFLAGS="-g"
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ac_cv_prog_cxx_g=yes
+else
+  CXXFLAGS=""
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+
+else
+  ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+	 CXXFLAGS="-g"
+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ac_cv_prog_cxx_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_cxx_werror_flag=$ac_save_cxx_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5
+$as_echo "$ac_cv_prog_cxx_g" >&6; }
+if test "$ac_test_CXXFLAGS" = set; then
+  CXXFLAGS=$ac_save_CXXFLAGS
+elif test $ac_cv_prog_cxx_g = yes; then
+  if test "$GXX" = yes; then
+    CXXFLAGS="-g -O2"
+  else
+    CXXFLAGS="-g"
+  fi
+else
+  if test "$GXX" = yes; then
+    CXXFLAGS="-O2"
+  else
+    CXXFLAGS=
+  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
+
+depcc="$CXX"  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 ${am_cv_CXX_dependencies_compiler_type+:} false; 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".
+  rm -rf conftest.dir
+  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_CXX_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 10 /bin/sh.
+      echo '/* dummy */' > 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
+      ;;
+    msvc7 | msvc7msys | 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_CXX_dependencies_compiler_type=$depmode
+        break
+      fi
+    fi
+  done
+
+  cd ..
+  rm -rf conftest.dir
+else
+  am_cv_CXX_dependencies_compiler_type=none
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5
+$as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; }
+CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type
+
+ if
+  test "x$enable_dependency_tracking" != xno \
+  && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then
+  am__fastdepCXX_TRUE=
+  am__fastdepCXX_FALSE='#'
+else
+  am__fastdepCXX_TRUE='#'
+  am__fastdepCXX_FALSE=
+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 ${ac_cv_prog_CC+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_CC+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_CC+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_CC+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_CC+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_CC+:} false; 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 as_fn_executable_p "$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
+  fi
+  rm -f conftest.er1 conftest.err
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+done
+
+{ $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 ${ac_cv_c_compiler_gnu+:} false; 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 ${ac_cv_prog_cc_g+:} false; 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 ${ac_cv_prog_cc_c89+:} false; 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>
+struct stat;
+/* 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
+
+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 ${am_cv_CC_dependencies_compiler_type+:} false; 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".
+  rm -rf conftest.dir
+  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 10 /bin/sh.
+      echo '/* dummy */' > 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
+      ;;
+    msvc7 | msvc7msys | 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
+
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+if test -z "$CXX"; then
+  if test -n "$CCC"; then
+    CXX=$CCC
+  else
+    if test -n "$ac_tool_prefix"; then
+  for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+  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 ${ac_cv_prog_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CXX"; then
+  ac_cv_prog_CXX="$CXX" # 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CXX="$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
+CXX=$ac_cv_prog_CXX
+if test -n "$CXX"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5
+$as_echo "$CXX" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+    test -n "$CXX" && break
+  done
+fi
+if test -z "$CXX"; then
+  ac_ct_CXX=$CXX
+  for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+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 ${ac_cv_prog_ac_ct_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_CXX"; then
+  ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CXX="$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_CXX=$ac_cv_prog_ac_ct_CXX
+if test -n "$ac_ct_CXX"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5
+$as_echo "$ac_ct_CXX" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$ac_ct_CXX" && break
+done
+
+  if test "x$ac_ct_CXX" = x; then
+    CXX="g++"
+  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
+    CXX=$ac_ct_CXX
+  fi
+fi
+
+  fi
+fi
+# 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
+  fi
+  rm -f conftest.er1 conftest.err
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+done
+
+{ $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 ${ac_cv_cxx_compiler_gnu+:} false; 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_cxx_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_cxx_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5
+$as_echo "$ac_cv_cxx_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+  GXX=yes
+else
+  GXX=
+fi
+ac_test_CXXFLAGS=${CXXFLAGS+set}
+ac_save_CXXFLAGS=$CXXFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5
+$as_echo_n "checking whether $CXX accepts -g... " >&6; }
+if ${ac_cv_prog_cxx_g+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_save_cxx_werror_flag=$ac_cxx_werror_flag
+   ac_cxx_werror_flag=yes
+   ac_cv_prog_cxx_g=no
+   CXXFLAGS="-g"
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ac_cv_prog_cxx_g=yes
+else
+  CXXFLAGS=""
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+
+else
+  ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+	 CXXFLAGS="-g"
+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ac_cv_prog_cxx_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_cxx_werror_flag=$ac_save_cxx_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5
+$as_echo "$ac_cv_prog_cxx_g" >&6; }
+if test "$ac_test_CXXFLAGS" = set; then
+  CXXFLAGS=$ac_save_CXXFLAGS
+elif test $ac_cv_prog_cxx_g = yes; then
+  if test "$GXX" = yes; then
+    CXXFLAGS="-g -O2"
+  else
+    CXXFLAGS="-g"
+  fi
+else
+  if test "$GXX" = yes; then
+    CXXFLAGS="-O2"
+  else
+    CXXFLAGS=
+  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
+
+depcc="$CXX"  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 ${am_cv_CXX_dependencies_compiler_type+:} false; 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".
+  rm -rf conftest.dir
+  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_CXX_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 10 /bin/sh.
+      echo '/* dummy */' > 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
+      ;;
+    msvc7 | msvc7msys | 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_CXX_dependencies_compiler_type=$depmode
+        break
+      fi
+    fi
+  done
+
+  cd ..
+  rm -rf conftest.dir
+else
+  am_cv_CXX_dependencies_compiler_type=none
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5
+$as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; }
+CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type
+
+ if
+  test "x$enable_dependency_tracking" != xno \
+  && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then
+  am__fastdepCXX_TRUE=
+  am__fastdepCXX_FALSE='#'
+else
+  am__fastdepCXX_TRUE='#'
+  am__fastdepCXX_FALSE=
+fi
+
+
+if test "x$CC" != xcc; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC and cc understand -c and -o together" >&5
+$as_echo_n "checking whether $CC and cc understand -c and -o together... " >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether cc understands -c and -o together" >&5
+$as_echo_n "checking whether cc understands -c and -o together... " >&6; }
+fi
+set dummy $CC; ac_cc=`$as_echo "$2" |
+		      sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'`
+if eval \${ac_cv_prog_cc_${ac_cc}_c_o+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+# Make sure it works both with $CC and with simple cc.
+# We do the test twice because some compilers refuse to overwrite an
+# existing .o file with -o, though they will create one.
+ac_try='$CC -c conftest.$ac_ext -o conftest2.$ac_objext >&5'
+rm -f conftest2.*
+if { { 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; } &&
+   test -f conftest2.$ac_objext && { { 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
+  eval ac_cv_prog_cc_${ac_cc}_c_o=yes
+  if test "x$CC" != xcc; then
+    # Test first that cc exists at all.
+    if { ac_try='cc -c conftest.$ac_ext >&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_try") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then
+      ac_try='cc -c conftest.$ac_ext -o conftest2.$ac_objext >&5'
+      rm -f conftest2.*
+      if { { 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; } &&
+	 test -f conftest2.$ac_objext && { { 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
+	# cc works too.
+	:
+      else
+	# cc exists but doesn't like -o.
+	eval ac_cv_prog_cc_${ac_cc}_c_o=no
+      fi
+    fi
+  fi
+else
+  eval ac_cv_prog_cc_${ac_cc}_c_o=no
+fi
+rm -f core conftest*
+
+fi
+if eval test \$ac_cv_prog_cc_${ac_cc}_c_o = yes; 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; }
+
+$as_echo "#define NO_MINUS_C_MINUS_O 1" >>confdefs.h
+
+fi
+
+# FIXME: we rely on the cache variable name because
+# there is no other way.
+set dummy $CC
+am_cc=`echo $2 | sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'`
+eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o
+if test "$am_t" != yes; then
+   # Losing compiler, so override with the script.
+   # FIXME: It is wrong to rewrite CC.
+   # But if we don't then we get into trouble of one sort or another.
+   # A longer-term fix would be to have automake use am__CC in this case,
+   # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
+   CC="$am_aux_dir/compile $CC"
+fi
+
+
+{ $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
+
+
+
+# Turn off shared libraries during beta-testing, since they
+# make the build process take too long.
+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.4.2'
+macro_revision='1.3337'
+
+
+
+
+
+
+
+
+
+
+
+
+
+ltmain="$ac_aux_dir/ltmain.sh"
+
+# 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 ${ac_cv_build+:} false; 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 ${ac_cv_host+:} false; 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
+
+
+# Backslashify 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'
+
+ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5
+$as_echo_n "checking how to print strings... " >&6; }
+# Test print first, because it will be a builtin if present.
+if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \
+   test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then
+  ECHO='print -r --'
+elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then
+  ECHO='printf %s\n'
+else
+  # Use this function as a fallback that always works.
+  func_fallback_echo ()
+  {
+    eval 'cat <<_LTECHO_EOF
+$1
+_LTECHO_EOF'
+  }
+  ECHO='func_fallback_echo'
+fi
+
+# func_echo_all arg...
+# Invoke $ECHO with all args, space-separated.
+func_echo_all ()
+{
+    $ECHO ""
+}
+
+case "$ECHO" in
+  printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5
+$as_echo "printf" >&6; } ;;
+  print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5
+$as_echo "print -r" >&6; } ;;
+  *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5
+$as_echo "cat" >&6; } ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+{ $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 ${ac_cv_path_SED+:} false; 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"
+      as_fn_executable_p "$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 ${ac_cv_path_GREP+:} false; 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"
+      as_fn_executable_p "$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 ${ac_cv_path_EGREP+:} false; 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"
+      as_fn_executable_p "$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 ${ac_cv_path_FGREP+:} false; 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"
+      as_fn_executable_p "$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 ${lt_cv_path_LD+:} false; 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 ${lt_cv_prog_gnu_ld+:} false; 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 ${lt_cv_path_NM+:} false; 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 "$DUMPBIN"; then :
+    # Let the user override the test.
+  else
+    if test -n "$ac_tool_prefix"; then
+  for ac_prog in dumpbin "link -dump"
+  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 ${ac_cv_prog_DUMPBIN+:} false; 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 as_fn_executable_p "$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 "link -dump"
+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 ${ac_cv_prog_ac_ct_DUMPBIN+:} false; 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 as_fn_executable_p "$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
+
+    case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in
+    *COFF*)
+      DUMPBIN="$DUMPBIN -symbols"
+      ;;
+    *)
+      DUMPBIN=:
+      ;;
+    esac
+  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 ${lt_cv_nm_interface+:} false; 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:$LINENO: $ac_compile\"" >&5)
+  (eval "$ac_compile" 2>conftest.err)
+  cat conftest.err >&5
+  (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
+  (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
+  cat conftest.err >&5
+  (eval echo "\"\$as_me:$LINENO: 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; }
+
+# 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 ${lt_cv_sys_max_cmd_len+:} false; 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;
+    ;;
+
+  mint*)
+    # On MiNT this can take a long time and run out of memory.
+    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
+    ;;
+
+  os2*)
+    # The test takes a long time on OS/2.
+    lt_cv_sys_max_cmd_len=8192
+    ;;
+
+  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"`env echo "$teststring$teststring" 2>/dev/null` \
+	         = "X$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%"$_lt_dummy"}, \
+      = c,a/b,b/c, \
+    && 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 how to convert $build file names to $host format" >&5
+$as_echo_n "checking how to convert $build file names to $host format... " >&6; }
+if ${lt_cv_to_host_file_cmd+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $host in
+  *-*-mingw* )
+    case $build in
+      *-*-mingw* ) # actually msys
+        lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32
+        ;;
+      *-*-cygwin* )
+        lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32
+        ;;
+      * ) # otherwise, assume *nix
+        lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32
+        ;;
+    esac
+    ;;
+  *-*-cygwin* )
+    case $build in
+      *-*-mingw* ) # actually msys
+        lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin
+        ;;
+      *-*-cygwin* )
+        lt_cv_to_host_file_cmd=func_convert_file_noop
+        ;;
+      * ) # otherwise, assume *nix
+        lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin
+        ;;
+    esac
+    ;;
+  * ) # unhandled hosts (and "normal" native builds)
+    lt_cv_to_host_file_cmd=func_convert_file_noop
+    ;;
+esac
+
+fi
+
+to_host_file_cmd=$lt_cv_to_host_file_cmd
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5
+$as_echo "$lt_cv_to_host_file_cmd" >&6; }
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5
+$as_echo_n "checking how to convert $build file names to toolchain format... " >&6; }
+if ${lt_cv_to_tool_file_cmd+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  #assume ordinary cross tools, or native build.
+lt_cv_to_tool_file_cmd=func_convert_file_noop
+case $host in
+  *-*-mingw* )
+    case $build in
+      *-*-mingw* ) # actually msys
+        lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32
+        ;;
+    esac
+    ;;
+esac
+
+fi
+
+to_tool_file_cmd=$lt_cv_to_tool_file_cmd
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5
+$as_echo "$lt_cv_to_tool_file_cmd" >&6; }
+
+
+
+
+
+{ $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 ${lt_cv_ld_reload_flag+:} false; 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
+  cygwin* | mingw* | pw32* | cegcc*)
+    if test "$GCC" != yes; then
+      reload_cmds=false
+    fi
+    ;;
+  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 ${ac_cv_prog_OBJDUMP+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_OBJDUMP+:} false; 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 as_fn_executable_p "$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 ${lt_cv_deplibs_check_method+:} false; 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.
+  # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin.
+  if ( test "$lt_cv_nm_interface" = "BSD nm" && 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
+    # Keep this pattern in sync with the one in func_win32_libid.
+    lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)'
+    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
+  ;;
+
+haiku*)
+  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])(-bit)?( [LM]SB)? 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 glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+netbsd*)
+  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_glob=
+want_nocaseglob=no
+if test "$build" = "$host"; then
+  case $host_os in
+  mingw* | pw32*)
+    if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then
+      want_nocaseglob=yes
+    else
+      file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"`
+    fi
+    ;;
+  esac
+fi
+
+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}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 ${ac_cv_prog_DLLTOOL+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_DLLTOOL+:} false; 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 as_fn_executable_p "$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
+
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5
+$as_echo_n "checking how to associate runtime and link libraries... " >&6; }
+if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_sharedlib_from_linklib_cmd='unknown'
+
+case $host_os in
+cygwin* | mingw* | pw32* | cegcc*)
+  # two different shell functions defined in ltmain.sh
+  # decide which to use based on capabilities of $DLLTOOL
+  case `$DLLTOOL --help 2>&1` in
+  *--identify-strict*)
+    lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib
+    ;;
+  *)
+    lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback
+    ;;
+  esac
+  ;;
+*)
+  # fallback: assume linklib IS sharedlib
+  lt_cv_sharedlib_from_linklib_cmd="$ECHO"
+  ;;
+esac
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5
+$as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; }
+sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd
+test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+  for ac_prog in ar
+  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 ${ac_cv_prog_AR+:} false; 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_AR="$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
+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
+
+
+    test -n "$AR" && break
+  done
+fi
+if test -z "$AR"; then
+  ac_ct_AR=$AR
+  for ac_prog in ar
+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 ${ac_cv_prog_ac_ct_AR+:} false; 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_AR="$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_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
+
+
+  test -n "$ac_ct_AR" && break
+done
+
+  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
+fi
+
+: ${AR=ar}
+: ${AR_FLAGS=cru}
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5
+$as_echo_n "checking for archiver @FILE support... " >&6; }
+if ${lt_cv_ar_at_file+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_ar_at_file=no
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  echo conftest.$ac_objext > conftest.lst
+      lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5'
+      { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5
+  (eval $lt_ar_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      if test "$ac_status" -eq 0; then
+	# Ensure the archiver fails upon bogus file names.
+	rm -f conftest.$ac_objext libconftest.a
+	{ { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5
+  (eval $lt_ar_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+	if test "$ac_status" -ne 0; then
+          lt_cv_ar_at_file=@
+        fi
+      fi
+      rm -f conftest.* libconftest.a
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5
+$as_echo "$lt_cv_ar_at_file" >&6; }
+
+if test "x$lt_cv_ar_at_file" = xno; then
+  archiver_list_spec=
+else
+  archiver_list_spec=$lt_cv_ar_at_file
+fi
+
+
+
+
+
+
+
+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 ${ac_cv_prog_STRIP+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_STRIP+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_RANLIB+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_RANLIB+:} false; 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 as_fn_executable_p "$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 \$tool_oldlib"
+    ;;
+  *)
+    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib"
+    ;;
+  esac
+  old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib"
+fi
+
+case $host_os in
+  darwin*)
+    lock_old_archive_extraction=yes ;;
+  *)
+    lock_old_archive_extraction=no ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 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 ${lt_cv_sys_global_symbol_pipe+:} false; 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};"\
+"     /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\
+"     /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
+  lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'"
+
+  # 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
+/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests.  */
+#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE)
+/* DATA imports from DLLs on WIN32 con't be const, because runtime
+   relocations are performed -- see ld's documentation on pseudo-relocs.  */
+# define LT_DLSYM_CONST
+#elif defined(__osf__)
+/* This system does not cope well with relocations in const data.  */
+# define LT_DLSYM_CONST
+#else
+# define LT_DLSYM_CONST const
+#endif
+
+#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.  */
+LT_DLSYM_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_globsym_save_LIBS=$LIBS
+	  lt_globsym_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_globsym_save_LIBS
+	  CFLAGS=$lt_globsym_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
+
+# Response file support.
+if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+  nm_file_list_spec='@'
+elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then
+  nm_file_list_spec='@'
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5
+$as_echo_n "checking for sysroot... " >&6; }
+
+# Check whether --with-sysroot was given.
+if test "${with_sysroot+set}" = set; then :
+  withval=$with_sysroot;
+else
+  with_sysroot=no
+fi
+
+
+lt_sysroot=
+case ${with_sysroot} in #(
+ yes)
+   if test "$GCC" = yes; then
+     lt_sysroot=`$CC --print-sysroot 2>/dev/null`
+   fi
+   ;; #(
+ /*)
+   lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"`
+   ;; #(
+ no|'')
+   ;; #(
+ *)
+   { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${with_sysroot}" >&5
+$as_echo "${with_sysroot}" >&6; }
+   as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5
+   ;;
+esac
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5
+$as_echo "${lt_sysroot:-no}" >&6; }
+
+
+
+
+
+# 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 '$LINENO' "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 ${lt_cv_cc_needs_belf+:} false; 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
+  ;;
+*-*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*)
+        case $host in
+        i?86-*-solaris*)
+          LD="${LD-ld} -m elf_x86_64"
+          ;;
+        sparc*-*-solaris*)
+          LD="${LD-ld} -m elf64_sparc"
+          ;;
+        esac
+        # GNU ld 2.21 introduced _sol2 emulations.  Use them if available.
+        if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then
+          LD="${LD-ld}_sol2"
+        fi
+        ;;
+      *)
+	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"
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args.
+set dummy ${ac_tool_prefix}mt; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_MANIFEST_TOOL+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$MANIFEST_TOOL"; then
+  ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt"
+    $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
+MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL
+if test -n "$MANIFEST_TOOL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5
+$as_echo "$MANIFEST_TOOL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_MANIFEST_TOOL"; then
+  ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL
+  # Extract the first word of "mt", so it can be a program name with args.
+set dummy mt; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_MANIFEST_TOOL"; then
+  ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_MANIFEST_TOOL="mt"
+    $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_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL
+if test -n "$ac_ct_MANIFEST_TOOL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5
+$as_echo "$ac_ct_MANIFEST_TOOL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_MANIFEST_TOOL" = x; then
+    MANIFEST_TOOL=":"
+  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
+    MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL
+  fi
+else
+  MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL"
+fi
+
+test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5
+$as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; }
+if ${lt_cv_path_mainfest_tool+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_path_mainfest_tool=no
+  echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5
+  $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out
+  cat conftest.err >&5
+  if $GREP 'Manifest Tool' conftest.out > /dev/null; then
+    lt_cv_path_mainfest_tool=yes
+  fi
+  rm -f conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5
+$as_echo "$lt_cv_path_mainfest_tool" >&6; }
+if test "x$lt_cv_path_mainfest_tool" != xyes; then
+  MANIFEST_TOOL=:
+fi
+
+
+
+
+
+
+  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 ${ac_cv_prog_DSYMUTIL+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_NMEDIT+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_NMEDIT+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_LIPO+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_LIPO+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_OTOOL+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_OTOOL+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_OTOOL64+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_OTOOL64+:} false; 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 as_fn_executable_p "$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 ${lt_cv_apple_cc_single_mod+:} false; 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 there is a non-empty error log, and "single_module"
+	# appears in it, assume the flag caused a linker warning
+        if test -s conftest.err && $GREP single_module conftest.err; then
+	  cat conftest.err >&5
+	# Otherwise, if the output was created with a 0 exit code from
+	# the compiler, it worked.
+	elif test -f libconftest.dylib && test $_lt_result -eq 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 ${lt_cv_ld_exported_symbols_list+:} false; 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; }
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5
+$as_echo_n "checking for -force_load linker flag... " >&6; }
+if ${lt_cv_ld_force_load+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_ld_force_load=no
+      cat > conftest.c << _LT_EOF
+int forced_loaded() { return 2;}
+_LT_EOF
+      echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5
+      $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5
+      echo "$AR cru libconftest.a conftest.o" >&5
+      $AR cru libconftest.a conftest.o 2>&5
+      echo "$RANLIB libconftest.a" >&5
+      $RANLIB libconftest.a 2>&5
+      cat > conftest.c << _LT_EOF
+int main() { return 0;}
+_LT_EOF
+      echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5
+      $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err
+      _lt_result=$?
+      if test -s conftest.err && $GREP force_load conftest.err; then
+	cat conftest.err >&5
+      elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then
+	lt_cv_ld_force_load=yes
+      else
+	cat conftest.err >&5
+      fi
+        rm -f conftest.err libconftest.a conftest conftest.c
+        rm -rf conftest.dSYM
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5
+$as_echo "$lt_cv_ld_force_load" >&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" != ":" && test "$lt_cv_ld_force_load" = "no"; 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 ${ac_cv_prog_CPP+:} false; 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.i 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.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i 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.i 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.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i 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 ${ac_cv_header_stdc+:} false; 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
+"
+if eval test \"x\$"$as_ac_Header"\" = 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" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_DLFCN_H 1
+_ACEOF
+
+fi
+
+done
+
+
+
+func_stripname_cnf ()
+{
+  case ${2} in
+  .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;;
+  *)  func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;;
+  esac
+} # func_stripname_cnf
+
+
+
+
+
+# Set options
+
+
+
+        enable_dlopen=no
+
+
+  enable_win32_dll=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; lt_p=${PACKAGE-default}
+    case $withval in
+    yes|no) pic_mode=$withval ;;
+    *)
+      pic_mode=default
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for lt_pkg in $withval; do
+	IFS="$lt_save_ifs"
+	if test "X$lt_pkg" = "X$lt_p"; then
+	  pic_mode=yes
+	fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac
+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 ${lt_cv_objdir+:} false; 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
+
+# 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 "$cc_temp" | $SED "s%.*/%%; 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 ${lt_cv_path_MAGIC_CMD+:} false; 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 ${lt_cv_path_MAGIC_CMD+:} false; 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*
+
+
+## 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...
+if test -n "$compiler"; then
+
+lt_prog_compiler_no_builtin_flag=
+
+if test "$GCC" = yes; then
+  case $cc_basename in
+  nvcc*)
+    lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;;
+  *)
+    lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;;
+  esac
+
+  { $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 ${lt_cv_prog_compiler_rtti_exceptions+:} false; 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:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $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 "$_lt_compiler_boilerplate" | $SED '/^$/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=
+
+
+  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'
+      ;;
+
+    haiku*)
+      # PIC is the default for Haiku.
+      # The "-static" flag exists, but is broken.
+      lt_prog_compiler_static=
+      ;;
+
+    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
+
+    case $cc_basename in
+    nvcc*) # Cuda Compiler Driver 2.2
+      lt_prog_compiler_wl='-Xlinker '
+      if test -n "$lt_prog_compiler_pic"; then
+        lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic"
+      fi
+      ;;
+    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 | kopensolaris*-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'
+	;;
+      nagfor*)
+	# NAG Fortran compiler
+	lt_prog_compiler_wl='-Wl,-Wl,,'
+	lt_prog_compiler_pic='-PIC'
+	lt_prog_compiler_static='-Bstatic'
+	;;
+      pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
+        # 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* | bgxl* | bgf* | mpixl*)
+	# IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene
+	lt_prog_compiler_wl='-Wl,'
+	lt_prog_compiler_pic='-qpic'
+	lt_prog_compiler_static='-qstaticlink'
+	;;
+      *)
+	case `$CC -V 2>&1 | sed 5q` in
+	*Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*)
+	  # 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=''
+	  ;;
+	*Sun\ F* | *Sun*Fortran*)
+	  lt_prog_compiler_pic='-KPIC'
+	  lt_prog_compiler_static='-Bstatic'
+	  lt_prog_compiler_wl='-Qoption ld '
+	  ;;
+	*Sun\ C*)
+	  # Sun C 5.9
+	  lt_prog_compiler_pic='-KPIC'
+	  lt_prog_compiler_static='-Bstatic'
+	  lt_prog_compiler_wl='-Wl,'
+	  ;;
+        *Intel*\ [CF]*Compiler*)
+	  lt_prog_compiler_wl='-Wl,'
+	  lt_prog_compiler_pic='-fPIC'
+	  lt_prog_compiler_static='-static'
+	  ;;
+	*Portland\ Group*)
+	  lt_prog_compiler_wl='-Wl,'
+	  lt_prog_compiler_pic='-fpic'
+	  lt_prog_compiler_static='-Bstatic'
+	  ;;
+	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* | sunf77* | sunf90* | sunf95*)
+	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}: checking for $compiler option to produce PIC" >&5
+$as_echo_n "checking for $compiler option to produce PIC... " >&6; }
+if ${lt_cv_prog_compiler_pic+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_pic=$lt_prog_compiler_pic
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5
+$as_echo "$lt_cv_prog_compiler_pic" >&6; }
+lt_prog_compiler_pic=$lt_cv_prog_compiler_pic
+
+#
+# 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 ${lt_cv_prog_compiler_pic_works+:} false; 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:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $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 "$_lt_compiler_boilerplate" | $SED '/^$/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 ${lt_cv_prog_compiler_static_works+:} false; 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 "$_lt_linker_boilerplate" | $SED '/^$/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 ${lt_cv_prog_compiler_c_o+:} false; 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:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $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 "$_lt_compiler_boilerplate" | $SED '/^$/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 ${lt_cv_prog_compiler_c_o+:} false; 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:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $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 "$_lt_compiler_boilerplate" | $SED '/^$/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_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
+    ;;
+  esac
+
+  ld_shlibs=yes
+
+  # On some targets, GNU ld is compatible enough with the native linker
+  # that we're better off using the native interface for both.
+  lt_use_gnu_ld_interface=no
+  if test "$with_gnu_ld" = yes; then
+    case $host_os in
+      aix*)
+	# The AIX port of GNU ld has always aspired to compatibility
+	# with the native linker.  However, as the warning in the GNU ld
+	# block says, versions before 2.19.5* couldn't really create working
+	# shared libraries, regardless of the interface used.
+	case `$LD -v 2>&1` in
+	  *\ \(GNU\ Binutils\)\ 2.19.5*) ;;
+	  *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;;
+	  *\ \(GNU\ Binutils\)\ [3-9]*) ;;
+	  *)
+	    lt_use_gnu_ld_interface=yes
+	    ;;
+	esac
+	;;
+      *)
+	lt_use_gnu_ld_interface=yes
+	;;
+    esac
+  fi
+
+  if test "$lt_use_gnu_ld_interface" = 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
+      *GNU\ gold*) supports_anon_versioning=yes ;;
+      *\ [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.19, 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 install binutils
+*** 2.20 or above, or modify your PATH so that a non-GNU linker is found.
+*** You will then need to restart the configuration process.
+
+_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'
+      export_dynamic_flag_spec='${wl}--export-all-symbols'
+      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/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols'
+      exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'
+
+      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
+      ;;
+
+    haiku*)
+      archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+      link_all_deplibs=yes
+      ;;
+
+    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 | kopensolaris*-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=' $pic_flag'
+	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; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+	  tmp_addflag=' $pic_flag'
+	  ;;
+	pgf77* | pgf90* | pgf95* | pgfortran*)
+					# 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; func_echo_all \"$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]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below)
+	  tmp_sharedflag='-qmkshrobj'
+	  tmp_addflag= ;;
+	nvcc*)	# Cuda Compiler Driver 2.2
+	  whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+	  compiler_needs_object=yes
+	  ;;
+	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; func_echo_all \"$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* | bgf* | bgxlf* | mpixlf*)
+	  # 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='${wl}-rpath ${wl}$libdir'
+	  archive_cmds='$LD -shared $libobjs $deplibs $linker_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 $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+	  fi
+	  ;;
+	esac
+      else
+        ld_shlibs=no
+      fi
+      ;;
+
+    netbsd*)
+      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 $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	archive_expsym_cmds='$CC -shared $pic_flag $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 $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	archive_expsym_cmds='$CC -shared $pic_flag $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 $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	archive_expsym_cmds='$CC -shared $pic_flag $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
+	# Also, AIX nm treats weak defined symbols like other global
+	# defined symbols, whereas GNU nm marks them as "W".
+	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") || (\$ 2 == "W")) && (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
+      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.
+        if test "${lt_cv_aix_libpath+set}" = set; then
+  aix_libpath=$lt_cv_aix_libpath
+else
+  if ${lt_cv_aix_libpath_+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  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
+	  }
+      }'
+  lt_cv_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 "$lt_cv_aix_libpath_"; then
+    lt_cv_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 "$lt_cv_aix_libpath_"; then
+    lt_cv_aix_libpath_="/usr/lib:/lib"
+  fi
+
+fi
+
+  aix_libpath=$lt_cv_aix_libpath_
+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 func_echo_all "${wl}${allow_undefined_flag}"; 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.
+	 if test "${lt_cv_aix_libpath+set}" = set; then
+  aix_libpath=$lt_cv_aix_libpath
+else
+  if ${lt_cv_aix_libpath_+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  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
+	  }
+      }'
+  lt_cv_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 "$lt_cv_aix_libpath_"; then
+    lt_cv_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 "$lt_cv_aix_libpath_"; then
+    lt_cv_aix_libpath_="/usr/lib:/lib"
+  fi
+
+fi
+
+  aix_libpath=$lt_cv_aix_libpath_
+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'
+	  if test "$with_gnu_ld" = yes; then
+	    # We only use this code for GNU lds that support --whole-archive.
+	    whole_archive_flag_spec='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+	  else
+	    # Exported symbols can be pulled into shared objects from archives
+	    whole_archive_flag_spec='$convenience'
+	  fi
+	  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.
+      case $cc_basename in
+      cl*)
+	# Native MSVC
+	hardcode_libdir_flag_spec=' '
+	allow_undefined_flag=unsupported
+	always_export_symbols=yes
+	file_list_spec='@'
+	# 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 $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
+	archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	    sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
+	  else
+	    sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
+	  fi~
+	  $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+	  linknames='
+	# The linker will not automatically build a static lib if we build a DLL.
+	# _LT_TAGVAR(old_archive_from_new_cmds, )='true'
+	enable_shared_with_static_runtimes=yes
+	exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
+	export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols'
+	# Don't use ranlib
+	old_postinstall_cmds='chmod 644 $oldlib'
+	postlink_cmds='lt_outputfile="@OUTPUT@"~
+	  lt_tool_outputfile="@TOOL_OUTPUT@"~
+	  case $lt_outputfile in
+	    *.exe|*.EXE) ;;
+	    *)
+	      lt_outputfile="$lt_outputfile.exe"
+	      lt_tool_outputfile="$lt_tool_outputfile.exe"
+	      ;;
+	  esac~
+	  if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
+	    $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+	    $RM "$lt_outputfile.manifest";
+	  fi'
+	;;
+      *)
+	# Assume MSVC wrapper
+	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 `func_echo_all "$deplibs" | $SED '\''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'
+	enable_shared_with_static_runtimes=yes
+	;;
+      esac
+      ;;
+
+    darwin* | rhapsody*)
+
+
+  archive_cmds_need_lc=no
+  hardcode_direct=no
+  hardcode_automatic=yes
+  hardcode_shlibpath_var=unsupported
+  if test "$lt_cv_ld_force_load" = "yes"; then
+    whole_archive_flag_spec='`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+
+  else
+    whole_archive_flag_spec=''
+  fi
+  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=func_echo_all
+    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
+      ;;
+
+    # 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 $pic_flag -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 $pic_flag ${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 && test "$with_gnu_ld" = no; then
+	archive_cmds='$CC -shared $pic_flag ${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_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 && test "$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 $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	*)
+	  archive_cmds='$CC -shared $pic_flag ${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'
+	  ;;
+	*)
+
+	  # Older versions of the 11.00 compiler do not understand -b yet
+	  # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does)
+	  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5
+$as_echo_n "checking if $CC understands -b... " >&6; }
+if ${lt_cv_prog_compiler__b+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler__b=no
+   save_LDFLAGS="$LDFLAGS"
+   LDFLAGS="$LDFLAGS -b"
+   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 "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
+       $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+       if diff conftest.exp conftest.er2 >/dev/null; then
+         lt_cv_prog_compiler__b=yes
+       fi
+     else
+       lt_cv_prog_compiler__b=yes
+     fi
+   fi
+   $RM -r conftest*
+   LDFLAGS="$save_LDFLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5
+$as_echo "$lt_cv_prog_compiler__b" >&6; }
+
+if test x"$lt_cv_prog_compiler__b" = xyes; then
+    archive_cmds='$CC -b ${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
+
+	  ;;
+	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 $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${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.
+	# This should be the same for all languages, so no per-tag cache variable.
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5
+$as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; }
+if ${lt_cv_irix_exported_symbol+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  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) { return 0; }
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  lt_cv_irix_exported_symbol=yes
+else
+  lt_cv_irix_exported_symbol=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_irix_exported_symbol" >&5
+$as_echo "$lt_cv_irix_exported_symbol" >&6; }
+	if test "$lt_cv_irix_exported_symbol" = yes; then
+          archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
+	fi
+      else
+	archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+	archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -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*)
+      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" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${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" && func_echo_all "-set_version $verstring"` -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} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${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" && func_echo_all "-set_version $verstring"` -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 "-set_version $verstring"` -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 $pic_flag ${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 $pic_flag ${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; }
+if ${lt_cv_archive_cmds_need_lc+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  $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
+	    lt_cv_archive_cmds_need_lc=no
+	  else
+	    lt_cv_archive_cmds_need_lc=yes
+	  fi
+	  allow_undefined_flag=$lt_save_allow_undefined_flag
+	else
+	  cat conftest.err 1>&5
+	fi
+	$RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5
+$as_echo "$lt_cv_archive_cmds_need_lc" >&6; }
+      archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc
+      ;;
+    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
+  case $host_os in
+    mingw* | cegcc*) lt_sed_strip_eq="s,=\([A-Za-z]:\),\1,g" ;;
+    *) lt_sed_strip_eq="s,=/,/,g" ;;
+  esac
+  lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq`
+  case $lt_search_path_spec in
+  *\;*)
+    # 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 's/;/ /g'`
+    ;;
+  *)
+    lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"`
+    ;;
+  esac
+  # 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; }
+}'`
+  # AWK program above erroneously prepends '/' to C:/dos/paths
+  # for these hosts.
+  case $host_os in
+    mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\
+      $SED 's,/\([A-Za-z]:\),\1,g'` ;;
+  esac
+  sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP`
+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 # correct to gnu/linux during the next big refactor
+  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 # correct to gnu/linux during the next big refactor
+  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=`func_echo_all "$lib" | $SED '\''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 # correct to gnu/linux during the next big refactor
+  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,$cc_basename in
+  yes,*)
+    # gcc
+    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="$sys_lib_search_path_spec /usr/lib/w32api"
+      ;;
+    mingw* | cegcc*)
+      # MinGW DLLs use traditional 'lib' prefix
+      soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      ;;
+    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
+    dynamic_linker='Win32 ld.exe'
+    ;;
+
+  *,cl*)
+    # Native MSVC
+    libname_spec='$name'
+    soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+    library_names_spec='${libname}.dll.lib'
+
+    case $build_os in
+    mingw*)
+      sys_lib_search_path_spec=
+      lt_save_ifs=$IFS
+      IFS=';'
+      for lt_path in $LIB
+      do
+        IFS=$lt_save_ifs
+        # Let DOS variable expansion print the short 8.3 style file name.
+        lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"`
+        sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path"
+      done
+      IFS=$lt_save_ifs
+      # Convert to MSYS style.
+      sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'`
+      ;;
+    cygwin*)
+      # Convert to unix form, then to dos form, then back to unix form
+      # but this time dos style (no spaces!) so that the unix form looks
+      # like /cygdrive/c/PROGRA~1:/cygdr...
+      sys_lib_search_path_spec=`cygpath --path --unix "$LIB"`
+      sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null`
+      sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+      ;;
+    *)
+      sys_lib_search_path_spec="$LIB"
+      if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then
+        # It is most probably a Windows format PATH.
+        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
+      # FIXME: find the short name or the path components, as spaces are
+      # common. (e.g. "Program Files" -> "PROGRA~1")
+      ;;
+    esac
+
+    # 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'
+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+      dlpath=$dir/\$dldll~
+       $RM \$dlpath'
+    shlibpath_overrides_runpath=yes
+    dynamic_linker='Win32 link.exe'
+    ;;
+
+  *)
+    # Assume MSVC wrapper
+    library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
+    dynamic_linker='Win32 ld.exe'
+    ;;
+  esac
+  # 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 # correct to gnu/linux during the next big refactor
+  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
+  ;;
+
+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[23].*) objformat=aout ;;
+    *) objformat=elf ;;
+    esac
+  fi
+  # Handle Gentoo/FreeBSD as it was Linux
+  case $host_vendor in
+    gentoo)
+      version_type=linux ;;
+    *)
+      version_type=freebsd-$objformat ;;
+  esac
+
+  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
+      ;;
+    linux)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+      soname_spec='${libname}${release}${shared_ext}$major'
+      need_lib_prefix=no
+      need_version=no
+      ;;
+  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 # correct to gnu/linux during the next big refactor
+  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
+  ;;
+
+haiku*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  dynamic_linker="$host_os runtime_loader"
+  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=LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
+  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'
+  # or fails outright, so override atomically:
+  install_override_mode=555
+  ;;
+
+interix[3-9]*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  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 # correct to gnu/linux during the next big refactor
+	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 glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  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
+  if ${lt_cv_shlibpath_overrides_runpath+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_shlibpath_overrides_runpath=no
+    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 :
+  lt_cv_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
+
+fi
+
+  shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath
+
+  # 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;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'
+  ;;
+
+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 # correct to gnu/linux during the next big refactor
+  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 # correct to gnu/linux during the next big refactor
+  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 # correct to gnu/linux during the next big refactor
+  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 # correct to gnu/linux during the next big refactor
+    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 # correct to gnu/linux during the next big refactor
+  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 # correct to gnu/linux during the next big refactor
+  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 ${ac_cv_lib_dl_dlopen+:} false; 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" = xyes; 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" = xyes; 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 ${ac_cv_lib_dld_shl_load+:} false; 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" = xyes; 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" = xyes; 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 ${ac_cv_lib_dl_dlopen+:} false; 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" = xyes; 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 ${ac_cv_lib_svld_dlopen+:} false; 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" = xyes; 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 ${ac_cv_lib_dld_dld_link+:} false; 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" = xyes; 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 ${lt_cv_dlopen_self+:} false; 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 $LINENO "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
+
+/* When -fvisbility=hidden is used, assume the code has been annotated
+   correspondingly for the symbols needed.  */
+#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+int fnord () __attribute__((visibility("default")));
+#endif
+
+int fnord () { return 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;
+          else puts (dlerror ());
+	}
+      /* 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 ${lt_cv_dlopen_self_static+:} false; 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 $LINENO "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
+
+/* When -fvisbility=hidden is used, assume the code has been annotated
+   correspondingly for the symbols needed.  */
+#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+int fnord () __attribute__((visibility("default")));
+#endif
+
+int fnord () { return 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;
+          else puts (dlerror ());
+	}
+      /* 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"
+
+      if test -n "$CXX" && ( test "X$CXX" != "Xno" &&
+    ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) ||
+    (test "X$CXX" != "Xg++"))) ; then
+  ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_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; }
+if test -z "$CXXCPP"; then
+  if ${ac_cv_prog_CXXCPP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+      # Double quotes because CXXCPP needs to be expanded
+    for CXXCPP in "$CXX -E" "/lib/cpp"
+    do
+      ac_preproc_ok=false
+for ac_cxx_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_cxx_try_cpp "$LINENO"; then :
+
+else
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i 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_cxx_try_cpp "$LINENO"; then :
+  # Broken: success on invalid input.
+continue
+else
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+  break
+fi
+
+    done
+    ac_cv_prog_CXXCPP=$CXXCPP
+
+fi
+  CXXCPP=$ac_cv_prog_CXXCPP
+else
+  ac_cv_prog_CXXCPP=$CXXCPP
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5
+$as_echo "$CXXCPP" >&6; }
+ac_preproc_ok=false
+for ac_cxx_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_cxx_try_cpp "$LINENO"; then :
+
+else
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i 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_cxx_try_cpp "$LINENO"; then :
+  # Broken: success on invalid input.
+continue
+else
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i 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 \"$CXXCPP\" 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
+
+else
+  _lt_caught_CXX_error=yes
+fi
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+archive_cmds_need_lc_CXX=no
+allow_undefined_flag_CXX=
+always_export_symbols_CXX=no
+archive_expsym_cmds_CXX=
+compiler_needs_object_CXX=no
+export_dynamic_flag_spec_CXX=
+hardcode_direct_CXX=no
+hardcode_direct_absolute_CXX=no
+hardcode_libdir_flag_spec_CXX=
+hardcode_libdir_separator_CXX=
+hardcode_minus_L_CXX=no
+hardcode_shlibpath_var_CXX=unsupported
+hardcode_automatic_CXX=no
+inherit_rpath_CXX=no
+module_cmds_CXX=
+module_expsym_cmds_CXX=
+link_all_deplibs_CXX=unknown
+old_archive_cmds_CXX=$old_archive_cmds
+reload_flag_CXX=$reload_flag
+reload_cmds_CXX=$reload_cmds
+no_undefined_flag_CXX=
+whole_archive_flag_spec_CXX=
+enable_shared_with_static_runtimes_CXX=no
+
+# Source file extension for C++ test sources.
+ac_ext=cpp
+
+# Object file extension for compiled C++ test sources.
+objext=o
+objext_CXX=$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.
+
+
+
+
+
+
+# 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_CFLAGS=$CFLAGS
+  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++"}
+  CFLAGS=$CXXFLAGS
+  compiler=$CC
+  compiler_CXX=$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 "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
+
+
+  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_prog_compiler_no_builtin_flag_CXX=' -fno-builtin'
+    else
+      lt_prog_compiler_no_builtin_flag_CXX=
+    fi
+
+    if test "$GXX" = yes; then
+      # Set up default GNU C++ configuration
+
+
+
+# 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 ${lt_cv_path_LD+:} false; 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 ${lt_cv_prog_gnu_ld+:} false; 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
+
+
+
+
+
+
+
+      # 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
+        archive_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+        archive_expsym_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+
+        hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+        export_dynamic_flag_spec_CXX='${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
+          whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+        else
+          whole_archive_flag_spec_CXX=
+        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.
+        archive_cmds_CXX='$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 -v "^Configured with:" | $GREP "\-L"'
+
+    else
+      GXX=no
+      with_gnu_ld=no
+      wlarc=
+    fi
+
+    # PORTME: fill in a description of your system's C++ link characteristics
+    { $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; }
+    ld_shlibs_CXX=yes
+    case $host_os in
+      aix3*)
+        # FIXME: insert proper C++ library support
+        ld_shlibs_CXX=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.
+
+        archive_cmds_CXX=''
+        hardcode_direct_CXX=yes
+        hardcode_direct_absolute_CXX=yes
+        hardcode_libdir_separator_CXX=':'
+        link_all_deplibs_CXX=yes
+        file_list_spec_CXX='${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
+	    hardcode_direct_CXX=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_CXX=yes
+	    hardcode_libdir_flag_spec_CXX='-L$libdir'
+	    hardcode_libdir_separator_CXX=
+	  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
+
+        export_dynamic_flag_spec_CXX='${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_CXX=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_CXX='-berok'
+          # Determine the default libpath from the value encoded in an empty
+          # executable.
+          if test "${lt_cv_aix_libpath+set}" = set; then
+  aix_libpath=$lt_cv_aix_libpath
+else
+  if ${lt_cv_aix_libpath__CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+
+  lt_aix_libpath_sed='
+      /Import File Strings/,/^$/ {
+	  /^0/ {
+	      s/^0  *\([^ ]*\) *$/\1/
+	      p
+	  }
+      }'
+  lt_cv_aix_libpath__CXX=`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 "$lt_cv_aix_libpath__CXX"; then
+    lt_cv_aix_libpath__CXX=`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 "$lt_cv_aix_libpath__CXX"; then
+    lt_cv_aix_libpath__CXX="/usr/lib:/lib"
+  fi
+
+fi
+
+  aix_libpath=$lt_cv_aix_libpath__CXX
+fi
+
+          hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath"
+
+          archive_expsym_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+        else
+          if test "$host_cpu" = ia64; then
+	    hardcode_libdir_flag_spec_CXX='${wl}-R $libdir:/usr/lib:/lib'
+	    allow_undefined_flag_CXX="-z nodefs"
+	    archive_expsym_cmds_CXX="\$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.
+	    if test "${lt_cv_aix_libpath+set}" = set; then
+  aix_libpath=$lt_cv_aix_libpath
+else
+  if ${lt_cv_aix_libpath__CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+
+  lt_aix_libpath_sed='
+      /Import File Strings/,/^$/ {
+	  /^0/ {
+	      s/^0  *\([^ ]*\) *$/\1/
+	      p
+	  }
+      }'
+  lt_cv_aix_libpath__CXX=`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 "$lt_cv_aix_libpath__CXX"; then
+    lt_cv_aix_libpath__CXX=`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 "$lt_cv_aix_libpath__CXX"; then
+    lt_cv_aix_libpath__CXX="/usr/lib:/lib"
+  fi
+
+fi
+
+  aix_libpath=$lt_cv_aix_libpath__CXX
+fi
+
+	    hardcode_libdir_flag_spec_CXX='${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_CXX=' ${wl}-bernotok'
+	    allow_undefined_flag_CXX=' ${wl}-berok'
+	    if test "$with_gnu_ld" = yes; then
+	      # We only use this code for GNU lds that support --whole-archive.
+	      whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+	    else
+	      # Exported symbols can be pulled into shared objects from archives
+	      whole_archive_flag_spec_CXX='$convenience'
+	    fi
+	    archive_cmds_need_lc_CXX=yes
+	    # This is similar to how AIX traditionally builds its shared
+	    # libraries.
+	    archive_expsym_cmds_CXX="\$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
+	  allow_undefined_flag_CXX=unsupported
+	  # Joseph Beckenbach <jrb3 at best.com> says some releases of gcc
+	  # support --undefined.  This deserves some investigation.  FIXME
+	  archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	else
+	  ld_shlibs_CXX=no
+	fi
+	;;
+
+      chorus*)
+        case $cc_basename in
+          *)
+	  # FIXME: insert proper C++ library support
+	  ld_shlibs_CXX=no
+	  ;;
+        esac
+        ;;
+
+      cygwin* | mingw* | pw32* | cegcc*)
+	case $GXX,$cc_basename in
+	,cl* | no,cl*)
+	  # Native MSVC
+	  # hardcode_libdir_flag_spec is actually meaningless, as there is
+	  # no search path for DLLs.
+	  hardcode_libdir_flag_spec_CXX=' '
+	  allow_undefined_flag_CXX=unsupported
+	  always_export_symbols_CXX=yes
+	  file_list_spec_CXX='@'
+	  # 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_CXX='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
+	  archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	      $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
+	    else
+	      $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
+	    fi~
+	    $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+	    linknames='
+	  # The linker will not automatically build a static lib if we build a DLL.
+	  # _LT_TAGVAR(old_archive_from_new_cmds, CXX)='true'
+	  enable_shared_with_static_runtimes_CXX=yes
+	  # Don't use ranlib
+	  old_postinstall_cmds_CXX='chmod 644 $oldlib'
+	  postlink_cmds_CXX='lt_outputfile="@OUTPUT@"~
+	    lt_tool_outputfile="@TOOL_OUTPUT@"~
+	    case $lt_outputfile in
+	      *.exe|*.EXE) ;;
+	      *)
+		lt_outputfile="$lt_outputfile.exe"
+		lt_tool_outputfile="$lt_tool_outputfile.exe"
+		;;
+	    esac~
+	    func_to_tool_file "$lt_outputfile"~
+	    if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
+	      $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+	      $RM "$lt_outputfile.manifest";
+	    fi'
+	  ;;
+	*)
+	  # g++
+	  # _LT_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless,
+	  # as there is no search path for DLLs.
+	  hardcode_libdir_flag_spec_CXX='-L$libdir'
+	  export_dynamic_flag_spec_CXX='${wl}--export-all-symbols'
+	  allow_undefined_flag_CXX=unsupported
+	  always_export_symbols_CXX=no
+	  enable_shared_with_static_runtimes_CXX=yes
+
+	  if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+	    archive_cmds_CXX='$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...
+	    archive_expsym_cmds_CXX='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
+	    ld_shlibs_CXX=no
+	  fi
+	  ;;
+	esac
+	;;
+      darwin* | rhapsody*)
+
+
+  archive_cmds_need_lc_CXX=no
+  hardcode_direct_CXX=no
+  hardcode_automatic_CXX=yes
+  hardcode_shlibpath_var_CXX=unsupported
+  if test "$lt_cv_ld_force_load" = "yes"; then
+    whole_archive_flag_spec_CXX='`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+
+  else
+    whole_archive_flag_spec_CXX=''
+  fi
+  link_all_deplibs_CXX=yes
+  allow_undefined_flag_CXX="$_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=func_echo_all
+    archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
+    module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
+    archive_expsym_cmds_CXX="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_CXX="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}"
+       if test "$lt_cv_apple_cc_single_mod" != "yes"; then
+      archive_cmds_CXX="\$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}"
+      archive_expsym_cmds_CXX="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
+  ld_shlibs_CXX=no
+  fi
+
+	;;
+
+      dgux*)
+        case $cc_basename in
+          ec++*)
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+          ghcx*)
+	    # Green Hills C++ Compiler
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+          *)
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+        esac
+        ;;
+
+      freebsd2.*)
+        # C++ shared libraries reported to be fairly broken before
+	# switch to ELF
+        ld_shlibs_CXX=no
+        ;;
+
+      freebsd-elf*)
+        archive_cmds_need_lc_CXX=no
+        ;;
+
+      freebsd* | dragonfly*)
+        # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF
+        # conventions
+        ld_shlibs_CXX=yes
+        ;;
+
+      gnu*)
+        ;;
+
+      haiku*)
+        archive_cmds_CXX='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+        link_all_deplibs_CXX=yes
+        ;;
+
+      hpux9*)
+        hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir'
+        hardcode_libdir_separator_CXX=:
+        export_dynamic_flag_spec_CXX='${wl}-E'
+        hardcode_direct_CXX=yes
+        hardcode_minus_L_CXX=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
+            ld_shlibs_CXX=no
+            ;;
+          aCC*)
+            archive_cmds_CXX='$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; func_echo_all "$list"'
+            ;;
+          *)
+            if test "$GXX" = yes; then
+              archive_cmds_CXX='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${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
+              ld_shlibs_CXX=no
+            fi
+            ;;
+        esac
+        ;;
+
+      hpux10*|hpux11*)
+        if test $with_gnu_ld = no; then
+	  hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir'
+	  hardcode_libdir_separator_CXX=:
+
+          case $host_cpu in
+            hppa*64*|ia64*)
+              ;;
+            *)
+	      export_dynamic_flag_spec_CXX='${wl}-E'
+              ;;
+          esac
+        fi
+        case $host_cpu in
+          hppa*64*|ia64*)
+            hardcode_direct_CXX=no
+            hardcode_shlibpath_var_CXX=no
+            ;;
+          *)
+            hardcode_direct_CXX=yes
+            hardcode_direct_absolute_CXX=yes
+            hardcode_minus_L_CXX=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
+	    ld_shlibs_CXX=no
+	    ;;
+          aCC*)
+	    case $host_cpu in
+	      hppa*64*)
+	        archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	        ;;
+	      ia64*)
+	        archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	        ;;
+	      *)
+	        archive_cmds_CXX='$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; func_echo_all "$list"'
+	    ;;
+          *)
+	    if test "$GXX" = yes; then
+	      if test $with_gnu_ld = no; then
+	        case $host_cpu in
+	          hppa*64*)
+	            archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	            ;;
+	          ia64*)
+	            archive_cmds_CXX='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	            ;;
+	          *)
+	            archive_cmds_CXX='$CC -shared -nostdlib $pic_flag ${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
+	      ld_shlibs_CXX=no
+	    fi
+	    ;;
+        esac
+        ;;
+
+      interix[3-9]*)
+	hardcode_direct_CXX=no
+	hardcode_shlibpath_var_CXX=no
+	hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+	export_dynamic_flag_spec_CXX='${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_CXX='$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_CXX='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++
+	    archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -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.
+	    old_archive_cmds_CXX='$CC -ar -WR,-u -o $oldlib $oldobjs'
+	    ;;
+          *)
+	    if test "$GXX" = yes; then
+	      if test "$with_gnu_ld" = no; then
+	        archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+	      else
+	        archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib'
+	      fi
+	    fi
+	    link_all_deplibs_CXX=yes
+	    ;;
+        esac
+        hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+        hardcode_libdir_separator_CXX=:
+        inherit_rpath_CXX=yes
+        ;;
+
+      linux* | k*bsd*-gnu | kopensolaris*-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.
+	    archive_cmds_CXX='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'
+	    archive_expsym_cmds_CXX='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; func_echo_all "$list"'
+
+	    hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+	    export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+
+	    # Archives containing C++ object files must be created using
+	    # "CC -Bstatic", where "CC" is the KAI C++ compiler.
+	    old_archive_cmds_CXX='$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."*)
+	        archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+		archive_expsym_cmds_CXX='$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
+	        archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+		archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+		;;
+	    esac
+	    archive_cmds_need_lc_CXX=no
+	    hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+	    export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+	    whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+	    ;;
+          pgCC* | pgcpp*)
+            # Portland Group C++ compiler
+	    case `$CC -V` in
+	    *pgCC\ [1-5].* | *pgcpp\ [1-5].*)
+	      prelink_cmds_CXX='tpldir=Template.dir~
+		rm -rf $tpldir~
+		$CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~
+		compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"'
+	      old_archive_cmds_CXX='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 | sort | $NL2SP`~
+		$RANLIB $oldlib'
+	      archive_cmds_CXX='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 | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+	      archive_expsym_cmds_CXX='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 | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
+	      ;;
+	    *) # Version 6 and above use weak symbols
+	      archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+	      archive_expsym_cmds_CXX='$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
+
+	    hardcode_libdir_flag_spec_CXX='${wl}--rpath ${wl}$libdir'
+	    export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+	    whole_archive_flag_spec_CXX='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+            ;;
+	  cxx*)
+	    # Compaq C++
+	    archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	    archive_expsym_cmds_CXX='$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
+	    hardcode_libdir_flag_spec_CXX='-rpath $libdir'
+	    hardcode_libdir_separator_CXX=:
+
+	    # 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=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed'
+	    ;;
+	  xl* | mpixl* | bgxl*)
+	    # IBM XL 8.0 on PPC, with GNU ld
+	    hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+	    export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+	    archive_cmds_CXX='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	    if test "x$supports_anon_versioning" = xyes; then
+	      archive_expsym_cmds_CXX='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
+	      no_undefined_flag_CXX=' -zdefs'
+	      archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	      archive_expsym_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols'
+	      hardcode_libdir_flag_spec_CXX='-R$libdir'
+	      whole_archive_flag_spec_CXX='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+	      compiler_needs_object_CXX=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='func_echo_all'
+
+	      # 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.
+	      old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs'
+	      ;;
+	    esac
+	    ;;
+	esac
+	;;
+
+      lynxos*)
+        # FIXME: insert proper C++ library support
+	ld_shlibs_CXX=no
+	;;
+
+      m88k*)
+        # FIXME: insert proper C++ library support
+        ld_shlibs_CXX=no
+	;;
+
+      mvs*)
+        case $cc_basename in
+          cxx*)
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+	  *)
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+	esac
+	;;
+
+      netbsd*)
+        if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+	  archive_cmds_CXX='$LD -Bshareable  -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags'
+	  wlarc=
+	  hardcode_libdir_flag_spec_CXX='-R$libdir'
+	  hardcode_direct_CXX=yes
+	  hardcode_shlibpath_var_CXX=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*)
+        ld_shlibs_CXX=yes
+	;;
+
+      openbsd2*)
+        # C++ shared libraries are fairly broken
+	ld_shlibs_CXX=no
+	;;
+
+      openbsd*)
+	if test -f /usr/libexec/ld.so; then
+	  hardcode_direct_CXX=yes
+	  hardcode_shlibpath_var_CXX=no
+	  hardcode_direct_absolute_CXX=yes
+	  archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+	  hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+	  if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+	    archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib'
+	    export_dynamic_flag_spec_CXX='${wl}-E'
+	    whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+	  fi
+	  output_verbose_link_cmd=func_echo_all
+	else
+	  ld_shlibs_CXX=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.
+	    archive_cmds_CXX='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'
+
+	    hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+	    hardcode_libdir_separator_CXX=:
+
+	    # Archives containing C++ object files must be created using
+	    # the KAI C++ compiler.
+	    case $host in
+	      osf3*) old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ;;
+	      *) old_archive_cmds_CXX='$CC -o $oldlib $oldobjs' ;;
+	    esac
+	    ;;
+          RCC*)
+	    # Rational C++ 2.4.1
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+          cxx*)
+	    case $host in
+	      osf3*)
+	        allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*'
+	        archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+	        hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+		;;
+	      *)
+	        allow_undefined_flag_CXX=' -expect_unresolved \*'
+	        archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+	        archive_expsym_cmds_CXX='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 "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~
+	          $RM $lib.exp'
+	        hardcode_libdir_flag_spec_CXX='-rpath $libdir'
+		;;
+	    esac
+
+	    hardcode_libdir_separator_CXX=:
+
+	    # 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=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+	    ;;
+	  *)
+	    if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+	      allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*'
+	      case $host in
+	        osf3*)
+	          archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+		  ;;
+	        *)
+	          archive_cmds_CXX='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+		  ;;
+	      esac
+
+	      hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+	      hardcode_libdir_separator_CXX=:
+
+	      # 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 -v "^Configured with:" | $GREP "\-L"'
+
+	    else
+	      # FIXME: insert proper C++ library support
+	      ld_shlibs_CXX=no
+	    fi
+	    ;;
+        esac
+        ;;
+
+      psos*)
+        # FIXME: insert proper C++ library support
+        ld_shlibs_CXX=no
+        ;;
+
+      sunos4*)
+        case $cc_basename in
+          CC*)
+	    # Sun C++ 4.x
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+          lcc*)
+	    # Lucid
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+          *)
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+        esac
+        ;;
+
+      solaris*)
+        case $cc_basename in
+          CC* | sunCC*)
+	    # Sun C++ 4.2, 5.x and Centerline C++
+            archive_cmds_need_lc_CXX=yes
+	    no_undefined_flag_CXX=' -zdefs'
+	    archive_cmds_CXX='$CC -G${allow_undefined_flag}  -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	    archive_expsym_cmds_CXX='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'
+
+	    hardcode_libdir_flag_spec_CXX='-R$libdir'
+	    hardcode_shlibpath_var_CXX=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?)
+		whole_archive_flag_spec_CXX='-z allextract$convenience -z defaultextract'
+	        ;;
+	    esac
+	    link_all_deplibs_CXX=yes
+
+	    output_verbose_link_cmd='func_echo_all'
+
+	    # 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.
+	    old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs'
+	    ;;
+          gcx*)
+	    # Green Hills C++ Compiler
+	    archive_cmds_CXX='$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.
+	    old_archive_cmds_CXX='$CC $LDFLAGS -archive -o $oldlib $oldobjs'
+	    ;;
+          *)
+	    # GNU C++ compiler with Solaris linker
+	    if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+	      no_undefined_flag_CXX=' ${wl}-z ${wl}defs'
+	      if $CC --version | $GREP -v '^2\.7' > /dev/null; then
+	        archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+	        archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+		  $CC -shared $pic_flag -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 -v "^Configured with:" | $GREP "\-L"'
+	      else
+	        # g++ 2.7 appears to require `-G' NOT `-shared' on this
+	        # platform.
+	        archive_cmds_CXX='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+	        archive_expsym_cmds_CXX='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 -v "^Configured with:" | $GREP "\-L"'
+	      fi
+
+	      hardcode_libdir_flag_spec_CXX='${wl}-R $wl$libdir'
+	      case $host_os in
+		solaris2.[0-5] | solaris2.[0-5].*) ;;
+		*)
+		  whole_archive_flag_spec_CXX='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+		  ;;
+	      esac
+	    fi
+	    ;;
+        esac
+        ;;
+
+    sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
+      no_undefined_flag_CXX='${wl}-z,text'
+      archive_cmds_need_lc_CXX=no
+      hardcode_shlibpath_var_CXX=no
+      runpath_var='LD_RUN_PATH'
+
+      case $cc_basename in
+        CC*)
+	  archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	*)
+	  archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  archive_expsym_cmds_CXX='$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.
+	no_undefined_flag_CXX='${wl}-z,text'
+	allow_undefined_flag_CXX='${wl}-z,nodefs'
+	archive_cmds_need_lc_CXX=no
+	hardcode_shlibpath_var_CXX=no
+	hardcode_libdir_flag_spec_CXX='${wl}-R,$libdir'
+	hardcode_libdir_separator_CXX=':'
+	link_all_deplibs_CXX=yes
+	export_dynamic_flag_spec_CXX='${wl}-Bexport'
+	runpath_var='LD_RUN_PATH'
+
+	case $cc_basename in
+          CC*)
+	    archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    old_archive_cmds_CXX='$CC -Tprelink_objects $oldobjs~
+	      '"$old_archive_cmds_CXX"
+	    reload_cmds_CXX='$CC -Tprelink_objects $reload_objs~
+	      '"$reload_cmds_CXX"
+	    ;;
+	  *)
+	    archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    archive_expsym_cmds_CXX='$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
+	    ld_shlibs_CXX=no
+	    ;;
+          *)
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+        esac
+        ;;
+
+      vxworks*)
+        # FIXME: insert proper C++ library support
+        ld_shlibs_CXX=no
+        ;;
+
+      *)
+        # FIXME: insert proper C++ library support
+        ld_shlibs_CXX=no
+        ;;
+    esac
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5
+$as_echo "$ld_shlibs_CXX" >&6; }
+    test "$ld_shlibs_CXX" = no && can_build_shared=no
+
+    GCC_CXX="$GXX"
+    LD_CXX="$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...
+    # Dependencies to place before and after the object being linked:
+predep_objects_CXX=
+postdep_objects_CXX=
+predeps_CXX=
+postdeps_CXX=
+compiler_lib_search_path_CXX=
+
+cat > conftest.$ac_ext <<_LT_EOF
+class Foo
+{
+public:
+  Foo (void) { a = 0; }
+private:
+  int a;
+};
+_LT_EOF
+
+
+_lt_libdeps_save_CFLAGS=$CFLAGS
+case "$CC $CFLAGS " in #(
+*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;;
+*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;;
+*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;;
+esac
+
+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
+  # 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 ${prev}${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
+       fi
+
+       # Expand the sysroot to ease extracting the directories later.
+       if test -z "$prev"; then
+         case $p in
+         -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;;
+         -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;;
+         -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;;
+         esac
+       fi
+       case $p in
+       =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;;
+       esac
+       if test "$pre_test_object_deps_done" = no; then
+	 case ${prev} 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 "$compiler_lib_search_path_CXX"; then
+	     compiler_lib_search_path_CXX="${prev}${p}"
+	   else
+	     compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} ${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 "$postdeps_CXX"; then
+	   postdeps_CXX="${prev}${p}"
+	 else
+	   postdeps_CXX="${postdeps_CXX} ${prev}${p}"
+	 fi
+       fi
+       prev=
+       ;;
+
+    *.lto.$objext) ;; # Ignore GCC LTO objects
+    *.$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 "$predep_objects_CXX"; then
+	   predep_objects_CXX="$p"
+	 else
+	   predep_objects_CXX="$predep_objects_CXX $p"
+	 fi
+       else
+	 if test -z "$postdep_objects_CXX"; then
+	   postdep_objects_CXX="$p"
+	 else
+	   postdep_objects_CXX="$postdep_objects_CXX $p"
+	 fi
+       fi
+       ;;
+
+    *) ;; # Ignore the rest.
+
+    esac
+  done
+
+  # Clean up.
+  rm -f a.out a.exe
+else
+  echo "libtool.m4: error: problem compiling CXX test program"
+fi
+
+$RM -f confest.$objext
+CFLAGS=$_lt_libdeps_save_CFLAGS
+
+# PORTME: override above test on systems where it is broken
+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.
+  predep_objects_CXX=
+  postdep_objects_CXX=
+  postdeps_CXX=
+  ;;
+
+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
+      postdeps_CXX='-library=Cstd -library=Crun'
+    fi
+    ;;
+  esac
+  ;;
+
+solaris*)
+  case $cc_basename in
+  CC* | sunCC*)
+    # 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
+      postdeps_CXX='-library=Cstd -library=Crun'
+    fi
+    ;;
+  esac
+  ;;
+esac
+
+
+case " $postdeps_CXX " in
+*" -lc "*) archive_cmds_need_lc_CXX=no ;;
+esac
+ compiler_lib_search_dirs_CXX=
+if test -n "${compiler_lib_search_path_CXX}"; then
+ compiler_lib_search_dirs_CXX=`echo " ${compiler_lib_search_path_CXX}" | ${SED} -e 's! -L! !g' -e 's!^ !!'`
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    lt_prog_compiler_wl_CXX=
+lt_prog_compiler_pic_CXX=
+lt_prog_compiler_static_CXX=
+
+
+  # C++ specific cases for pic, static, wl, etc.
+  if test "$GXX" = yes; then
+    lt_prog_compiler_wl_CXX='-Wl,'
+    lt_prog_compiler_static_CXX='-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_CXX='-Bstatic'
+      fi
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            lt_prog_compiler_pic_CXX='-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_CXX='-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
+      lt_prog_compiler_pic_CXX='-DDLL_EXPORT'
+      ;;
+    darwin* | rhapsody*)
+      # PIC is the default on this platform
+      # Common symbols not allowed in MH_DYLIB files
+      lt_prog_compiler_pic_CXX='-fno-common'
+      ;;
+    *djgpp*)
+      # DJGPP does not support shared libraries at all
+      lt_prog_compiler_pic_CXX=
+      ;;
+    haiku*)
+      # PIC is the default for Haiku.
+      # The "-static" flag exists, but is broken.
+      lt_prog_compiler_static_CXX=
+      ;;
+    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_prog_compiler_pic_CXX=-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_prog_compiler_pic_CXX='-fPIC'
+	;;
+      esac
+      ;;
+    *qnx* | *nto*)
+      # QNX uses GNU C++, but need to define -shared option too, otherwise
+      # it will coredump.
+      lt_prog_compiler_pic_CXX='-fPIC -shared'
+      ;;
+    *)
+      lt_prog_compiler_pic_CXX='-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_prog_compiler_static_CXX='-Bstatic'
+	else
+	  lt_prog_compiler_static_CXX='-bnso -bI:/lib/syscalls.exp'
+	fi
+	;;
+      chorus*)
+	case $cc_basename in
+	cxch68*)
+	  # Green Hills C++ Compiler
+	  # _LT_TAGVAR(lt_prog_compiler_static, CXX)="--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
+	;;
+      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).
+	lt_prog_compiler_pic_CXX='-DDLL_EXPORT'
+	;;
+      dgux*)
+	case $cc_basename in
+	  ec++*)
+	    lt_prog_compiler_pic_CXX='-KPIC'
+	    ;;
+	  ghcx*)
+	    # Green Hills C++ Compiler
+	    lt_prog_compiler_pic_CXX='-pic'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      freebsd* | dragonfly*)
+	# FreeBSD uses GNU C++
+	;;
+      hpux9* | hpux10* | hpux11*)
+	case $cc_basename in
+	  CC*)
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_static_CXX='${wl}-a ${wl}archive'
+	    if test "$host_cpu" != ia64; then
+	      lt_prog_compiler_pic_CXX='+Z'
+	    fi
+	    ;;
+	  aCC*)
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_static_CXX='${wl}-a ${wl}archive'
+	    case $host_cpu in
+	    hppa*64*|ia64*)
+	      # +Z the default
+	      ;;
+	    *)
+	      lt_prog_compiler_pic_CXX='+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_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_static_CXX='-non_shared'
+	    # CC pic flag -KPIC is the default.
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      linux* | k*bsd*-gnu | kopensolaris*-gnu)
+	case $cc_basename in
+	  KCC*)
+	    # KAI C++ Compiler
+	    lt_prog_compiler_wl_CXX='--backend -Wl,'
+	    lt_prog_compiler_pic_CXX='-fPIC'
+	    ;;
+	  ecpc* )
+	    # old Intel C++ for x86_64 which still supported -KPIC.
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_pic_CXX='-KPIC'
+	    lt_prog_compiler_static_CXX='-static'
+	    ;;
+	  icpc* )
+	    # Intel C++, used to be incompatible with GCC.
+	    # ICC 10 doesn't accept -KPIC any more.
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_pic_CXX='-fPIC'
+	    lt_prog_compiler_static_CXX='-static'
+	    ;;
+	  pgCC* | pgcpp*)
+	    # Portland Group C++ compiler
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_pic_CXX='-fpic'
+	    lt_prog_compiler_static_CXX='-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_prog_compiler_pic_CXX=
+	    lt_prog_compiler_static_CXX='-non_shared'
+	    ;;
+	  xlc* | xlC* | bgxl[cC]* | mpixl[cC]*)
+	    # IBM XL 8.0, 9.0 on PPC and BlueGene
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_pic_CXX='-qpic'
+	    lt_prog_compiler_static_CXX='-qstaticlink'
+	    ;;
+	  *)
+	    case `$CC -V 2>&1 | sed 5q` in
+	    *Sun\ C*)
+	      # Sun C++ 5.9
+	      lt_prog_compiler_pic_CXX='-KPIC'
+	      lt_prog_compiler_static_CXX='-Bstatic'
+	      lt_prog_compiler_wl_CXX='-Qoption ld '
+	      ;;
+	    esac
+	    ;;
+	esac
+	;;
+      lynxos*)
+	;;
+      m88k*)
+	;;
+      mvs*)
+	case $cc_basename in
+	  cxx*)
+	    lt_prog_compiler_pic_CXX='-W c,exportall'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      netbsd*)
+	;;
+      *qnx* | *nto*)
+        # QNX uses GNU C++, but need to define -shared option too, otherwise
+        # it will coredump.
+        lt_prog_compiler_pic_CXX='-fPIC -shared'
+        ;;
+      osf3* | osf4* | osf5*)
+	case $cc_basename in
+	  KCC*)
+	    lt_prog_compiler_wl_CXX='--backend -Wl,'
+	    ;;
+	  RCC*)
+	    # Rational C++ 2.4.1
+	    lt_prog_compiler_pic_CXX='-pic'
+	    ;;
+	  cxx*)
+	    # Digital/Compaq C++
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    # Make sure the PIC flag is empty.  It appears that all Alpha
+	    # Linux and Compaq Tru64 Unix objects are PIC.
+	    lt_prog_compiler_pic_CXX=
+	    lt_prog_compiler_static_CXX='-non_shared'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      psos*)
+	;;
+      solaris*)
+	case $cc_basename in
+	  CC* | sunCC*)
+	    # Sun C++ 4.2, 5.x and Centerline C++
+	    lt_prog_compiler_pic_CXX='-KPIC'
+	    lt_prog_compiler_static_CXX='-Bstatic'
+	    lt_prog_compiler_wl_CXX='-Qoption ld '
+	    ;;
+	  gcx*)
+	    # Green Hills C++ Compiler
+	    lt_prog_compiler_pic_CXX='-PIC'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      sunos4*)
+	case $cc_basename in
+	  CC*)
+	    # Sun C++ 4.x
+	    lt_prog_compiler_pic_CXX='-pic'
+	    lt_prog_compiler_static_CXX='-Bstatic'
+	    ;;
+	  lcc*)
+	    # Lucid
+	    lt_prog_compiler_pic_CXX='-pic'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+	case $cc_basename in
+	  CC*)
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_pic_CXX='-KPIC'
+	    lt_prog_compiler_static_CXX='-Bstatic'
+	    ;;
+	esac
+	;;
+      tandem*)
+	case $cc_basename in
+	  NCC*)
+	    # NonStop-UX NCC 3.20
+	    lt_prog_compiler_pic_CXX='-KPIC'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      vxworks*)
+	;;
+      *)
+	lt_prog_compiler_can_build_shared_CXX=no
+	;;
+    esac
+  fi
+
+case $host_os in
+  # For platforms which do not support PIC, -DPIC is meaningless:
+  *djgpp*)
+    lt_prog_compiler_pic_CXX=
+    ;;
+  *)
+    lt_prog_compiler_pic_CXX="$lt_prog_compiler_pic_CXX -DPIC"
+    ;;
+esac
+
+{ $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 ${lt_cv_prog_compiler_pic_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_pic_CXX=$lt_prog_compiler_pic_CXX
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_CXX" >&5
+$as_echo "$lt_cv_prog_compiler_pic_CXX" >&6; }
+lt_prog_compiler_pic_CXX=$lt_cv_prog_compiler_pic_CXX
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$lt_prog_compiler_pic_CXX"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5
+$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... " >&6; }
+if ${lt_cv_prog_compiler_pic_works_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_pic_works_CXX=no
+   ac_outfile=conftest.$ac_objext
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+   lt_compiler_flag="$lt_prog_compiler_pic_CXX -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:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $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 "$_lt_compiler_boilerplate" | $SED '/^$/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_CXX=yes
+     fi
+   fi
+   $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works_CXX" >&5
+$as_echo "$lt_cv_prog_compiler_pic_works_CXX" >&6; }
+
+if test x"$lt_cv_prog_compiler_pic_works_CXX" = xyes; then
+    case $lt_prog_compiler_pic_CXX in
+     "" | " "*) ;;
+     *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;;
+     esac
+else
+    lt_prog_compiler_pic_CXX=
+     lt_prog_compiler_can_build_shared_CXX=no
+fi
+
+fi
+
+
+
+
+
+#
+# Check to make sure the static flag actually works.
+#
+wl=$lt_prog_compiler_wl_CXX eval lt_tmp_static_flag=\"$lt_prog_compiler_static_CXX\"
+{ $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 ${lt_cv_prog_compiler_static_works_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_static_works_CXX=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 "$_lt_linker_boilerplate" | $SED '/^$/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_CXX=yes
+       fi
+     else
+       lt_cv_prog_compiler_static_works_CXX=yes
+     fi
+   fi
+   $RM -r conftest*
+   LDFLAGS="$save_LDFLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works_CXX" >&5
+$as_echo "$lt_cv_prog_compiler_static_works_CXX" >&6; }
+
+if test x"$lt_cv_prog_compiler_static_works_CXX" = xyes; then
+    :
+else
+    lt_prog_compiler_static_CXX=
+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 ${lt_cv_prog_compiler_c_o_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_c_o_CXX=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:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $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 "$_lt_compiler_boilerplate" | $SED '/^$/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_CXX=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_CXX" >&5
+$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&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 ${lt_cv_prog_compiler_c_o_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_c_o_CXX=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:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $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 "$_lt_compiler_boilerplate" | $SED '/^$/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_CXX=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_CXX" >&5
+$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; }
+
+
+
+
+hard_links="nottested"
+if test "$lt_cv_prog_compiler_c_o_CXX" = 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; }
+
+  export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  exclude_expsyms_CXX='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'
+  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
+    # Also, AIX nm treats weak defined symbols like other global defined
+    # symbols, whereas GNU nm marks them as "W".
+    if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+      export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+    else
+      export_symbols_cmds_CXX='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+    fi
+    ;;
+  pw32*)
+    export_symbols_cmds_CXX="$ltdll_cmds"
+    ;;
+  cygwin* | mingw* | cegcc*)
+    case $cc_basename in
+    cl*)
+      exclude_expsyms_CXX='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
+      ;;
+    *)
+      export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols'
+      exclude_expsyms_CXX='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'
+      ;;
+    esac
+    ;;
+  *)
+    export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+    ;;
+  esac
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5
+$as_echo "$ld_shlibs_CXX" >&6; }
+test "$ld_shlibs_CXX" = no && can_build_shared=no
+
+with_gnu_ld_CXX=$with_gnu_ld
+
+
+
+
+
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$archive_cmds_need_lc_CXX" in
+x|xyes)
+  # Assume -lc should be added
+  archive_cmds_need_lc_CXX=yes
+
+  if test "$enable_shared" = yes && test "$GCC" = yes; then
+    case $archive_cmds_CXX 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; }
+if ${lt_cv_archive_cmds_need_lc_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  $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_CXX
+	  pic_flag=$lt_prog_compiler_pic_CXX
+	  compiler_flags=-v
+	  linker_flags=-v
+	  verstring=
+	  output_objdir=.
+	  libname=conftest
+	  lt_save_allow_undefined_flag=$allow_undefined_flag_CXX
+	  allow_undefined_flag_CXX=
+	  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5
+  (eval $archive_cmds_CXX 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
+	    lt_cv_archive_cmds_need_lc_CXX=no
+	  else
+	    lt_cv_archive_cmds_need_lc_CXX=yes
+	  fi
+	  allow_undefined_flag_CXX=$lt_save_allow_undefined_flag
+	else
+	  cat conftest.err 1>&5
+	fi
+	$RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc_CXX" >&5
+$as_echo "$lt_cv_archive_cmds_need_lc_CXX" >&6; }
+      archive_cmds_need_lc_CXX=$lt_cv_archive_cmds_need_lc_CXX
+      ;;
+    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 # correct to gnu/linux during the next big refactor
+  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 # correct to gnu/linux during the next big refactor
+  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=`func_echo_all "$lib" | $SED '\''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 # correct to gnu/linux during the next big refactor
+  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,$cc_basename in
+  yes,*)
+    # gcc
+    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}'
+
+      ;;
+    mingw* | cegcc*)
+      # MinGW DLLs use traditional 'lib' prefix
+      soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      ;;
+    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
+    dynamic_linker='Win32 ld.exe'
+    ;;
+
+  *,cl*)
+    # Native MSVC
+    libname_spec='$name'
+    soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+    library_names_spec='${libname}.dll.lib'
+
+    case $build_os in
+    mingw*)
+      sys_lib_search_path_spec=
+      lt_save_ifs=$IFS
+      IFS=';'
+      for lt_path in $LIB
+      do
+        IFS=$lt_save_ifs
+        # Let DOS variable expansion print the short 8.3 style file name.
+        lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"`
+        sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path"
+      done
+      IFS=$lt_save_ifs
+      # Convert to MSYS style.
+      sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'`
+      ;;
+    cygwin*)
+      # Convert to unix form, then to dos form, then back to unix form
+      # but this time dos style (no spaces!) so that the unix form looks
+      # like /cygdrive/c/PROGRA~1:/cygdr...
+      sys_lib_search_path_spec=`cygpath --path --unix "$LIB"`
+      sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null`
+      sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+      ;;
+    *)
+      sys_lib_search_path_spec="$LIB"
+      if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then
+        # It is most probably a Windows format PATH.
+        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
+      # FIXME: find the short name or the path components, as spaces are
+      # common. (e.g. "Program Files" -> "PROGRA~1")
+      ;;
+    esac
+
+    # 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'
+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+      dlpath=$dir/\$dldll~
+       $RM \$dlpath'
+    shlibpath_overrides_runpath=yes
+    dynamic_linker='Win32 link.exe'
+    ;;
+
+  *)
+    # Assume MSVC wrapper
+    library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
+    dynamic_linker='Win32 ld.exe'
+    ;;
+  esac
+  # 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 # correct to gnu/linux during the next big refactor
+  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
+  ;;
+
+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[23].*) objformat=aout ;;
+    *) objformat=elf ;;
+    esac
+  fi
+  # Handle Gentoo/FreeBSD as it was Linux
+  case $host_vendor in
+    gentoo)
+      version_type=linux ;;
+    *)
+      version_type=freebsd-$objformat ;;
+  esac
+
+  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
+      ;;
+    linux)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+      soname_spec='${libname}${release}${shared_ext}$major'
+      need_lib_prefix=no
+      need_version=no
+      ;;
+  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 # correct to gnu/linux during the next big refactor
+  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
+  ;;
+
+haiku*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  dynamic_linker="$host_os runtime_loader"
+  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=LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
+  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'
+  # or fails outright, so override atomically:
+  install_override_mode=555
+  ;;
+
+interix[3-9]*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  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 # correct to gnu/linux during the next big refactor
+	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 glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  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
+  if ${lt_cv_shlibpath_overrides_runpath+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_shlibpath_overrides_runpath=no
+    save_LDFLAGS=$LDFLAGS
+    save_libdir=$libdir
+    eval "libdir=/foo; wl=\"$lt_prog_compiler_wl_CXX\"; \
+	 LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec_CXX\""
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+  if  ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then :
+  lt_cv_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
+
+fi
+
+  shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath
+
+  # 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;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'
+  ;;
+
+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 # correct to gnu/linux during the next big refactor
+  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 # correct to gnu/linux during the next big refactor
+  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 # correct to gnu/linux during the next big refactor
+  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 # correct to gnu/linux during the next big refactor
+    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 # correct to gnu/linux during the next big refactor
+  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 # correct to gnu/linux during the next big refactor
+  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_CXX=
+if test -n "$hardcode_libdir_flag_spec_CXX" ||
+   test -n "$runpath_var_CXX" ||
+   test "X$hardcode_automatic_CXX" = "Xyes" ; then
+
+  # We can hardcode non-existent directories.
+  if test "$hardcode_direct_CXX" != 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, CXX)" != no &&
+     test "$hardcode_minus_L_CXX" != no; then
+    # Linking always hardcodes the temporary library directory.
+    hardcode_action_CXX=relink
+  else
+    # We can link without hardcoding, and we can hardcode nonexisting dirs.
+    hardcode_action_CXX=immediate
+  fi
+else
+  # We cannot hardcode anything, or else we can only hardcode existing
+  # directories.
+  hardcode_action_CXX=unsupported
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action_CXX" >&5
+$as_echo "$hardcode_action_CXX" >&6; }
+
+if test "$hardcode_action_CXX" = relink ||
+   test "$inherit_rpath_CXX" = 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"
+
+  CC=$lt_save_CC
+  CFLAGS=$lt_save_CFLAGS
+  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_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_config_commands="$ac_config_commands libtool"
+
+
+
+
+# Only expand once:
+
+
+# ([shared])
+# LT_INIT(dlopen disable-static) # doesn't work on PowerPC!
+
+# Checks for libraries.
+
+DEFAULT_CHECKING_PATH="/usr /usr/local /sw /opt/local"
+
+
+# Check whether --with-gmp was given.
+if test "${with_gmp+set}" = set; then :
+  withval=$with_gmp; if test "$withval" = yes ; then
+			GMP_HOME_PATH="${DEFAULT_CHECKING_PATH}"
+	         elif test "$withval" != no ; then
+			GMP_HOME_PATH="$withval ${DEFAULT_CHECKING_PATH}"
+	        fi
+else
+  GMP_HOME_PATH="${DEFAULT_CHECKING_PATH}"
+fi
+
+
+min_gmp_version=3.1.1
+
+BACKUP_CFLAGS=${CFLAGS}
+BACKUP_LIBS=${LIBS}
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GMP >= $min_gmp_version" >&5
+$as_echo_n "checking for GMP >= $min_gmp_version... " >&6; }
+
+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
+
+
+for GMP_HOME in ${GMP_HOME_PATH}
+  do
+#	if test -r "$GMP_HOME/include/gmp.h"; then
+
+		if test "x$GMP_HOME" != "x/usr"; then
+			GMP_CFLAGS="-I${GMP_HOME}/include"
+			GMP_LIBS="-L${GMP_HOME}/lib -Wl,-rpath -Wl,${GMP_HOME}/lib -lgmp"
+		else
+			GMP_CFLAGS=""
+			GMP_LIBS="-lgmp"
+		fi
+
+		CFLAGS="${BACKUP_CFLAGS} ${GMP_CFLAGS}"
+		LIBS="${BACKUP_LIBS} ${GMP_LIBS}"
+
+    # According to C. Fieker this would link but would not RUN
+    # (AC_TRY_RUN) due to missing SHARED libgmp.so :(
+    # TODO: set LD_LIBRARY_PATH???
+		cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <gmp.h>
+int
+main ()
+{
+mpz_t a; mpz_init (a);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+        		if test "$cross_compiling" = yes; then :
+
+				{ $as_echo "$as_me:${as_lineno-$LINENO}: result: unknown" >&5
+$as_echo "unknown" >&6; }
+				echo "WARNING: You appear to be cross compiling, so there is no way to determine"
+				echo "whether your GMP version is new enough. I am assuming it is."
+
+
+
+				HAVE_GMP=yes
+
+$as_echo "#define HAVE_GMP 1" >>confdefs.h
+
+				:
+				break
+
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <gmp.h>
+			 int main () {  if (__GNU_MP_VERSION < 3) return -1; else return 0; }
+
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+				{ $as_echo "$as_me:${as_lineno-$LINENO}: result: found" >&5
+$as_echo "found" >&6; }
+
+
+
+$as_echo "#define HAVE_GMP 1" >>confdefs.h
+
+				# See if we are running GMP 4.0
+	   			{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether GMP is 4.0 or greater" >&5
+$as_echo_n "checking whether GMP is 4.0 or greater... " >&6; }
+		   		if test "$cross_compiling" = yes; then :
+
+										{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <gmp.h>
+	    			int main () { if (__GNU_MP_VERSION < 4) return -1; else return 0; }
+
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+					gmp_found="yes"
+					{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+					GMP_VERSION=""
+
+
+else
+
+					{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+$as_echo "#define GMP_VERSION_3 1" >>confdefs.h
+
+					GMP_VERSION="-DGMP_VERSION_3"
+
+
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+				:
+				break
+
+else
+
+				gmp_problem="$gmp_problem $GMP_HOME"
+				unset GMP_CFLAGS
+				unset GMP_LIBS
+
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+
+else
+
+		gmp_found="no"
+		unset GMP_CFLAGS
+		unset GMP_LIBS
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+
+#	else
+#		gmp_found="no"
+#	fi
+done
+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
+
+
+CFLAGS=${BACKUP_CFLAGS}
+LIBS=${BACKUP_LIBS}
+#unset LD_LIBRARY_PATH
+
+
+if test "x$gmp_found" != "xyes"; then
+	if test -n "$gmp_problem"; then
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: problem" >&5
+$as_echo "problem" >&6; }
+		echo "Sorry, your GMP version is too old. Disabling."
+	elif test "x$gmp_found" != "xno"; then
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5
+$as_echo "not found" >&6; }
+	fi
+	as_fn_error $? "Unable to find GMP on your machine: please use --with-gmp=PATH_TO_DIR_CONTAINING_LIB_AND_INCLUDE (see also ./configure --help if you do not understand what we are talking about)" "$LINENO" 5
+fi
+
+ if test "x$HAVE_GMP" = "xyes"; then
+  SING_HAVE_GMP_TRUE=
+  SING_HAVE_GMP_FALSE='#'
+else
+  SING_HAVE_GMP_TRUE='#'
+  SING_HAVE_GMP_FALSE=
+fi
+
+
+
+DEFAULT_CHECKING_PATH="/usr /usr/local /sw /opt/local"
+
+
+# Check whether --with-ntl was given.
+if test "${with_ntl+set}" = set; then :
+  withval=$with_ntl; if test "$withval" = yes ; then
+			NTL_HOME_PATH="${DEFAULT_CHECKING_PATH}"
+	      elif test "$withval" != no ; then
+			NTL_HOME_PATH="$withval"
+	     fi
+else
+  NTL_HOME_PATH="${DEFAULT_CHECKING_PATH}"
+fi
+
+
+min_ntl_version=5.0
+
+
+BACKUP_CXXFLAGS=${CXXFLAGS}
+BACKUP_CFLAGS=${CFLAGS}
+BACKUP_LIBS=${LIBS}
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+if test -n "$NTL_HOME_PATH"; then
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for NTL >= $min_ntl_version" >&5
+$as_echo_n "checking for NTL >= $min_ntl_version... " >&6; }
+fi
+
+for NTL_HOME in ${NTL_HOME_PATH}
+ do
+if test -r "$NTL_HOME/include/NTL/ZZ.h"; then
+
+	if test "x$NTL_HOME" != "x/usr"; then
+		NTL_CFLAGS="-I${NTL_HOME}/include"
+		NTL_LIBS="-L${NTL_HOME}/lib -lntl"
+	else
+		NTL_CFLAGS=
+		NTL_LIBS="-lntl"
+	fi
+###	CFLAGS="${BACKUP_CFLAGS} ${NTL_CFLAGS} ${GMP_CFLAGS}"
+	CXXFLAGS="${BACKUP_CFLAGS} ${BACKUP_CXXFLAGS} ${NTL_CFLAGS} ${GMP_CFLAGS}"
+	LIBS="${BACKUP_LIBS} ${NTL_LIBS} ${GMP_LIBS}"
+
+	cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <NTL/ZZ.h>
+int
+main ()
+{
+NTL::ZZ a;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+
+	if test "$cross_compiling" = yes; then :
+
+	ntl_found="yes"
+	ntl_cross="yes"
+	break
+
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <NTL/version.h>
+	#include <NTL/config.h>
+	#ifndef NTL_GMP_LIP
+	int main() {return -1;}
+	#else
+	int main () { if (NTL_MAJOR_VERSION < 5) return -1; else return 0;}
+	#endif
+
+_ACEOF
+if ac_fn_cxx_try_run "$LINENO"; then :
+
+	ntl_found="yes"
+	break
+
+else
+
+	ntl_problem="$problem $NTL_HOME"
+	unset NTL_CFLAGS
+	unset NTL_LIBS
+
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+
+else
+
+	ntl_found="no"
+	ntl_checked="$checked $NTL_HOME"
+	unset NTL_CFLAGS
+	unset NTL_LIBS
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+else
+	ntl_found="no"
+fi
+done
+
+if test "x$ntl_found" = "xyes" ; then
+
+
+
+$as_echo "#define HAVE_NTL 1" >>confdefs.h
+
+	HAVE_NTL=yes
+	if test "x$ntl_cross" != "xyes"; then
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: found" >&5
+$as_echo "found" >&6; }
+	else
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: unknown" >&5
+$as_echo "unknown" >&6; }
+		echo "WARNING: You appear to be cross compiling, so there is no way to determine"
+		echo "whether your NTL version is new enough. I am assuming it is."
+	fi
+	:
+elif test -n "$ntl_problem"; then
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: problem" >&5
+$as_echo "problem" >&6; }
+	echo "Sorry, your NTL version is too old or not configured with NTL_GMP_LIP=on. Disabling."
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to find NTL (which is strongly recommended) on your machine: please use --with-ntl=PATH_TO_DIR_CONTAINING_LIB_AND_INCLUDE (see also ./configure --help if you do not understand what we are talking about)" >&5
+$as_echo "$as_me: WARNING: Unable to find NTL (which is strongly recommended) on your machine: please use --with-ntl=PATH_TO_DIR_CONTAINING_LIB_AND_INCLUDE (see also ./configure --help if you do not understand what we are talking about)" >&2;}
+elif test   "x$ntl_found" = "xno";  then
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5
+$as_echo "not found" >&6; }
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to find NTL (which is strongly recommended) on your machine: please use --with-ntl=PATH_TO_DIR_CONTAINING_LIB_AND_INCLUDE (see also ./configure --help if you do not understand what we are talking about)" >&5
+$as_echo "$as_me: WARNING: Unable to find NTL (which is strongly recommended) on your machine: please use --with-ntl=PATH_TO_DIR_CONTAINING_LIB_AND_INCLUDE (see also ./configure --help if you do not understand what we are talking about)" >&2;}
+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 "x$HAVE_NTL" = "xyes"; then
+  SING_HAVE_NTL_TRUE=
+  SING_HAVE_NTL_FALSE='#'
+else
+  SING_HAVE_NTL_TRUE='#'
+  SING_HAVE_NTL_FALSE=
+fi
+
+
+# TODO: The following seems to set CXXFLAGS even if it was not defined previously!!!!
+CXXFLAGS=${BACKUP_CXXFLAGS}
+LIBS=${BACKUP_LIBS}
+#unset LD_LIBRARY_PATH
+
+
+
+DEFAULT_CHECKING_PATH="/usr /usr/local /sw /opt/local"
+
+
+# Check whether --with-flint was given.
+if test "${with_flint+set}" = set; then :
+  withval=$with_flint; if test "$withval" = yes ; then
+			FLINT_HOME_PATH="${DEFAULT_CHECKING_PATH}"
+	      elif test "$withval" != no ; then
+			FLINT_HOME_PATH="$withval"
+	     fi
+else
+  FLINT_HOME_PATH="${DEFAULT_CHECKING_PATH}"
+fi
+
+
+min_flint_version=2.3
+
+
+BACKUP_CFLAGS=${CFLAGS}
+BACKUP_LIBS=${LIBS}
+
+if test -n "$FLINT_HOME_PATH"; then
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for FLINT >= $min_flint_version" >&5
+$as_echo_n "checking for FLINT >= $min_flint_version... " >&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
+
+
+for FLINT_HOME in ${FLINT_HOME_PATH}
+ do
+## if test -r "$FLINT_HOME/include/flint/fmpz.h"; then
+
+	if test "x$FLINT_HOME" != "x/usr"; then
+		FLINT_CFLAGS="-I${FLINT_HOME}/include/"
+		FLINT_LIBS="-L${FLINT_HOME}/lib"
+	else
+		FLINT_CFLAGS=""
+		FLINT_LIBS=""
+	fi
+
+	# we suppose that mpfr and mpir to be in the same place or available by default
+	FLINT_LIBS="$FLINT_LIBS -lflint -lmpfr"
+
+	CFLAGS="${BACKUP_CFLAGS} ${FLINT_CFLAGS} ${GMP_CFLAGS}"
+	LIBS="${BACKUP_LIBS} ${FLINT_LIBS} ${GMP_LIBS}"
+
+	cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <flint/fmpz.h>
+int
+main ()
+{
+fmpz_t a; fmpz_init (a);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+	if test "$cross_compiling" = yes; then :
+
+	flint_found="yes"
+	flint_cross="yes"
+	break
+
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <flint/flint.h>
+	int main () { if ((int) version[0] < 2) return -1; else return 0; }
+
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+	flint_found="yes"
+	break
+
+else
+
+	flint_problem="$problem $FLINT_HOME"
+	unset FLINT_CFLAGS
+	unset FLINT_LIBS
+
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+
+else
+
+	flint_found="no"
+	flint_checked="$checked $FLINT_HOME"
+	unset FLINT_CFLAGS
+	unset FLINT_LIBS
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+#else
+#	flint_found="no"
+#fi
+done
+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
+
+
+CFLAGS=${BACKUP_CFLAGS}
+LIBS=${BACKUP_LIBS}
+#unset LD_LIBRARY_PATH
+
+
+if test "x$flint_found" = "xyes" ; then
+
+
+
+
+$as_echo "#define HAVE_FLINT 1" >>confdefs.h
+
+	HAVE_FLINT=yes
+	if test "x$flint_cross" != "xyes"; then
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: found" >&5
+$as_echo "found" >&6; }
+	else
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: unknown" >&5
+$as_echo "unknown" >&6; }
+		echo "WARNING: You appear to be cross compiling, so there is no way to determine"
+		echo "whether your FLINT version is new enough. I am assuming it is."
+	fi
+	:
+elif test -n "$flint_problem"; then
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: problem" >&5
+$as_echo "problem" >&6; }
+	echo "Sorry, your FLINT version is too old. Disabling."
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to find FLINT (which is strongly recommended) on your machine: please use --with-flint=PATH_TO_DIR_CONTAINING_LIB_AND_INCLUDE (see also ./configure --help if you do not understand what we are talking about)" >&5
+$as_echo "$as_me: WARNING: Unable to find FLINT (which is strongly recommended) on your machine: please use --with-flint=PATH_TO_DIR_CONTAINING_LIB_AND_INCLUDE (see also ./configure --help if you do not understand what we are talking about)" >&2;}
+elif test   "x$flint_found" = "xno";  then
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5
+$as_echo "not found" >&6; }
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to find FLINT (which is strongly recommended) on your machine: please use --with-flint=PATH_TO_DIR_CONTAINING_LIB_AND_INCLUDE (see also ./configure --help if you do not understand what we are talking about)" >&5
+$as_echo "$as_me: WARNING: Unable to find FLINT (which is strongly recommended) on your machine: please use --with-flint=PATH_TO_DIR_CONTAINING_LIB_AND_INCLUDE (see also ./configure --help if you do not understand what we are talking about)" >&2;}
+fi
+
+ if test "x$HAVE_FLINT" = "xyes"; then
+  SING_HAVE_FLINT_TRUE=
+  SING_HAVE_FLINT_FALSE='#'
+else
+  SING_HAVE_FLINT_TRUE='#'
+  SING_HAVE_FLINT_FALSE=
+fi
+
+
+
+
+# Checks for library functions.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for error_at_line" >&5
+$as_echo_n "checking for error_at_line... " >&6; }
+if ${ac_cv_lib_error_at_line+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <error.h>
+int
+main ()
+{
+error_at_line (0, 0, "", 0, "an error occurred");
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_error_at_line=yes
+else
+  ac_cv_lib_error_at_line=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_error_at_line" >&5
+$as_echo "$ac_cv_lib_error_at_line" >&6; }
+if test $ac_cv_lib_error_at_line = no; then
+  case " $LIBOBJS " in
+  *" error.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS error.$ac_objext"
+ ;;
+esac
+
+fi
+
+for ac_func in memmove memset pow sqrt strchr setenv putenv
+do :
+  as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in vprintf
+do :
+  ac_fn_c_check_func "$LINENO" "vprintf" "ac_cv_func_vprintf"
+if test "x$ac_cv_func_vprintf" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_VPRINTF 1
+_ACEOF
+
+ac_fn_c_check_func "$LINENO" "_doprnt" "ac_cv_func__doprnt"
+if test "x$ac_cv_func__doprnt" = xyes; then :
+
+$as_echo "#define HAVE_DOPRNT 1" >>confdefs.h
+
+fi
+
+fi
+done
+
+
+for ac_header in stdlib.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "stdlib.h" "ac_cv_header_stdlib_h" "$ac_includes_default"
+if test "x$ac_cv_header_stdlib_h" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_STDLIB_H 1
+_ACEOF
+
+fi
+
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU libc compatible malloc" >&5
+$as_echo_n "checking for GNU libc compatible malloc... " >&6; }
+if ${ac_cv_func_malloc_0_nonnull+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test "$cross_compiling" = yes; then :
+  ac_cv_func_malloc_0_nonnull=no
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#if defined STDC_HEADERS || defined HAVE_STDLIB_H
+# include <stdlib.h>
+#else
+char *malloc ();
+#endif
+
+int
+main ()
+{
+return ! malloc (0);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  ac_cv_func_malloc_0_nonnull=yes
+else
+  ac_cv_func_malloc_0_nonnull=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
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_malloc_0_nonnull" >&5
+$as_echo "$ac_cv_func_malloc_0_nonnull" >&6; }
+if test $ac_cv_func_malloc_0_nonnull = yes; then :
+
+$as_echo "#define HAVE_MALLOC 1" >>confdefs.h
+
+else
+  $as_echo "#define HAVE_MALLOC 0" >>confdefs.h
+
+   case " $LIBOBJS " in
+  *" malloc.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS malloc.$ac_objext"
+ ;;
+esac
+
+
+$as_echo "#define malloc rpl_malloc" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_func "$LINENO" "vsnprintf" "ac_cv_func_vsnprintf"
+if test "x$ac_cv_func_vsnprintf" = xyes; then :
+
+$as_echo "#define HAVE_VSNPRINTF 1" >>confdefs.h
+
+fi
+
+
+# Checks for header files.
+{ $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 ${ac_cv_header_stdc+:} false; 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
+
+{ $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 ${ac_cv_header_stdc+:} false; 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
+
+for ac_header in stdlib.h string.h unistd.h pwd.h sys/param.h limits.h float.h execinfo.h
+do :
+  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+# If the compiler supports GCC C++ ABI name demangling (has header
+#   cxxabi.h and abi::__cxa_demangle() function), define
+#   HAVE_GCC_ABI_DEMANGLE
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports GCC C++ ABI name demangling" >&5
+$as_echo_n "checking whether the compiler supports GCC C++ ABI name demangling... " >&6; }
+if ${ax_cv_cxx_gcc_abi_demangle+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <typeinfo>
+#include <cxxabi.h>
+#include <string>
+
+template<typename TYPE>
+class A {};
+
+int
+main ()
+{
+A<int> instance;
+int status = 0;
+char* c_name = 0;
+
+c_name = abi::__cxa_demangle(typeid(instance).name(), 0, 0, &status);
+
+std::string name(c_name);
+free(c_name);
+
+return name == "A<int>";
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ax_cv_cxx_gcc_abi_demangle=yes
+else
+  ax_cv_cxx_gcc_abi_demangle=no
+fi
+rm -f core conftest.err conftest.$ac_objext 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: $ax_cv_cxx_gcc_abi_demangle" >&5
+$as_echo "$ax_cv_cxx_gcc_abi_demangle" >&6; }
+if test "$ax_cv_cxx_gcc_abi_demangle" = yes; then
+
+$as_echo "#define HAVE_GCC_ABI_DEMANGLE 1" >>confdefs.h
+
+fi
+
+
+# Checks for typedefs, structures, and compiler characteristics.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5
+$as_echo_n "checking for an ANSI C-conforming const... " >&6; }
+if ${ac_cv_c_const+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+#ifndef __cplusplus
+  /* Ultrix mips cc rejects this sort of thing.  */
+  typedef int charset[2];
+  const charset cs = { 0, 0 };
+  /* SunOS 4.1.1 cc rejects this.  */
+  char const *const *pcpcc;
+  char **ppc;
+  /* NEC SVR4.0.2 mips cc rejects this.  */
+  struct point {int x, y;};
+  static struct point const zero = {0,0};
+  /* AIX XL C 1.02.0.0 rejects this.
+     It does not let you subtract one const X* pointer from another in
+     an arm of an if-expression whose if-part is not a constant
+     expression */
+  const char *g = "string";
+  pcpcc = &g + (g ? g-g : 0);
+  /* HPUX 7.0 cc rejects these. */
+  ++pcpcc;
+  ppc = (char**) pcpcc;
+  pcpcc = (char const *const *) ppc;
+  { /* SCO 3.2v4 cc rejects this sort of thing.  */
+    char tx;
+    char *t = &tx;
+    char const *s = 0 ? (char *) 0 : (char const *) 0;
+
+    *t++ = 0;
+    if (s) return 0;
+  }
+  { /* Someone thinks the Sun supposedly-ANSI compiler will reject this.  */
+    int x[] = {25, 17};
+    const int *foo = &x[0];
+    ++foo;
+  }
+  { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
+    typedef const int *iptr;
+    iptr p = 0;
+    ++p;
+  }
+  { /* AIX XL C 1.02.0.0 rejects this sort of thing, saying
+       "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
+    struct s { int j; const int *ap[3]; } bx;
+    struct s *b = &bx; b->j = 5;
+  }
+  { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
+    const int foo = 10;
+    if (!foo) return 0;
+  }
+  return !cs[0] && !zero.x;
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_c_const=yes
+else
+  ac_cv_c_const=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5
+$as_echo "$ac_cv_c_const" >&6; }
+if test $ac_cv_c_const = no; then
+
+$as_echo "#define const /**/" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5
+$as_echo_n "checking for inline... " >&6; }
+if ${ac_cv_c_inline+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_cv_c_inline=no
+for ac_kw in inline __inline__ __inline; do
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifndef __cplusplus
+typedef int foo_t;
+static $ac_kw foo_t static_foo () {return 0; }
+$ac_kw foo_t foo () {return 0; }
+#endif
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_c_inline=$ac_kw
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  test "$ac_cv_c_inline" != no && break
+done
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5
+$as_echo "$ac_cv_c_inline" >&6; }
+
+case $ac_cv_c_inline in
+  inline | yes) ;;
+  *)
+    case $ac_cv_c_inline in
+      no) ac_val=;;
+      *) ac_val=$ac_cv_c_inline;;
+    esac
+    cat >>confdefs.h <<_ACEOF
+#ifndef __cplusplus
+#define inline $ac_val
+#endif
+_ACEOF
+    ;;
+esac
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdbool.h that conforms to C99" >&5
+$as_echo_n "checking for stdbool.h that conforms to C99... " >&6; }
+if ${ac_cv_header_stdbool_h+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+             #include <stdbool.h>
+             #ifndef bool
+              "error: bool is not defined"
+             #endif
+             #ifndef false
+              "error: false is not defined"
+             #endif
+             #if false
+              "error: false is not 0"
+             #endif
+             #ifndef true
+              "error: true is not defined"
+             #endif
+             #if true != 1
+              "error: true is not 1"
+             #endif
+             #ifndef __bool_true_false_are_defined
+              "error: __bool_true_false_are_defined is not defined"
+             #endif
+
+             struct s { _Bool s: 1; _Bool t; } s;
+
+             char a[true == 1 ? 1 : -1];
+             char b[false == 0 ? 1 : -1];
+             char c[__bool_true_false_are_defined == 1 ? 1 : -1];
+             char d[(bool) 0.5 == true ? 1 : -1];
+             /* See body of main program for 'e'.  */
+             char f[(_Bool) 0.0 == false ? 1 : -1];
+             char g[true];
+             char h[sizeof (_Bool)];
+             char i[sizeof s.t];
+             enum { j = false, k = true, l = false * true, m = true * 256 };
+             /* The following fails for
+                HP aC++/ANSI C B3910B A.05.55 [Dec 04 2003]. */
+             _Bool n[m];
+             char o[sizeof n == m * sizeof n[0] ? 1 : -1];
+             char p[-1 - (_Bool) 0 < 0 && -1 - (bool) 0 < 0 ? 1 : -1];
+             /* Catch a bug in an HP-UX C compiler.  See
+                http://gcc.gnu.org/ml/gcc-patches/2003-12/msg02303.html
+                http://lists.gnu.org/archive/html/bug-coreutils/2005-11/msg00161.html
+              */
+             _Bool q = true;
+             _Bool *pq = &q;
+
+int
+main ()
+{
+
+             bool e = &s;
+             *pq |= q;
+             *pq |= ! q;
+             /* Refer to every declared value, to avoid compiler optimizations.  */
+             return (!a + !b + !c + !d + !e + !f + !g + !h + !i + !!j + !k + !!l
+                     + !m + !n + !o + !p + !q + !pq);
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_header_stdbool_h=yes
+else
+  ac_cv_header_stdbool_h=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdbool_h" >&5
+$as_echo "$ac_cv_header_stdbool_h" >&6; }
+   ac_fn_c_check_type "$LINENO" "_Bool" "ac_cv_type__Bool" "$ac_includes_default"
+if test "x$ac_cv_type__Bool" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE__BOOL 1
+_ACEOF
+
+
+fi
+
+
+if test $ac_cv_header_stdbool_h = yes; then
+
+$as_echo "#define HAVE_STDBOOL_H 1" >>confdefs.h
+
+fi
+
+ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default"
+if test "x$ac_cv_type_size_t" = xyes; then :
+
+else
+
+cat >>confdefs.h <<_ACEOF
+#define size_t unsigned int
+_ACEOF
+
+fi
+
+
+# SING_CHECK_PIPE
+
+# check for cpu properties
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long" >&5
+$as_echo_n "checking size of long... " >&6; }
+if ${ac_cv_sizeof_long+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long))" "ac_cv_sizeof_long"        "$ac_includes_default"; then :
+
+else
+  if test "$ac_cv_type_long" = yes; then
+     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (long)
+See \`config.log' for more details" "$LINENO" 5; }
+   else
+     ac_cv_sizeof_long=0
+   fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long" >&5
+$as_echo "$ac_cv_sizeof_long" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_LONG $ac_cv_sizeof_long
+_ACEOF
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking CPU for singular" >&5
+$as_echo_n "checking CPU for singular... " >&6; }
+
+# CPUUNAME and PATH
+ac_cv_singcpuname=`uname -m`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_singcpuname" >&5
+$as_echo "$ac_cv_singcpuname" >&6; }
+
+if test "$ac_cv_singcpuname" = i386; then
+
+$as_echo "#define SI_CPU_I386 1" >>confdefs.h
+
+
+fi
+if test "$ac_cv_singcpuname" = i686; then
+
+$as_echo "#define SI_CPU_I386 1" >>confdefs.h
+
+
+fi
+if test "$ac_cv_singcpuname" = x86_64; then
+
+$as_echo "#define SI_CPU_X86_64 1" >>confdefs.h
+
+
+fi
+if test "$ac_cv_singcpuname" = ia64; then
+
+$as_echo "#define SI_CPU_IA64 1" >>confdefs.h
+
+
+fi
+if test "$ac_cv_singcpuname" = sparc; then
+
+$as_echo "#define SI_CPU_SPARC 1" >>confdefs.h
+
+
+fi
+if test "$ac_cv_singcpuname" = ppc; then
+
+$as_echo "#define SI_CPU_PPC 1" >>confdefs.h
+
+
+fi
+
+# UNAME and PATH
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking uname for Singular" >&5
+$as_echo_n "checking uname for Singular... " >&6; }
+
+#ac_cv_singuname=`./config.guess`
+ac_cv_singuname=`uname -m`-`uname -s`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_singuname" >&5
+$as_echo "$ac_cv_singuname" >&6; }
+
+cat >>confdefs.h <<_ACEOF
+#define S_UNAME "$ac_cv_singuname"
+_ACEOF
+
+
+
+case $host_cpu in #(
+    i*86*|x86_64*) :
+
+$as_echo "#define HAVE_MULT_MOD 1" >>confdefs.h
+ ;; #(
+    ia64*) :
+
+$as_echo "#define HAVE_GENERIC_ADD 1" >>confdefs.h
+ ;; #(
+    sparc*) :
+
+
+$as_echo "#define HAVE_MULT_MOD 1" >>confdefs.h
+
+
+$as_echo "#define HAVE_DIV_MOD 1" >>confdefs.h
+
+	     ;; #(
+    powerpc*|ppc*) :
+
+$as_echo "#define HAVE_MULT_MOD 1" >>confdefs.h
+ ;; #(
+  *) :
+
+ ;;
+esac
+
+
+
+#check for host:
+
+
+case $host_os in
+  *cygwin* )
+
+for flag in -Wl,-Bdynamic; do
+  as_CACHEVAR=`$as_echo "ax_cv_check_ldflags__$flag" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the linker accepts $flag" >&5
+$as_echo_n "checking whether the linker accepts $flag... " >&6; }
+if eval \${$as_CACHEVAR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$LDFLAGS
+  LDFLAGS="$LDFLAGS  $flag"
+  _save_cflags="$CFLAGS"
+  CFLAGS="$CFLAGS -Werror"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "$as_CACHEVAR=yes"
+else
+  eval "$as_CACHEVAR=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+  CFLAGS="$_save_cflags"
+  LDFLAGS=$ax_check_save_flags
+fi
+eval ac_res=\$$as_CACHEVAR
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if test x"`eval 'as_val=${'$as_CACHEVAR'};$as_echo "$as_val"'`" = xyes; then :
+  if ${LDFLAGS+:} false; then :
+  case " $LDFLAGS " in
+    *" $flag "*)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : LDFLAGS already contains \$flag"; } >&5
+  (: LDFLAGS already contains $flag) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      ;;
+    *)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : LDFLAGS=\"\$LDFLAGS \$flag\""; } >&5
+  (: LDFLAGS="$LDFLAGS $flag") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      LDFLAGS="$LDFLAGS $flag"
+      ;;
+   esac
+else
+  LDFLAGS="$flag"
+fi
+
+else
+  :
+fi
+
+done
+;;
+esac
+
+
+
+  # Check whether --enable-omalloc was given.
+if test "${enable_omalloc+set}" = set; then :
+  enableval=$enable_omalloc; if test "x$enableval" = "xyes"; then
+      ENABLE_OMALLOC=yes
+    fi
+else
+  ENABLE_OMALLOC=no
+fi
+
+
+
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use omalloc" >&5
+$as_echo_n "checking whether to use omalloc... " >&6; }
+
+
+
+  if test "x$ENABLE_OMALLOC" = xyes; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking   OMALLOC_INCLUDES?.." >&5
+$as_echo_n "checking   OMALLOC_INCLUDES?..... " >&6; }
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${OMALLOC_INCLUDES:-unset}" >&5
+$as_echo "${OMALLOC_INCLUDES:-unset}" >&6; }
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking   OMALLOC_LIBS?.." >&5
+$as_echo_n "checking   OMALLOC_LIBS?..... " >&6; }
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${OMALLOC_LIBS:-unset}" >&5
+$as_echo "${OMALLOC_LIBS:-unset}" >&6; }
+
+    CPPFLAGS_save="$CPPFLAGS"
+    CFLAGS_save="$CFLAGS"
+    LIBS_save="$LIBS"
+
+    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
+
+#
+    CPPFLAGS="$CPPFLAGS ${OMALLOC_INCLUDES}"
+    CFLAGS="$CFLAGS ${OMALLOC_INCLUDES}"
+    LIBS="$LIBS ${OMALLOC_LIBS}"
+
+    for ac_header in omalloc/omalloc.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "omalloc/omalloc.h" "ac_cv_header_omalloc_omalloc_h" "$ac_includes_default"
+if test "x$ac_cv_header_omalloc_omalloc_h" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_OMALLOC_OMALLOC_H 1
+_ACEOF
+
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: trusting the omalloc locations given: ${OMALLOC_INCLUDES}" >&5
+$as_echo "$as_me: WARNING: trusting the omalloc locations given: ${OMALLOC_INCLUDES}" >&2;}
+fi
+
+done
+
+
+    CFLAGS="$CFLAGS_save"
+    CPPFLAGS="$CPPFLAGS_save"
+    LIBS="$LIBS_save"
+#
+    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 "#define HAVE_OMALLOC 1" >>confdefs.h
+
+
+    PKG_REQUIRE="$PKG_REQUIRE omalloc"
+
+  else
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+  fi
+
+   if test "x$ENABLE_OMALLOC" = xyes; then
+  ENABLE_OMALLOC_TRUE=
+  ENABLE_OMALLOC_FALSE='#'
+else
+  ENABLE_OMALLOC_TRUE='#'
+  ENABLE_OMALLOC_FALSE=
+fi
+
+
+
+ENABLE_RESOURCES="yes"
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether libresources should be used" >&5
+$as_echo_n "checking whether libresources should be used... " >&6; }
+
+if test "x$ENABLE_RESOURCES" = xyes;
+then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking   RESOURCES_INCLUDES?.." >&5
+$as_echo_n "checking   RESOURCES_INCLUDES?..... " >&6; }
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${RESOURCES_INCLUDES:-unset}" >&5
+$as_echo "${RESOURCES_INCLUDES:-unset}" >&6; }
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking   RESOURCES_LIBS?.." >&5
+$as_echo_n "checking   RESOURCES_LIBS?..... " >&6; }
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${RESOURCES_LIBS:-unset}" >&5
+$as_echo "${RESOURCES_LIBS:-unset}" >&6; }
+
+  PKG_REQUIRE="$PKG_REQUIRE resources"
+
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ENABLE_RESOURCES" = xyes; then
+  ENABLE_RESOURCES_TRUE=
+  ENABLE_RESOURCES_FALSE='#'
+else
+  ENABLE_RESOURCES_TRUE='#'
+  ENABLE_RESOURCES_FALSE=
+fi
+
+
+
+
+# Check whether --enable-factory was given.
+if test "${enable_factory+set}" = set; then :
+  enableval=$enable_factory; if test $enableval = yes; then
+     ENABLE_FACTORY="yes"
+ else
+     ENABLE_FACTORY="no"
+ fi
+
+else
+  ENABLE_FACTORY="yes"
+fi
+
+
+
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether factory should be enabled" >&5
+$as_echo_n "checking whether factory should be enabled... " >&6; }
+  if test "x$ENABLE_FACTORY" = xyes; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking   FACTORY_INCLUDES?.." >&5
+$as_echo_n "checking   FACTORY_INCLUDES?..... " >&6; }
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${FACTORY_INCLUDES:-unset}" >&5
+$as_echo "${FACTORY_INCLUDES:-unset}" >&6; }
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking   FACTORY_LIBS?.." >&5
+$as_echo_n "checking   FACTORY_LIBS?..... " >&6; }
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${FACTORY_LIBS:-unset}" >&5
+$as_echo "${FACTORY_LIBS:-unset}" >&6; }
+
+
+    CPPFLAGS_save="$CPPFLAGS"
+    CFLAGS_save="$CFLAGS"
+    CXXFLAGS_save="$CXXFLAGS"
+    LIBS_save="$LIBS"
+
+    ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+#
+    CPPFLAGS="$CPPFLAGS ${FACTORY_INCLUDES}"
+    CFLAGS="$CFLAGS ${FACTORY_INCLUDES}"
+    CXXFLAGS="$CXXFLAGS ${FACTORY_INCLUDES}"
+    LIBS="${FACTORY_LIBS} $LIBS"
+
+    for ac_header in factory/factory.h
+do :
+  ac_fn_cxx_check_header_mongrel "$LINENO" "factory/factory.h" "ac_cv_header_factory_factory_h" "$ac_includes_default"
+if test "x$ac_cv_header_factory_factory_h" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_FACTORY_FACTORY_H 1
+_ACEOF
+
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: trusting the factory locations given: ${FACTORY_INCLUDES}" >&5
+$as_echo "$as_me: WARNING: trusting the factory locations given: ${FACTORY_INCLUDES}" >&2;}
+fi
+
+done
+
+
+    CFLAGS="$CFLAGS_save"
+    CXXFLAGS="$CXXFLAGS_save"
+    CPPFLAGS="$CPPFLAGS_save"
+    LIBS="$LIBS_save"
+#
+    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 "#define HAVE_FACTORY 1" >>confdefs.h
+
+
+    PKG_REQUIRE="$PKG_REQUIRE factory"
+
+  else
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+  fi
+
+   if test x$ENABLE_FACTORY = xyes; then
+  ENABLE_FACTORY_TRUE=
+  ENABLE_FACTORY_FALSE='#'
+else
+  ENABLE_FACTORY_TRUE='#'
+  ENABLE_FACTORY_FALSE=
+fi
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ENABLE_FACTORY" >&5
+$as_echo "$ENABLE_FACTORY" >&6; }
+
+
+
+
+USEPPROCSDYNAMICLDFLAGS=""
+USEPPROCSDYNAMICLD=""
+
+# Check whether --enable-p-procs-static was given.
+if test "${enable_p_procs_static+set}" = set; then :
+  enableval=$enable_p_procs_static; if test $enableval = yes; then
+     ENABLE_P_PROCS_STATIC="yes"
+     ENABLE_P_PROCS_DYNAMIC="no"
+ else
+     ENABLE_P_PROCS_STATIC="no"
+ fi
+
+else
+  NO_P_PROCS_STATIC_GIVEN=yes
+fi
+
+
+# Check whether --enable-p-procs-dynamic was given.
+if test "${enable_p_procs_dynamic+set}" = set; then :
+  enableval=$enable_p_procs_dynamic; if test $enableval = yes; then
+     ENABLE_P_PROCS_DYNAMIC="yes"
+     ENABLE_P_PROCS_STATIC="no"
+ else
+     ENABLE_P_PROCS_DYNAMIC="no"
+ fi
+
+else
+  NO_P_PROCS_DYNAMIC_GIVEN=yes
+fi
+
+
+if test x$ENABLE_P_PROCS_DYNAMIC = xyes; then
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether system supports dynamic modules" >&5
+$as_echo_n "checking whether system supports dynamic modules... " >&6; }
+case $host in #(
+  *linux*) :
+    SUPPORTS_DYNAMIC_MODULES=yes ;; #(
+  *freebsd*) :
+    SUPPORTS_DYNAMIC_MODULES=yes ;; #(
+  *-sun-solaris2*) :
+    SUPPORTS_DYNAMIC_MODULES=yes ;; #(
+  *-apple-darwin*) :
+    SUPPORTS_DYNAMIC_MODULES=yes ;; #(
+  *) :
+    SUPPORTS_DYNAMIC_MODULES=no
+ ;;
+esac
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $SUPPORTS_DYNAMIC_MODULES" >&5
+$as_echo "$SUPPORTS_DYNAMIC_MODULES" >&6; }
+
+  if test $SUPPORTS_DYNAMIC_MODULES = no; then
+    as_fn_error $? "--enable-pprocs-dynamic requested but your system appears not to support dynamic modules properly" "$LINENO" 5
+  fi
+
+  ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen"
+if test "x$ac_cv_func_dlopen" = xyes; then :
+
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
+$as_echo_n "checking for dlopen in -ldl... " >&6; }
+if ${ac_cv_lib_dl_dlopen+:} false; 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" = xyes; then :
+  USEPPROCSDYNAMICLD="-ldl"
+else
+
+   { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Could not use dlopen" >&5
+$as_echo "$as_me: WARNING: Could not use dlopen" >&2;}
+
+fi
+
+fi
+
+
+elif test x$NO_P_PROCS_DYNAMIC_GIVEN = xyes -a x$NO_P_PROCS_STATIC_GIVEN = xyes; then
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether system supports dynamic modules" >&5
+$as_echo_n "checking whether system supports dynamic modules... " >&6; }
+case $host in #(
+  *linux*) :
+    SUPPORTS_DYNAMIC_MODULES=yes ;; #(
+  *freebsd*) :
+    SUPPORTS_DYNAMIC_MODULES=yes ;; #(
+  *-sun-solaris2*) :
+    SUPPORTS_DYNAMIC_MODULES=yes ;; #(
+  *-apple-darwin*) :
+    SUPPORTS_DYNAMIC_MODULES=yes ;; #(
+  *) :
+    SUPPORTS_DYNAMIC_MODULES=no
+ ;;
+esac
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $SUPPORTS_DYNAMIC_MODULES" >&5
+$as_echo "$SUPPORTS_DYNAMIC_MODULES" >&6; }
+
+  if test $SUPPORTS_DYNAMIC_MODULES = yes; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: Enabling dynamic modules and disabling static modules" >&5
+$as_echo "$as_me: Enabling dynamic modules and disabling static modules" >&6;}
+    ENABLE_P_PROCS_DYNAMIC="yes"
+    ENABLE_P_PROCS_STATIC="no"
+    USEPPROCSDYNAMICLDFLAGS=""
+    ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen"
+if test "x$ac_cv_func_dlopen" = xyes; then :
+
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
+$as_echo_n "checking for dlopen in -ldl... " >&6; }
+if ${ac_cv_lib_dl_dlopen+:} false; 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" = xyes; then :
+  USEPPROCSDYNAMICLD="-ldl"
+else
+
+      { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Could not use dlopen" >&5
+$as_echo "$as_me: WARNING: Could not use dlopen" >&2;}
+
+fi
+
+fi
+
+  elif test $SUPPORTS_DYNAMIC_MODULES = no; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: Enabling static modules and disabling dynamic modules" >&5
+$as_echo "$as_me: Enabling static modules and disabling dynamic modules" >&6;}
+    ENABLE_P_PROCS_DYNAMIC="no"
+    ENABLE_P_PROCS_STATIC="yes"
+  else
+    as_fn_error $? "Unknown whether system supports dynamic modules or not. This should not have happened." "$LINENO" 5
+  fi
+fi
+
+if test x$ENABLE_P_PROCS_DYNAMIC = xyes; then
+
+$as_echo "#define HAVE_DL 1" >>confdefs.h
+
+
+$as_echo "#define HAVE_DYNAMIC_LOADING 1" >>confdefs.h
+
+
+
+
+for flag in -rdynamic -flat_namespace -Wl,-bind_at_load -Wl,-undefined,dynamic_lookup; do
+  as_CACHEVAR=`$as_echo "ax_cv_check_ldflags__$flag" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the linker accepts $flag" >&5
+$as_echo_n "checking whether the linker accepts $flag... " >&6; }
+if eval \${$as_CACHEVAR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$LDFLAGS
+  LDFLAGS="$LDFLAGS  $flag"
+  _save_cflags="$CFLAGS"
+  CFLAGS="$CFLAGS -Werror"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "$as_CACHEVAR=yes"
+else
+  eval "$as_CACHEVAR=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+  CFLAGS="$_save_cflags"
+  LDFLAGS=$ax_check_save_flags
+fi
+eval ac_res=\$$as_CACHEVAR
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if test x"`eval 'as_val=${'$as_CACHEVAR'};$as_echo "$as_val"'`" = xyes; then :
+  if ${LDFLAGS+:} false; then :
+  case " $LDFLAGS " in
+    *" $flag "*)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : LDFLAGS already contains \$flag"; } >&5
+  (: LDFLAGS already contains $flag) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      ;;
+    *)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : LDFLAGS=\"\$LDFLAGS \$flag\""; } >&5
+  (: LDFLAGS="$LDFLAGS $flag") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      LDFLAGS="$LDFLAGS $flag"
+      ;;
+   esac
+else
+  LDFLAGS="$flag"
+fi
+
+else
+  :
+fi
+
+done
+
+fi
+
+
+
+
+ if test x$ENABLE_P_PROCS_DYNAMIC = xyes; then
+  ENABLE_P_PROCS_DYNAMIC_TRUE=
+  ENABLE_P_PROCS_DYNAMIC_FALSE='#'
+else
+  ENABLE_P_PROCS_DYNAMIC_TRUE='#'
+  ENABLE_P_PROCS_DYNAMIC_FALSE=
+fi
+
+ if test x$ENABLE_P_PROCS_STATIC = xyes; then
+  ENABLE_P_PROCS_STATIC_TRUE=
+  ENABLE_P_PROCS_STATIC_FALSE='#'
+else
+  ENABLE_P_PROCS_STATIC_TRUE='#'
+  ENABLE_P_PROCS_STATIC_FALSE=
+fi
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether arithmetical rings should be enabled" >&5
+$as_echo_n "checking whether arithmetical rings should be enabled... " >&6; }
+
+# Check whether --enable-arith-rings was given.
+if test "${enable_arith_rings+set}" = set; then :
+  enableval=$enable_arith_rings; if test $enableval = yes; then
+     ENABLE_RINGS="yes"
+ else
+     ENABLE_RINGS="no"
+ fi
+
+else
+  ENABLE_RINGS="yes"
+fi
+
+
+if test x$ENABLE_RINGS = xyes; then
+
+$as_echo "#define HAVE_RINGS 1" >>confdefs.h
+
+fi
+
+ if test x$ENABLE_RINGS = xyes; then
+  ENABLE_RINGS_TRUE=
+  ENABLE_RINGS_FALSE='#'
+else
+  ENABLE_RINGS_TRUE='#'
+  ENABLE_RINGS_FALSE=
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ENABLE_RINGS" >&5
+$as_echo "$ENABLE_RINGS" >&6; }
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether non-commutative subsystem should be enabled" >&5
+$as_echo_n "checking whether non-commutative subsystem should be enabled... " >&6; }
+
+# Check whether --enable-plural was given.
+if test "${enable_plural+set}" = set; then :
+  enableval=$enable_plural; ENABLE_PLURAL="$enableval"
+else
+  ENABLE_PLURAL="yes"
+fi
+
+
+if test "x$ENABLE_PLURAL" != xno; then
+
+$as_echo "#define HAVE_PLURAL 1" >>confdefs.h
+
+  #TODO make a seperate switch
+
+$as_echo "#define HAVE_SHIFTBBA 1" >>confdefs.h
+
+fi
+
+ if test x$ENABLE_PLURAL != xno; then
+  ENABLE_PLURAL_TRUE=
+  ENABLE_PLURAL_FALSE='#'
+else
+  ENABLE_PLURAL_TRUE='#'
+  ENABLE_PLURAL_FALSE=
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ENABLE_PLURAL" >&5
+$as_echo "$ENABLE_PLURAL" >&6; }
+
+
+
+# Check whether --with-RatGB was given.
+if test "${with_RatGB+set}" = set; then :
+  withval=$with_RatGB;
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to have ratGB" >&5
+$as_echo_n "checking whether to have ratGB... " >&6; }
+if test "x$with_ratGB" != xyes && test "x$enable_ratGB" != xyes; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+else
+
+$as_echo "#define HAVE_RATGRING 1" >>confdefs.h
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+fi
+
+
+
+
+# AC_SUBST(PREFIX)
+# AC_DEFINE_UNQUOTED(INSTALL_PREFIX,"$PREFIX",Prefix)
+
+
+$as_echo "#define SINGULAR 1" >>confdefs.h
+
+
+$as_echo "#define DISABLE_GMP_CPP 1" >>confdefs.h
+
+
+$as_echo "#define NOSTREAMIO 1" >>confdefs.h
+
+
+# AX_PYTHON_DEFAULT()
+# AX_PYTHON_WITH_VERSION([2.4])
+
+
+cat >>confdefs.h <<_ACEOF
+#define NTL_CFLAGS "$NTL_CFLAGS"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define NTL_LIBS "$NTL_LIBS"
+_ACEOF
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define GMP_CFLAGS "$GMP_CFLAGS"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define GMP_LIBS "$GMP_LIBS"
+_ACEOF
+
+
+# AC_DEFINE_UNQUOTED([FLINT_CFLAGS],"$FLINT_CFLAGS",[FLINT_CFLAGS])
+# AC_DEFINE_UNQUOTED([FLINT_LIBS],"$FLINT_LIBS",[FLINT_LIBS])
+
+## AC_DEFINE([HAVE_POLYEXTENSIONS], [1], [Enable the algebraic & transcendental extensions])
+
+ac_config_files="$ac_config_files Makefile"
+
+ac_config_files="$ac_config_files misc/Makefile"
+
+ac_config_files="$ac_config_files reporter/Makefile"
+
+ac_config_files="$ac_config_files coeffs/Makefile"
+
+ac_config_files="$ac_config_files polys/Makefile"
+
+ac_config_files="$ac_config_files tests/Makefile"
+
+ac_config_files="$ac_config_files libpolys-config libpolys.pc misc/auxiliary.h"
+
+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
+    if test "x$cache_file" != "x/dev/null"; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
+$as_echo "$as_me: updating cache $cache_file" >&6;}
+      if test ! -f "$cache_file" || test -h "$cache_file"; then
+	cat confcache >"$cache_file"
+      else
+        case $cache_file in #(
+        */* | ?:*)
+	  mv -f confcache "$cache_file"$$ &&
+	  mv -f "$cache_file"$$ "$cache_file" ;; #(
+        *)
+	  mv -f confcache "$cache_file" ;;
+	esac
+      fi
+    fi
+  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=
+U=
+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 -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
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5
+$as_echo_n "checking that generated files are newer than configure... " >&6; }
+   if test -n "$am_sleep_pid"; then
+     # Hide warnings about reused PIDs.
+     wait $am_sleep_pid 2>/dev/null
+   fi
+   { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5
+$as_echo "done" >&6; }
+ if test -n "$EXEEXT"; then
+  am__EXEEXT_TRUE=
+  am__EXEEXT_FALSE='#'
+else
+  am__EXEEXT_TRUE='#'
+  am__EXEEXT_FALSE=
+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
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5
+$as_echo_n "checking that generated files are newer than configure... " >&6; }
+   if test -n "$am_sleep_pid"; then
+     # Hide warnings about reused PIDs.
+     wait $am_sleep_pid 2>/dev/null
+   fi
+   { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5
+$as_echo "done" >&6; }
+if test -z "${WANT_DEBUG_TRUE}" && test -z "${WANT_DEBUG_FALSE}"; then
+  as_fn_error $? "conditional \"WANT_DEBUG\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${WANT_OPTIMIZATIONFLAGS_TRUE}" && test -z "${WANT_OPTIMIZATIONFLAGS_FALSE}"; then
+  as_fn_error $? "conditional \"WANT_OPTIMIZATIONFLAGS\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then
+  as_fn_error $? "conditional \"am__fastdepCXX\" 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 "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then
+  as_fn_error $? "conditional \"am__fastdepCXX\" 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 "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then
+  as_fn_error $? "conditional \"am__fastdepCXX\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${SING_HAVE_GMP_TRUE}" && test -z "${SING_HAVE_GMP_FALSE}"; then
+  as_fn_error $? "conditional \"SING_HAVE_GMP\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${SING_HAVE_NTL_TRUE}" && test -z "${SING_HAVE_NTL_FALSE}"; then
+  as_fn_error $? "conditional \"SING_HAVE_NTL\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${SING_HAVE_FLINT_TRUE}" && test -z "${SING_HAVE_FLINT_FALSE}"; then
+  as_fn_error $? "conditional \"SING_HAVE_FLINT\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${ENABLE_OMALLOC_TRUE}" && test -z "${ENABLE_OMALLOC_FALSE}"; then
+  as_fn_error $? "conditional \"ENABLE_OMALLOC\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${ENABLE_RESOURCES_TRUE}" && test -z "${ENABLE_RESOURCES_FALSE}"; then
+  as_fn_error $? "conditional \"ENABLE_RESOURCES\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${ENABLE_FACTORY_TRUE}" && test -z "${ENABLE_FACTORY_FALSE}"; then
+  as_fn_error $? "conditional \"ENABLE_FACTORY\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${ENABLE_P_PROCS_DYNAMIC_TRUE}" && test -z "${ENABLE_P_PROCS_DYNAMIC_FALSE}"; then
+  as_fn_error $? "conditional \"ENABLE_P_PROCS_DYNAMIC\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${ENABLE_P_PROCS_STATIC_TRUE}" && test -z "${ENABLE_P_PROCS_STATIC_FALSE}"; then
+  as_fn_error $? "conditional \"ENABLE_P_PROCS_STATIC\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${ENABLE_RINGS_TRUE}" && test -z "${ENABLE_RINGS_FALSE}"; then
+  as_fn_error $? "conditional \"ENABLE_RINGS\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${ENABLE_PLURAL_TRUE}" && test -z "${ENABLE_PLURAL_FALSE}"; then
+  as_fn_error $? "conditional \"ENABLE_PLURAL\" 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.
+as_myself=
+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 STATUS 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=$1; test $as_status -eq 0 && as_status=1
+  if test "$4"; then
+    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+  fi
+  $as_echo "$as_me: error: $2" >&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 -pR'.
+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+      as_ln_s='cp -pR'
+  elif ln conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s=ln
+  else
+    as_ln_s='cp -pR'
+  fi
+else
+  as_ln_s='cp -pR'
+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
+
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+  test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
+
+# 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 libpolys $as_me 4.0.1, which was
+generated by GNU Autoconf 2.69.  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
+      --config     print configuration, 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_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
+ac_cs_version="\\
+libpolys config.status 4.0.1
+configured by $0, generated by GNU Autoconf 2.69,
+  with options \\"\$ac_cs_config\\"
+
+Copyright (C) 2012 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=`expr "X$1" : 'X\([^=]*\)='`
+    ac_optarg=
+    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 ;;
+  --config | --confi | --conf | --con | --co | --c )
+    $as_echo "$ac_cs_config"; 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"` ;;
+    '') as_fn_error $? "missing file argument" ;;
+    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"
+PACKAGE="$PACKAGE"
+
+
+# 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'
+macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`'
+macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`'
+enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`'
+enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`'
+pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`'
+enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`'
+SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`'
+ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`'
+PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`'
+host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`'
+host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`'
+host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`'
+build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`'
+build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`'
+build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`'
+SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`'
+Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`'
+GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`'
+EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`'
+FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`'
+LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`'
+NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`'
+LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`'
+max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`'
+ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`'
+exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`'
+lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`'
+lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`'
+lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`'
+lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`'
+lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`'
+reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`'
+reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`'
+OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`'
+deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`'
+file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`'
+file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`'
+want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`'
+DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`'
+sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`'
+AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`'
+AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`'
+archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`'
+STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`'
+RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`'
+old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`'
+old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`'
+old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`'
+lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`'
+CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`'
+CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`'
+compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`'
+GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`'
+nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`'
+lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`'
+objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`'
+MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`'
+lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`'
+need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`'
+MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`'
+DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`'
+NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`'
+LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`'
+OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`'
+OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`'
+libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`'
+shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`'
+extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`'
+archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`'
+enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`'
+export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`'
+whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`'
+compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`'
+old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`'
+old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`'
+archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`'
+archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`'
+module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`'
+module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`'
+with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`'
+allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`'
+no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`'
+hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`'
+hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`'
+hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`'
+hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`'
+hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`'
+inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`'
+link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`'
+always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`'
+export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`'
+exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`'
+include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`'
+prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`'
+postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`'
+file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`'
+variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`'
+need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`'
+need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`'
+version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`'
+runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`'
+shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`'
+shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`'
+libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`'
+library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`'
+soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`'
+install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`'
+postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`'
+postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`'
+finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`'
+finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`'
+hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`'
+sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`'
+sys_lib_dlsearch_path_spec='`$ECHO "$sys_lib_dlsearch_path_spec" | $SED "$delay_single_quote_subst"`'
+hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`'
+enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`'
+enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`'
+enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`'
+old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`'
+striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`'
+compiler_lib_search_dirs='`$ECHO "$compiler_lib_search_dirs" | $SED "$delay_single_quote_subst"`'
+predep_objects='`$ECHO "$predep_objects" | $SED "$delay_single_quote_subst"`'
+postdep_objects='`$ECHO "$postdep_objects" | $SED "$delay_single_quote_subst"`'
+predeps='`$ECHO "$predeps" | $SED "$delay_single_quote_subst"`'
+postdeps='`$ECHO "$postdeps" | $SED "$delay_single_quote_subst"`'
+compiler_lib_search_path='`$ECHO "$compiler_lib_search_path" | $SED "$delay_single_quote_subst"`'
+LD_CXX='`$ECHO "$LD_CXX" | $SED "$delay_single_quote_subst"`'
+reload_flag_CXX='`$ECHO "$reload_flag_CXX" | $SED "$delay_single_quote_subst"`'
+reload_cmds_CXX='`$ECHO "$reload_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+old_archive_cmds_CXX='`$ECHO "$old_archive_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+compiler_CXX='`$ECHO "$compiler_CXX" | $SED "$delay_single_quote_subst"`'
+GCC_CXX='`$ECHO "$GCC_CXX" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_no_builtin_flag_CXX='`$ECHO "$lt_prog_compiler_no_builtin_flag_CXX" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_pic_CXX='`$ECHO "$lt_prog_compiler_pic_CXX" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_wl_CXX='`$ECHO "$lt_prog_compiler_wl_CXX" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_static_CXX='`$ECHO "$lt_prog_compiler_static_CXX" | $SED "$delay_single_quote_subst"`'
+lt_cv_prog_compiler_c_o_CXX='`$ECHO "$lt_cv_prog_compiler_c_o_CXX" | $SED "$delay_single_quote_subst"`'
+archive_cmds_need_lc_CXX='`$ECHO "$archive_cmds_need_lc_CXX" | $SED "$delay_single_quote_subst"`'
+enable_shared_with_static_runtimes_CXX='`$ECHO "$enable_shared_with_static_runtimes_CXX" | $SED "$delay_single_quote_subst"`'
+export_dynamic_flag_spec_CXX='`$ECHO "$export_dynamic_flag_spec_CXX" | $SED "$delay_single_quote_subst"`'
+whole_archive_flag_spec_CXX='`$ECHO "$whole_archive_flag_spec_CXX" | $SED "$delay_single_quote_subst"`'
+compiler_needs_object_CXX='`$ECHO "$compiler_needs_object_CXX" | $SED "$delay_single_quote_subst"`'
+old_archive_from_new_cmds_CXX='`$ECHO "$old_archive_from_new_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+old_archive_from_expsyms_cmds_CXX='`$ECHO "$old_archive_from_expsyms_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+archive_cmds_CXX='`$ECHO "$archive_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+archive_expsym_cmds_CXX='`$ECHO "$archive_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+module_cmds_CXX='`$ECHO "$module_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+module_expsym_cmds_CXX='`$ECHO "$module_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+with_gnu_ld_CXX='`$ECHO "$with_gnu_ld_CXX" | $SED "$delay_single_quote_subst"`'
+allow_undefined_flag_CXX='`$ECHO "$allow_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`'
+no_undefined_flag_CXX='`$ECHO "$no_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_flag_spec_CXX='`$ECHO "$hardcode_libdir_flag_spec_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_separator_CXX='`$ECHO "$hardcode_libdir_separator_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_direct_CXX='`$ECHO "$hardcode_direct_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_direct_absolute_CXX='`$ECHO "$hardcode_direct_absolute_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_minus_L_CXX='`$ECHO "$hardcode_minus_L_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_shlibpath_var_CXX='`$ECHO "$hardcode_shlibpath_var_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_automatic_CXX='`$ECHO "$hardcode_automatic_CXX" | $SED "$delay_single_quote_subst"`'
+inherit_rpath_CXX='`$ECHO "$inherit_rpath_CXX" | $SED "$delay_single_quote_subst"`'
+link_all_deplibs_CXX='`$ECHO "$link_all_deplibs_CXX" | $SED "$delay_single_quote_subst"`'
+always_export_symbols_CXX='`$ECHO "$always_export_symbols_CXX" | $SED "$delay_single_quote_subst"`'
+export_symbols_cmds_CXX='`$ECHO "$export_symbols_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+exclude_expsyms_CXX='`$ECHO "$exclude_expsyms_CXX" | $SED "$delay_single_quote_subst"`'
+include_expsyms_CXX='`$ECHO "$include_expsyms_CXX" | $SED "$delay_single_quote_subst"`'
+prelink_cmds_CXX='`$ECHO "$prelink_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+postlink_cmds_CXX='`$ECHO "$postlink_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+file_list_spec_CXX='`$ECHO "$file_list_spec_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_action_CXX='`$ECHO "$hardcode_action_CXX" | $SED "$delay_single_quote_subst"`'
+compiler_lib_search_dirs_CXX='`$ECHO "$compiler_lib_search_dirs_CXX" | $SED "$delay_single_quote_subst"`'
+predep_objects_CXX='`$ECHO "$predep_objects_CXX" | $SED "$delay_single_quote_subst"`'
+postdep_objects_CXX='`$ECHO "$postdep_objects_CXX" | $SED "$delay_single_quote_subst"`'
+predeps_CXX='`$ECHO "$predeps_CXX" | $SED "$delay_single_quote_subst"`'
+postdeps_CXX='`$ECHO "$postdeps_CXX" | $SED "$delay_single_quote_subst"`'
+compiler_lib_search_path_CXX='`$ECHO "$compiler_lib_search_path_CXX" | $SED "$delay_single_quote_subst"`'
+
+LTCC='$LTCC'
+LTCFLAGS='$LTCFLAGS'
+compiler='$compiler_DEFAULT'
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+  eval 'cat <<_LTECHO_EOF
+\$1
+_LTECHO_EOF'
+}
+
+# Quote evaled strings.
+for var in SHELL \
+ECHO \
+PATH_SEPARATOR \
+SED \
+GREP \
+EGREP \
+FGREP \
+LD \
+NM \
+LN_S \
+lt_SP2NL \
+lt_NL2SP \
+reload_flag \
+OBJDUMP \
+deplibs_check_method \
+file_magic_cmd \
+file_magic_glob \
+want_nocaseglob \
+DLLTOOL \
+sharedlib_from_linklib_cmd \
+AR \
+AR_FLAGS \
+archiver_list_spec \
+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 \
+nm_file_list_spec \
+lt_prog_compiler_no_builtin_flag \
+lt_prog_compiler_pic \
+lt_prog_compiler_wl \
+lt_prog_compiler_static \
+lt_cv_prog_compiler_c_o \
+need_locks \
+MANIFEST_TOOL \
+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_separator \
+exclude_expsyms \
+include_expsyms \
+file_list_spec \
+variables_saved_for_relink \
+libname_spec \
+library_names_spec \
+soname_spec \
+install_override_mode \
+finish_eval \
+old_striplib \
+striplib \
+compiler_lib_search_dirs \
+predep_objects \
+postdep_objects \
+predeps \
+postdeps \
+compiler_lib_search_path \
+LD_CXX \
+reload_flag_CXX \
+compiler_CXX \
+lt_prog_compiler_no_builtin_flag_CXX \
+lt_prog_compiler_pic_CXX \
+lt_prog_compiler_wl_CXX \
+lt_prog_compiler_static_CXX \
+lt_cv_prog_compiler_c_o_CXX \
+export_dynamic_flag_spec_CXX \
+whole_archive_flag_spec_CXX \
+compiler_needs_object_CXX \
+with_gnu_ld_CXX \
+allow_undefined_flag_CXX \
+no_undefined_flag_CXX \
+hardcode_libdir_flag_spec_CXX \
+hardcode_libdir_separator_CXX \
+exclude_expsyms_CXX \
+include_expsyms_CXX \
+file_list_spec_CXX \
+compiler_lib_search_dirs_CXX \
+predep_objects_CXX \
+postdep_objects_CXX \
+predeps_CXX \
+postdeps_CXX \
+compiler_lib_search_path_CXX; do
+    case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+    *[\\\\\\\`\\"\\\$]*)
+      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$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 \
+postlink_cmds \
+postinstall_cmds \
+postuninstall_cmds \
+finish_cmds \
+sys_lib_search_path_spec \
+sys_lib_dlsearch_path_spec \
+reload_cmds_CXX \
+old_archive_cmds_CXX \
+old_archive_from_new_cmds_CXX \
+old_archive_from_expsyms_cmds_CXX \
+archive_cmds_CXX \
+archive_expsym_cmds_CXX \
+module_cmds_CXX \
+module_expsym_cmds_CXX \
+export_symbols_cmds_CXX \
+prelink_cmds_CXX \
+postlink_cmds_CXX; do
+    case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+    *[\\\\\\\`\\"\\\$]*)
+      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\""
+      ;;
+    *)
+      eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+      ;;
+    esac
+done
+
+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'
+
+
+
+
+
+
+_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" ;;
+    "libpolysconfig.h") CONFIG_COMMANDS="$CONFIG_COMMANDS libpolysconfig.h" ;;
+    "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;;
+    "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+    "misc/Makefile") CONFIG_FILES="$CONFIG_FILES misc/Makefile" ;;
+    "reporter/Makefile") CONFIG_FILES="$CONFIG_FILES reporter/Makefile" ;;
+    "coeffs/Makefile") CONFIG_FILES="$CONFIG_FILES coeffs/Makefile" ;;
+    "polys/Makefile") CONFIG_FILES="$CONFIG_FILES polys/Makefile" ;;
+    "tests/Makefile") CONFIG_FILES="$CONFIG_FILES tests/Makefile" ;;
+    "libpolys-config") CONFIG_FILES="$CONFIG_FILES libpolys-config" ;;
+    "libpolys.pc") CONFIG_FILES="$CONFIG_FILES libpolys.pc" ;;
+    "misc/auxiliary.h") CONFIG_FILES="$CONFIG_FILES misc/auxiliary.h" ;;
+
+  *) 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= ac_tmp=
+  trap 'exit_status=$?
+  : "${ac_tmp:=$tmp}"
+  { test ! -d "$ac_tmp" || rm -fr "$ac_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 -d "$tmp"
+}  ||
+{
+  tmp=./conf$$-$RANDOM
+  (umask 077 && mkdir "$tmp")
+} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
+ac_tmp=$tmp
+
+# 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 {' >"$ac_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 >>"\$ac_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 >>"\$ac_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 < "$ac_tmp/subs1.awk" > "$ac_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 sole $(srcdir),
+# ${srcdir} and @srcdir@ entries 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[	 ]*=[	 ]*/{
+h
+s///
+s/^/:/
+s/[	 ]*$/:/
+s/:\$(srcdir):/:/g
+s/:\${srcdir}:/:/g
+s/:@srcdir@:/:/g
+s/^:*//
+s/:*$//
+x
+s/\(=[	 ]*\).*/\1/
+G
+s/\n//
+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 >"$ac_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_tt=`sed -n "/$ac_delim/p" confdefs.h`
+  if test -z "$ac_tt"; 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="$ac_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 1 "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 >"$ac_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 "$ac_tmp/subs.awk" \
+  >$ac_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' "$ac_tmp/out"`; test -n "$ac_out"; } &&
+  { ac_out=`sed -n '/^[	 ]*datarootdir[	 ]*:*=/p' \
+      "$ac_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 "$ac_tmp/stdin"
+  case $ac_file in
+  -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";;
+  *) rm -f "$ac_file" && mv "$ac_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 "$ac_tmp/defines.awk"' "$ac_file_inputs"
+    } >"$ac_tmp/config.h" \
+      || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+    if diff "$ac_file" "$ac_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 "$ac_tmp/config.h" "$ac_file" \
+	|| as_fn_error $? "could not create $ac_file" "$LINENO" 5
+    fi
+  else
+    $as_echo "/* $configure_input  */" \
+      && eval '$AWK -f "$ac_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"" || {
+  # Older Autoconf 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"`
+    # 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'`; 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
+}
+ ;;
+    "libpolysconfig.h":C)
+ac_prefix_conf_OUT=`echo libpolysconfig.h`
+ac_prefix_conf_PKG=`echo `
+ac_prefix_conf_LOW=`echo $ac_prefix_conf_PKG | sed -e "y:ABCDEFGHIJKLMNOPQRSTUVWXYZ-:abcdefghijklmnopqrstuvwxyz_:"`
+ac_prefix_conf_UPP=`echo $ac_prefix_conf_PKG | sed -e "y:abcdefghijklmnopqrstuvwxyz-:ABCDEFGHIJKLMNOPQRSTUVWXYZ_:"  -e "/^[0123456789]/s/^/_/"`
+ac_prefix_conf_INP=`echo "_config.h" | sed -e 's/ *//'`
+ac_prefix_conf_DEF=`echo "$ac_prefix_conf_UPP $PACKAGE $ac_prefix_conf_OUT" | sed -e "y:abcdefghijklmnopqrstuvwxyz:ABCDEFGHIJKLMNOPQRSTUVWXYZ:" -e "s/[^abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ]/_/g"`
+
+if test ".$ac_prefix_conf_INP" = "."; then
+   for ac_file in : $CONFIG_HEADERS; do test "_$ac_file" = _: && continue
+     case "$ac_file" in
+        *.h) ac_prefix_conf_INP=$ac_file ;;
+        *)
+     esac
+     test ".$ac_prefix_conf_INP" != "." && break
+   done
+fi
+if test ".$ac_prefix_conf_INP" = "."; then
+   case "$ac_prefix_conf_OUT" in
+      */*) ac_prefix_conf_INP=`basename "$ac_prefix_conf_OUT"`
+      ;;
+      *-*) ac_prefix_conf_INP=`echo "$ac_prefix_conf_OUT" | sed -e "s/[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_]*-//"`
+      ;;
+      *) ac_prefix_conf_INP=config.h
+      ;;
+   esac
+fi
+#if test -z "$_PKG" ; then
+#   AC_MSG_ERROR([no prefix for AX_PREFIX_PKG_CONFIG_H])
+#else
+  if test ! -f "$ac_prefix_conf_INP" ; then if test -f "$srcdir/$ac_prefix_conf_INP" ; then
+     ac_prefix_conf_INP="$srcdir/$ac_prefix_conf_INP"
+  fi fi
+  { $as_echo "$as_me:${as_lineno-$LINENO}: creating '$ac_prefix_conf_OUT' - prefix '$ac_prefix_conf_UPP' for '$ac_prefix_conf_INP' defines" >&5
+$as_echo "$as_me: creating '$ac_prefix_conf_OUT' - prefix '$ac_prefix_conf_UPP' for '$ac_prefix_conf_INP' defines" >&6;}
+  if test -f $ac_prefix_conf_INP ; then
+    $as_echo "s/^#undef  *\\([ABCDEFGHIJKLMNOPQRSTUVWXYZ_]\\)/#undef $ac_prefix_conf_UPP""\\1/" > conftest.prefix
+    $as_echo "s/^#undef  *\\([abcdefghijklmnopqrstuvwxyz]\\)/#undef $ac_prefix_conf_LOW""\\1/" >> conftest.prefix
+    $as_echo "s/^#define  *\\([ABCDEFGHIJKLMNOPQRSTUVWXYZ_][abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_]*\\)\\(.*\\)/#ifndef $ac_prefix_conf_UPP""\\1\\" >> conftest.prefix
+    $as_echo "#define $ac_prefix_conf_UPP""\\1\\2\\" >> conftest.prefix
+    $as_echo "#endif/" >> conftest.prefix
+    $as_echo "s/^#define  *\\([abcdefghijklmnopqrstuvwxyz][abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_]*\\)\\(.*\\)/#ifndef $ac_prefix_conf_LOW""\\1\\" >> conftest.prefix
+    $as_echo "#define $ac_prefix_conf_LOW""\\1\\2\\" >> conftest.prefix
+    $as_echo "#endif/" >> conftest.prefix
+
+    # now executing _script on _DEF input to create _OUT output file
+    echo "#ifndef $ac_prefix_conf_DEF"      >$tmp/pconfig.h
+    echo "#define $ac_prefix_conf_DEF 1" >>$tmp/pconfig.h
+    echo ' ' >>$tmp/pconfig.h
+
+    echo /'*' $ac_prefix_conf_OUT. Generated automatically at end of configure. '*'/ >>$tmp/pconfig.h
+    echo ' ' >>$tmp/pconfig.h
+
+    sed -f conftest.prefix $ac_prefix_conf_INP >>$tmp/pconfig.h
+    echo ' ' >>$tmp/pconfig.h
+    echo '/* once:' $ac_prefix_conf_DEF '*/' >>$tmp/pconfig.h
+    echo "#endif" >>$tmp/pconfig.h
+    if cmp -s $ac_prefix_conf_OUT $tmp/pconfig.h 2>/dev/null; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_prefix_conf_OUT is unchanged" >&5
+$as_echo "$as_me: $ac_prefix_conf_OUT is unchanged" >&6;}
+    else
+      ac_dir=`$as_dirname -- "$ac_prefix_conf_OUT" ||
+$as_expr X"$ac_prefix_conf_OUT" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$ac_prefix_conf_OUT" : 'X\(//\)[^/]' \| \
+	 X"$ac_prefix_conf_OUT" : 'X\(//\)$' \| \
+	 X"$ac_prefix_conf_OUT" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$ac_prefix_conf_OUT" |
+    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
+      rm -f "$ac_prefix_conf_OUT"
+      mv $tmp/pconfig.h "$ac_prefix_conf_OUT"
+    fi
+    cp conftest.prefix _configs.sed
+    rm _configs.sed
+  else
+    as_fn_error $? "input file $ac_prefix_conf_INP does not exist - skip generating $ac_prefix_conf_OUT" "$LINENO" 5
+  fi
+  rm -f conftest.*
+#fi
+ ;;
+    "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, 2009, 2010, 2011 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="CXX "
+
+# ### BEGIN LIBTOOL CONFIG
+
+# 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
+
+# Shell to use when invoking shell scripts.
+SHELL=$lt_SHELL
+
+# An echo program that protects backslashes.
+ECHO=$lt_ECHO
+
+# The PATH separator for the build system.
+PATH_SEPARATOR=$lt_PATH_SEPARATOR
+
+# 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
+
+# convert \$build file names to \$host format.
+to_host_file_cmd=$lt_cv_to_host_file_cmd
+
+# convert \$build files to toolchain format.
+to_tool_file_cmd=$lt_cv_to_tool_file_cmd
+
+# An object symbol dumper.
+OBJDUMP=$lt_OBJDUMP
+
+# 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
+
+# How to find potential files when deplibs_check_method = "file_magic".
+file_magic_glob=$lt_file_magic_glob
+
+# Find potential files using nocaseglob when deplibs_check_method = "file_magic".
+want_nocaseglob=$lt_want_nocaseglob
+
+# DLL creation program.
+DLLTOOL=$lt_DLLTOOL
+
+# Command to associate shared and link libraries.
+sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd
+
+# The archiver.
+AR=$lt_AR
+
+# Flags to create an archive.
+AR_FLAGS=$lt_AR_FLAGS
+
+# How to feed a file listing to the archiver.
+archiver_list_spec=$lt_archiver_list_spec
+
+# 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
+
+# Whether to use a lock for old archive extraction.
+lock_old_archive_extraction=$lock_old_archive_extraction
+
+# 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
+
+# Specify filename containing input files for \$NM.
+nm_file_list_spec=$lt_nm_file_list_spec
+
+# The root where to search for dependent libraries,and in which our libraries should be installed.
+lt_sysroot=$lt_sysroot
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# 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
+
+# Manifest tool.
+MANIFEST_TOOL=$lt_MANIFEST_TOOL
+
+# 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
+
+# Permission mode override for installation of shared libraries.
+install_override_mode=$lt_install_override_mode
+
+# 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
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag
+reload_cmds=$lt_reload_cmds
+
+# 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
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_lt_prog_compiler_pic
+
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl
+
+# 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
+
+# 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
+
+# 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
+
+# Commands necessary for finishing linking programs.
+postlink_cmds=$lt_postlink_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
+
+# The directories searched by this compiler when creating a shared library.
+compiler_lib_search_dirs=$lt_compiler_lib_search_dirs
+
+# Dependencies to place before and after the objects being linked to
+# create a shared library.
+predep_objects=$lt_predep_objects
+postdep_objects=$lt_postdep_objects
+predeps=$lt_predeps
+postdeps=$lt_postdeps
+
+# The library search path used internally by the compiler when linking
+# a shared library.
+compiler_lib_search_path=$lt_compiler_lib_search_path
+
+# ### 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 '$q' "$ltmain" >> "$cfgfile" \
+     || (rm -f "$cfgfile"; exit 1)
+
+  if test x"$xsi_shell" = xyes; then
+  sed -e '/^func_dirname ()$/,/^} # func_dirname /c\
+func_dirname ()\
+{\
+\    case ${1} in\
+\      */*) func_dirname_result="${1%/*}${2}" ;;\
+\      *  ) func_dirname_result="${3}" ;;\
+\    esac\
+} # Extended-shell func_dirname implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_basename ()$/,/^} # func_basename /c\
+func_basename ()\
+{\
+\    func_basename_result="${1##*/}"\
+} # Extended-shell func_basename implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_dirname_and_basename ()$/,/^} # func_dirname_and_basename /c\
+func_dirname_and_basename ()\
+{\
+\    case ${1} in\
+\      */*) func_dirname_result="${1%/*}${2}" ;;\
+\      *  ) func_dirname_result="${3}" ;;\
+\    esac\
+\    func_basename_result="${1##*/}"\
+} # Extended-shell func_dirname_and_basename implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_stripname ()$/,/^} # func_stripname /c\
+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}"}\
+} # Extended-shell func_stripname implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_split_long_opt ()$/,/^} # func_split_long_opt /c\
+func_split_long_opt ()\
+{\
+\    func_split_long_opt_name=${1%%=*}\
+\    func_split_long_opt_arg=${1#*=}\
+} # Extended-shell func_split_long_opt implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_split_short_opt ()$/,/^} # func_split_short_opt /c\
+func_split_short_opt ()\
+{\
+\    func_split_short_opt_arg=${1#??}\
+\    func_split_short_opt_name=${1%"$func_split_short_opt_arg"}\
+} # Extended-shell func_split_short_opt implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_lo2o ()$/,/^} # func_lo2o /c\
+func_lo2o ()\
+{\
+\    case ${1} in\
+\      *.lo) func_lo2o_result=${1%.lo}.${objext} ;;\
+\      *)    func_lo2o_result=${1} ;;\
+\    esac\
+} # Extended-shell func_lo2o implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_xform ()$/,/^} # func_xform /c\
+func_xform ()\
+{\
+    func_xform_result=${1%.*}.lo\
+} # Extended-shell func_xform implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_arith ()$/,/^} # func_arith /c\
+func_arith ()\
+{\
+    func_arith_result=$(( $* ))\
+} # Extended-shell func_arith implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_len ()$/,/^} # func_len /c\
+func_len ()\
+{\
+    func_len_result=${#1}\
+} # Extended-shell func_len implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+fi
+
+if test x"$lt_shell_append" = xyes; then
+  sed -e '/^func_append ()$/,/^} # func_append /c\
+func_append ()\
+{\
+    eval "${1}+=\\${2}"\
+} # Extended-shell func_append implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_append_quoted ()$/,/^} # func_append_quoted /c\
+func_append_quoted ()\
+{\
+\    func_quote_for_eval "${2}"\
+\    eval "${1}+=\\\\ \\$func_quote_for_eval_result"\
+} # Extended-shell func_append_quoted implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  # Save a `func_append' function call where possible by direct use of '+='
+  sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \
+    && mv -f "$cfgfile.tmp" "$cfgfile" \
+      || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+  test 0 -eq $? || _lt_function_replace_fail=:
+else
+  # Save a `func_append' function call even when '+=' is not available
+  sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \
+    && mv -f "$cfgfile.tmp" "$cfgfile" \
+      || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+  test 0 -eq $? || _lt_function_replace_fail=:
+fi
+
+if test x"$_lt_function_replace_fail" = x":"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to substitute extended shell functions in $ofile" >&5
+$as_echo "$as_me: WARNING: Unable to substitute extended shell functions in $ofile" >&2;}
+fi
+
+
+   mv -f "$cfgfile" "$ofile" ||
+    (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
+  chmod +x "$ofile"
+
+
+    cat <<_LT_EOF >> "$ofile"
+
+# ### BEGIN LIBTOOL TAG CONFIG: CXX
+
+# The linker used to build libraries.
+LD=$lt_LD_CXX
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag_CXX
+reload_cmds=$lt_reload_cmds_CXX
+
+# Commands used to build an old-style archive.
+old_archive_cmds=$lt_old_archive_cmds_CXX
+
+# A language specific compiler.
+CC=$lt_compiler_CXX
+
+# Is the compiler the GNU compiler?
+with_gcc=$GCC_CXX
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_CXX
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_lt_prog_compiler_pic_CXX
+
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl_CXX
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_lt_prog_compiler_static_CXX
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_lt_cv_prog_compiler_c_o_CXX
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$archive_cmds_need_lc_CXX
+
+# Whether or not to disallow shared libs when runtime libs are static.
+allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_CXX
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_CXX
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_whole_archive_flag_spec_CXX
+
+# Whether the compiler copes with passing no objects directly.
+compiler_needs_object=$lt_compiler_needs_object_CXX
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_CXX
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_CXX
+
+# Commands used to build a shared archive.
+archive_cmds=$lt_archive_cmds_CXX
+archive_expsym_cmds=$lt_archive_expsym_cmds_CXX
+
+# Commands used to build a loadable module if different from building
+# a shared archive.
+module_cmds=$lt_module_cmds_CXX
+module_expsym_cmds=$lt_module_expsym_cmds_CXX
+
+# Whether we are building with GNU ld or not.
+with_gnu_ld=$lt_with_gnu_ld_CXX
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_allow_undefined_flag_CXX
+
+# Flag that enforces no undefined symbols.
+no_undefined_flag=$lt_no_undefined_flag_CXX
+
+# 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_CXX
+
+# Whether we need a single "-rpath" flag with a separated argument.
+hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX
+
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
+# DIR into the resulting binary.
+hardcode_direct=$hardcode_direct_CXX
+
+# 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_CXX
+
+# Set to "yes" if using the -LDIR flag during linking hardcodes DIR
+# into the resulting binary.
+hardcode_minus_L=$hardcode_minus_L_CXX
+
+# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
+# into the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var_CXX
+
+# 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_CXX
+
+# Set to yes if linker adds runtime paths of dependent libraries
+# to runtime path list.
+inherit_rpath=$inherit_rpath_CXX
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$link_all_deplibs_CXX
+
+# Set to "yes" if exported symbols are required.
+always_export_symbols=$always_export_symbols_CXX
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_export_symbols_cmds_CXX
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_exclude_expsyms_CXX
+
+# Symbols that must always be exported.
+include_expsyms=$lt_include_expsyms_CXX
+
+# Commands necessary for linking programs (against libraries) with templates.
+prelink_cmds=$lt_prelink_cmds_CXX
+
+# Commands necessary for finishing linking programs.
+postlink_cmds=$lt_postlink_cmds_CXX
+
+# Specify filename containing input files.
+file_list_spec=$lt_file_list_spec_CXX
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action_CXX
+
+# The directories searched by this compiler when creating a shared library.
+compiler_lib_search_dirs=$lt_compiler_lib_search_dirs_CXX
+
+# Dependencies to place before and after the objects being linked to
+# create a shared library.
+predep_objects=$lt_predep_objects_CXX
+postdep_objects=$lt_postdep_objects_CXX
+predeps=$lt_predeps_CXX
+postdeps=$lt_postdeps_CXX
+
+# The library search path used internally by the compiler when linking
+# a shared library.
+compiler_lib_search_path=$lt_compiler_lib_search_path_CXX
+
+# ### END LIBTOOL TAG CONFIG: CXX
+_LT_EOF
+
+ ;;
+
+  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 1
+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/libpolys/configure.ac b/libpolys/configure.ac
new file mode 100644
index 0000000..0b3c5bb
--- /dev/null
+++ b/libpolys/configure.ac
@@ -0,0 +1,150 @@
+AC_INIT([libpolys], [4.0.1])
+
+AC_CONFIG_MACRO_DIR([../m4])
+AC_CONFIG_AUX_DIR([../build-aux])
+AC_CONFIG_SRCDIR([reporter/reporter.h])
+AC_CONFIG_HEADER([_config.h])
+
+AM_MAINTAINER_MODE([enable])
+
+AM_INIT_AUTOMAKE([-Wall foreign subdir-objects]) # -Wno-extra-portability -Werror silent-rules
+m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
+m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
+
+dnl Check if build env is sane
+AM_SANITY_CHECK
+
+# Add pre'prefixed config
+AX_PREFIX_CONFIG_H([libpolysconfig.h],[],[_config.h])
+
+# - Check for CC and CXX but be careful about CFLAGS.
+SING_RESET_FLAGS()
+SING_CHECK_SET_ARGS()
+
+AC_PROG_CC
+AC_PROG_CXX
+AM_PROG_CC_C_O
+AC_PROG_LN_S
+AC_PROG_INSTALL
+
+# Turn off shared libraries during beta-testing, since they
+# make the build process take too long.
+LT_INIT
+# ([shared])
+# LT_INIT(dlopen disable-static) # doesn't work on PowerPC!
+
+# Checks for libraries.
+LB_CHECK_GMP(3.1.1,,AC_MSG_ERROR([Unable to find GMP on your machine: please use --with-gmp=PATH_TO_DIR_CONTAINING_LIB_AND_INCLUDE (see also ./configure --help if you do not understand what we are talking about)]))
+LB_CHECK_NTL(5.0,,AC_MSG_WARN([Unable to find NTL (which is strongly recommended) on your machine: please use --with-ntl=PATH_TO_DIR_CONTAINING_LIB_AND_INCLUDE (see also ./configure --help if you do not understand what we are talking about)]))
+LB_CHECK_FLINT(2.3,,AC_MSG_WARN([Unable to find FLINT (which is strongly recommended) on your machine: please use --with-flint=PATH_TO_DIR_CONTAINING_LIB_AND_INCLUDE (see also ./configure --help if you do not understand what we are talking about)]))
+
+
+# Checks for library functions.
+AC_FUNC_ERROR_AT_LINE
+AC_CHECK_FUNCS([memmove memset pow sqrt strchr setenv putenv])
+AC_FUNC_VPRINTF
+AC_FUNC_MALLOC
+AC_CHECK_FUNC([vsnprintf], [AC_DEFINE([HAVE_VSNPRINTF], [1], [Define if vsnprintf exists.])])
+
+# Checks for header files.
+AC_HEADER_STDC
+AC_STDC_HEADERS
+AC_CHECK_HEADERS([stdlib.h string.h unistd.h pwd.h sys/param.h limits.h float.h execinfo.h])
+
+# If the compiler supports GCC C++ ABI name demangling (has header
+#   cxxabi.h and abi::__cxa_demangle() function), define
+#   HAVE_GCC_ABI_DEMANGLE
+AX_CXX_GCC_ABI_DEMANGLE
+
+# Checks for typedefs, structures, and compiler characteristics.
+AC_C_CONST
+AC_C_INLINE
+AC_HEADER_STDBOOL
+AC_TYPE_SIZE_T
+
+# SING_CHECK_PIPE
+
+# check for cpu properties
+AC_CHECK_SIZEOF(long,4)
+SING_CHECK_CPU
+
+#check for host:
+AC_CANONICAL_HOST
+
+case $host_os in
+  *cygwin* ) AX_APPEND_LINK_FLAGS([-Wl,-Bdynamic]);;
+esac
+
+dnl INCLUDES=""
+dnl dnl OS specific flags and options (does work without the following:)
+dnl case "$host" in
+dnl     *-*-freebsd*)
+dnl         LIBS="$LIBS -L/usr/local/lib -lc"
+dnl 	CFLAGS="$CFLAGS -I/usr/local/include"
+dnl 	INCLUDES="$INCLUDES -I/usr/local/include"
+dnl 	;;
+dnl esac
+dnl AC_SUBST(INCLUDES)
+
+SING_CHECK_OMALLOC()
+
+ENABLE_RESOURCES="yes"
+
+AC_ARG_VAR( [RESOURCES_INCLUDES], [INCLUDES for libresources] )
+AC_ARG_VAR( [RESOURCES_LIBS], [LIBS for libresources] )
+
+AC_MSG_CHECKING(whether libresources should be used)
+
+if test "x$ENABLE_RESOURCES" = xyes;
+then
+  AC_MSG_RESULT(yes)
+
+  AC_MSG_CHECKING([  RESOURCES_INCLUDES?..])
+  AC_MSG_RESULT(${RESOURCES_INCLUDES:-unset})
+
+  AC_MSG_CHECKING([  RESOURCES_LIBS?..])
+  AC_MSG_RESULT(${RESOURCES_LIBS:-unset})
+
+  PKG_REQUIRE="$PKG_REQUIRE resources"
+  AC_SUBST(PKG_REQUIRE)
+else
+  AC_MSG_RESULT(no)
+fi
+
+AM_CONDITIONAL([ENABLE_RESOURCES],[test "x$ENABLE_RESOURCES" = xyes])
+
+SING_CHECK_FACTORY()
+
+SING_CHECK_P_PROCS
+SING_CHECK_ARITH_RINGS
+SING_CHECK_PLURAL
+
+# AC_SUBST(PREFIX)
+# AC_DEFINE_UNQUOTED(INSTALL_PREFIX,"$PREFIX",Prefix)
+
+AC_DEFINE([SINGULAR],[1],[SINGULAR])
+AC_DEFINE([DISABLE_GMP_CPP],[1],[DISABLE_GMP_CPP])
+AC_DEFINE([NOSTREAMIO],[1],[DISABLE_GMP_CPP])
+
+# AX_PYTHON_DEFAULT()
+# AX_PYTHON_WITH_VERSION([2.4])
+
+AC_DEFINE_UNQUOTED([NTL_CFLAGS],"$NTL_CFLAGS",[NTL_CFLAGS])
+AC_DEFINE_UNQUOTED([NTL_LIBS],"$NTL_LIBS",[NTL_LIBS])
+
+AC_DEFINE_UNQUOTED([GMP_CFLAGS],"$GMP_CFLAGS",[GMP_CFLAGS])
+AC_DEFINE_UNQUOTED([GMP_LIBS],"$GMP_LIBS",[GMP_LIBS])
+
+# AC_DEFINE_UNQUOTED([FLINT_CFLAGS],"$FLINT_CFLAGS",[FLINT_CFLAGS])
+# AC_DEFINE_UNQUOTED([FLINT_LIBS],"$FLINT_LIBS",[FLINT_LIBS])
+
+## AC_DEFINE([HAVE_POLYEXTENSIONS], [1], [Enable the algebraic & transcendental extensions])
+
+AC_CONFIG_FILES([Makefile])
+AC_CONFIG_FILES([misc/Makefile])
+AC_CONFIG_FILES([reporter/Makefile])
+AC_CONFIG_FILES([coeffs/Makefile])
+AC_CONFIG_FILES([polys/Makefile])
+AC_CONFIG_FILES([tests/Makefile])
+AC_CONFIG_FILES([libpolys-config libpolys.pc  misc/auxiliary.h])
+AC_OUTPUT
diff --git a/libpolys/libpolys-config.in b/libpolys/libpolys-config.in
new file mode 100755
index 0000000..7e3d26e
--- /dev/null
+++ b/libpolys/libpolys-config.in
@@ -0,0 +1,108 @@
+#! /bin/bash
+
+#C="$0"
+#O=`pwd`
+#
+###C=`readlink -f "$C"`:::
+#cd `dirname "$C"`
+#C=`basename "$C"`
+#
+## Iterate down a (possible) chain of symlinks
+#while [ -L "$C" ]
+#do
+#    C=`readlink "$C"`
+#    cd `dirname "$C"`
+#    C=`basename "$C"`
+#done
+#
+#cd `dirname "$C"`
+#C=`pwd`
+#C=`dirname "$C"`
+#C=`ls -d1 "$C"`
+#
+#cd "$O"
+
+# NOTE: if you moved this config please either use the above or
+# make sure the following variables are up to date
+#prefix="$C"
+#exec_prefix=${prefix}
+#includedir=${prefix}/include
+#libdir=${exec_prefix}/lib
+
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+
+includedir=@includedir@
+libdir=@libdir@
+
+ECHO="echo"
+ECHOn="printf"
+
+usage()
+{
+    cat <<EOF
+Usage: libpolys-config [OPTION]
+
+Known values for OPTION are:
+
+  --prefix		show libpolys installation prefix
+  --libs		print library linking information
+  --cflags		print pre-processor and compiler flags
+  --help		display this help and exit
+  --version		output version information
+
+EOF
+
+    exit $1
+}
+
+if test $# -eq 0; then
+    usage 1
+fi
+
+cflags=false
+libs=false
+
+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
+	;;
+
+    --prefix)
+	${ECHO} $prefix
+	;;
+
+    --version)
+	${ECHO} @VERSION@
+	exit 0
+	;;
+
+    --help)
+	usage 0
+	;;
+
+    --cflags)
+    #### @FACTORY_INCLUDES@
+	${ECHOn} " -I${includedir} -I${includedir}/singular @SINGULAR_CFLAGS@ @NTL_CFLAGS@ @GMP_CFLAGS@ "
+	;;
+
+    --libs)
+	${ECHOn} " -L${libdir} -lpolys"
+	;;
+
+    *)
+	usage
+	exit 1
+	;;
+    esac
+    shift
+done
+${ECHO}
+
+exit 0
diff --git a/libpolys/libpolys.pc.in b/libpolys/libpolys.pc.in
new file mode 100644
index 0000000..cb5a4e1
--- /dev/null
+++ b/libpolys/libpolys.pc.in
@@ -0,0 +1,17 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: @PACKAGE@
+Description: The Singular polynomial/coefficient arithmetic and related supporting functionality
+Version: @PACKAGE_VERSION@
+URL: https://github.com/Singular/Sources/tree/spielwiese/@PACKAGE@
+
+Requires: @PKG_REQUIRE@
+Conflicts:
+
+Cflags: -I${includedir} -I${includedir}/singular @SINGULAR_CFLAGS@ @FLINT_CFLAGS@ @NTL_CFLAGS@ @GMP_CFLAGS@
+Libs: -L${libdir} -lpolys -lfactory @FLINT_LIBS@ @NTL_LIBS@ @GMP_LIBS@ @USEPPROCSDYNAMICLD@
+Libs.private:
+
diff --git a/libpolys/misc/Makefile.am b/libpolys/misc/Makefile.am
new file mode 100644
index 0000000..5079139
--- /dev/null
+++ b/libpolys/misc/Makefile.am
@@ -0,0 +1,22 @@
+ACLOCAL_AMFLAGS = -I ../../m4
+
+AM_CPPFLAGS = -I${top_srcdir} -I${top_srcdir}/.. -I${top_builddir} -I${top_builddir}/..
+
+noinst_LTLIBRARIES = libmisc.la  libintvec.la
+##### libmiscdir = $(libdir)/singular
+
+libmisc_la_LIBADD = libintvec.la
+
+## libmisc_la_LDFLAGS    = -release ${PACKAGE_VERSION}
+
+libmisc_la_SOURCES   = int64vec.cc options.c sirandom.c
+
+libmisc_la_includedir = $(includedir)/singular/misc
+libmisc_la_include_HEADERS = mylimits.h options.h intvec.h int64vec.h sirandom.h
+
+nodist_libmisc_la_include_HEADERS = auxiliary.h
+nodist_libmisc_la_SOURCES   = auxiliary.h
+
+libintvec_la_SOURCES = intvec.cc
+
+
diff --git a/libpolys/misc/Makefile.in b/libpolys/misc/Makefile.in
new file mode 100644
index 0000000..862d3ac
--- /dev/null
+++ b/libpolys/misc/Makefile.in
@@ -0,0 +1,766 @@
+# Makefile.in generated by automake 1.13.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 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@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+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 = misc
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(srcdir)/auxiliary.h.in $(top_srcdir)/../build-aux/depcomp \
+	$(libmisc_la_include_HEADERS)
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/../m4/ax_append_compile_flags.m4 \
+	$(top_srcdir)/../m4/ax_append_flag.m4 \
+	$(top_srcdir)/../m4/ax_append_link_flags.m4 \
+	$(top_srcdir)/../m4/ax_check_compile_flag.m4 \
+	$(top_srcdir)/../m4/ax_check_link_flag.m4 \
+	$(top_srcdir)/../m4/ax_cxx_gcc_abi_demangle.m4 \
+	$(top_srcdir)/../m4/ax_prefix_config_h.m4 \
+	$(top_srcdir)/../m4/cpu-check.m4 $(top_srcdir)/../m4/flags.m4 \
+	$(top_srcdir)/../m4/flint-check.m4 \
+	$(top_srcdir)/../m4/gmp-check.m4 \
+	$(top_srcdir)/../m4/libtool.m4 \
+	$(top_srcdir)/../m4/ltoptions.m4 \
+	$(top_srcdir)/../m4/ltsugar.m4 \
+	$(top_srcdir)/../m4/ltversion.m4 \
+	$(top_srcdir)/../m4/lt~obsolete.m4 \
+	$(top_srcdir)/../m4/ntl-check.m4 \
+	$(top_srcdir)/../m4/options.m4 $(top_srcdir)/../m4/p-procs.m4 \
+	$(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/_config.h
+CONFIG_CLEAN_FILES = auxiliary.h
+CONFIG_CLEAN_VPATH_FILES =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+libintvec_la_LIBADD =
+am_libintvec_la_OBJECTS = intvec.lo
+libintvec_la_OBJECTS = $(am_libintvec_la_OBJECTS)
+AM_V_lt = $(am__v_lt_ at AM_V@)
+am__v_lt_ = $(am__v_lt_ at AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 = 
+libmisc_la_DEPENDENCIES = libintvec.la
+am_libmisc_la_OBJECTS = int64vec.lo options.lo sirandom.lo
+nodist_libmisc_la_OBJECTS =
+libmisc_la_OBJECTS = $(am_libmisc_la_OBJECTS) \
+	$(nodist_libmisc_la_OBJECTS)
+AM_V_P = $(am__v_P_ at AM_V@)
+am__v_P_ = $(am__v_P_ at AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_ at AM_V@)
+am__v_GEN_ = $(am__v_GEN_ at AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_ at AM_V@)
+am__v_at_ = $(am__v_at_ at AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+DEFAULT_INCLUDES = -I. at am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/../build-aux/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+	$(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_ at AM_V@)
+am__v_CC_ = $(am__v_CC_ at AM_DEFAULT_V@)
+am__v_CC_0 = @echo "  CC      " $@;
+am__v_CC_1 = 
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+	$(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_ at AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_ at AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo "  CCLD    " $@;
+am__v_CCLD_1 = 
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \
+	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+	$(AM_CXXFLAGS) $(CXXFLAGS)
+AM_V_CXX = $(am__v_CXX_ at AM_V@)
+am__v_CXX_ = $(am__v_CXX_ at AM_DEFAULT_V@)
+am__v_CXX_0 = @echo "  CXX     " $@;
+am__v_CXX_1 = 
+CXXLD = $(CXX)
+CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+	$(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CXXLD = $(am__v_CXXLD_ at AM_V@)
+am__v_CXXLD_ = $(am__v_CXXLD_ at AM_DEFAULT_V@)
+am__v_CXXLD_0 = @echo "  CXXLD   " $@;
+am__v_CXXLD_1 = 
+SOURCES = $(libintvec_la_SOURCES) $(libmisc_la_SOURCES) \
+	$(nodist_libmisc_la_SOURCES)
+DIST_SOURCES = $(libintvec_la_SOURCES) $(libmisc_la_SOURCES)
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+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__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
+am__installdirs = "$(DESTDIR)$(libmisc_la_includedir)" \
+	"$(DESTDIR)$(libmisc_la_includedir)"
+HEADERS = $(libmisc_la_include_HEADERS) \
+	$(nodist_libmisc_la_include_HEADERS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+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@
+FACTORY_INCLUDES = @FACTORY_INCLUDES@
+FACTORY_LIBS = @FACTORY_LIBS@
+FGREP = @FGREP@
+FLINT_CFLAGS = @FLINT_CFLAGS@
+FLINT_HOME = @FLINT_HOME@
+FLINT_LIBS = @FLINT_LIBS@
+GMP_CFLAGS = @GMP_CFLAGS@
+GMP_HOME = @GMP_HOME@
+GMP_LIBS = @GMP_LIBS@
+GMP_VERSION = @GMP_VERSION@
+GREP = @GREP@
+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@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NTL_CFLAGS = @NTL_CFLAGS@
+NTL_LIBS = @NTL_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OMALLOC_INCLUDES = @OMALLOC_INCLUDES@
+OMALLOC_LIBS = @OMALLOC_LIBS@
+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@
+PKG_REQUIRE = @PKG_REQUIRE@
+POLYMAKE_CXXFLAGS = @POLYMAKE_CXXFLAGS@
+RANLIB = @RANLIB@
+RESOURCES_INCLUDES = @RESOURCES_INCLUDES@
+RESOURCES_LIBS = @RESOURCES_LIBS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SINGULAR_CFLAGS = @SINGULAR_CFLAGS@
+SI_CPU_I386 = @SI_CPU_I386@
+SI_CPU_IA64 = @SI_CPU_IA64@
+SI_CPU_PPC = @SI_CPU_PPC@
+SI_CPU_SPARC = @SI_CPU_SPARC@
+SI_CPU_X86_64 = @SI_CPU_X86_64@
+STRIP = @STRIP@
+USEPPROCSDYNAMICLD = @USEPPROCSDYNAMICLD@
+USEPPROCSDYNAMICLDFLAGS = @USEPPROCSDYNAMICLDFLAGS@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+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@
+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@
+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@
+ACLOCAL_AMFLAGS = -I ../../m4
+AM_CPPFLAGS = -I${top_srcdir} -I${top_srcdir}/.. -I${top_builddir} -I${top_builddir}/..
+noinst_LTLIBRARIES = libmisc.la  libintvec.la
+##### libmiscdir = $(libdir)/singular
+libmisc_la_LIBADD = libintvec.la
+libmisc_la_SOURCES = int64vec.cc options.c sirandom.c
+libmisc_la_includedir = $(includedir)/singular/misc
+libmisc_la_include_HEADERS = mylimits.h options.h intvec.h int64vec.h sirandom.h
+nodist_libmisc_la_include_HEADERS = auxiliary.h
+nodist_libmisc_la_SOURCES = auxiliary.h
+libintvec_la_SOURCES = intvec.cc
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .cc .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) --foreign misc/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign misc/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):
+auxiliary.h: $(top_builddir)/config.status $(srcdir)/auxiliary.h.in
+	cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+
+clean-noinstLTLIBRARIES:
+	-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+	@list='$(noinst_LTLIBRARIES)'; \
+	locs=`for p in $$list; do echo $$p; done | \
+	      sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+	      sort -u`; \
+	test -z "$$locs" || { \
+	  echo rm -f $${locs}; \
+	  rm -f $${locs}; \
+	}
+
+libintvec.la: $(libintvec_la_OBJECTS) $(libintvec_la_DEPENDENCIES) $(EXTRA_libintvec_la_DEPENDENCIES) 
+	$(AM_V_CXXLD)$(CXXLINK)  $(libintvec_la_OBJECTS) $(libintvec_la_LIBADD) $(LIBS)
+
+libmisc.la: $(libmisc_la_OBJECTS) $(libmisc_la_DEPENDENCIES) $(EXTRA_libmisc_la_DEPENDENCIES) 
+	$(AM_V_CXXLD)$(CXXLINK)  $(libmisc_la_OBJECTS) $(libmisc_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/int64vec.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/intvec.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/options.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/sirandom.Plo at am__quote@
+
+.c.o:
+ at am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+ at am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+ at am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+ at am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+ at am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+ at am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+ at am__fastdepCC_TRUE@	$(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+.cc.o:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+ at am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXXCOMPILE) -c -o $@ $<
+
+.cc.obj:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+ at am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.cc.lo:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+ at am__fastdepCXX_TRUE@	$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LTCXXCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+install-libmisc_la_includeHEADERS: $(libmisc_la_include_HEADERS)
+	@$(NORMAL_INSTALL)
+	@list='$(libmisc_la_include_HEADERS)'; test -n "$(libmisc_la_includedir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(libmisc_la_includedir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(libmisc_la_includedir)" || exit 1; \
+	fi; \
+	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)$(libmisc_la_includedir)'"; \
+	  $(INSTALL_HEADER) $$files "$(DESTDIR)$(libmisc_la_includedir)" || exit $$?; \
+	done
+
+uninstall-libmisc_la_includeHEADERS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(libmisc_la_include_HEADERS)'; test -n "$(libmisc_la_includedir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	dir='$(DESTDIR)$(libmisc_la_includedir)'; $(am__uninstall_files_from_dir)
+install-nodist_libmisc_la_includeHEADERS: $(nodist_libmisc_la_include_HEADERS)
+	@$(NORMAL_INSTALL)
+	@list='$(nodist_libmisc_la_include_HEADERS)'; test -n "$(libmisc_la_includedir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(libmisc_la_includedir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(libmisc_la_includedir)" || exit 1; \
+	fi; \
+	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)$(libmisc_la_includedir)'"; \
+	  $(INSTALL_HEADER) $$files "$(DESTDIR)$(libmisc_la_includedir)" || exit $$?; \
+	done
+
+uninstall-nodist_libmisc_la_includeHEADERS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(nodist_libmisc_la_include_HEADERS)'; test -n "$(libmisc_la_includedir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	dir='$(DESTDIR)$(libmisc_la_includedir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	$(am__define_uniq_tagged_files); \
+	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-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	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"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+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 $(LTLIBRARIES) $(HEADERS)
+installdirs:
+	for dir in "$(DESTDIR)$(libmisc_la_includedir)" "$(DESTDIR)$(libmisc_la_includedir)"; 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:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+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 clean-noinstLTLIBRARIES \
+	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-libmisc_la_includeHEADERS \
+	install-nodist_libmisc_la_includeHEADERS
+
+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: uninstall-libmisc_la_includeHEADERS \
+	uninstall-nodist_libmisc_la_includeHEADERS
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
+	clean-libtool clean-noinstLTLIBRARIES cscopelist-am ctags \
+	ctags-am 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-libmisc_la_includeHEADERS install-man \
+	install-nodist_libmisc_la_includeHEADERS 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 tags-am uninstall uninstall-am \
+	uninstall-libmisc_la_includeHEADERS \
+	uninstall-nodist_libmisc_la_includeHEADERS
+
+
+# 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/libpolys/misc/auxiliary.h.in b/libpolys/misc/auxiliary.h.in
new file mode 100644
index 0000000..9c184ae
--- /dev/null
+++ b/libpolys/misc/auxiliary.h.in
@@ -0,0 +1,459 @@
+/*****************************************************************************\
+ * Computer Algebra System SINGULAR
+\*****************************************************************************/
+/** @file auxiliary.h
+ *
+ * All the auxiliary stuff.
+ *
+ * ABSTRACT: we shall put here everything that does not have its own place.
+ *
+ * @author Oleksandr Motsak
+ *
+ *
+ **/
+/*****************************************************************************/
+
+#ifndef MISC_AUXILIARY_H
+#define MISC_AUXILIARY_H
+
+/* please include libpolysconfig.h exclusively via <misc/auxiliary.h> and before any other header */
+#include "libpolysconfig.h"
+
+// ----------------- which parts/extensions of Singular to build
+#ifndef HAVE_RINGS
+#undef HAVE_RINGS
+#endif
+
+#ifndef HAVE_PLURAL
+#undef HAVE_PLURAL
+#endif
+
+#ifndef HAVE_DL
+#undef HAVE_DL
+#endif
+
+#ifndef HAVE_FACTORY
+#undef HAVE_FACTORY
+#endif
+
+#ifndef HAVE_NTL
+#undef HAVE_NTL
+#endif
+
+/* letterplace gb:*/
+#ifndef HAVE_SHIFTBBA
+#undef HAVE_SHIFTBBA
+#endif
+
+#ifndef HAVE_POLYEXTENSIONS
+#undef HAVE_POLYEXTENSIONS
+#endif
+
+#ifndef DISABLE_GMP_CPP
+#undef DISABLE_GMP_CPP
+#endif
+
+#ifndef SINGULAR
+#undef SINGULAR
+#endif
+
+#ifndef NOSTREAMIO
+#undef NOSTREAMIO
+#endif
+
+/* the following cunstruct is to make it painless to add -DHAVE_NUMSTATS to CPPFLAGS for configure */
+#ifndef HAVE_NUMSTATS
+/* #define HAVE_NUMSTATS */
+#undef HAVE_NUMSTATS
+#endif /* HAVE_NUMSTATS */
+// ----------------  end of parts/extensions
+
+// ---------------- Singular standard types etc.
+/* SI_INTEGER_VARIANT: 1: from longrat.cc
+ *                     2: GMP
+ *                     3: rintegers.cc */
+#define SI_INTEGER_VARIANT 2
+
+/* SI_BIGINT_VARIANT: 1: from longrat.cc
+ *                    2: given by SI_INTEGER_VARIANT */
+#define SI_BIGINT_VARIANT 1
+
+/* preparation for versio 4.1.0: */
+#ifndef SINGULAR_4_1
+/* #define SINGULAR_4_1 */
+#undef SINGULAR_4_1
+#endif /* SINGULAR_4_1 */
+
+#ifndef SIZEOF_LONG
+
+#include <misc/mylimits.h>
+
+#ifndef LONG_BIT
+#if ULONG_MAX == 0xffffffffUL
+#define LONG_BIT 32
+#elif ULONG_MAX == 0xffffffffffffffffULL
+#define LONG_BIT 64
+#else
+#error "Unexpected max for unsigned long"
+#endif
+#endif
+
+
+
+#define SIZEOF_LONG (LONG_BIT/CHAR_BIT)
+// another option for SIZEOF_LONG: use omConfig included in <omalloc/omalloc.h>...
+
+#endif
+
+#include <sys/types.h>
+#if SIZEOF_LONG == 4
+typedef long long int64;
+#elif SIZEOF_LONG == 8
+typedef long int64;
+#else
+#error "Unexpected SIZEOF_LONG"
+#endif
+
+
+#ifndef CHAR_BIT
+#define CHAR_BIT (8)
+#endif /*ifndef CHAR_BIT*/
+
+
+#ifndef BIT_SIZEOF_LONG
+#define BIT_SIZEOF_LONG ((CHAR_BIT)*(SIZEOF_LONG))
+#endif /*ifndef BIT_SIZEOF_LONG*/
+
+
+
+
+#if (SIZEOF_LONG == 8)
+typedef int BOOLEAN;
+/* testet on x86_64, gcc 3.4.6: 2 % */
+/* testet on IA64, gcc 3.4.6: 1 % */
+#else
+/* testet on athlon, gcc 2.95.4: 1 % */
+typedef short BOOLEAN;
+#endif
+
+#ifndef FALSE
+#define FALSE       0
+#endif
+
+#ifndef TRUE
+#define TRUE        1
+#endif
+
+#ifndef NULL
+#define NULL        (0)
+#endif
+
+#ifndef NULLp
+#define NULLp        ((void*)NULL)
+#endif
+
+// #ifdef _TRY
+#ifndef ABS
+#define ABS(x) ((x)<0?(-(x)):(x))
+#endif
+// #endif
+
+typedef void* ADDRESS;
+
+#define loop for(;;)
+
+#if defined(__cplusplus)
+static inline int si_max(const int a, const int b)  { return (a>b) ? a : b; }
+static inline int si_min(const int a, const int b)  { return (a<b) ? a : b; }
+static inline long si_max(const long a, const long b)  { return (a>b) ? a : b; }
+static inline unsigned long si_max(const unsigned long a, const unsigned long b)  { return (a>b) ? a : b; }
+static inline long si_min(const long a, const long b)  { return (a<b) ? a : b; }
+static inline unsigned long si_min(const unsigned long a, const unsigned long b)  { return (a<b) ? a : b; }
+#else
+#define si_max(A,B) ((A) > (B) ? (A) : (B))
+#define si_min(A,B) ((A) < (B) ? (A) : (B))
+#endif
+
+
+// ---------------- end of Singular standard types etc.
+// ---------------- defines which depend on the settings above
+
+#ifndef HAVE_MULT_MOD
+#undef HAVE_MULT_MOD
+#endif
+
+#ifndef HAVE_DIV_MOD
+#undef HAVE_DIV_MOD
+#endif
+
+#ifndef HAVE_GENERIC_ADD
+#undef HAVE_GENERIC_ADD
+#endif
+
+/*******************************************************************
+ * DEBUG OPTIONS
+ * -- only significant for for compiling without -DSING_NDEBUG
+ * -- you better know what your are doing, if you touch this
+ ******************************************************************/
+#ifndef SING_NDEBUG
+
+/* undefine to enable inline */
+#define NO_INLINE
+
+/* undefine to disable assume -- should normally be defined for SING_NDEBUG */
+#define HAVE_ASSUME
+
+/* undef PDEBUG to disable checks of polys
+
+ define PDEBUG to
+  0 for enabling pTest
+  1 plus tests in Level 1 poly routines (operations on monomials)
+  2 plus tests in Level 2 poly routines (operations on single exponents)
+ -- see also polys.h for more info
+
+ NOTE: you can set the value of PDEBUG on a per-file basis, before
+       including mod2.h, provided ! PDEBUG is defined in mod2.h E.g.:
+
+       #define PDEBUG 2
+
+       ...
+
+       makes sure that all poly operations in your file are done with
+       PDEBUG == 2
+ To break after an error occured, set a debugger breakpoint on
+ dErrorBreak.
+*/
+#ifndef PDEBUG
+#define PDEBUG 0
+#endif
+
+/* define MDEBUG to enable memory checks */
+//////////////////////////////////////////// #define MDEBUG 0
+
+#ifdef MDEBUG
+/* If ! defined(OM_NDEBUG) and (defined(OM_TRACK) or defined(OM_CHECK)
+   then omDebug routines are used for memory allocation/free:
+
+   The omDebug routines are controlled by the values of OM_TRACK, OM_CHECK
+   and OM_KEEP.  There meaning is roughly as follows:
+   OM_TRACK: strored with address                              : extra space
+     0     : no additional info is stored                      : 0
+     1     : file:line of location where address was allocated : 1 word
+     2     : plus backtrace of stack where adress was allocated: 6 words
+     3     : plus size/bin info and front-, and back padding   : 9 words
+     4     : plus file:line of location where adress was freed : 10 words
+     5     : plus backtrace of stack where adress was allocated: 15 words
+   OM_CHECK: checks done
+     0     : no checks
+     1     : constant-time checks: i.e. addr checks only
+     2     : plus linear-time checks and constant related bin check
+     3     : plus quadratic-time checks and linear-time related bin checks and
+             constant time all memory checks
+     4     : and so on
+     ==> for OM_CHECK >= 3 it gets rather slow
+   OM_KEEP:  determines whether addresses are really freed  (
+     0     : addresses are really freed
+     1     : addresses are only marked as free and not really freed.
+
+   OM_CHECK, OM_TRACK, and OM_KEEP can be set on a per-file basis
+   (as can OM_NDEBUG),  e.g.:
+     #define OM_CHECK 3
+     #define OM_TRACK 5
+     #define OM_KEEP  1
+
+     #include <omalloc/omalloc.h>
+   ensures that all memory allocs/free in this file are done with
+   OM_CHECK==3 and OM_TRACK==5, and that all addresses allocated/freed
+   in this file are only marked as free and never really freed.
+
+   To set OM_CHECK, OM_TRACK and OM_KEEP under dynamic scope, set
+   om_Opts.MinCheck, om_Opts.MinTrack to the respectiv values and
+   om_Opts.Keep to the number of addresses which are kept before they are
+   actually freed. E.g.:
+     int check=om_Opts.MinCheck, track=om_Opts.MinTrack, keep= m_OPts.Keep;
+     om_Opts.MinCheck = 3; om_Opts.MinTrack = 5; omOpts.Keep = LONG_MAX;
+     ExternalRoutine();
+     om_Opts.MinCheck = check; omOpts.MinTrack = track; omOpts.Keep = keep;
+   ensures that all calls omDebug routines  occuring during the computation of
+   ExternalRoutine() are done with OM_CHECK==3 and OM_TRACK==5, and
+   calls to omFree only mark addresses as free and not really free them.
+
+   Furthermore, the value of OM_SING_KEEP (resp. om_Opts.Keep) specifies
+   how many addresses are kept before they are actually freed, independently
+   of the value of OM_KEEP.
+
+   Some tips on possible values of OM_TRACK, OM_CHECK, OM_KEEP:
+   + To find out about an address that has been freed twice, first locate the
+     file(s) where the error occured, and then at the beginning of these files:
+       #define OM_CHECK 3
+       #define OM_TRACK 5
+       #define OM_KEEP  1
+       #include <kernel/mod2.h>
+       #include <omalloc/omalloc.h>
+     Under dynamic scope, do (e.g., from within the debugger):
+       om_Opts.MinCheck = 3; om_Opts.MinTrack = 5; omOpts.Keep = LONG_MAX;
+   + to find out where "memory corruption" occured, increase value of
+     OM_CHECK - the higher this value is, the more consistency checks are
+     done (However a value > 3 checks the entire memory each time an omalloc
+     routine is used!)
+
+   Some more tips on the usage of omalloc:
+   + omAlloc*, omRealloc*, omFree*, omCheck* omDebug* omTest* rotuines
+     assume that sizes are > 0 and pointers are != NULL
+   + omalloc*, omrealloc*, omfree* omcheck*, omdebug* omtest* routines allow
+     NULL pointers and sizes == 0
+   + You can safely use any free/realloc routine in combination with any alloc
+     routine (including the debug versions): E.g., an address allocated with
+     omAllocBin can be freed with omfree, or an adress allocated with
+     om(Debug)Alloc can be freed with omfree, or omFree, or omFreeSize, etc.
+     However, keep in mind that the efficiency decreases from
+     Bin over Size to General routines (i.e., omFreeBin is more efficient than
+     omFreeSize which is more efficient than omFree, likewise with the alloc
+     routines).
+   + if OM_CHECK is undefined or 0, then all omCheck routines do nothing
+   + if OM_CHECK and OM_TRACK are both undefined (or 0), or if OM_NDEBUG is
+     defined, then the "real" alloc/realloc/free macros are used, and all
+     omTest, omDebug and omCheck routines are undefined
+   + to break after an omError occured within a debugger,
+     set a breakpoint on dErrorBreak
+   + to do checks from within the debugger, or to do checks with explicit
+     check level, use omTest routines.
+*/
+
+/* by default, store alloc info and file/line where addr was freed */
+#ifndef OM_TRACK
+#define OM_TRACK 4
+#endif
+/* only do constant-time memory checks */
+#ifndef OM_CHECK
+#define OM_CHECK 1
+#endif
+/* Do actually free memory:
+   (be careful: if this is set, memory is never really freed,
+    but only marked as free) */
+#ifndef OM_KEEP
+#define OM_KEEP 0
+#endif
+/* but only after you have freed 1000 more addresses
+   (this is actually independent of the value of OM_KEEP and used
+   to initialize om_Opts.Keep) */
+#ifndef OM_SING_KEEP
+#define OM_SING_KEEP 1000
+#endif
+
+#endif /* MDEBUG */
+
+
+/* undef KDEBUG for check of data during std computations
+ *
+ * define KDEBUG to
+ * 0 for basic tests
+ * 1 for tests in kSpoly
+ * NOTE: You can locally enable tests in kspoly by setting the
+ *       define at the beginning of kspoly.cc
+ */
+#define KDEBUG 0
+
+/* define LDEBUG checking numbers, undefine otherwise */
+#define LDEBUG
+
+/* define RDEBUG checking rings (together with TRACE=9) */
+#define RDEBUG
+
+/* define TEST for non time critical tests, undefine otherwise */
+#define TEST
+
+/* define YYDEBUG 1 for debugging bison texts, 0 otherwise */
+#define YYDEBUG 1
+
+#endif
+/* end of debugging option (ifndef SING_NDEBUG) */
+
+
+
+#ifdef _DEBUG
+#      define FORCE_INLINE inline
+#else
+#ifdef SING_NDEBUG
+#if   defined(_MSC_VER)
+#      define FORCE_INLINE __forceinline
+#elif defined(__GNUC__) && __GNUC__ > 3
+#      define FORCE_INLINE inline __attribute__ ((always_inline))
+#else
+#      define FORCE_INLINE inline
+#endif
+#else
+#      define FORCE_INLINE inline
+#endif
+/* SING_NDEBUG */
+#endif
+/* _DEBUG */
+
+
+#define DO_PRAGMA(x) _Pragma (#x)
+#define TODO(who, msg) DO_PRAGMA(message ("TODO [for " #who "]: " #msg))
+
+
+
+#if defined(__GNUC__) && defined(__GNUC_MINOR__)
+#define _GNUC_PREREQ(maj, min) ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
+#else
+#define _GNUC_PREREQ(maj, min) 0
+#endif
+
+#if _GNUC_PREREQ(3,3) && defined(__ELF__)
+#define FORCE_INTERNAL __attribute__ ((visibility ("internal")))
+#else
+#define FORCE_INTERNAL
+#endif
+
+#if _GNUC_PREREQ(3,3)
+#define FORCE_DEPRECATED __attribute__ ((deprecated))
+#else
+#define FORCE_DEPRECATED
+#endif
+
+#ifdef __cplusplus
+# define  BEGIN_CDECL extern "C" {
+# define  END_CDECL   }
+#else
+# define  BEGIN_CDECL
+# define  END_CDECL
+#endif
+
+#ifdef __cplusplus
+// hack to workaround warnings when casting void pointers
+// retrieved from dlsym? to function pointers.
+// see: http://trac.osgeo.org/qgis/ticket/234, http://www.trilithium.com/johan/2004/12/problem-with-dlsym/
+template<typename A, typename B>
+inline B cast_A_to_B( A a )
+{
+  union
+  {
+    A a;
+    B b;
+  } u;
+
+  u.a = a;
+  return u.b;
+}
+
+template<typename A>
+inline void* cast_A_to_vptr( A a )
+{
+  return cast_A_to_B<A, void*>(a);
+}
+
+
+template<typename A>
+inline A cast_vptr_to_A( void * p )
+{
+  return cast_A_to_B<void*, A>(p);
+}
+#endif
+
+
+
+#endif
+/* MISC_AUXILIARY_H */
+
diff --git a/libpolys/misc/int64vec.cc b/libpolys/misc/int64vec.cc
new file mode 100644
index 0000000..01d21e6
--- /dev/null
+++ b/libpolys/misc/int64vec.cc
@@ -0,0 +1,280 @@
+/*****************************************
+*  Computer Algebra System SINGULAR      *
+*****************************************/
+/*
+* ABSTRACT: class int64vec: lists/vectors of int64
+*/
+
+
+#include <misc/auxiliary.h>
+
+
+
+#include <misc/int64vec.h>
+#include <misc/intvec.h>
+#include <omalloc/omalloc.h>
+
+/*0 implementation*/
+
+
+int64vec::int64vec(int64vec* iv)
+{
+  row = iv->rows();
+  col = iv->cols();
+  v   = (int64 *)omAlloc(sizeof(int64)*row*col);
+  for (int i=0; i<row*col; i++)
+  {
+    v[i] = (*iv)[i];
+  }
+}
+
+int64vec::int64vec(intvec* iv)
+{
+  row = iv->rows();
+  col = iv->cols();
+  v   = (int64 *)omAlloc(sizeof(int64)*row*col);
+  for (int i=0; i<row*col; i++)
+  {
+    v[i] = (int64)((*iv)[i]);
+  }
+}
+
+int64vec::int64vec(int r, int c, int64 init)
+{
+  row = r;
+  col = c;
+  int l = r*c;
+  if ((r>0) && (c>0))
+    v = (int64 *)omAlloc(sizeof(int64)*l);
+  else
+    v = NULL;
+  for (int i=0; i<l; i++)
+  {
+    v[i] = init;
+  }
+}
+
+char * int64vec::iv64String(int not_mat, int /*mat*/, int spaces, int dim)
+{
+  StringSetS("");
+  if ((col == 1)&&(not_mat))
+  {
+    int i=0;
+    for (; i<row-1; i++)
+    {
+      StringAppend("%lld,",v[i]);
+    }
+    if (i<row)
+    {
+      StringAppend("%lld",v[i]);
+    }
+  }
+  else
+  {
+    for (int j=0; j<row; j++)
+    {
+      if (j<row-1)
+      {
+        for (int i=0; i<col; i++)
+        {
+          StringAppend("%lld%c",v[j*col+i],',');
+        }
+      }
+      else
+      {
+        for (int i=0; i<col; i++)
+        {
+          StringAppend("%lld%c",v[j*col+i],i<col-1 ? ',' : ' ');
+        }
+      }
+      if (j+1<row)
+      {
+        if (dim > 1) StringAppendS("\n");
+        if (spaces>0) StringAppend("%-*.*s",spaces,spaces," ");
+      }
+    }
+  }
+  return StringEndS();
+}
+
+char * int64vec::String(int dim)
+{
+  return iv64String(0, 0, dim);
+}
+
+void int64vec::show(int notmat,int spaces)
+{
+  char *s=iv64String(notmat,spaces);
+  if (spaces>0)
+  {
+    PrintNSpaces(spaces);
+    PrintS(s);
+  }
+  else
+  {
+    PrintS(s);
+  }
+  omFree(s);
+}
+
+void int64vec::operator*=(int64 intop)
+{
+  for (int i=row*col-1; i>=0; i--) { v[i] *= intop; }
+}
+
+void int64vec::operator/=(int64 intop)
+{
+  if (intop == 0) return;
+  int64 bb=ABS(intop);
+  for (int i=row*col-1; i>=0; i--)
+  {
+    int64 r=v[i];
+    int64 c=r%bb;
+    if (c<0) c+=bb;
+    r=(r-c)/intop;
+    v[i]=r;
+  }
+}
+
+int int64vec::compare(const int64vec* op) const
+{
+  if ((col!=1) ||(op->cols()!=1))
+  {
+    if((col!=op->cols())
+    || (row!=op->rows()))
+      return -2;
+  }
+  int i;
+  for (i=0; i<si_min(length(),op->length()); i++)
+  {
+    if (v[i] > (*op)[i])
+      return 1;
+    if (v[i] < (*op)[i])
+      return -1;
+  }
+  // this can only happen for int64vec: (i.e. col==1)
+  for (; i<row; i++)
+  {
+    if (v[i] > 0)
+      return 1;
+    if (v[i] < 0)
+      return -1;
+  }
+  for (; i<op->rows(); i++)
+  {
+    if (0 > (*op)[i])
+      return 1;
+    if (0 < (*op)[i])
+      return -1;
+  }
+  return 0;
+}
+
+int64vec * iv64Add(int64vec * a, int64vec * b)
+{
+  int64vec * iv;
+  int64 mn, ma, i;
+  if (a->cols() != b->cols()) return NULL;
+  mn = si_min(a->rows(),b->rows());
+  ma = si_max(a->rows(),b->rows());
+  if (a->cols() == 1)
+  {
+    iv = new int64vec(ma);
+    for (i=0; i<mn; i++) (*iv)[i] = (*a)[i] + (*b)[i];
+    if (ma > mn)
+    {
+      if (ma == a->rows())
+      {
+        for(i=mn; i<ma; i++) (*iv)[i] = (*a)[i];
+      }
+      else
+      {
+        for(i=mn; i<ma; i++) (*iv)[i] = (*b)[i];
+      }
+    }
+    return iv;
+  }
+  if (mn != ma) return NULL;
+  iv = new int64vec(a);
+  for (i=0; i<mn*a->cols(); i++) { (*iv)[i] += (*b)[i]; }
+  return iv;
+}
+
+int64vec * iv64Sub(int64vec * a, int64vec * b)
+{
+  int64vec * iv;
+  int mn, ma,i;
+  if (a->cols() != b->cols()) return NULL;
+  mn = si_min(a->rows(),b->rows());
+  ma = si_max(a->rows(),b->rows());
+  if (a->cols() == 1)
+  {
+    iv = new int64vec(ma);
+    for (i=0; i<mn; i++) (*iv)[i] = (*a)[i] - (*b)[i];
+    if (ma > mn)
+    {
+      if (ma == a->rows())
+      {
+        for(i=mn; i<ma; i++) (*iv)[i] = (*a)[i];
+      }
+      else
+      {
+        for(i=mn; i<ma; i++) (*iv)[i] = -(*b)[i];
+      }
+    }
+    return iv;
+  }
+  if (mn != ma) return NULL;
+  iv = new int64vec(a);
+  for (i=0; i<mn*a->cols(); i++) { (*iv)[i] -= (*b)[i]; }
+  return iv;
+}
+
+
+/*
+ * The following two functions are never used.
+ * Remove?
+
+// def. internals
+static int64 iv64Gcd(int, int);
+static int64 iv64L1Norm(intvec *);
+
+
+// The following two functions seem to be never used. Remove?
+static int64 iv64Gcd(int64 a,int64 b)
+{
+  int64 x;
+
+  if (a<0) a=-a;
+  if (b<0) b=-b;
+  if (b>a)
+  {
+    x=b;
+    b=a;
+    a=x;
+  }
+  while (b!=0)
+  {
+    x = a % b;
+    a = b;
+    b = x;
+  }
+  return a;
+}
+
+static int64 iv64L1Norm(int64vec *w)
+{
+  int i;
+  int64 j, s = 0;
+
+  for (i=w->rows()-1;i>=0;i--)
+  {
+    j = (*w)[i];
+    if (j>0)
+      s += j;
+    else
+      s -= j;
+  }
+  return s;
+}
+*/
diff --git a/libpolys/misc/int64vec.h b/libpolys/misc/int64vec.h
new file mode 100644
index 0000000..16cb0fe
--- /dev/null
+++ b/libpolys/misc/int64vec.h
@@ -0,0 +1,101 @@
+#ifndef INT64VEC_H
+#define INT64VEC_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: class intvec: lists/vectors of int64
+*/
+#include <string.h>
+#include <omalloc/omalloc.h>
+#include <misc/auxiliary.h>
+#include <misc/intvec.h>
+
+class int64vec
+{
+private:
+  int64 *v;
+  int row;
+  int col;
+public:
+
+  int64vec(int l = 1)
+    {
+      v = (int64 *)omAlloc0(sizeof(int64)*l);
+      row = l;
+      col = 1;
+    }
+  int64vec(int r, int c, int64 init);
+  int64vec(int64vec* iv);
+  int64vec(intvec* iv);
+  int64& operator[](int i)
+    {
+#ifndef SING_NDEBUG
+      if((i<0)||(i>=row*col))
+      {
+        Werror("wrong int64vec index:%d\n",i);
+      }
+#endif
+      return v[i];
+    }
+  inline const int64& operator[](int i) const
+    {
+#ifndef SING_NDEBUG
+      if((i<0)||(i>=row*col))
+      {
+        Werror("wrong int64vec index:%d\n",i);
+      }
+#endif
+      return v[i];
+    }
+  void operator*=(int64 intop);
+  void operator/=(int64 intop);
+  // -2: not compatible, -1: <, 0:=, 1: >
+  int compare(const int64vec* o) const;
+  int  length() const { return col*row; }
+  int  cols() const { return col; }
+  int  rows() const { return row; }
+  void show(int mat=0,int spaces=0);
+  char * String(int dim = 2);
+  char * iv64String(int not_mat=1,int mat=0,int spaces=0, int dim=2);
+  int64 * iv64GetVec() { return v; }
+  ~int64vec()
+    {
+      if (v!=NULL)
+      {
+        omFreeSize((ADDRESS)v,sizeof(int64)*row*col);
+        v=NULL;
+      }
+    }
+  void iv64TEST()
+    {
+      omCheckAddrSize((ADDRESS)v,sizeof(int64)*row*col);
+    }
+};
+inline int64vec * iv64Copy(int64vec * o)
+{
+  int64vec * iv=new int64vec(o);
+  return iv;
+}
+
+int64vec * iv64Add(int64vec * a, int64vec * b);
+int64vec * iv64Sub(int64vec * a, int64vec * b);
+
+#ifdef MDEBUG
+#define iv64Test(v) v->iv64TEST()
+#else
+#define iv64Test(v)   do {} while (0)
+#endif
+
+#endif
+
+
+
+
+
+
+
+
+
+
+
diff --git a/libpolys/misc/intvec.cc b/libpolys/misc/intvec.cc
new file mode 100644
index 0000000..b1747f8
--- /dev/null
+++ b/libpolys/misc/intvec.cc
@@ -0,0 +1,839 @@
+/*****************************************
+*  Computer Algebra System SINGULAR      *
+*****************************************/
+/*
+* ABSTRACT: class intvec: lists/vectors of integers
+*/
+#ifndef INTVEC_CC
+#define INTVEC_CC
+
+
+
+
+
+#include <misc/auxiliary.h>
+
+// #include <resources/feFopen.h>
+#include <misc/intvec.h>
+#include <misc/options.h>
+#include <omalloc/omalloc.h>
+
+#pragma GCC push_options
+#pragma GCC optimize ("wrapv")
+
+/*0 implementation*/
+
+// omBin intvec_bin = omGetSpecBin(sizeof(intvec));
+#if 0
+intvec::intvec(intvec* iv)
+{
+  row = iv->rows();
+  col = iv->cols();
+  v   = (int *)omAlloc(sizeof(int)*row*col);
+  for (int i=0; i<row*col; i++)
+  {
+    v[i] = (*iv)[i];
+  }
+}
+#endif
+
+intvec::intvec(int s, int e)
+{
+  int inc;
+  col = 1;
+  if (s<e)
+  {
+    row =  e-s+1;
+    inc =  1;
+  }
+  else
+  {
+    row = s-e+1;
+    inc = -1;
+  }
+  v = (int *)omAlloc(sizeof(int)*row);
+  for (int i=0; i<row; i++)
+  {
+    v[i] = s;
+    s+=inc;
+  }
+}
+
+intvec::intvec(int r, int c, int init)
+{
+  row = r;
+  col = c;
+  int l = r*c;
+  if (l>0) /*(r>0) && (c>0) */
+    v = (int *)omAlloc(sizeof(int)*l);
+  else
+    v = NULL;
+  for (int i=0; i<l; i++)
+  {
+    v[i] = init;
+  }
+}
+
+char * intvec::ivString(int not_mat,int spaces, int dim) const
+{
+  //Print("ivString:this=%x,v=%x,row=%d\n",this,v,row);
+#ifndef OM_NDEBUG
+  omCheckAddr((void *)this);
+  if (v!=NULL) omCheckAddr((void *)v);
+#endif
+  StringSetS("");
+  if ((col == 1)&&(not_mat))
+  {
+    int i=0;
+    for (; i<row-1; i++)
+    {
+      StringAppend("%d,",v[i]);
+    }
+    if (i<row)
+    {
+      StringAppend("%d",v[i]);
+    }
+  }
+  else
+  {
+    for (int j=0; j<row; j++)
+    {
+      if (j<row-1)
+      {
+        for (int i=0; i<col; i++)
+        {
+          StringAppend("%d%c",v[j*col+i],',');
+        }
+      }
+      else
+      {
+        for (int i=0; i<col; i++)
+        {
+          StringAppend("%d%c",v[j*col+i],i<col-1 ? ',' : ' ');
+        }
+      }
+      if (j+1<row)
+      {
+        if (dim > 1) StringAppendS("\n");
+        if (spaces>0) StringAppend("%-*.*s",spaces,spaces," ");
+      }
+    }
+  }
+  return StringEndS();
+}
+
+void intvec::resize(int new_length)
+{
+  assume(new_length > 0 && col == 1);
+  v = (int*) omRealloc0Size(v, row*sizeof(int), new_length*sizeof(int));
+  row = new_length;
+}
+
+char * intvec::String(int dim) const
+{
+  return ivString(1, 0, dim);
+}
+
+#ifndef SING_NDEBUG
+// debug only
+void intvec::view () const
+{
+  Print ("intvec: {rows: %d, cols: %d, length: %d, Values: \n", rows(), cols(), length());
+
+  for (int i = 0; i < rows(); i++)
+  {
+    Print ("Row[%3d]:", i);
+    for (int j = 0; j < cols(); j++)
+      Print (" %5d", this->operator[]((i)*cols()+j) );
+    PrintLn ();
+  }
+  PrintS ("}\n");
+}
+#endif
+
+void intvec::show(int notmat,int spaces) const
+{
+  char *s=ivString(notmat,spaces);
+  if (spaces>0)
+  {
+    PrintNSpaces(spaces);
+    PrintS(s);
+  }
+  else
+  {
+    PrintS(s);
+  }
+  omFree(s);
+}
+
+void intvec::operator+=(int intop)
+{
+  for (int i=0; i<row*col; i++) { v[i] += intop; }
+}
+
+void intvec::operator-=(int intop)
+{
+  for (int i=0; i<row*col; i++) { v[i] -= intop; }
+}
+
+void intvec::operator*=(int intop)
+{
+  for (int i=0; i<row*col; i++) { v[i] *= intop; }
+}
+
+void intvec::operator/=(int intop)
+{
+  if (intop == 0) return;
+  int bb=ABS(intop);
+  for (int i=0; i<row*col; i++)
+  {
+    int r=v[i];
+    int c=r%bb;
+    if (c<0) c+=bb;
+    r=(r-c)/intop;
+    v[i]=r;
+  }
+}
+
+void intvec::operator%=(int intop)
+{
+  if (intop == 0) return;
+  int bb=ABS(intop);
+  for (int i=0; i<row*col; i++)
+  {
+    int r=v[i];
+    int c=r%bb;
+    if (c<0) c+=bb;
+    v[i]=c;
+  }
+}
+
+int intvec::compare(const intvec* op) const
+{
+  if ((col!=1) ||(op->cols()!=1))
+  {
+    if((col!=op->cols())
+    || (row!=op->rows()))
+      return -2;
+  }
+  int i;
+  for (i=0; i<si_min(length(),op->length()); i++)
+  {
+    if (v[i] > (*op)[i])
+      return 1;
+    if (v[i] < (*op)[i])
+      return -1;
+  }
+  // this can only happen for intvec: (i.e. col==1)
+  for (; i<row; i++)
+  {
+    if (v[i] > 0)
+      return 1;
+    if (v[i] < 0)
+      return -1;
+  }
+  for (; i<op->rows(); i++)
+  {
+    if (0 > (*op)[i])
+      return 1;
+    if (0 < (*op)[i])
+      return -1;
+  }
+  return 0;
+}
+int intvec::compare(int o) const
+{
+  for (int i=0; i<row*col; i++)
+  {
+    if (v[i] <o) return -1;
+    if (v[i] >o) return 1;
+  }
+  return 0;
+}
+
+#if 0
+intvec * ivCopy(intvec * o)
+{
+  intvec * iv=new intvec(o);
+  return iv;
+}
+#endif
+
+intvec * ivAdd(intvec * a, intvec * b)
+{
+  intvec * iv;
+  int mn, ma, i;
+  if (a->cols() != b->cols()) return NULL;
+  mn = si_min(a->rows(),b->rows());
+  ma = si_max(a->rows(),b->rows());
+  if (a->cols() == 1)
+  {
+    iv = new intvec(ma);
+    for (i=0; i<mn; i++) (*iv)[i] = (*a)[i] + (*b)[i];
+    if (ma > mn)
+    {
+      if (ma == a->rows())
+      {
+        for(i=mn; i<ma; i++) (*iv)[i] = (*a)[i];
+      }
+      else
+      {
+        for(i=mn; i<ma; i++) (*iv)[i] = (*b)[i];
+      }
+    }
+    return iv;
+  }
+  if (mn != ma) return NULL;
+  iv = new intvec(a);
+  for (i=0; i<mn*a->cols(); i++) { (*iv)[i] += (*b)[i]; }
+  return iv;
+}
+
+intvec * ivSub(intvec * a, intvec * b)
+{
+  intvec * iv;
+  int mn, ma, i;
+  if (a->cols() != b->cols()) return NULL;
+  mn = si_min(a->rows(),b->rows());
+  ma = si_max(a->rows(),b->rows());
+  if (a->cols() == 1)
+  {
+    iv = new intvec(ma);
+    for (i=0; i<mn; i++) (*iv)[i] = (*a)[i] - (*b)[i];
+    if (ma > mn)
+    {
+      if (ma == a->rows())
+      {
+        for(i=mn; i<ma; i++) (*iv)[i] = (*a)[i];
+      }
+      else
+      {
+        for(i=mn; i<ma; i++) (*iv)[i] = -(*b)[i];
+      }
+    }
+    return iv;
+  }
+  if (mn != ma) return NULL;
+  iv = new intvec(a);
+  for (i=0; i<mn*a->cols(); i++) { (*iv)[i] -= (*b)[i]; }
+  return iv;
+}
+
+intvec * ivTranp(intvec * o)
+{
+  int i, j, r = o->rows(), c = o->cols();
+  intvec * iv= new intvec(c, r, 0);
+  for (i=0; i<r; i++)
+  {
+    for (j=0; j<c; j++)
+      (*iv)[j*r+i] = (*o)[i*c+j];
+  }
+  return iv;
+}
+
+int ivTrace(intvec * o)
+{
+  int i, s = 0, m = si_min(o->rows(),o->cols()), c = o->cols();
+  for (i=0; i<m; i++)
+  {
+    s += (*o)[i*c+i];
+  }
+  return s;
+}
+
+intvec * ivMult(intvec * a, intvec * b)
+{
+  int i, j, k, sum,
+      ra = a->rows(), ca = a->cols(),
+      rb = b->rows(), cb = b->cols();
+  intvec * iv;
+  if (ca != rb) return NULL;
+  iv = new intvec(ra, cb, 0);
+  for (i=0; i<ra; i++)
+  {
+    for (j=0; j<cb; j++)
+    {
+      sum = 0;
+      for (k=0; k<ca; k++)
+        sum += (*a)[i*ca+k]*(*b)[k*cb+j];
+      (*iv)[i*cb+j] = sum;
+    }
+  }
+  return iv;
+}
+
+/*2
+*computes a triangular matrix
+*/
+//void ivTriangMat(intvec * imat)
+//{
+//  int i=0,j=imat->rows(),k=j*imat->cols()-1;
+//
+//  ivTriangIntern(imat,i,j);
+//  i *= imat->cols();
+//  for(j=k;j>=i;j--)
+//    (*imat)[j] = 0;
+//}
+
+/* def. internals */
+static int ivColPivot(intvec *, int, int, int, int);
+static void ivNegRow(intvec *, int);
+static void ivSaveRow(intvec *, int);
+static void ivSetRow(intvec *, int, int);
+static void ivFreeRow(intvec *, int, int);
+static void ivReduce(intvec *, int, int, int, int);
+static void ivZeroElim(intvec *,int, int, int &);
+static void ivRowContent(intvec *, int, int);
+static void ivKernFromRow(intvec *, intvec *, intvec *,
+                          int, int, int);
+static intvec * ivOptimizeKern(intvec *);
+static int ivGcd(int, int);
+static void ivOptRecursive(intvec *, intvec *, intvec *,
+                          int &, int &, int);
+static void ivOptSolve(intvec *, intvec *, int &, int &);
+static void ivContent(intvec *);
+static int ivL1Norm(intvec *);
+static int ivCondNumber(intvec *, int);
+
+/* Triangulierung in intmat.cc */
+void ivTriangIntern(intvec *imat, int &ready, int &all)
+{
+  int rpiv, colpos=0, rowpos=0;
+  int ia=ready, ie=all;
+
+  do
+  {
+    rowpos++;
+    do
+    {
+      colpos++;
+      rpiv = ivColPivot(imat, colpos, rowpos, ia, ie);
+    } while (rpiv==0);
+    if (rpiv>ia)
+    {
+      if (rowpos!=rpiv)
+      {
+        ivSaveRow(imat, rpiv);
+        ivFreeRow(imat, rowpos, rpiv);
+        ivSetRow(imat, rowpos, colpos);
+        rpiv = rowpos;
+      }
+      ia++;
+      if (ia==imat->cols())
+      {
+        ready = ia;
+        all = ie;
+        return;
+      }
+    }
+    ivReduce(imat, rpiv, colpos, ia, ie);
+    ivZeroElim(imat, colpos, ia, ie);
+  } while (ie>ia);
+  ready = ia;
+  all = ie;
+}
+
+/* Kernberechnung in intmat.cc */
+intvec * ivSolveKern(intvec *imat, int dimtr)
+{
+  int d=imat->cols();
+  int kdim=d-dimtr;
+  intvec *perm = new intvec(dimtr+1);
+  intvec *kern = new intvec(kdim,d,0);
+  intvec *res;
+  int c, cp, r, t;
+
+  t = kdim;
+  c = 1;
+  for (r=1;r<=dimtr;r++)
+  {
+    while (IMATELEM(*imat,r,c)==0) c++;
+    (*perm)[r] = c;
+    c++;
+  }
+  c = d;
+  for (r=dimtr;r>0;r--)
+  {
+    cp = (*perm)[r];
+    if (cp!=c)
+    {
+      ivKernFromRow(kern, imat, perm, t, r, c);
+      t -= (c-cp);
+      if (t==0)
+        break;
+      c = cp-1;
+    }
+    else
+      c--;
+  }
+  if (kdim>1)
+    res = ivOptimizeKern(kern);
+  else
+    res = ivTranp(kern);
+  delete kern;
+  delete perm;
+  return res;
+}
+
+/* internals */
+static int ivColPivot(intvec *imat, int colpos, int rowpos, int ready, int all)
+{
+  int rpiv;
+
+  if (IMATELEM(*imat,rowpos,colpos)!=0)
+    return rowpos;
+  for (rpiv=ready+1;rpiv<=all;rpiv++)
+  {
+    if (IMATELEM(*imat,rpiv,colpos)!=0)
+      return rpiv;
+  }
+  return 0;
+}
+
+static void ivNegRow(intvec *imat, int rpiv)
+{
+  int i;
+  for (i=imat->cols();i!=0;i--)
+    IMATELEM(*imat,rpiv,i) = -(IMATELEM(*imat,rpiv,i));
+}
+
+static void ivSaveRow(intvec *imat, int rpiv)
+{
+  int i, j=imat->rows();
+
+  for (i=imat->cols();i!=0;i--)
+    IMATELEM(*imat,j,i) = IMATELEM(*imat,rpiv,i);
+}
+
+static void ivSetRow(intvec *imat, int rowpos, int colpos)
+{
+  int i, j=imat->rows();
+
+  for (i=imat->cols();i!=0;i--)
+    IMATELEM(*imat,rowpos,i) = IMATELEM(*imat,j,i);
+  ivRowContent(imat, rowpos, colpos);
+}
+
+static void ivFreeRow(intvec *imat, int rowpos, int rpiv)
+{
+  int i, j;
+
+  for (j=rpiv-1;j>=rowpos;j--)
+  {
+    for (i=imat->cols();i!=0;i--)
+      IMATELEM(*imat,j+1,i) = IMATELEM(*imat,j,i);
+  }
+}
+
+static void ivReduce(intvec *imat, int rpiv, int colpos,
+                     int ready, int all)
+{
+  int tgcd, ce, m1, m2, j, i;
+  int piv = IMATELEM(*imat,rpiv,colpos);
+
+  for (j=all;j>ready;j--)
+  {
+    ivRowContent(imat, j, 1);
+    ce = IMATELEM(*imat,j,colpos);
+    if (ce!=0)
+    {
+      IMATELEM(*imat,j,colpos) = 0;
+      m1 = piv;
+      m2 = ce;
+      tgcd = ivGcd(m1, m2);
+      if (tgcd != 1)
+      {
+        m1 /= tgcd;
+        m2 /= tgcd;
+      }
+      for (i=imat->cols();i>colpos;i--)
+      {
+        IMATELEM(*imat,j,i) = IMATELEM(*imat,j,i)*m1-
+                              IMATELEM(*imat,rpiv,i)*m2;
+      }
+      ivRowContent(imat, j, colpos+1);
+    }
+  }
+}
+
+static void ivZeroElim(intvec *imat, int colpos,
+                     int ready, int &all)
+{
+  int j, i, k, l;
+
+  k = ready;
+  for (j=ready+1;j<=all;j++)
+  {
+    for (i=imat->cols();i>colpos;i--)
+    {
+      if (IMATELEM(*imat,j,i)!=0)
+      {
+        k++;
+        if (k<j)
+        {
+          for (l=imat->cols();l>colpos;l--)
+            IMATELEM(*imat,k,l) = IMATELEM(*imat,j,l);
+        }
+        break;
+      }
+    }
+  }
+  all = k;
+}
+
+static void ivRowContent(intvec *imat, int rowpos, int colpos)
+{
+  int tgcd, m;
+  int i=imat->cols();
+
+  loop
+  {
+    tgcd = IMATELEM(*imat,rowpos,i--);
+    if (tgcd!=0) break;
+    if (i<colpos) return;
+  }
+  if (tgcd<0) tgcd = -tgcd;
+  if (tgcd==1) return;
+  loop
+  {
+    m = IMATELEM(*imat,rowpos,i--);
+    if (m!=0) tgcd= ivGcd(tgcd, m);
+    if (tgcd==1) return;
+    if (i<colpos) break;
+  }
+  for (i=imat->cols();i>=colpos;i--)
+    IMATELEM(*imat,rowpos,i) /= tgcd;
+}
+
+static void ivKernFromRow(intvec *kern, intvec *imat,
+                          intvec *perm, int pos, int r, int c)
+{
+  int piv, cp, g, i, j, k, s;
+
+  for (i=c;i>(*perm)[r];i--)
+  {
+    IMATELEM(*kern,pos,i) = 1;
+    for (j=r;j!=0;j--)
+    {
+      cp = (*perm)[j];
+      s=0;
+      for(k=c;k>cp;k--)
+        s += IMATELEM(*imat,j,k)*IMATELEM(*kern,pos,k);
+      if (s!=0)
+      {
+        piv = IMATELEM(*imat,j,cp);
+        g = ivGcd(piv,s);
+        if (g!=1)
+        {
+          s /= g;
+          piv /= g;
+        }
+        for(k=c;k>cp;k--)
+          IMATELEM(*kern,pos,k) *= piv;
+        IMATELEM(*kern,pos,cp) = -s;
+        ivRowContent(kern,pos,cp);
+      }
+    }
+    if (IMATELEM(*kern,pos,i)<0)
+      ivNegRow(kern,pos);
+    pos--;
+  }
+}
+
+static int ivGcd(int a,int b)
+{
+  int x;
+
+  if (a<0) a=-a;
+  if (b<0) b=-b;
+  if (b>a)
+  {
+    x=b;
+    b=a;
+    a=x;
+  }
+  while (b!=0)
+  {
+    x = a % b;
+    a = b;
+    b = x;
+  }
+  return a;
+}
+
+static intvec * ivOptimizeKern(intvec *kern)
+{
+  int i,l,j,c=kern->cols(),r=kern->rows();
+  intvec *res=new intvec(c);
+
+  if (TEST_OPT_PROT)
+    Warn(" %d linear independent solutions\n",r);
+  for (i=r;i>1;i--)
+  {
+    for (j=c;j>0;j--)
+    {
+      (*res)[j-1] += IMATELEM(*kern,i,j);
+    }
+  }
+  ivContent(res);
+  if (r<11)
+  {
+    l = ivCondNumber(res,-c);
+    j = ivL1Norm(res);
+    ivOptRecursive(res, NULL, kern, l, j, r);
+  }
+  return res;
+}
+
+static void ivOptRecursive(intvec *res, intvec *w, intvec *kern,
+                          int &l, int &j, int pos)
+{
+  int m, k, d;
+  intvec *h;
+
+  d=kern->rows();
+  d=96/(d*d);
+  if (d<3) d=3;
+  if (w!=0)
+    h = new intvec(w);
+  else
+    h = new intvec(res->rows());
+  for (m=d;m>0;m--)
+  {
+    for(k=h->rows()-1;k>=0;k--)
+      (*h)[k] += IMATELEM(*kern,pos,k+1);
+    if(pos>1)
+      ivOptRecursive(res, h, kern, l, j, pos-1);
+    else
+      ivOptSolve(res, h, l, j);
+  }
+  delete h;
+  if (pos>1)
+    ivOptRecursive(res, w, kern, l, j, pos-1);
+  else if (w!=NULL)
+    ivOptSolve(res, w, l, j);
+}
+
+static void ivOptSolve(intvec *res, intvec *w, int &l, int &j)
+{
+  int l0, j0, k;
+
+  l0 = ivCondNumber(w, l);
+  if (l0==l)
+  {
+    ivContent(w);
+    j0 = ivL1Norm(w);
+    if(j0<j)
+    {
+      j = j0;
+      for(k=w->rows()-1;k>=0;k--)
+        (*res)[k] = (*w)[k];
+    }
+    return;
+  }
+  if(l0>l)
+  {
+    l = l0;
+    ivContent(w);
+    j = ivL1Norm(w);
+    for(k=w->rows()-1;k>=0;k--)
+      (*res)[k] = (*w)[k];
+  }
+}
+
+static int ivL1Norm(intvec *w)
+{
+  int i, j, s = 0;
+
+  for (i=w->rows()-1;i>=0;i--)
+  {
+    j = (*w)[i];
+    if (j>0)
+      s += j;
+    else
+      s -= j;
+  }
+  return s;
+}
+
+static int ivCondNumber(intvec *w, int l)
+{
+  int l0=0, i;
+
+  if (l<0)
+  {
+    for (i=w->rows()-1;i>=0;i--)
+    {
+      if ((*w)[i]<0) l0--;
+    }
+    if (l0==0)
+    {
+      for (i=w->rows()-1;i>=0;i--)
+      {
+        if ((*w)[i]>0) l0++;
+      }
+    }
+    return l0;
+  }
+  else
+  {
+    for (i=w->rows()-1;i>=0;i--)
+    {
+      if ((*w)[i]<0) return -1;
+    }
+    for (i=w->rows()-1;i>=0;i--)
+    {
+      if ((*w)[i]>0) l0++;
+    }
+    return l0;
+  }
+}
+
+static void ivContent(intvec *w)
+{
+  int tgcd, m;
+  int i=w->rows()-1;
+
+  loop
+  {
+    tgcd = (*w)[i--];
+    if (tgcd!=0) break;
+    if (i<0) return;
+  }
+  if (tgcd<0) tgcd = -tgcd;
+  if (tgcd==1) return;
+  loop
+  {
+    m = (*w)[i--];
+    if (m!=0) tgcd= ivGcd(tgcd, m);
+    if (tgcd==1) return;
+    if (i<0) break;
+  }
+  for (i=w->rows()-1;i>=0;i--)
+    (*w)[i] /= tgcd;
+}
+
+// columnwise concatination of two intvecs
+intvec * ivConcat(intvec * a, intvec * b)
+{
+  int ac=a->cols();
+  int c = ac + b->cols(); int r = si_max(a->rows(),b->rows());
+  intvec * ab = new intvec(r,c,0);
+
+  int i,j;
+  for (i=1; i<=a->rows(); i++)
+  {
+    for(j=1; j<=ac; j++)
+      IMATELEM(*ab,i,j) = IMATELEM(*a,i,j);
+  }
+  for (i=1; i<=b->rows(); i++)
+  {
+    for(j=1; j<=b->cols(); j++)
+      IMATELEM(*ab,i,j+ac) = IMATELEM(*b,i,j);
+  }
+  return ab;
+}
+
+#pragma GCC pop_options
+
+#endif
diff --git a/libpolys/misc/intvec.h b/libpolys/misc/intvec.h
new file mode 100644
index 0000000..81e0c06
--- /dev/null
+++ b/libpolys/misc/intvec.h
@@ -0,0 +1,161 @@
+#ifndef INTVEC_H
+#define INTVEC_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: class intvec: lists/vectors of integers
+*/
+#include <string.h>
+#include <omalloc/omalloc.h>
+#include <reporter/reporter.h>
+
+
+//extern omBin intvec_bin;
+
+class intvec
+{
+private:
+  int *v;
+  int row;
+  int col;
+public:
+
+  inline intvec(int l = 1)
+  {
+    assume(l > 0);
+    v = (int *)omAlloc0(sizeof(int)*l);
+    row = l;
+    col = 1;
+  }
+  intvec(int s, int e);
+  intvec(int r, int c, int init);
+  intvec(const intvec* iv)
+  {
+    assume( iv != NULL );
+    row = iv->rows();
+    col = iv->cols();
+    assume(row > 0);
+    assume(col > 0);
+    if (row*col>0)
+    {
+      v   = (int *)omAlloc(sizeof(int)*row*col);
+      for (int i=row*col-1;i>=0; i--)
+      {
+        v[i] = (*iv)[i];
+      }
+    }
+    else v=NULL;
+  }
+
+  void resize(int new_length);
+  inline int range(int i) const
+    { return ((i<row) && (i>=0) && (col==1)); }
+  inline int range(int i, int j) const
+    { return ((i<row) && (i>=0) && (j<col) && (j>=0)); }
+  inline int& operator[](int i)
+    {
+#ifndef SING_NDEBUG
+      if((i<0)||(i>=row*col))
+      {
+        Werror("wrong intvec index:%d\n",i);
+      }
+#endif
+      return v[i];
+    }
+  inline const int& operator[](int i) const
+    {
+#ifndef SING_NDEBUG
+      if((i<0)||(i>=row*col))
+      {
+        Werror("wrong intvec index:%d\n",i);
+      }
+#endif
+      return v[i];
+    }
+#define IMATELEM(M,I,J) (M)[(I-1)*(M).cols()+J-1]
+  void operator+=(int intop);
+  void operator-=(int intop);
+  void operator*=(int intop);
+  void operator/=(int intop);
+  void operator%=(int intop);
+  // -2: not compatible, -1: <, 0:=, 1: >
+  int compare(const intvec* o) const;
+  int compare(int o) const;
+  inline int  length() const { return col*row; }
+  inline int  cols() const { return col; }
+  inline int  rows() const { return row; }
+  inline void length(int l) { row = l; col = 1; }
+  void show(int mat=0,int spaces=0) const;
+  #ifndef SING_NDEBUG
+  void view() const;
+  #endif
+
+  inline void makeVector() { row*=col;col=1; }
+  char * String(int dim = 2) const;
+  char * ivString(int not_mat=1,int spaces=0, int dim=2) const;
+  inline ~intvec()
+    {
+      if (v!=NULL)
+      {
+        omFreeSize((ADDRESS)v,sizeof(int)*row*col);
+        v=NULL;
+      }
+    }
+  inline void ivTEST() const
+    {
+      omCheckAddrSize((ADDRESS)v,sizeof(int)*row*col);
+    }
+  inline int min_in()
+  {
+    int m=v[0];
+    for (int i=row*col-1; i>0; i--) if (v[i]<m) m=v[i];
+    return m;
+  }
+#if 0
+  // TODO: no omalloc Bin (de-)/allocation?
+  void* operator new ( size_t size )
+  {
+    void* addr;
+    //omTypeAlloc(void*, addr, size);
+    addr=omAlloc0Bin(intvec_bin);
+    return addr;
+  }
+  void operator delete ( void* block )
+  { //omfree( block );
+    omFreeBin((ADDRESS)block, intvec_bin);
+  }
+#endif
+  // keiner (ausser obachman) darf das folgenden benutzen !!!
+  inline int * ivGetVec() { return v; }
+};
+inline intvec * ivCopy(const intvec * o)
+{
+  if( o != NULL )
+    return new intvec(o);
+
+  return NULL;
+}
+
+intvec * ivAdd(intvec * a, intvec * b);
+intvec * ivSub(intvec * a, intvec * b);
+intvec * ivTranp(intvec * o);
+int      ivTrace(intvec * o);
+intvec * ivMult(intvec * a, intvec * b);
+//void     ivTriangMat(intvec * imat);
+void     ivTriangIntern(intvec * imat, int &ready, int &all);
+intvec * ivSolveKern(intvec * imat, int ready);
+intvec * ivConcat(intvec * a, intvec * b);
+
+#ifdef MDEBUG
+inline void ivTest(intvec * v)
+{
+  v->ivTEST();
+}
+#else
+#define ivTest(v) do {} while (0)
+#endif
+
+#undef INLINE_THIS
+
+#endif
diff --git a/libpolys/misc/mylimits.h b/libpolys/misc/mylimits.h
new file mode 100644
index 0000000..cfc6db7
--- /dev/null
+++ b/libpolys/misc/mylimits.h
@@ -0,0 +1,16 @@
+/* -*-c++-*- */
+/*******************************************************************
+ *  File:    mylimits.h
+ *  Purpose: limits.h configuration for omalloc
+ *  Author:  hannes (Hans Schoenemann)
+ *  Created: 03/01
+ *******************************************************************/
+#ifndef _MYLIMITS_H
+#define _MYLIMITS_H
+
+/* Maximum/minimum value an `signed int' (in Singular interpreter) can hold. */
+const int MAX_INT_VAL = 0x7fffffff;
+const int MAX_INT_LEN = 11;
+#include <limits.h>
+
+#endif /* _MYLIMITS_H */
diff --git a/libpolys/misc/options.c b/libpolys/misc/options.c
new file mode 100644
index 0000000..325b8ee
--- /dev/null
+++ b/libpolys/misc/options.c
@@ -0,0 +1,12 @@
+// the following initialization is needed for linkage on Mac OS X,
+// since initialized variables will be "D" (uninit. go to "C") segments
+#include <misc/options.h>
+unsigned si_opt_1 = 0;
+unsigned si_opt_2 = Sy_bit(V_QUIET)
+                   //| Sy_bit(V_QRING) // not default, as speed drops by 10 %
+		   | Sy_bit(V_REDEFINE)
+		   | Sy_bit(V_LOAD_LIB)
+		   | Sy_bit(V_SHOW_USE)
+		   | Sy_bit(V_PROMPT)
+		   ;
+
diff --git a/libpolys/misc/options.h b/libpolys/misc/options.h
new file mode 100644
index 0000000..9e7edfb
--- /dev/null
+++ b/libpolys/misc/options.h
@@ -0,0 +1,140 @@
+#ifndef OPTIONS_H
+#define OPTIONS_H
+/*****************************************
+ * *  Computer Algebra System SINGULAR      *
+ * *****************************************/
+/*
+ * ABSTRACT: macros for global options
+ */
+
+/*the general set of std-options : si_opt_1(test) */
+/*the general set of verbose-options : si_opt_2(verbose) */
+#ifdef __cplusplus
+extern "C" unsigned si_opt_1; //< NOTE: Original option variable name: test
+extern "C" unsigned si_opt_2; //< NOTE: Original option variable name: verbose
+#else
+extern unsigned si_opt_1;
+extern unsigned si_opt_2;
+#endif
+#define SI_SAVE_OPT(A,B) { A=si_opt_1; B=si_opt_2; }
+#define SI_SAVE_OPT1(A) { A=si_opt_1; }
+#define SI_SAVE_OPT2(A) { A=si_opt_2; }
+#define SI_RESTORE_OPT(A,B) { si_opt_1=A; si_opt_2=B; }
+#define SI_RESTORE_OPT1(A) { si_opt_1=A; }
+#define SI_RESTORE_OPT2(A) { si_opt_2=A; }
+
+/*
+**  Set operations (small sets only)
+*/
+
+#define Sy_bit(x)     ((unsigned)1<<(x))
+#define Sy_inset(x,s) ((Sy_bit(x)&(s))?TRUE:FALSE)
+#define BTEST1(a)     Sy_inset((a), si_opt_1)
+#define BVERBOSE(a)   Sy_inset((a), si_opt_2)
+
+/*
+** defines for BITSETs
+*/
+
+#define V_QUIET       0
+#define V_QRING       1
+#define V_SHOW_MEM    2
+#define V_YACC        3
+#define V_REDEFINE    4
+#define V_READING     5
+#define V_LOAD_LIB    6
+#define V_DEBUG_LIB   7
+#define V_LOAD_PROC   8
+#define V_DEF_RES     9
+
+#define V_SHOW_USE   11
+#define V_IMAP       12
+#define V_PROMPT     13
+#define V_NSB        14
+#define V_CONTENTSB  15
+#define V_CANCELUNIT 16
+#define V_MODPSOLVSB 17
+#define V_UPTORADICAL 18
+#define V_FINDMONOM  19
+#define V_COEFSTRAT  20
+#define V_IDLIFT     21
+#define V_LENGTH     22
+/*23: kDebugPrint */
+#define V_ALLWARN    24
+#define V_INTERSECT_ELIM 25
+#define V_INTERSECT_SYZ 26
+/* for tests: 27-30 */
+#define V_DEG_STOP   31
+
+
+#define OPT_PROT           0
+#define OPT_REDSB          1
+#define OPT_NOT_BUCKETS    2
+#define OPT_NOT_SUGAR      3
+#define OPT_INTERRUPT      4
+#define OPT_SUGARCRIT      5
+#define OPT_DEBUG          6
+#define OPT_REDTHROUGH     7
+#define OPT_NO_SYZ_MINIM   8
+#define OPT_RETURN_SB      9
+#define OPT_FASTHC        10
+#define OPT_OLDSTD        20
+
+#define OPT_STAIRCASEBOUND 22
+#define OPT_MULTBOUND     23
+#define OPT_DEGBOUND      24
+#define OPT_REDTAIL       25
+#define OPT_INTSTRATEGY   26
+#define OPT_FINDET        27
+#define OPT_INFREDTAIL    28
+#define OPT_SB_1          29
+#define OPT_NOTREGULARITY 30
+#define OPT_WEIGHTM       31
+
+/* define ring dependent options */
+#define TEST_RINGDEP_OPTS \
+ (Sy_bit(OPT_INTSTRATEGY) | Sy_bit(OPT_REDTHROUGH) | Sy_bit(OPT_REDTAIL))
+
+#define TEST_OPT_PROT              BTEST1(OPT_PROT)
+#define TEST_OPT_REDSB             BTEST1(OPT_REDSB)
+#define TEST_OPT_NOT_BUCKETS       BTEST1(OPT_NOT_BUCKETS)
+#define TEST_OPT_NOT_SUGAR         BTEST1(OPT_NOT_SUGAR)
+#define TEST_OPT_SUGARCRIT         BTEST1(OPT_SUGARCRIT)
+#define TEST_OPT_DEBUG             BTEST1(OPT_DEBUG)
+#define TEST_OPT_FASTHC            BTEST1(OPT_FASTHC)
+#define TEST_OPT_INTSTRATEGY       BTEST1(OPT_INTSTRATEGY)
+#define TEST_OPT_FINDET            BTEST1(OPT_FINDET)
+#define TEST_OPT_RETURN_SB         BTEST1(OPT_RETURN_SB)
+#define TEST_OPT_DEGBOUND          BTEST1(OPT_DEGBOUND)
+#define TEST_OPT_MULTBOUND         BTEST1(OPT_MULTBOUND)
+#define TEST_OPT_STAIRCASEBOUND    BTEST1(OPT_STAIRCASEBOUND)
+#define TEST_OPT_REDTAIL           BTEST1(OPT_REDTAIL)
+#define TEST_OPT_INFREDTAIL        BTEST1(OPT_INFREDTAIL)
+#define TEST_OPT_SB_1              BTEST1(OPT_SB_1)
+#define TEST_OPT_NOTREGULARITY     BTEST1(OPT_NOTREGULARITY)
+#define TEST_OPT_WEIGHTM           BTEST1(OPT_WEIGHTM)
+#define TEST_OPT_REDTHROUGH        BTEST1(OPT_REDTHROUGH)
+#define TEST_OPT_OLDSTD            BTEST1(OPT_OLDSTD)
+#define TEST_OPT_NO_SYZ_MINIM      BTEST1(OPT_NO_SYZ_MINIM)
+
+
+#define TEST_OPT_CONTENTSB         BVERBOSE(V_CONTENTSB)
+#define TEST_OPT_CANCELUNIT        BVERBOSE(V_CANCELUNIT)
+#define TEST_OPT_IDLIFT            BVERBOSE(V_IDLIFT)
+#define TEST_OPT_LENGTH            BVERBOSE(V_LENGTH)
+#define TEST_V_QRING               BVERBOSE(V_QRING)
+#define TEST_V_NSB                 BVERBOSE(V_NSB)
+#define TEST_V_QUIET               BVERBOSE(V_QUIET)
+
+#define TEST_VERB_NSB              BVERBOSE(V_NSB)
+#define TEST_V_DEG_STOP            BVERBOSE(V_DEG_STOP)
+#define TEST_V_MODPSOLVSB          BVERBOSE(V_MODPSOLVSB)
+#define TEST_V_COEFSTRAT           BVERBOSE(V_COEFSTRAT)
+#define TEST_V_UPTORADICAL         BVERBOSE(V_UPTORADICAL)
+#define TEST_V_FINDMONOM           BVERBOSE(V_FINDMONOM)
+#define TEST_V_ALLWARN             BVERBOSE(V_ALLWARN)
+#define TEST_V_INTERSECT_ELIM      BVERBOSE(V_INTERSECT_ELIM)
+#define TEST_V_INTERSECT_SYZ       BVERBOSE(V_INTERSECT_SYZ)
+
+
+#endif
diff --git a/libpolys/misc/sirandom.c b/libpolys/misc/sirandom.c
new file mode 100644
index 0000000..8d70ea6
--- /dev/null
+++ b/libpolys/misc/sirandom.c
@@ -0,0 +1,49 @@
+#include "sirandom.h"
+
+/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
+/*
+ *
+ *  A prime modulus multiplicative linear congruential
+ *  generator (PMMLCG), or "Lehmer generator".
+ *  Implementation directly derived from the article:
+ *
+ *        S. K. Park and K. W. Miller
+ *        Random Number Generators: Good Ones are Hard to Find
+ *        CACM vol 31, #10. Oct. 1988. pp 1192-1201.
+ *
+ *  Using the following multiplier and modulus, we obtain a
+ *  generator which:
+ *
+ *        1)  Has a full period: 1 to 2^31 - 2.
+ *        2)  Is testably "random" (see the article).
+ *        3)  Has a known implementation by E. L. Schrage.
+ */
+
+
+#define  A        16807        /*  A "good" multiplier          */
+#define  M   2147483647        /*  Modulus: 2^31 - 1          */
+#define  Q       127773        /*  M / A                  */
+#define  R         2836        /*  M % A                  */
+
+
+int siSeed = 1;
+
+int siRandNext(int r)
+{
+  r = A * (r % Q) - R * (r / Q);
+
+  if ( r < 0 )
+    r += M;
+
+  return( r );
+}
+
+int siRand()
+{
+  siSeed=siRandNext(siSeed);
+  return siSeed;
+}
+int siRandPlus1(int r)
+{
+  return r+1;
+}
diff --git a/libpolys/misc/sirandom.h b/libpolys/misc/sirandom.h
new file mode 100644
index 0000000..318fc02
--- /dev/null
+++ b/libpolys/misc/sirandom.h
@@ -0,0 +1,20 @@
+#ifndef SIRANDOM_H
+#define SIRANDOM_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern int siSeed;
+int siRand();
+
+typedef int (*siRandProc)();
+typedef int (*siRandProc1)(int);
+int siRandNext(int);
+int siRandPlus1(int);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+//
diff --git a/libpolys/polys/Makefile.am b/libpolys/polys/Makefile.am
new file mode 100644
index 0000000..3311a96
--- /dev/null
+++ b/libpolys/polys/Makefile.am
@@ -0,0 +1,138 @@
+ACLOCAL_AMFLAGS = -I ../../m4
+
+AM_CPPFLAGS	= -I${top_srcdir} -I${top_builddir} \
+${FACTORY_INCLUDES} ${RESOURCES_INCLUDES} ${OMALLOC_INCLUDES} \
+${FLINT_CFLAGS} ${NTL_CFLAGS} ${GMP_CFLAGS}
+
+
+if ENABLE_P_PROCS_STATIC
+  USE_P_PROCS_STATIC_CC = templates/p_Procs_Static.cc
+  USE_P_PROCS_STATIC = -Dp_Procs_Static
+else
+  USE_P_PROCS_STATIC_CC =
+  USE_P_PROCS_STATIC =
+endif
+
+if ENABLE_P_PROCS_DYNAMIC
+  USE_P_PROCS_DYNAMIC_CC = templates/p_Procs_Dynamic.cc
+  P_PROCS_CPPFLAGS_COMMON = ${AM_CPPFLAGS} -DDYNAMIC_VERSION
+else
+  USE_P_PROCS_DYNAMIC_CC =
+  P_PROCS_CPPFLAGS_COMMON = ${AM_CPPFLAGS}
+endif
+
+
+libpolys_LTLIBRARIES = libpolys.la
+libpolysdir = $(libdir)
+
+SOURCES = \
+	monomials/monomials.cc monomials/p_polys.cc monomials/ring.cc monomials/maps.cc \
+	operations/pShallowCopyDelete.cc operations/p_Mult_q.cc \
+	nc/sca.cc nc/summator.cc nc/ncSAFormula.cc nc/ncSACache.cc nc/ncSAMult.cc \
+	pDebug.cc polys0.cc prCopy.cc prCopyMacros.h \
+	kbuckets.cc sbuckets.cc weight.cc weight0.c simpleideals.cc matpol.cc \
+	sparsmat.cc \
+        ${USE_P_PROCS_STATIC_CC} ${USE_P_PROCS_DYNAMIC_CC} mod_raw.cc \
+        ext_fields/algext.cc ext_fields/transext.cc \
+	clapsing.cc clapconv.cc  flintconv.cc\
+	nc/old.gring.cc PolyEnumerator.cc
+
+LIBPOLYSHEADERS = monomials/ring.h monomials/monomials.h \
+  monomials/p_polys.h monomials/maps.h PolyEnumerator.h  prCopy.h \
+	nc/nc.h nc/sca.h nc/summator.h nc/ncSAFormula.h nc/ncSACache.h nc/ncSAMult.h nc/gb_hack.h \
+	operations/pShallowCopyDelete.h \
+	templates/p_Procs.h templates/p_MemAdd.h templates/p_MemCmp.h \
+	kbuckets.h sbuckets.h simpleideals.h weight.h matpol.h \
+	sparsmat.h clapsing.h clapconv.h coeffrings.h flintconv.h\
+	ext_fields/algext.h ext_fields/transext.h mod_raw.h
+
+EXTRA_DIST = \
+	prCopy.pl prCopyTemplate.cc \
+	templates/p_Procs_Lib.cc templates/p_MemCopy.h templates/p_Numbers.h \
+	templates/p_Procs_Set.h templates/p_Procs_Static.h templates/p_Procs_Dynamic.h \
+	templates/p_Procs_Impl.h templates/p_Delete__T.cc templates/p_Copy__T.cc \
+	templates/p_ShallowCopyDelete__T.cc templates/p_Mult_nn__T.cc \
+	templates/pp_Mult_nn__T.cc templates/pp_Mult_mm__T.cc templates/p_Mult_mm__T.cc \
+	templates/pp_Mult_Coeff_mm_DivSelect__T.cc templates/pp_Mult_nn__T.cc \
+	templates/pp_Mult_Coeff_mm_DivSelectMult__T.cc \
+	templates/pp_Mult_mm_Noether__T.cc operations/p_Mult_q.h \
+	templates/p_kBucketSetLm__T.cc templates/p_Minus_mm_Mult_qq__T.cc \
+	templates/p_Merge_q__T.cc templates/p_Add_q__T.cc templates/p_Neg__T.cc
+
+
+p_Procs_FieldGeneral_la_CPPFLAGS = -Dp_Procs_FieldGeneral ${P_PROCS_CPPFLAGS_COMMON}
+p_Procs_FieldIndep_la_CPPFLAGS = -Dp_Procs_FieldIndep ${P_PROCS_CPPFLAGS_COMMON}
+p_Procs_FieldQ_la_CPPFLAGS = -Dp_Procs_FieldQ ${P_PROCS_CPPFLAGS_COMMON}
+p_Procs_FieldZp_la_CPPFLAGS = -Dp_Procs_FieldZp ${P_PROCS_CPPFLAGS_COMMON}
+
+P_PROCS_MODULE_LDFLAGS = -shared -module -dynamic -export-dynamic -avoid-version -weak_reference_mismatches weak -undefined dynamic_lookup -Wl,-undefined -Wl,dynamic_lookup -flat_namespace
+
+p_Procs_FieldGeneral_la_LDFLAGS = ${P_PROCS_MODULE_LDFLAGS}
+p_Procs_FieldIndep_la_LDFLAGS = ${P_PROCS_MODULE_LDFLAGS}
+p_Procs_FieldQ_la_LDFLAGS = ${P_PROCS_MODULE_LDFLAGS}
+p_Procs_FieldZp_la_LDFLAGS = ${P_PROCS_MODULE_LDFLAGS}
+
+P_PROCS = templates/p_Procs_Lib.cc
+
+p_Procs_FieldGeneral_la_SOURCES = ${P_PROCS}
+p_Procs_FieldIndep_la_SOURCES = ${P_PROCS}
+p_Procs_FieldQ_la_SOURCES = ${P_PROCS}
+p_Procs_FieldZp_la_SOURCES = ${P_PROCS}
+
+
+moduledir = $(libexecdir)/singular/MOD
+
+if ENABLE_P_PROCS_DYNAMIC
+  module_LTLIBRARIES=p_Procs_FieldGeneral.la p_Procs_FieldIndep.la p_Procs_FieldQ.la p_Procs_FieldZp.la
+endif
+
+libpolys_includedir=$(includedir)/singular/polys
+
+nobase_libpolys_include_HEADERS = $(LIBPOLYSHEADERS)
+
+libpolys_la_SOURCES = ${SOURCES}
+
+EXTRA_libpolys_la_SOURCES = templates/p_Procs_Static.cc templates/p_Procs_Dynamic.cc
+
+libpolys_la_LDFLAGS= ${USEPPROCSDYNAMICLDFLAGS} ${USEPPROCSDYNAMICLD} -release ${PACKAGE_VERSION}
+libpolys_la_LIBADD = ${USEPPROCSDYNAMICLDFLAGS} ${USEPPROCSDYNAMICLD} ${top_builddir}/coeffs/libcoeffs.la
+
+
+#################################################
+# autogenerated sources
+
+BUILT_SOURCES = prCopy.inc templates/p_Procs.inc gftables MOD
+
+noinst_PROGRAMS = templates/p_Procs_Generate
+templates_p_Procs_Generate_SOURCES = templates/p_Procs_Generate.cc
+templates_p_Procs_Generate_CPPFLAGS = ${USE_P_PROCS_STATIC} ${AM_CPPFLAGS}
+templates_p_Procs_Generate_LDADD    = \
+${top_builddir}/reporter/libreporter.la ${top_builddir}/misc/libmisc.la
+
+templates/p_Procs.inc: templates/p_Procs_Generate$(EXEEXT)
+	${builddir}/templates/p_Procs_Generate$(EXEEXT) > ${builddir}/templates/p_Procs.inc
+
+prCopy.inc: prCopy.pl
+	perl ${srcdir}/prCopy.pl >  prCopy.inc
+
+CLEANFILES = $(BUILT_SOURCES)
+
+######################################################################
+
+TESTS = test
+check_PROGRAMS = $(TESTS)
+
+test_LDADD=libpolys.la \
+${top_builddir}/reporter/libreporter.la ${top_builddir}/misc/libmisc.la \
+$(FACTORY_LIBS) $(RESOURCES_LIBS) $(OMALLOC_LIBS) \
+$(FLINT_LIBS) $(GMP_LIBS) $(NTL_LIBS)
+
+test_SOURCES=test.cc
+
+gftables: ${top_srcdir}/../factory/gftables
+	ln -snf ${top_srcdir}/../factory/gftables ${builddir}/gftables
+
+MOD:
+	if [ -d "${top_builddir}/libpolys/polys/.libs" ]; then \
+	  ln -snf ${top_builddir}/libpolys/polys/.libs/ ${abs_builddir}/MOD; \
+	fi
diff --git a/libpolys/polys/Makefile.in b/libpolys/polys/Makefile.in
new file mode 100644
index 0000000..a522433
--- /dev/null
+++ b/libpolys/polys/Makefile.in
@@ -0,0 +1,1538 @@
+# Makefile.in generated by automake 1.13.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 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@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+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 = templates/p_Procs_Generate$(EXEEXT)
+TESTS = test$(EXEEXT)
+check_PROGRAMS = $(am__EXEEXT_1)
+subdir = polys
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/../build-aux/depcomp \
+	$(nobase_libpolys_include_HEADERS) \
+	$(top_srcdir)/../build-aux/test-driver
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/../m4/ax_append_compile_flags.m4 \
+	$(top_srcdir)/../m4/ax_append_flag.m4 \
+	$(top_srcdir)/../m4/ax_append_link_flags.m4 \
+	$(top_srcdir)/../m4/ax_check_compile_flag.m4 \
+	$(top_srcdir)/../m4/ax_check_link_flag.m4 \
+	$(top_srcdir)/../m4/ax_cxx_gcc_abi_demangle.m4 \
+	$(top_srcdir)/../m4/ax_prefix_config_h.m4 \
+	$(top_srcdir)/../m4/cpu-check.m4 $(top_srcdir)/../m4/flags.m4 \
+	$(top_srcdir)/../m4/flint-check.m4 \
+	$(top_srcdir)/../m4/gmp-check.m4 \
+	$(top_srcdir)/../m4/libtool.m4 \
+	$(top_srcdir)/../m4/ltoptions.m4 \
+	$(top_srcdir)/../m4/ltsugar.m4 \
+	$(top_srcdir)/../m4/ltversion.m4 \
+	$(top_srcdir)/../m4/lt~obsolete.m4 \
+	$(top_srcdir)/../m4/ntl-check.m4 \
+	$(top_srcdir)/../m4/options.m4 $(top_srcdir)/../m4/p-procs.m4 \
+	$(top_srcdir)/configure.ac
+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__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
+am__installdirs = "$(DESTDIR)$(libpolysdir)" "$(DESTDIR)$(moduledir)" \
+	"$(DESTDIR)$(libpolys_includedir)"
+LTLIBRARIES = $(libpolys_LTLIBRARIES) $(module_LTLIBRARIES)
+am__DEPENDENCIES_1 =
+libpolys_la_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+	${top_builddir}/coeffs/libcoeffs.la
+am__libpolys_la_SOURCES_DIST = monomials/monomials.cc \
+	monomials/p_polys.cc monomials/ring.cc monomials/maps.cc \
+	operations/pShallowCopyDelete.cc operations/p_Mult_q.cc \
+	nc/sca.cc nc/summator.cc nc/ncSAFormula.cc nc/ncSACache.cc \
+	nc/ncSAMult.cc pDebug.cc polys0.cc prCopy.cc prCopyMacros.h \
+	kbuckets.cc sbuckets.cc weight.cc weight0.c simpleideals.cc \
+	matpol.cc sparsmat.cc templates/p_Procs_Static.cc \
+	templates/p_Procs_Dynamic.cc mod_raw.cc ext_fields/algext.cc \
+	ext_fields/transext.cc clapsing.cc clapconv.cc flintconv.cc \
+	nc/old.gring.cc PolyEnumerator.cc
+am__dirstamp = $(am__leading_dot)dirstamp
+ at ENABLE_P_PROCS_STATIC_TRUE@am__objects_1 =  \
+ at ENABLE_P_PROCS_STATIC_TRUE@	templates/p_Procs_Static.lo
+ at ENABLE_P_PROCS_DYNAMIC_TRUE@am__objects_2 =  \
+ at ENABLE_P_PROCS_DYNAMIC_TRUE@	templates/p_Procs_Dynamic.lo
+am__objects_3 = monomials/monomials.lo monomials/p_polys.lo \
+	monomials/ring.lo monomials/maps.lo \
+	operations/pShallowCopyDelete.lo operations/p_Mult_q.lo \
+	nc/sca.lo nc/summator.lo nc/ncSAFormula.lo nc/ncSACache.lo \
+	nc/ncSAMult.lo pDebug.lo polys0.lo prCopy.lo kbuckets.lo \
+	sbuckets.lo weight.lo weight0.lo simpleideals.lo matpol.lo \
+	sparsmat.lo $(am__objects_1) $(am__objects_2) mod_raw.lo \
+	ext_fields/algext.lo ext_fields/transext.lo clapsing.lo \
+	clapconv.lo flintconv.lo nc/old.gring.lo PolyEnumerator.lo
+am_libpolys_la_OBJECTS = $(am__objects_3)
+libpolys_la_OBJECTS = $(am_libpolys_la_OBJECTS)
+AM_V_lt = $(am__v_lt_ at AM_V@)
+am__v_lt_ = $(am__v_lt_ at AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 = 
+libpolys_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+	$(CXXFLAGS) $(libpolys_la_LDFLAGS) $(LDFLAGS) -o $@
+p_Procs_FieldGeneral_la_LIBADD =
+am__objects_4 = templates/p_Procs_FieldGeneral_la-p_Procs_Lib.lo
+am_p_Procs_FieldGeneral_la_OBJECTS = $(am__objects_4)
+p_Procs_FieldGeneral_la_OBJECTS =  \
+	$(am_p_Procs_FieldGeneral_la_OBJECTS)
+p_Procs_FieldGeneral_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
+	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
+	$(AM_CXXFLAGS) $(CXXFLAGS) $(p_Procs_FieldGeneral_la_LDFLAGS) \
+	$(LDFLAGS) -o $@
+ at ENABLE_P_PROCS_DYNAMIC_TRUE@am_p_Procs_FieldGeneral_la_rpath =  \
+ at ENABLE_P_PROCS_DYNAMIC_TRUE@	-rpath $(moduledir)
+p_Procs_FieldIndep_la_LIBADD =
+am__objects_5 = templates/p_Procs_FieldIndep_la-p_Procs_Lib.lo
+am_p_Procs_FieldIndep_la_OBJECTS = $(am__objects_5)
+p_Procs_FieldIndep_la_OBJECTS = $(am_p_Procs_FieldIndep_la_OBJECTS)
+p_Procs_FieldIndep_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
+	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
+	$(AM_CXXFLAGS) $(CXXFLAGS) $(p_Procs_FieldIndep_la_LDFLAGS) \
+	$(LDFLAGS) -o $@
+ at ENABLE_P_PROCS_DYNAMIC_TRUE@am_p_Procs_FieldIndep_la_rpath = -rpath \
+ at ENABLE_P_PROCS_DYNAMIC_TRUE@	$(moduledir)
+p_Procs_FieldQ_la_LIBADD =
+am__objects_6 = templates/p_Procs_FieldQ_la-p_Procs_Lib.lo
+am_p_Procs_FieldQ_la_OBJECTS = $(am__objects_6)
+p_Procs_FieldQ_la_OBJECTS = $(am_p_Procs_FieldQ_la_OBJECTS)
+p_Procs_FieldQ_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
+	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
+	$(AM_CXXFLAGS) $(CXXFLAGS) $(p_Procs_FieldQ_la_LDFLAGS) \
+	$(LDFLAGS) -o $@
+ at ENABLE_P_PROCS_DYNAMIC_TRUE@am_p_Procs_FieldQ_la_rpath = -rpath \
+ at ENABLE_P_PROCS_DYNAMIC_TRUE@	$(moduledir)
+p_Procs_FieldZp_la_LIBADD =
+am__objects_7 = templates/p_Procs_FieldZp_la-p_Procs_Lib.lo
+am_p_Procs_FieldZp_la_OBJECTS = $(am__objects_7)
+p_Procs_FieldZp_la_OBJECTS = $(am_p_Procs_FieldZp_la_OBJECTS)
+p_Procs_FieldZp_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
+	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
+	$(AM_CXXFLAGS) $(CXXFLAGS) $(p_Procs_FieldZp_la_LDFLAGS) \
+	$(LDFLAGS) -o $@
+ at ENABLE_P_PROCS_DYNAMIC_TRUE@am_p_Procs_FieldZp_la_rpath = -rpath \
+ at ENABLE_P_PROCS_DYNAMIC_TRUE@	$(moduledir)
+am__EXEEXT_1 = test$(EXEEXT)
+PROGRAMS = $(noinst_PROGRAMS)
+am_templates_p_Procs_Generate_OBJECTS = templates/templates_p_Procs_Generate-p_Procs_Generate.$(OBJEXT)
+templates_p_Procs_Generate_OBJECTS =  \
+	$(am_templates_p_Procs_Generate_OBJECTS)
+templates_p_Procs_Generate_DEPENDENCIES =  \
+	${top_builddir}/reporter/libreporter.la \
+	${top_builddir}/misc/libmisc.la
+am_test_OBJECTS = test.$(OBJEXT)
+test_OBJECTS = $(am_test_OBJECTS)
+test_DEPENDENCIES = libpolys.la \
+	${top_builddir}/reporter/libreporter.la \
+	${top_builddir}/misc/libmisc.la $(am__DEPENDENCIES_1) \
+	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+	$(am__DEPENDENCIES_1)
+AM_V_P = $(am__v_P_ at AM_V@)
+am__v_P_ = $(am__v_P_ at AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_ at AM_V@)
+am__v_GEN_ = $(am__v_GEN_ at AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_ at AM_V@)
+am__v_at_ = $(am__v_at_ at AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+DEFAULT_INCLUDES = -I. at am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/../build-aux/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+	$(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_ at AM_V@)
+am__v_CC_ = $(am__v_CC_ at AM_DEFAULT_V@)
+am__v_CC_0 = @echo "  CC      " $@;
+am__v_CC_1 = 
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+	$(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_ at AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_ at AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo "  CCLD    " $@;
+am__v_CCLD_1 = 
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \
+	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+	$(AM_CXXFLAGS) $(CXXFLAGS)
+AM_V_CXX = $(am__v_CXX_ at AM_V@)
+am__v_CXX_ = $(am__v_CXX_ at AM_DEFAULT_V@)
+am__v_CXX_0 = @echo "  CXX     " $@;
+am__v_CXX_1 = 
+CXXLD = $(CXX)
+CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+	$(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CXXLD = $(am__v_CXXLD_ at AM_V@)
+am__v_CXXLD_ = $(am__v_CXXLD_ at AM_DEFAULT_V@)
+am__v_CXXLD_0 = @echo "  CXXLD   " $@;
+am__v_CXXLD_1 = 
+DIST_SOURCES = $(am__libpolys_la_SOURCES_DIST) \
+	$(EXTRA_libpolys_la_SOURCES) \
+	$(p_Procs_FieldGeneral_la_SOURCES) \
+	$(p_Procs_FieldIndep_la_SOURCES) $(p_Procs_FieldQ_la_SOURCES) \
+	$(p_Procs_FieldZp_la_SOURCES) \
+	$(templates_p_Procs_Generate_SOURCES) $(test_SOURCES)
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+HEADERS = $(nobase_libpolys_include_HEADERS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors_dummy = \
+  mgn= red= grn= lgn= blu= brg= std=; \
+  am__color_tests=no
+am__tty_colors = { \
+  $(am__tty_colors_dummy); \
+  if test "X$(AM_COLOR_TESTS)" = Xno; then \
+    am__color_tests=no; \
+  elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+    am__color_tests=yes; \
+  elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+    am__color_tests=yes; \
+  fi; \
+  if test $$am__color_tests = yes; then \
+    red=''; \
+    grn=''; \
+    lgn=''; \
+    blu=''; \
+    mgn=''; \
+    brg=''; \
+    std=''; \
+  fi; \
+}
+am__recheck_rx = ^[ 	]*:recheck:[ 	]*
+am__global_test_result_rx = ^[ 	]*:global-test-result:[ 	]*
+am__copy_in_global_log_rx = ^[ 	]*:copy-in-global-log:[ 	]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+  recheck = 1; \
+  while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+    { \
+      if (rc < 0) \
+        { \
+          if ((getline line2 < ($$0 ".log")) < 0) \
+	    recheck = 0; \
+          break; \
+        } \
+      else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+        { \
+          recheck = 0; \
+          break; \
+        } \
+      else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+        { \
+          break; \
+        } \
+    }; \
+  if (recheck) \
+    print $$0; \
+  close ($$0 ".trs"); \
+  close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+  print "fatal: making $@: " msg | "cat >&2"; \
+  exit 1; \
+} \
+function rst_section(header) \
+{ \
+  print header; \
+  len = length(header); \
+  for (i = 1; i <= len; i = i + 1) \
+    printf "="; \
+  printf "\n\n"; \
+} \
+{ \
+  copy_in_global_log = 1; \
+  global_test_result = "RUN"; \
+  while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+    { \
+      if (rc < 0) \
+         fatal("failed to read from " $$0 ".trs"); \
+      if (line ~ /$(am__global_test_result_rx)/) \
+        { \
+          sub("$(am__global_test_result_rx)", "", line); \
+          sub("[ 	]*$$", "", line); \
+          global_test_result = line; \
+        } \
+      else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+        copy_in_global_log = 0; \
+    }; \
+  if (copy_in_global_log) \
+    { \
+      rst_section(global_test_result ": " $$0); \
+      while ((rc = (getline line < ($$0 ".log"))) != 0) \
+      { \
+        if (rc < 0) \
+          fatal("failed to read from " $$0 ".log"); \
+        print line; \
+      }; \
+      printf "\n"; \
+    }; \
+  close ($$0 ".trs"); \
+  close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/   &   /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this.  Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+  --color-tests "$$am__color_tests" \
+  --enable-hard-errors "$$am__enable_hard_errors" \
+  --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test.  Creates the
+# directory for the log if needed.  Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log.  Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT.  Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup);					\
+$(am__vpath_adj_setup) $(am__vpath_adj)			\
+$(am__tty_colors);					\
+srcdir=$(srcdir); export srcdir;			\
+case "$@" in						\
+  */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;;	\
+    *) am__odir=.;; 					\
+esac;							\
+test "x$$am__odir" = x"." || test -d "$$am__odir" 	\
+  || $(MKDIR_P) "$$am__odir" || exit $$?;		\
+if test -f "./$$f"; then dir=./;			\
+elif test -f "$$f"; then dir=;				\
+else dir="$(srcdir)/"; fi;				\
+tst=$$dir$$f; log='$@'; 				\
+if test -n '$(DISABLE_HARD_ERRORS)'; then		\
+  am__enable_hard_errors=no; 				\
+else							\
+  am__enable_hard_errors=yes; 				\
+fi; 							\
+case " $(XFAIL_TESTS) " in				\
+  *[\ \	]$$f[\ \	]* | *[\ \	]$$dir$$f[\ \	]*) \
+    am__expect_failure=yes;;				\
+  *)							\
+    am__expect_failure=no;;				\
+esac; 							\
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed).  The result is saved in the shell variable
+# '$bases'.  This honors runtime overriding of TESTS and TEST_LOGS.  Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+  bases='$(TEST_LOGS)'; \
+  bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+  bases=`echo $$bases`
+RECHECK_LOGS = $(TEST_LOGS)
+AM_RECURSIVE_TARGETS = check recheck
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_DRIVER = $(SHELL) $(top_srcdir)/../build-aux/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+  case '$@' in \
+    */*) \
+      case '$*' in \
+        */*) b='$*';; \
+          *) b=`echo '$@' | sed 's/\.log$$//'`; \
+       esac;; \
+    *) \
+      b='$*';; \
+  esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT at .log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/../build-aux/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+	$(TEST_LOG_FLAGS)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+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@
+FACTORY_INCLUDES = @FACTORY_INCLUDES@
+FACTORY_LIBS = @FACTORY_LIBS@
+FGREP = @FGREP@
+FLINT_CFLAGS = @FLINT_CFLAGS@
+FLINT_HOME = @FLINT_HOME@
+FLINT_LIBS = @FLINT_LIBS@
+GMP_CFLAGS = @GMP_CFLAGS@
+GMP_HOME = @GMP_HOME@
+GMP_LIBS = @GMP_LIBS@
+GMP_VERSION = @GMP_VERSION@
+GREP = @GREP@
+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@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NTL_CFLAGS = @NTL_CFLAGS@
+NTL_LIBS = @NTL_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OMALLOC_INCLUDES = @OMALLOC_INCLUDES@
+OMALLOC_LIBS = @OMALLOC_LIBS@
+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@
+PKG_REQUIRE = @PKG_REQUIRE@
+POLYMAKE_CXXFLAGS = @POLYMAKE_CXXFLAGS@
+RANLIB = @RANLIB@
+RESOURCES_INCLUDES = @RESOURCES_INCLUDES@
+RESOURCES_LIBS = @RESOURCES_LIBS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SINGULAR_CFLAGS = @SINGULAR_CFLAGS@
+SI_CPU_I386 = @SI_CPU_I386@
+SI_CPU_IA64 = @SI_CPU_IA64@
+SI_CPU_PPC = @SI_CPU_PPC@
+SI_CPU_SPARC = @SI_CPU_SPARC@
+SI_CPU_X86_64 = @SI_CPU_X86_64@
+STRIP = @STRIP@
+USEPPROCSDYNAMICLD = @USEPPROCSDYNAMICLD@
+USEPPROCSDYNAMICLDFLAGS = @USEPPROCSDYNAMICLDFLAGS@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+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@
+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@
+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@
+ACLOCAL_AMFLAGS = -I ../../m4
+AM_CPPFLAGS = -I${top_srcdir} -I${top_builddir} \
+${FACTORY_INCLUDES} ${RESOURCES_INCLUDES} ${OMALLOC_INCLUDES} \
+${FLINT_CFLAGS} ${NTL_CFLAGS} ${GMP_CFLAGS}
+
+ at ENABLE_P_PROCS_STATIC_FALSE@USE_P_PROCS_STATIC_CC = 
+ at ENABLE_P_PROCS_STATIC_TRUE@USE_P_PROCS_STATIC_CC = templates/p_Procs_Static.cc
+ at ENABLE_P_PROCS_STATIC_FALSE@USE_P_PROCS_STATIC = 
+ at ENABLE_P_PROCS_STATIC_TRUE@USE_P_PROCS_STATIC = -Dp_Procs_Static
+ at ENABLE_P_PROCS_DYNAMIC_FALSE@USE_P_PROCS_DYNAMIC_CC = 
+ at ENABLE_P_PROCS_DYNAMIC_TRUE@USE_P_PROCS_DYNAMIC_CC = templates/p_Procs_Dynamic.cc
+ at ENABLE_P_PROCS_DYNAMIC_FALSE@P_PROCS_CPPFLAGS_COMMON = ${AM_CPPFLAGS}
+ at ENABLE_P_PROCS_DYNAMIC_TRUE@P_PROCS_CPPFLAGS_COMMON = ${AM_CPPFLAGS} -DDYNAMIC_VERSION
+libpolys_LTLIBRARIES = libpolys.la
+libpolysdir = $(libdir)
+SOURCES = \
+	monomials/monomials.cc monomials/p_polys.cc monomials/ring.cc monomials/maps.cc \
+	operations/pShallowCopyDelete.cc operations/p_Mult_q.cc \
+	nc/sca.cc nc/summator.cc nc/ncSAFormula.cc nc/ncSACache.cc nc/ncSAMult.cc \
+	pDebug.cc polys0.cc prCopy.cc prCopyMacros.h \
+	kbuckets.cc sbuckets.cc weight.cc weight0.c simpleideals.cc matpol.cc \
+	sparsmat.cc \
+        ${USE_P_PROCS_STATIC_CC} ${USE_P_PROCS_DYNAMIC_CC} mod_raw.cc \
+        ext_fields/algext.cc ext_fields/transext.cc \
+	clapsing.cc clapconv.cc  flintconv.cc\
+	nc/old.gring.cc PolyEnumerator.cc
+
+LIBPOLYSHEADERS = monomials/ring.h monomials/monomials.h \
+  monomials/p_polys.h monomials/maps.h PolyEnumerator.h  prCopy.h \
+	nc/nc.h nc/sca.h nc/summator.h nc/ncSAFormula.h nc/ncSACache.h nc/ncSAMult.h nc/gb_hack.h \
+	operations/pShallowCopyDelete.h \
+	templates/p_Procs.h templates/p_MemAdd.h templates/p_MemCmp.h \
+	kbuckets.h sbuckets.h simpleideals.h weight.h matpol.h \
+	sparsmat.h clapsing.h clapconv.h coeffrings.h flintconv.h\
+	ext_fields/algext.h ext_fields/transext.h mod_raw.h
+
+EXTRA_DIST = \
+	prCopy.pl prCopyTemplate.cc \
+	templates/p_Procs_Lib.cc templates/p_MemCopy.h templates/p_Numbers.h \
+	templates/p_Procs_Set.h templates/p_Procs_Static.h templates/p_Procs_Dynamic.h \
+	templates/p_Procs_Impl.h templates/p_Delete__T.cc templates/p_Copy__T.cc \
+	templates/p_ShallowCopyDelete__T.cc templates/p_Mult_nn__T.cc \
+	templates/pp_Mult_nn__T.cc templates/pp_Mult_mm__T.cc templates/p_Mult_mm__T.cc \
+	templates/pp_Mult_Coeff_mm_DivSelect__T.cc templates/pp_Mult_nn__T.cc \
+	templates/pp_Mult_Coeff_mm_DivSelectMult__T.cc \
+	templates/pp_Mult_mm_Noether__T.cc operations/p_Mult_q.h \
+	templates/p_kBucketSetLm__T.cc templates/p_Minus_mm_Mult_qq__T.cc \
+	templates/p_Merge_q__T.cc templates/p_Add_q__T.cc templates/p_Neg__T.cc
+
+p_Procs_FieldGeneral_la_CPPFLAGS = -Dp_Procs_FieldGeneral ${P_PROCS_CPPFLAGS_COMMON}
+p_Procs_FieldIndep_la_CPPFLAGS = -Dp_Procs_FieldIndep ${P_PROCS_CPPFLAGS_COMMON}
+p_Procs_FieldQ_la_CPPFLAGS = -Dp_Procs_FieldQ ${P_PROCS_CPPFLAGS_COMMON}
+p_Procs_FieldZp_la_CPPFLAGS = -Dp_Procs_FieldZp ${P_PROCS_CPPFLAGS_COMMON}
+P_PROCS_MODULE_LDFLAGS = -shared -module -dynamic -export-dynamic -avoid-version -weak_reference_mismatches weak -undefined dynamic_lookup -Wl,-undefined -Wl,dynamic_lookup -flat_namespace
+p_Procs_FieldGeneral_la_LDFLAGS = ${P_PROCS_MODULE_LDFLAGS}
+p_Procs_FieldIndep_la_LDFLAGS = ${P_PROCS_MODULE_LDFLAGS}
+p_Procs_FieldQ_la_LDFLAGS = ${P_PROCS_MODULE_LDFLAGS}
+p_Procs_FieldZp_la_LDFLAGS = ${P_PROCS_MODULE_LDFLAGS}
+P_PROCS = templates/p_Procs_Lib.cc
+p_Procs_FieldGeneral_la_SOURCES = ${P_PROCS}
+p_Procs_FieldIndep_la_SOURCES = ${P_PROCS}
+p_Procs_FieldQ_la_SOURCES = ${P_PROCS}
+p_Procs_FieldZp_la_SOURCES = ${P_PROCS}
+moduledir = $(libexecdir)/singular/MOD
+ at ENABLE_P_PROCS_DYNAMIC_TRUE@module_LTLIBRARIES = p_Procs_FieldGeneral.la p_Procs_FieldIndep.la p_Procs_FieldQ.la p_Procs_FieldZp.la
+libpolys_includedir = $(includedir)/singular/polys
+nobase_libpolys_include_HEADERS = $(LIBPOLYSHEADERS)
+libpolys_la_SOURCES = ${SOURCES}
+EXTRA_libpolys_la_SOURCES = templates/p_Procs_Static.cc templates/p_Procs_Dynamic.cc
+libpolys_la_LDFLAGS = ${USEPPROCSDYNAMICLDFLAGS} ${USEPPROCSDYNAMICLD} -release ${PACKAGE_VERSION}
+libpolys_la_LIBADD = ${USEPPROCSDYNAMICLDFLAGS} ${USEPPROCSDYNAMICLD} ${top_builddir}/coeffs/libcoeffs.la
+
+#################################################
+# autogenerated sources
+BUILT_SOURCES = prCopy.inc templates/p_Procs.inc gftables MOD
+templates_p_Procs_Generate_SOURCES = templates/p_Procs_Generate.cc
+templates_p_Procs_Generate_CPPFLAGS = ${USE_P_PROCS_STATIC} ${AM_CPPFLAGS}
+templates_p_Procs_Generate_LDADD = \
+${top_builddir}/reporter/libreporter.la ${top_builddir}/misc/libmisc.la
+
+CLEANFILES = $(BUILT_SOURCES)
+test_LDADD = libpolys.la \
+${top_builddir}/reporter/libreporter.la ${top_builddir}/misc/libmisc.la \
+$(FACTORY_LIBS) $(RESOURCES_LIBS) $(OMALLOC_LIBS) \
+$(FLINT_LIBS) $(GMP_LIBS) $(NTL_LIBS)
+
+test_SOURCES = test.cc
+all: $(BUILT_SOURCES)
+	$(MAKE) $(AM_MAKEFLAGS) all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .cc .lo .log .o .obj .test .test$(EXEEXT) .trs
+$(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) --foreign polys/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign polys/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-libpolysLTLIBRARIES: $(libpolys_LTLIBRARIES)
+	@$(NORMAL_INSTALL)
+	@list='$(libpolys_LTLIBRARIES)'; test -n "$(libpolysdir)" || list=; \
+	list2=; for p in $$list; do \
+	  if test -f $$p; then \
+	    list2="$$list2 $$p"; \
+	  else :; fi; \
+	done; \
+	test -z "$$list2" || { \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(libpolysdir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(libpolysdir)" || exit 1; \
+	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libpolysdir)'"; \
+	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libpolysdir)"; \
+	}
+
+uninstall-libpolysLTLIBRARIES:
+	@$(NORMAL_UNINSTALL)
+	@list='$(libpolys_LTLIBRARIES)'; test -n "$(libpolysdir)" || list=; \
+	for p in $$list; do \
+	  $(am__strip_dir) \
+	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libpolysdir)/$$f'"; \
+	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libpolysdir)/$$f"; \
+	done
+
+clean-libpolysLTLIBRARIES:
+	-test -z "$(libpolys_LTLIBRARIES)" || rm -f $(libpolys_LTLIBRARIES)
+	@list='$(libpolys_LTLIBRARIES)'; \
+	locs=`for p in $$list; do echo $$p; done | \
+	      sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+	      sort -u`; \
+	test -z "$$locs" || { \
+	  echo rm -f $${locs}; \
+	  rm -f $${locs}; \
+	}
+
+install-moduleLTLIBRARIES: $(module_LTLIBRARIES)
+	@$(NORMAL_INSTALL)
+	@list='$(module_LTLIBRARIES)'; test -n "$(moduledir)" || list=; \
+	list2=; for p in $$list; do \
+	  if test -f $$p; then \
+	    list2="$$list2 $$p"; \
+	  else :; fi; \
+	done; \
+	test -z "$$list2" || { \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(moduledir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(moduledir)" || exit 1; \
+	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(moduledir)'"; \
+	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(moduledir)"; \
+	}
+
+uninstall-moduleLTLIBRARIES:
+	@$(NORMAL_UNINSTALL)
+	@list='$(module_LTLIBRARIES)'; test -n "$(moduledir)" || list=; \
+	for p in $$list; do \
+	  $(am__strip_dir) \
+	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(moduledir)/$$f'"; \
+	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(moduledir)/$$f"; \
+	done
+
+clean-moduleLTLIBRARIES:
+	-test -z "$(module_LTLIBRARIES)" || rm -f $(module_LTLIBRARIES)
+	@list='$(module_LTLIBRARIES)'; \
+	locs=`for p in $$list; do echo $$p; done | \
+	      sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+	      sort -u`; \
+	test -z "$$locs" || { \
+	  echo rm -f $${locs}; \
+	  rm -f $${locs}; \
+	}
+monomials/$(am__dirstamp):
+	@$(MKDIR_P) monomials
+	@: > monomials/$(am__dirstamp)
+monomials/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) monomials/$(DEPDIR)
+	@: > monomials/$(DEPDIR)/$(am__dirstamp)
+monomials/monomials.lo: monomials/$(am__dirstamp) \
+	monomials/$(DEPDIR)/$(am__dirstamp)
+monomials/p_polys.lo: monomials/$(am__dirstamp) \
+	monomials/$(DEPDIR)/$(am__dirstamp)
+monomials/ring.lo: monomials/$(am__dirstamp) \
+	monomials/$(DEPDIR)/$(am__dirstamp)
+monomials/maps.lo: monomials/$(am__dirstamp) \
+	monomials/$(DEPDIR)/$(am__dirstamp)
+operations/$(am__dirstamp):
+	@$(MKDIR_P) operations
+	@: > operations/$(am__dirstamp)
+operations/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) operations/$(DEPDIR)
+	@: > operations/$(DEPDIR)/$(am__dirstamp)
+operations/pShallowCopyDelete.lo: operations/$(am__dirstamp) \
+	operations/$(DEPDIR)/$(am__dirstamp)
+operations/p_Mult_q.lo: operations/$(am__dirstamp) \
+	operations/$(DEPDIR)/$(am__dirstamp)
+nc/$(am__dirstamp):
+	@$(MKDIR_P) nc
+	@: > nc/$(am__dirstamp)
+nc/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) nc/$(DEPDIR)
+	@: > nc/$(DEPDIR)/$(am__dirstamp)
+nc/sca.lo: nc/$(am__dirstamp) nc/$(DEPDIR)/$(am__dirstamp)
+nc/summator.lo: nc/$(am__dirstamp) nc/$(DEPDIR)/$(am__dirstamp)
+nc/ncSAFormula.lo: nc/$(am__dirstamp) nc/$(DEPDIR)/$(am__dirstamp)
+nc/ncSACache.lo: nc/$(am__dirstamp) nc/$(DEPDIR)/$(am__dirstamp)
+nc/ncSAMult.lo: nc/$(am__dirstamp) nc/$(DEPDIR)/$(am__dirstamp)
+templates/$(am__dirstamp):
+	@$(MKDIR_P) templates
+	@: > templates/$(am__dirstamp)
+templates/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) templates/$(DEPDIR)
+	@: > templates/$(DEPDIR)/$(am__dirstamp)
+templates/p_Procs_Static.lo: templates/$(am__dirstamp) \
+	templates/$(DEPDIR)/$(am__dirstamp)
+templates/p_Procs_Dynamic.lo: templates/$(am__dirstamp) \
+	templates/$(DEPDIR)/$(am__dirstamp)
+ext_fields/$(am__dirstamp):
+	@$(MKDIR_P) ext_fields
+	@: > ext_fields/$(am__dirstamp)
+ext_fields/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) ext_fields/$(DEPDIR)
+	@: > ext_fields/$(DEPDIR)/$(am__dirstamp)
+ext_fields/algext.lo: ext_fields/$(am__dirstamp) \
+	ext_fields/$(DEPDIR)/$(am__dirstamp)
+ext_fields/transext.lo: ext_fields/$(am__dirstamp) \
+	ext_fields/$(DEPDIR)/$(am__dirstamp)
+nc/old.gring.lo: nc/$(am__dirstamp) nc/$(DEPDIR)/$(am__dirstamp)
+
+libpolys.la: $(libpolys_la_OBJECTS) $(libpolys_la_DEPENDENCIES) $(EXTRA_libpolys_la_DEPENDENCIES) 
+	$(AM_V_CXXLD)$(libpolys_la_LINK) -rpath $(libpolysdir) $(libpolys_la_OBJECTS) $(libpolys_la_LIBADD) $(LIBS)
+templates/p_Procs_FieldGeneral_la-p_Procs_Lib.lo:  \
+	templates/$(am__dirstamp) templates/$(DEPDIR)/$(am__dirstamp)
+
+p_Procs_FieldGeneral.la: $(p_Procs_FieldGeneral_la_OBJECTS) $(p_Procs_FieldGeneral_la_DEPENDENCIES) $(EXTRA_p_Procs_FieldGeneral_la_DEPENDENCIES) 
+	$(AM_V_CXXLD)$(p_Procs_FieldGeneral_la_LINK) $(am_p_Procs_FieldGeneral_la_rpath) $(p_Procs_FieldGeneral_la_OBJECTS) $(p_Procs_FieldGeneral_la_LIBADD) $(LIBS)
+templates/p_Procs_FieldIndep_la-p_Procs_Lib.lo:  \
+	templates/$(am__dirstamp) templates/$(DEPDIR)/$(am__dirstamp)
+
+p_Procs_FieldIndep.la: $(p_Procs_FieldIndep_la_OBJECTS) $(p_Procs_FieldIndep_la_DEPENDENCIES) $(EXTRA_p_Procs_FieldIndep_la_DEPENDENCIES) 
+	$(AM_V_CXXLD)$(p_Procs_FieldIndep_la_LINK) $(am_p_Procs_FieldIndep_la_rpath) $(p_Procs_FieldIndep_la_OBJECTS) $(p_Procs_FieldIndep_la_LIBADD) $(LIBS)
+templates/p_Procs_FieldQ_la-p_Procs_Lib.lo: templates/$(am__dirstamp) \
+	templates/$(DEPDIR)/$(am__dirstamp)
+
+p_Procs_FieldQ.la: $(p_Procs_FieldQ_la_OBJECTS) $(p_Procs_FieldQ_la_DEPENDENCIES) $(EXTRA_p_Procs_FieldQ_la_DEPENDENCIES) 
+	$(AM_V_CXXLD)$(p_Procs_FieldQ_la_LINK) $(am_p_Procs_FieldQ_la_rpath) $(p_Procs_FieldQ_la_OBJECTS) $(p_Procs_FieldQ_la_LIBADD) $(LIBS)
+templates/p_Procs_FieldZp_la-p_Procs_Lib.lo:  \
+	templates/$(am__dirstamp) templates/$(DEPDIR)/$(am__dirstamp)
+
+p_Procs_FieldZp.la: $(p_Procs_FieldZp_la_OBJECTS) $(p_Procs_FieldZp_la_DEPENDENCIES) $(EXTRA_p_Procs_FieldZp_la_DEPENDENCIES) 
+	$(AM_V_CXXLD)$(p_Procs_FieldZp_la_LINK) $(am_p_Procs_FieldZp_la_rpath) $(p_Procs_FieldZp_la_OBJECTS) $(p_Procs_FieldZp_la_LIBADD) $(LIBS)
+
+clean-checkPROGRAMS:
+	@list='$(check_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
+
+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
+templates/templates_p_Procs_Generate-p_Procs_Generate.$(OBJEXT):  \
+	templates/$(am__dirstamp) templates/$(DEPDIR)/$(am__dirstamp)
+
+templates/p_Procs_Generate$(EXEEXT): $(templates_p_Procs_Generate_OBJECTS) $(templates_p_Procs_Generate_DEPENDENCIES) $(EXTRA_templates_p_Procs_Generate_DEPENDENCIES) templates/$(am__dirstamp)
+	@rm -f templates/p_Procs_Generate$(EXEEXT)
+	$(AM_V_CXXLD)$(CXXLINK) $(templates_p_Procs_Generate_OBJECTS) $(templates_p_Procs_Generate_LDADD) $(LIBS)
+
+test$(EXEEXT): $(test_OBJECTS) $(test_DEPENDENCIES) $(EXTRA_test_DEPENDENCIES) 
+	@rm -f test$(EXEEXT)
+	$(AM_V_CXXLD)$(CXXLINK) $(test_OBJECTS) $(test_LDADD) $(LIBS)
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+	-rm -f ext_fields/*.$(OBJEXT)
+	-rm -f ext_fields/*.lo
+	-rm -f monomials/*.$(OBJEXT)
+	-rm -f monomials/*.lo
+	-rm -f nc/*.$(OBJEXT)
+	-rm -f nc/*.lo
+	-rm -f operations/*.$(OBJEXT)
+	-rm -f operations/*.lo
+	-rm -f templates/*.$(OBJEXT)
+	-rm -f templates/*.lo
+
+distclean-compile:
+	-rm -f *.tab.c
+
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/PolyEnumerator.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/clapconv.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/clapsing.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/flintconv.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/kbuckets.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/matpol.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/mod_raw.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/pDebug.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/polys0.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/prCopy.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/sbuckets.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/simpleideals.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/sparsmat.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/test.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/weight.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/weight0.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ext_fields/$(DEPDIR)/algext.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ext_fields/$(DEPDIR)/transext.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at monomials/$(DEPDIR)/maps.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at monomials/$(DEPDIR)/monomials.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at monomials/$(DEPDIR)/p_polys.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at monomials/$(DEPDIR)/ring.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at nc/$(DEPDIR)/ncSACache.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at nc/$(DEPDIR)/ncSAFormula.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at nc/$(DEPDIR)/ncSAMult.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at nc/$(DEPDIR)/old.gring.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at nc/$(DEPDIR)/sca.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at nc/$(DEPDIR)/summator.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at operations/$(DEPDIR)/pShallowCopyDelete.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at operations/$(DEPDIR)/p_Mult_q.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at templates/$(DEPDIR)/p_Procs_Dynamic.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at templates/$(DEPDIR)/p_Procs_FieldGeneral_la-p_Procs_Lib.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at templates/$(DEPDIR)/p_Procs_FieldIndep_la-p_Procs_Lib.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at templates/$(DEPDIR)/p_Procs_FieldQ_la-p_Procs_Lib.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at templates/$(DEPDIR)/p_Procs_FieldZp_la-p_Procs_Lib.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at templates/$(DEPDIR)/p_Procs_Static.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at templates/$(DEPDIR)/templates_p_Procs_Generate-p_Procs_Generate.Po at am__quote@
+
+.c.o:
+ at am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+ at am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+ at am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+ at am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+ at am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+ at am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+ at am__fastdepCC_TRUE@	$(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+.cc.o:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+ at am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXXCOMPILE) -c -o $@ $<
+
+.cc.obj:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+ at am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.cc.lo:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+ at am__fastdepCXX_TRUE@	$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LTCXXCOMPILE) -c -o $@ $<
+
+templates/p_Procs_FieldGeneral_la-p_Procs_Lib.lo: templates/p_Procs_Lib.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(p_Procs_FieldGeneral_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT templates/p_Procs_FieldGeneral_la-p_Procs_Lib.lo -MD -MP -MF templates/$(DEPDIR)/p_Procs_FieldGeneral_la-p_Procs_Lib.Tpo -c -o templates/p_Procs_FieldGeneral_la-p_Procs_Lib.lo `test -f 'templates/p_Procs_Lib.cc' || echo '$(srcdir)/'`templates/p_Procs_Lib.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) templates/$(DEPDIR)/p_Procs_FieldGeneral_la-p_Procs_Lib.Tpo templates/$(DEPDIR)/p_Procs_FieldGeneral_la-p_Procs_Lib.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='templates/p_Procs_Lib.cc' object='templates/p_Procs_FieldGeneral_la-p_Procs_Lib.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(p_Procs_FieldGeneral_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o templates/p_Procs_FieldGeneral_la-p_Procs_Lib.lo `test -f 'templates/p_Procs_Lib.cc' || echo '$(srcdir)/'`templates/p_Procs_Lib.cc
+
+templates/p_Procs_FieldIndep_la-p_Procs_Lib.lo: templates/p_Procs_Lib.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(p_Procs_FieldIndep_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT templates/p_Procs_FieldIndep_la-p_Procs_Lib.lo -MD -MP -MF templates/$(DEPDIR)/p_Procs_FieldIndep_la-p_Procs_Lib.Tpo -c -o templates/p_Procs_FieldIndep_la-p_Procs_Lib.lo `test -f 'templates/p_Procs_Lib.cc' || echo '$(srcdir)/'`templates/p_Procs_Lib.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) templates/$(DEPDIR)/p_Procs_FieldIndep_la-p_Procs_Lib.Tpo templates/$(DEPDIR)/p_Procs_FieldIndep_la-p_Procs_Lib.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='templates/p_Procs_Lib.cc' object='templates/p_Procs_FieldIndep_la-p_Procs_Lib.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(p_Procs_FieldIndep_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o templates/p_Procs_FieldIndep_la-p_Procs_Lib.lo `test -f 'templates/p_Procs_Lib.cc' || echo '$(srcdir)/'`templates/p_Procs_Lib.cc
+
+templates/p_Procs_FieldQ_la-p_Procs_Lib.lo: templates/p_Procs_Lib.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(p_Procs_FieldQ_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT templates/p_Procs_FieldQ_la-p_Procs_Lib.lo -MD -MP -MF templates/$(DEPDIR)/p_Procs_FieldQ_la-p_Procs_Lib.Tpo -c -o templates/p_Procs_FieldQ_la-p_Procs_Lib.lo `test -f 'templates/p_Procs_Lib.cc' || echo '$(srcdir)/'`templates/p_Procs_Lib.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) templates/$(DEPDIR)/p_Procs_FieldQ_la-p_Procs_Lib.Tpo templates/$(DEPDIR)/p_Procs_FieldQ_la-p_Procs_Lib.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='templates/p_Procs_Lib.cc' object='templates/p_Procs_FieldQ_la-p_Procs_Lib.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(p_Procs_FieldQ_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o templates/p_Procs_FieldQ_la-p_Procs_Lib.lo `test -f 'templates/p_Procs_Lib.cc' || echo '$(srcdir)/'`templates/p_Procs_Lib.cc
+
+templates/p_Procs_FieldZp_la-p_Procs_Lib.lo: templates/p_Procs_Lib.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(p_Procs_FieldZp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT templates/p_Procs_FieldZp_la-p_Procs_Lib.lo -MD -MP -MF templates/$(DEPDIR)/p_Procs_FieldZp_la-p_Procs_Lib.Tpo -c -o templates/p_Procs_FieldZp_la-p_Procs_Lib.lo `test -f 'templates/p_Procs_Lib.cc' || echo '$(srcdir)/'`templates/p_Procs_Lib.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) templates/$(DEPDIR)/p_Procs_FieldZp_la-p_Procs_Lib.Tpo templates/$(DEPDIR)/p_Procs_FieldZp_la-p_Procs_Lib.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='templates/p_Procs_Lib.cc' object='templates/p_Procs_FieldZp_la-p_Procs_Lib.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(p_Procs_FieldZp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o templates/p_Procs_FieldZp_la-p_Procs_Lib.lo `test -f 'templates/p_Procs_Lib.cc' || echo '$(srcdir)/'`templates/p_Procs_Lib.cc
+
+templates/templates_p_Procs_Generate-p_Procs_Generate.o: templates/p_Procs_Generate.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(templates_p_Procs_Generate_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT templates/templates_p_Procs_Generate-p_Procs_Generate.o -MD -MP -MF templates/$(DEPDIR)/templates_p_Procs_Generate-p_Procs_Generate.Tpo -c -o templates/templates_p_Procs_Generate-p_Procs_Generate.o `test -f 'templates/p_Procs_Generate.cc' || echo '$(srcdir)/'`templates/p_Procs_Generate.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) templates/$(DEPDIR)/templates_p_Procs_Generate-p_Procs_Generate.Tpo templates/$(DEPDIR)/templates_p_Procs_Generate-p_Procs_Generate.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='templates/p_Procs_Generate.cc' object='templates/templates_p_Procs_Generate-p_Procs_Generate.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(templates_p_Procs_Generate_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o templates/templates_p_Procs_Generate-p_Procs_Generate.o `test -f 'templates/p_Procs_Generate.cc' || echo '$(srcdir)/'`templates/p_Procs_Generate.cc
+
+templates/templates_p_Procs_Generate-p_Procs_Generate.obj: templates/p_Procs_Generate.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(templates_p_Procs_Generate_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT templates/templates_p_Procs_Generate-p_Procs_Generate.obj -MD -MP -MF templates/$(DEPDIR)/templates_p_Procs_Generate-p_Procs_Generate.Tpo -c -o templates/templates_p_Procs_Generate-p_Procs_Generate.obj `if test -f 'templates/p_Procs_Generate.cc'; then $(CYGPATH_W) 'templates/p_Procs_Generate.cc'; else $(CYGPATH_W) '$(srcdir)/tem [...]
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) templates/$(DEPDIR)/templates_p_Procs_Generate-p_Procs_Generate.Tpo templates/$(DEPDIR)/templates_p_Procs_Generate-p_Procs_Generate.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='templates/p_Procs_Generate.cc' object='templates/templates_p_Procs_Generate-p_Procs_Generate.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(templates_p_Procs_Generate_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o templates/templates_p_Procs_Generate-p_Procs_Generate.obj `if test -f 'templates/p_Procs_Generate.cc'; then $(CYGPATH_W) 'templates/p_Procs_Generate.cc'; else $(CYGPATH_W) '$(srcdir)/templates/p_Procs_Generate.cc'; fi`
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+	-rm -rf ext_fields/.libs ext_fields/_libs
+	-rm -rf monomials/.libs monomials/_libs
+	-rm -rf nc/.libs nc/_libs
+	-rm -rf operations/.libs operations/_libs
+	-rm -rf templates/.libs templates/_libs
+install-nobase_libpolys_includeHEADERS: $(nobase_libpolys_include_HEADERS)
+	@$(NORMAL_INSTALL)
+	@list='$(nobase_libpolys_include_HEADERS)'; test -n "$(libpolys_includedir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(libpolys_includedir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(libpolys_includedir)" || exit 1; \
+	fi; \
+	$(am__nobase_list) | while read dir files; do \
+	  xfiles=; for file in $$files; do \
+	    if test -f "$$file"; then xfiles="$$xfiles $$file"; \
+	    else xfiles="$$xfiles $(srcdir)/$$file"; fi; done; \
+	  test -z "$$xfiles" || { \
+	    test "x$$dir" = x. || { \
+	      echo " $(MKDIR_P) '$(DESTDIR)$(libpolys_includedir)/$$dir'"; \
+	      $(MKDIR_P) "$(DESTDIR)$(libpolys_includedir)/$$dir"; }; \
+	    echo " $(INSTALL_HEADER) $$xfiles '$(DESTDIR)$(libpolys_includedir)/$$dir'"; \
+	    $(INSTALL_HEADER) $$xfiles "$(DESTDIR)$(libpolys_includedir)/$$dir" || exit $$?; }; \
+	done
+
+uninstall-nobase_libpolys_includeHEADERS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(nobase_libpolys_include_HEADERS)'; test -n "$(libpolys_includedir)" || list=; \
+	$(am__nobase_strip_setup); files=`$(am__nobase_strip)`; \
+	dir='$(DESTDIR)$(libpolys_includedir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	$(am__define_uniq_tagged_files); \
+	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-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	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"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'.  Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+	rm -f $< $@
+	$(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+	@:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+	@$(am__set_TESTS_bases); \
+	am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+	redo_bases=`for i in $$bases; do \
+	              am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+	            done`; \
+	if test -n "$$redo_bases"; then \
+	  redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+	  redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+	  if $(am__make_dryrun); then :; else \
+	    rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+	  fi; \
+	fi; \
+	if test -n "$$am__remaking_logs"; then \
+	  echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+	       "recursion detected" >&2; \
+	else \
+	  am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+	fi; \
+	if $(am__make_dryrun); then :; else \
+	  st=0;  \
+	  errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+	  for i in $$redo_bases; do \
+	    test -f $$i.trs && test -r $$i.trs \
+	      || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+	    test -f $$i.log && test -r $$i.log \
+	      || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+	  done; \
+	  test $$st -eq 0 || exit 1; \
+	fi
+	@$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+	ws='[ 	]'; \
+	results=`for b in $$bases; do echo $$b.trs; done`; \
+	test -n "$$results" || results=/dev/null; \
+	all=`  grep "^$$ws*:test-result:"           $$results | wc -l`; \
+	pass=` grep "^$$ws*:test-result:$$ws*PASS"  $$results | wc -l`; \
+	fail=` grep "^$$ws*:test-result:$$ws*FAIL"  $$results | wc -l`; \
+	skip=` grep "^$$ws*:test-result:$$ws*SKIP"  $$results | wc -l`; \
+	xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+	xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+	error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+	if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+	  success=true; \
+	else \
+	  success=false; \
+	fi; \
+	br='==================='; br=$$br$$br$$br$$br; \
+	result_count () \
+	{ \
+	    if test x"$$1" = x"--maybe-color"; then \
+	      maybe_colorize=yes; \
+	    elif test x"$$1" = x"--no-color"; then \
+	      maybe_colorize=no; \
+	    else \
+	      echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+	    fi; \
+	    shift; \
+	    desc=$$1 count=$$2; \
+	    if test $$maybe_colorize = yes && test $$count -gt 0; then \
+	      color_start=$$3 color_end=$$std; \
+	    else \
+	      color_start= color_end=; \
+	    fi; \
+	    echo "$${color_start}# $$desc $$count$${color_end}"; \
+	}; \
+	create_testsuite_report () \
+	{ \
+	  result_count $$1 "TOTAL:" $$all   "$$brg"; \
+	  result_count $$1 "PASS: " $$pass  "$$grn"; \
+	  result_count $$1 "SKIP: " $$skip  "$$blu"; \
+	  result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+	  result_count $$1 "FAIL: " $$fail  "$$red"; \
+	  result_count $$1 "XPASS:" $$xpass "$$red"; \
+	  result_count $$1 "ERROR:" $$error "$$mgn"; \
+	}; \
+	{								\
+	  echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" |	\
+	    $(am__rst_title);						\
+	  create_testsuite_report --no-color;				\
+	  echo;								\
+	  echo ".. contents:: :depth: 2";				\
+	  echo;								\
+	  for b in $$bases; do echo $$b; done				\
+	    | $(am__create_global_log);					\
+	} >$(TEST_SUITE_LOG).tmp || exit 1;				\
+	mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG);			\
+	if $$success; then						\
+	  col="$$grn";							\
+	 else								\
+	  col="$$red";							\
+	  test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG);		\
+	fi;								\
+	echo "$${col}$$br$${std}"; 					\
+	echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}";	\
+	echo "$${col}$$br$${std}"; 					\
+	create_testsuite_report --maybe-color;				\
+	echo "$$col$$br$$std";						\
+	if $$success; then :; else					\
+	  echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}";		\
+	  if test -n "$(PACKAGE_BUGREPORT)"; then			\
+	    echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}";	\
+	  fi;								\
+	  echo "$$col$$br$$std";					\
+	fi;								\
+	$$success || exit 1
+
+check-TESTS:
+	@list='$(RECHECK_LOGS)';           test -z "$$list" || rm -f $$list
+	@list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+	@test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+	@set +e; $(am__set_TESTS_bases); \
+	log_list=`for i in $$bases; do echo $$i.log; done`; \
+	trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+	log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+	$(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+	exit $$?;
+recheck: all $(check_PROGRAMS)
+	@test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+	@set +e; $(am__set_TESTS_bases); \
+	bases=`for i in $$bases; do echo $$i; done \
+	         | $(am__list_recheck_tests)` || exit 1; \
+	log_list=`for i in $$bases; do echo $$i.log; done`; \
+	log_list=`echo $$log_list`; \
+	$(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+	        am__force_recheck=am--force-recheck \
+	        TEST_LOGS="$$log_list"; \
+	exit $$?
+test.log: test$(EXEEXT)
+	@p='test$(EXEEXT)'; \
+	b='test'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+.test.log:
+	@p='$<'; \
+	$(am__set_b); \
+	$(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+ at am__EXEEXT_TRUE@.test$(EXEEXT).log:
+ at am__EXEEXT_TRUE@	@p='$<'; \
+ at am__EXEEXT_TRUE@	$(am__set_b); \
+ at am__EXEEXT_TRUE@	$(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ at am__EXEEXT_TRUE@	--log-file $$b.log --trs-file $$b.trs \
+ at am__EXEEXT_TRUE@	$(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ at am__EXEEXT_TRUE@	"$$tst" $(AM_TESTS_FD_REDIRECT)
+
+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_PROGRAMS)
+	$(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: $(BUILT_SOURCES)
+	$(MAKE) $(AM_MAKEFLAGS) check-am
+all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(HEADERS)
+installdirs:
+	for dir in "$(DESTDIR)$(libpolysdir)" "$(DESTDIR)$(moduledir)" "$(DESTDIR)$(libpolys_includedir)"; 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:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+	-test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+	-test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+	-test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+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)
+	-rm -f ext_fields/$(DEPDIR)/$(am__dirstamp)
+	-rm -f ext_fields/$(am__dirstamp)
+	-rm -f monomials/$(DEPDIR)/$(am__dirstamp)
+	-rm -f monomials/$(am__dirstamp)
+	-rm -f nc/$(DEPDIR)/$(am__dirstamp)
+	-rm -f nc/$(am__dirstamp)
+	-rm -f operations/$(DEPDIR)/$(am__dirstamp)
+	-rm -f operations/$(am__dirstamp)
+	-rm -f templates/$(DEPDIR)/$(am__dirstamp)
+	-rm -f templates/$(am__dirstamp)
+
+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-checkPROGRAMS clean-generic clean-libpolysLTLIBRARIES \
+	clean-libtool clean-moduleLTLIBRARIES clean-noinstPROGRAMS \
+	mostlyclean-am
+
+distclean: distclean-am
+	-rm -rf ./$(DEPDIR) ext_fields/$(DEPDIR) monomials/$(DEPDIR) nc/$(DEPDIR) operations/$(DEPDIR) templates/$(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-libpolysLTLIBRARIES install-moduleLTLIBRARIES \
+	install-nobase_libpolys_includeHEADERS
+
+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) ext_fields/$(DEPDIR) monomials/$(DEPDIR) nc/$(DEPDIR) operations/$(DEPDIR) templates/$(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-libpolysLTLIBRARIES \
+	uninstall-moduleLTLIBRARIES \
+	uninstall-nobase_libpolys_includeHEADERS
+
+.MAKE: all check check-am install install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am clean \
+	clean-checkPROGRAMS clean-generic clean-libpolysLTLIBRARIES \
+	clean-libtool clean-moduleLTLIBRARIES clean-noinstPROGRAMS \
+	cscopelist-am ctags ctags-am 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-libpolysLTLIBRARIES \
+	install-man install-moduleLTLIBRARIES \
+	install-nobase_libpolys_includeHEADERS 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 \
+	recheck tags tags-am uninstall uninstall-am \
+	uninstall-libpolysLTLIBRARIES uninstall-moduleLTLIBRARIES \
+	uninstall-nobase_libpolys_includeHEADERS
+
+
+templates/p_Procs.inc: templates/p_Procs_Generate$(EXEEXT)
+	${builddir}/templates/p_Procs_Generate$(EXEEXT) > ${builddir}/templates/p_Procs.inc
+
+prCopy.inc: prCopy.pl
+	perl ${srcdir}/prCopy.pl >  prCopy.inc
+
+gftables: ${top_srcdir}/../factory/gftables
+	ln -snf ${top_srcdir}/../factory/gftables ${builddir}/gftables
+
+MOD:
+	if [ -d "${top_builddir}/libpolys/polys/.libs" ]; then \
+	  ln -snf ${top_builddir}/libpolys/polys/.libs/ ${abs_builddir}/MOD; \
+	fi
+
+# 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/libpolys/polys/PolyEnumerator.cc b/libpolys/polys/PolyEnumerator.cc
new file mode 100644
index 0000000..aaf0b7d
--- /dev/null
+++ b/libpolys/polys/PolyEnumerator.cc
@@ -0,0 +1,9 @@
+
+
+
+
+#include <misc/auxiliary.h>
+
+#include "PolyEnumerator.h"
+
+const spolyrec CBasePolyEnumerator::m_prevposition_struct = {}; // it is assumed to zero-out all of the struct!
diff --git a/libpolys/polys/PolyEnumerator.h b/libpolys/polys/PolyEnumerator.h
new file mode 100644
index 0000000..b39f6fb
--- /dev/null
+++ b/libpolys/polys/PolyEnumerator.h
@@ -0,0 +1,227 @@
+// -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+/*****************************************************************************\
+ * Computer Algebra System SINGULAR
+\*****************************************************************************/
+/** @file PolyEnumerator.h
+ *
+ * Concrete implementation of enumerators over polynomials
+ *
+ * @author Oleksandr Motsak
+ *
+ *
+ **/
+/*****************************************************************************/
+
+#ifndef POLYENUMERATOR_H
+#define POLYENUMERATOR_H
+
+// include basic definitions
+#include <coeffs/Enumerator.h>
+#include <polys/monomials/monomials.h>
+#include <reporter/reporter.h> // for assume etc.
+
+/** @class CBasePolyEnumerator
+ *
+ * Base polynomial enumerator for simple iteration over terms of polynomials.
+ *
+ * Note that the first element desn't exist directly after Reset() call.
+ *
+ * The class doesn't inherit from IAccessor and thus doesn't override Current().
+ *
+ * @sa IBaseEnumerator, @sa CPolyCoeffsEnumerator
+ */
+class CBasePolyEnumerator: public virtual IBaseEnumerator
+{
+  template <class T>
+  friend class CRecursivePolyCoeffsEnumerator;
+  private:
+    poly m_poly; ///< essentially immutable original iterable object
+
+    static const spolyrec m_prevposition_struct; ///< tag for "-1" position
+
+  protected:
+    poly m_position; ///< current position in the iterable object
+
+  public:
+    virtual bool IsValid() const
+    {
+      // not -1 or past the end position?
+      return (m_position != NULL) && (m_position != &m_prevposition_struct);
+    }
+
+
+    /// Reset this polynomial Enumerator with a different input polynomial
+    void Reset(poly p)
+    {
+      m_poly = p;
+      m_position = const_cast<poly>(&m_prevposition_struct);
+      assume( !IsValid() );
+    }
+
+    /// This enumerator is an empty polynomial by default
+    CBasePolyEnumerator(poly p = NULL):
+        IBaseEnumerator(), m_poly(p), m_position(const_cast<poly>(&m_prevposition_struct))
+    {
+      assume( !IsValid() );
+    }
+
+    /// Sets the position marker to the leading term.
+    virtual void Reset()
+    {
+      m_position = const_cast<poly>(&m_prevposition_struct);
+      assume( !IsValid() );
+    }
+
+
+    /// Advances the position to the next term of the polynomial.
+    /// returns true if the position marker was successfully advanced to the
+    /// next term which can be used;
+    /// false if the position marker has passed the end of the
+    /// polynomial.
+    virtual bool MoveNext()
+    {
+      assume( m_position != NULL );
+
+      {
+        const poly p_next = pNext(m_position);
+
+        if (p_next != NULL) // not the last term?
+        {
+          m_position = p_next;
+          assume( IsValid() );
+          return true;
+        }
+      }
+
+      if (m_position == &m_prevposition_struct) // -1 position?
+      {
+        assume( !IsValid() );
+        m_position = m_poly;
+        return (m_position != NULL);
+      }
+
+      // else: past the end (or an empty polynomial)
+      m_position = NULL;
+      assume( !IsValid() );
+      return false;
+    }
+};
+
+
+/// This is the interface we use in coeffs.h for ClearDenominators and
+/// ClearContent.
+typedef IEnumerator<number> IPolyCoeffsEnumerator;
+
+/** @class CPolyCoeffsEnumerator
+ *
+ * This is a polynomial enumerator for simple iteration over
+ * coefficients of polynomials.
+ *
+ * It is required to inherit this class from IEnumerator<number> for
+ * its use in coeffs and implement IAccessor<number> interface.
+ *
+ * Note also the virtual multiple inheritance due to the diamond
+ * problem of inheriting both CBasePolyEnumerator and IEnumerator<T>
+ * from IBaseEnumerator.
+ *
+ * @sa CBasePolyEnumerator, @sa IEnumerator
+ */
+class CPolyCoeffsEnumerator: public CBasePolyEnumerator, public virtual IPolyCoeffsEnumerator
+{
+  public:
+    CPolyCoeffsEnumerator(poly p): CBasePolyEnumerator(p) {}
+
+    /// Gets the current element in the collection (read and write).
+    virtual IPolyCoeffsEnumerator::reference Current()
+    {
+      assume( IsValid() );
+      return pGetCoeff(m_position);
+    }
+
+    /// Gets the current element in the collection (read only).
+    virtual IPolyCoeffsEnumerator::const_reference Current() const
+    {
+      assume( IsValid() );
+      return pGetCoeff(m_position);
+    }
+};
+
+
+struct NAConverter
+{
+  static inline poly convert(const number& n)
+  {
+    // suitable for alg. ext. numbers that are just polys actually
+    return (poly)n;
+  }
+};
+
+/// go into polynomials over an alg. extension recursively
+template <class ConverterPolicy>
+class CRecursivePolyCoeffsEnumerator: public IPolyCoeffsEnumerator
+{
+  private:
+    IPolyCoeffsEnumerator& m_global_enumerator; ///< iterates the input polynomial
+    CBasePolyEnumerator m_local_enumerator; ///< iterates the current coeff. of m_global_enumerator
+
+  protected:
+    virtual bool IsValid() const
+    {
+      return m_global_enumerator.IsValid() &&  m_local_enumerator.IsValid();
+    }
+
+  public:
+
+    /// NOTE: carefull: don't destruct the input enumerator before doing it with this one...
+    /// this also changes the original IPolyCoeffsEnumerator& itr!
+    CRecursivePolyCoeffsEnumerator(IPolyCoeffsEnumerator& itr): m_global_enumerator(itr), m_local_enumerator(NULL) {}
+
+    virtual bool MoveNext()
+    {
+      if( m_local_enumerator.MoveNext() )
+        return true;
+
+      if( !m_global_enumerator.MoveNext() ) // at the end of the main input polynomial?
+        return false;
+
+      // TODO: make the following changeable (metaprogramming: use policy?),
+      // leave the following as default option...
+      poly p = ConverterPolicy::convert(m_global_enumerator.Current()); // Assumes that these numbers are just polynomials!
+      assume( p != NULL );
+
+      // the followig actually needs CPolyCoeffsEnumerator
+      m_local_enumerator.Reset( p ); // -1 position in p :: to be skipped now!
+
+      if( m_local_enumerator.MoveNext() ) // should be true
+        return true;
+
+      assume( FALSE ); return MoveNext(); // this should not happen as p should be non-zero, but just in case...
+    }
+
+    virtual void Reset()
+    {
+      m_global_enumerator.Reset();
+      m_local_enumerator.Reset(NULL);
+    }
+
+    /// Gets the current element in the collection (read and write).
+    virtual IPolyCoeffsEnumerator::reference Current()
+    {
+      assume( IsValid() );
+      return pGetCoeff(m_local_enumerator.m_position);
+    }
+
+    /// Gets the current element in the collection (read only).
+    virtual IPolyCoeffsEnumerator::const_reference Current() const
+    {
+      assume( IsValid() );
+      return pGetCoeff(m_local_enumerator.m_position);
+    }
+};
+
+
+#endif
+/* #ifndef POLYENUMERATOR_H */
+
+// Vi-modeline: vim: filetype=c:syntax:shiftwidth=2:tabstop=8:textwidth=0:expandtab
+
diff --git a/libpolys/polys/clapconv.cc b/libpolys/polys/clapconv.cc
new file mode 100644
index 0000000..ec320ef
--- /dev/null
+++ b/libpolys/polys/clapconv.cc
@@ -0,0 +1,427 @@
+// emacs edit mode for this file is -*- C++ -*-
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: convert data between Singular and factory
+*/
+
+
+
+
+
+#include <misc/auxiliary.h>
+#include <omalloc/omalloc.h>
+
+#include <factory/factory.h>
+
+#include <coeffs/coeffs.h>
+
+#include <coeffs/longrat.h> // snumber is necessary
+
+#include <polys/monomials/p_polys.h>
+#include <polys/sbuckets.h>
+#include <polys/clapconv.h>
+
+#include "simpleideals.h"
+
+#define TRANSEXT_PRIVATES
+#include <polys/ext_fields/transext.h>
+
+void out_cf(const char *s1,const CanonicalForm &f,const char *s2);
+
+static void conv_RecPP ( const CanonicalForm & f, int * exp, sBucket_pt result, ring r );
+
+static void convRecTrP ( const CanonicalForm & f, int * exp, poly & result, int offs, const ring r );
+
+//static void convRecGFGF ( const CanonicalForm & f, int * exp, poly & result );
+
+static number convFactoryNSingAN( const CanonicalForm &f, const ring r);
+
+poly convFactoryPSingP ( const CanonicalForm & f, const ring r )
+{
+  int n = rVar(r)+1;
+  /* ASSERT( level( f ) <= pVariables, "illegal number of variables" ); */
+  int * exp = (int*)omAlloc0(n*sizeof(int));
+  sBucket_pt result_bucket=sBucketCreate(r);
+  conv_RecPP( f, exp, result_bucket, r );
+  poly result; int dummy;
+  sBucketDestroyMerge(result_bucket,&result,&dummy);
+  omFreeSize((ADDRESS)exp,n*sizeof(int));
+  return result;
+}
+
+static void conv_RecPP ( const CanonicalForm & f, int * exp, sBucket_pt result, ring r )
+{
+  if (f.isZero())
+    return;
+  if ( ! f.inCoeffDomain() )
+  {
+    int l = f.level();
+    for ( CFIterator i = f; i.hasTerms(); i++ )
+    {
+      exp[l] = i.exp();
+      conv_RecPP( i.coeff(), exp, result, r );
+    }
+    exp[l] = 0;
+  }
+  else
+  {
+    poly term = p_Init(r);
+    pNext( term ) = NULL;
+    for ( int i = 1; i <= r->N; i++ )
+      p_SetExp( term, i, exp[i], r);
+    pGetCoeff( term )=r->cf->convFactoryNSingN(f, r->cf);
+    p_Setm( term, r );
+    if ( n_IsZero(pGetCoeff(term), r->cf) )
+    {
+      p_Delete(&term,r);
+    }
+    else
+    {
+      sBucket_Merge_p(result,term,1);
+    }
+  }
+}
+
+
+CanonicalForm convSingPFactoryP( poly p, const ring r )
+{
+  CanonicalForm result = 0;
+  int e, n = rVar(r);
+  BOOLEAN setChar=TRUE;
+
+  p=pReverse(p);
+  poly op=p;
+  while ( p!=NULL )
+  {
+    CanonicalForm term;
+    term=r->cf->convSingNFactoryN(pGetCoeff( p ),setChar, r->cf);
+    if (errorreported) break;
+    setChar=FALSE;
+    for ( int i = n; i >0; i-- )
+    {
+      if ( (e = p_GetExp( p, i, r)) != 0 )
+        term *= power( Variable( i ), e );
+    }
+    result += term;
+    pIter( p );
+ }
+ op=pReverse(op);
+ return result;
+}
+
+int convFactoryISingI( const CanonicalForm & f)
+{
+  if (!f.isImm()) WerrorS("int overflow in det");
+  return f.intval();
+}
+
+CanonicalForm convSingAPFactoryAP ( poly p , const Variable & a, const ring r)
+{
+  CanonicalForm result = 0;
+  int e, n = r-> N;
+  int off=rPar(r);
+
+  if (!rField_is_Zp_a(r))
+    On(SW_RATIONAL);
+  while ( p!=NULL)
+  {
+    CanonicalForm term=convSingAFactoryA(((poly)p_GetCoeff(p, r->cf->extRing)),a, r);
+    for ( int i = 1; i <= n; i++ )
+    {
+      if ( (e = p_GetExp( p, i, r )) != 0 )
+        term *= power( Variable( i + off), e );
+    }
+    result += term;
+    pIter( p );
+  }
+  return result;
+}
+
+static void
+convRecAP_R ( const CanonicalForm & f, int * exp, poly & result, int par_start, int var_start, const ring r) ;
+
+poly convFactoryAPSingAP_R ( const CanonicalForm & f, int par_start, int var_start, const ring r )
+{
+  int n = rVar(r)+rPar(r)+1;
+  int * exp = (int *)omAlloc0(n*sizeof(int));
+  poly result = NULL;
+  convRecAP_R( f, exp, result,par_start, var_start, r );
+  omFreeSize((ADDRESS)exp,n*sizeof(int));
+  return result;
+}
+
+poly convFactoryAPSingAP ( const CanonicalForm & f, const ring r )
+{
+  return convFactoryAPSingAP_R(f,0,rPar(r),r);
+}
+
+static void convRecAP_R ( const CanonicalForm & f, int * exp, poly & result, int par_start, int var_start, const ring r )
+{
+  if (f.isZero())
+    return;
+  if ( ! f.inCoeffDomain() )
+  {
+    int l = f.level();
+    for ( CFIterator i = f; i.hasTerms(); i++ )
+    {
+      exp[l] = i.exp();
+      convRecAP_R( i.coeff(), exp, result, par_start, var_start, r);
+    }
+    exp[l] = 0;
+  }
+  else
+  {
+    poly z=(poly)convFactoryASingA( f,r );
+    if (z!=NULL)
+    {
+      poly term = p_Init(r);
+      pNext( term ) = NULL;
+      int i;
+      for ( i = rVar(r); i>0 ; i-- )
+        p_SetExp( term, i , exp[i+var_start],r);
+      //if (rRing_has_Comp(currRing->extRing)) p_SetComp(term, 0, currRing->extRing); // done by pInit
+      if (par_start==0)
+      {
+        for ( i = 1; i <= var_start; i++ )
+        //z->e[i-1]+=exp[i];
+          p_AddExp(z,i,exp[i],r->cf->extRing);
+      }
+      else
+      {
+        for ( i = par_start+1; i <= var_start+rPar(r); i++ )
+        //z->e[i-1]+=exp[i];
+          p_AddExp(z,i,exp[i-par_start],r->cf->extRing);
+      }
+      pGetCoeff(term)=(number)ALLOC0_RNUMBER();
+      p_GetCoeff(term, r->cf->extRing)=(number) z;
+      p_Setm( term,r );
+      result = p_Add_q( result, term, r );
+    }
+  }
+}
+
+CanonicalForm convSingAFactoryA ( poly p , const Variable & a, const ring r )
+{
+  CanonicalForm result = 0;
+  int e;
+
+  while ( p!=NULL )
+  {
+    CanonicalForm term;
+    if ( rField_is_Zp_a(r) )
+    {
+      term = n_Int( p_GetCoeff( p, r->cf->extRing ), r->cf->extRing->cf );
+    }
+    else
+    {
+      if ( SR_HDL(p_GetCoeff( p, r->cf->extRing )) & SR_INT )
+        term = SR_TO_INT(p_GetCoeff( p, r->cf->extRing )) ;
+      else
+      {
+        if ( p_GetCoeff( p, r->cf->extRing )->s == 3 )
+        {
+          mpz_t dummy;
+          mpz_init_set( dummy, (p_GetCoeff( p,r->cf->extRing )->z) );
+          term = make_cf( dummy );
+        }
+        else
+        {
+          // assume s==0 or s==1
+          mpz_t num, den;
+          On(SW_RATIONAL);
+          mpz_init_set( num, (p_GetCoeff( p, r->cf->extRing )->z) );
+          mpz_init_set( den, (p_GetCoeff( p, r->cf->extRing )->n) );
+          term = make_cf( num, den, ( p_GetCoeff( p, r->cf->extRing )->s != 1 ));
+        }
+      }
+    }
+    if ( (e = p_GetExp( p, 1, r->cf->extRing )) != 0 )
+      term *= power( a , e );
+    result += term;
+    p = pNext( p );
+  }
+  return result;
+}
+
+static number convFactoryNSingAN( const CanonicalForm &f, const ring r)
+{
+  assume (r != NULL);
+  assume (r->cf != NULL);
+  assume (r->cf->extRing != NULL);
+  // r->cf->extRing->cf has to be Q or Z/p (the supported types of factory)
+  return n_convFactoryNSingN( f, r->cf->extRing->cf );
+}
+
+poly convFactoryASingA ( const CanonicalForm & f, const ring r )
+{
+  poly a=NULL;
+  poly t;
+  for( CFIterator i=f; i.hasTerms(); i++)
+  {
+    t= p_Init (r->cf->extRing);
+    p_GetCoeff(t, r->cf->extRing)= convFactoryNSingAN( i.coeff(), r );
+    if (n_IsZero(p_GetCoeff(t,r->cf->extRing),r->cf->extRing->cf))
+    {
+      p_Delete(&t,r->cf->extRing);
+    }
+    else
+    {
+      p_SetExp(t,1,i.exp(),r->cf->extRing);
+      a=p_Add_q(a,t,r->cf->extRing);
+    }
+  }
+  if (a!=NULL)
+  {
+    if( r->cf->extRing != NULL )
+      if (r->cf->extRing->qideal->m[0]!=NULL)
+      {
+        poly l=r->cf->extRing->qideal->m[0];
+        if (p_GetExp(a,1,r->cf->extRing) >= p_GetExp(l,1,r->cf->extRing))
+          a = p_PolyDiv (a, l, FALSE, r->cf->extRing); // ???
+      }
+  }
+  return a;
+}
+
+CanonicalForm convSingTrPFactoryP ( poly p, const ring r )
+{
+  CanonicalForm result = 0;
+  int e, n = rVar(r);
+  int offs = rPar(r);
+
+  while ( p!=NULL )
+  {
+    n_Normalize(p_GetCoeff(p, r), r->cf);
+
+    // test if denominator is constant
+    if (!p_IsConstantPoly(DEN (p_GetCoeff (p,r)),r->cf->extRing) && !errorreported)
+      WerrorS("conversion error: denominator!= 1");
+
+    CanonicalForm term=convSingPFactoryP(NUM (p_GetCoeff(p, r)),r->cf->extRing);
+
+    // if denominator is not NULL it should be a constant at this point
+    if (DEN (p_GetCoeff(p,r)) != NULL)
+    {
+      CanonicalForm den= convSingPFactoryP(DEN (p_GetCoeff(p, r)),r->cf->extRing);
+      if (rChar (r) == 0)
+        On (SW_RATIONAL);
+      term /= den;
+    }
+
+    for ( int i = n; i > 0; i-- )
+    {
+      if ( (e = p_GetExp( p, i,r )) != 0 )
+        term = term * power( Variable( i + offs ), e );
+    }
+    result += term;
+    p = pNext( p );
+  }
+  return result;
+}
+
+poly convFactoryPSingTrP ( const CanonicalForm & f, const ring r )
+{
+  int n = rVar(r)+1;
+  int * exp = (int*)omAlloc0(n*sizeof(int));
+  poly result = NULL;
+  convRecTrP( f, exp, result , rPar(r), r );
+  omFreeSize((ADDRESS)exp,n*sizeof(int));
+  return result;
+}
+
+static void
+convRecTrP ( const CanonicalForm & f, int * exp, poly & result , int offs, const ring r)
+{
+  if (f.isZero())
+    return;
+  if ( f.level() > offs )
+  {
+    int l = f.level();
+    for ( CFIterator i = f; i.hasTerms(); i++ )
+    {
+      exp[l-offs] = i.exp();
+      convRecTrP( i.coeff(), exp, result, offs, r );
+    }
+    exp[l-offs] = 0;
+  }
+  else
+  {
+    poly term = p_Init(r);
+    pNext( term ) = NULL;
+    for ( int i = rVar(r); i>0; i-- )
+      p_SetExp( term, i ,exp[i], r);
+    //if (rRing_has_Comp(currRing)) p_SetComp(term, 0, currRing); // done by pInit
+    pGetCoeff(term)=ntInit(convFactoryPSingP( f, r->cf->extRing ), r->cf);
+    p_Setm( term,r );
+    result = p_Add_q( result, term,r );
+  }
+}
+
+#if 0
+CanonicalForm
+convSingGFFactoryGF( poly p )
+{
+  CanonicalForm result=CanonicalForm(0);
+  int e, n = pVariables;
+
+  while ( p != NULL )
+  {
+    CanonicalForm term;
+    term = make_cf_from_gf( (int)(long)pGetCoeff( p ) );
+    //int * A=(int *)&term;
+    //Print("term=%x, == 0 ?: %d\n",*A, term.isZero());
+    for ( int i = 1; i <= n; i++ )
+    {
+      if ( (e = pGetExp( p, i )) != 0 )
+         term *= power( Variable( i ), e );
+    }
+    result += term;
+    p = pNext( p );
+  }
+  return result;
+}
+
+poly
+convFactoryGFSingGF ( const CanonicalForm & f )
+{
+//    cerr << " f = " << f << endl;
+  int n = pVariables+1;
+  /* ASSERT( level( f ) <= pVariables, "illegal number of variables" ); */
+  int * exp = (int*)omAlloc0(n*sizeof(int));
+  poly result = NULL;
+  convRecGFGF( f, exp, result );
+  omFreeSize((ADDRESS)exp,n*sizeof(int));
+  return result;
+}
+
+static void
+convRecGFGF ( const CanonicalForm & f, int * exp, poly & result )
+{
+  if (f.isZero())
+    return;
+  if ( ! f.inCoeffDomain() )
+  {
+    int l = f.level();
+    for ( CFIterator i = f; i.hasTerms(); i++ )
+    {
+      exp[l] = i.exp();
+      convRecGFGF( i.coeff(), exp, result );
+    }
+    exp[l] = 0;
+  }
+  else
+  {
+    poly term = pInit();
+    pNext( term ) = NULL;
+    for ( int i = 1; i <= pVariables; i++ )
+      pSetExp( term, i, exp[i]);
+    //if (rRing_has_Comp(currRing)) p_SetComp(term, 0, currRing); // done by pInit
+    pGetCoeff( term ) = (number) gf_value (f);
+    pSetm( term );
+    result = pAdd( result, term );
+  }
+}
+
+#endif
diff --git a/libpolys/polys/clapconv.h b/libpolys/polys/clapconv.h
new file mode 100644
index 0000000..cd0988e
--- /dev/null
+++ b/libpolys/polys/clapconv.h
@@ -0,0 +1,34 @@
+// emacs edit mode for this file is -*- C++ -*-
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: convert data between Singular and factory
+*/
+
+
+#ifndef INCL_SINGCONV_H
+#define INCL_SINGCONV_H
+
+#include <polys/monomials/ring.h>
+#include <factory/factory.h>
+
+
+poly convFactoryPSingP ( const CanonicalForm & f, const ring r );
+CanonicalForm convSingPFactoryP( poly p, const ring r );
+int convFactoryISingI( const CanonicalForm & f);
+
+CanonicalForm convSingAPFactoryAP ( poly p , const Variable & a, const ring r );
+poly convFactoryAPSingAP ( const CanonicalForm & f, const ring r );
+poly convFactoryAPSingAP_R ( const CanonicalForm & f, int par_start, int var_start );
+
+//CanonicalForm convSingGFFactoryGF ( poly p, const ring r );
+//poly convFactoryGFSingGF ( const CanonicalForm & f, const ring r );
+
+CanonicalForm convSingAFactoryA ( poly p , const Variable & a, const ring r );
+poly convFactoryASingA ( const CanonicalForm & f, const ring r );
+
+CanonicalForm convSingTrPFactoryP ( poly p, const ring r );
+poly convFactoryPSingTrP ( const CanonicalForm & f, const ring r );
+
+#endif /* INCL_SINGCONV_H */
diff --git a/libpolys/polys/clapsing.cc b/libpolys/polys/clapsing.cc
new file mode 100644
index 0000000..13664d7
--- /dev/null
+++ b/libpolys/polys/clapsing.cc
@@ -0,0 +1,1843 @@
+// emacs edit mode for this file is -*- C++ -*-
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: interface between Singular and factory
+*/
+
+//#define FACTORIZE2_DEBUG
+
+
+
+
+
+
+
+#include <misc/auxiliary.h>
+#include "clapsing.h"
+
+#include <factory/factory.h>
+
+#include <omalloc/omalloc.h>
+#include <coeffs/numbers.h>
+#include <coeffs/coeffs.h>
+#include <coeffs/bigintmat.h>
+
+// #include <kernel/ffields.h>
+
+#include "monomials/ring.h"
+#include "simpleideals.h"
+
+
+//#include "polys.h"
+#define TRANSEXT_PRIVATES
+
+#include "ext_fields/transext.h"
+
+
+#include "clapconv.h"
+// #include <kernel/clapconv.h>
+
+#include <polys/monomials/p_polys.h>
+#include <polys/monomials/ring.h>
+#include <polys/simpleideals.h>
+#include <misc/intvec.h>
+#include <polys/matpol.h>
+#include <coeffs/bigintmat.h>
+
+
+void out_cf(const char *s1,const CanonicalForm &f,const char *s2);
+
+poly singclap_gcd_r ( poly f, poly g, const ring r )
+{
+  poly res=NULL;
+
+  assume(f!=NULL);
+  assume(g!=NULL);
+
+  if(pNext(f)==NULL && pNext(g)==NULL)
+  {
+    poly p=p_One(r);
+    for(int i=rVar(r);i>0;i--)
+      p_SetExp(p,i,si_min(p_GetExp(f,i,r),p_GetExp(g,i,r)),r);
+    if (rField_is_Ring(r))
+    {
+      number c = p_GetCoeff(f,r);
+      number d = p_GetCoeff(g,r);
+      p_SetCoeff(p,n_Gcd(c,d,r->cf),r);
+    }
+    p_Setm(p,r);
+    return p;
+#if 0
+    else
+    {
+      poly h=g;
+      for(int i=rVar(r);i>0;i--)
+        p_SetExp(p,i,p_GetExp(f,i,r),r);
+      while(h!=NULL)
+      {
+        for(int i=rVar(r);i>0;i--)
+          p_SetExp(p,i,si_min(p_GetExp(p,i,r),p_GetExp(h,i,r)),r);
+        pIter(h);
+      }
+      p_Setm(p,r);
+      return p;
+    }
+#endif
+  }
+#if 0
+  else if (pNext(g)==NULL)
+  {
+    poly p=p_One(r);
+    poly h=f;
+    for(int i=rVar(r);i>0;i--)
+      p_SetExp(p,i,p_GetExp(g,i,r),r);
+    if (rField_is_Ring(r))
+    {
+      number c = p_GetCoeff(f,r);
+      number d = p_GetCoeff(g,r);
+      p_SetCoeff(p,n_Gcd(c,d,r->cf),r);
+    }
+    while(h!=NULL)
+    {
+      for(int i=rVar(r);i>0;i--)
+        p_SetExp(p,i,si_min(p_GetExp(p,i,r),p_GetExp(h,i,r)),r);
+      pIter(h);
+    }
+    p_Setm(p,r);
+    return p;
+  }
+#endif
+
+  Off(SW_RATIONAL);
+  if (rField_is_Q(r) || rField_is_Zp(r) || rField_is_Ring_Z(r))
+  {
+    setCharacteristic( rChar(r) );
+    CanonicalForm F( convSingPFactoryP( f,r ) ), G( convSingPFactoryP( g, r ) );
+    res=convFactoryPSingP( gcd( F, G ) , r);
+  }
+  // and over Q(a) / Fp(a)
+  else if ( r->cf->extRing!=NULL )
+  {
+    if ( rField_is_Q_a(r)) setCharacteristic( 0 );
+    else                   setCharacteristic( rChar(r) );
+    if (r->cf->extRing->qideal!=NULL)
+    {
+      bool b1=isOn(SW_USE_QGCD);
+      if ( rField_is_Q_a(r) ) On(SW_USE_QGCD);
+      CanonicalForm mipo=convSingPFactoryP(r->cf->extRing->qideal->m[0],
+                                           r->cf->extRing);
+      Variable a=rootOf(mipo);
+      CanonicalForm F( convSingAPFactoryAP( f,a,r ) ),
+                    G( convSingAPFactoryAP( g,a,r ) );
+      res= convFactoryAPSingAP( gcd( F, G ),r );
+      prune (a);
+      if (!b1) Off(SW_USE_QGCD);
+    }
+    else
+    {
+      CanonicalForm F( convSingTrPFactoryP( f,r ) ), G( convSingTrPFactoryP( g,r ) );
+      res= convFactoryPSingTrP( gcd( F, G ),r );
+    }
+  }
+  else
+    WerrorS( feNotImplemented );
+  Off(SW_RATIONAL);
+  return res;
+}
+
+poly singclap_gcd_and_divide ( poly& f, poly& g, const ring r)
+{
+  poly res=NULL;
+
+  if (g == NULL)
+  {
+    res= p_Copy (f,r);
+    p_Delete (&f, r);
+    f=p_One (r);
+    return res;
+  }
+  if (f==NULL)
+  {
+    res= p_Copy (g,r);
+    p_Delete (&g, r);
+    g=p_One (r);
+    return res;
+  }
+
+  Off(SW_RATIONAL);
+  CanonicalForm F,G,GCD;
+  if (rField_is_Q(r) || (rField_is_Zp(r)))
+  {
+    bool b1=isOn(SW_USE_EZGCD_P);
+    setCharacteristic( rChar(r) );
+    F=convSingPFactoryP( f,r );
+    G=convSingPFactoryP( g,r );
+    GCD=gcd(F,G);
+    if (!GCD.isOne())
+    {
+      p_Delete(&f,r);
+      p_Delete(&g,r);
+      if (getCharacteristic() == 0)
+        On (SW_RATIONAL);
+      F /= GCD;
+      G /= GCD;
+      if (getCharacteristic() == 0)
+      {
+        CanonicalForm denF= bCommonDen (F);
+        CanonicalForm denG= bCommonDen (G);
+        G *= denG;
+        F *= denF;
+        Off (SW_RATIONAL);
+        CanonicalForm gcddenFdenG= gcd (denG, denF);
+        denG /= gcddenFdenG;
+        denF /= gcddenFdenG;
+        On (SW_RATIONAL);
+        G *= denF;
+        F *= denG;
+      }
+      f=convFactoryPSingP( F, r);
+      g=convFactoryPSingP( G, r);
+    }
+    res=convFactoryPSingP( GCD , r);
+    if (!b1) Off (SW_USE_EZGCD_P);
+  }
+  // and over Q(a) / Fp(a)
+  else if ( r->cf->extRing )
+  {
+    if ( rField_is_Q_a(r)) setCharacteristic( 0 );
+    else                   setCharacteristic( rChar(r) );
+    if (r->cf->extRing->qideal!=NULL)
+    {
+      bool b1=isOn(SW_USE_QGCD);
+      if ( rField_is_Q_a(r) ) On(SW_USE_QGCD);
+      CanonicalForm mipo=convSingPFactoryP(r->cf->extRing->qideal->m[0],
+                                           r->cf->extRing);
+      Variable a=rootOf(mipo);
+      F=( convSingAPFactoryAP( f,a,r ) );
+      G=( convSingAPFactoryAP( g,a,r ) );
+      GCD=gcd(F,G);
+      if (!GCD.isOne())
+      {
+        p_Delete(&f,r);
+        p_Delete(&g,r);
+        if (getCharacteristic() == 0)
+          On (SW_RATIONAL);
+        F /= GCD;
+        G /= GCD;
+        if (getCharacteristic() == 0)
+        {
+          CanonicalForm denF= bCommonDen (F);
+          CanonicalForm denG= bCommonDen (G);
+          G *= denG;
+          F *= denF;
+          Off (SW_RATIONAL);
+          CanonicalForm gcddenFdenG= gcd (denG, denF);
+          denG /= gcddenFdenG;
+          denF /= gcddenFdenG;
+          On (SW_RATIONAL);
+          G *= denF;
+          F *= denG;
+        }
+        f= convFactoryAPSingAP( F,r );
+        g= convFactoryAPSingAP( G,r );
+      }
+      res= convFactoryAPSingAP( GCD,r );
+      prune (a);
+      if (!b1) Off(SW_USE_QGCD);
+    }
+    else
+    {
+      F=( convSingTrPFactoryP( f,r ) );
+      G=( convSingTrPFactoryP( g,r ) );
+      GCD=gcd(F,G);
+      if (!GCD.isOne())
+      {
+        p_Delete(&f,r);
+        p_Delete(&g,r);
+        if (getCharacteristic() == 0)
+          On (SW_RATIONAL);
+        F /= GCD;
+        G /= GCD;
+        if (getCharacteristic() == 0)
+        {
+          CanonicalForm denF= bCommonDen (F);
+          CanonicalForm denG= bCommonDen (G);
+          G *= denG;
+          F *= denF;
+          Off (SW_RATIONAL);
+          CanonicalForm gcddenFdenG= gcd (denG, denF);
+          denG /= gcddenFdenG;
+          denF /= gcddenFdenG;
+          On (SW_RATIONAL);
+          G *= denF;
+          F *= denG;
+        }
+        f= convFactoryPSingTrP( F,r );
+        g= convFactoryPSingTrP( G,r );
+      }
+      res= convFactoryPSingTrP( GCD,r );
+    }
+  }
+  else
+    WerrorS( feNotImplemented );
+  Off(SW_RATIONAL);
+  return res;
+}
+
+poly singclap_gcd ( poly f, poly g, const ring r)
+{
+  poly res=NULL;
+
+  if (f!=NULL) p_Cleardenom(f, r);
+  if (g!=NULL) p_Cleardenom(g, r);
+  else         return f; // g==0 => gcd=f (but do a p_Cleardenom)
+  if (f==NULL) return g; // f==0 => gcd=g (but do a p_Cleardenom)
+
+  res=singclap_gcd_r(f,g,r);
+  p_Delete(&f, r);
+  p_Delete(&g, r);
+  return res;
+}
+
+/*2 find the maximal exponent of var(i) in poly p*/
+int pGetExp_Var(poly p, int i, const ring r)
+{
+  int m=0;
+  int mm;
+  while (p!=NULL)
+  {
+    mm=p_GetExp(p,i,r);
+    if (mm>m) m=mm;
+    pIter(p);
+  }
+  return m;
+}
+
+// destroys f,g,x
+poly singclap_resultant ( poly f, poly g , poly x, const ring r)
+{
+  poly res=NULL;
+  int i=p_IsPurePower(x, r);
+  if (i==0)
+  {
+    WerrorS("3rd argument must be a ring variable");
+    goto resultant_returns_res;
+  }
+  if ((f==NULL) || (g==NULL))
+    goto resultant_returns_res;
+  // for now there is only the possibility to handle polynomials over
+  // Q and Fp ...
+  if (rField_is_Zp(r) || rField_is_Q(r))
+  {
+    Variable X(i);
+    setCharacteristic( rChar(r) );
+    CanonicalForm F( convSingPFactoryP( f,r ) ), G( convSingPFactoryP( g,r ) );
+    res=convFactoryPSingP( resultant( F, G, X),r );
+    Off(SW_RATIONAL);
+    goto resultant_returns_res;
+  }
+  // and over Q(a) / Fp(a)
+  else if (r->cf->extRing!=NULL)
+  {
+    if (rField_is_Q_a(r)) setCharacteristic( 0 );
+    else               setCharacteristic( rChar(r) );
+    Variable X(i+rPar(r));
+    if (r->cf->extRing->qideal!=NULL)
+    {
+      //Variable X(i);
+      CanonicalForm mipo=convSingPFactoryP(r->cf->extRing->qideal->m[0],
+                                           r->cf->extRing);
+      Variable a=rootOf(mipo);
+      CanonicalForm F( convSingAPFactoryAP( f,a,r ) ),
+                    G( convSingAPFactoryAP( g,a,r ) );
+      res= convFactoryAPSingAP( resultant( F, G, X ),r );
+      prune (a);
+    }
+    else
+    {
+      //Variable X(i+rPar(currRing));
+      number nf,ng;
+      p_Cleardenom_n(f,r,nf);p_Cleardenom_n(g,r,ng);
+      int ef,eg;
+      ef=pGetExp_Var(f,i,r);
+      eg=pGetExp_Var(g,i,r);
+      CanonicalForm F( convSingTrPFactoryP( f,r ) ), G( convSingTrPFactoryP( g,r ) );
+      res= convFactoryPSingTrP( resultant( F, G, X ),r );
+      if ((nf!=NULL)&&(!n_IsOne(nf,r->cf)))
+      {
+        number n=n_Invers(nf,r->cf);
+        while(eg>0)
+        {
+          res=p_Mult_nn(res,n,r);
+          eg--;
+        }
+        n_Delete(&n,r->cf);
+      }
+      n_Delete(&nf,r->cf);
+      if ((ng!=NULL)&&(!n_IsOne(ng,r->cf)))
+      {
+        number n=n_Invers(ng,r->cf);
+        while(ef>0)
+        {
+          res=p_Mult_nn(res,n,r);
+          ef--;
+        }
+        n_Delete(&n,r->cf);
+      }
+      n_Delete(&ng,r->cf);
+    }
+    Off(SW_RATIONAL);
+    goto resultant_returns_res;
+  }
+  else
+    WerrorS( feNotImplemented );
+resultant_returns_res:
+  p_Delete(&f,r);
+  p_Delete(&g,r);
+  p_Delete(&x,r);
+  return res;
+}
+//poly singclap_resultant ( poly f, poly g , poly x)
+//{
+//  int i=pVar(x);
+//  if (i==0)
+//  {
+//    WerrorS("ringvar expected");
+//    return NULL;
+//  }
+//  ideal I=idInit(1,1);
+//
+//  // get the coeffs von f wrt. x:
+//  I->m[0]=pCopy(f);
+//  matrix ffi=mpCoeffs(I,i);
+//  ffi->rank=1;
+//  ffi->ncols=ffi->nrows;
+//  ffi->nrows=1;
+//  ideal fi=(ideal)ffi;
+//
+//  // get the coeffs von g wrt. x:
+//  I->m[0]=pCopy(g);
+//  matrix ggi=mpCoeffs(I,i);
+//  ggi->rank=1;
+//  ggi->ncols=ggi->nrows;
+//  ggi->nrows=1;
+//  ideal gi=(ideal)ggi;
+//
+//  // contruct the matrix:
+//  int fn=IDELEMS(fi); //= deg(f,x)+1
+//  int gn=IDELEMS(gi); //= deg(g,x)+1
+//  matrix m=mpNew(fn+gn-2,fn+gn-2);
+//  if(m==NULL)
+//  {
+//    return NULL;
+//  }
+//
+//  // enter the coeffs into m:
+//  int j;
+//  for(i=0;i<gn-1;i++)
+//  {
+//    for(j=0;j<fn;j++)
+//    {
+//      MATELEM(m,i+1,fn-j+i)=pCopy(fi->m[j]);
+//    }
+//  }
+//  for(i=0;i<fn-1;i++)
+//  {
+//    for(j=0;j<gn;j++)
+//    {
+//      MATELEM(m,gn+i,gn-j+i)=pCopy(gi->m[j]);
+//    }
+//  }
+//
+//  poly r=mpDet(m);
+//
+//  idDelete(&fi);
+//  idDelete(&gi);
+//  idDelete((ideal *)&m);
+//  return r;
+//}
+
+BOOLEAN singclap_extgcd ( poly f, poly g, poly &res, poly &pa, poly &pb , const ring r)
+{
+  // for now there is only the possibility to handle univariate
+  // polynomials over
+  // Q and Fp ...
+  res=NULL;pa=NULL;pb=NULL;
+  On(SW_SYMMETRIC_FF);
+  if ( rField_is_Q(r) || rField_is_Zp(r) )
+  {
+    setCharacteristic( rChar(r) );
+    CanonicalForm F( convSingPFactoryP( f,r ) ), G( convSingPFactoryP( g,r) );
+    CanonicalForm FpG=F+G;
+    if (!(FpG.isUnivariate()|| FpG.inCoeffDomain()))
+    //if (!F.isUnivariate() || !G.isUnivariate() || F.mvar()!=G.mvar())
+    {
+      Off(SW_RATIONAL);
+      WerrorS("not univariate");
+      return TRUE;
+    }
+    CanonicalForm Fa,Gb;
+    On(SW_RATIONAL);
+    res=convFactoryPSingP( extgcd( F, G, Fa, Gb ),r );
+    pa=convFactoryPSingP(Fa,r);
+    pb=convFactoryPSingP(Gb,r);
+    Off(SW_RATIONAL);
+  }
+  // and over Q(a) / Fp(a)
+  else if ( r->cf->extRing!=NULL )
+  {
+    if (rField_is_Q_a(r)) setCharacteristic( 0 );
+    else                 setCharacteristic( rChar(r) );
+    CanonicalForm Fa,Gb;
+    if (r->cf->extRing->qideal!=NULL)
+    {
+      CanonicalForm mipo=convSingPFactoryP(r->cf->extRing->qideal->m[0],
+                                           r->cf->extRing);
+      Variable a=rootOf(mipo);
+      CanonicalForm F( convSingAPFactoryAP( f,a,r ) ),
+                    G( convSingAPFactoryAP( g,a,r ) );
+      CanonicalForm FpG=F+G;
+      if (!(FpG.isUnivariate()|| FpG.inCoeffDomain()))
+      //if (!F.isUnivariate() || !G.isUnivariate() || F.mvar()!=G.mvar())
+      {
+        WerrorS("not univariate");
+        return TRUE;
+      }
+      res= convFactoryAPSingAP( extgcd( F, G, Fa, Gb ),r );
+      pa=convFactoryAPSingAP(Fa,r);
+      pb=convFactoryAPSingAP(Gb,r);
+      prune (a);
+    }
+    else
+    {
+      CanonicalForm F( convSingTrPFactoryP( f, r ) ), G( convSingTrPFactoryP( g, r ) );
+      CanonicalForm FpG=F+G;
+      if (!(FpG.isUnivariate()|| FpG.inCoeffDomain()))
+      //if (!F.isUnivariate() || !G.isUnivariate() || F.mvar()!=G.mvar())
+      {
+        Off(SW_RATIONAL);
+        WerrorS("not univariate");
+        return TRUE;
+      }
+      res= convFactoryPSingTrP( extgcd( F, G, Fa, Gb ), r );
+      pa=convFactoryPSingTrP(Fa, r);
+      pb=convFactoryPSingTrP(Gb, r);
+    }
+    Off(SW_RATIONAL);
+  }
+  else
+  {
+    WerrorS( feNotImplemented );
+    return TRUE;
+  }
+#ifndef SING_NDEBUG
+  // checking the result of extgcd:
+  poly dummy;
+  dummy=p_Sub(p_Add_q(pp_Mult_qq(f,pa,r),pp_Mult_qq(g,pb,r),r),p_Copy(res,r),r);
+  if (dummy!=NULL)
+  {
+    PrintS("extgcd( ");p_Write(f,r);p_Write0(g,r);PrintS(" )\n");
+    PrintS("extgcd( ");p_Write(f,r);p_Write0(g,r);PrintS(" )\n");
+    p_Delete(&dummy,r);
+  }
+#endif
+  return FALSE;
+}
+
+poly singclap_pdivide ( poly f, poly g, const ring r )
+{
+  poly res=NULL;
+  On(SW_RATIONAL);
+  if (rField_is_Zp(r) || rField_is_Q(r))
+  {
+    setCharacteristic( rChar(r) );
+    CanonicalForm F( convSingPFactoryP( f,r ) ), G( convSingPFactoryP( g,r ) );
+    res = convFactoryPSingP( F / G,r );
+  }
+  else if (rField_is_Ring_Z(r))
+  {
+    Off(SW_RATIONAL);
+    setCharacteristic( rChar(r) );
+    CanonicalForm F( convSingPFactoryP( f,r ) ), G( convSingPFactoryP( g,r ) );
+    res = convFactoryPSingP( F / G,r );
+  }
+  else if (r->cf->extRing!=NULL)
+  {
+    if (rField_is_Q_a(r)) setCharacteristic( 0 );
+    else               setCharacteristic( rChar(r) );
+    if (r->cf->extRing->qideal!=NULL)
+    {
+      CanonicalForm mipo=convSingPFactoryP(r->cf->extRing->qideal->m[0],
+                                                 r->cf->extRing);
+      Variable a=rootOf(mipo);
+      CanonicalForm F( convSingAPFactoryAP( f,a,r ) ),
+                    G( convSingAPFactoryAP( g,a,r ) );
+      res= convFactoryAPSingAP(  F / G, r  );
+      prune (a);
+    }
+    else
+    {
+      CanonicalForm F( convSingTrPFactoryP( f,r ) ), G( convSingTrPFactoryP( g,r ) );
+      res= convFactoryPSingTrP(  F / G,r  );
+    }
+  }
+#if 0 // not yet working
+  else if (rField_is_GF())
+  {
+    //Print("GF(%d^%d)\n",nfCharP,nfMinPoly[0]);
+    setCharacteristic( nfCharP,nfMinPoly[0], currRing->parameter[0][0] );
+    CanonicalForm F( convSingGFFactoryGF( f ) ), G( convSingGFFactoryGF( g ) );
+    res = convFactoryGFSingGF( F / G );
+  }
+#endif
+  else
+    WerrorS( feNotImplemented );
+  Off(SW_RATIONAL);
+  return res;
+}
+
+void singclap_divide_content ( poly f, const ring r )
+{
+  if ( f==NULL )
+  {
+    return;
+  }
+  else  if ( pNext( f ) == NULL )
+  {
+    p_SetCoeff( f, n_Init( 1, r->cf ), r );
+    return;
+  }
+  else
+  {
+    if ( rField_is_Q_a(r) )
+      setCharacteristic( 0 );
+    else  if ( rField_is_Zp_a(r) )
+      setCharacteristic( -rChar(r) );
+    else
+      return; /* not implemented*/
+
+    CFList L;
+    CanonicalForm g, h;
+    poly p = pNext(f);
+
+    // first attemp: find 2 smallest g:
+
+    number g1=pGetCoeff(f);
+    number g2=pGetCoeff(p); // p==pNext(f);
+    pIter(p);
+    int sz1=n_Size(g1, r->cf);
+    int sz2=n_Size(g2, r->cf);
+    if (sz1>sz2)
+    {
+      number gg=g1;
+      g1=g2; g2=gg;
+      int sz=sz1;
+      sz1=sz2; sz2=sz;
+    }
+    while (p!=NULL)
+    {
+      int n_sz=n_Size(pGetCoeff(p),r->cf);
+      if (n_sz<sz1)
+      {
+        sz2=sz1;
+        g2=g1;
+        g1=pGetCoeff(p);
+        sz1=n_sz;
+        if (sz1<=3) break;
+      }
+      else if(n_sz<sz2)
+      {
+        sz2=n_sz;
+        g2=pGetCoeff(p);
+        sz2=n_sz;
+      }
+      pIter(p);
+    }
+    g = convSingPFactoryP( NUM(((fraction)g1)), r->cf->extRing );
+    g = gcd( g, convSingPFactoryP( NUM(((fraction)g2)) , r->cf->extRing));
+
+    // second run: gcd's
+
+    p = f;
+    while ( (p != NULL) && (g != 1)  && ( g != 0))
+    {
+      h = convSingPFactoryP( NUM(((fraction)pGetCoeff(p))), r->cf->extRing );
+      pIter( p );
+
+      g = gcd( g, h );
+
+      L.append( h );
+    }
+    if (( g == 1 ) || (g == 0))
+    {
+      // pTest(f);
+      return;
+    }
+    else
+    {
+      CFListIterator i;
+      for ( i = L, p = f; i.hasItem(); i++, p=pNext(p) )
+      {
+        fraction c=(fraction)pGetCoeff(p);
+        p_Delete(&(NUM(c)),r->cf->extRing); // 2nd arg used to be nacRing
+        NUM(c)=convFactoryPSingP( i.getItem() / g, r->cf->extRing );
+        //nTest((number)c);
+        //#ifdef LDEBUG
+        //number cn=(number)c;
+        //StringSetS(""); nWrite(nt); StringAppend(" ==> ");
+        //nWrite(cn);PrintS(StringEndS("\n")); // NOTE/TODO: use StringAppendS("\n"); omFree(s);
+        //#endif
+      }
+    }
+    // pTest(f);
+  }
+}
+
+BOOLEAN count_Factors(ideal I, intvec *v,int j, poly &f, poly fac, const ring r)
+{
+  p_Test(f,r);
+  p_Test(fac,r);
+  int e=0;
+  if (!p_IsConstantPoly(fac,r))
+  {
+#ifdef FACTORIZE2_DEBUG
+    printf("start count_Factors(%d), Fdeg=%d, factor deg=%d\n",j,p_Totaldegree(f,r),p_Totaldegree(fac,r));
+    p_wrp(fac,r);PrintLn();
+#endif
+    On(SW_RATIONAL);
+    CanonicalForm F, FAC,Q,R;
+    Variable a;
+    if (rField_is_Zp(r) || rField_is_Q(r))
+    {
+      F=convSingPFactoryP( f,r );
+      FAC=convSingPFactoryP( fac,r );
+    }
+    else if (r->cf->extRing!=NULL)
+    {
+      if (r->cf->extRing->qideal!=NULL)
+      {
+        CanonicalForm mipo=convSingPFactoryP(r->cf->extRing->qideal->m[0],
+                                    r->cf->extRing);
+        a=rootOf(mipo);
+        F=convSingAPFactoryAP( f,a,r );
+        FAC=convSingAPFactoryAP( fac,a,r );
+      }
+      else
+      {
+        F=convSingTrPFactoryP( f,r );
+        FAC=convSingTrPFactoryP( fac,r );
+      }
+    }
+    else
+      WerrorS( feNotImplemented );
+
+    poly q;
+    loop
+    {
+      Q=F;
+      Q/=FAC;
+      R=Q;
+      R*=FAC;
+      R-=F;
+      if (R.isZero())
+      {
+        if (rField_is_Zp(r) || rField_is_Q(r))
+        {
+          q = convFactoryPSingP( Q,r );
+        }
+        else if (r->cf->extRing!=NULL)
+        {
+          if (r->cf->extRing->qideal!=NULL)
+          {
+            q= convFactoryAPSingAP( Q,r );
+          }
+          else
+          {
+            q= convFactoryPSingTrP( Q,r );
+          }
+        }
+        e++; p_Delete(&f,r); f=q; q=NULL; F=Q;
+      }
+      else
+      {
+        break;
+      }
+    }
+    if (r->cf->extRing!=NULL)
+      if (r->cf->extRing->qideal!=NULL)
+        prune (a);
+    if (e==0)
+    {
+      Off(SW_RATIONAL);
+      return FALSE;
+    }
+  }
+  else e=1;
+  I->m[j]=fac;
+  if (v!=NULL) (*v)[j]=e;
+  Off(SW_RATIONAL);
+  return TRUE;
+}
+
+int singclap_factorize_retry;
+
+ideal singclap_factorize ( poly f, intvec ** v , int with_exps, const ring r)
+/* destroys f, sets *v */
+{
+  p_Test(f,r);
+#ifdef FACTORIZE2_DEBUG
+  printf("singclap_factorize, degree %ld\n",p_Totaldegree(f,r));
+#endif
+  // with_exps: 3,1 return only true factors, no exponents
+  //            2 return true factors and exponents
+  //            0 return coeff, factors and exponents
+  BOOLEAN save_errorreported=errorreported;
+
+  ideal res=NULL;
+
+  // handle factorize(0) =========================================
+  if (f==NULL)
+  {
+    res=idInit(1,1);
+    if (with_exps!=1)
+    {
+      (*v)=new intvec(1);
+      (**v)[0]=1;
+    }
+    return res;
+  }
+  // handle factorize(mon) =========================================
+  if (pNext(f)==NULL)
+  {
+    int i=0;
+    int n=0;
+    int e;
+    for(i=rVar(r);i>0;i--) if(p_GetExp(f,i,r)!=0) n++;
+    if (with_exps==0) n++; // with coeff
+    res=idInit(si_max(n,1),1);
+    switch(with_exps)
+    {
+      case 0: // with coef & exp.
+        res->m[0]=p_NSet(n_Copy(pGetCoeff(f),r->cf),r);
+        // no break
+      case 2: // with exp.
+        (*v)=new intvec(si_max(1,n));
+        (**v)[0]=1;
+        // no break
+      case 1: ;
+#ifdef TEST
+      default: ;
+#endif
+    }
+    if (n==0)
+    {
+      res->m[0]=p_One(r);
+      // (**v)[0]=1; is already done
+    }
+    else
+    {
+      for(i=rVar(r);i>0;i--)
+      {
+        e=p_GetExp(f,i,r);
+        if(e!=0)
+        {
+          n--;
+          poly p=p_One(r);
+          p_SetExp(p,i,1,r);
+          p_Setm(p,r);
+          res->m[n]=p;
+          if (with_exps!=1) (**v)[n]=e;
+        }
+      }
+    }
+    p_Delete(&f,r);
+    return res;
+  }
+  //PrintS("S:");p_Write(f,r);PrintLn();
+  // use factory/libfac in general ==============================
+  Off(SW_RATIONAL);
+  On(SW_SYMMETRIC_FF);
+  CFFList L;
+  number N=NULL;
+  number NN=NULL;
+  number old_lead_coeff=n_Copy(pGetCoeff(f), r->cf);
+
+  Variable a;
+  if (!rField_is_Zp(r) && !rField_is_Zp_a(r)) /* Q, Q(a) */
+  {
+    //if (f!=NULL) // already tested at start of routine
+    {
+      number n0=n_Copy(pGetCoeff(f),r->cf);
+      if (with_exps==0)
+        N=n_Copy(n0,r->cf);
+      p_Cleardenom(f, r);
+      //after here f should not have a denominator!!
+      //PrintS("S:");p_Write(f,r);PrintLn();
+      NN=n_Div(n0,pGetCoeff(f),r->cf);
+      n_Delete(&n0,r->cf);
+      if (with_exps==0)
+      {
+        n_Delete(&N,r->cf);
+        N=n_Copy(NN,r->cf);
+      }
+    }
+  }
+  else if (rField_is_Zp_a(r))
+  {
+    //if (f!=NULL) // already tested at start of routine
+    if (singclap_factorize_retry==0)
+    {
+      number n0=n_Copy(pGetCoeff(f),r->cf);
+      if (with_exps==0)
+        N=n_Copy(n0,r->cf);
+      p_Norm(f,r);
+      p_Cleardenom(f, r);
+      NN=n_Div(n0,pGetCoeff(f),r->cf);
+      n_Delete(&n0,r->cf);
+      if (with_exps==0)
+      {
+        n_Delete(&N,r->cf);
+        N=n_Copy(NN,r->cf);
+      }
+    }
+  }
+  if (rField_is_Q(r) || rField_is_Zp(r))
+  {
+    setCharacteristic( rChar(r) );
+    CanonicalForm F( convSingPFactoryP( f,r ) );
+    L = factorize( F );
+  }
+  // and over Q(a) / Fp(a)
+  else if (r->cf->extRing!=NULL)
+  {
+    if (rField_is_Q_a (r)) setCharacteristic (0);
+    else                   setCharacteristic( rChar(r) );
+    if (r->cf->extRing->qideal!=NULL)
+    {
+      CanonicalForm mipo=convSingPFactoryP(r->cf->extRing->qideal->m[0],
+                                           r->cf->extRing);
+      a=rootOf(mipo);
+      CanonicalForm F( convSingAPFactoryAP( f, a, r ) );
+      if (rField_is_Zp_a(r))
+      {
+        L = factorize( F, a );
+      }
+      else
+      {
+        //  over Q(a)
+        L= factorize (F, a);
+      }
+    }
+    else
+    {
+      CanonicalForm F( convSingTrPFactoryP( f,r ) );
+      L = factorize( F );
+    }
+  }
+  else
+  {
+    goto notImpl;
+  }
+  {
+    poly ff=p_Copy(f,r); // a copy for the retry stuff
+    // the first factor should be a constant
+    if ( ! L.getFirst().factor().inCoeffDomain() )
+      L.insert(CFFactor(1,1));
+    // convert into ideal
+    int n = L.length();
+    if (n==0) n=1;
+    CFFListIterator J=L;
+    int j=0;
+    if (with_exps!=1)
+    {
+      if ((with_exps==2)&&(n>1))
+      {
+        n--;
+        J++;
+      }
+      *v = new intvec( n );
+    }
+    res = idInit( n ,1);
+    for ( ; J.hasItem(); J++, j++ )
+    {
+      if (with_exps!=1) (**v)[j] = J.getItem().exp();
+      if (rField_is_Zp(r) || rField_is_Q(r))           /* Q, Fp */
+      {
+        //count_Factors(res,*v,f, j, convFactoryPSingP( J.getItem().factor() );
+        res->m[j] = convFactoryPSingP( J.getItem().factor(),r );
+      }
+#if 0
+      else if (rField_is_GF())
+        res->m[j] = convFactoryGFSingGF( J.getItem().factor() );
+#endif
+      else if (r->cf->extRing!=NULL)     /* Q(a), Fp(a) */
+      {
+#ifndef SING_NDEBUG
+        intvec *w=NULL;
+        if (v!=NULL) w=*v;
+#endif
+        if (r->cf->extRing->qideal==NULL)
+        {
+#ifdef SING_NDEBUG
+          res->m[j]= convFactoryPSingTrP( J.getItem().factor(),r );
+#else
+          if(!count_Factors(res,w,j,ff,convFactoryPSingTrP( J.getItem().factor(),r ),r))
+          {
+            if (w!=NULL)
+              (*w)[j]=1;
+            res->m[j]=p_One(r);
+          }
+#endif
+        }
+        else
+        {
+#ifdef SING_NDEBUG
+          res->m[j]= convFactoryAPSingAP( J.getItem().factor(),r );
+#else
+          if (!count_Factors(res,w,j,ff,convFactoryAPSingAP( J.getItem().factor(),r ),r))
+          {
+            if (w!=NULL)
+              (*w)[j]=1;
+            res->m[j]=p_One(r);
+          }
+#endif
+        }
+      }
+    }
+    if (r->cf->extRing!=NULL)
+      if (r->cf->extRing->qideal!=NULL)
+        prune (a);
+#ifndef SING_NDEBUG
+    if ((r->cf->extRing!=NULL) && (!p_IsConstantPoly(ff,r)))
+    {
+      singclap_factorize_retry++;
+      if (singclap_factorize_retry<3)
+      {
+        int jj;
+#ifdef FACTORIZE2_DEBUG
+        printf("factorize_retry\n");
+#endif
+        intvec *ww=NULL;
+        id_Test(res,r);
+        ideal h=singclap_factorize ( ff, &ww , with_exps, r );
+        id_Test(h,r);
+        int l=(*v)->length();
+        (*v)->resize(l+ww->length());
+        for(jj=0;jj<ww->length();jj++)
+          (**v)[jj+l]=(*ww)[jj];
+        delete ww;
+        ideal hh=idInit(IDELEMS(res)+IDELEMS(h),1);
+        for(jj=IDELEMS(res)-1;jj>=0;jj--)
+        {
+          hh->m[jj]=res->m[jj];
+          res->m[jj]=NULL;
+        }
+        for(jj=IDELEMS(h)-1;jj>=0;jj--)
+        {
+          hh->m[jj+IDELEMS(res)]=h->m[jj];
+          h->m[jj]=NULL;
+        }
+        id_Delete(&res,r);
+        id_Delete(&h,r);
+        res=hh;
+        id_Test(res,r);
+        ff=NULL;
+      }
+      else
+      {
+        WarnS("problem with factorize");
+#if 0
+        pWrite(ff);
+        idShow(res);
+#endif
+        id_Delete(&res,r);
+        res=idInit(2,1);
+        res->m[0]=p_One(r);
+        res->m[1]=ff; ff=NULL;
+      }
+    }
+#endif
+    p_Delete(&ff,r);
+    if (N!=NULL)
+    {
+      p_Mult_nn(res->m[0],N,r);
+      n_Delete(&N,r->cf);
+      N=NULL;
+    }
+    // delete constants
+    if (res!=NULL)
+    {
+      int i=IDELEMS(res)-1;
+      int j=0;
+      for(;i>=0;i--)
+      {
+        if ((res->m[i]!=NULL)
+        && (pNext(res->m[i])==NULL)
+        && (p_IsConstant(res->m[i],r)))
+        {
+          if (with_exps!=0)
+          {
+            p_Delete(&(res->m[i]),r);
+            if ((v!=NULL) && ((*v)!=NULL))
+              (**v)[i]=0;
+            j++;
+          }
+          else if (i!=0)
+          {
+            while ((v!=NULL) && ((*v)!=NULL) && ((**v)[i]>1))
+            {
+              res->m[0]=p_Mult_q(res->m[0],p_Copy(res->m[i],r),r);
+              (**v)[i]--;
+            }
+            res->m[0]=p_Mult_q(res->m[0],res->m[i],r);
+            res->m[i]=NULL;
+            if ((v!=NULL) && ((*v)!=NULL))
+              (**v)[i]=1;
+            j++;
+          }
+        }
+      }
+      if (j>0)
+      {
+        idSkipZeroes(res);
+        if ((v!=NULL) && ((*v)!=NULL))
+        {
+          intvec *w=*v;
+          int len=IDELEMS(res);
+          *v = new intvec( len );
+          for (i=0,j=0;i<si_min(w->length(),len);i++)
+          {
+            if((*w)[i]!=0)
+            {
+              (**v)[j]=(*w)[i]; j++;
+            }
+          }
+          delete w;
+        }
+      }
+      if (res->m[0]==NULL)
+      {
+        res->m[0]=p_One(r);
+      }
+    }
+  }
+  if (rField_is_Q_a(r) && (r->cf->extRing->qideal!=NULL))
+  {
+    int i=IDELEMS(res)-1;
+    int stop=1;
+    if (with_exps!=0) stop=0;
+    for(;i>=stop;i--)
+    {
+      p_Norm(res->m[i],r);
+    }
+    if (with_exps==0) p_SetCoeff(res->m[0],old_lead_coeff,r);
+    else n_Delete(&old_lead_coeff,r->cf);
+  }
+  else
+    n_Delete(&old_lead_coeff,r->cf);
+  errorreported=save_errorreported;
+notImpl:
+  if (res==NULL)
+    WerrorS( feNotImplemented );
+  if (NN!=NULL)
+  {
+    n_Delete(&NN,r->cf);
+  }
+  if (N!=NULL)
+  {
+    n_Delete(&N,r->cf);
+  }
+  if (f!=NULL) p_Delete(&f,r);
+  //PrintS("......S\n");
+  return res;
+}
+
+ideal singclap_sqrfree ( poly f, intvec ** v , int with_exps, const ring r)
+{
+  p_Test(f,r);
+#ifdef FACTORIZE2_DEBUG
+  printf("singclap_sqrfree, degree %d\n",pTotaldegree(f));
+#endif
+  // with_exps: 3,1 return only true factors, no exponents
+  //            2 return true factors and exponents
+  //            0 return coeff, factors and exponents
+  BOOLEAN save_errorreported=errorreported;
+
+  ideal res=NULL;
+
+  // handle factorize(0) =========================================
+  if (f==NULL)
+  {
+    res=idInit(1,1);
+    if (with_exps!=1 && with_exps!=3)
+    {
+      (*v)=new intvec(1);
+      (**v)[0]=1;
+    }
+    return res;
+  }
+  // handle factorize(mon) =========================================
+  if (pNext(f)==NULL)
+  {
+    int i=0;
+    int n=0;
+    int e;
+    for(i=rVar(r);i>0;i--) if(p_GetExp(f,i,r)!=0) n++;
+    if (with_exps==0 || with_exps==3) n++; // with coeff
+    res=idInit(si_max(n,1),1);
+    switch(with_exps)
+    {
+      case 0: // with coef & exp.
+        res->m[0]=p_NSet(n_Copy(pGetCoeff(f),r->cf),r);
+        // no break
+      case 3: // with coef & exp.
+        res->m[0]=p_NSet(n_Copy(pGetCoeff(f),r->cf),r);
+        // no break
+      case 2: // with exp.
+        (*v)=new intvec(si_max(1,n));
+        (**v)[0]=1;
+        // no break
+      case 1: ;
+      #ifdef TEST
+      default: ;
+      #endif
+    }
+    res->m[0]=p_NSet(n_Copy(pGetCoeff(f),r->cf),r);
+    if (n==0)
+    {
+      res->m[0]=p_One(r);
+      // (**v)[0]=1; is already done
+    }
+    else
+    {
+      for(i=rVar(r);i>0;i--)
+      {
+        e=p_GetExp(f,i,r);
+        if(e!=0)
+        {
+          n--;
+          poly p=p_One(r);
+          p_SetExp(p,i,1,r);
+          p_Setm(p,r);
+          res->m[n]=p;
+          if (with_exps!=1) (**v)[n]=e;
+        }
+      }
+    }
+    p_Delete(&f,r);
+    return res;
+  }
+  //PrintS("S:");pWrite(f);PrintLn();
+  // use factory/libfac in general ==============================
+  Off(SW_RATIONAL);
+  On(SW_SYMMETRIC_FF);
+  CFFList L;
+  number N=NULL;
+  number NN=NULL;
+  number old_lead_coeff=n_Copy(pGetCoeff(f), r->cf);
+  Variable a;
+
+  if (!rField_is_Zp(r) && !rField_is_Zp_a(r)) /* Q, Q(a) */
+  {
+    //if (f!=NULL) // already tested at start of routine
+    number n0=n_Copy(pGetCoeff(f),r->cf);
+    if (with_exps==0 || with_exps==3)
+      N=n_Copy(n0,r->cf);
+    p_Cleardenom(f, r);
+    //after here f should not have a denominator!!
+    //PrintS("S:");p_Write(f,r);PrintLn();
+    NN=n_Div(n0,pGetCoeff(f),r->cf);
+    n_Delete(&n0,r->cf);
+    if (with_exps==0 || with_exps==3)
+    {
+      n_Delete(&N,r->cf);
+      N=n_Copy(NN,r->cf);
+    }
+  }
+  else if (rField_is_Zp_a(r))
+  {
+    //if (f!=NULL) // already tested at start of routine
+    if (singclap_factorize_retry==0)
+    {
+      number n0=n_Copy(pGetCoeff(f),r->cf);
+      if (with_exps==0 || with_exps==3)
+        N=n_Copy(n0,r->cf);
+      p_Norm(f,r);
+      p_Cleardenom(f, r);
+      NN=n_Div(n0,pGetCoeff(f),r->cf);
+      n_Delete(&n0,r->cf);
+      if (with_exps==0 || with_exps==3)
+      {
+        n_Delete(&N,r->cf);
+        N=n_Copy(NN,r->cf);
+      }
+    }
+  }
+  if (rField_is_Q(r) || rField_is_Zp(r))
+  {
+    setCharacteristic( rChar(r) );
+    CanonicalForm F( convSingPFactoryP( f,r ) );
+    L = sqrFree( F );
+  }
+  else if (r->cf->extRing!=NULL)
+  {
+    if (rField_is_Q_a (r)) setCharacteristic (0);
+    else                   setCharacteristic( rChar(r) );
+    if (r->cf->extRing->qideal!=NULL)
+    {
+      CanonicalForm mipo=convSingPFactoryP(r->cf->extRing->qideal->m[0],
+                                           r->cf->extRing);
+      a=rootOf(mipo);
+      CanonicalForm F( convSingAPFactoryAP( f, a, r ) );
+      L= sqrFree (F);
+    }
+    else
+    {
+      CanonicalForm F( convSingTrPFactoryP( f,r ) );
+      L = sqrFree( F );
+    }
+  }
+  #if 0
+  else if (rField_is_GF())
+  {
+    int c=rChar(r);
+    setCharacteristic( c, primepower(c) );
+    CanonicalForm F( convSingGFFactoryGF( f ) );
+    if (F.isUnivariate())
+    {
+      L = factorize( F );
+    }
+    else
+    {
+      goto notImpl;
+    }
+  }
+  #endif
+  else
+  {
+    goto notImpl;
+  }
+  {
+    // convert into ideal
+    int n = L.length();
+    if (n==0) n=1;
+    CFFListIterator J=L;
+    int j=0;
+    if (with_exps!=1)
+    {
+      if ((with_exps==2)&&(n>1))
+      {
+        n--;
+        J++;
+      }
+      *v = new intvec( n );
+    }
+    else if (L.getFirst().factor().inCoeffDomain() && with_exps!=3)
+    {
+      n--;
+      J++;
+    }
+    res = idInit( n ,1);
+    for ( ; J.hasItem(); J++, j++ )
+    {
+      if (with_exps!=1 && with_exps!=3) (**v)[j] = J.getItem().exp();
+      if (rField_is_Zp(r) || rField_is_Q(r))
+        res->m[j] = convFactoryPSingP( J.getItem().factor(),r );
+      else if (r->cf->extRing!=NULL)     /* Q(a), Fp(a) */
+      {
+        if (r->cf->extRing->qideal==NULL)
+          res->m[j]=convFactoryPSingTrP( J.getItem().factor(),r );
+        else
+          res->m[j]=convFactoryAPSingAP( J.getItem().factor(),r );
+      }
+    }
+    if (res->m[0]==NULL)
+    {
+      res->m[0]=p_One(r);
+    }
+    if (N!=NULL)
+    {
+      p_Mult_nn(res->m[0],N,r);
+      n_Delete(&N,r->cf);
+      N=NULL;
+    }
+  }
+  if (r->cf->extRing!=NULL)
+    if (r->cf->extRing->qideal!=NULL)
+      prune (a);
+  if (rField_is_Q_a(r) && (r->cf->extRing->qideal!=NULL))
+  {
+    int i=IDELEMS(res)-1;
+    int stop=1;
+    if (with_exps!=0 || with_exps==3) stop=0;
+    for(;i>=stop;i--)
+    {
+      p_Norm(res->m[i],r);
+    }
+    if (with_exps==0 || with_exps==3) p_SetCoeff(res->m[0],old_lead_coeff,r);
+    else n_Delete(&old_lead_coeff,r->cf);
+  }
+  else
+    n_Delete(&old_lead_coeff,r->cf);
+  p_Delete(&f,r);
+  errorreported=save_errorreported;
+notImpl:
+  if (res==NULL)
+    WerrorS( feNotImplemented );
+  if (NN!=NULL)
+  {
+    n_Delete(&NN,r->cf);
+  }
+  if (N!=NULL)
+  {
+    n_Delete(&N,r->cf);
+  }
+  return res;
+}
+
+matrix singclap_irrCharSeries ( ideal I, const ring r)
+{
+  if (idIs0(I)) return mpNew(1,1);
+
+  // for now there is only the possibility to handle polynomials over
+  // Q and Fp ...
+  matrix res=NULL;
+  int i;
+  Off(SW_RATIONAL);
+  On(SW_SYMMETRIC_FF);
+  CFList L;
+  ListCFList LL;
+  if (rField_is_Q(r) || rField_is_Zp(r))
+  {
+    setCharacteristic( rChar(r) );
+    for(i=0;i<IDELEMS(I);i++)
+    {
+      poly p=I->m[i];
+      if (p!=NULL)
+      {
+        p=p_Copy(p,r);
+        p_Cleardenom(p, r);
+        L.append(convSingPFactoryP(p,r));
+      }
+    }
+  }
+  // and over Q(a) / Fp(a)
+  else if (nCoeff_is_transExt (r->cf))
+  {
+    setCharacteristic( rChar(r) );
+    for(i=0;i<IDELEMS(I);i++)
+    {
+      poly p=I->m[i];
+      if (p!=NULL)
+      {
+        p=p_Copy(p,r);
+        p_Cleardenom(p, r);
+        L.append(convSingTrPFactoryP(p,r));
+      }
+    }
+  }
+  else
+  {
+    WerrorS( feNotImplemented );
+    return res;
+  }
+
+  // a very bad work-around --- FIX IT in libfac
+  // should be fixed as of 2001/6/27
+  int tries=0;
+  int m,n;
+  ListIterator<CFList> LLi;
+  loop
+  {
+    LL=irrCharSeries(L);
+    m= LL.length(); // Anzahl Zeilen
+    n=0;
+    for ( LLi = LL; LLi.hasItem(); LLi++ )
+    {
+      n = si_max(LLi.getItem().length(),n);
+    }
+    if ((m!=0) && (n!=0)) break;
+    tries++;
+    if (tries>=5) break;
+  }
+  if ((m==0) || (n==0))
+  {
+    Warn("char_series returns %d x %d matrix from %d input polys (%d)",
+      m,n,IDELEMS(I)+1,LL.length());
+    iiWriteMatrix((matrix)I,"I",2,r,0);
+    m=si_max(m,1);
+    n=si_max(n,1);
+  }
+  res=mpNew(m,n);
+  CFListIterator Li;
+  for ( m=1, LLi = LL; LLi.hasItem(); LLi++, m++ )
+  {
+    for (n=1, Li = LLi.getItem(); Li.hasItem(); Li++, n++)
+    {
+      if (rField_is_Q(r) || rField_is_Zp(r))
+        MATELEM(res,m,n)=convFactoryPSingP(Li.getItem(),r);
+      else
+        MATELEM(res,m,n)=convFactoryPSingTrP(Li.getItem(),r);
+    }
+  }
+  Off(SW_RATIONAL);
+  return res;
+}
+
+char* singclap_neworder ( ideal I, const ring r)
+{
+  int i;
+  Off(SW_RATIONAL);
+  On(SW_SYMMETRIC_FF);
+  CFList L;
+  if (rField_is_Q(r) || rField_is_Zp(r))
+  {
+    setCharacteristic( rChar(r) );
+    for(i=0;i<IDELEMS(I);i++)
+    {
+      poly p=I->m[i];
+      if (p!=NULL)
+      {
+        p=p_Copy(p,r);
+        p_Cleardenom(p, r);
+        L.append(convSingPFactoryP(p,r));
+      }
+    }
+  }
+  // and over Q(a) / Fp(a)
+  else if (nCoeff_is_transExt (r->cf))
+  {
+    setCharacteristic( rChar(r) );
+    for(i=0;i<IDELEMS(I);i++)
+    {
+      poly p=I->m[i];
+      if (p!=NULL)
+      {
+        p=p_Copy(p,r);
+        p_Cleardenom(p, r);
+        L.append(convSingTrPFactoryP(p,r));
+      }
+    }
+  }
+  else
+  {
+    WerrorS( feNotImplemented );
+    return NULL;
+  }
+
+  List<int> IL=neworderint(L);
+  ListIterator<int> Li;
+  StringSetS("");
+  Li = IL;
+  int offs=rPar(r);
+  int* mark=(int*)omAlloc0((rVar(r)+offs)*sizeof(int));
+  int cnt=rVar(r)+offs;
+  loop
+  {
+    if(! Li.hasItem()) break;
+    BOOLEAN done=TRUE;
+    i=Li.getItem()-1;
+    mark[i]=1;
+    if (i<offs)
+    {
+      done=FALSE;
+      //StringAppendS(r->parameter[i]);
+    }
+    else
+    {
+      StringAppendS(r->names[i-offs]);
+    }
+    Li++;
+    cnt--;
+    if(cnt==0) break;
+    if (done) StringAppendS(",");
+  }
+  for(i=0;i<rVar(r)+offs;i++)
+  {
+    BOOLEAN done=TRUE;
+    if(mark[i]==0)
+    {
+      if (i<offs)
+      {
+        done=FALSE;
+        //StringAppendS(r->parameter[i]);
+      }
+      else
+      {
+        StringAppendS(r->names[i-offs]);
+      }
+      cnt--;
+      if(cnt==0) break;
+      if (done) StringAppendS(",");
+    }
+  }
+  char * s=StringEndS();
+  if (s[strlen(s)-1]==',') s[strlen(s)-1]='\0';
+  return s;
+}
+
+poly singclap_det( const matrix m, const ring s )
+{
+  int r=m->rows();
+  if (r!=m->cols())
+  {
+    Werror("det of %d x %d matrix",r,m->cols());
+    return NULL;
+  }
+  poly res=NULL;
+  CFMatrix M(r,r);
+  int i,j;
+  for(i=r;i>0;i--)
+  {
+    for(j=r;j>0;j--)
+    {
+      M(i,j)=convSingPFactoryP(MATELEM(m,i,j),s);
+    }
+  }
+  res= convFactoryPSingP( determinant(M,r),s ) ;
+  Off(SW_RATIONAL);
+  return res;
+}
+
+int singclap_det_i( intvec * m, const ring /*r*/)
+{
+//  assume( r == currRing ); // Anything else is not guaranted to work!
+
+  setCharacteristic( 0 ); // ?
+  CFMatrix M(m->rows(),m->cols());
+  int i,j;
+  for(i=m->rows();i>0;i--)
+  {
+    for(j=m->cols();j>0;j--)
+    {
+      M(i,j)=IMATELEM(*m,i,j);
+    }
+  }
+  int res= convFactoryISingI( determinant(M,m->rows()) ) ;
+  return res;
+}
+
+number singclap_det_bi( bigintmat * m, const coeffs cf)
+{
+  assume(m->basecoeffs()==cf);
+  CFMatrix M(m->rows(),m->cols());
+  int i,j;
+  BOOLEAN setchar=TRUE;
+  for(i=m->rows();i>0;i--)
+  {
+    for(j=m->cols();j>0;j--)
+    {
+      M(i,j)=n_convSingNFactoryN(BIMATELEM(*m,i,j),setchar,cf);
+      setchar=FALSE;
+    }
+  }
+  number res=n_convFactoryNSingN( determinant(M,m->rows()),cf ) ;
+  return res;
+}
+
+#ifdef HAVE_NTL
+#if 1
+matrix singntl_HNF(matrix  m, const ring s )
+{
+  int r=m->rows();
+  if (r!=m->cols())
+  {
+    Werror("HNF of %d x %d matrix",r,m->cols());
+    return NULL;
+  }
+
+  matrix res=mp_New(r,r);
+
+  if (rField_is_Q(s))
+  {
+
+    CFMatrix M(r,r);
+    int i,j;
+    for(i=r;i>0;i--)
+    {
+      for(j=r;j>0;j--)
+      {
+        M(i,j)=convSingPFactoryP(MATELEM(m,i,j),s );
+      }
+    }
+    CFMatrix *MM=cf_HNF(M);
+    for(i=r;i>0;i--)
+    {
+      for(j=r;j>0;j--)
+      {
+        MATELEM(res,i,j)=convFactoryPSingP((*MM)(i,j),s);
+      }
+    }
+    delete MM;
+  }
+  return res;
+}
+
+intvec* singntl_HNF(intvec*  m)
+{
+  int r=m->rows();
+  if (r!=m->cols())
+  {
+    Werror("HNF of %d x %d matrix",r,m->cols());
+    return NULL;
+  }
+  setCharacteristic( 0 );
+  CFMatrix M(r,r);
+  int i,j;
+  for(i=r;i>0;i--)
+  {
+    for(j=r;j>0;j--)
+    {
+      M(i,j)=IMATELEM(*m,i,j);
+    }
+  }
+  CFMatrix *MM=cf_HNF(M);
+  intvec *mm=ivCopy(m);
+  for(i=r;i>0;i--)
+  {
+    for(j=r;j>0;j--)
+    {
+      IMATELEM(*mm,i,j)=convFactoryISingI((*MM)(i,j));
+    }
+  }
+  delete MM;
+  return mm;
+}
+
+matrix singntl_LLL(matrix  m, const ring s )
+{
+  int r=m->rows();
+  int c=m->cols();
+  matrix res=mp_New(r,c);
+  if (rField_is_Q(s))
+  {
+    CFMatrix M(r,c);
+    int i,j;
+    for(i=r;i>0;i--)
+    {
+      for(j=c;j>0;j--)
+      {
+        M(i,j)=convSingPFactoryP(MATELEM(m,i,j),s);
+      }
+    }
+    CFMatrix *MM=cf_LLL(M);
+    for(i=r;i>0;i--)
+    {
+      for(j=c;j>0;j--)
+      {
+        MATELEM(res,i,j)=convFactoryPSingP((*MM)(i,j),s);
+      }
+    }
+    delete MM;
+  }
+  return res;
+}
+
+intvec* singntl_LLL(intvec*  m)
+{
+  int r=m->rows();
+  int c=m->cols();
+  setCharacteristic( 0 );
+  CFMatrix M(r,c);
+  int i,j;
+  for(i=r;i>0;i--)
+  {
+    for(j=c;j>0;j--)
+    {
+      M(i,j)=IMATELEM(*m,i,j);
+    }
+  }
+  CFMatrix *MM=cf_LLL(M);
+  intvec *mm=ivCopy(m);
+  for(i=r;i>0;i--)
+  {
+    for(j=c;j>0;j--)
+    {
+      IMATELEM(*mm,i,j)=convFactoryISingI((*MM)(i,j));
+    }
+  }
+  delete MM;
+  return mm;
+}
+
+ideal singclap_absFactorize ( poly f, ideal & mipos, intvec ** exps, int & numFactors, const ring r)
+{
+  p_Test(f, r);
+
+  ideal res=NULL;
+
+  int offs = rPar(r);
+  if (f==NULL)
+  {
+    res= idInit (1, 1);
+    mipos= idInit (1, 1);
+    mipos->m[0]= convFactoryPSingTrP (Variable (offs), r); //overkill
+    (*exps)=new intvec (1);
+    (**exps)[0]= 1;
+    numFactors= 0;
+    return res;
+  }
+  CanonicalForm F( convSingTrPFactoryP( f, r) );
+
+  bool isRat= isOn (SW_RATIONAL);
+  if (!isRat)
+    On (SW_RATIONAL);
+
+  CFAFList absFactors= absFactorize (F);
+
+  int n= absFactors.length();
+  *exps=new intvec (n);
+
+  res= idInit (n, 1);
+
+  mipos= idInit (n, 1);
+
+  Variable x= Variable (offs);
+  Variable alpha;
+  int i= 0;
+  numFactors= 0;
+  int count;
+  CFAFListIterator iter= absFactors;
+  CanonicalForm lead= iter.getItem().factor();
+  if (iter.getItem().factor().inCoeffDomain())
+  {
+    i++;
+    iter++;
+  }
+  for (; iter.hasItem(); iter++, i++)
+  {
+    (**exps)[i]= iter.getItem().exp();
+    alpha= iter.getItem().minpoly().mvar();
+    if (iter.getItem().minpoly().isOne())
+      lead /= power (bCommonDen (iter.getItem().factor()), iter.getItem().exp());
+    else
+      lead /= power (power (bCommonDen (iter.getItem().factor()), degree (iter.getItem().minpoly())), iter.getItem().exp());
+    res->m[i]= convFactoryPSingTrP (replacevar (iter.getItem().factor()*bCommonDen (iter.getItem().factor()), alpha, x), r);
+    if (iter.getItem().minpoly().isOne())
+    {
+      count= iter.getItem().exp();
+      mipos->m[i]= convFactoryPSingTrP (x,r);
+    }
+    else
+    {
+      count= iter.getItem().exp()*degree (iter.getItem().minpoly());
+      mipos->m[i]= convFactoryPSingTrP (replacevar (iter.getItem().minpoly(), alpha, x), r);
+    }
+    if (!iter.getItem().minpoly().isOne())
+      prune (alpha);
+    numFactors += count;
+  }
+  if (!isRat)
+    Off (SW_RATIONAL);
+
+  (**exps)[0]= 1;
+  res->m[0]= convFactoryPSingTrP (lead, r);
+  mipos->m[0]= convFactoryPSingTrP (x, r);
+  return res;
+}
+
+#endif
+#endif /* HAVE_NTL */
+
diff --git a/libpolys/polys/clapsing.h b/libpolys/polys/clapsing.h
new file mode 100644
index 0000000..3723892
--- /dev/null
+++ b/libpolys/polys/clapsing.h
@@ -0,0 +1,73 @@
+// emacs edit mode for this file is -*- C++ -*-
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: interface between Singular and factory
+*/
+
+#ifndef INCL_FACTORYSING_H
+#define INCL_FACTORYSING_H
+
+class bigintmat;
+class intvec;
+
+struct snumber; typedef struct snumber *   number;
+struct spolyrec; typedef struct spolyrec    polyrec; typedef polyrec *          poly;
+struct ip_sring; typedef struct ip_sring *         ring;
+struct sip_sideal; typedef struct sip_sideal *       ideal;
+
+class ip_smatrix; typedef ip_smatrix *       matrix;
+
+struct n_Procs_s; typedef struct  n_Procs_s  *coeffs;
+
+//#include <polys/clapconv.h>
+//#include <kernel/longtrans.h>
+
+/// destroys f and g
+poly singclap_gcd ( poly f, poly g, const ring r );
+
+poly singclap_gcd_r ( poly f, poly g, const ring r );
+
+/// clears denominators of f and g, divides by gcd(f,g)
+poly singclap_gcd_and_divide ( poly& f, poly& g, const ring r);
+
+// commented out!
+// poly singclap_alglcm ( poly f, poly g, const ring r );
+// void singclap_algdividecontent ( napoly f, napoly g, napoly &ff, napoly &gg );
+
+poly singclap_resultant ( poly f, poly g , poly x, const ring r);
+
+BOOLEAN singclap_extgcd ( poly f, poly g, poly &res, poly &pa, poly &pb , const ring r);
+
+poly singclap_pdivide ( poly f, poly g, const ring r );
+
+void singclap_divide_content ( poly f, const ring r);
+
+ideal singclap_factorize ( poly f, intvec ** v , int with_exps, const ring r);
+
+ideal singclap_sqrfree ( poly f, intvec ** v , int with_exps, const ring r );
+
+# ifdef HAVE_NTL
+#  if 1
+matrix  singntl_HNF(matrix A, const ring r);
+intvec* singntl_HNF(intvec* A);
+matrix  singntl_LLL(matrix A, const ring r);
+intvec* singntl_LLL(intvec* A);
+
+ideal singclap_absFactorize ( poly f, ideal & mipos, intvec ** exps, int & n, const ring r);
+#  endif
+# endif
+
+ matrix singclap_irrCharSeries ( ideal I, const ring r);
+ char* singclap_neworder ( ideal I, const ring r);
+
+poly singclap_det( const matrix m, const ring r );
+int singclap_det_i( intvec * m, const ring r );
+number singclap_det_bi( bigintmat * m, const coeffs cf);
+
+number   nChineseRemainder(number *x, number *q,int rl, const coeffs r);
+
+
+#endif /* INCL_FACTORYSING_H */
+
diff --git a/libpolys/polys/coeffrings.h b/libpolys/polys/coeffrings.h
new file mode 100644
index 0000000..f62a164
--- /dev/null
+++ b/libpolys/polys/coeffrings.h
@@ -0,0 +1,49 @@
+#ifndef COEFFRINGS_H
+#define COEFFRINGS_H
+
+#include <misc/auxiliary.h>
+#include <coeffs/coeffs.h>
+#include <polys/monomials/ring.h>
+
+static FORCE_INLINE number n_Copy(number n, const ring r){ return n_Copy(n, r->cf); }
+static FORCE_INLINE void n_Delete(number* p, const ring r){ n_Delete(p, r->cf); }
+static FORCE_INLINE BOOLEAN n_Equal(number a, number b, const ring r){ return n_Equal(a, b, r->cf); }
+static FORCE_INLINE nMapFunc n_SetMap(const ring src, const ring dst){ return n_SetMap(src->cf,dst->cf); }
+static FORCE_INLINE int n_GetChar(const ring r){ return n_GetChar(r->cf); }
+
+// static FORCE_INLINE BOOLEAN n_Test(number n, const char *filename, const int linenumber, const ring r){ return n_Test( n, r->cf); }
+// static FORCE_INLINE BOOLEAN n_Test(number a, const ring r){  return n_Test(a, r); }
+// #define n_Test(a,r)
+
+
+
+static FORCE_INLINE BOOLEAN n_IsZero(number n, const ring r){ return n_IsZero(n,r->cf); }
+static FORCE_INLINE BOOLEAN n_IsOne(number n,  const ring r){ return n_IsOne(n,r->cf); }
+static FORCE_INLINE BOOLEAN n_IsMOne(number n, const ring r){ return n_IsMOne(n,r->cf); }
+static FORCE_INLINE BOOLEAN n_GreaterZero(number n, const ring r){ return n_GreaterZero(n,r->cf); }
+static FORCE_INLINE number n_Init(int i,       const ring r){ return n_Init(i,r->cf); }
+static FORCE_INLINE number n_InpNeg(number n,     const ring r){ return n_InpNeg(n,r->cf); }
+static FORCE_INLINE number n_Invers(number a,  const ring r){ return n_Invers(a,r->cf); }
+static FORCE_INLINE int    n_Size(number n,    const ring r){ return n_Size(n,r->cf); }
+static FORCE_INLINE void   n_Normalize(number& n, const ring r){ return n_Normalize(n,r->cf); }
+static FORCE_INLINE void   n_Write(number& n,  const ring r){ return n_Write(n, r->cf, rShortOut(r)); }
+static FORCE_INLINE number n_GetDenom(number& n, const ring r){ return n_GetDenom(n, r->cf);}
+static FORCE_INLINE number n_GetNumerator(number& n, const ring r){ return n_GetNumerator(n, r->cf);}
+static FORCE_INLINE void   n_Power(number a, int b, number *res, const ring r){ n_Power(a,b,res,r->cf); }
+static FORCE_INLINE number n_Mult(number a, number b, const ring r){ return n_Mult(a, b, r->cf);}
+static FORCE_INLINE void n_InpMult(number &a, number b, const ring r){ n_InpMult(a,b,r->cf); }
+static FORCE_INLINE number n_Sub(number a, number b, const ring r){ return n_Sub(a, b, r->cf);}
+static FORCE_INLINE number n_Add(number a, number b, const ring r){ return n_Add(a, b, r->cf);}
+static FORCE_INLINE number n_Div(number a, number b, const ring r){ return n_Div(a,b, r->cf);}
+static FORCE_INLINE number n_ExactDiv(number a, number b, const ring r){ return n_ExactDiv(a,b, r->cf);}
+static FORCE_INLINE number n_Gcd(number a, number b, const ring r){ return n_Gcd(a,b, r->cf);}
+
+#ifdef HAVE_RINGS
+static FORCE_INLINE BOOLEAN n_IsUnit(number n, const ring r){ return n_IsUnit(n, r->cf);}
+static FORCE_INLINE number n_GetUnit(number n, const ring r){ return n_GetUnit(n, r->cf);}
+static FORCE_INLINE BOOLEAN n_DivBy(number a, number b, const ring r){ return n_DivBy(a,b, r->cf);}
+#endif
+
+static FORCE_INLINE int n_ParDeg(number n, const ring r){ assume(r != NULL); assume(r->cf != NULL); return n_ParDeg(n,r->cf); }
+
+#endif /* COEFFRINGS_H */
diff --git a/libpolys/polys/ext_fields/algext.cc b/libpolys/polys/ext_fields/algext.cc
new file mode 100644
index 0000000..4c7039e
--- /dev/null
+++ b/libpolys/polys/ext_fields/algext.cc
@@ -0,0 +1,1663 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/**
+  * ABSTRACT: numbers in an algebraic extension field K[a] / < f(a) >
+  *           Assuming that we have a coeffs object cf, then these numbers
+  *           are polynomials in the polynomial ring K[a] represented by
+  *           cf->extRing.
+  *           IMPORTANT ASSUMPTIONS:
+  *           1.) So far we assume that cf->extRing is a valid polynomial
+  *               ring in exactly one variable, i.e., K[a], where K is allowed
+  *               to be any field (representable in SINGULAR and which may
+  *               itself be some extension field, thus allowing for extension
+  *               towers).
+  *           2.) Moreover, this implementation assumes that
+  *               cf->extRing->qideal is not NULL but an ideal with at
+  *               least one non-zero generator which may be accessed by
+  *               cf->extRing->qideal->m[0] and which represents the minimal
+  *               polynomial f(a) of the extension variable 'a' in K[a].
+  *           3.) As soon as an std method for polynomial rings becomes
+  *               availabe, all reduction steps modulo f(a) should be replaced
+  *               by a call to std. Moreover, in this situation one can finally
+  *               move from K[a] / < f(a) > to
+  *                  K[a_1, ..., a_s] / I, with I some zero-dimensional ideal
+  *                                        in K[a_1, ..., a_s] given by a lex
+  *                                        Gröbner basis.
+  *               The code in algext.h and algext.cc is then capable of
+  *               computing in K[a_1, ..., a_s] / I.
+  **/
+
+
+
+
+#include <misc/auxiliary.h>
+
+#include <omalloc/omalloc.h>
+
+#include <reporter/reporter.h>
+
+#include <coeffs/coeffs.h>
+#include <coeffs/numbers.h>
+
+#include <coeffs/longrat.h>
+
+#include <polys/monomials/ring.h>
+#include <polys/monomials/p_polys.h>
+#include <polys/simpleideals.h>
+
+#include <polys/PolyEnumerator.h>
+
+#include <factory/factory.h>
+#include <polys/clapconv.h>
+#include <polys/clapsing.h>
+#include <polys/prCopy.h>
+
+#include <polys/ext_fields/algext.h>
+#define TRANSEXT_PRIVATES 1
+#include <polys/ext_fields/transext.h>
+
+#ifdef LDEBUG
+#define naTest(a) naDBTest(a,__FILE__,__LINE__,cf)
+BOOLEAN  naDBTest(number a, const char *f, const int l, const coeffs r);
+#else
+#define naTest(a) do {} while (0)
+#endif
+
+/// Our own type!
+static const n_coeffType ID = n_algExt;
+
+/* polynomial ring in which our numbers live */
+#define naRing cf->extRing
+
+/* coeffs object in which the coefficients of our numbers live;
+ * methods attached to naCoeffs may be used to compute with the
+ * coefficients of our numbers, e.g., use naCoeffs->nAdd to add
+ * coefficients of our numbers */
+#define naCoeffs cf->extRing->cf
+
+/* minimal polynomial */
+#define naMinpoly naRing->qideal->m[0]
+
+/// forward declarations
+BOOLEAN  naGreaterZero(number a, const coeffs cf);
+BOOLEAN  naGreater(number a, number b, const coeffs cf);
+BOOLEAN  naEqual(number a, number b, const coeffs cf);
+BOOLEAN  naIsOne(number a, const coeffs cf);
+BOOLEAN  naIsMOne(number a, const coeffs cf);
+BOOLEAN  naIsZero(number a, const coeffs cf);
+number   naInit(long i, const coeffs cf);
+int      naInt(number &a, const coeffs cf);
+number   naNeg(number a, const coeffs cf);
+number   naInvers(number a, const coeffs cf);
+number   naAdd(number a, number b, const coeffs cf);
+number   naSub(number a, number b, const coeffs cf);
+number   naMult(number a, number b, const coeffs cf);
+number   naDiv(number a, number b, const coeffs cf);
+void     naPower(number a, int exp, number *b, const coeffs cf);
+number   naCopy(number a, const coeffs cf);
+void     naWriteLong(number &a, const coeffs cf);
+void     naWriteShort(number &a, const coeffs cf);
+number   naGetDenom(number &a, const coeffs cf);
+number   naGetNumerator(number &a, const coeffs cf);
+number   naGcd(number a, number b, const coeffs cf);
+int      naSize(number a, const coeffs cf);
+void     naDelete(number *a, const coeffs cf);
+void     naCoeffWrite(const coeffs cf, BOOLEAN details);
+//number   naIntDiv(number a, number b, const coeffs cf);
+const char * naRead(const char *s, number *a, const coeffs cf);
+
+static BOOLEAN naCoeffIsEqual(const coeffs cf, n_coeffType n, void * param);
+
+
+/// returns NULL if p == NULL, otherwise makes p monic by dividing
+///   by its leading coefficient (only done if this is not already 1);
+///   this assumes that we are over a ground field so that division
+///   is well-defined;
+///   modifies p
+// void      p_Monic(poly p, const ring r);
+
+///   assumes that p and q are univariate polynomials in r,
+///   mentioning the same variable;
+///   assumes a global monomial ordering in r;
+///   assumes that not both p and q are NULL;
+///   returns the gcd of p and q;
+///   leaves p and q unmodified
+// poly      p_Gcd(const poly p, const poly q, const ring r);
+
+/* returns NULL if p == NULL, otherwise makes p monic by dividing
+   by its leading coefficient (only done if this is not already 1);
+   this assumes that we are over a ground field so that division
+   is well-defined;
+   modifies p */
+static inline void p_Monic(poly p, const ring r)
+{
+  if (p == NULL) return;
+  number n = n_Init(1, r->cf);
+  if (p->next==NULL) { p_SetCoeff(p,n,r); return; }
+  poly pp = p;
+  number lc = p_GetCoeff(p, r);
+  if (n_IsOne(lc, r->cf)) return;
+  number lcInverse = n_Invers(lc, r->cf);
+  p_SetCoeff(p, n, r);   // destroys old leading coefficient!
+  pIter(p);
+  while (p != NULL)
+  {
+    number n = n_Mult(p_GetCoeff(p, r), lcInverse, r->cf);
+    n_Normalize(n,r->cf);
+    p_SetCoeff(p, n, r);   // destroys old leading coefficient!
+    pIter(p);
+  }
+  n_Delete(&lcInverse, r->cf);
+  p = pp;
+}
+
+/// see p_Gcd;
+///   additional assumption: deg(p) >= deg(q);
+///   must destroy p and q (unless one of them is returned)
+static inline poly p_GcdHelper(poly &p, poly &q, const ring r)
+{
+  while (q != NULL)
+  {
+    p_PolyDiv(p, q, FALSE, r);
+    // swap p and q:
+    poly& t = q;
+    q = p;
+    p = t;
+
+  }
+  return p;
+}
+
+/* assumes that p and q are univariate polynomials in r,
+   mentioning the same variable;
+   assumes a global monomial ordering in r;
+   assumes that not both p and q are NULL;
+   returns the gcd of p and q;
+   leaves p and q unmodified */
+static inline poly      p_Gcd(const poly p, const poly q, const ring r)
+{
+  assume((p != NULL) || (q != NULL));
+
+  poly a = p; poly b = q;
+  if (p_Deg(a, r) < p_Deg(b, r)) { a = q; b = p; }
+  a = p_Copy(a, r); b = p_Copy(b, r);
+
+  /* We have to make p monic before we return it, so that if the
+     gcd is a unit in the ground field, we will actually return 1. */
+  a = p_GcdHelper(a, b, r);
+  p_Monic(a, r);
+  return a;
+}
+
+/* see p_ExtGcd;
+   additional assumption: deg(p) >= deg(q);
+   must destroy p and q (unless one of them is returned) */
+static inline poly p_ExtGcdHelper(poly &p, poly &pFactor, poly &q, poly &qFactor,
+                                  ring r)
+{
+  if (q == NULL)
+  {
+    qFactor = NULL;
+    pFactor = p_ISet(1, r);
+    p_SetCoeff(pFactor, n_Invers(p_GetCoeff(p, r), r->cf), r);
+    p_Monic(p, r);
+    return p;
+  }
+  else
+  {
+    poly pDivQ = p_PolyDiv(p, q, TRUE, r);
+    poly ppFactor = NULL; poly qqFactor = NULL;
+    poly theGcd = p_ExtGcdHelper(q, qqFactor, p, ppFactor, r);
+    pFactor = ppFactor;
+    qFactor = p_Add_q(qqFactor,
+                      p_Neg(p_Mult_q(pDivQ, p_Copy(ppFactor, r), r), r),
+                      r);
+    return theGcd;
+  }
+}
+
+
+/* assumes that p and q are univariate polynomials in r,
+   mentioning the same variable;
+   assumes a global monomial ordering in r;
+   assumes that not both p and q are NULL;
+   returns the gcd of p and q;
+   moreover, afterwards pFactor and qFactor contain appropriate
+   factors such that gcd(p, q) = p * pFactor + q * qFactor;
+   leaves p and q unmodified */
+poly p_ExtGcd(poly p, poly &pFactor, poly q, poly &qFactor, ring r)
+{
+  assume((p != NULL) || (q != NULL));
+  poly a = p; poly b = q; BOOLEAN aCorrespondsToP = TRUE;
+  if (p_Deg(a, r) < p_Deg(b, r))
+    { a = q; b = p; aCorrespondsToP = FALSE; }
+  a = p_Copy(a, r); b = p_Copy(b, r);
+  poly aFactor = NULL; poly bFactor = NULL;
+  poly theGcd = p_ExtGcdHelper(a, aFactor, b, bFactor, r);
+  if (aCorrespondsToP) { pFactor = aFactor; qFactor = bFactor; }
+  else                 { pFactor = bFactor; qFactor = aFactor; }
+  return theGcd;
+}
+
+
+
+#ifdef LDEBUG
+BOOLEAN naDBTest(number a, const char *f, const int l, const coeffs cf)
+{
+  if (a == NULL) return TRUE;
+  p_Test((poly)a, naRing);
+  if (getCoeffType(cf)==n_algExt)
+  {
+    if((((poly)a)!=naMinpoly)
+    && p_Totaldegree((poly)a, naRing) >= p_Totaldegree(naMinpoly, naRing)
+    && (p_Totaldegree((poly)a, naRing)> 1)) // allow to output par(1)
+    {
+      dReportError("deg >= deg(minpoly) in %s:%d\n",f,l);
+      return FALSE;
+    }
+  }
+  return TRUE;
+}
+#endif
+
+void heuristicReduce(poly &p, poly reducer, const coeffs cf);
+void definiteReduce(poly &p, poly reducer, const coeffs cf);
+
+/* returns the bottom field in this field extension tower; if the tower
+   is flat, i.e., if there is no extension, then r itself is returned;
+   as a side-effect, the counter 'height' is filled with the height of
+   the extension tower (in case the tower is flat, 'height' is zero) */
+static coeffs nCoeff_bottom(const coeffs r, int &height)
+{
+  assume(r != NULL);
+  coeffs cf = r;
+  height = 0;
+  while (nCoeff_is_Extension(cf))
+  {
+    assume(cf->extRing != NULL); assume(cf->extRing->cf != NULL);
+    cf = cf->extRing->cf;
+    height++;
+  }
+  return cf;
+}
+
+BOOLEAN naIsZero(number a, const coeffs cf)
+{
+  naTest(a);
+  return (a == NULL);
+}
+
+void naDelete(number * a, const coeffs cf)
+{
+  if (*a == NULL) return;
+  if (((poly)*a)==naMinpoly) { *a=NULL;return;}
+  poly aAsPoly = (poly)(*a);
+  p_Delete(&aAsPoly, naRing);
+  *a = NULL;
+}
+
+BOOLEAN naEqual(number a, number b, const coeffs cf)
+{
+  naTest(a); naTest(b);
+  /// simple tests
+  if (a == NULL) return (b == NULL);
+  if (b == NULL) return (a == NULL);
+  return p_EqualPolys((poly)a,(poly)b,naRing);
+}
+
+number naCopy(number a, const coeffs cf)
+{
+  naTest(a);
+  if (a == NULL) return NULL;
+  if (((poly)a)==naMinpoly) return a;
+  return (number)p_Copy((poly)a, naRing);
+}
+
+number naGetNumerator(number &a, const coeffs cf)
+{
+  return naCopy(a, cf);
+}
+
+number naGetDenom(number &a, const coeffs cf)
+{
+  naTest(a);
+  return naInit(1, cf);
+}
+
+BOOLEAN naIsOne(number a, const coeffs cf)
+{
+  naTest(a);
+  poly aAsPoly = (poly)a;
+  if ((a==NULL) || (!p_IsConstant(aAsPoly, naRing))) return FALSE;
+  return n_IsOne(p_GetCoeff(aAsPoly, naRing), naCoeffs);
+}
+
+BOOLEAN naIsMOne(number a, const coeffs cf)
+{
+  naTest(a);
+  poly aAsPoly = (poly)a;
+  if ((a==NULL) || (!p_IsConstant(aAsPoly, naRing))) return FALSE;
+  return n_IsMOne(p_GetCoeff(aAsPoly, naRing), naCoeffs);
+}
+
+/// this is in-place, modifies a
+number naNeg(number a, const coeffs cf)
+{
+  naTest(a);
+  if (a != NULL) a = (number)p_Neg((poly)a, naRing);
+  return a;
+}
+
+number naInit(long i, const coeffs cf)
+{
+  if (i == 0) return NULL;
+  else        return (number)p_ISet(i, naRing);
+}
+
+int naInt(number &a, const coeffs cf)
+{
+  naTest(a);
+  poly aAsPoly = (poly)a;
+  if(aAsPoly == NULL)
+    return 0;
+  if (!p_IsConstant(aAsPoly, naRing))
+    return 0;
+  assume( aAsPoly != NULL );
+  return n_Int(p_GetCoeff(aAsPoly, naRing), naCoeffs);
+}
+
+/* TRUE iff (a != 0 and (b == 0 or deg(a) > deg(b) or (deg(a)==deg(b) && lc(a)>lc(b))) */
+BOOLEAN naGreater(number a, number b, const coeffs cf)
+{
+  naTest(a); naTest(b);
+  if (naIsZero(a, cf))
+  {
+    if (naIsZero(b, cf)) return FALSE;
+    return !n_GreaterZero(pGetCoeff((poly)b),cf);
+  }
+  if (naIsZero(b, cf))
+  {
+    return n_GreaterZero(pGetCoeff((poly)a),cf);
+  }
+  int aDeg = p_Totaldegree((poly)a, naRing);
+  int bDeg = p_Totaldegree((poly)b, naRing);
+  if (aDeg>bDeg) return TRUE;
+  if (aDeg<bDeg) return FALSE;
+  return n_Greater(pGetCoeff((poly)a),pGetCoeff((poly)b),naCoeffs);
+}
+
+/* TRUE iff a != 0 and (LC(a) > 0 or deg(a) > 0) */
+BOOLEAN naGreaterZero(number a, const coeffs cf)
+{
+  naTest(a);
+  if (a == NULL)                                            return FALSE;
+  if (n_GreaterZero(p_GetCoeff((poly)a, naRing), naCoeffs)) return TRUE;
+  if (p_Totaldegree((poly)a, naRing) > 0)                   return TRUE;
+  return FALSE;
+}
+
+void naCoeffWrite(const coeffs cf, BOOLEAN details)
+{
+  assume( cf != NULL );
+
+  const ring A = cf->extRing;
+
+  assume( A != NULL );
+  assume( A->cf != NULL );
+
+  n_CoeffWrite(A->cf, details);
+
+//  rWrite(A);
+
+  const int P = rVar(A);
+  assume( P > 0 );
+
+  Print("//   %d parameter    : ", P);
+
+  for (int nop=0; nop < P; nop ++)
+    Print("%s ", rRingVar(nop, A));
+
+  PrintLn();
+
+  const ideal I = A->qideal;
+
+  assume( I != NULL );
+  assume( IDELEMS(I) == 1 );
+
+
+  if ( details )
+  {
+    PrintS("//   minpoly        : (");
+    p_Write0( I->m[0], A);
+    PrintS(")");
+  }
+  else
+    PrintS("//   minpoly        : ...");
+
+  PrintLn();
+
+/*
+  char *x = rRingVar(0, A);
+
+  Print("//   Coefficients live in the extension field K[%s]/<f(%s)>\n", x, x);
+  Print("//   with the minimal polynomial f(%s) = %s\n", x,
+        p_String(A->qideal->m[0], A));
+  PrintS("//   and K: ");
+*/
+}
+
+number naAdd(number a, number b, const coeffs cf)
+{
+  naTest(a); naTest(b);
+  if (a == NULL) return naCopy(b, cf);
+  if (b == NULL) return naCopy(a, cf);
+  poly aPlusB = p_Add_q(p_Copy((poly)a, naRing),
+                        p_Copy((poly)b, naRing), naRing);
+  //definiteReduce(aPlusB, naMinpoly, cf);
+  return (number)aPlusB;
+}
+
+number naSub(number a, number b, const coeffs cf)
+{
+  naTest(a); naTest(b);
+  if (b == NULL) return naCopy(a, cf);
+  poly minusB = p_Neg(p_Copy((poly)b, naRing), naRing);
+  if (a == NULL) return (number)minusB;
+  poly aMinusB = p_Add_q(p_Copy((poly)a, naRing), minusB, naRing);
+  //definiteReduce(aMinusB, naMinpoly, cf);
+  return (number)aMinusB;
+}
+
+number naMult(number a, number b, const coeffs cf)
+{
+  naTest(a); naTest(b);
+  if ((a == NULL)||(b == NULL)) return NULL;
+  poly aTimesB = p_Mult_q(p_Copy((poly)a, naRing),
+                          p_Copy((poly)b, naRing), naRing);
+  definiteReduce(aTimesB, naMinpoly, cf);
+  p_Normalize(aTimesB,naRing);
+  return (number)aTimesB;
+}
+
+number naDiv(number a, number b, const coeffs cf)
+{
+  naTest(a); naTest(b);
+  if (b == NULL) WerrorS(nDivBy0);
+  if (a == NULL) return NULL;
+  poly bInverse = (poly)naInvers(b, cf);
+  if(bInverse != NULL) // b is non-zero divisor!
+  {
+    poly aDivB = p_Mult_q(p_Copy((poly)a, naRing), bInverse, naRing);
+    definiteReduce(aDivB, naMinpoly, cf);
+    p_Normalize(aDivB,naRing);
+    return (number)aDivB;
+  }
+  return NULL;
+}
+
+/* 0^0 = 0;
+   for |exp| <= 7 compute power by a simple multiplication loop;
+   for |exp| >= 8 compute power along binary presentation of |exp|, e.g.
+      p^13 = p^1 * p^4 * p^8, where we utilise that
+      p^(2^(k+1)) = p^(2^k) * p^(2^k);
+   intermediate reduction modulo the minimal polynomial is controlled by
+   the in-place method heuristicReduce(poly, poly, coeffs); see there.
+*/
+void naPower(number a, int exp, number *b, const coeffs cf)
+{
+  naTest(a);
+
+  /* special cases first */
+  if (a == NULL)
+  {
+    if (exp >= 0) *b = NULL;
+    else          WerrorS(nDivBy0);
+    return;
+  }
+  else if (exp ==  0) { *b = naInit(1, cf); return; }
+  else if (exp ==  1) { *b = naCopy(a, cf); return; }
+  else if (exp == -1) { *b = naInvers(a, cf); return; }
+
+  int expAbs = exp; if (expAbs < 0) expAbs = -expAbs;
+
+  /* now compute a^expAbs */
+  poly pow; poly aAsPoly = (poly)a;
+  if (expAbs <= 7)
+  {
+    pow = p_Copy(aAsPoly, naRing);
+    for (int i = 2; i <= expAbs; i++)
+    {
+      pow = p_Mult_q(pow, p_Copy(aAsPoly, naRing), naRing);
+      heuristicReduce(pow, naMinpoly, cf);
+    }
+    definiteReduce(pow, naMinpoly, cf);
+  }
+  else
+  {
+    pow = p_ISet(1, naRing);
+    poly factor = p_Copy(aAsPoly, naRing);
+    while (expAbs != 0)
+    {
+      if (expAbs & 1)
+      {
+        pow = p_Mult_q(pow, p_Copy(factor, naRing), naRing);
+        heuristicReduce(pow, naMinpoly, cf);
+      }
+      expAbs = expAbs / 2;
+      if (expAbs != 0)
+      {
+        factor = p_Mult_q(factor, p_Copy(factor, naRing), naRing);
+        heuristicReduce(factor, naMinpoly, cf);
+      }
+    }
+    p_Delete(&factor, naRing);
+    definiteReduce(pow, naMinpoly, cf);
+  }
+
+  /* invert if original exponent was negative */
+  number n = (number)pow;
+  if (exp < 0)
+  {
+    number m = naInvers(n, cf);
+    naDelete(&n, cf);
+    n = m;
+  }
+  *b = n;
+}
+
+/* may reduce p modulo the reducer by calling definiteReduce;
+   the decision is made based on the following heuristic
+   (which should also only be changed here in this method):
+      if (deg(p) > 10*deg(reducer) then perform reduction;
+   modifies p */
+void heuristicReduce(poly &p, poly reducer, const coeffs cf)
+{
+  #ifdef LDEBUG
+  p_Test((poly)p, naRing);
+  p_Test((poly)reducer, naRing);
+  #endif
+  if (p_Totaldegree(p, naRing) > 10 * p_Totaldegree(reducer, naRing))
+    definiteReduce(p, reducer, cf);
+}
+
+void naWriteLong(number &a, const coeffs cf)
+{
+  naTest(a);
+  if (a == NULL)
+    StringAppendS("0");
+  else
+  {
+    poly aAsPoly = (poly)a;
+    /* basically, just write aAsPoly using p_Write,
+       but use brackets around the output, if a is not
+       a constant living in naCoeffs = cf->extRing->cf */
+    BOOLEAN useBrackets = !(p_IsConstant(aAsPoly, naRing));
+    if (useBrackets) StringAppendS("(");
+    p_String0Long(aAsPoly, naRing, naRing);
+    if (useBrackets) StringAppendS(")");
+  }
+}
+
+void naWriteShort(number &a, const coeffs cf)
+{
+  naTest(a);
+  if (a == NULL)
+    StringAppendS("0");
+  else
+  {
+    poly aAsPoly = (poly)a;
+    /* basically, just write aAsPoly using p_Write,
+       but use brackets around the output, if a is not
+       a constant living in naCoeffs = cf->extRing->cf */
+    BOOLEAN useBrackets = !(p_IsConstant(aAsPoly, naRing));
+    if (useBrackets) StringAppendS("(");
+    p_String0Short(aAsPoly, naRing, naRing);
+    if (useBrackets) StringAppendS(")");
+  }
+}
+
+const char * naRead(const char *s, number *a, const coeffs cf)
+{
+  poly aAsPoly;
+  const char * result = p_Read(s, aAsPoly, naRing);
+  if (aAsPoly!=NULL) definiteReduce(aAsPoly, naMinpoly, cf);
+  *a = (number)aAsPoly;
+  return result;
+}
+
+#if 0
+/* implemented by the rule lcm(a, b) = a * b / gcd(a, b) */
+number naLcm(number a, number b, const coeffs cf)
+{
+  naTest(a); naTest(b);
+  if (a == NULL) return NULL;
+  if (b == NULL) return NULL;
+  number theProduct = (number)p_Mult_q(p_Copy((poly)a, naRing),
+                                       p_Copy((poly)b, naRing), naRing);
+  /* note that theProduct needs not be reduced w.r.t. naMinpoly;
+     but the final division will take care of the necessary reduction */
+  number theGcd = naGcd(a, b, cf);
+  return naDiv(theProduct, theGcd, cf);
+}
+#endif
+number napNormalizeHelper(number b, const coeffs cf)
+{
+  number h=n_Init(1,naRing->cf);
+  poly bb=(poly)b;
+  number d;
+  while(bb!=NULL)
+  {
+    d=n_NormalizeHelper(h,pGetCoeff(bb), naRing->cf);
+    n_Delete(&h,naRing->cf);
+    h=d;
+    pIter(bb);
+  }
+  return h;
+}
+number naLcmContent(number a, number b, const coeffs cf)
+{
+  if (nCoeff_is_Zp(naRing->cf)) return naCopy(a,cf);
+#if 0
+  else {
+    number g = ndGcd(a, b, cf);
+    return g;
+  }
+#else
+  {
+    a=(number)p_Copy((poly)a,naRing);
+    number t=napNormalizeHelper(b,cf);
+    if(!n_IsOne(t,naRing->cf))
+    {
+      number bt, rr;
+      poly xx=(poly)a;
+      while (xx!=NULL)
+      {
+        bt = n_SubringGcd(t, pGetCoeff(xx), naRing->cf);
+        rr = n_Mult(t, pGetCoeff(xx), naRing->cf);
+        n_Delete(&pGetCoeff(xx),naRing->cf);
+        pGetCoeff(xx) = n_Div(rr, bt, naRing->cf);
+        n_Normalize(pGetCoeff(xx),naRing->cf);
+        n_Delete(&bt,naRing->cf);
+        n_Delete(&rr,naRing->cf);
+        pIter(xx);
+      }
+    }
+    n_Delete(&t,naRing->cf);
+    return (number) a;
+  }
+#endif
+}
+
+/* expects *param to be castable to AlgExtInfo */
+static BOOLEAN naCoeffIsEqual(const coeffs cf, n_coeffType n, void * param)
+{
+  if (n_algExt != n) return FALSE;
+  AlgExtInfo *e = (AlgExtInfo *)param;
+  /* for extension coefficient fields we expect the underlying
+     polynomial rings to be IDENTICAL, i.e. the SAME OBJECT;
+     this expectation is based on the assumption that we have properly
+     registered cf and perform reference counting rather than creating
+     multiple copies of the same coefficient field/domain/ring */
+  if (naRing == e->r)
+    return TRUE;
+  /* (Note that then also the minimal ideals will necessarily be
+     the same, as they are attached to the ring.) */
+
+  // NOTE: Q(a)[x] && Q(a)[y] should better share the _same_ Q(a)...
+  if( rEqual(naRing, e->r, TRUE) ) // also checks the equality of qideals
+  {
+    const ideal mi = naRing->qideal;
+    assume( IDELEMS(mi) == 1 );
+    const ideal ii = e->r->qideal;
+    assume( IDELEMS(ii) == 1 );
+
+    // TODO: the following should be extended for 2 *equal* rings...
+    assume( p_EqualPolys(mi->m[0], ii->m[0], naRing, e->r) );
+
+    rDelete(e->r);
+
+    return TRUE;
+  }
+
+  return FALSE;
+
+}
+
+int naSize(number a, const coeffs cf)
+{
+  if (a == NULL) return -1;
+  /* this has been taken from the old implementation of field extensions,
+     where we computed the sum of the degree and the number of terms in
+     (poly)a; so we leave it at that, for the time being;
+     maybe, the number of terms alone is a better measure? */
+  poly aAsPoly = (poly)a;
+  int theDegree = 0; int noOfTerms = 0;
+  while (aAsPoly != NULL)
+  {
+    noOfTerms++;
+    int d = p_GetExp(aAsPoly, 1, naRing);
+    if (d > theDegree) theDegree = d;
+    pIter(aAsPoly);
+  }
+  return theDegree + noOfTerms;
+}
+
+/* performs polynomial division and overrides p by the remainder
+   of division of p by the reducer;
+   modifies p */
+void definiteReduce(poly &p, poly reducer, const coeffs cf)
+{
+  #ifdef LDEBUG
+  p_Test((poly)p, naRing);
+  p_Test((poly)reducer, naRing);
+  #endif
+  if ((p!=NULL) && (p_GetExp(p,1,naRing)>=p_GetExp(reducer,1,naRing)))
+  {
+    p_PolyDiv(p, reducer, FALSE, naRing);
+  }
+}
+
+void  naNormalize(number &a, const coeffs cf)
+{
+  poly aa=(poly)a;
+  if (aa!=naMinpoly)
+    definiteReduce(aa,naMinpoly,cf);
+  a=(number)aa;
+}
+
+number naConvFactoryNSingN( const CanonicalForm n, const coeffs cf)
+{
+  if (n.isZero()) return NULL;
+  poly p=convFactoryPSingP(n,naRing);
+  return (number)p;
+}
+CanonicalForm naConvSingNFactoryN( number n, BOOLEAN /*setChar*/, const coeffs cf )
+{
+  naTest(n);
+  if (n==NULL) return CanonicalForm(0);
+
+  return convSingPFactoryP((poly)n,naRing);
+}
+
+/* IMPORTANT NOTE: Since an algebraic field extension is again a field,
+                   the gcd of two elements is not very interesting. (It
+                   is actually any unit in the field, i.e., any non-
+                   zero element.) Note that the below method does not operate
+                   in this strong sense but rather computes the gcd of
+                   two given elements in the underlying polynomial ring. */
+number naGcd(number a, number b, const coeffs cf)
+{
+  if (a==NULL)  return naCopy(b,cf);
+  if (b==NULL)  return naCopy(a,cf);
+
+  poly ax=(poly)a;
+  poly bx=(poly)b;
+  if (pNext(ax)!=NULL)
+    return (number)p_Copy(ax, naRing);
+  else
+  {
+    if(nCoeff_is_Zp(naRing->cf))
+      return naInit(1,cf);
+    else
+    {
+      number x = n_Copy(pGetCoeff((poly)a),naRing->cf);
+      if (n_IsOne(x,naRing->cf))
+        return (number)p_NSet(x,naRing);
+      while (pNext(ax)!=NULL)
+      {
+        pIter(ax);
+        number y = n_SubringGcd(x, pGetCoeff(ax), naRing->cf);
+        n_Delete(&x,naRing->cf);
+        x = y;
+        if (n_IsOne(x,naRing->cf))
+          return (number)p_NSet(x,naRing);
+      }
+      do
+      {
+        number y = n_SubringGcd(x, pGetCoeff(bx), naRing->cf);
+        n_Delete(&x,naRing->cf);
+        x = y;
+        if (n_IsOne(x,naRing->cf))
+          return (number)p_NSet(x,naRing);
+        pIter(bx);
+      }
+      while (bx!=NULL);
+      return (number)p_NSet(x,naRing);
+    }
+  }
+#if 0
+  naTest(a); naTest(b);
+  const ring R = naRing;
+  return (number) singclap_gcd(p_Copy((poly)a, R), p_Copy((poly)b, R), R);
+#endif
+//  return (number)p_Gcd((poly)a, (poly)b, naRing);
+}
+
+number naInvers(number a, const coeffs cf)
+{
+  naTest(a);
+  if (a == NULL) WerrorS(nDivBy0);
+
+  poly aFactor = NULL; poly mFactor = NULL; poly theGcd = NULL;
+// singclap_extgcd!
+  const BOOLEAN ret = singclap_extgcd ((poly)a, naMinpoly, theGcd, aFactor, mFactor, naRing);
+
+  assume( !ret );
+
+//  if( ret ) theGcd = p_ExtGcd((poly)a, aFactor, naMinpoly, mFactor, naRing);
+
+  naTest((number)theGcd); naTest((number)aFactor); naTest((number)mFactor);
+  p_Delete(&mFactor, naRing);
+
+  //  /* the gcd must be 1 since naMinpoly is irreducible and a != NULL: */
+  //  assume(naIsOne((number)theGcd, cf));
+
+  if( !naIsOne((number)theGcd, cf) )
+  {
+    WerrorS("zero divisor found - your minpoly is not irreducible");
+    p_Delete(&aFactor, naRing); aFactor = NULL;
+  }
+  p_Delete(&theGcd, naRing);
+
+  return (number)(aFactor);
+}
+
+/* assumes that src = Q or Z, dst = Q(a) */
+number naMap00(number a, const coeffs src, const coeffs dst)
+{
+  if (n_IsZero(a, src)) return NULL;
+  assume(src->rep == dst->extRing->cf->rep);
+  poly result = p_One(dst->extRing);
+  p_SetCoeff(result, n_Copy(a, src), dst->extRing);
+  return (number)result;
+}
+
+/* assumes that src = Z, dst = K(a) */
+number naMapZ0(number a, const coeffs src, const coeffs dst)
+{
+  if (n_IsZero(a, src)) return NULL;
+  poly result = p_One(dst->extRing);
+  nMapFunc nMap=n_SetMap(src,dst->extRing->cf);
+  p_SetCoeff(result, nMap(a, src, dst->extRing->cf), dst->extRing);
+  if (n_IsZero(pGetCoeff(result),dst->extRing->cf))
+    p_Delete(&result,dst->extRing);
+  return (number)result;
+}
+
+/* assumes that src = Z/p, dst = Q(a) */
+number naMapP0(number a, const coeffs src, const coeffs dst)
+{
+  if (n_IsZero(a, src)) return NULL;
+  /* mapping via intermediate int: */
+  int n = n_Int(a, src);
+  number q = n_Init(n, dst->extRing->cf);
+  poly result = p_One(dst->extRing);
+  p_SetCoeff(result, q, dst->extRing);
+  return (number)result;
+}
+
+#if 0
+/* assumes that either src = Q(a), dst = Q(a), or
+                       src = Z/p(a), dst = Z/p(a)     */
+number naCopyMap(number a, const coeffs src, const coeffs dst)
+{
+  return naCopy(a, dst);
+}
+#endif
+
+number naCopyTrans2AlgExt(number a, const coeffs src, const coeffs dst)
+{
+  assume (nCoeff_is_transExt (src));
+  assume (nCoeff_is_algExt (dst));
+  fraction fa=(fraction)a;
+  poly p, q;
+  if (rSamePolyRep(src->extRing, dst->extRing))
+  {
+    p = p_Copy(NUM(fa),src->extRing);
+    if (!DENIS1(fa))
+    {
+      q = p_Copy(DEN(fa),src->extRing);
+      assume (q != NULL);
+    }
+  }
+  else
+  {
+    assume ((strcmp(rRingVar(0,src->extRing),rRingVar(0,dst->extRing))==0) && (rVar (src->extRing) == rVar (dst->extRing)));
+
+    nMapFunc nMap= n_SetMap (src->extRing->cf, dst->extRing->cf);
+
+    assume (nMap != NULL);
+    p= p_PermPoly (NUM (fa), NULL, src->extRing, dst->extRing,nMap, NULL,rVar (src->extRing));
+    if (!DENIS1(fa))
+    {
+      q= p_PermPoly (DEN (fa), NULL, src->extRing, dst->extRing,nMap, NULL,rVar (src->extRing));
+      assume (q != NULL);
+    }
+  }
+  definiteReduce(p, dst->extRing->qideal->m[0], dst);
+  p_Test (p, dst->extRing);
+  if (!DENIS1(fa))
+  {
+    definiteReduce(q, dst->extRing->qideal->m[0], dst);
+    p_Test (q, dst->extRing);
+    if (q != NULL)
+    {
+      number t= naDiv ((number)p,(number)q, dst);
+      p_Delete (&p, dst->extRing);
+      p_Delete (&q, dst->extRing);
+      return t;
+    }
+    WerrorS ("mapping denominator to zero");
+  }
+  return (number) p;
+}
+
+/* assumes that src = Q, dst = Z/p(a) */
+number naMap0P(number a, const coeffs src, const coeffs dst)
+{
+  if (n_IsZero(a, src)) return NULL;
+  // int p = rChar(dst->extRing);
+
+  number q = nlModP(a, src, dst->extRing->cf); // FIXME? TODO? // extern number nlModP(number q, const coeffs Q, const coeffs Zp); // Map q \in QQ \to pZ
+
+  poly result = p_NSet(q, dst->extRing);
+
+  return (number)result;
+}
+
+/* assumes that src = Z/p, dst = Z/p(a) */
+number naMapPP(number a, const coeffs src, const coeffs dst)
+{
+  if (n_IsZero(a, src)) return NULL;
+  assume(src == dst->extRing->cf);
+  poly result = p_One(dst->extRing);
+  p_SetCoeff(result, n_Copy(a, src), dst->extRing);
+  return (number)result;
+}
+
+/* assumes that src = Z/u, dst = Z/p(a), where u != p */
+number naMapUP(number a, const coeffs src, const coeffs dst)
+{
+  if (n_IsZero(a, src)) return NULL;
+  /* mapping via intermediate int: */
+  int n = n_Int(a, src);
+  number q = n_Init(n, dst->extRing->cf);
+  poly result = p_One(dst->extRing);
+  p_SetCoeff(result, q, dst->extRing);
+  return (number)result;
+}
+
+number naGenMap(number a, const coeffs cf, const coeffs dst)
+{
+  if (a==NULL) return NULL;
+
+  const ring rSrc = cf->extRing;
+  const ring rDst = dst->extRing;
+
+  const nMapFunc nMap=n_SetMap(rSrc->cf,rDst->cf);
+  poly f = (poly)a;
+  poly g = prMapR(f, nMap, rSrc, rDst);
+
+  n_Test((number)g, dst);
+  return (number)g;
+}
+
+number naGenTrans2AlgExt(number a, const coeffs cf, const coeffs dst)
+{
+  if (a==NULL) return NULL;
+
+  const ring rSrc = cf->extRing;
+  const ring rDst = dst->extRing;
+
+  const nMapFunc nMap=n_SetMap(rSrc->cf,rDst->cf);
+  fraction f = (fraction)a;
+  poly g = prMapR(NUM(f), nMap, rSrc, rDst);
+
+  number result=NULL;
+  poly h = NULL;
+
+  if (!DENIS1(f))
+     h = prMapR(DEN(f), nMap, rSrc, rDst);
+
+  if (h!=NULL)
+  {
+    result=naDiv((number)g,(number)h,dst);
+    p_Delete(&g,dst->extRing);
+    p_Delete(&h,dst->extRing);
+  }
+  else
+    result=(number)g;
+
+  n_Test((number)result, dst);
+  return (number)result;
+}
+
+nMapFunc naSetMap(const coeffs src, const coeffs dst)
+{
+  /* dst is expected to be an algebraic field extension */
+  assume(getCoeffType(dst) == ID);
+
+  if( src == dst ) return ndCopyMap;
+
+  int h = 0; /* the height of the extension tower given by dst */
+  coeffs bDst = nCoeff_bottom(dst, h); /* the bottom field in the tower dst */
+  coeffs bSrc = nCoeff_bottom(src, h); /* the bottom field in the tower src */
+
+  /* for the time being, we only provide maps if h = 1 or 0 */
+  if (h==0)
+  {
+    if ((src->rep==n_rep_gap_rat) && nCoeff_is_Q(bDst))
+      return naMap00;                            /// Q or Z     -->  Q(a)
+    if ((src->rep==n_rep_gap_gmp) && nCoeff_is_Q(bDst))
+      return naMapZ0;                            /// Z     -->  Q(a)
+    if (nCoeff_is_Zp(src) && nCoeff_is_Q(bDst))
+      return naMapP0;                            /// Z/p   -->  Q(a)
+    if (nCoeff_is_Q(src) && nCoeff_is_Zp(bDst))
+      return naMap0P;                            /// Q      --> Z/p(a)
+    if ((src->rep==n_rep_gap_gmp) && nCoeff_is_Zp(bDst))
+      return naMapZ0;                            /// Z     -->  Z/p(a)
+    if (nCoeff_is_Zp(src) && nCoeff_is_Zp(bDst))
+    {
+      if (src->ch == dst->ch) return naMapPP;    /// Z/p    --> Z/p(a)
+      else return naMapUP;                       /// Z/u    --> Z/p(a)
+    }
+  }
+  if (h != 1) return NULL;
+  if ((!nCoeff_is_Zp(bDst)) && (!nCoeff_is_Q(bDst))) return NULL;
+  if ((!nCoeff_is_Zp(bSrc)) && (!nCoeff_is_Q(bSrc))) return NULL;
+
+  nMapFunc nMap=n_SetMap(src->extRing->cf,dst->extRing->cf);
+  if (rSamePolyRep(src->extRing, dst->extRing) && (strcmp(rRingVar(0, src->extRing), rRingVar(0, dst->extRing)) == 0))
+  {
+    if (src->type==n_algExt)
+       return ndCopyMap; // naCopyMap;         /// K(a)   --> K(a)
+    else
+       return naCopyTrans2AlgExt;
+  }
+  else if ((nMap!=NULL) && (strcmp(rRingVar(0,src->extRing),rRingVar(0,dst->extRing))==0) && (rVar (src->extRing) == rVar (dst->extRing)))
+  {
+    if (src->type==n_algExt)
+       return naGenMap; // naCopyMap;         /// K(a)   --> K'(a)
+    else
+       return naGenTrans2AlgExt;
+  }
+
+  return NULL;                                           /// default
+}
+
+static int naParDeg(number a, const coeffs cf)
+{
+  if (a == NULL) return -1;
+  poly aa=(poly)a;
+  return cf->extRing->pFDeg(aa,cf->extRing);
+}
+
+/// return the specified parameter as a number in the given alg. field
+static number naParameter(const int iParameter, const coeffs cf)
+{
+  assume(getCoeffType(cf) == ID);
+
+  const ring R = cf->extRing;
+  assume( R != NULL );
+  assume( 0 < iParameter && iParameter <= rVar(R) );
+
+  poly p = p_One(R); p_SetExp(p, iParameter, 1, R); p_Setm(p, R);
+
+  return (number) p;
+}
+
+
+/// if m == var(i)/1 => return i,
+int naIsParam(number m, const coeffs cf)
+{
+  assume(getCoeffType(cf) == ID);
+
+  const ring R = cf->extRing;
+  assume( R != NULL );
+
+  return p_Var( (poly)m, R );
+}
+
+
+static void naClearContent(ICoeffsEnumerator& numberCollectionEnumerator, number& c, const coeffs cf)
+{
+  assume(cf != NULL);
+  assume(getCoeffType(cf) == ID);
+  assume(nCoeff_is_Q_algext(cf)); // only over (Q[a]/m(a)), while the default impl. is used over Zp[a]/m(a) !
+
+  const ring   R = cf->extRing;
+  assume(R != NULL);
+  const coeffs Q = R->cf;
+  assume(Q != NULL);
+  assume(nCoeff_is_Q(Q));
+
+  numberCollectionEnumerator.Reset();
+
+  if( !numberCollectionEnumerator.MoveNext() ) // empty zero polynomial?
+  {
+    c = n_Init(1, cf);
+    return;
+  }
+
+  naTest(numberCollectionEnumerator.Current());
+
+  // part 1, find a small candidate for gcd
+  int s1; int s=2147483647; // max. int
+
+  const BOOLEAN lc_is_pos=naGreaterZero(numberCollectionEnumerator.Current(),cf);
+
+  int normalcount = 0;
+
+  poly cand1, cand;
+
+  do
+  {
+    number& n = numberCollectionEnumerator.Current();
+    naNormalize(n, cf); ++normalcount;
+
+    naTest(n);
+
+    cand1 = (poly)n;
+
+    s1 = p_Deg(cand1, R); // naSize?
+    if (s>s1)
+    {
+      cand = cand1;
+      s = s1;
+    }
+  } while (numberCollectionEnumerator.MoveNext() );
+
+//  assume( nlGreaterZero(cand,cf) ); // cand may be a negative integer!
+
+  cand = p_Copy(cand, R);
+  // part 2: compute gcd(cand,all coeffs)
+
+  numberCollectionEnumerator.Reset();
+
+  int length = 0;
+  while (numberCollectionEnumerator.MoveNext() )
+  {
+    number& n = numberCollectionEnumerator.Current();
+    ++length;
+
+    if( (--normalcount) <= 0)
+      naNormalize(n, cf);
+
+    naTest(n);
+
+//    p_InpGcd(cand, (poly)n, R);
+
+    cand = singclap_gcd(cand, p_Copy((poly)n, R), R);
+
+//    cand1 = p_Gcd(cand,(poly)n, R); p_Delete(&cand, R); cand = cand1;
+
+    assume( naGreaterZero((number)cand, cf) ); // ???
+/*
+    if(p_IsConstant(cand,R))
+    {
+      c = cand;
+
+      if(!lc_is_pos)
+      {
+        // make the leading coeff positive
+        c = nlNeg(c, cf);
+        numberCollectionEnumerator.Reset();
+
+        while (numberCollectionEnumerator.MoveNext() )
+        {
+          number& nn = numberCollectionEnumerator.Current();
+          nn = nlNeg(nn, cf);
+        }
+      }
+      return;
+    }
+*/
+
+  }
+
+
+  // part3: all coeffs = all coeffs / cand
+  if (!lc_is_pos)
+    cand = p_Neg(cand, R);
+
+  c = (number)cand; naTest(c);
+
+  poly cInverse = (poly)naInvers(c, cf);
+  assume(cInverse != NULL); // c is non-zero divisor!?
+
+
+  numberCollectionEnumerator.Reset();
+
+
+  while (numberCollectionEnumerator.MoveNext() )
+  {
+    number& n = numberCollectionEnumerator.Current();
+
+    assume( length > 0 );
+
+    if( --length > 0 )
+    {
+      assume( cInverse != NULL );
+      n = (number) p_Mult_q(p_Copy(cInverse, R), (poly)n, R);
+    }
+    else
+    {
+      n = (number) p_Mult_q(cInverse, (poly)n, R);
+      cInverse = NULL;
+      assume(length == 0);
+    }
+
+    definiteReduce((poly &)n, naMinpoly, cf);
+  }
+
+  assume(length == 0);
+  assume(cInverse == NULL); //   p_Delete(&cInverse, R);
+
+  // Quick and dirty fix for constant content clearing... !?
+  CRecursivePolyCoeffsEnumerator<NAConverter> itr(numberCollectionEnumerator); // recursively treat the numbers as polys!
+
+  number cc;
+
+  n_ClearContent(itr, cc, Q); // TODO: get rid of (-LC) normalization!?
+
+  // over alg. ext. of Q // takes over the input number
+  c = (number) p_Mult_nn( (poly)c, cc, R);
+//      p_Mult_q(p_NSet(cc, R), , R);
+
+  n_Delete(&cc, Q);
+
+  // TODO: the above is not enough! need GCD's of polynomial coeffs...!
+/*
+  // old and wrong part of p_Content
+    if (rField_is_Q_a(r) && !CLEARENUMERATORS) // should not be used anymore if CLEARENUMERATORS is 1
+    {
+      // we only need special handling for alg. ext.
+      if (getCoeffType(r->cf)==n_algExt)
+      {
+        number hzz = n_Init(1, r->cf->extRing->cf);
+        p=ph;
+        while (p!=NULL)
+        { // each monom: coeff in Q_a
+          poly c_n_n=(poly)pGetCoeff(p);
+          poly c_n=c_n_n;
+          while (c_n!=NULL)
+          { // each monom: coeff in Q
+            d=n_NormalizeHelper(hzz,pGetCoeff(c_n),r->cf->extRing->cf);
+            n_Delete(&hzz,r->cf->extRing->cf);
+            hzz=d;
+            pIter(c_n);
+          }
+          pIter(p);
+        }
+        // hzz contains the 1/lcm of all denominators in c_n_n
+        h=n_Invers(hzz,r->cf->extRing->cf);
+        n_Delete(&hzz,r->cf->extRing->cf);
+        n_Normalize(h,r->cf->extRing->cf);
+        if(!n_IsOne(h,r->cf->extRing->cf))
+        {
+          p=ph;
+          while (p!=NULL)
+          { // each monom: coeff in Q_a
+            poly c_n=(poly)pGetCoeff(p);
+            while (c_n!=NULL)
+            { // each monom: coeff in Q
+              d=n_Mult(h,pGetCoeff(c_n),r->cf->extRing->cf);
+              n_Normalize(d,r->cf->extRing->cf);
+              n_Delete(&pGetCoeff(c_n),r->cf->extRing->cf);
+              pGetCoeff(c_n)=d;
+              pIter(c_n);
+            }
+            pIter(p);
+          }
+        }
+        n_Delete(&h,r->cf->extRing->cf);
+      }
+    }
+*/
+
+
+//  c = n_Init(1, cf); assume(FALSE); // TODO: NOT YET IMPLEMENTED!!!
+}
+
+
+static void naClearDenominators(ICoeffsEnumerator& numberCollectionEnumerator, number& c, const coeffs cf)
+{
+  assume(cf != NULL);
+  assume(getCoeffType(cf) == ID);
+  assume(nCoeff_is_Q_algext(cf)); // only over (Q[a]/m(a)), while the default impl. is used over Zp[a]/m(a) !
+
+  assume(cf->extRing != NULL);
+  const coeffs Q = cf->extRing->cf;
+  assume(Q != NULL);
+  assume(nCoeff_is_Q(Q));
+  number n;
+  CRecursivePolyCoeffsEnumerator<NAConverter> itr(numberCollectionEnumerator); // recursively treat the numbers as polys!
+  n_ClearDenominators(itr, n, Q); // this should probably be fine...
+  c = (number)p_NSet(n, cf->extRing); // over alg. ext. of Q // takes over the input number
+}
+
+void naKillChar(coeffs cf)
+{
+   if ((--cf->extRing->ref) == 0)
+     rDelete(cf->extRing);
+}
+
+char* naCoeffString(const coeffs r) // currently also for tranext.
+{
+  const char* const* p=n_ParameterNames(r);
+  int l=0;
+  int i;
+  for(i=0; i<n_NumberOfParameters(r);i++)
+  {
+    l+=(strlen(p[i])+1);
+  }
+  char *s=(char *)omAlloc(l+10+1);
+  s[0]='\0';
+  snprintf(s,10+1,"%d",r->ch); /* Fp(a) or Q(a) */
+  char tt[2];
+  tt[0]=',';
+  tt[1]='\0';
+  for(i=0; i<n_NumberOfParameters(r);i++)
+  {
+    strcat(s,tt);
+    strcat(s,p[i]);
+  }
+  return s;
+}
+
+number  naChineseRemainder(number *x, number *q,int rl, BOOLEAN sym,const coeffs cf)
+{
+  poly *P=(poly*)omAlloc(rl*sizeof(poly*));
+  number *X=(number *)omAlloc(rl*sizeof(number));
+  int i;
+  for(i=0;i<rl;i++) P[i]=p_Copy((poly)(x[i]),cf->extRing);
+  poly result=p_ChineseRemainder(P,X,q,rl,cf->extRing);
+  omFreeSize(X,rl*sizeof(number));
+  omFreeSize(P,rl*sizeof(poly*));
+  return ((number)result);
+}
+
+number  naFarey(number p, number n, const coeffs cf)
+{
+  // n is really a bigint
+  poly result=p_Farey(p_Copy((poly)p,cf->extRing),n,cf->extRing);
+  return ((number)result);
+}
+
+
+BOOLEAN naInitChar(coeffs cf, void * infoStruct)
+{
+  assume( infoStruct != NULL );
+
+  AlgExtInfo *e = (AlgExtInfo *)infoStruct;
+  /// first check whether cf->extRing != NULL and delete old ring???
+
+  assume(e->r                     != NULL);      // extRing;
+  assume(e->r->cf                 != NULL);      // extRing->cf;
+
+  assume((e->r->qideal            != NULL) &&    // minideal has one
+         (IDELEMS(e->r->qideal)   == 1)    &&    // non-zero generator
+         (e->r->qideal->m[0]      != NULL)    ); // at m[0];
+
+  assume( cf != NULL );
+  assume(getCoeffType(cf) == ID);                     // coeff type;
+
+  e->r->ref ++; // increase the ref.counter for the ground poly. ring!
+  const ring R = e->r; // no copy!
+  cf->extRing  = R;
+
+  /* propagate characteristic up so that it becomes
+     directly accessible in cf: */
+  cf->ch = R->cf->ch;
+
+  cf->is_field=TRUE;
+  cf->is_domain=TRUE;
+  cf->rep=n_rep_poly;
+
+  #ifdef LDEBUG
+  p_Test((poly)naMinpoly, naRing);
+  #endif
+
+  cf->cfCoeffString = naCoeffString;
+
+  cf->cfGreaterZero  = naGreaterZero;
+  cf->cfGreater      = naGreater;
+  cf->cfEqual        = naEqual;
+  cf->cfIsZero       = naIsZero;
+  cf->cfIsOne        = naIsOne;
+  cf->cfIsMOne       = naIsMOne;
+  cf->cfInit         = naInit;
+  cf->cfFarey        = naFarey;
+  cf->cfChineseRemainder= naChineseRemainder;
+  cf->cfInt          = naInt;
+  cf->cfInpNeg       = naNeg;
+  cf->cfAdd          = naAdd;
+  cf->cfSub          = naSub;
+  cf->cfMult         = naMult;
+  cf->cfDiv          = naDiv;
+  cf->cfExactDiv     = naDiv;
+  cf->cfPower        = naPower;
+  cf->cfCopy         = naCopy;
+
+  cf->cfWriteLong        = naWriteLong;
+
+  if( rCanShortOut(naRing) )
+    cf->cfWriteShort = naWriteShort;
+  else
+    cf->cfWriteShort = naWriteLong;
+
+  cf->cfRead         = naRead;
+  cf->cfDelete       = naDelete;
+  cf->cfSetMap       = naSetMap;
+  cf->cfGetDenom     = naGetDenom;
+  cf->cfGetNumerator = naGetNumerator;
+  cf->cfRePart       = naCopy;
+  cf->cfCoeffWrite   = naCoeffWrite;
+  cf->cfNormalize    = naNormalize;
+  cf->cfKillChar     = naKillChar;
+#ifdef LDEBUG
+  cf->cfDBTest       = naDBTest;
+#endif
+  cf->cfGcd          = naGcd;
+  cf->cfNormalizeHelper          = naLcmContent;
+  cf->cfSize         = naSize;
+  cf->nCoeffIsEqual  = naCoeffIsEqual;
+  cf->cfInvers       = naInvers;
+  cf->convFactoryNSingN=naConvFactoryNSingN;
+  cf->convSingNFactoryN=naConvSingNFactoryN;
+  cf->cfParDeg = naParDeg;
+
+  cf->iNumberOfParameters = rVar(R);
+  cf->pParameterNames = (const char**)R->names;
+  cf->cfParameter = naParameter;
+  cf->has_simple_Inverse= R->cf->has_simple_Inverse;
+  /* cf->has_simple_Alloc= FALSE; */
+
+  if( nCoeff_is_Q(R->cf) )
+  {
+    cf->cfClearContent = naClearContent;
+    cf->cfClearDenominators = naClearDenominators;
+  }
+
+  return FALSE;
+}
+
+template class CRecursivePolyCoeffsEnumerator<NAConverter>;
+
+template class IAccessor<snumber*>;
+
+/* --------------------------------------------------------------------*/
+#if 0
+void npolyCoeffWrite(const coeffs cf, BOOLEAN details)
+{
+  assume( cf != NULL );
+
+  const ring A = cf->extRing;
+
+  assume( A != NULL );
+  Print("// polynomial ring as coefficient ring :\n");
+  rWrite(A);
+  PrintLn();
+}
+number npolyMult(number a, number b, const coeffs cf)
+{
+  naTest(a); naTest(b);
+  if ((a == NULL)||(b == NULL)) return NULL;
+  poly aTimesB = p_Mult_q(p_Copy((poly)a, naRing),
+                          p_Copy((poly)b, naRing), naRing);
+  return (number)aTimesB;
+}
+
+void npolyPower(number a, int exp, number *b, const coeffs cf)
+{
+  naTest(a);
+
+  /* special cases first */
+  if (a == NULL)
+  {
+    if (exp >= 0) *b = NULL;
+    else          WerrorS(nDivBy0);
+    return;
+  }
+  else if (exp ==  0) { *b = naInit(1, cf); return; }
+  else if (exp ==  1) { *b = naCopy(a, cf); return; }
+  else if (exp == -1) { *b = naInvers(a, cf); return; }
+
+  int expAbs = exp; if (expAbs < 0) expAbs = -expAbs;
+
+  /* now compute a^expAbs */
+  poly pow; poly aAsPoly = (poly)a;
+  if (expAbs <= 7)
+  {
+    pow = p_Copy(aAsPoly, naRing);
+    for (int i = 2; i <= expAbs; i++)
+    {
+      pow = p_Mult_q(pow, p_Copy(aAsPoly, naRing), naRing);
+    }
+  }
+  else
+  {
+    pow = p_ISet(1, naRing);
+    poly factor = p_Copy(aAsPoly, naRing);
+    while (expAbs != 0)
+    {
+      if (expAbs & 1)
+      {
+        pow = p_Mult_q(pow, p_Copy(factor, naRing), naRing);
+      }
+      expAbs = expAbs / 2;
+      if (expAbs != 0)
+      {
+        factor = p_Mult_q(factor, p_Copy(factor, naRing), naRing);
+      }
+    }
+    p_Delete(&factor, naRing);
+  }
+
+  /* invert if original exponent was negative */
+  number n = (number)pow;
+  if (exp < 0)
+  {
+    number m = npolyInvers(n, cf);
+    naDelete(&n, cf);
+    n = m;
+  }
+  *b = n;
+}
+
+number npolyDiv(number a, number b, const coeffs cf)
+{
+  naTest(a); naTest(b);
+  if (b == NULL) WerrorS(nDivBy0);
+  if (a == NULL) return NULL;
+  poly p=singclap_pdivide((poly)a,(poly)b,naRing);
+  return (number)p;
+}
+
+
+BOOLEAN npolyInitChar(coeffs cf, void * infoStruct)
+{
+  assume( infoStruct != NULL );
+
+  AlgExtInfo *e = (AlgExtInfo *)infoStruct;
+  /// first check whether cf->extRing != NULL and delete old ring???
+
+  assume(e->r                     != NULL);      // extRing;
+  assume(e->r->cf                 != NULL);      // extRing->cf;
+
+  assume( cf != NULL );
+
+  e->r->ref ++; // increase the ref.counter for the ground poly. ring!
+  const ring R = e->r; // no copy!
+  cf->extRing  = R;
+
+  /* propagate characteristic up so that it becomes
+     directly accessible in cf: */
+  cf->ch = R->cf->ch;
+  cf->is_field=FALSE;
+  cf->is_domain=TRUE;
+
+  cf->cfCoeffString = naCoeffString;
+
+  cf->cfGreaterZero  = naGreaterZero;
+  cf->cfGreater      = naGreater;
+  cf->cfEqual        = naEqual;
+  cf->cfIsZero       = naIsZero;
+  cf->cfIsOne        = naIsOne;
+  cf->cfIsMOne       = naIsMOne;
+  cf->cfInit         = naInit;
+  cf->cfFarey        = naFarey;
+  cf->cfChineseRemainder= naChineseRemainder;
+  cf->cfInt          = naInt;
+  cf->cfInpNeg       = naNeg;
+  cf->cfAdd          = naAdd;
+  cf->cfSub          = naSub;
+  cf->cfMult         = npolyMult;
+  cf->cfDiv          = npolyDiv;
+  cf->cfPower        = naPower;
+  cf->cfCopy         = naCopy;
+
+  cf->cfWriteLong        = naWriteLong;
+
+  if( rCanShortOut(naRing) )
+    cf->cfWriteShort = naWriteShort;
+  else
+    cf->cfWriteShort = naWriteLong;
+
+  cf->cfRead         = naRead;
+  cf->cfDelete       = naDelete;
+  cf->cfSetMap       = naSetMap;
+  cf->cfGetDenom     = naGetDenom;
+  cf->cfGetNumerator = naGetNumerator;
+  cf->cfRePart       = naCopy;
+  cf->cfCoeffWrite   = npolyCoeffWrite;
+  cf->cfNormalize    = npolyNormalize;
+  cf->cfKillChar     = naKillChar;
+#ifdef LDEBUG
+  cf->cfDBTest       = naDBTest;
+#endif
+  cf->cfGcd          = naGcd;
+  cf->cfNormalizeHelper          = naLcmContent;
+  cf->cfSize         = naSize;
+  cf->nCoeffIsEqual  = naCoeffIsEqual;
+  cf->cfInvers       = npolyInvers;
+  cf->convFactoryNSingN=naConvFactoryNSingN;
+  cf->convSingNFactoryN=naConvSingNFactoryN;
+  cf->cfParDeg = naParDeg;
+
+  cf->iNumberOfParameters = rVar(R);
+  cf->pParameterNames = (const char**)R->names;
+  cf->cfParameter = naParameter;
+  cf->has_simple_Inverse=FALSE;
+  /* cf->has_simple_Alloc= FALSE; */
+
+  if( nCoeff_is_Q(R->cf) )
+  {
+    cf->cfClearContent = naClearContent;
+    cf->cfClearDenominators = naClearDenominators;
+  }
+
+  return FALSE;
+}
+#endif
diff --git a/libpolys/polys/ext_fields/algext.h b/libpolys/polys/ext_fields/algext.h
new file mode 100644
index 0000000..851479a
--- /dev/null
+++ b/libpolys/polys/ext_fields/algext.h
@@ -0,0 +1,67 @@
+#ifndef ALGEXT_H
+#define ALGEXT_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: numbers in an algebraic extension field K[a] / < f(a) >
+*           Assuming that we have a coeffs object cf, then these numbers
+*           are polynomials in the polynomial ring K[a] represented by
+*           cf->extRing.
+*           IMPORTANT ASSUMPTIONS:
+*           1.) So far we assume that cf->extRing is a valid polynomial
+*               ring in exactly one variable, i.e., K[a], where K is allowed
+*               to be any field (representable in SINGULAR and which may
+*               itself be some extension field, thus allowing for extension
+*               towers).
+*           2.) Moreover, this implementation assumes that
+*               cf->extRing->qideal is not NULL but an ideal with at
+*               least one non-zero generator which may be accessed by
+*               cf->extRing->qideal->m[0] and which represents the minimal
+*               polynomial f(a) of the extension variable 'a' in K[a].
+*           3.) As soon as an std method for polynomial rings becomes
+*               availabe, all reduction steps modulo f(a) should be replaced
+*               by a call to std. Moreover, in this situation one can finally
+*               move from K[a] / < f(a) > to
+*                  K[a_1, ..., a_s] / I, with I some zero-dimensional ideal
+*                                        in K[a_1, ..., a_s] given by a lex
+*                                        Gröbner basis.
+*               The code in algext.h and algext.cc is then capable of
+*               computing in K[a_1, ..., a_s] / I.
+*/
+
+#include <coeffs/coeffs.h>
+
+// Forward declarations
+struct ip_sring; typedef struct ip_sring * ring;
+struct sip_sideal; typedef struct sip_sideal * ideal;
+
+/// struct for passing initialization parameters to naInitChar
+typedef struct { ring r; /*ideal i;*/ } AlgExtInfo; // `r.qideal` is supposed to be `i`
+
+/// Get a mapping function from src into the domain of this type (n_algExt)
+nMapFunc naSetMap(const coeffs src, const coeffs dst);
+
+/// Initialize the coeffs object
+BOOLEAN  naInitChar(coeffs cf, void* infoStruct);
+
+/// if m == var(i)/1 => return i,
+int naIsParam(number, const coeffs);
+
+struct  spolyrec;
+typedef struct spolyrec    polyrec;
+typedef polyrec *          poly;
+
+/// assumes that p and q are univariate polynomials in r,
+///   mentioning the same variable;
+///   assumes a global monomial ordering in r;
+///   assumes that not both p and q are NULL;
+///   returns the gcd of p and q;
+///   moreover, afterwards pFactor and qFactor contain appropriate
+///   factors such that gcd(p, q) = p * pFactor + q * qFactor;
+///   leaves p and q unmodified
+poly      p_ExtGcd(poly p, poly &pFactor, poly q, poly &qFactor, ring r);
+
+char* naCoeffString(const coeffs r); // will be reused in tranext.cc...
+#endif
+/* ALGEXT_H */
diff --git a/libpolys/polys/ext_fields/transext.cc b/libpolys/polys/ext_fields/transext.cc
new file mode 100644
index 0000000..97bab61
--- /dev/null
+++ b/libpolys/polys/ext_fields/transext.cc
@@ -0,0 +1,2466 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: numbers in a rational function field K(t_1, .., t_s) with
+*           transcendental variables t_1, ..., t_s, where s >= 1.
+*           Denoting the implemented coeffs object by cf, then these numbers
+*           are represented as quotients of polynomials living in the
+*           polynomial ring K[t_1, .., t_s] represented by cf->extring.
+*
+*           An element of K(t_1, .., t_s) may have numerous representations,
+*           due to the possibility of common polynomial factors in the
+*           numerator and denominator. This problem is handled by a
+*           cancellation heuristic: Each number "knows" its complexity
+*           which is 0 if and only if common factors have definitely been
+*           cancelled, and some positive integer otherwise.
+*           Each arithmetic operation of two numbers with complexities c1
+*           and c2 will result in a number of complexity c1 + c2 + some
+*           penalty (specific for each arithmetic operation; see constants
+*           in the *.h file). Whenever the resulting complexity exceeds a
+*           certain threshold (see constant in the *.h file), then the
+*           cancellation heuristic will call 'factory' to compute the gcd
+*           and cancel it out in the given number. (This definite cancel-
+*           lation will also be performed at the beginning of ntWrite,
+*           ensuring that any output is free of common factors.
+*           For the special case of K = Q (i.e., when computing over the
+*           rationals), this definite cancellation procedure will also take
+*           care of nested fractions: If there are fractional coefficients
+*           in the numerator or denominator of a number, then this number
+*           is being replaced by a quotient of two polynomials over Z, or
+*           - if the denominator is a constant - by a polynomial over Q.
+*
+*           TODO: the description above needs a major update!!!
+*/
+#define TRANSEXT_PRIVATES
+
+#include <misc/auxiliary.h>
+
+#include <omalloc/omalloc.h>
+#include <factory/factory.h>
+
+#include <reporter/reporter.h>
+
+#include <coeffs/coeffs.h>
+#include <coeffs/numbers.h>
+
+#include <coeffs/longrat.h>
+
+#include <polys/monomials/ring.h>
+#include <polys/monomials/p_polys.h>
+#include <polys/simpleideals.h>
+
+#include <polys/clapsing.h>
+#include <polys/clapconv.h>
+
+#include <polys/prCopy.h>
+#include "transext.h"
+#include "algext.h"
+
+#include <polys/PolyEnumerator.h>
+
+
+/* constants for controlling the complexity of numbers */
+#define ADD_COMPLEXITY 1   /**< complexity increase due to + and - */
+#define MULT_COMPLEXITY 2   /**< complexity increase due to * and / */
+#define DIFF_COMPLEXITY 2   /**< complexity increase due to * and / */
+#define BOUND_COMPLEXITY 10   /**< maximum complexity of a number */
+
+/// TRUE iff num. represents 1
+#define NUMIS1(f) (p_IsOne(NUM(f), cf->extRing))
+
+#define COM(f) f->complexity
+
+
+#ifdef LDEBUG
+#define ntTest(a) ntDBTest(a,__FILE__,__LINE__,cf)
+BOOLEAN  ntDBTest(number a, const char *f, const int l, const coeffs r);
+#else
+#define ntTest(a) do {} while (0)
+#endif
+
+/// Our own type!
+static const n_coeffType ID = n_transExt;
+
+/* polynomial ring in which the numerators and denominators of our
+   numbers live */
+#define ntRing cf->extRing
+
+/* coeffs object in which the coefficients of our numbers live;
+ * methods attached to ntCoeffs may be used to compute with the
+ * coefficients of our numbers, e.g., use ntCoeffs->nAdd to add
+ * coefficients of our numbers */
+#define ntCoeffs cf->extRing->cf
+
+
+omBin fractionObjectBin = omGetSpecBin(sizeof(fractionObject));
+
+/// forward declarations
+BOOLEAN  ntGreaterZero(number a, const coeffs cf);
+BOOLEAN  ntGreater(number a, number b, const coeffs cf);
+BOOLEAN  ntEqual(number a, number b, const coeffs cf);
+BOOLEAN  ntIsOne(number a, const coeffs cf);
+BOOLEAN  ntIsMOne(number a, const coeffs cf);
+BOOLEAN  ntIsZero(number a, const coeffs cf);
+number   ntInit(long i, const coeffs cf);
+int      ntInt(number &a, const coeffs cf);
+number   ntNeg(number a, const coeffs cf);
+number   ntInvers(number a, const coeffs cf);
+number   ntAdd(number a, number b, const coeffs cf);
+number   ntSub(number a, number b, const coeffs cf);
+number   ntMult(number a, number b, const coeffs cf);
+number   ntDiv(number a, number b, const coeffs cf);
+void     ntPower(number a, int exp, number *b, const coeffs cf);
+number   ntCopy(number a, const coeffs cf);
+void     ntWriteLong(number &a, const coeffs cf);
+void     ntWriteShort(number &a, const coeffs cf);
+number   ntRePart(number a, const coeffs cf);
+number   ntImPart(number a, const coeffs cf);
+number   ntGetDenom(number &a, const coeffs cf);
+number   ntGetNumerator(number &a, const coeffs cf);
+number   ntGcd(number a, number b, const coeffs cf);
+number   ntNormalizeHelper(number a, number b, const coeffs cf);
+int      ntSize(number a, const coeffs cf);
+void     ntDelete(number * a, const coeffs cf);
+void     ntCoeffWrite(const coeffs cf, BOOLEAN details);
+const char * ntRead(const char *s, number *a, const coeffs cf);
+static BOOLEAN ntCoeffIsEqual(const coeffs cf, n_coeffType n, void * param);
+
+void heuristicGcdCancellation(number a, const coeffs cf);
+void definiteGcdCancellation(number a, const coeffs cf,
+                             BOOLEAN simpleTestsHaveAlreadyBeenPerformed);
+void handleNestedFractionsOverQ(fraction f, const coeffs cf);
+
+/* test routine, usualy disabled *
+ * if want to activate it, activate also the calls to check_N *
+ *
+void check_normalized(number t,const coeffs cf, const char *f, int l)
+{
+  if (IS0(t)) return;
+  if(rField_is_Q(ntRing))
+  {
+    poly pp=NUM(t);
+    while(pp!=NULL)
+    {
+      if (((SR_HDL(pGetCoeff(pp)) & SR_INT)==0)&&(SR_HDL(pGetCoeff(pp))!=NULL))
+      {
+        if (pGetCoeff(pp)->s==0)
+        {
+          Print("NUM not normalized in %s:%d\n",f,l);
+          p_Normalize(pp,ntRing);
+        }
+        else if (pGetCoeff(pp)->s==1)
+          Print("NUM is rational in %s:%d\n",f,l);
+      }
+      pIter(pp);
+    }
+    pp=DEN(t);
+    while(pp!=NULL)
+    {
+      if (((SR_HDL(pGetCoeff(pp)) & SR_INT)==0)&&(SR_HDL(pGetCoeff(pp))!=NULL))
+      {
+        if (pGetCoeff(pp)->s==0)
+        {
+          Print("NUM not normalized in %s:%d\n",f,l);
+          p_Normalize(pp,ntRing);
+        }
+        else if (pGetCoeff(pp)->s==1)
+          Print("DEN is rational in %s:%d\n",f,l);
+      }
+      pIter(pp);
+    }
+  }
+}
+#define check_N(A,B) check_normalized(A,B,__FILE__,__LINE__)
+*/
+
+#ifdef LDEBUG
+BOOLEAN ntDBTest(number a, const char *f, const int l, const coeffs cf)
+{
+  assume(getCoeffType(cf) == ID);
+
+  if (IS0(a)) return TRUE;
+
+  const fraction t = (fraction)a;
+
+  //check_N(a,cf);
+  const poly num = NUM(t);
+  assume(num != NULL);   /**< t != 0 ==> numerator(t) != 0 */
+
+  p_Test(num, ntRing);
+
+  const poly den = DEN(t);
+
+  if (den != NULL) // !DENIS1(f)
+  {
+    p_Test(den, ntRing);
+
+    if(p_IsConstant(den, ntRing) && (n_IsOne(pGetCoeff(den), ntCoeffs)))
+    {
+      Print("?/1 in %s:%d\n",f,l);
+      return FALSE;
+    }
+
+    if( !n_GreaterZero(pGetCoeff(den), ntCoeffs) )
+    {
+      Print("negative sign of DEN. of a fraction in %s:%d\n",f,l);
+      return FALSE;
+    }
+
+    // test that den is over integers!?
+
+  } else
+  {  // num != NULL // den == NULL
+
+//    if( COM(t) != 0 )
+//    {
+//      Print("?//NULL with non-zero complexity: %d in %s:%d\n", COM(t), f, l);
+//      return FALSE;
+//    }
+    // test that nume is over integers!?
+  }
+  if (getCoeffType(ntCoeffs)==n_Q)
+  {
+    poly p=num; // !=NULL
+    do
+    {
+      number n=pGetCoeff(p);
+      n_Test(n,ntCoeffs);
+      if ((!(SR_HDL(n) & SR_INT))&&(n->s==0))
+      /* not normalized, just do for the following test*/
+      {
+        n_Normalize(pGetCoeff(p),ntCoeffs);
+        n=pGetCoeff(p);
+      }
+      if (!(SR_HDL(n) & SR_INT))
+      {
+        if (n->s<2)
+          Print("rational coeff in num: %s:%d\n",f,l);
+      }
+      pIter(p);
+    } while(p!=NULL);
+    p=den;
+    while(p!=NULL)
+    {
+      number n=pGetCoeff(p);
+      if (!(SR_HDL(n) & SR_INT))
+      {
+        if (n->s!=3)
+          Print("rational coeff in den.:%s:%d\n",f,l);
+      }
+      pIter(p);
+    }
+  }
+  return TRUE;
+}
+#endif
+
+/* returns the bottom field in this field extension tower; if the tower
+   is flat, i.e., if there is no extension, then r itself is returned;
+   as a side-effect, the counter 'height' is filled with the height of
+   the extension tower (in case the tower is flat, 'height' is zero) */
+static coeffs nCoeff_bottom(const coeffs r, int &height)
+{
+  assume(r != NULL);
+  coeffs cf = r;
+  height = 0;
+  while (nCoeff_is_Extension(cf))
+  {
+    assume(cf->extRing != NULL); assume(cf->extRing->cf != NULL);
+    cf = cf->extRing->cf;
+    height++;
+  }
+  return cf;
+}
+
+BOOLEAN ntIsZero(number a, const coeffs cf)
+{
+  //check_N(a,cf);
+  ntTest(a); // !!!
+  return (IS0(a));
+}
+
+void ntDelete(number * a, const coeffs cf)
+{
+  //check_N(*a,cf);
+  ntTest(*a); // !!!
+  fraction f = (fraction)(*a);
+  if (IS0(f)) return;
+  p_Delete(&NUM(f), ntRing);
+  if (!DENIS1(f)) p_Delete(&DEN(f), ntRing);
+  omFreeBin((ADDRESS)f, fractionObjectBin);
+  *a = NULL;
+}
+
+BOOLEAN ntEqual(number a, number b, const coeffs cf)
+{
+  //check_N(a,cf);
+  //check_N(b,cf);
+  ntTest(a);
+  ntTest(b);
+
+  /// simple tests
+  if (a == b) return TRUE;
+  if ((IS0(a)) && (!IS0(b))) return FALSE;
+  if ((IS0(b)) && (!IS0(a))) return FALSE;
+
+  /// cheap test if gcd's have been cancelled in both numbers
+  fraction fa = (fraction)a;
+  fraction fb = (fraction)b;
+  if ((COM(fa) == 1) && (COM(fb) == 1))
+  {
+    poly f = p_Add_q(p_Copy(NUM(fa), ntRing),
+                     p_Neg(p_Copy(NUM(fb), ntRing), ntRing),
+                     ntRing);
+    if (f != NULL) { p_Delete(&f, ntRing); return FALSE; }
+    if (DENIS1(fa) && DENIS1(fb))  return TRUE;
+    if (DENIS1(fa) && !DENIS1(fb)) return FALSE;
+    if (!DENIS1(fa) && DENIS1(fb)) return FALSE;
+    f = p_Add_q(p_Copy(DEN(fa), ntRing),
+                p_Neg(p_Copy(DEN(fb), ntRing), ntRing),
+                ntRing);
+    if (f != NULL) { p_Delete(&f, ntRing); return FALSE; }
+    return TRUE;
+  }
+
+  /* default: the more expensive multiplication test
+              a/b = c/d  <==>  a*d = b*c */
+  poly f = p_Copy(NUM(fa), ntRing);
+  if (!DENIS1(fb)) f = p_Mult_q(f, p_Copy(DEN(fb), ntRing), ntRing);
+  poly g = p_Copy(NUM(fb), ntRing);
+  if (!DENIS1(fa)) g = p_Mult_q(g, p_Copy(DEN(fa), ntRing), ntRing);
+  poly h = p_Add_q(f, p_Neg(g, ntRing), ntRing);
+  if (h == NULL) return TRUE;
+  else
+  {
+    p_Delete(&h, ntRing);
+    return FALSE;
+  }
+}
+
+number ntCopy(number a, const coeffs cf)
+{
+  //check_N(a,cf);
+  ntTest(a); // !!!
+  if (IS0(a)) return NULL;
+  fraction f = (fraction)a;
+  poly g = p_Copy(NUM(f), ntRing);
+  poly h = NULL; if (!DENIS1(f)) h = p_Copy(DEN(f), ntRing);
+  fraction result = (fraction)omAllocBin(fractionObjectBin);
+  NUM(result) = g;
+  DEN(result) = h;
+  COM(result) = COM(f);
+  ntTest((number)result);
+  return (number)result;
+}
+
+/// TODO: normalization of a!?
+number ntGetNumerator(number &a, const coeffs cf)
+{
+  //check_N(a,cf);
+  ntTest(a);
+  if (IS0(a)) return NULL;
+
+  definiteGcdCancellation(a, cf, FALSE);
+
+  fraction f = (fraction)a;
+  fraction result = (fraction)omAlloc0Bin(fractionObjectBin);
+
+  const BOOLEAN denis1= DENIS1 (f);
+
+  if (getCoeffType (ntCoeffs) == n_Q && !denis1)
+    handleNestedFractionsOverQ (f, cf);
+
+  if (getCoeffType (ntCoeffs) == n_Q && denis1)
+  {
+    assume( DEN (f) == NULL );
+
+    number g;
+    // TODO/NOTE: the following should not be necessary (due to
+    // Hannes!) as NUM (f) should be over Z!!!
+    CPolyCoeffsEnumerator itr(NUM(f));
+
+
+    n_ClearDenominators(itr, g, ntCoeffs);
+
+    if( !n_GreaterZero(g, ntCoeffs) )
+    {
+      NUM (f) = p_Neg(NUM (f), ntRing); // Ugly :(((
+      g = n_InpNeg(g, ntCoeffs);
+    }
+
+    // g should be a positive integer now!
+    assume( n_GreaterZero(g, ntCoeffs) );
+
+    if( !n_IsOne(g, ntCoeffs) )
+    {
+      DEN (f) = p_NSet(g, ntRing); // update COM(f)???
+      COM (f) ++;
+      assume( DEN (f) != NULL );
+    }
+    else
+      n_Delete(&g, ntCoeffs);
+
+    ntTest(a);
+  }
+
+  // Call ntNormalize instead of above?!?
+
+  NUM (result) = p_Copy (NUM (f), ntRing); // ???
+  //DEN (result) = NULL; // done by ..Alloc0..
+  //COM (result) = 0; // done by ..Alloc0..
+
+  ntTest((number)result);
+  //check_N((number)result,cf);
+  return (number)result;
+}
+
+/// TODO: normalization of a!?
+number ntGetDenom(number &a, const coeffs cf)
+{
+  //check_N(a,cf);
+  ntTest(a);
+
+  fraction result = (fraction)omAlloc0Bin(fractionObjectBin);
+  //DEN (result)= NULL; // done by ..Alloc0..
+  //COM (result)= 0; // done by ..Alloc0..
+
+  if (IS0(a))
+  {
+    NUM (result) = p_One(ntRing);
+    return (number)result;
+  }
+
+  definiteGcdCancellation(a, cf, FALSE);
+
+  fraction f = (fraction)a;
+
+  assume( !IS0(f) );
+
+  const BOOLEAN denis1 = DENIS1 (f);
+
+  if( denis1 && (getCoeffType (ntCoeffs) != n_Q) ) // */1 or 0
+  {
+    NUM (result)= p_One(ntRing);
+    ntTest((number)result);
+    return (number)result;
+  }
+
+  if (!denis1) // */* / Q
+  {
+    assume( DEN (f) != NULL );
+
+    if (getCoeffType (ntCoeffs) == n_Q)
+      handleNestedFractionsOverQ (f, cf);
+
+    ntTest(a);
+
+    if( DEN (f) != NULL ) // is it ?? // 1 now???
+    {
+      assume( !p_IsOne(DEN (f), ntRing) );
+
+      NUM (result) = p_Copy (DEN (f), ntRing);
+      ntTest((number)result);
+      return (number)result;
+    }
+//    NUM (result) = p_One(ntRing); // NOTE: just in order to be sure...
+  }
+
+  // */1 / Q
+  assume( getCoeffType (ntCoeffs) == n_Q );
+  assume( DEN (f) == NULL );
+
+  number g;
+//    poly num= p_Copy (NUM (f), ntRing); // ???
+
+
+  // TODO/NOTE: the following should not be necessary (due to
+  // Hannes!) as NUM (f) should be over Z!!!
+  CPolyCoeffsEnumerator itr(NUM(f));
+
+  n_ClearDenominators(itr, g, ntCoeffs); // may return -1 :(((
+
+  if( !n_GreaterZero(g, ntCoeffs) )
+  {
+//     NUM (f) = p_Neg(NUM (f), ntRing); // Ugly :(((
+//     g = n_InpNeg(g, ntCoeffs);
+    NUM (f) = p_Neg(NUM (f), ntRing); // Ugly :(((
+    g = n_InpNeg(g, ntCoeffs);
+  }
+
+  // g should be a positive integer now!
+  assume( n_GreaterZero(g, ntCoeffs) );
+
+  if( !n_IsOne(g, ntCoeffs) )
+  {
+    assume( n_GreaterZero(g, ntCoeffs) );
+    assume( !n_IsOne(g, ntCoeffs) );
+
+    DEN (f) = p_NSet(g, ntRing); // update COM(f)???
+    assume( DEN (f) != NULL );
+    COM (f) ++;
+
+    NUM (result)= p_Copy (DEN (f), ntRing);
+  }
+  else
+  { // common denom == 1?
+    NUM (result)= p_NSet(g, ntRing); // p_Copy (DEN (f), ntRing);
+//  n_Delete(&g, ntCoeffs);
+  }
+
+//    if (!p_IsConstant (num, ntRing) && pNext(num) != NULL)
+//    else
+//      g= p_GetAllDenom (num, ntRing);
+//    result= (fraction) ntSetMap (ntCoeffs, cf) (g, ntCoeffs, cf);
+
+  ntTest((number)result);
+  //check_N((number)result,cf);
+  return (number)result;
+}
+
+BOOLEAN ntIsOne(number a, const coeffs cf)
+{
+  //check_N(a,cf);
+  ntTest(a); // !!!
+  definiteGcdCancellation(a, cf, FALSE);
+  fraction f = (fraction)a;
+  return (f!=NULL) && DENIS1(f) && NUMIS1(f);
+}
+
+BOOLEAN ntIsMOne(number a, const coeffs cf)
+{
+  //check_N(a,cf);
+  ntTest(a);
+  definiteGcdCancellation(a, cf, FALSE);
+  fraction f = (fraction)a;
+  if ((f==NULL) || (!DENIS1(f))) return FALSE;
+  poly g = NUM(f);
+  if (!p_IsConstant(g, ntRing)) return FALSE;
+  return n_IsMOne(p_GetCoeff(g, ntRing), ntCoeffs);
+}
+
+/// this is in-place, modifies a
+number ntNeg(number a, const coeffs cf)
+{
+  //check_N(a,cf);
+  ntTest(a);
+  if (!IS0(a))
+  {
+    fraction f = (fraction)a;
+    NUM(f) = p_Neg(NUM(f), ntRing);
+  }
+  ntTest(a);
+  return a;
+}
+
+number ntImPart(number a, const coeffs cf)
+{
+  ntTest(a);
+  return NULL;
+}
+
+number ntInit(long i, const coeffs cf)
+{
+  if (i != 0)
+  {
+    poly p=p_ISet(i, ntRing);
+    if (p!=NULL)
+    {
+      fraction result = (fraction)omAlloc0Bin(fractionObjectBin);
+      NUM(result) = p;
+      //DEN(result) = NULL; // done by omAlloc0Bin
+      //COM(result) = 0; // done by omAlloc0Bin
+      ntTest((number)result);
+      //check_N((number)result,cf);
+      return (number)result;
+    }
+  }
+  return NULL;
+}
+
+
+/// takes over p!
+number ntInit(poly p, const coeffs cf)
+{
+  if (p == NULL) return NULL;
+
+  fraction f = (fraction)omAlloc0Bin(fractionObjectBin);
+
+  if (nCoeff_is_Q(ntCoeffs))
+  {
+    number g;
+    // the following is necessary because
+    // NUM (f) should be over Z,
+    // while p may be over Q
+    CPolyCoeffsEnumerator itr(p);
+
+    n_ClearDenominators(itr, g, ntCoeffs);
+
+    if( !n_GreaterZero(g, ntCoeffs) )
+    {
+      p = p_Neg(p, ntRing);
+      g = n_InpNeg(g, ntCoeffs);
+    }
+
+    // g should be a positive integer now!
+    assume( n_GreaterZero(g, ntCoeffs) );
+
+    if( !n_IsOne(g, ntCoeffs) )
+    {
+      DEN (f) = p_NSet(g, ntRing);
+      p_Normalize(DEN(f), ntRing);
+      assume( DEN (f) != NULL );
+    }
+    else
+    {
+      //DEN(f) = NULL; // done by omAlloc0
+      n_Delete(&g, ntCoeffs);
+    }
+  }
+
+  p_Normalize(p, ntRing);
+  NUM(f) = p;
+  //COM(f) = 0; // done by omAlloc0
+
+  //check_N((number)f,cf);
+  ntTest((number)f);
+  return (number)f;
+}
+
+int ntInt(number &a, const coeffs cf)
+{
+  //check_N(a,cf);
+  ntTest(a);
+  if (IS0(a)) return 0;
+  definiteGcdCancellation(a, cf, FALSE);
+  fraction f = (fraction)a;
+  if (!DENIS1(f)) return 0;
+
+  const poly aAsPoly = NUM(f);
+
+  if(aAsPoly == NULL)
+    return 0;
+
+  if (!p_IsConstant(aAsPoly, ntRing))
+    return 0;
+
+  assume( aAsPoly != NULL );
+
+  return n_Int(p_GetCoeff(aAsPoly, ntRing), ntCoeffs);
+}
+
+/* This method will only consider the numerators of a and b, without
+   cancelling gcd's before.
+   Moreover it may return TRUE only if one or both numerators
+   are zero or if their degrees are equal. Then TRUE is returned iff
+   coeff(numerator(a)) > coeff(numerator(b));
+   In all other cases, FALSE will be returned. */
+BOOLEAN ntGreater(number a, number b, const coeffs cf)
+{
+  //check_N(a,cf);
+  //check_N(b,cf);
+  ntTest(a);
+  ntTest(b);
+  number aNumCoeff = NULL; int aNumDeg = 0;
+  number aDenCoeff = NULL; int aDenDeg = 0;
+  number bNumCoeff = NULL; int bNumDeg = 0;
+  number bDenCoeff = NULL; int bDenDeg = 0;
+  if (!IS0(a))
+  {
+    fraction fa = (fraction)a;
+    aNumDeg = p_Totaldegree(NUM(fa), ntRing);
+    aNumCoeff = p_GetCoeff(NUM(fa), ntRing);
+    if (DEN(fa)!=NULL)
+    {
+      aDenDeg = p_Totaldegree(DEN(fa), ntRing);
+      aDenCoeff=p_GetCoeff(DEN(fa),ntRing);
+    }
+  }
+  else return !(ntGreaterZero (b,cf));
+  if (!IS0(b))
+  {
+    fraction fb = (fraction)b;
+    bNumDeg = p_Totaldegree(NUM(fb), ntRing);
+    bNumCoeff = p_GetCoeff(NUM(fb), ntRing);
+    if (DEN(fb)!=NULL)
+    {
+      bDenDeg = p_Totaldegree(DEN(fb), ntRing);
+      bDenCoeff=p_GetCoeff(DEN(fb),ntRing);
+    }
+  }
+  else return ntGreaterZero(a,cf);
+  if (aNumDeg-aDenDeg > bNumDeg-bDenDeg) return TRUE;
+  if (aNumDeg-aDenDeg < bNumDeg-bDenDeg) return FALSE;
+  number aa;
+  number bb;
+  if (bDenCoeff==NULL) aa=n_Copy(aNumCoeff,ntCoeffs);
+  else                 aa=n_Mult(aNumCoeff,bDenCoeff,ntCoeffs);
+  if (aDenCoeff==NULL) bb=n_Copy(bNumCoeff,ntCoeffs);
+  else                 bb=n_Mult(bNumCoeff,aDenCoeff,ntCoeffs);
+  BOOLEAN rr= n_Greater(aa, bb, ntCoeffs);
+  n_Delete(&aa,ntCoeffs);
+  n_Delete(&bb,ntCoeffs);
+  return rr;
+}
+
+/* this method will only consider the numerator of a, without cancelling
+   the gcd before;
+   returns TRUE iff the leading coefficient of the numerator of a is > 0
+                    or the leading term of the numerator of a is not a
+                    constant */
+BOOLEAN ntGreaterZero(number a, const coeffs cf)
+{
+  //check_N(a,cf);
+  ntTest(a);
+  if (IS0(a)) return FALSE;
+  fraction f = (fraction)a;
+  poly g = NUM(f);
+  return (!p_LmIsConstant(g,ntRing)|| n_GreaterZero(pGetCoeff(g), ntCoeffs));
+}
+
+void ntCoeffWrite(const coeffs cf, BOOLEAN details)
+{
+  assume( cf != NULL );
+
+  const ring A = cf->extRing;
+
+  assume( A != NULL );
+  assume( A->cf != NULL );
+
+  n_CoeffWrite(A->cf, details);
+
+//  rWrite(A);
+
+  const int P = rVar(A);
+  assume( P > 0 );
+
+  Print("//   %d parameter    : ", P);
+
+  for (int nop=0; nop < P; nop ++)
+    Print("%s ", rRingVar(nop, A));
+
+  assume( A->qideal == NULL );
+
+  PrintS("\n//   minpoly        : 0\n");
+
+/*
+  PrintS("//   Coefficients live in the rational function field\n");
+  Print("//   K(");
+  for (int i = 0; i < rVar(ntRing); i++)
+  {
+    if (i > 0) PrintS(" ");
+    Print("%s", rRingVar(i, ntRing));
+  }
+  PrintS(") with\n");
+  PrintS("//   K: "); n_CoeffWrite(cf->extRing->cf);
+*/
+}
+
+number ntDiff(number a, number d, const coeffs cf)
+{
+  //check_N(a,cf);
+  //check_N(d,cf);
+  ntTest(a);
+  ntTest(d);
+
+  if (IS0(d))
+  {
+    WerrorS("ringvar expected");
+    return NULL;
+  }
+  fraction t = (fraction) d;
+  if (!DENIS1(t))
+  {
+    WerrorS("expected differentiation by a variable");
+    return NULL;
+  }
+  int k=p_Var(NUM(t),ntRing);
+  if (k==0)
+  {
+    WerrorS("expected differentiation by a variable");
+    return NULL;
+  }
+
+  if (IS0(a)) return ntCopy(a, cf);
+
+  fraction fa = (fraction)a;
+  fraction result = (fraction)omAlloc0Bin(fractionObjectBin);
+  if (DENIS1(fa))
+  {
+     NUM(result) = p_Diff(NUM(fa),k,ntRing);
+     //DEN(result) = NULL; // done by ..Alloc0..
+     if (NUM(result)==NULL)
+     {
+       omFreeBin((ADDRESS)result, fractionObjectBin);
+       return(NULL);
+     }
+     COM(result) = COM(fa);
+     //check_N((number)result,cf);
+     return (number)result;
+  }
+
+  poly fg = p_Mult_q(p_Copy(DEN(fa),ntRing),p_Diff(NUM(fa),k,ntRing),ntRing);
+  poly gf = p_Mult_q(p_Copy(NUM(fa),ntRing),p_Diff(DEN(fa),k,ntRing),ntRing);
+  NUM(result) = p_Sub(fg,gf,ntRing);
+  if (NUM(result)==NULL) return(NULL);
+  DEN(result) = pp_Mult_qq(DEN(fa), DEN(fa), ntRing);
+  COM(result) = COM(fa) + COM(fa) + DIFF_COMPLEXITY;
+  heuristicGcdCancellation((number)result, cf);
+
+  //check_N((number)result,cf);
+  return (number)result;
+}
+
+
+number ntAdd(number a, number b, const coeffs cf)
+{
+  //check_N(a,cf);
+  //check_N(b,cf);
+  ntTest(a);
+  ntTest(b);
+  if (IS0(a)) return ntCopy(b, cf);
+  if (IS0(b)) return ntCopy(a, cf);
+
+  fraction fa = (fraction)a;
+  fraction fb = (fraction)b;
+
+  poly g = p_Copy(NUM(fa), ntRing);
+  if (!DENIS1(fb)) g = p_Mult_q(g, p_Copy(DEN(fb), ntRing), ntRing);
+  poly h = p_Copy(NUM(fb), ntRing);
+  if (!DENIS1(fa)) h = p_Mult_q(h, p_Copy(DEN(fa), ntRing), ntRing);
+  g = p_Add_q(g, h, ntRing);
+
+  if (g == NULL) return NULL;
+
+  poly f;
+  if      (DENIS1(fa) && DENIS1(fb))  f = NULL;
+  else if (!DENIS1(fa) && DENIS1(fb)) f = p_Copy(DEN(fa), ntRing);
+  else if (DENIS1(fa) && !DENIS1(fb)) f = p_Copy(DEN(fb), ntRing);
+  else /* both denom's are != 1 */    f = p_Mult_q(p_Copy(DEN(fa), ntRing),
+                                                   p_Copy(DEN(fb), ntRing),
+                                                   ntRing);
+
+  fraction result = (fraction)omAllocBin(fractionObjectBin);
+  NUM(result) = g;
+  DEN(result) = f;
+  COM(result) = COM(fa) + COM(fb) + ADD_COMPLEXITY;
+  heuristicGcdCancellation((number)result, cf);
+
+//  ntTest((number)result);
+
+  //check_N((number)result,cf);
+  return (number)result;
+}
+
+number ntSub(number a, number b, const coeffs cf)
+{
+  //check_N(a,cf);
+  //check_N(b,cf);
+  ntTest(a);
+  ntTest(b);
+  if (IS0(a)) return ntNeg(ntCopy(b, cf), cf);
+  if (IS0(b)) return ntCopy(a, cf);
+
+  fraction fa = (fraction)a;
+  fraction fb = (fraction)b;
+
+  poly g = p_Copy(NUM(fa), ntRing);
+  if (!DENIS1(fb)) g = p_Mult_q(g, p_Copy(DEN(fb), ntRing), ntRing);
+  poly h = p_Copy(NUM(fb), ntRing);
+  if (!DENIS1(fa)) h = p_Mult_q(h, p_Copy(DEN(fa), ntRing), ntRing);
+  g = p_Add_q(g, p_Neg(h, ntRing), ntRing);
+
+  if (g == NULL) return NULL;
+
+  poly f;
+  if      (DENIS1(fa) && DENIS1(fb))  f = NULL;
+  else if (!DENIS1(fa) && DENIS1(fb)) f = p_Copy(DEN(fa), ntRing);
+  else if (DENIS1(fa) && !DENIS1(fb)) f = p_Copy(DEN(fb), ntRing);
+  else /* both den's are != 1 */      f = p_Mult_q(p_Copy(DEN(fa), ntRing),
+                                                   p_Copy(DEN(fb), ntRing),
+                                                   ntRing);
+
+  fraction result = (fraction)omAllocBin(fractionObjectBin);
+  NUM(result) = g;
+  DEN(result) = f;
+  COM(result) = COM(fa) + COM(fb) + ADD_COMPLEXITY;
+  heuristicGcdCancellation((number)result, cf);
+//  ntTest((number)result);
+  //check_N((number)result,cf);
+  return (number)result;
+}
+
+number ntMult(number a, number b, const coeffs cf)
+{
+  //check_N(a,cf);
+  //check_N(b,cf);
+  ntTest(a); // !!!?
+  ntTest(b); // !!!?
+
+  if (IS0(a) || IS0(b)) return NULL;
+
+  fraction fa = (fraction)a;
+  fraction fb = (fraction)b;
+
+  const poly g = pp_Mult_qq(NUM(fa), NUM(fb), ntRing);
+
+  if (g == NULL) return NULL; // may happen due to zero divisors???
+
+  fraction result = (fraction)omAllocBin(fractionObjectBin);
+
+  NUM(result) = g;
+
+  const poly da = DEN(fa);
+  const poly db = DEN(fb);
+
+
+  //check_N((number)result,cf);
+  if (db == NULL)
+  {
+    // b = ? // NULL
+
+    if(da == NULL)
+    { // both fa && fb are ?? // NULL!
+      assume (da == NULL && db == NULL);
+      DEN(result) = NULL;
+      COM(result) = 0;
+    }
+    else
+    {
+      assume (da != NULL && db == NULL);
+      DEN(result) = p_Copy(da, ntRing);
+      COM(result) = COM(fa) + MULT_COMPLEXITY;
+      heuristicGcdCancellation((number)result, cf);
+      //check_N((number)result,cf);
+    }
+  }
+  else
+  { // b = ?? / ??
+    if (da == NULL)
+    { // a == ? // NULL
+      assume( db != NULL && da == NULL);
+      DEN(result) = p_Copy(db, ntRing);
+      COM(result) = COM(fb) + MULT_COMPLEXITY;
+      heuristicGcdCancellation((number)result, cf);
+      //check_N((number)result,cf);
+    }
+    else /* both den's are != 1 */
+    {
+      assume (da != NULL && db != NULL);
+      DEN(result) = pp_Mult_qq(da, db, ntRing);
+      COM(result) = COM(fa) + COM(fb) + MULT_COMPLEXITY;
+      heuristicGcdCancellation((number)result, cf);
+      //check_N((number)result,cf);
+    }
+  }
+
+//  ntTest((number)result);
+
+  //check_N((number)result,cf);
+  return (number)result;
+}
+
+number ntDiv(number a, number b, const coeffs cf)
+{
+  //check_N(a,cf);
+  //check_N(b,cf);
+  ntTest(a);
+  ntTest(b);
+  if (IS0(a)) return NULL;
+  if (IS0(b)) WerrorS(nDivBy0);
+
+  fraction fa = (fraction)a;
+  fraction fb = (fraction)b;
+
+  poly g = p_Copy(NUM(fa), ntRing);
+  if (!DENIS1(fb)) g = p_Mult_q(g, p_Copy(DEN(fb), ntRing), ntRing);
+
+  if (g == NULL) return NULL;   /* may happen due to zero divisors */
+
+  poly f = p_Copy(NUM(fb), ntRing);
+  if (!DENIS1(fa)) f = p_Mult_q(f, p_Copy(DEN(fa), ntRing), ntRing);
+
+  fraction result = (fraction)omAlloc0Bin(fractionObjectBin);
+  NUM(result) = g;
+  if (!n_GreaterZero(pGetCoeff(f),ntCoeffs))
+  {
+    g=p_Neg(g,ntRing);
+    f=p_Neg(f,ntRing);
+    NUM(result) = g;
+  }
+  if (!p_IsConstant(f,ntRing) || !n_IsOne(pGetCoeff(f),ntCoeffs))
+  {
+    DEN(result) = f;
+  }
+  COM(result) = COM(fa) + COM(fb) + MULT_COMPLEXITY;
+  heuristicGcdCancellation((number)result, cf);
+//  ntTest((number)result);
+  //check_N((number)result,cf);
+  return (number)result;
+}
+
+/* 0^0 = 0;
+   for |exp| <= 7 compute power by a simple multiplication loop;
+   for |exp| >= 8 compute power along binary presentation of |exp|, e.g.
+      p^13 = p^1 * p^4 * p^8, where we utilise that
+      p^(2^(k+1)) = p^(2^k) * p^(2^k);
+   intermediate cancellation is controlled by the in-place method
+   heuristicGcdCancellation; see there.
+*/
+void ntPower(number a, int exp, number *b, const coeffs cf)
+{
+  ntTest(a);
+
+  /* special cases first */
+  if (IS0(a))
+  {
+    if (exp >= 0) *b = NULL;
+    else          WerrorS(nDivBy0);
+  }
+  else if (exp ==  0) { *b = ntInit(1, cf); return;}
+  else if (exp ==  1) { *b = ntCopy(a, cf); return;}
+  else if (exp == -1) { *b = ntInvers(a, cf); return;}
+
+  int expAbs = exp; if (expAbs < 0) expAbs = -expAbs;
+
+  /* now compute a^expAbs */
+  number pow; number t;
+  if (expAbs <= 7)
+  {
+    pow = ntCopy(a, cf);
+    for (int i = 2; i <= expAbs; i++)
+    {
+      t = ntMult(pow, a, cf);
+      ntDelete(&pow, cf);
+      pow = t;
+      heuristicGcdCancellation(pow, cf);
+    }
+  }
+  else
+  {
+    pow = ntInit(1, cf);
+    number factor = ntCopy(a, cf);
+    while (expAbs != 0)
+    {
+      if (expAbs & 1)
+      {
+        t = ntMult(pow, factor, cf);
+        ntDelete(&pow, cf);
+        pow = t;
+        heuristicGcdCancellation(pow, cf);
+      }
+      expAbs = expAbs / 2;
+      if (expAbs != 0)
+      {
+        t = ntMult(factor, factor, cf);
+        ntDelete(&factor, cf);
+        factor = t;
+        heuristicGcdCancellation(factor, cf);
+      }
+    }
+    ntDelete(&factor, cf);
+  }
+
+  /* invert if original exponent was negative */
+  if (exp < 0)
+  {
+    t = ntInvers(pow, cf);
+    ntDelete(&pow, cf);
+    pow = t;
+  }
+  *b = pow;
+  ntTest(*b);
+  //check_N(*b,cf);
+}
+
+/* assumes that cf represents the rationals, i.e. Q, and will only
+   be called in that case;
+   assumes furthermore that f != NULL and that the denominator of f != 1;
+   generally speaking, this method removes denominators in the rational
+   coefficients of the numerator and denominator of 'a';
+   more concretely, the following normalizations will be performed,
+   where t^alpha denotes a monomial in the transcendental variables t_k
+   (1) if 'a' is of the form
+          (sum_alpha a_alpha/b_alpha * t^alpha)
+          -------------------------------------
+            (sum_beta c_beta/d_beta * t^beta)
+       with integers a_alpha, b_alpha, c_beta, d_beta, then both the
+       numerator and the denominator will be multiplied by the LCM of
+       the b_alpha's and the d_beta's (if this LCM is != 1),
+   (2) if 'a' is - e.g. after having performed step (1) - of the form
+          (sum_alpha a_alpha * t^alpha)
+          -----------------------------
+            (sum_beta c_beta * t^beta)
+       with integers a_alpha, c_beta, and with a non-constant denominator,
+       then both the numerator and the denominator will be divided by the
+       GCD of the a_alpha's and the c_beta's (if this GCD is != 1),
+   this procedure does not alter COM(f) (this has to be done by the
+   calling procedure);
+   modifies f */
+void handleNestedFractionsOverQ(fraction f, const coeffs cf)
+{
+  assume(nCoeff_is_Q(ntCoeffs));
+  assume(!IS0(f));
+  assume(!DENIS1(f));
+
+  { /* step (1); see documentation of this procedure above */
+    number lcmOfDenominators = n_Init(1, ntCoeffs);
+    number c; number tmp;
+    poly p = NUM(f);
+    /* careful when using n_NormalizeHelper!!! It computes the lcm of the numerator
+       of the 1st argument and the denominator of the 2nd!!! */
+    while (p != NULL)
+    {
+      c = p_GetCoeff(p, ntRing);
+      tmp = n_NormalizeHelper(lcmOfDenominators, c, ntCoeffs);
+      n_Delete(&lcmOfDenominators, ntCoeffs);
+      lcmOfDenominators = tmp;
+      pIter(p);
+    }
+    p = DEN(f);
+    while (p != NULL)
+    {
+      c = p_GetCoeff(p, ntRing);
+      tmp = n_NormalizeHelper(lcmOfDenominators, c, ntCoeffs);
+      n_Delete(&lcmOfDenominators, ntCoeffs);
+      lcmOfDenominators = tmp;
+      pIter(p);
+    }
+    if (!n_IsOne(lcmOfDenominators, ntCoeffs))
+    { /* multiply NUM(f) and DEN(f) with lcmOfDenominators */
+      NUM(f) = p_Mult_nn(NUM(f), lcmOfDenominators, ntRing);
+      p_Normalize(NUM(f), ntRing);
+      DEN(f) = p_Mult_nn(DEN(f), lcmOfDenominators, ntRing);
+      p_Normalize(DEN(f), ntRing);
+    }
+    n_Delete(&lcmOfDenominators, ntCoeffs);
+    if (DEN(f)!=NULL)
+    { /* step (2); see documentation of this procedure above */
+      p = NUM(f);
+      number gcdOfCoefficients = n_Copy(p_GetCoeff(p, ntRing), ntCoeffs);
+      pIter(p);
+      while ((p != NULL) && (!n_IsOne(gcdOfCoefficients, ntCoeffs)))
+      {
+        c = p_GetCoeff(p, ntRing);
+        tmp = n_Gcd(c, gcdOfCoefficients, ntCoeffs);
+        n_Delete(&gcdOfCoefficients, ntCoeffs);
+        gcdOfCoefficients = tmp;
+        pIter(p);
+      }
+      p = DEN(f);
+      while ((p != NULL) && (!n_IsOne(gcdOfCoefficients, ntCoeffs)))
+      {
+        c = p_GetCoeff(p, ntRing);
+        tmp = n_Gcd(c, gcdOfCoefficients, ntCoeffs);
+        n_Delete(&gcdOfCoefficients, ntCoeffs);
+        gcdOfCoefficients = tmp;
+        pIter(p);
+      }
+      if (!n_IsOne(gcdOfCoefficients, ntCoeffs))
+      { /* divide NUM(f) and DEN(f) by gcdOfCoefficients */
+        number inverseOfGcdOfCoefficients = n_Invers(gcdOfCoefficients,
+                                                     ntCoeffs);
+        NUM(f) = p_Mult_nn(NUM(f), inverseOfGcdOfCoefficients, ntRing);
+        p_Normalize(NUM(f), ntRing);
+        DEN(f) = p_Mult_nn(DEN(f), inverseOfGcdOfCoefficients, ntRing);
+        p_Normalize(DEN(f), ntRing);
+        n_Delete(&inverseOfGcdOfCoefficients, ntCoeffs);
+      }
+      n_Delete(&gcdOfCoefficients, ntCoeffs);
+    }
+  }
+
+  /* Now, due to the above computations, DEN(f) may have become the
+     1-polynomial which needs to be represented by NULL: */
+  if ((DEN(f) != NULL) &&
+      p_IsConstant(DEN(f), ntRing) &&
+      n_IsOne(p_GetCoeff(DEN(f), ntRing), ntCoeffs))
+  {
+    p_Delete(&DEN(f), ntRing); DEN(f) = NULL;
+  }
+
+  if( DEN(f) != NULL )
+    if( !n_GreaterZero(pGetCoeff(DEN(f)), ntCoeffs) )
+    {
+      NUM(f) = p_Neg(NUM(f), ntRing);
+      DEN(f) = p_Neg(DEN(f), ntRing);
+    }
+
+  ntTest((number)f); // TODO!
+}
+
+/* modifies a */
+void heuristicGcdCancellation(number a, const coeffs cf)
+{
+//  ntTest(a); // !!!!????
+  if (IS0(a)) return;
+
+  fraction f = (fraction)a;
+  p_Normalize(NUM(f),ntRing);
+  if (DENIS1(f) || NUMIS1(f)) { COM(f) = 0; return; }
+
+  assume( DEN(f) != NULL );
+  p_Normalize(DEN(f),ntRing);
+
+  /* check whether NUM(f) = DEN(f), and - if so - replace 'a' by 1 */
+  if (p_EqualPolys(NUM(f), DEN(f), ntRing))
+  { /* numerator and denominator are both != 1 */
+    p_Delete(&NUM(f), ntRing); NUM(f) = p_ISet(1, ntRing);
+    p_Delete(&DEN(f), ntRing); DEN(f) = NULL;
+    COM(f) = 0;
+  }
+  else
+  {
+    if (COM(f) > BOUND_COMPLEXITY)
+      definiteGcdCancellation(a, cf, TRUE);
+
+    // TODO: check if it is enough to put the following into definiteGcdCancellation?!
+    if( DEN(f) != NULL )
+    {
+      if( !n_GreaterZero(pGetCoeff(DEN(f)), ntCoeffs) )
+      {
+        NUM(f) = p_Neg(NUM(f), ntRing);
+        DEN(f) = p_Neg(DEN(f), ntRing);
+      }
+      if (ntCoeffs->has_simple_Inverse)
+      {
+        if (!n_IsOne(pGetCoeff(DEN(f)),ntCoeffs))
+        {
+          number inv=n_Invers(pGetCoeff(DEN(f)),ntCoeffs);
+          DEN(f)=p_Mult_nn(DEN(f),inv,ntRing);
+          NUM(f)=p_Mult_nn(NUM(f),inv,ntRing);
+        }
+        if(p_LmIsConstant(DEN(f),ntRing))
+        {
+          p_Delete(&DEN(f),ntRing);
+          COM(f)=0;
+        }
+      }
+    }
+  }
+
+  ntTest(a);
+}
+
+/// modifies a
+void definiteGcdCancellation(number a, const coeffs cf,
+                             BOOLEAN simpleTestsHaveAlreadyBeenPerformed)
+{
+  ntTest(a); // !!!!
+
+  fraction f = (fraction)a;
+
+  if (IS0(a)) return;
+  if (!simpleTestsHaveAlreadyBeenPerformed)
+  {
+    if (DENIS1(f) || NUMIS1(f)) { COM(f) = 0; return; }
+
+    /* check whether NUM(f) = DEN(f), and - if so - replace 'a' by 1 */
+    if (p_EqualPolys(NUM(f), DEN(f), ntRing))
+    { /* numerator and denominator are both != 1 */
+      p_Delete(&NUM(f), ntRing); NUM(f) = p_ISet(1, ntRing);
+      p_Delete(&DEN(f), ntRing); DEN(f) = NULL;
+      COM(f) = 0;
+      ntTest(a); // !!!!
+      return;
+    }
+  }
+  /*if (rField_is_Q(ntRing))
+  {
+    number c=n_Copy(pGetCoeff(NUM(f)),ntCoeffs);
+    poly p=pNext(NUM(f));
+    while((p!=NULL)&&(!n_IsOne(c,ntCoeffs)))
+    {
+      number cc=n_Gcd(c,pGetCoeff(p),ntCoeffs);
+      n_Delete(&c,ntCoeffs);
+      c=cc;
+      pIter(p);
+    };
+    p=DEN(f);
+    while((p!=NULL)&&(!n_IsOne(c,ntCoeffs)))
+    {
+      number cc=n_Gcd(c,pGetCoeff(p),ntCoeffs);
+      n_Delete(&c,ntCoeffs);
+      c=cc;
+      pIter(p);
+    };
+    if(!n_IsOne(c,ntCoeffs))
+    {
+      p=NUM(f);
+      do
+      {
+        number cc=n_Div(pGetCoeff(p),c,ntCoeffs);
+        n_Normalize(cc,ntCoeffs);
+        p_SetCoeff(p,cc,ntRing);
+        pIter(p);
+      } while(p!=NULL);
+      p=DEN(f);
+      do
+      {
+        number cc=n_Div(pGetCoeff(p),c,ntCoeffs);
+        n_Normalize(cc,ntCoeffs);
+        p_SetCoeff(p,cc,ntRing);
+        pIter(p);
+      } while(p!=NULL);
+      n_Delete(&c,ntCoeffs);
+      if(pNext(DEN(f))==NULL)
+      {
+        if (p_IsOne(DEN(f),ntRing))
+        {
+          p_LmDelete(&DEN(f),ntRing);
+          COM(f)=0;
+          return;
+        }
+        else
+        {
+          return;
+        }
+      }
+    }
+  }*/
+
+  /* here we assume: NUM(f), DEN(f) !=NULL, in Z_a reqp. Z/p_a */
+  poly pGcd = singclap_gcd_and_divide(NUM(f), DEN(f), ntRing);
+  if (p_IsConstant(pGcd, ntRing)
+  && n_IsOne(p_GetCoeff(pGcd, ntRing), ntCoeffs)
+  )
+  { /* gcd = 1; nothing to cancel;
+       Suppose the given rational function field is over Q. Although the
+       gcd is 1, we may have produced fractional coefficients in NUM(f),
+       DEN(f), or both, due to previous arithmetics. The next call will
+       remove those nested fractions, in case there are any. */
+    if (nCoeff_is_Zp(ntCoeffs))
+    {
+      NUM (f) = p_Div_nn (NUM (f), p_GetCoeff (DEN(f),ntRing), ntRing);
+      if (p_IsConstant (DEN (f), ntRing))
+      {
+        p_Delete(&DEN (f), ntRing);
+        DEN (f) = NULL;
+      }
+      else
+      {
+        p_Norm (DEN (f),ntRing);
+      }
+    } else if (nCoeff_is_Q(ntCoeffs)) handleNestedFractionsOverQ(f, cf);
+  }
+  else
+  { /* We divide both NUM(f) and DEN(f) by the gcd which is known
+       to be != 1. */
+    if (p_IsConstant(DEN(f), ntRing) &&
+        n_IsOne(p_GetCoeff(DEN(f), ntRing), ntCoeffs))
+    {
+      /* DEN(f) = 1 needs to be represented by NULL! */
+      p_Delete(&DEN(f), ntRing);
+      DEN(f) = NULL;
+    }
+    else
+    {
+      if (nCoeff_is_Zp(ntCoeffs))
+      {
+        NUM (f) = p_Div_nn (NUM (f), p_GetCoeff (DEN(f),ntRing), ntRing);
+        if (p_IsConstant (DEN (f), ntRing))
+        {
+          p_Delete(&DEN (f), ntRing);
+          DEN (f) = NULL;
+        }
+        else
+        {
+          p_Norm (DEN (f),ntRing);
+        }
+      }
+    }
+  }
+  COM(f) = 0;
+  p_Delete(&pGcd, ntRing);
+
+  if( DEN(f) != NULL )
+    if( !n_GreaterZero(pGetCoeff(DEN(f)), ntCoeffs) )
+    {
+      NUM(f) = p_Neg(NUM(f), ntRing);
+      DEN(f) = p_Neg(DEN(f), ntRing);
+      if (p_IsConstant(DEN(f), ntRing) &&
+        n_IsOne(p_GetCoeff(DEN(f), ntRing), ntCoeffs))
+      {
+        /* DEN(f) = 1 needs to be represented by NULL! */
+        p_Delete(&DEN(f), ntRing);
+        DEN (f) = NULL;
+      }
+    }
+  ntTest(a); // !!!!
+}
+
+// NOTE: modifies a
+void ntWriteLong(number &a, const coeffs cf)
+{
+  ntTest(a);
+  definiteGcdCancellation(a, cf, FALSE);
+  if (IS0(a))
+    StringAppendS("0");
+  else
+  {
+    fraction f = (fraction)a;
+    // stole logic from napWrite from kernel/longtrans.cc of legacy singular
+    BOOLEAN omitBrackets = p_IsConstant(NUM(f), ntRing);
+    if (!omitBrackets) StringAppendS("(");
+    p_String0Long(NUM(f), ntRing, ntRing);
+    if (!omitBrackets) StringAppendS(")");
+    if (!DENIS1(f))
+    {
+      StringAppendS("/");
+      omitBrackets = p_IsConstant(DEN(f), ntRing);
+      if (!omitBrackets) StringAppendS("(");
+      p_String0Long(DEN(f), ntRing, ntRing);
+      if (!omitBrackets) StringAppendS(")");
+    }
+  }
+  ntTest(a); // !!!!
+}
+
+// NOTE: modifies a
+void ntWriteShort(number &a, const coeffs cf)
+{
+  ntTest(a);
+  definiteGcdCancellation(a, cf, FALSE);
+  if (IS0(a))
+    StringAppendS("0");
+  else
+  {
+    fraction f = (fraction)a;
+    // stole logic from napWrite from kernel/longtrans.cc of legacy singular
+    BOOLEAN omitBrackets = p_IsConstant(NUM(f), ntRing);
+    if (!omitBrackets) StringAppendS("(");
+    p_String0Short(NUM(f), ntRing, ntRing);
+    if (!omitBrackets) StringAppendS(")");
+    if (!DENIS1(f))
+    {
+      StringAppendS("/");
+      omitBrackets = p_IsConstant(DEN(f), ntRing);
+      if (!omitBrackets) StringAppendS("(");
+      p_String0Short(DEN(f), ntRing, ntRing);
+      if (!omitBrackets) StringAppendS(")");
+    }
+  }
+  ntTest(a);
+}
+
+const char * ntRead(const char *s, number *a, const coeffs cf)
+{
+  poly p;
+  const char * result = p_Read(s, p, ntRing);
+  if (p == NULL) *a = NULL;
+  else *a = ntInit(p, cf);
+  return result;
+}
+
+void ntNormalize (number &a, const coeffs cf)
+{
+  if ( /*(*/ a!=NULL /*)*/ )
+  {
+    definiteGcdCancellation(a, cf, FALSE);
+    if ((DEN(a)!=NULL)
+    &&(!n_GreaterZero(pGetCoeff(DEN(a)),ntCoeffs)))
+    {
+      NUM(a)=p_Neg(NUM(a),ntRing);
+      DEN(a)=p_Neg(DEN(a),ntRing);
+    }
+  }
+  ntTest(a); // !!!!
+}
+
+/* expects *param to be castable to TransExtInfo */
+static BOOLEAN ntCoeffIsEqual(const coeffs cf, n_coeffType n, void * param)
+{
+  if (ID != n) return FALSE;
+  TransExtInfo *e = (TransExtInfo *)param;
+  /* for rational function fields we expect the underlying
+     polynomial rings to be IDENTICAL, i.e. the SAME OBJECT;
+     this expectation is based on the assumption that we have properly
+     registered cf and perform reference counting rather than creating
+     multiple copies of the same coefficient field/domain/ring */
+  if (ntRing == e->r)
+    return TRUE;
+
+  // NOTE: Q(a)[x] && Q(a)[y] should better share the _same_ Q(a)...
+  if( rEqual(ntRing, e->r, TRUE) )
+  {
+    rDelete(e->r);
+    return TRUE;
+  }
+
+  return FALSE;
+}
+
+number ntNormalizeHelper(number a, number b, const coeffs cf)
+{
+  ntTest(a);
+  ntTest(b);
+  fraction fb = (fraction)b;
+  if ((b==NULL)||(DEN(fb)==NULL)) return ntCopy(a,cf);
+  fraction fa = (fraction)a;
+  /* singclap_gcd destroys its arguments; we hence need copies: */
+  poly pa = p_Copy(NUM(fa), ntRing);
+  poly pb = p_Copy(DEN(fb), ntRing);
+
+  poly pGcd;
+  if (nCoeff_is_Q(ntCoeffs))
+  {
+    if (p_IsConstant(pa,ntRing) && p_IsConstant(pb,ntRing))
+    {
+      pGcd = pa;
+      p_SetCoeff (pGcd, n_Gcd (pGetCoeff(pGcd), pGetCoeff(pb), ntCoeffs), ntRing);
+    }
+    else
+    {
+      number contentpa, contentpb, tmp;
+
+      contentpb= p_GetCoeff(pb, ntRing);
+      pIter(pb);
+      while (pb != NULL)
+      {
+        tmp = n_SubringGcd(contentpb, p_GetCoeff(pb, ntRing) , ntCoeffs);
+        n_Delete(&contentpb, ntCoeffs);
+        contentpb = tmp;
+        pIter(pb);
+      }
+
+      contentpa= p_GetCoeff(pa, ntRing);
+      pIter(pa);
+      while (pa != NULL)
+      {
+        tmp = n_SubringGcd(contentpa, p_GetCoeff(pa, ntRing), ntCoeffs);
+        n_Delete(&contentpa, ntCoeffs);
+        contentpa = tmp;
+        pIter(pa);
+      }
+
+      tmp= n_SubringGcd (contentpb, contentpa, ntCoeffs);
+      n_Delete(&contentpa, ntCoeffs);
+      n_Delete(&contentpb, ntCoeffs);
+      contentpa= tmp;
+      p_Delete(&pb, ntRing);
+      p_Delete(&pa, ntRing);
+
+      /* singclap_gcd destroys its arguments; we hence need copies: */
+      pGcd = singclap_gcd(p_Copy(NUM(fa),ntRing), p_Copy(DEN(fb),ntRing), ntRing);
+      pGcd= p_Mult_nn (pGcd, contentpa, ntRing);
+      n_Delete(&contentpa, ntCoeffs);
+    }
+  }
+  else
+    pGcd = singclap_gcd(pa, pb, cf->extRing);
+
+  /* Note that, over Q, singclap_gcd will remove the denominators in all
+     rational coefficients of pa and pb, before starting to compute
+     the gcd. Thus, we do not need to ensure that the coefficients of
+     pa and pb live in Z; they may well be elements of Q\Z. */
+
+  if (p_IsConstant(pGcd, ntRing) &&
+      n_IsOne(p_GetCoeff(pGcd, ntRing), ntCoeffs))
+  { /* gcd = 1; return pa*pb*/
+    p_Delete(&pGcd,ntRing);
+    fraction result = (fraction)omAlloc0Bin(fractionObjectBin);
+    NUM(result) = pp_Mult_qq(NUM(fa),DEN(fb),ntRing);
+
+    ntTest((number)result); // !!!!
+
+    return (number)result;
+  }
+
+
+  /* return pa*pb/gcd */
+    poly newNum = singclap_pdivide(NUM(fa), pGcd, ntRing);
+    p_Delete(&pGcd,ntRing);
+    fraction result = (fraction)omAlloc0Bin(fractionObjectBin);
+    NUM(result) = p_Mult_q(p_Copy(DEN(fb),ntRing),newNum,ntRing);
+    ntTest((number)result); // !!!!
+    return (number)result;
+
+  return NULL;
+}
+
+number ntGcd(number a, number b, const coeffs cf)
+{
+  ntTest(a);
+  ntTest(b);
+  if (a==NULL) return ntCopy(b,cf);
+  if (b==NULL) return ntCopy(a,cf);
+  fraction fa = (fraction)a;
+  fraction fb = (fraction)b;
+
+  poly pa = p_Copy(NUM(fa), ntRing);
+  poly pb = p_Copy(NUM(fb), ntRing);
+
+  poly pGcd;
+  if (nCoeff_is_Q(ntCoeffs))
+  {
+    if (p_IsConstant(pa,ntRing) && p_IsConstant(pb,ntRing))
+    {
+      pGcd = pa;
+      p_SetCoeff (pGcd, n_SubringGcd (pGetCoeff(pGcd), pGetCoeff(pb), ntCoeffs), ntRing);
+    }
+    else
+    {
+      number contentpa, contentpb, tmp;
+
+      contentpb= p_GetCoeff(pb, ntRing);
+      pIter(pb);
+      while (pb != NULL)
+      {
+        tmp = n_SubringGcd(contentpb, p_GetCoeff(pb, ntRing) , ntCoeffs);
+        n_Delete(&contentpb, ntCoeffs);
+        contentpb = tmp;
+        pIter(pb);
+      }
+
+      contentpa= p_GetCoeff(pa, ntRing);
+      pIter(pa);
+      while (pa != NULL)
+      {
+        tmp = n_SubringGcd(contentpa, p_GetCoeff(pa, ntRing), ntCoeffs);
+        n_Delete(&contentpa, ntCoeffs);
+        contentpa = tmp;
+        pIter(pa);
+      }
+
+      tmp= n_SubringGcd (contentpb, contentpa, ntCoeffs);
+      n_Delete(&contentpa, ntCoeffs);
+      n_Delete(&contentpb, ntCoeffs);
+      contentpa= tmp;
+      p_Delete(&pb, ntRing);
+      p_Delete(&pa, ntRing);
+
+      /* singclap_gcd destroys its arguments; we hence need copies: */
+      pGcd = singclap_gcd(p_Copy(NUM(fa),ntRing), p_Copy(NUM(fb),ntRing), ntRing);
+      pGcd= p_Mult_nn (pGcd, contentpa, ntRing);
+      n_Delete(&contentpa, ntCoeffs);
+    }
+  }
+  else
+    pGcd = singclap_gcd(pa, pb, cf->extRing);
+  /* Note that, over Q, singclap_gcd will remove the denominators in all
+     rational coefficients of pa and pb, before starting to compute
+     the gcd. Thus, we do not need to ensure that the coefficients of
+     pa and pb live in Z; they may well be elements of Q\Z. */
+
+  fraction result = (fraction)omAlloc0Bin(fractionObjectBin);
+  NUM(result) = pGcd;
+  ntTest((number)result); // !!!!
+  return (number)result;
+}
+//number ntGcd_dummy(number a, number b, const coeffs cf)
+//{
+//  extern char my_yylinebuf[80];
+//  Print("ntGcd in >>%s<<\n",my_yylinebuf);
+//  return ntGcd(a,b,cf);
+//}
+
+int ntSize(number a, const coeffs cf)
+{
+  ntTest(a);
+  if (IS0(a)) return -1;
+  /* this has been taken from the old implementation of field extensions,
+     where we computed the sum of the degrees and the numbers of terms in
+     the numerator and denominator of a; so we leave it at that, for the
+     time being */
+  fraction f = (fraction)a;
+  poly p = NUM(f);
+  int noOfTerms = 0;
+  int numDegree = 0;
+  while (p != NULL)
+  {
+    noOfTerms++;
+    int d = 0;
+    for (int i = 1; i <= rVar(ntRing); i++)
+      d += p_GetExp(p, i, ntRing);
+    if (d > numDegree) numDegree = d;
+    pIter(p);
+  }
+  int denDegree = 0;
+  if (!DENIS1(f))
+  {
+    p = DEN(f);
+    while (p != NULL)
+    {
+      noOfTerms++;
+      int d = 0;
+      for (int i = 1; i <= rVar(ntRing); i++)
+        d += p_GetExp(p, i, ntRing);
+      if (d > denDegree) denDegree = d;
+      pIter(p);
+    }
+  }
+  ntTest(a); // !!!!
+  return numDegree + denDegree + noOfTerms;
+}
+
+number ntInvers(number a, const coeffs cf)
+{
+  //check_N(a,cf);
+  ntTest(a);
+  if (IS0(a))
+  {
+    WerrorS(nDivBy0);
+    return NULL;
+  }
+  fraction f = (fraction)a;
+  assume( f != NULL );
+
+  fraction result = (fraction)omAlloc0Bin(fractionObjectBin);
+
+  assume( NUM(f) != NULL );
+  const poly den = DEN(f);
+
+  if (den == NULL)
+    NUM(result) = p_One(ntRing);
+  else
+    NUM(result) = p_Copy(den, ntRing);
+
+  if( !NUMIS1(f) )
+  {
+    poly num_f=NUM(f);
+    BOOLEAN neg= !n_GreaterZero(pGetCoeff(num_f),ntCoeffs);
+    if (neg)
+    {
+      num_f=p_Neg(p_Copy(num_f, ntRing), ntRing);
+      NUM(result)=p_Neg(NUM(result), ntRing);
+    }
+    else
+    {
+      num_f=p_Copy(num_f, ntRing);
+    }
+    DEN(result) = num_f;
+    COM(result) = COM(f);
+    if (neg)
+    {
+      if (p_IsOne(num_f, ntRing))
+      {
+        DEN(result)=NULL;
+        //COM(result) = 0;
+        p_Delete(&num_f,ntRing);
+      }
+    }
+  }
+  //else// Alloc0
+  //{
+  //  DEN(result) = NULL;
+  //  COM(result) = 0;
+  //}
+  ntTest((number)result); // !!!!
+  //check_N((number)result,cf);
+  return (number)result;
+}
+
+/* assumes that src = Q or Z, dst = Q(t_1, ..., t_s) */
+number ntMap00(number a, const coeffs src, const coeffs dst)
+{
+  if (n_IsZero(a, src)) return NULL;
+  n_Test(a, src);
+  assume(src->rep == dst->extRing->cf->rep);
+  if ((SR_HDL(a) & SR_INT) || (a->s==3))
+  {
+    number res=ntInit(p_NSet(n_Copy(a, src), dst->extRing), dst);
+    n_Test(res,dst);
+    return res;
+  }
+  number nn=n_GetDenom(a,src);
+  number zz=n_GetNumerator(a,src);
+  number res=ntInit(p_NSet(zz,dst->extRing), dst);
+  fraction ff=(fraction)res;
+  if (n_IsOne(nn,src)) DEN(ff)=NULL;
+  else                 DEN(ff)=p_NSet(nn,dst->extRing);
+  n_Test((number)ff,dst);
+  //check_N((number)ff,dst);
+  return (number)ff;
+}
+
+number ntMapZ0(number a, const coeffs src, const coeffs dst)
+{
+  if (n_IsZero(a, src)) return NULL;
+  n_Test(a, src);
+  nMapFunc nMap=n_SetMap(src,dst->extRing->cf);
+  poly p=p_NSet(nMap(a, src,dst->extRing->cf), dst->extRing);
+  if (n_IsZero(pGetCoeff(p),dst->extRing->cf))
+    p_Delete(&p,dst->extRing);
+  number res=ntInit(p, dst);
+  n_Test(res,dst);
+  return res;
+}
+
+/* assumes that src = Z/p, dst = Q(t_1, ..., t_s) */
+number ntMapP0(number a, const coeffs src, const coeffs dst)
+{
+  if (n_IsZero(a, src)) return NULL;
+  n_Test(a, src);
+  /* mapping via intermediate int: */
+  int n = n_Int(a, src);
+  number q = n_Init(n, dst->extRing->cf);
+  if (n_IsZero(q, dst->extRing->cf))
+  {
+    n_Delete(&q, dst->extRing->cf);
+    return NULL;
+  }
+  return ntInit(p_NSet(q, dst->extRing), dst);
+}
+
+ /* assumes that either src = K(t_1, ..., t_s), dst = K(t_1, ..., t_s) */
+number ntCopyMap(number a, const coeffs cf, const coeffs dst)
+{
+  ntTest(a);
+  if (IS0(a)) return NULL;
+
+  const ring rSrc = cf->extRing;
+  const ring rDst = dst->extRing;
+
+  if( rSrc == rDst )
+    return ntCopy(a, dst); // USUALLY WRONG!
+
+  fraction f = (fraction)a;
+  poly g = prCopyR(NUM(f), rSrc, rDst);
+
+  poly h = NULL;
+
+  if (!DENIS1(f))
+     h = prCopyR(DEN(f), rSrc, rDst);
+
+  fraction result = (fraction)omAllocBin(fractionObjectBin);
+
+  NUM(result) = g;
+  DEN(result) = h;
+  COM(result) = COM(f);
+  //check_N((number)result,dst);
+  n_Test((number)result, dst);
+  return (number)result;
+}
+
+number ntGenMap(number a, const coeffs cf, const coeffs dst)
+{
+  ntTest(a);
+  if (IS0(a)) return NULL;
+
+  const ring rSrc = cf->extRing;
+  const ring rDst = dst->extRing;
+
+  const nMapFunc nMap=n_SetMap(rSrc->cf,rDst->cf);
+  fraction f = (fraction)a;
+  poly g = prMapR(NUM(f), nMap, rSrc, rDst);
+
+  poly h = NULL;
+
+  if (!DENIS1(f))
+     h = prMapR(DEN(f), nMap, rSrc, rDst);
+
+  fraction result = (fraction)omAllocBin(fractionObjectBin);
+
+  NUM(result) = g;
+  DEN(result) = h;
+  COM(result) = COM(f);
+  //check_N((number)result,dst);
+  n_Test((number)result, dst);
+  return (number)result;
+}
+
+number ntCopyAlg(number a, const coeffs cf, const coeffs dst)
+{
+  n_Test(a, cf) ;
+  if (n_IsZero(a, cf)) return NULL;
+  return ntInit(prCopyR((poly)a, cf->extRing, dst->extRing),dst);
+}
+
+number ntGenAlg(number a, const coeffs cf, const coeffs dst)
+{
+  n_Test(a, cf) ;
+  if (n_IsZero(a, cf)) return NULL;
+
+  const nMapFunc nMap=n_SetMap(cf->extRing->cf,dst->extRing->cf);
+  return ntInit(prMapR((poly)a, nMap, cf->extRing, dst->extRing),dst);
+}
+
+/* assumes that src = Q, dst = Z/p(t_1, ..., t_s) */
+number ntMap0P(number a, const coeffs src, const coeffs dst)
+{
+  n_Test(a, src) ;
+  if (n_IsZero(a, src)) return NULL;
+  // int p = rChar(dst->extRing);
+
+  number q = nlModP(a, src, dst->extRing->cf); // FIXME? TODO? // extern number nlModP(number q, const coeffs Q, const coeffs Zp); // Map q \in QQ \to Zp
+
+  if (n_IsZero(q, dst->extRing->cf))
+  {
+    n_Delete(&q, dst->extRing->cf);
+    return NULL;
+  }
+
+  poly g = p_NSet(q, dst->extRing);
+
+  fraction f = (fraction)omAlloc0Bin(fractionObjectBin);
+  NUM(f) = g; // DEN(f) = NULL; COM(f) = 0;
+  n_Test((number)f, dst);
+  //check_N((number)f,dst);
+  return (number)f;
+}
+
+/* assumes that src = Z/p, dst = Z/p(t_1, ..., t_s) */
+number ntMapPP(number a, const coeffs src, const coeffs dst)
+{
+  n_Test(a, src) ;
+  if (n_IsZero(a, src)) return NULL;
+  assume(src == dst->extRing->cf);
+  poly p = p_One(dst->extRing);
+  p_SetCoeff(p, n_Copy(a, src), dst->extRing);
+  fraction f = (fraction)omAlloc0Bin(fractionObjectBin);
+  NUM(f) = p; // DEN(f) = NULL; COM(f) = 0;
+  n_Test((number)f, dst);
+  //check_N((number)f,dst);
+  return (number)f;
+}
+
+/* assumes that src = Z/u, dst = Z/p(t_1, ..., t_s), where u != p */
+number ntMapUP(number a, const coeffs src, const coeffs dst)
+{
+  n_Test(a, src) ;
+  if (n_IsZero(a, src)) return NULL;
+  /* mapping via intermediate int: */
+  int n = n_Int(a, src);
+  number q = n_Init(n, dst->extRing->cf);
+  poly p;
+  if (n_IsZero(q, dst->extRing->cf))
+  {
+    n_Delete(&q, dst->extRing->cf);
+    return NULL;
+  }
+  p = p_One(dst->extRing);
+  p_SetCoeff(p, q, dst->extRing);
+  fraction f = (fraction)omAlloc0Bin(fractionObjectBin);
+  NUM(f) = p; // DEN(f) = NULL; COM(f) = 0;
+  n_Test((number)f, dst);
+  //check_N((number)f,dst);
+  return (number)f;
+}
+
+nMapFunc ntSetMap(const coeffs src, const coeffs dst)
+{
+  /* dst is expected to be a rational function field */
+  assume(getCoeffType(dst) == ID);
+
+  if( src == dst ) return ndCopyMap;
+
+  int h = 0; /* the height of the extension tower given by dst */
+  coeffs bDst = nCoeff_bottom(dst, h); /* the bottom field in the tower dst */
+  coeffs bSrc = nCoeff_bottom(src, h); /* the bottom field in the tower src */
+
+  /* for the time being, we only provide maps if h = 1 and if b is Q or
+     some field Z/pZ: */
+  if (h==0)
+  {
+    if ((src->rep==n_rep_gap_rat) && nCoeff_is_Q(bDst))
+      return ntMap00;                                 /// Q or Z   -->  Q(T)
+    if (src->rep==n_rep_gap_gmp)
+      return ntMapZ0;                                 /// Z   -->  K(T)
+    if (nCoeff_is_Zp(src) && nCoeff_is_Q(bDst))
+      return ntMapP0;                                 /// Z/p     -->  Q(T)
+    if (nCoeff_is_Q(src) && nCoeff_is_Zp(bDst))
+      return ntMap0P;                                 /// Q       --> Z/p(T)
+    if (nCoeff_is_Zp(src) && nCoeff_is_Zp(bDst))
+    {
+      if (src->ch == dst->ch) return ntMapPP;         /// Z/p     --> Z/p(T)
+      else return ntMapUP;                            /// Z/u     --> Z/p(T)
+    }
+  }
+  if (h != 1) return NULL;
+  //if ((!nCoeff_is_Zp(bDst)) && (!nCoeff_is_Q(bDst))) return NULL;
+
+  /* Let T denote the sequence of transcendental extension variables, i.e.,
+     K[t_1, ..., t_s] =: K[T];
+     Let moreover, for any such sequence T, T' denote any subsequence of T
+     of the form t_1, ..., t_w with w <= s. */
+
+  if (rVar(src->extRing) > rVar(dst->extRing))
+     return NULL;
+
+  for (int i = 0; i < rVar(src->extRing); i++)
+    if (strcmp(rRingVar(i, src->extRing), rRingVar(i, dst->extRing)) != 0)
+       return NULL;
+
+  if (src->type==n_transExt)
+  {
+     if (src->extRing->cf==dst->extRing->cf)
+       return ntCopyMap;          /// K(T')   --> K(T)
+     else
+       return ntGenMap;          /// K(T')   --> K'(T)
+  }
+  else
+  {
+     if (src->extRing->cf==dst->extRing->cf)
+       return ntCopyAlg;          /// K(T')   --> K(T)
+     else
+       return ntGenAlg;          /// K(T')   --> K'(T)
+  }
+
+  return NULL;                                 /// default
+}
+#if 0
+nMapFunc ntSetMap_T(const coeffs src, const coeffs dst)
+{
+  nMapFunc n=ntSetMap(src,dst);
+  if (n==ntCopyAlg) printf("n=ntCopyAlg\n");
+  else if (n==ntCopyMap) printf("n=ntCopyMap\n");
+  else if (n==ntMapUP) printf("n=ntMapUP\n");
+  else if (n==ntMap0P) printf("n=ntMap0P\n");
+  else if (n==ntMapP0) printf("n=ntMapP0\n");
+  else if (n==ntMap00) printf("n=ntMap00\n");
+  else if (n==NULL) printf("n=NULL\n");
+  else printf("n=?\n");
+  return n;
+}
+#endif
+
+void ntKillChar(coeffs cf)
+{
+  if ((--cf->extRing->ref) == 0)
+    rDelete(cf->extRing);
+}
+number ntConvFactoryNSingN( const CanonicalForm n, const coeffs cf)
+{
+  if (n.isZero()) return NULL;
+  poly p=convFactoryPSingP(n,ntRing);
+  p_Normalize(p,ntRing);
+  fraction result = (fraction)omAlloc0Bin(fractionObjectBin);
+  NUM(result) = p;
+  //DEN(result) = NULL; // done by omAlloc0Bin
+  //COM(result) = 0; // done by omAlloc0Bin
+  ntTest((number)result);
+  return (number)result;
+}
+CanonicalForm ntConvSingNFactoryN( number n, BOOLEAN /*setChar*/, const coeffs cf )
+{
+  ntTest(n);
+  if (IS0(n)) return CanonicalForm(0);
+
+  fraction f = (fraction)n;
+  return convSingPFactoryP(NUM(f),ntRing);
+}
+
+static int ntParDeg(number a, const coeffs cf)
+{
+  ntTest(a);
+  if (IS0(a)) return -1;
+  fraction fa = (fraction)a;
+  return cf->extRing->pFDeg(NUM(fa),cf->extRing);
+}
+
+/// return the specified parameter as a number in the given trans.ext.
+static number ntParameter(const int iParameter, const coeffs cf)
+{
+  assume(getCoeffType(cf) == ID);
+
+  const ring R = cf->extRing;
+  assume( R != NULL );
+  assume( 0 < iParameter && iParameter <= rVar(R) );
+
+  poly p = p_One(R); p_SetExp(p, iParameter, 1, R); p_Setm(p, R);
+  p_Test(p,R);
+
+  fraction f = (fraction)omAlloc0Bin(fractionObjectBin);
+  NUM(f) = p;
+  //DEN(f) = NULL;
+  //COM(f) = 0;
+
+  ntTest((number)f);
+
+  return (number)f;
+}
+
+/// if m == var(i)/1 => return i,
+int ntIsParam(number m, const coeffs cf)
+{
+  ntTest(m);
+  assume(getCoeffType(cf) == ID);
+
+  const ring R = cf->extRing;
+  assume( R != NULL );
+
+  fraction f = (fraction)m;
+
+  if( DEN(f) != NULL )
+    return 0;
+
+  return p_Var( NUM(f), R );
+}
+
+struct NTNumConverter
+{
+  static inline poly convert(const number& n)
+  {
+    // suitable for trans. ext. numbers that are fractions of polys
+    return NUM((fraction)n); // return the numerator
+  }
+};
+
+
+static void ntClearContent(ICoeffsEnumerator& numberCollectionEnumerator, number& c, const coeffs cf)
+{
+  assume(cf != NULL);
+  assume(getCoeffType(cf) == ID);
+  // all coeffs are given by fractions of polynomails over integers!!!
+  // without denominators!!!
+
+  const ring   R = cf->extRing;
+  assume(R != NULL);
+  const coeffs Q = R->cf;
+  assume(Q != NULL);
+  assume(nCoeff_is_Q(Q));
+
+
+  numberCollectionEnumerator.Reset();
+
+  if( !numberCollectionEnumerator.MoveNext() ) // empty zero polynomial?
+  {
+    c = ntInit(1, cf);
+    return;
+  }
+
+  // all coeffs are given by integers after returning from this routine
+
+  // part 1, collect product of all denominators /gcds
+  poly cand = NULL;
+
+  do
+  {
+    number &n = numberCollectionEnumerator.Current();
+
+    ntNormalize(n, cf);
+
+    fraction f = (fraction)n;
+
+    assume( f != NULL );
+
+    const poly den = DEN(f);
+
+    assume( den == NULL ); // ?? / 1 ?
+
+    const poly num = NUM(f);
+
+    if( cand == NULL )
+      cand = p_Copy(num, R);
+    else
+      cand = singclap_gcd(cand, p_Copy(num, R), R); // gcd(cand, num)
+
+    if( p_IsConstant(cand, R) )
+      break;
+  }
+  while( numberCollectionEnumerator.MoveNext() ) ;
+
+
+  // part2: all coeffs = all coeffs * cand
+  if( cand != NULL )
+  {
+  if( !p_IsConstant(cand, R) )
+  {
+    c = ntInit(cand, cf);
+    numberCollectionEnumerator.Reset();
+    while (numberCollectionEnumerator.MoveNext() )
+    {
+      number &n = numberCollectionEnumerator.Current();
+      const number t = ntDiv(n, c, cf); // TODO: rewrite!?
+      ntDelete(&n, cf);
+      n = t;
+    }
+  } // else NUM (result) = p_One(R);
+  else { p_Delete(&cand, R); cand = NULL; }
+  }
+
+  // Quick and dirty fix for constant content clearing: consider numerators???
+  CRecursivePolyCoeffsEnumerator<NTNumConverter> itr(numberCollectionEnumerator); // recursively treat the NUM(numbers) as polys!
+  number cc;
+
+  n_ClearContent(itr, cc, Q);
+  number g = ntInit(p_NSet(cc, R), cf);
+
+  if( cand != NULL )
+  {
+    number gg = ntMult(g, c, cf);
+    ntDelete(&g, cf);
+    ntDelete(&c, cf); c = gg;
+  } else
+    c = g;
+  ntTest(c);
+}
+
+static void ntClearDenominators(ICoeffsEnumerator& numberCollectionEnumerator, number& c, const coeffs cf)
+{
+  assume(cf != NULL);
+  assume(getCoeffType(cf) == ID); // both over Q(a) and Zp(a)!
+  // all coeffs are given by fractions of polynomails over integers!!!
+
+  numberCollectionEnumerator.Reset();
+
+  if( !numberCollectionEnumerator.MoveNext() ) // empty zero polynomial?
+  {
+    c = ntInit(1, cf);
+    return;
+  }
+
+  // all coeffs are given by integers after returning from this routine
+
+  // part 1, collect product of all denominators /gcds
+  poly cand = NULL;
+
+  const ring R = cf->extRing;
+  assume(R != NULL);
+
+  const coeffs Q = R->cf;
+  assume(Q != NULL);
+//  assume(nCoeff_is_Q(Q));
+
+  do
+  {
+    number &n = numberCollectionEnumerator.Current();
+
+    ntNormalize(n, cf);
+
+    fraction f = (fraction)ntGetDenom (n, cf);
+
+    assume( f != NULL );
+
+    const poly den = NUM(f);
+
+    if( den == NULL ) // ?? / 1 ?
+      continue;
+
+    if( cand == NULL )
+      cand = p_Copy(den, R);
+    else
+    {
+      // cand === LCM( cand, den )!!!!
+      // NOTE: maybe it's better to make the product and clearcontent afterwards!?
+      // TODO: move the following to factory?
+      poly gcd = singclap_gcd(p_Copy(cand, R), p_Copy(den, R), R); // gcd(cand, den) is monic no mater leading coeffs! :((((
+      if (nCoeff_is_Q (Q))
+      {
+        number LcGcd= n_SubringGcd (p_GetCoeff (cand, R), p_GetCoeff(den, R), Q);
+        gcd = p_Mult_nn(gcd, LcGcd, R);
+        n_Delete(&LcGcd,Q);
+      }
+//      assume( n_IsOne(pGetCoeff(gcd), Q) ); // TODO: this may be wrong...
+      cand = p_Mult_q(cand, p_Copy(den, R), R); // cand *= den
+      const poly t = singclap_pdivide( cand, gcd, R ); // cand' * den / gcd(cand', den)
+      p_Delete(&cand, R);
+      p_Delete(&gcd, R);
+      cand = t;
+    }
+  }
+  while( numberCollectionEnumerator.MoveNext() );
+
+  if( cand == NULL )
+  {
+    c = ntInit(1, cf);
+    return;
+  }
+
+  c = ntInit(cand, cf);
+
+  numberCollectionEnumerator.Reset();
+
+  number d = NULL;
+
+  while (numberCollectionEnumerator.MoveNext() )
+  {
+    number &n = numberCollectionEnumerator.Current();
+    number t = ntMult(n, c, cf); // TODO: rewrite!?
+    ntDelete(&n, cf);
+
+    ntNormalize(t, cf); // TODO: needed?
+    n = t;
+
+    fraction f = (fraction)t;
+    assume( f != NULL );
+
+    const poly den = DEN(f);
+
+    if( den != NULL ) // ?? / ?? ?
+    {
+      assume( p_IsConstant(den, R) );
+      assume( pNext(den) == NULL );
+
+      if( d == NULL )
+        d = n_Copy(pGetCoeff(den), Q);
+      else
+      {
+        number g = n_NormalizeHelper(d, pGetCoeff(den), Q);
+        n_Delete(&d, Q); d = g;
+      }
+    }
+  }
+
+  if( d != NULL )
+  {
+    numberCollectionEnumerator.Reset();
+    while (numberCollectionEnumerator.MoveNext() )
+    {
+      number &n = numberCollectionEnumerator.Current();
+      fraction f = (fraction)n;
+
+      assume( f != NULL );
+
+      const poly den = DEN(f);
+
+      if( den == NULL ) // ?? / 1 ?
+        NUM(f) = p_Mult_nn(NUM(f), d, R);
+      else
+      {
+        assume( p_IsConstant(den, R) );
+        assume( pNext(den) == NULL );
+
+        number ddd = n_Div(d, pGetCoeff(den), Q); // but be an integer now!!!
+        NUM(f) = p_Mult_nn(NUM(f), ddd, R);
+        n_Delete(&ddd, Q);
+
+        p_Delete(&DEN(f), R);
+        DEN(f) = NULL; // TODO: check if this is needed!?
+      }
+
+      assume( DEN(f) == NULL );
+    }
+
+    NUM(c) = p_Mult_nn(NUM(c), d, R);
+    n_Delete(&d, Q);
+  }
+
+
+  ntTest(c);
+}
+
+number  ntChineseRemainder(number *x, number *q,int rl, BOOLEAN sym,const coeffs cf)
+{
+  fraction result = (fraction)omAlloc0Bin(fractionObjectBin);
+  int i;
+
+  poly *P=(poly*)omAlloc(rl*sizeof(poly*));
+  number *X=(number *)omAlloc(rl*sizeof(number));
+
+  for(i=0;i<rl;i++) P[i]=p_Copy(NUM((fraction)(x[i])),cf->extRing);
+  NUM(result)=p_ChineseRemainder(P,X,q,rl,cf->extRing);
+
+  for(i=0;i<rl;i++)
+  {
+    P[i]=p_Copy(DEN((fraction)(x[i])),cf->extRing);
+    if (P[i]==NULL) P[i]=p_One(cf->extRing);
+  }
+  DEN(result)=p_ChineseRemainder(P,X,q,rl,cf->extRing);
+
+  omFreeSize(X,rl*sizeof(number));
+  omFreeSize(P,rl*sizeof(poly*));
+  if (p_IsConstant(DEN(result), ntRing)
+  && n_IsOne(pGetCoeff(DEN(result)), ntCoeffs))
+  {
+    p_Delete(&DEN(result),ntRing);
+  }
+  return ((number)result);
+}
+
+number  ntFarey(number p, number n, const coeffs cf)
+{
+  // n is really a bigint
+  fraction result = (fraction)omAlloc0Bin(fractionObjectBin);
+  NUM(result)=p_Farey(p_Copy(NUM((fraction)p),cf->extRing),n,cf->extRing);
+  DEN(result)=p_Farey(p_Copy(DEN((fraction)p),cf->extRing),n,cf->extRing);
+  return ((number)result);
+}
+
+BOOLEAN ntInitChar(coeffs cf, void * infoStruct)
+{
+
+  assume( infoStruct != NULL );
+
+  TransExtInfo *e = (TransExtInfo *)infoStruct;
+
+  assume( e->r                != NULL);      // extRing;
+  assume( e->r->cf            != NULL);      // extRing->cf;
+  assume( e->r->qideal == NULL );
+
+  assume( cf != NULL );
+  assume(getCoeffType(cf) == ID);                // coeff type;
+
+  ring R = e->r;
+  assume(R != NULL);
+
+  R->ref ++; // increase the ref.counter for the ground poly. ring!
+
+  cf->extRing           = R;
+  /* propagate characteristic up so that it becomes
+     directly accessible in cf: */
+  cf->ch = R->cf->ch;
+
+  cf->is_field=TRUE;
+  cf->is_domain=TRUE;
+  cf->rep=n_rep_rat_fct;
+
+  cf->factoryVarOffset = R->cf->factoryVarOffset + rVar(R);
+
+  cf->cfCoeffString = naCoeffString; // FIXME? TODO? // extern char* naCoeffString(const coeffs r);
+
+  cf->cfGreaterZero  = ntGreaterZero;
+  cf->cfGreater      = ntGreater;
+  cf->cfEqual        = ntEqual;
+  cf->cfIsZero       = ntIsZero;
+  cf->cfIsOne        = ntIsOne;
+  cf->cfIsMOne       = ntIsMOne;
+  cf->cfInit         = ntInit;
+  cf->cfFarey        = ntFarey;
+  cf->cfChineseRemainder = ntChineseRemainder;
+  cf->cfInt          = ntInt;
+  cf->cfInpNeg          = ntNeg;
+  cf->cfAdd          = ntAdd;
+  cf->cfSub          = ntSub;
+  cf->cfMult         = ntMult;
+  cf->cfDiv          = ntDiv;
+  cf->cfExactDiv     = ntDiv;
+  cf->cfPower        = ntPower;
+  cf->cfCopy         = ntCopy;
+  cf->cfWriteLong    = ntWriteLong;
+  cf->cfRead         = ntRead;
+  cf->cfNormalize    = ntNormalize;
+  cf->cfDelete       = ntDelete;
+  cf->cfSetMap       = ntSetMap;
+  cf->cfGetDenom     = ntGetDenom;
+  cf->cfGetNumerator = ntGetNumerator;
+  cf->cfRePart       = ntCopy;
+  cf->cfImPart       = ntImPart;
+  cf->cfCoeffWrite   = ntCoeffWrite;
+#ifdef LDEBUG
+  cf->cfDBTest       = ntDBTest;
+#endif
+  //cf->cfGcd          = ntGcd_dummy;
+  cf->cfSubringGcd   = ntGcd;
+  cf->cfNormalizeHelper = ntNormalizeHelper;
+  cf->cfSize         = ntSize;
+  cf->nCoeffIsEqual  = ntCoeffIsEqual;
+  cf->cfInvers       = ntInvers;
+  cf->cfKillChar     = ntKillChar;
+
+  if( rCanShortOut(ntRing) )
+    cf->cfWriteShort = ntWriteShort;
+  else
+    cf->cfWriteShort = ntWriteLong;
+
+  cf->convFactoryNSingN =ntConvFactoryNSingN;
+  cf->convSingNFactoryN =ntConvSingNFactoryN;
+  cf->cfParDeg = ntParDeg;
+
+  cf->iNumberOfParameters = rVar(R);
+  cf->pParameterNames = (const char**)R->names;
+  cf->cfParameter = ntParameter;
+  cf->has_simple_Inverse= FALSE;
+  /* cf->has_simple_Alloc= FALSE; */
+
+
+  if( nCoeff_is_Q(R->cf) )
+    cf->cfClearContent = ntClearContent;
+
+  cf->cfClearDenominators = ntClearDenominators;
+
+  return FALSE;
+}
+
+template class CRecursivePolyCoeffsEnumerator<NTNumConverter>;
+template class IEnumerator<snumber*>;
diff --git a/libpolys/polys/ext_fields/transext.h b/libpolys/polys/ext_fields/transext.h
new file mode 100644
index 0000000..675c810
--- /dev/null
+++ b/libpolys/polys/ext_fields/transext.h
@@ -0,0 +1,137 @@
+#ifndef TRANSEXT_H
+#define TRANSEXT_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: numbers in a rational function field K(t_1, .., t_s) with
+*           transcendental variables t_1, ..., t_s, where s >= 1.
+*           Denoting the implemented coeffs object by cf, then these numbers
+*           are represented as quotients of polynomials living in the
+*           polynomial ring K[t_1, .., t_s] represented by cf->extring.
+*
+*           An element of K(t_1, .., t_s) may have numerous representations,
+*           due to the possibility of common polynomial factors in the
+*           numerator and denominator. This problem is handled by a
+*           cancellation heuristic: Each number "knows" its complexity
+*           which is 0 if and only if common factors have definitely been
+*           cancelled, and some positive integer otherwise.
+*           Each arithmetic operation of two numbers with complexities c1
+*           and c2 will result in a number of complexity c1 + c2 + some
+*           penalty (specific for each arithmetic operation; see constants
+*           in the *.h file). Whenever the resulting complexity exceeds a
+*           certain threshold (see constant in the *.h file), then the
+*           cancellation heuristic will call 'factory' to compute the gcd
+*           and cancel it out in the given number. (This definite cancel-
+*           lation will also be performed at the beginning of ntWrite,
+*           ensuring that any output is free of common factors.
+*           For the special case of K = Q (i.e., when computing over the
+*           rationals), this definite cancellation procedure will also take
+*           care of nested fractions: If there are fractional coefficients
+*           in the numerator or denominator of a number, then this number
+*           is being replaced by a quotient of two polynomials over Z, or
+*           - if the denominator is a constant - by a polynomial over Q.
+*/
+
+#include <coeffs/coeffs.h>
+
+struct ip_sring;
+typedef struct ip_sring * ring;
+
+
+// the following is only needed _here_ due to its use in clapsing.cc!
+#ifdef TRANSEXT_PRIVATES
+struct spolyrec; typedef struct spolyrec polyrec; typedef polyrec * poly;
+
+
+/** a number in K(t_1, .., t_s) is represented by either NULL
+   (representing the zero number), or a pointer to a fraction which contains
+   the numerator polynomial and the denominator polynomial in K[t_1, .., t_s];
+   if the denominator is 1, the member 'denominator' is NULL;
+   as a consequence of the above we get: if some number n is not NULL, then
+   n->numerator cannot be NULL;
+   The member 'complexity' attempts to capture the complexity of any given
+   number n, i.e., starting with a bunch of numbers n_i that have their gcd's
+   cancelled out, n may be constructed from the n_i's by using field
+   arithmetics (+, -, *, /). If we never cancel out gcd's during this process,
+   n will become rather complex. The larger the attribute 'complexity' of n
+   is, the more likely it is that n contains some non-trivial gcd. Thus, this
+   attribute will be used by a heuristic method to cancel out gcd's from time
+   to time. (This heuristic may be set up such that cancellation can be
+   enforced after each arithmetic operation, or such that it will never take
+   place.) Moreover, the 'complexity' of n is zero iff the gcd in n (that is,
+     the gcd of its numerator and denominator) is trivial.
+ */
+struct fractionObject
+{
+  poly numerator;
+  poly denominator;
+  int complexity;
+};
+
+typedef struct fractionObject * fraction;
+
+
+#define NUM(f) (((fraction)f)->numerator)
+#define DEN(f) (((fraction)f)->denominator)
+
+/* some useful accessors for fractions: */
+#define IS0(f) (f == NULL)
+/**< TRUE iff n represents 0 in K(t_1, .., t_s) */
+
+#define DENIS1(f) (DEN(f) == NULL)
+/**< TRUE iff den. represents 1 */
+
+
+number ntInit(poly p, const coeffs cf);
+
+#endif
+
+
+/// struct for passing initialization parameters to naInitChar
+typedef struct { ring r; } TransExtInfo;
+
+/// Get a mapping function from src into the domain of this type (n_transExt)
+nMapFunc ntSetMap(const coeffs src, const coeffs dst);
+
+/// Initialize the coeffs object
+BOOLEAN  ntInitChar(coeffs cf, void* infoStruct);
+
+number ntDiff(number a, number d, const coeffs cf);
+
+/* Private hidden interface
+BOOLEAN  ntGreaterZero(number a, const coeffs cf);
+BOOLEAN  ntGreater(number a, number b, const coeffs cf);
+BOOLEAN  ntEqual(number a, number b, const coeffs cf);
+BOOLEAN  ntIsOne(number a, const coeffs cf);
+BOOLEAN  ntIsMOne(number a, const coeffs cf);
+BOOLEAN  ntIsZero(number a, const coeffs cf);
+number   ntInit(long i, const coeffs cf);
+int      ntInt(number &a, const coeffs cf);
+number   ntNeg(number a, const coeffs cf);
+number   ntInvers(number a, const coeffs cf);
+number   ntAdd(number a, number b, const coeffs cf);
+number   ntSub(number a, number b, const coeffs cf);
+number   ntMult(number a, number b, const coeffs cf);
+number   ntDiv(number a, number b, const coeffs cf);
+void     ntPower(number a, int exp, number *b, const coeffs cf);
+number   ntCopy(number a, const coeffs cf);
+void     ntWrite(number &a, const coeffs cf);
+number   ntRePart(number a, const coeffs cf);
+number   ntImPart(number a, const coeffs cf);
+number   ntGetDenom(number &a, const coeffs cf);
+number   ntGetNumerator(number &a, const coeffs cf);
+number   ntGcd(number a, number b, const coeffs cf);
+number   ntLcm(number a, number b, const coeffs cf);
+int      ntSize(number a, const coeffs cf);
+void     ntDelete(number * a, const coeffs cf);
+void     ntCoeffWrite(const coeffs cf, BOOLEAN details);
+const char * ntRead(const char *s, number *a, const coeffs cf);
+static BOOLEAN ntCoeffIsEqual(const coeffs cf, n_coeffType n, void * param);
+*/
+
+/// if m == var(i)/1 => return i,
+int ntIsParam(number, const coeffs);
+
+#endif
+/* TRANSEXT_H */
diff --git a/libpolys/polys/flintconv.cc b/libpolys/polys/flintconv.cc
new file mode 100644
index 0000000..6d5cf56
--- /dev/null
+++ b/libpolys/polys/flintconv.cc
@@ -0,0 +1,184 @@
+// emacs edit mode for this file is -*- C++ -*-
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: convert data between Singular and Flint
+*/
+
+
+
+#include <misc/auxiliary.h>
+#include "flintconv.h"
+
+#ifdef FLINT_VER_2_4_5
+#include <coeffs/coeffs.h>
+#include <polys/monomials/p_polys.h>
+
+#include <omalloc/omalloc.h>
+// #include <coeffs/longrat.h>
+// #include <coeffs/modulop.h>
+#include <polys/sbuckets.h>
+#include <polys/clapconv.h>
+
+#include "simpleideals.h"
+
+
+#ifdef HAVE_FLINT
+int convFlintISingI (fmpz_t f)
+{
+  int res;
+  res = fmpz_get_si(f);
+  return res;
+}
+
+void convSingIFlintI(fmpz_t f, int p)
+{
+  fmpz_init(f);
+  fmpz_set_si(f,p);
+  return;
+}
+
+void convFlintNSingN (mpz_t z, fmpz_t f)
+{
+  mpz_init(z);
+  fmpz_get_mpz(z,f);
+}
+
+void convSingNFlintN(fmpz_t f, mpz_t z)
+{
+  fmpz_init(f);
+  fmpz_set_mpz(f,z);
+}
+
+
+bigintmat* singflint_LLL(bigintmat*  m, bigintmat* T)
+{
+  int r=m->rows();
+  int c=m->cols();
+  bigintmat* res=new bigintmat(r,c,m->basecoeffs());
+  fmpz_mat_t M, Transf;
+  fmpz_mat_init(M, r, c);
+  if(T != NULL)
+  {
+    fmpz_mat_init(Transf, T->rows(), T->rows());
+  }
+  fmpz_t dummy;
+  mpz_t n;
+  int i,j;
+  for(i=r;i>0;i--)
+  {
+    for(j=c;j>0;j--)
+    {
+      n_MPZ(n, BIMATELEM(*m, i, j),m->basecoeffs());
+      convSingNFlintN(dummy,n);
+      mpz_clear(n);
+      fmpz_set(fmpz_mat_entry(M, i-1, j-1), dummy);
+      fmpz_clear(dummy);
+    }
+  }
+  if(T != NULL)
+  {
+    for(i=T->rows();i>0;i--)
+    {
+      for(j=T->rows();j>0;j--)
+      {
+        n_MPZ(n, BIMATELEM(*T, i, j),T->basecoeffs());
+        convSingNFlintN(dummy,n);
+        mpz_clear(n);
+        fmpz_set(fmpz_mat_entry(Transf, i-1, j-1), dummy);
+        fmpz_clear(dummy);
+      }
+    }
+  }
+  fmpz_lll_t fl;
+  fmpz_lll_context_init_default(fl);
+  if(T != NULL)
+    fmpz_lll(M, Transf, fl);
+  else
+    fmpz_lll(M, NULL, fl);
+  for(i=r;i>0;i--)
+  {
+    for(j=c;j>0;j--)
+    {
+      convFlintNSingN(n, fmpz_mat_entry(M, i-1, j-1));
+      n_Delete(&(BIMATELEM(*res,i,j)),res->basecoeffs());
+      BIMATELEM(*res,i,j)=n_InitMPZ(n,res->basecoeffs());
+      mpz_clear(n);
+    }
+  }
+  if(T != NULL)
+  {
+    for(i=T->rows();i>0;i--)
+    {
+      for(j=T->cols();j>0;j--)
+      {
+        convFlintNSingN(n, fmpz_mat_entry(Transf, i-1, j-1));
+        n_Delete(&(BIMATELEM(*T,i,j)),T->basecoeffs());
+        BIMATELEM(*T,i,j)=n_InitMPZ(n,T->basecoeffs());
+        mpz_clear(n);
+      }
+    }
+  }
+  return res;
+}
+
+intvec* singflint_LLL(intvec*  m, intvec* T)
+{
+  int r=m->rows();
+  int c=m->cols();
+  intvec* res = new intvec(r,c,(int)0);
+  fmpz_mat_t M,Transf;
+  fmpz_mat_init(M, r, c);
+  if(T != NULL)
+    fmpz_mat_init(Transf, r, r);
+  fmpz_t dummy;
+  int i,j;
+  for(i=r;i>0;i--)
+  {
+    for(j=c;j>0;j--)
+    {
+      convSingIFlintI(dummy,IMATELEM(*m,i,j));
+      fmpz_set(fmpz_mat_entry(M, i-1, j-1), dummy);
+      fmpz_clear(dummy);
+    }
+  }
+  if(T != NULL)
+  {
+    for(i=T->rows();i>0;i--)
+    {
+      for(j=T->rows();j>0;j--)
+      {
+        convSingIFlintI(dummy,IMATELEM(*T,i,j));
+        fmpz_set(fmpz_mat_entry(Transf, i-1, j-1), dummy);
+        fmpz_clear(dummy);
+      }
+    }
+  }
+  fmpz_lll_t fl;
+  fmpz_lll_context_init_default(fl);
+  if(T != NULL)
+    fmpz_lll(M, Transf, fl);
+  else
+    fmpz_lll(M, NULL, fl);
+  for(i=r;i>0;i--)
+  {
+    for(j=c;j>0;j--)
+    {
+      IMATELEM(*res,i,j)=convFlintISingI(fmpz_mat_entry(M, i-1, j-1));
+    }
+  }
+  if(T != NULL)
+  {
+    for(i=Transf->r;i>0;i--)
+    {
+      for(j=Transf->r;j>0;j--)
+      {
+        IMATELEM(*T,i,j)=convFlintISingI(fmpz_mat_entry(Transf, i-1, j-1));
+      }
+    }
+  }
+  return res;
+}
+#endif
+#endif
diff --git a/libpolys/polys/flintconv.h b/libpolys/polys/flintconv.h
new file mode 100644
index 0000000..1e0a125
--- /dev/null
+++ b/libpolys/polys/flintconv.h
@@ -0,0 +1,54 @@
+// emacs edit mode for this file is -*- C++ -*-
+#ifndef LIBPOLYS_POLYS_FLINTCONV_H
+#define LIBPOLYS_POLYS_FLINTCONV_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: convert data between Singular and Flint
+*/
+/** @file flintconv.h
+ *
+ * This file is work in progress and currently not part of the official Singular
+ *
+ * @note the code is garded by the undefined macro FLINT_VER_2_4_5
+ * In its current form it will never become an official part.
+ * (conversion routines may be moved to other files/directories, etc.)
+ *
+ * ABSTRACT: Conversion to/from FLINT, and access to some FLINT-routines
+ *
+ * REQUIREMENTS:
+ * - agreement about the interface to LLL
+ * - SINGULAR_4_1
+ * - FLINT providing LLL
+ * (none of the above is currently true, but all of them is required)
+ *
+ **/
+
+//  Have to define this when this code shall be used:
+//#define FLINT_VER_2_4_5
+#ifdef FLINT_VER_2_4_5
+#include <polys/matpol.h>
+#include <coeffs/bigintmat.h>
+// #include <polys/monomials/ring.h>
+
+
+#ifdef HAVE_FLINT
+#include <flint/flint.h>
+#include <flint/fmpz.h>
+#include <flint/fmpq.h>
+#include <flint/fmpz_poly.h>
+#include <flint/fmpz_poly_mat.h>
+#include <flint/fmpz_lll.h>
+
+int convFlintISingI (fmpz_t f);
+void convSingIFlintI(fmpz_t f, int p);
+void convFlintNSingN (mpz_t z, fmpz_t f);
+void convSingNFlintN(fmpz_t f, mpz_t z);
+bigintmat*  singflint_LLL(bigintmat* A, bigintmat* T);
+intvec* singflint_LLL(intvec* A, intvec* T);
+#endif
+
+#endif
+#endif
+// LIBPOLYS_POLYS_FLINTCONV_H
diff --git a/libpolys/polys/kbuckets.cc b/libpolys/polys/kbuckets.cc
new file mode 100644
index 0000000..6a8ce47
--- /dev/null
+++ b/libpolys/polys/kbuckets.cc
@@ -0,0 +1,1341 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+//#include <kernel/mod2.h>
+
+
+
+
+#include <omalloc/omalloc.h>
+#include <misc/auxiliary.h>
+
+#include <polys/monomials/p_polys.h>
+//#include <kernel/pShallowCopyDelete.h>
+#include <coeffs/coeffs.h>
+#include <polys/monomials/ring.h>
+//#include <kernel/p_Procs.h>
+//#include <kernel/GBEngine/kutil.h>
+#include <polys/kbuckets.h>
+
+// #include <polys/operations/pShallowCopyDelete.h>
+
+
+#ifdef HAVE_COEF_BUCKETS
+#define USE_COEF_BUCKETS
+#endif
+
+#ifdef USE_COEF_BUCKETS
+#ifdef HAVE_RINGS_OLD
+#define MULTIPLY_BUCKET(B,I) do                                        \
+  { if (B->coef[I]!=NULL)                                              \
+    {                                                                  \
+      assume(p_IsConstant(B->Coef[i],B->bucket->ring));           \
+      B->buckets[I]=p_Mult_q(B->buckets[I],B->coef[I],B->bucket_ring); \
+      B->coef[I]=NULL;                                                 \
+    }                                                                  \
+  } while(0)                                                           \
+    if (rField_is_Ring(B->bucket_ring)) B->buckets_length[i] = pLength(B->buckets[i]);
+#else
+#define MULTIPLY_BUCKET(B,I) do                                        \
+  { if (B->coef[I]!=NULL)                                              \
+    {                                                                  \
+      B->buckets[I]=p_Mult_q(B->buckets[I],B->coef[I],B->bucket_ring); \
+      B->coef[I]=NULL;                                                 \
+    }                                                                  \
+  } while(0)
+#endif
+#else
+#define MULTIPLY_BUCKET(B,I)
+#endif
+static omBin kBucket_bin = omGetSpecBin(sizeof(kBucket));
+#ifdef USE_COEF_BUCKETS
+static int coef_start=1;
+#endif
+//////////////////////////////////////////////////////////////////////////
+///
+/// Some internal stuff
+///
+
+// returns ceil(log_4(l))
+inline unsigned int pLogLength(unsigned int l)
+{
+  unsigned int i = 0;
+
+  if (l == 0) return 0;
+  l--;
+#ifdef BUCKET_TWO_BASE
+  while ((l = (l >> 1))) i++;
+#else
+  while ((l = (l >> 2))) i++;
+#endif
+  return i+1;
+}
+
+// returns ceil(log_4(pLength(p)))
+inline unsigned int pLogLength(poly p)
+{
+  return pLogLength((unsigned int) pLength(p));
+}
+
+#ifdef KDEBUG
+
+#ifndef HAVE_PSEUDO_BUCKETS
+BOOLEAN kbTest_i(kBucket_pt bucket, int i)
+{//sBucketSortMerge
+  #ifdef USE_COEF_BUCKETS
+  assume(bucket->coef[0]==NULL);
+  if ((bucket->coef[i]!=NULL) && (bucket->buckets[i]==NULL))
+  {
+    dReportError("Bucket %d coef not NULL", i);
+  }
+  if (bucket->coef[i]!=NULL)
+  {
+    assume(bucket->buckets[i]!=NULL);
+    p_Test(bucket->coef[i],bucket->bucket_ring);
+  }
+  #endif
+  pFalseReturn(p_Test(bucket->buckets[i], bucket->bucket_ring));
+  if (bucket->buckets_length[i] != pLength(bucket->buckets[i]))
+  {
+    dReportError("Bucket %d lengths difference should:%d has:%d",
+                 i, bucket->buckets_length[i], pLength(bucket->buckets[i]));
+  }
+  else if (i > 0 && (int) pLogLength(bucket->buckets_length[i]) > i)
+  {
+    dReportError("Bucket %d too long %d",
+                 i, bucket->buckets_length[i]);
+  }
+  if (i==0 && bucket->buckets_length[0] > 1)
+  {
+    dReportError("Bucket 0 too long");
+  }
+  return TRUE;
+}
+
+
+BOOLEAN kbTest(kBucket_pt bucket)
+{
+  #ifdef HAVE_COEF_BUCKETS
+  assume(bucket->coef[0]==NULL);
+  #endif
+  int i;
+  poly lm = bucket->buckets[0];
+
+  omCheckAddrBin(bucket, kBucket_bin);
+  assume(bucket->buckets_used <= MAX_BUCKET);
+  if (! kbTest_i(bucket, 0)) return FALSE;
+  for (i=1; i<= (int) bucket->buckets_used; i++)
+  {
+    if (!kbTest_i(bucket, i)) return FALSE;
+    if (lm != NULL &&  bucket->buckets[i] != NULL
+        && p_LmCmp(lm, bucket->buckets[i], bucket->bucket_ring) != 1)
+    {
+      dReportError("Bucket %d larger or equal than lm", i);
+      if (p_LmCmp(lm, bucket->buckets[i], bucket->bucket_ring) ==0)
+        dReportError("Bucket %d equal to lm", i);
+      return FALSE;
+    }
+    if (!p_Test(bucket->buckets[i],bucket->bucket_ring))
+    {
+      dReportError("Bucket %d is not =0(4)", i);
+      return FALSE;
+    }
+  }
+
+  for (; i<=MAX_BUCKET; i++)
+  {
+    if (bucket->buckets[i] != NULL || bucket->buckets_length[i] != 0)
+    {
+      dReportError("Bucket %d not zero", i);
+      return FALSE;
+    }
+  }
+  for(i=0;i<=MAX_BUCKET;i++)
+  {
+    if (bucket->buckets[i]!=NULL)
+    {
+      int j;
+      for(j=i+1;j<=MAX_BUCKET;j++)
+      {
+        if (bucket->buckets[j]==bucket->buckets[i])
+        {
+          dReportError("Bucket %d %d equal", i,j);
+          return FALSE;
+        }
+      }
+    }
+    #ifdef HAVE_COEF_BUCKETS
+    if (bucket->coef[i]!=NULL)
+    {
+      int j;
+      for(j=i+1;j<=MAX_BUCKET;j++)
+      {
+        if (bucket->coef[j]==bucket->coef[i])
+        {
+          dReportError("internal coef %d %d equal", i,j);
+          return FALSE;
+        }
+      }
+    }
+    #endif
+  }
+  return TRUE;
+}
+
+#else // HAVE_PSEUDO_BUCKETS
+BOOLEAN kbTest(kBucket_pt bucket)
+{
+  return TRUE;
+}
+#endif // ! HAVE_PSEUDO_BUCKETS
+#endif // KDEBUG
+
+//////////////////////////////////////////////////////////////////////////
+///
+/// Creation/Destruction of buckets
+///
+
+kBucket_pt kBucketCreate(ring bucket_ring)
+{
+  assume(bucket_ring != NULL);
+  kBucket_pt bucket = (kBucket_pt) omAlloc0Bin(kBucket_bin);
+  bucket->bucket_ring = bucket_ring;
+  return bucket;
+}
+void kBucketDestroy(kBucket_pt *bucket_pt)
+{
+  omFreeBin(*bucket_pt, kBucket_bin);
+  *bucket_pt = NULL;
+}
+
+
+void kBucketDeleteAndDestroy(kBucket_pt *bucket_pt)
+{
+  kBucket_pt bucket = *bucket_pt;
+  kbTest(bucket);
+  int i;
+  for (i=0; i<= bucket->buckets_used; i++)
+  {
+
+    if (bucket->buckets[i] != NULL)
+    {
+      p_Delete(&(bucket->buckets[i]), bucket->bucket_ring);
+#ifdef USE_COEF_BUCKETS
+      if (bucket->coef[i]!=NULL)
+        p_Delete(&(bucket->coef[i]), bucket->bucket_ring);
+#endif
+    }
+  }
+  omFreeBin(bucket, kBucket_bin);
+  *bucket_pt = NULL;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Convertion from/to Bpolys
+//
+#ifndef HAVE_PSEUDO_BUCKETS
+
+inline void kBucketMergeLm(kBucket_pt bucket)
+{
+  kbTest(bucket);
+  if (bucket->buckets[0] != NULL)
+  {
+    poly lm = bucket->buckets[0];
+    int i = 1;
+#ifdef BUCKET_TWO_BASE
+    int l = 2;
+    while ( bucket->buckets_length[i] >= l)
+    {
+      i++;
+      l = l << 1;
+    }
+#else
+    int l = 4;
+    while ( bucket->buckets_length[i] >= l)
+    {
+      i++;
+      l = l << 2;
+    }
+#endif
+#ifndef USE_COEF_BUCKETS
+    MULTIPLY_BUCKET(bucket,i);
+    pNext(lm) = bucket->buckets[i];
+    bucket->buckets[i] = lm;
+    bucket->buckets_length[i]++;
+    assume(i <= bucket->buckets_used+1);
+    if (i > bucket->buckets_used)  bucket->buckets_used = i;
+    bucket->buckets[0] = NULL;
+    bucket->buckets_length[0] = 0;
+    kbTest(bucket);
+#else
+    if (i > bucket->buckets_used)  bucket->buckets_used = i;
+    assume(i!=0);
+    if (bucket->buckets[i]!=NULL)
+    {
+       MULTIPLY_BUCKET(bucket,i);
+       pNext(lm) = bucket->buckets[i];
+       bucket->buckets[i] = lm;
+       bucket->buckets_length[i]++;
+       assume(i <= bucket->buckets_used+1);
+    }
+    else
+    {
+      #if 1
+       assume(bucket->buckets[i]==NULL);
+       assume(bucket->coef[0]==NULL);
+       assume(pLength(lm)==1);
+       assume(pNext(lm)==NULL);
+       number coef=p_GetCoeff(lm,bucket->bucket_ring);
+       //WARNING: not thread_safe
+       p_SetCoeff0(lm, n_Init(1,bucket->bucket_ring), bucket->bucket_ring);
+       bucket->buckets[i]=lm;
+       bucket->buckets_length[i]=1;
+       bucket->coef[i]=p_NSet(n_Copy(coef,bucket->bucket_ring),bucket->bucket_ring);
+
+       bucket->buckets[i]=lm;
+       bucket->buckets_length[i]=1;
+      #else
+       MULTIPLY_BUCKET(bucket,i);
+       pNext(lm) = bucket->buckets[i];
+       bucket->buckets[i] = lm;
+       bucket->buckets_length[i]++;
+       assume(i <= bucket->buckets_used+1);
+      #endif
+    }
+    bucket->buckets[0]=NULL;
+    bucket->buckets_length[0] = 0;
+    bucket->coef[0]=NULL;
+    kbTest(bucket);
+    #endif
+  }
+
+}
+
+BOOLEAN kBucketIsCleared(kBucket_pt bucket)
+{
+  int i;
+
+  for (i = 0;i<=MAX_BUCKET;i++)
+  {
+    if (bucket->buckets[i] != NULL) return FALSE;
+    #ifdef HAVE_COEF_BUCKETS
+    if (bucket->coef[i] != NULL) return FALSE;
+    #endif
+    if (bucket->buckets_length[i] != 0) return FALSE;
+  }
+  return TRUE;
+}
+
+void kBucketInit(kBucket_pt bucket, poly lm, int length)
+{
+  //assume(false);
+  assume(bucket != NULL);
+  assume(length <= 0 || length == pLength(lm));
+  assume(kBucketIsCleared(bucket));
+
+  if (lm == NULL) return;
+
+  if (length <= 0)
+    length = pLength(lm);
+
+  bucket->buckets[0] = lm;
+  #ifdef HAVE_COEF_BUCKETS
+  assume(bucket->coef[0]==NULL);
+  #endif
+  #ifdef USE_COEF_BUCKETS
+  bucket->coef[0]=NULL;
+  #endif
+  if (lm!=NULL)
+    bucket->buckets_length[0] = 1;
+  else
+    bucket->buckets_length[0]= 0;
+  if (length > 1)
+  {
+    unsigned int i = pLogLength(length-1);
+    bucket->buckets[i] = pNext(lm);
+    pNext(lm) = NULL;
+    bucket->buckets_length[i] = length-1;
+    bucket->buckets_used = i;
+  }
+  else
+  {
+    bucket->buckets_used = 0;
+  }
+}
+
+int kBucketCanonicalize(kBucket_pt bucket)
+{
+  assume(bucket->buckets_used<=MAX_BUCKET);
+  MULTIPLY_BUCKET(bucket,1);
+  kbTest(bucket);
+  poly p = bucket->buckets[1];
+  poly lm;
+  int pl = bucket->buckets_length[1];//, i;
+  int i;
+  bucket->buckets[1] = NULL;
+  bucket->buckets_length[1] = 0;
+  #ifdef USE_COEF_BUCKETS
+    assume(bucket->coef[1]==NULL);
+  #endif
+  ring r=bucket->bucket_ring;
+
+
+  for (i=1; i<=bucket->buckets_used; i++)
+  {
+  #ifdef USE_COEF_BUCKETS
+    if (bucket->coef[i]!=NULL)
+    {
+      assume(bucket->buckets[i]!=NULL);
+      p = p_Plus_mm_Mult_qq(p, bucket->coef[i], bucket->buckets[i],
+                 pl, bucket->buckets_length[i], r);
+      p_Delete(&bucket->coef[i],r);
+      p_Delete(&bucket->buckets[i],r);
+    }
+    else
+    p = p_Add_q(p, bucket->buckets[i],
+                 pl, bucket->buckets_length[i], r);
+  #else
+    p = p_Add_q(p, bucket->buckets[i],
+                 pl, bucket->buckets_length[i], r);
+  #endif
+    if (i==1) continue;
+    bucket->buckets[i] = NULL;
+    bucket->buckets_length[i] = 0;
+  }
+  #ifdef HAVE_COEF_BUCKETS
+  assume(bucket->coef[0]==NULL);
+  #endif
+  lm = bucket->buckets[0];
+  if (lm != NULL)
+  {
+    pNext(lm) = p;
+    p = lm;
+    pl++;
+    bucket->buckets[0] = NULL;
+    bucket->buckets_length[0] = 0;
+  }
+  if (pl > 0)
+  {
+    i = pLogLength(pl);
+    bucket->buckets[i] = p;
+    bucket->buckets_length[i] = pl;
+  }
+  else
+  {
+    i = 0;
+  }
+  bucket->buckets_used = i;
+  assume(bucket->buckets_used <= MAX_BUCKET);
+  #ifdef USE_COEF_BUCKETS
+    assume(bucket->coef[0]==NULL);
+    assume(bucket->coef[i]==NULL);
+  #endif
+  assume(pLength(p) == (int) pl);
+  //if (TEST_OPT_PROT) { Print("C(%d)",pl); }
+  kbTest(bucket);
+  return i;
+}
+
+void kBucketClear(kBucket_pt bucket, poly *p, int *length)
+{
+  int i = kBucketCanonicalize(bucket);
+  if (i > 0)
+  {
+  #ifdef USE_COEF_BUCKETS
+    MULTIPLY_BUCKET(bucket,i);
+    //bucket->coef[i]=NULL;
+  #endif
+    *p = bucket->buckets[i];
+    *length = bucket->buckets_length[i];
+    bucket->buckets[i] = NULL;
+    bucket->buckets_length[i] = 0;
+    bucket->buckets_used = 0;
+
+  }
+  else
+  {
+    *p = NULL;
+    *length = 0;
+  }
+}
+
+void kBucketSetLm(kBucket_pt bucket, poly lm)
+{
+  kBucketMergeLm(bucket);
+  pNext(lm) = NULL;
+  bucket->buckets[0] = lm;
+  bucket->buckets_length[0] = 1;
+}
+
+#else // HAVE_PSEUDO_BUCKETS
+
+void kBucketInit(kBucket_pt bucket, poly lm, int length)
+{
+  int i;
+
+  assume(bucket != NULL);
+  assume(length <= 0 || length == pLength(lm));
+
+  bucket->p = lm;
+  if (length <= 0) bucket->l = pLength(lm);
+  else bucket->l = length;
+
+}
+
+const poly kBucketGetLm(kBucket_pt bucket)
+{
+  return bucket->p;
+}
+
+poly kBucketExtractLm(kBucket_pt bucket)
+{
+  poly lm = bucket->p;
+  assume(pLength(bucket->p) == bucket->l);
+  pIter(bucket->p);
+  (bucket->l)--;
+  pNext(lm) = NULL;
+  return lm;
+}
+
+void kBucketClear(kBucket_pt bucket, poly *p, int *length)
+{
+  assume(pLength(bucket->p) == bucket->l);
+  *p = bucket->p;
+  *length = bucket->l;
+  bucket->p = NULL;
+  bucket->l = 0;
+}
+
+#endif // ! HAVE_PSEUDO_BUCKETS
+//////////////////////////////////////////////////////////////////////////
+///
+/// For changing the ring of the Bpoly to new_tailBin
+///
+void kBucketShallowCopyDelete(kBucket_pt bucket,
+                              ring new_tailRing, omBin new_tailBin,
+                              pShallowCopyDeleteProc p_shallow_copy_delete)
+{
+#ifndef HAVE_PSEUDO_BUCKETS
+  int i;
+
+  kBucketCanonicalize(bucket);
+  for (i=0; i<= bucket->buckets_used; i++)
+    if (bucket->buckets[i] != NULL)
+    {
+      MULTIPLY_BUCKET(bucket,i);
+      bucket->buckets[i] = p_shallow_copy_delete(bucket->buckets[i],
+                                                 bucket->bucket_ring,
+                                                 new_tailRing,
+                                                 new_tailBin);
+    }
+#else
+  bucket->p = p_shallow_copy_delete(p,
+                                    bucket_ring,
+                                    new_tailRing,
+                                    new_tailBin);
+#endif
+  bucket->bucket_ring = new_tailRing;
+}
+
+//////////////////////////////////////////////////////////////////////////
+///
+/// Bucket number i from bucket is out of length sync, resync
+///
+void kBucketAdjust(kBucket_pt bucket, int i) {
+
+  MULTIPLY_BUCKET(bucket,i);
+
+  int l1 = bucket->buckets_length[i];
+  poly p1 = bucket->buckets[i];
+  bucket->buckets[i] = NULL;
+  bucket->buckets_length[i] = 0;
+  i = pLogLength(l1);
+
+  while (bucket->buckets[i] != NULL)
+  {
+    //kbTest(bucket);
+    MULTIPLY_BUCKET(bucket,i);
+    p1 = p_Add_q(p1, bucket->buckets[i],
+                 l1, bucket->buckets_length[i], bucket->bucket_ring);
+    bucket->buckets[i] = NULL;
+    bucket->buckets_length[i] = 0;
+    i = pLogLength(l1);
+  }
+
+  bucket->buckets[i] = p1;
+  bucket->buckets_length[i]=l1;
+  if (i >= bucket->buckets_used)
+    bucket->buckets_used = i;
+  else
+    kBucketAdjustBucketsUsed(bucket);
+}
+
+//////////////////////////////////////////////////////////////////////////
+///
+/// Multiply Bucket by number ,i.e. Bpoly == n*Bpoly
+///
+void kBucket_Mult_n(kBucket_pt bucket, number n)
+{
+#ifndef HAVE_PSEUDO_BUCKETS
+  kbTest(bucket);
+  ring r=bucket->bucket_ring;
+  int i;
+
+  for (i=0; i<= bucket->buckets_used; i++)
+  {
+    if (bucket->buckets[i] != NULL)
+    {
+#ifdef USE_COEF_BUCKETS
+      if (i<coef_start)
+        bucket->buckets[i] = p_Mult_nn(bucket->buckets[i], n, r);
+#ifdef HAVE_RINGS
+        /* Frank Seelisch on March 11, 2010:
+           This looks a bit strange: The following "if" is indented
+           like the previous line of code. But coded as it is,
+           it should actually be two spaces less indented.
+           Question: Should the following "if" also only be
+           performed when "(i<coef_start)" is true?
+           For the time being, I leave it as it is. */
+        if (rField_is_Ring(r) && !(rField_is_Domain(r)))
+        {
+          bucket->buckets_length[i] = pLength(bucket->buckets[i]);
+          kBucketAdjust(bucket, i);
+        }
+#endif
+      else
+      if (bucket->coef[i]!=NULL)
+      {
+        bucket->coef[i] = p_Mult_nn(bucket->coef[i],n,r);
+      }
+      else
+      {
+        bucket->coef[i] = p_NSet(n_Copy(n,r),r);
+      }
+#else
+      bucket->buckets[i] = p_Mult_nn(bucket->buckets[i], n, r);
+#ifdef HAVE_RINGS
+      if (rField_is_Ring(r) && !(rField_is_Domain(r)))
+      {
+        bucket->buckets_length[i] = pLength(bucket->buckets[i]);
+        kBucketAdjust(bucket, i);
+      }
+#endif
+#endif
+    }
+  }
+  kbTest(bucket);
+#else
+  bucket->p = p_Mult_nn(bucket->p, n, bucket->bucket_ring);
+#endif
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+///
+/// Add to Bucket a poly ,i.e. Bpoly == q+Bpoly
+///
+void kBucket_Add_q(kBucket_pt bucket, poly q, int *l)
+{
+  if (q == NULL) return;
+  assume(*l <= 0 || pLength(q) == *l);
+
+  int i, l1;
+  ring r = bucket->bucket_ring;
+
+  if (*l <= 0)
+  {
+    l1 = pLength(q);
+    *l = l1;
+  }
+  else
+    l1 = *l;
+
+  kBucketMergeLm(bucket);
+  kbTest(bucket);
+  i = pLogLength(l1);
+
+  while (bucket->buckets[i] != NULL)
+  {
+    //MULTIPLY_BUCKET(bucket,i);
+  #ifdef USE_COEF_BUCKETS
+    if (bucket->coef[i]!=NULL)
+    {
+      q = p_Plus_mm_Mult_qq(q, bucket->coef[i], bucket->buckets[i],
+                 l1, bucket->buckets_length[i], r);
+      p_Delete(&bucket->coef[i],r);
+      p_Delete(&bucket->buckets[i],r);
+    }
+    else
+    q = p_Add_q(q, bucket->buckets[i],
+                 l1, bucket->buckets_length[i], r);
+  #else
+    q = p_Add_q(q, bucket->buckets[i],
+                 l1, bucket->buckets_length[i], r);
+  #endif
+    bucket->buckets[i] = NULL;
+    bucket->buckets_length[i] = 0;
+    i = pLogLength(l1);
+    assume(i<= MAX_BUCKET);
+    assume(bucket->buckets_used<= MAX_BUCKET);
+  }
+
+  kbTest(bucket);
+  bucket->buckets[i] = q;
+  bucket->buckets_length[i]=l1;
+  if (i >= bucket->buckets_used)
+    bucket->buckets_used = i;
+  else
+    kBucketAdjustBucketsUsed(bucket);
+  kbTest(bucket);
+}
+
+
+
+//////////////////////////////////////////////////////////////////////////
+///
+/// Bpoly == Bpoly - m*p; where m is a monom
+/// Does not destroy p and m
+/// assume (*l <= 0 || pLength(p) == *l)
+void kBucket_Minus_m_Mult_p(kBucket_pt bucket, poly m, poly p, int *l,
+                            poly spNoether)
+{
+  assume(*l <= 0 || pLength(p) == *l);
+  int i, l1;
+  poly p1 = p;
+  ring r = bucket->bucket_ring;
+
+  if (*l <= 0)
+  {
+    l1 = pLength(p1);
+    *l = l1;
+  }
+  else
+    l1 = *l;
+
+  if (m == NULL || p == NULL) return;
+
+#ifndef HAVE_PSEUDO_BUCKETS
+  kBucketMergeLm(bucket);
+  kbTest(bucket);
+  i = pLogLength(l1);
+
+#if defined(HAVE_RINGS)||defined(HAVE_PLURAL)
+  if ((rField_is_Ring(r) && !(rField_is_Domain(r)))
+  ||(rIsPluralRing(r)))
+  {
+    pSetCoeff0(m, n_InpNeg(pGetCoeff(m),r->cf));
+    p1=pp_Mult_mm(p,m,r);
+    pSetCoeff0(m, n_InpNeg(pGetCoeff(m),r->cf));
+    l1=pLength(p1);
+    i = pLogLength(l1);
+  }
+  else
+#endif
+  {
+    if ((i <= bucket->buckets_used) && (bucket->buckets[i] != NULL))
+    {
+      assume(pLength(bucket->buckets[i])==bucket->buckets_length[i]);
+//#ifdef USE_COEF_BUCKETS
+//     if(bucket->coef[i]!=NULL)
+//     {
+//       poly mult=p_Mult_mm(bucket->coef[i],m,r);
+//       bucket->coef[i]=NULL;
+//       p1 = p_Minus_mm_Mult_qq(bucket->buckets[i], mult, p1,
+//                               bucket->buckets_length[i], l1,
+//                             spNoether, r);
+//     }
+//     else
+//#endif
+      MULTIPLY_BUCKET(bucket,i);
+      p1 = p_Minus_mm_Mult_qq(bucket->buckets[i], m, p1,
+                            bucket->buckets_length[i], l1,
+                            spNoether, r);
+      l1 = bucket->buckets_length[i];
+      bucket->buckets[i] = NULL;
+      bucket->buckets_length[i] = 0;
+      i = pLogLength(l1);
+    }
+    else
+    {
+      pSetCoeff0(m, n_InpNeg(pGetCoeff(m),r->cf));
+      if (spNoether != NULL)
+      {
+        l1 = -1;
+        p1 = r->p_Procs->pp_Mult_mm_Noether(p1, m, spNoether, l1, r);
+        i = pLogLength(l1);
+      }
+      else
+      {
+        p1 = r->p_Procs->pp_Mult_mm(p1, m, r);
+      }
+      pSetCoeff0(m, n_InpNeg(pGetCoeff(m),r->cf));
+    }
+  }
+
+  while (bucket->buckets[i] != NULL)
+  {
+    //kbTest(bucket);
+    MULTIPLY_BUCKET(bucket,i);
+    p1 = p_Add_q(p1, bucket->buckets[i],
+                 l1, bucket->buckets_length[i], r);
+    bucket->buckets[i] = NULL;
+    bucket->buckets_length[i] = 0;
+    i = pLogLength(l1);
+  }
+
+  bucket->buckets[i] = p1;
+  bucket->buckets_length[i]=l1;
+  if (i >= bucket->buckets_used)
+    bucket->buckets_used = i;
+  else
+    kBucketAdjustBucketsUsed(bucket);
+#else // HAVE_PSEUDO_BUCKETS
+  bucket->p = p_Minus_mm_Mult_qq(bucket->p, m,  p,
+                               bucket->l, l1,
+                               spNoether, r);
+#endif
+}
+
+//////////////////////////////////////////////////////////////////////////
+///
+/// Bpoly == Bpoly + m*p; where m is a monom
+/// Does not destroy p and m
+/// assume (l <= 0 || pLength(p) == l)
+void kBucket_Plus_mm_Mult_pp(kBucket_pt bucket, poly m, poly p, int l)
+{
+    assume((!rIsPluralRing(bucket->bucket_ring))||p_IsConstant(m, bucket->bucket_ring));
+  assume(l <= 0 || pLength(p) == l);
+  int i, l1;
+  poly p1 = p;
+  ring r = bucket->bucket_ring;
+
+  if (m == NULL || p == NULL) return;
+
+  if (l <= 0)
+  {
+    l1 = pLength(p1);
+    l = l1;
+  }
+  else
+    l1 = l;
+
+  kBucketMergeLm(bucket);
+  kbTest(bucket);
+  i = pLogLength(l1);
+  #ifdef USE_COEF_BUCKETS
+  number n=n_Init(1,r->cf);
+  #endif
+  if (i <= bucket->buckets_used && bucket->buckets[i] != NULL)
+  {
+    //if (FALSE){
+    #ifdef USE_COEF_BUCKETS
+    if ((bucket->coef[i]!=NULL) &&(i>=coef_start))
+    {
+      number orig_coef=p_GetCoeff(bucket->coef[i],r);
+      //we take ownership:
+      p_SetCoeff0(bucket->coef[i],n_Init(0,r),r);
+      number add_coef=n_Copy(p_GetCoeff(m,r),r);
+      number gcd=n_Gcd(add_coef, orig_coef,r);
+
+      if (!(n_IsOne(gcd,r)))
+      {
+        number orig_coef2=n_ExactDiv(orig_coef,gcd,r);
+        number add_coef2=n_ExactDiv(add_coef, gcd,r);
+        n_Delete(&orig_coef,r);
+        n_Delete(&add_coef,r);
+        orig_coef=orig_coef2;
+        add_coef=add_coef2;
+
+        //p_Mult_nn(bucket->buckets[i], orig_coef,r);
+        n_Delete(&n,r);
+        n=gcd;
+      }
+
+      //assume(n_IsOne(n,r));
+      number backup=p_GetCoeff(m,r);
+
+      p_SetCoeff0(m,add_coef,r);
+      bucket->buckets[i]=p_Mult_nn(bucket->buckets[i],orig_coef,r);
+
+      n_Delete(&orig_coef,r);
+      p_Delete(&bucket->coef[i],r);
+
+      p1 = p_Plus_mm_Mult_qq(bucket->buckets[i], m, p1,
+                           bucket->buckets_length[i], l1, r);
+      l1=bucket->buckets_length[i];
+      bucket->buckets[i]=NULL;
+      bucket->buckets_length[i] = 0;
+      i = pLogLength(l1);
+      assume(l1==pLength(p1));
+
+      p_SetCoeff(m,backup,r); //deletes add_coef
+    }
+    else
+    #endif
+    {
+      MULTIPLY_BUCKET(bucket,i);
+      p1 = p_Plus_mm_Mult_qq(bucket->buckets[i], m, p1,
+                           bucket->buckets_length[i], l1, r);
+      l1 = bucket->buckets_length[i];
+      bucket->buckets[i] = NULL;
+      bucket->buckets_length[i] = 0;
+      i = pLogLength(l1);
+    }
+  }
+
+  else
+  {
+    #ifdef USE_COEF_BUCKETS
+    number swap_n=p_GetCoeff(m,r);
+
+    assume(n_IsOne(n,r));
+    p_SetCoeff0(m,n,r);
+    n=swap_n;
+    //p_SetCoeff0(n, swap_n, r);
+    //p_GetCoeff0(n, swap_n,r);
+    #endif
+    p1 = r->p_Procs->pp_Mult_mm(p1, m, r);
+    #ifdef USE_COEF_BUCKETS
+    //m may not be changed
+    p_SetCoeff(m,n_Copy(n,r),r);
+    #endif
+  }
+
+
+  while ((bucket->buckets[i] != NULL) && (p1!=NULL))
+  {
+    assume(i!=0);
+    #ifdef USE_COEF_BUCKETS
+    if ((bucket->coef[i]!=NULL) &&(i>=coef_start))
+    {
+      number orig_coef=p_GetCoeff(bucket->coef[i],r);
+      //we take ownership:
+      p_SetCoeff0(bucket->coef[i],n_Init(0,r),r);
+      number add_coef=n_Copy(n,r);
+      number gcd=n_Gcd(add_coef, orig_coef,r);
+
+      if (!(n_IsOne(gcd,r)))
+      {
+        number orig_coef2=n_ExactDiv(orig_coef,gcd,r);
+        number add_coef2=n_ExactDiv(add_coef, gcd,r);
+        n_Delete(&orig_coef,r);
+        n_Delete(&n,r);
+        n_Delete(&add_coef,r);
+        orig_coef=orig_coef2;
+        add_coef=add_coef2;
+        //p_Mult_nn(bucket->buckets[i], orig_coef,r);
+        n=gcd;
+      }
+      //assume(n_IsOne(n,r));
+      bucket->buckets[i]=p_Mult_nn(bucket->buckets[i],orig_coef,r);
+      p1=p_Mult_nn(p1,add_coef,r);
+
+      p1 = p_Add_q(p1, bucket->buckets[i],r);
+      l1=pLength(p1);
+
+      bucket->buckets[i]=NULL;
+      n_Delete(&orig_coef,r);
+      p_Delete(&bucket->coef[i],r);
+      //l1=bucket->buckets_length[i];
+      assume(l1==pLength(p1));
+    }
+    else
+    #endif
+    {
+      //don't do that, pull out gcd
+      #ifdef USE_COEF_BUCKETS
+      if(!(n_IsOne(n,r)))
+      {
+        p1=p_Mult_nn(p1, n, r);
+        n_Delete(&n,r);
+        n=n_Init(1,r);
+      }
+      #endif
+      MULTIPLY_BUCKET(bucket,i);
+      p1 = p_Add_q(p1, bucket->buckets[i],
+                 l1, bucket->buckets_length[i], r);
+      bucket->buckets[i] = NULL;
+      bucket->buckets_length[i] = 0;
+    }
+    i = pLogLength(l1);
+  }
+
+  bucket->buckets[i] = p1;
+#ifdef USE_COEF_BUCKETS
+  assume(bucket->coef[i]==NULL);
+
+  if (!(n_IsOne(n,r)))
+  {
+    bucket->coef[i]=p_NSet(n,r);
+  }
+  else
+  {
+    bucket->coef[i]=NULL;
+    n_Delete(&n,r);
+  }
+
+  if ((p1==NULL) && (bucket->coef[i]!=NULL))
+    p_Delete(&bucket->coef[i],r);
+#endif
+  bucket->buckets_length[i]=l1;
+  if (i >= bucket->buckets_used)
+    bucket->buckets_used = i;
+  else
+    kBucketAdjustBucketsUsed(bucket);
+
+  kbTest(bucket);
+}
+
+poly kBucket_ExtractLarger(kBucket_pt bucket, poly q, poly append)
+{
+  if (q == NULL) return append;
+  poly lm;
+  loop
+  {
+    lm = kBucketGetLm(bucket);
+    if (lm == NULL) return append;
+    if (p_LmCmp(lm, q, bucket->bucket_ring) == 1)
+    {
+      lm = kBucketExtractLm(bucket);
+      pNext(append) = lm;
+      pIter(append);
+    }
+    else
+    {
+      return append;
+    }
+  }
+}
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Extract all monomials from bucket with component comp
+// Return as a polynomial *p with length *l
+// In other words, afterwards
+// Bpoly = Bpoly - (poly consisting of all monomials with component comp)
+// and components of monomials of *p are all 0
+//
+
+// Hmm... for now I'm too lazy to implement those independent of currRing
+// But better declare it extern than including polys.h
+extern void p_TakeOutComp(poly *p, long comp, poly *q, int *lq, const ring r);
+
+void kBucketTakeOutComp(kBucket_pt bucket,
+                        long comp,
+                        poly *r_p, int *l)
+{
+  poly p = NULL, q;
+  int i, lp = 0, lq;
+
+#ifndef HAVE_PSEUDO_BUCKETS
+  kBucketMergeLm(bucket);
+  for (i=1; i<=bucket->buckets_used; i++)
+  {
+    if (bucket->buckets[i] != NULL)
+    {
+      MULTIPLY_BUCKET(bucket,i);
+      p_TakeOutComp(&(bucket->buckets[i]), comp, &q, &lq, bucket->bucket_ring);
+      if (q != NULL)
+      {
+        assume(pLength(q) == lq);
+        bucket->buckets_length[i] -= lq;
+        assume(pLength(bucket->buckets[i]) == bucket->buckets_length[i]);
+        p = p_Add_q(p, q, lp, lq, bucket->bucket_ring);
+      }
+    }
+  }
+  kBucketAdjustBucketsUsed(bucket);
+#else
+  p_TakeOutComp(&(bucket->p), comp, &p, &lp,bucket->bucket_ring);
+  (bucket->l) -= lp;
+#endif
+  *r_p = p;
+  *l = lp;
+
+  kbTest(bucket);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Reduction of Bpoly with a given poly
+//
+
+extern int ksCheckCoeff(number *a, number *b);
+
+number kBucketPolyRed(kBucket_pt bucket,
+                      poly p1, int l1,
+                      poly spNoether)
+{
+  ring r=bucket->bucket_ring;
+  assume((!rIsPluralRing(r))||p_LmEqual(p1,kBucketGetLm(bucket), r));
+  assume(p1 != NULL &&
+         p_DivisibleBy(p1,  kBucketGetLm(bucket), r));
+  assume(pLength(p1) == (int) l1);
+
+  poly a1 = pNext(p1), lm = kBucketExtractLm(bucket);
+  BOOLEAN reset_vec=FALSE;
+  number rn;
+
+  /* we shall reduce bucket=bn*lm+... by p1=an*t+a1 where t=lm(p1)
+     and an,bn shall be defined further down only if lc(p1)!=1
+     we already know: an|bn and t|lm */
+  if(a1==NULL)
+  {
+    p_LmDelete(&lm, r);
+    return n_Init(1,r->cf);
+  }
+
+  if (! n_IsOne(pGetCoeff(p1),r->cf))
+  {
+    number an = pGetCoeff(p1), bn = pGetCoeff(lm);
+//StringSetS("##### an = "); nWrite(an); PrintS(StringEndS("\n")); // NOTE/TODO: use StringAppendS("\n"); omFree(s);
+//StringSetS("##### bn = "); nWrite(bn); PrintS(StringEndS("\n")); // NOTE/TODO: use StringAppendS("\n"); omFree(s);
+    /* ksCheckCoeff: divide out gcd from an and bn: */
+    int ct = ksCheckCoeff(&an, &bn,r->cf);
+    /* the previous command returns ct=0 or ct=2 iff an!=1
+       note: an is now 1 or -1 */
+
+    /* setup factor for p1 which cancels leading terms */
+    p_SetCoeff(lm, bn, r);
+    if ((ct == 0) || (ct == 2))
+    {
+      /* next line used to be here before but is WRONG:
+      kBucket_Mult_n(bucket, an);
+        its use would result in a wrong sign for the tail of bucket
+        in the reduction */
+
+      /* correct factor for cancelation by changing sign if an=-1 */
+      if (rField_is_Ring(r))
+        lm = p_Mult_nn(lm, an, r);
+      else
+        kBucket_Mult_n(bucket, an);
+    }
+    rn = an;
+  }
+  else
+  {
+    rn = n_Init(1,r->cf);
+  }
+
+  if (p_GetComp(p1, r) != p_GetComp(lm, r))
+  {
+    p_SetCompP(a1, p_GetComp(lm, r), r);
+    reset_vec = TRUE;
+    p_SetComp(lm, p_GetComp(p1, r), r);
+    p_Setm(lm, r);
+  }
+
+  p_ExpVectorSub(lm, p1, r);
+  l1--;
+
+  assume(l1==pLength(a1));
+#if 0
+  BOOLEAN backuped=FALSE;
+  number coef;
+  //@Viktor, don't ignore coefficients on monomials
+  if(l1==1) {
+
+    //if (rField_is_Q(r)) {
+      //avoid this for function fields, as gcds are expensive at the moment
+
+
+      coef=p_GetCoeff(a1,r);
+      lm=p_Mult_nn(lm, coef, r);
+      p_SetCoeff0(a1, n_Init(1,r), r);
+      backuped=TRUE;
+      //WARNING: not thread_safe
+    //deletes coef as side effect
+    //}
+  }
+#endif
+
+  kBucket_Minus_m_Mult_p(bucket, lm, a1, &l1, spNoether);
+
+#if 0
+  if (backuped)
+    p_SetCoeff0(a1,coef,r);
+#endif
+
+  p_LmDelete(&lm, r);
+  if (reset_vec) p_SetCompP(a1, 0, r);
+  kbTest(bucket);
+  return rn;
+}
+
+#ifndef USE_COEF_BUCKETS
+void kBucketSimpleContent(kBucket_pt) {}
+#else
+static BOOLEAN nIsPseudoUnit(number n, ring r)
+{
+  if (rField_is_Zp(r))
+    return TRUE;
+
+  if (rParameter(r)==NULL)
+  {
+    return (n_Size(n,r->cf)==1);
+  }
+  //if (r->parameter!=NULL)
+  return (n_IsOne(n,r->cf) || n_IsMOne(n,r->cf));
+}
+
+void kBucketSimpleContent(kBucket_pt bucket)
+{
+  ring r=bucket->bucket_ring;
+  int i;
+  //PrintS("HHHHHHHHHHHHH");
+  for (i=0;i<=MAX_BUCKET;i++)
+  {
+    //if ((bucket->buckets[i]!=NULL) && (bucket->coef[i]!=NULL))
+    //    PrintS("H2H2H2");
+    if (i==0)
+    {
+      assume(bucket->buckets[i]==NULL);
+    }
+    if ((bucket->buckets[i]!=NULL) && (bucket->coef[i]==NULL))
+      return;
+  }
+  for (i=0;i<=MAX_BUCKET;i++)
+  {
+    //if ((bucket->buckets[i]!=NULL) && (bucket->coef[i]!=NULL))
+    //    PrintS("H2H2H2");
+    if (i==0)
+    {
+      assume(bucket->buckets[i]==NULL);
+    }
+    if ((bucket->buckets[i]!=NULL)
+    && (nIsPseudoUnit(p_GetCoeff(bucket->coef[i],r),r)))
+      return;
+  }
+  //return;
+
+  number coef=n_Init(0,r);
+  //ATTENTION: will not work correct for GB over ring
+  //if (TEST_OPT_PROT)
+  //    PrintS("CCCCCCCCCCCCC");
+  for (i=MAX_BUCKET;i>=0;i--)
+  {
+    if (i==0)
+    {
+      assume(bucket->buckets[i]==NULL);
+    }
+    if (bucket->buckets[i]!=NULL)
+    {
+      assume(bucket->coef[i]!=NULL);
+      assume(!(n_IsZero(pGetCoeff(bucket->coef[i]),r)));
+
+      //in this way it should crash on programming errors, yeah
+      number temp=n_Gcd(coef, pGetCoeff(bucket->coef[i]),r);
+      n_Delete(&coef,r );
+      coef=temp;
+      if (nIsPseudoUnit(coef,r))
+      {
+        n_Delete(&coef,r);
+        return;
+      }
+      assume(!(n_IsZero(coef,r)));
+    }
+  }
+  if (n_IsZero(coef,r))
+  {
+    n_Delete(&coef,r);
+    return;
+  }
+  if (TEST_OPT_PROT)
+    PrintS("S");
+  for(i=0;i<=MAX_BUCKET;i++)
+  {
+    if (bucket->buckets[i]!=NULL)
+    {
+      assume(!(n_IsZero(coef,r)));
+      assume(bucket->coef[i]!=NULL);
+      number lc=p_GetCoeff(bucket->coef[i],r);
+      p_SetCoeff(bucket->coef[i], n_ExactDiv(lc,coef,r),r);
+      assume(!(n_IsZero(p_GetCoeff(bucket->coef[i],r),r)));
+    }
+  }
+  n_Delete(&coef,r);
+}
+#endif
+
+
+poly kBucketExtractLmOfBucket(kBucket_pt bucket, int i)
+{
+  assume(bucket->buckets[i]!=NULL);
+
+  poly p=bucket->buckets[i];
+  bucket->buckets_length[i]--;
+#ifdef USE_COEF_BUCKETS
+  ring r=bucket->bucket_ring;
+  if (bucket->coef[i]!=NULL)
+  {
+    poly next=pNext(p);
+    if (next==NULL)
+    {
+      MULTIPLY_BUCKET(bucket,i);
+      p=bucket->buckets[i];
+      bucket->buckets[i]=NULL;
+      return p;
+    }
+    else
+    {
+      bucket->buckets[i]=next;
+      number c=p_GetCoeff(bucket->coef[i],r);
+      pNext(p)=NULL;
+      p=p_Mult_nn(p,c,r);
+      assume(p!=NULL);
+      return p;
+    }
+  }
+  else
+#endif
+  {
+    bucket->buckets[i]=pNext(bucket->buckets[i]);
+    pNext(p)=NULL;
+    assume(p!=NULL);
+    return p;
+  }
+}
+
+/*
+* input - output: a, b
+* returns:
+*   a := a/gcd(a,b), b := b/gcd(a,b)
+*   and return value
+*       0  ->  a != 1,  b != 1
+*       1  ->  a == 1,  b != 1
+*       2  ->  a != 1,  b == 1
+*       3  ->  a == 1,  b == 1
+*   this value is used to control the spolys
+*/
+int ksCheckCoeff(number *a, number *b, const coeffs r)
+{
+  int c = 0;
+  number an = *a, bn = *b;
+  n_Test(an,r);
+  n_Test(bn,r);
+
+  number cn = n_SubringGcd(an, bn, r);
+
+  if(n_IsOne(cn, r))
+  {
+    an = n_Copy(an, r);
+    bn = n_Copy(bn, r);
+  }
+  else
+  {
+    an = n_Div(an, cn, r); n_Normalize(an,r);
+    bn = n_Div(bn, cn, r); n_Normalize(bn,r);
+  }
+  n_Delete(&cn, r);
+  if (n_IsOne(an, r))
+  {
+    c = 1;
+  }
+  if (n_IsOne(bn, r))
+  {
+    c += 2;
+  }
+  *a = an;
+  *b = bn;
+  return c;
+}
+
diff --git a/libpolys/polys/kbuckets.h b/libpolys/polys/kbuckets.h
new file mode 100644
index 0000000..5582981
--- /dev/null
+++ b/libpolys/polys/kbuckets.h
@@ -0,0 +1,246 @@
+#ifndef KBUCKETS_H
+#define KBUCKETS_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+
+//#define HAVE_COEF_BUCKETS
+
+/////////////////////////////////////////////////////////////////////////
+// configuration
+//
+
+// define to not really use the bucket feature
+// #define HAVE_PSEUDO_BUCKETS
+class  kBucket; typedef kBucket* kBucket_pt;
+struct spolyrec; typedef struct spolyrec polyrec; typedef polyrec* poly;
+struct ip_sring; typedef struct ip_sring* ring; typedef struct ip_sring const* const_ring;
+
+#include <polys/monomials/ring.h> // for ring->p_Procs->p_kBucketSetLm!
+#include <polys/templates/p_Procs.h> // for p_kBucketSetLm_Proc_Ptr
+
+//////////////////////////////////////////////////////////////////////////
+// Creation/Destruction of buckets
+//
+kBucket_pt kBucketCreate(ring r);
+// only free memory allocated for bucket
+void kBucketDestroy(kBucket_pt *bucket);
+// frees polys/monomials in bucket and destroys bucket
+void kBucketDeleteAndDestroy(kBucket_pt *bucket);
+
+
+/////////////////////////////////////////////////////////////////////////////
+// Convertion from/to Bpolys
+//
+
+// Converts p into a bucket poly (Bpoly) and destroys p
+// Assumes length <= 0 || pLength(p) == length
+void kBucketInit(kBucket_pt bucket, poly p, int length);
+
+// Converts Bpoly into a poly and clears bucket
+// i.e., afterwards Bpoly == 0
+void kBucketClear(kBucket_pt bucket, poly *p, int *length);
+
+inline poly kBucketClear(kBucket_pt bucket)
+{
+  int dummy;
+  poly p;
+  kBucketClear(bucket, &p, &dummy);
+  return p;
+}
+
+// Canonicalizes Bpoly, i.e. converts polys of buckets into one poly in
+// one bucket: Returns number of bucket into which it is canonicalized
+int kBucketCanonicalize(kBucket_pt bucket);
+
+/////////////////////////////////////////////////////////////////////////////
+// Extracts lm of Bpoly, i.e. Bpoly is changed s.t.
+// Bpoly == Bpoly - Lm(Bpoly)
+//
+inline poly kBucketExtractLm(kBucket_pt bucket);
+
+/////////////////////////////////////////////////////////////////////////////
+// Sets Lm of Bpoly, i.e. Bpoly is changed s.t.
+// Bpoly = Bpoly + m
+// assumes that m is larger than all monomials of Bpoly
+void kBucketSetLm(kBucket_pt bucket, poly lm);
+
+
+//////////////////////////////////////////////////////////////////////////
+///
+/// Bucket number i from bucket is out of length sync, resync
+///
+void kBucketAdjust(kBucket_pt bucket, int i);
+
+/////////////////////////////////////////////////////////////////////////////
+// Reduces Bpoly (say, q) with p, i.e.:
+// q = (Lc(p) / gcd(Lc(p), Lc(q)))*q - (Lc(q)/gcd(Lc(p),Lc(q)))*p*(Lm(q)/Lm(p))
+// Assumes p1 != NULL, Bpoly != NULL
+//         Lm(p1) divides Lm(Bpoly)
+//         pLength(p1) == l1
+// Returns: Lc(p) / gcd(Lc(p), Lc(q))
+number kBucketPolyRed(kBucket_pt bucket,
+                      poly p, int l,
+                      poly spNoether);
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Extract all monomials from bucket with component comp
+// Return as a polynomial *p with length *l
+// In other words, afterwards
+// Bpoly == Bpoly - (poly consisting of all monomials with component comp)
+// and components of monomials of *p are all 0
+
+void kBucketTakeOutComp(kBucket_pt bucket,
+                        long comp,
+                        poly *p, int *l);
+
+//////////////////////////////////////////////////////////////////////////
+///
+/// Multiply Bucket by number ,i.e. Bpoly == n*Bpoly
+///
+void kBucket_Mult_n(kBucket_pt bucket, number n);
+
+//////////////////////////////////////////////////////////////////////////
+///
+/// Extract all monomials of bucket which are larger than q
+/// Append those to append, and return last monomial of append
+poly kBucket_ExtractLarger(kBucket_pt bucket, poly q, poly append);
+
+
+//////////////////////////////////////////////////////////////////////////
+///
+/// Add to Bucket a poly ,i.e. Bpoly == Bpoly + q
+///
+void kBucket_Add_q(kBucket_pt bucket, poly q, int* lq);
+
+// first, do ExtractLarger
+// then add q
+inline poly
+kBucket_ExtractLarger_Add_q(kBucket_pt bucket, poly append, poly q, int *lq)
+{
+  append = kBucket_ExtractLarger(bucket, q, append);
+  kBucket_Add_q(bucket, q, lq);
+  return append;
+}
+
+//////////////////////////////////////////////////////////////////////////
+///
+/// Bpoly == Bpoly - m*p; where m is a monom
+/// Does not destroy p and m (TODO: rename into kBucket_Minus_mm_Mult_pp!?)
+/// assume (*l <= 0 || pLength(p) == *l)
+void kBucket_Minus_m_Mult_p(kBucket_pt bucket, poly m, poly p, int *l,
+                            poly spNother = NULL);
+
+//////////////////////////////////////////////////////////////////////////
+///
+/// Bpoly == Bpoly + m*p; where m is a monom
+/// Does not destroy p and m
+/// assume (l <= 0 || pLength(p) == l)
+void kBucket_Plus_mm_Mult_pp(kBucket_pt bucket, poly m, poly p, int l);
+
+//////////////////////////////////////////////////////////////////////////
+///
+/// For changing the ring of the Bpoly to new_tailBin
+///
+void kBucketShallowCopyDelete(kBucket_pt bucket,
+                              ring new_tailRing, omBin new_tailBin,
+                              pShallowCopyDeleteProc p_shallow_copy_delete);
+
+//////////////////////////////////////////////////////////////////////////
+///
+/// Tests
+///
+///
+#ifdef KDEBUG
+BOOLEAN kbTest(kBucket_pt bucket);
+#else
+#define kbTest(bucket)  do {} while (0)
+#endif
+
+//////////////////////////////////////////////////////////////////////////
+///
+/// Bucket definition (should be no one elses business, though)
+///
+
+// define this if length of bucket polys are 2, 4, 8, etc
+// instead of 4, 16, 64 ... --
+// this seems to be less efficient, both, in theory and in practice
+// #define BUCKET_TWO_BASE
+#ifdef BUCKET_TWO_BASE
+#define MAX_BUCKET 28
+#else
+#define MAX_BUCKET 14 // suitable for polys up to a length of 4^14 = 2^28
+#endif
+
+class kBucket
+{
+public:
+#ifdef HAVE_PSEUDO_BUCKETS
+  poly p;
+  int l;
+#else
+  poly buckets[MAX_BUCKET + 1];        // polys in bucket
+#ifdef HAVE_COEF_BUCKETS
+  poly coef[MAX_BUCKET + 1];        // coeff of polys in bucket or NULL : 2..max
+#endif
+  int  buckets_length[MAX_BUCKET + 1]; // length if i-th poly
+  int buckets_used;                    // max number of used bucket
+#endif
+  ring bucket_ring;
+};
+
+#ifndef HAVE_PSEUDO_BUCKETS
+inline void kBucketAdjustBucketsUsed(kBucket_pt bucket)
+{
+  while ( bucket->buckets_used > 0 &&
+          bucket->buckets[bucket->buckets_used] == NULL)
+    (bucket->buckets_used)--;
+}
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// Gets leading monom of bucket, does NOT change Bpoly!!!!!
+// Returned monom is READ ONLY, i.e. no manipulations are allowed !!!!
+//
+inline poly kBucketGetLm(kBucket_pt bucket, p_kBucketSetLm_Proc_Ptr _p_kBucketSetLm)
+{
+#ifdef   HAVE_COEF_BUCKETS
+  assume(bucket->coef[0]==NULL);
+#endif
+
+  poly& lead = bucket->buckets[0];
+
+  if (lead == NULL)
+    _p_kBucketSetLm(bucket);
+
+#ifdef  HAVE_COEF_BUCKETS
+  assume(bucket->coef[0]==NULL);
+#endif
+
+  return lead;
+}
+
+inline poly kBucketGetLm(kBucket_pt bucket)
+{
+  return kBucketGetLm(bucket, bucket->bucket_ring->p_Procs->p_kBucketSetLm); // TODO: needs ring :(
+}
+
+inline poly kBucketExtractLm(kBucket_pt bucket)
+{
+  poly lm = kBucketGetLm(bucket);
+  #ifdef   HAVE_COEF_BUCKETS
+  assume(bucket->coef[0]==NULL);
+  #endif
+  bucket->buckets[0] = NULL;
+  bucket->buckets_length[0] = 0;
+
+  return lm;
+}
+
+poly kBucketExtractLmOfBucket(kBucket_pt bucket, int i);
+void kBucketSimpleContent(kBucket_pt bucket);
+BOOLEAN kBucketIsCleared(kBucket_pt bucket);
+int ksCheckCoeff(number *a, number *b, const coeffs r);
+#endif /* KBUCKETS_H */
diff --git a/libpolys/polys/matpol.cc b/libpolys/polys/matpol.cc
new file mode 100644
index 0000000..13c491f
--- /dev/null
+++ b/libpolys/polys/matpol.cc
@@ -0,0 +1,1703 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+
+/*
+* ABSTRACT:
+*/
+
+#include <stdio.h>
+#include <math.h>
+
+
+
+
+#include <misc/auxiliary.h>
+
+#include <omalloc/omalloc.h>
+#include <misc/mylimits.h>
+
+
+// #include <kernel/structs.h>
+// #include <kernel/GBEngine/kstd1.h>
+// #include <kernel/polys.h>
+
+#include <misc/intvec.h>
+#include <coeffs/numbers.h>
+
+#include <reporter/reporter.h>
+
+
+#include "monomials/ring.h"
+#include "monomials/p_polys.h"
+
+#include "coeffrings.h"
+#include "simpleideals.h"
+#include "matpol.h"
+#include "prCopy.h"
+
+#include "sparsmat.h"
+
+//omBin sip_sideal_bin = omGetSpecBin(sizeof(ip_smatrix));
+/*0 implementation*/
+
+static poly mp_Exdiv ( poly m, poly d, poly vars, const ring);
+static poly mp_Select (poly fro, poly what, const ring);
+
+/// create a r x c zero-matrix
+matrix mpNew(int r, int c)
+{
+  if (r<=0) r=1;
+  if ( (((int)(MAX_INT_VAL/sizeof(poly))) / r) <= c)
+  {
+    Werror("internal error: creating matrix[%d][%d]",r,c);
+    return NULL;
+  }
+  matrix rc = (matrix)omAllocBin(sip_sideal_bin);
+  rc->nrows = r;
+  rc->ncols = c;
+  rc->rank = r;
+  if (c != 0)
+  {
+    int s=r*c*sizeof(poly);
+    rc->m = (poly*)omAlloc0(s);
+    //if (rc->m==NULL)
+    //{
+    //  Werror("internal error: creating matrix[%d][%d]",r,c);
+    //  return NULL;
+    //}
+  }
+  return rc;
+}
+
+/// copies matrix a (from ring r to r)
+matrix mp_Copy (matrix a, const ring r)
+{
+  id_Test((ideal)a, r);
+  poly t;
+  int i, m=MATROWS(a), n=MATCOLS(a);
+  matrix b = mpNew(m, n);
+
+  for (i=m*n-1; i>=0; i--)
+  {
+    t = a->m[i];
+    if (t!=NULL)
+    {
+      p_Normalize(t, r);
+      b->m[i] = p_Copy(t, r);
+    }
+  }
+  b->rank=a->rank;
+  return b;
+}
+
+/// copies matrix a from rSrc into rDst
+matrix mp_Copy(const matrix a, const ring rSrc, const ring rDst)
+{
+  id_Test((ideal)a, rSrc);
+
+  poly t;
+  int i, m=MATROWS(a), n=MATCOLS(a);
+
+  matrix b = mpNew(m, n);
+
+  for (i=m*n-1; i>=0; i--)
+  {
+    t = a->m[i];
+    if (t!=NULL)
+    {
+      b->m[i] = prCopyR_NoSort(t, rSrc, rDst);
+      p_Normalize(b->m[i], rDst);
+    }
+  }
+  b->rank=a->rank;
+
+  id_Test((ideal)b, rDst);
+
+  return b;
+}
+
+
+
+/// make it a p * unit matrix
+matrix mp_InitP(int r, int c, poly p, const ring R)
+{
+  matrix rc = mpNew(r,c);
+  int i=si_min(r,c), n = c*(i-1)+i-1, inc = c+1;
+
+  p_Normalize(p, R);
+  while (n>0)
+  {
+    rc->m[n] = p_Copy(p, R);
+    n -= inc;
+  }
+  rc->m[0]=p;
+  return rc;
+}
+
+/// make it a v * unit matrix
+matrix mp_InitI(int r, int c, int v, const ring R)
+{
+  return mp_InitP(r, c, p_ISet(v, R), R);
+}
+
+/// c = f*a
+matrix mp_MultI(matrix a, int f, const ring R)
+{
+  int k, n = a->nrows, m = a->ncols;
+  poly p = p_ISet(f, R);
+  matrix c = mpNew(n,m);
+
+  for (k=m*n-1; k>0; k--)
+    c->m[k] = pp_Mult_qq(a->m[k], p, R);
+  c->m[0] = p_Mult_q(p_Copy(a->m[0], R), p, R);
+  return c;
+}
+
+/// multiply a matrix 'a' by a poly 'p', destroy the args
+matrix mp_MultP(matrix a, poly p, const ring R)
+{
+  int k, n = a->nrows, m = a->ncols;
+
+  p_Normalize(p, R);
+  for (k=m*n-1; k>0; k--)
+  {
+    if (a->m[k]!=NULL)
+      a->m[k] = p_Mult_q(a->m[k], p_Copy(p, R), R);
+  }
+  a->m[0] = p_Mult_q(a->m[0], p, R);
+  return a;
+}
+
+/*2
+* multiply a poly 'p' by a matrix 'a', destroy the args
+*/
+matrix pMultMp(poly p, matrix a, const ring R)
+{
+  int k, n = a->nrows, m = a->ncols;
+
+  p_Normalize(p, R);
+  for (k=m*n-1; k>0; k--)
+  {
+    if (a->m[k]!=NULL)
+      a->m[k] = p_Mult_q(p_Copy(p, R), a->m[k], R);
+  }
+  a->m[0] = p_Mult_q(p, a->m[0], R);
+  return a;
+}
+
+matrix mp_Add(matrix a, matrix b, const ring R)
+{
+  int k, n = a->nrows, m = a->ncols;
+  if ((n != b->nrows) || (m != b->ncols))
+  {
+/*
+*    Werror("cannot add %dx%d matrix and %dx%d matrix",
+*      m,n,b->cols(),b->rows());
+*/
+    return NULL;
+  }
+  matrix c = mpNew(n,m);
+  for (k=m*n-1; k>=0; k--)
+    c->m[k] = p_Add_q(p_Copy(a->m[k], R), p_Copy(b->m[k], R), R);
+  return c;
+}
+
+matrix mp_Sub(matrix a, matrix b, const ring R)
+{
+  int k, n = a->nrows, m = a->ncols;
+  if ((n != b->nrows) || (m != b->ncols))
+  {
+/*
+*    Werror("cannot sub %dx%d matrix and %dx%d matrix",
+*      m,n,b->cols(),b->rows());
+*/
+    return NULL;
+  }
+  matrix c = mpNew(n,m);
+  for (k=m*n-1; k>=0; k--)
+    c->m[k] = p_Sub(p_Copy(a->m[k], R), p_Copy(b->m[k], R), R);
+  return c;
+}
+
+matrix mp_Mult(matrix a, matrix b, const ring R)
+{
+  int i, j, k;
+  int m = MATROWS(a);
+  int p = MATCOLS(a);
+  int q = MATCOLS(b);
+
+  if (p!=MATROWS(b))
+  {
+/*
+*   Werror("cannot multiply %dx%d matrix and %dx%d matrix",
+*     m,p,b->rows(),q);
+*/
+    return NULL;
+  }
+  matrix c = mpNew(m,q);
+
+  for (i=1; i<=m; i++)
+  {
+    for (k=1; k<=p; k++)
+    {
+      poly aik;
+      if ((aik=MATELEM(a,i,k))!=NULL)
+      {
+        for (j=1; j<=q; j++)
+        {
+          poly bkj;
+          if ((bkj=MATELEM(b,k,j))!=NULL)
+          {
+            poly *cij=&(MATELEM(c,i,j));
+            poly s = pp_Mult_qq(aik /*MATELEM(a,i,k)*/, bkj/*MATELEM(b,k,j)*/, R);
+            if (/*MATELEM(c,i,j)*/ (*cij)==NULL) (*cij)=s;
+            else (*cij) = p_Add_q((*cij) /*MATELEM(c,i,j)*/ ,s, R);
+          }
+        }
+      }
+    //  pNormalize(t);
+    //  MATELEM(c,i,j) = t;
+    }
+  }
+  for(i=m*q-1;i>=0;i--) p_Normalize(c->m[i], R);
+  return c;
+}
+
+matrix mp_Transp(matrix a, const ring R)
+{
+  int    i, j, r = MATROWS(a), c = MATCOLS(a);
+  poly *p;
+  matrix b =  mpNew(c,r);
+
+  p = b->m;
+  for (i=0; i<c; i++)
+  {
+    for (j=0; j<r; j++)
+    {
+      if (a->m[j*c+i]!=NULL) *p = p_Copy(a->m[j*c+i], R);
+      p++;
+    }
+  }
+  return b;
+}
+
+/*2
+*returns the trace of matrix a
+*/
+poly mp_Trace ( matrix a, const ring R)
+{
+  int i;
+  int n = (MATCOLS(a)<MATROWS(a)) ? MATCOLS(a) : MATROWS(a);
+  poly  t = NULL;
+
+  for (i=1; i<=n; i++)
+    t = p_Add_q(t, p_Copy(MATELEM(a,i,i), R), R);
+  return t;
+}
+
+/*2
+*returns the trace of the product of a and b
+*/
+poly TraceOfProd ( matrix a, matrix b, int n, const ring R)
+{
+  int i, j;
+  poly  p, t = NULL;
+
+  for (i=1; i<=n; i++)
+  {
+    for (j=1; j<=n; j++)
+    {
+      p = pp_Mult_qq(MATELEM(a,i,j), MATELEM(b,j,i), R);
+      t = p_Add_q(t, p, R);
+    }
+  }
+  return t;
+}
+
+// #ifndef SIZE_OF_SYSTEM_PAGE
+// #define SIZE_OF_SYSTEM_PAGE 4096
+// #endif
+
+/*2
+* corresponds to Maple's coeffs:
+* var has to be the number of a variable
+*/
+matrix mp_Coeffs (ideal I, int var, const ring R)
+{
+  poly h,f;
+  int l, i, c, m=0;
+  matrix co;
+  /* look for maximal power m of x_var in I */
+  for (i=IDELEMS(I)-1; i>=0; i--)
+  {
+    f=I->m[i];
+    while (f!=NULL)
+    {
+      l=p_GetExp(f,var, R);
+      if (l>m) m=l;
+      pIter(f);
+    }
+  }
+  co=mpNew((m+1)*I->rank,IDELEMS(I));
+  /* divide each monomial by a power of x_var,
+  * remember the power in l and the component in c*/
+  for (i=IDELEMS(I)-1; i>=0; i--)
+  {
+    f=I->m[i];
+    I->m[i]=NULL;
+    while (f!=NULL)
+    {
+      l=p_GetExp(f,var, R);
+      p_SetExp(f,var,0, R);
+      c=si_max((int)p_GetComp(f, R),1);
+      p_SetComp(f,0, R);
+      p_Setm(f, R);
+      /* now add the resulting monomial to co*/
+      h=pNext(f);
+      pNext(f)=NULL;
+      //MATELEM(co,c*(m+1)-l,i+1)
+      //  =p_Add_q(MATELEM(co,c*(m+1)-l,i+1),f, R);
+      MATELEM(co,(c-1)*(m+1)+l+1,i+1)
+        =p_Add_q(MATELEM(co,(c-1)*(m+1)+l+1,i+1),f, R);
+      /* iterate f*/
+      f=h;
+    }
+  }
+  id_Delete(&I, R);
+  return co;
+}
+
+/*2
+* given the result c of mpCoeffs(ideal/module i, var)
+* i of rank r
+* build the matrix of the corresponding monomials in m
+*/
+void   mp_Monomials(matrix c, int r, int var, matrix m, const ring R)
+{
+  /* clear contents of m*/
+  int k,l;
+  for (k=MATROWS(m);k>0;k--)
+  {
+    for(l=MATCOLS(m);l>0;l--)
+    {
+      p_Delete(&MATELEM(m,k,l), R);
+    }
+  }
+  omfreeSize((ADDRESS)m->m,MATROWS(m)*MATCOLS(m)*sizeof(poly));
+  /* allocate monoms in the right size r x MATROWS(c)*/
+  m->m=(poly*)omAlloc0(r*MATROWS(c)*sizeof(poly));
+  MATROWS(m)=r;
+  MATCOLS(m)=MATROWS(c);
+  m->rank=r;
+  /* the maximal power p of x_var: MATCOLS(m)=r*(p+1) */
+  int p=MATCOLS(m)/r-1;
+  /* fill in the powers of x_var=h*/
+  poly h=p_One(R);
+  for(k=r;k>0; k--)
+  {
+    MATELEM(m,k,k*(p+1))=p_One(R);
+  }
+  for(l=p;l>=0; l--)
+  {
+    p_SetExp(h,var,p-l, R);
+    p_Setm(h, R);
+    for(k=r;k>0; k--)
+    {
+      MATELEM(m,k,k*(p+1)-l)=p_Copy(h, R);
+    }
+  }
+  p_Delete(&h, R);
+}
+
+matrix mp_CoeffProc (poly f, poly vars, const ring R)
+{
+  assume(vars!=NULL);
+  poly sel, h;
+  int l, i;
+  int pos_of_1 = -1;
+  matrix co;
+
+  if (f==NULL)
+  {
+    co = mpNew(2, 1);
+    MATELEM(co,1,1) = p_One(R);
+    MATELEM(co,2,1) = NULL;
+    return co;
+  }
+  sel = mp_Select(f, vars, R);
+  l = pLength(sel);
+  co = mpNew(2, l);
+
+  if (rHasLocalOrMixedOrdering(R))
+  {
+    for (i=l; i>=1; i--)
+    {
+      h = sel;
+      pIter(sel);
+      pNext(h)=NULL;
+      MATELEM(co,1,i) = h;
+      MATELEM(co,2,i) = NULL;
+      if (p_IsConstant(h, R)) pos_of_1 = i;
+    }
+  }
+  else
+  {
+    for (i=1; i<=l; i++)
+    {
+      h = sel;
+      pIter(sel);
+      pNext(h)=NULL;
+      MATELEM(co,1,i) = h;
+      MATELEM(co,2,i) = NULL;
+      if (p_IsConstant(h, R)) pos_of_1 = i;
+    }
+  }
+  while (f!=NULL)
+  {
+    i = 1;
+    loop
+    {
+      if (i!=pos_of_1)
+      {
+        h = mp_Exdiv(f, MATELEM(co,1,i),vars, R);
+        if (h!=NULL)
+        {
+          MATELEM(co,2,i) = p_Add_q(MATELEM(co,2,i), h, R);
+          break;
+        }
+      }
+      if (i == l)
+      {
+        // check monom 1 last:
+        if (pos_of_1 != -1)
+        {
+          h = mp_Exdiv(f, MATELEM(co,1,pos_of_1),vars, R);
+          if (h!=NULL)
+          {
+            MATELEM(co,2,pos_of_1) = p_Add_q(MATELEM(co,2,pos_of_1), h, R);
+          }
+        }
+        break;
+      }
+      i ++;
+    }
+    pIter(f);
+  }
+  return co;
+}
+
+/*2
+*exact divisor: let d  == x^i*y^j, m is thought to have only one term;
+*    return m/d iff d divides m, and no x^k*y^l (k>i or l>j) divides m
+* consider all variables in vars
+*/
+static poly mp_Exdiv ( poly m, poly d, poly vars, const ring R)
+{
+  int i;
+  poly h = p_Head(m, R);
+  for (i=1; i<=rVar(R); i++)
+  {
+    if (p_GetExp(vars,i, R) > 0)
+    {
+      if (p_GetExp(d,i, R) != p_GetExp(h,i, R))
+      {
+        p_Delete(&h, R);
+        return NULL;
+      }
+      p_SetExp(h,i,0, R);
+    }
+  }
+  p_Setm(h, R);
+  return h;
+}
+
+void mp_Coef2(poly v, poly mon, matrix *c, matrix *m, const ring R)
+{
+  poly* s;
+  poly p;
+  int sl,i,j;
+  int l=0;
+  poly sel=mp_Select(v,mon, R);
+
+  p_Vec2Polys(sel,&s,&sl, R);
+  for (i=0; i<sl; i++)
+    l=si_max(l,pLength(s[i]));
+  *c=mpNew(sl,l);
+  *m=mpNew(sl,l);
+  poly h;
+  int isConst;
+  for (j=1; j<=sl;j++)
+  {
+    p=s[j-1];
+    if (p_IsConstant(p, R)) /*p != NULL */
+    {
+      isConst=-1;
+      i=l;
+    }
+    else
+    {
+      isConst=1;
+      i=1;
+    }
+    while(p!=NULL)
+    {
+      h = p_Head(p, R);
+      MATELEM(*m,j,i) = h;
+      i+=isConst;
+      p = p->next;
+    }
+  }
+  while (v!=NULL)
+  {
+    i = 1;
+    j = p_GetComp(v, R);
+    loop
+    {
+      poly mp=MATELEM(*m,j,i);
+      if (mp!=NULL)
+      {
+        h = mp_Exdiv(v, mp /*MATELEM(*m,j,i)*/, mp, R);
+        if (h!=NULL)
+        {
+          p_SetComp(h,0, R);
+          MATELEM(*c,j,i) = p_Add_q(MATELEM(*c,j,i), h, R);
+          break;
+        }
+      }
+      if (i < l)
+        i++;
+      else
+        break;
+    }
+    v = v->next;
+  }
+}
+
+
+BOOLEAN mp_Equal(matrix a, matrix b, const ring R)
+{
+  if ((MATCOLS(a)!=MATCOLS(b)) || (MATROWS(a)!=MATROWS(b)))
+    return FALSE;
+  int i=MATCOLS(a)*MATROWS(b)-1;
+  while (i>=0)
+  {
+    if (a->m[i]==NULL)
+    {
+      if (b->m[i]!=NULL) return FALSE;
+    }
+    else
+      if (b->m[i]==NULL) return FALSE;
+      else if (p_Cmp(a->m[i],b->m[i], R)!=0) return FALSE;
+    i--;
+  }
+  i=MATCOLS(a)*MATROWS(b)-1;
+  while (i>=0)
+  {
+#if 0
+    poly tt=p_Sub(p_Copy(a->m[i], R),p_Copy(b->m[i], R), R);
+    if (tt!=NULL)
+    {
+      p_Delete(&tt, R);
+      return FALSE;
+    }
+#else
+    if(!p_EqualPolys(a->m[i],b->m[i], R)) return FALSE;
+#endif
+    i--;
+  }
+  return TRUE;
+}
+
+/*2
+* insert a monomial into a list, avoid duplicates
+* arguments are destroyed
+*/
+static poly p_Insert(poly p1, poly p2, const ring R)
+{
+  poly a1, p, a2, a;
+  int c;
+
+  if (p1==NULL) return p2;
+  if (p2==NULL) return p1;
+  a1 = p1;
+  a2 = p2;
+  a = p  = p_One(R);
+  loop
+  {
+    c = p_Cmp(a1, a2, R);
+    if (c == 1)
+    {
+      a = pNext(a) = a1;
+      pIter(a1);
+      if (a1==NULL)
+      {
+        pNext(a) = a2;
+        break;
+      }
+    }
+    else if (c == -1)
+    {
+      a = pNext(a) = a2;
+      pIter(a2);
+      if (a2==NULL)
+      {
+        pNext(a) = a1;
+        break;
+      }
+    }
+    else
+    {
+      p_LmDelete(&a2, R);
+      a = pNext(a) = a1;
+      pIter(a1);
+      if (a1==NULL)
+      {
+        pNext(a) = a2;
+        break;
+      }
+      else if (a2==NULL)
+      {
+        pNext(a) = a1;
+        break;
+      }
+    }
+  }
+  p_LmDelete(&p, R);
+  return p;
+}
+
+/*2
+*if what == xy the result is the list of all different power products
+*    x^i*y^j (i, j >= 0) that appear in fro
+*/
+static poly mp_Select (poly fro, poly what, const ring R)
+{
+  int i;
+  poly h, res;
+  res = NULL;
+  while (fro!=NULL)
+  {
+    h = p_One(R);
+    for (i=1; i<=rVar(R); i++)
+      p_SetExp(h,i, p_GetExp(fro,i, R) * p_GetExp(what, i, R), R);
+    p_SetComp(h, p_GetComp(fro, R), R);
+    p_Setm(h, R);
+    res = p_Insert(h, res, R);
+    fro = fro->next;
+  }
+  return res;
+}
+
+/*
+*static void ppp(matrix a)
+*{
+*  int j,i,r=a->nrows,c=a->ncols;
+*  for(j=1;j<=r;j++)
+*  {
+*    for(i=1;i<=c;i++)
+*    {
+*      if(MATELEM(a,j,i)!=NULL) Print("X");
+*      else Print("0");
+*    }
+*    Print("\n");
+*  }
+*}
+*/
+
+static void mp_PartClean(matrix a, int lr, int lc, const ring R)
+{
+  poly *q1;
+  int i,j;
+
+  for (i=lr-1;i>=0;i--)
+  {
+    q1 = &(a->m)[i*a->ncols];
+    for (j=lc-1;j>=0;j--) if(q1[j]) p_Delete(&q1[j], R);
+  }
+}
+
+BOOLEAN mp_IsDiagUnit(matrix U, const ring R)
+{
+  if(MATROWS(U)!=MATCOLS(U))
+    return FALSE;
+  for(int i=MATCOLS(U);i>=1;i--)
+  {
+    for(int j=MATCOLS(U); j>=1; j--)
+    {
+      if (i==j)
+      {
+        if (!p_IsUnit(MATELEM(U,i,i), R)) return FALSE;
+      }
+      else if (MATELEM(U,i,j)!=NULL) return FALSE;
+    }
+  }
+  return TRUE;
+}
+
+void iiWriteMatrix(matrix im, const char *n, int dim, const ring r, int spaces)
+{
+  int i,ii = MATROWS(im)-1;
+  int j,jj = MATCOLS(im)-1;
+  poly *pp = im->m;
+
+  for (i=0; i<=ii; i++)
+  {
+    for (j=0; j<=jj; j++)
+    {
+      if (spaces>0)
+        Print("%-*.*s",spaces,spaces," ");
+      if (dim == 2) Print("%s[%u,%u]=",n,i+1,j+1);
+      else if (dim == 1) Print("%s[%u]=",n,j+1);
+      else if (dim == 0) Print("%s=",n);
+      if ((i<ii)||(j<jj)) p_Write(*pp++, r);
+      else                p_Write0(*pp, r);
+    }
+  }
+}
+
+char * iiStringMatrix(matrix im, int dim, const ring r, char ch)
+{
+  int i,ii = MATROWS(im);
+  int j,jj = MATCOLS(im);
+  poly *pp = im->m;
+  char ch_s[2];
+  ch_s[0]=ch;
+  ch_s[1]='\0';
+
+  StringSetS("");
+
+  for (i=0; i<ii; i++)
+  {
+    for (j=0; j<jj; j++)
+    {
+      p_String0(*pp++, r);
+      StringAppendS(ch_s);
+      if (dim > 1) StringAppendS("\n");
+    }
+  }
+  char *s=StringEndS();
+  s[strlen(s)- (dim > 1 ? 2 : 1)]='\0';
+  return s;
+}
+
+void   mp_Delete(matrix* a, const ring r)
+{
+  id_Delete((ideal *) a, r);
+}
+
+/*
+* C++ classes for Bareiss algorithm
+*/
+class row_col_weight
+{
+  private:
+  int ym, yn;
+  public:
+  float *wrow, *wcol;
+  row_col_weight() : ym(0) {}
+  row_col_weight(int, int);
+  ~row_col_weight();
+};
+
+row_col_weight::row_col_weight(int i, int j)
+{
+  ym = i;
+  yn = j;
+  wrow = (float *)omAlloc(i*sizeof(float));
+  wcol = (float *)omAlloc(j*sizeof(float));
+}
+row_col_weight::~row_col_weight()
+{
+  if (ym!=0)
+  {
+    omFreeSize((ADDRESS)wcol, yn*sizeof(float));
+    omFreeSize((ADDRESS)wrow, ym*sizeof(float));
+  }
+}
+
+/*2
+*  a submatrix M of a matrix X[m,n]:
+*    0 <= i < s_m <= a_m
+*    0 <= j < s_n <= a_n
+*    M = ( Xarray[qrow[i],qcol[j]] )
+*    if a_m = a_n and s_m = s_n
+*      det(X) = sign*div^(s_m-1)*det(M)
+*    resticted pivot for elimination
+*      0 <= j < piv_s
+*/
+class mp_permmatrix
+{
+  private:
+  int       a_m, a_n, s_m, s_n, sign, piv_s;
+  int       *qrow, *qcol;
+  poly      *Xarray;
+  ring _R;
+  void mpInitMat();
+  poly * mpRowAdr(int r)
+  { return &(Xarray[a_n*qrow[r]]); }
+  poly * mpColAdr(int c)
+  { return &(Xarray[qcol[c]]); }
+  void mpRowWeight(float *);
+  void mpColWeight(float *);
+  void mpRowSwap(int, int);
+  void mpColSwap(int, int);
+  public:
+  mp_permmatrix() : a_m(0) {}
+  mp_permmatrix(matrix, ring);
+  mp_permmatrix(mp_permmatrix *);
+  ~mp_permmatrix();
+  int mpGetRow();
+  int mpGetCol();
+  int mpGetRdim() { return s_m; }
+  int mpGetCdim() { return s_n; }
+  int mpGetSign() { return sign; }
+  void mpSetSearch(int s);
+  void mpSaveArray() { Xarray = NULL; }
+  poly mpGetElem(int, int);
+  void mpSetElem(poly, int, int);
+  void mpDelElem(int, int);
+  void mpElimBareiss(poly);
+  int mpPivotBareiss(row_col_weight *);
+  int mpPivotRow(row_col_weight *, int);
+  void mpToIntvec(intvec *);
+  void mpRowReorder();
+  void mpColReorder();
+};
+mp_permmatrix::mp_permmatrix(matrix A, ring R) : sign(1)
+{
+  a_m = A->nrows;
+  a_n = A->ncols;
+  this->mpInitMat();
+  Xarray = A->m;
+  _R=R;
+}
+
+mp_permmatrix::mp_permmatrix(mp_permmatrix *M)
+{
+  poly p, *athis, *aM;
+  int i, j;
+
+  _R=M->_R;
+  a_m = M->s_m;
+  a_n = M->s_n;
+  sign = M->sign;
+  this->mpInitMat();
+  Xarray = (poly *)omAlloc0(a_m*a_n*sizeof(poly));
+  for (i=a_m-1; i>=0; i--)
+  {
+    athis = this->mpRowAdr(i);
+    aM = M->mpRowAdr(i);
+    for (j=a_n-1; j>=0; j--)
+    {
+      p = aM[M->qcol[j]];
+      if (p)
+      {
+        athis[j] = p_Copy(p,_R);
+      }
+    }
+  }
+}
+
+mp_permmatrix::~mp_permmatrix()
+{
+  int k;
+
+  if (a_m != 0)
+  {
+    omFreeSize((ADDRESS)qrow,a_m*sizeof(int));
+    omFreeSize((ADDRESS)qcol,a_n*sizeof(int));
+    if (Xarray != NULL)
+    {
+      for (k=a_m*a_n-1; k>=0; k--)
+        p_Delete(&Xarray[k],_R);
+      omFreeSize((ADDRESS)Xarray,a_m*a_n*sizeof(poly));
+    }
+  }
+}
+
+
+static float mp_PolyWeight(poly p, const ring r);
+void mp_permmatrix::mpColWeight(float *wcol)
+{
+  poly p, *a;
+  int i, j;
+  float count;
+
+  for (j=s_n; j>=0; j--)
+  {
+    a = this->mpColAdr(j);
+    count = 0.0;
+    for(i=s_m; i>=0; i--)
+    {
+      p = a[a_n*qrow[i]];
+      if (p)
+        count += mp_PolyWeight(p,_R);
+    }
+    wcol[j] = count;
+  }
+}
+void mp_permmatrix::mpRowWeight(float *wrow)
+{
+  poly p, *a;
+  int i, j;
+  float count;
+
+  for (i=s_m; i>=0; i--)
+  {
+    a = this->mpRowAdr(i);
+    count = 0.0;
+    for(j=s_n; j>=0; j--)
+    {
+      p = a[qcol[j]];
+      if (p)
+        count += mp_PolyWeight(p,_R);
+    }
+    wrow[i] = count;
+  }
+}
+
+void mp_permmatrix::mpRowSwap(int i1, int i2)
+{
+   poly p, *a1, *a2;
+   int j;
+
+   a1 = &(Xarray[a_n*i1]);
+   a2 = &(Xarray[a_n*i2]);
+   for (j=a_n-1; j>= 0; j--)
+   {
+     p = a1[j];
+     a1[j] = a2[j];
+     a2[j] = p;
+   }
+}
+
+void mp_permmatrix::mpColSwap(int j1, int j2)
+{
+   poly p, *a1, *a2;
+   int i, k = a_n*a_m;
+
+   a1 = &(Xarray[j1]);
+   a2 = &(Xarray[j2]);
+   for (i=0; i< k; i+=a_n)
+   {
+     p = a1[i];
+     a1[i] = a2[i];
+     a2[i] = p;
+   }
+}
+void mp_permmatrix::mpInitMat()
+{
+  int k;
+
+  s_m = a_m;
+  s_n = a_n;
+  piv_s = 0;
+  qrow = (int *)omAlloc(a_m*sizeof(int));
+  qcol = (int *)omAlloc(a_n*sizeof(int));
+  for (k=a_m-1; k>=0; k--) qrow[k] = k;
+  for (k=a_n-1; k>=0; k--) qcol[k] = k;
+}
+
+void mp_permmatrix::mpColReorder()
+{
+  int k, j, j1, j2;
+
+  if (a_n > a_m)
+    k = a_n - a_m;
+  else
+    k = 0;
+  for (j=a_n-1; j>=k; j--)
+  {
+    j1 = qcol[j];
+    if (j1 != j)
+    {
+      this->mpColSwap(j1, j);
+      j2 = 0;
+      while (qcol[j2] != j) j2++;
+      qcol[j2] = j1;
+    }
+  }
+}
+
+void mp_permmatrix::mpRowReorder()
+{
+  int k, i, i1, i2;
+
+  if (a_m > a_n)
+    k = a_m - a_n;
+  else
+    k = 0;
+  for (i=a_m-1; i>=k; i--)
+  {
+    i1 = qrow[i];
+    if (i1 != i)
+    {
+      this->mpRowSwap(i1, i);
+      i2 = 0;
+      while (qrow[i2] != i) i2++;
+      qrow[i2] = i1;
+    }
+  }
+}
+
+/*
+* perform replacement for pivot strategy in Bareiss algorithm
+* change sign of determinant
+*/
+static void mpReplace(int j, int n, int &sign, int *perm)
+{
+  int k;
+
+  if (j != n)
+  {
+    k = perm[n];
+    perm[n] = perm[j];
+    perm[j] = k;
+    sign = -sign;
+  }
+}
+/*2
+* pivot strategy for Bareiss algorithm
+*/
+int mp_permmatrix::mpPivotBareiss(row_col_weight *C)
+{
+  poly p, *a;
+  int i, j, iopt, jopt;
+  float sum, f1, f2, fo, r, ro, lp;
+  float *dr = C->wrow, *dc = C->wcol;
+
+  fo = 1.0e20;
+  ro = 0.0;
+  iopt = jopt = -1;
+
+  s_n--;
+  s_m--;
+  if (s_m == 0)
+    return 0;
+  if (s_n == 0)
+  {
+    for(i=s_m; i>=0; i--)
+    {
+      p = this->mpRowAdr(i)[qcol[0]];
+      if (p)
+      {
+        f1 = mp_PolyWeight(p,_R);
+        if (f1 < fo)
+        {
+          fo = f1;
+          if (iopt >= 0)
+            p_Delete(&(this->mpRowAdr(iopt)[qcol[0]]),_R);
+          iopt = i;
+        }
+        else
+          p_Delete(&(this->mpRowAdr(i)[qcol[0]]),_R);
+      }
+    }
+    if (iopt >= 0)
+      mpReplace(iopt, s_m, sign, qrow);
+    return 0;
+  }
+  this->mpRowWeight(dr);
+  this->mpColWeight(dc);
+  sum = 0.0;
+  for(i=s_m; i>=0; i--)
+    sum += dr[i];
+  for(i=s_m; i>=0; i--)
+  {
+    r = dr[i];
+    a = this->mpRowAdr(i);
+    for(j=s_n; j>=0; j--)
+    {
+      p = a[qcol[j]];
+      if (p)
+      {
+        lp = mp_PolyWeight(p,_R);
+        ro = r - lp;
+        f1 = ro * (dc[j]-lp);
+        if (f1 != 0.0)
+        {
+          f2 = lp * (sum - ro - dc[j]);
+          f2 += f1;
+        }
+        else
+          f2 = lp-r-dc[j];
+        if (f2 < fo)
+        {
+          fo = f2;
+          iopt = i;
+          jopt = j;
+        }
+      }
+    }
+  }
+  if (iopt < 0)
+    return 0;
+  mpReplace(iopt, s_m, sign, qrow);
+  mpReplace(jopt, s_n, sign, qcol);
+  return 1;
+}
+poly mp_permmatrix::mpGetElem(int r, int c)
+{
+  return Xarray[a_n*qrow[r]+qcol[c]];
+}
+
+/*
+* the Bareiss-type elimination with division by div (div != NULL)
+*/
+void mp_permmatrix::mpElimBareiss(poly div)
+{
+  poly piv, elim, q1, q2, *ap, *a;
+  int i, j, jj;
+
+  ap = this->mpRowAdr(s_m);
+  piv = ap[qcol[s_n]];
+  for(i=s_m-1; i>=0; i--)
+  {
+    a = this->mpRowAdr(i);
+    elim = a[qcol[s_n]];
+    if (elim != NULL)
+    {
+      elim = p_Neg(elim,_R);
+      for (j=s_n-1; j>=0; j--)
+      {
+        q2 = NULL;
+        jj = qcol[j];
+        if (ap[jj] != NULL)
+        {
+          q2 = SM_MULT(ap[jj], elim, div,_R);
+          if (a[jj] != NULL)
+          {
+            q1 = SM_MULT(a[jj], piv, div,_R);
+            p_Delete(&a[jj],_R);
+            q2 = p_Add_q(q2, q1, _R);
+          }
+        }
+        else if (a[jj] != NULL)
+        {
+          q2 = SM_MULT(a[jj], piv, div, _R);
+        }
+        if ((q2!=NULL) && div)
+          SM_DIV(q2, div, _R);
+        a[jj] = q2;
+      }
+      p_Delete(&a[qcol[s_n]], _R);
+    }
+    else
+    {
+      for (j=s_n-1; j>=0; j--)
+      {
+        jj = qcol[j];
+        if (a[jj] != NULL)
+        {
+          q2 = SM_MULT(a[jj], piv, div, _R);
+          p_Delete(&a[jj], _R);
+          if (div)
+            SM_DIV(q2, div, _R);
+          a[jj] = q2;
+        }
+      }
+    }
+  }
+}
+/*
+* weigth of a polynomial, for pivot strategy
+*/
+static float mp_PolyWeight(poly p, const ring r)
+{
+  int i;
+  float res;
+
+  if (pNext(p) == NULL)
+  {
+    res = (float)n_Size(pGetCoeff(p),r->cf);
+    for (i=rVar(r);i>0;i--)
+    {
+      if(p_GetExp(p,i,r)!=0)
+      {
+        res += 2.0;
+        break;
+      }
+    }
+  }
+  else
+  {
+    res = 0.0;
+    do
+    {
+      res += (float)n_Size(pGetCoeff(p),r->cf)+2.0;
+      pIter(p);
+    }
+    while (p);
+  }
+  return res;
+}
+/*
+* find best row
+*/
+static int mp_PivBar(matrix a, int lr, int lc, const ring r)
+{
+  float f1, f2;
+  poly *q1;
+  int i,j,io;
+
+  io = -1;
+  f1 = 1.0e30;
+  for (i=lr-1;i>=0;i--)
+  {
+    q1 = &(a->m)[i*a->ncols];
+    f2 = 0.0;
+    for (j=lc-1;j>=0;j--)
+    {
+      if (q1[j]!=NULL)
+        f2 += mp_PolyWeight(q1[j],r);
+    }
+    if ((f2!=0.0) && (f2<f1))
+    {
+      f1 = f2;
+      io = i;
+    }
+  }
+  if (io<0) return 0;
+  else return io+1;
+}
+
+static void mpSwapRow(matrix a, int pos, int lr, int lc)
+{
+  poly sw;
+  int j;
+  poly* a2 = a->m;
+  poly* a1 = &a2[a->ncols*(pos-1)];
+
+  a2 = &a2[a->ncols*(lr-1)];
+  for (j=lc-1; j>=0; j--)
+  {
+    sw = a1[j];
+    a1[j] = a2[j];
+    a2[j] = sw;
+  }
+}
+
+/*2
+*  prepare one step of 'Bareiss' algorithm
+*  for application in minor
+*/
+static int mp_PrepareRow (matrix a, int lr, int lc, const ring R)
+{
+  int r;
+
+  r = mp_PivBar(a,lr,lc,R);
+  if(r==0) return 0;
+  if(r<lr) mpSwapRow(a, r, lr, lc);
+  return 1;
+}
+
+/*
+* find pivot in the last row
+*/
+static int mp_PivRow(matrix a, int lr, int lc, const ring r)
+{
+  float f1, f2;
+  poly *q1;
+  int j,jo;
+
+  jo = -1;
+  f1 = 1.0e30;
+  q1 = &(a->m)[(lr-1)*a->ncols];
+  for (j=lc-1;j>=0;j--)
+  {
+    if (q1[j]!=NULL)
+    {
+      f2 = mp_PolyWeight(q1[j],r);
+      if (f2<f1)
+      {
+        f1 = f2;
+        jo = j;
+      }
+    }
+  }
+  if (jo<0) return 0;
+  else return jo+1;
+}
+
+static void mpSwapCol(matrix a, int pos, int lr, int lc)
+{
+  poly sw;
+  int j;
+  poly* a2 = a->m;
+  poly* a1 = &a2[pos-1];
+
+  a2 = &a2[lc-1];
+  for (j=a->ncols*(lr-1); j>=0; j-=a->ncols)
+  {
+    sw = a1[j];
+    a1[j] = a2[j];
+    a2[j] = sw;
+  }
+}
+
+/*2
+*  prepare one step of 'Bareiss' algorithm
+*  for application in minor
+*/
+static int mp_PreparePiv (matrix a, int lr, int lc,const ring r)
+{
+  int c;
+
+  c = mp_PivRow(a, lr, lc,r);
+  if(c==0) return 0;
+  if(c<lc) mpSwapCol(a, c, lr, lc);
+  return 1;
+}
+
+static void mp_ElimBar(matrix a0, matrix re, poly div, int lr, int lc, const ring R)
+{
+  int r=lr-1, c=lc-1;
+  poly *b = a0->m, *x = re->m;
+  poly piv, elim, q1, q2, *ap, *a, *q;
+  int i, j;
+
+  ap = &b[r*a0->ncols];
+  piv = ap[c];
+  for(j=c-1; j>=0; j--)
+    if (ap[j] != NULL) ap[j] = p_Neg(ap[j],R);
+  for(i=r-1; i>=0; i--)
+  {
+    a = &b[i*a0->ncols];
+    q = &x[i*re->ncols];
+    if (a[c] != NULL)
+    {
+      elim = a[c];
+      for (j=c-1; j>=0; j--)
+      {
+        q1 = NULL;
+        if (a[j] != NULL)
+        {
+          q1 = sm_MultDiv(a[j], piv, div,R);
+          if (ap[j] != NULL)
+          {
+            q2 = sm_MultDiv(ap[j], elim, div, R);
+            q1 = p_Add_q(q1,q2,R);
+          }
+        }
+        else if (ap[j] != NULL)
+          q1 = sm_MultDiv(ap[j], elim, div, R);
+        if (q1 != NULL)
+        {
+          if (div)
+            sm_SpecialPolyDiv(q1, div,R);
+          q[j] = q1;
+        }
+      }
+    }
+    else
+    {
+      for (j=c-1; j>=0; j--)
+      {
+        if (a[j] != NULL)
+        {
+          q1 = sm_MultDiv(a[j], piv, div, R);
+          if (div)
+            sm_SpecialPolyDiv(q1, div, R);
+          q[j] = q1;
+        }
+      }
+    }
+  }
+}
+
+/*2*/
+/// entries of a are minors and go to result (only if not in R)
+void mp_MinorToResult(ideal result, int &elems, matrix a, int r, int c,
+                     ideal R, const ring)
+{
+  poly *q1;
+  int e=IDELEMS(result);
+  int i,j;
+
+  if (R != NULL)
+  {
+    for (i=r-1;i>=0;i--)
+    {
+      q1 = &(a->m)[i*a->ncols];
+      //for (j=c-1;j>=0;j--)
+      //{
+      //  if (q1[j]!=NULL) q1[j] = kNF(R,currRing->qideal,q1[j]);
+      //}
+    }
+  }
+  for (i=r-1;i>=0;i--)
+  {
+    q1 = &(a->m)[i*a->ncols];
+    for (j=c-1;j>=0;j--)
+    {
+      if (q1[j]!=NULL)
+      {
+        if (elems>=e)
+        {
+          pEnlargeSet(&(result->m),e,e);
+          e += e;
+          IDELEMS(result) =e;
+        }
+        result->m[elems] = q1[j];
+        q1[j] = NULL;
+        elems++;
+      }
+    }
+  }
+}
+/*
+// from  linalg_from_matpol.cc: TODO: compare with above & remove...
+void mp_MinorToResult(ideal result, int &elems, matrix a, int r, int c,
+                     ideal R, const ring R)
+{
+  poly *q1;
+  int e=IDELEMS(result);
+  int i,j;
+
+  if (R != NULL)
+  {
+    for (i=r-1;i>=0;i--)
+    {
+      q1 = &(a->m)[i*a->ncols];
+      for (j=c-1;j>=0;j--)
+      {
+        if (q1[j]!=NULL) q1[j] = kNF(R,currRing->qideal,q1[j]);
+      }
+    }
+  }
+  for (i=r-1;i>=0;i--)
+  {
+    q1 = &(a->m)[i*a->ncols];
+    for (j=c-1;j>=0;j--)
+    {
+      if (q1[j]!=NULL)
+      {
+        if (elems>=e)
+        {
+          if(e<SIZE_OF_SYSTEM_PAGE)
+          {
+            pEnlargeSet(&(result->m),e,e);
+            e += e;
+          }
+          else
+          {
+            pEnlargeSet(&(result->m),e,SIZE_OF_SYSTEM_PAGE);
+            e += SIZE_OF_SYSTEM_PAGE;
+          }
+          IDELEMS(result) =e;
+        }
+        result->m[elems] = q1[j];
+        q1[j] = NULL;
+        elems++;
+      }
+    }
+  }
+}
+*/
+
+static void mpFinalClean(matrix a)
+{
+  omFreeSize((ADDRESS)a->m,a->nrows*a->ncols*sizeof(poly));
+  omFreeBin((ADDRESS)a, sip_sideal_bin);
+}
+
+/*2*/
+/// produces recursively the ideal of all arxar-minors of a
+void mp_RecMin(int ar,ideal result,int &elems,matrix a,int lr,int lc,
+              poly barDiv, ideal R, const ring r)
+{
+  int k;
+  int kr=lr-1,kc=lc-1;
+  matrix nextLevel=mpNew(kr,kc);
+
+  loop
+  {
+/*--- look for an optimal row and bring it to last position ------------*/
+    if(mp_PrepareRow(a,lr,lc,r)==0) break;
+/*--- now take all pivots from the last row ------------*/
+    k = lc;
+    loop
+    {
+      if(mp_PreparePiv(a,lr,k,r)==0) break;
+      mp_ElimBar(a,nextLevel,barDiv,lr,k,r);
+      k--;
+      if (ar>1)
+      {
+        mp_RecMin(ar-1,result,elems,nextLevel,kr,k,a->m[kr*a->ncols+k],R,r);
+        mp_PartClean(nextLevel,kr,k, r);
+      }
+      else mp_MinorToResult(result,elems,nextLevel,kr,k,R,r);
+      if (ar>k-1) break;
+    }
+    if (ar>=kr) break;
+/*--- now we have to take out the last row...------------*/
+    lr = kr;
+    kr--;
+  }
+  mpFinalClean(nextLevel);
+}
+/*
+// from  linalg_from_matpol.cc: TODO: compare with above & remove...
+void mp_RecMin(int ar,ideal result,int &elems,matrix a,int lr,int lc,
+              poly barDiv, ideal R, const ring R)
+{
+  int k;
+  int kr=lr-1,kc=lc-1;
+  matrix nextLevel=mpNew(kr,kc);
+
+  loop
+  {
+// --- look for an optimal row and bring it to last position ------------
+    if(mpPrepareRow(a,lr,lc)==0) break;
+// --- now take all pivots from the last row ------------
+    k = lc;
+    loop
+    {
+      if(mpPreparePiv(a,lr,k)==0) break;
+      mpElimBar(a,nextLevel,barDiv,lr,k);
+      k--;
+      if (ar>1)
+      {
+        mpRecMin(ar-1,result,elems,nextLevel,kr,k,a->m[kr*a->ncols+k],R);
+        mpPartClean(nextLevel,kr,k);
+      }
+      else mpMinorToResult(result,elems,nextLevel,kr,k,R);
+      if (ar>k-1) break;
+    }
+    if (ar>=kr) break;
+// --- now we have to take out the last row...------------
+    lr = kr;
+    kr--;
+  }
+  mpFinalClean(nextLevel);
+}
+*/
+
+/*2*/
+/// returns the determinant of the matrix m;
+/// uses Bareiss algorithm
+poly mp_DetBareiss (matrix a, const ring r)
+{
+  int s;
+  poly div, res;
+  if (MATROWS(a) != MATCOLS(a))
+  {
+    Werror("det of %d x %d matrix",MATROWS(a),MATCOLS(a));
+    return NULL;
+  }
+  matrix c = mp_Copy(a,r);
+  mp_permmatrix *Bareiss = new mp_permmatrix(c,r);
+  row_col_weight w(Bareiss->mpGetRdim(), Bareiss->mpGetCdim());
+
+  /* Bareiss */
+  div = NULL;
+  while(Bareiss->mpPivotBareiss(&w))
+  {
+    Bareiss->mpElimBareiss(div);
+    div = Bareiss->mpGetElem(Bareiss->mpGetRdim(), Bareiss->mpGetCdim());
+  }
+  Bareiss->mpRowReorder();
+  Bareiss->mpColReorder();
+  Bareiss->mpSaveArray();
+  s = Bareiss->mpGetSign();
+  delete Bareiss;
+
+  /* result */
+  res = MATELEM(c,1,1);
+  MATELEM(c,1,1) = NULL;
+  id_Delete((ideal *)&c,r);
+  if (s < 0)
+    res = p_Neg(res,r);
+  return res;
+}
+/*
+// from  linalg_from_matpol.cc: TODO: compare with above & remove...
+poly mp_DetBareiss (matrix a, const ring R)
+{
+  int s;
+  poly div, res;
+  if (MATROWS(a) != MATCOLS(a))
+  {
+    Werror("det of %d x %d matrix",MATROWS(a),MATCOLS(a));
+    return NULL;
+  }
+  matrix c = mp_Copy(a, R);
+  mp_permmatrix *Bareiss = new mp_permmatrix(c, R);
+  row_col_weight w(Bareiss->mpGetRdim(), Bareiss->mpGetCdim());
+
+  // Bareiss
+  div = NULL;
+  while(Bareiss->mpPivotBareiss(&w))
+  {
+    Bareiss->mpElimBareiss(div);
+    div = Bareiss->mpGetElem(Bareiss->mpGetRdim(), Bareiss->mpGetCdim());
+  }
+  Bareiss->mpRowReorder();
+  Bareiss->mpColReorder();
+  Bareiss->mpSaveArray();
+  s = Bareiss->mpGetSign();
+  delete Bareiss;
+
+  // result
+  res = MATELEM(c,1,1);
+  MATELEM(c,1,1) = NULL;
+  id_Delete((ideal *)&c, R);
+  if (s < 0)
+    res = p_Neg(res, R);
+  return res;
+}
+*/
+
+/*2
+* compute all ar-minors of the matrix a
+*/
+matrix mp_Wedge(matrix a, int ar, const ring R)
+{
+  int     i,j,k,l;
+  int *rowchoise,*colchoise;
+  BOOLEAN rowch,colch;
+  matrix result;
+  matrix tmp;
+  poly p;
+
+  i = binom(a->nrows,ar);
+  j = binom(a->ncols,ar);
+
+  rowchoise=(int *)omAlloc(ar*sizeof(int));
+  colchoise=(int *)omAlloc(ar*sizeof(int));
+  result = mpNew(i,j);
+  tmp    = mpNew(ar,ar);
+  l = 1; /* k,l:the index in result*/
+  idInitChoise(ar,1,a->nrows,&rowch,rowchoise);
+  while (!rowch)
+  {
+    k=1;
+    idInitChoise(ar,1,a->ncols,&colch,colchoise);
+    while (!colch)
+    {
+      for (i=1; i<=ar; i++)
+      {
+        for (j=1; j<=ar; j++)
+        {
+          MATELEM(tmp,i,j) = MATELEM(a,rowchoise[i-1],colchoise[j-1]);
+        }
+      }
+      p = mp_DetBareiss(tmp, R);
+      if ((k+l) & 1) p=p_Neg(p, R);
+      MATELEM(result,l,k) = p;
+      k++;
+      idGetNextChoise(ar,a->ncols,&colch,colchoise);
+    }
+    idGetNextChoise(ar,a->nrows,&rowch,rowchoise);
+    l++;
+  }
+
+  /*delete the matrix tmp*/
+  for (i=1; i<=ar; i++)
+  {
+    for (j=1; j<=ar; j++) MATELEM(tmp,i,j) = NULL;
+  }
+  id_Delete((ideal *) &tmp, R);
+  return (result);
+}
diff --git a/libpolys/polys/matpol.h b/libpolys/polys/matpol.h
new file mode 100644
index 0000000..6038374
--- /dev/null
+++ b/libpolys/polys/matpol.h
@@ -0,0 +1,95 @@
+#ifndef MATPOL_H
+#define MATPOL_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT
+*/
+
+// #include <kernel/structs.h>
+#include <polys/monomials/ring.h>
+
+// THIS IS REALLY DIRTY: ip_smatrix HAS TO BE IDENTICAL TO ip_sideal
+// SO, DON'T CHANGE THE DECLARATION OF ip_smatrix
+class ip_smatrix
+{
+  public:
+
+  poly *m;
+  long rank;
+  int nrows;
+  int ncols;
+
+  inline int& rows() { return nrows; }
+  inline int& cols() { return ncols; }
+
+  #define MATROWS(i) ((i)->nrows)
+  #define MATCOLS(i) ((i)->ncols)
+  #define MATELEM(mat,i,j) ((mat)->m)[MATCOLS((mat)) * ((i)-1) + (j)-1]
+};
+
+typedef ip_smatrix *       matrix;
+
+matrix mpNew(int r, int c);
+static inline matrix mp_New(int r, int c){ return mpNew(r,c); }
+
+// matrix mpCopy(matrix a);
+void   mp_Delete(matrix* a, const ring r);
+matrix mp_Copy(const matrix a, const ring rSrc, const ring rDst);
+
+matrix mp_Copy(matrix a, const ring r);
+// static inline matrix mp_Copy(matrix a, const ring r){ return mp_Copy(a, r, r); }
+
+matrix mp_InitP(int r, int c, poly p, const ring R);
+matrix mp_InitI(int r, int c, int v, const ring R);
+matrix mp_MultI(matrix a, int f, const ring r);
+matrix mp_MultP(matrix a, poly p, const ring r);
+matrix pMultMp(poly p, matrix a, const ring r);
+matrix mp_Add(matrix a, matrix b, const ring r);
+matrix mp_Sub(matrix a, matrix b, const ring r);
+matrix mp_Mult(matrix a, matrix b, const ring r);
+matrix mp_Transp(matrix a, const ring r);
+BOOLEAN mp_Equal(matrix a, matrix b, const ring r);
+poly mp_Trace ( matrix a, const ring r);
+poly TraceOfProd ( matrix a, matrix b, int n, const ring r);
+
+// poly mp_Det (matrix m, const ring r);
+matrix mp_Wedge(matrix a, int ar, const ring r);
+
+// BOOLEAN mpJacobi(leftv res,leftv a);
+// BOOLEAN mpKoszul(leftv res,leftv b/*in*/, leftv c/*ip*/, leftv id=NULL);
+
+poly mp_DetBareiss (matrix a, const ring r);
+
+//matrix mp_Homogen(matrix a, int v, const ring r);
+
+void   mp_Monomials(matrix c, int r, int var, matrix m, const ring R);
+
+/// corresponds to Maple's coeffs:
+/// var has to be the number of a variable
+matrix mp_Coeffs(ideal I, int var, const ring r);
+
+matrix mp_CoeffProc (poly f, poly vars, const ring r);
+/// corresponds to Macauley's coef:
+/// the exponent vector of vars has to contain the variables, eg 'xy';
+/// then the poly f is searched for monomials in x and y, these monimials
+/// are written to the first row of the matrix co.
+/// the second row of co contains the respective factors in f.
+/// Thus f = sum co[1,i]*co[2,i], i = 1..cols, rows equals 2.
+void mp_Coef2(poly v, poly vars, matrix *c, matrix *m, const ring r);
+
+/// for minors with Bareiss
+void mp_RecMin(int, ideal, int &, matrix, int, int, poly, ideal, const ring);
+void mp_MinorToResult(ideal, int &, matrix, int, int, ideal, const ring);
+
+BOOLEAN mp_IsDiagUnit(matrix U, const ring r);
+
+/// set spaces to zero by default
+void iiWriteMatrix(matrix im, const char *n, int dim, const ring r, int spaces);
+
+char * iiStringMatrix(matrix im, int dim, const ring r, char ch=',');
+
+extern omBin ip_smatrix_bin;
+
+#endif/* MATPOL_H */
diff --git a/libpolys/polys/mod_raw.cc b/libpolys/polys/mod_raw.cc
new file mode 100644
index 0000000..a199648
--- /dev/null
+++ b/libpolys/polys/mod_raw.cc
@@ -0,0 +1,288 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+ * ABSTRACT: machine depend code for dynamic modules
+ *
+ * Provides: dynl_check_opened()
+ *           dynl_open()
+ *           dynl_sym()
+ *           dynl_error()
+ *           dynl_close()
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <unistd.h>
+
+
+
+
+
+#include <misc/auxiliary.h>
+
+#include <omalloc/omalloc.h>
+
+#include <reporter/reporter.h>
+
+#include <resources/feResource.h>
+
+#include "mod_raw.h"
+
+#ifdef HAVE_STATIC
+#undef HAVE_DL
+#endif
+/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
+#if defined(HAVE_DL)
+
+/*****************************************************************************
+ *
+ * General section
+ * These are just wrappers around the repsective dynl_* calls
+ * which look for the binary in the bin_dir of Singular and ommit warnings if
+ * somethings goes wrong
+ *
+ *****************************************************************************/
+static BOOLEAN warn_handle = FALSE;
+static BOOLEAN warn_proc = FALSE;
+#ifndef DL_TAIL
+#ifdef SING_NDEBUG
+#define DL_TAIL ".so"
+#else
+#define DL_TAIL ".so"
+//#define DL_TAIL "_g.so"
+#endif
+#endif
+
+void* dynl_open_binary_warn(const char* binary_name, const char* msg)
+{
+  void* handle = NULL;
+  char* binary_name_so=NULL;
+  BOOLEAN found=FALSE;
+
+  // try P_PROCS_DIR (%P)
+  char* proc_path = feGetResource('P');
+  if (proc_path != NULL)
+  {
+    char *p;
+    char *q;
+    p=proc_path;
+    int binary_name_so_length = 3 + strlen(DL_TAIL) + strlen(binary_name) + strlen(DIR_SEPP) + strlen(proc_path);
+    binary_name_so = (char *)omAlloc0( binary_name_so_length * sizeof(char) );
+    while((p!=NULL)&&(*p!='\0'))
+    {
+      q=strchr(p,fePathSep);
+      if (q!=NULL) *q='\0';
+      strcpy(binary_name_so,p);
+      if (q!=NULL) *q=fePathSep;
+      strcat(binary_name_so,DIR_SEPP);
+      strcat(binary_name_so,binary_name);
+      strcat(binary_name_so,DL_TAIL);
+      if(!access(binary_name_so, R_OK)) { found=TRUE; break; }
+      if (q!=NULL) p=q+1; else p=NULL;
+    }
+    if (found) handle = dynl_open(binary_name_so);
+  }
+
+  if (handle == NULL && ! warn_handle)
+  {
+    Warn("Could not find dynamic library: %s%s (path %s)",
+            binary_name, DL_TAIL,proc_path);
+    if (found) Warn("Error message from system: %s", dynl_error());
+    if (msg != NULL) Warn("%s", msg);
+    Warn("See the INSTALL section in the Singular manual for details.");
+    warn_handle = TRUE;
+  }
+  omfree((ADDRESS)binary_name_so );
+
+  return  handle;
+}
+
+void* dynl_sym_warn(void* handle, const char* proc, const char* msg)
+{
+  void *proc_ptr = NULL;
+  if (handle != NULL)
+  {
+    proc_ptr = dynl_sym(handle, proc);
+    if (proc_ptr == NULL && ! warn_proc)
+    {
+      Warn("Could load a procedure from a dynamic library");
+      Warn("Error message from system: %s", dynl_error());
+      if (msg != NULL) Warn("%s", msg);
+      Warn("See the INSTALL section in the Singular manual for details.");
+      warn_proc = TRUE;
+    }
+  }
+  return proc_ptr;
+}
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*****************************************************************************
+ * SECTION generic ELF: ix86-linux / alpha-linux / IA64-linux /x86_64_Linux  *
+ *                      SunOS-5 / IRIX-6 / ppcMac-Darwin / FreeeBSD          *
+ *****************************************************************************/
+// relying on gcc to define __ELF__, check with cpp -dM /dev/null
+#if defined(__ELF__)
+#define HAVE_ELF_SYSTEM
+#endif
+
+// Mac OsX is an ELF system, but does not define __ELF__
+#if (defined(__APPLE__) && defined(__MACH__)) && (!defined(HAVE_ELF_SYSTEM))
+#define HAVE_ELF_SYSTEM
+#endif
+
+// Solaris is an ELF system, but does not define __ELF__
+#if defined(__sun) && defined(__SVR4)
+#define HAVE_ELF_SYSTEM
+#endif
+
+#if defined(HAVE_ELF_SYSTEM)
+#include <dlfcn.h>
+#define DL_IMPLEMENTED
+
+static void* kernel_handle = NULL;
+int dynl_check_opened(
+  char *filename    /* I: filename to check */
+  )
+{
+  return dlopen(filename,RTLD_NOW|RTLD_NOLOAD) != NULL;
+}
+
+void *dynl_open(
+  char *filename    /* I: filename to load */
+  )
+{
+// glibc 2.2:
+  if ((filename==NULL) || (dlopen(filename,RTLD_NOW|RTLD_NOLOAD)==NULL))
+    return(dlopen(filename, RTLD_NOW|RTLD_GLOBAL));
+  else
+    Werror("module %s already loaded",filename);
+  return NULL;
+// alternative
+//    return(dlopen(filename, RTLD_NOW|RTLD_GLOBAL));
+}
+
+void *dynl_sym(void *handle, const char *symbol)
+{
+  if (handle == DYNL_KERNEL_HANDLE)
+  {
+    if (kernel_handle == NULL)
+      kernel_handle = dynl_open(NULL);
+    handle = kernel_handle;
+  }
+  return(dlsym(handle, symbol));
+}
+
+int dynl_close (void *handle)
+{
+  return(dlclose (handle));
+}
+
+const char *dynl_error()
+{
+  return(dlerror());
+}
+#endif /* ELF_SYSTEM */
+
+/*****************************************************************************
+ * SECTION HPUX-9/10                                                         *
+ *****************************************************************************/
+#if defined(HPUX_9) || defined(HPUX_10)
+#define DL_IMPLEMENTED
+#include <dl.h>
+
+typedef char *((*func_ptr) ());
+
+int dynl_check_opened(    /* NOTE: untested */
+  char *filename    /* I: filename to check */
+  )
+{
+  struct shl_descriptor *desc;
+  for (int idx = 0; shl_get(idx, &desc) != -1; ++idx)
+  {
+    if (strcmp(filename, desc->filename) == 0) return TRUE;
+  }
+  return FALSE;
+}
+
+void *dynl_open(char *filename)
+{
+  shl_t           handle = shl_load(filename, BIND_DEFERRED, 0);
+
+  return ((void *) handle);
+}
+
+void *dynl_sym(void *handle, const char *symbol)
+{
+  func_ptr        f;
+
+  if (handle == DYNL_KERNEL_HANDLE)
+    handle = PROG_HANDLE;
+
+  if (shl_findsym((shl_t *) & handle, symbol, TYPE_PROCEDURE, &f) == -1)
+  {
+    if (shl_findsym((shl_t *) & handle, symbol, TYPE_UNDEFINED, &f) == -1)
+    {
+      f = (func_ptr) NULL;
+    }
+  }
+  return ((void *)f);
+}
+
+int dynl_close (void *handle)
+{
+  shl_unload((shl_t) handle);
+  return(0);
+}
+
+const char *dynl_error()
+{
+  static char errmsg[] = "shl_load failed";
+
+  return errmsg;
+}
+#endif /* HPUX_9  or HPUX_10 */
+
+/*****************************************************************************
+ * SECTION generic: dynamic madules not available
+ *****************************************************************************/
+#ifndef DL_IMPLEMENTED
+
+int dynl_check_opened(char *filename)
+{
+  return FALSE;
+}
+
+void *dynl_open(char *filename)
+{
+  return(NULL);
+}
+
+void *dynl_sym(void *handle, const char *symbol)
+{
+  return(NULL);
+}
+
+int dynl_close (void *handle)
+{
+  return(0);
+}
+
+const char *dynl_error()
+{
+  static char errmsg[] = "support for dynamic loading not implemented";
+  return errmsg;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAVE_DL */
diff --git a/libpolys/polys/mod_raw.h b/libpolys/polys/mod_raw.h
new file mode 100644
index 0000000..6c5780a
--- /dev/null
+++ b/libpolys/polys/mod_raw.h
@@ -0,0 +1,44 @@
+#ifndef MOD_RAW_H
+#define MOD_RAW_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+ * ABSTRACT: machine depend code for dynamic modules
+ *
+ * Provides: dynl_check_opened()
+ *           dynl_open()
+ *           dynl_sym()
+ *           dynl_error()
+ *           dunl_close()
+*/
+
+typedef enum { LT_NONE, LT_NOTFOUND, LT_SINGULAR, LT_ELF, LT_HPUX, LT_MACH_O, LT_BUILTIN} lib_types;
+
+
+#if defined(HAVE_DL)
+#ifdef __cplusplus
+void* dynl_open_binary_warn(const char* binary_name, const char* msg = NULL );
+void* dynl_sym_warn(void* handle, const char* proc, const char* msg = NULL );
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+int          dynl_check_opened(char* filename);
+void *       dynl_open(char *filename);
+// if handle == DYNL_KERNEL_HANDLE, then symbol is searched for
+// in kernel of program
+#define DYNL_KERNEL_HANDLE ((void*) 0x1)
+void *       dynl_sym(void *handle, const char *symbol);
+int          dynl_close (void *handle);
+const char * dynl_error();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAVE_DL */
+
+
+#endif /* MOD_RAW_H */
diff --git a/libpolys/polys/monomials/maps.cc b/libpolys/polys/monomials/maps.cc
new file mode 100644
index 0000000..417a19a
--- /dev/null
+++ b/libpolys/polys/monomials/maps.cc
@@ -0,0 +1,355 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT - the mapping of polynomials to other rings
+*/
+
+#include <omalloc/omalloc.h>
+
+
+
+
+#include <misc/auxiliary.h>
+#include <misc/options.h>
+
+#include <coeffs/coeffs.h>
+#include <coeffs/numbers.h>
+
+#include <polys/monomials/p_polys.h>
+#include <polys/monomials/ring.h>
+#include <polys/simpleideals.h>
+#include <polys/prCopy.h>
+// #include <polys/ext_fields/longtrans.h>
+#include <polys/monomials/maps.h>
+
+#ifdef HAVE_PLURAL
+#include <polys/nc/nc.h>
+#endif
+
+// This is a very dirty way to "normalize" numbers w.r.t. a
+// MinPoly
+
+#define MAX_MAP_DEG 128
+
+/*2
+* copy a map
+*/
+map maCopy(map theMap, const ring r)
+{
+  int i;
+  map m=(map)idInit(IDELEMS(theMap),0);
+  for (i=IDELEMS(theMap)-1; i>=0; i--)
+      m->m[i] = p_Copy(theMap->m[i],r);
+  m->preimage=omStrDup(theMap->preimage);
+  return m;
+}
+
+
+/*2
+* return the image of var(v)^pExp, where var(v) maps to p
+*/
+poly maEvalVariable(poly p, int v,int pExp, ideal s, const ring dst_r)
+{
+  if (pExp==1)
+    return p_Copy(p,dst_r);
+
+  poly res;
+
+  if((s!=NULL)&&(pExp<MAX_MAP_DEG))
+  {
+    int j=2;
+    poly p0=p;
+    // find starting point
+    if(MATELEM(s,v,1)==NULL)
+    {
+      MATELEM(s,v,1)=p_Copy(p/*theMap->m[v-1]*/,dst_r);
+    }
+    else
+    {
+      while((j<=pExp)&&(MATELEM(s,v,j)!=NULL))
+      {
+        j++;
+      }
+      p0=MATELEM(s,v,j-1);
+    }
+    // multiply
+    for(;j<=pExp;j++)
+    {
+      p0=MATELEM(s,v,j)=pp_Mult_qq(p0, p,dst_r);
+      p_Normalize(p0, dst_r);
+    }
+    res=p_Copy(p0/*MATELEM(s,v,pExp)*/,dst_r);
+  }
+  else //if ((p->next!=NULL)&&(p->next->next==NULL))
+  {
+    res=p_Power(p_Copy(p,dst_r),pExp,dst_r);
+  }
+  return res;
+}
+
+static poly maEvalMonom(map theMap, poly p,ring preimage_r, ideal s,
+           nMapFunc nMap, const ring dst_r)
+{
+    p_Test(p,preimage_r);
+    poly q=p_NSet(nMap(pGetCoeff(p),preimage_r->cf,dst_r->cf),dst_r);
+
+    int i;
+    for(i=1;i<=preimage_r->N; i++)
+    {
+      int pExp=p_GetExp( p,i,preimage_r);
+      if (pExp != 0)
+      {
+        if (theMap->m[i-1]!=NULL)
+        {
+          poly p1=theMap->m[i-1];
+          poly pp=maEvalVariable(p1,i,pExp,s,dst_r);
+          q = p_Mult_q(q,pp,dst_r);
+        }
+        else
+        {
+          p_Delete(&q,dst_r);
+          break;
+        }
+      }
+    }
+    int modulComp = p_GetComp( p,preimage_r);
+    if (q!=NULL) p_SetCompP(q,modulComp,dst_r);
+  return q;
+}
+
+poly maEval(map theMap, poly p,ring preimage_r,nMapFunc nMap, ideal s, const ring dst_r)
+{
+  poly result = NULL;
+  int i;
+
+//  for(i=1; i<=preimage_r->N; i++)
+//  {
+//    pTest(theMap->m[i-1]);
+//  }
+//  while (p!=NULL)
+//  {
+//    poly q=maEvalMonom(theMap,p,preimage_r,s);
+//    result = pAdd(result,q);
+//    pIter(p);
+//  }
+  if (p!=NULL)
+  {
+    int l = pLength(p)-1;
+    poly* monoms;
+    if (l>0)
+    {
+      monoms = (poly*) omAlloc(l*sizeof(poly));
+
+      for (i=0; i<l; i++)
+      {
+        monoms[i]=maEvalMonom(theMap,p,preimage_r,s, nMap, dst_r);
+        pIter(p);
+      }
+    }
+    result=maEvalMonom(theMap,p,preimage_r,s, nMap, dst_r);
+    if (l>0)
+    {
+      for(i = l-1; i>=0; i--)
+      {
+        result=p_Add_q(result, monoms[i], dst_r);
+      }
+      omFreeSize((ADDRESS)monoms,l*sizeof(poly));
+    }
+
+    assume(dst_r != NULL);
+    assume(dst_r->cf != NULL);
+
+    if (nCoeff_is_algExt(dst_r->cf))
+      result = p_MinPolyNormalize(result, dst_r);
+  }
+  return result;
+}
+
+void maFindPerm(char const * const * const preim_names, int preim_n, char const * const * const preim_par, int preim_p,
+                char const * const * const names,       int n,       char const * const * const par,       int nop,
+                int * perm, int *par_perm, n_coeffType ch)
+{
+  int i,j;
+  /* find correspondig vars */
+  for (i=0; i<preim_n; i++)
+  {
+    for(j=0; j<n; j++)
+    {
+      if (strcmp(preim_names[i],names[j])==0)
+      {
+        if (BVERBOSE(V_IMAP))
+          Print("// var %s: nr %d -> nr %d\n",preim_names[i],i+1,j+1);
+        /* var i+1 from preimage ring is var j+1  (index j+1) from image ring */
+        perm[i+1]=j+1;
+        break;
+      }
+    }
+    if ((perm[i+1]==0)&&(par!=NULL)
+        // do not consider par of Fq
+         && (ch!=n_GF))
+    {
+      for(j=0; j<nop; j++)
+      {
+        if (strcmp(preim_names[i],par[j])==0)
+        {
+          if (BVERBOSE(V_IMAP))
+            Print("// var %s: nr %d -> par %d\n",preim_names[i],i+1,j+1);
+          /* var i+1 from preimage ring is par j+1 (index j) from image ring */
+          perm[i+1]=-(j+1);
+        }
+      }
+    }
+  }
+  if (par_perm!=NULL)
+  {
+    for (i=0; i<preim_p; i++)
+    {
+      for(j=0; j<n; j++)
+      {
+        if (strcmp(preim_par[i],names[j])==0)
+        {
+          if (BVERBOSE(V_IMAP))
+            Print("// par %s: par %d -> nr %d\n",preim_par[i],i+1,j+1);
+          /*par i+1 from preimage ring is var j+1  (index j+1) from image ring*/
+          par_perm[i]=j+1;
+          break;
+        }
+      }
+      if ((par!=NULL) && (par_perm[i]==0))
+      {
+        for(j=0; j<nop; j++)
+        {
+          if (strcmp(preim_par[i],par[j])==0)
+          {
+            if (BVERBOSE(V_IMAP))
+              Print("// par %s: nr %d -> par %d\n",preim_par[i],i+1,j+1);
+            /*par i+1 from preimage ring is par j+1 (index j) from image ring */
+            par_perm[i]=-(j+1);
+          }
+        }
+      }
+    }
+  }
+}
+
+/*2
+* embeds poly p from the subring r into the current ring
+*/
+poly maIMap(ring r, poly p, const ring dst_r)
+{
+  /* the simplest case:*/
+  if(r==dst_r) return p_Copy(p,dst_r);
+  nMapFunc nMap=n_SetMap(r->cf,dst_r->cf);
+  int *perm=(int *)omAlloc0((r->N+1)*sizeof(int));
+  //int *par_perm=(int *)omAlloc0(rPar(r)*sizeof(int));
+  maFindPerm(r->names, rVar(r), rParameter(r), rPar(r),
+             dst_r->names, rVar(dst_r),rParameter(dst_r), rPar(dst_r),
+             perm,NULL, dst_r->cf->type);
+  poly res=p_PermPoly(p,perm,r,dst_r, nMap /*,par_perm,rPar(r)*/);
+  omFreeSize((ADDRESS)perm,(r->N+1)*sizeof(int));
+  //omFreeSize((ADDRESS)par_perm,rPar(r)*sizeof(int));
+  return res;
+}
+
+/*3
+* find the max. degree in one variable, but not larger than MAX_MAP_DEG
+*/
+int maMaxDeg_Ma(ideal a,ring preimage_r)
+{
+  int i,j;
+  int N = preimage_r->N;
+  poly p;
+  int *m=(int *)omAlloc0(N*sizeof(int));
+
+  for (i=MATROWS(a)*MATCOLS(a)-1;i>=0;i--)
+  {
+    p=a->m[i];
+    //pTest(p); // cannot test p because it is from another ring
+    while(p!=NULL)
+    {
+      for(j=N-1;j>=0;j--)
+      {
+        m[j]=si_max(m[j],(int)p_GetExp( p,j+1,preimage_r));
+        if (m[j]>=MAX_MAP_DEG)
+        {
+          i=MAX_MAP_DEG;
+          goto max_deg_fertig_id;
+        }
+      }
+      pIter(p);
+    }
+  }
+  i=m[0];
+  for(j=N-1;j>0;j--)
+  {
+    i=si_max(i,m[j]);
+  }
+max_deg_fertig_id:
+  omFreeSize((ADDRESS)m,N*sizeof(int));
+  return i;
+}
+
+/*3
+* find the max. degree in one variable, but not larger than MAX_MAP_DEG
+*/
+int maMaxDeg_P(poly p,ring preimage_r)
+{
+  int i,j;
+  int N = preimage_r->N;
+  int *m=(int *)omAlloc0(N*sizeof(int));
+
+//  pTest(p);
+  while(p!=NULL)
+  {
+    for(j=N-1;j>=0;j--)
+    {
+      m[j]=si_max(m[j],(int)p_GetExp(p,j+1,preimage_r));
+      if (m[j]>=MAX_MAP_DEG)
+      {
+        i=MAX_MAP_DEG;
+        goto max_deg_fertig_p;
+      }
+    }
+    pIter(p);
+  }
+  i=m[0];
+  for(j=N-1;j>0;j--)
+  {
+    i=si_max(i,m[j]);
+  }
+max_deg_fertig_p:
+  omFreeSize((ADDRESS)m,N*sizeof(int));
+  return i;
+}
+
+// This is a very dirty way to cancel monoms whose number equals the
+// MinPoly
+poly p_MinPolyNormalize(poly p, const ring r)
+{
+  const coeffs C = r->cf;
+  number one = n_Init(1, C);
+  spolyrec rp;
+
+  poly q = &rp;
+
+  while (p != NULL)
+  {
+    // this returns 0, if p == MinPoly
+    number product = n_Mult(p_GetCoeff(p, r), one, C);
+    if ((product == NULL)||(n_IsZero(product, C)))
+    {
+      p_LmDelete(&p, r);
+    }
+    else
+    {
+      p_SetCoeff(p, product, r);
+      pNext(q) = p;
+      q = p;
+      p = pNext(p);
+    }
+  }
+  pNext(q) = NULL;
+  n_Delete(&one, C);
+  return rp.next;
+}
diff --git a/libpolys/polys/monomials/maps.h b/libpolys/polys/monomials/maps.h
new file mode 100644
index 0000000..f587f7f
--- /dev/null
+++ b/libpolys/polys/monomials/maps.h
@@ -0,0 +1,32 @@
+#ifndef MAPS_H
+#define MAPS_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT - the mapping of polynomials to other rings
+*/
+#include <coeffs/coeffs.h>
+#include <polys/monomials/ring.h>
+//#include <kernel/ideals.h>
+
+struct sip_smap;
+typedef struct sip_smap *         map;
+
+// poly maEval(map theMap, poly p, ring dst_ring, nMapFunc nMap, ideal s=NULL);
+poly maEval(map theMap, poly p,ring preimage_r,nMapFunc nMap, ideal s, const ring dst_r);
+
+map maCopy(map theMap, const ring dst_ring);
+
+poly maIMap(ring src_ring, ring dst_ring, poly p);
+
+void maFindPerm(char const * const * const preim_names, int preim_n, char const * const * const preim_par, int preim_p,
+                char const * const * const names,       int n,       char const * const * const par,       int nop,
+                int * perm, int *par_perm, n_coeffType ch);
+poly pSubstPoly(poly p, int var, poly image);
+ideal  idSubstPoly(ideal id, int n, poly e);
+
+poly p_MinPolyNormalize(poly p, const ring r);
+int maMaxDeg_P(poly p,ring preimage_r);
+int maMaxDeg_Ma(ideal a,ring preimage_r);
+#endif
diff --git a/libpolys/polys/monomials/monomials.cc b/libpolys/polys/monomials/monomials.cc
new file mode 100644
index 0000000..ab5f9ad
--- /dev/null
+++ b/libpolys/polys/monomials/monomials.cc
@@ -0,0 +1,34 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+
+/***************************************************************
+ *
+ * File:       polys-impl.cc
+ * Purpose:    low-level procuders for polys.
+ *
+ * If you touch anything here, you better know what you are doing.
+ * What is here should not be used directly from other routines -- the
+ * encapsulations in polys.[h,cc] should be used, instead.
+ *
+ ***************************************************************/
+#ifndef POLYS_IMPL_CC
+#define POLYS_IMPL_CC
+
+#include <stdio.h>
+#include <string.h>
+
+
+
+
+
+#include <omalloc/omalloc.h>
+#include <misc/auxiliary.h>
+
+#ifdef PDEBUG
+#undef NO_INLINE3
+#define NO_INLINE3
+#endif
+
+
+#endif // POLYS_IMPL_CC
diff --git a/libpolys/polys/monomials/monomials.h b/libpolys/polys/monomials/monomials.h
new file mode 100644
index 0000000..9ac4c7c
--- /dev/null
+++ b/libpolys/polys/monomials/monomials.h
@@ -0,0 +1,276 @@
+#ifndef MONOMIALS_H
+#define MONOMIALS_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT
+*/
+
+#include <omalloc/omalloc.h>
+#include <reporter/reporter.h> // for assume etc.
+
+struct snumber;
+typedef struct snumber *   number;
+
+struct ip_sring;
+typedef struct ip_sring *         ring;
+typedef struct ip_sring const *   const_ring;
+
+/***************************************************************
+ *
+ * definition of the poly structure and its fields
+ *
+ ***************************************************************/
+
+struct spolyrec;
+typedef struct spolyrec *          poly;
+
+struct  spolyrec
+{
+  poly      next;           // next needs to be the first field
+  number    coef;           // and coef the second --- do not change this !!!
+  unsigned long exp[1];     // make sure that exp is aligned
+};
+
+/***************************************************************
+ *
+ * Primitives for accessing and setting fields of a poly
+ * poly must be != NULL
+ *
+ ***************************************************************/
+// next
+#define pNext(p)            ((p)->next)
+#define pIter(p)            (void)((p) = (p)->next)
+
+// coeff
+// #define pGetCoeff(p)        ((p)->coef)
+/// return an alias to the leading coefficient of p
+/// assumes that p != NULL
+/// NOTE: not copy
+static inline number& pGetCoeff(poly p)
+{
+  assume(p != NULL);
+  return p->coef;
+}
+
+#define p_GetCoeff(p,r)     pGetCoeff(p)
+//static inline number& p_GetCoeff(poly p, const ring r)
+//{
+//  assume(r != NULL);
+//  return pGetCoeff(p);
+//}
+
+
+//
+// deletes old coeff before setting the new one???
+#define pSetCoeff0(p,n)     (p)->coef=(n)
+#define p_SetCoeff0(p,n,r)  pSetCoeff0(p,n)
+
+
+#define __p_GetComp(p, r)   (p)->exp[r->pCompIndex]
+#define p_GetComp(p, r)    ((long) (r->pCompIndex >= 0 ? __p_GetComp(p, r) : 0))
+
+
+/***************************************************************
+ *
+ * prepare debugging
+ *
+ ***************************************************************/
+
+#if defined(PDEBUG)
+
+extern BOOLEAN dPolyReportError(poly p, ring r, const char* fmt, ...);
+
+// macros for checking of polys
+#define pAssumeReturn(cond)                                  \
+do                                                          \
+{                                                           \
+  if (! (cond))                                             \
+  {                                                         \
+    dPolyReportError(NULL, NULL, "pAssume violation of: %s", \
+                 #cond);                                    \
+    return FALSE;                                           \
+  }                                                         \
+}                                                           \
+while (0)
+
+#define pAssume(cond)                                        \
+do                                                          \
+{                                                           \
+  if (! (cond))                                             \
+  {                                                         \
+    dPolyReportError(NULL, NULL, "pAssume violation of: %s", \
+                 #cond);                                    \
+  }                                                         \
+}                                                           \
+while (0)
+
+#define _pPolyAssumeReturn(cond, p, r)                       \
+do                                                          \
+{                                                           \
+  if (! (cond))                                             \
+  {                                                         \
+    dPolyReportError(p, r, "pPolyAssume violation of: %s",   \
+                 #cond);                                    \
+    return FALSE;                                           \
+  }                                                         \
+}                                                           \
+while (0)
+
+#define _pPolyAssume(cond,p,r)                                   \
+do                                                              \
+{                                                               \
+  if (! (cond))                                                 \
+  {                                                             \
+    dPolyReportError(p, r, "pPolyAssume violation of: %s",    \
+                 #cond);                                        \
+  }                                                             \
+}                                                               \
+while (0)
+
+#define _pPolyAssumeReturnMsg(cond, msg, p, r)   \
+do                                              \
+{                                               \
+  if (! (cond))                                 \
+  {                                             \
+    dPolyReportError(p, r, "%s ",  msg);        \
+    return FALSE;                               \
+  }                                             \
+}                                               \
+while (0)
+
+#define pPolyAssume(cond)        _pPolyAssume(cond, p, r)
+#define pPolyAssumeReturn(cond)  _pPolyAssumeReturn(cond, p, r)
+#define pPolyAssumeReturnMsg(cond, msg)  _pPolyAssumeReturnMsg(cond, msg, p, r)
+
+#define pFalseReturn(cond)  do {if (! (cond)) return FALSE;} while (0)
+#if (OM_TRACK > 2) && defined(OM_TRACK_CUSTOM)
+#define p_SetRingOfLm(p, r) omSetCustomOfAddr(p, r)
+//void p_SetRingOfLeftv(leftv l, ring r);
+#else
+#define p_SetRingOfLm(p, r) do {} while (0)
+//#define p_SetRingOfLeftv(l, r) do {} while (0)
+#endif
+
+#else // ! defined(PDEBUG)
+#define pFalseReturn(cond)           do {} while (0)
+#define pAssume(cond)                do {} while (0)
+#define pPolyAssume(cond)            do {} while (0)
+#define _pPolyAssume(cond, p,r)      do {} while (0)
+#define pAssumeReturn(cond)          do {} while (0)
+#define pPolyAssumeReturn(cond)      do {} while (0)
+#define _pPolyAssumeReturn(cond,p,r) do {} while (0)
+#define p_SetRingOfLm(p, r)          do {} while (0)
+//#define p_SetRingOfLeftv(l, r)       do {} while (0)
+#endif // defined(PDEBUG)
+
+#if PDEBUG >= 1
+#define pAssume1             pAssume
+#define pPolyAssume1         pPolyAssume
+#define _pPolyAssume1        _pPolyAssume
+#define pAssumeReturn1       pAssumeReturn
+#define pPolyAssumeReturn1   pPolyAssumeReturn
+#define _pPolyAssumeReturn1  _pPolyAssumeReturn
+#define p_LmCheckPolyRing1    p_LmCheckPolyRing
+#define p_CheckRing1        p_CheckRing
+#define pIfThen1          pIfThen
+#else
+#define pAssume1(cond)               do {} while (0)
+#define pPolyAssume1(cond)           do {} while (0)
+#define _pPolyAssume1(cond,p,r)      do {} while (0)
+#define pAssumeReturn1(cond)         do {} while (0)
+#define pPolyAssumeReturn1(cond)     do {} while (0)
+#define _pPolyAssumeReturn1(cond,p,r)do {} while (0)
+#define p_LmCheckPolyRing1(p,r)       do {} while (0)
+#define p_CheckRing1(r)             do {} while (0)
+#define pIfThen1(cond, check)     do {} while (0)
+#endif // PDEBUG >= 1
+
+#if PDEBUG >= 2
+#define pAssume2             pAssume
+#define pPolyAssume2         pPolyAssume
+#define _pPolyAssume2        _pPolyAssume
+#define pAssumeReturn2       pAssumeReturn
+#define pPolyAssumeReturn2   pPolyAssumeReturn
+#define _pPolyAssumeReturn2  _pPolyAssumeReturn
+#define p_LmCheckPolyRing2    p_LmCheckPolyRing
+#define p_CheckRing2        p_CheckRing
+#define pIfThen2          pIfThen
+#else
+#define pAssume2(cond)               do {} while (0)
+#define pPolyAssume2(cond)           do {} while (0)
+#define _pPolyAssume2(cond,p,r)      do {} while (0)
+#define pAssumeReturn2(cond)         do {} while (0)
+#define pPolyAssumeReturn2(cond)     do {} while (0)
+#define _pPolyAssumeReturn2(cond,p,r)do {} while (0)
+#define p_LmCheckPolyRing2(p,r)       do {} while (0)
+#define p_CheckRing2(r)             do {} while (0)
+#define pIfThen2(cond, check)     do {} while (0)
+#endif // PDEBUG >= 2
+
+/***************************************************************
+ *
+ * Macros for low-level allocation
+ *
+ ***************************************************************/
+#ifdef PDEBUG
+#define p_AllocBin(p, bin, r)                   \
+do                                              \
+{                                               \
+  omTypeAllocBin(poly, p, bin);                 \
+  p_SetRingOfLm(p, r);                        \
+}                                               \
+while (0)
+#define p_FreeBinAddr(p, r) p_LmFree(p, r)
+#else
+#define p_AllocBin(p, bin, r)   omTypeAllocBin(poly, p, bin)
+#define p_FreeBinAddr(p, r)     omFreeBinAddr(p)
+#endif
+
+/***************************************************************
+ *
+ * Purpose:    low-level and macro definition of polys
+ *
+ * If you touch anything here, you better know what you are doing.
+ * What is here should not be used directly from other routines -- the
+ * encapsulations in polys.h should be used, instead.
+ *
+ ***************************************************************/
+
+#define POLYSIZE (sizeof(poly) + sizeof(number))
+#define POLYSIZEW (POLYSIZE / sizeof(long))
+#if SIZEOF_LONG == 8
+#define POLY_NEGWEIGHT_OFFSET (((long)0x80000000) << 32)
+#else
+#define POLY_NEGWEIGHT_OFFSET ((long)0x80000000)
+#endif
+
+
+/***************************************************************
+ *
+ * Macros for low-level allocation
+ *
+ ***************************************************************/
+#ifdef PDEBUG
+#define p_AllocBin(p, bin, r)                   \
+do                                              \
+{                                               \
+  omTypeAllocBin(poly, p, bin);                 \
+  p_SetRingOfLm(p, r);                        \
+}                                               \
+while (0)
+#define p_FreeBinAddr(p, r) p_LmFree(p, r)
+#else
+#define p_AllocBin(p, bin, r)   omTypeAllocBin(poly, p, bin)
+#define p_FreeBinAddr(p, r)     omFreeBinAddr(p)
+#endif
+
+/***************************************************************
+ *
+ * Misc macros
+ *
+ ***************************************************************/
+#define rRing_has_Comp(r)   (r->pCompIndex >= 0)
+
+#endif
diff --git a/libpolys/polys/monomials/p_polys.cc b/libpolys/polys/monomials/p_polys.cc
new file mode 100644
index 0000000..4dc1b46
--- /dev/null
+++ b/libpolys/polys/monomials/p_polys.cc
@@ -0,0 +1,4676 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    p_polys.cc
+ *  Purpose: implementation of ring independent poly procedures?
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 8/00
+ *******************************************************************/
+
+#include <ctype.h>
+
+#include <omalloc/omalloc.h>
+
+#include <misc/auxiliary.h>
+
+#include <misc/options.h>
+#include <misc/intvec.h>
+
+
+#include <coeffs/longrat.h> // snumber is needed...
+
+#include <polys/PolyEnumerator.h>
+
+#define TRANSEXT_PRIVATES
+
+#include <polys/ext_fields/transext.h>
+#include <polys/ext_fields/algext.h>
+
+#include <polys/weight.h>
+#include <polys/simpleideals.h>
+
+#include "ring.h"
+#include "p_polys.h"
+
+#include <polys/templates/p_MemCmp.h>
+#include <polys/templates/p_MemAdd.h>
+#include <polys/templates/p_MemCopy.h>
+
+
+// #include <???/ideals.h>
+// #include <???/int64vec.h>
+
+#ifndef SING_NDEBUG
+// #include <???/febase.h>
+#endif
+
+#ifdef HAVE_PLURAL
+#include "nc/nc.h"
+#include "nc/sca.h"
+#endif
+
+#include "coeffrings.h"
+#include "clapsing.h"
+
+#define ADIDEBUG 0
+
+/*
+ * lift ideal with coeffs over Z (mod N) to Q via Farey
+ */
+poly p_Farey(poly p, number N, const ring r)
+{
+  poly h=p_Copy(p,r);
+  poly hh=h;
+  while(h!=NULL)
+  {
+    number c=pGetCoeff(h);
+    pSetCoeff0(h,n_Farey(c,N,r->cf));
+    n_Delete(&c,r->cf);
+    pIter(h);
+  }
+  while((hh!=NULL)&&(n_IsZero(pGetCoeff(hh),r->cf)))
+  {
+    p_LmDelete(&hh,r);
+  }
+  h=hh;
+  while((h!=NULL) && (pNext(h)!=NULL))
+  {
+    if(n_IsZero(pGetCoeff(pNext(h)),r->cf))
+    {
+      p_LmDelete(&pNext(h),r);
+    }
+    else pIter(h);
+  }
+  return hh;
+}
+/*2
+* xx,q: arrays of length 0..rl-1
+* xx[i]: SB mod q[i]
+* assume: char=0
+* assume: q[i]!=0
+* destroys xx
+*/
+poly p_ChineseRemainder(poly *xx, number *x,number *q, int rl, const ring R)
+{
+  poly r,h,hh;
+  int j;
+  poly  res_p=NULL;
+  loop
+  {
+    /* search the lead term */
+    r=NULL;
+    for(j=rl-1;j>=0;j--)
+    {
+      h=xx[j];
+      if ((h!=NULL)
+      &&((r==NULL)||(p_LmCmp(r,h,R)==-1)))
+        r=h;
+    }
+    /* nothing found -> return */
+    if (r==NULL) break;
+    /* create the monomial in h */
+    h=p_Head(r,R);
+    /* collect the coeffs in x[..]*/
+    for(j=rl-1;j>=0;j--)
+    {
+      hh=xx[j];
+      if ((hh!=NULL) && (p_LmCmp(r,hh,R)==0))
+      {
+        x[j]=pGetCoeff(hh);
+        hh=p_LmFreeAndNext(hh,R);
+        xx[j]=hh;
+      }
+      else
+        x[j]=n_Init(0, R);
+    }
+    number n=n_ChineseRemainderSym(x,q,rl,TRUE,R->cf);
+    for(j=rl-1;j>=0;j--)
+    {
+      x[j]=NULL; // n_Init(0...) takes no memory
+    }
+    if (n_IsZero(n,R)) p_Delete(&h,R);
+    else
+    {
+      //Print("new mon:");pWrite(h);
+      p_SetCoeff(h,n,R);
+      pNext(h)=res_p;
+      res_p=h; // building res_p in reverse order!
+    }
+  }
+  res_p=pReverse(res_p);
+  p_Test(res_p, R);
+  return res_p;
+}
+/***************************************************************
+ *
+ * Completing what needs to be set for the monomial
+ *
+ ***************************************************************/
+// this is special for the syz stuff
+static int* _components = NULL;
+static long* _componentsShifted = NULL;
+static int _componentsExternal = 0;
+
+BOOLEAN pSetm_error=0;
+
+#ifndef SING_NDEBUG
+# define MYTEST 0
+#else /* ifndef SING_NDEBUG */
+# define MYTEST 0
+#endif /* ifndef SING_NDEBUG */
+
+void p_Setm_General(poly p, const ring r)
+{
+  p_LmCheckPolyRing(p, r);
+  int pos=0;
+  if (r->typ!=NULL)
+  {
+    loop
+    {
+      unsigned long ord=0;
+      sro_ord* o=&(r->typ[pos]);
+      switch(o->ord_typ)
+      {
+        case ro_dp:
+        {
+          int a,e;
+          a=o->data.dp.start;
+          e=o->data.dp.end;
+          for(int i=a;i<=e;i++) ord+=p_GetExp(p,i,r);
+          p->exp[o->data.dp.place]=ord;
+          break;
+        }
+        case ro_wp_neg:
+          ord=POLY_NEGWEIGHT_OFFSET;
+          // no break;
+        case ro_wp:
+        {
+          int a,e;
+          a=o->data.wp.start;
+          e=o->data.wp.end;
+          int *w=o->data.wp.weights;
+#if 1
+          for(int i=a;i<=e;i++) ord+=((unsigned long)p_GetExp(p,i,r))*((unsigned long)w[i-a]);
+#else
+          long ai;
+          int ei,wi;
+          for(int i=a;i<=e;i++)
+          {
+             ei=p_GetExp(p,i,r);
+             wi=w[i-a];
+             ai=ei*wi;
+             if (ai/ei!=wi) pSetm_error=TRUE;
+             ord+=ai;
+             if (ord<ai) pSetm_error=TRUE;
+          }
+#endif
+          p->exp[o->data.wp.place]=ord;
+          break;
+        }
+        case ro_am:
+        {
+          ord = POLY_NEGWEIGHT_OFFSET;
+          const short a=o->data.am.start;
+          const short e=o->data.am.end;
+          const int * w=o->data.am.weights;
+#if 1
+          for(short i=a; i<=e; i++, w++)
+            ord += ((*w) * p_GetExp(p,i,r));
+#else
+          long ai;
+          int ei,wi;
+          for(short i=a;i<=e;i++)
+          {
+             ei=p_GetExp(p,i,r);
+             wi=w[i-a];
+             ai=ei*wi;
+             if (ai/ei!=wi) pSetm_error=TRUE;
+             ord += ai;
+             if (ord<ai) pSetm_error=TRUE;
+          }
+#endif
+          const int c = p_GetComp(p,r);
+
+          const short len_gen= o->data.am.len_gen;
+
+          if ((c > 0) && (c <= len_gen))
+          {
+            assume( w == o->data.am.weights_m );
+            assume( w[0] == len_gen );
+            ord += w[c];
+          }
+
+          p->exp[o->data.am.place] = ord;
+          break;
+        }
+      case ro_wp64:
+        {
+          int64 ord=0;
+          int a,e;
+          a=o->data.wp64.start;
+          e=o->data.wp64.end;
+          int64 *w=o->data.wp64.weights64;
+          int64 ei,wi,ai;
+          for(int i=a;i<=e;i++)
+          {
+            //Print("exp %d w %d \n",p_GetExp(p,i,r),(int)w[i-a]);
+            //ord+=((int64)p_GetExp(p,i,r))*w[i-a];
+            ei=(int64)p_GetExp(p,i,r);
+            wi=w[i-a];
+            ai=ei*wi;
+            if(ei!=0 && ai/ei!=wi)
+            {
+              pSetm_error=TRUE;
+              #if SIZEOF_LONG == 4
+              Print("ai %lld, wi %lld\n",ai,wi);
+              #else
+              Print("ai %ld, wi %ld\n",ai,wi);
+              #endif
+            }
+            ord+=ai;
+            if (ord<ai)
+            {
+              pSetm_error=TRUE;
+              #if SIZEOF_LONG == 4
+              Print("ai %lld, ord %lld\n",ai,ord);
+              #else
+              Print("ai %ld, ord %ld\n",ai,ord);
+              #endif
+            }
+          }
+          int64 mask=(int64)0x7fffffff;
+          long a_0=(long)(ord&mask); //2^31
+          long a_1=(long)(ord >>31 ); /*(ord/(mask+1));*/
+
+          //Print("mask: %x,  ord: %d,  a_0: %d,  a_1: %d\n"
+          //,(int)mask,(int)ord,(int)a_0,(int)a_1);
+                    //Print("mask: %d",mask);
+
+          p->exp[o->data.wp64.place]=a_1;
+          p->exp[o->data.wp64.place+1]=a_0;
+//            if(p_Setm_error) Print("***************************\n
+//                                    ***************************\n
+//                                    **WARNING: overflow error**\n
+//                                    ***************************\n
+//                                    ***************************\n");
+          break;
+        }
+        case ro_cp:
+        {
+          int a,e;
+          a=o->data.cp.start;
+          e=o->data.cp.end;
+          int pl=o->data.cp.place;
+          for(int i=a;i<=e;i++) { p->exp[pl]=p_GetExp(p,i,r); pl++; }
+          break;
+        }
+        case ro_syzcomp:
+        {
+          int c=p_GetComp(p,r);
+          long sc = c;
+          int* Components = (_componentsExternal ? _components :
+                             o->data.syzcomp.Components);
+          long* ShiftedComponents = (_componentsExternal ? _componentsShifted:
+                                     o->data.syzcomp.ShiftedComponents);
+          if (ShiftedComponents != NULL)
+          {
+            assume(Components != NULL);
+            assume(c == 0 || Components[c] != 0);
+            sc = ShiftedComponents[Components[c]];
+            assume(c == 0 || sc != 0);
+          }
+          p->exp[o->data.syzcomp.place]=sc;
+          break;
+        }
+        case ro_syz:
+        {
+          const unsigned long c = p_GetComp(p, r);
+          const short place = o->data.syz.place;
+          const int limit = o->data.syz.limit;
+
+          if (c > (unsigned long)limit)
+            p->exp[place] = o->data.syz.curr_index;
+          else if (c > 0)
+          {
+            assume( (1 <= c) && (c <= (unsigned long)limit) );
+            p->exp[place]= o->data.syz.syz_index[c];
+          }
+          else
+          {
+            assume(c == 0);
+            p->exp[place]= 0;
+          }
+          break;
+        }
+        // Prefix for Induced Schreyer ordering
+        case ro_isTemp: // Do nothing?? (to be removed into suffix later on...?)
+        {
+          assume(p != NULL);
+
+#ifndef SING_NDEBUG
+#if MYTEST
+          Print("p_Setm_General: ro_isTemp ord: pos: %d, p: ", pos);  p_DebugPrint(p, r, r, 1);
+#endif
+#endif
+          int c = p_GetComp(p, r);
+
+          assume( c >= 0 );
+
+          // Let's simulate case ro_syz above....
+          // Should accumulate (by Suffix) and be a level indicator
+          const int* const pVarOffset = o->data.isTemp.pVarOffset;
+
+          assume( pVarOffset != NULL );
+
+          // TODO: Can this be done in the suffix???
+          for( int i = 1; i <= r->N; i++ ) // No v[0] here!!!
+          {
+            const int vo = pVarOffset[i];
+            if( vo != -1) // TODO: optimize: can be done once!
+            {
+              // Hans! Please don't break it again! p_SetExp(p, ..., r, vo) is correct:
+              p_SetExp(p, p_GetExp(p, i, r), r, vo); // copy put them verbatim
+              // Hans! Please don't break it again! p_GetExp(p, r, vo) is correct:
+              assume( p_GetExp(p, r, vo) == p_GetExp(p, i, r) ); // copy put them verbatim
+            }
+          }
+#ifndef SING_NDEBUG
+          for( int i = 1; i <= r->N; i++ ) // No v[0] here!!!
+          {
+            const int vo = pVarOffset[i];
+            if( vo != -1) // TODO: optimize: can be done once!
+            {
+              // Hans! Please don't break it again! p_GetExp(p, r, vo) is correct:
+              assume( p_GetExp(p, r, vo) == p_GetExp(p, i, r) ); // copy put them verbatim
+            }
+          }
+#if MYTEST
+//          if( p->exp[o->data.isTemp.start] > 0 )
+            PrintS("after Values: "); p_DebugPrint(p, r, r, 1);
+#endif
+#endif
+          break;
+        }
+
+        // Suffix for Induced Schreyer ordering
+        case ro_is:
+        {
+#ifndef SING_NDEBUG
+#if MYTEST
+          Print("p_Setm_General: ro_is ord: pos: %d, p: ", pos);  p_DebugPrint(p, r, r, 1);
+#endif
+#endif
+
+          assume(p != NULL);
+
+          int c = p_GetComp(p, r);
+
+          assume( c >= 0 );
+          const ideal F = o->data.is.F;
+          const int limit = o->data.is.limit;
+          assume( limit >= 0 );
+          const int start = o->data.is.start;
+
+          if( F != NULL && c > limit )
+          {
+#ifndef SING_NDEBUG
+#if MYTEST
+            Print("p_Setm_General: ro_is : in rSetm: pos: %d, c: %d >  limit: %d\n", c, pos, limit); // p_DebugPrint(p, r, r, 1);
+            PrintS("preComputed Values: ");
+            p_DebugPrint(p, r, r, 1);
+#endif
+#endif
+//          if( c > limit ) // BUG???
+            p->exp[start] = 1;
+//          else
+//            p->exp[start] = 0;
+
+
+            c -= limit;
+            assume( c > 0 );
+            c--;
+
+            if( c >= IDELEMS(F) )
+              break;
+
+            assume( c < IDELEMS(F) ); // What about others???
+
+            const poly pp = F->m[c]; // get reference monomial!!!
+
+            if(pp == NULL)
+              break;
+
+            assume(pp != NULL);
+
+#ifndef SING_NDEBUG
+#if MYTEST
+            Print("Respective F[c - %d: %d] pp: ", limit, c);
+            p_DebugPrint(pp, r, r, 1);
+#endif
+#endif
+
+            const int end = o->data.is.end;
+            assume(start <= end);
+
+
+//          const int st = o->data.isTemp.start;
+
+#ifndef SING_NDEBUG
+            Print("p_Setm_General: is(-Temp-) :: c: %d, limit: %d, [st:%d] ===>>> %ld\n", c, limit, start, p->exp[start]);
+#endif
+
+            // p_ExpVectorAdd(p, pp, r);
+
+            for( int i = start; i <= end; i++) // v[0] may be here...
+              p->exp[i] += pp->exp[i]; // !!!!!!!! ADD corresponding LT(F)
+
+            // p_MemAddAdjust(p, ri);
+            if (r->NegWeightL_Offset != NULL)
+            {
+              for (int i=r->NegWeightL_Size-1; i>=0; i--)
+              {
+                const int _i = r->NegWeightL_Offset[i];
+                if( start <= _i && _i <= end )
+                  p->exp[_i] -= POLY_NEGWEIGHT_OFFSET;
+              }
+            }
+
+
+#ifndef SING_NDEBUG
+            const int* const pVarOffset = o->data.is.pVarOffset;
+
+            assume( pVarOffset != NULL );
+
+            for( int i = 1; i <= r->N; i++ ) // No v[0] here!!!
+            {
+              const int vo = pVarOffset[i];
+              if( vo != -1) // TODO: optimize: can be done once!
+                // Hans! Please don't break it again! p_GetExp(p/pp, r, vo) is correct:
+                assume( p_GetExp(p, r, vo) == (p_GetExp(p, i, r) + p_GetExp(pp, r, vo)) );
+            }
+            // TODO: how to check this for computed values???
+#if MYTEST
+            PrintS("Computed Values: "); p_DebugPrint(p, r, r, 1);
+#endif
+#endif
+          } else
+          {
+            p->exp[start] = 0; //!!!!????? where?????
+
+            const int* const pVarOffset = o->data.is.pVarOffset;
+
+            // What about v[0] - component: it will be added later by
+            // suffix!!!
+            // TODO: Test it!
+            const int vo = pVarOffset[0];
+            if( vo != -1 )
+              p->exp[vo] = c; // initial component v[0]!
+
+#ifndef SING_NDEBUG
+#if MYTEST
+            Print("ELSE p_Setm_General: ro_is :: c: %d <= limit: %d, vo: %d, exp: %d\n", c, limit, vo, p->exp[vo]);
+            p_DebugPrint(p, r, r, 1);
+#endif
+#endif
+          }
+
+          break;
+        }
+        default:
+          dReportError("wrong ord in rSetm:%d\n",o->ord_typ);
+          return;
+      }
+      pos++;
+      if (pos == r->OrdSize) return;
+    }
+  }
+}
+
+void p_Setm_Syz(poly p, ring r, int* Components, long* ShiftedComponents)
+{
+  _components = Components;
+  _componentsShifted = ShiftedComponents;
+  _componentsExternal = 1;
+  p_Setm_General(p, r);
+  _componentsExternal = 0;
+}
+
+// dummy for lp, ls, etc
+void p_Setm_Dummy(poly p, const ring r)
+{
+  p_LmCheckPolyRing(p, r);
+}
+
+// for dp, Dp, ds, etc
+void p_Setm_TotalDegree(poly p, const ring r)
+{
+  p_LmCheckPolyRing(p, r);
+  p->exp[r->pOrdIndex] = p_Totaldegree(p, r);
+}
+
+// for wp, Wp, ws, etc
+void p_Setm_WFirstTotalDegree(poly p, const ring r)
+{
+  p_LmCheckPolyRing(p, r);
+  p->exp[r->pOrdIndex] = p_WFirstTotalDegree(p, r);
+}
+
+p_SetmProc p_GetSetmProc(ring r)
+{
+  // covers lp, rp, ls,
+  if (r->typ == NULL) return p_Setm_Dummy;
+
+  if (r->OrdSize == 1)
+  {
+    if (r->typ[0].ord_typ == ro_dp &&
+        r->typ[0].data.dp.start == 1 &&
+        r->typ[0].data.dp.end == r->N &&
+        r->typ[0].data.dp.place == r->pOrdIndex)
+      return p_Setm_TotalDegree;
+    if (r->typ[0].ord_typ == ro_wp &&
+        r->typ[0].data.wp.start == 1 &&
+        r->typ[0].data.wp.end == r->N &&
+        r->typ[0].data.wp.place == r->pOrdIndex &&
+        r->typ[0].data.wp.weights == r->firstwv)
+      return p_Setm_WFirstTotalDegree;
+  }
+  return p_Setm_General;
+}
+
+
+/* -------------------------------------------------------------------*/
+/* several possibilities for pFDeg: the degree of the head term       */
+
+/* comptible with ordering */
+long p_Deg(poly a, const ring r)
+{
+  p_LmCheckPolyRing(a, r);
+//  assume(p_GetOrder(a, r) == p_WTotaldegree(a, r)); // WRONG assume!
+  return p_GetOrder(a, r);
+}
+
+// p_WTotalDegree for weighted orderings
+// whose first block covers all variables
+long p_WFirstTotalDegree(poly p, const ring r)
+{
+  int i;
+  long sum = 0;
+
+  for (i=1; i<= r->firstBlockEnds; i++)
+  {
+    sum += p_GetExp(p, i, r)*r->firstwv[i-1];
+  }
+  return sum;
+}
+
+/*2
+* compute the degree of the leading monomial of p
+* with respect to weigths from the ordering
+* the ordering is not compatible with degree so do not use p->Order
+*/
+long p_WTotaldegree(poly p, const ring r)
+{
+  p_LmCheckPolyRing(p, r);
+  int i, k;
+  long j =0;
+
+  // iterate through each block:
+  for (i=0;r->order[i]!=0;i++)
+  {
+    int b0=r->block0[i];
+    int b1=r->block1[i];
+    switch(r->order[i])
+    {
+      case ringorder_M:
+        for (k=b0 /*r->block0[i]*/;k<=b1 /*r->block1[i]*/;k++)
+        { // in jedem block:
+          j+= p_GetExp(p,k,r)*r->wvhdl[i][k - b0 /*r->block0[i]*/]*r->OrdSgn;
+        }
+        break;
+      case ringorder_wp:
+      case ringorder_ws:
+      case ringorder_Wp:
+      case ringorder_Ws:
+        for (k=b0 /*r->block0[i]*/;k<=b1 /*r->block1[i]*/;k++)
+        { // in jedem block:
+          j+= p_GetExp(p,k,r)*r->wvhdl[i][k - b0 /*r->block0[i]*/];
+        }
+        break;
+      case ringorder_lp:
+      case ringorder_ls:
+      case ringorder_rs:
+      case ringorder_dp:
+      case ringorder_ds:
+      case ringorder_Dp:
+      case ringorder_Ds:
+      case ringorder_rp:
+        for (k=b0 /*r->block0[i]*/;k<=b1 /*r->block1[i]*/;k++)
+        {
+          j+= p_GetExp(p,k,r);
+        }
+        break;
+      case ringorder_a64:
+        {
+          int64* w=(int64*)r->wvhdl[i];
+          for (k=0;k<=(b1 /*r->block1[i]*/ - b0 /*r->block0[i]*/);k++)
+          {
+            //there should be added a line which checks if w[k]>2^31
+            j+= p_GetExp(p,k+1, r)*(long)w[k];
+          }
+          //break;
+          return j;
+        }
+      case ringorder_c:
+      case ringorder_C:
+      case ringorder_S:
+      case ringorder_s:
+      case ringorder_aa:
+      case ringorder_IS:
+        break;
+      case ringorder_a:
+        for (k=b0 /*r->block0[i]*/;k<=b1 /*r->block1[i]*/;k++)
+        { // only one line
+          j+= p_GetExp(p,k, r)*r->wvhdl[i][ k- b0 /*r->block0[i]*/];
+        }
+        //break;
+        return j;
+
+#ifndef SING_NDEBUG
+      default:
+        Print("missing order %d in p_WTotaldegree\n",r->order[i]);
+        break;
+#endif
+    }
+  }
+  return  j;
+}
+
+long p_DegW(poly p, const short *w, const ring R)
+{
+  p_Test(p, R);
+  assume( w != NULL );
+  long r=-LONG_MAX;
+
+  while (p!=NULL)
+  {
+    long t=totaldegreeWecart_IV(p,R,w);
+    if (t>r) r=t;
+    pIter(p);
+  }
+  return r;
+}
+
+int p_Weight(int i, const ring r)
+{
+  if ((r->firstwv==NULL) || (i>r->firstBlockEnds))
+  {
+    return 1;
+  }
+  return r->firstwv[i-1];
+}
+
+long p_WDegree(poly p, const ring r)
+{
+  if (r->firstwv==NULL) return p_Totaldegree(p, r);
+  p_LmCheckPolyRing(p, r);
+  int i;
+  long j =0;
+
+  for(i=1;i<=r->firstBlockEnds;i++)
+    j+=p_GetExp(p, i, r)*r->firstwv[i-1];
+
+  for (;i<=rVar(r);i++)
+    j+=p_GetExp(p,i, r)*p_Weight(i, r);
+
+  return j;
+}
+
+
+/* ---------------------------------------------------------------------*/
+/* several possibilities for pLDeg: the maximal degree of a monomial in p*/
+/*  compute in l also the pLength of p                                   */
+
+/*2
+* compute the length of a polynomial (in l)
+* and the degree of the monomial with maximal degree: the last one
+*/
+long pLDeg0(poly p,int *l, const ring r)
+{
+  p_CheckPolyRing(p, r);
+  long k= p_GetComp(p, r);
+  int ll=1;
+
+  if (k > 0)
+  {
+    while ((pNext(p)!=NULL) && (p_GetComp(pNext(p), r)==k))
+    {
+      pIter(p);
+      ll++;
+    }
+  }
+  else
+  {
+     while (pNext(p)!=NULL)
+     {
+       pIter(p);
+       ll++;
+     }
+  }
+  *l=ll;
+  return r->pFDeg(p, r);
+}
+
+/*2
+* compute the length of a polynomial (in l)
+* and the degree of the monomial with maximal degree: the last one
+* but search in all components before syzcomp
+*/
+long pLDeg0c(poly p,int *l, const ring r)
+{
+  assume(p!=NULL);
+  p_Test(p,r);
+  p_CheckPolyRing(p, r);
+  long o;
+  int ll=1;
+
+  if (! rIsSyzIndexRing(r))
+  {
+    while (pNext(p) != NULL)
+    {
+      pIter(p);
+      ll++;
+    }
+    o = r->pFDeg(p, r);
+  }
+  else
+  {
+    int curr_limit = rGetCurrSyzLimit(r);
+    poly pp = p;
+    while ((p=pNext(p))!=NULL)
+    {
+      if (p_GetComp(p, r)<=curr_limit/*syzComp*/)
+        ll++;
+      else break;
+      pp = p;
+    }
+    p_Test(pp,r);
+    o = r->pFDeg(pp, r);
+  }
+  *l=ll;
+  return o;
+}
+
+/*2
+* compute the length of a polynomial (in l)
+* and the degree of the monomial with maximal degree: the first one
+* this works for the polynomial case with degree orderings
+* (both c,dp and dp,c)
+*/
+long pLDegb(poly p,int *l, const ring r)
+{
+  p_CheckPolyRing(p, r);
+  long k= p_GetComp(p, r);
+  long o = r->pFDeg(p, r);
+  int ll=1;
+
+  if (k != 0)
+  {
+    while (((p=pNext(p))!=NULL) && (p_GetComp(p, r)==k))
+    {
+      ll++;
+    }
+  }
+  else
+  {
+    while ((p=pNext(p)) !=NULL)
+    {
+      ll++;
+    }
+  }
+  *l=ll;
+  return o;
+}
+
+/*2
+* compute the length of a polynomial (in l)
+* and the degree of the monomial with maximal degree:
+* this is NOT the last one, we have to look for it
+*/
+long pLDeg1(poly p,int *l, const ring r)
+{
+  p_CheckPolyRing(p, r);
+  long k= p_GetComp(p, r);
+  int ll=1;
+  long  t,max;
+
+  max=r->pFDeg(p, r);
+  if (k > 0)
+  {
+    while (((p=pNext(p))!=NULL) && (p_GetComp(p, r)==k))
+    {
+      t=r->pFDeg(p, r);
+      if (t>max) max=t;
+      ll++;
+    }
+  }
+  else
+  {
+    while ((p=pNext(p))!=NULL)
+    {
+      t=r->pFDeg(p, r);
+      if (t>max) max=t;
+      ll++;
+    }
+  }
+  *l=ll;
+  return max;
+}
+
+/*2
+* compute the length of a polynomial (in l)
+* and the degree of the monomial with maximal degree:
+* this is NOT the last one, we have to look for it
+* in all components
+*/
+long pLDeg1c(poly p,int *l, const ring r)
+{
+  p_CheckPolyRing(p, r);
+  int ll=1;
+  long  t,max;
+
+  max=r->pFDeg(p, r);
+  if (rIsSyzIndexRing(r))
+  {
+    long limit = rGetCurrSyzLimit(r);
+    while ((p=pNext(p))!=NULL)
+    {
+      if (p_GetComp(p, r)<=limit)
+      {
+        if ((t=r->pFDeg(p, r))>max) max=t;
+        ll++;
+      }
+      else break;
+    }
+  }
+  else
+  {
+    while ((p=pNext(p))!=NULL)
+    {
+      if ((t=r->pFDeg(p, r))>max) max=t;
+      ll++;
+    }
+  }
+  *l=ll;
+  return max;
+}
+
+// like pLDeg1, only pFDeg == pDeg
+long pLDeg1_Deg(poly p,int *l, const ring r)
+{
+  assume(r->pFDeg == p_Deg);
+  p_CheckPolyRing(p, r);
+  long k= p_GetComp(p, r);
+  int ll=1;
+  long  t,max;
+
+  max=p_GetOrder(p, r);
+  if (k > 0)
+  {
+    while (((p=pNext(p))!=NULL) && (p_GetComp(p, r)==k))
+    {
+      t=p_GetOrder(p, r);
+      if (t>max) max=t;
+      ll++;
+    }
+  }
+  else
+  {
+    while ((p=pNext(p))!=NULL)
+    {
+      t=p_GetOrder(p, r);
+      if (t>max) max=t;
+      ll++;
+    }
+  }
+  *l=ll;
+  return max;
+}
+
+long pLDeg1c_Deg(poly p,int *l, const ring r)
+{
+  assume(r->pFDeg == p_Deg);
+  p_CheckPolyRing(p, r);
+  int ll=1;
+  long  t,max;
+
+  max=p_GetOrder(p, r);
+  if (rIsSyzIndexRing(r))
+  {
+    long limit = rGetCurrSyzLimit(r);
+    while ((p=pNext(p))!=NULL)
+    {
+      if (p_GetComp(p, r)<=limit)
+      {
+        if ((t=p_GetOrder(p, r))>max) max=t;
+        ll++;
+      }
+      else break;
+    }
+  }
+  else
+  {
+    while ((p=pNext(p))!=NULL)
+    {
+      if ((t=p_GetOrder(p, r))>max) max=t;
+      ll++;
+    }
+  }
+  *l=ll;
+  return max;
+}
+
+// like pLDeg1, only pFDeg == pTotoalDegree
+long pLDeg1_Totaldegree(poly p,int *l, const ring r)
+{
+  p_CheckPolyRing(p, r);
+  long k= p_GetComp(p, r);
+  int ll=1;
+  long  t,max;
+
+  max=p_Totaldegree(p, r);
+  if (k > 0)
+  {
+    while (((p=pNext(p))!=NULL) && (p_GetComp(p, r)==k))
+    {
+      t=p_Totaldegree(p, r);
+      if (t>max) max=t;
+      ll++;
+    }
+  }
+  else
+  {
+    while ((p=pNext(p))!=NULL)
+    {
+      t=p_Totaldegree(p, r);
+      if (t>max) max=t;
+      ll++;
+    }
+  }
+  *l=ll;
+  return max;
+}
+
+long pLDeg1c_Totaldegree(poly p,int *l, const ring r)
+{
+  p_CheckPolyRing(p, r);
+  int ll=1;
+  long  t,max;
+
+  max=p_Totaldegree(p, r);
+  if (rIsSyzIndexRing(r))
+  {
+    long limit = rGetCurrSyzLimit(r);
+    while ((p=pNext(p))!=NULL)
+    {
+      if (p_GetComp(p, r)<=limit)
+      {
+        if ((t=p_Totaldegree(p, r))>max) max=t;
+        ll++;
+      }
+      else break;
+    }
+  }
+  else
+  {
+    while ((p=pNext(p))!=NULL)
+    {
+      if ((t=p_Totaldegree(p, r))>max) max=t;
+      ll++;
+    }
+  }
+  *l=ll;
+  return max;
+}
+
+// like pLDeg1, only pFDeg == p_WFirstTotalDegree
+long pLDeg1_WFirstTotalDegree(poly p,int *l, const ring r)
+{
+  p_CheckPolyRing(p, r);
+  long k= p_GetComp(p, r);
+  int ll=1;
+  long  t,max;
+
+  max=p_WFirstTotalDegree(p, r);
+  if (k > 0)
+  {
+    while (((p=pNext(p))!=NULL) && (p_GetComp(p, r)==k))
+    {
+      t=p_WFirstTotalDegree(p, r);
+      if (t>max) max=t;
+      ll++;
+    }
+  }
+  else
+  {
+    while ((p=pNext(p))!=NULL)
+    {
+      t=p_WFirstTotalDegree(p, r);
+      if (t>max) max=t;
+      ll++;
+    }
+  }
+  *l=ll;
+  return max;
+}
+
+long pLDeg1c_WFirstTotalDegree(poly p,int *l, const ring r)
+{
+  p_CheckPolyRing(p, r);
+  int ll=1;
+  long  t,max;
+
+  max=p_WFirstTotalDegree(p, r);
+  if (rIsSyzIndexRing(r))
+  {
+    long limit = rGetCurrSyzLimit(r);
+    while ((p=pNext(p))!=NULL)
+    {
+      if (p_GetComp(p, r)<=limit)
+      {
+        if ((t=p_Totaldegree(p, r))>max) max=t;
+        ll++;
+      }
+      else break;
+    }
+  }
+  else
+  {
+    while ((p=pNext(p))!=NULL)
+    {
+      if ((t=p_Totaldegree(p, r))>max) max=t;
+      ll++;
+    }
+  }
+  *l=ll;
+  return max;
+}
+
+/***************************************************************
+ *
+ * Maximal Exponent business
+ *
+ ***************************************************************/
+
+static inline unsigned long
+p_GetMaxExpL2(unsigned long l1, unsigned long l2, const ring r,
+              unsigned long number_of_exp)
+{
+  const unsigned long bitmask = r->bitmask;
+  unsigned long ml1 = l1 & bitmask;
+  unsigned long ml2 = l2 & bitmask;
+  unsigned long max = (ml1 > ml2 ? ml1 : ml2);
+  unsigned long j = number_of_exp - 1;
+
+  if (j > 0)
+  {
+    unsigned long mask = bitmask << r->BitsPerExp;
+    while (1)
+    {
+      ml1 = l1 & mask;
+      ml2 = l2 & mask;
+      max |= ((ml1 > ml2 ? ml1 : ml2) & mask);
+      j--;
+      if (j == 0) break;
+      mask = mask << r->BitsPerExp;
+    }
+  }
+  return max;
+}
+
+static inline unsigned long
+p_GetMaxExpL2(unsigned long l1, unsigned long l2, const ring r)
+{
+  return p_GetMaxExpL2(l1, l2, r, r->ExpPerLong);
+}
+
+poly p_GetMaxExpP(poly p, const ring r)
+{
+  p_CheckPolyRing(p, r);
+  if (p == NULL) return p_Init(r);
+  poly max = p_LmInit(p, r);
+  pIter(p);
+  if (p == NULL) return max;
+  int i, offset;
+  unsigned long l_p, l_max;
+  unsigned long divmask = r->divmask;
+
+  do
+  {
+    offset = r->VarL_Offset[0];
+    l_p = p->exp[offset];
+    l_max = max->exp[offset];
+    // do the divisibility trick to find out whether l has an exponent
+    if (l_p > l_max ||
+        (((l_max & divmask) ^ (l_p & divmask)) != ((l_max-l_p) & divmask)))
+      max->exp[offset] = p_GetMaxExpL2(l_max, l_p, r);
+
+    for (i=1; i<r->VarL_Size; i++)
+    {
+      offset = r->VarL_Offset[i];
+      l_p = p->exp[offset];
+      l_max = max->exp[offset];
+      // do the divisibility trick to find out whether l has an exponent
+      if (l_p > l_max ||
+          (((l_max & divmask) ^ (l_p & divmask)) != ((l_max-l_p) & divmask)))
+        max->exp[offset] = p_GetMaxExpL2(l_max, l_p, r);
+    }
+    pIter(p);
+  }
+  while (p != NULL);
+  return max;
+}
+
+unsigned long p_GetMaxExpL(poly p, const ring r, unsigned long l_max)
+{
+  unsigned long l_p, divmask = r->divmask;
+  int i;
+
+  while (p != NULL)
+  {
+    l_p = p->exp[r->VarL_Offset[0]];
+    if (l_p > l_max ||
+        (((l_max & divmask) ^ (l_p & divmask)) != ((l_max-l_p) & divmask)))
+      l_max = p_GetMaxExpL2(l_max, l_p, r);
+    for (i=1; i<r->VarL_Size; i++)
+    {
+      l_p = p->exp[r->VarL_Offset[i]];
+      // do the divisibility trick to find out whether l has an exponent
+      if (l_p > l_max ||
+          (((l_max & divmask) ^ (l_p & divmask)) != ((l_max-l_p) & divmask)))
+        l_max = p_GetMaxExpL2(l_max, l_p, r);
+    }
+    pIter(p);
+  }
+  return l_max;
+}
+
+
+
+
+/***************************************************************
+ *
+ * Misc things
+ *
+ ***************************************************************/
+// returns TRUE, if all monoms have the same component
+BOOLEAN p_OneComp(poly p, const ring r)
+{
+  if(p!=NULL)
+  {
+    long i = p_GetComp(p, r);
+    while (pNext(p)!=NULL)
+    {
+      pIter(p);
+      if(i != p_GetComp(p, r)) return FALSE;
+    }
+  }
+  return TRUE;
+}
+
+/*2
+*test if a monomial /head term is a pure power
+*/
+int p_IsPurePower(const poly p, const ring r)
+{
+#ifdef HAVE_RINGS
+  if (rField_is_Ring(r))
+          {
+          if (p == NULL) return 0;
+          if (!n_IsUnit(pGetCoeff(p), r->cf)) return 0;
+          }
+#endif
+  int i,k=0;
+
+  for (i=r->N;i;i--)
+  {
+    if (p_GetExp(p,i, r)!=0)
+    {
+      if(k!=0) return 0;
+      k=i;
+    }
+  }
+  return k;
+}
+
+/*2
+*test if a polynomial is univariate
+* return -1 for constant,
+* 0 for not univariate,s
+* i if dep. on var(i)
+*/
+int p_IsUnivariate(poly p, const ring r)
+{
+  int i,k=-1;
+
+  while (p!=NULL)
+  {
+    for (i=r->N;i;i--)
+    {
+      if (p_GetExp(p,i, r)!=0)
+      {
+        if((k!=-1)&&(k!=i)) return 0;
+        k=i;
+      }
+    }
+    pIter(p);
+  }
+  return k;
+}
+
+// set entry e[i] to 1 if var(i) occurs in p, ignore var(j) if e[j]>0
+int  p_GetVariables(poly p, int * e, const ring r)
+{
+  int i;
+  int n=0;
+  while(p!=NULL)
+  {
+    n=0;
+    for(i=r->N; i>0; i--)
+    {
+      if(e[i]==0)
+      {
+        if (p_GetExp(p,i,r)>0)
+        {
+          e[i]=1;
+          n++;
+        }
+      }
+      else
+        n++;
+    }
+    if (n==r->N) break;
+    pIter(p);
+  }
+  return n;
+}
+
+
+/*2
+* returns a polynomial representing the integer i
+*/
+poly p_ISet(long i, const ring r)
+{
+  poly rc = NULL;
+  if (i!=0)
+  {
+    rc = p_Init(r);
+    pSetCoeff0(rc,n_Init(i,r->cf));
+    if (n_IsZero(pGetCoeff(rc),r->cf))
+      p_LmDelete(&rc,r);
+  }
+  return rc;
+}
+
+/*2
+* an optimized version of p_ISet for the special case 1
+*/
+poly p_One(const ring r)
+{
+  poly rc = p_Init(r);
+  pSetCoeff0(rc,n_Init(1,r->cf));
+  return rc;
+}
+
+void p_Split(poly p, poly *h)
+{
+  *h=pNext(p);
+  pNext(p)=NULL;
+}
+
+/*2
+* pair has no common factor ? or is no polynomial
+*/
+BOOLEAN p_HasNotCF(poly p1, poly p2, const ring r)
+{
+
+  if (p_GetComp(p1,r) > 0 || p_GetComp(p2,r) > 0)
+    return FALSE;
+  int i = rVar(r);
+  loop
+  {
+    if ((p_GetExp(p1, i, r) > 0) && (p_GetExp(p2, i, r) > 0))
+      return FALSE;
+    i--;
+    if (i == 0)
+      return TRUE;
+  }
+}
+
+/*2
+* convert monomial given as string to poly, e.g. 1x3y5z
+*/
+const char * p_Read(const char *st, poly &rc, const ring r)
+{
+  if (r==NULL) { rc=NULL;return st;}
+  int i,j;
+  rc = p_Init(r);
+  const char *s = n_Read(st,&(p_GetCoeff(rc, r)),r->cf);
+  if (s==st)
+  /* i.e. it does not start with a coeff: test if it is a ringvar*/
+  {
+    j = r_IsRingVar(s,r->names,r->N);
+    if (j >= 0)
+    {
+      p_IncrExp(rc,1+j,r);
+      while (*s!='\0') s++;
+      goto done;
+    }
+  }
+  while (*s!='\0')
+  {
+    char ss[2];
+    ss[0] = *s++;
+    ss[1] = '\0';
+    j = r_IsRingVar(ss,r->names,r->N);
+    if (j >= 0)
+    {
+      const char *s_save=s;
+      s = eati(s,&i);
+      if (((unsigned long)i) >  r->bitmask)
+      {
+        // exponent to large: it is not a monomial
+        p_LmDelete(&rc,r);
+        return s_save;
+      }
+      p_AddExp(rc,1+j, (long)i, r);
+    }
+    else
+    {
+      // 1st char of is not a varname
+      // We return the parsed polynomial nevertheless. This is needed when
+      // we are parsing coefficients in a rational function field.
+      s--;
+      break;
+    }
+  }
+done:
+  if (n_IsZero(pGetCoeff(rc),r->cf)) p_LmDelete(&rc,r);
+  else
+  {
+#ifdef HAVE_PLURAL
+    // in super-commutative ring
+    // squares of anti-commutative variables are zeroes!
+    if(rIsSCA(r))
+    {
+      const unsigned int iFirstAltVar = scaFirstAltVar(r);
+      const unsigned int iLastAltVar  = scaLastAltVar(r);
+
+      assume(rc != NULL);
+
+      for(unsigned int k = iFirstAltVar; k <= iLastAltVar; k++)
+        if( p_GetExp(rc, k, r) > 1 )
+        {
+          p_LmDelete(&rc, r);
+          goto finish;
+        }
+    }
+#endif
+
+    p_Setm(rc,r);
+  }
+finish:
+  return s;
+}
+poly p_mInit(const char *st, BOOLEAN &ok, const ring r)
+{
+  poly p;
+  const char *s=p_Read(st,p,r);
+  if (*s!='\0')
+  {
+    if ((s!=st)&&isdigit(st[0]))
+    {
+      errorreported=TRUE;
+    }
+    ok=FALSE;
+    p_Delete(&p,r);
+    return NULL;
+  }
+  p_Test(p,r);
+  ok=!errorreported;
+  return p;
+}
+
+/*2
+* returns a polynomial representing the number n
+* destroys n
+*/
+poly p_NSet(number n, const ring r)
+{
+  if (n_IsZero(n,r->cf))
+  {
+    n_Delete(&n, r->cf);
+    return NULL;
+  }
+  else
+  {
+    poly rc = p_Init(r);
+    pSetCoeff0(rc,n);
+    return rc;
+  }
+}
+/*2
+* assumes that LM(a) = LM(b)*m, for some monomial m,
+* returns the multiplicant m,
+* leaves a and b unmodified
+*/
+poly p_Divide(poly a, poly b, const ring r)
+{
+  assume((p_GetComp(a,r)==p_GetComp(b,r)) || (p_GetComp(b,r)==0));
+  int i;
+  poly result = p_Init(r);
+
+  for(i=(int)r->N; i; i--)
+    p_SetExp(result,i, p_GetExp(a,i,r)- p_GetExp(b,i,r),r);
+  p_SetComp(result, p_GetComp(a,r) - p_GetComp(b,r),r);
+  p_Setm(result,r);
+  return result;
+}
+
+poly p_Div_nn(poly p, const number n, const ring r)
+{
+  pAssume(!n_IsZero(n,r->cf));
+  p_Test(p, r);
+
+  poly q = p;
+  while (p != NULL)
+  {
+    number nc = pGetCoeff(p);
+    pSetCoeff0(p, n_Div(nc, n, r->cf));
+    n_Delete(&nc, r->cf);
+    pIter(p);
+  }
+  p_Test(q, r);
+  return q;
+}
+
+/*2
+* divides a by the monomial b, ignores monomials which are not divisible
+* assumes that b is not NULL, destroyes b
+*/
+poly p_DivideM(poly a, poly b, const ring r)
+{
+  if (a==NULL) { p_Delete(&b,r); return NULL; }
+  poly result=a;
+  poly prev=NULL;
+  int i;
+#ifdef HAVE_RINGS
+  number inv=pGetCoeff(b);
+#else
+  number inv=n_Invers(pGetCoeff(b),r->cf);
+#endif
+
+  while (a!=NULL)
+  {
+    if (p_DivisibleBy(b,a,r))
+    {
+      for(i=(int)r->N; i; i--)
+         p_SubExp(a,i, p_GetExp(b,i,r),r);
+      p_SubComp(a, p_GetComp(b,r),r);
+      p_Setm(a,r);
+      prev=a;
+      pIter(a);
+    }
+    else
+    {
+      if (prev==NULL)
+      {
+        p_LmDelete(&result,r);
+        a=result;
+      }
+      else
+      {
+        p_LmDelete(&pNext(prev),r);
+        a=pNext(prev);
+      }
+    }
+  }
+#ifdef HAVE_RINGS
+  if (n_IsUnit(inv,r->cf))
+  {
+    inv = n_Invers(inv,r->cf);
+    p_Mult_nn(result,inv,r);
+    n_Delete(&inv, r->cf);
+  }
+  else
+  {
+    p_Div_nn(result,inv,r);
+  }
+#else
+  p_Mult_nn(result,inv,r);
+  n_Delete(&inv, r->cf);
+#endif
+  p_Delete(&b, r);
+  return result;
+}
+
+#ifdef HAVE_RINGS
+/* TRUE iff LT(f) | LT(g) */
+BOOLEAN p_DivisibleByRingCase(poly f, poly g, const ring r)
+{
+  int exponent;
+  for(int i = (int)rVar(r); i>0; i--)
+  {
+    exponent = p_GetExp(g, i, r) - p_GetExp(f, i, r);
+    if (exponent < 0) return FALSE;
+  }
+  return n_DivBy(pGetCoeff(g), pGetCoeff(f), r->cf);
+}
+#endif
+
+// returns the LCM of the head terms of a and b in *m
+void p_Lcm(const poly a, const poly b, poly m, const ring r)
+{
+  for (int i=rVar(r); i; --i)
+    p_SetExp(m,i, si_max( p_GetExp(a,i,r), p_GetExp(b,i,r)),r);
+
+  p_SetComp(m, si_max(p_GetComp(a,r), p_GetComp(b,r)),r);
+  /* Don't do a pSetm here, otherwise hres/lres chockes */
+}
+
+
+
+#ifdef HAVE_RATGRING
+/*2
+* returns the rational LCM of the head terms of a and b
+* without coefficient!!!
+*/
+poly p_LcmRat(const poly a, const poly b, const long lCompM, const ring r)
+{
+  poly m = // p_One( r);
+          p_Init(r);
+
+//  const int (currRing->N) = r->N;
+
+  //  for (int i = (currRing->N); i>=r->real_var_start; i--)
+  for (int i = r->real_var_end; i>=r->real_var_start; i--)
+  {
+    const int lExpA = p_GetExp (a, i, r);
+    const int lExpB = p_GetExp (b, i, r);
+
+    p_SetExp (m, i, si_max(lExpA, lExpB), r);
+  }
+
+  p_SetComp (m, lCompM, r);
+  p_Setm(m,r);
+  n_New(&(p_GetCoeff(m, r)), r);
+
+  return(m);
+};
+
+void p_LmDeleteAndNextRat(poly *p, int ishift, ring r)
+{
+  /* modifies p*/
+  //  Print("start: "); Print(" "); p_wrp(*p,r);
+  p_LmCheckPolyRing2(*p, r);
+  poly q = p_Head(*p,r);
+  const long cmp = p_GetComp(*p, r);
+  while ( ( (*p)!=NULL ) && ( p_Comp_k_n(*p, q, ishift+1, r) ) && (p_GetComp(*p, r) == cmp) )
+  {
+    p_LmDelete(p,r);
+    //    Print("while: ");p_wrp(*p,r);Print(" ");
+  }
+  //  p_wrp(*p,r);Print(" ");
+  //  PrintS("end\n");
+  p_LmDelete(&q,r);
+}
+
+
+/* returns x-coeff of p, i.e. a poly in x, s.t. corresponding xd-monomials
+have the same D-part and the component 0
+does not destroy p
+*/
+poly p_GetCoeffRat(poly p, int ishift, ring r)
+{
+  poly q   = pNext(p);
+  poly res; // = p_Head(p,r);
+  res = p_GetExp_k_n(p, ishift+1, r->N, r); // does pSetm internally
+  p_SetCoeff(res,n_Copy(p_GetCoeff(p,r),r),r);
+  poly s;
+  long cmp = p_GetComp(p, r);
+  while ( (q!= NULL) && (p_Comp_k_n(p, q, ishift+1, r)) && (p_GetComp(q, r) == cmp) )
+  {
+    s   = p_GetExp_k_n(q, ishift+1, r->N, r);
+    p_SetCoeff(s,n_Copy(p_GetCoeff(q,r),r),r);
+    res = p_Add_q(res,s,r);
+    q   = pNext(q);
+  }
+  cmp = 0;
+  p_SetCompP(res,cmp,r);
+  return res;
+}
+
+
+
+void p_ContentRat(poly &ph, const ring r)
+// changes ph
+// for rat coefficients in K(x1,..xN)
+{
+  // init array of RatLeadCoeffs
+  //  poly p_GetCoeffRat(poly p, int ishift, ring r);
+
+  int len=pLength(ph);
+  poly *C = (poly *)omAlloc0((len+1)*sizeof(poly));  //rat coeffs
+  poly *LM = (poly *)omAlloc0((len+1)*sizeof(poly));  // rat lead terms
+  int *D = (int *)omAlloc0((len+1)*sizeof(int));  //degrees of coeffs
+  int *L = (int *)omAlloc0((len+1)*sizeof(int));  //lengths of coeffs
+  int k = 0;
+  poly p = p_Copy(ph, r); // ph will be needed below
+  int mintdeg = p_Totaldegree(p, r);
+  int minlen = len;
+  int dd = 0; int i;
+  int HasConstantCoef = 0;
+  int is = r->real_var_start - 1;
+  while (p!=NULL)
+  {
+    LM[k] = p_GetExp_k_n(p,1,is, r); // need LmRat istead of  p_HeadRat(p, is, currRing); !
+    C[k] = p_GetCoeffRat(p, is, r);
+    D[k] =  p_Totaldegree(C[k], r);
+    mintdeg = si_min(mintdeg,D[k]);
+    L[k] = pLength(C[k]);
+    minlen = si_min(minlen,L[k]);
+    if (p_IsConstant(C[k], r))
+    {
+      // C[k] = const, so the content will be numerical
+      HasConstantCoef = 1;
+      // smth like goto cleanup and return(pContent(p));
+    }
+    p_LmDeleteAndNextRat(&p, is, r);
+    k++;
+  }
+
+  // look for 1 element of minimal degree and of minimal length
+  k--;
+  poly d;
+  int mindeglen = len;
+  if (k<=0) // this poly is not a ratgring poly -> pContent
+  {
+    p_Delete(&C[0], r);
+    p_Delete(&LM[0], r);
+    p_Content(ph, r);
+    goto cleanup;
+  }
+
+  int pmindeglen;
+  for(i=0; i<=k; i++)
+  {
+    if (D[i] == mintdeg)
+    {
+      if (L[i] < mindeglen)
+      {
+        mindeglen=L[i];
+        pmindeglen = i;
+      }
+    }
+  }
+  d = p_Copy(C[pmindeglen], r);
+  // there are dd>=1 mindeg elements
+  // and pmideglen is the coordinate of one of the smallest among them
+
+  //  poly g = singclap_gcd(p_Copy(p,r),p_Copy(q,r));
+  //  return naGcd(d,d2,currRing);
+
+  // adjoin pContentRat here?
+  for(i=0; i<=k; i++)
+  {
+    d=singclap_gcd(d,p_Copy(C[i], r), r);
+    if (p_Totaldegree(d, r)==0)
+    {
+      // cleanup, pContent, return
+      p_Delete(&d, r);
+      for(;k>=0;k--)
+      {
+        p_Delete(&C[k], r);
+        p_Delete(&LM[k], r);
+      }
+      p_Content(ph, r);
+      goto cleanup;
+    }
+  }
+  for(i=0; i<=k; i++)
+  {
+    poly h=singclap_pdivide(C[i],d, r);
+    p_Delete(&C[i], r);
+    C[i]=h;
+  }
+
+  // zusammensetzen,
+  p=NULL; // just to be sure
+  for(i=0; i<=k; i++)
+  {
+    p = p_Add_q(p, p_Mult_q(C[i],LM[i], r), r);
+    C[i]=NULL; LM[i]=NULL;
+  }
+  p_Delete(&ph, r); // do not need it anymore
+  ph = p;
+  // aufraeumen, return
+cleanup:
+  omFree(C);
+  omFree(LM);
+  omFree(D);
+  omFree(L);
+}
+
+
+#endif
+
+
+/* assumes that p and divisor are univariate polynomials in r,
+   mentioning the same variable;
+   assumes divisor != NULL;
+   p may be NULL;
+   assumes a global monomial ordering in r;
+   performs polynomial division of p by divisor:
+     - afterwards p contains the remainder of the division, i.e.,
+       p_before = result * divisor + p_afterwards;
+     - if needResult == TRUE, then the method computes and returns 'result',
+       otherwise NULL is returned (This parametrization can be used when
+       one is only interested in the remainder of the division. In this
+       case, the method will be slightly faster.)
+   leaves divisor unmodified */
+poly      p_PolyDiv(poly &p, const poly divisor, const BOOLEAN needResult, const ring r)
+{
+  assume(divisor != NULL);
+  if (p == NULL) return NULL;
+
+  poly result = NULL;
+  number divisorLC = p_GetCoeff(divisor, r);
+  int divisorLE = p_GetExp(divisor, 1, r);
+  while ((p != NULL) && (p_Deg(p, r) >= p_Deg(divisor, r)))
+  {
+    /* determine t = LT(p) / LT(divisor) */
+    poly t = p_ISet(1, r);
+    number c = n_Div(p_GetCoeff(p, r), divisorLC, r->cf);
+    n_Normalize(c,r->cf);
+    p_SetCoeff(t, c, r);
+    int e = p_GetExp(p, 1, r) - divisorLE;
+    p_SetExp(t, 1, e, r);
+    p_Setm(t, r);
+    if (needResult) result = p_Add_q(result, p_Copy(t, r), r);
+    p = p_Add_q(p, p_Neg(p_Mult_q(t, p_Copy(divisor, r), r), r), r);
+  }
+  return result;
+}
+
+/*2
+* returns the partial differentiate of a by the k-th variable
+* does not destroy the input
+*/
+poly p_Diff(poly a, int k, const ring r)
+{
+  poly res, f, last;
+  number t;
+
+  last = res = NULL;
+  while (a!=NULL)
+  {
+    if (p_GetExp(a,k,r)!=0)
+    {
+      f = p_LmInit(a,r);
+      t = n_Init(p_GetExp(a,k,r),r->cf);
+      pSetCoeff0(f,n_Mult(t,pGetCoeff(a),r->cf));
+      n_Delete(&t,r->cf);
+      if (n_IsZero(pGetCoeff(f),r->cf))
+        p_LmDelete(&f,r);
+      else
+      {
+        p_DecrExp(f,k,r);
+        p_Setm(f,r);
+        if (res==NULL)
+        {
+          res=last=f;
+        }
+        else
+        {
+          pNext(last)=f;
+          last=f;
+        }
+      }
+    }
+    pIter(a);
+  }
+  return res;
+}
+
+static poly p_DiffOpM(poly a, poly b,BOOLEAN multiply, const ring r)
+{
+  int i,j,s;
+  number n,h,hh;
+  poly p=p_One(r);
+  n=n_Mult(pGetCoeff(a),pGetCoeff(b),r->cf);
+  for(i=rVar(r);i>0;i--)
+  {
+    s=p_GetExp(b,i,r);
+    if (s<p_GetExp(a,i,r))
+    {
+      n_Delete(&n,r->cf);
+      p_LmDelete(&p,r);
+      return NULL;
+    }
+    if (multiply)
+    {
+      for(j=p_GetExp(a,i,r); j>0;j--)
+      {
+        h = n_Init(s,r->cf);
+        hh=n_Mult(n,h,r->cf);
+        n_Delete(&h,r->cf);
+        n_Delete(&n,r->cf);
+        n=hh;
+        s--;
+      }
+      p_SetExp(p,i,s,r);
+    }
+    else
+    {
+      p_SetExp(p,i,s-p_GetExp(a,i,r),r);
+    }
+  }
+  p_Setm(p,r);
+  /*if (multiply)*/ p_SetCoeff(p,n,r);
+  if (n_IsZero(n,r->cf))  p=p_LmDeleteAndNext(p,r); // return NULL as p is a monomial
+  return p;
+}
+
+poly p_DiffOp(poly a, poly b,BOOLEAN multiply, const ring r)
+{
+  poly result=NULL;
+  poly h;
+  for(;a!=NULL;pIter(a))
+  {
+    for(h=b;h!=NULL;pIter(h))
+    {
+      result=p_Add_q(result,p_DiffOpM(a,h,multiply,r),r);
+    }
+  }
+  return result;
+}
+/*2
+* subtract p2 from p1, p1 and p2 are destroyed
+* do not put attention on speed: the procedure is only used in the interpreter
+*/
+poly p_Sub(poly p1, poly p2, const ring r)
+{
+  return p_Add_q(p1, p_Neg(p2,r),r);
+}
+
+/*3
+* compute for a monomial m
+* the power m^exp, exp > 1
+* destroys p
+*/
+static poly p_MonPower(poly p, int exp, const ring r)
+{
+  int i;
+
+  if(!n_IsOne(pGetCoeff(p),r->cf))
+  {
+    number x, y;
+    y = pGetCoeff(p);
+    n_Power(y,exp,&x,r->cf);
+    n_Delete(&y,r->cf);
+    pSetCoeff0(p,x);
+  }
+  for (i=rVar(r); i!=0; i--)
+  {
+    p_MultExp(p,i, exp,r);
+  }
+  p_Setm(p,r);
+  return p;
+}
+
+/*3
+* compute for monomials p*q
+* destroys p, keeps q
+*/
+static void p_MonMult(poly p, poly q, const ring r)
+{
+  number x, y;
+
+  y = pGetCoeff(p);
+  x = n_Mult(y,pGetCoeff(q),r->cf);
+  n_Delete(&y,r->cf);
+  pSetCoeff0(p,x);
+  //for (int i=pVariables; i!=0; i--)
+  //{
+  //  pAddExp(p,i, pGetExp(q,i));
+  //}
+  //p->Order += q->Order;
+  p_ExpVectorAdd(p,q,r);
+}
+
+/*3
+* compute for monomials p*q
+* keeps p, q
+*/
+static poly p_MonMultC(poly p, poly q, const ring rr)
+{
+  number x;
+  poly r = p_Init(rr);
+
+  x = n_Mult(pGetCoeff(p),pGetCoeff(q),rr->cf);
+  pSetCoeff0(r,x);
+  p_ExpVectorSum(r,p, q, rr);
+  return r;
+}
+
+/*3
+*  create binomial coef.
+*/
+static number* pnBin(int exp, const ring r)
+{
+  int e, i, h;
+  number x, y, *bin=NULL;
+
+  x = n_Init(exp,r->cf);
+  if (n_IsZero(x,r->cf))
+  {
+    n_Delete(&x,r->cf);
+    return bin;
+  }
+  h = (exp >> 1) + 1;
+  bin = (number *)omAlloc0(h*sizeof(number));
+  bin[1] = x;
+  if (exp < 4)
+    return bin;
+  i = exp - 1;
+  for (e=2; e<h; e++)
+  {
+      x = n_Init(i,r->cf);
+      i--;
+      y = n_Mult(x,bin[e-1],r->cf);
+      n_Delete(&x,r->cf);
+      x = n_Init(e,r->cf);
+      bin[e] = n_ExactDiv(y,x,r->cf);
+      n_Delete(&x,r->cf);
+      n_Delete(&y,r->cf);
+  }
+  return bin;
+}
+
+static void pnFreeBin(number *bin, int exp,const coeffs r)
+{
+  int e, h = (exp >> 1) + 1;
+
+  if (bin[1] != NULL)
+  {
+    for (e=1; e<h; e++)
+      n_Delete(&(bin[e]),r);
+  }
+  omFreeSize((ADDRESS)bin, h*sizeof(number));
+}
+
+/*
+*  compute for a poly p = head+tail, tail is monomial
+*          (head + tail)^exp, exp > 1
+*          with binomial coef.
+*/
+static poly p_TwoMonPower(poly p, int exp, const ring r)
+{
+  int eh, e;
+  long al;
+  poly *a;
+  poly tail, b, res, h;
+  number x;
+  number *bin = pnBin(exp,r);
+
+  tail = pNext(p);
+  if (bin == NULL)
+  {
+    p_MonPower(p,exp,r);
+    p_MonPower(tail,exp,r);
+    p_Test(p,r);
+    return p;
+  }
+  eh = exp >> 1;
+  al = (exp + 1) * sizeof(poly);
+  a = (poly *)omAlloc(al);
+  a[1] = p;
+  for (e=1; e<exp; e++)
+  {
+    a[e+1] = p_MonMultC(a[e],p,r);
+  }
+  res = a[exp];
+  b = p_Head(tail,r);
+  for (e=exp-1; e>eh; e--)
+  {
+    h = a[e];
+    x = n_Mult(bin[exp-e],pGetCoeff(h),r->cf);
+    p_SetCoeff(h,x,r);
+    p_MonMult(h,b,r);
+    res = pNext(res) = h;
+    p_MonMult(b,tail,r);
+  }
+  for (e=eh; e!=0; e--)
+  {
+    h = a[e];
+    x = n_Mult(bin[e],pGetCoeff(h),r->cf);
+    p_SetCoeff(h,x,r);
+    p_MonMult(h,b,r);
+    res = pNext(res) = h;
+    p_MonMult(b,tail,r);
+  }
+  p_LmDelete(&tail,r);
+  pNext(res) = b;
+  pNext(b) = NULL;
+  res = a[exp];
+  omFreeSize((ADDRESS)a, al);
+  pnFreeBin(bin, exp, r->cf);
+//  tail=res;
+// while((tail!=NULL)&&(pNext(tail)!=NULL))
+// {
+//   if(nIsZero(pGetCoeff(pNext(tail))))
+//   {
+//     pLmDelete(&pNext(tail));
+//   }
+//   else
+//     pIter(tail);
+// }
+  p_Test(res,r);
+  return res;
+}
+
+static poly p_Pow(poly p, int i, const ring r)
+{
+  poly rc = p_Copy(p,r);
+  i -= 2;
+  do
+  {
+    rc = p_Mult_q(rc,p_Copy(p,r),r);
+    p_Normalize(rc,r);
+    i--;
+  }
+  while (i != 0);
+  return p_Mult_q(rc,p,r);
+}
+
+/*2
+* returns the i-th power of p
+* p will be destroyed
+*/
+poly p_Power(poly p, int i, const ring r)
+{
+  poly rc=NULL;
+
+  if (i==0)
+  {
+    p_Delete(&p,r);
+    return p_One(r);
+  }
+
+  if(p!=NULL)
+  {
+    if ( (i > 0) && ((unsigned long ) i > (r->bitmask)))
+    {
+      Werror("exponent %d is too large, max. is %ld",i,r->bitmask);
+      return NULL;
+    }
+    switch (i)
+    {
+// cannot happen, see above
+//      case 0:
+//      {
+//        rc=pOne();
+//        pDelete(&p);
+//        break;
+//      }
+      case 1:
+        rc=p;
+        break;
+      case 2:
+        rc=p_Mult_q(p_Copy(p,r),p,r);
+        break;
+      default:
+        if (i < 0)
+        {
+          p_Delete(&p,r);
+          return NULL;
+        }
+        else
+        {
+#ifdef HAVE_PLURAL
+          if (rIsPluralRing(r)) /* in the NC case nothing helps :-( */
+          {
+            int j=i;
+            rc = p_Copy(p,r);
+            while (j>1)
+            {
+              rc = p_Mult_q(p_Copy(p,r),rc,r);
+              j--;
+            }
+            p_Delete(&p,r);
+            return rc;
+          }
+#endif
+          rc = pNext(p);
+          if (rc == NULL)
+            return p_MonPower(p,i,r);
+          /* else: binom ?*/
+          int char_p=rChar(r);
+          if ((pNext(rc) != NULL)
+#ifdef HAVE_RINGS
+             || rField_is_Ring(r)
+#endif
+             )
+            return p_Pow(p,i,r);
+          if ((char_p==0) || (i<=char_p))
+            return p_TwoMonPower(p,i,r);
+          return p_Pow(p,i,r);
+        }
+      /*end default:*/
+    }
+  }
+  return rc;
+}
+
+/* --------------------------------------------------------------------------------*/
+/* content suff                                                                   */
+
+static number p_InitContent(poly ph, const ring r);
+
+#define CLEARENUMERATORS 1
+
+void p_Content(poly ph, const ring r)
+{
+  assume( ph != NULL );
+
+  assume( r != NULL ); assume( r->cf != NULL );
+
+
+#if CLEARENUMERATORS
+  if( 0 )
+  {
+    const coeffs C = r->cf;
+      // experimentall (recursive enumerator treatment) of alg. Ext!
+    CPolyCoeffsEnumerator itr(ph);
+    n_ClearContent(itr, r->cf);
+
+    p_Test(ph, r); n_Test(pGetCoeff(ph), C);
+    assume(n_GreaterZero(pGetCoeff(ph), C)); // ??
+
+      // if(!n_GreaterZero(pGetCoeff(ph),r->cf)) ph = p_Neg(ph,r);
+    return;
+  }
+#endif
+
+
+#ifdef HAVE_RINGS
+  if (rField_is_Ring(r))
+  {
+    if (rField_has_Units(r))
+    {
+      number k = n_GetUnit(pGetCoeff(ph),r->cf);
+      if (!n_IsOne(k,r->cf))
+      {
+        number tmpGMP = k;
+        k = n_Invers(k,r->cf);
+        n_Delete(&tmpGMP,r->cf);
+        poly h = pNext(ph);
+        p_SetCoeff(ph, n_Mult(pGetCoeff(ph), k,r->cf),r);
+        while (h != NULL)
+        {
+          p_SetCoeff(h, n_Mult(pGetCoeff(h), k,r->cf),r);
+          pIter(h);
+        }
+//        assume( n_GreaterZero(pGetCoeff(ph),r->cf) );
+//        if(!n_GreaterZero(pGetCoeff(ph),r->cf)) ph = p_Neg(ph,r);
+      }
+      n_Delete(&k,r->cf);
+    }
+    return;
+  }
+#endif
+  number h,d;
+  poly p;
+
+  if(TEST_OPT_CONTENTSB) return;
+  if(pNext(ph)==NULL)
+  {
+    p_SetCoeff(ph,n_Init(1,r->cf),r);
+  }
+  else
+  {
+    assume( pNext(ph) != NULL );
+#if CLEARENUMERATORS
+    if( nCoeff_is_Q(r->cf) )
+    {
+      // experimentall (recursive enumerator treatment) of alg. Ext!
+      CPolyCoeffsEnumerator itr(ph);
+      n_ClearContent(itr, r->cf);
+
+      p_Test(ph, r); n_Test(pGetCoeff(ph), r->cf);
+      assume(n_GreaterZero(pGetCoeff(ph), r->cf)); // ??
+
+      // if(!n_GreaterZero(pGetCoeff(ph),r->cf)) ph = p_Neg(ph,r);
+      return;
+    }
+#endif
+
+    n_Normalize(pGetCoeff(ph),r->cf);
+    if(!n_GreaterZero(pGetCoeff(ph),r->cf)) ph = p_Neg(ph,r);
+    if (rField_is_Q(r)) // should not be used anymore if CLEARENUMERATORS is 1
+    {
+      h=p_InitContent(ph,r);
+      p=ph;
+    }
+    else
+    {
+      h=n_Copy(pGetCoeff(ph),r->cf);
+      p = pNext(ph);
+    }
+    while (p!=NULL)
+    {
+      n_Normalize(pGetCoeff(p),r->cf);
+      d=n_SubringGcd(h,pGetCoeff(p),r->cf);
+      n_Delete(&h,r->cf);
+      h = d;
+      if(n_IsOne(h,r->cf))
+      {
+        break;
+      }
+      pIter(p);
+    }
+    p = ph;
+    //number tmp;
+    if(!n_IsOne(h,r->cf))
+    {
+      while (p!=NULL)
+      {
+        //d = nDiv(pGetCoeff(p),h);
+        //tmp = nExactDiv(pGetCoeff(p),h);
+        //if (!nEqual(d,tmp))
+        //{
+        //  StringSetS("** div0:");nWrite(pGetCoeff(p));StringAppendS("/");
+        //  nWrite(h);StringAppendS("=");nWrite(d);StringAppendS(" int:");
+        //  nWrite(tmp);Print(StringEndS("\n")); // NOTE/TODO: use StringAppendS("\n"); omFree(s);
+        //}
+        //nDelete(&tmp);
+        d = n_ExactDiv(pGetCoeff(p),h,r->cf);
+        p_SetCoeff(p,d,r);
+        pIter(p);
+      }
+    }
+    n_Delete(&h,r->cf);
+    if (rField_is_Q_a(r))
+    {
+      // special handling for alg. ext.:
+      if (getCoeffType(r->cf)==n_algExt)
+      {
+        h = n_Init(1, r->cf->extRing->cf);
+        p=ph;
+        while (p!=NULL)
+        { // each monom: coeff in Q_a
+          poly c_n_n=(poly)pGetCoeff(p);
+          poly c_n=c_n_n;
+          while (c_n!=NULL)
+          { // each monom: coeff in Q
+            d=n_NormalizeHelper(h,pGetCoeff(c_n),r->cf->extRing->cf);
+            n_Delete(&h,r->cf->extRing->cf);
+            h=d;
+            pIter(c_n);
+          }
+          pIter(p);
+        }
+        /* h contains the 1/lcm of all denominators in c_n_n*/
+        //n_Normalize(h,r->cf->extRing->cf);
+        if(!n_IsOne(h,r->cf->extRing->cf))
+        {
+          p=ph;
+          while (p!=NULL)
+          { // each monom: coeff in Q_a
+            poly c_n=(poly)pGetCoeff(p);
+            while (c_n!=NULL)
+            { // each monom: coeff in Q
+              d=n_Mult(h,pGetCoeff(c_n),r->cf->extRing->cf);
+              n_Normalize(d,r->cf->extRing->cf);
+              n_Delete(&pGetCoeff(c_n),r->cf->extRing->cf);
+              pGetCoeff(c_n)=d;
+              pIter(c_n);
+            }
+            pIter(p);
+          }
+        }
+        n_Delete(&h,r->cf->extRing->cf);
+      }
+      /*else
+      {
+      // special handling for rat. functions.:
+        number hzz =NULL;
+        p=ph;
+        while (p!=NULL)
+        { // each monom: coeff in Q_a (Z_a)
+          fraction f=(fraction)pGetCoeff(p);
+          poly c_n=NUM(f);
+          if (hzz==NULL)
+          {
+            hzz=n_Copy(pGetCoeff(c_n),r->cf->extRing->cf);
+            pIter(c_n);
+          }
+          while ((c_n!=NULL)&&(!n_IsOne(hzz,r->cf->extRing->cf)))
+          { // each monom: coeff in Q (Z)
+            d=n_Gcd(hzz,pGetCoeff(c_n),r->cf->extRing->cf);
+            n_Delete(&hzz,r->cf->extRing->cf);
+            hzz=d;
+            pIter(c_n);
+          }
+          pIter(p);
+        }
+        // hzz contains the gcd of all numerators in f
+        h=n_Invers(hzz,r->cf->extRing->cf);
+        n_Delete(&hzz,r->cf->extRing->cf);
+        n_Normalize(h,r->cf->extRing->cf);
+        if(!n_IsOne(h,r->cf->extRing->cf))
+        {
+          p=ph;
+          while (p!=NULL)
+          { // each monom: coeff in Q_a (Z_a)
+            fraction f=(fraction)pGetCoeff(p);
+            NUM(f)=p_Mult_nn(NUM(f),h,r->cf->extRing);
+            p_Normalize(NUM(f),r->cf->extRing);
+            pIter(p);
+          }
+        }
+        n_Delete(&h,r->cf->extRing->cf);
+      }*/
+    }
+  }
+  if(!n_GreaterZero(pGetCoeff(ph),r->cf)) ph = p_Neg(ph,r);
+}
+
+// Not yet?
+#if 1 // currently only used by Singular/janet
+void p_SimpleContent(poly ph, int smax, const ring r)
+{
+  if(TEST_OPT_CONTENTSB) return;
+  if (ph==NULL) return;
+  if (pNext(ph)==NULL)
+  {
+    p_SetCoeff(ph,n_Init(1,r->cf),r);
+    return;
+  }
+  if ((pNext(pNext(ph))==NULL)||(!rField_is_Q(r)))
+  {
+    return;
+  }
+  number d=p_InitContent(ph,r);
+  if (n_Size(d,r->cf)<=smax)
+  {
+    //if (TEST_OPT_PROT) PrintS("G");
+    return;
+  }
+
+
+  poly p=ph;
+  number h=d;
+  if (smax==1) smax=2;
+  while (p!=NULL)
+  {
+#if 0
+    d=n_Gcd(h,pGetCoeff(p),r->cf);
+    n_Delete(&h,r->cf);
+    h = d;
+#else
+    STATISTIC(n_Gcd); nlInpGcd(h,pGetCoeff(p),r->cf); // FIXME? TODO? // extern void nlInpGcd(number &a, number b, const coeffs r);
+#endif
+    if(n_Size(h,r->cf)<smax)
+    {
+      //if (TEST_OPT_PROT) PrintS("g");
+      return;
+    }
+    pIter(p);
+  }
+  p = ph;
+  if (!n_GreaterZero(pGetCoeff(p),r->cf)) h=n_InpNeg(h,r->cf);
+  if(n_IsOne(h,r->cf)) return;
+  //if (TEST_OPT_PROT) PrintS("c");
+  while (p!=NULL)
+  {
+#if 1
+    d = n_ExactDiv(pGetCoeff(p),h,r->cf);
+    p_SetCoeff(p,d,r);
+#else
+    STATISTIC(n_ExactDiv); nlInpExactDiv(pGetCoeff(p),h,r->cf); // no such function... ?
+#endif
+    pIter(p);
+  }
+  n_Delete(&h,r->cf);
+}
+#endif
+
+static number p_InitContent(poly ph, const ring r)
+// only for coefficients in Q
+#if 0
+{
+  assume(!TEST_OPT_CONTENTSB);
+  assume(ph!=NULL);
+  assume(pNext(ph)!=NULL);
+  assume(rField_is_Q(r));
+  if (pNext(pNext(ph))==NULL)
+  {
+    return n_GetNumerator(pGetCoeff(pNext(ph)),r->cf);
+  }
+  poly p=ph;
+  number n1=n_GetNumerator(pGetCoeff(p),r->cf);
+  pIter(p);
+  number n2=n_GetNumerator(pGetCoeff(p),r->cf);
+  pIter(p);
+  number d;
+  number t;
+  loop
+  {
+    nlNormalize(pGetCoeff(p),r->cf);
+    t=n_GetNumerator(pGetCoeff(p),r->cf);
+    if (nlGreaterZero(t,r->cf))
+      d=nlAdd(n1,t,r->cf);
+    else
+      d=nlSub(n1,t,r->cf);
+    nlDelete(&t,r->cf);
+    nlDelete(&n1,r->cf);
+    n1=d;
+    pIter(p);
+    if (p==NULL) break;
+    nlNormalize(pGetCoeff(p),r->cf);
+    t=n_GetNumerator(pGetCoeff(p),r->cf);
+    if (nlGreaterZero(t,r->cf))
+      d=nlAdd(n2,t,r->cf);
+    else
+      d=nlSub(n2,t,r->cf);
+    nlDelete(&t,r->cf);
+    nlDelete(&n2,r->cf);
+    n2=d;
+    pIter(p);
+    if (p==NULL) break;
+  }
+  d=nlGcd(n1,n2,r->cf);
+  nlDelete(&n1,r->cf);
+  nlDelete(&n2,r->cf);
+  return d;
+}
+#else
+{
+  number d=pGetCoeff(ph);
+  if(SR_HDL(d)&SR_INT) return d;
+  int s=mpz_size1(d->z);
+  int s2=-1;
+  number d2;
+  loop
+  {
+    pIter(ph);
+    if(ph==NULL)
+    {
+      if (s2==-1) return n_Copy(d,r->cf);
+      break;
+    }
+    if (SR_HDL(pGetCoeff(ph))&SR_INT)
+    {
+      s2=s;
+      d2=d;
+      s=0;
+      d=pGetCoeff(ph);
+      if (s2==0) break;
+    }
+    else
+    if (mpz_size1((pGetCoeff(ph)->z))<=s)
+    {
+      s2=s;
+      d2=d;
+      d=pGetCoeff(ph);
+      s=mpz_size1(d->z);
+    }
+  }
+  return n_Gcd(d,d2,r->cf);
+}
+#endif
+
+//void pContent(poly ph)
+//{
+//  number h,d;
+//  poly p;
+//
+//  p = ph;
+//  if(pNext(p)==NULL)
+//  {
+//    pSetCoeff(p,nInit(1));
+//  }
+//  else
+//  {
+//#ifdef PDEBUG
+//    if (!pTest(p)) return;
+//#endif
+//    nNormalize(pGetCoeff(p));
+//    if(!nGreaterZero(pGetCoeff(ph)))
+//    {
+//      ph = pNeg(ph);
+//      nNormalize(pGetCoeff(p));
+//    }
+//    h=pGetCoeff(p);
+//    pIter(p);
+//    while (p!=NULL)
+//    {
+//      nNormalize(pGetCoeff(p));
+//      if (nGreater(h,pGetCoeff(p))) h=pGetCoeff(p);
+//      pIter(p);
+//    }
+//    h=nCopy(h);
+//    p=ph;
+//    while (p!=NULL)
+//    {
+//      d=n_Gcd(h,pGetCoeff(p));
+//      nDelete(&h);
+//      h = d;
+//      if(nIsOne(h))
+//      {
+//        break;
+//      }
+//      pIter(p);
+//    }
+//    p = ph;
+//    //number tmp;
+//    if(!nIsOne(h))
+//    {
+//      while (p!=NULL)
+//      {
+//        d = nExactDiv(pGetCoeff(p),h);
+//        pSetCoeff(p,d);
+//        pIter(p);
+//      }
+//    }
+//    nDelete(&h);
+//    if ( (nGetChar() == 1) || (nGetChar() < 0) ) /* Q[a],Q(a),Zp[a],Z/p(a) */
+//    {
+//      pTest(ph);
+//      singclap_divide_content(ph);
+//      pTest(ph);
+//    }
+//  }
+//}
+#if 0
+void p_Content(poly ph, const ring r)
+{
+  number h,d;
+  poly p;
+
+  if(pNext(ph)==NULL)
+  {
+    p_SetCoeff(ph,n_Init(1,r->cf),r);
+  }
+  else
+  {
+    n_Normalize(pGetCoeff(ph),r->cf);
+    if(!n_GreaterZero(pGetCoeff(ph),r->cf)) ph = p_Neg(ph,r);
+    h=n_Copy(pGetCoeff(ph),r->cf);
+    p = pNext(ph);
+    while (p!=NULL)
+    {
+      n_Normalize(pGetCoeff(p),r->cf);
+      d=n_Gcd(h,pGetCoeff(p),r->cf);
+      n_Delete(&h,r->cf);
+      h = d;
+      if(n_IsOne(h,r->cf))
+      {
+        break;
+      }
+      pIter(p);
+    }
+    p = ph;
+    //number tmp;
+    if(!n_IsOne(h,r->cf))
+    {
+      while (p!=NULL)
+      {
+        //d = nDiv(pGetCoeff(p),h);
+        //tmp = nExactDiv(pGetCoeff(p),h);
+        //if (!nEqual(d,tmp))
+        //{
+        //  StringSetS("** div0:");nWrite(pGetCoeff(p));StringAppendS("/");
+        //  nWrite(h);StringAppendS("=");nWrite(d);StringAppendS(" int:");
+        //  nWrite(tmp);Print(StringEndS("\n")); // NOTE/TODO: use StringAppendS("\n"); omFree(s);
+        //}
+        //nDelete(&tmp);
+        d = n_ExactDiv(pGetCoeff(p),h,r->cf);
+        p_SetCoeff(p,d,r->cf);
+        pIter(p);
+      }
+    }
+    n_Delete(&h,r->cf);
+    //if ( (n_GetChar(r) == 1) || (n_GetChar(r) < 0) ) /* Q[a],Q(a),Zp[a],Z/p(a) */
+    //{
+    //  singclap_divide_content(ph);
+    //  if(!n_GreaterZero(pGetCoeff(ph),r)) ph = p_Neg(ph,r);
+    //}
+  }
+}
+#endif
+/* ---------------------------------------------------------------------------*/
+/* cleardenom suff                                                           */
+poly p_Cleardenom(poly p, const ring r)
+{
+  if( p == NULL )
+    return NULL;
+
+  assume( r != NULL ); assume( r->cf != NULL ); const coeffs C = r->cf;
+
+#if CLEARENUMERATORS
+  if( 0 )
+  {
+    CPolyCoeffsEnumerator itr(p);
+
+    n_ClearDenominators(itr, C);
+
+    n_ClearContent(itr, C); // divide out the content
+
+    p_Test(p, r); n_Test(pGetCoeff(p), C);
+    assume(n_GreaterZero(pGetCoeff(p), C)); // ??
+//    if(!n_GreaterZero(pGetCoeff(p),C)) p = p_Neg(p,r);
+
+    return p;
+  }
+#endif
+
+
+  number d, h;
+
+#ifdef HAVE_RINGS
+  if (rField_is_Ring(r))
+  {
+    p_Content(p,r);
+    if(!n_GreaterZero(pGetCoeff(p),C)) p = p_Neg(p,r);
+    return p;
+  }
+#endif
+
+  if (rField_is_Zp(r) && TEST_OPT_INTSTRATEGY)
+  {
+    if(!n_GreaterZero(pGetCoeff(p),C)) p = p_Neg(p,r);
+    return p;
+  }
+
+  assume(p != NULL);
+
+  if(pNext(p)==NULL)
+  {
+    /*
+    if (TEST_OPT_CONTENTSB)
+    {
+      number n=n_GetDenom(pGetCoeff(p),r->cf);
+      if (!n_IsOne(n,r->cf))
+      {
+        number nn=n_Mult(pGetCoeff(p),n,r->cf);
+        n_Normalize(nn,r->cf);
+        p_SetCoeff(p,nn,r);
+      }
+      n_Delete(&n,r->cf);
+    }
+    else
+    */
+      p_SetCoeff(p,n_Init(1,r->cf),r);
+
+    /*assume( n_GreaterZero(pGetCoeff(p),C) );
+    if(!n_GreaterZero(pGetCoeff(p),C)) p = p_Neg(p,r);
+    */
+    return p;
+  }
+
+  assume(pNext(p)!=NULL);
+  poly start=p;
+
+#if 0 && CLEARENUMERATORS
+//CF: does not seem to work that well..
+
+  if( nCoeff_is_Q(C) || nCoeff_is_Q_a(C) )
+  {
+    CPolyCoeffsEnumerator itr(p);
+
+    n_ClearDenominators(itr, C);
+
+    n_ClearContent(itr, C); // divide out the content
+
+    p_Test(p, r); n_Test(pGetCoeff(p), C);
+    assume(n_GreaterZero(pGetCoeff(p), C)); // ??
+//    if(!n_GreaterZero(pGetCoeff(p),C)) p = p_Neg(p,r);
+
+    return start;
+  }
+#endif
+
+  if(1)
+  {
+    h = n_Init(1,r->cf);
+    while (p!=NULL)
+    {
+      n_Normalize(pGetCoeff(p),r->cf);
+      d=n_NormalizeHelper(h,pGetCoeff(p),r->cf);
+      n_Delete(&h,r->cf);
+      h=d;
+      pIter(p);
+    }
+    /* contains the 1/lcm of all denominators */
+    if(!n_IsOne(h,r->cf))
+    {
+      p = start;
+      while (p!=NULL)
+      {
+        /* should be: // NOTE: don't use ->coef!!!!
+        * number hh;
+        * nGetDenom(p->coef,&hh);
+        * nMult(&h,&hh,&d);
+        * nNormalize(d);
+        * nDelete(&hh);
+        * nMult(d,p->coef,&hh);
+        * nDelete(&d);
+        * nDelete(&(p->coef));
+        * p->coef =hh;
+        */
+        d=n_Mult(h,pGetCoeff(p),r->cf);
+        n_Normalize(d,r->cf);
+        p_SetCoeff(p,d,r);
+        pIter(p);
+      }
+      n_Delete(&h,r->cf);
+    }
+    n_Delete(&h,r->cf);
+    p=start;
+
+    p_Content(p,r);
+#ifdef HAVE_RATGRING
+    if (rIsRatGRing(r))
+    {
+      /* quick unit detection in the rational case is done in gr_nc_bba */
+      p_ContentRat(p, r);
+      start=p;
+    }
+#endif
+  }
+
+  if(!n_GreaterZero(pGetCoeff(p),C)) p = p_Neg(p,r);
+
+  return start;
+}
+
+void p_Cleardenom_n(poly ph,const ring r,number &c)
+{
+  const coeffs C = r->cf;
+  number d, h;
+
+  assume( ph != NULL );
+
+  poly p = ph;
+
+#if CLEARENUMERATORS
+  if( 0 )
+  {
+    CPolyCoeffsEnumerator itr(ph);
+
+    n_ClearDenominators(itr, d, C); // multiply with common denom. d
+    n_ClearContent(itr, h, C); // divide by the content h
+
+    c = n_Div(d, h, C); // d/h
+
+    n_Delete(&d, C);
+    n_Delete(&h, C);
+
+    n_Test(c, C);
+
+    p_Test(ph, r); n_Test(pGetCoeff(ph), C);
+    assume(n_GreaterZero(pGetCoeff(ph), C)); // ??
+/*
+    if(!n_GreaterZero(pGetCoeff(ph),C))
+    {
+      ph = p_Neg(ph,r);
+      c = n_InpNeg(c, C);
+    }
+*/
+    return;
+  }
+#endif
+
+
+  if( pNext(p) == NULL )
+  {
+    c=n_Invers(pGetCoeff(p), C);
+    p_SetCoeff(p, n_Init(1, C), r);
+
+    assume( n_GreaterZero(pGetCoeff(ph),C) );
+    if(!n_GreaterZero(pGetCoeff(ph),C))
+    {
+      ph = p_Neg(ph,r);
+      c = n_InpNeg(c, C);
+    }
+
+    return;
+  }
+
+  assume( pNext(p) != NULL );
+
+#if CLEARENUMERATORS
+  if( nCoeff_is_Q(C) || nCoeff_is_Q_a(C) )
+  {
+    CPolyCoeffsEnumerator itr(ph);
+
+    n_ClearDenominators(itr, d, C); // multiply with common denom. d
+    n_ClearContent(itr, h, C); // divide by the content h
+
+    c = n_Div(d, h, C); // d/h
+
+    n_Delete(&d, C);
+    n_Delete(&h, C);
+
+    n_Test(c, C);
+
+    p_Test(ph, r); n_Test(pGetCoeff(ph), C);
+    assume(n_GreaterZero(pGetCoeff(ph), C)); // ??
+/*
+    if(!n_GreaterZero(pGetCoeff(ph),C))
+    {
+      ph = p_Neg(ph,r);
+      c = n_InpNeg(c, C);
+    }
+*/
+    return;
+  }
+#endif
+
+
+
+
+  if(1)
+  {
+    h = n_Init(1,r->cf);
+    while (p!=NULL)
+    {
+      n_Normalize(pGetCoeff(p),r->cf);
+      d=n_NormalizeHelper(h,pGetCoeff(p),r->cf);
+      n_Delete(&h,r->cf);
+      h=d;
+      pIter(p);
+    }
+    c=h;
+    /* contains the 1/lcm of all denominators */
+    if(!n_IsOne(h,r->cf))
+    {
+      p = ph;
+      while (p!=NULL)
+      {
+        /* should be: // NOTE: don't use ->coef!!!!
+        * number hh;
+        * nGetDenom(p->coef,&hh);
+        * nMult(&h,&hh,&d);
+        * nNormalize(d);
+        * nDelete(&hh);
+        * nMult(d,p->coef,&hh);
+        * nDelete(&d);
+        * nDelete(&(p->coef));
+        * p->coef =hh;
+        */
+        d=n_Mult(h,pGetCoeff(p),r->cf);
+        n_Normalize(d,r->cf);
+        p_SetCoeff(p,d,r);
+        pIter(p);
+      }
+      if (rField_is_Q_a(r))
+      {
+        loop
+        {
+          h = n_Init(1,r->cf);
+          p=ph;
+          while (p!=NULL)
+          {
+            d=n_NormalizeHelper(h,pGetCoeff(p),r->cf);
+            n_Delete(&h,r->cf);
+            h=d;
+            pIter(p);
+          }
+          /* contains the 1/lcm of all denominators */
+          if(!n_IsOne(h,r->cf))
+          {
+            p = ph;
+            while (p!=NULL)
+            {
+              /* should be: // NOTE: don't use ->coef!!!!
+              * number hh;
+              * nGetDenom(p->coef,&hh);
+              * nMult(&h,&hh,&d);
+              * nNormalize(d);
+              * nDelete(&hh);
+              * nMult(d,p->coef,&hh);
+              * nDelete(&d);
+              * nDelete(&(p->coef));
+              * p->coef =hh;
+              */
+              d=n_Mult(h,pGetCoeff(p),r->cf);
+              n_Normalize(d,r->cf);
+              p_SetCoeff(p,d,r);
+              pIter(p);
+            }
+            number t=n_Mult(c,h,r->cf);
+            n_Delete(&c,r->cf);
+            c=t;
+          }
+          else
+          {
+            break;
+          }
+          n_Delete(&h,r->cf);
+        }
+      }
+    }
+  }
+
+  if(!n_GreaterZero(pGetCoeff(ph),C))
+  {
+    ph = p_Neg(ph,r);
+    c = n_InpNeg(c, C);
+  }
+
+}
+
+  // normalization: for poly over Q: make poly primitive, integral
+  //                              Qa make poly integral with leading
+  //                                  coefficient minimal in N
+  //                            Q(t) make poly primitive, integral
+
+void p_ProjectiveUnique(poly ph, const ring r)
+{
+  if( ph == NULL )
+    return;
+
+  assume( r != NULL ); assume( r->cf != NULL ); const coeffs C = r->cf;
+
+  number h;
+  poly p;
+
+#ifdef HAVE_RINGS
+  if (rField_is_Ring(r))
+  {
+    p_Content(ph,r);
+    if(!n_GreaterZero(pGetCoeff(ph),C)) ph = p_Neg(ph,r);
+        assume( n_GreaterZero(pGetCoeff(ph),C) );
+    return;
+  }
+#endif
+
+  if (rField_is_Zp(r) && TEST_OPT_INTSTRATEGY)
+  {
+    assume( n_GreaterZero(pGetCoeff(ph),C) );
+    if(!n_GreaterZero(pGetCoeff(ph),C)) ph = p_Neg(ph,r);
+    return;
+  }
+  p = ph;
+
+  assume(p != NULL);
+
+  if(pNext(p)==NULL) // a monomial
+  {
+    p_SetCoeff(p, n_Init(1, C), r);
+    return;
+  }
+
+  assume(pNext(p)!=NULL);
+
+  if(!rField_is_Q(r) && !nCoeff_is_transExt(C))
+  {
+    h = p_GetCoeff(p, C);
+    number hInv = n_Invers(h, C);
+    pIter(p);
+    while (p!=NULL)
+    {
+      p_SetCoeff(p, n_Mult(p_GetCoeff(p, C), hInv, C), r);
+      pIter(p);
+    }
+    n_Delete(&hInv, C);
+    p = ph;
+    p_SetCoeff(p, n_Init(1, C), r);
+  }
+
+  p_Cleardenom(ph, r); //performs also a p_Content
+
+
+    /* normalize ph over a transcendental extension s.t.
+       lead (ph) is > 0 if extRing->cf == Q
+       or lead (ph) is monic if extRing->cf == Zp*/
+  if (nCoeff_is_transExt(C))
+  {
+    p= ph;
+    h= p_GetCoeff (p, C);
+    fraction f = (fraction) h;
+    number n=p_GetCoeff (NUM (f),C->extRing->cf);
+    if (rField_is_Q (C->extRing))
+    {
+      if (!n_GreaterZero(n,C->extRing->cf))
+      {
+        p=p_Neg (p,r);
+      }
+    }
+    else if (rField_is_Zp(C->extRing))
+    {
+      if (!n_IsOne (n, C->extRing->cf))
+      {
+        n=n_Invers (n,C->extRing->cf);
+        nMapFunc nMap;
+        nMap= n_SetMap (C->extRing->cf, C);
+        number ninv= nMap (n,C->extRing->cf, C);
+        p=p_Mult_nn (p, ninv, r);
+        n_Delete (&ninv, C);
+        n_Delete (&n, C->extRing->cf);
+      }
+    }
+    p= ph;
+  }
+
+  return;
+}
+
+#if 0   /*unused*/
+number p_GetAllDenom(poly ph, const ring r)
+{
+  number d=n_Init(1,r->cf);
+  poly p = ph;
+
+  while (p!=NULL)
+  {
+    number h=n_GetDenom(pGetCoeff(p),r->cf);
+    if (!n_IsOne(h,r->cf))
+    {
+      number dd=n_Mult(d,h,r->cf);
+      n_Delete(&d,r->cf);
+      d=dd;
+    }
+    n_Delete(&h,r->cf);
+    pIter(p);
+  }
+  return d;
+}
+#endif
+
+int p_Size(poly p, const ring r)
+{
+  int count = 0;
+  while ( p != NULL )
+  {
+    count+= n_Size( pGetCoeff( p ), r->cf );
+    pIter( p );
+  }
+  return count;
+}
+
+/*2
+*make p homogeneous by multiplying the monomials by powers of x_varnum
+*assume: deg(var(varnum))==1
+*/
+poly p_Homogen (poly p, int varnum, const ring r)
+{
+  pFDegProc deg;
+  if (r->pLexOrder && (r->order[0]==ringorder_lp))
+    deg=p_Totaldegree;
+  else
+    deg=r->pFDeg;
+
+  poly q=NULL, qn;
+  int  o,ii;
+  sBucket_pt bp;
+
+  if (p!=NULL)
+  {
+    if ((varnum < 1) || (varnum > rVar(r)))
+    {
+      return NULL;
+    }
+    o=deg(p,r);
+    q=pNext(p);
+    while (q != NULL)
+    {
+      ii=deg(q,r);
+      if (ii>o) o=ii;
+      pIter(q);
+    }
+    q = p_Copy(p,r);
+    bp = sBucketCreate(r);
+    while (q != NULL)
+    {
+      ii = o-deg(q,r);
+      if (ii!=0)
+      {
+        p_AddExp(q,varnum, (long)ii,r);
+        p_Setm(q,r);
+      }
+      qn = pNext(q);
+      pNext(q) = NULL;
+      sBucket_Add_p(bp, q, 1);
+      q = qn;
+    }
+    sBucketDestroyAdd(bp, &q, &ii);
+  }
+  return q;
+}
+
+/*2
+*tests if p is homogeneous with respect to the actual weigths
+*/
+BOOLEAN p_IsHomogeneous (poly p, const ring r)
+{
+  poly qp=p;
+  int o;
+
+  if ((p == NULL) || (pNext(p) == NULL)) return TRUE;
+  pFDegProc d;
+  if (r->pLexOrder && (r->order[0]==ringorder_lp))
+    d=p_Totaldegree;
+  else
+    d=r->pFDeg;
+  o = d(p,r);
+  do
+  {
+    if (d(qp,r) != o) return FALSE;
+    pIter(qp);
+  }
+  while (qp != NULL);
+  return TRUE;
+}
+
+/*----------utilities for syzygies--------------*/
+BOOLEAN   p_VectorHasUnitB(poly p, int * k, const ring r)
+{
+  poly q=p,qq;
+  int i;
+
+  while (q!=NULL)
+  {
+    if (p_LmIsConstantComp(q,r))
+    {
+      i = p_GetComp(q,r);
+      qq = p;
+      while ((qq != q) && (p_GetComp(qq,r) != i)) pIter(qq);
+      if (qq == q)
+      {
+        *k = i;
+        return TRUE;
+      }
+      else
+        pIter(q);
+    }
+    else pIter(q);
+  }
+  return FALSE;
+}
+
+void   p_VectorHasUnit(poly p, int * k, int * len, const ring r)
+{
+  poly q=p,qq;
+  int i,j=0;
+
+  *len = 0;
+  while (q!=NULL)
+  {
+    if (p_LmIsConstantComp(q,r))
+    {
+      i = p_GetComp(q,r);
+      qq = p;
+      while ((qq != q) && (p_GetComp(qq,r) != i)) pIter(qq);
+      if (qq == q)
+      {
+       j = 0;
+       while (qq!=NULL)
+       {
+         if (p_GetComp(qq,r)==i) j++;
+        pIter(qq);
+       }
+       if ((*len == 0) || (j<*len))
+       {
+         *len = j;
+         *k = i;
+       }
+      }
+    }
+    pIter(q);
+  }
+}
+
+poly p_TakeOutComp1(poly * p, int k, const ring r)
+{
+  poly q = *p;
+
+  if (q==NULL) return NULL;
+
+  poly qq=NULL,result = NULL;
+
+  if (p_GetComp(q,r)==k)
+  {
+    result = q; /* *p */
+    while ((q!=NULL) && (p_GetComp(q,r)==k))
+    {
+      p_SetComp(q,0,r);
+      p_SetmComp(q,r);
+      qq = q;
+      pIter(q);
+    }
+    *p = q;
+    pNext(qq) = NULL;
+  }
+  if (q==NULL) return result;
+//  if (pGetComp(q) > k) pGetComp(q)--;
+  while (pNext(q)!=NULL)
+  {
+    if (p_GetComp(pNext(q),r)==k)
+    {
+      if (result==NULL)
+      {
+        result = pNext(q);
+        qq = result;
+      }
+      else
+      {
+        pNext(qq) = pNext(q);
+        pIter(qq);
+      }
+      pNext(q) = pNext(pNext(q));
+      pNext(qq) =NULL;
+      p_SetComp(qq,0,r);
+      p_SetmComp(qq,r);
+    }
+    else
+    {
+      pIter(q);
+//      if (pGetComp(q) > k) pGetComp(q)--;
+    }
+  }
+  return result;
+}
+
+poly p_TakeOutComp(poly * p, int k, const ring r)
+{
+  poly q = *p,qq=NULL,result = NULL;
+
+  if (q==NULL) return NULL;
+  BOOLEAN use_setmcomp=rOrd_SetCompRequiresSetm(r);
+  if (p_GetComp(q,r)==k)
+  {
+    result = q;
+    do
+    {
+      p_SetComp(q,0,r);
+      if (use_setmcomp) p_SetmComp(q,r);
+      qq = q;
+      pIter(q);
+    }
+    while ((q!=NULL) && (p_GetComp(q,r)==k));
+    *p = q;
+    pNext(qq) = NULL;
+  }
+  if (q==NULL) return result;
+  if (p_GetComp(q,r) > k)
+  {
+    p_SubComp(q,1,r);
+    if (use_setmcomp) p_SetmComp(q,r);
+  }
+  poly pNext_q;
+  while ((pNext_q=pNext(q))!=NULL)
+  {
+    if (p_GetComp(pNext_q,r)==k)
+    {
+      if (result==NULL)
+      {
+        result = pNext_q;
+        qq = result;
+      }
+      else
+      {
+        pNext(qq) = pNext_q;
+        pIter(qq);
+      }
+      pNext(q) = pNext(pNext_q);
+      pNext(qq) =NULL;
+      p_SetComp(qq,0,r);
+      if (use_setmcomp) p_SetmComp(qq,r);
+    }
+    else
+    {
+      /*pIter(q);*/ q=pNext_q;
+      if (p_GetComp(q,r) > k)
+      {
+        p_SubComp(q,1,r);
+        if (use_setmcomp) p_SetmComp(q,r);
+      }
+    }
+  }
+  return result;
+}
+
+// Splits *p into two polys: *q which consists of all monoms with
+// component == comp and *p of all other monoms *lq == pLength(*q)
+void p_TakeOutComp(poly *r_p, long comp, poly *r_q, int *lq, const ring r)
+{
+  spolyrec pp, qq;
+  poly p, q, p_prev;
+  int l = 0;
+
+#ifdef HAVE_ASSUME
+  int lp = pLength(*r_p);
+#endif
+
+  pNext(&pp) = *r_p;
+  p = *r_p;
+  p_prev = &pp;
+  q = &qq;
+
+  while(p != NULL)
+  {
+    while (p_GetComp(p,r) == comp)
+    {
+      pNext(q) = p;
+      pIter(q);
+      p_SetComp(p, 0,r);
+      p_SetmComp(p,r);
+      pIter(p);
+      l++;
+      if (p == NULL)
+      {
+        pNext(p_prev) = NULL;
+        goto Finish;
+      }
+    }
+    pNext(p_prev) = p;
+    p_prev = p;
+    pIter(p);
+  }
+
+  Finish:
+  pNext(q) = NULL;
+  *r_p = pNext(&pp);
+  *r_q = pNext(&qq);
+  *lq = l;
+#ifdef HAVE_ASSUME
+  assume(pLength(*r_p) + pLength(*r_q) == lp);
+#endif
+  p_Test(*r_p,r);
+  p_Test(*r_q,r);
+}
+
+void p_DeleteComp(poly * p,int k, const ring r)
+{
+  poly q;
+
+  while ((*p!=NULL) && (p_GetComp(*p,r)==k)) p_LmDelete(p,r);
+  if (*p==NULL) return;
+  q = *p;
+  if (p_GetComp(q,r)>k)
+  {
+    p_SubComp(q,1,r);
+    p_SetmComp(q,r);
+  }
+  while (pNext(q)!=NULL)
+  {
+    if (p_GetComp(pNext(q),r)==k)
+      p_LmDelete(&(pNext(q)),r);
+    else
+    {
+      pIter(q);
+      if (p_GetComp(q,r)>k)
+      {
+        p_SubComp(q,1,r);
+        p_SetmComp(q,r);
+      }
+    }
+  }
+}
+
+/*2
+* convert a vector to a set of polys,
+* allocates the polyset, (entries 0..(*len)-1)
+* the vector will not be changed
+*/
+void  p_Vec2Polys(poly v, poly* *p, int *len, const ring r)
+{
+  poly h;
+  int k;
+
+  *len=p_MaxComp(v,r);
+  if (*len==0) *len=1;
+  *p=(poly*)omAlloc0((*len)*sizeof(poly));
+  while (v!=NULL)
+  {
+    h=p_Head(v,r);
+    k=p_GetComp(h,r);
+    p_SetComp(h,0,r);
+    (*p)[k-1]=p_Add_q((*p)[k-1],h,r);
+    pIter(v);
+  }
+}
+
+//
+// resets the pFDeg and pLDeg: if pLDeg is not given, it is
+// set to currRing->pLDegOrig, i.e. to the respective LDegProc which
+// only uses pFDeg (and not p_Deg, or pTotalDegree, etc)
+void pSetDegProcs(ring r, pFDegProc new_FDeg, pLDegProc new_lDeg)
+{
+  assume(new_FDeg != NULL);
+  r->pFDeg = new_FDeg;
+
+  if (new_lDeg == NULL)
+    new_lDeg = r->pLDegOrig;
+
+  r->pLDeg = new_lDeg;
+}
+
+// restores pFDeg and pLDeg:
+void pRestoreDegProcs(ring r, pFDegProc old_FDeg, pLDegProc old_lDeg)
+{
+  assume(old_FDeg != NULL && old_lDeg != NULL);
+  r->pFDeg = old_FDeg;
+  r->pLDeg = old_lDeg;
+}
+
+/*-------- several access procedures to monomials -------------------- */
+/*
+* the module weights for std
+*/
+static pFDegProc pOldFDeg;
+static pLDegProc pOldLDeg;
+static BOOLEAN pOldLexOrder;
+
+static long pModDeg(poly p, ring r)
+{
+  long d=pOldFDeg(p, r);
+  int c=p_GetComp(p, r);
+  if ((c>0) && ((r->pModW)->range(c-1))) d+= (*(r->pModW))[c-1];
+  return d;
+  //return pOldFDeg(p, r)+(*pModW)[p_GetComp(p, r)-1];
+}
+
+void p_SetModDeg(intvec *w, ring r)
+{
+  if (w!=NULL)
+  {
+    r->pModW = w;
+    pOldFDeg = r->pFDeg;
+    pOldLDeg = r->pLDeg;
+    pOldLexOrder = r->pLexOrder;
+    pSetDegProcs(r,pModDeg);
+    r->pLexOrder = TRUE;
+  }
+  else
+  {
+    r->pModW = NULL;
+    pRestoreDegProcs(r,pOldFDeg, pOldLDeg);
+    r->pLexOrder = pOldLexOrder;
+  }
+}
+
+/*2
+* handle memory request for sets of polynomials (ideals)
+* l is the length of *p, increment is the difference (may be negative)
+*/
+void pEnlargeSet(poly* *p, int l, int increment)
+{
+  poly* h;
+
+  h=(poly*)omReallocSize((poly*)*p,l*sizeof(poly),(l+increment)*sizeof(poly));
+  if (increment>0)
+  {
+    //for (i=l; i<l+increment; i++)
+    //  h[i]=NULL;
+    memset(&(h[l]),0,increment*sizeof(poly));
+  }
+  *p=h;
+}
+
+/*2
+*divides p1 by its leading coefficient
+*/
+void p_Norm(poly p1, const ring r)
+{
+#ifdef HAVE_RINGS
+  if (rField_is_Ring(r))
+  {
+    if (!n_IsUnit(pGetCoeff(p1), r->cf)) return;
+    // Werror("p_Norm not possible in the case of coefficient rings.");
+  }
+  else
+#endif
+  if (p1!=NULL)
+  {
+    if (pNext(p1)==NULL)
+    {
+      p_SetCoeff(p1,n_Init(1,r->cf),r);
+      return;
+    }
+    poly h;
+    if (!n_IsOne(pGetCoeff(p1),r->cf))
+    {
+      number k, c;
+      n_Normalize(pGetCoeff(p1),r->cf);
+      k = pGetCoeff(p1);
+      c = n_Init(1,r->cf);
+      pSetCoeff0(p1,c);
+      h = pNext(p1);
+      while (h!=NULL)
+      {
+        c=n_Div(pGetCoeff(h),k,r->cf);
+        // no need to normalize: Z/p, R
+        // normalize already in nDiv: Q_a, Z/p_a
+        // remains: Q
+        if (rField_is_Q(r) && (!n_IsOne(c,r->cf))) n_Normalize(c,r->cf);
+        p_SetCoeff(h,c,r);
+        pIter(h);
+      }
+      n_Delete(&k,r->cf);
+    }
+    else
+    {
+      //if (r->cf->cfNormalize != nDummy2) //TODO: OPTIMIZE
+      {
+        h = pNext(p1);
+        while (h!=NULL)
+        {
+          n_Normalize(pGetCoeff(h),r->cf);
+          pIter(h);
+        }
+      }
+    }
+  }
+}
+
+/*2
+*normalize all coefficients
+*/
+void p_Normalize(poly p,const ring r)
+{
+  if (rField_has_simple_inverse(r)) return; /* Z/p, GF(p,n), R, long R/C */
+  while (p!=NULL)
+  {
+#ifdef LDEBUG
+    n_Test(pGetCoeff(p), r->cf);
+#endif
+    n_Normalize(pGetCoeff(p),r->cf);
+    pIter(p);
+  }
+}
+
+// splits p into polys with Exp(n) == 0 and Exp(n) != 0
+// Poly with Exp(n) != 0 is reversed
+static void p_SplitAndReversePoly(poly p, int n, poly *non_zero, poly *zero, const ring r)
+{
+  if (p == NULL)
+  {
+    *non_zero = NULL;
+    *zero = NULL;
+    return;
+  }
+  spolyrec sz;
+  poly z, n_z, next;
+  z = &sz;
+  n_z = NULL;
+
+  while(p != NULL)
+  {
+    next = pNext(p);
+    if (p_GetExp(p, n,r) == 0)
+    {
+      pNext(z) = p;
+      pIter(z);
+    }
+    else
+    {
+      pNext(p) = n_z;
+      n_z = p;
+    }
+    p = next;
+  }
+  pNext(z) = NULL;
+  *zero = pNext(&sz);
+  *non_zero = n_z;
+}
+/*3
+* substitute the n-th variable by 1 in p
+* destroy p
+*/
+static poly p_Subst1 (poly p,int n, const ring r)
+{
+  poly qq=NULL, result = NULL;
+  poly zero=NULL, non_zero=NULL;
+
+  // reverse, so that add is likely to be linear
+  p_SplitAndReversePoly(p, n, &non_zero, &zero,r);
+
+  while (non_zero != NULL)
+  {
+    assume(p_GetExp(non_zero, n,r) != 0);
+    qq = non_zero;
+    pIter(non_zero);
+    qq->next = NULL;
+    p_SetExp(qq,n,0,r);
+    p_Setm(qq,r);
+    result = p_Add_q(result,qq,r);
+  }
+  p = p_Add_q(result, zero,r);
+  p_Test(p,r);
+  return p;
+}
+
+/*3
+* substitute the n-th variable by number e in p
+* destroy p
+*/
+static poly p_Subst2 (poly p,int n, number e, const ring r)
+{
+  assume( ! n_IsZero(e,r->cf) );
+  poly qq,result = NULL;
+  number nn, nm;
+  poly zero, non_zero;
+
+  // reverse, so that add is likely to be linear
+  p_SplitAndReversePoly(p, n, &non_zero, &zero,r);
+
+  while (non_zero != NULL)
+  {
+    assume(p_GetExp(non_zero, n, r) != 0);
+    qq = non_zero;
+    pIter(non_zero);
+    qq->next = NULL;
+    n_Power(e, p_GetExp(qq, n, r), &nn,r->cf);
+    nm = n_Mult(nn, pGetCoeff(qq),r->cf);
+#ifdef HAVE_RINGS
+    if (n_IsZero(nm,r->cf))
+    {
+      p_LmFree(&qq,r);
+      n_Delete(&nm,r->cf);
+    }
+    else
+#endif
+    {
+      p_SetCoeff(qq, nm,r);
+      p_SetExp(qq, n, 0,r);
+      p_Setm(qq,r);
+      result = p_Add_q(result,qq,r);
+    }
+    n_Delete(&nn,r->cf);
+  }
+  p = p_Add_q(result, zero,r);
+  p_Test(p,r);
+  return p;
+}
+
+
+/* delete monoms whose n-th exponent is different from zero */
+static poly p_Subst0(poly p, int n, const ring r)
+{
+  spolyrec res;
+  poly h = &res;
+  pNext(h) = p;
+
+  while (pNext(h)!=NULL)
+  {
+    if (p_GetExp(pNext(h),n,r)!=0)
+    {
+      p_LmDelete(&pNext(h),r);
+    }
+    else
+    {
+      pIter(h);
+    }
+  }
+  p_Test(pNext(&res),r);
+  return pNext(&res);
+}
+
+/*2
+* substitute the n-th variable by e in p
+* destroy p
+*/
+poly p_Subst(poly p, int n, poly e, const ring r)
+{
+  if (e == NULL) return p_Subst0(p, n,r);
+
+  if (p_IsConstant(e,r))
+  {
+    if (n_IsOne(pGetCoeff(e),r->cf)) return p_Subst1(p,n,r);
+    else return p_Subst2(p, n, pGetCoeff(e),r);
+  }
+
+#ifdef HAVE_PLURAL
+  if (rIsPluralRing(r))
+  {
+    return nc_pSubst(p,n,e,r);
+  }
+#endif
+
+  int exponent,i;
+  poly h, res, m;
+  int *me,*ee;
+  number nu,nu1;
+
+  me=(int *)omAlloc((rVar(r)+1)*sizeof(int));
+  ee=(int *)omAlloc((rVar(r)+1)*sizeof(int));
+  if (e!=NULL) p_GetExpV(e,ee,r);
+  res=NULL;
+  h=p;
+  while (h!=NULL)
+  {
+    if ((e!=NULL) || (p_GetExp(h,n,r)==0))
+    {
+      m=p_Head(h,r);
+      p_GetExpV(m,me,r);
+      exponent=me[n];
+      me[n]=0;
+      for(i=rVar(r);i>0;i--)
+        me[i]+=exponent*ee[i];
+      p_SetExpV(m,me,r);
+      if (e!=NULL)
+      {
+        n_Power(pGetCoeff(e),exponent,&nu,r->cf);
+        nu1=n_Mult(pGetCoeff(m),nu,r->cf);
+        n_Delete(&nu,r->cf);
+        p_SetCoeff(m,nu1,r);
+      }
+      res=p_Add_q(res,m,r);
+    }
+    p_LmDelete(&h,r);
+  }
+  omFreeSize((ADDRESS)me,(rVar(r)+1)*sizeof(int));
+  omFreeSize((ADDRESS)ee,(rVar(r)+1)*sizeof(int));
+  return res;
+}
+
+/*2
+ * returns a re-ordered convertion of a number as a polynomial,
+ * with permutation of parameters
+ * NOTE: this only works for Frank's alg. & trans. fields
+ */
+poly n_PermNumber(const number z, const int *par_perm, const int , const ring src, const ring dst)
+{
+#if 0
+  PrintS("\nSource Ring: \n");
+  rWrite(src);
+
+  if(0)
+  {
+    number zz = n_Copy(z, src->cf);
+    PrintS("z: "); n_Write(zz, src);
+    n_Delete(&zz, src->cf);
+  }
+
+  PrintS("\nDestination Ring: \n");
+  rWrite(dst);
+
+  /*Print("\nOldPar: %d\n", OldPar);
+  for( int i = 1; i <= OldPar; i++ )
+  {
+    Print("par(%d) -> par/var (%d)\n", i, par_perm[i-1]);
+  }*/
+#endif
+  if( z == NULL )
+     return NULL;
+
+  const coeffs srcCf = src->cf;
+  assume( srcCf != NULL );
+
+  assume( !nCoeff_is_GF(srcCf) );
+  assume( src->cf->extRing!=NULL );
+
+  poly zz = NULL;
+
+  const ring srcExtRing = srcCf->extRing;
+  assume( srcExtRing != NULL );
+
+  const coeffs dstCf = dst->cf;
+  assume( dstCf != NULL );
+
+  if( nCoeff_is_algExt(srcCf) ) // nCoeff_is_GF(srcCf)?
+  {
+    zz = (poly) z;
+    if( zz == NULL ) return NULL;
+  }
+  else if (nCoeff_is_transExt(srcCf))
+  {
+    assume( !IS0(z) );
+
+    zz = NUM(z);
+    p_Test (zz, srcExtRing);
+
+    if( zz == NULL ) return NULL;
+    if( !DENIS1(z) )
+    {
+      if (p_IsConstant(DEN(z),srcExtRing))
+      {
+        number n=pGetCoeff(DEN(z));
+        zz=p_Div_nn(zz,n,srcExtRing);
+        p_Normalize(zz,srcExtRing);
+      }
+      else
+        WarnS("Not defined: Cannot map a rational fraction and make a polynomial out of it! Ignoring the denumerator.");
+    }
+  }
+  else
+  {
+    assume (FALSE);
+    Werror("Number permutation is not implemented for this data yet!");
+    return NULL;
+  }
+
+  assume( zz != NULL );
+  p_Test (zz, srcExtRing);
+
+  nMapFunc nMap = n_SetMap(srcExtRing->cf, dstCf);
+
+  assume( nMap != NULL );
+
+  poly qq;
+  if ((par_perm == NULL) && (rPar(dst) != 0 && rVar (srcExtRing) > 0))
+  {
+    int* perm;
+    perm=(int *)omAlloc0((rVar(srcExtRing)+1)*sizeof(int));
+    perm[0]= 0;
+    for(int i=si_min(rVar(srcExtRing),rPar(dst));i>0;i--)
+      perm[i]=-i;
+    qq = p_PermPoly(zz, perm, srcExtRing, dst, nMap, NULL, rVar(srcExtRing)-1);
+    omFreeSize ((ADDRESS)perm, (rVar(srcExtRing)+1)*sizeof(int));
+  }
+  else
+    qq = p_PermPoly(zz, par_perm-1, srcExtRing, dst, nMap, NULL, rVar (srcExtRing)-1);
+
+  p_Test (qq, dst);
+
+//       poly p_PermPoly (poly p, int * perm, const ring oldRing, const ring dst, nMapFunc nMap, int *par_perm, int OldPar)
+
+//  assume( FALSE );  WarnS("longalg missing 2");
+
+  return qq;
+}
+
+
+/*2
+*returns a re-ordered copy of a polynomial, with permutation of the variables
+*/
+poly p_PermPoly (poly p, const int * perm, const ring oldRing, const ring dst,
+       nMapFunc nMap, const int *par_perm, int OldPar)
+{
+#if 0
+    p_Test(p, oldRing);
+    PrintS("\np_PermPoly::p: "); p_Write(p, oldRing, oldRing); PrintLn();
+#endif
+
+  const int OldpVariables = rVar(oldRing);
+  poly result = NULL;
+  poly result_last = NULL;
+  poly aq = NULL; /* the map coefficient */
+  poly qq; /* the mapped monomial */
+
+  assume(dst != NULL);
+  assume(dst->cf != NULL);
+
+  while (p != NULL)
+  {
+    // map the coefficient
+    if ( ((OldPar == 0) || (par_perm == NULL) || rField_is_GF(oldRing)) && (nMap != NULL) )
+    {
+      qq = p_Init(dst);
+      assume( nMap != NULL );
+
+      number n = nMap(p_GetCoeff(p, oldRing), oldRing->cf, dst->cf);
+
+      n_Test (n,dst->cf);
+
+      if ( nCoeff_is_algExt(dst->cf) )
+        n_Normalize(n, dst->cf);
+
+      p_GetCoeff(qq, dst) = n;// Note: n can be a ZERO!!!
+      // coef may be zero:
+//      p_Test(qq, dst);
+    }
+    else
+    {
+      qq = p_One(dst);
+
+//      aq = naPermNumber(p_GetCoeff(p, oldRing), par_perm, OldPar, oldRing); // no dst???
+//      poly    n_PermNumber(const number z, const int *par_perm, const int P, const ring src, const ring dst)
+      aq = n_PermNumber(p_GetCoeff(p, oldRing), par_perm, OldPar, oldRing, dst);
+
+      p_Test(aq, dst);
+
+      if ( nCoeff_is_algExt(dst->cf) )
+        p_Normalize(aq,dst);
+
+      if (aq == NULL)
+        p_SetCoeff(qq, n_Init(0, dst->cf),dst); // Very dirty trick!!!
+
+      p_Test(aq, dst);
+    }
+
+    if (rRing_has_Comp(dst))
+       p_SetComp(qq, p_GetComp(p, oldRing), dst);
+
+    if ( n_IsZero(pGetCoeff(qq), dst->cf) )
+    {
+      p_LmDelete(&qq,dst);
+      qq = NULL;
+    }
+    else
+    {
+      // map pars:
+      int mapped_to_par = 0;
+      for(int i = 1; i <= OldpVariables; i++)
+      {
+        int e = p_GetExp(p, i, oldRing);
+        if (e != 0)
+        {
+          if (perm==NULL)
+            p_SetExp(qq, i, e, dst);
+          else if (perm[i]>0)
+            p_AddExp(qq,perm[i], e/*p_GetExp( p,i,oldRing)*/, dst);
+          else if (perm[i]<0)
+          {
+            number c = p_GetCoeff(qq, dst);
+            if (rField_is_GF(dst))
+            {
+              assume( dst->cf->extRing == NULL );
+              number ee = n_Param(1, dst);
+
+              number eee;
+              n_Power(ee, e, &eee, dst->cf); //nfDelete(ee,dst);
+
+              ee = n_Mult(c, eee, dst->cf);
+              //nfDelete(c,dst);nfDelete(eee,dst);
+              pSetCoeff0(qq,ee);
+            }
+            else if (nCoeff_is_Extension(dst->cf))
+            {
+              const int par = -perm[i];
+              assume( par > 0 );
+
+//              WarnS("longalg missing 3");
+#if 1
+              const coeffs C = dst->cf;
+              assume( C != NULL );
+
+              const ring R = C->extRing;
+              assume( R != NULL );
+
+              assume( par <= rVar(R) );
+
+              poly pcn; // = (number)c
+
+              assume( !n_IsZero(c, C) );
+
+              if( nCoeff_is_algExt(C) )
+                 pcn = (poly) c;
+               else //            nCoeff_is_transExt(C)
+                 pcn = NUM(c);
+
+              if (pNext(pcn) == NULL) // c->z
+                p_AddExp(pcn, -perm[i], e, R);
+              else /* more difficult: we have really to multiply: */
+              {
+                poly mmc = p_ISet(1, R);
+                p_SetExp(mmc, -perm[i], e, R);
+                p_Setm(mmc, R);
+
+                number nnc;
+                // convert back to a number: number nnc = mmc;
+                if( nCoeff_is_algExt(C) )
+                   nnc = (number) mmc;
+                else //            nCoeff_is_transExt(C)
+                  nnc = ntInit(mmc, C);
+
+                p_GetCoeff(qq, dst) = n_Mult((number)c, nnc, C);
+                n_Delete((number *)&c, C);
+                n_Delete((number *)&nnc, C);
+              }
+
+              mapped_to_par=1;
+#endif
+            }
+          }
+          else
+          {
+            /* this variable maps to 0 !*/
+            p_LmDelete(&qq, dst);
+            break;
+          }
+        }
+      }
+      if ( mapped_to_par && qq!= NULL && nCoeff_is_algExt(dst->cf) )
+      {
+        number n = p_GetCoeff(qq, dst);
+        n_Normalize(n, dst->cf);
+        p_GetCoeff(qq, dst) = n;
+      }
+    }
+    pIter(p);
+
+#if 0
+    p_Test(aq,dst);
+    PrintS("\naq: "); p_Write(aq, dst, dst); PrintLn();
+#endif
+
+
+#if 1
+    if (qq!=NULL)
+    {
+      p_Setm(qq,dst);
+
+      p_Test(aq,dst);
+      p_Test(qq,dst);
+
+#if 0
+    p_Test(qq,dst);
+    PrintS("\nqq: "); p_Write(qq, dst, dst); PrintLn();
+#endif
+
+      if (aq!=NULL)
+         qq=p_Mult_q(aq,qq,dst);
+
+      aq = qq;
+
+      while (pNext(aq) != NULL) pIter(aq);
+
+      if (result_last==NULL)
+      {
+        result=qq;
+      }
+      else
+      {
+        pNext(result_last)=qq;
+      }
+      result_last=aq;
+      aq = NULL;
+    }
+    else if (aq!=NULL)
+    {
+      p_Delete(&aq,dst);
+    }
+  }
+
+  result=p_SortAdd(result,dst);
+#else
+  //  if (qq!=NULL)
+  //  {
+  //    pSetm(qq);
+  //    pTest(qq);
+  //    pTest(aq);
+  //    if (aq!=NULL) qq=pMult(aq,qq);
+  //    aq = qq;
+  //    while (pNext(aq) != NULL) pIter(aq);
+  //    pNext(aq) = result;
+  //    aq = NULL;
+  //    result = qq;
+  //  }
+  //  else if (aq!=NULL)
+  //  {
+  //    pDelete(&aq);
+  //  }
+  //}
+  //p = result;
+  //result = NULL;
+  //while (p != NULL)
+  //{
+  //  qq = p;
+  //  pIter(p);
+  //  qq->next = NULL;
+  //  result = pAdd(result, qq);
+  //}
+#endif
+  p_Test(result,dst);
+
+#if 0
+  p_Test(result,dst);
+  PrintS("\nresult: "); p_Write(result,dst,dst); PrintLn();
+#endif
+  return result;
+}
+/**************************************************************
+ *
+ * Jet
+ *
+ **************************************************************/
+
+poly pp_Jet(poly p, int m, const ring R)
+{
+  poly r=NULL;
+  poly t=NULL;
+
+  while (p!=NULL)
+  {
+    if (p_Totaldegree(p,R)<=m)
+    {
+      if (r==NULL)
+        r=p_Head(p,R);
+      else
+      if (t==NULL)
+      {
+        pNext(r)=p_Head(p,R);
+        t=pNext(r);
+      }
+      else
+      {
+        pNext(t)=p_Head(p,R);
+        pIter(t);
+      }
+    }
+    pIter(p);
+  }
+  return r;
+}
+
+poly p_Jet(poly p, int m,const ring R)
+{
+  while((p!=NULL) && (p_Totaldegree(p,R)>m)) p_LmDelete(&p,R);
+  if (p==NULL) return NULL;
+  poly r=p;
+  while (pNext(p)!=NULL)
+  {
+    if (p_Totaldegree(pNext(p),R)>m)
+    {
+      p_LmDelete(&pNext(p),R);
+    }
+    else
+      pIter(p);
+  }
+  return r;
+}
+
+poly pp_JetW(poly p, int m, short *w, const ring R)
+{
+  poly r=NULL;
+  poly t=NULL;
+  while (p!=NULL)
+  {
+    if (totaldegreeWecart_IV(p,R,w)<=m)
+    {
+      if (r==NULL)
+        r=p_Head(p,R);
+      else
+      if (t==NULL)
+      {
+        pNext(r)=p_Head(p,R);
+        t=pNext(r);
+      }
+      else
+      {
+        pNext(t)=p_Head(p,R);
+        pIter(t);
+      }
+    }
+    pIter(p);
+  }
+  return r;
+}
+
+poly p_JetW(poly p, int m, short *w, const ring R)
+{
+  while((p!=NULL) && (totaldegreeWecart_IV(p,R,w)>m)) p_LmDelete(&p,R);
+  if (p==NULL) return NULL;
+  poly r=p;
+  while (pNext(p)!=NULL)
+  {
+    if (totaldegreeWecart_IV(pNext(p),R,w)>m)
+    {
+      p_LmDelete(&pNext(p),R);
+    }
+    else
+      pIter(p);
+  }
+  return r;
+}
+
+/*************************************************************/
+int p_MinDeg(poly p,intvec *w, const ring R)
+{
+  if(p==NULL)
+    return -1;
+  int d=-1;
+  while(p!=NULL)
+  {
+    int d0=0;
+    for(int j=0;j<rVar(R);j++)
+      if(w==NULL||j>=w->length())
+        d0+=p_GetExp(p,j+1,R);
+      else
+        d0+=(*w)[j]*p_GetExp(p,j+1,R);
+    if(d0<d||d==-1)
+      d=d0;
+    pIter(p);
+  }
+  return d;
+}
+
+/***************************************************************/
+
+poly p_Series(int n,poly p,poly u, intvec *w, const ring R)
+{
+  short *ww=iv2array(w,R);
+  if(p!=NULL)
+  {
+    if(u==NULL)
+      p=p_JetW(p,n,ww,R);
+    else
+      p=p_JetW(p_Mult_q(p,p_Invers(n-p_MinDeg(p,w,R),u,w,R),R),n,ww,R);
+  }
+  omFreeSize((ADDRESS)ww,(rVar(R)+1)*sizeof(short));
+  return p;
+}
+
+poly p_Invers(int n,poly u,intvec *w, const ring R)
+{
+  if(n<0)
+    return NULL;
+  number u0=n_Invers(pGetCoeff(u),R->cf);
+  poly v=p_NSet(u0,R);
+  if(n==0)
+    return v;
+  short *ww=iv2array(w,R);
+  poly u1=p_JetW(p_Sub(p_One(R),p_Mult_nn(u,u0,R),R),n,ww,R);
+  if(u1==NULL)
+  {
+    omFreeSize((ADDRESS)ww,(rVar(R)+1)*sizeof(short));
+    return v;
+  }
+  poly v1=p_Mult_nn(p_Copy(u1,R),u0,R);
+  v=p_Add_q(v,p_Copy(v1,R),R);
+  for(int i=n/p_MinDeg(u1,w,R);i>1;i--)
+  {
+    v1=p_JetW(p_Mult_q(v1,p_Copy(u1,R),R),n,ww,R);
+    v=p_Add_q(v,p_Copy(v1,R),R);
+  }
+  p_Delete(&u1,R);
+  p_Delete(&v1,R);
+  omFreeSize((ADDRESS)ww,(rVar(R)+1)*sizeof(short));
+  return v;
+}
+
+BOOLEAN p_EqualPolys(poly p1,poly p2, const ring r)
+{
+  while ((p1 != NULL) && (p2 != NULL))
+  {
+    if (! p_LmEqual(p1, p2,r))
+      return FALSE;
+    if (! n_Equal(p_GetCoeff(p1,r), p_GetCoeff(p2,r),r->cf ))
+      return FALSE;
+    pIter(p1);
+    pIter(p2);
+  }
+  return (p1==p2);
+}
+
+static inline BOOLEAN p_ExpVectorEqual(poly p1, poly p2, const ring r1, const ring r2)
+{
+  assume( r1 == r2 || rSamePolyRep(r1, r2) );
+
+  p_LmCheckPolyRing1(p1, r1);
+  p_LmCheckPolyRing1(p2, r2);
+
+  int i = r1->ExpL_Size;
+
+  assume( r1->ExpL_Size == r2->ExpL_Size );
+
+  unsigned long *ep = p1->exp;
+  unsigned long *eq = p2->exp;
+
+  do
+  {
+    i--;
+    if (ep[i] != eq[i]) return FALSE;
+  }
+  while (i);
+
+  return TRUE;
+}
+
+BOOLEAN p_EqualPolys(poly p1,poly p2, const ring r1, const ring r2)
+{
+  assume( r1 == r2 || rSamePolyRep(r1, r2) ); // will be used in rEqual!
+  assume( r1->cf == r2->cf );
+
+  while ((p1 != NULL) && (p2 != NULL))
+  {
+    // returns 1 if ExpVector(p)==ExpVector(q): does not compare numbers !!
+    // #define p_LmEqual(p1, p2, r) p_ExpVectorEqual(p1, p2, r)
+
+    if (! p_ExpVectorEqual(p1, p2, r1, r2))
+      return FALSE;
+
+    if (! n_Equal(p_GetCoeff(p1,r1), p_GetCoeff(p2,r2), r1->cf ))
+      return FALSE;
+
+    pIter(p1);
+    pIter(p2);
+  }
+  return (p1==p2);
+}
+
+/*2
+*returns TRUE if p1 is a skalar multiple of p2
+*assume p1 != NULL and p2 != NULL
+*/
+BOOLEAN p_ComparePolys(poly p1,poly p2, const ring r)
+{
+  number n,nn;
+  pAssume(p1 != NULL && p2 != NULL);
+
+  if (!p_LmEqual(p1,p2,r)) //compare leading mons
+      return FALSE;
+  if ((pNext(p1)==NULL) && (pNext(p2)!=NULL))
+     return FALSE;
+  if ((pNext(p2)==NULL) && (pNext(p1)!=NULL))
+     return FALSE;
+  if (pLength(p1) != pLength(p2))
+    return FALSE;
+#ifdef HAVE_RINGS
+  if (rField_is_Ring(r))
+  {
+    if (!n_DivBy(p_GetCoeff(p1, r), p_GetCoeff(p2, r), r)) return FALSE;
+  }
+#endif
+  n=n_Div(p_GetCoeff(p1,r),p_GetCoeff(p2,r),r);
+  while ((p1 != NULL) /*&& (p2 != NULL)*/)
+  {
+    if ( ! p_LmEqual(p1, p2,r))
+    {
+        n_Delete(&n, r);
+        return FALSE;
+    }
+    if (!n_Equal(p_GetCoeff(p1, r), nn = n_Mult(p_GetCoeff(p2, r),n, r->cf), r->cf))
+    {
+      n_Delete(&n, r);
+      n_Delete(&nn, r);
+      return FALSE;
+    }
+    n_Delete(&nn, r);
+    pIter(p1);
+    pIter(p2);
+  }
+  n_Delete(&n, r);
+  return TRUE;
+}
+
+/*2
+* returns the length of a (numbers of monomials)
+* respect syzComp
+*/
+poly p_Last(const poly p, int &l, const ring r)
+{
+  if (p == NULL)
+  {
+    l = 0;
+    return NULL;
+  }
+  l = 1;
+  poly a = p;
+  if (! rIsSyzIndexRing(r))
+  {
+    poly next = pNext(a);
+    while (next!=NULL)
+    {
+      a = next;
+      next = pNext(a);
+      l++;
+    }
+  }
+  else
+  {
+    int curr_limit = rGetCurrSyzLimit(r);
+    poly pp = a;
+    while ((a=pNext(a))!=NULL)
+    {
+      if (p_GetComp(a,r)<=curr_limit/*syzComp*/)
+        l++;
+      else break;
+      pp = a;
+    }
+    a=pp;
+  }
+  return a;
+}
+
+int p_Var(poly m,const ring r)
+{
+  if (m==NULL) return 0;
+  if (pNext(m)!=NULL) return 0;
+  int i,e=0;
+  for (i=rVar(r); i>0; i--)
+  {
+    int exp=p_GetExp(m,i,r);
+    if (exp==1)
+    {
+      if (e==0) e=i;
+      else return 0;
+    }
+    else if (exp!=0)
+    {
+      return 0;
+    }
+  }
+  return e;
+}
+
+/*2
+*the minimal index of used variables - 1
+*/
+int p_LowVar (poly p, const ring r)
+{
+  int k,l,lex;
+
+  if (p == NULL) return -1;
+
+  k = 32000;/*a very large dummy value*/
+  while (p != NULL)
+  {
+    l = 1;
+    lex = p_GetExp(p,l,r);
+    while ((l < (rVar(r))) && (lex == 0))
+    {
+      l++;
+      lex = p_GetExp(p,l,r);
+    }
+    l--;
+    if (l < k) k = l;
+    pIter(p);
+  }
+  return k;
+}
+
+/*2
+* verschiebt die Indizees der Modulerzeugenden um i
+*/
+void p_Shift (poly * p,int i, const ring r)
+{
+  poly qp1 = *p,qp2 = *p;/*working pointers*/
+  int     j = p_MaxComp(*p,r),k = p_MinComp(*p,r);
+
+  if (j+i < 0) return ;
+  while (qp1 != NULL)
+  {
+    if ((p_GetComp(qp1,r)+i > 0) || ((j == -i) && (j == k)))
+    {
+      p_AddComp(qp1,i,r);
+      p_SetmComp(qp1,r);
+      qp2 = qp1;
+      pIter(qp1);
+    }
+    else
+    {
+      if (qp2 == *p)
+      {
+        pIter(*p);
+        p_LmDelete(&qp2,r);
+        qp2 = *p;
+        qp1 = *p;
+      }
+      else
+      {
+        qp2->next = qp1->next;
+        if (qp1!=NULL) p_LmDelete(&qp1,r);
+        qp1 = qp2->next;
+      }
+    }
+  }
+}
+
+/***************************************************************
+ *
+ * Storage Managament Routines
+ *
+ ***************************************************************/
+
+
+static inline unsigned long GetBitFields(long e,
+                                         unsigned int s, unsigned int n)
+{
+#define Sy_bit_L(x)     (((unsigned long)1L)<<(x))
+  unsigned int i = 0;
+  unsigned long  ev = 0L;
+  assume(n > 0 && s < BIT_SIZEOF_LONG);
+  do
+  {
+    assume(s+i < BIT_SIZEOF_LONG);
+    if (e > (long) i) ev |= Sy_bit_L(s+i);
+    else break;
+    i++;
+  }
+  while (i < n);
+  return ev;
+}
+
+// Short Exponent Vectors are used for fast divisibility tests
+// ShortExpVectors "squeeze" an exponent vector into one word as follows:
+// Let n = BIT_SIZEOF_LONG / pVariables.
+// If n == 0 (i.e. pVariables > BIT_SIZE_OF_LONG), let m == the number
+// of non-zero exponents. If (m>BIT_SIZEOF_LONG), then sev = ~0, else
+// first m bits of sev are set to 1.
+// Otherwise (i.e. pVariables <= BIT_SIZE_OF_LONG)
+// represented by a bit-field of length n (resp. n+1 for some
+// exponents). If the value of an exponent is greater or equal to n, then
+// all of its respective n bits are set to 1. If the value of an exponent
+// is smaller than n, say m, then only the first m bits of the respective
+// n bits are set to 1, the others are set to 0.
+// This way, we have:
+// exp1 / exp2 ==> (ev1 & ~ev2) == 0, i.e.,
+// if (ev1 & ~ev2) then exp1 does not divide exp2
+unsigned long p_GetShortExpVector(poly p, const ring r)
+{
+  assume(p != NULL);
+  if (p == NULL) return 0;
+  unsigned long ev = 0; // short exponent vector
+  unsigned int n = BIT_SIZEOF_LONG / r->N; // number of bits per exp
+  unsigned int m1; // highest bit which is filled with (n+1)
+  unsigned int i = 0, j=1;
+
+  if (n == 0)
+  {
+    if (r->N <2*BIT_SIZEOF_LONG)
+    {
+      n=1;
+      m1=0;
+    }
+    else
+    {
+      for (; j<=(unsigned long) r->N; j++)
+      {
+        if (p_GetExp(p,j,r) > 0) i++;
+        if (i == BIT_SIZEOF_LONG) break;
+      }
+      if (i>0)
+        ev = ~((unsigned long)0) >> ((unsigned long) (BIT_SIZEOF_LONG - i));
+      return ev;
+    }
+  }
+  else
+  {
+    m1 = (n+1)*(BIT_SIZEOF_LONG - n*r->N);
+  }
+
+  n++;
+  while (i<m1)
+  {
+    ev |= GetBitFields(p_GetExp(p, j,r), i, n);
+    i += n;
+    j++;
+  }
+
+  n--;
+  while (i<BIT_SIZEOF_LONG)
+  {
+    ev |= GetBitFields(p_GetExp(p, j,r), i, n);
+    i += n;
+    j++;
+  }
+  return ev;
+}
+
+
+unsigned long p_GetShortExpVector(const poly p, const poly pp, const ring r)
+{
+  assume(p != NULL);
+  assume(pp != NULL);
+  if (p == NULL || pp == NULL) return 0;
+
+  unsigned long ev = 0; // short exponent vector
+  unsigned int n = BIT_SIZEOF_LONG / r->N; // number of bits per exp
+  unsigned int m1; // highest bit which is filled with (n+1)
+  unsigned int i = 0, j=1;
+
+  if (n == 0)
+  {
+    if (r->N <2*BIT_SIZEOF_LONG)
+    {
+      n=1;
+      m1=0;
+    }
+    else
+    {
+      for (; j<=(unsigned long) r->N; j++)
+      {
+        if (p_GetExp(p,j,r) > 0 || p_GetExp(pp,j,r) > 0) i++;
+        if (i == BIT_SIZEOF_LONG) break;
+      }
+      if (i>0)
+        ev = ~((unsigned long)0) >> ((unsigned long) (BIT_SIZEOF_LONG - i));
+      return ev;
+    }
+  }
+  else
+  {
+    m1 = (n+1)*(BIT_SIZEOF_LONG - n*r->N);
+  }
+
+  n++;
+  while (i<m1)
+  {
+    ev |= GetBitFields(p_GetExp(p, j,r) + p_GetExp(pp, j,r), i, n);
+    i += n;
+    j++;
+  }
+
+  n--;
+  while (i<BIT_SIZEOF_LONG)
+  {
+    ev |= GetBitFields(p_GetExp(p, j,r) + p_GetExp(pp, j,r), i, n);
+    i += n;
+    j++;
+  }
+  return ev;
+}
+
+
+
+/***************************************************************
+ *
+ * p_ShallowDelete
+ *
+ ***************************************************************/
+#undef LINKAGE
+#define LINKAGE
+#undef p_Delete__T
+#define p_Delete__T p_ShallowDelete
+#undef n_Delete__T
+#define n_Delete__T(n, r) do {} while (0)
+
+#include <polys/templates/p_Delete__T.cc>
+
diff --git a/libpolys/polys/monomials/p_polys.h b/libpolys/polys/monomials/p_polys.h
new file mode 100644
index 0000000..153640d
--- /dev/null
+++ b/libpolys/polys/monomials/p_polys.h
@@ -0,0 +1,1930 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    p_polys.h
+ *  Purpose: declaration of poly stuf which are independent of
+ *           currRing
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 9/00
+ *******************************************************************/
+/***************************************************************
+ *  Purpose: implementation of poly procs which iter over ExpVector
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 8/00
+ *******************************************************************/
+#ifndef P_POLYS_H
+#define P_POLYS_H
+
+#include <omalloc/omalloc.h>
+
+#include <misc/mylimits.h>
+#include <misc/intvec.h>
+#include <coeffs/coeffs.h>
+
+#include <polys/monomials/monomials.h>
+#include <polys/monomials/ring.h>
+
+#include <polys/templates/p_MemAdd.h>
+#include <polys/templates/p_MemCmp.h>
+#include <polys/templates/p_Procs.h>
+
+#include <polys/sbuckets.h>
+
+#ifdef HAVE_PLURAL
+#include <polys/nc/nc.h>
+#endif
+
+poly p_Farey(poly p, number N, const ring r);
+/*
+* xx,q: arrays of length 0..rl-1
+* xx[i]: SB mod q[i]
+* assume: char=0
+* assume: q[i]!=0
+* destroys xx
+*/
+poly p_ChineseRemainder(poly *xx, number *x,number *q, int rl, const ring R);
+/***************************************************************
+ *
+ * Divisiblity tests, args must be != NULL, except for
+ * pDivisbleBy
+ *
+ ***************************************************************/
+unsigned long p_GetShortExpVector(poly a, const ring r);
+
+/// p_GetShortExpVector of p * pp
+unsigned long p_GetShortExpVector(const poly p, const poly pp, const ring r);
+
+#ifdef HAVE_RINGS
+/*! divisibility check over ground ring (which may contain zero divisors);
+   TRUE iff LT(f) divides LT(g), i.e., LT(f)*c*m = LT(g), for some
+   coefficient c and some monomial m;
+   does not take components into account
+ */
+BOOLEAN p_DivisibleByRingCase(poly f, poly g, const ring r);
+#endif
+
+/***************************************************************
+ *
+ * Misc things on polys
+ *
+ ***************************************************************/
+
+poly p_One(const ring r);
+
+int p_MinDeg(poly p,intvec *w, const ring R);
+
+long p_DegW(poly p, const short *w, const ring R);
+
+/// return TRUE if all monoms have the same component
+BOOLEAN   p_OneComp(poly p, const ring r);
+
+/// return i, if head depends only on var(i)
+int       p_IsPurePower(const poly p, const ring r);
+
+/// return i, if poly depends only on var(i)
+int       p_IsUnivariate(poly p, const ring r);
+
+/// set entry e[i] to 1 if var(i) occurs in p, ignore var(j) if e[j]>0
+/// return #(e[i]>0)
+int      p_GetVariables(poly p, int * e, const ring r);
+
+/// returns the poly representing the integer i
+poly      p_ISet(long i, const ring r);
+
+/// returns the poly representing the number n, destroys n
+poly      p_NSet(number n, const ring r);
+
+void  p_Vec2Polys(poly v, poly**p, int *len, const ring r);
+
+/***************************************************************
+ *
+ * Copying/Deletion of polys: args may be NULL
+ *
+ ***************************************************************/
+
+// simply deletes monomials, does not free coeffs
+void p_ShallowDelete(poly *p, const ring r);
+
+
+
+/***************************************************************
+ *
+ * Copying/Deleteion of polys: args may be NULL
+ *  - p/q as arg mean a poly
+ *  - m a monomial
+ *  - n a number
+ *  - pp (resp. qq, mm, nn) means arg is constant
+ *  - p (resp, q, m, n)     means arg is destroyed
+ *
+ ***************************************************************/
+
+poly      p_Sub(poly a, poly b, const ring r);
+
+poly      p_Power(poly p, int i, const ring r);
+
+
+/***************************************************************
+ *
+ * PDEBUG stuff
+ *
+ ***************************************************************/
+#ifdef PDEBUG
+// Returns TRUE if m is monom of p, FALSE otherwise
+BOOLEAN pIsMonomOf(poly p, poly m);
+// Returns TRUE if p and q have common monoms
+BOOLEAN pHaveCommonMonoms(poly p, poly q);
+
+// p_Check* routines return TRUE if everything is ok,
+// else, they report error message and return false
+
+// check if Lm(p) is from ring r
+BOOLEAN p_LmCheckIsFromRing(poly p, ring r);
+// check if Lm(p) != NULL, r != NULL and initialized && Lm(p) is from r
+BOOLEAN p_LmCheckPolyRing(poly p, ring r);
+// check if all monoms of p are from ring r
+BOOLEAN p_CheckIsFromRing(poly p, ring r);
+// check r != NULL and initialized && all monoms of p are from r
+BOOLEAN p_CheckPolyRing(poly p, ring r);
+// check if r != NULL and initialized
+BOOLEAN p_CheckRing(ring r);
+// only do check if cond
+
+
+#define pIfThen(cond, check) do {if (cond) {check;}} while (0)
+
+BOOLEAN _p_Test(poly p, ring r, int level);
+BOOLEAN _p_LmTest(poly p, ring r, int level);
+BOOLEAN _pp_Test(poly p, ring lmRing, ring tailRing, int level);
+
+#define p_Test(p,r)     _p_Test(p, r, PDEBUG)
+#define p_LmTest(p,r)   _p_LmTest(p, r, PDEBUG)
+#define pp_Test(p, lmRing, tailRing)    _pp_Test(p, lmRing, tailRing, PDEBUG)
+
+#else // ! PDEBUG
+
+#define pIsMonomOf(p, q)        (TRUE)
+#define pHaveCommonMonoms(p, q) (TRUE)
+#define p_LmCheckIsFromRing(p,r)  do {} while (0)
+#define p_LmCheckPolyRing(p,r)    do {} while (0)
+#define p_CheckIsFromRing(p,r)  do {} while (0)
+#define p_CheckPolyRing(p,r)    do {} while (0)
+#define p_CheckRing(r)          do {} while (0)
+#define P_CheckIf(cond, check)  do {} while (0)
+
+#define p_Test(p,r)     do {} while (0)
+#define p_LmTest(p,r)   do {} while (0)
+#define pp_Test(p, lmRing, tailRing) do {} while (0)
+
+#endif
+
+/***************************************************************
+ *
+ * Misc stuff
+ *
+ ***************************************************************/
+/*2
+* returns the length of a polynomial (numbers of monomials)
+*/
+static inline int pLength(poly a)
+{
+  int l = 0;
+  while (a!=NULL)
+  {
+    pIter(a);
+    l++;
+  }
+  return l;
+}
+
+// returns the length of a polynomial (numbers of monomials) and the last mon.
+// respect syzComp
+poly p_Last(const poly a, int &l, const ring r);
+
+/*----------------------------------------------------*/
+
+void      p_Norm(poly p1, const ring r);
+void      p_Normalize(poly p,const ring r);
+void      p_ProjectiveUnique(poly p,const ring r);
+
+void      p_Content(poly p, const ring r);
+#if 1
+// currently only used by Singular/janet
+void      p_SimpleContent(poly p, int s, const ring r);
+#endif
+
+poly      p_Cleardenom(poly p, const ring r);
+void      p_Cleardenom_n(poly p, const ring r,number &c);
+//number    p_GetAllDenom(poly ph, const ring r);// unused
+
+int       p_Size( poly p, const ring r );
+
+// homogenizes p by multiplying certain powers of the varnum-th variable
+poly      p_Homogen (poly p, int varnum, const ring r);
+
+BOOLEAN   p_IsHomogeneous (poly p, const ring r);
+
+static inline void p_Setm(poly p, const ring r);
+p_SetmProc p_GetSetmProc(ring r);
+
+poly      p_Subst(poly p, int n, poly e, const ring r);
+
+// TODO:
+#define p_SetmComp  p_Setm
+
+// component
+static inline  unsigned long p_SetComp(poly p, unsigned long c, ring r)
+{
+  p_LmCheckPolyRing2(p, r);
+  if (r->pCompIndex>=0) __p_GetComp(p,r) = c;
+  return c;
+}
+// sets component of poly a to i
+static inline   void p_SetCompP(poly p, int i, ring r)
+{
+  if (p != NULL)
+  {
+    p_Test(p, r);
+    if (rOrd_SetCompRequiresSetm(r))
+    {
+      do
+      {
+        p_SetComp(p, i, r);
+        p_SetmComp(p, r);
+        pIter(p);
+      }
+      while (p != NULL);
+    }
+    else
+    {
+      do
+      {
+        p_SetComp(p, i, r);
+        pIter(p);
+      }
+      while(p != NULL);
+    }
+  }
+}
+
+static inline   void p_SetCompP(poly p, int i, ring lmRing, ring tailRing)
+{
+  if (p != NULL)
+  {
+    p_SetComp(p, i, lmRing);
+    p_SetmComp(p, lmRing);
+    p_SetCompP(pNext(p), i, tailRing);
+  }
+}
+
+// returns maximal column number in the modul element a (or 0)
+static inline long p_MaxComp(poly p, ring lmRing, ring tailRing)
+{
+  long result,i;
+
+  if(p==NULL) return 0;
+  result = p_GetComp(p, lmRing);
+  if (result != 0)
+  {
+    loop
+    {
+      pIter(p);
+      if(p==NULL) break;
+      i = p_GetComp(p, tailRing);
+      if (i>result) result = i;
+    }
+  }
+  return result;
+}
+
+static inline long p_MaxComp(poly p,ring lmRing) {return p_MaxComp(p,lmRing,lmRing);}
+
+static inline   long p_MinComp(poly p, ring lmRing, ring tailRing)
+{
+  long result,i;
+
+  if(p==NULL) return 0;
+  result = p_GetComp(p,lmRing);
+  if (result != 0)
+  {
+    loop
+    {
+      pIter(p);
+      if(p==NULL) break;
+      i = p_GetComp(p,tailRing);
+      if (i<result) result = i;
+    }
+  }
+  return result;
+}
+
+static inline long p_MinComp(poly p,ring lmRing) {return p_MinComp(p,lmRing,lmRing);}
+
+
+static inline poly pReverse(poly p)
+{
+  if (p == NULL || pNext(p) == NULL) return p;
+
+  poly q = pNext(p), // == pNext(p)
+    qn;
+  pNext(p) = NULL;
+  do
+  {
+    qn = pNext(q);
+    pNext(q) = p;
+    p = q;
+    q = qn;
+  }
+  while (qn != NULL);
+  return p;
+}
+void      pEnlargeSet(poly**p, int length, int increment);
+
+
+/***************************************************************
+ *
+ * I/O
+ *
+ ***************************************************************/
+/// print p according to ShortOut in lmRing & tailRing
+void      p_String0(poly p, ring lmRing, ring tailRing);
+char*     p_String(poly p, ring lmRing, ring tailRing);
+void      p_Write(poly p, ring lmRing, ring tailRing);
+void      p_Write0(poly p, ring lmRing, ring tailRing);
+void      p_wrp(poly p, ring lmRing, ring tailRing);
+
+/// print p in a short way, if possible
+void  p_String0Short(const poly p, ring lmRing, ring tailRing);
+
+/// print p in a long way
+void   p_String0Long(const poly p, ring lmRing, ring tailRing);
+
+
+/***************************************************************
+ *
+ * Degree stuff -- see p_polys.cc for explainations
+ *
+ ***************************************************************/
+
+static inline long  p_FDeg(const poly p, const ring r)  { return r->pFDeg(p,r); }
+static inline long  p_LDeg(const poly p, int *l, const ring r)  { return r->pLDeg(p,l,r); }
+
+long p_WFirstTotalDegree(poly p, ring r);
+long p_WTotaldegree(poly p, const ring r);
+long p_WDegree(poly p,const ring r);
+long pLDeg0(poly p,int *l, ring r);
+long pLDeg0c(poly p,int *l, ring r);
+long pLDegb(poly p,int *l, ring r);
+long pLDeg1(poly p,int *l, ring r);
+long pLDeg1c(poly p,int *l, ring r);
+long pLDeg1_Deg(poly p,int *l, ring r);
+long pLDeg1c_Deg(poly p,int *l, ring r);
+long pLDeg1_Totaldegree(poly p,int *l, ring r);
+long pLDeg1c_Totaldegree(poly p,int *l, ring r);
+long pLDeg1_WFirstTotalDegree(poly p,int *l, ring r);
+long pLDeg1c_WFirstTotalDegree(poly p,int *l, ring r);
+
+BOOLEAN p_EqualPolys(poly p1, poly p2, const ring r);
+
+/// same as the usual p_EqualPolys for polys belonging to *equal* rings
+BOOLEAN p_EqualPolys(poly p1, poly p2, const ring r1, const ring r2);
+
+long p_Deg(poly a, const ring r);
+
+
+/***************************************************************
+ *
+ * Primitives for accessing and setting fields of a poly
+ *
+ ***************************************************************/
+
+static inline number p_SetCoeff(poly p, number n, ring r)
+{
+  p_LmCheckPolyRing2(p, r);
+  n_Delete(&(p->coef), r->cf);
+  (p)->coef=n;
+  return n;
+}
+
+// order
+static inline long p_GetOrder(poly p, ring r)
+{
+  p_LmCheckPolyRing2(p, r);
+  if (r->typ==NULL) return ((p)->exp[r->pOrdIndex]);
+  int i=0;
+  loop
+  {
+    switch(r->typ[i].ord_typ)
+    {
+      case ro_am:
+      case ro_wp_neg:
+        return ((p->exp[r->pOrdIndex])-POLY_NEGWEIGHT_OFFSET);
+      case ro_syzcomp:
+      case ro_syz:
+      case ro_cp:
+        i++;
+        break;
+      //case ro_dp:
+      //case ro_wp:
+      default:
+        return ((p)->exp[r->pOrdIndex]);
+    }
+  }
+}
+
+// Setm
+static inline void p_Setm(poly p, const ring r)
+{
+  p_CheckRing2(r);
+  r->p_Setm(p, r);
+}
+
+
+static inline unsigned long p_AddComp(poly p, unsigned long v, ring r)
+{
+  p_LmCheckPolyRing2(p, r);
+  pAssume2(rRing_has_Comp(r));
+  return __p_GetComp(p,r) += v;
+}
+static inline unsigned long p_SubComp(poly p, unsigned long v, ring r)
+{
+  p_LmCheckPolyRing2(p, r);
+  pAssume2(rRing_has_Comp(r));
+  _pPolyAssume2(__p_GetComp(p,r) >= v,p,r);
+  return __p_GetComp(p,r) -= v;
+}
+
+#ifndef HAVE_EXPSIZES
+
+/// get a single variable exponent
+/// @Note:
+/// the integer VarOffset encodes:
+/// 1. the position of a variable in the exponent vector p->exp (lower 24 bits)
+/// 2. number of bits to shift to the right in the upper 8 bits (which takes at most 6 bits for 64 bit)
+/// Thus VarOffset always has 2 zero higher bits!
+static inline long p_GetExp(const poly p, const unsigned long iBitmask, const int VarOffset)
+{
+  pAssume2((VarOffset >> (24 + 6)) == 0);
+#if 0
+  int pos=(VarOffset & 0xffffff);
+  int bitpos=(VarOffset >> 24);
+  unsigned long exp=(p->exp[pos] >> bitmask) & iBitmask;
+  return exp;
+#else
+  return (long)
+         ((p->exp[(VarOffset & 0xffffff)] >> (VarOffset >> 24))
+          & iBitmask);
+#endif
+}
+
+
+/// set a single variable exponent
+/// @Note:
+/// VarOffset encodes the position in p->exp @see p_GetExp
+static inline unsigned long p_SetExp(poly p, const unsigned long e, const unsigned long iBitmask, const int VarOffset)
+{
+  pAssume2(e>=0);
+  pAssume2(e<=iBitmask);
+  pAssume2((VarOffset >> (24 + 6)) == 0);
+
+  // shift e to the left:
+  register int shift = VarOffset >> 24;
+  unsigned long ee = e << shift /*(VarOffset >> 24)*/;
+  // find the bits in the exponent vector
+  register int offset = (VarOffset & 0xffffff);
+  // clear the bits in the exponent vector:
+  p->exp[offset]  &= ~( iBitmask << shift );
+  // insert e with |
+  p->exp[ offset ] |= ee;
+  return e;
+}
+
+
+#else // #ifdef HAVE_EXPSIZES // EXPERIMENTAL!!!
+
+static inline unsigned long BitMask(unsigned long bitmask, int twobits)
+{
+  // bitmask = 00000111111111111
+  // 0 must give bitmask!
+  // 1, 2, 3 - anything like 00011..11
+  pAssume2((twobits >> 2) == 0);
+  static const unsigned long _bitmasks[4] = {-1, 0x7fff, 0x7f, 0x3};
+  return bitmask & _bitmasks[twobits];
+}
+
+
+/// @Note: we may add some more info (6 ) into VarOffset and thus encode
+static inline long p_GetExp(const poly p, const unsigned long iBitmask, const int VarOffset)
+{
+  int pos  =(VarOffset & 0xffffff);
+  int hbyte= (VarOffset >> 24); // the highest byte
+  int bitpos = hbyte & 0x3f; // last 6 bits
+  long bitmask = BitMask(iBitmask, hbyte >> 6);
+
+  long exp=(p->exp[pos] >> bitpos) & bitmask;
+  return exp;
+
+}
+
+static inline long p_SetExp(poly p, const long e, const unsigned long iBitmask, const int VarOffset)
+{
+  pAssume2(e>=0);
+  pAssume2(e <= BitMask(iBitmask, VarOffset >> 30));
+
+  // shift e to the left:
+  register int hbyte = VarOffset >> 24;
+  int bitmask = BitMask(iBitmask, hbyte >> 6);
+  register int shift = hbyte & 0x3f;
+  long ee = e << shift;
+  // find the bits in the exponent vector
+  register int offset = (VarOffset & 0xffffff);
+  // clear the bits in the exponent vector:
+  p->exp[offset]  &= ~( bitmask << shift );
+  // insert e with |
+  p->exp[ offset ] |= ee;
+  return e;
+}
+
+#endif // #ifndef HAVE_EXPSIZES
+
+
+static inline long p_GetExp(const poly p, const ring r, const int VarOffset)
+{
+  p_LmCheckPolyRing2(p, r);
+  pAssume2(VarOffset != -1);
+  return p_GetExp(p, r->bitmask, VarOffset);
+}
+
+static inline long p_SetExp(poly p, const long e, const ring r, const int VarOffset)
+{
+  p_LmCheckPolyRing2(p, r);
+  pAssume2(VarOffset != -1);
+  return p_SetExp(p, e, r->bitmask, VarOffset);
+}
+
+
+
+/// get v^th exponent for a monomial
+static inline long p_GetExp(const poly p, const int v, const ring r)
+{
+  p_LmCheckPolyRing2(p, r);
+  pAssume2(v>0 && v <= r->N);
+  pAssume2(r->VarOffset[v] != -1);
+  return p_GetExp(p, r->bitmask, r->VarOffset[v]);
+}
+
+
+/// set v^th exponent for a monomial
+static inline long p_SetExp(poly p, const int v, const long e, const ring r)
+{
+  p_LmCheckPolyRing2(p, r);
+  pAssume2(v>0 && v <= r->N);
+  pAssume2(r->VarOffset[v] != -1);
+  return p_SetExp(p, e, r->bitmask, r->VarOffset[v]);
+}
+
+// the following should be implemented more efficiently
+static inline  long p_IncrExp(poly p, int v, ring r)
+{
+  p_LmCheckPolyRing2(p, r);
+  int e = p_GetExp(p,v,r);
+  e++;
+  return p_SetExp(p,v,e,r);
+}
+static inline  long p_DecrExp(poly p, int v, ring r)
+{
+  p_LmCheckPolyRing2(p, r);
+  int e = p_GetExp(p,v,r);
+  pAssume2(e > 0);
+  e--;
+  return p_SetExp(p,v,e,r);
+}
+static inline  long p_AddExp(poly p, int v, long ee, ring r)
+{
+  p_LmCheckPolyRing2(p, r);
+  int e = p_GetExp(p,v,r);
+  e += ee;
+  return p_SetExp(p,v,e,r);
+}
+static inline  long p_SubExp(poly p, int v, long ee, ring r)
+{
+  p_LmCheckPolyRing2(p, r);
+  long e = p_GetExp(p,v,r);
+  pAssume2(e >= ee);
+  e -= ee;
+  return p_SetExp(p,v,e,r);
+}
+static inline  long p_MultExp(poly p, int v, long ee, ring r)
+{
+  p_LmCheckPolyRing2(p, r);
+  long e = p_GetExp(p,v,r);
+  e *= ee;
+  return p_SetExp(p,v,e,r);
+}
+
+static inline long p_GetExpSum(poly p1, poly p2, int i, ring r)
+{
+  p_LmCheckPolyRing2(p1, r);
+  p_LmCheckPolyRing2(p2, r);
+  return p_GetExp(p1,i,r) + p_GetExp(p2,i,r);
+}
+static inline long p_GetExpDiff(poly p1, poly p2, int i, ring r)
+{
+  return p_GetExp(p1,i,r) - p_GetExp(p2,i,r);
+}
+
+static inline int p_Comp_k_n(poly a, poly b, int k, ring r)
+{
+  if ((a==NULL) || (b==NULL) ) return FALSE;
+  p_LmCheckPolyRing2(a, r);
+  p_LmCheckPolyRing2(b, r);
+  pAssume2(k > 0 && k <= r->N);
+  int i=k;
+  for(;i<=r->N;i++)
+  {
+    if (p_GetExp(a,i,r) != p_GetExp(b,i,r)) return FALSE;
+    //    if (a->exp[(r->VarOffset[i] & 0xffffff)] != b->exp[(r->VarOffset[i] & 0xffffff)]) return FALSE;
+  }
+  return TRUE;
+}
+
+
+/***************************************************************
+ *
+ * Allocation/Initalization/Deletion
+ *
+ ***************************************************************/
+#if (OM_TRACK > 2) && defined(OM_TRACK_CUSTOM)
+static inline poly p_New(const ring r, omBin bin)
+#else
+static inline poly p_New(const ring /*r*/, omBin bin)
+#endif
+{
+  p_CheckRing2(r);
+  pAssume2(bin != NULL && omSizeWOfBin(r->PolyBin) == omSizeWOfBin(bin));
+  poly p;
+  omTypeAllocBin(poly, p, bin);
+  p_SetRingOfLm(p, r);
+  return p;
+}
+
+static inline poly p_New(ring r)
+{
+  return p_New(r, r->PolyBin);
+}
+
+#if PDEBUG > 2
+static inline void p_LmFree(poly p, ring r)
+#else
+static inline void p_LmFree(poly p, ring)
+#endif
+{
+  p_LmCheckPolyRing2(p, r);
+  omFreeBinAddr(p);
+}
+#if PDEBUG > 2
+static inline void p_LmFree(poly *p, ring r)
+#else
+static inline void p_LmFree(poly *p, ring)
+#endif
+{
+  p_LmCheckPolyRing2(*p, r);
+  poly h = *p;
+  *p = pNext(h);
+  omFreeBinAddr(h);
+}
+#if PDEBUG > 2
+static inline poly p_LmFreeAndNext(poly p, ring r)
+#else
+static inline poly p_LmFreeAndNext(poly p, ring)
+#endif
+{
+  p_LmCheckPolyRing2(p, r);
+  poly pnext = pNext(p);
+  omFreeBinAddr(p);
+  return pnext;
+}
+static inline void p_LmDelete(poly p, const ring r)
+{
+  p_LmCheckPolyRing2(p, r);
+  n_Delete(&pGetCoeff(p), r->cf);
+  omFreeBinAddr(p);
+}
+static inline void p_LmDelete(poly *p, const ring r)
+{
+  p_LmCheckPolyRing2(*p, r);
+  poly h = *p;
+  *p = pNext(h);
+  n_Delete(&pGetCoeff(h), r->cf);
+  omFreeBinAddr(h);
+}
+static inline poly p_LmDeleteAndNext(poly p, const ring r)
+{
+  p_LmCheckPolyRing2(p, r);
+  poly pnext = pNext(p);
+  n_Delete(&pGetCoeff(p), r->cf);
+  omFreeBinAddr(p);
+  return pnext;
+}
+
+/***************************************************************
+ *
+ * Misc routines
+ *
+ ***************************************************************/
+
+/// return the maximal exponent of p in form of the maximal long var
+unsigned long p_GetMaxExpL(poly p, const ring r, unsigned long l_max = 0);
+
+/// return monomial r such that GetExp(r,i) is maximum of all
+/// monomials in p; coeff == 0, next == NULL, ord is not set
+poly p_GetMaxExpP(poly p, ring r);
+
+static inline unsigned long p_GetMaxExp(const unsigned long l, const ring r)
+{
+  unsigned long bitmask = r->bitmask;
+  unsigned long max = (l & bitmask);
+  unsigned long j = r->ExpPerLong - 1;
+
+  if (j > 0)
+  {
+    unsigned long i = r->BitsPerExp;
+    long e;
+    loop
+    {
+      e = ((l >> i) & bitmask);
+      if ((unsigned long) e > max)
+        max = e;
+      j--;
+      if (j==0) break;
+      i += r->BitsPerExp;
+    }
+  }
+  return max;
+}
+
+static inline unsigned long p_GetMaxExp(const poly p, const ring r)
+{
+  return p_GetMaxExp(p_GetMaxExpL(p, r), r);
+}
+
+static inline unsigned long
+p_GetTotalDegree(const unsigned long l, const ring r, const int number_of_exps)
+{
+  const unsigned long bitmask = r->bitmask;
+  unsigned long sum = (l & bitmask);
+  unsigned long j = number_of_exps - 1;
+
+  if (j > 0)
+  {
+    unsigned long i = r->BitsPerExp;
+    loop
+    {
+      sum += ((l >> i) & bitmask);
+      j--;
+      if (j==0) break;
+      i += r->BitsPerExp;
+    }
+  }
+  return sum;
+}
+
+static inline unsigned long
+p_GetTotalDegree(const unsigned long l, const ring r)
+{
+  return p_GetTotalDegree(l, r, r->ExpPerLong);
+}
+
+/***************************************************************
+ *
+ * Dispatcher to r->p_Procs, they do the tests/checks
+ *
+ ***************************************************************/
+/// returns a copy of p (without any additional testing)
+static inline poly p_Copy_noCheck(poly p, const ring r)
+{
+  assume(r != NULL); assume(r->p_Procs != NULL); assume(r->p_Procs->p_Copy != NULL);
+  return r->p_Procs->p_Copy(p, r);
+}
+
+/// returns a copy of p
+static inline poly p_Copy(poly p, const ring r)
+{
+  p_Test(p,r);
+  const poly pp = p_Copy_noCheck(p, r);
+  p_Test(pp,r);
+  return pp;
+}
+
+static inline poly p_Head(poly p, const ring r)
+{
+  if (p == NULL) return NULL;
+  p_LmCheckPolyRing1(p, r);
+  poly np;
+  omTypeAllocBin(poly, np, r->PolyBin);
+  p_SetRingOfLm(np, r);
+  memcpy(np->exp, p->exp, r->ExpL_Size*sizeof(long));
+  pNext(np) = NULL;
+  pSetCoeff0(np, n_Copy(pGetCoeff(p), r->cf));
+  return np;
+}
+
+// returns a copy of p with Lm(p) from lmRing and Tail(p) from tailRing
+static inline poly p_Copy(poly p, const ring lmRing, const ring tailRing)
+{
+  if (p != NULL)
+  {
+#ifndef PDEBUG
+    if (tailRing == lmRing)
+      return p_Copy_noCheck(p, tailRing);
+#endif
+    poly pres = p_Head(p, lmRing);
+    pNext(pres) = p_Copy_noCheck(pNext(p), tailRing);
+    return pres;
+  }
+  else
+    return NULL;
+}
+
+// deletes *p, and sets *p to NULL
+static inline void p_Delete(poly *p, const ring r)
+{
+  assume( p!= NULL );
+  r->p_Procs->p_Delete(p, r);
+}
+
+static inline void p_Delete(poly *p,  const ring lmRing, const ring tailRing)
+{
+  assume( p!= NULL );
+  if (*p != NULL)
+  {
+#ifndef PDEBUG
+    if (tailRing == lmRing)
+    {
+      p_Delete(p, tailRing);
+      return;
+    }
+#endif
+    if (pNext(*p) != NULL)
+      p_Delete(&pNext(*p), tailRing);
+    p_LmDelete(p, lmRing);
+  }
+}
+
+// copys monomials of p, allocates new monomials from bin,
+// deletes monomoals of p
+static inline poly p_ShallowCopyDelete(poly p, const ring r, omBin bin)
+{
+  p_LmCheckPolyRing2(p, r);
+  pAssume2(omSizeWOfBin(r->PolyBin) == omSizeWOfBin(bin));
+  return r->p_Procs->p_ShallowCopyDelete(p, r, bin);
+}
+
+// returns p+q, destroys p and q
+static inline poly p_Add_q(poly p, poly q, const ring r)
+{
+  assume( (p != q) || (p == NULL && q == NULL) );
+  int shorter;
+  return r->p_Procs->p_Add_q(p, q, shorter, r);
+}
+
+/// like p_Add_q, except that if lp == pLength(lp) lq == pLength(lq) then lp == pLength(p+q)
+static inline poly p_Add_q(poly p, poly q, int &lp, int lq, const ring r)
+{
+  assume( (p != q) || (p == NULL && q == NULL) );
+  int shorter;
+  poly res = r->p_Procs->p_Add_q(p, q, shorter, r);
+  lp = (lp + lq) - shorter;
+  return res;
+}
+
+// returns p*n, destroys p
+static inline poly p_Mult_nn(poly p, number n, const ring r)
+{
+  if (n_IsOne(n, r->cf))
+    return p;
+  else if (n_IsZero(n, r->cf))
+    return NULL;
+  else
+    return r->p_Procs->p_Mult_nn(p, n, r);
+}
+
+static inline poly p_Mult_nn(poly p, number n, const ring lmRing,
+                        const ring tailRing)
+{
+#ifndef PDEBUG
+  if (lmRing == tailRing)
+    return p_Mult_nn(p, n, tailRing);
+#endif
+  poly pnext = pNext(p);
+  pNext(p) = NULL;
+  p = lmRing->p_Procs->p_Mult_nn(p, n, lmRing);
+  pNext(p) = tailRing->p_Procs->p_Mult_nn(pnext, n, tailRing);
+  return p;
+}
+
+// returns p*n, does not destroy p
+static inline poly pp_Mult_nn(poly p, number n, const ring r)
+{
+  if (n_IsOne(n, r->cf))
+    return p_Copy(p, r);
+  else
+    return r->p_Procs->pp_Mult_nn(p, n, r);
+}
+
+// test if the monomial is a constant as a vector component
+// i.e., test if all exponents are zero
+static inline BOOLEAN p_LmIsConstantComp(const poly p, const ring r)
+{
+  //p_LmCheckPolyRing(p, r);
+  int i = r->VarL_Size - 1;
+
+  do
+  {
+    if (p->exp[r->VarL_Offset[i]] != 0)
+      return FALSE;
+    i--;
+  }
+  while (i >= 0);
+  return TRUE;
+}
+
+// test if monomial is a constant, i.e. if all exponents and the component
+// is zero
+static inline BOOLEAN p_LmIsConstant(const poly p, const ring r)
+{
+  if (p_LmIsConstantComp(p, r))
+    return (p_GetComp(p, r) == 0);
+  return FALSE;
+}
+
+// returns Copy(p)*m, does neither destroy p nor m
+static inline poly pp_Mult_mm(poly p, poly m, const ring r)
+{
+  if (p_LmIsConstant(m, r))
+    return pp_Mult_nn(p, pGetCoeff(m), r);
+  else
+  {
+    return r->p_Procs->pp_Mult_mm(p, m, r);
+  }
+}
+
+// returns p*m, destroys p, const: m
+static inline poly p_Mult_mm(poly p, poly m, const ring r)
+{
+  if (p_LmIsConstant(m, r))
+    return p_Mult_nn(p, pGetCoeff(m), r);
+  else
+    return r->p_Procs->p_Mult_mm(p, m, r);
+}
+
+static inline poly p_Minus_mm_Mult_qq(poly p, const poly m, const poly q, int &lp, int lq,
+                                      const poly spNoether, const ring r)
+{
+  int shorter;
+  const poly res = r->p_Procs->p_Minus_mm_Mult_qq(p, m, q, shorter, spNoether, r);
+  lp += lq - shorter;
+//  assume( lp == pLength(res) );
+  return res;
+}
+
+// return p - m*Copy(q), destroys p; const: p,m
+static inline poly p_Minus_mm_Mult_qq(poly p, const poly m, const poly q, const ring r)
+{
+  int shorter;
+
+  return r->p_Procs->p_Minus_mm_Mult_qq(p, m, q, shorter, NULL, r);
+}
+
+
+// returns p*Coeff(m) for such monomials pm of p, for which m is divisble by pm
+static inline poly pp_Mult_Coeff_mm_DivSelect(poly p, const poly m, const ring r)
+{
+  int shorter;
+  return r->p_Procs->pp_Mult_Coeff_mm_DivSelect(p, m, shorter, r);
+}
+
+// returns p*Coeff(m) for such monomials pm of p, for which m is divisble by pm
+// if lp is length of p on input then lp is length of returned poly on output
+static inline poly pp_Mult_Coeff_mm_DivSelect(poly p, int &lp, const poly m, const ring r)
+{
+  int shorter;
+  poly pp = r->p_Procs->pp_Mult_Coeff_mm_DivSelect(p, m, shorter, r);
+  lp -= shorter;
+  return pp;
+}
+
+// returns -p, destroys p
+static inline poly p_Neg(poly p, const ring r)
+{
+  return r->p_Procs->p_Neg(p, r);
+}
+
+extern poly  _p_Mult_q(poly p, poly q, const int copy, const ring r);
+// returns p*q, destroys p and q
+static inline poly p_Mult_q(poly p, poly q, const ring r)
+{
+  assume( (p != q) || (p == NULL && q == NULL) );
+
+  if (p == NULL)
+  {
+    r->p_Procs->p_Delete(&q, r);
+    return NULL;
+  }
+  if (q == NULL)
+  {
+    r->p_Procs->p_Delete(&p, r);
+    return NULL;
+  }
+
+  if (pNext(p) == NULL)
+  {
+#ifdef HAVE_PLURAL
+    if (rIsPluralRing(r))
+      q = nc_mm_Mult_p(p, q, r);
+    else
+#endif /* HAVE_PLURAL */
+      q = r->p_Procs->p_Mult_mm(q, p, r);
+
+    r->p_Procs->p_Delete(&p, r);
+    return q;
+  }
+
+  if (pNext(q) == NULL)
+  {
+  // NEEDED
+#ifdef HAVE_PLURAL
+/*    if (rIsPluralRing(r))
+      p = gnc_p_Mult_mm(p, q, r); // ???
+    else*/
+#endif /* HAVE_PLURAL */
+      p = r->p_Procs->p_Mult_mm(p, q, r);
+
+    r->p_Procs->p_Delete(&q, r);
+    return p;
+  }
+#ifdef HAVE_PLURAL
+  if (rIsPluralRing(r))
+    return _nc_p_Mult_q(p, q, r);
+  else
+#endif
+  return _p_Mult_q(p, q, 0, r);
+}
+
+// returns p*q, does neither destroy p nor q
+static inline poly pp_Mult_qq(poly p, poly q, const ring r)
+{
+  if (p == NULL || q == NULL) return NULL;
+
+  if (pNext(p) == NULL)
+  {
+#ifdef HAVE_PLURAL
+    if (rIsPluralRing(r))
+      return nc_mm_Mult_pp(p, q, r);
+#endif
+    return r->p_Procs->pp_Mult_mm(q, p, r);
+  }
+
+  if (pNext(q) == NULL)
+  {
+    return r->p_Procs->pp_Mult_mm(p, q, r);
+  }
+
+  poly qq = q;
+  if (p == q)
+    qq = p_Copy(q, r);
+
+  poly res;
+#ifdef HAVE_PLURAL
+  if (rIsPluralRing(r))
+    res = _nc_pp_Mult_qq(p, qq, r);
+  else
+#endif
+    res = _p_Mult_q(p, qq, 1, r);
+
+  if (qq != q)
+    p_Delete(&qq, r);
+  return res;
+}
+
+// returns p + m*q destroys p, const: q, m
+static inline poly p_Plus_mm_Mult_qq(poly p, poly m, poly q, int &lp, int lq,
+                                const ring r)
+{
+#ifdef HAVE_PLURAL
+  if (rIsPluralRing(r))
+    return nc_p_Plus_mm_Mult_qq(p, m, q, lp, lq, r);
+#endif
+
+// this should be implemented more efficiently
+  poly res;
+  int shorter;
+  number n_old = pGetCoeff(m);
+  number n_neg = n_Copy(n_old, r->cf);
+  n_neg = n_InpNeg(n_neg, r->cf);
+  pSetCoeff0(m, n_neg);
+  res = r->p_Procs->p_Minus_mm_Mult_qq(p, m, q, shorter, NULL, r);
+  lp = (lp + lq) - shorter;
+  pSetCoeff0(m, n_old);
+  n_Delete(&n_neg, r->cf);
+  return res;
+}
+
+static inline poly p_Plus_mm_Mult_qq(poly p, poly m, poly q, const ring r)
+{
+  int lp = 0, lq = 0;
+  return p_Plus_mm_Mult_qq(p, m, q, lp, lq, r);
+}
+
+// returns merged p and q, assumes p and q have no monomials which are equal
+static inline poly p_Merge_q(poly p, poly q, const ring r)
+{
+  assume( (p != q) || (p == NULL && q == NULL) );
+  return r->p_Procs->p_Merge_q(p, q, r);
+}
+
+// like p_SortMerge, except that p may have equal monimals
+static inline poly p_SortAdd(poly p, const ring r, BOOLEAN revert= FALSE)
+{
+  if (revert) p = pReverse(p);
+  return sBucketSortAdd(p, r);
+}
+
+// sorts p using bucket sort: returns sorted poly
+// assumes that monomials of p are all different
+// reverses it first, if revert == TRUE, use this if input p is "almost" sorted
+// correctly
+static inline poly p_SortMerge(poly p, const ring r, BOOLEAN revert= FALSE)
+{
+  if (revert) p = pReverse(p);
+  return sBucketSortMerge(p, r);
+}
+
+/***************************************************************
+ *
+ * I/O
+ *
+ ***************************************************************/
+static inline char*     p_String(poly p, ring p_ring)
+{
+  return p_String(p, p_ring, p_ring);
+}
+static inline void     p_String0(poly p, ring p_ring)
+{
+  p_String0(p, p_ring, p_ring);
+}
+static inline void      p_Write(poly p, ring p_ring)
+{
+  p_Write(p, p_ring, p_ring);
+}
+static inline void      p_Write0(poly p, ring p_ring)
+{
+  p_Write0(p, p_ring, p_ring);
+}
+static inline void      p_wrp(poly p, ring p_ring)
+{
+  p_wrp(p, p_ring, p_ring);
+}
+
+
+#if PDEBUG > 0
+
+#define _p_LmCmpAction(p, q, r, actionE, actionG, actionS)  \
+do                                                          \
+{                                                           \
+  int _cmp = p_LmCmp(p,q,r);                                \
+  if (_cmp == 0) actionE;                                   \
+  if (_cmp == 1) actionG;                                   \
+  actionS;                                                  \
+}                                                           \
+while(0)
+
+#else
+
+#define _p_LmCmpAction(p, q, r, actionE, actionG, actionS)                      \
+ p_MemCmp_LengthGeneral_OrdGeneral(p->exp, q->exp, r->CmpL_Size, r->ordsgn,    \
+                                   actionE, actionG, actionS)
+
+#endif
+
+#define pDivAssume(x)   do {} while (0)
+
+
+
+/***************************************************************
+ *
+ * Allocation/Initalization/Deletion
+ *
+ ***************************************************************/
+// adjustments for negative weights
+static inline void p_MemAdd_NegWeightAdjust(poly p, const ring r)
+{
+  if (r->NegWeightL_Offset != NULL)
+  {
+    for (int i=r->NegWeightL_Size-1; i>=0; i--)
+    {
+      p->exp[r->NegWeightL_Offset[i]] -= POLY_NEGWEIGHT_OFFSET;
+    }
+  }
+}
+static inline void p_MemSub_NegWeightAdjust(poly p, const ring r)
+{
+  if (r->NegWeightL_Offset != NULL)
+  {
+    for (int i=r->NegWeightL_Size-1; i>=0; i--)
+    {
+      p->exp[r->NegWeightL_Offset[i]] += POLY_NEGWEIGHT_OFFSET;
+    }
+  }
+}
+// ExpVextor(d_p) = ExpVector(s_p)
+static inline void p_ExpVectorCopy(poly d_p, poly s_p, const ring r)
+{
+  p_LmCheckPolyRing1(d_p, r);
+  p_LmCheckPolyRing1(s_p, r);
+  memcpy(d_p->exp, s_p->exp, r->ExpL_Size*sizeof(long));
+}
+
+static inline poly p_Init(const ring r, omBin bin)
+{
+  p_CheckRing1(r);
+  pAssume1(bin != NULL && omSizeWOfBin(r->PolyBin) == omSizeWOfBin(bin));
+  poly p;
+  omTypeAlloc0Bin(poly, p, bin);
+  p_MemAdd_NegWeightAdjust(p, r);
+  p_SetRingOfLm(p, r);
+  return p;
+}
+static inline poly p_Init(const ring r)
+{
+  return p_Init(r, r->PolyBin);
+}
+
+static inline poly p_LmInit(poly p, const ring r)
+{
+  p_LmCheckPolyRing1(p, r);
+  poly np;
+  omTypeAllocBin(poly, np, r->PolyBin);
+  p_SetRingOfLm(np, r);
+  memcpy(np->exp, p->exp, r->ExpL_Size*sizeof(long));
+  pNext(np) = NULL;
+  pSetCoeff0(np, NULL);
+  return np;
+}
+static inline poly p_LmInit(poly s_p, const ring s_r, const ring d_r, omBin d_bin)
+{
+  p_LmCheckPolyRing1(s_p, s_r);
+  p_CheckRing(d_r);
+  pAssume1(d_r->N <= s_r->N);
+  poly d_p = p_Init(d_r, d_bin);
+  for (int i=d_r->N; i>0; i--)
+  {
+    p_SetExp(d_p, i, p_GetExp(s_p, i,s_r), d_r);
+  }
+  if (rRing_has_Comp(d_r))
+  {
+    p_SetComp(d_p, p_GetComp(s_p,s_r), d_r);
+  }
+  p_Setm(d_p, d_r);
+  return d_p;
+}
+static inline poly p_LmInit(poly s_p, const ring s_r, const ring d_r)
+{
+  pAssume1(d_r != NULL);
+  return p_LmInit(s_p, s_r, d_r, d_r->PolyBin);
+}
+
+// set all exponents l..k to 0, assume exp. k+1..n and 1..l-1 are in
+// different blocks
+// set coeff to 1
+static inline poly p_GetExp_k_n(poly p, int l, int k, const ring r)
+{
+  if (p == NULL) return NULL;
+  p_LmCheckPolyRing1(p, r);
+  poly np;
+  omTypeAllocBin(poly, np, r->PolyBin);
+  p_SetRingOfLm(np, r);
+  memcpy(np->exp, p->exp, r->ExpL_Size*sizeof(long));
+  pNext(np) = NULL;
+  pSetCoeff0(np, n_Init(1, r->cf));
+  int i;
+  for(i=l;i<=k;i++)
+  {
+    //np->exp[(r->VarOffset[i] & 0xffffff)] =0;
+    p_SetExp(np,i,0,r);
+  }
+  p_Setm(np,r);
+  return np;
+}
+
+// simialar to p_ShallowCopyDelete but does it only for leading monomial
+static inline poly p_LmShallowCopyDelete(poly p, const ring r)
+{
+  p_LmCheckPolyRing1(p, r);
+  pAssume1(omSizeWOfBin(bin) == omSizeWOfBin(r->PolyBin));
+  poly new_p = p_New(r);
+  memcpy(new_p->exp, p->exp, r->ExpL_Size*sizeof(long));
+  pSetCoeff0(new_p, pGetCoeff(p));
+  pNext(new_p) = pNext(p);
+  omFreeBinAddr(p);
+  return new_p;
+}
+
+/***************************************************************
+ *
+ * Operation on ExpVectors
+ *
+ ***************************************************************/
+// ExpVector(p1) += ExpVector(p2)
+static inline void p_ExpVectorAdd(poly p1, poly p2, const ring r)
+{
+  p_LmCheckPolyRing1(p1, r);
+  p_LmCheckPolyRing1(p2, r);
+#if PDEBUG >= 1
+  for (int i=1; i<=r->N; i++)
+    pAssume1((unsigned long) (p_GetExp(p1, i, r) + p_GetExp(p2, i, r)) <= r->bitmask);
+  pAssume1(p_GetComp(p1, r) == 0 || p_GetComp(p2, r) == 0);
+#endif
+
+  p_MemAdd_LengthGeneral(p1->exp, p2->exp, r->ExpL_Size);
+  p_MemAdd_NegWeightAdjust(p1, r);
+}
+// ExpVector(pr) = ExpVector(p1) + ExpVector(p2)
+static inline void p_ExpVectorSum(poly pr, poly p1, poly p2, const ring r)
+{
+  p_LmCheckPolyRing1(p1, r);
+  p_LmCheckPolyRing1(p2, r);
+  p_LmCheckPolyRing1(pr, r);
+#if PDEBUG >= 1
+  for (int i=1; i<=r->N; i++)
+    pAssume1((unsigned long) (p_GetExp(p1, i, r) + p_GetExp(p2, i, r)) <= r->bitmask);
+  pAssume1(p_GetComp(p1, r) == 0 || p_GetComp(p2, r) == 0);
+#endif
+
+  p_MemSum_LengthGeneral(pr->exp, p1->exp, p2->exp, r->ExpL_Size);
+  p_MemAdd_NegWeightAdjust(pr, r);
+}
+// ExpVector(p1) -= ExpVector(p2)
+static inline void p_ExpVectorSub(poly p1, poly p2, const ring r)
+{
+  p_LmCheckPolyRing1(p1, r);
+  p_LmCheckPolyRing1(p2, r);
+#if PDEBUG >= 1
+  for (int i=1; i<=r->N; i++)
+    pAssume1(p_GetExp(p1, i, r) >= p_GetExp(p2, i, r));
+  pAssume1(p_GetComp(p1, r) == 0 || p_GetComp(p2, r) == 0 ||
+          p_GetComp(p1, r) == p_GetComp(p2, r));
+#endif
+
+  p_MemSub_LengthGeneral(p1->exp, p2->exp, r->ExpL_Size);
+  p_MemSub_NegWeightAdjust(p1, r);
+
+}
+// ExpVector(p1) += ExpVector(p2) - ExpVector(p3)
+static inline void p_ExpVectorAddSub(poly p1, poly p2, poly p3, const ring r)
+{
+  p_LmCheckPolyRing1(p1, r);
+  p_LmCheckPolyRing1(p2, r);
+  p_LmCheckPolyRing1(p3, r);
+#if PDEBUG >= 1
+  for (int i=1; i<=r->N; i++)
+    pAssume1(p_GetExp(p1, i, r) + p_GetExp(p2, i, r) >= p_GetExp(p3, i, r));
+  pAssume1(p_GetComp(p1, r) == 0 ||
+           (p_GetComp(p2, r) - p_GetComp(p3, r) == 0) ||
+           (p_GetComp(p1, r) == p_GetComp(p2, r) - p_GetComp(p3, r)));
+#endif
+
+  p_MemAddSub_LengthGeneral(p1->exp, p2->exp, p3->exp, r->ExpL_Size);
+  // no need to adjust in case of NegWeights
+}
+
+// ExpVector(pr) = ExpVector(p1) - ExpVector(p2)
+static inline void p_ExpVectorDiff(poly pr, poly p1, poly p2, const ring r)
+{
+  p_LmCheckPolyRing1(p1, r);
+  p_LmCheckPolyRing1(p2, r);
+  p_LmCheckPolyRing1(pr, r);
+#if PDEBUG >= 2
+  for (int i=1; i<=r->N; i++)
+    pAssume1(p_GetExp(p1, i, r) >= p_GetExp(p2, i, r));
+  pAssume1(!rRing_has_Comp(r) || p_GetComp(p1, r) == p_GetComp(p2, r));
+#endif
+
+  p_MemDiff_LengthGeneral(pr->exp, p1->exp, p2->exp, r->ExpL_Size);
+  p_MemSub_NegWeightAdjust(pr, r);
+}
+
+static inline BOOLEAN p_ExpVectorEqual(poly p1, poly p2, const ring r)
+{
+  p_LmCheckPolyRing1(p1, r);
+  p_LmCheckPolyRing1(p2, r);
+
+  int i = r->ExpL_Size;
+  unsigned long *ep = p1->exp;
+  unsigned long *eq = p2->exp;
+
+  do
+  {
+    i--;
+    if (ep[i] != eq[i]) return FALSE;
+  }
+  while (i);
+  return TRUE;
+}
+
+static inline long p_Totaldegree(poly p, const ring r)
+{
+  p_LmCheckPolyRing1(p, r);
+  unsigned long s = p_GetTotalDegree(p->exp[r->VarL_Offset[0]],
+                                     r,
+                                     r->MinExpPerLong);
+  for (int i=r->VarL_Size-1; i>0; i--)
+  {
+    s += p_GetTotalDegree(p->exp[r->VarL_Offset[i]], r);
+  }
+  return (long)s;
+}
+
+static inline void p_GetExpV(poly p, int *ev, const ring r)
+{
+  p_LmCheckPolyRing1(p, r);
+  for (int j = r->N; j; j--)
+      ev[j] = p_GetExp(p, j, r);
+
+  ev[0] = p_GetComp(p, r);
+}
+static inline void p_SetExpV(poly p, int *ev, const ring r)
+{
+  p_LmCheckPolyRing1(p, r);
+  for (int j = r->N; j; j--)
+      p_SetExp(p, j, ev[j], r);
+
+  p_SetComp(p, ev[0],r);
+  p_Setm(p, r);
+}
+
+/***************************************************************
+ *
+ * Comparison w.r.t. monomial ordering
+ *
+ ***************************************************************/
+
+static inline int p_LmCmp(poly p, poly q, const ring r)
+{
+  p_LmCheckPolyRing1(p, r);
+  p_LmCheckPolyRing1(q, r);
+
+  const unsigned long* _s1 = ((unsigned long*) p->exp);
+  const unsigned long* _s2 = ((unsigned long*) q->exp);
+  register unsigned long _v1;
+  register unsigned long _v2;
+  const unsigned long _l = r->CmpL_Size;
+
+  register unsigned long _i=0;
+
+  LengthGeneral_OrdGeneral_LoopTop:
+  _v1 = _s1[_i];
+  _v2 = _s2[_i];
+  if (_v1 == _v2)
+  {
+    _i++;
+    if (_i == _l) return 0;
+    goto LengthGeneral_OrdGeneral_LoopTop;
+  }
+  const long* _ordsgn = (long*) r->ordsgn;
+  if (_v1 > _v2)
+  {
+    if (_ordsgn[_i] == 1) return 1;
+    return -1;
+  }
+  if (_ordsgn[_i] == 1) return -1;
+  return 1;
+
+}
+
+/// returns TRUE if p1 is a skalar multiple of p2
+/// assume p1 != NULL and p2 != NULL
+BOOLEAN p_ComparePolys(poly p1,poly p2, const ring r);
+
+
+/***************************************************************
+ *
+ * Comparisons: they are all done without regarding coeffs
+ *
+ ***************************************************************/
+#define p_LmCmpAction(p, q, r, actionE, actionG, actionS) \
+  _p_LmCmpAction(p, q, r, actionE, actionG, actionS)
+
+// returns 1 if ExpVector(p)==ExpVector(q): does not compare numbers !!
+#define p_LmEqual(p1, p2, r) p_ExpVectorEqual(p1, p2, r)
+
+// pCmp: args may be NULL
+// returns: (p2==NULL ? 1 : (p1 == NULL ? -1 : p_LmCmp(p1, p2)))
+static inline int p_Cmp(poly p1, poly p2, ring r)
+{
+  if (p2==NULL)
+    return 1;
+  if (p1==NULL)
+    return -1;
+  return p_LmCmp(p1,p2,r);
+}
+
+
+/***************************************************************
+ *
+ * divisibility
+ *
+ ***************************************************************/
+/// return: FALSE, if there exists i, such that a->exp[i] > b->exp[i]
+///         TRUE, otherwise
+/// (1) Consider long vars, instead of single exponents
+/// (2) Clearly, if la > lb, then FALSE
+/// (3) Suppose la <= lb, and consider first bits of single exponents in l:
+///     if TRUE, then value of these bits is la ^ lb
+///     if FALSE, then la-lb causes an "overflow" into one of those bits, i.e.,
+///               la ^ lb != la - lb
+static inline BOOLEAN _p_LmDivisibleByNoComp(poly a, poly b, const ring r)
+{
+  int i=r->VarL_Size - 1;
+  unsigned long divmask = r->divmask;
+  unsigned long la, lb;
+
+  if (r->VarL_LowIndex >= 0)
+  {
+    i += r->VarL_LowIndex;
+    do
+    {
+      la = a->exp[i];
+      lb = b->exp[i];
+      if ((la > lb) ||
+          (((la & divmask) ^ (lb & divmask)) != ((lb - la) & divmask)))
+      {
+        pDivAssume(p_DebugLmDivisibleByNoComp(a, b, r) == FALSE);
+        return FALSE;
+      }
+      i--;
+    }
+    while (i>=r->VarL_LowIndex);
+  }
+  else
+  {
+    do
+    {
+      la = a->exp[r->VarL_Offset[i]];
+      lb = b->exp[r->VarL_Offset[i]];
+      if ((la > lb) ||
+          (((la & divmask) ^ (lb & divmask)) != ((lb - la) & divmask)))
+      {
+        pDivAssume(p_DebugLmDivisibleByNoComp(a, b, r) == FALSE);
+        return FALSE;
+      }
+      i--;
+    }
+    while (i>=0);
+  }
+#ifdef HAVE_RINGS
+  pDivAssume(p_DebugLmDivisibleByNoComp(a, b, r) == n_DivBy(p_GetCoeff(b, r), p_GetCoeff(a, r), r->cf));
+  return (!rField_is_Ring(r)) || n_DivBy(p_GetCoeff(b, r), p_GetCoeff(a, r), r->cf);
+#else
+  pDivAssume(p_DebugLmDivisibleByNoComp(a, b, r) == TRUE);
+  return TRUE;
+#endif
+}
+
+static inline BOOLEAN _p_LmDivisibleByNoComp(poly a, const ring r_a, poly b, const ring r_b)
+{
+  int i=r_a->N;
+  pAssume1(r_a->N == r_b->N);
+
+  do
+  {
+    if (p_GetExp(a,i,r_a) > p_GetExp(b,i,r_b))
+      return FALSE;
+    i--;
+  }
+  while (i);
+#ifdef HAVE_RINGS
+  return n_DivBy(p_GetCoeff(b, r_b), p_GetCoeff(a, r_a), r_a->cf);
+#else
+  return TRUE;
+#endif
+}
+
+#ifdef HAVE_RATGRING
+static inline BOOLEAN _p_LmDivisibleByNoCompPart(poly a, const ring r_a, poly b, const ring r_b,const int start, const int end)
+{
+  int i=end;
+  pAssume1(r_a->N == r_b->N);
+
+  do
+  {
+    if (p_GetExp(a,i,r_a) > p_GetExp(b,i,r_b))
+      return FALSE;
+    i--;
+  }
+  while (i>=start);
+#ifdef HAVE_RINGS
+  return n_DivBy(p_GetCoeff(b, r_b), p_GetCoeff(a, r_a), r_a->cf);
+#else
+  return TRUE;
+#endif
+}
+static inline BOOLEAN _p_LmDivisibleByPart(poly a, const ring r_a, poly b, const ring r_b,const int start, const int end)
+{
+  if (p_GetComp(a, r_a) == 0 || p_GetComp(a,r_a) == p_GetComp(b,r_b))
+    return _p_LmDivisibleByNoCompPart(a, r_a, b, r_b,start,end);
+  return FALSE;
+}
+static inline BOOLEAN p_LmDivisibleByPart(poly a, poly b, const ring r,const int start, const int end)
+{
+  p_LmCheckPolyRing1(b, r);
+  pIfThen1(a != NULL, p_LmCheckPolyRing1(b, r));
+  if (p_GetComp(a, r) == 0 || p_GetComp(a,r) == p_GetComp(b,r))
+    return _p_LmDivisibleByNoCompPart(a, r, b, r,start, end);
+  return FALSE;
+}
+#endif
+static inline BOOLEAN _p_LmDivisibleBy(poly a, poly b, const ring r)
+{
+  if (p_GetComp(a, r) == 0 || p_GetComp(a,r) == p_GetComp(b,r))
+    return _p_LmDivisibleByNoComp(a, b, r);
+  return FALSE;
+}
+static inline BOOLEAN _p_LmDivisibleBy(poly a, const ring r_a, poly b, const ring r_b)
+{
+  if (p_GetComp(a, r_a) == 0 || p_GetComp(a,r_a) == p_GetComp(b,r_b))
+    return _p_LmDivisibleByNoComp(a, r_a, b, r_b);
+  return FALSE;
+}
+static inline BOOLEAN p_LmDivisibleByNoComp(poly a, poly b, const ring r)
+{
+  p_LmCheckPolyRing1(a, r);
+  p_LmCheckPolyRing1(b, r);
+  return _p_LmDivisibleByNoComp(a, b, r);
+}
+
+static inline BOOLEAN p_LmDivisibleByNoComp(poly a, const ring ra, poly b, const ring rb)
+{
+  p_LmCheckPolyRing1(a, ra);
+  p_LmCheckPolyRing1(b, rb);
+  return _p_LmDivisibleByNoComp(a, ra, b, rb);
+}
+
+static inline BOOLEAN p_LmDivisibleBy(poly a, poly b, const ring r)
+{
+  p_LmCheckPolyRing1(b, r);
+  pIfThen1(a != NULL, p_LmCheckPolyRing1(b, r));
+  if (p_GetComp(a, r) == 0 || p_GetComp(a,r) == p_GetComp(b,r))
+    return _p_LmDivisibleByNoComp(a, b, r);
+  return FALSE;
+}
+
+static inline BOOLEAN p_DivisibleBy(poly a, poly b, const ring r)
+{
+  pIfThen1(b!=NULL, p_LmCheckPolyRing1(b, r));
+  pIfThen1(a!=NULL, p_LmCheckPolyRing1(a, r));
+
+  if (a != NULL && (p_GetComp(a, r) == 0 || p_GetComp(a,r) == p_GetComp(b,r)))
+      return _p_LmDivisibleByNoComp(a,b,r);
+  return FALSE;
+}
+static inline BOOLEAN p_DivisibleBy(poly a, const ring r_a, poly b, const ring r_b)
+{
+  pIfThen1(b!=NULL, p_LmCheckPolyRing1(b, r_b));
+  pIfThen1(a!=NULL, p_LmCheckPolyRing1(a, r_a));
+  if (a != NULL) {
+      return _p_LmDivisibleBy(a, r_a, b, r_b);
+  }
+  return FALSE;
+}
+static inline BOOLEAN p_LmDivisibleBy(poly a, const ring r_a, poly b, const ring r_b)
+{
+  p_LmCheckPolyRing(a, r_a);
+  p_LmCheckPolyRing(b, r_b);
+  return _p_LmDivisibleBy(a, r_a, b, r_b);
+}
+
+static inline BOOLEAN p_LmShortDivisibleBy(poly a, unsigned long sev_a,
+                                    poly b, unsigned long not_sev_b, const ring r)
+{
+  p_LmCheckPolyRing1(a, r);
+  p_LmCheckPolyRing1(b, r);
+#ifndef PDIV_DEBUG
+  _pPolyAssume2(p_GetShortExpVector(a, r) == sev_a, a, r);
+  _pPolyAssume2(p_GetShortExpVector(b, r) == ~ not_sev_b, b, r);
+
+  if (sev_a & not_sev_b)
+  {
+    pAssume1(p_LmDivisibleByNoComp(a, b, r) == FALSE);
+    return FALSE;
+  }
+  return p_LmDivisibleBy(a, b, r);
+#else
+  return pDebugLmShortDivisibleBy(a, sev_a, r, b, not_sev_b, r);
+#endif
+}
+
+static inline BOOLEAN p_LmShortDivisibleByNoComp(poly a, unsigned long sev_a,
+                                           poly b, unsigned long not_sev_b, const ring r)
+{
+  p_LmCheckPolyRing1(a, r);
+  p_LmCheckPolyRing1(b, r);
+#ifndef PDIV_DEBUG
+  _pPolyAssume2(p_GetShortExpVector(a, r) == sev_a, a, r);
+  _pPolyAssume2(p_GetShortExpVector(b, r) == ~ not_sev_b, b, r);
+
+  if (sev_a & not_sev_b)
+  {
+    pAssume1(p_LmDivisibleByNoComp(a, b, r) == FALSE);
+    return FALSE;
+  }
+  return p_LmDivisibleByNoComp(a, b, r);
+#else
+  return pDebugLmShortDivisibleByNoComp(a, sev_a, r, b, not_sev_b, r);
+#endif
+}
+
+static inline BOOLEAN p_LmShortDivisibleBy(poly a, unsigned long sev_a, const ring r_a,
+                                      poly b, unsigned long not_sev_b, const ring r_b)
+{
+  p_LmCheckPolyRing1(a, r_a);
+  p_LmCheckPolyRing1(b, r_b);
+#ifndef PDIV_DEBUG
+  _pPolyAssume2(p_GetShortExpVector(a, r_a) == sev_a, a, r_a);
+  _pPolyAssume2(p_GetShortExpVector(b, r_b) == ~ not_sev_b, b, r_b);
+
+  if (sev_a & not_sev_b)
+  {
+    pAssume1(_p_LmDivisibleByNoComp(a, r_a, b, r_b) == FALSE);
+    return FALSE;
+  }
+  return _p_LmDivisibleBy(a, r_a, b, r_b);
+#else
+  return pDebugLmShortDivisibleBy(a, sev_a, r_a, b, not_sev_b, r_b);
+#endif
+}
+
+/***************************************************************
+ *
+ * Misc things on Lm
+ *
+ ***************************************************************/
+
+
+// like the respective p_LmIs* routines, except that p might be empty
+static inline BOOLEAN p_IsConstantComp(const poly p, const ring r)
+{
+  if (p == NULL) return TRUE;
+  return (pNext(p)==NULL) && p_LmIsConstantComp(p, r);
+}
+
+static inline BOOLEAN p_IsConstant(const poly p, const ring r)
+{
+  if (p == NULL) return TRUE;
+  p_Test(p, r);
+  return (pNext(p)==NULL) && p_LmIsConstant(p, r);
+}
+
+/// either poly(1)  or gen(k)?!
+static inline BOOLEAN p_IsOne(const poly p, const ring R)
+{
+  p_Test(p, R);
+  return (p_IsConstant(p, R) && n_IsOne(p_GetCoeff(p, R), R->cf));
+}
+
+static inline BOOLEAN p_IsConstantPoly(const poly p, const ring r)
+{
+  p_Test(p, r);
+  poly pp=p;
+  while(pp!=NULL)
+  {
+    if (! p_LmIsConstantComp(pp, r))
+      return FALSE;
+    pIter(pp);
+  }
+  return TRUE;
+}
+
+static inline BOOLEAN p_IsUnit(const poly p, const ring r)
+{
+  if (p == NULL) return FALSE;
+#ifdef HAVE_RINGS
+  if (rField_is_Ring(r))
+    return (p_LmIsConstant(p, r) && n_IsUnit(pGetCoeff(p),r->cf));
+#endif
+  return p_LmIsConstant(p, r);
+}
+
+static inline BOOLEAN p_LmExpVectorAddIsOk(const poly p1, const poly p2,
+                                      const ring r)
+{
+  p_LmCheckPolyRing(p1, r);
+  p_LmCheckPolyRing(p2, r);
+  unsigned long l1, l2, divmask = r->divmask;
+  int i;
+
+  for (i=0; i<r->VarL_Size; i++)
+  {
+    l1 = p1->exp[r->VarL_Offset[i]];
+    l2 = p2->exp[r->VarL_Offset[i]];
+    // do the divisiblity trick
+    if ( (l1 > ULONG_MAX - l2) ||
+         (((l1 & divmask) ^ (l2 & divmask)) != ((l1 + l2) & divmask)))
+      return FALSE;
+  }
+  return TRUE;
+}
+void      p_Split(poly p, poly * r);   /*p => IN(p), r => REST(p) */
+BOOLEAN p_HasNotCF(poly p1, poly p2, const ring r);
+poly      p_mInit(const char *s, BOOLEAN &ok, const ring r); /* monom s -> poly, interpreter */
+const char *    p_Read(const char *s, poly &p,const ring r); /* monom -> poly */
+poly      p_Divide(poly a, poly b, const ring r);
+poly      p_DivideM(poly a, poly b, const ring r);
+poly      p_Div_nn(poly p, const number n, const ring r);
+
+// returns the LCM of the head terms of a and b in *m
+void p_Lcm(const poly a, const poly b, poly m, const ring r);
+
+#ifdef HAVE_RATGRING
+poly p_LcmRat(const poly a, const poly b, const long lCompM, const ring r);
+poly p_GetCoeffRat(poly p, int ishift, ring r);
+void p_LmDeleteAndNextRat(poly *p, int ishift, ring r);
+void p_ContentRat(poly &ph, const ring r);
+#endif /* ifdef HAVE_RATGRING */
+
+
+poly      p_Diff(poly a, int k, const ring r);
+poly      p_DiffOp(poly a, poly b,BOOLEAN multiply, const ring r);
+int       p_Weight(int c, const ring r);
+
+///   assumes that p and divisor are univariate polynomials in r,
+///   mentioning the same variable;
+///   assumes divisor != NULL;
+///   p may be NULL;
+///   assumes a global monomial ordering in r;
+///   performs polynomial division of p by divisor:
+///     - afterwards p contains the remainder of the division, i.e.,
+///       p_before = result * divisor + p_afterwards;
+///     - if needResult == TRUE, then the method computes and returns 'result',
+///       otherwise NULL is returned (This parametrization can be used when
+///       one is only interested in the remainder of the division. In this
+///       case, the method will be slightly faster.)
+///   leaves divisor unmodified
+poly      p_PolyDiv(poly &p, const poly divisor, const BOOLEAN needResult, const ring r);
+
+/* syszygy stuff */
+BOOLEAN   p_VectorHasUnitB(poly p, int * k, const ring r);
+void      p_VectorHasUnit(poly p, int * k, int * len, const ring r);
+poly      p_TakeOutComp1(poly * p, int k, const ring r);
+// Splits *p into two polys: *q which consists of all monoms with
+// component == comp and *p of all other monoms *lq == pLength(*q)
+// On return all components pf *q == 0
+void p_TakeOutComp(poly *p, long comp, poly *q, int *lq, const ring r);
+
+// This is something weird -- Don't use it, unless you know what you are doing
+poly      p_TakeOutComp(poly * p, int k, const ring r);
+
+void      p_DeleteComp(poly * p,int k, const ring r);
+
+/*-------------ring management:----------------------*/
+
+// resets the pFDeg and pLDeg: if pLDeg is not given, it is
+// set to currRing->pLDegOrig, i.e. to the respective LDegProc which
+// only uses pFDeg (and not pDeg, or pTotalDegree, etc).
+// If you use this, make sure your procs does not make any assumptions
+// on ordering and/or OrdIndex -- otherwise they might return wrong results
+// on strat->tailRing
+void pSetDegProcs(ring r, pFDegProc new_FDeg, pLDegProc new_lDeg = NULL);
+// restores pFDeg and pLDeg:
+void pRestoreDegProcs(ring r, pFDegProc old_FDeg, pLDegProc old_lDeg);
+
+/*-------------pComp for syzygies:-------------------*/
+void p_SetModDeg(intvec *w, ring r);
+
+/*------------ Jet ----------------------------------*/
+poly pp_Jet(poly p, int m, const ring R);
+poly p_Jet(poly p, int m,const ring R);
+poly pp_JetW(poly p, int m, short *w, const ring R);
+poly p_JetW(poly p, int m, short *w, const ring R);
+
+poly n_PermNumber(const number z, const int *par_perm, const int OldPar, const ring src, const ring dst);
+
+poly p_PermPoly (poly p, const int * perm,const ring OldRing, const ring dst,
+                     nMapFunc nMap, const int *par_perm=NULL, int OldPar=0);
+
+/*----------------------------------------------------*/
+poly p_Series(int n,poly p,poly u, intvec *w, const ring R);
+poly p_Invers(int n,poly u,intvec *w, const ring R);
+
+
+
+/*----------------------------------------------------*/
+int   p_Var(poly mi, const ring r);
+/// the minimal index of used variables - 1
+int   p_LowVar (poly p, const ring r);
+
+/*----------------------------------------------------*/
+/// shifts components of the vector p by i
+void p_Shift (poly * p,int i, const ring r);
+#endif // P_POLYS_H
+
diff --git a/libpolys/polys/monomials/ring.cc b/libpolys/polys/monomials/ring.cc
new file mode 100644
index 0000000..d886bfc
--- /dev/null
+++ b/libpolys/polys/monomials/ring.cc
@@ -0,0 +1,5598 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT - the interpreter related ring operations
+*/
+
+/* includes */
+#include <math.h>
+
+
+
+
+
+#include <omalloc/omalloc.h>
+
+#include <misc/auxiliary.h>
+#include <misc/mylimits.h>
+#include <misc/options.h>
+#include <misc/int64vec.h>
+
+#include <coeffs/numbers.h>
+#include <coeffs/coeffs.h>
+
+#include <polys/monomials/p_polys.h>
+#include <polys/simpleideals.h>
+// #include <???/febase.h>
+// #include <???/intvec.h>
+// #include <coeffs/ffields.h>
+#include <polys/monomials/ring.h>
+#include <polys/monomials/maps.h>
+#include <polys/prCopy.h>
+// #include "../Singular/ipshell.h"
+#include <polys/templates/p_Procs.h>
+
+#include <polys/matpol.h>
+
+#include <polys/monomials/ring.h>
+
+#ifdef HAVE_PLURAL
+#include <polys/nc/nc.h>
+#include <polys/nc/sca.h>
+#endif
+// #include <???/maps.h>
+// #include <???/matpol.h>
+
+
+#include "ext_fields/algext.h"
+#include "ext_fields/transext.h"
+
+
+#define BITS_PER_LONG 8*SIZEOF_LONG
+
+omBin sip_sring_bin = omGetSpecBin(sizeof(ip_sring));
+omBin char_ptr_bin =  omGetSpecBin(sizeof(char*));
+
+
+static const char * const ringorder_name[] =
+{
+  " ?", ///< ringorder_no = 0,
+  "a", ///< ringorder_a,
+  "A", ///< ringorder_a64,
+  "c", ///< ringorder_c,
+  "C", ///< ringorder_C,
+  "M", ///< ringorder_M,
+  "S", ///< ringorder_S,
+  "s", ///< ringorder_s,
+  "lp", ///< ringorder_lp,
+  "dp", ///< ringorder_dp,
+  "rp", ///< ringorder_rp,
+  "Dp", ///< ringorder_Dp,
+  "wp", ///< ringorder_wp,
+  "Wp", ///< ringorder_Wp,
+  "ls", ///< ringorder_ls,
+  "ds", ///< ringorder_ds,
+  "Ds", ///< ringorder_Ds,
+  "ws", ///< ringorder_ws,
+  "Ws", ///< ringorder_Ws,
+  "am",  ///< ringorder_am,
+  "L", ///< ringorder_L,
+  "aa", ///< ringorder_aa
+  "rs", ///< ringorder_rs,
+  "IS", ///<  ringorder_IS
+  " _" ///< ringorder_unspec
+};
+
+
+const char * rSimpleOrdStr(int ord)
+{
+  return ringorder_name[ord];
+}
+
+/// unconditionally deletes fields in r
+void rDelete(ring r);
+/// set r->VarL_Size, r->VarL_Offset, r->VarL_LowIndex
+static void rSetVarL(ring r);
+/// get r->divmask depending on bits per exponent
+static unsigned long rGetDivMask(int bits);
+/// right-adjust r->VarOffset
+static void rRightAdjustVarOffset(ring r);
+static void rOptimizeLDeg(ring r);
+
+/*0 implementation*/
+//BOOLEAN rField_is_R(ring r)
+//{
+//  if (r->cf->ch== -1)
+//  {
+//    if (r->float_len==(short)0) return TRUE;
+//  }
+//  return FALSE;
+//}
+
+ring rDefault(const coeffs cf, int N, char **n,int ord_size, int *ord, int *block0, int *block1, int** wvhdl)
+{
+  assume( cf != NULL);
+  ring r=(ring) omAlloc0Bin(sip_sring_bin);
+  r->N     = N;
+  r->cf = cf;
+  /*rPar(r)  = 0; Alloc0 */
+  /*names*/
+  r->names = (char **) omAlloc0(N * sizeof(char *));
+  int i;
+  for(i=0;i<N;i++)
+  {
+    r->names[i]  = omStrDup(n[i]);
+  }
+  /*weights: entries for 2 blocks: NULL*/
+  if (wvhdl==NULL)
+    r->wvhdl = (int **)omAlloc0((ord_size+1) * sizeof(int *));
+  else
+    r->wvhdl=wvhdl;
+  r->order = ord;
+  r->block0 = block0;
+  r->block1 = block1;
+
+  /* complete ring intializations */
+  rComplete(r);
+  return r;
+}
+ring rDefault(int ch, int N, char **n,int ord_size, int *ord, int *block0, int *block1,int ** wvhdl)
+{
+  coeffs cf;
+  if (ch==0) cf=nInitChar(n_Q,NULL);
+  else       cf=nInitChar(n_Zp,(void*)(long)ch);
+  assume( cf != NULL);
+  return rDefault(cf,N,n,ord_size,ord,block0,block1,wvhdl);
+}
+ring   rDefault(const coeffs cf, int N, char **n)
+{
+  assume( cf != NULL);
+  /*order: lp,0*/
+  int *order = (int *) omAlloc(2* sizeof(int));
+  int *block0 = (int *)omAlloc0(2 * sizeof(int));
+  int *block1 = (int *)omAlloc0(2 * sizeof(int));
+  /* ringorder dp for the first block: var 1..N */
+  order[0]  = ringorder_lp;
+  block0[0] = 1;
+  block1[0] = N;
+  /* the last block: everything is 0 */
+  order[1]  = 0;
+
+  return rDefault(cf,N,n,2,order,block0,block1);
+}
+
+ring rDefault(int ch, int N, char **n)
+{
+  coeffs cf;
+  if (ch==0) cf=nInitChar(n_Q,NULL);
+  else       cf=nInitChar(n_Zp,(void*)(long)ch);
+  assume( cf != NULL);
+  return rDefault(cf,N,n);
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+// rInit: define a new ring from sleftv's
+//
+//-> ipshell.cc
+
+/////////////////////////////
+// Auxillary functions
+//
+
+// check intvec, describing the ordering
+BOOLEAN rCheckIV(intvec *iv)
+{
+  if ((iv->length()!=2)&&(iv->length()!=3))
+  {
+    WerrorS("weights only for orderings wp,ws,Wp,Ws,a,M");
+    return TRUE;
+  }
+  return FALSE;
+}
+
+int rTypeOfMatrixOrder(intvec * order)
+{
+  int i=0,j,typ=1;
+  int sz = (int)sqrt((double)(order->length()-2));
+  if ((sz*sz)!=(order->length()-2))
+  {
+    WerrorS("Matrix order is not a square matrix");
+    typ=0;
+  }
+  while ((i<sz) && (typ==1))
+  {
+    j=0;
+    while ((j<sz) && ((*order)[j*sz+i+2]==0)) j++;
+    if (j>=sz)
+    {
+      typ = 0;
+      WerrorS("Matrix order not complete");
+    }
+    else if ((*order)[j*sz+i+2]<0)
+      typ = -1;
+    else
+      i++;
+  }
+  return typ;
+}
+
+
+int r_IsRingVar(const char *n, char**names,int N)
+{
+  if (names!=NULL)
+  {
+    for (int i=0; i<N; i++)
+    {
+      if (names[i]==NULL) return -1;
+      if (strcmp(n,names[i]) == 0) return (int)i;
+    }
+  }
+  return -1;
+}
+
+
+void   rWrite(ring r, BOOLEAN details)
+{
+  if ((r==NULL)||(r->order==NULL))
+    return; /*to avoid printing after errors....*/
+
+  assume(r != NULL);
+  const coeffs C = r->cf;
+  assume(C != NULL);
+
+  int nblocks=rBlocks(r);
+
+  // omCheckAddrSize(r,sizeof(ip_sring));
+  omCheckAddrSize(r->order,nblocks*sizeof(int));
+  omCheckAddrSize(r->block0,nblocks*sizeof(int));
+  omCheckAddrSize(r->block1,nblocks*sizeof(int));
+  omCheckAddrSize(r->wvhdl,nblocks*sizeof(int *));
+  omCheckAddrSize(r->names,r->N*sizeof(char *));
+
+  nblocks--;
+
+
+  if( nCoeff_is_algExt(C) )
+  {
+    // NOTE: the following (non-thread-safe!) UGLYNESS
+    // (changing naRing->ShortOut for a while) is due to Hans!
+    // Just think of other ring using the VERY SAME naRing and possible
+    // side-effects...
+    ring R = C->extRing;
+    const BOOLEAN bSaveShortOut = rShortOut(R); R->ShortOut = rShortOut(r) & rCanShortOut(R);
+
+    n_CoeffWrite(C, details); // for correct printing of minpoly... WHAT AN UGLYNESS!!!
+
+    R->ShortOut = bSaveShortOut;
+  }
+  else
+    n_CoeffWrite(C, details);
+//   {
+//     PrintS("//   characteristic : ");
+//
+//     char const * const * const params = rParameter(r);
+//
+//     if (params!=NULL)
+//     {
+//       Print ("//   %d parameter    : ",rPar(r));
+//
+//       char const * const * sp= params;
+//       int nop=0;
+//       while (nop<rPar(r))
+//       {
+//         PrintS(*sp);
+//         PrintS(" ");
+//         sp++; nop++;
+//       }
+//       PrintS("\n//   minpoly        : ");
+//       if ( rField_is_long_C(r) )
+//       {
+//         // i^2+1:
+//         Print("(%s^2+1)\n", params[0]);
+//       }
+//       else if (rMinpolyIsNULL(r))
+//       {
+//         PrintS("0\n");
+//       }
+//       else
+//       {
+//         StringSetS(""); n_Write(r->cf->minpoly, r); PrintS(StringEndS("\n")); // NOTE/TODO: use StringAppendS("\n"); omFree(s);
+//       }
+//       //if (r->qideal!=NULL)
+//       //{
+//       //  iiWriteMatrix((matrix)r->qideal,"//   minpolys",1,r,0);
+//       //  PrintLn();
+//       //}
+//     }
+//   }
+  Print("//   number of vars : %d",r->N);
+
+  //for (nblocks=0; r->order[nblocks]; nblocks++);
+  nblocks=rBlocks(r)-1;
+
+  for (int l=0, nlen=0 ; l<nblocks; l++)
+  {
+    int i;
+    Print("\n//        block %3d : ",l+1);
+
+    Print("ordering %s", rSimpleOrdStr(r->order[l]));
+
+
+    if (r->order[l] == ringorder_s)
+    {
+      assume( l == 0 );
+#ifndef SING_NDEBUG
+      Print("  syzcomp at %d",r->typ[l].data.syz.limit);
+#endif
+      continue;
+    }
+    else if (r->order[l] == ringorder_IS)
+    {
+      assume( r->block0[l] == r->block1[l] );
+      const int s = r->block0[l];
+      assume( (-2 < s) && (s < 2) );
+      Print("(%d)", s); // 0 => prefix! +/-1 => suffix!
+      continue;
+    }
+    else if (
+    (  (r->order[l] >= ringorder_lp)
+    ||(r->order[l] == ringorder_M)
+    ||(r->order[l] == ringorder_a)
+    ||(r->order[l] == ringorder_am)
+    ||(r->order[l] == ringorder_a64)
+    ||(r->order[l] == ringorder_aa) ) && (r->order[l] < ringorder_IS) )
+    {
+      PrintS("\n//                  : names   ");
+      for (i = r->block0[l]-1; i<r->block1[l]; i++)
+      {
+        nlen = strlen(r->names[i]);
+        Print(" %s",r->names[i]);
+      }
+    }
+
+    if (r->wvhdl[l]!=NULL)
+    {
+      for (int j= 0;
+           j<(r->block1[l]-r->block0[l]+1)*(r->block1[l]-r->block0[l]+1);
+           j+=i)
+      {
+        PrintS("\n//                  : weights ");
+        for (i = 0; i<=r->block1[l]-r->block0[l]; i++)
+        {
+          if (r->order[l] == ringorder_a64)
+          {
+            int64 *w=(int64 *)r->wvhdl[l];
+            #if SIZEOF_LONG == 4
+            Print("%*lld " ,nlen,w[i+j]);
+            #else
+            Print(" %*ld"  ,nlen,w[i+j]);
+            #endif
+          }
+          else
+            Print(" %*d" ,nlen,r->wvhdl[l][i+j]);
+        }
+        if (r->order[l]!=ringorder_M) break;
+      }
+      if (r->order[l]==ringorder_am)
+      {
+        int m=r->wvhdl[l][i];
+        Print("\n//                  : %d module weights ",m);
+        m+=i;i++;
+        for(;i<=m;i++) Print(" %*d" ,nlen,r->wvhdl[l][i]);
+      }
+    }
+  }
+#ifdef HAVE_PLURAL
+  if(rIsPluralRing(r))
+  {
+    PrintS("\n//   noncommutative relations:");
+    if( details )
+    {
+      poly pl=NULL;
+      int nl;
+      int i,j;
+      for (i = 1; i<r->N; i++)
+      {
+        for (j = i+1; j<=r->N; j++)
+        {
+          nl = n_IsOne(p_GetCoeff(MATELEM(r->GetNC()->C,i,j),r), r->cf);
+          if ( (MATELEM(r->GetNC()->D,i,j)!=NULL) || (!nl) )
+          {
+            Print("\n//    %s%s=",r->names[j-1],r->names[i-1]);
+            pl = MATELEM(r->GetNC()->MT[UPMATELEM(i,j,r->N)],1,1);
+            p_Write0(pl, r, r);
+          }
+        }
+      }
+    } else
+      PrintS(" ...");
+
+#if MYTEST  /*Singularg should not differ from Singular except in error case*/
+    Print("\n//   noncommutative type:%d", (int)ncRingType(r));
+    Print("\n//      is skew constant:%d",r->GetNC()->IsSkewConstant);
+    if( rIsSCA(r) )
+    {
+      Print("\n//   alternating variables: [%d, %d]", scaFirstAltVar(r), scaLastAltVar(r));
+      const ideal Q = SCAQuotient(r); // resides within r!
+      PrintS("\n//   quotient of sca by ideal");
+
+      if (Q!=NULL)
+      {
+//        if (r==currRing)
+//        {
+//          PrintLn();
+          iiWriteMatrix((matrix)Q,"scaQ",1,r,0);
+//        }
+//        else
+//            PrintS(" ...");
+      }
+      else
+        PrintS(" (NULL)");
+    }
+#endif
+  }
+#endif
+  if (r->qideal!=NULL)
+  {
+    PrintS("\n// quotient ring from ideal");
+    if( details )
+    {
+      PrintLn();
+      iiWriteMatrix((matrix)r->qideal,"_",1,r,0);
+    } else PrintS(" ...");
+  }
+}
+
+void rDelete(ring r)
+{
+  int i, j;
+
+  if (r == NULL) return;
+
+  assume( r->ref <= 0 );
+
+  if( r->ref > 0 ) // ->ref means the number of Interpreter objects referring to the ring...
+    return;       // this should never happen.
+
+  if( r->qideal != NULL )
+  {
+    ideal q = r->qideal;
+    r->qideal = NULL;
+    id_Delete(&q, r);
+  }
+
+#ifdef HAVE_PLURAL
+  if (rIsPluralRing(r))
+    nc_rKill(r);
+#endif
+
+  nKillChar(r->cf); r->cf = NULL;
+  rUnComplete(r);
+  // delete order stuff
+  if (r->order != NULL)
+  {
+    i=rBlocks(r);
+    assume(r->block0 != NULL && r->block1 != NULL && r->wvhdl != NULL);
+    // delete order
+    omFreeSize((ADDRESS)r->order,i*sizeof(int));
+    omFreeSize((ADDRESS)r->block0,i*sizeof(int));
+    omFreeSize((ADDRESS)r->block1,i*sizeof(int));
+    // delete weights
+    for (j=0; j<i; j++)
+    {
+      if (r->wvhdl[j]!=NULL)
+        omFree(r->wvhdl[j]);
+    }
+    omFreeSize((ADDRESS)r->wvhdl,i*sizeof(int *));
+  }
+  else
+  {
+    assume(r->block0 == NULL && r->block1 == NULL && r->wvhdl == NULL);
+  }
+
+  // delete varnames
+  if(r->names!=NULL)
+  {
+    for (i=0; i<r->N; i++)
+    {
+      if (r->names[i] != NULL) omFree((ADDRESS)r->names[i]);
+    }
+    omFreeSize((ADDRESS)r->names,r->N*sizeof(char *));
+  }
+
+  omFreeBin(r, sip_sring_bin);
+}
+
+int rOrderName(char * ordername)
+{
+  int order=ringorder_unspec;
+  while (order!= 0)
+  {
+    if (strcmp(ordername,rSimpleOrdStr(order))==0)
+      break;
+    order--;
+  }
+  if (order==0) Werror("wrong ring order `%s`",ordername);
+  omFree((ADDRESS)ordername);
+  return order;
+}
+
+char * rOrdStr(ring r)
+{
+  if ((r==NULL)||(r->order==NULL)) return omStrDup("");
+  int nblocks,l,i;
+
+  for (nblocks=0; r->order[nblocks]; nblocks++);
+  nblocks--;
+
+  StringSetS("");
+  for (l=0; ; l++)
+  {
+    StringAppendS((char *)rSimpleOrdStr(r->order[l]));
+    if (
+           (r->order[l] != ringorder_c)
+        && (r->order[l] != ringorder_C)
+        && (r->order[l] != ringorder_s)
+        && (r->order[l] != ringorder_S)
+        && (r->order[l] != ringorder_IS)
+       )
+    {
+      if (r->wvhdl[l]!=NULL)
+      {
+        StringAppendS("(");
+        for (int j= 0;
+             j<(r->block1[l]-r->block0[l]+1)*(r->block1[l]-r->block0[l]+1);
+             j+=i+1)
+        {
+          char c=',';
+          if(r->order[l]==ringorder_a64)
+          {
+            int64 * w=(int64 *)r->wvhdl[l];
+            for (i = 0; i<r->block1[l]-r->block0[l]; i++)
+            {
+              StringAppend("%lld," ,w[i]);
+            }
+            StringAppend("%lld)" ,w[i]);
+            break;
+          }
+          else
+          {
+            for (i = 0; i<r->block1[l]-r->block0[l]; i++)
+            {
+              StringAppend("%d," ,r->wvhdl[l][i+j]);
+            }
+          }
+          if (r->order[l]!=ringorder_M)
+          {
+            StringAppend("%d)" ,r->wvhdl[l][i+j]);
+            break;
+          }
+          if (j+i+1==(r->block1[l]-r->block0[l]+1)*(r->block1[l]-r->block0[l]+1))
+            c=')';
+          StringAppend("%d%c" ,r->wvhdl[l][i+j],c);
+        }
+      }
+      else
+        StringAppend("(%d)",r->block1[l]-r->block0[l]+1);
+    }
+    else if (r->order[l] == ringorder_IS)
+    {
+      assume( r->block0[l] == r->block1[l] );
+      const int s = r->block0[l];
+      assume( (-2 < s) && (s < 2) );
+
+      StringAppend("(%d)", s);
+    }
+
+    if (l==nblocks) return StringEndS();
+    StringAppendS(",");
+  }
+}
+
+char * rVarStr(ring r)
+{
+  if ((r==NULL)||(r->names==NULL)) return omStrDup("");
+  int i;
+  int l=2;
+  char *s;
+
+  for (i=0; i<r->N; i++)
+  {
+    l+=strlen(r->names[i])+1;
+  }
+  s=(char *)omAlloc((long)l);
+  s[0]='\0';
+  for (i=0; i<r->N-1; i++)
+  {
+    strcat(s,r->names[i]);
+    strcat(s,",");
+  }
+  strcat(s,r->names[i]);
+  return s;
+}
+
+/// TODO: make it a virtual method of coeffs, together with:
+/// Decompose & Compose, rParameter & rPar
+char * rCharStr(const ring r){ assume( r != NULL ); return nCoeffString(r->cf); }
+
+char * rParStr(ring r)
+{
+  if ((r==NULL)||(rParameter(r)==NULL)) return omStrDup("");
+
+  char const * const * const params = rParameter(r);
+
+  int i;
+  int l=2;
+
+  for (i=0; i<rPar(r); i++)
+  {
+    l+=strlen(params[i])+1;
+  }
+  char *s=(char *)omAlloc((long)l);
+  s[0]='\0';
+  for (i=0; i<rPar(r)-1; i++)
+  {
+    strcat(s, params[i]);
+    strcat(s,",");
+  }
+  strcat(s, params[i]);
+  return s;
+}
+
+char * rString(ring r)
+{
+  if (r!=NULL)
+  {
+    char *ch=rCharStr(r);
+    char *var=rVarStr(r);
+    char *ord=rOrdStr(r);
+    char *res=(char *)omAlloc(strlen(ch)+strlen(var)+strlen(ord)+9);
+    sprintf(res,"(%s),(%s),(%s)",ch,var,ord);
+    omFree((ADDRESS)ch);
+    omFree((ADDRESS)var);
+    omFree((ADDRESS)ord);
+    return res;
+  }
+  else
+    return omStrDup("NULL");
+}
+
+
+/*
+// The fowolling function seems to be never used. Remove?
+static int binaryPower (const int a, const int b)
+{
+  // computes a^b according to the binary representation of b,
+  //   i.e., a^7 = a^4 * a^2 * a^1. This saves some multiplications.
+  int result = 1;
+  int factor = a;
+  int bb = b;
+  while (bb != 0)
+  {
+    if (bb % 2 != 0) result = result * factor;
+    bb = bb / 2;
+    factor = factor * factor;
+  }
+  return result;
+}
+*/
+
+/* we keep this otherwise superfluous method for compatibility reasons
+   towards the SINGULAR svn trunk */
+int rChar(ring r) { return r->cf->ch; }
+
+// typedef char *             char_ptr;
+// omBin char_ptr_bin = omGetSpecBin(sizeof(char_ptr)); // deallocation?
+
+
+// creates a commutative nc extension; "converts" comm.ring to a Plural ring
+#ifdef HAVE_PLURAL
+ring nc_rCreateNCcomm_rCopy(ring r)
+{
+  r = rCopy(r);
+  if (rIsPluralRing(r))
+    return r;
+
+  matrix C = mpNew(r->N,r->N); // ring-independent!?!
+  matrix D = mpNew(r->N,r->N);
+
+  for(int i=1; i<r->N; i++)
+    for(int j=i+1; j<=r->N; j++)
+      MATELEM(C,i,j) = p_One( r);
+
+  if (nc_CallPlural(C, D, NULL, NULL, r, false, true, false, r/*??currRing??*/, TRUE)) // TODO: what about quotient ideal?
+    WarnS("Error initializing multiplication!"); // No reaction!???
+
+  return r;
+}
+#endif
+
+
+/*2
+ *returns -1 for not compatible, (sum is undefined)
+ *         1 for compatible (and sum)
+ */
+/* vartest: test for variable/paramter names
+* dp_dp: for comm. rings: use block order dp + dp/ds/wp
+*/
+int rSumInternal(ring r1, ring r2, ring &sum, BOOLEAN vartest, BOOLEAN dp_dp)
+{
+
+  ip_sring tmpR;
+  memset(&tmpR,0,sizeof(tmpR));
+  /* check coeff. field =====================================================*/
+
+  if (r1->cf==r2->cf)
+  {
+    tmpR.cf=nCopyCoeff(r1->cf);
+  }
+  else /* different type */
+  {
+    if (getCoeffType(r1->cf)==n_Zp)
+    {
+      if (getCoeffType(r2->cf)==n_Q)
+      {
+        tmpR.cf=nCopyCoeff(r1->cf);
+      }
+      else if (nCoeff_is_Extension(r2->cf) && rChar(r2) == rChar(r1))
+      {
+        /*AlgExtInfo extParam;
+        extParam.r = r2->cf->extRing;
+        extParam.i = r2->cf->extRing->qideal;*/
+        tmpR.cf=nCopyCoeff(r2->cf);
+      }
+      else
+      {
+        WerrorS("Z/p+...");
+        return -1;
+      }
+    }
+    else if (getCoeffType(r1->cf)==n_R)
+    {
+      WerrorS("R+..");
+      return -1;
+    }
+    else if (getCoeffType(r1->cf)==n_Q)
+    {
+      if (getCoeffType(r2->cf)==n_Zp)
+      {
+        tmpR.cf=nCopyCoeff(r2->cf);
+      }
+      else if (nCoeff_is_Extension(r2->cf))
+      {
+        tmpR.cf=nCopyCoeff(r2->cf);
+      }
+      else
+      {
+        WerrorS("Q+...");
+        return -1;
+      }
+    }
+    else if (nCoeff_is_Extension(r1->cf))
+    {
+      if (r1->cf->extRing->cf==r2->cf)
+      {
+        tmpR.cf=nCopyCoeff(r1->cf);
+      }
+      else if (getCoeffType(r1->cf->extRing->cf)==n_Zp && getCoeffType(r2->cf)==n_Q) //r2->cf == n_Zp should have been handled above
+      {
+        tmpR.cf=nCopyCoeff(r1->cf);
+      }
+      else
+      {
+        WerrorS ("coeff sum of two extension fields not implemented");
+        return -1;
+      }
+    }
+    else
+    {
+      WerrorS("coeff sum not yet implemented");
+      return -1;
+    }
+  }
+  /* variable names ========================================================*/
+  int i,j,k;
+  int l=r1->N+r2->N;
+  char **names=(char **)omAlloc0(l*sizeof(char *));
+  k=0;
+
+  // collect all varnames from r1, except those which are parameters
+  // of r2, or those which are the empty string
+  for (i=0;i<r1->N;i++)
+  {
+    BOOLEAN b=TRUE;
+
+    if (*(r1->names[i]) == '\0')
+      b = FALSE;
+    else if ((rParameter(r2)!=NULL) && (strlen(r1->names[i])==1))
+    {
+      if (vartest)
+      {
+        for(j=0;j<rPar(r2);j++)
+        {
+          if (strcmp(r1->names[i],rParameter(r2)[j])==0)
+          {
+            b=FALSE;
+            break;
+          }
+        }
+      }
+    }
+
+    if (b)
+    {
+      //Print("name : %d: %s\n",k,r1->names[i]);
+      names[k]=omStrDup(r1->names[i]);
+      k++;
+    }
+    //else
+    //  Print("no name (par1) %s\n",r1->names[i]);
+  }
+  // Add variables from r2, except those which are parameters of r1
+  // those which are empty strings, and those which equal a var of r1
+  for(i=0;i<r2->N;i++)
+  {
+    BOOLEAN b=TRUE;
+
+    if (*(r2->names[i]) == '\0')
+      b = FALSE;
+    else if ((rParameter(r1)!=NULL) && (strlen(r2->names[i])==1))
+    {
+      if (vartest)
+      {
+        for(j=0;j<rPar(r1);j++)
+        {
+          if (strcmp(r2->names[i],rParameter(r1)[j])==0)
+          {
+            b=FALSE;
+            break;
+          }
+        }
+      }
+    }
+
+    if (b)
+    {
+      if (vartest)
+      {
+        for(j=0;j<r1->N;j++)
+        {
+          if (strcmp(r1->names[j],r2->names[i])==0)
+          {
+            b=FALSE;
+            break;
+          }
+        }
+      }
+      if (b)
+      {
+        //Print("name : %d : %s\n",k,r2->names[i]);
+        names[k]=omStrDup(r2->names[i]);
+        k++;
+      }
+      //else
+      //  Print("no name (var): %s\n",r2->names[i]);
+    }
+    //else
+    //  Print("no name (par): %s\n",r2->names[i]);
+  }
+  // check whether we found any vars at all
+  if (k == 0)
+  {
+    names[k]=omStrDup("");
+    k=1;
+  }
+  tmpR.N=k;
+  tmpR.names=names;
+  /* ordering *======================================================== */
+  tmpR.OrdSgn=1;
+  if (dp_dp
+#ifdef HAVE_PLURAL
+      && !rIsPluralRing(r1) && !rIsPluralRing(r2)
+#endif
+     )
+  {
+    tmpR.order=(int*)omAlloc(4*sizeof(int));
+    tmpR.block0=(int*)omAlloc0(4*sizeof(int));
+    tmpR.block1=(int*)omAlloc0(4*sizeof(int));
+    tmpR.wvhdl=(int**)omAlloc0(4*sizeof(int *));
+    tmpR.order[0]=ringorder_dp;
+    tmpR.block0[0]=1;
+    tmpR.block1[0]=rVar(r1);
+    if (r2->OrdSgn==1)
+    {
+      if ((r2->block0[0]==1)
+      && (r2->block1[0]==rVar(r2))
+      && ((r2->order[0]==ringorder_wp)
+        || (r2->order[0]==ringorder_Wp)
+        || (r2->order[0]==ringorder_Dp))
+     )
+     {
+       tmpR.order[1]=r2->order[0];
+       if (r2->wvhdl[0]!=NULL)
+         tmpR.wvhdl[1]=(int *)omMemDup(r2->wvhdl[0]);
+     }
+     else
+        tmpR.order[1]=ringorder_dp;
+    }
+    else
+    {
+      tmpR.order[1]=ringorder_ds;
+      tmpR.OrdSgn=-1;
+    }
+    tmpR.block0[1]=rVar(r1)+1;
+    tmpR.block1[1]=rVar(r1)+rVar(r2);
+    tmpR.order[2]=ringorder_C;
+    tmpR.order[3]=0;
+  }
+  else
+  {
+    if ((r1->order[0]==ringorder_unspec)
+        && (r2->order[0]==ringorder_unspec))
+    {
+      tmpR.order=(int*)omAlloc(3*sizeof(int));
+      tmpR.block0=(int*)omAlloc(3*sizeof(int));
+      tmpR.block1=(int*)omAlloc(3*sizeof(int));
+      tmpR.wvhdl=(int**)omAlloc0(3*sizeof(int *));
+      tmpR.order[0]=ringorder_unspec;
+      tmpR.order[1]=ringorder_C;
+      tmpR.order[2]=0;
+      tmpR.block0[0]=1;
+      tmpR.block1[0]=tmpR.N;
+    }
+    else if (l==k) /* r3=r1+r2 */
+    {
+      int b;
+      ring rb;
+      if (r1->order[0]==ringorder_unspec)
+      {
+        /* extend order of r2 to r3 */
+        b=rBlocks(r2);
+        rb=r2;
+        tmpR.OrdSgn=r2->OrdSgn;
+      }
+      else if (r2->order[0]==ringorder_unspec)
+      {
+        /* extend order of r1 to r3 */
+        b=rBlocks(r1);
+        rb=r1;
+        tmpR.OrdSgn=r1->OrdSgn;
+      }
+      else
+      {
+        b=rBlocks(r1)+rBlocks(r2)-2; /* for only one order C, only one 0 */
+        rb=NULL;
+      }
+      tmpR.order=(int*)omAlloc0(b*sizeof(int));
+      tmpR.block0=(int*)omAlloc0(b*sizeof(int));
+      tmpR.block1=(int*)omAlloc0(b*sizeof(int));
+      tmpR.wvhdl=(int**)omAlloc0(b*sizeof(int *));
+      /* weights not implemented yet ...*/
+      if (rb!=NULL)
+      {
+        for (i=0;i<b;i++)
+        {
+          tmpR.order[i]=rb->order[i];
+          tmpR.block0[i]=rb->block0[i];
+          tmpR.block1[i]=rb->block1[i];
+          if (rb->wvhdl[i]!=NULL)
+            WarnS("rSum: weights not implemented");
+        }
+        tmpR.block0[0]=1;
+      }
+      else /* ring sum for complete rings */
+      {
+        for (i=0;r1->order[i]!=0;i++)
+        {
+          tmpR.order[i]=r1->order[i];
+          tmpR.block0[i]=r1->block0[i];
+          tmpR.block1[i]=r1->block1[i];
+          if (r1->wvhdl[i]!=NULL)
+            tmpR.wvhdl[i] = (int*) omMemDup(r1->wvhdl[i]);
+        }
+        j=i;
+        i--;
+        if ((r1->order[i]==ringorder_c)
+            ||(r1->order[i]==ringorder_C))
+        {
+          j--;
+          tmpR.order[b-2]=r1->order[i];
+        }
+        for (i=0;r2->order[i]!=0;i++)
+        {
+          if ((r2->order[i]!=ringorder_c)
+              &&(r2->order[i]!=ringorder_C))
+          {
+            tmpR.order[j]=r2->order[i];
+            tmpR.block0[j]=r2->block0[i]+rVar(r1);
+            tmpR.block1[j]=r2->block1[i]+rVar(r1);
+            if (r2->wvhdl[i]!=NULL)
+            {
+              tmpR.wvhdl[j] = (int*) omMemDup(r2->wvhdl[i]);
+            }
+            j++;
+          }
+        }
+        if((r1->OrdSgn==-1)||(r2->OrdSgn==-1))
+          tmpR.OrdSgn=-1;
+      }
+    }
+    else if ((k==rVar(r1)) && (k==rVar(r2))) /* r1 and r2 are "quite"
+                                                the same ring */
+      /* copy r1, because we have the variables from r1 */
+    {
+      int b=rBlocks(r1);
+
+      tmpR.order=(int*)omAlloc0(b*sizeof(int));
+      tmpR.block0=(int*)omAlloc0(b*sizeof(int));
+      tmpR.block1=(int*)omAlloc0(b*sizeof(int));
+      tmpR.wvhdl=(int**)omAlloc0(b*sizeof(int *));
+      /* weights not implemented yet ...*/
+      for (i=0;i<b;i++)
+      {
+        tmpR.order[i]=r1->order[i];
+        tmpR.block0[i]=r1->block0[i];
+        tmpR.block1[i]=r1->block1[i];
+        if (r1->wvhdl[i]!=NULL)
+        {
+          tmpR.wvhdl[i] = (int*) omMemDup(r1->wvhdl[i]);
+        }
+      }
+      tmpR.OrdSgn=r1->OrdSgn;
+    }
+    else
+    {
+      for(i=0;i<k;i++) omFree((ADDRESS)tmpR.names[i]);
+      omFreeSize((ADDRESS)names,tmpR.N*sizeof(char *));
+      Werror("difficulties with variables: %d,%d -> %d",rVar(r1),rVar(r2),k);
+      return -1;
+    }
+  }
+  sum=(ring)omAllocBin(sip_sring_bin);
+  memcpy(sum,&tmpR,sizeof(ip_sring));
+  rComplete(sum);
+
+//#ifdef RDEBUG
+//  rDebugPrint(sum);
+//#endif
+
+
+
+#ifdef HAVE_PLURAL
+  if(1)
+  {
+//    ring old_ring = currRing;
+
+    BOOLEAN R1_is_nc = rIsPluralRing(r1);
+    BOOLEAN R2_is_nc = rIsPluralRing(r2);
+
+    if ( (R1_is_nc) || (R2_is_nc))
+    {
+      ring R1 = nc_rCreateNCcomm_rCopy(r1);
+      assume( rIsPluralRing(R1) );
+
+#if 0
+#ifdef RDEBUG
+      rWrite(R1);
+      rDebugPrint(R1);
+#endif
+#endif
+      ring R2 = nc_rCreateNCcomm_rCopy(r2);
+#if 0
+#ifdef RDEBUG
+      rWrite(R2);
+      rDebugPrint(R2);
+#endif
+#endif
+
+//      rChangeCurrRing(sum); // ?
+
+      // Projections from R_i into Sum:
+      /* multiplication matrices business: */
+      /* find permutations of vars and pars */
+      int *perm1 = (int *)omAlloc0((rVar(R1)+1)*sizeof(int));
+      int *par_perm1 = NULL;
+      if (rPar(R1)!=0) par_perm1=(int *)omAlloc0((rPar(R1)+1)*sizeof(int));
+
+      int *perm2 = (int *)omAlloc0((rVar(R2)+1)*sizeof(int));
+      int *par_perm2 = NULL;
+      if (rPar(R2)!=0) par_perm2=(int *)omAlloc0((rPar(R2)+1)*sizeof(int));
+
+      maFindPerm(R1->names,  rVar(R1),  rParameter(R1),  rPar(R1),
+                 sum->names, rVar(sum), rParameter(sum), rPar(sum),
+                 perm1, par_perm1, sum->cf->type);
+
+      maFindPerm(R2->names,  rVar(R2),  rParameter(R2),  rPar(R2),
+                 sum->names, rVar(sum), rParameter(sum), rPar(sum),
+                 perm2, par_perm2, sum->cf->type);
+
+
+      matrix C1 = R1->GetNC()->C, C2 = R2->GetNC()->C;
+      matrix D1 = R1->GetNC()->D, D2 = R2->GetNC()->D;
+
+      // !!!! BUG? C1 and C2 might live in different baserings!!!
+
+      int l = rVar(R1) + rVar(R2);
+
+      matrix C  = mpNew(l,l);
+      matrix D  = mpNew(l,l);
+
+      for (i = 1; i <= rVar(R1); i++)
+        for (j= rVar(R1)+1; j <= l; j++)
+          MATELEM(C,i,j) = p_One(sum); // in 'sum'
+
+      id_Test((ideal)C, sum);
+
+      nMapFunc nMap1 = n_SetMap(R1->cf,sum->cf); /* can change something global: not usable
+                                                    after the next nSetMap call :( */
+      // Create blocked C and D matrices:
+      for (i=1; i<= rVar(R1); i++)
+        for (j=i+1; j<=rVar(R1); j++)
+        {
+          assume(MATELEM(C1,i,j) != NULL);
+          MATELEM(C,i,j) = p_PermPoly(MATELEM(C1,i,j), perm1, R1, sum, nMap1, par_perm1, rPar(R1)); // need ADD + CMP ops.
+
+          if (MATELEM(D1,i,j) != NULL)
+            MATELEM(D,i,j) = p_PermPoly(MATELEM(D1,i,j), perm1, R1, sum, nMap1, par_perm1, rPar(R1));
+        }
+
+      id_Test((ideal)C, sum);
+      id_Test((ideal)D, sum);
+
+
+      nMapFunc nMap2 = n_SetMap(R2->cf,sum->cf); /* can change something global: not usable
+                                                    after the next nSetMap call :( */
+      for (i=1; i<= rVar(R2); i++)
+        for (j=i+1; j<=rVar(R2); j++)
+        {
+          assume(MATELEM(C2,i,j) != NULL);
+          MATELEM(C,rVar(R1)+i,rVar(R1)+j) = p_PermPoly(MATELEM(C2,i,j),perm2,R2,sum, nMap2,par_perm2,rPar(R2));
+
+          if (MATELEM(D2,i,j) != NULL)
+            MATELEM(D,rVar(R1)+i,rVar(R1)+j) = p_PermPoly(MATELEM(D2,i,j),perm2,R2,sum, nMap2,par_perm2,rPar(R2));
+        }
+
+      id_Test((ideal)C, sum);
+      id_Test((ideal)D, sum);
+
+      // Now sum is non-commutative with blocked structure constants!
+      if (nc_CallPlural(C, D, NULL, NULL, sum, false, false, true, sum))
+        WarnS("Error initializing non-commutative multiplication!");
+
+      /* delete R1, R2*/
+
+#if 0
+#ifdef RDEBUG
+      rWrite(sum);
+      rDebugPrint(sum);
+
+      Print("\nRefs: R1: %d, R2: %d\n", R1->GetNC()->ref, R2->GetNC()->ref);
+
+#endif
+#endif
+
+
+      rDelete(R1);
+      rDelete(R2);
+
+      /* delete perm arrays */
+      if (perm1!=NULL) omFree((ADDRESS)perm1);
+      if (perm2!=NULL) omFree((ADDRESS)perm2);
+      if (par_perm1!=NULL) omFree((ADDRESS)par_perm1);
+      if (par_perm2!=NULL) omFree((ADDRESS)par_perm2);
+
+//      rChangeCurrRing(old_ring);
+    }
+
+  }
+#endif
+
+  ideal Q=NULL;
+  ideal Q1=NULL, Q2=NULL;
+  if (r1->qideal!=NULL)
+  {
+//    rChangeCurrRing(sum);
+//     if (r2->qideal!=NULL)
+//     {
+//       WerrorS("todo: qring+qring");
+//       return -1;
+//     }
+//     else
+//     {}
+    /* these were defined in the Plural Part above... */
+    int *perm1 = (int *)omAlloc0((rVar(r1)+1)*sizeof(int));
+    int *par_perm1 = NULL;
+    if (rPar(r1)!=0) par_perm1=(int *)omAlloc0((rPar(r1)+1)*sizeof(int));
+    maFindPerm(r1->names,  rVar(r1),  rParameter(r1),  rPar(r1),
+               sum->names, rVar(sum), rParameter(sum), rPar(sum),
+               perm1, par_perm1, sum->cf->type);
+    nMapFunc nMap1 = n_SetMap(r1->cf,sum->cf);
+    Q1 = idInit(IDELEMS(r1->qideal),1);
+
+    for (int for_i=0;for_i<IDELEMS(r1->qideal);for_i++)
+      Q1->m[for_i] = p_PermPoly(
+                                r1->qideal->m[for_i], perm1,
+                                r1, sum,
+                                nMap1,
+                                par_perm1, rPar(r1));
+
+    omFree((ADDRESS)perm1);
+  }
+
+  if (r2->qideal!=NULL)
+  {
+    //if (currRing!=sum)
+    //  rChangeCurrRing(sum);
+    int *perm2 = (int *)omAlloc0((rVar(r2)+1)*sizeof(int));
+    int *par_perm2 = NULL;
+    if (rPar(r2)!=0) par_perm2=(int *)omAlloc0((rPar(r2)+1)*sizeof(int));
+    maFindPerm(r2->names,  rVar(r2),  rParameter(r2),  rPar(r2),
+               sum->names, rVar(sum), rParameter(sum), rPar(sum),
+               perm2, par_perm2, sum->cf->type);
+    nMapFunc nMap2 = n_SetMap(r2->cf,sum->cf);
+    Q2 = idInit(IDELEMS(r2->qideal),1);
+
+    for (int for_i=0;for_i<IDELEMS(r2->qideal);for_i++)
+      Q2->m[for_i] = p_PermPoly(
+                  r2->qideal->m[for_i], perm2,
+                  r2, sum,
+                  nMap2,
+                  par_perm2, rPar(r2));
+
+    omFree((ADDRESS)perm2);
+  }
+  if ( (Q1!=NULL) || ( Q2!=NULL))
+  {
+    Q = id_SimpleAdd(Q1,Q2,sum);
+  }
+  sum->qideal = Q;
+
+#ifdef HAVE_PLURAL
+  if( rIsPluralRing(sum) )
+    nc_SetupQuotient( sum );
+#endif
+  return 1;
+}
+
+/*2
+ *returns -1 for not compatible, (sum is undefined)
+ *         0 for equal, (and sum)
+ *         1 for compatible (and sum)
+ */
+int rSum(ring r1, ring r2, ring &sum)
+{
+  if (r1==r2)
+  {
+    sum=r1;
+    r1->ref++;
+    return 0;
+  }
+  return rSumInternal(r1,r2,sum,TRUE,FALSE);
+}
+
+/*2
+ * create a copy of the ring r
+ * used for qring definition,..
+ * DOES NOT CALL rComplete
+ */
+ring rCopy0(const ring r, BOOLEAN copy_qideal, BOOLEAN copy_ordering)
+{
+  if (r == NULL) return NULL;
+  int i,j;
+  ring res=(ring)omAllocBin(sip_sring_bin);
+  memset(res,0,sizeof(ip_sring));
+  //memcpy(res,r,sizeof(ip_sring));
+  //memset: res->idroot=NULL; /* local objects */
+  //ideal      minideal;
+  res->options=r->options; /* ring dependent options */
+
+  //memset: res->ordsgn=NULL;
+  //memset: res->typ=NULL;
+  //memset: res->VarOffset=NULL;
+  //memset: res->firstwv=NULL;
+
+  //struct omBin   PolyBin; /* Bin from where monoms are allocated */
+  //memset: res->PolyBin=NULL; // rComplete
+  res->cf=nCopyCoeff(r->cf);     /* coeffs */
+
+  //memset: res->ref=0; /* reference counter to the ring */
+
+  res->N=rVar(r);      /* number of vars */
+  res->OrdSgn=r->OrdSgn; /* 1 for polynomial rings, -1 otherwise */
+
+  res->firstBlockEnds=r->firstBlockEnds;
+#ifdef HAVE_PLURAL
+  res->real_var_start=r->real_var_start;
+  res->real_var_end=r->real_var_end;
+#endif
+
+#ifdef HAVE_SHIFTBBA
+  res->isLPring=r->isLPring; /* 0 for non-letterplace rings, otherwise the number of LP blocks, at least 1, known also as lV */
+#endif
+
+  res->VectorOut=r->VectorOut;
+  res->ShortOut=r->ShortOut;
+  res->CanShortOut=r->CanShortOut;
+  res->LexOrder=r->LexOrder; // TRUE if the monomial ordering has polynomial and power series blocks
+  res->MixedOrder=r->MixedOrder; // ?? 1 for lex ordering (except ls), -1 otherwise
+  res->ComponentOrder=r->ComponentOrder;
+
+  //memset: res->ExpL_Size=0;
+  //memset: res->CmpL_Size=0;
+  //memset: res->VarL_Size=0;
+  //memset: res->pCompIndex=0;
+  //memset: res->pOrdIndex=0;
+  //memset: res->OrdSize=0;
+  //memset: res->VarL_LowIndex=0;
+  //memset: res->MinExpPerLong=0;
+  //memset: res->NegWeightL_Size=0;
+  //memset: res->NegWeightL_Offset=NULL;
+  //memset: res->VarL_Offset=NULL;
+
+  // the following are set by rComplete unless predefined
+  // therefore, we copy these values: maybe they are non-standard
+  /* mask for getting single exponents */
+  res->bitmask=r->bitmask;
+  res->divmask=r->divmask;
+  res->BitsPerExp = r->BitsPerExp;
+  res->ExpPerLong =  r->ExpPerLong;
+
+  //memset: res->p_Procs=NULL;
+  //memset: res->pFDeg=NULL;
+  //memset: res->pLDeg=NULL;
+  //memset: res->pFDegOrig=NULL;
+  //memset: res->pLDegOrig=NULL;
+  //memset: res->p_Setm=NULL;
+  //memset: res->cf=NULL;
+
+/*
+  if (r->extRing!=NULL)
+    r->extRing->ref++;
+
+  res->extRing=r->extRing;
+  //memset: res->qideal=NULL;
+*/
+
+
+  if (copy_ordering == TRUE)
+  {
+    i=rBlocks(r);
+    res->wvhdl   = (int **)omAlloc(i * sizeof(int *));
+    res->order   = (int *) omAlloc(i * sizeof(int));
+    res->block0  = (int *) omAlloc(i * sizeof(int));
+    res->block1  = (int *) omAlloc(i * sizeof(int));
+    for (j=0; j<i; j++)
+    {
+      if (r->wvhdl[j]!=NULL)
+      {
+        res->wvhdl[j] = (int*) omMemDup(r->wvhdl[j]);
+      }
+      else
+        res->wvhdl[j]=NULL;
+    }
+    memcpy(res->order,r->order,i * sizeof(int));
+    memcpy(res->block0,r->block0,i * sizeof(int));
+    memcpy(res->block1,r->block1,i * sizeof(int));
+  }
+  //memset: else
+  //memset: {
+  //memset:   res->wvhdl = NULL;
+  //memset:   res->order = NULL;
+  //memset:   res->block0 = NULL;
+  //memset:   res->block1 = NULL;
+  //memset: }
+
+  res->names   = (char **)omAlloc0(rVar(r) * sizeof(char *));
+  for (i=0; i<rVar(res); i++)
+  {
+    res->names[i] = omStrDup(r->names[i]);
+  }
+  if (r->qideal!=NULL)
+  {
+    if (copy_qideal)
+    {
+      #ifndef SING_NDEBUG
+      if (!copy_ordering)
+        WerrorS("internal error: rCopy0(Q,TRUE,FALSE)");
+      else
+      #endif
+      {
+      #ifndef SING_NDEBUG
+        WarnS("internal bad stuff: rCopy0(Q,TRUE,TRUE)");
+      #endif
+        rComplete(res);
+        res->qideal= idrCopyR_NoSort(r->qideal, r, res);
+        rUnComplete(res);
+      }
+    }
+    //memset: else res->qideal = NULL;
+  }
+  //memset: else res->qideal = NULL;
+  //memset: res->GetNC() = NULL; // copy is purely commutative!!!
+  return res;
+}
+
+/*2
+ * create a copy of the ring r
+ * used for qring definition,..
+ * DOES NOT CALL rComplete
+ */
+ring rCopy0AndAddA(const ring r,  int64vec *wv64, BOOLEAN copy_qideal, BOOLEAN copy_ordering)
+{
+  if (r == NULL) return NULL;
+  int i,j;
+  ring res=(ring)omAllocBin(sip_sring_bin);
+  memset(res,0,sizeof(ip_sring));
+  //memcpy(res,r,sizeof(ip_sring));
+  //memset: res->idroot=NULL; /* local objects */
+  //ideal      minideal;
+  res->options=r->options; /* ring dependent options */
+
+  //memset: res->ordsgn=NULL;
+  //memset: res->typ=NULL;
+  //memset: res->VarOffset=NULL;
+  //memset: res->firstwv=NULL;
+
+  //struct omBin   PolyBin; /* Bin from where monoms are allocated */
+  //memset: res->PolyBin=NULL; // rComplete
+  res->cf=nCopyCoeff(r->cf);     /* coeffs */
+
+  //memset: res->ref=0; /* reference counter to the ring */
+
+  res->N=rVar(r);      /* number of vars */
+  res->OrdSgn=r->OrdSgn; /* 1 for polynomial rings, -1 otherwise */
+
+  res->firstBlockEnds=r->firstBlockEnds;
+#ifdef HAVE_PLURAL
+  res->real_var_start=r->real_var_start;
+  res->real_var_end=r->real_var_end;
+#endif
+
+#ifdef HAVE_SHIFTBBA
+  res->isLPring=r->isLPring; /* 0 for non-letterplace rings, otherwise the number of LP blocks, at least 1, known also as lV */
+#endif
+
+  res->VectorOut=r->VectorOut;
+  res->ShortOut=r->ShortOut;
+  res->CanShortOut=r->CanShortOut;
+  res->LexOrder=r->LexOrder; // TRUE if the monomial ordering has polynomial and power series blocks
+  res->MixedOrder=r->MixedOrder; // ?? 1 for lex ordering (except ls), -1 otherwise
+  res->ComponentOrder=r->ComponentOrder;
+
+  //memset: res->ExpL_Size=0;
+  //memset: res->CmpL_Size=0;
+  //memset: res->VarL_Size=0;
+  //memset: res->pCompIndex=0;
+  //memset: res->pOrdIndex=0;
+  //memset: res->OrdSize=0;
+  //memset: res->VarL_LowIndex=0;
+  //memset: res->MinExpPerLong=0;
+  //memset: res->NegWeightL_Size=0;
+  //memset: res->NegWeightL_Offset=NULL;
+  //memset: res->VarL_Offset=NULL;
+
+  // the following are set by rComplete unless predefined
+  // therefore, we copy these values: maybe they are non-standard
+  /* mask for getting single exponents */
+  res->bitmask=r->bitmask;
+  res->divmask=r->divmask;
+  res->BitsPerExp = r->BitsPerExp;
+  res->ExpPerLong =  r->ExpPerLong;
+
+  //memset: res->p_Procs=NULL;
+  //memset: res->pFDeg=NULL;
+  //memset: res->pLDeg=NULL;
+  //memset: res->pFDegOrig=NULL;
+  //memset: res->pLDegOrig=NULL;
+  //memset: res->p_Setm=NULL;
+  //memset: res->cf=NULL;
+
+/*
+  if (r->extRing!=NULL)
+    r->extRing->ref++;
+
+  res->extRing=r->extRing;
+  //memset: res->qideal=NULL;
+*/
+
+
+  if (copy_ordering == TRUE)
+  {
+    i=rBlocks(r)+1; // DIFF to rCopy0
+    res->wvhdl   = (int **)omAlloc(i * sizeof(int *));
+    res->order   = (int *) omAlloc(i * sizeof(int));
+    res->block0  = (int *) omAlloc(i * sizeof(int));
+    res->block1  = (int *) omAlloc(i * sizeof(int));
+    for (j=0; j<i-1; j++)
+    {
+      if (r->wvhdl[j]!=NULL)
+      {
+        res->wvhdl[j+1] = (int*) omMemDup(r->wvhdl[j]); //DIFF
+      }
+      else
+        res->wvhdl[j+1]=NULL; //DIFF
+    }
+    memcpy(&(res->order[1]),r->order,(i-1) * sizeof(int)); //DIFF
+    memcpy(&(res->block0[1]),r->block0,(i-1) * sizeof(int)); //DIFF
+    memcpy(&(res->block1[1]),r->block1,(i-1) * sizeof(int)); //DIFF
+  }
+  //memset: else
+  //memset: {
+  //memset:   res->wvhdl = NULL;
+  //memset:   res->order = NULL;
+  //memset:   res->block0 = NULL;
+  //memset:   res->block1 = NULL;
+  //memset: }
+
+  //the added A
+  res->order[0]=ringorder_a64;
+  int length=wv64->rows();
+  int64 *A=(int64 *)omAlloc(length*sizeof(int64));
+  for(j=length-1;j>=0;j--)
+  {
+     A[j]=(*wv64)[j];
+  }
+  res->wvhdl[0]=(int *)A;
+  res->block0[0]=1;
+  res->block1[0]=length;
+  //
+
+  res->names   = (char **)omAlloc0(rVar(r) * sizeof(char *));
+  for (i=0; i<rVar(res); i++)
+  {
+    res->names[i] = omStrDup(r->names[i]);
+  }
+  if (r->qideal!=NULL)
+  {
+    if (copy_qideal)
+    {
+      #ifndef SING_NDEBUG
+      if (!copy_ordering)
+        WerrorS("internal error: rCopy0(Q,TRUE,FALSE)");
+      else
+      #endif
+      {
+      #ifndef SING_NDEBUG
+        WarnS("internal bad stuff: rCopy0(Q,TRUE,TRUE)");
+      #endif
+        rComplete(res);
+        res->qideal= idrCopyR_NoSort(r->qideal, r, res);
+        rUnComplete(res);
+      }
+    }
+    //memset: else res->qideal = NULL;
+  }
+  //memset: else res->qideal = NULL;
+  //memset: res->GetNC() = NULL; // copy is purely commutative!!!
+  return res;
+}
+
+/*2
+ * create a copy of the ring r, which must be equivalent to currRing
+ * used for qring definition,..
+ * (i.e.: normal rings: same nCopy as currRing;
+ *        qring:        same nCopy, same idCopy as currRing)
+ */
+ring rCopy(ring r)
+{
+  if (r == NULL) return NULL;
+  ring res=rCopy0(r,FALSE,TRUE);
+  rComplete(res, 1); // res is purely commutative so far
+  if (r->qideal!=NULL) res->qideal=idrCopyR_NoSort(r->qideal, r, res);
+
+#ifdef HAVE_PLURAL
+  if (rIsPluralRing(r))
+    if( nc_rCopy(res, r, true) ) {}
+#endif
+
+  return res;
+}
+
+BOOLEAN rEqual(ring r1, ring r2, BOOLEAN qr)
+{
+  if (r1 == r2) return TRUE;
+  if (r1 == NULL || r2 == NULL) return FALSE;
+  if (r1->cf!=r2->cf) return FALSE;
+  if (rVar(r1)!=rVar(r2)) return FALSE;
+
+  if( !rSamePolyRep(r1, r2) )
+    return FALSE;
+
+  int i/*, j*/;
+
+  for (i=0; i<rVar(r1); i++)
+  {
+    if ((r1->names[i] != NULL) && (r2->names[i] != NULL))
+    {
+      if (strcmp(r1->names[i], r2->names[i])) return FALSE;
+    }
+    else if ((r1->names[i] != NULL) ^ (r2->names[i] != NULL))
+    {
+      return FALSE;
+    }
+  }
+
+  if (qr)
+  {
+    if (r1->qideal != NULL)
+    {
+      ideal id1 = r1->qideal, id2 = r2->qideal;
+      int i, n;
+      poly *m1, *m2;
+
+      if (id2 == NULL) return FALSE;
+      if ((n = IDELEMS(id1)) != IDELEMS(id2)) return FALSE;
+
+      {
+        m1 = id1->m;
+        m2 = id2->m;
+        for (i=0; i<n; i++)
+          if (! p_EqualPolys(m1[i],m2[i], r1, r2)) return FALSE;
+      }
+    }
+    else if (r2->qideal != NULL) return FALSE;
+  }
+
+  return TRUE;
+}
+
+BOOLEAN rSamePolyRep(ring r1, ring r2)
+{
+  int i, j;
+
+  if (r1 == r2) return TRUE;
+
+  if (r1 == NULL || r2 == NULL) return FALSE;
+
+  if ((r1->cf != r2->cf)
+  || (rVar(r1) != rVar(r2))
+  || (r1->OrdSgn != r2->OrdSgn))
+    return FALSE;
+
+  i=0;
+  while (r1->order[i] != 0)
+  {
+    if (r2->order[i] == 0) return FALSE;
+    if ((r1->order[i] != r2->order[i])
+    || (r1->block0[i] != r2->block0[i])
+    || (r1->block1[i] != r2->block1[i]))
+      return FALSE;
+    if (r1->wvhdl[i] != NULL)
+    {
+      if (r2->wvhdl[i] == NULL)
+        return FALSE;
+      for (j=0; j<r1->block1[i]-r1->block0[i]+1; j++)
+        if (r2->wvhdl[i][j] != r1->wvhdl[i][j])
+          return FALSE;
+    }
+    else if (r2->wvhdl[i] != NULL) return FALSE;
+    i++;
+  }
+  if (r2->order[i] != 0) return FALSE;
+
+  // we do not check variable names
+  // we do not check minpoly/minideal
+  // we do not check qideal
+
+  return TRUE;
+}
+
+rOrderType_t rGetOrderType(ring r)
+{
+  // check for simple ordering
+  if (rHasSimpleOrder(r))
+  {
+    if ((r->order[1] == ringorder_c)
+    || (r->order[1] == ringorder_C))
+    {
+      switch(r->order[0])
+      {
+          case ringorder_dp:
+          case ringorder_wp:
+          case ringorder_ds:
+          case ringorder_ws:
+          case ringorder_ls:
+          case ringorder_unspec:
+            if (r->order[1] == ringorder_C
+            ||  r->order[0] == ringorder_unspec)
+              return rOrderType_ExpComp;
+            return rOrderType_Exp;
+
+          default:
+            assume(r->order[0] == ringorder_lp ||
+                   r->order[0] == ringorder_rs ||
+                   r->order[0] == ringorder_Dp ||
+                   r->order[0] == ringorder_Wp ||
+                   r->order[0] == ringorder_Ds ||
+                   r->order[0] == ringorder_Ws);
+
+            if (r->order[1] == ringorder_c) return rOrderType_ExpComp;
+            return rOrderType_Exp;
+      }
+    }
+    else
+    {
+      assume((r->order[0]==ringorder_c)||(r->order[0]==ringorder_C));
+      return rOrderType_CompExp;
+    }
+  }
+  else
+    return rOrderType_General;
+}
+
+BOOLEAN rHas_c_Ordering(const ring r)
+{
+  return (r->order[0] == ringorder_c);
+}
+BOOLEAN rHasSimpleOrder(const ring r)
+{
+  if (r->order[0] == ringorder_unspec) return TRUE;
+  int blocks = rBlocks(r) - 1;
+  assume(blocks >= 1);
+  if (blocks == 1) return TRUE;
+
+  int s = 0;
+  while( (s < blocks) && (r->order[s] == ringorder_IS) && (r->order[blocks-1] == ringorder_IS) )
+  {
+    s++;
+    blocks--;
+  }
+
+  if ((blocks - s) > 2)  return FALSE;
+
+  assume( blocks == s + 2 );
+
+  if (
+     (r->order[s] != ringorder_c)
+  && (r->order[s] != ringorder_C)
+  && (r->order[s+1] != ringorder_c)
+  && (r->order[s+1] != ringorder_C)
+     )
+    return FALSE;
+  if ((r->order[s+1] == ringorder_M)
+  || (r->order[s] == ringorder_M))
+    return FALSE;
+  return TRUE;
+}
+
+// returns TRUE, if simple lp or ls ordering
+BOOLEAN rHasSimpleLexOrder(const ring r)
+{
+  return rHasSimpleOrder(r) &&
+    (r->order[0] == ringorder_ls ||
+     r->order[0] == ringorder_lp ||
+     r->order[1] == ringorder_ls ||
+     r->order[1] == ringorder_lp);
+}
+
+BOOLEAN rOrder_is_DegOrdering(const rRingOrder_t order)
+{
+  switch(order)
+  {
+      case ringorder_dp:
+      case ringorder_Dp:
+      case ringorder_ds:
+      case ringorder_Ds:
+      case ringorder_Ws:
+      case ringorder_Wp:
+      case ringorder_ws:
+      case ringorder_wp:
+        return TRUE;
+
+      default:
+        return FALSE;
+  }
+}
+
+BOOLEAN rOrder_is_WeightedOrdering(rRingOrder_t order)
+{
+  switch(order)
+  {
+      case ringorder_Ws:
+      case ringorder_Wp:
+      case ringorder_ws:
+      case ringorder_wp:
+        return TRUE;
+
+      default:
+        return FALSE;
+  }
+}
+
+BOOLEAN rHasSimpleOrderAA(ring r)
+{
+  if (r->order[0] == ringorder_unspec) return TRUE;
+  int blocks = rBlocks(r) - 1;
+  assume(blocks >= 1);
+  if (blocks == 1) return TRUE;
+
+  int s = 0;
+  while( (s < blocks) && (r->order[s] == ringorder_IS) && (r->order[blocks-1] == ringorder_IS) )
+  {
+    s++;
+    blocks--;
+  }
+
+  if ((blocks - s) > 3)  return FALSE;
+
+//  if ((blocks > 3) || (blocks < 2)) return FALSE;
+  if ((blocks - s) == 3)
+  {
+    return (((r->order[s] == ringorder_aa) && (r->order[s+1] != ringorder_M) &&
+             ((r->order[s+2] == ringorder_c) || (r->order[s+2] == ringorder_C))) ||
+            (((r->order[s] == ringorder_c) || (r->order[s] == ringorder_C)) &&
+             (r->order[s+1] == ringorder_aa) && (r->order[s+2] != ringorder_M)));
+  }
+  else
+  {
+    return ((r->order[s] == ringorder_aa) && (r->order[s+1] != ringorder_M));
+  }
+}
+
+// return TRUE if p_SetComp requires p_Setm
+BOOLEAN rOrd_SetCompRequiresSetm(ring r)
+{
+  if (r->typ != NULL)
+  {
+    int pos;
+    for (pos=0;pos<r->OrdSize;pos++)
+    {
+      sro_ord* o=&(r->typ[pos]);
+      if (   (o->ord_typ == ro_syzcomp)
+          || (o->ord_typ == ro_syz)
+          || (o->ord_typ == ro_is)
+          || (o->ord_typ == ro_am)
+          || (o->ord_typ == ro_isTemp))
+        return TRUE;
+    }
+  }
+  return FALSE;
+}
+
+// return TRUE if p->exp[r->pOrdIndex] holds total degree of p */
+BOOLEAN rOrd_is_Totaldegree_Ordering(ring r)
+{
+  // Hmm.... what about Syz orderings?
+  return (rVar(r) > 1 &&
+          ((rHasSimpleOrder(r) &&
+           (rOrder_is_DegOrdering((rRingOrder_t)r->order[0]) ||
+            rOrder_is_DegOrdering(( rRingOrder_t)r->order[1]))) ||
+           (rHasSimpleOrderAA(r) &&
+            (rOrder_is_DegOrdering((rRingOrder_t)r->order[1]) ||
+             rOrder_is_DegOrdering((rRingOrder_t)r->order[2])))));
+}
+
+// return TRUE if p->exp[r->pOrdIndex] holds a weighted degree of p */
+BOOLEAN rOrd_is_WeightedDegree_Ordering(ring r )
+{
+  // Hmm.... what about Syz orderings?
+  return ((rVar(r) > 1) &&
+          rHasSimpleOrder(r) &&
+          (rOrder_is_WeightedOrdering((rRingOrder_t)r->order[0]) ||
+           rOrder_is_WeightedOrdering(( rRingOrder_t)r->order[1])));
+}
+
+BOOLEAN rIsPolyVar(int v, ring r)
+{
+  int  i=0;
+  while(r->order[i]!=0)
+  {
+    if((r->block0[i]<=v)
+    && (r->block1[i]>=v))
+    {
+      switch(r->order[i])
+      {
+        case ringorder_a:
+          return (r->wvhdl[i][v-r->block0[i]]>0);
+        case ringorder_M:
+          return 2; /*don't know*/
+        case ringorder_a64: /* assume: all weight are non-negative!*/
+        case ringorder_lp:
+        case ringorder_rs:
+        case ringorder_dp:
+        case ringorder_Dp:
+        case ringorder_wp:
+        case ringorder_Wp:
+          return TRUE;
+        case ringorder_ls:
+        case ringorder_ds:
+        case ringorder_Ds:
+        case ringorder_ws:
+        case ringorder_Ws:
+          return FALSE;
+        default:
+          break;
+      }
+    }
+    i++;
+  }
+  return 3; /* could not find var v*/
+}
+
+#ifdef RDEBUG
+// This should eventually become a full-fledge ring check, like pTest
+BOOLEAN rDBTest(ring r, const char* fn, const int l)
+{
+  int i,j;
+
+  if (r == NULL)
+  {
+    dReportError("Null ring in %s:%d", fn, l);
+    return FALSE;
+  }
+
+
+  if (r->N == 0) return TRUE;
+
+//  omCheckAddrSize(r,sizeof(ip_sring));
+#if OM_CHECK > 0
+  i=rBlocks(r);
+  omCheckAddrSize(r->order,i*sizeof(int));
+  omCheckAddrSize(r->block0,i*sizeof(int));
+  omCheckAddrSize(r->block1,i*sizeof(int));
+  if (r->wvhdl!=NULL)
+  {
+    omCheckAddrSize(r->wvhdl,i*sizeof(int *));
+    for (j=0;j<i; j++)
+    {
+      if (r->wvhdl[j] != NULL) omCheckAddr(r->wvhdl[j]);
+    }
+  }
+#endif
+  if (r->VarOffset == NULL)
+  {
+    dReportError("Null ring VarOffset -- no rComplete (?) in n %s:%d", fn, l);
+    return FALSE;
+  }
+  omCheckAddrSize(r->VarOffset,(r->N+1)*sizeof(int));
+
+  if ((r->OrdSize==0)!=(r->typ==NULL))
+  {
+    dReportError("mismatch OrdSize and typ-pointer in %s:%d");
+    return FALSE;
+  }
+  omcheckAddrSize(r->typ,r->OrdSize*sizeof(*(r->typ)));
+  omCheckAddrSize(r->VarOffset,(r->N+1)*sizeof(*(r->VarOffset)));
+  // test assumptions:
+  for(i=0;i<=r->N;i++) // for all variables (i = 0..N)
+  {
+    if(r->typ!=NULL)
+    {
+      for(j=0;j<r->OrdSize;j++) // for all ordering blocks (j =0..OrdSize-1)
+      {
+        if(r->typ[j].ord_typ == ro_isTemp)
+        {
+          const int p = r->typ[j].data.isTemp.suffixpos;
+
+          if(p <= j)
+            dReportError("ordrec prefix %d is unmatched",j);
+
+          assume( p < r->OrdSize );
+
+          if(r->typ[p].ord_typ != ro_is)
+            dReportError("ordrec prefix %d is unmatched (suffix: %d is wrong!!!)",j, p);
+
+          // Skip all intermediate blocks for undone variables:
+          if(r->typ[j].data.isTemp.pVarOffset[i] != -1) // Check i^th variable
+          {
+            j = p - 1; // SKIP ALL INTERNAL BLOCKS...???
+            continue; // To make for check OrdSize bound...
+          }
+        }
+        else if (r->typ[j].ord_typ == ro_is)
+        {
+          // Skip all intermediate blocks for undone variables:
+          if(r->typ[j].data.is.pVarOffset[i] != -1)
+          {
+            // TODO???
+          }
+
+        }
+        else
+        {
+          if (r->typ[j].ord_typ==ro_cp)
+          {
+            if(((short)r->VarOffset[i]) == r->typ[j].data.cp.place)
+              dReportError("ordrec %d conflicts with var %d",j,i);
+          }
+          else
+            if ((r->typ[j].ord_typ!=ro_syzcomp)
+            && (r->VarOffset[i] == r->typ[j].data.dp.place))
+              dReportError("ordrec %d conflicts with var %d",j,i);
+        }
+      }
+    }
+    int tmp;
+      tmp=r->VarOffset[i] & 0xffffff;
+      #if SIZEOF_LONG == 8
+        if ((r->VarOffset[i] >> 24) >63)
+      #else
+        if ((r->VarOffset[i] >> 24) >31)
+      #endif
+          dReportError("bit_start out of range:%d",r->VarOffset[i] >> 24);
+      if (i > 0 && ((tmp<0) ||(tmp>r->ExpL_Size-1)))
+      {
+        dReportError("varoffset out of range for var %d: %d",i,tmp);
+      }
+  }
+  if(r->typ!=NULL)
+  {
+    for(j=0;j<r->OrdSize;j++)
+    {
+      if ((r->typ[j].ord_typ==ro_dp)
+      || (r->typ[j].ord_typ==ro_wp)
+      || (r->typ[j].ord_typ==ro_wp_neg))
+      {
+        if (r->typ[j].data.dp.start > r->typ[j].data.dp.end)
+          dReportError("in ordrec %d: start(%d) > end(%d)",j,
+            r->typ[j].data.dp.start, r->typ[j].data.dp.end);
+        if ((r->typ[j].data.dp.start < 1)
+        || (r->typ[j].data.dp.end > r->N))
+          dReportError("in ordrec %d: start(%d)<1 or end(%d)>vars(%d)",j,
+            r->typ[j].data.dp.start, r->typ[j].data.dp.end,r->N);
+      }
+    }
+  }
+
+  assume(r != NULL);
+  assume(r->cf != NULL);
+
+  if (nCoeff_is_algExt(r->cf))
+  {
+    assume(r->cf->extRing != NULL);
+    assume(r->cf->extRing->qideal != NULL);
+    omCheckAddr(r->cf->extRing->qideal->m[0]);
+  }
+
+  //assume(r->cf!=NULL);
+
+  return TRUE;
+}
+#endif
+
+static void rO_Align(int &place, int &bitplace)
+{
+  // increment place to the next aligned one
+  // (count as Exponent_t,align as longs)
+  if (bitplace!=BITS_PER_LONG)
+  {
+    place++;
+    bitplace=BITS_PER_LONG;
+  }
+}
+
+static void rO_TDegree(int &place, int &bitplace, int start, int end,
+    long *o, sro_ord &ord_struct)
+{
+  // degree (aligned) of variables v_start..v_end, ordsgn 1
+  rO_Align(place,bitplace);
+  ord_struct.ord_typ=ro_dp;
+  ord_struct.data.dp.start=start;
+  ord_struct.data.dp.end=end;
+  ord_struct.data.dp.place=place;
+  o[place]=1;
+  place++;
+  rO_Align(place,bitplace);
+}
+
+static void rO_TDegree_neg(int &place, int &bitplace, int start, int end,
+    long *o, sro_ord &ord_struct)
+{
+  // degree (aligned) of variables v_start..v_end, ordsgn -1
+  rO_Align(place,bitplace);
+  ord_struct.ord_typ=ro_dp;
+  ord_struct.data.dp.start=start;
+  ord_struct.data.dp.end=end;
+  ord_struct.data.dp.place=place;
+  o[place]=-1;
+  place++;
+  rO_Align(place,bitplace);
+}
+
+static void rO_WDegree(int &place, int &bitplace, int start, int end,
+    long *o, sro_ord &ord_struct, int *weights)
+{
+  // weighted degree (aligned) of variables v_start..v_end, ordsgn 1
+  while((start<end) && (weights[0]==0)) { start++; weights++; }
+  while((start<end) && (weights[end-start]==0)) { end--; }
+  int i;
+  int pure_tdeg=1;
+  for(i=start;i<=end;i++)
+  {
+    if(weights[i-start]!=1)
+    {
+      pure_tdeg=0;
+      break;
+    }
+  }
+  if (pure_tdeg)
+  {
+    rO_TDegree(place,bitplace,start,end,o,ord_struct);
+    return;
+  }
+  rO_Align(place,bitplace);
+  ord_struct.ord_typ=ro_wp;
+  ord_struct.data.wp.start=start;
+  ord_struct.data.wp.end=end;
+  ord_struct.data.wp.place=place;
+  ord_struct.data.wp.weights=weights;
+  o[place]=1;
+  place++;
+  rO_Align(place,bitplace);
+  for(i=start;i<=end;i++)
+  {
+    if(weights[i-start]<0)
+    {
+      ord_struct.ord_typ=ro_wp_neg;
+      break;
+    }
+  }
+}
+
+static void rO_WMDegree(int &place, int &bitplace, int start, int end,
+    long *o, sro_ord &ord_struct, int *weights)
+{
+  assume(weights != NULL);
+
+  // weighted degree (aligned) of variables v_start..v_end, ordsgn 1
+//  while((start<end) && (weights[0]==0)) { start++; weights++; }
+//  while((start<end) && (weights[end-start]==0)) { end--; }
+  rO_Align(place,bitplace);
+  ord_struct.ord_typ=ro_am;
+  ord_struct.data.am.start=start;
+  ord_struct.data.am.end=end;
+  ord_struct.data.am.place=place;
+  ord_struct.data.am.weights=weights;
+  ord_struct.data.am.weights_m = weights + (end-start+1);
+  ord_struct.data.am.len_gen=weights[end-start+1];
+  assume( ord_struct.data.am.weights_m[0] == ord_struct.data.am.len_gen );
+  o[place]=1;
+  place++;
+  rO_Align(place,bitplace);
+}
+
+static void rO_WDegree64(int &place, int &bitplace, int start, int end,
+    long *o, sro_ord &ord_struct, int64 *weights)
+{
+  // weighted degree (aligned) of variables v_start..v_end, ordsgn 1,
+  // reserved 2 places
+  rO_Align(place,bitplace);
+  ord_struct.ord_typ=ro_wp64;
+  ord_struct.data.wp64.start=start;
+  ord_struct.data.wp64.end=end;
+  ord_struct.data.wp64.place=place;
+  ord_struct.data.wp64.weights64=weights;
+  o[place]=1;
+  place++;
+  o[place]=1;
+  place++;
+  rO_Align(place,bitplace);
+}
+
+static void rO_WDegree_neg(int &place, int &bitplace, int start, int end,
+    long *o, sro_ord &ord_struct, int *weights)
+{
+  // weighted degree (aligned) of variables v_start..v_end, ordsgn -1
+  while((start<end) && (weights[0]==0)) { start++; weights++; }
+  while((start<end) && (weights[end-start]==0)) { end--; }
+  rO_Align(place,bitplace);
+  ord_struct.ord_typ=ro_wp;
+  ord_struct.data.wp.start=start;
+  ord_struct.data.wp.end=end;
+  ord_struct.data.wp.place=place;
+  ord_struct.data.wp.weights=weights;
+  o[place]=-1;
+  place++;
+  rO_Align(place,bitplace);
+  int i;
+  for(i=start;i<=end;i++)
+  {
+    if(weights[i-start]<0)
+    {
+      ord_struct.ord_typ=ro_wp_neg;
+      break;
+    }
+  }
+}
+
+static void rO_LexVars(int &place, int &bitplace, int start, int end,
+  int &prev_ord, long *o,int *v, int bits, int opt_var)
+{
+  // a block of variables v_start..v_end with lex order, ordsgn 1
+  int k;
+  int incr=1;
+  if(prev_ord==-1) rO_Align(place,bitplace);
+
+  if (start>end)
+  {
+    incr=-1;
+  }
+  for(k=start;;k+=incr)
+  {
+    bitplace-=bits;
+    if (bitplace < 0) { bitplace=BITS_PER_LONG-bits; place++; }
+    o[place]=1;
+    v[k]= place | (bitplace << 24);
+    if (k==end) break;
+  }
+  prev_ord=1;
+  if (opt_var!= -1)
+  {
+    assume((opt_var == end+1) ||(opt_var == end-1));
+    if((opt_var != end+1) &&(opt_var != end-1)) WarnS("hier-2");
+    int save_bitplace=bitplace;
+    bitplace-=bits;
+    if (bitplace < 0)
+    {
+      bitplace=save_bitplace;
+      return;
+    }
+    // there is enough space for the optional var
+    v[opt_var]=place | (bitplace << 24);
+  }
+}
+
+static void rO_LexVars_neg(int &place, int &bitplace, int start, int end,
+  int &prev_ord, long *o,int *v, int bits, int opt_var)
+{
+  // a block of variables v_start..v_end with lex order, ordsgn -1
+  int k;
+  int incr=1;
+  if(prev_ord==1) rO_Align(place,bitplace);
+
+  if (start>end)
+  {
+    incr=-1;
+  }
+  for(k=start;;k+=incr)
+  {
+    bitplace-=bits;
+    if (bitplace < 0) { bitplace=BITS_PER_LONG-bits; place++; }
+    o[place]=-1;
+    v[k]=place | (bitplace << 24);
+    if (k==end) break;
+  }
+  prev_ord=-1;
+//  #if 0
+  if (opt_var!= -1)
+  {
+    assume((opt_var == end+1) ||(opt_var == end-1));
+    if((opt_var != end+1) &&(opt_var != end-1)) WarnS("hier-1");
+    int save_bitplace=bitplace;
+    bitplace-=bits;
+    if (bitplace < 0)
+    {
+      bitplace=save_bitplace;
+      return;
+    }
+    // there is enough space for the optional var
+    v[opt_var]=place | (bitplace << 24);
+  }
+//  #endif
+}
+
+static void rO_Syzcomp(int &place, int &bitplace, int &prev_ord,
+    long *o, sro_ord &ord_struct)
+{
+  // ordering is derived from component number
+  rO_Align(place,bitplace);
+  ord_struct.ord_typ=ro_syzcomp;
+  ord_struct.data.syzcomp.place=place;
+  ord_struct.data.syzcomp.Components=NULL;
+  ord_struct.data.syzcomp.ShiftedComponents=NULL;
+  o[place]=1;
+  prev_ord=1;
+  place++;
+  rO_Align(place,bitplace);
+}
+
+static void rO_Syz(int &place, int &bitplace, int &prev_ord,
+    long *o, sro_ord &ord_struct)
+{
+  // ordering is derived from component number
+  // let's reserve one Exponent_t for it
+  if ((prev_ord== 1) || (bitplace!=BITS_PER_LONG))
+    rO_Align(place,bitplace);
+  ord_struct.ord_typ=ro_syz;
+  ord_struct.data.syz.place=place;
+  ord_struct.data.syz.limit=0;
+  ord_struct.data.syz.syz_index = NULL;
+  ord_struct.data.syz.curr_index = 1;
+  o[place]= -1;
+  prev_ord=-1;
+  place++;
+}
+
+#ifndef SING_NDEBUG
+# define MYTEST 0
+#else /* ifndef SING_NDEBUG */
+# define MYTEST 0
+#endif /* ifndef SING_NDEBUG */
+
+static void rO_ISPrefix(int &place, int &bitplace, int &prev_ord,
+    long *o, int /*N*/, int *v, sro_ord &ord_struct)
+{
+  if ((prev_ord== 1) || (bitplace!=BITS_PER_LONG))
+    rO_Align(place,bitplace);
+  // since we add something afterwards - it's better to start with anew!?
+
+  ord_struct.ord_typ = ro_isTemp;
+  ord_struct.data.isTemp.start = place;
+  ord_struct.data.isTemp.pVarOffset = (int *)omMemDup(v);
+  ord_struct.data.isTemp.suffixpos = -1;
+
+  // We will act as rO_Syz on our own!!!
+  // Here we allocate an exponent as a level placeholder
+  o[place]= -1;
+  prev_ord=-1;
+  place++;
+}
+static void rO_ISSuffix(int &place, int &bitplace, int &prev_ord, long *o,
+  int N, int *v, sro_ord *tmp_typ, int &typ_i, int sgn)
+{
+
+  // Let's find previous prefix:
+  int typ_j = typ_i - 1;
+  while(typ_j >= 0)
+  {
+    if( tmp_typ[typ_j].ord_typ == ro_isTemp)
+      break;
+    typ_j --;
+  }
+
+  assume( typ_j >= 0 );
+
+  if( typ_j < 0 ) // Found NO prefix!!! :(
+    return;
+
+  assume( tmp_typ[typ_j].ord_typ == ro_isTemp );
+
+  // Get saved state:
+  const int start = tmp_typ[typ_j].data.isTemp.start;
+  int *pVarOffset = tmp_typ[typ_j].data.isTemp.pVarOffset;
+
+/*
+  // shift up all blocks
+  while(typ_j < (typ_i-1))
+  {
+    tmp_typ[typ_j] = tmp_typ[typ_j+1];
+    typ_j++;
+  }
+  typ_j = typ_i - 1; // No increment for typ_i
+*/
+  tmp_typ[typ_j].data.isTemp.suffixpos = typ_i;
+
+  // Let's keep that dummy for now...
+  typ_j = typ_i; // the typ to change!
+  typ_i++; // Just for now...
+
+
+  for( int i = 0; i <= N; i++ ) // Note [0] == component !!! No Skip?
+  {
+    // Was i-th variable allocated inbetween?
+    if( v[i] != pVarOffset[i] )
+    {
+      pVarOffset[i] = v[i]; // Save for later...
+      v[i] = -1; // Undo!
+      assume( pVarOffset[i] != -1 );
+    }
+    else
+      pVarOffset[i] = -1; // No change here...
+  }
+
+  if( pVarOffset[0] != -1 )
+    pVarOffset[0] &= 0x0fff;
+
+  sro_ord &ord_struct = tmp_typ[typ_j];
+
+
+  ord_struct.ord_typ = ro_is;
+  ord_struct.data.is.start = start;
+  ord_struct.data.is.end   = place;
+  ord_struct.data.is.pVarOffset = pVarOffset;
+
+
+  // What about component???
+//   if( v[0] != -1 ) // There is a component already...???
+//     if( o[ v[0] & 0x0fff ] == sgn )
+//     {
+//       pVarOffset[0] = -1; // NEVER USED Afterwards...
+//       return;
+//     }
+
+
+  // Moreover: we need to allocate the module component (v[0]) here!
+  if( v[0] == -1) // It's possible that there was module component v0 at the begining (before prefix)!
+  {
+    // Start with a whole long exponent
+    if( bitplace != BITS_PER_LONG )
+      rO_Align(place, bitplace);
+
+    assume( bitplace == BITS_PER_LONG );
+    bitplace -= BITS_PER_LONG;
+    assume(bitplace == 0);
+    v[0] = place | (bitplace << 24); // Never mind whether pVarOffset[0] > 0!!!
+    o[place] = sgn; // Singnum for component ordering
+    prev_ord = sgn;
+  }
+}
+
+
+static unsigned long rGetExpSize(unsigned long bitmask, int & bits)
+{
+  if (bitmask == 0)
+  {
+    bits=16; bitmask=0xffff;
+  }
+  else if (bitmask <= 1L)
+  {
+    bits=1; bitmask = 1L;
+  }
+  else if (bitmask <= 3L)
+  {
+    bits=2; bitmask = 3L;
+  }
+  else if (bitmask <= 7L)
+  {
+    bits=3; bitmask=7L;
+  }
+  else if (bitmask <= 0xfL)
+  {
+    bits=4; bitmask=0xfL;
+  }
+  else if (bitmask <= 0x1fL)
+  {
+    bits=5; bitmask=0x1fL;
+  }
+  else if (bitmask <= 0x3fL)
+  {
+    bits=6; bitmask=0x3fL;
+  }
+#if SIZEOF_LONG == 8
+  else if (bitmask <= 0x7fL)
+  {
+    bits=7; bitmask=0x7fL; /* 64 bit longs only */
+  }
+#endif
+  else if (bitmask <= 0xffL)
+  {
+    bits=8; bitmask=0xffL;
+  }
+#if SIZEOF_LONG == 8
+  else if (bitmask <= 0x1ffL)
+  {
+    bits=9; bitmask=0x1ffL; /* 64 bit longs only */
+  }
+#endif
+  else if (bitmask <= 0x3ffL)
+  {
+    bits=10; bitmask=0x3ffL;
+  }
+#if SIZEOF_LONG == 8
+  else if (bitmask <= 0xfffL)
+  {
+    bits=12; bitmask=0xfff; /* 64 bit longs only */
+  }
+#endif
+  else if (bitmask <= 0xffffL)
+  {
+    bits=16; bitmask=0xffffL;
+  }
+#if SIZEOF_LONG == 8
+  else if (bitmask <= 0xfffffL)
+  {
+    bits=20; bitmask=0xfffffL; /* 64 bit longs only */
+  }
+  else if (bitmask <= 0xffffffffL)
+  {
+    bits=32; bitmask=0xffffffffL;
+  }
+  else if (bitmask <= 0x7fffffffffffffffL)
+  {
+    bits=63; bitmask=0x7fffffffffffffffL; /* for overflow tests*/
+  }
+  else
+  {
+    bits=63; bitmask=0x7fffffffffffffffL; /* for overflow tests*/
+  }
+#else
+  else if (bitmask <= 0x7fffffff)
+  {
+    bits=31; bitmask=0x7fffffff; /* for overflow tests*/
+  }
+  else
+  {
+    bits=31; bitmask=0x7fffffffL; /* for overflow tests*/
+  }
+#endif
+  return bitmask;
+}
+
+/*2
+* optimize rGetExpSize for a block of N variables, exp <=bitmask
+*/
+static unsigned long rGetExpSize(unsigned long bitmask, int & bits, int N)
+{
+  bitmask =rGetExpSize(bitmask, bits);
+  int vars_per_long=BIT_SIZEOF_LONG/bits;
+  int bits1;
+  loop
+  {
+    if (bits == BIT_SIZEOF_LONG-1)
+    {
+      bits =  BIT_SIZEOF_LONG - 1;
+      return LONG_MAX;
+    }
+    unsigned long bitmask1 =rGetExpSize(bitmask+1, bits1);
+    int vars_per_long1=BIT_SIZEOF_LONG/bits1;
+    if ((((N+vars_per_long-1)/vars_per_long) ==
+         ((N+vars_per_long1-1)/vars_per_long1)))
+    {
+      vars_per_long=vars_per_long1;
+      bits=bits1;
+      bitmask=bitmask1;
+    }
+    else
+    {
+      return bitmask; /* and bits */
+    }
+  }
+}
+
+
+/*2
+ * create a copy of the ring r, which must be equivalent to currRing
+ * used for std computations
+ * may share data structures with currRing
+ * DOES CALL rComplete
+ */
+ring rModifyRing(ring r, BOOLEAN omit_degree,
+                         BOOLEAN try_omit_comp,
+                         unsigned long exp_limit)
+{
+  assume (r != NULL );
+  assume (exp_limit > 1);
+  BOOLEAN need_other_ring;
+  BOOLEAN omitted_degree = FALSE;
+
+  int iNeedInducedOrderingSetup = 0; ///< How many induced ordering block do we have?
+  int bits;
+
+  exp_limit=rGetExpSize(exp_limit, bits, r->N);
+  need_other_ring = (exp_limit != r->bitmask);
+
+  int nblocks=rBlocks(r);
+  int *order=(int*)omAlloc0((nblocks+1)*sizeof(int));
+  int *block0=(int*)omAlloc0((nblocks+1)*sizeof(int));
+  int *block1=(int*)omAlloc0((nblocks+1)*sizeof(int));
+  int **wvhdl=(int**)omAlloc0((nblocks+1)*sizeof(int *));
+
+  int i=0;
+  int j=0; /*  i index in r, j index in res */
+
+  for( int r_ord=r->order[i]; (r_ord != 0) && (i < nblocks); j++, r_ord=r->order[++i])
+  {
+    BOOLEAN copy_block_index=TRUE;
+
+    if (r->block0[i]==r->block1[i])
+    {
+      switch(r_ord)
+      {
+        case ringorder_wp:
+        case ringorder_dp:
+        case ringorder_Wp:
+        case ringorder_Dp:
+          r_ord=ringorder_lp;
+          break;
+        case ringorder_Ws:
+        case ringorder_Ds:
+        case ringorder_ws:
+        case ringorder_ds:
+          r_ord=ringorder_ls;
+          break;
+        default:
+          break;
+      }
+    }
+    switch(r_ord)
+    {
+      case ringorder_S:
+      {
+#ifndef SING_NDEBUG
+        Warn("Error: unhandled ordering in rModifyRing: ringorder_S = [%d]", r_ord);
+#endif
+        order[j]=r_ord; /*r->order[i];*/
+        break;
+      }
+      case ringorder_C:
+      case ringorder_c:
+        if (!try_omit_comp)
+        {
+          order[j]=r_ord; /*r->order[i]*/;
+        }
+        else
+        {
+          j--;
+          need_other_ring=TRUE;
+          try_omit_comp=FALSE;
+          copy_block_index=FALSE;
+        }
+        break;
+      case ringorder_wp:
+      case ringorder_dp:
+      case ringorder_ws:
+      case ringorder_ds:
+        if(!omit_degree)
+        {
+          order[j]=r_ord; /*r->order[i]*/;
+        }
+        else
+        {
+          order[j]=ringorder_rs;
+          need_other_ring=TRUE;
+          omit_degree=FALSE;
+          omitted_degree = TRUE;
+        }
+        break;
+      case ringorder_Wp:
+      case ringorder_Dp:
+      case ringorder_Ws:
+      case ringorder_Ds:
+        if(!omit_degree)
+        {
+          order[j]=r_ord; /*r->order[i];*/
+        }
+        else
+        {
+          order[j]=ringorder_lp;
+          need_other_ring=TRUE;
+          omit_degree=FALSE;
+          omitted_degree = TRUE;
+        }
+        break;
+      case ringorder_IS:
+      {
+        if (try_omit_comp)
+        {
+          // tried, but cannot omit component due to the ordering block [%d]: %d (ringorder_IS)", i, r_ord
+          try_omit_comp = FALSE;
+        }
+        order[j]=r_ord; /*r->order[i];*/
+        iNeedInducedOrderingSetup++;
+        break;
+      }
+      case ringorder_s:
+      {
+        assume((i == 0) && (j == 0));
+        if (try_omit_comp)
+        {
+          // tried, but cannot omit component due to the ordering block [%d]: %d (ringorder_s)", i, r_ord
+          try_omit_comp = FALSE;
+        }
+        order[j]=r_ord; /*r->order[i];*/
+        break;
+      }
+      default:
+        order[j]=r_ord; /*r->order[i];*/
+        break;
+    }
+    if (copy_block_index)
+    {
+      block0[j]=r->block0[i];
+      block1[j]=r->block1[i];
+      wvhdl[j]=r->wvhdl[i];
+    }
+
+    // order[j]=ringorder_no; //  done by omAlloc0
+  }
+  if(!need_other_ring)
+  {
+    omFreeSize(order,(nblocks+1)*sizeof(int));
+    omFreeSize(block0,(nblocks+1)*sizeof(int));
+    omFreeSize(block1,(nblocks+1)*sizeof(int));
+    omFreeSize(wvhdl,(nblocks+1)*sizeof(int *));
+    return r;
+  }
+  ring res=(ring)omAlloc0Bin(sip_sring_bin);
+  *res = *r;
+
+#ifdef HAVE_PLURAL
+  res->GetNC() = NULL;
+#endif
+
+  // res->qideal, res->idroot ???
+  res->wvhdl=wvhdl;
+  res->order=order;
+  res->block0=block0;
+  res->block1=block1;
+  res->bitmask=exp_limit;
+  //int tmpref=r->cf->ref0;
+  rComplete(res, 1);
+  //r->cf->ref=tmpref;
+
+  // adjust res->pFDeg: if it was changed globally, then
+  // it must also be changed for new ring
+  if (r->pFDegOrig != res->pFDegOrig &&
+           rOrd_is_WeightedDegree_Ordering(r))
+  {
+    // still might need adjustment for weighted orderings
+    // and omit_degree
+    res->firstwv = r->firstwv;
+    res->firstBlockEnds = r->firstBlockEnds;
+    res->pFDeg = res->pFDegOrig = p_WFirstTotalDegree;
+  }
+  if (omitted_degree)
+    res->pLDeg = r->pLDegOrig;
+
+  rOptimizeLDeg(res); // also sets res->pLDegOrig
+
+  // set syzcomp
+  if (res->typ != NULL)
+  {
+    if( res->typ[0].ord_typ == ro_syz) // "s" Always on [0] place!
+    {
+      res->typ[0] = r->typ[0]; // Copy struct!? + setup the same limit!
+
+      if (r->typ[0].data.syz.limit > 0)
+      {
+        res->typ[0].data.syz.syz_index
+          = (int*) omAlloc((r->typ[0].data.syz.limit +1)*sizeof(int));
+        memcpy(res->typ[0].data.syz.syz_index, r->typ[0].data.syz.syz_index,
+              (r->typ[0].data.syz.limit +1)*sizeof(int));
+      }
+    }
+
+    if( iNeedInducedOrderingSetup > 0 )
+    {
+      for(j = 0, i = 0; (i < nblocks) && (iNeedInducedOrderingSetup > 0); i++)
+        if( res->typ[i].ord_typ == ro_is ) // Search for suffixes!
+        {
+          ideal F = idrHeadR(r->typ[i].data.is.F, r, res); // Copy F from r into res!
+          assume(
+            rSetISReference( res,
+              F,  // WILL BE COPIED!
+              r->typ[i].data.is.limit,
+              j++
+              )
+            );
+          id_Delete(&F, res);
+          iNeedInducedOrderingSetup--;
+        }
+    } // Process all induced Ordering blocks! ...
+  }
+  // the special case: homog (omit_degree) and 1 block rs: that is global:
+  // it comes from dp
+  res->OrdSgn=r->OrdSgn;
+
+
+#ifdef HAVE_PLURAL
+  if (rIsPluralRing(r))
+  {
+    if ( nc_rComplete(r, res, false) ) // no qideal!
+    {
+#ifndef SING_NDEBUG
+      WarnS("error in nc_rComplete");
+#endif
+      // cleanup?
+
+//      rDelete(res);
+//      return r;
+
+      // just go on..
+    }
+
+    if( rIsSCA(r) )
+    {
+      if( !sca_Force(res, scaFirstAltVar(r), scaLastAltVar(r)) )
+      WarnS("error in sca_Force!");
+    }
+  }
+#endif
+
+  return res;
+}
+
+// construct Wp,C ring
+ring rModifyRing_Wp(ring r, int* weights)
+{
+  ring res=(ring)omAlloc0Bin(sip_sring_bin);
+  *res = *r;
+#ifdef HAVE_PLURAL
+  res->GetNC() = NULL;
+#endif
+
+  /*weights: entries for 3 blocks: NULL*/
+  res->wvhdl = (int **)omAlloc0(3 * sizeof(int *));
+  /*order: Wp,C,0*/
+  res->order = (int *) omAlloc(3 * sizeof(int *));
+  res->block0 = (int *)omAlloc0(3 * sizeof(int *));
+  res->block1 = (int *)omAlloc0(3 * sizeof(int *));
+  /* ringorder Wp for the first block: var 1..r->N */
+  res->order[0]  = ringorder_Wp;
+  res->block0[0] = 1;
+  res->block1[0] = r->N;
+  res->wvhdl[0] = weights;
+  /* ringorder C for the second block: no vars */
+  res->order[1]  = ringorder_C;
+  /* the last block: everything is 0 */
+  res->order[2]  = 0;
+
+  //int tmpref=r->cf->ref;
+  rComplete(res, 1);
+  //r->cf->ref=tmpref;
+#ifdef HAVE_PLURAL
+  if (rIsPluralRing(r))
+  {
+    if ( nc_rComplete(r, res, false) ) // no qideal!
+    {
+#ifndef SING_NDEBUG
+      WarnS("error in nc_rComplete");
+#endif
+      // cleanup?
+
+//      rDelete(res);
+//      return r;
+
+      // just go on..
+    }
+  }
+#endif
+  return res;
+}
+
+// construct lp, C ring with r->N variables, r->names vars....
+ring rModifyRing_Simple(ring r, BOOLEAN ommit_degree, BOOLEAN ommit_comp, unsigned long exp_limit, BOOLEAN &simple)
+{
+  simple=TRUE;
+  if (!rHasSimpleOrder(r))
+  {
+    simple=FALSE; // sorting needed
+    assume (r != NULL );
+    assume (exp_limit > 1);
+    int bits;
+
+    exp_limit=rGetExpSize(exp_limit, bits, r->N);
+
+    int nblocks=1+(ommit_comp!=0);
+    int *order=(int*)omAlloc0((nblocks+1)*sizeof(int));
+    int *block0=(int*)omAlloc0((nblocks+1)*sizeof(int));
+    int *block1=(int*)omAlloc0((nblocks+1)*sizeof(int));
+    int **wvhdl=(int**)omAlloc0((nblocks+1)*sizeof(int *));
+
+    order[0]=ringorder_lp;
+    block0[0]=1;
+    block1[0]=r->N;
+    if (!ommit_comp)
+    {
+      order[1]=ringorder_C;
+    }
+    ring res=(ring)omAlloc0Bin(sip_sring_bin);
+    *res = *r;
+#ifdef HAVE_PLURAL
+    res->GetNC() = NULL;
+#endif
+    // res->qideal, res->idroot ???
+    res->wvhdl=wvhdl;
+    res->order=order;
+    res->block0=block0;
+    res->block1=block1;
+    res->bitmask=exp_limit;
+    //int tmpref=r->cf->ref;
+    rComplete(res, 1);
+    //r->cf->ref=tmpref;
+
+#ifdef HAVE_PLURAL
+    if (rIsPluralRing(r))
+    {
+      if ( nc_rComplete(r, res, false) ) // no qideal!
+      {
+#ifndef SING_NDEBUG
+        WarnS("error in nc_rComplete");
+#endif
+        // cleanup?
+
+//      rDelete(res);
+//      return r;
+
+      // just go on..
+      }
+    }
+#endif
+
+    rOptimizeLDeg(res);
+
+    return res;
+  }
+  return rModifyRing(r, ommit_degree, ommit_comp, exp_limit);
+}
+
+void rKillModifiedRing_Simple(ring r)
+{
+  rKillModifiedRing(r);
+}
+
+
+void rKillModifiedRing(ring r)
+{
+  rUnComplete(r);
+  omFree(r->order);
+  omFree(r->block0);
+  omFree(r->block1);
+  omFree(r->wvhdl);
+  omFreeBin(r,sip_sring_bin);
+}
+
+void rKillModified_Wp_Ring(ring r)
+{
+  rUnComplete(r);
+  omFree(r->order);
+  omFree(r->block0);
+  omFree(r->block1);
+  omFree(r->wvhdl[0]);
+  omFree(r->wvhdl);
+  omFreeBin(r,sip_sring_bin);
+}
+
+static void rSetOutParams(ring r)
+{
+  r->VectorOut = (r->order[0] == ringorder_c);
+  r->CanShortOut = TRUE;
+  {
+    int i;
+    if (rParameter(r)!=NULL)
+    {
+      for (i=0;i<rPar(r);i++)
+      {
+        if(strlen(rParameter(r)[i])>1)
+        {
+          r->CanShortOut=FALSE;
+          break;
+        }
+      }
+    }
+    if (r->CanShortOut)
+    {
+      // Hmm... sometimes (e.g., from maGetPreimage) new variables
+      // are introduced, but their names are never set
+      // hence, we do the following awkward trick
+      int N = omSizeOfAddr(r->names)/sizeof(char*);
+      if (r->N < N) N = r->N;
+
+      for (i=(N-1);i>=0;i--)
+      {
+        if(r->names[i] != NULL && strlen(r->names[i])>1)
+        {
+          r->CanShortOut=FALSE;
+          break;
+        }
+      }
+    }
+  }
+  r->ShortOut = r->CanShortOut;
+
+  assume( !( !r->CanShortOut && r->ShortOut ) );
+}
+
+/*2
+* sets r->MixedOrder and r->ComponentOrder for orderings with more than one block
+* block of variables (ip is the block number, o_r the number of the ordering)
+* o is the position of the orderingering in r
+*/
+static void rHighSet(ring r, int o_r, int o)
+{
+  switch(o_r)
+  {
+    case ringorder_lp:
+    case ringorder_dp:
+    case ringorder_Dp:
+    case ringorder_wp:
+    case ringorder_Wp:
+    case ringorder_rp:
+    case ringorder_a:
+    case ringorder_aa:
+    case ringorder_am:
+    case ringorder_a64:
+      if (r->OrdSgn==-1) r->MixedOrder=TRUE;
+      break;
+    case ringorder_ls:
+    case ringorder_rs:
+    case ringorder_ds:
+    case ringorder_Ds:
+    case ringorder_s:
+      break;
+    case ringorder_ws:
+    case ringorder_Ws:
+      if (r->wvhdl[o]!=NULL)
+      {
+        int i;
+        for(i=r->block1[o]-r->block0[o];i>=0;i--)
+          if (r->wvhdl[o][i]<0) { r->MixedOrder=TRUE; break; }
+      }
+      break;
+    case ringorder_c:
+      r->ComponentOrder=1;
+      break;
+    case ringorder_C:
+    case ringorder_S:
+      r->ComponentOrder=-1;
+      break;
+    case ringorder_M:
+      r->LexOrder=TRUE;
+      break;
+    case ringorder_IS:
+    { // TODO: What is r->ComponentOrder???
+//      r->MixedOrder=TRUE;
+      if( r->block0[o] != 0 ) // Suffix has the component
+        r->ComponentOrder = r->block0[o];
+/*      else // Prefix has level...
+        r->ComponentOrder=-1;
+*/
+      // TODO: think about this a bit...!?
+      break;
+    }
+
+    default:
+      dReportError("wrong internal ordering:%d at %s, l:%d\n",o_r,__FILE__,__LINE__);
+  }
+}
+
+static void rSetFirstWv(ring r, int i, int* order, int* block1, int** wvhdl)
+{
+  // cheat for ringorder_aa
+  if (order[i] == ringorder_aa)
+    i++;
+  if(block1[i]!=r->N) r->LexOrder=TRUE;
+  r->firstBlockEnds=block1[i];
+  r->firstwv = wvhdl[i];
+  if ((order[i]== ringorder_ws)
+  || (order[i]==ringorder_Ws)
+  || (order[i]== ringorder_wp)
+  || (order[i]==ringorder_Wp)
+  || (order[i]== ringorder_a)
+   /*|| (order[i]==ringorder_A)*/)
+  {
+    int j;
+    for(j=block1[i]-r->block0[i];j>=0;j--)
+    {
+      if (r->firstwv[j]<0) r->MixedOrder=TRUE;
+      if (r->firstwv[j]==0) r->LexOrder=TRUE;
+    }
+  }
+  else if (order[i]==ringorder_a64)
+  {
+    int j;
+    int64 *w=rGetWeightVec(r);
+    for(j=block1[i]-r->block0[i];j>=0;j--)
+    {
+      if (w[j]==0) r->LexOrder=TRUE;
+    }
+  }
+}
+
+static void rOptimizeLDeg(ring r)
+{
+  if (r->pFDeg == p_Deg)
+  {
+    if (r->pLDeg == pLDeg1)
+      r->pLDeg = pLDeg1_Deg;
+    if (r->pLDeg == pLDeg1c)
+      r->pLDeg = pLDeg1c_Deg;
+  }
+  else if (r->pFDeg == p_Totaldegree)
+  {
+    if (r->pLDeg == pLDeg1)
+      r->pLDeg = pLDeg1_Totaldegree;
+    if (r->pLDeg == pLDeg1c)
+      r->pLDeg = pLDeg1c_Totaldegree;
+  }
+  else if (r->pFDeg == p_WFirstTotalDegree)
+  {
+    if (r->pLDeg == pLDeg1)
+      r->pLDeg = pLDeg1_WFirstTotalDegree;
+    if (r->pLDeg == pLDeg1c)
+      r->pLDeg = pLDeg1c_WFirstTotalDegree;
+  }
+  r->pLDegOrig = r->pLDeg;
+}
+
+// set pFDeg, pLDeg, MixOrder, ComponentOrder, etc
+static void rSetDegStuff(ring r)
+{
+  int* order = r->order;
+  int* block0 = r->block0;
+  int* block1 = r->block1;
+  int** wvhdl = r->wvhdl;
+
+  if (order[0]==ringorder_S ||order[0]==ringorder_s || order[0]==ringorder_IS)
+  {
+    order++;
+    block0++;
+    block1++;
+    wvhdl++;
+  }
+  r->LexOrder = FALSE;
+  r->MixedOrder = FALSE;
+  r->ComponentOrder = 1;
+  r->pFDeg = p_Totaldegree;
+  r->pLDeg = (r->OrdSgn == 1 ? pLDegb : pLDeg0);
+
+  /*======== ordering type is (am,_) ==================*/
+  if (order[0]==ringorder_am)
+  {
+    r->MixedOrder = FALSE;
+    for(int ii=block0[0];ii<=block1[0];ii++)
+      if (wvhdl[0][ii-1]<0) { r->MixedOrder=TRUE;break;}
+    r->LexOrder=FALSE;
+    for(int ii=block0[0];ii<=block1[0];ii++)
+      if (wvhdl[0][ii-1]==0) { r->LexOrder=TRUE;break;}
+    if ((block0[0]==1)&&(block1[0]==r->N))
+    {
+      r->pFDeg = p_Deg;
+      r->pLDeg = pLDeg1c_Deg;
+    }
+    else
+   {
+      r->pFDeg = p_WTotaldegree;
+      r->LexOrder=TRUE;
+      r->pLDeg = pLDeg1c_WFirstTotalDegree;
+    }
+    r->firstwv = wvhdl[0];
+  }
+  /*======== ordering type is (_,c) =========================*/
+  else if ((order[0]==ringorder_unspec) || (order[1] == 0)
+      ||(
+    ((order[1]==ringorder_c)||(order[1]==ringorder_C)
+     ||(order[1]==ringorder_S)
+     ||(order[1]==ringorder_s))
+    && (order[0]!=ringorder_M)
+    && (order[2]==0))
+    )
+  {
+    if ((order[0]!=ringorder_unspec)
+    && ((order[1]==ringorder_C)||(order[1]==ringorder_S)||
+        (order[1]==ringorder_s)))
+      r->ComponentOrder=-1;
+    if (r->OrdSgn == -1) r->pLDeg = pLDeg0c;
+    if ((order[0] == ringorder_lp)
+    || (order[0] == ringorder_ls)
+    || (order[0] == ringorder_rp)
+    || (order[0] == ringorder_rs))
+    {
+      r->LexOrder=TRUE;
+      r->pLDeg = pLDeg1c;
+      r->pFDeg = p_Totaldegree;
+    }
+    if ((order[0] == ringorder_a)
+    || (order[0] == ringorder_wp)
+    || (order[0] == ringorder_Wp)
+    || (order[0] == ringorder_ws)
+    || (order[0] == ringorder_Ws))
+      r->pFDeg = p_WFirstTotalDegree;
+    r->firstBlockEnds=block1[0];
+    r->firstwv = wvhdl[0];
+  }
+  /*======== ordering type is (c,_) =========================*/
+  else if (((order[0]==ringorder_c)
+            ||(order[0]==ringorder_C)
+            ||(order[0]==ringorder_S)
+            ||(order[0]==ringorder_s))
+  && (order[1]!=ringorder_M)
+  &&  (order[2]==0))
+  {
+    if ((order[0]==ringorder_C)||(order[0]==ringorder_S)||
+        order[0]==ringorder_s)
+      r->ComponentOrder=-1;
+    if ((order[1] == ringorder_lp)
+    || (order[1] == ringorder_ls)
+    || (order[1] == ringorder_rp)
+    || order[1] == ringorder_rs)
+    {
+      r->LexOrder=TRUE;
+      r->pLDeg = pLDeg1c;
+      r->pFDeg = p_Totaldegree;
+    }
+    r->firstBlockEnds=block1[1];
+    if (wvhdl!=NULL) r->firstwv = wvhdl[1];
+    if ((order[1] == ringorder_a)
+    || (order[1] == ringorder_wp)
+    || (order[1] == ringorder_Wp)
+    || (order[1] == ringorder_ws)
+    || (order[1] == ringorder_Ws))
+      r->pFDeg = p_WFirstTotalDegree;
+  }
+  /*------- more than one block ----------------------*/
+  else
+  {
+    if ((r->VectorOut)||(order[0]==ringorder_C)||(order[0]==ringorder_S)||(order[0]==ringorder_s))
+    {
+      rSetFirstWv(r, 1, order, block1, wvhdl);
+    }
+    else
+      rSetFirstWv(r, 0, order, block1, wvhdl);
+
+    /*the number of orderings:*/
+    int i = 0; while (order[++i] != 0);
+
+    do
+    {
+      i--;
+      rHighSet(r, order[i],i);
+    }
+    while (i != 0);
+
+    if ((order[0]!=ringorder_c)
+        && (order[0]!=ringorder_C)
+        && (order[0]!=ringorder_S)
+        && (order[0]!=ringorder_s))
+    {
+      r->pLDeg = pLDeg1c;
+    }
+    else
+    {
+      r->pLDeg = pLDeg1;
+    }
+    r->pFDeg = p_WTotaldegree; // may be improved: p_Totaldegree for lp/dp/ls/.. blocks
+  }
+
+  if (rOrd_is_Totaldegree_Ordering(r) || rOrd_is_WeightedDegree_Ordering(r))
+    r->pFDeg = p_Deg;
+
+  if( rGetISPos(0, r) != -1 ) // Are there Schreyer induced blocks?
+  {
+#ifndef SING_NDEBUG
+      assume( r->pFDeg == p_Deg || r->pFDeg == p_WTotaldegree || r->pFDeg == p_Totaldegree);
+#endif
+
+    r->pLDeg = pLDeg1; // ?
+  }
+
+  r->pFDegOrig = r->pFDeg;
+  // NOTE: this leads to wrong ecart during std
+  // in Old/sre.tst
+  rOptimizeLDeg(r); // also sets r->pLDegOrig
+
+}
+
+/*2
+* set NegWeightL_Size, NegWeightL_Offset
+*/
+static void rSetNegWeight(ring r)
+{
+  int i,l;
+  if (r->typ!=NULL)
+  {
+    l=0;
+    for(i=0;i<r->OrdSize;i++)
+    {
+      if((r->typ[i].ord_typ==ro_wp_neg)
+      ||(r->typ[i].ord_typ==ro_am))
+        l++;
+    }
+    if (l>0)
+    {
+      r->NegWeightL_Size=l;
+      r->NegWeightL_Offset=(int *) omAlloc(l*sizeof(int));
+      l=0;
+      for(i=0;i<r->OrdSize;i++)
+      {
+        if(r->typ[i].ord_typ==ro_wp_neg)
+        {
+          r->NegWeightL_Offset[l]=r->typ[i].data.wp.place;
+          l++;
+        }
+        else if(r->typ[i].ord_typ==ro_am)
+        {
+          r->NegWeightL_Offset[l]=r->typ[i].data.am.place;
+          l++;
+        }
+      }
+      return;
+    }
+  }
+  r->NegWeightL_Size = 0;
+  r->NegWeightL_Offset = NULL;
+}
+
+static void rSetOption(ring r)
+{
+  // set redthrough
+  if (!TEST_OPT_OLDSTD && r->OrdSgn == 1 && ! r->LexOrder)
+    r->options |= Sy_bit(OPT_REDTHROUGH);
+  else
+    r->options &= ~Sy_bit(OPT_REDTHROUGH);
+
+  // set intStrategy
+  if ( (r->cf->extRing!=NULL)
+      || rField_is_Q(r)
+#ifdef HAVE_RINGS
+      || rField_is_Ring(r)
+#endif
+  )
+    r->options |= Sy_bit(OPT_INTSTRATEGY);
+  else
+    r->options &= ~Sy_bit(OPT_INTSTRATEGY);
+
+  // set redTail
+  if (r->LexOrder || r->OrdSgn == -1 || (r->cf->extRing!=NULL))
+    r->options &= ~Sy_bit(OPT_REDTAIL);
+  else
+    r->options |= Sy_bit(OPT_REDTAIL);
+}
+
+static void rCheckOrdSgn(ring r,int i/*current block*/);
+
+/* -------------------------------------------------------- */
+/*2
+* change all global variables to fit the description of the new ring
+*/
+
+void p_SetGlobals(const ring r, BOOLEAN complete)
+{
+// // //  if (r->ppNoether!=NULL) p_Delete(&r->ppNoether,r); // ???
+
+  r->pLexOrder=r->LexOrder;
+  if (complete)
+  {
+    si_opt_1 &= ~ TEST_RINGDEP_OPTS;
+    si_opt_1 |= r->options;
+  }
+}
+
+BOOLEAN rComplete(ring r, int force)
+{
+  if (r->VarOffset!=NULL && force == 0) return FALSE;
+  rSetOutParams(r);
+  int n=rBlocks(r)-1;
+  int i;
+  int bits;
+  r->bitmask=rGetExpSize(r->bitmask,bits,r->N);
+  r->BitsPerExp = bits;
+  r->ExpPerLong = BIT_SIZEOF_LONG / bits;
+  r->divmask=rGetDivMask(bits);
+  if (r->OrdSgn!=-1) r->OrdSgn=1; //rCheckOrdSgn will changed that, if needed
+
+  // will be used for ordsgn:
+  long *tmp_ordsgn=(long *)omAlloc0(3*(n+r->N)*sizeof(long));
+  // will be used for VarOffset:
+  int *v=(int *)omAlloc((r->N+1)*sizeof(int));
+  for(i=r->N; i>=0 ; i--)
+  {
+    v[i]=-1;
+  }
+  sro_ord *tmp_typ=(sro_ord *)omAlloc0(3*(n+r->N)*sizeof(sro_ord));
+  int typ_i=0;
+  int prev_ordsgn=0;
+
+  // fill in v, tmp_typ, tmp_ordsgn, determine typ_i (== ordSize)
+  int j=0;
+  int j_bits=BITS_PER_LONG;
+
+  BOOLEAN need_to_add_comp=FALSE; // Only for ringorder_s and ringorder_S!
+
+  for(i=0;i<n;i++)
+  {
+    tmp_typ[typ_i].order_index=i;
+    switch (r->order[i])
+    {
+      case ringorder_a:
+      case ringorder_aa:
+        rO_WDegree(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,tmp_typ[typ_i],
+                   r->wvhdl[i]);
+        typ_i++;
+        break;
+
+      case ringorder_am:
+        rO_WMDegree(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,tmp_typ[typ_i],
+                   r->wvhdl[i]);
+        typ_i++;
+        break;
+
+      case ringorder_a64:
+        rO_WDegree64(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,
+                     tmp_typ[typ_i], (int64 *)(r->wvhdl[i]));
+        typ_i++;
+        break;
+
+      case ringorder_c:
+        rO_Align(j, j_bits);
+        rO_LexVars_neg(j, j_bits, 0,0, prev_ordsgn,tmp_ordsgn,v,BITS_PER_LONG, -1);
+        break;
+
+      case ringorder_C:
+        rO_Align(j, j_bits);
+        rO_LexVars(j, j_bits, 0,0, prev_ordsgn,tmp_ordsgn,v,BITS_PER_LONG, -1);
+        break;
+
+      case ringorder_M:
+        {
+          int k,l;
+          k=r->block1[i]-r->block0[i]+1; // number of vars
+          for(l=0;l<k;l++)
+          {
+            rO_WDegree(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,
+                       tmp_typ[typ_i],
+                       r->wvhdl[i]+(r->block1[i]-r->block0[i]+1)*l);
+            typ_i++;
+          }
+          break;
+        }
+
+      case ringorder_lp:
+        rO_LexVars(j, j_bits, r->block0[i],r->block1[i], prev_ordsgn,
+                   tmp_ordsgn,v,bits, -1);
+        break;
+
+      case ringorder_ls:
+        rO_LexVars_neg(j, j_bits, r->block0[i],r->block1[i], prev_ordsgn,
+                       tmp_ordsgn,v, bits, -1);
+        rCheckOrdSgn(r,i);
+        break;
+
+      case ringorder_rs:
+        rO_LexVars_neg(j, j_bits, r->block1[i],r->block0[i], prev_ordsgn,
+                       tmp_ordsgn,v, bits, -1);
+        rCheckOrdSgn(r,i);
+        break;
+
+      case ringorder_rp:
+        rO_LexVars(j, j_bits, r->block1[i],r->block0[i], prev_ordsgn,
+                       tmp_ordsgn,v, bits, -1);
+        break;
+
+      case ringorder_dp:
+        if (r->block0[i]==r->block1[i])
+        {
+          rO_LexVars(j, j_bits, r->block0[i],r->block0[i], prev_ordsgn,
+                     tmp_ordsgn,v, bits, -1);
+        }
+        else
+        {
+          rO_TDegree(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,
+                     tmp_typ[typ_i]);
+          typ_i++;
+          rO_LexVars_neg(j, j_bits, r->block1[i],r->block0[i]+1,
+                         prev_ordsgn,tmp_ordsgn,v,bits, r->block0[i]);
+        }
+        break;
+
+      case ringorder_Dp:
+        if (r->block0[i]==r->block1[i])
+        {
+          rO_LexVars(j, j_bits, r->block0[i],r->block0[i], prev_ordsgn,
+                     tmp_ordsgn,v, bits, -1);
+        }
+        else
+        {
+          rO_TDegree(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,
+                     tmp_typ[typ_i]);
+          typ_i++;
+          rO_LexVars(j, j_bits, r->block0[i],r->block1[i]-1, prev_ordsgn,
+                     tmp_ordsgn,v, bits, r->block1[i]);
+        }
+        break;
+
+      case ringorder_ds:
+        if (r->block0[i]==r->block1[i])
+        {
+          rO_LexVars_neg(j, j_bits,r->block0[i],r->block1[i],prev_ordsgn,
+                         tmp_ordsgn,v,bits, -1);
+        }
+        else
+        {
+          rO_TDegree_neg(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,
+                         tmp_typ[typ_i]);
+          typ_i++;
+          rO_LexVars_neg(j, j_bits, r->block1[i],r->block0[i]+1,
+                         prev_ordsgn,tmp_ordsgn,v,bits, r->block0[i]);
+        }
+        rCheckOrdSgn(r,i);
+        break;
+
+      case ringorder_Ds:
+        if (r->block0[i]==r->block1[i])
+        {
+          rO_LexVars_neg(j, j_bits, r->block0[i],r->block0[i],prev_ordsgn,
+                         tmp_ordsgn,v, bits, -1);
+        }
+        else
+        {
+          rO_TDegree_neg(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,
+                         tmp_typ[typ_i]);
+          typ_i++;
+          rO_LexVars(j, j_bits, r->block0[i],r->block1[i]-1, prev_ordsgn,
+                     tmp_ordsgn,v, bits, r->block1[i]);
+        }
+        rCheckOrdSgn(r,i);
+        break;
+
+      case ringorder_wp:
+        rO_WDegree(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,
+                   tmp_typ[typ_i], r->wvhdl[i]);
+        typ_i++;
+        { // check for weights <=0
+          int jj;
+          BOOLEAN have_bad_weights=FALSE;
+          for(jj=r->block1[i]-r->block0[i];jj>=0; jj--)
+          {
+            if (r->wvhdl[i][jj]<=0) have_bad_weights=TRUE;
+          }
+          if (have_bad_weights)
+          {
+             rO_TDegree(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,
+                                     tmp_typ[typ_i]);
+             typ_i++;
+             rCheckOrdSgn(r,i);
+          }
+        }
+        if (r->block1[i]!=r->block0[i])
+        {
+          rO_LexVars_neg(j, j_bits,r->block1[i],r->block0[i]+1, prev_ordsgn,
+                         tmp_ordsgn, v,bits, r->block0[i]);
+        }
+        break;
+
+      case ringorder_Wp:
+        rO_WDegree(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,
+                   tmp_typ[typ_i], r->wvhdl[i]);
+        typ_i++;
+        { // check for weights <=0
+          int jj;
+          BOOLEAN have_bad_weights=FALSE;
+          for(jj=r->block1[i]-r->block0[i];jj>=0; jj--)
+          {
+            if (r->wvhdl[i][jj]<=0) have_bad_weights=TRUE;
+          }
+          if (have_bad_weights)
+          {
+             rO_TDegree(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,
+                                     tmp_typ[typ_i]);
+             typ_i++;
+             rCheckOrdSgn(r,i);
+          }
+        }
+        if (r->block1[i]!=r->block0[i])
+        {
+          rO_LexVars(j, j_bits,r->block0[i],r->block1[i]-1, prev_ordsgn,
+                     tmp_ordsgn,v, bits, r->block1[i]);
+        }
+        break;
+
+      case ringorder_ws:
+        rO_WDegree_neg(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,
+                       tmp_typ[typ_i], r->wvhdl[i]);
+        typ_i++;
+        if (r->block1[i]!=r->block0[i])
+        {
+          rO_LexVars_neg(j, j_bits,r->block1[i],r->block0[i]+1, prev_ordsgn,
+                         tmp_ordsgn, v,bits, r->block0[i]);
+        }
+        rCheckOrdSgn(r,i);
+        break;
+
+      case ringorder_Ws:
+        rO_WDegree_neg(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,
+                       tmp_typ[typ_i], r->wvhdl[i]);
+        typ_i++;
+        if (r->block1[i]!=r->block0[i])
+        {
+          rO_LexVars(j, j_bits,r->block0[i],r->block1[i]-1, prev_ordsgn,
+                     tmp_ordsgn,v, bits, r->block1[i]);
+        }
+        rCheckOrdSgn(r,i);
+        break;
+
+      case ringorder_S:
+        assume(typ_i == 1); // For LaScala3 only: on the 2nd place ([1])!
+        // TODO: for K[x]: it is 0...?!
+        rO_Syzcomp(j, j_bits,prev_ordsgn, tmp_ordsgn,tmp_typ[typ_i]);
+        need_to_add_comp=TRUE;
+        typ_i++;
+        break;
+
+      case ringorder_s:
+        assume(typ_i == 0 && j == 0);
+        rO_Syz(j, j_bits, prev_ordsgn, tmp_ordsgn, tmp_typ[typ_i]); // set syz-limit?
+        need_to_add_comp=TRUE;
+        typ_i++;
+        break;
+
+      case ringorder_IS:
+      {
+
+        assume( r->block0[i] == r->block1[i] );
+        const int s = r->block0[i];
+        assume( -2 < s && s < 2);
+
+        if(s == 0) // Prefix IS
+          rO_ISPrefix(j, j_bits, prev_ordsgn, tmp_ordsgn, r->N, v, tmp_typ[typ_i++]); // What about prev_ordsgn?
+        else // s = +1 or -1 // Note: typ_i might be incrimented here inside!
+        {
+          rO_ISSuffix(j, j_bits, prev_ordsgn, tmp_ordsgn, r->N, v, tmp_typ, typ_i, s); // Suffix.
+          need_to_add_comp=FALSE;
+        }
+
+        break;
+      }
+      case ringorder_unspec:
+      case ringorder_no:
+      default:
+        dReportError("undef. ringorder used\n");
+        break;
+    }
+  }
+
+  int j0=j; // save j
+  int j_bits0=j_bits; // save jbits
+  rO_Align(j,j_bits);
+  r->CmpL_Size = j;
+
+  j_bits=j_bits0; j=j0;
+
+  // fill in some empty slots with variables not already covered
+  // v0 is special, is therefore normally already covered
+  // now we do have rings without comp...
+  if((need_to_add_comp) && (v[0]== -1))
+  {
+    if (prev_ordsgn==1)
+    {
+      rO_Align(j, j_bits);
+      rO_LexVars(j, j_bits, 0,0, prev_ordsgn,tmp_ordsgn,v,BITS_PER_LONG, -1);
+    }
+    else
+    {
+      rO_Align(j, j_bits);
+      rO_LexVars_neg(j, j_bits, 0,0, prev_ordsgn,tmp_ordsgn,v,BITS_PER_LONG, -1);
+    }
+  }
+  // the variables
+  for(i=1 ; i<=r->N ; i++)
+  {
+    if(v[i]==(-1))
+    {
+      if (prev_ordsgn==1)
+      {
+        rO_LexVars(j, j_bits, i,i, prev_ordsgn,tmp_ordsgn,v,bits, -1);
+      }
+      else
+      {
+        rO_LexVars_neg(j,j_bits,i,i, prev_ordsgn,tmp_ordsgn,v,bits, -1);
+      }
+    }
+  }
+
+  rO_Align(j,j_bits);
+  // ----------------------------
+  // finished with constructing the monomial, computing sizes:
+
+  r->ExpL_Size=j;
+  r->PolyBin = omGetSpecBin(POLYSIZE + (r->ExpL_Size)*sizeof(long));
+  assume(r->PolyBin != NULL);
+
+  // ----------------------------
+  // indices and ordsgn vector for comparison
+  //
+  // r->pCompHighIndex already set
+  r->ordsgn=(long *)omAlloc0(r->ExpL_Size*sizeof(long));
+
+  for(j=0;j<r->CmpL_Size;j++)
+  {
+    r->ordsgn[j] = tmp_ordsgn[j];
+  }
+
+  omFreeSize((ADDRESS)tmp_ordsgn,(3*(n+r->N)*sizeof(long)));
+
+  // ----------------------------
+  // description of orderings for setm:
+  //
+  r->OrdSize=typ_i;
+  if (typ_i==0) r->typ=NULL;
+  else
+  {
+    r->typ=(sro_ord*)omAlloc(typ_i*sizeof(sro_ord));
+    memcpy(r->typ,tmp_typ,typ_i*sizeof(sro_ord));
+  }
+  omFreeSize((ADDRESS)tmp_typ,(3*(n+r->N)*sizeof(sro_ord)));
+
+  // ----------------------------
+  // indices for (first copy of ) variable entries in exp.e vector (VarOffset):
+  r->VarOffset=v;
+
+  // ----------------------------
+  // other indicies
+  r->pCompIndex=(r->VarOffset[0] & 0xffff); //r->VarOffset[0];
+  i=0; // position
+  j=0; // index in r->typ
+  if (i==r->pCompIndex) i++; // IS???
+  while ((j < r->OrdSize)
+         && ((r->typ[j].ord_typ==ro_syzcomp) ||
+             (r->typ[j].ord_typ==ro_syz) || (r->typ[j].ord_typ==ro_isTemp) || (r->typ[j].ord_typ==ro_is) ||
+             (r->order[r->typ[j].order_index] == ringorder_aa)))
+  {
+    i++; j++;
+  }
+  // No use of j anymore!!!????
+
+  if (i==r->pCompIndex) i++;
+  r->pOrdIndex=i; // How came it is "i" here???!!!! exp[r->pOrdIndex] is order of a poly... This may be wrong!!! IS
+
+  // ----------------------------
+  rSetDegStuff(r);
+  rSetOption(r);
+  // ----------------------------
+  // r->p_Setm
+  r->p_Setm = p_GetSetmProc(r);
+
+  // ----------------------------
+  // set VarL_*
+  rSetVarL(r);
+
+  //  ----------------------------
+  // right-adjust VarOffset
+  rRightAdjustVarOffset(r);
+
+  // ----------------------------
+  // set NegWeightL*
+  rSetNegWeight(r);
+
+  // ----------------------------
+  // p_Procs: call AFTER NegWeightL
+  r->p_Procs = (p_Procs_s*)omAlloc(sizeof(p_Procs_s));
+  p_ProcsSet(r, r->p_Procs);
+  return FALSE;
+}
+
+static void rCheckOrdSgn(ring r,int b/*current block*/)
+{ // set r->OrdSgn, return, if already checked
+  if (r->OrdSgn==-1) return;
+  // for each variable:
+  for(int i=1;i<=r->N;i++)
+  {
+    int found=0;
+    // for all blocks:
+    for(int j=0;(j<=b) && (found==0);j++)
+    {
+      // search the first block containing var(i)
+      if ((r->block0[j]<=i)&&(r->block1[j]>=i))
+      {
+        // what kind if block is it?
+        if ((r->order[j]==ringorder_ls)
+        || (r->order[j]==ringorder_ds)
+        || (r->order[j]==ringorder_Ds)
+        || (r->order[j]==ringorder_ws)
+        || (r->order[j]==ringorder_Ws)
+        || (r->order[j]==ringorder_rs))
+        {
+          r->OrdSgn=-1;
+          return;
+        }
+        if((r->order[j]==ringorder_a)
+        ||(r->order[j]==ringorder_aa))
+        {
+          // <0: local/mixed ordering return
+          // >0: var(i) is okay, look at other vars
+          // ==0: look at other blocks for var(i)
+          if(r->wvhdl[j][i-r->block0[j]]<0) { r->OrdSgn=-1; return;}
+          if(r->wvhdl[j][i-r->block0[j]]>0) { found=1; break;}
+        }
+      }
+    }
+  }
+  // no local var found in 1..N:
+  //r->OrdSgn=1;
+}
+
+void rUnComplete(ring r)
+{
+  if (r == NULL) return;
+  if (r->VarOffset != NULL)
+  {
+    if (r->OrdSize!=0 && r->typ != NULL)
+    {
+      for(int i = 0; i < r->OrdSize; i++)
+        if( r->typ[i].ord_typ == ro_is) // Search for suffixes! (prefix have the same VarOffset)
+        {
+          id_Delete(&r->typ[i].data.is.F, r);
+          r->typ[i].data.is.F = NULL; // ?
+
+          if( r->typ[i].data.is.pVarOffset != NULL )
+          {
+            omFreeSize((ADDRESS)r->typ[i].data.is.pVarOffset, (r->N +1)*sizeof(int));
+            r->typ[i].data.is.pVarOffset = NULL; // ?
+          }
+        }
+        else if (r->typ[i].ord_typ == ro_syz)
+        {
+          if(r->typ[i].data.syz.limit > 0)
+            omFreeSize(r->typ[i].data.syz.syz_index, ((r->typ[i].data.syz.limit) +1)*sizeof(int));
+          r->typ[i].data.syz.syz_index = NULL;
+        }
+        else if (r->typ[i].ord_typ == ro_syzcomp)
+        {
+          assume( r->typ[i].data.syzcomp.ShiftedComponents == NULL );
+          assume( r->typ[i].data.syzcomp.Components        == NULL );
+//          WarnS( "rUnComplete : ord_typ == ro_syzcomp was unhandled!!! Possibly memory leak!!!"  );
+#ifndef SING_NDEBUG
+//          assume(0);
+#endif
+        }
+
+      omFreeSize((ADDRESS)r->typ,r->OrdSize*sizeof(sro_ord)); r->typ = NULL;
+    }
+
+    if (r->PolyBin != NULL)
+      omUnGetSpecBin(&(r->PolyBin));
+
+    omFreeSize((ADDRESS)r->VarOffset, (r->N +1)*sizeof(int));
+
+    if (r->ordsgn != NULL && r->CmpL_Size != 0)
+      omFreeSize((ADDRESS)r->ordsgn,r->ExpL_Size*sizeof(long));
+    if (r->p_Procs != NULL)
+      omFreeSize(r->p_Procs, sizeof(p_Procs_s));
+    omfreeSize(r->VarL_Offset, r->VarL_Size*sizeof(int));
+  }
+  if (r->NegWeightL_Offset!=NULL)
+  {
+    omFreeSize(r->NegWeightL_Offset, r->NegWeightL_Size*sizeof(int));
+    r->NegWeightL_Offset=NULL;
+  }
+}
+
+// set r->VarL_Size, r->VarL_Offset, r->VarL_LowIndex
+static void rSetVarL(ring r)
+{
+  int  min = MAX_INT_VAL, min_j = -1;
+  int* VarL_Number = (int*) omAlloc0(r->ExpL_Size*sizeof(int));
+
+  int i,j;
+
+  // count how often a var long is occupied by an exponent
+  for (i=1; i<=r->N; i++)
+  {
+    VarL_Number[r->VarOffset[i] & 0xffffff]++;
+  }
+
+  // determine how many and min
+  for (i=0, j=0; i<r->ExpL_Size; i++)
+  {
+    if (VarL_Number[i] != 0)
+    {
+      if (min > VarL_Number[i])
+      {
+        min = VarL_Number[i];
+        min_j = j;
+      }
+      j++;
+    }
+  }
+
+  r->VarL_Size = j; // number of long with exp. entries in
+                    //  in p->exp
+  r->VarL_Offset = (int*) omAlloc(r->VarL_Size*sizeof(int));
+  r->VarL_LowIndex = 0;
+
+  // set VarL_Offset
+  for (i=0, j=0; i<r->ExpL_Size; i++)
+  {
+    if (VarL_Number[i] != 0)
+    {
+      r->VarL_Offset[j] = i;
+      if (j > 0 && r->VarL_Offset[j-1] != r->VarL_Offset[j] - 1)
+        r->VarL_LowIndex = -1;
+      j++;
+    }
+  }
+  if (r->VarL_LowIndex >= 0)
+    r->VarL_LowIndex = r->VarL_Offset[0];
+
+  r->MinExpPerLong = min;
+  if (min_j != 0)
+  {
+    j = r->VarL_Offset[min_j];
+    r->VarL_Offset[min_j] = r->VarL_Offset[0];
+    r->VarL_Offset[0] = j;
+  }
+  omFree(VarL_Number);
+}
+
+static void rRightAdjustVarOffset(ring r)
+{
+  int* shifts = (int*) omAlloc(r->ExpL_Size*sizeof(int));
+  int i;
+  // initialize shifts
+  for (i=0;i<r->ExpL_Size;i++)
+    shifts[i] = BIT_SIZEOF_LONG;
+
+  // find minimal bit shift in each long exp entry
+  for (i=1;i<=r->N;i++)
+  {
+    if (shifts[r->VarOffset[i] & 0xffffff] > r->VarOffset[i] >> 24)
+      shifts[r->VarOffset[i] & 0xffffff] = r->VarOffset[i] >> 24;
+  }
+  // reset r->VarOffset: set the minimal shift to 0
+  for (i=1;i<=r->N;i++)
+  {
+    if (shifts[r->VarOffset[i] & 0xffffff] != 0)
+      r->VarOffset[i]
+        = (r->VarOffset[i] & 0xffffff) |
+        (((r->VarOffset[i] >> 24) - shifts[r->VarOffset[i] & 0xffffff]) << 24);
+  }
+  omFree(shifts);
+}
+
+// get r->divmask depending on bits per exponent
+static unsigned long rGetDivMask(int bits)
+{
+  unsigned long divmask = 1;
+  int i = bits;
+
+  while (i < BIT_SIZEOF_LONG)
+  {
+    divmask |= (((unsigned long) 1) << (unsigned long) i);
+    i += bits;
+  }
+  return divmask;
+}
+
+#ifdef RDEBUG
+void rDebugPrint(ring r)
+{
+  if (r==NULL)
+  {
+    PrintS("NULL ?\n");
+    return;
+  }
+  // corresponds to ro_typ from ring.h:
+  const char *TYP[]={"ro_dp","ro_wp","ro_am","ro_wp64","ro_wp_neg","ro_cp",
+                     "ro_syzcomp", "ro_syz", "ro_isTemp", "ro_is", "ro_none"};
+  int i,j;
+
+  Print("ExpL_Size:%d ",r->ExpL_Size);
+  Print("CmpL_Size:%d ",r->CmpL_Size);
+  Print("VarL_Size:%d\n",r->VarL_Size);
+  Print("bitmask=0x%lx (expbound=%ld) \n",r->bitmask, r->bitmask);
+  Print("divmask=%lx\n", r->divmask);
+  Print("BitsPerExp=%d ExpPerLong=%d MinExpPerLong=%d at L[%d]\n", r->BitsPerExp, r->ExpPerLong, r->MinExpPerLong, r->VarL_Offset[0]);
+
+  Print("VarL_LowIndex: %d\n", r->VarL_LowIndex);
+  PrintS("VarL_Offset:\n");
+  if (r->VarL_Offset==NULL) PrintS(" NULL");
+  else
+    for(j = 0; j < r->VarL_Size; j++)
+      Print("  VarL_Offset[%d]: %d ", j, r->VarL_Offset[j]);
+  PrintLn();
+
+
+  PrintS("VarOffset:\n");
+  if (r->VarOffset==NULL) PrintS(" NULL\n");
+  else
+    for(j=0;j<=r->N;j++)
+      Print("  v%d at e-pos %d, bit %d\n",
+            j,r->VarOffset[j] & 0xffffff, r->VarOffset[j] >>24);
+  PrintS("ordsgn:\n");
+  for(j=0;j<r->CmpL_Size;j++)
+    Print("  ordsgn %ld at pos %d\n",r->ordsgn[j],j);
+  Print("OrdSgn:%d\n",r->OrdSgn);
+  PrintS("ordrec:\n");
+  for(j=0;j<r->OrdSize;j++)
+  {
+    Print("  typ %s", TYP[r->typ[j].ord_typ]);
+    if (r->typ[j].ord_typ==ro_syz)
+    {
+      const short place = r->typ[j].data.syz.place;
+      const int limit = r->typ[j].data.syz.limit;
+      const int curr_index = r->typ[j].data.syz.curr_index;
+      const int* syz_index = r->typ[j].data.syz.syz_index;
+
+      Print("  limit %d (place: %d, curr_index: %d), syz_index: ", limit, place, curr_index);
+
+      if( syz_index == NULL )
+        PrintS("(NULL)");
+      else
+      {
+        Print("{");
+        for( i=0; i <= limit; i++ )
+          Print("%d ", syz_index[i]);
+        Print("}");
+      }
+
+    }
+    else if (r->typ[j].ord_typ==ro_isTemp)
+    {
+      Print("  start (level) %d, suffixpos: %d, VO: ",r->typ[j].data.isTemp.start, r->typ[j].data.isTemp.suffixpos);
+
+    }
+    else if (r->typ[j].ord_typ==ro_is)
+    {
+      Print("  start %d, end: %d: ",r->typ[j].data.is.start, r->typ[j].data.is.end);
+
+//      for( int k = 0; k <= r->N; k++) if (r->typ[j].data.is.pVarOffset[k] != -1) Print("[%2d]: %04x; ", k, r->typ[j].data.is.pVarOffset[k]);
+
+      Print("  limit %d",r->typ[j].data.is.limit);
+#ifndef SING_NDEBUG
+      //PrintS("  F: ");idShow(r->typ[j].data.is.F, r, r, 1);
+#endif
+
+      PrintLn();
+    }
+    else if  (r->typ[j].ord_typ==ro_am)
+    {
+      Print("  place %d",r->typ[j].data.am.place);
+      Print("  start %d",r->typ[j].data.am.start);
+      Print("  end %d",r->typ[j].data.am.end);
+      Print("  len_gen %d",r->typ[j].data.am.len_gen);
+      PrintS(" w:");
+      int l=0;
+      for(l=r->typ[j].data.am.start;l<=r->typ[j].data.am.end;l++)
+            Print(" %d",r->typ[j].data.am.weights[l-r->typ[j].data.am.start]);
+      l=r->typ[j].data.am.end+1;
+      int ll=r->typ[j].data.am.weights[l-r->typ[j].data.am.start];
+      PrintS(" m:");
+      for(int lll=l+1;lll<l+ll+1;lll++)
+            Print(" %d",r->typ[j].data.am.weights[lll-r->typ[j].data.am.start]);
+    }
+    else
+    {
+      Print("  place %d",r->typ[j].data.dp.place);
+
+      if (r->typ[j].ord_typ!=ro_syzcomp  && r->typ[j].ord_typ!=ro_syz)
+      {
+        Print("  start %d",r->typ[j].data.dp.start);
+        Print("  end %d",r->typ[j].data.dp.end);
+        if ((r->typ[j].ord_typ==ro_wp)
+        || (r->typ[j].ord_typ==ro_wp_neg))
+        {
+          PrintS(" w:");
+          for(int l=r->typ[j].data.wp.start;l<=r->typ[j].data.wp.end;l++)
+            Print(" %d",r->typ[j].data.wp.weights[l-r->typ[j].data.wp.start]);
+        }
+        else if (r->typ[j].ord_typ==ro_wp64)
+        {
+          PrintS(" w64:");
+          int l;
+          for(l=r->typ[j].data.wp64.start;l<=r->typ[j].data.wp64.end;l++)
+            Print(" %ld",(long)(((int64*)r->typ[j].data.wp64.weights64)+l-r->typ[j].data.wp64.start));
+          }
+        }
+    }
+    PrintLn();
+  }
+  Print("pOrdIndex:%d pCompIndex:%d\n", r->pOrdIndex, r->pCompIndex);
+  Print("OrdSize:%d\n",r->OrdSize);
+  PrintS("--------------------\n");
+  for(j=0;j<r->ExpL_Size;j++)
+  {
+    Print("L[%d]: ",j);
+    if (j< r->CmpL_Size)
+      Print("ordsgn %ld ", r->ordsgn[j]);
+    else
+      PrintS("no comp ");
+    i=1;
+    for(;i<=r->N;i++)
+    {
+      if( (r->VarOffset[i] & 0xffffff) == j )
+      {  Print("v%d at e[%d], bit %d; ", i,r->VarOffset[i] & 0xffffff,
+                                         r->VarOffset[i] >>24 ); }
+    }
+    if( r->pCompIndex==j ) PrintS("v0; ");
+    for(i=0;i<r->OrdSize;i++)
+    {
+      if (r->typ[i].data.dp.place == j)
+      {
+        Print("ordrec:%s (start:%d, end:%d) ",TYP[r->typ[i].ord_typ],
+          r->typ[i].data.dp.start, r->typ[i].data.dp.end);
+      }
+    }
+
+    if (j==r->pOrdIndex)
+      PrintS("pOrdIndex\n");
+    else
+      PrintLn();
+  }
+  Print("LexOrder:%d, MixedOrder:%d\n",r->LexOrder, r->MixedOrder);
+
+  Print("NegWeightL_Size: %d, NegWeightL_Offset: ", r->NegWeightL_Size);
+  if (r->NegWeightL_Offset==NULL) PrintS(" NULL");
+  else
+    for(j = 0; j < r->NegWeightL_Size; j++)
+      Print("  [%d]: %d ", j, r->NegWeightL_Offset[j]);
+  PrintLn();
+
+  // p_Procs stuff
+  p_Procs_s proc_names;
+  const char* field;
+  const char* length;
+  const char* ord;
+  p_Debug_GetProcNames(r, &proc_names); // changes p_Procs!!!
+  p_Debug_GetSpecNames(r, field, length, ord);
+
+  Print("p_Spec  : %s, %s, %s\n", field, length, ord);
+  PrintS("p_Procs :\n");
+  for (i=0; i<(int) (sizeof(p_Procs_s)/sizeof(void*)); i++)
+  {
+    Print(" %s,\n", ((char**) &proc_names)[i]);
+  }
+
+  {
+      PrintLn();
+      Print("pFDeg   : ");
+#define pFDeg_CASE(A) if(r->pFDeg == A) PrintS( "" #A "" )
+      pFDeg_CASE(p_Totaldegree); else
+      pFDeg_CASE(p_WFirstTotalDegree); else
+      pFDeg_CASE(p_WTotaldegree); else
+      pFDeg_CASE(p_Deg); else
+#undef pFDeg_CASE
+      Print("(%p)", r->pFDeg); // default case
+
+    PrintLn();
+    Print("pLDeg   : (%p)", r->pLDeg);
+    PrintLn();
+  }
+  Print("pSetm:");
+  void p_Setm_Dummy(poly p, const ring r);
+  void p_Setm_TotalDegree(poly p, const ring r);
+  void p_Setm_WFirstTotalDegree(poly p, const ring r);
+  void p_Setm_General(poly p, const ring r);
+  if (r->p_Setm==p_Setm_General) PrintS("p_Setm_General\n");
+  else if (r->p_Setm==p_Setm_Dummy) PrintS("p_Setm_Dummy\n");
+  else if (r->p_Setm==p_Setm_TotalDegree) PrintS("p_Setm_Totaldegree\n");
+  else if (r->p_Setm==p_Setm_WFirstTotalDegree) PrintS("p_Setm_WFirstTotalDegree\n");
+  else Print("%p\n",r->p_Setm);
+}
+
+void p_DebugPrint(poly p, const ring r)
+{
+  int i,j;
+  p_Write(p,r);
+  j=2;
+  while(p!=NULL)
+  {
+    Print("\nexp[0..%d]\n",r->ExpL_Size-1);
+    for(i=0;i<r->ExpL_Size;i++)
+      Print("%ld ",p->exp[i]);
+    PrintLn();
+    Print("v0:%ld ",p_GetComp(p, r));
+    for(i=1;i<=r->N;i++) Print(" v%d:%ld",i,p_GetExp(p,i, r));
+    PrintLn();
+    pIter(p);
+    j--;
+    if (j==0) { PrintS("...\n"); break; }
+  }
+}
+
+#endif // RDEBUG
+
+/// debug-print monomial poly/vector p, assuming that it lives in the ring R
+static inline void m_DebugPrint(const poly p, const ring R)
+{
+  Print("\nexp[0..%d]\n", R->ExpL_Size - 1);
+  for(int i = 0; i < R->ExpL_Size; i++)
+    Print("%09lx ", p->exp[i]);
+  PrintLn();
+  Print("v0:%9ld ", p_GetComp(p, R));
+  for(int i = 1; i <= R->N; i++) Print(" v%d:%5ld",i, p_GetExp(p, i, R));
+  PrintLn();
+}
+
+
+#ifndef SING_NDEBUG
+/// debug-print at most nTerms (2 by default) terms from poly/vector p,
+/// assuming that lt(p) lives in lmRing and tail(p) lives in tailRing.
+void p_DebugPrint(const poly p, const ring lmRing, const ring tailRing, const int nTerms)
+{
+  assume( nTerms >= 0 );
+  if( p != NULL )
+  {
+    assume( p != NULL );
+
+    p_Write(p, lmRing, tailRing);
+
+    if( (p != NULL) && (nTerms > 0) )
+    {
+      assume( p != NULL );
+      assume( nTerms > 0 );
+
+      // debug pring leading term
+      m_DebugPrint(p, lmRing);
+
+      poly q = pNext(p); // q = tail(p)
+
+      // debug pring tail (at most nTerms-1 terms from it)
+      for(int j = nTerms - 1; (q !=NULL) && (j > 0); pIter(q), --j)
+        m_DebugPrint(q, tailRing);
+
+      if (q != NULL)
+        PrintS("...\n");
+    }
+  }
+  else
+    PrintS("0\n");
+}
+#endif
+
+
+//    F = system("ISUpdateComponents", F, V, MIN );
+//    // replace gen(i) -> gen(MIN + V[i-MIN]) for all i > MIN in all terms from F!
+void pISUpdateComponents(ideal F, const intvec *const V, const int MIN, const ring r )
+{
+  assume( V != NULL );
+  assume( MIN >= 0 );
+
+  if( F == NULL )
+    return;
+
+  for( int j = (F->ncols*F->nrows) - 1; j >= 0; j-- )
+  {
+#ifdef PDEBUG
+    Print("F[%d]:", j);
+    p_DebugPrint(F->m[j], r, r, 0);
+#endif
+
+    for( poly p = F->m[j]; p != NULL; pIter(p) )
+    {
+      int c = p_GetComp(p, r);
+
+      if( c > MIN )
+      {
+#ifdef PDEBUG
+        Print("gen[%d] -> gen(%d)\n", c, MIN + (*V)[ c - MIN - 1 ]);
+#endif
+
+        p_SetComp( p, MIN + (*V)[ c - MIN - 1 ], r );
+      }
+    }
+#ifdef PDEBUG
+    Print("new F[%d]:", j);
+    p_Test(F->m[j], r);
+    p_DebugPrint(F->m[j], r, r, 0);
+#endif
+  }
+
+}
+
+
+
+
+/*2
+* asssume that rComplete was called with r
+* assume that the first block ist ringorder_S
+* change the block to reflect the sequence given by appending v
+*/
+static inline void rNChangeSComps(int* currComponents, long* currShiftedComponents, ring r)
+{
+  assume(r->typ[1].ord_typ == ro_syzcomp);
+
+  r->typ[1].data.syzcomp.ShiftedComponents = currShiftedComponents;
+  r->typ[1].data.syzcomp.Components = currComponents;
+}
+
+static inline void rNGetSComps(int** currComponents, long** currShiftedComponents, ring r)
+{
+  assume(r->typ[1].ord_typ == ro_syzcomp);
+
+  *currShiftedComponents = r->typ[1].data.syzcomp.ShiftedComponents;
+  *currComponents =   r->typ[1].data.syzcomp.Components;
+}
+#ifdef PDEBUG
+static inline void rDBChangeSComps(int* currComponents,
+                     long* currShiftedComponents,
+                     int length,
+                     ring r)
+{
+  assume(r->typ[1].ord_typ == ro_syzcomp);
+
+  r->typ[1].data.syzcomp.length = length;
+  rNChangeSComps( currComponents, currShiftedComponents, r);
+}
+static inline void rDBGetSComps(int** currComponents,
+                 long** currShiftedComponents,
+                 int *length,
+                 ring r)
+{
+  assume(r->typ[1].ord_typ == ro_syzcomp);
+
+  *length = r->typ[1].data.syzcomp.length;
+  rNGetSComps( currComponents, currShiftedComponents, r);
+}
+#endif
+
+void rChangeSComps(int* currComponents, long* currShiftedComponents, int length, ring r)
+{
+#ifdef PDEBUG
+   rDBChangeSComps(currComponents, currShiftedComponents, length, r);
+#else
+   rNChangeSComps(currComponents, currShiftedComponents, r);
+#endif
+}
+
+void rGetSComps(int** currComponents, long** currShiftedComponents, int *length, ring r)
+{
+#ifdef PDEBUG
+   rDBGetSComps(currComponents, currShiftedComponents, length, r);
+#else
+   rNGetSComps(currComponents, currShiftedComponents, r);
+#endif
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// The following routines all take as input a ring r, and return R
+// where R has a certain property. R might be equal r in which case r
+// had already this property
+//
+ring rAssure_SyzComp(const ring r, BOOLEAN complete)
+{
+  if ( r->order[0] == ringorder_s ) return r;
+
+  if ( r->order[0] == ringorder_IS )
+  {
+#ifndef SING_NDEBUG
+    WarnS("rAssure_SyzComp: input ring has an IS-ordering!");
+#endif
+//    return r;
+  }
+  ring res=rCopy0(r, FALSE, FALSE);
+  int i=rBlocks(r);
+  int j;
+
+  res->order=(int *)omAlloc((i+1)*sizeof(int));
+  res->block0=(int *)omAlloc0((i+1)*sizeof(int));
+  res->block1=(int *)omAlloc0((i+1)*sizeof(int));
+  int ** wvhdl =(int **)omAlloc0((i+1)*sizeof(int**));
+  for(j=i;j>0;j--)
+  {
+    res->order[j]=r->order[j-1];
+    res->block0[j]=r->block0[j-1];
+    res->block1[j]=r->block1[j-1];
+    if (r->wvhdl[j-1] != NULL)
+    {
+      wvhdl[j] = (int*) omMemDup(r->wvhdl[j-1]);
+    }
+  }
+  res->order[0]=ringorder_s;
+
+  res->wvhdl = wvhdl;
+
+  if (complete)
+  {
+    rComplete(res, 1);
+
+#ifdef HAVE_PLURAL
+    if (rIsPluralRing(r))
+    {
+      if ( nc_rComplete(r, res, false) ) // no qideal!
+      {
+#ifndef SING_NDEBUG
+        WarnS("error in nc_rComplete");      // cleanup?//      rDelete(res);//      return r;      // just go on..
+#endif
+      }
+    }
+    assume(rIsPluralRing(r) == rIsPluralRing(res));
+#endif
+
+
+#ifdef HAVE_PLURAL
+    ring old_ring = r;
+#endif
+
+    if (r->qideal!=NULL)
+    {
+      res->qideal= idrCopyR_NoSort(r->qideal, r, res);
+
+      assume(id_RankFreeModule(res->qideal, res) == 0);
+
+#ifdef HAVE_PLURAL
+      if( rIsPluralRing(res) )
+        if( nc_SetupQuotient(res, r, true) )
+        {
+//          WarnS("error in nc_SetupQuotient"); // cleanup?      rDelete(res);       return r;  // just go on...?
+        }
+
+#endif
+      assume(id_RankFreeModule(res->qideal, res) == 0);
+    }
+
+#ifdef HAVE_PLURAL
+    assume((res->qideal==NULL) == (old_ring->qideal==NULL));
+    assume(rIsPluralRing(res) == rIsPluralRing(old_ring));
+    assume(rIsSCA(res) == rIsSCA(old_ring));
+    assume(ncRingType(res) == ncRingType(old_ring));
+#endif
+  }
+
+  return res;
+}
+
+ring rAssure_TDeg(ring r, int start_var, int end_var, int &pos)
+{
+  int i;
+  if (r->typ!=NULL)
+  {
+    for(i=r->OrdSize-1;i>=0;i--)
+    {
+      if ((r->typ[i].ord_typ==ro_dp)
+      && (r->typ[i].data.dp.start==start_var)
+      && (r->typ[i].data.dp.end==end_var))
+      {
+        pos=r->typ[i].data.dp.place;
+        //printf("no change, pos=%d\n",pos);
+        return r;
+      }
+    }
+  }
+
+#ifdef HAVE_PLURAL
+  nc_struct* save=r->GetNC();
+  r->GetNC()=NULL;
+#endif
+  ring res=rCopy(r);
+
+  i=rBlocks(r);
+  int j;
+
+  res->ExpL_Size=r->ExpL_Size+1; // one word more in each monom
+  res->PolyBin=omGetSpecBin(POLYSIZE + (res->ExpL_Size)*sizeof(long));
+  omFree((ADDRESS)res->ordsgn);
+  res->ordsgn=(long *)omAlloc0(res->ExpL_Size*sizeof(long));
+  for(j=0;j<r->CmpL_Size;j++)
+  {
+    res->ordsgn[j] = r->ordsgn[j];
+  }
+  res->OrdSize=r->OrdSize+1;   // one block more for pSetm
+  if (r->typ!=NULL)
+    omFree((ADDRESS)res->typ);
+  res->typ=(sro_ord*)omAlloc0(res->OrdSize*sizeof(sro_ord));
+  if (r->typ!=NULL)
+    memcpy(res->typ,r->typ,r->OrdSize*sizeof(sro_ord));
+  // the additional block for pSetm: total degree at the last word
+  // but not included in the compare part
+  res->typ[res->OrdSize-1].ord_typ=ro_dp;
+  res->typ[res->OrdSize-1].data.dp.start=start_var;
+  res->typ[res->OrdSize-1].data.dp.end=end_var;
+  res->typ[res->OrdSize-1].data.dp.place=res->ExpL_Size-1;
+  pos=res->ExpL_Size-1;
+  //if ((start_var==1) && (end_var==res->N)) res->pOrdIndex=pos;
+  extern void p_Setm_General(poly p, ring r);
+  res->p_Setm=p_Setm_General;
+  // ----------------------------
+  omFree((ADDRESS)res->p_Procs);
+  res->p_Procs = (p_Procs_s*)omAlloc(sizeof(p_Procs_s));
+
+  p_ProcsSet(res, res->p_Procs);
+  if (res->qideal!=NULL) id_Delete(&res->qideal,res);
+#ifdef HAVE_PLURAL
+  r->GetNC()=save;
+  if (rIsPluralRing(r))
+  {
+    if ( nc_rComplete(r, res, false) ) // no qideal!
+    {
+#ifndef SING_NDEBUG
+      WarnS("error in nc_rComplete");
+#endif
+      // just go on..
+    }
+  }
+#endif
+  if (r->qideal!=NULL)
+  {
+     res->qideal=idrCopyR_NoSort(r->qideal,r, res);
+#ifdef HAVE_PLURAL
+     if (rIsPluralRing(res))
+     {
+//       nc_SetupQuotient(res, currRing);
+       nc_SetupQuotient(res, r); // ?
+     }
+     assume((res->qideal==NULL) == (r->qideal==NULL));
+#endif
+  }
+
+#ifdef HAVE_PLURAL
+  assume(rIsPluralRing(res) == rIsPluralRing(r));
+  assume(rIsSCA(res) == rIsSCA(r));
+  assume(ncRingType(res) == ncRingType(r));
+#endif
+
+  return res;
+}
+
+ring rAssure_HasComp(const ring r)
+{
+  int last_block;
+  int i=0;
+  do
+  {
+     if (r->order[i] == ringorder_c ||
+        r->order[i] == ringorder_C) return r;
+     if (r->order[i] == 0)
+        break;
+     i++;
+  } while (1);
+  //WarnS("re-creating ring with comps");
+  last_block=i-1;
+
+  ring new_r = rCopy0(r, FALSE, FALSE);
+  i+=2;
+  new_r->wvhdl=(int **)omAlloc0(i * sizeof(int *));
+  new_r->order   = (int *) omAlloc0(i * sizeof(int));
+  new_r->block0   = (int *) omAlloc0(i * sizeof(int));
+  new_r->block1   = (int *) omAlloc0(i * sizeof(int));
+  memcpy(new_r->order,r->order,(i-1) * sizeof(int));
+  memcpy(new_r->block0,r->block0,(i-1) * sizeof(int));
+  memcpy(new_r->block1,r->block1,(i-1) * sizeof(int));
+  for (int j=0; j<=last_block; j++)
+  {
+    if (r->wvhdl[j]!=NULL)
+    {
+      new_r->wvhdl[j] = (int*) omMemDup(r->wvhdl[j]);
+    }
+  }
+  last_block++;
+  new_r->order[last_block]=ringorder_C;
+  //new_r->block0[last_block]=0;
+  //new_r->block1[last_block]=0;
+  //new_r->wvhdl[last_block]=NULL;
+
+  rComplete(new_r, 1);
+
+#ifdef HAVE_PLURAL
+  if (rIsPluralRing(r))
+  {
+    if ( nc_rComplete(r, new_r, false) ) // no qideal!
+    {
+#ifndef SING_NDEBUG
+      WarnS("error in nc_rComplete");      // cleanup?//      rDelete(res);//      return r;      // just go on..
+#endif
+    }
+  }
+  assume(rIsPluralRing(r) == rIsPluralRing(new_r));
+#endif
+
+  return new_r;
+}
+
+ring rAssure_CompLastBlock(ring r, BOOLEAN complete)
+{
+  int last_block = rBlocks(r) - 2;
+  if (r->order[last_block] != ringorder_c &&
+      r->order[last_block] != ringorder_C)
+  {
+    int c_pos = 0;
+    int i;
+
+    for (i=0; i< last_block; i++)
+    {
+      if (r->order[i] == ringorder_c || r->order[i] == ringorder_C)
+      {
+        c_pos = i;
+        break;
+      }
+    }
+    if (c_pos != -1)
+    {
+      ring new_r = rCopy0(r, FALSE, TRUE);
+      for (i=c_pos+1; i<=last_block; i++)
+      {
+        new_r->order[i-1] = new_r->order[i];
+        new_r->block0[i-1] = new_r->block0[i];
+        new_r->block1[i-1] = new_r->block1[i];
+        new_r->wvhdl[i-1] = new_r->wvhdl[i];
+      }
+      new_r->order[last_block] = r->order[c_pos];
+      new_r->block0[last_block] = r->block0[c_pos];
+      new_r->block1[last_block] = r->block1[c_pos];
+      new_r->wvhdl[last_block] = r->wvhdl[c_pos];
+      if (complete)
+      {
+        rComplete(new_r, 1);
+
+#ifdef HAVE_PLURAL
+        if (rIsPluralRing(r))
+        {
+          if ( nc_rComplete(r, new_r, false) ) // no qideal!
+          {
+#ifndef SING_NDEBUG
+            WarnS("error in nc_rComplete");   // cleanup?//      rDelete(res);//      return r;      // just go on..
+#endif
+          }
+        }
+        assume(rIsPluralRing(r) == rIsPluralRing(new_r));
+#endif
+      }
+      return new_r;
+    }
+  }
+  return r;
+}
+
+// Moves _c or _C ordering to the last place AND adds _s on the 1st place
+ring rAssure_SyzComp_CompLastBlock(const ring r, BOOLEAN)
+{
+  rTest(r);
+
+  ring new_r_1 = rAssure_CompLastBlock(r, FALSE); // due to this FALSE - no completion!
+  ring new_r = rAssure_SyzComp(new_r_1, FALSE); // new_r_1 is used only here!!!
+
+  if (new_r == r)
+     return r;
+
+  ring old_r = r;
+  if (new_r_1 != new_r && new_r_1 != old_r) rDelete(new_r_1);
+
+   rComplete(new_r, 1);
+#ifdef HAVE_PLURAL
+   if (rIsPluralRing(old_r))
+   {
+       if ( nc_rComplete(old_r, new_r, false) ) // no qideal!
+       {
+# ifndef SING_NDEBUG
+          WarnS("error in nc_rComplete"); // cleanup?      rDelete(res);       return r;  // just go on...?
+# endif
+       }
+   }
+#endif
+
+///?    rChangeCurrRing(new_r);
+   if (old_r->qideal != NULL)
+   {
+      new_r->qideal = idrCopyR(old_r->qideal, old_r, new_r);
+   }
+
+#ifdef HAVE_PLURAL
+   if( rIsPluralRing(old_r) )
+     if( nc_SetupQuotient(new_r, old_r, true) )
+       {
+#ifndef SING_NDEBUG
+          WarnS("error in nc_SetupQuotient"); // cleanup?      rDelete(res);       return r;  // just go on...?
+#endif
+       }
+#endif
+
+#ifdef HAVE_PLURAL
+   assume((new_r->qideal==NULL) == (old_r->qideal==NULL));
+   assume(rIsPluralRing(new_r) == rIsPluralRing(old_r));
+   assume(rIsSCA(new_r) == rIsSCA(old_r));
+   assume(ncRingType(new_r) == ncRingType(old_r));
+#endif
+
+   rTest(new_r);
+   rTest(old_r);
+   return new_r;
+}
+
+// use this for global orderings consisting of two blocks
+static ring rAssure_Global(rRingOrder_t b1, rRingOrder_t b2, const ring r)
+{
+  int r_blocks = rBlocks(r);
+
+  assume(b1 == ringorder_c || b1 == ringorder_C ||
+         b2 == ringorder_c || b2 == ringorder_C ||
+         b2 == ringorder_S);
+  if ((r_blocks == 3) &&
+      (r->order[0] == b1) &&
+      (r->order[1] == b2) &&
+      (r->order[2] == 0))
+    return r;
+  ring res = rCopy0(r, TRUE, FALSE);
+  res->order = (int*)omAlloc0(3*sizeof(int));
+  res->block0 = (int*)omAlloc0(3*sizeof(int));
+  res->block1 = (int*)omAlloc0(3*sizeof(int));
+  res->wvhdl = (int**)omAlloc0(3*sizeof(int*));
+  res->order[0] = b1;
+  res->order[1] = b2;
+  if (b1 == ringorder_c || b1 == ringorder_C)
+  {
+    res->block0[1] = 1;
+    res->block1[1] = r->N;
+  }
+  else
+  {
+    res->block0[0] = 1;
+    res->block1[0] = r->N;
+  }
+  rComplete(res, 1);
+#ifdef HAVE_PLURAL
+  if (rIsPluralRing(r))
+  {
+    if ( nc_rComplete(r, res, false) ) // no qideal!
+    {
+#ifndef SING_NDEBUG
+      WarnS("error in nc_rComplete");
+#endif
+    }
+  }
+#endif
+//  rChangeCurrRing(res);
+  return res;
+}
+
+ring rAssure_InducedSchreyerOrdering(const ring r, BOOLEAN complete = TRUE, int sgn = 1)
+{ // TODO: ???? Add leading Syz-comp ordering here...????
+
+#if MYTEST
+    Print("rAssure_InducedSchreyerOrdering(r, complete = %d, sgn = %d): r: \n", complete, sgn);
+    rWrite(r);
+#ifdef RDEBUG
+    rDebugPrint(r);
+#endif
+    PrintLn();
+#endif
+  assume((sgn == 1) || (sgn == -1));
+
+  ring res=rCopy0(r, FALSE, FALSE); // No qideal & ordering copy.
+
+  int n = rBlocks(r); // Including trailing zero!
+
+  // Create 2 more blocks for prefix/suffix:
+  res->order=(int *)omAlloc0((n+2)*sizeof(int)); // 0  ..  n+1
+  res->block0=(int *)omAlloc0((n+2)*sizeof(int));
+  res->block1=(int *)omAlloc0((n+2)*sizeof(int));
+  int ** wvhdl =(int **)omAlloc0((n+2)*sizeof(int**));
+
+  // Encapsulate all existing blocks between induced Schreyer ordering markers: prefix and suffix!
+  // Note that prefix and suffix have the same ringorder marker and only differ in block[] parameters!
+
+  // new 1st block
+  int j = 0;
+  res->order[j] = ringorder_IS; // Prefix
+  res->block0[j] = res->block1[j] = 0;
+  // wvhdl[j] = NULL;
+  j++;
+
+  for(int i = 0; (i <= n) && (r->order[i] != 0); i++, j++) // i = [0 .. n-1] <- non-zero old blocks
+  {
+    res->order [j] = r->order [i];
+    res->block0[j] = r->block0[i];
+    res->block1[j] = r->block1[i];
+
+    if (r->wvhdl[i] != NULL)
+    {
+      wvhdl[j] = (int*) omMemDup(r->wvhdl[i]);
+    } // else wvhdl[j] = NULL;
+  }
+
+  // new last block
+  res->order [j] = ringorder_IS; // Suffix
+  res->block0[j] = res->block1[j] = sgn; // Sign of v[o]: 1 for C, -1 for c
+  // wvhdl[j] = NULL;
+  j++;
+
+  // res->order [j] = 0; // The End!
+  res->wvhdl = wvhdl;
+
+  // j == the last zero block now!
+  assume(j == (n+1));
+  assume(res->order[0]==ringorder_IS);
+  assume(res->order[j-1]==ringorder_IS);
+  assume(res->order[j]==0);
+
+
+  if (complete)
+  {
+    rComplete(res, 1);
+
+#ifdef HAVE_PLURAL
+    if (rIsPluralRing(r))
+    {
+      if ( nc_rComplete(r, res, false) ) // no qideal!
+      {
+#ifndef SING_NDEBUG
+        WarnS("error in nc_rComplete");      // cleanup?//      rDelete(res);//      return r;      // just go on..
+#endif
+      }
+    }
+    assume(rIsPluralRing(r) == rIsPluralRing(res));
+#endif
+
+
+#ifdef HAVE_PLURAL
+    ring old_ring = r;
+#endif
+
+    if (r->qideal!=NULL)
+    {
+      res->qideal= idrCopyR_NoSort(r->qideal, r, res);
+
+      assume(id_RankFreeModule(res->qideal, res) == 0);
+
+#ifdef HAVE_PLURAL
+      if( rIsPluralRing(res) )
+        if( nc_SetupQuotient(res, r, true) )
+        {
+//          WarnS("error in nc_SetupQuotient"); // cleanup?      rDelete(res);       return r;  // just go on...?
+        }
+
+#endif
+      assume(id_RankFreeModule(res->qideal, res) == 0);
+    }
+
+#ifdef HAVE_PLURAL
+    assume((res->qideal==NULL) == (old_ring->qideal==NULL));
+    assume(rIsPluralRing(res) == rIsPluralRing(old_ring));
+    assume(rIsSCA(res) == rIsSCA(old_ring));
+    assume(ncRingType(res) == ncRingType(old_ring));
+#endif
+  }
+
+  return res;
+}
+
+ring rAssure_dp_S(const ring r)
+{
+  return rAssure_Global(ringorder_dp, ringorder_S, r);
+}
+
+ring rAssure_dp_C(const ring r)
+{
+  return rAssure_Global(ringorder_dp, ringorder_C, r);
+}
+
+ring rAssure_C_dp(const ring r)
+{
+  return rAssure_Global(ringorder_C, ringorder_dp, r);
+}
+
+
+
+/// Finds p^th IS ordering, and returns its position in r->typ[]
+/// returns -1 if something went wrong!
+/// p - starts with 0!
+int rGetISPos(const int p, const ring r)
+{
+  // Put the reference set F into the ring -ordering -recor
+#if MYTEST
+  Print("rIsIS(p: %d)\nF:", p);
+  PrintLn();
+#endif
+
+  if (r->typ==NULL)
+  {
+//    dReportError("'rIsIS:' Error: wrong ring! (typ == NULL)");
+    return -1;
+  }
+
+  int j = p; // Which IS record to use...
+  for( int pos = 0; pos < r->OrdSize; pos++ )
+    if( r->typ[pos].ord_typ == ro_is)
+      if( j-- == 0 )
+        return pos;
+
+  return -1;
+}
+
+
+
+
+
+
+/// Changes r by setting induced ordering parameters: limit and reference leading terms
+/// F belong to r, we will DO a copy!
+/// We will use it AS IS!
+/// returns true is everything was allright!
+BOOLEAN rSetISReference(const ring r, const ideal F, const int i, const int p)
+{
+  // Put the reference set F into the ring -ordering -recor
+
+  if (r->typ==NULL)
+  {
+    dReportError("Error: WRONG USE of rSetISReference: wrong ring! (typ == NULL)");
+    return FALSE;
+  }
+
+
+  int pos = rGetISPos(p, r);
+
+  if( pos == -1 )
+  {
+    dReportError("Error: WRONG USE of rSetISReference: specified ordering block was not found!!!" );
+    return FALSE;
+  }
+
+#if MYTEST
+  if( i != r->typ[pos].data.is.limit )
+    Print("Changing record on pos: %d\nOld limit: %d --->> New Limit: %d\n", pos, r->typ[pos].data.is.limit, i);
+#endif
+
+  const ideal FF = idrHeadR(F, r, r); // id_Copy(F, r); // ???
+
+
+  if( r->typ[pos].data.is.F != NULL)
+  {
+#if MYTEST
+    PrintS("Deleting old reference set F... \n");        // idShow(r->typ[pos].data.is.F, r);         PrintLn();
+#endif
+    id_Delete(&r->typ[pos].data.is.F, r);
+    r->typ[pos].data.is.F = NULL;
+  }
+
+  assume(r->typ[pos].data.is.F == NULL);
+
+  r->typ[pos].data.is.F = FF; // F is owened by ring now! TODO: delete at the end!
+
+  r->typ[pos].data.is.limit = i; // First induced component
+
+#if MYTEST
+  PrintS("New reference set FF : \n");        idShow(FF, r, r, 1);         PrintLn();
+#endif
+
+  return TRUE;
+}
+
+#ifdef PDEBUG
+int pDBsyzComp=0;
+#endif
+
+
+void rSetSyzComp(int k, const ring r)
+{
+  if(k < 0)
+  {
+    dReportError("rSetSyzComp with negative limit!");
+    return;
+  }
+
+  assume( k >= 0 );
+  if (TEST_OPT_PROT) Print("{%d}", k);
+  if ((r->typ!=NULL) && (r->typ[0].ord_typ==ro_syz))
+  {
+    if( k == r->typ[0].data.syz.limit )
+      return; // nothing to do
+
+    int i;
+    if (r->typ[0].data.syz.limit == 0)
+    {
+      r->typ[0].data.syz.syz_index = (int*) omAlloc0((k+1)*sizeof(int));
+      r->typ[0].data.syz.syz_index[0] = 0;
+      r->typ[0].data.syz.curr_index = 1;
+    }
+    else
+    {
+      r->typ[0].data.syz.syz_index = (int*)
+        omReallocSize(r->typ[0].data.syz.syz_index,
+                (r->typ[0].data.syz.limit+1)*sizeof(int),
+                (k+1)*sizeof(int));
+    }
+    for (i=r->typ[0].data.syz.limit + 1; i<= k; i++)
+    {
+      r->typ[0].data.syz.syz_index[i] =
+        r->typ[0].data.syz.curr_index;
+    }
+    if(k < r->typ[0].data.syz.limit) // ?
+    {
+#ifndef SING_NDEBUG
+      Warn("rSetSyzComp called with smaller limit (%d) as before (%d)", k, r->typ[0].data.syz.limit);
+#endif
+      r->typ[0].data.syz.curr_index = 1 + r->typ[0].data.syz.syz_index[k];
+    }
+
+
+    r->typ[0].data.syz.limit = k;
+    r->typ[0].data.syz.curr_index++;
+  }
+  else if(
+            (r->typ!=NULL) &&
+            (r->typ[0].ord_typ==ro_isTemp)
+           )
+  {
+//      (r->typ[currRing->typ[0].data.isTemp.suffixpos].data.is.limit == k)
+#ifndef SING_NDEBUG
+    Warn("rSetSyzComp(%d) in an IS ring! Be careful!", k);
+#endif
+  }
+  else
+  if ((r->order[0]!=ringorder_c) && (k!=0)) // ???
+  {
+    dReportError("syzcomp in incompatible ring");
+  }
+#ifdef PDEBUG
+  extern int pDBsyzComp;
+  pDBsyzComp=k;
+#endif
+}
+
+// return the max-comonent wchich has syzIndex i
+int rGetMaxSyzComp(int i, const ring r)
+{
+  if ((r->typ!=NULL) && (r->typ[0].ord_typ==ro_syz) &&
+      r->typ[0].data.syz.limit > 0 && i > 0)
+  {
+    assume(i <= r->typ[0].data.syz.limit);
+    int j;
+    for (j=0; j<r->typ[0].data.syz.limit; j++)
+    {
+      if (r->typ[0].data.syz.syz_index[j] == i  &&
+          r->typ[0].data.syz.syz_index[j+1] != i)
+      {
+        assume(r->typ[0].data.syz.syz_index[j+1] == i+1);
+        return j;
+      }
+    }
+    return r->typ[0].data.syz.limit;
+  }
+  else
+  {
+    return 0;
+  }
+}
+
+BOOLEAN rRing_is_Homog(ring r)
+{
+  if (r == NULL) return FALSE;
+  int i, j, nb = rBlocks(r);
+  for (i=0; i<nb; i++)
+  {
+    if (r->wvhdl[i] != NULL)
+    {
+      int length = r->block1[i] - r->block0[i];
+      int* wvhdl = r->wvhdl[i];
+      if (r->order[i] == ringorder_M) length *= length;
+      assume(omSizeOfAddr(wvhdl) >= length*sizeof(int));
+
+      for (j=0; j< length; j++)
+      {
+        if (wvhdl[j] != 0 && wvhdl[j] != 1) return FALSE;
+      }
+    }
+  }
+  return TRUE;
+}
+
+BOOLEAN rRing_has_CompLastBlock(ring r)
+{
+  assume(r != NULL);
+  int lb = rBlocks(r) - 2;
+  return (r->order[lb] == ringorder_c || r->order[lb] == ringorder_C);
+}
+
+n_coeffType rFieldType(ring r)
+{
+  return (r->cf->type);
+  if (rField_is_Zp(r))     return n_Zp;
+  if (rField_is_Q(r))      return n_Q;
+  if (rField_is_R(r))      return n_R;
+  if (rField_is_GF(r))     return n_GF;
+  if (rField_is_long_R(r)) return n_long_R;
+  if (rField_is_Zp_a(r))   return getCoeffType(r->cf);
+  if (rField_is_Q_a(r))    return getCoeffType(r->cf);
+  if (rField_is_long_C(r)) return n_long_C;
+  #ifdef HAVE_RINGS
+   if (rField_is_Ring_Z(r)) return n_Z;
+   if (rField_is_Ring_ModN(r)) return n_Zn;
+   if (rField_is_Ring_PtoM(r)) return n_Znm;
+   if (rField_is_Ring_2toM(r)) return  n_Z2m;
+  #endif
+
+  return n_unknown;
+}
+
+int64 * rGetWeightVec(ring r)
+{
+  assume(r!=NULL);
+  assume(r->OrdSize>0);
+  int i=0;
+  while((r->typ[i].ord_typ!=ro_wp64) && (r->typ[i].ord_typ>0)) i++;
+  assume(r->typ[i].ord_typ==ro_wp64);
+  return (int64*)(r->typ[i].data.wp64.weights64);
+}
+
+void rSetWeightVec(ring r, int64 *wv)
+{
+  assume(r!=NULL);
+  assume(r->OrdSize>0);
+  assume(r->typ[0].ord_typ==ro_wp64);
+  memcpy(r->typ[0].data.wp64.weights64,wv,r->N*sizeof(int64));
+}
+
+#include <ctype.h>
+
+static int rRealloc1(ring r, int size, int pos)
+{
+  r->order=(int*)omReallocSize(r->order, size*sizeof(int), (size+1)*sizeof(int));
+  r->block0=(int*)omReallocSize(r->block0, size*sizeof(int), (size+1)*sizeof(int));
+  r->block1=(int*)omReallocSize(r->block1, size*sizeof(int), (size+1)*sizeof(int));
+  r->wvhdl=(int **)omReallocSize(r->wvhdl,size*sizeof(int *), (size+1)*sizeof(int *));
+  for(int k=size; k>pos; k--) r->wvhdl[k]=r->wvhdl[k-1];
+  r->order[size]=0;
+  size++;
+  return size;
+}
+#if 0 // currently unused
+static int rReallocM1(ring r, int size, int pos)
+{
+  r->order=(int*)omReallocSize(r->order, size*sizeof(int), (size-1)*sizeof(int));
+  r->block0=(int*)omReallocSize(r->block0, size*sizeof(int), (size-1)*sizeof(int));
+  r->block1=(int*)omReallocSize(r->block1, size*sizeof(int), (size-1)*sizeof(int));
+  r->wvhdl=(int **)omReallocSize(r->wvhdl,size*sizeof(int *), (size-1)*sizeof(int *));
+  for(int k=pos+1; k<size; k++) r->wvhdl[k]=r->wvhdl[k+1];
+  size--;
+  return size;
+}
+#endif
+static void rOppWeight(int *w, int l)
+{
+  int i2=(l+1)/2;
+  for(int j=0; j<=i2; j++)
+  {
+    int t=w[j];
+    w[j]=w[l-j];
+    w[l-j]=t;
+  }
+}
+
+#define rOppVar(R,I) (rVar(R)+1-I)
+
+ring rOpposite(ring src)
+  /* creates an opposite algebra of R */
+  /* that is R^opp, where f (*^opp) g = g*f  */
+  /* treats the case of qring */
+{
+  if (src == NULL) return(NULL);
+
+#ifdef RDEBUG
+  rTest(src);
+#endif
+
+  //rChangeCurrRing(src);
+
+#ifdef RDEBUG
+  rTest(src);
+//  rWrite(src);
+//  rDebugPrint(src);
+#endif
+
+
+  ring r = rCopy0(src,FALSE); /* qideal will be deleted later on!!! */
+
+  // change vars v1..vN -> vN..v1
+  int i;
+  int i2 = (rVar(r)-1)/2;
+  for(i=i2; i>=0; i--)
+  {
+    // index: 0..N-1
+    //Print("ex var names: %d <-> %d\n",i,rOppVar(r,i));
+    // exchange names
+    char *p;
+    p = r->names[rVar(r)-1-i];
+    r->names[rVar(r)-1-i] = r->names[i];
+    r->names[i] = p;
+  }
+//  i2=(rVar(r)+1)/2;
+//  for(int i=i2; i>0; i--)
+//  {
+//    // index: 1..N
+//    //Print("ex var places: %d <-> %d\n",i,rVar(r)+1-i);
+//    // exchange VarOffset
+//    int t;
+//    t=r->VarOffset[i];
+//    r->VarOffset[i]=r->VarOffset[rOppVar(r,i)];
+//    r->VarOffset[rOppVar(r,i)]=t;
+//  }
+  // change names:
+  for (i=rVar(r)-1; i>=0; i--)
+  {
+    char *p=r->names[i];
+    if(isupper(*p)) *p = tolower(*p);
+    else            *p = toupper(*p);
+  }
+  // change ordering: listing
+  // change ordering: compare
+//  for(i=0; i<r->OrdSize; i++)
+//  {
+//    int t,tt;
+//    switch(r->typ[i].ord_typ)
+//    {
+//      case ro_dp:
+//      //
+//        t=r->typ[i].data.dp.start;
+//        r->typ[i].data.dp.start=rOppVar(r,r->typ[i].data.dp.end);
+//        r->typ[i].data.dp.end=rOppVar(r,t);
+//        break;
+//      case ro_wp:
+//      case ro_wp_neg:
+//      {
+//        t=r->typ[i].data.wp.start;
+//        r->typ[i].data.wp.start=rOppVar(r,r->typ[i].data.wp.end);
+//        r->typ[i].data.wp.end=rOppVar(r,t);
+//        // invert r->typ[i].data.wp.weights
+//        rOppWeight(r->typ[i].data.wp.weights,
+//                   r->typ[i].data.wp.end-r->typ[i].data.wp.start);
+//        break;
+//      }
+//      //case ro_wp64:
+//      case ro_syzcomp:
+//      case ro_syz:
+//         WerrorS("not implemented in rOpposite");
+//         // should not happen
+//         break;
+//
+//      case ro_cp:
+//        t=r->typ[i].data.cp.start;
+//        r->typ[i].data.cp.start=rOppVar(r,r->typ[i].data.cp.end);
+//        r->typ[i].data.cp.end=rOppVar(r,t);
+//        break;
+//      case ro_none:
+//      default:
+//       Werror("unknown type in rOpposite(%d)",r->typ[i].ord_typ);
+//       break;
+//    }
+//  }
+  // Change order/block structures (needed for rPrint, rAdd etc.)
+  int j=0;
+  int l=rBlocks(src);
+  for(i=0; src->order[i]!=0; i++)
+  {
+    switch (src->order[i])
+    {
+      case ringorder_c: /* c-> c */
+      case ringorder_C: /* C-> C */
+      case ringorder_no /*=0*/: /* end-of-block */
+        r->order[j]=src->order[i];
+        j++; break;
+      case ringorder_lp: /* lp -> rp */
+        r->order[j]=ringorder_rp;
+        r->block0[j]=rOppVar(r, src->block1[i]);
+        r->block1[j]=rOppVar(r, src->block0[i]);
+        break;
+      case ringorder_rp: /* rp -> lp */
+        r->order[j]=ringorder_lp;
+        r->block0[j]=rOppVar(r, src->block1[i]);
+        r->block1[j]=rOppVar(r, src->block0[i]);
+        break;
+      case ringorder_dp: /* dp -> a(1..1),ls */
+      {
+        l=rRealloc1(r,l,j);
+        r->order[j]=ringorder_a;
+        r->block0[j]=rOppVar(r, src->block1[i]);
+        r->block1[j]=rOppVar(r, src->block0[i]);
+        r->wvhdl[j]=(int*)omAlloc((r->block1[j]-r->block0[j]+1)*sizeof(int));
+        for(int k=r->block0[j]; k<=r->block1[j]; k++)
+          r->wvhdl[j][k-r->block0[j]]=1;
+        j++;
+        r->order[j]=ringorder_ls;
+        r->block0[j]=rOppVar(r, src->block1[i]);
+        r->block1[j]=rOppVar(r, src->block0[i]);
+        j++;
+        break;
+      }
+      case ringorder_Dp: /* Dp -> a(1..1),rp */
+      {
+        l=rRealloc1(r,l,j);
+        r->order[j]=ringorder_a;
+        r->block0[j]=rOppVar(r, src->block1[i]);
+        r->block1[j]=rOppVar(r, src->block0[i]);
+        r->wvhdl[j]=(int*)omAlloc((r->block1[j]-r->block0[j]+1)*sizeof(int));
+        for(int k=r->block0[j]; k<=r->block1[j]; k++)
+          r->wvhdl[j][k-r->block0[j]]=1;
+        j++;
+        r->order[j]=ringorder_rp;
+        r->block0[j]=rOppVar(r, src->block1[i]);
+        r->block1[j]=rOppVar(r, src->block0[i]);
+        j++;
+        break;
+      }
+      case ringorder_wp: /* wp -> a(...),ls */
+      {
+        l=rRealloc1(r,l,j);
+        r->order[j]=ringorder_a;
+        r->block0[j]=rOppVar(r, src->block1[i]);
+        r->block1[j]=rOppVar(r, src->block0[i]);
+        r->wvhdl[j]=r->wvhdl[j+1]; r->wvhdl[j+1]=NULL;
+        rOppWeight(r->wvhdl[j], r->block1[j]-r->block0[j]);
+        j++;
+        r->order[j]=ringorder_ls;
+        r->block0[j]=rOppVar(r, src->block1[i]);
+        r->block1[j]=rOppVar(r, src->block0[i]);
+        j++;
+        break;
+      }
+      case ringorder_Wp: /* Wp -> a(...),rp */
+      {
+        l=rRealloc1(r,l,j);
+        r->order[j]=ringorder_a;
+        r->block0[j]=rOppVar(r, src->block1[i]);
+        r->block1[j]=rOppVar(r, src->block0[i]);
+        r->wvhdl[j]=r->wvhdl[j+1]; r->wvhdl[j+1]=NULL;
+        rOppWeight(r->wvhdl[j], r->block1[j]-r->block0[j]);
+        j++;
+        r->order[j]=ringorder_rp;
+        r->block0[j]=rOppVar(r, src->block1[i]);
+        r->block1[j]=rOppVar(r, src->block0[i]);
+        j++;
+        break;
+      }
+      case ringorder_M: /* M -> M */
+      {
+        r->order[j]=ringorder_M;
+        r->block0[j]=rOppVar(r, src->block1[i]);
+        r->block1[j]=rOppVar(r, src->block0[i]);
+        int n=r->block1[j]-r->block0[j];
+        /* M is a (n+1)x(n+1) matrix */
+        for (int nn=0; nn<=n; nn++)
+        {
+          rOppWeight(&(r->wvhdl[j][nn*(n+1)]), n /*r->block1[j]-r->block0[j]*/);
+        }
+        j++;
+        break;
+      }
+      case ringorder_a: /*  a(...),ls -> wp/dp */
+      {
+        r->block0[j]=rOppVar(r, src->block1[i]);
+        r->block1[j]=rOppVar(r, src->block0[i]);
+        rOppWeight(r->wvhdl[j], r->block1[j]-r->block0[j]);
+        if (src->order[i+1]==ringorder_ls)
+        {
+          r->order[j]=ringorder_wp;
+          i++;
+          //l=rReallocM1(r,l,j);
+        }
+        else
+        {
+          r->order[j]=ringorder_a;
+        }
+        j++;
+        break;
+      }
+      // not yet done:
+      case ringorder_ls:
+      case ringorder_rs:
+      case ringorder_ds:
+      case ringorder_Ds:
+      case ringorder_ws:
+      case ringorder_Ws:
+      // should not occur:
+      case ringorder_S:
+      case ringorder_IS:
+      case ringorder_s:
+      case ringorder_aa:
+      case ringorder_L:
+      case ringorder_unspec:
+        Werror("order %s not (yet) supported", rSimpleOrdStr(src->order[i]));
+        break;
+    }
+  }
+  rComplete(r);
+
+
+#ifdef RDEBUG
+  rTest(r);
+#endif
+
+  //rChangeCurrRing(r);
+
+#ifdef RDEBUG
+  rTest(r);
+//  rWrite(r);
+//  rDebugPrint(r);
+#endif
+
+
+#ifdef HAVE_PLURAL
+  // now, we initialize a non-comm structure on r
+  if (rIsPluralRing(src))
+  {
+//    assume( currRing == r);
+
+    int *perm       = (int *)omAlloc0((rVar(r)+1)*sizeof(int));
+    int *par_perm   = NULL;
+    nMapFunc nMap   = n_SetMap(src->cf,r->cf);
+    int ni,nj;
+    for(i=1; i<=r->N; i++)
+    {
+      perm[i] = rOppVar(r,i);
+    }
+
+    matrix C = mpNew(rVar(r),rVar(r));
+    matrix D = mpNew(rVar(r),rVar(r));
+
+    for (i=1; i< rVar(r); i++)
+    {
+      for (j=i+1; j<=rVar(r); j++)
+      {
+        ni = r->N +1 - i;
+        nj = r->N +1 - j; /* i<j ==>   nj < ni */
+
+        assume(MATELEM(src->GetNC()->C,i,j) != NULL);
+        MATELEM(C,nj,ni) = p_PermPoly(MATELEM(src->GetNC()->C,i,j),perm,src,r, nMap,par_perm,rPar(src));
+
+        if(MATELEM(src->GetNC()->D,i,j) != NULL)
+          MATELEM(D,nj,ni) = p_PermPoly(MATELEM(src->GetNC()->D,i,j),perm,src,r, nMap,par_perm,rPar(src));
+      }
+    }
+
+    id_Test((ideal)C, r);
+    id_Test((ideal)D, r);
+
+    if (nc_CallPlural(C, D, NULL, NULL, r, false, false, true, r)) // no qring setup!
+      WarnS("Error initializing non-commutative multiplication!");
+
+#ifdef RDEBUG
+    rTest(r);
+//    rWrite(r);
+//    rDebugPrint(r);
+#endif
+
+    assume( r->GetNC()->IsSkewConstant == src->GetNC()->IsSkewConstant);
+
+    omFreeSize((ADDRESS)perm,(rVar(r)+1)*sizeof(int));
+  }
+#endif /* HAVE_PLURAL */
+
+  /* now oppose the qideal for qrings */
+  if (src->qideal != NULL)
+  {
+    id_Delete(&(r->qideal), r);
+
+#ifdef HAVE_PLURAL
+    r->qideal = idOppose(src, src->qideal, r); // into the currRing: r
+#else
+    r->qideal = id_Copy(src->qideal, r); // ?
+#endif
+
+#ifdef HAVE_PLURAL
+    if( rIsPluralRing(r) )
+    {
+      nc_SetupQuotient(r);
+#ifdef RDEBUG
+      rTest(r);
+//      rWrite(r);
+//      rDebugPrint(r);
+#endif
+    }
+#endif
+  }
+#ifdef HAVE_PLURAL
+  if( rIsPluralRing(r) )
+    assume( ncRingType(r) == ncRingType(src) );
+#endif
+  rTest(r);
+
+  return r;
+}
+
+ring rEnvelope(ring R)
+  /* creates an enveloping algebra of R */
+  /* that is R^e = R \tensor_K R^opp */
+{
+  ring Ropp = rOpposite(R);
+  ring Renv = NULL;
+  int stat = rSum(R, Ropp, Renv); /* takes care of qideals */
+  if ( stat <=0 )
+    WarnS("Error in rEnvelope at rSum");
+  rTest(Renv);
+  return Renv;
+}
+
+#ifdef HAVE_PLURAL
+BOOLEAN nc_rComplete(const ring src, ring dest, bool bSetupQuotient)
+/* returns TRUE is there were errors */
+/* dest is actualy equals src with the different ordering */
+/* we map src->nc correctly to dest->src */
+/* to be executed after rComplete, before rChangeCurrRing */
+{
+// NOTE: Originally used only by idElimination to transfer NC structure to dest
+// ring created by dirty hack (without nc_CallPlural)
+  rTest(src);
+
+  assume(!rIsPluralRing(dest)); // destination must be a newly constructed commutative ring
+
+  if (!rIsPluralRing(src))
+  {
+    return FALSE;
+  }
+
+  const int N = dest->N;
+
+  assume(src->N == N);
+
+//  ring save = currRing;
+
+//  if (dest != save)
+//    rChangeCurrRing(dest);
+
+  const ring srcBase = src;
+
+  assume( n_SetMap(srcBase->cf,dest->cf) == n_SetMap(dest->cf,dest->cf) ); // currRing is important here!
+
+  matrix C = mpNew(N,N); // ring independent
+  matrix D = mpNew(N,N);
+
+  matrix C0 = src->GetNC()->C;
+  matrix D0 = src->GetNC()->D;
+
+  // map C and D into dest
+  for (int i = 1; i < N; i++)
+  {
+    for (int j = i + 1; j <= N; j++)
+    {
+      const number n = n_Copy(p_GetCoeff(MATELEM(C0,i,j), srcBase), srcBase->cf); // src, mapping for coeffs into currRing = dest!
+      const poly   p = p_NSet(n, dest);
+      MATELEM(C,i,j) = p;
+      if (MATELEM(D0,i,j) != NULL)
+        MATELEM(D,i,j) = prCopyR(MATELEM(D0,i,j), srcBase, dest); // ?
+    }
+  }
+  /* One must test C and D _only_ in r->GetNC()->basering!!! not in r!!! */
+
+  id_Test((ideal)C, dest);
+  id_Test((ideal)D, dest);
+
+  if (nc_CallPlural(C, D, NULL, NULL, dest, bSetupQuotient, false, true, dest)) // also takes care about quotient ideal
+  {
+    //WarnS("Error transferring non-commutative structure");
+    // error message should be in the interpreter interface
+
+    mp_Delete(&C, dest);
+    mp_Delete(&D, dest);
+
+//    if (currRing != save)
+//       rChangeCurrRing(save);
+
+    return TRUE;
+  }
+
+//  mp_Delete(&C, dest); // used by nc_CallPlural!
+//  mp_Delete(&D, dest);
+
+//  if (dest != save)
+//    rChangeCurrRing(save);
+
+  assume(rIsPluralRing(dest));
+  return FALSE;
+}
+#endif
+
+void rModify_a_to_A(ring r)
+// to be called BEFORE rComplete:
+// changes every Block with a(...) to A(...)
+{
+   int i=0;
+   int j;
+   while(r->order[i]!=0)
+   {
+      if (r->order[i]==ringorder_a)
+      {
+        r->order[i]=ringorder_a64;
+        int *w=r->wvhdl[i];
+        int64 *w64=(int64 *)omAlloc((r->block1[i]-r->block0[i]+1)*sizeof(int64));
+        for(j=r->block1[i]-r->block0[i];j>=0;j--)
+                w64[j]=(int64)w[j];
+        r->wvhdl[i]=(int*)w64;
+        omFreeSize(w,(r->block1[i]-r->block0[i]+1)*sizeof(int));
+      }
+      i++;
+   }
+}
+
+
+poly rGetVar(const int varIndex, const ring r)
+{
+    poly p = p_ISet(1, r);
+    p_SetExp(p, varIndex, 1, r);
+    p_Setm(p, r);
+    return p;
+}
+
+
+/// TODO: rewrite somehow...
+int n_IsParam(const number m, const ring r)
+{
+  assume(r != NULL);
+  const coeffs C = r->cf;
+  assume(C != NULL);
+
+  assume( nCoeff_is_Extension(C) );
+
+  const n_coeffType _filed_type = getCoeffType(C);
+
+  if( _filed_type == n_algExt )
+    return naIsParam(m, C);
+
+  if( _filed_type == n_transExt )
+    return ntIsParam(m, C);
+
+  Werror("n_IsParam: IsParam is not to be used for (coeff_type = %d)",getCoeffType(C));
+
+  return 0;
+}
+
diff --git a/libpolys/polys/monomials/ring.h b/libpolys/polys/monomials/ring.h
new file mode 100644
index 0000000..815d581
--- /dev/null
+++ b/libpolys/polys/monomials/ring.h
@@ -0,0 +1,824 @@
+#ifndef RING_H
+#define RING_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT - the interpreter related ring operations
+*/
+
+/* includes */
+#include <omalloc/omalloc.h>
+#include <misc/auxiliary.h>
+#include <coeffs/coeffs.h>
+//#include <polys/monomials/polys-impl.h>
+//
+
+/* forward declaration of types */
+class idrec; typedef idrec *   idhdl; // _only_ for idhdl ip_sring::idroot
+struct  spolyrec;
+typedef struct spolyrec    polyrec;
+typedef struct spolyrec *         poly;
+typedef struct spolyrec const *   const_poly;
+struct ip_sring;
+typedef struct ip_sring *         ring;
+typedef struct ip_sring const *   const_ring;
+class intvec;
+class int64vec;
+struct p_Procs_s;
+typedef struct p_Procs_s p_Procs_s;
+//class slists;
+//typedef slists *           lists;
+class kBucket;
+typedef kBucket*           kBucket_pt;
+
+struct sip_sideal;
+typedef struct sip_sideal *       ideal;
+typedef struct sip_sideal const * const_ideal;
+
+struct sip_smap;
+typedef struct sip_smap *         map;
+typedef struct sip_smap const *   const_map;
+
+/* the function pointer types */
+
+typedef long     (*pLDegProc)(poly p, int *length, ring r);
+typedef long     (*pFDegProc)(poly p, ring r);
+typedef void     (*p_SetmProc)(poly p, const ring r);
+
+
+/// returns a poly from dest_r which is a ShallowCopy of s_p from source_r
+/// assumes that source_r->N == dest_r->N and that orderings are the same
+typedef poly (*pShallowCopyDeleteProc)(poly s_p, ring source_r, ring dest_r,
+                                       omBin dest_bin);
+
+// ro_typ describes what to store at the corresping "data" place in p->exp
+// none of the directly corresponds to a ring ordering (ringorder_*)
+// as each ringorder_* blocks corrsponds to 0..2 sro-blocks
+typedef enum
+{
+  ro_dp, // total degree with weights 1
+  ro_wp, // total weighted degree with weights>0 in wvhdl
+  ro_am, // weights for vars + weights for gen
+  ro_wp64, // weighted64 degree weights in wvhdl
+  ro_wp_neg, // total weighted degree with weights in Z in wvhdl
+             // (with possibly negative weights)
+  ro_cp,    // ??ordering duplicates variables
+  ro_syzcomp, // ??ordering indicates "subset" of component number (ringorder_S)
+  ro_syz, // component number if <=syzcomp else 0 (ringorder_s)
+  ro_isTemp, ro_is, // ??Induced Syzygy (Schreyer) ordering (and prefix data placeholder dummy) (ringorder_IS)
+  ro_none
+}
+ro_typ;
+
+// ordering is a degree ordering
+struct sro_dp
+{
+  short place;  // where degree is stored (in L):
+  short start;  // bounds of ordering (in E):
+  short end;
+};
+typedef struct sro_dp sro_dp;
+
+// ordering is a weighted degree ordering
+struct sro_wp
+{
+  short place;  // where weighted degree is stored (in L)
+  short start;  // bounds of ordering (in E)
+  short end;
+  int *weights; // pointers into wvhdl field
+};
+typedef struct sro_wp sro_wp;
+
+// ordering is a weighted degree ordering
+struct sro_am
+{
+  short place;  // where weighted degree is stored (in L)
+  short start;  // bounds of ordering (in E)
+  short end;
+  short len_gen; // i>len_gen: weight(gen(i)):=0
+  int *weights; // pointers into wvhdl field of length (end-start+1) + len_gen + 1
+                // contents w_{start},... w_{end}, len, mod_w_1, .. mod_w_len, 0
+  int *weights_m; // pointers into wvhdl field of length len_gen + 1
+                // len_gen, mod_w_1, .. mod_w_len, 0
+
+};
+typedef struct sro_am sro_am;
+
+// ordering is a weighted degree ordering
+struct sro_wp64
+{
+    short place;  // where weighted degree is stored (in L)
+    short start;  // bounds of ordering (in E)
+    short end;
+    int64 *weights64; // pointers into wvhdl field
+};
+typedef struct sro_wp64 sro_wp64;
+
+// ordering duplicates variables
+struct sro_cp
+{
+  short place;  // where start is copied to (in E)
+  short start;  // bounds of sources of copied variables (in E)
+  short end;
+};
+typedef struct sro_cp sro_cp;
+
+// ordering indicates "subset" of component number
+struct sro_syzcomp
+{
+  short place;  // where the index is stored (in L)
+  long *ShiftedComponents; // pointer into index field
+  int* Components;
+#ifdef PDEBUG
+  long length;
+#endif
+};
+typedef struct sro_syzcomp sro_syzcomp;
+
+// ordering  with component number >syzcomp is lower
+struct sro_syz
+{
+  short place;       // where the index is stored (in L)
+  int limit;         // syzcomp
+  int* syz_index;    // mapping Component -> SyzIndex for Comp <= limit
+  int  curr_index;   // SyzIndex for Component > limit
+};
+
+typedef struct sro_syz sro_syz;
+// Induced Syzygy (Schreyer) ordering is built inductively as follows:
+// we look for changes made by ordering blocks which are between prefix/suffix markers:
+// that is: which variables where placed by them and where (judging by v)
+
+// due to prefix/suffix nature we need some placeholder:
+// prefix stores here initial state
+// suffix cleares this up
+struct sro_ISTemp
+{
+  short start; // 1st member SHOULD be short "place"
+  int   suffixpos;
+  int*  pVarOffset; // copy!
+};
+
+// So this is the actuall thing!
+// suffix uses last sro_ISTemp (cleares it up afterwards) and
+// creates this block
+struct sro_IS
+{
+  short start, end;  // which part of L we want to want to update...
+  int*  pVarOffset; // same as prefix!
+
+  int limit; // first referenced component
+
+  // reference poly set?? // Should it be owned by ring?!!!
+  ideal F; // reference leading (module)-monomials set. owned by ring...
+};
+
+typedef struct sro_IS sro_IS;
+typedef struct sro_ISTemp sro_ISTemp;
+
+struct sro_ord
+{
+  ro_typ  ord_typ;
+  int     order_index; // comes from r->order[order_index]
+  union
+  {
+     sro_dp dp;
+     sro_wp wp;
+     sro_am am;
+     sro_wp64 wp64;
+     sro_cp cp;
+     sro_syzcomp syzcomp;
+     sro_syz syz;
+     sro_IS is;
+     sro_ISTemp isTemp;
+  } data;
+};
+
+#ifdef HAVE_PLURAL
+struct nc_struct;
+typedef struct nc_struct   nc_struct;
+#endif
+
+struct ip_sring
+{
+// each entry must have a description and a procedure defining it,
+// general ordering: pointer/structs, long, int, short, BOOLEAN/char/enum
+// general defining procedures: rInit, rComplete, interpreter, ??
+  idhdl      idroot; /* local objects , interpreter*/
+  int*       order;  /* array of orderings, rInit/rSleftvOrdering2Ordering */
+  int*       block0; /* starting pos., rInit/rSleftvOrdering2Ordering*/
+  int*       block1; /* ending pos., rInit/rSleftvOrdering2Ordering*/
+//  char**     parameter; /* names of parameters, rInit */
+  int**      wvhdl;  /* array of weight vectors, rInit/rSleftvOrdering2Ordering */
+  char **    names;  /* array of variable names, rInit */
+
+  // what follows below here should be set by rComplete, _only_
+  long      *ordsgn;  /* array of +/- 1 (or 0) for comparing monomials */
+                       /*  ExpL_Size entries*/
+
+  // is NULL for lp or N == 1, otherwise non-NULL (with OrdSize > 0 entries) */
+  sro_ord*   typ;   /* array of orderings + sizes, OrdSize entries */
+  /* if NegWeightL_Size > 0, then NegWeightL_Offset[0..size_1] is index of longs
+  in ExpVector whose values need an offset due to negative weights */
+  /* array of NegWeigtL_Size indicies */
+  int*      NegWeightL_Offset;
+
+  int*     VarOffset;
+
+//  ideal      minideal;
+//  number     minpoly;  /* replaced by minideal->m[0] */
+  ideal      qideal; /**< extension to the ring structure: qring, rInit, OR
+                          for Q_a/Zp_a, rInit (replaces minideal!);
+                          for a start, we assume that there is either no
+                          or exactly one generator in minideal, playing
+                          the role of the former minpoly; minideal may
+                          also be NULL which coincides with the
+                          no-generator-case **/
+
+  int*     firstwv;
+
+  omBin    PolyBin; /* Bin from where monoms are allocated */
+  intvec * pModW;   /* std: module weights */
+  poly      ppNoether; /*  variables, set by procedures from hecke/kstd1:
+                            the highest monomial below pHEdge */
+  void * ext_ref;   /* libsing GAP object */
+// #ifdef HAVE_RINGS
+//   unsigned int  cf->ringtype;  /* cring = 0 => coefficient field, cring = 1 => coeffs from Z/2^m */
+//   mpz_ptr    cf->modBase; /* Z/(ringflag^cf->modExponent)=Z/cf->modNumber*/
+//   unsigned long cf->modExponent;
+//   unsigned long cf->modNumber;  /* Z/cf->modNumber */
+//   mpz_ptr    cf->modNumber;
+// #endif
+
+  unsigned long options; /* ring dependent options */
+
+//  int        ch;  /* characteristic, rInit */
+  int        ref; /* reference counter to the ring, interpreter */
+
+  short      N;      /* number of vars, rInit */
+
+  short      OrdSgn; /* 1 for polynomial rings, -1 otherwise, rInit */
+
+  short     firstBlockEnds;
+#ifdef HAVE_PLURAL
+  short     real_var_start, real_var_end;
+#endif
+
+#ifdef HAVE_SHIFTBBA
+  short          isLPring; /* 0 for non-letterplace rings, otherwise the number of LP blocks, at least 1, known also as lV */
+#endif
+
+  BOOLEAN   VectorOut;
+  BOOLEAN   ShortOut;
+  BOOLEAN   CanShortOut;
+  BOOLEAN   LexOrder; // TRUE if the monomial ordering has polynomial and power series blocks
+  BOOLEAN   MixedOrder; // TRUE for global/local mixed orderings, FALSE otherwise
+  BOOLEAN   pLexOrder; /* TRUE if the monomial ordering is not compatible with pFDeg */
+
+  BOOLEAN   ComponentOrder; // ???
+
+  // what follows below here should be set by rComplete, _only_
+  // contains component, but no weight fields in E */
+  short      ExpL_Size; // size of exponent vector in long
+  short      CmpL_Size; // portions which need to be compared
+  /* number of long vars in exp vector:
+     long vars are those longs in the exponent vector which are
+     occupied by variables, only */
+  short      VarL_Size;
+  short      BitsPerExp; /* number of bits per exponent */
+  short      ExpPerLong; /* maximal number of Exponents per long */
+  short      pCompIndex; /* p->exp.e[pCompIndex] is the component */
+  short      pOrdIndex; /* p->exp[pOrdIndex] is pGetOrd(p) */
+  short      OrdSize; /* size of ord vector (in sro_ord) */
+
+  /* if >= 0, long vars in exp vector are consecutive and start there
+     if <  0, long vars in exp vector are not consecutive */
+  short     VarL_LowIndex;
+  // number of exponents in r->VarL_Offset[0]
+  // is minimal number of exponents in a long var
+  short     MinExpPerLong;
+
+  short     NegWeightL_Size;
+  /* array of size VarL_Size,
+     VarL_Offset[i] gets i-th long var in exp vector */
+  int*      VarL_Offset;
+
+  /* mask for getting single exponents */
+  unsigned long bitmask;
+  /* mask used for divisiblity tests */
+  unsigned long divmask; // rComplete
+
+  p_Procs_s*    p_Procs; // rComplete/p_ProcsSet
+
+  /* FDeg and LDeg */
+  pFDegProc     pFDeg; // rComplete/rSetDegStuff
+  pLDegProc     pLDeg; // rComplete/rSetDegStuff
+
+  /* as it was determined by rComplete */
+  pFDegProc     pFDegOrig;
+  /* and as it was determined before rOptimizeLDeg */
+  pLDegProc     pLDegOrig;
+
+  p_SetmProc    p_Setm;
+  n_Procs_s*    cf;
+#ifdef HAVE_PLURAL
+  private:
+    nc_struct*    _nc; // private
+  public:
+    inline const nc_struct* GetNC() const { return _nc; }; // public!!!
+    inline nc_struct*& GetNC() { return _nc; }; // public!!!
+#endif
+ public:
+  operator coeffs() const { return cf; }
+};
+
+////////// DEPRECATED
+/////// void   rChangeCurrRing(ring r);
+
+ring   rDefault(int ch, int N, char **n);
+ring   rDefault(const coeffs cf, int N, char **n);
+ring   rDefault(int ch, int N, char **n,int ord_size, int *ord, int *block0, int *block1, int **wvhdl=NULL);
+ring   rDefault(const coeffs cf, int N, char **n,int ord_size, int *ord, int *block0, int *block1, int **wvhdl=NULL);
+
+// #define rIsRingVar(A) r_IsRingVar(A,currRing)
+int    r_IsRingVar(const char *n, char**names, int N);
+void   rWrite(ring r, BOOLEAN details = FALSE);
+ring   rCopy(ring r);
+ring   rCopy0(const ring r, BOOLEAN copy_qideal = TRUE, BOOLEAN copy_ordering = TRUE);
+ring rCopy0AndAddA(ring r, int64vec *wv64, BOOLEAN copy_qideal = TRUE,
+                   BOOLEAN copy_ordering = TRUE);
+ring   rOpposite(ring r);
+ring   rEnvelope(ring r);
+
+/// we must always have this test!
+static inline bool rIsPluralRing(const ring r)
+{
+  assume(r != NULL); assume(r->cf != NULL);
+#ifdef HAVE_PLURAL
+  nc_struct *n;
+  return (r != NULL) && ((n=r->GetNC()) != NULL) /*&& (n->type != nc_error)*/;
+#else
+  return false;
+#endif
+}
+
+static inline bool rIsRatGRing(const ring r)
+{
+  assume(r != NULL);
+#ifdef HAVE_PLURAL
+  /* nc_struct *n; */
+  return (r != NULL) /* && ((n=r->GetNC()) != NULL) */
+          && (r->real_var_start>1);
+#else
+  return false;
+#endif
+}
+
+
+
+
+// The following are for LaScala3 only!
+void rChangeSComps(int* currComponents, long* currShiftedComponents, int length, ring r);
+void rGetSComps(int** currComponents, long** currShiftedComponents, int *length, ring r);
+
+
+
+const char * rSimpleOrdStr(int ord);
+int rOrderName(char * ordername);
+char * rOrdStr(ring r);
+char * rVarStr(ring r);
+char * rCharStr(ring r);
+char * rString(ring r);
+int    rChar(ring r);
+
+char * rParStr(ring r);
+
+int    rSum(ring r1, ring r2, ring &sum);
+int rSumInternal(ring r1, ring r2, ring &sum, BOOLEAN vartest, BOOLEAN dp_dp);
+
+/// returns TRUE, if r1 equals r2 FALSE, otherwise Equality is
+/// determined componentwise, if qr == 1, then qrideal equality is
+/// tested, as well
+BOOLEAN rEqual(ring r1, ring r2, BOOLEAN qr = TRUE);
+
+/// returns TRUE, if r1 and r2 represents the monomials in the same way
+/// FALSE, otherwise
+/// this is an analogue to rEqual but not so strict
+BOOLEAN rSamePolyRep(ring r1, ring r2);
+
+void   rUnComplete(ring r);
+
+BOOLEAN rRing_is_Homog(ring r);
+BOOLEAN rRing_has_CompLastBlock(ring r);
+
+#ifdef HAVE_RINGS
+static inline BOOLEAN rField_is_Ring_2toM(const ring r)
+{ assume(r != NULL); assume(r->cf != NULL); return ( nCoeff_is_Ring_2toM(r->cf) ); }
+
+static inline BOOLEAN rField_is_Ring_ModN(const ring r)
+{ assume(r != NULL); assume(r->cf != NULL); return ( nCoeff_is_Ring_ModN(r->cf) ); }
+
+static inline BOOLEAN rField_is_Ring_PtoM(const ring r)
+{ assume(r != NULL); assume(r->cf != NULL); return ( nCoeff_is_Ring_PtoM(r->cf) ); }
+
+static inline BOOLEAN rField_is_Ring_Z(const ring r)
+{ assume(r != NULL); assume(r->cf != NULL); return ( nCoeff_is_Ring_Z(r->cf) ); }
+
+static inline BOOLEAN rField_is_Ring(const ring r)
+{ assume(r != NULL); assume(r->cf != NULL); return nCoeff_is_Ring(r->cf); }
+
+static inline BOOLEAN rField_is_Domain(const ring r)
+{ assume(r != NULL); assume(r->cf != NULL); return nCoeff_is_Domain(r->cf); }
+
+static inline BOOLEAN rField_has_Units(const ring r)
+{ assume(r != NULL); assume(r->cf != NULL); return nCoeff_has_Units(r->cf); }
+#else
+#define rField_is_Ring(A) (0)
+#define rField_is_Ring_2toM(A) (0)
+#define rField_is_Ring_ModN(A) (0)
+#define rField_is_Ring_PtoM(A) (0)
+#define rField_is_Ring_Z(A) (0)
+#define rField_is_Domain(A) (1)
+#define rField_has_Units(A) (1)
+#endif
+
+static inline BOOLEAN rField_is_Zp(const ring r)
+{ assume(r != NULL); assume(r->cf != NULL); return (getCoeffType(r->cf) == n_Zp); }
+
+static inline BOOLEAN rField_is_Zp(const ring r, int p)
+{ assume(r != NULL); assume(r->cf != NULL); return (getCoeffType(r->cf) == n_Zp) && (r->cf->ch == p); }
+
+static inline BOOLEAN rField_is_Q(const ring r)
+{ assume(r != NULL); assume(r->cf != NULL); return nCoeff_is_Q(r->cf); }
+
+static inline BOOLEAN rField_is_numeric(const ring r) /* R, long R, long C */
+{ assume(r != NULL); assume(r->cf != NULL); return nCoeff_is_numeric(r->cf); }
+
+static inline BOOLEAN rField_is_R(const ring r)
+{ assume(r != NULL); assume(r->cf != NULL); return nCoeff_is_R(r->cf); }
+
+static inline BOOLEAN rField_is_GF(const ring r)
+{ assume(r != NULL); assume(r->cf != NULL); return nCoeff_is_GF(r->cf); }
+
+static inline BOOLEAN rField_is_GF(const ring r, int q)
+{ assume(r != NULL); assume(r->cf != NULL); return nCoeff_is_GF(r->cf, q); }
+
+/* DO NOT USE; just here for compatibility reasons towards
+   the SINGULAR svn trunk */
+static inline BOOLEAN rField_is_Zp_a(const ring r)
+{ assume(r != NULL); assume(r->cf != NULL); return nCoeff_is_Zp_a(r->cf); }
+
+/* DO NOT USE; just here for compatibility reasons towards
+   the SINGULAR svn trunk */
+static inline BOOLEAN rField_is_Zp_a(const ring r, int p)
+{ assume(r != NULL); assume(r->cf != NULL); return nCoeff_is_Zp_a(r->cf, p); }
+
+/* DO NOT USE; just here for compatibility reasons towards
+   the SINGULAR svn trunk */
+static inline BOOLEAN rField_is_Q_a(const ring r)
+{ assume(r != NULL); assume(r->cf != NULL); return nCoeff_is_Q_a(r->cf); }
+
+static inline BOOLEAN rField_is_long_R(const ring r)
+{ assume(r != NULL); assume(r->cf != NULL); return nCoeff_is_long_R(r->cf); }
+
+static inline BOOLEAN rField_is_long_C(const ring r)
+{ assume(r != NULL); assume(r->cf != NULL); return nCoeff_is_long_C(r->cf); }
+
+static inline BOOLEAN rField_has_simple_inverse(const ring r)
+{ assume(r != NULL); assume(r->cf != NULL); return nCoeff_has_simple_inverse(r->cf); }
+
+/// Z/p, GF(p,n), R: nCopy, nNew, nDelete are dummies
+static inline BOOLEAN rField_has_simple_Alloc(const ring r)
+{ assume(r != NULL); assume(r->cf != NULL); return nCoeff_has_simple_Alloc(r->cf); }
+
+n_coeffType rFieldType(const ring r);
+
+/// this needs to be called whenever a new ring is created: new fields
+/// in ring are created (like VarOffset), unless they already exist
+/// with force == 1, new fields are _always_ created (overwritten),
+/// even if they exist
+BOOLEAN rComplete(ring r, int force = 0);
+// use this to free fields created by rComplete //?
+
+/// set all properties of a new ring - also called by rComplete
+void p_SetGlobals(const ring r, BOOLEAN complete = TRUE);
+
+static inline int rBlocks(ring r)
+{
+  assume(r != NULL);
+  int i=0;
+  while (r->order[i]!=0) i++;
+  return i+1;
+}
+
+// misc things
+static inline char* rRingVar(short i, const ring r)
+{
+  assume(r != NULL); assume(r->cf != NULL); return r->names[i];
+}
+static inline BOOLEAN rShortOut(const ring r)
+{
+  assume(r != NULL); return (r->ShortOut);
+}
+
+static inline BOOLEAN rCanShortOut(const ring r)
+{
+  assume(r != NULL); return (r->CanShortOut);
+}
+
+/// #define rVar(r) (r->N)
+static inline short rVar(const ring r)
+{
+  assume(r != NULL);
+  return r->N;
+}
+
+/// (r->cf->P)
+static inline int rPar(const ring r)
+{
+  assume(r != NULL);
+  const coeffs C = r->cf;
+  assume(C != NULL);
+
+  return n_NumberOfParameters(C);
+//   if( nCoeff_is_Extension(C) )
+//   {
+//     const ring R = C->extRing;
+//     assume( R != NULL );
+//     return rVar( R );
+//   }
+//   else if (nCoeff_is_GF(C))
+//   {
+//     return 1;
+//   }
+//   else if (nCoeff_is_long_C(C))
+//   {
+//     return 1;
+//   }
+//   return 0;
+}
+
+
+/// (r->cf->parameter)
+static inline char const ** rParameter(const ring r)
+{
+  assume(r != NULL);
+  const coeffs C = r->cf;
+  assume(C != NULL);
+
+  return n_ParameterNames(C);
+//   if( nCoeff_is_Extension(C) ) // only alg / trans. exts...
+//   {
+//     const ring R = C->extRing;
+//     assume( R != NULL );
+//     return R->names;
+//   }
+//   else if (nCoeff_is_GF(C))
+//   {
+//     return &(C->m_nfParameter);
+//   }
+//   else if (nCoeff_is_long_C(C))
+//   {
+//     return &(C->complex_parameter);
+//   }
+//   return NULL;
+}
+
+/// return the specified parameter as a (new!) number in the given
+/// polynomial ring, or NULL if invalid
+/// parameters (as variables) begin with 1!
+static inline number n_Param(const short iParameter, const ring r)
+{
+  assume(r != NULL);
+  const coeffs C = r->cf;
+  assume(C != NULL);
+  return n_Param(iParameter, C);
+//   const n_coeffType _filed_type = getCoeffType(C);
+//
+//   if ( iParameter <= 0 || iParameter > rPar(r) )
+//     // Wrong parameter
+//     return NULL;
+//
+//   if( _filed_type == n_algExt )
+//     return naParameter(iParameter, C);
+//
+//   if( _filed_type == n_transExt )
+//     return ntParameter(iParameter, C);
+//
+//   if (_filed_type == n_GF)// if (nCoeff_is_GF(C))
+//   {
+//     number nfPar (int i, const coeffs);
+//     return nfPar(iParameter, C);
+//   }
+//
+//   if (_filed_type == n_long_C) // if (nCoeff_is_long_C(C))
+//   {
+//     number   ngcPar(int i, const coeffs r);
+//     return ngcPar(iParameter, C);
+//   }
+//
+//   return NULL;
+}
+
+/// if m == var(i)/1 => return i,
+int n_IsParam(number m, const ring r);
+
+//#define  rInternalChar(r) ((r)->cf->ch)
+static inline int rInternalChar(const ring r)
+{
+  assume(r != NULL);
+  const coeffs C = r->cf;
+  assume(C != NULL);
+  return C->ch;
+}
+
+
+/// Tests whether '(r->cf->minpoly) == NULL'
+static inline BOOLEAN rMinpolyIsNULL(const ring r)
+{
+  assume(r != NULL);
+  const coeffs C = r->cf;
+  assume(C != NULL);
+
+  const BOOLEAN ret = nCoeff_is_algExt(C); //  || nCoeff_is_GF(C) || nCoeff_is_long_C(C);
+
+  if( ret )
+  {
+    assume( (C->extRing) != NULL );
+    BOOLEAN idIs0 (ideal h);
+    assume((!((C->extRing)->qideal==NULL)) && (!idIs0((C->extRing)->qideal)));
+  }
+
+  // TODO: this leads to test fails (due to rDecompose?)
+  return !ret;
+}
+
+
+
+/// order stuff
+typedef enum rRingOrder_t
+{
+  ringorder_no = 0,
+  ringorder_a,
+  ringorder_a64, ///< for int64 weights
+  ringorder_c,
+  ringorder_C,
+  ringorder_M,
+  ringorder_S, ///< S?
+  ringorder_s, ///< s?
+  ringorder_lp,
+  ringorder_dp,
+  ringorder_rp,
+  ringorder_Dp,
+  ringorder_wp,
+  ringorder_Wp,
+  ringorder_ls,
+  ringorder_ds,
+  ringorder_Ds,
+  ringorder_ws,
+  ringorder_Ws,
+  ringorder_am,
+  ringorder_L,
+  // the following are only used internally
+  ringorder_aa, ///< for idElimination, like a, except pFDeg, pWeigths ignore it
+  ringorder_rs, ///< opposite of ls
+  ringorder_IS, ///< Induced (Schreyer) ordering
+  ringorder_unspec
+} rRingOrder_t;
+
+typedef enum rOrderType_t
+{
+  rOrderType_General = 0, ///< non-simple ordering as specified by currRing
+  rOrderType_CompExp,     ///< simple ordering, component has priority
+  rOrderType_ExpComp,     ///< simple ordering, exponent vector has priority
+                          ///< component not compatible with exp-vector order
+  rOrderType_Exp,         ///< simple ordering, exponent vector has priority
+                          ///< component is compatible with exp-vector order
+  rOrderType_Syz,         ///< syzygy ordering
+  rOrderType_Schreyer,    ///< Schreyer ordering
+  rOrderType_Syz2dpc,     ///< syzcomp2dpc
+  rOrderType_ExpNoComp    ///< simple ordering, differences in component are
+                          ///< not considered
+} rOrderType_t;
+
+static inline BOOLEAN rIsSyzIndexRing(const ring r)
+{ assume(r != NULL); assume(r->cf != NULL); return r->order[0] == ringorder_s;}
+
+static inline int rGetCurrSyzLimit(const ring r)
+{ assume(r != NULL); assume(r->cf != NULL); return (rIsSyzIndexRing(r)? r->typ[0].data.syz.limit : 0);}
+
+void   rSetSyzComp(int k, const ring r);
+
+// Ring Manipulations
+ring   rAssure_HasComp(const ring r);
+ring   rAssure_SyzComp(const ring r, BOOLEAN complete = TRUE);
+
+ring   rAssure_dp_S(const ring r);
+ring   rAssure_dp_C(const ring r);
+ring   rAssure_C_dp(const ring r);
+
+/// makes sure that c/C ordering is last ordering
+ring   rAssure_CompLastBlock(const ring r, BOOLEAN complete = TRUE);
+
+/// makes sure that c/C ordering is last ordering and SyzIndex is first
+ring   rAssure_SyzComp_CompLastBlock(const ring r, BOOLEAN complete = TRUE);
+ring   rAssure_TDeg(const ring r, int start_var, int end_var, int &pos);
+
+/// return the max-comonent wchich has syzIndex i
+/// Assume: i<= syzIndex_limit
+int rGetMaxSyzComp(int i, const ring r);
+
+BOOLEAN rHasSimpleOrder(const ring r);
+BOOLEAN rHas_c_Ordering(const ring r);
+
+/// returns TRUE, if simple lp or ls ordering
+BOOLEAN rHasSimpleLexOrder(const ring r);
+
+//???? return TRUE if p->exp[r->pOrdIndex] holds total degree of p ???
+
+
+inline BOOLEAN rHasGlobalOrdering(const ring r){ return (r->OrdSgn==1); }
+inline BOOLEAN rHasLocalOrMixedOrdering(const ring r){ return (r->OrdSgn==-1); }
+
+// #define rHasGlobalOrdering(R) ((R)->OrdSgn==1)
+// #define rHasLocalOrMixedOrdering(R) ((R)->OrdSgn==-1)
+
+#define rHasGlobalOrdering_currRing() rHasGlobalOrdering(currRing)
+#define rHasLocalOrMixedOrdering_currRing() rHasLocalOrMixedOrdering(currRing)
+
+BOOLEAN rOrd_is_Totaldegree_Ordering(ring r );
+
+/// return TRUE if p_SetComp requires p_Setm
+BOOLEAN rOrd_SetCompRequiresSetm(ring r);
+rOrderType_t    rGetOrderType(ring r);
+
+/// returns TRUE if var(i) belongs to p-block
+BOOLEAN rIsPolyVar(int i, ring r);
+
+static inline BOOLEAN rOrd_is_Comp_dp(ring r)
+{
+  assume(r != NULL);
+  assume(r->cf != NULL);
+  return ((r->order[0] == ringorder_c || r->order[0] == ringorder_C) &&
+          r->order[1] == ringorder_dp &&
+          r->order[2] == 0);
+}
+
+#ifdef RDEBUG
+#define rTest(r)    rDBTest(r, __FILE__, __LINE__)
+extern BOOLEAN rDBTest(ring r, const char* fn, const int l);
+#else
+#define rTest(r)
+#endif
+
+ring rModifyRing(ring r, BOOLEAN omit_degree,
+                         BOOLEAN omit_comp,
+                         unsigned long exp_limit);
+
+/// construct Wp, C ring
+ring rModifyRing_Wp(ring r, int* weights);
+void rModify_a_to_A(ring r);
+
+void rKillModifiedRing(ring r);
+// also frees weights
+void rKillModified_Wp_Ring(ring r);
+
+ring rModifyRing_Simple(ring r, BOOLEAN omit_degree, BOOLEAN omit_comp, unsigned long exp_limit, BOOLEAN &simple);
+void rKillModifiedRing_Simple(ring r);
+
+#ifdef RDEBUG
+void rDebugPrint(ring r);
+// void pDebugPrint(poly p);
+void p_DebugPrint(poly p, const ring r);
+#endif
+
+#ifndef SING_NDEBUG
+/// debug-print at most nTerms (2 by default) terms from poly/vector p,
+/// assuming that lt(p) lives in lmRing and tail(p) lives in tailRing.
+void p_DebugPrint(const poly p, const ring lmRing, const ring tailRing, const int nTerms = 2);
+#endif
+
+int64 * rGetWeightVec(ring r);
+void rSetWeightVec(ring r, int64 *wv);
+
+/////////////////////////////
+// Auxillary functions
+//
+
+/* return the varIndex-th ring variable as a poly;
+   varIndex starts at index 1 */
+poly rGetVar(const int varIndex, const ring r);
+
+BOOLEAN rSetISReference(const ring r, const ideal F, const int i = 0, const int p = 0);
+
+/// return the position of the p^th IS block order block in r->typ[]...
+int rGetISPos(const int p, const ring r);
+
+BOOLEAN rCheckIV(intvec *iv);
+int rTypeOfMatrixOrder(intvec * order);
+
+void rDelete(ring r); // To be used instead of rKill!
+
+extern omBin sip_sring_bin;
+#endif
diff --git a/libpolys/polys/nc/gb_hack.h b/libpolys/polys/nc/gb_hack.h
new file mode 100644
index 0000000..6e5c216
--- /dev/null
+++ b/libpolys/polys/nc/gb_hack.h
@@ -0,0 +1,61 @@
+#ifndef POLYS_NC_GB_HACK_H
+#define POLYS_NC_GB_HACK_H
+
+#ifdef HAVE_PLURAL
+
+#ifdef PLURAL_INTERNAL_DECLARATIONS
+
+struct  spolyrec; typedef struct spolyrec    polyrec; typedef polyrec *          poly;
+struct ip_sring; typedef struct ip_sring *         ring;
+struct sip_sideal; typedef struct sip_sideal *       ideal;
+
+class intvec;
+
+class skStrategy; typedef skStrategy * kStrategy;
+typedef ideal (*GB_Proc_Ptr)(const ideal, const ideal, const intvec*, const intvec*, kStrategy, const ring);
+
+
+ideal gnc_gr_bba(const ideal, const ideal, const intvec *, const intvec *, kStrategy, const ring _currRing);
+ideal gnc_gr_mora(const ideal, const ideal, const intvec *, const intvec *, kStrategy, const ring _currRing);
+
+/// Modified Plural's Buchberger's algorithmus.
+ideal sca_gr_bba(const ideal, const ideal, const intvec *, const intvec *, kStrategy, const ring _currRing);
+
+/// Modified modern Sinuglar Buchberger's algorithm.
+ideal sca_bba(const ideal, const ideal, const intvec *, const intvec *, kStrategy, const ring _currRing);
+
+/// Modified modern Sinuglar Mora's algorithm.
+ideal sca_mora(const ideal, const ideal, const intvec *, const intvec *, kStrategy, const ring _currRing);
+
+poly kNF(ideal, ideal, poly, int, int, const ring _currRing);
+
+
+
+# ifdef PLURAL_INTERNAL_DECLARATIONS_GB_HACK
+
+extern void WerrorS(const char *);
+
+# define STR_EXPAND(tok) #tok
+# define D(A)    A{ WerrorS("This is a hack. Function is not defined: " STR_EXPAND(A) ); return NULL; (void)(_currRing); }
+
+D(ideal gnc_gr_bba(const ideal, const ideal, const intvec *, const intvec *, kStrategy, const ring _currRing))
+D(ideal gnc_gr_mora(const ideal, const ideal, const intvec *, const intvec *, kStrategy, const ring _currRing))
+
+/// Modified Plural's Buchberger's algorithmus.
+D(ideal sca_gr_bba(const ideal, const ideal, const intvec *, const intvec *, kStrategy, const ring _currRing))
+
+/// Modified modern Sinuglar Buchberger's algorithm.
+D(ideal sca_bba(const ideal, const ideal, const intvec *, const intvec *, kStrategy, const ring _currRing))
+
+/// Modified modern Sinuglar Mora's algorithm.
+D(ideal sca_mora(const ideal, const ideal, const intvec *, const intvec *, kStrategy, const ring _currRing))
+
+D(poly kNF(ideal, ideal, poly, int, int, const ring _currRing))
+
+#endif // # ifdef PLURAL_INTERNAL_DECLARATIONS_GB_HACK
+#endif // PLURAL_INTERNAL_DECLARATIONS
+
+
+#endif // HAVE_PLURAL
+#endif // POLYS_NC_GB_HACK_H
+
diff --git a/libpolys/polys/nc/nc.h b/libpolys/polys/nc/nc.h
new file mode 100644
index 0000000..1639d33
--- /dev/null
+++ b/libpolys/polys/nc/nc.h
@@ -0,0 +1,422 @@
+#ifndef POLYS_NC_H
+#define POLYS_NC_H
+
+#include <polys/monomials/ring.h>
+#include <polys/kbuckets.h>
+
+#ifdef HAVE_PLURAL
+
+// TODO: the following is a part of ring.h... would be nice to have a
+// clear public NC interface defined here!
+
+
+class ip_smatrix;
+typedef ip_smatrix *       matrix;
+
+
+matrix nc_PrintMat(int a, int b, ring r, int metric);
+
+
+enum nc_type
+{
+  nc_error = -1, // Something's gone wrong!
+  nc_general = 0, /* yx=q xy+... */
+  nc_skew, /*1*/ /* yx=q xy */
+  nc_comm, /*2*/ /* yx= xy */
+  nc_lie,  /*3*/ /* yx=xy+... */
+  nc_undef, /*4*/  /* for internal reasons */
+
+  nc_exterior /*5*/ // Exterior Algebra(SCA): yx= -xy & (!:) x^2 = 0
+};
+
+
+// //////////////////////////////////////////////////////
+
+
+/// checks whether rings rBase and rCandidate
+/// could be opposite to each other
+/// returns TRUE if it is so
+BOOLEAN rIsLikeOpposite(ring rBase, ring rCandidate);
+
+
+
+// Macros used to access upper triangle matrices C,D... (which are actually ideals) // afaik
+#define UPMATELEM(i,j,nVar) ( (nVar * ((i)-1) - ((i) * ((i)-1))/2 + (j)-1)-(i) )
+
+/// complete destructor
+void nc_rKill(ring r);
+
+
+BOOLEAN nc_CheckSubalgebra(poly PolyVar, ring r);
+
+// NC pProcs:
+typedef poly (*mm_Mult_p_Proc_Ptr)(const poly m, poly p, const ring r);
+typedef poly (*mm_Mult_pp_Proc_Ptr)(const poly m, const poly p, const ring r);
+
+
+
+typedef poly (*SPoly_Proc_Ptr)(const poly p1, const poly p2, const ring r);
+typedef poly (*SPolyReduce_Proc_Ptr)(const poly p1, poly p2, const ring r);
+
+typedef void (*bucket_Proc_Ptr)(kBucket_pt b, poly p, number *c);
+
+struct nc_pProcs
+{
+public:
+  mm_Mult_p_Proc_Ptr                    mm_Mult_p;
+  mm_Mult_pp_Proc_Ptr                   mm_Mult_pp;
+
+  bucket_Proc_Ptr                       BucketPolyRed;
+  bucket_Proc_Ptr                       BucketPolyRed_Z;
+
+  SPoly_Proc_Ptr                        SPoly;
+  SPolyReduce_Proc_Ptr                  ReduceSPoly;
+
+  void*                                 GB; ///< From "gb_hack.h"
+//                                         GlobalGB, // BBA
+//                                         LocalGB;  // MORA
+};
+
+class CGlobalMultiplier;
+class CFormulaPowerMultiplier;
+
+struct nc_struct
+{
+  nc_type type;
+  //ring basering; // the ring C,D,.. live in (commutative ring with this NC structure!)
+
+  // initial data: square matrices rVar() x rVar()
+  // logically: upper triangular!!!
+  // TODO: eliminate this waste of memory!!!!
+  matrix C;
+  matrix D;
+
+  // computed data:
+  matrix *MT; // size 0.. (rVar()*rVar()-1)/2
+  matrix COM;
+  int *MTsize; // size 0.. (rVar()*rVar()-1)/2
+
+  // IsSkewConstant indicates whethere coeffs C_ij are all equal,
+  // effective together with nc_type=nc_skew
+  int IsSkewConstant;
+
+  private:
+    // internal data for different implementations
+    // if dynamic => must be deallocated in destructor (nc_rKill!)
+    union
+    {
+      struct
+      {
+        // treat variables from iAltVarsStart till iAltVarsEnd as alternating vars.
+        // these variables should have odd degree, though that will not be checked
+        // iAltVarsStart, iAltVarsEnd are only used together with nc_type=nc_exterior
+        // 1 <= iAltVarsStart <= iAltVarsEnd <= r->N
+        short iFirstAltVar, iLastAltVar; // = 0 by default
+
+        // for factors of super-commutative algebras we need
+        // the part of general quotient ideal modulo squares!
+        ideal idSCAQuotient; // = NULL by default. // must be deleted in Kill!
+      } sca;
+    } data;
+
+  public:
+
+    inline nc_type& ncRingType() { return (type); };
+    inline nc_type ncRingType() const { return (type); };
+
+    inline short& FirstAltVar()
+        { assume(ncRingType() == nc_exterior); return (data.sca.iFirstAltVar); };
+    inline short& LastAltVar ()
+        { assume(ncRingType() == nc_exterior); return (data.sca.iLastAltVar ); };
+
+    inline short FirstAltVar() const
+        { assume(ncRingType() == nc_exterior); return (data.sca.iFirstAltVar); };
+    inline short LastAltVar () const
+        { assume(ncRingType() == nc_exterior); return (data.sca.iLastAltVar ); };
+
+    inline ideal& SCAQuotient()
+        { assume(ncRingType() == nc_exterior); return (data.sca.idSCAQuotient); };
+  private:
+
+    CGlobalMultiplier* m_Multiplier;
+    CFormulaPowerMultiplier* m_PowerMultiplier;
+
+  public:
+
+    inline CGlobalMultiplier* GetGlobalMultiplier() const
+        { return (m_Multiplier); };
+
+    inline CGlobalMultiplier*& GetGlobalMultiplier()
+        { return (m_Multiplier); };
+
+
+    inline CFormulaPowerMultiplier* GetFormulaPowerMultiplier() const
+        { return (m_PowerMultiplier); };
+
+    inline CFormulaPowerMultiplier*& GetFormulaPowerMultiplier()
+        { return (m_PowerMultiplier); };
+
+  public:
+    nc_pProcs p_Procs; // NC procedures.
+
+};
+
+
+
+
+// //////////////////////////////////////////////////////////////////////// //
+// NC inlines
+
+static inline nc_struct*& GetNC(ring r)
+{
+  return r->GetNC();
+}
+
+static inline nc_type& ncRingType(nc_struct* p)
+{
+  assume(p!=NULL);
+  return (p->ncRingType());
+}
+
+static inline nc_type ncRingType(ring r) // Get
+{
+  if(rIsPluralRing(r))
+    return (ncRingType(r->GetNC()));
+  else
+    return (nc_error);
+}
+
+static inline void ncRingType(ring r, nc_type t) // Set
+{
+  assume((r != NULL) && (r->GetNC() != NULL));
+  ncRingType(r->GetNC()) = t;
+}
+
+static inline void ncRingType(nc_struct* p, nc_type t) // Set
+{
+  assume(p!=NULL);
+  ncRingType(p) = t;
+}
+
+
+
+
+// //////////////////////////////////////////////////////////////////////// //
+// we must always have this test!?
+static inline bool rIsSCA(const ring r)
+{
+#ifdef HAVE_PLURAL
+  return rIsPluralRing(r) && (ncRingType(r) == nc_exterior);
+#else
+  return false;
+#endif
+}
+
+// //////////////////////////////////////////////////////////////////////// //
+// NC inlines
+
+
+/// general NC-multiplication with destruction
+poly _nc_p_Mult_q(poly p, poly q, const ring r);
+
+/// general NC-multiplication without destruction
+poly _nc_pp_Mult_qq(const poly p, const poly q, const ring r);
+
+
+
+/// for p_Minus_mm_Mult_qq in pInline2.h
+poly nc_p_Minus_mm_Mult_qq(poly p, const poly m, const poly q, int &lp,
+                                    const poly, const ring r);
+
+// // for p_Plus_mm_Mult_qq in pInline2.h
+// returns p + m*q destroys p, const: q, m
+poly nc_p_Plus_mm_Mult_qq(poly p, const poly m, const poly q, int &lp,
+                              const int, const ring r);
+
+
+
+
+// returns m*p, does neither destroy p nor m
+static inline poly nc_mm_Mult_pp(const poly m, const poly p, const ring r)
+{
+  assume(rIsPluralRing(r));
+  assume(r->GetNC()->p_Procs.mm_Mult_pp!=NULL);
+  return r->GetNC()->p_Procs.mm_Mult_pp(m, p, r);
+//  return pp_Mult_mm( p, m, r);
+}
+
+
+// returns m*p, does destroy p, preserves m
+static inline poly nc_mm_Mult_p(const poly m, poly p, const ring r)
+{
+  assume(rIsPluralRing(r));
+  assume(r->GetNC()->p_Procs.mm_Mult_p!=NULL);
+  return r->GetNC()->p_Procs.mm_Mult_p(m, p, r);
+//   return p_Mult_mm( p, m, r);
+}
+
+static inline poly nc_CreateSpoly(const poly p1, const poly p2, const ring r)
+{
+  assume(rIsPluralRing(r));
+  assume(r->GetNC()->p_Procs.SPoly!=NULL);
+  return r->GetNC()->p_Procs.SPoly(p1, p2, r);
+}
+
+// ?
+poly nc_CreateShortSpoly(poly p1, poly p2, const ring r);
+
+/* brackets: p will be destroyed... */
+poly nc_p_Bracket_qq(poly p, const poly q, const ring r);
+
+static inline poly nc_ReduceSpoly(const poly p1, poly p2, const ring r)
+{
+  assume(rIsPluralRing(r));
+  assume(r->GetNC()->p_Procs.ReduceSPoly!=NULL);
+#ifdef PDEBUG
+//  assume(p_LmDivisibleBy(p1, p2, r));
+#endif
+  return r->GetNC()->p_Procs.ReduceSPoly(p1, p2, r);
+}
+
+void nc_PolyPolyRed(poly &b, poly p, number *c, const ring r);
+
+/*
+static inline void nc_PolyReduce(poly &b, const poly p, number *c, const ring r) // nc_PolyPolyRed
+{
+  assume(rIsPluralRing(r));
+//  assume(r->GetNC()->p_Procs.PolyReduce!=NULL);
+//  r->GetNC()->p_Procs.PolyReduce(b, p, c, r);
+}
+*/
+
+static inline void nc_kBucketPolyRed(kBucket_pt b, poly p, number *c)
+{
+  const ring r = b->bucket_ring;
+  assume(rIsPluralRing(r));
+
+//   return gnc_kBucketPolyRedNew(b, p, c);
+
+  assume(r->GetNC()->p_Procs.BucketPolyRed!=NULL);
+  return r->GetNC()->p_Procs.BucketPolyRed(b, p, c);
+}
+
+static inline void nc_BucketPolyRed_Z(kBucket_pt b, poly p, number *c)
+{
+  const ring r = b->bucket_ring;
+  assume(rIsPluralRing(r));
+
+//   return gnc_kBucketPolyRed_ZNew(b, p, c);
+
+  assume(r->GetNC()->p_Procs.BucketPolyRed_Z!=NULL);
+  return r->GetNC()->p_Procs.BucketPolyRed_Z(b, p, c);
+
+}
+
+/* subst: */
+poly nc_pSubst(poly p, int n, poly e, const ring r);
+
+// the part, related to the interface
+// Changes r, Assumes that all other input belongs to curr
+BOOLEAN nc_CallPlural(matrix cc, matrix dd, poly cn, poly dn, ring r,
+                      bool bSetupQuotient, //< false
+                      bool bCopyInput, //< true
+                      bool bBeQuiet, //< false
+                      ring curr,
+                      bool dummy_ring = false
+		      /* allow to create a nc-ring with 1 variable*/);
+
+
+// this function should be used inside QRing definition!
+// we go from rG into factor ring rGR with factor ideal rGR->qideal.
+bool nc_SetupQuotient(ring rGR, const ring rG = NULL, bool bCopy = false); // rG == NULL means that there is no base G-algebra
+
+BOOLEAN nc_rComplete(const ring src, ring dest, bool bSetupQuotient = true); // in ring.cc
+
+bool nc_rCopy(ring res, const ring r, bool bSetupQuotient);
+
+poly pOppose(ring Rop_src, poly p, const ring Rop_dst);
+ideal idOppose(ring Rop_src, ideal I, const ring Rop_dst);
+
+
+
+// returns the LCM of the head terms of a and b with the given component
+// NOTE: coeff will be created but remains undefined(zero?)
+poly p_Lcm(const poly a, const poly b, const long lCompM, const ring r);
+
+// returns the LCM of the head terms of a and b with component = max comp. of a & b
+// NOTE: coeff will be created but remains undefined(zero?)
+poly p_Lcm(const poly a, const poly b, const ring r);
+
+
+
+
+
+const int GENERICMASK = 0x000; // gnc... must do its dirty job first!
+const int SCAMASK     = 0x001;
+
+#if 0
+static const bool bNoPluralMultiplication = false;  // use only formula shortcuts in my OOP Multiplier
+// the following make sense only if bNoPluralMultiplication is false:
+static const bool bNoFormula = true;  // don't use any formula shortcuts
+static const bool bNoCache   = false; // only formula whenever possible, only make sanse if bNoFormula is false!
+#endif
+
+// false, true, false == old "good" Plural
+// false, false ==>> Plural + Cache + Direct Formula - not much
+// false, false, true ==>> Plural Mult + Direct Formula (no ~cache)
+// true, *, *  == new OOP multiplication!
+
+const int NOPLURALMASK= 0x002; // bNoPluralMultiplication
+const int NOFORMULAMASK=0x004; // bNoFormula
+const int NOCACHEMASK = 0x008; // bNoCache
+
+const int TESTSYZSCAMASK = 0x0100 | SCAMASK;
+
+
+
+// NCExtensions Mask Property
+int& getNCExtensions();
+int  setNCExtensions(int iMask);
+
+// Test
+bool ncExtensions(int iMask); //  = 0x0FFFF
+
+
+
+#ifdef PLURAL_INTERNAL_DECLARATIONS
+
+// set pProcs table for rGR and global variable p_Procs
+// this should be used by p_ProcsSet in p_Procs_Set.h
+void nc_p_ProcsSet(ring rGR, p_Procs_s* p_Procs);
+
+
+#include <polys/matpol.h>
+
+// read only access to NC matrices C/D:
+// get C_{i,j}, 1 <= row = i < j = col <= N
+static inline poly GetC( const ring r, int i, int j )
+{
+  assume(r!= NULL && rIsPluralRing(r));
+  const matrix C = GetNC(r)->C;
+  assume(C != NULL);
+  const int ncols = C->ncols;
+  assume( (i > 0) && (i < j) && (j <= ncols) );
+  return ( C->m[ncols * ((i)-1) + (j)-1] );
+}
+
+// get D_{i,j}, 1 <= row = i < j = col <= N
+static inline poly GetD( const ring r, int i, int j )
+{
+  assume(r!= NULL && rIsPluralRing(r));
+  const matrix D = GetNC(r)->D;
+  assume(D != NULL);
+  const int ncols = D->ncols;
+  assume( (i > 0) && (i < j) && (j <= ncols) );
+  return ( D->m[ncols * ((i)-1) + (j)-1] );
+}
+
+#endif // PLURAL_INTERNAL_DECLARATIONS
+
+#endif /* HAVE_PLURAL */
+
+#endif /* POLYS_NC_H */
diff --git a/libpolys/polys/nc/ncSACache.cc b/libpolys/polys/nc/ncSACache.cc
new file mode 100644
index 0000000..24e1d2f
--- /dev/null
+++ b/libpolys/polys/nc/ncSACache.cc
@@ -0,0 +1,78 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    ncSACache.cc
+ *  Purpose: implementation of special Cache+Hash for Multiplier
+ *  Author:  motsak
+ *  Created:
+ *******************************************************************/
+
+#define MYTEST 0
+
+#if MYTEST
+#define OM_CHECK 4
+#define OM_TRACK 5
+// these settings must be before "mod2.h" in order to work!!!
+#endif
+
+
+
+
+
+#include <misc/auxiliary.h>
+
+#ifndef SING_NDEBUG
+#define OUTPUT MYTEST
+#else
+#define OUTPUT 0
+#endif
+
+#if OUTPUT
+namespace
+{
+  static const char* m_Typenames[2] = {"lookup", "store"};
+}
+#endif
+
+#include <coeffs/numbers.h>
+#include "coeffrings.h"
+
+#include "nc/ncSACache.h" // for CCacheHash etc classes
+
+#include "monomials/ring.h"
+#include "monomials/p_polys.h"
+
+
+void CGlobalCacheHash::History(const EHistoryType t, const CGlobalCacheHash::CExponent a, const CGlobalCacheHash::CExponent b, const poly p)
+{
+#if OUTPUT
+  Print("History: GlobalPair, Action: %s", m_Typenames[(int)(t)]);
+  PrintLn();
+  PrintS("Left : "); p_Write(a, GetBasering());
+  PrintS("Right: "); p_Write(b, GetBasering());
+  if( t == MULT_STORE )
+  {
+    PrintS("Result: "); p_Write(p, GetBasering());
+  }
+#endif
+}
+
+
+void  CSpecialPairCacheHash::History(const EHistoryType t, const CSpecialPairCacheHash::CExponent a, const CSpecialPairCacheHash::CExponent b, const poly p)
+{
+#if OUTPUT
+  Print("History: SpecialPair, Action: %s", m_Typenames[(int)(t)]);
+  PrintLn();
+  Print("Left : %d, Right: %d", a, b);
+  PrintLn();
+  if( t == MULT_STORE )
+  {
+    PrintS("Result: "); p_Write(p, GetBasering());
+  }
+#endif
+}
+
+
+template class CCacheHash<int>;
+template class CCacheHash<spolyrec*>;
diff --git a/libpolys/polys/nc/ncSACache.h b/libpolys/polys/nc/ncSACache.h
new file mode 100644
index 0000000..97fce5a
--- /dev/null
+++ b/libpolys/polys/nc/ncSACache.h
@@ -0,0 +1,131 @@
+#ifndef GRING_SA_CACHEHASH_H
+#define GRING_SA_CACHEHASH_H
+/*****************************************
+ *  Computer Algebra System SINGULAR     *
+ *****************************************/
+
+// #include <ncSACache.h> // for CCacheHash etc classes
+
+#include <polys/monomials/ring.h>
+#include <polys/monomials/p_polys.h>
+#include <reporter/reporter.h> // for Print!
+// //////////////////////////////////////////////////////////////////////// //
+//
+
+const int iMaxCacheSize = 20;
+
+template <typename CExponent>
+class CCacheHash
+{
+  private:
+    ring m_basering;
+    int m_NVars;
+
+  public:
+    CCacheHash(ring r): m_basering(r), m_NVars(r->N){};
+
+    ring GetBasering() const { return m_basering; };
+    inline int NVars() const { return m_NVars; }
+
+    virtual ~CCacheHash(){};
+
+
+    enum EHistoryType {
+      MULT_LOOKUP = 0,
+      MULT_STORE  = 1
+    };
+
+    struct CCacheItem
+    {
+      union{
+        CExponent aExponent;
+        poly aMonom;
+      } a;
+
+      union{
+        CExponent bExponent;
+        poly bMonom;
+      } b;
+
+      poly pProduct;
+
+      int iPairType;
+      long lHits;
+    };
+
+
+    // -1 means no hits!
+    int LookupEE(CExponent a, CExponent b, CCacheItem*& pItems)
+    {
+/*
+      PrintS("//////////////////////////////////////////////////////////////////////////////////////////////");
+      PrintLn();
+      PrintS("CCacheHash::LookupEE(a, b, *results)!");
+      PrintLn();
+*/
+      History(MULT_LOOKUP, a, b);
+
+      pItems = NULL;
+      return -1;
+    }
+
+    bool StoreEE(CExponent a, CExponent b, poly pProduct)
+    {
+/*
+      PrintS("CCacheHash::StoreEE(a, b, Product)!");
+      PrintLn();
+*/
+
+      History(MULT_STORE, a, b, pProduct);
+
+/*
+      PrintS("\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\");
+      PrintLn();
+*/
+
+      return false; // the pair was not stored!
+    };
+
+    virtual void History(const EHistoryType , const CExponent /*a*/, const CExponent /*b*/, const poly = NULL)
+    {
+      PrintS("CCacheHash::History(a, b, [p])!\n");
+    }
+
+  private: // no copy constuctors!
+    CCacheHash(const CCacheHash&);
+    CCacheHash& operator=(const CCacheHash&);
+};
+
+
+
+class CGlobalCacheHash: public CCacheHash<poly>
+{
+  public:
+    typedef poly CExponent;
+
+    CGlobalCacheHash(ring r): CCacheHash<poly>(r) {};
+
+    virtual ~CGlobalCacheHash() {};
+
+  protected:
+    virtual void History(const EHistoryType t, const CExponent a, const CExponent b, const poly p = NULL);
+};
+
+class CSpecialPairCacheHash: public CCacheHash<int>
+{
+  public:
+    typedef int CExponent;
+
+    CSpecialPairCacheHash(ring r): CCacheHash<int>(r) {};
+
+    virtual ~CSpecialPairCacheHash() {};
+
+  protected:
+    virtual void History(const EHistoryType t, const CExponent a, const CExponent b, const poly p = NULL);
+};
+
+
+
+#endif // GRING_SA_CACHEHASH_H
+
+
diff --git a/libpolys/polys/nc/ncSAFormula.cc b/libpolys/polys/nc/ncSAFormula.cc
new file mode 100644
index 0000000..68e5e34
--- /dev/null
+++ b/libpolys/polys/nc/ncSAFormula.cc
@@ -0,0 +1,759 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    ncSAFormula.cc
+ *  Purpose: implementation of multiplication by formulas in simple NC subalgebras
+ *  Author:  motsak
+ *  Created:
+ *******************************************************************/
+
+#define MYTEST 0
+
+#if MYTEST
+#define OM_CHECK 4
+#define OM_TRACK 5
+// these settings must be before "mod2.h" in order to work!!!
+#endif
+
+
+
+
+
+#include <misc/auxiliary.h>
+
+#ifdef HAVE_PLURAL
+
+#define PLURAL_INTERNAL_DECLARATIONS
+
+#ifndef SING_NDEBUG
+#define OUTPUT MYTEST
+#else
+#define OUTPUT 0
+#endif
+
+#include <reporter/reporter.h>
+
+#include <coeffs/numbers.h>
+#include "coeffrings.h"
+
+#include "nc/ncSAFormula.h"
+// for CFormulaPowerMultiplier
+
+#include "monomials/ring.h"
+#include "monomials/p_polys.h"
+
+#include "nc/sca.h"
+
+
+
+
+bool ncInitSpecialPowersMultiplication(ring r)
+{
+#if OUTPUT
+  Print("ncInitSpecialPowersMultiplication(ring), ring: \n");
+  rWrite(r, TRUE);
+  PrintLn();
+#endif
+
+  assume(rIsPluralRing(r));
+  assume(!rIsSCA(r));
+
+
+  if( r->GetNC()->GetFormulaPowerMultiplier() != NULL )
+  {
+    WarnS("Already defined!");
+    return false;
+  }
+
+
+  r->GetNC()->GetFormulaPowerMultiplier() = new CFormulaPowerMultiplier(r);
+
+  return true;
+
+}
+
+
+
+
+
+
+
+// TODO: return q-coeff?
+static inline BOOLEAN AreCommutingVariables(const ring r, int i, int j/*, number *qq*/)
+{
+#if OUTPUT
+  Print("AreCommutingVariables(ring, k: %d, i: %d)!", j, i);
+  PrintLn();
+#endif
+
+  assume(i != j);
+
+  assume(i > 0);
+  assume(i <= r->N);
+
+
+  assume(j > 0);
+  assume(j <= r->N);
+
+  const BOOLEAN reverse = (i > j);
+
+  if (reverse) { int k = j; j = i; i = k; }
+
+  assume(i < j);
+
+  {
+    const poly d = GetD(r, i, j);
+
+#if OUTPUT
+    Print("D_{%d, %d} = ", i, j); p_Write(d, r);
+#endif
+
+    if( d != NULL)
+      return FALSE;
+  }
+
+
+  {
+    const number q = p_GetCoeff(GetC(r, i, j), r);
+
+    if( !n_IsOne(q, r) )
+      return FALSE;
+  }
+
+  return TRUE; // [VAR(I), VAR(J)] = 0!!
+
+/*
+  if (reverse)
+    *qq = n_Invers(q, r);
+  else
+    *qq = n_Copy(q, r);
+  return TRUE;
+*/
+}
+
+static inline Enum_ncSAType AnalyzePairType(const ring r, int i, int j)
+{
+#if OUTPUT
+  Print("AnalyzePair(ring, i: %d, j: %d):", i, j);
+  PrintLn();
+#endif
+
+  const int N = r->N;
+
+  assume(i < j);
+  assume(i > 0);
+  assume(j <= N);
+
+
+  const poly c = GetC(r, i, j);
+  const number q = p_GetCoeff(c, r);
+  const poly d = GetD(r, i, j);
+
+#if 0 && OUTPUT
+  Print("C_{%d, %d} = ", i, j); p_Write(c, r); PrintLn();
+  Print("D_{%d, %d} = ", i, j); p_Write(d, r);
+#endif
+
+//  const number q = p_GetCoeff(c, r);
+
+  if( d == NULL)
+  {
+
+    if( n_IsOne(q, r) ) // commutative
+      return _ncSA_1xy0x0y0;
+
+    if( n_IsMOne(q, r) ) // anti-commutative
+      return _ncSA_Mxy0x0y0;
+
+    return _ncSA_Qxy0x0y0; // quasi-commutative
+  } else
+  {
+    if( n_IsOne(q, r) ) // "Lie" case
+    {
+      if( pNext(d) == NULL ) // Our Main Special Case: d is only a term!
+      {
+//         const number g = p_GetCoeff(d, r); // not used for now
+        if( p_LmIsConstantComp(d, r) ) // Weyl
+          return _ncSA_1xy0x0yG;
+
+        const int k = p_IsPurePower(d, r); // k if not pure power
+
+        if( k > 0 ) // d = var(k)^??
+        {
+          const int exp = p_GetExp(d, k, r);
+
+          if (exp == 1)
+          {
+            if(k == i) // 2 -ubalgebra in var(i) & var(j), with linear relation...?
+              return _ncSA_1xyAx0y0;
+
+            if(k == j)
+              return _ncSA_1xy0xBy0;
+          } else if ( exp == 2 && k!= i && k != j)  // Homogenized Weyl algebra [x, Dx] = t^2?
+          {
+//            number qi, qj;
+            if (AreCommutingVariables(r, k, i/*, &qi*/) && AreCommutingVariables(r, k, j/*, &qj*/) ) // [x, t] = [Dx, t] = 0?
+            {
+              const number g = p_GetCoeff(d, r);
+
+              if (n_IsOne(g, r))
+                return _ncSA_1xy0x0yT2; // save k!?, G = LC(d) == qi == qj == 1!!!
+            }
+          }
+        }
+      }
+    }
+    // Hmm, what about a more general case of q != 1???
+  }
+#if OUTPUT
+  Print("C_{%d, %d} = ", i, j); p_Write(c, r);
+  Print("D_{%d, %d} = ", i, j); p_Write(d, r);
+  PrintS("====>>>>_ncSA_notImplemented\n");
+#endif
+
+  return _ncSA_notImplemented;
+}
+
+
+CFormulaPowerMultiplier::CFormulaPowerMultiplier(ring r): m_NVars(r->N), m_BaseRing(r)
+{
+#if OUTPUT
+  Print("CFormulaPowerMultiplier::CFormulaPowerMultiplier(ring)!");
+  PrintLn();
+#endif
+
+  m_SAPairTypes = (Enum_ncSAType*)omAlloc0( ((NVars() * (NVars()-1)) / 2) * sizeof(Enum_ncSAType) );
+
+  for( int i = 1; i < NVars(); i++ )
+    for( int j = i + 1; j <= NVars(); j++ )
+      GetPair(i, j) = AnalyzePairType(GetBasering(), i, j);
+}
+
+
+
+
+CFormulaPowerMultiplier::~CFormulaPowerMultiplier()
+{
+#if OUTPUT
+  Print("CFormulaPowerMultiplier::~CFormulaPowerMultiplier()!");
+  PrintLn();
+#endif
+
+  omFreeSize((ADDRESS)m_SAPairTypes, ((NVars() * (NVars()-1)) / 2) * sizeof(Enum_ncSAType) );
+}
+
+
+
+
+///////////////////////////////////////////////////////////////////////////////////////////
+static inline void CorrectPolyWRTOrdering(poly &pResult, const ring r)
+{
+  if( pNext(pResult) != NULL )
+  {
+    const int cmp = p_LmCmp(pResult, pNext(pResult), r);
+    assume( cmp != 0 ); // must not be equal!!!
+    if( cmp != 1 ) // Wrong order!!!
+      pResult = pReverse(pResult); // Reverse!!!
+  }
+  p_Test(pResult, r);
+}
+///////////////////////////////////////////////////////////////////////////////////////////
+static inline poly ncSA_1xy0x0y0(const int i, const int j, const int n, const int m, const ring r)
+{
+#if OUTPUT
+  Print("ncSA_1xy0x0y0(var(%d)^{%d}, var(%d)^{%d}, r)!", j, m, i, n);
+  PrintLn();
+#endif
+
+  poly p = p_One( r);
+  p_SetExp(p, j, m, r);
+  p_SetExp(p, i, n, r);
+  p_Setm(p, r);
+
+  p_Test(p, r);
+
+  return p;
+
+} // 	return ncSA_1xy0x0y0(GetI(), GetJ(), expRight, expLeft, r);
+///////////////////////////////////////////////////////////////////////////////////////////
+static inline poly ncSA_Mxy0x0y0(const int i, const int j, const int n, const int m, const ring r)
+{
+#if OUTPUT
+  Print("ncSA_{M = -1}xy0x0y0(var(%d)^{%d}, var(%d)^{%d}, r)!", j, m, i, n);
+  PrintLn();
+#endif
+
+  const int  sign = 1 - ((n & (m & 1)) << 1);
+  poly p = p_ISet(sign, r);
+  p_SetExp(p, j, m, r);
+  p_SetExp(p, i, n, r);
+  p_Setm(p, r);
+
+
+  p_Test(p, r);
+
+  return p;
+
+} // 	return ncSA_Mxy0x0y0(GetI(), GetJ(), expRight, expLeft, r);
+///////////////////////////////////////////////////////////////////////////////////////////
+static inline poly ncSA_Qxy0x0y0(const int i, const int j, const int n, const int m, const number m_q, const ring r)
+{
+#if OUTPUT
+  Print("ncSA_Qxy0x0y0(var(%d)^{%d}, var(%d)^{%d}, Q, r)!", j, m, i, n);
+  PrintLn();
+#endif
+
+  int min, max;
+
+  if( n < m )
+  {
+    min = n;
+    max = m;
+  } else
+  {
+    min = m;
+    max = n;
+  }
+
+  number qN;
+
+  if( max == 1 )
+    qN = n_Copy(m_q, r);
+  else
+  {
+    number t;
+    n_Power(m_q, max, &t, r);
+
+    if( min > 1 )
+    {
+      n_Power(t, min, &qN, r);
+      n_Delete(&t, r);
+    }
+    else
+      qN = t;
+  }
+
+  poly p = p_NSet(qN, r);
+  p_SetExp(p, j, m, r);
+  p_SetExp(p, i, n, r);
+  p_Setm(p, r);
+
+
+  p_Test(p, r);
+
+  return p;
+
+} // 	return ncSA_Qxy0x0y0(GetI(), GetJ(), expRight, expLeft, m_q, r);
+///////////////////////////////////////////////////////////////////////////////////////////
+static inline poly ncSA_1xy0x0yG(const int i, const int j, const int n, const int m, const number m_g, const ring r)
+{
+#if OUTPUT
+  Print("ncSA_1xy0x0yG(var(%d)^{%d}, var(%d)^{%d}, G, r)!", j, m, i, n);
+  PrintLn();
+  number t = n_Copy(m_g, r);
+  PrintS("Parameter G: "); n_Write(t, r);
+  n_Delete(&t, r);
+#endif
+
+  int kn = n;
+  int km = m;
+
+  number c = n_Init(1, r);
+
+  poly p = p_One( r);
+
+  p_SetExp(p, j, km--, r); // y ^ (m-k)
+  p_SetExp(p, i, kn--, r); // x ^ (n-k)
+
+  p_Setm(p, r); // pResult = x^n * y^m
+
+
+  poly pResult = p;
+  poly pLast = p;
+
+  int min = si_min(m, n);
+
+  int k = 1;
+
+  for(; k < min; k++ )
+  {
+    number t = n_Init(km + 1, r);
+    n_InpMult(t, m_g, r); // t = ((m - k) + 1) * gamma
+    n_InpMult(c, t, r);   // c = c'* ((m - k) + 1) * gamma
+    n_Delete(&t, r);
+
+    t = n_Init(kn + 1, r);
+    n_InpMult(c, t, r);   // c = (c'* ((m - k) + 1) * gamma) * ((n - k) + 1)
+    n_Delete(&t, r);
+
+    t = n_Init(k, r);
+    c = n_Div(c, t, r);
+    n_Delete(&t, r);
+
+//    n_Normalize(c, r);
+
+    t = n_Copy(c, r); // not the last!
+
+    p = p_NSet(t, r);
+
+    p_SetExp(p, j, km--, r); // y ^ (m-k)
+    p_SetExp(p, i, kn--, r); // x ^ (n-k)
+
+    p_Setm(p, r); // pResult = x^n * y^m
+
+    pNext(pLast) = p;
+    pLast = p;
+  }
+
+  assume(k == min);
+  assume((km == 0) || (kn == 0) );
+
+  {
+    n_InpMult(c, m_g, r);   // c = c'* gamma
+
+    if( km > 0 )
+    {
+      number t = n_Init(km + 1, r);
+      n_InpMult(c, t, r);   // c = (c'* gamma) * (m - k + 1)
+      n_Delete(&t, r);
+    }
+
+    if( kn > 0 )
+    {
+      number t = n_Init(kn + 1, r);
+      n_InpMult(c, t, r);   // c = (c'* gamma) * (n - k + 1)
+      n_Delete(&t, r);
+    }
+
+    number t = n_Init(k, r); // c = ((c'* gamma) * ((n - k + 1) * (m - k + 1))) / k;
+    c = n_Div(c, t, r);
+    n_Delete(&t, r);
+  }
+
+  p = p_NSet(c, r);
+
+  p_SetExp(p, j, km, r); // y ^ (m-k)
+  p_SetExp(p, i, kn, r); // x ^ (n-k)
+
+  p_Setm(p, r); //
+
+  pNext(pLast) = p;
+
+  CorrectPolyWRTOrdering(pResult, r);
+
+  return pResult;
+}
+///////////////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////
+static inline poly ncSA_1xy0x0yT2(const int i, const int j, const int n, const int m, const int m_k, const ring r)
+{
+#if OUTPUT
+  Print("ncSA_1xy0x0yT2(var(%d)^{%d}, var(%d)^{%d}, t: var(%d), r)!", j, m, i, n, m_k);
+  PrintLn();
+#endif
+
+  int kn = n;
+  int km = m;
+
+  // k == 0!
+  number c = n_Init(1, r);
+
+  poly p = p_One( r );
+
+  p_SetExp(p, j, km--, r); // y ^ (m)
+  p_SetExp(p, i, kn--, r); // x ^ (n)
+//  p_SetExp(p, m_k, k << 1, r); // homogenization with var(m_k) ^ (2*k)
+
+  p_Setm(p, r); // pResult = x^n * y^m
+
+
+  poly pResult = p;
+  poly pLast = p;
+
+  int min = si_min(m, n);
+
+  int k = 1;
+
+  for(; k < min; k++ )
+  {
+    number t = n_Init(km + 1, r);
+//    n_InpMult(t, m_g, r); // t = ((m - k) + 1) * gamma
+    n_InpMult(c, t, r);   // c = c'* ((m - k) + 1) * gamma
+    n_Delete(&t, r);
+
+    t = n_Init(kn + 1, r);
+    n_InpMult(c, t, r);   // c = (c'* ((m - k) + 1) * gamma) * ((n - k) + 1)
+    n_Delete(&t, r);
+
+    t = n_Init(k, r);
+    c = n_Div(c, t, r);
+    n_Delete(&t, r);
+
+// //    n_Normalize(c, r);
+
+    t = n_Copy(c, r); // not the last!
+
+    p = p_NSet(t, r);
+
+    p_SetExp(p, j, km--, r); // y ^ (m-k)
+    p_SetExp(p, i, kn--, r); // x ^ (n-k)
+
+    p_SetExp(p, m_k, k << 1, r); // homogenization with var(m_k) ^ (2*k)
+
+    p_Setm(p, r); // pResult = x^(n-k) * y^(m-k)
+
+    pNext(pLast) = p;
+    pLast = p;
+  }
+
+  assume(k == min);
+  assume((km == 0) || (kn == 0) );
+
+  {
+//    n_InpMult(c, m_g, r);   // c = c'* gamma
+
+    if( km > 0 )
+    {
+      number t = n_Init(km + 1, r);
+      n_InpMult(c, t, r);   // c = (c'* gamma) * (m - k + 1)
+      n_Delete(&t, r);
+    }
+
+    if( kn > 0 )
+    {
+      number t = n_Init(kn + 1, r);
+      n_InpMult(c, t, r);   // c = (c'* gamma) * (n - k + 1)
+      n_Delete(&t, r);
+    }
+
+    number t = n_Init(k, r); // c = ((c'* gamma) * ((n - k + 1) * (m - k + 1))) / k;
+    c = n_Div(c, t, r);
+    n_Delete(&t, r);
+  }
+
+  p = p_NSet(c, r);
+
+  p_SetExp(p, j, km, r); // y ^ (m-k)
+  p_SetExp(p, i, kn, r); // x ^ (n-k)
+
+  p_SetExp(p, m_k, k << 1, r); // homogenization with var(m_k) ^ (2*k)
+
+  p_Setm(p, r); //
+
+  pNext(pLast) = p;
+
+  CorrectPolyWRTOrdering(pResult, r);
+
+  return pResult;
+}
+///////////////////////////////////////////////////////////////////////////////////////////
+
+
+
+///////////////////////////////////////////////////////////////////////////////////////////
+static inline poly ncSA_ShiftAx(int i, int j, int n, int m, const number m_shiftCoef, const ring r)
+{
+  // Char == 0, otherwise - problem!
+
+  int k = m; // to 0
+
+  number c = n_Init(1, r); // k = m, C_k = 1
+  poly p = p_One( r);
+
+  p_SetExp(p, j, k, r); // Y^{k}
+  p_SetExp(p, i, n, r);
+
+  p_Setm(p, r); // pResult = C_k * x^n * y^k, k == m
+
+
+  poly pResult = p;
+  poly pLast = p;
+
+  number nn =  n_Init(n, r); // number(n)!
+  n_InpMult(nn, m_shiftCoef, r); // nn = (alpha*n)
+
+  --k;
+
+  int mk = 1; // mk = (m - k)
+
+  for(; k > 0; k-- )
+  {
+    number t = n_Init(k + 1, r);  // t = k+1
+    n_InpMult(c, t, r);           // c = c' * (k+1)
+    n_InpMult(c, nn, r);          // c = (c' * (k+1)) * (alpha * n)
+
+    n_Delete(&t, r);
+    t = n_Init(mk++, r);
+    c = n_Div(c, t, r);           // c = ((c' * (k+1))  * (alpha * n)) / (m-k);
+    n_Delete(&t, r);
+
+//    n_Normalize(c, r);
+
+    t = n_Copy(c, r); // not the last!
+
+    p = p_NSet(t, r);
+
+    p_SetExp(p, j, k, r); // y^k
+    p_SetExp(p, i, n, r); // x^n
+
+    p_Setm(p, r); // pResult = x^n * y^m
+
+    pNext(pLast) = p;
+    pLast = p;
+  }
+
+  assume(k == 0);
+
+  {
+    n_InpMult(c, nn, r);          // c = (c' * (0+1)) * (alpha * n)
+
+    number t = n_Init(m, r);
+    c = n_Div(c, t, r);           // c = ((c' * (0+1))  * (alpha * n)) / (m-0);
+    n_Delete(&t, r);
+  }
+
+  n_Delete(&nn, r);
+
+  p = p_NSet(c, r);
+
+  p_SetExp(p, j, k, r); // y^k
+  p_SetExp(p, i, n, r); // x^n
+
+  p_Setm(p, r); //
+
+  pNext(pLast) = p;
+
+  CorrectPolyWRTOrdering(pResult, r);
+
+  return pResult;
+}
+///////////////////////////////////////////////////////////////////////////////////////////
+static inline poly ncSA_1xyAx0y0(const int i, const int j, const int n, const int m, const number m_shiftCoef, const ring r)
+{
+#if OUTPUT
+  Print("ncSA_1xyAx0y0(var(%d)^{%d}, var(%d)^{%d}, A, r)!", j, m, i, n);
+  PrintLn();
+  number t = n_Copy(m_shiftCoef, r);
+  PrintS("Parameter A: "); n_Write(t, r);
+  n_Delete(&t, r);
+#endif
+
+  return ncSA_ShiftAx(i, j, n, m, m_shiftCoef, r);
+}
+///////////////////////////////////////////////////////////////////////////////////////////
+static inline poly ncSA_1xy0xBy0(const int i, const int j, const int n, const int m, const number m_shiftCoef, const ring r)
+{
+#if OUTPUT
+  Print("ncSA_1xy0xBy0(var(%d)^{%d}, var(%d)^{%d}, B, r)!", j, m, i, n);
+  PrintLn();
+  number t = n_Copy(m_shiftCoef, r);
+  PrintS("Parameter B: "); n_Write(t, r);
+  n_Delete(&t, r);
+#endif
+
+  return ncSA_ShiftAx(j, i, m, n, m_shiftCoef, r);
+}
+///////////////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////
+
+
+static inline poly ncSA_Multiply( Enum_ncSAType type, const int i, const int j, const int n, const int m, const ring r)
+{
+#if OUTPUT
+  Print("ncSA_Multiply(type: %d, ring, (var(%d)^{%d} * var(%d)^{%d}, r)!", (int)type, j, m, i, n);
+  PrintLn();
+#endif
+
+  assume( type != _ncSA_notImplemented );
+  assume( (n > 0) && (m > 0) );
+
+  if( type == _ncSA_1xy0x0y0 )
+    return ::ncSA_1xy0x0y0(i, j, n, m, r);
+
+  if( type == _ncSA_Mxy0x0y0 )
+    return ::ncSA_Mxy0x0y0(i, j, n, m, r);
+
+  if( type == _ncSA_Qxy0x0y0 )
+  {
+    const number q = p_GetCoeff(GetC(r, i, j), r);
+    return ::ncSA_Qxy0x0y0(i, j, n, m, q, r);
+  }
+
+  const poly d = GetD(r, i, j);
+  const number g = p_GetCoeff(d, r);
+
+  if( type == _ncSA_1xy0x0yG ) // Weyl
+    return ::ncSA_1xy0x0yG(i, j, n, m, g, r);
+
+  if( type == _ncSA_1xy0x0yT2 ) // Homogenous Weyl...
+    return ::ncSA_1xy0x0yT2(i, j, n, m, p_IsPurePower(d, r), r);
+
+  if( type == _ncSA_1xyAx0y0 ) // Shift 1
+    return ::ncSA_1xyAx0y0(i, j, n, m, g, r);
+
+  if( type == _ncSA_1xy0xBy0 ) // Shift 2
+    return ::ncSA_1xy0xBy0(i, j, n, m, g, r);
+
+  assume( type == _ncSA_notImplemented );
+
+  return NULL;
+}
+
+
+poly CFormulaPowerMultiplier::Multiply( Enum_ncSAType type, const int i, const int j, const int n, const int m, const ring r)
+{
+  return ncSA_Multiply( type, i, j, n, m, r);
+}
+
+
+Enum_ncSAType CFormulaPowerMultiplier::AnalyzePair(const ring r, int i, int j)
+{
+  return ::AnalyzePairType( r, i, j);
+}
+
+poly CFormulaPowerMultiplier::Multiply( int i, int j, const int n, const int m)
+{
+  return ncSA_Multiply( GetPair(i, j), i, j, n, m, GetBasering());
+}
+
+
+
+
+poly CFormulaPowerMultiplier::ncSA_1xy0x0y0(const int i, const int j, const int n, const int m, const ring r)
+{
+  return ::ncSA_1xy0x0y0(i, j, n, m, r);
+}
+
+poly CFormulaPowerMultiplier::ncSA_Mxy0x0y0(const int i, const int j, const int n, const int m, const ring r)
+{
+  return ::ncSA_Mxy0x0y0(i, j, n, m, r);
+}
+
+poly CFormulaPowerMultiplier::ncSA_Qxy0x0y0(const int i, const int j, const int n, const int m, const number m_q, const ring r)
+{
+  return ::ncSA_Qxy0x0y0(i, j, n, m, m_q, r);
+}
+
+poly CFormulaPowerMultiplier::ncSA_1xy0x0yG(const int i, const int j, const int n, const int m, const number m_g, const ring r)
+{
+  return ::ncSA_1xy0x0yG(i, j, n, m, m_g, r);
+}
+
+poly CFormulaPowerMultiplier::ncSA_1xy0x0yT2(const int i, const int j, const int n, const int m, const int k, const ring r)
+{
+  return ::ncSA_1xy0x0yT2(i, j, n, m, k, r);
+}
+
+poly CFormulaPowerMultiplier::ncSA_1xyAx0y0(const int i, const int j, const int n, const int m, const number m_shiftCoef, const ring r)
+{
+  return ::ncSA_1xyAx0y0(i, j, n, m, m_shiftCoef, r);
+}
+
+poly CFormulaPowerMultiplier::ncSA_1xy0xBy0(const int i, const int j, const int n, const int m, const number m_shiftCoef, const ring r)
+{
+  return ::ncSA_1xy0xBy0(i, j, n, m, m_shiftCoef, r);
+}
+#endif
diff --git a/libpolys/polys/nc/ncSAFormula.h b/libpolys/polys/nc/ncSAFormula.h
new file mode 100644
index 0000000..8edd214
--- /dev/null
+++ b/libpolys/polys/nc/ncSAFormula.h
@@ -0,0 +1,104 @@
+#ifndef GRING_SA_MULT_FORMULA_H
+#define GRING_SA_MULT_FORMULA_H
+/*****************************************
+ *  Computer Algebra System SINGULAR     *
+ *****************************************/
+#ifdef HAVE_PLURAL
+
+// #include <ncSAFormula.h> // for CFormulaPowerMultiplier and enum Enum_ncSAType
+
+// //////////////////////////////////////////////////////////////////////// //
+
+#include <polys/monomials/ring.h>
+#include <polys/nc/nc.h>
+
+bool ncInitSpecialPowersMultiplication(ring r);
+
+enum Enum_ncSAType
+{
+  _ncSA_notImplemented = -1,
+  _ncSA_1xy0x0y0 = 0x00, // commutative
+  _ncSA_Mxy0x0y0 = 0x01, // anti-commutative
+  _ncSA_Qxy0x0y0 = 0x02, // quasi-commutative
+  _ncSA_1xyAx0y0 = 0x10, // shift 1
+  _ncSA_1xy0xBy0 = 0x20, // shift 2
+  _ncSA_1xy0x0yG = 0x30, // Weyl
+  _ncSA_1xy0x0yT2 = 0x100 // homogenized Weyl algebra?
+};
+
+class CFormulaPowerMultiplier
+{
+  private:
+    Enum_ncSAType* m_SAPairTypes; // upper triangular submatrix of pairs 1 <= i < j <= N of a N x N matrix.
+
+    const int m_NVars;
+    const ring m_BaseRing;
+
+
+
+  public:
+    inline int NVars() const { return m_NVars; }
+    inline ring GetBasering() const { return m_BaseRing; }
+
+    CFormulaPowerMultiplier(ring r);
+    virtual ~CFormulaPowerMultiplier();
+
+    inline Enum_ncSAType GetPair(int i, int j) const
+    {
+      assume( m_SAPairTypes != NULL );
+      assume( i > 0 );
+      assume( i < j );
+      assume( j <= NVars() );
+
+      return m_SAPairTypes[( (NVars() * ((i)-1) - ((i) * ((i)-1))/2 + (j)-1) - (i) )];
+    }
+
+    inline Enum_ncSAType& GetPair(int i, int j)
+    {
+      assume( m_SAPairTypes != NULL );
+      assume( i > 0 );
+      assume( i < j );
+      assume( j <= NVars() );
+
+      return m_SAPairTypes[( (NVars() * ((i)-1) - ((i) * ((i)-1))/2 + (j)-1) - (i) )];
+    }
+
+    // Lowest level routines!
+    static Enum_ncSAType AnalyzePair(const ring r, int i, int j);
+    static poly Multiply( Enum_ncSAType type, const int i, const int j, const int n, const int m, const ring r);
+
+    static poly ncSA_1xy0x0y0(const int i, const int j, const int n, const int m, const ring r);
+    static poly ncSA_Mxy0x0y0(const int i, const int j, const int n, const int m, const ring r);
+
+    static poly ncSA_Qxy0x0y0(const int i, const int j, const int n, const int m, const number m_q, const ring r);
+
+    static poly ncSA_1xy0x0yG(const int i, const int j, const int n, const int m, const number m_g, const ring r);
+    static poly ncSA_1xy0x0yT2(const int i, const int j, const int n, const int m, const int k, const ring r);
+
+    static poly ncSA_1xyAx0y0(const int i, const int j, const int n, const int m, const number m_shiftCoef, const ring r);
+    static poly ncSA_1xy0xBy0(const int i, const int j, const int n, const int m, const number m_shiftCoef, const ring r);
+
+
+
+    // Higher level abstraction for keeping track of all the pair types!
+    poly Multiply( int i, int j, const int n, const int m);
+
+  private: // no copy constuctors!
+    CFormulaPowerMultiplier();
+    CFormulaPowerMultiplier(const CFormulaPowerMultiplier&);
+    CFormulaPowerMultiplier& operator=(const CFormulaPowerMultiplier&);
+
+
+};
+
+
+static inline CFormulaPowerMultiplier* GetFormulaPowerMultiplier(const ring r)
+{
+  return r->GetNC()->GetFormulaPowerMultiplier();
+}
+
+
+
+
+#endif // HAVE_PLURAL :(
+#endif //
diff --git a/libpolys/polys/nc/ncSAMult.cc b/libpolys/polys/nc/ncSAMult.cc
new file mode 100644
index 0000000..584f83f
--- /dev/null
+++ b/libpolys/polys/nc/ncSAMult.cc
@@ -0,0 +1,1114 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    ncSAMult.cc
+ *  Purpose: implementation of multiplication in simple NC subalgebras
+ *  Author:  motsak
+ *  Created:
+ *******************************************************************/
+
+#define MYTEST 0
+
+#if MYTEST
+#define OM_CHECK 4
+#define OM_TRACK 5
+// these settings must be before "mod2.h" in order to work!!!
+#endif
+
+
+
+
+
+#include <misc/auxiliary.h>
+
+#ifdef HAVE_PLURAL
+
+
+#ifndef SING_NDEBUG
+#define OUTPUT MYTEST
+#else
+#define OUTPUT 0
+#endif
+
+# define PLURAL_INTERNAL_DECLARATIONS
+#include "nc/nc.h"
+#include "nc/sca.h"
+
+#include <misc/options.h>
+#include <coeffs/numbers.h>
+#include "coeffrings.h"
+
+
+// #include <kernel/p_Procs.h>
+#include "monomials/ring.h"
+#include "monomials/p_polys.h"
+
+#include "nc/ncSAMult.h" // for CMultiplier etc classes
+// #include "nc/sca.h" // for SCA
+
+
+namespace
+{
+
+// poly functions defined in p_Procs: ;
+static poly ggnc_pp_Mult_mm(const poly p, const poly m, const ring r)
+{
+  if( (p == NULL) || (m == NULL) )
+    return NULL;
+
+  assume( (p != NULL) && (m != NULL) && (r != NULL) );
+
+#if OUTPUT
+  PrintS("VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV ggnc_pp_Mult_mm(p, m) VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV ");
+  PrintLn();
+  PrintS("p: "); p_Write(p, r);
+  PrintS("m: "); p_Write(m, r);
+#endif
+  poly pResult;
+
+  if (p_IsConstant(m, r))
+    pResult = pp_Mult_nn(p, p_GetCoeff(m,r),r);
+  else
+  {
+    CGlobalMultiplier* const pMultiplier = r->GetNC()->GetGlobalMultiplier();
+    assume( pMultiplier != NULL );
+
+    poly pMonom = pMultiplier->LM(m, r);
+    pResult = pMultiplier->MultiplyPE(p, pMonom);
+    p_Delete(&pMonom, r);
+    p_Test(pResult, r);
+    pResult = p_Mult_nn(pResult, p_GetCoeff(m, r), r);
+  }
+
+#if OUTPUT
+  p_Test(pResult, r);
+
+  PrintS("ggnc_pp_Mult_mm(p, m) => "); p_Write(pResult, r);
+  PrintS("p: "); p_Write(p, r);
+  PrintS("m: "); p_Write(m, r);
+  PrintS("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ");
+  PrintLn();
+#endif
+
+  return pResult;
+
+}
+
+static poly ggnc_p_Mult_mm(poly p, const poly m, const ring r)
+{
+  if( (p == NULL) || (m == NULL) )
+  {
+    p_Delete(&p, r);
+    return NULL;
+  }
+
+  assume( (p != NULL) && (m != NULL) && (r != NULL) );
+
+#if OUTPUT
+  PrintS("VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV ggnc_p_Mult_mm(p, m) VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV ");
+  PrintLn();
+  PrintS("p: ");
+  p_Write(p, r);
+  PrintS("m: ");
+  p_Write(m, r);
+#endif
+
+  poly pResult;
+
+  if (p_IsConstant(m, r))
+    pResult = p_Mult_nn(p, p_GetCoeff(m,r),r);
+  else
+  {
+    CGlobalMultiplier* const pMultiplier = r->GetNC()->GetGlobalMultiplier();
+    assume( pMultiplier != NULL );
+
+    poly pMonom = pMultiplier->LM(m, r);
+    pResult = pMultiplier->MultiplyPEDestroy(p, pMonom);
+    p_Delete(&pMonom, r);
+    p_Test(pResult, r);
+    pResult = p_Mult_nn(pResult, p_GetCoeff(m, r), r);
+  }
+
+#if OUTPUT
+  p_Test(pResult, r);
+
+  PrintS("ggnc_p_Mult_mm(p, m) => "); p_Write(pResult, r);
+//  PrintS("p: "); p_Write(p, r);
+  PrintS("m: "); p_Write(m, r);
+  PrintS("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ");
+  PrintLn();
+#endif
+
+  return pResult;
+
+}
+
+static poly ggnc_mm_Mult_p(const poly m, poly p, const ring r)
+{
+  if( (p == NULL) || (m == NULL) )
+  {
+    p_Delete(&p, r);
+    return NULL;
+  }
+
+  assume( (p != NULL) && (m != NULL) && (r != NULL) );
+
+  p_Test(m, r);
+  p_Test(p, r);
+
+#if OUTPUT
+  PrintS("VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV ggnc_mm_Mult_p(m, p) VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV ");
+  PrintLn();
+  PrintS("m: "); p_Write(m, r);
+  PrintS("p: "); p_Write(p, r);
+#endif
+
+  poly pResult;
+
+  if (p_IsConstant(m, r))
+    pResult = p_Mult_nn(p, p_GetCoeff(m,r),r);
+  else
+  {
+    CGlobalMultiplier* const pMultiplier = r->GetNC()->GetGlobalMultiplier();
+    assume( pMultiplier != NULL );
+
+    poly pMonom = pMultiplier->LM(m, r);
+    pResult = pMultiplier->MultiplyEPDestroy(pMonom, p);
+    p_Delete(&pMonom, r);
+    p_Test(pResult, r);
+    pResult = p_Mult_nn(pResult, p_GetCoeff(m, r), r);
+  }
+
+#if OUTPUT
+  p_Test(pResult, r);
+
+  PrintS("ggnc_mm_Mult_p(m, p) => "); p_Write(pResult, r);
+//  PrintS("p: "); p_Write(p, r);
+  PrintS("m: "); p_Write(m, r);
+  PrintS("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ");
+  PrintLn();
+#endif
+
+  return pResult;
+}
+
+static poly ggnc_mm_Mult_pp(const poly m, const poly p, const ring r)
+{
+  if( (p == NULL) || (m == NULL) )
+  {
+    return NULL;
+  }
+
+  assume( (p != NULL) && (m != NULL) && (r != NULL) );
+
+  p_Test(m, r);
+  p_Test(p, r);
+
+#if OUTPUT
+  PrintS("VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV ggnc_mm_Mult_pp(m, p) VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV ");
+  PrintLn();
+  PrintS("m: "); p_Write(m, r);
+  PrintS("p: "); p_Write(p, r);
+#endif
+
+  poly pResult;
+
+  if (p_IsConstant(m, r))
+    pResult = pp_Mult_nn(p, p_GetCoeff(m,r),r);
+  else
+  {
+    CGlobalMultiplier* const pMultiplier = r->GetNC()->GetGlobalMultiplier();
+    assume( pMultiplier != NULL );
+
+    poly pMonom = pMultiplier->LM(m, r);
+    pResult = pMultiplier->MultiplyEP(pMonom, p);
+    p_Delete(&pMonom, r);
+    p_Test(pResult, r);
+    pResult = p_Mult_nn(pResult, p_GetCoeff(m, r), r);
+  }
+
+#if OUTPUT
+  p_Test(pResult, r);
+
+  PrintS("ggnc_mm_Mult_pp(m, p) => "); p_Write(pResult, r);
+  PrintS("p: "); p_Write(p, r);
+  PrintS("m: "); p_Write(m, r);
+  PrintS("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ");
+  PrintLn();
+#endif
+
+  return pResult;
+}
+
+static void ggnc_p_ProcsSet(ring rGR, p_Procs_s* p_Procs)
+{
+#if OUTPUT
+  PrintS("|ggnc_p_ProcsSet()");
+  PrintLn();
+#endif
+
+  assume( p_Procs != NULL );
+
+  // "commutative"
+  p_Procs->p_Mult_mm  = rGR->p_Procs->p_Mult_mm  = ggnc_p_Mult_mm;
+  p_Procs->pp_Mult_mm = rGR->p_Procs->pp_Mult_mm = ggnc_pp_Mult_mm;
+
+  p_Procs->p_Minus_mm_Mult_qq = rGR->p_Procs->p_Minus_mm_Mult_qq = NULL;
+
+  // non-commutaitve multiplication by monomial from the left
+  rGR->GetNC()->p_Procs.mm_Mult_p   = ggnc_mm_Mult_p;
+  rGR->GetNC()->p_Procs.mm_Mult_pp  = ggnc_mm_Mult_pp;
+
+}
+
+}
+
+BOOLEAN ncInitSpecialPairMultiplication(ring r)
+{
+#if OUTPUT
+  PrintS("ncInitSpecialPairMultiplication(ring), ring: \n");
+  rWrite(r, TRUE);
+  PrintLn();
+#endif
+
+  if(!rIsPluralRing(r))// ; // :(((
+    return TRUE;
+
+  if(rIsSCA(r))
+    return TRUE;
+
+  if( r->GetNC()->GetGlobalMultiplier() != NULL )
+  {
+    WarnS("Already defined!");
+    return TRUE;
+  }
+
+  r->GetNC()->GetGlobalMultiplier() = new CGlobalMultiplier(r);
+
+  ggnc_p_ProcsSet(r, r->p_Procs);
+  return FALSE; // ok!
+}
+
+
+CGlobalMultiplier::CGlobalMultiplier(ring r):
+    CMultiplier<poly>(r), m_RingFormulaMultiplier(GetFormulaPowerMultiplier(r))
+{
+#if OUTPUT
+  PrintS("CGlobalMultiplier::CGlobalMultiplier(ring)!");
+  PrintLn();
+#endif
+
+//  m_cache = new CGlobalCacheHash(r);
+  m_powers = new CPowerMultiplier(r);
+}
+
+
+CGlobalMultiplier::~CGlobalMultiplier()
+{
+#if OUTPUT
+  PrintS("CGlobalMultiplier::~CGlobalMultiplier()!");
+  PrintLn();
+#endif
+
+//  delete m_cache;
+  delete m_powers;
+
+  // we cannot delete m_RingFormulaMultiplier as it belongs to the ring!
+}
+
+
+
+// Exponent * Exponent
+// TODO: handle components!!!
+poly CGlobalMultiplier::MultiplyEE(const CGlobalMultiplier::CExponent expLeft, const CGlobalMultiplier::CExponent expRight)
+{
+
+  const ring r = GetBasering();
+
+#if OUTPUT
+  PrintS("CGlobalMultiplier::MultiplyEE(expLeft, expRight)!");
+  PrintLn();
+  PrintS("expL: "); p_Write(expLeft, GetBasering());
+  PrintS("expR: "); p_Write(expRight, GetBasering());
+#endif
+
+//  CCacheHash<poly>::CCacheItem* pLookup;
+//
+//  int b = m_cache->LookupEE(expLeft, expRight, pLookup);
+//  // TODO!!!
+//
+//  // up to now:
+//  assume( b == -1 );
+
+  // TODO: use PowerMultiplier!!!!
+
+  poly product = NULL;
+
+  const int N = NVars();
+  int j = N;
+  int i = 1;
+
+  int ej = p_GetExp(expLeft, j, r);
+  int ei = p_GetExp(expRight, i, r);
+
+  while( (i < j) && !((ej != 0) && (ei != 0)) )
+  {
+    if( ei == 0 )
+      ei = p_GetExp(expRight, ++i, r);
+
+    if( ej == 0 )
+      ej = p_GetExp(expLeft, --j, r);
+  }
+
+
+#if OUTPUT
+  PrintS("<CGlobalMultiplier::MultiplyEE>");
+  PrintLn();
+  Print("i: %d, j: %d", i, j);
+  PrintLn();
+  Print("ei: %d, ej: %d", ei, ej);
+  PrintLn();
+#endif
+
+
+  // |  expLeft   | * |  expRight  |
+  // |<<<< ej 0..0| , |0..0 ei >>>>|
+  // |<<<<  j <<<N| , |1>>>  i >>>>|
+
+  if( i >= j ) // BUG here!!!???
+  {
+    // either i == j or i = j + 1 => commutative multiple!
+    // TODO: it can be done more efficiently! ()
+    product = p_Head(expRight, r);
+
+  // |  expLeft     | * |  expRight   |
+  // |<<<< ej 0....0| , |0..00 ei >>>>|
+  // |<<<<  j i <<<N| , |1>>>j  i >>>>|
+
+    if(i > j)
+    {
+      --i;
+      ei = 0;
+    }
+
+    if( i == j )
+    {
+      if( ej != 0 )
+        p_SetExp(product, i, ei + ej, r);
+    }
+
+    --i;
+
+    for(; i > 0; --i)
+    {
+      const int e = p_GetExp(expLeft, i, r);
+
+      if( e > 0 )
+        p_SetExp(product, i, e, r);
+    }
+
+    p_Setm(product, r);
+
+  } else
+  { // i < j, ei != 0, ej != 0
+
+    Enum_ncSAType PairType = _ncSA_notImplemented;
+
+    if( m_RingFormulaMultiplier != NULL )
+      PairType = m_RingFormulaMultiplier->GetPair(i, j);
+
+
+    if( PairType == _ncSA_notImplemented )
+      product = m_powers->MultiplyEE( CPower(j, ej), CPower(i, ei) );
+//    return ggnc_uu_Mult_ww_vert(i, a, j, b, r);
+    else
+ //    return m_RingFormulaMultiplier->Multiply(j, i, b, a);
+      product = CFormulaPowerMultiplier::Multiply( PairType, i, j, ei, ej, GetBasering());
+
+
+#if OUTPUT
+    PrintS("<CGlobalMultiplier::MultiplyEE> ==> ");
+    PrintLn();
+    Print("i: %d, j: %d", i, j);
+    PrintLn();
+    Print("ei: %d, ej: %d", ei, ej);
+    PrintLn();
+    PrintS("<product>: "); p_Write(product, GetBasering());
+#endif
+
+
+    // TODO: Choose some multiplication strategy!!!
+
+    while( (product != NULL) && !((i == NVars()) && (j == 1)) )
+    {
+
+      // make some choice here!:
+
+      if( i < NVars() )
+      {
+        ei = p_GetExp(expRight, ++i, r);
+
+        while( (ei == 0) && (i < NVars()) )
+          ei = p_GetExp(expRight, ++i, r);
+
+        if( ei != 0 )
+          product = m_powers->MultiplyPEDestroy(product, CPower(i, ei));
+      }
+
+      if( j > 1 )
+      {
+        ej = p_GetExp(expLeft, --j, r);
+
+        while( (ej == 0) && (1 < j) )
+          ej = p_GetExp(expLeft, --j, r);
+
+        if( ej != 0 )
+          product = m_powers->MultiplyEPDestroy(CPower(j, ej), product);
+      }
+
+
+#if OUTPUT
+      PrintS("<CGlobalMultiplier::MultiplyEE> ==> ");
+      PrintLn();
+      Print("i: %d, j: %d", i, j);
+      PrintLn();
+      Print("ei: %d, ej: %d", ei, ej);
+      PrintLn();
+      PrintS("<product>: "); p_Write(product, GetBasering());
+#endif
+
+    }
+
+  }
+
+//  // TODO!
+//
+//  m_cache->StoreEE( expLeft, expRight, product);
+//  // up to now:
+  return product;
+}
+
+    // Monom * Exponent
+poly CGlobalMultiplier::MultiplyME(const poly pMonom, const CGlobalMultiplier::CExponent expRight)
+{
+#if OUTPUT
+  PrintS("CGlobalMultiplier::MultiplyME(monom, expR)!");
+  PrintLn();
+  PrintS("Monom: "); p_Write(pMonom, GetBasering());
+  PrintS("expR: "); p_Write(expRight, GetBasering());
+#endif
+
+  return MultiplyEE(pMonom, expRight);
+}
+
+    // Exponent * Monom
+poly CGlobalMultiplier::MultiplyEM(const CGlobalMultiplier::CExponent expLeft, const poly pMonom)
+{
+#if OUTPUT
+  PrintS("CGlobalMultiplier::MultiplyEM(expL, monom)!");
+  PrintLn();
+  PrintS("expL: "); p_Write(expLeft, GetBasering());
+  PrintS("Monom: "); p_Write(pMonom, GetBasering());
+#endif
+
+  return MultiplyEE(expLeft, pMonom);
+}
+
+
+
+
+
+///////////////////////////////////////////////////////////////////////////////////////////
+CCommutativeSpecialPairMultiplier::CCommutativeSpecialPairMultiplier(ring r, int i, int j):
+    CSpecialPairMultiplier(r, i, j)
+{
+#if OUTPUT
+  Print("CCommutativeSpecialPairMultiplier::CCommutativeSpecialPairMultiplier(ring, i: %d, j: %d)!", i, j);
+  PrintLn();
+#endif
+}
+
+
+CCommutativeSpecialPairMultiplier::~CCommutativeSpecialPairMultiplier()
+{
+#if OUTPUT
+  PrintS("CCommutativeSpecialPairMultiplier::~CCommutativeSpecialPairMultiplier()");
+  PrintLn();
+#endif
+}
+
+// Exponent * Exponent
+poly CCommutativeSpecialPairMultiplier::MultiplyEE(const int expLeft, const int expRight)
+{
+#if OUTPUT
+  Print("CCommutativeSpecialPairMultiplier::MultiplyEE(var(%d)^{%d}, var(%d)^{%d})!", GetJ(), expLeft, GetI(), expRight);
+  PrintLn();
+#endif
+
+  const ring r = GetBasering();
+
+  return CFormulaPowerMultiplier::ncSA_1xy0x0y0(GetI(), GetJ(), expRight, expLeft, r);
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////
+CAntiCommutativeSpecialPairMultiplier::CAntiCommutativeSpecialPairMultiplier(ring r, int i, int j):
+		CSpecialPairMultiplier(r, i, j)
+{
+#if OUTPUT
+	Print("CAntiCommutativeSpecialPairMultiplier::CAntiCommutativeSpecialPairMultiplier(ring, i: %d, j: %d)!", i, j);
+	PrintLn();
+#endif
+}
+
+
+CAntiCommutativeSpecialPairMultiplier::~CAntiCommutativeSpecialPairMultiplier()
+{
+#if OUTPUT
+	PrintS("CAntiCommutativeSpecialPairMultiplier::~CAntiCommutativeSpecialPairMultiplier()");
+	PrintLn();
+#endif
+}
+
+// Exponent * Exponent
+poly CAntiCommutativeSpecialPairMultiplier::MultiplyEE(const int expLeft, const int expRight)
+{
+#if OUTPUT
+	Print("CAntiCommutativeSpecialPairMultiplier::MultiplyEE(var(%d)^{%d}, var(%d)^{%d})!", GetJ(), expLeft, GetI(), expRight);
+	PrintLn();
+#endif
+
+	const ring r = GetBasering();
+
+	return CFormulaPowerMultiplier::ncSA_Mxy0x0y0(GetI(), GetJ(), expRight, expLeft, r);
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////
+CQuasiCommutativeSpecialPairMultiplier::CQuasiCommutativeSpecialPairMultiplier(ring r, int i, int j, number q):
+		CSpecialPairMultiplier(r, i, j), m_q(q)
+{
+#if OUTPUT
+	Print("CQuasiCommutativeSpecialPairMultiplier::CQuasiCommutativeSpecialPairMultiplier(ring, i: %d, j: %d, q)!", i, j);
+	PrintLn();
+	PrintS("Parameter q: ");
+	n_Write(q, r);
+#endif
+}
+
+
+CQuasiCommutativeSpecialPairMultiplier::~CQuasiCommutativeSpecialPairMultiplier()
+{
+#if OUTPUT
+	PrintS("CQuasiCommutativeSpecialPairMultiplier::~CQuasiCommutativeSpecialPairMultiplier()");
+	PrintLn();
+#endif
+}
+
+// Exponent * Exponent
+poly CQuasiCommutativeSpecialPairMultiplier::MultiplyEE(const int expLeft, const int expRight)
+{
+#if OUTPUT
+	Print("CQuasiCommutativeSpecialPairMultiplier::MultiplyEE(var(%d)^{%d}, var(%d)^{%d})!", GetJ(), expLeft, GetI(), expRight);
+	PrintLn();
+#endif
+
+	const ring r = GetBasering();
+
+	return CFormulaPowerMultiplier::ncSA_Qxy0x0y0(GetI(), GetJ(), expRight, expLeft, m_q, r);
+}
+
+
+///////////////////////////////////////////////////////////////////////////////////////////
+CWeylSpecialPairMultiplier::CWeylSpecialPairMultiplier(ring r, int i, int j, number g):
+    CSpecialPairMultiplier(r, i, j), m_g(g)
+{
+#if OUTPUT
+  Print("CWeylSpecialPairMultiplier::CWeylSpecialPairMultiplier(ring, i: %d, j: %d, g)!", i, j);
+  PrintLn();
+  PrintS("Parameter g: ");
+  n_Write(g, r);
+#endif
+}
+
+
+CWeylSpecialPairMultiplier::~CWeylSpecialPairMultiplier()
+{
+#if OUTPUT
+  PrintS("CWeylSpecialPairMultiplier::~CWeylSpecialPairMultiplier()");
+  PrintLn();
+#endif
+}
+
+// Exponent * Exponent
+poly CWeylSpecialPairMultiplier::MultiplyEE(const int expLeft, const int expRight)
+{
+#if OUTPUT
+  Print("CWeylSpecialPairMultiplier::MultiplyEE(var(%d)^{%d}, var(%d)^{%d})!", GetJ(), expLeft, GetI(), expRight);
+  PrintLn();
+#endif
+  // Char == 0, otherwise - problem!
+
+
+  const ring r = GetBasering();
+
+  assume( expLeft*expRight > 0 );
+
+  return CFormulaPowerMultiplier::ncSA_1xy0x0yG(GetI(), GetJ(), expRight, expLeft, m_g, r);
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////
+CHWeylSpecialPairMultiplier::CHWeylSpecialPairMultiplier(ring r, int i, int j, int k):
+    CSpecialPairMultiplier(r, i, j), m_k(k)
+{
+#if OUTPUT
+  Print("CHWeylSpecialPairMultiplier::CHWeylSpecialPairMultiplier(ring, i: %d, j: %d, k: %d)!", i, j, k);
+  PrintLn();
+#endif
+}
+
+
+CHWeylSpecialPairMultiplier::~CHWeylSpecialPairMultiplier()
+{
+#if OUTPUT
+  PrintS("CHWeylSpecialPairMultiplier::~CHWeylSpecialPairMultiplier()");
+  PrintLn();
+#endif
+}
+
+// Exponent * Exponent
+poly CHWeylSpecialPairMultiplier::MultiplyEE(const int expLeft, const int expRight)
+{
+#if OUTPUT
+  Print("CHWeylSpecialPairMultiplier::MultiplyEE(var(%d)^{%d}, var(%d)^{%d})!", GetJ(), expLeft, GetI(), expRight);
+  PrintLn();
+#endif
+  // Char == 0, otherwise - problem!
+
+
+  const ring r = GetBasering();
+
+  assume( expLeft*expRight > 0 );
+
+  return CFormulaPowerMultiplier::ncSA_1xy0x0yT2(GetI(), GetJ(), expRight, expLeft, m_k, r);
+}
+
+
+///////////////////////////////////////////////////////////////////////////////////////////
+CShiftSpecialPairMultiplier::CShiftSpecialPairMultiplier(ring r, int i, int j, int s, number c):
+    CSpecialPairMultiplier(r, i, j), m_shiftCoef(c), m_shiftVar(s)
+{
+#if OUTPUT
+  Print("CShiftSpecialPairMultiplier::CShiftSpecialPairMultiplier(ring, i: %d, j: %d, s: %d, c)!", i, j, s);
+  PrintLn();
+  PrintS("Parameter c: "); n_Write(c, r);
+#endif
+}
+
+
+CShiftSpecialPairMultiplier::~CShiftSpecialPairMultiplier()
+{
+#if OUTPUT
+  PrintS("CShiftSpecialPairMultiplier::~CShiftSpecialPairMultiplier()");
+  PrintLn();
+#endif
+}
+
+// Exponent * Exponent
+poly CShiftSpecialPairMultiplier::MultiplyEE(const int expLeft, const int expRight)
+{
+#if OUTPUT
+  Print("CShiftSpecialPairMultiplier::MultiplyEE(var(%d)^{%d}, var(%d)^{%d})!", GetJ(), expLeft, GetI(), expRight);
+  PrintLn();
+#endif
+  // Char == 0, otherwise - problem!
+
+  assume( expLeft*expRight > 0 );
+
+  const ring r = GetBasering();
+
+  if( m_shiftVar != GetI() ) // YX = XY + b*Y?
+    return CFormulaPowerMultiplier::ncSA_1xy0xBy0(GetI(), GetJ(), expRight, expLeft, m_shiftCoef, r); // case: (1, 0, beta, 0, 0)
+  else
+    return CFormulaPowerMultiplier::ncSA_1xyAx0y0(GetI(), GetJ(), expRight, expLeft, m_shiftCoef, r); // case: (1, alpha, 0, 0)
+
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////////////////////
+CExternalSpecialPairMultiplier::CExternalSpecialPairMultiplier(ring r, int i, int j, Enum_ncSAType type):
+    CSpecialPairMultiplier(r, i, j), m_ncSAtype(type)
+{
+#if OUTPUT
+  Print("CExternalSpecialPairMultiplier::CExternalSpecialPairMultiplier(ring, i: %d, j: %d, type: %d, c)!", i, j, (int)type);
+  PrintLn();
+#endif
+}
+
+
+CExternalSpecialPairMultiplier::~CExternalSpecialPairMultiplier()
+{
+#if OUTPUT
+  PrintS("CExternalSpecialPairMultiplier::~CExternalSpecialPairMultiplier()");
+  PrintLn();
+#endif
+}
+
+// Exponent * Exponent
+poly CExternalSpecialPairMultiplier::MultiplyEE(const int expLeft, const int expRight)
+{
+#if OUTPUT
+  Print("CExternalSpecialPairMultiplier::MultiplyEE(var(%d)^{%d}, var(%d)^{%d})!", GetJ(), expLeft, GetI(), expRight);
+  PrintLn();
+#endif
+  // Char == 0, otherwise - problem!
+
+  assume( expLeft*expRight > 0 );
+
+  const ring r = GetBasering();
+
+  return CFormulaPowerMultiplier::Multiply(m_ncSAtype, GetI(), GetJ(), expRight, expLeft, r);
+
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////////////////////
+
+// factory method!
+CSpecialPairMultiplier* AnalyzePair(const ring r, int i, int j)
+{
+#if OUTPUT
+  Print("AnalyzePair(ring, i: %d, j: %d)!", i, j);
+  PrintLn();
+#endif
+
+  Enum_ncSAType type = CFormulaPowerMultiplier::AnalyzePair(r, i, j);
+
+  if( type == _ncSA_notImplemented ) return NULL;
+
+
+  // last possibility:
+  return new CExternalSpecialPairMultiplier(r, i, j, type); // For tests!
+
+
+  if( type == _ncSA_1xy0x0y0 )
+    return new CCommutativeSpecialPairMultiplier(r, i, j);
+
+  if( type == _ncSA_Mxy0x0y0 )
+    return new CAntiCommutativeSpecialPairMultiplier(r, i, j);
+
+  if( type == _ncSA_Qxy0x0y0 )
+  {
+    const number q = p_GetCoeff(GetC(r, i, j), r);
+    return new CQuasiCommutativeSpecialPairMultiplier(r, i, j, q);
+  }
+
+  const poly d = GetD(r, i, j);
+
+  assume( d != NULL );
+  assume( pNext(d) == NULL );
+
+  const number g = p_GetCoeff(d, r);
+
+  if( type == _ncSA_1xy0x0yG ) // Weyl
+    return new CWeylSpecialPairMultiplier(r, i, j, g);
+
+  if( type == _ncSA_1xyAx0y0 ) // Shift 1
+    return new CShiftSpecialPairMultiplier(r, i, j, i, g);
+
+  if( type == _ncSA_1xy0xBy0 ) // Shift 2
+    return new CShiftSpecialPairMultiplier(r, i, j, j, g);
+
+  if( type == _ncSA_1xy0x0yT2 ) // simple homogenized Weyl algebra
+    return new CHWeylSpecialPairMultiplier(r, i, j, p_IsPurePower(d, r));
+
+}
+
+
+
+
+
+
+CPowerMultiplier::CPowerMultiplier(ring r): CMultiplier<CPower>(r)
+{
+#if OUTPUT
+  PrintS("CPowerMultiplier::CPowerMultiplier(ring)!");
+  PrintLn();
+#endif
+
+  m_specialpairs = (CSpecialPairMultiplier**)omAlloc0( ((NVars() * (NVars()-1)) / 2) * sizeof(CSpecialPairMultiplier*) );
+
+  for( int i = 1; i < NVars(); i++ )
+    for( int j = i + 1; j <= NVars(); j++ )
+      GetPair(i, j) = AnalyzePair(GetBasering(), i, j); // factory method!
+}
+
+
+CPowerMultiplier::~CPowerMultiplier()
+{
+#if OUTPUT
+  PrintS("CPowerMultiplier::~CPowerMultiplier()!");
+  PrintLn();
+#endif
+
+  omFreeSize((ADDRESS)m_specialpairs, ((NVars() * (NVars()-1)) / 2) * sizeof(CSpecialPairMultiplier*) );
+}
+
+
+// Monom * Exponent
+// pMonom may NOT be of the form: var(j)^{n}!
+poly CPowerMultiplier::MultiplyME(const poly pMonom, const CExponent expRight)
+{
+  const int j = expRight.Var;
+  const int n = expRight.Power;
+
+  const ring r = GetBasering();
+
+#if OUTPUT
+  Print("CPowerMultiplier::MultiplyME(monom * var(%d)^{%d})!", j, n);
+  PrintLn();
+  PrintS("Monom: "); p_Write(pMonom, r);
+#endif
+
+  assume( (j > 0) && (j <= NVars()));
+
+  if( n == 0 )
+    return p_Head(pMonom, r); // Copy?!?
+
+
+  int v = NVars();
+  int e = p_GetExp(pMonom, v, r);
+
+  while((v > j) && (e == 0))
+    e = p_GetExp(pMonom, --v, r);
+
+  // TODO: review this!
+  if( v == j )
+  {
+    poly p = p_Head(pMonom, r);
+    p_SetExp(p, v, e + n, r);
+    p_Setm(p, r);
+
+    return p;
+  }
+
+  assume( v > j );
+  assume( e > 0 );
+
+  // And now the General Case: v > j!
+
+  poly p = MultiplyEE( CPower(v, e), expRight ); // Easy way!
+
+  --v;
+
+  while(v > 0)
+  {
+    e = p_GetExp(pMonom, v, GetBasering());
+
+    if( e > 0 )
+      p = MultiplyEPDestroy(CPower(v, e), p);
+
+    --v;
+  }
+
+#if OUTPUT
+  PrintS("CPowerMultiplier::MultiplyME() ===> ");
+  p_Write(p, GetBasering());
+#endif
+
+  return p;
+}
+
+// Exponent * Monom
+// pMonom may NOT be of the form: var(i)^{m}!
+poly CPowerMultiplier::MultiplyEM(const CExponent expLeft, const poly pMonom)
+{
+  const ring r = GetBasering();
+
+  // TODO: as above! (difference due to Left/Right semmantics!)
+  const int j = expLeft.Var;
+  const int n = expLeft.Power;
+
+#if OUTPUT
+  Print("CPowerMultiplier::MultiplyEM(var(%d)^{%d} * monom)!", j, n);
+  PrintLn();
+  PrintS("Monom: "); p_Write(pMonom, r);
+#endif
+
+  assume( (j > 0) && (j <= NVars()));
+
+  if( n == 0 )
+    return p_Head(pMonom, r); // Copy?!?
+
+
+  int v = 1; // NVars();
+  int e = p_GetExp(pMonom, v, r);
+
+  while((v < j) && (e == 0))
+    e = p_GetExp(pMonom, ++v, r);
+
+  if( v == j )
+  {
+    poly p = p_Head(pMonom, r);
+    p_SetExp(p, j, e + n, r);
+    p_Setm(p, r);
+
+    return p;
+  }
+
+  assume( v < j );
+  assume( e > 0 );
+
+
+  // And now the General Case: v > j!
+
+  poly p = MultiplyEE( expLeft, CPower(v, e) ); // Easy way!
+
+  ++v;
+
+  while(v <= NVars())
+  {
+    e = p_GetExp(pMonom, v, r);
+
+    if( e > 0 )
+      p = MultiplyPEDestroy(p, CPower(v, e));
+
+    ++v;
+  }
+
+#if OUTPUT
+  PrintS("CPowerMultiplier::MultiplyEM() ===> ");
+  p_Write(p, r);
+#endif
+
+  return p;
+
+}
+
+
+// Exponent * Exponent
+// Computes: var(j)^{expLeft} * var(i)^{expRight}
+poly CPowerMultiplier::MultiplyEE(const CExponent expLeft, const CExponent expRight)
+{
+#if OUTPUT
+  PrintS("CPowerMultiplier::MultiplyEE)!");
+  PrintLn();
+#endif
+
+  const int i = expRight.Var, j = expLeft.Var;
+  const int ei = expRight.Power, ej = expLeft.Power;
+
+#if OUTPUT
+  Print("Input: var(%d)^{%d} * var(%d)^{%d}", j, ej, i, ei);
+  PrintLn();
+#endif
+
+  assume(1 <= i);
+  assume(j <= NVars());
+  assume(1 <= j);
+  assume(i <= NVars());
+  assume(ei > 0);
+  assume(ej > 0);
+
+  if( i >= j )
+  {
+    const ring r = GetBasering();
+
+    poly product = p_One(r);
+    p_SetExp(product, j, ej, r);
+    p_SetExp(product, i, ei, r);
+    p_Setm(product, r);
+
+    return product;
+
+  } else
+  {
+    assume(i <  j);
+
+    // No Cache Lookup!? :(
+
+    CSpecialPairMultiplier* pSpecialMultiplier = GetPair(i, j);
+
+    // Special case?
+    if( pSpecialMultiplier != NULL )
+    {
+      assume( pSpecialMultiplier->GetI() == i );
+      assume( pSpecialMultiplier->GetJ() == j );
+      assume( pSpecialMultiplier->GetBasering() == GetBasering() );
+
+      return pSpecialMultiplier->MultiplyEE(ej, ei);
+    } else
+    {
+      // Perform general NC Multiplication:
+      // TODO
+
+      WerrorS("Sorry the general case is not implemented this way yet!!!");
+      assume(0);
+
+      // poly product = NULL;
+    }
+  }
+
+  return NULL;
+}
+
+
+
+
+
+
+CSpecialPairMultiplier::CSpecialPairMultiplier(ring r, int i, int j):
+    CMultiplier<int>(r), m_i(i), m_j(j)
+{
+#if OUTPUT
+  Print("CSpecialPairMultiplier::CSpecialPairMultiplier(ring, i: %d, j: %d)!", i, j);
+  PrintLn();
+#endif
+
+  assume(i < j);
+  assume(i > 0);
+  assume(j <= NVars());
+}
+
+
+CSpecialPairMultiplier::~CSpecialPairMultiplier()
+{
+#if OUTPUT
+  PrintS("CSpecialPairMultiplier::~CSpecialPairMultiplier()!");
+  PrintLn();
+#endif
+}
+
+
+
+// Monom * Exponent
+poly CSpecialPairMultiplier::MultiplyME(const poly pMonom, const CExponent expRight)
+{
+#if OUTPUT
+  Print("CSpecialPairMultiplier::MultiplyME(monom, var(%d)^{%d})!", GetI(), expRight);
+  PrintLn();
+  PrintS("Monom: "); p_Write(pMonom, GetBasering());
+#endif
+
+  return MultiplyEE(p_GetExp(pMonom, GetJ(), GetBasering()), expRight);
+}
+
+    // Exponent * Monom
+poly CSpecialPairMultiplier::MultiplyEM(const CExponent expLeft, const poly pMonom)
+{
+#if OUTPUT
+  Print("CSpecialPairMultiplier::MultiplyEM(var(%d)^{%d}, monom)!", GetJ(), expLeft);
+  PrintLn();
+  PrintS("Monom: "); p_Write(pMonom, GetBasering());
+#endif
+
+  return MultiplyEE(expLeft, p_GetExp(pMonom, GetI(), GetBasering()));
+}
+
+template class CMultiplier<CPower>;
+template class CMultiplier<int>;
+template class CMultiplier<spolyrec*>;
+
+
+#endif
diff --git a/libpolys/polys/nc/ncSAMult.h b/libpolys/polys/nc/ncSAMult.h
new file mode 100644
index 0000000..c24291d
--- /dev/null
+++ b/libpolys/polys/nc/ncSAMult.h
@@ -0,0 +1,610 @@
+#ifndef GRING_SA_MULT_H
+#define GRING_SA_MULT_H
+/*****************************************
+ *  Computer Algebra System SINGULAR     *
+ *****************************************/
+
+#ifdef HAVE_PLURAL
+
+// #include <ncSAMult.h> // for CMultiplier etc classes
+
+#include <misc/options.h>
+#include <polys/monomials/ring.h>
+#include <polys/nc/summator.h>// for CPolynomialSummator class
+#include <reporter/reporter.h> // for Print!
+#include <polys/monomials/p_polys.h>
+#include <polys/operations/p_Mult_q.h>
+
+#include <polys/coeffrings.h>
+
+//#include <polys/nc/ncSACache.h> // for CCacheHash etc classes
+#include <polys/nc/ncSAFormula.h> // for CFormulaPowerMultiplier and enum Enum_ncSAType
+
+// //////////////////////////////////////////////////////////////////////// //
+//
+
+BOOLEAN ncInitSpecialPairMultiplication(ring r);
+
+
+template <typename CExponent>
+class CMultiplier
+{
+  protected:
+    const ring m_basering;
+    const int  m_NVars; // N = number of variables
+
+  public:
+    CMultiplier(ring rBaseRing): m_basering(rBaseRing), m_NVars(rBaseRing->N) {};
+    virtual ~CMultiplier() {};
+
+    inline ring GetBasering() const { return m_basering; };
+    inline int NVars() const { return m_NVars; }
+
+
+    inline poly LM(const poly pTerm, const ring r, int i = 1) const
+    {
+      poly pMonom = p_LmInit(pTerm, r);
+      pSetCoeff0(pMonom, n_Init(i, r));
+      return pMonom;
+    }
+
+    // Term * Exponent -> Monom * Exponent
+    inline poly MultiplyTE(const poly pTerm, const CExponent expRight)
+    {
+      const ring r = GetBasering();
+      poly pMonom = LM(pTerm, r);
+
+      poly result = p_Mult_nn(MultiplyME(pMonom, expRight), p_GetCoeff(pTerm, r), r);
+
+      p_Delete(&pMonom, r);
+
+      return result;
+    }
+
+
+    // Exponent * Term -> Exponent * Monom
+    inline poly MultiplyET(const CExponent expLeft, const poly pTerm)
+    {
+      const ring r = GetBasering();
+      poly pMonom = LM(pTerm, r);
+
+      poly result = p_Mult_nn(MultiplyEM(expLeft, pMonom), p_GetCoeff(pTerm, r), r);
+
+      p_Delete(&pMonom, r);
+      return result;
+
+
+    }
+
+//  protected:
+
+    // Exponent * Exponent
+    virtual poly MultiplyEE(const CExponent expLeft, const CExponent expRight) = 0;
+
+    // Monom * Exponent
+    virtual poly MultiplyME(const poly pMonom, const CExponent expRight) = 0;
+
+    // Exponent * Monom
+    virtual poly MultiplyEM(const CExponent expLeft, const poly pMonom) = 0;
+
+  private: // no copy constuctors!
+    CMultiplier();
+    CMultiplier(const CMultiplier&);
+    CMultiplier& operator=(const CMultiplier&);
+
+};
+
+
+class CSpecialPairMultiplier: public CMultiplier<int>
+{
+  private:
+    int m_i; // 2-gen subalgebra in these variables...
+    int m_j;
+
+//    poly m_c_ij;
+//    poly m_d_ij;
+
+
+  public:
+    // 1 <= i < j <= NVars()
+    CSpecialPairMultiplier(ring r, int i, int j);
+    virtual ~CSpecialPairMultiplier();
+
+    inline int GetI() const { return m_i; } // X
+    inline int GetJ() const { return m_j; } // Y > X!
+
+//  protected:
+    typedef int CExponent;
+
+    // Exponent * Exponent
+    // Computes: var(j)^{expLeft} * var(i)^{expRight}
+    virtual poly MultiplyEE(const CExponent expLeft, const CExponent expRight) = 0;
+
+    // Monom * Exponent
+    // pMonom must be of the form: var(j)^{n}
+    virtual poly MultiplyME(const poly pMonom, const CExponent expRight);
+
+    // Exponent * Monom
+    // pMonom must be of the form: var(i)^{m}
+    virtual poly MultiplyEM(const CExponent expLeft, const poly pMonom);
+
+};
+
+
+
+
+
+struct CPower // represents var(iVar)^{iPower}
+{
+  int Var;
+  int Power;
+
+  CPower(int i, int n): Var(i), Power(n) {};
+
+/*
+  inline poly GetPoly(const ring r) const // TODO: search for GetPoly(r, 1) and remove "1"!
+  {
+    poly p = p_One(r);
+    p_SetExp(p, Var, Power, r);
+    p_Setm(p, r);
+    return p;
+  };
+  inline poly GetPoly(const ring r, int c) const
+  {
+    poly p = p_ISet(c, r);
+    p_SetExp(p, Var, Power, r);
+    p_Setm(p, r);
+    return p;
+  };
+*/
+
+};
+
+
+
+
+
+
+class CPowerMultiplier: public CMultiplier<CPower>
+{
+  private:
+    CSpecialPairMultiplier** m_specialpairs; // upper triangular submatrix of pairs 1 <= i < j <= N of a N x N matrix.
+
+
+  public:
+    CPowerMultiplier(ring r);
+    virtual ~CPowerMultiplier();
+
+    inline CSpecialPairMultiplier* GetPair(int i, int j) const
+    {
+      assume( m_specialpairs != NULL );
+      assume( i > 0 );
+      assume( i < j );
+      assume( j <= NVars() );
+
+      return m_specialpairs[( (NVars() * ((i)-1) - ((i) * ((i)-1))/2 + (j)-1) - (i) )];
+    }
+
+    inline CSpecialPairMultiplier*& GetPair(int i, int j)
+    {
+      assume( m_specialpairs != NULL );
+      assume( i > 0 );
+      assume( i < j );
+      assume( j <= NVars() );
+
+      return m_specialpairs[( (NVars() * ((i)-1) - ((i) * ((i)-1))/2 + (j)-1) - (i) )];
+    }
+
+//  protected:
+    typedef CPower CExponent;
+
+    // Exponent * Exponent
+    // Computes: var(j)^{expLeft} * var(i)^{expRight}
+    virtual poly MultiplyEE(const CExponent expLeft, const CExponent expRight);
+
+    // Monom * Exponent
+    // pMonom may NOT be of the form: var(j)^{n}!
+    virtual poly MultiplyME(const poly pMonom, const CExponent expRight);
+
+    // Exponent * Monom
+    // pMonom may NOT be of the form: var(i)^{m}!
+    virtual poly MultiplyEM(const CExponent expLeft, const poly pMonom);
+
+    // Main templates:
+
+    // Poly * Exponent
+    inline poly MultiplyPE(const poly pPoly, const CExponent expRight)
+    {
+      bool bUsePolynomial = TEST_OPT_NOT_BUCKETS || (pLength(pPoly) < MIN_LENGTH_BUCKET);
+      CPolynomialSummator sum(GetBasering(), bUsePolynomial);
+
+      for( poly q = pPoly; q !=NULL; q = pNext(q) )
+        sum += MultiplyTE(q, expRight);
+
+      return sum;
+    }
+
+    // Exponent * Poly
+    inline poly MultiplyEP(const CExponent expLeft, const poly pPoly)
+    {
+      bool bUsePolynomial = TEST_OPT_NOT_BUCKETS || (pLength(pPoly) < MIN_LENGTH_BUCKET);
+      CPolynomialSummator sum(GetBasering(), bUsePolynomial);
+
+      for( poly q = pPoly; q !=NULL; q = pNext(q) )
+        sum += MultiplyET(expLeft, q);
+
+      return sum;
+    }
+
+    // Poly * Exponent
+    inline poly MultiplyPEDestroy(poly pPoly, const CExponent expRight)
+    {
+      bool bUsePolynomial = TEST_OPT_NOT_BUCKETS || (pLength(pPoly) < MIN_LENGTH_BUCKET);
+      CPolynomialSummator sum(GetBasering(), bUsePolynomial);
+
+      for( ; pPoly!=NULL; pPoly  = p_LmDeleteAndNext(pPoly, GetBasering()) )
+        sum += MultiplyTE(pPoly, expRight);
+
+      return sum;
+    }
+
+    // Exponent * Poly
+    inline poly MultiplyEPDestroy(const CExponent expLeft, poly pPoly)
+    {
+      bool bUsePolynomial = TEST_OPT_NOT_BUCKETS || (pLength(pPoly) < MIN_LENGTH_BUCKET);
+      CPolynomialSummator sum(GetBasering(), bUsePolynomial);
+
+      for( ; pPoly!=NULL; pPoly  = p_LmDeleteAndNext(pPoly, GetBasering()) )
+        sum += MultiplyET(expLeft, pPoly);
+
+      return sum;
+    }
+
+
+};
+
+
+
+class CGlobalMultiplier: public CMultiplier<poly>
+{
+  private:
+//    CGlobalCacheHash* m_cache;
+    CPowerMultiplier* m_powers;
+    const CFormulaPowerMultiplier* m_RingFormulaMultiplier;
+
+  public:
+    typedef CMultiplier<poly> CBaseType;
+
+    CGlobalMultiplier(ring r);
+    virtual ~CGlobalMultiplier();
+
+
+//  protected:
+    typedef poly CExponent;
+
+    // the following methods are literally equal!
+
+    // Exponent * Exponent
+    // TODO: handle components!!!
+    virtual poly MultiplyEE(const CExponent expLeft, const CExponent expRight);
+
+    // Monom * Exponent
+    virtual poly MultiplyME(const poly pMonom, const CExponent expRight);
+
+    // Exponent * Monom
+    virtual poly MultiplyEM(const CExponent expLeft, const poly pMonom);
+
+
+    // Main templates:
+
+    // Poly * Exponent
+    inline poly MultiplyPE(const poly pPoly, const CExponent expRight)
+    {
+      assume( pPoly != NULL );      assume( expRight != NULL );
+      const int iComponentMonom = p_GetComp(expRight, GetBasering());
+
+      bool bUsePolynomial = TEST_OPT_NOT_BUCKETS || (pLength(pPoly) < MIN_LENGTH_BUCKET);
+      CPolynomialSummator sum(GetBasering(), bUsePolynomial);
+
+
+      if( iComponentMonom!=0 )
+      {
+        for( poly q = pPoly; q !=NULL; q = pNext(q) )
+        {
+#ifdef PDEBUG
+          {
+            const int iComponent = p_GetComp(q, GetBasering());
+            assume(iComponent == 0);
+            if( iComponent!=0 )
+            {
+              Werror("MultiplyPE: both sides have non-zero components: %d and %d!\n", iComponent, iComponentMonom);
+              // what should we do further?!?
+              return NULL;
+            }
+
+          }
+#endif
+          sum += MultiplyTE(q, expRight); // NO Component!!!
+        }
+        poly t = sum; p_SetCompP(t, iComponentMonom, GetBasering());
+        return t;
+      } // iComponentMonom != 0!
+      else
+      { // iComponentMonom == 0!
+        for( poly q = pPoly; q !=NULL; q = pNext(q) )
+        {
+          const int iComponent = p_GetComp(q, GetBasering());
+
+#ifdef PDEBUG
+          if( iComponent!=0 )
+          {
+            Warn("MultiplyPE: Multiplication in the left module from the right by component %d!\n", iComponent);
+            // what should we do further?!?
+          }
+#endif
+          poly t = MultiplyTE(q, expRight); // NO Component!!!
+          p_SetCompP(t, iComponent, GetBasering());
+          sum += t;
+        }
+        return sum;
+      } // iComponentMonom == 0!
+    }
+
+    // Exponent * Poly
+    inline poly MultiplyEP(const CExponent expLeft, const poly pPoly)
+    {
+      assume( pPoly != NULL );      assume( expLeft != NULL );
+      const int iComponentMonom = p_GetComp(expLeft, GetBasering());
+
+      bool bUsePolynomial = TEST_OPT_NOT_BUCKETS || (pLength(pPoly) < MIN_LENGTH_BUCKET);
+      CPolynomialSummator sum(GetBasering(), bUsePolynomial);
+
+      if( iComponentMonom!=0 )
+      {
+        for( poly q = pPoly; q !=NULL; q = pNext(q) )
+        {
+#ifdef PDEBUG
+          {
+            const int iComponent = p_GetComp(q, GetBasering());
+            assume(iComponent == 0);
+            if( iComponent!=0 )
+            {
+              Werror("MultiplyEP: both sides have non-zero components: %d and %d!\n", iComponent, iComponentMonom);
+                // what should we do further?!?
+              return NULL;
+            }
+          }
+#endif
+          sum += MultiplyET(expLeft, q);
+        }
+        poly t = sum; p_SetCompP(t, iComponentMonom, GetBasering());
+        return t;
+      } // iComponentMonom != 0!
+      else
+      { // iComponentMonom == 0!
+        for( poly q = pPoly; q !=NULL; q = pNext(q) )
+        {
+          const int iComponent = p_GetComp(q, GetBasering());
+
+          poly t = MultiplyET(expLeft, q); // NO Component!!!
+          p_SetCompP(t, iComponent, GetBasering());
+          sum += t;
+        }
+        return sum;
+      } // iComponentMonom == 0!
+    }
+
+    // Poly * Exponent
+    inline poly MultiplyPEDestroy(poly pPoly, const CExponent expRight)
+    {
+      assume( pPoly != NULL );      assume( expRight != NULL );
+      const int iComponentMonom = p_GetComp(expRight, GetBasering());
+
+      bool bUsePolynomial = TEST_OPT_NOT_BUCKETS || (pLength(pPoly) < MIN_LENGTH_BUCKET);
+      CPolynomialSummator sum(GetBasering(), bUsePolynomial);
+
+
+      if( iComponentMonom!=0 )
+      {
+        for(poly q = pPoly ; q!=NULL; q = p_LmDeleteAndNext(q, GetBasering()) )
+        {
+#ifdef PDEBUG
+          {
+            const int iComponent = p_GetComp(q, GetBasering());
+            assume(iComponent == 0);
+            if( iComponent!=0 )
+            {
+              Werror("MultiplyPEDestroy: both sides have non-zero components: %d and %d!\n", iComponent, iComponentMonom);
+              // what should we do further?!?
+              return NULL;
+            }
+
+          }
+#endif
+          sum += MultiplyTE(q, expRight); // NO Component!!!
+        }
+        poly t = sum; p_SetCompP(t, iComponentMonom, GetBasering());
+        return t;
+      } // iComponentMonom != 0!
+      else
+      { // iComponentMonom == 0!
+        for(poly q = pPoly ; q!=NULL; q = p_LmDeleteAndNext(q, GetBasering()) )
+        {
+          const int iComponent = p_GetComp(q, GetBasering());
+
+#ifdef PDEBUG
+          if( iComponent!=0 )
+          {
+            Warn("MultiplyPEDestroy: Multiplication in the left module from the right by component %d!\n", iComponent);
+            // what should we do further?!?
+          }
+#endif
+          poly t = MultiplyTE(q, expRight); // NO Component!!!
+          p_SetCompP(t, iComponent, GetBasering());
+          sum += t;
+        }
+        return sum;
+      } // iComponentMonom == 0!
+
+    }
+
+    // Exponent * Poly
+    inline poly MultiplyEPDestroy(const CExponent expLeft, poly pPoly)
+    {
+
+      assume( pPoly != NULL );      assume( expLeft != NULL );
+      const int iComponentMonom = p_GetComp(expLeft, GetBasering());
+
+      bool bUsePolynomial = TEST_OPT_NOT_BUCKETS || (pLength(pPoly) < MIN_LENGTH_BUCKET);
+      CPolynomialSummator sum(GetBasering(), bUsePolynomial);
+
+      if( iComponentMonom!=0 )
+      {
+        for(poly q = pPoly ; q!=NULL; q = p_LmDeleteAndNext(q, GetBasering()) )
+        {
+#ifdef PDEBUG
+          {
+            const int iComponent = p_GetComp(q, GetBasering());
+            assume(iComponent == 0);
+            if( iComponent!=0 )
+            {
+              Werror("MultiplyEPDestroy: both sides have non-zero components: %d and %d!\n", iComponent, iComponentMonom);
+                // what should we do further?!?
+              return NULL;
+            }
+          }
+#endif
+          sum += MultiplyET(expLeft, q);
+        }
+        poly t = sum; p_SetCompP(t, iComponentMonom, GetBasering());
+        return t;
+      } // iComponentMonom != 0!
+      else
+      { // iComponentMonom == 0!
+        for(poly q = pPoly ; q!=NULL; q = p_LmDeleteAndNext(q, GetBasering()) )
+        {
+          const int iComponent = p_GetComp(q, GetBasering());
+
+          poly t = MultiplyET(expLeft, q); // NO Component!!!
+          p_SetCompP(t, iComponent, GetBasering());
+          sum += t;
+        }
+        return sum;
+      } // iComponentMonom == 0!
+
+    }
+
+
+
+
+};
+
+
+
+//////////////////////////////////////////////////////////////////////////
+class CCommutativeSpecialPairMultiplier: public CSpecialPairMultiplier
+{
+	public:
+		CCommutativeSpecialPairMultiplier(ring r, int i, int j);
+		virtual ~CCommutativeSpecialPairMultiplier();
+
+		// Exponent * Exponent
+		virtual poly MultiplyEE(const int expLeft, const int expRight);
+};
+
+//////////////////////////////////////////////////////////////////////////
+class CAntiCommutativeSpecialPairMultiplier: public CSpecialPairMultiplier
+{
+	public:
+		CAntiCommutativeSpecialPairMultiplier(ring r, int i, int j);
+		virtual ~CAntiCommutativeSpecialPairMultiplier();
+
+		// Exponent * Exponent
+		virtual poly MultiplyEE(const int expLeft, const int expRight);
+};
+
+
+//////////////////////////////////////////////////////////////////////////
+class CQuasiCommutativeSpecialPairMultiplier: public CSpecialPairMultiplier
+{
+	private:
+		const number m_q;
+		// TODO: make cache for some 'good' powers!?
+
+  public:
+		CQuasiCommutativeSpecialPairMultiplier(ring r, int i, int j, number q);
+		virtual ~CQuasiCommutativeSpecialPairMultiplier();
+
+		// Exponent * Exponent
+		virtual poly MultiplyEE(const int expLeft, const int expRight);
+};
+
+
+//////////////////////////////////////////////////////////////////////////
+class CWeylSpecialPairMultiplier: public CSpecialPairMultiplier
+{
+  private:
+    const number m_g;
+    // TODO: make cache for some 'good' powers!?
+
+  public:
+    CWeylSpecialPairMultiplier(ring r, int i, int j, number g);
+    virtual ~CWeylSpecialPairMultiplier();
+
+    // Exponent * Exponent
+    virtual poly MultiplyEE(const int expLeft, const int expRight);
+};
+
+//////////////////////////////////////////////////////////////////////////
+class CHWeylSpecialPairMultiplier: public CSpecialPairMultiplier
+{
+  private:
+    const int m_k;
+    // TODO: make cache for some 'good' powers!?
+
+  public:
+    CHWeylSpecialPairMultiplier(ring r, int i, int j, int k);
+    virtual ~CHWeylSpecialPairMultiplier();
+
+    // Exponent * Exponent
+    virtual poly MultiplyEE(const int expLeft, const int expRight);
+};
+
+
+//////////////////////////////////////////////////////////////////////////
+class CShiftSpecialPairMultiplier: public CSpecialPairMultiplier
+{
+  private:
+    const number m_shiftCoef;
+    const int m_shiftVar;
+    // TODO: make cache for some 'good' powers!?
+
+  public:
+    CShiftSpecialPairMultiplier(ring r, int i, int j, int s, number c);
+    virtual ~CShiftSpecialPairMultiplier();
+
+    // Exponent * Exponent
+    virtual poly MultiplyEE(const int expLeft, const int expRight);
+};
+
+
+
+// need: enum Enum_ncSAType;
+
+//////////////////////////////////////////////////////////////////////////
+// Using external 'formula' routins
+class CExternalSpecialPairMultiplier: public CSpecialPairMultiplier
+{
+  private:
+    Enum_ncSAType m_ncSAtype;
+  public:
+    CExternalSpecialPairMultiplier(ring r, int i, int j, Enum_ncSAType type);
+    virtual ~CExternalSpecialPairMultiplier();
+
+    // Exponent * Exponent
+    virtual poly MultiplyEE(const int expLeft, const int expRight);
+};
+
+
+#endif // HAVE_PLURAL :(
+#endif //
diff --git a/libpolys/polys/nc/old.gring.cc b/libpolys/polys/nc/old.gring.cc
new file mode 100644
index 0000000..5993e63
--- /dev/null
+++ b/libpolys/polys/nc/old.gring.cc
@@ -0,0 +1,3531 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    gring.cc
+ *  Purpose: noncommutative kernel procedures
+ *  Author:  levandov (Viktor Levandovsky)
+ *  Created: 8/00 - 11/00
+ *******************************************************************/
+
+#define MYTEST 0
+#define OUTPUT 0
+
+#if MYTEST
+#define OM_CHECK 4
+#define OM_TRACK 5
+#endif
+
+
+
+
+#include <misc/auxiliary.h>
+
+#ifdef HAVE_PLURAL
+
+# define PLURAL_INTERNAL_DECLARATIONS
+#include "nc.h"
+#include "sca.h"
+#include "gb_hack.h"
+
+#include <polys/monomials/ring.h>
+
+#include <coeffs/numbers.h>
+#include <polys/coeffrings.h>
+
+// #include <polys/febase.h>
+#include <misc/options.h>
+
+#include <polys/monomials/ring.h>
+#include <polys/monomials/p_polys.h>
+
+#include <polys/simpleideals.h>
+#include <polys/matpol.h>
+
+#include <polys/kbuckets.h>
+#include <polys/sbuckets.h>
+
+// #include <polys/kstd1.h>
+#include <polys/prCopy.h>
+
+#include <polys/operations/p_Mult_q.h>
+
+// #include <polys/pInline1.h>
+
+
+#include "summator.h"
+
+#include "ncSAMult.h" // for CMultiplier etc classes
+#include "ncSAFormula.h" // for CFormulaPowerMultiplier and enum Enum_ncSAType
+
+// #ifdef HAVE_RATGRING
+// #include <polys/ratgring.h>
+// #endif
+
+
+/* copy : */
+poly nc_p_CopyGet(poly a, const ring r);
+poly nc_p_CopyPut(poly a, const ring r);
+
+poly nc_p_Bracket_qq(poly p, const poly q, const ring r);
+
+// only SCA can be used by default, formulas are off by default
+int  iNCExtensions = SCAMASK | NOFORMULAMASK;
+
+int& getNCExtensions()
+{
+  return (iNCExtensions);
+}
+
+int setNCExtensions(int iMask)
+{
+  const int iOld = getNCExtensions();
+  getNCExtensions() = iMask;
+  return (iOld);
+}
+
+bool ncExtensions(int iMask) //  = 0x0FFFF
+{
+  return ((getNCExtensions() & iMask) == iMask);
+}
+
+/* global nc_macros : */
+
+#define freeT(A,v) omFreeSize((ADDRESS)A,(v+1)*sizeof(int))
+#define freeN(A,k) omFreeSize((ADDRESS)A,k*sizeof(number))
+
+
+// some forward declarations:
+
+
+// polynomial multiplication functions for p_Procs :
+poly gnc_pp_Mult_mm(const poly p, const poly m, const ring r, poly &last);
+poly gnc_p_Mult_mm(poly p, const poly m, const ring r);
+poly gnc_mm_Mult_p(const poly m, poly p, const ring r);
+poly gnc_mm_Mult_pp(const poly m, const poly p, const ring r);
+
+
+/* syzygies : */
+poly gnc_CreateSpolyOld(const poly p1, const poly p2/*, poly spNoether*/, const ring r);
+poly gnc_ReduceSpolyOld(const poly p1, poly p2/*, poly spNoether*/, const ring r);
+
+poly gnc_CreateSpolyNew(const poly p1, const poly p2/*, poly spNoether*/, const ring r);
+poly gnc_ReduceSpolyNew(const poly p1, poly p2/*, poly spNoether*/, const ring r);
+
+
+
+void gnc_kBucketPolyRedNew(kBucket_pt b, poly p, number *c);
+void gnc_kBucketPolyRed_ZNew(kBucket_pt b, poly p, number *c);
+
+void gnc_kBucketPolyRedOld(kBucket_pt b, poly p, number *c);
+void gnc_kBucketPolyRed_ZOld(kBucket_pt b, poly p, number *c);
+
+
+// poly gnc_ReduceSpolyNew(poly p1, poly p2, poly spNoether, const ring r);
+// void gnc_ReduceSpolyTail(poly p1, poly q, poly q2, poly spNoether, const ring r);
+
+// void nc_kBucketPolyRed(kBucket_pt b, poly p);
+
+void nc_CleanUp(nc_struct* p); // just free memory!
+void nc_rCleanUp(ring r); // smaller than kill: just free mem
+
+
+#if 0
+// deprecated functions:
+//  poly gnc_p_Minus_mm_Mult_qq_ign(poly p, const poly m, poly q, int & d1, poly d2, const ring ri, poly &d3);
+//  poly gnc_p_Minus_mm_Mult_qq(poly p, const poly m, poly q, const ring r);
+//  poly nc_p_Minus_mm_Mult_qq(poly p, const poly m, const poly q, int &lp, int lq, const ring r);
+//  poly nc_p_Plus_mm_Mult_qq (poly p, const poly m, const poly q, int &lp, int lq, const ring r);
+#endif
+
+
+
+/*2
+* returns the LCM of the head terms of a and b
+* without coefficient!!!
+*/
+poly p_Lcm(const poly a, const poly b, const long lCompM, const ring r)
+{
+  poly m = // p_One( r);
+          p_Init(r);
+
+  const int pVariables = r->N;
+
+  for (int i = pVariables; i!=0; i--)
+  {
+    const int lExpA = p_GetExp (a, i, r);
+    const int lExpB = p_GetExp (b, i, r);
+
+    p_SetExp (m, i, si_max(lExpA, lExpB), r);
+  }
+
+  p_SetComp (m, lCompM, r);
+
+  p_Setm(m,r);
+
+#ifdef PDEBUG
+//  p_Test(m,r);
+#endif
+
+  n_New(&(p_GetCoeff(m, r)), r);
+
+  return(m);
+}
+
+poly p_Lcm(const poly a, const poly b, const ring r)
+{
+#ifdef PDEBUG
+  p_Test(a, r);
+  p_Test(b, r);
+#endif
+
+  const long lCompP1 = p_GetComp(a, r);
+  const long lCompP2 = p_GetComp(b, r);
+
+  const poly m = p_Lcm(a, b, si_max(lCompP1, lCompP2), r);
+
+#ifdef PDEBUG
+//  p_Test(m,r);
+#endif
+  return(m);
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+poly nc_p_Minus_mm_Mult_qq(poly p, const poly m, const poly q, int &shorter,
+                                    const poly, const ring r)
+{
+  poly mc  = p_Neg( p_Copy(m, r), r );
+  poly mmc = nc_mm_Mult_pp( mc, q, r );
+  p_Delete(&mc, r);
+
+  int org_p=pLength(p);
+  int org_q=pLength(q);
+
+  p = p_Add_q(p, mmc, r);
+
+  shorter = pLength(p)-org_p-org_q; // ring independent!
+
+  return(p);
+}
+
+// returns p + m*q destroys p, const: q, m
+poly nc_p_Plus_mm_Mult_qq(poly p, const poly m, const poly q, int &lp,
+                              const int, const ring r)
+{
+  p = p_Add_q(p, nc_mm_Mult_pp( m, q, r ), r);
+
+  lp = pLength(p);
+
+  return(p);
+}
+
+#if 0
+poly gnc_p_Minus_mm_Mult_qq_ign(poly p, const poly m, poly q, int & d1, poly d2, const ring r, poly &d3)
+{
+  poly t;
+  int  i;
+
+  return gnc_p_Minus_mm_Mult_qq(p, m, q, d1, i, t, r);
+}
+#endif
+
+
+//----------- auxiliary routines--------------------------
+poly _gnc_p_Mult_q(poly p, poly q, const int copy, const ring r) // not used anymore!
+  /* destroy p,q unless copy=1 */
+{
+  poly res=NULL;
+  poly qq,pp;
+  if (copy)
+  {
+    qq=p_Copy(q,r);
+    pp=p_Copy(p,r);
+  }
+  else
+  {
+    qq=q;
+    pp=p;
+  }
+  while (qq!=NULL)
+  {
+    res=p_Add_q(res, pp_Mult_mm(pp, qq, r), r); // p_Head(qq, r)?
+    qq=p_LmDeleteAndNext(qq,r);
+  }
+  p_Delete(&pp,r);
+  return(res);
+}
+
+// return pPolyP * pPolyQ; destroy or reuse pPolyP and pPolyQ
+poly _nc_p_Mult_q(poly pPolyP, poly pPolyQ, const ring rRing)
+{
+  assume( rIsPluralRing(rRing) );
+#ifdef PDEBUG
+  p_Test(pPolyP, rRing);
+  p_Test(pPolyQ, rRing);
+#endif
+#ifdef RDEBUG
+  rTest(rRing);
+#endif
+
+  int lp, lq;
+
+  pqLength(pPolyP, pPolyQ, lp, lq, MIN_LENGTH_BUCKET);
+
+  bool bUsePolynomial = TEST_OPT_NOT_BUCKETS || (si_max(lp, lq) < MIN_LENGTH_BUCKET); // ???
+
+  CPolynomialSummator sum(rRing, bUsePolynomial);
+
+  if (lq <= lp) // ?
+  {
+    // always length(q) times "p * q[j]"
+    for( ; pPolyQ!=NULL; pPolyQ  = p_LmDeleteAndNext( pPolyQ, rRing ) )
+      sum += pp_Mult_mm( pPolyP, pPolyQ, rRing);
+
+    p_Delete( &pPolyP, rRing );
+  } else
+  {
+    // always length(p) times "p[i] * q"
+    for( ; pPolyP!=NULL; pPolyP  = p_LmDeleteAndNext( pPolyP, rRing ) )
+      sum += nc_mm_Mult_pp( pPolyP, pPolyQ, rRing);
+
+    p_Delete( &pPolyQ, rRing );
+  }
+
+  return(sum);
+}
+
+// return pPolyP * pPolyQ; preserve pPolyP and pPolyQ
+poly _nc_pp_Mult_qq(const poly pPolyP, const poly pPolyQ, const ring rRing)
+{
+  assume( rIsPluralRing(rRing) );
+#ifdef PDEBUG
+  p_Test(pPolyP, rRing);
+  p_Test(pPolyQ, rRing);
+#endif
+#ifdef RDEBUG
+  rTest(rRing);
+#endif
+
+  int lp, lq;
+
+  pqLength(pPolyP, pPolyQ, lp, lq, MIN_LENGTH_BUCKET);
+
+  bool bUsePolynomial = TEST_OPT_NOT_BUCKETS || (si_max(lp, lq) < MIN_LENGTH_BUCKET); // ???
+
+  CPolynomialSummator sum(rRing, bUsePolynomial);
+
+  if (lq <= lp) // ?
+  {
+    // always length(q) times "p * q[j]"
+    for( poly q = pPolyQ; q !=NULL; q = pNext(q) )
+      sum += pp_Mult_mm(pPolyP, q, rRing);
+  } else
+  {
+    // always length(p) times "p[i] * q"
+    for( poly p = pPolyP; p !=NULL; p = pNext(p) )
+      sum += nc_mm_Mult_pp( p, pPolyQ, rRing);
+  }
+
+  return(sum);
+}
+
+
+
+poly gnc_mm_Mult_nn (int *F, int *G, const ring r);
+poly gnc_mm_Mult_uu (int *F,int jG,int bG, const ring r);
+
+/* #define nc_uu_Mult_ww nc_uu_Mult_ww_vert */
+poly gnc_uu_Mult_ww (int i, int a, int j, int b, const ring r);
+/* poly nc_uu_Mult_ww_vert (int i, int a, int j, int b, const ring r); */
+/* poly nc_uu_Mult_ww_horvert (int i, int a, int j, int b, const ring r); */
+/* poly nc_uu_Mult_ww_hvdiag (int i, int a, int j, int b, const ring r); */
+/* not written yet */
+
+
+poly gnc_p_Mult_mm_Common(poly p, const poly m, int side, const ring r)
+/* p is poly, m is mono with coeff, destroys p */
+/* if side==1, computes p_Mult_mm; otherwise, mm_Mult_p */
+{
+  if ((p==NULL) || (m==NULL)) return NULL;
+  /*  if (pNext(p)==NULL) return(nc_mm_Mult_nn(p,pCopy(m),r)); */
+  /* excluded  - the cycle will do it anyway - OK. */
+  if (p_IsConstant(m,r)) return(p_Mult_nn(p,p_GetCoeff(m,r),r));
+
+#ifdef PDEBUG
+  p_Test(p,r);
+  p_Test(m,r);
+#endif
+  poly v=NULL;
+  int rN=r->N;
+  int *P=(int *)omAlloc0((rN+1)*sizeof(int));
+  int *M=(int *)omAlloc0((rN+1)*sizeof(int));
+  /* coefficients: */
+  number cP,cM,cOut;
+  p_GetExpV(m, M, r);
+  cM=p_GetCoeff(m,r);
+  /* components:*/
+  const int expM=p_GetComp(m,r);
+  int expP=0;
+  int expOut=0;
+  /* bucket constraints: */
+  int UseBuckets=1;
+  if (pLength(p)< MIN_LENGTH_BUCKET || TEST_OPT_NOT_BUCKETS) UseBuckets=0;
+
+  CPolynomialSummator sum(r, UseBuckets == 0);
+
+  while (p!=NULL)
+  {
+#ifdef PDEBUG
+    p_Test(p,r);
+#endif
+    expP=p_GetComp(p,r);
+    if (expP==0)
+    {
+      expOut=expM;
+    }
+    else
+    {
+      if (expM==0)
+      {
+        expOut=expP;
+#ifdef PDEBUG
+        if (side)
+        {
+          Print("gnc_p_Mult_mm: Multiplication in the left module from the right");
+        }
+#endif
+      }
+      else
+      {
+        /* REPORT_ERROR */
+#ifdef PDEBUG
+        const char* s;
+        if (side==1) s="gnc_p_Mult_mm";
+        else s="gnc_mm_Mult_p";
+        Print("%s: exponent mismatch %d and %d\n",s,expP,expM);
+#endif
+        expOut=0;
+      }
+    }
+    p_GetExpV(p,P,r);
+    cP=p_GetCoeff(p,r);
+    cOut=n_Mult(cP,cM,r);
+    if (side==1)
+    {
+      v = gnc_mm_Mult_nn(P, M, r);
+    }
+    else
+    {
+      v = gnc_mm_Mult_nn(M, P, r);
+    }
+    v = p_Mult_nn(v,cOut,r);
+    n_Delete(&cOut,r);
+    p_SetCompP(v,expOut,r);
+
+    sum += v;
+
+    p_LmDelete(&p,r);
+  }
+  freeT(P,rN);
+  freeT(M,rN);
+
+  return(sum);
+}
+
+/* poly functions defined in p_Procs : */
+poly gnc_pp_Mult_mm(const poly p, const poly m, const ring r)
+{
+  return( gnc_p_Mult_mm_Common(p_Copy(p,r), m, 1, r) );
+}
+
+poly gnc_p_Mult_mm(poly p, const poly m, const ring r)
+{
+  return( gnc_p_Mult_mm_Common(p, m, 1, r) );
+}
+
+poly gnc_mm_Mult_p(const poly m, poly p, const ring r)
+{
+  return( gnc_p_Mult_mm_Common(p, m, 0, r) );
+}
+
+poly gnc_mm_Mult_pp(const poly m, const poly p, const ring r)
+{
+  return( gnc_p_Mult_mm_Common(p_Copy(p,r), m, 0, r) );
+}
+
+
+
+poly gnc_mm_Mult_nn(int *F0, int *G0, const ring r)
+/* destroys nothing, no coeffs and exps */
+{
+  poly out=NULL;
+  int i,j;
+  int iF,jG,iG;
+  int rN=r->N;
+
+  int *F=(int *)omAlloc0((rN+1)*sizeof(int));
+  int *G=(int *)omAlloc0((rN+1)*sizeof(int));
+
+  memcpy(F, F0,(rN+1)*sizeof(int));
+  // pExpVectorCopy(F,F0);
+  memcpy(G, G0,(rN+1)*sizeof(int));
+  //  pExpVectorCopy(G,G0);
+  F[0]=0;
+  G[0]=0;
+
+  iF=rN;
+  while ((F[iF]==0)&&(iF>=1)) iF--; /* last exp_num of F */
+  if (iF==0) /* F0 is zero vector */
+  {
+    out=p_One(r);
+    p_SetExpV(out,G0,r);
+    p_Setm(out,r);
+    freeT(F,rN);
+    freeT(G,rN);
+    return(out);
+  }
+  jG=1;
+  while ((G[jG]==0)&&(jG<rN)) jG++;  /* first exp_num of G */
+  iG=rN;
+  while ((G[iG]==0)&&(iG>1)) iG--;  /* last exp_num of G */
+
+  out=p_One(r);
+
+  if (iF<=jG)
+    /* i.e. no mixed exp_num , MERGE case */
+  {
+    { for(int ii=rN;ii>0;ii--) F[ii]+=G[ii]; }
+    p_SetExpV(out,F,r);
+    p_Setm(out,r);
+    freeT(F,rN);
+    freeT(G,rN);
+    return(out);
+  }
+
+  number cff=n_Init(1,r);
+  number tmp_num=NULL;
+  int cpower=0;
+
+  if (ncRingType(r)==nc_skew)
+  {
+    if (r->GetNC()->IsSkewConstant==1)
+    {
+      int tpower=0;
+      for(j=jG; j<=iG; j++)
+      {
+        if (G[j]!=0)
+        {
+          cpower = 0;
+          for(i=j+1; i<=iF; i++)
+          {
+            cpower = cpower + F[i];
+          }
+          cpower = cpower*G[j]; // bug! here may happen an arithmetic overflow!!!
+          tpower = tpower + cpower;
+        }
+      }
+      cff = n_Copy(p_GetCoeff(MATELEM(r->GetNC()->COM,1,2),r),r);
+      n_Power(cff,tpower,&tmp_num, r);
+      n_Delete(&cff,r);
+      cff = tmp_num;
+    }
+    else /* skew commutative with nonequal coeffs */
+    {
+      number totcff=n_Init(1,r);
+      for(j=jG; j<=iG; j++)
+      {
+        if (G[j]!=0)
+        {
+          cpower = 0;
+          for(i=j+1; i<=iF; i++)
+          {
+            if (F[i]!=0)
+            {
+              cpower = F[i]*G[j]; // bug! overflow danger!!!
+              cff = n_Copy(p_GetCoeff(MATELEM(r->GetNC()->COM,j,i),r),r);
+              n_Power(cff,cpower,&tmp_num, r);
+              cff = n_Mult(totcff,tmp_num, r);
+              n_Delete(&totcff, r);
+              n_Delete(&tmp_num, r);
+              totcff = n_Copy(cff,r);
+              n_Delete(&cff,r);
+            }
+          } /* end 2nd for */
+        }
+      }
+      cff=totcff;
+    }
+    { for(int ii=rN;ii>0;ii--) F[ii]+=G[ii]; }
+    p_SetExpV(out,F,r);
+    p_Setm(out,r);
+    p_SetCoeff(out,cff,r);
+    freeT(F,rN);
+    freeT(G,rN);
+    return(out);
+  } /* end nc_skew */
+
+  /* now we have to destroy out! */
+  p_Delete(&out,r);
+
+  if (iG==jG)
+    /* g is univariate monomial */
+  {
+    /*    if (ri->GetNC()->type==nc_skew) -- postpone to TU */
+    out = gnc_mm_Mult_uu(F,jG,G[jG],r);
+    freeT(F,rN);
+    freeT(G,rN);
+    return(out);
+  }
+
+  int *Prv=(int *)omAlloc0((rN+1)*sizeof(int));
+  int *Nxt=(int *)omAlloc0((rN+1)*sizeof(int));
+
+  int *log=(int *)omAlloc0((rN+1)*sizeof(int));
+  int cnt=0; int cnf=0;
+
+  /* splitting F wrt jG */
+  for (i=1;i<=jG;i++)
+  {
+    Prv[i]=F[i]; Nxt[i]=0; /* mult at the very end */
+    if (F[i]!=0) cnf++;
+  }
+
+  if (cnf==0) freeT(Prv,rN);
+
+  for (i=jG+1;i<=rN;i++)
+  {
+    Nxt[i]=F[i];
+    /*    if (cnf!=0)  Prv[i]=0; */
+    if (F[i]!=0)
+    {
+      cnt++;
+    }              /* effective part for F */
+  }
+  freeT(F,rN);
+  cnt=0;
+
+  for (i=1;i<=rN;i++)
+  {
+    if (G[i]!=0)
+    {
+     cnt++;
+     log[cnt]=i;
+     }               /* lG for G */
+   }
+
+/* ---------------------- A C T I O N ------------------------ */
+  poly D=NULL;
+  poly Rout=NULL;
+  number *c=(number *)omAlloc0((rN+1)*sizeof(number));
+  c[0]=n_Init(1,r);
+
+  int *Op=Nxt;
+  int *On=G;
+  int *U=(int *)omAlloc0((rN+1)*sizeof(int));
+
+  for (i=jG;i<=rN;i++) U[i]=Nxt[i]+G[i];  /* make leadterm */
+  Nxt=NULL;
+  G=NULL;
+  cnt=1;
+  int t=0;
+  poly w=NULL;
+  poly Pn=p_One(r);
+  p_SetExpV(Pn,On,r);
+  p_Setm(Pn,r);
+
+  while (On[iG]!=0)
+  {
+     t=log[cnt];
+
+     w=gnc_mm_Mult_uu(Op,t,On[t],r);
+     c[cnt]=n_Mult(c[cnt-1],p_GetCoeff(w,r),r);
+     D = pNext(w);  /* getting coef and rest D */
+     p_LmDelete(&w,r);
+     w=NULL;
+
+     Op[t] += On[t];   /* update exp_vectors */
+     On[t] = 0;
+
+     if (t!=iG)    /* not the last step */
+     {
+       p_SetExpV(Pn,On,r);
+       p_Setm(Pn,r);
+#ifdef PDEBUG
+       p_Test(Pn,r);
+#endif
+
+//       if (pNext(D)==0)
+// is D a monomial? could be postponed higher
+//       {
+//       Rout=nc_mm_Mult_nn(D,Pn,r);
+//       }
+//       else
+//       {
+       Rout=gnc_p_Mult_mm(D,Pn,r);
+//       }
+     }
+     else
+     {
+       Rout=D;
+       D=NULL;
+     }
+
+     if (Rout!=NULL)
+     {
+       Rout=p_Mult_nn(Rout,c[cnt-1],r); /* Rest is ready */
+       out=p_Add_q(out,Rout,r);
+       Rout=NULL;
+     }
+     cnt++;
+  }
+  freeT(On,rN);
+  freeT(Op,rN);
+  p_Delete(&Pn,r);
+  omFreeSize((ADDRESS)log,(rN+1)*sizeof(int));
+
+  /* leadterm and Prv-part */
+
+  Rout=p_One(r);
+  /* U is lead.monomial */
+  U[0]=0;
+  p_SetExpV(Rout,U,r);
+  p_Setm(Rout,r);  /* use again this name Rout */
+#ifdef PDEBUG
+  p_Test(Rout,r);
+#endif
+  p_SetCoeff(Rout,c[cnt-1],r);
+  out=p_Add_q(out,Rout,r);
+  freeT(U,rN);
+  freeN(c,rN+1);
+  if (cnf!=0)  /* Prv is non-zero vector */
+  {
+    Rout=p_One(r);
+    Prv[0]=0;
+    p_SetExpV(Rout,Prv,r);
+    p_Setm(Rout,r);
+#ifdef PDEBUG
+    p_Test(Rout,r);
+#endif
+    out=gnc_mm_Mult_p(Rout,out,r); /* getting the final result */
+    freeT(Prv,rN);
+    p_Delete(&Rout,r);
+  }
+  return (out);
+}
+
+
+poly gnc_mm_Mult_uu(int *F,int jG,int bG, const ring r)
+/* f=mono(F),g=(x_iG)^bG */
+{
+  poly out=NULL;
+  int i;
+  number num=NULL;
+
+  int rN=r->N;
+  int iF=r->N;
+  while ((F[iF]==0)&&(iF>0)) iF-- ;   /* last exponent_num of F */
+
+  if (iF==0)  /* F==zero vector in other words */
+  {
+   out=p_One(r);
+   p_SetExp(out,jG,bG,r);
+   p_Setm(out,r);
+   return(out);
+  }
+
+  int jF=1;
+  while ((F[jF]==0)&&(jF<=rN)) jF++;  /* first exp of F */
+
+  if (iF<=jG)                       /* i.e. no mixed exp_num */
+  {
+    out=p_One(r);
+    F[jG]=F[jG]+bG;
+    p_SetExpV(out,F,r);
+    p_Setm(out,r);
+    return(out);
+  }
+
+  if (iF==jF)              /* uni times uni */
+  {
+   out=gnc_uu_Mult_ww(iF,F[iF],jG,bG,r);
+   return(out);
+  }
+
+  /* Now: F is mono with >=2 exponents, jG<iF */
+  /* check the quasi-commutative case */
+//   matrix LCOM=r->GetNC()->COM;
+//   number rescoef=n_Init(1,r);
+//   number tmpcoef=n_Init(1,r);
+//   int tmpint;
+//   i=iF;
+//   while (i>=jG+1)
+//     /* all the non-zero exponents */
+//   {
+//     if (MATELEM(LCOM,jG,i)!=NULL)
+//     {
+//       tmpcoef=pGetCoeff(MATELEM(LCOM,jG,i));
+//       tmpint=(int)F[i];
+//       nPower(tmpcoef,F[i],&tmpcoef);
+//       rescoef=nMult(rescoef,tmpcoef);
+//       i--;
+//     }
+//     else
+//     {
+//       if (F[i]!=0) break;
+//     }
+//   }
+//   if (iF==i)
+//   /* no action took place*/
+//   {
+
+//   }
+//   else /* power the result up to bG */
+//   {
+//     nPower(rescoef,bG,&rescoef);
+//     /* + cleanup, post-processing */
+//   }
+
+  int *Prv=(int*)omAlloc0((rN+1)*sizeof(int));
+  int *Nxt=(int*)omAlloc0((rN+1)*sizeof(int));
+  int *lF=(int *)omAlloc0((rN+1)*sizeof(int));
+
+  int cnt=0; int cnf=0;
+  /* splitting F wrt jG */
+  for (i=1;i<=jG;i++) /* mult at the very end */
+  {
+    Prv[i]=F[i]; Nxt[i]=0;
+    if (F[i]!=0) cnf++;
+  }
+
+  if (cnf==0)
+  {
+    freeT(Prv,rN); Prv = NULL;
+  }
+
+  for (i=jG+1;i<=rN;i++)
+  {
+    Nxt[i]=F[i];
+    if (cnf!=0) { Prv[i]=0;}
+    if (F[i]!=0)
+    {
+      cnt++;
+      lF[cnt]=i;
+    }                 /* eff_part,lF_for_F */
+  }
+
+  if (cnt==1) /* Nxt consists of 1 nonzero el-t only */
+  {
+    int q=lF[1];
+    poly Rout=p_One(r);
+    out=gnc_uu_Mult_ww(q,Nxt[q],jG,bG,r);
+
+    freeT(Nxt,rN);  Nxt = NULL;
+
+    if (cnf!=0)
+    {
+       Prv[0]=0;
+       p_SetExpV(Rout,Prv,r);
+       p_Setm(Rout,r);
+
+#ifdef PDEBUG
+       p_Test(Rout,r);
+#endif
+
+       freeT(Prv,rN);
+       Prv = NULL;
+
+       out=gnc_mm_Mult_p(Rout,out,r); /* getting the final result */
+    }
+
+    freeT(lF,rN);
+    lF = NULL;
+
+    p_Delete(&Rout,r);
+
+    assume(Nxt == NULL);
+    assume(lF == NULL);
+    assume(Prv == NULL);
+
+    return (out);
+  }
+/* -------------------- MAIN ACTION --------------------- */
+
+  poly D=NULL;
+  poly Rout=NULL;
+  number *c=(number *)omAlloc0((cnt+2)*sizeof(number));
+  c[cnt+1]=n_Init(1,r);
+  i=cnt+2;         /* later in freeN */
+  int *Op=Nxt;
+
+  int *On=(int *)omAlloc0((rN+1)*sizeof(int));
+  int *U=(int *)omAlloc0((rN+1)*sizeof(int));
+
+
+  //  pExpVectorCopy(U,Nxt);
+  memcpy(U, Nxt,(rN+1)*sizeof(int));
+  U[jG] = U[jG] + bG;
+
+  /* Op=Nxt and initial On=(0); */
+  Nxt=NULL;
+
+  poly Pp;
+  poly Pn;
+  int t=0;
+  int first=lF[1];
+  int nlast=lF[cnt];
+  int kk=0;
+  /*  cnt--;   */
+  /* now lF[cnt] should be <=iF-1 */
+
+  while (Op[first]!=0)
+  {
+     t=lF[cnt];   /* cnt as it was computed */
+
+     poly w=gnc_uu_Mult_ww(t,Op[t],jG,bG,r);
+     c[cnt]=n_Copy(p_GetCoeff(w,r),r);
+     D = pNext(w);  /* getting coef and rest D */
+     p_LmDelete(&w,r);
+     w=NULL;
+
+     Op[t]= 0;
+     Pp=p_One(r);
+     p_SetExpV(Pp,Op,r);
+     p_Setm(Pp,r);
+
+     if (t<nlast)
+     {
+       kk=lF[cnt+1];
+       On[kk]=F[kk];
+
+       Pn=p_One(r);
+       p_SetExpV(Pn,On,r);
+       p_Setm(Pn,r);
+
+       if (t!=first)   /* typical expr */
+       {
+         w=gnc_p_Mult_mm(D,Pn,r);
+         Rout=gnc_mm_Mult_p(Pp,w,r);
+         w=NULL;
+       }
+       else                   /* last step */
+       {
+         On[t]=0;
+         p_SetExpV(Pn,On,r);
+         p_Setm(Pn,r);
+         Rout=gnc_p_Mult_mm(D,Pn,r);
+       }
+#ifdef PDEBUG
+       p_Test(Pp,r);
+#endif
+       p_Delete(&Pn,r);
+     }
+     else                     /* first step */
+     {
+       Rout=gnc_mm_Mult_p(Pp,D,r);
+     }
+#ifdef PDEBUG
+     p_Test(Pp,r);
+#endif
+     p_Delete(&Pp,r);
+     num=n_Mult(c[cnt+1],c[cnt],r);
+     n_Delete(&c[cnt],r);
+     c[cnt]=num;
+     Rout=p_Mult_nn(Rout,c[cnt+1],r); /* Rest is ready */
+     out=p_Add_q(out,Rout,r);
+     Pp=NULL;
+     cnt--;
+  }
+  /* only to feel safe:*/
+  Pn=Pp=NULL;
+  freeT(On,rN);
+  freeT(Op,rN);
+
+/* leadterm and Prv-part with coef 1 */
+/*  U[0]=exp; */
+/*  U[jG]=U[jG]+bG;  */
+/* make leadterm */
+/* ??????????? we have done it already :-0 */
+
+  Rout=p_One(r);
+  p_SetExpV(Rout,U,r);
+  p_Setm(Rout,r);  /* use again this name */
+  p_SetCoeff(Rout,c[cnt+1],r);  /* last computed coef */
+
+  out=p_Add_q(out,Rout,r);
+
+  Rout=NULL;
+
+  freeT(U, rN);
+  freeN(c, i);
+  freeT(lF, rN);
+
+  if (cnf!=0)
+  {
+    Rout=p_One(r);
+    p_SetExpV(Rout,Prv,r);
+    p_Setm(Rout,r);
+    freeT(Prv, rN);
+    out=gnc_mm_Mult_p(Rout,out,r); /* getting the final result */
+    p_Delete(&Rout,r);
+  }
+
+  return (out);
+}
+
+poly gnc_uu_Mult_ww_vert (int i, int a, int j, int b, const ring r)
+{
+  int k,m;
+  int rN=r->N;
+  const int cMTindex = UPMATELEM(j,i,rN);
+  matrix cMT=r->GetNC()->MT[cMTindex];         /* cMT=current MT */
+
+  poly x=p_One(r);p_SetExp(x,j,1,r);p_Setm(x,r);
+/* var(j); */
+  poly y=p_One(r);p_SetExp(y,i,1,r);p_Setm(y,r);
+/*var(i);  for convenience */
+#ifdef PDEBUG
+  p_Test(x,r);
+  p_Test(y,r);
+#endif
+  poly t=NULL;
+/* ------------ Main Cycles ----------------------------*/
+
+  for (k=2;k<=a;k++)
+  {
+     t = MATELEM(cMT,k,1);
+
+     if (t==NULL)   /* not computed yet */
+     {
+       t = nc_p_CopyGet(MATELEM(cMT,k-1,1),r);
+       //        t=p_Copy(MATELEM(cMT,k-1,1),r);
+       t = gnc_mm_Mult_p(y,t,r);
+       cMT=r->GetNC()->MT[cMTindex]; // since multiplication can change the MT table...
+       assume( t != NULL );
+#ifdef PDEBUG
+       p_Test(t,r);
+#endif
+       MATELEM(cMT,k,1) = nc_p_CopyPut(t,r);
+       //        omCheckAddr(cMT->m);
+       p_Delete(&t,r);
+     }
+     t=NULL;
+  }
+
+  for (m=2;m<=b;m++)
+  {
+    t = MATELEM(cMT,a,m);
+    //     t=MATELEM(cMT,a,m);
+    if (t==NULL)   //not computed yet
+    {
+      t = nc_p_CopyGet(MATELEM(cMT,a,m-1),r);
+      assume( t != NULL );
+      //      t=p_Copy(MATELEM(cMT,a,m-1),r);
+      t = gnc_p_Mult_mm(t,x,r);
+      cMT=r->GetNC()->MT[cMTindex]; // since multiplication can change the MT table...
+#ifdef PDEBUG
+      p_Test(t,r);
+#endif
+      MATELEM(cMT,a,m) = nc_p_CopyPut(t,r);
+      //      MATELEM(cMT,a,m) = t;
+      //        omCheckAddr(cMT->m);
+      p_Delete(&t,r);
+    }
+    t=NULL;
+  }
+  p_Delete(&x,r);
+  p_Delete(&y,r);
+  t=MATELEM(cMT,a,b);
+  assume( t != NULL );
+
+  t= nc_p_CopyGet(t,r);
+#ifdef PDEBUG
+  p_Test(t,r);
+#endif
+  //  return(p_Copy(t,r));
+  /* since the last computed element was cMT[a,b] */
+  return(t);
+}
+
+
+static inline poly gnc_uu_Mult_ww_formula (int i, int a, int j, int b, const ring r)
+{
+  if(ncExtensions(NOFORMULAMASK))
+    return gnc_uu_Mult_ww_vert(i, a, j, b, r);
+
+  CFormulaPowerMultiplier* FormulaMultiplier = GetFormulaPowerMultiplier(r);
+  Enum_ncSAType PairType = _ncSA_notImplemented;
+
+  if( FormulaMultiplier != NULL )
+    PairType = FormulaMultiplier->GetPair(j, i);
+
+
+  if( PairType == _ncSA_notImplemented )
+    return gnc_uu_Mult_ww_vert(i, a, j, b, r);
+
+
+ //    return FormulaMultiplier->Multiply(j, i, b, a);
+  poly t = CFormulaPowerMultiplier::Multiply( PairType, j, i, b, a, r);
+
+  int rN=r->N;
+  matrix cMT = r->GetNC()->MT[UPMATELEM(j,i,rN)];         /* cMT=current MT */
+
+
+  MATELEM(cMT, a, b) = nc_p_CopyPut(t,r);
+
+  //  t=MATELEM(cMT,a,b);
+//  t= nc_p_CopyGet(MATELEM(cMT,a,b),r);
+  //  return(p_Copy(t,r));
+  /* since the last computed element was cMT[a,b] */
+  return(t);
+}
+
+
+poly gnc_uu_Mult_ww (int i, int a, int j, int b, const ring r)
+  /* (x_i)^a times (x_j)^b */
+  /* x_i = y,  x_j = x ! */
+{
+  /* Check zero exceptions, (q-)commutativity and is there something to do? */
+  assume(a!=0);
+  assume(b!=0);
+  poly out=p_One(r);
+  if (i<=j)
+  {
+    p_SetExp(out,i,a,r);
+    p_AddExp(out,j,b,r);
+    p_Setm(out,r);
+    return(out);
+  }/* zero exeptions and usual case */
+  /*  if ((a==0)||(b==0)||(i<=j)) return(out); */
+
+  if (MATELEM(r->GetNC()->COM,j,i)!=NULL)
+    /* commutative or quasicommutative case */
+  {
+    p_SetExp(out,i,a,r);
+    p_AddExp(out,j,b,r);
+    p_Setm(out,r);
+    if (n_IsOne(p_GetCoeff(MATELEM(r->GetNC()->COM,j,i),r),r)) /* commutative case */
+    {
+      return(out);
+    }
+    else
+    {
+      number tmp_number=p_GetCoeff(MATELEM(r->GetNC()->COM,j,i),r); /* quasicommutative case */
+      n_Power(tmp_number,a*b,&tmp_number, r); // BUG! ;-(
+      p_SetCoeff(out,tmp_number,r);
+      return(out);
+    }
+  }/* end_of commutative or quasicommutative case */
+  p_Delete(&out,r);
+
+
+  if(ncExtensions(NOCACHEMASK) && !ncExtensions(NOFORMULAMASK)) // don't use cache whenever possible!
+  { // without cache!?
+    CFormulaPowerMultiplier* FormulaMultiplier = GetFormulaPowerMultiplier(r);
+    Enum_ncSAType PairType = _ncSA_notImplemented;
+
+     if( FormulaMultiplier != NULL )
+       PairType = FormulaMultiplier->GetPair(j, i);
+
+     if( PairType != _ncSA_notImplemented )
+  // //    return FormulaMultiplier->Multiply(j, i, b, a);
+       return CFormulaPowerMultiplier::Multiply( PairType, j, i, b, a, r);
+  }
+
+
+  /* we are here if  i>j and variables do not commute or quasicommute */
+  /* in fact, now a>=1 and b>=1; and j<i */
+  /* now check whether the polynomial is already computed */
+  int rN=r->N;
+  int vik = UPMATELEM(j,i,rN);
+  int cMTsize=r->GetNC()->MTsize[vik];
+  int newcMTsize=0;
+  newcMTsize=si_max(a,b);
+
+  if (newcMTsize<=cMTsize)
+  {
+    out =  nc_p_CopyGet(MATELEM(r->GetNC()->MT[vik],a,b),r);
+    if (out !=NULL) return (out);
+  }
+  int k,m;
+  if (newcMTsize > cMTsize)
+  {
+    int inM=(((newcMTsize+6)/7)*7);
+    assume (inM>=newcMTsize);
+    newcMTsize = inM;
+    //    matrix tmp = (matrix)omAlloc0(inM*inM*sizeof(poly));
+    matrix tmp = mpNew(newcMTsize,newcMTsize);
+
+    for (k=1;k<=cMTsize;k++)
+    {
+      for (m=1;m<=cMTsize;m++)
+      {
+        out = MATELEM(r->GetNC()->MT[UPMATELEM(j,i,rN)],k,m);
+        if ( out != NULL )
+        {
+          MATELEM(tmp,k,m) = out;/*MATELEM(r->GetNC()->MT[UPMATELEM(j,i,rN)],k,m)*/
+          //           omCheckAddr(tmp->m);
+          MATELEM(r->GetNC()->MT[UPMATELEM(j,i,rN)],k,m)=NULL;
+          //           omCheckAddr(r->GetNC()->MT[UPMATELEM(j,i,rN)]->m);
+          out=NULL;
+        }
+      }
+    }
+    id_Delete((ideal *)&(r->GetNC()->MT[UPMATELEM(j,i,rN)]),r);
+    r->GetNC()->MT[UPMATELEM(j,i,rN)] = tmp;
+    tmp=NULL;
+    r->GetNC()->MTsize[UPMATELEM(j,i,rN)] = newcMTsize;
+  }
+  /* The update of multiplication matrix is finished */
+
+
+  return gnc_uu_Mult_ww_formula(i, a, j, b, r);
+
+  out = gnc_uu_Mult_ww_vert(i, a, j, b, r);
+  //    out = nc_uu_Mult_ww_horvert(i, a, j, b, r);
+  return(out);
+}
+
+poly gnc_uu_Mult_ww_horvert (int i, int a, int j, int b, const ring r)
+
+{
+  int k,m;
+  int rN=r->N;
+  matrix cMT=r->GetNC()->MT[UPMATELEM(j,i,rN)];         /* cMT=current MT */
+
+  poly x=p_One(r);p_SetExp(x,j,1,r);p_Setm(x,r);/* var(j); */
+  poly y=p_One(r);p_SetExp(y,i,1,r);p_Setm(y,r); /*var(i);  for convenience */
+#ifdef PDEBUG
+  p_Test(x,r);
+  p_Test(y,r);
+#endif
+
+  poly t=NULL;
+
+  int toXY;
+  int toYX;
+
+  if (a==1) /* y*x^b, b>=2 */
+  {
+    toXY=b-1;
+    while ( (MATELEM(cMT,1,toXY)==NULL) && (toXY>=2)) toXY--;
+    for (m=toXY+1;m<=b;m++)
+    {
+      t=MATELEM(cMT,1,m);
+      if (t==NULL)   /* remove after debug */
+      {
+        t = p_Copy(MATELEM(cMT,1,m-1),r);
+        t = gnc_p_Mult_mm(t,x,r);
+        MATELEM(cMT,1,m) = t;
+        /*        omCheckAddr(cMT->m); */
+      }
+      else
+      {
+        /* Error, should never get there */
+        WarnS("Error: a=1; MATELEM!=0");
+      }
+      t=NULL;
+    }
+    return(p_Copy(MATELEM(cMT,1,b),r));
+  }
+
+  if (b==1) /* y^a*x, a>=2 */
+  {
+    toYX=a-1;
+    while ( (MATELEM(cMT,toYX,1)==NULL) && (toYX>=2)) toYX--;
+    for (m=toYX+1;m<=a;m++)
+    {
+      t=MATELEM(cMT,m,1);
+      if (t==NULL)   /* remove after debug */
+      {
+        t = p_Copy(MATELEM(cMT,m-1,1),r);
+        t = gnc_mm_Mult_p(y,t,r);
+        MATELEM(cMT,m,1) = t;
+        /*        omCheckAddr(cMT->m); */
+      }
+      else
+      {
+        /* Error, should never get there */
+        WarnS("Error: b=1, MATELEM!=0");
+      }
+      t=NULL;
+    }
+    return(p_Copy(MATELEM(cMT,a,1),r));
+  }
+
+/* ------------ Main Cycles ----------------------------*/
+  /*            a>1, b>1              */
+
+  int dXY=0; int dYX=0;
+  /* dXY = distance for computing x-mult, then y-mult */
+  /* dYX = distance for computing y-mult, then x-mult */
+  int toX=a-1; int toY=b-1; /* toX = to axe X, toY = to axe Y */
+  toXY=b-1; toYX=a-1;
+  /* if toX==0, toXY = dist. to computed y * x^toXY */
+  /* if toY==0, toYX = dist. to computed y^toYX * x */
+  while ( (MATELEM(cMT,toX,b)==NULL) && (toX>=1)) toX--;
+  if (toX==0) /* the whole column is not computed yet */
+  {
+    while ( (MATELEM(cMT,1,toXY)==NULL) && (toXY>=1)) toXY--;
+    /* toXY >=1 */
+    dXY=b-1-toXY;
+  }
+  dXY=dXY+a-toX; /* the distance to nearest computed y^toX x^b */
+
+  while ( (MATELEM(cMT,a,toY)==NULL) && (toY>=1)) toY--;
+  if (toY==0) /* the whole row is not computed yet */
+  {
+    while ( (MATELEM(cMT,toYX,1)==NULL) && (toYX>=1)) toYX--;
+    /* toYX >=1 */
+    dYX=a-1-toYX;
+  }
+  dYX=dYX+b-toY; /* the distance to nearest computed y^a x^toY */
+
+  if (dYX>=dXY)
+  {
+    /* first x, then y */
+    if (toX==0) /* start with the row*/
+    {
+      for (m=toXY+1;m<=b;m++)
+      {
+        t=MATELEM(cMT,1,m);
+        if (t==NULL)   /* remove after debug */
+        {
+          t = p_Copy(MATELEM(cMT,1,m-1),r);
+          t = gnc_p_Mult_mm(t,x,r);
+          MATELEM(cMT,1,m) = t;
+          /*        omCheckAddr(cMT->m); */
+        }
+        else
+        {
+          /* Error, should never get there */
+          WarnS("dYX>=dXY,toXY; MATELEM==0");
+        }
+        t=NULL;
+      }
+      toX=1; /* y*x^b is computed */
+    }
+    /* Now toX>=1 */
+    for (k=toX+1;k<=a;k++)
+    {
+      t=MATELEM(cMT,k,b);
+      if (t==NULL)   /* remove after debug */
+      {
+        t = p_Copy(MATELEM(cMT,k-1,b),r);
+        t = gnc_mm_Mult_p(y,t,r);
+        MATELEM(cMT,k,b) = t;
+        /*        omCheckAddr(cMT->m); */
+      }
+      else
+      {
+        /* Error, should never get there */
+        WarnS("dYX>=dXY,toX; MATELEM==0");
+      }
+      t=NULL;
+    }
+  } /* endif (dYX>=dXY) */
+
+
+  if (dYX<dXY)
+  {
+    /* first y, then x */
+    if (toY==0) /* start with the column*/
+    {
+      for (m=toYX+1;m<=a;m++)
+      {
+        t=MATELEM(cMT,m,1);
+        if (t==NULL)   /* remove after debug */
+        {
+          t = p_Copy(MATELEM(cMT,m-1,1),r);
+          t = gnc_mm_Mult_p(y,t,r);
+          MATELEM(cMT,m,1) = t;
+          /*        omCheckAddr(cMT->m); */
+        }
+        else
+        {
+          /* Error, should never get there */
+          WarnS("dYX<dXY,toYX; MATELEM==0");
+        }
+        t=NULL;
+      }
+      toY=1; /* y^a*x is computed */
+    }
+    /* Now toY>=1 */
+    for (k=toY+1;k<=b;k++)
+    {
+      t=MATELEM(cMT,a,k);
+      if (t==NULL)   /* remove after debug */
+      {
+        t = p_Copy(MATELEM(cMT,a,k-1),r);
+        t = gnc_p_Mult_mm(t,x,r);
+        MATELEM(cMT,a,k) = t;
+        /*        omCheckAddr(cMT->m); */
+      }
+      else
+      {
+        /* Error, should never get there */
+        WarnS("dYX<dXY,toY; MATELEM==0");
+      }
+      t=NULL;
+    }
+  } /* endif (dYX<dXY) */
+
+  p_Delete(&x,r);
+  p_Delete(&y,r);
+  t=p_Copy(MATELEM(cMT,a,b),r);
+  return(t);  /* since the last computed element was cMT[a,b] */
+}
+
+
+/* ----------------------------- Syzygies ---------------------- */
+
+/*2
+* reduction of p2 with p1
+* do not destroy p1, but p2
+* p1 divides p2 -> for use in NF algorithm
+*/
+poly gnc_ReduceSpolyOld(const poly p1, poly p2/*,poly spNoether*/, const ring r)
+{
+  assume(p_LmDivisibleBy(p1, p2, r));
+
+#ifdef PDEBUG
+  if (p_GetComp(p1,r)!=p_GetComp(p2,r)
+  && (p_GetComp(p1,r)!=0)
+  && (p_GetComp(p2,r)!=0))
+  {
+    dReportError("nc_ReduceSpolyOld: different components");
+    return(NULL);
+  }
+#endif
+  poly m = p_One(r);
+  p_ExpVectorDiff(m,p2,p1,r);
+  //p_Setm(m,r);
+#ifdef PDEBUG
+  p_Test(m,r);
+#endif
+  /* pSetComp(m,r)=0? */
+  poly   N  = nc_mm_Mult_p(m, p_Head(p1,r), r);
+  number C  =  p_GetCoeff(N,  r);
+  number cF =  p_GetCoeff(p2, r);
+  /* GCD stuff */
+  number cG = n_SubringGcd(C, cF, r->cf);
+  if ( !n_IsOne(cG,r) )
+  {
+    cF = n_Div(cF, cG, r); n_Normalize(cF, r);
+    C  = n_Div(C,  cG, r); n_Normalize(C, r);
+  }
+  else
+  {
+    cF = n_Copy(cF, r);
+    C  = n_Copy(C, r);
+  }
+  n_Delete(&cG,r);
+  p2 = p_Mult_nn(p2, C, r);
+  poly out = nc_mm_Mult_pp(m, pNext(p1), r);
+  N = p_Add_q(N, out, r);
+  p_Test(p2,r);
+  p_Test(N,r);
+  if (!n_IsMOne(cF,r))
+  {
+    cF = n_InpNeg(cF,r);
+    N  = p_Mult_nn(N, cF, r);
+    p_Test(N,r);
+  }
+  out = p_Add_q(p2,N,r);
+  p_Test(out,r);
+  if ( out!=NULL ) p_Content(out,r);
+  p_Delete(&m,r);
+  n_Delete(&cF,r);
+  n_Delete(&C,r);
+  return(out);
+}
+
+poly gnc_ReduceSpolyNew(const poly p1, poly p2, const ring r)
+{
+  assume(p_LmDivisibleBy(p1, p2, r));
+
+  const long lCompP1 = p_GetComp(p1,r);
+  const long lCompP2 = p_GetComp(p2,r);
+
+  if ((lCompP1!=lCompP2) && (lCompP1!=0) && (lCompP2!=0))
+  {
+#ifdef PDEBUG
+    Werror("gnc_ReduceSpolyNew: different non-zero components!");
+#endif
+    return(NULL);
+  }
+
+  poly m = p_One(r);
+  p_ExpVectorDiff(m, p2, p1, r);
+  //p_Setm(m,r);
+#ifdef PDEBUG
+  p_Test(m,r);
+#endif
+
+  /* pSetComp(m,r)=0? */
+  poly   N  = nc_mm_Mult_p(m, p_Head(p1,r), r);
+
+  number C  = p_GetCoeff(N,  r);
+  number cF = p_GetCoeff(p2, r);
+
+  /* GCD stuff */
+  number cG = n_SubringGcd(C, cF, r->cf);
+
+  if (!n_IsOne(cG, r))
+  {
+    cF = n_Div(cF, cG, r); n_Normalize(cF, r);
+    C  = n_Div(C,  cG, r); n_Normalize(C, r);
+  }
+  else
+  {
+    cF = n_Copy(cF, r);
+    C  = n_Copy(C, r);
+  }
+  n_Delete(&cG,r);
+
+  p2 = p_Mult_nn(p2, C, r); // p2 !!!
+  p_Test(p2,r);
+  n_Delete(&C,r);
+  n_Delete(&cG,r);
+
+  poly out = nc_mm_Mult_pp(m, pNext(p1), r);
+  p_Delete(&m,r);
+
+  N = p_Add_q(N, out, r);
+  p_Test(N,r);
+
+  if (!n_IsMOne(cF,r)) // ???
+  {
+    cF = n_InpNeg(cF,r);
+    N  = p_Mult_nn(N, cF, r);
+    p_Test(N,r);
+  }
+  n_Delete(&cF,r);
+
+  out = p_Add_q(p2,N,r); // delete N, p2
+  p_Test(out,r);
+  if ( out!=NULL ) p_Content(out,r);
+  return(out);
+}
+
+
+/*4
+* creates the S-polynomial of p1 and p2
+* do not destroy p1 and p2
+*/
+poly gnc_CreateSpolyOld(poly p1, poly p2/*,poly spNoether*/, const ring r)
+{
+#ifdef PDEBUG
+  if ((p_GetComp(p1,r)!=p_GetComp(p2,r))
+  && (p_GetComp(p1,r)!=0)
+  && (p_GetComp(p2,r)!=0))
+  {
+    dReportError("gnc_CreateSpolyOld : different components!");
+    return(NULL);
+  }
+#endif
+  if ((ncRingType(r)==nc_lie) && p_HasNotCF(p1,p2, r)) /* prod crit */
+  {
+    return(nc_p_Bracket_qq(p_Copy(p2, r),p1, r));
+  }
+  poly pL=p_One(r);
+  poly m1=p_One(r);
+  poly m2=p_One(r);
+  pL = p_Lcm(p1,p2,r);
+  p_Setm(pL,r);
+#ifdef PDEBUG
+  p_Test(pL,r);
+#endif
+  p_ExpVectorDiff(m1,pL,p1,r);
+  //p_SetComp(m1,0,r);
+  //p_Setm(m1,r);
+#ifdef PDEBUG
+  p_Test(m1,r);
+#endif
+  p_ExpVectorDiff(m2,pL,p2,r);
+  //p_SetComp(m2,0,r);
+  //p_Setm(m2,r);
+#ifdef PDEBUG
+  p_Test(m2,r);
+#endif
+  p_Delete(&pL,r);
+  /* zero exponents ! */
+  poly M1    = nc_mm_Mult_p(m1,p_Head(p1,r),r);
+  number C1  = p_GetCoeff(M1,r);
+  poly M2    = nc_mm_Mult_p(m2,p_Head(p2,r),r);
+  number C2  = p_GetCoeff(M2,r);
+  /* GCD stuff */
+  number C = n_SubringGcd(C1,C2,r->cf);
+  if (!n_IsOne(C,r))
+  {
+    C1=n_Div(C1,C, r);n_Normalize(C1,r);
+    C2=n_Div(C2,C, r);n_Normalize(C2,r);
+  }
+  else
+  {
+    C1=n_Copy(C1, r);
+    C2=n_Copy(C2, r);
+  }
+  n_Delete(&C,r);
+  M1=p_Mult_nn(M1,C2,r);
+  p_SetCoeff(m1,C2,r);
+  if (n_IsMOne(C1,r))
+  {
+    M2=p_Add_q(M1,M2,r);
+  }
+  else
+  {
+    C1=n_InpNeg(C1,r);
+    M2=p_Mult_nn(M2,C1,r);
+    M2=p_Add_q(M1,M2,r);
+    p_SetCoeff(m2,C1,r);
+  }
+  /* M1 is killed, M2=res = C2 M1 - C1 M2 */
+  poly tmp=p_Copy(p1,r);
+  tmp=p_LmDeleteAndNext(tmp,r);
+  M1=nc_mm_Mult_p(m1,tmp,r);
+  tmp=p_Copy(p2,r);
+  tmp=p_LmDeleteAndNext(tmp,r);
+  M2=p_Add_q(M2,M1,r);
+  M1=nc_mm_Mult_p(m2,tmp,r);
+  M2=p_Add_q(M2,M1,r);
+  p_Delete(&m1,r);
+  p_Delete(&m2,r);
+  //  n_Delete(&C1,r);
+  //  n_Delete(&C2,r);
+#ifdef PDEBUG
+  p_Test(M2,r);
+#endif
+  if (M2!=NULL) M2=p_Cleardenom(M2,r);
+  //if (M2!=NULL) p_Content(M2); // done by pCleardenom
+  return(M2);
+}
+
+poly gnc_CreateSpolyNew(poly p1, poly p2/*,poly spNoether*/, const ring r)
+{
+#ifdef PDEBUG
+  p_Test(p1, r);
+  p_Test(p2, r);
+#if MYTEST
+  Print("p1: "); p_Write(p1, r);
+  Print("p2: "); p_Write(p2, r);
+#endif
+#endif
+
+  const long lCompP1 = p_GetComp(p1,r);
+  const long lCompP2 = p_GetComp(p2,r);
+
+  if ((lCompP1!=lCompP2) && (lCompP1!=0) && (lCompP2!=0))
+  {
+#ifdef PDEBUG
+    Werror("gnc_CreateSpolyNew: different non-zero components!");
+    assume(0);
+#endif
+    return(NULL);
+  }
+
+//   if ((r->GetNC()->type==nc_lie) && pHasNotCF(p1,p2)) /* prod crit */
+//   {
+//     return(nc_p_Bracket_qq(pCopy(p2),p1));
+//   }
+
+//  poly pL=p_One( r);
+
+  poly m1=p_One( r);
+  poly m2=p_One( r);
+
+  poly pL = p_Lcm(p1,p2,r);                               // pL = lcm( lm(p1), lm(p2) )
+
+
+#ifdef PDEBUG
+//  p_Test(pL,r);
+#endif
+
+  p_ExpVectorDiff(m1, pL, p1, r);                  // m1 = pL / lm(p1)
+  //p_SetComp(m1,0,r);
+  //p_Setm(m1,r);
+
+#ifdef PDEBUG
+  p_Test(m1,r);
+#endif
+//  assume(p_GetComp(m1,r) == 0);
+
+  p_ExpVectorDiff(m2, pL, p2, r);                  // m2 = pL / lm(p2)
+
+  //p_SetComp(m2,0,r);
+  //p_Setm(m2,r);
+#ifdef PDEBUG
+  p_Test(m2,r);
+#endif
+
+#ifdef PDEBUG
+#if MYTEST
+  Print("m1: "); pWrite(m1);
+  Print("m2: "); pWrite(m2);
+#endif
+#endif
+
+
+//  assume(p_GetComp(m2,r) == 0);
+
+#ifdef PDEBUG
+#if 0
+  if(  (p_GetComp(m2,r) != 0) || (p_GetComp(m1,r) != 0) )
+  {
+    WarnS("gnc_CreateSpolyNew: wrong monomials!");
+
+
+#ifdef RDEBUG
+    PrintS("m1 = "); p_Write(m1, r);
+    p_DebugPrint(m1, r);
+
+    PrintS("m2 = "); p_Write(m2, r);
+    p_DebugPrint(m2, r);
+
+    PrintS("p1 = "); p_Write(p1, r);
+    p_DebugPrint(p1, r);
+
+    PrintS("p2 = "); p_Write(p2, r);
+    p_DebugPrint(p2, r);
+
+    PrintS("pL = "); p_Write(pL, r);
+    p_DebugPrint(pL, r);
+#endif
+
+  }
+
+#endif
+#endif
+
+  p_Delete(&pL,r);
+
+  /* zero exponents !? */
+  poly M1    = nc_mm_Mult_p(m1,p_Head(p1,r),r); // M1 = m1 * lt(p1)
+  poly M2    = nc_mm_Mult_p(m2,p_Head(p2,r),r); // M2 = m2 * lt(p2)
+
+#ifdef PDEBUG
+  p_Test(M1,r);
+  p_Test(M2,r);
+
+#if MYTEST
+  Print("M1: "); pWrite(M1);
+  Print("M2: "); pWrite(M2);
+#endif
+#endif
+
+  if(M1 == NULL || M2 == NULL)
+  {
+#ifdef PDEBUG
+       Print("\np1 = ");
+       p_Write(p1, r);
+
+       Print("m1 = ");
+       p_Write(m1, r);
+
+       Print("p2 = ");
+       p_Write(p2, r);
+
+       Print("m2 = ");
+       p_Write(m2, r);
+
+       Werror("ERROR in nc_CreateSpoly: result of multiplication is Zero!\n");
+#endif
+       return(NULL);
+  }
+
+  number C1  = p_GetCoeff(M1,r);      // C1 = lc(M1)
+  number C2  = p_GetCoeff(M2,r);      // C2 = lc(M2)
+
+  /* GCD stuff */
+  number C = n_SubringGcd(C1, C2, r->cf);           // C = gcd(C1, C2)
+
+  if (!n_IsOne(C, r))                              // if C != 1
+  {
+    C1=n_Div(C1, C, r);n_Normalize(C1,r);            // C1 = C1 / C
+    C2=n_Div(C2, C, r);n_Normalize(C2,r);            // C2 = C2 / C
+  }
+  else
+  {
+    C1=n_Copy(C1,r);
+    C2=n_Copy(C2,r);
+  }
+
+  n_Delete(&C,r); // destroy the number C
+
+  C1=n_InpNeg(C1,r);
+
+//   number MinusOne=n_Init(-1,r);
+//   if (n_Equal(C1,MinusOne,r))                   // lc(M1) / gcd( lc(M1), lc(M2)) == -1 ????
+//   {
+//     M2=p_Add_q(M1,M2,r);                        // ?????
+//   }
+//   else
+//   {
+  M1=p_Mult_nn(M1,C2,r);                           // M1 = (C2*lc(p1)) * (lcm(lm(p1),lm(p2)) / lm(p1)) * lm(p1)
+
+#ifdef PDEBUG
+  p_Test(M1,r);
+#endif
+
+  M2=p_Mult_nn(M2,C1,r);                           // M2 =(-C1*lc(p2)) * (lcm(lm(p1),lm(p2)) / lm(p2)) * lm(p2)
+
+
+
+#ifdef PDEBUG
+  p_Test(M2,r);
+
+#if MYTEST
+  Print("M1: "); pWrite(M1);
+  Print("M2: "); pWrite(M2);
+#endif
+#endif
+
+
+  M2=p_Add_q(M1,M2,r);                             // M1 is killed, M2 = spoly(lt(p1), lt(p2)) = C2*M1 - C1*M2
+
+#ifdef PDEBUG
+  p_Test(M2,r);
+
+#if MYTEST
+  Print("M2: "); pWrite(M2);
+#endif
+
+#endif
+
+// M2 == 0 for supercommutative algebras!
+//   }
+//   n_Delete(&MinusOne,r);
+
+  p_SetCoeff(m1,C2,r);                           // lc(m1) = C2!!!
+  p_SetCoeff(m2,C1,r);                           // lc(m2) = C1!!!
+
+#ifdef PDEBUG
+  p_Test(m1,r);
+  p_Test(m2,r);
+#endif
+
+//  poly tmp = p_Copy(p1,r);                         // tmp = p1
+//  tmp=p_LmDeleteAndNext(tmp,r);                  // tmp = tail(p1)
+//#ifdef PDEBUG
+//  p_Test(tmp,r);
+//#endif
+
+  M1 = nc_mm_Mult_pp(m1, pNext(p1), r);                      // M1 = m1 * tail(p1), delete tmp // ???
+
+#ifdef PDEBUG
+  p_Test(M1,r);
+
+#if MYTEST
+  Print("M1: "); pWrite(M1);
+#endif
+
+#endif
+
+  M2=p_Add_q(M2,M1,r);                           // M2 = spoly(lt(p1), lt(p2)) + m1 * tail(p1), delete M1
+#ifdef PDEBUG
+  M1=NULL;
+  p_Test(M2,r);
+
+#if MYTEST
+  Print("M2: "); pWrite(M2);
+#endif
+
+#endif
+
+//  tmp=p_Copy(p2,r);                              // tmp = p2
+//  tmp=p_LmDeleteAndNext(tmp,r);                  // tmp = tail(p2)
+
+//#ifdef PDEBUG
+//  p_Test(tmp,r);
+//#endif
+
+  M1 = nc_mm_Mult_pp(m2, pNext(p2), r);                      // M1 = m2 * tail(p2), detele tmp
+
+#ifdef PDEBUG
+  p_Test(M1,r);
+
+#if MYTEST
+  Print("M1: "); pWrite(M1);
+#endif
+
+#endif
+
+  M2 = p_Add_q(M2,M1,r);                           // M2 = spoly(lt(p1), lt(p2)) + m1 * tail(p1) + m2*tail(p2)
+
+#ifdef PDEBUG
+  M1=NULL;
+  p_Test(M2,r);
+
+#if MYTEST
+  Print("M2: "); pWrite(M2);
+#endif
+
+#endif
+
+  p_Delete(&m1,r);  //  => n_Delete(&C1,r);
+  p_Delete(&m2,r);  //  => n_Delete(&C2,r);
+
+#ifdef PDEBUG
+  p_Test(M2,r);
+#endif
+
+  if (M2!=NULL) p_Cleardenom(M2,r);
+
+  return(M2);
+}
+
+
+
+
+#if 0
+/*5
+* reduction of tail(q) with p1
+* lead(p1) divides lead(pNext(q2)) and pNext(q2) is reduced
+* do not destroy p1, but tail(q)
+*/
+void gnc_ReduceSpolyTail(poly p1, poly q, poly q2, poly spNoether, const ring r)
+{
+  poly a1=p_Head(p1,r);
+  poly Q=pNext(q2);
+  number cQ=p_GetCoeff(Q,r);
+  poly m=p_One(r);
+  p_ExpVectorDiff(m,Q,p1,r);
+  //  p_SetComp(m,0,r);
+  //p_Setm(m,r);
+#ifdef PDEBUG
+  p_Test(m,r);
+#endif
+  /* pSetComp(m,r)=0? */
+  poly M = nc_mm_Mult_pp(m, p1,r);
+  number C=p_GetCoeff(M,r);
+  M=p_Add_q(M,nc_mm_Mult_p(m,p_LmDeleteAndNext(p_Copy(p1,r),r),r),r); // _pp?
+  q=p_Mult_nn(q,C,r);
+  number MinusOne=n_Init(-1,r);
+  if (!n_Equal(cQ,MinusOne,r))
+  {
+    cQ=nInpNeg(cQ);
+    M=p_Mult_nn(M,cQ,r);
+  }
+  Q=p_Add_q(Q,M,r);
+  pNext(q2)=Q;
+
+  p_Delete(&m,r);
+  n_Delete(&C,r);
+  n_Delete(&cQ,r);
+  n_Delete(&MinusOne,r);
+  /*  return(q); */
+}
+#endif
+
+
+/*6
+* creates the commutative lcm(lm(p1),lm(p2))
+* do not destroy p1 and p2
+*/
+poly nc_CreateShortSpoly(poly p1, poly p2, const ring r)
+{
+#ifdef PDEBUG
+  p_Test(p1, r);
+  p_Test(p2, r);
+#endif
+
+  const long lCompP1 = p_GetComp(p1,r);
+  const long lCompP2 = p_GetComp(p2,r);
+
+  if ((lCompP1!=lCompP2) && (lCompP1!=0) && (lCompP2!=0))
+  {
+#ifdef PDEBUG
+    Werror("nc_CreateShortSpoly: wrong module components!"); // !!!!
+#endif
+    return(NULL);
+  }
+
+  poly m;
+
+#ifdef HAVE_RATGRING
+  if ( rIsRatGRing(r))
+  {
+    /* rational version */
+    m = p_LcmRat(p1, p2, si_max(lCompP1, lCompP2), r);
+  } else
+#endif
+  {
+    m = p_Lcm(p1, p2, si_max(lCompP1, lCompP2), r);
+  }
+
+//  n_Delete(&p_GetCoeff(m, r), r);
+//  pSetCoeff0(m, NULL);
+
+#ifdef PDEBUG
+//  p_Test(m,r);
+#endif
+
+  return(m);
+}
+
+void gnc_kBucketPolyRedOld(kBucket_pt b, poly p, number *c)
+{
+  const ring r = b->bucket_ring;
+  // b will not be multiplied by any constant in this impl.
+  // ==> *c=1
+  if (c!=NULL) *c=n_Init(1, r);
+  poly m=p_One(r);
+  p_ExpVectorDiff(m,kBucketGetLm(b),p, r);
+  //pSetm(m);
+#ifdef PDEBUG
+  p_Test(m, r);
+#endif
+  poly pp= nc_mm_Mult_pp(m,p, r);
+  assume(pp!=NULL);
+  p_Delete(&m, r);
+  number n=p_GetCoeff(pp, r);
+  number nn;
+  if (!n_IsMOne(n, r))
+  {
+    nn=n_InpNeg(n_Invers(n, r), r);
+    n= n_Mult(nn,p_GetCoeff(kBucketGetLm(b), r), r);
+    n_Delete(&nn, r);
+    pp=p_Mult_nn(pp,n,r);
+    n_Delete(&n, r);
+  }
+  else
+  {
+    pp=p_Mult_nn(pp,p_GetCoeff(kBucketGetLm(b), r),r);
+  }
+  int l=pLength(pp);
+  kBucket_Add_q(b,pp,&l);
+}
+
+void gnc_kBucketPolyRedNew(kBucket_pt b, poly p, number *c)
+{
+  const ring r = b->bucket_ring;
+#ifdef PDEBUG
+//   Print(">*");
+#endif
+
+#ifdef KDEBUG
+  if( !kbTest(b) )Werror("nc_kBucketPolyRed: broken bucket!");
+#endif
+
+#ifdef PDEBUG
+  p_Test(p, r);
+#if MYTEST
+  Print("p: "); p_Write(p, r);
+#endif
+#endif
+
+  // b will not be multiplied by any constant in this impl.
+  // ==> *c=1
+  if (c!=NULL) *c=n_Init(1, r);
+  poly m = p_One(r);
+  const poly pLmB = kBucketGetLm(b); // no new copy!
+
+  assume( pLmB != NULL );
+
+#ifdef PDEBUG
+  p_Test(pLmB, r);
+
+#if MYTEST
+  Print("pLmB: "); p_Write(pLmB, r);
+#endif
+#endif
+
+  p_ExpVectorDiff(m, pLmB, p, r);
+  //pSetm(m);
+
+#ifdef PDEBUG
+  p_Test(m, r);
+#if MYTEST
+  Print("m: "); p_Write(m, r);
+#endif
+#endif
+
+  poly pp = nc_mm_Mult_pp(m, p, r);
+  p_Delete(&m, r);
+
+  assume( pp != NULL );
+  const number n = p_GetCoeff(pp, r); // bug!
+
+  if (!n_IsMOne(n, r) ) // does this improve performance??!? also see below... // TODO: check later on.
+  // if n == -1 => nn = 1 and -1/n
+  {
+    number nn=n_InpNeg(n_Invers(n, r), r);
+    number t = n_Mult(nn,p_GetCoeff(pLmB, r), r);
+    n_Delete(&nn, r);
+    pp = p_Mult_nn(pp,t,r);
+    n_Delete(&t, r);
+  }
+  else
+  {
+    pp = p_Mult_nn(pp,p_GetCoeff(pLmB, r), r);
+  }
+
+  int l = pLength(pp);
+
+#ifdef PDEBUG
+  p_Test(pp, r);
+//   Print("PP: "); pWrite(pp);
+#endif
+
+  kBucket_Add_q(b,pp,&l);
+
+
+#ifdef PDEBUG
+//   Print("*>");
+#endif
+}
+
+
+void gnc_kBucketPolyRed_ZOld(kBucket_pt b, poly p, number *c)
+{
+  const ring r = b->bucket_ring;
+  // b is multiplied by a constant in this impl.
+  number ctmp;
+  poly m=p_One(r);
+  p_ExpVectorDiff(m,kBucketGetLm(b),p, r);
+  //pSetm(m);
+#ifdef PDEBUG
+  p_Test(m, r);
+#endif
+  if(p_IsConstant(m,r))
+  {
+    p_Delete(&m, r);
+    ctmp = kBucketPolyRed(b,p,pLength(p),NULL);
+  }
+  else
+  {
+    poly pp = nc_mm_Mult_pp(m,p,r);
+    number c2;
+    p_Cleardenom_n(pp,r,c2);
+    p_Delete(&m, r);
+    ctmp = kBucketPolyRed(b,pp,pLength(pp),NULL);
+    //cc=*c;
+    //*c=nMult(*c,c2);
+    n_Delete(&c2, r);
+    //nDelete(&cc);
+    p_Delete(&pp, r);
+  }
+  if (c!=NULL) *c=ctmp;
+  else n_Delete(&ctmp, r);
+}
+
+void gnc_kBucketPolyRed_ZNew(kBucket_pt b, poly p, number *c)
+{
+  const ring r = b->bucket_ring;
+  // b is multiplied by a constant in this impl.
+  number ctmp;
+  poly m=p_One(r);
+  p_ExpVectorDiff(m,kBucketGetLm(b),p, r);
+  //pSetm(m);
+#ifdef PDEBUG
+  p_Test(m, r);
+#endif
+
+  if(p_IsConstant(m,r))
+  {
+    p_Delete(&m, r);
+    ctmp = kBucketPolyRed(b,p,pLength(p),NULL);
+  }
+  else
+  {
+    poly pp = nc_mm_Mult_pp(m,p,r);
+    number c2;
+    p_Cleardenom_n(pp,r,c2);
+    p_Delete(&m, r);
+    ctmp = kBucketPolyRed(b,pp,pLength(pp),NULL);
+    //cc=*c;
+    //*c=nMult(*c,c2);
+    n_Delete(&c2, r);
+    //nDelete(&cc);
+    p_Delete(&pp, r);
+  }
+  if (c!=NULL) *c=ctmp;
+  else n_Delete(&ctmp, r);
+}
+
+
+inline void nc_PolyPolyRedOld(poly &b, poly p, number *c, const ring r)
+  // reduces b with p, do not delete both
+{
+  // b will not by multiplied by any constant in this impl.
+  // ==> *c=1
+  if (c!=NULL) *c=n_Init(1, r);
+  poly m=p_One(r);
+  p_ExpVectorDiff(m,p_Head(b, r),p, r);
+  //pSetm(m);
+#ifdef PDEBUG
+  p_Test(m, r);
+#endif
+  poly pp=nc_mm_Mult_pp(m,p,r);
+  assume(pp!=NULL);
+
+  p_Delete(&m, r);
+  number n=p_GetCoeff(pp, r);
+  number nn;
+  if (!n_IsMOne(n, r))
+  {
+    nn=n_InpNeg(n_Invers(n, r), r);
+    n =n_Mult(nn,p_GetCoeff(b, r), r);
+    n_Delete(&nn, r);
+    pp=p_Mult_nn(pp,n,r);
+    n_Delete(&n, r);
+  }
+  else
+  {
+    pp=p_Mult_nn(pp,p_GetCoeff(b, r),r);
+  }
+  b=p_Add_q(b,pp,r);
+}
+
+
+inline void nc_PolyPolyRedNew(poly &b, poly p, number *c, const ring r)
+  // reduces b with p, do not delete both
+{
+#ifdef PDEBUG
+  p_Test(b, r);
+  p_Test(p, r);
+#endif
+
+#if MYTEST
+  PrintS("nc_PolyPolyRedNew(");
+  p_Write0(b, r);
+  PrintS(", ");
+  p_Write0(p, r);
+  PrintS(", *c): ");
+#endif
+
+  // b will not by multiplied by any constant in this impl.
+  // ==> *c=1
+  if (c!=NULL) *c=n_Init(1, r);
+
+  poly pp = NULL;
+
+  // there is a problem when p is a square(=>0!)
+
+  while((b != NULL) && (pp == NULL))
+  {
+
+//    poly pLmB = p_Head(b, r);
+    poly m = p_One(r);
+    p_ExpVectorDiff(m, b, p, r);
+//    pDelete(&pLmB);
+  //pSetm(m);
+
+#ifdef PDEBUG
+    p_Test(m, r);
+    p_Test(b, r);
+#endif
+
+    pp = nc_mm_Mult_pp(m, p, r);
+
+#if MYTEST
+    PrintS("\n{b': ");
+    p_Write0(b, r);
+    PrintS(", m: ");
+    p_Write0(m, r);
+    PrintS(", pp: ");
+    p_Write0(pp, r);
+    PrintS(" }\n");
+#endif
+
+    p_Delete(&m, r); // one m for all tries!
+
+//    assume( pp != NULL );
+
+    if( pp == NULL )
+    {
+      b = p_LmDeleteAndNext(b, r);
+
+      if( !p_DivisibleBy(p, b, r) )
+        return;
+
+    }
+  }
+
+#if MYTEST
+  PrintS("{b': ");
+  p_Write0(b, r);
+  PrintS(", pp: ");
+  p_Write0(pp, r);
+  PrintS(" }\n");
+#endif
+
+
+  if(b == NULL) return;
+
+
+  assume(pp != NULL);
+
+  const number n = p_GetCoeff(pp, r); // no new copy
+
+  number nn;
+
+  if (!n_IsMOne(n, r)) // TODO: as above.
+  {
+    nn=n_InpNeg(n_Invers(n, r), r);
+    number t = n_Mult(nn, p_GetCoeff(b, r), r);
+    n_Delete(&nn, r);
+    pp=p_Mult_nn(pp, t, r);
+    n_Delete(&t, r);
+  }
+  else
+  {
+    pp=p_Mult_nn(pp, pGetCoeff(b), r);
+  }
+
+
+  b=p_Add_q(b,pp,r);
+
+}
+
+void nc_PolyPolyRed(poly &b, poly p, number *c, const ring r)
+{
+#if 0
+  nc_PolyPolyRedOld(b, p, c, r);
+#else
+  nc_PolyPolyRedNew(b, p, c, r);
+#endif
+}
+
+
+poly nc_mm_Bracket_nn(poly m1, poly m2, const ring r);
+
+/// returns [p,q], destroys p
+poly nc_p_Bracket_qq(poly p, const poly q, const ring r)
+{
+  assume(p != NULL && q!= NULL);
+
+  if (!rIsPluralRing(r)) return(NULL);
+  if (p_ComparePolys(p,q, r)) return(NULL);
+  /* Components !? */
+  poly Q=NULL;
+  number coef=NULL;
+  poly pres=NULL;
+  int UseBuckets=1;
+  if (((pLength(p)< MIN_LENGTH_BUCKET/2) && (pLength(q)< MIN_LENGTH_BUCKET/2))
+  || TEST_OPT_NOT_BUCKETS)
+    UseBuckets=0;
+
+
+  CPolynomialSummator sum(r, UseBuckets == 0);
+
+  while (p!=NULL)
+  {
+    Q=q;
+    while(Q!=NULL)
+    {
+      pres=nc_mm_Bracket_nn(p,Q, r); /* since no coeffs are taken into account there */
+      if (pres!=NULL)
+      {
+        coef = n_Mult(p_GetCoeff(p, r),p_GetCoeff(Q, r), r);
+        pres = p_Mult_nn(pres,coef,r);
+
+        sum += pres;
+        n_Delete(&coef, r);
+      }
+      pIter(Q);
+    }
+    p=p_LmDeleteAndNext(p, r);
+  }
+  return(sum);
+}
+
+/// returns [m1,m2] for two monoms, destroys nothing
+/// without coeffs
+poly nc_mm_Bracket_nn(poly m1, poly m2, const ring r)
+{
+  if (p_LmIsConstant(m1, r) || p_LmIsConstant(m1, r)) return(NULL);
+  if (p_LmCmp(m1,m2, r)==0) return(NULL);
+  int rN=r->N;
+  int *M1=(int *)omAlloc0((rN+1)*sizeof(int));
+  int *M2=(int *)omAlloc0((rN+1)*sizeof(int));
+  int *aPREFIX=(int *)omAlloc0((rN+1)*sizeof(int));
+  int *aSUFFIX=(int *)omAlloc0((rN+1)*sizeof(int));
+  p_GetExpV(m1,M1, r);
+  p_GetExpV(m2,M2, r);
+  poly res=NULL;
+  poly ares=NULL;
+  poly bres=NULL;
+  poly prefix=NULL;
+  poly suffix=NULL;
+  int nMin,nMax;
+  number nTmp=NULL;
+  int i,j,k;
+  for (i=1;i<=rN;i++)
+  {
+    if (M2[i]!=0)
+    {
+      ares=NULL;
+      for (j=1;j<=rN;j++)
+      {
+        if (M1[j]!=0)
+        {
+          bres=NULL;
+          /* compute [ x_j^M1[j],x_i^M2[i] ] */
+          if (i<j) {nMax=j;  nMin=i;} else {nMax=i;  nMin=j;}
+          if ( (i==j) || ((MATELEM(r->GetNC()->COM,nMin,nMax)!=NULL) && n_IsOne(p_GetCoeff(MATELEM(r->GetNC()->C,nMin,nMax), r), r) )) /* not (the same exp. or commuting exps)*/
+          { bres=NULL; }
+          else
+          {
+            if (i<j) { bres=gnc_uu_Mult_ww(j,M1[j],i,M2[i], r); }
+            else bres=gnc_uu_Mult_ww(i,M2[i],j,M1[j], r);
+            if (n_IsOne(p_GetCoeff(bres, r), r))
+            {
+              bres=p_LmDeleteAndNext(bres, r);
+            }
+            else
+            {
+              nTmp=n_Sub(p_GetCoeff(bres, r),n_Init(1, r), r);
+              p_SetCoeff(bres,nTmp, r); /* only lc ! */
+            }
+#ifdef PDEBUG
+            p_Test(bres, r);
+#endif
+            if (i>j)  bres=p_Neg(bres, r);
+          }
+          if (bres!=NULL)
+          {
+            /* now mult (prefix, bres, suffix) */
+            memcpy(aSUFFIX, M1,(rN+1)*sizeof(int));
+            memcpy(aPREFIX, M1,(rN+1)*sizeof(int));
+            for (k=1;k<=j;k++) aSUFFIX[k]=0;
+            for (k=j;k<=rN;k++) aPREFIX[k]=0;
+            aSUFFIX[0]=0;
+            aPREFIX[0]=0;
+            prefix=p_One(r);
+            suffix=p_One(r);
+            p_SetExpV(prefix,aPREFIX, r);
+            p_Setm(prefix, r);
+            p_SetExpV(suffix,aSUFFIX, r);
+            p_Setm(suffix, r);
+            if (!p_LmIsConstant(prefix, r)) bres = gnc_mm_Mult_p(prefix, bres, r);
+            if (!p_LmIsConstant(suffix, r)) bres = gnc_p_Mult_mm(bres, suffix, r);
+            ares=p_Add_q(ares, bres, r);
+            /* What to give free? */
+        /* Do we have to free aPREFIX/aSUFFIX? it seems so */
+            p_Delete(&prefix, r);
+            p_Delete(&suffix, r);
+          }
+        }
+      }
+      if (ares!=NULL)
+      {
+        /* now mult (prefix, bres, suffix) */
+        memcpy(aSUFFIX, M2,(rN+1)*sizeof(int));
+        memcpy(aPREFIX, M2,(rN+1)*sizeof(int));
+        for (k=1;k<=i;k++) aSUFFIX[k]=0;
+        for (k=i;k<=rN;k++) aPREFIX[k]=0;
+        aSUFFIX[0]=0;
+        aPREFIX[0]=0;
+        prefix=p_One(r);
+        suffix=p_One(r);
+        p_SetExpV(prefix,aPREFIX, r);
+        p_Setm(prefix, r);
+        p_SetExpV(suffix,aSUFFIX, r);
+        p_Setm(suffix, r);
+        bres=ares;
+        if (!p_LmIsConstant(prefix, r)) bres = gnc_mm_Mult_p(prefix, bres, r);
+        if (!p_LmIsConstant(suffix, r)) bres = gnc_p_Mult_mm(bres, suffix, r);
+        res=p_Add_q(res, bres, r);
+        p_Delete(&prefix, r);
+        p_Delete(&suffix, r);
+      }
+    }
+  }
+  freeT(M1, rN);
+  freeT(M2, rN);
+  freeT(aPREFIX, rN);
+  freeT(aSUFFIX, rN);
+#ifdef PDEBUG
+  p_Test(res, r);
+#endif
+   return(res);
+}
+/// returns matrix with the info on noncomm multiplication
+matrix nc_PrintMat(int a, int b, ring r, int metric)
+{
+
+  if ( (a==b) || !rIsPluralRing(r) ) return(NULL);
+  int i;
+  int j;
+  if (a>b) {j=b; i=a;}
+  else {j=a; i=b;}
+  /* i<j */
+  int rN=r->N;
+  int size=r->GetNC()->MTsize[UPMATELEM(i,j,rN)];
+  matrix M = r->GetNC()->MT[UPMATELEM(i,j,rN)];
+  /*  return(M); */
+/*
+  int sizeofres;
+  if (metric==0)
+  {
+    sizeofres=sizeof(int);
+  }
+  if (metric==1)
+  {
+    sizeofres=sizeof(number);
+  }
+*/
+  matrix res=mpNew(size,size);
+  int s;
+  int t;
+  int length;
+  long totdeg;
+  poly p;
+  for(s=1;s<=size;s++)
+  {
+    for(t=1;t<=size;t++)
+    {
+      p=MATELEM(M,s,t);
+      if (p==NULL)
+      {
+        MATELEM(res,s,t)=0;
+      }
+      else
+      {
+        length = pLength(p);
+        if (metric==0) /* length */
+        {
+          MATELEM(res,s,t)= p_ISet(length,r);
+        }
+        else if (metric==1) /* sum of deg divided by the length */
+        {
+          totdeg=0;
+          while (p!=NULL)
+          {
+            totdeg=totdeg+p_Deg(p,r);
+            pIter(p);
+          }
+          number ntd = n_Init(totdeg, r);
+          number nln = n_Init(length, r);
+          number nres= n_Div(ntd,nln, r);
+          n_Delete(&ntd, r);
+          n_Delete(&nln, r);
+          MATELEM(res,s,t)=p_NSet(nres,r);
+        }
+      }
+    }
+  }
+  return(res);
+}
+
+inline void nc_CleanUp(nc_struct* p)
+{
+  assume(p != NULL);
+  omFreeSize((ADDRESS)p,sizeof(nc_struct));
+}
+
+inline void nc_CleanUp(ring r)
+{
+  /* small CleanUp of r->GetNC() */
+  assume(r != NULL);
+  nc_CleanUp(r->GetNC());
+  r->GetNC() = NULL;
+}
+
+void nc_rKill(ring r)
+// kills the nc extension of ring r
+{
+  if( r->GetNC()->GetGlobalMultiplier() != NULL )
+  {
+    delete r->GetNC()->GetGlobalMultiplier();
+    r->GetNC()->GetGlobalMultiplier() = NULL;
+  }
+
+  if( r->GetNC()->GetFormulaPowerMultiplier() != NULL )
+  {
+    delete r->GetNC()->GetFormulaPowerMultiplier();
+    r->GetNC()->GetFormulaPowerMultiplier() = NULL;
+  }
+
+
+  int i,j;
+  int rN=r->N;
+  if ( rN > 1 )
+  {
+    for(i=1;i<rN;i++)
+    {
+      for(j=i+1;j<=rN;j++)
+      {
+        id_Delete((ideal *)&(r->GetNC()->MT[UPMATELEM(i,j,rN)]),r);
+      }
+    }
+    omFreeSize((ADDRESS)r->GetNC()->MT,rN*(rN-1)/2*sizeof(matrix));
+    omFreeSize((ADDRESS)r->GetNC()->MTsize,rN*(rN-1)/2*sizeof(int));
+    id_Delete((ideal *)&(r->GetNC()->COM),r);
+  }
+  id_Delete((ideal *)&(r->GetNC()->C),r);
+  id_Delete((ideal *)&(r->GetNC()->D),r);
+
+  if( rIsSCA(r) && (r->GetNC()->SCAQuotient() != NULL) )
+  {
+    id_Delete(&r->GetNC()->SCAQuotient(), r); // Custom SCA destructor!!!
+  }
+
+
+  nc_CleanUp(r);
+}
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+
+// deprecated:
+/* for use in getting the mult. matrix elements*/
+/* ring r must be a currRing! */
+/* for consistency, copies a poly from the comm. r->GetNC()->basering */
+/* to its image in NC ring */
+poly nc_p_CopyGet(poly a, const ring r)
+{
+#ifndef PDEBUG
+  p_Test(a, r);
+#endif
+
+//  if (r != currRing)
+//  {
+//#ifdef PDEBUF
+//    Werror("nc_p_CopyGet call not in currRing");
+//#endif
+//    return(NULL);
+//  }
+  return(p_Copy(a,r));
+}
+
+// deprecated:
+/* for use in defining the mult. matrix elements*/
+/* ring r must be a currRing! */
+/* for consistency, puts a polynomial from the NC ring */
+/* to its presentation in the comm. r->GetNC()->basering */
+poly nc_p_CopyPut(poly a, const ring r)
+{
+#ifndef PDEBUG
+  p_Test(a, r);
+#endif
+
+//  if (r != currRing)
+//  {
+//#ifdef PDEBUF
+//    Werror("nc_p_CopyGet call not in currRing");
+//#endif
+//    return(NULL);
+//  }
+
+  return(p_Copy(a,r));
+}
+
+/* returns TRUE if there were errors */
+/* checks whether product of vars from PolyVar defines */
+/* an admissible subalgebra of r */
+/* r is indeed currRing and assumed to be noncomm. */
+BOOLEAN nc_CheckSubalgebra(poly PolyVar, ring r)
+{
+//  ring save = currRing;
+//  int WeChangeRing = 0;
+//  if (currRing != r)
+//    rChangeCurrRing(r);
+//    WeChangeRing = 1;
+//  }
+  int rN=r->N;
+  int *ExpVar=(int*)omAlloc0((rN+1)*sizeof(int));
+  int *ExpTmp=(int*)omAlloc0((rN+1)*sizeof(int));
+  p_GetExpV(PolyVar, ExpVar, r);
+  int i; int j; int k;
+  poly test=NULL;
+  int OK=1;
+  for (i=1; i<rN; i++)
+  {
+    if (ExpVar[i]==0) /* i.e. not in PolyVar */
+    {
+      for (j=i+1; j<=rN; j++)
+      {
+        if (ExpVar[j]==0)
+        {
+          test = MATELEM(r->GetNC()->D,i,j);
+          while (test!=NULL)
+          {
+            p_GetExpV(test, ExpTmp, r);
+            OK=1;
+            for (k=1;k<=rN;k++)
+            {
+              if (ExpTmp[k]!=0)
+              {
+                if (ExpVar[k]!=0) OK=0;
+              }
+            }
+            if (!OK)
+            {
+//              if ( WeChangeRing )
+//                rChangeCurrRing(save);
+              return(TRUE);
+            }
+            pIter(test);
+          }
+        }
+      }
+    }
+  }
+  freeT(ExpVar,rN);
+  freeT(ExpTmp,rN);
+//  if ( WeChangeRing )
+//    rChangeCurrRing(save);
+  return(FALSE);
+}
+
+
+/* returns TRUE if there were errors */
+/* checks whether the current ordering */
+/* is admissible for r and D == r->GetNC()->D */
+/* to be executed in a currRing */
+BOOLEAN gnc_CheckOrdCondition(matrix D, ring r)
+{
+  /* analyze D: an upper triangular matrix of polys */
+  /* check the ordering condition for D */
+//  ring save = currRing;
+//  int WeChangeRing = 0;
+//  if (r != currRing)
+//  {
+//    rChangeCurrRing(r);
+//    WeChangeRing = 1;
+//  }
+  poly p,q;
+  int i,j;
+  int report = 0;
+  for(i=1; i<r->N; i++)
+  {
+    for(j=i+1; j<=r->N; j++)
+    {
+      p = nc_p_CopyGet(MATELEM(D,i,j),r);
+      if ( p != NULL)
+      {
+	 q = p_One(r);
+	 p_SetExp(q,i,1,r);
+	 p_SetExp(q,j,1,r);
+	 p_Setm(q,r);
+	 if (p_LmCmp(q,p,r) != 1) /* i.e. lm(p)==xy < lm(q)==D_ij  */
+	   {
+	      Werror("Bad ordering at %d,%d\n",i,j);
+#if 0 /*Singularg should not differ from Singular except in error case*/
+      p_Write(p,r);
+      p_Write(q,r);
+#endif
+	      report = 1;
+	   }
+	 p_Delete(&q,r);
+	 p_Delete(&p,r);
+	 p = NULL;
+      }
+    }
+  }
+//  if ( WeChangeRing )
+//    rChangeCurrRing(save);
+  return(report);
+}
+
+
+
+BOOLEAN gnc_InitMultiplication(ring r, bool bSetupQuotient = false); // just for a moment
+
+/// returns TRUE if there were errors
+/// analyze inputs, check them for consistency
+/// detects nc_type, DO NOT initialize multiplication but call for it at the end
+/// checks the ordering condition and evtl. NDC
+/// NOTE: all the data belong to the curr,
+/// we change r which may be the same ring, and must have the same representation!
+BOOLEAN nc_CallPlural(matrix CCC, matrix DDD,
+                      poly CCN, poly DDN,
+                      ring r,
+                      bool bSetupQuotient, bool bCopyInput, bool bBeQuiet,
+                      ring curr, bool dummy_ring /*=false*/)
+{
+  assume( r != NULL );
+  assume( curr != NULL );
+
+  if( !bSetupQuotient)
+    assume( (r->qideal == NULL) ); // The basering must NOT be a qring!??
+
+  assume( rSamePolyRep(r, curr) || bCopyInput ); // wrong assumption?
+
+
+  if( r->N == 1 ) // clearly commutative!!!
+  {
+    assume(
+           ( (CCC != NULL) && (MATCOLS(CCC) == 1) && (MATROWS(CCC) == 1) && (MATELEM(CCC,1,1) == NULL) ) ||
+           ( (CCN == NULL) )
+          );
+
+    assume(
+           ( (DDD != NULL) && (MATCOLS(DDD) == 1) && (MATROWS(DDD) == 1) && (MATELEM(DDD,1,1) == NULL) ) ||
+           ( (DDN == NULL) )
+          );
+    if(!dummy_ring)
+    {
+      WarnS("commutative ring with 1 variable");
+      return FALSE;
+    }
+  }
+
+  // there must be:
+  assume( (CCC != NULL) != (CCN != NULL) ); // exactly one data about coeffs (C).
+  assume( !((DDD != NULL) && (DDN != NULL)) ); // at most one data about tails (D).
+
+//  ring save = currRing;
+//  if( save != curr )
+//    rChangeCurrRing(curr);
+
+
+#if OUTPUT
+  if( CCC != NULL )
+  {
+    PrintS("nc_CallPlural(), Input data, CCC: \n");
+    iiWriteMatrix(CCC, "C", 2, curr, 4);
+  }
+  if( DDD != NULL )
+  {
+    PrintS("nc_CallPlural(), Input data, DDD: \n");
+    iiWriteMatrix(DDD, "D", 2, curr, 4);
+  }
+#endif
+
+
+#ifndef SING_NDEBUG
+  id_Test((ideal)CCC, curr);
+  id_Test((ideal)DDD, curr);
+  p_Test(CCN, curr);
+  p_Test(DDN, curr);
+#endif
+
+  if( (!bBeQuiet) && (r->GetNC() != NULL) )
+    WarnS("going to redefine the algebra structure");
+
+//  if( currRing != r )
+//    rChangeCurrRing(r);
+
+  matrix CC = NULL;
+  poly CN = NULL;
+  matrix C; bool bCnew = false;
+
+  matrix DD = NULL;
+  poly DN = NULL;
+  matrix D; bool bDnew = false;
+
+  number nN, pN, qN;
+
+  bool IsSkewConstant = false, tmpIsSkewConstant;
+  int i, j;
+
+  nc_type nctype = nc_undef;
+
+  //////////////////////////////////////////////////////////////////
+  // check the correctness of arguments, without any real chagnes!!!
+
+
+
+  // check C
+  if ((CCC != NULL) && ( (MATCOLS(CCC)==1) || MATROWS(CCC)==1 ) )
+  {
+    CN = MATELEM(CCC,1,1);
+  }
+  else
+  {
+    if ((CCC != NULL) && ( (MATCOLS(CCC)!=r->N) || (MATROWS(CCC)!=r->N) ))
+    {
+      Werror("Square %d x %d  matrix expected", r->N, r->N);
+
+//      if( currRing != save )
+//        rChangeCurrRing(save);
+      return TRUE;
+    }
+  }
+  if (( CCC != NULL) && (CC == NULL)) CC = CCC; // mp_Copy(CCC, ?); // bug!?
+  if (( CCN != NULL) && (CN == NULL)) CN = CCN;
+
+  // check D
+  if ((DDD != NULL) && ( (MATCOLS(DDD)==1) || MATROWS(DDD)==1 ) )
+  {
+    DN = MATELEM(DDD,1,1);
+  }
+  else
+  {
+    if ((DDD != NULL) && ( (MATCOLS(DDD)!=r->N) || (MATROWS(DDD)!=r->N) ))
+    {
+      Werror("Square %d x %d  matrix expected",r->N,r->N);
+
+//      if( currRing != save )
+//        rChangeCurrRing(save);
+      return TRUE;
+    }
+  }
+
+  if (( DDD != NULL) && (DD == NULL)) DD = DDD; // mp_Copy(DDD, ?); // ???
+  if (( DDN != NULL) && (DN == NULL)) DN = DDN;
+
+  // further checks and some analysis:
+  // all data in 'curr'!
+  if (CN != NULL)       /* create matrix C = CN * Id */
+  {
+    if (!p_IsConstant(CN,curr))
+    {
+      Werror("Incorrect input : non-constants are not allowed as coefficients (first argument)");
+      return TRUE;
+    }
+    assume(p_IsConstant(CN,curr));
+
+    nN = p_GetCoeff(CN, curr);
+    if (n_IsZero(nN, curr))
+    {
+      Werror("Incorrect input : zero coefficients are not allowed");
+
+//      if( currRing != save )
+//        rChangeCurrRing(save);
+      return TRUE;
+    }
+
+    if (n_IsOne(nN, curr))
+      nctype = nc_lie;
+    else
+      nctype = nc_general;
+
+    IsSkewConstant = true;
+
+    C = mpNew(r->N,r->N); // ring independent!
+    bCnew = true;
+
+    for(i=1; i<r->N; i++)
+      for(j=i+1; j<=r->N; j++)
+        MATELEM(C,i,j) = prCopyR_NoSort(CN, curr, r); // nc_p_CopyPut(CN, r); // copy CN from curr into r
+
+#ifndef SING_NDEBUG
+    id_Test((ideal)C, r);
+#endif
+
+  } else
+  if ( (CN == NULL) && (CC != NULL) ) /* copy matrix C */
+  {
+    /* analyze C */
+
+    pN = NULL; /* check the consistency later */
+
+    if( r->N > 1 )
+      if ( MATELEM(CC,1,2) != NULL )
+        pN = p_GetCoeff(MATELEM(CC,1,2), curr);
+
+    tmpIsSkewConstant = true;
+
+    for(i=1; i<r->N; i++)
+      for(j=i+1; j<=r->N; j++)
+      {
+        if (MATELEM(CC,i,j) == NULL)
+          qN = NULL;
+        else
+	{
+	  if (!p_IsConstant(MATELEM(CC,i,j),curr))
+          {
+            Werror("Incorrect input : non-constants are not allowed as coefficients (first argument at [%d, %d])", i, j);
+            return TRUE;
+          }
+	  assume(p_IsConstant(MATELEM(CC,i,j),curr));
+          qN = p_GetCoeff(MATELEM(CC,i,j),curr);
+	}
+
+
+        if ( qN == NULL )   /* check the consistency: Cij!=0 */
+        // find also illegal pN
+        {
+          Werror("Incorrect input : matrix of coefficients contains zeros in the upper triangle");
+
+//        if( currRing != save )
+//            rChangeCurrRing(save);
+          return TRUE;
+        }
+
+        if (!n_Equal(pN, qN, curr->cf)) tmpIsSkewConstant = false;
+      }
+
+    if( bCopyInput )
+    {
+      C = mp_Copy(CC, curr, r); // Copy C into r!!!???
+#ifndef SING_NDEBUG
+      id_Test((ideal)C, r);
+#endif
+      bCnew = true;
+    }
+    else
+      C = CC;
+
+    IsSkewConstant = tmpIsSkewConstant;
+
+    if ( tmpIsSkewConstant && n_IsOne(pN, curr) )
+      nctype = nc_lie;
+    else
+      nctype = nc_general;
+  }
+
+  /* initialition of the matrix D */
+  if ( DD == NULL ) /* we treat DN only (it could also be NULL) */
+  {
+    D = mpNew(r->N,r->N); bDnew = true;
+
+    if (DN  == NULL)
+    {
+      if ( (nctype == nc_lie) || (nctype == nc_undef) )
+        nctype = nc_comm; /* it was nc_skew earlier */
+      else /* nc_general, nc_skew */
+        nctype = nc_skew;
+    }
+    else /* DN  != NULL */
+      for(i=1; i<r->N; i++)
+        for(j=i+1; j<=r->N; j++)
+          MATELEM(D,i,j) = prCopyR_NoSort(DN, curr, r); // project DN into r->GetNC()->basering!
+#ifndef SING_NDEBUG
+  id_Test((ideal)D, r);
+#endif
+  }
+  else /* DD != NULL */
+  {
+    bool b = true; // DD == null ?
+
+    for(int i = 1; (i < r->N) && b; i++)
+    for(int j = i+1; (j <= r->N) && b; j++)
+      if (MATELEM(DD, i, j) != NULL)
+      {
+        b = false;
+        break;
+      }
+
+    if (b) // D == NULL!!!
+    {
+      if ( (nctype == nc_lie) || (nctype == nc_undef) )
+        nctype = nc_comm; /* it was nc_skew earlier */
+      else /* nc_general, nc_skew */
+        nctype = nc_skew;
+    }
+
+    if( bCopyInput )
+    {
+      D = mp_Copy(DD, curr, r); // Copy DD into r!!!
+#ifndef SING_NDEBUG
+      id_Test((ideal)D, r);
+#endif
+      bDnew = true;
+    }
+    else
+      D = DD;
+  }
+
+  assume( C != NULL );
+  assume( D != NULL );
+
+#if OUTPUT
+  PrintS("nc_CallPlural(), Computed data, C: \n");
+  iiWriteMatrix(C, "C", 2, r, 4);
+
+  PrintS("nc_CallPlural(), Computed data, D: \n");
+  iiWriteMatrix(D, "D", 2, r, 4);
+
+  Print("\nTemporary: type = %d, IsSkewConstant = %d\n", nctype, IsSkewConstant);
+#endif
+
+
+  // check the ordering condition for D (both matrix and poly cases):
+  if ( gnc_CheckOrdCondition(D, r) )
+  {
+    if( bCnew ) mp_Delete( &C, r );
+    if( bDnew ) mp_Delete( &D, r );
+
+    Werror("Matrix of polynomials violates the ordering condition");
+
+//    if( currRing != save )
+//      rChangeCurrRing(save);
+    return TRUE;
+  }
+
+  // okay now we are ready for this!!!
+
+  // create new non-commutative structure
+  nc_struct *nc_new = (nc_struct *)omAlloc0(sizeof(nc_struct));
+
+  ncRingType(nc_new, nctype);
+
+  nc_new->C = C; // if C and D were given by matrices at the beginning they are in r
+  nc_new->D = D; // otherwise they should be in r->GetNC()->basering(polynomial * Id_{N})
+
+  nc_new->IsSkewConstant = (IsSkewConstant?1:0);
+
+  // Setup new NC structure!!!
+  if (r->GetNC() != NULL)
+  {
+#ifndef SING_NDEBUG
+    WarnS("Changing the NC-structure of an existing NC-ring!!!");
+#endif
+    nc_rKill(r);
+  }
+
+  r->GetNC() = nc_new;
+
+  r->ext_ref=NULL;
+
+//  if( currRing != save )
+//    rChangeCurrRing(save);
+
+  return gnc_InitMultiplication(r, bSetupQuotient);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+bool nc_rCopy(ring res, const ring r, bool bSetupQuotient)
+{
+  if (nc_CallPlural(r->GetNC()->C, r->GetNC()->D, NULL, NULL, res, bSetupQuotient, true, true, r))
+  {
+    WarnS("Error occured while coping/setuping the NC structure!"); // No reaction!???
+    return true; // error
+  }
+
+  return false;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+BOOLEAN gnc_InitMultiplication(ring r, bool bSetupQuotient)
+{
+  /* returns TRUE if there were errors */
+  /* initialize the multiplication: */
+  /*  r->GetNC()->MTsize, r->GetNC()->MT, r->GetNC()->COM, */
+  /* and r->GetNC()->IsSkewConstant for the skew case */
+  if (rVar(r)==1)
+  {
+    ncRingType(r, nc_comm);
+    r->GetNC()->IsSkewConstant=1;
+    return FALSE;
+  }
+
+//  ring save = currRing;
+//  int WeChangeRing = 0;
+
+//  if (currRing!=r)
+//  {
+//    rChangeCurrRing(r);
+//    WeChangeRing = 1;
+//  }
+//  assume( (currRing == r)
+//       && (currRing->GetNC()!=NULL) );   // otherwise we cannot work with all these matrices!
+
+  int i,j;
+  r->GetNC()->MT = (matrix *)omAlloc0((r->N*(r->N-1))/2*sizeof(matrix));
+  r->GetNC()->MTsize = (int *)omAlloc0((r->N*(r->N-1))/2*sizeof(int));
+  id_Test((ideal)r->GetNC()->C, r);
+  matrix COM = mp_Copy(r->GetNC()->C, r);
+  poly p,q;
+  short DefMTsize=7;
+  int IsNonComm=0;
+//  bool tmpIsSkewConstant = false;
+
+  for(i=1; i<r->N; i++)
+  {
+    for(j=i+1; j<=r->N; j++)
+    {
+      if ( MATELEM(r->GetNC()->D,i,j) == NULL ) /* quasicommutative case */
+      {
+        /* 1x1 mult.matrix */
+        r->GetNC()->MTsize[UPMATELEM(i,j,r->N)] = 1;
+        r->GetNC()->MT[UPMATELEM(i,j,r->N)] = mpNew(1,1);
+      }
+      else /* pure noncommutative case */
+      {
+        /* TODO check the special multiplication properties */
+        IsNonComm = 1;
+        p_Delete(&(MATELEM(COM,i,j)),r);
+        //MATELEM(COM,i,j) = NULL; // done by p_Delete
+        r->GetNC()->MTsize[UPMATELEM(i,j,r->N)] = DefMTsize; /* default sizes */
+        r->GetNC()->MT[UPMATELEM(i,j,r->N)] = mpNew(DefMTsize, DefMTsize);
+      }
+      /* set MT[i,j,1,1] to c_i_j*x_i*x_j + D_i_j */
+      p = p_One(r);
+      if (MATELEM(r->GetNC()->C,i,j)!=NULL)
+        p_SetCoeff(p,n_Copy(pGetCoeff(MATELEM(r->GetNC()->C,i,j)),r),r);
+      p_SetExp(p,i,1,r);
+      p_SetExp(p,j,1,r);
+      p_Setm(p,r);
+      p_Test(MATELEM(r->GetNC()->D,i,j),r);
+      q =  nc_p_CopyGet(MATELEM(r->GetNC()->D,i,j),r);
+      p = p_Add_q(p,q,r);
+      MATELEM(r->GetNC()->MT[UPMATELEM(i,j,r->N)],1,1) = nc_p_CopyPut(p,r);
+      p_Delete(&p,r);
+      // p = NULL;// done by p_Delete
+    }
+  }
+  if (ncRingType(r)==nc_undef)
+  {
+    if (IsNonComm==1)
+    {
+      //      assume(pN!=NULL);
+      //      if ((tmpIsSkewConstant==1) && (nIsOne(pGetCoeff(pN)))) r->GetNC()->type=nc_lie;
+      //      else r->GetNC()->type=nc_general;
+    }
+    if (IsNonComm==0)
+    {
+      ncRingType(r, nc_skew); // TODO: check whether it is commutative
+      r->GetNC()->IsSkewConstant = 0; // true; //tmpIsSkewConstant; //  BUG???
+    } else
+       assume( FALSE );
+  }
+  r->GetNC()->COM=COM;
+
+  nc_p_ProcsSet(r, r->p_Procs);
+
+  if(bSetupQuotient) // Test me!!!
+    nc_SetupQuotient(r, NULL, false); // no copy!
+
+
+//  if (save != currRing)
+//    rChangeCurrRing(save);
+
+  return FALSE;
+}
+
+
+// set pProcs for r and global variable p_Procs as for general non-commutative algebras.
+static inline
+void gnc_p_ProcsSet(ring rGR, p_Procs_s* p_Procs)
+{
+  // "commutative"
+  p_Procs->p_Mult_mm  = rGR->p_Procs->p_Mult_mm  = gnc_p_Mult_mm;
+  p_Procs->pp_Mult_mm = rGR->p_Procs->pp_Mult_mm = gnc_pp_Mult_mm;
+  p_Procs->p_Minus_mm_Mult_qq = rGR->p_Procs->p_Minus_mm_Mult_qq = nc_p_Minus_mm_Mult_qq;
+
+  // non-commutaitve multiplication by monomial from the left
+  rGR->GetNC()->p_Procs.mm_Mult_p   = gnc_mm_Mult_p;
+  rGR->GetNC()->p_Procs.mm_Mult_pp  = gnc_mm_Mult_pp;
+
+#if 0
+  // Previous Plural's implementation...
+  rGR->GetNC()->p_Procs.SPoly       = gnc_CreateSpolyOld;
+  rGR->GetNC()->p_Procs.ReduceSPoly = gnc_ReduceSpolyOld;
+
+  rGR->GetNC()->p_Procs.BucketPolyRed  = gnc_kBucketPolyRedOld;
+  rGR->GetNC()->p_Procs.BucketPolyRed_Z= gnc_kBucketPolyRed_ZOld;
+#else
+  // A bit cleaned up and somewhat rewritten functions...
+  rGR->GetNC()->p_Procs.SPoly       = gnc_CreateSpolyNew;
+  rGR->GetNC()->p_Procs.ReduceSPoly = gnc_ReduceSpolyNew;
+
+  rGR->GetNC()->p_Procs.BucketPolyRed  = gnc_kBucketPolyRedNew;
+  rGR->GetNC()->p_Procs.BucketPolyRed_Z= gnc_kBucketPolyRed_ZNew;
+#endif
+
+  // warning: ISO C++ forbids casting between pointer-to-function and pointer-to-object?
+  if (rHasLocalOrMixedOrdering(rGR))
+    rGR->GetNC()->p_Procs.GB = cast_A_to_vptr(gnc_gr_mora);
+  else
+    rGR->GetNC()->p_Procs.GB = cast_A_to_vptr(gnc_gr_bba);
+
+///////////  rGR->GetNC()->p_Procs.GB          = gnc_gr_bba; // bba even for local case!
+// old ///    r->GetNC()->GB()            = gnc_gr_bba;
+//   rGR->GetNC()->p_Procs.GlobalGB    = gnc_gr_bba;
+//   rGR->GetNC()->p_Procs.LocalGB     = gnc_gr_mora;
+//  const ring save = currRing; if( save != r ) rChangeCurrRing(r);
+//  ideal res = gnc_gr_bba(F, Q, w, hilb, strat/*, r*/);
+//  if( save != r )     rChangeCurrRing(save);     return (res);
+
+
+#if 0
+    // Old Stuff
+    p_Procs->p_Mult_mm   = gnc_p_Mult_mm;
+    _p_procs->p_Mult_mm  = gnc_p_Mult_mm;
+
+    p_Procs->pp_Mult_mm  = gnc_pp_Mult_mm;
+    _p_procs->pp_Mult_mm = gnc_pp_Mult_mm;
+
+    p_Procs->p_Minus_mm_Mult_qq = NULL; // gnc_p_Minus_mm_Mult_qq_ign;
+    _p_procs->p_Minus_mm_Mult_qq= NULL; // gnc_p_Minus_mm_Mult_qq_ign;
+
+    r->GetNC()->mmMultP()       = gnc_mm_Mult_p;
+    r->GetNC()->mmMultPP()      = gnc_mm_Mult_pp;
+
+    r->GetNC()->SPoly()         = gnc_CreateSpoly;
+    r->GetNC()->ReduceSPoly()   = gnc_ReduceSpoly;
+
+#endif
+}
+
+
+// set pProcs table for rGR and global variable p_Procs
+void nc_p_ProcsSet(ring rGR, p_Procs_s* p_Procs)
+{
+  assume(rIsPluralRing(rGR));
+  assume(p_Procs!=NULL);
+
+  gnc_p_ProcsSet(rGR, p_Procs);
+
+  if(rIsSCA(rGR) && ncExtensions(SCAMASK) )
+  {
+    sca_p_ProcsSet(rGR, p_Procs);
+  }
+
+  if( ncExtensions(NOPLURALMASK) )
+    ncInitSpecialPairMultiplication(rGR);
+
+  if(!rIsSCA(rGR) && !ncExtensions(NOFORMULAMASK))
+    ncInitSpecialPowersMultiplication(rGR);
+
+}
+
+
+/// substitute the n-th variable by e in p
+/// destroy p
+/// e is not a constant
+poly nc_pSubst(poly p, int n, poly e, const ring r)
+{
+  int rN = r->N;
+  int *PRE = (int *)omAlloc0((rN+1)*sizeof(int));
+  int *SUF = (int *)omAlloc0((rN+1)*sizeof(int));
+  int i,pow;
+  number C;
+  poly suf,pre;
+  poly res = NULL;
+  poly out = NULL;
+  while ( p!= NULL )
+  {
+    C =  p_GetCoeff(p, r);
+    p_GetExpV(p, PRE, r); /* faster splitting? */
+    pow = PRE[n]; PRE[n]=0;
+    res = NULL;
+    if (pow!=0)
+    {
+      for (i=n+1; i<=rN; i++)
+      {
+	 SUF[i] = PRE[i];
+	 PRE[i] = 0;
+      }
+      res =  p_Power(p_Copy(e, r),pow, r);
+      /* multiply with prefix */
+      pre = p_One(r);
+      p_SetExpV(pre,PRE, r);
+      p_Setm(pre, r);
+      res = nc_mm_Mult_p(pre,res, r);
+      /* multiply with suffix */
+      suf = p_One(r);
+      p_SetExpV(suf,SUF, r);
+      p_Setm(suf, r);
+      res = p_Mult_mm(res,suf, r);
+      res = p_Mult_nn(res,C, r);
+      p_SetComp(res,PRE[0], r);
+    }
+    else /* pow==0 */
+    {
+      res = p_Head(p, r);
+    }
+    p   = p_LmDeleteAndNext(p, r);
+    out = p_Add_q(out,res, r);
+  }
+  freeT(PRE,rN);
+  freeT(SUF,rN);
+  return(out);
+}
+
+
+// creates a commutative nc extension; "converts" comm.ring to a Plural ring
+ring nc_rCreateNCcomm(ring r)
+{
+  if (rIsPluralRing(r)) return r;
+
+  ring rr = rCopy(r);
+
+  matrix C = mpNew(rr->N,rr->N); // ring-independent!?!
+  matrix D = mpNew(rr->N,rr->N);
+
+  for(int i=1; i<rr->N; i++)
+    for(int j=i+1; j<=rr->N; j++)
+      MATELEM(C,i,j) = p_One(rr);
+
+  if (nc_CallPlural(C, D, NULL, NULL, rr, false, true, false, rr, TRUE)) // TODO: what about quotient ideal?
+    WarnS("Error initializing multiplication!"); // No reaction!???
+
+  return rr;
+}
+
+  /* NOT USED ANYMORE: replaced by maFindPerm in ring.cc */
+  /* for use with embeddings: currRing is a sum of smaller rings */
+  /* and srcRing is one of such smaller rings */
+  /* shift defines the position of a subring in srcRing */
+  /* par_shift defines the position of a subfield in basefield of CurrRing */
+poly p_CopyEmbed(poly p, ring srcRing, int shift, int /*par_shift*/, ring dstRing)
+{
+  if (dstRing == srcRing)
+  {
+    return(p_Copy(p,dstRing));
+  }
+  nMapFunc nMap=n_SetMap(srcRing->cf, dstRing->cf);
+  poly q;
+  //  if ( nMap == nCopy)
+  //  {
+  //    q = prCopyR(p,srcRing);
+  //  }
+  //  else
+  {
+    int *perm = (int *)omAlloc0((rVar(srcRing)+1)*sizeof(int));
+    int *par_perm = (int *)omAlloc0((rPar(srcRing)+1)*sizeof(int));
+    //    int *par_perm = (int *)omAlloc0((rPar(srcRing)+1)*sizeof(int));
+    int i;
+    //    if (srcRing->P > 0)
+    //    {
+    //      for (i=0; i<srcRing->P; i++)
+    //  par_perm[i]=-i;
+    //    }
+    if ((shift<0) || (shift > rVar(srcRing))) // ???
+    {
+      Werror("bad shifts in p_CopyEmbed");
+      return(0);
+    }
+    for (i=1; i<= srcRing->N; i++)
+    {
+      perm[i] = shift+i;
+    }
+    q = p_PermPoly(p,perm,srcRing, dstRing, nMap,par_perm, rPar(srcRing));
+  }
+  return(q);
+}
+
+BOOLEAN rIsLikeOpposite(ring rBase, ring rCandidate)
+{
+  /* the same basefield */
+  int diagnose = TRUE;
+  nMapFunc nMap = n_SetMap(rCandidate->cf, rBase->cf); // reverse?
+
+//////  if (nMap != nCopy) diagnose = FALSE;
+  if (nMap == NULL) diagnose = FALSE;
+
+
+  /* same number of variables */
+  if (rBase->N != rCandidate->N) diagnose = FALSE;
+  /* nc and comm ring */
+  if ( rIsPluralRing(rBase) != rIsPluralRing(rCandidate) ) diagnose = FALSE;
+  /* both are qrings */
+  /* NO CHECK, since it is used in building opposite qring */
+  /*  if ( ((rBase->qideal != NULL) && (rCandidate->qideal == NULL)) */
+  /*       || ((rBase->qideal == NULL) && (rCandidate->qideal != NULL)) ) */
+  /*  diagnose = FALSE; */
+  /* TODO: varnames are e->E etc */
+  return diagnose;
+}
+
+
+
+
+/// opposes a vector p from Rop to currRing (dst!)
+poly pOppose(ring Rop, poly p, const ring dst)
+{
+  /* the simplest case:*/
+  if (  Rop == dst )  return(p_Copy(p, dst));
+  /* check Rop == rOpposite(currRing) */
+
+
+  if ( !rIsLikeOpposite(dst, Rop) )
+  {
+    WarnS("an opposite ring should be used");
+    return NULL;
+  }
+
+  nMapFunc nMap = n_SetMap(Rop->cf, dst->cf); // reverse?
+
+  /* nMapFunc nMap = nSetMap(Rop);*/
+  /* since we know that basefields coinside! */
+
+  // coinside???
+
+  int *perm=(int *)omAlloc0((Rop->N+1)*sizeof(int));
+  if (!p_IsConstantPoly(p, Rop))
+  {
+    /* we know perm exactly */
+    int i;
+    for(i=1; i<=Rop->N; i++)
+    {
+      perm[i] = Rop->N+1-i;
+    }
+  }
+  poly res = p_PermPoly(p, perm, Rop, dst, nMap);
+  omFreeSize((ADDRESS)perm,(Rop->N+1)*sizeof(int));
+
+  p_Test(res, dst);
+
+  return res;
+}
+
+/// opposes a module I from Rop to currRing(dst)
+ideal idOppose(ring Rop, ideal I, const ring dst)
+{
+  /* the simplest case:*/
+  if ( Rop == dst ) return id_Copy(I, dst);
+
+  /* check Rop == rOpposite(currRing) */
+  if (!rIsLikeOpposite(dst, Rop))
+  {
+    WarnS("an opposite ring should be used");
+    return NULL;
+  }
+  int i;
+  ideal idOp = idInit(I->ncols, I->rank);
+  for (i=0; i< (I->ncols)*(I->nrows); i++)
+  {
+    idOp->m[i] = pOppose(Rop,I->m[i], dst);
+  }
+  id_Test(idOp, dst);
+  return idOp;
+}
+
+
+bool nc_SetupQuotient(ring rGR, const ring rG, bool bCopy)
+{
+  if( rGR->qideal == NULL )
+    return false; // no quotient = no work! done!? What about factors of SCA?
+
+  bool ret = true;
+  // currently only super-commutative extension deals with factors.
+
+  if( ncExtensions(SCAMASK)  )
+  {
+    bool sca_ret = sca_SetupQuotient(rGR, rG, bCopy);
+
+    if(sca_ret) // yes it was dealt with!
+      ret = false;
+  }
+
+  if( bCopy )
+  {
+    assume(rIsPluralRing(rGR) == rIsPluralRing(rG));
+    assume((rGR->qideal==NULL) == (rG->qideal==NULL));
+    assume(rIsSCA(rGR) == rIsSCA(rG));
+    assume(ncRingType(rGR) == ncRingType(rG));
+  }
+
+  return ret;
+}
+
+
+
+// int Commutative_Context(ring r, leftv expression)
+//   /* returns 1 if expression consists */
+//   /*  of commutative elements */
+// {
+//   /* crucial: poly -> ideal, module, matrix  */
+// }
+
+// int Comm_Context_Poly(ring r, poly p)
+// {
+//   poly COMM=r->GetNC()->COMM;
+//   poly pp=pOne();
+//   memset(pp->exp,0,r->ExpL_Size*sizeof(long));
+//   while (p!=NULL)
+//   {
+//     for (i=0;i<=r->ExpL_Size;i++)
+//     {
+//       if ((p->exp[i]) && (pp->exp[i]))  return(FALSE);
+//       /* nonzero exponent of non-comm variable */
+//     }
+//     pIter(p);
+//   }
+//   return(TRUE);
+// }
+
+#endif
+
+
+
diff --git a/libpolys/polys/nc/sca.cc b/libpolys/polys/nc/sca.cc
new file mode 100644
index 0000000..c902a7b
--- /dev/null
+++ b/libpolys/polys/nc/sca.cc
@@ -0,0 +1,1592 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    sca.cc
+ *  Purpose: supercommutative kernel procedures
+ *  Author:  motsak (Oleksandr Motsak)
+ *  Created: 2006/12/18
+ *******************************************************************/
+
+// set it here if needed.
+#define OUTPUT 0
+#define MYTEST 0
+
+#if MYTEST
+#define OM_CHECK 4
+#define OM_TRACK 5
+#endif
+
+// #define PDEBUG 2
+
+
+
+#include <misc/auxiliary.h>
+
+#ifdef HAVE_PLURAL
+
+// for
+#define PLURAL_INTERNAL_DECLARATIONS
+
+#include <polys/nc/sca.h>
+#include <polys/nc/nc.h>
+#include <polys/nc/gb_hack.h>
+// #include <polys/gring.h>
+
+
+#include <coeffs/numbers.h>
+#include <polys/coeffrings.h>
+
+
+// #include <polys/febase.h>
+#include <misc/options.h>
+
+#include <polys/monomials/p_polys.h>
+
+// #include <polys/kutil.h>
+#include <polys/simpleideals.h>
+#include <misc/intvec.h>
+
+#include <polys/monomials/ring.h>
+#include <polys/kbuckets.h>
+// #include <polys/kstd1.h>
+#include <polys/sbuckets.h>
+
+#include <polys/prCopy.h>
+
+#include <polys/operations/p_Mult_q.h>
+#include <polys/templates/p_MemAdd.h>
+
+// #include <polys/kutil.h>
+// #include <polys/kstd1.h>
+
+#include <polys/weight.h>
+
+
+// poly functions defined in p_Procs :
+
+// return pPoly * pMonom; preserve pPoly and pMonom.
+poly sca_pp_Mult_mm(const poly pPoly, const poly pMonom, const ring rRing, poly &);
+
+// return pMonom * pPoly; preserve pPoly and pMonom.
+static poly sca_mm_Mult_pp(const poly pMonom, const poly pPoly, const ring rRing);
+
+// return pPoly * pMonom; preserve pMonom, destroy or reuse pPoly.
+poly sca_p_Mult_mm(poly pPoly, const poly pMonom, const ring rRing);
+
+// return pMonom * pPoly; preserve pMonom, destroy or reuse pPoly.
+static poly sca_mm_Mult_p(const poly pMonom, poly pPoly, const ring rRing);
+
+
+// compute the spolynomial of p1 and p2
+poly sca_SPoly(const poly p1, const poly p2, const ring r);
+poly sca_ReduceSpoly(const poly p1, poly p2, const ring r);
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Super Commutative Algebra extension by Oleksandr
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+// returns the sign of: lm(pMonomM) * lm(pMonomMM),
+// preserves input, may return +/-1, 0
+static inline int sca_Sign_mm_Mult_mm( const poly pMonomM, const poly pMonomMM, const ring rRing )
+{
+#ifdef PDEBUG
+    p_Test(pMonomM,  rRing);
+    p_Test(pMonomMM, rRing);
+#endif
+
+    const short iFirstAltVar = scaFirstAltVar(rRing);
+    const short iLastAltVar  = scaLastAltVar(rRing);
+
+    register unsigned int tpower = 0;
+    register unsigned int cpower = 0;
+
+    for( register short j = iLastAltVar; j >= iFirstAltVar; j-- )
+    {
+      const unsigned int iExpM  = p_GetExp(pMonomM,  j, rRing);
+      const unsigned int iExpMM = p_GetExp(pMonomMM, j, rRing);
+
+#ifdef PDEBUG
+      assume( iExpM <= 1);
+      assume( iExpMM <= 1);
+#endif
+
+      if( iExpMM != 0 ) // TODO: think about eliminating there if-s...
+      {
+        if( iExpM != 0 )
+        {
+          return 0; // lm(pMonomM) * lm(pMonomMM) == 0
+        }
+        tpower ^= cpower; // compute degree of (-1).
+      }
+      cpower ^= iExpM;
+    }
+
+#ifdef PDEBUG
+    assume(tpower <= 1);
+#endif
+
+    // 1 => -1  // degree is odd => negate coeff.
+    // 0 =>  1
+
+    return(1 - (tpower << 1) );
+}
+
+
+
+
+// returns and changes pMonomM: lt(pMonomM) = lt(pMonomM) * lt(pMonomMM),
+// preserves pMonomMM. may return NULL!
+// if result != NULL => next(result) = next(pMonomM), lt(result) = lt(pMonomM) * lt(pMonomMM)
+// if result == NULL => pMonomM MUST BE deleted manually!
+static inline poly sca_m_Mult_mm( poly pMonomM, const poly pMonomMM, const ring rRing )
+{
+#ifdef PDEBUG
+    p_Test(pMonomM,  rRing);
+    p_Test(pMonomMM, rRing);
+#endif
+
+    const unsigned int iFirstAltVar = scaFirstAltVar(rRing);
+    const unsigned int iLastAltVar = scaLastAltVar(rRing);
+
+    register unsigned int tpower = 0;
+    register unsigned int cpower = 0;
+
+    for( register unsigned int j = iLastAltVar; j >= iFirstAltVar; j-- )
+    {
+      const unsigned int iExpM  = p_GetExp(pMonomM,  j, rRing);
+      const unsigned int iExpMM = p_GetExp(pMonomMM, j, rRing);
+
+#ifdef PDEBUG
+      assume( iExpM <= 1);
+      assume( iExpMM <= 1);
+#endif
+
+      if( iExpMM != 0 )
+      {
+        if( iExpM != 0 ) // result is zero!
+        {
+          return NULL; // we do nothing with pMonomM in this case!
+        }
+
+        tpower ^= cpower; // compute degree of (-1).
+      }
+
+      cpower ^= iExpM;
+    }
+
+#ifdef PDEBUG
+    assume(tpower <= 1);
+#endif
+
+    p_ExpVectorAdd(pMonomM, pMonomMM, rRing); // "exponents" are additive!!!
+
+    number nCoeffM = p_GetCoeff(pMonomM, rRing); // no new copy! should be deleted!
+
+    if( (tpower) != 0 ) // degree is odd => negate coeff.
+      nCoeffM = n_InpNeg(nCoeffM, rRing); // negate nCoeff (will destroy the original number)
+
+    const number nCoeffMM = p_GetCoeff(pMonomMM, rRing); // no new copy!
+
+    number nCoeff = n_Mult(nCoeffM, nCoeffMM, rRing); // new number!
+
+    p_SetCoeff(pMonomM, nCoeff, rRing); // delete lc(pMonomM) and set lc(pMonomM) = nCoeff
+
+#ifdef PDEBUG
+    p_LmTest(pMonomM, rRing);
+#endif
+
+    return(pMonomM);
+}
+
+// returns and changes pMonomM: lt(pMonomM) = lt(pMonomMM) * lt(pMonomM),
+// preserves pMonomMM. may return NULL!
+// if result != NULL => next(result) = next(pMonomM), lt(result) = lt(pMonomMM) * lt(pMonomM)
+// if result == NULL => pMonomM MUST BE deleted manually!
+static inline poly sca_mm_Mult_m( const poly pMonomMM, poly pMonomM, const ring rRing )
+{
+#ifdef PDEBUG
+    p_Test(pMonomM,  rRing);
+    p_Test(pMonomMM, rRing);
+#endif
+
+    const unsigned int iFirstAltVar = scaFirstAltVar(rRing);
+    const unsigned int iLastAltVar = scaLastAltVar(rRing);
+
+    register unsigned int tpower = 0;
+    register unsigned int cpower = 0;
+
+    for( register unsigned int j = iLastAltVar; j >= iFirstAltVar; j-- )
+    {
+      const unsigned int iExpMM = p_GetExp(pMonomMM, j, rRing);
+      const unsigned int iExpM  = p_GetExp(pMonomM,  j, rRing);
+
+#ifdef PDEBUG
+      assume( iExpM <= 1);
+      assume( iExpMM <= 1);
+#endif
+
+      if( iExpM != 0 )
+      {
+        if( iExpMM != 0 ) // result is zero!
+        {
+          return NULL; // we do nothing with pMonomM in this case!
+        }
+
+        tpower ^= cpower; // compute degree of (-1).
+      }
+
+      cpower ^= iExpMM;
+    }
+
+#ifdef PDEBUG
+    assume(tpower <= 1);
+#endif
+
+    p_ExpVectorAdd(pMonomM, pMonomMM, rRing); // "exponents" are additive!!!
+
+    number nCoeffM = p_GetCoeff(pMonomM, rRing); // no new copy! should be deleted!
+
+    if( (tpower) != 0 ) // degree is odd => negate coeff.
+      nCoeffM = n_InpNeg(nCoeffM, rRing); // negate nCoeff (will destroy the original number), creates new number!
+
+    const number nCoeffMM = p_GetCoeff(pMonomMM, rRing); // no new copy!
+
+    number nCoeff = n_Mult(nCoeffM, nCoeffMM, rRing); // new number!
+
+    p_SetCoeff(pMonomM, nCoeff, rRing); // delete lc(pMonomM) and set lc(pMonomM) = nCoeff
+
+#ifdef PDEBUG
+    p_LmTest(pMonomM, rRing);
+#endif
+
+    return(pMonomM);
+}
+
+
+
+// returns: result = lt(pMonom1) * lt(pMonom2),
+// preserves pMonom1, pMonom2. may return NULL!
+// if result != NULL => next(result) = NULL, lt(result) = lt(pMonom1) * lt(pMonom2)
+static inline poly sca_mm_Mult_mm( poly pMonom1, const poly pMonom2, const ring rRing )
+{
+#ifdef PDEBUG
+    p_Test(pMonom1, rRing);
+    p_Test(pMonom2, rRing);
+#endif
+
+    const unsigned int iFirstAltVar = scaFirstAltVar(rRing);
+    const unsigned int iLastAltVar = scaLastAltVar(rRing);
+
+    register unsigned int tpower = 0;
+    register unsigned int cpower = 0;
+
+    for( register unsigned int j = iLastAltVar; j >= iFirstAltVar; j-- )
+    {
+      const unsigned int iExp1 = p_GetExp(pMonom1, j, rRing);
+      const unsigned int iExp2 = p_GetExp(pMonom2, j, rRing);
+
+#ifdef PDEBUG
+      assume( iExp1 <= 1);
+      assume( iExp2 <= 1);
+#endif
+
+      if( iExp2 != 0 )
+      {
+        if( iExp1 != 0 ) // result is zero!
+        {
+          return NULL;
+        }
+        tpower ^= cpower; // compute degree of (-1).
+      }
+      cpower ^= iExp1;
+    }
+
+#ifdef PDEBUG
+    assume(cpower <= 1);
+#endif
+
+    poly pResult;
+    p_AllocBin(pResult,rRing->PolyBin,rRing);
+
+    p_ExpVectorSum(pResult, pMonom1, pMonom2, rRing); // "exponents" are additive!!!
+
+    pNext(pResult) = NULL;
+
+    const number nCoeff1 = p_GetCoeff(pMonom1, rRing); // no new copy!
+    const number nCoeff2 = p_GetCoeff(pMonom2, rRing); // no new copy!
+
+    number nCoeff = n_Mult(nCoeff1, nCoeff2, rRing); // new number!
+
+    if( (tpower) != 0 ) // degree is odd => negate coeff.
+      nCoeff = n_InpNeg(nCoeff, rRing); // negate nCoeff (will destroy the original number)
+
+    p_SetCoeff0(pResult, nCoeff, rRing); // set lc(pResult) = nCoeff, no destruction!
+
+#ifdef PDEBUG
+    p_LmTest(pResult, rRing);
+#endif
+
+    return(pResult);
+}
+
+// returns: result =  x_i * lt(pMonom),
+// preserves pMonom. may return NULL!
+// if result != NULL => next(result) = NULL, lt(result) = x_i * lt(pMonom)
+static inline poly sca_xi_Mult_mm(short i, const poly pMonom, const ring rRing)
+{
+#ifdef PDEBUG
+    p_Test(pMonom, rRing);
+#endif
+
+    assume( i <= scaLastAltVar(rRing));
+    assume( scaFirstAltVar(rRing) <= i );
+
+    if( p_GetExp(pMonom, i, rRing) != 0 ) // => result is zero!
+      return NULL;
+
+    const short iFirstAltVar = scaFirstAltVar(rRing);
+
+    register unsigned int cpower = 0;
+
+    for( register short j = iFirstAltVar; j < i ; j++ )
+      cpower ^= p_GetExp(pMonom, j, rRing);
+
+#ifdef PDEBUG
+    assume(cpower <= 1);
+#endif
+
+    poly pResult = p_LmInit(pMonom, rRing);
+
+    p_SetExp(pResult, i, 1, rRing); // pResult*=X_i &&
+    p_Setm(pResult, rRing);         // addjust degree after previous step!
+
+    number nCoeff = n_Copy(p_GetCoeff(pMonom, rRing), rRing); // new number!
+
+    if( cpower != 0 ) // degree is odd => negate coeff.
+      nCoeff = n_InpNeg(nCoeff, rRing); // negate nCoeff (will destroy the original number)
+
+    p_SetCoeff0(pResult, nCoeff, rRing); // set lc(pResult) = nCoeff, no destruction!
+
+#ifdef PDEBUG
+    p_LmTest(pResult, rRing);
+#endif
+
+    return(pResult);
+}
+
+//-----------------------------------------------------------------------------------//
+
+// return poly = pPoly * pMonom; preserve pMonom, destroy or reuse pPoly.
+poly sca_p_Mult_mm(poly pPoly, const poly pMonom, const ring rRing)
+{
+  assume( rIsSCA(rRing) );
+
+#ifdef PDEBUG
+//  Print("sca_p_Mult_mm\n"); // !
+
+  p_Test(pPoly, rRing);
+  p_Test(pMonom, rRing);
+#endif
+
+  if( pPoly == NULL )
+    return NULL;
+
+  assume(pMonom !=NULL);
+  //if( pMonom == NULL )
+  //{
+  //  // pPoly != NULL =>
+  //  p_Delete( &pPoly, rRing );
+  //  return NULL;
+  //}
+
+  const int iComponentMonomM = p_GetComp(pMonom, rRing);
+
+  poly p = pPoly; poly* ppPrev = &pPoly;
+
+  loop
+  {
+#ifdef PDEBUG
+    p_Test(p, rRing);
+#endif
+    const int iComponent = p_GetComp(p, rRing);
+
+    if( iComponent!=0 )
+    {
+      if( iComponentMonomM!=0 ) // TODO: make global if on iComponentMonomM =?= 0
+      {
+        // REPORT_ERROR
+        Werror("sca_p_Mult_mm: exponent mismatch %d and %d\n", iComponent, iComponentMonomM);
+        // what should we do further?!?
+
+        p_Delete( &pPoly, rRing); // delete the result AND rest
+        return NULL;
+      }
+#ifdef PDEBUG
+      if(iComponentMonomM==0 )
+      {
+        dReportError("sca_p_Mult_mm: Multiplication in the left module from the right");
+      }
+#endif
+    }
+
+    // terms will be in the same order because of quasi-ordering!
+    poly v = sca_m_Mult_mm(p, pMonom, rRing);
+
+    if( v != NULL )
+    {
+      ppPrev = &pNext(p); // fixed!
+
+    // *p is changed if v != NULL ( p == v )
+      pIter(p);
+
+      if( p == NULL )
+        break;
+    }
+    else
+    { // Upps! Zero!!! we must kill this term!
+
+      //
+      p = p_LmDeleteAndNext(p, rRing);
+
+      *ppPrev = p;
+
+      if( p == NULL )
+        break;
+    }
+  }
+
+#ifdef PDEBUG
+  p_Test(pPoly,rRing);
+#endif
+
+  return(pPoly);
+}
+
+// return new poly = pPoly * pMonom; preserve pPoly and pMonom.
+poly sca_pp_Mult_mm(const poly pPoly, const poly pMonom, const ring rRing)
+{
+  assume( rIsSCA(rRing) );
+
+#ifdef PDEBUG
+//  Print("sca_pp_Mult_mm\n"); // !
+
+  p_Test(pPoly, rRing);
+  p_Test(pMonom, rRing);
+#endif
+
+  if (/*(*/  pPoly == NULL  /*)*/) /*|| ( pMonom == NULL )*/
+    return NULL;
+
+  const int iComponentMonomM = p_GetComp(pMonom, rRing);
+
+  poly pResult = NULL;
+  poly* ppPrev = &pResult;
+
+  for( poly p = pPoly; p!= NULL; pIter(p) )
+  {
+#ifdef PDEBUG
+    p_Test(p, rRing);
+#endif
+    const int iComponent = p_GetComp(p, rRing);
+
+    if( iComponent!=0 )
+    {
+      if( iComponentMonomM!=0 ) // TODO: make global if on iComponentMonomM =?= 0
+      {
+        // REPORT_ERROR
+        Werror("sca_pp_Mult_mm: exponent mismatch %d and %d\n", iComponent, iComponentMonomM);
+        // what should we do further?!?
+
+        p_Delete( &pResult, rRing); // delete the result
+        return NULL;
+      }
+
+#ifdef PDEBUG
+      if(iComponentMonomM==0 )
+      {
+        dReportError("sca_pp_Mult_mm: Multiplication in the left module from the right");
+      }
+#endif
+    }
+
+    // terms will be in the same order because of quasi-ordering!
+    poly v = sca_mm_Mult_mm(p, pMonom, rRing);
+
+    if( v != NULL )
+    {
+      *ppPrev = v;
+      ppPrev = &pNext(v);
+    }
+  }
+
+#ifdef PDEBUG
+  p_Test(pResult,rRing);
+#endif
+
+  return(pResult);
+}
+
+//-----------------------------------------------------------------------------------//
+
+// return x_i * pPoly; preserve pPoly.
+static inline poly sca_xi_Mult_pp(short i, const poly pPoly, const ring rRing)
+{
+  assume( rIsSCA(rRing) );
+
+#ifdef PDEBUG
+  p_Test(pPoly, rRing);
+#endif
+
+  assume(i <= scaLastAltVar(rRing));
+  assume(scaFirstAltVar(rRing) <= i);
+
+  if( pPoly == NULL )
+    return NULL;
+
+  poly pResult = NULL;
+  poly* ppPrev = &pResult;
+
+  for( poly p = pPoly; p!= NULL; pIter(p) )
+  {
+
+    // terms will be in the same order because of quasi-ordering!
+    poly v = sca_xi_Mult_mm(i, p, rRing);
+
+#ifdef PDEBUG
+    p_Test(v, rRing);
+#endif
+
+    if( v != NULL )
+    {
+      *ppPrev = v;
+      ppPrev = &pNext(*ppPrev);
+    }
+  }
+
+
+#ifdef PDEBUG
+  p_Test(pResult, rRing);
+#endif
+
+  return(pResult);
+}
+
+
+// return new poly = pMonom * pPoly; preserve pPoly and pMonom.
+static poly sca_mm_Mult_pp(const poly pMonom, const poly pPoly, const ring rRing)
+{
+  assume( rIsSCA(rRing) );
+
+#ifdef PDEBUG
+//  Print("sca_mm_Mult_pp\n"); // !
+
+  p_Test(pPoly, rRing);
+  p_Test(pMonom, rRing);
+#endif
+
+  if ((pPoly==NULL) || (pMonom==NULL)) return NULL;
+
+  assume( (pPoly != NULL) && (pMonom !=NULL));
+
+  const int iComponentMonomM = p_GetComp(pMonom, rRing);
+
+  poly pResult = NULL;
+  poly* ppPrev = &pResult;
+
+  for( poly p = pPoly; p!= NULL; pIter(p) )
+  {
+#ifdef PDEBUG
+    p_Test(p, rRing);
+#endif
+    const int iComponent = p_GetComp(p, rRing);
+
+    if( iComponentMonomM!=0 )
+    {
+      if( iComponent!=0 ) // TODO: make global if on iComponentMonomM =?= 0
+      {
+        // REPORT_ERROR
+        Werror("sca_mm_Mult_pp: exponent mismatch %d and %d\n", iComponent, iComponentMonomM);
+        // what should we do further?!?
+
+        p_Delete( &pResult, rRing); // delete the result
+        return NULL;
+      }
+#ifdef PDEBUG
+      if(iComponent==0 )
+      {
+        dReportError("sca_mm_Mult_pp: Multiplication in the left module from the right!");
+//        PrintS("mm = "); p_Write(pMonom, rRing);
+//        PrintS("pp = "); p_Write(pPoly, rRing);
+//        assume(iComponent!=0);
+      }
+#endif
+    }
+
+    // terms will be in the same order because of quasi-ordering!
+    poly v = sca_mm_Mult_mm(pMonom, p, rRing);
+
+    if( v != NULL )
+    {
+      *ppPrev = v;
+      ppPrev = &pNext(*ppPrev); // nice line ;-)
+    }
+  }
+
+#ifdef PDEBUG
+  p_Test(pResult,rRing);
+#endif
+
+  return(pResult);
+}
+
+
+// return poly = pMonom * pPoly; preserve pMonom, destroy or reuse pPoly.
+static poly sca_mm_Mult_p(const poly pMonom, poly pPoly, const ring rRing) // !!!!! the MOST used procedure !!!!!
+{
+  assume( rIsSCA(rRing) );
+
+#ifdef PDEBUG
+  p_Test(pPoly, rRing);
+  p_Test(pMonom, rRing);
+#endif
+
+  if( pPoly == NULL )
+    return NULL;
+
+  assume(pMonom!=NULL);
+  //if( pMonom == NULL )
+  //{
+  //  // pPoly != NULL =>
+  //  p_Delete( &pPoly, rRing );
+  //  return NULL;
+  //}
+
+  const int iComponentMonomM = p_GetComp(pMonom, rRing);
+
+  poly p = pPoly; poly* ppPrev = &pPoly;
+
+  loop
+  {
+#ifdef PDEBUG
+    if( !p_Test(p, rRing) )
+    {
+      PrintS("p is wrong!");
+      p_Write(p,rRing);
+    }
+#endif
+
+    const int iComponent = p_GetComp(p, rRing);
+
+    if( iComponentMonomM!=0 )
+    {
+      if( iComponent!=0 )
+      {
+        // REPORT_ERROR
+        Werror("sca_mm_Mult_p: exponent mismatch %d and %d\n", iComponent, iComponentMonomM);
+        // what should we do further?!?
+
+        p_Delete( &pPoly, rRing); // delete the result
+        return NULL;
+      }
+#ifdef PDEBUG
+      if(iComponent==0)
+      {
+        dReportError("sca_mm_Mult_p: Multiplication in the left module from the right!");
+//        PrintS("mm = "); p_Write(pMonom, rRing);
+//        PrintS("p = "); p_Write(pPoly, rRing);
+//        assume(iComponent!=0);
+      }
+#endif
+    }
+
+    // terms will be in the same order because of quasi-ordering!
+    poly v = sca_mm_Mult_m(pMonom, p, rRing);
+
+    if( v != NULL )
+    {
+      ppPrev = &pNext(p);
+
+    // *p is changed if v != NULL ( p == v )
+      pIter(p);
+
+      if( p == NULL )
+        break;
+    }
+    else
+    { // Upps! Zero!!! we must kill this term!
+      p = p_LmDeleteAndNext(p, rRing);
+
+      *ppPrev = p;
+
+      if( p == NULL )
+        break;
+    }
+  }
+
+#ifdef PDEBUG
+    if( !p_Test(pPoly, rRing) )
+    {
+      PrintS("pPoly is wrong!");
+      p_Write(pPoly, rRing);
+    }
+#endif
+
+  return(pPoly);
+}
+
+//-----------------------------------------------------------------------------------//
+
+#ifdef PDEBUG
+#endif
+
+
+
+
+//-----------------------------------------------------------------------------------//
+
+// GB computation routines:
+
+/*4
+* creates the S-polynomial of p1 and p2
+* does not destroy p1 and p2
+*/
+poly sca_SPoly( const poly p1, const poly p2, const ring r )
+{
+  assume( rIsSCA(r) );
+
+  const long lCompP1 = p_GetComp(p1,r);
+  const long lCompP2 = p_GetComp(p2,r);
+
+  if ((lCompP1!=lCompP2) && (lCompP1!=0) && (lCompP2!=0))
+  {
+#ifdef PDEBUG
+    dReportError("sca_SPoly: different non-zero components!\n");
+#endif
+    return(NULL);
+  }
+
+  poly pL = p_Lcm(p1, p2, si_max(lCompP1, lCompP2), r);       // pL = lcm( lm(p1), lm(p2) )
+
+  poly m1 = p_One( r);
+  p_ExpVectorDiff(m1, pL, p1, r);                  // m1 = pL / lm(p1)
+
+  //p_SetComp(m1,0,r);
+  //p_Setm(m1,r);
+#ifdef PDEBUG
+  p_Test(m1,r);
+#endif
+
+
+  poly m2 = p_One( r);
+  p_ExpVectorDiff (m2, pL, p2, r);                  // m2 = pL / lm(p2)
+
+  //p_SetComp(m2,0,r);
+  //p_Setm(m2,r);
+#ifdef PDEBUG
+  p_Test(m2,r);
+#endif
+
+  p_Delete(&pL,r);
+
+  number C1  = n_Copy(p_GetCoeff(p1,r),r);      // C1 = lc(p1)
+  number C2  = n_Copy(p_GetCoeff(p2,r),r);      // C2 = lc(p2)
+
+  number C = n_Gcd(C1,C2,r);                     // C = gcd(C1, C2)
+
+  if (!n_IsOne(C, r))                              // if C != 1
+  {
+    C1=n_Div(C1, C, r);                              // C1 = C1 / C
+    C2=n_Div(C2, C, r);                              // C2 = C2 / C
+  }
+
+  n_Delete(&C,r); // destroy the number C
+
+  const int iSignSum = sca_Sign_mm_Mult_mm (m1, p1, r) + sca_Sign_mm_Mult_mm (m2, p2, r);
+  // zero if different signs
+
+  assume( (iSignSum*iSignSum == 0) || (iSignSum*iSignSum == 4) );
+
+  if( iSignSum != 0 ) // the same sign!
+    C2=n_InpNeg (C2, r);
+
+  p_SetCoeff(m1, C2, r);                           // lc(m1) = C2!!!
+  p_SetCoeff(m2, C1, r);                           // lc(m2) = C1!!!
+
+  poly tmp1 = nc_mm_Mult_pp (m1, pNext(p1), r);    // tmp1 = m1 * tail(p1),
+  p_Delete(&m1,r);  //  => n_Delete(&C1,r);
+
+  poly tmp2 = nc_mm_Mult_pp (m2, pNext(p2), r);    // tmp1 = m2 * tail(p2),
+  p_Delete(&m2,r);  //  => n_Delete(&C1,r);
+
+  poly spoly = p_Add_q (tmp1, tmp2, r); // spoly = spoly(lt(p1), lt(p2)) + m1 * tail(p1), delete tmp1,2
+
+  if (spoly!=NULL) p_Cleardenom (spoly, r);
+//  if (spoly!=NULL) p_Content (spoly); // r?
+
+#ifdef PDEBUG
+  p_Test (spoly, r);
+#endif
+
+  return(spoly);
+}
+
+
+
+
+/*2
+* reduction of p2 with p1
+* do not destroy p1, but p2
+* p1 divides p2 -> for use in NF algorithm
+*/
+poly sca_ReduceSpoly(const poly p1, poly p2, const ring r)
+{
+  assume( rIsSCA(r) );
+
+  assume( p1 != NULL );
+
+  const long lCompP1 = p_GetComp (p1, r);
+  const long lCompP2 = p_GetComp (p2, r);
+
+  if ((lCompP1!=lCompP2) && (lCompP1!=0) && (lCompP2!=0))
+  {
+#ifdef PDEBUG
+    dReportError("sca_ReduceSpoly: different non-zero components!");
+#endif
+    return(NULL);
+  }
+
+  poly m = p_ISet (1, r);
+  p_ExpVectorDiff (m, p2, p1, r);                      // m = lm(p2) / lm(p1)
+  //p_Setm(m,r);
+#ifdef PDEBUG
+  p_Test (m,r);
+#endif
+
+  number C1 = n_Copy( p_GetCoeff(p1, r), r);
+  number C2 = n_Copy( p_GetCoeff(p2, r), r);
+
+  /* GCD stuff */
+  number C = n_Gcd(C1, C2, r);
+
+  if (!n_IsOne(C, r))
+  {
+    C1 = n_Div(C1, C, r);
+    C2 = n_Div(C2, C, r);
+  }
+  n_Delete(&C,r);
+
+  const int iSign = sca_Sign_mm_Mult_mm( m, p1, r );
+
+  if(iSign == 1)
+    C2 = n_InpNeg(C2,r);
+
+  p_SetCoeff(m, C2, r);
+
+#ifdef PDEBUG
+  p_Test(m,r);
+#endif
+
+  p2 = p_LmDeleteAndNext( p2, r );
+
+  p2 = p_Mult_nn(p2, C1, r); // p2 !!!
+  n_Delete(&C1,r);
+
+  poly T = nc_mm_Mult_pp(m, pNext(p1), r);
+  p_Delete(&m, r);
+
+  p2 = p_Add_q(p2, T, r);
+
+  if ( p2!=NULL ) p_Content(p2,r);
+
+#ifdef PDEBUG
+  p_Test(p2,r);
+#endif
+
+  return(p2);
+}
+
+// should be used only inside nc_SetupQuotient!
+// Check whether this our case:
+//  1. rG is  a commutative polynomial ring \otimes anticommutative algebra
+//  2. factor ideal rGR->qideal contains squares of all alternating variables.
+//
+// if yes, make rGR a super-commutative algebra!
+// NOTE: Factors of SuperCommutative Algebras are supported this way!
+//
+//  rG == NULL means that there is no separate base G-algebra in this case take rGR == rG
+
+// special case: bCopy == true (default value: false)
+// meaning: rGR copies structure from rG
+// (maybe with some minor changes, which don't change the type!)
+bool sca_SetupQuotient(ring rGR, ring rG, bool bCopy)
+{
+
+  //////////////////////////////////////////////////////////////////////////
+  // checks...
+  //////////////////////////////////////////////////////////////////////////
+  if( rG == NULL )
+    rG = rGR;
+
+  assume(rGR != NULL);
+  assume(rG  != NULL);
+  assume(rIsPluralRing(rG));
+
+#if ((defined(PDEBUG) && OUTPUT) || MYTEST)
+  PrintS("sca_SetupQuotient(rGR, rG, bCopy)");
+
+  {
+    PrintS("\nrG: \n"); rWrite(rG);
+    PrintS("\nrGR: \n"); rWrite(rGR);
+    PrintLn();
+  }
+#endif
+
+
+  if(bCopy)
+  {
+    if(rIsSCA(rG) && (rG != rGR))
+      return sca_Force(rGR, scaFirstAltVar(rG), scaLastAltVar(rG));
+    else
+      return false;
+  }
+
+  assume(!bCopy);
+
+  const int N = rG->N;
+
+  if(N < 2)
+    return false;
+
+
+//  if( (ncRingType(rG) != nc_skew) || (ncRingType(rG) != nc_comm) )
+//    return false;
+
+#if OUTPUT
+  PrintS("sca_SetupQuotient: qring?\n");
+#endif
+
+  if(rGR->qideal == NULL) // there should be a factor!
+    return false;
+
+#if OUTPUT
+  PrintS("sca_SetupQuotient: qideal!!!\n");
+#endif
+
+//  if((rG->qideal != NULL) && (rG != rGR) ) // we cannot change from factor to factor at the time, sorry!
+//    return false;
+
+
+  int iAltVarEnd = -1;
+  int iAltVarStart   = N+1;
+
+  const nc_struct* NC = rG->GetNC();
+  const ring rBase = rG; //NC->basering;
+  const matrix C   = NC->C; // live in rBase!
+  const matrix D   = NC->D; // live in rBase!
+
+#if OUTPUT
+  PrintS("sca_SetupQuotient: AltVars?!\n");
+#endif
+
+  for(int i = 1; i < N; i++)
+  {
+    for(int j = i + 1; j <= N; j++)
+    {
+      if( MATELEM(D,i,j) != NULL) // !!!???
+      {
+#if ((defined(PDEBUG) && OUTPUT) || MYTEST)
+        Print("Nonzero D[%d, %d]\n", i, j);
+#endif
+        return false;
+      }
+
+
+      assume(MATELEM(C,i,j) != NULL); // after CallPlural!
+      number c = p_GetCoeff(MATELEM(C,i,j), rBase);
+
+      if( n_IsMOne(c, rBase) ) // !!!???
+      {
+        if( i < iAltVarStart)
+          iAltVarStart = i;
+
+        if( j > iAltVarEnd)
+          iAltVarEnd = j;
+      } else
+      {
+        if( !n_IsOne(c, rBase) )
+        {
+#if ((defined(PDEBUG) && OUTPUT) || MYTEST)
+          Print("Wrong Coeff at: [%d, %d]\n", i, j);
+#endif
+          return false;
+        }
+      }
+    }
+  }
+
+#if ((defined(PDEBUG) && OUTPUT) || MYTEST)
+  Print("AltVars?1: [%d, %d]\n", iAltVarStart, iAltVarEnd);
+#endif
+
+
+  if( (iAltVarEnd == -1) || (iAltVarStart == (N+1)) )
+    return false; // either no alternating varables, or a single one => we are in commutative case!
+
+
+  for(int i = 1; i < N; i++)
+  {
+    for(int j = i + 1; j <= N; j++)
+    {
+      assume(MATELEM(C,i,j) != NULL); // after CallPlural!
+      number c = p_GetCoeff(MATELEM(C,i,j), rBase);
+
+      if( (iAltVarStart <= i) && (j <= iAltVarEnd) ) // S <= i < j <= E
+      { // anticommutative part
+        if( !n_IsMOne(c, rBase) )
+        {
+#if ((defined(PDEBUG) && OUTPUT) || MYTEST)
+          Print("Wrong Coeff at: [%d, %d]\n", i, j);
+#endif
+          return false;
+        }
+      } else
+      { // should commute
+        if( !n_IsOne(c, rBase) )
+        {
+#if ((defined(PDEBUG) && OUTPUT) || MYTEST)
+          Print("Wrong Coeff at: [%d, %d]\n", i, j);
+#endif
+          return false;
+        }
+      }
+    }
+  }
+
+#if ((defined(PDEBUG) && OUTPUT) || MYTEST)
+  Print("AltVars!?: [%d, %d]\n", iAltVarStart, iAltVarEnd);
+#endif
+
+  assume( 1            <= iAltVarStart );
+  assume( iAltVarStart < iAltVarEnd   );
+  assume( iAltVarEnd   <= N            );
+
+
+//  ring rSaveRing = assureCurrentRing(rG);
+
+
+  assume(rGR->qideal != NULL);
+  assume(rGR->N == rG->N);
+//  assume(rG->qideal == NULL); // ?
+
+  const ideal idQuotient = rGR->qideal;
+
+
+#if ((defined(PDEBUG) && OUTPUT) || MYTEST)
+  PrintS("Analyzing quotient ideal:\n");
+  idPrint(idQuotient); // in rG!!!
+#endif
+
+
+  // check for
+  // y_{iAltVarStart}^2, y_{iAltVarStart+1}^2, \ldots, y_{iAltVarEnd}^2  (iAltVarEnd > iAltVarStart)
+  // to be within quotient ideal.
+
+  bool bSCA = true;
+
+  int b = N+1;
+  int e = -1;
+
+  if(rIsSCA(rG))
+  {
+    b = si_min(b, scaFirstAltVar(rG));
+    e = si_max(e, scaLastAltVar(rG));
+
+#if ((defined(PDEBUG) && OUTPUT) || MYTEST)
+    Print("AltVars!?: [%d, %d]\n", b, e);
+#endif
+  }
+
+  for ( int i = iAltVarStart; (i <= iAltVarEnd) && bSCA; i++ )
+    if( (i < b) || (i > e) ) // otherwise it's ok since rG is an SCA!
+    {
+      poly square = p_One( rG);
+      p_SetExp(square, i, 2, rG); // square = var(i)^2.
+      p_Setm(square, rG);
+
+      // square = NF( var(i)^2 | Q )
+      // NOTE: there is no better way to check this in general!
+      square = kNF(idQuotient, NULL, square, 0, 1, rG); // must ran in currRing == rG!
+
+      if( square != NULL ) // var(i)^2 is not in Q?
+      {
+        p_Delete(&square, rG);
+        bSCA = false;
+        break;
+      }
+    }
+
+#if ((defined(PDEBUG) && OUTPUT) || MYTEST)
+  Print("ScaVars!: [%d, %d]\n", iAltVarStart, iAltVarEnd);
+#endif
+
+
+  //////////////////////////////////////////////////////////////////////////
+  // ok... here we go. let's setup it!!!
+  //////////////////////////////////////////////////////////////////////////
+  ideal tempQ = id_KillSquares(idQuotient, iAltVarStart, iAltVarEnd, rG); // in rG!!!
+
+
+#if ((defined(PDEBUG) && OUTPUT) || MYTEST)
+  PrintS("Quotient: \n");
+  iiWriteMatrix((matrix)idQuotient,"__",1, rG, 0);
+  PrintS("tempSCAQuotient: \n");
+  iiWriteMatrix((matrix)tempQ,"__",1, rG, 0);
+#endif
+
+  idSkipZeroes( tempQ );
+
+  ncRingType( rGR, nc_exterior );
+
+  scaFirstAltVar( rGR, iAltVarStart );
+  scaLastAltVar( rGR, iAltVarEnd );
+
+  if( idIs0(tempQ) )
+    rGR->GetNC()->SCAQuotient() = NULL;
+  else
+    rGR->GetNC()->SCAQuotient() = idrMoveR(tempQ, rG, rGR); // deletes tempQ!
+
+  nc_p_ProcsSet(rGR, rGR->p_Procs); // !!!!!!!!!!!!!!!!!
+
+
+#if ((defined(PDEBUG) && OUTPUT) || MYTEST)
+  PrintS("SCAQuotient: \n");
+  if(tempQ != NULL)
+    iiWriteMatrix((matrix)tempQ,"__",1, rGR, 0);
+  else
+    PrintS("(NULL)\n");
+#endif
+
+  return true;
+}
+
+
+bool sca_Force(ring rGR, int b, int e)
+{
+  assume(rGR != NULL);
+  assume(rIsPluralRing(rGR));
+  assume(!rIsSCA(rGR));
+
+  const int N = rGR->N;
+
+//  ring rSaveRing = currRing;
+//  if(rSaveRing != rGR)
+//    rChangeCurrRing(rGR);
+
+  const ideal idQuotient = rGR->qideal;
+
+  ideal tempQ = idQuotient;
+
+  if( b <= N && e >= 1 )
+    tempQ = id_KillSquares(idQuotient, b, e, rGR);
+
+  idSkipZeroes( tempQ );
+
+  ncRingType( rGR, nc_exterior );
+
+  if( idIs0(tempQ) )
+    rGR->GetNC()->SCAQuotient() = NULL;
+  else
+    rGR->GetNC()->SCAQuotient() = tempQ;
+
+
+  scaFirstAltVar( rGR, b );
+  scaLastAltVar( rGR, e );
+
+
+  nc_p_ProcsSet(rGR, rGR->p_Procs);
+
+//  if(rSaveRing != rGR)
+//    rChangeCurrRing(rSaveRing);
+
+  return true;
+}
+
+// return x_i * pPoly; preserve pPoly.
+poly sca_pp_Mult_xi_pp(short i, const poly pPoly, const ring rRing)
+{
+  assume(1 <= i);
+  assume(i <= rVar(rRing));
+
+  if(rIsSCA(rRing))
+    return sca_xi_Mult_pp(i, pPoly, rRing);
+
+
+
+  poly xi =  p_One( rRing);
+  p_SetExp(xi, i, 1, rRing);
+  p_Setm(xi, rRing);
+
+  poly pResult = pp_Mult_qq(xi, pPoly, rRing);
+
+  p_Delete( &xi, rRing);
+
+  return pResult;
+
+}
+
+void sca_p_ProcsSet(ring rGR, p_Procs_s* p_Procs)
+{
+
+  // "commutative" procedures:
+  rGR->p_Procs->p_Mult_mm     = sca_p_Mult_mm;
+  rGR->p_Procs->pp_Mult_mm    = sca_pp_Mult_mm;
+
+  p_Procs->p_Mult_mm          = sca_p_Mult_mm;
+  p_Procs->pp_Mult_mm         = sca_pp_Mult_mm;
+
+  // non-commutaitve
+  rGR->GetNC()->p_Procs.mm_Mult_p   = sca_mm_Mult_p;
+  rGR->GetNC()->p_Procs.mm_Mult_pp  = sca_mm_Mult_pp;
+
+//   rGR->GetNC()->p_Procs.SPoly         = sca_SPoly;
+//   rGR->GetNC()->p_Procs.ReduceSPoly   = sca_ReduceSpoly;
+
+#if 0
+
+        // Multiplication procedures:
+
+        p_Procs->p_Mult_mm   = sca_p_Mult_mm;
+        _p_procs->p_Mult_mm  = sca_p_Mult_mm;
+
+        p_Procs->pp_Mult_mm  = sca_pp_Mult_mm;
+        _p_procs->pp_Mult_mm = sca_pp_Mult_mm;
+
+        r->GetNC()->mmMultP()     = sca_mm_Mult_p;
+        r->GetNC()->mmMultPP()    = sca_mm_Mult_pp;
+
+/*
+        // ??????????????????????????????????????? coefficients swell...
+        r->GetNC()->SPoly()         = sca_SPoly;
+        r->GetNC()->ReduceSPoly()   = sca_ReduceSpoly;
+*/
+//         r->GetNC()->BucketPolyRed() = gnc_kBucketPolyRed;
+//         r->GetNC()->BucketPolyRed_Z()= gnc_kBucketPolyRed_Z;
+#endif
+
+  // local ordering => Mora, otherwise - Buchberger!
+  if (rHasLocalOrMixedOrdering(rGR))
+    rGR->GetNC()->p_Procs.GB          = cast_A_to_vptr(sca_mora);
+  else
+    rGR->GetNC()->p_Procs.GB          = cast_A_to_vptr(sca_bba); // sca_gr_bba?
+}
+
+
+// bi-Degree (x, y) of monomial "m"
+// x-es and y-s are weighted by wx and wy resp.
+// [optional] components have weights by wCx and wCy.
+static inline void m_GetBiDegree(const poly m,
+  const intvec *wx, const intvec *wy,
+  const intvec *wCx, const intvec *wCy,
+  int& dx, int& dy, const ring r)
+{
+  const unsigned int N  = r->N;
+
+  p_Test(m, r);
+
+  assume( wx != NULL );
+  assume( wy != NULL );
+
+  assume( wx->cols() == 1 );
+  assume( wy->cols() == 1 );
+
+  assume( (unsigned int)wx->rows() >= N );
+  assume( (unsigned int)wy->rows() >= N );
+
+  int x = 0;
+  int y = 0;
+
+  for(int i = N; i > 0; i--)
+  {
+    const int d = p_GetExp(m, i, r);
+    x += d * (*wx)[i-1];
+    y += d * (*wy)[i-1];
+  }
+
+  if( (wCx != NULL) && (wCy != NULL) )
+  {
+    const int c = p_GetComp(m, r);
+
+    if( wCx->range(c) )
+      x += (*wCx)[c];
+
+    if( wCy->range(c) )
+      x += (*wCy)[c];
+  }
+
+  dx = x;
+  dy = y;
+}
+
+// returns true if polynom p is bi-homogenous with respect to the given weights
+// simultaneously sets bi-Degree
+bool p_IsBiHomogeneous(const poly p,
+  const intvec *wx, const intvec *wy,
+  const intvec *wCx, const intvec *wCy,
+  int &dx, int &dy,
+  const ring r)
+{
+  if( p == NULL )
+  {
+    dx = 0;
+    dy = 0;
+    return true;
+  }
+
+  poly q = p;
+
+
+  int ddx, ddy;
+
+  m_GetBiDegree( q, wx, wy, wCx, wCy, ddx, ddy, r); // get bi degree of lm(p)
+
+  pIter(q);
+
+  for(; q != NULL; pIter(q) )
+  {
+    int x, y;
+
+    m_GetBiDegree( q, wx, wy, wCx, wCy, x, y, r); // get bi degree of q
+
+    if ( (x != ddx) || (y != ddy) ) return false;
+  }
+
+  dx = ddx;
+  dy = ddy;
+
+  return true;
+}
+
+
+// returns true if id is bi-homogenous without respect to the given weights
+bool id_IsBiHomogeneous(const ideal id,
+  const intvec *wx, const intvec *wy,
+  const intvec *wCx, const intvec *wCy,
+  const ring r)
+{
+  if (id == NULL) return true; // zero ideal
+
+  const int iSize = IDELEMS(id);
+
+  if (iSize == 0) return true;
+
+  bool b = true;
+  int x, y;
+
+  for(int i = iSize - 1; (i >= 0 ) && b; i--)
+    b = p_IsBiHomogeneous(id->m[i], wx, wy, wCx, wCy, x, y, r);
+
+  return b;
+}
+
+
+// returns an intvector with [nvars(r)] integers [1/0]
+// 1 - for commutative variables
+// 0 - for anticommutative variables
+intvec *ivGetSCAXVarWeights(const ring r)
+{
+  const unsigned int N  = r->N;
+
+  const int CommutativeVariable = 0; // bug correction!
+  const int AntiCommutativeVariable = 0;
+
+  intvec* w = new intvec(N, 1, CommutativeVariable);
+
+  if(AntiCommutativeVariable != CommutativeVariable)
+  if( rIsSCA(r) )
+  {
+    const unsigned int m_iFirstAltVar = scaFirstAltVar(r);
+    const unsigned int m_iLastAltVar  = scaLastAltVar(r);
+
+    for (unsigned int i = m_iFirstAltVar; i<= m_iLastAltVar; i++)
+    {
+      (*w)[i-1] = AntiCommutativeVariable;
+    }
+  }
+
+  return w;
+}
+
+
+// returns an intvector with [nvars(r)] integers [1/0]
+// 0 - for commutative variables
+// 1 - for anticommutative variables
+intvec *ivGetSCAYVarWeights(const ring r)
+{
+  const unsigned int N  = r->N;
+
+  const int CommutativeVariable = 0;
+  const int AntiCommutativeVariable = 1;
+
+  intvec* w = new intvec(N, 1, CommutativeVariable);
+
+  if(AntiCommutativeVariable != CommutativeVariable)
+  if( rIsSCA(r) )
+  {
+    const unsigned int m_iFirstAltVar = scaFirstAltVar(r);
+    const unsigned int m_iLastAltVar  = scaLastAltVar(r);
+
+    for (unsigned int i = m_iFirstAltVar; i<= m_iLastAltVar; i++)
+    {
+      (*w)[i-1] = AntiCommutativeVariable;
+    }
+  }
+  return w;
+}
+
+
+
+
+// reduce term lt(m) modulo <y_i^2> , i = iFirstAltVar .. iLastAltVar:
+// either create a copy of m or return NULL
+static inline poly m_KillSquares(const poly m,
+  const short iFirstAltVar, const short iLastAltVar,
+  const ring r)
+{
+#ifdef PDEBUG
+  p_Test(m, r);
+  assume( (iFirstAltVar >= 1) && (iLastAltVar <= rVar(r)) && (iFirstAltVar <= iLastAltVar) );
+
+#if 0
+  Print("m_KillSquares, m = "); // !
+  p_Write(m, r);
+#endif
+#endif
+
+  assume( m != NULL );
+
+  for(short k = iFirstAltVar; k <= iLastAltVar; k++)
+    if( p_GetExp(m, k, r) > 1 )
+      return NULL;
+
+  return p_Head(m, r);
+}
+
+
+// reduce polynomial p modulo <y_i^2> , i = iFirstAltVar .. iLastAltVar
+// returns a new poly!
+poly p_KillSquares(const poly p,
+  const short iFirstAltVar, const short iLastAltVar,
+  const ring r)
+{
+#ifdef PDEBUG
+  p_Test(p, r);
+
+  assume( (iFirstAltVar >= 1) && (iLastAltVar <= r->N) && (iFirstAltVar <= iLastAltVar) );
+
+#if 0
+  Print("p_KillSquares, p = "); // !
+  p_Write(p, r);
+#endif
+#endif
+
+
+  if( p == NULL )
+    return NULL;
+
+  poly pResult = NULL;
+  poly* ppPrev = &pResult;
+
+  for( poly q = p; q!= NULL; pIter(q) )
+  {
+#ifdef PDEBUG
+    p_Test(q, r);
+#endif
+
+    // terms will be in the same order because of quasi-ordering!
+    poly v = m_KillSquares(q, iFirstAltVar, iLastAltVar, r);
+
+    if( v != NULL )
+    {
+      *ppPrev = v;
+      ppPrev = &pNext(v);
+    }
+
+  }
+
+#ifdef PDEBUG
+  p_Test(pResult, r);
+#if 0
+  Print("p_KillSquares => "); // !
+  p_Write(pResult, r);
+#endif
+#endif
+
+  return(pResult);
+}
+
+
+
+
+// reduces ideal id modulo <y_i^2> , i = iFirstAltVar .. iLastAltVar
+// returns the reduced ideal or zero ideal.
+ideal id_KillSquares(const ideal id,
+  const short iFirstAltVar, const short iLastAltVar,
+  const ring r, const bool bSkipZeroes)
+{
+  if (id == NULL) return id; // zero ideal
+
+  assume( (iFirstAltVar >= 1) && (iLastAltVar <= rVar(r)) && (iFirstAltVar <= iLastAltVar) );
+
+  const int iSize = IDELEMS(id);
+
+  if (iSize == 0) return id;
+
+  ideal temp = idInit(iSize, id->rank);
+
+#if 0
+   PrintS("<id_KillSquares>\n");
+  {
+    PrintS("ideal id: \n");
+    for (unsigned int i = 0; i < IDELEMS(id); i++)
+    {
+      Print("; id[%d] = ", i+1);
+      p_Write(id->m[i], r);
+    }
+    PrintS(";\n");
+    PrintLn();
+  }
+#endif
+
+
+  for (int j = 0; j < iSize; j++)
+    temp->m[j] = p_KillSquares(id->m[j], iFirstAltVar, iLastAltVar, r);
+
+  if( bSkipZeroes )
+    idSkipZeroes(temp);
+
+#if 0
+   PrintS("<id_KillSquares>\n");
+  {
+    PrintS("ideal temp: \n");
+    for (int i = 0; i < IDELEMS(temp); i++)
+    {
+      Print("; temp[%d] = ", i+1);
+      p_Write(temp->m[i], r);
+    }
+    PrintS(";\n");
+    PrintLn();
+  }
+   PrintS("</id_KillSquares>\n");
+#endif
+
+//  temp->rank = idRankFreeModule(temp, r);
+
+  return temp;
+}
+
+
+
+
+#endif
diff --git a/libpolys/polys/nc/sca.h b/libpolys/polys/nc/sca.h
new file mode 100644
index 0000000..16e3f2e
--- /dev/null
+++ b/libpolys/polys/nc/sca.h
@@ -0,0 +1,183 @@
+#ifndef SCA_H
+#define SCA_H
+
+#ifdef HAVE_PLURAL
+
+#include <polys/nc/nc.h>
+#include <misc/intvec.h>
+
+// we must always have this test!
+inline ideal SCAQuotient(const ring r)
+{
+  assume(rIsSCA(r));
+  return r->GetNC()->SCAQuotient();
+}
+
+
+
+static inline short scaFirstAltVar(ring r)
+{
+  assume(rIsSCA(r));
+
+  return (r->GetNC()->FirstAltVar());
+}
+
+static inline short scaLastAltVar(ring r)
+{
+  assume(rIsSCA(r));
+
+  return (r->GetNC()->LastAltVar());
+}
+
+
+// The following inlines are just helpers for setup functions.
+static inline void scaFirstAltVar(ring r, short n)
+{
+  assume(rIsSCA(r));
+
+  r->GetNC()->FirstAltVar() = n;
+}
+
+static inline void scaLastAltVar(ring r, short n)
+{
+  assume(rIsSCA(r));
+
+  r->GetNC()->LastAltVar() = n;
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////////////////////
+// fast procedures for for SuperCommutative Algebras:
+///////////////////////////////////////////////////////////////////////////////////////////
+
+// this is not a basic operation... but it for efficiency we did it specially for SCA:
+// return x_i * pPoly; preserve pPoly.
+poly sca_pp_Mult_xi_pp(short i, const poly pPoly, const ring rRing);
+
+//////////////////////////////////////////////////////////////////////////////////////
+
+// TODO: correct the following descriptions...
+
+// tests whether p is bi-homogeneous with respect to the given variable'(component')-weights
+// ps: polynomial is bi-homogeneous iff all terms have the same bi-degree (x,y).
+bool p_IsBiHomogeneous(const poly p,
+  const intvec *wx, const intvec *wy,
+  const intvec *wCx, const intvec *wCy,
+  int &dx, int &dy,
+  const ring r);
+
+
+//////////////////////////////////////////////////////////////////////////////////////
+
+// tests whether p is bi-homogeneous with respect to the given variable'(component')-weights
+// ps: ideal is bi-homogeneous iff all its generators are bi-homogeneous polynomials.
+bool id_IsBiHomogeneous(const ideal id,
+  const intvec *wx, const intvec *wy,
+  const intvec *wCx, const intvec *wCy,
+  const ring r);
+
+
+//////////////////////////////////////////////////////////////////////////////////////
+
+// Scecial for SCA:
+
+// returns an intvector with [nvars(r)] integers [1/0]
+// 1 - for commutative variables
+// 0 - for anticommutative variables
+intvec *ivGetSCAXVarWeights(const ring r);
+
+// returns an intvector with [nvars(r)] integers [1/0]
+// 0 - for commutative variables
+// 1 - for anticommutative variables
+intvec *ivGetSCAYVarWeights(const ring r);
+
+
+static inline bool p_IsSCAHomogeneous(const poly p,
+  const intvec *wCx, const intvec *wCy,
+  const ring r)
+{
+  // inefficient! don't use it in time-critical code!
+  intvec *wx = ivGetSCAXVarWeights(r);
+  intvec *wy = ivGetSCAYVarWeights(r);
+
+  int x,y;
+
+  bool homog = p_IsBiHomogeneous( p, wx, wy, wCx, wCy, x, y, r );
+
+  delete wx;
+  delete wy;
+
+  return homog;
+}
+
+
+static inline bool id_IsSCAHomogeneous(const ideal id,
+  const intvec *wCx, const intvec *wCy,
+  const ring r)
+{
+  // inefficient! don't use it in time-critical code!
+  intvec *wx = ivGetSCAXVarWeights(r);
+  intvec *wy = ivGetSCAYVarWeights(r);
+
+  bool homog = id_IsBiHomogeneous( id, wx, wy, wCx, wCy, r );
+
+  delete wx;
+  delete wy;
+
+  return homog;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////////////
+
+// reduce polynomial p modulo <y_i^2> , i = iFirstAltVar .. iLastAltVar
+poly p_KillSquares(const poly p,
+  const short iFirstAltVar, const short iLastAltVar,
+  const ring r);
+
+//////////////////////////////////////////////////////////////////////////////////////
+
+// reduce ideal id modulo <y_i^2> , i = iFirstAltVar .. iLastAltVar
+// optional argument bSkipZeroes allow skipping of zero entries, by
+// default - no skipping!
+ideal id_KillSquares(const ideal id,
+  const short iFirstAltVar, const short iLastAltVar,
+  const ring r, const bool bSkipZeroes = false);
+
+// for benchmarking
+bool sca_Force(ring rGR, int b, int e);
+
+
+#ifdef PLURAL_INTERNAL_DECLARATIONS
+
+// set pProcs for r and the variable p_Procs
+// should be used by nc_p_ProcsSet in "gring.h"
+void sca_p_ProcsSet(ring rGR, p_Procs_s* p_Procs);
+
+// should be used only inside nc_SetupQuotient!
+// Check whether this our case:
+//  1. rG is  a commutative polynomial ring \otimes anticommutative algebra
+//  2. factor ideal rGR->qideal contains squares of all alternating variables.
+//
+// if yes, make rGR a super-commutative algebra!
+// NOTE: Factors of SuperCommutative Algebras are supported this way!
+//
+//  rG == NULL means that there is no separate base G-algebra in this
+//  case take rGR == rG
+
+// special case: bCopy == true (default value: false)
+// meaning: rGR copies structure from rG
+// (maybe with some minor changes, which don't change the type!)
+bool sca_SetupQuotient(ring rGR, ring rG, bool bCopy);
+
+#endif // PLURAL_INTERNAL_DECLARATIONS
+
+
+#else
+// these must not be used at all.
+// #define scaFirstAltVar(R) 0
+// #define scaLastAltVar(R) 0
+#endif // HAVE_PLURAL
+
+#endif // #ifndef SCA_H
diff --git a/libpolys/polys/nc/summator.cc b/libpolys/polys/nc/summator.cc
new file mode 100644
index 0000000..05155c8
--- /dev/null
+++ b/libpolys/polys/nc/summator.cc
@@ -0,0 +1,204 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    summator.cc
+ *  Purpose: simple Summator usecase implementation
+ *  Author:  motsak
+ *  Created:
+ *******************************************************************/
+
+
+#define MYTEST 0
+#define OUTPUT 0
+
+#if MYTEST
+#define OM_CHECK 4
+#define OM_TRACK 5
+#endif
+
+#include "summator.h"
+
+#include <misc/auxiliary.h>
+
+#ifdef HAVE_SUMMATOR
+
+
+
+
+#include <misc/options.h>
+
+#include <polys/monomials/ring.h>
+#include <polys/monomials/p_polys.h>
+#include <polys/sbuckets.h>
+
+
+
+CPolynomialSummator::CPolynomialSummator(const ring& rBaseRing, bool bUsePolynomial):
+    m_basering(rBaseRing), m_bUsePolynomial(bUsePolynomial)
+{
+#ifdef RDEBUG
+  rTest(rBaseRing);
+#endif
+
+  if(bUsePolynomial)
+    m_temp.m_poly = NULL;
+  else
+  {
+    assume(!TEST_OPT_NOT_BUCKETS);
+    m_temp.m_bucket = sBucketCreate(rBaseRing);
+  }
+}
+
+/*
+// no sBucketInit defined :(((
+CPolynomialSummator::CPolynomialSummator(ring rBaseRing, poly pInitialSum, int iLength, bool bUsePolynomial):
+    m_basering(rBaseRing), m_bUsePolynomial(bUsePolynomial)
+{
+#ifdef PDEBUG
+  p_Test(pInitialSum, rBaseRing);
+#endif
+
+  if(bUsePolynomial)
+  {
+    m_temp.m_poly = pInitialSum;
+  }
+  else
+  {
+    assume(!TEST_OPT_NOT_BUCKETS);
+    m_temp.m_bucket = sBucketInit(pInitialSum, iLength, rBaseRing);
+  }
+}
+*/
+
+CPolynomialSummator::~CPolynomialSummator()
+{
+  if(!m_bUsePolynomial)
+  {
+    poly out;
+    int pLength;
+
+    sBucketClearAdd(m_temp.m_bucket, &out, &pLength);
+    sBucketDestroy(&m_temp.m_bucket);
+
+    assume(out == NULL); // otherwise wrong usage pattern!
+    if(out != NULL)
+      p_Delete(&out, m_basering);
+//    m_temp.m_bucket = NULL;
+  }
+  else
+  {
+    assume(m_temp.m_poly == NULL); // otherwise wrong usage pattern!
+    if(m_temp.m_poly!=NULL)
+    {
+#ifdef PDEBUG
+      p_Test(m_temp.m_poly, m_basering);
+#endif
+      p_Delete(&m_temp.m_poly, m_basering);
+//      m_temp.m_poly = NULL;
+    }
+  }
+}
+
+void CPolynomialSummator::AddAndDelete(poly pSummand, int iLength)
+{
+#ifdef PDEBUG
+  p_Test(pSummand, m_basering);
+#endif
+
+  if(m_bUsePolynomial)
+    m_temp.m_poly = p_Add_q(m_temp.m_poly, pSummand, m_basering);
+  else
+    sBucket_Add_p(m_temp.m_bucket, pSummand, iLength); // sBucket_Merge_p???
+}
+
+void CPolynomialSummator::AddAndDelete(poly pSummand)
+{
+#ifdef PDEBUG
+  p_Test(pSummand, m_basering);
+#endif
+
+  if(m_bUsePolynomial)
+    m_temp.m_poly = p_Add_q(m_temp.m_poly, pSummand, m_basering);
+  else
+    sBucket_Add_p(m_temp.m_bucket, pSummand, 0); // sBucket_Merge_p???
+}
+
+poly CPolynomialSummator::AddUpAndClear()
+{
+  poly out = NULL;
+
+  if(m_bUsePolynomial)
+  {
+    out = m_temp.m_poly;
+    m_temp.m_poly = NULL;
+  }
+  else
+  {
+    int pLength;
+    sBucketClearAdd(m_temp.m_bucket, &out, &pLength);
+  }
+
+#ifdef PDEBUG
+  p_Test(out, m_basering);
+#endif
+
+  return out;
+}
+
+
+poly CPolynomialSummator::AddUpAndClear(int *piLength)
+{
+  poly out = NULL;
+
+  if(m_bUsePolynomial)
+  {
+    out = m_temp.m_poly;
+    m_temp.m_poly = NULL;
+    *piLength = pLength(out);
+  }
+  else
+  {
+    *piLength = 0;
+    sBucketClearAdd(m_temp.m_bucket, &out, piLength);
+  }
+
+#ifdef PDEBUG
+  p_Test(out, m_basering);
+  assume(pLength(out) == *piLength);
+#endif
+
+  return out;
+}
+
+
+
+void CPolynomialSummator::Add(poly pSummand, int iLength)
+{
+  AddAndDelete(p_Copy(pSummand, m_basering), iLength);
+}
+
+void CPolynomialSummator::Add(poly pSummand)
+{
+  AddAndDelete(p_Copy(pSummand, m_basering));
+}
+
+
+
+CPolynomialSummator::CPolynomialSummator(const CPolynomialSummator& b):
+    m_basering(b.m_basering), m_bUsePolynomial(b.m_bUsePolynomial)
+{
+//  try{
+    if(m_bUsePolynomial)
+      m_temp.m_poly = p_Copy( b.m_temp.m_poly, m_basering);
+    else
+      m_temp.m_bucket = sBucketCopy(b.m_temp.m_bucket);
+//  }
+//  catch(...)
+//  {
+//    assume(false);
+//  }
+}
+
+
+#endif // ifdef HAVE_SUMMATOR
diff --git a/libpolys/polys/nc/summator.h b/libpolys/polys/nc/summator.h
new file mode 100644
index 0000000..d6dfd5f
--- /dev/null
+++ b/libpolys/polys/nc/summator.h
@@ -0,0 +1,72 @@
+#ifndef SUMMATOR_H
+#define SUMMATOR_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+
+// #include <polys/nc/summator.h> // for CPolynomialSummator class
+
+#define HAVE_SUMMATOR 1
+
+#ifdef HAVE_SUMMATOR
+
+// struct snumber; typedef struct snumber *   number;
+
+class  sBucket; typedef sBucket* sBucket_pt;
+struct spolyrec; typedef struct spolyrec polyrec; typedef polyrec* poly;
+struct ip_sring; typedef struct ip_sring* ring; typedef struct ip_sring const* const_ring;
+
+
+class  kBucket; typedef kBucket* kBucket_pt;
+
+// TODO: redesign into templates with no extra run-time cost!!!
+// TODO: make several out of CPolynomialSummator with similar (?) usage
+// pattern/interface!!!
+
+// //////////////////////////////////////////////////////////////////////// //
+/// CPolynomialSummator: unifies bucket and polynomial summation as the
+/// later is brocken in buckets :(
+class CPolynomialSummator
+{
+  private:
+    const ring& m_basering;
+    const bool m_bUsePolynomial;
+    union
+    {
+      sBucket_pt m_bucket;
+//      kBucket_pt m_kbucket;
+      poly       m_poly;
+    } m_temp;
+  public:
+    CPolynomialSummator(const ring& rBaseRing, bool bUsePolynomial = false);
+//    CPolynomialSummator(ring rBaseRing, poly pInitialSum, int iLength = 0, bool bUsePolynomial = false);
+    ~CPolynomialSummator();
+
+    // adds and destroes the summand
+    void AddAndDelete(poly pSummand, int iLength);
+    void AddAndDelete(poly pSummand);
+
+    inline void operator +=(poly pSummand){ AddAndDelete(pSummand); }
+
+    // only adds and keeps the summand
+    // please use AddAndDelete instead!
+    void Add(poly pSummand, int iLength);
+    void Add(poly pSummand);
+
+    // get the final result and clear (set to zero) the summator
+    poly AddUpAndClear();
+    poly AddUpAndClear(int *piLength);
+
+    inline operator poly() { return AddUpAndClear(); }
+
+    /// Copy constructor
+    CPolynomialSummator(const CPolynomialSummator&);
+  private:
+
+    /// no assignment operator yet
+    CPolynomialSummator& operator= (const CPolynomialSummator&);
+};
+
+#endif // ifdef HAVE_SUMMATOR
+#endif // ifndef  SUMMATOR_H
+
diff --git a/libpolys/polys/operations/pShallowCopyDelete.cc b/libpolys/polys/operations/pShallowCopyDelete.cc
new file mode 100644
index 0000000..3cae58e
--- /dev/null
+++ b/libpolys/polys/operations/pShallowCopyDelete.cc
@@ -0,0 +1,53 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    pShallowCopyDelete.cc
+ *  Purpose: implementation of pShallowCopyDelete routines
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 8/00
+ *******************************************************************/
+
+#include <misc/auxiliary.h>
+
+#include "pShallowCopyDelete.h"
+
+// a simple implementations
+poly pShallowCopyDelete_General(poly s_p, ring s_r, ring d_r, omBin d_bin)
+{
+  p_CheckPolyRing(s_p, s_r);
+  p_CheckRing(d_r);
+  assume(d_bin != NULL);
+  assume(d_bin == d_r->PolyBin || omSizeWOfBin(d_bin) == omSizeWOfBin(d_r->PolyBin));
+  assume(s_r->N == d_r->N);
+
+  spolyrec dp;
+  poly d_p = &dp;
+  int N = d_r->N;
+  int i;
+
+
+  while (s_p != NULL)
+  {
+    d_p->next = p_Init(d_r, d_bin);
+    pIter(d_p);
+
+    pSetCoeff0(d_p, pGetCoeff(s_p));
+    for (i=1; i<= N; i++)
+      p_SetExp(d_p, i, p_GetExp(s_p, i, s_r), d_r);
+
+    if (rRing_has_Comp(d_r))
+      p_SetComp(d_p, p_GetComp(s_p, s_r), d_r);
+    p_Setm(d_p, d_r);
+
+    s_p = p_LmFreeAndNext(s_p, s_r);
+  }
+  pNext(d_p) = NULL;
+
+  return dp.next;
+}
+
+pShallowCopyDeleteProc pGetShallowCopyDeleteProc(ring /*source_r*/, ring /*dest_r*/)
+{
+  return pShallowCopyDelete_General;
+}
diff --git a/libpolys/polys/operations/pShallowCopyDelete.h b/libpolys/polys/operations/pShallowCopyDelete.h
new file mode 100644
index 0000000..127b3b3
--- /dev/null
+++ b/libpolys/polys/operations/pShallowCopyDelete.h
@@ -0,0 +1,18 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    pShallowCopyDelete.cc
+ *  Purpose: implementation of pShallowCopyDelete routines
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 8/00
+ *******************************************************************/
+#ifndef PSHALLOWCOPYDELETE_H
+#define PSHALLOWCOPYDELETE_H
+
+#include <polys/monomials/p_polys.h>
+#include <polys/monomials/ring.h>
+
+pShallowCopyDeleteProc pGetShallowCopyDeleteProc(ring source_r, ring dest_r);
+
+#endif // PSHALLOWCOPYDELETE_H
diff --git a/libpolys/polys/operations/p_Mult_q.cc b/libpolys/polys/operations/p_Mult_q.cc
new file mode 100644
index 0000000..4f468b7
--- /dev/null
+++ b/libpolys/polys/operations/p_Mult_q.cc
@@ -0,0 +1,302 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    p_Mult_q.cc
+ *  Purpose: multiplication of polynomials
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 8/00
+ *******************************************************************/
+
+#include <misc/auxiliary.h>
+#include <factory/factory.h>
+
+#include <misc/options.h>
+
+#include <polys/monomials/p_polys.h>
+#include <polys/kbuckets.h>
+
+#include <polys/templates/p_Procs.h>
+#include <polys/templates/p_MemCmp.h>
+#include <polys/templates/p_MemAdd.h>
+#include <polys/templates/p_MemCopy.h>
+
+#include "p_Mult_q.h"
+
+
+BOOLEAN pqLength(poly p, poly q, int &lp, int &lq, const int min)
+{
+  int l = 0;
+
+  do
+  {
+    if (p == NULL)
+    {
+      lp = l;
+      if (l < min)
+      {
+        if (q != NULL)
+          lq = l+1;
+        else
+          lq = l;
+        return FALSE;
+      }
+      lq = l + pLength(q);
+      return TRUE;
+    }
+    pIter(p);
+    if (q == NULL)
+    {
+      lq = l;
+      if (l < min)
+      {
+        lp = l+1;
+        return FALSE;
+      }
+      lp = l + 1 + pLength(p);
+      return TRUE;
+    }
+    pIter(q);
+    l++;
+  }
+  while (1);
+}
+
+
+static poly _p_Mult_q_Bucket(poly p, const int lp,
+                             poly q, const int lq,
+                             const int copy, const ring r)
+{
+  assume(p != NULL && pNext(p) != NULL && q != NULL && pNext(q) != NULL);
+  pAssume1(! pHaveCommonMonoms(p, q));
+#ifdef HAVE_RINGS
+  assume(!rField_is_Ring(r) || rField_is_Domain(r));
+#endif
+  assume(lp >= 1 && lq >= 1);
+  p_Test(p, r);
+  p_Test(q, r);
+
+  poly res = pp_Mult_mm(p,q,r);     // holds initially q1*p
+  poly qq = pNext(q);               // we iter of this
+  poly qn = pp_Mult_mm(qq, p,r);    // holds p1*qi
+  poly pp = pNext(p);               // used for Lm(qq)*pp
+  poly rr = res;                    // last monom which is surely not NULL
+  poly rn = pNext(res);             // pNext(rr)
+  number n, n1;
+
+  kBucket_pt bucket = kBucketCreate(r);
+
+  // initialize bucket
+  kBucketInit(bucket, pNext(rn), lp - 2);
+  pNext(rn) = NULL;
+
+  // now the main loop
+  Top:
+  if (rn == NULL) goto Smaller;
+  p_LmCmpAction(rn, qn, r, goto Equal, goto Greater, goto Smaller);
+
+  Greater:
+  // rn > qn, so iter
+  rr = rn;
+  pNext(rn) = kBucketExtractLm(bucket);
+  pIter(rn);
+  goto Top;
+
+  // rn < qn, append qn to rr, and compute next Lm(qq)*pp
+  Smaller:
+  pNext(rr) = qn;
+  rr = qn;
+  pIter(qn);
+  Work: // compute res + Lm(qq)*pp
+  if (rn == NULL)
+  {
+    pNext(rr) = pp_Mult_mm(pp, qq, r);
+    kBucketInit(bucket, pNext(pNext(rr)), lp - 2);
+    pNext(pNext(rr)) = NULL;
+  }
+  else
+  {
+    kBucketSetLm(bucket, rn);
+    kBucket_Plus_mm_Mult_pp(bucket, qq, pp, lp - 1);
+    pNext(rr) = kBucketExtractLm(bucket);
+  }
+
+  pIter(qq);
+  if (qq == NULL) goto Finish;
+  rn = pNext(rr);
+  goto Top;
+
+  Equal:
+  n1 = pGetCoeff(rn);
+  n = n_Add(n1, pGetCoeff(qn), r->cf);
+  n_Delete(&n1, r->cf);
+  if (n_IsZero(n, r->cf))
+  {
+    n_Delete(&n, r->cf);
+    p_LmFree(rn, r);
+  }
+  else
+  {
+    pSetCoeff0(rn, n);
+    rr = rn;
+  }
+  rn = kBucketExtractLm(bucket);
+  n_Delete(&pGetCoeff(qn),r->cf);
+  qn = p_LmFreeAndNext(qn, r);
+  goto Work;
+
+  Finish:
+  assume(rr != NULL && pNext(rr) != NULL);
+  pNext(pNext(rr)) = kBucketClear(bucket);
+  kBucketDestroy(&bucket);
+
+  if (!copy)
+  {
+    p_Delete(&p, r);
+    p_Delete(&q, r);
+  }
+  p_Test(res, r);
+  return res;
+}
+
+#ifdef HAVE_RINGS
+static poly _p_Mult_q_Normal_ZeroDiv(poly p, poly q, const int copy, const ring r)
+{
+  assume(p != NULL && pNext(p) != NULL && q != NULL && pNext(q) != NULL);
+  pAssume1(! pHaveCommonMonoms(p, q));
+  p_Test(p, r);
+  p_Test(q, r);
+
+  poly res = pp_Mult_mm(p,q,r);     // holds initially q1*p
+  poly qq = pNext(q);               // we iter of this
+
+  while (qq != NULL)
+  {
+    res = p_Plus_mm_Mult_qq(res, qq, p, r);
+    pIter(qq);
+  }
+
+  if (!copy)
+  {
+    p_Delete(&p, r);
+    p_Delete(&q, r);
+  }
+
+  p_Test(res, r);
+
+  return res;
+}
+#endif
+
+static poly _p_Mult_q_Normal(poly p, poly q, const int copy, const ring r)
+{
+  assume(r != NULL);
+  assume(p != NULL && pNext(p) != NULL && q != NULL && pNext(q) != NULL);
+#ifdef HAVE_RINGS
+  assume(nCoeff_is_Domain(r->cf));
+#endif
+  pAssume1(! p_HaveCommonMonoms(p, q, r));
+  p_Test(p, r);
+  p_Test(q, r);
+
+  poly res = pp_Mult_mm(p,q,r);     // holds initially q1*p
+  poly qq = pNext(q);               // we iter of this
+  poly qn = pp_Mult_mm(qq, p,r);    // holds p1*qi
+  poly pp = pNext(p);               // used for Lm(qq)*pp
+  poly rr = res;                    // last monom which is surely not NULL
+  poly rn = pNext(res);             // pNext(rr)
+  number n, n1;
+
+  // now the main loop
+  Top:
+  if (rn == NULL) goto Smaller;
+  p_LmCmpAction(rn, qn, r, goto Equal, goto Greater, goto Smaller);
+
+  Greater:
+  // rn > qn, so iter
+  rr = rn;
+  pIter(rn);
+  goto Top;
+
+  // rn < qn, append qn to rr, and compute next Lm(qq)*pp
+  Smaller:
+  pNext(rr) = qn;
+  rr = qn;
+  pIter(qn);
+
+  Work: // compute res + Lm(qq)*pp
+  if (rn == NULL)
+    pNext(rr) = pp_Mult_mm(pp, qq, r);
+  else
+  {
+    pNext(rr) = p_Plus_mm_Mult_qq(rn, qq, pp, r);
+  }
+
+  pIter(qq);
+  if (qq == NULL) goto Finish;
+  rn = pNext(rr);
+  goto Top;
+
+  Equal:
+  n1 = pGetCoeff(rn);
+  n = n_Add(n1, pGetCoeff(qn), r->cf);
+  n_Delete(&n1, r->cf);
+  if (n_IsZero(n, r->cf))
+  {
+    n_Delete(&n, r->cf);
+    rn = p_LmFreeAndNext(rn, r);
+  }
+  else
+  {
+    pSetCoeff0(rn, n);
+    rr = rn;
+    pIter(rn);
+  }
+  n_Delete(&pGetCoeff(qn),r->cf);
+  qn = p_LmFreeAndNext(qn, r);
+  goto Work;
+
+  Finish:
+  if (!copy)
+  {
+    p_Delete(&p, r);
+    p_Delete(&q, r);
+  }
+  p_Test(res, r);
+  return res;
+}
+
+
+/// Returns:  p * q,
+/// Destroys: if !copy then p, q
+/// Assumes: pLength(p) >= 2 pLength(q) >=2
+poly _p_Mult_q(poly p, poly q, const int copy, const ring r)
+{
+  assume(r != NULL);
+#ifdef HAVE_RINGS
+  if (!nCoeff_is_Domain(r->cf))
+    return _p_Mult_q_Normal_ZeroDiv(p, q, copy, r);
+#endif
+  int lp, lq, l;
+  poly pt;
+
+  pqLength(p, q, lp, lq, MIN_LENGTH_BUCKET);
+
+  if (lp < lq)
+  {
+    pt = p;
+    p =  q;
+    q = pt;
+    l = lp;
+    lp = lq;
+    lq = l;
+  }
+  if (lq < MIN_LENGTH_BUCKET || TEST_OPT_NOT_BUCKETS)
+    return _p_Mult_q_Normal(p, q, copy, r);
+  else
+  {
+    assume(lp == pLength(p));
+    assume(lq == pLength(q));
+    return _p_Mult_q_Bucket(p, lp, q, lq, copy, r);
+  }
+}
diff --git a/libpolys/polys/operations/p_Mult_q.h b/libpolys/polys/operations/p_Mult_q.h
new file mode 100644
index 0000000..b83945a
--- /dev/null
+++ b/libpolys/polys/operations/p_Mult_q.h
@@ -0,0 +1,32 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    p_Mult_q.h
+ *  Purpose: declaration of some auxillary routines for
+ *           p_Mult_q
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 8/00
+ *******************************************************************/
+
+#ifndef P_MULT_Q_H
+#define P_MULT_Q_H
+
+#include <misc/auxiliary.h>
+
+struct spolyrec; typedef struct spolyrec polyrec; typedef polyrec* poly;
+
+// Use buckets if min(pLength(p), pLength(q)) >= MIN_LENGTH_BUCKET
+// Not thoroughly tested what is best
+#ifndef MIN_LENGTH_BUCKET
+#define MIN_LENGTH_BUCKET 10
+#endif
+
+//  return TRUE and lp == pLength(p), lq == pLength(q),
+//              if min(pLength(p), pLength(q)) >= min
+//         FALSE if min(pLength(p), pLength(q)) < min
+//              and lp >= lq if pLength(p) >= pLength(lq)
+//                  lp < lq  if pLength(p) < pLength(q)
+BOOLEAN pqLength(poly p, poly q, int &lp, int &lq, const int min);
+
+#endif // P_MULT_Q_H
diff --git a/libpolys/polys/pDebug.cc b/libpolys/polys/pDebug.cc
new file mode 100644
index 0000000..a7418e7
--- /dev/null
+++ b/libpolys/polys/pDebug.cc
@@ -0,0 +1,422 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    pDebug.h
+ *  Purpose: implementation of debug related poly routines
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 8/00
+ *******************************************************************/
+
+#ifndef PDEBUG_CC
+#define PDEBUG_CC
+
+#include <stdarg.h>
+#include <stdio.h>
+
+
+
+
+
+#include <misc/auxiliary.h>
+
+
+#ifdef PDEBUG
+
+// do the following to always enforce checking of pSetm
+// #undef PDEBUG
+// #define PDEBUG 2
+
+#include <omalloc/omalloc.h>
+
+#include <polys/monomials/ring.h>
+#include <polys/monomials/p_polys.h>
+
+#include <coeffs/coeffs.h>
+
+/***************************************************************
+ *
+ * Error reporting
+ *
+ ***************************************************************/
+// avoid recursive calls
+static BOOLEAN d_poly_error_reporting = FALSE;
+BOOLEAN dPolyReportError(poly p, ring r, const char* fmt, ...)
+{
+  if (d_poly_error_reporting) return FALSE;
+  d_poly_error_reporting = TRUE;
+  va_list ap;
+  va_start(ap, fmt);
+
+  fprintf(stderr, "\n// ***dPolyReportError: ");
+  vfprintf(stderr, fmt, ap);
+  fprintf(stderr, "\n occured at\n");
+  omPrintCurrentBackTraceMax(stderr, 8);
+  if (p != NULL)
+  {
+    fprintf(stderr, " occured for poly: ");
+    p_wrp(p, r);
+    omPrintAddrInfo(stderr, p, " ");
+  }
+  dErrorBreak();
+  d_poly_error_reporting = FALSE;
+  return FALSE;
+}
+
+/***************************************************************
+ *
+ * checking for ring stuff
+ *
+ ***************************************************************/
+BOOLEAN p_LmCheckIsFromRing(poly p, ring r)
+{
+  if (p != NULL)
+  {
+    #if (OM_TRACK > 0) && defined(OM_TRACK_CUSTOM)
+    void* custom = omGetCustomOfAddr(p);
+    if (custom != NULL)
+    {
+      pPolyAssumeReturnMsg(custom == r ||
+                           // be more sloppy for qrings
+                           (r->qideal != NULL &&
+                            omIsBinPageAddr(p) &&
+                            omSizeWOfAddr(p)==omSizeWOfBin(r->PolyBin)) ||
+                           rSamePolyRep((ring) custom, r),
+                           "monomial not from specified ring",p,r);
+      return TRUE;
+    }
+    else
+    #endif
+    #ifndef X_OMALLOC
+    {
+      _pPolyAssumeReturn(omIsBinPageAddr(p) && omSizeWOfAddr(p)==omSizeWOfBin(r->PolyBin),p,r);
+      return TRUE;
+    }
+    return FALSE;
+    #endif
+  }
+  return TRUE;
+}
+
+BOOLEAN p_CheckIsFromRing(poly p, ring r)
+{
+  while (p!=NULL)
+  {
+    pFalseReturn(p_LmCheckIsFromRing(p, r));
+    pIter(p);
+  }
+  return TRUE;
+}
+
+BOOLEAN p_CheckPolyRing(poly p, ring r)
+{
+  #ifndef X_OMALLOC
+  pAssumeReturn(r != NULL && r->PolyBin != NULL);
+  #endif
+  return p_CheckIsFromRing(p, r);
+}
+
+BOOLEAN p_LmCheckPolyRing(poly p, ring r)
+{
+  #ifndef X_OMALLOC
+  pAssumeReturn(r != NULL && r->PolyBin != NULL);
+  #endif
+  pAssumeReturn(p != NULL);
+  return p_LmCheckIsFromRing(p, r);
+}
+BOOLEAN p_CheckRing(ring r)
+{
+  #ifndef X_OMALLOC
+  pAssumeReturn(r != NULL && r->PolyBin != NULL);
+  #endif
+  return TRUE;
+}
+
+/***************************************************************
+ *
+ * Debugging/statistics of pDivisibleBy
+ *
+ ***************************************************************/
+BOOLEAN p_DebugLmDivisibleByNoComp(poly a, poly b, ring r)
+{
+  int i=r->N;
+
+  do
+  {
+    if (p_GetExp(a,i,r) > p_GetExp(b,i,r))
+      return FALSE;
+    i--;
+  }
+  while (i);
+#ifdef HAVE_RINGS
+  return n_DivBy(pGetCoeff(b), pGetCoeff(a), r->cf);
+#else
+  return TRUE;
+#endif
+     }
+
+
+/***************************************************************
+ *
+ * Misc things helpful for debugging
+ *
+ ***************************************************************/
+BOOLEAN pIsMonomOf(poly p, poly m)
+{
+  if (m == NULL) return TRUE;
+  while (p != NULL)
+  {
+    if (p == m) return TRUE;
+    pIter(p);
+  }
+  return FALSE;
+}
+BOOLEAN pHaveCommonMonoms(poly p, poly q)
+{
+  while (p != NULL)
+  {
+    if (pIsMonomOf(q, p))
+    {
+      return TRUE;
+    }
+    pIter(p);
+  }
+  return FALSE;
+}
+
+/***************************************************************
+ *
+ * Testing of polys
+ *
+ ***************************************************************/
+extern void p_Setm_General(poly p, ring r);
+
+static poly p_DebugInit(poly p, ring src_ring, ring dest_ring)
+{
+  poly d_p = p_Init(dest_ring);
+  int i;
+  assume(dest_ring->N == src_ring->N);
+
+  for (i=1; i<= src_ring->N; i++)
+  {
+    p_SetExp(d_p, i, p_GetExp(p, i, src_ring), dest_ring);
+  }
+  if (rRing_has_Comp(dest_ring))
+    p_SetComp(d_p, p_GetComp(p, src_ring), dest_ring);
+
+  p_Setm_General(d_p, dest_ring);
+  return d_p;
+}
+
+BOOLEAN _p_Test(poly p, ring r, int level)
+{
+  assume(r->cf !=NULL);
+
+  if (PDEBUG > level) level = PDEBUG;
+  if (level < 0 || p == NULL) return TRUE;
+
+  poly p_prev = NULL;
+
+  #ifndef OM_NDEBUG
+  #ifndef X_OMALLOC
+  // check addr with level+1 so as to check bin/page of addr
+  _pPolyAssumeReturnMsg(omTestBinAddrSize(p, (omSizeWOfBin(r->PolyBin))*SIZEOF_LONG, level+1)
+                        == omError_NoError, "memory error",p,r);
+  #endif
+  #endif
+
+  pFalseReturn(p_CheckRing(r));
+
+  // this checks that p does not contain a loop: rather expensive O(length^2)
+  #ifndef OM_NDEBUG
+  if (level > 1)
+    pFalseReturn(omTestList(p, level) == omError_NoError);
+  #endif
+
+  int ismod = p_GetComp(p, r) != 0;
+
+  while (p != NULL)
+  {
+    // ring check
+    pFalseReturn(p_LmCheckIsFromRing(p, r));
+    #ifndef OM_NDEBUG
+    #ifndef X_OMALLOC
+    // omAddr check
+    _pPolyAssumeReturnMsg(omTestBinAddrSize(p, (omSizeWOfBin(r->PolyBin))*SIZEOF_LONG, 1)
+                     == omError_NoError, "memory error",p,r);
+    #endif
+    #endif
+    // number/coef check
+    _pPolyAssumeReturnMsg(p->coef != NULL || (n_GetChar(r->cf) >= 2), "NULL coef",p,r);
+
+    #ifdef LDEBUG
+    _pPolyAssumeReturnMsg(n_Test(p->coef,r->cf),"coeff err",p,r);
+    #endif
+    _pPolyAssumeReturnMsg(!n_IsZero(p->coef, r->cf), "Zero coef",p,r);
+
+    // check for valid comp
+    _pPolyAssumeReturnMsg(p_GetComp(p, r) >= 0 && (p_GetComp(p, r)<65000), "component out of range ?",p,r);
+    // check for mix poly/vec representation
+    _pPolyAssumeReturnMsg(ismod == (p_GetComp(p, r) != 0), "mixed poly/vector",p,r);
+
+    // special check for ringorder_s/S
+    if ((r->typ!=NULL) && (r->typ[0].ord_typ == ro_syzcomp))
+    {
+      long c1, cc1, ccc1, ec1;
+      sro_ord* o = &(r->typ[0]);
+
+      c1 = p_GetComp(p, r);
+      if (o->data.syzcomp.Components!=NULL)
+      {
+        cc1 = o->data.syzcomp.Components[c1];
+        ccc1 = o->data.syzcomp.ShiftedComponents[cc1];
+      }
+      else { cc1=0; ccc1=0; }
+      _pPolyAssumeReturnMsg(c1 == 0 || cc1 != 0, "Component <-> TrueComponent zero mismatch",p,r);
+      _pPolyAssumeReturnMsg(c1 == 0 || ccc1 != 0,"Component <-> ShiftedComponent zero mismatch",p,r);
+      ec1 = p->exp[o->data.syzcomp.place];
+      //pPolyAssumeReturnMsg(ec1 == ccc1, "Shifted comp out of sync. should %d, is %d");
+      if (ec1 != ccc1)
+      {
+        dPolyReportError(p,r,"Shifted comp out of sync. should %d, is %d",ccc1,ec1);
+        return FALSE;
+      }
+    }
+
+    // check that p_Setm works ok
+    if (level > 0)
+    {
+      poly p_should_equal = p_DebugInit(p, r, r);
+      _pPolyAssumeReturnMsg(p_ExpVectorEqual(p, p_should_equal, r), "p_Setm field(s) out of sync",p,r);
+      p_LmFree(p_should_equal, r);
+    }
+
+    // check order
+    if (p_prev != NULL)
+    {
+      int cmp = p_LmCmp(p_prev, p, r);
+      if (cmp == 0)
+      {
+        _pPolyAssumeReturnMsg(0, "monoms p and p->next are equal", p_prev, r);
+      }
+      else
+        _pPolyAssumeReturnMsg(p_LmCmp(p_prev, p, r) == 1, "wrong order", p_prev, r);
+
+      // check that compare worked sensibly
+      if (level > 1 && p_GetComp(p_prev, r) == p_GetComp(p, r))
+      {
+        int i;
+        for (i=r->N; i>0; i--)
+        {
+          if (p_GetExp(p_prev, i, r) != p_GetExp(p, i, r)) break;
+        }
+        _pPolyAssumeReturnMsg(i > 0, "Exponents equal but compare different", p_prev, r);
+      }
+    }
+    p_prev = p;
+    pIter(p);
+  }
+  return TRUE;
+}
+
+BOOLEAN _p_LmTest(poly p, ring r, int level)
+{
+  if (level < 0 || p == NULL) return TRUE;
+  poly pnext = pNext(p);
+  pNext(p) = NULL;
+  BOOLEAN test_res = _p_Test(p, r, level);
+  pNext(p) = pnext;
+  return test_res;
+}
+
+BOOLEAN _pp_Test(poly p, ring lmRing, ring tailRing, int level)
+{
+  if (PDEBUG > level) level = PDEBUG;
+  if (level < 0 || p == NULL) return TRUE;
+  if (pNext(p) == NULL || lmRing == tailRing) return _p_Test(p, lmRing, level);
+
+  pFalseReturn(_p_LmTest(p, lmRing, level));
+  pFalseReturn(_p_Test(pNext(p), tailRing, level));
+
+  // check that lm > Lm(tail)
+  if (level > 1)
+  {
+    poly lm = p;
+    poly tail = p_DebugInit(pNext(p), tailRing, lmRing);
+    poly pnext = pNext(lm);
+    pNext(lm) = tail;
+    BOOLEAN cmp = p_LmCmp(lm, tail, lmRing);
+    if (cmp != 1)
+      dPolyReportError(lm, lmRing, "wrong order: lm <= Lm(tail)");
+    p_LmFree(tail, lmRing);
+    pNext(lm) = pnext;
+    return (cmp == 1);
+  }
+  return TRUE;
+}
+
+#endif // PDEBUG
+
+#if defined(PDEBUG) || defined(PDIV_DEBUG)
+static unsigned long pDivisibleBy_number = 1;
+static unsigned long pDivisibleBy_FALSE = 1;
+static unsigned long pDivisibleBy_ShortFalse = 1;
+
+BOOLEAN pDebugLmShortDivisibleBy(poly p1, unsigned long sev_1, ring r_1,
+                               poly p2, unsigned long not_sev_2, ring r_2)
+{
+  _pPolyAssume(p_GetShortExpVector(p1, r_1) == sev_1, p1, r_1);
+  _pPolyAssume(p_GetShortExpVector(p2, r_2) == ~ not_sev_2, p2, r_2);
+
+  pDivisibleBy_number++;
+  BOOLEAN ret;
+  if (r_1 == r_2)
+    ret = p_LmDivisibleBy(p1, p2, r_1);
+  else
+    ret = p_LmDivisibleBy(p1, r_1, p2, r_2);
+
+  if (! ret) pDivisibleBy_FALSE++;
+  if (sev_1 & not_sev_2)
+  {
+    pDivisibleBy_ShortFalse++;
+    if (ret)
+      dReportError("p1 divides p2, but sev's are wrong");
+  }
+  return ret;
+}
+
+BOOLEAN pDebugLmShortDivisibleByNoComp(poly p1, unsigned long sev_1, ring r_1,
+                                       poly p2, unsigned long not_sev_2, ring r_2)
+{
+//  _pPolyAssume((p_GetComp(p1, r_1) == p_GetComp(p2, r_2)) || (p_GetComp(p1, r_1) == 0));
+  _pPolyAssume(p_GetShortExpVector(p1, r_1) == sev_1, p1, r_1);
+  _pPolyAssume(p_GetShortExpVector(p2, r_2) == ~ not_sev_2, p2, r_2);
+
+  pDivisibleBy_number++;
+  BOOLEAN ret;
+  if (r_1 == r_2)
+    ret = p_LmDivisibleByNoComp(p1, p2, r_1);
+  else
+    ret = p_LmDivisibleByNoComp(p1, r_1, p2, r_2);
+
+  if (! ret) pDivisibleBy_FALSE++;
+  if (sev_1 & not_sev_2)
+  {
+    pDivisibleBy_ShortFalse++;
+    if (ret)
+      dReportError("p1 divides p2, but sev's are wrong");
+  }
+  return ret;
+}
+
+void pPrintDivisbleByStat()
+{
+  Print("#Tests: %ld; #FALSE %ld(%ld); #SHORT %ld(%ld)\n",
+        pDivisibleBy_number,
+        pDivisibleBy_FALSE, (unsigned long) ((double)pDivisibleBy_FALSE*((double) 100)/(double)pDivisibleBy_number),
+        pDivisibleBy_ShortFalse, (unsigned long) ((double)pDivisibleBy_ShortFalse*((double)100)/(double)pDivisibleBy_FALSE));
+}
+
+#endif // PDEBUG
+
+#endif // PDEBUG_CC
diff --git a/libpolys/polys/polys0.cc b/libpolys/polys/polys0.cc
new file mode 100644
index 0000000..f112309
--- /dev/null
+++ b/libpolys/polys/polys0.cc
@@ -0,0 +1,252 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+
+/*
+* ABSTRACT - all basic methods to convert polynomials to strings
+*/
+
+/* includes */
+
+#include <misc/auxiliary.h>
+
+// #include <polys/structs.h>
+#include <coeffs/numbers.h>
+#include <polys/monomials/ring.h>
+#include <polys/monomials/p_polys.h>
+// #include <???/febase.h>
+
+/*2
+* writes a monomial (p),
+* uses form x*gen(.) if ko != coloumn number of p
+*/
+static void writemon(poly p, int ko, const ring r)
+{
+  assume(r != NULL);
+  const coeffs C = r->cf;
+  assume(C != NULL);
+
+  BOOLEAN wroteCoef=FALSE,writeGen=FALSE;
+  const BOOLEAN bNotShortOut = (rShortOut(r) == FALSE);
+
+  if (pGetCoeff(p)!=NULL)
+    n_Normalize(pGetCoeff(p),C);
+
+  if (((p_GetComp(p,r) == (short)ko)
+    &&(p_LmIsConstantComp(p, r)))
+  || ((!n_IsOne(pGetCoeff(p),C))
+    && (!n_IsMOne(pGetCoeff(p),C))
+  )
+  )
+  {
+    if( bNotShortOut )
+      n_WriteLong(pGetCoeff(p),C);
+    else
+      n_WriteShort(pGetCoeff(p),C);
+
+    wroteCoef=(bNotShortOut)
+    || (rParameter(r)!=NULL)
+    || rField_is_R(r) || (rField_is_long_R(r)) || (rField_is_long_C(r));
+    writeGen=TRUE;
+  }
+  else if (n_IsMOne(pGetCoeff(p),C))
+  {
+    if (n_GreaterZero(pGetCoeff(p),C))
+    {
+      if( bNotShortOut )
+        n_WriteLong(pGetCoeff(p),C);
+      else
+        n_WriteShort(pGetCoeff(p),C);
+
+      wroteCoef=(bNotShortOut)
+      || (rParameter(r)!=NULL)
+      || rField_is_R(r) || (rField_is_long_R(r)) || (rField_is_long_C(r));
+      writeGen=TRUE;
+    }
+    else
+      StringAppendS("-");
+  }
+
+  int i;
+  for (i=0; i<rVar(r); i++)
+  {
+    {
+      long ee = p_GetExp(p,i+1,r);
+      if (ee!=0L)
+      {
+        if (wroteCoef)
+          StringAppendS("*");
+        //else
+          wroteCoef=(bNotShortOut);
+        writeGen=TRUE;
+        StringAppendS(rRingVar(i, r));
+        if (ee != 1L)
+        {
+          if (bNotShortOut) StringAppendS("^");
+          StringAppend("%ld", ee);
+        }
+      }
+    }
+  }
+  //StringAppend("{%d}",p->Order);
+  if (p_GetComp(p, r) != (long)ko)
+  {
+    if (writeGen) StringAppendS("*");
+    StringAppend("gen(%d)", p_GetComp(p, r));
+  }
+}
+
+/// if possible print p in a short way...
+void p_String0Short(const poly p, ring lmRing, ring tailRing)
+{
+  // NOTE: the following (non-thread-safe!) UGLYNESS
+  // (changing naRing->ShortOut for a while) is due to Hans!
+  // Just think of other ring using the VERY SAME naRing and possible
+  // side-effects...
+  const BOOLEAN bLMShortOut = rShortOut(lmRing);
+  const BOOLEAN bTAILShortOut = rShortOut(tailRing);
+
+  lmRing->ShortOut = rCanShortOut(lmRing);
+  tailRing->ShortOut = rCanShortOut(tailRing);
+
+  p_String0(p, lmRing, tailRing);
+
+  lmRing->ShortOut = bLMShortOut;
+  tailRing->ShortOut = bTAILShortOut;
+}
+
+/// print p in a long way...
+void p_String0Long(const poly p, ring lmRing, ring tailRing)
+{
+  // NOTE: the following (non-thread-safe!) UGLYNESS
+  // (changing naRing->ShortOut for a while) is due to Hans!
+  // Just think of other ring using the VERY SAME naRing and possible
+  // side-effects...
+  const BOOLEAN bLMShortOut = rShortOut(lmRing);
+  const BOOLEAN bTAILShortOut = rShortOut(tailRing);
+
+  lmRing->ShortOut = FALSE;
+  tailRing->ShortOut = FALSE;
+
+  p_String0(p, lmRing, tailRing);
+
+  lmRing->ShortOut = bLMShortOut;
+  tailRing->ShortOut = bTAILShortOut;
+}
+
+
+void p_String0(poly p, ring lmRing, ring tailRing)
+{
+  if (p == NULL)
+  {
+    StringAppendS("0");
+    return;
+  }
+  if ((p_GetComp(p, lmRing) == 0) || (!lmRing->VectorOut))
+  {
+    writemon(p,0, lmRing);
+    p = pNext(p);
+    while (p!=NULL)
+    {
+      assume((p->coef==NULL)||(!n_IsZero(p->coef,tailRing->cf)));
+      if ((p->coef==NULL)||n_GreaterZero(p->coef,tailRing->cf))
+        StringAppendS("+");
+      writemon(p,0, tailRing);
+      p = pNext(p);
+    }
+    return;
+  }
+
+  long k = 1;
+  StringAppendS("[");
+  loop
+  {
+    while (k < p_GetComp(p,lmRing))
+    {
+      StringAppendS("0,");
+      k++;
+    }
+    writemon(p,k,lmRing);
+    pIter(p);
+    while ((p!=NULL) && (k == p_GetComp(p, tailRing)))
+    {
+      if (n_GreaterZero(p->coef,tailRing->cf)) StringAppendS("+");
+      writemon(p,k,tailRing);
+      pIter(p);
+    }
+    if (p == NULL) break;
+    StringAppendS(",");
+    k++;
+  }
+  StringAppendS("]");
+}
+
+char* p_String(poly p, ring lmRing, ring tailRing)
+{
+  StringSetS("");
+  p_String0(p, lmRing, tailRing);
+  return StringEndS();
+}
+
+/*2
+* writes a polynomial p to stdout
+*/
+void p_Write0(poly p, ring lmRing, ring tailRing)
+{
+  char *s=p_String(p, lmRing, tailRing);
+  PrintS(s);
+  omFree(s);
+}
+
+/*2
+* writes a polynomial p to stdout followed by \n
+*/
+void p_Write(poly p, ring lmRing, ring tailRing)
+{
+  p_Write0(p, lmRing, tailRing);
+  PrintLn();
+}
+
+#if !defined(__OPTIMIZE__) || defined(KDEBUG)
+/*2
+*the standard debugging output:
+*print the first two monomials of the poly (wrp) or only the lead term (wrp0),
+*possibly followed by the string "+..."
+*/
+void p_wrp0(poly p, ring ri)
+{
+  poly r;
+
+  if (p==NULL) PrintS("NULL");
+  else if (pNext(p)==NULL) p_Write0(p, ri);
+  else
+  {
+    r = pNext(p);
+    pNext(p) = NULL;
+    p_Write0(p, ri);
+    if (r!=NULL)
+    {
+      PrintS("+...");
+      pNext(p) = r;
+    }
+  }
+}
+#endif
+void p_wrp(poly p, ring lmRing, ring tailRing)
+{
+  poly r;
+
+  if (p==NULL) PrintS("NULL");
+  else if (pNext(p)==NULL) p_Write0(p, lmRing);
+  else
+  {
+    r = pNext(pNext(p));
+    pNext(pNext(p)) = NULL;
+    p_Write0(p, lmRing, tailRing);
+    if (r!=NULL)
+    {
+      PrintS("+...");
+      pNext(pNext(p)) = r;
+    }
+  }
+}
diff --git a/libpolys/polys/prCopy.cc b/libpolys/polys/prCopy.cc
new file mode 100644
index 0000000..4632fc9
--- /dev/null
+++ b/libpolys/polys/prCopy.cc
@@ -0,0 +1,274 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT - implementation of functions for Copy/Move/Delete for Polys
+*/
+
+
+#include <misc/auxiliary.h>
+
+#include <omalloc/omalloc.h>
+#include <polys/monomials/ring.h>
+#include <polys/monomials/p_polys.h>
+#include <coeffs/numbers.h>
+#include <polys/monomials/ring.h>
+#include <polys/simpleideals.h>
+// #include <polys/sbuckets.h>
+
+static inline void
+prCopyEvector(poly dest, ring dest_r, poly src, ring src_r,int max)
+{
+  //memset(dest->exp,0,dest_r->ExpL_Size*sizeof(long));
+  int i;
+  for (i=max; i>0; i--)
+  {
+    p_SetExp(dest, i, p_GetExp( src, i,src_r), dest_r);
+  }
+  if (rRing_has_Comp(dest_r) && rRing_has_Comp(src_r))
+    p_SetComp(dest, p_GetComp( src,src_r), dest_r);
+  p_Setm(dest, dest_r);
+}
+
+#include <polys/prCopy.inc>
+
+/////////////////////////////////////////////////////////////////////////
+poly prCopyR(poly p, ring src_r, ring dest_r)
+{
+  poly res;
+  if (rField_has_simple_Alloc(dest_r))
+    res =  pr_Copy_NoREqual_NSimple_Sort(p, src_r, dest_r);
+  else
+    res =  pr_Copy_NoREqual_NoNSimple_Sort(p, src_r, dest_r);
+  p_Test(res, dest_r);
+  return res;
+}
+
+poly prMapR(poly src, nMapFunc nMap, ring src_r, ring dest_r)
+{
+  if (src==NULL) return NULL;
+  int _min = si_min(dest_r->N, src_r->N);
+
+  spolyrec dest_s;
+
+  poly dest = &dest_s;
+
+  while (src != NULL)
+  {
+    poly prev=dest;
+    pNext(dest) = (poly) p_Init(dest_r); pIter(dest);
+
+    pSetCoeff0(dest, nMap(pGetCoeff(src),src_r->cf,dest_r->cf));
+    prCopyEvector(dest, dest_r, src, src_r, _min);
+    if (n_IsZero(pGetCoeff(dest),dest_r->cf))
+    {
+      p_LmDelete(pNext(prev),dest_r);
+      dest=pNext(prev);
+    }
+    pIter(src);
+  }
+  pNext(dest) = NULL;
+  dest = pNext(&dest_s);
+  dest=p_SortAdd(dest, dest_r);
+  p_Test(dest, dest_r);
+  return dest;
+}
+
+poly prCopyR_NoSort(poly p, ring src_r, ring dest_r)
+{
+  poly res;
+  if (rField_has_simple_Alloc(dest_r))
+    res =  pr_Copy_NoREqual_NSimple_NoSort(p, src_r, dest_r);
+  else
+    res =  pr_Copy_NoREqual_NoNSimple_NoSort(p, src_r, dest_r);
+  p_Test(res, dest_r);
+  return res;
+}
+
+/////////////////////////////////////////////////////////////////////////
+// prMove
+poly prMoveR(poly &p, ring src_r, ring dest_r)
+{
+  poly res;
+  if (rField_has_simple_Alloc(dest_r))
+    res =  pr_Move_NoREqual_NSimple_Sort(p, src_r, dest_r);
+  else
+    res =  pr_Move_NoREqual_NoNSimple_Sort(p, src_r, dest_r);
+  p_Test(res, dest_r);
+  return res;
+}
+
+poly prMoveR_NoSort(poly &p, ring src_r, ring dest_r)
+{
+  poly res;
+  if (rField_has_simple_Alloc(dest_r))
+    res =  pr_Move_NoREqual_NSimple_NoSort(p, src_r, dest_r);
+  else
+    res =  pr_Move_NoREqual_NoNSimple_NoSort(p, src_r, dest_r);
+  p_Test(res, dest_r);
+  return res;
+}
+
+poly prShallowCopyR_NoSort(poly p, ring r, ring dest_r)
+{
+  return pr_Copy_NoREqual_NSimple_NoSort(p, r, dest_r);
+}
+
+poly prShallowCopyR(poly p, ring r, ring dest_r)
+{
+  return pr_Copy_NoREqual_NSimple_Sort(p, r, dest_r);
+}
+
+/////////////////////////////////////////////////////////////////////////
+// prHead
+typedef poly (*prCopyProc_t)(poly &src_p, ring src_r, ring dest_r);
+
+poly prHeadR(poly p, ring src_r, ring dest_r, prCopyProc_t prproc)
+{
+  if (p == NULL) return NULL;
+  poly tail, head, q = p;
+  tail = pNext(p);
+  pNext(p) = NULL;
+  head = prproc(q, src_r, dest_r);
+  pNext(p) = tail;
+
+  p_Test(p, src_r);
+  p_Test(head, dest_r);
+
+  return head;
+}
+
+poly prHeadR(poly p, ring src_r, ring dest_r)
+{
+  prCopyProc_t prproc;
+  if (rField_has_simple_Alloc(dest_r))
+    prproc = pr_Copy_NoREqual_NSimple_NoSort;
+  else
+    prproc = pr_Copy_NoREqual_NoNSimple_NoSort;
+
+  const poly res = prHeadR(p, src_r, dest_r, prproc);
+  p_Test(res, dest_r);
+  return res;
+}
+
+/////////////////////////////////////////////////////////////////////////
+/// Copy leading terms of id[i] via prHeeadR into dest_r
+ideal idrHeadR(ideal id, ring r, ring dest_r)
+{
+  if (id == NULL) return NULL;
+
+  prCopyProc_t prproc = pr_Copy_NoREqual_NoNSimple_NoSort;
+  if (rField_has_simple_Alloc(dest_r))
+    prproc = pr_Copy_NoREqual_NSimple_NoSort;
+
+  const int N = IDELEMS(id);
+  ideal res = idInit(N, id->rank);
+
+  for (int i = N - 1; i >= 0; i--)
+    res->m[i] = prHeadR(id->m[i], r, dest_r, prproc); // !!!
+
+  return res;
+}
+
+
+static inline ideal
+idrCopy(ideal id, ring src_r, ring dest_r, prCopyProc_t prproc)
+{
+  if (id == NULL) return NULL;
+  assume(src_r->cf==dest_r->cf);
+  poly p;
+  ideal res = idInit(IDELEMS(id), id->rank);
+  int i;
+
+  for (i=IDELEMS(id)-1; i>=0; i--)
+  {
+    p = id->m[i];
+    res->m[i] = prproc(p, src_r, dest_r);
+    p_Test(res->m[i], dest_r);
+  }
+  return res;
+}
+
+ideal idrCopyR(ideal id, ring src_r, ring dest_r)
+{
+  assume(src_r->cf==dest_r->cf);
+  ideal res;
+  prCopyProc_t prproc;
+  if (rField_has_simple_Alloc(dest_r))
+    prproc = pr_Copy_NoREqual_NSimple_Sort;
+  else
+    prproc = pr_Copy_NoREqual_NoNSimple_Sort;
+  res =  idrCopy(id, src_r, dest_r, prproc);
+  return res;
+}
+
+ideal idrCopyR_NoSort(ideal id, ring src_r, ring dest_r)
+{
+  assume(src_r->cf==dest_r->cf);
+  ideal res;
+  prCopyProc_t prproc;
+  if (rField_has_simple_Alloc(dest_r))
+    prproc = pr_Copy_NoREqual_NSimple_NoSort;
+  else
+    prproc = pr_Copy_NoREqual_NoNSimple_NoSort;
+  res =  idrCopy(id, src_r, dest_r, prproc);
+  return res;
+}
+
+/////////////////////////////////////////////////////////////////////////
+// idrShallowCopy
+ideal idrShallowCopyR(ideal id, ring src_r, ring dest_r)
+{
+  return idrCopy(id, src_r, dest_r, pr_Copy_NoREqual_NSimple_Sort);
+}
+
+ideal idrShallowCopyR_NoSort(ideal id, ring src_r, ring dest_r)
+{
+  return idrCopy(id, src_r, dest_r, pr_Copy_NoREqual_NSimple_NoSort);
+}
+
+/////////////////////////////////////////////////////////////////////////
+// idrMove
+static inline ideal
+idrMove(ideal &id, ring src_r, ring dest_r, prCopyProc_t prproc)
+{
+  assume(src_r->cf==dest_r->cf);
+  assume( prproc != NULL );
+
+  if (id == NULL) return NULL;
+
+  ideal res = id; id = NULL;
+
+  for (int i = IDELEMS(res) - 1; i >= 0; i--)
+    res->m[i] = prproc(res->m[i], src_r, dest_r);
+
+  return res;
+}
+
+ideal idrMoveR(ideal &id, ring src_r, ring dest_r)
+{
+  assume(src_r->cf==dest_r->cf);
+  prCopyProc_t prproc;
+  ideal res;
+  if (rField_has_simple_Alloc(dest_r))
+    prproc = pr_Move_NoREqual_NSimple_Sort;
+  else
+    prproc = pr_Move_NoREqual_NoNSimple_Sort;
+  res =  idrMove(id, src_r, dest_r, prproc);
+  return res;
+}
+
+ideal idrMoveR_NoSort(ideal &id, ring src_r, ring dest_r)
+{
+  assume(src_r->cf==dest_r->cf);
+  prCopyProc_t prproc;
+  ideal res;
+  if (rField_has_simple_Alloc(dest_r))
+    prproc = pr_Move_NoREqual_NSimple_NoSort;
+  else
+    prproc = pr_Move_NoREqual_NoNSimple_NoSort;
+  res =  idrMove(id, src_r, dest_r, prproc);
+  return res;
+}
+
+
diff --git a/libpolys/polys/prCopy.h b/libpolys/polys/prCopy.h
new file mode 100644
index 0000000..8e6e31d
--- /dev/null
+++ b/libpolys/polys/prCopy.h
@@ -0,0 +1,51 @@
+#ifndef PRCOPY_H
+#define PRCOPY_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT - declarations of functions for Copy/Move/Delete for Polys
+*/
+
+struct spolyrec; typedef struct spolyrec polyrec; typedef polyrec* poly;
+struct ip_sring; typedef struct ip_sring* ring; typedef struct ip_sring const* const_ring;
+struct sip_sideal; typedef struct sip_sideal *ideal;
+
+struct snumber; typedef struct snumber *   number;
+struct n_Procs_s; typedef struct  n_Procs_s  *coeffs;
+
+typedef number (*nMapFunc)(number a, const coeffs src, const coeffs dst);
+
+/*************************************************************************
+ *
+ * MoveR, CopyR, ShallowCopyR: operations to get ideals/polys
+ *                             from source_r to dest_r where
+ *  - Coeff(source_r) == Coeff(dest_r)
+ *  - dest_r->N <= source_r->N
+ * Move:        input is destroyed
+ * ShallowCopy: monomials are copied, coeffs are set
+ * Copy:        monomials and coeffs are copied
+ *
+ ************************************************************************/
+poly prMoveR_NoSort(poly &p, ring r, ring dest_r);
+poly prMoveR(poly &p, ring r, ring dest_r);
+poly prCopyR_NoSort(poly p, ring r, ring dest_r);
+poly prCopyR(poly p, ring r, ring dest_r);
+poly prShallowCopyR_NoSort(poly p, ring r, ring dest_t);
+poly prShallowCopyR(poly p, ring r, ring dest_t);
+poly prHeadR(poly p, ring r, ring dest_rg);
+
+ideal idrMoveR_NoSort(ideal &id, ring r, ring dest_r );
+ideal idrMoveR(ideal &id, ring r, ring dest_r );
+
+ideal idrCopyR_NoSort(ideal id, ring r, ring dest_r );
+ideal idrCopyR(ideal id, ring r, ring dest_r );
+
+ideal idrShallowCopyR_NoSort(ideal id, ring r, ring dest_r );
+ideal idrShallowCopyR(ideal id, ring r, ring dest_r );
+
+/// Copy leading terms of id[i] via prHeeadR into dest_r
+ideal idrHeadR(ideal id, ring r, ring dest_r );
+
+poly prMapR(poly src, nMapFunc nMap, ring src_r, ring dest_r);
+#endif
diff --git a/libpolys/polys/prCopy.pl b/libpolys/polys/prCopy.pl
new file mode 100644
index 0000000..5049ebd
--- /dev/null
+++ b/libpolys/polys/prCopy.pl
@@ -0,0 +1,38 @@
+#!/usr/bin/perl
+# generate prCopy.inc
+
+ at defines = ("PR_DELETE_SRC",  "Move", "Copy",
+            "PR_RING_EQUAL",   "REqual", "NoREqual",
+            "PR_NUMBER_SIMPLE", "NSimple", "NoNSimple",
+            "PR_NO_SORT", "NoSort", "Sort");
+
+ at def = ("Move", "REqual", "NSimple", "NoSort");
+ at notdef = ("Copy", "NoREqaul", "NoNSimple", "Sort");
+
+sub Generate
+{
+  my ($prefix, @args) = @_;
+
+  if (@args)
+  {
+    my $name = shift @args;
+    my $yes = shift @args;
+    my $no = shift @args;
+    print "#undef $name\n";
+    print "#define $name 0\n";
+    Generate($prefix."_".$no, @args);
+    print "#undef $name\n";
+    print "#define $name 1\n";
+    Generate($prefix."_".$yes, @args);
+  }
+  else
+  {
+    print "#undef PR_NAME\n";
+    print "#define PR_NAME $prefix\n";
+    print "#include <polys/prCopyMacros.h>\n";
+    print "#include <polys/prCopyTemplate.cc>\n";
+  }
+  print "\n";
+}
+
+Generate("pr", @defines);
diff --git a/libpolys/polys/prCopyMacros.h b/libpolys/polys/prCopyMacros.h
new file mode 100644
index 0000000..0182af1
--- /dev/null
+++ b/libpolys/polys/prCopyMacros.h
@@ -0,0 +1,52 @@
+#undef PR_DELETE_MONOM
+#if PR_DELETE_SRC > 0
+#define PR_DELETE_MONOM(src, r_src)             \
+do                                              \
+{                                               \
+  PR_NDELETE(&pGetCoeff(src), r_src);           \
+  p_LmFree(src, r_src);            \
+}                                               \
+while (0)
+#else
+#define PR_DELETE_MONOM(src, r_src) do {} while (0)
+#endif
+
+#undef PR_INIT_EVECTOR_COPY
+#undef PR_CPY_EVECTOR
+#undef PR_ALLOC_MONOM
+#if PR_RING_EQUAL > 0
+#undef PR_NO_SORT
+#define PR_NO_SORT 1
+#define PR_INIT_EVECTOR_COPY(r_src, r_dest) do {} while (0)
+#define PR_CPY_EVECTOR(dest, dest_r, src, src_r) \
+  omMemcpyW(dest->exp, src->exp, dest_r->ExpL_Size)
+#define PR_ALLOC_MONOM(r) p_New(r)
+#undef PR_ALLOC_MONOM
+#define PR_ALLOC_MONOM(r) p_Init(r)
+#else
+#define  PR_INIT_EVECTOR_COPY(r_src, r_dest) int _min = si_min(r_dest->N, r_src->N)
+#define  PR_CPY_EVECTOR(dest, dest_r, src, src_r) \
+  prCopyEvector(dest, dest_r, src, src_r, _min)
+#define PR_ALLOC_MONOM(r) p_Init(r)
+#endif
+
+#undef PR_NCOPY
+#undef PR_NDELETE
+#undef PR_NUMBER_SIMPLE_NAME
+#if PR_NUMBER_SIMPLE > 0
+#define PR_NCOPY(n, r) n
+#define PR_NDELETE(n, r) do {} while (0)
+#define PR_NUMBER_SIMPLE_NAME NSimple
+#else
+#define PR_NCOPY(n, r) n_Copy(n,r->cf)
+#define PR_NDELETE(n, r) n_Delete(n,r->cf)
+#define PR_NUMBER_SIMPLE_NAME NoNSimple
+#endif
+
+#undef PR_SORT_POLY
+#if PR_NO_SORT > 0
+#define PR_SORT_POLY(p, d_r, s_r) do {} while (0)
+#else
+#define PR_SORT_POLY(p, d_r, s_r) p = p_SortMerge(p, d_r, d_r->OrdSgn == s_r->OrdSgn)
+#endif
+
diff --git a/libpolys/polys/prCopyTemplate.cc b/libpolys/polys/prCopyTemplate.cc
new file mode 100644
index 0000000..4526da9
--- /dev/null
+++ b/libpolys/polys/prCopyTemplate.cc
@@ -0,0 +1,37 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT - templates for pr routines
+*/
+
+
+static poly PR_NAME
+(poly &src, const ring r_src, const ring r_dest)
+{
+  if (src==NULL) return NULL;
+
+  /* PrintS("src: "); p_Write(src, r_src); PrintLn(); */
+
+  //  p_Test(src, r_src); // may fail due to wrong monomial order
+  spolyrec dest_s;
+
+  poly dest = &dest_s;
+  PR_INIT_EVECTOR_COPY(r_src, r_dest);
+
+  poly p = src; src = NULL;
+  while (p != NULL)
+  {
+    pNext(dest) = (poly) PR_ALLOC_MONOM(r_dest); pIter(dest);
+
+    p_SetCoeff0(dest, PR_NCOPY(p_GetCoeff(p, r_src), r_src), r_dest);
+    PR_CPY_EVECTOR(dest, r_dest, p, r_src);
+
+    { poly tmp = pNext(p); PR_DELETE_MONOM(p, r_src); p = tmp; }
+  }
+  pNext(dest) = NULL;
+  dest = pNext(&dest_s);
+  PR_SORT_POLY(dest, r_dest, r_src);
+  p_Test(dest, r_dest);
+  return dest;
+}
diff --git a/libpolys/polys/sbuckets.cc b/libpolys/polys/sbuckets.cc
new file mode 100644
index 0000000..665a92a
--- /dev/null
+++ b/libpolys/polys/sbuckets.cc
@@ -0,0 +1,400 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    sbuckets.cc
+ *  Purpose: implementation of routines for sorting polys using
+ *           a bucket sort
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 9/00
+ *******************************************************************/
+//#include <kernel/mod2.h>
+
+#include <omalloc/omalloc.h>
+
+
+
+
+#include <misc/auxiliary.h>
+
+#include <polys/sbuckets.h>
+
+#include <polys/monomials/ring.h>
+//#include <kernel/p_Procs.h>
+#include <polys/monomials/p_polys.h>
+
+
+
+//////////////////////////////////////////////////////////////////////////
+// Declarations
+//
+
+class sBucketPoly
+{
+public:
+  poly p;
+  long length;
+};
+
+class sBucket
+{
+public:
+  ring          bucket_ring;
+  long          max_bucket;
+  sBucketPoly   buckets[BIT_SIZEOF_LONG - 3];
+}
+;
+
+static omBin sBucket_bin = omGetSpecBin(sizeof(sBucket));
+
+
+//////////////////////////////////////////////////////////////////////////
+// New API:
+//
+
+/// Returns bucket ring
+ring sBucketGetRing(const sBucket_pt bucket)
+{ return bucket->bucket_ring; }
+
+
+bool sIsEmpty(const sBucket_pt bucket)
+{
+  for(int i = 0; i < (BIT_SIZEOF_LONG - 3); i++)
+  {
+    assume( i < (BIT_SIZEOF_LONG - 3) );
+    assume( pLength(bucket->buckets[i].p) == bucket->buckets[i].length );
+
+    if( bucket->buckets[i].p != NULL )
+      return false;
+
+    if( bucket->buckets[i].length != 0 )
+      return false;
+  }
+
+  return( bucket->max_bucket == 0 );
+
+}
+
+
+/// Copy sBucket non-intrusive!!!
+sBucket_pt    sBucketCopy(const sBucket_pt bucket)
+{
+  const ring r = bucket->bucket_ring;
+
+  sBucket_pt newbucket = sBucketCreate(r);
+
+  newbucket->max_bucket = bucket->max_bucket;
+
+  for(int i = 0; i <= bucket->max_bucket; i++)
+  {
+    assume( i < (BIT_SIZEOF_LONG - 3) );
+    assume( pLength(bucket->buckets[i].p) == bucket->buckets[i].length );
+
+    newbucket->buckets[i].p = p_Copy(bucket->buckets[i].p, r);
+    newbucket->buckets[i].length = bucket->buckets[i].length;
+
+    assume( pLength(newbucket->buckets[i].p) == newbucket->buckets[i].length );
+  }
+
+  return newbucket;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// internal routines
+//
+// returns floor(log_2(i))
+static inline int LOG2(int i)
+{
+  assume (i > 0);
+  int j = 0;
+
+  do
+  {
+    i = i >> 1;
+    if (i == 0) return j;
+    j++;
+  }
+  while (1);
+
+  return j;
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Creation/Destruction of buckets
+//
+sBucket_pt    sBucketCreate(ring r)
+{
+  sBucket_pt bucket = (sBucket_pt) omAlloc0Bin(sBucket_bin);
+  bucket->bucket_ring = r;
+  return bucket;
+}
+
+void          sBucketDestroy(sBucket_pt *bucket)
+{
+  assume(bucket != NULL);
+  omFreeBin(*bucket, sBucket_bin);
+  *bucket = NULL;
+}
+
+void sBucketDeleteAndDestroy(sBucket_pt *bucket_pt)
+{
+  sBucket_pt bucket = *bucket_pt;
+  int i;
+  for (i=0; i<= bucket->max_bucket; i++)
+  {
+
+    if (bucket->buckets[i].p != NULL)
+    {
+      p_Delete(&(bucket->buckets[i].p), bucket->bucket_ring);
+    }
+  }
+  omFreeBin(bucket, sBucket_bin);
+  *bucket_pt = NULL;
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+// Convertion from/to SBpolys
+//
+
+static void sBucket_Merge_m(sBucket_pt bucket, poly p)
+{
+  assume(p != NULL && pNext(p) == NULL);
+  int length = 1;
+  int i = 0;
+
+  while (bucket->buckets[i].p != NULL)
+  {
+    p = p_Merge_q(p, bucket->buckets[i].p, bucket->bucket_ring);
+    length += bucket->buckets[i].length;
+    bucket->buckets[i].p = NULL;
+    bucket->buckets[i].length = 0;
+    i++;
+    assume(LOG2(length) == i);
+  }
+
+  bucket->buckets[i].p = p;
+  bucket->buckets[i].length = length;
+  if (i > bucket->max_bucket) bucket->max_bucket = i;
+}
+
+void sBucket_Merge_p(sBucket_pt bucket, poly p, int length)
+{
+  assume(bucket != NULL);
+  assume(length <= 0 || length == pLength(p));
+
+  if (p == NULL) return;
+  if (length <= 0) length = pLength(p);
+
+  int i = LOG2(length);
+
+  while (bucket->buckets[i].p != NULL)
+  {
+    p = p_Merge_q(p, bucket->buckets[i].p, bucket->bucket_ring);
+    length += bucket->buckets[i].length;
+    bucket->buckets[i].p = NULL;
+    bucket->buckets[i].length = 0;
+    i++;
+    assume(LOG2(length) == i);
+  }
+
+  bucket->buckets[i].p = p;
+  bucket->buckets[i].length = length;
+  if (i > bucket->max_bucket) bucket->max_bucket = i;
+}
+
+void sBucket_Add_p(sBucket_pt bucket, poly p, int length)
+{
+  assume(bucket != NULL);
+  assume(length <= 0 || length == pLength(p));
+
+  if (p == NULL) return;
+  if (length <= 0) length = pLength(p);
+
+  int i = LOG2(length);
+
+  while (bucket->buckets[i].p != NULL)
+  {
+    p = p_Add_q(p, bucket->buckets[i].p, length, bucket->buckets[i].length,
+                bucket->bucket_ring);
+    bucket->buckets[i].p = NULL;
+    bucket->buckets[i].length = 0;
+    if (p==NULL)
+    {
+      if (i > bucket->max_bucket) bucket->max_bucket = i;
+      return;
+    }
+    i = LOG2(length);
+  }
+
+  bucket->buckets[i].p = p;
+  bucket->buckets[i].length = length;
+  if (i > bucket->max_bucket) bucket->max_bucket = i;
+}
+
+// Converts SBpoly into a poly and clears bucket
+// i.e., afterwards SBpoly == 0
+void sBucketClearMerge(sBucket_pt bucket, poly *p, int *length)
+{
+  poly pr = NULL;
+  int  lr = 0;
+  int i = 0;
+
+  while (bucket->buckets[i].p == NULL)
+  {
+    i++;
+    if (i > bucket->max_bucket) goto done;
+  }
+
+  pr = bucket->buckets[i].p;
+  lr = bucket->buckets[i].length;
+  bucket->buckets[i].p = NULL;
+  bucket->buckets[i].length = 0;
+  i++;
+
+  while (i <= bucket->max_bucket)
+  {
+    if (bucket->buckets[i].p != NULL)
+    {
+      pr = p_Merge_q(pr, bucket->buckets[i].p,bucket->bucket_ring);
+      lr += bucket->buckets[i].length;
+      bucket->buckets[i].p = NULL;
+      bucket->buckets[i].length = 0;
+    }
+    i++;
+  }
+
+  done:
+  *p = pr;
+  *length = lr;
+  bucket->max_bucket = 0;
+}
+
+// Converts SBpoly into a poly and clears bucket
+// i.e., afterwards SBpoly == 0
+void sBucketClearAdd(sBucket_pt bucket, poly *p, int *length)
+{
+  poly pr = NULL;
+  int  lr = 0;
+  int i = 0;
+
+  while (bucket->buckets[i].p == NULL)
+  {
+    assume( bucket->buckets[i].length == 0 );
+    i++;
+    if (i > bucket->max_bucket) goto done;
+  }
+
+  pr = bucket->buckets[i].p;
+  lr = bucket->buckets[i].length;
+
+  assume( pr != NULL && (lr > 0) );
+
+  bucket->buckets[i].p = NULL;
+  bucket->buckets[i].length = 0;
+  i++;
+
+  while (i <= bucket->max_bucket)
+  {
+    if (bucket->buckets[i].p != NULL)
+    {
+      assume( bucket->buckets[i].length == pLength(bucket->buckets[i].p) );
+
+      pr = p_Add_q(pr, bucket->buckets[i].p, lr, bucket->buckets[i].length,
+                   bucket->bucket_ring);
+
+      bucket->buckets[i].p = NULL;
+      bucket->buckets[i].length = 0;
+    }
+
+    assume( bucket->buckets[i].p == NULL );
+    assume( bucket->buckets[i].length == 0 );
+    i++;
+  }
+
+done:
+
+  *p = pr;
+  *length = lr;
+
+  bucket->max_bucket = 0;
+
+  assume( sIsEmpty(bucket) );
+}
+
+
+
+
+/////////////////////////////////////////////////////////////////////////////
+// Sorts a poly using BucketSort
+//
+
+poly sBucketSortMerge(poly p, ring r)
+{
+#ifdef HAVE_ASSUME
+  int l_in = pLength(p);
+#endif
+
+  if (p == NULL || pNext(p) == NULL) return p;
+
+  sBucket_pt bucket = sBucketCreate(r);
+  poly pn = pNext(p);
+
+  do
+  {
+    pNext(p) = NULL;
+    sBucket_Merge_m(bucket, p);
+    p = pn;
+    if (p == NULL) break;
+    pn = pNext(pn);
+  }
+  while (1);
+
+  int l_dummy;
+  sBucketClearMerge(bucket, &pn, &l_dummy);
+  sBucketDestroy(&bucket);
+
+  p_Test(pn, r);
+#ifdef HAVE_ASSUME
+  assume(l_dummy == pLength(pn));
+  assume(l_in == l_dummy);
+#endif
+  return pn;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Sorts a poly using BucketSort
+//
+
+poly sBucketSortAdd(poly p, ring r)
+{
+#ifdef HAVE_ASSUME
+  int l_in = pLength(p);
+#endif
+
+  if (p == NULL || pNext(p) == NULL) return p;
+
+  sBucket_pt bucket = sBucketCreate(r);
+  poly pn = pNext(p);
+
+  do
+  {
+    pNext(p) = NULL;
+    sBucket_Add_p(bucket, p, 1);
+    p = pn;
+    if (p == NULL) break;
+    pn = pNext(pn);
+  }
+  while (1);
+
+  int l_dummy;
+  sBucketClearAdd(bucket, &pn, &l_dummy);
+  sBucketDestroy(&bucket);
+
+  p_Test(pn, r);
+#ifdef HAVE_ASSUME
+  assume(l_dummy == pLength(pn));
+  assume(l_in >= l_dummy);
+#endif
+  return pn;
+}
diff --git a/libpolys/polys/sbuckets.h b/libpolys/polys/sbuckets.h
new file mode 100644
index 0000000..36f57e2
--- /dev/null
+++ b/libpolys/polys/sbuckets.h
@@ -0,0 +1,104 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    sbuckets.h
+ *  Purpose: declaration of routines for sorting and adding up polys using
+ *           a bucket sort
+ *  Note:    If you need to extract the leading momonial of a bucket,
+ *           use kbuckets, instead.
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 9/00
+ *******************************************************************/
+#ifndef S_BUCKETS_H
+#define S_BUCKETS_H
+
+class sBucket; typedef sBucket*           sBucket_pt;
+struct  spolyrec; typedef struct spolyrec polyrec; typedef polyrec* poly;
+struct ip_sring; typedef struct ip_sring* ring; typedef struct ip_sring const* const_ring;
+
+
+
+//////////////////////////////////////////////////////////////////////////
+// Creation/Destruction of buckets
+//
+sBucket_pt    sBucketCreate(ring r);
+void          sBucketDestroy(sBucket_pt *bucket);
+
+//////////////////////////////////////////////////////////////////////////
+// New API:
+//
+
+/// Copy sBucket non-intrusive!!!
+sBucket_pt    sBucketCopy(const sBucket_pt bucket);
+
+/// Returns bucket ring
+ring sBucketGetRing(const sBucket_pt bucket);
+
+/// Test whether bucket is empty!?
+bool sIsEmpty(const sBucket_pt bucket);
+
+
+
+/////////////////////////////////////////////////////////////////////////////
+// Convertion from/to SBpolys
+//
+
+// Converts p into a bucket poly (SBpoly) and destroys p
+// Assumes length <= 0 || pLength(p) == length
+// void sBucketInit(sBucket_pt bucket, poly p, int length);
+
+// creates and returns new bucket, initializes it with p
+// sBucket_pt sBucketInit( poly p, int length, ring r = currRing);
+
+// Converts SBpoly into a poly and clears bucket
+// i.e., afterwards SBpoly == 0
+// assumes all monomials in bucket are different
+void sBucketClearMerge(sBucket_pt bucket, poly *p, int *length);
+
+// Converts SBpoly into a poly and clears bucket
+// i.e., afterwards SBpoly == 0
+// bucket may contain equal monials
+void sBucketClearAdd(sBucket_pt bucket, poly *p, int *length);
+
+// Converts SBpoly into a poly and detroys bucket
+inline void sBucketDestroyMerge(sBucket_pt bucket, poly *p, int *length)
+{
+  sBucketClearMerge(bucket, p, length);
+  sBucketDestroy(&bucket);
+}
+
+// Converts SBpoly into a poly and detroys bucket
+inline void sBucketDestroyAdd(sBucket_pt bucket, poly *p, int *length)
+{
+  sBucketClearAdd(bucket, p, length);
+  sBucketDestroy(&bucket);
+}
+
+void sBucketDeleteAndDestroy(sBucket_pt *bucket_pt);
+
+//////////////////////////////////////////////////////////////////////////
+
+/// Merges p into Spoly: assumes Bpoly and p have no common monoms
+/// destroys p!
+void sBucket_Merge_p(sBucket_pt bucket, poly p, int lp);
+
+/// adds poly p to bucket
+/// destroys p!
+void sBucket_Add_p(sBucket_pt bucket, poly p, int lp);
+
+
+//////////////////////////////////////////////////////////////////////////
+///
+/// Sorts p with bucketSort: assumes all monomials of p are different
+///
+poly sBucketSortMerge(poly p, ring r);
+
+//////////////////////////////////////////////////////////////////////////
+///
+/// Sorts p with bucketSort: p may have equal monomials
+///
+poly sBucketSortAdd(poly p, ring r);
+
+
+#endif // P_BUCKET_SORT
diff --git a/libpolys/polys/simpleideals.cc b/libpolys/polys/simpleideals.cc
new file mode 100644
index 0000000..5f24b7a
--- /dev/null
+++ b/libpolys/polys/simpleideals.cc
@@ -0,0 +1,1735 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT - all basic methods to manipulate ideals
+*/
+
+
+/* includes */
+
+
+
+#include <misc/auxiliary.h>
+
+#include <omalloc/omalloc.h>
+
+#include <misc/options.h>
+#include <misc/intvec.h>
+
+// #include <coeffs/longrat.h>
+#include "matpol.h"
+
+#include "monomials/p_polys.h"
+#include "weight.h"
+#include "sbuckets.h"
+#include "clapsing.h"
+
+#include "simpleideals.h"
+
+omBin sip_sideal_bin = omGetSpecBin(sizeof(sip_sideal));
+
+static poly * idpower;
+/*collects the monomials in makemonoms, must be allocated befor*/
+static int idpowerpoint;
+/*index of the actual monomial in idpower*/
+
+/*2
+* initialise an ideal
+*/
+ideal idInit(int idsize, int rank)
+{
+  /*- initialise an ideal -*/
+  ideal hh = (ideal )omAllocBin(sip_sideal_bin);
+  hh->nrows = 1;
+  hh->rank = rank;
+  IDELEMS(hh) = idsize;
+  if (idsize>0)
+  {
+    hh->m = (poly *)omAlloc0(idsize*sizeof(poly));
+  }
+  else
+    hh->m=NULL;
+  return hh;
+}
+
+#ifdef PDEBUG
+// this is only for outputting an ideal within the debugger
+void idShow(const ideal id, const ring lmRing, const ring tailRing, const int debugPrint)
+{
+  assume( debugPrint >= 0 );
+
+  if( id == NULL )
+    PrintS("(NULL)");
+  else
+  {
+    Print("Module of rank %ld,real rank %ld and %d generators.\n",
+          id->rank,id_RankFreeModule(id, lmRing, tailRing),IDELEMS(id));
+
+    int j = (id->ncols*id->nrows) - 1;
+    while ((j > 0) && (id->m[j]==NULL)) j--;
+    for (int i = 0; i <= j; i++)
+    {
+      Print("generator %d: ",i); p_DebugPrint(id->m[i], lmRing, tailRing, debugPrint);
+    }
+  }
+}
+#endif
+
+/// index of generator with leading term in ground ring (if any);
+/// otherwise -1
+int id_PosConstant(ideal id, const ring r)
+{
+  id_Test(id, r);
+  const int N = IDELEMS(id) - 1;
+  const poly * m = id->m + N;
+
+  for (int k = N; k >= 0; --k, --m)
+  {
+    const poly p = *m;
+    if (p!=NULL)
+       if (p_LmIsConstantComp(p, r) == TRUE)
+	 return k;
+  }
+
+  return -1;
+}
+
+/*2
+* initialise the maximal ideal (at 0)
+*/
+ideal id_MaxIdeal (const ring r)
+{
+  int l;
+  ideal hh=NULL;
+
+  hh=idInit(rVar(r),1);
+  for (l=0; l<rVar(r); l++)
+  {
+    hh->m[l] = p_One(r);
+    p_SetExp(hh->m[l],l+1,1,r);
+    p_Setm(hh->m[l],r);
+  }
+  return hh;
+}
+
+/*2
+* deletes an ideal/matrix
+*/
+void id_Delete (ideal * h, ring r)
+{
+  int j,elems;
+  if (*h == NULL)
+    return;
+  elems=j=(*h)->nrows*(*h)->ncols;
+  if (j>0)
+  {
+    do
+    {
+      j--;
+      poly pp=((*h)->m[j]);
+      if (pp!=NULL) p_Delete(&pp, r);
+    }
+    while (j>0);
+    omFreeSize((ADDRESS)((*h)->m),sizeof(poly)*elems);
+  }
+  omFreeBin((ADDRESS)*h, sip_sideal_bin);
+  *h=NULL;
+}
+
+
+/*2
+* Shallowdeletes an ideal/matrix
+*/
+void id_ShallowDelete (ideal *h, ring r)
+{
+  int j,elems;
+  if (*h == NULL)
+    return;
+  elems=j=(*h)->nrows*(*h)->ncols;
+  if (j>0)
+  {
+    do
+    {
+      p_ShallowDelete(&((*h)->m[--j]), r);
+    }
+    while (j>0);
+    omFreeSize((ADDRESS)((*h)->m),sizeof(poly)*elems);
+  }
+  omFreeBin((ADDRESS)*h, sip_sideal_bin);
+  *h=NULL;
+}
+
+/*2
+*gives an ideal the minimal possible size
+*/
+void idSkipZeroes (ideal ide)
+{
+  int k;
+  int j = -1;
+  BOOLEAN change=FALSE;
+  for (k=0; k<IDELEMS(ide); k++)
+  {
+    if (ide->m[k] != NULL)
+    {
+      j++;
+      if (change)
+      {
+        ide->m[j] = ide->m[k];
+      }
+    }
+    else
+    {
+      change=TRUE;
+    }
+  }
+  if (change)
+  {
+    if (j == -1)
+      j = 0;
+    else
+    {
+      for (k=j+1; k<IDELEMS(ide); k++)
+        ide->m[k] = NULL;
+    }
+    pEnlargeSet(&(ide->m),IDELEMS(ide),j+1-IDELEMS(ide));
+    IDELEMS(ide) = j+1;
+  }
+}
+
+int idElem(const ideal F)
+{
+  int i=0,j=IDELEMS(F)-1;
+
+  while(j>=0)
+  {
+    if ((F->m)[j]!=NULL) i++;
+    j--;
+  }
+  return i;
+}
+
+/*2
+* copies the first k (>= 1) entries of the given ideal
+* and returns these as a new ideal
+* (Note that the copied polynomials may be zero.)
+*/
+ideal id_CopyFirstK (const ideal ide, const int k,const ring r)
+{
+  ideal newI = idInit(k, 0);
+  for (int i = 0; i < k; i++)
+    newI->m[i] = p_Copy(ide->m[i],r);
+  return newI;
+}
+
+/*2
+* ideal id = (id[i])
+* result is leadcoeff(id[i]) = 1
+*/
+void id_Norm(ideal id, const ring r)
+{
+  for (int i=IDELEMS(id)-1; i>=0; i--)
+  {
+    if (id->m[i] != NULL)
+    {
+      p_Norm(id->m[i],r);
+    }
+  }
+}
+
+/*2
+* ideal id = (id[i]), c any unit
+* if id[i] = c*id[j] then id[j] is deleted for j > i
+*/
+void id_DelMultiples(ideal id, const ring r)
+{
+  int i, j;
+  int k = IDELEMS(id)-1;
+  for (i=k; i>=0; i--)
+  {
+    if (id->m[i]!=NULL)
+    {
+      for (j=k; j>i; j--)
+      {
+        if (id->m[j]!=NULL)
+        {
+#ifdef HAVE_RINGS
+          if (rField_is_Ring(r))
+          {
+            /* if id[j] = c*id[i] then delete id[j].
+               In the below cases of a ground field, we
+               check whether id[i] = c*id[j] and, if so,
+               delete id[j] for historical reasons (so
+               that previous output does not change) */
+            if (p_ComparePolys(id->m[j], id->m[i],r)) p_Delete(&id->m[j],r);
+          }
+          else
+          {
+            if (p_ComparePolys(id->m[i], id->m[j],r)) p_Delete(&id->m[j],r);
+          }
+#else
+          if (p_ComparePolys(id->m[i], id->m[j],r)) p_Delete(&id->m[j],r);
+#endif
+        }
+      }
+    }
+  }
+}
+
+/*2
+* ideal id = (id[i])
+* if id[i] = id[j] then id[j] is deleted for j > i
+*/
+void id_DelEquals(ideal id, const ring r)
+{
+  int i, j;
+  int k = IDELEMS(id)-1;
+  for (i=k; i>=0; i--)
+  {
+    if (id->m[i]!=NULL)
+    {
+      for (j=k; j>i; j--)
+      {
+        if ((id->m[j]!=NULL)
+        && (p_EqualPolys(id->m[i], id->m[j],r)))
+        {
+          p_Delete(&id->m[j],r);
+        }
+      }
+    }
+  }
+}
+
+//
+// Delete id[j], if Lm(j) == Lm(i) and both LC(j), LC(i) are units and j > i
+//
+void id_DelLmEquals(ideal id, const ring r)
+{
+  int i, j;
+  int k = IDELEMS(id)-1;
+  for (i=k; i>=0; i--)
+  {
+    if (id->m[i] != NULL)
+    {
+      for (j=k; j>i; j--)
+      {
+        if ((id->m[j] != NULL)
+        && p_LmEqual(id->m[i], id->m[j],r)
+#ifdef HAVE_RINGS
+        && n_IsUnit(pGetCoeff(id->m[i]),r->cf) && n_IsUnit(pGetCoeff(id->m[j]),r->cf)
+#endif
+        )
+        {
+          p_Delete(&id->m[j],r);
+        }
+      }
+    }
+  }
+}
+
+//
+// delete id[j], if LT(j) == coeff*mon*LT(i) and vice versa, i.e.,
+// delete id[i], if LT(i) == coeff*mon*LT(j)
+//
+void id_DelDiv(ideal id, const ring r)
+{
+  int i, j;
+  int k = IDELEMS(id)-1;
+  for (i=k; i>=0; i--)
+  {
+    if (id->m[i] != NULL)
+    {
+      for (j=k; j>i; j--)
+      {
+        if (id->m[j]!=NULL)
+        {
+#ifdef HAVE_RINGS
+          if (rField_is_Ring(r))
+          {
+            if (p_DivisibleByRingCase(id->m[i], id->m[j],r))
+            {
+              p_Delete(&id->m[j],r);
+            }
+            else if (p_DivisibleByRingCase(id->m[j], id->m[i],r))
+            {
+              p_Delete(&id->m[i],r);
+              break;
+            }
+          }
+          else
+          {
+#endif
+          /* the case of a ground field: */
+          if (p_DivisibleBy(id->m[i], id->m[j],r))
+          {
+            p_Delete(&id->m[j],r);
+          }
+          else if (p_DivisibleBy(id->m[j], id->m[i],r))
+          {
+            p_Delete(&id->m[i],r);
+            break;
+          }
+#ifdef HAVE_RINGS
+          }
+#endif
+        }
+      }
+    }
+  }
+}
+
+/*2
+*test if the ideal has only constant polynomials
+*/
+BOOLEAN id_IsConstant(ideal id, const ring r)
+{
+  int k;
+  for (k = IDELEMS(id)-1; k>=0; k--)
+  {
+    if (!p_IsConstantPoly(id->m[k],r))
+      return FALSE;
+  }
+  return TRUE;
+}
+
+/*2
+* copy an ideal
+*/
+ideal id_Copy(ideal h1, const ring r)
+{
+  int i;
+  ideal h2;
+
+//#ifdef TEST
+  if (h1 == NULL)
+  {
+    h2=idInit(1,1);
+  }
+  else
+//#endif
+  {
+    h2=idInit(IDELEMS(h1),h1->rank);
+    for (i=IDELEMS(h1)-1; i>=0; i--)
+      h2->m[i] = p_Copy(h1->m[i],r);
+  }
+  return h2;
+}
+
+#ifdef PDEBUG
+void id_DBTest(ideal h1, int level, const char *f,const int l, const ring r, const ring tailRing)
+{
+  int i;
+
+  if (h1 != NULL)
+  {
+    // assume(IDELEMS(h1) > 0); for ideal/module, does not apply to matrix
+    omCheckAddrSize(h1,sizeof(*h1));
+    omdebugAddrSize(h1->m,h1->ncols*h1->nrows*sizeof(poly));
+
+    /* to be able to test matrices: */
+    for (i=(h1->ncols*h1->nrows)-1; i>=0; i--)
+      _pp_Test(h1->m[i], r, tailRing, level);
+
+    int new_rk=id_RankFreeModule(h1, r, tailRing);
+    if(new_rk > h1->rank)
+    {
+      dReportError("wrong rank %d (should be %d) in %s:%d\n",
+                   h1->rank, new_rk, f,l);
+      omPrintAddrInfo(stderr, h1, " for ideal");
+      h1->rank=new_rk;
+    }
+  }
+}
+#endif
+
+///3 for idSort: compare a and b revlex inclusive module comp.
+static int p_Comp_RevLex(poly a, poly b,BOOLEAN nolex, const ring R)
+{
+  if (b==NULL) return 1;
+  if (a==NULL) return -1;
+
+  if (nolex)
+  {
+    int r=p_LmCmp(a,b,R);
+    if (r!=0) return r;
+    number h=n_Sub(pGetCoeff(a),pGetCoeff(b),R->cf);
+    r = -1+n_IsZero(h,R->cf)+2*n_GreaterZero(h,R->cf); /* -1: <, 0:==, 1: > */
+    n_Delete(&h, R->cf);
+    return r;
+  }
+  int l=rVar(R);
+  while ((l>0) && (p_GetExp(a,l,R)==p_GetExp(b,l,R))) l--;
+  if (l==0)
+  {
+    if (p_GetComp(a,R)==p_GetComp(b,R))
+    {
+      number h=n_Sub(pGetCoeff(a),pGetCoeff(b),R->cf);
+      int r = -1+n_IsZero(h,R->cf)+2*n_GreaterZero(h,R->cf); /* -1: <, 0:==, 1: > */
+      n_Delete(&h,R->cf);
+      return r;
+    }
+    if (p_GetComp(a,R)>p_GetComp(b,R)) return 1;
+  }
+  else if (p_GetExp(a,l,R)>p_GetExp(b,l,R))
+    return 1;
+  return -1;
+}
+
+// sorts the ideal w.r.t. the actual ringordering
+// uses lex-ordering when nolex = FALSE
+intvec *id_Sort(const ideal id, const BOOLEAN nolex, const ring r)
+{
+  intvec * result = new intvec(IDELEMS(id));
+  int i, j, actpos=0, newpos;
+  int diff, olddiff, lastcomp, newcomp;
+  BOOLEAN notFound;
+
+  for (i=0;i<IDELEMS(id);i++)
+  {
+    if (id->m[i]!=NULL)
+    {
+      notFound = TRUE;
+      newpos = actpos / 2;
+      diff = (actpos+1) / 2;
+      diff = (diff+1) / 2;
+      lastcomp = p_Comp_RevLex(id->m[i],id->m[(*result)[newpos]],nolex,r);
+      if (lastcomp<0)
+      {
+        newpos -= diff;
+      }
+      else if (lastcomp>0)
+      {
+        newpos += diff;
+      }
+      else
+      {
+        notFound = FALSE;
+      }
+      //while ((newpos>=0) && (newpos<actpos) && (notFound))
+      while (notFound && (newpos>=0) && (newpos<actpos))
+      {
+        newcomp = p_Comp_RevLex(id->m[i],id->m[(*result)[newpos]],nolex,r);
+        olddiff = diff;
+        if (diff>1)
+        {
+          diff = (diff+1) / 2;
+          if ((newcomp==1)
+          && (actpos-newpos>1)
+          && (diff>1)
+          && (newpos+diff>=actpos))
+          {
+            diff = actpos-newpos-1;
+          }
+          else if ((newcomp==-1)
+          && (diff>1)
+          && (newpos<diff))
+          {
+            diff = newpos;
+          }
+        }
+        if (newcomp<0)
+        {
+          if ((olddiff==1) && (lastcomp>0))
+            notFound = FALSE;
+          else
+            newpos -= diff;
+        }
+        else if (newcomp>0)
+        {
+          if ((olddiff==1) && (lastcomp<0))
+          {
+            notFound = FALSE;
+            newpos++;
+          }
+          else
+          {
+            newpos += diff;
+          }
+        }
+        else
+        {
+          notFound = FALSE;
+        }
+        lastcomp = newcomp;
+        if (diff==0) notFound=FALSE; /*hs*/
+      }
+      if (newpos<0) newpos = 0;
+      if (newpos>actpos) newpos = actpos;
+      while ((newpos<actpos) && (p_Comp_RevLex(id->m[i],id->m[(*result)[newpos]],nolex,r)==0))
+        newpos++;
+      for (j=actpos;j>newpos;j--)
+      {
+        (*result)[j] = (*result)[j-1];
+      }
+      (*result)[newpos] = i;
+      actpos++;
+    }
+  }
+  for (j=0;j<actpos;j++) (*result)[j]++;
+  return result;
+}
+
+/*2
+* concat the lists h1 and h2 without zeros
+*/
+ideal id_SimpleAdd (ideal h1,ideal h2, const ring R)
+{
+  int i,j,r,l;
+  ideal result;
+
+  if (h1==NULL) return id_Copy(h2,R);
+  if (h2==NULL) return id_Copy(h1,R);
+  j = IDELEMS(h1)-1;
+  while ((j >= 0) && (h1->m[j] == NULL)) j--;
+  i = IDELEMS(h2)-1;
+  while ((i >= 0) && (h2->m[i] == NULL)) i--;
+  r = si_max(h1->rank,h2->rank);
+  if (i+j==(-2))
+    return idInit(1,r);
+  else
+    result=idInit(i+j+2,r);
+  for (l=j; l>=0; l--)
+  {
+    result->m[l] = p_Copy(h1->m[l],R);
+  }
+  r = i+j+1;
+  for (l=i; l>=0; l--, r--)
+  {
+    result->m[r] = p_Copy(h2->m[l],R);
+  }
+  return result;
+}
+
+/*2
+* insert h2 into h1 (if h2 is not the zero polynomial)
+* return TRUE iff h2 was indeed inserted
+*/
+BOOLEAN idInsertPoly (ideal h1, poly h2)
+{
+  if (h2==NULL) return FALSE;
+  int j = IDELEMS(h1)-1;
+  while ((j >= 0) && (h1->m[j] == NULL)) j--;
+  j++;
+  if (j==IDELEMS(h1))
+  {
+    pEnlargeSet(&(h1->m),IDELEMS(h1),16);
+    IDELEMS(h1)+=16;
+  }
+  h1->m[j]=h2;
+  return TRUE;
+}
+
+/*2
+* insert h2 into h1 depending on the two boolean parameters:
+* - if zeroOk is true, then h2 will also be inserted when it is zero
+* - if duplicateOk is true, then h2 will also be inserted when it is
+*   already present in h1
+* return TRUE iff h2 was indeed inserted
+*/
+BOOLEAN id_InsertPolyWithTests (ideal h1, const int validEntries,
+  const poly h2, const bool zeroOk, const bool duplicateOk, const ring r)
+{
+  if ((!zeroOk) && (h2 == NULL)) return FALSE;
+  if (!duplicateOk)
+  {
+    bool h2FoundInH1 = false;
+    int i = 0;
+    while ((i < validEntries) && (!h2FoundInH1))
+    {
+      h2FoundInH1 = p_EqualPolys(h1->m[i], h2,r);
+      i++;
+    }
+    if (h2FoundInH1) return FALSE;
+  }
+  if (validEntries == IDELEMS(h1))
+  {
+    pEnlargeSet(&(h1->m), IDELEMS(h1), 16);
+    IDELEMS(h1) += 16;
+  }
+  h1->m[validEntries] = h2;
+  return TRUE;
+}
+
+/*2
+* h1 + h2
+*/
+ideal id_Add (ideal h1,ideal h2, const ring r)
+{
+  ideal result = id_SimpleAdd(h1,h2,r);
+  id_Compactify(result,r);
+  return result;
+}
+
+/*2
+* h1 * h2
+*/
+ideal  id_Mult (ideal h1,ideal  h2, const ring r)
+{
+  int i,j,k;
+  ideal  hh;
+
+  j = IDELEMS(h1);
+  while ((j > 0) && (h1->m[j-1] == NULL)) j--;
+  i = IDELEMS(h2);
+  while ((i > 0) && (h2->m[i-1] == NULL)) i--;
+  j = j * i;
+  if (j == 0)
+    hh = idInit(1,1);
+  else
+    hh=idInit(j,1);
+  if (h1->rank<h2->rank)
+    hh->rank = h2->rank;
+  else
+    hh->rank = h1->rank;
+  if (j==0) return hh;
+  k = 0;
+  for (i=0; i<IDELEMS(h1); i++)
+  {
+    if (h1->m[i] != NULL)
+    {
+      for (j=0; j<IDELEMS(h2); j++)
+      {
+        if (h2->m[j] != NULL)
+        {
+          hh->m[k] = pp_Mult_qq(h1->m[i],h2->m[j],r);
+          k++;
+        }
+      }
+    }
+  }
+  {
+    id_Compactify(hh,r);
+    return hh;
+  }
+}
+
+/*2
+*returns true if h is the zero ideal
+*/
+BOOLEAN idIs0 (ideal h)
+{
+  int i;
+
+  if (h == NULL) return TRUE;
+  i = IDELEMS(h)-1;
+  while ((i >= 0) && (h->m[i] == NULL))
+  {
+    i--;
+  }
+  if (i < 0)
+    return TRUE;
+  else
+    return FALSE;
+}
+
+/*2
+* return the maximal component number found in any polynomial in s
+*/
+long id_RankFreeModule (ideal s, ring lmRing, ring tailRing)
+{
+  if (s!=NULL)
+  {
+    long  j=0;
+
+    if (rRing_has_Comp(tailRing) && rRing_has_Comp(lmRing))
+    {
+      poly *p=s->m;
+      for (unsigned int l=IDELEMS(s); l != 0; --l, ++p)
+      {
+        if (*p!=NULL)
+        {
+          pp_Test(*p, lmRing, tailRing);
+          const long k = p_MaxComp(*p, lmRing, tailRing);
+          if (k>j) j = k;
+        }
+      }
+    }
+    return j;
+  }
+  return -1;
+}
+
+BOOLEAN idIsModule(ideal id, ring r)
+{
+  if (id != NULL && rRing_has_Comp(r))
+  {
+    int j, l = IDELEMS(id);
+    for (j=0; j<l; j++)
+    {
+      if (id->m[j] != NULL && p_GetComp(id->m[j], r) > 0) return TRUE;
+    }
+  }
+  return FALSE;
+}
+
+
+/*2
+*returns true if id is homogenous with respect to the aktual weights
+*/
+BOOLEAN id_HomIdeal (ideal id, ideal Q, const ring r)
+{
+  int i;
+  BOOLEAN     b;
+  if ((id == NULL) || (IDELEMS(id) == 0)) return TRUE;
+  i = 0;
+  b = TRUE;
+  while ((i < IDELEMS(id)) && b)
+  {
+    b = p_IsHomogeneous(id->m[i],r);
+    i++;
+  }
+  if ((b) && (Q!=NULL) && (IDELEMS(Q)>0))
+  {
+    i=0;
+    while ((i < IDELEMS(Q)) && b)
+    {
+      b = p_IsHomogeneous(Q->m[i],r);
+      i++;
+    }
+  }
+  return b;
+}
+
+/*2
+*initialized a field with r numbers between beg and end for the
+*procedure idNextChoise
+*/
+void idInitChoise (int r,int beg,int end,BOOLEAN  *endch,int * choise)
+{
+  /*returns the first choise of r numbers between beg and end*/
+  int i;
+  for (i=0; i<r; i++)
+  {
+    choise[i] = 0;
+  }
+  if (r <= end-beg+1)
+    for (i=0; i<r; i++)
+    {
+      choise[i] = beg+i;
+    }
+  if (r > end-beg+1)
+    *endch = TRUE;
+  else
+    *endch = FALSE;
+}
+
+/*2
+*returns the next choise of r numbers between beg and end
+*/
+void idGetNextChoise (int r,int end,BOOLEAN  *endch,int * choise)
+{
+  int i = r-1,j;
+  while ((i >= 0) && (choise[i] == end))
+  {
+    i--;
+    end--;
+  }
+  if (i == -1)
+    *endch = TRUE;
+  else
+  {
+    choise[i]++;
+    for (j=i+1; j<r; j++)
+    {
+      choise[j] = choise[i]+j-i;
+    }
+    *endch = FALSE;
+  }
+}
+
+/*2
+*takes the field choise of d numbers between beg and end, cancels the t-th
+*entree and searches for the ordinal number of that d-1 dimensional field
+* w.r.t. the algorithm of construction
+*/
+int idGetNumberOfChoise(int t, int d, int begin, int end, int * choise)
+{
+  int * localchoise,i,result=0;
+  BOOLEAN b=FALSE;
+
+  if (d<=1) return 1;
+  localchoise=(int*)omAlloc((d-1)*sizeof(int));
+  idInitChoise(d-1,begin,end,&b,localchoise);
+  while (!b)
+  {
+    result++;
+    i = 0;
+    while ((i<t) && (localchoise[i]==choise[i])) i++;
+    if (i>=t)
+    {
+      i = t+1;
+      while ((i<d) && (localchoise[i-1]==choise[i])) i++;
+      if (i>=d)
+      {
+        omFreeSize((ADDRESS)localchoise,(d-1)*sizeof(int));
+        return result;
+      }
+    }
+    idGetNextChoise(d-1,end,&b,localchoise);
+  }
+  omFreeSize((ADDRESS)localchoise,(d-1)*sizeof(int));
+  return 0;
+}
+
+/*2
+*computes the binomial coefficient
+*/
+int binom (int n,int r)
+{
+  int i,result;
+
+  if (r==0) return 1;
+  if (n-r<r) return binom(n,n-r);
+  result = n-r+1;
+  for (i=2;i<=r;i++)
+  {
+    result *= n-r+i;
+    if (result<0)
+    {
+      WarnS("overflow in binomials");
+      return 0;
+    }
+    result /= i;
+  }
+  return result;
+}
+
+/*2
+*the free module of rank i
+*/
+ideal id_FreeModule (int i, const ring r)
+{
+  int j;
+  ideal h;
+
+  h=idInit(i,i);
+  for (j=0; j<i; j++)
+  {
+    h->m[j] = p_One(r);
+    p_SetComp(h->m[j],j+1,r);
+    p_SetmComp(h->m[j],r);
+  }
+  return h;
+}
+
+/*2
+*computes recursively all monomials of a certain degree
+*in every step the actvar-th entry in the exponential
+*vector is incremented and the other variables are
+*computed by recursive calls of makemonoms
+*if the last variable is reached, the difference to the
+*degree is computed directly
+*vars is the number variables
+*actvar is the actual variable to handle
+*deg is the degree of the monomials to compute
+*monomdeg is the actual degree of the monomial in consideration
+*/
+static void makemonoms(int vars,int actvar,int deg,int monomdeg, const ring r)
+{
+  poly p;
+  int i=0;
+
+  if ((idpowerpoint == 0) && (actvar ==1))
+  {
+    idpower[idpowerpoint] = p_One(r);
+    monomdeg = 0;
+  }
+  while (i<=deg)
+  {
+    if (deg == monomdeg)
+    {
+      p_Setm(idpower[idpowerpoint],r);
+      idpowerpoint++;
+      return;
+    }
+    if (actvar == vars)
+    {
+      p_SetExp(idpower[idpowerpoint],actvar,deg-monomdeg,r);
+      p_Setm(idpower[idpowerpoint],r);
+      p_Test(idpower[idpowerpoint],r);
+      idpowerpoint++;
+      return;
+    }
+    else
+    {
+      p = p_Copy(idpower[idpowerpoint],r);
+      makemonoms(vars,actvar+1,deg,monomdeg,r);
+      idpower[idpowerpoint] = p;
+    }
+    monomdeg++;
+    p_SetExp(idpower[idpowerpoint],actvar,p_GetExp(idpower[idpowerpoint],actvar,r)+1,r);
+    p_Setm(idpower[idpowerpoint],r);
+    p_Test(idpower[idpowerpoint],r);
+    i++;
+  }
+}
+
+/*2
+*returns the deg-th power of the maximal ideal of 0
+*/
+ideal id_MaxIdeal(int deg, const ring r)
+{
+  if (deg < 0)
+  {
+    WarnS("maxideal: power must be non-negative");
+  }
+  if (deg < 1)
+  {
+    ideal I=idInit(1,1);
+    I->m[0]=p_One(r);
+    return I;
+  }
+  if (deg == 1)
+  {
+    return id_MaxIdeal(r);
+  }
+
+  int vars = rVar(r);
+  int i = binom(vars+deg-1,deg);
+  if (i<=0) return idInit(1,1);
+  ideal id=idInit(i,1);
+  idpower = id->m;
+  idpowerpoint = 0;
+  makemonoms(vars,1,deg,0,r);
+  idpower = NULL;
+  idpowerpoint = 0;
+  return id;
+}
+
+static void id_NextPotence(ideal given, ideal result,
+  int begin, int end, int deg, int restdeg, poly ap, const ring r)
+{
+  poly p;
+  int i;
+
+  p = p_Power(p_Copy(given->m[begin],r),restdeg,r);
+  i = result->nrows;
+  result->m[i] = p_Mult_q(p_Copy(ap,r),p,r);
+//PrintS(".");
+  (result->nrows)++;
+  if (result->nrows >= IDELEMS(result))
+  {
+    pEnlargeSet(&(result->m),IDELEMS(result),16);
+    IDELEMS(result) += 16;
+  }
+  if (begin == end) return;
+  for (i=restdeg-1;i>0;i--)
+  {
+    p = p_Power(p_Copy(given->m[begin],r),i,r);
+    p = p_Mult_q(p_Copy(ap,r),p,r);
+    id_NextPotence(given, result, begin+1, end, deg, restdeg-i, p,r);
+    p_Delete(&p,r);
+  }
+  id_NextPotence(given, result, begin+1, end, deg, restdeg, ap,r);
+}
+
+ideal id_Power(ideal given,int exp, const ring r)
+{
+  ideal result,temp;
+  poly p1;
+  int i;
+
+  if (idIs0(given)) return idInit(1,1);
+  temp = id_Copy(given,r);
+  idSkipZeroes(temp);
+  i = binom(IDELEMS(temp)+exp-1,exp);
+  result = idInit(i,1);
+  result->nrows = 0;
+//Print("ideal contains %d elements\n",i);
+  p1=p_One(r);
+  id_NextPotence(temp,result,0,IDELEMS(temp)-1,exp,exp,p1,r);
+  p_Delete(&p1,r);
+  id_Delete(&temp,r);
+  result->nrows = 1;
+  id_DelEquals(result,r);
+  idSkipZeroes(result);
+  return result;
+}
+
+/*2
+*skips all zeroes and double elements, searches also for units
+*/
+void id_Compactify(ideal id, const ring r)
+{
+  int i;
+  BOOLEAN b=FALSE;
+
+  i = IDELEMS(id)-1;
+  while ((! b) && (i>=0))
+  {
+    b=p_IsUnit(id->m[i],r);
+    i--;
+  }
+  if (b)
+  {
+    for(i=IDELEMS(id)-1;i>=0;i--) p_Delete(&id->m[i],r);
+    id->m[0]=p_One(r);
+  }
+  else
+  {
+    id_DelMultiples(id,r);
+  }
+  idSkipZeroes(id);
+}
+
+/*2
+* returns the ideals of initial terms
+*/
+ideal id_Head(ideal h,const ring r)
+{
+  ideal m = idInit(IDELEMS(h),h->rank);
+  int i;
+
+  for (i=IDELEMS(h)-1;i>=0; i--)
+  {
+    if (h->m[i]!=NULL) m->m[i]=p_Head(h->m[i],r);
+  }
+  return m;
+}
+
+ideal id_Homogen(ideal h, int varnum,const ring r)
+{
+  ideal m = idInit(IDELEMS(h),h->rank);
+  int i;
+
+  for (i=IDELEMS(h)-1;i>=0; i--)
+  {
+    m->m[i]=p_Homogen(h->m[i],varnum,r);
+  }
+  return m;
+}
+
+/*------------------type conversions----------------*/
+ideal id_Vec2Ideal(poly vec, const ring R)
+{
+   ideal result=idInit(1,1);
+   omFree((ADDRESS)result->m);
+   result->m=NULL; // remove later
+   p_Vec2Polys(vec, &(result->m), &(IDELEMS(result)),R);
+   return result;
+}
+
+
+// converts mat to module, destroys mat
+ideal id_Matrix2Module(matrix mat, const ring R)
+{
+  int mc=MATCOLS(mat);
+  int mr=MATROWS(mat);
+  ideal result = idInit(si_max(mc,1),si_max(mr,1));
+  int i,j,l;
+  poly h;
+  sBucket_pt bucket = sBucketCreate(R);
+
+  for(j=0;j<mc /*MATCOLS(mat)*/;j++) /* j is also index in result->m */
+  {
+    for (i=1;i<=mr /*MATROWS(mat)*/;i++)
+    {
+      h = MATELEM(mat,i,j+1);
+      if (h!=NULL)
+      {
+        l=pLength(h);
+        MATELEM(mat,i,j+1)=NULL;
+        p_SetCompP(h,i, R);
+        sBucket_Merge_p(bucket, h, l);
+      }
+    }
+    sBucketClearMerge(bucket, &(result->m[j]), &l);
+  }
+  sBucketDestroy(&bucket);
+
+  // obachman: need to clean this up
+  id_Delete((ideal*) &mat,R);
+  return result;
+}
+
+/*2
+* converts a module into a matrix, destroyes the input
+*/
+matrix id_Module2Matrix(ideal mod, const ring R)
+{
+  matrix result = mpNew(mod->rank,IDELEMS(mod));
+  long i; long cp;
+  poly p,h;
+
+  for(i=0;i<IDELEMS(mod);i++)
+  {
+    p=pReverse(mod->m[i]);
+    mod->m[i]=NULL;
+    while (p!=NULL)
+    {
+      h=p;
+      pIter(p);
+      pNext(h)=NULL;
+      cp = si_max((long)1,p_GetComp(h, R));     // if used for ideals too
+      //cp = p_GetComp(h,R);
+      p_SetComp(h,0,R);
+      p_SetmComp(h,R);
+#ifdef TEST
+      if (cp>mod->rank)
+      {
+        Print("## inv. rank %ld -> %ld\n",mod->rank,cp);
+        int k,l,o=mod->rank;
+        mod->rank=cp;
+        matrix d=mpNew(mod->rank,IDELEMS(mod));
+        for (l=1; l<=o; l++)
+        {
+          for (k=1; k<=IDELEMS(mod); k++)
+          {
+            MATELEM(d,l,k)=MATELEM(result,l,k);
+            MATELEM(result,l,k)=NULL;
+          }
+        }
+        id_Delete((ideal *)&result,R);
+        result=d;
+      }
+#endif
+      MATELEM(result,cp,i+1) = p_Add_q(MATELEM(result,cp,i+1),h,R);
+    }
+  }
+  // obachman 10/99: added the following line, otherwise memory leack!
+  id_Delete(&mod,R);
+  return result;
+}
+
+matrix id_Module2formatedMatrix(ideal mod,int rows, int cols, const ring R)
+{
+  matrix result = mpNew(rows,cols);
+  int i,cp,r=id_RankFreeModule(mod,R),c=IDELEMS(mod);
+  poly p,h;
+
+  if (r>rows) r = rows;
+  if (c>cols) c = cols;
+  for(i=0;i<c;i++)
+  {
+    p=pReverse(mod->m[i]);
+    mod->m[i]=NULL;
+    while (p!=NULL)
+    {
+      h=p;
+      pIter(p);
+      pNext(h)=NULL;
+      cp = p_GetComp(h,R);
+      if (cp<=r)
+      {
+        p_SetComp(h,0,R);
+        p_SetmComp(h,R);
+        MATELEM(result,cp,i+1) = p_Add_q(MATELEM(result,cp,i+1),h,R);
+      }
+      else
+        p_Delete(&h,R);
+    }
+  }
+  id_Delete(&mod,R);
+  return result;
+}
+
+/*2
+* substitute the n-th variable by the monomial e in id
+* destroy id
+*/
+ideal  id_Subst(ideal id, int n, poly e, const ring r)
+{
+  int k=MATROWS((matrix)id)*MATCOLS((matrix)id);
+  ideal res=(ideal)mpNew(MATROWS((matrix)id),MATCOLS((matrix)id));
+
+  res->rank = id->rank;
+  for(k--;k>=0;k--)
+  {
+    res->m[k]=p_Subst(id->m[k],n,e,r);
+    id->m[k]=NULL;
+  }
+  id_Delete(&id,r);
+  return res;
+}
+
+BOOLEAN id_HomModule(ideal m, ideal Q, intvec **w, const ring R)
+{
+  if (w!=NULL) *w=NULL;
+  if ((Q!=NULL) && (!id_HomIdeal(Q,NULL,R))) return FALSE;
+  if (idIs0(m))
+  {
+    if (w!=NULL) (*w)=new intvec(m->rank);
+    return TRUE;
+  }
+
+  long cmax=1,order=0,ord,* diff,diffmin=32000;
+  int *iscom;
+  int i;
+  poly p=NULL;
+  pFDegProc d;
+  if (R->pLexOrder && (R->order[0]==ringorder_lp))
+     d=p_Totaldegree;
+  else
+     d=R->pFDeg;
+  int length=IDELEMS(m);
+  poly* P=m->m;
+  poly* F=(poly*)omAlloc(length*sizeof(poly));
+  for (i=length-1;i>=0;i--)
+  {
+    p=F[i]=P[i];
+    cmax=si_max(cmax,(long)p_MaxComp(p,R));
+  }
+  cmax++;
+  diff = (long *)omAlloc0(cmax*sizeof(long));
+  if (w!=NULL) *w=new intvec(cmax-1);
+  iscom = (int *)omAlloc0(cmax*sizeof(int));
+  i=0;
+  while (i<=length)
+  {
+    if (i<length)
+    {
+      p=F[i];
+      while ((p!=NULL) && (iscom[p_GetComp(p,R)]==0)) pIter(p);
+    }
+    if ((p==NULL) && (i<length))
+    {
+      i++;
+    }
+    else
+    {
+      if (p==NULL) /* && (i==length) */
+      {
+        i=0;
+        while ((i<length) && (F[i]==NULL)) i++;
+        if (i>=length) break;
+        p = F[i];
+      }
+      //if (pLexOrder && (currRing->order[0]==ringorder_lp))
+      //  order=pTotaldegree(p);
+      //else
+      //  order = p->order;
+      //  order = pFDeg(p,currRing);
+      order = d(p,R) +diff[p_GetComp(p,R)];
+      //order += diff[pGetComp(p)];
+      p = F[i];
+//Print("Actual p=F[%d]: ",i);pWrite(p);
+      F[i] = NULL;
+      i=0;
+    }
+    while (p!=NULL)
+    {
+      if (R->pLexOrder && (R->order[0]==ringorder_lp))
+        ord=p_Totaldegree(p,R);
+      else
+      //  ord = p->order;
+        ord = R->pFDeg(p,R);
+      if (iscom[p_GetComp(p,R)]==0)
+      {
+        diff[p_GetComp(p,R)] = order-ord;
+        iscom[p_GetComp(p,R)] = 1;
+/*
+*PrintS("new diff: ");
+*for (j=0;j<cmax;j++) Print("%d ",diff[j]);
+*PrintLn();
+*PrintS("new iscom: ");
+*for (j=0;j<cmax;j++) Print("%d ",iscom[j]);
+*PrintLn();
+*Print("new set %d, order %d, ord %d, diff %d\n",pGetComp(p),order,ord,diff[pGetComp(p)]);
+*/
+      }
+      else
+      {
+/*
+*PrintS("new diff: ");
+*for (j=0;j<cmax;j++) Print("%d ",diff[j]);
+*PrintLn();
+*Print("order %d, ord %d, diff %d\n",order,ord,diff[pGetComp(p)]);
+*/
+        if (order != (ord+diff[p_GetComp(p,R)]))
+        {
+          omFreeSize((ADDRESS) iscom,cmax*sizeof(int));
+          omFreeSize((ADDRESS) diff,cmax*sizeof(long));
+          omFreeSize((ADDRESS) F,length*sizeof(poly));
+          delete *w;*w=NULL;
+          return FALSE;
+        }
+      }
+      pIter(p);
+    }
+  }
+  omFreeSize((ADDRESS) iscom,cmax*sizeof(int));
+  omFreeSize((ADDRESS) F,length*sizeof(poly));
+  for (i=1;i<cmax;i++) (**w)[i-1]=(int)(diff[i]);
+  for (i=1;i<cmax;i++)
+  {
+    if (diff[i]<diffmin) diffmin=diff[i];
+  }
+  if (w!=NULL)
+  {
+    for (i=1;i<cmax;i++)
+    {
+      (**w)[i-1]=(int)(diff[i]-diffmin);
+    }
+  }
+  omFreeSize((ADDRESS) diff,cmax*sizeof(long));
+  return TRUE;
+}
+
+ideal id_Jet(ideal i,int d, const ring R)
+{
+  ideal r=idInit((i->nrows)*(i->ncols),i->rank);
+  r->nrows = i-> nrows;
+  r->ncols = i-> ncols;
+  //r->rank = i-> rank;
+  int k;
+  for(k=(i->nrows)*(i->ncols)-1;k>=0; k--)
+  {
+    r->m[k]=pp_Jet(i->m[k],d,R);
+  }
+  return r;
+}
+
+ideal id_JetW(ideal i,int d, intvec * iv, const ring R)
+{
+  ideal r=idInit(IDELEMS(i),i->rank);
+  if (ecartWeights!=NULL)
+  {
+    WerrorS("cannot compute weighted jets now");
+  }
+  else
+  {
+    short *w=iv2array(iv,R);
+    int k;
+    for(k=0; k<IDELEMS(i); k++)
+    {
+      r->m[k]=pp_JetW(i->m[k],d,w,R);
+    }
+    omFreeSize((ADDRESS)w,(rVar(R)+1)*sizeof(short));
+  }
+  return r;
+}
+
+/*3
+* searches for the next unit in the components of the module arg and
+* returns the first one;
+*/
+int id_ReadOutPivot(ideal arg,int* comp, const ring r)
+{
+  if (idIs0(arg)) return -1;
+  int i=0,j, generator=-1;
+  int rk_arg=arg->rank; //idRankFreeModule(arg);
+  int * componentIsUsed =(int *)omAlloc((rk_arg+1)*sizeof(int));
+  poly p;
+
+  while ((generator<0) && (i<IDELEMS(arg)))
+  {
+    memset(componentIsUsed,0,(rk_arg+1)*sizeof(int));
+    p = arg->m[i];
+    while (p!=NULL)
+    {
+      j = p_GetComp(p,r);
+      if (componentIsUsed[j]==0)
+      {
+#ifdef HAVE_RINGS
+        if (p_LmIsConstantComp(p,r) &&
+            (!rField_is_Ring(r) || n_IsUnit(pGetCoeff(p),r->cf)))
+        {
+#else
+        if (p_LmIsConstantComp(p,r))
+        {
+#endif
+          generator = i;
+          componentIsUsed[j] = 1;
+        }
+        else
+        {
+          componentIsUsed[j] = -1;
+        }
+      }
+      else if (componentIsUsed[j]>0)
+      {
+        (componentIsUsed[j])++;
+      }
+      pIter(p);
+    }
+    i++;
+  }
+  i = 0;
+  *comp = -1;
+  for (j=0;j<=rk_arg;j++)
+  {
+    if (componentIsUsed[j]>0)
+    {
+      if ((*comp==-1) || (componentIsUsed[j]<i))
+      {
+        *comp = j;
+        i= componentIsUsed[j];
+      }
+    }
+  }
+  omFree(componentIsUsed);
+  return generator;
+}
+
+#if 0
+static void idDeleteComp(ideal arg,int red_comp)
+{
+  int i,j;
+  poly p;
+
+  for (i=IDELEMS(arg)-1;i>=0;i--)
+  {
+    p = arg->m[i];
+    while (p!=NULL)
+    {
+      j = pGetComp(p);
+      if (j>red_comp)
+      {
+        pSetComp(p,j-1);
+        pSetm(p);
+      }
+      pIter(p);
+    }
+  }
+  (arg->rank)--;
+}
+#endif
+
+intvec * id_QHomWeight(ideal id, const ring r)
+{
+  poly head, tail;
+  int k;
+  int in=IDELEMS(id)-1, ready=0, all=0,
+      coldim=rVar(r), rowmax=2*coldim;
+  if (in<0) return NULL;
+  intvec *imat=new intvec(rowmax+1,coldim,0);
+
+  do
+  {
+    head = id->m[in--];
+    if (head!=NULL)
+    {
+      tail = pNext(head);
+      while (tail!=NULL)
+      {
+        all++;
+        for (k=1;k<=coldim;k++)
+          IMATELEM(*imat,all,k) = p_GetExpDiff(head,tail,k,r);
+        if (all==rowmax)
+        {
+          ivTriangIntern(imat, ready, all);
+          if (ready==coldim)
+          {
+            delete imat;
+            return NULL;
+          }
+        }
+        pIter(tail);
+      }
+    }
+  } while (in>=0);
+  if (all>ready)
+  {
+    ivTriangIntern(imat, ready, all);
+    if (ready==coldim)
+    {
+      delete imat;
+      return NULL;
+    }
+  }
+  intvec *result = ivSolveKern(imat, ready);
+  delete imat;
+  return result;
+}
+
+BOOLEAN id_IsZeroDim(ideal I, const ring r)
+{
+  BOOLEAN *UsedAxis=(BOOLEAN *)omAlloc0(rVar(r)*sizeof(BOOLEAN));
+  int i,n;
+  poly po;
+  BOOLEAN res=TRUE;
+  for(i=IDELEMS(I)-1;i>=0;i--)
+  {
+    po=I->m[i];
+    if ((po!=NULL) &&((n=p_IsPurePower(po,r))!=0)) UsedAxis[n-1]=TRUE;
+  }
+  for(i=rVar(r)-1;i>=0;i--)
+  {
+    if(UsedAxis[i]==FALSE) {res=FALSE; break;} // not zero-dim.
+  }
+  omFreeSize(UsedAxis,rVar(r)*sizeof(BOOLEAN));
+  return res;
+}
+
+void id_Normalize(ideal I,const ring r) /* for ideal/matrix */
+{
+  if (rField_has_simple_inverse(r)) return; /* Z/p, GF(p,n), R, long R/C */
+  int i;
+  for(i=I->nrows*I->ncols-1;i>=0;i--)
+  {
+    p_Normalize(I->m[i],r);
+  }
+}
+
+int id_MinDegW(ideal M,intvec *w, const ring r)
+{
+  int d=-1;
+  for(int i=0;i<IDELEMS(M);i++)
+  {
+    if (M->m[i]!=NULL)
+    {
+      int d0=p_MinDeg(M->m[i],w,r);
+      if(-1<d0&&((d0<d)||(d==-1)))
+        d=d0;
+    }
+  }
+  return d;
+}
+
+// #include <kernel/clapsing.h>
+
+/*2
+* transpose a module
+*/
+ideal id_Transp(ideal a, const ring rRing)
+{
+  int r = a->rank, c = IDELEMS(a);
+  ideal b =  idInit(r,c);
+
+  for (int i=c; i>0; i--)
+  {
+    poly p=a->m[i-1];
+    while(p!=NULL)
+    {
+      poly h=p_Head(p, rRing);
+      int co=p_GetComp(h, rRing)-1;
+      p_SetComp(h, i, rRing);
+      p_Setm(h, rRing);
+      b->m[co] = p_Add_q(b->m[co], h, rRing);
+      pIter(p);
+    }
+  }
+  return b;
+}
+
+
+
+/*2
+* The following is needed to compute the image of certain map used in
+* the computation of cohomologies via BGG
+* let M = { w_1, ..., w_k }, k = size(M) == ncols(M), n = nvars(currRing).
+* assuming that nrows(M) <= m*n; the procedure computes:
+* transpose(M) * transpose( var(1) I_m | ... | var(n) I_m ) :== transpose(module{f_1, ... f_k}),
+* where f_i = \sum_{j=1}^{m} (w_i, v_j) gen(j),  (w_i, v_j) is a `scalar` multiplication.
+* that is, if w_i = (a^1_1, ... a^1_m) | (a^2_1, ..., a^2_m) | ... | (a^n_1, ..., a^n_m) then
+
+  (a^1_1, ... a^1_m) | (a^2_1, ..., a^2_m) | ... | (a^n_1, ..., a^n_m)
+*  var_1  ... var_1  |  var_2  ...  var_2  | ... |  var_n  ...  var(n)
+*  gen_1  ... gen_m  |  gen_1  ...  gen_m  | ... |  gen_1  ...  gen_m
++ =>
+  f_i =
+
+   a^1_1 * var(1) * gen(1) + ... + a^1_m * var(1) * gen(m) +
+   a^2_1 * var(2) * gen(1) + ... + a^2_m * var(2) * gen(m) +
+                             ...
+   a^n_1 * var(n) * gen(1) + ... + a^n_m * var(n) * gen(m);
+
+   NOTE: for every f_i we run only ONCE along w_i saving partial sums into a temporary array of polys of size m
+*/
+ideal id_TensorModuleMult(const int m, const ideal M, const ring rRing)
+{
+// #ifdef DEBU
+//  WarnS("tensorModuleMult!!!!");
+
+  assume(m > 0);
+  assume(M != NULL);
+
+  const int n = rRing->N;
+
+  assume(M->rank <= m * n);
+
+  const int k = IDELEMS(M);
+
+  ideal idTemp =  idInit(k,m); // = {f_1, ..., f_k }
+
+  for( int i = 0; i < k; i++ ) // for every w \in M
+  {
+    poly pTempSum = NULL;
+
+    poly w = M->m[i];
+
+    while(w != NULL) // for each term of w...
+    {
+      poly h = p_Head(w, rRing);
+
+      const int  gen = p_GetComp(h, rRing); // 1 ...
+
+      assume(gen > 0);
+      assume(gen <= n*m);
+
+      // TODO: write a formula with %, / instead of while!
+      /*
+      int c = gen;
+      int v = 1;
+      while(c > m)
+      {
+        c -= m;
+        v++;
+      }
+      */
+
+      int cc = gen % m;
+      if( cc == 0) cc = m;
+      int vv = 1 + (gen - cc) / m;
+
+//      assume( cc == c );
+//      assume( vv == v );
+
+      //  1<= c <= m
+      assume( cc > 0 );
+      assume( cc <= m );
+
+      assume( vv > 0 );
+      assume( vv <= n );
+
+      assume( (cc + (vv-1)*m) == gen );
+
+      p_IncrExp(h, vv, rRing); // h *= var(j) && //      p_AddExp(h, vv, 1, rRing);
+      p_SetComp(h, cc, rRing);
+
+      p_Setm(h, rRing);         // addjust degree after the previous steps!
+
+      pTempSum = p_Add_q(pTempSum, h, rRing); // it is slow since h will be usually put to the back of pTempSum!!!
+
+      pIter(w);
+    }
+
+    idTemp->m[i] = pTempSum;
+  }
+
+  // simplify idTemp???
+
+  ideal idResult = id_Transp(idTemp, rRing);
+
+  id_Delete(&idTemp, rRing);
+
+  return(idResult);
+}
+
+ideal id_ChineseRemainder(ideal *xx, number *q, int rl, const ring r)
+{
+  int cnt=IDELEMS(xx[0])*xx[0]->nrows;
+  ideal result=idInit(cnt,xx[0]->rank);
+  result->nrows=xx[0]->nrows; // for lifting matrices
+  result->ncols=xx[0]->ncols; // for lifting matrices
+  int i,j;
+  number *x=(number *)omAlloc(rl*sizeof(number));
+  poly *p=(poly *)omAlloc(rl*sizeof(poly));
+  for(i=cnt-1;i>=0;i--)
+  {
+    for(j=rl-1;j>=0;j--)
+    {
+      p[j]=xx[j]->m[i];
+    }
+    result->m[i]=p_ChineseRemainder(p,x,q,rl,r);
+    for(j=rl-1;j>=0;j--)
+    {
+      xx[j]->m[i]=p[j];
+    }
+  }
+  omFreeSize(p,rl*sizeof(poly));
+  omFreeSize(x,rl*sizeof(number));
+  for(i=rl-1;i>=0;i--) id_Delete(&(xx[i]),r);
+  omFreeSize(xx,rl*sizeof(ideal));
+  return result;
+}
diff --git a/libpolys/polys/simpleideals.h b/libpolys/polys/simpleideals.h
new file mode 100644
index 0000000..dfd244f
--- /dev/null
+++ b/libpolys/polys/simpleideals.h
@@ -0,0 +1,154 @@
+#ifndef SIMPLEIDEALS_H
+#define SIMPLEIDEALS_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT - all basic methods to manipulate ideals
+*/
+#include <omalloc/omalloc.h>
+#include <polys/monomials/ring.h>
+#include <polys/matpol.h>
+
+struct sip_sideal
+{
+  poly*  m;
+  long rank;
+  int nrows;
+  int ncols;
+  #define IDELEMS(i) ((i)->ncols)
+  #define MATCOLS(i) ((i)->ncols)
+  #define MATROWS(i) ((i)->nrows)
+  #define MATELEM(mat,i,j) ((mat)->m)[MATCOLS((mat)) * ((i)-1) + (j)-1]
+
+};
+
+struct sip_smap
+{
+  poly *m;
+  char *preimage;
+  int nrows;
+  int ncols;
+};
+
+struct sideal_list;
+typedef struct sideal_list *      ideal_list;
+
+struct sideal_list
+{
+  ideal_list next;
+  ideal      d;
+#ifndef SING_NDEBUG
+  int nr;
+#endif
+};
+
+extern omBin sip_sideal_bin;
+
+/*- creates an ideal -*/
+ideal idInit (int size, int rank=1);
+
+/*- deletes an ideal -*/
+void id_Delete (ideal* h, ring r);
+void id_ShallowDelete (ideal* h, ring r);
+void idSkipZeroes (ideal ide);
+  /*gives an ideal the minimal possible size*/
+
+/// number of non-zero polys in F
+int     idElem(const ideal F);
+/// normialize all polys in id
+void    id_Normalize(ideal id, const ring r);
+
+int id_MinDegW(ideal M,intvec *w, const ring r);
+
+#ifdef PDEBUG
+void id_DBTest(ideal h1, int level, const char *f,const int l, const ring lR, const ring tR );
+#define id_TestTail(A, lR, tR) id_DBTest(A, PDEBUG, __FILE__,__LINE__, lR, tR)
+#define id_Test(A, lR) id_DBTest(A, PDEBUG, __FILE__,__LINE__, lR, lR)
+#else
+#define id_TestTail(A, lR, tR)  do {} while (0)
+#define id_Test(A, lR) do {} while (0)
+#endif
+
+ideal id_Copy (ideal h1,const ring r);
+
+  /*adds two ideals without simplifying the result*/
+ideal id_SimpleAdd (ideal h1,ideal h2, const ring r);
+  /*adds the quotient ideal*/
+ideal id_Add (ideal h1,ideal h2,const ring r);
+  /* h1 + h2 */
+
+ideal id_Power(ideal given,int exp, const ring r);
+BOOLEAN idIs0 (ideal h);
+
+long id_RankFreeModule(ideal m, ring lmRing, ring tailRing);
+static inline long id_RankFreeModule(ideal m, ring r)
+{return id_RankFreeModule(m, r, r);}
+// returns TRUE, if idRankFreeModule(m) > 0
+BOOLEAN id_IsModule(ideal m, ring r);
+ideal   id_FreeModule (int i, const ring r);
+int     idElem(const ideal F);
+int id_PosConstant(ideal id, const ring r);
+ideal id_Head(ideal h,const ring r);
+ideal id_MaxIdeal (const ring r);
+ideal id_MaxIdeal(int deg, const ring r);
+ideal id_CopyFirstK (const ideal ide, const int k,const ring r);
+void id_DelMultiples(ideal id, const ring r);
+void id_Norm(ideal id, const ring r);
+void id_DelEquals(ideal id, const ring r);
+void id_DelLmEquals(ideal id, const ring r);
+void id_DelDiv(ideal id, const ring r);
+BOOLEAN id_IsConstant(ideal id, const ring r);
+
+/// sorts the ideal w.r.t. the actual ringordering
+/// uses lex-ordering when nolex = FALSE
+intvec *id_Sort(const ideal id, const BOOLEAN nolex, const ring r);
+
+ideal id_Transp(ideal a, const ring rRing);
+void id_Compactify(ideal id, const ring r);
+ideal  id_Mult (ideal h1,ideal  h2, const ring r);
+ideal id_Homogen(ideal h, int varnum,const ring r);
+BOOLEAN id_HomIdeal (ideal id, ideal Q, const ring r);
+BOOLEAN id_HomModule(ideal m, ideal Q, intvec **w, const ring R);
+BOOLEAN id_IsZeroDim(ideal I, const ring r);
+ideal id_Jet(ideal i,int d, const ring R);
+ideal id_JetW(ideal i,int d, intvec * iv, const ring R);
+ideal  id_Subst(ideal id, int n, poly e, const ring r);
+matrix id_Module2Matrix(ideal mod, const ring R);
+matrix id_Module2formatedMatrix(ideal mod,int rows, int cols, const ring R);
+ideal id_Matrix2Module(matrix mat, const ring R);
+ideal id_Vec2Ideal(poly vec, const ring R);
+
+int id_ReadOutPivot(ideal arg, int* comp, const ring r);
+
+int     binom (int n,int r);
+
+  /*- verschiebt die Indizes der Modulerzeugenden um i -*/
+void    idInitChoise (int r,int beg,int end,BOOLEAN *endch,int * choise);
+void    idGetNextChoise (int r,int end,BOOLEAN *endch,int * choise);
+int     idGetNumberOfChoise(int t, int d, int begin, int end, int * choise);
+
+#ifdef PDEBUG
+void idShow(const ideal id, const ring lmRing, const ring tailRing, const int debugPrint = 0);
+#define id_Print(id, lR, tR) idShow(id, lR, tR)
+#else
+#define id_Print(A, lR, tR) do {} while (0)
+#endif
+
+
+
+/// insert h2 into h1 depending on the two boolean parameters:
+/// - if zeroOk is true, then h2 will also be inserted when it is zero
+/// - if duplicateOk is true, then h2 will also be inserted when it is
+///   already present in h1
+/// return TRUE iff h2 was indeed inserted
+BOOLEAN id_InsertPolyWithTests (ideal h1, const int validEntries,
+                                const poly h2, const bool zeroOk,
+                                const bool duplicateOk, const ring r);
+
+
+intvec * id_QHomWeight(ideal id, const ring r);
+
+
+ideal id_ChineseRemainder(ideal *xx, number *q, int rl, const ring r);
+#endif
diff --git a/libpolys/polys/sparsmat.cc b/libpolys/polys/sparsmat.cc
new file mode 100644
index 0000000..4ab5db9
--- /dev/null
+++ b/libpolys/polys/sparsmat.cc
@@ -0,0 +1,2958 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+
+/*
+* ABSTRACT: operations with sparse matrices (bareiss, ...)
+*/
+
+
+
+
+#include <misc/auxiliary.h>
+
+#include <omalloc/omalloc.h>
+#include <misc/mylimits.h>
+
+#include <misc/options.h>
+
+#include <reporter/reporter.h>
+#include <misc/intvec.h>
+
+#include <coeffs/numbers.h>
+#include "coeffrings.h"
+
+#include "monomials/ring.h"
+#include "monomials/p_polys.h"
+
+#include "simpleideals.h"
+
+
+#include "sparsmat.h"
+#include "prCopy.h"
+
+#include "templates/p_Procs.h"
+
+#include "kbuckets.h"
+#include "operations/p_Mult_q.h"
+
+// define SM_NO_BUCKETS, if sparsemat stuff should not use buckets
+// #define SM_NO_BUCKETS
+
+// this is also influenced by TEST_OPT_NOTBUCKETS
+#ifndef SM_NO_BUCKETS
+// buckets do carry a small additional overhead: only use them if
+// min-length of polys is >= SM_MIN_LENGTH_BUCKET
+#define SM_MIN_LENGTH_BUCKET MIN_LENGTH_BUCKET - 5
+#else
+#define SM_MIN_LENGTH_BUCKET    MAX_INT_VAL
+#endif
+
+typedef struct smprec sm_prec;
+typedef sm_prec * smpoly;
+struct smprec
+{
+  smpoly n;            // the next element
+  int pos;             // position
+  int e;               // level
+  poly m;              // the element
+  float f;             // complexity of the element
+};
+
+
+/* declare internal 'C' stuff */
+static void sm_ExactPolyDiv(poly, poly, const ring);
+static BOOLEAN sm_IsNegQuot(poly, const poly, const poly, const ring);
+static void sm_ExpMultDiv(poly, const poly, const poly, const ring);
+static void sm_PolyDivN(poly, const number, const ring);
+static BOOLEAN smSmaller(poly, poly);
+static void sm_CombineChain(poly *, poly, const ring);
+static void sm_FindRef(poly *, poly *, poly, const ring);
+
+static void sm_ElemDelete(smpoly *, const ring);
+static smpoly smElemCopy(smpoly);
+static float sm_PolyWeight(smpoly, const ring);
+static smpoly sm_Poly2Smpoly(poly, const ring);
+static poly sm_Smpoly2Poly(smpoly, const ring);
+static BOOLEAN sm_HaveDenom(poly, const ring);
+static number sm_Cleardenom(ideal, const ring);
+
+omBin smprec_bin = omGetSpecBin(sizeof(smprec));
+
+static poly pp_Mult_Coeff_mm_DivSelect_MultDiv(poly p, int &lp, poly m,
+                                               poly a, poly b, const ring currRing)
+{
+  if (rOrd_is_Comp_dp(currRing) && currRing->ExpL_Size > 2)
+  {
+    // pp_Mult_Coeff_mm_DivSelectMult only works for (c/C,dp) and
+    // ExpL_Size > 2
+    // should be generalized, at least to dp with ExpL_Size == 2
+    // (is the case for 1 variable)
+    int shorter;
+    p = currRing->p_Procs->pp_Mult_Coeff_mm_DivSelectMult(p, m, a, b,
+                                                          shorter, currRing);
+    lp -= shorter;
+  }
+  else
+  {
+    p = pp_Mult_Coeff_mm_DivSelect(p, lp, m, currRing);
+    sm_ExpMultDiv(p, a, b, currRing);
+  }
+  return p;
+}
+
+static poly sm_SelectCopy_ExpMultDiv(poly p, poly m, poly a, poly b, const ring currRing)
+{
+  int lp = 0;
+  return pp_Mult_Coeff_mm_DivSelect_MultDiv(p, lp, m, a, b, currRing);
+}
+
+
+/* class for sparse matrix:
+*      3 parts of matrix during the algorithm
+*      m_act[cols][pos(rows)] => m_row[rows][pos(cols)] => m_res[cols][pos(rows)]
+*      input                     pivotcols as rows         result
+*      pivot                     like a stack              from pivot and pivotcols
+*      elimination                                         rows reordered according
+*                                                          to pivot choise
+*                                                          stored in perm
+*      a step is as follows
+*      - search of pivot (smPivot)
+*      - swap pivot column and last column (smSwapC)
+*        select pivotrow to piv and red (smSelectPR)
+*        consider sign
+*      - elimination (smInitElim, sm0Elim, sm1Elim)
+*        clear zero column as result of elimination (smZeroElim)
+*      - tranfer from
+*        piv and m_row to m_res (smRowToCol)
+*        m_act to m_row (smColToRow)
+*/
+class sparse_mat{
+private:
+  int nrows, ncols;    // dimension of the problem
+  int sign;            // for determinant (start: 1)
+  int act;             // number of unreduced columns (start: ncols)
+  int crd;             // number of reduced columns (start: 0)
+  int tored;           // border for rows to reduce
+  int inred;           // unreducable part
+  int rpiv, cpiv;      // position of the pivot
+  int normalize;       // Normalization flag
+  int *perm;           // permutation of rows
+  float wpoints;       // weight of all points
+  float *wrw, *wcl;    // weights of rows and columns
+  smpoly * m_act;      // unreduced columns
+  smpoly * m_res;      // reduced columns (result)
+  smpoly * m_row;      // reduced part of rows
+  smpoly red;          // row to reduce
+  smpoly piv, oldpiv;  // pivot and previous pivot
+  smpoly dumm;         // allocated dummy
+  ring _R;
+
+  void smColToRow();
+  void smRowToCol();
+  void smFinalMult();
+  void smSparseHomog();
+  void smWeights();
+  void smPivot();
+  void smNewWeights();
+  void smNewPivot();
+  void smZeroElim();
+  void smToredElim();
+  void smCopToRes();
+  void smSelectPR();
+  void sm1Elim();
+  void smHElim();
+  void smMultCol();
+  poly smMultPoly(smpoly);
+  void smActDel();
+  void smColDel();
+  void smPivDel();
+  void smSign();
+  void smInitPerm();
+  int smCheckNormalize();
+  void smNormalize();
+public:
+  sparse_mat(ideal, const ring);
+  ~sparse_mat();
+  int smGetSign() { return sign; }
+  smpoly * smGetAct() { return m_act; }
+  int smGetRed() { return tored; }
+  ideal smRes2Mod();
+  poly smDet();
+  void smNewBareiss(int, int);
+  void smToIntvec(intvec *);
+};
+
+/*
+* estimate maximal exponent for det or minors,
+* the module m has di vectors and maximal rank ra,
+* estimate yields for the tXt minors,
+* we have di,ra >= t
+*/
+static void smMinSelect(long *, int, int);
+
+long sm_ExpBound( ideal m, int di, int ra, int t, const ring currRing)
+{
+  poly p;
+  long kr, kc;
+  long *r, *c;
+  int al, bl, i, j, k;
+
+  if (ra==0) ra=1;
+  al = di*sizeof(long);
+  c = (long *)omAlloc(al);
+  bl = ra*sizeof(long);
+  r = (long *)omAlloc0(bl);
+  for (i=di-1;i>=0;i--)
+  {
+    kc = 0;
+    p = m->m[i];
+    while(p!=NULL)
+    {
+      k = p_GetComp(p, currRing)-1;
+      kr = r[k];
+      for (j=rVar(currRing);j>0;j--)
+      {
+        if(p_GetExp(p,j, currRing)>kc)
+          kc=p_GetExp(p,j, currRing);
+        if(p_GetExp(p,j, currRing)>kr)
+          kr=p_GetExp(p,j, currRing);
+      }
+      r[k] = kr;
+      pIter(p);
+    }
+    c[i] = kc;
+  }
+  if (t<di) smMinSelect(c, t, di);
+  if (t<ra) smMinSelect(r, t, ra);
+  kr = kc = 0;
+  for (j=t-1;j>=0;j--)
+  {
+    kr += r[j];
+    kc += c[j];
+  }
+  omFreeSize((ADDRESS)c, al);
+  omFreeSize((ADDRESS)r, bl);
+  if (kr<kc) kc = kr;
+  if (kr<1) kr = 1;
+  return kr;
+}
+
+static void smMinSelect(long *c, int t, int d)
+{
+  long m;
+  int pos, i;
+  do
+  {
+    d--;
+    pos = d;
+    m = c[pos];
+    for (i=d-1;i>=0;i--)
+    {
+      if(c[i]<m)
+      {
+        pos = i;
+        m = c[i];
+      }
+    }
+    for (i=pos;i<d;i++) c[i] = c[i+1];
+  } while (d>t);
+}
+
+/* ----------------- ops with rings ------------------ */
+ring sm_RingChange(const ring origR, long bound)
+{
+//  *origR =currRing;
+  ring tmpR=rCopy0(origR,FALSE,FALSE);
+  int *ord=(int*)omAlloc0(3*sizeof(int));
+  int *block0=(int*)omAlloc(3*sizeof(int));
+  int *block1=(int*)omAlloc(3*sizeof(int));
+  ord[0]=ringorder_c;
+  ord[1]=ringorder_dp;
+  tmpR->order=ord;
+  tmpR->OrdSgn=1;
+  block0[1]=1;
+  tmpR->block0=block0;
+  block1[1]=tmpR->N;
+  tmpR->block1=block1;
+  tmpR->bitmask = 2*bound;
+  tmpR->wvhdl = (int **)omAlloc0((3) * sizeof(int*));
+
+// ???
+//  if (tmpR->bitmask > currRing->bitmask) tmpR->bitmask = currRing->bitmask;
+
+  rComplete(tmpR,1);
+  if (origR->qideal!=NULL)
+  {
+    tmpR->qideal= idrCopyR_NoSort(origR->qideal, origR, tmpR);
+  }
+  if (TEST_OPT_PROT)
+    Print("[%ld:%d]", (long) tmpR->bitmask, tmpR->ExpL_Size);
+  return tmpR;
+}
+
+void sm_KillModifiedRing(ring r)
+{
+  if (r->qideal!=NULL) id_Delete(&(r->qideal),r);
+  rKillModifiedRing(r);
+}
+
+/*2
+* Bareiss or Chinese remainder ?
+* I is dXd
+* sw = TRUE  -> I Matrix
+*      FALSE -> I Module
+* return True  -> change Type
+*        FALSE -> same Type
+*/
+BOOLEAN sm_CheckDet(ideal I, int d, BOOLEAN sw, const ring r)
+{
+  int s,t,i;
+  poly p;
+
+  if (d>100)
+    return sw;
+  if (!rField_is_Q(r))
+    return sw;
+  s = t = 0;
+  if (sw)
+  {
+    for(i=IDELEMS(I)-1;i>=0;i--)
+    {
+      p=I->m[i];
+      if (p!=NULL)
+      {
+        if(!p_IsConstant(p,r))
+          return sw;
+        s++;
+        t+=n_Size(pGetCoeff(p),r->cf);
+      }
+    }
+  }
+  else
+  {
+    for(i=IDELEMS(I)-1;i>=0;i--)
+    {
+      p=I->m[i];
+      if (!p_IsConstantPoly(p,r))
+        return sw;
+      while (p!=NULL)
+      {
+        s++;
+        t+=n_Size(pGetCoeff(p),r->cf);
+        pIter(p);
+      }
+    }
+  }
+  s*=15;
+  if (t>s)
+    return !sw;
+  else
+    return sw;
+}
+
+/* ----------------- basics (used from 'C') ------------------ */
+/*2
+*returns the determinant of the module I;
+*uses Bareiss algorithm
+*/
+poly sm_CallDet(ideal I,const ring R)
+{
+  if (I->ncols != I->rank)
+  {
+    Werror("det of %ld x %d module (matrix)",I->rank,I->ncols);
+    return NULL;
+  }
+  int r=id_RankFreeModule(I,R);
+  if (I->ncols != r) // some 0-lines at the end
+  {
+    return NULL;
+  }
+  long bound=sm_ExpBound(I,r,r,r,R);
+  number diag,h=n_Init(1,R->cf);
+  poly res;
+  ring tmpR;
+  sparse_mat *det;
+  ideal II;
+
+  tmpR=sm_RingChange(R,bound);
+  II = idrCopyR(I, R, tmpR);
+  diag = sm_Cleardenom(II,tmpR);
+  det = new sparse_mat(II,tmpR);
+  id_Delete(&II,tmpR);
+  if (det->smGetAct() == NULL)
+  {
+    delete det;
+    sm_KillModifiedRing(tmpR);
+    return NULL;
+  }
+  res=det->smDet();
+  if(det->smGetSign()<0) res=p_Neg(res,tmpR);
+  delete det;
+  res = prMoveR(res, tmpR, R);
+  sm_KillModifiedRing(tmpR);
+  if (!n_Equal(diag,h,R->cf))
+  {
+    p_Mult_nn(res,diag,R);
+    p_Normalize(res,R);
+  }
+  n_Delete(&diag,R->cf);
+  n_Delete(&h,R->cf);
+  return res;
+}
+
+void sm_CallBareiss(ideal I, int x, int y, ideal & M, intvec **iv, const ring R)
+{
+  int r=id_RankFreeModule(I,R),t=r;
+  int c=IDELEMS(I),s=c;
+  long bound;
+  ring tmpR;
+  sparse_mat *bareiss;
+
+  if ((x>0) && (x<t))
+    t-=x;
+  if ((y>1) && (y<s))
+    s-=y;
+  if (t>s) t=s;
+  bound=sm_ExpBound(I,c,r,t,R);
+  tmpR=sm_RingChange(R,bound);
+  ideal II = idrCopyR(I, R, tmpR);
+  bareiss = new sparse_mat(II,tmpR);
+  if (bareiss->smGetAct() == NULL)
+  {
+    delete bareiss;
+    *iv=new intvec(1,rVar(tmpR));
+  }
+  else
+  {
+    id_Delete(&II,tmpR);
+    bareiss->smNewBareiss(x, y);
+    II = bareiss->smRes2Mod();
+    *iv = new intvec(bareiss->smGetRed());
+    bareiss->smToIntvec(*iv);
+    delete bareiss;
+    II = idrMoveR(II,tmpR,R);
+  }
+  sm_KillModifiedRing(tmpR);
+  M=II;
+}
+
+/*
+* constructor
+*/
+sparse_mat::sparse_mat(ideal smat, const ring RR)
+{
+  int i;
+  poly* pmat;
+  _R=RR;
+
+  ncols = smat->ncols;
+  nrows = id_RankFreeModule(smat,RR);
+  if (nrows <= 0)
+  {
+    m_act = NULL;
+    return;
+  }
+  sign = 1;
+  inred = act = ncols;
+  crd = 0;
+  tored = nrows; // without border
+  i = tored+1;
+  perm = (int *)omAlloc(sizeof(int)*(i+1));
+  perm[i] = 0;
+  m_row = (smpoly *)omAlloc0(sizeof(smpoly)*i);
+  wrw = (float *)omAlloc(sizeof(float)*i);
+  i = ncols+1;
+  wcl = (float *)omAlloc(sizeof(float)*i);
+  m_act = (smpoly *)omAlloc(sizeof(smpoly)*i);
+  m_res = (smpoly *)omAlloc0(sizeof(smpoly)*i);
+  dumm = (smpoly)omAllocBin(smprec_bin);
+  m_res[0] = (smpoly)omAllocBin(smprec_bin);
+  m_res[0]->m = NULL;
+  pmat = smat->m;
+  for(i=ncols; i; i--)
+  {
+    m_act[i] = sm_Poly2Smpoly(pmat[i-1], RR);
+    pmat[i-1] = NULL;
+  }
+  this->smZeroElim();
+  oldpiv = NULL;
+}
+
+/*
+* destructor
+*/
+sparse_mat::~sparse_mat()
+{
+  int i;
+  if (m_act == NULL) return;
+  omFreeBin((ADDRESS)m_res[0],  smprec_bin);
+  omFreeBin((ADDRESS)dumm,  smprec_bin);
+  i = ncols+1;
+  omFreeSize((ADDRESS)m_res, sizeof(smpoly)*i);
+  omFreeSize((ADDRESS)m_act, sizeof(smpoly)*i);
+  omFreeSize((ADDRESS)wcl, sizeof(float)*i);
+  i = nrows+1;
+  omFreeSize((ADDRESS)wrw, sizeof(float)*i);
+  omFreeSize((ADDRESS)m_row, sizeof(smpoly)*i);
+  omFreeSize((ADDRESS)perm, sizeof(int)*(i+1));
+}
+
+/*
+* transform the result to a module
+*/
+
+ideal sparse_mat::smRes2Mod()
+{
+  ideal res = idInit(crd, crd);
+  int i;
+
+  for (i=crd; i; i--) res->m[i-1] = sm_Smpoly2Poly(m_res[i],_R);
+  res->rank = id_RankFreeModule(res,_R);
+  return res;
+}
+
+/*
+* permutation of rows
+*/
+void sparse_mat::smToIntvec(intvec *v)
+{
+  int i;
+
+  for (i=v->rows()-1; i>=0; i--)
+    (*v)[i] = perm[i+1];
+}
+/* ---------------- the algorithm's ------------------ */
+/*
+* the determinant (up to sign), uses new Bareiss elimination
+*/
+poly sparse_mat::smDet()
+{
+  poly res = NULL;
+
+  if (sign == 0)
+  {
+    this->smActDel();
+    return NULL;
+  }
+  if (act < 2)
+  {
+    if (act != 0) res = m_act[1]->m;
+    omFreeBin((void *)m_act[1],  smprec_bin);
+    return res;
+  }
+  normalize = 0;
+  this->smInitPerm();
+  this->smPivot();
+  this->smSign();
+  this->smSelectPR();
+  this->sm1Elim();
+  crd++;
+  m_res[crd] = piv;
+  this->smColDel();
+  act--;
+  this->smZeroElim();
+  if (sign == 0)
+  {
+    this->smActDel();
+    return NULL;
+  }
+  if (act < 2)
+  {
+    this->smFinalMult();
+    this->smPivDel();
+    if (act != 0) res = m_act[1]->m;
+    omFreeBin((void *)m_act[1],  smprec_bin);
+    return res;
+  }
+  loop
+  {
+    this->smNewPivot();
+    this->smSign();
+    this->smSelectPR();
+    this->smMultCol();
+    this->smHElim();
+    crd++;
+    m_res[crd] = piv;
+    this->smColDel();
+    act--;
+    this->smZeroElim();
+    if (sign == 0)
+    {
+      this->smPivDel();
+      this->smActDel();
+      return NULL;
+    }
+    if (act < 2)
+    {
+      if (TEST_OPT_PROT) PrintS(".\n");
+      this->smFinalMult();
+      this->smPivDel();
+      if (act != 0) res = m_act[1]->m;
+      omFreeBin((void *)m_act[1],  smprec_bin);
+      return res;
+    }
+  }
+}
+
+/*
+* the new Bareiss elimination:
+*   - with x unreduced last rows, pivots from here are not allowed
+*   - the method will finish for number of unreduced columns < y
+*/
+void sparse_mat::smNewBareiss(int x, int y)
+{
+  if ((x > 0) && (x < nrows))
+  {
+    tored -= x;
+    this->smToredElim();
+  }
+  if (y < 1) y = 1;
+  if (act <= y)
+  {
+    this->smCopToRes();
+    return;
+  }
+  normalize = this->smCheckNormalize();
+  if (normalize) this->smNormalize();
+  this->smPivot();
+  this->smSelectPR();
+  this->sm1Elim();
+  crd++;
+  this->smColToRow();
+  act--;
+  this->smRowToCol();
+  this->smZeroElim();
+  if (tored != nrows)
+    this->smToredElim();
+  if (act <= y)
+  {
+    this->smFinalMult();
+    this->smCopToRes();
+    return;
+  }
+  loop
+  {
+    if (normalize) this->smNormalize();
+    this->smNewPivot();
+    this->smSelectPR();
+    this->smMultCol();
+    this->smHElim();
+    crd++;
+    this->smColToRow();
+    act--;
+    this->smRowToCol();
+    this->smZeroElim();
+    if (tored != nrows)
+      this->smToredElim();
+    if (act <= y)
+    {
+      if (TEST_OPT_PROT) PrintS(".\n");
+      this->smFinalMult();
+      this->smCopToRes();
+      return;
+    }
+  }
+}
+
+/* ----------------- pivot method ------------------ */
+
+/*
+* prepare smPivot, compute weights for rows and columns
+* and the weight for all points
+*/
+void sparse_mat::smWeights()
+{
+  float wc, wp, w;
+  smpoly a;
+  int i;
+
+  wp = 0.0;
+  for (i=tored; i; i--) wrw[i] = 0.0; // ???
+  for (i=act; i; i--)
+  {
+    wc = 0.0;
+    a = m_act[i];
+    loop
+    {
+      if (a->pos > tored)
+        break;
+      w = a->f = sm_PolyWeight(a,_R);
+      wc += w;
+      wrw[a->pos] += w;
+      a = a->n;
+      if (a == NULL)
+        break;
+    }
+    wp += wc;
+    wcl[i] = wc;
+  }
+  wpoints = wp;
+}
+
+/*
+* compute pivot
+*/
+void sparse_mat::smPivot()
+{
+  float wopt = 1.0e30;
+  float wc, wr, wp, w;
+  smpoly a;
+  int i, copt, ropt;
+
+  this->smWeights();
+  for (i=act; i; i--)
+  {
+    a = m_act[i];
+    loop
+    {
+      if (a->pos > tored)
+        break;
+      w = a->f;
+      wc = wcl[i]-w;
+      wr = wrw[a->pos]-w;
+      if ((wr<0.25) || (wc<0.25)) // row or column with only one point
+      {
+        if (w<wopt)
+        {
+          wopt = w;
+          copt = i;
+          ropt = a->pos;
+        }
+      }
+      else // elimination
+      {
+        wp = w*(wpoints-wcl[i]-wr);
+        wp += wr*wc;
+        if (wp < wopt)
+        {
+          wopt = wp;
+          copt = i;
+          ropt = a->pos;
+        }
+      }
+      a = a->n;
+      if (a == NULL)
+        break;
+    }
+  }
+  rpiv = ropt;
+  cpiv = copt;
+  if (cpiv != act)
+  {
+    a = m_act[act];
+    m_act[act] = m_act[cpiv];
+    m_act[cpiv] = a;
+  }
+}
+
+/*
+* prepare smPivot, compute weights for rows and columns
+* and the weight for all points
+*/
+void sparse_mat::smNewWeights()
+{
+  float wc, wp, w, hp = piv->f;
+  smpoly a;
+  int i, f, e = crd;
+
+  wp = 0.0;
+  for (i=tored; i; i--) wrw[i] = 0.0; // ???
+  for (i=act; i; i--)
+  {
+    wc = 0.0;
+    a = m_act[i];
+    loop
+    {
+      if (a->pos > tored)
+        break;
+      w = a->f;
+      f = a->e;
+      if (f < e)
+      {
+        w *= hp;
+        if (f) w /= m_res[f]->f;
+      }
+      wc += w;
+      wrw[a->pos] += w;
+      a = a->n;
+      if (a == NULL)
+        break;
+    }
+    wp += wc;
+    wcl[i] = wc;
+  }
+  wpoints = wp;
+}
+
+/*
+* compute pivot
+*/
+void sparse_mat::smNewPivot()
+{
+  float wopt = 1.0e30, hp = piv->f;
+  float wc, wr, wp, w;
+  smpoly a;
+  int i, copt, ropt, f, e = crd;
+
+  this->smNewWeights();
+  for (i=act; i; i--)
+  {
+    a = m_act[i];
+    loop
+    {
+      if (a->pos > tored)
+        break;
+      w = a->f;
+      f = a->e;
+      if (f < e)
+      {
+        w *= hp;
+        if (f) w /= m_res[f]->f;
+      }
+      wc = wcl[i]-w;
+      wr = wrw[a->pos]-w;
+      if ((wr<0.25) || (wc<0.25)) // row or column with only one point
+      {
+        if (w<wopt)
+        {
+          wopt = w;
+          copt = i;
+          ropt = a->pos;
+        }
+      }
+      else // elimination
+      {
+        wp = w*(wpoints-wcl[i]-wr);
+        wp += wr*wc;
+        if (wp < wopt)
+        {
+          wopt = wp;
+          copt = i;
+          ropt = a->pos;
+        }
+      }
+      a = a->n;
+      if (a == NULL)
+        break;
+    }
+  }
+  rpiv = ropt;
+  cpiv = copt;
+  if (cpiv != act)
+  {
+    a = m_act[act];
+    m_act[act] = m_act[cpiv];
+    m_act[cpiv] = a;
+  }
+}
+
+/* ----------------- elimination ------------------ */
+
+/* first step of elimination */
+void sparse_mat::sm1Elim()
+{
+  poly p = piv->m;        // pivotelement
+  smpoly c = m_act[act];  // pivotcolumn
+  smpoly r = red;         // row to reduce
+  smpoly res, a, b;
+  poly w, ha, hb;
+
+  if ((c == NULL) || (r == NULL))
+  {
+    while (r!=NULL) sm_ElemDelete(&r,_R);
+    return;
+  }
+  do
+  {
+    a = m_act[r->pos];
+    res = dumm;
+    res->n = NULL;
+    b = c;
+    w = r->m;
+    loop                  // combine the chains a and b: p*a + w*b
+    {
+      if (a == NULL)
+      {
+        do
+        {
+          res = res->n = smElemCopy(b);
+          res->m = pp_Mult_qq(b->m, w,_R);
+          res->e = 1;
+          res->f = sm_PolyWeight(res,_R);
+          b = b->n;
+        } while (b != NULL);
+        break;
+      }
+      if (a->pos < b->pos)
+      {
+        res = res->n = a;
+        a = a->n;
+      }
+      else if (a->pos > b->pos)
+      {
+        res = res->n = smElemCopy(b);
+        res->m = pp_Mult_qq(b->m, w,_R);
+        res->e = 1;
+        res->f = sm_PolyWeight(res,_R);
+        b = b->n;
+      }
+      else
+      {
+        ha = pp_Mult_qq(a->m, p,_R);
+        p_Delete(&a->m,_R);
+        hb = pp_Mult_qq(b->m, w,_R);
+        ha = p_Add_q(ha, hb,_R);
+        if (ha != NULL)
+        {
+          a->m = ha;
+          a->e = 1;
+          a->f = sm_PolyWeight(a,_R);
+          res = res->n = a;
+          a = a->n;
+        }
+        else
+        {
+          sm_ElemDelete(&a,_R);
+        }
+        b = b->n;
+      }
+      if (b == NULL)
+      {
+        res->n = a;
+        break;
+      }
+    }
+    m_act[r->pos] = dumm->n;
+    sm_ElemDelete(&r,_R);
+  } while (r != NULL);
+}
+
+/* higher steps of elimination */
+void sparse_mat::smHElim()
+{
+  poly hp = this->smMultPoly(piv);
+  poly gp = piv->m;       // pivotelement
+  smpoly c = m_act[act];  // pivotcolumn
+  smpoly r = red;         // row to reduce
+  smpoly res, a, b;
+  poly ha, hr, x, y;
+  int e, ip, ir, ia;
+
+  if ((c == NULL) || (r == NULL))
+  {
+    while(r!=NULL) sm_ElemDelete(&r,_R);
+    p_Delete(&hp,_R);
+    return;
+  }
+  e = crd+1;
+  ip = piv->e;
+  do
+  {
+    a = m_act[r->pos];
+    res = dumm;
+    res->n = NULL;
+    b = c;
+    hr = r->m;
+    ir = r->e;
+    loop                  // combine the chains a and b: (hp,gp)*a(l) + hr*b(h)
+    {
+      if (a == NULL)
+      {
+        do
+        {
+          res = res->n = smElemCopy(b);
+          x = SM_MULT(b->m, hr, m_res[ir]->m,_R);
+          b = b->n;
+          if(ir) SM_DIV(x, m_res[ir]->m,_R);
+          res->m = x;
+          res->e = e;
+          res->f = sm_PolyWeight(res,_R);
+        } while (b != NULL);
+        break;
+      }
+      if (a->pos < b->pos)
+      {
+        res = res->n = a;
+        a = a->n;
+      }
+      else if (a->pos > b->pos)
+      {
+        res = res->n = smElemCopy(b);
+        x = SM_MULT(b->m, hr, m_res[ir]->m,_R);
+        b = b->n;
+        if(ir) SM_DIV(x, m_res[ir]->m,_R);
+        res->m = x;
+        res->e = e;
+        res->f = sm_PolyWeight(res,_R);
+      }
+      else
+      {
+        ha = a->m;
+        ia = a->e;
+        if (ir >= ia)
+        {
+          if (ir > ia)
+          {
+            x = SM_MULT(ha, m_res[ir]->m, m_res[ia]->m,_R);
+            p_Delete(&ha,_R);
+            ha = x;
+            if (ia) SM_DIV(ha, m_res[ia]->m,_R);
+            ia = ir;
+          }
+          x = SM_MULT(ha, gp, m_res[ia]->m,_R);
+          p_Delete(&ha,_R);
+          y = SM_MULT(b->m, hr, m_res[ia]->m,_R);
+        }
+        else if (ir >= ip)
+        {
+          if (ia < crd)
+          {
+            x = SM_MULT(ha, m_res[crd]->m, m_res[ia]->m,_R);
+            p_Delete(&ha,_R);
+            ha = x;
+            SM_DIV(ha, m_res[ia]->m,_R);
+          }
+          y = hp;
+          if(ir > ip)
+          {
+            y = SM_MULT(y, m_res[ir]->m, m_res[ip]->m,_R);
+            if (ip) SM_DIV(y, m_res[ip]->m,_R);
+          }
+          ia = ir;
+          x = SM_MULT(ha, y, m_res[ia]->m,_R);
+          if (y != hp) p_Delete(&y,_R);
+          p_Delete(&ha,_R);
+          y = SM_MULT(b->m, hr, m_res[ia]->m,_R);
+        }
+        else
+        {
+          x = SM_MULT(hr, m_res[ia]->m, m_res[ir]->m,_R);
+          if (ir) SM_DIV(x, m_res[ir]->m,_R);
+          y = SM_MULT(b->m, x, m_res[ia]->m,_R);
+          p_Delete(&x,_R);
+          x = SM_MULT(ha, gp, m_res[ia]->m,_R);
+          p_Delete(&ha,_R);
+        }
+        ha = p_Add_q(x, y,_R);
+        if (ha != NULL)
+        {
+          if (ia) SM_DIV(ha, m_res[ia]->m,_R);
+          a->m = ha;
+          a->e = e;
+          a->f = sm_PolyWeight(a,_R);
+          res = res->n = a;
+          a = a->n;
+        }
+        else
+        {
+          a->m = NULL;
+          sm_ElemDelete(&a,_R);
+        }
+        b = b->n;
+      }
+      if (b == NULL)
+      {
+        res->n = a;
+        break;
+      }
+    }
+    m_act[r->pos] = dumm->n;
+    sm_ElemDelete(&r,_R);
+  } while (r != NULL);
+  p_Delete(&hp,_R);
+}
+
+/* ----------------- transfer ------------------ */
+
+/*
+* select the pivotrow and store it to red and piv
+*/
+void sparse_mat::smSelectPR()
+{
+  smpoly b = dumm;
+  smpoly a, ap;
+  int i;
+
+  if (TEST_OPT_PROT)
+  {
+    if ((crd+1)%10)
+      PrintS(".");
+    else
+      PrintS(".\n");
+  }
+  a = m_act[act];
+  if (a->pos < rpiv)
+  {
+    do
+    {
+      ap = a;
+      a = a->n;
+    } while (a->pos < rpiv);
+    ap->n = a->n;
+  }
+  else
+    m_act[act] = a->n;
+  piv = a;
+  a->n = NULL;
+  for (i=1; i<act; i++)
+  {
+    a = m_act[i];
+    if (a->pos < rpiv)
+    {
+      loop
+      {
+        ap = a;
+        a = a->n;
+        if ((a == NULL) || (a->pos > rpiv))
+          break;
+        if (a->pos == rpiv)
+        {
+          ap->n = a->n;
+          a->m = p_Neg(a->m,_R);
+          b = b->n = a;
+          b->pos = i;
+          break;
+        }
+      }
+    }
+    else if (a->pos == rpiv)
+    {
+      m_act[i] = a->n;
+      a->m = p_Neg(a->m,_R);
+      b = b->n = a;
+      b->pos = i;
+    }
+  }
+  b->n = NULL;
+  red = dumm->n;
+}
+
+/*
+* store the pivotcol in m_row
+*   m_act[cols][pos(rows)] => m_row[rows][pos(cols)]
+*/
+void sparse_mat::smColToRow()
+{
+  smpoly c = m_act[act];
+  smpoly h;
+
+  while (c != NULL)
+  {
+    h = c;
+    c = c->n;
+    h->n = m_row[h->pos];
+    m_row[h->pos] = h;
+    h->pos = crd;
+  }
+}
+
+/*
+* store the pivot and the assosiated row in m_row
+* to m_res (result):
+*   piv + m_row[rows][pos(cols)] => m_res[cols][pos(rows)]
+*/
+void sparse_mat::smRowToCol()
+{
+  smpoly r = m_row[rpiv];
+  smpoly a, ap, h;
+
+  m_row[rpiv] = NULL;
+  perm[crd] = rpiv;
+  piv->pos = crd;
+  m_res[crd] = piv;
+  while (r != NULL)
+  {
+    ap = m_res[r->pos];
+    loop
+    {
+      a = ap->n;
+      if (a == NULL)
+      {
+        ap->n = h = r;
+        r = r->n;
+        h->n = a;
+        h->pos = crd;
+        break;
+      }
+      ap = a;
+    }
+  }
+}
+
+/* ----------------- C++ stuff ------------------ */
+
+/*
+*  clean m_act from zeros (after elim)
+*/
+void sparse_mat::smZeroElim()
+{
+  int i = 0;
+  int j;
+
+  loop
+  {
+    i++;
+    if (i > act) return;
+    if (m_act[i] == NULL) break;
+  }
+  j = i;
+  loop
+  {
+    j++;
+    if (j > act) break;
+    if (m_act[j] != NULL)
+    {
+      m_act[i] = m_act[j];
+      i++;
+    }
+  }
+  act -= (j-i);
+  sign = 0;
+}
+
+/*
+*  clean m_act from cols not to reduced (after elim)
+*  put them to m_res
+*/
+void sparse_mat::smToredElim()
+{
+  int i = 0;
+  int j;
+
+  loop
+  {
+    i++;
+    if (i > act) return;
+    if (m_act[i]->pos > tored)
+    {
+      m_res[inred] = m_act[i];
+      inred--;
+      break;
+    }
+  }
+  j = i;
+  loop
+  {
+    j++;
+    if (j > act) break;
+    if (m_act[j]->pos > tored)
+    {
+      m_res[inred] = m_act[j];
+      inred--;
+    }
+    else
+    {
+      m_act[i] = m_act[j];
+      i++;
+    }
+  }
+  act -= (j-i);
+  sign = 0;
+}
+
+/*
+*  copy m_act to m_res
+*/
+void sparse_mat::smCopToRes()
+{
+  smpoly a,ap,r,h;
+  int i,j,k,l;
+
+  i = 0;
+  if (act)
+  {
+    a = m_act[act]; // init perm
+    do
+    {
+      i++;
+      perm[crd+i] = a->pos;
+      a = a->n;
+    } while ((a != NULL) && (a->pos <= tored));
+    for (j=act-1;j;j--) // load all positions of perm
+    {
+      a = m_act[j];
+      k = 1;
+      loop
+      {
+        if (perm[crd+k] >= a->pos)
+        {
+          if (perm[crd+k] > a->pos)
+          {
+            for (l=i;l>=k;l--) perm[crd+l+1] = perm[crd+l];
+            perm[crd+k] = a->pos;
+            i++;
+          }
+          a = a->n;
+          if ((a == NULL) || (a->pos > tored)) break;
+        }
+        k++;
+        if ((k > i) && (a->pos <= tored))
+        {
+          do
+          {
+            i++;
+            perm[crd+i] = a->pos;
+            a = a->n;
+          } while ((a != NULL) && (a->pos <= tored));
+          break;
+        }
+      }
+    }
+  }
+  for (j=act;j;j--) // renumber m_act
+  {
+    k = 1;
+    a = m_act[j];
+    while ((a != NULL) && (a->pos <= tored))
+    {
+      if (perm[crd+k] == a->pos)
+      {
+        a->pos = crd+k;
+        a = a->n;
+      }
+      k++;
+    }
+  }
+  tored = crd+i;
+  for(k=1;k<=i;k++) // clean this from m_row
+  {
+    j = perm[crd+k];
+    if (m_row[j] != NULL)
+    {
+      r = m_row[j];
+      m_row[j] = NULL;
+      do
+      {
+        ap = m_res[r->pos];
+        loop
+        {
+          a = ap->n;
+          if (a == NULL)
+          {
+            h = ap->n = r;
+            r = r->n;
+            h->n = NULL;
+            h->pos = crd+k;
+            break;
+          }
+          ap = a;
+        }
+      } while (r!=NULL);
+    }
+  }
+  while(act) // clean m_act
+  {
+    crd++;
+    m_res[crd] = m_act[act];
+    act--;
+  }
+  for (i=1;i<=tored;i++) // take the rest of m_row
+  {
+    if(m_row[i] != NULL)
+    {
+      tored++;
+      r = m_row[i];
+      m_row[i] = NULL;
+      perm[tored] = i;
+      do
+      {
+        ap = m_res[r->pos];
+        loop
+        {
+          a = ap->n;
+          if (a == NULL)
+          {
+            h = ap->n = r;
+            r = r->n;
+            h->n = NULL;
+            h->pos = tored;
+            break;
+          }
+          ap = a;
+        }
+      } while (r!=NULL);
+    }
+  }
+  for (i=tored+1;i<=nrows;i++) // take the rest of m_row
+  {
+    if(m_row[i] != NULL)
+    {
+      r = m_row[i];
+      m_row[i] = NULL;
+      do
+      {
+        ap = m_res[r->pos];
+        loop
+        {
+          a = ap->n;
+          if (a == NULL)
+          {
+            h = ap->n = r;
+            r = r->n;
+            h->n = NULL;
+            h->pos = i;
+            break;
+          }
+          ap = a;
+        }
+      } while (r!=NULL);
+    }
+  }
+  while (inred < ncols) // take unreducable
+  {
+    crd++;
+    inred++;
+    m_res[crd] = m_res[inred];
+  }
+}
+
+/*
+* multiply and divide the column, that goes to result
+*/
+void sparse_mat::smMultCol()
+{
+  smpoly a = m_act[act];
+  int e = crd;
+  poly ha;
+  int f;
+
+  while (a != NULL)
+  {
+    f = a->e;
+    if (f < e)
+    {
+      ha = SM_MULT(a->m, m_res[e]->m, m_res[f]->m,_R);
+      p_Delete(&a->m,_R);
+      if (f) SM_DIV(ha, m_res[f]->m,_R);
+      a->m = ha;
+      if (normalize) p_Normalize(a->m,_R);
+    }
+    a = a->n;
+  }
+}
+
+/*
+* multiply and divide the m_act finaly
+*/
+void sparse_mat::smFinalMult()
+{
+  smpoly a;
+  poly ha;
+  int i, f;
+  int e = crd;
+
+  for (i=act; i; i--)
+  {
+    a = m_act[i];
+    do
+    {
+      f = a->e;
+      if (f < e)
+      {
+        ha = SM_MULT(a->m, m_res[e]->m, m_res[f]->m, _R);
+        p_Delete(&a->m,_R);
+        if (f) SM_DIV(ha, m_res[f]->m, _R);
+        a->m = ha;
+      }
+      if (normalize) p_Normalize(a->m, _R);
+      a = a->n;
+    } while (a != NULL);
+  }
+}
+
+/*
+* check for denominators
+*/
+int sparse_mat::smCheckNormalize()
+{
+  int i;
+  smpoly a;
+
+  for (i=act; i; i--)
+  {
+    a = m_act[i];
+    do
+    {
+      if(sm_HaveDenom(a->m,_R)) return 1;
+      a = a->n;
+    } while (a != NULL);
+  }
+  return 0;
+}
+
+/*
+* normalize
+*/
+void sparse_mat::smNormalize()
+{
+  smpoly a;
+  int i;
+  int e = crd;
+
+  for (i=act; i; i--)
+  {
+    a = m_act[i];
+    do
+    {
+      if (e == a->e) p_Normalize(a->m,_R);
+      a = a->n;
+    } while (a != NULL);
+  }
+}
+
+/*
+* multiply and divide the element, save poly
+*/
+poly sparse_mat::smMultPoly(smpoly a)
+{
+  int f = a->e;
+  poly r, h;
+
+  if (f < crd)
+  {
+    h = r = a->m;
+    h = SM_MULT(h, m_res[crd]->m, m_res[f]->m, _R);
+    if (f) SM_DIV(h, m_res[f]->m, _R);
+    a->m = h;
+    if (normalize) p_Normalize(a->m,_R);
+    a->f = sm_PolyWeight(a,_R);
+    return r;
+  }
+  else
+    return NULL;
+}
+
+/*
+* delete the m_act finaly
+*/
+void sparse_mat::smActDel()
+{
+  smpoly a;
+  int i;
+
+  for (i=act; i; i--)
+  {
+    a = m_act[i];
+    do
+    {
+      sm_ElemDelete(&a,_R);
+    } while (a != NULL);
+  }
+}
+
+/*
+* delete the pivotcol
+*/
+void sparse_mat::smColDel()
+{
+  smpoly a = m_act[act];
+
+  while (a != NULL)
+  {
+    sm_ElemDelete(&a,_R);
+  }
+}
+
+/*
+* delete pivot elements
+*/
+void sparse_mat::smPivDel()
+{
+  int i=crd;
+
+  while (i != 0)
+  {
+    sm_ElemDelete(&m_res[i],_R);
+    i--;
+  }
+}
+
+/*
+* the sign of the determinant
+*/
+void sparse_mat::smSign()
+{
+  int j,i;
+  if (act > 2)
+  {
+    if (cpiv!=act) sign=-sign;
+    if ((act%2)==0) sign=-sign;
+    i=1;
+    j=perm[1];
+    while(j<rpiv)
+    {
+      sign=-sign;
+      i++;
+      j=perm[i];
+    }
+    while(perm[i]!=0)
+    {
+      perm[i]=perm[i+1];
+      i++;
+    }
+  }
+  else
+  {
+    if (cpiv!=1) sign=-sign;
+    if (rpiv!=perm[1]) sign=-sign;
+  }
+}
+
+void sparse_mat::smInitPerm()
+{
+  int i;
+  for (i=act;i;i--) perm[i]=i;
+}
+
+/* ----------------- arithmetic ------------------ */
+/*2
+* exact division a/b
+* a destroyed, b NOT destroyed
+*/
+void sm_PolyDiv(poly a, poly b, const ring R)
+{
+  const number x = pGetCoeff(b);
+  number y, yn;
+  poly t, h, dummy;
+  int i;
+
+  if (pNext(b) == NULL)
+  {
+    do
+    {
+      if (!p_LmIsConstantComp(b,R))
+      {
+        for (i=rVar(R); i; i--)
+          p_SubExp(a,i,p_GetExp(b,i,R),R);
+        p_Setm(a,R);
+      }
+      y = n_Div(pGetCoeff(a),x,R->cf);
+      n_Normalize(y,R->cf);
+      p_SetCoeff(a,y,R);
+      pIter(a);
+    } while (a != NULL);
+    return;
+  }
+  dummy = p_Init(R);
+  do
+  {
+    for (i=rVar(R); i; i--)
+      p_SubExp(a,i,p_GetExp(b,i,R),R);
+    p_Setm(a,R);
+    y = n_Div(pGetCoeff(a),x,R->cf);
+    n_Normalize(y,R->cf);
+    p_SetCoeff(a,y,R);
+    yn = n_InpNeg(n_Copy(y,R->cf),R->cf);
+    t = pNext(b);
+    h = dummy;
+    do
+    {
+      h = pNext(h) = p_Init(R);
+      //pSetComp(h,0);
+      for (i=rVar(R); i; i--)
+        p_SetExp(h,i,p_GetExp(a,i,R)+p_GetExp(t,i,R),R);
+      p_Setm(h,R);
+      pSetCoeff0(h,n_Mult(yn, pGetCoeff(t),R->cf));
+      pIter(t);
+    } while (t != NULL);
+    n_Delete(&yn,R->cf);
+    pNext(h) = NULL;
+    a = pNext(a) = p_Add_q(pNext(a), pNext(dummy),R);
+  } while (a!=NULL);
+  p_LmFree(dummy, R);
+}
+
+
+//disable that, as it fails with coef buckets
+//#define X_MAS
+#ifdef X_MAS
+// Note: the following in not addapted to SW :(
+/*
+///  returns the part of (a*b)/exp(lead(c)) with nonegative exponents
+poly smMultDiv(poly a, poly b, const poly c)
+{
+  poly pa, e, res, r;
+  BOOLEAN lead;
+  int la, lb, lr;
+
+  if ((c == NULL) || pLmIsConstantComp(c))
+  {
+    return pp_Mult_qq(a, b);
+  }
+
+  pqLength(a, b, la, lb, SM_MIN_LENGTH_BUCKET);
+
+  // we iter over b, so, make sure b is the shortest
+  // such that we minimize our iterations
+  if (lb > la)
+  {
+    r = a;
+    a = b;
+    b = r;
+    lr = la;
+    la = lb;
+    lb = lr;
+  }
+  res = NULL;
+  e = p_Init();
+  lead = FALSE;
+  while (!lead)
+  {
+    pSetCoeff0(e,pGetCoeff(b));
+    if (smIsNegQuot(e, b, c))
+    {
+      lead = pLmDivisibleByNoComp(e, a);
+      r = smSelectCopy_ExpMultDiv(a, e, b, c);
+    }
+    else
+    {
+      lead = TRUE;
+      r = pp_Mult__mm(a, e);
+    }
+    if (lead)
+    {
+      if (res != NULL)
+      {
+        smFindRef(&pa, &res, r);
+        if (pa == NULL)
+          lead = FALSE;
+      }
+      else
+      {
+        pa = res = r;
+      }
+    }
+    else
+      res = p_Add_q(res, r);
+    pIter(b);
+    if (b == NULL)
+    {
+      pLmFree(e);
+      return res;
+    }
+  }
+
+  if (!TEST_OPT_NOT_BUCKETS && lb >= SM_MIN_LENGTH_BUCKET)
+  {
+    // use buckets if minimum length is smaller than threshold
+    spolyrec rp;
+    poly append;
+    // find the last monomial before pa
+    if (res == pa)
+    {
+      append = &rp;
+      pNext(append) = res;
+    }
+    else
+    {
+      append = res;
+      while (pNext(append) != pa)
+      {
+        assume(pNext(append) != NULL);
+        pIter(append);
+      }
+    }
+    kBucket_pt bucket = kBucketCreate(currRing);
+    kBucketInit(bucket, pNext(append), 0);
+    do
+    {
+      pSetCoeff0(e,pGetCoeff(b));
+      if (smIsNegQuot(e, b, c))
+      {
+        lr = la;
+        r = pp_Mult_Coeff_mm_DivSelect_MultDiv(a, lr, e, b, c);
+        if (pLmDivisibleByNoComp(e, a))
+          append = kBucket_ExtractLarger_Add_q(bucket, append, r, &lr);
+        else
+          kBucket_Add_q(bucket, r, &lr);
+      }
+      else
+      {
+        r = pp_Mult__mm(a, e);
+        append = kBucket_ExtractLarger_Add_q(bucket, append, r, &la);
+      }
+      pIter(b);
+    } while (b != NULL);
+    pNext(append) = kBucketClear(bucket);
+    kBucketDestroy(&bucket);
+    pTest(append);
+  }
+  else
+  {
+    // use old sm stuff
+    do
+    {
+      pSetCoeff0(e,pGetCoeff(b));
+      if (smIsNegQuot(e, b, c))
+      {
+        r = smSelectCopy_ExpMultDiv(a, e, b, c);
+        if (pLmDivisibleByNoComp(e, a))
+          smCombineChain(&pa, r);
+        else
+          pa = p_Add_q(pa,r);
+      }
+      else
+      {
+        r = pp_Mult__mm(a, e);
+        smCombineChain(&pa, r);
+      }
+      pIter(b);
+    } while (b != NULL);
+  }
+  pLmFree(e);
+  return res;
+}
+*/
+#else
+
+/*
+*  returns the part of (a*b)/exp(lead(c)) with nonegative exponents
+*/
+poly sm_MultDiv(poly a, poly b, const poly c, const ring R)
+{
+  poly pa, e, res, r;
+  BOOLEAN lead;
+
+  if ((c == NULL) || p_LmIsConstantComp(c,R))
+  {
+    return pp_Mult_qq(a, b, R);
+  }
+  if (smSmaller(a, b))
+  {
+    r = a;
+    a = b;
+    b = r;
+  }
+  res = NULL;
+  e = p_Init(R);
+  lead = FALSE;
+  while (!lead)
+  {
+    pSetCoeff0(e,pGetCoeff(b));
+    if (sm_IsNegQuot(e, b, c, R))
+    {
+      lead = p_LmDivisibleByNoComp(e, a, R);
+      r = sm_SelectCopy_ExpMultDiv(a, e, b, c, R);
+    }
+    else
+    {
+      lead = TRUE;
+      r = pp_Mult_mm(a, e,R);
+    }
+    if (lead)
+    {
+      if (res != NULL)
+      {
+        sm_FindRef(&pa, &res, r, R);
+        if (pa == NULL)
+          lead = FALSE;
+      }
+      else
+      {
+        pa = res = r;
+      }
+    }
+    else
+      res = p_Add_q(res, r, R);
+    pIter(b);
+    if (b == NULL)
+    {
+      p_LmFree(e, R);
+      return res;
+    }
+  }
+  do
+  {
+    pSetCoeff0(e,pGetCoeff(b));
+    if (sm_IsNegQuot(e, b, c, R))
+    {
+      r = sm_SelectCopy_ExpMultDiv(a, e, b, c, R);
+      if (p_LmDivisibleByNoComp(e, a,R))
+        sm_CombineChain(&pa, r, R);
+      else
+        pa = p_Add_q(pa,r,R);
+    }
+    else
+    {
+      r = pp_Mult_mm(a, e, R);
+      sm_CombineChain(&pa, r, R);
+    }
+    pIter(b);
+  } while (b != NULL);
+  p_LmFree(e, R);
+  return res;
+}
+#endif
+/*n
+* exact division a/b
+* a is a result of smMultDiv
+* a destroyed, b NOT destroyed
+*/
+void sm_SpecialPolyDiv(poly a, poly b, const ring R)
+{
+  if (pNext(b) == NULL)
+  {
+    sm_PolyDivN(a, pGetCoeff(b),R);
+    return;
+  }
+  sm_ExactPolyDiv(a, b, R);
+}
+
+
+/* ------------ internals arithmetic ------------- */
+static void sm_ExactPolyDiv(poly a, poly b, const ring R)
+{
+  const number x = pGetCoeff(b);
+  poly tail = pNext(b), e = p_Init(R);
+  poly h;
+  number y, yn;
+  int lt = pLength(tail);
+
+  if (lt + 1 >= SM_MIN_LENGTH_BUCKET &&  !TEST_OPT_NOT_BUCKETS)
+  {
+    kBucket_pt bucket = kBucketCreate(R);
+    kBucketInit(bucket, pNext(a), 0);
+    int lh = 0;
+    do
+    {
+      y = n_Div(pGetCoeff(a), x, R->cf);
+      n_Normalize(y, R->cf);
+      p_SetCoeff(a,y, R);
+      yn = n_InpNeg(n_Copy(y, R->cf), R->cf);
+      pSetCoeff0(e,yn);
+      lh = lt;
+      if (sm_IsNegQuot(e, a, b, R))
+      {
+        h = pp_Mult_Coeff_mm_DivSelect_MultDiv(tail, lh, e, a, b, R);
+      }
+      else
+        h = pp_Mult_mm(tail, e, R);
+      n_Delete(&yn, R->cf);
+      kBucket_Add_q(bucket, h, &lh);
+
+      a = pNext(a) = kBucketExtractLm(bucket);
+    } while (a!=NULL);
+    kBucketDestroy(&bucket);
+  }
+  else
+  {
+    do
+    {
+      y = n_Div(pGetCoeff(a), x, R->cf);
+      n_Normalize(y, R->cf);
+      p_SetCoeff(a,y, R);
+      yn = n_InpNeg(n_Copy(y, R->cf), R->cf);
+      pSetCoeff0(e,yn);
+      if (sm_IsNegQuot(e, a, b, R))
+        h = sm_SelectCopy_ExpMultDiv(tail, e, a, b, R);
+      else
+        h = pp_Mult_mm(tail, e, R);
+      n_Delete(&yn, R->cf);
+      a = pNext(a) = p_Add_q(pNext(a), h, R);
+    } while (a!=NULL);
+  }
+  p_LmFree(e, R);
+}
+
+// obachman --> Wilfried: check the following
+static BOOLEAN sm_IsNegQuot(poly a, const poly b, const poly c, const ring R)
+{
+  if (p_LmDivisibleByNoComp(c, b,R))
+  {
+    p_ExpVectorDiff(a, b, c,R);
+    // Hmm: here used to be a p_Setm(a): but it is unnecessary,
+    // if b and c are correct
+    return FALSE;
+  }
+  else
+  {
+    int i;
+    for (i=rVar(R); i>0; i--)
+    {
+      if(p_GetExp(c,i,R) > p_GetExp(b,i,R))
+        p_SetExp(a,i,p_GetExp(c,i,R)-p_GetExp(b,i,R),R);
+      else
+        p_SetExp(a,i,0,R);
+    }
+    // here we actually might need a p_Setm, if a is to be used in
+    // comparisons
+    return TRUE;
+  }
+}
+
+static void sm_ExpMultDiv(poly t, const poly b, const poly c, const ring R)
+{
+  p_Test(t,R);
+  p_LmTest(b,R);
+  p_LmTest(c,R);
+  poly bc = p_New(R);
+
+  p_ExpVectorDiff(bc, b, c, R);
+
+  while(t!=NULL)
+  {
+    p_ExpVectorAdd(t, bc, R);
+    pIter(t);
+  }
+  p_LmFree(bc, R);
+}
+
+
+static void sm_PolyDivN(poly a, const number x, const ring R)
+{
+  number y;
+
+  do
+  {
+    y = n_Div(pGetCoeff(a),x, R->cf);
+    n_Normalize(y, R->cf);
+    p_SetCoeff(a,y, R);
+    pIter(a);
+  } while (a != NULL);
+}
+
+static BOOLEAN smSmaller(poly a, poly b)
+{
+  loop
+  {
+    pIter(b);
+    if (b == NULL) return TRUE;
+    pIter(a);
+    if (a == NULL) return FALSE;
+  }
+}
+
+static void sm_CombineChain(poly *px, poly r, const ring R)
+{
+  poly pa = *px, pb;
+  number x;
+  int i;
+
+  loop
+  {
+    pb = pNext(pa);
+    if (pb == NULL)
+    {
+      pa = pNext(pa) = r;
+      break;
+    }
+    i = p_LmCmp(pb, r,R);
+    if (i > 0)
+      pa = pb;
+    else
+    {
+      if (i == 0)
+      {
+        x = n_Add(pGetCoeff(pb), pGetCoeff(r),R->cf);
+        p_LmDelete(&r,R);
+        if (n_IsZero(x,R->cf))
+        {
+          p_LmDelete(&pb,R);
+          pNext(pa) = p_Add_q(pb,r,R);
+        }
+        else
+        {
+          pa = pb;
+          p_SetCoeff(pa,x,R);
+          pNext(pa) = p_Add_q(pNext(pa), r, R);
+        }
+      }
+      else
+      {
+        pa = pNext(pa) = r;
+        pNext(pa) = p_Add_q(pb, pNext(pa),R);
+      }
+      break;
+    }
+  }
+  *px = pa;
+}
+
+
+static void sm_FindRef(poly *ref, poly *px, poly r, const ring R)
+{
+  number x;
+  int i;
+  poly pa = *px, pp = NULL;
+
+  loop
+  {
+    i = p_LmCmp(pa, r,R);
+    if (i > 0)
+    {
+      pp = pa;
+      pIter(pa);
+      if (pa==NULL)
+      {
+        pNext(pp) = r;
+        break;
+      }
+    }
+    else
+    {
+      if (i == 0)
+      {
+        x = n_Add(pGetCoeff(pa), pGetCoeff(r),R->cf);
+        p_LmDelete(&r,R);
+        if (n_IsZero(x,R->cf))
+        {
+          p_LmDelete(&pa,R);
+          if (pp!=NULL)
+            pNext(pp) = p_Add_q(pa,r,R);
+          else
+            *px = p_Add_q(pa,r,R);
+        }
+        else
+        {
+          pp = pa;
+          p_SetCoeff(pp,x,R);
+          pNext(pp) = p_Add_q(pNext(pp), r, R);
+        }
+      }
+      else
+      {
+        if (pp!=NULL)
+          pp = pNext(pp) = r;
+        else
+          *px = pp = r;
+        pNext(pp) = p_Add_q(pa, pNext(r),R);
+      }
+      break;
+    }
+  }
+  *ref = pp;
+}
+
+/* ----------------- internal 'C' stuff ------------------ */
+
+static void sm_ElemDelete(smpoly *r, const ring R)
+{
+  smpoly a = *r, b = a->n;
+
+  p_Delete(&a->m, R);
+  omFreeBin((void *)a,  smprec_bin);
+  *r = b;
+}
+
+static smpoly smElemCopy(smpoly a)
+{
+  smpoly r = (smpoly)omAllocBin(smprec_bin);
+  memcpy(r, a, sizeof(smprec));
+/*  r->m = pCopy(r->m); */
+  return r;
+}
+
+/*
+* from poly to smpoly
+* do not destroy p
+*/
+static smpoly sm_Poly2Smpoly(poly q, const ring R)
+{
+  poly pp;
+  smpoly res, a;
+  long x;
+
+  if (q == NULL)
+    return NULL;
+  a = res = (smpoly)omAllocBin(smprec_bin);
+  a->pos = x = p_GetComp(q,R);
+  a->m = q;
+  a->e = 0;
+  loop
+  {
+    p_SetComp(q,0,R);
+    pp = q;
+    pIter(q);
+    if (q == NULL)
+    {
+      a->n = NULL;
+      return res;
+    }
+    if (p_GetComp(q,R) != x)
+    {
+      a = a->n = (smpoly)omAllocBin(smprec_bin);
+      pNext(pp) = NULL;
+      a->pos = x = p_GetComp(q,R);
+      a->m = q;
+      a->e = 0;
+    }
+  }
+}
+
+/*
+* from smpoly to poly
+* destroy a
+*/
+static poly sm_Smpoly2Poly(smpoly a, const ring R)
+{
+  smpoly b;
+  poly res, pp, q;
+  long x;
+
+  if (a == NULL)
+    return NULL;
+  x = a->pos;
+  q = res = a->m;
+  loop
+  {
+    p_SetComp(q,x,R);
+    pp = q;
+    pIter(q);
+    if (q == NULL)
+      break;
+  }
+  loop
+  {
+    b = a;
+    a = a->n;
+    omFreeBin((void *)b,  smprec_bin);
+    if (a == NULL)
+      return res;
+    x = a->pos;
+    q = pNext(pp) = a->m;
+    loop
+    {
+      p_SetComp(q,x,R);
+      pp = q;
+      pIter(q);
+      if (q == NULL)
+        break;
+    }
+  }
+}
+
+/*
+* weigth of a polynomial, for pivot strategy
+*/
+static float sm_PolyWeight(smpoly a, const ring R)
+{
+  poly p = a->m;
+  int i;
+  float res = (float)n_Size(pGetCoeff(p),R->cf);
+
+  if (pNext(p) == NULL)
+  {
+    for(i=rVar(R); i>0; i--)
+    {
+      if (p_GetExp(p,i,R) != 0) return res+1.0;
+    }
+    return res;
+  }
+  else
+  {
+    i = 0;
+    res = 0.0;
+    do
+    {
+      i++;
+      res += (float)n_Size(pGetCoeff(p),R->cf);
+      pIter(p);
+    }
+    while (p);
+    return res+(float)i;
+  }
+}
+
+static BOOLEAN sm_HaveDenom(poly a, const ring R)
+{
+  BOOLEAN sw;
+  number x;
+
+  while (a != NULL)
+  {
+    x = n_GetDenom(pGetCoeff(a),R->cf);
+    sw = n_IsOne(x,R->cf);
+    n_Delete(&x,R->cf);
+    if (!sw)
+    {
+      return TRUE;
+    }
+    pIter(a);
+  }
+  return FALSE;
+}
+
+static number sm_Cleardenom(ideal id, const ring R)
+{
+  poly a;
+  number x,y,res=n_Init(1,R->cf);
+  BOOLEAN sw=FALSE;
+
+  for (int i=0; i<IDELEMS(id); i++)
+  {
+    a = id->m[i];
+    sw = sm_HaveDenom(a,R);
+    if (sw) break;
+  }
+  if (!sw) return res;
+  for (int i=0; i<IDELEMS(id); i++)
+  {
+    a = id->m[i];
+    if (a!=NULL)
+    {
+      x = n_Copy(pGetCoeff(a),R->cf);
+      p_Cleardenom(a, R);
+      y = n_Div(x,pGetCoeff(a),R->cf);
+      n_Delete(&x,R->cf);
+      x = n_Mult(res,y,R->cf);
+      n_Normalize(x,R->cf);
+      n_Delete(&res,R->cf);
+      res = x;
+    }
+  }
+  return res;
+}
+
+/* ----------------- gauss elimination ------------------ */
+/* in structs.h */
+typedef struct smnrec sm_nrec;
+typedef sm_nrec * smnumber;
+struct smnrec{
+  smnumber n;          // the next element
+  int pos;             // position
+  number m;            // the element
+};
+
+static omBin smnrec_bin = omGetSpecBin(sizeof(smnrec));
+
+/* declare internal 'C' stuff */
+static void sm_NumberDelete(smnumber *, const ring R);
+static smnumber smNumberCopy(smnumber);
+static smnumber sm_Poly2Smnumber(poly, const ring);
+static poly sm_Smnumber2Poly(number,const ring);
+static BOOLEAN smCheckSolv(ideal);
+
+/* class for sparse number matrix:
+*/
+class sparse_number_mat{
+private:
+  int nrows, ncols;    // dimension of the problem
+  int act;             // number of unreduced columns (start: ncols)
+  int crd;             // number of reduced columns (start: 0)
+  int tored;           // border for rows to reduce
+  int sing;            // indicator for singular problem
+  int rpiv;            // row-position of the pivot
+  int *perm;           // permutation of rows
+  number *sol;         // field for solution
+  int *wrw, *wcl;      // weights of rows and columns
+  smnumber * m_act;    // unreduced columns
+  smnumber * m_res;    // reduced columns (result)
+  smnumber * m_row;    // reduced part of rows
+  smnumber red;        // row to reduce
+  smnumber piv;        // pivot
+  smnumber dumm;       // allocated dummy
+  ring _R;
+  void smColToRow();
+  void smRowToCol();
+  void smSelectPR();
+  void smRealPivot();
+  void smZeroToredElim();
+  void smGElim();
+  void smAllDel();
+public:
+  sparse_number_mat(ideal, const ring);
+  ~sparse_number_mat();
+  int smIsSing() { return sing; }
+  void smTriangular();
+  void smSolv();
+  ideal smRes2Ideal();
+};
+
+/* ----------------- basics (used from 'C') ------------------ */
+/*2
+* returns the solution of a linear equation
+* solution of M*x = r (M has dimension nXn) =>
+*   I = module(transprose(M)) + r*gen(n+1)
+* uses  Gauss-elimination
+*/
+ideal sm_CallSolv(ideal I, const ring R)
+{
+  sparse_number_mat *linsolv;
+  ring tmpR;
+  ideal rr;
+
+  if (id_IsConstant(I,R)==FALSE)
+  {
+    WerrorS("symbol in equation");
+    return NULL;
+  }
+  I->rank = id_RankFreeModule(I,R);
+  if (smCheckSolv(I)) return NULL;
+  tmpR=sm_RingChange(R,1);
+  rr=idrCopyR(I,R, tmpR);
+  linsolv = new sparse_number_mat(rr,tmpR);
+  rr=NULL;
+  linsolv->smTriangular();
+  if (linsolv->smIsSing() == 0)
+  {
+    linsolv->smSolv();
+    rr = linsolv->smRes2Ideal();
+  }
+  else
+    WerrorS("singular problem for linsolv");
+  delete linsolv;
+  if (rr!=NULL)
+    rr = idrMoveR(rr,tmpR,R);
+  sm_KillModifiedRing(tmpR);
+  return rr;
+}
+
+/*
+* constructor, destroy smat
+*/
+sparse_number_mat::sparse_number_mat(ideal smat, const ring R)
+{
+  int i;
+  poly* pmat;
+  _R=R;
+
+  crd = sing = 0;
+  act = ncols = smat->ncols;
+  tored = nrows = smat->rank;
+  i = tored+1;
+  perm = (int *)omAlloc(sizeof(int)*i);
+  m_row = (smnumber *)omAlloc0(sizeof(smnumber)*i);
+  wrw = (int *)omAlloc(sizeof(int)*i);
+  i = ncols+1;
+  wcl = (int *)omAlloc(sizeof(int)*i);
+  m_act = (smnumber *)omAlloc(sizeof(smnumber)*i);
+  m_res = (smnumber *)omAlloc0(sizeof(smnumber)*i);
+  dumm = (smnumber)omAllocBin(smnrec_bin);
+  pmat = smat->m;
+  for(i=ncols; i; i--)
+  {
+    m_act[i] = sm_Poly2Smnumber(pmat[i-1],_R);
+  }
+  omFreeSize((ADDRESS)pmat,smat->ncols*sizeof(poly));
+  omFreeBin((ADDRESS)smat, sip_sideal_bin);
+}
+
+/*
+* destructor
+*/
+sparse_number_mat::~sparse_number_mat()
+{
+  int i;
+  omFreeBin((ADDRESS)dumm,  smnrec_bin);
+  i = ncols+1;
+  omFreeSize((ADDRESS)m_res, sizeof(smnumber)*i);
+  omFreeSize((ADDRESS)m_act, sizeof(smnumber)*i);
+  omFreeSize((ADDRESS)wcl, sizeof(int)*i);
+  i = nrows+1;
+  omFreeSize((ADDRESS)wrw, sizeof(int)*i);
+  omFreeSize((ADDRESS)m_row, sizeof(smnumber)*i);
+  omFreeSize((ADDRESS)perm, sizeof(int)*i);
+}
+
+/*
+* triangularization by Gauss-elimination
+*/
+void sparse_number_mat::smTriangular()
+{
+  tored--;
+  this->smZeroToredElim();
+  if (sing != 0) return;
+  while (act > 1)
+  {
+    this->smRealPivot();
+    this->smSelectPR();
+    this->smGElim();
+    crd++;
+    this->smColToRow();
+    act--;
+    this->smRowToCol();
+    this->smZeroToredElim();
+    if (sing != 0) return;
+  }
+  if (TEST_OPT_PROT) PrintS(".\n");
+  piv = m_act[1];
+  rpiv = piv->pos;
+  m_act[1] = piv->n;
+  piv->n = NULL;
+  crd++;
+  this->smColToRow();
+  act--;
+  this->smRowToCol();
+}
+
+/*
+* solve the triangular system
+*/
+void sparse_number_mat::smSolv()
+{
+  int i, j;
+  number x, y, z;
+  smnumber s, d, r = m_row[nrows];
+
+  m_row[nrows] = NULL;
+  sol = (number *)omAlloc0(sizeof(number)*(crd+1));
+  while (r != NULL)  // expand the rigth hand side
+  {
+    sol[r->pos] = r->m;
+    s = r;
+    r = r->n;
+    omFreeBin((ADDRESS)s,  smnrec_bin);
+  }
+  i = crd;  // solve triangular system
+  if (sol[i] != NULL)
+  {
+    x = sol[i];
+    sol[i] = n_Div(x, m_res[i]->m,_R->cf);
+    n_Delete(&x,_R->cf);
+  }
+  i--;
+  while (i > 0)
+  {
+    x = NULL;
+    d = m_res[i];
+    s = d->n;
+    while (s != NULL)
+    {
+      j = s->pos;
+      if (sol[j] != NULL)
+      {
+        z = n_Mult(sol[j], s->m,_R->cf);
+        if (x != NULL)
+        {
+          y = x;
+          x = n_Sub(y, z,_R->cf);
+          n_Delete(&y,_R->cf);
+          n_Delete(&z,_R->cf);
+        }
+        else
+          x = n_InpNeg(z,_R->cf);
+      }
+      s = s->n;
+    }
+    if (sol[i] != NULL)
+    {
+      if (x != NULL)
+      {
+        y = n_Add(x, sol[i],_R->cf);
+        n_Delete(&x,_R->cf);
+        if (n_IsZero(y,_R->cf))
+        {
+          n_Delete(&sol[i],_R->cf);
+          sol[i] = NULL;
+        }
+        else
+          sol[i] = y;
+      }
+    }
+    else
+      sol[i] = x;
+    if (sol[i] != NULL)
+    {
+      x = sol[i];
+      sol[i] = n_Div(x, d->m,_R->cf);
+      n_Delete(&x,_R->cf);
+    }
+    i--;
+  }
+  this->smAllDel();
+}
+
+/*
+* transform the result to an ideal
+*/
+ideal sparse_number_mat::smRes2Ideal()
+{
+  int i, j;
+  ideal res = idInit(crd, 1);
+
+  for (i=crd; i; i--)
+  {
+    j = perm[i]-1;
+    res->m[j] = sm_Smnumber2Poly(sol[i],_R);
+  }
+  omFreeSize((ADDRESS)sol, sizeof(number)*(crd+1));
+  return res;
+}
+
+/* ----------------- pivot method ------------------ */
+
+/*
+* compute pivot
+*/
+void sparse_number_mat::smRealPivot()
+{
+  smnumber a;
+  number x, xo;
+  int i, copt, ropt;
+
+  xo=n_Init(0,_R->cf);
+  for (i=act; i; i--)
+  {
+    a = m_act[i];
+    while ((a!=NULL) && (a->pos<=tored))
+    {
+      x = a->m;
+      if (n_GreaterZero(x,_R->cf))
+      {
+        if (n_Greater(x,xo,_R->cf))
+        {
+          n_Delete(&xo,_R->cf);
+          xo = n_Copy(x,_R->cf);
+          copt = i;
+          ropt = a->pos;
+        }
+      }
+      else
+      {
+        xo = n_InpNeg(xo,_R->cf);
+        if (n_Greater(xo,x,_R->cf))
+        {
+          n_Delete(&xo,_R->cf);
+          xo = n_Copy(x,_R->cf);
+          copt = i;
+          ropt = a->pos;
+        }
+        xo = n_InpNeg(xo,_R->cf);
+      }
+      a = a->n;
+    }
+  }
+  rpiv = ropt;
+  if (copt != act)
+  {
+    a = m_act[act];
+    m_act[act] = m_act[copt];
+    m_act[copt] = a;
+  }
+  n_Delete(&xo,_R->cf);
+}
+
+/* ----------------- elimination ------------------ */
+
+/* one step of Gauss-elimination */
+void sparse_number_mat::smGElim()
+{
+  number p = n_Invers(piv->m,_R->cf);  // pivotelement
+  smnumber c = m_act[act];      // pivotcolumn
+  smnumber r = red;             // row to reduce
+  smnumber res, a, b;
+  number w, ha, hb;
+
+  if ((c == NULL) || (r == NULL))
+  {
+    while (r!=NULL) sm_NumberDelete(&r,_R);
+    return;
+  }
+  do
+  {
+    a = m_act[r->pos];
+    res = dumm;
+    res->n = NULL;
+    b = c;
+    w = n_Mult(r->m, p,_R->cf);
+    n_Delete(&r->m,_R->cf);
+    r->m = w;
+    loop   // combine the chains a and b: a + w*b
+    {
+      if (a == NULL)
+      {
+        do
+        {
+          res = res->n = smNumberCopy(b);
+          res->m = n_Mult(b->m, w,_R->cf);
+          b = b->n;
+        } while (b != NULL);
+        break;
+      }
+      if (a->pos < b->pos)
+      {
+        res = res->n = a;
+        a = a->n;
+      }
+      else if (a->pos > b->pos)
+      {
+        res = res->n = smNumberCopy(b);
+        res->m = n_Mult(b->m, w,_R->cf);
+        b = b->n;
+      }
+      else
+      {
+        hb = n_Mult(b->m, w,_R->cf);
+        ha = n_Add(a->m, hb,_R->cf);
+        n_Delete(&hb,_R->cf);
+        n_Delete(&a->m,_R->cf);
+        if (n_IsZero(ha,_R->cf))
+        {
+          sm_NumberDelete(&a,_R);
+        }
+        else
+        {
+          a->m = ha;
+          res = res->n = a;
+          a = a->n;
+        }
+        b = b->n;
+      }
+      if (b == NULL)
+      {
+        res->n = a;
+        break;
+      }
+    }
+    m_act[r->pos] = dumm->n;
+    sm_NumberDelete(&r,_R);
+  } while (r != NULL);
+  n_Delete(&p,_R->cf);
+}
+
+/* ----------------- transfer ------------------ */
+
+/*
+* select the pivotrow and store it to red and piv
+*/
+void sparse_number_mat::smSelectPR()
+{
+  smnumber b = dumm;
+  smnumber a, ap;
+  int i;
+
+  if (TEST_OPT_PROT)
+  {
+    if ((crd+1)%10)
+      PrintS(".");
+    else
+      PrintS(".\n");
+  }
+  a = m_act[act];
+  if (a->pos < rpiv)
+  {
+    do
+    {
+      ap = a;
+      a = a->n;
+    } while (a->pos < rpiv);
+    ap->n = a->n;
+  }
+  else
+    m_act[act] = a->n;
+  piv = a;
+  a->n = NULL;
+  for (i=1; i<act; i++)
+  {
+    a = m_act[i];
+    if (a->pos < rpiv)
+    {
+      loop
+      {
+        ap = a;
+        a = a->n;
+        if ((a == NULL) || (a->pos > rpiv))
+          break;
+        if (a->pos == rpiv)
+        {
+          ap->n = a->n;
+          a->m = n_InpNeg(a->m,_R);
+          b = b->n = a;
+          b->pos = i;
+          break;
+        }
+      }
+    }
+    else if (a->pos == rpiv)
+    {
+      m_act[i] = a->n;
+      a->m = n_InpNeg(a->m,_R);
+      b = b->n = a;
+      b->pos = i;
+    }
+  }
+  b->n = NULL;
+  red = dumm->n;
+}
+
+/*
+* store the pivotcol in m_row
+*   m_act[cols][pos(rows)] => m_row[rows][pos(cols)]
+*/
+void sparse_number_mat::smColToRow()
+{
+  smnumber c = m_act[act];
+  smnumber h;
+
+  while (c != NULL)
+  {
+    h = c;
+    c = c->n;
+    h->n = m_row[h->pos];
+    m_row[h->pos] = h;
+    h->pos = crd;
+  }
+}
+
+/*
+* store the pivot and the assosiated row in m_row
+* to m_res (result):
+*   piv + m_row[rows][pos(cols)] => m_res[cols][pos(rows)]
+*/
+void sparse_number_mat::smRowToCol()
+{
+  smnumber r = m_row[rpiv];
+  smnumber a, ap, h;
+
+  m_row[rpiv] = NULL;
+  perm[crd] = rpiv;
+  piv->pos = crd;
+  m_res[crd] = piv;
+  while (r != NULL)
+  {
+    ap = m_res[r->pos];
+    loop
+    {
+      a = ap->n;
+      if (a == NULL)
+      {
+        ap->n = h = r;
+        r = r->n;
+        h->n = a;
+        h->pos = crd;
+        break;
+      }
+      ap = a;
+    }
+  }
+}
+
+/* ----------------- C++ stuff ------------------ */
+
+/*
+*  check singularity
+*/
+void sparse_number_mat::smZeroToredElim()
+{
+  smnumber a;
+  int i = act;
+
+  loop
+  {
+    if (i == 0) return;
+    a = m_act[i];
+    if ((a==NULL) || (a->pos>tored))
+    {
+      sing = 1;
+      this->smAllDel();
+      return;
+    }
+    i--;
+  }
+}
+
+/*
+* delete all smnumber's
+*/
+void sparse_number_mat::smAllDel()
+{
+  smnumber a;
+  int i;
+
+  for (i=act; i; i--)
+  {
+    a = m_act[i];
+    while (a != NULL)
+      sm_NumberDelete(&a,_R);
+  }
+  for (i=crd; i; i--)
+  {
+    a = m_res[i];
+    while (a != NULL)
+      sm_NumberDelete(&a,_R);
+  }
+  if (act)
+  {
+    for (i=nrows; i; i--)
+    {
+      a = m_row[i];
+      while (a != NULL)
+        sm_NumberDelete(&a,_R);
+    }
+  }
+}
+
+/* ----------------- internal 'C' stuff ------------------ */
+
+static void sm_NumberDelete(smnumber *r, const ring R)
+{
+  smnumber a = *r, b = a->n;
+
+  n_Delete(&a->m,R->cf);
+  omFreeBin((ADDRESS)a,  smnrec_bin);
+  *r = b;
+}
+
+static smnumber smNumberCopy(smnumber a)
+{
+  smnumber r = (smnumber)omAllocBin(smnrec_bin);
+  memcpy(r, a, sizeof(smnrec));
+  return r;
+}
+
+/*
+* from poly to smnumber
+* do not destroy p
+*/
+static smnumber sm_Poly2Smnumber(poly q, const ring R)
+{
+  smnumber a, res;
+  poly p = q;
+
+  if (p == NULL)
+    return NULL;
+  a = res = (smnumber)omAllocBin(smnrec_bin);
+  a->pos = p_GetComp(p,R);
+  a->m = pGetCoeff(p);
+  n_New(&pGetCoeff(p),R->cf);
+  loop
+  {
+    pIter(p);
+    if (p == NULL)
+    {
+      p_Delete(&q,R);
+      a->n = NULL;
+      return res;
+    }
+    a = a->n = (smnumber)omAllocBin(smnrec_bin);
+    a->pos = p_GetComp(p,R);
+    a->m = pGetCoeff(p);
+    n_New(&pGetCoeff(p),R->cf);
+  }
+}
+
+/*
+* from smnumber to poly
+* destroy a
+*/
+static poly sm_Smnumber2Poly(number a, const ring R)
+{
+  poly res;
+
+  if (a == NULL) return NULL;
+  res = p_Init(R);
+  pSetCoeff0(res, a);
+  return res;
+}
+
+/*2
+* check the input
+*/
+static BOOLEAN smCheckSolv(ideal I)
+{ int i = I->ncols;
+  if ((i == 0) || (i != I->rank-1))
+  {
+    WerrorS("wrong dimensions for linsolv");
+    return TRUE;
+  }
+  for(;i;i--)
+  {
+    if(I->m[i-1] == NULL)
+    {
+      WerrorS("singular input for linsolv");
+      return TRUE;
+    }
+  }
+  return FALSE;
+}
diff --git a/libpolys/polys/sparsmat.h b/libpolys/polys/sparsmat.h
new file mode 100644
index 0000000..023bfe6
--- /dev/null
+++ b/libpolys/polys/sparsmat.h
@@ -0,0 +1,35 @@
+#ifndef SPARSEMAT_H
+#define SPARSEMAT_H
+/*******************************************************************
+ *  Computer Algebra System SINGULAR
+ *
+ *  sparsmat.h: operations with sparse matrices
+ *          (bareis, ...)
+ *
+ *******************************************************************/
+
+
+poly sm_Mult(poly, poly, const ring);
+void sm_PolyDiv(poly, poly, const ring);
+poly sm_MultDiv(poly, poly, const poly, const ring);
+void sm_SpecialPolyDiv(poly, poly, const ring);
+/* ----------------- macros ------------------ */
+/* #define OLD_DIV 1 */
+
+#ifdef OLD_DIV
+#define SM_MULT(A,B,C, R) sm_Mult(A,B,R)
+#define SM_DIV sm_PolyDiv
+#else
+#define SM_MULT sm_MultDiv
+#define SM_DIV sm_SpecialPolyDiv
+#endif
+
+poly sm_CallDet(ideal I, const ring);
+void sm_CallBareiss(ideal smat, int x, int y, ideal & M, intvec ** iv, const ring);
+ideal sm_CallSolv(ideal I, const ring);
+
+ring sm_RingChange(const ring, long);
+void sm_KillModifiedRing(ring r);
+long sm_ExpBound(ideal, int, int, int, const ring);
+BOOLEAN sm_CheckDet(ideal, int, BOOLEAN, const ring);
+#endif
diff --git a/libpolys/polys/templates/p_Add_q__T.cc b/libpolys/polys/templates/p_Add_q__T.cc
new file mode 100644
index 0000000..89fc67c
--- /dev/null
+++ b/libpolys/polys/templates/p_Add_q__T.cc
@@ -0,0 +1,93 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    p_Add_q__Template.cc
+ *  Purpose: template for p_Add_q
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 8/00
+ *******************************************************************/
+
+/***************************************************************
+ *
+ * Returns:  p + q,
+ *           Shorter, where Shorter == Length(p) + Length(q) - Length(p+q);
+ * Destroys: p, q
+ *
+ ***************************************************************/
+LINKAGE poly p_Add_q__T(poly p, poly q, int &Shorter, const ring r)
+{
+  p_Test(p, r);
+  p_Test(q, r);
+#if PDEBUG > 0
+  int l = pLength(p) + pLength(q);
+#endif
+
+  // test for trivial cases
+  Shorter = 0;
+  if (q == NULL) return p;
+  if (p == NULL) return q;
+
+  number t, n1, n2;
+  int shorter = 0;
+  spolyrec rp;
+  poly a = &rp;
+  DECLARE_LENGTH(const unsigned long length = r->CmpL_Size);
+  DECLARE_ORDSGN(const long* ordsgn = r->ordsgn);
+
+  Top:     // compare p and q w.r.t. monomial ordering
+  p_MemCmp__T(p->exp, q->exp, length, ordsgn, goto Equal, goto Greater , goto Smaller);
+
+  Equal:
+  n1 = pGetCoeff(p);
+  n2 = pGetCoeff(q);
+  #if 0
+  t = n_Add__T(n1,n2, r);
+  n_Delete__T(&n1, r);
+  #else
+  n_InpAdd__T(n1,n2,r);
+  t = n1;
+  #endif
+  n_Delete__T(&n2, r);
+  q = p_LmFreeAndNext(q, r);
+
+  if (n_IsZero__T(t, r))
+  {
+    shorter += 2;
+    n_Delete__T(&t, r);
+    p = p_LmFreeAndNext(p, r);
+  }
+  else
+  {
+    shorter++;
+    pSetCoeff0(p,t);
+    a = pNext(a) = p;
+    pIter(p);
+  }
+  if (p==NULL) { pNext(a) = q; goto Finish;}
+  if (q==NULL) { pNext(a) = p; goto Finish;}
+  goto Top;
+
+  Greater:
+  a = pNext(a) = p;
+  pIter(p);
+  if (p==NULL) { pNext(a) = q; goto Finish;}
+  goto Top;
+
+  Smaller:
+  a = pNext(a) = q;
+  pIter(q);
+  if (q==NULL) { pNext(a) = p; goto Finish;}
+  goto Top;
+
+
+  Finish:
+  Shorter = shorter;
+
+  p_Test(pNext(&rp), r);
+#if PDEBUG > 0
+  pAssume1(l - pLength(pNext(&rp)) == Shorter);
+#endif
+  return pNext(&rp);
+}
+
diff --git a/libpolys/polys/templates/p_Copy__T.cc b/libpolys/polys/templates/p_Copy__T.cc
new file mode 100644
index 0000000..fa52cdb
--- /dev/null
+++ b/libpolys/polys/templates/p_Copy__T.cc
@@ -0,0 +1,37 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    p_Copy__Template.cc
+ *  Purpose: template for p_Copy__T
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 8/00
+ *******************************************************************/
+
+LINKAGE poly p_Copy__T(poly s_p, const ring r)
+{
+  // let's not do tests here -- but instead allow
+  // to be sloppy
+  spolyrec dp;
+  poly d_p = &dp;
+  omBin bin = r->PolyBin;
+  poly h;
+
+  DECLARE_LENGTH(const unsigned long length = r->ExpL_Size);
+
+  while (s_p != NULL)
+  {
+    p_AllocBin(pNext(d_p), bin, r);
+    pIter(d_p);
+    pSetCoeff0(d_p, n_Copy__T(pGetCoeff(s_p), r));
+    // it is better to iter here,
+    // for MemCopy advances goes from low to high addresses
+    h = s_p;
+    s_p = pNext(s_p);
+    p_MemCopy__T(d_p->exp, h->exp, length);
+  }
+  pNext(d_p) = NULL;
+
+  return dp.next;
+}
+
diff --git a/libpolys/polys/templates/p_Delete__T.cc b/libpolys/polys/templates/p_Delete__T.cc
new file mode 100644
index 0000000..a37261f
--- /dev/null
+++ b/libpolys/polys/templates/p_Delete__T.cc
@@ -0,0 +1,22 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    p_Delete__Template.cc
+ *  Purpose: template for p_Delete
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 8/00
+ *******************************************************************/
+
+LINKAGE void p_Delete__T(poly* pp, const ring r)
+{
+  poly p = *pp;
+
+  while (p != NULL)
+  {
+    n_Delete__T(&(p->coef), r);
+    p = p_LmFreeAndNext(p, r);
+  }
+  *pp = NULL;
+}
+
diff --git a/libpolys/polys/templates/p_MemAdd.h b/libpolys/polys/templates/p_MemAdd.h
new file mode 100644
index 0000000..18bdc1e
--- /dev/null
+++ b/libpolys/polys/templates/p_MemAdd.h
@@ -0,0 +1,388 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    p_MemAdd.h
+ *  Purpose: macros for memory addition
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 8/00
+ *******************************************************************/
+#ifndef P_MEM_ADD_H
+#define P_MEM_ADD_H
+
+/***************************************************************
+ *
+ * MemSum
+ *
+ ***************************************************************/
+
+#define _p_MemSum(i, r, s1, s2) r[i] = s1[i] + s2[i]
+
+#define _p_MemSum_LengthOne(r, s1, s2) _p_MemSum(0, r, s1, s2)
+#define _p_MemSum_LengthTwo(r, s1, s2) do{_p_MemSum_LengthOne(r, s1, s2); _p_MemSum(1, r, s1, s2);} while(0)
+#define _p_MemSum_LengthThree(r, s1, s2) do{_p_MemSum_LengthTwo(r, s1, s2); _p_MemSum(2, r, s1, s2);} while(0)
+#define _p_MemSum_LengthFour(r, s1, s2) do{_p_MemSum_LengthThree(r, s1, s2); _p_MemSum(3, r, s1, s2);} while(0)
+#define _p_MemSum_LengthFive(r, s1, s2) do{_p_MemSum_LengthFour(r, s1, s2); _p_MemSum(4, r, s1, s2);} while(0)
+#define _p_MemSum_LengthSix(r, s1, s2) do{_p_MemSum_LengthFive(r, s1, s2); _p_MemSum(5, r, s1, s2);} while(0)
+#define _p_MemSum_LengthSeven(r, s1, s2) do{_p_MemSum_LengthSix(r, s1, s2); _p_MemSum(6, r, s1, s2);} while(0)
+#define _p_MemSum_LengthEight(r, s1, s2) do{_p_MemSum_LengthSeven(r, s1, s2); _p_MemSum(7, r, s1, s2);} while(0)
+
+#define _p_MemSum_Declare(r, s1, s2)                \
+  const unsigned long* _s1 = ((unsigned long*) s1); \
+  const unsigned long* _s2 = ((unsigned long*) s2); \
+  unsigned long* _r = ((unsigned long*) r)
+
+#define p_MemSum_LengthOne(r, s1, s2, length) _p_MemSum_LengthOne(r, s1, s2)
+#define p_MemSum_LengthTwo(r, s1, s2, length)   \
+do                                              \
+{                                               \
+  _p_MemSum_Declare(r,s1,s2);                    \
+  _p_MemSum_LengthTwo(_r, _s1, _s2);            \
+}                                               \
+while (0)
+#define p_MemSum_LengthThree(r, s1, s2, length) \
+do                                              \
+{                                               \
+  _p_MemSum_Declare(r,s1,s2);                    \
+  _p_MemSum_LengthThree(_r, _s1, _s2);          \
+}                                               \
+while (0)
+#define p_MemSum_LengthFour(r, s1, s2, length)  \
+do                                              \
+{                                               \
+  _p_MemSum_Declare(r,s1,s2);                    \
+  _p_MemSum_LengthFour(_r, _s1, _s2);           \
+}                                               \
+while (0)
+#define p_MemSum_LengthFive(r, s1, s2, length)  \
+do                                              \
+{                                               \
+  _p_MemSum_Declare(r,s1,s2);                    \
+  _p_MemSum_LengthFive(_r, _s1, _s2);           \
+}                                               \
+while (0)
+#define p_MemSum_LengthSix(r, s1, s2, length)   \
+do                                              \
+{                                               \
+  _p_MemSum_Declare(r,s1,s2);                    \
+  _p_MemSum_LengthSix(_r, _s1, _s2);            \
+}                                               \
+while (0)
+#define p_MemSum_LengthSeven(r, s1, s2, length) \
+do                                              \
+{                                               \
+  _p_MemSum_Declare(r,s1,s2);                    \
+  _p_MemSum_LengthSeven(_r, _s1, _s2);          \
+}                                               \
+while (0)
+#define p_MemSum_LengthEight(r, s1, s2, length) \
+do                                              \
+{                                               \
+  _p_MemSum_Declare(r,s1,s2);                    \
+  _p_MemSum_LengthEight(_r, _s1, _s2);          \
+}                                               \
+while (0)
+
+#define p_MemSum_LengthGeneral(r, s1, s2, length)   \
+do                                                  \
+{                                                   \
+  _p_MemSum_Declare(r,s1,s2);                       \
+  const unsigned long _l = (unsigned long) length;       \
+  unsigned long _i = 0;                             \
+                                                    \
+  do                                                \
+  {                                                 \
+    _r[_i] = _s1[_i] + _s2[_i];                     \
+    _i++;                                           \
+  }                                                 \
+  while (_i != _l);                                 \
+}                                                   \
+while (0)
+
+/***************************************************************
+ *
+ * MemAdd
+ *
+ ***************************************************************/
+#define _p_MemAdd(i, r, s) r[i] += s[i]
+
+#define _p_MemAdd_LengthOne(r, s) _p_MemAdd(0, r, s)
+#define _p_MemAdd_LengthTwo(r, s) do{_p_MemAdd_LengthOne(r, s); _p_MemAdd(1, r, s);} while(0)
+#define _p_MemAdd_LengthThree(r, s) do{_p_MemAdd_LengthTwo(r, s); _p_MemAdd(2, r, s);} while(0)
+#define _p_MemAdd_LengthFour(r, s) do{_p_MemAdd_LengthThree(r, s); _p_MemAdd(3, r, s);} while(0)
+#define _p_MemAdd_LengthFive(r, s) do{_p_MemAdd_LengthFour(r, s); _p_MemAdd(4, r, s);} while(0)
+#define _p_MemAdd_LengthSix(r, s) do{_p_MemAdd_LengthFive(r, s); _p_MemAdd(5, r, s);} while(0)
+#define _p_MemAdd_LengthSeven(r, s) do{_p_MemAdd_LengthSix(r, s); _p_MemAdd(6, r, s);} while(0)
+#define _p_MemAdd_LengthEight(r, s) do{_p_MemAdd_LengthSeven(r, s); _p_MemAdd(7, r, s);} while(0)
+
+#define _p_MemAdd_Declare(r, s)                \
+  const unsigned long* _s = ((unsigned long*) s); \
+  unsigned long* _r = ((unsigned long*) r)
+
+#define p_MemAdd_LengthOne(r, s, length) _p_MemAdd_LengthOne(r, s)
+#define p_MemAdd_LengthTwo(r, s, length)   \
+do                                              \
+{                                               \
+  _p_MemAdd_Declare(r,s);                    \
+  _p_MemAdd_LengthTwo(_r, _s);            \
+}                                               \
+while (0)
+#define p_MemAdd_LengthThree(r, s, length) \
+do                                              \
+{                                               \
+  _p_MemAdd_Declare(r,s);                    \
+  _p_MemAdd_LengthThree(_r, _s);          \
+}                                               \
+while (0)
+#define p_MemAdd_LengthFour(r, s, length)  \
+do                                              \
+{                                               \
+  _p_MemAdd_Declare(r,s);                    \
+  _p_MemAdd_LengthFour(_r, _s);           \
+}                                               \
+while (0)
+#define p_MemAdd_LengthFive(r, s, length)  \
+do                                              \
+{                                               \
+  _p_MemAdd_Declare(r,s);                    \
+  _p_MemAdd_LengthFive(_r, _s);           \
+}                                               \
+while (0)
+#define p_MemAdd_LengthSix(r, s, length)   \
+do                                              \
+{                                               \
+  _p_MemAdd_Declare(r,s);                    \
+  _p_MemAdd_LengthSix(_r, _s);            \
+}                                               \
+while (0)
+#define p_MemAdd_LengthSeven(r, s, length) \
+do                                              \
+{                                               \
+  _p_MemAdd_Declare(r,s);                    \
+  _p_MemAdd_LengthSeven(_r, _s);          \
+}                                               \
+while (0)
+#define p_MemAdd_LengthEight(r, s, length) \
+do                                              \
+{                                               \
+  _p_MemAdd_Declare(r,s);                    \
+  _p_MemAdd_LengthEight(_r, _s);          \
+}                                               \
+while (0)
+
+#define p_MemAdd_LengthGeneral(r, s, length)       \
+do                                                  \
+{                                                   \
+  _p_MemAdd_Declare(r,s);                          \
+  const unsigned long _l = (unsigned long) length;  \
+  unsigned long _i = 0;                             \
+                                                    \
+  do                                                \
+  {                                                 \
+    _r[_i] += _s[_i];                               \
+    _i++;                                           \
+  }                                                 \
+  while (_i != _l);                                 \
+}                                                   \
+while (0)
+
+
+/***************************************************************
+ *
+ * MemDiff
+ *
+ ***************************************************************/
+#define _p_MemDiff(i, r, s1, s2) r[i] = s1[i] - s2[i]
+
+#define _p_MemDiff_LengthOne(r, s1, s2) _p_MemDiff(0, r, s1, s2)
+#define _p_MemDiff_LengthTwo(r, s1, s2) do{_p_MemDiff_LengthOne(r, s1, s2); _p_MemDiff(1, r, s1, s2);} while(0)
+#define _p_MemDiff_LengthThree(r, s1, s2) do{_p_MemDiff_LengthTwo(r, s1, s2); _p_MemDiff(2, r, s1, s2);} while(0)
+#define _p_MemDiff_LengthFour(r, s1, s2) do{_p_MemDiff_LengthThree(r, s1, s2); _p_MemDiff(3, r, s1, s2);} while(0)
+#define _p_MemDiff_LengthFive(r, s1, s2) do{_p_MemDiff_LengthFour(r, s1, s2); _p_MemDiff(4, r, s1, s2);} while(0)
+#define _p_MemDiff_LengthSix(r, s1, s2) do{_p_MemDiff_LengthFive(r, s1, s2); _p_MemDiff(5, r, s1, s2);} while(0)
+#define _p_MemDiff_LengthSeven(r, s1, s2) do{_p_MemDiff_LengthSix(r, s1, s2); _p_MemDiff(6, r, s1, s2);} while(0)
+#define _p_MemDiff_LengthEight(r, s1, s2) do{_p_MemDiff_LengthSeven(r, s1, s2); _p_MemDiff(7, r, s1, s2);} while(0)
+
+#define _p_MemDiff_Declare(r, s1, s2)                \
+  const unsigned long* _s1 = ((unsigned long*) s1); \
+  const unsigned long* _s2 = ((unsigned long*) s2); \
+  unsigned long* _r = ((unsigned long*) r)
+
+#define p_MemDiff_LengthOne(r, s1, s2, length) _p_MemDiff_LengthOne(r, s1, s2)
+#define p_MemDiff_LengthTwo(r, s1, s2, length)   \
+do                                              \
+{                                               \
+  _p_MemDiff_Declare(r,s1,s2);                    \
+  _p_MemDiff_LengthTwo(_r, _s1, _s2);            \
+}                                               \
+while (0)
+#define p_MemDiff_LengthThree(r, s1, s2, length) \
+do                                              \
+{                                               \
+  _p_MemDiff_Declare(r,s1,s2);                    \
+  _p_MemDiff_LengthThree(_r, _s1, _s2);          \
+}                                               \
+while (0)
+#define p_MemDiff_LengthFour(r, s1, s2, length)  \
+do                                              \
+{                                               \
+  _p_MemDiff_Declare(r,s1,s2);                    \
+  _p_MemDiff_LengthFour(_r, _s1, _s2);           \
+}                                               \
+while (0)
+#define p_MemDiff_LengthFive(r, s1, s2, length)  \
+do                                              \
+{                                               \
+  _p_MemDiff_Declare(r,s1,s2);                    \
+  _p_MemDiff_LengthFive(_r, _s1, _s2);           \
+}                                               \
+while (0)
+#define p_MemDiff_LengthSix(r, s1, s2, length)   \
+do                                              \
+{                                               \
+  _p_MemDiff_Declare(r,s1,s2);                    \
+  _p_MemDiff_LengthSix(_r, _s1, _s2);            \
+}                                               \
+while (0)
+#define p_MemDiff_LengthSeven(r, s1, s2, length) \
+do                                              \
+{                                               \
+  _p_MemDiff_Declare(r,s1,s2);                    \
+  _p_MemDiff_LengthSeven(_r, _s1, _s2);          \
+}                                               \
+while (0)
+#define p_MemDiff_LengthEight(r, s1, s2, length) \
+do                                              \
+{                                               \
+  _p_MemDiff_Declare(r,s1,s2);                    \
+  _p_MemDiff_LengthEight(_r, _s1, _s2);          \
+}                                               \
+while (0)
+
+#define p_MemDiff_LengthGeneral(r, s1, s2, length)   \
+do                                                  \
+{                                                   \
+  _p_MemDiff_Declare(r,s1,s2);                       \
+  const unsigned long _l = (unsigned long) length;       \
+  unsigned long _i = 0;                             \
+                                                    \
+  do                                                \
+  {                                                 \
+    _r[_i] = _s1[_i] - _s2[_i];                     \
+    _i++;                                           \
+  }                                                 \
+  while (_i != _l);                                 \
+}                                                   \
+while (0)
+
+
+/***************************************************************
+ *
+ * MemSub
+ *
+ ***************************************************************/
+
+#define _p_MemSub(i, r, s) r[i] -= s[i]
+
+#define _p_MemSub_LengthOne(r, s) _p_MemSub(0, r, s)
+#define _p_MemSub_LengthTwo(r, s) do{_p_MemSub_LengthOne(r, s); _p_MemSub(1, r, s);} while(0)
+#define _p_MemSub_LengthThree(r, s) do{_p_MemSub_LengthTwo(r, s); _p_MemSub(2, r, s);} while(0)
+#define _p_MemSub_LengthFour(r, s) do{_p_MemSub_LengthThree(r, s); _p_MemSub(3, r, s);} while(0)
+#define _p_MemSub_LengthFive(r, s) do{_p_MemSub_LengthFour(r, s); _p_MemSub(4, r, s);} while(0)
+#define _p_MemSub_LengthSix(r, s) do{_p_MemSub_LengthFive(r, s); _p_MemSub(5, r, s);} while(0)
+#define _p_MemSub_LengthSeven(r, s) do{_p_MemSub_LengthSix(r, s); _p_MemSub(6, r, s);} while(0)
+#define _p_MemSub_LengthEight(r, s) do{_p_MemSub_LengthSeven(r, s); _p_MemSub(7, r, s);} while(0)
+
+#define _p_MemSub_Declare(r, s)                \
+  const unsigned long* _s = ((unsigned long*) s); \
+  unsigned long* _r = ((unsigned long*) r)
+
+#define p_MemSub_LengthOne(r, s, length) _p_MemSub_LengthOne(r, s)
+#define p_MemSub_LengthTwo(r, s, length)   \
+do                                              \
+{                                               \
+  _p_MemSub_Declare(r,s);                    \
+  _p_MemSub_LengthTwo(_r, _s);            \
+}                                               \
+while (0)
+#define p_MemSub_LengthThree(r, s, length) \
+do                                              \
+{                                               \
+  _p_MemSub_Declare(r,s);                    \
+  _p_MemSub_LengthThree(_r, _s);          \
+}                                               \
+while (0)
+#define p_MemSub_LengthFour(r, s, length)  \
+do                                              \
+{                                               \
+  _p_MemSub_Declare(r,s);                    \
+  _p_MemSub_LengthFour(_r, _s);           \
+}                                               \
+while (0)
+#define p_MemSub_LengthFive(r, s, length)  \
+do                                              \
+{                                               \
+  _p_MemSub_Declare(r,s);                    \
+  _p_MemSub_LengthFive(_r, _s);           \
+}                                               \
+while (0)
+#define p_MemSub_LengthSix(r, s, length)   \
+do                                              \
+{                                               \
+  _p_MemSub_Declare(r,s);                    \
+  _p_MemSub_LengthSix(_r, _s);            \
+}                                               \
+while (0)
+#define p_MemSub_LengthSeven(r, s, length) \
+do                                              \
+{                                               \
+  _p_MemSub_Declare(r,s);                    \
+  _p_MemSub_LengthSeven(_r, _s);          \
+}                                               \
+while (0)
+#define p_MemSub_LengthEight(r, s, length) \
+do                                              \
+{                                               \
+  _p_MemSub_Declare(r,s);                    \
+  _p_MemSub_LengthEight(_r, _s);          \
+}                                               \
+while (0)
+
+#define p_MemSub_LengthGeneral(r, s, length)       \
+do                                                  \
+{                                                   \
+  _p_MemSub_Declare(r,s);                          \
+  const unsigned long _l = (unsigned long) length;  \
+  unsigned long _i = 0;                             \
+                                                    \
+  do                                                \
+  {                                                 \
+    _r[_i] -= _s[_i];                               \
+    _i++;                                           \
+  }                                                 \
+  while (_i != _l);                                 \
+}                                                   \
+while (0)
+
+#define _p_MemAddSub_Declare(r, s, t)                \
+  const unsigned long* _s = ((unsigned long*) s); \
+  const unsigned long* _t = ((unsigned long*) t); \
+  unsigned long* _r = ((unsigned long*) r)
+
+#define p_MemAddSub_LengthGeneral(r, s, t, length)  \
+do                                                  \
+{                                                   \
+  _p_MemAddSub_Declare(r,s, t);                     \
+  const unsigned long _l = (unsigned long) length;  \
+  unsigned long _i = 0;                             \
+                                                    \
+  do                                                \
+  {                                                 \
+    _r[_i] += _s[_i] - _t[_i];                      \
+    _i++;                                           \
+  }                                                 \
+  while (_i != _l);                                 \
+}                                                   \
+while (0)
+
+#endif /* P_MEM_ADD_H */
diff --git a/libpolys/polys/templates/p_MemCmp.h b/libpolys/polys/templates/p_MemCmp.h
new file mode 100644
index 0000000..942f746
--- /dev/null
+++ b/libpolys/polys/templates/p_MemCmp.h
@@ -0,0 +1,948 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    p_MemCmp.h
+ *  Purpose: macros for memory comparisons
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 8/00
+ *******************************************************************/
+#ifndef P_MEM_CMP_H
+#define P_MEM_CMP_H
+
+/***************************************************************
+ *
+ *  auxiallary macros
+ *
+ *******************************************************************/
+#define _p_MemCmp_Declare(s1, s2)                   \
+  const unsigned long* _s1 = ((unsigned long*) s1); \
+  const unsigned long* _s2 = ((unsigned long*) s2); \
+  register unsigned long _v1;                       \
+  register unsigned long _v2
+
+#define _p_MemCmp_Equal(i, s1, s2, actionE) \
+  do {  _v1=((unsigned long*)s1)[i]; _v2=((unsigned long*)s2)[i]; if (_v1==_v2) actionE; }while (0)
+#define _p_MemCmp_NotEqual(actionG, actionS)   \
+  do {if (_v1 > _v2) actionG; actionS;} while (0)
+
+#define _p_MemCmp_LengthOne_Equal(i, s1, s2, actionE) \
+  _p_MemCmp_Equal(i, s1, s2, actionE)
+#define _p_MemCmp_LengthTwo_Equal(i, s1, s2, actionE) \
+  _p_MemCmp_Equal(i, s1, s2, _p_MemCmp_Equal(i+1, s1, s2, actionE))
+#define _p_MemCmp_LengthThree_Equal(i, s1, s2, actionE) \
+  _p_MemCmp_LengthTwo_Equal(i, s1, s2, _p_MemCmp_Equal(i+2, s1, s2, actionE))
+#define _p_MemCmp_LengthFour_Equal(i, s1, s2, actionE) \
+  _p_MemCmp_LengthThree_Equal(i, s1, s2, _p_MemCmp_Equal(i+3, s1, s2, actionE))
+#define _p_MemCmp_LengthFive_Equal(i, s1, s2, actionE) \
+  _p_MemCmp_LengthFour_Equal(i, s1, s2, _p_MemCmp_Equal(i+4, s1, s2, actionE))
+#define _p_MemCmp_LengthSix_Equal(i, s1, s2, actionE) \
+  _p_MemCmp_LengthFive_Equal(i, s1, s2, _p_MemCmp_Equal(i+5, s1, s2, actionE))
+#define _p_MemCmp_LengthSeven_Equal(i, s1, s2, actionE) \
+  _p_MemCmp_LengthSix_Equal(i, s1, s2, _p_MemCmp_Equal(i+6, s1, s2, actionE))
+#define _p_MemCmp_LengthEight_Equal(i, s1, s2, actionE) \
+  _p_MemCmp_LengthSeven_Equal(i, s1, s2, _p_MemCmp_Equal(i+7, s1, s2, actionE))
+#define _p_MemCmp_LengthGeneral_Equal(i, s1, s2, length, actionE)   \
+do                                                                  \
+{                                                                   \
+                                                                    \
+  register unsigned long _i = (unsigned long) i;                    \
+  const unsigned long _l =                                          \
+         (unsigned long) length + (unsigned long)i ;                \
+                                                                    \
+  LengthGeneral_LoopTop:                                            \
+    _v1 = s1[_i];                                                   \
+    _v2 = s2[_i];                                                   \
+    if (_v1 == _v2)                                                 \
+    {                                                               \
+      _i++;                                                         \
+      if (_i == _l) actionE;                                        \
+      else  goto LengthGeneral_LoopTop;                             \
+    }                                                               \
+}                                                                   \
+while (0)
+
+/***************************************************************
+ *
+ *  Pomog
+ *
+ *******************************************************************/
+#define p_MemCmp_LengthOne_OrdPomog(s1, s2, length, ordsgn, actionE, actionG, actionS) \
+do                                                                          \
+{                                                                           \
+  _p_MemCmp_Declare(s1,s2);                                                 \
+  _p_MemCmp_LengthOne_Equal(0, _s1, _s2, actionE);                          \
+  _p_MemCmp_NotEqual(actionG, actionS);                                     \
+}                                                                           \
+while (0)
+#define p_MemCmp_LengthTwo_OrdPomog(s1, s2, length, ordsgn, actionE, actionG, actionS) \
+do                                                                          \
+{                                                                           \
+  _p_MemCmp_Declare(s1,s2);                                                 \
+  _p_MemCmp_LengthTwo_Equal(0, _s1, _s2, actionE);                 \
+  _p_MemCmp_NotEqual(actionG, actionS);                                      \
+}                                                                           \
+while (0)
+#define p_MemCmp_LengthThree_OrdPomog(s1, s2, length, ordsgn, actionE, actionG, actionS)   \
+do                                                                              \
+{                                                                               \
+  _p_MemCmp_Declare(s1,s2);                                                     \
+  _p_MemCmp_LengthThree_Equal(0, _s1, _s2, actionE);                   \
+  _p_MemCmp_NotEqual(actionG, actionS);                                      \
+}                                                                               \
+while (0)
+#define p_MemCmp_LengthFour_OrdPomog(s1, s2, length, ordsgn, actionE, actionG, actionS)    \
+do                                                                              \
+{                                                                               \
+  _p_MemCmp_Declare(s1,s2);                                                     \
+  _p_MemCmp_LengthFour_Equal(0, _s1, _s2, actionE);                    \
+  _p_MemCmp_NotEqual(actionG, actionS);                                      \
+}                                                                               \
+while (0)
+#define p_MemCmp_LengthFive_OrdPomog(s1, s2, length, ordsgn, actionE, actionG, actionS)    \
+do                                                                              \
+{                                                                               \
+  _p_MemCmp_Declare(s1,s2);                                                     \
+  _p_MemCmp_LengthFive_Equal(0, _s1, _s2, actionE);                    \
+  _p_MemCmp_NotEqual(actionG, actionS);                                      \
+}                                                                               \
+while (0)
+#define p_MemCmp_LengthSix_OrdPomog(s1, s2, length, ordsgn, actionE, actionG, actionS) \
+do                                                                          \
+{                                                                           \
+  _p_MemCmp_Declare(s1,s2);                                                 \
+  _p_MemCmp_LengthSix_Equal(0, _s1, _s2, actionE);                 \
+  _p_MemCmp_NotEqual(actionG, actionS);                                      \
+}                                                                           \
+while (0)
+#define p_MemCmp_LengthSeven_OrdPomog(s1, s2, length, ordsgn, actionE, actionG, actionS)   \
+do                                                                              \
+{                                                                               \
+  _p_MemCmp_Declare(s1,s2);                                                     \
+  _p_MemCmp_LengthSeven_Equal(0, _s1, _s2, actionE);                   \
+  _p_MemCmp_NotEqual(actionG, actionS);;                                      \
+}                                                                               \
+while (0)
+
+#define p_MemCmp_LengthEight_OrdPomog(s1, s2, length, ordsgn, actionE, actionG, actionS)   \
+do                                                                              \
+{                                                                               \
+  _p_MemCmp_Declare(s1,s2);                                                     \
+  _p_MemCmp_LengthEight_Equal(0, _s1, _s2, actionE);                   \
+  _p_MemCmp_NotEqual(actionG, actionS);                                      \
+}                                                                               \
+while (0)
+#define p_MemCmp_LengthGeneral_OrdPomog(s1, s2, length, ordsgn, actionE, actionG, actionS) \
+do                                                                              \
+{                                                                               \
+  _p_MemCmp_Declare(s1,s2);                                                     \
+  _p_MemCmp_LengthGeneral_Equal(0, _s1, _s2, length, actionE);      \
+  _p_MemCmp_NotEqual(actionG, actionS);                                          \
+}                                                                               \
+while (0)
+
+/***************************************************************
+ *
+ *  Nomog
+ *
+ *******************************************************************/
+#define p_MemCmp_LengthOne_OrdNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)     \
+  p_MemCmp_LengthOne_OrdPomog(s1, s2, length, ordsgn, actionE, actionS, actionG)
+#define p_MemCmp_LengthTwo_OrdNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)     \
+  p_MemCmp_LengthTwo_OrdPomog(s1, s2, length, ordsgn, actionE, actionS, actionG)
+#define p_MemCmp_LengthThree_OrdNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)   \
+  p_MemCmp_LengthThree_OrdPomog(s1, s2, length, ordsgn, actionE, actionS, actionG)
+#define p_MemCmp_LengthFour_OrdNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)    \
+  p_MemCmp_LengthFour_OrdPomog(s1, s2, length, ordsgn, actionE, actionS, actionG)
+#define p_MemCmp_LengthFive_OrdNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)    \
+  p_MemCmp_LengthFive_OrdPomog(s1, s2, length, ordsgn, actionE, actionS, actionG)
+#define p_MemCmp_LengthSix_OrdNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)     \
+  p_MemCmp_LengthSix_OrdPomog(s1, s2, length, ordsgn, actionE, actionS, actionG)
+#define p_MemCmp_LengthSeven_OrdNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)   \
+  p_MemCmp_LengthSeven_OrdPomog(s1, s2, length, ordsgn, actionE, actionS, actionG)
+#define p_MemCmp_LengthEight_OrdNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)   \
+  p_MemCmp_LengthEight_OrdPomog(s1, s2, length, ordsgn, actionE, actionS, actionG)
+#define p_MemCmp_LengthGeneral_OrdNomog(s1, s2, length, ordsgn, actionE, actionG, actionS) \
+  p_MemCmp_LengthGeneral_OrdPomog(s1, s2, length, ordsgn, actionE, actionS, actionG)
+
+/***************************************************************
+ *
+ *  PomogZero
+ *
+ *******************************************************************/
+#define p_MemCmp_LengthTwo_OrdPomogZero(s1, s2, length, ordsgn, actionE, actionG, actionS)     \
+  p_MemCmp_LengthOne_OrdPomog(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthThree_OrdPomogZero(s1, s2, length, ordsgn, actionE, actionG, actionS)   \
+  p_MemCmp_LengthTwo_OrdPomog(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthFour_OrdPomogZero(s1, s2, length, ordsgn, actionE, actionG, actionS)    \
+  p_MemCmp_LengthThree_OrdPomog(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthFive_OrdPomogZero(s1, s2, length, ordsgn, actionE, actionG, actionS)    \
+  p_MemCmp_LengthFour_OrdPomog(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthSix_OrdPomogZero(s1, s2, length, ordsgn, actionE, actionG, actionS)     \
+  p_MemCmp_LengthFive_OrdPomog(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthSeven_OrdPomogZero(s1, s2, length, ordsgn, actionE, actionG, actionS)   \
+  p_MemCmp_LengthSix_OrdPomog(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthEight_OrdPomogZero(s1, s2, length, ordsgn, actionE, actionG, actionS)   \
+  p_MemCmp_LengthSeven_OrdPomog(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthGeneral_OrdPomogZero(s1, s2, length, ordsgn, actionE, actionG, actionS) \
+  p_MemCmp_LengthGeneral_OrdPomog(s1, s2, (length) -1, ordsgn, actionE, actionG, actionS)
+
+/***************************************************************
+ *
+ *  NomogZero
+ *
+ *******************************************************************/
+#define p_MemCmp_LengthTwo_OrdNomogZero(s1, s2, length, ordsgn, actionE, actionG, actionS)     \
+  p_MemCmp_LengthOne_OrdNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthThree_OrdNomogZero(s1, s2, length, ordsgn, actionE, actionG, actionS)   \
+  p_MemCmp_LengthTwo_OrdNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthFour_OrdNomogZero(s1, s2, length, ordsgn, actionE, actionG, actionS)    \
+  p_MemCmp_LengthThree_OrdNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthFive_OrdNomogZero(s1, s2, length, ordsgn, actionE, actionG, actionS)    \
+  p_MemCmp_LengthFour_OrdNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthSix_OrdNomogZero(s1, s2, length, ordsgn, actionE, actionG, actionS)     \
+  p_MemCmp_LengthFive_OrdNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthSeven_OrdNomogZero(s1, s2, length, ordsgn, actionE, actionG, actionS)   \
+  p_MemCmp_LengthSix_OrdNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthEight_OrdNomogZero(s1, s2, length, ordsgn, actionE, actionG, actionS)   \
+  p_MemCmp_LengthSeven_OrdNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthGeneral_OrdNomogZero(s1, s2, length, ordsgn, actionE, actionG, actionS) \
+  p_MemCmp_LengthGeneral_OrdNomog(s1, s2, (length) -1, ordsgn, actionE, actionG, actionS)
+
+/***************************************************************
+ *
+ *  NegPomog
+ *
+ *******************************************************************/
+#define p_MemCmp_LengthTwo_OrdNegPomog(s1, s2, length, ordsgn, actionE, actionG, actionS)  \
+  p_MemCmp_LengthOne_OrdPomog(s1, s2, length, ordsgn,                                      \
+                           _p_MemCmp_LengthOne_Equal(1, _s2, _s1,actionE),      \
+                           actionS, actionG)
+#define p_MemCmp_LengthThree_OrdNegPomog(s1, s2, length, ordsgn, actionE, actionG, actionS)    \
+  p_MemCmp_LengthOne_OrdPomog(s1, s2, length, ordsgn,                                          \
+                           _p_MemCmp_LengthTwo_Equal(1, _s2, _s1, actionE),              \
+                           actionS, actionG)
+#define p_MemCmp_LengthFour_OrdNegPomog(s1, s2, length, ordsgn, actionE, actionG, actionS) \
+  p_MemCmp_LengthOne_OrdPomog(s1, s2, length, ordsgn,                                      \
+                           _p_MemCmp_LengthThree_Equal(1, _s2, _s1, actionE),        \
+                           actionS, actionG)
+#define p_MemCmp_LengthFive_OrdNegPomog(s1, s2, length, ordsgn, actionE, actionG, actionS) \
+  p_MemCmp_LengthOne_OrdPomog(s1, s2, length, ordsgn,                                      \
+                           _p_MemCmp_LengthFour_Equal(1, _s2, _s1, actionE),         \
+                           actionS, actionG)
+#define p_MemCmp_LengthSix_OrdNegPomog(s1, s2, length, ordsgn, actionE, actionG, actionS)  \
+  p_MemCmp_LengthOne_OrdPomog(s1, s2, length, ordsgn,                                      \
+                           _p_MemCmp_LengthFive_Equal(1, _s2, _s1, actionE),         \
+                           actionS, actionG)
+#define p_MemCmp_LengthSeven_OrdNegPomog(s1, s2, length, ordsgn, actionE, actionG, actionS)    \
+  p_MemCmp_LengthOne_OrdPomog(s1, s2, length, ordsgn,                                          \
+                           _p_MemCmp_LengthSix_Equal(1, _s2, _s1, actionE),              \
+                           actionS, actionG)
+#define p_MemCmp_LengthEight_OrdNegPomog(s1, s2, length, ordsgn, actionE, actionG, actionS)    \
+  p_MemCmp_LengthOne_OrdPomog(s1, s2, length, ordsgn,                                          \
+                           _p_MemCmp_LengthSeven_Equal(1, _s2, _s1, actionE),            \
+                           actionS, actionG)
+#define p_MemCmp_LengthGeneral_OrdNegPomog(s1, s2, length, ordsgn, actionE, actionG, actionS)      \
+  p_MemCmp_LengthOne_OrdPomog(s1, s2, length, ordsgn,                                              \
+                           _p_MemCmp_LengthGeneral_Equal(1, _s2, _s1, (length) -1, actionE), \
+                           actionS, actionG)
+
+/***************************************************************
+ *
+ *  PomogNeg
+ *
+ *******************************************************************/
+#define p_MemCmp_LengthTwo_OrdPomogNeg(s1, s2, length, ordsgn, actionE, actionG, actionS)  \
+  p_MemCmp_LengthOne_OrdPomog(s1, s2, length, ordsgn,                                      \
+                           _p_MemCmp_Equal(1, _s2, _s1, actionE),               \
+                           actionG, actionS)
+#define p_MemCmp_LengthThree_OrdPomogNeg(s1, s2, length, ordsgn, actionE, actionG, actionS)    \
+  p_MemCmp_LengthTwo_OrdPomog(s1, s2, length, ordsgn,                                          \
+                           _p_MemCmp_Equal(2, _s2, _s1, actionE),                   \
+                           actionG, actionS)
+#define p_MemCmp_LengthFour_OrdPomogNeg(s1, s2, length, ordsgn, actionE, actionG, actionS) \
+  p_MemCmp_LengthThree_OrdPomog(s1, s2, length, ordsgn,                                    \
+                           _p_MemCmp_Equal(3, _s2, _s1, actionE),              \
+                           actionG, actionS)
+#define p_MemCmp_LengthFive_OrdPomogNeg(s1, s2, length, ordsgn, actionE, actionG, actionS) \
+  p_MemCmp_LengthFour_OrdPomog(s1, s2, length, ordsgn,                                     \
+                           _p_MemCmp_Equal(4, _s2, _s1, actionE),               \
+                           actionG, actionS)
+#define p_MemCmp_LengthSix_OrdPomogNeg(s1, s2, length, ordsgn, actionE, actionG, actionS)  \
+  p_MemCmp_LengthFive_OrdPomog(s1, s2, length, ordsgn,                                     \
+                           _p_MemCmp_Equal(5, _s2, _s1, actionE),               \
+                           actionG, actionS)
+#define p_MemCmp_LengthSeven_OrdPomogNeg(s1, s2, length, ordsgn, actionE, actionG, actionS)    \
+  p_MemCmp_LengthSix_OrdPomog(s1, s2, length, ordsgn,                                          \
+                           _p_MemCmp_Equal(6, _s2, _s1, actionE),                   \
+                           actionG, actionS)
+#define p_MemCmp_LengthEight_OrdPomogNeg(s1, s2, length, ordsgn, actionE, actionG, actionS)    \
+  p_MemCmp_LengthSeven_OrdPomog(s1, s2, length, ordsgn,                                        \
+                           _p_MemCmp_Equal(7, _s2, _s1, actionE),                   \
+                           actionG, actionS)
+#define p_MemCmp_LengthGeneral_OrdPomogNeg(s1, s2, length, ordsgn, actionE, actionG, actionS)  \
+  p_MemCmp_LengthGeneral_OrdPomog(s1, s2, (length-1), ordsgn,                                  \
+                           _p_MemCmp_Equal(_i, _s2, _s1, actionE),                  \
+                           actionG, actionS)
+
+/***************************************************************
+ *
+ *  PosNomog
+ *
+ *******************************************************************/
+#define p_MemCmp_LengthThree_OrdPosNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)    \
+  p_MemCmp_LengthThree_OrdNegPomog(s1, s2, length, ordsgn, actionE, actionS, actionG)
+#define p_MemCmp_LengthFour_OrdPosNomog(s1, s2, length, ordsgn, actionE, actionG, actionS) \
+  p_MemCmp_LengthFour_OrdNegPomog(s1, s2, length, ordsgn, actionE, actionS, actionG)
+#define p_MemCmp_LengthFive_OrdPosNomog(s1, s2, length, ordsgn, actionE, actionG, actionS) \
+  p_MemCmp_LengthFive_OrdNegPomog(s1, s2, length, ordsgn, actionE, actionS, actionG)
+#define p_MemCmp_LengthSix_OrdPosNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)  \
+  p_MemCmp_LengthSix_OrdNegPomog(s1, s2, length, ordsgn, actionE, actionS, actionG)
+#define p_MemCmp_LengthSeven_OrdPosNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)    \
+  p_MemCmp_LengthSeven_OrdNegPomog(s1, s2, length, ordsgn, actionE, actionS, actionG)
+#define p_MemCmp_LengthEight_OrdPosNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)    \
+  p_MemCmp_LengthEight_OrdNegPomog(s1, s2, length, ordsgn, actionE, actionS, actionG)
+#define p_MemCmp_LengthGeneral_OrdPosNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)  \
+  p_MemCmp_LengthGeneral_OrdNegPomog(s1, s2, length, ordsgn, actionE, actionS, actionG)
+
+/***************************************************************
+ *
+ *  NomogPos
+ *
+ *******************************************************************/
+#define p_MemCmp_LengthThree_OrdNomogPos(s1, s2, length, ordsgn, actionE, actionG, actionS)    \
+  p_MemCmp_LengthThree_OrdPomogNeg(s1, s2, length, ordsgn, actionE, actionS, actionG)
+#define p_MemCmp_LengthFour_OrdNomogPos(s1, s2, length, ordsgn, actionE, actionG, actionS) \
+  p_MemCmp_LengthFour_OrdPomogNeg(s1, s2, length, ordsgn, actionE, actionS, actionG)
+#define p_MemCmp_LengthFive_OrdNomogPos(s1, s2, length, ordsgn, actionE, actionG, actionS) \
+  p_MemCmp_LengthFive_OrdPomogNeg(s1, s2, length, ordsgn, actionE, actionS, actionG)
+#define p_MemCmp_LengthSix_OrdNomogPos(s1, s2, length, ordsgn, actionE, actionG, actionS)  \
+  p_MemCmp_LengthSix_OrdPomogNeg(s1, s2, length, ordsgn, actionE, actionS, actionG)
+#define p_MemCmp_LengthSeven_OrdNomogPos(s1, s2, length, ordsgn, actionE, actionG, actionS)    \
+  p_MemCmp_LengthSeven_OrdPomogNeg(s1, s2, length, ordsgn, actionE, actionS, actionG)
+#define p_MemCmp_LengthEight_OrdNomogPos(s1, s2, length, ordsgn, actionE, actionG, actionS)    \
+  p_MemCmp_LengthEight_OrdPomogNeg(s1, s2, length, ordsgn, actionE, actionS, actionG)
+#define p_MemCmp_LengthGeneral_OrdNomogPos(s1, s2, length, ordsgn, actionE, actionG, actionS)  \
+  p_MemCmp_LengthGeneral_OrdPomogNeg(s1, s2, length, ordsgn, actionE, actionS, actionG)
+
+
+/***************************************************************
+ *
+ *  PomogNegZero
+ *
+ *******************************************************************/
+#define p_MemCmp_LengthThree_OrdPomogNegZero(s1, s2, length, ordsgn, actionE, actionG, actionS)   \
+  p_MemCmp_LengthTwo_OrdPomogNeg(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthFour_OrdPomogNegZero(s1, s2, length, ordsgn, actionE, actionG, actionS)    \
+  p_MemCmp_LengthThree_OrdPomogNeg(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthFive_OrdPomogNegZero(s1, s2, length, ordsgn, actionE, actionG, actionS)    \
+  p_MemCmp_LengthFour_OrdPomogNeg(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthSix_OrdPomogNegZero(s1, s2, length, ordsgn, actionE, actionG, actionS)     \
+  p_MemCmp_LengthFive_OrdPomogNeg(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthSeven_OrdPomogNegZero(s1, s2, length, ordsgn, actionE, actionG, actionS)   \
+  p_MemCmp_LengthSix_OrdPomogNeg(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthEight_OrdPomogNegZero(s1, s2, length, ordsgn, actionE, actionG, actionS)   \
+  p_MemCmp_LengthSeven_OrdPomogNeg(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthGeneral_OrdPomogNegZero(s1, s2, length, ordsgn, actionE, actionG, actionS) \
+  p_MemCmp_LengthGeneral_OrdPomogNeg(s1, s2, (length) -1, ordsgn, actionE, actionG, actionS)
+
+/***************************************************************
+ *
+ *  NegPomogZero
+ *
+ *******************************************************************/
+#define p_MemCmp_LengthThree_OrdNegPomogZero(s1, s2, length, ordsgn, actionE, actionG, actionS)   \
+  p_MemCmp_LengthTwo_OrdNegPomog(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthFour_OrdNegPomogZero(s1, s2, length, ordsgn, actionE, actionG, actionS)    \
+  p_MemCmp_LengthThree_OrdNegPomog(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthFive_OrdNegPomogZero(s1, s2, length, ordsgn, actionE, actionG, actionS)    \
+  p_MemCmp_LengthFour_OrdNegPomog(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthSix_OrdNegPomogZero(s1, s2, length, ordsgn, actionE, actionG, actionS)     \
+  p_MemCmp_LengthFive_OrdNegPomog(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthSeven_OrdNegPomogZero(s1, s2, length, ordsgn, actionE, actionG, actionS)   \
+  p_MemCmp_LengthSix_OrdNegPomog(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthEight_OrdNegPomogZero(s1, s2, length, ordsgn, actionE, actionG, actionS)   \
+  p_MemCmp_LengthSeven_OrdNegPomog(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthGeneral_OrdNegPomogZero(s1, s2, length, ordsgn, actionE, actionG, actionS) \
+  p_MemCmp_LengthGeneral_OrdNegPomog(s1, s2, (length) -1, ordsgn, actionE, actionG, actionS)
+
+/***************************************************************
+ *
+ *  NomogPosZero
+ *
+ *******************************************************************/
+#define p_MemCmp_LengthFour_OrdNomogPosZero(s1, s2, length, ordsgn, actionE, actionG, actionS)    \
+  p_MemCmp_LengthThree_OrdNomogPos(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthFive_OrdNomogPosZero(s1, s2, length, ordsgn, actionE, actionG, actionS)    \
+  p_MemCmp_LengthFour_OrdNomogPos(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthSix_OrdNomogPosZero(s1, s2, length, ordsgn, actionE, actionG, actionS)     \
+  p_MemCmp_LengthFive_OrdNomogPos(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthSeven_OrdNomogPosZero(s1, s2, length, ordsgn, actionE, actionG, actionS)   \
+  p_MemCmp_LengthSix_OrdNomogPos(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthEight_OrdNomogPosZero(s1, s2, length, ordsgn, actionE, actionG, actionS)   \
+  p_MemCmp_LengthSeven_OrdNomogPos(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthGeneral_OrdNomogPosZero(s1, s2, length, ordsgn, actionE, actionG, actionS) \
+  p_MemCmp_LengthGeneral_OrdNomogPos(s1, s2, (length) -1, ordsgn, actionE, actionG, actionS)
+
+/***************************************************************
+ *
+ *  PosNomogZero
+ *
+ *******************************************************************/
+#define p_MemCmp_LengthFour_OrdPosNomogZero(s1, s2, length, ordsgn, actionE, actionG, actionS)    \
+  p_MemCmp_LengthThree_OrdPosNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthFive_OrdPosNomogZero(s1, s2, length, ordsgn, actionE, actionG, actionS)    \
+  p_MemCmp_LengthFour_OrdPosNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthSix_OrdPosNomogZero(s1, s2, length, ordsgn, actionE, actionG, actionS)     \
+  p_MemCmp_LengthFive_OrdPosNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthSeven_OrdPosNomogZero(s1, s2, length, ordsgn, actionE, actionG, actionS)   \
+  p_MemCmp_LengthSix_OrdPosNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthEight_OrdPosNomogZero(s1, s2, length, ordsgn, actionE, actionG, actionS)   \
+  p_MemCmp_LengthSeven_OrdPosNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthGeneral_OrdPosNomogZero(s1, s2, length, ordsgn, actionE, actionG, actionS) \
+  p_MemCmp_LengthGeneral_OrdPosNomog(s1, s2, (length) -1, ordsgn, actionE, actionG, actionS)
+
+/***************************************************************
+ *
+ * PosPosNomog
+ *
+ *******************************************************************/
+#define p_MemCmp_LengthThree_OrdPosPosNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)             \
+  p_MemCmp_LengthOne_OrdPomog(s1, s2, length, ordsgn,                                                      \
+                           _p_MemCmp_Equal(1, _s1, _s2,                                         \
+                                           _p_MemCmp_LengthOne_Equal(2, _s2, _s1, actionE)),    \
+                           actionG, actionS)
+#define p_MemCmp_LengthFour_OrdPosPosNomog(s1, s2, length, ordsgn, actionE, actionG, actionS) \
+  p_MemCmp_LengthOne_OrdPomog(s1, s2, length, ordsgn,                                                      \
+                           _p_MemCmp_Equal(1, _s1, _s2,                                         \
+                                           _p_MemCmp_LengthTwo_Equal(2, _s2, _s1, actionE)),    \
+                           actionG, actionS)
+#define p_MemCmp_LengthFive_OrdPosPosNomog(s1, s2, length, ordsgn, actionE, actionG, actionS) \
+  p_MemCmp_LengthOne_OrdPomog(s1, s2, length, ordsgn,                                                      \
+                           _p_MemCmp_Equal(1, _s1, _s2,                                         \
+                                           _p_MemCmp_LengthThree_Equal(2, _s2, _s1, actionE)),    \
+                           actionG, actionS)
+#define p_MemCmp_LengthSix_OrdPosPosNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)  \
+  p_MemCmp_LengthOne_OrdPomog(s1, s2, length, ordsgn,                                                      \
+                           _p_MemCmp_Equal(1, _s1, _s2,                                         \
+                                           _p_MemCmp_LengthFour_Equal(2, _s2, _s1, actionE)),    \
+                           actionG, actionS)
+#define p_MemCmp_LengthSeven_OrdPosPosNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)    \
+  p_MemCmp_LengthOne_OrdPomog(s1, s2, length, ordsgn,                                                      \
+                           _p_MemCmp_Equal(1, _s1, _s2,                                         \
+                                           _p_MemCmp_LengthFive_Equal(2, _s2, _s1, actionE)),    \
+                           actionG, actionS)
+#define p_MemCmp_LengthEight_OrdPosPosNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)    \
+  p_MemCmp_LengthOne_OrdPomog(s1, s2, length, ordsgn,                                                      \
+                           _p_MemCmp_Equal(1, _s1, _s2,                                         \
+                                           _p_MemCmp_LengthSix_Equal(2, _s2, _s1, actionE)),    \
+                           actionG, actionS)
+#define p_MemCmp_LengthGeneral_OrdPosPosNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)          \
+  p_MemCmp_LengthOne_OrdPomog(s1, s2, length, ordsgn,                                                     \
+                           _p_MemCmp_Equal(1, _s1, _s2,                                                   \
+                                           _p_MemCmp_LengthGeneral_Equal(2,_s2,_s1,(length-2), actionE)), \
+                           actionG, actionS)
+
+/***************************************************************
+ *
+ * NegPosNomog
+ *
+ *******************************************************************/
+#define p_MemCmp_LengthThree_OrdNegPosNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)             \
+  p_MemCmp_LengthOne_OrdPomog(s1, s2, length, ordsgn,                                                      \
+                           _p_MemCmp_Equal(1, _s2, _s1,                                         \
+                                           _p_MemCmp_LengthOne_Equal(2, _s1, _s2, actionE)),    \
+                           actionS, actionG)
+#define p_MemCmp_LengthFour_OrdNegPosNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)              \
+  p_MemCmp_LengthOne_OrdPomog(s1, s2, length, ordsgn,                                                      \
+                           _p_MemCmp_Equal(1, _s2, _s1,                                         \
+                                           _p_MemCmp_LengthTwo_Equal(2, _s1, _s2, actionE)),    \
+                           actionS, actionG)
+#define p_MemCmp_LengthFive_OrdNegPosNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)              \
+  p_MemCmp_LengthOne_OrdPomog(s1, s2, length, ordsgn,                                                      \
+                           _p_MemCmp_Equal(1, _s2, _s1,                                         \
+                                           _p_MemCmp_LengthThree_Equal(2, _s1, _s2, actionE)),  \
+                           actionS, actionG)
+#define p_MemCmp_LengthSix_OrdNegPosNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)               \
+  p_MemCmp_LengthOne_OrdPomog(s1, s2, length, ordsgn,                                                      \
+                           _p_MemCmp_Equal(1, _s2, _s1,                                         \
+                                           _p_MemCmp_LengthFour_Equal(2, _s1, _s2, actionE)),   \
+                           actionS, actionG)
+#define p_MemCmp_LengthSeven_OrdNegPosNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)             \
+  p_MemCmp_LengthOne_OrdPomog(s1, s2, length, ordsgn,                                                      \
+                           _p_MemCmp_Equal(1, _s2, _s1,                                         \
+                                           _p_MemCmp_LengthFive_Equal(2, _s1, _s2, actionE)),   \
+                           actionS, actionG)
+#define p_MemCmp_LengthEight_OrdNegPosNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)             \
+  p_MemCmp_LengthOne_OrdPomog(s1, s2, length, ordsgn,                                                      \
+                           _p_MemCmp_Equal(1, _s2, _s1,                                         \
+                                           _p_MemCmp_LengthSix_Equal(2, _s1, _s2, actionE)),    \
+                           actionS, actionG)
+#define p_MemCmp_LengthGeneral_OrdNegPosNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)               \
+  p_MemCmp_LengthOne_OrdPomog(s1, s2, length, ordsgn,                                                          \
+                           _p_MemCmp_Equal(1, _s2, _s1,                                             \
+                                           _p_MemCmp_LengthGeneral_Equal(2, _s1,_s2,                \
+                                                                         (length-2) , actionE)),    \
+                           actionS, actionG)
+
+/***************************************************************
+ *
+ * PosNomogPos
+ *
+ *******************************************************************/
+#define p_MemCmp_LengthThree_OrdPosNomogPos(s1, s2, length, ordsgn, actionE, actionG, actionS)             \
+  p_MemCmp_LengthOne_OrdPomog(s1, s2, length, ordsgn,                                                      \
+                           _p_MemCmp_LengthOne_Equal(1, _s2, _s1,                               \
+                                           _p_MemCmp_LengthOne_Equal(2, _s1, _s2, actionE)),    \
+                           actionG, actionS)
+#define p_MemCmp_LengthFour_OrdPosNomogPos(s1, s2, length, ordsgn, actionE, actionG, actionS)  \
+  p_MemCmp_LengthOne_OrdPomog(s1, s2, length, ordsgn,                                          \
+                           _p_MemCmp_LengthTwo_Equal(1, _s2, _s1,                  \
+                                           _p_MemCmp_Equal(3, _s1, _s2, actionE)),  \
+                           actionG, actionS)
+#define p_MemCmp_LengthFive_OrdPosNomogPos(s1, s2, length, ordsgn, actionE, actionG, actionS)  \
+  p_MemCmp_LengthOne_OrdPomog(s1, s2, length, ordsgn,                                          \
+                           _p_MemCmp_LengthThree_Equal(1, _s2, _s1,                 \
+                                           _p_MemCmp_Equal(4, _s1, _s2, actionE)),  \
+                           actionG, actionS)
+#define p_MemCmp_LengthSix_OrdPosNomogPos(s1, s2, length, ordsgn, actionE, actionG, actionS)   \
+  p_MemCmp_LengthOne_OrdPomog(s1, s2, length, ordsgn,                                          \
+                           _p_MemCmp_LengthFour_Equal(1, _s2, _s1,                  \
+                                           _p_MemCmp_Equal(5, _s1, _s2, actionE)),  \
+                           actionG, actionS)
+#define p_MemCmp_LengthSeven_OrdPosNomogPos(s1, s2, length, ordsgn, actionE, actionG, actionS) \
+  p_MemCmp_LengthOne_OrdPomog(s1, s2, length, ordsgn,                                          \
+                           _p_MemCmp_LengthFive_Equal(1, _s2, _s1,                  \
+                                           _p_MemCmp_Equal(6, _s1, _s2, actionE)),  \
+                           actionG, actionS)
+#define p_MemCmp_LengthEight_OrdPosNomogPos(s1, s2, length, ordsgn, actionE, actionG, actionS) \
+  p_MemCmp_LengthOne_OrdPomog(s1, s2, length, ordsgn,                                          \
+                           _p_MemCmp_LengthSix_Equal(1, _s2, _s1,                   \
+                                           _p_MemCmp_Equal(7, _s1, _s2, actionE)),  \
+                           actionG, actionS)
+#define p_MemCmp_LengthGeneral_OrdPosNomogPos(s1, s2, length, ordsgn, actionE, actionG, actionS)       \
+  p_MemCmp_LengthOne_OrdPomog(s1, s2, length, ordsgn,                                                  \
+                           _p_MemCmp_LengthGeneral_Equal(1, _s2, _s1, (length - 2),         \
+                                                   _p_MemCmp_Equal(_i, _s1, _s2, actionE)), \
+                           actionG, actionS)
+
+
+/***************************************************************
+ *
+ *  PosPosNomogZero
+ *
+ *******************************************************************/
+#define p_MemCmp_LengthFour_OrdPosPosNomogZero(s1, s2, length, ordsgn, actionE, actionG, actionS)    \
+  p_MemCmp_LengthThree_OrdPosPosNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthFive_OrdPosPosNomogZero(s1, s2, length, ordsgn, actionE, actionG, actionS)    \
+  p_MemCmp_LengthFour_OrdPosPosNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthSix_OrdPosPosNomogZero(s1, s2, length, ordsgn, actionE, actionG, actionS)     \
+  p_MemCmp_LengthFive_OrdPosPosNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthSeven_OrdPosPosNomogZero(s1, s2, length, ordsgn, actionE, actionG, actionS)   \
+  p_MemCmp_LengthSix_OrdPosPosNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthEight_OrdPosPosNomogZero(s1, s2, length, ordsgn, actionE, actionG, actionS)   \
+  p_MemCmp_LengthSeven_OrdPosPosNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthGeneral_OrdPosPosNomogZero(s1, s2, length, ordsgn, actionE, actionG, actionS) \
+  p_MemCmp_LengthGeneral_OrdPosPosNomog(s1, s2, (length) -1, ordsgn, actionE, actionG, actionS)
+
+/***************************************************************
+ *
+ *  PosNomogPosZero
+ *
+ *******************************************************************/
+#define p_MemCmp_LengthFour_OrdPosNomogPosZero(s1, s2, length, ordsgn, actionE, actionG, actionS)    \
+  p_MemCmp_LengthThree_OrdPosNomogPos(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthFive_OrdPosNomogPosZero(s1, s2, length, ordsgn, actionE, actionG, actionS)    \
+  p_MemCmp_LengthFour_OrdPosNomogPos(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthSix_OrdPosNomogPosZero(s1, s2, length, ordsgn, actionE, actionG, actionS)     \
+  p_MemCmp_LengthFive_OrdPosNomogPos(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthSeven_OrdPosNomogPosZero(s1, s2, length, ordsgn, actionE, actionG, actionS)   \
+  p_MemCmp_LengthSix_OrdPosNomogPos(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthEight_OrdPosNomogPosZero(s1, s2, length, ordsgn, actionE, actionG, actionS)   \
+  p_MemCmp_LengthSeven_OrdPosNomogPos(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthGeneral_OrdPosNomogPosZero(s1, s2, length, ordsgn, actionE, actionG, actionS) \
+  p_MemCmp_LengthGeneral_OrdPosNomogPos(s1, s2, (length) -1, ordsgn, actionE, actionG, actionS)
+
+/***************************************************************
+ *
+ *  NegPosNomogZero
+ *
+ *******************************************************************/
+#define p_MemCmp_LengthFour_OrdNegPosNomogZero(s1, s2, length, ordsgn, actionE, actionG, actionS)    \
+  p_MemCmp_LengthThree_OrdNegPosNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthFive_OrdNegPosNomogZero(s1, s2, length, ordsgn, actionE, actionG, actionS)    \
+  p_MemCmp_LengthFour_OrdNegPosNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthSix_OrdNegPosNomogZero(s1, s2, length, ordsgn, actionE, actionG, actionS)     \
+  p_MemCmp_LengthFive_OrdNegPosNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthSeven_OrdNegPosNomogZero(s1, s2, length, ordsgn, actionE, actionG, actionS)   \
+  p_MemCmp_LengthSix_OrdNegPosNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthEight_OrdNegPosNomogZero(s1, s2, length, ordsgn, actionE, actionG, actionS)   \
+  p_MemCmp_LengthSeven_OrdNegPosNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthGeneral_OrdNegPosNomogZero(s1, s2, length, ordsgn, actionE, actionG, actionS) \
+  p_MemCmp_LengthGeneral_OrdNegPosNomog(s1, s2, (length) -1, ordsgn, actionE, actionG, actionS)
+
+
+/***************************************************************
+ *
+ *  OrdGeneral
+ *
+ *******************************************************************/
+#define _p_MemCmp_OrdGeneral_Declare(s1, s2)    \
+  const unsigned long* _s1 = ((unsigned long*) s1);     \
+  const unsigned long* _s2 = ((unsigned long*) s2);     \
+  register unsigned long _v1;                           \
+  register unsigned long _v2;                           \
+  register unsigned long _i
+
+#define _p_MemCmp_OrdGeneral_NotEqual(ordsgn, actionG, actionS) \
+do                                                              \
+{                                                               \
+  const long* _ordsgn = (long*) ordsgn;                        \
+  if (_v1 > _v2)                                                \
+  {                                                             \
+    if (_ordsgn[_i] == 1) actionG;                              \
+    actionS;                                                    \
+  }                                                             \
+  if (_ordsgn[_i] == 1) actionS;                                \
+  actionG;                                                      \
+}                                                               \
+while (0)
+
+#define _p_MemCmp_OrdGeneral(i, actionE)         \
+do                                              \
+{                                               \
+  _i = i;                                       \
+  _v1 = _s1[i];                                 \
+  _v2 = _s2[i];                                 \
+  if (_v1 == _v2) actionE;                      \
+}                                               \
+while(0)
+
+#define _p_MemCmp_LengthTwo_OrdGeneral(actionE)          \
+  _p_MemCmp_OrdGeneral(0, _p_MemCmp_OrdGeneral(1, actionE))
+
+#define _p_MemCmp_LengthThree_OrdGeneral(actionE)          \
+  _p_MemCmp_LengthTwo_OrdGeneral(_p_MemCmp_OrdGeneral(2, actionE))
+
+#define _p_MemCmp_LengthFour_OrdGeneral(actionE)          \
+  _p_MemCmp_LengthThree_OrdGeneral(_p_MemCmp_OrdGeneral(3, actionE))
+
+#define _p_MemCmp_LengthFive_OrdGeneral(actionE)          \
+  _p_MemCmp_LengthFour_OrdGeneral(_p_MemCmp_OrdGeneral(4, actionE))
+
+#define _p_MemCmp_LengthSix_OrdGeneral(actionE)          \
+  _p_MemCmp_LengthFive_OrdGeneral(_p_MemCmp_OrdGeneral(5, actionE))
+
+#define _p_MemCmp_LengthSeven_OrdGeneral(actionE)          \
+  _p_MemCmp_LengthSix_OrdGeneral(_p_MemCmp_OrdGeneral(6, actionE))
+
+#define _p_MemCmp_LengthEight_OrdGeneral(actionE)          \
+  _p_MemCmp_LengthSeven_OrdGeneral(_p_MemCmp_OrdGeneral(7, actionE))
+
+#define p_MemCmp_LengthOne_OrdGeneral(s1, s2, length, ordsgn, actionE, actionG, actionS)    \
+do                                                                                          \
+{                                                                                           \
+  _p_MemCmp_OrdGeneral_Declare(s1, s2);                                                     \
+  _p_MemCmp_OrdGeneral(0, actionE);                                                         \
+  _p_MemCmp_OrdGeneral_NotEqual(ordsgn, actionG, actionS);                                  \
+}                                                                                           \
+while (0)
+
+#define p_MemCmp_LengthTwo_OrdGeneral(s1, s2, length, ordsgn, actionE, actionG, actionS)    \
+do                                                                                          \
+{                                                                                           \
+  _p_MemCmp_OrdGeneral_Declare(s1, s2);                                                     \
+  _p_MemCmp_LengthTwo_OrdGeneral(actionE);                                               \
+  _p_MemCmp_OrdGeneral_NotEqual(ordsgn, actionG, actionS);                                  \
+}                                                                                           \
+while (0)
+
+#define p_MemCmp_LengthThree_OrdGeneral(s1, s2, length, ordsgn, actionE, actionG, actionS)  \
+do                                                                                          \
+{                                                                                           \
+  _p_MemCmp_OrdGeneral_Declare(s1, s2);                                                     \
+  _p_MemCmp_LengthThree_OrdGeneral(actionE);                                             \
+  _p_MemCmp_OrdGeneral_NotEqual(ordsgn, actionG, actionS);                                  \
+}                                                                                           \
+while (0)
+
+#define p_MemCmp_LengthFour_OrdGeneral(s1, s2, length, ordsgn, actionE, actionG, actionS)   \
+do                                                                                          \
+{                                                                                           \
+  _p_MemCmp_OrdGeneral_Declare(s1, s2);                                                     \
+  _p_MemCmp_LengthFour_OrdGeneral(actionE);                                              \
+  _p_MemCmp_OrdGeneral_NotEqual(ordsgn, actionG, actionS);                                  \
+}                                                                                           \
+while (0)
+
+#define p_MemCmp_LengthFive_OrdGeneral(s1, s2, length, ordsgn, actionE, actionG, actionS)   \
+do                                                                                          \
+{                                                                                           \
+  _p_MemCmp_OrdGeneral_Declare(s1, s2);                                                     \
+  _p_MemCmp_LengthFive_OrdGeneral(actionE);                                              \
+  _p_MemCmp_OrdGeneral_NotEqual(ordsgn, actionG, actionS);                                  \
+}                                                                                           \
+while (0)
+
+#define p_MemCmp_LengthSix_OrdGeneral(s1, s2, length, ordsgn, actionE, actionG, actionS)    \
+do                                                                                          \
+{                                                                                           \
+  _p_MemCmp_OrdGeneral_Declare(s1, s2);                                                     \
+  _p_MemCmp_LengthSix_OrdGeneral(actionE);                                               \
+  _p_MemCmp_OrdGeneral_NotEqual(ordsgn, actionG, actionS);                                  \
+}                                                                                           \
+while (0)
+
+#define p_MemCmp_LengthSeven_OrdGeneral(s1, s2, length, ordsgn, actionE, actionG, actionS)  \
+do                                                                                          \
+{                                                                                           \
+  _p_MemCmp_OrdGeneral_Declare(s1, s2);                                                     \
+  _p_MemCmp_LengthSeven_OrdGeneral(actionE);                                             \
+  _p_MemCmp_OrdGeneral_NotEqual(ordsgn, actionG, actionS);                                  \
+}                                                                                           \
+while (0)
+
+#define p_MemCmp_LengthEight_OrdGeneral(s1, s2, length, ordsgn, actionE, actionG, actionS)  \
+do                                                                                          \
+{                                                                                           \
+  _p_MemCmp_OrdGeneral_Declare(s1, s2);                                                     \
+  _p_MemCmp_LengthEight_OrdGeneral(actionE);                                                \
+  _p_MemCmp_OrdGeneral_NotEqual(ordsgn, actionG, actionS);                                  \
+}                                                                                           \
+while (0)
+
+/***************************************************************
+ *
+ *  Last but not least LengthGeneral_OrdGeneral
+ *
+ *******************************************************************/
+#define p_MemCmp_LengthGeneral_OrdGeneral(s1, s2, length, ordsgn, actionE, actionG, actionS)    \
+do                                                                                              \
+{                                                                                               \
+  _p_MemCmp_OrdGeneral_Declare(s1, s2);                                                         \
+  const unsigned long _l = (unsigned long) length;                                              \
+                                                                                                \
+  _i=0;                                                                                         \
+                                                                                                \
+  LengthGeneral_OrdGeneral_LoopTop:                                                             \
+  _v1 = _s1[_i];                                                                                \
+  _v2 = _s2[_i];                                                                                \
+  if (_v1 == _v2)                                                                               \
+  {                                                                                             \
+    _i++;                                                                                       \
+    if (_i == _l) actionE;                                                                      \
+    goto LengthGeneral_OrdGeneral_LoopTop;                                                      \
+  }                                                                                             \
+                                                                                                \
+  _p_MemCmp_OrdGeneral_NotEqual(ordsgn, actionG, actionS);                                      \
+}                                                                                               \
+while (0)
+
+// or, in other (less efficient) words
+#define p_MemCmp_LengthGeneral_OrdGeneral2(s1, s2, length, ordsgn, actionE, actionG, actionS)   \
+do                                                                                              \
+{                                                                                               \
+  int _i;                                                                                       \
+                                                                                                \
+  for (_i=0; _i<length;_i++)                                                                    \
+  {                                                                                             \
+    if (s1[_i] != s2[_i])                                                                       \
+    {                                                                                           \
+      if (s1[_i] > s2[_i])                                                                      \
+      {                                                                                         \
+        if (ordsgn[_i] == 1)                                                                    \
+          actionG;                                                                              \
+        actionS;                                                                                \
+      }                                                                                         \
+      if (ordsgn[_i] == 1)                                                                      \
+        actionS;                                                                                \
+      actionG;                                                                                  \
+    }                                                                                           \
+  }                                                                                             \
+  actionE;                                                                                      \
+}                                                                                               \
+while (0)
+
+/***************************************************************
+ *
+ *  Bitmask
+ *
+ *******************************************************************/
+#define _p_MemCmp_Bitmask_Declare(s1, s2, bitmask)  \
+  const unsigned long* _s1 = ((unsigned long*) s1); \
+  const unsigned long* _s2 = ((unsigned long*) s2); \
+  register const unsigned long _bitmask = bitmask;  \
+  register unsigned long _v1;                       \
+  register unsigned long _v2;                       \
+  register unsigned long _i                         \
+
+
+#define p_MemCmp_Bitmask_LengthGeneral(s1, s2, bitmask, length, actionG, actionS)   \
+do                                                                                  \
+{                                                                                   \
+  _p_MemCmp_Bitmask_Declare(s1, s2, bitmask);                                             \
+  const unsigned long _l = (unsigned long) length;                                  \
+                                                                                    \
+  _i=0;                                                                             \
+                                                                                    \
+  while (_i < _l)                                                                   \
+  {                                                                                 \
+    _v1 = _s1[_i];                                                                  \
+    _v2 = _s2[_i];                                                                  \
+                                                                                    \
+    if ((_v1 > _v2) ||                                                              \
+        (((_v1 & _bitmask) ^ (_v2 & _bitmask)) != ((_v2 - _v1) & _bitmask)))           \
+      actionS;                                                                      \
+    _i++;                                                                           \
+  }                                                                                 \
+  actionG;                                                                          \
+}                                                                                   \
+while (0)
+
+
+#define _p_MemCmp_Bitmask(i, actionS)                                       \
+do                                                                          \
+{                                                                           \
+  _i = i;                                                                   \
+  _v1 = _s1[i];                                                             \
+  _v2 = _s2[i];                                                             \
+  if ((_v1 > _v2) ||                                                        \
+      (((_v1 & _bitmask) ^ (_v2 & _bitmask)) != ((_v2 - _v1) & _bitmask)))     \
+    actionS;                                                               \
+}                                                                           \
+while (0)
+
+#define _p_MemCmp_Bitmask_LengthTwo(actionS)    \
+  do                                            \
+{                                               \
+  _p_MemCmp_Bitmask(0, actionS);                \
+  _p_MemCmp_Bitmask(1, actionS);                \
+}                                               \
+while (0)
+
+#define _p_MemCmp_Bitmask_LengthThree(actionS)  \
+  do                                            \
+{                                               \
+  _p_MemCmp_Bitmask_LengthTwo(actionS);         \
+  _p_MemCmp_Bitmask(2, actionS);                \
+}                                               \
+while (0)
+
+#define _p_MemCmp_Bitmask_LengthFour(actionS)   \
+  do                                            \
+{                                               \
+  _p_MemCmp_Bitmask_LengthThree(actionS);    \
+  _p_MemCmp_Bitmask(3, actionS);                \
+}                                               \
+while (0)
+
+
+#define _p_MemCmp_Bitmask_LengthFive(actionS)   \
+  do                                            \
+{                                               \
+  _p_MemCmp_Bitmask_LengthFour(actionS);     \
+  _p_MemCmp_Bitmask(4, actionS);                \
+}                                               \
+while (0)
+
+
+#define _p_MemCmp_Bitmask_LengthSix(actionS)    \
+  do                                            \
+{                                               \
+  _p_MemCmp_Bitmask_LengthFive(actionS);     \
+  _p_MemCmp_Bitmask(5, actionS);                \
+}                                               \
+while (0)
+
+#define _p_MemCmp_Bitmask_LengthSeven(actionS)  \
+  do                                            \
+{                                               \
+  _p_MemCmp_Bitmask_LengthSix(actionS);      \
+  _p_MemCmp_Bitmask(6, actionS);                \
+}                                               \
+while (0)
+
+#define _p_MemCmp_Bitmask_LengthEight(actionS)  \
+do                                              \
+{                                               \
+  _p_MemCmp_Bitmask_LengthSeven(actionS);    \
+  _p_MemCmp_Bitmask(7, actionS);                \
+}                                               \
+while (0)
+
+#define p_MemCmp_Bitmask_LengthZero(s1, s2, bitmask, length, actionG, actionS) actionG
+
+#define p_MemCmp_Bitmask_LengthOne(s1, s2, bitmask, length, actionG, actionS)   \
+do                                                                              \
+{                                                                               \
+  _p_MemCmp_Bitmask_Declare(s1, s2, bitmask);                                         \
+  _p_MemCmp_Bitmask(0, actionS);                                                \
+  actionG;                                                                      \
+}                                                                               \
+while (0)
+
+#define p_MemCmp_Bitmask_LengthTwo(s1, s2, bitmask, length, actionG, actionS)   \
+do                                                                              \
+{                                                                               \
+  _p_MemCmp_Bitmask_Declare(s1, s2, bitmask);                                         \
+  _p_MemCmp_Bitmask_LengthTwo(actionS);                                         \
+  actionG;                                                                      \
+}                                                                               \
+while (0)
+
+#define p_MemCmp_Bitmask_LengthThree(s1, s2, bitmask, length, actionG, actionS)   \
+do                                                                              \
+{                                                                               \
+  _p_MemCmp_Bitmask_Declare(s1, s2, bitmask);                                         \
+  _p_MemCmp_Bitmask_LengthThree(actionS);                                         \
+  actionG;                                                                      \
+}                                                                               \
+while (0)
+
+#define p_MemCmp_Bitmask_LengthFour(s1, s2, bitmask, length, actionG, actionS)   \
+do                                                                              \
+{                                                                               \
+  _p_MemCmp_Bitmask_Declare(s1, s2, bitmask);                                         \
+  _p_MemCmp_Bitmask_LengthFour(actionS);                                         \
+  actionG;                                                                      \
+}                                                                               \
+while (0)
+
+#define p_MemCmp_Bitmask_LengthFive(s1, s2, bitmask, length, actionG, actionS)   \
+do                                                                              \
+{                                                                               \
+  _p_MemCmp_Bitmask_Declare(s1, s2, bitmask);                                         \
+  _p_MemCmp_Bitmask_LengthFive(actionS);                                         \
+  actionG;                                                                      \
+}                                                                               \
+while (0)
+
+#define p_MemCmp_Bitmask_LengthSix(s1, s2, bitmask, length, actionG, actionS)   \
+do                                                                              \
+{                                                                               \
+  _p_MemCmp_Bitmask_Declare(s1, s2, bitmask);                                         \
+  _p_MemCmp_Bitmask_LengthSix(actionS);                                         \
+  actionG;                                                                      \
+}                                                                               \
+while (0)
+
+#define p_MemCmp_Bitmask_LengthSeven(s1, s2, bitmask, length, actionG, actionS) \
+do                                                                              \
+{                                                                               \
+  _p_MemCmp_Bitmask_Declare(s1, s2, bitmask);                                         \
+  _p_MemCmp_Bitmask_LengthSeven(actionS);                                       \
+  actionG;                                                                      \
+}                                                                               \
+while (0)
+
+#define p_MemCmp_Bitmask_LengthEigth(s1, s2, bitmask, length, actionG, actionS) \
+do                                                                              \
+{                                                                               \
+  _p_MemCmp_Bitmask_Declare(s1, s2, bitmask);                                         \
+  _p_MemCmp_Bitmask_LengthEigth(actionS);                                       \
+  actionG;                                                                      \
+}                                                                               \
+while (0)
+
+
+#endif // P_MEM_CMP
diff --git a/libpolys/polys/templates/p_MemCopy.h b/libpolys/polys/templates/p_MemCopy.h
new file mode 100644
index 0000000..5a49780
--- /dev/null
+++ b/libpolys/polys/templates/p_MemCopy.h
@@ -0,0 +1,95 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    p_MemCopy.h
+ *  Purpose: macros for memory addition
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 8/00
+ *******************************************************************/
+#ifndef P_MEM_COPY_H
+#define P_MEM_COPY_H
+
+#define _p_MemCopy(i, d, s) d[i] = s[i]
+
+#define _p_MemCopy_LengthOne(d, s) _p_MemCopy(0, d, s)
+#define _p_MemCopy_LengthTwo(d, s) do{_p_MemCopy_LengthOne(d, s); _p_MemCopy(1, d, s);} while(0)
+#define _p_MemCopy_LengthThree(d, s) do{_p_MemCopy_LengthTwo(d, s); _p_MemCopy(2, d, s);} while(0)
+#define _p_MemCopy_LengthFour(d, s) do{_p_MemCopy_LengthThree(d, s); _p_MemCopy(3, d, s);} while(0)
+#define _p_MemCopy_LengthFive(d, s) do{_p_MemCopy_LengthFour(d, s); _p_MemCopy(4, d, s);} while(0)
+#define _p_MemCopy_LengthSix(d, s) do{_p_MemCopy_LengthFive(d, s); _p_MemCopy(5, d, s);} while(0)
+#define _p_MemCopy_LengthSeven(d, s) do{_p_MemCopy_LengthSix(d, s); _p_MemCopy(6, d, s);} while(0)
+#define _p_MemCopy_LengthEight(d, s) do{_p_MemCopy_LengthSeven(d, s); _p_MemCopy(7, d, s);} while(0)
+
+#define _p_MemCopy_Declare(d, s)                \
+  unsigned long* _d = ((unsigned long*) d); \
+  const unsigned long* _s = ((unsigned long*) s)
+
+#define p_MemCopy_LengthOne(d, s, length) _p_MemCopy_LengthOne(d, s)
+#define p_MemCopy_LengthTwo(d, s, length)   \
+do                                              \
+{                                               \
+  _p_MemCopy_Declare(d,s);                    \
+  _p_MemCopy_LengthTwo(_d, _s);            \
+}                                               \
+while (0)
+#define p_MemCopy_LengthThree(d, s, length) \
+do                                              \
+{                                               \
+  _p_MemCopy_Declare(d,s);                    \
+  _p_MemCopy_LengthThree(_d, _s);          \
+}                                               \
+while (0)
+#define p_MemCopy_LengthFour(d, s, length)  \
+do                                              \
+{                                               \
+  _p_MemCopy_Declare(d,s);                    \
+  _p_MemCopy_LengthFour(_d, _s);           \
+}                                               \
+while (0)
+#define p_MemCopy_LengthFive(d, s, length)  \
+do                                              \
+{                                               \
+  _p_MemCopy_Declare(d,s);                    \
+  _p_MemCopy_LengthFive(_d, _s);           \
+}                                               \
+while (0)
+#define p_MemCopy_LengthSix(d, s, length)   \
+do                                              \
+{                                               \
+  _p_MemCopy_Declare(d,s);                    \
+  _p_MemCopy_LengthSix(_d, _s);            \
+}                                               \
+while (0)
+#define p_MemCopy_LengthSeven(d, s, length) \
+do                                              \
+{                                               \
+  _p_MemCopy_Declare(d,s);                    \
+  _p_MemCopy_LengthSeven(_d, _s);          \
+}                                               \
+while (0)
+#define p_MemCopy_LengthEight(d, s, length) \
+do                                              \
+{                                               \
+  _p_MemCopy_Declare(d,s);                    \
+  _p_MemCopy_LengthEight(_d, _s);          \
+}                                               \
+while (0)
+
+#define p_MemCopy_LengthGeneral(d, s, length)   \
+do                                              \
+{                                               \
+  _p_MemCopy_Declare(d,s);                      \
+  const unsigned long _l = (unsigned long) length;   \
+  unsigned long _i = 0;                         \
+                                                \
+  do                                            \
+  {                                             \
+    _d[_i] = _s[_i];                            \
+    _i++;                                       \
+  }                                             \
+  while (_i != _l);                             \
+}                                               \
+while (0)
+
+#endif // P_MEM_COPY_H
diff --git a/libpolys/polys/templates/p_Merge_q__T.cc b/libpolys/polys/templates/p_Merge_q__T.cc
new file mode 100644
index 0000000..a440f29
--- /dev/null
+++ b/libpolys/polys/templates/p_Merge_q__T.cc
@@ -0,0 +1,59 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    p_Merge_q__Template.cc
+ *  Purpose: template for p_Add_q
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 8/00
+ *******************************************************************/
+
+/***************************************************************
+ *
+ * Returns:  p merged with q
+ * Destroys: p, q
+ *
+ ***************************************************************/
+LINKAGE poly p_Merge_q__T(poly p, poly q, const ring r)
+{
+  assume(p != NULL && q != NULL);
+  p_Test(p, r);
+  p_Test(q, r);
+#if PDEBUG > 0
+  int l = pLength(p) + pLength(q);
+#endif
+
+  spolyrec rp;
+  poly a = &rp;
+  DECLARE_LENGTH(const unsigned long length = r->CmpL_Size);
+  DECLARE_ORDSGN(const long* ordsgn = r->ordsgn);
+
+  Top:     // compare p and q w.r.t. monomial ordering
+  p_MemCmp__T(p->exp, q->exp, length, ordsgn, goto Equal, goto Greater , goto Smaller);
+
+  Equal:
+  // should never get here
+  dReportError("Equal monomials in p_Merge_q");
+  return NULL;
+
+  Greater:
+  a = pNext(a) = p;
+  pIter(p);
+  if (p==NULL) { pNext(a) = q; goto Finish;}
+  goto Top;
+
+  Smaller:
+  a = pNext(a) = q;
+  pIter(q);
+  if (q==NULL) { pNext(a) = p; goto Finish;}
+  goto Top;
+
+  Finish:
+
+  p_Test(pNext(&rp), r);
+#if PDEBUG > 0
+  pAssume1(l - pLength(pNext(&rp)) == 0);
+#endif
+  return pNext(&rp);
+}
+
diff --git a/libpolys/polys/templates/p_Minus_mm_Mult_qq__T.cc b/libpolys/polys/templates/p_Minus_mm_Mult_qq__T.cc
new file mode 100644
index 0000000..32d88a0
--- /dev/null
+++ b/libpolys/polys/templates/p_Minus_mm_Mult_qq__T.cc
@@ -0,0 +1,164 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    p_Minus_mm_Mult_qq__Template.cc
+ *  Purpose: template for p_Minus_m_Mult_q
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 8/00
+ *******************************************************************/
+
+/***************************************************************
+ *
+ * Returns:  p - m*q
+ *           Shorter, where Shorter == Length(p) + Length(q) - Length(p - m*q);
+ * Destroys: p
+ * Const:    m, q
+ *
+ ***************************************************************/
+LINKAGE poly p_Minus_mm_Mult_qq__T(poly p, poly m, poly q, int& Shorter, const poly spNoether, const ring r)
+{
+  p_Test(p, r);
+  p_Test(q, r);
+  p_LmTest(m, r);
+
+#if PDEBUG > 0
+  int l_debug = pLength(p) + pLength(q);
+#endif
+
+  Shorter = 0;
+  // we are done if q == NULL || m == NULL
+  if (q == NULL || m == NULL) return p;
+
+  spolyrec rp;
+  poly a = &rp,                    // collects the result
+    qm = NULL;                     // stores q*m
+
+
+  number tm = pGetCoeff(m),           // coefficient of m
+    tneg = n_Neg__T(n_Copy__T(tm, r), r),    // - (coefficient of m)
+    tb,                            // used for tm*coeff(a1)
+    tc;                            // used as intermediate number
+
+
+  int shorter = 0;
+  DECLARE_LENGTH(const unsigned long length = r->ExpL_Size);
+  DECLARE_ORDSGN(const long* ordsgn = r->ordsgn);
+
+  const unsigned long* m_e = m->exp;
+  omBin bin = r->PolyBin;
+
+  if (p == NULL) goto Finish;           // return tneg*q if (p == NULL)
+
+  pAssume(p_GetComp(q, r) == 0 || p_GetComp(m, r) == 0);
+
+  AllocTop:
+  p_AllocBin(qm, bin, r);
+  SumTop:
+  p_MemSum__T(qm->exp, q->exp, m_e, length);
+  p_MemAddAdjust__T(qm, r);
+
+  CmpTop:
+  // compare qm = m*q and p w.r.t. monomial ordering
+  p_MemCmp__T(qm->exp, p->exp, length, ordsgn, goto Equal, goto Greater, goto Smaller );
+
+  Equal:   // qm equals p
+  tb = n_Mult__T(pGetCoeff(q), tm, r);
+#ifdef HAVE_ZERODIVISORS
+  if (!n_IsZero__T(tb,r)) {
+#endif
+  tc = pGetCoeff(p);
+  if (!n_Equal__T(tc, tb, r))
+  {
+    shorter++;
+    tc = n_Sub__T(tc, tb, r);
+    n_Delete__T(&(pGetCoeff(p)), r);
+    pSetCoeff0(p,tc); // adjust coeff of p
+    a = pNext(a) = p; // append p to result and advance p
+    pIter(p);
+  }
+  else
+  { // coeffs are equal, so their difference is 0:
+    shorter += 2;
+    n_Delete__T(&tc, r);
+    p = p_LmFreeAndNext(p, r);
+  }
+#ifdef HAVE_ZERODIVISORS
+  }
+  else
+  { // coeff itself is zero
+    shorter += 1;
+  }
+#endif
+  n_Delete__T(&tb, r);
+  pIter(q);
+  if (q == NULL || p == NULL) goto Finish; // are we done ?
+  // no, so update qm
+  goto SumTop;
+
+
+  Greater:
+#ifdef HAVE_ZERODIVISORS
+  tb = n_Mult__T(pGetCoeff(q), tneg, r);
+  if (!n_IsZero__T(tb,r))
+  {
+#endif
+    pSetCoeff0(qm, n_Mult__T(pGetCoeff(q), tneg, r));
+    a = pNext(a) = qm;       // append qm to result and advance q
+#ifdef HAVE_ZERODIVISORS
+  }
+  else
+  {
+    shorter++;
+  }
+  n_Delete__T(&tb, r);
+#endif
+  pIter(q);
+  if (q == NULL) // are we done?
+  {
+    qm = NULL;
+    goto Finish;
+  }
+  // construct new qm
+  goto AllocTop;
+
+  Smaller:
+  a = pNext(a) = p;// append p to result and advance p
+  pIter(p);
+  if (p == NULL) goto Finish;
+  goto CmpTop;
+
+
+  Finish: // q or p is NULL: Clean-up time
+  if (q == NULL) // append rest of p to result
+  {
+    pNext(a) = p;
+  }
+  else  // append (- m*q) to result
+  {
+    pSetCoeff0(m, tneg);
+    if (spNoether != NULL)
+    {
+      int ll = 0;
+      pNext(a) = r->p_Procs->pp_Mult_mm_Noether(q, m, spNoether, ll, r);
+      shorter += ll;
+    }
+    else
+    {
+      pNext(a) = r->p_Procs->pp_Mult_mm(q, m, r);
+#ifdef HAVE_RINGS
+      if (! rField_is_Domain(r))
+      {
+        shorter += pLength(q) - pLength(pNext(a));
+      }
+#endif
+    }
+    pSetCoeff0(m, tm);
+  }
+
+  n_Delete__T(&tneg, r);
+  if (qm != NULL) p_FreeBinAddr(qm, r);
+  Shorter = shorter;
+  p_Test(pNext(&rp), r);
+  return pNext(&rp);
+}
diff --git a/libpolys/polys/templates/p_Mult_mm__T.cc b/libpolys/polys/templates/p_Mult_mm__T.cc
new file mode 100644
index 0000000..7ae968d
--- /dev/null
+++ b/libpolys/polys/templates/p_Mult_mm__T.cc
@@ -0,0 +1,71 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    p_Mult_mm__Template.cc
+ *  Purpose: template for p_Mult_n
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 8/00
+ *******************************************************************/
+
+/***************************************************************
+ *
+ *   Returns:  p*m
+ *   Const:    m
+ *   Destroys: p
+ *
+ ***************************************************************/
+LINKAGE poly p_Mult_mm__T(poly p, const poly m, const ring ri)
+{
+  p_Test(p, ri);
+  p_LmTest(m, ri);
+  if (p == NULL) return NULL;
+  pAssume(m != NULL);
+  poly q = p;
+  number ln = pGetCoeff(m);
+  number pn;
+  DECLARE_LENGTH(const unsigned long length = ri->ExpL_Size);
+  const unsigned long* m_e = m->exp;
+  pAssume(!n_IsZero__T(ln,ri));
+
+#ifdef HAVE_ZERODIVISORS
+  poly before = p;
+#endif
+  while (p != NULL)
+  {
+    pn = pGetCoeff(p);
+    number tmp = n_Mult__T(ln, pn, ri);
+#ifdef HAVE_ZERODIVISORS
+    if (n_IsZero__T(tmp, ri))
+    {
+      n_Delete__T(&tmp, ri);
+      if (before == p)
+      {
+        p = p_LmDeleteAndNext(p, ri);
+        before = p;
+        q = p;
+      }
+      else
+      {
+        p = p_LmDeleteAndNext(p, ri);
+        pNext(before) = p;
+      }
+    }
+    else
+#endif
+    {
+      pSetCoeff0(p, tmp);
+      n_Delete__T(&pn, ri);
+      p_MemAdd__T(p->exp, m_e, length);
+      p_MemAddAdjust__T(p, ri);
+#ifdef HAVE_ZERODIVISORS
+      before = p;
+#endif
+      p = pNext(p);
+    }
+  }
+  p_Test(q, ri);
+  return q;
+}
+
+
diff --git a/libpolys/polys/templates/p_Mult_nn__T.cc b/libpolys/polys/templates/p_Mult_nn__T.cc
new file mode 100644
index 0000000..650c5d2
--- /dev/null
+++ b/libpolys/polys/templates/p_Mult_nn__T.cc
@@ -0,0 +1,60 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    p_Mult_n__Template.cc
+ *  Purpose: template for p_Mult_n
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 8/00
+ *******************************************************************/
+
+/***************************************************************
+ *
+ *   Returns:  p*n
+ *   Destroys: p
+ *   Const:    n
+ *
+ ***************************************************************/
+LINKAGE poly p_Mult_nn__T(poly p, const number n, const ring r)
+{
+  pAssume(!n_IsZero__T(n,r));
+  p_Test(p, r);
+
+  poly q = p;
+#ifdef HAVE_ZERODIVISORS
+  poly old = NULL;
+#endif
+  while (p != NULL)
+  {
+#ifndef HAVE_ZERODIVISORS
+    n_InpMult__T(pGetCoeff(p), n, r);
+    pIter(p);
+#else
+    number tmp = n_Mult__T(n, pGetCoeff(p), r);
+    if (!n_IsZero__T(tmp,r))
+    {
+       number nc = pGetCoeff(p);
+       p_SetCoeff0(p, tmp, r);
+       n_Delete__T(&nc, r);
+       old = p;
+       pIter(p);
+    }
+    else
+    {
+      n_Delete__T(&tmp, r);
+      if (old == NULL)
+      {
+        pIter(p);
+        p_LmDelete(&q, r);
+      }
+      else
+      {
+        p_LmDelete(&p, r);
+        pNext(old) = p;
+      }
+    }
+#endif
+  }
+  p_Test(q, r);
+  return q;
+}
diff --git a/libpolys/polys/templates/p_Neg__T.cc b/libpolys/polys/templates/p_Neg__T.cc
new file mode 100644
index 0000000..5e0440e
--- /dev/null
+++ b/libpolys/polys/templates/p_Neg__T.cc
@@ -0,0 +1,28 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    p_Neg__Template.cc
+ *  Purpose: template for p_Neg
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 8/00
+ *******************************************************************/
+
+/***************************************************************
+ *
+ *   Returns:  -p
+ *   Destroys: p
+ *
+ ***************************************************************/
+LINKAGE poly p_Neg__T(poly p, const ring r)
+{
+  poly q = p;
+  while (p != NULL)
+  {
+    pSetCoeff0(p, n_Neg__T(pGetCoeff(p), r));
+    pIter(p);
+  }
+  return q;
+}
+
+
diff --git a/libpolys/polys/templates/p_Numbers.h b/libpolys/polys/templates/p_Numbers.h
new file mode 100644
index 0000000..25a4bc8
--- /dev/null
+++ b/libpolys/polys/templates/p_Numbers.h
@@ -0,0 +1,180 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    p_Numbers.h
+ *  Purpose: macros/inline functions for number operations
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 8/00
+ *******************************************************************/
+#ifndef P_NUMBERS_H
+#define P_NUMBERS_H
+
+#include <misc/auxiliary.h>
+#include <coeffs/coeffs.h>
+#include <coeffs/numbers.h>
+#include <polys/monomials/ring.h>
+
+static FORCE_INLINE number n_Copy_FieldGeneral(number n,    const ring r)
+{ return n_Copy(n,r->cf); }
+
+static FORCE_INLINE void   n_Delete_FieldGeneral(number* p, const ring r)
+{ n_Delete(p,r->cf); }
+
+static FORCE_INLINE number n_Mult_FieldGeneral(number n1, number n2, const ring r)
+{ return n_Mult(n1, n2, r->cf); }
+
+static FORCE_INLINE number n_Add_FieldGeneral(number n1, number n2, const ring r)
+{ return n_Add(n1, n2, r->cf); }
+
+static FORCE_INLINE BOOLEAN n_IsZero_FieldGeneral(number n, const ring r)
+{ return n_IsZero(n, r->cf); }
+
+static FORCE_INLINE BOOLEAN n_Equal_FieldGeneral(number n1, number n2, const ring r)
+{ return n_Equal(n1, n2, r->cf); }
+
+static FORCE_INLINE number n_Neg_FieldGeneral(number n,     const ring r)
+{ return n_InpNeg(n, r->cf); }
+
+static FORCE_INLINE number n_Sub_FieldGeneral(number n1, number n2, const ring r)
+{ return n_Sub(n1, n2, r->cf); }
+
+static FORCE_INLINE void n_InpMult_FieldGeneral(number &n1, number n2, const ring r)
+{ n_InpMult(n1, n2, r->cf); }
+
+static FORCE_INLINE void n_InpAdd_FieldGeneral(number &n1, number n2, const ring r)
+{ n_InpAdd(n1, n2, r->cf); }
+
+#ifdef HAVE_RINGS
+#define n_Copy_RingGeneral(n, r)           n_Copy_FieldGeneral(n, r)
+#define n_Delete_RingGeneral(n, r)         n_Delete_FieldGeneral(n, r)
+#define n_Mult_RingGeneral(n1, n2, r)      n_Mult_FieldGeneral(n1, n2, r)
+#define n_Add_RingGeneral(n1, n2, r)       n_Add_FieldGeneral(n1, n2, r)
+#define n_IsZero_RingGeneral(n, r)         n_IsZero_FieldGeneral(n, r)
+#define n_Equal_RingGeneral(n1, n2, r)     n_Equal_FieldGeneral(n1, n2, r)
+#define n_Neg_RingGeneral(n, r)            n_Neg_FieldGeneral(n, r)
+#define n_Sub_RingGeneral(n1, n2, r)       n_Sub_FieldGeneral(n1, n2, r)
+//#define n_InpMult_RingGeneral(n1, n2, r)   n_InpMult_FieldGeneral(n1, n2, r)
+#define n_InpMult_RingGeneral(n1, n2, r)   n_InpMult_FieldGeneral(n1, n2, r)
+
+static FORCE_INLINE void n_InpAdd_RingGeneral(number &n1, number n2, const ring r)
+{  assume(rField_is_Ring(r)); n_InpAdd(n1, n2, r->cf); }
+#endif
+
+#include <coeffs/modulop.h>
+
+#define n_Copy_FieldZp(n, r)        n
+#define n_Delete_FieldZp(n, r)      do {} while (0)
+
+static FORCE_INLINE number n_Mult_FieldZp(number n1, number n2, const ring r)
+{ STATISTIC(n_Mult); return npMultM(n1, n2, r->cf); }
+
+#ifdef HAVE_NUMSTATS
+static FORCE_INLINE number n_Add_FieldZp(number n1, number n2, const ring r)
+{ STATISTIC(n_Add); const number sum = npAddM(n1, n2, r->cf);
+  // avoid double counting
+  if( npIsZeroM(sum,r->cf) ) STATISTIC(n_CancelOut);
+ return sum;
+}
+#else
+static FORCE_INLINE number n_Add_FieldZp(number n1, number n2, const ring r)
+{ return npAddM(n1, n2, r->cf); }
+#endif
+
+#ifdef HAVE_NUMSTATS
+static FORCE_INLINE number n_Sub_FieldZp(number n1, number n2, const ring r)
+{ STATISTIC(n_Sub); const number d = npSubM(n1, n2, r->cf);
+  // avoid double counting
+  if( npIsZeroM(d,r->cf) ) STATISTIC(n_CancelOut);
+  return d;
+}
+#else
+static FORCE_INLINE number n_Sub_FieldZp(number n1, number n2, const ring r)
+{ return npSubM(n1, n2, r->cf); }
+#endif
+
+static FORCE_INLINE BOOLEAN n_IsZero_FieldZp(number n, const ring r)
+{ STATISTIC(n_IsZero); return npIsZeroM(n, r->cf); }
+
+static FORCE_INLINE BOOLEAN n_Equal_FieldZp(number n1, number n2, const ring r)
+{ STATISTIC(n_Equal); return  npEqualM(n1, n2, r->cf); }
+
+static FORCE_INLINE number n_Neg_FieldZp(number n,     const ring r)
+{ STATISTIC(n_InpNeg); return npNegM(n, r->cf); }
+
+static FORCE_INLINE void n_InpMult_FieldZp(number &n1, number n2, const ring r)
+{ STATISTIC(n_InpMult); n1=npMultM(n1, n2, r->cf);  }
+
+#ifdef HAVE_NUMSTATS
+static FORCE_INLINE void n_InpAdd_FieldZp(number &n1, number n2, const ring r)
+{
+  STATISTIC(n_InpAdd); n1=npAddM(n1, n2, r->cf);
+  // avoid double counting
+  if( npIsZeroM(n1,r->cf) ) STATISTIC(n_CancelOut);
+}
+#else
+static FORCE_INLINE void n_InpAdd_FieldZp(number &n1, number n2, const ring r)
+{ n1=npAddM(n1, n2, r->cf); }
+#endif
+
+#define DO_LFORCE_INLINE
+#include <coeffs/longrat.cc> // for inlining... TODO: fix this Uglyness?!!!
+
+static FORCE_INLINE number n_Copy_FieldQ(number n,    const ring r)
+{ STATISTIC(n_Copy); return nlCopy(n, r->cf); }
+
+static FORCE_INLINE void   n_Delete_FieldQ(number* n, const ring r)
+{ STATISTIC(n_Delete); nlDelete(n,r->cf); }
+
+static FORCE_INLINE number n_Mult_FieldQ(number n1, number n2, const ring r)
+{ STATISTIC(n_Mult); return nlMult(n1,n2, r->cf); }
+
+#ifdef HAVE_NUMSTATS
+static FORCE_INLINE number n_Add_FieldQ(number n1, number n2, const ring r)
+{ STATISTIC(n_Add); const number sum = nlAdd(n1, n2, r->cf);
+  // avoid double counting
+  if( nlIsZero(sum,r->cf) ) STATISTIC(n_CancelOut);
+ return sum;
+}
+#else
+static FORCE_INLINE number n_Add_FieldQ(number n1, number n2, const ring r)
+{ return nlAdd(n1, n2, r->cf); }
+#endif
+
+#ifdef HAVE_NUMSTATS
+static FORCE_INLINE number n_Sub_FieldQ(number n1, number n2, const ring r)
+{ STATISTIC(n_Sub); const number d = nlSub(n1, n2, r->cf);
+  // avoid double counting
+  if( nlIsZero(d,r->cf) ) STATISTIC(n_CancelOut);
+  return d;
+}
+#else
+static FORCE_INLINE number n_Sub_FieldQ(number n1, number n2, const ring r)
+{ return nlSub(n1, n2, r->cf); }
+#endif
+
+static FORCE_INLINE BOOLEAN n_IsZero_FieldQ(number n, const ring r)
+{ STATISTIC(n_IsZero); return nlIsZero(n, r->cf); }
+
+static FORCE_INLINE BOOLEAN n_Equal_FieldQ(number n1, number n2, const ring r)
+{ STATISTIC(n_Equal); return  nlEqual(n1, n2, r->cf); }
+
+static FORCE_INLINE number n_Neg_FieldQ(number n,     const ring r)
+{ STATISTIC(n_InpNeg); return nlNeg(n, r->cf); }
+
+static FORCE_INLINE void n_InpMult_FieldQ(number &n1, number n2, const ring r)
+{ STATISTIC(n_InpMult); nlInpMult(n1, n2, r->cf); }
+
+#ifdef HAVE_NUMSTATS
+static FORCE_INLINE void n_InpAdd_FieldQ(number &n1, number n2, const ring r)
+{ STATISTIC(n_InpAdd); assume(rField_is_Q(r)); nlInpAdd(n1, n2, r->cf);
+
+  // avoid double counting
+  if( nlIsZero(n1,r->cf) ) STATISTIC(n_CancelOut);
+}
+#else
+static FORCE_INLINE void n_InpAdd_FieldQ(number &n1, number n2, const ring r)
+{ nlInpAdd(n1, n2, r->cf); }
+#endif
+
+#endif
diff --git a/libpolys/polys/templates/p_Procs.h b/libpolys/polys/templates/p_Procs.h
new file mode 100644
index 0000000..84585f1
--- /dev/null
+++ b/libpolys/polys/templates/p_Procs.h
@@ -0,0 +1,74 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+
+/***************************************************************
+ *  File:    pProcs.h
+ *  Purpose: declaration of primitive procs for polys
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 8/00
+ *******************************************************************/
+#ifndef P_PROCS_H
+#define P_PROCS_H
+
+// #include <polys/monomials/ring.h>
+// #include <polys/structs.h>
+#include <omalloc/omalloc.h>
+
+struct spolyrec; typedef struct spolyrec polyrec; typedef polyrec* poly;
+struct ip_sring; typedef struct ip_sring* ring; typedef struct ip_sring const* const_ring;
+
+/*------------- p_Proc stuff ----------------------*/
+typedef poly (*p_Copy_Proc_Ptr)(poly p, const ring r);
+typedef void (*p_Delete_Proc_Ptr)(poly *p, const ring r);
+typedef poly (*p_ShallowCopyDelete_Proc_Ptr)(poly p, const ring r, omBin dest_bin);
+typedef poly (*p_Mult_nn_Proc_Ptr)(poly p, const number n, const ring r);
+typedef poly (*pp_Mult_nn_Proc_Ptr)(poly p, const number n, const ring r);
+typedef poly (*p_Mult_mm_Proc_Ptr)(poly p, const poly m, const ring r);
+typedef poly (*pp_Mult_mm_Proc_Ptr)(poly p, const poly m, const ring r);
+typedef poly (*pp_Mult_mm_Noether_Proc_Ptr)(poly p, const poly m,
+                                            const poly spNoether, int &ll,
+                                            const ring r);
+typedef poly (*p_Add_q_Proc_Ptr)(poly p, poly q, int & shorter, const ring r);
+typedef poly (*p_Minus_mm_Mult_qq_Proc_Ptr)(poly p, poly m, poly q,
+                                            int &shorter, const poly spNoether,
+                                            const ring r);
+typedef poly (*p_Neg_Proc_Ptr)(poly p, const ring r);
+typedef poly (*pp_Mult_Coeff_mm_DivSelect_Proc_Ptr)(poly p, const poly m,
+                                                    int &shorter,const ring r);
+typedef poly (*pp_Mult_Coeff_mm_DivSelectMult_Proc_Ptr)
+  (poly p,const poly m, const poly a, const poly b, int &shorter,const ring r);
+
+typedef poly (*p_Merge_q_Proc_Ptr)(poly p, poly q, const ring r);
+typedef void (*p_kBucketSetLm_Proc_Ptr)(kBucket_pt bucket);
+
+typedef struct p_Procs_s
+{
+  p_Copy_Proc_Ptr                       p_Copy;
+  p_Delete_Proc_Ptr                     p_Delete;
+  p_ShallowCopyDelete_Proc_Ptr          p_ShallowCopyDelete;
+  p_Mult_nn_Proc_Ptr                    p_Mult_nn;
+  pp_Mult_nn_Proc_Ptr                   pp_Mult_nn;
+  pp_Mult_mm_Proc_Ptr                   pp_Mult_mm;
+  pp_Mult_mm_Noether_Proc_Ptr           pp_Mult_mm_Noether;
+  p_Mult_mm_Proc_Ptr                    p_Mult_mm;
+  p_Add_q_Proc_Ptr                      p_Add_q;
+  p_Minus_mm_Mult_qq_Proc_Ptr           p_Minus_mm_Mult_qq;
+  p_Neg_Proc_Ptr                        p_Neg;
+  pp_Mult_Coeff_mm_DivSelect_Proc_Ptr   pp_Mult_Coeff_mm_DivSelect;
+  pp_Mult_Coeff_mm_DivSelectMult_Proc_Ptr   pp_Mult_Coeff_mm_DivSelectMult;
+  p_Merge_q_Proc_Ptr                    p_Merge_q;
+  p_kBucketSetLm_Proc_Ptr               p_kBucketSetLm;
+} pProcs_s;
+
+
+void p_ProcsSet(ring r, p_Procs_s* p_Procs);
+#ifdef RDEBUG
+void p_Debug_GetSpecNames(const ring r, const char* &field, const char* &length,
+                          const char* &ord);
+void p_Debug_GetProcNames(const ring r, p_Procs_s* p_Procs);
+#endif
+// if set, then dynamic p_procs are used, otherwise static
+extern const BOOLEAN p_procs_dynamic;
+
+#endif /* ! P_PROCS_H */
diff --git a/libpolys/polys/templates/p_Procs_Dynamic.cc b/libpolys/polys/templates/p_Procs_Dynamic.cc
new file mode 100644
index 0000000..af54494
--- /dev/null
+++ b/libpolys/polys/templates/p_Procs_Dynamic.cc
@@ -0,0 +1,237 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    p_Procs_Dynamic.cc
+ *  Purpose: source for dynamically loaded version of p_Procs
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 12/00
+ *******************************************************************/
+#include <misc/auxiliary.h>
+
+#include <factory/factory.h>
+
+#include <reporter/reporter.h>
+
+// #include <polys/structs.h>
+#include <polys/monomials/ring.h>
+#include <polys/monomials/p_polys.h>
+
+#include <polys/kbuckets.h>
+
+#include <polys/templates/p_Numbers.h>
+
+#include <polys/templates/p_Procs.h>
+#include <polys/templates/p_MemCmp.h>
+#include <polys/templates/p_MemAdd.h>
+#include <polys/templates/p_MemCopy.h>
+
+
+#ifdef HAVE_DL
+const BOOLEAN p_procs_dynamic = TRUE;
+
+#define WARN_MSG "Singular will work properly, but much slower."
+
+// need external linkage, so that dynl_sym works
+#undef LINKAGE
+#define LINKAGE extern "C"
+#define p_Procs_Kernel
+
+#include "templates/p_Procs.inc"
+
+#include "templates/p_Procs_Dynamic.h"
+// include general p_Proc stuff
+#include "templates/p_Procs_Impl.h"
+
+#include "mod_raw.h"
+
+// define to bound for length of p_Proc name
+#define MAX_PROCNAME_LEN 200
+
+static void* p_procs_handle_FieldIndep = NULL;
+static void* p_procs_handle_FieldZp = NULL;
+static void* p_procs_handle_FieldQ = NULL;
+static void* p_procs_handle_FieldGeneral = NULL;
+
+static void* p_ProcInitHandle(void** handle, const char* module)
+{
+  if (*handle == NULL)
+  {
+    char name[25];
+    sprintf(name, "p_Procs_%s", module);
+    *handle = dynl_open_binary_warn(name, WARN_MSG);
+  }
+  return *handle;
+}
+
+static inline void* p_ProcGetHandle(p_Proc proc, p_Field field)
+{
+  const char* module =  p_ProcField_2_Module(proc, field);
+
+  if (strcmp(module, "FieldIndep") == 0)
+    return p_ProcInitHandle(&p_procs_handle_FieldIndep, module);
+  else if (strcmp(module, "FieldZp") == 0)
+    return p_ProcInitHandle(&p_procs_handle_FieldZp, module);
+  else if (strcmp(module, "FieldQ") == 0)
+    return p_ProcInitHandle(&p_procs_handle_FieldQ, module);
+  else if (strcmp(module, "FieldGeneral") == 0)
+    return p_ProcInitHandle(&p_procs_handle_FieldGeneral, module);
+  else
+  {
+    assume(0);
+    return NULL;
+  }
+}
+
+
+static void* GetGeneralProc(p_Proc proc)
+{
+  switch(proc)
+  {
+      case p_Copy_Proc:
+        return cast_A_to_vptr(p_Copy__FieldGeneral_LengthGeneral_OrdGeneral);
+      case p_Delete_Proc:
+        return cast_A_to_vptr(p_Delete__FieldGeneral_LengthGeneral_OrdGeneral);
+      case p_ShallowCopyDelete_Proc:
+        return cast_A_to_vptr(p_ShallowCopyDelete__FieldGeneral_LengthGeneral_OrdGeneral);
+      case p_Mult_nn_Proc:
+        return cast_A_to_vptr(p_Mult_nn__FieldGeneral_LengthGeneral_OrdGeneral);
+      case pp_Mult_nn_Proc:
+        return cast_A_to_vptr(pp_Mult_nn__FieldGeneral_LengthGeneral_OrdGeneral);
+      case pp_Mult_mm_Proc:
+        return cast_A_to_vptr(pp_Mult_mm__FieldGeneral_LengthGeneral_OrdGeneral);
+      case pp_Mult_mm_Noether_Proc:
+        return cast_A_to_vptr(pp_Mult_mm_Noether__FieldGeneral_LengthGeneral_OrdGeneral);
+      case p_Mult_mm_Proc:
+        return cast_A_to_vptr(p_Mult_mm__FieldGeneral_LengthGeneral_OrdGeneral);
+      case p_Add_q_Proc:
+        return cast_A_to_vptr(p_Add_q__FieldGeneral_LengthGeneral_OrdGeneral);
+      case p_Minus_mm_Mult_qq_Proc:
+        return cast_A_to_vptr(p_Minus_mm_Mult_qq__FieldGeneral_LengthGeneral_OrdGeneral);
+      case p_Neg_Proc:
+        return cast_A_to_vptr(p_Neg__FieldGeneral_LengthGeneral_OrdGeneral);
+      case pp_Mult_Coeff_mm_DivSelect_Proc:
+        return cast_A_to_vptr(pp_Mult_Coeff_mm_DivSelect__FieldGeneral_LengthGeneral_OrdGeneral);
+      case pp_Mult_Coeff_mm_DivSelectMult_Proc:
+        return cast_A_to_vptr(pp_Mult_Coeff_mm_DivSelectMult__FieldGeneral_LengthGeneral_OrdGeneral);
+      case p_Merge_q_Proc:
+        return cast_A_to_vptr(p_Merge_q__FieldGeneral_LengthGeneral_OrdGeneral);
+      case p_kBucketSetLm_Proc:
+        return cast_A_to_vptr(p_kBucketSetLm__FieldGeneral_LengthGeneral_OrdGeneral);
+      case p_Unknown_Proc:
+        break;
+  }
+  dReportBug("p_Unknown_Proc");
+  return NULL;
+}
+
+#ifdef RDEBUG
+#include <omalloc/omalloc.h>
+
+static const char* GetGeneralProcName(p_Proc proc)
+{
+  switch(proc)
+  {
+      case p_Copy_Proc:
+        return "p_Copy__FieldGeneral_LengthGeneral_OrdGeneral";
+      case p_Delete_Proc:
+        return "p_Delete__FieldGeneral_LengthGeneral_OrdGeneral";
+      case p_ShallowCopyDelete_Proc:
+        return "p_ShallowCopyDelete__FieldGeneral_LengthGeneral_OrdGeneral";
+      case p_Mult_nn_Proc:
+        return "p_Mult_nn__FieldGeneral_LengthGeneral_OrdGeneral";
+      case pp_Mult_nn_Proc:
+        return "pp_Mult_nn__FieldGeneral_LengthGeneral_OrdGeneral";
+      case pp_Mult_mm_Proc:
+        return "pp_Mult_mm__FieldGeneral_LengthGeneral_OrdGeneral";
+      case pp_Mult_mm_Noether_Proc:
+        return "pp_Mult_mm_Noether__FieldGeneral_LengthGeneral_OrdGeneral";
+      case p_Mult_mm_Proc:
+        return "p_Mult_mm__FieldGeneral_LengthGeneral_OrdGeneral";
+      case p_Add_q_Proc:
+        return "p_Add_q__FieldGeneral_LengthGeneral_OrdGeneral";
+      case p_Minus_mm_Mult_qq_Proc:
+        return "p_Minus_mm_Mult_qq__FieldGeneral_LengthGeneral_OrdGeneral";
+      case p_Neg_Proc:
+        return "p_Neg__FieldGeneral_LengthGeneral_OrdGeneral";
+      case pp_Mult_Coeff_mm_DivSelect_Proc:
+        return "pp_Mult_Coeff_mm_DivSelect__FieldGeneral_LengthGeneral_OrdGeneral";
+      case pp_Mult_Coeff_mm_DivSelectMult_Proc:
+        return "pp_Mult_Coeff_mm_DivSelectMult__FieldGeneral_LengthGeneral_OrdGeneral";
+      case p_Merge_q_Proc:
+        return "p_Merge_q__FieldGeneral_LengthGeneral_OrdGeneral";
+      case p_kBucketSetLm_Proc:
+        return "p_kBucketSetLm__FieldGeneral_LengthGeneral_OrdGeneral";
+      case p_Unknown_Proc:
+        break;
+  }
+  return "p_Unknown_Proc";
+}
+#endif
+
+
+static void* GetDynamicProc(const char* proc_s, p_Proc proc,
+                            p_Field field, p_Length length, p_Ord ord
+#ifdef RDEBUG
+                     , int get_name = 0
+#endif
+                     )
+{
+  void* proc_ptr = NULL;
+  char proc_name[MAX_PROCNAME_LEN];
+  sprintf(proc_name, "%s__%s_%s_%s", proc_s,
+          p_FieldEnum_2_String(field),
+          p_LengthEnum_2_String(length),
+          p_OrdEnum_2_String(ord));
+  // printf("set %s\n",proc_name);
+  // first, try to get the proc from the kernel
+  proc_ptr = dynl_sym(DYNL_KERNEL_HANDLE, proc_name);
+  if (proc_ptr == NULL)
+  {
+    proc_ptr = dynl_sym_warn(p_ProcGetHandle(proc, field), proc_name, WARN_MSG);
+    // last but not least use general proc
+    if (proc_ptr == NULL)
+    {
+      proc_ptr = GetGeneralProc(proc);
+#ifdef RDEBUG
+      sprintf(proc_name,"%s", GetGeneralProcName(proc));
+#endif
+    }
+  }
+#ifdef RDEBUG
+  if (get_name)
+  {
+    char* name = omStrDup(proc_name);
+#if (!defined(SING_NDEBUG)) && (!defined(OM_NDEBUG))
+    omMarkAsStaticAddr(name);
+#endif
+    return (void*) name;
+  }
+#endif
+  return  proc_ptr;
+}
+
+
+#define DoReallySetProc(what, field, length, ord)           \
+  _p_procs->what =    cast_vptr_to_A<what##_Proc_Ptr>(      \
+     GetDynamicProc(#what, what##_Proc, field, length, ord))
+
+#ifdef RDEBUG
+#define DoSetProc(what, field, length, ord)                         \
+do                                                                  \
+{                                                                   \
+  if (set_names)                                                    \
+    _p_procs->what =    cast_vptr_to_A<what##_Proc_Ptr>(            \
+       GetDynamicProc(#what,  what##_Proc, field, length, ord, 1));  \
+  else                                                              \
+    DoReallySetProc(what, field, length, ord);                      \
+}                                                                   \
+while(0)
+#else
+#define DoSetProc DoReallySetProc
+#endif
+
+#include "templates/p_Procs_Set.h"
+
+#endif
+
diff --git a/libpolys/polys/templates/p_Procs_Dynamic.h b/libpolys/polys/templates/p_Procs_Dynamic.h
new file mode 100644
index 0000000..296b6fb
--- /dev/null
+++ b/libpolys/polys/templates/p_Procs_Dynamic.h
@@ -0,0 +1,32 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+
+/***************************************************************
+ *  File:    p_Procs_Dynamic.h
+ *  Purpose: Configuration for p_Procs as dynamic library procedures
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 12/00
+ *******************************************************************/
+
+#ifndef P_PROCS_DYNAMIC_H
+#define P_PROCS_DYNAMIC_H
+
+// see p_Procs_Impl.h for an explaination of these defines
+#define HAVE_FAST_P_PROCS   5
+#define HAVE_FAST_FIELD     2
+#define HAVE_FAST_ORD 4
+#define HAVE_FAST_ZERO_ORD 2
+
+// stupid hpux -- can not handle sl which are that large
+#ifdef __hpux
+#define HAVE_FAST_LENGTH 3
+#else
+#define HAVE_FAST_LENGTH 4
+#endif
+
+// for the configuration of what goes into the kenel and what into
+// shared libs, see p_Procs_Generate.cc:IsKernelProc(...)
+
+#endif // P_PROCS_DYNAMC_H
+
diff --git a/libpolys/polys/templates/p_Procs_Generate.cc b/libpolys/polys/templates/p_Procs_Generate.cc
new file mode 100644
index 0000000..6de2149
--- /dev/null
+++ b/libpolys/polys/templates/p_Procs_Generate.cc
@@ -0,0 +1,328 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    p_ProcsGenerate.cc
+ *  Purpose: generate p_Procs*.inc at compile
+ *  Note:    this file is included by p_Procs.cc
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 8/00
+ *******************************************************************/
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+#include <misc/auxiliary.h>
+
+#include <reporter/reporter.h>
+
+
+#ifdef p_Procs_Static
+#include <polys/templates/p_Procs_Static.h>
+#else
+#include <polys/templates/p_Procs_Dynamic.h>
+#endif
+
+#include <polys/templates/p_Procs_Impl.h>
+
+#ifndef p_Procs_Static
+int FieldGeneralProcs = 0,
+  FieldIndepProcs = 0,
+  FieldZpProcs = 0,
+  FieldQProcs = 0,
+#ifdef HAVE_RINGS
+  RingGeneralProcs = 0,
+#endif
+  KernelProcs = 0,
+  UnknownProcs = 0;
+
+// returns 1, if proc should go into kernel, 0 otherwise
+int IsKernelProc(p_Proc proc, p_Field field, p_Length length, p_Ord ord)
+{
+  // general procs go into kernel
+  if (field == FieldGeneral && length == LengthGeneral && ord == OrdGeneral)
+    return 1;
+
+  // plus procs with FieldZp
+  if ((field == FieldZp || field == FieldQ) &&
+      // which are not general in length or ord
+      !((length == LengthGeneral && p_ProcDependsOn_Length(proc)) ||
+        (ord == OrdGeneral && p_ProcDependsOn_Ord(proc))) &&
+      // and whose length is smaller than five
+      (!p_ProcDependsOn_Length(proc) || (length >= LengthFour)))
+    return 1;
+
+  return 0;
+}
+
+#endif
+
+#define DoSetProc(what, field, length, ord) \
+      GenerateProc(#what, what##_Proc, field, length, ord)
+
+char*** generated_p_procs;
+
+inline int AlreadyHaveProc(p_Proc proc, p_Field field, p_Length length, p_Ord ord)
+{
+  return (generated_p_procs[proc])[index(proc, field, length, ord)] != 0;
+}
+
+const char* macros_field[] = {"n_Copy","n_Delete", "n_Mult", "n_Add", "n_Sub", "n_IsZero", "n_Equal" , "n_Neg", "n_InpMult", "n_InpAdd", NULL};
+
+const char* macros_length[] =
+{"p_MemCopy", "p_MemAdd", "p_MemSum", "p_MemDiff", NULL};
+
+const char* macros_length_ord[] = {"p_MemCmp", NULL};
+int DummyProcs = 0;
+
+int NumberOfHaveProcs = 0;
+
+void AddProc(const char* s_what, p_Proc proc, p_Field field, p_Length length, p_Ord ord)
+{
+  NumberOfHaveProcs++;
+  int i;
+  const char* s_length = p_LengthEnum_2_String(length);
+  const char* s_ord = p_OrdEnum_2_String(ord);
+  const char* s_field = p_FieldEnum_2_String(field);
+  char* s_full_proc_name = (char*) malloc(200);
+
+  sprintf(s_full_proc_name, "%s__%s_%s_%s", s_what, s_field, s_length, s_ord);
+
+  (generated_p_procs[proc])[index(proc, field, length, ord)] = s_full_proc_name;
+  // define all macros
+  printf("\n// definition of %s\n", s_full_proc_name);
+#ifndef p_Procs_Static
+  if (IsKernelProc(proc, field, length, ord))
+  {
+    KernelProcs++;
+    printf("#ifdef p_Procs_Kernel\n");
+  }
+  else
+  {
+    const char* module = p_ProcField_2_Module(proc, field);
+    if (strcmp(module, "FieldGeneral") == 0)
+      FieldGeneralProcs++;
+    else if (strcmp(module, "FieldIndep") == 0)
+      FieldIndepProcs++;
+    else if (strcmp(module, "FieldZp") == 0)
+      FieldZpProcs++;
+    else if (strcmp(module, "FieldQ") == 0)
+      FieldQProcs++;
+#ifdef HAVE_RINGS
+    else if (strcmp(module, "RingGeneral") == 0)
+      RingGeneralProcs++;
+#endif
+    else
+      UnknownProcs++;
+
+    printf("#ifdef p_Procs_%s\n", module);
+  }
+#endif
+#ifdef HAVE_RINGS
+  if (strcmp(s_field, "RingGeneral") == 0)
+    printf("#define HAVE_ZERODIVISORS\n");
+#endif
+  i = 0;
+  while (macros_field[i] != NULL)
+  {
+    printf("#undef %s__T\n#define %s__T\t%s_%s\n",
+           macros_field[i], macros_field[i],  macros_field[i], s_field);
+    i++;
+  }
+  i = 0;
+  while (macros_length[i] != NULL)
+  {
+    printf("#undef %s__T\n#define %s__T\t%s_%s\n",
+           macros_length[i], macros_length[i], macros_length[i], s_length);
+    i++;
+  }
+  i = 0;
+  while (macros_length_ord[i] != NULL)
+  {
+    printf("#undef %s__T\n#define %s__T\t%s_%s_%s\n",
+           macros_length_ord[i], macros_length_ord[i], macros_length_ord[i], s_length, s_ord);
+    i++;
+  }
+
+  // define DECLARE_LENGTH
+  printf("#undef DECLARE_LENGTH\n");
+  printf("#undef p_MemAddAdjust__T\n");
+  if (length != LengthGeneral)
+  {
+    printf("#define DECLARE_LENGTH(what) do {} while (0)\n");
+    printf("#define p_MemAddAdjust__T(p, r) do {} while (0)\n");
+  }
+  else
+  {
+    printf("#define DECLARE_LENGTH(what) what\n");
+    if (proc != pp_Mult_Coeff_mm_DivSelectMult_Proc)
+      printf("#define p_MemAddAdjust__T(p, r) p_MemAdd_NegWeightAdjust(p, r)\n");
+    else
+      printf("#define p_MemAddAdjust__T(p, r) do {} while (0)\n");
+  }
+
+  // define DECLARE_ORDSGN
+  printf("#undef DECLARE_ORDSGN\n");
+  if (ord != OrdGeneral)
+    printf("#define DECLARE_ORDSGN(what) do {} while (0)\n");
+  else
+    printf("#define DECLARE_ORDSGN(what) what\n");
+
+  if (proc == pp_Mult_Coeff_mm_DivSelectMult_Proc)
+  {
+    printf("#undef DECLARE_LENGTH_2\n");
+    printf("#undef p_MemCmp_Bitmask_2\n");
+    if (length != LengthGeneral)
+    {
+      printf("#define DECLARE_LENGTH_2(what) do {} while (0)\n");
+      if (length < LengthTwo)
+        printf("#define p_MemCmp_Bitmask_2 p_MemCmp_Bitmask_%s\n", p_LengthEnum_2_String((p_Length) ((int) length + 2)));
+      else
+      printf("#define p_MemCmp_Bitmask_2 p_MemCmp_Bitmask_LengthZero\n");
+    }
+    else
+    {
+      printf("#define DECLARE_LENGTH_2(what) what \n");
+      printf("#define p_MemCmp_Bitmask_2 p_MemCmp_Bitmask_LengthGeneral\n");
+    }
+
+
+    printf("#undef p_MemAddAdjust__T\n");
+    printf("#define p_MemAddAdjust__T(p, r) do {} while (0)\n");
+  }
+
+  printf("#undef %s__T\n#define %s__T %s\n", s_what, s_what, s_full_proc_name);
+  printf("#include \"polys/templates/%s__T.cc\"\n", s_what);
+  printf("#undef %s\n", s_what);
+#ifdef HAVE_RINGS
+  if (strcmp(s_field, "RingGeneral") == 0)
+    printf("#undef HAVE_ZERODIVISORS\n");
+#endif
+#ifndef p_Procs_Static
+  printf("#endif // p_Procs_[Kernel|Field*]\n");
+#endif
+}
+
+void GenerateProc(const char* s_what, p_Proc proc, p_Field field, p_Length length, p_Ord ord)
+{
+  if (! AlreadyHaveProc(proc, field, length, ord))
+    AddProc(s_what, proc, field, length, ord);
+}
+
+int main()
+{
+  int field = FieldGeneral;
+  int length  = LengthGeneral;
+  int ord = OrdGeneral;
+  int i;
+
+
+  printf("/* -*-c++-*- */\n");
+  printf("/***************************************************************\n");
+  printf(" * This file was generated automatically by p_ProcsGenerate.cc: DO NOT EDIT\n");
+  printf(" *\n");
+  printf(" * This file provides the needed implementation of p_Procs for\n");
+  printf(" *               %s\n",
+#if defined(p_Procs_Static)
+         "p_Procs_Static"
+#else
+         "p_Procs_Dynamic"
+#endif
+  );
+  printf(" * See the end for a summary.\n");
+  printf(" *******************************************************************/\n");
+
+
+  generated_p_procs = (char***) malloc(p_Unknown_Proc*sizeof(char**));
+  for (i=0; i<p_Unknown_Proc; i++)
+  {
+    generated_p_procs[i] =
+      (char**) calloc(index((p_Proc)i, FieldUnknown, LengthUnknown, OrdUnknown), sizeof(char*));
+  }
+
+  // set default procs
+  for (field = 0; field < (int) FieldUnknown; field++)
+  {
+    for (length=0; length < (int) LengthUnknown; length++)
+    {
+      for (ord=0; ord < (int)OrdUnknown; ord++)
+      {
+        if (IsValidSpec((p_Field) field, (p_Length) length, (p_Ord) ord))
+            SetProcs((p_Field) field, (p_Length) length, (p_Ord) ord);
+      }
+    }
+  }
+
+// we only need lookup tables for p_Procs_Static
+#ifdef p_Procs_Static
+  int j;
+  printf("\n"
+  "/***************************************************************\n"
+  "Names of procs for RDEBUG */\n"
+  "#ifdef RDEBUG\n");
+
+  for (i=0; i<p_Unknown_Proc; i++)
+  {
+    printf("static const char* %s_names[] = {", p_ProcEnum_2_String((p_Proc)i));
+    for (j=0;j<index((p_Proc)i, FieldUnknown, LengthUnknown, OrdUnknown); j++)
+    {
+      char* s = (generated_p_procs[i])[j];
+      if (s != 0)
+      {
+        printf("\n\"%s\",", s);
+      }
+      else
+        printf("0,");
+
+    }
+    printf("\n};\n");
+  }
+  printf("\n #endif // RDEBUG\n\n"
+  "/***************************************************************/\n"
+  "/* Tables for lookup of procedures: */\n");
+
+  for (i=0; i<p_Unknown_Proc; i++)
+  {
+    printf("static const %s_Ptr %s_funcs[] = {", p_ProcEnum_2_String((p_Proc)i), p_ProcEnum_2_String((p_Proc)i));
+    for (j=0;j<index((p_Proc)i, FieldUnknown, LengthUnknown, OrdUnknown); j++)
+    {
+      char* s = (generated_p_procs[i])[j];
+      if (s != 0)
+      {
+        printf("\n%s,", s);
+      }
+      else
+        printf("0,");
+    }
+    printf("\n};\n");
+  }
+#endif
+
+  printf("\n/***************************************************************");
+  printf("* Summary:\n");
+  printf("*   HAVE_FAST_P_PROCS  = %d,\n",HAVE_FAST_P_PROCS);
+  printf("*   HAVE_FAST_FIELD    = %d,\n",HAVE_FAST_FIELD);
+  printf("*   HAVE_FAST_LENGTH   = %d,\n",HAVE_FAST_LENGTH);
+  printf("*   HAVE_FAST_ORD      = %d,\n",HAVE_FAST_ORD);
+  printf("*   HAVE_FAST_ZERO_ORD = %d\n",HAVE_FAST_ZERO_ORD);
+  printf("*\n");
+  printf("*   Generated PolyProcs= %d\n",NumberOfHaveProcs);
+
+#ifndef p_Procs_Static
+  printf("*\n");
+  printf("* KernelProcs          = %d\n",KernelProcs);
+  printf("* FieldIndepProcs      = %d\n",FieldIndepProcs);
+  printf("* FieldZpProcs         = %d\n",FieldZpProcs);
+  printf("* FieldQProcs          = %d\n",FieldQProcs);
+  printf("* FieldGeneralProcs    = %d\n",FieldGeneralProcs);
+  printf("* FieldUnknownProcs    = %d\n",UnknownProcs);
+#endif
+
+  printf("*\n");
+  printf("*******************************************************************/\n");
+}
+
+
diff --git a/libpolys/polys/templates/p_Procs_Impl.h b/libpolys/polys/templates/p_Procs_Impl.h
new file mode 100644
index 0000000..772108a
--- /dev/null
+++ b/libpolys/polys/templates/p_Procs_Impl.h
@@ -0,0 +1,704 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    p_Procs_Impl.h
+ *  Purpose: implementation of primitive procs for polys
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 12/00
+ *******************************************************************/
+#ifndef P_PROCS_IMPL_H
+#define P_PROCS_IMPL_H
+
+/***************************************************************
+ *
+ * Configurations
+ *
+ *******************************************************************/
+
+/***************************************************************
+ Here is how it works:
+ At run-time, SetProcs is used to choose the appropriate PolyProcs
+              based on the ring properies.
+ At generate-time, SetProcs is used to generate all
+              possible PolyProcs.
+ Which PolyProcs are generated/used can be controled by values of
+ HAVE_FAST_P_PROCS, HAVE_FAST_LENGTH, HAVE_FAST_ORD, and FAST_FIELD
+
+ At generate-time, the file p_Procs.inc is generated,
+ which provides implementations of the p_Procs, based on
+ the p_*_Templates.cc and header files which provide the respective
+ macros.
+
+ At run-time, a fast proc is set/choosen if found/generated, else
+ a general proc is set/choosen.
+ *******************************************************************/
+
+// Define HAVE_FAST_P_PROCS to:
+//   0 -- only FieldGeneral_LengthGeneral_OrdGeneral
+//   1 -- plus FieldZp_Length*_OrdGeneral procs
+//   2 -- plus FieldZp_Length*_Ord* procs
+//   3 -- plus FieldQ_Length*_Ord*
+//   4 -- plus FieldGeneral_Length*_OrdGeneral procs
+//   5 -- all Field*_Length*_Ord* procs
+#ifndef HAVE_FAST_P_PROCS
+#define HAVE_FAST_P_PROCS 0
+#endif
+
+// Define HAVE_FAST_FIELD to:
+//   0 -- only FieldGeneral
+//   1 -- special cases for FieldZp
+//   2 -- plus special cases for FieldQ
+//   nothing else is implemented, yet
+#ifndef HAVE_FAST_FIELD
+#define HAVE_FAST_FIELD 0
+#endif
+
+// Define HAVE_FAST_LENGTH to:
+//   0 -- only LengthGeneral
+//   1 -- special cases for length <= 1
+//   2 -- special cases for length <= 2
+//   3 -- special cases for length <= 4
+//   4 -- special cases for length <= 8
+#ifndef HAVE_FAST_LENGTH
+#define HAVE_FAST_LENGTH 0
+#endif
+
+// Define HAVE_FAST_ORD to:
+//  0  -- only OrdGeneral
+//  1  -- special for ords with n_min <= 1
+//  2  -- special for ords with n_min <= 2
+//  3  -- special ords for with n_min <= 3
+//  4  -- special for all ords
+#ifndef HAVE_FAST_ORD
+#define HAVE_FAST_ORD 0
+#endif
+
+// Define HAVE_FAST_ZERO_ORD to:
+//  0 -- no zero ords are considered
+//  1 -- only ZeroOrds for OrdPosNomogPosZero, OrdNomogPosZero, OrdPomogNegZero
+//  2 -- ZeroOrds for all
+#ifndef HAVE_FAST_ZERO_ORD
+#define HAVE_FAST_ZERO_ORD 0
+#endif
+
+// undefine this, if ExpL_Size always equals CompLSize
+#define HAVE_LENGTH_DIFF
+
+
+// Predicate which returns true if alloc/copy/free of numbers is
+// like that of Zp (rings should use GMP in future)
+#ifdef HAVE_RINGS
+#define ZP_COPY_FIELD(field) \
+  (field == FieldZp || field == FieldGF || field == FieldR)
+#else
+#define ZP_COPY_FIELD(field) \
+  (field == FieldZp || field == FieldGF || field == FieldR)
+#endif
+
+/***************************************************************
+ *
+ * Definitions of our fields, lengths, ords, procs we work with
+ *
+ *******************************************************************/
+
+// Here are the different parameters for setting the PolyProcs:
+
+// If you add/remove things from here, also remeber to adjust the
+// respective *_2_String
+typedef enum p_Field
+{
+  FieldGeneral = 0,
+  FieldZp,
+  FieldQ,
+  FieldR,
+  FieldGF,
+#if HAVE_MORE_FIELDS_IMPLEMENTED
+  FieldLong_R,
+  FieldLong_C,
+  FieldZp_a,
+  FieldQ_a,
+#endif
+#ifdef HAVE_RINGS
+  RingGeneral,
+#endif
+  FieldUnknown
+} p_Field;
+typedef enum p_Length // Length of exponent vector in words
+{
+  LengthGeneral = 0, // n >= 1
+  LengthEight,       // n == 8
+  LengthSeven,
+  LengthSix,
+  LengthFive,
+  LengthFour,
+  LengthThree,
+  LengthTwo,
+  LengthOne,
+  LengthUnknown
+} p_Length;
+typedef enum p_Ord
+{
+  OrdGeneral = 0,
+                    //     ordsgn
+                    //  0   1   i   n-1 n   n_min   Example
+  OrdPomog,         //  +   +   +   +   +   1       (lp,C)
+  OrdNomog,         //  -   -   -   -   -   1       (ls, c), (ds, c)
+#define ORD_MAX_N_1 OrdNomog
+
+#ifdef HAVE_LENGTH_DIFF
+  OrdPomogZero,     //  +   +   +   +   0   2       (Dp, C), Even vars
+  OrdNomogZero,     //  -   -   -   -   0   2       (ds, c), Even vars
+#endif
+
+  OrdNegPomog,      //  -   +   +   +   +   2       (c, lp), (Ds, c)
+  OrdPomogNeg,      //  +   +   +   +   -   2       (lp, c)
+#define ORD_MAX_N_2 OrdPomogNeg
+
+  OrdPosNomog,      //  +   -   -   -   +   3       (dp, c) (for n == 2, use PomogNeg)
+  OrdNomogPos,      //  -   -   -   -   +   3       (ls, C) (for n == 2, use NegPomog)
+
+#ifdef HAVE_LENGTH_DIFF
+  OrdNegPomogZero,  //  -   +   +   +   0   3       (c, lp), (Ds, c)
+  OrdPomogNegZero,  //  +   +   +   -   0   3       (lp, c)
+#endif
+
+  OrdPosPosNomog,   //  +   +   -   -   -   3       (C, dp)
+  OrdPosNomogPos,   //  +   -   -   -   +   3       (dp, C)
+  OrdNegPosNomog,   //  -   +   -   -   -   3       (c, dp)
+#define ORD_MAX_N_3 OrdNegPosNomog
+
+#ifdef HAVE_LENGTH_DIFF
+  OrdNomogPosZero,  //  -   -   -   +   0   4       (ls, C) (for n == 3, use NegPomogZero)
+  OrdPosNomogZero,  //  +   -   -   -   0   4       (dp, c) (for n == 3, use PomogNegZero)
+
+  OrdPosPosNomogZero,// +   +   -   -   0   4       (C, dp)
+  OrdPosNomogPosZero,// +   -   -   +   0   4       (dp, C)
+  OrdNegPosNomogZero,// -   +   -   -   0   4       (c, dp)
+#endif
+
+  OrdUnknown
+} p_Ord;
+
+typedef enum p_Proc
+{
+  p_Copy_Proc = 0,
+  p_Delete_Proc,
+  p_ShallowCopyDelete_Proc,
+  p_Mult_nn_Proc,
+  pp_Mult_nn_Proc,
+  pp_Mult_mm_Proc,
+  pp_Mult_mm_Noether_Proc,
+  p_Mult_mm_Proc,
+  p_Add_q_Proc,
+  p_Minus_mm_Mult_qq_Proc,
+  p_Neg_Proc,
+  pp_Mult_Coeff_mm_DivSelect_Proc,
+  pp_Mult_Coeff_mm_DivSelectMult_Proc,
+  p_Merge_q_Proc,
+  p_kBucketSetLm_Proc,
+  p_Unknown_Proc
+} p_Proc;
+
+static inline const char* p_FieldEnum_2_String(p_Field field)
+{
+  switch(field)
+  {
+      case FieldGeneral: return "FieldGeneral";
+      case FieldZp: return "FieldZp";
+      case FieldQ: return "FieldQ";
+      case FieldR: return "FieldR";
+      case FieldGF: return "FieldGF";
+#if HAVE_MORE_FIELDS_IMPLEMENTED
+      case FieldLong_R: return "FieldLong_R";
+      case FieldLong_C: return "FieldLong_C";
+      case FieldZp_a: return "FieldZp_a";
+      case FieldQ_a: return "FieldQ_a";
+#endif
+#ifdef HAVE_RINGS
+      case RingGeneral: return "RingGeneral";
+#endif
+      case FieldUnknown: return "FieldUnknown";
+  }
+  return "NoField_2_String";
+}
+
+static inline const char* p_LengthEnum_2_String(p_Length length)
+{
+  switch(length)
+  {
+      case LengthGeneral: return "LengthGeneral";
+      case LengthEight: return "LengthEight";
+      case LengthSeven: return "LengthSeven";
+      case LengthSix: return "LengthSix";
+      case LengthFive: return "LengthFive";
+      case LengthFour: return "LengthFour";
+      case LengthThree: return "LengthThree";
+      case LengthTwo: return "LengthTwo";
+      case LengthOne: return "LengthOne";
+      case LengthUnknown: return "LengthUnknown";
+  }
+  return "NoLength_2_String";
+}
+
+static inline const char* p_OrdEnum_2_String(p_Ord ord)
+{
+  switch(ord)
+  {
+      case OrdGeneral: return "OrdGeneral";
+      case OrdPomog: return "OrdPomog";
+      case OrdNomog: return "OrdNomog";
+      case OrdNegPomog: return "OrdNegPomog";
+      case OrdPomogNeg: return "OrdPomogNeg";
+      case OrdPosNomog: return "OrdPosNomog";
+      case OrdNomogPos: return "OrdNomogPos";
+      case OrdPosPosNomog: return "OrdPosPosNomog";
+      case OrdPosNomogPos: return "OrdPosNomogPos";
+      case OrdNegPosNomog: return "OrdNegPosNomog";
+#ifdef HAVE_LENGTH_DIFF
+      case OrdNegPomogZero: return "OrdNegPomogZero";
+      case OrdPomogNegZero: return "OrdPomogNegZero";
+      case OrdPomogZero: return "OrdPomogZero";
+      case OrdNomogZero: return "OrdNomogZero";
+      case OrdNomogPosZero: return "OrdNomogPosZero";
+      case OrdPosNomogZero: return "OrdPosNomogZero";
+      case OrdPosPosNomogZero: return "OrdPosPosNomogZero";
+      case OrdPosNomogPosZero: return "OrdPosNomogPosZero";
+      case OrdNegPosNomogZero: return "OrdNegPosNomogZero";
+#endif
+      case OrdUnknown: return "OrdUnknown";
+  }
+  return "NoOrd_2_String";
+}
+
+static inline const char* p_ProcEnum_2_String(p_Proc proc)
+{
+  switch(proc)
+  {
+      case p_Copy_Proc: return "p_Copy_Proc";
+      case p_Delete_Proc: return "p_Delete_Proc";
+      case p_ShallowCopyDelete_Proc: return "p_ShallowCopyDelete_Proc";
+      case p_Mult_nn_Proc: return "p_Mult_nn_Proc";
+      case pp_Mult_nn_Proc: return "pp_Mult_nn_Proc";
+      case pp_Mult_mm_Proc: return "pp_Mult_mm_Proc";
+      case pp_Mult_mm_Noether_Proc: return "pp_Mult_mm_Noether_Proc";
+      case p_Mult_mm_Proc: return "p_Mult_mm_Proc";
+      case p_Add_q_Proc: return "p_Add_q_Proc";
+      case p_Minus_mm_Mult_qq_Proc: return "p_Minus_mm_Mult_qq_Proc";
+      case p_Neg_Proc: return "p_Neg_Proc";
+      case pp_Mult_Coeff_mm_DivSelect_Proc: return "pp_Mult_Coeff_mm_DivSelect_Proc";
+      case pp_Mult_Coeff_mm_DivSelectMult_Proc: return "pp_Mult_Coeff_mm_DivSelectMult_Proc";
+      case p_Merge_q_Proc: return "p_Merge_q_Proc";
+      case p_kBucketSetLm_Proc: return "p_kBucketSetLm_Proc";
+      case p_Unknown_Proc: return "p_Unknown_Proc";
+  }
+  return "NoProc_2_String";
+}
+
+static inline int p_ProcDependsOn_Field(p_Proc proc)
+{
+  if (proc == p_ShallowCopyDelete_Proc ||
+      proc == p_Merge_q_Proc)
+    return 0;
+  return 1;
+}
+
+static inline int p_ProcDependsOn_Ord(p_Proc proc)
+{
+  switch(proc)
+  {
+      case p_Add_q_Proc:
+      case p_Minus_mm_Mult_qq_Proc:
+      case pp_Mult_mm_Noether_Proc:
+      case p_kBucketSetLm_Proc:
+      case p_Merge_q_Proc:
+        return 1;
+
+      default:
+        return 0;
+  }
+}
+
+static inline int p_ProcDependsOn_Length(p_Proc proc)
+{
+  switch(proc)
+  {
+      case p_Delete_Proc:
+      case p_Mult_nn_Proc:
+      case p_Neg_Proc:
+        return 0;
+
+      default:
+        return 1;
+  }
+}
+
+// returns string specifying the module into which the p_Proc
+// should go
+static inline const char* p_ProcField_2_Module(p_Proc proc,  p_Field field)
+{
+  if (! p_ProcDependsOn_Field(proc))
+    return "FieldIndep";
+  else
+  {
+    if (field > FieldQ) field = FieldGeneral;
+    return p_FieldEnum_2_String(field);
+  }
+}
+
+/***************************************************************
+ *
+ *
+ * Deal with OrdZero
+ *
+ *******************************************************************/
+#ifdef HAVE_LENGTH_DIFF
+static inline int IsZeroOrd(p_Ord ord)
+{
+  return (ord == OrdPomogZero || ord == OrdNomogZero ||
+          ord == OrdNegPomogZero || ord == OrdPosNomogZero ||
+          ord == OrdPomogNegZero || ord == OrdNomogPosZero ||
+          ord == OrdPosNomogPosZero || ord == OrdPosPosNomogZero ||
+          ord == OrdNegPosNomogZero);
+}
+
+static inline p_Ord ZeroOrd_2_NonZeroOrd(p_Ord ord, int strict)
+{
+  if (IsZeroOrd(ord))
+  {
+    switch (ord)
+    {
+        case OrdPomogZero:      return OrdPomog;
+        case OrdNomogZero:      return OrdNomog;
+        case OrdNegPomogZero:   return OrdNegPomog;
+        case OrdPosNomogZero:   return OrdPosNomog;
+        case OrdPosPosNomogZero:    return OrdPosPosNomog;
+        case OrdNegPosNomogZero:    return OrdNegPosNomog;
+        default:
+          if (strict) return OrdGeneral;
+          else if (ord == OrdPomogNegZero) return OrdPomogNeg;
+          else if (ord == OrdNomogPosZero) return OrdNomogPos;
+          else if (ord == OrdPosNomogPosZero) return OrdPosNomogPos;
+          else return OrdGeneral;
+    }
+  }
+  else
+  {
+    return ord;
+  }
+}
+#else
+#define IsZeroOrd(ord) 0
+#define ZeroOrd_2_NonZeroOrd(ord) (ord)
+#endif
+
+/***************************************************************
+ *
+ * Filters which are applied to field/length/ord, before a proc is
+ * choosen
+ *
+ *******************************************************************/
+#ifdef p_Procs_Static
+static inline void StaticKernelFilter(p_Field &field, p_Length &length,
+                                      p_Ord &ord, const p_Proc proc)
+{
+  // simply exclude some things
+  if ((proc == pp_Mult_mm_Noether_Proc || proc == p_kBucketSetLm_Proc) &&
+#ifdef HAVE_RINGS
+      (field != RingGeneral) &&
+#endif
+      (field != FieldZp))
+  {
+    field = FieldGeneral;
+    length = LengthGeneral;
+    ord = OrdGeneral;
+  }
+}
+#endif
+
+static inline void FastP_ProcsFilter(p_Field &field, p_Length &length, p_Ord &ord, const p_Proc proc)
+{
+  if (HAVE_FAST_P_PROCS >= 5) return;
+
+  if (HAVE_FAST_P_PROCS < 3 && field == FieldQ)
+    field = FieldGeneral;
+
+  if ((HAVE_FAST_P_PROCS == 0) ||
+      (HAVE_FAST_P_PROCS <= 4 && field != FieldZp && field != FieldQ &&
+       proc != p_Merge_q_Proc))
+  {
+#ifdef HAVE_RINGS
+    if (field != RingGeneral)
+#endif
+    field = FieldGeneral;
+    length = LengthGeneral;
+    ord = OrdGeneral;
+    return;
+  }
+  if (HAVE_FAST_P_PROCS == 1 ||
+      (HAVE_FAST_P_PROCS == 4 && field != FieldZp && proc != p_Merge_q_Proc))
+    ord = OrdGeneral;
+}
+
+static inline void FastFieldFilter(p_Field &field)
+{
+  if (HAVE_FAST_FIELD <= 0 ||
+      (HAVE_FAST_FIELD == 1 && field != FieldZp) ||
+      (field != FieldZp && field != FieldQ))
+#ifdef HAVE_RINGS
+    if (field != RingGeneral)
+#endif
+    field = FieldGeneral;
+}
+
+static inline void FastLengthFilter(p_Length &length)
+{
+  if ((HAVE_FAST_LENGTH == 3 && length <= LengthFive) ||
+      (HAVE_FAST_LENGTH == 2 && length <= LengthFour) ||
+      (HAVE_FAST_LENGTH == 1 && length <= LengthTwo) ||
+      (HAVE_FAST_LENGTH <= 0))
+  {
+    length = LengthGeneral;
+  }
+}
+
+static inline void FastOrdFilter(p_Ord &ord)
+{
+  if ((HAVE_FAST_ORD == 3 && ord >= OrdNomogPosZero) ||
+      (HAVE_FAST_ORD == 2 && ord >= OrdPosNomog) ||
+      (HAVE_FAST_ORD == 1 && ord >= OrdPomogZero) ||
+      (HAVE_FAST_ORD <= 0))
+    ord = OrdGeneral;
+}
+
+static inline void FastOrdZeroFilter(p_Ord &ord)
+{
+  if (IsZeroOrd(ord))
+  {
+    if ((HAVE_FAST_ZERO_ORD == 1 && (ord != OrdPosNomogPosZero &&
+                                     ord != OrdNomogPosZero &&
+                                     ord != OrdPomogNegZero)) ||
+        (HAVE_FAST_ZERO_ORD <= 0))
+      ord = ZeroOrd_2_NonZeroOrd(ord, 1);
+  }
+}
+
+static inline void NCopy__Filter(p_Field &field)
+{
+  if (ZP_COPY_FIELD(field)) field = FieldZp;
+}
+
+// in p_Add_q, p_MemCmp works with CompLSize,
+// hence, we do not need to consider ZeroOrds
+static inline void p_Add_q__Filter(p_Length &length, p_Ord &ord)
+{
+  if (IsZeroOrd(ord))
+  {
+    ord = ZeroOrd_2_NonZeroOrd(ord, 0);
+    if (length > LengthGeneral)
+    {
+      length = (p_Length) ((int)length + 1);
+    }
+  }
+}
+
+static inline void pp_Mult_mm_Noether_Filter(p_Field &field,
+                                             p_Length &length, p_Ord &ord)
+{
+  if (ord == OrdPomog
+      || ord == OrdPomogZero
+      || (ord == OrdPomogNeg && length > LengthTwo)
+#ifdef HAVE_LENGTH_DIFF
+      || (ord == OrdPomogZero)
+      || (ord == OrdPomogNegZero && length > LengthThree)
+#endif
+      )
+  {
+    // all the other orderings might occur (remember Mixed Orderings!)
+#ifdef HAVE_RINGS
+    if (field != RingGeneral)
+#endif
+    field = FieldGeneral;
+    ord = OrdGeneral;
+    length = LengthGeneral;
+  }
+}
+
+static inline void FastProcFilter(p_Proc proc, p_Field &field,
+                                  p_Length &length, p_Ord &ord)
+{
+  switch(proc)
+  {
+      case p_Add_q_Proc:
+      case p_Merge_q_Proc:
+        p_Add_q__Filter(length, ord);
+        break;
+
+      case p_Copy_Proc:
+      case p_Delete_Proc:
+        NCopy__Filter(field);
+        break;
+
+      case pp_Mult_mm_Noether_Proc:
+        pp_Mult_mm_Noether_Filter(field, length, ord);
+        break;
+
+        case pp_Mult_Coeff_mm_DivSelectMult_Proc:
+          if (length == LengthOne || length == LengthTwo)
+          {
+#ifdef HAVE_RINGS
+            if (field != RingGeneral)
+#endif
+            field = FieldGeneral;
+            length = LengthGeneral;
+            ord = OrdGeneral;
+            return;
+          }
+          break;
+
+      default: break;
+  }
+
+  FastOrdFilter(ord);
+  FastOrdZeroFilter(ord);
+  FastLengthFilter(length);
+  FastFieldFilter(field);
+  FastP_ProcsFilter(field, length, ord, proc);
+#ifdef p_Procs_Static
+  StaticKernelFilter(field, length, ord, proc);
+#endif
+}
+
+// returns 1 if combination of field/length/ord is invalid
+static inline int IsValidSpec(p_Field field, p_Length length, p_Ord ord)
+{
+  if (field == FieldUnknown || length == LengthUnknown || ord == OrdUnknown)
+    return 0;
+
+  if (length >= LengthThree && // i.e. 1, 2, or 3
+      ord > ORD_MAX_N_3)       //  i.e. OrdNomogPosZero and below
+    return 0;
+
+  if (length >= LengthTwo &&    // i.e. 1 or 2
+      ord > ORD_MAX_N_2)        // i.e. PosNomog and below
+    return 0;
+
+  if (length == LengthOne &&
+      ord > ORD_MAX_N_1)           // i.e. PosPomogZero and below
+    return 0;
+
+  // we cover everything for length <= two
+  if (ord == OrdGeneral && length >= LengthTwo)
+    return 0;
+  return 1;
+}
+
+
+static inline int index(p_Length length, p_Ord ord)
+{
+  return length*OrdUnknown + ord;
+}
+
+static inline int index(p_Field field, p_Length length)
+{
+  return field*LengthUnknown + length;
+}
+
+static inline int index(p_Field field, p_Length length, p_Ord ord)
+{
+  return field*LengthUnknown*OrdUnknown + length*OrdUnknown + ord;
+}
+
+static inline int index(p_Proc proc, p_Field field, p_Length length, p_Ord ord)
+{
+  switch(proc)
+  {
+      case p_Delete_Proc:
+      case p_Mult_nn_Proc:
+      case p_Neg_Proc:
+        return field;
+
+      case p_ShallowCopyDelete_Proc:
+        return length;
+
+      case p_Copy_Proc:
+      case pp_Mult_mm_Proc:
+      case p_Mult_mm_Proc:
+      case pp_Mult_nn_Proc:
+      case pp_Mult_Coeff_mm_DivSelect_Proc:
+      case pp_Mult_Coeff_mm_DivSelectMult_Proc:
+        return index(field, length);
+
+      case p_Add_q_Proc:
+      case p_Minus_mm_Mult_qq_Proc:
+      case pp_Mult_mm_Noether_Proc:
+      case p_kBucketSetLm_Proc:
+        return index(field, length, ord);
+
+      case p_Merge_q_Proc:
+        return index(length, ord);
+
+      default:
+        assume(0);
+        return -1;
+  }
+}
+
+
+
+/***************************************************************
+ *
+ * Macros for setting procs -- these are used for
+ * generation and setting
+ *
+ ***************************************************************/
+
+#define SetProc(what, field, length, ord)                   \
+do                                                          \
+{                                                           \
+  p_Field t_field = field;                                  \
+  p_Ord t_ord = ord;                                        \
+  p_Length t_length = length;                               \
+  FastProcFilter(what##_Proc, t_field, t_length, t_ord);    \
+  DoSetProc(what, t_field, t_length, t_ord);                \
+}                                                           \
+while (0)                                                   \
+
+#define SetProcs(field, length, ord)                                    \
+do                                                                      \
+{                                                                       \
+  SetProc(p_Copy, field, length, OrdGeneral);                           \
+  SetProc(p_Delete, field, LengthGeneral, OrdGeneral);                  \
+  SetProc(p_ShallowCopyDelete, FieldGeneral, length, OrdGeneral);       \
+  SetProc(p_Mult_nn, field, LengthGeneral, OrdGeneral);                 \
+  SetProc(pp_Mult_nn, field, length, OrdGeneral);                       \
+  SetProc(pp_Mult_mm, field, length, OrdGeneral);                       \
+  SetProc(p_Mult_mm, field, length, OrdGeneral);                        \
+  SetProc(p_Minus_mm_Mult_qq, field, length, ord);                      \
+  SetProc(pp_Mult_mm_Noether, field, length, ord);                      \
+  SetProc(p_Add_q, field, length, ord);                                 \
+  SetProc(p_Neg, field, LengthGeneral, OrdGeneral);                     \
+  SetProc(pp_Mult_Coeff_mm_DivSelect, field, length, OrdGeneral);       \
+  SetProc(pp_Mult_Coeff_mm_DivSelectMult, field, length, OrdGeneral);   \
+  SetProc(p_Merge_q, FieldGeneral, length, ord);                        \
+  SetProc(p_kBucketSetLm, field, length, ord);                          \
+}                                                                       \
+while (0)
+
+#ifdef NV_OPS
+#define SetProcs_nv(field, length, ord)                                 \
+do                                                                      \
+{                                                                       \
+  SetProc(p_Delete, field, LengthGeneral, OrdGeneral);                  \
+  SetProc(p_ShallowCopyDelete, FieldGeneral, length, OrdGeneral);       \
+  SetProc(p_Copy, field, length, OrdGeneral);                           \
+  SetProc(p_Add_q, field, length, ord);                                 \
+  SetProc(p_kBucketSetLm, field, length, ord);                          \
+  SetProc(p_Neg, field, LengthGeneral, OrdGeneral);                     \
+  SetProc(p_Merge_q, FieldGeneral, length, ord);                        \
+}                                                                       \
+while (0)
+#endif
+
+#endif // P_PROCS_IMPL_H
+
diff --git a/libpolys/polys/templates/p_Procs_Lib.cc b/libpolys/polys/templates/p_Procs_Lib.cc
new file mode 100644
index 0000000..cf7e85c
--- /dev/null
+++ b/libpolys/polys/templates/p_Procs_Lib.cc
@@ -0,0 +1,34 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    p_Procs_Lib.cc
+ *  Purpose: source for shared library of p_Procs
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 12/00
+ *******************************************************************/
+
+#ifdef DYNAMIC_VERSION
+#define LINKAGE extern "C"
+#else
+#define LINKAGE
+#endif
+
+
+
+
+#include <misc/auxiliary.h>
+
+#include <factory/factory.h>
+
+#include <polys/monomials/p_polys.h>
+#include <polys/monomials/ring.h>
+#include <polys/templates/p_Procs.h>
+#include <polys/templates/p_Numbers.h>
+#include <polys/templates/p_MemCmp.h>
+#include <polys/templates/p_MemAdd.h>
+#include <polys/templates/p_MemCopy.h>
+#include <polys/kbuckets.h>
+
+#include "templates/p_Procs.inc"
+
diff --git a/libpolys/polys/templates/p_Procs_Set.h b/libpolys/polys/templates/p_Procs_Set.h
new file mode 100644
index 0000000..e628678
--- /dev/null
+++ b/libpolys/polys/templates/p_Procs_Set.h
@@ -0,0 +1,211 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    p_Procs_Set.h
+ *  Purpose: Procedures for setting p_Procs at run time
+ *  Note:    this file is included by p_Procs_Dynamic/Static.cc
+ *           The macros
+ *              DoSetProc(what, field, length, ord)
+ *              InitSetProc(field, length ord)
+ *           have to be defined before this file is included
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 12/00
+ *******************************************************************/
+
+#include <reporter/reporter.h>
+
+// extract p_Procs properties from a ring
+static inline p_Field p_FieldIs(ring r)
+{
+  if (rField_is_Zp(r))
+    return FieldZp;
+  if (rField_is_R(r)) return FieldR;
+  if (rField_is_GF(r)) return FieldGF;
+  if (rField_is_Q(r)) return FieldQ;
+#ifdef HAVE_MORE_FIELDS_IMPLEMENTED
+  if (rField_is_long_R(r)) return FieldLong_R;
+  if (rField_is_long_C(r)) return FieldLong_C;
+  if (rField_is_Zp_a(r)) return FieldZp_a;
+  if (rField_is_Q_a(r)) return FieldQ_a;
+#endif
+#ifdef HAVE_RINGS
+  if (rField_is_Ring(r)) return RingGeneral;
+#endif
+  return FieldGeneral;
+}
+
+static inline p_Length p_LengthIs(ring r)
+{
+  assume(r->ExpL_Size > 0);
+  // here is a quick hack to take care of p_MemAddAdjust
+  if (r->NegWeightL_Offset != NULL) return LengthGeneral;
+  if (r->ExpL_Size == 1) return LengthOne;
+  if (r->ExpL_Size == 2) return LengthTwo;
+  if (r->ExpL_Size == 3) return LengthThree;
+  if (r->ExpL_Size == 4) return LengthFour;
+  if (r->ExpL_Size == 5) return LengthFive;
+  if (r->ExpL_Size == 6) return LengthSix;
+  if (r->ExpL_Size == 7) return LengthSeven;
+  if (r->ExpL_Size == 8) return LengthEight;
+  return LengthGeneral;
+}
+
+static inline int p_IsNomog(long* sgn, int l)
+{
+  int i;
+  for (i=0;i<l;i++)
+    if (sgn[i] > 0) return 0;
+
+  return 1;
+}
+
+static inline int p_IsPomog(long* sgn, int l)
+{
+  int i;
+  for (i=0;i<l;i++)
+    if (sgn[i] < 0) return 0;
+  return 1;
+}
+
+static inline p_Ord p_OrdIs(ring r)
+{
+  long* sgn = r->ordsgn;
+  long l = r->ExpL_Size;
+  int zero = 0;
+
+  if (sgn[l-1] == 0)
+  {
+    l--;
+    zero = 1;
+  }
+
+  // we always favour the pomog cases
+  if (p_IsPomog(sgn,l)) return (zero ? OrdPomogZero : OrdPomog);
+  if (p_IsNomog(sgn,l)) return (zero ? OrdNomogZero : OrdNomog);
+
+  assume(l > 1);
+
+  if (sgn[0] == -1 && p_IsPomog(&sgn[1], l-1))
+    return (zero ? OrdNegPomogZero : OrdNegPomog);
+  if (sgn[l-1] == -1 && p_IsPomog(sgn, l-1))
+    return (zero ? OrdPomogNegZero : OrdPomogNeg);
+
+  if (sgn[0] == 1 && p_IsNomog(&sgn[1], l-1))
+    return (zero ? OrdPosNomogZero : OrdPosNomog);
+  if (sgn[l-1] == 1 && p_IsNomog(sgn, l-1))
+    return (zero ? OrdNomogPosZero : OrdNomogPos);
+
+  assume(l > 2);
+
+  if (sgn[0] == 1 && sgn[1] == 1 && p_IsNomog(&sgn[2], l-2))
+    return (zero ? OrdPosPosNomogZero : OrdPosPosNomog);
+
+  if (sgn[0] == 1 && sgn[l-1] == 1 && p_IsNomog(&sgn[1], l-2))
+    return (zero ? OrdPosNomogPosZero : OrdPosNomogPos);
+
+  if (sgn[0] == -1 && sgn[1] == 1 && p_IsNomog(&sgn[2], l-2))
+    return (zero ? OrdNegPosNomogZero : OrdNegPosNomog);
+
+  return OrdGeneral;
+}
+
+// fields of this struct are set by DoSetProc
+static p_Procs_s *_p_procs;
+
+#ifdef RDEBUG
+// if set, then SetProcs sets only names, instead of functions
+static int set_names = 0;
+#endif
+
+// (which##_Proc_Ptr)F ->-> cast_vptr_to_A<which##_Proc_Ptr>(F)?
+#define CheckProc(which)                                    \
+do                                                          \
+{                                                           \
+  if (p_Procs->which == NULL)                               \
+  {                                                         \
+    dReportBug("p_Procs is NULL");                          \
+    WarnS("Singular will work properly, but much slower");  \
+    WarnS("If you chose a coef ring, it may not work at all");\
+    p_Procs->which =                 (which##_Proc_Ptr)(    \
+      which##__FieldGeneral_LengthGeneral_OrdGeneral);       \
+  }                                                         \
+}                                                           \
+while (0);
+
+void nc_p_ProcsSet(ring rGR, p_Procs_s* p_Procs);
+
+// Choose a set of p_Procs
+void p_ProcsSet(ring r, p_Procs_s* p_Procs)
+{
+  p_Field     field = p_FieldIs(r);
+  p_Length    length = p_LengthIs(r);
+  p_Ord       ord = p_OrdIs(r);
+
+  assume(p_Procs != NULL);
+  memset(p_Procs, 0, sizeof(p_Procs_s));
+  _p_procs = p_Procs;
+  assume(IsValidSpec(field, length, ord));
+
+  SetProcs(field, length, ord);
+  extern poly p_Mult_nn_pthread(poly p, const number n, const ring r);
+  #ifdef NV_OPS
+  if ((field==FieldZp) && (r->cf->ch>NV_MAX_PRIME))
+  {
+    // set all (mult/div.) routines to FieldGeneral-variants
+    SetProcs(FieldGeneral, length,ord); // p_Mult_nn, ...
+    // set all non-mult/div. routines to FieldZp-variants
+    SetProcs_nv(FieldZp, length,ord); // p_Delete, p_ShallowCopyDelete...
+  }
+  #endif
+  CheckProc(p_Copy);
+  CheckProc(p_Delete);
+  CheckProc(p_ShallowCopyDelete);
+  CheckProc(p_Mult_nn);
+  CheckProc(pp_Mult_nn);
+  CheckProc(pp_Mult_mm);
+  CheckProc(p_Mult_mm);
+  CheckProc(p_Minus_mm_Mult_qq);
+  CheckProc(pp_Mult_mm_Noether);
+  CheckProc(p_Add_q);
+  CheckProc(p_Neg);
+  CheckProc(pp_Mult_Coeff_mm_DivSelect);
+  CheckProc(pp_Mult_Coeff_mm_DivSelectMult);
+  CheckProc(p_Merge_q);
+  CheckProc(p_kBucketSetLm);
+
+/*
+  assume(p_Procs->pp_Mult_mm_Noether != pp_Mult_mm_Noether__FieldGeneral_LengthGeneral_OrdGeneral ||
+         p_Procs->p_Minus_mm_Mult_qq == p_Minus_mm_Mult_qq__FieldGeneral_LengthGeneral_OrdGeneral ||
+         r->OrdSgn == 1 || r->LexOrder);
+*/
+#ifdef HAVE_PLURAL
+#ifndef SING_NDEBUG
+  if (rIsPluralRing(r))
+  {
+    dReportError("Setting pProcs in p_ProcsSet (rDebugPrint!?)!!!");
+    nc_p_ProcsSet(r, _p_procs); // Setup non-commutative p_Procs table!
+  }
+#endif
+#endif
+}
+
+#ifdef RDEBUG
+void p_Debug_GetSpecNames(const ring r, const char* &field, const char* &length, const char* &ord)
+{
+  /*p_Field     e_field =*/ (void) p_FieldIs(r);
+  /*p_Length    e_length =*/ (void) p_LengthIs(r);
+  /*p_Ord       e_ord =*/ (void) p_OrdIs(r);
+
+  field  = p_FieldEnum_2_String(p_FieldIs(r));
+  length = p_LengthEnum_2_String(p_LengthIs(r));
+  ord    = p_OrdEnum_2_String(p_OrdIs(r));
+}
+
+void p_Debug_GetProcNames(const ring r, p_Procs_s* p_Procs)
+{
+  set_names = 1;
+  p_ProcsSet(r, p_Procs); // changes p_Procs!!!
+  set_names = 0;
+}
+#endif // RDEBUG
diff --git a/libpolys/polys/templates/p_Procs_Static.cc b/libpolys/polys/templates/p_Procs_Static.cc
new file mode 100644
index 0000000..63afdc2
--- /dev/null
+++ b/libpolys/polys/templates/p_Procs_Static.cc
@@ -0,0 +1,70 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    p_Procs_Static.cc
+ *  Purpose: source for static version of p_Procs
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 12/00
+ *******************************************************************/
+
+
+
+#include <misc/auxiliary.h>
+
+#include <factory/factory.h>
+
+// #include <polys/structs.h>
+#include <polys/monomials/ring.h>
+#include <polys/monomials/p_polys.h>
+#include <polys/templates/p_Procs.h>
+#include <polys/templates/p_Numbers.h>
+#include <polys/templates/p_MemCmp.h>
+#include <polys/templates/p_MemAdd.h>
+#include <polys/templates/p_MemCopy.h>
+#include <polys/kbuckets.h>
+#include <reporter/reporter.h>
+
+const BOOLEAN p_procs_dynamic = FALSE;
+
+#define LINKAGE
+
+#define p_Procs_Static
+#include "templates/p_Procs.inc"
+
+// include generated configuration
+#include "templates/p_Procs_Static.h"
+// include general p_Proc stuff
+#include "templates/p_Procs_Impl.h"
+
+// define DoSetProc and InitSetProcs
+// cast_A_to_B<what##_Proc_Ptr, what##_Proc_Ptr> ???
+//  _p_procs->what =            cast_vptr_to_A<what##_Proc_Ptr>( ???
+#define SetStaticProcFromArray(what, type, field, length, ord) \
+  _p_procs->what =            (what##_Proc_Ptr)( \
+    what##_Proc_##type [index(what##_Proc, field, length, ord)])
+
+#define SetStaticProcFromFuncsArray(what, field, length, ord) \
+  SetStaticProcFromArray(what, funcs, field, length, ord)
+
+#ifdef RDEBUG
+#define DoSetProc(what, field, length, ord)                     \
+do                                                              \
+{                                                               \
+  if (set_names)                                                \
+    SetStaticProcFromArray(what, names, field, length, ord);    \
+  else                                                          \
+    SetStaticProcFromFuncsArray(what, field, length, ord);      \
+}                                                               \
+while(0)
+#else
+#define DoSetProc SetStaticProcFromFuncsArray
+#endif
+
+// include routines for setting p_ProcsSet
+
+#include "templates/p_Procs_Set.h"
+
+
+
+
diff --git a/libpolys/polys/templates/p_Procs_Static.h b/libpolys/polys/templates/p_Procs_Static.h
new file mode 100644
index 0000000..bdd2fd9
--- /dev/null
+++ b/libpolys/polys/templates/p_Procs_Static.h
@@ -0,0 +1,53 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    p_Procs_Static.h
+ *  Purpose: Configuration for static p_Procs
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 12/00
+ *******************************************************************/
+
+#ifndef P_PROCS_STATIC_H
+#define P_PROCS_STATIC_H
+
+// Set HAVE_FAST_P_PROCS to:
+//   0 -- only FieldGeneral_LengthGeneral_OrdGeneral
+//   1 -- plus FieldZp_Length*_OrdGeneral procs
+//   2 -- plus FieldZp_Length*_Ord* procs
+//   3 -- plus FieldQ_Length*_Ord*
+//   4 -- plus FieldGeneral_Length*_OrdGeneral procs
+//   5 -- all Field*_Length*_Ord* procs
+#define HAVE_FAST_P_PROCS 5
+
+// Set HAVE_FAST_FIELD to:
+//   0 -- only FieldGeneral
+//   1 -- special cases for FieldZp
+//   2 -- plus special cases for FieldQ
+//   nothing else is implemented, yet
+#define HAVE_FAST_FIELD 2
+
+// Set HAVE_FAST_LENGTH to:
+//   0 -- only LengthGeneral
+//   1 -- special cases for length <= 1
+//   2 -- special cases for length <= 2
+//   3 -- special cases for length <= 4
+//   4 -- special cases for length <= 8
+#define HAVE_FAST_LENGTH 4
+
+// Set HAVE_FAST_ORD to:
+//  0  -- only OrdGeneral
+//  1  -- special for ords with n_min <= 1
+//  2  -- special for ords with n_min <= 2
+//  3  -- special ords for with n_min <= 3
+//  4  -- special for all ords
+#define HAVE_FAST_ORD 4
+
+// Set HAVE_FAST_ZERO_ORD to:
+//  0 -- no zero ords are considered
+//  1 -- only ZeroOrds for OrdPosNomogPosZero, OrdNomogPosZero, OrdPomogNegZero
+//  2 -- ZeroOrds for all
+#define HAVE_FAST_ZERO_ORD 2
+
+// on top of all this, see the StaticKernelFilter in p_Procs_Impl.h
+#endif
diff --git a/libpolys/polys/templates/p_ShallowCopyDelete__T.cc b/libpolys/polys/templates/p_ShallowCopyDelete__T.cc
new file mode 100644
index 0000000..657eeaa
--- /dev/null
+++ b/libpolys/polys/templates/p_ShallowCopyDelete__T.cc
@@ -0,0 +1,38 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    p_ShallowCopyDelete__Template.cc
+ *  Purpose: template for p_ShallowCopyDelete
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 8/00
+ *******************************************************************/
+
+/***************************************************************
+ *
+ * Destroys: p
+ * Assumes:  Monoms of p are from
+ * Returns:
+ ***************************************************************/
+LINKAGE poly p_ShallowCopyDelete__T(poly s_p, const ring r, omBin d_bin)
+{
+  spolyrec dp;
+  poly d_p = &dp;
+  poly h;
+
+  DECLARE_LENGTH(const unsigned long length = r->ExpL_Size);
+
+  while (s_p != NULL)
+  {
+    p_AllocBin(d_p->next, d_bin, r);
+    pIter(d_p);
+    pSetCoeff0(d_p, pGetCoeff(s_p));
+    h = s_p;
+    s_p =  pNext(s_p);
+    p_MemCopy__T(d_p->exp, h->exp, length);
+    p_FreeBinAddr(h, r);
+  }
+  pNext(d_p) = NULL;
+  return dp.next;
+}
+
diff --git a/libpolys/polys/templates/p_kBucketSetLm__T.cc b/libpolys/polys/templates/p_kBucketSetLm__T.cc
new file mode 100644
index 0000000..de7dee2
--- /dev/null
+++ b/libpolys/polys/templates/p_kBucketSetLm__T.cc
@@ -0,0 +1,183 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    p_KBucketSetLm__Template.cc
+ *  Purpose: template for setting the Lm of a bucket
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 12/00
+ *******************************************************************/
+#undef USE_COEF_BUCKETS
+#ifdef HAVE_COEF_BUCKETS
+#define USE_COEF_BUCKETS
+#endif
+
+#ifdef USE_COEF_BUCKETS
+#define MULTIPLY_BUCKET(B,I) do                                        \
+  { if (B->coef[I]!=NULL)                                              \
+    {                                                                  \
+      B->buckets[I]=p_Mult_q(B->buckets[I],B->coef[I],B->bucket_ring); \
+      B->coef[I]=NULL;                                                 \
+    }                                                                  \
+  } while(0)
+#else
+#define MULTIPLY_BUCKET(B,I)
+#endif
+#ifndef USE_COEF_BUCKETS
+LINKAGE void p_kBucketSetLm__T(kBucket_pt bucket)
+{
+  int j = 0;
+  poly lt;
+  ring r = bucket->bucket_ring;
+  assume(bucket->buckets[0] == NULL && bucket->buckets_length[0] == 0);
+  DECLARE_LENGTH(const unsigned long length = r->ExpL_Size);
+  DECLARE_ORDSGN(const long* ordsgn = r->ordsgn);
+  poly p;
+
+  do
+  {
+    j = 0;
+    for (int i = 1; i<=bucket->buckets_used; i++)
+    {
+      if (bucket->buckets[i] != NULL)
+      {
+        MULTIPLY_BUCKET(bucket,i);
+        p =  bucket->buckets[j];
+        if (j == 0)
+        {
+          if (p != NULL) goto Greater;
+          j = i;
+          goto Continue;
+        }
+        assume(p != NULL);
+        p_MemCmp__T(bucket->buckets[i]->exp, p->exp, length, ordsgn, goto Equal, goto Greater, goto Continue);
+
+        Greater:
+        {
+          if (n_IsZero__T(pGetCoeff(p), r))
+          {
+            n_Delete__T(&pGetCoeff(p), r);
+            pIter(bucket->buckets[j]);
+            p_FreeBinAddr(p, r);
+            (bucket->buckets_length[j])--;
+          }
+          j = i;
+          goto Continue;
+        }
+
+        Equal:
+        {
+          MULTIPLY_BUCKET(bucket,i);
+          number tn = pGetCoeff(p);
+          #if 0
+          pSetCoeff0(p, n_Add__T(pGetCoeff(bucket->buckets[i]), tn, r));
+          n_Delete__T(&tn, r);
+          #else
+          n_InpAdd__T(tn,pGetCoeff(bucket->buckets[i]), r);
+          pSetCoeff0(p, tn);
+          #endif
+          p = bucket->buckets[i];
+          pIter(bucket->buckets[i]);
+          n_Delete__T(&pGetCoeff(p), r);
+          p_FreeBinAddr(p, r);
+          (bucket->buckets_length[i])--;
+        }
+
+        Continue:;
+      }
+    }
+    p = bucket->buckets[j];
+    if (j > 0 && n_IsZero__T(pGetCoeff(p), r))
+    {
+      n_Delete__T(&pGetCoeff(p), r);
+      pIter(bucket->buckets[j]);
+      p_FreeBinAddr(p, r);
+      (bucket->buckets_length[j])--;
+      j = -1;
+    }
+  }
+  while (j < 0);
+
+  if (j == 0)
+  {
+    return;
+  }
+
+  assume(bucket->buckets[j] != NULL);
+  lt = bucket->buckets[j];
+  bucket->buckets[j] = pNext(lt);
+  bucket->buckets_length[j]--;
+  pNext(lt) = NULL;
+  bucket->buckets[0] = lt;
+  bucket->buckets_length[0] = 1;
+
+  kBucketAdjustBucketsUsed(bucket);
+}
+#else
+LINKAGE void p_kBucketSetLm__T(kBucket_pt bucket)
+{
+  //int j = 0;
+  poly lt;
+  ring r = bucket->bucket_ring;
+  assume((bucket->buckets[0] == NULL) && (bucket->buckets_length[0] == 0) && (bucket->coef[0]==0));
+  DECLARE_LENGTH(const unsigned long length = r->ExpL_Size);
+  DECLARE_ORDSGN(const long* ordsgn = r->ordsgn);
+  poly p=NULL;
+  while(p==NULL)
+  {
+    int found=-1000;
+    for (int i = 1; i<=bucket->buckets_used; i++)
+    {
+      if (bucket->buckets[i] != NULL)
+      {
+        if (p == NULL)
+        {
+          p=bucket->buckets[i];
+          found=i;
+          continue;
+        }
+        assume(p != NULL);
+        p_MemCmp__T(bucket->buckets[i]->exp, p->exp, length, ordsgn, goto Continue, goto Greater, goto Continue);
+        //assume(p_LmCmp(bucket->buckets[i],p,r)==1);
+        Greater:
+        //if (p_LmCmp(bucket->buckets[i],p,r)!=1) continue;
+        found=i;
+        p=bucket->buckets[i];
+        Continue:;
+      }
+    }
+    if (found<0) return;
+    assume(p==bucket->buckets[found]);
+    assume(p!=NULL);
+
+    p=kBucketExtractLmOfBucket(bucket, found);
+    assume(p!=NULL);
+    p_Test(p,r);
+    poly copy=p_LmInit(p, r);
+
+    for (int i = found+1; i<=bucket->buckets_used; i++)
+    {
+      if (bucket->buckets[i] != NULL)
+      {
+        if(p_LmEqual(bucket->buckets[i], copy,r))
+	{
+          poly q=kBucketExtractLmOfBucket(bucket,i);
+          assume(p!=q);
+          p=p_Add_q(p, q,r);
+          assume(pLength(bucket->buckets[i])==bucket->buckets_length[i]);
+        }
+      }
+    }
+    p_Delete(&copy, r);
+  }
+
+  //assume(bucket->buckets[j] != NULL);
+  assume(pLength(lt)==1);
+
+  bucket->buckets[0] = lt;
+  bucket->buckets_length[0] = 1;
+
+  kBucketAdjustBucketsUsed(bucket);
+  kbTest(bucket);
+}
+#endif
diff --git a/libpolys/polys/templates/pp_Mult_Coeff_mm_DivSelectMult__T.cc b/libpolys/polys/templates/pp_Mult_Coeff_mm_DivSelectMult__T.cc
new file mode 100644
index 0000000..f0313b8
--- /dev/null
+++ b/libpolys/polys/templates/pp_Mult_Coeff_mm_DivSelectMult__T.cc
@@ -0,0 +1,77 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    pp_Mult_Coeff_mm_DivSelectMult__Template.cc
+ *  Purpose: template for pp_Mult_Coeff_mm__DivSelectMult
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 8/00
+ *******************************************************************/
+
+/***************************************************************
+ *
+ *   Returns:  p*Coeff(m)*a/b for such monomials pm of p, for which
+ *             m is divisble by pm, shorter == #of monomials left out
+ *   Assumes:  m, a, b are monomials, ordering is (c, dp),
+ *            (p*a) is divisble by b for all monimials in question
+ *   Const:    p, m, a, b
+ *
+ ***************************************************************/
+LINKAGE poly pp_Mult_Coeff_mm_DivSelectMult__T(poly p,const poly m, const poly a, const poly b, int &shorter,const ring r)
+{
+  assume(rOrd_is_Comp_dp(r) && r->ExpL_Size > 2);
+  p_Test(p, r);
+  if (p == NULL) return NULL;
+  number n = pGetCoeff(m);
+  number nc;
+  pAssume(!n_IsZero__T(n,r));
+
+  spolyrec rp;
+  omBin bin = r->PolyBin;
+  const unsigned long bitmask = r->divmask;
+  const unsigned long* m_e = &(m->exp[2]);
+  DECLARE_LENGTH(const unsigned long length = r->ExpL_Size);
+  DECLARE_LENGTH_2(const unsigned long length_2 = length - 2);
+
+  poly ab;
+  p_AllocBin(ab, bin, r);
+  unsigned long* ab_e = &(ab->exp[0]);
+
+  p_MemDiff__T(ab_e, ((unsigned long*) &(a->exp[0])), ((unsigned long*) &(b->exp[0])),
+            length);
+
+  int Shorter = 0;
+  poly q = &rp;
+
+  do
+  {
+    p_MemCmp_Bitmask_2(m_e, &(p->exp[2]), bitmask, length_2,
+                       goto Divisible, goto NotDivisible);
+
+    NotDivisible:
+    pAssume(!p_LmDivisibleByNoComp(m, p, r));
+    Shorter++;
+    goto Iter;
+
+    Divisible:
+    pAssume(p_LmDivisibleByNoComp(m, p, r));
+    p_AllocBin(pNext(q), bin, r);
+    q = pNext(q);
+    nc = pGetCoeff(p);
+    pSetCoeff0(q, n_Mult__T(n, nc, r));
+    p_MemSum__T(q->exp, p->exp, ab_e, length);
+
+    Iter:
+    pIter(p);
+  }
+  while (p != NULL);
+
+  pNext(q) = NULL;
+  p_FreeBinAddr(ab, r);
+
+  shorter = Shorter;
+  p_Test(rp.next, r);
+  return rp.next;
+}
+
+
diff --git a/libpolys/polys/templates/pp_Mult_Coeff_mm_DivSelect__T.cc b/libpolys/polys/templates/pp_Mult_Coeff_mm_DivSelect__T.cc
new file mode 100644
index 0000000..616c9a8
--- /dev/null
+++ b/libpolys/polys/templates/pp_Mult_Coeff_mm_DivSelect__T.cc
@@ -0,0 +1,55 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    pp_Mult_Coeff_mm_DivSelect__Template.cc
+ *  Purpose: template for pp_Mult_Coeff_mm__DivSelect
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 8/00
+ *******************************************************************/
+
+/***************************************************************
+ *
+ *   Returns:  p*Coeff(m) for such monomials pm of p, for which
+ *             m is divisble by pm
+ *   Const:    p, m
+ *
+ ***************************************************************/
+LINKAGE poly pp_Mult_Coeff_mm_DivSelect__T(poly p, const poly m, int &shorter,
+                                        const ring r)
+{
+  number n = pGetCoeff(m);
+  pAssume(!n_IsZero__T(n,r));
+  p_Test(p, r);
+  if (p == NULL) return NULL;
+  spolyrec rp;
+  DECLARE_LENGTH(const unsigned long length = r->ExpL_Size);
+  int Shorter = 0;
+  poly q = &rp;
+  omBin bin = r->PolyBin;
+
+  do
+  {
+    if (p_LmDivisibleByNoComp(m, p, r))
+    {
+      p_AllocBin(pNext(q), bin, r);
+      q = pNext(q);
+      number nc = pGetCoeff(p);
+      pSetCoeff0(q, n_Mult__T(n, nc, r));
+      p_MemCopy__T(q->exp, p->exp, length);
+    }
+    else
+    {
+      Shorter++;
+    }
+    pIter(p);
+  }
+  while (p != NULL);
+  pNext(q) = NULL;
+
+  shorter = Shorter;
+  p_Test(rp.next, r);
+  return rp.next;
+}
+
+
diff --git a/libpolys/polys/templates/pp_Mult_mm_Noether__T.cc b/libpolys/polys/templates/pp_Mult_mm_Noether__T.cc
new file mode 100644
index 0000000..5d63d99
--- /dev/null
+++ b/libpolys/polys/templates/pp_Mult_mm_Noether__T.cc
@@ -0,0 +1,86 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    pp_Mult_mm__Template.cc
+ *  Purpose: template for p_Mult_n
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 8/00
+ *******************************************************************/
+
+/***************************************************************
+ *
+ *   Returns:  p*m, ll
+ *   ll == pLength(p*m) , if on input ll < 0
+ *   pLength(p) - pLength(p*m), if on input ll >= 0
+ *   Const:    p, m
+ *
+ ***************************************************************/
+LINKAGE poly pp_Mult_mm_Noether__T(poly p, const poly m, const poly spNoether, int &ll, const ring ri)
+{
+  p_Test(p, ri);
+  p_LmTest(m, ri);
+  assume(spNoether != NULL);
+  if (p == NULL)
+  {
+    ll = 0;
+    return NULL;
+  }
+  spolyrec rp;
+  poly q = &rp, r;
+  number n;
+  const unsigned long *spNoether_exp = spNoether->exp;
+  number ln = pGetCoeff(m);
+  omBin bin = ri->PolyBin;
+  DECLARE_LENGTH(const unsigned long length = ri->ExpL_Size);
+  DECLARE_ORDSGN(const long* ordsgn = ri->ordsgn);
+  const unsigned long* m_e = m->exp;
+  pAssume(!n_IsZero__T(ln,ri));
+  pAssume1(p_GetComp(m, ri) == 0 || p_MaxComp(p, ri) == 0);
+  int l = 0;
+
+  do
+  {
+    p_AllocBin(r, bin, ri);
+    p_MemSum__T(r->exp, p->exp, m_e, length);
+    p_MemAddAdjust__T(r, ri);
+
+    p_MemCmp__T(r->exp, spNoether_exp, length, ordsgn, goto Continue, goto Continue, goto Break);
+
+    Break:
+    p_FreeBinAddr(r, ri);
+    break;
+
+    Continue:
+
+    n = n_Mult__T(ln, pGetCoeff(p), ri);
+
+    #ifdef HAVE_RINGS
+    if(n_IsZero__T(n, ri))
+    {
+      n_Delete__T(&n, ri);
+      p_FreeBinAddr(r, ri);
+    } else
+    #endif
+    {
+      l++;
+      q = pNext(q) = r;
+      pSetCoeff0(q, n);
+    }
+
+    pIter(p);
+
+  } while (p != NULL);
+
+  if (ll < 0)
+    ll = l;
+  else
+    ll = pLength(p);
+
+  pNext(q) = NULL;
+
+  p_Test(pNext(&rp), ri);
+  return pNext(&rp);
+}
+
+
diff --git a/libpolys/polys/templates/pp_Mult_mm__T.cc b/libpolys/polys/templates/pp_Mult_mm__T.cc
new file mode 100644
index 0000000..e9fe7fa
--- /dev/null
+++ b/libpolys/polys/templates/pp_Mult_mm__T.cc
@@ -0,0 +1,63 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    pp_Mult_mm__Template.cc
+ *  Purpose: template for p_Mult_n
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 8/00
+ *******************************************************************/
+
+/***************************************************************
+ *
+ *   Returns:  p*m
+ *   Const:    p, m
+ *
+ ***************************************************************/
+LINKAGE poly pp_Mult_mm__T(poly p, const poly m, const ring ri)
+{
+  p_Test(p, ri);
+  p_LmTest(m, ri);
+  if (p == NULL)
+  {
+    return NULL;
+  }
+  spolyrec rp;
+#ifdef HAVE_ZERODIVISORS
+  rp.next = NULL;
+#endif
+  poly q = &rp;
+  number ln = pGetCoeff(m);
+  omBin bin = ri->PolyBin;
+  DECLARE_LENGTH(const unsigned long length = ri->ExpL_Size);
+  const unsigned long* m_e = m->exp;
+  pAssume(!n_IsZero__T(ln,ri));
+  pAssume1(p_GetComp(m, ri) == 0 || p_MaxComp(p, ri) == 0);
+  number tmp;
+
+  do
+  {
+    tmp = n_Mult__T(ln, pGetCoeff(p), ri);
+#ifdef HAVE_ZERODIVISORS
+    if (! n_IsZero__T(tmp, ri))
+    {
+#endif
+      p_AllocBin( pNext(q), bin, ri);
+      q = pNext(q);
+      pSetCoeff0(q, tmp);
+      p_MemSum__T(q->exp, p->exp, m_e, length);
+      p_MemAddAdjust__T(q, ri);
+#ifdef HAVE_ZERODIVISORS
+    }
+    else n_Delete__T(&tmp, ri);
+#endif
+    p = pNext(p);
+  }
+  while (p != NULL);
+  pNext(q) = NULL;
+
+  p_Test(pNext(&rp), ri);
+  return pNext(&rp);
+}
+
+
diff --git a/libpolys/polys/templates/pp_Mult_nn__T.cc b/libpolys/polys/templates/pp_Mult_nn__T.cc
new file mode 100644
index 0000000..1f10458
--- /dev/null
+++ b/libpolys/polys/templates/pp_Mult_nn__T.cc
@@ -0,0 +1,60 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    pp_Mult_nn__Template.cc
+ *  Purpose: template for pp_Mult_nn
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 8/00
+ *******************************************************************/
+
+/***************************************************************
+ *
+ *   Returns:  p*n
+ *   Const:    p, n
+ *
+ ***************************************************************/
+LINKAGE poly pp_Mult_nn__T(poly p, const number n, const ring r)
+{
+  pAssume(!n_IsZero__T(n,r));
+  p_Test(p, r);
+  if (p == NULL) return NULL;
+  spolyrec rp;
+#ifdef HAVE_ZERODIVISORS
+  rp.next = NULL;
+#endif
+  poly q = &rp;
+  omBin bin = r->PolyBin;
+  DECLARE_LENGTH(const unsigned long length = r->ExpL_Size);
+
+  do
+  {
+#ifndef HAVE_ZERODIVISORS
+    p_AllocBin(pNext(q), bin, r);
+    pIter(q);
+    number nc = pGetCoeff(p);
+    pSetCoeff0(q, n_Mult__T(n, nc, r));
+    p_MemCopy__T(q->exp, p->exp, length);
+#else
+    number nc = pGetCoeff(p);
+    number tmp = n_Mult__T(n, nc, r);
+    if (! n_IsZero__T(tmp,r))
+    {
+      p_AllocBin(pNext(q), bin, r);
+      pIter(q);
+      pSetCoeff0(q, tmp);
+      p_MemCopy__T(q->exp, p->exp, length);
+    }
+    else
+      n_Delete__T(&tmp,r);
+#endif
+    pIter(p);
+  }
+  while (p != NULL);
+  pNext(q) = NULL;
+
+  p_Test(rp.next, r);
+  return rp.next;
+}
+
+
diff --git a/libpolys/polys/test.cc b/libpolys/polys/test.cc
new file mode 100644
index 0000000..7a84bc4
--- /dev/null
+++ b/libpolys/polys/test.cc
@@ -0,0 +1,429 @@
+#include <iostream>
+#include <fstream>
+#include <sstream>
+#include <string.h>
+
+#include <misc/auxiliary.h>
+#include <omalloc/omalloc.h>
+
+#include <coeffs/coeffs.h>
+#include <coeffs/numbers.h>
+
+#include <reporter/reporter.h>
+#include <resources/feResource.h>
+
+#ifndef PLURAL_INTERNAL_DECLARATIONS
+#define PLURAL_INTERNAL_DECLARATIONS
+#endif
+
+#ifndef PLURAL_INTERNAL_DECLARATIONS_GB_HACK
+#define PLURAL_INTERNAL_DECLARATIONS_GB_HACK
+#endif
+
+#ifndef TRANSEXT_PRIVATES
+#define TRANSEXT_PRIVATES
+#endif
+
+#include <polys/nc/gb_hack.h>
+
+#include <polys/monomials/ring.h>
+#include <polys/monomials/p_polys.h>
+
+#include <polys/simpleideals.h>
+
+#include <polys/ext_fields/algext.h>
+#include <polys/ext_fields/transext.h>
+
+#pragma GCC diagnostic ignored "-Wwrite-strings"
+
+#define  TS_ASSERT(a) assume(a)
+#define  TS_ASSERT_EQUALS(a, b) assume( a == b )
+#define  TS_ASSERT_DIFFERS(a, b) assume( a != b )
+#define  TS_FAIL(a) WerrorS(a)
+
+
+namespace
+{
+  static inline std::ostream& operator<< (std::ostream& o, const n_coeffType& type)
+  {
+#define CASE(A) case A: return o << (" " # A) << " ";
+    switch( type )
+    {
+      CASE(n_unknown);
+      CASE(n_Zp);
+      CASE(n_Q);
+      CASE(n_R);
+      CASE(n_GF);
+      CASE(n_long_R);
+      CASE(n_algExt);
+      CASE(n_transExt);
+      CASE(n_long_C);
+      CASE(n_Z);
+      CASE(n_Zn);
+      CASE(n_Znm);
+      CASE(n_Z2m);
+      CASE(n_CF);
+      default: return o << "Unknown type: [" << (const unsigned long) type << "]";
+    }
+#undef CASE
+    return o;
+  }
+
+  template<typename T>
+      static inline std::string _2S(T i)
+  {
+    std::stringstream ss;
+    ss << i;
+//    std::string s = ss.str();
+    return ss.str();
+  }
+
+
+  static inline std::string _2S(number a, const coeffs r)
+  {
+    n_Test(a,r);
+    StringSetS("");
+    n_Write(a, r);
+
+    std::stringstream ss;
+    {
+      char* s = StringEndS();  ss << s; omFree(s);
+    }
+
+    return ss.str();
+
+  }
+
+  static inline void PrintSized(/*const*/ number a, const coeffs r, BOOLEAN eoln = TRUE)
+  {
+    std::clog << _2S(a, r) << ", of size: " << n_Size(a, r);
+
+    if( eoln )
+      std::clog << std::endl;
+  }
+
+
+
+}
+
+using namespace std;
+
+
+
+
+void PrintRing(const ring r)
+  {
+    rWrite(r); PrintLn();
+  #ifdef  RDEBUG
+    rDebugPrint(r); PrintLn();
+  #endif
+  }
+
+
+  static inline std::string _2S(poly a, const ring r)
+  {
+    p_Test(a,r);
+
+    StringSetS("");
+    p_Write(a, r);
+
+    std::stringstream ss;
+    {
+      char* s = StringEndS();  ss << s; omFree(s);
+    }
+
+    return ss.str();
+  }
+
+  static inline void PrintSized(/*const*/ poly a, const ring r, BOOLEAN eoln = TRUE)
+  {
+    std::clog << _2S(a, r) << ", of size: " << p_Size(a, r);
+
+    if( eoln )
+      std::clog << std::endl;
+  }
+
+static inline void Delete(poly &p, const ring r)
+{
+  if( p != NULL )
+    p_Delete(&p, r);
+
+  p = NULL;
+}
+
+void TestSum(const ring r, const int N)
+{
+  TS_ASSERT_DIFFERS( r    , NULLp);
+  TS_ASSERT_DIFFERS( r->cf, NULLp);
+
+
+  clog << ( _2S("TEST: sum[0..") + _2S(N) + "]: ");
+  clog << endl;
+
+  assume( N > 0 ); // just for now...
+
+  const int ssss = (N * (N+1)) / 2;
+
+  poly sum1 = p_ISet(ssss, r);
+  clog<< "poly(N*(N+1)/2) (int: " << ssss << "): "; PrintSized(sum1, r);
+
+  poly s=NULL, ss=NULL, i=NULL, res=NULL;
+
+  s = p_ISet(N  , r);
+  i = p_ISet(N+1, r);
+
+  i = p_Mult_q(s, i, r); s = NULL;
+
+  clog<< "poly(N)*poly(N+1): (int: "<< N*(N+1) << "): "; PrintSized(i, r);
+
+  number t = n_Init(2, r->cf);
+  clog<< "number(2): "; PrintSized(t, r->cf);
+
+  if( !n_IsZero( t, r->cf) )
+  {
+    if( i != NULL )
+    {
+      number ii = p_GetCoeff(i, r);
+      clog<< "number(poly(N)*poly(N+1)): "; PrintSized(ii, r->cf);
+
+#ifdef HAVE_RINGS
+      TS_ASSERT( n_DivBy(ii, t, r->cf) );
+#endif
+       res = p_Div_nn(i, t, r); i = NULL;
+    }
+
+
+
+    clog<< "(poly(N)*poly(N+1))/number(2): "; PrintSized(res, r);
+    poly d = p_Sub(p_Copy(res, r), p_Copy(sum1, r), r);
+
+    if( d != NULL )
+      TS_ASSERT( n_IsZeroDivisor(p_GetCoeff(d, r), r->cf) );
+
+    Delete(d, r);
+
+    if( n_GetChar(r->cf) == 0 )
+    {
+      TS_ASSERT( p_EqualPolys(sum1, res, r) );
+      TS_ASSERT( p_EqualPolys(res, sum1, r) );
+    }
+  } else
+    TS_ASSERT_EQUALS( n_GetChar(r->cf), 2);
+
+  n_Delete(&t, r->cf);
+
+
+  s = NULL;
+  ss = NULL;
+  for( int k = N; k >= 0; k-- )
+  {
+    i = p_ISet(k, r);
+    s = p_Add_q(s, i, r); // s += i
+
+    i = p_Neg( p_ISet(k, r), r );
+    ss = p_Add_q(ss, i, r); // ss -= i
+  }
+
+  clog<< "ss(-sum): "; PrintSized(ss, r);
+
+  ss = p_Neg(ss, r); // ss = -ss
+
+  clog<< "real sum    : "; PrintSized(s, r);
+  clog<< "real sum(--): "; PrintSized(ss, r);
+
+  TS_ASSERT( p_EqualPolys(s, ss, r) );
+  TS_ASSERT( p_EqualPolys(ss, s, r) );
+
+//   TODO(somebody, fix the delete method!);
+
+  Delete(sum1, r);
+  Delete(res, r);
+
+  Delete(s, r);
+  Delete(ss, r);
+
+  clog << ( " >>> TEST DONE!" );
+  clog << endl;
+
+}
+
+void Test(const ring r)
+{
+  if( r == NULL )
+      TS_FAIL("Could not get needed ring");
+  else
+  {
+    TestSum( r, 10 );
+    TestSum( r, 100 );
+    TestSum( r, 101 );
+    TestSum( r, 1001 );
+    TestSum( r, 9000 );
+  }
+}
+
+  void test_Z13_t()
+  {
+    cout << "Creating  Z/13[t]: " << endl;
+
+    char* n[] = {(char*)"t"};
+    ring r = rDefault( 13, 1, n);
+    TS_ASSERT_DIFFERS( r, NULLp );
+
+    PrintRing(r);
+
+    TS_ASSERT( rField_is_Domain(r) );
+    TS_ASSERT( !rField_is_Q(r) );
+
+    TS_ASSERT( rField_is_Zp(r) );
+    TS_ASSERT( !rField_is_Zp(r, 11) );
+    TS_ASSERT( rField_is_Zp(r, 13) );
+
+    TS_ASSERT_EQUALS( rVar(r), 1);
+
+    Test(r);
+
+    rDelete(r);
+  }
+
+  void test_QQ_t()
+  {
+    cout << "Creating  Q[s]: " << endl;
+
+    char* n[] = {(char*)"s"};
+    ring r = rDefault( 0, 1, n);
+    TS_ASSERT_DIFFERS( r, NULLp );
+
+    PrintRing(r);
+
+    TS_ASSERT( rField_is_Domain(r) );
+    TS_ASSERT( rField_is_Q(r) );
+
+    TS_ASSERT( !rField_is_Zp(r) );
+    TS_ASSERT( !rField_is_Zp(r, 11) );
+
+    TS_ASSERT_EQUALS( rVar(r), 1);
+
+    Test(r);
+
+    rDelete(r);
+  }
+
+  void test_Z11_x_y_z()
+  {
+     cout << "Creating  Z/11[x, y, z]: " << endl;
+
+     char* n[] = {(char*)"x", (char*)"y", (char*)"z"};
+     ring r = rDefault( 11, 3, n);
+     TS_ASSERT_DIFFERS( r, NULLp );
+
+     PrintRing(r);
+
+     TS_ASSERT( rField_is_Domain(r) );
+     TS_ASSERT( !rField_is_Q(r) );
+
+     TS_ASSERT( rField_is_Zp(r) );
+     TS_ASSERT( rField_is_Zp(r, 11) );
+     TS_ASSERT( !rField_is_Zp(r, 13) );
+
+     TS_ASSERT_EQUALS( rVar(r), 3);
+
+     Test(r);
+
+     rDelete(r);
+  }
+   void test_QQ_x_y_z()
+   {
+     cout << "Creating  QQ[x, y, z, u]: " << endl;
+
+     char* n[] = {(char*)"x", (char*)"y", (char*)"z", (char*)"u"};
+     ring r = rDefault( 0, 4, n);
+     TS_ASSERT_DIFFERS( r, NULLp );
+
+     PrintRing(r);
+
+     TS_ASSERT( rField_is_Domain(r) );
+     TS_ASSERT( rField_is_Q(r) );
+
+     TS_ASSERT( !rField_is_Zp(r) );
+     TS_ASSERT( !rField_is_Zp(r, 11) );
+
+     TS_ASSERT_EQUALS( rVar(r), 4);
+
+     Test(r);
+
+     rDelete(r);
+   }
+
+
+   void test_Z13_t_GF()
+   {
+     cout << "Creating  GF[t]: " << endl;
+
+     char* n[] = {(char*)"t"};
+
+     GFInfo param;
+
+     param.GFChar= 5;
+     param.GFDegree= 2;
+     param.GFPar_name= (const char*)"Q";
+
+     const coeffs cf = nInitChar( n_GF, &param );
+
+     if( cf == NULL )
+       TS_FAIL("Could not get needed coeff. domain");
+
+     TS_ASSERT_DIFFERS( cf, NULLp );
+
+     ring r = rDefault( cf, 1, n);  // now cf belongs to r!
+     TS_ASSERT_DIFFERS( r, NULLp );
+
+     PrintRing(r);
+
+     TS_ASSERT( rField_is_Domain(r) );
+     TS_ASSERT( !rField_is_Q(r) );
+
+     TS_ASSERT( !rField_is_Zp(r) );
+     TS_ASSERT( !rField_is_Zp(r, 11) );
+     TS_ASSERT( !rField_is_Zp(r, 13) );
+     TS_ASSERT( rField_is_GF(r) );
+
+     TS_ASSERT( rField_is_GF(r, 5) );
+     TS_ASSERT( !rField_is_GF(r, 25) );
+
+     TS_ASSERT_EQUALS( rVar(r), 1);
+
+     Test(r);
+
+     rDelete(r); // kills 'cf' as well!
+   }
+
+
+int main( int, char *argv[] )
+{
+  assume( sizeof(long) == SIZEOF_LONG );
+
+  if( sizeof(long) != SIZEOF_LONG )
+  {
+    WerrorS("Bad config.h: wrong size of long!");
+
+    return(1);
+  }
+
+
+  feInitResources(argv[0]);
+
+  StringSetS("ressources in use (as reported by feStringAppendResources(0):\n");
+  feStringAppendResources(0);
+  PrintLn();
+
+  { char* s = StringEndS(); PrintS(s); omFree(s); }
+
+
+   test_Z13_t();
+   test_QQ_t();
+   test_Z11_x_y_z();
+   test_QQ_x_y_z();
+   test_Z13_t_GF();
+
+   return 0;
+}
diff --git a/libpolys/polys/weight.cc b/libpolys/polys/weight.cc
new file mode 100644
index 0000000..9df02df
--- /dev/null
+++ b/libpolys/polys/weight.cc
@@ -0,0 +1,272 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+
+/*
+* ABSTRACT:
+*/
+
+
+
+
+
+#include <misc/auxiliary.h>
+
+#include <omalloc/omalloc.h>
+
+#include <misc/options.h>
+#include <misc/intvec.h>
+
+#include <polys/monomials/ring.h>
+#include <polys/monomials/p_polys.h>
+
+#include <polys/weight.h>
+
+#include <math.h>
+
+/*0 implementation*/
+extern "C" double (*wFunctional)(int *degw, int *lpol, int npol,
+       double *rel, double wx, double wNsqr);
+extern "C" double wFunctionalMora(int *degw, int *lpol, int npol,
+       double *rel, double wx, double wNsqr);
+extern "C" double wFunctionalBuch(int *degw, int *lpol, int npol,
+       double *rel, double wx, double wNsqr);
+extern "C" void wAdd(int *A, int mons, int kn, int xx, int rvar);
+extern "C" void wNorm(int *degw, int *lpol, int npol, double *rel);
+extern "C" void wFirstSearch(int *A, int *x, int mons,
+        int *lpol, int npol, double *rel, double *fopt, double wNsqr, int rvar);
+extern "C" void wSecondSearch(int *A, int *x, int *lpol,
+        int npol, int mons, double *rel, double *fk, double wNsqr, int rvar);
+extern "C" void wGcd(int *x, int n);
+
+static void wDimensions(poly* s, int sl, int *lpol, int *npol, int *mons)
+{
+  int  i, i1, j, k;
+  poly p, q;
+
+  i1 = j = 0;
+  for (i = 0; i <= sl; i++)
+  {
+    p = s[i];
+    if (p!=NULL)
+    {
+      k = 1;
+      q = pNext(p);
+      while (q!=NULL)
+      {
+        k++;
+        q = pNext(q);
+      }
+      if (k > 1)
+      {
+        lpol[i1++] = k;
+        j += k;
+      }
+    }
+  }
+  *npol = i1;
+  *mons = j;
+}
+
+
+static void wInit(poly* s, int sl, int mons, int *A, const ring R)
+{
+  int  n, a, i, j, *B, *C;
+  poly p, q;
+  int *pl;
+
+  B = A;
+  n = rVar(R);
+  a = (n + 1) * sizeof(int);
+  pl = (int *)omAlloc(a);
+  for (i = 0; i <= sl; i++)
+  {
+    p = s[i];
+    if (p!=NULL)
+    {
+      q = pNext(p);
+      if (q!=NULL)
+      {
+        C = B;
+        B++;
+        p_GetExpV(p, pl,R);
+        for (j = 0; j < n; j++)
+        {
+          *C = pl[j+1];
+          C += mons;
+        }
+      }
+      while (q!=NULL)
+      {
+        C = B;
+        B++;
+        p_GetExpV(q, pl,R);
+        for (j = 0; j < n; j++)
+        {
+          *C = pl[j+1];
+          C += mons;
+        }
+        pIter(q);
+      }
+    }
+  }
+  omFreeSize((ADDRESS)pl, a);
+}
+
+void wCall(poly* s, int sl, int *x, double wNsqr, const ring R)
+{
+  int  n, q, npol, mons, i;
+  int  *A, *xopt, *lpol, *degw;
+  double  f1, fx, eps, *rel;
+  void *adr;
+
+  n = rVar(R);
+  lpol = (int * )omAlloc((sl + 1) * sizeof(int));
+  wDimensions(s, sl, lpol, &npol, &mons);
+  xopt = x + (n + 1);
+  for (i = n; i!=0; i--)
+    xopt[i] = 1;
+  if (mons==0)
+  {
+    omFreeSize((ADDRESS)lpol, (sl + 1) * sizeof(int));
+    return;
+  }
+  adr = (void * )omAllocAligned(npol * sizeof(double));
+  rel = (double*)adr;
+  q = (n + 1) * mons * sizeof(int);
+  A = (int * )omAlloc(q);
+  wInit(s, sl, mons, A, R);
+  degw = A + (n * mons);
+  memset(degw, 0, mons * sizeof(int));
+  for (i = n; i!=0; i--)
+    wAdd(A, mons, i, 1, rVar(R));
+  wNorm(degw, lpol, npol, rel);
+  f1 = (*wFunctional)(degw, lpol, npol, rel, (double)1.0, wNsqr);
+  if (TEST_OPT_PROT) Print("// %e\n",f1);
+  eps = f1;
+  fx = (double)2.0 * eps;
+  memset(x, 0, (n + 1) * sizeof(int));
+  wFirstSearch(A, x, mons, lpol, npol, rel, &fx, wNsqr, rVar(R));
+  if (TEST_OPT_PROT) Print("// %e\n",fx);
+  memcpy(x + 1, xopt + 1, n * sizeof(int));
+  memset(degw, 0, mons * sizeof(int));
+  for (i = n; i!=0; i--)
+  {
+    x[i] *= 16;
+    wAdd(A, mons, i, x[i], rVar(R));
+  }
+  wSecondSearch(A, x, lpol, npol, mons, rel, &fx, wNsqr, rVar(R));
+  if (TEST_OPT_PROT) Print("// %e\n",fx);
+  if (fx >= eps)
+  {
+    for (i = n; i!=0; i--)
+      xopt[i] = 1;
+  }
+  else
+  {
+    wGcd(xopt, n);
+//    if (BTEST1(22))
+//    {
+//      f1 = fx + (double)0.1 * (f1 - fx);
+//      wSimple(x, n);
+//      memset(degw, 0, mons * sizeof(int));
+//      for (i = n; i!=0; i--)
+//        wAdd(A, mons, i, x[i], rVar(R));
+//      eps = wPrWeight(x, n);
+//      fx = (*wFunctional)(degw, lpol, npol, rel, eps);
+//      if (fx < f1)
+//      {
+//        if (TEST_OPT_PROT) Print("// %e\n",fx);
+//        memcpy(xopt + 1, x + 1, n * sizeof(int));
+//      }
+//    }
+  }
+  omFreeSize((ADDRESS)A, q);
+  omFreeSize((ADDRESS)lpol, (sl + 1) * sizeof(int));
+  omFreeSize((ADDRESS)adr, npol * sizeof(double));
+}
+
+
+void kEcartWeights(poly* s, int sl, short *eweight, const ring R)
+{
+  int  n, i;
+  int  *x;
+
+  *eweight = 0;
+  n = rVar(R);
+  if (rHasLocalOrMixedOrdering(R))
+    wFunctional = wFunctionalMora;
+  else
+    wFunctional = wFunctionalBuch;
+  x = (int * )omAlloc(2 * (n + 1) * sizeof(int));
+  wCall(s, sl, x, (double)2.0 / (double)n, R);
+  for (i = n; i!=0; i--)
+    eweight[i] = x[i + n + 1];
+  omFreeSize((ADDRESS)x, 2 * (n + 1) * sizeof(int));
+}
+
+short * iv2array(intvec * iv, const ring R)
+{
+  short *s=(short *)omAlloc0((rVar(R)+1)*sizeof(short));
+  int len=0;
+  if(iv!=NULL)
+    len=si_min(iv->length(),rVar(R)); // usually: rVar(R)==length()
+  int i;
+  //for(i=pVariables;i>len;i--) s[i]=1;
+  for(i=len;i>0;i--)               s[i]=(*iv)[i-1];
+  return s;
+}
+
+/*2
+*computes the degree of the leading term of the polynomial
+*with respect to given ecartWeights
+*used for Graebes method if BTEST1(31) is set
+*/
+long totaldegreeWecart(poly p, ring r)
+{
+  int i;
+  long j =0;
+
+  for (i=rVar(r); i>0; i--)
+    j += (int)(p_GetExp(p,i,r) * ecartWeights[i]);
+  return  j;
+}
+
+/*2
+*computes the degree of the leading term of the polynomial
+*with respect to given weights
+*/
+long totaldegreeWecart_IV(poly p, ring r, const short *w)
+{
+  int i;
+  long j =0;
+
+  for (i=rVar(r); i>0; i--)
+    j += (long)((int)(p_GetExp(p,i,r) * w[i]));
+  return  j;
+}
+
+/*2
+*computes the maximal degree of all terms of the polynomial
+*with respect to given ecartWeights and
+*computes the length of the polynomial
+*used for Graebes method if BTEST1(31) is set
+*/
+long maxdegreeWecart(poly p,int *l, ring r)
+{
+  short k=p_GetComp(p, r);
+  int ll=1;
+  long t,max;
+
+  max=totaldegreeWecart(p, r);
+  pIter(p);
+  while ((p!=NULL) && (p_GetComp(p, r)==k))
+  {
+    t=totaldegreeWecart(p, r);
+    if (t>max) max=t;
+    ll++;
+    pIter(p);
+  }
+  *l=ll;
+  return max;
+}
diff --git a/libpolys/polys/weight.h b/libpolys/polys/weight.h
new file mode 100644
index 0000000..744a105
--- /dev/null
+++ b/libpolys/polys/weight.h
@@ -0,0 +1,33 @@
+#ifndef WEIGHT_H
+#define WEIGHT_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT
+*/
+
+#include <polys/monomials/ring.h>
+
+extern short * ecartWeights;
+//extern pFDegProc pFDegOld;
+//extern pLDegProc pLDegOld;
+
+void kEcartWeights(poly* s, int sl, short *eweight, const ring R);
+//BOOLEAN kWeight(leftv res,leftv id);
+//BOOLEAN kQHWeight(leftv res,leftv v);
+long maxdegreeWecart(poly p,int *l, ring r);
+long totaldegreeWecart(poly p, ring r);
+long totaldegreeWecart_IV(poly p, ring r, const short *w);
+
+short * iv2array(intvec * iv, const ring R);
+
+// internal:
+extern "C" double (*wFunctional)(int *degw, int *lpol, int npol,
+       double *rel, double wx, double wNsqr);
+extern "C" double wFunctionalBuch(int *degw, int *lpol, int npol,
+       double *rel, double wx, double wNsqr);
+void wCall(poly* s, int sl, int *x, double wNsqr, const ring R);
+
+#endif
+
diff --git a/libpolys/polys/weight0.c b/libpolys/polys/weight0.c
new file mode 100644
index 0000000..c49c3fe
--- /dev/null
+++ b/libpolys/polys/weight0.c
@@ -0,0 +1,487 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+
+/*
+* ABSTRACT:
+*/
+
+
+
+
+
+#include <misc/auxiliary.h>
+#include <omalloc/omalloc.h>
+
+#include <math.h>
+#include <string.h>
+
+double wFunctionalMora(int *degw, int *lpol, int npol,
+       double *rel, double wx, double wwNsqr);
+double wFunctionalBuch(int *degw, int *lpol, int npol,
+       double *rel, double wx, double wwNsqr);
+void wAdd(int *A, int mons, int kn, int xx, int rvar);
+void wNorm(int *degw, int *lpol, int npol, double *rel);
+void wFirstSearch(int *A, int *x, int mons,
+        int *lpol, int npol, double *rel, double *fopt, double wNsqr, int rvar);
+void wSecondSearch(int *A, int *x, int *lpol,
+        int npol, int mons, double *rel, double *fk, double wNsqr, int rvar);
+void wGcd(int *x, int n);
+/*0 implementation*/
+
+short * ecartWeights=NULL;
+
+double (*wFunctional)(int *degw, int *lpol, int npol,
+       double *rel, double wx, double wNsqr);
+
+
+double wFunctionalMora(int *degw, int *lpol, int npol,
+       double *rel, double wx, double wNsqr)
+{
+  int  i, j, e1, ecu, ecl, ec;
+  int  *ex;
+  double gfmax, gecart, ghom, pfmax;
+  double *r;
+
+  ex = degw;
+  r = rel;
+  gfmax = (double)0.0;
+  gecart = (double)0.4 + (double)npol;
+  ghom = (double)1.0;
+  for (i = 0; i < npol; i++)
+  {
+    ecl = ecu = e1 = *ex++;
+    for (j = lpol[i] - 1; j!=0; j--)
+    {
+      ec = *ex++;
+      if (ec > ecu)
+        ecu = ec;
+      else if (ec < ecl)
+        ecl = ec;
+    }
+    pfmax = (double)ecl / (double)ecu;
+    if (pfmax < ghom)
+      ghom = pfmax;
+    pfmax = (double)e1 / (double)ecu;
+    if (pfmax > (double)0.5)
+      gecart -= (pfmax * pfmax);
+    else
+      gecart -= (double)0.25;
+    ecu = 2 * ecu - ecl;
+    gfmax += (double)(ecu * ecu) * (*r++);
+  }
+  if (ghom > (double)0.8)
+  {
+    ghom *= (double)5.0;
+    gecart *= ((double)5.0 - ghom);
+  }
+  return (gfmax * gecart) / pow(wx, wNsqr);
+}
+
+
+double wFunctionalBuch(int *degw, int *lpol, int npol,
+       double *rel, double wx, double wNsqr)
+{
+  int  i, j, ecl, ecu, ec;
+  int  *ex;
+  double gfmax, ghom, pfmax;
+  double *r;
+
+  ex = degw;
+  r = rel;
+  gfmax = (double)0.0;
+  ghom = (double)1.0;
+  for (i = 0; i < npol; i++)
+  {
+    ecu = ecl = *ex++;
+    for (j = lpol[i] - 1; j!=0 ; j--)
+    {
+      ec = *ex++;
+      if (ec < ecl)
+        ecl = ec;
+      else if (ec > ecu)
+        ecu = ec;
+    }
+    pfmax = (double)ecl / (double)ecu;
+    if (pfmax < ghom)
+      ghom = pfmax;
+    gfmax += (double)(ecu * ecu) * (*r++);
+  }
+  if (ghom > (double)0.5)
+    gfmax *= ((double)1.0 - (ghom * ghom)) / (double)0.75;
+  return gfmax / pow(wx, wNsqr);
+}
+
+
+static void wSub(int *A, int mons, int kn, int xx,int rvar)
+{
+  int  i, *B, *ex;
+
+  B = A + ((kn - 1) * mons);
+  ex = A + (rvar * mons);
+  i = mons;
+  if (xx == 1)
+  {
+    for (/* i=mons */; i!=0 ; i--)
+      *ex++ -= *B++;
+  }
+  else
+  {
+    for (/* i=mons */; i!=0 ; i--)
+      *ex++ -= (*B++) * xx;
+  }
+}
+
+
+void wAdd(int *A, int mons, int kn, int xx, int rvar)
+{
+  int  i, *B, *ex;
+
+  B = A + ((kn - 1) * mons);
+  ex = A + (rvar * mons);
+  i = mons;
+  if (xx == 1)
+  {
+    for (/* i=mons */; i!=0 ; i--)
+      *ex++ += *B++;
+  }
+  else
+  {
+    for (/* i=mons */; i!=0 ; i--)
+      *ex++ += (*B++) * xx;
+  }
+}
+
+
+void wFirstSearch(int *A, int *x, int mons,
+  int *lpol, int npol, double *rel, double *fopt, double wNsqr, int rvar)
+{
+  int  a0, a, n, xn, t, xx, y1;
+  int  *y, *degw, *xopt;
+  double  fy, fmax, wx;
+  double *pr;
+  void *adr;
+
+  fy = *fopt;
+  n = rvar;
+  xn = n + 6 + (21 / n);
+  a0 = n * sizeof(double);
+  a = n * sizeof(int);
+  y = (int * )omAlloc((long)a);
+  adr = (void * )omAllocAligned((long)a0);
+  pr = adr;
+  *pr = (double)1.0;
+  *y = 0;
+  degw = A + (n * mons);
+  xopt = x + (n + 2);
+  t = 1;
+  loop
+  {
+    while (t < n)
+    {
+      xx = x[t] + 1;
+      wx = pr[t-1] * (double)xx;
+      y1 = y[t-1] + xx;
+      if ((y1 + n - t) <= xn)
+      {
+        pr[t] = wx;
+        y[t] = y1;
+        x[t] = xx;
+        if (xx > 1)
+          wAdd(A, mons, t, 1, rvar);
+        t++;
+      }
+      else
+      {
+        xx = x[t] - 1;
+        x[t] = 0;
+        if (xx!=0)
+          wSub(A, mons, t, xx, rvar);
+        t--;
+        if (t==0)
+        {
+          *fopt = fy;
+          omFreeSize((ADDRESS)y, (long)a);
+          omFreeSize((ADDRESS)adr, (long)a0);
+          return;
+        }
+      }
+    }
+    xx = xn - y[t-1];
+    wx = pr[t-1] * (double)xx;
+    x[t] = xx;
+    xx--;
+    if (xx!=0)
+      wAdd(A, mons, t, xx, rvar);
+    fmax = (*wFunctional)(degw, lpol, npol, rel, wx,wNsqr);
+    if (xx!=0)
+      wSub(A, mons, t, xx, rvar);
+    if (fmax < fy)
+    {
+      fy = fmax;
+      memcpy(xopt, x + 1, a);
+    }
+    t--;
+  } /* end loop */
+}
+
+
+static double wPrWeight(int *x, int n)
+{
+  int i;
+  double y;
+
+  y = (double)x[n];
+  for (i = n - 1; i!=0 ; i--)
+    y *= (double)x[i];
+  return y;
+}
+
+
+static void wEstimate(int *A, int *x, int *lpol, int npol, int mons,
+double wx, double *rel, double *fopt, int *s0, int *s1, int *s2, double wNsqr, int rvar)
+{
+  int  n, i1, i2, k0 = 0, k1 = 0, k2 = 0;
+  int  *degw;
+  double fo1, fo2, fmax, wx1, wx2;
+
+  n = rvar;
+  degw = A + (n * mons);
+  fo2 = fo1 = (double)1.0e10;
+  for (i1 = n; i1!=0 ; i1--)
+  {
+    if (x[i1] > 1)
+    {
+      wSub(A, mons, i1, 1, rvar);
+      wx1 = wx - wx / (double)x[i1];
+      x[i1]--;
+      fmax = (*wFunctional)(degw, lpol, npol, rel, wx1,wNsqr);
+      if (fmax < fo1)
+      {
+        fo1 = fmax;
+        k0 = i1;
+      }
+      for (i2 = i1; i2!=0 ; i2--)
+      {
+        if (x[i2] > 1)
+        {
+          wSub(A, mons, i2, 1, rvar);
+          wx2 = wx1 - wx1 / (double)x[i2];
+          fmax = (*wFunctional)(degw, lpol, npol, rel, wx2, wNsqr);
+          if (fmax < fo2)
+          {
+            fo2 = fmax;
+            k1 = i1;
+            k2 = i2;
+          }
+          wAdd(A, mons, i2, 1, rvar);
+        }
+      }
+      wAdd(A, mons, i1, 1, rvar);
+      x[i1]++;
+    }
+  }
+  if (fo1 < fo2)
+  {
+    *fopt = fo1;
+    *s0 = k0;
+  }
+  else
+  {
+    *fopt = fo2;
+    *s0 = 0;
+  }
+  *s1 = k1;
+  *s2 = k2;
+}
+
+
+void wSecondSearch(int *A, int *x, int *lpol,
+int npol, int mons, double *rel, double *fk, double wNsqr, int rvar)
+{
+  int  n, s0, s1, s2, *xopt;
+  double  one, fx, fopt, wx;
+
+  n = rvar;
+  xopt = x + (n + 2);
+  fopt = *fk * (double)0.999999999999;
+  wx = wPrWeight(x, n);
+  one = (double)1.0;
+  loop
+  {
+    wEstimate(A, x, lpol, npol, mons, wx, rel, &fx, &s0, &s1, &s2, wNsqr, rvar);
+    if (fx > fopt)
+    {
+      if (s0!=0)
+        x[s0]--;
+      else if (s1!=0)
+      {
+        x[s1]--;
+        x[s2]--;
+      }
+      else
+        break;
+    }
+    else
+    {
+      fopt = fx;
+      if (s0!=0)
+      {
+        x[s0]--;
+        memcpy(xopt, x + 1, n * sizeof(int));
+        if (s1==0)
+          break;
+      }
+      else if (s1!=0)
+      {
+        x[s1]--;
+        x[s2]--;
+        memcpy(xopt, x + 1, n * sizeof(int));
+      }
+      else
+        break;
+    }
+    if (s0!=0)
+      wSub(A, mons, s0, 1, rvar);
+    else
+    {
+      wSub(A, mons, s1, 1, rvar);
+      wSub(A, mons, s2, 1, rvar);
+    }
+    wx = wPrWeight(x, n);
+  }
+  *fk = fopt;
+}
+
+
+void wGcd(int *x, int n)
+{
+  int i, b, a, h;
+
+  i = n;
+  b = x[i];
+  loop
+  {
+    i--;
+    if (i==0)
+      break;
+    a = x[i];
+    if (a < b)
+    {
+      h = a;
+      a = b;
+      b = h;
+    }
+    do
+    {
+      h = a % b;
+      a = b;
+      b = h;
+    }
+    while (b!=0);
+    b = a;
+    if (b == 1)
+      return;
+  }
+  for (i = n; i!=0 ; i--)
+    x[i] /= b;
+}
+
+
+static void wSimple(int *x, int n)
+{
+  int g, min, c, d, f, kopt, k, i;
+  int *xopt;
+  double sopt, s1, s2;
+
+  xopt = x + (n + 1);
+  kopt = k = g = 0;
+  min = 1000000;
+  for (i = n; i!=0 ; i--)
+  {
+    c = xopt[i];
+    if (c > 1)
+    {
+      if (c < min)
+        min = c;
+      if (c > k)
+        k = c;
+    }
+    else
+      g = 1;
+  }
+  k -= min;
+  if ((g==0) && (k < 4))
+    return;
+  if (k < min)
+    min = k+1;
+  sopt = (double)1.0e10;
+  for (k = min; k > 1; k--)
+  {
+    s2 = s1 = (double)0.0;
+    for(i = n; i!=0 ; i--)
+    {
+      c = xopt[i];
+      if (c > 1)
+      {
+        d = c / k;
+        d *= k;
+        f = d = c - d;
+        if (f!=0)
+        {
+          f = k - f;
+          if (f < d)
+            s2 += (double)f / (double)c;
+          else
+            s1 += (double)d / (double)c;
+        }
+      }
+    }
+    s1 += s2 + sqrt(s1 * s2);
+    s1 -= (double)0.01 * sqrt((double)k);
+    if (s1 < sopt)
+    {
+      sopt = s1;
+      kopt = k;
+    }
+  }
+  for(i = n; i!=0 ; i--)
+  {
+    x[i] = 1;
+    c = xopt[i];
+    if (c > 1)
+    {
+      d = c / kopt;
+      d *= kopt;
+      x[i] = d;
+      d = c - d;
+      if ((d!=0) && (kopt < 2 * d))
+        x[i] += kopt;
+    }
+  }
+  if (g==0)
+    wGcd(x, n);
+}
+
+
+void wNorm(int *degw, int *lpol, int npol, double *rel)
+{
+  int  i, j, ecu, ec;
+  int  *ex;
+  double *r;
+
+  ex = degw;
+  r = rel;
+  for (i = 0; i < npol; i++)
+  {
+    ecu = *ex++;
+    for (j = lpol[i] - 1; j!=0 ; j--)
+    {
+      ec = *ex++;
+      if (ec > ecu)
+        ecu = ec;
+    }
+    *r = (double)1.0 / (double)(ecu * ecu);
+    r++;
+  }
+}
diff --git a/libpolys/reporter/Makefile.am b/libpolys/reporter/Makefile.am
new file mode 100644
index 0000000..391cd11
--- /dev/null
+++ b/libpolys/reporter/Makefile.am
@@ -0,0 +1,15 @@
+ACLOCAL_AMFLAGS = -I ../../m4
+
+AM_CPPFLAGS = -I${top_srcdir} -I${top_srcdir}/.. -I${top_builddir} -I${top_builddir}/..  ${GMP_CFLAGS}
+
+noinst_LTLIBRARIES = libreporter.la
+#### libreporterdir = $(libdir)/singular
+
+libreporter_la_SOURCES  = dError.cc reporter.cc s_buff.cc
+## libreporter_la_LDFLAGS  = -release ${PACKAGE_VERSION}
+## libreporter_la_LIBADD   = ${top_builddir}/misc/libmisc.la
+
+libreporter_la_includedir  =$(includedir)/singular/reporter
+libreporter_la_include_HEADERS   = reporter.h s_buff.h si_signals.h
+
+
diff --git a/libpolys/reporter/Makefile.in b/libpolys/reporter/Makefile.in
new file mode 100644
index 0000000..636a55d
--- /dev/null
+++ b/libpolys/reporter/Makefile.in
@@ -0,0 +1,681 @@
+# Makefile.in generated by automake 1.13.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 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@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+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 = reporter
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/../build-aux/depcomp \
+	$(libreporter_la_include_HEADERS)
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/../m4/ax_append_compile_flags.m4 \
+	$(top_srcdir)/../m4/ax_append_flag.m4 \
+	$(top_srcdir)/../m4/ax_append_link_flags.m4 \
+	$(top_srcdir)/../m4/ax_check_compile_flag.m4 \
+	$(top_srcdir)/../m4/ax_check_link_flag.m4 \
+	$(top_srcdir)/../m4/ax_cxx_gcc_abi_demangle.m4 \
+	$(top_srcdir)/../m4/ax_prefix_config_h.m4 \
+	$(top_srcdir)/../m4/cpu-check.m4 $(top_srcdir)/../m4/flags.m4 \
+	$(top_srcdir)/../m4/flint-check.m4 \
+	$(top_srcdir)/../m4/gmp-check.m4 \
+	$(top_srcdir)/../m4/libtool.m4 \
+	$(top_srcdir)/../m4/ltoptions.m4 \
+	$(top_srcdir)/../m4/ltsugar.m4 \
+	$(top_srcdir)/../m4/ltversion.m4 \
+	$(top_srcdir)/../m4/lt~obsolete.m4 \
+	$(top_srcdir)/../m4/ntl-check.m4 \
+	$(top_srcdir)/../m4/options.m4 $(top_srcdir)/../m4/p-procs.m4 \
+	$(top_srcdir)/configure.ac
+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 =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+libreporter_la_LIBADD =
+am_libreporter_la_OBJECTS = dError.lo reporter.lo s_buff.lo
+libreporter_la_OBJECTS = $(am_libreporter_la_OBJECTS)
+AM_V_lt = $(am__v_lt_ at AM_V@)
+am__v_lt_ = $(am__v_lt_ at AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 = 
+AM_V_P = $(am__v_P_ at AM_V@)
+am__v_P_ = $(am__v_P_ at AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_ at AM_V@)
+am__v_GEN_ = $(am__v_GEN_ at AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_ at AM_V@)
+am__v_at_ = $(am__v_at_ at AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+DEFAULT_INCLUDES = -I. at am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/../build-aux/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \
+	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+	$(AM_CXXFLAGS) $(CXXFLAGS)
+AM_V_CXX = $(am__v_CXX_ at AM_V@)
+am__v_CXX_ = $(am__v_CXX_ at AM_DEFAULT_V@)
+am__v_CXX_0 = @echo "  CXX     " $@;
+am__v_CXX_1 = 
+CXXLD = $(CXX)
+CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+	$(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CXXLD = $(am__v_CXXLD_ at AM_V@)
+am__v_CXXLD_ = $(am__v_CXXLD_ at AM_DEFAULT_V@)
+am__v_CXXLD_0 = @echo "  CXXLD   " $@;
+am__v_CXXLD_1 = 
+SOURCES = $(libreporter_la_SOURCES)
+DIST_SOURCES = $(libreporter_la_SOURCES)
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+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__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
+am__installdirs = "$(DESTDIR)$(libreporter_la_includedir)"
+HEADERS = $(libreporter_la_include_HEADERS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+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@
+FACTORY_INCLUDES = @FACTORY_INCLUDES@
+FACTORY_LIBS = @FACTORY_LIBS@
+FGREP = @FGREP@
+FLINT_CFLAGS = @FLINT_CFLAGS@
+FLINT_HOME = @FLINT_HOME@
+FLINT_LIBS = @FLINT_LIBS@
+GMP_CFLAGS = @GMP_CFLAGS@
+GMP_HOME = @GMP_HOME@
+GMP_LIBS = @GMP_LIBS@
+GMP_VERSION = @GMP_VERSION@
+GREP = @GREP@
+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@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NTL_CFLAGS = @NTL_CFLAGS@
+NTL_LIBS = @NTL_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OMALLOC_INCLUDES = @OMALLOC_INCLUDES@
+OMALLOC_LIBS = @OMALLOC_LIBS@
+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@
+PKG_REQUIRE = @PKG_REQUIRE@
+POLYMAKE_CXXFLAGS = @POLYMAKE_CXXFLAGS@
+RANLIB = @RANLIB@
+RESOURCES_INCLUDES = @RESOURCES_INCLUDES@
+RESOURCES_LIBS = @RESOURCES_LIBS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SINGULAR_CFLAGS = @SINGULAR_CFLAGS@
+SI_CPU_I386 = @SI_CPU_I386@
+SI_CPU_IA64 = @SI_CPU_IA64@
+SI_CPU_PPC = @SI_CPU_PPC@
+SI_CPU_SPARC = @SI_CPU_SPARC@
+SI_CPU_X86_64 = @SI_CPU_X86_64@
+STRIP = @STRIP@
+USEPPROCSDYNAMICLD = @USEPPROCSDYNAMICLD@
+USEPPROCSDYNAMICLDFLAGS = @USEPPROCSDYNAMICLDFLAGS@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+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@
+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@
+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@
+ACLOCAL_AMFLAGS = -I ../../m4
+AM_CPPFLAGS = -I${top_srcdir} -I${top_srcdir}/.. -I${top_builddir} -I${top_builddir}/..  ${GMP_CFLAGS}
+noinst_LTLIBRARIES = libreporter.la
+#### libreporterdir = $(libdir)/singular
+libreporter_la_SOURCES = dError.cc reporter.cc s_buff.cc
+libreporter_la_includedir = $(includedir)/singular/reporter
+libreporter_la_include_HEADERS = reporter.h s_buff.h si_signals.h
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .cc .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) --foreign reporter/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign reporter/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-noinstLTLIBRARIES:
+	-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+	@list='$(noinst_LTLIBRARIES)'; \
+	locs=`for p in $$list; do echo $$p; done | \
+	      sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+	      sort -u`; \
+	test -z "$$locs" || { \
+	  echo rm -f $${locs}; \
+	  rm -f $${locs}; \
+	}
+
+libreporter.la: $(libreporter_la_OBJECTS) $(libreporter_la_DEPENDENCIES) $(EXTRA_libreporter_la_DEPENDENCIES) 
+	$(AM_V_CXXLD)$(CXXLINK)  $(libreporter_la_OBJECTS) $(libreporter_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/dError.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/reporter.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/s_buff.Plo at am__quote@
+
+.cc.o:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+ at am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXXCOMPILE) -c -o $@ $<
+
+.cc.obj:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+ at am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.cc.lo:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+ at am__fastdepCXX_TRUE@	$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LTCXXCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+install-libreporter_la_includeHEADERS: $(libreporter_la_include_HEADERS)
+	@$(NORMAL_INSTALL)
+	@list='$(libreporter_la_include_HEADERS)'; test -n "$(libreporter_la_includedir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(libreporter_la_includedir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(libreporter_la_includedir)" || exit 1; \
+	fi; \
+	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)$(libreporter_la_includedir)'"; \
+	  $(INSTALL_HEADER) $$files "$(DESTDIR)$(libreporter_la_includedir)" || exit $$?; \
+	done
+
+uninstall-libreporter_la_includeHEADERS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(libreporter_la_include_HEADERS)'; test -n "$(libreporter_la_includedir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	dir='$(DESTDIR)$(libreporter_la_includedir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	$(am__define_uniq_tagged_files); \
+	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-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	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"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+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 $(LTLIBRARIES) $(HEADERS)
+installdirs:
+	for dir in "$(DESTDIR)$(libreporter_la_includedir)"; 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:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+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 clean-noinstLTLIBRARIES \
+	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-libreporter_la_includeHEADERS
+
+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: uninstall-libreporter_la_includeHEADERS
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
+	clean-libtool clean-noinstLTLIBRARIES cscopelist-am ctags \
+	ctags-am 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-libreporter_la_includeHEADERS \
+	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 tags-am uninstall \
+	uninstall-am uninstall-libreporter_la_includeHEADERS
+
+
+# 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/libpolys/reporter/dError.cc b/libpolys/reporter/dError.cc
new file mode 100644
index 0000000..3dbd894
--- /dev/null
+++ b/libpolys/reporter/dError.cc
@@ -0,0 +1,143 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    dError.cc
+ *  Purpose: implementation for debug error handling
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 9/00
+ *******************************************************************/
+#ifndef DERROR_C
+#define DERROR_C
+
+#include <misc/auxiliary.h>
+
+#include <omalloc/omalloc.h>
+
+#include <reporter/reporter.h>
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+
+static inline void malloc_free( void * ptr )
+{
+  free(ptr);
+}
+
+#ifdef HAVE_EXECINFO_H
+#include <execinfo.h>
+#endif
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#ifdef HAVE_GCC_ABI_DEMANGLE
+#include <cxxabi.h>
+#endif
+
+
+extern "C"
+{
+
+int dReportError(const char* fmt, ...)
+{
+#if 0
+#ifdef HAVE_EXECINFO_H
+#define SIZE 50
+  void *buffer[SIZE+1]; int ret;
+#endif
+#endif
+
+  va_list ap;
+  va_start(ap, fmt);
+#ifndef MAKE_DISTRIBUTION
+  fprintf(stderr, "\n// ***dError: ");
+  vfprintf(stderr, fmt, ap);
+#if !defined(OM_NDEBUG)
+  #ifdef omPrintCurrentBackTraceMax
+  fprintf(stderr, " occured at: \n");
+  omPrintCurrentBackTraceMax(stderr, 8);
+  #endif
+#endif
+
+#if 0
+#ifdef HAVE_EXECINFO_H
+  ret = backtrace( buffer, SIZE ); // execinfo.h
+  fprintf(stderr, "\nExecinfo backtrace (with %zd stack frames): \n", ret);
+
+#ifndef HAVE_GCC_ABI_DEMANGLE
+  backtrace_symbols_fd(buffer, ret, STDERR_FILENO); // execinfo.h
+#else
+  char **ptr = backtrace_symbols( buffer, ret ); // execinfo.h
+
+  int status;
+  char *demangledName;
+  char *s;
+  char *ss;
+  for (int i = 0; i < ret; i++)
+  {
+    status = -1;
+
+    s = ptr[i];
+//    fprintf (stderr, " #%02d: %s\n", i, s);
+
+    ss = index(s, '(');
+    ss[0] = 0;
+    fprintf (stderr, " #%02d: '%s': ", i, s);
+    ss[0] = '('; s = ss + 1;
+
+    ss = index(s, '+');
+
+    if ( ss != NULL )
+    {
+      ss[0] = 0;
+      demangledName = abi::__cxa_demangle( s, NULL, NULL, &status ); // cxxabi.h!
+      if( status == 0 && demangledName != NULL )
+        fprintf (stderr, " '%s'", (demangledName[0] != 0)? demangledName: s);
+      else
+        fprintf (stderr, " '%s'", s);
+
+      malloc_free( demangledName );
+      ss[0] = '+';
+      s = ss + 1;
+    }
+
+    ss = index(s, ')');
+    if( s != ss)
+    {
+      ss[0] = 0;
+      fprintf (stderr, " + %s", s);
+      ss[0] = ')';
+    }
+
+    fprintf (stderr, " %s\n", ss + 2);
+  }
+  malloc_free (ptr);
+#endif
+#endif
+
+#undef SIZE
+#endif
+
+  dErrorBreak();
+#else
+  fprintf(stderr, "\n// !!! YOU HAVE FOUND A BUG IN SINGULAR.");
+  fprintf(stderr, "// !!! Please, email the input\n// and the following error message to singular at mathematik.uni-kl.de")
+  vfprintf(stderr, fmt, ap);
+#endif
+  return 0;
+}
+
+}
+
+#endif
+
+#ifndef MAKE_DISTRIBUTION
+// dummy procedure for setting a breakpoint
+// within the debugger
+void dErrorBreak()
+{}
+#endif
diff --git a/libpolys/reporter/reporter.cc b/libpolys/reporter/reporter.cc
new file mode 100644
index 0000000..4a2ff6c
--- /dev/null
+++ b/libpolys/reporter/reporter.cc
@@ -0,0 +1,422 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: output system
+*/
+
+#include <misc/auxiliary.h>
+
+#include <omalloc/omalloc.h>
+
+#include <reporter/reporter.h>
+#include <resources/feResource.h>
+#include <resources/feFopen.h>
+//#include "options.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <misc/mylimits.h>
+#include <stdarg.h>
+#include <sys/stat.h>
+#include <ctype.h>
+#include <unistd.h>
+
+#ifdef HAVE_PWD_H
+#include <pwd.h>
+#endif
+
+
+#define fePutChar(c) fputc((unsigned char)(c),stdout)
+/*0 implementation */
+
+// output/print buffer:
+#define INITIAL_PRINT_BUFFER 24*1024L
+// line buffer for reading:
+// minimal value for MAX_FILE_BUFFER: 4*4096 - see Tst/Long/gcd0_l.tst
+// this is an upper limit for the size of monomials/numbers read via the interpreter
+#define MAX_FILE_BUFFER 4*4096
+static long feBufferLength=0;
+static char * feBuffer=NULL;
+static long feBufferLength_save[8];
+static char * feBuffer_save[8];
+static int feBuffer_cnt=0;
+static char * feBufferStart_save[8];
+
+
+char *  feErrors=NULL;
+int     feErrorsLen=0;
+BOOLEAN feWarn = TRUE;
+BOOLEAN feOut = TRUE;
+
+//void (*WerrorS_callback)(const char *s) = NULL;
+
+const char feNotImplemented[]="not implemented";
+
+int feProt = FALSE;
+FILE*   feProtFile;
+
+static char * feBufferStart;
+  /* only used in StringSet(S)/StringAppend(S)*/
+void StringAppend(const char *fmt, ...)
+{
+  va_list ap;
+  char *s = feBufferStart; /*feBuffer + strlen(feBuffer);*/
+  int vs;
+  long more;
+  va_start(ap, fmt);
+  if ((more=feBufferStart-feBuffer+strlen(fmt)+100)>feBufferLength)
+  {
+    more = ((more + (8*1024-1))/(8*1024))*(8*1024);
+    int l=s-feBuffer;
+    feBuffer=(char *)omReallocSize((void *)feBuffer,feBufferLength,
+                                                     more);
+#if (!defined(SING_NDEBUG)) && (!defined(OM_NDEBUG))
+    omMarkAsStaticAddr(feBuffer);
+#endif
+    feBufferLength=more;
+    s=feBuffer+l;
+#ifndef BSD_SPRINTF
+    feBufferStart=s;
+#endif
+  }
+#ifdef BSD_SPRINTF
+  vsprintf(s, fmt, ap);
+  while (*s!='\0') s++;
+  feBufferStart =s;
+#else
+#ifdef HAVE_VSNPRINTF
+  vs = vsnprintf(s, feBufferLength - (feBufferStart - feBuffer), fmt, ap);
+  if (vs == -1)
+  {
+    assume(0);
+    feBufferStart = feBuffer + feBufferLength -1;
+  }
+  else
+  {
+    feBufferStart += vs;
+  }
+#else
+  feBufferStart += vsprintf(s, fmt, ap);
+#endif
+#endif
+  omCheckAddrSize(feBuffer, feBufferLength);
+  va_end(ap);
+}
+
+void StringAppendS(const char *st)
+{
+  if (*st!='\0')
+  {
+    /* feBufferStart is feBuffer + strlen(feBuffer);*/
+    int l;
+    long more;
+    int ll=feBufferStart-feBuffer;
+    if ((more=ll+2+(l=strlen(st)))>feBufferLength)
+    {
+      more = ((more + (8*1024-1))/(8*1024))*(8*1024);
+      feBuffer=(char *)omreallocSize((void *)feBuffer,feBufferLength,
+                                                       more);
+      feBufferLength=more;
+      feBufferStart=feBuffer+ll;
+    }
+    strcat(feBufferStart, st);
+    feBufferStart +=l;
+  }
+}
+
+void StringSetS(const char *st)
+{
+  feBuffer_save[feBuffer_cnt]=feBuffer;
+  feBuffer=(char*)omAlloc0(INITIAL_PRINT_BUFFER);
+  feBufferLength_save[feBuffer_cnt]=feBufferLength;
+  feBufferLength=INITIAL_PRINT_BUFFER;
+  feBufferStart_save[feBuffer_cnt]=feBufferStart;
+  feBufferStart=feBuffer;
+  feBuffer_cnt++;
+  assume(feBuffer_cnt<8);
+  int l;
+  long more;
+  if ((l=strlen(st))>feBufferLength)
+  {
+    more = ((l + (4*1024-1))/(4*1024))*(4*1024);
+    feBuffer=(char *)omReallocSize((ADDRESS)feBuffer,feBufferLength,
+                                                     more);
+    feBufferLength=more;
+  }
+  strcpy(feBuffer,st);
+  feBufferStart=feBuffer+l;
+}
+
+char * StringEndS()
+{
+  char *r=feBuffer;
+  feBuffer_cnt--;
+  assume(feBuffer_cnt >=0);
+  feBuffer=feBuffer_save[feBuffer_cnt];
+  feBufferLength=feBufferLength_save[feBuffer_cnt];
+  feBufferStart=feBufferStart_save[feBuffer_cnt];
+  if (strlen(r)<1024)
+  {
+    // if the used buffer is a "smal block",
+    // substitue the "large" initial block by a small one
+    char *s=omStrDup(r); omFree(r); r=s;
+  }
+  return r;
+}
+
+#ifdef HAVE_TCL
+extern "C" {
+void PrintTCLS(const char c, const char *s)
+{
+  int l=strlen(s);
+  if (l>0) PrintTCL(c,l,s);
+}
+}
+#endif
+
+void WerrorS_batch(const char *s)
+{
+  if (feErrors==NULL)
+  {
+    feErrors=(char *)omAlloc(256);
+    feErrorsLen=256;
+    *feErrors = '\0';
+  }
+  else
+  {
+    if (((int)(strlen((char *)s)+ 20 +strlen(feErrors)))>=feErrorsLen)
+    {
+      feErrors=(char *)omReallocSize(feErrors,feErrorsLen,feErrorsLen+256);
+      feErrorsLen+=256;
+    }
+  }
+  strcat(feErrors, "Singular error: ");
+  strcat(feErrors, (char *)s);
+  errorreported = TRUE;
+}
+
+void Werror(const char *fmt, ...)
+{
+  va_list ap;
+  va_start(ap, fmt);
+  char *s=(char *)omAlloc(256);
+  vsprintf(s, fmt, ap);
+  WerrorS(s);
+  omFreeSize(s,256);
+  va_end(ap);
+}
+
+void WarnS(const char *s)
+{
+  #define warn_str "// ** "
+#ifdef HAVE_TCL
+  if (tclmode)
+  {
+    PrintTCLS('W',warn_str);
+    PrintTCLS('W',s);
+    PrintTCLS('W',"\n");
+  }
+  else
+#endif
+  if (feWarn) /* ignore warnings if option --no-warn was given */
+  {
+    fwrite(warn_str,1,6,stdout);
+    fwrite(s,1,strlen(s),stdout);
+    fwrite("\n",1,1,stdout);
+    fflush(stdout);
+    if (feProt&SI_PROT_O)
+    {
+      fwrite(warn_str,1,6,feProtFile);
+      fwrite(s,1,strlen(s),feProtFile);
+      fwrite("\n",1,1,feProtFile);
+    }
+  }
+}
+
+void Warn(const char *fmt, ...)
+{
+  va_list ap;
+  va_start(ap, fmt);
+  char *s=(char *)omAlloc(256);
+#ifdef HAVE_VSNPRINTF
+  vsnprintf(s, 256, fmt, ap);
+#else
+  vsprintf(s, fmt, ap);
+#endif
+  WarnS(s);
+  omFreeSize(s,256);
+  va_end(ap);
+}
+
+
+// some routines which redirect the output of print to a string
+static char* sprint = NULL;
+static char* sprint_backup = NULL;
+void SPrintStart()
+{
+  if (sprint!=NULL)
+  {
+    if (sprint_backup!=NULL) WerrorS("internal error: SPrintStart");
+    else sprint_backup=sprint;
+  }
+  sprint = omStrDup("");
+}
+
+static void SPrintS(const char* s)
+{
+  omCheckAddr(sprint);
+  if ((s == NULL)||(*s == '\0')) return;
+  int ls = strlen(s);
+
+  char* ns;
+  int l = strlen(sprint);
+  ns = (char*) omAlloc((l + ls + 1)*sizeof(char));
+  if (l > 0) strcpy(ns, sprint);
+
+  strcpy(&(ns[l]), s);
+  omFree(sprint);
+  sprint = ns;
+  omCheckAddr(sprint);
+}
+
+char* SPrintEnd()
+{
+  char* ns = sprint;
+  sprint = sprint_backup;
+  sprint_backup=NULL;
+  omCheckAddr(ns);
+  return ns;
+}
+
+// Print routines
+extern "C" {
+void PrintS(const char *s)
+{
+  if (sprint != NULL)
+  {
+    SPrintS(s);
+    return;
+  }
+  else if (feOut) /* do not print when option --no-out was given */
+  {
+
+#ifdef HAVE_TCL
+    if (tclmode)
+    {
+      PrintTCLS('N',s);
+    }
+    else
+#endif
+    {
+      fwrite(s,1,strlen(s),stdout);
+      fflush(stdout);
+      if (feProt&SI_PROT_O)
+      {
+        fwrite(s,1,strlen(s),feProtFile);
+      }
+    }
+  }
+}
+
+void PrintLn()
+{
+  PrintS("\n");
+}
+
+void Print(const char *fmt, ...)
+{
+  if (sprint != NULL)
+  {
+    va_list ap;
+    va_start(ap, fmt);
+    omCheckAddr(sprint);
+    int ls = strlen(fmt);
+    if (fmt != NULL && ls > 0)
+    {
+      char* ns;
+      int l = strlen(sprint);
+      ns = (char*) omAlloc(sizeof(char)*(ls + l + 512));
+      if (l > 0)  strcpy(ns, sprint);
+
+#ifdef HAVE_VSNPRINTF
+      l = vsnprintf(&(ns[l]), ls+511, fmt, ap);
+      assume(l != -1);
+#else
+      vsprintf(&(ns[l]), fmt, ap);
+#endif
+      omCheckAddr(ns);
+      omFree(sprint);
+      sprint = ns;
+    }
+    va_end(ap);
+    return;
+  }
+  else if (feOut)
+  {
+    va_list ap;
+    va_start(ap, fmt);
+    int l;
+    long ls=strlen(fmt);
+    char *s=(char *)omAlloc(ls+512);
+#ifdef HAVE_VSNPRINTF
+    l = vsnprintf(s, ls+511, fmt, ap);
+    if ((l==-1)||(s[l]!='\0')||(l!=(int)strlen(s)))
+    {
+      printf("Print problem: l=%d, fmt=>>%s<<\n",l,fmt);
+    }
+#else
+    vsprintf(s, fmt, ap);
+#endif
+    PrintS(s);
+    omFree(s);
+    va_end(ap);
+  }
+}
+void PrintNSpaces(const int n)
+{
+  int l=n-1;
+  while(l>=0) { PrintS(" "); l--; }
+}
+
+/* end extern "C" */
+}
+
+const char* eati(const char *s, int *i)
+{
+  int l=0;
+
+  if    (*s >= '0' && *s <= '9')
+  {
+    *i = 0;
+    while (*s >= '0' && *s <= '9')
+    {
+      *i *= 10;
+      *i += *s++ - '0';
+      l++;
+      if ((l>=MAX_INT_LEN)||((*i) <0))
+      {
+        s-=l;
+        Werror("`%s` greater than %d(max. integer representation)",
+                s,MAX_INT_VAL);
+        return s;
+      }
+    }
+  }
+  else *i = 1;
+  return s;
+}
+
+void feStringAppendResources(int warn)
+{
+  int i = 0;
+  char* r;
+  StringAppend("%-10s:\t%s\n", "argv[0]", feArgv0);
+  while (feResourceConfigs[i].key != NULL)
+  {
+    r = feResource(feResourceConfigs[i].key, warn);
+    StringAppend("%-10s:\t%s\n", feResourceConfigs[i].key,
+                 (r != NULL ? r : ""));
+    i++;
+  }
+}
diff --git a/libpolys/reporter/reporter.h b/libpolys/reporter/reporter.h
new file mode 100644
index 0000000..5cc5f55
--- /dev/null
+++ b/libpolys/reporter/reporter.h
@@ -0,0 +1,141 @@
+#ifndef OUTPUT_H
+#define OUTPUT_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: basic output
+*/
+#include <stdio.h>
+#include <string.h>
+#include <misc/auxiliary.h>
+#include <resources/feFopen.h>
+
+extern char*  feErrors;
+extern int    feErrorsLen;
+extern FILE*  feProtFile;
+extern int    pagelength, colmax;
+extern int    yy_blocklineno;
+extern int    yy_noeof;
+extern const char feNotImplemented[];
+extern int     feProt;
+extern BOOLEAN feWarn;
+extern BOOLEAN feOut;
+extern int  traceit ;
+#define TRACE_SHOW_PROC   1
+#define TRACE_SHOW_LINENO 2
+#define TRACE_SHOW_LINE   4
+#define TRACE_SHOW_RINGS  8
+#define TRACE_SHOW_LINE1  16
+#define TRACE_BREAKPOINT  32
+#define TRACE_TMP_BREAKPOINT  64
+#define TRACE_CALL       128
+#define TRACE_ASSIGN     256
+#define TRACE_CONV       512
+
+
+#define SI_PROT_I    1
+#define SI_PROT_O    2
+#define SI_PROT_IO   3
+
+/* the C-part: */
+#define mflush() fflush(stdout)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void    Werror(const char *fmt, ...) __attribute__((format(printf,1,2)));
+void    WerrorS_batch(const char *s);
+void    WarnS(const char *s);
+void    Print(const char* fmt, ...) __attribute__((format(printf,1,2)));
+/* Print should not produce more than strlen(fmt)+510 characters! */
+
+void    PrintNSpaces(const int n);
+void    PrintLn();
+void    PrintS(const char* s);
+
+#ifdef __cplusplus
+}
+/* the C++-part: */
+
+// a new output buffer will be allocated by StringSetS,
+// used by several calls to StringAppend/StringAppendS
+// and closed by StringEndS:
+// StringEndS() returns this buffer which must be freed by omFree
+// several buffer may be active at the same time
+// (for example in subroutines)
+void  StringAppend(const char *fmt, ...);
+void  StringAppendS(const char *s);
+void  StringSetS(const char* s);
+char * StringEndS();
+void  Warn(const char *fmt, ...);
+
+const char *  eati(const char *s, int *i);
+
+// Prints resources into string with StringAppend, etc
+void feStringAppendResources(int warn = -1);
+#endif /* c++ only */
+
+/* everything in between calls to these procedures is printed into a string
+ * which is returned by SprintEnd()
+ * Shall ONLY be used for a temporary redirection of the standard output
+ * (i.e. if Singular runs as a server)
+ */
+// unlike the StringSet/StringEndS stuff:
+// only one SPrintStart/SPrintEnd buffer may be active
+// the returned string must be free via omFree
+void SPrintStart();
+char* SPrintEnd();
+
+/* error reporting */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+extern int dReportError(const char* fmt, ...);
+#define dReportBug(s) \
+  dReportError("Bug reported: %s\n occured at %s,%d\n", s, __FILE__, __LINE__)
+
+// this is just a dummy procedure which is called after the error
+// has been reported. Within the debugger, set a breakpoint on this
+// proc.
+extern void dErrorBreak();
+#ifdef __cplusplus
+}
+#endif
+
+#ifndef HAVE_ASSUME
+#define assume(x) do {} while (0)
+#define r_assume(x) do {} while (0)
+#else /* ! HAVE_ASSUME */
+
+#define assume_violation(s,f,l) \
+  dReportError("assume violation at %s:%d condition: %s", f,l,s)
+
+#define assume(x)   _assume(x, __FILE__, __LINE__)
+#define r_assume(x) _r_assume(x, __FILE__, __LINE__)
+
+#define _assume(x, f, l)                        \
+do                                              \
+{                                               \
+  if (! (x))                                    \
+  {                                             \
+    assume_violation(#x, f, l);                 \
+  }                                             \
+}                                               \
+while (0)
+
+#define _r_assume(x, f, l)                      \
+do                                              \
+{                                               \
+  if (! (x))                                    \
+  {                                             \
+    assume_violation(#x, f, l);                 \
+    return 0;                                   \
+  }                                             \
+}                                               \
+while (0)
+#endif /* HAVE_ASSUME */
+
+#endif /* ifndef OUTPUT_H */
diff --git a/libpolys/reporter/s_buff.cc b/libpolys/reporter/s_buff.cc
new file mode 100644
index 0000000..d5d2099
--- /dev/null
+++ b/libpolys/reporter/s_buff.cc
@@ -0,0 +1,265 @@
+#include <misc/auxiliary.h>
+
+#include <unistd.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <signal.h>
+
+//#include <kernel/mod2.h>
+#include <gmp.h>
+
+#include <omalloc/omalloc.h>
+#include <reporter/s_buff.h>
+#include <reporter/si_signals.h>
+
+//struct s_buff_s
+//{
+//    char * buff; // buffer
+//    int fd;      // file descrr.
+//    int size;    // size of buff
+//    int bp;      // current pos. in buff
+//    int end;     // last position in buff
+//};
+
+//typedef struct s_buff_s * s_buff;
+
+#define S_BUFF_LEN 4096
+
+s_buff s_open(int fd)
+{
+  s_buff F=(s_buff)omAlloc0(sizeof(*F));
+  F->fd=fd;
+  F->buff=(char*)omAlloc(S_BUFF_LEN);
+  return F;
+}
+
+s_buff s_open_by_name(const char *n)
+{
+  int fd=si_open(n,O_RDONLY);
+  return s_open(fd);
+}
+
+int    s_free(s_buff &F)
+{
+  if (F!=NULL)
+  {
+    omFreeSize(F->buff,S_BUFF_LEN);
+    omFreeSize(F,sizeof(*F));
+    F=NULL;
+  }
+  return 0;
+}
+
+int    s_close(s_buff &F)
+{
+  if (F!=NULL)
+  {
+    int r=close(F->fd);
+    return r;
+  }
+  return 0;
+}
+
+int s_getc(s_buff F)
+{
+  if (F==NULL)
+  {
+    printf("link closed");
+    return 0;
+  }
+  if (F->bp>=F->end)
+  {
+    memset(F->buff,0,S_BUFF_LEN); /*debug*/
+    int r=si_read(F->fd,F->buff,S_BUFF_LEN);
+    if (r<=0)
+    {
+      F->is_eof=1;
+      return -1;
+    }
+    else
+    {
+      F->end=r-1;
+      F->bp=0;
+      return F->buff[0];
+    }
+  }
+  /*else*/
+  F->bp++;
+  return F->buff[F->bp];
+}
+int s_isready(s_buff F)
+{
+  if (F==NULL)
+  {
+    printf("link closed");
+    return 0;
+  }
+  if (F->bp>=F->end) return 0;
+  int p=F->bp+1;
+  while((p<F->end)&&(F->buff[p]<=' ')) p++;
+  if (p>=F->end) return 0;
+  return 1;
+}
+
+void s_ungetc(int c, s_buff F)
+{
+  if (F==NULL)
+  {
+    printf("link closed");
+  }
+  else if (F->bp>=0)
+  {
+    F->buff[F->bp]=c;
+    F->bp--;
+  }
+}
+
+int s_readint(s_buff F)
+{
+  if (F==NULL)
+  {
+    printf("link closed");
+    return 0;
+  }
+  char c;
+  int neg=1;
+  int r=0;
+  //int digit=0;
+  do
+  {
+    c=s_getc(F);
+  } while((!F->is_eof) && (c<=' '));
+  if (c=='-') { neg=-1; c=s_getc(F); }
+  while(isdigit(c))
+  {
+    //digit++;
+    r=r*10+(c-'0');
+    c=s_getc(F);
+  }
+  s_ungetc(c,F);
+  //if (digit==0) { printf("unknown char %c(%d)\n",c,c); /*debug*/
+  //                printf("buffer:%s\np=%d,e=%d\n",F->buff,F->bp,F->end);fflush(stdout); } /*debug*/
+  return r*neg;
+}
+
+long s_readlong(s_buff F)
+{
+  if (F==NULL)
+  {
+    printf("link closed");
+    return 0;
+  }
+  char c;
+  long neg=1;
+  long r=0;
+  //int digit=0;
+  do
+  {
+    c=s_getc(F);
+  } while((!F->is_eof) && (c<=' '));
+  if (c=='-') { neg=-1; c=s_getc(F); }
+  while(isdigit(c))
+  {
+    //digit++;
+    r=r*10+(c-'0');
+    c=s_getc(F);
+  }
+  s_ungetc(c,F);
+  //if (digit==0) { printf("unknown char %c(%d)\n",c,c); /*debug*/
+  //                printf("buffer:%s\np=%d,e=%d\n",F->buff,F->bp,F->end);fflush(stdout); } /*debug*/
+  return r*neg;
+}
+
+int s_readbytes(char *buff,int len, s_buff F)
+{
+  if (F==NULL)
+  {
+    printf("link closed");
+    return 0;
+  }
+  int i=0;
+  while((!F->is_eof)&&(i<len))
+  {
+    buff[i]=s_getc(F);
+    i++;
+  }
+  return i;
+}
+
+void s_readmpz(s_buff F, mpz_t a)
+{
+  if (F==NULL)
+  {
+    printf("link closed");
+    return;
+  }
+  mpz_set_ui(a,0);
+  char c;
+  int neg=1;
+  do
+  {
+    c=s_getc(F);
+  } while((!F->is_eof) && (c<=' '));
+  if (c=='-') { neg=-1; c=s_getc(F); }
+  while(isdigit(c))
+  {
+    mpz_mul_ui(a,a,10);
+    mpz_add_ui(a,a,(c-'0'));
+    c=s_getc(F);
+  }
+  s_ungetc(c,F);
+  if (neg==-1) mpz_neg(a,a);
+}
+
+void s_readmpz_base(s_buff F, mpz_ptr a, int base)
+{
+  if (F==NULL)
+  {
+    printf("link closed");
+    return;
+  }
+  mpz_set_ui(a,0);
+  char c;
+  int neg=1;
+  do
+  {
+    c=s_getc(F);
+  } while((!F->is_eof) && (c<=' '));
+  if (c=='-') { neg=-1; c=s_getc(F); }
+  char *str=(char*)omAlloc0(128);
+  int str_l=128;
+  int str_p=0;
+  while(c>' ')
+  {
+    if ((isdigit(c))
+    || ((c>='a') && (c<='z'))
+    || ((c>='A') && (c<='Z')))
+    {
+      str[str_p]=c;
+      str_p++;
+    }
+    else
+    {
+      s_ungetc(c,F);
+      break;
+    }
+    if (str_p>=str_l)
+    {
+      str_l=str_l*2;
+      str=(char*)omRealloc0(str,str_l);
+    }
+    c=s_getc(F);
+  }
+  mpz_set_str(a,str,base);
+  omFreeSize(str,str_l);
+  if (neg==-1) mpz_neg(a,a);
+}
+int s_iseof(s_buff F)
+{
+  if (F!=NULL) return F->is_eof;
+  else         return 1;
+}
+
diff --git a/libpolys/reporter/s_buff.h b/libpolys/reporter/s_buff.h
new file mode 100644
index 0000000..39fb8fb
--- /dev/null
+++ b/libpolys/reporter/s_buff.h
@@ -0,0 +1,33 @@
+#ifndef S_BUFFIO_H
+#define S_BUFFIO_H
+
+#include<signal.h>
+#include<gmp.h>
+
+struct s_buff_s
+{
+    char * buff; // buffer
+    int fd;      // file descrr.
+    int bp;      // current pos. in buff (of the last read char)
+    int end;     // last position in buff
+    int is_eof;
+};
+
+typedef struct s_buff_s * s_buff;
+
+s_buff s_open(int fd);
+s_buff s_open_by_name(const char *n);
+int    s_free(s_buff &f);
+int    s_close(s_buff &f);
+
+int s_getc(s_buff F);
+void s_ungetc(int c, s_buff F);
+
+int s_readint(s_buff F);
+long s_readlong(s_buff F);
+int s_readbytes(char *buff,int len, s_buff F);
+void s_readmpz(s_buff F, mpz_ptr a);
+void s_readmpz_base(s_buff F, mpz_ptr a, int base);
+int s_isready(s_buff F);
+int s_iseof(s_buff F);
+#endif
diff --git a/libpolys/reporter/si_signals.h b/libpolys/reporter/si_signals.h
new file mode 100644
index 0000000..f64aacb
--- /dev/null
+++ b/libpolys/reporter/si_signals.h
@@ -0,0 +1,201 @@
+/*****************************************
+*  Computer Algebra System SINGULAR      *
+*****************************************/
+/*
+* ABSTRACT: wrappijng signal-interuptable system calls
+* AUTHOR: Alexander Dreyer, The PolyBoRi Team, 2013
+*/
+
+#include <signal.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include <unistd.h>
+#include <sys/uio.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/socket.h>
+#include <time.h>
+#include <stdio.h>
+#include <semaphore.h>
+#include <stdarg.h>
+
+#ifndef SINGULAR_SI_SIGNALS_H
+#define SINGULAR_SI_SIGNALS_H
+
+#define SI_EINTR_SAVE_FUNC_TEMPLATE(return_type, newfunc, func, decl, args, err_domain) \
+static inline return_type newfunc decl   \
+{                                        \
+  int res = -1;	                         \
+  do                                     \
+  {                                      \
+    res = func args;		         \
+  } while((res err_domain) && (errno == EINTR));\
+  return res;                            \
+}
+
+#define SI_EINTR_SAVE_FUNC(return_type, func, decl, args) \
+  SI_EINTR_SAVE_FUNC_TEMPLATE(return_type, si_##func, func, decl, args, < 0)
+
+#define SI_EINTR_SAVE_SCANF(return_type, func, decl, args) \
+  SI_EINTR_SAVE_FUNC_TEMPLATE(return_type, si_##func, func, decl, args, == EOF)
+
+SI_EINTR_SAVE_FUNC(int, select,
+                   (int nfds, fd_set *readfds, fd_set *writefds,
+                    fd_set *exceptfds, struct timeval *timeout),
+                   (nfds,readfds, writefds, exceptfds, timeout)
+                   )
+
+SI_EINTR_SAVE_FUNC(pid_t, wait, (int *status), (status))
+SI_EINTR_SAVE_FUNC(pid_t, waitpid, (pid_t pid, int *status, int options),
+                   (pid, status, options))
+
+//SI_EINTR_SAVE_FUNC(int, waitid,
+//                   (idtype_t idtype, id_t id, siginfo_t *infop, int options),
+//                   (idtype, id, infop, options))
+
+SI_EINTR_SAVE_FUNC(ssize_t,  read, (int fd, void *buf, size_t count),
+                   (fd, buf, count))
+
+
+SI_EINTR_SAVE_FUNC(ssize_t, readv,
+                   (int fd, const struct iovec *iov, int iovcnt),
+                   (fd, iov,iovcnt))
+
+SI_EINTR_SAVE_FUNC(ssize_t, write, (int fd, const void *buf, size_t count),
+                   (fd, buf, count))
+
+SI_EINTR_SAVE_FUNC(ssize_t, writev, (int fd, const struct iovec *iov, int iovcnt),
+                   (fd, iov, iovcnt) )
+
+SI_EINTR_SAVE_FUNC_TEMPLATE(int, si_open1, open, (const char *pathname, int flags),
+                            (pathname, flags), < 0)
+SI_EINTR_SAVE_FUNC_TEMPLATE(int, si_open2, open,
+                            (const char *pathname, int flags, mode_t mode),
+                            (pathname, flags, mode), < 0)
+
+/* Enulate overloading usung preprocessor (we need to be C-compatible) */
+#define SI_GET_FIFTH(_4,_3, _2, _1, N, ...) N
+#define si_open(...) SI_GET_FIFTH(X,##__VA_ARGS__, si_open2, si_open1)(__VA_ARGS__)
+
+SI_EINTR_SAVE_FUNC(int, creat, (const char *pathname, mode_t mode),
+                   (pathname, mode))
+
+
+SI_EINTR_SAVE_FUNC(int, close, (int fd), (fd))
+
+SI_EINTR_SAVE_FUNC(int, accept,
+                   (int sockfd, struct sockaddr *addr, socklen_t *addrlen),
+                   (sockfd, addr, addrlen))
+
+SI_EINTR_SAVE_FUNC(int, connect,
+                   (int sockfd, const struct sockaddr *addr, socklen_t addrlen),
+                   (sockfd, addr, addrlen))
+
+/* @note: We respect that the user may explictely deactivate the
+ * restart feature by setting the second argumetn to NULL.
+ */
+static inline int
+si_nanosleep(const struct timespec *req, struct timespec *rem) {
+
+  int res = -1;
+  do
+  {
+    res = nanosleep(req, rem);
+  } while((rem != NULL) && (res < 0) && (errno == EINTR));
+  return res;
+}
+
+static inline unsigned int
+si_sleep(unsigned int seconds)
+{
+  do
+  {
+    seconds = sleep(seconds);
+  } while(seconds != 0);
+  return 0;
+}
+
+SI_EINTR_SAVE_FUNC(int, dup, (int oldfd), (oldfd))
+SI_EINTR_SAVE_FUNC(int, dup2, (int oldfd, int newfd), (oldfd, newfd))
+//SI_EINTR_SAVE_FUNC(int, dup3, (int oldfd, int newfd, int flags),
+//		   (oldfd, newfd, flags))
+
+SI_EINTR_SAVE_FUNC(int, unlink, (const char *pathname), (pathname))
+
+SI_EINTR_SAVE_SCANF(int, vscanf,
+		   (const char *format, va_list ap),
+		   (format, ap))
+
+static inline
+int si_scanf(const char *format, ...)
+{
+  va_list argptr;
+  va_start(argptr, format);
+  int res = si_vscanf(format, argptr);
+  va_end(argptr);
+  return res;
+}
+
+SI_EINTR_SAVE_SCANF(int, vfscanf,
+		   (FILE *stream, const char *format, va_list ap),
+		   (stream, format, ap))
+
+static inline int
+si_fscanf(FILE *stream, const char *format, ...)
+{
+  va_list argptr;
+  va_start(argptr, format);
+  int res = si_vfscanf(stream, format, argptr);
+  va_end(argptr);
+  return res;
+}
+
+SI_EINTR_SAVE_SCANF(int, vsscanf,
+		   (const char *str, const char *format, va_list ap),
+		   (str, format, ap))
+
+static inline int
+si_sscanf(const char *str, const char *format, ...)
+{
+  va_list argptr;
+  va_start(argptr, format);
+  int res = si_vsscanf(str, format, argptr);
+  va_end(argptr);
+  return res;
+}
+
+SI_EINTR_SAVE_FUNC(int, stat, (const char *path, struct stat *buf),
+                   (path, buf))
+SI_EINTR_SAVE_FUNC(int, fstat, (int fd, struct stat *buf),
+                   (fd, buf))
+SI_EINTR_SAVE_FUNC(int, lstat, (const char *path, struct stat *buf),
+                   (path, buf))
+
+
+SI_EINTR_SAVE_FUNC(int, sigaction,
+                   (int signum, const struct sigaction *act,
+                    struct sigaction *oldact),
+                   (signum, act, oldact))
+
+
+#ifdef HAVE_SIGINTERRUPT
+SI_EINTR_SAVE_FUNC(int, siginterrupt, (int sig, int flag),
+                   (sig, flag))
+#else
+#define si_siginterrupt(arg1, arg2)
+#endif
+
+
+SI_EINTR_SAVE_FUNC(int, sem_wait, (sem_t *sem), (sem))
+SI_EINTR_SAVE_FUNC(int, sem_trywait, (sem_t *sem), (sem))
+//SI_EINTR_SAVE_FUNC(int, sem_timedwait,
+//                   (sem_t *sem, const struct timespec *abs_timeout),
+//                   (sem, abs_timeout))
+
+
+#undef SI_EINTR_SAVE_FUNC
+
+
+#endif /* SINGULAR_SI_SIGNALS_H */
diff --git a/libpolys/tests/Makefile.am b/libpolys/tests/Makefile.am
new file mode 100644
index 0000000..6acc6a3
--- /dev/null
+++ b/libpolys/tests/Makefile.am
@@ -0,0 +1,66 @@
+ACLOCAL_AMFLAGS = -I ../../m4
+
+AM_CPPFLAGS = -I${top_srcdir} -I${top_builddir} \
+${FACTORY_INCLUDES} ${RESOURCES_INCLUDES} ${OMALLOC_INCLUDES} \
+${FLINT_CFLAGS} ${NTL_CFLAGS} ${GMP_CFLAGS}
+
+TESTS = simple_test \
+    coeffs_test \
+    polys_test \
+    rings_test
+
+check_PROGRAMS = $(TESTS)
+
+nodist_simple_test_SOURCES = simple_test_runner.cpp
+
+nodist_coeffs_test_SOURCES = coeffs_test_runner.cpp
+nodist_polys_test_SOURCES = polys_test_runner.cpp
+nodist_rings_test_SOURCES = rings_test_runner.cpp
+
+coeffs_test_LDADD = ${top_builddir}/coeffs/libcoeffs.la \
+${top_builddir}/reporter/libreporter.la ${top_builddir}/misc/libmisc.la \
+$(FACTORY_LIBS) $(RESOURCES_LIBS) $(OMALLOC_LIBS) \
+$(FLINT_LIBS) $(GMP_LIBS) $(NTL_LIBS)
+
+polys_test_LDADD = ${top_builddir}/polys/libpolys.la $(coeffs_test_LDADD)
+rings_test_LDADD = $(polys_test_LDADD)
+
+BUILT_SOURCES = gftables MOD \
+        simple_test_runner.cpp coeffs_test_runner.cpp polys_test_runner.cpp rings_test_runner.cpp
+
+gftables: ${top_srcdir}/../factory/gftables
+	ln -snf ${top_srcdir}/../factory/gftables ${builddir}
+
+MOD:
+	if [ -d "${top_builddir}/libpolys/polys/.libs" ]; then \
+	  ln -snf ${top_builddir}/libpolys/polys/.libs/ ${abs_builddir}/MOD; \
+	fi
+
+# How to generate *_runner.cpp
+simple_test_runner.cpp: simple_test.h
+	${srcdir}/cxxtestgen.pl --no-eh -o $@ --error-printer ${srcdir}/simple_test.h
+
+coeffs_test_runner.cpp: coeffs_test.h
+	${srcdir}/cxxtestgen.pl --no-eh -o $@ --error-printer ${srcdir}/coeffs_test.h
+
+polys_test_runner.cpp: polys_test.h
+	${srcdir}/cxxtestgen.pl --no-eh -o $@ --error-printer ${srcdir}/polys_test.h
+
+rings_test_runner.cpp: rings_test.h
+	${srcdir}/cxxtestgen.pl --no-eh -o $@ --error-printer ${srcdir}/rings_test.h
+
+CLEANFILES = $(BUILT_SOURCES)
+
+EXTRA_DIST = cxxtestgen.pl simple_test.h coeffs_test.h polys_test.h rings_test.h common.h \
+    cxxtest/Descriptions.h       cxxtest/ParenPrinter.h      cxxtest/TestListener.h	\
+    cxxtest/DummyDescriptions.h  cxxtest/QtGui.h             cxxtest/TestRunner.h	\
+    cxxtest/ErrorFormatter.h     cxxtest/RealDescriptions.h  cxxtest/TestSuite.h	\
+    cxxtest/ErrorPrinter.h       cxxtest/SelfTest.h          cxxtest/TestTracker.h	\
+    cxxtest/Flags.h              cxxtest/StdHeaders.h        cxxtest/ValueTraits.h	\
+    cxxtest/GlobalFixture.h      cxxtest/StdioFilePrinter.h  cxxtest/Win32Gui.h		\
+    cxxtest/Gui.h                cxxtest/StdioPrinter.h      cxxtest/X11Gui.h		\
+    cxxtest/LinkedList.h         cxxtest/StdValueTraits.h    cxxtest/YesNoRunner.h	\
+    cxxtest/Mock.h               cxxtest/TeeListener.h					\
+    cxxtest/Descriptions.cpp     cxxtest/LinkedList.cpp      cxxtest/TestSuite.cpp	\
+    cxxtest/DummyDescriptions.cpp cxxtest/RealDescriptions.cpp  cxxtest/TestTracker.cpp \
+    cxxtest/GlobalFixture.cpp    cxxtest/Root.cpp            cxxtest/ValueTraits.cpp
diff --git a/libpolys/tests/Makefile.in b/libpolys/tests/Makefile.in
new file mode 100644
index 0000000..fa693cc
--- /dev/null
+++ b/libpolys/tests/Makefile.in
@@ -0,0 +1,1112 @@
+# Makefile.in generated by automake 1.13.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 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@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+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@
+TESTS = simple_test$(EXEEXT) coeffs_test$(EXEEXT) polys_test$(EXEEXT) \
+	rings_test$(EXEEXT)
+check_PROGRAMS = $(am__EXEEXT_1)
+subdir = tests
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/../build-aux/depcomp \
+	$(top_srcdir)/../build-aux/test-driver
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/../m4/ax_append_compile_flags.m4 \
+	$(top_srcdir)/../m4/ax_append_flag.m4 \
+	$(top_srcdir)/../m4/ax_append_link_flags.m4 \
+	$(top_srcdir)/../m4/ax_check_compile_flag.m4 \
+	$(top_srcdir)/../m4/ax_check_link_flag.m4 \
+	$(top_srcdir)/../m4/ax_cxx_gcc_abi_demangle.m4 \
+	$(top_srcdir)/../m4/ax_prefix_config_h.m4 \
+	$(top_srcdir)/../m4/cpu-check.m4 $(top_srcdir)/../m4/flags.m4 \
+	$(top_srcdir)/../m4/flint-check.m4 \
+	$(top_srcdir)/../m4/gmp-check.m4 \
+	$(top_srcdir)/../m4/libtool.m4 \
+	$(top_srcdir)/../m4/ltoptions.m4 \
+	$(top_srcdir)/../m4/ltsugar.m4 \
+	$(top_srcdir)/../m4/ltversion.m4 \
+	$(top_srcdir)/../m4/lt~obsolete.m4 \
+	$(top_srcdir)/../m4/ntl-check.m4 \
+	$(top_srcdir)/../m4/options.m4 $(top_srcdir)/../m4/p-procs.m4 \
+	$(top_srcdir)/configure.ac
+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__EXEEXT_1 = simple_test$(EXEEXT) coeffs_test$(EXEEXT) \
+	polys_test$(EXEEXT) rings_test$(EXEEXT)
+nodist_coeffs_test_OBJECTS = coeffs_test_runner.$(OBJEXT)
+coeffs_test_OBJECTS = $(nodist_coeffs_test_OBJECTS)
+am__DEPENDENCIES_1 =
+coeffs_test_DEPENDENCIES = ${top_builddir}/coeffs/libcoeffs.la \
+	${top_builddir}/reporter/libreporter.la \
+	${top_builddir}/misc/libmisc.la $(am__DEPENDENCIES_1) \
+	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+	$(am__DEPENDENCIES_1)
+AM_V_lt = $(am__v_lt_ at AM_V@)
+am__v_lt_ = $(am__v_lt_ at AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 = 
+nodist_polys_test_OBJECTS = polys_test_runner.$(OBJEXT)
+polys_test_OBJECTS = $(nodist_polys_test_OBJECTS)
+am__DEPENDENCIES_2 = ${top_builddir}/coeffs/libcoeffs.la \
+	${top_builddir}/reporter/libreporter.la \
+	${top_builddir}/misc/libmisc.la $(am__DEPENDENCIES_1) \
+	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+	$(am__DEPENDENCIES_1)
+polys_test_DEPENDENCIES = ${top_builddir}/polys/libpolys.la \
+	$(am__DEPENDENCIES_2)
+nodist_rings_test_OBJECTS = rings_test_runner.$(OBJEXT)
+rings_test_OBJECTS = $(nodist_rings_test_OBJECTS)
+am__DEPENDENCIES_3 = ${top_builddir}/polys/libpolys.la \
+	$(am__DEPENDENCIES_2)
+rings_test_DEPENDENCIES = $(am__DEPENDENCIES_3)
+nodist_simple_test_OBJECTS = simple_test_runner.$(OBJEXT)
+simple_test_OBJECTS = $(nodist_simple_test_OBJECTS)
+simple_test_LDADD = $(LDADD)
+AM_V_P = $(am__v_P_ at AM_V@)
+am__v_P_ = $(am__v_P_ at AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_ at AM_V@)
+am__v_GEN_ = $(am__v_GEN_ at AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_ at AM_V@)
+am__v_at_ = $(am__v_at_ at AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+DEFAULT_INCLUDES = -I. at am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/../build-aux/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \
+	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+	$(AM_CXXFLAGS) $(CXXFLAGS)
+AM_V_CXX = $(am__v_CXX_ at AM_V@)
+am__v_CXX_ = $(am__v_CXX_ at AM_DEFAULT_V@)
+am__v_CXX_0 = @echo "  CXX     " $@;
+am__v_CXX_1 = 
+CXXLD = $(CXX)
+CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+	$(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CXXLD = $(am__v_CXXLD_ at AM_V@)
+am__v_CXXLD_ = $(am__v_CXXLD_ at AM_DEFAULT_V@)
+am__v_CXXLD_0 = @echo "  CXXLD   " $@;
+am__v_CXXLD_1 = 
+SOURCES = $(nodist_coeffs_test_SOURCES) $(nodist_polys_test_SOURCES) \
+	$(nodist_rings_test_SOURCES) $(nodist_simple_test_SOURCES)
+DIST_SOURCES =
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors_dummy = \
+  mgn= red= grn= lgn= blu= brg= std=; \
+  am__color_tests=no
+am__tty_colors = { \
+  $(am__tty_colors_dummy); \
+  if test "X$(AM_COLOR_TESTS)" = Xno; then \
+    am__color_tests=no; \
+  elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+    am__color_tests=yes; \
+  elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+    am__color_tests=yes; \
+  fi; \
+  if test $$am__color_tests = yes; then \
+    red=''; \
+    grn=''; \
+    lgn=''; \
+    blu=''; \
+    mgn=''; \
+    brg=''; \
+    std=''; \
+  fi; \
+}
+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__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
+am__recheck_rx = ^[ 	]*:recheck:[ 	]*
+am__global_test_result_rx = ^[ 	]*:global-test-result:[ 	]*
+am__copy_in_global_log_rx = ^[ 	]*:copy-in-global-log:[ 	]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+  recheck = 1; \
+  while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+    { \
+      if (rc < 0) \
+        { \
+          if ((getline line2 < ($$0 ".log")) < 0) \
+	    recheck = 0; \
+          break; \
+        } \
+      else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+        { \
+          recheck = 0; \
+          break; \
+        } \
+      else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+        { \
+          break; \
+        } \
+    }; \
+  if (recheck) \
+    print $$0; \
+  close ($$0 ".trs"); \
+  close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+  print "fatal: making $@: " msg | "cat >&2"; \
+  exit 1; \
+} \
+function rst_section(header) \
+{ \
+  print header; \
+  len = length(header); \
+  for (i = 1; i <= len; i = i + 1) \
+    printf "="; \
+  printf "\n\n"; \
+} \
+{ \
+  copy_in_global_log = 1; \
+  global_test_result = "RUN"; \
+  while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+    { \
+      if (rc < 0) \
+         fatal("failed to read from " $$0 ".trs"); \
+      if (line ~ /$(am__global_test_result_rx)/) \
+        { \
+          sub("$(am__global_test_result_rx)", "", line); \
+          sub("[ 	]*$$", "", line); \
+          global_test_result = line; \
+        } \
+      else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+        copy_in_global_log = 0; \
+    }; \
+  if (copy_in_global_log) \
+    { \
+      rst_section(global_test_result ": " $$0); \
+      while ((rc = (getline line < ($$0 ".log"))) != 0) \
+      { \
+        if (rc < 0) \
+          fatal("failed to read from " $$0 ".log"); \
+        print line; \
+      }; \
+      printf "\n"; \
+    }; \
+  close ($$0 ".trs"); \
+  close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/   &   /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this.  Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+  --color-tests "$$am__color_tests" \
+  --enable-hard-errors "$$am__enable_hard_errors" \
+  --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test.  Creates the
+# directory for the log if needed.  Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log.  Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT.  Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup);					\
+$(am__vpath_adj_setup) $(am__vpath_adj)			\
+$(am__tty_colors);					\
+srcdir=$(srcdir); export srcdir;			\
+case "$@" in						\
+  */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;;	\
+    *) am__odir=.;; 					\
+esac;							\
+test "x$$am__odir" = x"." || test -d "$$am__odir" 	\
+  || $(MKDIR_P) "$$am__odir" || exit $$?;		\
+if test -f "./$$f"; then dir=./;			\
+elif test -f "$$f"; then dir=;				\
+else dir="$(srcdir)/"; fi;				\
+tst=$$dir$$f; log='$@'; 				\
+if test -n '$(DISABLE_HARD_ERRORS)'; then		\
+  am__enable_hard_errors=no; 				\
+else							\
+  am__enable_hard_errors=yes; 				\
+fi; 							\
+case " $(XFAIL_TESTS) " in				\
+  *[\ \	]$$f[\ \	]* | *[\ \	]$$dir$$f[\ \	]*) \
+    am__expect_failure=yes;;				\
+  *)							\
+    am__expect_failure=no;;				\
+esac; 							\
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed).  The result is saved in the shell variable
+# '$bases'.  This honors runtime overriding of TESTS and TEST_LOGS.  Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+  bases='$(TEST_LOGS)'; \
+  bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+  bases=`echo $$bases`
+RECHECK_LOGS = $(TEST_LOGS)
+AM_RECURSIVE_TARGETS = check recheck
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_DRIVER = $(SHELL) $(top_srcdir)/../build-aux/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+  case '$@' in \
+    */*) \
+      case '$*' in \
+        */*) b='$*';; \
+          *) b=`echo '$@' | sed 's/\.log$$//'`; \
+       esac;; \
+    *) \
+      b='$*';; \
+  esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT at .log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/../build-aux/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+	$(TEST_LOG_FLAGS)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+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@
+FACTORY_INCLUDES = @FACTORY_INCLUDES@
+FACTORY_LIBS = @FACTORY_LIBS@
+FGREP = @FGREP@
+FLINT_CFLAGS = @FLINT_CFLAGS@
+FLINT_HOME = @FLINT_HOME@
+FLINT_LIBS = @FLINT_LIBS@
+GMP_CFLAGS = @GMP_CFLAGS@
+GMP_HOME = @GMP_HOME@
+GMP_LIBS = @GMP_LIBS@
+GMP_VERSION = @GMP_VERSION@
+GREP = @GREP@
+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@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NTL_CFLAGS = @NTL_CFLAGS@
+NTL_LIBS = @NTL_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OMALLOC_INCLUDES = @OMALLOC_INCLUDES@
+OMALLOC_LIBS = @OMALLOC_LIBS@
+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@
+PKG_REQUIRE = @PKG_REQUIRE@
+POLYMAKE_CXXFLAGS = @POLYMAKE_CXXFLAGS@
+RANLIB = @RANLIB@
+RESOURCES_INCLUDES = @RESOURCES_INCLUDES@
+RESOURCES_LIBS = @RESOURCES_LIBS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SINGULAR_CFLAGS = @SINGULAR_CFLAGS@
+SI_CPU_I386 = @SI_CPU_I386@
+SI_CPU_IA64 = @SI_CPU_IA64@
+SI_CPU_PPC = @SI_CPU_PPC@
+SI_CPU_SPARC = @SI_CPU_SPARC@
+SI_CPU_X86_64 = @SI_CPU_X86_64@
+STRIP = @STRIP@
+USEPPROCSDYNAMICLD = @USEPPROCSDYNAMICLD@
+USEPPROCSDYNAMICLDFLAGS = @USEPPROCSDYNAMICLDFLAGS@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+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@
+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@
+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@
+ACLOCAL_AMFLAGS = -I ../../m4
+AM_CPPFLAGS = -I${top_srcdir} -I${top_builddir} \
+${FACTORY_INCLUDES} ${RESOURCES_INCLUDES} ${OMALLOC_INCLUDES} \
+${FLINT_CFLAGS} ${NTL_CFLAGS} ${GMP_CFLAGS}
+
+nodist_simple_test_SOURCES = simple_test_runner.cpp
+nodist_coeffs_test_SOURCES = coeffs_test_runner.cpp
+nodist_polys_test_SOURCES = polys_test_runner.cpp
+nodist_rings_test_SOURCES = rings_test_runner.cpp
+coeffs_test_LDADD = ${top_builddir}/coeffs/libcoeffs.la \
+${top_builddir}/reporter/libreporter.la ${top_builddir}/misc/libmisc.la \
+$(FACTORY_LIBS) $(RESOURCES_LIBS) $(OMALLOC_LIBS) \
+$(FLINT_LIBS) $(GMP_LIBS) $(NTL_LIBS)
+
+polys_test_LDADD = ${top_builddir}/polys/libpolys.la $(coeffs_test_LDADD)
+rings_test_LDADD = $(polys_test_LDADD)
+BUILT_SOURCES = gftables MOD \
+        simple_test_runner.cpp coeffs_test_runner.cpp polys_test_runner.cpp rings_test_runner.cpp
+
+CLEANFILES = $(BUILT_SOURCES)
+EXTRA_DIST = cxxtestgen.pl simple_test.h coeffs_test.h polys_test.h rings_test.h common.h \
+    cxxtest/Descriptions.h       cxxtest/ParenPrinter.h      cxxtest/TestListener.h	\
+    cxxtest/DummyDescriptions.h  cxxtest/QtGui.h             cxxtest/TestRunner.h	\
+    cxxtest/ErrorFormatter.h     cxxtest/RealDescriptions.h  cxxtest/TestSuite.h	\
+    cxxtest/ErrorPrinter.h       cxxtest/SelfTest.h          cxxtest/TestTracker.h	\
+    cxxtest/Flags.h              cxxtest/StdHeaders.h        cxxtest/ValueTraits.h	\
+    cxxtest/GlobalFixture.h      cxxtest/StdioFilePrinter.h  cxxtest/Win32Gui.h		\
+    cxxtest/Gui.h                cxxtest/StdioPrinter.h      cxxtest/X11Gui.h		\
+    cxxtest/LinkedList.h         cxxtest/StdValueTraits.h    cxxtest/YesNoRunner.h	\
+    cxxtest/Mock.h               cxxtest/TeeListener.h					\
+    cxxtest/Descriptions.cpp     cxxtest/LinkedList.cpp      cxxtest/TestSuite.cpp	\
+    cxxtest/DummyDescriptions.cpp cxxtest/RealDescriptions.cpp  cxxtest/TestTracker.cpp \
+    cxxtest/GlobalFixture.cpp    cxxtest/Root.cpp            cxxtest/ValueTraits.cpp
+
+all: $(BUILT_SOURCES)
+	$(MAKE) $(AM_MAKEFLAGS) all-am
+
+.SUFFIXES:
+.SUFFIXES: .cpp .lo .log .o .obj .test .test$(EXEEXT) .trs
+$(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) --foreign tests/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign tests/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-checkPROGRAMS:
+	@list='$(check_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
+
+coeffs_test$(EXEEXT): $(coeffs_test_OBJECTS) $(coeffs_test_DEPENDENCIES) $(EXTRA_coeffs_test_DEPENDENCIES) 
+	@rm -f coeffs_test$(EXEEXT)
+	$(AM_V_CXXLD)$(CXXLINK) $(coeffs_test_OBJECTS) $(coeffs_test_LDADD) $(LIBS)
+
+polys_test$(EXEEXT): $(polys_test_OBJECTS) $(polys_test_DEPENDENCIES) $(EXTRA_polys_test_DEPENDENCIES) 
+	@rm -f polys_test$(EXEEXT)
+	$(AM_V_CXXLD)$(CXXLINK) $(polys_test_OBJECTS) $(polys_test_LDADD) $(LIBS)
+
+rings_test$(EXEEXT): $(rings_test_OBJECTS) $(rings_test_DEPENDENCIES) $(EXTRA_rings_test_DEPENDENCIES) 
+	@rm -f rings_test$(EXEEXT)
+	$(AM_V_CXXLD)$(CXXLINK) $(rings_test_OBJECTS) $(rings_test_LDADD) $(LIBS)
+
+simple_test$(EXEEXT): $(simple_test_OBJECTS) $(simple_test_DEPENDENCIES) $(EXTRA_simple_test_DEPENDENCIES) 
+	@rm -f simple_test$(EXEEXT)
+	$(AM_V_CXXLD)$(CXXLINK) $(simple_test_OBJECTS) $(simple_test_LDADD) $(LIBS)
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/coeffs_test_runner.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/polys_test_runner.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/rings_test_runner.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/simple_test_runner.Po at am__quote@
+
+.cpp.o:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+ at am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXXCOMPILE) -c -o $@ $<
+
+.cpp.obj:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+ at am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.cpp.lo:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+ at am__fastdepCXX_TRUE@	$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LTCXXCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	$(am__define_uniq_tagged_files); \
+	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-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	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"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'.  Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+	rm -f $< $@
+	$(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+	@:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+	@$(am__set_TESTS_bases); \
+	am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+	redo_bases=`for i in $$bases; do \
+	              am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+	            done`; \
+	if test -n "$$redo_bases"; then \
+	  redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+	  redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+	  if $(am__make_dryrun); then :; else \
+	    rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+	  fi; \
+	fi; \
+	if test -n "$$am__remaking_logs"; then \
+	  echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+	       "recursion detected" >&2; \
+	else \
+	  am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+	fi; \
+	if $(am__make_dryrun); then :; else \
+	  st=0;  \
+	  errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+	  for i in $$redo_bases; do \
+	    test -f $$i.trs && test -r $$i.trs \
+	      || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+	    test -f $$i.log && test -r $$i.log \
+	      || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+	  done; \
+	  test $$st -eq 0 || exit 1; \
+	fi
+	@$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+	ws='[ 	]'; \
+	results=`for b in $$bases; do echo $$b.trs; done`; \
+	test -n "$$results" || results=/dev/null; \
+	all=`  grep "^$$ws*:test-result:"           $$results | wc -l`; \
+	pass=` grep "^$$ws*:test-result:$$ws*PASS"  $$results | wc -l`; \
+	fail=` grep "^$$ws*:test-result:$$ws*FAIL"  $$results | wc -l`; \
+	skip=` grep "^$$ws*:test-result:$$ws*SKIP"  $$results | wc -l`; \
+	xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+	xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+	error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+	if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+	  success=true; \
+	else \
+	  success=false; \
+	fi; \
+	br='==================='; br=$$br$$br$$br$$br; \
+	result_count () \
+	{ \
+	    if test x"$$1" = x"--maybe-color"; then \
+	      maybe_colorize=yes; \
+	    elif test x"$$1" = x"--no-color"; then \
+	      maybe_colorize=no; \
+	    else \
+	      echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+	    fi; \
+	    shift; \
+	    desc=$$1 count=$$2; \
+	    if test $$maybe_colorize = yes && test $$count -gt 0; then \
+	      color_start=$$3 color_end=$$std; \
+	    else \
+	      color_start= color_end=; \
+	    fi; \
+	    echo "$${color_start}# $$desc $$count$${color_end}"; \
+	}; \
+	create_testsuite_report () \
+	{ \
+	  result_count $$1 "TOTAL:" $$all   "$$brg"; \
+	  result_count $$1 "PASS: " $$pass  "$$grn"; \
+	  result_count $$1 "SKIP: " $$skip  "$$blu"; \
+	  result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+	  result_count $$1 "FAIL: " $$fail  "$$red"; \
+	  result_count $$1 "XPASS:" $$xpass "$$red"; \
+	  result_count $$1 "ERROR:" $$error "$$mgn"; \
+	}; \
+	{								\
+	  echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" |	\
+	    $(am__rst_title);						\
+	  create_testsuite_report --no-color;				\
+	  echo;								\
+	  echo ".. contents:: :depth: 2";				\
+	  echo;								\
+	  for b in $$bases; do echo $$b; done				\
+	    | $(am__create_global_log);					\
+	} >$(TEST_SUITE_LOG).tmp || exit 1;				\
+	mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG);			\
+	if $$success; then						\
+	  col="$$grn";							\
+	 else								\
+	  col="$$red";							\
+	  test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG);		\
+	fi;								\
+	echo "$${col}$$br$${std}"; 					\
+	echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}";	\
+	echo "$${col}$$br$${std}"; 					\
+	create_testsuite_report --maybe-color;				\
+	echo "$$col$$br$$std";						\
+	if $$success; then :; else					\
+	  echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}";		\
+	  if test -n "$(PACKAGE_BUGREPORT)"; then			\
+	    echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}";	\
+	  fi;								\
+	  echo "$$col$$br$$std";					\
+	fi;								\
+	$$success || exit 1
+
+check-TESTS:
+	@list='$(RECHECK_LOGS)';           test -z "$$list" || rm -f $$list
+	@list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+	@test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+	@set +e; $(am__set_TESTS_bases); \
+	log_list=`for i in $$bases; do echo $$i.log; done`; \
+	trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+	log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+	$(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+	exit $$?;
+recheck: all $(check_PROGRAMS)
+	@test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+	@set +e; $(am__set_TESTS_bases); \
+	bases=`for i in $$bases; do echo $$i; done \
+	         | $(am__list_recheck_tests)` || exit 1; \
+	log_list=`for i in $$bases; do echo $$i.log; done`; \
+	log_list=`echo $$log_list`; \
+	$(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+	        am__force_recheck=am--force-recheck \
+	        TEST_LOGS="$$log_list"; \
+	exit $$?
+simple_test.log: simple_test$(EXEEXT)
+	@p='simple_test$(EXEEXT)'; \
+	b='simple_test'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+coeffs_test.log: coeffs_test$(EXEEXT)
+	@p='coeffs_test$(EXEEXT)'; \
+	b='coeffs_test'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+polys_test.log: polys_test$(EXEEXT)
+	@p='polys_test$(EXEEXT)'; \
+	b='polys_test'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+rings_test.log: rings_test$(EXEEXT)
+	@p='rings_test$(EXEEXT)'; \
+	b='rings_test'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+.test.log:
+	@p='$<'; \
+	$(am__set_b); \
+	$(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+ at am__EXEEXT_TRUE@.test$(EXEEXT).log:
+ at am__EXEEXT_TRUE@	@p='$<'; \
+ at am__EXEEXT_TRUE@	$(am__set_b); \
+ at am__EXEEXT_TRUE@	$(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ at am__EXEEXT_TRUE@	--log-file $$b.log --trs-file $$b.trs \
+ at am__EXEEXT_TRUE@	$(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ at am__EXEEXT_TRUE@	"$$tst" $(AM_TESTS_FD_REDIRECT)
+
+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_PROGRAMS)
+	$(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: $(BUILT_SOURCES)
+	$(MAKE) $(AM_MAKEFLAGS) check-am
+all-am: Makefile
+installdirs:
+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:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+	-test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+	-test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+	-test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+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-checkPROGRAMS 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-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: all check check-am install install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am clean \
+	clean-checkPROGRAMS clean-generic clean-libtool cscopelist-am \
+	ctags ctags-am 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 \
+	recheck tags tags-am uninstall uninstall-am
+
+
+gftables: ${top_srcdir}/../factory/gftables
+	ln -snf ${top_srcdir}/../factory/gftables ${builddir}
+
+MOD:
+	if [ -d "${top_builddir}/libpolys/polys/.libs" ]; then \
+	  ln -snf ${top_builddir}/libpolys/polys/.libs/ ${abs_builddir}/MOD; \
+	fi
+
+# How to generate *_runner.cpp
+simple_test_runner.cpp: simple_test.h
+	${srcdir}/cxxtestgen.pl --no-eh -o $@ --error-printer ${srcdir}/simple_test.h
+
+coeffs_test_runner.cpp: coeffs_test.h
+	${srcdir}/cxxtestgen.pl --no-eh -o $@ --error-printer ${srcdir}/coeffs_test.h
+
+polys_test_runner.cpp: polys_test.h
+	${srcdir}/cxxtestgen.pl --no-eh -o $@ --error-printer ${srcdir}/polys_test.h
+
+rings_test_runner.cpp: rings_test.h
+	${srcdir}/cxxtestgen.pl --no-eh -o $@ --error-printer ${srcdir}/rings_test.h
+
+# 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/libpolys/tests/coeffs_test.h b/libpolys/tests/coeffs_test.h
new file mode 100644
index 0000000..2d1483a
--- /dev/null
+++ b/libpolys/tests/coeffs_test.h
@@ -0,0 +1,510 @@
+
+
+
+#include <misc/auxiliary.h>
+#include <omalloc/omalloc.h>
+
+
+#include <reporter/reporter.h>
+#include <resources/feResource.h>
+
+#include <coeffs/coeffs.h>
+#include <coeffs/numbers.h>
+
+
+// the following headers are private...
+#include <coeffs/longrat.h>
+#include <coeffs/gnumpfl.h>
+#include <coeffs/gnumpc.h>
+#include <coeffs/shortfl.h>
+#include <coeffs/ffields.h>
+#include <coeffs/modulop.h>
+#include <coeffs/rmodulon.h>
+#include <coeffs/rmodulo2m.h>
+#include <coeffs/rintegers.h>
+
+
+#include "common.h"
+using namespace std;
+
+
+void TestSum(const coeffs r, const unsigned long N)
+{
+  clog << ( _2S("TEST: sum[0..") + _2S(N) + "]: ");
+  clog << endl;
+
+  assume( N > 0 ); // just for now...
+
+  const unsigned long ssss = (N * (N+1)) / 2;
+
+  number sum1 = n_Init(ssss, r);
+  clog<< "N*(N+1)/2 (int: " << ssss << "): "; PrintSized(sum1, r);
+
+  number s, ss, i, res;
+
+  s = n_Init(N  , r);
+  i = n_Init(N+1, r);
+  n_InpMult(s, i, r);
+  n_Delete(&i, r);
+
+  clog<< "N*(N+1): ("<< N*(N+1) << ")"; PrintSized(s, r);
+
+  i = n_Init(2, r);
+  clog<< "2: "; PrintSized(i, r);
+
+  if( !n_IsZero( i, r) )
+  {
+#ifdef HAVE_RINGS
+    TS_ASSERT( n_DivBy(s, i, r) );
+#endif
+
+    res = n_Div(s, i, r);
+
+    clog<< "N*(N+1)/2: "; PrintSized(res, r);
+
+
+    number d = n_Sub(res, sum1, r);
+    TS_ASSERT( n_IsZeroDivisor(d, r) );
+    n_Delete(&d, r);
+
+    if( n_GetChar(r) == 0 )
+    {
+      TS_ASSERT( n_Equal(sum1, res, r) );
+      TS_ASSERT( n_Equal(res, sum1, r) );
+    }
+  } else
+    TS_ASSERT_EQUALS( n_GetChar(r), 2);
+
+
+  n_Delete(&s, r);  n_Delete(&i, r);
+
+  n_Delete(&sum1, r); n_Delete(&res, r);
+
+
+  s = n_Init(0  , r);
+  ss = n_Init(0 , r);
+  for( int k = N; k >= 0; k-- )
+  {
+    i = n_Init(k, r);
+    n_InpAdd(s, i, r); // s += i
+
+    i = n_InpNeg(i, r);
+    n_InpAdd(ss, i, r); // ss -= i
+
+    n_Delete(&i, r);
+  }
+  clog<< "ss: "; PrintSized(ss, r);
+
+  ss = n_InpNeg(ss, r); // ss = -ss
+
+  clog<< "real sum    : "; PrintSized(s, r);
+  clog<< "real sum(--): "; PrintSized(ss, r);
+
+  TS_ASSERT( n_Equal(s, ss, r) );
+  TS_ASSERT( n_Equal(ss, s, r) );
+
+  n_Delete(&s, r);
+  n_Delete(&ss, r);
+
+  clog << ( " >>> TEST DONE!" );
+  clog << endl;
+
+}
+
+
+void TestArith(const coeffs r)
+{
+  clog << ("TEST: Simple Arithmetics: ");
+  clog << endl;
+
+  number two = n_Init(2, r);
+
+  number t = n_Init(1, r);
+  n_InpAdd(t, t, r);
+  TS_ASSERT( n_Equal(two, t, r) );
+  n_Delete(&t, r);
+
+  if( getCoeffType(r) == n_Q )
+  {
+    number t = n_Init(1, r);
+    n_InpAdd(t, t, r);
+    TS_ASSERT( n_Equal(two, t, r) );
+    n_Delete(&t, r);
+  }
+
+
+
+
+  const int N = 66666;
+
+  number a = n_Init(N, r);
+
+  clog<< "a: "; PrintSized(a, r);
+
+
+  clog<< "two: "; PrintSized(two, r);
+
+  number aa0 = n_Init(N*2, r);
+
+  number aa = n_Add(a, a, r);
+
+  clog<< "aa = a + a: "; PrintSized(aa, r);
+
+  number aa2 = n_Mult(a, two, r);
+
+  clog<< "aa2 = a * 2: "; PrintSized(aa2, r);
+
+  number aa1 = n_Mult(two, a, r);
+
+  clog<< "aa1 = 2 * a: "; PrintSized(aa1, r);
+
+  n_Delete(&a, r);
+  n_Delete(&two, r);
+
+
+  a = n_Sub( aa, aa1, r );
+
+  clog<< "a = aa - aa1: "; PrintSized(a, r);
+
+  TS_ASSERT( n_IsZero(a, r) );
+
+  n_Delete(&a, r);
+
+  a = n_Sub( aa, aa2, r );
+
+  clog<< "a = aa - aa2: "; PrintSized(a, r);
+
+  TS_ASSERT( n_IsZero(a, r) );
+
+  n_Delete(&a, r);
+
+
+  a = n_Sub( aa1, aa2, r );
+
+  clog<< "a = aa1 - aa2: "; PrintSized(a, r);
+
+  TS_ASSERT( n_IsZero(a, r) );
+
+  n_Delete(&a, r);
+
+
+
+  TS_ASSERT( n_Equal(aa, aa1, r) );
+  TS_ASSERT( n_Equal(aa, aa2, r) );
+  TS_ASSERT( n_Equal(aa1, aa2, r) );
+
+  TS_ASSERT( n_Equal(aa0, aa, r) );
+  TS_ASSERT( n_Equal(aa0, aa1, r) );
+  TS_ASSERT( n_Equal(aa0, aa2, r) );
+
+  n_Delete(&aa, r);
+  n_Delete(&aa1, r);
+  n_Delete(&aa2, r);
+
+  n_Delete(&aa0, r);
+
+  clog << ( " >>> TEST DONE!" );
+  clog << endl;
+
+}
+
+
+
+
+
+BOOLEAN Test(const n_coeffType type, void* p = NULLp)
+{
+
+  clog << endl;
+  clog << ( "----------------------- Testing coeffs: [" + _2S(type) +  ", " + _2S(p) + "]: -----------------------");
+  clog << endl;
+
+  const coeffs r = nInitChar( type, p );
+
+  if( r == NULLp )
+  {
+    clog << ( "Test: could not get this coeff. domain" );
+    return FALSE;
+  };
+
+  TS_ASSERT_DIFFERS( r->cfCoeffWrite, NULLp );
+
+  if( r->cfCoeffWrite != NULL )
+  {
+    clog << "Coeff-domain: "  << endl;
+    n_CoeffWrite(r); PrintLn();
+  }
+
+  if (n_NumberOfParameters(r) > 0)
+  {
+    number z = n_Param(1, r); // also any integer instead of 0//?
+    PrintS("Parameter: "); PrintSized(z, r);
+    n_Delete(&z, r);
+  }
+
+
+  clog << "Char: " << n_GetChar(r) << endl;
+
+
+  TS_ASSERT_DIFFERS( r, NULLp );
+  nSetChar( r );
+  TS_ASSERT_EQUALS( getCoeffType(r), type );
+
+  TS_ASSERT_DIFFERS( r->cfInit, NULLp );
+  TS_ASSERT_DIFFERS( r->cfWriteLong, NULLp );
+  TS_ASSERT_DIFFERS( r->cfAdd, NULLp );
+  TS_ASSERT_DIFFERS( r->cfDelete, NULLp );
+
+  switch( type )
+  {
+    case n_Q:
+    {
+      //TS_ASSERT_EQUALS( r->cfInit, nlInit );
+      //TS_ASSERT_EQUALS( r->cfAdd, nlAdd );
+      //TS_ASSERT_EQUALS( r->cfDelete, nlDelete );
+
+      TS_ASSERT(  nCoeff_is_Q( r ));
+      TS_ASSERT(  nCoeff_is_Domain( r ));
+
+      TS_ASSERT( !nCoeff_has_Units( r )); // ?
+      TS_ASSERT( !nCoeff_has_simple_inverse( r ));// ?
+      TS_ASSERT( !nCoeff_has_simple_Alloc( r )); // ?
+
+      TS_ASSERT( !nCoeff_is_Ring_2toM( r ));
+      TS_ASSERT( !nCoeff_is_Ring_ModN( r ));
+      TS_ASSERT( !nCoeff_is_Ring_PtoM( r ));
+      TS_ASSERT( !nCoeff_is_Ring_Z( r ));
+      TS_ASSERT( !nCoeff_is_Ring( r ));
+      TS_ASSERT( !nCoeff_is_Zp( r ));
+      TS_ASSERT( !nCoeff_is_numeric( r ));
+      TS_ASSERT( !nCoeff_is_R( r ));
+      TS_ASSERT( !nCoeff_is_GF( r ));
+      TS_ASSERT( !nCoeff_is_long_R( r ));
+      TS_ASSERT( !nCoeff_is_long_C( r ));
+      TS_ASSERT( !nCoeff_is_CF( r ));
+      TS_ASSERT( !nCoeff_is_Extension( r ));
+
+      break;
+    }
+    case n_long_R:
+    {
+      //TS_ASSERT_EQUALS( r->cfInit, ngfInit );
+      //TS_ASSERT_EQUALS( r->cfAdd, ngfAdd );
+      //TS_ASSERT_EQUALS( r->cfDelete, ngfDelete );
+      break;
+    }
+    case n_long_C:
+    {
+//       TS_ASSERT_EQUALS( r->cfInit, ngcInit );
+//       TS_ASSERT_EQUALS( r->cfAdd, ngcAdd );
+//       TS_ASSERT_EQUALS( r->cfDelete, ngcDelete );
+      break;
+    }
+    case n_R:
+    {
+      //TS_ASSERT_EQUALS( r->cfInit, nrInit );
+      //TS_ASSERT_EQUALS( r->cfAdd, nrAdd );
+  //    TS_ASSERT_EQUALS( r->cfDelete, nrDelete ); // No?
+      break;
+    }
+    case n_GF:
+    {
+//       TS_ASSERT_EQUALS( r->cfInit, nfInit );
+//       TS_ASSERT_EQUALS( r->cfAdd, nfAdd );
+      //TS_ASSERT_EQUALS( r->cfDelete, nfDelete );
+      break;
+    }
+#ifdef HAVE_RINGS
+    case n_Z2m:
+    {
+      //TS_ASSERT_EQUALS( r->cfInit, nr2mInit );
+      //TS_ASSERT_EQUALS( r->cfAdd, nr2mAdd );
+      //TS_ASSERT_EQUALS( r->cfDelete, ndDelete );
+      break;
+    }
+    case n_Zn:
+    {
+      //TS_ASSERT_EQUALS( r->cfInit, nrnInit );
+      //TS_ASSERT_EQUALS( r->cfAdd, nrnAdd );
+      //TS_ASSERT_EQUALS( r->cfDelete, nrnDelete );
+      break;
+    }
+#endif
+    default:
+    {
+      // ...
+    }
+  }
+
+  TestArith( r );
+  TestSum( r, 10 );
+  TestSum( r, 100 );
+  TestSum( r, 101 );
+  TestSum( r, 1001 );
+  TestSum( r, 9000 );
+
+  nKillChar( r );
+
+  return TRUE;
+}
+
+
+
+// We can rely on this file being included exactly once
+// and declare this global variable in the header file.
+//
+static GlobalPrintingFixture globalPrintingFixture;
+
+
+class CoeffsTestSuite : public CxxTest::TestSuite
+{
+ public:
+//   void test_dummy() { float fnum = 2.00001f; TS_ASSERT_DELTA (fnum, 2.0f, 0.0001f);  }
+
+   void test_Z2m4()
+   {
+#ifdef HAVE_RINGS
+     n_coeffType type = n_Z2m;
+     TS_ASSERT( Test(type, (void*) 4) );
+#endif
+   }
+
+   void test_Zp101()
+   {
+     n_coeffType type = n_Zp;
+     TS_ASSERT( Test(type, (void*) 101) );
+   }
+
+   void test_Z2m8()
+   {
+#ifdef HAVE_RINGS
+     n_coeffType type =  n_Z2m;
+     TS_ASSERT( Test(type, (void*) 8) );
+#endif
+   }
+
+   void simple(const n_coeffType _type)
+   {
+     n_coeffType type = _type;
+     TS_ASSERT( type == _type ); // ?
+     TS_ASSERT( Test(type) );
+   }
+
+   void test_Q()
+   {
+     simple(n_Q);
+   }
+
+   void test_R()
+   {
+     simple(n_R);
+   }
+
+
+   void test_Z()
+   {
+#ifdef HAVE_RINGS
+     simple(n_Z);  // No need in GMP?
+#endif
+   }
+
+
+   void test_GF_toobig()
+   {
+     n_coeffType type = n_GF;
+
+     GFInfo param;
+
+     param.GFChar= 5;
+     param.GFDegree= 12;
+     param.GFPar_name= (const char*)"q";
+
+     TS_ASSERT( !Test(type, (void*) &param) );
+
+      // it should not be used by numbers... right?
+      // TODO: what is our policy wrt param-pointer-ownership?
+   }
+
+   void test_GF()
+   {
+     // TODO: what if it was already registered?
+     // Q: no way to deRegister a type?
+     n_coeffType type = n_GF;
+
+     GFInfo param;
+
+     param.GFChar= 5;
+     param.GFDegree= 2;
+     param.GFPar_name= (const char*)"Q";
+
+     TS_ASSERT( Test(type, (void*) &param) );
+
+      // it should not be used by numbers... right?
+      // TODO: what is our policy wrt param-pointer-ownership?
+   }
+
+
+   void test_Zn3()
+   {
+#ifdef HAVE_RINGS
+     n_coeffType type = n_Zn;
+
+     ZnmInfo Znmparam;
+     Znmparam.base= (mpz_ptr) omAlloc (sizeof (mpz_t));
+     mpz_init_set_ui (Znmparam.base, 3);
+     Znmparam.exp= 1;
+
+     TS_ASSERT( Test(type, (void*) &Znmparam) );
+#endif
+   }
+
+   void test_Z2m2()
+   {
+#ifdef HAVE_RINGS
+     n_coeffType type = n_Z2m;
+
+     TS_ASSERT( Test(type, (void*) 2) );
+#endif
+   }
+
+   void test_LR()
+   {
+     simple(n_long_R);
+   }
+
+   void test_LC()
+   {
+     simple(n_long_C);
+   }
+
+   void test_Q_special()
+   {
+     const coeffs cf = nInitChar(n_Q, NULLp);
+
+     if (cf == NULLp)
+       clog << ( "Test: could not get this coeff. domain" );
+
+     TS_ASSERT_DIFFERS(cf->cfCoeffWrite, NULLp);
+
+     if (cf->cfCoeffWrite != NULL )
+     {
+       clog << "Coeff-domain: "  << endl;
+       n_CoeffWrite(cf); PrintLn();
+     }
+
+     number q1 = n_Init(21, cf);
+     number q2 = n_Init(2, cf);
+     number q3 = n_Div(q1, q2, cf);
+     number q4 = n_Init(30, cf);
+     number q5 = n_Mult(q3, q4, cf);
+     TS_ASSERT(n_Test(q5, cf));
+     Print("21/2 * 30 = %d\n", n_Int(q5, cf));
+     TS_ASSERT(n_Test(q5, cf));
+     n_Delete(&q1, cf);
+     n_Delete(&q2, cf);
+     n_Delete(&q3, cf);
+     n_Delete(&q4, cf);
+     n_Delete(&q5, cf);
+   }
+};
+
diff --git a/libpolys/tests/common.h b/libpolys/tests/common.h
new file mode 100644
index 0000000..0238d71
--- /dev/null
+++ b/libpolys/tests/common.h
@@ -0,0 +1,182 @@
+#ifndef TESTS_COMMON_H
+#define TESTS_COMMON_H
+
+#include <iostream>
+#include <fstream>
+#include <string.h>
+
+#include <cxxtest/TestSuite.h>
+#include <cxxtest/GlobalFixture.h>
+
+
+
+
+
+#include <misc/auxiliary.h>
+#include <omalloc/omalloc.h>
+
+#include <coeffs/coeffs.h>
+#include <coeffs/numbers.h>
+
+#include <reporter/reporter.h>
+#include <resources/feResource.h>
+
+#ifndef PLURAL_INTERNAL_DECLARATIONS
+#define PLURAL_INTERNAL_DECLARATIONS
+#endif
+
+#ifndef PLURAL_INTERNAL_DECLARATIONS_GB_HACK
+#define PLURAL_INTERNAL_DECLARATIONS_GB_HACK
+#endif
+
+#include <polys/nc/gb_hack.h>
+
+// #pragma GCC diagnostic ignored "-Wwrite-strings"
+namespace
+{
+  static inline std::ostream& operator<< (std::ostream& o, const n_coeffType& type)
+  {
+#define CASE(A) case A: return o << (" " # A) << " ";
+    switch( type )
+    {
+      CASE(n_unknown);
+      CASE(n_Zp);
+      CASE(n_Q);
+      CASE(n_R);
+      CASE(n_GF);
+      CASE(n_long_R);
+      CASE(n_algExt);
+      CASE(n_transExt);
+      CASE(n_long_C);
+      CASE(n_Z);
+      CASE(n_Zn);
+      CASE(n_Znm);
+      CASE(n_Z2m);
+      CASE(n_CF);
+      default: return o << "Unknown type: [" << (const unsigned long) type << "]";
+    }
+#undef CASE
+    return o;
+  }
+
+  template<typename T>
+      static inline std::string _2S(T i)
+  {
+    std::stringstream ss;
+    ss << i;
+//    std::string s = ss.str();
+    return ss.str();
+  }
+
+
+  static inline std::string _2S(number a, const coeffs r)
+  {
+    n_Test(a,r);
+    StringSetS("");
+    n_Write(a, r);
+
+    std::stringstream ss;
+    {
+      char* s = StringEndS();  ss << s; omFree(s);
+    }
+
+    return ss.str();
+
+  }
+
+  static inline void PrintSized(/*const*/ number a, const coeffs r, BOOLEAN eoln = TRUE)
+  {
+    std::clog << _2S(a, r) << ", of size: " << n_Size(a, r);
+
+    if( eoln )
+      std::clog << std::endl;
+  }
+
+
+
+}
+
+class GlobalPrintingFixture : public CxxTest::GlobalFixture
+{
+   std::ofstream _ofs;
+   bool _redirect;
+  public:
+    GlobalPrintingFixture(bool redirect = false): _redirect(redirect){}
+
+    ~GlobalPrintingFixture()
+    {
+      if( _ofs)
+        _ofs.close();
+    }
+
+    void Redirect()
+    {
+      const int ll = strlen(argv0);
+      const int l = 5 + ll;
+      char* s = (char *)omAlloc0(l);
+      s = strncpy(s, argv0, ll);
+      strncpy(s + ll, ".log", 4);
+      _ofs.open(s); // , ios_base::out)
+      omFreeSize((ADDRESS)s, l);
+
+      std::clog.rdbuf(_ofs.rdbuf());
+    }
+
+    virtual bool setUpWorld()
+    {
+      if( _redirect )
+        Redirect();
+
+      std::clog << std::endl << ( "<world>" ) << std::endl << std::endl;
+      feInitResources(argv0);
+
+      StringSetS("ressources in use (as reported by feStringAppendResources(0):\n");
+      feStringAppendResources(0);
+
+      { char* s = StringEndS(); PrintS(s); omFree(s); }
+
+      return true;
+    }
+
+    virtual bool tearDownWorld()
+    {
+        std::clog << std::endl << std::endl <<( "</world>" )  << std::endl  << std::endl ;
+        return true;
+    }
+    virtual bool setUp() { std::clog << std::endl << std::endl <<( "<test>" ) << std::endl  << std::endl; return true; }
+    virtual bool tearDown() { std::clog << std::endl << std::endl <<( "</test>" ) << std::endl  << std::endl; return true; }
+};
+
+
+template void CxxTest::doAssertDiffers<n_Procs_s*, void*>(char const*, unsigned int, char const*, n_Procs_s*, char const*, void*, char const*);
+template void CxxTest::doAssertDiffers<snumber* (*)(long, n_Procs_s*), void*>(char const*, unsigned int, char const*, snumber* (*)(long, n_Procs_s*), char const*, void*, char const*);
+template void CxxTest::doAssertDiffers<snumber* (*)(snumber*, snumber*, n_Procs_s*), void*>(char const*, unsigned int, char const*, snumber* (*)(snumber*, snumber*, n_Procs_s*), char const*, void*, char const*);
+template void CxxTest::doAssertDiffers<void (*)(n_Procs_s*, int), void*>(char const*, unsigned int, char const*, void (*)(n_Procs_s*, int), char const*, void*, char const*);
+template void CxxTest::doAssertDiffers<void (*)(snumber**, n_Procs_s*), void*>(char const*, unsigned int, char const*, void (*)(snumber**, n_Procs_s*), char const*, void*, char const*);
+template void CxxTest::doAssertDiffers<void (*)(snumber*&, n_Procs_s*), void*>(char const*, unsigned int, char const*, void (*)(snumber*&, n_Procs_s*), char const*, void*, char const*);
+template void CxxTest::doAssertEquals<int, int>(char const*, unsigned int, char const*, int, char const*, int, char const*);
+template void CxxTest::doAssertEquals<n_coeffType, n_coeffType>(char const*, unsigned int, char const*, n_coeffType, char const*, n_coeffType, char const*);
+template void CxxTest::doAssertEquals<snumber* (*)(long, n_Procs_s*), snumber* (*)(long, n_Procs_s*)>(char const*, unsigned int, char const*, snumber* (*)(long, n_Procs_s*), char const*, snumber* (*)(long, n_Procs_s*), char const*);
+template void CxxTest::doAssertEquals<snumber* (*)(snumber*, snumber*, n_Procs_s*), snumber* (*)(snumber*, snumber*, n_Procs_s*)>(char const*, unsigned int, char const*, snumber* (*)(snumber*, snumber*, n_Procs_s*), char const*, snumber* (*)(snumber*, snumber*, n_Procs_s*), char const*);
+template void CxxTest::doAssertEquals<void (*)(snumber**, n_Procs_s*), void (*)(snumber**, n_Procs_s*)>(char const*, unsigned int, char const*, void (*)(snumber**, n_Procs_s*), char const*, void (*)(snumber**, n_Procs_s*), char const*);
+
+template bool CxxTest::differs<n_Procs_s*, void*>(n_Procs_s*, void*);
+template bool CxxTest::differs<snumber* (*)(long, n_Procs_s*), void*>(snumber* (*)(long, n_Procs_s*), void*);
+template bool CxxTest::differs<snumber* (*)(snumber*, snumber*, n_Procs_s*), void*>(snumber* (*)(snumber*, snumber*, n_Procs_s*), void*);
+template bool CxxTest::differs<void (*)(n_Procs_s*, int), void*>(void (*)(n_Procs_s*, int), void*);
+template bool CxxTest::differs<void (*)(snumber**, n_Procs_s*), void*>(void (*)(snumber**, n_Procs_s*), void*);
+template bool CxxTest::differs<void (*)(snumber*&, n_Procs_s*), void*>(void (*)(snumber*&, n_Procs_s*), void*);
+template bool CxxTest::equals<int, int>(int, int);
+template bool CxxTest::equals<n_coeffType, n_coeffType>(n_coeffType, n_coeffType);
+template bool CxxTest::equals<snumber* (*)(long, n_Procs_s*), snumber* (*)(long, n_Procs_s*)>(snumber* (*)(long, n_Procs_s*), snumber* (*)(long, n_Procs_s*));
+template bool CxxTest::equals<snumber* (*)(snumber*, snumber*, n_Procs_s*), snumber* (*)(snumber*, snumber*, n_Procs_s*)>(snumber* (*)(snumber*, snumber*, n_Procs_s*), snumber* (*)(snumber*, snumber*, n_Procs_s*));
+template bool CxxTest::equals<void (*)(snumber**, n_Procs_s*), void (*)(snumber**, n_Procs_s*)>(void (*)(snumber**, n_Procs_s*), void (*)(snumber**, n_Procs_s*));
+template char* CxxTest::numberToString<long>(long, char*, long, unsigned int, unsigned int);
+
+template void CxxTest::doAssertDiffers<ip_sring*, void*>(char const*, unsigned int, char const*, ip_sring*, char const*, void*, char const*);
+template void CxxTest::doAssertEquals<short, int>(char const*, unsigned int, char const*, short, char const*, int, char const*);
+
+template bool CxxTest::differs<ip_sring*, void*>(ip_sring*, void*);
+template bool CxxTest::equals<short, int>(short, int);
+
+#endif /* TESTS_COMMON_H */
diff --git a/libpolys/tests/cxxtest/Descriptions.cpp b/libpolys/tests/cxxtest/Descriptions.cpp
new file mode 100644
index 0000000..e2831aa
--- /dev/null
+++ b/libpolys/tests/cxxtest/Descriptions.cpp
@@ -0,0 +1,58 @@
+#ifndef __cxxtest__Descriptions_cpp__
+#define __cxxtest__Descriptions_cpp__
+
+#include <cxxtest/Descriptions.h>
+
+namespace CxxTest
+{
+    TestDescription::~TestDescription() {}
+    SuiteDescription::~SuiteDescription() {}
+    WorldDescription::~WorldDescription() {}
+
+    //
+    // Convert total tests to string
+    //
+#ifndef _CXXTEST_FACTOR
+    char *WorldDescription::strTotalTests( char *s ) const
+    {
+        numberToString( numTotalTests(), s );
+        return s;
+    }
+#else // _CXXTEST_FACTOR
+    char *WorldDescription::strTotalTests( char *s ) const
+    {
+        char *p = numberToString( numTotalTests(), s );
+
+        if ( numTotalTests() <= 1 )
+            return s;
+
+        unsigned n = numTotalTests();
+        unsigned numFactors = 0;
+
+        for ( unsigned factor = 2; (factor * factor) <= n; factor += (factor == 2) ? 1 : 2 ) {
+            unsigned power;
+
+            for ( power = 0; (n % factor) == 0; n /= factor )
+                ++ power;
+
+            if ( !power )
+                continue;
+
+            p = numberToString( factor, copyString( p, (numFactors == 0) ? " = " : " * " ) );
+            if ( power > 1 )
+                p = numberToString( power, copyString( p, "^" ) );
+            ++ numFactors;
+        }
+
+        if ( n > 1 ) {
+            if ( !numFactors )
+                copyString( p, tracker().failedTests() ? " :(" : tracker().warnings() ? " :|" : " :)" );
+            else
+                numberToString( n, copyString( p, " * " ) );
+        }
+        return s;
+    }
+#endif // _CXXTEST_FACTOR
+};
+
+#endif // __cxxtest__Descriptions_cpp__
diff --git a/libpolys/tests/cxxtest/Descriptions.h b/libpolys/tests/cxxtest/Descriptions.h
new file mode 100644
index 0000000..c25b88d
--- /dev/null
+++ b/libpolys/tests/cxxtest/Descriptions.h
@@ -0,0 +1,74 @@
+#ifndef __cxxtest__Descriptions_h__
+#define __cxxtest__Descriptions_h__
+
+//
+// TestDescription, SuiteDescription and WorldDescription
+// hold information about tests so they can be run and reported.
+//
+
+#include <cxxtest/LinkedList.h>
+
+namespace CxxTest
+{
+    class TestSuite;
+
+    class TestDescription : public Link
+    {
+    public:
+        virtual ~TestDescription();
+
+        virtual const char *file() const = 0;
+        virtual unsigned line() const = 0;
+        virtual const char *testName() const = 0;
+        virtual const char *suiteName() const = 0;
+
+        virtual void run() = 0;
+
+        virtual const TestDescription *next() const = 0;
+        virtual TestDescription *next() = 0;
+    };
+
+    class SuiteDescription : public Link
+    {
+    public:
+        virtual ~SuiteDescription();
+
+        virtual const char *file() const = 0;
+        virtual unsigned line() const = 0;
+        virtual const char *suiteName() const = 0;
+        virtual TestSuite *suite() const = 0;
+
+        virtual unsigned numTests() const = 0;
+        virtual const TestDescription &testDescription( unsigned /*i*/ ) const = 0;
+
+        virtual TestDescription *firstTest() = 0;
+        virtual const TestDescription *firstTest() const = 0;
+        virtual SuiteDescription *next() = 0;
+        virtual const SuiteDescription *next() const = 0;
+
+        virtual void activateAllTests() = 0;
+        virtual bool leaveOnly( const char * /*testName*/ ) = 0;
+    };
+
+    class WorldDescription : public Link
+    {
+    public:
+        virtual ~WorldDescription();
+
+        virtual unsigned numSuites( void ) const = 0;
+        virtual unsigned numTotalTests( void ) const = 0;
+        virtual const SuiteDescription &suiteDescription( unsigned /*i*/ ) const = 0;
+
+        enum { MAX_STRLEN_TOTAL_TESTS = 32 };
+        char *strTotalTests( char * /*buffer*/ ) const;
+
+        virtual SuiteDescription *firstSuite() = 0;
+        virtual const SuiteDescription *firstSuite() const = 0;
+
+        virtual void activateAllTests() = 0;
+        virtual bool leaveOnly( const char * /*suiteName*/, const char * /*testName*/ = 0 ) = 0;
+    };
+}
+
+#endif // __cxxtest__Descriptions_h__
+
diff --git a/libpolys/tests/cxxtest/DummyDescriptions.cpp b/libpolys/tests/cxxtest/DummyDescriptions.cpp
new file mode 100644
index 0000000..04869bf
--- /dev/null
+++ b/libpolys/tests/cxxtest/DummyDescriptions.cpp
@@ -0,0 +1,49 @@
+#include <cxxtest/DummyDescriptions.h>
+
+namespace CxxTest
+{
+    DummyTestDescription::DummyTestDescription() {}
+
+    const char *DummyTestDescription::file() const { return "<no file>"; }
+    unsigned DummyTestDescription::line() const { return 0; }
+    const char *DummyTestDescription::testName() const { return "<no test>"; }
+    const char *DummyTestDescription::suiteName() const { return "<no suite>"; }
+    bool DummyTestDescription::setUp() { return true;}
+    void DummyTestDescription::run() {}
+    bool DummyTestDescription::tearDown() { return true;}
+
+    TestDescription *DummyTestDescription::next() { return 0; }
+    const TestDescription *DummyTestDescription::next() const { return 0; }
+
+    DummySuiteDescription::DummySuiteDescription() : _test() {}
+
+    const char *DummySuiteDescription::file() const { return "<no file>"; }
+    unsigned DummySuiteDescription::line() const { return 0; }
+    const char *DummySuiteDescription::suiteName() const { return "<no suite>"; }
+    TestSuite *DummySuiteDescription::suite() const { return 0; }
+    unsigned DummySuiteDescription::numTests() const { return 0; }
+    const TestDescription &DummySuiteDescription::testDescription( unsigned ) const { return _test; }
+    SuiteDescription *DummySuiteDescription::next() { return 0; }
+    TestDescription *DummySuiteDescription::firstTest() { return 0; }
+    const SuiteDescription *DummySuiteDescription::next() const { return 0; }
+    const TestDescription *DummySuiteDescription::firstTest() const { return 0; }
+    void DummySuiteDescription::activateAllTests() {}
+    bool DummySuiteDescription::leaveOnly( const char * /*testName*/ ) { return false; }
+
+    bool DummySuiteDescription::setUp() { return true;}
+    bool DummySuiteDescription::tearDown() { return true;}
+
+    DummyWorldDescription::DummyWorldDescription() : _suite() {}
+
+    unsigned DummyWorldDescription::numSuites( void ) const { return 0; }
+    unsigned DummyWorldDescription::numTotalTests( void ) const { return 0; }
+    const SuiteDescription &DummyWorldDescription::suiteDescription( unsigned ) const { return _suite; }
+    SuiteDescription *DummyWorldDescription::firstSuite() { return 0; }
+    const SuiteDescription *DummyWorldDescription::firstSuite() const { return 0; }
+    void DummyWorldDescription::activateAllTests() {}
+    bool DummyWorldDescription::leaveOnly( const char * /*suiteName*/, const char * /*testName*/ ) { return false; }
+
+    bool DummyWorldDescription::setUp() { return true;}
+    bool DummyWorldDescription::tearDown() { return true;}
+}
+
diff --git a/libpolys/tests/cxxtest/DummyDescriptions.h b/libpolys/tests/cxxtest/DummyDescriptions.h
new file mode 100644
index 0000000..69d1116
--- /dev/null
+++ b/libpolys/tests/cxxtest/DummyDescriptions.h
@@ -0,0 +1,76 @@
+#ifndef __cxxtest__DummyDescriptions_h__
+#define __cxxtest__DummyDescriptions_h__
+
+//
+// DummyTestDescription, DummySuiteDescription and DummyWorldDescription
+//
+
+#include <cxxtest/Descriptions.h>
+
+namespace CxxTest
+{
+    class DummyTestDescription : public TestDescription
+    {
+    public:
+        DummyTestDescription();
+
+        const char *file() const;
+        unsigned line() const;
+        const char *testName() const;
+        const char *suiteName() const;
+        bool setUp();
+        void run();
+        bool tearDown();
+
+        TestDescription *next();
+        const TestDescription *next() const;
+    };
+
+    class DummySuiteDescription : public SuiteDescription
+    {
+    public:
+        DummySuiteDescription();
+
+        const char *file() const;
+        unsigned line() const;
+        const char *suiteName() const;
+        TestSuite *suite() const;
+        unsigned numTests() const;
+        const TestDescription &testDescription( unsigned ) const;
+        SuiteDescription *next();
+        TestDescription *firstTest();
+        const SuiteDescription *next() const;
+        const TestDescription *firstTest() const;
+        void activateAllTests();
+        bool leaveOnly( const char * /*testName*/ );
+
+        bool setUp();
+        bool tearDown();
+
+    private:
+        DummyTestDescription _test;
+    };
+
+    class DummyWorldDescription : public WorldDescription
+    {
+    public:
+        DummyWorldDescription();
+
+        unsigned numSuites( void ) const;
+        unsigned numTotalTests( void ) const;
+        const SuiteDescription &suiteDescription( unsigned ) const;
+        SuiteDescription *firstSuite();
+        const SuiteDescription *firstSuite() const;
+        void activateAllTests();
+        bool leaveOnly( const char * /*suiteName*/, const char * /*testName*/ = 0 );
+
+        bool setUp();
+        bool tearDown();
+
+    private:
+        DummySuiteDescription _suite;
+    };
+}
+
+#endif // __cxxtest__DummyDescriptions_h__
+
diff --git a/libpolys/tests/cxxtest/ErrorFormatter.h b/libpolys/tests/cxxtest/ErrorFormatter.h
new file mode 100644
index 0000000..aaa824b
--- /dev/null
+++ b/libpolys/tests/cxxtest/ErrorFormatter.h
@@ -0,0 +1,281 @@
+#ifndef __cxxtest__ErrorFormatter_h__
+#define __cxxtest__ErrorFormatter_h__
+
+//
+// The ErrorFormatter is a TestListener that
+// prints reports of the errors to an output
+// stream.  Since we cannot rely ou the standard
+// iostreams, this header defines a base class
+// analogout to std::ostream.
+//
+
+#include <cxxtest/TestRunner.h>
+#include <cxxtest/TestListener.h>
+#include <cxxtest/TestTracker.h>
+#include <cxxtest/ValueTraits.h>
+
+namespace CxxTest
+{
+    class OutputStream
+    {
+    public:
+        virtual ~OutputStream() {}
+        virtual void flush() {};
+        virtual OutputStream &operator<<( unsigned /*number*/ ) { return *this; }
+        virtual OutputStream &operator<<( const char * /*string*/ ) { return *this; }
+
+        typedef void (*Manipulator)( OutputStream & );
+
+        virtual OutputStream &operator<<( Manipulator m ) { m( *this ); return *this; }
+        static void endl( OutputStream &o ) { (o << "\n").flush(); }
+    };
+
+    class ErrorFormatter : public TestListener
+    {
+    public:
+        ErrorFormatter( OutputStream *o, const char *preLine = ":", const char *postLine = "" ) :
+            _dotting( true ),
+            _reported( false ),
+            _o(o),
+            _preLine(preLine),
+            _postLine(postLine)
+        {
+        }
+
+        int run()
+        {
+            TestRunner::runAllTests( *this );
+            return tracker().failedTests();
+        }
+
+        void enterWorld( const WorldDescription & /*desc*/ )
+        {
+            (*_o) << "Running " << totalTests;
+            _o->flush();
+            _dotting = true;
+            _reported = false;
+        }
+
+        static void totalTests( OutputStream &o )
+        {
+            char s[WorldDescription::MAX_STRLEN_TOTAL_TESTS];
+            const WorldDescription &wd = tracker().world();
+            o << wd.strTotalTests( s ) << (wd.numTotalTests() == 1 ? " test" : " tests");
+        }
+
+        void enterSuite( const SuiteDescription & )
+        {
+            _reported = false;
+        }
+
+        void enterTest( const TestDescription & )
+        {
+            _reported = false;
+        }
+
+        void leaveTest( const TestDescription & )
+        {
+            if ( !tracker().testFailed() ) {
+                ((*_o) << ".").flush();
+                _dotting = true;
+            }
+        }
+
+        void leaveWorld( const WorldDescription &desc )
+        {
+            if ( !tracker().failedTests() ) {
+                (*_o) << "OK!" << endl;
+                return;
+            }
+            newLine();
+            (*_o) << "Failed " << tracker().failedTests() << " of " << totalTests << endl;
+            unsigned numPassed = desc.numTotalTests() - tracker().failedTests();
+            (*_o) << "Success rate: " << (numPassed * 100 / desc.numTotalTests()) << "%" << endl;
+        }
+
+        void trace( const char *file, unsigned line, const char *expression )
+        {
+            stop( file, line ) << "Trace: " <<
+                expression << endl;
+        }
+
+        void warning( const char *file, unsigned line, const char *expression )
+        {
+            stop( file, line ) << "Warning: " <<
+                expression << endl;
+        }
+
+        void failedTest( const char *file, unsigned line, const char *expression )
+        {
+            stop( file, line ) << "Error: Test failed: " <<
+                expression << endl;
+        }
+
+        void failedAssert( const char *file, unsigned line, const char *expression )
+        {
+            stop( file, line ) << "Error: Assertion failed: " <<
+                expression << endl;
+        }
+
+        void failedAssertEquals( const char *file, unsigned line,
+                                 const char *xStr, const char *yStr,
+                                 const char *x, const char *y )
+        {
+            stop( file, line ) << "Error: Expected (" <<
+                xStr << " == " << yStr << "), found (" <<
+                x << " != " << y << ")" << endl;
+        }
+
+        void failedAssertSameData( const char *file, unsigned line,
+                                   const char *xStr, const char *yStr,
+                                   const char *sizeStr, const void *x,
+                                   const void *y, unsigned size )
+        {
+            stop( file, line ) << "Error: Expected " << sizeStr << " (" << size << ") bytes to be equal at (" <<
+                xStr << ") and (" << yStr << "), found:" << endl;
+            dump( x, size );
+            (*_o) << "     differs from" << endl;
+            dump( y, size );
+        }
+
+        void failedAssertDelta( const char *file, unsigned line,
+                                const char *xStr, const char *yStr, const char *dStr,
+                                const char *x, const char *y, const char *d )
+        {
+            stop( file, line ) << "Error: Expected (" <<
+                xStr << " == " << yStr << ") up to " << dStr << " (" << d << "), found (" <<
+                x << " != " << y << ")" << endl;
+        }
+
+        void failedAssertDiffers( const char *file, unsigned line,
+                                  const char *xStr, const char *yStr,
+                                  const char *value )
+        {
+            stop( file, line ) << "Error: Expected (" <<
+                xStr << " != " << yStr << "), found (" <<
+                value << ")" << endl;
+        }
+
+        void failedAssertLessThan( const char *file, unsigned line,
+                                   const char *xStr, const char *yStr,
+                                   const char *x, const char *y )
+        {
+            stop( file, line ) << "Error: Expected (" <<
+                xStr << " < " << yStr << "), found (" <<
+                x << " >= " << y << ")" << endl;
+        }
+
+        void failedAssertLessThanEquals( const char *file, unsigned line,
+                                         const char *xStr, const char *yStr,
+                                         const char *x, const char *y )
+        {
+            stop( file, line ) << "Error: Expected (" <<
+                xStr << " <= " << yStr << "), found (" <<
+                x << " > " << y << ")" << endl;
+        }
+
+        void failedAssertRelation( const char *file, unsigned line,
+                                   const char *relation, const char *xStr, const char *yStr,
+                                   const char *x, const char *y )
+        {
+            stop( file, line ) << "Error: Expected " << relation << "( " <<
+                xStr << ", " << yStr << " ), found !" << relation << "( " << x << ", " << y << " )" << endl;
+        }
+
+        void failedAssertPredicate( const char *file, unsigned line,
+                                    const char *predicate, const char *xStr, const char *x )
+        {
+            stop( file, line ) << "Error: Expected " << predicate << "( " <<
+                xStr << " ), found !" << predicate << "( " << x << " )" << endl;
+        }
+
+        void failedAssertThrows( const char *file, unsigned line,
+                                 const char *expression, const char *type,
+                                 bool otherThrown )
+        {
+            stop( file, line ) << "Error: Expected (" << expression << ") to throw (" <<
+                type << ") but it " << (otherThrown ? "threw something else" : "didn't throw") <<
+                endl;
+        }
+
+        void failedAssertThrowsNot( const char *file, unsigned line, const char *expression )
+        {
+            stop( file, line ) << "Error: Expected (" << expression << ") not to throw, but it did" <<
+                endl;
+        }
+
+    protected:
+        OutputStream *outputStream() const
+        {
+            return _o;
+        }
+
+    private:
+        ErrorFormatter( const ErrorFormatter & );
+        ErrorFormatter &operator=( const ErrorFormatter & );
+
+        OutputStream &stop( const char *file, unsigned line )
+        {
+            newLine();
+            reportTest();
+            return (*_o) << file << _preLine << line << _postLine << ": ";
+        }
+
+        void newLine( void )
+        {
+            if ( _dotting ) {
+                (*_o) << endl;
+                _dotting = false;
+            }
+        }
+
+        void reportTest( void )
+        {
+            if( _reported )
+                return;
+            (*_o) << "In " << tracker().suite().suiteName() << "::" << tracker().test().testName() << ":" << endl;
+            _reported = true;
+        }
+
+        void dump( const void *buffer, unsigned size )
+        {
+            if ( !buffer )
+                dumpNull();
+            else
+                dumpBuffer( buffer, size );
+        }
+
+        void dumpNull()
+        {
+            (*_o) << "   (null)" << endl;
+        }
+
+        void dumpBuffer( const void *buffer, unsigned size )
+        {
+            unsigned dumpSize = size;
+            if ( maxDumpSize() && dumpSize > maxDumpSize() )
+                dumpSize = maxDumpSize();
+
+            const unsigned char *p = (const unsigned char *)buffer;
+            (*_o) << "   { ";
+            for ( unsigned i = 0; i < dumpSize; ++ i )
+                (*_o) << byteToHex( *p++ ) << " ";
+            if ( dumpSize < size )
+                (*_o) << "... ";
+            (*_o) << "}" << endl;
+        }
+
+        static void endl( OutputStream &o )
+        {
+            OutputStream::endl( o );
+        }
+
+        bool _dotting;
+        bool _reported;
+        OutputStream *_o;
+        const char *_preLine;
+        const char *_postLine;
+    };
+};
+
+#endif // __cxxtest__ErrorFormatter_h__
diff --git a/libpolys/tests/cxxtest/ErrorPrinter.h b/libpolys/tests/cxxtest/ErrorPrinter.h
new file mode 100644
index 0000000..8c95c2a
--- /dev/null
+++ b/libpolys/tests/cxxtest/ErrorPrinter.h
@@ -0,0 +1,55 @@
+#ifndef __cxxtest__ErrorPrinter_h__
+#define __cxxtest__ErrorPrinter_h__
+
+//
+// The ErrorPrinter is a simple TestListener that
+// just prints "OK" if everything goes well, otherwise
+// reports the error in the format of compiler messages.
+// The ErrorPrinter uses std::cout
+//
+
+#include <cxxtest/Flags.h>
+
+#ifndef _CXXTEST_HAVE_STD
+#   define _CXXTEST_HAVE_STD
+#endif // _CXXTEST_HAVE_STD
+
+#include <cxxtest/ErrorFormatter.h>
+#include <cxxtest/StdValueTraits.h>
+
+#ifdef _CXXTEST_OLD_STD
+#   include <iostream.h>
+#else // !_CXXTEST_OLD_STD
+#   include <iostream>
+#endif // _CXXTEST_OLD_STD
+
+namespace CxxTest
+{
+    class ErrorPrinter : public ErrorFormatter
+    {
+    public:
+        ErrorPrinter( CXXTEST_STD(ostream) &o = CXXTEST_STD(cout), const char *preLine = ":", const char *postLine = "" ) :
+            ErrorFormatter( new Adapter(o), preLine, postLine ) {}
+        virtual ~ErrorPrinter() { delete outputStream(); }
+
+    private:
+        class Adapter : public OutputStream
+        {
+            CXXTEST_STD(ostream) &_o;
+        public:
+            Adapter( CXXTEST_STD(ostream) &o ) : _o(o) {}
+            void flush() { _o.flush(); }
+            OutputStream &operator<<( const char *s ) { _o << s; return *this; }
+            OutputStream &operator<<( Manipulator m ) { return OutputStream::operator<<( m ); }
+            OutputStream &operator<<( unsigned i )
+            {
+                char s[1 + 3 * sizeof(unsigned)];
+                numberToString( i, s );
+                _o << s;
+                return *this;
+            }
+        };
+    };
+}
+
+#endif // __cxxtest__ErrorPrinter_h__
diff --git a/libpolys/tests/cxxtest/Flags.h b/libpolys/tests/cxxtest/Flags.h
new file mode 100644
index 0000000..be2f9f2
--- /dev/null
+++ b/libpolys/tests/cxxtest/Flags.h
@@ -0,0 +1,121 @@
+#ifndef __cxxtest__Flags_h__
+#define __cxxtest__Flags_h__
+
+//
+// These are the flags that control CxxTest
+//
+
+#if !defined(CXXTEST_FLAGS)
+#   define CXXTEST_FLAGS
+#endif // !CXXTEST_FLAGS
+
+#if defined(CXXTEST_HAVE_EH) && !defined(_CXXTEST_HAVE_EH)
+#   define _CXXTEST_HAVE_EH
+#endif // CXXTEST_HAVE_EH
+
+#if defined(CXXTEST_HAVE_STD) && !defined(_CXXTEST_HAVE_STD)
+#   define _CXXTEST_HAVE_STD
+#endif // CXXTEST_HAVE_STD
+
+#if defined(CXXTEST_OLD_TEMPLATE_SYNTAX) && !defined(_CXXTEST_OLD_TEMPLATE_SYNTAX)
+#   define _CXXTEST_OLD_TEMPLATE_SYNTAX
+#endif // CXXTEST_OLD_TEMPLATE_SYNTAX
+
+#if defined(CXXTEST_OLD_STD) && !defined(_CXXTEST_OLD_STD)
+#   define _CXXTEST_OLD_STD
+#endif // CXXTEST_OLD_STD
+
+#if defined(CXXTEST_ABORT_TEST_ON_FAIL) && !defined(_CXXTEST_ABORT_TEST_ON_FAIL)
+#   define _CXXTEST_ABORT_TEST_ON_FAIL
+#endif // CXXTEST_ABORT_TEST_ON_FAIL
+
+#if defined(CXXTEST_NO_COPY_CONST) && !defined(_CXXTEST_NO_COPY_CONST)
+#   define _CXXTEST_NO_COPY_CONST
+#endif // CXXTEST_NO_COPY_CONST
+
+#if defined(CXXTEST_FACTOR) && !defined(_CXXTEST_FACTOR)
+#   define _CXXTEST_FACTOR
+#endif // CXXTEST_FACTOR
+
+#if defined(CXXTEST_PARTIAL_TEMPLATE_SPECIALIZATION) && !defined(_CXXTEST_PARTIAL_TEMPLATE_SPECIALIZATION)
+#   define _CXXTEST_PARTIAL_TEMPLATE_SPECIALIZATION
+#endif // CXXTEST_PARTIAL_TEMPLATE_SPECIALIZATION
+
+#if defined(CXXTEST_LONGLONG)
+#   if defined(_CXXTEST_LONGLONG)
+#       undef _CXXTEST_LONGLONG
+#   endif
+#   define _CXXTEST_LONGLONG CXXTEST_LONGLONG
+#endif // CXXTEST_LONGLONG
+
+#ifndef CXXTEST_MAX_DUMP_SIZE
+#   define CXXTEST_MAX_DUMP_SIZE 0
+#endif // CXXTEST_MAX_DUMP_SIZE
+
+#if defined(_CXXTEST_ABORT_TEST_ON_FAIL) && !defined(CXXTEST_DEFAULT_ABORT)
+#   define CXXTEST_DEFAULT_ABORT true
+#endif // _CXXTEST_ABORT_TEST_ON_FAIL && !CXXTEST_DEFAULT_ABORT
+
+#if !defined(CXXTEST_DEFAULT_ABORT)
+#   define CXXTEST_DEFAULT_ABORT false
+#endif // !CXXTEST_DEFAULT_ABORT
+
+#if defined(_CXXTEST_ABORT_TEST_ON_FAIL) && !defined(_CXXTEST_HAVE_EH)
+#   warning "CXXTEST_ABORT_TEST_ON_FAIL is meaningless without CXXTEST_HAVE_EH"
+#   undef _CXXTEST_ABORT_TEST_ON_FAIL
+#endif // _CXXTEST_ABORT_TEST_ON_FAIL && !_CXXTEST_HAVE_EH
+
+//
+// Some minimal per-compiler configuration to allow us to compile
+//
+
+#ifdef __BORLANDC__
+#   if __BORLANDC__ <= 0x520 // Borland C++ 5.2 or earlier
+#       ifndef _CXXTEST_OLD_STD
+#           define _CXXTEST_OLD_STD
+#       endif
+#       ifndef _CXXTEST_OLD_TEMPLATE_SYNTAX
+#           define _CXXTEST_OLD_TEMPLATE_SYNTAX
+#       endif
+#   endif
+#   if __BORLANDC__ >= 0x540 // C++ Builder 4.0 or later
+#       ifndef _CXXTEST_NO_COPY_CONST
+#           define _CXXTEST_NO_COPY_CONST
+#       endif
+#       ifndef _CXXTEST_LONGLONG
+#           define _CXXTEST_LONGLONG __int64
+#       endif
+#   endif
+#endif // __BORLANDC__
+
+#ifdef _MSC_VER // Visual C++
+#   ifndef _CXXTEST_LONGLONG
+#       define _CXXTEST_LONGLONG __int64
+#   endif
+#   if (_MSC_VER >= 0x51E)
+#       ifndef _CXXTEST_PARTIAL_TEMPLATE_SPECIALIZATION
+#           define _CXXTEST_PARTIAL_TEMPLATE_SPECIALIZATION
+#       endif
+#   endif
+#   pragma warning( disable : 4127 )
+#   pragma warning( disable : 4290 )
+#   pragma warning( disable : 4511 )
+#   pragma warning( disable : 4512 )
+#   pragma warning( disable : 4514 )
+#endif // _MSC_VER
+
+#ifdef __GNUC__
+#   if (__GNUC__ > 2) || (__GNUC__ == 2 && __GNUC_MINOR__ >= 9)
+#       ifndef _CXXTEST_PARTIAL_TEMPLATE_SPECIALIZATION
+#           define _CXXTEST_PARTIAL_TEMPLATE_SPECIALIZATION
+#       endif
+#   endif
+#endif // __GNUC__
+
+#ifdef __DMC__ // Digital Mars
+#   ifndef _CXXTEST_OLD_STD
+#       define _CXXTEST_OLD_STD
+#   endif
+#endif
+
+#endif // __cxxtest__Flags_h__
diff --git a/libpolys/tests/cxxtest/GlobalFixture.cpp b/libpolys/tests/cxxtest/GlobalFixture.cpp
new file mode 100644
index 0000000..edcaf1e
--- /dev/null
+++ b/libpolys/tests/cxxtest/GlobalFixture.cpp
@@ -0,0 +1,23 @@
+#ifndef __cxxtest__GlobalFixture_cpp__
+#define __cxxtest__GlobalFixture_cpp__
+
+#include <cxxtest/GlobalFixture.h>
+
+namespace CxxTest
+{
+    bool GlobalFixture::setUpWorld() { return true; }
+    bool GlobalFixture::tearDownWorld() { return true; }
+    bool GlobalFixture::setUp() { return true; }
+    bool GlobalFixture::tearDown() { return true; }
+
+    GlobalFixture::GlobalFixture() { attach( _list ); }
+    GlobalFixture::~GlobalFixture() { detach( _list ); }
+
+    GlobalFixture *GlobalFixture::firstGlobalFixture() { return (GlobalFixture *)_list.head(); }
+    GlobalFixture *GlobalFixture::lastGlobalFixture() { return (GlobalFixture *)_list.tail(); }
+    GlobalFixture *GlobalFixture::nextGlobalFixture() { return (GlobalFixture *)next(); }
+    GlobalFixture *GlobalFixture::prevGlobalFixture() { return (GlobalFixture *)prev(); }
+}
+
+#endif // __cxxtest__GlobalFixture_cpp__
+
diff --git a/libpolys/tests/cxxtest/GlobalFixture.h b/libpolys/tests/cxxtest/GlobalFixture.h
new file mode 100644
index 0000000..cbecb0d
--- /dev/null
+++ b/libpolys/tests/cxxtest/GlobalFixture.h
@@ -0,0 +1,30 @@
+#ifndef __cxxtest__GlobalFixture_h__
+#define __cxxtest__GlobalFixture_h__
+
+#include <cxxtest/LinkedList.h>
+
+namespace CxxTest
+{
+    class GlobalFixture : public Link
+    {
+    public:
+        virtual bool setUpWorld();
+        virtual bool tearDownWorld();
+        virtual bool setUp();
+        virtual bool tearDown();
+
+        GlobalFixture();
+        ~GlobalFixture();
+
+        static GlobalFixture *firstGlobalFixture();
+        static GlobalFixture *lastGlobalFixture();
+        GlobalFixture *nextGlobalFixture();
+        GlobalFixture *prevGlobalFixture();
+
+    private:
+        static List _list;
+    };
+}
+
+#endif // __cxxtest__GlobalFixture_h__
+
diff --git a/libpolys/tests/cxxtest/Gui.h b/libpolys/tests/cxxtest/Gui.h
new file mode 100644
index 0000000..8e6b411
--- /dev/null
+++ b/libpolys/tests/cxxtest/Gui.h
@@ -0,0 +1,178 @@
+#ifndef __CXXTEST__GUI_H
+#define __CXXTEST__GUI_H
+
+//
+// GuiListener is a simple base class for the differes GUIs
+// GuiTuiRunner<GuiT, TuiT> combines a GUI with a text-mode error formatter
+//
+
+#include <cxxtest/TeeListener.h>
+
+namespace CxxTest
+{
+    class GuiListener : public TestListener
+    {
+    public:
+        GuiListener() : _state( GREEN_BAR ) {}
+        virtual ~GuiListener() {}
+
+        virtual void runGui( int &argc, char **argv, TestListener &listener )
+        {
+            enterGui( argc, argv );
+            TestRunner::runAllTests( listener );
+            leaveGui();
+        }
+
+        virtual void enterGui( int & /*argc*/, char ** /*argv*/ ) {}
+        virtual void leaveGui() {}
+
+        //
+        // The easy way is to implement these functions:
+        //
+        virtual void guiEnterWorld( unsigned /*numTotalTests*/ ) {}
+        virtual void guiEnterSuite( const char * /*suiteName*/ ) {}
+        virtual void guiEnterTest( const char * /*suiteName*/, const char * /*testName*/ ) {}
+        virtual void yellowBar() {}
+        virtual void redBar() {}
+
+        //
+        // The hard way is this:
+        //
+        void enterWorld( const WorldDescription &d ) { guiEnterWorld( d.numTotalTests() ); }
+        void enterSuite( const SuiteDescription &d ) { guiEnterSuite( d.suiteName() ); }
+        void enterTest( const TestDescription &d ) { guiEnterTest( d.suiteName(), d.testName() ); }
+        void leaveTest( const TestDescription & ) {}
+        void leaveSuite( const SuiteDescription & ) {}
+        void leaveWorld( const WorldDescription & ) {}
+
+        void warning( const char * /*file*/, unsigned /*line*/, const char * /*expression*/ )
+        {
+            yellowBarSafe();
+        }
+
+        void failedTest( const char * /*file*/, unsigned /*line*/, const char * /*expression*/ )
+        {
+            redBarSafe();
+        }
+
+        void failedAssert( const char * /*file*/, unsigned /*line*/, const char * /*expression*/ )
+        {
+            redBarSafe();
+        }
+
+        void failedAssertEquals( const char * /*file*/, unsigned /*line*/,
+                                 const char * /*xStr*/, const char * /*yStr*/,
+                                 const char * /*x*/, const char * /*y*/ )
+        {
+            redBarSafe();
+        }
+
+        void failedAssertSameData( const char * /*file*/, unsigned /*line*/,
+                                   const char * /*xStr*/, const char * /*yStr*/,
+                                   const char * /*sizeStr*/, const void * /*x*/,
+                                   const void * /*y*/, unsigned /*size*/ )
+        {
+            redBarSafe();
+        }
+
+        void failedAssertDelta( const char * /*file*/, unsigned /*line*/,
+                                const char * /*xStr*/, const char * /*yStr*/, const char * /*dStr*/,
+                                const char * /*x*/, const char * /*y*/, const char * /*d*/ )
+        {
+            redBarSafe();
+        }
+
+        void failedAssertDiffers( const char * /*file*/, unsigned /*line*/,
+                                  const char * /*xStr*/, const char * /*yStr*/,
+                                  const char * /*value*/ )
+        {
+            redBarSafe();
+        }
+
+        void failedAssertLessThan( const char * /*file*/, unsigned /*line*/,
+                                   const char * /*xStr*/, const char * /*yStr*/,
+                                   const char * /*x*/, const char * /*y*/ )
+        {
+            redBarSafe();
+        }
+
+        void failedAssertLessThanEquals( const char * /*file*/, unsigned /*line*/,
+                                         const char * /*xStr*/, const char * /*yStr*/,
+                                         const char * /*x*/, const char * /*y*/ )
+        {
+            redBarSafe();
+        }
+
+        void failedAssertPredicate( const char * /*file*/, unsigned /*line*/,
+                                    const char * /*predicate*/, const char * /*xStr*/, const char * /*x*/ )
+        {
+            redBarSafe();
+        }
+
+        void failedAssertRelation( const char * /*file*/, unsigned /*line*/,
+                                   const char * /*relation*/, const char * /*xStr*/, const char * /*yStr*/,
+                                   const char * /*x*/, const char * /*y*/ )
+        {
+            redBarSafe();
+        }
+
+        void failedAssertThrows( const char * /*file*/, unsigned /*line*/,
+                                 const char * /*expression*/, const char * /*type*/,
+                                 bool /*otherThrown*/ )
+        {
+            redBarSafe();
+        }
+
+        void failedAssertThrowsNot( const char * /*file*/, unsigned /*line*/,
+                                    const char * /*expression*/ )
+        {
+            redBarSafe();
+        }
+
+    protected:
+        void yellowBarSafe()
+        {
+            if ( _state < YELLOW_BAR ) {
+                yellowBar();
+                _state = YELLOW_BAR;
+            }
+        }
+
+        void redBarSafe()
+        {
+            if ( _state < RED_BAR ) {
+                redBar();
+                _state = RED_BAR;
+            }
+        }
+
+    private:
+        enum { GREEN_BAR, YELLOW_BAR, RED_BAR } _state;
+    };
+
+    template<class GuiT, class TuiT>
+    class GuiTuiRunner : public TeeListener
+    {
+        int &_argc;
+        char **_argv;
+        GuiT _gui;
+        TuiT _tui;
+
+    public:
+        GuiTuiRunner( int &argc, char **argv ) :
+            _argc( argc ),
+            _argv( argv )
+        {
+            setFirst( _gui );
+            setSecond( _tui );
+        }
+
+        int run()
+        {
+            _gui.runGui( _argc, _argv, *this );
+            return tracker().failedTests();
+        }
+    };
+};
+
+#endif //__CXXTEST__GUI_H
diff --git a/libpolys/tests/cxxtest/LinkedList.cpp b/libpolys/tests/cxxtest/LinkedList.cpp
new file mode 100644
index 0000000..b71447f
--- /dev/null
+++ b/libpolys/tests/cxxtest/LinkedList.cpp
@@ -0,0 +1,172 @@
+#ifndef __cxxtest__LinkedList_cpp__
+#define __cxxtest__LinkedList_cpp__
+
+#include <cxxtest/LinkedList.h>
+
+namespace CxxTest
+{
+    List GlobalFixture::_list = { 0, 0 };
+    List RealSuiteDescription::_suites = { 0, 0 };
+
+    void List::initialize()
+    {
+        _head = _tail = 0;
+    }
+
+    Link *List::head()
+    {
+        Link *l = _head;
+        while ( l && !l->active() )
+            l = l->next();
+        return l;
+    }
+
+    const Link *List::head() const
+    {
+        Link *l = _head;
+        while ( l && !l->active() )
+            l = l->next();
+        return l;
+    }
+
+    Link *List::tail()
+    {
+        Link *l = _tail;
+        while ( l && !l->active() )
+            l = l->prev();
+        return l;
+    }
+
+    const Link *List::tail() const
+    {
+        Link *l = _tail;
+        while ( l && !l->active() )
+            l = l->prev();
+        return l;
+    }
+
+    bool List::empty() const
+    {
+        return (_head == 0);
+    }
+
+    unsigned List::size() const
+    {
+        unsigned count = 0;
+        for ( const Link *l = head(); l != 0; l = l->next() )
+            ++ count;
+        return count;
+    }
+
+    Link *List::nth( unsigned n )
+    {
+        Link *l = head();
+        while ( n -- )
+            l = l->next();
+        return l;
+    }
+
+    void List::activateAll()
+    {
+        for ( Link *l = _head; l != 0; l = l->justNext() )
+            l->setActive( true );
+    }
+
+    void List::leaveOnly( const Link &link )
+    {
+        for ( Link *l = head(); l != 0; l = l->next() )
+            if ( l != &link )
+                l->setActive( false );
+    }
+
+    Link::Link() :
+        _next( 0 ),
+        _prev( 0 ),
+        _active( true )
+    {
+    }
+
+    Link::~Link()
+    {
+    }
+
+    bool Link::active() const
+    {
+        return _active;
+    }
+
+    void Link::setActive( bool value )
+    {
+        _active = value;
+    }
+
+    Link * Link::justNext()
+    {
+        return _next;
+    }
+
+    Link * Link::justPrev()
+    {
+        return _prev;
+    }
+
+    Link * Link::next()
+    {
+        Link *l = _next;
+        while ( l && !l->_active )
+            l = l->_next;
+        return l;
+    }
+
+    Link * Link::prev()
+    {
+        Link *l = _prev;
+        while ( l && !l->_active )
+            l = l->_prev;
+        return l;
+    }
+
+    const Link * Link::next() const
+    {
+        Link *l = _next;
+        while ( l && !l->_active )
+            l = l->_next;
+        return l;
+    }
+
+    const Link * Link::prev() const
+    {
+        Link *l = _prev;
+        while ( l && !l->_active )
+            l = l->_prev;
+        return l;
+    }
+
+    void Link::attach( List &l )
+    {
+        if ( l._tail )
+            l._tail->_next = this;
+
+        _prev = l._tail;
+        _next = 0;
+
+        if ( l._head == 0 )
+            l._head = this;
+        l._tail = this;
+    }
+
+    void Link::detach( List &l )
+    {
+        if ( _prev )
+            _prev->_next = _next;
+        else
+            l._head = _next;
+
+        if ( _next )
+            _next->_prev = _prev;
+        else
+            l._tail = _prev;
+    }
+};
+
+#endif // __cxxtest__LinkedList_cpp__
diff --git a/libpolys/tests/cxxtest/LinkedList.h b/libpolys/tests/cxxtest/LinkedList.h
new file mode 100644
index 0000000..bb5e842
--- /dev/null
+++ b/libpolys/tests/cxxtest/LinkedList.h
@@ -0,0 +1,65 @@
+#ifndef __cxxtest__LinkedList_h__
+#define __cxxtest__LinkedList_h__
+
+#include <cxxtest/Flags.h>
+
+namespace CxxTest
+{
+    struct List;
+    class Link;
+
+    struct List
+    {
+        Link *_head;
+        Link *_tail;
+
+        void initialize();
+
+        Link *head();
+        const Link *head() const;
+        Link *tail();
+        const Link *tail() const;
+
+        bool empty() const;
+        unsigned size() const;
+        Link *nth( unsigned n );
+
+        void activateAll();
+        void leaveOnly( const Link &link );
+    };
+
+    class Link
+    {
+    public:
+        Link();
+        virtual ~Link();
+
+        bool active() const;
+        void setActive( bool value = true );
+
+        Link *justNext();
+        Link *justPrev();
+
+        Link *next();
+        Link *prev();
+        const Link *next() const;
+        const Link *prev() const;
+
+        virtual bool setUp() = 0;
+        virtual bool tearDown() = 0;
+
+        void attach( List &l );
+        void detach( List &l );
+
+    private:
+        Link *_next;
+        Link *_prev;
+        bool _active;
+
+        Link( const Link & );
+        Link &operator=( const Link & );
+    };
+}
+
+#endif // __cxxtest__LinkedList_h__
+
diff --git a/libpolys/tests/cxxtest/Mock.h b/libpolys/tests/cxxtest/Mock.h
new file mode 100644
index 0000000..647088e
--- /dev/null
+++ b/libpolys/tests/cxxtest/Mock.h
@@ -0,0 +1,350 @@
+#ifndef __cxxtest__Mock_h__
+#define __cxxtest__Mock_h__
+
+//
+// The default namespace is T::
+//
+#ifndef CXXTEST_MOCK_NAMESPACE
+#   define CXXTEST_MOCK_NAMESPACE T
+#endif // CXXTEST_MOCK_NAMESPACE
+
+//
+// MockTraits: What to return when no mock object has been created
+//
+#define __CXXTEST_MOCK__TRAITS \
+    namespace CXXTEST_MOCK_NAMESPACE \
+    { \
+        template<class T> \
+        class MockTraits \
+        { \
+        public: \
+            static T defaultValue() { return 0; } \
+        }; \
+    };
+
+//
+// extern "C" when needed
+//
+#ifdef __cplusplus
+#   define CXXTEST_EXTERN_C extern "C"
+#else
+#   define CXXTEST_EXTERN_C
+#endif // __cplusplus
+
+//
+// Prototypes: For "normal" headers
+//
+#define __CXXTEST_MOCK__PROTOTYPE( MOCK, TYPE, NAME, ARGS, REAL, CALL ) \
+    namespace CXXTEST_MOCK_NAMESPACE { TYPE NAME ARGS; }
+
+#define __CXXTEST_MOCK_VOID__PROTOTYPE( MOCK, NAME, ARGS, REAL, CALL ) \
+    __CXXTEST_MOCK__PROTOTYPE( MOCK, void, NAME, ARGS, REAL, CALL )
+
+#define __CXXTEST_SUPPLY__PROTOTYPE( MOCK, TYPE, NAME, ARGS, REAL, CALL ) \
+    TYPE REAL ARGS;
+
+#define __CXXTEST_SUPPLY_VOID__PROTOTYPE( MOCK, NAME, ARGS, REAL, CALL ) \
+    __CXXTEST_SUPPLY__PROTOTYPE( MOCK, void, NAME, ARGS, REAL, CALL )
+
+//
+// Class declarations: For test files
+//
+#define __CXXTEST_MOCK__CLASS_DECLARATION( MOCK, TYPE, NAME, ARGS, REAL, CALL ) \
+    namespace CXXTEST_MOCK_NAMESPACE { \
+        class Base_##MOCK : public CxxTest::Link \
+        { \
+        public: \
+            Base_##MOCK(); \
+            ~Base_##MOCK(); \
+            bool setUp(); \
+            bool tearDown(); \
+         \
+            static Base_##MOCK &current(); \
+         \
+            virtual TYPE NAME ARGS = 0; \
+         \
+        private: \
+            static CxxTest::List _list; \
+        }; \
+         \
+        class Real_##MOCK  : public Base_##MOCK \
+        { \
+        public: \
+            TYPE NAME ARGS; \
+        }; \
+         \
+        class _Unimplemented_##MOCK  : public Base_##MOCK \
+        { \
+        public: \
+            TYPE NAME ARGS; \
+        }; \
+    }
+
+#define __CXXTEST_MOCK_VOID__CLASS_DECLARATION( MOCK, NAME, ARGS, REAL, CALL ) \
+    __CXXTEST_MOCK__CLASS_DECLARATION( MOCK, void, NAME, ARGS, REAL, CALL )
+
+#define __CXXTEST_SUPPLY__CLASS_DECLARATION( MOCK, TYPE, NAME, ARGS, REAL, CALL ) \
+    namespace CXXTEST_MOCK_NAMESPACE { \
+        class Base_##MOCK : public CxxTest::Link \
+        { \
+        public: \
+            Base_##MOCK(); \
+            ~Base_##MOCK(); \
+            bool setUp(); \
+            bool tearDown(); \
+         \
+            static Base_##MOCK &current(); \
+         \
+            virtual TYPE NAME ARGS = 0; \
+         \
+        private: \
+            static CxxTest::List _list; \
+        }; \
+         \
+        class _Unimplemented_##MOCK  : public Base_##MOCK \
+        { \
+        public: \
+            TYPE NAME ARGS; \
+        }; \
+    }
+
+#define __CXXTEST_SUPPLY_VOID__CLASS_DECLARATION( MOCK, NAME, ARGS, REAL, CALL ) \
+    __CXXTEST_SUPPLY__CLASS_DECLARATION( MOCK, void, NAME, ARGS, REAL, CALL )
+
+//
+// Class implementation: For test source files
+//
+#define __CXXTEST_MOCK__COMMON_CLASS_IMPLEMENTATION( MOCK, NAME ) \
+    namespace CXXTEST_MOCK_NAMESPACE { \
+         \
+        CxxTest::List Base_##MOCK::_list = { 0, 0 }; \
+         \
+        Base_##MOCK::Base_##MOCK() { attach( _list ); } \
+        Base_##MOCK::~Base_##MOCK() { detach( _list ); } \
+        bool Base_##MOCK::setUp() { return true; } \
+        bool Base_##MOCK::tearDown() { return true; } \
+         \
+        Base_##MOCK &Base_##MOCK::current() \
+        { \
+            if ( _list.empty() ) \
+                static _Unimplemented_##MOCK unimplemented; \
+            return *(Base_##MOCK *)_list.tail(); \
+        } \
+    }
+
+#define __CXXTEST_MOCK__CLASS_IMPLEMENTATION( MOCK, TYPE, NAME, ARGS, REAL, CALL ) \
+    __CXXTEST_MOCK__COMMON_CLASS_IMPLEMENTATION( MOCK, NAME ) \
+    namespace CXXTEST_MOCK_NAMESPACE { \
+        TYPE Real_##MOCK::NAME ARGS \
+        { \
+            return REAL CALL; \
+        } \
+         \
+        TYPE _Unimplemented_##MOCK::NAME ARGS \
+        { \
+            while ( false ) \
+                return NAME CALL; \
+            __CXXTEST_MOCK_UNIMPLEMENTED( NAME, ARGS ); \
+            return MockTraits<TYPE>::defaultValue(); \
+        } \
+         \
+        TYPE NAME ARGS \
+        { \
+            return Base_##MOCK::current().NAME CALL; \
+        } \
+    }
+
+#define __CXXTEST_MOCK_VOID__CLASS_IMPLEMENTATION( MOCK, NAME, ARGS, REAL, CALL ) \
+    __CXXTEST_MOCK__COMMON_CLASS_IMPLEMENTATION( MOCK, NAME ) \
+    namespace CXXTEST_MOCK_NAMESPACE { \
+        void Real_##MOCK::NAME ARGS \
+        { \
+            REAL CALL; \
+        } \
+         \
+        void _Unimplemented_##MOCK::NAME ARGS \
+        { \
+            while ( false ) \
+                NAME CALL; \
+            __CXXTEST_MOCK_UNIMPLEMENTED( NAME, ARGS ); \
+        } \
+         \
+        void NAME ARGS \
+        { \
+            Base_##MOCK::current().NAME CALL; \
+        } \
+    }
+
+#define __CXXTEST_SUPPLY__CLASS_IMPLEMENTATION( MOCK, TYPE, NAME, ARGS, REAL, CALL ) \
+    __CXXTEST_MOCK__COMMON_CLASS_IMPLEMENTATION( MOCK, NAME ) \
+    namespace CXXTEST_MOCK_NAMESPACE { \
+        TYPE _Unimplemented_##MOCK::NAME ARGS \
+        { \
+            while ( false ) \
+                return NAME CALL; \
+            __CXXTEST_MOCK_UNIMPLEMENTED( NAME, ARGS ); \
+            return MockTraits<TYPE>::defaultValue(); \
+        } \
+    } \
+     \
+    TYPE REAL ARGS \
+    { \
+        return CXXTEST_MOCK_NAMESPACE::Base_##MOCK::current().NAME CALL; \
+    }
+
+#define __CXXTEST_SUPPLY_VOID__CLASS_IMPLEMENTATION( MOCK, NAME, ARGS, REAL, CALL ) \
+    __CXXTEST_MOCK__COMMON_CLASS_IMPLEMENTATION( MOCK, NAME ) \
+    namespace CXXTEST_MOCK_NAMESPACE { \
+        void _Unimplemented_##MOCK::NAME ARGS \
+        { \
+            while ( false ) \
+                NAME CALL; \
+            __CXXTEST_MOCK_UNIMPLEMENTED( NAME, ARGS ); \
+        } \
+    } \
+     \
+    void REAL ARGS \
+    { \
+        CXXTEST_MOCK_NAMESPACE::Base_##MOCK::current().NAME CALL; \
+    } \
+
+//
+// Error for calling mock function w/o object
+//
+#define __CXXTEST_MOCK_UNIMPLEMENTED( NAME, ARGS ) \
+    TS_FAIL( CXXTEST_MOCK_NAMESPACE_STR #NAME #ARGS " called with no " \
+             CXXTEST_MOCK_NAMESPACE_STR "Base_" #NAME " object" ); \
+
+#define CXXTEST_MOCK_NAMESPACE_STR __CXXTEST_STR(CXXTEST_MOCK_NAMESPACE) "::"
+#define __CXXTEST_STR(X) __CXXTEST_XSTR(X)
+#define __CXXTEST_XSTR(X) #X
+
+#if defined(CXXTEST_MOCK_TEST_SOURCE_FILE)
+//
+// Test source file: Prototypes, class declarations and implementation
+//
+#include <cxxtest/TestSuite.h>
+
+__CXXTEST_MOCK__TRAITS;
+
+#define CXXTEST_MOCK( MOCK, TYPE, NAME, ARGS, REAL, CALL ) \
+    __CXXTEST_MOCK__PROTOTYPE( MOCK, TYPE, NAME, ARGS, REAL, CALL ) \
+    __CXXTEST_MOCK__CLASS_DECLARATION( MOCK, TYPE, NAME, ARGS, REAL, CALL ) \
+    __CXXTEST_MOCK__CLASS_IMPLEMENTATION( MOCK, TYPE, NAME, ARGS, REAL, CALL )
+
+#define CXXTEST_MOCK_VOID( MOCK, NAME, ARGS, REAL, CALL ) \
+    __CXXTEST_MOCK_VOID__PROTOTYPE( MOCK, NAME, ARGS, REAL, CALL ) \
+    __CXXTEST_MOCK_VOID__CLASS_DECLARATION( MOCK, NAME, ARGS, REAL, CALL ) \
+    __CXXTEST_MOCK_VOID__CLASS_IMPLEMENTATION( MOCK, NAME, ARGS, REAL, CALL )
+
+#define CXXTEST_SUPPLY( MOCK, TYPE, NAME, ARGS, REAL, CALL ) \
+    __CXXTEST_SUPPLY__PROTOTYPE( MOCK, TYPE, NAME, ARGS, REAL, CALL ) \
+    __CXXTEST_SUPPLY__CLASS_DECLARATION( MOCK, TYPE, NAME, ARGS, REAL, CALL ) \
+    __CXXTEST_SUPPLY__CLASS_IMPLEMENTATION( MOCK, TYPE, NAME, ARGS, REAL, CALL )
+
+#define CXXTEST_SUPPLY_VOID( MOCK, NAME, ARGS, REAL, CALL ) \
+    __CXXTEST_SUPPLY_VOID__PROTOTYPE( MOCK, NAME, ARGS, REAL, CALL ) \
+    __CXXTEST_SUPPLY_VOID__CLASS_DECLARATION( MOCK, NAME, ARGS, REAL, CALL ) \
+    __CXXTEST_SUPPLY_VOID__CLASS_IMPLEMENTATION( MOCK, NAME, ARGS, REAL, CALL )
+
+#elif defined(CXXTEST_FLAGS) || defined(CXXTEST_RUNNING)
+//
+// Test file other than source: Prototypes and class declarations
+//
+#include <cxxtest/TestSuite.h>
+
+__CXXTEST_MOCK__TRAITS;
+
+#define CXXTEST_MOCK( MOCK, TYPE, NAME, ARGS, REAL, CALL ) \
+    __CXXTEST_MOCK__PROTOTYPE( MOCK, TYPE, NAME, ARGS, REAL, CALL ) \
+    __CXXTEST_MOCK__CLASS_DECLARATION( MOCK, TYPE, NAME, ARGS, REAL, CALL )
+
+#define CXXTEST_MOCK_VOID( MOCK, NAME, ARGS, REAL, CALL ) \
+    __CXXTEST_MOCK_VOID__PROTOTYPE( MOCK, NAME, ARGS, REAL, CALL ) \
+    __CXXTEST_MOCK_VOID__CLASS_DECLARATION( MOCK, NAME, ARGS, REAL, CALL )
+
+#define CXXTEST_SUPPLY( MOCK, TYPE, NAME, ARGS, REAL, CALL ) \
+    __CXXTEST_SUPPLY__PROTOTYPE( MOCK, TYPE, NAME, ARGS, REAL, CALL ) \
+    __CXXTEST_SUPPLY__CLASS_DECLARATION( MOCK, TYPE, NAME, ARGS, REAL, CALL )
+
+#define CXXTEST_SUPPLY_VOID( MOCK, NAME, ARGS, REAL, CALL ) \
+    __CXXTEST_SUPPLY_VOID__PROTOTYPE( MOCK, NAME, ARGS, REAL, CALL ) \
+    __CXXTEST_SUPPLY_VOID__CLASS_DECLARATION( MOCK, NAME, ARGS, REAL, CALL )
+
+#elif defined(CXXTEST_MOCK_REAL_SOURCE_FILE)
+//
+// Real source file: "Real" implementations
+//
+#define CXXTEST_MOCK( MOCK, TYPE, NAME, ARGS, REAL, CALL ) \
+    namespace CXXTEST_MOCK_NAMESPACE { TYPE NAME ARGS { return REAL CALL; } }
+
+#define CXXTEST_MOCK_VOID( MOCK, NAME, ARGS, REAL, CALL ) \
+    namespace CXXTEST_MOCK_NAMESPACE { void NAME ARGS { REAL CALL; } }
+
+#else
+//
+// Ordinary header file: Just prototypes
+//
+
+#define CXXTEST_MOCK( MOCK, TYPE, NAME, ARGS, REAL, CALL ) \
+    __CXXTEST_MOCK__PROTOTYPE( MOCK, TYPE, NAME, ARGS, REAL, CALL )
+
+#define CXXTEST_MOCK_VOID( MOCK, NAME, ARGS, REAL, CALL ) \
+    __CXXTEST_MOCK_VOID__PROTOTYPE( MOCK, NAME, ARGS, REAL, CALL )
+
+#define CXXTEST_SUPPLY( MOCK, TYPE, NAME, ARGS, REAL, CALL ) \
+    __CXXTEST_SUPPLY__PROTOTYPE( MOCK, TYPE, NAME, ARGS, REAL, CALL )
+
+#define CXXTEST_SUPPLY_VOID( MOCK, NAME, ARGS, REAL, CALL ) \
+    __CXXTEST_SUPPLY_VOID__PROTOTYPE( MOCK, NAME, ARGS, REAL, CALL )
+
+#endif // Ordinary header file
+
+//
+// How to supply extern "C" functions
+//
+#define CXXTEST_SUPPLY_C( MOCK, TYPE, NAME, ARGS, REAL, CALL ) \
+    CXXTEST_EXTERN_C __CXXTEST_SUPPLY__PROTOTYPE( MOCK, TYPE, NAME, ARGS, REAL, CALL ) \
+    CXXTEST_SUPPLY( MOCK, TYPE, NAME, ARGS, REAL, CALL )
+
+#define CXXTEST_SUPPLY_VOID_C( MOCK, NAME, ARGS, REAL, CALL ) \
+    CXXTEST_EXTERN_C __CXXTEST_SUPPLY_VOID__PROTOTYPE( MOCK, NAME, ARGS, REAL, CALL ) \
+    CXXTEST_SUPPLY_VOID( MOCK, NAME, ARGS, REAL, CALL )
+
+//
+// Usually we mean the global namespace
+//
+#define CXXTEST_MOCK_GLOBAL( TYPE, NAME, ARGS, CALL ) \
+    CXXTEST_MOCK( NAME, TYPE, NAME, ARGS, ::NAME, CALL )
+
+#define CXXTEST_MOCK_VOID_GLOBAL( NAME, ARGS, CALL ) \
+    CXXTEST_MOCK_VOID( NAME, NAME, ARGS, ::NAME, CALL )
+
+#define CXXTEST_SUPPLY_GLOBAL( TYPE, NAME, ARGS, CALL ) \
+    CXXTEST_SUPPLY( NAME, TYPE, NAME, ARGS, NAME, CALL )
+
+#define CXXTEST_SUPPLY_VOID_GLOBAL( NAME, ARGS, CALL ) \
+    CXXTEST_SUPPLY_VOID( NAME, NAME, ARGS, NAME, CALL )
+
+#define CXXTEST_SUPPLY_GLOBAL_C( TYPE, NAME, ARGS, CALL ) \
+    CXXTEST_SUPPLY_C( NAME, TYPE, NAME, ARGS, NAME, CALL )
+
+#define CXXTEST_SUPPLY_VOID_GLOBAL_C( NAME, ARGS, CALL ) \
+    CXXTEST_SUPPLY_VOID_C( NAME, NAME, ARGS, NAME, CALL )
+
+//
+// What to return when no mock object has been created.
+// The default value of 0 usually works, but some cases may need this.
+//
+#define CXXTEST_MOCK_DEFAULT_VALUE( TYPE, VALUE ) \
+    namespace CXXTEST_MOCK_NAMESPACE \
+    { \
+        template<> \
+        class MockTraits<TYPE> \
+        { \
+        public: \
+            static TYPE defaultValue() { return VALUE; } \
+        }; \
+    }
+
+#endif // __cxxtest__Mock_h__
diff --git a/libpolys/tests/cxxtest/ParenPrinter.h b/libpolys/tests/cxxtest/ParenPrinter.h
new file mode 100644
index 0000000..1db54fc
--- /dev/null
+++ b/libpolys/tests/cxxtest/ParenPrinter.h
@@ -0,0 +1,21 @@
+#ifndef __cxxtest__ParenPrinter_h__
+#define __cxxtest__ParenPrinter_h__
+
+//
+// The ParenPrinter is identical to the ErrorPrinter, except it
+// prints the line number in a format expected by some compilers
+// (notably, MSVC).
+//
+
+#include <cxxtest/ErrorPrinter.h>
+
+namespace CxxTest
+{
+    class ParenPrinter : public ErrorPrinter
+    {
+    public:
+        ParenPrinter( CXXTEST_STD(ostream) &o = CXXTEST_STD(cout) ) : ErrorPrinter( o, "(", ")" ) {}
+    };
+}
+
+#endif // __cxxtest__ParenPrinter_h__
diff --git a/libpolys/tests/cxxtest/QtGui.h b/libpolys/tests/cxxtest/QtGui.h
new file mode 100644
index 0000000..812aefb
--- /dev/null
+++ b/libpolys/tests/cxxtest/QtGui.h
@@ -0,0 +1,271 @@
+#ifndef __cxxtest__QtGui_h__
+#define __cxxtest__QtGui_h__
+
+//
+// The QtGui displays a simple progress bar using the Qt Toolkit.  It
+// has been tested with versions 2.x and 3.x.
+//
+// Apart from normal Qt command-line arguments, it accepts the following options:
+//   -minimized    Start minimized, pop up on error
+//   -keep         Don't close the window at the end
+//   -title TITLE  Set the window caption
+//
+// If both are -minimized and -keep specified, GUI will only keep the
+// window if it's in focus.
+//
+
+#include <cxxtest/Gui.h>
+
+#include <qapplication.h>
+#include <qglobal.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qmessagebox.h>
+#include <qpixmap.h>
+#include <qprogressbar.h>
+#include <qstatusbar.h>
+
+namespace CxxTest
+{
+    class QtGui : public GuiListener
+    {
+    public:
+        void enterGui( int &argc, char **argv )
+        {
+            parseCommandLine( argc, argv );
+            createApplication( argc, argv );
+        }
+
+        void enterWorld( const WorldDescription &wd )
+        {
+            createWindow( wd );
+            processEvents();
+        }
+
+        void guiEnterSuite( const char *suiteName )
+        {
+            showSuiteName( suiteName );
+        }
+
+        void guiEnterTest( const char *suiteName, const char *testName )
+        {
+            setCaption( suiteName, testName );
+            advanceProgressBar();
+            showTestName( testName );
+            showTestsDone( _progressBar->progress() );
+            processEvents();
+        }
+
+        void yellowBar()
+        {
+            setColor( 255, 255, 0 );
+            setIcon( QMessageBox::Warning );
+            getTotalTests();
+            processEvents();
+        }
+
+        void redBar()
+        {
+            if ( _startMinimized && _mainWindow->isMinimized() )
+                showNormal();
+            setColor( 255, 0, 0 );
+            setIcon( QMessageBox::Critical );
+            getTotalTests();
+            processEvents();
+        }
+
+        void leaveGui()
+        {
+            if ( keep() ) {
+                showSummary();
+                _application->exec();
+            }
+            else
+                _mainWindow->close( true );
+        }
+
+    private:
+        QString _title;
+        bool _startMinimized, _keep;
+        unsigned _numTotalTests;
+        QString _strTotalTests;
+        QApplication *_application;
+        QWidget *_mainWindow;
+        QVBoxLayout *_layout;
+        QProgressBar *_progressBar;
+        QStatusBar *_statusBar;
+        QLabel *_suiteName, *_testName, *_testsDone;
+
+        void parseCommandLine( int argc, char **argv )
+        {
+            _startMinimized = _keep = false;
+            _title = argv[0];
+
+            for ( int i = 1; i < argc; ++ i ) {
+                QString arg( argv[i] );
+                if ( arg == "-minimized" )
+                    _startMinimized = true;
+                else if ( arg == "-keep" )
+                    _keep = true;
+                else if ( arg == "-title" && (i + 1 < argc) )
+                    _title = argv[++i];
+            }
+        }
+
+        void createApplication( int &argc, char **argv )
+        {
+            _application = new QApplication( argc, argv );
+        }
+
+        void createWindow( const WorldDescription &wd )
+        {
+            getTotalTests( wd );
+            createMainWindow();
+            createProgressBar();
+            createStatusBar();
+            setMainWidget();
+            if ( _startMinimized )
+                showMinimized();
+            else
+                showNormal();
+        }
+
+        void getTotalTests()
+        {
+            getTotalTests( tracker().world() );
+        }
+
+        void getTotalTests( const WorldDescription &wd )
+        {
+            _numTotalTests = wd.numTotalTests();
+            char s[WorldDescription::MAX_STRLEN_TOTAL_TESTS];
+            _strTotalTests = wd.strTotalTests( s );
+        }
+
+        void createMainWindow()
+        {
+            _mainWindow = new QWidget();
+            _layout = new QVBoxLayout( _mainWindow );
+        }
+
+        void createProgressBar()
+        {
+            _layout->addWidget( _progressBar = new QProgressBar( _numTotalTests, _mainWindow ) );
+            _progressBar->setProgress( 0 );
+            setColor( 0, 255, 0 );
+            setIcon( QMessageBox::Information );
+        }
+
+        void createStatusBar()
+        {
+            _layout->addWidget( _statusBar = new QStatusBar( _mainWindow ) );
+            _statusBar->addWidget( _suiteName = new QLabel( _statusBar ), 2 );
+            _statusBar->addWidget( _testName = new QLabel( _statusBar ), 4 );
+            _statusBar->addWidget( _testsDone = new QLabel( _statusBar ), 1 );
+        }
+
+        void setMainWidget()
+        {
+            _application->setMainWidget( _mainWindow );
+        }
+
+        void showMinimized()
+        {
+            _mainWindow->showMinimized();
+        }
+
+        void showNormal()
+        {
+            _mainWindow->showNormal();
+            centerWindow();
+        }
+
+        void setCaption( const QString &suiteName, const QString &testName )
+        {
+            _mainWindow->setCaption( _title + " - " + suiteName + "::" + testName + "()" );
+        }
+
+        void showSuiteName( const QString &suiteName )
+        {
+            _suiteName->setText( "class " + suiteName );
+        }
+
+        void advanceProgressBar()
+        {
+            _progressBar->setProgress( _progressBar->progress() + 1 );
+        }
+
+        void showTestName( const QString &testName )
+        {
+            _testName->setText( testName + "()" );
+        }
+
+        void showTestsDone( unsigned testsDone )
+        {
+            _testsDone->setText( asString( testsDone ) + " of " + _strTotalTests );
+        }
+
+        static QString asString( unsigned n )
+        {
+            return QString::number( n );
+        }
+
+        void setColor( int r, int g, int b )
+        {
+            QPalette palette = _progressBar->palette();
+            palette.setColor( QColorGroup::Highlight, QColor( r, g, b ) );
+            _progressBar->setPalette( palette );
+        }
+
+        void setIcon( QMessageBox::Icon icon )
+        {
+#if QT_VERSION >= 0x030000
+            _mainWindow->setIcon( QMessageBox::standardIcon( icon ) );
+#else // Qt version < 3.0.0
+            _mainWindow->setIcon( QMessageBox::standardIcon( icon, QApplication::style().guiStyle() ) );
+#endif // QT_VERSION
+        }
+
+        void processEvents()
+        {
+            _application->processEvents();
+        }
+
+        void centerWindow()
+        {
+            QWidget *desktop = QApplication::desktop();
+            int xCenter = desktop->x() + (desktop->width() / 2);
+            int yCenter = desktop->y() + (desktop->height() / 2);
+
+            int windowWidth = (desktop->width() * 4) / 5;
+            int windowHeight = _mainWindow->height();
+            _mainWindow->setGeometry( xCenter - (windowWidth / 2), yCenter - (windowHeight / 2), windowWidth, windowHeight );
+        }
+
+        bool keep()
+        {
+            if ( !_keep )
+                return false;
+            if ( !_startMinimized )
+                return true;
+            return (_mainWindow == _application->activeWindow());
+        }
+
+        void showSummary()
+        {
+            QString summary = _strTotalTests + (_numTotalTests == 1 ? " test" : " tests");
+            if ( tracker().failedTests() )
+                summary = "Failed " + asString( tracker().failedTests() ) + " of " + summary;
+            else
+                summary = summary + " passed";
+
+            _mainWindow->setCaption( _title + " - " + summary );
+
+            _statusBar->removeWidget( _suiteName );
+            _statusBar->removeWidget( _testName );
+            _testsDone->setText( summary );
+        }
+    };
+};
+
+#endif // __cxxtest__QtGui_h__
diff --git a/libpolys/tests/cxxtest/RealDescriptions.cpp b/libpolys/tests/cxxtest/RealDescriptions.cpp
new file mode 100644
index 0000000..234622c
--- /dev/null
+++ b/libpolys/tests/cxxtest/RealDescriptions.cpp
@@ -0,0 +1,311 @@
+#ifndef __cxxtest__RealDescriptions_cpp__
+#define __cxxtest__RealDescriptions_cpp__
+
+//
+// NOTE: If an error occur during world construction/deletion, CxxTest cannot
+//       know where the error originated.
+//
+
+#include <cxxtest/RealDescriptions.h>
+
+namespace CxxTest
+{
+    RealTestDescription::RealTestDescription()
+    {
+    }
+
+    RealTestDescription::RealTestDescription( List &argList,
+                                              SuiteDescription &argSuite,
+                                              unsigned argLine,
+                                              const char *argTestName )
+    {
+        initialize( argList, argSuite, argLine, argTestName );
+    }
+
+    void RealTestDescription::initialize( List &argList,
+                                          SuiteDescription &argSuite,
+                                          unsigned argLine,
+                                          const char *argTestName )
+    {
+        _suite = &argSuite;
+        _line = argLine;
+        _testName = argTestName;
+        attach( argList );
+    }
+
+    bool RealTestDescription::setUp()
+    {
+        if ( !suite() )
+            return false;
+
+        for ( GlobalFixture *gf = GlobalFixture::firstGlobalFixture(); gf != 0; gf = gf->nextGlobalFixture() ) {
+            bool ok;
+            _TS_TRY { ok = gf->setUp(); }
+            _TS_LAST_CATCH( { ok = false; } );
+
+            if ( !ok ) {
+                doFailTest( file(), line(), "Error in GlobalFixture::setUp()" );
+                return false;
+            }
+        }
+
+        _TS_TRY {
+            _TSM_ASSERT_THROWS_NOTHING( file(), line(), "Exception thrown from setUp()", suite()->setUp() );
+        }
+        _TS_CATCH_ABORT( { return false; } );
+
+        return true;
+    }
+
+    bool RealTestDescription::tearDown()
+    {
+        if ( !suite() )
+            return false;
+
+        _TS_TRY {
+            _TSM_ASSERT_THROWS_NOTHING( file(), line(), "Exception thrown from tearDown()", suite()->tearDown() );
+        }
+        _TS_CATCH_ABORT( { return false; } );
+
+        for ( GlobalFixture *gf = GlobalFixture::lastGlobalFixture(); gf != 0; gf = gf->prevGlobalFixture() ) {
+            bool ok;
+            _TS_TRY { ok = gf->tearDown(); }
+            _TS_LAST_CATCH( { ok = false; } );
+
+            if ( !ok ) {
+                doFailTest( file(), line(), "Error in GlobalFixture::tearDown()" );
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    const char *RealTestDescription::file() const { return _suite->file(); }
+    unsigned RealTestDescription::line() const { return _line; }
+    const char *RealTestDescription::testName() const { return _testName; }
+    const char *RealTestDescription::suiteName() const { return _suite->suiteName(); }
+
+    TestDescription *RealTestDescription::next() { return (RealTestDescription *)Link::next(); }
+    const TestDescription *RealTestDescription::next() const { return (const RealTestDescription *)Link::next(); }
+
+    TestSuite *RealTestDescription::suite() const { return _suite->suite(); }
+
+    void RealTestDescription::run()
+    {
+        _TS_TRY { runTest(); }
+        _TS_CATCH_ABORT( {} )
+            ___TSM_CATCH( file(), line(), "Exception thrown from test" );
+    }
+
+    RealSuiteDescription::RealSuiteDescription() {}
+    RealSuiteDescription::RealSuiteDescription( const char *argFile,
+                                                unsigned argLine,
+                                                const char *argSuiteName,
+                                                List &argTests )
+    {
+        initialize( argFile, argLine, argSuiteName, argTests );
+    }
+
+    void RealSuiteDescription::initialize( const char *argFile,
+                                           unsigned argLine,
+                                           const char *argSuiteName,
+                                           List &argTests )
+    {
+        _file = argFile;
+        _line = argLine;
+        _suiteName = argSuiteName;
+        _tests = &argTests;
+
+        attach( _suites );
+    }
+
+    const char *RealSuiteDescription::file() const { return _file; }
+    unsigned RealSuiteDescription::line() const { return _line; }
+    const char *RealSuiteDescription::suiteName() const { return _suiteName; }
+
+    TestDescription *RealSuiteDescription::firstTest() { return (RealTestDescription *)_tests->head(); }
+    const TestDescription *RealSuiteDescription::firstTest() const { return (const RealTestDescription *)_tests->head(); }
+    SuiteDescription *RealSuiteDescription::next() { return (RealSuiteDescription *)Link::next(); }
+    const SuiteDescription *RealSuiteDescription::next() const { return (const RealSuiteDescription *)Link::next(); }
+
+    unsigned RealSuiteDescription::numTests() const { return _tests->size(); }
+
+    const TestDescription &RealSuiteDescription::testDescription( unsigned i ) const
+    {
+        return *(RealTestDescription *)_tests->nth( i );
+    }
+
+    void RealSuiteDescription::activateAllTests()
+    {
+        _tests->activateAll();
+    }
+
+    bool RealSuiteDescription::leaveOnly( const char *testName )
+    {
+        for ( TestDescription *td = firstTest(); td != 0; td = td->next() ) {
+            if ( stringsEqual( td->testName(), testName ) ) {
+                _tests->leaveOnly( *td );
+                return true;
+            }
+        }
+        return false;
+    }
+
+    StaticSuiteDescription::StaticSuiteDescription() {}
+    StaticSuiteDescription::StaticSuiteDescription( const char *argFile, unsigned argLine,
+                                                    const char *argSuiteName, TestSuite &argSuite,
+                                                    List &argTests ) :
+        RealSuiteDescription( argFile, argLine, argSuiteName, argTests )
+    {
+        doInitialize( argSuite );
+    }
+
+    void StaticSuiteDescription::initialize( const char *argFile, unsigned argLine,
+                                             const char *argSuiteName, TestSuite &argSuite,
+                                             List &argTests )
+    {
+        RealSuiteDescription::initialize( argFile, argLine, argSuiteName, argTests );
+        doInitialize( argSuite );
+    }
+
+    void StaticSuiteDescription::doInitialize( TestSuite &argSuite )
+    {
+        _suite = &argSuite;
+    }
+
+    TestSuite *StaticSuiteDescription::suite() const
+    {
+        return _suite;
+    }
+
+    bool StaticSuiteDescription::setUp() { return true; }
+    bool StaticSuiteDescription::tearDown() { return true; }
+
+    CommonDynamicSuiteDescription::CommonDynamicSuiteDescription() {}
+    CommonDynamicSuiteDescription::CommonDynamicSuiteDescription( const char *argFile, unsigned argLine,
+                                                                  const char *argSuiteName, List &argTests,
+                                                                  unsigned argCreateLine, unsigned argDestroyLine ) :
+        RealSuiteDescription( argFile, argLine, argSuiteName, argTests )
+    {
+        doInitialize( argCreateLine, argDestroyLine );
+    }
+
+    void CommonDynamicSuiteDescription::initialize( const char *argFile, unsigned argLine,
+                                                    const char *argSuiteName, List &argTests,
+                                                    unsigned argCreateLine, unsigned argDestroyLine )
+    {
+        RealSuiteDescription::initialize( argFile, argLine, argSuiteName, argTests );
+        doInitialize( argCreateLine, argDestroyLine );
+    }
+
+    void CommonDynamicSuiteDescription::doInitialize( unsigned argCreateLine, unsigned argDestroyLine )
+    {
+        _createLine = argCreateLine;
+        _destroyLine = argDestroyLine;
+    }
+
+    List &RealWorldDescription::suites()
+    {
+        return RealSuiteDescription::_suites;
+    }
+
+    unsigned RealWorldDescription::numSuites( void ) const
+    {
+        return suites().size();
+    }
+
+    unsigned RealWorldDescription::numTotalTests( void ) const
+    {
+        unsigned count = 0;
+        for ( const SuiteDescription *sd = firstSuite(); sd != 0; sd = sd->next() )
+            count += sd->numTests();
+        return count;
+    }
+
+    SuiteDescription *RealWorldDescription::firstSuite()
+    {
+        return (RealSuiteDescription *)suites().head();
+    }
+
+    const SuiteDescription *RealWorldDescription::firstSuite() const
+    {
+        return (const RealSuiteDescription *)suites().head();
+    }
+
+    const SuiteDescription &RealWorldDescription::suiteDescription( unsigned i ) const
+    {
+        return *(const RealSuiteDescription *)suites().nth( i );
+    }
+
+    void RealWorldDescription::activateAllTests()
+    {
+        suites().activateAll();
+        for ( SuiteDescription *sd = firstSuite(); sd != 0; sd = sd->next() )
+            sd->activateAllTests();
+    }
+
+    bool RealWorldDescription::leaveOnly( const char *suiteName, const char *testName )
+    {
+        for ( SuiteDescription *sd = firstSuite(); sd != 0; sd = sd->next() ) {
+            if ( stringsEqual( sd->suiteName(), suiteName ) ) {
+                if ( testName )
+                    if ( !sd->leaveOnly( testName ) )
+                        return false;
+                suites().leaveOnly( *sd );
+                return true;
+            }
+        }
+        return false;
+    }
+
+    bool RealWorldDescription::setUp()
+    {
+        for ( GlobalFixture *gf = GlobalFixture::firstGlobalFixture(); gf != 0; gf = gf->nextGlobalFixture() ) {
+            bool ok;
+            _TS_TRY { ok = gf->setUpWorld(); }
+            _TS_LAST_CATCH( { ok = false; } );
+
+            if ( !ok ) {
+                reportError( "Error setting up world" );
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    bool RealWorldDescription::tearDown()
+    {
+        for ( GlobalFixture *gf = GlobalFixture::lastGlobalFixture(); gf != 0; gf = gf->prevGlobalFixture() ) {
+            bool ok;
+            _TS_TRY { ok = gf->tearDownWorld(); }
+            _TS_LAST_CATCH( { ok = false; } );
+
+            if ( !ok ) {
+                reportError( "Error tearing down world" );
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    void RealWorldDescription::reportError( const char *message )
+    {
+        doWarn( __FILE__, 5, message );
+    }
+
+    void activateAllTests()
+    {
+        RealWorldDescription().activateAllTests();
+    }
+
+    bool leaveOnly( const char *suiteName, const char *testName )
+    {
+        return RealWorldDescription().leaveOnly( suiteName, testName );
+    }
+}
+
+#endif // __cxxtest__RealDescriptions_cpp__
+
diff --git a/libpolys/tests/cxxtest/RealDescriptions.h b/libpolys/tests/cxxtest/RealDescriptions.h
new file mode 100644
index 0000000..ad455db
--- /dev/null
+++ b/libpolys/tests/cxxtest/RealDescriptions.h
@@ -0,0 +1,223 @@
+#ifndef __cxxtest__RealDescriptions_h__
+#define __cxxtest__RealDescriptions_h__
+
+//
+// The "real" description classes
+//
+
+#include <cxxtest/Descriptions.h>
+#include <cxxtest/TestSuite.h>
+#include <cxxtest/GlobalFixture.h>
+
+namespace CxxTest
+{
+    class RealTestDescription : public TestDescription
+    {
+    public:
+        RealTestDescription();
+        RealTestDescription( List &argList, SuiteDescription &argSuite, unsigned argLine, const char *argTestName );
+        void initialize( List &argList, SuiteDescription &argSuite, unsigned argLine, const char *argTestName );
+
+        const char *file() const;
+        unsigned line() const;
+        const char *testName() const;
+        const char *suiteName() const;
+
+        TestDescription *next();
+        const TestDescription *next() const;
+
+        TestSuite *suite() const;
+
+        bool setUp();
+        void run();
+        bool tearDown();
+
+    private:
+        RealTestDescription( const RealTestDescription & );
+        RealTestDescription &operator=( const RealTestDescription & );
+
+        virtual void runTest() = 0;
+
+        SuiteDescription *_suite;
+        unsigned _line;
+        const char *_testName;
+    };
+
+    class RealSuiteDescription : public SuiteDescription
+    {
+    public:
+        RealSuiteDescription();
+        RealSuiteDescription( const char *argFile, unsigned argLine, const char *argSuiteName, List &argTests );
+
+        void initialize( const char *argFile, unsigned argLine, const char *argSuiteName, List &argTests );
+
+        const char *file() const;
+        unsigned line() const;
+        const char *suiteName() const;
+
+        TestDescription *firstTest();
+        const TestDescription *firstTest() const;
+        SuiteDescription *next();
+        const SuiteDescription *next() const;
+
+        unsigned numTests() const;
+        const TestDescription &testDescription( unsigned i ) const;
+
+        void activateAllTests();
+        bool leaveOnly( const char *testName );
+
+    private:
+        RealSuiteDescription( const RealSuiteDescription & );
+        RealSuiteDescription &operator=( const RealSuiteDescription & );
+
+        const char *_file;
+        unsigned _line;
+        const char *_suiteName;
+        List *_tests;
+
+        static List _suites;
+        friend class RealWorldDescription;
+    };
+
+    class StaticSuiteDescription : public RealSuiteDescription
+    {
+    public:
+        StaticSuiteDescription();
+        StaticSuiteDescription( const char *argFile, unsigned argLine,
+                                const char *argSuiteName, TestSuite &argSuite,
+                                List &argTests );
+
+        void initialize( const char *argFile, unsigned argLine,
+                         const char *argSuiteName, TestSuite &argSuite,
+                         List &argTests );
+        TestSuite *suite() const;
+
+        bool setUp();
+        bool tearDown();
+
+    private:
+        StaticSuiteDescription( const StaticSuiteDescription & );
+        StaticSuiteDescription &operator=( const StaticSuiteDescription & );
+
+        void doInitialize( TestSuite &argSuite );
+
+        TestSuite *_suite;
+    };
+
+    class CommonDynamicSuiteDescription : public RealSuiteDescription
+    {
+    public:
+        CommonDynamicSuiteDescription();
+        CommonDynamicSuiteDescription( const char *argFile, unsigned argLine,
+                                       const char *argSuiteName, List &argTests,
+                                       unsigned argCreateLine, unsigned argDestroyLine );
+
+        void initialize( const char *argFile, unsigned argLine,
+                         const char *argSuiteName, List &argTests,
+                         unsigned argCreateLine, unsigned argDestroyLine );
+
+    protected:
+        unsigned _createLine, _destroyLine;
+
+    private:
+        void doInitialize( unsigned argCreateLine, unsigned argDestroyLine );
+    };
+
+    template<class S>
+    class DynamicSuiteDescription : public CommonDynamicSuiteDescription
+    {
+    public:
+        DynamicSuiteDescription() {}
+        DynamicSuiteDescription( const char *argFile, unsigned argLine,
+                                 const char *argSuiteName, List &argTests,
+                                 S *&argSuite, unsigned argCreateLine,
+                                 unsigned argDestroyLine ) :
+            CommonDynamicSuiteDescription( argFile, argLine, argSuiteName, argTests, argCreateLine, argDestroyLine )
+        {
+            _suite = &argSuite;
+        }
+
+        void initialize( const char *argFile, unsigned argLine,
+                         const char *argSuiteName, List &argTests,
+                         S *&argSuite, unsigned argCreateLine,
+                         unsigned argDestroyLine )
+        {
+            CommonDynamicSuiteDescription::initialize( argFile, argLine,
+                                                       argSuiteName, argTests,
+                                                       argCreateLine, argDestroyLine );
+            _suite = &argSuite;
+        }
+
+        TestSuite *suite() const { return realSuite(); }
+
+        bool setUp();
+        bool tearDown();
+
+    private:
+        S *realSuite() const { return *_suite; }
+        void setSuite( S *s ) { *_suite = s; }
+
+        void createSuite()
+        {
+            setSuite( S::createSuite() );
+        }
+
+        void destroySuite()
+        {
+            S *s = realSuite();
+            setSuite( 0 );
+            S::destroySuite( s );
+        }
+
+        S **_suite;
+    };
+
+    template<class S>
+    bool DynamicSuiteDescription<S>::setUp()
+    {
+        _TS_TRY {
+            _TSM_ASSERT_THROWS_NOTHING( file(), _createLine, "Exception thrown from createSuite()", createSuite() );
+            _TSM_ASSERT( file(), _createLine, "createSuite() failed", suite() != 0 );
+        }
+        _TS_CATCH_ABORT( { return false; } );
+
+        return (suite() != 0);
+    }
+
+    template<class S>
+    bool DynamicSuiteDescription<S>::tearDown()
+    {
+        if ( !_suite )
+            return true;
+
+        _TS_TRY {
+            _TSM_ASSERT_THROWS_NOTHING( file(), _destroyLine, "destroySuite() failed", destroySuite() );
+        }
+        _TS_CATCH_ABORT( { return false; } );
+
+        return true;
+    }
+
+    class RealWorldDescription : public WorldDescription
+    {
+    public:
+        static List &suites();
+        unsigned numSuites( void ) const;
+        unsigned numTotalTests( void ) const;
+        SuiteDescription *firstSuite();
+        const SuiteDescription *firstSuite() const;
+        const SuiteDescription &suiteDescription( unsigned i ) const;
+        void activateAllTests();
+        bool leaveOnly( const char *suiteName, const char *testName = 0 );
+
+        bool setUp();
+        bool tearDown();
+        static void reportError( const char *message );
+    };
+
+    void activateAllTests();
+    bool leaveOnly( const char *suiteName, const char *testName = 0 );
+}
+
+#endif // __cxxtest__RealDescriptions_h__
+
diff --git a/libpolys/tests/cxxtest/Root.cpp b/libpolys/tests/cxxtest/Root.cpp
new file mode 100644
index 0000000..63c4358
--- /dev/null
+++ b/libpolys/tests/cxxtest/Root.cpp
@@ -0,0 +1,27 @@
+#ifndef __cxxtest__Root_cpp__
+#define __cxxtest__Root_cpp__
+
+//
+// This file holds the "root" of CxxTest, i.e.
+// the parts that must be in a source file file.
+//
+
+#include <cxxtest/Descriptions.cpp>
+#include <cxxtest/DummyDescriptions.cpp>
+#include <cxxtest/GlobalFixture.cpp>
+#include <cxxtest/LinkedList.cpp>
+#include <cxxtest/RealDescriptions.cpp>
+#include <cxxtest/TestSuite.cpp>
+#include <cxxtest/TestTracker.cpp>
+#include <cxxtest/ValueTraits.cpp>
+
+
+template char* CxxTest::numberToString<double>(double, char*, double, unsigned int, unsigned int);
+template char* CxxTest::numberToString<unsigned int>(unsigned int, char*, unsigned int, unsigned int, unsigned int);
+template char* CxxTest::numberToString<unsigned long>(unsigned long, char*, unsigned long, unsigned int, unsigned int);
+template std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*);
+template void CxxTest::doAssertDelta<float, float, float>(char const*, unsigned int, char const*, float, char const*, float, char const*, float, char const*);
+template bool CxxTest::delta<float, float, float>(float, float, float);
+
+
+#endif // __cxxtest__Root_cpp__
diff --git a/libpolys/tests/cxxtest/SelfTest.h b/libpolys/tests/cxxtest/SelfTest.h
new file mode 100644
index 0000000..6d6b96e
--- /dev/null
+++ b/libpolys/tests/cxxtest/SelfTest.h
@@ -0,0 +1,7 @@
+#ifndef __cxxtest_SelfTest_h__
+#define __cxxtest_SelfTest_h__
+
+#define CXXTEST_SUITE(name)
+#define CXXTEST_CODE(member)
+
+#endif // __cxxtest_SelfTest_h__
diff --git a/libpolys/tests/cxxtest/StdHeaders.h b/libpolys/tests/cxxtest/StdHeaders.h
new file mode 100644
index 0000000..7c80b76
--- /dev/null
+++ b/libpolys/tests/cxxtest/StdHeaders.h
@@ -0,0 +1,25 @@
+#ifndef __cxxtest_StdHeaders_h__
+#define __cxxtest_StdHeaders_h__
+
+//
+// This file basically #includes the STL headers.
+// It exists to support warning level 4 in Visual C++
+//
+
+#ifdef _MSC_VER
+#   pragma warning( push, 1 )
+#endif // _MSC_VER
+
+#include <complex>
+#include <deque>
+#include <list>
+#include <map>
+#include <set>
+#include <string>
+#include <vector>
+
+#ifdef _MSC_VER
+#   pragma warning( pop )
+#endif // _MSC_VER
+
+#endif // __cxxtest_StdHeaders_h__
diff --git a/libpolys/tests/cxxtest/StdValueTraits.h b/libpolys/tests/cxxtest/StdValueTraits.h
new file mode 100644
index 0000000..aaf106b
--- /dev/null
+++ b/libpolys/tests/cxxtest/StdValueTraits.h
@@ -0,0 +1,229 @@
+#ifndef __cxxtest_StdValueTraits_h__
+#define __cxxtest_StdValueTraits_h__
+
+//
+// This file defines ValueTraits for std:: stuff.
+// It is #included by <cxxtest/ValueTraits.h> if you
+// define CXXTEST_HAVE_STD
+//
+
+#include <cxxtest/ValueTraits.h>
+#include <cxxtest/StdHeaders.h>
+
+#ifdef _CXXTEST_OLD_STD
+#   define CXXTEST_STD(x) x
+#else // !_CXXTEST_OLD_STD
+#   define CXXTEST_STD(x) std::x
+#endif // _CXXTEST_OLD_STD
+
+#ifndef CXXTEST_USER_VALUE_TRAITS
+
+namespace CxxTest
+{
+    //
+    // NOTE: This should have been
+    // template<class Char, class Traits, class Allocator>
+    // class ValueTraits< std::basic_string<Char, Traits, Allocator> > {};
+    // But MSVC doesn't support it (yet).
+    //
+
+    //
+    // If we have std::string, we might as well use it
+    //
+    class StdTraitsBase
+    {
+    public:
+        StdTraitsBase &operator<<( const CXXTEST_STD(string) &s ) { _s += s; return *this; }
+        const char *asString() const { return _s.c_str(); }
+
+    private:
+        CXXTEST_STD(string) _s;
+    };
+
+    //
+    // std::string
+    //
+    CXXTEST_TEMPLATE_INSTANTIATION
+    class ValueTraits<const CXXTEST_STD(string)> : public StdTraitsBase
+    {
+    public:
+        ValueTraits( const CXXTEST_STD(string) &s )
+        {
+            *this << "\"";
+            for ( unsigned i = 0; i < s.length(); ++ i ) {
+                char c[sizeof("\\xXX")];
+                charToString( s[i], c );
+                *this << c;
+            }
+            *this << "\"";
+        }
+    };
+
+    CXXTEST_COPY_CONST_TRAITS( CXXTEST_STD(string) );
+
+#ifndef _CXXTEST_OLD_STD
+    //
+    // std::wstring
+    //
+    CXXTEST_TEMPLATE_INSTANTIATION
+    class ValueTraits<const CXXTEST_STD(basic_string<wchar_t>)> : public StdTraitsBase
+    {
+    public:
+        ValueTraits( const CXXTEST_STD(basic_string<wchar_t>) &s )
+        {
+            *this << "L\"";
+            for ( unsigned i = 0; i < s.length(); ++ i ) {
+                char c[sizeof("\\x12345678")];
+                charToString( (unsigned long)s[i], c );
+                *this << c;
+            }
+            *this << "\"";
+        }
+    };
+
+    CXXTEST_COPY_CONST_TRAITS( CXXTEST_STD(basic_string<wchar_t>) );
+#endif // _CXXTEST_OLD_STD
+
+    //
+    // Convert a range defined by iterators to a string
+    // This is useful for almost all STL containers
+    //
+    template<class Stream, class Iterator>
+    void dumpRange( Stream &s, Iterator first, Iterator last )
+    {
+        s << "{ ";
+        while ( first != last ) {
+            s << TS_AS_STRING(*first);
+            ++ first;
+            s << ((first == last) ? " }" : ", ");
+        }
+    }
+
+#ifdef _CXXTEST_PARTIAL_TEMPLATE_SPECIALIZATION
+    //
+    // std::pair
+    //
+    template<class First, class Second>
+    class ValueTraits< CXXTEST_STD(pair)<First, Second> > : public StdTraitsBase
+    {
+    public:
+        ValueTraits( const CXXTEST_STD(pair)<First, Second> &p )
+        {
+            *this << "<" << TS_AS_STRING( p.first ) << ", " << TS_AS_STRING( p.second ) << ">";
+        }
+    };
+
+    //
+    // std::vector
+    //
+    template<class Element>
+    class ValueTraits< CXXTEST_STD(vector)<Element> > : public StdTraitsBase
+    {
+    public:
+        ValueTraits( const CXXTEST_STD(vector)<Element> &v )
+        {
+            dumpRange( *this, v.begin(), v.end() );
+        }
+    };
+
+    //
+    // std::list
+    //
+    template<class Element>
+    class ValueTraits< CXXTEST_STD(list)<Element> > : public StdTraitsBase
+    {
+    public:
+        ValueTraits( const CXXTEST_STD(list)<Element> &l )
+        {
+            dumpRange( *this, l.begin(), l.end() );
+        }
+    };
+
+    //
+    // std::set
+    //
+    template<class Element>
+    class ValueTraits< CXXTEST_STD(set)<Element> > : public StdTraitsBase
+    {
+    public:
+        ValueTraits( const CXXTEST_STD(set)<Element> &s )
+        {
+            dumpRange( *this, s.begin(), s.end() );
+        }
+    };
+
+    //
+    // std::map
+    //
+    template<class Key, class Value>
+    class ValueTraits< CXXTEST_STD(map)<Key, Value> > : public StdTraitsBase
+    {
+    public:
+        ValueTraits( const CXXTEST_STD(map)<Key, Value> &m )
+        {
+            dumpRange( *this, m.begin(), m.end() );
+        }
+    };
+
+    //
+    // std::deque
+    //
+    template<class Element>
+    class ValueTraits< CXXTEST_STD(deque)<Element> > : public StdTraitsBase
+    {
+    public:
+        ValueTraits( const CXXTEST_STD(deque)<Element> &d )
+        {
+            dumpRange( *this, d.begin(), d.end() );
+        }
+    };
+
+    //
+    // std::multiset
+    //
+    template<class Element>
+    class ValueTraits< CXXTEST_STD(multiset)<Element> > : public StdTraitsBase
+    {
+    public:
+        ValueTraits( const CXXTEST_STD(multiset)<Element> &ms )
+        {
+            dumpRange( *this, ms.begin(), ms.end() );
+        }
+    };
+
+    //
+    // std::multimap
+    //
+    template<class Key, class Value>
+    class ValueTraits< CXXTEST_STD(multimap)<Key, Value> > : public StdTraitsBase
+    {
+    public:
+        ValueTraits( const CXXTEST_STD(multimap)<Key, Value> &mm )
+        {
+            dumpRange( *this, mm.begin(), mm.end() );
+        }
+    };
+
+    //
+    // std::complex
+    //
+    template<class Number>
+    class ValueTraits< CXXTEST_STD(complex)<Number> > : public StdTraitsBase
+    {
+    public:
+        ValueTraits( const CXXTEST_STD(complex)<Number> &c )
+        {
+            if ( !c.imag() )
+                *this << TS_AS_STRING(c.real());
+            else if ( !c.real() )
+                *this << "(" << TS_AS_STRING(c.imag()) << " * i)";
+            else
+                *this << "(" << TS_AS_STRING(c.real()) << " + " << TS_AS_STRING(c.imag()) << " * i)";
+        }
+    };
+#endif // _CXXTEST_PARTIAL_TEMPLATE_SPECIALIZATION
+};
+
+#endif // CXXTEST_USER_VALUE_TRAITS
+
+#endif // __cxxtest_StdValueTraits_h__
diff --git a/libpolys/tests/cxxtest/StdioFilePrinter.h b/libpolys/tests/cxxtest/StdioFilePrinter.h
new file mode 100644
index 0000000..33e0ca6
--- /dev/null
+++ b/libpolys/tests/cxxtest/StdioFilePrinter.h
@@ -0,0 +1,41 @@
+#ifndef __cxxtest__StdioFilePrinter_h__
+#define __cxxtest__StdioFilePrinter_h__
+
+//
+// The StdioFilePrinter is a simple TestListener that
+// just prints "OK" if everything goes well, otherwise
+// reports the error in the format of compiler messages.
+// This class uses <stdio.h>, i.e. FILE * and fprintf().
+//
+
+#include <cxxtest/ErrorFormatter.h>
+#include <stdio.h>
+
+namespace CxxTest
+{
+    class StdioFilePrinter : public ErrorFormatter
+    {
+    public:
+        StdioFilePrinter( FILE *o, const char *preLine = ":", const char *postLine = "" ) :
+            ErrorFormatter( new Adapter(o), preLine, postLine ) {}
+        virtual ~StdioFilePrinter() { delete outputStream(); }
+
+    private:
+        class Adapter : public OutputStream
+        {
+            Adapter( const Adapter & );
+            Adapter &operator=( const Adapter & );
+
+            FILE *_o;
+
+        public:
+            Adapter( FILE *o ) : _o(o) {}
+            void flush() { fflush( _o ); }
+            OutputStream &operator<<( unsigned i ) { fprintf( _o, "%u", i ); return *this; }
+            OutputStream &operator<<( const char *s ) { fputs( s, _o ); return *this; }
+            OutputStream &operator<<( Manipulator m ) { return OutputStream::operator<<( m ); }
+        };
+    };
+}
+
+#endif // __cxxtest__StdioFilePrinter_h__
diff --git a/libpolys/tests/cxxtest/StdioPrinter.h b/libpolys/tests/cxxtest/StdioPrinter.h
new file mode 100644
index 0000000..2b89f38
--- /dev/null
+++ b/libpolys/tests/cxxtest/StdioPrinter.h
@@ -0,0 +1,22 @@
+#ifndef __cxxtest__StdioPrinter_h__
+#define __cxxtest__StdioPrinter_h__
+
+//
+// The StdioPrinter is an StdioFilePrinter which defaults to stdout.
+// This should have been called StdOutPrinter or something, but the name
+// has been historically used.
+//
+
+#include <cxxtest/StdioFilePrinter.h>
+
+namespace CxxTest
+{
+    class StdioPrinter : public StdioFilePrinter
+    {
+    public:
+        StdioPrinter( FILE *o = stdout, const char *preLine = ":", const char *postLine = "" ) :
+            StdioFilePrinter( o, preLine, postLine ) {}
+    };
+}
+
+#endif // __cxxtest__StdioPrinter_h__
diff --git a/libpolys/tests/cxxtest/TeeListener.h b/libpolys/tests/cxxtest/TeeListener.h
new file mode 100644
index 0000000..29eeab9
--- /dev/null
+++ b/libpolys/tests/cxxtest/TeeListener.h
@@ -0,0 +1,182 @@
+#ifndef __cxxtest__TeeListener_h__
+#define __cxxtest__TeeListener_h__
+
+//
+// A TeeListener notifies two "reular" TestListeners
+//
+
+#include <cxxtest/TestListener.h>
+#include <cxxtest/TestListener.h>
+
+namespace CxxTest
+{
+    class TeeListener : public TestListener
+    {
+    public:
+        TeeListener()
+        {
+            setFirst( _dummy );
+            setSecond( _dummy );
+        }
+
+        virtual ~TeeListener()
+        {
+        }
+
+        void setFirst( TestListener &first )
+        {
+            _first = &first;
+        }
+
+        void setSecond( TestListener &second )
+        {
+            _second = &second;
+        }
+
+        void enterWorld( const WorldDescription &d )
+        {
+            _first->enterWorld( d );
+            _second->enterWorld( d );
+        }
+
+        void enterSuite( const SuiteDescription &d )
+        {
+            _first->enterSuite( d );
+            _second->enterSuite( d );
+        }
+
+        void enterTest( const TestDescription &d )
+        {
+            _first->enterTest( d );
+            _second->enterTest( d );
+        }
+
+        void trace( const char *file, unsigned line, const char *expression )
+        {
+            _first->trace( file, line, expression );
+            _second->trace( file, line, expression );
+        }
+
+        void warning( const char *file, unsigned line, const char *expression )
+        {
+            _first->warning( file, line, expression );
+            _second->warning( file, line, expression );
+        }
+
+        void failedTest( const char *file, unsigned line, const char *expression )
+        {
+            _first->failedTest( file, line, expression );
+            _second->failedTest( file, line, expression );
+        }
+
+        void failedAssert( const char *file, unsigned line, const char *expression )
+        {
+            _first->failedAssert( file, line, expression );
+            _second->failedAssert( file, line, expression );
+        }
+
+        void failedAssertEquals( const char *file, unsigned line,
+                                 const char *xStr, const char *yStr,
+                                 const char *x, const char *y )
+        {
+            _first->failedAssertEquals( file, line, xStr, yStr, x, y );
+            _second->failedAssertEquals( file, line, xStr, yStr, x, y );
+        }
+
+        void failedAssertSameData( const char *file, unsigned line,
+                                   const char *xStr, const char *yStr,
+                                   const char *sizeStr, const void *x,
+                                   const void *y, unsigned size )
+        {
+            _first->failedAssertSameData( file, line, xStr, yStr, sizeStr, x, y, size );
+            _second->failedAssertSameData( file, line, xStr, yStr, sizeStr, x, y, size );
+        }
+
+        void failedAssertDelta( const char *file, unsigned line,
+                                const char *xStr, const char *yStr, const char *dStr,
+                                const char *x, const char *y, const char *d )
+        {
+            _first->failedAssertDelta( file, line, xStr, yStr, dStr, x, y, d );
+            _second->failedAssertDelta( file, line, xStr, yStr, dStr, x, y, d );
+        }
+
+        void failedAssertDiffers( const char *file, unsigned line,
+                                  const char *xStr, const char *yStr,
+                                  const char *value )
+        {
+            _first->failedAssertDiffers( file, line, xStr, yStr, value );
+            _second->failedAssertDiffers( file, line, xStr, yStr, value );
+        }
+
+        void failedAssertLessThan( const char *file, unsigned line,
+                                   const char *xStr, const char *yStr,
+                                   const char *x, const char *y )
+        {
+            _first->failedAssertLessThan( file, line, xStr, yStr, x, y );
+            _second->failedAssertLessThan( file, line, xStr, yStr, x, y );
+        }
+
+        void failedAssertLessThanEquals( const char *file, unsigned line,
+                                         const char *xStr, const char *yStr,
+                                         const char *x, const char *y )
+        {
+            _first->failedAssertLessThanEquals( file, line, xStr, yStr, x, y );
+            _second->failedAssertLessThanEquals( file, line, xStr, yStr, x, y );
+        }
+
+        void failedAssertPredicate( const char *file, unsigned line,
+                                    const char *predicate, const char *xStr, const char *x )
+        {
+            _first->failedAssertPredicate( file, line, predicate, xStr, x );
+            _second->failedAssertPredicate( file, line, predicate, xStr, x );
+        }
+
+        void failedAssertRelation( const char *file, unsigned line,
+                                   const char *relation, const char *xStr, const char *yStr,
+                                   const char *x, const char *y )
+        {
+            _first->failedAssertRelation( file, line, relation, xStr, yStr, x, y );
+            _second->failedAssertRelation( file, line, relation, xStr, yStr, x, y );
+        }
+
+        void failedAssertThrows( const char *file, unsigned line,
+                                 const char *expression, const char *type,
+                                 bool otherThrown )
+        {
+            _first->failedAssertThrows( file, line, expression, type, otherThrown );
+            _second->failedAssertThrows( file, line, expression, type, otherThrown );
+        }
+
+        void failedAssertThrowsNot( const char *file, unsigned line,
+                                    const char *expression )
+        {
+            _first->failedAssertThrowsNot( file, line, expression );
+            _second->failedAssertThrowsNot( file, line, expression );
+        }
+
+        void leaveTest( const TestDescription &d )
+        {
+            _first->leaveTest(d);
+            _second->leaveTest(d);
+        }
+
+        void leaveSuite( const SuiteDescription &d )
+        {
+            _first->leaveSuite(d);
+            _second->leaveSuite(d);
+        }
+
+        void leaveWorld( const WorldDescription &d )
+        {
+            _first->leaveWorld(d);
+            _second->leaveWorld(d);
+        }
+
+    private:
+        TestListener *_first, *_second;
+        TestListener _dummy;
+    };
+};
+
+
+#endif // __cxxtest__TeeListener_h__
diff --git a/libpolys/tests/cxxtest/TestListener.h b/libpolys/tests/cxxtest/TestListener.h
new file mode 100644
index 0000000..982d66a
--- /dev/null
+++ b/libpolys/tests/cxxtest/TestListener.h
@@ -0,0 +1,70 @@
+#ifndef __cxxtest__TestListener_h__
+#define __cxxtest__TestListener_h__
+
+//
+// TestListener is the base class for all "listeners",
+// i.e. classes that receive notifications of the
+// testing process.
+//
+// The names of the parameters are in comments to avoid
+// "unused parameter" warnings.
+//
+
+#include <cxxtest/Descriptions.h>
+
+namespace CxxTest
+{
+    class TestListener
+    {
+    public:
+        TestListener() {}
+        virtual ~TestListener() {}
+
+        virtual void enterWorld( const WorldDescription & /*desc*/ ) {}
+        virtual void enterSuite( const SuiteDescription & /*desc*/ ) {}
+        virtual void enterTest( const TestDescription & /*desc*/ ) {}
+        virtual void trace( const char * /*file*/, unsigned /*line*/,
+                            const char * /*expression*/ ) {}
+        virtual void warning( const char * /*file*/, unsigned /*line*/,
+                              const char * /*expression*/ ) {}
+        virtual void failedTest( const char * /*file*/, unsigned /*line*/,
+                                 const char * /*expression*/ ) {}
+        virtual void failedAssert( const char * /*file*/, unsigned /*line*/,
+                                   const char * /*expression*/ ) {}
+        virtual void failedAssertEquals( const char * /*file*/, unsigned /*line*/,
+                                         const char * /*xStr*/, const char * /*yStr*/,
+                                         const char * /*x*/, const char * /*y*/ ) {}
+        virtual void failedAssertSameData( const char * /*file*/, unsigned /*line*/,
+                                           const char * /*xStr*/, const char * /*yStr*/,
+                                           const char * /*sizeStr*/, const void * /*x*/,
+                                           const void * /*y*/, unsigned /*size*/ ) {}
+        virtual void failedAssertDelta( const char * /*file*/, unsigned /*line*/,
+                                        const char * /*xStr*/, const char * /*yStr*/,
+                                        const char * /*dStr*/, const char * /*x*/,
+                                        const char * /*y*/, const char * /*d*/ ) {}
+        virtual void failedAssertDiffers( const char * /*file*/, unsigned /*line*/,
+                                          const char * /*xStr*/, const char * /*yStr*/,
+                                          const char * /*value*/ ) {}
+        virtual void failedAssertLessThan( const char * /*file*/, unsigned /*line*/,
+                                           const char * /*xStr*/, const char * /*yStr*/,
+                                           const char * /*x*/, const char * /*y*/ ) {}
+        virtual void failedAssertLessThanEquals( const char * /*file*/, unsigned /*line*/,
+                                                 const char * /*xStr*/, const char * /*yStr*/,
+                                                 const char * /*x*/, const char * /*y*/ ) {}
+        virtual void failedAssertPredicate( const char * /*file*/, unsigned /*line*/,
+                                            const char * /*predicate*/, const char * /*xStr*/, const char * /*x*/ ) {}
+        virtual void failedAssertRelation( const char * /*file*/, unsigned /*line*/,
+                                           const char * /*relation*/, const char * /*xStr*/, const char * /*yStr*/,
+                                           const char * /*x*/, const char * /*y*/ ) {}
+        virtual void failedAssertThrows( const char * /*file*/, unsigned /*line*/,
+                                         const char * /*expression*/, const char * /*type*/,
+                                         bool /*otherThrown*/ ) {}
+        virtual void failedAssertThrowsNot( const char * /*file*/, unsigned /*line*/,
+                                            const char * /*expression*/ ) {}
+        virtual void leaveTest( const TestDescription & /*desc*/ ) {}
+        virtual void leaveSuite( const SuiteDescription & /*desc*/ ) {}
+        virtual void leaveWorld( const WorldDescription & /*desc*/ ) {}
+    };
+}
+
+#endif // __cxxtest__TestListener_h__
diff --git a/libpolys/tests/cxxtest/TestRunner.h b/libpolys/tests/cxxtest/TestRunner.h
new file mode 100644
index 0000000..bd1983d
--- /dev/null
+++ b/libpolys/tests/cxxtest/TestRunner.h
@@ -0,0 +1,125 @@
+#ifndef __cxxtest_TestRunner_h__
+#define __cxxtest_TestRunner_h__
+
+//
+// TestRunner is the class that runs all the tests.
+// To use it, create an object that implements the TestListener
+// interface and call TestRunner::runAllTests( myListener );
+//
+
+#include <cxxtest/TestListener.h>
+#include <cxxtest/RealDescriptions.h>
+#include <cxxtest/TestSuite.h>
+#include <cxxtest/TestTracker.h>
+
+namespace CxxTest
+{
+    class TestRunner
+    {
+    public:
+        static void runAllTests( TestListener &listener )
+        {
+            tracker().setListener( &listener );
+            _TS_TRY { TestRunner().runWorld(); }
+            _TS_LAST_CATCH( { tracker().failedTest( __FILE__, __LINE__, "Exception thrown from world" ); } );
+            tracker().setListener( 0 );
+        }
+
+        static void runAllTests( TestListener *listener )
+        {
+            if ( listener ) {
+                listener->warning( __FILE__, __LINE__, "Deprecated; Use runAllTests( TestListener & )" );
+                runAllTests( *listener );
+            }
+        }
+
+    private:
+        void runWorld()
+        {
+            RealWorldDescription wd;
+            WorldGuard sg;
+
+            tracker().enterWorld( wd );
+            if ( wd.setUp() ) {
+                for ( SuiteDescription *sd = wd.firstSuite(); sd; sd = sd->next() )
+                    if ( sd->active() )
+                        runSuite( *sd );
+
+                wd.tearDown();
+            }
+            tracker().leaveWorld( wd );
+        }
+
+        void runSuite( SuiteDescription &sd )
+        {
+            StateGuard sg;
+
+            tracker().enterSuite( sd );
+            if ( sd.setUp() ) {
+                for ( TestDescription *td = sd.firstTest(); td; td = td->next() )
+                    if ( td->active() )
+                        runTest( *td );
+
+                sd.tearDown();
+            }
+            tracker().leaveSuite( sd );
+        }
+
+        void runTest( TestDescription &td )
+        {
+            StateGuard sg;
+
+            tracker().enterTest( td );
+            if ( td.setUp() ) {
+                td.run();
+                td.tearDown();
+            }
+            tracker().leaveTest( td );
+        }
+
+        class StateGuard
+        {
+#ifdef _CXXTEST_HAVE_EH
+            bool _abortTestOnFail;
+#endif // _CXXTEST_HAVE_EH
+            unsigned _maxDumpSize;
+
+        public:
+            StateGuard()
+            {
+#ifdef _CXXTEST_HAVE_EH
+                _abortTestOnFail = abortTestOnFail();
+#endif // _CXXTEST_HAVE_EH
+                _maxDumpSize = maxDumpSize();
+            }
+
+            ~StateGuard()
+            {
+#ifdef _CXXTEST_HAVE_EH
+                setAbortTestOnFail( _abortTestOnFail );
+#endif // _CXXTEST_HAVE_EH
+                setMaxDumpSize( _maxDumpSize );
+            }
+        };
+
+        class WorldGuard : public StateGuard
+        {
+        public:
+            WorldGuard() : StateGuard()
+            {
+#ifdef _CXXTEST_HAVE_EH
+                setAbortTestOnFail( CXXTEST_DEFAULT_ABORT );
+#endif // _CXXTEST_HAVE_EH
+                setMaxDumpSize( CXXTEST_MAX_DUMP_SIZE );
+            }
+        };
+    };
+
+    //
+    // For --no-static-init
+    //
+    void initialize();
+};
+
+
+#endif // __cxxtest_TestRunner_h__
diff --git a/libpolys/tests/cxxtest/TestSuite.cpp b/libpolys/tests/cxxtest/TestSuite.cpp
new file mode 100644
index 0000000..8c828da
--- /dev/null
+++ b/libpolys/tests/cxxtest/TestSuite.cpp
@@ -0,0 +1,138 @@
+#ifndef __cxxtest__TestSuite_cpp__
+#define __cxxtest__TestSuite_cpp__
+
+#include <cxxtest/TestSuite.h>
+
+namespace CxxTest
+{
+    //
+    // TestSuite members
+    //
+    TestSuite::~TestSuite() {}
+    void TestSuite::setUp() {}
+    void TestSuite::tearDown() {}
+
+    //
+    // Test-aborting stuff
+    //
+    static bool currentAbortTestOnFail = false;
+
+    bool abortTestOnFail()
+    {
+        return currentAbortTestOnFail;
+    }
+
+    void setAbortTestOnFail( bool value )
+    {
+        currentAbortTestOnFail = value;
+    }
+
+    void doAbortTest()
+    {
+#   if defined(_CXXTEST_HAVE_EH)
+        if ( currentAbortTestOnFail )
+            throw AbortTest();
+#   endif // _CXXTEST_HAVE_EH
+    }
+
+    //
+    // Max dump size
+    //
+    static unsigned currentMaxDumpSize = CXXTEST_MAX_DUMP_SIZE;
+
+    unsigned maxDumpSize()
+    {
+        return currentMaxDumpSize;
+    }
+
+    void setMaxDumpSize( unsigned value )
+    {
+        currentMaxDumpSize = value;
+    }
+
+    //
+    // Some non-template functions
+    //
+    void doTrace( const char *file, unsigned line, const char *message )
+    {
+        tracker().trace( file, line, message );
+    }
+
+    void doWarn( const char *file, unsigned line, const char *message )
+    {
+        tracker().warning( file, line, message );
+    }
+
+    void doFailTest( const char *file, unsigned line, const char *message )
+    {
+        tracker().failedTest( file, line, message );
+        TS_ABORT();
+    }
+
+    void doFailAssert( const char *file, unsigned line,
+                       const char *expression, const char *message )
+    {
+        if ( message )
+            tracker().failedTest( file, line, message );
+        tracker().failedAssert( file, line, expression );
+        TS_ABORT();
+    }
+
+    bool sameData( const void *x, const void *y, unsigned size )
+    {
+        if ( size == 0 )
+            return true;
+
+        if ( x == y )
+            return true;
+
+        if ( !x || !y )
+            return false;
+
+        const char *cx = (const char *)x;
+        const char *cy = (const char *)y;
+        while ( size -- )
+            if ( *cx++ != *cy++ )
+                return false;
+
+        return true;
+    }
+
+    void doAssertSameData( const char *file, unsigned line,
+                           const char *xExpr, const void *x,
+                           const char *yExpr, const void *y,
+                           const char *sizeExpr, unsigned size,
+                           const char *message )
+    {
+        if ( !sameData( x, y, size ) ) {
+            if ( message )
+                tracker().failedTest( file, line, message );
+            tracker().failedAssertSameData( file, line, xExpr, yExpr, sizeExpr, x, y, size );
+            TS_ABORT();
+        }
+    }
+
+    void doFailAssertThrows( const char *file, unsigned line,
+                             const char *expr, const char *type,
+                             bool otherThrown,
+                             const char *message )
+    {
+        if ( message )
+            tracker().failedTest( file, line, message );
+
+        tracker().failedAssertThrows( file, line, expr, type, otherThrown );
+        TS_ABORT();
+    }
+
+    void doFailAssertThrowsNot( const char *file, unsigned line,
+                                const char *expression, const char *message )
+    {
+        if ( message )
+            tracker().failedTest( file, line, message );
+
+        tracker().failedAssertThrowsNot( file, line, expression );
+        TS_ABORT();
+    }
+};
+
+#endif // __cxxtest__TestSuite_cpp__
diff --git a/libpolys/tests/cxxtest/TestSuite.h b/libpolys/tests/cxxtest/TestSuite.h
new file mode 100644
index 0000000..92fa4ea
--- /dev/null
+++ b/libpolys/tests/cxxtest/TestSuite.h
@@ -0,0 +1,512 @@
+#ifndef __cxxtest__TestSuite_h__
+#define __cxxtest__TestSuite_h__
+
+//
+// class TestSuite is the base class for all test suites.
+// To define a test suite, derive from this class and add
+// member functions called void test*();
+//
+
+#include <cxxtest/Flags.h>
+#include <cxxtest/TestTracker.h>
+#include <cxxtest/Descriptions.h>
+#include <cxxtest/ValueTraits.h>
+
+#ifdef _CXXTEST_HAVE_STD
+#   include <stdexcept>
+#endif // _CXXTEST_HAVE_STD
+
+namespace CxxTest
+{
+    class TestSuite
+    {
+    public:
+        virtual ~TestSuite();
+        virtual void setUp();
+        virtual void tearDown();
+    };
+
+    class AbortTest {};
+    void doAbortTest();
+#   define TS_ABORT() CxxTest::doAbortTest()
+
+    bool abortTestOnFail();
+    void setAbortTestOnFail( bool value = CXXTEST_DEFAULT_ABORT );
+
+    unsigned maxDumpSize();
+    void setMaxDumpSize( unsigned value = CXXTEST_MAX_DUMP_SIZE );
+
+    void doTrace( const char *file, unsigned line, const char *message );
+    void doWarn( const char *file, unsigned line, const char *message );
+    void doFailTest( const char *file, unsigned line, const char *message );
+    void doFailAssert( const char *file, unsigned line, const char *expression, const char *message );
+
+    template<class X, class Y>
+    bool equals( X x, Y y )
+    {
+        return (x == y);
+    }
+
+    template<class X, class Y>
+    void doAssertEquals( const char *file, unsigned line,
+                         const char *xExpr, X x,
+                         const char *yExpr, Y y,
+                         const char *message )
+    {
+        if ( !equals( x, y ) ) {
+            if ( message )
+                tracker().failedTest( file, line, message );
+            tracker().failedAssertEquals( file, line, xExpr, yExpr, TS_AS_STRING(x), TS_AS_STRING(y) );
+            TS_ABORT();
+        }
+    }
+
+    void doAssertSameData( const char *file, unsigned line,
+                           const char *xExpr, const void *x,
+                           const char *yExpr, const void *y,
+                           const char *sizeExpr, unsigned size,
+                           const char *message );
+
+    template<class X, class Y>
+    bool differs( X x, Y y )
+    {
+        return !(x == y);
+    }
+
+    template<class X, class Y>
+    void doAssertDiffers( const char *file, unsigned line,
+                          const char *xExpr, X x,
+                          const char *yExpr, Y y,
+                          const char *message )
+    {
+        if ( !differs( x, y ) ) {
+            if ( message )
+                tracker().failedTest( file, line, message );
+            tracker().failedAssertDiffers( file, line, xExpr, yExpr, TS_AS_STRING(x) );
+            TS_ABORT();
+        }
+    }
+
+    template<class X, class Y>
+    bool lessThan( X x, Y y )
+    {
+        return (x < y);
+    }
+
+    template<class X, class Y>
+    void doAssertLessThan( const char *file, unsigned line,
+                           const char *xExpr, X x,
+                           const char *yExpr, Y y,
+                           const char *message )
+    {
+        if ( !lessThan(x, y) ) {
+            if ( message )
+                tracker().failedTest( file, line, message );
+            tracker().failedAssertLessThan( file, line, xExpr, yExpr, TS_AS_STRING(x), TS_AS_STRING(y) );
+            TS_ABORT();
+        }
+    }
+
+    template<class X, class Y>
+    bool lessThanEquals( X x, Y y )
+    {
+        return (x <= y);
+    }
+
+    template<class X, class Y>
+    void doAssertLessThanEquals( const char *file, unsigned line,
+                                 const char *xExpr, X x,
+                                 const char *yExpr, Y y,
+                                 const char *message )
+    {
+        if ( !lessThanEquals( x, y ) ) {
+            if ( message )
+                tracker().failedTest( file, line, message );
+            tracker().failedAssertLessThanEquals( file, line, xExpr, yExpr, TS_AS_STRING(x), TS_AS_STRING(y) );
+            TS_ABORT();
+        }
+    }
+
+    template<class X, class P>
+    void doAssertPredicate( const char *file, unsigned line,
+                            const char *pExpr, const P &p,
+                            const char *xExpr, X x,
+                            const char *message )
+    {
+        if ( !p( x ) ) {
+            if ( message )
+                tracker().failedTest( file, line, message );
+            tracker().failedAssertPredicate( file, line, pExpr, xExpr, TS_AS_STRING(x) );
+            TS_ABORT();
+        }
+    }
+
+    template<class X, class Y, class R>
+    void doAssertRelation( const char *file, unsigned line,
+                           const char *rExpr, const R &r,
+                           const char *xExpr, X x,
+                           const char *yExpr, Y y,
+                           const char *message )
+    {
+        if ( !r( x, y ) ) {
+            if ( message )
+                tracker().failedTest( file, line, message );
+            tracker().failedAssertRelation( file, line, rExpr, xExpr, yExpr, TS_AS_STRING(x), TS_AS_STRING(y) );
+            TS_ABORT();
+        }
+    }
+
+    template<class X, class Y, class D>
+    bool delta( X x, Y y, D d )
+    {
+        return ((y >= x - d) && (y <= x + d));
+    }
+
+    template<class X, class Y, class D>
+    void doAssertDelta( const char *file, unsigned line,
+                        const char *xExpr, X x,
+                        const char *yExpr, Y y,
+                        const char *dExpr, D d,
+                        const char *message )
+    {
+        if ( !delta( x, y, d ) ) {
+            if ( message )
+                tracker().failedTest( file, line, message );
+
+            tracker().failedAssertDelta( file, line, xExpr, yExpr, dExpr,
+                                         TS_AS_STRING(x), TS_AS_STRING(y), TS_AS_STRING(d) );
+            TS_ABORT();
+        }
+    }
+
+    void doFailAssertThrows( const char *file, unsigned line,
+                             const char *expr, const char *type,
+                             bool otherThrown,
+                             const char *message );
+
+    void doFailAssertThrowsNot( const char *file, unsigned line,
+                                const char *expression, const char *message );
+
+#   ifdef _CXXTEST_HAVE_EH
+#       define _TS_TRY try
+#       define _TS_CATCH_TYPE(t, b) catch t b
+#       define _TS_CATCH_ABORT(b) _TS_CATCH_TYPE( (const CxxTest::AbortTest &), b )
+#       define _TS_LAST_CATCH(b) _TS_CATCH_TYPE( (...), b )
+#       define _TSM_LAST_CATCH(f,l,m) _TS_LAST_CATCH( { (CxxTest::tracker()).failedTest(f,l,m); } )
+#       ifdef _CXXTEST_HAVE_STD
+#           define ___TSM_CATCH(f,l,m) \
+                    catch(const std::exception &e) { (CxxTest::tracker()).failedTest(f,l,e.what()); } \
+                    _TSM_LAST_CATCH(f,l,m)
+#       else // !_CXXTEST_HAVE_STD
+#           define ___TSM_CATCH(f,l,m) _TSM_LAST_CATCH(f,l,m)
+#       endif // _CXXTEST_HAVE_STD
+#       define __TSM_CATCH(f,l,m) \
+                _TS_CATCH_ABORT( { throw; } ) \
+                ___TSM_CATCH(f,l,m)
+#       define __TS_CATCH(f,l) __TSM_CATCH(f,l,"Unhandled exception")
+#       define _TS_CATCH __TS_CATCH(__FILE__,__LINE__)
+#   else // !_CXXTEST_HAVE_EH
+#       define _TS_TRY
+#       define ___TSM_CATCH(f,l,m)
+#       define __TSM_CATCH(f,l,m)
+#       define __TS_CATCH(f,l)
+#       define _TS_CATCH
+#       define _TS_CATCH_TYPE(t, b)
+#       define _TS_LAST_CATCH(b)
+#       define _TS_CATCH_ABORT(b)
+#   endif // _CXXTEST_HAVE_EH
+
+    // TS_TRACE
+#   define _TS_TRACE(f,l,e) CxxTest::doTrace( (f), (l), TS_AS_STRING(e) )
+#   define TS_TRACE(e) _TS_TRACE( __FILE__, __LINE__, e )
+
+    // TS_WARN
+#   define _TS_WARN(f,l,e) CxxTest::doWarn( (f), (l), TS_AS_STRING(e) )
+#   define TS_WARN(e) _TS_WARN( __FILE__, __LINE__, e )
+
+    // TS_FAIL
+#   define _TS_FAIL(f,l,e) CxxTest::doFailTest( (f), (l), TS_AS_STRING(e) )
+#   define TS_FAIL(e) _TS_FAIL( __FILE__, __LINE__, e )
+
+    // TS_ASSERT
+#   define ___ETS_ASSERT(f,l,e,m) { if ( !(e) ) CxxTest::doFailAssert( (f), (l), #e, (m) ); }
+#   define ___TS_ASSERT(f,l,e,m) { _TS_TRY { ___ETS_ASSERT(f,l,e,m); } __TS_CATCH(f,l) }
+
+#   define _ETS_ASSERT(f,l,e) ___ETS_ASSERT(f,l,e,0)
+#   define _TS_ASSERT(f,l,e) ___TS_ASSERT(f,l,e,0)
+
+#   define ETS_ASSERT(e) _ETS_ASSERT(__FILE__,__LINE__,e)
+#   define TS_ASSERT(e) _TS_ASSERT(__FILE__,__LINE__,e)
+
+#   define _ETSM_ASSERT(f,l,m,e) ___ETS_ASSERT(f,l,e,TS_AS_STRING(m) )
+#   define _TSM_ASSERT(f,l,m,e) ___TS_ASSERT(f,l,e,TS_AS_STRING(m) )
+
+#   define ETSM_ASSERT(m,e) _ETSM_ASSERT(__FILE__,__LINE__,m,e)
+#   define TSM_ASSERT(m,e) _TSM_ASSERT(__FILE__,__LINE__,m,e)
+
+    // TS_ASSERT_EQUALS
+#   define ___ETS_ASSERT_EQUALS(f,l,x,y,m) CxxTest::doAssertEquals( (f), (l), #x, (x), #y, (y), (m) )
+#   define ___TS_ASSERT_EQUALS(f,l,x,y,m) { _TS_TRY { ___ETS_ASSERT_EQUALS(f,l,x,y,m); } __TS_CATCH(f,l) }
+
+#   define _ETS_ASSERT_EQUALS(f,l,x,y) ___ETS_ASSERT_EQUALS(f,l,x,y,0)
+#   define _TS_ASSERT_EQUALS(f,l,x,y) ___TS_ASSERT_EQUALS(f,l,x,y,0)
+
+#   define ETS_ASSERT_EQUALS(x,y) _ETS_ASSERT_EQUALS(__FILE__,__LINE__,x,y)
+#   define TS_ASSERT_EQUALS(x,y) _TS_ASSERT_EQUALS(__FILE__,__LINE__,x,y)
+
+#   define _ETSM_ASSERT_EQUALS(f,l,m,x,y) ___ETS_ASSERT_EQUALS(f,l,x,y,TS_AS_STRING(m))
+#   define _TSM_ASSERT_EQUALS(f,l,m,x,y) ___TS_ASSERT_EQUALS(f,l,x,y,TS_AS_STRING(m))
+
+#   define ETSM_ASSERT_EQUALS(m,x,y) _ETSM_ASSERT_EQUALS(__FILE__,__LINE__,m,x,y)
+#   define TSM_ASSERT_EQUALS(m,x,y) _TSM_ASSERT_EQUALS(__FILE__,__LINE__,m,x,y)
+
+    // TS_ASSERT_SAME_DATA
+#   define ___ETS_ASSERT_SAME_DATA(f,l,x,y,s,m) CxxTest::doAssertSameData( (f), (l), #x, (x), #y, (y), #s, (s), (m) )
+#   define ___TS_ASSERT_SAME_DATA(f,l,x,y,s,m) { _TS_TRY { ___ETS_ASSERT_SAME_DATA(f,l,x,y,s,m); } __TS_CATCH(f,l) }
+
+#   define _ETS_ASSERT_SAME_DATA(f,l,x,y,s) ___ETS_ASSERT_SAME_DATA(f,l,x,y,s,0)
+#   define _TS_ASSERT_SAME_DATA(f,l,x,y,s) ___TS_ASSERT_SAME_DATA(f,l,x,y,s,0)
+
+#   define ETS_ASSERT_SAME_DATA(x,y,s) _ETS_ASSERT_SAME_DATA(__FILE__,__LINE__,x,y,s)
+#   define TS_ASSERT_SAME_DATA(x,y,s) _TS_ASSERT_SAME_DATA(__FILE__,__LINE__,x,y,s)
+
+#   define _ETSM_ASSERT_SAME_DATA(f,l,m,x,y,s) ___ETS_ASSERT_SAME_DATA(f,l,x,y,s,TS_AS_STRING(m))
+#   define _TSM_ASSERT_SAME_DATA(f,l,m,x,y,s) ___TS_ASSERT_SAME_DATA(f,l,x,y,s,TS_AS_STRING(m))
+
+#   define ETSM_ASSERT_SAME_DATA(m,x,y,s) _ETSM_ASSERT_SAME_DATA(__FILE__,__LINE__,m,x,y,s)
+#   define TSM_ASSERT_SAME_DATA(m,x,y,s) _TSM_ASSERT_SAME_DATA(__FILE__,__LINE__,m,x,y,s)
+
+    // TS_ASSERT_DIFFERS
+#   define ___ETS_ASSERT_DIFFERS(f,l,x,y,m) CxxTest::doAssertDiffers( (f), (l), #x, (x), #y, (y), (m) )
+#   define ___TS_ASSERT_DIFFERS(f,l,x,y,m) { _TS_TRY { ___ETS_ASSERT_DIFFERS(f,l,x,y,m); } __TS_CATCH(f,l) }
+
+#   define _ETS_ASSERT_DIFFERS(f,l,x,y) ___ETS_ASSERT_DIFFERS(f,l,x,y,0)
+#   define _TS_ASSERT_DIFFERS(f,l,x,y) ___TS_ASSERT_DIFFERS(f,l,x,y,0)
+
+#   define ETS_ASSERT_DIFFERS(x,y) _ETS_ASSERT_DIFFERS(__FILE__,__LINE__,x,y)
+#   define TS_ASSERT_DIFFERS(x,y) _TS_ASSERT_DIFFERS(__FILE__,__LINE__,x,y)
+
+#   define _ETSM_ASSERT_DIFFERS(f,l,m,x,y) ___ETS_ASSERT_DIFFERS(f,l,x,y,TS_AS_STRING(m))
+#   define _TSM_ASSERT_DIFFERS(f,l,m,x,y) ___TS_ASSERT_DIFFERS(f,l,x,y,TS_AS_STRING(m))
+
+#   define ETSM_ASSERT_DIFFERS(m,x,y) _ETSM_ASSERT_DIFFERS(__FILE__,__LINE__,m,x,y)
+#   define TSM_ASSERT_DIFFERS(m,x,y) _TSM_ASSERT_DIFFERS(__FILE__,__LINE__,m,x,y)
+
+    // TS_ASSERT_LESS_THAN
+#   define ___ETS_ASSERT_LESS_THAN(f,l,x,y,m) CxxTest::doAssertLessThan( (f), (l), #x, (x), #y, (y), (m) )
+#   define ___TS_ASSERT_LESS_THAN(f,l,x,y,m) { _TS_TRY { ___ETS_ASSERT_LESS_THAN(f,l,x,y,m); } __TS_CATCH(f,l) }
+
+#   define _ETS_ASSERT_LESS_THAN(f,l,x,y) ___ETS_ASSERT_LESS_THAN(f,l,x,y,0)
+#   define _TS_ASSERT_LESS_THAN(f,l,x,y) ___TS_ASSERT_LESS_THAN(f,l,x,y,0)
+
+#   define ETS_ASSERT_LESS_THAN(x,y) _ETS_ASSERT_LESS_THAN(__FILE__,__LINE__,x,y)
+#   define TS_ASSERT_LESS_THAN(x,y) _TS_ASSERT_LESS_THAN(__FILE__,__LINE__,x,y)
+
+#   define _ETSM_ASSERT_LESS_THAN(f,l,m,x,y) ___ETS_ASSERT_LESS_THAN(f,l,x,y,TS_AS_STRING(m))
+#   define _TSM_ASSERT_LESS_THAN(f,l,m,x,y) ___TS_ASSERT_LESS_THAN(f,l,x,y,TS_AS_STRING(m))
+
+#   define ETSM_ASSERT_LESS_THAN(m,x,y) _ETSM_ASSERT_LESS_THAN(__FILE__,__LINE__,m,x,y)
+#   define TSM_ASSERT_LESS_THAN(m,x,y) _TSM_ASSERT_LESS_THAN(__FILE__,__LINE__,m,x,y)
+
+    // TS_ASSERT_LESS_THAN_EQUALS
+#   define ___ETS_ASSERT_LESS_THAN_EQUALS(f,l,x,y,m) \
+        CxxTest::doAssertLessThanEquals( (f), (l), #x, (x), #y, (y), (m) )
+#   define ___TS_ASSERT_LESS_THAN_EQUALS(f,l,x,y,m) \
+        { _TS_TRY { ___ETS_ASSERT_LESS_THAN_EQUALS(f,l,x,y,m); } __TS_CATCH(f,l) }
+
+#   define _ETS_ASSERT_LESS_THAN_EQUALS(f,l,x,y) ___ETS_ASSERT_LESS_THAN_EQUALS(f,l,x,y,0)
+#   define _TS_ASSERT_LESS_THAN_EQUALS(f,l,x,y) ___TS_ASSERT_LESS_THAN_EQUALS(f,l,x,y,0)
+
+#   define ETS_ASSERT_LESS_THAN_EQUALS(x,y) _ETS_ASSERT_LESS_THAN_EQUALS(__FILE__,__LINE__,x,y)
+#   define TS_ASSERT_LESS_THAN_EQUALS(x,y) _TS_ASSERT_LESS_THAN_EQUALS(__FILE__,__LINE__,x,y)
+
+#   define _ETSM_ASSERT_LESS_THAN_EQUALS(f,l,m,x,y) ___ETS_ASSERT_LESS_THAN_EQUALS(f,l,x,y,TS_AS_STRING(m))
+#   define _TSM_ASSERT_LESS_THAN_EQUALS(f,l,m,x,y) ___TS_ASSERT_LESS_THAN_EQUALS(f,l,x,y,TS_AS_STRING(m))
+
+#   define ETSM_ASSERT_LESS_THAN_EQUALS(m,x,y) _ETSM_ASSERT_LESS_THAN_EQUALS(__FILE__,__LINE__,m,x,y)
+#   define TSM_ASSERT_LESS_THAN_EQUALS(m,x,y) _TSM_ASSERT_LESS_THAN_EQUALS(__FILE__,__LINE__,m,x,y)
+
+    // TS_ASSERT_PREDICATE
+#   define ___ETS_ASSERT_PREDICATE(f,l,p,x,m) \
+        CxxTest::doAssertPredicate( (f), (l), #p, p, #x, (x), (m) )
+#   define ___TS_ASSERT_PREDICATE(f,l,p,x,m) \
+        { _TS_TRY { ___ETS_ASSERT_PREDICATE(f,l,p,x,m); } __TS_CATCH(f,l) }
+
+#   define _ETS_ASSERT_PREDICATE(f,l,p,x) ___ETS_ASSERT_PREDICATE(f,l,p,x,0)
+#   define _TS_ASSERT_PREDICATE(f,l,p,x) ___TS_ASSERT_PREDICATE(f,l,p,x,0)
+
+#   define ETS_ASSERT_PREDICATE(p,x) _ETS_ASSERT_PREDICATE(__FILE__,__LINE__,p,x)
+#   define TS_ASSERT_PREDICATE(p,x) _TS_ASSERT_PREDICATE(__FILE__,__LINE__,p,x)
+
+#   define _ETSM_ASSERT_PREDICATE(f,l,m,p,x) ___ETS_ASSERT_PREDICATE(f,l,p,x,TS_AS_STRING(m))
+#   define _TSM_ASSERT_PREDICATE(f,l,m,p,x) ___TS_ASSERT_PREDICATE(f,l,p,x,TS_AS_STRING(m))
+
+#   define ETSM_ASSERT_PREDICATE(m,p,x) _ETSM_ASSERT_PREDICATE(__FILE__,__LINE__,m,p,x)
+#   define TSM_ASSERT_PREDICATE(m,p,x) _TSM_ASSERT_PREDICATE(__FILE__,__LINE__,m,p,x)
+
+    // TS_ASSERT_RELATION
+#   define ___ETS_ASSERT_RELATION(f,l,r,x,y,m) \
+        CxxTest::doAssertRelation( (f), (l), #r, r(), #x, (x), #y, (y), (m) )
+#   define ___TS_ASSERT_RELATION(f,l,r,x,y,m) \
+        { _TS_TRY { ___ETS_ASSERT_RELATION(f,l,r,x,y,m); } __TS_CATCH(f,l) }
+
+#   define _ETS_ASSERT_RELATION(f,l,r,x,y) ___ETS_ASSERT_RELATION(f,l,r,x,y,0)
+#   define _TS_ASSERT_RELATION(f,l,r,x,y) ___TS_ASSERT_RELATION(f,l,r,x,y,0)
+
+#   define ETS_ASSERT_RELATION(r,x,y) _ETS_ASSERT_RELATION(__FILE__,__LINE__,r,x,y)
+#   define TS_ASSERT_RELATION(r,x,y) _TS_ASSERT_RELATION(__FILE__,__LINE__,r,x,y)
+
+#   define _ETSM_ASSERT_RELATION(f,l,m,r,x,y) ___ETS_ASSERT_RELATION(f,l,r,x,y,TS_AS_STRING(m))
+#   define _TSM_ASSERT_RELATION(f,l,m,r,x,y) ___TS_ASSERT_RELATION(f,l,r,x,y,TS_AS_STRING(m))
+
+#   define ETSM_ASSERT_RELATION(m,r,x,y) _ETSM_ASSERT_RELATION(__FILE__,__LINE__,m,r,x,y)
+#   define TSM_ASSERT_RELATION(m,r,x,y) _TSM_ASSERT_RELATION(__FILE__,__LINE__,m,r,x,y)
+
+    // TS_ASSERT_DELTA
+#   define ___ETS_ASSERT_DELTA(f,l,x,y,d,m) CxxTest::doAssertDelta( (f), (l), #x, (x), #y, (y), #d, (d), (m) )
+#   define ___TS_ASSERT_DELTA(f,l,x,y,d,m) { _TS_TRY { ___ETS_ASSERT_DELTA(f,l,x,y,d,m); } __TS_CATCH(f,l) }
+
+#   define _ETS_ASSERT_DELTA(f,l,x,y,d) ___ETS_ASSERT_DELTA(f,l,x,y,d,0)
+#   define _TS_ASSERT_DELTA(f,l,x,y,d) ___TS_ASSERT_DELTA(f,l,x,y,d,0)
+
+#   define ETS_ASSERT_DELTA(x,y,d) _ETS_ASSERT_DELTA(__FILE__,__LINE__,x,y,d)
+#   define TS_ASSERT_DELTA(x,y,d) _TS_ASSERT_DELTA(__FILE__,__LINE__,x,y,d)
+
+#   define _ETSM_ASSERT_DELTA(f,l,m,x,y,d) ___ETS_ASSERT_DELTA(f,l,x,y,d,TS_AS_STRING(m))
+#   define _TSM_ASSERT_DELTA(f,l,m,x,y,d) ___TS_ASSERT_DELTA(f,l,x,y,d,TS_AS_STRING(m))
+
+#   define ETSM_ASSERT_DELTA(m,x,y,d) _ETSM_ASSERT_DELTA(__FILE__,__LINE__,m,x,y,d)
+#   define TSM_ASSERT_DELTA(m,x,y,d) _TSM_ASSERT_DELTA(__FILE__,__LINE__,m,x,y,d)
+
+    // TS_ASSERT_THROWS
+#   define ___TS_ASSERT_THROWS(f,l,e,t,m) { \
+            bool _ts_threw_expected = false, _ts_threw_else = false; \
+            _TS_TRY { e; } \
+            _TS_CATCH_TYPE( (t), { _ts_threw_expected = true; } ) \
+            _TS_CATCH_ABORT( { throw; } ) \
+            _TS_LAST_CATCH( { _ts_threw_else = true; } ) \
+            if ( !_ts_threw_expected ) { CxxTest::doFailAssertThrows( (f), (l), #e, #t, _ts_threw_else, (m) ); } }
+
+#   define _TS_ASSERT_THROWS(f,l,e,t) ___TS_ASSERT_THROWS(f,l,e,t,0)
+#   define TS_ASSERT_THROWS(e,t) _TS_ASSERT_THROWS(__FILE__,__LINE__,e,t)
+
+#   define _TSM_ASSERT_THROWS(f,l,m,e,t) ___TS_ASSERT_THROWS(f,l,e,t,TS_AS_STRING(m))
+#   define TSM_ASSERT_THROWS(m,e,t) _TSM_ASSERT_THROWS(__FILE__,__LINE__,m,e,t)
+
+    // TS_ASSERT_THROWS_ASSERT
+#   define ___TS_ASSERT_THROWS_ASSERT(f,l,e,t,a,m) { \
+            bool _ts_threw_expected = false, _ts_threw_else = false; \
+            _TS_TRY { e; } \
+            _TS_CATCH_TYPE( (t), { a; _ts_threw_expected = true; } ) \
+            _TS_CATCH_ABORT( { throw; } ) \
+            _TS_LAST_CATCH( { _ts_threw_else = true; } ) \
+            if ( !_ts_threw_expected ) { CxxTest::doFailAssertThrows( (f), (l), #e, #t, _ts_threw_else, (m) ); } }
+
+#   define _TS_ASSERT_THROWS_ASSERT(f,l,e,t,a) ___TS_ASSERT_THROWS_ASSERT(f,l,e,t,a,0)
+#   define TS_ASSERT_THROWS_ASSERT(e,t,a) _TS_ASSERT_THROWS_ASSERT(__FILE__,__LINE__,e,t,a)
+
+#   define _TSM_ASSERT_THROWS_ASSERT(f,l,m,e,t,a) ___TS_ASSERT_THROWS_ASSERT(f,l,e,t,a,TS_AS_STRING(m))
+#   define TSM_ASSERT_THROWS_ASSERT(m,e,t,a) _TSM_ASSERT_THROWS_ASSERT(__FILE__,__LINE__,m,e,t,a)
+
+    // TS_ASSERT_THROWS_EQUALS
+#   define TS_ASSERT_THROWS_EQUALS(e,t,x,y) TS_ASSERT_THROWS_ASSERT(e,t,TS_ASSERT_EQUALS(x,y))
+#   define TSM_ASSERT_THROWS_EQUALS(m,e,t,x,y) TSM_ASSERT_THROWS_ASSERT(m,e,t,TSM_ASSERT_EQUALS(m,x,y))
+
+    // TS_ASSERT_THROWS_DIFFERS
+#   define TS_ASSERT_THROWS_DIFFERS(e,t,x,y) TS_ASSERT_THROWS_ASSERT(e,t,TS_ASSERT_DIFFERS(x,y))
+#   define TSM_ASSERT_THROWS_DIFFERS(m,e,t,x,y) TSM_ASSERT_THROWS_ASSERT(m,e,t,TSM_ASSERT_DIFFERS(m,x,y))
+
+    // TS_ASSERT_THROWS_DELTA
+#   define TS_ASSERT_THROWS_DELTA(e,t,x,y,d) TS_ASSERT_THROWS_ASSERT(e,t,TS_ASSERT_DELTA(x,y,d))
+#   define TSM_ASSERT_THROWS_DELTA(m,e,t,x,y,d) TSM_ASSERT_THROWS_ASSERT(m,e,t,TSM_ASSERT_DELTA(m,x,y,d))
+
+    // TS_ASSERT_THROWS_SAME_DATA
+#   define TS_ASSERT_THROWS_SAME_DATA(e,t,x,y,s) TS_ASSERT_THROWS_ASSERT(e,t,TS_ASSERT_SAME_DATA(x,y,s))
+#   define TSM_ASSERT_THROWS_SAME_DATA(m,e,t,x,y,s) TSM_ASSERT_THROWS_ASSERT(m,e,t,TSM_ASSERT_SAME_DATA(m,x,y,s))
+
+    // TS_ASSERT_THROWS_LESS_THAN
+#   define TS_ASSERT_THROWS_LESS_THAN(e,t,x,y) TS_ASSERT_THROWS_ASSERT(e,t,TS_ASSERT_LESS_THAN(x,y))
+#   define TSM_ASSERT_THROWS_LESS_THAN(m,e,t,x,y) TSM_ASSERT_THROWS_ASSERT(m,e,t,TSM_ASSERT_LESS_THAN(m,x,y))
+
+    // TS_ASSERT_THROWS_LESS_THAN_EQUALS
+#   define TS_ASSERT_THROWS_LESS_THAN_EQUALS(e,t,x,y) TS_ASSERT_THROWS_ASSERT(e,t,TS_ASSERT_LESS_THAN_EQUALS(x,y))
+#   define TSM_ASSERT_THROWS_LESS_THAN_EQUALS(m,e,t,x,y) TSM_ASSERT_THROWS_ASSERT(m,e,t,TSM_ASSERT_LESS_THAN_EQUALS(m,x,y))
+
+    // TS_ASSERT_THROWS_PREDICATE
+#   define TS_ASSERT_THROWS_PREDICATE(e,t,p,v) TS_ASSERT_THROWS_ASSERT(e,t,TS_ASSERT_PREDICATE(p,v))
+#   define TSM_ASSERT_THROWS_PREDICATE(m,e,t,p,v) TSM_ASSERT_THROWS_ASSERT(m,e,t,TSM_ASSERT_PREDICATE(m,p,v))
+
+    // TS_ASSERT_THROWS_RELATION
+#   define TS_ASSERT_THROWS_RELATION(e,t,r,x,y) TS_ASSERT_THROWS_ASSERT(e,t,TS_ASSERT_RELATION(r,x,y))
+#   define TSM_ASSERT_THROWS_RELATION(m,e,t,r,x,y) TSM_ASSERT_THROWS_ASSERT(m,e,t,TSM_ASSERT_RELATION(m,r,x,y))
+
+    // TS_ASSERT_THROWS_ANYTHING
+#   define ___TS_ASSERT_THROWS_ANYTHING(f,l,e,m) { \
+            bool _ts_threw = false; \
+            _TS_TRY { e; } \
+            _TS_LAST_CATCH( { _ts_threw = true; } ) \
+            if ( !_ts_threw ) { CxxTest::doFailAssertThrows( (f), (l), #e, "...", false, (m) ); } }
+
+#   define _TS_ASSERT_THROWS_ANYTHING(f,l,e) ___TS_ASSERT_THROWS_ANYTHING(f,l,e,0)
+#   define TS_ASSERT_THROWS_ANYTHING(e) _TS_ASSERT_THROWS_ANYTHING(__FILE__, __LINE__, e)
+
+#   define _TSM_ASSERT_THROWS_ANYTHING(f,l,m,e) ___TS_ASSERT_THROWS_ANYTHING(f,l,e,TS_AS_STRING(m))
+#   define TSM_ASSERT_THROWS_ANYTHING(m,e) _TSM_ASSERT_THROWS_ANYTHING(__FILE__,__LINE__,m,e)
+
+    // TS_ASSERT_THROWS_NOTHING
+#   define ___TS_ASSERT_THROWS_NOTHING(f,l,e,m) { \
+            _TS_TRY { e; } \
+            _TS_CATCH_ABORT( { throw; } ) \
+            _TS_LAST_CATCH( { CxxTest::doFailAssertThrowsNot( (f), (l), #e, (m) ); } ) }
+
+#   define _TS_ASSERT_THROWS_NOTHING(f,l,e) ___TS_ASSERT_THROWS_NOTHING(f,l,e,0)
+#   define TS_ASSERT_THROWS_NOTHING(e) _TS_ASSERT_THROWS_NOTHING(__FILE__,__LINE__,e)
+
+#   define _TSM_ASSERT_THROWS_NOTHING(f,l,m,e) ___TS_ASSERT_THROWS_NOTHING(f,l,e,TS_AS_STRING(m))
+#   define TSM_ASSERT_THROWS_NOTHING(m,e) _TSM_ASSERT_THROWS_NOTHING(__FILE__,__LINE__,m,e)
+
+
+    //
+    // This takes care of "signed <-> unsigned" warnings
+    //
+#   define CXXTEST_COMPARISONS(CXXTEST_X, CXXTEST_Y, CXXTEST_T) \
+    inline bool equals( CXXTEST_X x, CXXTEST_Y y ) { return (((CXXTEST_T)x) == ((CXXTEST_T)y)); } \
+    inline bool equals( CXXTEST_Y y, CXXTEST_X x ) { return (((CXXTEST_T)y) == ((CXXTEST_T)x)); } \
+    inline bool differs( CXXTEST_X x, CXXTEST_Y y ) { return (((CXXTEST_T)x) != ((CXXTEST_T)y)); } \
+    inline bool differs( CXXTEST_Y y, CXXTEST_X x ) { return (((CXXTEST_T)y) != ((CXXTEST_T)x)); } \
+    inline bool lessThan( CXXTEST_X x, CXXTEST_Y y ) { return (((CXXTEST_T)x) < ((CXXTEST_T)y)); } \
+    inline bool lessThan( CXXTEST_Y y, CXXTEST_X x ) { return (((CXXTEST_T)y) < ((CXXTEST_T)x)); } \
+    inline bool lessThanEquals( CXXTEST_X x, CXXTEST_Y y ) { return (((CXXTEST_T)x) <= ((CXXTEST_T)y)); } \
+    inline bool lessThanEquals( CXXTEST_Y y, CXXTEST_X x ) { return (((CXXTEST_T)y) <= ((CXXTEST_T)x)); }
+
+#   define CXXTEST_INTEGRAL(CXXTEST_T) \
+    CXXTEST_COMPARISONS( signed CXXTEST_T, unsigned CXXTEST_T, unsigned CXXTEST_T )
+
+    CXXTEST_INTEGRAL( char )
+    CXXTEST_INTEGRAL( short )
+    CXXTEST_INTEGRAL( int )
+    CXXTEST_INTEGRAL( long )
+#   ifdef _CXXTEST_LONGLONG
+    CXXTEST_INTEGRAL( _CXXTEST_LONGLONG )
+#   endif // _CXXTEST_LONGLONG
+
+#   define CXXTEST_SMALL_BIG(CXXTEST_SMALL, CXXTEST_BIG) \
+    CXXTEST_COMPARISONS( signed CXXTEST_SMALL, unsigned CXXTEST_BIG, unsigned CXXTEST_BIG ) \
+    CXXTEST_COMPARISONS( signed CXXTEST_BIG, unsigned CXXTEST_SMALL, unsigned CXXTEST_BIG )
+
+    CXXTEST_SMALL_BIG( char, short )
+    CXXTEST_SMALL_BIG( char, int )
+    CXXTEST_SMALL_BIG( short, int )
+    CXXTEST_SMALL_BIG( char, long )
+    CXXTEST_SMALL_BIG( short, long )
+    CXXTEST_SMALL_BIG( int, long )
+
+#   ifdef _CXXTEST_LONGLONG
+    CXXTEST_SMALL_BIG( char, _CXXTEST_LONGLONG )
+    CXXTEST_SMALL_BIG( short, _CXXTEST_LONGLONG )
+    CXXTEST_SMALL_BIG( int, _CXXTEST_LONGLONG )
+    CXXTEST_SMALL_BIG( long, _CXXTEST_LONGLONG )
+#   endif // _CXXTEST_LONGLONG
+}
+
+#endif // __cxxtest__TestSuite_h__
diff --git a/libpolys/tests/cxxtest/TestTracker.cpp b/libpolys/tests/cxxtest/TestTracker.cpp
new file mode 100644
index 0000000..1b68e9b
--- /dev/null
+++ b/libpolys/tests/cxxtest/TestTracker.cpp
@@ -0,0 +1,248 @@
+#ifndef __cxxtest__TestTracker_cpp__
+#define __cxxtest__TestTracker_cpp__
+
+#include <cxxtest/TestTracker.h>
+
+namespace CxxTest
+{
+    bool TestTracker::_created = false;
+
+    TestTracker::TestTracker()
+    {
+        if ( !_created ) {
+            initialize();
+            _created = true;
+        }
+    }
+
+    TestTracker::~TestTracker()
+    {
+    }
+
+    TestTracker & TestTracker::tracker()
+    {
+        static TestTracker theTracker;
+        return theTracker;
+    }
+
+    void TestTracker::initialize()
+    {
+        _warnings = 0;
+        _failedTests = 0;
+        _testFailedAsserts = 0;
+        _suiteFailedTests = 0;
+        _failedSuites = 0;
+        setListener( 0 );
+        _world = 0;
+        _suite = 0;
+        _test = 0;
+    }
+
+    const TestDescription *TestTracker::fixTest( const TestDescription *d ) const
+    {
+        return d ? d : &dummyTest();
+    }
+
+    const SuiteDescription *TestTracker::fixSuite( const SuiteDescription *d ) const
+    {
+        return d ? d : &dummySuite();
+    }
+
+    const WorldDescription *TestTracker::fixWorld( const WorldDescription *d ) const
+    {
+        return d ? d : &dummyWorld();
+    }
+
+    const TestDescription &TestTracker::dummyTest() const
+    {
+        return dummySuite().testDescription(0);
+    }
+
+    const SuiteDescription &TestTracker::dummySuite() const
+    {
+        return dummyWorld().suiteDescription(0);
+    }
+
+    const WorldDescription &TestTracker::dummyWorld() const
+    {
+        return _dummyWorld;
+    }
+
+    void TestTracker::setListener( TestListener *l )
+    {
+        _l = l ? l : &_dummyListener;
+    }
+
+    void TestTracker::enterWorld( const WorldDescription &wd )
+    {
+        setWorld( &wd );
+        _warnings = _failedTests = _testFailedAsserts = _suiteFailedTests = _failedSuites = 0;
+        _l->enterWorld( wd );
+    }
+
+    void TestTracker::enterSuite( const SuiteDescription &sd )
+    {
+        setSuite( &sd );
+        _testFailedAsserts = _suiteFailedTests = 0;
+        _l->enterSuite(sd);
+    }
+
+    void TestTracker::enterTest( const TestDescription &td )
+    {
+        setTest( &td );
+        _testFailedAsserts = false;
+        _l->enterTest(td);
+    }
+
+    void TestTracker::leaveTest( const TestDescription &td )
+    {
+        _l->leaveTest( td );
+        setTest( 0 );
+    }
+
+    void TestTracker::leaveSuite( const SuiteDescription &sd )
+    {
+        _l->leaveSuite( sd );
+        setSuite( 0 );
+    }
+
+    void TestTracker::leaveWorld( const WorldDescription &wd )
+    {
+        _l->leaveWorld( wd );
+        setWorld( 0 );
+    }
+
+    void TestTracker::trace( const char *file, unsigned line, const char *expression )
+    {
+        _l->trace( file, line, expression );
+    }
+
+    void TestTracker::warning( const char *file, unsigned line, const char *expression )
+    {
+        countWarning();
+        _l->warning( file, line, expression );
+    }
+
+    void TestTracker::failedTest( const char *file, unsigned line, const char *expression )
+    {
+        countFailure();
+        _l->failedTest( file, line, expression );
+    }
+
+    void TestTracker::failedAssert( const char *file, unsigned line, const char *expression )
+    {
+        countFailure();
+        _l->failedAssert( file, line, expression );
+    }
+
+    void TestTracker::failedAssertEquals( const char *file, unsigned line,
+                                          const char *xStr, const char *yStr,
+                                          const char *x, const char *y )
+    {
+        countFailure();
+        _l->failedAssertEquals( file, line, xStr, yStr, x, y );
+    }
+
+    void TestTracker::failedAssertSameData( const char *file, unsigned line,
+                                            const char *xStr, const char *yStr,
+                                            const char *sizeStr, const void *x,
+                                            const void *y, unsigned size )
+    {
+        countFailure();
+        _l->failedAssertSameData( file, line, xStr, yStr, sizeStr, x, y, size );
+    }
+
+    void TestTracker::failedAssertDelta( const char *file, unsigned line,
+                                         const char *xStr, const char *yStr, const char *dStr,
+                                         const char *x, const char *y, const char *d )
+    {
+        countFailure();
+        _l->failedAssertDelta( file, line, xStr, yStr, dStr, x, y, d );
+    }
+
+    void TestTracker::failedAssertDiffers( const char *file, unsigned line,
+                                           const char *xStr, const char *yStr,
+                                           const char *value )
+    {
+        countFailure();
+        _l->failedAssertDiffers( file, line, xStr, yStr, value );
+    }
+
+    void TestTracker::failedAssertLessThan( const char *file, unsigned line,
+                                            const char *xStr, const char *yStr,
+                                            const char *x, const char *y )
+    {
+        countFailure();
+        _l->failedAssertLessThan( file, line, xStr, yStr, x, y );
+    }
+
+    void TestTracker::failedAssertLessThanEquals( const char *file, unsigned line,
+                                                  const char *xStr, const char *yStr,
+                                                  const char *x, const char *y )
+    {
+        countFailure();
+        _l->failedAssertLessThanEquals( file, line, xStr, yStr, x, y );
+    }
+
+    void TestTracker::failedAssertPredicate( const char *file, unsigned line,
+                                             const char *predicate, const char *xStr, const char *x )
+    {
+        countFailure();
+        _l->failedAssertPredicate( file, line, predicate, xStr, x );
+    }
+
+    void TestTracker::failedAssertRelation( const char *file, unsigned line,
+                                            const char *relation, const char *xStr, const char *yStr,
+                                            const char *x, const char *y )
+    {
+        countFailure();
+        _l->failedAssertRelation( file, line, relation, xStr, yStr, x, y );
+    }
+
+    void TestTracker::failedAssertThrows( const char *file, unsigned line,
+                                          const char *expression, const char *type,
+                                          bool otherThrown )
+    {
+        countFailure();
+        _l->failedAssertThrows( file, line, expression, type, otherThrown );
+    }
+
+    void TestTracker::failedAssertThrowsNot( const char *file, unsigned line, const char *expression )
+    {
+        countFailure();
+        _l->failedAssertThrowsNot( file, line, expression );
+    }
+
+    void TestTracker::setWorld( const WorldDescription *w )
+    {
+        _world = fixWorld( w );
+        setSuite( 0 );
+    }
+
+    void TestTracker::setSuite( const SuiteDescription *s )
+    {
+        _suite = fixSuite( s );
+        setTest( 0 );
+    }
+
+    void TestTracker::setTest( const TestDescription *t )
+    {
+        _test = fixTest( t );
+    }
+
+    void TestTracker::countWarning()
+    {
+        ++ _warnings;
+    }
+
+    void TestTracker::countFailure()
+    {
+        if ( ++ _testFailedAsserts == 1 ) {
+            ++ _failedTests;
+            if ( ++ _suiteFailedTests == 1 )
+                ++ _failedSuites;
+        }
+    }
+};
+
+#endif // __cxxtest__TestTracker_cpp__
diff --git a/libpolys/tests/cxxtest/TestTracker.h b/libpolys/tests/cxxtest/TestTracker.h
new file mode 100644
index 0000000..715e686
--- /dev/null
+++ b/libpolys/tests/cxxtest/TestTracker.h
@@ -0,0 +1,114 @@
+#ifndef __cxxtest__TestTracker_h__
+#define __cxxtest__TestTracker_h__
+
+//
+// The TestTracker tracks running tests
+// The actual work is done in CountingListenerProxy,
+// but this way avoids cyclic references TestListener<->CountingListenerProxy
+//
+
+#include <cxxtest/TestListener.h>
+#include <cxxtest/DummyDescriptions.h>
+
+namespace CxxTest
+{
+    class TestListener;
+
+    class TestTracker : public TestListener
+    {
+    public:
+        virtual ~TestTracker();
+
+        static TestTracker &tracker();
+
+        const TestDescription *fixTest( const TestDescription *d ) const;
+        const SuiteDescription *fixSuite( const SuiteDescription *d ) const;
+        const WorldDescription *fixWorld( const WorldDescription *d ) const;
+
+        const TestDescription &test() const { return *_test; }
+        const SuiteDescription &suite() const { return *_suite; }
+        const WorldDescription &world() const { return *_world; }
+
+        bool testFailed() const { return (testFailedAsserts() > 0); }
+        bool suiteFailed() const { return (suiteFailedTests() > 0); }
+        bool worldFailed() const { return (failedSuites() > 0); }
+
+        unsigned warnings() const { return _warnings; }
+        unsigned failedTests() const { return _failedTests; }
+        unsigned testFailedAsserts() const { return _testFailedAsserts; }
+        unsigned suiteFailedTests() const { return _suiteFailedTests; }
+        unsigned failedSuites() const { return _failedSuites; }
+
+        void enterWorld( const WorldDescription &wd );
+        void enterSuite( const SuiteDescription &sd );
+        void enterTest( const TestDescription &td );
+        void leaveTest( const TestDescription &td );
+        void leaveSuite( const SuiteDescription &sd );
+        void leaveWorld( const WorldDescription &wd );
+        void trace( const char *file, unsigned line, const char *expression );
+        void warning( const char *file, unsigned line, const char *expression );
+        void failedTest( const char *file, unsigned line, const char *expression );
+        void failedAssert( const char *file, unsigned line, const char *expression );
+        void failedAssertEquals( const char *file, unsigned line,
+                                 const char *xStr, const char *yStr,
+                                 const char *x, const char *y );
+        void failedAssertSameData( const char *file, unsigned line,
+                                   const char *xStr, const char *yStr,
+                                   const char *sizeStr, const void *x,
+                                   const void *y, unsigned size );
+        void failedAssertDelta( const char *file, unsigned line,
+                                const char *xStr, const char *yStr, const char *dStr,
+                                const char *x, const char *y, const char *d );
+        void failedAssertDiffers( const char *file, unsigned line,
+                                  const char *xStr, const char *yStr,
+                                  const char *value );
+        void failedAssertLessThan( const char *file, unsigned line,
+                                   const char *xStr, const char *yStr,
+                                   const char *x, const char *y );
+        void failedAssertLessThanEquals( const char *file, unsigned line,
+                                         const char *xStr, const char *yStr,
+                                         const char *x, const char *y );
+        void failedAssertPredicate( const char *file, unsigned line,
+                                    const char *predicate, const char *xStr, const char *x );
+        void failedAssertRelation( const char *file, unsigned line,
+                                   const char *relation, const char *xStr, const char *yStr,
+                                   const char *x, const char *y );
+        void failedAssertThrows( const char *file, unsigned line,
+                                 const char *expression, const char *type,
+                                 bool otherThrown );
+        void failedAssertThrowsNot( const char *file, unsigned line, const char *expression );
+
+    private:
+        TestTracker( const TestTracker & );
+        TestTracker &operator=( const TestTracker & );
+
+        static bool _created;
+        TestListener _dummyListener;
+        DummyWorldDescription _dummyWorld;
+        unsigned _warnings, _failedTests, _testFailedAsserts, _suiteFailedTests, _failedSuites;
+        TestListener *_l;
+        const WorldDescription *_world;
+        const SuiteDescription *_suite;
+        const TestDescription *_test;
+
+        const TestDescription &dummyTest() const;
+        const SuiteDescription &dummySuite() const;
+        const WorldDescription &dummyWorld() const;
+
+        void setWorld( const WorldDescription *w );
+        void setSuite( const SuiteDescription *s );
+        void setTest( const TestDescription *t );
+        void countWarning();
+        void countFailure();
+
+        friend class TestRunner;
+
+        TestTracker();
+        void initialize();
+        void setListener( TestListener *l );
+    };
+
+    inline TestTracker &tracker() { return TestTracker::tracker(); }
+};
+
+#endif // __cxxtest__TestTracker_h__
diff --git a/libpolys/tests/cxxtest/ValueTraits.cpp b/libpolys/tests/cxxtest/ValueTraits.cpp
new file mode 100644
index 0000000..32f64fb
--- /dev/null
+++ b/libpolys/tests/cxxtest/ValueTraits.cpp
@@ -0,0 +1,140 @@
+#ifndef __cxxtest__ValueTraits_cpp__
+#define __cxxtest__ValueTraits_cpp__
+
+#include <cxxtest/ValueTraits.h>
+
+namespace CxxTest
+{
+    //
+    // Non-inline functions from ValueTraits.h
+    //
+
+    char digitToChar( unsigned digit )
+    {
+        if ( digit < 10 )
+            return (char)('0' + digit);
+        if ( digit <= 10 + 'Z' - 'A' )
+            return (char)('A' + digit - 10);
+        return '?';
+    }
+
+    const char *byteToHex( unsigned char byte )
+    {
+        static char asHex[3];
+        asHex[0] = digitToChar( byte >> 4 );
+        asHex[1] = digitToChar( byte & 0x0F );
+        asHex[2] = '\0';
+        return asHex;
+    }
+
+    char *copyString( char *dst, const char *src )
+    {
+        while ( (*dst = *src) != '\0' ) {
+            ++ dst;
+            ++ src;
+        }
+        return dst;
+    }
+
+    bool stringsEqual( const char *s1, const char *s2 )
+    {
+        char c;
+        while ( (c = *s1++) == *s2++ )
+            if ( c == '\0' )
+                return true;
+        return false;
+    }
+
+    char *charToString( unsigned long c, char *s )
+    {
+        switch( c ) {
+        case '\\': return copyString( s, "\\\\" );
+        case '\"': return copyString( s, "\\\"" );
+        case '\'': return copyString( s, "\\\'" );
+        case '\0': return copyString( s, "\\0" );
+        case '\a': return copyString( s, "\\a" );
+        case '\b': return copyString( s, "\\b" );
+        case '\n': return copyString( s, "\\n" );
+        case '\r': return copyString( s, "\\r" );
+        case '\t': return copyString( s, "\\t" );
+        }
+        if ( c >= 32 && c <= 127 ) {
+            s[0] = (char)c;
+            s[1] = '\0';
+            return s + 1;
+        }
+        else {
+            s[0] = '\\';
+            s[1] = 'x';
+            if ( c < 0x10 ) {
+                s[2] = '0';
+                ++ s;
+            }
+            return numberToString( c, s + 2, 16UL );
+        }
+    }
+
+    char *charToString( char c, char *s )
+    {
+        return charToString( (unsigned long)(unsigned char)c, s );
+    }
+
+    char *bytesToString( const unsigned char *bytes, unsigned numBytes, unsigned maxBytes, char *s )
+    {
+        bool truncate = (numBytes > maxBytes);
+        if ( truncate )
+            numBytes = maxBytes;
+
+        s = copyString( s, "{ " );
+        for ( unsigned i = 0; i < numBytes; ++ i, ++ bytes )
+            s = copyString( copyString( s, byteToHex( *bytes ) ), " " );
+        if ( truncate )
+            s = copyString( s, "..." );
+        return copyString( s, " }" );
+    }
+
+#ifndef CXXTEST_USER_VALUE_TRAITS
+    unsigned ValueTraits<const double>::requiredDigitsOnLeft( double t )
+    {
+        unsigned digits = 1;
+        for ( t = (t < 0.0) ? -t : t; t > 1.0; t /= BASE )
+            ++ digits;
+        return digits;
+    }
+
+    char *ValueTraits<const double>::doNegative( double &t )
+    {
+        if ( t >= 0 )
+            return _asString;
+        _asString[0] = '-';
+        t = -t;
+        return _asString + 1;
+    }
+
+    void ValueTraits<const double>::hugeNumber( double t )
+    {
+        char *s = doNegative( t );
+        s = doubleToString( t, s, 0, 1 );
+        s = copyString( s, "." );
+        s = doubleToString( t, s, 1, DIGITS_ON_RIGHT );
+        s = copyString( s, "E" );
+        s = numberToString( requiredDigitsOnLeft( t ) - 1, s );
+    }
+
+    void ValueTraits<const double>::normalNumber( double t )
+    {
+        char *s = doNegative( t );
+        s = doubleToString( t, s );
+        s = copyString( s, "." );
+        for ( unsigned i = 0; i < DIGITS_ON_RIGHT; ++ i )
+            s = numberToString( (unsigned)(t *= BASE) % BASE, s );
+    }
+
+    char *ValueTraits<const double>::doubleToString( double t, char *s, unsigned skip, unsigned max )
+    {
+        return numberToString<double>( t, s, BASE, skip, max );
+    }
+#endif // !CXXTEST_USER_VALUE_TRAITS
+};
+
+#endif // __cxxtest__ValueTraits_cpp__
diff --git a/libpolys/tests/cxxtest/ValueTraits.h b/libpolys/tests/cxxtest/ValueTraits.h
new file mode 100644
index 0000000..fb3b974
--- /dev/null
+++ b/libpolys/tests/cxxtest/ValueTraits.h
@@ -0,0 +1,377 @@
+#ifndef __cxxtest__ValueTraits_h__
+#define __cxxtest__ValueTraits_h__
+
+//
+// ValueTraits are used by CxxTest to convert arbitrary
+// values used in TS_ASSERT_EQUALS() to a string representation.
+//
+// This header file contains value traits for builtin integral types.
+// To declare value traits for new types you should instantiate the class
+// ValueTraits<YourClass>.
+//
+
+#include <cxxtest/Flags.h>
+
+#ifdef _CXXTEST_OLD_TEMPLATE_SYNTAX
+#   define CXXTEST_TEMPLATE_INSTANTIATION
+#else // !_CXXTEST_OLD_TEMPLATE_SYNTAX
+#   define CXXTEST_TEMPLATE_INSTANTIATION template<>
+#endif // _CXXTEST_OLD_TEMPLATE_SYNTAX
+
+namespace CxxTest
+{
+    //
+    // This is how we use the value traits
+    //
+#   define TS_AS_STRING(x) CxxTest::traits(x).asString()
+
+    //
+    // Char representation of a digit
+    //
+    char digitToChar( unsigned digit );
+
+    //
+    // Convert byte value to hex digits
+    // Returns pointer to internal buffer
+    //
+    const char *byteToHex( unsigned char byte );
+
+    //
+    // Convert byte values to string
+    // Returns one past the copied data
+    //
+    char *bytesToString( const unsigned char *bytes, unsigned numBytes, unsigned maxBytes, char *s );
+
+    //
+    // Copy a string.
+    // Returns one past the end of the destination string
+    // Remember -- we can't use the standard library!
+    //
+    char *copyString( char *dst, const char *src );
+
+    //
+    // Compare two strings.
+    // Remember -- we can't use the standard library!
+    //
+    bool stringsEqual( const char *s1, const char *s2 );
+
+    //
+    // Represent a character value as a string
+    // Returns one past the end of the string
+    // This will be the actual char if printable or '\xXXXX' otherwise
+    //
+    char *charToString( unsigned long c, char *s );
+
+    //
+    // Prevent problems with negative (signed char)s
+    //
+    char *charToString( char c, char *s );
+
+    //
+    // The default ValueTraits class dumps up to 8 bytes as hex values
+    //
+    template <class T>
+    class ValueTraits
+    {
+        enum { MAX_BYTES = 8 };
+        char _asString[sizeof("{ ") + sizeof("XX ") * MAX_BYTES + sizeof("... }")];
+
+    public:
+        ValueTraits( const T &t ) { bytesToString( (const unsigned char *)&t, sizeof(T), MAX_BYTES, _asString ); }
+        const char *asString( void ) const { return _asString; }
+    };
+
+    //
+    // traits( T t )
+    // Creates an object of type ValueTraits<T>
+    //
+    template <class T>
+    inline ValueTraits<T> traits( T t )
+    {
+        return ValueTraits<T>( t );
+    }
+
+    //
+    // You can duplicate the implementation of an existing ValueTraits
+    //
+#   define CXXTEST_COPY_TRAITS(CXXTEST_NEW_CLASS, CXXTEST_OLD_CLASS) \
+    CXXTEST_TEMPLATE_INSTANTIATION \
+    class ValueTraits< CXXTEST_NEW_CLASS > \
+    { \
+        ValueTraits< CXXTEST_OLD_CLASS > _old; \
+    public: \
+        ValueTraits( CXXTEST_NEW_CLASS n ) : _old( (CXXTEST_OLD_CLASS)n ) {} \
+        const char *asString( void ) const { return _old.asString(); } \
+    }
+
+    //
+    // Certain compilers need separate declarations for T and const T
+    //
+#   ifdef _CXXTEST_NO_COPY_CONST
+#       define CXXTEST_COPY_CONST_TRAITS(CXXTEST_CLASS)
+#   else // !_CXXTEST_NO_COPY_CONST
+#       define CXXTEST_COPY_CONST_TRAITS(CXXTEST_CLASS) CXXTEST_COPY_TRAITS(CXXTEST_CLASS, const CXXTEST_CLASS)
+#   endif // _CXXTEST_NO_COPY_CONST
+
+    //
+    // Avoid compiler warnings about unsigned types always >= 0
+    //
+    template<class N> inline bool negative( N n ) { return n < 0; }
+    template<class N> inline N abs( N n ) { return negative(n) ? -n : n; }
+
+#   define CXXTEST_NON_NEGATIVE(Type) \
+    CXXTEST_TEMPLATE_INSTANTIATION \
+    inline bool negative<Type>( Type ) { return false; } \
+    CXXTEST_TEMPLATE_INSTANTIATION \
+    inline Type abs<Type>( Type value ) { return value; }
+
+    CXXTEST_NON_NEGATIVE( bool )
+    CXXTEST_NON_NEGATIVE( unsigned char )
+    CXXTEST_NON_NEGATIVE( unsigned short int )
+    CXXTEST_NON_NEGATIVE( unsigned int )
+    CXXTEST_NON_NEGATIVE( unsigned long int )
+#   ifdef _CXXTEST_LONGLONG
+    CXXTEST_NON_NEGATIVE( unsigned _CXXTEST_LONGLONG )
+#   endif // _CXXTEST_LONGLONG
+
+    //
+    // Represent (integral) number as a string
+    // Returns one past the end of the string
+    // Remember -- we can't use the standard library!
+    //
+    template<class N>
+    char *numberToString( N n, char *s,
+                          N base = 10,
+                          unsigned skipDigits = 0,
+                          unsigned maxDigits = (unsigned)-1 )
+    {
+        if ( negative(n) ) {
+            *s++ = '-';
+            n = abs(n);
+        }
+
+        N digit = 1;
+        while ( digit <= (n / base) )
+            digit *= base;
+        N digitValue;
+        for ( ; digit >= 1 && skipDigits; n -= digit * digitValue, digit /= base, -- skipDigits )
+            digitValue = (unsigned)(n / digit);
+        for ( ; digit >= 1 && maxDigits; n -= digit * digitValue, digit /= base, -- maxDigits )
+            *s++ = digitToChar( (unsigned)(digitValue = (unsigned)(n / digit)) );
+
+        *s = '\0';
+        return s;
+    }
+
+    //
+    // All the specific ValueTraits follow.
+    // You can #define CXXTEST_USER_VALUE_TRAITS if you don't want them
+    //
+
+#ifndef CXXTEST_USER_VALUE_TRAITS
+    //
+    // ValueTraits: const char * const &
+    // This is used for printing strings, as in TS_FAIL( "Message" )
+    //
+    CXXTEST_TEMPLATE_INSTANTIATION
+    class ValueTraits<const char * const &>
+    {
+        ValueTraits &operator=( const ValueTraits & );
+        const char *_asString;
+
+    public:
+        ValueTraits( const char * const &value ) : _asString( value ) {}
+        ValueTraits( const ValueTraits &other ) : _asString( other._asString ) {}
+        const char *asString( void ) const { return _asString; }
+    };
+
+    CXXTEST_COPY_TRAITS( const char *, const char * const & );
+    CXXTEST_COPY_TRAITS( char *, const char * const & );
+
+    //
+    // ValueTraits: bool
+    //
+    CXXTEST_TEMPLATE_INSTANTIATION
+    class ValueTraits<const bool>
+    {
+        bool _value;
+
+    public:
+        ValueTraits( const bool value ) : _value( value ) {}
+        const char *asString( void ) const { return _value ? "true" : "false"; }
+    };
+
+    CXXTEST_COPY_CONST_TRAITS( bool );
+
+#   ifdef _CXXTEST_LONGLONG
+    //
+    // ValueTraits: signed long long
+    //
+    CXXTEST_TEMPLATE_INSTANTIATION
+    class ValueTraits<const signed _CXXTEST_LONGLONG>
+    {
+        typedef _CXXTEST_LONGLONG T;
+        char _asString[2 + 3 * sizeof(T)];
+    public:
+        ValueTraits( T t ) { numberToString<T>( t, _asString ); }
+        const char *asString( void ) const { return _asString; }
+    };
+
+    CXXTEST_COPY_CONST_TRAITS( signed _CXXTEST_LONGLONG );
+
+    //
+    // ValueTraits: unsigned long long
+    //
+    CXXTEST_TEMPLATE_INSTANTIATION
+    class ValueTraits<const unsigned _CXXTEST_LONGLONG>
+    {
+        typedef unsigned _CXXTEST_LONGLONG T;
+        char _asString[1 + 3 * sizeof(T)];
+    public:
+        ValueTraits( T t ) { numberToString<T>( t, _asString ); }
+        const char *asString( void ) const { return _asString; }
+    };
+
+    CXXTEST_COPY_CONST_TRAITS( unsigned _CXXTEST_LONGLONG );
+#   endif // _CXXTEST_LONGLONG
+
+    //
+    // ValueTraits: signed long
+    //
+    CXXTEST_TEMPLATE_INSTANTIATION
+    class ValueTraits<const signed long int>
+    {
+        typedef signed long int T;
+        char _asString[2 + 3 * sizeof(T)];
+    public:
+        ValueTraits( T t ) { numberToString<T>( t, _asString ); }
+        const char *asString( void ) const { return _asString; }
+    };
+
+    CXXTEST_COPY_CONST_TRAITS( signed long int );
+
+    //
+    // ValueTraits: unsigned long
+    //
+    CXXTEST_TEMPLATE_INSTANTIATION
+    class ValueTraits<const unsigned long int>
+    {
+        typedef unsigned long int T;
+        char _asString[1 + 3 * sizeof(T)];
+    public:
+        ValueTraits( T t ) { numberToString<T>( t, _asString ); }
+        const char *asString( void ) const { return _asString; }
+    };
+
+    CXXTEST_COPY_CONST_TRAITS( unsigned long int );
+
+    //
+    // All decimals are the same as the long version
+    //
+
+    CXXTEST_COPY_TRAITS( const signed int, const signed long int );
+    CXXTEST_COPY_TRAITS( const unsigned int, const unsigned long int );
+    CXXTEST_COPY_TRAITS( const signed short int, const signed long int );
+    CXXTEST_COPY_TRAITS( const unsigned short int, const unsigned long int );
+    CXXTEST_COPY_TRAITS( const unsigned char, const unsigned long int );
+
+    CXXTEST_COPY_CONST_TRAITS( signed int );
+    CXXTEST_COPY_CONST_TRAITS( unsigned int );
+    CXXTEST_COPY_CONST_TRAITS( signed short int );
+    CXXTEST_COPY_CONST_TRAITS( unsigned short int );
+    CXXTEST_COPY_CONST_TRAITS( unsigned char );
+
+    //
+    // ValueTraits: char
+    // Returns 'x' for printable chars, '\x??' for others
+    //
+    CXXTEST_TEMPLATE_INSTANTIATION
+    class ValueTraits<const char>
+    {
+        char _asString[sizeof("'\\xXX'")];
+    public:
+        ValueTraits( char c ) { copyString( charToString( c, copyString( _asString, "'" ) ), "'" ); }
+        const char *asString( void ) const { return _asString; }
+    };
+
+    CXXTEST_COPY_CONST_TRAITS( char );
+
+    //
+    // ValueTraits: signed char
+    // Same as char, some compilers need it
+    //
+    CXXTEST_COPY_TRAITS( const signed char, const char );
+    CXXTEST_COPY_CONST_TRAITS( signed char );
+
+    //
+    // ValueTraits: double
+    //
+    CXXTEST_TEMPLATE_INSTANTIATION
+    class ValueTraits<const double>
+    {
+    public:
+        ValueTraits( double t )
+        {
+            ( requiredDigitsOnLeft( t ) > MAX_DIGITS_ON_LEFT ) ?
+                hugeNumber( t ) :
+                normalNumber( t );
+        }
+
+        const char *asString( void ) const { return _asString; }
+
+    private:
+        enum { MAX_DIGITS_ON_LEFT = 24, DIGITS_ON_RIGHT = 4, BASE = 10 };
+        char _asString[1 + MAX_DIGITS_ON_LEFT + 1 + DIGITS_ON_RIGHT + 1];
+
+        static unsigned requiredDigitsOnLeft( double t );
+        char *doNegative( double &t );
+        void hugeNumber( double t );
+        void normalNumber( double t );
+        char *doubleToString( double t, char *s, unsigned skip = 0, unsigned max = (unsigned)-1 );
+    };
+
+    CXXTEST_COPY_CONST_TRAITS( double );
+
+    //
+    // ValueTraits: float
+    //
+    CXXTEST_COPY_TRAITS( const float, const double );
+    CXXTEST_COPY_CONST_TRAITS( float );
+#endif // !CXXTEST_USER_VALUE_TRAITS
+};
+
+#ifdef _CXXTEST_HAVE_STD
+#   include <cxxtest/StdValueTraits.h>
+#endif // _CXXTEST_HAVE_STD
+
+//
+// CXXTEST_ENUM_TRAITS
+//
+#define CXXTEST_ENUM_TRAITS( TYPE, VALUES ) \
+    namespace CxxTest \
+    { \
+        CXXTEST_TEMPLATE_INSTANTIATION \
+        class ValueTraits<TYPE> \
+        { \
+            TYPE _value; \
+            char _fallback[sizeof("(" #TYPE ")") + 3 * sizeof(TYPE)]; \
+        public: \
+            ValueTraits( TYPE value ) { \
+                _value = value; \
+                numberToString<unsigned long int>( _value, copyString( _fallback, "(" #TYPE ")" ) ); \
+            } \
+            const char *asString( void ) const \
+            { \
+                switch ( _value ) \
+                { \
+                    VALUES \
+                    default: return _fallback; \
+                } \
+            } \
+        }; \
+    }
+
+#define CXXTEST_ENUM_MEMBER( MEMBER ) \
+    case MEMBER: return #MEMBER;
+
+#endif // __cxxtest__ValueTraits_h__
diff --git a/libpolys/tests/cxxtest/Win32Gui.h b/libpolys/tests/cxxtest/Win32Gui.h
new file mode 100644
index 0000000..73e149a
--- /dev/null
+++ b/libpolys/tests/cxxtest/Win32Gui.h
@@ -0,0 +1,531 @@
+#ifndef __cxxtest__Win32Gui_h__
+#define __cxxtest__Win32Gui_h__
+
+//
+// The Win32Gui displays a simple progress bar using the Win32 API.
+//
+// It accepts the following command line options:
+//   -minimized    Start minimized, pop up on error
+//   -keep         Don't close the window at the end
+//   -title TITLE  Set the window caption
+//
+// If both -minimized and -keep are specified, GUI will only keep the
+// window if it's in focus.
+//
+// N.B. If you're wondering why this class doesn't use any standard
+// library or STL (<string> would have been nice) it's because it only
+// uses "straight" Win32 API.
+//
+
+#include <cxxtest/Gui.h>
+
+#include <windows.h>
+#include <commctrl.h>
+
+namespace CxxTest
+{
+    class Win32Gui : public GuiListener
+    {
+    public:
+        void enterGui( int &argc, char **argv )
+	{
+	    parseCommandLine( argc, argv );
+	}
+
+        void enterWorld( const WorldDescription &wd )
+        {
+            getTotalTests( wd );
+            _testsDone = 0;
+            startGuiThread();
+        }
+
+	void guiEnterSuite( const char *suiteName )
+	{
+	    showSuiteName( suiteName );
+            reset( _suiteStart );
+	}
+
+        void guiEnterTest( const char *suiteName, const char *testName )
+        {
+            ++ _testsDone;
+            setTestCaption( suiteName, testName );
+            showTestName( testName );
+	    showTestsDone();
+            progressBarMessage( PBM_STEPIT );
+            reset( _testStart );
+        }
+
+        void yellowBar()
+        {
+	    setColor( 255, 255, 0 );
+            setIcon( IDI_WARNING );
+            getTotalTests();
+        }
+
+        void redBar()
+        {
+            if ( _startMinimized )
+                showMainWindow( SW_SHOWNORMAL );
+	    setColor( 255, 0, 0 );
+	    setIcon( IDI_ERROR );
+            getTotalTests();
+        }
+
+        void leaveGui()
+        {
+            if ( keep() )
+            {
+                showSummary();
+                WaitForSingleObject( _gui, INFINITE );
+            }
+            DestroyWindow( _mainWindow );
+        }
+
+    private:
+        const char *_title;
+        bool _startMinimized, _keep;
+        HANDLE _gui;
+        WNDCLASSEX _windowClass;
+        HWND _mainWindow, _progressBar, _statusBar;
+        HANDLE _canStartTests;
+        unsigned _numTotalTests, _testsDone;
+        char _strTotalTests[WorldDescription::MAX_STRLEN_TOTAL_TESTS];
+        enum {
+            STATUS_SUITE_NAME, STATUS_SUITE_TIME,
+            STATUS_TEST_NAME, STATUS_TEST_TIME,
+            STATUS_TESTS_DONE, STATUS_WORLD_TIME,
+            STATUS_TOTAL_PARTS
+        };
+        int _statusWidths[STATUS_TOTAL_PARTS];
+        unsigned _statusOffsets[STATUS_TOTAL_PARTS];
+        unsigned _statusTotal;
+        char _statusTestsDone[sizeof("1000000000 of  (100%)") + WorldDescription::MAX_STRLEN_TOTAL_TESTS];
+        DWORD _worldStart, _suiteStart, _testStart;
+        char _timeString[sizeof("00:00:00")];
+
+        void parseCommandLine( int argc, char **argv )
+        {
+            _startMinimized = _keep = false;
+	    _title = argv[0];
+
+            for ( int i = 1; i < argc; ++ i )
+            {
+                if ( !lstrcmpA( argv[i], "-minimized" ) )
+                    _startMinimized = true;
+                else if ( !lstrcmpA( argv[i], "-keep" ) )
+                    _keep = true;
+                else if ( !lstrcmpA( argv[i], "-title" ) && (i + 1 < argc) )
+                    _title = argv[++i];
+            }
+        }
+
+        void getTotalTests()
+        {
+            getTotalTests( tracker().world() );
+        }
+
+        void getTotalTests( const WorldDescription &wd )
+        {
+            _numTotalTests = wd.numTotalTests();
+            wd.strTotalTests( _strTotalTests );
+        }
+
+        void startGuiThread()
+        {
+            _canStartTests = CreateEvent( NULL, TRUE, FALSE, NULL );
+			DWORD threadId;
+            _gui = CreateThread( NULL, 0, &(Win32Gui::guiThread), (LPVOID)this, 0, &threadId );
+            WaitForSingleObject( _canStartTests, INFINITE );
+        }
+
+        static DWORD WINAPI guiThread( LPVOID parameter )
+        {
+            ((Win32Gui *)parameter)->gui();
+            return 0;
+        }
+
+        void gui()
+        {
+            registerWindowClass();
+            createMainWindow();
+            initCommonControls();
+            createProgressBar();
+            createStatusBar();
+            centerMainWindow();
+            showMainWindow();
+            startTimer();
+            startTests();
+
+            messageLoop();
+        }
+
+        void registerWindowClass()
+        {
+            _windowClass.cbSize = sizeof(_windowClass);
+            _windowClass.style = CS_HREDRAW | CS_VREDRAW;
+            _windowClass.lpfnWndProc = &(Win32Gui::windowProcedure);
+            _windowClass.cbClsExtra = 0;
+            _windowClass.cbWndExtra = sizeof(LONG);
+            _windowClass.hInstance = (HINSTANCE)NULL;
+            _windowClass.hIcon = (HICON)NULL;
+            _windowClass.hCursor = (HCURSOR)NULL;
+            _windowClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
+            _windowClass.lpszMenuName = NULL;
+            _windowClass.lpszClassName = TEXT("CxxTest Window Class");
+            _windowClass.hIconSm = (HICON)NULL;
+
+            RegisterClassEx( &_windowClass );
+        }
+
+        void createMainWindow()
+        {
+            _mainWindow = createWindow( _windowClass.lpszClassName, WS_OVERLAPPEDWINDOW );
+        }
+
+        void initCommonControls()
+        {
+            HMODULE dll = LoadLibraryA( "comctl32.dll" );
+            if ( !dll )
+		return;
+
+	    typedef void (WINAPI *FUNC)( void );
+	    FUNC func = (FUNC)GetProcAddress( dll, "InitCommonControls" );
+	    if ( !func )
+                return;
+
+	    func();
+        }
+
+        void createProgressBar()
+        {
+            _progressBar = createWindow( PROGRESS_CLASS, WS_CHILD | WS_VISIBLE | PBS_SMOOTH, _mainWindow );
+
+#ifdef PBM_SETRANGE32
+            progressBarMessage( PBM_SETRANGE32, 0, _numTotalTests );
+#else // No PBM_SETRANGE32, use PBM_SETRANGE
+	    progressBarMessage( PBM_SETRANGE, 0, MAKELPARAM( 0, (WORD)_numTotalTests ) );
+#endif // PBM_SETRANGE32
+            progressBarMessage( PBM_SETPOS, 0 );
+            progressBarMessage( PBM_SETSTEP, 1 );
+            greenBar();
+            UpdateWindow( _progressBar );
+        }
+
+        void createStatusBar()
+        {
+            _statusBar = createWindow( STATUSCLASSNAME, WS_CHILD | WS_VISIBLE, _mainWindow );
+            setRatios( 4, 1, 3, 1, 3, 1 );
+        }
+
+        void setRatios( unsigned suiteNameRatio, unsigned suiteTimeRatio,
+                        unsigned testNameRatio, unsigned testTimeRatio,
+                        unsigned testsDoneRatio, unsigned worldTimeRatio )
+        {
+            _statusTotal = 0;
+            _statusOffsets[STATUS_SUITE_NAME] = (_statusTotal += suiteNameRatio);
+            _statusOffsets[STATUS_SUITE_TIME] = (_statusTotal += suiteTimeRatio);
+            _statusOffsets[STATUS_TEST_NAME] = (_statusTotal += testNameRatio);
+            _statusOffsets[STATUS_TEST_TIME] = (_statusTotal += testTimeRatio);
+            _statusOffsets[STATUS_TESTS_DONE] = (_statusTotal += testsDoneRatio);
+            _statusOffsets[STATUS_WORLD_TIME] = (_statusTotal += worldTimeRatio);
+        }
+
+        HWND createWindow( LPCTSTR className, DWORD style, HWND parent = (HWND)NULL )
+        {
+            return CreateWindow( className, NULL, style, 0, 0, 0, 0, parent,
+                                 (HMENU)NULL, (HINSTANCE)NULL, (LPVOID)this );
+        }
+
+        void progressBarMessage( UINT message, WPARAM wParam = 0, LPARAM lParam = 0 )
+        {
+            SendMessage( _progressBar, message, wParam, lParam );
+        }
+
+        void centerMainWindow()
+        {
+            RECT screen;
+            getScreenArea( screen );
+
+            LONG screenWidth = screen.right - screen.left;
+            LONG screenHeight = screen.bottom - screen.top;
+
+            LONG xCenter = (screen.right + screen.left) / 2;
+            LONG yCenter = (screen.bottom + screen.top) / 2;
+
+            LONG windowWidth = (screenWidth * 4) / 5;
+            LONG windowHeight = screenHeight / 10;
+            LONG minimumHeight = 2 * (GetSystemMetrics( SM_CYCAPTION ) + GetSystemMetrics( SM_CYFRAME ));
+            if ( windowHeight < minimumHeight )
+                windowHeight = minimumHeight;
+
+            SetWindowPos( _mainWindow, HWND_TOP,
+                          xCenter - (windowWidth / 2), yCenter - (windowHeight / 2),
+                          windowWidth, windowHeight, 0 );
+        }
+
+        void getScreenArea( RECT &area )
+        {
+            if ( !getScreenAreaWithoutTaskbar( area ) )
+                getWholeScreenArea( area );
+        }
+
+        bool getScreenAreaWithoutTaskbar( RECT &area )
+        {
+            return (SystemParametersInfo( SPI_GETWORKAREA, sizeof(RECT), &area, 0 ) != 0);
+        }
+
+        void getWholeScreenArea( RECT &area )
+        {
+            area.left = area.top = 0;
+            area.right = GetSystemMetrics( SM_CXSCREEN );
+            area.bottom = GetSystemMetrics( SM_CYSCREEN );
+        }
+
+        void showMainWindow()
+        {
+            showMainWindow( _startMinimized ? SW_MINIMIZE : SW_SHOWNORMAL );
+            UpdateWindow( _mainWindow );
+        }
+
+        void showMainWindow( int mode )
+        {
+            ShowWindow( _mainWindow, mode );
+        }
+
+        enum { TIMER_ID = 1, TIMER_DELAY = 1000 };
+
+        void startTimer()
+        {
+            reset( _worldStart );
+            reset( _suiteStart );
+            reset( _testStart );
+            SetTimer( _mainWindow, TIMER_ID, TIMER_DELAY, 0 );
+        }
+
+        void reset( DWORD &tick )
+        {
+            tick = GetTickCount();
+        }
+
+        void startTests()
+        {
+            SetEvent( _canStartTests );
+        }
+
+        void messageLoop()
+        {
+            MSG message;
+            while ( BOOL haveMessage = GetMessage( &message, NULL, 0, 0 ) )
+                if ( haveMessage != -1 )
+                    DispatchMessage( &message );
+        }
+
+        static LRESULT CALLBACK windowProcedure( HWND window, UINT message, WPARAM wParam, LPARAM lParam )
+        {
+            if ( message == WM_CREATE )
+                setUp( window, (LPCREATESTRUCT)lParam );
+
+            Win32Gui *that = (Win32Gui *)GetWindowLong( window, GWL_USERDATA );
+            return that->handle( window, message, wParam, lParam );
+        }
+
+        static void setUp( HWND window, LPCREATESTRUCT create )
+        {
+            SetWindowLong( window, GWL_USERDATA, (LONG)create->lpCreateParams );
+        }
+
+        LRESULT handle( HWND window, UINT message, WPARAM wParam, LPARAM lParam )
+        {
+            switch ( message )
+            {
+            case WM_SIZE: resizeControls(); break;
+
+            case WM_TIMER: updateTime(); break;
+
+            case WM_CLOSE:
+            case WM_DESTROY:
+            case WM_QUIT:
+                ExitProcess( 0 );
+
+            default: return DefWindowProc( window, message, wParam, lParam );
+            }
+            return 0;
+        }
+
+        void resizeControls()
+        {
+            RECT r;
+            GetClientRect( _mainWindow, &r );
+            LONG width = r.right - r.left;
+            LONG height = r.bottom - r.top;
+
+            GetClientRect( _statusBar, &r );
+            LONG statusHeight = r.bottom - r.top;
+            LONG resizeGripWidth = statusHeight;
+            LONG progressHeight = height - statusHeight;
+
+            SetWindowPos( _progressBar, HWND_TOP, 0, 0, width, progressHeight, 0 );
+            SetWindowPos( _statusBar, HWND_TOP, 0, progressHeight, width, statusHeight, 0 );
+            setStatusParts( width - resizeGripWidth );
+        }
+
+        void setStatusParts( LONG width )
+        {
+            for ( unsigned i = 0; i < STATUS_TOTAL_PARTS; ++ i )
+                _statusWidths[i] = (width * _statusOffsets[i]) / _statusTotal;
+
+            statusBarMessage( SB_SETPARTS, STATUS_TOTAL_PARTS, _statusWidths );
+        }
+
+        void statusBarMessage( UINT message, WPARAM wParam = 0, const void *lParam = 0 )
+        {
+            SendMessage( _statusBar, message, wParam, (LPARAM)lParam );
+        }
+
+        void greenBar()
+        {
+            setColor( 0, 255, 0 );
+            setIcon( IDI_INFORMATION );
+        }
+
+#ifdef PBM_SETBARCOLOR
+        void setColor( BYTE red, BYTE green, BYTE blue )
+        {
+            progressBarMessage( PBM_SETBARCOLOR, 0, RGB( red, green, blue ) );
+        }
+#else // !PBM_SETBARCOLOR
+        void setColor( BYTE, BYTE, BYTE )
+        {
+        }
+#endif // PBM_SETBARCOLOR
+
+        void setIcon( LPCTSTR icon )
+        {
+            SendMessage( _mainWindow, WM_SETICON, ICON_BIG, (LPARAM)loadStandardIcon( icon ) );
+        }
+
+        HICON loadStandardIcon( LPCTSTR icon )
+        {
+            return LoadIcon( (HINSTANCE)NULL, icon );
+        }
+
+        void setTestCaption( const char *suiteName, const char *testName )
+        {
+            setCaption( suiteName, "::", testName, "()" );
+        }
+
+        void setCaption( const char *a = "", const char *b = "", const char *c = "", const char *d = "" )
+        {
+            unsigned length = lstrlenA( _title ) + sizeof( " - " ) +
+                lstrlenA( a ) + lstrlenA( b ) + lstrlenA( c ) + lstrlenA( d );
+            char *name = allocate( length );
+            lstrcpyA( name, _title );
+            lstrcatA( name, " - " );
+            lstrcatA( name, a );
+            lstrcatA( name, b );
+            lstrcatA( name, c );
+            lstrcatA( name, d );
+            SetWindowTextA( _mainWindow, name );
+            deallocate( name );
+        }
+
+        void showSuiteName( const char *suiteName )
+        {
+            setStatusPart( STATUS_SUITE_NAME, suiteName );
+	}
+
+	void showTestName( const char *testName )
+	{
+            setStatusPart( STATUS_TEST_NAME, testName );
+	}
+
+	void showTestsDone()
+	{
+            wsprintfA( _statusTestsDone, "%u of %s (%u%%)",
+                       _testsDone, _strTotalTests,
+                       (_testsDone * 100) / _numTotalTests );
+            setStatusPart( STATUS_TESTS_DONE, _statusTestsDone );
+        }
+
+        void updateTime()
+        {
+            setStatusTime( STATUS_WORLD_TIME, _worldStart );
+            setStatusTime( STATUS_SUITE_TIME, _suiteStart );
+            setStatusTime( STATUS_TEST_TIME, _testStart );
+        }
+
+        void setStatusTime( unsigned part, DWORD start )
+        {
+            unsigned total = (GetTickCount() - start) / 1000;
+            unsigned hours = total / 3600;
+            unsigned minutes = (total / 60) % 60;
+            unsigned seconds = total % 60;
+
+            if ( hours )
+                wsprintfA( _timeString, "%u:%02u:%02u", hours, minutes, seconds );
+            else
+                wsprintfA( _timeString, "%02u:%02u", minutes, seconds );
+
+            setStatusPart( part, _timeString );
+        }
+
+        bool keep()
+        {
+            if ( !_keep )
+                return false;
+            if ( !_startMinimized )
+                return true;
+            return (_mainWindow == GetForegroundWindow());
+        }
+
+        void showSummary()
+        {
+            stopTimer();
+            setSummaryStatusBar();
+            setSummaryCaption();
+        }
+
+        void setStatusPart( unsigned part, const char *text )
+        {
+            statusBarMessage( SB_SETTEXTA, part, text );
+        }
+
+        void stopTimer()
+        {
+            KillTimer( _mainWindow, TIMER_ID );
+            setStatusTime( STATUS_WORLD_TIME, _worldStart );
+        }
+
+        void setSummaryStatusBar()
+        {
+            setRatios( 0, 0, 0, 0, 1, 1 );
+            resizeControls();
+
+            const char *tests = (_numTotalTests == 1) ? "test" : "tests";
+            if ( tracker().failedTests() )
+                wsprintfA( _statusTestsDone, "Failed %u of %s %s",
+                          tracker().failedTests(), _strTotalTests, tests );
+            else
+                wsprintfA( _statusTestsDone, "%s %s passed", _strTotalTests, tests );
+
+            setStatusPart( STATUS_TESTS_DONE, _statusTestsDone );
+        }
+
+        void setSummaryCaption()
+        {
+            setCaption( _statusTestsDone );
+        }
+
+        char *allocate( unsigned length )
+        {
+            return (char *)HeapAlloc( GetProcessHeap(), 0, length );
+        }
+
+        void deallocate( char *data )
+        {
+            HeapFree( GetProcessHeap(), 0, data );
+        }
+    };
+};
+
+#endif // __cxxtest__Win32Gui_h__
diff --git a/libpolys/tests/cxxtest/X11Gui.h b/libpolys/tests/cxxtest/X11Gui.h
new file mode 100644
index 0000000..c14820a
--- /dev/null
+++ b/libpolys/tests/cxxtest/X11Gui.h
@@ -0,0 +1,327 @@
+#ifndef __cxxtest__X11Gui_h__
+#define __cxxtest__X11Gui_h__
+
+//
+// X11Gui displays a simple progress bar using X11
+//
+// It accepts the following command-line arguments:
+//  -title <title>              - Sets the application title
+//  -fn or -font <font>         - Sets the font
+//  -bg or -background <color>  - Sets the background color (default=Grey)
+//  -fg or -foreground <color>  - Sets the text color (default=Black)
+//  -green/-yellow/-red <color> - Sets the colors of the bar
+//
+
+#include <cxxtest/Gui.h>
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+namespace CxxTest
+{
+    class X11Gui : public GuiListener
+    {
+    public:
+        void enterGui( int &argc, char **argv )
+        {
+            parseCommandLine( argc, argv );
+        }
+
+        void enterWorld( const WorldDescription &wd )
+        {
+            openDisplay();
+            if ( _display ) {
+                createColors();
+                createWindow();
+                createGc();
+                createFont();
+                centerWindow();
+                initializeEvents();
+                initializeBar( wd );
+                processEvents();
+            }
+        }
+
+        void guiEnterTest( const char *suiteName, const char *testName )
+        {
+            if ( _display ) {
+                ++ _testsDone;
+                setWindowName( suiteName, testName );
+                redraw();
+            }
+        }
+
+        void yellowBar()
+        {
+            if ( _display ) {
+                _barColor = getColor( _yellowName );
+                getTotalTests();
+                processEvents();
+            }
+        }
+
+        void redBar()
+        {
+            if ( _display ) {
+                _barColor = getColor( _redName );
+                getTotalTests();
+                processEvents();
+            }
+        }
+
+        void leaveGui()
+        {
+            if ( _display ) {
+                freeFontInfo();
+                destroyGc();
+                destroyWindow();
+                closeDisplay();
+            }
+        }
+
+    private:
+        const char *_programName;
+        Display *_display;
+        Window _window;
+        unsigned _numTotalTests, _testsDone;
+        char _strTotalTests[WorldDescription::MAX_STRLEN_TOTAL_TESTS];
+        const char *_foregroundName, *_backgroundName;
+        const char *_greenName, *_yellowName, *_redName;
+        unsigned long _foreground, _background, _barColor;
+        int _width, _height;
+        GC _gc;
+        const char *_fontName;
+        XID _fontId;
+        XFontStruct *_fontInfo;
+        int _textHeight, _textDescent;
+        long _eventMask;
+        Colormap _colormap;
+
+        void parseCommandLine( int &argc, char **argv )
+        {
+            _programName = argv[0];
+
+            _fontName = 0;
+            _foregroundName = "Black";
+            _backgroundName = "Grey";
+            _greenName = "Green";
+            _yellowName = "Yellow";
+            _redName = "Red";
+
+            for ( int i = 1; i + 1 < argc; ++ i ) {
+                if ( !strcmp( argv[i], "-title" ) )
+                    _programName = argv[++ i];
+                else if ( !strcmp( argv[i], "-fn" ) || !strcmp( argv[i], "-font" ) )
+                    _fontName = argv[++ i];
+                else if ( !strcmp( argv[i], "-fg" ) || !strcmp( argv[i], "-foreground" ) )
+                    _foregroundName = argv[++ i];
+                else if ( !strcmp( argv[i], "-bg" ) || !strcmp( argv[i], "-background" ) )
+                    _backgroundName = argv[++ i];
+                else if ( !strcmp( argv[i], "-green" ) )
+                    _greenName = argv[++ i];
+                else if ( !strcmp( argv[i], "-yellow" ) )
+                    _yellowName = argv[++ i];
+                else if ( !strcmp( argv[i], "-red" ) )
+                    _redName = argv[++ i];
+            }
+        }
+
+        void openDisplay()
+        {
+            _display = XOpenDisplay( NULL );
+        }
+
+        void createColors()
+        {
+            _colormap = DefaultColormap( _display, 0 );
+            _foreground = getColor( _foregroundName );
+            _background = getColor( _backgroundName );
+        }
+
+        unsigned long getColor( const char *colorName )
+        {
+            XColor color;
+            XParseColor( _display, _colormap, colorName, &color );
+            XAllocColor( _display, _colormap, &color );
+            return color.pixel;
+        }
+
+        void createWindow()
+        {
+            _window = XCreateSimpleWindow( _display, RootWindow( _display, 0 ), 0, 0, 1, 1, 0, 0, _background );
+        }
+
+        void createGc()
+        {
+            _gc = XCreateGC( _display, _window, 0, 0 );
+        }
+
+        void createFont()
+        {
+            if ( !loadFont() )
+                useDefaultFont();
+            getFontInfo();
+            _textHeight = _fontInfo->ascent + _fontInfo->descent;
+            _textDescent = _fontInfo->descent;
+        }
+
+        bool loadFont()
+        {
+            if ( !_fontName )
+                return false;
+            _fontId = XLoadFont( _display, _fontName );
+            return (XSetFont( _display, _gc, _fontId ) == Success);
+        }
+
+        void useDefaultFont()
+        {
+            _fontId = XGContextFromGC( _gc );
+        }
+
+        void getFontInfo()
+        {
+            _fontInfo = XQueryFont( _display, _fontId );
+        }
+
+        void freeFontInfo()
+        {
+            XFreeFontInfo( NULL, _fontInfo, 1 );
+        }
+
+        void initializeEvents()
+        {
+            _eventMask = ExposureMask;
+            XSelectInput( _display, _window, _eventMask );
+        }
+
+        void initializeBar( const WorldDescription &wd )
+        {
+            getTotalTests( wd );
+            _testsDone = 0;
+            _barColor = getColor( _greenName );
+        }
+
+        void getTotalTests()
+        {
+            getTotalTests( tracker().world() );
+        }
+
+        void getTotalTests( const WorldDescription &wd )
+        {
+            _numTotalTests = wd.numTotalTests();
+            wd.strTotalTests( _strTotalTests );
+        }
+
+        void centerWindow()
+        {
+            XMapWindow( _display, _window );
+
+            Screen *screen = XDefaultScreenOfDisplay( _display );
+            int screenWidth = WidthOfScreen( screen );
+            int screenHeight = HeightOfScreen( screen );
+            int xCenter = screenWidth / 2;
+            int yCenter = screenHeight / 2;
+
+            _width = (screenWidth * 4) / 5;
+            _height = screenHeight / 14;
+
+            XMoveResizeWindow( _display, _window, xCenter - (_width / 2), yCenter - (_height / 2), _width, _height );
+        }
+
+        void processEvents()
+        {
+            redraw();
+
+            XEvent event;
+            while( XCheckMaskEvent( _display, _eventMask, &event ) )
+                redraw();
+        }
+
+        void setWindowName( const char *suiteName, const char *testName )
+        {
+            unsigned length = strlen( _programName ) + strlen( suiteName ) + strlen( testName ) + sizeof( " - ::()" );
+            char *name = (char *)malloc( length );
+            sprintf( name, "%s - %s::%s()", _programName, suiteName, testName );
+            XSetStandardProperties( _display, _window, name, 0, 0, 0, 0, 0 );
+            free( name );
+        }
+
+        void redraw()
+        {
+            getWindowSize();
+            drawSolidBar();
+            drawDividers();
+            drawPercentage();
+            flush();
+        }
+
+        void getWindowSize()
+        {
+            XWindowAttributes attributes;
+            XGetWindowAttributes( _display, _window, &attributes );
+            _width = attributes.width;
+            _height = attributes.height;
+        }
+
+        void drawSolidBar()
+        {
+            unsigned barWidth = (_width * _testsDone) / _numTotalTests;
+
+            XSetForeground( _display, _gc, _barColor );
+            XFillRectangle( _display, _window, _gc, 0, 0, barWidth, _height );
+
+            XSetForeground( _display, _gc, _background );
+            XFillRectangle( _display, _window, _gc, barWidth, 0, _width + 1 - barWidth, _height );
+        }
+
+        void drawDividers()
+        {
+            if(_width / _numTotalTests < 5)
+                return;
+            for ( unsigned i = 1; i < _testsDone; ++ i ) {
+                int x = (_width * i) / _numTotalTests;
+                XDrawLine( _display, _window, _gc, x, 0, x, _height);
+            }
+        }
+
+        void drawPercentage()
+        {
+            XSetForeground( _display, _gc, _foreground );
+
+            char str[sizeof("1000000000 of ") + sizeof(_strTotalTests) + sizeof(" (100%)")];
+            sprintf( str, "%u of %s (%u%%)", _testsDone, _strTotalTests, (_testsDone * 100) / _numTotalTests );
+            unsigned len = strlen( str );
+
+            int textWidth = XTextWidth( _fontInfo, str, len );
+
+            XDrawString( _display, _window, _gc,
+                         (_width - textWidth) / 2, ((_height + _textHeight) / 2) - _textDescent,
+                         str, len );
+        }
+
+        void flush()
+        {
+            XFlush( _display );
+        }
+
+        void destroyGc()
+        {
+            XFreeGC( _display, _gc );
+        }
+
+        void destroyWindow()
+        {
+            XDestroyWindow( _display, _window );
+        }
+
+        void closeDisplay()
+        {
+            XCloseDisplay( _display );
+        }
+    };
+};
+
+#endif //__cxxtest__X11Gui_h__
diff --git a/libpolys/tests/cxxtest/YesNoRunner.h b/libpolys/tests/cxxtest/YesNoRunner.h
new file mode 100644
index 0000000..c8e891d
--- /dev/null
+++ b/libpolys/tests/cxxtest/YesNoRunner.h
@@ -0,0 +1,29 @@
+#ifndef __cxxtest__YesNoRunner_h__
+#define __cxxtest__YesNoRunner_h__
+
+//
+// The YesNoRunner is a simple TestListener that
+// just returns true iff all tests passed.
+//
+
+#include <cxxtest/TestRunner.h>
+#include <cxxtest/TestListener.h>
+
+namespace CxxTest
+{
+    class YesNoRunner : public TestListener
+    {
+    public:
+        YesNoRunner()
+        {
+        }
+
+        int run()
+        {
+            TestRunner::runAllTests( *this );
+            return tracker().failedTests();
+        }
+    };
+}
+
+#endif // __cxxtest__YesNoRunner_h__
diff --git a/libpolys/tests/cxxtestgen.pl b/libpolys/tests/cxxtestgen.pl
new file mode 100755
index 0000000..8e59c65
--- /dev/null
+++ b/libpolys/tests/cxxtestgen.pl
@@ -0,0 +1,555 @@
+#!/usr/bin/perl -w
+use strict;
+use Getopt::Long;
+
+sub usage() {
+  print STDERR "Usage: $0 [OPTIONS] <input file(s)>\n";
+  print STDERR "Generate test source file for CxxTest.\n";
+  print STDERR "\n";
+  print STDERR "  -v, --version        Write CxxTest version\n";
+  print STDERR "  -o, --output=NAME    Write output to file NAME\n";
+  print STDERR "  --runner=CLASS       Create a main() function that runs CxxTest::CLASS\n";
+  print STDERR "  --gui=CLASS          Like --runner, with GUI component\n";
+  print STDERR "  --error-printer      Same as --runner=ErrorPrinter\n";
+  print STDERR "  --abort-on-fail      Abort tests on failed asserts (like xUnit)\n";
+  print STDERR "  --have-std           Use standard library (even if not found in tests)\n";
+  print STDERR "  --no-std             Don't use standard library (even if found in tests)\n";
+  print STDERR "  --have-eh            Use exception handling (even if not found in tests)\n";
+  print STDERR "  --no-eh              Don't use exception handling (even if found in tests)\n";
+  print STDERR "  --longlong=[TYPE]    Use TYPE as `long long' (defaut = long long)\n";
+  print STDERR "  --template=TEMPLATE  Use TEMPLATE file to generate the test runner\n";
+  print STDERR "  --include=HEADER     Include \"HEADER\" in test runner before other headers\n";
+  print STDERR "  --root               Write CxxTest globals\n";
+  print STDERR "  --part               Don't write CxxTest globals\n";
+  print STDERR "  --no-static-init     Don't rely on static initialization\n";
+  exit -1;
+}
+
+main();
+
+sub main {
+  parseCommandline();
+  scanInputFiles();
+  writeOutput();
+}
+
+#
+# Handling the command line
+#
+
+my ($output, $runner, $gui, $template, $abortOnFail, $haveEh, $noEh, $haveStd, $noStd);
+my ($root, $part, $noStaticInit, $longlong, $factor);
+my @headers = ();
+
+sub parseCommandline() {
+  @ARGV = expandWildcards(@ARGV);
+  GetOptions( 'version'        => \&printVersion,
+	      'output=s'       => \$output,
+	      'template=s'     => \$template,
+	      'runner=s'       => \$runner,
+	      'gui=s',         => \$gui,
+	      'error-printer'  => sub { $runner = 'ErrorPrinter'; $haveStd = 1; },
+	      'abort-on-fail'  => \$abortOnFail,
+	      'have-eh'        => \$haveEh,
+	      'no-eh'          => \$noEh,
+	      'have-std'        => \$haveStd,
+	      'no-std'          => \$noStd,
+	      'include=s'      => \@headers,
+	      'root'           => \$root,
+	      'part'           => \$part,
+	      'no-static-init' => \$noStaticInit,
+	      'factor'         => \$factor,
+	      'longlong:s'     => \$longlong
+	    ) or usage();
+  scalar @ARGV or $root or usage();
+
+  if ( defined($noStaticInit) && (defined($root) || defined($part)) ) {
+    die "--no-static-init cannot be used with --root/--part\n";
+  }
+
+  if ( $gui && !$runner ) {
+    $runner = 'StdioPrinter';
+  }
+
+  if ( defined($longlong) && !$longlong ) {
+    $longlong = 'long long';
+  }
+
+  foreach my $header (@headers) {
+    if ( !($header =~ m/^["<].*[>"]$/) ) {
+      $header = "\"$header\"";
+    }
+  }
+}
+
+sub printVersion() {
+  print "This is CxxTest version 3.10.1.\n";
+  exit 0;
+}
+
+sub expandWildcards() {
+  my @result = ();
+  while( my $fn = shift @_ ) {
+    push @result, glob($fn);
+  }
+  return @result;
+}
+
+#
+# Reading the input files and scanning for test cases
+#
+
+my (@suites, $suite, $test, $inBlock);
+my $numTotalTests = 0;
+
+sub scanInputFiles() {
+  foreach my $file (@ARGV) {
+    scanInputFile( $file );
+  }
+  scalar @suites or $root or die("No tests defined\n");
+}
+
+sub scanInputFile($) {
+  my ($file) = @_;
+  open FILE, "<$file" or die("Cannot open input file \"$file\"\n");
+
+  my $line;
+  while (defined($line = <FILE>)) {
+    scanLineForExceptionHandling( $line );
+    scanLineForStandardLibrary( $line );
+
+    scanLineForSuiteStart( $file, $., $line );
+
+    if ( $suite ) {
+      if ( lineBelongsToSuite( $suite, $., $line ) ) {
+	scanLineForTest( $., $line );
+	scanLineForCreate( $., $line );
+	scanLineForDestroy( $., $line );
+      }
+    }
+  }
+  closeSuite();
+  close FILE;
+}
+
+sub lineBelongsToSuite($$$) {
+  my ($suite, $lineNo, $line) = @_;
+  if ( !$suite->{'generated'} ) {
+    return 1;
+  }
+
+  if ( !$inBlock ) {
+    $inBlock = lineStartsBlock( $line );
+  }
+  if ( $inBlock ) {
+    addLineToBlock( $suite->{'file'}, $lineNo, $line );
+  }
+  return $inBlock;
+}
+
+sub scanLineForExceptionHandling($) {
+  my ($line) = @_;
+  if ( $line =~ m/\b(try|throw|catch|TSM?_ASSERT_THROWS[A-Z_]*)\b/ ) {
+    addExceptionHandling();
+  }
+}
+
+sub scanLineForStandardLibrary($) {
+  my ($line) = @_;
+  if ( $line =~ m/\b(std\s*::|CXXTEST_STD|using\s+namespace\s+std\b|^\s*\#\s*include\s+<[a-z0-9]+>)/ ) {
+    addStandardLibrary();
+  }
+}
+
+sub scanLineForSuiteStart($$$) {
+  my ($fileName, $lineNo, $line) = @_;
+  if ( $line =~ m/\bclass\s+(\w+)\s*:\s*public\s+((::)?\s*CxxTest\s*::\s*)?TestSuite\b/ ) {
+    startSuite( $1, $fileName, $lineNo, 0 );
+  }
+  if ( $line =~ m/\bCXXTEST_SUITE\s*\(\s*(\w*)\s*\)/ ) {
+    print "$fileName:$lineNo: Warning: Inline test suites are deprecated.\n";
+    startSuite( $1, $fileName, $lineNo, 1 );
+  }
+}
+
+sub startSuite($$$$) {
+  my ($name, $file, $line, $generated) = @_;
+  closeSuite();
+  $suite = { 'name' => $name,
+	     'file' => $file,
+	     'line' => $line,
+	     'generated' => $generated,
+	     'create' => 0,
+	     'destroy' => 0,
+	     'tests' => [],
+	     'lines' => [] };
+}
+
+sub lineStartsBlock($) {
+  my ($line) = @_;
+  return $line =~ m/\bCXXTEST_CODE\s*\(/;
+}
+
+sub scanLineForTest($$) {
+  my ($lineNo, $line) = @_;
+  if ( $line =~ m/^([^\/]|\/[^\/])*\bvoid\s+([Tt]est\w+)\s*\(\s*(void)?\s*\)/ ) {
+    addTest( $2, $lineNo );
+  }
+}
+
+sub addTest($$$) {
+  my ($name, $line) = @_;
+  $test = { 'name' => $name,
+	    'line' => $line };
+  push @{suiteTests()}, $test;
+}
+
+sub addLineToBlock($$$) {
+  my ($fileName, $lineNo, $line) = @_;
+  $line = fixBlockLine( $fileName, $lineNo, $line );
+  $line =~ s/^.*\{\{//;
+  my $end = ($line =~ s/\}\}.*//s);
+  push @{$suite->{'lines'}}, $line;
+  if ( $end ) {
+    $inBlock = 0;
+  }
+}
+
+sub fixBlockLine($$$) {
+  my ($fileName, $lineNo, $line) = @_;
+  my $fileLine = cstr($fileName) . "," . $lineNo;
+  $line =~ s/\b(E?TSM?_(ASSERT[A-Z_]*|FAIL))\s*\(/_$1($fileLine,/g;
+  return $line;
+}
+
+sub scanLineForCreate($$) {
+  my ($lineNo, $line) = @_;
+  if ( $line =~ m/\bstatic\s+\w+\s*\*\s*createSuite\s*\(\s*(void)?\s*\)/ ) {
+    addCreateSuite( $lineNo );
+  }
+}
+
+sub scanLineForDestroy($$) {
+  my ($lineNo, $line) = @_;
+  if ( $line =~ m/\bstatic\s+void\s+destroySuite\s*\(\s*\w+\s*\*\s*\w*\s*\)/ ) {
+    addDestroySuite( $lineNo );
+  }
+}
+
+sub closeSuite() {
+  if ( $suite && scalar @{suiteTests()} ) {
+    verifySuite();
+    rememberSuite();
+  }
+  undef $suite;
+}
+
+sub addCreateSuite($) {
+  $suite->{'createSuite'} = $_[0];
+}
+
+sub addDestroySuite($) {
+  $suite->{'destroySuite'} = $_[0];
+}
+
+sub addExceptionHandling() {
+  $haveEh = 1 unless defined($noEh);
+}
+
+sub addStandardLibrary() {
+  $haveStd = 1 unless defined($noStd);
+}
+
+sub verifySuite() {
+  if (suiteCreateLine() || suiteDestroyLine()) {
+    die("Suite ", suiteName(), "  must have both createSuite() and destroySuite()\n")
+      unless (suiteCreateLine() && suiteDestroyLine());
+  }
+}
+
+sub rememberSuite() {
+  push @suites, $suite;
+  $numTotalTests += scalar @{$suite->{'tests'}};
+}
+
+sub suiteName() { return $suite->{'name'}; }
+sub suiteTests() { return $suite->{'tests'}; }
+sub suiteCreateLine() { return $suite->{'createSuite'}; }
+sub suiteDestroyLine() { return $suite->{'destroySuite'}; }
+sub fileName() { return $suite->{'file'}; }
+sub fileString() { return cstr(fileName()); }
+sub testName() { return $test->{'name'}; }
+sub testLine() { return $test->{'line'}; }
+
+sub suiteObject() { return "suite_".suiteName(); }
+
+sub cstr($) {
+  my $file = $_[0];
+  $file =~ s/\\/\\\\/g;
+  return "\"".$file."\"";
+}
+
+#
+# Writing the test source file
+#
+
+sub writeOutput() {
+  $template ? writeTemplateOutput() : writeSimpleOutput();
+}
+
+sub startOutputFile() {
+  if ( !standardOutput() ) {
+    open OUTPUT_FILE,">$output" or die("Cannot create output file \"$output\"\n");
+    select OUTPUT_FILE;
+  }
+  print "/* Generated file, do not edit */\n\n";
+}
+
+sub standardOutput() {
+  return !$output;
+}
+
+sub writeSimpleOutput() {
+  startOutputFile();
+  writePreamble();
+  writeMain();
+  writeWorld();
+}
+
+my ($didPreamble, $didWorld);
+
+sub writeTemplateOutput() {
+  openTemplateFile();
+  startOutputFile();
+  my $line;
+  while (defined($line = <TEMPLATE_FILE>)) {
+    if ( $line =~ m/^\s*\#\s*include\s*<cxxtest\// ) {
+      writePreamble();
+      print $line;
+    } elsif ( $line =~ m/^\s*<CxxTest\s+preamble>\s*$/ ) {
+      writePreamble();
+    } elsif ( $line =~ m/^\s*<CxxTest\s+world>\s*$/ ) {
+      writeWorld();
+    } else {
+      print $line;
+    }
+  }
+}
+
+sub openTemplateFile() {
+  open TEMPLATE_FILE, "<$template" or die("Cannot open template file \"$template\"\n");
+}
+
+sub writePreamble() {
+  return if $didPreamble;
+  print "#ifndef CXXTEST_RUNNING\n";
+  print "#define CXXTEST_RUNNING\n";
+  print "#endif\n";
+  print "\n";
+  if ( $haveStd ) {
+    print "#define _CXXTEST_HAVE_STD\n";
+  }
+  if ( $haveEh ) {
+    print "#define _CXXTEST_HAVE_EH\n";
+  }
+  if ( $abortOnFail ) {
+    print "#define _CXXTEST_ABORT_TEST_ON_FAIL\n";
+  }
+  if ( $longlong ) {
+    print "#define _CXXTEST_LONGLONG $longlong\n";
+  }
+  if ( $factor ) {
+    print "#define _CXXTEST_FACTOR\n";
+  }
+  foreach my $header (@headers) {
+    print "#include $header\n";
+  }
+  print "#include <cxxtest/TestListener.h>\n";
+  print "#include <cxxtest/TestTracker.h>\n";
+  print "#include <cxxtest/TestRunner.h>\n";
+  print "#include <cxxtest/RealDescriptions.h>\n";
+  print "#include <cxxtest/$runner.h>\n" if $runner;
+  print "#include <cxxtest/$gui.h>\n" if $gui;
+  print "\n";
+  $didPreamble = 1;
+}
+
+sub writeWorld() {
+  return if $didWorld;
+  writePreamble();
+  writeSuites();
+  ($root or !$part) and writeRoot();
+  $noStaticInit and writeInitialize();
+  $didWorld = 1;
+}
+
+sub writeSuites() {
+  foreach (@suites) {
+    $suite = $_;
+    writeInclude(fileName());
+    if ( $suite->{'generated'} ) { generateSuite(); }
+    dynamicSuite() ? writeSuitePointer() : writeSuiteObject();
+    writeTestList();
+    writeSuiteDescription();
+    writeTestDescriptions();
+  }
+}
+
+sub dynamicSuite() {
+  return suiteCreateLine();
+}
+
+my $lastIncluded;
+
+sub writeInclude($) {
+  my $file = $_[0];
+  return if $lastIncluded && ($file eq $lastIncluded);
+  print "#include \"$file\"\n\n";
+  $lastIncluded = $file;
+}
+
+sub generateSuite() {
+  print "class ", suiteName(), " : public CxxTest::TestSuite {\n";
+  print "public:\n";
+  foreach my $line (@{$suite->{'lines'}}) {
+    print $line;
+  }
+  print "};\n\n";
+}
+
+sub writeTestDescriptionsBase() {
+  my $class = "TestDescriptionBase_" . suiteName();
+  print "class $class : public CxxTest::TestDescription {\n";
+  print "public:\n";
+  print " const char *file() const { return ", fileString(), "; }\n";
+  print " const char *suiteName() const { return \"", suiteName(), "\"; }\n";
+  print "};\n\n";
+}
+
+sub writeSuitePointer() {
+  if ( $noStaticInit ) {
+    print "static ", suiteName(), " *", suiteObject(), ";\n\n";
+  } else {
+    print "static ", suiteName(), " *", suiteObject(), " = 0;\n\n";
+  }
+}
+
+sub writeSuiteObject() {
+  print "static ", suiteName(), " ", suiteObject(), ";\n\n";
+}
+
+sub testList() {
+  return "Tests_" . suiteName();
+}
+
+sub writeTestList() {
+  if ( $noStaticInit ) {
+    printf "static CxxTest::List %s;\n", testList();
+  } else {
+    printf "static CxxTest::List %s = { 0, 0 };\n", testList();
+  }
+}
+
+sub writeTestDescriptions() {
+  foreach (@{suiteTests()}) {
+    $test = $_;
+    writeTestDescription();
+  }
+}
+
+sub suiteDescription() {
+  return "suiteDescription_" . suiteName();
+}
+
+sub writeTestDescription() {
+  my $class = "TestDescription_" . suiteName() . "_" . testName();
+  printf "static class $class : public CxxTest::RealTestDescription {\n";
+  printf "public:\n";
+  $noStaticInit or
+    printf " $class() : CxxTest::RealTestDescription( %s, %s, %s, \"%s\" ) {}\n",
+      testList(), suiteDescription(), testLine(), testName();
+  printf " void runTest() { %s }\n", dynamicSuite() ? dynamicRun() : staticRun();
+  printf "} testDescription_%s_%s;\n\n", suiteName(), testName();
+}
+
+sub dynamicRun() {
+  return sprintf( "if ( %s ) %s->%s();", suiteObject(), suiteObject(), testName() );
+}
+
+sub staticRun() {
+  return sprintf( "%s.%s();", suiteObject(), testName() );
+}
+
+sub writeSuiteDescription() {
+  dynamicSuite() ? writeDynamicDescription() : writeStaticDescription();
+}
+
+sub writeDynamicDescription() {
+  printf "CxxTest::DynamicSuiteDescription<%s> %s", suiteName(), suiteDescription();
+  if ( !$noStaticInit ) {
+    printf "( %s, %s, \"%s\", %s, %s, %s, %s )",
+      fileString(), $suite->{'line'}, suiteName(), testList(),
+	suiteObject(), suiteCreateLine(), suiteDestroyLine();
+  }
+  print ";\n\n";
+}
+
+sub writeStaticDescription() {
+  printf "CxxTest::StaticSuiteDescription %s", suiteDescription();
+  if ( !$noStaticInit ) {
+    printf "( %s, %s, \"%s\", %s, %s )", fileString(), $suite->{'line'}, suiteName(), suiteObject(), testList();
+  }
+  print ";\n\n";
+}
+
+sub writeRoot() {
+  print "#include <cxxtest/Root.cpp>\n";
+}
+
+sub writeInitialize() {
+  print "namespace CxxTest {\n";
+  print " void initialize()\n";
+  print " {\n";
+  foreach (@suites) {
+    $suite = $_;
+    printf "  %s.initialize();\n", testList();
+    if ( dynamicSuite() ) {
+      printf "  %s = 0;\n", suiteObject();
+      printf "  %s.initialize( %s, %s, \"%s\", %s, %s, %s, %s );\n",
+	suiteDescription(), fileString(), $suite->{'line'}, suiteName(), testList(),
+	  suiteObject(), suiteCreateLine(), suiteDestroyLine();
+    } else {
+      printf "  %s.initialize( %s, %s, \"%s\", %s, %s );\n",
+	suiteDescription(), fileString(), $suite->{'line'}, suiteName(), suiteObject(), testList();
+    }
+
+    foreach (@{suiteTests()}) {
+      $test = $_;
+      printf "  testDescription_%s_%s.initialize( %s, %s, %s, \"%s\" );\n",
+	suiteName(), testName(), testList(), suiteDescription(), testLine(), testName();
+    }
+  }
+  print " }\n";
+  print "}\n";
+}
+
+sub writeMain() {
+  if ( $gui ) {
+    print "char* argv0 = NULL;\n";
+    print "int main( int argc, char *argv[] ) {\n";
+    print "argv0 = argv[0];\n";
+    $noStaticInit &&
+      print " CxxTest::initialize();\n";
+    print " return CxxTest::GuiTuiRunner<CxxTest::$gui, CxxTest::$runner>( argc, argv ).run();\n";
+    print "}\n";
+  }
+  elsif ( $runner ) {
+    print "char* argv0 = NULL;\n";
+    print "int main( int, char *argv[] ) {\n";
+    print "argv0 = argv[0];\n";
+    $noStaticInit &&
+      print " CxxTest::initialize();\n";
+    print " return CxxTest::$runner().run();\n";
+    print "}\n";
+  }
+}
diff --git a/libpolys/tests/polys_test.h b/libpolys/tests/polys_test.h
new file mode 100644
index 0000000..09c07de
--- /dev/null
+++ b/libpolys/tests/polys_test.h
@@ -0,0 +1,2627 @@
+#include "common.h"
+using namespace std;
+
+// the following headers are private...
+
+
+#include <polys/monomials/ring.h>
+#include <polys/monomials/p_polys.h>
+
+#include <polys/simpleideals.h>
+
+#if 0 //ifdef HAVE_FACTORY
+#include <polys/clapsing.h>
+#include <factory/factory.h>
+#endif
+
+
+#define TRANSEXT_PRIVATES
+
+#include <polys/ext_fields/algext.h>
+#include <polys/ext_fields/transext.h>
+
+
+class MyGlobalPrintingFixture : public GlobalPrintingFixture
+{
+  public:
+    virtual bool setUpWorld()
+    {
+
+      GlobalPrintingFixture::setUpWorld();
+
+
+      //TS_ASSERT_EQUALS( nRegister( n_Zp, npInitChar), n_Zp );
+      //TS_ASSERT_EQUALS( nRegister( n_GF, nfInitChar), n_GF );
+      //TS_ASSERT_EQUALS( nRegister( n_R, nrInitChar), n_R );
+      //TS_ASSERT_EQUALS( nRegister( n_Q, nlInitChar), n_Q );
+      //TS_ASSERT_EQUALS( nRegister( n_R, nrInitChar), n_R );
+
+#ifdef HAVE_RINGS
+      //TS_ASSERT_EQUALS( nRegister( n_Z, nrzInitChar), n_Z ); // these are UNusable at the moment!
+#endif
+
+      return true;
+    }
+};
+
+
+//
+// We can rely on this file being included exactly once
+// and declare this global variable in the header file.
+//
+static MyGlobalPrintingFixture globalPrintingFixture;
+
+
+namespace
+{
+
+  void PrintRing(const ring r)
+  {
+    rWrite(r); PrintLn();
+  #ifdef  RDEBUG
+    rDebugPrint(r); PrintLn();
+  #endif
+  }
+
+  static inline std::string _2S(poly a, const ring r)
+  {
+    p_Test(a,r);
+
+    StringSetS("");
+    p_Write(a, r);
+
+    std::stringstream ss;
+    {
+      char* s = StringEndS();  ss << s; omFree(s);
+    }
+
+    return ss.str();
+  }
+
+  static inline void PrintSized(/*const*/ poly a, const ring r, BOOLEAN eoln = TRUE)
+  {
+    std::clog << _2S(a, r) << ", of size: " << p_Size(a, r);
+
+    if( eoln )
+      std::clog << std::endl;
+  }
+
+static inline void Delete(poly &p, const ring r)
+{
+  if( p != NULL )
+    p_Delete(&p, r);
+
+  p = NULL;
+}
+
+void TestSum(const ring r, const int N)
+{
+  TS_ASSERT_DIFFERS( r    , NULLp);
+  TS_ASSERT_DIFFERS( r->cf, NULLp);
+
+
+  clog << ( _2S("TEST: sum[0..") + _2S(N) + "]: ");
+  clog << endl;
+
+  assume( N > 0 ); // just for now...
+
+  const int ssss = (N * (N+1)) / 2;
+
+  poly sum1 = p_ISet(ssss, r);
+  clog<< "poly(N*(N+1)/2) (int: " << ssss << "): "; PrintSized(sum1, r);
+
+  poly s=NULL, ss=NULL, i=NULL, res=NULL;
+
+  s = p_ISet(N  , r);
+  i = p_ISet(N+1, r);
+
+  i = p_Mult_q(s, i, r); s = NULL;
+
+  clog<< "poly(N)*poly(N+1): (int: "<< N*(N+1) << "): "; PrintSized(i, r);
+
+  number t = n_Init(2, r->cf);
+  clog<< "number(2): "; PrintSized(t, r->cf);
+
+  if( !n_IsZero( t, r->cf) )
+  {
+    if( i != NULL )
+    {
+      number ii = p_GetCoeff(i, r);
+      clog<< "number(poly(N)*poly(N+1)): "; PrintSized(ii, r->cf);
+
+#ifdef HAVE_RINGS
+      TS_ASSERT( n_DivBy(ii, t, r->cf) );
+#endif
+       res = p_Div_nn(i, t, r); i = NULL;
+    }
+
+
+
+    clog<< "(poly(N)*poly(N+1))/number(2): "; PrintSized(res, r);
+    poly d = p_Sub(p_Copy(res, r), p_Copy(sum1, r), r);
+
+    if( d != NULL )
+      TS_ASSERT( n_IsZeroDivisor(p_GetCoeff(d, r), r->cf) );
+
+    Delete(d, r);
+
+    if( n_GetChar(r->cf) == 0 )
+    {
+      TS_ASSERT( p_EqualPolys(sum1, res, r) );
+      TS_ASSERT( p_EqualPolys(res, sum1, r) );
+    }
+  } else
+    TS_ASSERT_EQUALS( n_GetChar(r->cf), 2);
+
+  n_Delete(&t, r->cf);
+
+
+  s = NULL;
+  ss = NULL;
+  for( int k = N; k >= 0; k-- )
+  {
+    i = p_ISet(k, r);
+    s = p_Add_q(s, i, r); // s += i
+
+    i = p_Neg( p_ISet(k, r), r );
+    ss = p_Add_q(ss, i, r); // ss -= i
+  }
+
+  clog<< "ss(-sum): "; PrintSized(ss, r);
+
+  ss = p_Neg(ss, r); // ss = -ss
+
+  clog<< "real sum    : "; PrintSized(s, r);
+  clog<< "real sum(--): "; PrintSized(ss, r);
+
+  TS_ASSERT( p_EqualPolys(s, ss, r) );
+  TS_ASSERT( p_EqualPolys(ss, s, r) );
+
+//   TODO(somebody, fix the delete method!);
+
+  Delete(sum1, r);
+  Delete(res, r);
+
+  Delete(s, r);
+  Delete(ss, r);
+
+  clog << ( " >>> TEST DONE!" );
+  clog << endl;
+
+}
+
+void Test(const ring r)
+{
+  if( r == NULL )
+      TS_FAIL("Could not get needed ring");
+  else
+  {
+    TestSum( r, 10 );
+    TestSum( r, 100 );
+    TestSum( r, 101 );
+    TestSum( r, 1001 );
+    TestSum( r, 9000 );
+  }
+}
+
+}
+
+class PolysTestSuite : public CxxTest::TestSuite
+{
+private:
+  /* replaces p by p + c * var(i)^exp (in-place);
+     expects exp >= 0 */
+  void plusTerm(poly &p, int c, int i, int exp, const ring r)
+  {
+    poly t = p_ISet(c, r);
+    if (exp > 0) { p_SetExp(t, i, exp, r); p_Setm(t, r); }
+    p = p_Add_q(p, t, r);
+  }
+  /* assumes that r is over Q;
+     replaces p by p + c1 / c2 * var(i)^exp (in-place);
+     expects exp >= 0, and c2 != 0 */
+  void plusTermOverQ(poly &p, int c1, int c2, int i, int exp, const ring r)
+  {
+    number c1AsN = n_Init(c1, r->cf);
+    number c2AsN = n_Init(c2, r->cf);
+    number c =  n_Div(c1AsN, c2AsN, r->cf);
+    poly t = p_ISet(1, r); p_SetCoeff(t, c, r);
+    if (exp > 0) { p_SetExp(t, i, exp, r); p_Setm(t, r); }
+    p = p_Add_q(p, t, r);
+  }
+  /* assumes r to represent Q(x)[y], for some variable names x and y;
+     replaces p by p + (c1 * 1000000 + c2) * x^xExp * y^yExp (in-place);
+     expects xExp, yExp >= 0 */
+  void specialPlusTerm(poly &p, int c1, int c2, int sign,
+                       int xExp, int yExp, const ring r)
+  {
+    poly c1p = p_ISet(c1, r->cf->extRing);
+    poly c2p = p_ISet(c2, r->cf->extRing);
+    poly c3p = p_ISet(1000000, r->cf->extRing);
+    poly xterm = p_Mult_q(c1p, c3p, r->cf->extRing);
+    xterm = p_Add_q(xterm, c2p, r->cf->extRing);
+    if (sign == -1) xterm = p_Neg(xterm, r->cf->extRing);
+    if (xExp > 0)
+    {
+      p_SetExp(xterm, 1, xExp, r->cf->extRing);
+      p_Setm(xterm, r->cf->extRing);
+    }
+    number xtermAsN = toFractionNumber(xterm, r->cf);
+    poly yterm = p_ISet(1, r);
+    if (yExp > 0)
+    {
+      p_SetExp(yterm, 1, yExp, r);
+      p_Setm(yterm, r);
+    }
+    p_SetCoeff(yterm, xtermAsN, r);
+    p = p_Add_q(p, yterm, r);
+  }
+  /* defines a special test polynomial in Q(x)[y], for some variable
+     names x and y, by excessively using specialPlusTerm */
+  void specialPoly(poly &p, const ring r)
+  {
+    p = NULL;
+    specialPlusTerm(p, 0, 1, 1, 0, 17, r);
+    specialPlusTerm(p, 0, 1, -1, 15, 16, r);
+    specialPlusTerm(p, 0, 2, -1, 14, 16, r);
+    specialPlusTerm(p, 0, 3, -1, 13, 16, r);
+    specialPlusTerm(p, 0, 4, -1, 12, 16, r);
+    specialPlusTerm(p, 0, 5, -1, 11, 16, r);
+    specialPlusTerm(p, 0, 6, -1, 10, 16, r);
+    specialPlusTerm(p, 0, 7, -1, 9, 16, r);
+    specialPlusTerm(p, 0, 8, -1, 8, 16, r);
+    specialPlusTerm(p, 0, 9, -1, 7, 16, r);
+    specialPlusTerm(p, 0, 10, -1, 6, 16, r);
+    specialPlusTerm(p, 0, 11, -1, 5, 16, r);
+    specialPlusTerm(p, 0, 12, -1, 4, 16, r);
+    specialPlusTerm(p, 0, 13, -1, 3, 16, r);
+    specialPlusTerm(p, 0, 14, -1, 2, 16, r);
+    specialPlusTerm(p, 0, 15, -1, 1, 16, r);
+    specialPlusTerm(p, 0, 16, -1, 0, 16, r);
+    specialPlusTerm(p, 0, 1, 1, 29, 15, r);
+    specialPlusTerm(p, 0, 3, 1, 28, 15, r);
+    specialPlusTerm(p, 0, 7, 1, 27, 15, r);
+    specialPlusTerm(p, 0, 13, 1, 26, 15, r);
+    specialPlusTerm(p, 0, 22, 1, 25, 15, r);
+    specialPlusTerm(p, 0, 34, 1, 24, 15, r);
+    specialPlusTerm(p, 0, 50, 1, 23, 15, r);
+    specialPlusTerm(p, 0, 70, 1, 22, 15, r);
+    specialPlusTerm(p, 0, 95, 1, 21, 15, r);
+    specialPlusTerm(p, 0, 125, 1, 20, 15, r);
+    specialPlusTerm(p, 0, 161, 1, 19, 15, r);
+    specialPlusTerm(p, 0, 203, 1, 18, 15, r);
+    specialPlusTerm(p, 0, 252, 1, 17, 15, r);
+    specialPlusTerm(p, 0, 308, 1, 16, 15, r);
+    specialPlusTerm(p, 0, 372, 1, 15, 15, r);
+    specialPlusTerm(p, 0, 428, 1, 14, 15, r);
+    specialPlusTerm(p, 0, 476, 1, 13, 15, r);
+    specialPlusTerm(p, 0, 515, 1, 12, 15, r);
+    specialPlusTerm(p, 0, 545, 1, 11, 15, r);
+    specialPlusTerm(p, 0, 565, 1, 10, 15, r);
+    specialPlusTerm(p, 0, 575, 1, 9, 15, r);
+    specialPlusTerm(p, 0, 574, 1, 8, 15, r);
+    specialPlusTerm(p, 0, 562, 1, 7, 15, r);
+    specialPlusTerm(p, 0, 538, 1, 6, 15, r);
+    specialPlusTerm(p, 0, 502, 1, 5, 15, r);
+    specialPlusTerm(p, 0, 453, 1, 4, 15, r);
+    specialPlusTerm(p, 0, 391, 1, 3, 15, r);
+    specialPlusTerm(p, 0, 315, 1, 2, 15, r);
+    specialPlusTerm(p, 0, 225, 1, 1, 15, r);
+    specialPlusTerm(p, 0, 120, 1, 0, 15, r);
+    specialPlusTerm(p, 0, 1, -1, 42, 14, r);
+    specialPlusTerm(p, 0, 4, -1, 41, 14, r);
+    specialPlusTerm(p, 0, 11, -1, 40, 14, r);
+    specialPlusTerm(p, 0, 25, -1, 39, 14, r);
+    specialPlusTerm(p, 0, 50, -1, 38, 14, r);
+    specialPlusTerm(p, 0, 91, -1, 37, 14, r);
+    specialPlusTerm(p, 0, 155, -1, 36, 14, r);
+    specialPlusTerm(p, 0, 250, -1, 35, 14, r);
+    specialPlusTerm(p, 0, 386, -1, 34, 14, r);
+    specialPlusTerm(p, 0, 575, -1, 33, 14, r);
+    specialPlusTerm(p, 0, 831, -1, 32, 14, r);
+    specialPlusTerm(p, 0, 1170, -1, 31, 14, r);
+    specialPlusTerm(p, 0, 1611, -1, 30, 14, r);
+    specialPlusTerm(p, 0, 2175, -1, 29, 14, r);
+    specialPlusTerm(p, 0, 2871, -1, 28, 14, r);
+    specialPlusTerm(p, 0, 3710, -1, 27, 14, r);
+    specialPlusTerm(p, 0, 4690, -1, 26, 14, r);
+    specialPlusTerm(p, 0, 5810, -1, 25, 14, r);
+    specialPlusTerm(p, 0, 7056, -1, 24, 14, r);
+    specialPlusTerm(p, 0, 8414, -1, 23, 14, r);
+    specialPlusTerm(p, 0, 9856, -1, 22, 14, r);
+    specialPlusTerm(p, 0, 11354, -1, 21, 14, r);
+    specialPlusTerm(p, 0, 12865, -1, 20, 14, r);
+    specialPlusTerm(p, 0, 14345, -1, 19, 14, r);
+    specialPlusTerm(p, 0, 15735, -1, 18, 14, r);
+    specialPlusTerm(p, 0, 16974, -1, 17, 14, r);
+    specialPlusTerm(p, 0, 17985, -1, 16, 14, r);
+    specialPlusTerm(p, 0, 18689, -1, 15, 14, r);
+    specialPlusTerm(p, 0, 18990, -1, 14, 14, r);
+    specialPlusTerm(p, 0, 18909, -1, 13, 14, r);
+    specialPlusTerm(p, 0, 18465, -1, 12, 14, r);
+    specialPlusTerm(p, 0, 17689, -1, 11, 14, r);
+    specialPlusTerm(p, 0, 16610, -1, 10, 14, r);
+    specialPlusTerm(p, 0, 15270, -1, 9, 14, r);
+    specialPlusTerm(p, 0, 13709, -1, 8, 14, r);
+    specialPlusTerm(p, 0, 11980, -1, 7, 14, r);
+    specialPlusTerm(p, 0, 10135, -1, 6, 14, r);
+    specialPlusTerm(p, 0, 8239, -1, 5, 14, r);
+    specialPlusTerm(p, 0, 6356, -1, 4, 14, r);
+    specialPlusTerm(p, 0, 4564, -1, 3, 14, r);
+    specialPlusTerm(p, 0, 2940, -1, 2, 14, r);
+    specialPlusTerm(p, 0, 1575, -1, 1, 14, r);
+    specialPlusTerm(p, 0, 560, -1, 0, 14, r);
+    specialPlusTerm(p, 0, 1, 1, 54, 13, r);
+    specialPlusTerm(p, 0, 5, 1, 53, 13, r);
+    specialPlusTerm(p, 0, 16, 1, 52, 13, r);
+    specialPlusTerm(p, 0, 41, 1, 51, 13, r);
+    specialPlusTerm(p, 0, 92, 1, 50, 13, r);
+    specialPlusTerm(p, 0, 187, 1, 49, 13, r);
+    specialPlusTerm(p, 0, 353, 1, 48, 13, r);
+    specialPlusTerm(p, 0, 628, 1, 47, 13, r);
+    specialPlusTerm(p, 0, 1065, 1, 46, 13, r);
+    specialPlusTerm(p, 0, 1735, 1, 45, 13, r);
+    specialPlusTerm(p, 0, 2732, 1, 44, 13, r);
+    specialPlusTerm(p, 0, 4177, 1, 43, 13, r);
+    specialPlusTerm(p, 0, 6225, 1, 42, 13, r);
+    specialPlusTerm(p, 0, 9056, 1, 41, 13, r);
+    specialPlusTerm(p, 0, 12882, 1, 40, 13, r);
+    specialPlusTerm(p, 0, 17939, 1, 39, 13, r);
+    specialPlusTerm(p, 0, 24481, 1, 38, 13, r);
+    specialPlusTerm(p, 0, 32771, 1, 37, 13, r);
+    specialPlusTerm(p, 0, 43075, 1, 36, 13, r);
+    specialPlusTerm(p, 0, 55639, 1, 35, 13, r);
+    specialPlusTerm(p, 0, 70682, 1, 34, 13, r);
+    specialPlusTerm(p, 0, 88372, 1, 33, 13, r);
+    specialPlusTerm(p, 0, 108804, 1, 32, 13, r);
+    specialPlusTerm(p, 0, 131974, 1, 31, 13, r);
+    specialPlusTerm(p, 0, 157756, 1, 30, 13, r);
+    specialPlusTerm(p, 0, 185860, 1, 29, 13, r);
+    specialPlusTerm(p, 0, 215806, 1, 28, 13, r);
+    specialPlusTerm(p, 0, 246985, 1, 27, 13, r);
+    specialPlusTerm(p, 0, 278631, 1, 26, 13, r);
+    specialPlusTerm(p, 0, 309893, 1, 25, 13, r);
+    specialPlusTerm(p, 0, 339819, 1, 24, 13, r);
+    specialPlusTerm(p, 0, 367427, 1, 23, 13, r);
+    specialPlusTerm(p, 0, 391701, 1, 22, 13, r);
+    specialPlusTerm(p, 0, 411675, 1, 21, 13, r);
+    specialPlusTerm(p, 0, 426428, 1, 20, 13, r);
+    specialPlusTerm(p, 0, 435181, 1, 19, 13, r);
+    specialPlusTerm(p, 0, 437306, 1, 18, 13, r);
+    specialPlusTerm(p, 0, 432423, 1, 17, 13, r);
+    specialPlusTerm(p, 0, 420422, 1, 16, 13, r);
+    specialPlusTerm(p, 0, 401575, 1, 15, 13, r);
+    specialPlusTerm(p, 0, 376559, 1, 14, 13, r);
+    specialPlusTerm(p, 0, 346582, 1, 13, 13, r);
+    specialPlusTerm(p, 0, 312861, 1, 12, 13, r);
+    specialPlusTerm(p, 0, 276645, 1, 11, 13, r);
+    specialPlusTerm(p, 0, 239149, 1, 10, 13, r);
+    specialPlusTerm(p, 0, 201578, 1, 9, 13, r);
+    specialPlusTerm(p, 0, 165048, 1, 8, 13, r);
+    specialPlusTerm(p, 0, 130611, 1, 7, 13, r);
+    specialPlusTerm(p, 0, 99177, 1, 6, 13, r);
+    specialPlusTerm(p, 0, 71526, 1, 5, 13, r);
+    specialPlusTerm(p, 0, 48230, 1, 4, 13, r);
+    specialPlusTerm(p, 0, 29666, 1, 3, 13, r);
+    specialPlusTerm(p, 0, 15925, 1, 2, 13, r);
+    specialPlusTerm(p, 0, 6825, 1, 1, 13, r);
+    specialPlusTerm(p, 0, 1820, 1, 0, 13, r);
+    specialPlusTerm(p, 0, 1, -1, 65, 12, r);
+    specialPlusTerm(p, 0, 6, -1, 64, 12, r);
+    specialPlusTerm(p, 0, 22, -1, 63, 12, r);
+    specialPlusTerm(p, 0, 63, -1, 62, 12, r);
+    specialPlusTerm(p, 0, 155, -1, 61, 12, r);
+    specialPlusTerm(p, 0, 343, -1, 60, 12, r);
+    specialPlusTerm(p, 0, 701, -1, 59, 12, r);
+    specialPlusTerm(p, 0, 1345, -1, 58, 12, r);
+    specialPlusTerm(p, 0, 2451, -1, 57, 12, r);
+    specialPlusTerm(p, 0, 4278, -1, 56, 12, r);
+    specialPlusTerm(p, 0, 7198, -1, 55, 12, r);
+    specialPlusTerm(p, 0, 11733, -1, 54, 12, r);
+    specialPlusTerm(p, 0, 18589, -1, 53, 12, r);
+    specialPlusTerm(p, 0, 28699, -1, 52, 12, r);
+    specialPlusTerm(p, 0, 43265, -1, 51, 12, r);
+    specialPlusTerm(p, 0, 63799, -1, 50, 12, r);
+    specialPlusTerm(p, 0, 92152, -1, 49, 12, r);
+    specialPlusTerm(p, 0, 130543, -1, 48, 12, r);
+    specialPlusTerm(p, 0, 181565, -1, 47, 12, r);
+    specialPlusTerm(p, 0, 248179, -1, 46, 12, r);
+    specialPlusTerm(p, 0, 333673, -1, 45, 12, r);
+    specialPlusTerm(p, 0, 441596, -1, 44, 12, r);
+    specialPlusTerm(p, 0, 575643, -1, 43, 12, r);
+    specialPlusTerm(p, 0, 739501, -1, 42, 12, r);
+    specialPlusTerm(p, 0, 936619, -1, 41, 12, r);
+    specialPlusTerm(p, 1, 170014, -1, 40, 12, r);
+    specialPlusTerm(p, 1, 441997, -1, 39, 12, r);
+    specialPlusTerm(p, 1, 753919, -1, 38, 12, r);
+    specialPlusTerm(p, 2, 105911, -1, 37, 12, r);
+    specialPlusTerm(p, 2, 496652, -1, 36, 12, r);
+    specialPlusTerm(p, 2, 923127, -1, 35, 12, r);
+    specialPlusTerm(p, 3, 380499, -1, 34, 12, r);
+    specialPlusTerm(p, 3, 861979, -1, 33, 12, r);
+    specialPlusTerm(p, 4, 358819, -1, 32, 12, r);
+    specialPlusTerm(p, 4, 860402, -1, 31, 12, r);
+    specialPlusTerm(p, 5, 354477, -1, 30, 12, r);
+    specialPlusTerm(p, 5, 827501, -1, 29, 12, r);
+    specialPlusTerm(p, 6, 265239, -1, 28, 12, r);
+    specialPlusTerm(p, 6, 653507, -1, 27, 12, r);
+    specialPlusTerm(p, 6, 978743, -1, 26, 12, r);
+    specialPlusTerm(p, 7, 228746, -1, 25, 12, r);
+    specialPlusTerm(p, 7, 393190, -1, 24, 12, r);
+    specialPlusTerm(p, 7, 464241, -1, 23, 12, r);
+    specialPlusTerm(p, 7, 436963, -1, 22, 12, r);
+    specialPlusTerm(p, 7, 309763, -1, 21, 12, r);
+    specialPlusTerm(p, 7, 84549, -1, 20, 12, r);
+    specialPlusTerm(p, 6, 766941, -1, 19, 12, r);
+    specialPlusTerm(p, 6, 366119, -1, 18, 12, r);
+    specialPlusTerm(p, 5, 894636, -1, 17, 12, r);
+    specialPlusTerm(p, 5, 367870, -1, 16, 12, r);
+    specialPlusTerm(p, 4, 803365, -1, 15, 12, r);
+    specialPlusTerm(p, 4, 219710, -1, 14, 12, r);
+    specialPlusTerm(p, 3, 635296, -1, 13, 12, r);
+    specialPlusTerm(p, 3, 66522, -1, 12, 12, r);
+    specialPlusTerm(p, 2, 527597, -1, 11, 12, r);
+    specialPlusTerm(p, 2, 30222, -1, 10, 12, r);
+    specialPlusTerm(p, 1, 583491, -1, 9, 12, r);
+    specialPlusTerm(p, 1, 193660, -1, 8, 12, r);
+    specialPlusTerm(p, 0, 864214, -1, 7, 12, r);
+    specialPlusTerm(p, 0, 595790, -1, 6, 12, r);
+    specialPlusTerm(p, 0, 386386, -1, 5, 12, r);
+    specialPlusTerm(p, 0, 231504, -1, 4, 12, r);
+    specialPlusTerm(p, 0, 124579, -1, 3, 12, r);
+    specialPlusTerm(p, 0, 57330, -1, 2, 12, r);
+    specialPlusTerm(p, 0, 20475, -1, 1, 12, r);
+    specialPlusTerm(p, 0, 4368, -1, 0, 12, r);
+    specialPlusTerm(p, 0, 1, 1, 75, 11, r);
+    specialPlusTerm(p, 0, 7, 1, 74, 11, r);
+    specialPlusTerm(p, 0, 29, 1, 73, 11, r);
+    specialPlusTerm(p, 0, 92, 1, 72, 11, r);
+    specialPlusTerm(p, 0, 247, 1, 71, 11, r);
+    specialPlusTerm(p, 0, 590, 1, 70, 11, r);
+    specialPlusTerm(p, 0, 1292, 1, 69, 11, r);
+    specialPlusTerm(p, 0, 2643, 1, 68, 11, r);
+    specialPlusTerm(p, 0, 5116, 1, 67, 11, r);
+    specialPlusTerm(p, 0, 9457, 1, 66, 11, r);
+    specialPlusTerm(p, 0, 16810, 1, 65, 11, r);
+    specialPlusTerm(p, 0, 28874, 1, 64, 11, r);
+    specialPlusTerm(p, 0, 48105, 1, 63, 11, r);
+    specialPlusTerm(p, 0, 77963, 1, 62, 11, r);
+    specialPlusTerm(p, 0, 123209, 1, 61, 11, r);
+    specialPlusTerm(p, 0, 190245, 1, 60, 11, r);
+    specialPlusTerm(p, 0, 287494, 1, 59, 11, r);
+    specialPlusTerm(p, 0, 425804, 1, 58, 11, r);
+    specialPlusTerm(p, 0, 618866, 1, 57, 11, r);
+    specialPlusTerm(p, 0, 883609, 1, 56, 11, r);
+    specialPlusTerm(p, 1, 240541, 1, 55, 11, r);
+    specialPlusTerm(p, 1, 713978, 1, 54, 11, r);
+    specialPlusTerm(p, 2, 332107, 1, 53, 11, r);
+    specialPlusTerm(p, 3, 126867, 1, 52, 11, r);
+    specialPlusTerm(p, 4, 133571, 1, 51, 11, r);
+    specialPlusTerm(p, 5, 390227, 1, 50, 11, r);
+    specialPlusTerm(p, 6, 936520, 1, 49, 11, r);
+    specialPlusTerm(p, 8, 812464, 1, 48, 11, r);
+    specialPlusTerm(p, 11, 56669, 1, 47, 11, r);
+    specialPlusTerm(p, 13, 704280, 1, 46, 11, r);
+    specialPlusTerm(p, 16, 784594, 1, 45, 11, r);
+    specialPlusTerm(p, 20, 318470, 1, 44, 11, r);
+    specialPlusTerm(p, 24, 315607, 1, 43, 11, r);
+    specialPlusTerm(p, 28, 771888, 1, 42, 11, r);
+    specialPlusTerm(p, 33, 666946, 1, 41, 11, r);
+    specialPlusTerm(p, 38, 962309, 1, 40, 11, r);
+    specialPlusTerm(p, 44, 600023, 1, 39, 11, r);
+    specialPlusTerm(p, 50, 502149, 1, 38, 11, r);
+    specialPlusTerm(p, 56, 571139, 1, 37, 11, r);
+    specialPlusTerm(p, 62, 691244, 1, 36, 11, r);
+    specialPlusTerm(p, 68, 730935, 1, 35, 11, r);
+    specialPlusTerm(p, 74, 546533, 1, 34, 11, r);
+    specialPlusTerm(p, 79, 986722, 1, 33, 11, r);
+    specialPlusTerm(p, 84, 898120, 1, 32, 11, r);
+    specialPlusTerm(p, 89, 131550, 1, 31, 11, r);
+    specialPlusTerm(p, 92, 548805, 1, 30, 11, r);
+    specialPlusTerm(p, 95, 29441, 1, 29, 11, r);
+    specialPlusTerm(p, 96, 477351, 1, 28, 11, r);
+    specialPlusTerm(p, 96, 826185, 1, 27, 11, r);
+    specialPlusTerm(p, 96, 43174, 1, 26, 11, r);
+    specialPlusTerm(p, 94, 131647, 1, 25, 11, r);
+    specialPlusTerm(p, 91, 131660, 1, 24, 11, r);
+    specialPlusTerm(p, 87, 119171, 1, 23, 11, r);
+    specialPlusTerm(p, 82, 203392, 1, 22, 11, r);
+    specialPlusTerm(p, 76, 522667, 1, 21, 11, r);
+    specialPlusTerm(p, 70, 238707, 1, 20, 11, r);
+    specialPlusTerm(p, 63, 529796, 1, 19, 11, r);
+    specialPlusTerm(p, 56, 582713, 1, 18, 11, r);
+    specialPlusTerm(p, 49, 584249, 1, 17, 11, r);
+    specialPlusTerm(p, 42, 712395, 1, 16, 11, r);
+    specialPlusTerm(p, 36, 128059, 1, 15, 11, r);
+    specialPlusTerm(p, 29, 967652, 1, 14, 11, r);
+    specialPlusTerm(p, 24, 337808, 1, 13, 11, r);
+    specialPlusTerm(p, 19, 312634, 1, 12, 11, r);
+    specialPlusTerm(p, 14, 935096, 1, 11, 11, r);
+    specialPlusTerm(p, 11, 218988, 1, 10, 11, r);
+    specialPlusTerm(p, 8, 151858, 1, 9, 11, r);
+    specialPlusTerm(p, 5, 698407, 1, 8, 11, r);
+    specialPlusTerm(p, 3, 804801, 1, 7, 11, r);
+    specialPlusTerm(p, 2, 403115, 1, 6, 11, r);
+    specialPlusTerm(p, 1, 416415, 1, 5, 11, r);
+    specialPlusTerm(p, 0, 763763, 1, 4, 11, r);
+    specialPlusTerm(p, 0, 365365, 1, 3, 11, r);
+    specialPlusTerm(p, 0, 147147, 1, 2, 11, r);
+    specialPlusTerm(p, 0, 45045, 1, 1, 11, r);
+    specialPlusTerm(p, 0, 8008, 1, 0, 11, r);
+    specialPlusTerm(p, 0, 1, -1, 84, 10, r);
+    specialPlusTerm(p, 0, 8, -1, 83, 10, r);
+    specialPlusTerm(p, 0, 37, -1, 82, 10, r);
+    specialPlusTerm(p, 0, 129, -1, 81, 10, r);
+    specialPlusTerm(p, 0, 376, -1, 80, 10, r);
+    specialPlusTerm(p, 0, 966, -1, 79, 10, r);
+    specialPlusTerm(p, 0, 2258, -1, 78, 10, r);
+    specialPlusTerm(p, 0, 4902, -1, 77, 10, r);
+    specialPlusTerm(p, 0, 10025, -1, 76, 10, r);
+    specialPlusTerm(p, 0, 19511, -1, 75, 10, r);
+    specialPlusTerm(p, 0, 36402, -1, 74, 10, r);
+    specialPlusTerm(p, 0, 65457, -1, 73, 10, r);
+    specialPlusTerm(p, 0, 113910, -1, 72, 10, r);
+    specialPlusTerm(p, 0, 192472, -1, 71, 10, r);
+    specialPlusTerm(p, 0, 316620, -1, 70, 10, r);
+    specialPlusTerm(p, 0, 508215, -1, 69, 10, r);
+    specialPlusTerm(p, 0, 797473, -1, 68, 10, r);
+    specialPlusTerm(p, 1, 225306, -1, 67, 10, r);
+    specialPlusTerm(p, 1, 846017, -1, 66, 10, r);
+    specialPlusTerm(p, 2, 730299, -1, 65, 10, r);
+    specialPlusTerm(p, 3, 968427, -1, 64, 10, r);
+    specialPlusTerm(p, 5, 673536, -1, 63, 10, r);
+    specialPlusTerm(p, 7, 984777, -1, 62, 10, r);
+    specialPlusTerm(p, 11, 70116, -1, 61, 10, r);
+    specialPlusTerm(p, 15, 128465, -1, 60, 10, r);
+    specialPlusTerm(p, 20, 390819, -1, 59, 10, r);
+    specialPlusTerm(p, 27, 120017, -1, 58, 10, r);
+    specialPlusTerm(p, 35, 608761, -1, 57, 10, r);
+    specialPlusTerm(p, 46, 175479, -1, 56, 10, r);
+    specialPlusTerm(p, 59, 157726, -1, 55, 10, r);
+    specialPlusTerm(p, 74, 902862, -1, 54, 10, r);
+    specialPlusTerm(p, 93, 755945, -1, 53, 10, r);
+    specialPlusTerm(p, 116, 44932, -1, 52, 10, r);
+    specialPlusTerm(p, 142, 63382, -1, 51, 10, r);
+    specialPlusTerm(p, 172, 51120, -1, 50, 10, r);
+    specialPlusTerm(p, 206, 173563, -1, 49, 10, r);
+    specialPlusTerm(p, 244, 500607, -1, 48, 10, r);
+    specialPlusTerm(p, 286, 986083, -1, 47, 10, r);
+    specialPlusTerm(p, 333, 449096, -1, 46, 10, r);
+    specialPlusTerm(p, 383, 558571, -1, 45, 10, r);
+    specialPlusTerm(p, 436, 822461, -1, 44, 10, r);
+    specialPlusTerm(p, 492, 582939, -1, 43, 10, r);
+    specialPlusTerm(p, 550, 18832, -1, 42, 10, r);
+    specialPlusTerm(p, 608, 156141, -1, 41, 10, r);
+    specialPlusTerm(p, 665, 887167, -1, 40, 10, r);
+    specialPlusTerm(p, 721, 997807, -1, 39, 10, r);
+    specialPlusTerm(p, 775, 202852, -1, 38, 10, r);
+    specialPlusTerm(p, 824, 187996, -1, 37, 10, r);
+    specialPlusTerm(p, 867, 657138, -1, 36, 10, r);
+    specialPlusTerm(p, 904, 382945, -1, 35, 10, r);
+    specialPlusTerm(p, 933, 258541, -1, 34, 10, r);
+    specialPlusTerm(p, 953, 347368, -1, 33, 10, r);
+    specialPlusTerm(p, 963, 928871, -1, 32, 10, r);
+    specialPlusTerm(p, 964, 536834, -1, 31, 10, r);
+    specialPlusTerm(p, 954, 987850, -1, 30, 10, r);
+    specialPlusTerm(p, 935, 397536, -1, 29, 10, r);
+    specialPlusTerm(p, 906, 183073, -1, 28, 10, r);
+    specialPlusTerm(p, 868, 50862, -1, 27, 10, r);
+    specialPlusTerm(p, 821, 970338, -1, 26, 10, r);
+    specialPlusTerm(p, 769, 135827, -1, 25, 10, r);
+    specialPlusTerm(p, 710, 918057, -1, 24, 10, r);
+    specialPlusTerm(p, 648, 808233, -1, 23, 10, r);
+    specialPlusTerm(p, 584, 357073, -1, 22, 10, r);
+    specialPlusTerm(p, 519, 112032, -1, 21, 10, r);
+    specialPlusTerm(p, 454, 555728, -1, 20, 10, r);
+    specialPlusTerm(p, 392, 49009, -1, 19, 10, r);
+    specialPlusTerm(p, 332, 781273, -1, 18, 10, r);
+    specialPlusTerm(p, 277, 731388, -1, 17, 10, r);
+    specialPlusTerm(p, 227, 641117, -1, 16, 10, r);
+    specialPlusTerm(p, 183, 2853, -1, 15, 10, r);
+    specialPlusTerm(p, 144, 62127, -1, 14, 10, r);
+    specialPlusTerm(p, 110, 834647, -1, 13, 10, r);
+    specialPlusTerm(p, 83, 135184, -1, 12, 10, r);
+    specialPlusTerm(p, 60, 614741, -1, 11, 10, r);
+    specialPlusTerm(p, 42, 799119, -1, 10, 10, r);
+    specialPlusTerm(p, 29, 127956, -1, 9, 10, r);
+    specialPlusTerm(p, 18, 992545, -1, 8, 10, r);
+    specialPlusTerm(p, 11, 771474, -1, 7, 10, r);
+    specialPlusTerm(p, 6, 862141, -1, 6, 10, r);
+    specialPlusTerm(p, 3, 707704, -1, 5, 10, r);
+    specialPlusTerm(p, 1, 817816, -1, 4, 10, r);
+    specialPlusTerm(p, 0, 782782, -1, 3, 10, r);
+    specialPlusTerm(p, 0, 280280, -1, 2, 10, r);
+    specialPlusTerm(p, 0, 75075, -1, 1, 10, r);
+    specialPlusTerm(p, 0, 11440, -1, 0, 10, r);
+    specialPlusTerm(p, 0, 1, 1, 92, 9, r);
+    specialPlusTerm(p, 0, 9, 1, 91, 9, r);
+    specialPlusTerm(p, 0, 46, 1, 90, 9, r);
+    specialPlusTerm(p, 0, 175, 1, 89, 9, r);
+    specialPlusTerm(p, 0, 551, 1, 88, 9, r);
+    specialPlusTerm(p, 0, 1517, 1, 87, 9, r);
+    specialPlusTerm(p, 0, 3775, 1, 86, 9, r);
+    specialPlusTerm(p, 0, 8677, 1, 85, 9, r);
+    specialPlusTerm(p, 0, 18703, 1, 84, 9, r);
+    specialPlusTerm(p, 0, 38212, 1, 83, 9, r);
+    specialPlusTerm(p, 0, 74581, 1, 82, 9, r);
+    specialPlusTerm(p, 0, 139877, 1, 81, 9, r);
+    specialPlusTerm(p, 0, 253243, 1, 80, 9, r);
+    specialPlusTerm(p, 0, 444211, 1, 79, 9, r);
+    specialPlusTerm(p, 0, 757189, 1, 78, 9, r);
+    specialPlusTerm(p, 1, 257386, 1, 77, 9, r);
+    specialPlusTerm(p, 2, 38445, 1, 76, 9, r);
+    specialPlusTerm(p, 3, 232029, 1, 75, 9, r);
+    specialPlusTerm(p, 5, 19547, 1, 74, 9, r);
+    specialPlusTerm(p, 7, 646140, 1, 73, 9, r);
+    specialPlusTerm(p, 11, 436924, 1, 72, 9, r);
+    specialPlusTerm(p, 16, 815312, 1, 71, 9, r);
+    specialPlusTerm(p, 24, 323016, 1, 70, 9, r);
+    specialPlusTerm(p, 34, 641066, 1, 69, 9, r);
+    specialPlusTerm(p, 48, 610873, 1, 68, 9, r);
+    specialPlusTerm(p, 67, 254061, 1, 67, 9, r);
+    specialPlusTerm(p, 91, 789450, 1, 66, 9, r);
+    specialPlusTerm(p, 123, 645277, 1, 65, 9, r);
+    specialPlusTerm(p, 164, 464508, 1, 64, 9, r);
+    specialPlusTerm(p, 216, 101017, 1, 63, 9, r);
+    specialPlusTerm(p, 280, 604281, 1, 62, 9, r);
+    specialPlusTerm(p, 360, 190441, 1, 61, 9, r);
+    specialPlusTerm(p, 457, 197865, 1, 60, 9, r);
+    specialPlusTerm(p, 574, 25922, 1, 59, 9, r);
+    specialPlusTerm(p, 713, 56365, 1, 58, 9, r);
+    specialPlusTerm(p, 876, 557703, 1, 57, 9, r);
+    specialPlusTerm(p, 1066, 573992, 1, 56, 9, r);
+    specialPlusTerm(p, 1284, 800887, 1, 55, 9, r);
+    specialPlusTerm(p, 1532, 453056, 1, 54, 9, r);
+    specialPlusTerm(p, 1810, 128450, 1, 53, 9, r);
+    specialPlusTerm(p, 2117, 675954, 1, 52, 9, r);
+    specialPlusTerm(p, 2454, 73820, 1, 51, 9, r);
+    specialPlusTerm(p, 2817, 326941, 1, 50, 9, r);
+    specialPlusTerm(p, 3204, 391243, 1, 49, 9, r);
+    specialPlusTerm(p, 3611, 133043, 1, 48, 9, r);
+    specialPlusTerm(p, 4032, 330356, 1, 47, 9, r);
+    specialPlusTerm(p, 4461, 721846, 1, 46, 9, r);
+    specialPlusTerm(p, 4892, 107024, 1, 45, 9, r);
+    specialPlusTerm(p, 5315, 498836, 1, 44, 9, r);
+    specialPlusTerm(p, 5723, 326840, 1, 43, 9, r);
+    specialPlusTerm(p, 6106, 686025, 1, 42, 9, r);
+    specialPlusTerm(p, 6456, 623000, 1, 41, 9, r);
+    specialPlusTerm(p, 6764, 448368, 1, 40, 9, r);
+    specialPlusTerm(p, 7022, 61523, 1, 39, 9, r);
+    specialPlusTerm(p, 7222, 273135, 1, 38, 9, r);
+    specialPlusTerm(p, 7359, 108966, 1, 37, 9, r);
+    specialPlusTerm(p, 7428, 79054, 1, 36, 9, r);
+    specialPlusTerm(p, 7426, 396980, 1, 35, 9, r);
+    specialPlusTerm(p, 7353, 135921, 1, 34, 9, r);
+    specialPlusTerm(p, 7209, 310506, 1, 33, 9, r);
+    specialPlusTerm(p, 6997, 877688, 1, 32, 9, r);
+    specialPlusTerm(p, 6723, 653256, 1, 31, 9, r);
+    specialPlusTerm(p, 6393, 146079, 1, 30, 9, r);
+    specialPlusTerm(p, 6014, 316858, 1, 29, 9, r);
+    specialPlusTerm(p, 5596, 273275, 1, 28, 9, r);
+    specialPlusTerm(p, 5148, 917160, 1, 27, 9, r);
+    specialPlusTerm(p, 4682, 563401, 1, 26, 9, r);
+    specialPlusTerm(p, 4207, 550601, 1, 25, 9, r);
+    specialPlusTerm(p, 3733, 862769, 1, 24, 9, r);
+    specialPlusTerm(p, 3270, 780702, 1, 23, 9, r);
+    specialPlusTerm(p, 2826, 579105, 1, 22, 9, r);
+    specialPlusTerm(p, 2408, 283186, 1, 21, 9, r);
+    specialPlusTerm(p, 2021, 494926, 1, 20, 9, r);
+    specialPlusTerm(p, 1670, 295297, 1, 19, 9, r);
+    specialPlusTerm(p, 1357, 224099, 1, 18, 9, r);
+    specialPlusTerm(p, 1083, 335088, 1, 17, 9, r);
+    specialPlusTerm(p, 848, 318658, 1, 16, 9, r);
+    specialPlusTerm(p, 650, 680536, 1, 15, 9, r);
+    specialPlusTerm(p, 487, 961232, 1, 14, 9, r);
+    specialPlusTerm(p, 356, 978589, 1, 13, 9, r);
+    specialPlusTerm(p, 254, 74425, 1, 12, 9, r);
+    specialPlusTerm(p, 175, 348338, 1, 11, 9, r);
+    specialPlusTerm(p, 116, 865243, 1, 10, 9, r);
+    specialPlusTerm(p, 74, 831757, 1, 9, 9, r);
+    specialPlusTerm(p, 45, 737406, 1, 8, 9, r);
+    specialPlusTerm(p, 26, 458575, 1, 7, 9, r);
+    specialPlusTerm(p, 14, 324310, 1, 6, 9, r);
+    specialPlusTerm(p, 7, 145853, 1, 5, 9, r);
+    specialPlusTerm(p, 3, 212352, 1, 4, 9, r);
+    specialPlusTerm(p, 1, 257828, 1, 3, 9, r);
+    specialPlusTerm(p, 0, 405405, 1, 2, 9, r);
+    specialPlusTerm(p, 0, 96525, 1, 1, 9, r);
+    specialPlusTerm(p, 0, 12870, 1, 0, 9, r);
+    specialPlusTerm(p, 0, 1, -1, 99, 8, r);
+    specialPlusTerm(p, 0, 10, -1, 98, 8, r);
+    specialPlusTerm(p, 0, 56, -1, 97, 8, r);
+    specialPlusTerm(p, 0, 231, -1, 96, 8, r);
+    specialPlusTerm(p, 0, 782, -1, 95, 8, r);
+    specialPlusTerm(p, 0, 2299, -1, 94, 8, r);
+    specialPlusTerm(p, 0, 6074, -1, 93, 8, r);
+    specialPlusTerm(p, 0, 14751, -1, 92, 8, r);
+    specialPlusTerm(p, 0, 33445, -1, 91, 8, r);
+    specialPlusTerm(p, 0, 71586, -1, 90, 8, r);
+    specialPlusTerm(p, 0, 145843, -1, 89, 8, r);
+    specialPlusTerm(p, 0, 284605, -1, 88, 8, r);
+    specialPlusTerm(p, 0, 534639, -1, 87, 8, r);
+    specialPlusTerm(p, 0, 970707, -1, 86, 8, r);
+    specialPlusTerm(p, 1, 709091, -1, 85, 8, r);
+    specialPlusTerm(p, 2, 926134, -1, 84, 8, r);
+    specialPlusTerm(p, 4, 883022, -1, 83, 8, r);
+    specialPlusTerm(p, 7, 958118, -1, 82, 8, r);
+    specialPlusTerm(p, 12, 688161, -1, 81, 8, r);
+    specialPlusTerm(p, 19, 819543, -1, 80, 8, r);
+    specialPlusTerm(p, 30, 370620, -1, 79, 8, r);
+    specialPlusTerm(p, 45, 705588, -1, 78, 8, r);
+    specialPlusTerm(p, 67, 619803, -1, 77, 8, r);
+    specialPlusTerm(p, 98, 435565, -1, 76, 8, r);
+    specialPlusTerm(p, 141, 106293, -1, 75, 8, r);
+    specialPlusTerm(p, 199, 325748, -1, 74, 8, r);
+    specialPlusTerm(p, 277, 637550, -1, 73, 8, r);
+    specialPlusTerm(p, 381, 538692, -1, 72, 8, r);
+    specialPlusTerm(p, 517, 569184, -1, 71, 8, r);
+    specialPlusTerm(p, 693, 378528, -1, 70, 8, r);
+    specialPlusTerm(p, 917, 758545, -1, 69, 8, r);
+    specialPlusTerm(p, 1200, 631327, -1, 68, 8, r);
+    specialPlusTerm(p, 1552, 980935, -1, 67, 8, r);
+    specialPlusTerm(p, 1986, 718008, -1, 66, 8, r);
+    specialPlusTerm(p, 2514, 467898, -1, 65, 8, r);
+    specialPlusTerm(p, 3149, 275373, -1, 64, 8, r);
+    specialPlusTerm(p, 3904, 222333, -1, 63, 8, r);
+    specialPlusTerm(p, 4791, 959202, -1, 62, 8, r);
+    specialPlusTerm(p, 5824, 155954, -1, 61, 8, r);
+    specialPlusTerm(p, 7010, 884530, -1, 60, 8, r);
+    specialPlusTerm(p, 8359, 950639, -1, 59, 8, r);
+    specialPlusTerm(p, 9876, 199091, -1, 58, 8, r);
+    specialPlusTerm(p, 11560, 822647, -1, 57, 8, r);
+    specialPlusTerm(p, 13410, 709233, -1, 56, 8, r);
+    specialPlusTerm(p, 15417, 866033, -1, 55, 8, r);
+    specialPlusTerm(p, 17568, 960466, -1, 54, 8, r);
+    specialPlusTerm(p, 19845, 17463, -1, 53, 8, r);
+    specialPlusTerm(p, 22221, 309147, -1, 52, 8, r);
+    specialPlusTerm(p, 24667, 467342, -1, 51, 8, r);
+    specialPlusTerm(p, 27147, 841107, -1, 50, 8, r);
+    specialPlusTerm(p, 29622, 110916, -1, 49, 8, r);
+    specialPlusTerm(p, 32046, 158421, -1, 48, 8, r);
+    specialPlusTerm(p, 34373, 176970, -1, 47, 8, r);
+    specialPlusTerm(p, 36554, 993654, -1, 46, 8, r);
+    specialPlusTerm(p, 38543, 559373, -1, 45, 8, r);
+    specialPlusTerm(p, 40292, 550458, -1, 44, 8, r);
+    specialPlusTerm(p, 41759, 14716, -1, 43, 8, r);
+    specialPlusTerm(p, 42904, 987186, -1, 42, 8, r);
+    specialPlusTerm(p, 43698, 997388, -1, 41, 8, r);
+    specialPlusTerm(p, 44117, 391022, -1, 40, 8, r);
+    specialPlusTerm(p, 44145, 394986, -1, 39, 8, r);
+    specialPlusTerm(p, 43777, 865188, -1, 38, 8, r);
+    specialPlusTerm(p, 43019, 670206, -1, 37, 8, r);
+    specialPlusTerm(p, 41885, 681598, -1, 36, 8, r);
+    specialPlusTerm(p, 40400, 361216, -1, 35, 8, r);
+    specialPlusTerm(p, 38596, 956954, -1, 34, 8, r);
+    specialPlusTerm(p, 36516, 339240, -1, 33, 8, r);
+    specialPlusTerm(p, 34205, 530818, -1, 32, 8, r);
+    specialPlusTerm(p, 31715, 999202, -1, 31, 8, r);
+    specialPlusTerm(p, 29101, 795368, -1, 30, 8, r);
+    specialPlusTerm(p, 26417, 630514, -1, 29, 8, r);
+    specialPlusTerm(p, 23716, 985664, -1, 28, 8, r);
+    specialPlusTerm(p, 21050, 345182, -1, 27, 8, r);
+    specialPlusTerm(p, 18463, 636290, -1, 26, 8, r);
+    specialPlusTerm(p, 15996, 940992, -1, 25, 8, r);
+    specialPlusTerm(p, 13683, 529134, -1, 24, 8, r);
+    specialPlusTerm(p, 11549, 242308, -1, 23, 8, r);
+    specialPlusTerm(p, 9612, 238032, -1, 22, 8, r);
+    specialPlusTerm(p, 7883, 84208, -1, 21, 8, r);
+    specialPlusTerm(p, 6365, 175366, -1, 20, 8, r);
+    specialPlusTerm(p, 5055, 425826, -1, 19, 8, r);
+    specialPlusTerm(p, 3945, 181834, -1, 18, 8, r);
+    specialPlusTerm(p, 3021, 285630, -1, 17, 8, r);
+    specialPlusTerm(p, 2267, 219328, -1, 16, 8, r);
+    specialPlusTerm(p, 1664, 257320, -1, 15, 8, r);
+    specialPlusTerm(p, 1192, 561524, -1, 14, 8, r);
+    specialPlusTerm(p, 832, 164102, -1, 13, 8, r);
+    specialPlusTerm(p, 563, 796684, -1, 12, 8, r);
+    specialPlusTerm(p, 369, 542514, -1, 11, 8, r);
+    specialPlusTerm(p, 233, 304720, -1, 10, 8, r);
+    specialPlusTerm(p, 141, 98386, -1, 9, 8, r);
+    specialPlusTerm(p, 81, 180528, -1, 8, 8, r);
+    specialPlusTerm(p, 44, 38137, -1, 7, 8, r);
+    specialPlusTerm(p, 22, 259094, -1, 6, 8, r);
+    specialPlusTerm(p, 10, 314447, -1, 5, 8, r);
+    specialPlusTerm(p, 4, 281420, -1, 4, 8, r);
+    specialPlusTerm(p, 1, 537107, -1, 3, 8, r);
+    specialPlusTerm(p, 0, 450450, -1, 2, 8, r);
+    specialPlusTerm(p, 0, 96525, -1, 1, 8, r);
+    specialPlusTerm(p, 0, 11440, -1, 0, 8, r);
+    specialPlusTerm(p, 0, 1, 1, 105, 7, r);
+    specialPlusTerm(p, 0, 11, 1, 104, 7, r);
+    specialPlusTerm(p, 0, 67, 1, 103, 7, r);
+    specialPlusTerm(p, 0, 298, 1, 102, 7, r);
+    specialPlusTerm(p, 0, 1080, 1, 101, 7, r);
+    specialPlusTerm(p, 0, 3379, 1, 100, 7, r);
+    specialPlusTerm(p, 0, 9453, 1, 99, 7, r);
+    specialPlusTerm(p, 0, 24196, 1, 98, 7, r);
+    specialPlusTerm(p, 0, 57569, 1, 97, 7, r);
+    specialPlusTerm(p, 0, 128787, 1, 96, 7, r);
+    specialPlusTerm(p, 0, 273231, 1, 95, 7, r);
+    specialPlusTerm(p, 0, 553438, 1, 94, 7, r);
+    specialPlusTerm(p, 1, 75997, 1, 93, 7, r);
+    specialPlusTerm(p, 2, 16735, 1, 92, 7, r);
+    specialPlusTerm(p, 3, 657192, 1, 91, 7, r);
+    specialPlusTerm(p, 6, 436037, 1, 90, 7, r);
+    specialPlusTerm(p, 11, 19717, 1, 89, 7, r);
+    specialPlusTerm(p, 18, 397189, 1, 88, 7, r);
+    specialPlusTerm(p, 30, 3973, 1, 87, 7, r);
+    specialPlusTerm(p, 47, 880870, 1, 86, 7, r);
+    specialPlusTerm(p, 74, 872383, 1, 85, 7, r);
+    specialPlusTerm(p, 114, 869036, 1, 84, 7, r);
+    specialPlusTerm(p, 173, 96283, 1, 83, 7, r);
+    specialPlusTerm(p, 256, 450472, 1, 82, 7, r);
+    specialPlusTerm(p, 373, 879259, 1, 81, 7, r);
+    specialPlusTerm(p, 536, 799939, 1, 80, 7, r);
+    specialPlusTerm(p, 759, 544391, 1, 79, 7, r);
+    specialPlusTerm(p, 1059, 813880, 1, 78, 7, r);
+    specialPlusTerm(p, 1459, 121011, 1, 77, 7, r);
+    specialPlusTerm(p, 1983, 190069, 1, 76, 7, r);
+    specialPlusTerm(p, 2662, 281192, 1, 75, 7, r);
+    specialPlusTerm(p, 3531, 398853, 1, 74, 7, r);
+    specialPlusTerm(p, 4630, 341477, 1, 73, 7, r);
+    specialPlusTerm(p, 6003, 547268, 1, 72, 7, r);
+    specialPlusTerm(p, 7699, 692101, 1, 71, 7, r);
+    specialPlusTerm(p, 9770, 999253, 1, 70, 7, r);
+    specialPlusTerm(p, 12272, 228155, 1, 69, 7, r);
+    specialPlusTerm(p, 15259, 320516, 1, 68, 7, r);
+    specialPlusTerm(p, 18787, 697047, 1, 67, 7, r);
+    specialPlusTerm(p, 22910, 216326, 1, 66, 7, r);
+    specialPlusTerm(p, 27674, 828551, 1, 65, 7, r);
+    specialPlusTerm(p, 33121, 980096, 1, 64, 7, r);
+    specialPlusTerm(p, 39281, 848637, 1, 63, 7, r);
+    specialPlusTerm(p, 46171, 511745, 1, 62, 7, r);
+    specialPlusTerm(p, 53792, 172793, 1, 61, 7, r);
+    specialPlusTerm(p, 62126, 584715, 1, 60, 7, r);
+    specialPlusTerm(p, 71136, 823074, 1, 59, 7, r);
+    specialPlusTerm(p, 80762, 563409, 1, 58, 7, r);
+    specialPlusTerm(p, 90920, 12755, 1, 57, 7, r);
+    specialPlusTerm(p, 101501, 630586, 1, 56, 7, r);
+    specialPlusTerm(p, 112376, 750037, 1, 55, 7, r);
+    specialPlusTerm(p, 123393, 176185, 1, 54, 7, r);
+    specialPlusTerm(p, 134379, 795971, 1, 53, 7, r);
+    specialPlusTerm(p, 145150, 185558, 1, 52, 7, r);
+    specialPlusTerm(p, 155507, 148257, 1, 51, 7, r);
+    specialPlusTerm(p, 165248, 62169, 1, 50, 7, r);
+    specialPlusTerm(p, 174170, 864688, 1, 49, 7, r);
+    specialPlusTerm(p, 182080, 454274, 1, 48, 7, r);
+    specialPlusTerm(p, 188795, 252141, 1, 47, 7, r);
+    specialPlusTerm(p, 194153, 640367, 1, 46, 7, r);
+    specialPlusTerm(p, 198019, 981033, 1, 45, 7, r);
+    specialPlusTerm(p, 200289, 925212, 1, 44, 7, r);
+    specialPlusTerm(p, 200894, 741748, 1, 43, 7, r);
+    specialPlusTerm(p, 199804, 433264, 1, 42, 7, r);
+    specialPlusTerm(p, 197029, 459520, 1, 41, 7, r);
+    specialPlusTerm(p, 192620, 953188, 1, 40, 7, r);
+    specialPlusTerm(p, 186669, 386562, 1, 39, 7, r);
+    specialPlusTerm(p, 179301, 725204, 1, 38, 7, r);
+    specialPlusTerm(p, 170677, 181240, 1, 37, 7, r);
+    specialPlusTerm(p, 160981, 751274, 1, 36, 7, r);
+    specialPlusTerm(p, 150421, 786460, 1, 35, 7, r);
+    specialPlusTerm(p, 139216, 891710, 1, 34, 7, r);
+    specialPlusTerm(p, 127592, 483930, 1, 33, 7, r);
+    specialPlusTerm(p, 115772, 353582, 1, 32, 7, r);
+    specialPlusTerm(p, 103971, 568098, 1, 31, 7, r);
+    specialPlusTerm(p, 92390, 30732, 1, 30, 7, r);
+    specialPlusTerm(p, 81206, 964790, 1, 29, 7, r);
+    specialPlusTerm(p, 70576, 534794, 1, 28, 7, r);
+    specialPlusTerm(p, 60624, 746714, 1, 27, 7, r);
+    specialPlusTerm(p, 51447, 694586, 1, 26, 7, r);
+    specialPlusTerm(p, 43111, 145244, 1, 25, 7, r);
+    specialPlusTerm(p, 35651, 383472, 1, 24, 7, r);
+    specialPlusTerm(p, 29077, 179220, 1, 23, 7, r);
+    specialPlusTerm(p, 23372, 689230, 1, 22, 7, r);
+    specialPlusTerm(p, 18501, 69995, 1, 21, 7, r);
+    specialPlusTerm(p, 14408, 558395, 1, 20, 7, r);
+    specialPlusTerm(p, 11028, 771237, 1, 19, 7, r);
+    specialPlusTerm(p, 8286, 985223, 1, 18, 7, r);
+    specialPlusTerm(p, 6104, 182964, 1, 17, 7, r);
+    specialPlusTerm(p, 4400, 686554, 1, 16, 7, r);
+    specialPlusTerm(p, 3099, 245270, 1, 15, 7, r);
+    specialPlusTerm(p, 2127, 493720, 1, 14, 7, r);
+    specialPlusTerm(p, 1419, 747120, 1, 13, 7, r);
+    specialPlusTerm(p, 918, 147362, 1, 12, 7, r);
+    specialPlusTerm(p, 573, 212794, 1, 11, 7, r);
+    specialPlusTerm(p, 343, 872738, 1, 10, 7, r);
+    specialPlusTerm(p, 197, 84030, 1, 9, 7, r);
+    specialPlusTerm(p, 107, 132168, 1, 8, 7, r);
+    specialPlusTerm(p, 54, 719808, 1, 7, 7, r);
+    specialPlusTerm(p, 25, 940200, 1, 6, 7, r);
+    specialPlusTerm(p, 11, 223212, 1, 5, 7, r);
+    specialPlusTerm(p, 4, 327323, 1, 4, 7, r);
+    specialPlusTerm(p, 1, 434433, 1, 3, 7, r);
+    specialPlusTerm(p, 0, 385385, 1, 2, 7, r);
+    specialPlusTerm(p, 0, 75075, 1, 1, 7, r);
+    specialPlusTerm(p, 0, 8008, 1, 0, 7, r);
+    specialPlusTerm(p, 0, 1, -1, 110, 6, r);
+    specialPlusTerm(p, 0, 12, -1, 109, 6, r);
+    specialPlusTerm(p, 0, 79, -1, 108, 6, r);
+    specialPlusTerm(p, 0, 377, -1, 107, 6, r);
+    specialPlusTerm(p, 0, 1457, -1, 106, 6, r);
+    specialPlusTerm(p, 0, 4836, -1, 105, 6, r);
+    specialPlusTerm(p, 0, 14282, -1, 104, 6, r);
+    specialPlusTerm(p, 0, 38408, -1, 103, 6, r);
+    specialPlusTerm(p, 0, 95585, -1, 102, 6, r);
+    specialPlusTerm(p, 0, 222755, -1, 101, 6, r);
+    specialPlusTerm(p, 0, 490512, -1, 100, 6, r);
+    specialPlusTerm(p, 1, 27858, -1, 99, 6, r);
+    specialPlusTerm(p, 2, 61348, -1, 98, 6, r);
+    specialPlusTerm(p, 3, 974921, -1, 97, 6, r);
+    specialPlusTerm(p, 7, 398548, -1, 96, 6, r);
+    specialPlusTerm(p, 13, 335851, -1, 95, 6, r);
+    specialPlusTerm(p, 23, 342939, -1, 94, 6, r);
+    specialPlusTerm(p, 39, 772696, -1, 93, 6, r);
+    specialPlusTerm(p, 66, 100395, -1, 92, 6, r);
+    specialPlusTerm(p, 107, 347509, -1, 91, 6, r);
+    specialPlusTerm(p, 170, 620609, -1, 90, 6, r);
+    specialPlusTerm(p, 265, 780891, -1, 89, 6, r);
+    specialPlusTerm(p, 406, 256761, -1, 88, 6, r);
+    specialPlusTerm(p, 610, 6662, -1, 87, 6, r);
+    specialPlusTerm(p, 900, 631638, -1, 86, 6, r);
+    specialPlusTerm(p, 1308, 626820, -1, 85, 6, r);
+    specialPlusTerm(p, 1872, 748088, -1, 84, 6, r);
+    specialPlusTerm(p, 2641, 454830, -1, 83, 6, r);
+    specialPlusTerm(p, 3674, 372459, -1, 82, 6, r);
+    specialPlusTerm(p, 5043, 699859, -1, 81, 6, r);
+    specialPlusTerm(p, 6835, 468267, -1, 80, 6, r);
+    specialPlusTerm(p, 9150, 540598, -1, 79, 6, r);
+    specialPlusTerm(p, 12105, 225506, -1, 78, 6, r);
+    specialPlusTerm(p, 15831, 370284, -1, 77, 6, r);
+    specialPlusTerm(p, 20475, 792894, -1, 76, 6, r);
+    specialPlusTerm(p, 26198, 917672, -1, 75, 6, r);
+    specialPlusTerm(p, 33172, 493074, -1, 74, 6, r);
+    specialPlusTerm(p, 41576, 294268, -1, 73, 6, r);
+    specialPlusTerm(p, 51593, 749027, -1, 72, 6, r);
+    specialPlusTerm(p, 63406, 472134, -1, 71, 6, r);
+    specialPlusTerm(p, 77187, 750422, -1, 70, 6, r);
+    specialPlusTerm(p, 93095, 85649, -1, 69, 6, r);
+    specialPlusTerm(p, 111261, 972846, -1, 68, 6, r);
+    specialPlusTerm(p, 131789, 163843, -1, 67, 6, r);
+    specialPlusTerm(p, 154735, 735031, -1, 66, 6, r);
+    specialPlusTerm(p, 180110, 340164, -1, 65, 6, r);
+    specialPlusTerm(p, 207863, 78032, -1, 64, 6, r);
+    specialPlusTerm(p, 237878, 436148, -1, 63, 6, r);
+    specialPlusTerm(p, 269969, 780853, -1, 62, 6, r);
+    specialPlusTerm(p, 303875, 847919, -1, 61, 6, r);
+    specialPlusTerm(p, 339259, 643405, -1, 60, 6, r);
+    specialPlusTerm(p, 375710, 91709, -1, 59, 6, r);
+    specialPlusTerm(p, 412746, 667621, -1, 58, 6, r);
+    specialPlusTerm(p, 449827, 124838, -1, 57, 6, r);
+    specialPlusTerm(p, 486358, 289884, -1, 56, 6, r);
+    specialPlusTerm(p, 521709, 734617, -1, 55, 6, r);
+    specialPlusTerm(p, 555229, 980825, -1, 54, 6, r);
+    specialPlusTerm(p, 586264, 736452, -1, 53, 6, r);
+    specialPlusTerm(p, 614176, 524327, -1, 52, 6, r);
+    specialPlusTerm(p, 638364, 950461, -1, 51, 6, r);
+    specialPlusTerm(p, 658286, 778382, -1, 50, 6, r);
+    specialPlusTerm(p, 673474, 935703, -1, 49, 6, r);
+    specialPlusTerm(p, 683555, 584035, -1, 48, 6, r);
+    specialPlusTerm(p, 688262, 435939, -1, 47, 6, r);
+    specialPlusTerm(p, 687447, 601958, -1, 46, 6, r);
+    specialPlusTerm(p, 681088, 393321, -1, 45, 6, r);
+    specialPlusTerm(p, 669289, 685002, -1, 44, 6, r);
+    specialPlusTerm(p, 652281, 650056, -1, 43, 6, r);
+    specialPlusTerm(p, 630412, 897910, -1, 42, 6, r);
+    specialPlusTerm(p, 604139, 273828, -1, 41, 6, r);
+    specialPlusTerm(p, 574008, 790372, -1, 40, 6, r);
+    specialPlusTerm(p, 540643, 351434, -1, 39, 6, r);
+    specialPlusTerm(p, 504718, 83850, -1, 38, 6, r);
+    specialPlusTerm(p, 466939, 201686, -1, 37, 6, r);
+    specialPlusTerm(p, 428021, 387818, -1, 36, 6, r);
+    specialPlusTerm(p, 388665, 682772, -1, 35, 6, r);
+    specialPlusTerm(p, 349538, 822179, -1, 34, 6, r);
+    specialPlusTerm(p, 311254, 865006, -1, 33, 6, r);
+    specialPlusTerm(p, 274359, 811613, -1, 32, 6, r);
+    specialPlusTerm(p, 239319, 732987, -1, 31, 6, r);
+    specialPlusTerm(p, 206512, 732148, -1, 30, 6, r);
+    specialPlusTerm(p, 176224, 848533, -1, 29, 6, r);
+    specialPlusTerm(p, 148649, 810169, -1, 28, 6, r);
+    specialPlusTerm(p, 123892, 349306, -1, 27, 6, r);
+    specialPlusTerm(p, 101974, 636229, -1, 26, 6, r);
+    specialPlusTerm(p, 82845, 261439, -1, 25, 6, r);
+    specialPlusTerm(p, 66390, 113996, -1, 24, 6, r);
+    specialPlusTerm(p, 52444, 464455, -1, 23, 6, r);
+    specialPlusTerm(p, 40805, 563557, -1, 22, 6, r);
+    specialPlusTerm(p, 31245, 109466, -1, 21, 6, r);
+    specialPlusTerm(p, 23521, 11382, -1, 20, 6, r);
+    specialPlusTerm(p, 17387, 978784, -1, 19, 6, r);
+    specialPlusTerm(p, 12606, 585145, -1, 18, 6, r);
+    specialPlusTerm(p, 8950, 583389, -1, 17, 6, r);
+    specialPlusTerm(p, 6212, 378502, -1, 16, 6, r);
+    specialPlusTerm(p, 4206, 681655, -1, 15, 6, r);
+    specialPlusTerm(p, 2772, 472065, -1, 14, 6, r);
+    specialPlusTerm(p, 1773, 471986, -1, 13, 6, r);
+    specialPlusTerm(p, 1097, 393517, -1, 12, 6, r);
+    specialPlusTerm(p, 654, 242447, -1, 11, 6, r);
+    specialPlusTerm(p, 373, 966384, -1, 10, 6, r);
+    specialPlusTerm(p, 203, 716799, -1, 9, 6, r);
+    specialPlusTerm(p, 104, 963287, -1, 8, 6, r);
+    specialPlusTerm(p, 50, 659180, -1, 7, 6, r);
+    specialPlusTerm(p, 22, 613305, -1, 6, 6, r);
+    specialPlusTerm(p, 9, 176167, -1, 5, 6, r);
+    specialPlusTerm(p, 3, 303300, -1, 4, 6, r);
+    specialPlusTerm(p, 1, 17016, -1, 3, 6, r);
+    specialPlusTerm(p, 0, 252252, -1, 2, 6, r);
+    specialPlusTerm(p, 0, 45045, -1, 1, 6, r);
+    specialPlusTerm(p, 0, 4368, -1, 0, 6, r);
+    specialPlusTerm(p, 0, 1, 1, 114, 5, r);
+    specialPlusTerm(p, 0, 13, 1, 113, 5, r);
+    specialPlusTerm(p, 0, 92, 1, 112, 5, r);
+    specialPlusTerm(p, 0, 469, 1, 111, 5, r);
+    specialPlusTerm(p, 0, 1926, 1, 110, 5, r);
+    specialPlusTerm(p, 0, 6756, 1, 109, 5, r);
+    specialPlusTerm(p, 0, 20972, 1, 108, 5, r);
+    specialPlusTerm(p, 0, 58978, 1, 107, 5, r);
+    specialPlusTerm(p, 0, 152775, 1, 106, 5, r);
+    specialPlusTerm(p, 0, 369050, 1, 105, 5, r);
+    specialPlusTerm(p, 0, 839288, 1, 104, 5, r);
+    specialPlusTerm(p, 1, 810449, 1, 103, 5, r);
+    specialPlusTerm(p, 3, 726832, 1, 102, 5, r);
+    specialPlusTerm(p, 7, 357527, 1, 101, 5, r);
+    specialPlusTerm(p, 13, 988283, 1, 100, 5, r);
+    specialPlusTerm(p, 25, 701547, 1, 99, 5, r);
+    specialPlusTerm(p, 45, 773588, 1, 98, 5, r);
+    specialPlusTerm(p, 79, 222619, 1, 97, 5, r);
+    specialPlusTerm(p, 133, 546121, 1, 96, 5, r);
+    specialPlusTerm(p, 219, 688458, 1, 95, 5, r);
+    specialPlusTerm(p, 353, 280515, 1, 94, 5, r);
+    specialPlusTerm(p, 556, 190572, 1, 93, 5, r);
+    specialPlusTerm(p, 858, 418990, 1, 92, 5, r);
+    specialPlusTerm(p, 1300, 357646, 1, 91, 5, r);
+    specialPlusTerm(p, 1935, 417677, 1, 90, 5, r);
+    specialPlusTerm(p, 2833, 5498, 1, 89, 5, r);
+    specialPlusTerm(p, 4081, 797160, 1, 88, 5, r);
+    specialPlusTerm(p, 5793, 225338, 1, 87, 5, r);
+    specialPlusTerm(p, 8105, 52608, 1, 86, 5, r);
+    specialPlusTerm(p, 11184, 860904, 1, 85, 5, r);
+    specialPlusTerm(p, 15233, 242543, 1, 84, 5, r);
+    specialPlusTerm(p, 20486, 436025, 1, 83, 5, r);
+    specialPlusTerm(p, 27218, 113560, 1, 82, 5, r);
+    specialPlusTerm(p, 35740, 941, 1, 81, 5, r);
+    specialPlusTerm(p, 46400, 998184, 1, 80, 5, r);
+    specialPlusTerm(p, 59584, 475380, 1, 79, 5, r);
+    specialPlusTerm(p, 75703, 446044, 1, 78, 5, r);
+    specialPlusTerm(p, 95193, 372588, 1, 77, 5, r);
+    specialPlusTerm(p, 118502, 436837, 1, 76, 5, r);
+    specialPlusTerm(p, 146079, 212557, 1, 75, 5, r);
+    specialPlusTerm(p, 178357, 804753, 1, 74, 5, r);
+    specialPlusTerm(p, 215740, 667987, 1, 73, 5, r);
+    specialPlusTerm(p, 258579, 477117, 1, 72, 5, r);
+    specialPlusTerm(p, 307154, 590636, 1, 71, 5, r);
+    specialPlusTerm(p, 361653, 809467, 1, 70, 5, r);
+    specialPlusTerm(p, 422151, 281668, 1, 69, 5, r);
+    specialPlusTerm(p, 488587, 524562, 1, 68, 5, r);
+    specialPlusTerm(p, 560751, 619043, 1, 67, 5, r);
+    specialPlusTerm(p, 638266, 666013, 1, 66, 5, r);
+    specialPlusTerm(p, 720579, 573693, 1, 65, 5, r);
+    specialPlusTerm(p, 806956, 161270, 1, 64, 5, r);
+    specialPlusTerm(p, 896482, 416756, 1, 63, 5, r);
+    specialPlusTerm(p, 988072, 536828, 1, 62, 5, r);
+    specialPlusTerm(p, 1080484, 109735, 1, 61, 5, r);
+    specialPlusTerm(p, 1172340, 489345, 1, 60, 5, r);
+    specialPlusTerm(p, 1262160, 63390, 1, 59, 5, r);
+    specialPlusTerm(p, 1348391, 759522, 1, 58, 5, r);
+    specialPlusTerm(p, 1429455, 778912, 1, 57, 5, r);
+    specialPlusTerm(p, 1503788, 220123, 1, 56, 5, r);
+    specialPlusTerm(p, 1569887, 977111, 1, 55, 5, r);
+    specialPlusTerm(p, 1626364, 84113, 1, 54, 5, r);
+    specialPlusTerm(p, 1671981, 553512, 1, 53, 5, r);
+    specialPlusTerm(p, 1705703, 722632, 1, 52, 5, r);
+    specialPlusTerm(p, 1726729, 198623, 1, 51, 5, r);
+    specialPlusTerm(p, 1734521, 667786, 1, 50, 5, r);
+    specialPlusTerm(p, 1728831, 111168, 1, 49, 5, r);
+    specialPlusTerm(p, 1709705, 329909, 1, 48, 5, r);
+    specialPlusTerm(p, 1677491, 113716, 1, 47, 5, r);
+    specialPlusTerm(p, 1632824, 861010, 1, 46, 5, r);
+    specialPlusTerm(p, 1576612, 953462, 1, 45, 5, r);
+    specialPlusTerm(p, 1510002, 672602, 1, 44, 5, r);
+    specialPlusTerm(p, 1434344, 893769, 1, 43, 5, r);
+    specialPlusTerm(p, 1351150, 176624, 1, 42, 5, r);
+    specialPlusTerm(p, 1262040, 169393, 1, 41, 5, r);
+    specialPlusTerm(p, 1168696, 438727, 1, 40, 5, r);
+    specialPlusTerm(p, 1072808, 918138, 1, 39, 5, r);
+    specialPlusTerm(p, 976026, 132162, 1, 38, 5, r);
+    specialPlusTerm(p, 879909, 204828, 1, 37, 5, r);
+    specialPlusTerm(p, 785891, 410576, 1, 36, 5, r);
+    specialPlusTerm(p, 695244, 690346, 1, 35, 5, r);
+    specialPlusTerm(p, 609054, 157073, 1, 34, 5, r);
+    specialPlusTerm(p, 528201, 178547, 1, 33, 5, r);
+    specialPlusTerm(p, 453355, 178523, 1, 32, 5, r);
+    specialPlusTerm(p, 384973, 865967, 1, 31, 5, r);
+    specialPlusTerm(p, 323311, 212357, 1, 30, 5, r);
+    specialPlusTerm(p, 268432, 169189, 1, 29, 5, r);
+    specialPlusTerm(p, 220232, 868421, 1, 28, 5, r);
+    specialPlusTerm(p, 178464, 887323, 1, 27, 5, r);
+    specialPlusTerm(p, 142762, 89447, 1, 26, 5, r);
+    specialPlusTerm(p, 112668, 572043, 1, 25, 5, r);
+    specialPlusTerm(p, 87666, 348585, 1, 24, 5, r);
+    specialPlusTerm(p, 67201, 559745, 1, 23, 5, r);
+    specialPlusTerm(p, 50708, 221257, 1, 22, 5, r);
+    specialPlusTerm(p, 37628, 764983, 1, 21, 5, r);
+    specialPlusTerm(p, 27430, 891847, 1, 20, 5, r);
+    specialPlusTerm(p, 19620, 514504, 1, 19, 5, r);
+    specialPlusTerm(p, 13750, 807706, 1, 18, 5, r);
+    specialPlusTerm(p, 9427, 591898, 1, 17, 5, r);
+    specialPlusTerm(p, 6311, 440762, 1, 16, 5, r);
+    specialPlusTerm(p, 4117, 20228, 1, 15, 5, r);
+    specialPlusTerm(p, 2610, 233212, 1, 14, 5, r);
+    specialPlusTerm(p, 1603, 763552, 1, 13, 5, r);
+    specialPlusTerm(p, 951, 590329, 1, 12, 5, r);
+    specialPlusTerm(p, 542, 988511, 1, 11, 5, r);
+    specialPlusTerm(p, 296, 453834, 1, 10, 5, r);
+    specialPlusTerm(p, 153, 899291, 1, 9, 5, r);
+    specialPlusTerm(p, 75, 376496, 1, 8, 5, r);
+    specialPlusTerm(p, 34, 484437, 1, 7, 5, r);
+    specialPlusTerm(p, 14, 545453, 1, 6, 5, r);
+    specialPlusTerm(p, 5, 557552, 1, 5, 5, r);
+    specialPlusTerm(p, 1, 876238, 1, 4, 5, r);
+    specialPlusTerm(p, 0, 539266, 1, 3, 5, r);
+    specialPlusTerm(p, 0, 124215, 1, 2, 5, r);
+    specialPlusTerm(p, 0, 20475, 1, 1, 5, r);
+    specialPlusTerm(p, 0, 1820, 1, 0, 5, r);
+    specialPlusTerm(p, 0, 1, -1, 117, 4, r);
+    specialPlusTerm(p, 0, 14, -1, 116, 4, r);
+    specialPlusTerm(p, 0, 106, -1, 115, 4, r);
+    specialPlusTerm(p, 0, 575, -1, 114, 4, r);
+    specialPlusTerm(p, 0, 2496, -1, 113, 4, r);
+    specialPlusTerm(p, 0, 9192, -1, 112, 4, r);
+    specialPlusTerm(p, 0, 29769, -1, 111, 4, r);
+    specialPlusTerm(p, 0, 86862, -1, 110, 4, r);
+    specialPlusTerm(p, 0, 232352, -1, 109, 4, r);
+    specialPlusTerm(p, 0, 577237, -1, 108, 4, r);
+    specialPlusTerm(p, 1, 345280, -1, 107, 4, r);
+    specialPlusTerm(p, 2, 964694, -1, 106, 4, r);
+    specialPlusTerm(p, 6, 218071, -1, 105, 4, r);
+    specialPlusTerm(p, 12, 478024, -1, 104, 4, r);
+    specialPlusTerm(p, 24, 64445, -1, 103, 4, r);
+    specialPlusTerm(p, 44, 768554, -1, 102, 4, r);
+    specialPlusTerm(p, 80, 598456, -1, 101, 4, r);
+    specialPlusTerm(p, 140, 809905, -1, 100, 4, r);
+    specialPlusTerm(p, 239, 293294, -1, 99, 4, r);
+    specialPlusTerm(p, 396, 392192, -1, 98, 4, r);
+    specialPlusTerm(p, 641, 228471, -1, 97, 4, r);
+    specialPlusTerm(p, 1014, 602512, -1, 96, 4, r);
+    specialPlusTerm(p, 1572, 522451, -1, 95, 4, r);
+    specialPlusTerm(p, 2390, 392393, -1, 94, 4, r);
+    specialPlusTerm(p, 3567, 854826, -1, 93, 4, r);
+    specialPlusTerm(p, 5234, 236531, -1, 92, 4, r);
+    specialPlusTerm(p, 7554, 490334, -1, 91, 4, r);
+    specialPlusTerm(p, 10735, 458285, -1, 90, 4, r);
+    specialPlusTerm(p, 15032, 207608, -1, 89, 4, r);
+    specialPlusTerm(p, 20754, 112592, -1, 88, 4, r);
+    specialPlusTerm(p, 28270, 278236, -1, 87, 4, r);
+    specialPlusTerm(p, 38013, 830749, -1, 86, 4, r);
+    specialPlusTerm(p, 50484, 542623, -1, 85, 4, r);
+    specialPlusTerm(p, 66249, 223101, -1, 84, 4, r);
+    specialPlusTerm(p, 85939, 295631, -1, 83, 4, r);
+    specialPlusTerm(p, 110245, 8968, -1, 82, 4, r);
+    specialPlusTerm(p, 139905, 793448, -1, 81, 4, r);
+    specialPlusTerm(p, 175696, 382307, -1, 80, 4, r);
+    specialPlusTerm(p, 218408, 471011, -1, 79, 4, r);
+    specialPlusTerm(p, 268827, 883672, -1, 78, 4, r);
+    specialPlusTerm(p, 327707, 449671, -1, 77, 4, r);
+    specialPlusTerm(p, 395736, 57018, -1, 76, 4, r);
+    specialPlusTerm(p, 473504, 629765, -1, 75, 4, r);
+    specialPlusTerm(p, 561470, 59952, -1, 74, 4, r);
+    specialPlusTerm(p, 659918, 392736, -1, 73, 4, r);
+    specialPlusTerm(p, 768928, 797683, -1, 72, 4, r);
+    specialPlusTerm(p, 888340, 40490, -1, 71, 4, r);
+    specialPlusTerm(p, 1017721, 279436, -1, 70, 4, r);
+    specialPlusTerm(p, 1156349, 33848, -1, 69, 4, r);
+    specialPlusTerm(p, 1303192, 95883, -1, 68, 4, r);
+    specialPlusTerm(p, 1456905, 975122, -1, 67, 4, r);
+    specialPlusTerm(p, 1615838, 177110, -1, 66, 4, r);
+    specialPlusTerm(p, 1778045, 228075, -1, 65, 4, r);
+    specialPlusTerm(p, 1941321, 881690, -1, 64, 4, r);
+    specialPlusTerm(p, 2103242, 399767, -1, 63, 4, r);
+    specialPlusTerm(p, 2261213, 213104, -1, 62, 4, r);
+    specialPlusTerm(p, 2412535, 672007, -1, 61, 4, r);
+    specialPlusTerm(p, 2554477, 22053, -1, 60, 4, r);
+    specialPlusTerm(p, 2684347, 224260, -1, 59, 4, r);
+    specialPlusTerm(p, 2799578, 813532, -1, 58, 4, r);
+    specialPlusTerm(p, 2897806, 685056, -1, 57, 4, r);
+    specialPlusTerm(p, 2976944, 539523, -1, 56, 4, r);
+    specialPlusTerm(p, 3035254, 721183, -1, 55, 4, r);
+    specialPlusTerm(p, 3071408, 355156, -1, 54, 4, r);
+    specialPlusTerm(p, 3084533, 29299, -1, 53, 4, r);
+    specialPlusTerm(p, 3074245, 758101, -1, 52, 4, r);
+    specialPlusTerm(p, 3040669, 588583, -1, 51, 4, r);
+    specialPlusTerm(p, 2984432, 929416, -1, 50, 4, r);
+    specialPlusTerm(p, 2906651, 466023, -1, 49, 4, r);
+    specialPlusTerm(p, 2808893, 323361, -1, 48, 4, r);
+    specialPlusTerm(p, 2693128, 909640, -1, 47, 4, r);
+    specialPlusTerm(p, 2561667, 574760, -1, 46, 4, r);
+    specialPlusTerm(p, 2417083, 807115, -1, 45, 4, r);
+    specialPlusTerm(p, 2262136, 138608, -1, 44, 4, r);
+    specialPlusTerm(p, 2099682, 206060, -1, 43, 4, r);
+    specialPlusTerm(p, 1932593, 513922, -1, 42, 4, r);
+    specialPlusTerm(p, 1763673, 355846, -1, 41, 4, r);
+    specialPlusTerm(p, 1595581, 90061, -1, 40, 4, r);
+    specialPlusTerm(p, 1430765, 545095, -1, 39, 4, r);
+    specialPlusTerm(p, 1271409, 786637, -1, 38, 4, r);
+    specialPlusTerm(p, 1119388, 838595, -1, 37, 4, r);
+    specialPlusTerm(p, 976241, 261398, -1, 36, 4, r);
+    specialPlusTerm(p, 843154, 789753, -1, 35, 4, r);
+    specialPlusTerm(p, 720965, 560845, -1, 34, 4, r);
+    specialPlusTerm(p, 610169, 859179, -1, 33, 4, r);
+    specialPlusTerm(p, 510946, 796821, -1, 32, 4, r);
+    specialPlusTerm(p, 423189, 960892, -1, 31, 4, r);
+    specialPlusTerm(p, 346545, 808032, -1, 30, 4, r);
+    specialPlusTerm(p, 280456, 472902, -1, 29, 4, r);
+    specialPlusTerm(p, 224204, 680080, -1, 28, 4, r);
+    specialPlusTerm(p, 176958, 593014, -1, 27, 4, r);
+    specialPlusTerm(p, 137814, 680334, -1, 26, 4, r);
+    specialPlusTerm(p, 105837, 4252, -1, 25, 4, r);
+    specialPlusTerm(p, 80091, 710806, -1, 24, 4, r);
+    specialPlusTerm(p, 59675, 899582, -1, 23, 4, r);
+    specialPlusTerm(p, 43740, 445029, -1, 22, 4, r);
+    specialPlusTerm(p, 31506, 709211, -1, 21, 4, r);
+    specialPlusTerm(p, 22277, 407599, -1, 20, 4, r);
+    specialPlusTerm(p, 15442, 151129, -1, 19, 4, r);
+    specialPlusTerm(p, 10478, 380611, -1, 18, 4, r);
+    specialPlusTerm(p, 6948, 530664, -1, 17, 4, r);
+    specialPlusTerm(p, 4494, 312038, -1, 16, 4, r);
+    specialPlusTerm(p, 2828, 990461, -1, 15, 4, r);
+    specialPlusTerm(p, 1728, 477668, -1, 14, 4, r);
+    specialPlusTerm(p, 1021, 949004, -1, 13, 4, r);
+    specialPlusTerm(p, 582, 575810, -1, 12, 4, r);
+    specialPlusTerm(p, 318, 823114, -1, 11, 4, r);
+    specialPlusTerm(p, 166, 625848, -1, 10, 4, r);
+    specialPlusTerm(p, 82, 629352, -1, 9, 4, r);
+    specialPlusTerm(p, 38, 568972, -1, 8, 4, r);
+    specialPlusTerm(p, 16, 773120, -1, 7, 4, r);
+    specialPlusTerm(p, 6, 706050, -1, 6, 4, r);
+    specialPlusTerm(p, 2, 420964, -1, 5, 4, r);
+    specialPlusTerm(p, 0, 769496, -1, 4, 4, r);
+    specialPlusTerm(p, 0, 207389, -1, 3, 4, r);
+    specialPlusTerm(p, 0, 44590, -1, 2, 4, r);
+    specialPlusTerm(p, 0, 6825, -1, 1, 4, r);
+    specialPlusTerm(p, 0, 560, -1, 0, 4, r);
+    specialPlusTerm(p, 0, 1, 1, 119, 3, r);
+    specialPlusTerm(p, 0, 15, 1, 118, 3, r);
+    specialPlusTerm(p, 0, 121, 1, 117, 3, r);
+    specialPlusTerm(p, 0, 692, 1, 116, 3, r);
+    specialPlusTerm(p, 0, 3136, 1, 115, 3, r);
+    specialPlusTerm(p, 0, 11960, 1, 114, 3, r);
+    specialPlusTerm(p, 0, 39853, 1, 113, 3, r);
+    specialPlusTerm(p, 0, 119021, 1, 112, 3, r);
+    specialPlusTerm(p, 0, 324469, 1, 111, 3, r);
+    specialPlusTerm(p, 0, 818608, 1, 110, 3, r);
+    specialPlusTerm(p, 1, 931746, 1, 109, 3, r);
+    specialPlusTerm(p, 4, 299910, 1, 108, 3, r);
+    specialPlusTerm(p, 9, 90121, 1, 107, 3, r);
+    specialPlusTerm(p, 18, 353593, 1, 106, 3, r);
+    specialPlusTerm(p, 35, 558983, 1, 105, 3, r);
+    specialPlusTerm(p, 66, 370113, 1, 104, 3, r);
+    specialPlusTerm(p, 119, 744513, 1, 103, 3, r);
+    specialPlusTerm(p, 209, 439344, 1, 102, 3, r);
+    specialPlusTerm(p, 356, 18067, 1, 101, 3, r);
+    specialPlusTerm(p, 589, 452669, 1, 100, 3, r);
+    specialPlusTerm(p, 952, 410212, 1, 99, 3, r);
+    specialPlusTerm(p, 1504, 296795, 1, 98, 3, r);
+    specialPlusTerm(p, 2326, 104760, 1, 97, 3, r);
+    specialPlusTerm(p, 3526, 68612, 1, 96, 3, r);
+    specialPlusTerm(p, 5246, 80850, 1, 95, 3, r);
+    specialPlusTerm(p, 7668, 750896, 1, 94, 3, r);
+    specialPlusTerm(p, 11024, 909967, 1, 93, 3, r);
+    specialPlusTerm(p, 15601, 274876, 1, 92, 3, r);
+    specialPlusTerm(p, 21747, 888690, 1, 91, 3, r);
+    specialPlusTerm(p, 29884, 861708, 1, 90, 3, r);
+    specialPlusTerm(p, 40507, 849459, 1, 89, 3, r);
+    specialPlusTerm(p, 54191, 633482, 1, 88, 3, r);
+    specialPlusTerm(p, 71591, 124221, 1, 87, 3, r);
+    specialPlusTerm(p, 93439, 92109, 1, 86, 3, r);
+    specialPlusTerm(p, 120539, 960778, 1, 85, 3, r);
+    specialPlusTerm(p, 153759, 71799, 1, 84, 3, r);
+    specialPlusTerm(p, 194006, 957680, 1, 83, 3, r);
+    specialPlusTerm(p, 242218, 340335, 1, 82, 3, r);
+    specialPlusTerm(p, 299325, 803637, 1, 81, 3, r);
+    specialPlusTerm(p, 366228, 364763, 1, 80, 3, r);
+    specialPlusTerm(p, 443755, 479465, 1, 79, 3, r);
+    specialPlusTerm(p, 532627, 346793, 1, 78, 3, r);
+    specialPlusTerm(p, 633412, 711280, 1, 77, 3, r);
+    specialPlusTerm(p, 746485, 674616, 1, 76, 3, r);
+    specialPlusTerm(p, 871983, 302274, 1, 75, 3, r);
+    specialPlusTerm(p, 1009766, 21123, 1, 74, 3, r);
+    specialPlusTerm(p, 1159382, 930867, 1, 73, 3, r);
+    specialPlusTerm(p, 1320044, 177277, 1, 72, 3, r);
+    specialPlusTerm(p, 1490602, 445312, 1, 71, 3, r);
+    specialPlusTerm(p, 1669545, 418046, 1, 70, 3, r);
+    specialPlusTerm(p, 1855000, 712658, 1, 69, 3, r);
+    specialPlusTerm(p, 2044754, 355265, 1, 68, 3, r);
+    specialPlusTerm(p, 2236283, 307760, 1, 67, 3, r);
+    specialPlusTerm(p, 2426801, 935374, 1, 66, 3, r);
+    specialPlusTerm(p, 2613321, 633418, 1, 65, 3, r);
+    specialPlusTerm(p, 2792722, 150781, 1, 64, 3, r);
+    specialPlusTerm(p, 2961832, 494671, 1, 63, 3, r);
+    specialPlusTerm(p, 3117518, 715055, 1, 62, 3, r);
+    specialPlusTerm(p, 3256775, 385842, 1, 61, 3, r);
+    specialPlusTerm(p, 3376817, 256340, 1, 60, 3, r);
+    specialPlusTerm(p, 3475167, 367466, 1, 59, 3, r);
+    specialPlusTerm(p, 3549737, 930366, 1, 58, 3, r);
+    specialPlusTerm(p, 3598900, 457938, 1, 57, 3, r);
+    specialPlusTerm(p, 3621542, 18424, 1, 56, 3, r);
+    specialPlusTerm(p, 3617105, 29495, 1, 55, 3, r);
+    specialPlusTerm(p, 3585608, 705050, 1, 54, 3, r);
+    specialPlusTerm(p, 3527651, 69853, 1, 53, 3, r);
+    specialPlusTerm(p, 3444391, 326416, 1, 52, 3, r);
+    specialPlusTerm(p, 3337513, 246817, 1, 51, 3, r);
+    specialPlusTerm(p, 3209171, 120352, 1, 50, 3, r);
+    specialPlusTerm(p, 3061920, 568442, 1, 49, 3, r);
+    specialPlusTerm(p, 2898637, 197953, 1, 48, 3, r);
+    specialPlusTerm(p, 2722426, 567254, 1, 47, 3, r);
+    specialPlusTerm(p, 2536529, 259766, 1, 46, 3, r);
+    specialPlusTerm(p, 2344224, 982535, 1, 45, 3, r);
+    specialPlusTerm(p, 2148739, 529673, 1, 44, 3, r);
+    specialPlusTerm(p, 1953158, 181630, 1, 43, 3, r);
+    specialPlusTerm(p, 1760348, 671733, 1, 42, 3, r);
+    specialPlusTerm(p, 1572896, 271477, 1, 41, 3, r);
+    specialPlusTerm(p, 1393052, 863345, 1, 40, 3, r);
+    specialPlusTerm(p, 1222701, 126910, 1, 39, 3, r);
+    specialPlusTerm(p, 1063334, 204889, 1, 38, 3, r);
+    specialPlusTerm(p, 916050, 483828, 1, 37, 3, r);
+    specialPlusTerm(p, 781562, 458519, 1, 36, 3, r);
+    specialPlusTerm(p, 660218, 83241, 1, 35, 3, r);
+    specialPlusTerm(p, 552032, 571637, 1, 34, 3, r);
+    specialPlusTerm(p, 456728, 306449, 1, 33, 3, r);
+    specialPlusTerm(p, 373780, 366678, 1, 32, 3, r);
+    specialPlusTerm(p, 302465, 169735, 1, 31, 3, r);
+    specialPlusTerm(p, 241909, 847846, 1, 30, 3, r);
+    specialPlusTerm(p, 191140, 212177, 1, 29, 3, r);
+    specialPlusTerm(p, 149125, 480301, 1, 28, 3, r);
+    specialPlusTerm(p, 114818, 324960, 1, 27, 3, r);
+    specialPlusTerm(p, 87189, 215772, 1, 26, 3, r);
+    specialPlusTerm(p, 65254, 442815, 1, 25, 3, r);
+    specialPlusTerm(p, 48097, 606920, 1, 24, 3, r);
+    specialPlusTerm(p, 34884, 715247, 1, 23, 3, r);
+    specialPlusTerm(p, 24873, 316659, 1, 22, 3, r);
+    specialPlusTerm(p, 17416, 339482, 1, 21, 3, r);
+    specialPlusTerm(p, 11961, 450014, 1, 20, 3, r);
+    specialPlusTerm(p, 8046, 834503, 1, 19, 3, r);
+    specialPlusTerm(p, 5294, 325768, 1, 18, 3, r);
+    specialPlusTerm(p, 3400, 757398, 1, 17, 3, r);
+    specialPlusTerm(p, 2128, 345318, 1, 16, 3, r);
+    specialPlusTerm(p, 1294, 781596, 1, 15, 3, r);
+    specialPlusTerm(p, 763, 591975, 1, 14, 3, r);
+    specialPlusTerm(p, 435, 169111, 1, 13, 3, r);
+    specialPlusTerm(p, 238, 758463, 1, 12, 3, r);
+    specialPlusTerm(p, 125, 551459, 1, 11, 3, r);
+    specialPlusTerm(p, 62, 936621, 1, 10, 3, r);
+    specialPlusTerm(p, 29, 876893, 1, 9, 3, r);
+    specialPlusTerm(p, 13, 321355, 1, 8, 3, r);
+    specialPlusTerm(p, 5, 520901, 1, 7, 3, r);
+    specialPlusTerm(p, 2, 98067, 1, 6, 3, r);
+    specialPlusTerm(p, 0, 717871, 1, 5, 3, r);
+    specialPlusTerm(p, 0, 215565, 1, 4, 3, r);
+    specialPlusTerm(p, 0, 54691, 1, 3, 3, r);
+    specialPlusTerm(p, 0, 11025, 1, 2, 3, r);
+    specialPlusTerm(p, 0, 1575, 1, 1, 3, r);
+    specialPlusTerm(p, 0, 120, 1, 0, 3, r);
+    specialPlusTerm(p, 0, 1, -1, 120, 2, r);
+    specialPlusTerm(p, 0, 16, -1, 119, 2, r);
+    specialPlusTerm(p, 0, 134, -1, 118, 2, r);
+    specialPlusTerm(p, 0, 784, -1, 117, 2, r);
+    specialPlusTerm(p, 0, 3602, -1, 116, 2, r);
+    specialPlusTerm(p, 0, 13843, -1, 115, 2, r);
+    specialPlusTerm(p, 0, 46286, -1, 114, 2, r);
+    specialPlusTerm(p, 0, 138283, -1, 113, 2, r);
+    specialPlusTerm(p, 0, 376259, -1, 112, 2, r);
+    specialPlusTerm(p, 0, 945827, -1, 111, 2, r);
+    specialPlusTerm(p, 2, 220933, -1, 110, 2, r);
+    specialPlusTerm(p, 4, 914174, -1, 109, 2, r);
+    specialPlusTerm(p, 10, 318553, -1, 108, 2, r);
+    specialPlusTerm(p, 20, 680144, -1, 107, 2, r);
+    specialPlusTerm(p, 39, 750869, -1, 106, 2, r);
+    specialPlusTerm(p, 73, 579984, -1, 105, 2, r);
+    specialPlusTerm(p, 131, 610793, -1, 104, 2, r);
+    specialPlusTerm(p, 228, 154162, -1, 103, 2, r);
+    specialPlusTerm(p, 384, 310996, -1, 102, 2, r);
+    specialPlusTerm(p, 630, 410278, -1, 101, 2, r);
+    specialPlusTerm(p, 1009, 15895, -1, 100, 2, r);
+    specialPlusTerm(p, 1578, 532849, -1, 99, 2, r);
+    specialPlusTerm(p, 2417, 410542, -1, 98, 2, r);
+    specialPlusTerm(p, 3628, 897233, -1, 97, 2, r);
+    specialPlusTerm(p, 5346, 245930, -1, 96, 2, r);
+    specialPlusTerm(p, 7738, 209354, -1, 95, 2, r);
+    specialPlusTerm(p, 11014, 592780, -1, 94, 2, r);
+    specialPlusTerm(p, 15431, 562271, -1, 93, 2, r);
+    specialPlusTerm(p, 21296, 336917, -1, 92, 2, r);
+    specialPlusTerm(p, 28970, 832923, -1, 91, 2, r);
+    specialPlusTerm(p, 38873, 781118, -1, 90, 2, r);
+    specialPlusTerm(p, 51480, 814244, -1, 89, 2, r);
+    specialPlusTerm(p, 67322, 22502, -1, 88, 2, r);
+    specialPlusTerm(p, 86976, 510707, -1, 87, 2, r);
+    specialPlusTerm(p, 111063, 562039, -1, 86, 2, r);
+    specialPlusTerm(p, 140230, 123797, -1, 85, 2, r);
+    specialPlusTerm(p, 175134, 479331, -1, 84, 2, r);
+    specialPlusTerm(p, 216426, 154185, -1, 83, 2, r);
+    specialPlusTerm(p, 264722, 317163, -1, 82, 2, r);
+    specialPlusTerm(p, 320581, 169273, -1, 81, 2, r);
+    specialPlusTerm(p, 384473, 53329, -1, 80, 2, r);
+    specialPlusTerm(p, 456750, 250207, -1, 79, 2, r);
+    specialPlusTerm(p, 537616, 638714, -1, 78, 2, r);
+    specialPlusTerm(p, 627098, 568602, -1, 77, 2, r);
+    specialPlusTerm(p, 725018, 414915, -1, 76, 2, r);
+    specialPlusTerm(p, 830972, 332853, -1, 75, 2, r);
+    specialPlusTerm(p, 944313, 704873, -1, 74, 2, r);
+    specialPlusTerm(p, 1064143, 659019, -1, 73, 2, r);
+    specialPlusTerm(p, 1189309, 837532, -1, 72, 2, r);
+    specialPlusTerm(p, 1318414, 311129, -1, 71, 2, r);
+    specialPlusTerm(p, 1449831, 176128, -1, 70, 2, r);
+    specialPlusTerm(p, 1581733, 953526, -1, 69, 2, r);
+    specialPlusTerm(p, 1712132, 450851, -1, 68, 2, r);
+    specialPlusTerm(p, 1838918, 272730, -1, 67, 2, r);
+    specialPlusTerm(p, 1959917, 700931, -1, 66, 2, r);
+    specialPlusTerm(p, 2072950, 236513, -1, 65, 2, r);
+    specialPlusTerm(p, 2175890, 732337, -1, 64, 2, r);
+    specialPlusTerm(p, 2266732, 767744, -1, 63, 2, r);
+    specialPlusTerm(p, 2343650, 748669, -1, 62, 2, r);
+    specialPlusTerm(p, 2405058, 170088, -1, 61, 2, r);
+    specialPlusTerm(p, 2449659, 560856, -1, 60, 2, r);
+    specialPlusTerm(p, 2476493, 843437, -1, 59, 2, r);
+    specialPlusTerm(p, 2484967, 174656, -1, 58, 2, r);
+    specialPlusTerm(p, 2474873, 772785, -1, 57, 2, r);
+    specialPlusTerm(p, 2446403, 758673, -1, 56, 2, r);
+    specialPlusTerm(p, 2400137, 616515, -1, 55, 2, r);
+    specialPlusTerm(p, 2337027, 481818, -1, 54, 2, r);
+    specialPlusTerm(p, 2258366, 57059, -1, 53, 2, r);
+    specialPlusTerm(p, 2165744, 506758, -1, 52, 2, r);
+    specialPlusTerm(p, 2061001, 163040, -1, 51, 2, r);
+    specialPlusTerm(p, 1946163, 254505, -1, 50, 2, r);
+    specialPlusTerm(p, 1823384, 135692, -1, 49, 2, r);
+    specialPlusTerm(p, 1694878, 629195, -1, 48, 2, r);
+    specialPlusTerm(p, 1562859, 93097, -1, 47, 2, r);
+    specialPlusTerm(p, 1429474, 696453, -1, 46, 2, r);
+    specialPlusTerm(p, 1296756, 136371, -1, 45, 2, r);
+    specialPlusTerm(p, 1166567, 679850, -1, 44, 2, r);
+    specialPlusTerm(p, 1040567, 985354, -1, 43, 2, r);
+    specialPlusTerm(p, 920180, 680239, -1, 42, 2, r);
+    specialPlusTerm(p, 806575, 169521, -1, 41, 2, r);
+    specialPlusTerm(p, 700657, 657865, -1, 40, 2, r);
+    specialPlusTerm(p, 603071, 906907, -1, 39, 2, r);
+    specialPlusTerm(p, 514208, 847321, -1, 38, 2, r);
+    specialPlusTerm(p, 434223, 837763, -1, 37, 2, r);
+    specialPlusTerm(p, 363060, 123557, -1, 36, 2, r);
+    specialPlusTerm(p, 300476, 903127, -1, 35, 2, r);
+    specialPlusTerm(p, 246080, 359923, -1, 34, 2, r);
+    specialPlusTerm(p, 199356, 56374, -1, 33, 2, r);
+    specialPlusTerm(p, 159701, 203700, -1, 32, 2, r);
+    specialPlusTerm(p, 126455, 502830, -1, 31, 2, r);
+    specialPlusTerm(p, 98929, 480219, -1, 30, 2, r);
+    specialPlusTerm(p, 76429, 499829, -1, 29, 2, r);
+    specialPlusTerm(p, 58278, 900847, -1, 28, 2, r);
+    specialPlusTerm(p, 43834, 973084, -1, 27, 2, r);
+    specialPlusTerm(p, 32501, 723962, -1, 26, 2, r);
+    specialPlusTerm(p, 23738, 601098, -1, 25, 2, r);
+    specialPlusTerm(p, 17065, 504721, -1, 24, 2, r);
+    specialPlusTerm(p, 12064, 550062, -1, 23, 2, r);
+    specialPlusTerm(p, 8379, 120417, -1, 22, 2, r);
+    specialPlusTerm(p, 5710, 788839, -1, 21, 2, r);
+    specialPlusTerm(p, 3814, 684934, -1, 20, 2, r);
+    specialPlusTerm(p, 2493, 849460, -1, 19, 2, r);
+    specialPlusTerm(p, 1593, 60962, -1, 18, 2, r);
+    specialPlusTerm(p, 992, 543577, -1, 17, 2, r);
+    specialPlusTerm(p, 601, 881264, -1, 16, 2, r);
+    specialPlusTerm(p, 354, 378149, -1, 15, 2, r);
+    specialPlusTerm(p, 202, 23344, -1, 14, 2, r);
+    specialPlusTerm(p, 111, 145993, -1, 13, 2, r);
+    specialPlusTerm(p, 58, 785390, -1, 12, 2, r);
+    specialPlusTerm(p, 29, 753317, -1, 11, 2, r);
+    specialPlusTerm(p, 14, 331491, -1, 10, 2, r);
+    specialPlusTerm(p, 6, 525379, -1, 9, 2, r);
+    specialPlusTerm(p, 2, 785083, -1, 8, 2, r);
+    specialPlusTerm(p, 1, 102494, -1, 7, 2, r);
+    specialPlusTerm(p, 0, 399235, -1, 6, 2, r);
+    specialPlusTerm(p, 0, 129826, -1, 5, 2, r);
+    specialPlusTerm(p, 0, 36944, -1, 4, 2, r);
+    specialPlusTerm(p, 0, 8854, -1, 3, 2, r);
+    specialPlusTerm(p, 0, 1680, -1, 2, 2, r);
+    specialPlusTerm(p, 0, 225, -1, 1, 2, r);
+    specialPlusTerm(p, 0, 16, -1, 0, 2, r);
+    specialPlusTerm(p, 0, 1, 1, 120, 1, r);
+    specialPlusTerm(p, 0, 15, 1, 119, 1, r);
+    specialPlusTerm(p, 0, 119, 1, 118, 1, r);
+    specialPlusTerm(p, 0, 664, 1, 117, 1, r);
+    specialPlusTerm(p, 0, 2924, 1, 116, 1, r);
+    specialPlusTerm(p, 0, 10813, 1, 115, 1, r);
+    specialPlusTerm(p, 0, 34900, 1, 114, 1, r);
+    specialPlusTerm(p, 0, 100913, 1, 113, 1, r);
+    specialPlusTerm(p, 0, 266338, 1, 112, 1, r);
+    specialPlusTerm(p, 0, 650658, 1, 111, 1, r);
+    specialPlusTerm(p, 1, 487262, 1, 110, 1, r);
+    specialPlusTerm(p, 3, 208036, 1, 109, 1, r);
+    specialPlusTerm(p, 6, 574987, 1, 108, 1, r);
+    specialPlusTerm(p, 12, 876702, 1, 107, 1, r);
+    specialPlusTerm(p, 24, 210652, 1, 106, 1, r);
+    specialPlusTerm(p, 43, 874857, 1, 105, 1, r);
+    specialPlusTerm(p, 76, 893687, 1, 104, 1, r);
+    specialPlusTerm(p, 130, 701986, 1, 103, 1, r);
+    specialPlusTerm(p, 216, 8661, 1, 102, 1, r);
+    specialPlusTerm(p, 347, 854815, 1, 101, 1, r);
+    specialPlusTerm(p, 546, 871981, 1, 100, 1, r);
+    specialPlusTerm(p, 840, 732790, 1, 99, 1, r);
+    specialPlusTerm(p, 1265, 769513, 1, 98, 1, r);
+    specialPlusTerm(p, 1868, 715733, 1, 97, 1, r);
+    specialPlusTerm(p, 2708, 503701, 1, 96, 1, r);
+    specialPlusTerm(p, 3858, 25899, 1, 95, 1, r);
+    specialPlusTerm(p, 5405, 745562, 1, 94, 1, r);
+    specialPlusTerm(p, 7457, 19331, 1, 93, 1, r);
+    specialPlusTerm(p, 10134, 977992, 1, 92, 1, r);
+    specialPlusTerm(p, 13580, 800674, 1, 91, 1, r);
+    specialPlusTerm(p, 17953, 216130, 1, 90, 1, r);
+    specialPlusTerm(p, 23427, 73737, 1, 89, 1, r);
+    specialPlusTerm(p, 30190, 848078, 1, 88, 1, r);
+    specialPlusTerm(p, 38442, 975195, 1, 87, 1, r);
+    specialPlusTerm(p, 48386, 965771, 1, 86, 1, r);
+    specialPlusTerm(p, 60225, 299589, 1, 85, 1, r);
+    specialPlusTerm(p, 74152, 174574, 1, 84, 1, r);
+    specialPlusTerm(p, 90345, 259476, 1, 83, 1, r);
+    specialPlusTerm(p, 108956, 677797, 1, 82, 1, r);
+    specialPlusTerm(p, 130103, 527156, 1, 81, 1, r);
+    specialPlusTerm(p, 153858, 307693, 1, 80, 1, r);
+    specialPlusTerm(p, 180239, 689955, 1, 79, 1, r);
+    specialPlusTerm(p, 209204, 91832, 1, 78, 1, r);
+    specialPlusTerm(p, 240638, 550997, 1, 77, 1, r);
+    specialPlusTerm(p, 274355, 370450, 1, 76, 1, r);
+    specialPlusTerm(p, 310088, 978041, 1, 75, 1, r);
+    specialPlusTerm(p, 347495, 375766, 1, 74, 1, r);
+    specialPlusTerm(p, 386154, 462530, 1, 73, 1, r);
+    specialPlusTerm(p, 425575, 398166, 1, 72, 1, r);
+    specialPlusTerm(p, 465205, 41801, 1, 71, 1, r);
+    specialPlusTerm(p, 504439, 350762, 1, 70, 1, r);
+    specialPlusTerm(p, 542637, 474944, 1, 69, 1, r);
+    specialPlusTerm(p, 579138, 134521, 1, 68, 1, r);
+    specialPlusTerm(p, 613277, 734909, 1, 67, 1, r);
+    specialPlusTerm(p, 644409, 560477, 1, 66, 1, r);
+    specialPlusTerm(p, 671923, 305201, 1, 65, 1, r);
+    specialPlusTerm(p, 695264, 150336, 1, 64, 1, r);
+    specialPlusTerm(p, 713950, 590364, 1, 63, 1, r);
+    specialPlusTerm(p, 727590, 240796, 1, 62, 1, r);
+    specialPlusTerm(p, 735892, 934219, 1, 61, 1, r);
+    specialPlusTerm(p, 738680, 521142, 1, 60, 1, r);
+    specialPlusTerm(p, 735892, 934219, 1, 59, 1, r);
+    specialPlusTerm(p, 727590, 240796, 1, 58, 1, r);
+    specialPlusTerm(p, 713950, 590364, 1, 57, 1, r);
+    specialPlusTerm(p, 695264, 150336, 1, 56, 1, r);
+    specialPlusTerm(p, 671923, 305201, 1, 55, 1, r);
+    specialPlusTerm(p, 644409, 560477, 1, 54, 1, r);
+    specialPlusTerm(p, 613277, 734909, 1, 53, 1, r);
+    specialPlusTerm(p, 579138, 134521, 1, 52, 1, r);
+    specialPlusTerm(p, 542637, 474944, 1, 51, 1, r);
+    specialPlusTerm(p, 504439, 350762, 1, 50, 1, r);
+    specialPlusTerm(p, 465205, 41801, 1, 49, 1, r);
+    specialPlusTerm(p, 425575, 398166, 1, 48, 1, r);
+    specialPlusTerm(p, 386154, 462530, 1, 47, 1, r);
+    specialPlusTerm(p, 347495, 375766, 1, 46, 1, r);
+    specialPlusTerm(p, 310088, 978041, 1, 45, 1, r);
+    specialPlusTerm(p, 274355, 370450, 1, 44, 1, r);
+    specialPlusTerm(p, 240638, 550997, 1, 43, 1, r);
+    specialPlusTerm(p, 209204, 91832, 1, 42, 1, r);
+    specialPlusTerm(p, 180239, 689955, 1, 41, 1, r);
+    specialPlusTerm(p, 153858, 307693, 1, 40, 1, r);
+    specialPlusTerm(p, 130103, 527156, 1, 39, 1, r);
+    specialPlusTerm(p, 108956, 677797, 1, 38, 1, r);
+    specialPlusTerm(p, 90345, 259476, 1, 37, 1, r);
+    specialPlusTerm(p, 74152, 174574, 1, 36, 1, r);
+    specialPlusTerm(p, 60225, 299589, 1, 35, 1, r);
+    specialPlusTerm(p, 48386, 965771, 1, 34, 1, r);
+    specialPlusTerm(p, 38442, 975195, 1, 33, 1, r);
+    specialPlusTerm(p, 30190, 848078, 1, 32, 1, r);
+    specialPlusTerm(p, 23427, 73737, 1, 31, 1, r);
+    specialPlusTerm(p, 17953, 216130, 1, 30, 1, r);
+    specialPlusTerm(p, 13580, 800674, 1, 29, 1, r);
+    specialPlusTerm(p, 10134, 977992, 1, 28, 1, r);
+    specialPlusTerm(p, 7457, 19331, 1, 27, 1, r);
+    specialPlusTerm(p, 5405, 745562, 1, 26, 1, r);
+    specialPlusTerm(p, 3858, 25899, 1, 25, 1, r);
+    specialPlusTerm(p, 2708, 503701, 1, 24, 1, r);
+    specialPlusTerm(p, 1868, 715733, 1, 23, 1, r);
+    specialPlusTerm(p, 1265, 769513, 1, 22, 1, r);
+    specialPlusTerm(p, 840, 732790, 1, 21, 1, r);
+    specialPlusTerm(p, 546, 871981, 1, 20, 1, r);
+    specialPlusTerm(p, 347, 854815, 1, 19, 1, r);
+    specialPlusTerm(p, 216, 8661, 1, 18, 1, r);
+    specialPlusTerm(p, 130, 701986, 1, 17, 1, r);
+    specialPlusTerm(p, 76, 893687, 1, 16, 1, r);
+    specialPlusTerm(p, 43, 874857, 1, 15, 1, r);
+    specialPlusTerm(p, 24, 210652, 1, 14, 1, r);
+    specialPlusTerm(p, 12, 876702, 1, 13, 1, r);
+    specialPlusTerm(p, 6, 574987, 1, 12, 1, r);
+    specialPlusTerm(p, 3, 208036, 1, 11, 1, r);
+    specialPlusTerm(p, 1, 487262, 1, 10, 1, r);
+    specialPlusTerm(p, 0, 650658, 1, 9, 1, r);
+    specialPlusTerm(p, 0, 266338, 1, 8, 1, r);
+    specialPlusTerm(p, 0, 100913, 1, 7, 1, r);
+    specialPlusTerm(p, 0, 34900, 1, 6, 1, r);
+    specialPlusTerm(p, 0, 10813, 1, 5, 1, r);
+    specialPlusTerm(p, 0, 2924, 1, 4, 1, r);
+    specialPlusTerm(p, 0, 664, 1, 3, 1, r);
+    specialPlusTerm(p, 0, 119, 1, 2, 1, r);
+    specialPlusTerm(p, 0, 15, 1, 1, 1, r);
+    specialPlusTerm(p, 0, 1, 1, 0, 1, r);
+  }
+  void checkInverse(number n, const coeffs cf)
+  {
+    clog << "n = "; p_Write((poly)n, cf->extRing);
+    number n1 = n_Invers(n, cf);
+    clog << "==> n^(-1) = "; p_Write((poly)n1, cf->extRing);
+    number n2 = n_Mult(n, n1, cf);
+    clog << "check: n * n^(-1) = "; p_Write((poly)n2, cf->extRing);
+    TS_ASSERT( n_IsOne(n2, cf) );
+    n_Delete(&n1, cf); n_Delete(&n2, cf);
+  }
+  /* to be used over a rational function field, only!
+     assumes that cf represents a rational function field;
+     uses p inside the resulting number (and not a copy of it!) */
+  number toFractionNumber(poly p, const coeffs cf)
+  {
+    number n = n_Init(1, cf);
+    fraction f = (fraction)n;
+    p_Delete(&(f->numerator), cf->extRing);
+    f->numerator = p;
+    return n;
+  }
+  void TestArithCf(const coeffs r)
+  {
+    clog << ("TEST: Simple Arithmetics: ");
+    clog << endl;
+
+    number two = n_Init(2, r);
+
+    number t = n_Init(1, r);
+    n_InpAdd(t, t, r);
+    TS_ASSERT( n_Equal(two, t, r) );
+    n_Delete(&t, r);
+
+    if( getCoeffType(r) == n_Q )
+    {
+      number t = n_Init(1, r);
+      n_InpAdd(t, t, r);
+      TS_ASSERT( n_Equal(two, t, r) );
+      n_Delete(&t, r);
+    }
+
+    const int N = 66666;
+
+    number a = n_Init(N, r);
+
+    clog<< "a: "; PrintSized(a, r);
+
+    clog<< "two: "; PrintSized(two, r);
+
+    number aa0 = n_Init(N*2, r);
+
+    number aa = n_Add(a, a, r);
+
+    clog<< "aa = a + a: "; PrintSized(aa, r);
+
+    number aa2 = n_Mult(a, two, r);
+
+    clog<< "aa2 = a * 2: "; PrintSized(aa2, r);
+
+    number aa1 = n_Mult(two, a, r);
+
+    clog<< "aa1 = 2 * a: "; PrintSized(aa1, r);
+
+    n_Delete(&a, r);
+    n_Delete(&two, r);
+
+    a = n_Sub( aa, aa1, r );
+
+    clog<< "a = aa - aa1: "; PrintSized(a, r);
+
+    TS_ASSERT( n_IsZero(a, r) );
+
+    n_Delete(&a, r);
+
+    a = n_Sub( aa, aa2, r );
+
+    clog<< "a = aa - aa2: "; PrintSized(a, r);
+
+    TS_ASSERT( n_IsZero(a, r) );
+
+    n_Delete(&a, r);
+
+    a = n_Sub( aa1, aa2, r );
+
+    clog<< "a = aa1 - aa2: "; PrintSized(a, r);
+
+    TS_ASSERT( n_IsZero(a, r) );
+
+    n_Delete(&a, r);
+
+    TS_ASSERT( n_Equal(aa, aa1, r) );
+    TS_ASSERT( n_Equal(aa, aa2, r) );
+    TS_ASSERT( n_Equal(aa1, aa2, r) );
+
+    TS_ASSERT( n_Equal(aa0, aa, r) );
+    TS_ASSERT( n_Equal(aa0, aa1, r) );
+    TS_ASSERT( n_Equal(aa0, aa2, r) );
+
+    n_Delete(&aa, r);
+    n_Delete(&aa1, r);
+    n_Delete(&aa2, r);
+
+    n_Delete(&aa0, r);
+
+    clog << ( " >>> TEST DONE!" );
+    clog << endl;
+  }
+  void TestSumCf(const coeffs r, const unsigned long N)
+  {
+    clog << ( _2S("TEST: sum[0..") + _2S(N) + "]: ");
+    clog << endl;
+
+    assume( N > 0 ); // just for now...
+
+    const unsigned long ssss = (N * (N+1)) / 2;
+
+    number sum1 = n_Init(ssss, r);
+    clog<< "N*(N+1)/2 (int: " << ssss << "): "; PrintSized(sum1, r);
+
+    number s, ss, i, res;
+
+    s = n_Init(N  , r);
+    i = n_Init(N+1, r);
+    n_InpMult(s, i, r);
+    n_Delete(&i, r);
+
+    clog<< "N*(N+1): ("<< N*(N+1) << ")"; PrintSized(s, r);
+
+    i = n_Init(2, r);
+    clog<< "2: "; PrintSized(i, r);
+
+    if( !n_IsZero( i, r) )
+    {
+  #ifdef HAVE_RINGS
+      TS_ASSERT( n_DivBy(s, i, r) );
+  #endif
+
+      res = n_Div(s, i, r);
+
+      clog<< "N*(N+1)/2: "; PrintSized(res, r);
+
+
+      number d = n_Sub(res, sum1, r);
+      TS_ASSERT( n_IsZeroDivisor(d, r) );
+      n_Delete(&d, r);
+
+      if( n_GetChar(r) == 0 )
+      {
+        TS_ASSERT( n_Equal(sum1, res, r) );
+        TS_ASSERT( n_Equal(res, sum1, r) );
+      }
+    } else
+      TS_ASSERT_EQUALS( n_GetChar(r), 2);
+
+
+    n_Delete(&s, r);  n_Delete(&i, r);
+
+    n_Delete(&sum1, r); n_Delete(&res, r);
+
+
+    s = n_Init(0  , r);
+    ss = n_Init(0 , r);
+    for( int k = N; k >= 0; k-- )
+    {
+      i = n_Init(k, r);
+      n_InpAdd(s, i, r); // s += i
+
+      i = n_InpNeg(i, r);
+      n_InpAdd(ss, i, r); // ss -= i
+
+      n_Delete(&i, r);
+    }
+    clog<< "ss: "; PrintSized(ss, r);
+
+    ss = n_InpNeg(ss, r); // ss = -ss
+
+    clog<< "real sum    : "; PrintSized(s, r);
+    clog<< "real sum(--): "; PrintSized(ss, r);
+
+    TS_ASSERT( n_Equal(s, ss, r) );
+    TS_ASSERT( n_Equal(ss, s, r) );
+
+    n_Delete(&s, r);
+    n_Delete(&ss, r);
+
+    clog << ( " >>> TEST DONE!" );
+    clog << endl;
+
+  }
+public:
+  void test_Z13_t()
+  {
+    clog << "Creating  Z/13[t]: " << endl;
+
+    char* n[] = {(char*)"t"};
+    ring r = rDefault( 13, 1, n);
+    TS_ASSERT_DIFFERS( r, NULLp );
+
+    PrintRing(r);
+
+    TS_ASSERT( rField_is_Domain(r) );
+    TS_ASSERT( !rField_is_Q(r) );
+
+    TS_ASSERT( rField_is_Zp(r) );
+    TS_ASSERT( !rField_is_Zp(r, 11) );
+    TS_ASSERT( rField_is_Zp(r, 13) );
+
+    TS_ASSERT_EQUALS( rVar(r), 1);
+
+    Test(r);
+
+    rDelete(r);
+  }
+
+  void test_QQ_t()
+  {
+    clog << "Creating  Q[s]: " << endl;
+
+    char* n[] = {(char*)"s"};
+    ring r = rDefault( 0, 1, n);
+    TS_ASSERT_DIFFERS( r, NULLp );
+
+    PrintRing(r);
+
+    TS_ASSERT( rField_is_Domain(r) );
+    TS_ASSERT( rField_is_Q(r) );
+
+    TS_ASSERT( !rField_is_Zp(r) );
+    TS_ASSERT( !rField_is_Zp(r, 11) );
+
+    TS_ASSERT_EQUALS( rVar(r), 1);
+
+    Test(r);
+
+    rDelete(r);
+  }
+
+  void test_Z11_x_y_z()
+  {
+     clog << "Creating  Z/11[x, y, z]: " << endl;
+
+     char* n[] = {(char*)"x", (char*)"y", (char*)"z"};
+     ring r = rDefault( 11, 3, n);
+     TS_ASSERT_DIFFERS( r, NULLp );
+
+     PrintRing(r);
+
+     TS_ASSERT( rField_is_Domain(r) );
+     TS_ASSERT( !rField_is_Q(r) );
+
+     TS_ASSERT( rField_is_Zp(r) );
+     TS_ASSERT( rField_is_Zp(r, 11) );
+     TS_ASSERT( !rField_is_Zp(r, 13) );
+
+     TS_ASSERT_EQUALS( rVar(r), 3);
+
+     Test(r);
+
+     rDelete(r);
+  }
+   void test_QQ_x_y_z()
+   {
+     clog << "Creating  QQ[x, y, z, u]: " << endl;
+
+     char* n[] = {(char*)"x", (char*)"y", (char*)"z", (char*)"u"};
+     ring r = rDefault( 0, 4, n);
+     TS_ASSERT_DIFFERS( r, NULLp );
+
+     PrintRing(r);
+
+     TS_ASSERT( rField_is_Domain(r) );
+     TS_ASSERT( rField_is_Q(r) );
+
+     TS_ASSERT( !rField_is_Zp(r) );
+     TS_ASSERT( !rField_is_Zp(r, 11) );
+
+     TS_ASSERT_EQUALS( rVar(r), 4);
+
+     Test(r);
+
+     rDelete(r);
+   }
+
+
+   void test_Z13_t_GF()
+   {
+     clog << "Creating  GF[t]: " << endl;
+
+     char* n[] = {(char*)"t"};
+
+     GFInfo param;
+
+     param.GFChar= 5;
+     param.GFDegree= 2;
+     param.GFPar_name= (const char*)"Q";
+
+     const coeffs cf = nInitChar( n_GF, &param );
+
+     if( cf == NULL )
+       TS_FAIL("Could not get needed coeff. domain");
+
+     TS_ASSERT_DIFFERS( cf, NULLp );
+
+     ring r = rDefault( cf, 1, n);  // now cf belongs to r!
+     TS_ASSERT_DIFFERS( r, NULLp );
+
+     PrintRing(r);
+
+     TS_ASSERT( rField_is_Domain(r) );
+     TS_ASSERT( !rField_is_Q(r) );
+
+     TS_ASSERT( !rField_is_Zp(r) );
+     TS_ASSERT( !rField_is_Zp(r, 11) );
+     TS_ASSERT( !rField_is_Zp(r, 13) );
+     TS_ASSERT( rField_is_GF(r) );
+
+     TS_ASSERT( rField_is_GF(r, 5) );
+     TS_ASSERT( !rField_is_GF(r, 25) );
+
+     TS_ASSERT_EQUALS( rVar(r), 1);
+
+     Test(r);
+
+     rDelete(r); // kills 'cf' as well!
+   }
+
+  void test_Q_Ext_a()
+  {
+    clog << "Start by creating Q[a]..." << endl;
+
+    char* n[] = {(char*)"a"};
+    ring r = rDefault( 0, 1, n);   // Q[a]
+    TS_ASSERT_DIFFERS( r, NULLp );
+
+    PrintRing(r);
+
+    TS_ASSERT( rField_is_Domain(r) );
+    TS_ASSERT( rField_is_Q(r) );
+
+    TS_ASSERT( !rField_is_Zp(r) );
+    TS_ASSERT( !rField_is_Zp(r, 11) );
+
+    TS_ASSERT_EQUALS( rVar(r), 1);
+
+    poly minPoly = p_ISet(1, r);                    // minPoly = 1
+    p_SetExp(minPoly, 1, 2, r); p_Setm(minPoly, r); // minPoly = a^2
+    minPoly = p_Add_q(minPoly, p_ISet(1, r), r);    // minPoly = a^2 + 1
+    ideal minIdeal = idInit(1);                     // minIdeal = < 0 >
+    minIdeal->m[0] = minPoly;                       // minIdeal = < a^2 + 1 >
+
+    n_coeffType type = nRegister(n_algExt, naInitChar);
+    TS_ASSERT(type == n_algExt);
+
+    r->qideal = minIdeal;
+    AlgExtInfo extParam;
+    extParam.r = r;
+
+    clog << "Next create the extension field Q[a]/<a2+1>..." << endl;
+
+    const coeffs cf = nInitChar(type, &extParam);   // Q[a]/<a2+1>
+
+    if( cf == NULL )
+      TS_FAIL("Could not get needed coeff. domain");
+
+    TS_ASSERT_DIFFERS( cf->cfCoeffWrite, NULLp );
+
+    if( cf->cfCoeffWrite != NULL )
+    {
+      clog << "Coeff-domain: "  << endl;
+      n_CoeffWrite(cf); PrintLn();
+    }
+
+    TS_ASSERT( nCoeff_is_algExt(cf) );
+    TS_ASSERT( !nCoeff_is_transExt(cf) );
+
+    // some tests for the coefficient field represented by cf:
+    TestArithCf(cf);
+    TestSumCf(cf, 10);
+    TestSumCf(cf, 100);
+    TestSumCf(cf, 101);
+    TestSumCf(cf, 1001);
+    TestSumCf(cf, 2000);
+
+    clog << "Finally create the polynomial ring (Q[a]/<a2+1>)[x, y]..."
+         << endl;
+
+    char* m[] = {(char*)"x", (char*)"y"};
+    ring s = rDefault(cf, 2, m);   // (Q[a]/<a2+1>)[x, y]
+    TS_ASSERT_DIFFERS(s, NULLp);
+
+    PrintRing(s);
+
+    TS_ASSERT( rField_is_Domain(s) );
+    TS_ASSERT( !rField_is_Q(s) );
+    TS_ASSERT( !rField_is_Zp(s) );
+    TS_ASSERT( !rField_is_Zp(s, 11) );
+    TS_ASSERT( !rField_is_Zp(s, 13) );
+    TS_ASSERT( !rField_is_GF(s) );
+    TS_ASSERT( (s->cf->extRing!=NULL) );
+    TS_ASSERT( !rField_is_GF(s, 25) );
+    TS_ASSERT_EQUALS(rVar(s), 2);
+
+    Test(s);
+
+    clog << endl
+         << "Now let's compute some inverses in Q[a]/<a^2+1>..."
+         << endl;
+
+    poly u;
+    u = NULL; plusTerm(u, 1, 1, 1, cf->extRing);
+    plusTerm(u, 1, 1, 0, cf->extRing);  // a + 1
+    checkInverse((number)u, cf); p_Delete(&u, cf->extRing);
+    u = NULL; plusTerm(u, 1, 1, 1, cf->extRing);
+    plusTerm(u, -1, 1, 0, cf->extRing); // a - 1
+    checkInverse((number)u, cf); p_Delete(&u, cf->extRing);
+    u = NULL; plusTerm(u, 1, 1, 1, cf->extRing);
+    plusTerm(u, 5, 1, 0, cf->extRing);  // a + 5
+    checkInverse((number)u, cf); p_Delete(&u, cf->extRing);
+    u = NULL; plusTerm(u, 1, 1, 1, cf->extRing);
+    plusTerm(u, -5, 1, 0, cf->extRing); // a - 5
+    checkInverse((number)u, cf); p_Delete(&u, cf->extRing);
+    u = NULL; plusTerm(u, 17, 1, 1, cf->extRing);
+    plusTerm(u, 5, 1, 0, cf->extRing); // 17a + 5
+    checkInverse((number)u, cf); p_Delete(&u, cf->extRing);
+
+    rDelete(s); // kills 'cf' and 'r' as well
+  }
+  void test_Q_Ext_b()
+  {
+    clog << "Start by creating Q[b]..." << endl;
+
+    char* n[] = {(char*)"b"};
+    ring r = rDefault( 0, 1, n);   // Q[b]
+    TS_ASSERT_DIFFERS( r, NULLp );
+
+    PrintRing(r);
+
+    TS_ASSERT( rField_is_Domain(r) );
+    TS_ASSERT( rField_is_Q(r) );
+
+    TS_ASSERT( !rField_is_Zp(r) );
+    TS_ASSERT( !rField_is_Zp(r, 11) );
+
+    TS_ASSERT_EQUALS( rVar(r), 1);
+
+    poly minPoly = p_ISet(1, r);                    // minPoly = 1
+    p_SetExp(minPoly, 1, 7, r); p_Setm(minPoly, r); // minPoly = b^7
+    minPoly = p_Add_q(minPoly, p_ISet(17, r), r);   // minPoly = b^7 + 17
+    ideal minIdeal = idInit(1);                     // minIdeal = < 0 >
+    minIdeal->m[0] = minPoly;                       // minIdeal = < b^7 + 17 >
+
+    n_coeffType type = nRegister(n_algExt, naInitChar);
+    TS_ASSERT(type == n_algExt);
+
+    r->qideal = minIdeal;
+    AlgExtInfo extParam;
+    extParam.r = r;
+
+    clog << "Next create the extension field Q[b]/<b^7+17>..." << endl;
+
+    const coeffs cf = nInitChar(type, &extParam);   // Q[b]/<b^7+17>
+
+    if( cf == NULL )
+      TS_FAIL("Could not get needed coeff. domain");
+
+    TS_ASSERT_DIFFERS( cf->cfCoeffWrite, NULLp );
+
+    if( cf->cfCoeffWrite != NULL )
+    {
+      clog << "Coeff-domain: "  << endl;
+      n_CoeffWrite(cf); PrintLn();
+    }
+
+    TS_ASSERT( nCoeff_is_algExt(cf) );
+    TS_ASSERT( !nCoeff_is_transExt(cf) );
+
+    // some tests for the coefficient field represented by cf:
+    TestArithCf(cf);
+    TestSumCf(cf, 10);
+    TestSumCf(cf, 100);
+    TestSumCf(cf, 101);
+    TestSumCf(cf, 1001);
+    TestSumCf(cf, 9000);
+
+    clog << "Finally create the polynomial ring (Q[b]/<b^7+17>)[u, v, w]..."
+         << endl;
+
+    char* m[] = {(char*)"u", (char*)"v", (char*)"w"};
+    ring s = rDefault(cf, 3, m);   // (Q[b]/<b^7+17>)[u, v, w]
+    TS_ASSERT_DIFFERS(s, NULLp);
+
+    PrintRing(s);
+
+    TS_ASSERT( rField_is_Domain(s) );
+    TS_ASSERT( !rField_is_Q(s) );
+    TS_ASSERT( !rField_is_Zp(s) );
+    TS_ASSERT( !rField_is_Zp(s, 11) );
+    TS_ASSERT( !rField_is_Zp(s, 13) );
+    TS_ASSERT( !rField_is_GF(s) );
+    TS_ASSERT( (s->cf->extRing!=NULL) );
+    TS_ASSERT( !rField_is_GF(s, 25) );
+    TS_ASSERT_EQUALS(rVar(s), 3);
+
+    Test(s);
+
+    clog << endl
+         << "Now let's compute some inverses in Q[b]/<b^7+17>..."
+         << endl;
+
+    poly u;
+    u = NULL; plusTerm(u, 1, 1, 2, cf->extRing);
+    plusTerm(u, 33, 1, 0, cf->extRing);     // b^2 + 33
+    checkInverse((number)u, cf); p_Delete(&u, cf->extRing);
+    u = NULL; plusTerm(u, 1, 1, 5, cf->extRing);
+    plusTerm(u, -137, 1, 0, cf->extRing);   // b^5 - 137
+    checkInverse((number)u, cf); p_Delete(&u, cf->extRing);
+
+    clog << endl
+         << "Now let's check a gcd computation in Q[b]..."
+         << endl;
+
+    poly v;
+    v = NULL; plusTerm(v, 1, 1, 2, cf->extRing);
+    plusTerm(v, 7, 1, 1, cf->extRing);
+    plusTerm(v, 1, 1, 0, cf->extRing);            // b^2 + 7b + 1
+    number w = n_Mult((number)v, (number)v, cf);  // (b^2 + 7b + 1)^2
+    number y = n_Mult((number)v, (number)w, cf);  // (b^2 + 7b + 1)^3
+    p_Delete(&v, cf->extRing);
+    v = NULL; plusTerm(v, 2, 1, 2, cf->extRing);
+    plusTerm(v, -61, 1, 1, cf->extRing);          // 2b^2 - 61b
+    number z = n_Mult((number)w,
+                      (number)v, cf);   // (b^2 + 7b + 1)^2 * (2b^2 - 61b)
+    p_Delete(&v, cf->extRing);
+
+    clog << "z = "; p_Write((poly)z, cf->extRing);
+    clog << "y = "; p_Write((poly)y, cf->extRing);
+    number theGcd = n_Gcd(z, y, cf);   // should yield w = (b^2 + 7b + 1)^2
+    clog << "gcd(z, y) = "; p_Write((poly)theGcd, cf->extRing);
+
+    v = (poly)n_Sub(theGcd, w, cf);
+//    TS_ASSERT( v == NULL );
+    p_Delete(&v, cf->extRing);
+
+    clog << endl
+         << "Now let's check an ext_gcd computation in Q[b]..."
+         << endl;
+
+    poly zFactor; poly yFactor;
+    poly ppp = p_ExtGcd((poly)z, zFactor, (poly)y, yFactor, cf->extRing);
+    v = (poly)n_Sub(theGcd, (number)ppp, cf);
+//    TS_ASSERT( v == NULL );
+    p_Delete(&v, cf->extRing);
+    clog << "z = "; p_Write((poly)z, cf->extRing);
+    clog << "zFactor = "; p_Write(zFactor, cf->extRing);
+    clog << "y = "; p_Write((poly)y, cf->extRing);
+    clog << "yFactor = "; p_Write((poly)yFactor, cf->extRing);
+    number v1 = n_Mult(z, (number)zFactor, cf);
+    number v2 = n_Mult(y, (number)yFactor, cf);
+    number v3 = n_Add(v1, v2, cf);
+    clog << "z * zFactor + y * yFactor = "; p_Write((poly)v3, cf->extRing);
+    clog << "gcd(z, y) = "; p_Write(ppp, cf->extRing);
+    number v4 = n_Sub(v3, w, cf);
+    TS_ASSERT( v4 == NULL );
+
+    p_Delete(&ppp, cf->extRing); p_Delete(&zFactor, cf->extRing);
+    p_Delete(&yFactor, cf->extRing);
+    n_Delete(&z, cf); n_Delete(&y, cf); n_Delete(&w, cf);
+    n_Delete(&theGcd, cf); p_Delete(&v, cf->extRing); n_Delete(&v1, cf);
+    n_Delete(&v2, cf); n_Delete(&v3, cf); n_Delete(&v4, cf);
+
+    rDelete(s); // kills 'cf' and 'r' as well
+  }
+  void test_Z_17_Ext_a()
+  {
+    clog << "Start by creating Z_17[a]..." << endl;
+
+    char* n[] = {(char*)"a"};
+    ring r = rDefault( 17, 1, n);   // Z/17Z[a]
+    TS_ASSERT_DIFFERS( r, NULLp );
+
+    PrintRing(r);
+
+    TS_ASSERT( rField_is_Domain(r) );
+    TS_ASSERT( !rField_is_Q(r) );
+
+    TS_ASSERT( rField_is_Zp(r) );
+    TS_ASSERT( rField_is_Zp(r, 17) );
+
+    TS_ASSERT_EQUALS( rVar(r), 1);
+
+    poly minPoly = p_ISet(1, r);                    // minPoly = 1
+    p_SetExp(minPoly, 1, 2, r); p_Setm(minPoly, r); // minPoly = a^2
+    minPoly = p_Add_q(minPoly, p_ISet(3, r), r);    // minPoly = a^2 + 3
+    ideal minIdeal = idInit(1);                     // minIdeal = < 0 >
+    minIdeal->m[0] = minPoly;                       // minIdeal = < a^2 + 3 >
+
+    n_coeffType type = nRegister(n_algExt, naInitChar);
+    TS_ASSERT(type == n_algExt);
+
+    r->qideal = minIdeal;
+    AlgExtInfo extParam;
+    extParam.r = r;
+
+    clog << "Next create the extension field Z_17[a]/<a^2+3>..." << endl;
+
+    const coeffs cf = nInitChar(type, &extParam);   // Z_17[a]/<a^2+3>
+
+    if( cf == NULL )
+      TS_FAIL("Could not get needed coeff. domain");
+
+    TS_ASSERT_DIFFERS( cf->cfCoeffWrite, NULLp );
+
+    if( cf->cfCoeffWrite != NULL )
+    {
+      clog << "Coeff-domain: "  << endl;
+      n_CoeffWrite(cf); PrintLn();
+    }
+
+    TS_ASSERT( nCoeff_is_algExt(cf) );
+    TS_ASSERT( !nCoeff_is_transExt(cf) );
+
+    // some tests for the coefficient field represented by cf:
+    TestArithCf(cf);
+    TestSumCf(cf, 10);
+    TestSumCf(cf, 100);
+    TestSumCf(cf, 101);
+    TestSumCf(cf, 1001);
+    TestSumCf(cf, 9000);
+
+    clog << "Finally create the polynomial ring (Z_17[a]/<a^2+3>)[u, v, w]..."
+         << endl;
+
+    char* m[] = {(char*)"u", (char*)"v", (char*)"w"};
+    ring s = rDefault(cf, 3, m);   // (Z_17[a]/<a^2+3>)[u, v, w]
+    TS_ASSERT_DIFFERS(s, NULLp);
+
+    PrintRing(s);
+
+    TS_ASSERT( rField_is_Domain(s) );
+    TS_ASSERT( !rField_is_Q(s) );
+    TS_ASSERT( !rField_is_Zp(s) );
+    TS_ASSERT( !rField_is_Zp(s, 11) );
+    TS_ASSERT( !rField_is_Zp(s, 17) );
+    TS_ASSERT( !rField_is_GF(s) );
+    TS_ASSERT( (s->cf->extRing!=NULL) );
+    TS_ASSERT( !rField_is_GF(s, 25) );
+    TS_ASSERT_EQUALS(rVar(s), 3);
+
+    Test(s);
+
+    rDelete(s); // kills 'cf' and 'r' as well
+  }
+  void test_Q_Ext_s_t()
+  {
+    clog << "Start by creating Q[s, t]..." << endl;
+
+    char* n[] = {(char*)"s", (char*)"t"};
+    ring r = rDefault( 0, 2, n);   // Q[s, t]
+    TS_ASSERT_DIFFERS( r, NULLp );
+
+    PrintRing(r);
+
+    TS_ASSERT( rField_is_Domain(r) );
+    TS_ASSERT( rField_is_Q(r) );
+
+    TS_ASSERT( !rField_is_Zp(r) );
+    TS_ASSERT( !rField_is_Zp(r, 17) );
+
+    TS_ASSERT_EQUALS( rVar(r), 2);
+
+    n_coeffType type = nRegister(n_transExt, ntInitChar);
+    TS_ASSERT(type == n_transExt);
+
+    TransExtInfo extParam;
+    extParam.r = r;
+
+    clog << "Next create the rational function field Q(s, t)..." << endl;
+
+    const coeffs cf = nInitChar(type, &extParam);   // Q(s, t)
+
+    if( cf == NULL )
+      TS_FAIL("Could not get needed coeff. domain");
+
+    TS_ASSERT_DIFFERS( cf->cfCoeffWrite, NULLp );
+
+    if( cf->cfCoeffWrite != NULL )
+    {
+      clog << "Coeff-domain: "  << endl;
+      n_CoeffWrite(cf); PrintLn();
+    }
+
+    TS_ASSERT( !nCoeff_is_algExt(cf) );
+    TS_ASSERT( nCoeff_is_transExt(cf) );
+
+    // some tests for the coefficient field represented by cf:
+    TestArithCf(cf);
+    TestSumCf(cf, 10);
+    TestSumCf(cf, 100);
+    TestSumCf(cf, 101);
+    TestSumCf(cf, 1001);
+    TestSumCf(cf, 9000);
+
+    clog << "Finally create the polynomial ring Q(s, t)[x, y, z]..."
+         << endl;
+
+    char* m[] = {(char*)"x", (char*)"y", (char*)"z"};
+    ring s = rDefault(cf, 3, m);   // Q(s, t)[x, y, z]
+    TS_ASSERT_DIFFERS(s, NULLp);
+
+    PrintRing(s);
+
+    TS_ASSERT( rField_is_Domain(s) );
+    TS_ASSERT( !rField_is_Q(s) );
+    TS_ASSERT( !rField_is_Zp(s) );
+    TS_ASSERT( !rField_is_Zp(s, 11) );
+    TS_ASSERT( !rField_is_Zp(s, 17) );
+    TS_ASSERT( !rField_is_GF(s) );
+    TS_ASSERT( (s->cf->extRing!=NULL) );
+    TS_ASSERT( !rField_is_GF(s, 25) );
+    TS_ASSERT_EQUALS(rVar(s), 3);
+
+    Test(s);
+
+    /* some special tests: */
+    poly v1 = NULL;
+    plusTerm(v1, 1, 1, 1, cf->extRing);       // s
+    plusTerm(v1, 1, 1, 0, cf->extRing);       // s + 1
+    poly v2 = NULL;
+    plusTerm(v2, 1, 1, 1, cf->extRing);       // s
+    plusTerm(v2, 2, 2, 1, cf->extRing);       // s + 2t
+    poly v = p_Mult_q(v1, v2, cf->extRing);   // (s + 1) * (s + 2t)
+    number v_n = toFractionNumber(v, cf);
+    PrintSized(v_n, cf);
+    poly w1 = NULL;
+    plusTerm(w1, 1, 1, 1, cf->extRing);       // s
+    plusTerm(w1, 1, 1, 0, cf->extRing);       // s + 1
+    poly w2 = NULL;
+    plusTerm(w2, 3, 1, 1, cf->extRing);       // 3s
+    plusTerm(w2, -7, 2, 1, cf->extRing);      // 3s - 7t
+    poly w = p_Mult_q(w1, w2, cf->extRing);   // (s + 1) * (3s - 7t)
+    number w_n = toFractionNumber(w, cf);
+    PrintSized(w_n, cf);
+    number vOverW_n = n_Div(v_n, w_n, cf);
+    PrintSized(vOverW_n, cf);
+    number wOverV_n = n_Invers(vOverW_n, cf);
+    PrintSized(wOverV_n, cf);
+    number prod = n_Mult(vOverW_n, wOverV_n, cf);
+    PrintSized(prod, cf);
+    number tmp; number nn = n_Copy(vOverW_n, cf);
+    for (int i = 1; i <= 6; i++)
+    {
+      tmp = n_Div(nn, v_n, cf);
+      n_Delete(&nn, cf);
+      nn = tmp;
+      clog << i << ". "; PrintSized(nn, cf);
+    }
+
+    n_Delete(&prod, cf); n_Delete(&nn, cf);
+    n_Delete(&v_n, cf); n_Delete(&w_n, cf);
+    n_Delete(&vOverW_n, cf); n_Delete(&wOverV_n, cf);
+
+    rDelete(s); // kills 'cf' and 'r' as well
+  }
+  void test_Q_Ext_Performance()
+  {
+    clog << "Start by creating Q[q]..." << endl;
+
+    char* n[] = {(char*)"q"};
+    ring r = rDefault( 0, 1, n);   // Q[q]
+    r->order[0] = ringorder_dp;
+    TS_ASSERT_DIFFERS( r, NULLp );
+
+    PrintRing(r);
+
+    TS_ASSERT( rField_is_Domain(r) );
+    TS_ASSERT( rField_is_Q(r) );
+
+    TS_ASSERT( !rField_is_Zp(r) );
+    TS_ASSERT( !rField_is_Zp(r, 17) );
+
+    TS_ASSERT_EQUALS( rVar(r), 1);
+
+    n_coeffType type = nRegister(n_transExt, ntInitChar);
+    TS_ASSERT(type == n_transExt);
+
+    TransExtInfo extParam;
+    extParam.r = r;
+
+    clog << "Next create the rational function field Q(q)..." << endl;
+
+    const coeffs cf = nInitChar(type, &extParam);   // Q(q)
+
+    if( cf == NULL )
+      TS_FAIL("Could not get needed coeff. domain");
+
+    TS_ASSERT_DIFFERS( cf->cfCoeffWrite, NULLp );
+
+    if( cf->cfCoeffWrite != NULL )
+    {
+      clog << "Coeff-domain: "  << endl;
+      n_CoeffWrite(cf); PrintLn();
+    }
+
+    TS_ASSERT( !nCoeff_is_algExt(cf) );
+    TS_ASSERT( nCoeff_is_transExt(cf) );
+
+    // some tests for the coefficient field represented by cf:
+    TestArithCf(cf);
+    TestSumCf(cf, 10);
+    TestSumCf(cf, 100);
+    TestSumCf(cf, 101);
+    TestSumCf(cf, 1001);
+    TestSumCf(cf, 9000);
+
+    clog << "Finally create the polynomial ring Q(q)[t]..."
+         << endl;
+
+    char* m[] = {(char*)"t"};
+    ring s = rDefault(cf, 1, m);   // Q(q)[t]
+    s->order[0] = ringorder_dp;
+    TS_ASSERT_DIFFERS(s, NULLp);
+
+    PrintRing(s);
+
+    TS_ASSERT( rField_is_Domain(s) );
+    TS_ASSERT( !rField_is_Q(s) );
+    TS_ASSERT( !rField_is_Zp(s) );
+    TS_ASSERT( !rField_is_Zp(s, 11) );
+    TS_ASSERT( !rField_is_Zp(s, 17) );
+    TS_ASSERT( !rField_is_GF(s) );
+    TS_ASSERT( (s->cf->extRing!=NULL) );
+    TS_ASSERT( !rField_is_GF(s, 25) );
+    TS_ASSERT_EQUALS(rVar(s), 1);
+
+    Test(s);
+
+    /* a special performance test: */
+    poly entry = NULL;
+    for (int ti = 0; ti <= 20; ti++)
+    {
+      for (int qi = 0; qi <= 100; qi++)
+      {
+        int c = rand() % 1000000;
+        poly qterm = p_ISet(c, r); p_SetExp(qterm, 1, qi, r);
+        p_Setm(qterm, r);
+        number qtermAsN = toFractionNumber(qterm, cf);
+        poly tterm = p_ISet(1, s); p_SetExp(tterm, 1, ti, s);
+        p_Setm(tterm, r); p_SetCoeff(tterm, qtermAsN, s);
+        entry = p_Add_q(entry, tterm, s);
+      }
+    }
+    p_Write(entry, s);
+    poly qfactor = p_ISet(1, r); p_SetExp(qfactor, 1, 66, r);
+    p_Setm(qfactor, r);   /* q^66 */
+    number qfactorAsN = toFractionNumber(qfactor, cf);
+    number uuu = n_Invers(qfactorAsN, cf);   /* 1 / q^66 */
+    poly factor = p_ISet(1, s); p_SetCoeff(factor, uuu, s);   /* 1 / q^66 */
+    p_Write(factor, s);
+    clog << "starting multiplication..." << endl;
+    poly theProduct = p_Mult_q(entry, factor, s);
+    p_Write(theProduct, s);
+    clog << "...ending multiplication" << endl;
+    n_Delete(&qfactorAsN, cf); p_Delete(&theProduct, s);
+
+    /* a very special performance test: */
+    specialPoly(entry, s);
+    p_Write(entry, s);
+    qfactor = p_ISet(1, r); p_SetExp(qfactor, 1, 66, r);
+    p_Setm(qfactor, r);   /* q^66 */
+    qfactorAsN = toFractionNumber(qfactor, cf);
+    uuu = n_Invers(qfactorAsN, cf);   /* 1 / q^66 */
+    factor = p_ISet(1, s); p_SetCoeff(factor, uuu, s);   /* 1 / q^66 */
+    p_Write(factor, s);
+    clog << "starting very special multiplication..." << endl;
+    /* The following multiplication + output of the product is very slow
+       in the svn/trunk SINGULAR version; see trac ticket #308.
+       Here, in the Spielwiese, the result is instantaneous. */
+    theProduct = p_Mult_q(entry, factor, s);
+    p_Write(theProduct, s);
+    clog << "...ending very special multiplication" << endl;
+    n_Delete(&qfactorAsN, cf); p_Delete(&theProduct, s);
+
+    rDelete(s); // kills 'cf' and 'r' as well
+  }
+  void test_Q_Ext_s_t_NestedFractions()
+  {
+    clog << "Start by creating Q[s, t]..." << endl;
+
+    char* n[] = {(char*)"s", (char*)"t"};
+    ring r = rDefault( 0, 2, n);   // Q[s, t]
+    TS_ASSERT_DIFFERS( r, NULLp );
+
+    PrintRing(r);
+
+    TS_ASSERT( rField_is_Domain(r) );
+    TS_ASSERT( rField_is_Q(r) );
+
+    TS_ASSERT( !rField_is_Zp(r) );
+    TS_ASSERT( !rField_is_Zp(r, 17) );
+
+    TS_ASSERT_EQUALS( rVar(r), 2);
+
+    n_coeffType type = nRegister(n_transExt, ntInitChar);
+    TS_ASSERT(type == n_transExt);
+
+    TransExtInfo extParam;
+    extParam.r = r;
+
+    clog << "Next create the rational function field Q(s, t)..." << endl;
+
+    const coeffs cf = nInitChar(type, &extParam);   // Q(s, t)
+
+    if( cf == NULL )
+      TS_FAIL("Could not get needed coeff. domain");
+
+    TS_ASSERT_DIFFERS( cf->cfCoeffWrite, NULLp );
+
+    if( cf->cfCoeffWrite != NULL )
+    {
+      clog << "Coeff-domain: "  << endl;
+      n_CoeffWrite(cf); PrintLn();
+    }
+
+    TS_ASSERT( !nCoeff_is_algExt(cf) );
+    TS_ASSERT( nCoeff_is_transExt(cf) );
+
+    clog << "Finally create the polynomial ring Q(s, t)[x, y, z]..."
+         << endl;
+
+    char* m[] = {(char*)"x", (char*)"y", (char*)"z"};
+    ring s = rDefault(cf, 3, m);   // Q(s, t)[x, y, z]
+    TS_ASSERT_DIFFERS(s, NULLp);
+
+    PrintRing(s);
+
+    TS_ASSERT( rField_is_Domain(s) );
+    TS_ASSERT( !rField_is_Q(s) );
+    TS_ASSERT( !rField_is_Zp(s) );
+    TS_ASSERT( !rField_is_Zp(s, 11) );
+    TS_ASSERT( !rField_is_Zp(s, 17) );
+    TS_ASSERT( !rField_is_GF(s) );
+    TS_ASSERT( (s->cf->extRing!=NULL) );
+    TS_ASSERT( !rField_is_GF(s, 25) );
+    TS_ASSERT_EQUALS(rVar(s), 3);
+
+    /* test 1 for nested fractions, i.e. fractional coefficients: */
+    poly v1 = NULL;
+    plusTermOverQ(v1, 21, 2, 1, 1, cf->extRing);       // 21/2*s
+    plusTermOverQ(v1, 14, 3, 1, 0, cf->extRing);       // 21/2*s + 14/3
+    number v1_n = toFractionNumber(v1, cf);
+    PrintSized(v1_n, cf);
+    poly v2 = NULL;
+    plusTermOverQ(v2, 7, 5, 1, 1, cf->extRing);       // 7/5*s
+    plusTermOverQ(v2, -49, 6, 2, 1, cf->extRing);     // 7/5*s - 49/6*t
+    number v2_n = toFractionNumber(v2, cf);
+    PrintSized(v2_n, cf);
+    number v3_n = n_Div(v1_n, v2_n, cf);   // (45*s + 20) / (6s - 35*t)
+    PrintSized(v3_n, cf);
+    n_Delete(&v1_n, cf); n_Delete(&v2_n, cf); n_Delete(&v3_n, cf);
+
+    /* test 2 for nested fractions, i.e. fractional coefficients: */
+    v1 = NULL;
+    plusTermOverQ(v1, 1, 2, 1, 1, cf->extRing);       // 1/2*s
+    plusTermOverQ(v1, 1, 1, 1, 0, cf->extRing);       // 1/2*s + 1
+    v2 = NULL;
+    plusTermOverQ(v2, 1, 1, 1, 1, cf->extRing);       // s
+    plusTermOverQ(v2, 2, 3, 2, 1, cf->extRing);       // s + 2/3*t
+    poly v3 = p_Mult_q(v1, v2, cf->extRing);   // (1/2*s + 1) * (s + 2/3*t)
+    number v_n = toFractionNumber(v3, cf);
+    PrintSized(v_n, cf);
+    poly w1 = NULL;
+    plusTermOverQ(w1, 1, 2, 1, 1, cf->extRing);       // 1/2*s
+    plusTermOverQ(w1, 1, 1, 1, 0, cf->extRing);       // 1/2*s + 1
+    poly w2 = NULL;
+    plusTermOverQ(w2, -7, 5, 1, 0, cf->extRing);      // -7/5
+    poly w3 = p_Mult_q(w1, w2, cf->extRing);   // (1/2*s + 1) * (-7/5)
+    number w_n = toFractionNumber(w3, cf);
+    PrintSized(w_n, cf);
+    number z_n = n_Div(v_n, w_n, cf);          // -5/7*s - 10/21*t
+    PrintSized(z_n, cf);
+    n_Delete(&v_n, cf); n_Delete(&w_n, cf); n_Delete(&z_n, cf);
+
+    rDelete(s); // kills 'cf' and 'r' as well
+  }
+};
+
diff --git a/libpolys/tests/rings_test.h b/libpolys/tests/rings_test.h
new file mode 100644
index 0000000..f8a66b5
--- /dev/null
+++ b/libpolys/tests/rings_test.h
@@ -0,0 +1,239 @@
+#include "common.h"
+using namespace std;
+
+// the following headers are private...
+
+
+#include <polys/monomials/ring.h>
+#include <polys/monomials/p_polys.h>
+
+
+
+
+class MyGlobalPrintingFixture : public GlobalPrintingFixture
+{
+  public:
+    virtual bool setUpWorld()
+    {
+
+      GlobalPrintingFixture::setUpWorld();
+
+
+      //TS_ASSERT_EQUALS( nRegister( n_Zp, npInitChar), n_Zp );
+      //TS_ASSERT_EQUALS( nRegister( n_GF, nfInitChar), n_GF );
+      //TS_ASSERT_EQUALS( nRegister( n_R, nrInitChar), n_R );
+      //TS_ASSERT_EQUALS( nRegister( n_Q, nlInitChar), n_Q );
+      //TS_ASSERT_EQUALS( nRegister( n_R, nrInitChar), n_R );
+
+#ifdef HAVE_RINGS
+      //TS_ASSERT_EQUALS( nRegister( n_Z, nrzInitChar), n_Z ); // these are UNusable at the moment!
+#endif
+
+      return true;
+    }
+};
+
+
+//
+// We can rely on this file being included exactly once
+// and declare this global variable in the header file.
+//
+static MyGlobalPrintingFixture globalPrintingFixture;
+
+
+namespace
+{
+  void PrintRing(const ring r)
+  {
+    rWrite(r); PrintLn();
+#ifdef RDEBUG
+    rDebugPrint(r); PrintLn();
+#endif
+  }
+static inline void Test(const ring)
+{
+  // does nothing yet...
+}
+
+}
+
+class PolysTestSuite : public CxxTest::TestSuite
+{
+public:
+  void test_Z13_t()
+  {
+    clog << "Creating  Z/13[t]: " << endl;
+
+    char* n[] = { (char*)"t"};
+    ring r = rDefault( 13, 1, n);
+    TS_ASSERT_DIFFERS( r, NULLp );
+
+    PrintRing(r);
+
+    TS_ASSERT( rField_is_Domain(r) );
+    TS_ASSERT( !rField_is_Q(r) );
+
+    TS_ASSERT( rField_is_Zp(r) );
+    TS_ASSERT( !rField_is_Zp(r, 11) );
+    TS_ASSERT( rField_is_Zp(r, 13) );
+
+    TS_ASSERT_EQUALS( rVar(r), 1);
+
+    Test(r);
+
+    rDelete(r);
+  }
+
+  void test_QQ_t()
+  {
+    clog << "Creating  Q[s]: " << endl;
+
+    char* n[] = {(char*)"s"};
+    ring r = rDefault( 0, 1, n);
+    TS_ASSERT_DIFFERS( r, NULLp );
+
+    PrintRing(r);
+
+    TS_ASSERT( rField_is_Domain(r) );
+    TS_ASSERT( rField_is_Q(r) );
+
+    TS_ASSERT( !rField_is_Zp(r) );
+    TS_ASSERT( !rField_is_Zp(r, 11) );
+
+    TS_ASSERT_EQUALS( rVar(r), 1);
+
+    Test(r);
+
+    rDelete(r);
+  }
+
+  void test_Z11_x_y_z()
+  {
+     clog << "Creating  Z/11[x, y, z]: " << endl;
+
+     char* n[] = {(char*)"x", (char*)"y", (char*)"z"};
+     ring r = rDefault( 11, 3, n);
+     TS_ASSERT_DIFFERS( r, NULLp );
+
+     PrintRing(r);
+
+     TS_ASSERT( rField_is_Domain(r) );
+     TS_ASSERT( !rField_is_Q(r) );
+
+     TS_ASSERT( rField_is_Zp(r) );
+     TS_ASSERT( rField_is_Zp(r, 11) );
+     TS_ASSERT( !rField_is_Zp(r, 13) );
+
+     TS_ASSERT_EQUALS( rVar(r), 3);
+
+     Test(r);
+
+     rDelete(r);
+  }
+
+  void test_QQ_x_y_z()
+  {
+     clog << "Creating  QQ[x, y, z, u]: " << endl;
+
+     char* n[] = {(char*)"x", (char*)"y", (char*)"z", (char*)"u"};
+     ring r = rDefault( 0, 4, n);
+     TS_ASSERT_DIFFERS( r, NULLp );
+
+     PrintRing(r);
+
+     TS_ASSERT( rField_is_Domain(r) );
+     TS_ASSERT( rField_is_Q(r) );
+
+     TS_ASSERT( !rField_is_Zp(r) );
+     TS_ASSERT( !rField_is_Zp(r, 11) );
+
+     TS_ASSERT_EQUALS( rVar(r), 4);
+
+     Test(r);
+
+     rDelete(r);
+   }
+
+
+   void test_Z13_t_GF()
+   {
+     clog << "Creating  GF[t]: " << endl;
+
+     char* n[] = {(char*)"t"};
+
+     GFInfo param;
+
+     param.GFChar= 5;
+     param.GFDegree= 2;
+     param.GFPar_name= (const char*)"Q";
+
+     const coeffs cf = nInitChar( n_GF, &param );
+
+     TS_ASSERT_DIFFERS( cf, NULLp );
+
+     ring r = rDefault( cf, 1, n);  // now cf belongs to r!
+     TS_ASSERT_DIFFERS( r, NULLp );
+
+     PrintRing(r);
+
+     TS_ASSERT( rField_is_Domain(r) );
+     TS_ASSERT( !rField_is_Q(r) );
+
+     TS_ASSERT( !rField_is_Zp(r) );
+     TS_ASSERT( !rField_is_Zp(r, 11) );
+     TS_ASSERT( !rField_is_Zp(r, 13) );
+     TS_ASSERT( rField_is_GF(r) );
+
+     TS_ASSERT( rField_is_GF(r, 5) );
+     TS_ASSERT( !rField_is_GF(r, 25) );
+
+     TS_ASSERT_EQUALS( rVar(r), 1);
+
+     Test(r);
+
+     rDelete(r); // kills 'cf' as well!
+   }
+
+
+
+
+
+  void test_QQ_x_y_z_ord_2_lp()
+  {
+     clog << "Creating  QQ[x, y, z, u]: " << endl;
+
+     const int N = 4;
+     char* n[N] = {(char*)"x", (char*)"y", (char*)"z", (char*)"u"};
+
+
+     const int D = 2;
+     /*order: lp,0*/
+     int *order = (int *) omAlloc0(D* sizeof(int));
+     int *block0 = (int *)omAlloc0(D * sizeof(int));
+     int *block1 = (int *)omAlloc0(D * sizeof(int));
+     /* ringorder dp for the first block: var 1..N */
+     order[0]  = ringorder_dp;
+     block0[0] = 1;
+     block1[0] = N;
+     /* the last block: everything is 0 */
+//     order[1]  = 0;
+
+     ring r = rDefault(0, N, n, D, order, block0, block1);
+     TS_ASSERT_DIFFERS( r, NULLp );
+
+     PrintRing(r);
+
+     TS_ASSERT( rField_is_Domain(r) );
+     TS_ASSERT( rField_is_Q(r) );
+
+     TS_ASSERT( !rField_is_Zp(r) );
+     TS_ASSERT( !rField_is_Zp(r, 11) );
+
+     TS_ASSERT_EQUALS( rVar(r), N);
+
+     Test(r);
+
+     rDelete(r);
+   }
+};
+
diff --git a/libpolys/tests/simple_test.h b/libpolys/tests/simple_test.h
new file mode 100644
index 0000000..ba82951
--- /dev/null
+++ b/libpolys/tests/simple_test.h
@@ -0,0 +1,21 @@
+
+
+
+#include <misc/auxiliary.h>
+
+class SimplestTestSuite : public CxxTest::TestSuite
+{
+public:
+   void testMyTest()
+   {
+		float fnum = 2.00001f;
+		TS_ASSERT_DELTA (fnum, 2.0f, 0.0001f);
+   }
+
+   void testSIZEOFLONG()
+   {
+      TS_ASSERT( sizeof(long) == SIZEOF_LONG ); // correct config.h?
+   }
+
+};
+
diff --git a/libsingular-config.in b/libsingular-config.in
new file mode 100755
index 0000000..11ac23d
--- /dev/null
+++ b/libsingular-config.in
@@ -0,0 +1,108 @@
+#! /bin/bash
+
+#C="$0"
+#O=`pwd`
+#
+###C=`readlink -f "$C"`:::
+#cd `dirname "$C"`
+#C=`basename "$C"`
+#
+## Iterate down a (possible) chain of symlinks
+#while [ -L "$C" ]
+#do
+#    C=`readlink "$C"`
+#    cd `dirname "$C"`
+#    C=`basename "$C"`
+#done
+#
+#cd `dirname "$C"`
+#C=`pwd`
+#C=`dirname "$C"`
+#C=`ls -d1 "$C"`
+#
+#cd "$O"
+
+# NOTE: if you moved this config please either use the above or
+# make sure the following variables are up to date
+#prefix="$C"
+#exec_prefix=${prefix}
+#includedir=${prefix}/include
+#libdir=${exec_prefix}/lib
+
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+
+includedir=@includedir@
+libdir=@libdir@
+
+ECHO="echo"
+ECHOn="printf"
+
+usage()
+{
+    cat <<EOF
+Usage: libsingular-config [OPTION]
+
+Known values for OPTION are:
+
+  --prefix		show libsingular installation prefix
+  --libs		print library linking information
+  --cflags		print pre-processor and compiler flags
+  --help		display this help and exit
+  --version		output version information
+
+EOF
+
+    exit $1
+}
+
+if test $# -eq 0; then
+    usage 1
+fi
+
+cflags=false
+libs=false
+
+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
+	;;
+
+    --prefix)
+	${ECHO} $prefix
+	;;
+
+    --version)
+	${ECHO} @VERSION@
+	exit 0
+	;;
+
+    --help)
+	usage 0
+	;;
+
+    --cflags)
+    #### @FACTORY_INCLUDES@
+	${ECHOn} " -I${includedir} -I${includedir}/singular @SINGULAR_CFLAGS@ @FLINT_CFLAGS@ @NTL_CFLAGS@ @GMP_CFLAGS@ "
+	;;
+
+    --libs)
+	${ECHOn} " -L${libdir} -lSingular @USEPPROCSDYNAMICLD@"
+	;;
+
+    *)
+	usage
+	exit 1
+	;;
+    esac
+    shift
+done
+${ECHO}
+
+exit 0
diff --git a/m4/ax_append_compile_flags.m4 b/m4/ax_append_compile_flags.m4
new file mode 100644
index 0000000..1f8e708
--- /dev/null
+++ b/m4/ax_append_compile_flags.m4
@@ -0,0 +1,65 @@
+# ===========================================================================
+#  http://www.gnu.org/software/autoconf-archive/ax_append_compile_flags.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_APPEND_COMPILE_FLAGS([FLAG1 FLAG2 ...], [FLAGS-VARIABLE], [EXTRA-FLAGS])
+#
+# DESCRIPTION
+#
+#   For every FLAG1, FLAG2 it is checked whether the compiler works with the
+#   flag.  If it does, the flag is added FLAGS-VARIABLE
+#
+#   If FLAGS-VARIABLE is not specified, the current language's flags (e.g.
+#   CFLAGS) is used.  During the check the flag is always added to the
+#   current language's flags.
+#
+#   If EXTRA-FLAGS is defined, it is added to the current language's default
+#   flags (e.g. CFLAGS) when the check is done.  The check is thus made with
+#   the flags: "CFLAGS EXTRA-FLAGS FLAG".  This can for example be used to
+#   force the compiler to issue an error when a bad flag is given.
+#
+#   NOTE: This macro depends on the AX_APPEND_FLAG and
+#   AX_CHECK_COMPILE_FLAG. Please keep this macro in sync with
+#   AX_APPEND_LINK_FLAGS.
+#
+# LICENSE
+#
+#   Copyright (c) 2011 Maarten Bosmans <mkbosmans at gmail.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 3 of the License, or (at your
+#   option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+#   Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License along
+#   with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+#   As a special exception, the respective Autoconf Macro's copyright owner
+#   gives unlimited permission to copy, distribute and modify the configure
+#   scripts that are the output of Autoconf when processing the Macro. You
+#   need not follow the terms of the GNU General Public License when using
+#   or distributing such scripts, even though portions of the text of the
+#   Macro appear in them. The GNU General Public License (GPL) does govern
+#   all other use of the material that constitutes the Autoconf Macro.
+#
+#   This special exception to the GPL applies to versions of the Autoconf
+#   Macro released by the Autoconf Archive. When you make and distribute a
+#   modified version of the Autoconf Macro, you may extend this special
+#   exception to the GPL to apply to your modified version as well.
+
+#serial 3
+
+AC_DEFUN([AX_APPEND_COMPILE_FLAGS],
+[AC_REQUIRE([AX_CHECK_COMPILE_FLAG])
+AC_REQUIRE([AX_APPEND_FLAG])
+for flag in $1; do
+  AX_CHECK_COMPILE_FLAG([$flag], [AX_APPEND_FLAG([$flag], [$2])], [], [$3])
+done
+])dnl AX_APPEND_COMPILE_FLAGS
diff --git a/m4/ax_append_flag.m4 b/m4/ax_append_flag.m4
new file mode 100644
index 0000000..1d38b76
--- /dev/null
+++ b/m4/ax_append_flag.m4
@@ -0,0 +1,69 @@
+# ===========================================================================
+#      http://www.gnu.org/software/autoconf-archive/ax_append_flag.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_APPEND_FLAG(FLAG, [FLAGS-VARIABLE])
+#
+# DESCRIPTION
+#
+#   FLAG is appended to the FLAGS-VARIABLE shell variable, with a space
+#   added in between.
+#
+#   If FLAGS-VARIABLE is not specified, the current language's flags (e.g.
+#   CFLAGS) is used.  FLAGS-VARIABLE is not changed if it already contains
+#   FLAG.  If FLAGS-VARIABLE is unset in the shell, it is set to exactly
+#   FLAG.
+#
+#   NOTE: Implementation based on AX_CFLAGS_GCC_OPTION.
+#
+# LICENSE
+#
+#   Copyright (c) 2008 Guido U. Draheim <guidod at gmx.de>
+#   Copyright (c) 2011 Maarten Bosmans <mkbosmans at gmail.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 3 of the License, or (at your
+#   option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+#   Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License along
+#   with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+#   As a special exception, the respective Autoconf Macro's copyright owner
+#   gives unlimited permission to copy, distribute and modify the configure
+#   scripts that are the output of Autoconf when processing the Macro. You
+#   need not follow the terms of the GNU General Public License when using
+#   or distributing such scripts, even though portions of the text of the
+#   Macro appear in them. The GNU General Public License (GPL) does govern
+#   all other use of the material that constitutes the Autoconf Macro.
+#
+#   This special exception to the GPL applies to versions of the Autoconf
+#   Macro released by the Autoconf Archive. When you make and distribute a
+#   modified version of the Autoconf Macro, you may extend this special
+#   exception to the GPL to apply to your modified version as well.
+
+#serial 2
+
+AC_DEFUN([AX_APPEND_FLAG],
+[AC_PREREQ(2.59)dnl for _AC_LANG_PREFIX
+AS_VAR_PUSHDEF([FLAGS], [m4_default($2,_AC_LANG_PREFIX[FLAGS])])dnl
+AS_VAR_SET_IF(FLAGS,
+  [case " AS_VAR_GET(FLAGS) " in
+    *" $1 "*)
+      AC_RUN_LOG([: FLAGS already contains $1])
+      ;;
+    *)
+      AC_RUN_LOG([: FLAGS="$FLAGS $1"])
+      AS_VAR_SET(FLAGS, ["AS_VAR_GET(FLAGS) $1"])
+      ;;
+   esac],
+  [AS_VAR_SET(FLAGS,["$1"])])
+AS_VAR_POPDEF([FLAGS])dnl
+])dnl AX_APPEND_FLAG
diff --git a/m4/ax_append_link_flags.m4 b/m4/ax_append_link_flags.m4
new file mode 100644
index 0000000..48cbd4b
--- /dev/null
+++ b/m4/ax_append_link_flags.m4
@@ -0,0 +1,63 @@
+# ===========================================================================
+#   http://www.gnu.org/software/autoconf-archive/ax_append_link_flags.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_APPEND_LINK_FLAGS([FLAG1 FLAG2 ...], [FLAGS-VARIABLE], [EXTRA-FLAGS])
+#
+# DESCRIPTION
+#
+#   For every FLAG1, FLAG2 it is checked whether the linker works with the
+#   flag.  If it does, the flag is added FLAGS-VARIABLE
+#
+#   If FLAGS-VARIABLE is not specified, the linker's flags (LDFLAGS) is
+#   used. During the check the flag is always added to the linker's flags.
+#
+#   If EXTRA-FLAGS is defined, it is added to the linker's default flags
+#   when the check is done.  The check is thus made with the flags: "LDFLAGS
+#   EXTRA-FLAGS FLAG".  This can for example be used to force the linker to
+#   issue an error when a bad flag is given.
+#
+#   NOTE: This macro depends on the AX_APPEND_FLAG and AX_CHECK_LINK_FLAG.
+#   Please keep this macro in sync with AX_APPEND_COMPILE_FLAGS.
+#
+# LICENSE
+#
+#   Copyright (c) 2011 Maarten Bosmans <mkbosmans at gmail.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 3 of the License, or (at your
+#   option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+#   Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License along
+#   with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+#   As a special exception, the respective Autoconf Macro's copyright owner
+#   gives unlimited permission to copy, distribute and modify the configure
+#   scripts that are the output of Autoconf when processing the Macro. You
+#   need not follow the terms of the GNU General Public License when using
+#   or distributing such scripts, even though portions of the text of the
+#   Macro appear in them. The GNU General Public License (GPL) does govern
+#   all other use of the material that constitutes the Autoconf Macro.
+#
+#   This special exception to the GPL applies to versions of the Autoconf
+#   Macro released by the Autoconf Archive. When you make and distribute a
+#   modified version of the Autoconf Macro, you may extend this special
+#   exception to the GPL to apply to your modified version as well.
+
+#serial 3
+
+AC_DEFUN([AX_APPEND_LINK_FLAGS],
+[AC_REQUIRE([AX_CHECK_LINK_FLAG])
+AC_REQUIRE([AX_APPEND_FLAG])
+for flag in $1; do
+  AX_CHECK_LINK_FLAG([$flag], [AX_APPEND_FLAG([$flag], [m4_default([$2], [LDFLAGS])])], [], [$3])
+done
+])dnl AX_APPEND_LINK_FLAGS
diff --git a/m4/ax_check_compile_flag.m4 b/m4/ax_check_compile_flag.m4
new file mode 100644
index 0000000..bac1316
--- /dev/null
+++ b/m4/ax_check_compile_flag.m4
@@ -0,0 +1,72 @@
+# ===========================================================================
+#   http://www.gnu.org/software/autoconf-archive/ax_check_compile_flag.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS])
+#
+# DESCRIPTION
+#
+#   Check whether the given FLAG works with the current language's compiler
+#   or gives an error.  (Warnings, however, are ignored)
+#
+#   ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on
+#   success/failure.
+#
+#   If EXTRA-FLAGS is defined, it is added to the current language's default
+#   flags (e.g. CFLAGS) when the check is done.  The check is thus made with
+#   the flags: "CFLAGS EXTRA-FLAGS FLAG".  This can for example be used to
+#   force the compiler to issue an error when a bad flag is given.
+#
+#   NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this
+#   macro in sync with AX_CHECK_{PREPROC,LINK}_FLAG.
+#
+# LICENSE
+#
+#   Copyright (c) 2008 Guido U. Draheim <guidod at gmx.de>
+#   Copyright (c) 2011 Maarten Bosmans <mkbosmans at gmail.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 3 of the License, or (at your
+#   option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+#   Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License along
+#   with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+#   As a special exception, the respective Autoconf Macro's copyright owner
+#   gives unlimited permission to copy, distribute and modify the configure
+#   scripts that are the output of Autoconf when processing the Macro. You
+#   need not follow the terms of the GNU General Public License when using
+#   or distributing such scripts, even though portions of the text of the
+#   Macro appear in them. The GNU General Public License (GPL) does govern
+#   all other use of the material that constitutes the Autoconf Macro.
+#
+#   This special exception to the GPL applies to versions of the Autoconf
+#   Macro released by the Autoconf Archive. When you make and distribute a
+#   modified version of the Autoconf Macro, you may extend this special
+#   exception to the GPL to apply to your modified version as well.
+
+#serial 2
+
+AC_DEFUN([AX_CHECK_COMPILE_FLAG],
+[AC_PREREQ(2.59)dnl for _AC_LANG_PREFIX
+AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl
+AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [
+  ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS
+  _AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1 -Werror"
+  AC_COMPILE_IFELSE([AC_LANG_PROGRAM()],
+    [AS_VAR_SET(CACHEVAR,[yes])],
+    [AS_VAR_SET(CACHEVAR,[no])])
+  _AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags])
+AS_IF([test x"AS_VAR_GET(CACHEVAR)" = xyes],
+  [m4_default([$2], :)],
+  [m4_default([$3], :)])
+AS_VAR_POPDEF([CACHEVAR])dnl
+])dnl AX_CHECK_COMPILE_FLAGS
diff --git a/m4/ax_check_link_flag.m4 b/m4/ax_check_link_flag.m4
new file mode 100644
index 0000000..7cf2157
--- /dev/null
+++ b/m4/ax_check_link_flag.m4
@@ -0,0 +1,74 @@
+# ===========================================================================
+#    http://www.gnu.org/software/autoconf-archive/ax_check_link_flag.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_CHECK_LINK_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS])
+#
+# DESCRIPTION
+#
+#   Check whether the given FLAG works with the linker or gives an error.
+#   (Warnings, however, are ignored)
+#
+#   ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on
+#   success/failure.
+#
+#   If EXTRA-FLAGS is defined, it is added to the linker's default flags
+#   when the check is done.  The check is thus made with the flags: "LDFLAGS
+#   EXTRA-FLAGS FLAG".  This can for example be used to force the linker to
+#   issue an error when a bad flag is given.
+#
+#   NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this
+#   macro in sync with AX_CHECK_{PREPROC,COMPILE}_FLAG.
+#
+# LICENSE
+#
+#   Copyright (c) 2008 Guido U. Draheim <guidod at gmx.de>
+#   Copyright (c) 2011 Maarten Bosmans <mkbosmans at gmail.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 3 of the License, or (at your
+#   option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+#   Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License along
+#   with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+#   As a special exception, the respective Autoconf Macro's copyright owner
+#   gives unlimited permission to copy, distribute and modify the configure
+#   scripts that are the output of Autoconf when processing the Macro. You
+#   need not follow the terms of the GNU General Public License when using
+#   or distributing such scripts, even though portions of the text of the
+#   Macro appear in them. The GNU General Public License (GPL) does govern
+#   all other use of the material that constitutes the Autoconf Macro.
+#
+#   This special exception to the GPL applies to versions of the Autoconf
+#   Macro released by the Autoconf Archive. When you make and distribute a
+#   modified version of the Autoconf Macro, you may extend this special
+#   exception to the GPL to apply to your modified version as well.
+
+#serial 2
+
+AC_DEFUN([AX_CHECK_LINK_FLAG],
+[AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_ldflags_$4_$1])dnl
+AC_CACHE_CHECK([whether the linker accepts $1], CACHEVAR, [
+  ax_check_save_flags=$LDFLAGS
+  LDFLAGS="$LDFLAGS $4 $1"
+  _save_cflags="$CFLAGS"
+  CFLAGS="$CFLAGS -Werror"
+  AC_LINK_IFELSE([AC_LANG_PROGRAM()],
+    [AS_VAR_SET(CACHEVAR,[yes])],
+    [AS_VAR_SET(CACHEVAR,[no])])
+  CFLAGS="$_save_cflags"
+  LDFLAGS=$ax_check_save_flags])
+AS_IF([test x"AS_VAR_GET(CACHEVAR)" = xyes],
+  [m4_default([$2], :)],
+  [m4_default([$3], :)])
+AS_VAR_POPDEF([CACHEVAR])dnl
+])dnl AX_CHECK_LINK_FLAGS
diff --git a/m4/ax_compute_relative_paths.m4 b/m4/ax_compute_relative_paths.m4
new file mode 100644
index 0000000..6bc790a
--- /dev/null
+++ b/m4/ax_compute_relative_paths.m4
@@ -0,0 +1,190 @@
+# =============================================================================
+#  http://www.gnu.org/software/autoconf-archive/ax_compute_relative_paths.html
+# =============================================================================
+#
+# SYNOPSIS
+#
+#   AX_COMPUTE_RELATIVE_PATHS(PATH_LIST)
+#
+# DESCRIPTION
+#
+#   PATH_LIST is a space-separated list of colon-separated triplets of the
+#   form 'FROM:TO:RESULT'. This function iterates over these triplets and
+#   set $RESULT to the relative path from $FROM to $TO. Note that $FROM and
+#   $TO needs to be absolute filenames for this macro to success.
+#
+#   For instance,
+#
+#     first=/usr/local/bin
+#     second=/usr/local/share
+#     AX_COMPUTE_RELATIVE_PATHS([first:second:fs second:first:sf])
+#     # $fs is set to ../share
+#     # $sf is set to ../bin
+#
+#   $FROM and $TO are both eval'ed recursively and normalized, this means
+#   that you can call this macro with autoconf's dirnames like `prefix' or
+#   `datadir'. For example:
+#
+#     AX_COMPUTE_RELATIVE_PATHS([bindir:datadir:bin_to_data])
+#
+#   AX_COMPUTE_RELATIVE_PATHS should also works with DOS filenames.
+#
+#   You may want to use this macro in order to make your package
+#   relocatable. Instead of hardcoding $datadir into your programs just
+#   encode $bin_to_data and try to determine $bindir at run-time.
+#
+#   This macro requires AX_NORMALIZE_PATH.
+#
+# LICENSE
+#
+#   Copyright (c) 2008 Alexandre Duret-Lutz <adl at gnu.org>
+#
+#   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, see <http://www.gnu.org/licenses/>.
+#
+#   As a special exception, the respective Autoconf Macro's copyright owner
+#   gives unlimited permission to copy, distribute and modify the configure
+#   scripts that are the output of Autoconf when processing the Macro. You
+#   need not follow the terms of the GNU General Public License when using
+#   or distributing such scripts, even though portions of the text of the
+#   Macro appear in them. The GNU General Public License (GPL) does govern
+#   all other use of the material that constitutes the Autoconf Macro.
+#
+#   This special exception to the GPL applies to versions of the Autoconf
+#   Macro released by the Autoconf Archive. When you make and distribute a
+#   modified version of the Autoconf Macro, you may extend this special
+#   exception to the GPL to apply to your modified version as well.
+
+#serial 6
+
+AU_ALIAS([ADL_COMPUTE_RELATIVE_PATHS], [AX_COMPUTE_RELATIVE_PATHS])
+AC_DEFUN([AX_COMPUTE_RELATIVE_PATHS],
+[for _lcl_i in $1; do
+  _lcl_from=\[$]`echo "[$]_lcl_i" | sed 's,:.*$,,'`
+  _lcl_to=\[$]`echo "[$]_lcl_i" | sed 's,^[[^:]]*:,,' | sed 's,:[[^:]]*$,,'`
+  _lcl_result_var=`echo "[$]_lcl_i" | sed 's,^.*:,,'`
+  AX_RECURSIVE_EVAL([[$]_lcl_from], [_lcl_from])
+  AX_RECURSIVE_EVAL([[$]_lcl_to], [_lcl_to])
+  _lcl_notation="$_lcl_from$_lcl_to"
+  AX_NORMALIZE_PATH([_lcl_from],['/'])
+  AX_NORMALIZE_PATH([_lcl_to],['/'])
+  AX_COMPUTE_RELATIVE_PATH([_lcl_from], [_lcl_to], [_lcl_result_tmp])
+  AX_NORMALIZE_PATH([_lcl_result_tmp],["[$]_lcl_notation"])
+  eval $_lcl_result_var='[$]_lcl_result_tmp'
+done])
+
+## Note:
+## *****
+## The following helper macros are too fragile to be used out
+## of AX_COMPUTE_RELATIVE_PATHS (mainly because they assume that
+## paths are normalized), that's why I'm keeping them in the same file.
+## Still, some of them maybe worth to reuse.
+
+dnl AX_COMPUTE_RELATIVE_PATH(FROM, TO, RESULT)
+dnl ===========================================
+dnl Compute the relative path to go from $FROM to $TO and set the value
+dnl of $RESULT to that value.  This function work on raw filenames
+dnl (for instead it will considerate /usr//local and /usr/local as
+dnl two distinct paths), you should really use AX_COMPUTE_REALTIVE_PATHS
+dnl instead to have the paths sanitized automatically.
+dnl
+dnl For instance:
+dnl    first_dir=/somewhere/on/my/disk/bin
+dnl    second_dir=/somewhere/on/another/disk/share
+dnl    AX_COMPUTE_RELATIVE_PATH(first_dir, second_dir, first_to_second)
+dnl will set $first_to_second to '../../../another/disk/share'.
+AC_DEFUN([AX_COMPUTE_RELATIVE_PATH],
+[AX_COMPUTE_COMMON_PATH([$1], [$2], [_lcl_common_prefix])
+AX_COMPUTE_BACK_PATH([$1], [_lcl_common_prefix], [_lcl_first_rel])
+AX_COMPUTE_SUFFIX_PATH([$2], [_lcl_common_prefix], [_lcl_second_suffix])
+$3="[$]_lcl_first_rel[$]_lcl_second_suffix"])
+
+dnl AX_COMPUTE_COMMON_PATH(LEFT, RIGHT, RESULT)
+dnl ============================================
+dnl Compute the common path to $LEFT and $RIGHT and set the result to $RESULT.
+dnl
+dnl For instance:
+dnl    first_path=/somewhere/on/my/disk/bin
+dnl    second_path=/somewhere/on/another/disk/share
+dnl    AX_COMPUTE_COMMON_PATH(first_path, second_path, common_path)
+dnl will set $common_path to '/somewhere/on'.
+AC_DEFUN([AX_COMPUTE_COMMON_PATH],
+[$3=''
+_lcl_second_prefix_match=''
+while test "[$]_lcl_second_prefix_match" != 0; do
+  _lcl_first_prefix=`expr "x[$]$1" : "x\([$]$3/*[[^/]]*\)"`
+  _lcl_second_prefix_match=`expr "x[$]$2" : "x[$]_lcl_first_prefix"`
+  if test "[$]_lcl_second_prefix_match" != 0; then
+    if test "[$]_lcl_first_prefix" != "[$]$3"; then
+      $3="[$]_lcl_first_prefix"
+    else
+      _lcl_second_prefix_match=0
+    fi
+  fi
+done])
+
+dnl AX_COMPUTE_SUFFIX_PATH(PATH, SUBPATH, RESULT)
+dnl ==============================================
+dnl Substrack $SUBPATH from $PATH, and set the resulting suffix
+dnl (or the empty string if $SUBPATH is not a subpath of $PATH)
+dnl to $RESULT.
+dnl
+dnl For instace:
+dnl    first_path=/somewhere/on/my/disk/bin
+dnl    second_path=/somewhere/on
+dnl    AX_COMPUTE_SUFFIX_PATH(first_path, second_path, common_path)
+dnl will set $common_path to '/my/disk/bin'.
+AC_DEFUN([AX_COMPUTE_SUFFIX_PATH],
+[$3=`expr "x[$]$1" : "x[$]$2/*\(.*\)"`])
+
+dnl AX_COMPUTE_BACK_PATH(PATH, SUBPATH, RESULT)
+dnl ============================================
+dnl Compute the relative path to go from $PATH to $SUBPATH, knowing that
+dnl $SUBPATH is a subpath of $PATH (any other words, only repeated '../'
+dnl should be needed to move from $PATH to $SUBPATH) and set the value
+dnl of $RESULT to that value.  If $SUBPATH is not a subpath of PATH,
+dnl set $RESULT to the empty string.
+dnl
+dnl For instance:
+dnl    first_path=/somewhere/on/my/disk/bin
+dnl    second_path=/somewhere/on
+dnl    AX_COMPUTE_BACK_PATH(first_path, second_path, back_path)
+dnl will set $back_path to '../../../'.
+AC_DEFUN([AX_COMPUTE_BACK_PATH],
+[AX_COMPUTE_SUFFIX_PATH([$1], [$2], [_lcl_first_suffix])
+$3=''
+_lcl_tmp='xxx'
+while test "[$]_lcl_tmp" != ''; do
+  _lcl_tmp=`expr "x[$]_lcl_first_suffix" : "x[[^/]]*/*\(.*\)"`
+  if test "[$]_lcl_first_suffix" != ''; then
+     _lcl_first_suffix="[$]_lcl_tmp"
+     $3="../[$]$3"
+  fi
+done])
+
+
+dnl AX_RECURSIVE_EVAL(VALUE, RESULT)
+dnl =================================
+dnl Interpolate the VALUE in loop until it doesn't change,
+dnl and set the result to $RESULT.
+dnl WARNING: It's easy to get an infinite loop with some unsane input.
+AC_DEFUN([AX_RECURSIVE_EVAL],
+[_lcl_receval="$1"
+$2=`(test "x$prefix" = xNONE && prefix="$ac_default_prefix"
+     test "x$exec_prefix" = xNONE && exec_prefix="${prefix}"
+     _lcl_receval_old=''
+     while test "[$]_lcl_receval_old" != "[$]_lcl_receval"; do
+       _lcl_receval_old="[$]_lcl_receval"
+       eval _lcl_receval="\"[$]_lcl_receval\""
+     done
+     echo "[$]_lcl_receval")`])
diff --git a/m4/ax_cxx_gcc_abi_demangle.m4 b/m4/ax_cxx_gcc_abi_demangle.m4
new file mode 100644
index 0000000..2642ced
--- /dev/null
+++ b/m4/ax_cxx_gcc_abi_demangle.m4
@@ -0,0 +1,57 @@
+# ===========================================================================
+#  http://www.gnu.org/software/autoconf-archive/ax_cxx_gcc_abi_demangle.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_CXX_GCC_ABI_DEMANGLE
+#
+# DESCRIPTION
+#
+#   If the compiler supports GCC C++ ABI name demangling (has header
+#   cxxabi.h and abi::__cxa_demangle() function), define
+#   HAVE_GCC_ABI_DEMANGLE
+#
+#   Adapted from AX_CXX_RTTI by Luc Maisonobe
+#
+# LICENSE
+#
+#   Copyright (c) 2008 Neil Ferguson <nferguso at eso.org>
+#
+#   Copying and distribution of this file, with or without modification, are
+#   permitted in any medium without royalty provided the copyright notice
+#   and this notice are preserved. This file is offered as-is, without any
+#   warranty.
+
+#serial 8
+
+AC_DEFUN([AX_CXX_GCC_ABI_DEMANGLE],
+[AC_CACHE_CHECK(whether the compiler supports GCC C++ ABI name demangling,
+ax_cv_cxx_gcc_abi_demangle,
+[AC_LANG_SAVE
+ AC_LANG_CPLUSPLUS
+ AC_TRY_COMPILE([#include <typeinfo>
+#include <cxxabi.h>
+#include <string>
+
+template<typename TYPE>
+class A {};
+],[A<int> instance;
+int status = 0;
+char* c_name = 0;
+
+c_name = abi::__cxa_demangle(typeid(instance).name(), 0, 0, &status);
+
+std::string name(c_name);
+free(c_name);
+
+return name == "A<int>";
+],
+ ax_cv_cxx_gcc_abi_demangle=yes, ax_cv_cxx_gcc_abi_demangle=no)
+ AC_LANG_RESTORE
+])
+if test "$ax_cv_cxx_gcc_abi_demangle" = yes; then
+  AC_DEFINE(HAVE_GCC_ABI_DEMANGLE,1,
+            [define if the compiler supports GCC C++ ABI name demangling])
+fi
+])
diff --git a/m4/ax_normalize_path.m4 b/m4/ax_normalize_path.m4
new file mode 100644
index 0000000..e8f9973
--- /dev/null
+++ b/m4/ax_normalize_path.m4
@@ -0,0 +1,115 @@
+# ===========================================================================
+#     http://www.gnu.org/software/autoconf-archive/ax_normalize_path.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_NORMALIZE_PATH(VARNAME, [REFERENCE_STRING])
+#
+# DESCRIPTION
+#
+#   Perform some cleanups on the value of $VARNAME (interpreted as a path):
+#
+#     - empty paths are changed to '.'
+#     - trailing slashes are removed
+#     - repeated slashes are squeezed except a leading doubled slash '//'
+#       (which might indicate a networked disk on some OS).
+#
+#   REFERENCE_STRING is used to turn '/' into '\' and vice-versa: if
+#   REFERENCE_STRING contains some backslashes, all slashes and backslashes
+#   are turned into backslashes, otherwise they are all turned into slashes.
+#
+#   This makes processing of DOS filenames quite easier, because you can
+#   turn a filename to the Unix notation, make your processing, and turn it
+#   back to original notation.
+#
+#     filename='A:\FOO\\BAR\'
+#     old_filename="$filename"
+#     # Switch to the unix notation
+#     AX_NORMALIZE_PATH([filename], ["/"])
+#     # now we have $filename = 'A:/FOO/BAR' and we can process it as if
+#     # it was a Unix path.  For instance let's say that you want
+#     # to append '/subpath':
+#     filename="$filename/subpath"
+#     # finally switch back to the original notation
+#     AX_NORMALIZE_PATH([filename], ["$old_filename"])
+#     # now $filename equals to 'A:\FOO\BAR\subpath'
+#
+#   One good reason to make all path processing with the unix convention is
+#   that backslashes have a special meaning in many cases. For instance
+#
+#     expr 'A:\FOO' : 'A:\Foo'
+#
+#   will return 0 because the second argument is a regex in which
+#   backslashes have to be backslashed. In other words, to have the two
+#   strings to match you should write this instead:
+#
+#     expr 'A:\Foo' : 'A:\\Foo'
+#
+#   Such behavior makes DOS filenames extremely unpleasant to work with. So
+#   temporary turn your paths to the Unix notation, and revert them to the
+#   original notation after the processing. See the macro
+#   AX_COMPUTE_RELATIVE_PATHS for a concrete example of this.
+#
+#   REFERENCE_STRING defaults to $VARIABLE, this means that slashes will be
+#   converted to backslashes if $VARIABLE already contains some backslashes
+#   (see $thirddir below).
+#
+#     firstdir='/usr/local//share'
+#     seconddir='C:\Program Files\\'
+#     thirddir='C:\home/usr/'
+#     AX_NORMALIZE_PATH([firstdir])
+#     AX_NORMALIZE_PATH([seconddir])
+#     AX_NORMALIZE_PATH([thirddir])
+#     # $firstdir = '/usr/local/share'
+#     # $seconddir = 'C:\Program Files'
+#     # $thirddir = 'C:\home\usr'
+#
+# LICENSE
+#
+#   Copyright (c) 2008 Alexandre Duret-Lutz <adl at gnu.org>
+#
+#   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, see <http://www.gnu.org/licenses/>.
+#
+#   As a special exception, the respective Autoconf Macro's copyright owner
+#   gives unlimited permission to copy, distribute and modify the configure
+#   scripts that are the output of Autoconf when processing the Macro. You
+#   need not follow the terms of the GNU General Public License when using
+#   or distributing such scripts, even though portions of the text of the
+#   Macro appear in them. The GNU General Public License (GPL) does govern
+#   all other use of the material that constitutes the Autoconf Macro.
+#
+#   This special exception to the GPL applies to versions of the Autoconf
+#   Macro released by the Autoconf Archive. When you make and distribute a
+#   modified version of the Autoconf Macro, you may extend this special
+#   exception to the GPL to apply to your modified version as well.
+
+#serial 5
+
+AU_ALIAS([ADL_NORMALIZE_PATH], [AX_NORMALIZE_PATH])
+AC_DEFUN([AX_NORMALIZE_PATH],
+[case ":[$]$1:" in
+# change empty paths to '.'
+  ::) $1='.' ;;
+# strip trailing slashes
+  :*[[\\/]]:) $1=`echo "[$]$1" | sed 's,[[\\/]]*[$],,'` ;;
+  :*:) ;;
+esac
+# squeze repeated slashes
+case ifelse($2,,"[$]$1",$2) in
+# if the path contains any backslashes, turn slashes into backslashes
+ *\\*) $1=`echo "[$]$1" | sed 's,\(.\)[[\\/]][[\\/]]*,\1\\\\,g'` ;;
+# if the path contains slashes, also turn backslashes into slashes
+ *) $1=`echo "[$]$1" | sed 's,\(.\)[[\\/]][[\\/]]*,\1/,g'` ;;
+esac])
diff --git a/m4/ax_prefix_config_h.m4 b/m4/ax_prefix_config_h.m4
new file mode 100644
index 0000000..3de728d
--- /dev/null
+++ b/m4/ax_prefix_config_h.m4
@@ -0,0 +1,211 @@
+# ===========================================================================
+#    http://www.gnu.org/software/autoconf-archive/ax_prefix_config_h.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_PREFIX_CONFIG_H (OUTPUT-HEADER, PREFIX [,ORIG-HEADER])
+#
+# DESCRIPTION
+#
+#   This is a new variant from ac_prefix_config_ this one will use a
+#   lowercase-prefix if the config-define was starting with a
+#   lowercase-char, e.g. "#define const", "#define restrict", or "#define
+#   off_t", (and this one can live in another directory, e.g.
+#   testpkg/config.h therefore I decided to move the output-header to be the
+#   first arg)
+#
+#   takes the usual config.h generated header file; looks for each of the
+#   generated "#define SOMEDEF" lines, and prefixes the defined name (ie.
+#   makes it "#define PREFIX_SOMEDEF". The result is written to the output
+#   config.header file. The PREFIX is converted to uppercase for the
+#   conversions.
+#
+#   Defaults:
+#
+#     ORIG-HEADER, from AM_CONFIG_HEADER(config.h)
+#
+#   Your configure.ac script should contain both macros in this order, and
+#   unlike the earlier variations of this prefix-macro it is okay to place
+#   the AX_PREFIX_CONFIG_H call before the AC_OUTPUT invokation.
+#
+#   Example:
+#
+#     AC_INIT(config.h.in)        # config.h.in as created by "autoheader"
+#     AM_INIT_AUTOMAKE(testpkg, 0.1.1)    # makes #undef VERSION and PACKAGE
+#     AM_CONFIG_HEADER(config.h)          # prep config.h from config.h.in
+#     AX_PREFIX_CONFIG_H(mylib/_config.h, TESTPKG_) # prep mylib/_config.h from it..
+#     AC_MEMORY_H                         # makes "#undef NEED_MEMORY_H"
+#     AC_C_CONST_H                        # makes "#undef const"
+#     AC_OUTPUT(Makefile)                 # creates the "config.h" now
+#                                         # and also mylib/_config.h
+#
+#   outputfile called "mylib/_config.h" contains prefix-defines like
+#
+#     #ifndef TESTPKG_VERSION
+#     #define TESTPKG_VERSION "0.1.1"
+#     #endif
+#     #ifndef TESTPKG_NEED_MEMORY_H
+#     #define TESTPKG_NEED_MEMORY_H 1
+#     #endif
+#     #ifndef testpkg_const
+#     #define testpkg_const _const
+#     #endif
+#
+#   and this "mylib/_config.h" can be installed along with other
+#   header-files, which is most convenient when creating a shared library
+#   (that has some headers) where some functionality is dependent on the
+#   OS-features detected at compile-time. No need to invent some
+#   "mylib-confdefs.h.in" manually. :-)
+#
+#   Note that some AC_DEFINEs that end up in the config.h file are actually
+#   self-referential - e.g. AC_C_INLINE, AC_C_CONST, and the AC_TYPE_OFF_T
+#   say that they "will define inline|const|off_t if the system does not do
+#   it by itself". You might want to clean up about these - consider an
+#   extra mylib/conf.h that reads something like:
+#
+#     #include <mylib/_config.h>
+#     #ifndef testpkg_const
+#     #define testpkg_const const
+#     #endif
+#
+#   and then start using testpkg_const in the header files. That is also a
+#   good thing to differentiate whether some library-user has starting to
+#   take up with a different compiler, so perhaps it could read something
+#   like this:
+#
+#     #ifdef _MSC_VER
+#     #include <mylib/_msvc.h>
+#     #else
+#     #include <mylib/_config.h>
+#     #endif
+#     #ifndef testpkg_const
+#     #define testpkg_const const
+#     #endif
+#
+# LICENSE
+#
+#   Copyright (c) 2008 Guido U. Draheim <guidod at gmx.de>
+#   Copyright (c) 2008 Marten Svantesson
+#   Copyright (c) 2008 Gerald Point <Gerald.Point at labri.fr>
+#
+#   This program is free software; you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by the
+#   Free Software Foundation; either version 3 of the License, or (at your
+#   option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+#   Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License along
+#   with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+#   As a special exception, the respective Autoconf Macro's copyright owner
+#   gives unlimited permission to copy, distribute and modify the configure
+#   scripts that are the output of Autoconf when processing the Macro. You
+#   need not follow the terms of the GNU General Public License when using
+#   or distributing such scripts, even though portions of the text of the
+#   Macro appear in them. The GNU General Public License (GPL) does govern
+#   all other use of the material that constitutes the Autoconf Macro.
+#
+#   This special exception to the GPL applies to versions of the Autoconf
+#   Macro released by the Autoconf Archive. When you make and distribute a
+#   modified version of the Autoconf Macro, you may extend this special
+#   exception to the GPL to apply to your modified version as well.
+
+#serial 11
+
+AC_DEFUN([AX_PREFIX_CONFIG_H],[dnl
+AC_PREREQ([2.62])
+AC_BEFORE([AC_CONFIG_HEADERS],[$0])dnl
+AC_CONFIG_COMMANDS([ifelse($1,,$PACKAGE-config.h,$1)],[dnl
+AS_VAR_PUSHDEF([_OUT],[ac_prefix_conf_OUT])dnl
+AS_VAR_PUSHDEF([_DEF],[ac_prefix_conf_DEF])dnl
+AS_VAR_PUSHDEF([_PKG],[ac_prefix_conf_PKG])dnl
+AS_VAR_PUSHDEF([_LOW],[ac_prefix_conf_LOW])dnl
+AS_VAR_PUSHDEF([_UPP],[ac_prefix_conf_UPP])dnl
+AS_VAR_PUSHDEF([_INP],[ac_prefix_conf_INP])dnl
+m4_pushdef([_script],[conftest.prefix])dnl
+m4_pushdef([_symbol],[m4_cr_Letters[]m4_cr_digits[]_])dnl
+
+_OUT=`echo ifelse($1, , $PACKAGE-config.h, $1)`
+_PKG=`echo $2`
+_LOW=`echo $_PKG | sed -e "y:m4_cr_LETTERS-:m4_cr_letters[]_:"`
+_UPP=`echo $_PKG | sed -e "y:m4_cr_letters-:m4_cr_LETTERS[]_:"  -e "/^@<:@m4_cr_digits@:>@/s/^/_/"`
+_INP=`echo "ifelse($3,,,$3)" | sed -e 's/ *//'`
+_DEF=`echo "$_UPP $PACKAGE $_OUT" | sed -e "y:m4_cr_letters:m4_cr_LETTERS[]:" -e "s/@<:@^m4_cr_Letters@:>@/_/g"`
+
+if test ".$_INP" = "."; then
+   for ac_file in : $CONFIG_HEADERS; do test "_$ac_file" = _: && continue
+     case "$ac_file" in
+        *.h) _INP=$ac_file ;;
+        *)
+     esac
+     test ".$_INP" != "." && break
+   done
+fi
+if test ".$_INP" = "."; then
+   case "$_OUT" in
+      */*) _INP=`basename "$_OUT"`
+      ;;
+      *-*) _INP=`echo "$_OUT" | sed -e "s/@<:@_symbol@:>@*-//"`
+      ;;
+      *) _INP=config.h
+      ;;
+   esac
+fi
+#if test -z "$_PKG" ; then
+#   AC_MSG_ERROR([no prefix for AX_PREFIX_PKG_CONFIG_H])
+#else
+  if test ! -f "$_INP" ; then if test -f "$srcdir/$_INP" ; then
+     _INP="$srcdir/$_INP"
+  fi fi
+  AC_MSG_NOTICE([creating '$_OUT' - prefix '$_UPP' for '$_INP' defines])
+  if test -f $_INP ; then
+    AS_ECHO(["s/^@%:@undef  *\\(@<:@m4_cr_LETTERS[]_@:>@\\)/@%:@undef $_UPP""\\1/"]) > _script
+    AS_ECHO(["s/^@%:@undef  *\\(@<:@m4_cr_letters@:>@\\)/@%:@undef $_LOW""\\1/"]) >> _script
+    AS_ECHO(["s/^@%:@def[]ine  *\\(@<:@m4_cr_LETTERS[]_@:>@@<:@_symbol@:>@*\\)\\(.*\\)/@%:@ifndef $_UPP""\\1\\"]) >> _script
+    AS_ECHO(["@%:@def[]ine $_UPP""\\1\\2\\"]) >> _script
+    AS_ECHO(["@%:@endif/"]) >> _script
+    AS_ECHO(["s/^@%:@def[]ine  *\\(@<:@m4_cr_letters@:>@@<:@_symbol@:>@*\\)\\(.*\\)/@%:@ifndef $_LOW""\\1\\"]) >> _script
+    AS_ECHO(["@%:@define $_LOW""\\1\\2\\"]) >> _script
+    AS_ECHO(["@%:@endif/"]) >> _script
+
+    # now executing _script on _DEF input to create _OUT output file
+    echo "@%:@ifndef $_DEF"      >$tmp/pconfig.h
+    echo "@%:@def[]ine $_DEF 1" >>$tmp/pconfig.h
+    echo ' ' >>$tmp/pconfig.h
+
+    echo /'*' $_OUT. Generated automatically at end of configure. '*'/ >>$tmp/pconfig.h
+    echo ' ' >>$tmp/pconfig.h
+
+    sed -f _script $_INP >>$tmp/pconfig.h
+    echo ' ' >>$tmp/pconfig.h
+    echo '/* once:' $_DEF '*/' >>$tmp/pconfig.h
+    echo "@%:@endif" >>$tmp/pconfig.h
+    if cmp -s $_OUT $tmp/pconfig.h 2>/dev/null; then
+      AC_MSG_NOTICE([$_OUT is unchanged])
+    else
+      ac_dir=`AS_DIRNAME(["$_OUT"])`
+      AS_MKDIR_P(["$ac_dir"])
+      rm -f "$_OUT"
+      mv $tmp/pconfig.h "$_OUT"
+    fi
+    cp _script _configs.sed
+    rm _configs.sed
+  else
+    AC_MSG_ERROR([input file $_INP does not exist - skip generating $_OUT])
+  fi
+  rm -f conftest.*
+#fi
+m4_popdef([_symbol])dnl
+m4_popdef([_script])dnl
+AS_VAR_POPDEF([_INP])dnl
+AS_VAR_POPDEF([_UPP])dnl
+AS_VAR_POPDEF([_LOW])dnl
+AS_VAR_POPDEF([_PKG])dnl
+AS_VAR_POPDEF([_DEF])dnl
+AS_VAR_POPDEF([_OUT])dnl
+],[PACKAGE="$PACKAGE"])])
diff --git a/m4/ax_pthread.m4 b/m4/ax_pthread.m4
new file mode 100644
index 0000000..d383ad5
--- /dev/null
+++ b/m4/ax_pthread.m4
@@ -0,0 +1,332 @@
+# ===========================================================================
+#        http://www.gnu.org/software/autoconf-archive/ax_pthread.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
+#
+# DESCRIPTION
+#
+#   This macro figures out how to build C programs using POSIX threads. It
+#   sets the PTHREAD_LIBS output variable to the threads library and linker
+#   flags, and the PTHREAD_CFLAGS output variable to any special C compiler
+#   flags that are needed. (The user can also force certain compiler
+#   flags/libs to be tested by setting these environment variables.)
+#
+#   Also sets PTHREAD_CC to any special C compiler that is needed for
+#   multi-threaded programs (defaults to the value of CC otherwise). (This
+#   is necessary on AIX to use the special cc_r compiler alias.)
+#
+#   NOTE: You are assumed to not only compile your program with these flags,
+#   but also link it with them as well. e.g. you should link with
+#   $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS
+#
+#   If you are only building threads programs, you may wish to use these
+#   variables in your default LIBS, CFLAGS, and CC:
+#
+#     LIBS="$PTHREAD_LIBS $LIBS"
+#     CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+#     CC="$PTHREAD_CC"
+#
+#   In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant
+#   has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to that name
+#   (e.g. PTHREAD_CREATE_UNDETACHED on AIX).
+#
+#   Also HAVE_PTHREAD_PRIO_INHERIT is defined if pthread is found and the
+#   PTHREAD_PRIO_INHERIT symbol is defined when compiling with
+#   PTHREAD_CFLAGS.
+#
+#   ACTION-IF-FOUND is a list of shell commands to run if a threads library
+#   is found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it
+#   is not found. If ACTION-IF-FOUND is not specified, the default action
+#   will define HAVE_PTHREAD.
+#
+#   Please let the authors know if this macro fails on any platform, or if
+#   you have any other suggestions or comments. This macro was based on work
+#   by SGJ on autoconf scripts for FFTW (http://www.fftw.org/) (with help
+#   from M. Frigo), as well as ac_pthread and hb_pthread macros posted by
+#   Alejandro Forero Cuervo to the autoconf macro repository. We are also
+#   grateful for the helpful feedback of numerous users.
+#
+#   Updated for Autoconf 2.68 by Daniel Richard G.
+#
+# LICENSE
+#
+#   Copyright (c) 2008 Steven G. Johnson <stevenj at alum.mit.edu>
+#   Copyright (c) 2011 Daniel Richard G. <skunk at iSKUNK.ORG>
+#
+#   This program is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by the
+#   Free Software Foundation, either version 3 of the License, or (at your
+#   option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+#   Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License along
+#   with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+#   As a special exception, the respective Autoconf Macro's copyright owner
+#   gives unlimited permission to copy, distribute and modify the configure
+#   scripts that are the output of Autoconf when processing the Macro. You
+#   need not follow the terms of the GNU General Public License when using
+#   or distributing such scripts, even though portions of the text of the
+#   Macro appear in them. The GNU General Public License (GPL) does govern
+#   all other use of the material that constitutes the Autoconf Macro.
+#
+#   This special exception to the GPL applies to versions of the Autoconf
+#   Macro released by the Autoconf Archive. When you make and distribute a
+#   modified version of the Autoconf Macro, you may extend this special
+#   exception to the GPL to apply to your modified version as well.
+
+#serial 21
+
+AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD])
+AC_DEFUN([AX_PTHREAD], [
+AC_REQUIRE([AC_CANONICAL_HOST])
+AC_LANG_PUSH([C])
+ax_pthread_ok=no
+
+# We used to check for pthread.h first, but this fails if pthread.h
+# requires special compiler flags (e.g. on True64 or Sequent).
+# It gets checked for in the link test anyway.
+
+# First of all, check if the user has set any of the PTHREAD_LIBS,
+# etcetera environment variables, and if threads linking works using
+# them:
+if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then
+        save_CFLAGS="$CFLAGS"
+        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+        save_LIBS="$LIBS"
+        LIBS="$PTHREAD_LIBS $LIBS"
+        AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS])
+        AC_TRY_LINK_FUNC([pthread_join], [ax_pthread_ok=yes])
+        AC_MSG_RESULT([$ax_pthread_ok])
+        if test x"$ax_pthread_ok" = xno; then
+                PTHREAD_LIBS=""
+                PTHREAD_CFLAGS=""
+        fi
+        LIBS="$save_LIBS"
+        CFLAGS="$save_CFLAGS"
+fi
+
+# We must check for the threads library under a number of different
+# names; the ordering is very important because some systems
+# (e.g. DEC) have both -lpthread and -lpthreads, where one of the
+# libraries is broken (non-POSIX).
+
+# Create a list of thread flags to try.  Items starting with a "-" are
+# C compiler flags, and other items are library names, except for "none"
+# which indicates that we try without any flags at all, and "pthread-config"
+# which is a program returning the flags for the Pth emulation library.
+
+ax_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
+
+# The ordering *is* (sometimes) important.  Some notes on the
+# individual items follow:
+
+# pthreads: AIX (must check this before -lpthread)
+# none: in case threads are in libc; should be tried before -Kthread and
+#       other compiler flags to prevent continual compiler warnings
+# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
+# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
+# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
+# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads)
+# -pthreads: Solaris/gcc
+# -mthreads: Mingw32/gcc, Lynx/gcc
+# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
+#      doesn't hurt to check since this sometimes defines pthreads too;
+#      also defines -D_REENTRANT)
+#      ... -mt is also the pthreads flag for HP/aCC
+# pthread: Linux, etcetera
+# --thread-safe: KAI C++
+# pthread-config: use pthread-config program (for GNU Pth library)
+
+case ${host_os} in
+        solaris*)
+
+        # On Solaris (at least, for some versions), libc contains stubbed
+        # (non-functional) versions of the pthreads routines, so link-based
+        # tests will erroneously succeed.  (We need to link with -pthreads/-mt/
+        # -lpthread.)  (The stubs are missing pthread_cleanup_push, or rather
+        # a function called by this macro, so we could check for that, but
+        # who knows whether they'll stub that too in a future libc.)  So,
+        # we'll just look for -pthreads and -lpthread first:
+
+        ax_pthread_flags="-pthreads pthread -mt -pthread $ax_pthread_flags"
+        ;;
+
+        darwin*)
+        ax_pthread_flags="-pthread $ax_pthread_flags"
+        ;;
+esac
+
+# Clang doesn't consider unrecognized options an error unless we specify
+# -Werror. We throw in some extra Clang-specific options to ensure that
+# this doesn't happen for GCC, which also accepts -Werror.
+
+AC_MSG_CHECKING([if compiler needs -Werror to reject unknown flags])
+save_CFLAGS="$CFLAGS"
+ax_pthread_extra_flags="-Werror"
+CFLAGS="$CFLAGS $ax_pthread_extra_flags -Wunknown-warning-option -Wsizeof-array-argument"
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([int foo(void);],[foo()])],
+                  [AC_MSG_RESULT([yes])],
+                  [ax_pthread_extra_flags=
+                   AC_MSG_RESULT([no])])
+CFLAGS="$save_CFLAGS"
+
+if test x"$ax_pthread_ok" = xno; then
+for flag in $ax_pthread_flags; do
+
+        case $flag in
+                none)
+                AC_MSG_CHECKING([whether pthreads work without any flags])
+                ;;
+
+                -*)
+                AC_MSG_CHECKING([whether pthreads work with $flag])
+                PTHREAD_CFLAGS="$flag"
+                ;;
+
+                pthread-config)
+                AC_CHECK_PROG([ax_pthread_config], [pthread-config], [yes], [no])
+                if test x"$ax_pthread_config" = xno; then continue; fi
+                PTHREAD_CFLAGS="`pthread-config --cflags`"
+                PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
+                ;;
+
+                *)
+                AC_MSG_CHECKING([for the pthreads library -l$flag])
+                PTHREAD_LIBS="-l$flag"
+                ;;
+        esac
+
+        save_LIBS="$LIBS"
+        save_CFLAGS="$CFLAGS"
+        LIBS="$PTHREAD_LIBS $LIBS"
+        CFLAGS="$CFLAGS $PTHREAD_CFLAGS $ax_pthread_extra_flags"
+
+        # Check for various functions.  We must include pthread.h,
+        # since some functions may be macros.  (On the Sequent, we
+        # need a special flag -Kthread to make this header compile.)
+        # We check for pthread_join because it is in -lpthread on IRIX
+        # while pthread_create is in libc.  We check for pthread_attr_init
+        # due to DEC craziness with -lpthreads.  We check for
+        # pthread_cleanup_push because it is one of the few pthread
+        # functions on Solaris that doesn't have a non-functional libc stub.
+        # We try pthread_create on general principles.
+        AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>
+                        static void routine(void *a) { a = 0; }
+                        static void *start_routine(void *a) { return a; }],
+                       [pthread_t th; pthread_attr_t attr;
+                        pthread_create(&th, 0, start_routine, 0);
+                        pthread_join(th, 0);
+                        pthread_attr_init(&attr);
+                        pthread_cleanup_push(routine, 0);
+                        pthread_cleanup_pop(0) /* ; */])],
+                [ax_pthread_ok=yes],
+                [])
+
+        LIBS="$save_LIBS"
+        CFLAGS="$save_CFLAGS"
+
+        AC_MSG_RESULT([$ax_pthread_ok])
+        if test "x$ax_pthread_ok" = xyes; then
+                break;
+        fi
+
+        PTHREAD_LIBS=""
+        PTHREAD_CFLAGS=""
+done
+fi
+
+# Various other checks:
+if test "x$ax_pthread_ok" = xyes; then
+        save_LIBS="$LIBS"
+        LIBS="$PTHREAD_LIBS $LIBS"
+        save_CFLAGS="$CFLAGS"
+        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+
+        # Detect AIX lossage: JOINABLE attribute is called UNDETACHED.
+        AC_MSG_CHECKING([for joinable pthread attribute])
+        attr_name=unknown
+        for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
+            AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>],
+                           [int attr = $attr; return attr /* ; */])],
+                [attr_name=$attr; break],
+                [])
+        done
+        AC_MSG_RESULT([$attr_name])
+        if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then
+            AC_DEFINE_UNQUOTED([PTHREAD_CREATE_JOINABLE], [$attr_name],
+                               [Define to necessary symbol if this constant
+                                uses a non-standard name on your system.])
+        fi
+
+        AC_MSG_CHECKING([if more special flags are required for pthreads])
+        flag=no
+        case ${host_os} in
+            aix* | freebsd* | darwin*) flag="-D_THREAD_SAFE";;
+            osf* | hpux*) flag="-D_REENTRANT";;
+            solaris*)
+            if test "$GCC" = "yes"; then
+                flag="-D_REENTRANT"
+            else
+                # TODO: What about Clang on Solaris?
+                flag="-mt -D_REENTRANT"
+            fi
+            ;;
+        esac
+        AC_MSG_RESULT([$flag])
+        if test "x$flag" != xno; then
+            PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS"
+        fi
+
+        AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT],
+            [ax_cv_PTHREAD_PRIO_INHERIT], [
+                AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <pthread.h>]],
+                                                [[int i = PTHREAD_PRIO_INHERIT;]])],
+                    [ax_cv_PTHREAD_PRIO_INHERIT=yes],
+                    [ax_cv_PTHREAD_PRIO_INHERIT=no])
+            ])
+        AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes"],
+            [AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], [1], [Have PTHREAD_PRIO_INHERIT.])])
+
+        LIBS="$save_LIBS"
+        CFLAGS="$save_CFLAGS"
+
+        # More AIX lossage: compile with *_r variant
+        if test "x$GCC" != xyes; then
+            case $host_os in
+                aix*)
+                AS_CASE(["x/$CC"],
+                  [x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6],
+                  [#handle absolute path differently from PATH based program lookup
+                   AS_CASE(["x$CC"],
+                     [x/*],
+                     [AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"])],
+                     [AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC])])])
+                ;;
+            esac
+        fi
+fi
+
+test -n "$PTHREAD_CC" || PTHREAD_CC="$CC"
+
+AC_SUBST([PTHREAD_LIBS])
+AC_SUBST([PTHREAD_CFLAGS])
+AC_SUBST([PTHREAD_CC])
+
+# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
+if test x"$ax_pthread_ok" = xyes; then
+        ifelse([$1],,[AC_DEFINE([HAVE_PTHREAD],[1],[Define if you have POSIX threads libraries and header files.])],[$1])
+        :
+else
+        ax_pthread_ok=no
+        $2
+fi
+AC_LANG_POP
+])dnl AX_PTHREAD
diff --git a/m4/ax_python_embed.m4 b/m4/ax_python_embed.m4
new file mode 100644
index 0000000..d370566
--- /dev/null
+++ b/m4/ax_python_embed.m4
@@ -0,0 +1,524 @@
+# ===========================================================================
+#      http://www.gnu.org/software/autoconf-archive/ax_python_embed.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_PYTHON_DEFAULT
+#   AX_PYTHON_ENABLE
+#   AX_PYTHON_WITH
+#   AX_PYTHON_PATH
+#   AX_PYTHON_VERSION_ENSURE( [2.2] )
+#   AX_PYTHON_CSPEC
+#   AX_PYTHON_LSPEC
+#
+# DESCRIPTION
+#
+#   This file provides autoconf support for those applications that want to
+#   embed python. It supports all pythons >= 2.2 which is the first official
+#   release containing distutils. Version 2.2 of python was released
+#   December 21, 2001. Since it actually executes the python, cross platform
+#   configuration will probably not work. Also, most of the platforms
+#   supported are consistent until you look into Mac OS X. The python
+#   included with it is installed as a framework which is a very different
+#   environment to set up the normal tools such as gcc and libtool to deal
+#   with. Therefore, once we establish which python that we are going to
+#   use, we use its distutils to actually compile and link our modules or
+#   applications.
+#
+#   At this time, it does NOT support linking with Python statically. It
+#   does support dynamic linking.
+#
+#   This set of macros help define $PYTHON, $PYTHON_USE, $PYTHON_CSPEC and
+#   $PYTHON_LSPEC. $PYTHON defines the full executable path for the Python
+#   being linked to and is used within these macros to determine if that has
+#   been specified or found. These macros do execute this python version so
+#   it must be present on the system at configure time.
+#
+#   $PYTHON_USE is an automake variable that defines whether Python support
+#   should be included or not in your application. $PYTHON_CSPEC is a
+#   variable that supplies additional CFLAGS for the compilation of the
+#   application/shared library. $PYTHON_LSPEC is a variable that supplies
+#   additional LDFLAGS for linking the application/shared library.
+#
+#   The following is an example of how to set up for python usage within
+#   your application in your configure.in:
+#
+#     AX_PYTHON_DEFAULT( )
+#     AX_PYTHON_ENABLE( )             # Optional
+#     AX_PYTHON_WITH( )               # Optional
+#     AX_PYTHON_PATH( )               # or AX_PYTHON_INSIST( )
+#     # if $PYTHON is not defined, then the following do nothing.
+#     AX_PYTHON_VERSION_ENSURE( [2.2] )
+#     AX_PYTHON_CSPEC
+#     AX_PYTHON_LSPEC
+#
+#   The AX_PYTHON_DEFAULT sets the $PYTHON_USE to false. Thereby, excluding
+#   it if it was optional.
+#
+#   The AX_PYTHON_ENABLE looks for the optional configure parameters of
+#   --enable-python/--disable-python and establishes the $PYTHON and
+#   $PYTHON_USE variables accordingly.
+#
+#   The AX_PYTHON_WITH looks for the optional configure parameters of
+#   --with-python/--without-python and establishes the $PYTHON and
+#   $PYTHON_USE variables accordingly.
+#
+#   The AX_PYTHON_PATH looks for python assuming that none has been
+#   previously found or defined and issues an error if it does not find it.
+#   If it does find it, it establishes the $PYTHON and $PYTHON_USE variables
+#   accordingly. AX_PYTHON_INSIST could be used here instead if you want to
+#   insist that Python support be included using the --enable-python or
+#   --with-python checks previously done.
+#
+#   The AX_PYTHON_VERSION_ENSURE issues an error if the Python previously
+#   found is not of version 2.2 or greater.
+#
+#   Once that these macros have be run, we can use PYTHON_USE within the
+#   makefile.am file to conditionally add the Python support such as:
+#
+#   Makefile.am example showing optional inclusion of directories:
+#
+#    if PYTHON_USE
+#    plugins = plugins
+#    src = src
+#    else
+#    plugins =
+#    src =
+#    endif
+#
+#    SUBDIRS = . $(plugins) $(src)
+#
+#   Makefile.am example showing optional shared library build:
+#
+#    if PYTHON_USE
+#    lib_LTLIBRARIES        = libElemList.la
+#    libElemList_la_SOURCES = libElemList.c
+#    libElemList_la_CFLAGS  = @PYTHON_CSPEC@
+#    libElemList_la_LDFLAGS = @PYTHON_LSPEC@
+#    endif
+#
+#   Makefile.am example showing optional program build:
+#
+#    if PYTHON_USE
+#    bin_PROGRAMS    = runFunc
+#    runFunc_SOURCES = runFunc.c
+#    runFunc_CFLAGS  = @PYTHON_CSPEC@
+#    runFunc_LDFLAGS = @PYTHON_LSPEC@
+#    endif
+#
+#   The above compiles the modules only if PYTHON_USE was specified as true.
+#   Also, the else portion of the if was optional.
+#
+# LICENSE
+#
+#   Copyright (c) 2008 Robert White <kranki at mac.com>
+#   Copyright (c) 2008 Dustin J. Mitchell <dustin at cs.uchicago.edu>
+#
+#   Copying and distribution of this file, with or without modification, are
+#   permitted in any medium without royalty provided the copyright notice
+#   and this notice are preserved. This file is offered as-is, without any
+#   warranty.
+
+#serial 8
+
+# AX_PYTHON_DEFAULT( )
+# -----------------
+# Sets the default to not include Python support.
+
+AC_DEFUN([AX_PYTHON_DEFAULT],
+[
+    ax_python_use=false
+    AM_CONDITIONAL(PYTHON_USE, test x"$ax_python_use" = x"true")
+])
+
+
+
+# AX_PYTHON_ENABLE( [path] )
+# -----------------------------------------------------------------
+# Handles the various --enable-python commands.
+# Input:
+#   $1 is the optional search path for the python executable if needed
+# Ouput:
+#   PYTHON_USE (AM_CONDITIONAL) is true if python executable found
+#   and --enable-python was requested; otherwise false.
+#   $PYTHON contains the full executable path to python if PYTHON_ENABLE_USE
+#   is true.
+#
+# Example:
+#   AX_PYTHON_ENABLE( )
+#   or
+#   AX_PYTHON_ENABLE( "/usr/bin" )
+
+AC_DEFUN([AX_PYTHON_ENABLE],
+[
+    AC_ARG_VAR([PYTHON],[Python Executable Path])
+
+    # unless PYTHON was supplied to us (as a precious variable),
+    # see if --enable-python[=PythonExecutablePath], --enable-python,
+    # --disable-python or --enable-python=no was given.
+    if test -z "$PYTHON"
+    then
+        AC_MSG_CHECKING(for --enable-python)
+        AC_ARG_ENABLE(
+            python,
+            AS_HELP_STRING([--enable-python@<:@=PYTHON@:>@],
+                [absolute path name of Python executable]
+            ),
+            [
+                if test "$enableval" = "yes"
+                then
+                    # "yes" was specified, but we don't have a path
+                    # for the executable.
+                    # So, let's searth the PATH Environment Variable.
+                    AC_MSG_RESULT(yes)
+                    AC_PATH_PROG(
+                        [PYTHON],
+                        python,
+                        [],
+                        $1
+                    )
+                    if test -z "$PYTHON"
+                    then
+                        AC_MSG_ERROR(no path to python found)
+                    fi
+                    ax_python_use=true
+                    AM_CONDITIONAL(PYTHON_USE, test x"$ax_python_use" = x"true")
+                    AX_PYTHON_PREFIX( )
+                elif test "$enableval" = "no"
+                then
+                    AC_MSG_RESULT(no)
+                    ax_python_use=false
+                    AM_CONDITIONAL(PYTHON_USE, test x"$ax_python_use" = x"true")
+                else
+                    # $enableval must be the executable path then.
+                    AC_SUBST([PYTHON], ["${enableval}"])
+                    AC_MSG_RESULT($withval)
+                    ax_python_use=true
+                    AM_CONDITIONAL(PYTHON_USE, test x"$ax_python_use" = x"true")
+                    AX_PYTHON_PREFIX( )
+                fi
+            ],
+            [
+                # --with-python was not specified.
+                AC_MSG_RESULT(no)
+                ax_python_use=false
+                AM_CONDITIONAL(PYTHON_USE, test x"$ax_python_use" = x"true")
+            ]
+        )
+    fi
+
+])
+
+
+
+# AX_PYTHON_CSPEC( )
+# -----------------
+# Set up the c compiler options to compile Python
+# embedded programs/libraries in $PYTHON_CSPEC if
+# $PYTHON has been defined.
+
+AC_DEFUN([AX_PYTHON_CSPEC],
+[
+    AC_ARG_VAR( [PYTHON], [Python Executable Path] )
+    if test -n "$PYTHON"
+    then
+        ax_python_prefix=`${PYTHON}-config --prefix`
+        if test -z "$ax_python_prefix"
+        then
+            AC_MSG_ERROR([Python Prefix is not known])
+        fi
+#        ax_python_execprefix=`${PYTHON}-config --exec-prefix`
+#        ax_python_version=`$PYTHON -c "import sys; print sys.version[[:3]]"`
+#        ax_python_includespec="-I${ax_python_prefix}/include/python${ax_python_version}"
+#        if test x"$python_prefix" != x"$python_execprefix"; then
+#            ax_python_execspec="-I${ax_python_execprefix}/include/python${ax_python_version}"
+#            ax_python_includespec="${ax_python_includespec} $ax_python_execspec"
+#        fi
+        ax_python_cspec=`${PYTHON}-config --cflags | sed -e 's@ -mno-fused-madd @ @g'`
+        #   or -Qunused-arguments / clang :(
+#        ax_python_cspec="${ax_python_ccshared} ${ax_python_includespec}"
+        AC_SUBST([PYTHON_CSPEC], [${ax_python_cspec}])
+        AC_MSG_NOTICE([PYTHON_CSPEC=${ax_python_cspec}])
+    fi
+])
+
+
+
+# AX_PYTHON_INSIST( )
+# -----------------
+# Look for Python and set the output variable 'PYTHON'
+# to 'python' if found, empty otherwise.
+
+AC_DEFUN([AX_PYTHON_INSIST],
+[
+    AC_ARG_VAR( [PYTHON], [Python Executable Path] )
+    if test -z "$PYTHON"
+    then
+        AC_MSG_ERROR([Python Executable not found])
+    fi
+])
+
+
+
+# AX_PYTHON_LSPEC( )
+# -----------------
+# Set up the linker options to link Python embedded
+# programs/libraries in $PYTHON_LSPEC if $PYTHON
+# has been defined.
+
+AC_DEFUN([AX_PYTHON_LSPEC],
+[
+
+    AC_ARG_VAR( [PYTHON], [Python Executable Path] )
+    if test -n "$PYTHON"
+    then
+
+        AX_PYTHON_RUN([
+import sys
+import distutils.sysconfig
+strUseFrameWork = "--enable-framework"
+dictConfig = distutils.sysconfig.get_config_vars( )
+strConfigArgs = dictConfig.get("CONFIG_ARGS")
+strLinkSpec =  dictConfig.get('LDFLAGS')
+if -1 ==  strConfigArgs.find(strUseFrameWork):
+    strLibPL = dictConfig.get("LIBPL")
+    if strLibPL and (strLibPL != ""):
+        strLinkSpec += " -L%s" % (strLibPL)
+    strSys = dictConfig.get("SYSLIBS")
+    if strSys and (strSys != ""):
+        strLinkSpec += " %s" % (strSys)
+    strSHL = dictConfig.get("SHLIBS")
+    if strSHL and (strSHL != ""):
+        strLinkSpec += " %s" % (strSHL)
+    # Construct the Python Library Name.
+    strTmplte = " -lpython%d.%d"
+    if (sys.platform == "win32") or (sys.platform == "os2emx"):
+        strTmplte = " -lpython%d%d"
+    strWrk = strTmplte % ( (sys.hexversion >> 24),
+                            ((sys.hexversion >> 16) & 0xff))
+    strLinkSpec += strWrk
+else:
+    # This is not ideal since it changes the search path
+    # for Frameworks which could have side-effects on
+    # other included Frameworks.  However, it is necessary
+    # where someone has installed more than one frameworked
+    # Python.  Frameworks are really only used in Mac OS X.
+    strLibFW = dictConfig.get("PYTHONFRAMEWORKPREFIX")
+    if strLibFW and (strLibFW != ""):
+        strLinkSpec += " -F%s" % (strLibFW)
+strLinkSpec += " %s" % (dictConfig.get('LINKFORSHARED'))
+print strLinkSpec
+        ])
+
+#        AC_SUBST([PYTHON_LSPEC], [${ax_python_output}])
+#        AC_MSG_NOTICE([PYTHON_LSPEC=${ax_python_output}])
+
+        ax_python_lspec=`${PYTHON}-config --ldflags`
+        AC_SUBST([PYTHON_LSPEC], [${ax_python_lspec}])
+        AC_MSG_NOTICE([PYTHON_LSPEC=${ax_python_lspec}])
+
+    fi
+])
+
+
+
+# AX_PYTHON_PATH( )
+# -----------------
+# Look for Python and set the output variable 'PYTHON'
+# to 'python' if found, empty otherwise.
+
+AC_DEFUN([AX_PYTHON_PATH],
+[
+    AC_ARG_VAR( [PYTHON], [Python Executable Path] )
+    AC_PATH_PROG( PYTHON, python, [], $1 )
+    if test -z "$PYTHON"
+    then
+        AC_MSG_ERROR([Python Executable not found])
+    else
+        ax_python_use=true
+    fi
+    AM_CONDITIONAL(PYTHON_USE, test "$ax_python_use" = "true")
+])
+
+
+
+# AX_PYTHON_PREFIX( )
+# -------------------
+# Use the values of $prefix and $exec_prefix for the corresponding
+# values of PYTHON_PREFIX and PYTHON_EXEC_PREFIX.
+
+AC_DEFUN([AX_PYTHON_PREFIX],
+[
+    if test -z "$PYTHON"
+    then
+        AC_MSG_ERROR([Python Executable Path is not known])
+    fi
+    ax_python_prefix=`${PYTHON} -c "import sys; print sys.prefix"`
+    ax_python_execprefix=`${PYTHON} -c "import sys; print sys.exec_prefix"`
+    AC_SUBST([PYTHON_PREFIX], ["${ax_python_prefix}"])
+    AC_SUBST([PYTHON_EXECPREFIX], ["${ax_python_execprefix}"])
+])
+
+
+
+# AX_PYTHON_RUN( PYTHON_PROGRAM )
+# -----------------
+# Run a Python Test Program saving its output
+# in ax_python_output and its condition code
+# in ax_python_cc.
+
+AC_DEFUN([AX_PYTHON_RUN],
+[
+    AC_ARG_VAR( [PYTHON], [Python Executable Path] )
+    if test -z "$PYTHON"
+    then
+        AC_MSG_ERROR([Python Executable not found])
+    else
+        cat >conftest.py <<_ACEOF
+$1
+_ACEOF
+        ax_python_output=`$PYTHON conftest.py`
+        ax_python_cc=$?
+        rm conftest.py
+        if test -f "conftest.pyc"
+        then
+            rm conftest.pyc
+        fi
+    fi
+])
+
+
+
+# AX_PYTHON_VERSION_CHECK( VERSION, [ACTION-IF-TRUE], [ACTION-IF-FALSE] )
+# -----------------------------------------------------------------------------
+# Run ACTION-IF-TRUE if the Python interpreter has version >= VERSION.
+# Run ACTION-IF-FALSE otherwise.
+# This test uses sys.hexversion instead of the string equivalant (first
+# word of sys.version), in order to cope with versions such as 2.2c1.
+# hexversion has been introduced in Python 1.5.2; it's probably not
+# worth to support older versions (1.5.1 was released on October 31, 1998).
+
+AC_DEFUN([AX_PYTHON_VERSION_CHECK],
+ [
+    AC_ARG_VAR( [PYTHON], [Python Executable Path] )
+    if test -n "$PYTHON"
+    then
+        AC_MSG_CHECKING([whether $PYTHON version >= $1])
+        AX_PYTHON_RUN([
+import sys, string
+# split strings by '.' and convert to numeric.  Append some zeros
+# because we need at least 4 digits for the hex conversion.
+minver = map(int, string.split('$1', '.')) + [[0, 0, 0]]
+minverhex = 0
+for i in xrange(0, 4): minverhex = (minverhex << 8) + minver[[i]]
+if sys.hexversion >= minverhex:
+    sys.exit( 0 )
+else:
+    sys.exit( 1 )
+        ])
+        if test $ax_python_cc -eq 0
+        then
+            $2
+        m4_ifvaln(
+            [$3],
+            [else $3]
+        )
+        fi
+    fi
+])
+
+
+
+# AX_PYTHON_VERSION_ENSURE( VERSION )
+# -----------------
+# Insure that the Python Interpreter Version
+# is greater than or equal to the VERSION
+# parameter.
+
+AC_DEFUN([AX_PYTHON_VERSION_ENSURE],
+[
+    AX_PYTHON_VERSION_CHECK(
+        [$1],
+        [AC_MSG_RESULT(yes)],
+        [AC_MSG_ERROR(too old)]
+    )
+])
+
+
+
+# AX_PYTHON_WITH( [path] )
+# -----------------------------------------------------------------
+# Handles the various --with-python commands.
+# Input:
+#   $1 is the optional search path for the python executable if needed
+# Ouput:
+#   PYTHON_USE (AM_CONDITIONAL) is true if python executable found
+#   and --with-python was requested; otherwise false.
+#   $PYTHON contains the full executable path to python if PYTHON_USE
+#   is true.
+#
+# Example:
+#   AX_PYTHON_WITH( )
+#   or
+#   AX_PYTHON_WITH("/usr/bin")
+
+AC_DEFUN([AX_PYTHON_WITH],
+[
+    AC_ARG_VAR([PYTHON],[Python Executable Path])
+
+    # unless PYTHON was supplied to us (as a precious variable),
+    # see if --with-python[=PythonExecutablePath], --with-python,
+    # --without-python or --with-python=no was given.
+    if test -z "$PYTHON"
+    then
+        AC_MSG_CHECKING(for --with-python)
+        AC_ARG_WITH(
+            python,
+            AS_HELP_STRING([--with-python@<:@=PYTHON@:>@],
+                [absolute path name of Python executable]
+            ),
+            [
+                if test "$withval" = "yes"
+                then
+                    # "yes" was specified, but we don't have a path
+                    # for the executable.
+                    # So, let's searth the PATH Environment Variable.
+                    AC_MSG_RESULT(yes)
+                    AC_PATH_PROG(
+                        [PYTHON],
+                        python,
+                        [],
+                        $1
+                    )
+                    if test -z "$PYTHON"
+                    then
+                        AC_MSG_ERROR(no path to python found)
+                    fi
+                    ax_python_use=true
+                    AM_CONDITIONAL(PYTHON_USE, test x"$ax_python_use" = x"true")
+                    AX_PYTHON_PREFIX( )
+                elif test "$withval" = "no"
+                then
+                    AC_MSG_RESULT(no)
+                    ax_python_use=false
+                    AM_CONDITIONAL(PYTHON_USE, test x"$ax_python_use" = x"true")
+                else
+                    # $withval must be the executable path then.
+                    AC_SUBST([PYTHON], ["${withval}"])
+                    AC_MSG_RESULT($withval)
+                    ax_python_use=true
+                    AM_CONDITIONAL(PYTHON_USE, test x"$ax_python_use" = x"true")
+                    AX_PYTHON_PREFIX( )
+                fi
+            ],
+            [
+                # --with-python was not specified.
+                AC_MSG_RESULT(no)
+                ax_python_use=false
+                AM_CONDITIONAL(PYTHON_USE, test x"$ax_python_use" = x"true")
+            ]
+        )
+    fi
+
+])
diff --git a/m4/ax_python_with_version.m4 b/m4/ax_python_with_version.m4
new file mode 100644
index 0000000..543afcb
--- /dev/null
+++ b/m4/ax_python_with_version.m4
@@ -0,0 +1,128 @@
+# AX_PYTHON_WITH_VERSION( [version], [path] )
+# -----------------------------------------------------------------
+# Handles the various --with-python commands.
+# Input:
+#   $1 is the minimun required python version
+#   $2 is the optional search path for the python executable if needed
+# Ouput:
+#   PYTHON_USE (AM_CONDITIONAL) is true if python executable found
+#   and --with-python was requested; otherwise false.
+#   $PYTHON contains the full executable path to python if PYTHON_USE
+#   is true.
+#
+# Example:
+#   AX_PYTHON_WITH_VERSION([2.4])
+#   or
+#   AX_PYTHON_WITH_VERSION([2.4], "/usr/bin")
+
+AC_DEFUN([AX_PYTHON_WITH_VERSION],
+[
+    AC_ARG_VAR([PYTHON],[Python Executable Path])
+
+    # unless PYTHON was supplied to us (as a precious variable),
+    # see if --with-python[=PythonExecutablePath], --with-python,
+    # --without-python or --with-python=no was given.
+    if test -z "$PYTHON"
+    then
+        AC_MSG_CHECKING(for --with-python)
+# @<:@=@<:@embed,@:>@PYTHON@:>@
+          AC_ARG_WITH(
+            python,
+            AS_HELP_STRING([--with-python],
+                [absolute path name of Python executable]
+            ),
+            [],[withval="yes"]
+        )
+        si_try_embed="no"
+        py_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+        for elt in $withval; do
+          IFS="$py_save_ifs"
+          case $elt in
+            embed|embedding)
+              si_try_embed="yes"
+            ;;
+            static|dynamic|shared|module)
+            ;;
+            *)
+            si_withval=$elt
+          esac
+        done
+        IFS="$py_save_ifs"
+        if test x"$si_withval" = x""
+        then
+           withval="yes"
+        else
+	   withval="$si_withval"
+        fi
+
+        AC_MSG_RESULT($withval)
+        if test "$withval" = "no"
+        then
+            ax_python_use=false
+        else
+            if test "$withval" = "yes"
+            then
+                # "yes" was specified, but we don't have a path
+                # for the executable.
+                # So, let's search the PATH Environment Variable.
+                AC_PATH_PROGS(
+                    [PYTHON],
+                    [python2.7 python2.6 python2.5 python2.4 python2.3 python2.2 python2.1 python2 python],
+                    [],
+                    $2
+                )
+            else
+                # $withval must be the executable path then.
+                AC_SUBST([PYTHON], ["${withval}"])
+            fi
+            if test -z "$PYTHON"
+            then
+                AC_MSG_RESULT([no path to python found, skipping python interface!])
+            else
+                AX_PYTHON_VERSION_CHECK([$1],
+                  [ AC_MSG_RESULT(yes)
+                    AX_PYTHON_VERSION_CHECK([3],
+                    [ ax_python_use=false
+                      AC_MSG_RESULT([too recent, skipping python interface!])
+                    ],
+                    [ AC_MSG_RESULT([no (ok)])
+                      ax_python_version=`$PYTHON -c "import sys; print '.'.join(sys.version.split('.')[[:2]])"`
+                      AC_CHECK_LIB([python${ax_python_version}],[main], [
+                          ax_python_use=true
+                          si_embed_python=$si_try_embed
+                          AC_MSG_CHECKING(embedding python interface module)
+                          AC_MSG_RESULT($si_try_embed)
+                          AX_PYTHON_PREFIX( )
+                          AX_PYTHON_LSPEC( )
+                          AX_PYTHON_CSPEC( )
+                        ],
+                        [ ax_python_use=false
+                          AC_MSG_RESULT([Cannot link to python, skipping python interface!])
+                        ]
+                      )
+                    ])
+                  ],
+                  [ ax_python_use=false
+                    AC_MSG_RESULT([too old, skipping python interface!])]
+                )
+            fi
+        fi
+
+        if  test x"$si_embed_python" = x"yes"
+        then
+          AC_DEFINE(EMBED_PYTHON,1,integrate python)
+#          AC_SUBST(EMBED_PYOBJECT_CFLAGS,"\${PYTHON_CSPEC}")
+#          AC_SUBST(EMBED_PYOBJECT_LDFLAGS,"\${PYTHON_LSPEC}")
+        fi
+	if test x"$ax_python_use" = x"true"
+	then
+          AC_DEFINE(HAVE_PYTHON,1,[compile python-related stuff])
+        fi
+    fi
+
+    AM_CONDITIONAL(PYTHON_USE, test x"$ax_python_use" = x"true")
+    AM_CONDITIONAL(SI_EMBED_PYTHON, test x"$ax_python_use$si_embed_python" = x"trueyes")
+    AM_CONDITIONAL(PYTHON_MODULE, test x"$ax_python_use" = x"true" -a x"$si_embed_python" != x"yes" )
+
+])
+
diff --git a/m4/cpu-check.m4 b/m4/cpu-check.m4
new file mode 100644
index 0000000..0c91348
--- /dev/null
+++ b/m4/cpu-check.m4
@@ -0,0 +1,67 @@
+# Check the cpu type
+
+dnl SING_CHECK_CPU
+dnl
+dnl check the cpu and define EXEC_EXT and SI_CPU*
+
+AC_DEFUN([SING_CHECK_CPU],
+[
+AC_CANONICAL_HOST
+AC_MSG_CHECKING(CPU for singular)
+
+# CPUUNAME and PATH
+ac_cv_singcpuname=`uname -m`
+AC_MSG_RESULT($ac_cv_singcpuname)
+
+if test "$ac_cv_singcpuname" = i386; then
+  AC_DEFINE(SI_CPU_I386,1,"i386")
+  AC_SUBST(SI_CPU_I386)
+fi
+if test "$ac_cv_singcpuname" = i686; then
+  AC_DEFINE(SI_CPU_I386,1,"i686")
+  AC_SUBST(SI_CPU_I386)
+fi
+if test "$ac_cv_singcpuname" = x86_64; then
+  AC_DEFINE(SI_CPU_X86_64,1,"x86-64")
+  AC_SUBST(SI_CPU_X86_64)
+fi
+if test "$ac_cv_singcpuname" = ia64; then
+  AC_DEFINE(SI_CPU_IA64,1,"ia64")
+  AC_SUBST(SI_CPU_IA64)
+fi
+if test "$ac_cv_singcpuname" = sparc; then
+  AC_DEFINE(SI_CPU_SPARC,1,"SPARC")
+  AC_SUBST(SI_CPU_SPARC)
+fi
+if test "$ac_cv_singcpuname" = ppc; then
+  AC_DEFINE(SI_CPU_PPC,1,"PPC")
+  AC_SUBST(SI_CPU_PPC)
+fi
+
+# UNAME and PATH
+AC_MSG_CHECKING(uname for Singular)
+
+#ac_cv_singuname=`./config.guess`
+ac_cv_singuname=`uname -m`-`uname -s`
+AC_MSG_RESULT($ac_cv_singuname)
+AC_DEFINE_UNQUOTED(S_UNAME, "$ac_cv_singuname", Singular\'s own uname\, believe it or not)
+
+
+AS_CASE([$host_cpu],
+dnl the following settings seems to be better on i386 and x86_64 processors
+  [i*86*|x86_64*], [AC_DEFINE(HAVE_MULT_MOD,1,multiplication is fast on the cpu: a*b is with mod otherwise using tables of logartihms)],
+dnl the following settings seems to be better on itanium processors
+dnl AC_DEFINE(HAVE_MULT_MOD,1,)
+  [ia64*], [AC_DEFINE(HAVE_GENERIC_ADD,1,use branch for addition in Z/p otherwise it uses a generic add)],
+dnl the following settings seems to be better on sparc processors
+  [sparc*], [
+  	    AC_DEFINE(HAVE_MULT_MOD,1,multiplication is fast on the cpu: a*b is with mod otherwise using tables of logartihms)
+	    AC_DEFINE(HAVE_DIV_MOD,1,division using extend euclidian algorithm otherwise using tables of logartihms)
+	    ],
+dnl the following settings seems to be better on ppc processors
+dnl testet on: ppc_Linux, 740/750 PowerMac G3, 512k L2 cache
+  [powerpc*|ppc*], [AC_DEFINE(HAVE_MULT_MOD,1,multiplication is fast on the cpu: a*b is with mod otherwise using tables of logartihms)],
+  []
+)
+
+])
diff --git a/m4/dbm-check.m4 b/m4/dbm-check.m4
new file mode 100644
index 0000000..bc76258
--- /dev/null
+++ b/m4/dbm-check.m4
@@ -0,0 +1,17 @@
+AC_DEFUN([SING_CHECK_DBM],
+[
+
+AC_ARG_WITH(
+  dbm,
+  [  --without-dbm           do not use dbm (no DBM links)])
+
+AC_MSG_CHECKING(whether to have dbm links)
+
+if test "$with_dbm" != no; then
+  AC_DEFINE([HAVE_DBM], [1], [Define to have dbm links])
+  AC_MSG_RESULT(yes)
+else
+  AC_MSG_RESULT(no)
+fi
+
+])
diff --git a/m4/flags.m4 b/m4/flags.m4
new file mode 100644
index 0000000..d78fea6
--- /dev/null
+++ b/m4/flags.m4
@@ -0,0 +1,155 @@
+AC_DEFUN([SING_SHOW_FLAGS], [
+
+echo "/* --------------- $1 --------------- */";
+
+AC_MSG_CHECKING([  CFLAGS?..])
+AC_MSG_RESULT(${CFLAGS:-unset})
+AC_MSG_CHECKING([CXXFLAGS?..])
+AC_MSG_RESULT(${CXXFLAGS:-unset})
+AC_MSG_CHECKING([CPPFLAGS?..])
+AC_MSG_RESULT(${CPPFLAGS:-unset})
+AC_MSG_CHECKING([    DEFS?..])
+AC_MSG_RESULT(${DEFS:-unset})
+AC_MSG_CHECKING([ LDFLAGS?..])
+AC_MSG_RESULT(${LDFLAGS:-unset})
+AC_MSG_CHECKING([    LIBS?..])
+AC_MSG_RESULT(${LIBS:-unset})
+AC_MSG_CHECKING([     GCC?..])
+AC_MSG_RESULT(${GCC:-unset})
+AC_MSG_CHECKING([      CC?..])
+AC_MSG_RESULT(${CC:-unset})
+AC_MSG_CHECKING([     GXX?..])
+AC_MSG_RESULT(${GXX:-unset})
+AC_MSG_CHECKING([     CXX?..])
+AC_MSG_RESULT(${CXX:-unset})
+
+# echo "/* =============== $1 =============== */";
+])
+
+AC_DEFUN([SING_RESET_FLAGS], [
+ AC_MSG_WARN([Please note that we set empty defaults for \`CFLAGS' and \`CXXFLAGS' (instead of \`-g -O')])
+ : ${CFLAGS:=""}
+ : ${CXXFLAGS:=""}
+])
+
+
+AC_DEFUN([SING_CHECK_SET_ARGS], [
+#  SING_SHOW_FLAGS([Initial state?...])dnl
+
+ AC_ARG_ENABLE([debug],
+  AS_HELP_STRING([--enable-debug], [build the debugging version of the libraries]),
+  [ENABLE_DEBUG="$enableval"], [ENABLE_DEBUG=""])
+
+ AC_MSG_CHECKING([debugging checks should be embedded])
+ if test "x${ENABLE_DEBUG}" != xyes; then
+  AC_MSG_RESULT([no])
+ else
+  AC_MSG_RESULT([yes])
+ fi
+
+ AC_ARG_ENABLE([optimizationflags],
+  AS_HELP_STRING([--disable-optimizationflags], [build the without default optimization flags]),
+  [ENABLE_OPTIMIZATION="$enableval"], [ENABLE_OPTIMIZATION="yeah"])
+
+ if test "x${ENABLE_DEBUG}" = xyes; then
+  SINGULAR_CFLAGS=""
+  if test "x${ENABLE_OPTIMIZATION}" = xyeah; then
+   ENABLE_OPTIMIZATION="no"
+   AC_MSG_WARN([Please note that we disable implicit (default) optimization flags since you have enabled the debug flags... ])
+  fi
+ else
+  SINGULAR_CFLAGS="-DSING_NDEBUG -DOM_NDEBUG"
+  # for now let '-DSING_NDEBUG -DOM_NDEBUG' be here...
+  AC_DEFINE([OM_NDEBUG],1,"Disable OM Debug")
+  AC_DEFINE([SING_NDEBUG],1,"Disable Singular Debug")
+ fi
+
+ if test "x${ENABLE_OPTIMIZATION}" = xyeah; then
+   ENABLE_OPTIMIZATION="yes"
+ fi
+
+ if test "x${ENABLE_OPTIMIZATION}" = xyes; then
+  if test "x${ENABLE_DEBUG}" = xyes; then
+   AC_MSG_WARN([Please note that you will be using our optimization flags together with debug flags... ])
+  fi
+ fi
+
+ AC_MSG_CHECKING([whether optimization flags should be used])
+ if test "x${ENABLE_OPTIMIZATION}" = xyes; then
+  AC_MSG_RESULT([yes])
+ else
+  AC_MSG_RESULT([no])
+ fi
+
+
+ AM_CONDITIONAL(WANT_DEBUG, test x"${ENABLE_DEBUG}" = xyes)
+ AM_CONDITIONAL(WANT_OPTIMIZATIONFLAGS, test x"${ENABLE_OPTIMIZATION}" = xyes)
+
+ AC_DEFINE_UNQUOTED([SINGULAR_CFLAGS],"$SINGULAR_CFLAGS",[SINGULAR_CFLAGS])
+ AC_SUBST(SINGULAR_CFLAGS)
+
+# SING_SHOW_FLAGS([checking flags....])
+
+ FLAGS="-pipe -fno-common"
+ AC_LANG_PUSH([C])
+ AX_APPEND_COMPILE_FLAGS(${FLAGS}, [CFLAGS])
+ AC_LANG_POP([C])
+
+ AC_LANG_PUSH([C++])
+ AX_APPEND_COMPILE_FLAGS(${FLAGS}, [CXXFLAGS])
+ AX_APPEND_COMPILE_FLAGS([-fexceptions -frtti], [POLYMAKE_CXXFLAGS])
+ AC_LANG_POP([C++])
+
+ AX_APPEND_LINK_FLAGS(${FLAGS})
+
+ AC_SUBST(POLYMAKE_CXXFLAGS)
+
+ if test "x${ENABLE_DEBUG}" = xyes; then
+  DBGFLAGS="-g -ftrapv -fdiagnostics-show-option -Wall -Wextra"
+  #  -pedantic too strict ??? -Wvla -Wno-long-long ???
+  AC_LANG_PUSH([C])
+  AX_APPEND_COMPILE_FLAGS(${DBGFLAGS}, [CFLAGS])
+  AC_LANG_POP([C])
+  AC_LANG_PUSH([C++])
+  AX_APPEND_COMPILE_FLAGS(${DBGFLAGS}, [CXXFLAGS])
+  AC_LANG_POP([C++])
+  AX_APPEND_LINK_FLAGS(${DBGFLAGS})
+ fi
+
+ ## for clang: -Wunneeded-internal-declaration
+
+ if test "x${ENABLE_OPTIMIZATION}" != xno; then
+  OPTFLAGS="-O3 -Wno-unused-function -Wno-trigraphs -Wno-unused-parameter -Wunknown-pragmas -Wno-unused-variable -fomit-frame-pointer -fwrapv -fvisibility=default -finline-functions -fno-exceptions -fno-rtti -fno-threadsafe-statics -fno-enforce-eh-specs -fconserve-space -funroll-loops"
+  #  -O3 - crashes gcc???!!!
+  # -fpermissive
+  AC_LANG_PUSH([C])
+  AX_APPEND_COMPILE_FLAGS(${OPTFLAGS}, [CFLAGS])
+  AC_LANG_POP([C])
+  AC_LANG_PUSH([C++])
+  AX_APPEND_COMPILE_FLAGS(${OPTFLAGS}, [CXXFLAGS])
+#   AX_APPEND_COMPILE_FLAGS([-fno-threadsafe-statics -fno-enforce-eh-specs -fconserve-space], [CXXFLAGS])
+###  AX_APPEND_COMPILE_FLAGS([-fno-implicit-templates], [CXXFLAGS]) # problems due to STL
+  AC_LANG_POP([C++])
+  AX_APPEND_LINK_FLAGS(${OPTFLAGS})
+#  AX_APPEND_LINK_FLAGS([-fno-threadsafe-statics -fno-enforce-eh-specs -fconserve-space])
+###  AX_APPEND_LINK_FLAGS([-fno-implicit-templates]) # see above :(
+#  AX_APPEND_LINK_FLAGS([ ])
+ fi
+
+ FLAGS2="-Qunused-arguments"
+ AC_LANG_PUSH([C])
+ AX_APPEND_COMPILE_FLAGS(${FLAGS2}, [CFLAGS])
+ AC_LANG_POP([C])
+
+ AC_LANG_PUSH([C++])
+ AX_APPEND_COMPILE_FLAGS(${FLAGS2}, [CXXFLAGS])
+ AC_LANG_POP([C++])
+
+ AX_APPEND_LINK_FLAGS(${FLAGS2})
+
+# SING_SHOW_FLAGS([before PROG_C_CC])
+
+
+AC_PROG_CC
+AC_PROG_CXX
+])
diff --git a/m4/flint-check.m4 b/m4/flint-check.m4
new file mode 100755
index 0000000..814a408
--- /dev/null
+++ b/m4/flint-check.m4
@@ -0,0 +1,128 @@
+# Check for FLINT
+# Bradford Hovinen, 2001-06-13
+# Modified by Pascal Giorgi, 2003-12-03
+# Inspired by gnome-bonobo-check.m4 by Miguel de Icaza, 99-04-12
+# Stolen from Chris Lahey       99-2-5
+# stolen from Manish Singh again
+# stolen back from Frank Belew
+# stolen from Manish Singh
+# Shamelessly stolen from Owen Taylor
+
+dnl LB_CHECK_FLINT ([MINIMUM-VERSION [, ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
+dnl
+dnl Test for FLINT and define
+dnl FLINT_CFLAGS and FLINT_LIBS
+
+AC_DEFUN([LB_CHECK_FLINT],
+[
+DEFAULT_CHECKING_PATH="/usr /usr/local /sw /opt/local"
+
+AC_ARG_WITH(flint,
+[  --with-flint=<path>|yes|no  Use FLINT library. If argument is no, you do not have
+                            the library installed on your machine (set as
+			    default). If argument is yes or <empty> that means
+			    the library is reachable with the standard search
+			    path (/usr or /usr/local). Otherwise you give the
+			    <path> to the directory which contain the library.
+	     ],
+	     [if test "$withval" = yes ; then
+			FLINT_HOME_PATH="${DEFAULT_CHECKING_PATH}"
+	      elif test "$withval" != no ; then
+			FLINT_HOME_PATH="$withval"
+	     fi],
+	     [FLINT_HOME_PATH="${DEFAULT_CHECKING_PATH}"])
+
+min_flint_version=ifelse([$1], ,2.3,$1)
+
+
+dnl Check for existence
+BACKUP_CFLAGS=${CFLAGS}
+BACKUP_LIBS=${LIBS}
+
+if test -n "$FLINT_HOME_PATH"; then
+AC_MSG_CHECKING(for FLINT >= $min_flint_version)
+fi
+
+AC_LANG_PUSH([C])
+
+for FLINT_HOME in ${FLINT_HOME_PATH}
+ do
+## if test -r "$FLINT_HOME/include/flint/fmpz.h"; then
+
+	if test "x$FLINT_HOME" != "x/usr"; then
+		FLINT_CFLAGS="-I${FLINT_HOME}/include/"
+		FLINT_LIBS="-L${FLINT_HOME}/lib"
+	else
+		FLINT_CFLAGS=""
+		FLINT_LIBS=""
+	fi
+
+	# we suppose that mpfr and mpir to be in the same place or available by default
+	FLINT_LIBS="$FLINT_LIBS -lflint -lmpfr"
+
+	CFLAGS="${BACKUP_CFLAGS} ${FLINT_CFLAGS} ${GMP_CFLAGS}"
+	LIBS="${BACKUP_LIBS} ${FLINT_LIBS} ${GMP_LIBS}"
+
+	AC_TRY_LINK(
+	[#include <flint/fmpz.h>],
+	[fmpz_t a; fmpz_init (a);],
+	[
+	AC_TRY_RUN(
+	[#include <flint/flint.h>
+	int main () { if ((int) version[0] < 2) return -1; else return 0; }
+	],[
+	flint_found="yes"
+	break
+	],[
+	flint_problem="$problem $FLINT_HOME"
+	unset FLINT_CFLAGS
+	unset FLINT_LIBS
+	],[
+	flint_found="yes"
+	flint_cross="yes"
+	break
+	])
+	],
+	[
+	flint_found="no"
+	flint_checked="$checked $FLINT_HOME"
+	unset FLINT_CFLAGS
+	unset FLINT_LIBS
+	])
+#else
+#	flint_found="no"
+#fi
+done
+AC_LANG_POP([C])
+
+CFLAGS=${BACKUP_CFLAGS}
+LIBS=${BACKUP_LIBS}
+#unset LD_LIBRARY_PATH
+
+
+if test "x$flint_found" = "xyes" ; then
+	AC_SUBST(FLINT_CFLAGS)
+	AC_SUBST(FLINT_LIBS)
+	AC_SUBST(FLINT_HOME)
+	AC_DEFINE(HAVE_FLINT,1,[Define if FLINT is installed])
+	HAVE_FLINT=yes
+	if test "x$flint_cross" != "xyes"; then
+		AC_MSG_RESULT(found)
+	else
+		AC_MSG_RESULT(unknown)
+		echo "WARNING: You appear to be cross compiling, so there is no way to determine"
+		echo "whether your FLINT version is new enough. I am assuming it is."
+	fi
+	ifelse([$2], , :, [$2])
+elif test -n "$flint_problem"; then
+	AC_MSG_RESULT(problem)
+	echo "Sorry, your FLINT version is too old. Disabling."
+	ifelse([$3], , :, [$3])
+elif test   "x$flint_found" = "xno";  then
+	AC_MSG_RESULT(not found)
+	ifelse([$3], , :, [$3])
+fi
+
+AM_CONDITIONAL(SING_HAVE_FLINT, test "x$HAVE_FLINT" = "xyes")
+])
+
diff --git a/m4/gfanlib-check.m4 b/m4/gfanlib-check.m4
new file mode 100644
index 0000000..4d13173
--- /dev/null
+++ b/m4/gfanlib-check.m4
@@ -0,0 +1,76 @@
+# gfanlib.m4
+
+AC_DEFUN([SING_CHECK_GFANLIB],
+[
+
+AC_ARG_ENABLE(gfanlib,
+AS_HELP_STRING([--enable-gfanlib], [Enables gfanlib, a package for basic convex geometry]),
+[ENABLE_GFANLIB="$enableval"],
+[ENABLE_GFANLIB=""])
+
+AC_MSG_CHECKING(whether to check for gfanlib)
+
+if test "x$ENABLE_GFANLIB" != "xno"; then
+ AC_MSG_RESULT([yes])
+
+ AC_CHECK_HEADERS([setoper.h cdd/setoper.h cddlib/setoper.h])
+
+ if test "x$ac_cv_header_setoper_h" = xno -a "x$ac_cv_header_cdd_setoper_h" = xno -a "x$ac_cv_header_cddlib_setoper_h" = xno; then
+   AC_MSG_WARN([Note that setoper.h is missing!])
+ fi
+
+ AC_MSG_CHECKING([whether libcddgmp is usable])
+
+ BACKUP_LIBS=$LIBS
+
+ LIBS="$LIBS -lcddgmp $GMP_LIBS "
+
+ AC_LANG_PUSH(C)
+ AC_LINK_IFELSE(
+  [
+   AC_LANG_PROGRAM(
+    [
+    #define GMPRATIONAL
+     #ifdef HAVE_SETOPER_H
+     # include <setoper.h>
+     # include <cdd.h>
+     #endif
+     #ifdef HAVE_CDD_SETOPER_H
+     # include <cdd/setoper.h>
+     # include <cdd/cdd.h>
+     #endif
+     #ifdef HAVE_CDDLIB_SETOPER_H
+     # include <cddlib/setoper.h>
+     # include <cddlib/cdd.h>
+     #endif
+    ], [dd_set_global_constants(); dd_log=dd_FALSE; ]
+    )
+  ],
+  [PASSED_ALL_TESTS_FOR_GFANLIB="1"] [CDDGMPLDFLAGS="-lcddgmp $GMP_LIBS"]  [CDDGMPCPPFLAGS="-DGMPRATIONAL"],
+  [PASSED_ALL_TESTS_FOR_GFANLIB="0"]
+ )
+ AC_LANG_POP()
+
+ LIBS=$BACKUP_LIBS
+
+ if test "x$PASSED_ALL_TESTS_FOR_GFANLIB" = x1; then
+  AC_MSG_RESULT([yes])
+  AC_SUBST(CDDGMPLDFLAGS)
+  AC_SUBST(CDDGMPCPPFLAGS)
+ else
+  AC_MSG_RESULT([no])
+  if test "x$ENABLE_GFANLIB" = "xyes"; then
+   AC_MSG_ERROR([Error, could not use libcddgmp])
+  fi
+ fi
+else
+ AC_MSG_RESULT(no)
+ PASSED_ALL_TESTS_FOR_GFANLIB="0"
+fi
+
+
+
+AM_CONDITIONAL(HAVE_GFANLIB, test "x$PASSED_ALL_TESTS_FOR_GFANLIB" = x1)
+AC_DEFINE_UNQUOTED(HAVE_GFANLIB, ${PASSED_ALL_TESTS_FOR_GFANLIB}, [whether gfanlib support is enabled])
+
+])
diff --git a/m4/gmp-check.m4 b/m4/gmp-check.m4
new file mode 100644
index 0000000..9c4a2d4
--- /dev/null
+++ b/m4/gmp-check.m4
@@ -0,0 +1,132 @@
+# Check for GMP
+# Modified by Pascal Giorgi, 2003-12-03
+
+dnl LB_CHECK_GMP ([MINIMUM-VERSION [, ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
+dnl
+dnl Test for the GNU Multiprecision library and define GMP_CFLAGS and GMP_LIBS
+
+AC_DEFUN([LB_CHECK_GMP],
+[
+DEFAULT_CHECKING_PATH="/usr /usr/local /sw /opt/local"
+
+AC_ARG_WITH(gmp,
+[  --with-gmp= <path>|yes Use GMP library. This library is mandatory for Singular
+	                 compilation. If argument is yes or <empty> that means
+   	       		 the library is reachable with the standard search path
+			 "/usr" or "/usr/local" (set as default). Otherwise you
+			 give the <path> to the directory which contain the
+			 library.
+],
+		[if test "$withval" = yes ; then
+			GMP_HOME_PATH="${DEFAULT_CHECKING_PATH}"
+	         elif test "$withval" != no ; then
+			GMP_HOME_PATH="$withval ${DEFAULT_CHECKING_PATH}"
+	        fi],
+		[GMP_HOME_PATH="${DEFAULT_CHECKING_PATH}"])
+
+min_gmp_version=ifelse([$1], ,1.0,$1)
+
+dnl Check for existence
+BACKUP_CFLAGS=${CFLAGS}
+BACKUP_LIBS=${LIBS}
+
+AC_MSG_CHECKING(for GMP >= $min_gmp_version)
+
+AC_LANG_PUSH([C])
+
+for GMP_HOME in ${GMP_HOME_PATH}
+  do
+#	if test -r "$GMP_HOME/include/gmp.h"; then
+
+		if test "x$GMP_HOME" != "x/usr"; then
+			GMP_CFLAGS="-I${GMP_HOME}/include"
+			GMP_LIBS="-L${GMP_HOME}/lib -Wl,-rpath -Wl,${GMP_HOME}/lib -lgmp"
+		else
+			GMP_CFLAGS=""
+			GMP_LIBS="-lgmp"
+		fi
+
+		CFLAGS="${BACKUP_CFLAGS} ${GMP_CFLAGS}"
+		LIBS="${BACKUP_LIBS} ${GMP_LIBS}"
+
+    # According to C. Fieker this would link but would not RUN
+    # (AC_TRY_RUN) due to missing SHARED libgmp.so :(
+    # TODO: set LD_LIBRARY_PATH???
+		AC_TRY_LINK(
+		[#include <gmp.h>],
+		[mpz_t a; mpz_init (a);],
+		[
+        		AC_TRY_RUN(
+ 			[#include <gmp.h>
+			 int main () {  if (__GNU_MP_VERSION < 3) return -1; else return 0; }
+		  	],[
+				AC_MSG_RESULT(found)
+				AC_SUBST(GMP_CFLAGS)
+		  		AC_SUBST(GMP_LIBS)
+				AC_DEFINE(HAVE_GMP,1,[Define if GMP is installed])
+				# See if we are running GMP 4.0
+	   			AC_MSG_CHECKING(whether GMP is 4.0 or greater)
+		   		AC_TRY_RUN(
+		   		[#include <gmp.h>
+	    			int main () { if (__GNU_MP_VERSION < 4) return -1; else return 0; }
+	   			],[
+					gmp_found="yes"
+					AC_MSG_RESULT(yes)
+					GMP_VERSION=""
+					AC_SUBST(GMP_VERSION)
+				],[
+					AC_MSG_RESULT(no)
+					AC_DEFINE(GMP_VERSION_3,1,[Define if GMP is version 3.xxx])
+					GMP_VERSION="-DGMP_VERSION_3"
+					AC_SUBST(GMP_VERSION)
+				],[
+					dnl This should never happen
+					AC_MSG_RESULT(no)
+				])
+				ifelse([$2], , :, [$2])
+				break
+			],[
+				gmp_problem="$gmp_problem $GMP_HOME"
+				unset GMP_CFLAGS
+				unset GMP_LIBS
+			],[
+				AC_MSG_RESULT(unknown)
+				echo "WARNING: You appear to be cross compiling, so there is no way to determine"
+				echo "whether your GMP version is new enough. I am assuming it is."
+				AC_SUBST(GMP_CFLAGS)
+				AC_SUBST(GMP_LIBS)
+				AC_SUBST(GMP_HOME)
+				HAVE_GMP=yes
+				AC_DEFINE(HAVE_GMP,1,[Define if GMP is installed])
+				ifelse([$2], , :, [$2])
+				break
+			])
+		],[
+		gmp_found="no"
+		unset GMP_CFLAGS
+		unset GMP_LIBS
+		])
+
+#	else
+#		gmp_found="no"
+#	fi
+done
+AC_LANG_POP([C])
+
+CFLAGS=${BACKUP_CFLAGS}
+LIBS=${BACKUP_LIBS}
+#unset LD_LIBRARY_PATH
+
+
+if test "x$gmp_found" != "xyes"; then
+	if test -n "$gmp_problem"; then
+		AC_MSG_RESULT(problem)
+		echo "Sorry, your GMP version is too old. Disabling."
+	elif test "x$gmp_found" != "xno"; then
+		AC_MSG_RESULT(not found)
+	fi
+	ifelse($3, , :, $3)
+fi
+
+AM_CONDITIONAL(SING_HAVE_GMP, test "x$HAVE_GMP" = "xyes")
+])
diff --git a/m4/google-perftools.m4 b/m4/google-perftools.m4
new file mode 100644
index 0000000..229b7c6
--- /dev/null
+++ b/m4/google-perftools.m4
@@ -0,0 +1,183 @@
+dnl
+dnl    Copyright 2005-2006 Intel Corporation
+dnl
+dnl    Licensed under the Apache License, Version 2.0 (the "License");
+dnl    you may not use this file except in compliance with the License.
+dnl    You may obtain a copy of the License at
+dnl
+dnl        http://www.apache.org/licenses/LICENSE-2.0
+dnl
+dnl    Unless required by applicable law or agreed to in writing, software
+dnl    distributed under the License is distributed on an "AS IS" BASIS,
+dnl    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+dnl    See the License for the specific language governing permissions and
+dnl    limitations under the License.
+dnl
+
+dnl
+dnl Autoconf support for linking with google's performace code
+dnl
+
+AC_DEFUN([AC_CONFIG_GOOGLE_PERFTOOLS], [
+
+    ac_google_perfdir='no'
+    AC_ARG_WITH(google-perftools,
+        AC_HELP_STRING([--with-google-perftools=DIR],
+            [location of a google perftools installation (default none)]),
+        ac_google_perfdir=$withval)
+
+    AC_ARG_ENABLE(google-profiling,
+                  AC_HELP_STRING([--enable-google-profiling],
+		  [compile with google profiling]),
+                  [google_profile=$enableval],
+                  [google_profile=no])
+
+    AC_MSG_CHECKING([whether to compile with google profiling])
+    AC_MSG_RESULT($google_profile)
+
+    GOOGLE_PROFILE_ENABLED=0
+    if test $google_profile = yes ; then
+        if test $ac_google_perfdir = no ; then
+	   AC_MSG_ERROR([must specify --with-google-perftools to use google profiling])
+	fi
+        GOOGLE_PROFILE_ENABLED=1
+    fi
+
+    AC_DEFINE_UNQUOTED(GOOGLE_PROFILE_ENABLED, $GOOGLE_PROFILE_ENABLED,
+	 [whether google profiling support is enabled])
+
+    dnl
+    dnl First make sure we even want it
+    dnl
+    if test "$ac_google_perfdir" = no; then
+    GOOGLE_PERFTOOLS_ENABLED=0
+    else
+
+    GOOGLE_PERFTOOLS_ENABLED=1
+    AC_DEFINE_UNQUOTED(GOOGLE_PERFTOOLS_ENABLED, 1,
+	 [whether google perftools support is enabled])
+
+    dnl
+    dnl Now check if we have a cached value, unless the user specified
+    dnl something explicit with the --with-google-perf= argument, in
+    dnl which case we force it to redo the checks (i.e. ignore the
+    dnl cached values)
+    dnl
+    if test "$ac_google_perfdir" = yes -a \
+	    ! "$oasys_cv_path_google_perf_h" = "" ; then
+        echo "checking for google_perf installation... (cached)"
+    else
+        AC_OASYS_FIND_GOOGLE_PERFTOOLS
+    fi
+
+    if test ! $oasys_cv_path_google_perf_h = /usr/include ; then
+        GOOGLE_PERFTOOLS_CFLAGS="-I$oasys_cv_path_google_perf_h"
+    fi
+
+    if test ! $oasys_cv_path_google_perf_lib = /usr/lib ; then
+        GOOGLE_PERFTOOLS_LDFLAGS="-L$oasys_cv_path_google_perf_lib"
+    fi
+
+    GOOGLE_PERFTOOL_LDFLAGS="$GOOGLE_PERFTOOLS_LDFLAGS -Wl,-Bstatic -lprofiler -Wl,-Bdynamic"
+
+    fi # GOOGLE_PERF_ENABLED
+])
+
+AC_DEFUN([AC_OASYS_FIND_GOOGLE_PERFTOOLS], [
+    oasys_cv_path_google_perf_h=
+    oasys_cv_path_google_perf_lib=
+
+    ac_save_CPPFLAGS="$CPPFLAGS"
+    ac_save_LDFLAGS="$LDFLAGS"
+    ac_save_LIBS="$LIBS"
+
+    AC_LANG_PUSH(C++)
+
+    if test "$ac_google_perfdir" = system -o \
+            "$ac_google_perfdir" = yes -o \
+            "$ac_google_perfdir" = "" ;
+    then
+        ac_google_perfincdirs="/usr/local/include \
+	                       /usr/local/google-perftools/include"
+        ac_google_perflibdirs="/usr/local/lib \
+	                       /usr/local/google-perftools/lib"
+    else
+        ac_google_perfincdirs="$ac_google_perfdir/include"
+        ac_google_perflibdirs="$ac_google_perfdir/lib"
+    fi
+
+    for ac_google_perfincdir in $ac_google_perfincdirs; do
+
+	CPPFLAGS="$ac_save_CPPFLAGS -I$ac_google_perfincdir"
+	LDFLAGS="$ac_save_LDFLAGS"
+	LIBS="$ac_save_LIBS"
+
+	dnl
+	dnl First check the version in the header file. If there's a match,
+	dnl fall through to the other check to make sure it links.
+	dnl If not, then we can break out of the two inner loops.
+	dnl
+        AC_MSG_CHECKING([for google perftools header profiler.h in $ac_google_perfincdir])
+	AC_LINK_IFELSE(
+	  [AC_LANG_PROGRAM(
+	    [
+                #include <google/profiler.h>
+            ],
+
+            [
+            ])],
+          [
+	      AC_MSG_RESULT([yes])
+              oasys_cv_path_google_perf_h=$ac_google_perfincdir
+	      break
+          ],
+          [
+              AC_MSG_RESULT([no])
+	      continue
+          ])
+    done
+
+    AC_LANG_POP(C++)
+
+    if test x$oasys_cv_path_google_perf_h = x ; then
+        AC_MSG_ERROR([can't find usable google perftools installation])
+    fi
+
+    AC_LANG_PUSH(C++)
+
+    for ac_google_perflibdir in $ac_google_perflibdirs; do
+
+	LDFLAGS="$ac_save_LDFLAGS -L$ac_google_perflibdir"
+        LIBS="$ac_save_LIBS -lprofiler"
+
+        AC_MSG_CHECKING([for google perftolos library libprofiler in $ac_google_perflibdir])
+	AC_LINK_IFELSE(
+	  [AC_LANG_PROGRAM(
+	    [
+                #include <google/profiler.h>
+            ],
+
+            [
+		ProfilerStart("test");
+            ])],
+
+          [
+              AC_MSG_RESULT([yes])
+              oasys_cv_path_google_perf_lib=$ac_google_perflibdir
+              break
+          ],
+          [
+              AC_MSG_RESULT([no])
+          ])
+    done
+
+    CPPFLAGS="$ac_save_CPPFLAGS"
+    LDFLAGS="$ac_save_LDFLAGS"
+    LIBS="$ac_save_LIBS"
+
+    AC_LANG_POP(C++)
+
+    if test x$oasys_cv_path_google_perf_lib = x ; then
+        AC_MSG_ERROR([can't find usable google perftools library])
+    fi
+])
diff --git a/m4/libtool.m4 b/m4/libtool.m4
new file mode 100644
index 0000000..bc28ccc
--- /dev/null
+++ b/m4/libtool.m4
@@ -0,0 +1,7995 @@
+# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*-
+#
+#   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
+#                 2006, 2007, 2008, 2009, 2010, 2011 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, 2009, 2010, 2011 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 57 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_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl
+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
+
+_LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}])
+
+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 "$cc_temp" | $SED "s%.*/%%; 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
+AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl
+AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl
+
+_LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl
+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_PATH_CONVERSION_FUNCTIONS])dnl
+m4_require([_LT_CMD_RELOAD])dnl
+m4_require([_LT_CHECK_MAGIC_METHOD])dnl
+m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl
+m4_require([_LT_CMD_OLD_ARCHIVE])dnl
+m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl
+m4_require([_LT_WITH_SYSROOT])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
+
+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
+
+# 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_PREPARE_SED_QUOTE_VARS
+# --------------------------
+# Define a few sed substitution that help us do robust quoting.
+m4_defun([_LT_PREPARE_SED_QUOTE_VARS],
+[# Backslashify 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'
+])
+
+# _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
+
+
+## ------------------------------------- ##
+## Accumulate code for creating libtool. ##
+## ------------------------------------- ##
+
+# 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], [[!?.]$], [], [.])
+)])
+
+
+
+## ------------------------ ##
+## FIXME: Eliminate VARNAME ##
+## ------------------------ ##
+
+
+# _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 "$][$1" | $SED "$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 "$<var>" | $SED "$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'
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+  eval 'cat <<_LTECHO_EOF
+\$[]1
+_LTECHO_EOF'
+}
+
+# Quote evaled strings.
+for var in lt_decl_all_varnames([[ \
+]], lt_decl_quote_varnames); do
+    case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+    *[[\\\\\\\`\\"\\\$]]*)
+      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$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 \\\\""\\\\\$\$var"\\\\"\` in
+    *[[\\\\\\\`\\"\\\$]]*)
+      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\""
+      ;;
+    *)
+      eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+      ;;
+    esac
+done
+
+_LT_OUTPUT_LIBTOOL_INIT
+])
+
+# _LT_GENERATED_FILE_INIT(FILE, [COMMENT])
+# ------------------------------------
+# Generate a child script FILE with all initialization necessary to
+# reuse the environment learned by the parent script, and make the
+# file executable.  If COMMENT is supplied, it is inserted after the
+# `#!' sequence but before initialization text begins.  After this
+# macro, additional text can be appended to FILE to form the body of
+# the child script.  The macro ends with non-zero status if the
+# file could not be fully written (such as if the disk is full).
+m4_ifdef([AS_INIT_GENERATED],
+[m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])],
+[m4_defun([_LT_GENERATED_FILE_INIT],
+[m4_require([AS_PREPARE])]dnl
+[m4_pushdef([AS_MESSAGE_LOG_FD])]dnl
+[lt_write_fail=0
+cat >$1 <<_ASEOF || lt_write_fail=1
+#! $SHELL
+# Generated by $as_me.
+$2
+SHELL=\${CONFIG_SHELL-$SHELL}
+export SHELL
+_ASEOF
+cat >>$1 <<\_ASEOF || lt_write_fail=1
+AS_SHELL_SANITIZE
+_AS_PREPARE
+exec AS_MESSAGE_FD>&1
+_ASEOF
+test $lt_write_fail = 0 && chmod +x $1[]dnl
+m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_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])
+_LT_GENERATED_FILE_INIT(["$CONFIG_LT"],
+[# Run this file to recreate a libtool stub with the current configuration.])
+
+cat >>"$CONFIG_LT" <<\_LTEOF
+lt_cl_silent=false
+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) 2011 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.
+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)
+])# 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 '$q' "$ltmain" >> "$cfgfile" \
+     || (rm -f "$cfgfile"; exit 1)
+
+  _LT_PROG_REPLACE_SHELLFNS
+
+   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)],
+  [Go],			[_LT_LANG(GO)],
+  [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
+
+
+m4_ifndef([AC_PROG_GO], [
+############################################################
+# NOTE: This macro has been submitted for inclusion into   #
+#  GNU Autoconf as AC_PROG_GO.  When it is available in    #
+#  a released version of Autoconf we should remove this    #
+#  macro and use it instead.                               #
+############################################################
+m4_defun([AC_PROG_GO],
+[AC_LANG_PUSH(Go)dnl
+AC_ARG_VAR([GOC],     [Go compiler command])dnl
+AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl
+_AC_ARG_VAR_LDFLAGS()dnl
+AC_CHECK_TOOL(GOC, gccgo)
+if test -z "$GOC"; then
+  if test -n "$ac_tool_prefix"; then
+    AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo])
+  fi
+fi
+if test -z "$GOC"; then
+  AC_CHECK_PROG(GOC, gccgo, gccgo, false)
+fi
+])#m4_defun
+])#m4_ifndef
+
+
+# _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([AC_PROG_GO],
+  [LT_LANG(GO)],
+  [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])])
+
+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)])
+AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)])
+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], [])
+dnl AC_DEFUN([AC_LIBTOOL_RC], [])
+
+
+# _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 there is a non-empty error log, and "single_module"
+	# appears in it, assume the flag caused a linker warning
+        if test -s conftest.err && $GREP single_module conftest.err; then
+	  cat conftest.err >&AS_MESSAGE_LOG_FD
+	# Otherwise, if the output was created with a 0 exit code from
+	# the compiler, it worked.
+	elif test -f libconftest.dylib && test $_lt_result -eq 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"
+    ])
+
+    AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load],
+      [lt_cv_ld_force_load=no
+      cat > conftest.c << _LT_EOF
+int forced_loaded() { return 2;}
+_LT_EOF
+      echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD
+      $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD
+      echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD
+      $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD
+      echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD
+      $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD
+      cat > conftest.c << _LT_EOF
+int main() { return 0;}
+_LT_EOF
+      echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD
+      $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err
+      _lt_result=$?
+      if test -s conftest.err && $GREP force_load conftest.err; then
+	cat conftest.err >&AS_MESSAGE_LOG_FD
+      elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then
+	lt_cv_ld_force_load=yes
+      else
+	cat conftest.err >&AS_MESSAGE_LOG_FD
+      fi
+        rm -f conftest.err libconftest.a conftest conftest.c
+        rm -rf conftest.dSYM
+    ])
+    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" != ":" && test "$lt_cv_ld_force_load" = "no"; then
+      _lt_dsymutil='~$DSYMUTIL $lib || :'
+    else
+      _lt_dsymutil=
+    fi
+    ;;
+  esac
+])
+
+
+# _LT_DARWIN_LINKER_FEATURES([TAG])
+# ---------------------------------
+# 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
+  if test "$lt_cv_ld_force_load" = "yes"; then
+    _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+    m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes],
+                  [FC],  [_LT_TAGVAR(compiler_needs_object, $1)=yes])
+  else
+    _LT_TAGVAR(whole_archive_flag_spec, $1)=''
+  fi
+  _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=func_echo_all
+    _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([TAGNAME])
+# ----------------------------------
+# 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.
+# Store the results from the different compilers for each TAGNAME.
+# Allow to override them for all tags through lt_cv_aix_libpath.
+m4_defun([_LT_SYS_MODULE_PATH_AIX],
+[m4_require([_LT_DECL_SED])dnl
+if test "${lt_cv_aix_libpath+set}" = set; then
+  aix_libpath=$lt_cv_aix_libpath
+else
+  AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])],
+  [AC_LINK_IFELSE([AC_LANG_PROGRAM],[
+  lt_aix_libpath_sed='[
+      /Import File Strings/,/^$/ {
+	  /^0/ {
+	      s/^0  *\([^ ]*\) *$/\1/
+	      p
+	  }
+      }]'
+  _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`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 "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then
+    _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+  fi],[])
+  if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then
+    _LT_TAGVAR([lt_cv_aix_libpath_], [$1])="/usr/lib:/lib"
+  fi
+  ])
+  aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])
+fi
+])# _LT_SYS_MODULE_PATH_AIX
+
+
+# _LT_SHELL_INIT(ARG)
+# -------------------
+m4_define([_LT_SHELL_INIT],
+[m4_divert_text([M4SH-INIT], [$1
+])])# _LT_SHELL_INIT
+
+
+
+# _LT_PROG_ECHO_BACKSLASH
+# -----------------------
+# Find how we can fake an echo command that does not interpret backslash.
+# In particular, with Autoconf 2.60 or later we add some code to the start
+# of the generated configure script which will find a shell with a builtin
+# printf (which we can use as an echo command).
+m4_defun([_LT_PROG_ECHO_BACKSLASH],
+[ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
+
+AC_MSG_CHECKING([how to print strings])
+# Test print first, because it will be a builtin if present.
+if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \
+   test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then
+  ECHO='print -r --'
+elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then
+  ECHO='printf %s\n'
+else
+  # Use this function as a fallback that always works.
+  func_fallback_echo ()
+  {
+    eval 'cat <<_LTECHO_EOF
+$[]1
+_LTECHO_EOF'
+  }
+  ECHO='func_fallback_echo'
+fi
+
+# func_echo_all arg...
+# Invoke $ECHO with all args, space-separated.
+func_echo_all ()
+{
+    $ECHO "$*" 
+}
+
+case "$ECHO" in
+  printf*) AC_MSG_RESULT([printf]) ;;
+  print*) AC_MSG_RESULT([print -r]) ;;
+  *) AC_MSG_RESULT([cat]) ;;
+esac
+
+m4_ifdef([_AS_DETECT_SUGGESTED],
+[_AS_DETECT_SUGGESTED([
+  test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || (
+    ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+    ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
+    ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
+    PATH=/empty FPATH=/empty; export PATH FPATH
+    test "X`printf %s $ECHO`" = "X$ECHO" \
+      || test "X`print -r -- $ECHO`" = "X$ECHO" )])])
+
+_LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts])
+_LT_DECL([], [ECHO], [1], [An echo program that protects backslashes])
+])# _LT_PROG_ECHO_BACKSLASH
+
+
+# _LT_WITH_SYSROOT
+# ----------------
+AC_DEFUN([_LT_WITH_SYSROOT],
+[AC_MSG_CHECKING([for sysroot])
+AC_ARG_WITH([sysroot],
+[  --with-sysroot[=DIR] Search for dependent libraries within DIR
+                        (or the compiler's sysroot if not specified).],
+[], [with_sysroot=no])
+
+dnl lt_sysroot will always be passed unquoted.  We quote it here
+dnl in case the user passed a directory name.
+lt_sysroot=
+case ${with_sysroot} in #(
+ yes)
+   if test "$GCC" = yes; then
+     lt_sysroot=`$CC --print-sysroot 2>/dev/null`
+   fi
+   ;; #(
+ /*)
+   lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"`
+   ;; #(
+ no|'')
+   ;; #(
+ *)
+   AC_MSG_RESULT([${with_sysroot}])
+   AC_MSG_ERROR([The sysroot must be an absolute path.])
+   ;;
+esac
+
+ AC_MSG_RESULT([${lt_sysroot:-no}])
+_LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl
+[dependent libraries, and in which our libraries should be installed.])])
+
+# _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 '$LINENO' "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
+  ;;
+*-*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*)
+        case $host in
+        i?86-*-solaris*)
+          LD="${LD-ld} -m elf_x86_64"
+          ;;
+        sparc*-*-solaris*)
+          LD="${LD-ld} -m elf64_sparc"
+          ;;
+        esac
+        # GNU ld 2.21 introduced _sol2 emulations.  Use them if available.
+        if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then
+          LD="${LD-ld}_sol2"
+        fi
+        ;;
+      *)
+	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_PROG_AR
+# -----------
+m4_defun([_LT_PROG_AR],
+[AC_CHECK_TOOLS(AR, [ar], false)
+: ${AR=ar}
+: ${AR_FLAGS=cru}
+_LT_DECL([], [AR], [1], [The archiver])
+_LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive])
+
+AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file],
+  [lt_cv_ar_at_file=no
+   AC_COMPILE_IFELSE([AC_LANG_PROGRAM],
+     [echo conftest.$ac_objext > conftest.lst
+      lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD'
+      AC_TRY_EVAL([lt_ar_try])
+      if test "$ac_status" -eq 0; then
+	# Ensure the archiver fails upon bogus file names.
+	rm -f conftest.$ac_objext libconftest.a
+	AC_TRY_EVAL([lt_ar_try])
+	if test "$ac_status" -ne 0; then
+          lt_cv_ar_at_file=@
+        fi
+      fi
+      rm -f conftest.* libconftest.a
+     ])
+  ])
+
+if test "x$lt_cv_ar_at_file" = xno; then
+  archiver_list_spec=
+else
+  archiver_list_spec=$lt_cv_ar_at_file
+fi
+_LT_DECL([], [archiver_list_spec], [1],
+  [How to feed a file listing to the archiver])
+])# _LT_PROG_AR
+
+
+# _LT_CMD_OLD_ARCHIVE
+# -------------------
+m4_defun([_LT_CMD_OLD_ARCHIVE],
+[_LT_PROG_AR
+
+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 \$tool_oldlib"
+    ;;
+  *)
+    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib"
+    ;;
+  esac
+  old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib"
+fi
+
+case $host_os in
+  darwin*)
+    lock_old_archive_extraction=yes ;;
+  *)
+    lock_old_archive_extraction=no ;;
+esac
+_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_DECL([], [lock_old_archive_extraction], [0],
+    [Whether to use a lock for old archive extraction])
+])# _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:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&AS_MESSAGE_LOG_FD
+   echo "$as_me:$LINENO: \$? = $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 "$_lt_compiler_boilerplate" | $SED '/^$/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 "$_lt_linker_boilerplate" | $SED '/^$/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;
+    ;;
+
+  mint*)
+    # On MiNT this can take a long time and run out of memory.
+    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
+    ;;
+
+  os2*)
+    # The test takes a long time on OS/2.
+    lt_cv_sys_max_cmd_len=8192
+    ;;
+
+  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"`env echo "$teststring$teststring" 2>/dev/null` \
+	         = "X$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 $LINENO "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
+
+/* When -fvisbility=hidden is used, assume the code has been annotated
+   correspondingly for the symbols needed.  */
+#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+int fnord () __attribute__((visibility("default")));
+#endif
+
+int fnord () { return 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;
+          else puts (dlerror ());
+	}
+      /* 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:$LINENO: $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:$LINENO: \$? = $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 "$_lt_compiler_boilerplate" | $SED '/^$/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
+m4_require([_LT_CHECK_SHELL_FEATURES])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
+  case $host_os in
+    mingw* | cegcc*) lt_sed_strip_eq="s,=\([[A-Za-z]]:\),\1,g" ;;
+    *) lt_sed_strip_eq="s,=/,/,g" ;;
+  esac
+  lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq`
+  case $lt_search_path_spec in
+  *\;*)
+    # 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 's/;/ /g'`
+    ;;
+  *)
+    lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"`
+    ;;
+  esac
+  # 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; }
+}'`
+  # AWK program above erroneously prepends '/' to C:/dos/paths
+  # for these hosts.
+  case $host_os in
+    mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\
+      $SED 's,/\([[A-Za-z]]:\),\1,g'` ;;
+  esac
+  sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP`
+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 # correct to gnu/linux during the next big refactor
+  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 # correct to gnu/linux during the next big refactor
+  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=`func_echo_all "$lib" | $SED '\''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 # correct to gnu/linux during the next big refactor
+  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,$cc_basename in
+  yes,*)
+    # gcc
+    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}'
+m4_if([$1], [],[
+      sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"])
+      ;;
+    mingw* | cegcc*)
+      # MinGW DLLs use traditional 'lib' prefix
+      soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+      ;;
+    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
+    dynamic_linker='Win32 ld.exe'
+    ;;
+
+  *,cl*)
+    # Native MSVC
+    libname_spec='$name'
+    soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+    library_names_spec='${libname}.dll.lib'
+
+    case $build_os in
+    mingw*)
+      sys_lib_search_path_spec=
+      lt_save_ifs=$IFS
+      IFS=';'
+      for lt_path in $LIB
+      do
+        IFS=$lt_save_ifs
+        # Let DOS variable expansion print the short 8.3 style file name.
+        lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"`
+        sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path"
+      done
+      IFS=$lt_save_ifs
+      # Convert to MSYS style.
+      sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'`
+      ;;
+    cygwin*)
+      # Convert to unix form, then to dos form, then back to unix form
+      # but this time dos style (no spaces!) so that the unix form looks
+      # like /cygdrive/c/PROGRA~1:/cygdr...
+      sys_lib_search_path_spec=`cygpath --path --unix "$LIB"`
+      sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null`
+      sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+      ;;
+    *)
+      sys_lib_search_path_spec="$LIB"
+      if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then
+        # It is most probably a Windows format PATH.
+        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
+      # FIXME: find the short name or the path components, as spaces are
+      # common. (e.g. "Program Files" -> "PROGRA~1")
+      ;;
+    esac
+
+    # 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'
+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+      dlpath=$dir/\$dldll~
+       $RM \$dlpath'
+    shlibpath_overrides_runpath=yes
+    dynamic_linker='Win32 link.exe'
+    ;;
+
+  *)
+    # Assume MSVC wrapper
+    library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib'
+    dynamic_linker='Win32 ld.exe'
+    ;;
+  esac
+  # 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 # correct to gnu/linux during the next big refactor
+  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
+  ;;
+
+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[[23]].*) objformat=aout ;;
+    *) objformat=elf ;;
+    esac
+  fi
+  # Handle Gentoo/FreeBSD as it was Linux
+  case $host_vendor in
+    gentoo)
+      version_type=linux ;;
+    *)
+      version_type=freebsd-$objformat ;;
+  esac
+
+  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
+      ;;
+    linux)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+      soname_spec='${libname}${release}${shared_ext}$major'
+      need_lib_prefix=no
+      need_version=no
+      ;;
+  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 # correct to gnu/linux during the next big refactor
+  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
+  ;;
+
+haiku*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  dynamic_linker="$host_os runtime_loader"
+  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=LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
+  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'
+  # or fails outright, so override atomically:
+  install_override_mode=555
+  ;;
+
+interix[[3-9]]*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  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 # correct to gnu/linux during the next big refactor
+	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 glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  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
+  AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath],
+    [lt_cv_shlibpath_overrides_runpath=no
+    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],
+	 [lt_cv_shlibpath_overrides_runpath=yes])])
+    LDFLAGS=$save_LDFLAGS
+    libdir=$save_libdir
+    ])
+  shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath
+
+  # 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;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'
+  ;;
+
+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 # correct to gnu/linux during the next big refactor
+  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 # correct to gnu/linux during the next big refactor
+  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 # correct to gnu/linux during the next big refactor
+  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 # correct to gnu/linux during the next big refactor
+    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 # correct to gnu/linux during the next big refactor
+  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 # correct to gnu/linux during the next big refactor
+  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([], [install_override_mode], [1],
+    [Permission mode override for installation of shared libraries])
+_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
+m4_require([_LT_PROG_ECHO_BACKSLASH])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
+  cygwin* | mingw* | pw32* | cegcc*)
+    if test "$GCC" != yes; then
+      reload_cmds=false
+    fi
+    ;;
+  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_TAGDECL([], [reload_flag], [1], [How to create reloadable object files])dnl
+_LT_TAGDECL([], [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.
+  # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin.
+  if ( test "$lt_cv_nm_interface" = "BSD nm" && 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
+    # Keep this pattern in sync with the one in func_win32_libid.
+    lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)'
+    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
+  ;;
+
+haiku*)
+  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])(-bit)?( [LM]SB)? 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 glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+netbsd*)
+  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_glob=
+want_nocaseglob=no
+if test "$build" = "$host"; then
+  case $host_os in
+  mingw* | pw32*)
+    if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then
+      want_nocaseglob=yes
+    else
+      file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"`
+    fi
+    ;;
+  esac
+fi
+
+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_DECL([], [file_magic_glob], [1],
+    [How to find potential files when deplibs_check_method = "file_magic"])
+_LT_DECL([], [want_nocaseglob], [1],
+    [Find potential files using nocaseglob 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.
+  if test -n "$DUMPBIN"; then :
+    # Let the user override the test.
+  else
+    AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :)
+    case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in
+    *COFF*)
+      DUMPBIN="$DUMPBIN -symbols"
+      ;;
+    *)
+      DUMPBIN=:
+      ;;
+    esac
+  fi
+  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:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD)
+  (eval "$ac_compile" 2>conftest.err)
+  cat conftest.err >&AS_MESSAGE_LOG_FD
+  (eval echo "\"\$as_me:$LINENO: $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:$LINENO: 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_CHECK_SHAREDLIB_FROM_LINKLIB
+# --------------------------------
+# how to determine the name of the shared library
+# associated with a specific link library.
+#  -- PORTME fill in with the dynamic library characteristics
+m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB],
+[m4_require([_LT_DECL_EGREP])
+m4_require([_LT_DECL_OBJDUMP])
+m4_require([_LT_DECL_DLLTOOL])
+AC_CACHE_CHECK([how to associate runtime and link libraries],
+lt_cv_sharedlib_from_linklib_cmd,
+[lt_cv_sharedlib_from_linklib_cmd='unknown'
+
+case $host_os in
+cygwin* | mingw* | pw32* | cegcc*)
+  # two different shell functions defined in ltmain.sh
+  # decide which to use based on capabilities of $DLLTOOL
+  case `$DLLTOOL --help 2>&1` in
+  *--identify-strict*)
+    lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib
+    ;;
+  *)
+    lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback
+    ;;
+  esac
+  ;;
+*)
+  # fallback: assume linklib IS sharedlib
+  lt_cv_sharedlib_from_linklib_cmd="$ECHO"
+  ;;
+esac
+])
+sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd
+test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO
+
+_LT_DECL([], [sharedlib_from_linklib_cmd], [1],
+    [Command to associate shared and link libraries])
+])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB
+
+
+# _LT_PATH_MANIFEST_TOOL
+# ----------------------
+# locate the manifest tool
+m4_defun([_LT_PATH_MANIFEST_TOOL],
+[AC_CHECK_TOOL(MANIFEST_TOOL, mt, :)
+test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt
+AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool],
+  [lt_cv_path_mainfest_tool=no
+  echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD
+  $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out
+  cat conftest.err >&AS_MESSAGE_LOG_FD
+  if $GREP 'Manifest Tool' conftest.out > /dev/null; then
+    lt_cv_path_mainfest_tool=yes
+  fi
+  rm -f conftest*])
+if test "x$lt_cv_path_mainfest_tool" != xyes; then
+  MANIFEST_TOOL=:
+fi
+_LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl
+])# _LT_PATH_MANIFEST_TOOL
+
+
+# LT_LIB_M
+# --------
+# check for math library
+AC_DEFUN([LT_LIB_M],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+LIBM=
+case $host in
+*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-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
+  case $cc_basename in
+  nvcc*)
+    _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;;
+  *)
+    _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;;
+  esac
+
+  _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([AC_PROG_AWK])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};"\
+"     /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\
+"     /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
+  lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'"
+
+  # 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
+/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests.  */
+#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE)
+/* DATA imports from DLLs on WIN32 con't be const, because runtime
+   relocations are performed -- see ld's documentation on pseudo-relocs.  */
+# define LT@&t at _DLSYM_CONST
+#elif defined(__osf__)
+/* This system does not cope well with relocations in const data.  */
+# define LT@&t at _DLSYM_CONST
+#else
+# define LT@&t at _DLSYM_CONST const
+#endif
+
+#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.  */
+LT@&t at _DLSYM_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_globsym_save_LIBS=$LIBS
+	  lt_globsym_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_globsym_save_LIBS
+	  CFLAGS=$lt_globsym_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
+
+# Response file support.
+if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+  nm_file_list_spec='@'
+elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then
+  nm_file_list_spec='@'
+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_DECL([], [nm_file_list_spec], [1],
+    [Specify filename containing input files for $NM])
+]) # _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)=
+
+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)=
+      ;;
+    haiku*)
+      # PIC is the default for Haiku.
+      # The "-static" flag exists, but is broken.
+      _LT_TAGVAR(lt_prog_compiler_static, $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
+	;;
+      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).
+	m4_if([$1], [GCJ], [],
+	  [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+	;;
+      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 | kopensolaris*-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* | bgxl[[cC]]* | mpixl[[cC]]*)
+	    # IBM XL 8.0, 9.0 on PPC and BlueGene
+	    _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*)
+	;;
+      *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* | sunCC*)
+	    # 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'
+      ;;
+
+    haiku*)
+      # PIC is the default for Haiku.
+      # The "-static" flag exists, but is broken.
+      _LT_TAGVAR(lt_prog_compiler_static, $1)=
+      ;;
+
+    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
+
+    case $cc_basename in
+    nvcc*) # Cuda Compiler Driver 2.2
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker '
+      if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then
+        _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)"
+      fi
+      ;;
+    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 | kopensolaris*-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'
+	;;
+      nagfor*)
+	# NAG Fortran compiler
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,'
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	;;
+      pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
+        # 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* | bgxl* | bgf* | mpixl*)
+	# IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene
+	_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\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*)
+	  # 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)=''
+	  ;;
+	*Sun\ F* | *Sun*Fortran*)
+	  _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 '
+	  ;;
+	*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,'
+	  ;;
+        *Intel*\ [[CF]]*Compiler*)
+	  _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	  _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+	  _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+	  ;;
+	*Portland\ Group*)
+	  _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	  _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
+	  _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	  ;;
+	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* | sunf77* | sunf90* | sunf95*)
+	_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_CACHE_CHECK([for $compiler option to produce PIC],
+  [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)],
+  [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)])
+_LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)
+
+#
+# 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])
+
+_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1],
+	[How to pass a linker flag through the compiler])
+#
+# 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_PATH_MANIFEST_TOOL])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'
+  _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']
+  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
+    # Also, AIX nm treats weak defined symbols like other global defined
+    # symbols, whereas GNU nm marks them as "W".
+    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") || (\$ 2 == "W")) && ([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*)
+    case $cc_basename in
+    cl*)
+      _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
+      ;;
+    *)
+      _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols'
+      _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname']
+      ;;
+    esac
+    ;;
+  *)
+    _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+    ;;
+  esac
+], [
+  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_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
+    ;;
+  esac
+
+  _LT_TAGVAR(ld_shlibs, $1)=yes
+
+  # On some targets, GNU ld is compatible enough with the native linker
+  # that we're better off using the native interface for both.
+  lt_use_gnu_ld_interface=no
+  if test "$with_gnu_ld" = yes; then
+    case $host_os in
+      aix*)
+	# The AIX port of GNU ld has always aspired to compatibility
+	# with the native linker.  However, as the warning in the GNU ld
+	# block says, versions before 2.19.5* couldn't really create working
+	# shared libraries, regardless of the interface used.
+	case `$LD -v 2>&1` in
+	  *\ \(GNU\ Binutils\)\ 2.19.5*) ;;
+	  *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;;
+	  *\ \(GNU\ Binutils\)\ [[3-9]]*) ;;
+	  *)
+	    lt_use_gnu_ld_interface=yes
+	    ;;
+	esac
+	;;
+      *)
+	lt_use_gnu_ld_interface=yes
+	;;
+    esac
+  fi
+
+  if test "$lt_use_gnu_ld_interface" = 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
+      *GNU\ gold*) supports_anon_versioning=yes ;;
+      *\ [[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.19, 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 install binutils
+*** 2.20 or above, or modify your PATH so that a non-GNU linker is found.
+*** You will then need to restart the configuration process.
+
+_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(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols'
+      _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/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols'
+      _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname']
+
+      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
+      ;;
+
+    haiku*)
+      _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+      _LT_TAGVAR(link_all_deplibs, $1)=yes
+      ;;
+
+    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 | kopensolaris*-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=' $pic_flag'
+	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; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+	  tmp_addflag=' $pic_flag'
+	  ;;
+	pgf77* | pgf90* | pgf95* | pgfortran*)
+					# 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; func_echo_all \"$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]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below)
+	  tmp_sharedflag='-qmkshrobj'
+	  tmp_addflag= ;;
+	nvcc*)	# Cuda Compiler Driver 2.2
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+	  _LT_TAGVAR(compiler_needs_object, $1)=yes
+	  ;;
+	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; func_echo_all \"$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* | bgf* | bgxlf* | mpixlf*)
+	  # 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)='${wl}-rpath ${wl}$libdir'
+	  _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_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 $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+	  fi
+	  ;;
+	esac
+      else
+        _LT_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+
+    netbsd*)
+      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 $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $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 $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $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 $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $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
+	# Also, AIX nm treats weak defined symbols like other global
+	# defined symbols, whereas GNU nm marks them as "W".
+	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") || (\$ 2 == "W")) && ([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
+      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([$1])
+        _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 func_echo_all "${wl}${allow_undefined_flag}"; 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([$1])
+	 _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'
+	  if test "$with_gnu_ld" = yes; then
+	    # We only use this code for GNU lds that support --whole-archive.
+	    _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+	  else
+	    # Exported symbols can be pulled into shared objects from archives
+	    _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
+	  fi
+	  _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.
+      case $cc_basename in
+      cl*)
+	# Native MSVC
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
+	_LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+	_LT_TAGVAR(always_export_symbols, $1)=yes
+	_LT_TAGVAR(file_list_spec, $1)='@'
+	# 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 $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
+	_LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	    sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
+	  else
+	    sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
+	  fi~
+	  $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+	  linknames='
+	# The linker will not automatically build a static lib if we build a DLL.
+	# _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
+	_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+	_LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
+	_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'
+	# Don't use ranlib
+	_LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib'
+	_LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~
+	  lt_tool_outputfile="@TOOL_OUTPUT@"~
+	  case $lt_outputfile in
+	    *.exe|*.EXE) ;;
+	    *)
+	      lt_outputfile="$lt_outputfile.exe"
+	      lt_tool_outputfile="$lt_tool_outputfile.exe"
+	      ;;
+	  esac~
+	  if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
+	    $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+	    $RM "$lt_outputfile.manifest";
+	  fi'
+	;;
+      *)
+	# Assume MSVC wrapper
+	_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 `func_echo_all "$deplibs" | $SED '\''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(enable_shared_with_static_runtimes, $1)=yes
+	;;
+      esac
+      ;;
+
+    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
+      ;;
+
+    # 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 $pic_flag -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 $pic_flag ${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 && test "$with_gnu_ld" = no; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${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_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 && test "$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 $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	*)
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${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'
+	  ;;
+	*)
+	m4_if($1, [], [
+	  # Older versions of the 11.00 compiler do not understand -b yet
+	  # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does)
+	  _LT_LINKER_OPTION([if $CC understands -b],
+	    _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b],
+	    [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'],
+	    [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_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 $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${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.
+	# This should be the same for all languages, so no per-tag cache variable.
+	AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol],
+	  [lt_cv_irix_exported_symbol],
+	  [save_LDFLAGS="$LDFLAGS"
+	   LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null"
+	   AC_LINK_IFELSE(
+	     [AC_LANG_SOURCE(
+	        [AC_LANG_CASE([C], [[int foo (void) { return 0; }]],
+			      [C++], [[int foo (void) { return 0; }]],
+			      [Fortran 77], [[
+      subroutine foo
+      end]],
+			      [Fortran], [[
+      subroutine foo
+      end]])])],
+	      [lt_cv_irix_exported_symbol=yes],
+	      [lt_cv_irix_exported_symbol=no])
+           LDFLAGS="$save_LDFLAGS"])
+	if test "$lt_cv_irix_exported_symbol" = yes; then
+          _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
+	fi
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -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" && func_echo_all "-set_version $verstring"` -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*)
+      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" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${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" && func_echo_all "-set_version $verstring"` -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} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${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" && func_echo_all "-set_version $verstring"` -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 "-set_version $verstring"` -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 $pic_flag ${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 $pic_flag ${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_CACHE_CHECK([whether -lc should be explicitly linked in],
+	[lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1),
+	[$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_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+	  else
+	    lt_cv_[]_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*
+	])
+      _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_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_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([], [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([], [postlink_cmds], [2],
+    [Commands necessary for finishing linking programs])
+_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
+
+## 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...
+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_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],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_PATH_MANIFEST_TOOL])dnl
+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
+
+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_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(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_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_CFLAGS=$CFLAGS
+  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++"}
+  CFLAGS=$CXXFLAGS
+  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 $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+        _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -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 -v "^Configured with:" | $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([$1])
+          _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 func_echo_all "${wl}${allow_undefined_flag}"; 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([$1])
+	    _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'
+	    if test "$with_gnu_ld" = yes; then
+	      # We only use this code for GNU lds that support --whole-archive.
+	      _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+	    else
+	      # Exported symbols can be pulled into shared objects from archives
+	      _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
+	    fi
+	    _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*)
+	case $GXX,$cc_basename in
+	,cl* | no,cl*)
+	  # Native MSVC
+	  # 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
+	  _LT_TAGVAR(always_export_symbols, $1)=yes
+	  _LT_TAGVAR(file_list_spec, $1)='@'
+	  # 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 $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
+	  _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	      $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
+	    else
+	      $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
+	    fi~
+	    $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+	    linknames='
+	  # The linker will not automatically build a static lib if we build a DLL.
+	  # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
+	  _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+	  # Don't use ranlib
+	  _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib'
+	  _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~
+	    lt_tool_outputfile="@TOOL_OUTPUT@"~
+	    case $lt_outputfile in
+	      *.exe|*.EXE) ;;
+	      *)
+		lt_outputfile="$lt_outputfile.exe"
+		lt_tool_outputfile="$lt_tool_outputfile.exe"
+		;;
+	    esac~
+	    func_to_tool_file "$lt_outputfile"~
+	    if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
+	      $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+	      $RM "$lt_outputfile.manifest";
+	    fi'
+	  ;;
+	*)
+	  # g++
+	  # _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(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols'
+	  _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
+	  ;;
+	esac
+	;;
+      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
+        ;;
+
+      freebsd2.*)
+        # 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*)
+        ;;
+
+      haiku*)
+        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+        _LT_TAGVAR(link_all_deplibs, $1)=yes
+        ;;
+
+      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; func_echo_all "$list"'
+            ;;
+          *)
+            if test "$GXX" = yes; then
+              _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${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; func_echo_all "$list"'
+	    ;;
+          *)
+	    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 $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	            ;;
+	          *)
+	            _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${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" && func_echo_all "-set_version $verstring"` -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 $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+	      else
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -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 | kopensolaris*-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; func_echo_all "$list"'
+
+	    _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 | sort | $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 | sort | $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 | sort | $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 | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
+	      ;;
+	    *) # Version 6 and above 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; func_echo_all \"$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=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed'
+	    ;;
+	  xl* | mpixl* | bgxl*)
+	    # 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; func_echo_all \"$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='func_echo_all'
+
+	      # 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=func_echo_all
+	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" && func_echo_all "${wl}-set_version $verstring"` -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" && func_echo_all "-set_version $verstring"` -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 "-set_version $verstring"` -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=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+	    ;;
+	  *)
+	    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" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+		  ;;
+	        *)
+	          _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${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 -v "^Configured with:" | $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* | sunCC*)
+	    # 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='func_echo_all'
+
+	    # 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 $pic_flag -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 $pic_flag -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 -v "^Configured with:" | $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 -v "^Configured with:" | $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(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~
+	      '"$_LT_TAGVAR(old_archive_cmds, $1)"
+	    _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~
+	      '"$_LT_TAGVAR(reload_cmds, $1)"
+	    ;;
+	  *)
+	    _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
+  CFLAGS=$lt_save_CFLAGS
+  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_FUNC_STRIPNAME_CNF
+# ----------------------
+# func_stripname_cnf 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).
+#
+# This function is identical to the (non-XSI) version of func_stripname,
+# except this one can be used by m4 code that may be executed by configure,
+# rather than the libtool script.
+m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl
+AC_REQUIRE([_LT_DECL_SED])
+AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])
+func_stripname_cnf ()
+{
+  case ${2} in
+  .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;;
+  *)  func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;;
+  esac
+} # func_stripname_cnf
+])# _LT_FUNC_STRIPNAME_CNF
+
+# _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
+AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])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
+], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF
+package foo
+func foo() {
+}
+_LT_EOF
+])
+
+_lt_libdeps_save_CFLAGS=$CFLAGS
+case "$CC $CFLAGS " in #(
+*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;;
+*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;;
+*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;;
+esac
+
+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 ${prev}${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
+       fi
+
+       # Expand the sysroot to ease extracting the directories later.
+       if test -z "$prev"; then
+         case $p in
+         -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;;
+         -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;;
+         -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;;
+         esac
+       fi
+       case $p in
+       =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;;
+       esac
+       if test "$pre_test_object_deps_done" = no; then
+	 case ${prev} 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
+       prev=
+       ;;
+
+    *.lto.$objext) ;; # Ignore GCC LTO objects
+    *.$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
+CFLAGS=$_lt_libdeps_save_CFLAGS
+
+# 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* | sunCC*)
+    # 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_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_LANG_PUSH(Fortran 77)
+if test -z "$F77" || test "X$F77" = "Xno"; then
+  _lt_disable_F77=yes
+fi
+
+_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_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(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_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
+  lt_save_CFLAGS=$CFLAGS
+  CC=${F77-"f77"}
+  CFLAGS=$FFLAGS
+  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"
+  CFLAGS="$lt_save_CFLAGS"
+fi # test "$_lt_disable_F77" != yes
+
+AC_LANG_POP
+])# _LT_LANG_F77_CONFIG
+
+
+# _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_LANG_PUSH(Fortran)
+
+if test -z "$FC" || test "X$FC" = "Xno"; then
+  _lt_disable_FC=yes
+fi
+
+_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_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(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_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
+  lt_save_CFLAGS=$CFLAGS
+  CC=${FC-"f95"}
+  CFLAGS=$FCFLAGS
+  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
+  CFLAGS=$lt_save_CFLAGS
+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_CFLAGS=$CFLAGS
+lt_save_GCC=$GCC
+GCC=yes
+CC=${GCJ-"gcj"}
+CFLAGS=$GCJFLAGS
+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
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+
+## 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...
+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
+CFLAGS=$lt_save_CFLAGS
+])# _LT_LANG_GCJ_CONFIG
+
+
+# _LT_LANG_GO_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for the GNU Go compiler
+# are suitably defined.  These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_GO_CONFIG],
+[AC_REQUIRE([LT_PROG_GO])dnl
+AC_LANG_SAVE
+
+# Source file extension for Go test sources.
+ac_ext=go
+
+# Object file extension for compiled Go test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="package main; func main() { }"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='package main; func main() { }'
+
+# 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_CFLAGS=$CFLAGS
+lt_save_GCC=$GCC
+GCC=yes
+CC=${GOC-"gccgo"}
+CFLAGS=$GOFLAGS
+compiler=$CC
+_LT_TAGVAR(compiler, $1)=$CC
+_LT_TAGVAR(LD, $1)="$LD"
+_LT_CC_BASENAME([$compiler])
+
+# Go 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
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+
+## 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...
+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
+CFLAGS=$lt_save_CFLAGS
+])# _LT_LANG_GO_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_CFLAGS=$CFLAGS
+lt_save_GCC=$GCC
+GCC=
+CC=${RC-"windres"}
+CFLAGS=
+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
+CFLAGS=$lt_save_CFLAGS
+])# _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_GO
+# ----------
+AC_DEFUN([LT_PROG_GO],
+[AC_CHECK_TOOL(GOC, gccgo,)
+])
+
+
+# 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_DLLTOOL
+# ----------------
+# Ensure DLLTOOL variable is set.
+m4_defun([_LT_DECL_DLLTOOL],
+[AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+_LT_DECL([], [DLLTOOL], [1], [DLL creation program])
+AC_SUBST([DLLTOOL])
+])
+
+# _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%"$_lt_dummy"}, \
+      = c,a/b,b/c, \
+    && 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_FUNCTION_REPLACE (FUNCNAME, REPLACEMENT-BODY)
+# ------------------------------------------------------
+# In `$cfgfile', look for function FUNCNAME delimited by `^FUNCNAME ()$' and
+# '^} FUNCNAME ', and replace its body with REPLACEMENT-BODY.
+m4_defun([_LT_PROG_FUNCTION_REPLACE],
+[dnl {
+sed -e '/^$1 ()$/,/^} # $1 /c\
+$1 ()\
+{\
+m4_bpatsubsts([$2], [$], [\\], [^\([	 ]\)], [\\\1])
+} # Extended-shell $1 implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+])
+
+
+# _LT_PROG_REPLACE_SHELLFNS
+# -------------------------
+# Replace existing portable implementations of several shell functions with
+# equivalent extended shell implementations where those features are available..
+m4_defun([_LT_PROG_REPLACE_SHELLFNS],
+[if test x"$xsi_shell" = xyes; then
+  _LT_PROG_FUNCTION_REPLACE([func_dirname], [dnl
+    case ${1} in
+      */*) func_dirname_result="${1%/*}${2}" ;;
+      *  ) func_dirname_result="${3}" ;;
+    esac])
+
+  _LT_PROG_FUNCTION_REPLACE([func_basename], [dnl
+    func_basename_result="${1##*/}"])
+
+  _LT_PROG_FUNCTION_REPLACE([func_dirname_and_basename], [dnl
+    case ${1} in
+      */*) func_dirname_result="${1%/*}${2}" ;;
+      *  ) func_dirname_result="${3}" ;;
+    esac
+    func_basename_result="${1##*/}"])
+
+  _LT_PROG_FUNCTION_REPLACE([func_stripname], [dnl
+    # 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}"}])
+
+  _LT_PROG_FUNCTION_REPLACE([func_split_long_opt], [dnl
+    func_split_long_opt_name=${1%%=*}
+    func_split_long_opt_arg=${1#*=}])
+
+  _LT_PROG_FUNCTION_REPLACE([func_split_short_opt], [dnl
+    func_split_short_opt_arg=${1#??}
+    func_split_short_opt_name=${1%"$func_split_short_opt_arg"}])
+
+  _LT_PROG_FUNCTION_REPLACE([func_lo2o], [dnl
+    case ${1} in
+      *.lo) func_lo2o_result=${1%.lo}.${objext} ;;
+      *)    func_lo2o_result=${1} ;;
+    esac])
+
+  _LT_PROG_FUNCTION_REPLACE([func_xform], [    func_xform_result=${1%.*}.lo])
+
+  _LT_PROG_FUNCTION_REPLACE([func_arith], [    func_arith_result=$(( $[*] ))])
+
+  _LT_PROG_FUNCTION_REPLACE([func_len], [    func_len_result=${#1}])
+fi
+
+if test x"$lt_shell_append" = xyes; then
+  _LT_PROG_FUNCTION_REPLACE([func_append], [    eval "${1}+=\\${2}"])
+
+  _LT_PROG_FUNCTION_REPLACE([func_append_quoted], [dnl
+    func_quote_for_eval "${2}"
+dnl m4 expansion turns \\\\ into \\, and then the shell eval turns that into \
+    eval "${1}+=\\\\ \\$func_quote_for_eval_result"])
+
+  # Save a `func_append' function call where possible by direct use of '+='
+  sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \
+    && mv -f "$cfgfile.tmp" "$cfgfile" \
+      || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+  test 0 -eq $? || _lt_function_replace_fail=:
+else
+  # Save a `func_append' function call even when '+=' is not available
+  sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \
+    && mv -f "$cfgfile.tmp" "$cfgfile" \
+      || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+  test 0 -eq $? || _lt_function_replace_fail=:
+fi
+
+if test x"$_lt_function_replace_fail" = x":"; then
+  AC_MSG_WARN([Unable to substitute extended shell functions in $ofile])
+fi
+])
+
+# _LT_PATH_CONVERSION_FUNCTIONS
+# -----------------------------
+# Determine which file name conversion functions should be used by
+# func_to_host_file (and, implicitly, by func_to_host_path).  These are needed
+# for certain cross-compile configurations and native mingw.
+m4_defun([_LT_PATH_CONVERSION_FUNCTIONS],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+AC_MSG_CHECKING([how to convert $build file names to $host format])
+AC_CACHE_VAL(lt_cv_to_host_file_cmd,
+[case $host in
+  *-*-mingw* )
+    case $build in
+      *-*-mingw* ) # actually msys
+        lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32
+        ;;
+      *-*-cygwin* )
+        lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32
+        ;;
+      * ) # otherwise, assume *nix
+        lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32
+        ;;
+    esac
+    ;;
+  *-*-cygwin* )
+    case $build in
+      *-*-mingw* ) # actually msys
+        lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin
+        ;;
+      *-*-cygwin* )
+        lt_cv_to_host_file_cmd=func_convert_file_noop
+        ;;
+      * ) # otherwise, assume *nix
+        lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin
+        ;;
+    esac
+    ;;
+  * ) # unhandled hosts (and "normal" native builds)
+    lt_cv_to_host_file_cmd=func_convert_file_noop
+    ;;
+esac
+])
+to_host_file_cmd=$lt_cv_to_host_file_cmd
+AC_MSG_RESULT([$lt_cv_to_host_file_cmd])
+_LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd],
+         [0], [convert $build file names to $host format])dnl
+
+AC_MSG_CHECKING([how to convert $build file names to toolchain format])
+AC_CACHE_VAL(lt_cv_to_tool_file_cmd,
+[#assume ordinary cross tools, or native build.
+lt_cv_to_tool_file_cmd=func_convert_file_noop
+case $host in
+  *-*-mingw* )
+    case $build in
+      *-*-mingw* ) # actually msys
+        lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32
+        ;;
+    esac
+    ;;
+esac
+])
+to_tool_file_cmd=$lt_cv_to_tool_file_cmd
+AC_MSG_RESULT([$lt_cv_to_tool_file_cmd])
+_LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd],
+         [0], [convert $build files to toolchain format])dnl
+])# _LT_PATH_CONVERSION_FUNCTIONS
diff --git a/m4/ltoptions.m4 b/m4/ltoptions.m4
new file mode 100644
index 0000000..5d9acd8
--- /dev/null
+++ b/m4/ltoptions.m4
@@ -0,0 +1,384 @@
+# Helper functions for option handling.                    -*- Autoconf -*-
+#
+#   Copyright (C) 2004, 2005, 2007, 2008, 2009 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 7 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
+
+
+## --------------------------------- ##
+## Macros to handle LT_INIT 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],      [1], [Assembler program])dnl
+
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+_LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl
+
+test -z "$OBJDUMP" && OBJDUMP=objdump
+_LT_DECL([], [OBJDUMP], [1], [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@<:@=PKGS@:>@],
+	[try to use only PIC/non-PIC objects @<:@default=use both@:>@])],
+    [lt_p=${PACKAGE-default}
+    case $withval in
+    yes|no) pic_mode=$withval ;;
+    *)
+      pic_mode=default
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for lt_pkg in $withval; do
+	IFS="$lt_save_ifs"
+	if test "X$lt_pkg" = "X$lt_p"; then
+	  pic_mode=yes
+	fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac],
+    [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], [])
+
+## ----------------- ##
+## LTDL_INIT Options ##
+## ----------------- ##
+
+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])])
diff --git a/m4/ltsugar.m4 b/m4/ltsugar.m4
new file mode 100644
index 0000000..9000a05
--- /dev/null
+++ b/m4/ltsugar.m4
@@ -0,0 +1,123 @@
+# 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
+])
diff --git a/m4/ltversion.m4 b/m4/ltversion.m4
new file mode 100644
index 0000000..07a8602
--- /dev/null
+++ b/m4/ltversion.m4
@@ -0,0 +1,23 @@
+# 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.
+
+# @configure_input@
+
+# serial 3337 ltversion.m4
+# This file is part of GNU Libtool
+
+m4_define([LT_PACKAGE_VERSION], [2.4.2])
+m4_define([LT_PACKAGE_REVISION], [1.3337])
+
+AC_DEFUN([LTVERSION_VERSION],
+[macro_version='2.4.2'
+macro_revision='1.3337'
+_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?])
+_LT_DECL(, macro_revision, 0)
+])
diff --git a/m4/lt~obsolete.m4 b/m4/lt~obsolete.m4
new file mode 100644
index 0000000..c573da9
--- /dev/null
+++ b/m4/lt~obsolete.m4
@@ -0,0 +1,98 @@
+# lt~obsolete.m4 -- aclocal satisfying obsolete definitions.    -*-Autoconf-*-
+#
+#   Copyright (C) 2004, 2005, 2007, 2009 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 5 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_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])])
+m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS],	[AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])])
+m4_ifndef([_LT_AC_PROG_CXXCPP],		[AC_DEFUN([_LT_AC_PROG_CXXCPP])])
+m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS],	[AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])])
+m4_ifndef([_LT_PROG_ECHO_BACKSLASH],	[AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])])
+m4_ifndef([_LT_PROG_F77],		[AC_DEFUN([_LT_PROG_F77])])
+m4_ifndef([_LT_PROG_FC],		[AC_DEFUN([_LT_PROG_FC])])
+m4_ifndef([_LT_PROG_CXX],		[AC_DEFUN([_LT_PROG_CXX])])
diff --git a/m4/mathic-check.m4 b/m4/mathic-check.m4
new file mode 100644
index 0000000..b0dc818
--- /dev/null
+++ b/m4/mathic-check.m4
@@ -0,0 +1,31 @@
+AC_DEFUN([LB_CHECK_MATHICGB],
+[
+#
+ AC_ARG_WITH(mathicgb,
+   [AS_HELP_STRING(
+     [--with-mathicgb=yes|no],
+     [Use the MathicGB library. Default is no.]
+   )],
+   [],
+   [with_mathicgb="no"]
+ )
+ #
+ # MathicGB
+ dnl Checking these pre-requisites and adding them to libs is necessary
+ dnl for some reason, at least on Cygwin.
+ AS_IF( [test "x$with_mathicgb" = xyes],
+ [
+  AC_LANG_PUSH([C++])
+  AC_CHECK_LIB(memtailor, libmemtailorIsPresent, [],
+    [AC_MSG_ERROR([Cannot find libmemtailor, which is required for MathicGB.])])
+  AC_CHECK_LIB(mathic, libmathicIsPresent, [],
+    [AC_MSG_ERROR([Cannot find libmathic, which is required for MathicGB.])])
+  AC_CHECK_LIB(mathicgb, libmathicgbIsPresent, [],
+    [AC_MSG_ERROR([Cannot find the MathicGB library.])])
+  AC_CHECK_HEADER([mathicgb.h])
+  AC_LANG_POP([C++])
+  AC_DEFINE(HAVE_MATHICGB,1,[Define if mathicgb is to be used])
+#  AC_SUBST(HAVE_MATHICGB_VALUE, 1)
+ ])
+ #
+])
diff --git a/m4/ntl-check.m4 b/m4/ntl-check.m4
new file mode 100644
index 0000000..c8f9bab
--- /dev/null
+++ b/m4/ntl-check.m4
@@ -0,0 +1,132 @@
+# Check for NTL
+# Bradford Hovinen, 2001-06-13
+# Modified by Pascal Giorgi, 2003-12-03
+# Inspired by gnome-bonobo-check.m4 by Miguel de Icaza, 99-04-12
+# Stolen from Chris Lahey       99-2-5
+# stolen from Manish Singh again
+# stolen back from Frank Belew
+# stolen from Manish Singh
+# Shamelessly stolen from Owen Taylor
+
+dnl LB_CHECK_NTL ([MINIMUM-VERSION [, ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
+dnl
+dnl Test for Victor Shoup's NTL (Number Theory Library) and define
+dnl NTL_CFLAGS and NTL_LIBS
+
+AC_DEFUN([LB_CHECK_NTL],
+[
+DEFAULT_CHECKING_PATH="/usr /usr/local /sw /opt/local"
+
+AC_ARG_WITH(ntl,
+[  --with-ntl=<path>|yes|no  Use NTL library. If argument is no, you do not have
+                            the library installed on your machine (set as
+			    default). If argument is yes or <empty> that means
+			    the library is reachable with the standard search
+			    path (/usr or /usr/local). Otherwise you give the
+			    <path> to the directory which contain the library.
+	     ],
+	     [if test "$withval" = yes ; then
+			NTL_HOME_PATH="${DEFAULT_CHECKING_PATH}"
+	      elif test "$withval" != no ; then
+			NTL_HOME_PATH="$withval"
+	     fi],
+	     [NTL_HOME_PATH="${DEFAULT_CHECKING_PATH}"])
+
+min_ntl_version=ifelse([$1], ,1.0,$1)
+
+
+dnl Check for existence
+BACKUP_CXXFLAGS=${CXXFLAGS}
+BACKUP_CFLAGS=${CFLAGS}
+BACKUP_LIBS=${LIBS}
+
+AC_LANG_PUSH(C++)
+
+if test -n "$NTL_HOME_PATH"; then
+AC_MSG_CHECKING(for NTL >= $min_ntl_version)
+fi
+
+for NTL_HOME in ${NTL_HOME_PATH}
+ do
+if test -r "$NTL_HOME/include/NTL/ZZ.h"; then
+
+	if test "x$NTL_HOME" != "x/usr"; then
+		NTL_CFLAGS="-I${NTL_HOME}/include"
+		NTL_LIBS="-L${NTL_HOME}/lib -lntl"
+	else
+		NTL_CFLAGS=
+		NTL_LIBS="-lntl"
+	fi
+###	CFLAGS="${BACKUP_CFLAGS} ${NTL_CFLAGS} ${GMP_CFLAGS}"
+	CXXFLAGS="${BACKUP_CFLAGS} ${BACKUP_CXXFLAGS} ${NTL_CFLAGS} ${GMP_CFLAGS}"
+	LIBS="${BACKUP_LIBS} ${NTL_LIBS} ${GMP_LIBS}"
+
+	AC_TRY_LINK(
+	[#include <NTL/ZZ.h>],
+	[NTL::ZZ a;],
+	[
+	AC_TRY_RUN(
+	[#include <NTL/version.h>
+	#include <NTL/config.h>
+	#ifndef NTL_GMP_LIP
+	int main() {return -1;}
+	#else
+	int main () { if (NTL_MAJOR_VERSION < 5) return -1; else return 0;}
+	#endif
+	],[
+	ntl_found="yes"
+	break
+	],[
+	ntl_problem="$problem $NTL_HOME"
+	unset NTL_CFLAGS
+	unset NTL_LIBS
+	],[
+	ntl_found="yes"
+	ntl_cross="yes"
+	break
+	])
+	],
+	[
+	ntl_found="no"
+	ntl_checked="$checked $NTL_HOME"
+	unset NTL_CFLAGS
+	unset NTL_LIBS
+	])
+else
+	ntl_found="no"
+fi
+done
+
+if test "x$ntl_found" = "xyes" ; then
+	AC_SUBST(NTL_CFLAGS)
+	AC_SUBST(NTL_LIBS)
+	AC_DEFINE(HAVE_NTL,1,[Define if NTL is installed])
+	HAVE_NTL=yes
+	if test "x$ntl_cross" != "xyes"; then
+		AC_MSG_RESULT(found)
+	else
+		AC_MSG_RESULT(unknown)
+		echo "WARNING: You appear to be cross compiling, so there is no way to determine"
+		echo "whether your NTL version is new enough. I am assuming it is."
+	fi
+	ifelse([$2], , :, [$2])
+elif test -n "$ntl_problem"; then
+	AC_MSG_RESULT(problem)
+	echo "Sorry, your NTL version is too old or not configured with NTL_GMP_LIP=on. Disabling."
+	ifelse([$3], , :, [$3])
+elif test   "x$ntl_found" = "xno";  then
+	AC_MSG_RESULT(not found)
+	ifelse([$3], , :, [$3])
+fi
+
+AC_LANG_POP
+
+AM_CONDITIONAL(SING_HAVE_NTL, test "x$HAVE_NTL" = "xyes")
+
+# TODO: The following seems to set CXXFLAGS even if it was not defined previously!!!!
+CXXFLAGS=${BACKUP_CXXFLAGS}
+LIBS=${BACKUP_LIBS}
+#unset LD_LIBRARY_PATH
+
+])
+
diff --git a/m4/options.m4 b/m4/options.m4
new file mode 100644
index 0000000..4ec43e6
--- /dev/null
+++ b/m4/options.m4
@@ -0,0 +1,383 @@
+AC_DEFUN([SING_CHECK_ARITH_RINGS],
+[
+AC_MSG_CHECKING(whether arithmetical rings should be enabled)
+
+AC_ARG_ENABLE(arith-rings, AS_HELP_STRING([--disable-arith-rings], [Disable arithmetical rings]),
+[if test $enableval = yes; then
+     ENABLE_RINGS="yes"
+ else
+     ENABLE_RINGS="no"
+ fi
+],[ENABLE_RINGS="yes"])
+
+if test x$ENABLE_RINGS = xyes; then
+  AC_DEFINE(HAVE_RINGS,1,Enable arithmetical rings)
+fi
+
+AM_CONDITIONAL([ENABLE_RINGS],[test x$ENABLE_RINGS = xyes])
+AC_MSG_RESULT($ENABLE_RINGS)
+])
+
+AC_DEFUN([SING_CHECK_PLURAL],
+[
+AC_MSG_CHECKING(whether non-commutative subsystem should be enabled)
+
+AC_ARG_ENABLE(plural, AS_HELP_STRING([--disable-plural], [Disable non-commutative subsystem]),
+[ENABLE_PLURAL="$enableval"],[ENABLE_PLURAL="yes"])
+
+if test "x$ENABLE_PLURAL" != xno; then
+  AC_DEFINE(HAVE_PLURAL,[1],[Enable non-commutative subsystem])
+  #TODO make a seperate switch
+  AC_DEFINE(HAVE_SHIFTBBA,[1],[Enable letterplace])
+fi
+
+AM_CONDITIONAL([ENABLE_PLURAL],[test x$ENABLE_PLURAL != xno])
+
+AC_MSG_RESULT($ENABLE_PLURAL)
+
+
+AC_ARG_WITH(RatGB, AS_HELP_STRING([--with-ratGB], [do compile with ratGB support (experimental)]))
+
+AC_MSG_CHECKING(whether to have ratGB)
+if test "x$with_ratGB" != xyes && test "x$enable_ratGB" != xyes; then
+  AC_MSG_RESULT(no)
+else
+  AC_DEFINE(HAVE_RATGRING, 1, [Enable RatGB support])
+  AC_MSG_RESULT(yes)
+fi
+
+
+])
+
+
+AC_DEFUN([SING_CHECK_OMALLOC],
+[
+  AC_ARG_ENABLE(omalloc,
+    [AS_HELP_STRING([--enable-omalloc],[build for use with omalloc])],
+    [if test "x$enableval" = "xyes"; then
+      ENABLE_OMALLOC=yes
+    fi],
+      ENABLE_OMALLOC=no)
+
+  AC_ARG_VAR( [OMALLOC_INCLUDES], [INCLUDES for libomalloc] )
+  AC_ARG_VAR( [OMALLOC_LIBS], [LIBS for libomalloc] )
+
+  AC_MSG_CHECKING([whether to use omalloc])
+
+  AH_TEMPLATE([HAVE_OMALLOC], [define if build with OMALLOC])
+
+  if test "x$ENABLE_OMALLOC" = xyes; then
+    AC_MSG_RESULT(yes)
+
+    AC_MSG_CHECKING([  OMALLOC_INCLUDES?..])
+    AC_MSG_RESULT(${OMALLOC_INCLUDES:-unset})
+
+    AC_MSG_CHECKING([  OMALLOC_LIBS?..])
+    AC_MSG_RESULT(${OMALLOC_LIBS:-unset})
+
+    CPPFLAGS_save="$CPPFLAGS"
+    CFLAGS_save="$CFLAGS"
+    LIBS_save="$LIBS"
+
+    AC_LANG_PUSH([C])
+#
+    CPPFLAGS="$CPPFLAGS ${OMALLOC_INCLUDES}"
+    CFLAGS="$CFLAGS ${OMALLOC_INCLUDES}"
+    LIBS="$LIBS ${OMALLOC_LIBS}"
+
+    AC_CHECK_HEADERS([omalloc/omalloc.h],,AC_MSG_WARN([trusting the omalloc locations given: ${OMALLOC_INCLUDES}]))
+
+    CFLAGS="$CFLAGS_save"
+    CPPFLAGS="$CPPFLAGS_save"
+    LIBS="$LIBS_save"
+#
+    AC_LANG_POP([C])
+
+    AC_DEFINE([HAVE_OMALLOC],[1])
+
+    PKG_REQUIRE="$PKG_REQUIRE omalloc"
+    AC_SUBST(PKG_REQUIRE)
+  else
+    AC_MSG_RESULT(no)
+  fi
+
+  AM_CONDITIONAL([ENABLE_OMALLOC],[test "x$ENABLE_OMALLOC" = xyes])
+])
+
+AC_DEFUN([SING_USE_OMALLOC],
+[
+ AC_ARG_ENABLE(omalloc,
+  [AS_HELP_STRING([--disable-omalloc], [do NOT use omalloc within the factory])],
+  [if test "x$enableval"  = "xyes"; then
+    ENABLE_OMALLOC=yes
+   fi],
+    ENABLE_OMALLOC=add)
+
+ ENABLE_OMALLOC_ARG=""
+
+ if test "x$ENABLE_OMALLOC" = xadd; then
+   ENABLE_OMALLOC=yes
+   ENABLE_OMALLOC_ARG="--enable-omalloc $ENABLE_OMALLOC_ARG"
+ fi
+
+ AC_MSG_CHECKING(whether to use omalloc in factory and co.)
+
+ if test "x$ENABLE_OMALLOC" = xyes; then
+  AC_MSG_RESULT(yes)
+  OMALLOC_INCLUDES="-I$ac_abs_top_srcdir"
+
+  if test "x$ac_abs_top_srcdir" != "x$ac_abs_top_builddir"; then
+    OMALLOC_INCLUDES="$OMALLOC_INCLUDES -I$ac_abs_top_builddir"
+  fi
+
+  OMALLOC_LIBS="$ac_abs_top_builddir/omalloc/libomalloc.la"
+
+  AC_SUBST(OMALLOC_INCLUDES)
+  AC_SUBST(OMALLOC_LIBS)
+
+  ENABLE_OMALLOC_ARG="$ENABLE_OMALLOC_ARG OMALLOC_LIBS='$OMALLOC_LIBS' OMALLOC_INCLUDES='$OMALLOC_INCLUDES'"
+  ac_configure_args="$ac_configure_args $ENABLE_OMALLOC_ARG"
+
+  PKG_REQUIRE="$PKG_REQUIRE omalloc"
+  AC_SUBST(PKG_REQUIRE)
+ else
+  AC_MSG_RESULT(no)
+ fi
+
+
+ AM_CONDITIONAL([ENABLE_OMALLOC],[test "x$ENABLE_OMALLOC" = xyes])
+])
+
+AC_DEFUN([SING_USE_RESOURCES],
+[
+ AC_ARG_ENABLE(resources,
+  [AS_HELP_STRING([--disable-resources], [do NOT use libresources within the factory])],
+  [if test "x$enableval"  = "xyes"; then
+    ENABLE_RESOURCES=yes
+   fi],
+    ENABLE_RESOURCES=yes)
+
+ AC_MSG_CHECKING(whether to use libresources in factory and co.)
+ if test "x$ENABLE_RESOURCES" = xyes; then
+  AC_MSG_RESULT(yes)
+  RESOURCES_INCLUDES="-I$ac_abs_top_srcdir "
+
+  RESOURCES_LIBS="$ac_abs_top_builddir/resources/libresources.la"
+
+  AC_SUBST(RESOURCES_INCLUDES)
+  AC_SUBST(RESOURCES_LIBS)
+
+  ENABLE_ARG="--with-Singular RESOURCES_LIBS='$RESOURCES_LIBS' RESOURCES_INCLUDES='$RESOURCES_INCLUDES'"
+
+  ac_configure_args="$ac_configure_args $ENABLE_ARG"
+
+  PKG_REQUIRE="$PKG_REQUIRE resources"
+  AC_SUBST(PKG_REQUIRE)
+ else
+  AC_MSG_RESULT(no)
+ fi
+
+ AM_CONDITIONAL([ENABLE_RESOURCES],[test "x$ENABLE_RESOURCES" = xyes])
+])
+
+
+AC_DEFUN([SING_USE_FACTORY],
+[
+ AC_MSG_CHECKING(whether factory should be enabled)
+
+ AC_ARG_ENABLE(factory, AS_HELP_STRING([--disable-factory], [Disable factory]),
+ [if test $enableval = yes; then
+     ENABLE_FACTORY="yes"
+  else
+     ENABLE_FACTORY="no"
+  fi],[ENABLE_FACTORY="yes"])
+
+ if test x$ENABLE_FACTORY = xyes; then
+
+  FACTORY_INCLUDES="-I$ac_abs_top_srcdir -I$ac_abs_top_srcdir/factory/include"
+  if test "x$ac_abs_top_srcdir" != "x$ac_abs_top_builddir"; then
+    FACTORY_INCLUDES="$FACTORY_INCLUDES -I$ac_abs_top_builddir -I$ac_abs_top_builddir/factory/include"
+  fi
+
+  FACTORY_LIBS="$ac_abs_top_builddir/factory/libfactory.la"
+
+  AC_SUBST(FACTORY_INCLUDES)
+  AC_SUBST(FACTORY_LIBS)
+
+  AC_MSG_CHECKING([  FACTORY_INCLUDES?..])
+  AC_MSG_RESULT(${FACTORY_INCLUDES:-unset})
+
+  AC_MSG_CHECKING([  FACTORY_LIBS?..])
+  AC_MSG_RESULT(${FACTORY_LIBS:-unset})
+
+  AC_DEFINE(HAVE_FACTORY,[1],[Enable factory])
+
+  ENABLE_ARG="FACTORY_LIBS='$FACTORY_LIBS' FACTORY_INCLUDES='$FACTORY_INCLUDES'"
+
+  ac_configure_args="$ac_configure_args $ENABLE_ARG"
+
+  PKG_REQUIRE="$PKG_REQUIRE factory"
+  AC_SUBST(PKG_REQUIRE)
+ fi
+
+
+ AM_CONDITIONAL([ENABLE_FACTORY],[test x$ENABLE_FACTORY = xyes])
+ AC_MSG_RESULT($ENABLE_FACTORY)
+
+])
+
+AC_DEFUN([SING_CHECK_FACTORY],
+[
+AC_ARG_ENABLE(factory, AS_HELP_STRING([--disable-factory], [Disable factory]),
+[if test $enableval = yes; then
+     ENABLE_FACTORY="yes"
+ else
+     ENABLE_FACTORY="no"
+ fi
+],[ENABLE_FACTORY="yes"])
+
+  AC_ARG_VAR( [FACTORY_INCLUDES], [INCLUDES for FACTORY] )
+  AC_ARG_VAR( [FACTORY_LIBS], [LIBS for FACTORY] )
+
+  AC_MSG_CHECKING(whether factory should be enabled)
+  if test "x$ENABLE_FACTORY" = xyes; then
+    AC_MSG_RESULT(yes)
+
+    AC_MSG_CHECKING([  FACTORY_INCLUDES?..])
+    AC_MSG_RESULT(${FACTORY_INCLUDES:-unset})
+
+    AC_MSG_CHECKING([  FACTORY_LIBS?..])
+    AC_MSG_RESULT(${FACTORY_LIBS:-unset})
+
+
+    CPPFLAGS_save="$CPPFLAGS"
+    CFLAGS_save="$CFLAGS"
+    CXXFLAGS_save="$CXXFLAGS"
+    LIBS_save="$LIBS"
+
+    AC_LANG_PUSH([C++])
+#
+    CPPFLAGS="$CPPFLAGS ${FACTORY_INCLUDES}"
+    CFLAGS="$CFLAGS ${FACTORY_INCLUDES}"
+    CXXFLAGS="$CXXFLAGS ${FACTORY_INCLUDES}"
+    LIBS="${FACTORY_LIBS} $LIBS"
+
+    AC_CHECK_HEADERS([factory/factory.h],,AC_MSG_WARN([trusting the factory locations given: ${FACTORY_INCLUDES}]))
+
+    CFLAGS="$CFLAGS_save"
+    CXXFLAGS="$CXXFLAGS_save"
+    CPPFLAGS="$CPPFLAGS_save"
+    LIBS="$LIBS_save"
+#
+    AC_LANG_POP([C++])
+
+    AC_DEFINE(HAVE_FACTORY,[1],[Enable factory])
+
+    PKG_REQUIRE="$PKG_REQUIRE factory"
+    AC_SUBST(PKG_REQUIRE)
+  else
+    AC_MSG_RESULT(no)
+  fi
+
+  AM_CONDITIONAL([ENABLE_FACTORY],[test x$ENABLE_FACTORY = xyes])
+  AC_MSG_RESULT($ENABLE_FACTORY)
+
+])
+
+
+
+AC_DEFUN([SING_BUILTIN_MODULES],
+[
+## m4_pushdef([_symbol],[m4_cr_Letters[]m4_cr_digits[]_])dnl
+ AC_MSG_CHECKING([built-in modules])
+
+ AC_ARG_VAR( [BUILTIN_LIBS], [LIB FLAGS for buildins] )
+ AC_ARG_WITH(builtinmodules,
+   AS_HELP_STRING([--with-builtinmodules], [List of builtin modules (experimental), default: staticdemo,bigintm,syzextra]),
+   [if test "x$with_builtinmodules" = "xyes"; then
+    with_builtinmodules=syzextra
+   fi],
+   [with_builtinmodules=""]
+ )
+ # staticdemo,bigintm,
+ # ,pyobject,gfanlib,polymake,singmathic
+
+ AH_TEMPLATE([SI_BUILTINMODULES_ADD],[Add(list) for Builtin modules])
+
+ #### TODO Dynamic Modules???
+  L=""
+  bi_staticdemo=false
+  bi_syzextra=false
+  bi_pyobject=false
+  bi_gfanlib=false
+  bi_polymake=false
+  bi_singmathic=false
+  bi_bigintm=false
+  bi_Order=false
+
+
+ if test -z "$with_builtinmodules"; then
+  AC_MSG_RESULT(no)
+ else
+  AC_MSG_RESULT(yes)
+
+  LL=""
+
+  for a in `echo ${with_builtinmodules}|tr ',' ' '`;
+  do
+    AC_MSG_CHECKING([whether to build-in '$a'?])
+
+      L="${L} add($a)"
+      LL="${LL} $a"
+      BUILTIN_LIBS="${BUILTIN_LIBS} dyn_modules/$a/$a.la"
+      AC_MSG_RESULT(yes)
+
+# *) AC_MSG_ERROR([bad value ${enableval} for	    --enable-debug]) ;;
+
+      case "${a}" in
+       staticdemo ) bi_staticdemo=true;;
+       syzextra ) bi_syzextra=true ;;
+       pyobject ) bi_pyobject=true ;;
+       gfanlib ) bi_gfanlib=true ;;
+       polymake ) bi_polymake=true ;;
+       singmathic ) bi_singmathic=true ;;
+       bigintm ) bi_bigintm=true ;;
+       Order ) bi_Order=true ;;
+      esac
+
+###### In case of out-of tree building: the build dir is empty in configure time!!!
+    if test ! -d "Singular/dyn_modules/$a"; then
+        AC_MSG_WARN([The directory 'Singular/dyn_modules/$a' is missing :(])
+##    else
+##      AC_MSG_RESULT(no)
+    fi
+
+#    A=`echo "SI_BUILTIN_$a" | sed -e "y:m4_cr_letters-:m4_cr_LETTERS[]_:"  -e "/^@<:@m4_cr_digits@:>@/s/^/_/"`
+#    echo "A:: $A"
+#    AM_CONDITIONAL(m4_unquote([A]),[test -d "Singular/dyn_modules/$a"]) ## :(((
+  done # for
+
+  AC_DEFINE_UNQUOTED([SI_BUILTINMODULES],"$LL",[Refined list of builtin modules])
+
+ fi # else ("x$with_builtinmodules" != xno)
+
+ AC_MSG_CHECKING([SI_BUILTINMODULES_ADD(add)...])
+ AC_MSG_RESULT(${L:-unset})
+
+ AC_DEFINE_UNQUOTED([SI_BUILTINMODULES_ADD(add)],[$L],[Add(list) for Builtin modules])
+ AC_SUBST(BUILTIN_LIBS)
+
+ AM_CONDITIONAL([SI_BUILTIN_STATICDEMO], [test x$bi_staticdemo = xtrue])
+ AM_CONDITIONAL([SI_BUILTIN_SYZEXTRA], [test x$bi_syzextra = xtrue])
+ AM_CONDITIONAL([SI_BUILTIN_PYOBJECT], [test x$bi_pyobject = xtrue])
+ AM_CONDITIONAL([SI_BUILTIN_GFANLIB], [test x$bi_gfanlib = xtrue])
+ AM_CONDITIONAL([SI_BUILTIN_POLYMAKE], [test x$bi_polymake = xtrue])
+ AM_CONDITIONAL([SI_BUILTIN_SINGMATHIC], [test x$bi_singmathic = xtrue])
+ AM_CONDITIONAL([SI_BUILTIN_BIGINTM], [test x$bi_bigintm = xtrue])
+ AM_CONDITIONAL([SI_BUILTIN_ORDER], [test x$bi_Order = xtrue])
+
+ AC_MSG_CHECKING([BUILTIN_LIBS...])
+ AC_MSG_RESULT(${BUILTIN_LIBS:-unset})
+])
+
+
diff --git a/m4/p-procs.m4 b/m4/p-procs.m4
new file mode 100644
index 0000000..b1e289c
--- /dev/null
+++ b/m4/p-procs.m4
@@ -0,0 +1,90 @@
+# pprocs.m4
+# Copyright 2011 Bradford Hovinen <hovinen at gmail.com>
+#
+# Macro to check user-preferences and system-settings and enable or
+# disable static or dynamic modules for polynomial-operations
+
+AC_DEFUN([SING_SYSTEM_SUPPORTS_DYNAMIC_MODULES],
+[
+AC_CANONICAL_HOST
+AC_MSG_CHECKING(whether system supports dynamic modules)
+AS_CASE([$host],
+  [*linux*], [SUPPORTS_DYNAMIC_MODULES=yes],
+  [*freebsd*], [SUPPORTS_DYNAMIC_MODULES=yes],
+  [*-sun-solaris2*], [SUPPORTS_DYNAMIC_MODULES=yes],
+  [*-apple-darwin*], [SUPPORTS_DYNAMIC_MODULES=yes],
+  [SUPPORTS_DYNAMIC_MODULES=no]
+)
+AC_MSG_RESULT($SUPPORTS_DYNAMIC_MODULES)
+])
+
+AC_DEFUN([SING_CHECK_P_PROCS],
+[
+USEPPROCSDYNAMICLDFLAGS=""
+USEPPROCSDYNAMICLD=""
+
+AC_ARG_ENABLE(p-procs-static,
+[  --enable-p-procs-static Enable statically compiled p_Procs-modules
+],
+[if test $enableval = yes; then
+     ENABLE_P_PROCS_STATIC="yes"
+     ENABLE_P_PROCS_DYNAMIC="no"
+ else
+     ENABLE_P_PROCS_STATIC="no"
+ fi
+],[NO_P_PROCS_STATIC_GIVEN=yes])
+
+AC_ARG_ENABLE(p-procs-dynamic,
+[  --enable-p-procs-dynamic Enable dynamically compiled p_Procs-modules
+],
+[if test $enableval = yes; then
+     ENABLE_P_PROCS_DYNAMIC="yes"
+     ENABLE_P_PROCS_STATIC="no"
+ else
+     ENABLE_P_PROCS_DYNAMIC="no"
+ fi
+],[NO_P_PROCS_DYNAMIC_GIVEN=yes])
+
+if test x$ENABLE_P_PROCS_DYNAMIC = xyes; then
+  SING_SYSTEM_SUPPORTS_DYNAMIC_MODULES
+  if test $SUPPORTS_DYNAMIC_MODULES = no; then
+    AC_MSG_ERROR([--enable-pprocs-dynamic requested but your system appears not to support dynamic modules properly])
+  fi
+
+  AC_CHECK_FUNC(dlopen,,[AC_CHECK_LIB(dl,dlopen,USEPPROCSDYNAMICLD="-ldl", [
+   AC_MSG_WARN(Could not use dlopen)
+  ]) ])
+
+elif test x$NO_P_PROCS_DYNAMIC_GIVEN = xyes -a x$NO_P_PROCS_STATIC_GIVEN = xyes; then
+  SING_SYSTEM_SUPPORTS_DYNAMIC_MODULES
+  if test $SUPPORTS_DYNAMIC_MODULES = yes; then
+    AC_MSG_NOTICE([Enabling dynamic modules and disabling static modules])
+    ENABLE_P_PROCS_DYNAMIC="yes"
+    ENABLE_P_PROCS_STATIC="no"
+    USEPPROCSDYNAMICLDFLAGS=""
+    AC_CHECK_FUNC(dlopen,,[AC_CHECK_LIB(dl,dlopen,USEPPROCSDYNAMICLD="-ldl", [
+      AC_MSG_WARN(Could not use dlopen)
+    ]) ])
+  elif test $SUPPORTS_DYNAMIC_MODULES = no; then
+    AC_MSG_NOTICE([Enabling static modules and disabling dynamic modules])
+    ENABLE_P_PROCS_DYNAMIC="no"
+    ENABLE_P_PROCS_STATIC="yes"
+  else
+    AC_MSG_ERROR([Unknown whether system supports dynamic modules or not. This should not have happened.])
+  fi
+fi
+
+if test x$ENABLE_P_PROCS_DYNAMIC = xyes; then
+  AC_DEFINE(HAVE_DL,1,enable dynamic modules)
+  AC_DEFINE(HAVE_DYNAMIC_LOADING,1,enable dynamic modules)
+
+  AX_APPEND_LINK_FLAGS([-rdynamic -flat_namespace -Wl,-bind_at_load -Wl,-undefined,dynamic_lookup])
+fi
+
+AC_SUBST(USEPPROCSDYNAMICLDFLAGS)
+AC_SUBST(USEPPROCSDYNAMICLD)
+
+AM_CONDITIONAL([ENABLE_P_PROCS_DYNAMIC],[test x$ENABLE_P_PROCS_DYNAMIC = xyes])
+AM_CONDITIONAL([ENABLE_P_PROCS_STATIC],[test x$ENABLE_P_PROCS_STATIC = xyes])
+
+])
diff --git a/m4/polymake-check.m4 b/m4/polymake-check.m4
new file mode 100644
index 0000000..0b00d48
--- /dev/null
+++ b/m4/polymake-check.m4
@@ -0,0 +1,82 @@
+# polymake.m4
+
+AC_DEFUN([SING_CHECK_POLYMAKE],
+[
+
+AC_ARG_ENABLE(polymake,
+ AS_HELP_STRING([--enable-polymake], [Enables interface for Singular to Polymake (needs gfanlib)]),
+ [ENABLE_POLYMAKE="$enableval"], [ENABLE_POLYMAKE=""])
+
+AC_MSG_CHECKING(whether to check for polymake interface)
+
+if test "x$ENABLE_POLYMAKE" != xno; then
+  AC_MSG_RESULT([yes])
+
+
+  if test "x$PASSED_ALL_TESTS_FOR_GFANLIB" != x1; then
+
+   PASSED_ALL_TEST_FOR_POLYMAKE="no";
+
+   if test "x$ENABLE_POLYMAKE" = xyes; then
+    AC_MSG_ERROR([gfanlib was not enabled])
+   else
+    AC_MSG_WARN([gfanlib was not enabled])
+   fi
+
+  else
+
+##  AC_MSG_CHECKING(whether polymake is properly installed)
+   AC_CHECK_PROG([PMCONFIG],[polymake-config],[1],[0])
+   if test $PMCONFIG = "1"; then
+##    AC_MSG_CHECKING([whether polymake is up-to-date])
+    SUPPORTEDPOLYMAKEVERSION="212"
+    CURRENTPOLYMAKEVERSION=`polymake-config --version | cut -c -4 -| sed s'/\.//'`
+    if test $CURRENTPOLYMAKEVERSION -ge $SUPPORTEDPOLYMAKEVERSION; then
+      AC_MSG_RESULT([yes])
+
+      PM_INC=`polymake-config --includes`
+      PM_CFLAGS=`polymake-config --cflags`
+      PM_LIBS=`polymake-config --libs`
+      PM_LDFLAGS=`polymake-config --ldflags`
+
+      AC_SUBST(PM_INC)
+      AC_SUBST(PM_CFLAGS)
+      AC_SUBST(PM_LIBS)
+      AC_SUBST(PM_LDFLAGS)
+
+      AC_DEFINE(HAVE_POLYMAKE,1,[Define if POLYMAKE is installed])
+
+      AC_MSG_CHECKING([polymake includes])
+      AC_MSG_RESULT($PM_INC)
+      AC_MSG_CHECKING([polymake cflags])
+      AC_MSG_RESULT($PM_CFLAGS)
+      AC_MSG_CHECKING([polymake libs])
+      AC_MSG_RESULT($PM_LIBS)
+      AC_MSG_CHECKING([polymake ldflags])
+      AC_MSG_RESULT($PM_LDFLAGS)
+
+      PASSED_ALL_TEST_FOR_POLYMAKE="yes";
+    else
+      PASSED_ALL_TEST_FOR_POLYMAKE="no";
+
+      if test "x$ENABLE_POLYMAKE" = xyes; then
+        AC_MSG_ERROR([outdated polymake version])
+      fi
+    fi
+   else
+    PASSED_ALL_TEST_FOR_POLYMAKE="no";
+
+    if test "x$ENABLE_POLYMAKE" = xyes; then
+     AC_MSG_ERROR([polymake not installed])
+    fi
+   fi
+  fi
+else
+  AC_MSG_RESULT(no)
+
+  PASSED_ALL_TEST_FOR_POLYMAKE="no";
+fi
+
+AM_CONDITIONAL(SING_HAVE_POLYMAKE, test "x$PASSED_ALL_TEST_FOR_POLYMAKE" != xno)
+
+])
diff --git a/m4/readline-check.m4 b/m4/readline-check.m4
new file mode 100644
index 0000000..12d084e
--- /dev/null
+++ b/m4/readline-check.m4
@@ -0,0 +1,119 @@
+# Check for readline
+
+AC_DEFUN([SING_CHECK_READLINE],
+[
+## DEFAULT_CHECKING_PATH="/usr /usr/local /sw /opt/local"
+
+#AC_ARG_WITH([readline],
+#  [AS_HELP_STRING([--without-readline],
+#    [disable support for readline])],
+#  [],
+#  [with_readline=yes])
+
+
+AC_CHECK_HEADERS(sys/file.h sys/ioctl.h sys/time.h sys/times.h sys/types.h \
+ sys/stat.h fcntl.h sys/param.h pwd.h asm/sigcontext.h pwd.h termcap.h \
+ termios.h term.h readline/readline.h)
+
+AC_ARG_WITH(
+  readline,
+  [  --with-readline=[dynamic,static,no]
+                        do use dynamic/static/no readline for fancy display])
+
+AC_CHECK_LIB(ncurses,tgetent,,\
+ AC_CHECK_LIB(curses,tgetent,,\
+  AC_CHECK_LIB(termcap,tgetent)))
+
+# readline
+if test "$with_readline" = dynamic && test "$ac_have_dl" != yes; then
+  AC_MSG_WARN(can not build dynamic readline without dynamic linking)
+  with_readline=static
+fi
+
+
+if test "$with_readline" != dynamic && test "$with_readline" != no; then
+AC_LANG_SAVE
+AC_LANG_CPLUSPLUS
+   AC_CHECK_LIB(readline, readline)
+   AC_CHECK_HEADERS(readline/readline.h readline/history.h)
+   if test "$ac_cv_lib_readline_readline" = yes && \
+      test "$ac_cv_header_readline_readline_h" = yes; then
+     AC_MSG_CHECKING(whether readline.h is ok)
+     AC_CACHE_VAL(ac_cv_header_readline_readline_h_ok,
+     AC_TRY_LINK(
+#include<unistd.h>
+#include<stdio.h>
+#include<readline/readline.h>
+#ifdef HAVE_READLINE_HISTORY_H
+#include<readline/history.h>
+#endif
+,
+,
+ac_cv_header_readline_readline_h_ok="yes",
+ac_cv_header_readline_readline_h_ok="no",
+))
+    AC_MSG_RESULT($ac_cv_header_readline_readline_h_ok)
+    if test "$ac_cv_header_readline_readline_h_ok" != yes; then
+#not ok -- try once more with explicitly declaring everything
+      AC_MSG_CHECKING(whether or not we nevertheless can use readline)
+      AC_CACHE_VAL(ac_cv_have_readline,
+      AC_TRY_LINK(
+#include <stdio.h>
+extern "C"
+{
+extern char * rl_readline_name;
+extern char *rl_line_buffer;
+char *filename_completion_function();
+typedef char **CPPFunction ();
+extern char ** completion_matches ();
+extern CPPFunction * rl_attempted_completion_function;
+extern FILE * rl_outstream;
+char * readline ();
+void add_history ();
+int write_history ();
+int read_history();
+}
+#ifndef NULL
+#define NULL 0
+#endif
+,
+rl_readline_name=NULL;
+*rl_line_buffer=1;
+completion_matches(NULL, filename_completion_function);
+rl_attempted_completion_function = (CPPFunction *) NULL;
+rl_outstream=NULL;
+readline(NULL);
+add_history(NULL);
+read_history(NULL);
+write_history(NULL);
+,
+ac_cv_have_readline="yes"
+,
+ac_cv_have_readline="no"
+))
+      AC_MSG_RESULT($ac_cv_have_readline)
+    else
+      AC_DEFINE([READLINE_READLINE_H_OK], [1], [Use readline.h])
+      ac_cv_have_readline="yes"
+    fi
+  fi
+  if test "$ac_cv_have_readline" = yes; then
+    AC_DEFINE([HAVE_READLINE], [1], [Use readline])
+  fi
+AC_LANG_RESTORE
+fi
+
+AC_MSG_CHECKING(which readline to use)
+if test "$ac_cv_with_readline" = dynamic; then
+  AC_MSG_RESULT(dynamic)
+  AC_DEFINE([HAVE_DYN_RL], [1], [Use dynamic readline])
+elif test "$ac_cv_have_readline" = yes; then
+  AC_MSG_RESULT(static)
+elif test "$ac_cv_singuname" = PowerMacintosh-darwin; then
+  AC_MSG_ERROR(building without readline impossible on PowerMacintosh-darwin)
+else
+  AC_MSG_RESULT(none)
+  AC_MSG_WARN(building without readline: disabling fancy display)
+fi
+
+])
diff --git a/omalloc/AUTHORS b/omalloc/AUTHORS
new file mode 100644
index 0000000..e69de29
diff --git a/omalloc/COPYING b/omalloc/COPYING
new file mode 100644
index 0000000..5ef918f
--- /dev/null
+++ b/omalloc/COPYING
@@ -0,0 +1,36 @@
+                       SINGULAR version 4-0
+                       Package name:   omalloc
+
+                      University of Kaiserslautern
+
+      Department of Mathematics and  Centre for Computer Algebra
+
+                  Author of this package: O. Bachmann
+
+                        Copyright (C) 1999-2010
+
+                               *NOTICE*
+
+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 with the following additional remarks:
+
+This package is part of the software SINGULAR. The GPL is valid for
+this package, other packages may have other copyrights.
+
+Their copyrights and licences can be found in the accompanying files
+which are distributed along with these packages.
+
+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 (see GPL)
+
+Please send any comments or bug reports to
+<singular at mathematik.uni-kl.de>.
+
diff --git a/omalloc/ChangeLog b/omalloc/ChangeLog
new file mode 100644
index 0000000..e69de29
diff --git a/omalloc/Makefile.am b/omalloc/Makefile.am
new file mode 100644
index 0000000..615d3c3
--- /dev/null
+++ b/omalloc/Makefile.am
@@ -0,0 +1,80 @@
+ACLOCAL_AMFLAGS = -I ../m4
+
+lib_LTLIBRARIES=libomalloc.la
+
+libomalloc_includedir=$(includedir)/omalloc
+
+libomalloc_include_HEADERS = \
+omalloc.h		omDerivedConfig.h	\
+omError.h		omStructs.h		omAllocDecl.h		\
+omInlineDecl.h		omBin.h			omMemOps.h		\
+omList.h		omGetBackTrace.h	\
+omRet2Info.h		omStats.h		omOpts.h		\
+omBinPage.h		omAllocSystem.h		\
+omAllocPrivate.h	omDebug.h		omInline.h		\
+omAllocFunc.h 		mylimits.h
+
+noinst_HEADERS= omPage.h omDefaultConfig.h omReturn.h omGetPageSize.h \
+  omMalloc.h omMallocSystem.h
+
+SOURCES=\
+omBinPage.c       omList.c         omAllocEmulate.c omDebug.c        \
+om_Alloc.c        omDebugCheck.c   omOpts.c         omGetBackTrace.c \
+omAllocSystem.c   omError.c        omStats.c	    omRet2Info.c     \
+omBin.c           omDebugTrack.c   		     \
+omalloc_provide.c omAllocFunc.c
+
+EXTRA_DIST = omalloc.c omtTestAlloc.c omtTest.h omMmap.c
+
+AM_CPPFLAGS =-I${top_srcdir}/.. -I${top_builddir}/..
+
+libomalloc_la_SOURCES=$(SOURCES) $(noinst_HEADERS)
+
+libomalloc_la_LDFLAGS    = -release ${PACKAGE_VERSION}
+if WANT_DEBUG
+libomalloc_la_CFLAGS    = -g
+else !WANT_DEBUG
+libomalloc_la_CFLAGS    = -O2
+endif
+
+nodist_libomalloc_la_SOURCES = omTables.inc omTables.h mylimits.h
+nodist_libomalloc_include_HEADERS = omConfig.h mylimits.h omTables.h
+
+libomalloc_la_CPPFLAGS  = ${AM_CPPFLAGS} -DOM_ALLOC_INTERNAL
+
+BUILT_SOURCES = omTables.inc omTables.h
+
+omTables.inc: omTables$(EXEEXT) omalloc.h
+	./omTables$(EXEEXT) > omTables.xx && mv omTables.xx  $@
+
+omTables.h: omTables$(EXEEXT)
+	./omTables$(EXEEXT) 1 >omTables.yy && mv omTables.yy $@
+
+noinst_PROGRAMS = omTables
+omTables_SOURCES = omAllocPrivate.h omTables.c mylimits.h
+nodist_omTables_SOURCES = omConfig.h
+omTables_CPPFLAGS = ${AM_CPPFLAGS} -DOM_GENERATE_INC
+
+CLEANFILES = $(BUILT_SOURCES)
+DISTCLEANFILES = omConfig.h
+####################################################
+## Test program
+
+TESTS = omtTest-m omtTest-r
+
+check_PROGRAMS = $(TESTS)
+
+# EXTRA_PROGRAMS = omtTest-r
+
+OMTTESTSSOURCES = omtTestReal.c omtTestDebug.c omtTestKeep.c omtTestError.c omtTest.c
+
+omtTest_m_CPPFLAGS = ${AM_CPPFLAGS} -DOM_TEST_MALLOC
+omtTest_m_SOURCES  = $(OMTTESTSSOURCES)
+omtTest_m_LDADD    = libomalloc.la
+
+omtTest_r_SOURCES  = $(OMTTESTSSOURCES)
+omtTest_r_LDADD    = libomalloc.la
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = omalloc.pc
+
diff --git a/omalloc/Makefile.in b/omalloc/Makefile.in
new file mode 100644
index 0000000..861f9a5
--- /dev/null
+++ b/omalloc/Makefile.in
@@ -0,0 +1,1614 @@
+# Makefile.in generated by automake 1.13.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 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@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+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 = omTables$(EXEEXT)
+TESTS = omtTest-m$(EXEEXT) omtTest-r$(EXEEXT)
+check_PROGRAMS = $(am__EXEEXT_1)
+subdir = .
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/configure $(am__configure_deps) \
+	$(srcdir)/_config.h.in $(srcdir)/omalloc.pc.in \
+	$(top_srcdir)/../build-aux/depcomp \
+	$(libomalloc_include_HEADERS) $(noinst_HEADERS) \
+	$(top_srcdir)/../build-aux/test-driver AUTHORS COPYING \
+	ChangeLog NEWS README ../build-aux/ar-lib ../build-aux/compile \
+	../build-aux/config.guess ../build-aux/config.sub \
+	../build-aux/depcomp ../build-aux/install-sh \
+	../build-aux/missing ../build-aux/ylwrap \
+	../build-aux/ltmain.sh $(top_srcdir)/../build-aux/ar-lib \
+	$(top_srcdir)/../build-aux/compile \
+	$(top_srcdir)/../build-aux/config.guess \
+	$(top_srcdir)/../build-aux/config.sub \
+	$(top_srcdir)/../build-aux/install-sh \
+	$(top_srcdir)/../build-aux/ltmain.sh \
+	$(top_srcdir)/../build-aux/missing
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/../m4/ax_prefix_config_h.m4 \
+	$(top_srcdir)/../m4/flags.m4 $(top_srcdir)/../m4/libtool.m4 \
+	$(top_srcdir)/../m4/ltoptions.m4 \
+	$(top_srcdir)/../m4/ltsugar.m4 \
+	$(top_srcdir)/../m4/ltversion.m4 \
+	$(top_srcdir)/../m4/lt~obsolete.m4 $(top_srcdir)/configure.ac
+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 = omalloc.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__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
+am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(pkgconfigdir)" \
+	"$(DESTDIR)$(libomalloc_includedir)" \
+	"$(DESTDIR)$(libomalloc_includedir)"
+LTLIBRARIES = $(lib_LTLIBRARIES)
+libomalloc_la_LIBADD =
+am__objects_1 = libomalloc_la-omBinPage.lo libomalloc_la-omList.lo \
+	libomalloc_la-omAllocEmulate.lo libomalloc_la-omDebug.lo \
+	libomalloc_la-om_Alloc.lo libomalloc_la-omDebugCheck.lo \
+	libomalloc_la-omOpts.lo libomalloc_la-omGetBackTrace.lo \
+	libomalloc_la-omAllocSystem.lo libomalloc_la-omError.lo \
+	libomalloc_la-omStats.lo libomalloc_la-omRet2Info.lo \
+	libomalloc_la-omBin.lo libomalloc_la-omDebugTrack.lo \
+	libomalloc_la-omalloc_provide.lo libomalloc_la-omAllocFunc.lo
+am__objects_2 =
+am_libomalloc_la_OBJECTS = $(am__objects_1) $(am__objects_2)
+nodist_libomalloc_la_OBJECTS =
+libomalloc_la_OBJECTS = $(am_libomalloc_la_OBJECTS) \
+	$(nodist_libomalloc_la_OBJECTS)
+AM_V_lt = $(am__v_lt_ at AM_V@)
+am__v_lt_ = $(am__v_lt_ at AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 = 
+libomalloc_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(libomalloc_la_CFLAGS) \
+	$(CFLAGS) $(libomalloc_la_LDFLAGS) $(LDFLAGS) -o $@
+am__EXEEXT_1 = omtTest-m$(EXEEXT) omtTest-r$(EXEEXT)
+PROGRAMS = $(noinst_PROGRAMS)
+am_omTables_OBJECTS = omTables-omTables.$(OBJEXT)
+nodist_omTables_OBJECTS =
+omTables_OBJECTS = $(am_omTables_OBJECTS) $(nodist_omTables_OBJECTS)
+omTables_LDADD = $(LDADD)
+am__objects_3 = omtTest_m-omtTestReal.$(OBJEXT) \
+	omtTest_m-omtTestDebug.$(OBJEXT) \
+	omtTest_m-omtTestKeep.$(OBJEXT) \
+	omtTest_m-omtTestError.$(OBJEXT) omtTest_m-omtTest.$(OBJEXT)
+am_omtTest_m_OBJECTS = $(am__objects_3)
+omtTest_m_OBJECTS = $(am_omtTest_m_OBJECTS)
+omtTest_m_DEPENDENCIES = libomalloc.la
+am__objects_4 = omtTestReal.$(OBJEXT) omtTestDebug.$(OBJEXT) \
+	omtTestKeep.$(OBJEXT) omtTestError.$(OBJEXT) omtTest.$(OBJEXT)
+am_omtTest_r_OBJECTS = $(am__objects_4)
+omtTest_r_OBJECTS = $(am_omtTest_r_OBJECTS)
+omtTest_r_DEPENDENCIES = libomalloc.la
+AM_V_P = $(am__v_P_ at AM_V@)
+am__v_P_ = $(am__v_P_ at AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_ at AM_V@)
+am__v_GEN_ = $(am__v_GEN_ at AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_ at AM_V@)
+am__v_at_ = $(am__v_at_ at AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+DEFAULT_INCLUDES = -I. at am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/../build-aux/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+	$(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_ at AM_V@)
+am__v_CC_ = $(am__v_CC_ at AM_DEFAULT_V@)
+am__v_CC_0 = @echo "  CC      " $@;
+am__v_CC_1 = 
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+	$(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_ at AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_ at AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo "  CCLD    " $@;
+am__v_CCLD_1 = 
+DIST_SOURCES = $(libomalloc_la_SOURCES) $(omTables_SOURCES) \
+	$(omtTest_m_SOURCES) $(omtTest_r_SOURCES)
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+DATA = $(pkgconfig_DATA)
+HEADERS = $(libomalloc_include_HEADERS) \
+	$(nodist_libomalloc_include_HEADERS) $(noinst_HEADERS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \
+	$(LISP)_config.h.in
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+CSCOPE = cscope
+AM_RECURSIVE_TARGETS = cscope check recheck
+am__tty_colors_dummy = \
+  mgn= red= grn= lgn= blu= brg= std=; \
+  am__color_tests=no
+am__tty_colors = { \
+  $(am__tty_colors_dummy); \
+  if test "X$(AM_COLOR_TESTS)" = Xno; then \
+    am__color_tests=no; \
+  elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+    am__color_tests=yes; \
+  elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+    am__color_tests=yes; \
+  fi; \
+  if test $$am__color_tests = yes; then \
+    red=''; \
+    grn=''; \
+    lgn=''; \
+    blu=''; \
+    mgn=''; \
+    brg=''; \
+    std=''; \
+  fi; \
+}
+am__recheck_rx = ^[ 	]*:recheck:[ 	]*
+am__global_test_result_rx = ^[ 	]*:global-test-result:[ 	]*
+am__copy_in_global_log_rx = ^[ 	]*:copy-in-global-log:[ 	]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+  recheck = 1; \
+  while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+    { \
+      if (rc < 0) \
+        { \
+          if ((getline line2 < ($$0 ".log")) < 0) \
+	    recheck = 0; \
+          break; \
+        } \
+      else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+        { \
+          recheck = 0; \
+          break; \
+        } \
+      else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+        { \
+          break; \
+        } \
+    }; \
+  if (recheck) \
+    print $$0; \
+  close ($$0 ".trs"); \
+  close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+  print "fatal: making $@: " msg | "cat >&2"; \
+  exit 1; \
+} \
+function rst_section(header) \
+{ \
+  print header; \
+  len = length(header); \
+  for (i = 1; i <= len; i = i + 1) \
+    printf "="; \
+  printf "\n\n"; \
+} \
+{ \
+  copy_in_global_log = 1; \
+  global_test_result = "RUN"; \
+  while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+    { \
+      if (rc < 0) \
+         fatal("failed to read from " $$0 ".trs"); \
+      if (line ~ /$(am__global_test_result_rx)/) \
+        { \
+          sub("$(am__global_test_result_rx)", "", line); \
+          sub("[ 	]*$$", "", line); \
+          global_test_result = line; \
+        } \
+      else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+        copy_in_global_log = 0; \
+    }; \
+  if (copy_in_global_log) \
+    { \
+      rst_section(global_test_result ": " $$0); \
+      while ((rc = (getline line < ($$0 ".log"))) != 0) \
+      { \
+        if (rc < 0) \
+          fatal("failed to read from " $$0 ".log"); \
+        print line; \
+      }; \
+      printf "\n"; \
+    }; \
+  close ($$0 ".trs"); \
+  close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/   &   /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this.  Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+  --color-tests "$$am__color_tests" \
+  --enable-hard-errors "$$am__enable_hard_errors" \
+  --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test.  Creates the
+# directory for the log if needed.  Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log.  Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT.  Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup);					\
+$(am__vpath_adj_setup) $(am__vpath_adj)			\
+$(am__tty_colors);					\
+srcdir=$(srcdir); export srcdir;			\
+case "$@" in						\
+  */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;;	\
+    *) am__odir=.;; 					\
+esac;							\
+test "x$$am__odir" = x"." || test -d "$$am__odir" 	\
+  || $(MKDIR_P) "$$am__odir" || exit $$?;		\
+if test -f "./$$f"; then dir=./;			\
+elif test -f "$$f"; then dir=;				\
+else dir="$(srcdir)/"; fi;				\
+tst=$$dir$$f; log='$@'; 				\
+if test -n '$(DISABLE_HARD_ERRORS)'; then		\
+  am__enable_hard_errors=no; 				\
+else							\
+  am__enable_hard_errors=yes; 				\
+fi; 							\
+case " $(XFAIL_TESTS) " in				\
+  *[\ \	]$$f[\ \	]* | *[\ \	]$$dir$$f[\ \	]*) \
+    am__expect_failure=yes;;				\
+  *)							\
+    am__expect_failure=no;;				\
+esac; 							\
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed).  The result is saved in the shell variable
+# '$bases'.  This honors runtime overriding of TESTS and TEST_LOGS.  Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+  bases='$(TEST_LOGS)'; \
+  bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+  bases=`echo $$bases`
+RECHECK_LOGS = $(TEST_LOGS)
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_DRIVER = $(SHELL) $(top_srcdir)/../build-aux/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+  case '$@' in \
+    */*) \
+      case '$*' in \
+        */*) b='$*';; \
+          *) b=`echo '$@' | sed 's/\.log$$//'`; \
+       esac;; \
+    *) \
+      b='$*';; \
+  esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT at .log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/../build-aux/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+	$(TEST_LOG_FLAGS)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+distdir = $(PACKAGE)-$(VERSION)
+top_distdir = $(distdir)
+am__remove_distdir = \
+  if test -d "$(distdir)"; then \
+    find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \
+      && rm -rf "$(distdir)" \
+      || { sleep 5 && rm -rf "$(distdir)"; }; \
+  else :; fi
+am__post_remove_distdir = $(am__remove_distdir)
+DIST_ARCHIVES = $(distdir).tar.gz
+GZIP_ENV = --best
+DIST_TARGETS = dist-gzip
+distuninstallcheck_listfiles = find . -type f -print
+am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \
+  | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$'
+distcleancheck_listfiles = find . -type f -print
+ACLOCAL = @ACLOCAL@
+ADDR2LINE = @ADDR2LINE@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+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@
+EXTERNAL_CONFIG_HEADER = @EXTERNAL_CONFIG_HEADER@
+EXTERNAL_CONFIG_SOURCE = @EXTERNAL_CONFIG_SOURCE@
+FGREP = @FGREP@
+GREP = @GREP@
+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@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OM_MALLOC_HEADER = @OM_MALLOC_HEADER@
+OM_MALLOC_SOURCE = @OM_MALLOC_SOURCE@
+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@
+PERL = @PERL@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+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@
+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@
+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@
+ACLOCAL_AMFLAGS = -I ../m4
+lib_LTLIBRARIES = libomalloc.la
+libomalloc_includedir = $(includedir)/omalloc
+libomalloc_include_HEADERS = \
+omalloc.h		omDerivedConfig.h	\
+omError.h		omStructs.h		omAllocDecl.h		\
+omInlineDecl.h		omBin.h			omMemOps.h		\
+omList.h		omGetBackTrace.h	\
+omRet2Info.h		omStats.h		omOpts.h		\
+omBinPage.h		omAllocSystem.h		\
+omAllocPrivate.h	omDebug.h		omInline.h		\
+omAllocFunc.h 		mylimits.h
+
+noinst_HEADERS = omPage.h omDefaultConfig.h omReturn.h omGetPageSize.h \
+  omMalloc.h omMallocSystem.h
+
+SOURCES = \
+omBinPage.c       omList.c         omAllocEmulate.c omDebug.c        \
+om_Alloc.c        omDebugCheck.c   omOpts.c         omGetBackTrace.c \
+omAllocSystem.c   omError.c        omStats.c	    omRet2Info.c     \
+omBin.c           omDebugTrack.c   		     \
+omalloc_provide.c omAllocFunc.c
+
+EXTRA_DIST = omalloc.c omtTestAlloc.c omtTest.h omMmap.c
+AM_CPPFLAGS = -I${top_srcdir}/.. -I${top_builddir}/..
+libomalloc_la_SOURCES = $(SOURCES) $(noinst_HEADERS)
+libomalloc_la_LDFLAGS = -release ${PACKAGE_VERSION}
+ at WANT_DEBUG_FALSE@libomalloc_la_CFLAGS = -O2
+ at WANT_DEBUG_TRUE@libomalloc_la_CFLAGS = -g
+nodist_libomalloc_la_SOURCES = omTables.inc omTables.h mylimits.h
+nodist_libomalloc_include_HEADERS = omConfig.h mylimits.h omTables.h
+libomalloc_la_CPPFLAGS = ${AM_CPPFLAGS} -DOM_ALLOC_INTERNAL
+BUILT_SOURCES = omTables.inc omTables.h
+omTables_SOURCES = omAllocPrivate.h omTables.c mylimits.h
+nodist_omTables_SOURCES = omConfig.h
+omTables_CPPFLAGS = ${AM_CPPFLAGS} -DOM_GENERATE_INC
+CLEANFILES = $(BUILT_SOURCES)
+DISTCLEANFILES = omConfig.h
+
+# EXTRA_PROGRAMS = omtTest-r
+OMTTESTSSOURCES = omtTestReal.c omtTestDebug.c omtTestKeep.c omtTestError.c omtTest.c
+omtTest_m_CPPFLAGS = ${AM_CPPFLAGS} -DOM_TEST_MALLOC
+omtTest_m_SOURCES = $(OMTTESTSSOURCES)
+omtTest_m_LDADD = libomalloc.la
+omtTest_r_SOURCES = $(OMTTESTSSOURCES)
+omtTest_r_LDADD = libomalloc.la
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = omalloc.pc
+all: $(BUILT_SOURCES) _config.h
+	$(MAKE) $(AM_MAKEFLAGS) all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs
+am--refresh: Makefile
+	@:
+$(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) --foreign'; \
+	      $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \
+		&& exit 0; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign 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; else :; fi
+	@if test ! -f $@; then $(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
+omalloc.pc: $(top_builddir)/config.status $(srcdir)/omalloc.pc.in
+	cd $(top_builddir) && $(SHELL) ./config.status $@
+
+install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+	@$(NORMAL_INSTALL)
+	@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 " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \
+	  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)'; \
+	locs=`for p in $$list; do echo $$p; done | \
+	      sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+	      sort -u`; \
+	test -z "$$locs" || { \
+	  echo rm -f $${locs}; \
+	  rm -f $${locs}; \
+	}
+
+libomalloc.la: $(libomalloc_la_OBJECTS) $(libomalloc_la_DEPENDENCIES) $(EXTRA_libomalloc_la_DEPENDENCIES) 
+	$(AM_V_CCLD)$(libomalloc_la_LINK) -rpath $(libdir) $(libomalloc_la_OBJECTS) $(libomalloc_la_LIBADD) $(LIBS)
+
+clean-checkPROGRAMS:
+	@list='$(check_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
+
+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
+
+omTables$(EXEEXT): $(omTables_OBJECTS) $(omTables_DEPENDENCIES) $(EXTRA_omTables_DEPENDENCIES) 
+	@rm -f omTables$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(omTables_OBJECTS) $(omTables_LDADD) $(LIBS)
+
+omtTest-m$(EXEEXT): $(omtTest_m_OBJECTS) $(omtTest_m_DEPENDENCIES) $(EXTRA_omtTest_m_DEPENDENCIES) 
+	@rm -f omtTest-m$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(omtTest_m_OBJECTS) $(omtTest_m_LDADD) $(LIBS)
+
+omtTest-r$(EXEEXT): $(omtTest_r_OBJECTS) $(omtTest_r_DEPENDENCIES) $(EXTRA_omtTest_r_DEPENDENCIES) 
+	@rm -f omtTest-r$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(omtTest_r_OBJECTS) $(omtTest_r_LDADD) $(LIBS)
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libomalloc_la-omAllocEmulate.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libomalloc_la-omAllocFunc.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libomalloc_la-omAllocSystem.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libomalloc_la-omBin.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libomalloc_la-omBinPage.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libomalloc_la-omDebug.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libomalloc_la-omDebugCheck.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libomalloc_la-omDebugTrack.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libomalloc_la-omError.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libomalloc_la-omGetBackTrace.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libomalloc_la-omList.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libomalloc_la-omOpts.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libomalloc_la-omRet2Info.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libomalloc_la-omStats.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libomalloc_la-om_Alloc.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libomalloc_la-omalloc_provide.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/omTables-omTables.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/omtTest.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/omtTestDebug.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/omtTestError.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/omtTestKeep.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/omtTestReal.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/omtTest_m-omtTest.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/omtTest_m-omtTestDebug.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/omtTest_m-omtTestError.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/omtTest_m-omtTestKeep.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/omtTest_m-omtTestReal.Po at am__quote@
+
+.c.o:
+ at am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+ at am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+ at am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+ at am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+ at am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+ at am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+ at am__fastdepCC_TRUE@	$(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+libomalloc_la-omBinPage.lo: omBinPage.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libomalloc_la_CPPFLAGS) $(CPPFLAGS) $(libomalloc_la_CFLAGS) $(CFLAGS) -MT libomalloc_la-omBinPage.lo -MD -MP -MF $(DEPDIR)/libomalloc_la-omBinPage.Tpo -c -o libomalloc_la-omBinPage.lo `test -f 'omBinPage.c' || echo '$(srcdir)/'`omBinPage.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libomalloc_la-omBinPage.Tpo $(DEPDIR)/libomalloc_la-omBinPage.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='omBinPage.c' object='libomalloc_la-omBinPage.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libomalloc_la_CPPFLAGS) $(CPPFLAGS) $(libomalloc_la_CFLAGS) $(CFLAGS) -c -o libomalloc_la-omBinPage.lo `test -f 'omBinPage.c' || echo '$(srcdir)/'`omBinPage.c
+
+libomalloc_la-omList.lo: omList.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libomalloc_la_CPPFLAGS) $(CPPFLAGS) $(libomalloc_la_CFLAGS) $(CFLAGS) -MT libomalloc_la-omList.lo -MD -MP -MF $(DEPDIR)/libomalloc_la-omList.Tpo -c -o libomalloc_la-omList.lo `test -f 'omList.c' || echo '$(srcdir)/'`omList.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libomalloc_la-omList.Tpo $(DEPDIR)/libomalloc_la-omList.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='omList.c' object='libomalloc_la-omList.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libomalloc_la_CPPFLAGS) $(CPPFLAGS) $(libomalloc_la_CFLAGS) $(CFLAGS) -c -o libomalloc_la-omList.lo `test -f 'omList.c' || echo '$(srcdir)/'`omList.c
+
+libomalloc_la-omAllocEmulate.lo: omAllocEmulate.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libomalloc_la_CPPFLAGS) $(CPPFLAGS) $(libomalloc_la_CFLAGS) $(CFLAGS) -MT libomalloc_la-omAllocEmulate.lo -MD -MP -MF $(DEPDIR)/libomalloc_la-omAllocEmulate.Tpo -c -o libomalloc_la-omAllocEmulate.lo `test -f 'omAllocEmulate.c' || echo '$(srcdir)/'`omAllocEmulate.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libomalloc_la-omAllocEmulate.Tpo $(DEPDIR)/libomalloc_la-omAllocEmulate.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='omAllocEmulate.c' object='libomalloc_la-omAllocEmulate.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libomalloc_la_CPPFLAGS) $(CPPFLAGS) $(libomalloc_la_CFLAGS) $(CFLAGS) -c -o libomalloc_la-omAllocEmulate.lo `test -f 'omAllocEmulate.c' || echo '$(srcdir)/'`omAllocEmulate.c
+
+libomalloc_la-omDebug.lo: omDebug.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libomalloc_la_CPPFLAGS) $(CPPFLAGS) $(libomalloc_la_CFLAGS) $(CFLAGS) -MT libomalloc_la-omDebug.lo -MD -MP -MF $(DEPDIR)/libomalloc_la-omDebug.Tpo -c -o libomalloc_la-omDebug.lo `test -f 'omDebug.c' || echo '$(srcdir)/'`omDebug.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libomalloc_la-omDebug.Tpo $(DEPDIR)/libomalloc_la-omDebug.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='omDebug.c' object='libomalloc_la-omDebug.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libomalloc_la_CPPFLAGS) $(CPPFLAGS) $(libomalloc_la_CFLAGS) $(CFLAGS) -c -o libomalloc_la-omDebug.lo `test -f 'omDebug.c' || echo '$(srcdir)/'`omDebug.c
+
+libomalloc_la-om_Alloc.lo: om_Alloc.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libomalloc_la_CPPFLAGS) $(CPPFLAGS) $(libomalloc_la_CFLAGS) $(CFLAGS) -MT libomalloc_la-om_Alloc.lo -MD -MP -MF $(DEPDIR)/libomalloc_la-om_Alloc.Tpo -c -o libomalloc_la-om_Alloc.lo `test -f 'om_Alloc.c' || echo '$(srcdir)/'`om_Alloc.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libomalloc_la-om_Alloc.Tpo $(DEPDIR)/libomalloc_la-om_Alloc.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='om_Alloc.c' object='libomalloc_la-om_Alloc.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libomalloc_la_CPPFLAGS) $(CPPFLAGS) $(libomalloc_la_CFLAGS) $(CFLAGS) -c -o libomalloc_la-om_Alloc.lo `test -f 'om_Alloc.c' || echo '$(srcdir)/'`om_Alloc.c
+
+libomalloc_la-omDebugCheck.lo: omDebugCheck.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libomalloc_la_CPPFLAGS) $(CPPFLAGS) $(libomalloc_la_CFLAGS) $(CFLAGS) -MT libomalloc_la-omDebugCheck.lo -MD -MP -MF $(DEPDIR)/libomalloc_la-omDebugCheck.Tpo -c -o libomalloc_la-omDebugCheck.lo `test -f 'omDebugCheck.c' || echo '$(srcdir)/'`omDebugCheck.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libomalloc_la-omDebugCheck.Tpo $(DEPDIR)/libomalloc_la-omDebugCheck.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='omDebugCheck.c' object='libomalloc_la-omDebugCheck.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libomalloc_la_CPPFLAGS) $(CPPFLAGS) $(libomalloc_la_CFLAGS) $(CFLAGS) -c -o libomalloc_la-omDebugCheck.lo `test -f 'omDebugCheck.c' || echo '$(srcdir)/'`omDebugCheck.c
+
+libomalloc_la-omOpts.lo: omOpts.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libomalloc_la_CPPFLAGS) $(CPPFLAGS) $(libomalloc_la_CFLAGS) $(CFLAGS) -MT libomalloc_la-omOpts.lo -MD -MP -MF $(DEPDIR)/libomalloc_la-omOpts.Tpo -c -o libomalloc_la-omOpts.lo `test -f 'omOpts.c' || echo '$(srcdir)/'`omOpts.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libomalloc_la-omOpts.Tpo $(DEPDIR)/libomalloc_la-omOpts.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='omOpts.c' object='libomalloc_la-omOpts.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libomalloc_la_CPPFLAGS) $(CPPFLAGS) $(libomalloc_la_CFLAGS) $(CFLAGS) -c -o libomalloc_la-omOpts.lo `test -f 'omOpts.c' || echo '$(srcdir)/'`omOpts.c
+
+libomalloc_la-omGetBackTrace.lo: omGetBackTrace.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libomalloc_la_CPPFLAGS) $(CPPFLAGS) $(libomalloc_la_CFLAGS) $(CFLAGS) -MT libomalloc_la-omGetBackTrace.lo -MD -MP -MF $(DEPDIR)/libomalloc_la-omGetBackTrace.Tpo -c -o libomalloc_la-omGetBackTrace.lo `test -f 'omGetBackTrace.c' || echo '$(srcdir)/'`omGetBackTrace.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libomalloc_la-omGetBackTrace.Tpo $(DEPDIR)/libomalloc_la-omGetBackTrace.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='omGetBackTrace.c' object='libomalloc_la-omGetBackTrace.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libomalloc_la_CPPFLAGS) $(CPPFLAGS) $(libomalloc_la_CFLAGS) $(CFLAGS) -c -o libomalloc_la-omGetBackTrace.lo `test -f 'omGetBackTrace.c' || echo '$(srcdir)/'`omGetBackTrace.c
+
+libomalloc_la-omAllocSystem.lo: omAllocSystem.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libomalloc_la_CPPFLAGS) $(CPPFLAGS) $(libomalloc_la_CFLAGS) $(CFLAGS) -MT libomalloc_la-omAllocSystem.lo -MD -MP -MF $(DEPDIR)/libomalloc_la-omAllocSystem.Tpo -c -o libomalloc_la-omAllocSystem.lo `test -f 'omAllocSystem.c' || echo '$(srcdir)/'`omAllocSystem.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libomalloc_la-omAllocSystem.Tpo $(DEPDIR)/libomalloc_la-omAllocSystem.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='omAllocSystem.c' object='libomalloc_la-omAllocSystem.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libomalloc_la_CPPFLAGS) $(CPPFLAGS) $(libomalloc_la_CFLAGS) $(CFLAGS) -c -o libomalloc_la-omAllocSystem.lo `test -f 'omAllocSystem.c' || echo '$(srcdir)/'`omAllocSystem.c
+
+libomalloc_la-omError.lo: omError.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libomalloc_la_CPPFLAGS) $(CPPFLAGS) $(libomalloc_la_CFLAGS) $(CFLAGS) -MT libomalloc_la-omError.lo -MD -MP -MF $(DEPDIR)/libomalloc_la-omError.Tpo -c -o libomalloc_la-omError.lo `test -f 'omError.c' || echo '$(srcdir)/'`omError.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libomalloc_la-omError.Tpo $(DEPDIR)/libomalloc_la-omError.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='omError.c' object='libomalloc_la-omError.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libomalloc_la_CPPFLAGS) $(CPPFLAGS) $(libomalloc_la_CFLAGS) $(CFLAGS) -c -o libomalloc_la-omError.lo `test -f 'omError.c' || echo '$(srcdir)/'`omError.c
+
+libomalloc_la-omStats.lo: omStats.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libomalloc_la_CPPFLAGS) $(CPPFLAGS) $(libomalloc_la_CFLAGS) $(CFLAGS) -MT libomalloc_la-omStats.lo -MD -MP -MF $(DEPDIR)/libomalloc_la-omStats.Tpo -c -o libomalloc_la-omStats.lo `test -f 'omStats.c' || echo '$(srcdir)/'`omStats.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libomalloc_la-omStats.Tpo $(DEPDIR)/libomalloc_la-omStats.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='omStats.c' object='libomalloc_la-omStats.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libomalloc_la_CPPFLAGS) $(CPPFLAGS) $(libomalloc_la_CFLAGS) $(CFLAGS) -c -o libomalloc_la-omStats.lo `test -f 'omStats.c' || echo '$(srcdir)/'`omStats.c
+
+libomalloc_la-omRet2Info.lo: omRet2Info.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libomalloc_la_CPPFLAGS) $(CPPFLAGS) $(libomalloc_la_CFLAGS) $(CFLAGS) -MT libomalloc_la-omRet2Info.lo -MD -MP -MF $(DEPDIR)/libomalloc_la-omRet2Info.Tpo -c -o libomalloc_la-omRet2Info.lo `test -f 'omRet2Info.c' || echo '$(srcdir)/'`omRet2Info.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libomalloc_la-omRet2Info.Tpo $(DEPDIR)/libomalloc_la-omRet2Info.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='omRet2Info.c' object='libomalloc_la-omRet2Info.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libomalloc_la_CPPFLAGS) $(CPPFLAGS) $(libomalloc_la_CFLAGS) $(CFLAGS) -c -o libomalloc_la-omRet2Info.lo `test -f 'omRet2Info.c' || echo '$(srcdir)/'`omRet2Info.c
+
+libomalloc_la-omBin.lo: omBin.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libomalloc_la_CPPFLAGS) $(CPPFLAGS) $(libomalloc_la_CFLAGS) $(CFLAGS) -MT libomalloc_la-omBin.lo -MD -MP -MF $(DEPDIR)/libomalloc_la-omBin.Tpo -c -o libomalloc_la-omBin.lo `test -f 'omBin.c' || echo '$(srcdir)/'`omBin.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libomalloc_la-omBin.Tpo $(DEPDIR)/libomalloc_la-omBin.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='omBin.c' object='libomalloc_la-omBin.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libomalloc_la_CPPFLAGS) $(CPPFLAGS) $(libomalloc_la_CFLAGS) $(CFLAGS) -c -o libomalloc_la-omBin.lo `test -f 'omBin.c' || echo '$(srcdir)/'`omBin.c
+
+libomalloc_la-omDebugTrack.lo: omDebugTrack.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libomalloc_la_CPPFLAGS) $(CPPFLAGS) $(libomalloc_la_CFLAGS) $(CFLAGS) -MT libomalloc_la-omDebugTrack.lo -MD -MP -MF $(DEPDIR)/libomalloc_la-omDebugTrack.Tpo -c -o libomalloc_la-omDebugTrack.lo `test -f 'omDebugTrack.c' || echo '$(srcdir)/'`omDebugTrack.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libomalloc_la-omDebugTrack.Tpo $(DEPDIR)/libomalloc_la-omDebugTrack.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='omDebugTrack.c' object='libomalloc_la-omDebugTrack.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libomalloc_la_CPPFLAGS) $(CPPFLAGS) $(libomalloc_la_CFLAGS) $(CFLAGS) -c -o libomalloc_la-omDebugTrack.lo `test -f 'omDebugTrack.c' || echo '$(srcdir)/'`omDebugTrack.c
+
+libomalloc_la-omalloc_provide.lo: omalloc_provide.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libomalloc_la_CPPFLAGS) $(CPPFLAGS) $(libomalloc_la_CFLAGS) $(CFLAGS) -MT libomalloc_la-omalloc_provide.lo -MD -MP -MF $(DEPDIR)/libomalloc_la-omalloc_provide.Tpo -c -o libomalloc_la-omalloc_provide.lo `test -f 'omalloc_provide.c' || echo '$(srcdir)/'`omalloc_provide.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libomalloc_la-omalloc_provide.Tpo $(DEPDIR)/libomalloc_la-omalloc_provide.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='omalloc_provide.c' object='libomalloc_la-omalloc_provide.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libomalloc_la_CPPFLAGS) $(CPPFLAGS) $(libomalloc_la_CFLAGS) $(CFLAGS) -c -o libomalloc_la-omalloc_provide.lo `test -f 'omalloc_provide.c' || echo '$(srcdir)/'`omalloc_provide.c
+
+libomalloc_la-omAllocFunc.lo: omAllocFunc.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libomalloc_la_CPPFLAGS) $(CPPFLAGS) $(libomalloc_la_CFLAGS) $(CFLAGS) -MT libomalloc_la-omAllocFunc.lo -MD -MP -MF $(DEPDIR)/libomalloc_la-omAllocFunc.Tpo -c -o libomalloc_la-omAllocFunc.lo `test -f 'omAllocFunc.c' || echo '$(srcdir)/'`omAllocFunc.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libomalloc_la-omAllocFunc.Tpo $(DEPDIR)/libomalloc_la-omAllocFunc.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='omAllocFunc.c' object='libomalloc_la-omAllocFunc.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libomalloc_la_CPPFLAGS) $(CPPFLAGS) $(libomalloc_la_CFLAGS) $(CFLAGS) -c -o libomalloc_la-omAllocFunc.lo `test -f 'omAllocFunc.c' || echo '$(srcdir)/'`omAllocFunc.c
+
+omTables-omTables.o: omTables.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(omTables_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT omTables-omTables.o -MD -MP -MF $(DEPDIR)/omTables-omTables.Tpo -c -o omTables-omTables.o `test -f 'omTables.c' || echo '$(srcdir)/'`omTables.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/omTables-omTables.Tpo $(DEPDIR)/omTables-omTables.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='omTables.c' object='omTables-omTables.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(omTables_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o omTables-omTables.o `test -f 'omTables.c' || echo '$(srcdir)/'`omTables.c
+
+omTables-omTables.obj: omTables.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(omTables_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT omTables-omTables.obj -MD -MP -MF $(DEPDIR)/omTables-omTables.Tpo -c -o omTables-omTables.obj `if test -f 'omTables.c'; then $(CYGPATH_W) 'omTables.c'; else $(CYGPATH_W) '$(srcdir)/omTables.c'; fi`
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/omTables-omTables.Tpo $(DEPDIR)/omTables-omTables.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='omTables.c' object='omTables-omTables.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(omTables_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o omTables-omTables.obj `if test -f 'omTables.c'; then $(CYGPATH_W) 'omTables.c'; else $(CYGPATH_W) '$(srcdir)/omTables.c'; fi`
+
+omtTest_m-omtTestReal.o: omtTestReal.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(omtTest_m_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT omtTest_m-omtTestReal.o -MD -MP -MF $(DEPDIR)/omtTest_m-omtTestReal.Tpo -c -o omtTest_m-omtTestReal.o `test -f 'omtTestReal.c' || echo '$(srcdir)/'`omtTestReal.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/omtTest_m-omtTestReal.Tpo $(DEPDIR)/omtTest_m-omtTestReal.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='omtTestReal.c' object='omtTest_m-omtTestReal.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(omtTest_m_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o omtTest_m-omtTestReal.o `test -f 'omtTestReal.c' || echo '$(srcdir)/'`omtTestReal.c
+
+omtTest_m-omtTestReal.obj: omtTestReal.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(omtTest_m_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT omtTest_m-omtTestReal.obj -MD -MP -MF $(DEPDIR)/omtTest_m-omtTestReal.Tpo -c -o omtTest_m-omtTestReal.obj `if test -f 'omtTestReal.c'; then $(CYGPATH_W) 'omtTestReal.c'; else $(CYGPATH_W) '$(srcdir)/omtTestReal.c'; fi`
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/omtTest_m-omtTestReal.Tpo $(DEPDIR)/omtTest_m-omtTestReal.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='omtTestReal.c' object='omtTest_m-omtTestReal.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(omtTest_m_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o omtTest_m-omtTestReal.obj `if test -f 'omtTestReal.c'; then $(CYGPATH_W) 'omtTestReal.c'; else $(CYGPATH_W) '$(srcdir)/omtTestReal.c'; fi`
+
+omtTest_m-omtTestDebug.o: omtTestDebug.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(omtTest_m_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT omtTest_m-omtTestDebug.o -MD -MP -MF $(DEPDIR)/omtTest_m-omtTestDebug.Tpo -c -o omtTest_m-omtTestDebug.o `test -f 'omtTestDebug.c' || echo '$(srcdir)/'`omtTestDebug.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/omtTest_m-omtTestDebug.Tpo $(DEPDIR)/omtTest_m-omtTestDebug.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='omtTestDebug.c' object='omtTest_m-omtTestDebug.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(omtTest_m_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o omtTest_m-omtTestDebug.o `test -f 'omtTestDebug.c' || echo '$(srcdir)/'`omtTestDebug.c
+
+omtTest_m-omtTestDebug.obj: omtTestDebug.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(omtTest_m_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT omtTest_m-omtTestDebug.obj -MD -MP -MF $(DEPDIR)/omtTest_m-omtTestDebug.Tpo -c -o omtTest_m-omtTestDebug.obj `if test -f 'omtTestDebug.c'; then $(CYGPATH_W) 'omtTestDebug.c'; else $(CYGPATH_W) '$(srcdir)/omtTestDebug.c'; fi`
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/omtTest_m-omtTestDebug.Tpo $(DEPDIR)/omtTest_m-omtTestDebug.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='omtTestDebug.c' object='omtTest_m-omtTestDebug.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(omtTest_m_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o omtTest_m-omtTestDebug.obj `if test -f 'omtTestDebug.c'; then $(CYGPATH_W) 'omtTestDebug.c'; else $(CYGPATH_W) '$(srcdir)/omtTestDebug.c'; fi`
+
+omtTest_m-omtTestKeep.o: omtTestKeep.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(omtTest_m_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT omtTest_m-omtTestKeep.o -MD -MP -MF $(DEPDIR)/omtTest_m-omtTestKeep.Tpo -c -o omtTest_m-omtTestKeep.o `test -f 'omtTestKeep.c' || echo '$(srcdir)/'`omtTestKeep.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/omtTest_m-omtTestKeep.Tpo $(DEPDIR)/omtTest_m-omtTestKeep.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='omtTestKeep.c' object='omtTest_m-omtTestKeep.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(omtTest_m_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o omtTest_m-omtTestKeep.o `test -f 'omtTestKeep.c' || echo '$(srcdir)/'`omtTestKeep.c
+
+omtTest_m-omtTestKeep.obj: omtTestKeep.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(omtTest_m_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT omtTest_m-omtTestKeep.obj -MD -MP -MF $(DEPDIR)/omtTest_m-omtTestKeep.Tpo -c -o omtTest_m-omtTestKeep.obj `if test -f 'omtTestKeep.c'; then $(CYGPATH_W) 'omtTestKeep.c'; else $(CYGPATH_W) '$(srcdir)/omtTestKeep.c'; fi`
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/omtTest_m-omtTestKeep.Tpo $(DEPDIR)/omtTest_m-omtTestKeep.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='omtTestKeep.c' object='omtTest_m-omtTestKeep.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(omtTest_m_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o omtTest_m-omtTestKeep.obj `if test -f 'omtTestKeep.c'; then $(CYGPATH_W) 'omtTestKeep.c'; else $(CYGPATH_W) '$(srcdir)/omtTestKeep.c'; fi`
+
+omtTest_m-omtTestError.o: omtTestError.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(omtTest_m_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT omtTest_m-omtTestError.o -MD -MP -MF $(DEPDIR)/omtTest_m-omtTestError.Tpo -c -o omtTest_m-omtTestError.o `test -f 'omtTestError.c' || echo '$(srcdir)/'`omtTestError.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/omtTest_m-omtTestError.Tpo $(DEPDIR)/omtTest_m-omtTestError.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='omtTestError.c' object='omtTest_m-omtTestError.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(omtTest_m_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o omtTest_m-omtTestError.o `test -f 'omtTestError.c' || echo '$(srcdir)/'`omtTestError.c
+
+omtTest_m-omtTestError.obj: omtTestError.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(omtTest_m_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT omtTest_m-omtTestError.obj -MD -MP -MF $(DEPDIR)/omtTest_m-omtTestError.Tpo -c -o omtTest_m-omtTestError.obj `if test -f 'omtTestError.c'; then $(CYGPATH_W) 'omtTestError.c'; else $(CYGPATH_W) '$(srcdir)/omtTestError.c'; fi`
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/omtTest_m-omtTestError.Tpo $(DEPDIR)/omtTest_m-omtTestError.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='omtTestError.c' object='omtTest_m-omtTestError.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(omtTest_m_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o omtTest_m-omtTestError.obj `if test -f 'omtTestError.c'; then $(CYGPATH_W) 'omtTestError.c'; else $(CYGPATH_W) '$(srcdir)/omtTestError.c'; fi`
+
+omtTest_m-omtTest.o: omtTest.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(omtTest_m_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT omtTest_m-omtTest.o -MD -MP -MF $(DEPDIR)/omtTest_m-omtTest.Tpo -c -o omtTest_m-omtTest.o `test -f 'omtTest.c' || echo '$(srcdir)/'`omtTest.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/omtTest_m-omtTest.Tpo $(DEPDIR)/omtTest_m-omtTest.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='omtTest.c' object='omtTest_m-omtTest.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(omtTest_m_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o omtTest_m-omtTest.o `test -f 'omtTest.c' || echo '$(srcdir)/'`omtTest.c
+
+omtTest_m-omtTest.obj: omtTest.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(omtTest_m_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT omtTest_m-omtTest.obj -MD -MP -MF $(DEPDIR)/omtTest_m-omtTest.Tpo -c -o omtTest_m-omtTest.obj `if test -f 'omtTest.c'; then $(CYGPATH_W) 'omtTest.c'; else $(CYGPATH_W) '$(srcdir)/omtTest.c'; fi`
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/omtTest_m-omtTest.Tpo $(DEPDIR)/omtTest_m-omtTest.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='omtTest.c' object='omtTest_m-omtTest.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(omtTest_m_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o omtTest_m-omtTest.obj `if test -f 'omtTest.c'; then $(CYGPATH_W) 'omtTest.c'; else $(CYGPATH_W) '$(srcdir)/omtTest.c'; fi`
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+
+distclean-libtool:
+	-rm -f libtool config.lt
+install-pkgconfigDATA: $(pkgconfig_DATA)
+	@$(NORMAL_INSTALL)
+	@list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(pkgconfigdir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" || exit 1; \
+	fi; \
+	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|^.*/||'`; \
+	dir='$(DESTDIR)$(pkgconfigdir)'; $(am__uninstall_files_from_dir)
+install-libomalloc_includeHEADERS: $(libomalloc_include_HEADERS)
+	@$(NORMAL_INSTALL)
+	@list='$(libomalloc_include_HEADERS)'; test -n "$(libomalloc_includedir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(libomalloc_includedir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(libomalloc_includedir)" || exit 1; \
+	fi; \
+	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)$(libomalloc_includedir)'"; \
+	  $(INSTALL_HEADER) $$files "$(DESTDIR)$(libomalloc_includedir)" || exit $$?; \
+	done
+
+uninstall-libomalloc_includeHEADERS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(libomalloc_include_HEADERS)'; test -n "$(libomalloc_includedir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	dir='$(DESTDIR)$(libomalloc_includedir)'; $(am__uninstall_files_from_dir)
+install-nodist_libomalloc_includeHEADERS: $(nodist_libomalloc_include_HEADERS)
+	@$(NORMAL_INSTALL)
+	@list='$(nodist_libomalloc_include_HEADERS)'; test -n "$(libomalloc_includedir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(libomalloc_includedir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(libomalloc_includedir)" || exit 1; \
+	fi; \
+	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)$(libomalloc_includedir)'"; \
+	  $(INSTALL_HEADER) $$files "$(DESTDIR)$(libomalloc_includedir)" || exit $$?; \
+	done
+
+uninstall-nodist_libomalloc_includeHEADERS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(nodist_libomalloc_include_HEADERS)'; test -n "$(libomalloc_includedir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	dir='$(DESTDIR)$(libomalloc_includedir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	$(am__define_uniq_tagged_files); \
+	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-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	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"
+cscope: cscope.files
+	test ! -s cscope.files \
+	  || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS)
+clean-cscope:
+	-rm -f cscope.files
+cscope.files: clean-cscope cscopelist
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+	-rm -f cscope.out cscope.in.out cscope.po.out cscope.files
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'.  Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+	rm -f $< $@
+	$(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+	@:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+	@$(am__set_TESTS_bases); \
+	am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+	redo_bases=`for i in $$bases; do \
+	              am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+	            done`; \
+	if test -n "$$redo_bases"; then \
+	  redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+	  redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+	  if $(am__make_dryrun); then :; else \
+	    rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+	  fi; \
+	fi; \
+	if test -n "$$am__remaking_logs"; then \
+	  echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+	       "recursion detected" >&2; \
+	else \
+	  am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+	fi; \
+	if $(am__make_dryrun); then :; else \
+	  st=0;  \
+	  errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+	  for i in $$redo_bases; do \
+	    test -f $$i.trs && test -r $$i.trs \
+	      || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+	    test -f $$i.log && test -r $$i.log \
+	      || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+	  done; \
+	  test $$st -eq 0 || exit 1; \
+	fi
+	@$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+	ws='[ 	]'; \
+	results=`for b in $$bases; do echo $$b.trs; done`; \
+	test -n "$$results" || results=/dev/null; \
+	all=`  grep "^$$ws*:test-result:"           $$results | wc -l`; \
+	pass=` grep "^$$ws*:test-result:$$ws*PASS"  $$results | wc -l`; \
+	fail=` grep "^$$ws*:test-result:$$ws*FAIL"  $$results | wc -l`; \
+	skip=` grep "^$$ws*:test-result:$$ws*SKIP"  $$results | wc -l`; \
+	xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+	xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+	error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+	if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+	  success=true; \
+	else \
+	  success=false; \
+	fi; \
+	br='==================='; br=$$br$$br$$br$$br; \
+	result_count () \
+	{ \
+	    if test x"$$1" = x"--maybe-color"; then \
+	      maybe_colorize=yes; \
+	    elif test x"$$1" = x"--no-color"; then \
+	      maybe_colorize=no; \
+	    else \
+	      echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+	    fi; \
+	    shift; \
+	    desc=$$1 count=$$2; \
+	    if test $$maybe_colorize = yes && test $$count -gt 0; then \
+	      color_start=$$3 color_end=$$std; \
+	    else \
+	      color_start= color_end=; \
+	    fi; \
+	    echo "$${color_start}# $$desc $$count$${color_end}"; \
+	}; \
+	create_testsuite_report () \
+	{ \
+	  result_count $$1 "TOTAL:" $$all   "$$brg"; \
+	  result_count $$1 "PASS: " $$pass  "$$grn"; \
+	  result_count $$1 "SKIP: " $$skip  "$$blu"; \
+	  result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+	  result_count $$1 "FAIL: " $$fail  "$$red"; \
+	  result_count $$1 "XPASS:" $$xpass "$$red"; \
+	  result_count $$1 "ERROR:" $$error "$$mgn"; \
+	}; \
+	{								\
+	  echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" |	\
+	    $(am__rst_title);						\
+	  create_testsuite_report --no-color;				\
+	  echo;								\
+	  echo ".. contents:: :depth: 2";				\
+	  echo;								\
+	  for b in $$bases; do echo $$b; done				\
+	    | $(am__create_global_log);					\
+	} >$(TEST_SUITE_LOG).tmp || exit 1;				\
+	mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG);			\
+	if $$success; then						\
+	  col="$$grn";							\
+	 else								\
+	  col="$$red";							\
+	  test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG);		\
+	fi;								\
+	echo "$${col}$$br$${std}"; 					\
+	echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}";	\
+	echo "$${col}$$br$${std}"; 					\
+	create_testsuite_report --maybe-color;				\
+	echo "$$col$$br$$std";						\
+	if $$success; then :; else					\
+	  echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}";		\
+	  if test -n "$(PACKAGE_BUGREPORT)"; then			\
+	    echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}";	\
+	  fi;								\
+	  echo "$$col$$br$$std";					\
+	fi;								\
+	$$success || exit 1
+
+check-TESTS:
+	@list='$(RECHECK_LOGS)';           test -z "$$list" || rm -f $$list
+	@list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+	@test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+	@set +e; $(am__set_TESTS_bases); \
+	log_list=`for i in $$bases; do echo $$i.log; done`; \
+	trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+	log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+	$(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+	exit $$?;
+recheck: all $(check_PROGRAMS)
+	@test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+	@set +e; $(am__set_TESTS_bases); \
+	bases=`for i in $$bases; do echo $$i; done \
+	         | $(am__list_recheck_tests)` || exit 1; \
+	log_list=`for i in $$bases; do echo $$i.log; done`; \
+	log_list=`echo $$log_list`; \
+	$(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+	        am__force_recheck=am--force-recheck \
+	        TEST_LOGS="$$log_list"; \
+	exit $$?
+omtTest-m.log: omtTest-m$(EXEEXT)
+	@p='omtTest-m$(EXEEXT)'; \
+	b='omtTest-m'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+omtTest-r.log: omtTest-r$(EXEEXT)
+	@p='omtTest-r$(EXEEXT)'; \
+	b='omtTest-r'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+.test.log:
+	@p='$<'; \
+	$(am__set_b); \
+	$(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+ at am__EXEEXT_TRUE@.test$(EXEEXT).log:
+ at am__EXEEXT_TRUE@	@p='$<'; \
+ at am__EXEEXT_TRUE@	$(am__set_b); \
+ at am__EXEEXT_TRUE@	$(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ at am__EXEEXT_TRUE@	--log-file $$b.log --trs-file $$b.trs \
+ at am__EXEEXT_TRUE@	$(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ at am__EXEEXT_TRUE@	"$$tst" $(AM_TESTS_FD_REDIRECT)
+
+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
+	-test -n "$(am__skip_mode_fix)" \
+	|| find "$(distdir)" -type d ! -perm -755 \
+		-exec chmod u+rwx,go+rx {} \; -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__post_remove_distdir)
+
+dist-bzip2: distdir
+	tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2
+	$(am__post_remove_distdir)
+
+dist-lzip: distdir
+	tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz
+	$(am__post_remove_distdir)
+
+dist-xz: distdir
+	tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz
+	$(am__post_remove_distdir)
+
+dist-tarZ: distdir
+	tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
+	$(am__post_remove_distdir)
+
+dist-shar: distdir
+	shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
+	$(am__post_remove_distdir)
+
+dist-zip: distdir
+	-rm -f $(distdir).zip
+	zip -rq $(distdir).zip $(distdir)
+	$(am__post_remove_distdir)
+
+dist dist-all:
+	$(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:'
+	$(am__post_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) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\
+	*.tar.bz2*) \
+	  bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
+	*.tar.lz*) \
+	  lzip -dc $(distdir).tar.lz | $(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) gzip -dc $(distdir).shar.gz | unshar ;;\
+	*.zip*) \
+	  unzip $(distdir).zip ;;\
+	esac
+	chmod -R a-w $(distdir)
+	chmod u+w $(distdir)
+	mkdir $(distdir)/_build $(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" \
+	    $(AM_DISTCHECK_CONFIGURE_FLAGS) \
+	    $(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__post_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:
+	@test -n '$(distuninstallcheck_dir)' || { \
+	  echo 'ERROR: trying to run $@ with an empty' \
+	       '$$(distuninstallcheck_dir)' >&2; \
+	  exit 1; \
+	}; \
+	$(am__cd) '$(distuninstallcheck_dir)' || { \
+	  echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \
+	  exit 1; \
+	}; \
+	test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \
+	   || { 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
+	$(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS)
+	$(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: $(BUILT_SOURCES)
+	$(MAKE) $(AM_MAKEFLAGS) check-am
+all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(DATA) $(HEADERS) \
+		_config.h
+installdirs:
+	for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(libomalloc_includedir)" "$(DESTDIR)$(libomalloc_includedir)"; 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:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+	-test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+	-test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+	-test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+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)
+	-test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
+
+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-checkPROGRAMS clean-generic clean-libLTLIBRARIES \
+	clean-libtool clean-noinstPROGRAMS mostlyclean-am
+
+distclean: distclean-am
+	-rm -f $(am__CONFIG_DISTCLEAN_FILES)
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+	distclean-hdr distclean-libtool distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-libomalloc_includeHEADERS \
+	install-nodist_libomalloc_includeHEADERS install-pkgconfigDATA
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am: install-libLTLIBRARIES
+
+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 $(am__CONFIG_DISTCLEAN_FILES)
+	-rm -rf $(top_srcdir)/autom4te.cache
+	-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-libLTLIBRARIES \
+	uninstall-libomalloc_includeHEADERS \
+	uninstall-nodist_libomalloc_includeHEADERS \
+	uninstall-pkgconfigDATA
+
+.MAKE: all check check-am install install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am am--refresh check check-TESTS \
+	check-am clean clean-checkPROGRAMS clean-cscope clean-generic \
+	clean-libLTLIBRARIES clean-libtool clean-noinstPROGRAMS cscope \
+	cscopelist-am ctags ctags-am dist dist-all dist-bzip2 \
+	dist-gzip dist-lzip dist-shar dist-tarZ dist-xz dist-zip \
+	distcheck distclean distclean-compile 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-libLTLIBRARIES install-libomalloc_includeHEADERS \
+	install-man install-nodist_libomalloc_includeHEADERS \
+	install-pdf install-pdf-am install-pkgconfigDATA 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 recheck tags tags-am \
+	uninstall uninstall-am uninstall-libLTLIBRARIES \
+	uninstall-libomalloc_includeHEADERS \
+	uninstall-nodist_libomalloc_includeHEADERS \
+	uninstall-pkgconfigDATA
+
+
+omTables.inc: omTables$(EXEEXT) omalloc.h
+	./omTables$(EXEEXT) > omTables.xx && mv omTables.xx  $@
+
+omTables.h: omTables$(EXEEXT)
+	./omTables$(EXEEXT) 1 >omTables.yy && mv omTables.yy $@
+
+# 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/omalloc/NEWS b/omalloc/NEWS
new file mode 100644
index 0000000..e69de29
diff --git a/omalloc/README b/omalloc/README
new file mode 100644
index 0000000..e69de29
diff --git a/omalloc/_config.h.in b/omalloc/_config.h.in
new file mode 100644
index 0000000..ad04a74
--- /dev/null
+++ b/omalloc/_config.h.in
@@ -0,0 +1,203 @@
+/* _config.h.in.  Generated from configure.ac by autoheader.  */
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#undef HAVE_FCNTL_H
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the <limits.h> header file. */
+#undef HAVE_LIMITS_H
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the `mmap' function. */
+#undef HAVE_MMAP
+
+/* Define to 1 if you have the `popen' function. */
+#undef HAVE_POPEN
+
+/* Define to 1 if you have the `random' function. */
+#undef HAVE_RANDOM
+
+/* Define to 1 if you have the `sbrk' function. */
+#undef HAVE_SBRK
+
+/* 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/mman.h> header file. */
+#undef HAVE_SYS_MMAN_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
+
+/* "Whether we have a working mmap" */
+#undef HAVE_WORKING_MMAP
+
+/* Define to 1 if you have the </usr/include/malloc.h> header file. */
+#undef HAVE__USR_INCLUDE_MALLOC_H
+
+/* Define to the sub-directory in which libtool stores uninstalled libraries.
+   */
+#undef LT_OBJDIR
+
+/* Define to 1 if your C compiler doesn't accept -c and -o together. */
+#undef NO_MINUS_C_MINUS_O
+
+/* use external malloc as system allocator */
+#undef OMALLOC_USES_EXTERNAL_MALLOC
+
+/* the system allocator is called malloc */
+#undef OMALLOC_USES_MALLOC
+
+/* use system malloc as system allocator */
+#undef OMALLOC_USES_SYSTEM_MALLOC
+
+/* "Whether alignment needs work" */
+#undef OM_ALIGNMENT_NEEDS_WORK
+
+/* "Align to 8 bytes" */
+#undef OM_ALIGN_8
+
+/* "Whether omInitGetBackTrace () works" */
+#undef OM_GET_BACKTRACE_WORKS
+
+/* "Whether get return address works" */
+#undef OM_GET_RETURN_ADDR_WORKS
+
+/* "Whether we have dense bins" */
+#undef OM_HAVE_DENSE_BIN_DISTRIBUTION
+
+/* "Wether we have an external config.c" */
+#undef OM_HAVE_EXTERNAL_CONFIG_C
+
+/* "Whether we have external config.h" */
+#undef OM_HAVE_EXTERNAL_CONFIG_H
+
+/* "Whether we have the source for malloc ()" */
+#undef OM_HAVE_MALLOC_SOURCE
+
+/* "Have track" */
+#undef OM_HAVE_TRACK
+
+/* "Have valloc" */
+#undef OM_HAVE_VALLOC_MALLOC
+
+/* "Have valloc" */
+#undef OM_HAVE_VALLOC_MMAP
+
+/* "inline-declaration" */
+#undef OM_INLINE
+
+/* "inline-declaration" */
+#undef OM_INLINE_DECL
+
+/* "inline-declaration" */
+#undef OM_INLINE_IMPL
+
+/* "inline-declaration" */
+#undef OM_INLINE_LOCAL
+
+/* "Internal debug" */
+#undef OM_INTERNAL_DEBUG
+
+/* "Whether malloc provides SIZEOF_ADDR" */
+#undef OM_MALLOC_PROVIDES_SIZEOF_ADDR
+
+/* "Disable debug" */
+#undef OM_NDEBUG
+
+/* "Name of addr2line" */
+#undef OM_PROG_ADDR2LINE
+
+/* Provide NO standard routines! */
+#undef OM_PROVIDE_MALLOC
+
+/* "Whether to track backtrace" */
+#undef OM_TRACK_BACKTRACE
+
+/* "Enable custom tracking" */
+#undef OM_TRACK_CUSTOM
+
+/* "Whether to track file-line" */
+#undef OM_TRACK_FILE_LINE
+
+/* "Whether to track return" */
+#undef OM_TRACK_RETURN
+
+/* Name of package */
+#undef PACKAGE
+
+/* 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
+
+/* The size of `double', as computed by sizeof. */
+#undef SIZEOF_DOUBLE
+
+/* The size of `long', as computed by sizeof. */
+#undef SIZEOF_LONG
+
+/* Page-size of the build-system */
+#undef SIZEOF_OM_PAGE
+
+/* The size of `size_t', as computed by sizeof. */
+#undef SIZEOF_SIZE_T
+
+/* "Page-size of the build-system" */
+#undef SIZEOF_SYSTEM_PAGE
+
+/* The size of `void*', as computed by sizeof. */
+#undef SIZEOF_VOIDP
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Version number of package */
+#undef VERSION
+
+/* "Type of void" */
+#undef Void_t
+
+/* Define to empty if `const' does not conform to ANSI C. */
+#undef const
+
+/* Define to `__inline__' or `__inline' if that's what the C compiler
+   calls it, or to nothing if 'inline' is not supported under any name.  */
+#ifndef __cplusplus
+#undef inline
+#endif
diff --git a/omalloc/aclocal.m4 b/omalloc/aclocal.m4
new file mode 100644
index 0000000..4ab0e5d
--- /dev/null
+++ b/omalloc/aclocal.m4
@@ -0,0 +1,1173 @@
+# generated automatically by aclocal 1.13.4 -*- Autoconf -*-
+
+# Copyright (C) 1996-2013 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_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])
+m4_ifndef([AC_AUTOCONF_VERSION],
+  [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],,
+[m4_warning([this file was generated for autoconf 2.69.
+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'.])])
+
+# Copyright (C) 2002-2013 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.13'
+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.13.4], [],
+      [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.13.4])dnl
+m4_ifndef([AC_AUTOCONF_VERSION],
+  [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
+
+# Copyright (C) 2011-2013 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_AR([ACT-IF-FAIL])
+# -------------------------
+# Try to determine the archiver interface, and trigger the ar-lib wrapper
+# if it is needed.  If the detection of archiver interface fails, run
+# ACT-IF-FAIL (default is to abort configure with a proper error message).
+AC_DEFUN([AM_PROG_AR],
+[AC_BEFORE([$0], [LT_INIT])dnl
+AC_BEFORE([$0], [AC_PROG_LIBTOOL])dnl
+AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([ar-lib])dnl
+AC_CHECK_TOOLS([AR], [ar lib "link -lib"], [false])
+: ${AR=ar}
+
+AC_CACHE_CHECK([the archiver ($AR) interface], [am_cv_ar_interface],
+  [am_cv_ar_interface=ar
+   AC_COMPILE_IFELSE([AC_LANG_SOURCE([[int some_variable = 0;]])],
+     [am_ar_try='$AR cru libconftest.a conftest.$ac_objext >&AS_MESSAGE_LOG_FD'
+      AC_TRY_EVAL([am_ar_try])
+      if test "$ac_status" -eq 0; then
+        am_cv_ar_interface=ar
+      else
+        am_ar_try='$AR -NOLOGO -OUT:conftest.lib conftest.$ac_objext >&AS_MESSAGE_LOG_FD'
+        AC_TRY_EVAL([am_ar_try])
+        if test "$ac_status" -eq 0; then
+          am_cv_ar_interface=lib
+        else
+          am_cv_ar_interface=unknown
+        fi
+      fi
+      rm -f conftest.lib libconftest.a
+     ])
+   ])
+
+case $am_cv_ar_interface in
+ar)
+  ;;
+lib)
+  # Microsoft lib, so override with the ar-lib wrapper script.
+  # FIXME: It is wrong to rewrite AR.
+  # But if we don't then we get into trouble of one sort or another.
+  # A longer-term fix would be to have automake use am__AR in this case,
+  # and then we could set am__AR="$am_aux_dir/ar-lib \$(AR)" or something
+  # similar.
+  AR="$am_aux_dir/ar-lib $AR"
+  ;;
+unknown)
+  m4_default([$1],
+             [AC_MSG_ERROR([could not determine $AR interface])])
+  ;;
+esac
+AC_SUBST([AR])dnl
+])
+
+# AM_AUX_DIR_EXPAND                                         -*- Autoconf -*-
+
+# Copyright (C) 2001-2013 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-2013 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_CONDITIONAL(NAME, SHELL-CONDITION)
+# -------------------------------------
+# Define a conditional.
+AC_DEFUN([AM_CONDITIONAL],
+[AC_PREREQ([2.52])dnl
+ m4_if([$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-2013 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.
+
+
+# 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", "OBJC", "OBJCXX", "UPC", or "GJC".
+# 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
+
+m4_if([$1], [CC],   [depcc="$CC"   am_compiler_list=],
+      [$1], [CXX],  [depcc="$CXX"  am_compiler_list=],
+      [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
+      [$1], [OBJCXX], [depcc="$OBJCXX" 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".
+  rm -rf conftest.dir
+  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 10 /bin/sh.
+      echo '/* dummy */' > 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
+      ;;
+    msvc7 | msvc7msys | 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], [dnl
+AS_HELP_STRING(
+  [--enable-dependency-tracking],
+  [do not reject slow dependency extractors])
+AS_HELP_STRING(
+  [--disable-dependency-tracking],
+  [speeds up one-time build])])
+if test "x$enable_dependency_tracking" != xno; then
+  am_depcomp="$ac_aux_dir/depcomp"
+  AMDEPBACKSLASH='\'
+  am__nodep='_no'
+fi
+AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
+AC_SUBST([AMDEPBACKSLASH])dnl
+_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl
+AC_SUBST([am__nodep])dnl
+_AM_SUBST_NOTMAKE([am__nodep])dnl
+])
+
+# Generate code to set up dependency tracking.              -*- Autoconf -*-
+
+# Copyright (C) 1999-2013 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_OUTPUT_DEPENDENCY_COMMANDS
+# ------------------------------
+AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
+[{
+  # Older Autoconf 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"`
+    # 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'`; 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"])
+])
+
+# Do all the work for Automake.                             -*- Autoconf -*-
+
+# Copyright (C) 1996-2013 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 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.65])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],
+[AC_DIAGNOSE([obsolete],
+             [$0: two- and three-arguments forms are deprecated.])
+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], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]),
+  [ok:ok],,
+  [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([AC_PROG_MKDIR_P])dnl
+# For better backward compatibility.  To be removed once Automake 1.9.x
+# dies out for good.  For more background, see:
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
+AC_SUBST([mkdir_p], ['$(MKDIR_P)'])
+# 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])],
+		  [m4_define([AC_PROG_CC],
+			     m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_CXX],
+		  [_AM_DEPENDENCIES([CXX])],
+		  [m4_define([AC_PROG_CXX],
+			     m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_OBJC],
+		  [_AM_DEPENDENCIES([OBJC])],
+		  [m4_define([AC_PROG_OBJC],
+			     m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_OBJCXX],
+		  [_AM_DEPENDENCIES([OBJCXX])],
+		  [m4_define([AC_PROG_OBJCXX],
+			     m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl
+])
+AC_REQUIRE([AM_SILENT_RULES])dnl
+dnl The testsuite driver may need to know about EXEEXT, so add the
+dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen.  This
+dnl macro 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-2013 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-2013 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.
+
+# 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-2013 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_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 enable maintainer-specific portions of Makefiles])
+  dnl maintainer-mode's default is 'disable' unless 'enable' is passed
+  AC_ARG_ENABLE([maintainer-mode],
+    [AS_HELP_STRING([--]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
+]
+)
+
+# Check to see how 'make' treats includes.	            -*- Autoconf -*-
+
+# Copyright (C) 2001-2013 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_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
+])
+
+# Copyright (C) 1999-2013 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_CC_C_O
+# --------------
+# Like AC_PROG_CC_C_O, but changed for automake.
+AC_DEFUN([AM_PROG_CC_C_O],
+[AC_REQUIRE([AC_PROG_CC_C_O])dnl
+AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([compile])dnl
+# FIXME: we rely on the cache variable name because
+# there is no other way.
+set dummy $CC
+am_cc=`echo $[2] | sed ['s/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/']`
+eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o
+if test "$am_t" != yes; then
+   # Losing compiler, so override with the script.
+   # FIXME: It is wrong to rewrite CC.
+   # But if we don't then we get into trouble of one sort or another.
+   # A longer-term fix would be to have automake use am__CC in this case,
+   # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
+   CC="$am_aux_dir/compile $CC"
+fi
+dnl Make sure AC_PROG_CC is never called again, or it will override our
+dnl setting of CC.
+m4_define([AC_PROG_CC],
+          [m4_fatal([AC_PROG_CC cannot be called after AM_PROG_CC_C_O])])
+])
+
+# Fake the existence of programs that GNU maintainers use.  -*- Autoconf -*-
+
+# Copyright (C) 1997-2013 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_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 is modern enough.
+# If it is, 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 --is-lightweight"; then
+  am_missing_run="$MISSING "
+else
+  am_missing_run=
+  AC_MSG_WARN(['missing' script is too old or missing])
+fi
+])
+
+# Helper functions for option handling.                     -*- Autoconf -*-
+
+# Copyright (C) 2001-2013 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_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-2013 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_SANITY_CHECK
+# ---------------
+AC_DEFUN([AM_SANITY_CHECK],
+[AC_MSG_CHECKING([whether build environment is sane])
+# 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 (
+   am_has_slept=no
+   for am_try in 1 2; do
+     echo "timestamp, slept: $am_has_slept" > conftest.file
+     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
+     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
+     if test "$[2]" = conftest.file || test $am_try -eq 2; then
+       break
+     fi
+     # Just in case.
+     sleep 1
+     am_has_slept=yes
+   done
+   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])
+# If we didn't sleep, we still need to ensure time stamps of config.status and
+# generated files are strictly newer.
+am_sleep_pid=
+if grep 'slept: no' conftest.file >/dev/null 2>&1; then
+  ( sleep 1 ) &
+  am_sleep_pid=$!
+fi
+AC_CONFIG_COMMANDS_PRE(
+  [AC_MSG_CHECKING([that generated files are newer than configure])
+   if test -n "$am_sleep_pid"; then
+     # Hide warnings about reused PIDs.
+     wait $am_sleep_pid 2>/dev/null
+   fi
+   AC_MSG_RESULT([done])])
+rm -f conftest.file
+])
+
+# Copyright (C) 2009-2013 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_SILENT_RULES([DEFAULT])
+# --------------------------
+# Enable less verbose build rules; with the default set to DEFAULT
+# ("yes" being less verbose, "no" or empty being verbose).
+AC_DEFUN([AM_SILENT_RULES],
+[AC_ARG_ENABLE([silent-rules], [dnl
+AS_HELP_STRING(
+  [--enable-silent-rules],
+  [less verbose build output (undo: "make V=1")])
+AS_HELP_STRING(
+  [--disable-silent-rules],
+  [verbose build output (undo: "make V=0")])dnl
+])
+case $enable_silent_rules in @%:@ (((
+  yes) AM_DEFAULT_VERBOSITY=0;;
+   no) AM_DEFAULT_VERBOSITY=1;;
+    *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);;
+esac
+dnl
+dnl A few 'make' implementations (e.g., NonStop OS and NextStep)
+dnl do not support nested variable expansions.
+dnl See automake bug#9928 and bug#10237.
+am_make=${MAKE-make}
+AC_CACHE_CHECK([whether $am_make supports nested variables],
+   [am_cv_make_support_nested_variables],
+   [if AS_ECHO([['TRUE=$(BAR$(V))
+BAR0=false
+BAR1=true
+V=1
+am__doit:
+	@$(TRUE)
+.PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then
+  am_cv_make_support_nested_variables=yes
+else
+  am_cv_make_support_nested_variables=no
+fi])
+if test $am_cv_make_support_nested_variables = yes; then
+  dnl Using '$V' instead of '$(V)' breaks IRIX make.
+  AM_V='$(V)'
+  AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
+else
+  AM_V=$AM_DEFAULT_VERBOSITY
+  AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY
+fi
+AC_SUBST([AM_V])dnl
+AM_SUBST_NOTMAKE([AM_V])dnl
+AC_SUBST([AM_DEFAULT_V])dnl
+AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl
+AC_SUBST([AM_DEFAULT_VERBOSITY])dnl
+AM_BACKSLASH='\'
+AC_SUBST([AM_BACKSLASH])dnl
+_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl
+])
+
+# Copyright (C) 2001-2013 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-2013 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_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-2013 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_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.  Yes, it's still used
+# in the wild :-(  We should find a proper way to deprecate it ...
+AC_SUBST([AMTAR], ['$${TAR-tar}'])
+
+# We'll loop over all known methods to create a tar archive until one works.
+_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
+
+m4_if([$1], [v7],
+  [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'],
+
+  [m4_case([$1],
+    [ustar],
+     [# The POSIX 1988 'ustar' format is defined with fixed-size fields.
+      # There is notably a 21 bits limit for the UID and the GID.  In fact,
+      # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343
+      # and bug#13588).
+      am_max_uid=2097151 # 2^21 - 1
+      am_max_gid=$am_max_uid
+      # The $UID and $GID variables are not portable, so we need to resort
+      # to the POSIX-mandated id(1) utility.  Errors in the 'id' calls
+      # below are definitely unexpected, so allow the users to see them
+      # (that is, avoid stderr redirection).
+      am_uid=`id -u || echo unknown`
+      am_gid=`id -g || echo unknown`
+      AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format])
+      if test $am_uid -le $am_max_uid; then
+         AC_MSG_RESULT([yes])
+      else
+         AC_MSG_RESULT([no])
+         _am_tools=none
+      fi
+      AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format])
+      if test $am_gid -le $am_max_gid; then
+         AC_MSG_RESULT([yes])
+      else
+        AC_MSG_RESULT([no])
+        _am_tools=none
+      fi],
+
+  [pax],
+    [],
+
+  [m4_fatal([Unknown tar format])])
+
+  AC_MSG_CHECKING([how to create a $1 tar archive])
+
+  # Go ahead even if we have the value already cached.  We do so because we
+  # need to set the values for the 'am__tar' and 'am__untar' variables.
+  _am_tools=${am_cv_prog_tar_$1-$_am_tools}
+
+  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])
+      AM_RUN_LOG([cat conftest.dir/file])
+      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([../m4/ax_prefix_config_h.m4])
+m4_include([../m4/flags.m4])
+m4_include([../m4/libtool.m4])
+m4_include([../m4/ltoptions.m4])
+m4_include([../m4/ltsugar.m4])
+m4_include([../m4/ltversion.m4])
+m4_include([../m4/lt~obsolete.m4])
diff --git a/omalloc/configure b/omalloc/configure
new file mode 100755
index 0000000..8633f3c
--- /dev/null
+++ b/omalloc/configure
@@ -0,0 +1,16582 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.69 for omalloc 0.9.6.
+#
+#
+# Copyright (C) 1992-1996, 1998-2012 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.
+as_myself=
+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
+
+# Use a proper internal environment variable to ensure we don't fall
+  # into an infinite loop, continuously re-executing ourselves.
+  if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then
+    _as_can_reexec=no; export _as_can_reexec;
+    # 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.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+  *v*x* | *x*v* ) as_opts=-vx ;;
+  *v* ) as_opts=-v ;;
+  *x* ) as_opts=-x ;;
+  * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+as_fn_exit 255
+  fi
+  # We don't want this to propagate to other subprocesses.
+          { _as_can_reexec=; unset _as_can_reexec;}
+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
+test -x / || 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 -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || (
+    ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+    ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO
+    ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO
+    PATH=/empty FPATH=/empty; export PATH FPATH
+    test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\
+      || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || 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 :
+  export CONFIG_SHELL
+             # 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.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+  *v*x* | *x*v* ) as_opts=-vx ;;
+  *v* ) as_opts=-v ;;
+  *x* ) as_opts=-x ;;
+  * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+exit 255
+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_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+  test -f "$1" && test -x "$1"
+} # as_fn_executable_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 STATUS 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=$1; test $as_status -eq 0 && as_status=1
+  if test "$4"; then
+    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+  fi
+  $as_echo "$as_me: error: $2" >&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; }
+
+  # If we had to re-execute with $CONFIG_SHELL, we're ensured to have
+  # already done that, so ensure we don't try to do so again and fall
+  # in an infinite loop.  This has already happened in practice.
+  _as_can_reexec=no; export _as_can_reexec
+  # 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 -pR'.
+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+      as_ln_s='cp -pR'
+  elif ln conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s=ln
+  else
+    as_ln_s='cp -pR'
+  fi
+else
+  as_ln_s='cp -pR'
+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
+
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
+
+# 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'"
+
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+
+test -n "$DJDIR" || exec 7<&0 </dev/null
+exec 6>&1
+
+# Name of the host.
+# hostname on some systems (SVR3.2, old GNU/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='omalloc'
+PACKAGE_TARNAME='omalloc'
+PACKAGE_VERSION='0.9.6'
+PACKAGE_STRING='omalloc 0.9.6'
+PACKAGE_BUGREPORT=''
+PACKAGE_URL=''
+
+ac_unique_file="om_Alloc.c"
+# 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
+WANT_DEBUG_FALSE
+WANT_DEBUG_TRUE
+OM_MALLOC_SOURCE
+OM_MALLOC_HEADER
+EXTERNAL_CONFIG_SOURCE
+EXTERNAL_CONFIG_HEADER
+ADDR2LINE
+PERL
+OTOOL64
+OTOOL
+LIPO
+NMEDIT
+DSYMUTIL
+MANIFEST_TOOL
+RANLIB
+DLLTOOL
+OBJDUMP
+NM
+ac_ct_DUMPBIN
+DUMPBIN
+LD
+FGREP
+EGREP
+GREP
+SED
+host_os
+host_vendor
+host_cpu
+host
+build_os
+build_vendor
+build_cpu
+build
+LIBTOOL
+LN_S
+CPP
+am__fastdepCC_FALSE
+am__fastdepCC_TRUE
+CCDEPMODE
+am__nodep
+AMDEPBACKSLASH
+AMDEP_FALSE
+AMDEP_TRUE
+am__quote
+am__include
+DEPDIR
+OBJEXT
+EXEEXT
+ac_ct_CC
+CPPFLAGS
+LDFLAGS
+CFLAGS
+CC
+ac_ct_AR
+AR
+AM_BACKSLASH
+AM_DEFAULT_VERBOSITY
+AM_DEFAULT_V
+AM_V
+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
+MAINT
+MAINTAINER_MODE_FALSE
+MAINTAINER_MODE_TRUE
+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
+enable_silent_rules
+enable_dependency_tracking
+with_external_config_h
+with_external_config_c
+with_malloc
+with_external_malloc_h
+with_external_malloc_c
+with_valloc
+with_align
+with_dense_bins
+with_inline
+with_debug
+with_track
+with_track_fl
+with_track_return
+with_track_backtrace
+with_track_custom
+with_internal_debug
+enable_shared
+enable_static
+with_pic
+enable_fast_install
+with_gnu_ld
+with_sysroot
+enable_libtool_lock
+'
+      ac_precious_vars='build_alias
+host_alias
+target_alias
+CC
+CFLAGS
+LDFLAGS
+LIBS
+CPPFLAGS
+CPP'
+
+
+# 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_TARNAME}'
+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= ;;
+  *)    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
+  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 omalloc 0.9.6 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/omalloc]
+  --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
+  case $ac_init_help in
+     short | recursive ) echo "Configuration of omalloc 0.9.6:";;
+   esac
+  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]
+  --disable-maintainer-mode
+                          disable make rules and dependencies not useful (and
+                          sometimes confusing) to the casual installer
+  --enable-silent-rules   less verbose build output (undo: "make V=1")
+  --disable-silent-rules  verbose build output (undo: "make V=0")
+  --enable-dependency-tracking
+                          do not reject slow dependency extractors
+  --disable-dependency-tracking
+                          speeds up one-time build
+  --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)
+
+Optional Packages:
+  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
+  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
+ --with-external-config_h=HEADER_FILE
+                    use HEADER_FILE for external configuration
+ --with-external-config_c=C_FILE
+                    use C_FILE for external implementations
+ --with-malloc=system|external
+                    which malloc to use, default: malloc
+ --with-external-malloc-h=HEADER_FILE
+		    use HEADER_FILE for external malloc declaration
+ --with-external-malloc-c=C_FILE
+		    use C_FILE for external malloc implementation
+ --with-valloc=mmap|system|emulate
+                    how to get page-aligned memory, default: use first possible
+ --with-align=8|sloppy|strict
+                    how memory is aligned,
+                    default: if possible sloppy, else strict
+ --with-dense-bins  use dense bin distribution
+ --without-inline   do not inline
+ --without-debug    disable all debugging facilities
+ --without-track    disable debug tracking functionality
+ --with-track-fl    track file and line numbers
+ --with-track-return track return addresses
+ --with-track-backtrace track stack backtraces
+ --with-track-custom track custom values
+ --with-internal-debug
+                       turn on internal debugging
+  --with-pic[=PKGS]       try to use only PIC/non-PIC objects [default=use
+                          both]
+  --with-gnu-ld           assume the C compiler uses GNU ld [default=no]
+  --with-sysroot=DIR Search for dependent libraries within DIR
+                        (or the compiler's sysroot if not specified).
+
+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    (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
+              you have headers in a nonstandard directory <include dir>
+  CPP         C preprocessor
+
+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
+omalloc configure 0.9.6
+generated by GNU Autoconf 2.69
+
+Copyright (C) 2012 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; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_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; } > conftest.i && {
+	 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; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_cpp
+
+# 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 ||
+	 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; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $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 eval \${$3+:} false; 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; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_header_compile
+
+# 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; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $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 eval \${$3+:} false; 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; ${as_lineno_stack:+:} 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 eval \${$3+:} false; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; 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.i 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 eval \${$3+:} false; 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; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_header_mongrel
+
+# ac_fn_c_compute_int LINENO EXPR VAR INCLUDES
+# --------------------------------------------
+# Tries to find the compile-time value of EXPR in a program that includes
+# INCLUDES, setting VAR accordingly. Returns whether the value could be
+# computed
+ac_fn_c_compute_int ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if test "$cross_compiling" = yes; then
+    # Depending upon the size, compute the lo and hi bounds.
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) >= 0)];
+test_array [0] = 0;
+return test_array [0];
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_lo=0 ac_mid=0
+  while :; do
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) <= $ac_mid)];
+test_array [0] = 0;
+return test_array [0];
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_hi=$ac_mid; break
+else
+  as_fn_arith $ac_mid + 1 && ac_lo=$as_val
+			if test $ac_lo -le $ac_mid; then
+			  ac_lo= ac_hi=
+			  break
+			fi
+			as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) < 0)];
+test_array [0] = 0;
+return test_array [0];
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_hi=-1 ac_mid=-1
+  while :; do
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) >= $ac_mid)];
+test_array [0] = 0;
+return test_array [0];
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_lo=$ac_mid; break
+else
+  as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val
+			if test $ac_mid -le $ac_hi; then
+			  ac_lo= ac_hi=
+			  break
+			fi
+			as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
+else
+  ac_lo= ac_hi=
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+# Binary search between lo and hi bounds.
+while test "x$ac_lo" != "x$ac_hi"; do
+  as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) <= $ac_mid)];
+test_array [0] = 0;
+return test_array [0];
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_hi=$ac_mid
+else
+  as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+case $ac_lo in #((
+?*) eval "$3=\$ac_lo"; ac_retval=0 ;;
+'') ac_retval=1 ;;
+esac
+  else
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+static long int longval () { return $2; }
+static unsigned long int ulongval () { return $2; }
+#include <stdio.h>
+#include <stdlib.h>
+int
+main ()
+{
+
+  FILE *f = fopen ("conftest.val", "w");
+  if (! f)
+    return 1;
+  if (($2) < 0)
+    {
+      long int i = longval ();
+      if (i != ($2))
+	return 1;
+      fprintf (f, "%ld", i);
+    }
+  else
+    {
+      unsigned long int i = ulongval ();
+      if (i != ($2))
+	return 1;
+      fprintf (f, "%lu", i);
+    }
+  /* Do not output a trailing newline, as this causes \r\n confusion
+     on some platforms.  */
+  return ferror (f) || fclose (f) != 0;
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  echo >>conftest.val; read $3 <conftest.val; ac_retval=0
+else
+  ac_retval=1
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+rm -f conftest.val
+
+  fi
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_compute_int
+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 omalloc $as_me 0.9.6, which was
+generated by GNU Autoconf 2.69.  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
+
+    $as_echo "## ---------------- ##
+## Cache variables. ##
+## ---------------- ##"
+    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
+
+    $as_echo "## ----------------- ##
+## Output variables. ##
+## ----------------- ##"
+    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
+      $as_echo "## ------------------- ##
+## File substitutions. ##
+## ------------------- ##"
+      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
+      $as_echo "## ----------- ##
+## confdefs.h. ##
+## ----------- ##"
+      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
+  # We do not want a PATH search for config.site.
+  case $CONFIG_SITE in #((
+    -*)  ac_site_file1=./$CONFIG_SITE;;
+    */*) ac_site_file1=$CONFIG_SITE;;
+    *)   ac_site_file1=./$CONFIG_SITE;;
+  esac
+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 /dev/null != "$ac_site_file" && 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" \
+      || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "failed to load site script $ac_site_file
+See \`config.log' for more details" "$LINENO" 5; }
+  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.  DJGPP emulates it as a regular file.
+  if test /dev/null != "$cache_file" && 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_aux_dir=
+for ac_dir in ../build-aux "$srcdir"/../build-aux; do
+  if test -f "$ac_dir/install-sh"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install-sh -c"
+    break
+  elif test -f "$ac_dir/install.sh"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install.sh -c"
+    break
+  elif test -f "$ac_dir/shtool"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/shtool install -c"
+    break
+  fi
+done
+if test -z "$ac_aux_dir"; then
+  as_fn_error $? "cannot find install-sh, install.sh, or shtool in ../build-aux \"$srcdir\"/../build-aux" "$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.
+
+
+
+ac_config_headers="$ac_config_headers _config.h"
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Please note that we set empty defaults for \`CFLAGS' and \`CXXFLAGS' (instead of \`-g -O')" >&5
+$as_echo "$as_me: WARNING: Please note that we set empty defaults for \`CFLAGS' and \`CXXFLAGS' (instead of \`-g -O')" >&2;}
+ : ${CFLAGS:=""}
+ : ${CXXFLAGS:=""}
+
+
+
+{ $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=yes
+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
+
+
+am__api_version='1.13'
+
+# 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 ${ac_cv_path_install+:} false; 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 as_fn_executable_p "$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; }
+# 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 (
+   am_has_slept=no
+   for am_try in 1 2; do
+     echo "timestamp, slept: $am_has_slept" > conftest.file
+     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
+     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
+     if test "$2" = conftest.file || test $am_try -eq 2; then
+       break
+     fi
+     # Just in case.
+     sleep 1
+     am_has_slept=yes
+   done
+   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; }
+# If we didn't sleep, we still need to ensure time stamps of config.status and
+# generated files are strictly newer.
+am_sleep_pid=
+if grep 'slept: no' conftest.file >/dev/null 2>&1; then
+  ( sleep 1 ) &
+  am_sleep_pid=$!
+fi
+
+rm -f conftest.file
+
+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 --is-lightweight"; then
+  am_missing_run="$MISSING "
+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 ${ac_cv_prog_STRIP+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_STRIP+:} false; 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 as_fn_executable_p "$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 ${ac_cv_path_mkdir+:} false; 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
+	   as_fn_executable_p "$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
+
+  test -d ./--version && rmdir ./--version
+  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.
+    MKDIR_P="$ac_install_sh -d"
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5
+$as_echo "$MKDIR_P" >&6; }
+
+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 ${ac_cv_prog_AWK+:} false; 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 as_fn_executable_p "$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 eval \${ac_cv_prog_make_${ac_make}_set+:} false; 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
+
+# Check whether --enable-silent-rules was given.
+if test "${enable_silent_rules+set}" = set; then :
+  enableval=$enable_silent_rules;
+fi
+
+case $enable_silent_rules in # (((
+  yes) AM_DEFAULT_VERBOSITY=0;;
+   no) AM_DEFAULT_VERBOSITY=1;;
+    *) AM_DEFAULT_VERBOSITY=1;;
+esac
+am_make=${MAKE-make}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5
+$as_echo_n "checking whether $am_make supports nested variables... " >&6; }
+if ${am_cv_make_support_nested_variables+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if $as_echo 'TRUE=$(BAR$(V))
+BAR0=false
+BAR1=true
+V=1
+am__doit:
+	@$(TRUE)
+.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then
+  am_cv_make_support_nested_variables=yes
+else
+  am_cv_make_support_nested_variables=no
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5
+$as_echo "$am_cv_make_support_nested_variables" >&6; }
+if test $am_cv_make_support_nested_variables = yes; then
+    AM_V='$(V)'
+  AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
+else
+  AM_V=$AM_DEFAULT_VERBOSITY
+  AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY
+fi
+AM_BACKSLASH='\'
+
+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='omalloc'
+ VERSION='0.9.6'
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE "$PACKAGE"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define VERSION "$VERSION"
+_ACEOF
+
+# 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"}
+
+# For better backward compatibility.  To be removed once Automake 1.9.x
+# dies out for good.  For more background, see:
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
+mkdir_p='$(MKDIR_P)'
+
+# We need awk for the "check" target.  The system "awk" is bad on
+# some platforms.
+# Always define AMTAR for backward compatibility.  Yes, it's still used
+# in the wild :-(  We should find a proper way to deprecate it ...
+AMTAR='$${TAR-tar}'
+
+
+# We'll loop over all known methods to create a tar archive until one works.
+_am_tools='gnutar  pax cpio none'
+
+am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'
+
+
+
+
+
+ # -Wno-extra-portability -Werror silent-rules
+# Check whether --enable-silent-rules was given.
+if test "${enable_silent_rules+set}" = set; then :
+  enableval=$enable_silent_rules;
+fi
+
+case $enable_silent_rules in # (((
+  yes) AM_DEFAULT_VERBOSITY=0;;
+   no) AM_DEFAULT_VERBOSITY=1;;
+    *) AM_DEFAULT_VERBOSITY=0;;
+esac
+am_make=${MAKE-make}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5
+$as_echo_n "checking whether $am_make supports nested variables... " >&6; }
+if ${am_cv_make_support_nested_variables+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if $as_echo 'TRUE=$(BAR$(V))
+BAR0=false
+BAR1=true
+V=1
+am__doit:
+	@$(TRUE)
+.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then
+  am_cv_make_support_nested_variables=yes
+else
+  am_cv_make_support_nested_variables=no
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5
+$as_echo "$am_cv_make_support_nested_variables" >&6; }
+if test $am_cv_make_support_nested_variables = yes; then
+    AM_V='$(V)'
+  AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
+else
+  AM_V=$AM_DEFAULT_VERBOSITY
+  AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY
+fi
+AM_BACKSLASH='\'
+
+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='\'
+  am__nodep='_no'
+fi
+ if test "x$enable_dependency_tracking" != xno; then
+  AMDEP_TRUE=
+  AMDEP_FALSE='#'
+else
+  AMDEP_TRUE='#'
+  AMDEP_FALSE=
+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 ${ac_cv_prog_CC+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_CC+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_CC+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_CC+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_CC+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_CC+:} false; 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 as_fn_executable_p "$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
+  fi
+  rm -f conftest.er1 conftest.err
+  $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.  */
+
+int
+main ()
+{
+
+  ;
+  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"
+# 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 whether the C compiler works" >&5
+$as_echo_n "checking whether the C compiler works... " >&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
+if test -z "$ac_file"; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+$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 77 "C compiler cannot create executables
+See \`config.log' for more details" "$LINENO" 5; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+fi
+{ $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; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
+$as_echo "$ac_file" >&6; }
+ac_exeext=$ac_cv_exeext
+
+rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+{ $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 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
+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="$ac_clean_files conftest.out"
+# 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; }
+if test "$cross_compiling" != yes; then
+  { { 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; }
+  if { ac_try='./conftest$ac_cv_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
+    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: $cross_compiling" >&5
+$as_echo "$cross_compiling" >&6; }
+
+rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out
+ac_clean_files=$ac_clean_files_save
+{ $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 ${ac_cv_objext+:} false; 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 ${ac_cv_c_compiler_gnu+:} false; 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 ${ac_cv_prog_cc_g+:} false; 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 ${ac_cv_prog_cc_c89+:} false; 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>
+struct stat;
+/* 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
+
+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 ${am_cv_CC_dependencies_compiler_type+:} false; 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".
+  rm -rf conftest.dir
+  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 10 /bin/sh.
+      echo '/* dummy */' > 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
+      ;;
+    msvc7 | msvc7msys | 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 -n "$ac_tool_prefix"; then
+  for ac_prog in ar lib "link -lib"
+  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 ${ac_cv_prog_AR+:} false; 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_AR="$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
+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
+
+
+    test -n "$AR" && break
+  done
+fi
+if test -z "$AR"; then
+  ac_ct_AR=$AR
+  for ac_prog in ar lib "link -lib"
+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 ${ac_cv_prog_ac_ct_AR+:} false; 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_AR="$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_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
+
+
+  test -n "$ac_ct_AR" && break
+done
+
+  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
+fi
+
+: ${AR=ar}
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the archiver ($AR) interface" >&5
+$as_echo_n "checking the archiver ($AR) interface... " >&6; }
+if ${am_cv_ar_interface+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  am_cv_ar_interface=ar
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+int some_variable = 0;
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  am_ar_try='$AR cru libconftest.a conftest.$ac_objext >&5'
+      { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$am_ar_try\""; } >&5
+  (eval $am_ar_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      if test "$ac_status" -eq 0; then
+        am_cv_ar_interface=ar
+      else
+        am_ar_try='$AR -NOLOGO -OUT:conftest.lib conftest.$ac_objext >&5'
+        { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$am_ar_try\""; } >&5
+  (eval $am_ar_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+        if test "$ac_status" -eq 0; then
+          am_cv_ar_interface=lib
+        else
+          am_cv_ar_interface=unknown
+        fi
+      fi
+      rm -f conftest.lib libconftest.a
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_ar_interface" >&5
+$as_echo "$am_cv_ar_interface" >&6; }
+
+case $am_cv_ar_interface in
+ar)
+  ;;
+lib)
+  # Microsoft lib, so override with the ar-lib wrapper script.
+  # FIXME: It is wrong to rewrite AR.
+  # But if we don't then we get into trouble of one sort or another.
+  # A longer-term fix would be to have automake use am__AR in this case,
+  # and then we could set am__AR="$am_aux_dir/ar-lib \$(AR)" or something
+  # similar.
+  AR="$am_aux_dir/ar-lib $AR"
+  ;;
+unknown)
+  as_fn_error $? "could not determine $AR interface" "$LINENO" 5
+  ;;
+esac
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5
+$as_echo_n "checking whether build environment is sane... " >&6; }
+# 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 (
+   am_has_slept=no
+   for am_try in 1 2; do
+     echo "timestamp, slept: $am_has_slept" > conftest.file
+     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
+     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
+     if test "$2" = conftest.file || test $am_try -eq 2; then
+       break
+     fi
+     # Just in case.
+     sleep 1
+     am_has_slept=yes
+   done
+   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; }
+# If we didn't sleep, we still need to ensure time stamps of config.status and
+# generated files are strictly newer.
+am_sleep_pid=
+if grep 'slept: no' conftest.file >/dev/null 2>&1; then
+  ( sleep 1 ) &
+  am_sleep_pid=$!
+fi
+
+rm -f conftest.file
+
+
+# Add pre'prefixed config
+
+ac_config_commands="$ac_config_commands omConfig.h"
+
+
+# SING_CHECK_SET_ARGS()
+
+
+
+
+
+# Check whether --with-external-config_h was given.
+if test "${with_external_config_h+set}" = set; then :
+  withval=$with_external_config_h;
+fi
+
+
+# Check whether --with-external-config_c was given.
+if test "${with_external_config_c+set}" = set; then :
+  withval=$with_external_config_c;
+fi
+
+
+# Check whether --with-malloc was given.
+if test "${with_malloc+set}" = set; then :
+  withval=$with_malloc;
+fi
+
+
+# Check whether --with-external-malloc_h was given.
+if test "${with_external_malloc_h+set}" = set; then :
+  withval=$with_external_malloc_h;
+fi
+
+
+# Check whether --with-external-malloc_c was given.
+if test "${with_external_malloc_c+set}" = set; then :
+  withval=$with_external_malloc_c;
+fi
+
+
+# Check whether --with-valloc was given.
+if test "${with_valloc+set}" = set; then :
+  withval=$with_valloc;
+fi
+
+
+# Check whether --with-align was given.
+if test "${with_align+set}" = set; then :
+  withval=$with_align;
+fi
+
+
+# Check whether --with-dense-bins was given.
+if test "${with_dense_bins+set}" = set; then :
+  withval=$with_dense_bins;
+fi
+
+
+# Check whether --with-inline was given.
+if test "${with_inline+set}" = set; then :
+  withval=$with_inline;
+fi
+
+
+# Check whether --with-debug was given.
+if test "${with_debug+set}" = set; then :
+  withval=$with_debug;
+fi
+
+
+# Check whether --with-track was given.
+if test "${with_track+set}" = set; then :
+  withval=$with_track;
+fi
+
+
+# Check whether --with-track-fl was given.
+if test "${with_track_fl+set}" = set; then :
+  withval=$with_track_fl;
+fi
+
+
+# Check whether --with-track-return was given.
+if test "${with_track_return+set}" = set; then :
+  withval=$with_track_return;
+fi
+
+
+# Check whether --with-track-backtrace was given.
+if test "${with_track_backtrace+set}" = set; then :
+  withval=$with_track_backtrace;
+fi
+
+
+# Check whether --with-track-custom was given.
+if test "${with_track_custom+set}" = set; then :
+  withval=$with_track_custom;
+fi
+
+
+# Check whether --with-internal_debug was given.
+if test "${with_internal_debug+set}" = set; then :
+  withval=$with_internal_debug;
+fi
+
+
+CPPFLAGS="-I.. -I."
+{ $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 eval \${ac_cv_prog_make_${ac_make}_set+:} false; 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
+
+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 ${ac_cv_prog_CC+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_CC+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_CC+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_CC+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_CC+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_CC+:} false; 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 as_fn_executable_p "$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
+  fi
+  rm -f conftest.er1 conftest.err
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+done
+
+{ $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 ${ac_cv_c_compiler_gnu+:} false; 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 ${ac_cv_prog_cc_g+:} false; 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 ${ac_cv_prog_cc_c89+:} false; 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>
+struct stat;
+/* 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
+
+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 ${am_cv_CC_dependencies_compiler_type+:} false; 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".
+  rm -rf conftest.dir
+  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 10 /bin/sh.
+      echo '/* dummy */' > 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
+      ;;
+    msvc7 | msvc7msys | 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
+
+
+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 ${ac_cv_prog_CPP+:} false; 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.i 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.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i 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.i 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.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i 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 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
+
+
+if test "x$CC" != xcc; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC and cc understand -c and -o together" >&5
+$as_echo_n "checking whether $CC and cc understand -c and -o together... " >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether cc understands -c and -o together" >&5
+$as_echo_n "checking whether cc understands -c and -o together... " >&6; }
+fi
+set dummy $CC; ac_cc=`$as_echo "$2" |
+		      sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'`
+if eval \${ac_cv_prog_cc_${ac_cc}_c_o+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+# Make sure it works both with $CC and with simple cc.
+# We do the test twice because some compilers refuse to overwrite an
+# existing .o file with -o, though they will create one.
+ac_try='$CC -c conftest.$ac_ext -o conftest2.$ac_objext >&5'
+rm -f conftest2.*
+if { { 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; } &&
+   test -f conftest2.$ac_objext && { { 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
+  eval ac_cv_prog_cc_${ac_cc}_c_o=yes
+  if test "x$CC" != xcc; then
+    # Test first that cc exists at all.
+    if { ac_try='cc -c conftest.$ac_ext >&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_try") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then
+      ac_try='cc -c conftest.$ac_ext -o conftest2.$ac_objext >&5'
+      rm -f conftest2.*
+      if { { 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; } &&
+	 test -f conftest2.$ac_objext && { { 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
+	# cc works too.
+	:
+      else
+	# cc exists but doesn't like -o.
+	eval ac_cv_prog_cc_${ac_cc}_c_o=no
+      fi
+    fi
+  fi
+else
+  eval ac_cv_prog_cc_${ac_cc}_c_o=no
+fi
+rm -f core conftest*
+
+fi
+if eval test \$ac_cv_prog_cc_${ac_cc}_c_o = yes; 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; }
+
+$as_echo "#define NO_MINUS_C_MINUS_O 1" >>confdefs.h
+
+fi
+
+# FIXME: we rely on the cache variable name because
+# there is no other way.
+set dummy $CC
+am_cc=`echo $2 | sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'`
+eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o
+if test "$am_t" != yes; then
+   # Losing compiler, so override with the script.
+   # FIXME: It is wrong to rewrite CC.
+   # But if we don't then we get into trouble of one sort or another.
+   # A longer-term fix would be to have automake use am__CC in this case,
+   # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
+   CC="$am_aux_dir/compile $CC"
+fi
+
+
+# AM_PROG_AR
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5
+$as_echo_n "checking for an ANSI C-conforming const... " >&6; }
+if ${ac_cv_c_const+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+#ifndef __cplusplus
+  /* Ultrix mips cc rejects this sort of thing.  */
+  typedef int charset[2];
+  const charset cs = { 0, 0 };
+  /* SunOS 4.1.1 cc rejects this.  */
+  char const *const *pcpcc;
+  char **ppc;
+  /* NEC SVR4.0.2 mips cc rejects this.  */
+  struct point {int x, y;};
+  static struct point const zero = {0,0};
+  /* AIX XL C 1.02.0.0 rejects this.
+     It does not let you subtract one const X* pointer from another in
+     an arm of an if-expression whose if-part is not a constant
+     expression */
+  const char *g = "string";
+  pcpcc = &g + (g ? g-g : 0);
+  /* HPUX 7.0 cc rejects these. */
+  ++pcpcc;
+  ppc = (char**) pcpcc;
+  pcpcc = (char const *const *) ppc;
+  { /* SCO 3.2v4 cc rejects this sort of thing.  */
+    char tx;
+    char *t = &tx;
+    char const *s = 0 ? (char *) 0 : (char const *) 0;
+
+    *t++ = 0;
+    if (s) return 0;
+  }
+  { /* Someone thinks the Sun supposedly-ANSI compiler will reject this.  */
+    int x[] = {25, 17};
+    const int *foo = &x[0];
+    ++foo;
+  }
+  { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
+    typedef const int *iptr;
+    iptr p = 0;
+    ++p;
+  }
+  { /* AIX XL C 1.02.0.0 rejects this sort of thing, saying
+       "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
+    struct s { int j; const int *ap[3]; } bx;
+    struct s *b = &bx; b->j = 5;
+  }
+  { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
+    const int foo = 10;
+    if (!foo) return 0;
+  }
+  return !cs[0] && !zero.x;
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_c_const=yes
+else
+  ac_cv_c_const=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5
+$as_echo "$ac_cv_c_const" >&6; }
+if test $ac_cv_c_const = no; then
+
+$as_echo "#define const /**/" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5
+$as_echo_n "checking for inline... " >&6; }
+if ${ac_cv_c_inline+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_cv_c_inline=no
+for ac_kw in inline __inline__ __inline; do
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifndef __cplusplus
+typedef int foo_t;
+static $ac_kw foo_t static_foo () {return 0; }
+$ac_kw foo_t foo () {return 0; }
+#endif
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_c_inline=$ac_kw
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  test "$ac_cv_c_inline" != no && break
+done
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5
+$as_echo "$ac_cv_c_inline" >&6; }
+
+case $ac_cv_c_inline in
+  inline | yes) ;;
+  *)
+    case $ac_cv_c_inline in
+      no) ac_val=;;
+      *) ac_val=$ac_cv_c_inline;;
+    esac
+    cat >>confdefs.h <<_ACEOF
+#ifndef __cplusplus
+#define inline $ac_val
+#endif
+_ACEOF
+    ;;
+esac
+
+
+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.4.2'
+macro_revision='1.3337'
+
+
+
+
+
+
+
+
+
+
+
+
+
+ltmain="$ac_aux_dir/ltmain.sh"
+
+# 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 ${ac_cv_build+:} false; 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 ${ac_cv_host+:} false; 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
+
+
+# Backslashify 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'
+
+ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5
+$as_echo_n "checking how to print strings... " >&6; }
+# Test print first, because it will be a builtin if present.
+if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \
+   test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then
+  ECHO='print -r --'
+elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then
+  ECHO='printf %s\n'
+else
+  # Use this function as a fallback that always works.
+  func_fallback_echo ()
+  {
+    eval 'cat <<_LTECHO_EOF
+$1
+_LTECHO_EOF'
+  }
+  ECHO='func_fallback_echo'
+fi
+
+# func_echo_all arg...
+# Invoke $ECHO with all args, space-separated.
+func_echo_all ()
+{
+    $ECHO ""
+}
+
+case "$ECHO" in
+  printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5
+$as_echo "printf" >&6; } ;;
+  print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5
+$as_echo "print -r" >&6; } ;;
+  *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5
+$as_echo "cat" >&6; } ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+{ $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 ${ac_cv_path_SED+:} false; 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"
+      as_fn_executable_p "$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 ${ac_cv_path_GREP+:} false; 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"
+      as_fn_executable_p "$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 ${ac_cv_path_EGREP+:} false; 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"
+      as_fn_executable_p "$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 ${ac_cv_path_FGREP+:} false; 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"
+      as_fn_executable_p "$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 ${lt_cv_path_LD+:} false; 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 ${lt_cv_prog_gnu_ld+:} false; 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 ${lt_cv_path_NM+:} false; 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 "$DUMPBIN"; then :
+    # Let the user override the test.
+  else
+    if test -n "$ac_tool_prefix"; then
+  for ac_prog in dumpbin "link -dump"
+  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 ${ac_cv_prog_DUMPBIN+:} false; 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 as_fn_executable_p "$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 "link -dump"
+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 ${ac_cv_prog_ac_ct_DUMPBIN+:} false; 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 as_fn_executable_p "$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
+
+    case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in
+    *COFF*)
+      DUMPBIN="$DUMPBIN -symbols"
+      ;;
+    *)
+      DUMPBIN=:
+      ;;
+    esac
+  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 ${lt_cv_nm_interface+:} false; 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:$LINENO: $ac_compile\"" >&5)
+  (eval "$ac_compile" 2>conftest.err)
+  cat conftest.err >&5
+  (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
+  (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
+  cat conftest.err >&5
+  (eval echo "\"\$as_me:$LINENO: 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; }
+
+# 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 ${lt_cv_sys_max_cmd_len+:} false; 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;
+    ;;
+
+  mint*)
+    # On MiNT this can take a long time and run out of memory.
+    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
+    ;;
+
+  os2*)
+    # The test takes a long time on OS/2.
+    lt_cv_sys_max_cmd_len=8192
+    ;;
+
+  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"`env echo "$teststring$teststring" 2>/dev/null` \
+	         = "X$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%"$_lt_dummy"}, \
+      = c,a/b,b/c, \
+    && 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 how to convert $build file names to $host format" >&5
+$as_echo_n "checking how to convert $build file names to $host format... " >&6; }
+if ${lt_cv_to_host_file_cmd+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $host in
+  *-*-mingw* )
+    case $build in
+      *-*-mingw* ) # actually msys
+        lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32
+        ;;
+      *-*-cygwin* )
+        lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32
+        ;;
+      * ) # otherwise, assume *nix
+        lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32
+        ;;
+    esac
+    ;;
+  *-*-cygwin* )
+    case $build in
+      *-*-mingw* ) # actually msys
+        lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin
+        ;;
+      *-*-cygwin* )
+        lt_cv_to_host_file_cmd=func_convert_file_noop
+        ;;
+      * ) # otherwise, assume *nix
+        lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin
+        ;;
+    esac
+    ;;
+  * ) # unhandled hosts (and "normal" native builds)
+    lt_cv_to_host_file_cmd=func_convert_file_noop
+    ;;
+esac
+
+fi
+
+to_host_file_cmd=$lt_cv_to_host_file_cmd
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5
+$as_echo "$lt_cv_to_host_file_cmd" >&6; }
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5
+$as_echo_n "checking how to convert $build file names to toolchain format... " >&6; }
+if ${lt_cv_to_tool_file_cmd+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  #assume ordinary cross tools, or native build.
+lt_cv_to_tool_file_cmd=func_convert_file_noop
+case $host in
+  *-*-mingw* )
+    case $build in
+      *-*-mingw* ) # actually msys
+        lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32
+        ;;
+    esac
+    ;;
+esac
+
+fi
+
+to_tool_file_cmd=$lt_cv_to_tool_file_cmd
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5
+$as_echo "$lt_cv_to_tool_file_cmd" >&6; }
+
+
+
+
+
+{ $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 ${lt_cv_ld_reload_flag+:} false; 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
+  cygwin* | mingw* | pw32* | cegcc*)
+    if test "$GCC" != yes; then
+      reload_cmds=false
+    fi
+    ;;
+  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 ${ac_cv_prog_OBJDUMP+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_OBJDUMP+:} false; 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 as_fn_executable_p "$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 ${lt_cv_deplibs_check_method+:} false; 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.
+  # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin.
+  if ( test "$lt_cv_nm_interface" = "BSD nm" && 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
+    # Keep this pattern in sync with the one in func_win32_libid.
+    lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)'
+    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
+  ;;
+
+haiku*)
+  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])(-bit)?( [LM]SB)? 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 glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+netbsd*)
+  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_glob=
+want_nocaseglob=no
+if test "$build" = "$host"; then
+  case $host_os in
+  mingw* | pw32*)
+    if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then
+      want_nocaseglob=yes
+    else
+      file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"`
+    fi
+    ;;
+  esac
+fi
+
+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}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 ${ac_cv_prog_DLLTOOL+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_DLLTOOL+:} false; 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 as_fn_executable_p "$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
+
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5
+$as_echo_n "checking how to associate runtime and link libraries... " >&6; }
+if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_sharedlib_from_linklib_cmd='unknown'
+
+case $host_os in
+cygwin* | mingw* | pw32* | cegcc*)
+  # two different shell functions defined in ltmain.sh
+  # decide which to use based on capabilities of $DLLTOOL
+  case `$DLLTOOL --help 2>&1` in
+  *--identify-strict*)
+    lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib
+    ;;
+  *)
+    lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback
+    ;;
+  esac
+  ;;
+*)
+  # fallback: assume linklib IS sharedlib
+  lt_cv_sharedlib_from_linklib_cmd="$ECHO"
+  ;;
+esac
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5
+$as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; }
+sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd
+test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+  for ac_prog in ar
+  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 ${ac_cv_prog_AR+:} false; 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_AR="$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
+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
+
+
+    test -n "$AR" && break
+  done
+fi
+if test -z "$AR"; then
+  ac_ct_AR=$AR
+  for ac_prog in ar
+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 ${ac_cv_prog_ac_ct_AR+:} false; 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_AR="$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_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
+
+
+  test -n "$ac_ct_AR" && break
+done
+
+  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
+fi
+
+: ${AR=ar}
+: ${AR_FLAGS=cru}
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5
+$as_echo_n "checking for archiver @FILE support... " >&6; }
+if ${lt_cv_ar_at_file+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_ar_at_file=no
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  echo conftest.$ac_objext > conftest.lst
+      lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5'
+      { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5
+  (eval $lt_ar_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      if test "$ac_status" -eq 0; then
+	# Ensure the archiver fails upon bogus file names.
+	rm -f conftest.$ac_objext libconftest.a
+	{ { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5
+  (eval $lt_ar_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+	if test "$ac_status" -ne 0; then
+          lt_cv_ar_at_file=@
+        fi
+      fi
+      rm -f conftest.* libconftest.a
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5
+$as_echo "$lt_cv_ar_at_file" >&6; }
+
+if test "x$lt_cv_ar_at_file" = xno; then
+  archiver_list_spec=
+else
+  archiver_list_spec=$lt_cv_ar_at_file
+fi
+
+
+
+
+
+
+
+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 ${ac_cv_prog_STRIP+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_STRIP+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_RANLIB+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_RANLIB+:} false; 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 as_fn_executable_p "$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 \$tool_oldlib"
+    ;;
+  *)
+    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib"
+    ;;
+  esac
+  old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib"
+fi
+
+case $host_os in
+  darwin*)
+    lock_old_archive_extraction=yes ;;
+  *)
+    lock_old_archive_extraction=no ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 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 ${lt_cv_sys_global_symbol_pipe+:} false; 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};"\
+"     /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\
+"     /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
+  lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'"
+
+  # 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
+/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests.  */
+#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE)
+/* DATA imports from DLLs on WIN32 con't be const, because runtime
+   relocations are performed -- see ld's documentation on pseudo-relocs.  */
+# define LT_DLSYM_CONST
+#elif defined(__osf__)
+/* This system does not cope well with relocations in const data.  */
+# define LT_DLSYM_CONST
+#else
+# define LT_DLSYM_CONST const
+#endif
+
+#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.  */
+LT_DLSYM_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_globsym_save_LIBS=$LIBS
+	  lt_globsym_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_globsym_save_LIBS
+	  CFLAGS=$lt_globsym_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
+
+# Response file support.
+if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+  nm_file_list_spec='@'
+elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then
+  nm_file_list_spec='@'
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5
+$as_echo_n "checking for sysroot... " >&6; }
+
+# Check whether --with-sysroot was given.
+if test "${with_sysroot+set}" = set; then :
+  withval=$with_sysroot;
+else
+  with_sysroot=no
+fi
+
+
+lt_sysroot=
+case ${with_sysroot} in #(
+ yes)
+   if test "$GCC" = yes; then
+     lt_sysroot=`$CC --print-sysroot 2>/dev/null`
+   fi
+   ;; #(
+ /*)
+   lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"`
+   ;; #(
+ no|'')
+   ;; #(
+ *)
+   { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${with_sysroot}" >&5
+$as_echo "${with_sysroot}" >&6; }
+   as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5
+   ;;
+esac
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5
+$as_echo "${lt_sysroot:-no}" >&6; }
+
+
+
+
+
+# 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 '$LINENO' "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 ${lt_cv_cc_needs_belf+:} false; 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
+  ;;
+*-*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*)
+        case $host in
+        i?86-*-solaris*)
+          LD="${LD-ld} -m elf_x86_64"
+          ;;
+        sparc*-*-solaris*)
+          LD="${LD-ld} -m elf64_sparc"
+          ;;
+        esac
+        # GNU ld 2.21 introduced _sol2 emulations.  Use them if available.
+        if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then
+          LD="${LD-ld}_sol2"
+        fi
+        ;;
+      *)
+	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"
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args.
+set dummy ${ac_tool_prefix}mt; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_MANIFEST_TOOL+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$MANIFEST_TOOL"; then
+  ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt"
+    $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
+MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL
+if test -n "$MANIFEST_TOOL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5
+$as_echo "$MANIFEST_TOOL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_MANIFEST_TOOL"; then
+  ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL
+  # Extract the first word of "mt", so it can be a program name with args.
+set dummy mt; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_MANIFEST_TOOL"; then
+  ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_MANIFEST_TOOL="mt"
+    $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_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL
+if test -n "$ac_ct_MANIFEST_TOOL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5
+$as_echo "$ac_ct_MANIFEST_TOOL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_MANIFEST_TOOL" = x; then
+    MANIFEST_TOOL=":"
+  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
+    MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL
+  fi
+else
+  MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL"
+fi
+
+test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5
+$as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; }
+if ${lt_cv_path_mainfest_tool+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_path_mainfest_tool=no
+  echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5
+  $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out
+  cat conftest.err >&5
+  if $GREP 'Manifest Tool' conftest.out > /dev/null; then
+    lt_cv_path_mainfest_tool=yes
+  fi
+  rm -f conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5
+$as_echo "$lt_cv_path_mainfest_tool" >&6; }
+if test "x$lt_cv_path_mainfest_tool" != xyes; then
+  MANIFEST_TOOL=:
+fi
+
+
+
+
+
+
+  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 ${ac_cv_prog_DSYMUTIL+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_NMEDIT+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_NMEDIT+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_LIPO+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_LIPO+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_OTOOL+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_OTOOL+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_OTOOL64+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_OTOOL64+:} false; 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 as_fn_executable_p "$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 ${lt_cv_apple_cc_single_mod+:} false; 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 there is a non-empty error log, and "single_module"
+	# appears in it, assume the flag caused a linker warning
+        if test -s conftest.err && $GREP single_module conftest.err; then
+	  cat conftest.err >&5
+	# Otherwise, if the output was created with a 0 exit code from
+	# the compiler, it worked.
+	elif test -f libconftest.dylib && test $_lt_result -eq 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 ${lt_cv_ld_exported_symbols_list+:} false; 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; }
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5
+$as_echo_n "checking for -force_load linker flag... " >&6; }
+if ${lt_cv_ld_force_load+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_ld_force_load=no
+      cat > conftest.c << _LT_EOF
+int forced_loaded() { return 2;}
+_LT_EOF
+      echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5
+      $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5
+      echo "$AR cru libconftest.a conftest.o" >&5
+      $AR cru libconftest.a conftest.o 2>&5
+      echo "$RANLIB libconftest.a" >&5
+      $RANLIB libconftest.a 2>&5
+      cat > conftest.c << _LT_EOF
+int main() { return 0;}
+_LT_EOF
+      echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5
+      $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err
+      _lt_result=$?
+      if test -s conftest.err && $GREP force_load conftest.err; then
+	cat conftest.err >&5
+      elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then
+	lt_cv_ld_force_load=yes
+      else
+	cat conftest.err >&5
+      fi
+        rm -f conftest.err libconftest.a conftest conftest.c
+        rm -rf conftest.dSYM
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5
+$as_echo "$lt_cv_ld_force_load" >&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" != ":" && test "$lt_cv_ld_force_load" = "no"; then
+      _lt_dsymutil='~$DSYMUTIL $lib || :'
+    else
+      _lt_dsymutil=
+    fi
+    ;;
+  esac
+
+
+{ $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 ${ac_cv_header_stdc+:} false; 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
+"
+if eval test \"x\$"$as_ac_Header"\" = 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" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_DLFCN_H 1
+_ACEOF
+
+fi
+
+done
+
+
+
+
+
+# Set options
+
+
+
+        enable_dlopen=no
+
+
+  enable_win32_dll=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; lt_p=${PACKAGE-default}
+    case $withval in
+    yes|no) pic_mode=$withval ;;
+    *)
+      pic_mode=default
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for lt_pkg in $withval; do
+	IFS="$lt_save_ifs"
+	if test "X$lt_pkg" = "X$lt_p"; then
+	  pic_mode=yes
+	fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac
+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 ${lt_cv_objdir+:} false; 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
+
+# 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 "$cc_temp" | $SED "s%.*/%%; 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 ${lt_cv_path_MAGIC_CMD+:} false; 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 ${lt_cv_path_MAGIC_CMD+:} false; 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*
+
+
+## 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...
+if test -n "$compiler"; then
+
+lt_prog_compiler_no_builtin_flag=
+
+if test "$GCC" = yes; then
+  case $cc_basename in
+  nvcc*)
+    lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;;
+  *)
+    lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;;
+  esac
+
+  { $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 ${lt_cv_prog_compiler_rtti_exceptions+:} false; 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:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $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 "$_lt_compiler_boilerplate" | $SED '/^$/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=
+
+
+  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'
+      ;;
+
+    haiku*)
+      # PIC is the default for Haiku.
+      # The "-static" flag exists, but is broken.
+      lt_prog_compiler_static=
+      ;;
+
+    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
+
+    case $cc_basename in
+    nvcc*) # Cuda Compiler Driver 2.2
+      lt_prog_compiler_wl='-Xlinker '
+      if test -n "$lt_prog_compiler_pic"; then
+        lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic"
+      fi
+      ;;
+    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 | kopensolaris*-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'
+	;;
+      nagfor*)
+	# NAG Fortran compiler
+	lt_prog_compiler_wl='-Wl,-Wl,,'
+	lt_prog_compiler_pic='-PIC'
+	lt_prog_compiler_static='-Bstatic'
+	;;
+      pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
+        # 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* | bgxl* | bgf* | mpixl*)
+	# IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene
+	lt_prog_compiler_wl='-Wl,'
+	lt_prog_compiler_pic='-qpic'
+	lt_prog_compiler_static='-qstaticlink'
+	;;
+      *)
+	case `$CC -V 2>&1 | sed 5q` in
+	*Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*)
+	  # 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=''
+	  ;;
+	*Sun\ F* | *Sun*Fortran*)
+	  lt_prog_compiler_pic='-KPIC'
+	  lt_prog_compiler_static='-Bstatic'
+	  lt_prog_compiler_wl='-Qoption ld '
+	  ;;
+	*Sun\ C*)
+	  # Sun C 5.9
+	  lt_prog_compiler_pic='-KPIC'
+	  lt_prog_compiler_static='-Bstatic'
+	  lt_prog_compiler_wl='-Wl,'
+	  ;;
+        *Intel*\ [CF]*Compiler*)
+	  lt_prog_compiler_wl='-Wl,'
+	  lt_prog_compiler_pic='-fPIC'
+	  lt_prog_compiler_static='-static'
+	  ;;
+	*Portland\ Group*)
+	  lt_prog_compiler_wl='-Wl,'
+	  lt_prog_compiler_pic='-fpic'
+	  lt_prog_compiler_static='-Bstatic'
+	  ;;
+	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* | sunf77* | sunf90* | sunf95*)
+	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}: checking for $compiler option to produce PIC" >&5
+$as_echo_n "checking for $compiler option to produce PIC... " >&6; }
+if ${lt_cv_prog_compiler_pic+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_pic=$lt_prog_compiler_pic
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5
+$as_echo "$lt_cv_prog_compiler_pic" >&6; }
+lt_prog_compiler_pic=$lt_cv_prog_compiler_pic
+
+#
+# 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 ${lt_cv_prog_compiler_pic_works+:} false; 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:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $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 "$_lt_compiler_boilerplate" | $SED '/^$/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 ${lt_cv_prog_compiler_static_works+:} false; 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 "$_lt_linker_boilerplate" | $SED '/^$/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 ${lt_cv_prog_compiler_c_o+:} false; 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:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $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 "$_lt_compiler_boilerplate" | $SED '/^$/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 ${lt_cv_prog_compiler_c_o+:} false; 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:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $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 "$_lt_compiler_boilerplate" | $SED '/^$/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_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
+    ;;
+  esac
+
+  ld_shlibs=yes
+
+  # On some targets, GNU ld is compatible enough with the native linker
+  # that we're better off using the native interface for both.
+  lt_use_gnu_ld_interface=no
+  if test "$with_gnu_ld" = yes; then
+    case $host_os in
+      aix*)
+	# The AIX port of GNU ld has always aspired to compatibility
+	# with the native linker.  However, as the warning in the GNU ld
+	# block says, versions before 2.19.5* couldn't really create working
+	# shared libraries, regardless of the interface used.
+	case `$LD -v 2>&1` in
+	  *\ \(GNU\ Binutils\)\ 2.19.5*) ;;
+	  *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;;
+	  *\ \(GNU\ Binutils\)\ [3-9]*) ;;
+	  *)
+	    lt_use_gnu_ld_interface=yes
+	    ;;
+	esac
+	;;
+      *)
+	lt_use_gnu_ld_interface=yes
+	;;
+    esac
+  fi
+
+  if test "$lt_use_gnu_ld_interface" = 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
+      *GNU\ gold*) supports_anon_versioning=yes ;;
+      *\ [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.19, 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 install binutils
+*** 2.20 or above, or modify your PATH so that a non-GNU linker is found.
+*** You will then need to restart the configuration process.
+
+_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'
+      export_dynamic_flag_spec='${wl}--export-all-symbols'
+      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/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols'
+      exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'
+
+      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
+      ;;
+
+    haiku*)
+      archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+      link_all_deplibs=yes
+      ;;
+
+    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 | kopensolaris*-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=' $pic_flag'
+	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; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+	  tmp_addflag=' $pic_flag'
+	  ;;
+	pgf77* | pgf90* | pgf95* | pgfortran*)
+					# 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; func_echo_all \"$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]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below)
+	  tmp_sharedflag='-qmkshrobj'
+	  tmp_addflag= ;;
+	nvcc*)	# Cuda Compiler Driver 2.2
+	  whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+	  compiler_needs_object=yes
+	  ;;
+	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; func_echo_all \"$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* | bgf* | bgxlf* | mpixlf*)
+	  # 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='${wl}-rpath ${wl}$libdir'
+	  archive_cmds='$LD -shared $libobjs $deplibs $linker_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 $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+	  fi
+	  ;;
+	esac
+      else
+        ld_shlibs=no
+      fi
+      ;;
+
+    netbsd*)
+      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 $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	archive_expsym_cmds='$CC -shared $pic_flag $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 $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	archive_expsym_cmds='$CC -shared $pic_flag $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 $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	archive_expsym_cmds='$CC -shared $pic_flag $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
+	# Also, AIX nm treats weak defined symbols like other global
+	# defined symbols, whereas GNU nm marks them as "W".
+	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") || (\$ 2 == "W")) && (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
+      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.
+        if test "${lt_cv_aix_libpath+set}" = set; then
+  aix_libpath=$lt_cv_aix_libpath
+else
+  if ${lt_cv_aix_libpath_+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  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
+	  }
+      }'
+  lt_cv_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 "$lt_cv_aix_libpath_"; then
+    lt_cv_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 "$lt_cv_aix_libpath_"; then
+    lt_cv_aix_libpath_="/usr/lib:/lib"
+  fi
+
+fi
+
+  aix_libpath=$lt_cv_aix_libpath_
+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 func_echo_all "${wl}${allow_undefined_flag}"; 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.
+	 if test "${lt_cv_aix_libpath+set}" = set; then
+  aix_libpath=$lt_cv_aix_libpath
+else
+  if ${lt_cv_aix_libpath_+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  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
+	  }
+      }'
+  lt_cv_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 "$lt_cv_aix_libpath_"; then
+    lt_cv_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 "$lt_cv_aix_libpath_"; then
+    lt_cv_aix_libpath_="/usr/lib:/lib"
+  fi
+
+fi
+
+  aix_libpath=$lt_cv_aix_libpath_
+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'
+	  if test "$with_gnu_ld" = yes; then
+	    # We only use this code for GNU lds that support --whole-archive.
+	    whole_archive_flag_spec='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+	  else
+	    # Exported symbols can be pulled into shared objects from archives
+	    whole_archive_flag_spec='$convenience'
+	  fi
+	  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.
+      case $cc_basename in
+      cl*)
+	# Native MSVC
+	hardcode_libdir_flag_spec=' '
+	allow_undefined_flag=unsupported
+	always_export_symbols=yes
+	file_list_spec='@'
+	# 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 $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
+	archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	    sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
+	  else
+	    sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
+	  fi~
+	  $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+	  linknames='
+	# The linker will not automatically build a static lib if we build a DLL.
+	# _LT_TAGVAR(old_archive_from_new_cmds, )='true'
+	enable_shared_with_static_runtimes=yes
+	exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
+	export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols'
+	# Don't use ranlib
+	old_postinstall_cmds='chmod 644 $oldlib'
+	postlink_cmds='lt_outputfile="@OUTPUT@"~
+	  lt_tool_outputfile="@TOOL_OUTPUT@"~
+	  case $lt_outputfile in
+	    *.exe|*.EXE) ;;
+	    *)
+	      lt_outputfile="$lt_outputfile.exe"
+	      lt_tool_outputfile="$lt_tool_outputfile.exe"
+	      ;;
+	  esac~
+	  if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
+	    $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+	    $RM "$lt_outputfile.manifest";
+	  fi'
+	;;
+      *)
+	# Assume MSVC wrapper
+	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 `func_echo_all "$deplibs" | $SED '\''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'
+	enable_shared_with_static_runtimes=yes
+	;;
+      esac
+      ;;
+
+    darwin* | rhapsody*)
+
+
+  archive_cmds_need_lc=no
+  hardcode_direct=no
+  hardcode_automatic=yes
+  hardcode_shlibpath_var=unsupported
+  if test "$lt_cv_ld_force_load" = "yes"; then
+    whole_archive_flag_spec='`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+
+  else
+    whole_archive_flag_spec=''
+  fi
+  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=func_echo_all
+    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
+      ;;
+
+    # 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 $pic_flag -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 $pic_flag ${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 && test "$with_gnu_ld" = no; then
+	archive_cmds='$CC -shared $pic_flag ${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_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 && test "$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 $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	*)
+	  archive_cmds='$CC -shared $pic_flag ${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'
+	  ;;
+	*)
+
+	  # Older versions of the 11.00 compiler do not understand -b yet
+	  # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does)
+	  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5
+$as_echo_n "checking if $CC understands -b... " >&6; }
+if ${lt_cv_prog_compiler__b+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler__b=no
+   save_LDFLAGS="$LDFLAGS"
+   LDFLAGS="$LDFLAGS -b"
+   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 "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
+       $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+       if diff conftest.exp conftest.er2 >/dev/null; then
+         lt_cv_prog_compiler__b=yes
+       fi
+     else
+       lt_cv_prog_compiler__b=yes
+     fi
+   fi
+   $RM -r conftest*
+   LDFLAGS="$save_LDFLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5
+$as_echo "$lt_cv_prog_compiler__b" >&6; }
+
+if test x"$lt_cv_prog_compiler__b" = xyes; then
+    archive_cmds='$CC -b ${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
+
+	  ;;
+	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 $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${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.
+	# This should be the same for all languages, so no per-tag cache variable.
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5
+$as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; }
+if ${lt_cv_irix_exported_symbol+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  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) { return 0; }
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  lt_cv_irix_exported_symbol=yes
+else
+  lt_cv_irix_exported_symbol=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_irix_exported_symbol" >&5
+$as_echo "$lt_cv_irix_exported_symbol" >&6; }
+	if test "$lt_cv_irix_exported_symbol" = yes; then
+          archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
+	fi
+      else
+	archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+	archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -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*)
+      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" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${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" && func_echo_all "-set_version $verstring"` -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} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${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" && func_echo_all "-set_version $verstring"` -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 "-set_version $verstring"` -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 $pic_flag ${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 $pic_flag ${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; }
+if ${lt_cv_archive_cmds_need_lc+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  $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
+	    lt_cv_archive_cmds_need_lc=no
+	  else
+	    lt_cv_archive_cmds_need_lc=yes
+	  fi
+	  allow_undefined_flag=$lt_save_allow_undefined_flag
+	else
+	  cat conftest.err 1>&5
+	fi
+	$RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5
+$as_echo "$lt_cv_archive_cmds_need_lc" >&6; }
+      archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc
+      ;;
+    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
+  case $host_os in
+    mingw* | cegcc*) lt_sed_strip_eq="s,=\([A-Za-z]:\),\1,g" ;;
+    *) lt_sed_strip_eq="s,=/,/,g" ;;
+  esac
+  lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq`
+  case $lt_search_path_spec in
+  *\;*)
+    # 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 's/;/ /g'`
+    ;;
+  *)
+    lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"`
+    ;;
+  esac
+  # 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; }
+}'`
+  # AWK program above erroneously prepends '/' to C:/dos/paths
+  # for these hosts.
+  case $host_os in
+    mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\
+      $SED 's,/\([A-Za-z]:\),\1,g'` ;;
+  esac
+  sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP`
+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 # correct to gnu/linux during the next big refactor
+  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 # correct to gnu/linux during the next big refactor
+  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=`func_echo_all "$lib" | $SED '\''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 # correct to gnu/linux during the next big refactor
+  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,$cc_basename in
+  yes,*)
+    # gcc
+    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="$sys_lib_search_path_spec /usr/lib/w32api"
+      ;;
+    mingw* | cegcc*)
+      # MinGW DLLs use traditional 'lib' prefix
+      soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      ;;
+    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
+    dynamic_linker='Win32 ld.exe'
+    ;;
+
+  *,cl*)
+    # Native MSVC
+    libname_spec='$name'
+    soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+    library_names_spec='${libname}.dll.lib'
+
+    case $build_os in
+    mingw*)
+      sys_lib_search_path_spec=
+      lt_save_ifs=$IFS
+      IFS=';'
+      for lt_path in $LIB
+      do
+        IFS=$lt_save_ifs
+        # Let DOS variable expansion print the short 8.3 style file name.
+        lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"`
+        sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path"
+      done
+      IFS=$lt_save_ifs
+      # Convert to MSYS style.
+      sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'`
+      ;;
+    cygwin*)
+      # Convert to unix form, then to dos form, then back to unix form
+      # but this time dos style (no spaces!) so that the unix form looks
+      # like /cygdrive/c/PROGRA~1:/cygdr...
+      sys_lib_search_path_spec=`cygpath --path --unix "$LIB"`
+      sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null`
+      sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+      ;;
+    *)
+      sys_lib_search_path_spec="$LIB"
+      if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then
+        # It is most probably a Windows format PATH.
+        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
+      # FIXME: find the short name or the path components, as spaces are
+      # common. (e.g. "Program Files" -> "PROGRA~1")
+      ;;
+    esac
+
+    # 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'
+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+      dlpath=$dir/\$dldll~
+       $RM \$dlpath'
+    shlibpath_overrides_runpath=yes
+    dynamic_linker='Win32 link.exe'
+    ;;
+
+  *)
+    # Assume MSVC wrapper
+    library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
+    dynamic_linker='Win32 ld.exe'
+    ;;
+  esac
+  # 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 # correct to gnu/linux during the next big refactor
+  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
+  ;;
+
+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[23].*) objformat=aout ;;
+    *) objformat=elf ;;
+    esac
+  fi
+  # Handle Gentoo/FreeBSD as it was Linux
+  case $host_vendor in
+    gentoo)
+      version_type=linux ;;
+    *)
+      version_type=freebsd-$objformat ;;
+  esac
+
+  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
+      ;;
+    linux)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+      soname_spec='${libname}${release}${shared_ext}$major'
+      need_lib_prefix=no
+      need_version=no
+      ;;
+  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 # correct to gnu/linux during the next big refactor
+  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
+  ;;
+
+haiku*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  dynamic_linker="$host_os runtime_loader"
+  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=LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
+  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'
+  # or fails outright, so override atomically:
+  install_override_mode=555
+  ;;
+
+interix[3-9]*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  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 # correct to gnu/linux during the next big refactor
+	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 glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  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
+  if ${lt_cv_shlibpath_overrides_runpath+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_shlibpath_overrides_runpath=no
+    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 :
+  lt_cv_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
+
+fi
+
+  shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath
+
+  # 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;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'
+  ;;
+
+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 # correct to gnu/linux during the next big refactor
+  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 # correct to gnu/linux during the next big refactor
+  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 # correct to gnu/linux during the next big refactor
+  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 # correct to gnu/linux during the next big refactor
+    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 # correct to gnu/linux during the next big refactor
+  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 # correct to gnu/linux during the next big refactor
+  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 ${ac_cv_lib_dl_dlopen+:} false; 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" = xyes; 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" = xyes; 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 ${ac_cv_lib_dld_shl_load+:} false; 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" = xyes; 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" = xyes; 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 ${ac_cv_lib_dl_dlopen+:} false; 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" = xyes; 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 ${ac_cv_lib_svld_dlopen+:} false; 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" = xyes; 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 ${ac_cv_lib_dld_dld_link+:} false; 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" = xyes; 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 ${lt_cv_dlopen_self+:} false; 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 $LINENO "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
+
+/* When -fvisbility=hidden is used, assume the code has been annotated
+   correspondingly for the symbols needed.  */
+#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+int fnord () __attribute__((visibility("default")));
+#endif
+
+int fnord () { return 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;
+          else puts (dlerror ());
+	}
+      /* 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 ${lt_cv_dlopen_self_static+:} false; 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 $LINENO "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
+
+/* When -fvisbility=hidden is used, assume the code has been annotated
+   correspondingly for the symbols needed.  */
+#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+int fnord () __attribute__((visibility("default")));
+#endif
+
+int fnord () { return 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;
+          else puts (dlerror ());
+	}
+      /* 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:
+
+
+
+
+# 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 ${ac_cv_prog_AR+:} false; 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_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
+
+  test -z "$ac_cv_prog_AR" && ac_cv_prog_AR=":"
+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
+
+
+if test "$ac_cv_prog_AR" != ar; then
+  as_fn_error $? "*** ar program not found" "$LINENO" 5
+fi
+for ac_prog in perl
+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 ${ac_cv_prog_PERL+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$PERL"; then
+  ac_cv_prog_PERL="$PERL" # 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_PERL="$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
+PERL=$ac_cv_prog_PERL
+if test -n "$PERL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PERL" >&5
+$as_echo "$PERL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$PERL" && break
+done
+test -n "$PERL" || PERL=""no""
+
+if test "$ac_cv_prog_PERL" = no; then
+  as_fn_error $? "*** perl program not found" "$LINENO" 5
+fi
+
+# Extract the first word of "addr2line", so it can be a program name with args.
+set dummy addr2line; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ADDR2LINE+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ADDR2LINE"; then
+  ac_cv_prog_ADDR2LINE="$ADDR2LINE" # 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ADDR2LINE="addr2line"
+    $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_ADDR2LINE" && ac_cv_prog_ADDR2LINE="no"
+fi
+fi
+ADDR2LINE=$ac_cv_prog_ADDR2LINE
+if test -n "$ADDR2LINE"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ADDR2LINE" >&5
+$as_echo "$ADDR2LINE" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+if test "$ac_cv_prog_ADDR2LINE" = addr2line; then
+
+cat >>confdefs.h <<_ACEOF
+#define OM_PROG_ADDR2LINE "$ac_cv_prog_ADDR2LINE"
+_ACEOF
+
+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 ${ac_cv_header_stdc+:} false; 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
+
+for ac_header in limits.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "limits.h" "ac_cv_header_limits_h" "$ac_includes_default"
+if test "x$ac_cv_header_limits_h" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIMITS_H 1
+_ACEOF
+
+else
+  as_fn_error $? "Can not compile without limits.h" "$LINENO" 5
+fi
+
+done
+
+
+for ac_header in unistd.h sys/mman.h fcntl.h /usr/include/malloc.h
+do :
+  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+for ac_func in popen mmap sbrk random
+do :
+  as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+
+# sizes
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long" >&5
+$as_echo_n "checking size of long... " >&6; }
+if ${ac_cv_sizeof_long+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long))" "ac_cv_sizeof_long"        "$ac_includes_default"; then :
+
+else
+  if test "$ac_cv_type_long" = yes; then
+     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (long)
+See \`config.log' for more details" "$LINENO" 5; }
+   else
+     ac_cv_sizeof_long=0
+   fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long" >&5
+$as_echo "$ac_cv_sizeof_long" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_LONG $ac_cv_sizeof_long
+_ACEOF
+
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of void*" >&5
+$as_echo_n "checking size of void*... " >&6; }
+if ${ac_cv_sizeof_voidp+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (void*))" "ac_cv_sizeof_voidp"        "$ac_includes_default"; then :
+
+else
+  if test "$ac_cv_type_voidp" = yes; then
+     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (void*)
+See \`config.log' for more details" "$LINENO" 5; }
+   else
+     ac_cv_sizeof_voidp=0
+   fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_voidp" >&5
+$as_echo "$ac_cv_sizeof_voidp" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_VOIDP $ac_cv_sizeof_voidp
+_ACEOF
+
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of double" >&5
+$as_echo_n "checking size of double... " >&6; }
+if ${ac_cv_sizeof_double+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (double))" "ac_cv_sizeof_double"        "$ac_includes_default"; then :
+
+else
+  if test "$ac_cv_type_double" = yes; then
+     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (double)
+See \`config.log' for more details" "$LINENO" 5; }
+   else
+     ac_cv_sizeof_double=0
+   fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_double" >&5
+$as_echo "$ac_cv_sizeof_double" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_DOUBLE $ac_cv_sizeof_double
+_ACEOF
+
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of size_t" >&5
+$as_echo_n "checking size of size_t... " >&6; }
+if ${ac_cv_sizeof_size_t+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (size_t))" "ac_cv_sizeof_size_t"        "$ac_includes_default"; then :
+
+else
+  if test "$ac_cv_type_size_t" = yes; then
+     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (size_t)
+See \`config.log' for more details" "$LINENO" 5; }
+   else
+     ac_cv_sizeof_size_t=0
+   fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_size_t" >&5
+$as_echo "$ac_cv_sizeof_size_t" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_SIZE_T $ac_cv_sizeof_size_t
+_ACEOF
+
+
+
+if test "$ac_cv_sizeof_long" != "$ac_cv_sizeof_voidp"; then
+  as_fn_error $? "need equal sizes for long and void*" "$LINENO" 5
+fi
+if test "$ac_cv_sizeof_voidp" != 4 && test "$ac_cv_sizeof_voidp" != 8; then
+  as_fn_error $? "need void* to be 4 or 8 bytes long" "$LINENO" 5
+fi
+if test "$ac_cv_sizeof_double" != 4 && test "$ac_cv_sizeof_double" != 8; then
+  as_fn_error $? "need double to be 4 or 8 bytes long" "$LINENO" 5
+fi
+
+BACKUP_CFLAGS=$CFLAGS
+BACKUP_CXXFLAGS=$CXXFLAGS
+BACKUP_LDFLAGS=$LDFLAGS
+
+CFLAGS="$CFLAGS -I$srcdir"
+CXXFLAGS="$CXXFLAGS -I$srcdir"
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of system page" >&5
+$as_echo_n "checking size of system page... " >&6; }
+if ${ac_cv_pagesize+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test "$cross_compiling" = yes; then :
+  ac_cv_pagesize=0
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdio.h>
+#include <stdlib.h>
+#include "omGetPageSize.h"
+
+int main()
+{
+  FILE *f=fopen("conftestval", "w");
+  if (!f) exit(1);
+  fprintf(f, "%d\n", omalloc_getpagesize);
+  exit(0);
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  ac_cv_pagesize=`cat conftestval`
+else
+  ac_cv_pagesize=0
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+
+# can not really handle pagesizes which are greater -- there must be a
+# bug somewhere
+if test $ac_cv_pagesize -gt 8192; then
+  ac_cv_pagesize=8192
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_pagesize" >&5
+$as_echo "$ac_cv_pagesize" >&6; }
+if test "$ac_cv_pagesize" = 4096 || test "$ac_cv_pagesize" = 8192; then
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_SYSTEM_PAGE $ac_cv_pagesize
+_ACEOF
+
+else
+as_fn_error $? "need sytem page to be of size 4096 or 8192, but is $ac_cv_pagesize" "$LINENO" 5
+fi
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_OM_PAGE SIZEOF_SYSTEM_PAGE
+_ACEOF
+
+
+if test "$ac_cv_func_mmap" = yes; then
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether mmap works" >&5
+$as_echo_n "checking whether mmap works... " >&6; }
+if ${ac_cv_working_mmap+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test "$cross_compiling" = yes; then :
+  ac_cv_working_mmap=no
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <stdlib.h>
+#include "omMmap.c"
+int main()
+{
+  void* addr = omVallocMmap(128*${ac_cv_pagesize});
+  if (addr == 0 || ((unsigned long) addr % ${ac_cv_pagesize}))
+    exit(1);
+  exit(omVfreeMmap(addr, 128*${ac_cv_pagesize}));
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  ac_cv_working_mmap=yes
+else
+  ac_cv_working_mmap=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
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_working_mmap" >&5
+$as_echo "$ac_cv_working_mmap" >&6; }
+if test "$ac_cv_working_mmap" = yes; then
+
+$as_echo "#define HAVE_WORKING_MMAP 1" >>confdefs.h
+
+fi
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether alignment needs to be strict" >&5
+$as_echo_n "checking whether alignment needs to be strict... " >&6; }
+if ${ac_cv_align_need_strict+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test "$cross_compiling" = yes; then :
+  ac_cv_align_need_strict=yes
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <stdlib.h>
+int main()
+{
+  void* ptr = (void*) malloc(12);
+  volatile double* d_ptr;
+  if ((unsigned long) ptr % 8 == 0) ptr = ptr + 4;
+  d_ptr = (double*) ptr;
+  *d_ptr = (double) 1.25;
+  if (*d_ptr != (double) 1.25) exit(1);
+  else exit(0);
+}
+
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  ac_cv_align_need_strict=no
+else
+  ac_cv_align_need_strict=yes
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_align_need_strict" >&5
+$as_echo "$ac_cv_align_need_strict" >&6; }
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for external config files" >&5
+$as_echo_n "checking for external config files... " >&6; }
+if test "${with_external_config_h+set}" = set; then
+
+$as_echo "#define OM_HAVE_EXTERNAL_CONFIG_H 1" >>confdefs.h
+
+    EXTERNAL_CONFIG_HEADER=${with_external_config_h}
+    rm -f omExternalConfig.h
+    cp ${with_external_config_h} omExternalConfig.h
+fi
+if test "${with_external_config_c+set}" = set; then
+
+$as_echo "#define OM_HAVE_EXTERNAL_CONFIG_C 1" >>confdefs.h
+
+    EXTERNAL_CONFIG_SOURCE=${with_external_config_c}
+fi
+
+
+if test "${EXTERNAL_CONFIG_HEADER+set}" = set || test "${EXTERNAL_CONFIG_SOURCE+set}" = set; then
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${EXTERNAL_CONFIG_HEADER} ${EXTERNAL_CONFIG_SOURCE}" >&5
+$as_echo "${EXTERNAL_CONFIG_HEADER} ${EXTERNAL_CONFIG_SOURCE}" >&6; }
+else
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5
+$as_echo "none" >&6; }
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking which malloc to use" >&5
+$as_echo_n "checking which malloc to use... " >&6; }
+if test "${with_malloc}" = system; then
+  OM_MALLOC_HEADER=omMallocSystem.h
+
+$as_echo "#define OMALLOC_USES_MALLOC 1" >>confdefs.h
+
+
+$as_echo "#define OMALLOC_USES_SYSTEM_MALLOC 1" >>confdefs.h
+
+elif test "${with_malloc}" = external; then
+  if test "${with_external_malloc_h+set}" != set; then
+    as_fn_error $? "need --with_external_malloc_h for external malloc" "$LINENO" 5
+  fi
+
+$as_echo "#define OMALLOC_USES_EXTERNAL_MALLOC 1" >>confdefs.h
+
+  OM_MALLOC_HEADER=$with_external_malloc_h
+  OM_MALLOC_SOURCE=$with_external_malloc_c
+
+$as_echo "#define OMALLOC_USES_MALLOC 1" >>confdefs.h
+
+else	## default
+  OM_MALLOC_HEADER=omMallocSystem.h
+
+$as_echo "#define OMALLOC_USES_MALLOC 1" >>confdefs.h
+
+
+$as_echo "#define OMALLOC_USES_SYSTEM_MALLOC 1" >>confdefs.h
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_malloc" >&5
+$as_echo "$with_malloc" >&6; }
+
+
+
+if test "${OM_MALLOC_SOURCE+set}" = set; then
+
+$as_echo "#define OM_HAVE_MALLOC_SOURCE 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether malloc provides SizeOfAddr" >&5
+$as_echo_n "checking whether malloc provides SizeOfAddr... " >&6; }
+if test "${ac_cv_malloc_sizeof_addr}" = no; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: (cached) no" >&5
+$as_echo "(cached) no" >&6; }
+elif test "${ac_cv_malloc_sizeof_addr}" = "${OM_MALLOC_HEADER}_${OM_MALLOC_SOURCE}"; then
+   { $as_echo "$as_me:${as_lineno-$LINENO}: result: (cached) yes" >&5
+$as_echo "(cached) yes" >&6; }
+else
+if test "$cross_compiling" = yes; then :
+  ac_cv_malloc_sizeof_addr=no
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <stdlib.h>
+#include "$OM_MALLOC_HEADER"
+#ifdef OM_HAVE_MALLOC_SOURCE
+#include "$OM_MALLOC_SOURCE"
+#endif
+
+int main()
+{
+  void* addr = OM_MALLOC_MALLOC(512);
+#ifdef OM_MALLOC_SIZEOF_ADDR
+  if (OM_MALLOC_SIZEOF_ADDR(addr) < 512)
+    exit(1);
+  exit(0);
+#else
+  exit(1);
+#endif
+}
+
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  ac_cv_malloc_sizeof_addr="${OM_MALLOC_HEADER}_${OM_MALLOC_SOURCE}"
+else
+  ac_cv_malloc_sizeof_addr=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+if test "${ac_cv_malloc_sizeof_addr}" = no; then
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+else
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+fi
+fi
+if test "$ac_cv_malloc_sizeof_addr" != no; then
+
+$as_echo "#define OM_MALLOC_PROVIDES_SIZEOF_ADDR 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether working valloc exists" >&5
+$as_echo_n "checking whether working valloc exists... " >&6; }
+if test "${ac_cv_working_valloc}" = no; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: (cached) no" >&5
+$as_echo "(cached) no" >&6; }
+elif test "${ac_cv_working_valloc}" = "${OM_MALLOC_HEADER}_${OM_MALLOC_SOURCE}"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: (cached) yes" >&5
+$as_echo "(cached) yes" >&6; }
+else
+if test "$cross_compiling" = yes; then :
+  ac_cv_working_valloc=no
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <stdlib.h>
+#include "$OM_MALLOC_HEADER"
+#ifdef OM_HAVE_MALLOC_SOURCE
+#include "$OM_MALLOC_SOURCE"
+#endif
+
+int main()
+{
+  void* addr = OM_MALLOC_VALLOC(128*${ac_cv_pagesize});
+  if (addr == 0 || ((unsigned long) addr % ${ac_cv_pagesize}))
+    exit(1);
+  OM_MALLOC_VFREE(addr, 128*${ac_cv_pagesize});
+  exit(0);
+}
+
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  ac_cv_working_valloc="${OM_MALLOC_HEADER}_${OM_MALLOC_SOURCE}"
+else
+  ac_cv_working_valloc=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+if test "${ac_cv_working_valloc}" = no; then
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+else
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+fi
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking which valloc to use" >&5
+$as_echo_n "checking which valloc to use... " >&6; }
+if test "${with_valloc+set}" != set || test "${with_valloc}" = mmap; then
+  if test "${ac_cv_working_mmap}" = yes; then
+    with_valloc=mmap
+
+$as_echo "#define OM_HAVE_VALLOC_MMAP 1" >>confdefs.h
+
+  else
+    with_valloc=malloc
+  fi
+fi
+if test "${with_valloc}" = malloc; then
+  if test "${ac_cv_working_valloc}" != no; then
+
+$as_echo "#define OM_HAVE_VALLOC_MALLOC 1" >>confdefs.h
+
+  else
+    with_valloc=emulate
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_valloc" >&5
+$as_echo "$with_valloc" >&6; }
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to align" >&5
+$as_echo_n "checking how to align... " >&6; }
+if test "$with_align" = 8 || test "$ac_cv_sizeof_long" = 8; then
+  ac_cv_align=8
+
+$as_echo "#define OM_ALIGN_8 1" >>confdefs.h
+
+else
+if test "$ac_cv_align_need_strict" = "yes" || test "$with_align" = "strict"; then
+
+$as_echo "#define OM_ALIGNMENT_NEEDS_WORK 1" >>confdefs.h
+
+  ac_cv_align="strict"
+else
+  ac_cv_align="sloppy"
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_align" >&5
+$as_echo "$ac_cv_align" >&6; }
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use dense bins" >&5
+$as_echo_n "checking whether to use dense bins... " >&6; }
+if test "$with_dense_bins" = yes; then
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define OM_HAVE_DENSE_BIN_DISTRIBUTION 1" >>confdefs.h
+
+else
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+save_cflags="$CFLAGS"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to disable debugging" >&5
+$as_echo_n "checking whether to disable debugging... " >&6; }
+if test "$with_debug" != no; then
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+CFLAGS="$CFLAGS -g"
+else
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define OM_NDEBUG 1" >>confdefs.h
+
+with_track=no
+fi
+ if test x"$with_debug" = xyes; then
+  WANT_DEBUG_TRUE=
+  WANT_DEBUG_FALSE='#'
+else
+  WANT_DEBUG_TRUE='#'
+  WANT_DEBUG_FALSE=
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to have tracking debug functionality" >&5
+$as_echo_n "checking whether to have tracking debug functionality... " >&6; }
+if test "$with_track" != no; then
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define OM_HAVE_TRACK 1" >>confdefs.h
+
+else
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use internal debug" >&5
+$as_echo_n "checking whether to use internal debug... " >&6; }
+if test "$with_internal_debug" = yes; then
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define OM_INTERNAL_DEBUG 1" >>confdefs.h
+
+with_inline=no
+else
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to inline" >&5
+$as_echo_n "checking whether to inline... " >&6; }
+if test "$ac_cv_c_inline" != no && test "$with_inline" != no; then
+
+cat >>confdefs.h <<_ACEOF
+#define OM_INLINE static $ac_cv_c_inline
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define OM_INLINE_DECL static $ac_cv_c_inline
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define OM_INLINE_IMPL static $ac_cv_c_inline
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define OM_INLINE_LOCAL static $ac_cv_c_inline
+_ACEOF
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+
+cat >>confdefs.h <<_ACEOF
+#define OM_INLINE_DECL extern
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define OM_INLINE_IMPL /**/
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define OM_INLINE_LOCAL static
+_ACEOF
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether GET_RET_ADDR works" >&5
+$as_echo_n "checking whether GET_RET_ADDR works... " >&6; }
+if ${ac_cv_get_return_addr_works+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test "$cross_compiling" = yes; then :
+  ac_cv_get_return_addr_works=no
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <stdlib.h>
+#include "omReturn.h"
+int test_return_addr()
+{
+  char* f;
+  GET_RET_ADDR(f);
+  return (int)(long) f;
+}
+int main()
+{
+   exit(! test_return_addr());
+}
+
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  ac_cv_get_return_addr_works=yes
+else
+  ac_cv_get_return_addr_works=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
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_get_return_addr_works" >&5
+$as_echo "$ac_cv_get_return_addr_works" >&6; }
+if test "$ac_cv_get_return_addr_works" = yes; then
+
+$as_echo "#define OM_GET_RETURN_ADDR_WORKS 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether omGetBackTrace works" >&5
+$as_echo_n "checking whether omGetBackTrace works... " >&6; }
+if ${ac_cv_get_backtrace_works+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test "$cross_compiling" = yes; then :
+  ac_cv_get_backtrace_works=no
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "omGetBackTrace.c"
+int test_backtrace0()
+{
+  void* bt [ 10 ] ;
+  int i = omGetBackTrace(bt, 0, 10);
+  return i;
+}
+int test_backtrace(){ return test_backtrace0(); }
+int main()
+{
+   int i;
+   #ifdef __APPLE__
+   /* omGetBackTrace crashes on OsX for i>2 */
+   i=0;
+   #else
+   omInitGetBackTrace();
+   i = test_backtrace();
+   #endif
+   if (i > 0) exit(0);
+   else exit(i+10);
+}
+
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  ac_cv_get_backtrace_works=yes
+else
+  ac_cv_get_backtrace_works=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
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_get_backtrace_works" >&5
+$as_echo "$ac_cv_get_backtrace_works" >&6; }
+if test "$ac_cv_get_backtrace_works" = yes; then
+
+$as_echo "#define OM_GET_BACKTRACE_WORKS 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether addr2line works" >&5
+$as_echo_n "checking whether addr2line works... " >&6; }
+if ${ac_cv_prog_addr2line_works+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test "$cross_compiling" = yes; then :
+  ac_cv_prog_addr2line_works=no
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <stdlib.h>
+#include "omReturn.h"
+#include "omStructs.h"
+/* #include "omGetBackTrace.h" */
+#include "omGetBackTrace.c"
+#include "omRet2Info.c"
+
+int test_Ret_2_Info()
+{
+  void* bt;
+  int i;
+  struct omRetInfo_s info;
+
+  GET_RET_ADDR(bt);
+  i = omBackTrace_2_RetInfo(&bt, &info, 1);
+  return i;
+}
+
+int main(int argc, char** argv)
+{
+  int i;
+  omInitRet_2_Info(*argv);
+  i = test_Ret_2_Info();
+  if (i==1) exit(0);
+  else exit (i+10);
+}
+
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  ac_cv_prog_addr2line_works=yes
+else
+  ac_cv_prog_addr2line_works=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
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_addr2line_works" >&5
+$as_echo "$ac_cv_prog_addr2line_works" >&6; }
+
+CFLAGS="$save_cflags"
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to track return addresses" >&5
+$as_echo_n "checking whether to track return addresses... " >&6; }
+if test "$with_track_return" = no || test "$ac_cv_get_return_addr_works" = no || test "$ac_cv_prog_addr2line_works" != yes; then
+  with_track_return=no
+else
+
+$as_echo "#define OM_TRACK_RETURN 1" >>confdefs.h
+
+  with_track_return=yes
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_track_return" >&5
+$as_echo "$with_track_return" >&6; }
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to track files and line numbers" >&5
+$as_echo_n "checking whether to track files and line numbers... " >&6; }
+if test "$with_track_fl" = no && test "$with_track_return" = no; then
+  with_track_fl=yes
+fi
+if test "${with_track_fl+set}" != set; then
+  if test "$with_track_return" = yes; then
+    with_track_fl=no
+  else
+    with_track_fl=yes
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_track_fl" >&5
+$as_echo "$with_track_fl" >&6; }
+if test "$with_track_fl" = yes; then
+
+$as_echo "#define OM_TRACK_FILE_LINE 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to track stack backtraces" >&5
+$as_echo_n "checking whether to track stack backtraces... " >&6; }
+if test "$with_track" != no && test "$ac_cv_get_backtrace_works" = yes && test "$with_track_backtrace" != no && test "$ac_cv_prog_addr2line_works" = yes; then
+  with_track_backtrace=yes
+
+$as_echo "#define OM_TRACK_BACKTRACE 1" >>confdefs.h
+
+else
+  with_track_backtrace=no
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_track_backtrace" >&5
+$as_echo "$with_track_backtrace" >&6; }
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to track custom values" >&5
+$as_echo_n "checking whether to track custom values... " >&6; }
+if test "$with_track" != no && test "$with_track_custom" = yes; then
+
+$as_echo "#define OM_TRACK_CUSTOM 1" >>confdefs.h
+
+else
+  with_track_custom=no
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_track_custom" >&5
+$as_echo "$with_track_custom" >&6; }
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking return type of sbrk" >&5
+$as_echo_n "checking return type of sbrk... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#define __USE_MISC
+#include <unistd.h>
+
+int
+main ()
+{
+void *sbrk();
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+$as_echo "#define Void_t void" >>confdefs.h
+
+else
+
+$as_echo "#define Void_t char" >>confdefs.h
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: Void_t" >&5
+$as_echo "Void_t" >&6; }
+
+
+
+$as_echo "#define OM_PROVIDE_MALLOC 0" >>confdefs.h
+
+
+
+
+CFLAGS=$BACKUP_CFLAGS
+CXXFLAGS=$BACKUP_CXXFLAGS
+LDFLAGS=$BACKUP_LDFLAGS
+
+ac_config_files="$ac_config_files Makefile omalloc.pc"
+
+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
+    if test "x$cache_file" != "x/dev/null"; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
+$as_echo "$as_me: updating cache $cache_file" >&6;}
+      if test ! -f "$cache_file" || test -h "$cache_file"; then
+	cat confcache >"$cache_file"
+      else
+        case $cache_file in #(
+        */* | ?:*)
+	  mv -f confcache "$cache_file"$$ &&
+	  mv -f "$cache_file"$$ "$cache_file" ;; #(
+        *)
+	  mv -f confcache "$cache_file" ;;
+	esac
+      fi
+    fi
+  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=
+U=
+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 -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
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5
+$as_echo_n "checking that generated files are newer than configure... " >&6; }
+   if test -n "$am_sleep_pid"; then
+     # Hide warnings about reused PIDs.
+     wait $am_sleep_pid 2>/dev/null
+   fi
+   { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5
+$as_echo "done" >&6; }
+ if test -n "$EXEEXT"; then
+  am__EXEEXT_TRUE=
+  am__EXEEXT_FALSE='#'
+else
+  am__EXEEXT_TRUE='#'
+  am__EXEEXT_FALSE=
+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
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5
+$as_echo_n "checking that generated files are newer than configure... " >&6; }
+   if test -n "$am_sleep_pid"; then
+     # Hide warnings about reused PIDs.
+     wait $am_sleep_pid 2>/dev/null
+   fi
+   { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5
+$as_echo "done" >&6; }
+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 "${WANT_DEBUG_TRUE}" && test -z "${WANT_DEBUG_FALSE}"; then
+  as_fn_error $? "conditional \"WANT_DEBUG\" 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.
+as_myself=
+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 STATUS 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=$1; test $as_status -eq 0 && as_status=1
+  if test "$4"; then
+    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+  fi
+  $as_echo "$as_me: error: $2" >&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 -pR'.
+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+      as_ln_s='cp -pR'
+  elif ln conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s=ln
+  else
+    as_ln_s='cp -pR'
+  fi
+else
+  as_ln_s='cp -pR'
+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
+
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+  test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
+
+# 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 omalloc $as_me 0.9.6, which was
+generated by GNU Autoconf 2.69.  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
+      --config     print configuration, 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_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
+ac_cs_version="\\
+omalloc config.status 0.9.6
+configured by $0, generated by GNU Autoconf 2.69,
+  with options \\"\$ac_cs_config\\"
+
+Copyright (C) 2012 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=`expr "X$1" : 'X\([^=]*\)='`
+    ac_optarg=
+    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 ;;
+  --config | --confi | --conf | --con | --co | --c )
+    $as_echo "$ac_cs_config"; 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"` ;;
+    '') as_fn_error $? "missing file argument" ;;
+    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"
+PACKAGE="$PACKAGE"
+
+
+# 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'
+macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`'
+macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`'
+enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`'
+enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`'
+pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`'
+enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`'
+SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`'
+ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`'
+PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`'
+host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`'
+host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`'
+host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`'
+build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`'
+build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`'
+build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`'
+SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`'
+Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`'
+GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`'
+EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`'
+FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`'
+LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`'
+NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`'
+LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`'
+max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`'
+ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`'
+exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`'
+lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`'
+lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`'
+lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`'
+lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`'
+lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`'
+reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`'
+reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`'
+OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`'
+deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`'
+file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`'
+file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`'
+want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`'
+DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`'
+sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`'
+AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`'
+AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`'
+archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`'
+STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`'
+RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`'
+old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`'
+old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`'
+old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`'
+lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`'
+CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`'
+CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`'
+compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`'
+GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`'
+nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`'
+lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`'
+objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`'
+MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`'
+lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`'
+need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`'
+MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`'
+DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`'
+NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`'
+LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`'
+OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`'
+OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`'
+libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`'
+shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`'
+extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`'
+archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`'
+enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`'
+export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`'
+whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`'
+compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`'
+old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`'
+old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`'
+archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`'
+archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`'
+module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`'
+module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`'
+with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`'
+allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`'
+no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`'
+hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`'
+hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`'
+hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`'
+hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`'
+hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`'
+inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`'
+link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`'
+always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`'
+export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`'
+exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`'
+include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`'
+prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`'
+postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`'
+file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`'
+variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`'
+need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`'
+need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`'
+version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`'
+runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`'
+shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`'
+shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`'
+libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`'
+library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`'
+soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`'
+install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`'
+postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`'
+postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`'
+finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`'
+finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`'
+hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`'
+sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`'
+sys_lib_dlsearch_path_spec='`$ECHO "$sys_lib_dlsearch_path_spec" | $SED "$delay_single_quote_subst"`'
+hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`'
+enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`'
+enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`'
+enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`'
+old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`'
+striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`'
+
+LTCC='$LTCC'
+LTCFLAGS='$LTCFLAGS'
+compiler='$compiler_DEFAULT'
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+  eval 'cat <<_LTECHO_EOF
+\$1
+_LTECHO_EOF'
+}
+
+# Quote evaled strings.
+for var in SHELL \
+ECHO \
+PATH_SEPARATOR \
+SED \
+GREP \
+EGREP \
+FGREP \
+LD \
+NM \
+LN_S \
+lt_SP2NL \
+lt_NL2SP \
+reload_flag \
+OBJDUMP \
+deplibs_check_method \
+file_magic_cmd \
+file_magic_glob \
+want_nocaseglob \
+DLLTOOL \
+sharedlib_from_linklib_cmd \
+AR \
+AR_FLAGS \
+archiver_list_spec \
+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 \
+nm_file_list_spec \
+lt_prog_compiler_no_builtin_flag \
+lt_prog_compiler_pic \
+lt_prog_compiler_wl \
+lt_prog_compiler_static \
+lt_cv_prog_compiler_c_o \
+need_locks \
+MANIFEST_TOOL \
+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_separator \
+exclude_expsyms \
+include_expsyms \
+file_list_spec \
+variables_saved_for_relink \
+libname_spec \
+library_names_spec \
+soname_spec \
+install_override_mode \
+finish_eval \
+old_striplib \
+striplib; do
+    case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+    *[\\\\\\\`\\"\\\$]*)
+      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$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 \
+postlink_cmds \
+postinstall_cmds \
+postuninstall_cmds \
+finish_cmds \
+sys_lib_search_path_spec \
+sys_lib_dlsearch_path_spec; do
+    case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+    *[\\\\\\\`\\"\\\$]*)
+      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\""
+      ;;
+    *)
+      eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+      ;;
+    esac
+done
+
+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'
+
+
+
+
+_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" ;;
+    "omConfig.h") CONFIG_COMMANDS="$CONFIG_COMMANDS omConfig.h" ;;
+    "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;;
+    "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+    "omalloc.pc") CONFIG_FILES="$CONFIG_FILES omalloc.pc" ;;
+
+  *) 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= ac_tmp=
+  trap 'exit_status=$?
+  : "${ac_tmp:=$tmp}"
+  { test ! -d "$ac_tmp" || rm -fr "$ac_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 -d "$tmp"
+}  ||
+{
+  tmp=./conf$$-$RANDOM
+  (umask 077 && mkdir "$tmp")
+} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
+ac_tmp=$tmp
+
+# 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 {' >"$ac_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 >>"\$ac_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 >>"\$ac_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 < "$ac_tmp/subs1.awk" > "$ac_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 sole $(srcdir),
+# ${srcdir} and @srcdir@ entries 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[	 ]*=[	 ]*/{
+h
+s///
+s/^/:/
+s/[	 ]*$/:/
+s/:\$(srcdir):/:/g
+s/:\${srcdir}:/:/g
+s/:@srcdir@:/:/g
+s/^:*//
+s/:*$//
+x
+s/\(=[	 ]*\).*/\1/
+G
+s/\n//
+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 >"$ac_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_tt=`sed -n "/$ac_delim/p" confdefs.h`
+  if test -z "$ac_tt"; 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="$ac_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 1 "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 >"$ac_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 "$ac_tmp/subs.awk" \
+  >$ac_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' "$ac_tmp/out"`; test -n "$ac_out"; } &&
+  { ac_out=`sed -n '/^[	 ]*datarootdir[	 ]*:*=/p' \
+      "$ac_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 "$ac_tmp/stdin"
+  case $ac_file in
+  -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";;
+  *) rm -f "$ac_file" && mv "$ac_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 "$ac_tmp/defines.awk"' "$ac_file_inputs"
+    } >"$ac_tmp/config.h" \
+      || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+    if diff "$ac_file" "$ac_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 "$ac_tmp/config.h" "$ac_file" \
+	|| as_fn_error $? "could not create $ac_file" "$LINENO" 5
+    fi
+  else
+    $as_echo "/* $configure_input  */" \
+      && eval '$AWK -f "$ac_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"" || {
+  # Older Autoconf 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"`
+    # 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'`; 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
+}
+ ;;
+    "omConfig.h":C)
+ac_prefix_conf_OUT=`echo omConfig.h`
+ac_prefix_conf_PKG=`echo `
+ac_prefix_conf_LOW=`echo $ac_prefix_conf_PKG | sed -e "y:ABCDEFGHIJKLMNOPQRSTUVWXYZ-:abcdefghijklmnopqrstuvwxyz_:"`
+ac_prefix_conf_UPP=`echo $ac_prefix_conf_PKG | sed -e "y:abcdefghijklmnopqrstuvwxyz-:ABCDEFGHIJKLMNOPQRSTUVWXYZ_:"  -e "/^[0123456789]/s/^/_/"`
+ac_prefix_conf_INP=`echo "_config.h" | sed -e 's/ *//'`
+ac_prefix_conf_DEF=`echo "$ac_prefix_conf_UPP $PACKAGE $ac_prefix_conf_OUT" | sed -e "y:abcdefghijklmnopqrstuvwxyz:ABCDEFGHIJKLMNOPQRSTUVWXYZ:" -e "s/[^abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ]/_/g"`
+
+if test ".$ac_prefix_conf_INP" = "."; then
+   for ac_file in : $CONFIG_HEADERS; do test "_$ac_file" = _: && continue
+     case "$ac_file" in
+        *.h) ac_prefix_conf_INP=$ac_file ;;
+        *)
+     esac
+     test ".$ac_prefix_conf_INP" != "." && break
+   done
+fi
+if test ".$ac_prefix_conf_INP" = "."; then
+   case "$ac_prefix_conf_OUT" in
+      */*) ac_prefix_conf_INP=`basename "$ac_prefix_conf_OUT"`
+      ;;
+      *-*) ac_prefix_conf_INP=`echo "$ac_prefix_conf_OUT" | sed -e "s/[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_]*-//"`
+      ;;
+      *) ac_prefix_conf_INP=config.h
+      ;;
+   esac
+fi
+#if test -z "$_PKG" ; then
+#   AC_MSG_ERROR([no prefix for AX_PREFIX_PKG_CONFIG_H])
+#else
+  if test ! -f "$ac_prefix_conf_INP" ; then if test -f "$srcdir/$ac_prefix_conf_INP" ; then
+     ac_prefix_conf_INP="$srcdir/$ac_prefix_conf_INP"
+  fi fi
+  { $as_echo "$as_me:${as_lineno-$LINENO}: creating '$ac_prefix_conf_OUT' - prefix '$ac_prefix_conf_UPP' for '$ac_prefix_conf_INP' defines" >&5
+$as_echo "$as_me: creating '$ac_prefix_conf_OUT' - prefix '$ac_prefix_conf_UPP' for '$ac_prefix_conf_INP' defines" >&6;}
+  if test -f $ac_prefix_conf_INP ; then
+    $as_echo "s/^#undef  *\\([ABCDEFGHIJKLMNOPQRSTUVWXYZ_]\\)/#undef $ac_prefix_conf_UPP""\\1/" > conftest.prefix
+    $as_echo "s/^#undef  *\\([abcdefghijklmnopqrstuvwxyz]\\)/#undef $ac_prefix_conf_LOW""\\1/" >> conftest.prefix
+    $as_echo "s/^#define  *\\([ABCDEFGHIJKLMNOPQRSTUVWXYZ_][abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_]*\\)\\(.*\\)/#ifndef $ac_prefix_conf_UPP""\\1\\" >> conftest.prefix
+    $as_echo "#define $ac_prefix_conf_UPP""\\1\\2\\" >> conftest.prefix
+    $as_echo "#endif/" >> conftest.prefix
+    $as_echo "s/^#define  *\\([abcdefghijklmnopqrstuvwxyz][abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_]*\\)\\(.*\\)/#ifndef $ac_prefix_conf_LOW""\\1\\" >> conftest.prefix
+    $as_echo "#define $ac_prefix_conf_LOW""\\1\\2\\" >> conftest.prefix
+    $as_echo "#endif/" >> conftest.prefix
+
+    # now executing _script on _DEF input to create _OUT output file
+    echo "#ifndef $ac_prefix_conf_DEF"      >$tmp/pconfig.h
+    echo "#define $ac_prefix_conf_DEF 1" >>$tmp/pconfig.h
+    echo ' ' >>$tmp/pconfig.h
+
+    echo /'*' $ac_prefix_conf_OUT. Generated automatically at end of configure. '*'/ >>$tmp/pconfig.h
+    echo ' ' >>$tmp/pconfig.h
+
+    sed -f conftest.prefix $ac_prefix_conf_INP >>$tmp/pconfig.h
+    echo ' ' >>$tmp/pconfig.h
+    echo '/* once:' $ac_prefix_conf_DEF '*/' >>$tmp/pconfig.h
+    echo "#endif" >>$tmp/pconfig.h
+    if cmp -s $ac_prefix_conf_OUT $tmp/pconfig.h 2>/dev/null; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_prefix_conf_OUT is unchanged" >&5
+$as_echo "$as_me: $ac_prefix_conf_OUT is unchanged" >&6;}
+    else
+      ac_dir=`$as_dirname -- "$ac_prefix_conf_OUT" ||
+$as_expr X"$ac_prefix_conf_OUT" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$ac_prefix_conf_OUT" : 'X\(//\)[^/]' \| \
+	 X"$ac_prefix_conf_OUT" : 'X\(//\)$' \| \
+	 X"$ac_prefix_conf_OUT" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$ac_prefix_conf_OUT" |
+    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
+      rm -f "$ac_prefix_conf_OUT"
+      mv $tmp/pconfig.h "$ac_prefix_conf_OUT"
+    fi
+    cp conftest.prefix _configs.sed
+    rm _configs.sed
+  else
+    as_fn_error $? "input file $ac_prefix_conf_INP does not exist - skip generating $ac_prefix_conf_OUT" "$LINENO" 5
+  fi
+  rm -f conftest.*
+#fi
+ ;;
+    "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, 2009, 2010, 2011 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=""
+
+# ### BEGIN LIBTOOL CONFIG
+
+# 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
+
+# Shell to use when invoking shell scripts.
+SHELL=$lt_SHELL
+
+# An echo program that protects backslashes.
+ECHO=$lt_ECHO
+
+# The PATH separator for the build system.
+PATH_SEPARATOR=$lt_PATH_SEPARATOR
+
+# 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
+
+# convert \$build file names to \$host format.
+to_host_file_cmd=$lt_cv_to_host_file_cmd
+
+# convert \$build files to toolchain format.
+to_tool_file_cmd=$lt_cv_to_tool_file_cmd
+
+# An object symbol dumper.
+OBJDUMP=$lt_OBJDUMP
+
+# 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
+
+# How to find potential files when deplibs_check_method = "file_magic".
+file_magic_glob=$lt_file_magic_glob
+
+# Find potential files using nocaseglob when deplibs_check_method = "file_magic".
+want_nocaseglob=$lt_want_nocaseglob
+
+# DLL creation program.
+DLLTOOL=$lt_DLLTOOL
+
+# Command to associate shared and link libraries.
+sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd
+
+# The archiver.
+AR=$lt_AR
+
+# Flags to create an archive.
+AR_FLAGS=$lt_AR_FLAGS
+
+# How to feed a file listing to the archiver.
+archiver_list_spec=$lt_archiver_list_spec
+
+# 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
+
+# Whether to use a lock for old archive extraction.
+lock_old_archive_extraction=$lock_old_archive_extraction
+
+# 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
+
+# Specify filename containing input files for \$NM.
+nm_file_list_spec=$lt_nm_file_list_spec
+
+# The root where to search for dependent libraries,and in which our libraries should be installed.
+lt_sysroot=$lt_sysroot
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# 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
+
+# Manifest tool.
+MANIFEST_TOOL=$lt_MANIFEST_TOOL
+
+# 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
+
+# Permission mode override for installation of shared libraries.
+install_override_mode=$lt_install_override_mode
+
+# 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
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag
+reload_cmds=$lt_reload_cmds
+
+# 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
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_lt_prog_compiler_pic
+
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl
+
+# 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
+
+# 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
+
+# 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
+
+# Commands necessary for finishing linking programs.
+postlink_cmds=$lt_postlink_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 '$q' "$ltmain" >> "$cfgfile" \
+     || (rm -f "$cfgfile"; exit 1)
+
+  if test x"$xsi_shell" = xyes; then
+  sed -e '/^func_dirname ()$/,/^} # func_dirname /c\
+func_dirname ()\
+{\
+\    case ${1} in\
+\      */*) func_dirname_result="${1%/*}${2}" ;;\
+\      *  ) func_dirname_result="${3}" ;;\
+\    esac\
+} # Extended-shell func_dirname implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_basename ()$/,/^} # func_basename /c\
+func_basename ()\
+{\
+\    func_basename_result="${1##*/}"\
+} # Extended-shell func_basename implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_dirname_and_basename ()$/,/^} # func_dirname_and_basename /c\
+func_dirname_and_basename ()\
+{\
+\    case ${1} in\
+\      */*) func_dirname_result="${1%/*}${2}" ;;\
+\      *  ) func_dirname_result="${3}" ;;\
+\    esac\
+\    func_basename_result="${1##*/}"\
+} # Extended-shell func_dirname_and_basename implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_stripname ()$/,/^} # func_stripname /c\
+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}"}\
+} # Extended-shell func_stripname implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_split_long_opt ()$/,/^} # func_split_long_opt /c\
+func_split_long_opt ()\
+{\
+\    func_split_long_opt_name=${1%%=*}\
+\    func_split_long_opt_arg=${1#*=}\
+} # Extended-shell func_split_long_opt implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_split_short_opt ()$/,/^} # func_split_short_opt /c\
+func_split_short_opt ()\
+{\
+\    func_split_short_opt_arg=${1#??}\
+\    func_split_short_opt_name=${1%"$func_split_short_opt_arg"}\
+} # Extended-shell func_split_short_opt implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_lo2o ()$/,/^} # func_lo2o /c\
+func_lo2o ()\
+{\
+\    case ${1} in\
+\      *.lo) func_lo2o_result=${1%.lo}.${objext} ;;\
+\      *)    func_lo2o_result=${1} ;;\
+\    esac\
+} # Extended-shell func_lo2o implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_xform ()$/,/^} # func_xform /c\
+func_xform ()\
+{\
+    func_xform_result=${1%.*}.lo\
+} # Extended-shell func_xform implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_arith ()$/,/^} # func_arith /c\
+func_arith ()\
+{\
+    func_arith_result=$(( $* ))\
+} # Extended-shell func_arith implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_len ()$/,/^} # func_len /c\
+func_len ()\
+{\
+    func_len_result=${#1}\
+} # Extended-shell func_len implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+fi
+
+if test x"$lt_shell_append" = xyes; then
+  sed -e '/^func_append ()$/,/^} # func_append /c\
+func_append ()\
+{\
+    eval "${1}+=\\${2}"\
+} # Extended-shell func_append implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_append_quoted ()$/,/^} # func_append_quoted /c\
+func_append_quoted ()\
+{\
+\    func_quote_for_eval "${2}"\
+\    eval "${1}+=\\\\ \\$func_quote_for_eval_result"\
+} # Extended-shell func_append_quoted implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  # Save a `func_append' function call where possible by direct use of '+='
+  sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \
+    && mv -f "$cfgfile.tmp" "$cfgfile" \
+      || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+  test 0 -eq $? || _lt_function_replace_fail=:
+else
+  # Save a `func_append' function call even when '+=' is not available
+  sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \
+    && mv -f "$cfgfile.tmp" "$cfgfile" \
+      || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+  test 0 -eq $? || _lt_function_replace_fail=:
+fi
+
+if test x"$_lt_function_replace_fail" = x":"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to substitute extended shell functions in $ofile" >&5
+$as_echo "$as_me: WARNING: Unable to substitute extended shell functions in $ofile" >&2;}
+fi
+
+
+   mv -f "$cfgfile" "$ofile" ||
+    (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
+  chmod +x "$ofile"
+
+ ;;
+
+  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 1
+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/omalloc/configure.ac b/omalloc/configure.ac
new file mode 100644
index 0000000..90defe1
--- /dev/null
+++ b/omalloc/configure.ac
@@ -0,0 +1,624 @@
+dnl lllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll
+dnl File: configure.ac
+dnl Purpose: Process this file with autoconf to produce configure
+dnl Author:  obachman at mathematik.uni-kl.de (Olaf Bachmann)
+dnl Created: 11/99
+dnl lllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll
+
+AC_INIT([omalloc],[0.9.6])
+
+AC_CONFIG_MACRO_DIR([../m4])
+AC_CONFIG_AUX_DIR([../build-aux])
+AC_CONFIG_SRCDIR(om_Alloc.c)
+AC_CONFIG_HEADER([_config.h])
+
+SING_RESET_FLAGS()
+
+AM_MAINTAINER_MODE([enable])
+AM_INIT_AUTOMAKE([-Wall foreign subdir-objects]) # -Wno-extra-portability -Werror silent-rules
+m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
+m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
+
+AM_SANITY_CHECK
+
+# Add pre'prefixed config
+AX_PREFIX_CONFIG_H([omConfig.h],[],[_config.h])
+
+# SING_CHECK_SET_ARGS()
+
+AC_SUBST(VERSION)
+
+dnl lllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll
+dnl help for configure
+dnl
+
+AC_ARG_WITH(
+  external-config_h,
+  [ --with-external-config_h=HEADER_FILE
+                    use HEADER_FILE for external configuration])
+AC_ARG_WITH(
+  external-config_c,
+  [ --with-external-config_c=C_FILE
+                    use C_FILE for external implementations])
+AC_ARG_WITH(
+  malloc,
+  [ --with-malloc=system|external
+                    which malloc to use, default: malloc ])
+AC_ARG_WITH(
+  external-malloc_h,
+  [ --with-external-malloc-h=HEADER_FILE
+		    use HEADER_FILE for external malloc declaration])
+AC_ARG_WITH(
+  external-malloc_c,
+  [ --with-external-malloc-c=C_FILE
+		    use C_FILE for external malloc implementation])
+AC_ARG_WITH(
+  valloc,
+  [ --with-valloc=mmap|system|emulate
+                    how to get page-aligned memory, default: use first possible])
+AC_ARG_WITH(
+  align,
+  [ --with-align=8|sloppy|strict
+                    how memory is aligned,
+                    default: if possible sloppy, else strict])
+AC_ARG_WITH(
+  dense-bins,
+  [ --with-dense-bins  use dense bin distribution])
+AC_ARG_WITH(
+  inline,
+  [ --without-inline   do not inline])
+AC_ARG_WITH(
+  debug,
+  [ --without-debug    disable all debugging facilities])
+AC_ARG_WITH(
+  track,
+  [ --without-track    disable debug tracking functionality])
+AC_ARG_WITH(
+  track-fl,
+  [ --with-track-fl    track file and line numbers])
+AC_ARG_WITH(
+  track-return,
+  [ --with-track-return track return addresses])
+AC_ARG_WITH(
+  track-backtrace,
+  [ --with-track-backtrace track stack backtraces])
+AC_ARG_WITH(
+  track-custom,
+  [ --with-track-custom track custom values])
+AC_ARG_WITH(
+  internal_debug,
+  [ --with-internal-debug
+                       turn on internal debugging])
+dnl lllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll
+dnl compiler/make  config
+dnl
+dnl I'm not sure why I did this
+dnl if test "${CFLAGS+set}" != set; then
+dnl  CFLAGS="-O"
+dnl  ac_cflags_set=no
+dnl fi
+
+CPPFLAGS="-I.. -I."
+AC_PROG_MAKE_SET
+AC_PROG_CC
+AC_PROG_CPP
+
+AC_PROG_LN_S
+AC_PROG_INSTALL
+AM_PROG_CC_C_O
+# AM_PROG_AR
+AC_C_CONST
+AC_C_INLINE
+
+LT_INIT
+
+
+dnl lllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll
+dnl check for programs
+dnl
+AC_CHECK_PROG(AR, ar, ar, :)
+if test "$ac_cv_prog_AR" != ar; then
+  AC_MSG_ERROR(*** ar program not found)
+fi
+AC_CHECK_PROGS(PERL, perl, "no")
+if test "$ac_cv_prog_PERL" = no; then
+  AC_MSG_ERROR(*** perl program not found)
+fi
+
+AC_CHECK_PROG(ADDR2LINE, addr2line, addr2line, no)
+if test "$ac_cv_prog_ADDR2LINE" = addr2line; then
+  AC_DEFINE_UNQUOTED(OM_PROG_ADDR2LINE, "$ac_cv_prog_ADDR2LINE", "Name of addr2line")
+fi
+
+dnl lllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll
+dnl header file checks
+dnl
+AC_HEADER_STDC
+AC_CHECK_HEADERS(limits.h,,
+  AC_MSG_ERROR(Can not compile without limits.h))
+
+AC_CHECK_HEADERS(unistd.h sys/mman.h fcntl.h /usr/include/malloc.h)
+
+AC_CHECK_FUNCS(popen mmap sbrk random)
+
+dnl llllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll
+dnl Find out more about particularity of the system
+dnl
+
+# sizes
+AC_CHECK_SIZEOF(long,4)
+AC_CHECK_SIZEOF(void*,4)
+AC_CHECK_SIZEOF(double, 8)
+AC_CHECK_SIZEOF(size_t, 4)
+
+if test "$ac_cv_sizeof_long" != "$ac_cv_sizeof_voidp"; then
+  AC_MSG_ERROR(need equal sizes for long and void*)
+fi
+if test "$ac_cv_sizeof_voidp" != 4 && test "$ac_cv_sizeof_voidp" != 8; then
+  AC_MSG_ERROR(need void* to be 4 or 8 bytes long)
+fi
+if test "$ac_cv_sizeof_double" != 4 && test "$ac_cv_sizeof_double" != 8; then
+  AC_MSG_ERROR(need double to be 4 or 8 bytes long)
+fi
+
+dnl Set compiler, linker flags so that we can work with omalloc
+BACKUP_CFLAGS=$CFLAGS
+BACKUP_CXXFLAGS=$CXXFLAGS
+BACKUP_LDFLAGS=$LDFLAGS
+
+CFLAGS="$CFLAGS -I$srcdir"
+CXXFLAGS="$CXXFLAGS -I$srcdir"
+
+dnl lllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll
+dnl figure out page size of the system
+dnl
+AC_MSG_CHECKING(size of system page)
+AC_CACHE_VAL(ac_cv_pagesize,
+AC_TRY_RUN([#include <stdio.h>
+#include <stdlib.h>
+#include "omGetPageSize.h"
+
+int main()
+{
+  FILE *f=fopen("conftestval", "w");
+  if (!f) exit(1);
+  fprintf(f, "%d\n", omalloc_getpagesize);
+  exit(0);
+}], ac_cv_pagesize=`cat conftestval`, ac_cv_pagesize=0, ac_cv_pagesize=0))
+# can not really handle pagesizes which are greater -- there must be a
+# bug somewhere
+if test $ac_cv_pagesize -gt 8192; then
+  ac_cv_pagesize=8192
+fi
+AC_MSG_RESULT($ac_cv_pagesize)
+if test "$ac_cv_pagesize" = 4096 || test "$ac_cv_pagesize" = 8192; then
+  AC_DEFINE_UNQUOTED(SIZEOF_SYSTEM_PAGE, $ac_cv_pagesize, "Page-size of the build-system")
+else
+AC_MSG_ERROR([need sytem page to be of size 4096 or 8192, but is $ac_cv_pagesize])
+fi
+
+AC_DEFINE_UNQUOTED(SIZEOF_OM_PAGE,SIZEOF_SYSTEM_PAGE,Page-size of the build-system)
+
+dnl lllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll
+dnl check whether mmap actually works
+dnl
+if test "$ac_cv_func_mmap" = yes; then
+AC_MSG_CHECKING(whether mmap works)
+AC_CACHE_VAL(ac_cv_working_mmap,
+AC_TRY_RUN([
+#include <stdlib.h>
+#include "omMmap.c"
+int main()
+{
+  void* addr = omVallocMmap(128*${ac_cv_pagesize});
+  if (addr == 0 || ((unsigned long) addr % ${ac_cv_pagesize}))
+    exit(1);
+  exit(omVfreeMmap(addr, 128*${ac_cv_pagesize}));
+}], ac_cv_working_mmap=yes, ac_cv_working_mmap=no, ac_cv_working_mmap=no))
+AC_MSG_RESULT($ac_cv_working_mmap)
+if test "$ac_cv_working_mmap" = yes; then
+  AC_DEFINE(HAVE_WORKING_MMAP,1,"Whether we have a working mmap")
+fi
+fi
+
+dnl lllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll
+dnl for strict alignment
+dnl
+AC_CACHE_CHECK(whether alignment needs to be strict, ac_cv_align_need_strict,
+AC_TRY_RUN([
+#include <stdlib.h>
+int main()
+{
+  void* ptr = (void*) malloc(12);
+  volatile double* d_ptr;
+  if ((unsigned long) ptr % 8 == 0) ptr = ptr + 4;
+  d_ptr = (double*) ptr;
+  *d_ptr = (double) 1.25;
+  if (*d_ptr != (double) 1.25) exit(1);
+  else exit(0);
+}
+], ac_cv_align_need_strict=no, ac_cv_align_need_strict=yes, ac_cv_align_need_strict=yes))
+
+dnl lllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll
+dnl external config files
+dnl
+AC_MSG_CHECKING(for external config files)
+if test "${with_external_config_h+set}" = set; then
+    AC_DEFINE(OM_HAVE_EXTERNAL_CONFIG_H,1,"Whether we have external config.h")
+    EXTERNAL_CONFIG_HEADER=${with_external_config_h}
+    rm -f omExternalConfig.h
+    cp ${with_external_config_h} omExternalConfig.h
+fi
+if test "${with_external_config_c+set}" = set; then
+    AC_DEFINE(OM_HAVE_EXTERNAL_CONFIG_C,1,"Wether we have an external config.c")
+    EXTERNAL_CONFIG_SOURCE=${with_external_config_c}
+fi
+AC_SUBST(EXTERNAL_CONFIG_HEADER)
+AC_SUBST(EXTERNAL_CONFIG_SOURCE)
+if test "${EXTERNAL_CONFIG_HEADER+set}" = set || test "${EXTERNAL_CONFIG_SOURCE+set}" = set; then
+AC_MSG_RESULT(${EXTERNAL_CONFIG_HEADER} ${EXTERNAL_CONFIG_SOURCE})
+else
+AC_MSG_RESULT(none)
+fi
+
+dnl lllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll
+dnl for malloc
+dnl
+AC_MSG_CHECKING(which malloc to use)
+if test "${with_malloc}" = system; then
+  OM_MALLOC_HEADER=omMallocSystem.h
+  AC_DEFINE(OMALLOC_USES_MALLOC,1,the system allocator is called malloc)
+  AC_DEFINE(OMALLOC_USES_SYSTEM_MALLOC,1,use system malloc as system allocator)
+elif test "${with_malloc}" = external; then
+  if test "${with_external_malloc_h+set}" != set; then
+    AC_MSG_ERROR(need --with_external_malloc_h for external malloc)
+  fi
+  AC_DEFINE(OMALLOC_USES_EXTERNAL_MALLOC,1,use external malloc as system allocator)
+  OM_MALLOC_HEADER=$with_external_malloc_h
+  OM_MALLOC_SOURCE=$with_external_malloc_c
+  AC_DEFINE(OMALLOC_USES_MALLOC,1,the system allocator is called malloc)
+else	## default
+  OM_MALLOC_HEADER=omMallocSystem.h
+  AC_DEFINE(OMALLOC_USES_MALLOC,1,the system allocator is called malloc)
+  AC_DEFINE(OMALLOC_USES_SYSTEM_MALLOC,1,use system malloc as system allocator)
+fi
+AC_MSG_RESULT($with_malloc)
+
+AC_SUBST(OM_MALLOC_HEADER)
+AC_SUBST(OM_MALLOC_SOURCE)
+if test "${OM_MALLOC_SOURCE+set}" = set; then
+  AC_DEFINE(OM_HAVE_MALLOC_SOURCE,1,"Whether we have the source for malloc ()")
+fi
+
+AC_MSG_CHECKING(whether malloc provides SizeOfAddr)
+if test "${ac_cv_malloc_sizeof_addr}" = no; then
+  AC_MSG_RESULT( (cached) no)
+elif test "${ac_cv_malloc_sizeof_addr}" = "${OM_MALLOC_HEADER}_${OM_MALLOC_SOURCE}"; then
+   AC_MSG_RESULT( (cached) yes)
+else
+AC_TRY_RUN([
+#include <stdlib.h>
+#include "$OM_MALLOC_HEADER"
+#ifdef OM_HAVE_MALLOC_SOURCE
+#include "$OM_MALLOC_SOURCE"
+#endif
+
+int main()
+{
+  void* addr = OM_MALLOC_MALLOC(512);
+#ifdef OM_MALLOC_SIZEOF_ADDR
+  if (OM_MALLOC_SIZEOF_ADDR(addr) < 512)
+    exit(1);
+  exit(0);
+#else
+  exit(1);
+#endif
+}
+], ac_cv_malloc_sizeof_addr="${OM_MALLOC_HEADER}_${OM_MALLOC_SOURCE}", ac_cv_malloc_sizeof_addr=no, ac_cv_malloc_sizeof_addr=no)
+if test "${ac_cv_malloc_sizeof_addr}" = no; then
+AC_MSG_RESULT(no)
+else
+AC_MSG_RESULT(yes)
+fi
+fi
+if test "$ac_cv_malloc_sizeof_addr" != no; then
+AC_DEFINE(OM_MALLOC_PROVIDES_SIZEOF_ADDR,1,"Whether malloc provides SIZEOF_ADDR")
+fi
+
+dnl lllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll
+dnl check whether valloc is provided and that it works
+dnl
+AC_MSG_CHECKING(whether working valloc exists)
+if test "${ac_cv_working_valloc}" = no; then
+  AC_MSG_RESULT( (cached) no)
+elif test "${ac_cv_working_valloc}" = "${OM_MALLOC_HEADER}_${OM_MALLOC_SOURCE}"; then
+  AC_MSG_RESULT( (cached) yes)
+else
+AC_TRY_RUN([
+#include <stdlib.h>
+#include "$OM_MALLOC_HEADER"
+#ifdef OM_HAVE_MALLOC_SOURCE
+#include "$OM_MALLOC_SOURCE"
+#endif
+
+int main()
+{
+  void* addr = OM_MALLOC_VALLOC(128*${ac_cv_pagesize});
+  if (addr == 0 || ((unsigned long) addr % ${ac_cv_pagesize}))
+    exit(1);
+  OM_MALLOC_VFREE(addr, 128*${ac_cv_pagesize});
+  exit(0);
+}
+], ac_cv_working_valloc="${OM_MALLOC_HEADER}_${OM_MALLOC_SOURCE}", ac_cv_working_valloc=no, ac_cv_working_valloc=no)
+if test "${ac_cv_working_valloc}" = no; then
+AC_MSG_RESULT(no)
+else
+AC_MSG_RESULT(yes)
+fi
+fi
+
+dnl lllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll
+dnl for valloc
+dnl
+AC_MSG_CHECKING(which valloc to use)
+if test "${with_valloc+set}" != set || test "${with_valloc}" = mmap; then
+  if test "${ac_cv_working_mmap}" = yes; then
+    with_valloc=mmap
+    AC_DEFINE(OM_HAVE_VALLOC_MMAP,1,"Have valloc")
+  else
+    with_valloc=malloc
+  fi
+fi
+if test "${with_valloc}" = malloc; then
+  if test "${ac_cv_working_valloc}" != no; then
+    AC_DEFINE(OM_HAVE_VALLOC_MALLOC,1,"Have valloc")
+  else
+    with_valloc=emulate
+  fi
+fi
+AC_MSG_RESULT($with_valloc)
+
+dnl lllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll
+dnl alignment
+dnl
+AC_MSG_CHECKING(how to align)
+if test "$with_align" = 8 || test "$ac_cv_sizeof_long" = 8; then
+  ac_cv_align=8
+  AC_DEFINE(OM_ALIGN_8,1,"Align to 8 bytes")
+else
+if test "$ac_cv_align_need_strict" = "yes" || test "$with_align" = "strict"; then
+  AC_DEFINE(OM_ALIGNMENT_NEEDS_WORK,1,"Whether alignment needs work")
+  ac_cv_align="strict"
+else
+  ac_cv_align="sloppy"
+fi
+fi
+AC_MSG_RESULT($ac_cv_align)
+
+dnl lllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll
+dnl dense bins
+dnl
+AC_MSG_CHECKING(whether to use dense bins)
+if test "$with_dense_bins" = yes; then
+AC_MSG_RESULT(yes)
+AC_DEFINE(OM_HAVE_DENSE_BIN_DISTRIBUTION,1,"Whether we have dense bins")
+else
+AC_MSG_RESULT(no)
+fi
+
+dnl lllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll
+dnl debug and inline
+dnl
+save_cflags="$CFLAGS"
+AC_MSG_CHECKING(whether to disable debugging)
+if test "$with_debug" != no; then
+AC_MSG_RESULT(no)
+CFLAGS="$CFLAGS -g"
+else
+AC_MSG_RESULT(yes)
+AC_DEFINE(OM_NDEBUG,1,"Disable debug")
+with_track=no
+fi
+AM_CONDITIONAL([WANT_DEBUG],[test x"$with_debug" = xyes])
+
+AC_MSG_CHECKING(whether to have tracking debug functionality)
+if test "$with_track" != no; then
+AC_MSG_RESULT(yes)
+AC_DEFINE(OM_HAVE_TRACK,1,"Have track")
+else
+AC_MSG_RESULT(no)
+fi
+
+AC_MSG_CHECKING(whether to use internal debug)
+if test "$with_internal_debug" = yes; then
+AC_MSG_RESULT(yes)
+AC_DEFINE(OM_INTERNAL_DEBUG,1,"Internal debug")
+with_inline=no
+else
+AC_MSG_RESULT(no)
+fi
+
+AC_MSG_CHECKING(whether to inline)
+if test "$ac_cv_c_inline" != no && test "$with_inline" != no; then
+  AC_DEFINE_UNQUOTED(OM_INLINE, static $ac_cv_c_inline, "inline-declaration")
+  AC_DEFINE_UNQUOTED(OM_INLINE_DECL, static $ac_cv_c_inline, "inline-declaration")
+  AC_DEFINE_UNQUOTED(OM_INLINE_IMPL, static $ac_cv_c_inline, "inline-declaration")
+  AC_DEFINE_UNQUOTED(OM_INLINE_LOCAL, static $ac_cv_c_inline, "inline-declaration")
+  AC_MSG_RESULT(yes)
+else
+  AC_DEFINE_UNQUOTED(OM_INLINE_DECL, extern, "inline-declaration")
+  AC_DEFINE_UNQUOTED(OM_INLINE_IMPL,, "inline-declaration")
+  AC_DEFINE_UNQUOTED(OM_INLINE_LOCAL, static, "inline-declaration")
+  AC_MSG_RESULT(no)
+fi
+
+dnl lllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll
+dnl backtrace business
+dnl
+AC_MSG_CHECKING(whether GET_RET_ADDR works)
+AC_CACHE_VAL(ac_cv_get_return_addr_works,
+AC_TRY_RUN([
+#include <stdlib.h>
+#include "omReturn.h"
+int test_return_addr()
+{
+  char* f;
+  GET_RET_ADDR(f);
+  return (int)(long) f;
+}
+int main()
+{
+   exit(! test_return_addr());
+}
+], ac_cv_get_return_addr_works=yes,
+   ac_cv_get_return_addr_works=no,
+   ac_cv_get_return_addr_works=no))
+AC_MSG_RESULT($ac_cv_get_return_addr_works)
+if test "$ac_cv_get_return_addr_works" = yes; then
+AC_DEFINE(OM_GET_RETURN_ADDR_WORKS,1, "Whether get return address works")
+fi
+
+AC_MSG_CHECKING(whether omGetBackTrace works)
+AC_CACHE_VAL(ac_cv_get_backtrace_works,
+AC_TRY_RUN([
+#include <stdio.h>
+#include <stdlib.h>
+#include "omGetBackTrace.c"
+int test_backtrace0()
+{
+  void* bt @<:@ 10 @:>@ ;
+  int i = omGetBackTrace(bt, 0, 10);
+  return i;
+}
+int test_backtrace(){ return test_backtrace0(); }
+int main()
+{
+   int i;
+   #ifdef __APPLE__
+   /* omGetBackTrace crashes on OsX for i>2 */
+   i=0;
+   #else
+   omInitGetBackTrace();
+   i = test_backtrace();
+   #endif
+   if (i > 0) exit(0);
+   else exit(i+10);
+}
+], ac_cv_get_backtrace_works=yes,
+   ac_cv_get_backtrace_works=no,
+   ac_cv_get_backtrace_works=no))
+AC_MSG_RESULT($ac_cv_get_backtrace_works)
+if test "$ac_cv_get_backtrace_works" = yes; then
+AC_DEFINE(OM_GET_BACKTRACE_WORKS,1,"Whether omInitGetBackTrace () works")
+fi
+
+AC_MSG_CHECKING(whether addr2line works)
+AC_CACHE_VAL(ac_cv_prog_addr2line_works,
+AC_TRY_RUN([
+#include <stdlib.h>
+#include "omReturn.h"
+#include "omStructs.h"
+/* #include "omGetBackTrace.h" */
+#include "omGetBackTrace.c"
+#include "omRet2Info.c"
+
+int test_Ret_2_Info()
+{
+  void* bt;
+  int i;
+  struct omRetInfo_s info;
+
+  GET_RET_ADDR(bt);
+  i = omBackTrace_2_RetInfo(&bt, &info, 1);
+  return i;
+}
+
+int main(int argc, char** argv)
+{
+  int i;
+  omInitRet_2_Info(*argv);
+  i = test_Ret_2_Info();
+  if (i==1) exit(0);
+  else exit (i+10);
+}
+], ac_cv_prog_addr2line_works=yes,
+   ac_cv_prog_addr2line_works=no,
+   ac_cv_prog_addr2line_works=no))
+AC_MSG_RESULT($ac_cv_prog_addr2line_works)
+
+CFLAGS="$save_cflags"
+
+AC_MSG_CHECKING(whether to track return addresses)
+if test "$with_track_return" = no || test "$ac_cv_get_return_addr_works" = no || test "$ac_cv_prog_addr2line_works" != yes; then
+  with_track_return=no
+else
+  AC_DEFINE(OM_TRACK_RETURN,1,"Whether to track return")
+  with_track_return=yes
+fi
+AC_MSG_RESULT($with_track_return)
+
+AC_MSG_CHECKING(whether to track files and line numbers)
+if test "$with_track_fl" = no && test "$with_track_return" = no; then
+  with_track_fl=yes
+fi
+if test "${with_track_fl+set}" != set; then
+  if test "$with_track_return" = yes; then
+    with_track_fl=no
+  else
+    with_track_fl=yes
+  fi
+fi
+AC_MSG_RESULT($with_track_fl)
+if test "$with_track_fl" = yes; then
+  AC_DEFINE(OM_TRACK_FILE_LINE,1,"Whether to track file-line")
+fi
+
+AC_MSG_CHECKING(whether to track stack backtraces)
+if test "$with_track" != no && test "$ac_cv_get_backtrace_works" = yes && test "$with_track_backtrace" != no && test "$ac_cv_prog_addr2line_works" = yes; then
+  with_track_backtrace=yes
+  AC_DEFINE(OM_TRACK_BACKTRACE,1,"Whether to track backtrace")
+else
+  with_track_backtrace=no
+fi
+AC_MSG_RESULT($with_track_backtrace)
+
+AC_MSG_CHECKING(whether to track custom values)
+if test "$with_track" != no && test "$with_track_custom" = yes; then
+  AC_DEFINE(OM_TRACK_CUSTOM,1,"Enable custom tracking")
+else
+  with_track_custom=no
+fi
+AC_MSG_RESULT($with_track_custom)
+
+dnl lllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll
+dnl figure out the return type of sbrk
+dnl
+
+AC_MSG_CHECKING(return type of sbrk)
+AC_TRY_LINK(
+#define __USE_MISC
+#include <unistd.h>
+,
+void *sbrk();
+,
+AC_DEFINE(Void_t,void,"Type of void"),
+AC_DEFINE(Void_t,char,"Type of void"),
+)
+AC_MSG_RESULT(Void_t)
+
+
+AC_DEFINE(OM_PROVIDE_MALLOC,0,[Provide NO standard routines!])
+
+
+dnl Restore user-specified CFLAGS, CXXFLAGS, LIBS
+
+CFLAGS=$BACKUP_CFLAGS
+CXXFLAGS=$BACKUP_CXXFLAGS
+LDFLAGS=$BACKUP_LDFLAGS
+
+dnl lllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll
+dnl wrap it up
+dnl
+AC_CONFIG_FILES([Makefile omalloc.pc])
+AC_OUTPUT
+
diff --git a/omalloc/mylimits.h b/omalloc/mylimits.h
new file mode 100644
index 0000000..80c1e17
--- /dev/null
+++ b/omalloc/mylimits.h
@@ -0,0 +1,14 @@
+/* -*-c++-*- */
+/*******************************************************************
+ *  File:    mylimits.h
+ *  Purpose: limits.h configuration for omalloc
+ *  Author:  hannes (Hans Schoenemann)
+ *  Created: 03/01
+ *******************************************************************/
+
+#ifndef _MYLIMITS_H
+#define _MYLIMITS_H
+
+#include <limits.h>
+
+#endif /* _MYLIMITS_H */
diff --git a/omalloc/omAllocDecl.h b/omalloc/omAllocDecl.h
new file mode 100644
index 0000000..c7d7bc0
--- /dev/null
+++ b/omalloc/omAllocDecl.h
@@ -0,0 +1,374 @@
+/*******************************************************************
+ *  File:    omAllocDecl.h
+ *  Purpose: declaration of Alloc routines
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 11/99
+ *******************************************************************/
+#ifndef OM_ALLOC_DECL_H
+#define OM_ALLOC_DECL_H
+
+#if (!defined(OM_NDEBUG) && (defined(OM_CHECK) || (defined(OM_HAVE_TRACK) && defined(OM_TRACK)))) || defined(OM_T1)
+
+/*******************************************************************
+ *
+ * Alloc/Free/Check for Debug
+ *
+ *******************************************************************/
+#ifndef OM_CHECK
+#define OM_CHECK    0
+#endif
+#ifndef OM_TRACK
+#define OM_TRACK    0
+#endif
+
+#if OM_KEEP > 0
+#define _OM_FKEEP OM_FKEEP
+#else
+#define _OM_FKEEP 0
+#endif
+
+#if !defined(OM_T_ALLOC)
+#define omTypeAllocBin(type,addr,bin)           addr=(type)_omDebugAlloc(bin,OM_FBIN|_OM_FKEEP,OM_CTFL)
+#define omTypeAlloc0Bin(type,addr,bin)          addr=(type)_omDebugAlloc(bin,OM_FBIN|OM_FZERO|_OM_FKEEP,OM_CTFL)
+#define omAllocBin(bin)                         _omDebugAlloc(bin,OM_FBIN|_OM_FKEEP,OM_CTFL)
+#define omAlloc0Bin(bin)                        _omDebugAlloc(bin,OM_FBIN|OM_FZERO|_OM_FKEEP,OM_CTFL)
+
+#define omTypeAlloc(type,addr,size)             addr=(type)_omDebugAlloc((void*)(size),OM_FSIZE|_OM_FKEEP,OM_CTFL)
+#define omTypeAlloc0(type,addr,size)            addr=(type)_omDebugAlloc((void*)(size),OM_FSIZE|OM_FZERO|_OM_FKEEP,OM_CTFL)
+#define omAlloc(size)                           _omDebugAlloc((void*)(size),OM_FSIZE|_OM_FKEEP,OM_CTFL)
+#define omAlloc0(size)                          _omDebugAlloc((void*)(size),OM_FSIZE|OM_FZERO|_OM_FKEEP,OM_CTFL)
+
+#define omalloc(size)   _omDebugAlloc((void*)(size),OM_FSIZE|OM_FSLOPPY|OM_FALIGN|_OM_FKEEP,OM_CTFL)
+#define omalloc0(size)  _omDebugAlloc((void*)(size),OM_FSIZE|OM_FZERO|OM_FSLOPPY|OM_FALIGN|_OM_FKEEP,OM_CTFL)
+
+#else
+#define omTypeAllocBin(type,addr,bin)           __omTypeAllocBin(type,addr,bin)
+#define omTypeAlloc0Bin(type,addr,bin)          __omTypeAlloc0Bin(type,addr,bin)
+#define omAllocBin(bin)                         _omAllocBin(bin)
+#define omAlloc0Bin(bin)                        _omAlloc0Bin(bin)
+
+#define omTypeAlloc(type,addr,size)             __omTypeAlloc(type,addr,size)
+#define omTypeAlloc0(type,addr,size)            __omTypeAlloc0(type,addr,size)
+#define omAlloc(size)                           _omAlloc(size)
+#define omAlloc0(size)                          _omAlloc0(size)
+
+#define omalloc(size)   _omalloc(size)
+#define omalloc0(size)  _omalloc0(size)
+
+#endif
+
+#if !defined(OM_T_REALLOC)
+#define omTypeReallocBin(o_addr,o_bin,type,addr,bin)            addr=(type)_omDebugRealloc(o_addr,o_bin,bin,OM_FBIN|_OM_FKEEP,OM_FBIN|_OM_FKEEP,OM_CTFL)
+#define omTypeRealloc0Bin(o_addr,o_bin,type,addr,bin)           addr=(type)_omDebugRealloc(o_addr,o_bin,bin,OM_FBIN|_OM_FKEEP,OM_FBIN|OM_FZERO|_OM_FKEEP,OM_CTFL)
+#define omReallocBin(o_addr,o_bin,bin)                          _omDebugRealloc(o_addr,o_bin,bin,OM_FBIN|_OM_FKEEP,OM_FBIN|_OM_FKEEP,OM_CTFL)
+#define omRealloc0Bin(o_addr,o_bin,bin)                         _omDebugRealloc(o_addr,o_bin,bin,OM_FBIN|_OM_FKEEP,OM_FBIN|OM_FZERO|_OM_FKEEP,OM_CTFL)
+
+#define omTypeReallocSize(o_addr,o_size,type,addr,size)         addr=(type)_omDebugRealloc(o_addr,(void*)(o_size),(void*)(size),OM_FSIZE|_OM_FKEEP,OM_FSIZE|_OM_FKEEP,OM_CTFL)
+#define omTypeRealloc0Size(o_addr,o_size,type,addr,size)        addr=(type)_omDebugRealloc(o_addr,(void*)(o_size),(void*)(size),OM_FSIZE|_OM_FKEEP,OM_FSIZE|OM_FZERO|_OM_FKEEP,OM_CTFL)
+#define omReallocSize(addr,o_size,size)                         _omDebugRealloc(addr,(void*)(o_size),(void*)(size),OM_FSIZE|_OM_FKEEP,OM_FSIZE|_OM_FKEEP,OM_CTFL)
+#define omRealloc0Size(addr,o_size,size)                        _omDebugRealloc(addr,(void*)(o_size),(void*)(size),OM_FSIZE|_OM_FKEEP,OM_FSIZE|OM_FZERO|_OM_FKEEP,OM_CTFL)
+
+#define omTypeRealloc(o_addr,type,addr,size)                    addr=(type)_omDebugRealloc(o_addr,NULL,(void*)(size),_OM_FKEEP,OM_FSIZE|_OM_FKEEP,OM_CTFL)
+#define omTypeRealloc0(o_addr,type,addr,size)                   addr=(type)_omDebugRealloc(o_addr,NULL,(void*)(size),_OM_FKEEP,OM_FSIZE|OM_FZERO|_OM_FKEEP,OM_CTFL)
+#define omRealloc(addr,size)                                    _omDebugRealloc(addr,NULL,(void*)(size),_OM_FKEEP,OM_FSIZE,OM_CTFL)
+#define omRealloc0(addr,size)                                   _omDebugRealloc(addr,NULL,(void*)(size),_OM_FKEEP,OM_FSIZE|OM_FZERO,OM_CTFL)
+
+#define omreallocSize(addr,o_size,size) _omDebugRealloc(addr,(void*)(o_size),(void*)(size),OM_FSIZE|OM_FSLOPPY|_OM_FKEEP,OM_FSIZE|OM_FSLOPPY|OM_FALIGN|_OM_FKEEP,OM_CTFL)
+#define omrealloc0Size(addr,o_size,size)_omDebugRealloc(addr,(void*)(o_size),(void*)(size),OM_FSIZE|OM_FSLOPPY|_OM_FKEEP,OM_FSIZE|OM_FZERO|OM_FSLOPPY|OM_FALIGN|_OM_FKEEP,OM_CTFL)
+#define omrealloc(addr,size)            _omDebugRealloc(addr,NULL,(void*)(size),OM_FSLOPPY|_OM_FKEEP,OM_FSIZE|OM_FSLOPPY|OM_FALIGN|_OM_FKEEP,OM_CTFL)
+#define omrealloc0(addr,size)           _omDebugRealloc(addr,NULL,(void*)(size),OM_FSLOPPY|_OM_FKEEP,OM_FSIZE|OM_FZERO|OM_FSLOPPY|OM_FALIGN|_OM_FKEEP,OM_CTFL)
+
+#else
+#define omTypeReallocBin(o_addr,o_bin,type,addr,bin)            __omTypeReallocBin(o_addr,o_bin,type,addr,bin)
+#define omTypeRealloc0Bin(o_addr,o_bin,type,addr,bin)           __omTypeRealloc0Bin(o_addr,o_bin,type,addr,bin)
+#define omReallocBin(o_addr,o_bin,bin)                          _omReallocBin(o_addr,o_bin,bin)
+#define omRealloc0Bin(o_addr,o_bin,bin)                         _omRealloc0Bin(o_addr,o_bin,bin)
+
+#define omTypeReallocSize(o_addr,o_size,type,addr,size)         __omTypeReallocSize(o_addr,o_size,type,addr,size)
+#define omTypeRealloc0Size(o_addr,o_size,type,addr,size)        __omTypeRealloc0Size(o_addr,o_size,type,addr,size)
+#define omReallocSize(addr,o_size,size)                         _omReallocSize(addr,o_size,size)
+#define omRealloc0Size(addr,o_size,size)                        _omRealloc0Size(addr,o_size,size)
+
+#define omTypeRealloc(o_addr,type,addr,size)                    __omTypeRealloc(o_addr,type,addr,size)
+#define omTypeRealloc0(o_addr,type,addr,size)                   __omTypeRealloc0(o_addr,type,addr,size)
+#define omRealloc(addr,size)                                    _omRealloc(addr,size)
+#define omRealloc0(addr,size)                                   _omRealloc0(addr,size)
+
+#define omreallocSize(addr,o_size,size) _omreallocSize(addr,o_size,size)
+#define omrealloc0Size(addr,o_size,size)_omrealloc0Size(addr,o_size,size)
+#define omrealloc(addr,size)            _omrealloc(addr, size)
+#define omrealloc0(addr,size)           _omrealloc0(addr, size)
+
+#endif
+
+#if !defined(OM_T_FREE1)
+#define omFreeBinAddr(addr)     _omDebugFree(addr,NULL,OM_FBINADDR|_OM_FKEEP,OM_CFL)
+#define omFreeBin(addr,bin)     _omDebugFree(addr,bin,OM_FBIN|_OM_FKEEP,OM_CFL)
+#else
+#define omFreeBinAddr(addr)     __omFreeBinAddr(addr)
+#define omFreeBin(addr,bin)     __omFreeBinAddr(addr)
+#endif
+
+#if !defined(OM_T_FREE2)
+#define omFreeSize(addr,size)   _omDebugFree(addr,(void*)(size),OM_FSIZE|_OM_FKEEP,OM_CFL)
+#define omfreeSize(addr,size)   _omDebugFree(addr,(void*)(size),OM_FSIZE|OM_FSLOPPY|_OM_FKEEP,OM_CFL)
+#else
+#define omFreeSize(addr,size)   __omFreeSize(addr,size)
+#define omfreeSize(addr,size)   do {if (addr && size) omFreeSize(addr, size);} while (0)
+#endif
+
+#if !defined(OM_T_FREE3)
+#define omFree(addr)            _omDebugFree(addr,0,0,OM_CFL)
+#define omfree(addr)            _omDebugFree(addr,NULL,OM_FSLOPPY|_OM_FKEEP,OM_CFL)
+#else
+#define omFree(addr)            __omFree(addr)
+#define omfree(addr)            do {if (addr) omFree(addr);} while (0)
+#endif
+
+#if !defined(OM_T_STR)
+#define omStrDup(s)                             _omDebugStrDup(s,OM_TFL)
+#define omMemDup(addr)                          _omDebugMemDup(addr,_OM_FKEEP,OM_CTFL)
+#else
+#define omStrDup(s)         _omStrDup(s)
+#define omMemDup(s)         _omMemDup(s)
+#endif
+
+#define omDebugBinAddr(addr)                 _omDebugAddr(addr,NULL,OM_FBINADDR,OM_CFL)
+#define omDebugAddrBin(addr, bin)            _omDebugAddr(addr,bin,OM_FBIN,OM_CFL)
+#define omDebugBinAddrSize(addr, size)       _omDebugAddr(addr,(void*)(size),OM_FBINADDR|OM_FSIZE,OM_CFL)
+#define omDebugAddrSize(addr,size)           _omDebugAddr(addr,(void*)(size),OM_FSIZE,OM_CFL)
+#define omDebugAddr(addr)                    _omDebugAddr(addr,NULL, 0, OM_CFL)
+#define omdebugAddrSize(addr,size)           _omDebugAddr(addr,(void*)(size),OM_FSIZE|OM_FSLOPPY,OM_CFL)
+#define omdebugAddr(addr)                    _omDebugAddr(addr,NULL, OM_FSLOPPY, OM_CFL)
+#define omDebugBin(bin)                      _omDebugBin(bin,OM_CFL)
+#define omDebugMemory()                      _omDebugMemory(OM_CFL)
+#define omDebugIf(cond, statement)           do { if (cond) {statement;}} while (0)
+
+#if OM_CHECK > 0
+#define omCheckBinAddr      omDebugBinAddr
+#define omCheckAddrBin      omDebugAddrBin
+#define omCheckBinAddrSize  omDebugBinAddrSize
+#define omCheckAddrSize     omDebugAddrSize
+#define omCheckAddr         omDebugAddr
+#define omcheckAddrSize     omdebugAddrSize
+#define omcheckAddr         omdebugAddr
+#define omCheckBin          omDebugBin
+#define omCheckMemory       omDebugMemory
+#define omCheckIf           omDebugIf
+#endif /* OM_CHECK > 0 */
+
+
+#ifdef OM_ALIGNMENT_NEEDS_WORK
+
+#define omTypeAllocAligned(type,addr,size)             addr=(type)_omDebugAlloc((void*)(size),OM_FSIZE|OM_FALIGN|_OM_FKEEP,OM_CTFL)
+#define omTypeAlloc0Aligned(type,addr,size)            addr=(type)_omDebugAlloc((void*)(size),OM_FSIZE|OM_FZERO|OM_FALIGN|_OM_FKEEP,OM_CTFL)
+#define omAllocAligned(size)                           _omDebugAlloc((void*)(size),OM_FSIZE|OM_FALIGN|_OM_FKEEP,OM_CTFL)
+#define omAlloc0Aligned(size)                          _omDebugAlloc((void*)(size),OM_FSIZE|OM_FZERO|OM_FALIGN|_OM_FKEEP,OM_CTFL)
+
+#define omTypeReallocAlignedSize(o_addr,o_size,type,addr,size)         addr=(type)_omDebugRealloc(o_addr,(void*)(o_size),(void*)(size),OM_FSIZE|_OM_FKEEP,OM_FSIZE|OM_FALIGN|_OM_FKEEP,OM_CTFL)
+#define omTypeRealloc0AlignedSize(o_addr,o_size,type,addr,size)        addr=(type)_omDebugRealloc(o_addr,(void*)(o_size),(void*)(size),OM_FSIZE|_OM_FKEEP,OM_FSIZE|OM_FZERO|OM_FALIGN|_OM_FKEEP,OM_CTFL)
+#define omReallocAlignedSize(addr,o_size,size)                         _omDebugRealloc(addr,(void*)(o_size),(void*)(size),OM_FSIZE|_OM_FKEEP,OM_FSIZE|OM_FALIGN|_OM_FKEEP,OM_CTFL)
+#define omRealloc0AlignedSize(addr,o_size,size)                        _omDebugRealloc(addr,(void*)(o_size),(void*)(size),OM_FSIZE|_OM_FKEEP,OM_FSIZE|OM_FZERO|OM_FALIGN|_OM_FKEEP,OM_CTFL)
+
+#define omTypeReallocAligned(o_addr,type,addr,size)                    addr=(type)_omDebugRealloc(o_addr,NULL,(void*)(size),_OM_FKEEP,OM_FSIZE|OM_FALIGN|_OM_FKEEP,OM_CTFL)
+#define omTypeRealloc0Aligned(o_addr,type,addr,size)                   addr=(type)_omDebugRealloc(o_addr,NULL,(void*)(size),_OM_FKEEP,OM_FSIZE|OM_FZERO|OM_FALIGN|_OM_FKEEP,OM_CTFL)
+#define omReallocAligned(addr,size)                                    _omDebugRealloc(addr,NULL,(void*)(size),0,OM_FSIZE|OM_FALIGN|_OM_FKEEP,OM_CTFL)
+#define omRealloc0Aligned(addr,size)                                   _omDebugRealloc(addr,NULL,(void*)(size),0,OM_FSIZE|OM_FZERO|OM_FALIGN|_OM_FKEEP,OM_CTFL)
+
+#define omMemDupAligned(addr)                       _omDebugMemDup(addr,OM_FALIGN|_OM_FKEEP,OM_CTFL)
+
+#define omDebugBinAddrAligned(addr)                 _omDebugAddr(addr,NULL,OM_FBINADDR|OM_FALIGN,OM_CFL)
+#define omDebugAddrAlignedBin(addr, bin)            _omDebugAddr(addr,bin,OM_FBIN|OM_FALIGN,OM_CFL)
+#define omDebugAddrAlignedSize(addr,size)           _omDebugAddr(addr,(void*)(size),OM_FSIZE|OM_FALIGN,OM_CFL)
+#define omDebugAddrAligned(addr)                    _omDebugAddr(addr,NULL, OM_FALIGN, OM_CFL)
+#define omdebugAddrAlignedSize(addr,size)           _omDebugAddr(addr,(void*)(size),OM_FSIZE|OM_FSLOPPY|OM_FALIGN,OM_CFL)
+#define omdebugAddrAligned(addr)                    _omDebugAddr(addr,NULL, OM_FSLOPPY|OM_FALIGN, OM_CFL)
+
+#if OM_CHECK > 0
+#define omCheckBinAddrAligned    omDebugBinAddrAligned
+#define omCheckAddrAlignedBin    omDebugAddrAlignedBin
+#define omCheckAddrAlignedSize   omDebugAddrAlignedSize
+#define omCheckAddrAligned       omDebugAddrAligned
+#define omcheckAddrAlignedSize   omdebugAddrAlignedSize
+#define omcheckAddrAligned       omdebugAddrAligned
+#endif
+#endif /* OM_ALIGNMENT_NEEDS_WORK */
+
+#else
+/*******************************************************************
+ *
+ * Alloc/Free -- the real thing
+ *
+ *******************************************************************/
+#define omTypeAllocBin(type,addr,bin)           __omTypeAllocBin(type,addr,bin)
+#define omTypeAlloc0Bin(type,addr,bin)          __omTypeAlloc0Bin(type,addr,bin)
+#define omAllocBin(bin)                         _omAllocBin(bin)
+#define omAlloc0Bin(bin)                        _omAlloc0Bin(bin)
+
+#define omTypeAlloc(type,addr,size)             __omTypeAlloc(type,addr,size)
+#define omTypeAlloc0(type,addr,size)            __omTypeAlloc0(type,addr,size)
+#define omAlloc(size)                           _omAlloc(size)
+#define omAlloc0(size)                          _omAlloc0(size)
+
+#define omTypeReallocBin(o_addr,o_bin,type,addr,bin)            __omTypeReallocBin(o_addr,o_bin,type,addr,bin)
+#define omTypeRealloc0Bin(o_addr,o_bin,type,addr,bin)           __omTypeRealloc0Bin(o_addr,o_bin,type,addr,bin)
+#define omReallocBin(o_addr,o_bin,bin)                          _omReallocBin(o_addr,o_bin,bin)
+#define omRealloc0Bin(o_addr,o_bin,bin)                         _omRealloc0Bin(o_addr,o_bin,bin)
+
+#define omTypeReallocSize(o_addr,o_size,type,addr,size)         __omTypeReallocSize(o_addr,o_size,type,addr,size)
+#define omTypeRealloc0Size(o_addr,o_size,type,addr,size)        __omTypeRealloc0Size(o_addr,o_size,type,addr,size)
+#define omReallocSize(addr,o_size,size)                         _omReallocSize(addr,o_size,size)
+#define omRealloc0Size(addr,o_size,size)                        _omRealloc0Size(addr,o_size,size)
+
+#define omTypeRealloc(o_addr,type,addr,size)                    __omTypeRealloc(o_addr,type,addr,size)
+#define omTypeRealloc0(o_addr,type,addr,size)                   __omTypeRealloc0(o_addr,type,addr,size)
+#define omRealloc(addr,size)                                    _omRealloc(addr,size)
+#define omRealloc0(addr,size)                                   _omRealloc0(addr,size)
+
+#define omalloc(size)   _omalloc(size)
+#define omalloc0(size)  _omalloc0(size)
+
+#define omreallocSize(addr,o_size,size) _omreallocSize(addr,o_size,size)
+#define omrealloc0Size(addr,o_size,size)_omrealloc0Size(addr,o_size,size)
+#define omrealloc(addr,size)            _omrealloc(addr, size)
+#define omrealloc0(addr,size)           _omrealloc0(addr, size)
+
+#define omfreeSize(addr,size)   do {if (addr && size) omFreeSize(addr, size);} while (0)
+#define omfree(addr)            do {if (addr) omFree(addr);} while (0)
+
+#ifdef OM_ALIGNMENT_NEEDS_WORK
+#define omTypeAllocAligned(type,addr,size)      __omTypeAllocAligned(type,addr,size)
+#define omTypeAlloc0Aligned(type,addr,size)     __omTypeAlloc0Aligned(type,addr,size)
+#define omAllocAligned(size)                    _omAllocAligned(size)
+#define omAlloc0Aligned(size)                   _omAlloc0Aligned(size)
+
+#define omTypeReallocAlignedSize(o_addr,o_size,type,addr,size)  __omTypeReallocAlignedSize(o_addr,o_size,type,addr,size)
+#define omTypeRealloc0AlignedSize(o_addr,o_size,type,addr,size) __omTypeRealloc0AlignedSize(o_addr,o_size,type,addr,size)
+#define omReallocAlignedSize(addr,o_size,size)                  _omReallocAlignedSize(addr,o_size,size)
+#define omRealloc0AlignedSize(addr,o_size,size)                 _omRealloc0AlignedSize(addr,o_size,size)
+
+#define omTypeReallocAligned(o_addr,type,addr,size)             __omTypeReallocAligned(o_addr,type,addr,size)
+#define omTypeRealloc0Aligned(o_addr,type,addr,size)            __omTypeRealloc0Aligned(o_addr,type,addr,size)
+#define omReallocAligned(addr,size)                             _omReallocAligned(addr,size)
+#define omRealloc0Aligned(addr,size)                            _omRealloc0Aligned(addr,size)
+
+#define omMemDupAligned(addr)                                   _omMemDupAligned(addr)
+#endif  /* OM_ALIGNMENT_NEEDS_WORK */
+
+#define omFreeBinAddr(addr)     __omFreeBinAddr(addr)
+#define omFreeBin(addr,bin)     __omFreeBinAddr(addr)
+#define omFreeSize(addr,size)   __omFreeSize(addr,size)
+#define omFree(addr)            __omFree(addr)
+
+#define omStrDup(s)         _omStrDup(s)
+#define omMemDup(s)         _omMemDup(s)
+
+#endif /* ! debug && ! the real thing */
+
+
+/* define alignment stuff, if necessary */
+#if !defined(omTypeAllocAligned)
+#define omTypeAllocAligned      omTypeAlloc
+#define omTypeAlloc0Aligned     omTypeAlloc0
+#define omAllocAligned          omAlloc
+#define omAlloc0Aligned         omAlloc0
+
+#define omTypeReallocAlignedSize     omTypeReallocSize
+#define omTypeRealloc0AlignedSize    omTypeRealloc0Size
+#define omReallocAlignedSize         omReallocSize
+#define omRealloc0AlignedSize        omRealloc0Size
+
+#define omTypeReallocAligned         omTypeRealloc
+#define omTypeRealloc0Aligned        omTypeRealloc0
+#define omReallocAligned             omRealloc
+#define omRealloc0Aligned            omRealloc0
+
+#define omMemDupAligned     omMemDup
+#endif /* !defined(omTypeAllocAligned) */
+
+#if !defined(omDebugAddrAlignedBin)
+#define omDebugBinAddrAligned   omDebugBinAddr
+#define omDebugAddrAlignedBin   omDebugAddrBin
+#define omDebugAddrAlignedSize  omDebugAddrSize
+#define omDebugAddrAligned      omDebugAddr
+#define omdebugAddrAlignedSize  omdebugAddrSize
+#define omdebugAddrAligned      omdebugAddr
+#endif /* !defined(omDebugAddrAlignedBin) */
+
+#if !defined(omCheckAddrAlignedBin)
+#define omCheckBinAddrAligned   omCheckBinAddr
+#define omCheckAddrAlignedBin   omCheckAddrBin
+#define omCheckAddrAlignedSize  omCheckAddrSize
+#define omCheckAddrAligned      omCheckAddr
+#define omcheckAddrAlignedSize  omcheckAddrSize
+#define omcheckAddrAligned      omcheckAddr
+#endif /* !defined(omCheckAddrAlignedBin) */
+
+/* define debug stuff, if necessary */
+#if !defined(omDebugAddrBin)
+#define omDebugIf(cond, test)                    do {} while (0)
+#define omDebugBinAddr(addr)                     do {} while (0)
+#define omDebugAddrBin(addr,bin)                 do {} while (0)
+#define omDebugBinAddrSize(addr,size)            do {} while (0)
+#define omDebugAddrSize(addr,size)               do {} while (0)
+#define omDebugAddr(addr)                        do {} while (0)
+#define omdebugAddrSize(addr,size)               do {} while (0)
+#define omdebugAddr(addr)                        do {} while (0)
+#define omDebugBin(bin)                          do {} while (0)
+#define omDebugMemory()                          do {} while (0)
+#endif /* !defined(omDebugAddrBin) */
+
+/* define check stuff, if necessary */
+#if !defined(omCheckAddrBin)
+#define omCheckIf(cond, test)                    do {} while (0)
+#define omCheckBinAddr(addr)                     do {} while (0)
+#define omCheckAddrBin(addr,bin)                 do {} while (0)
+#define omCheckBinAddrSize(addr,size)            do {} while (0)
+#define omCheckAddrSize(addr,size)               do {} while (0)
+#define omCheckAddr(addr)                        do {} while (0)
+#define omcheckAddrSize(addr,size)               do {} while (0)
+#define omcheckAddr(addr)                        do {} while (0)
+#define omCheckBin(bin)                          do {} while (0)
+#define omCheckMemory()                          do {} while (0)
+#endif /* !defined(omCheckAddrBin) */
+
+
+
+#if !defined(OM_NDEBUG)
+omError_t omTestAddrBin(void* addr, omBin bin, int check_level);
+omError_t omTestBinAddr(void* addr, int check_level);
+omError_t omTestBinAddrSize(void* addr, size_t size, int check_level);
+omError_t omTestAddrSize(void* addr, size_t size, int check_level);
+omError_t omTestAddr(void* addr, int check_level);
+omError_t omtestAddrSize(void* addr, size_t size, int check_level);
+omError_t omtestAddr(void* addr, int check_level);
+omError_t omTestAddrAlignedBin(void* addr, omBin bin, int check_level);
+omError_t omTestAddrAlignedSize(void* addr, size_t size, int check_level);
+omError_t omTestAddrAligned(void* addr, int check_level);
+omError_t omtestAddrAlignedSize(void* addr, size_t size, int check_level);
+omError_t omtestAddrAligned(void* addr, int check_level);
+omError_t omTestBin(omBin bin, int check_level);
+omError_t omTestMemory(int check_level);
+#define omTestIf(cond, statement)           do { if (cond) {statement;}} while (0)
+
+#else
+
+#define omTestIf(cond, test)                      do {} while (0)
+#define omTestAddrBin(addr,bin,l)                 do {} while (0)
+#define omTestBinAddr(addr,l)                     do {} while (0)
+#define omTestBinAddrSize(addr,size,l)            do {} while (0)
+#define omTestAddrSize(addr,size,l)               do {} while (0)
+#define omTestAddr(addr,l)                        do {} while (0)
+#define omtestAddrSize(addr,size,l)               do {} while (0)
+#define omtestAddr(addr,l)                        do {} while (0)
+#define omTestAddrAlignedBin(addr,bin,l)                 do {} while (0)
+#define omTestAddrAlignedSize(addr,size,l)               do {} while (0)
+#define omTestAddrAligned(addr,l)                        do {} while (0)
+#define omtestAddrAlignedSize(addr,size,l)               do {} while (0)
+#define omtestAddrAligned(addr,l)                        do {} while (0)
+#define omTestBin(bin,l)                          do {} while (0)
+#define omTestMemory(l)                           do {} while (0)
+
+#endif
+
+#endif /* OM_ALLOC_DECL_H */
diff --git a/omalloc/omAllocEmulate.c b/omalloc/omAllocEmulate.c
new file mode 100644
index 0000000..e2b2f4a
--- /dev/null
+++ b/omalloc/omAllocEmulate.c
@@ -0,0 +1,43 @@
+/*******************************************************************
+ *  File:    omAllocEmulate.c
+ *  Purpose: implementation of emulated omalloc routines
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 11/99
+ *******************************************************************/
+#include <stdlib.h>
+#include <string.h>
+
+#include "omMalloc.h"
+
+#ifdef OM_EMULATE_OMALLOC
+
+void* omEmulateAlloc0(size_t size)
+{
+  void* addr = OM_MALLOC_MALLOC(size);
+  memset(addr, 0, size);
+  return addr;
+}
+
+void* omEmulateRealloc0Size(void* o_addr, size_t o_size, size_t n_size)
+{
+  void* addr = OM_MALLOC_REALLOC(o_addr, n_size);
+
+  if (n_size > o_size)
+    memset((char *)addr + o_size, 0, n_size - o_size);
+
+  return addr;
+}
+
+void* omEmulateRealloc0(void* o_addr, size_t n_size)
+{
+#ifdef OM_MALLOC_SIZEOF_ADDR
+  size_t o_size = OM_MALLOC_SIZEOF_ADDR(o_addr);
+#endif
+  void* addr = OM_MALLOC_REALLOC(o_addr, n_size);
+#ifdef OM_MALLOC_SIZEOF_ADDR
+  if (n_size > o_size)
+    memset((char *)addr + o_size, 0, n_size - o_size);
+#endif
+  return addr;
+}
+#endif
diff --git a/omalloc/omAllocFunc.c b/omalloc/omAllocFunc.c
new file mode 100644
index 0000000..5580501
--- /dev/null
+++ b/omalloc/omAllocFunc.c
@@ -0,0 +1,21 @@
+/*******************************************************************
+ *  File:    omAllocFunc.c
+ *  Purpose: implementation of ANSI-C conforming malloc functions
+ *           which are sure to be functions, which start with the om prefix,
+ *           and end with the Func suffix.
+ *  Author:  obachman at mathematik.uni-kl.de (Olaf Bachmann)
+ *  Created: 11/99
+ *******************************************************************/
+
+#define malloc      omMallocFunc
+#define calloc      omCallocFunc
+#define free        omFreeFunc
+#define freeSize    omFreeSizeFunc
+#define realloc     omReallocFunc
+#define reallocSize omReallocSizeFunc
+#define memalign    omMemalignFunc
+#define strdup      omStrdupFunc
+#define valloc      omVallocFunc
+
+#define OMALLOC_FUNC
+#include <omalloc/omalloc.c>
diff --git a/omalloc/omAllocFunc.h b/omalloc/omAllocFunc.h
new file mode 100644
index 0000000..b96a67d
--- /dev/null
+++ b/omalloc/omAllocFunc.h
@@ -0,0 +1,26 @@
+/*******************************************************************
+ *  File:    omAllocFunc.h
+ *  Purpose: declaration of ANSI-C conforming malloc functions
+ *           which are sure to be functions, which start with the om prefix,
+ *           and end with the Func suffix.
+ *  Author:  obachman at mathematik.uni-kl.de (Olaf Bachmann)
+ *  Created: 11/99
+ *******************************************************************/
+
+void* omCallocFunc(size_t nmemb, size_t size);
+void* omMallocFunc(size_t size);
+void omFreeFunc(void* addr);
+void* omVallocFunc(size_t size);
+#if defined(sgi)
+void* omMemalignFunc(size_t size_1, size_t size_2);
+#else
+#if (defined(__sun) && (defined(__sparc) || defined(__i386) || defined(__x86_64)) || defined(__CYGWIN__))
+extern void* omMemalignFunc(size_t, size_t);
+#else
+void* omMemalignFunc(void* alignment, size_t size);
+#endif
+#endif
+void* omReallocFunc(void* old_addr, size_t new_size);
+char* omStrdupFunc(const char* addr);
+void* omReallocSizeFunc(void* old_addr, size_t old_size, size_t new_size);
+void omFreeSizeFunc(void* addr, size_t size);
diff --git a/omalloc/omAllocPrivate.h b/omalloc/omAllocPrivate.h
new file mode 100644
index 0000000..914ae56
--- /dev/null
+++ b/omalloc/omAllocPrivate.h
@@ -0,0 +1,373 @@
+/*******************************************************************
+ *  File:    omAllocPrivate.h
+ *  Purpose: declaration of "private" (but visible to the outside)
+ *           routines for omalloc
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 11/99
+ *******************************************************************/
+#ifndef OM_ALLOC_PRIVATE_H
+#define OM_ALLOC_PRIVATE_H
+
+/*******************************************************************
+ *
+ *  Definitions of structures we work with
+ *
+ *******************************************************************/
+/* Need to define it here, has to be known to macros */
+struct omBinPage_s
+{
+  long          used_blocks;    /* number of used blocks of this page */
+  void*         current;        /* pointer to current freelist */
+  omBinPage     next;           /* next/prev pointer of pages */
+  omBinPage     prev;
+  void*         bin_sticky;     /* bin this page belongs to with
+                                   sticky tag of page hidden in ptr */
+  omBinPageRegion region;       /* BinPageRegion of this page */
+};
+
+/* Change this appropriately, if you change omBinPage                 */
+/* However, make sure that omBinPage is a multiple of SIZEOF_MAX_TYPE */
+#define SIZEOF_OM_BIN_PAGE_HEADER (5*SIZEOF_VOIDP + SIZEOF_LONG)
+#define SIZEOF_OM_BIN_PAGE (SIZEOF_SYSTEM_PAGE - SIZEOF_OM_BIN_PAGE_HEADER)
+
+/* keep all members of omBin_s a sizeof(long) type,
+   otherwise list operations will fail */
+struct omBin_s
+{
+  omBinPage     current_page;   /* page of current freelist */
+  omBinPage     last_page;      /* pointer to last page of freelist */
+  omBin         next;           /* sticky bins of the same size */
+  size_t        sizeW;          /* size in words */
+  long          max_blocks;     /* if > 0   # blocks in one page,
+                                   if < 0   # pages for one block */
+  unsigned long sticky;         /* sticky tag */
+};
+
+struct omSpecBin_s
+{
+  omSpecBin        next;       /* pointer to next bin */
+  omBin            bin;        /* pointer to bin itself */
+  long             max_blocks; /* max_blocks of bin*/
+  long             ref;        /* ref count */
+};
+
+extern  omSpecBin   om_SpecBin;
+extern  omBin       om_StickyBins;
+extern  omBinPage_t om_ZeroPage[];
+extern  omBin       om_Size2Bin[];
+
+/*******************************************************************
+ *
+ *  Working with pages/bins
+ *
+ *******************************************************************/
+#define omGetTopBinOfPage(page) \
+  ((omBin) ( ((unsigned long) ((page)->bin_sticky)) & ~((unsigned long)SIZEOF_VOIDP - 1)))
+#define omGetStickyOfPage(page) \
+  (((unsigned long) ((page)->bin_sticky)) & ((unsigned long)SIZEOF_VOIDP-1))
+#define omSetTopBinOfPage(page, bin) \
+  (page)->bin_sticky= (void*)((unsigned long)bin + omGetStickyOfPage(page))
+#define omSetStickyOfPage(page, sticky) \
+  (page)->bin_sticky = (void*)(((unsigned long)sticky & ((unsigned long)SIZEOF_VOIDP-1)) + \
+                                (unsigned long)omGetTopBinOfPage(page))
+#define omSetTopBinAndStickyOfPage(page, bin, sticky) \
+  (page)->bin_sticky= (void*)(((unsigned long)sticky & (SIZEOF_VOIDP-1)) \
+                               + (unsigned long)bin)
+
+#define omGetTopBinOfAddr(addr) \
+  omGetTopBinOfPage(((omBinPage) omGetPageOfAddr(addr)))
+#define omGetBinOfAddr(addr) omGetBinOfPage(omGetBinPageOfAddr(addr))
+
+#ifndef OM_GENERATE_INC
+extern omBin_t om_StaticBin[];
+extern omBin om_Size2Bin[];
+#ifdef OM_ALIGNMENT_NEEDS_WORK
+extern omBin om_Size2AlignedBin[];
+#endif
+
+/*******************************************************************
+ *
+ *  SizeOfAddr
+ *
+ *******************************************************************/
+#ifdef OM_INTERNAL_DEBUG
+size_t omSizeOfBinAddr(void* addr);
+#else
+#define omSizeOfBinAddr(addr) _omSizeOfBinAddr(addr)
+#endif
+
+#define omSizeWOfBin(bin_ptr) ((bin_ptr)->sizeW)
+
+#define _omSizeOfBinAddr(addr)  ((omSizeWOfBinAddr(addr)) << LOG_SIZEOF_LONG)
+#define omSizeWOfBinAddr(addr) ((omGetTopBinOfAddr(addr))->sizeW)
+
+/*******************************************************************
+ *
+ *  lowest level alloc/free macros
+ *
+ *******************************************************************/
+extern void* omAllocBinFromFullPage(omBin bin);
+extern void  omFreeToPageFault(omBinPage page, void* addr);
+
+/*******************************************************************/
+/* Page                                                            */
+#define __omTypeAllocFromNonEmptyPage(type, addr, page) \
+do                                                      \
+{                                                       \
+  ((page)->used_blocks)++;                              \
+  addr = (type)((page)->current);                       \
+  (page)->current =  *((void**) (page)->current);       \
+}                                                       \
+while (0)
+
+#define __omFreeToPage(addr, page)              \
+do                                              \
+{                                               \
+  if ((page)->used_blocks > 0L)                 \
+  {                                             \
+    *((void**) (addr)) = (page)->current;       \
+    ((page)->used_blocks)--;                    \
+    (page)->current = (addr);                   \
+  }                                             \
+  else                                          \
+  {                                             \
+    omFreeToPageFault(page, addr);              \
+  }                                             \
+}                                               \
+while (0)
+
+
+/*******************************************************************/
+/* Bin                                                             */
+#define __omTypeAllocBin(type, addr, bin)                   \
+do                                                          \
+{                                                           \
+  register omBinPage __om_page = (bin)->current_page;       \
+  if (__om_page->current != NULL)                           \
+    __omTypeAllocFromNonEmptyPage(type, addr, __om_page);   \
+  else                                                      \
+    addr = (type) omAllocBinFromFullPage(bin);              \
+}                                                           \
+while (0)
+
+#define __omTypeAlloc0Bin(type, addr, bin)      \
+do                                              \
+{                                               \
+  __omTypeAllocBin(type, addr, bin);            \
+  omMemsetW(addr, 0, (bin)->sizeW);             \
+}                                               \
+while (0)
+
+
+#define __omFreeBinAddr(addr)                                   \
+do                                                              \
+{                                                               \
+  register void* __om_addr = (void*) (addr);                    \
+  register omBinPage __om_page = omGetBinPageOfAddr(__om_addr); \
+  __omFreeToPage(__om_addr, __om_page);                         \
+}                                                               \
+while (0)
+
+#define __omTypeReallocBin(old_addr, old_bin, new_type, new_addr, new_bin)                              \
+do                                                                                                      \
+{                                                                                                       \
+  if (old_bin != new_bin)                                                                               \
+  {                                                                                                     \
+    size_t old_sizeW = (omIsNormalBinPageAddr(old_addr) ? old_bin->sizeW : omSizeWOfAddr(old_addr));    \
+    __omTypeAllocBin(new_type, new_addr, new_bin);                                                      \
+    omMemcpyW(new_addr, old_addr, (new_bin->sizeW > old_sizeW ? old_sizeW : new_bin->sizeW));           \
+    __omFreeBinAddr(old_addr);                                                                     \
+  }                                                                                                     \
+  else                                                                                                  \
+  {                                                                                                     \
+    new_addr = (new_type) old_addr;                                                                     \
+  }                                                                                                     \
+}                                                                                                       \
+while (0)
+
+
+#define __omTypeRealloc0Bin(old_addr, old_bin, new_type, new_addr, new_bin)                             \
+do                                                                                                      \
+{                                                                                                       \
+  if (old_bin != new_bin)                                                                               \
+  {                                                                                                     \
+    size_t old_sizeW = (omIsNormalBinPageAddr(old_addr) ? old_bin->sizeW : omSizeWOfAddr(old_addr));    \
+    __omTypeAllocBin(new_type, new_addr, new_bin);                                                      \
+    omMemcpyW(new_addr, old_addr, (new_bin->sizeW > old_sizeW ? old_sizeW : new_bin->sizeW));           \
+    if (new_bin->sizeW > old_sizeW)                                                                     \
+       omMemsetW((void**)new_addr + old_sizeW, 0, new_bin->sizeW - old_sizeW);                          \
+    __omFreeBinAddr(old_addr);                                                                     \
+  }                                                                                                     \
+  else                                                                                                  \
+  {                                                                                                     \
+    new_addr = (new_type) old_addr;                                                                     \
+  }                                                                                                     \
+}                                                                                                       \
+while (0)
+
+/*******************************************************************/
+/* Size                                                            */
+#define omSmallSize2Bin(size) om_Size2Bin[((size) -1)>>LOG_SIZEOF_OM_ALIGNMENT]
+
+#define __omTypeAlloc(type, addr, size)         \
+do                                              \
+{                                               \
+  size_t __size = size;                         \
+  if (__size <= OM_MAX_BLOCK_SIZE)              \
+  {                                             \
+    omBin __om_bin = omSmallSize2Bin(__size);   \
+    __omTypeAllocBin(type, addr, __om_bin);     \
+  }                                             \
+  else                                          \
+  {                                             \
+    addr = (type) omAllocLarge(__size);         \
+  }                                             \
+}                                               \
+while(0)
+
+#define __omTypeAlloc0(type, addr, size)        \
+do                                              \
+{                                               \
+  size_t __size = size;                         \
+  if (__size <= OM_MAX_BLOCK_SIZE)              \
+  {                                             \
+    omBin __om_bin = omSmallSize2Bin(__size);   \
+    __omTypeAlloc0Bin(type, addr, __om_bin);    \
+  }                                             \
+  else                                          \
+  {                                             \
+    addr = (type) omAlloc0Large(__size);        \
+  }                                             \
+}                                               \
+while (0)
+
+#ifdef OM_ALIGNMENT_NEEDS_WORK
+#define omSmallSize2AlignedBin(size) om_Size2AlignedBin[((size) -1)>>LOG_SIZEOF_OM_ALIGNMENT]
+
+#define __omTypeAllocAligned(type, addr, size)          \
+do                                                      \
+{                                                       \
+  size_t __size = size;                                 \
+  if (__size <= OM_MAX_BLOCK_SIZE)                      \
+  {                                                     \
+    omBin __om_bin = omSmallSize2AlignedBin(__size);    \
+    __omTypeAllocBin(type, addr, __om_bin);             \
+  }                                                     \
+  else                                                  \
+  {                                                     \
+    addr = (type) omAllocLarge(__size);                 \
+  }                                                     \
+}                                                       \
+while(0)
+
+#define __omTypeAlloc0Aligned(type, addr, size)         \
+do                                                      \
+{                                                       \
+  size_t __size = size;                                 \
+  if (__size <= OM_MAX_BLOCK_SIZE)                      \
+  {                                                     \
+    omBin __om_bin = omSmallSize2AlignedBin(__size);    \
+    __omTypeAlloc0Bin(type, addr, __om_bin);            \
+  }                                                     \
+  else                                                  \
+  {                                                     \
+    addr = (type) omAlloc0Large(__size);                \
+  }                                                     \
+}                                                       \
+while (0)
+#else
+#define __omTypeAllocAligned    __omTypeAlloc
+#define __omTypeAlloc0Aligned   __omTypeAlloc0
+#endif /* OM_ALIGNMENT_NEEDS_WORK */
+
+#define __omFreeSize(addr, size)                            \
+do                                                          \
+{                                                           \
+  if ((size <= OM_MAX_BLOCK_SIZE) || omIsBinPageAddr(addr)) \
+  {                                                         \
+    __omFreeBinAddr(addr);                                  \
+  }                                                         \
+  else                                                      \
+  {                                                         \
+    omFreeLarge(addr);                                      \
+  }                                                         \
+}                                                           \
+while (0)
+
+#define __omFree(addr)                          \
+do                                              \
+{                                               \
+  if (omIsBinPageAddr(addr))                    \
+  {                                             \
+    __omFreeBinAddr(addr);                         \
+  }                                             \
+  else                                          \
+  {                                             \
+    omFreeLarge(addr);                          \
+  }                                             \
+}                                               \
+while (0)
+
+void* omDoRealloc(void* old_addr, size_t new_size, int flags);
+
+#define ___omTypeRealloc(old_addr, new_type, new_addr, new_size, SIZE_2_BIN, REALLOC_BIN, flags)    \
+do                                                                                                  \
+{                                                                                                   \
+  size_t __new_size = new_size;                                                                     \
+  if (__new_size <= OM_MAX_BLOCK_SIZE && omIsBinPageAddr(old_addr))                                 \
+  {                                                                                                 \
+    omBin __old_bin = omGetBinOfAddr(old_addr);                                                     \
+    omBin __new_bin = SIZE_2_BIN(__new_size);                                                       \
+    REALLOC_BIN(old_addr, __old_bin, new_type, new_addr, __new_bin);                                \
+  }                                                                                                 \
+  else                                                                                              \
+  {                                                                                                 \
+    new_addr = (new_type) omDoRealloc(old_addr, __new_size, flags);                                 \
+  }                                                                                                 \
+}                                                                                                   \
+while (0)
+
+#define ___omTypeReallocSize(old_addr, old_size, new_type, new_addr, new_size, SIZE_2_BIN, REALLOC_BIN, flags)  \
+do                                                                                                              \
+{                                                                                                               \
+  size_t __new_size = new_size;                                                                                 \
+  if (__new_size <= OM_MAX_BLOCK_SIZE && old_size <= OM_MAX_BLOCK_SIZE)                                         \
+  {                                                                                                             \
+    omBin __old_bin = omGetBinOfAddr(old_addr);                                                                 \
+    omBin __new_bin = SIZE_2_BIN(__new_size);                                                                   \
+    REALLOC_BIN(old_addr, __old_bin, new_type, new_addr, __new_bin);                                            \
+  }                                                                                                             \
+  else                                                                                                          \
+  {                                                                                                             \
+    new_addr = (new_type) omDoRealloc(old_addr, __new_size, flags);                                             \
+  }                                                                                                             \
+}                                                                                                               \
+while (0)
+
+#define __omTypeRealloc(old_addr, new_type, new_addr, new_size)                 \
+  ___omTypeRealloc(old_addr, new_type, new_addr, new_size, omSmallSize2Bin, __omTypeReallocBin, 0)
+#define __omTypeRealloc0(old_addr, new_type, new_addr, new_size)                \
+  ___omTypeRealloc(old_addr, new_type, new_addr, new_size, omSmallSize2Bin, __omTypeRealloc0Bin, 1)
+#define __omTypeReallocSize(old_addr, old_size, new_type, new_addr, new_size)     \
+  ___omTypeReallocSize(old_addr, old_size, new_type, new_addr, new_size, omSmallSize2Bin, __omTypeReallocBin, 0)
+#define __omTypeRealloc0Size(old_addr, old_size, new_type, new_addr, new_size)    \
+  ___omTypeReallocSize(old_addr, old_size, new_type, new_addr, new_size, omSmallSize2Bin, __omTypeRealloc0Bin, 1)
+
+#ifdef OM_ALIGNMENT_NEEDS_WORK
+#define __omTypeReallocAligned(old_addr, new_type, new_addr, new_size)                 \
+  ___omTypeRealloc(old_addr, new_type, new_addr, new_size, omSmallSize2AlignedBin, __omTypeReallocBin, 2)
+#define __omTypeRealloc0Aligned(old_addr, new_type, new_addr, new_size)                \
+  ___omTypeRealloc(old_addr, new_type, new_addr, new_size, omSmallSize2AlignedBin, __omTypeRealloc0Bin, 3)
+#define __omTypeReallocAlignedSize(old_addr, old_size, new_type, new_addr, new_size)     \
+  ___omTypeReallocSize(old_addr, old_size, new_type, new_addr, new_size, omSmallSize2AlignedBin, __omTypeReallocBin, 2)
+#define __omTypeRealloc0AlignedSize(old_addr, old_size, new_type, new_addr, new_size)    \
+  ___omTypeReallocSize(old_addr, old_size, new_type, new_addr, new_size, omSmallSize2AlignedBin, __omTypeRealloc0Bin, 3)
+#else
+#define __omTypeReallocAligned      __omTypeRealloc
+#define __omTypeRealloc0Aligned     __omTypeRealloc0
+#define __omTypeReallocAlignedSize      __omTypeReallocSize
+#define __omTypeRealloc0AlignedSize     __omTypeRealloc0Size
+#endif
+
+#endif /* OM_GENERATE_INC */
+#endif /* OM_ALLOC_PRIVATE_H */
diff --git a/omalloc/omAllocSystem.c b/omalloc/omAllocSystem.c
new file mode 100644
index 0000000..00f3885
--- /dev/null
+++ b/omalloc/omAllocSystem.c
@@ -0,0 +1,356 @@
+/*******************************************************************
+ *  File:    omAllocSystem.c
+ *  Purpose: implementation of main lowl-level alloc functions
+ *  Author:  obachman at mathematik.uni-kl.de (Olaf Bachmann)
+ *  Created: 11/99
+ *******************************************************************/
+#ifndef OM_ALLOC_SYSTEM_C
+#define OM_ALLOC_SYSTEM_C
+
+#include <unistd.h>
+#include <mylimits.h>
+
+
+#include "omConfig.h"
+#include "omDefaultConfig.h"
+#include "omMalloc.h"
+#include "omalloc.h"
+/* include after omMalloc.h */
+#include <string.h>
+
+#define OM_MALLOC_FROM_SYSTEM   OM_MALLOC_MALLOC
+#define OM_REALLOC_FROM_SYSTEM  OM_MALLOC_REALLOC
+#define OM_FREE_TO_SYSTEM       OM_MALLOC_FREE
+
+/*******************************************************************
+ *
+ *  AllocLarge/FreeLarge if malloc can not return sizeof(addr)
+ *
+ *******************************************************************/
+/* allocation of large addr */
+#if defined(OM_MALLOC_PROVIDES_SIZEOF_ADDR)
+#define _omSizeOfLargeAddr(addr) (OM_MALLOC_SIZEOF_ADDR(addr) & (~SIZEOF_OM_ALIGNMENT_1))
+#else
+void* omAllocLarge(size_t size)
+{
+  char* addr;
+  size = OM_ALIGN_SIZE(size);
+  addr = omAllocFromSystem(size + SIZEOF_STRICT_ALIGNMENT);
+  *((size_t*) addr) = size;
+  return (void *)(addr + SIZEOF_STRICT_ALIGNMENT);
+}
+
+void* omReallocLarge(void* old_addr, size_t new_size)
+{
+  char* _old_addr;
+  char* new_addr;
+
+  omAssume(omIsLargeAddr(old_addr));
+
+  new_size = OM_ALIGN_SIZE(new_size);
+  _old_addr = (char *)old_addr - SIZEOF_STRICT_ALIGNMENT;
+  new_addr = omReallocSizeFromSystem(_old_addr,
+                                     *((size_t*) _old_addr) + SIZEOF_STRICT_ALIGNMENT,
+                                     new_size + SIZEOF_STRICT_ALIGNMENT);
+  *((size_t*) new_addr) = new_size;
+  return (void *)(new_addr + SIZEOF_STRICT_ALIGNMENT);
+}
+
+void omFreeLarge(void* addr)
+{
+  char* _addr = (char *)addr - SIZEOF_STRICT_ALIGNMENT;
+  omFreeSizeToSystem(_addr, *((size_t*) _addr) + SIZEOF_STRICT_ALIGNMENT);
+}
+
+#define _omSizeOfLargeAddr(addr)  (*((size_t*) ((char*) addr - SIZEOF_STRICT_ALIGNMENT)))
+#endif /* OM_MALLOC_PROVIDES_SIZEOF_ADDR */
+
+void* omAlloc0Large(size_t size)
+{
+  void* addr = omAllocLarge(size);
+  size = omSizeOfLargeAddr(addr);
+  memset(addr, 0, size);
+  return addr;
+}
+
+void* omRealloc0Large(void* old_addr, size_t new_size)
+{
+  size_t old_size;
+  char* new_addr;
+
+  omAssume(!omIsBinPageAddr(old_addr));
+
+  old_size = omSizeOfLargeAddr(old_addr);
+
+  new_addr = omReallocLarge(old_addr, new_size);
+  new_size = omSizeOfLargeAddr(new_addr);
+  if (new_size > old_size)
+    memset(new_addr + old_size, 0, new_size - old_size);
+  return (void *)new_addr;
+}
+
+size_t omSizeOfLargeAddr(void* addr)
+{
+  return _omSizeOfLargeAddr((char *)addr);
+}
+
+size_t omSizeOfAddr(const void* addr)
+{
+
+  return (omIsBinPageAddr(addr) ?
+#ifdef OM_HAVE_TRACK
+          (omIsBinAddrTrackAddr(addr) ? omOutSizeOfTrackAddr((char *)addr) : omSizeOfBinAddr(addr)) :
+#else
+          omSizeOfBinAddr(addr) :
+#endif
+          omSizeOfLargeAddr((char *)addr));
+}
+
+size_t omSizeWOfAddr(void* addr)
+{
+
+  return (omIsBinPageAddr(addr) ?
+#ifdef OM_HAVE_TRACK
+          (omIsBinAddrTrackAddr(addr) ? omOutSizeOfTrackAddr(addr) >> LOG_SIZEOF_LONG : omSizeWOfBinAddr(addr)) :
+#else
+          omSizeWOfBinAddr(addr) :
+#endif
+          omSizeOfLargeAddr(addr) >> LOG_SIZEOF_LONG);
+}
+
+/*******************************************************************
+ *
+ *  Valloc
+ *
+ *******************************************************************/
+#ifdef OM_HAVE_VALLOC_MMAP
+
+#include "omMmap.c"
+
+#define OM_VALLOC_FROM_SYSTEM   omVallocMmap
+#define OM_VFREE_TO_SYSTEM      omVfreeMmap
+
+#elif defined(OM_HAVE_VALLOC_MALLOC)
+
+#define OM_VALLOC_FROM_SYSTEM OM_MALLOC_VALLOC
+#define OM_VFREE_TO_SYSTEM    OM_MALLOC_VFREE
+
+#else
+
+#define OM_VALLOC_FROM_SYSTEM   omEmulateValloc
+#define OM_VFREE_TO_SYSTEM      omEmulateVfree
+
+#define OM_ALIGN_PAGE(addr) ( ((long)addr + (SIZEOF_SYSTEM_PAGE -1)) & ~(SIZEOF_SYSTEM_PAGE - 1))
+/* now we implement an emulation */
+void* omEmulateValloc(size_t size)
+{
+  void* addr;
+  size_t padding = SIZEOF_VOIDP;
+  size = OM_ALIGN_SIZE(size);
+  while (1)
+  {
+    addr = OM_MALLOC_FROM_SYSTEM(size + padding);
+    if (addr == NULL) return NULL;
+    if ((OM_ALIGN_PAGE(addr) + SIZEOF_VOIDP) - (long) addr <= padding)
+    {
+      void* ret_addr = (void*) OM_ALIGN_PAGE(addr);
+      *((void**) ((void*) ret_addr + size)) = addr;
+      return ret_addr;
+    }
+    else
+    {
+      OM_FREE_TO_SYSTEM(addr);
+      padding = padding << 1;
+    }
+  }
+}
+
+void omEmulateVfree(void* addr, size_t size)
+{
+  size = OM_ALIGN_SIZE(size);
+  OM_FREE_TO_SYSTEM( *((void**) ((void*) addr + size)) );
+}
+#endif /* OM_HAVE_VALLOC_MMAP */
+
+/*******************************************************************
+ *
+ *  System-level Alloc/Free
+ *
+ *******************************************************************/
+void* omAllocFromSystem(size_t size)
+{
+  void* ptr;
+
+  ptr = OM_MALLOC_FROM_SYSTEM(size);
+  if (ptr == NULL)
+  {
+    OM_MEMORY_LOW_HOOK();
+    ptr = OM_MALLOC_FROM_SYSTEM(size);
+    if (ptr == NULL)
+    {
+      OM_OUT_OF_MEMORY_HOOK();
+      exit(1);
+    }
+  }
+
+#ifndef OM_NDEBUG
+  if (((unsigned long) ptr) + size > om_MaxAddr)
+    om_MaxAddr = ((unsigned long) ptr) + size;
+  if (((unsigned long) ptr) < om_MinAddr)
+    om_MinAddr = ((unsigned long) ptr);
+#endif
+
+  om_Info.CurrentBytesFromMalloc += size;
+  if (om_Info.CurrentBytesFromMalloc > om_Info.MaxBytesFromMalloc)
+  {
+    om_Info.MaxBytesFromMalloc = om_Info.CurrentBytesFromMalloc;
+#if defined(OM_HAVE_VALLOC_MMAP) && defined(OM_MALLOC_MAX_BYTES_SYSTEM)
+    if (om_Info.CurrentBytesFromValloc + OM_MALLOC_MAX_BYTES_SYSTEM > om_Info.MaxBytesSystem)
+      om_Info.MaxBytesSystem = om_Info.CurrentBytesFromValloc + OM_MALLOC_MAX_BYTES_SYSTEM;
+#endif
+#if defined(HAVE_SBRK) && !defined(OM_MALLOC_MAX_BYTES_SBRK)
+    if (! om_SbrkInit) om_SbrkInit = (unsigned long) sbrk(0) - size;
+    if (om_Info.MaxBytesFromMalloc
+#ifndef OM_HAVE_VALLOC_MMAP
+        + om_Info.CurrentBytesFromValloc
+#endif
+        > om_Info.MaxBytesSbrk)
+    {
+      om_Info.MaxBytesSbrk = (unsigned long) sbrk(0) - om_SbrkInit;
+    }
+#endif
+  }
+  OM_MALLOC_HOOK(size);
+  return ptr;
+}
+
+void* omReallocFromSystem(void* addr, size_t newsize)
+{
+  return omReallocSizeFromSystem(addr, omSizeOfAddr(addr), newsize);
+}
+
+void* omReallocSizeFromSystem(void* addr, size_t oldsize, size_t newsize)
+{
+  void* res;
+
+  res = OM_REALLOC_FROM_SYSTEM(addr, newsize);
+  if (res == NULL)
+  {
+    OM_MEMORY_LOW_HOOK();
+    /* Can do a realloc again: manpage reads:
+       "If realloc() fails the original block is left untouched -
+       it is not freed or moved." */
+    res = OM_REALLOC_FROM_SYSTEM(addr, newsize);
+    if (res == NULL)
+    {
+      OM_OUT_OF_MEMORY_HOOK();
+      /* should never get here */
+      omAssume(0);
+      exit(1);
+    }
+  }
+
+#ifndef OM_NDEBUG
+  if (((unsigned long) res) + newsize > om_MaxAddr)
+    om_MaxAddr = ((unsigned long) res) + newsize;
+  if (((unsigned long) res) < om_MinAddr)
+    om_MinAddr = ((unsigned long) res);
+#endif
+
+  om_Info.CurrentBytesFromMalloc += (long) newsize - (long) oldsize;
+
+
+  if (om_Info.CurrentBytesFromMalloc > om_Info.MaxBytesFromMalloc)
+  {
+    om_Info.MaxBytesFromMalloc = om_Info.CurrentBytesFromMalloc;
+#if defined(OM_HAVE_VALLOC_MMAP) && defined(OM_MALLOC_MAX_BYTES_SYSTEM)
+    if (om_Info.CurrentBytesFromValloc + OM_MALLOC_MAX_BYTES_SYSTEM > om_Info.MaxBytesSystem)
+      om_Info.MaxBytesSystem = om_Info.CurrentBytesFromValloc + OM_MALLOC_MAX_BYTES_SYSTEM;
+#endif
+#if defined(HAVE_SBRK) && !defined(OM_MALLOC_MAX_BYTES_SBRK)
+    if (om_Info.MaxBytesFromMalloc
+#ifndef OM_HAVE_VALLOC_MMAP
+        + om_Info.CurrentBytesFromValloc
+#endif
+        > om_Info.MaxBytesSbrk)
+    {
+      om_Info.MaxBytesSbrk = (unsigned long) sbrk(0) - om_SbrkInit;
+    }
+#endif
+  }
+
+  OM_REALLOC_HOOK(oldsize, newsize);
+  return res;
+}
+
+void omFreeToSystem(void* addr)
+{
+  omFreeSizeToSystem(addr, omSizeOfAddr(addr));
+}
+
+void omFreeSizeToSystem(void* addr, size_t size)
+{
+  OM_FREE_TO_SYSTEM( addr );
+  om_Info.CurrentBytesFromMalloc -= size;
+  OM_FREE_HOOK(size);
+}
+
+void* _omVallocFromSystem(size_t size, int fail)
+{
+  void* page = OM_VALLOC_FROM_SYSTEM(size);
+  if (page == NULL)
+  {
+    OM_MEMORY_LOW_HOOK();
+    page = OM_VALLOC_FROM_SYSTEM(size);
+    if (page == NULL)
+    {
+      if (fail) return NULL;
+      else
+      {
+        OM_OUT_OF_MEMORY_HOOK();
+        /* should never get here */
+        omAssume(0);
+        exit(1);
+      }
+    }
+  }
+
+#ifndef OM_NDEBUG
+  if (((unsigned long) page) + size > om_MaxAddr)
+    om_MaxAddr = ((unsigned long) page) + size;
+  if (((unsigned long) page) < om_MinAddr)
+    om_MinAddr = ((unsigned long) page);
+#endif
+
+  omAssume(omIsAddrPageAligned(page));
+  om_Info.CurrentBytesFromValloc += size;
+  if (om_Info.CurrentBytesFromValloc > om_Info.MaxBytesFromValloc)
+  {
+    om_Info.MaxBytesFromValloc = om_Info.CurrentBytesFromValloc;
+#if defined(OM_HAVE_VALLOC_MMAP) && defined(OM_MALLOC_MAX_BYTES_SYSTEM)
+    if (om_Info.MaxBytesFromValloc + OM_MALLOC_MAX_BYTES_SYSTEM > om_Info.MaxBytesSystem)
+      om_Info.MaxBytesSystem = om_Info.MaxBytesFromValloc + OM_MALLOC_MAX_BYTES_SYSTEM;
+#endif
+#if defined(HAVE_SBRK) && !defined(OM_HAVE_VALLOC_MMAP) && !defined(OM_MALLOC_MAX_BYTES_SBRK)
+    if (! om_SbrkInit) om_SbrkInit = (unsigned long) sbrk(0) - size;
+    if (om_Info.CurrentBytesFromMalloc + om_Info.CurrentBytesFromValloc > om_Info.MaxBytesSbrk)
+    {
+      om_Info.MaxBytesSbrk = (unsigned long) sbrk(0) - om_SbrkInit;
+      omAssume(om_Info.MaxBytesSbrk >= om_Info.CurrentBytesFromMalloc
+               + om_Info.CurrentBytesFromValloc);
+    }
+#endif
+  }
+  OM_VALLOC_HOOK(size);
+  return page;
+}
+
+void omVfreeToSystem(void* page, size_t size)
+{
+  omAssume(omIsAddrPageAligned(page));
+  OM_VFREE_TO_SYSTEM(page, size);
+  om_Info.CurrentBytesFromValloc  -= size;
+  OM_VFREE_HOOK(size);
+}
+
+#endif /* OM_ALLOC_SYSTEM_C */
diff --git a/omalloc/omAllocSystem.h b/omalloc/omAllocSystem.h
new file mode 100644
index 0000000..4cbe586
--- /dev/null
+++ b/omalloc/omAllocSystem.h
@@ -0,0 +1,41 @@
+/*******************************************************************
+ *  File:    omAllocSystem.h
+ *  Purpose: declaration of routines for low-level alloc routines
+ *           and page management
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 11/99
+ *******************************************************************/
+#ifndef OM_ALLOC_SYSTEM_H
+#define OM_ALLOC_SYSTEM_H
+
+size_t omSizeOfAddr(const void* addr);
+size_t omSizeWOfAddr(void* addr);
+
+size_t omSizeOfLargeAddr(void* addr);
+#define omSizeWOfLargeAddr(addr) (omSizeOfLargeAddr(addr) >> LOG_SIZEOF_LONG)
+
+void* omAllocFromSystem(size_t size);
+void* omReallocFromSystem(void* addr, size_t newsize);
+void  omFreeToSystem(void* addr);
+
+void* omReallocSizeFromSystem(void* addr, size_t oldsize, size_t newsize);
+void  omFreeSizeToSystem(void* addr, size_t size);
+
+#define omVallocFromSystem(size) _omVallocFromSystem(size, 0)
+void* _omVallocFromSystem(size_t size, int fail);
+void omVfreeToSystem(void* page, size_t size);
+
+
+#ifdef OM_MALLOC_PROVIDES_SIZEOF_ADDR
+#define omAllocLarge(size)             omAllocFromSystem(OM_ALIGN_SIZE(size))
+#define omReallocLarge(addr, new_size) omReallocSizeFromSystem(addr, omSizeOfLargeAddr(addr), OM_ALIGN_SIZE(new_size))
+#define omFreeLarge(addr)              omFreeSizeToSystem(addr, omSizeOfLargeAddr(addr))
+#else
+void* omAllocLarge(size_t size);
+void* omReallocLarge(void* old_addr, size_t new_size);
+void  omFreeLarge(void* addr);
+#endif
+void* omRealloc0Large(void* old_addr, size_t new_size);
+void* omAlloc0Large(size_t size);
+
+#endif /* OM_ALLOC_SYSTEM_H */
diff --git a/omalloc/omBin.c b/omalloc/omBin.c
new file mode 100644
index 0000000..ee09487
--- /dev/null
+++ b/omalloc/omBin.c
@@ -0,0 +1,796 @@
+/*******************************************************************
+ *  File:    omBin.c
+ *  Purpose: definitions of routines for working with bins
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 11/99
+ *******************************************************************/
+
+#include "omalloc.h"
+/* this should go away */
+
+#ifdef OM_INTERNAL_DEBUG
+size_t omSizeOfBinAddr(void* addr)
+{
+  return _omSizeOfBinAddr(addr);
+}
+#endif
+
+/*****************************************************************
+ *
+ * SpecBin business
+ *
+ *****************************************************************/
+#define om_LargeBin ((omBin) 1)
+omBin _omGetSpecBin(size_t size, int align, int track)
+
+{
+  omBin om_new_specBin;
+  long max_blocks;
+  long sizeW;
+
+
+  size = OM_ALIGN_SIZE(size);
+#ifdef OM_ALIGNMENT_NEEDS_WORK
+  if (align || size >= OM_SIZEOF_UNIQUE_MAX_BLOCK_THRESHOLD)
+  {
+    align = 1;
+    size = OM_STRICT_ALIGN_SIZE(size);
+  }
+#else
+  align = 0;
+#endif
+
+  if (size > SIZEOF_OM_BIN_PAGE)
+  {
+    /* need page header */
+    max_blocks = - (long)
+      ((size+(SIZEOF_SYSTEM_PAGE-SIZEOF_OM_BIN_PAGE))+SIZEOF_SYSTEM_PAGE-1)
+      / SIZEOF_SYSTEM_PAGE;
+    sizeW = ((-max_blocks*SIZEOF_SYSTEM_PAGE) -
+             (SIZEOF_SYSTEM_PAGE - SIZEOF_OM_BIN_PAGE)) / SIZEOF_LONG;
+    om_new_specBin = om_LargeBin;
+  }
+  else
+  {
+    /* SIZEOF_OM_BIN_PAGE == max_blocks*size + r1; r1 < size */
+    /* r1 = max_blocks*(size_padding) + r2; r2 < max_blocks */
+    max_blocks = SIZEOF_OM_BIN_PAGE / size;
+    sizeW = (SIZEOF_OM_BIN_PAGE % size) / max_blocks;
+#ifdef OM_ALIGNMENT_NEEDS_WORK
+    if (align)
+      sizeW = ((size + sizeW) & ~ (SIZEOF_STRICT_ALIGNMENT - 1));
+    else
+#endif
+      sizeW = ((size + sizeW) & ~ (SIZEOF_OM_ALIGNMENT - 1));
+
+    omAssume(sizeW >= size);
+    omAssume(max_blocks*sizeW <= SIZEOF_OM_BIN_PAGE);
+    omAssume((max_blocks+1)*sizeW > SIZEOF_OM_BIN_PAGE ||
+             max_blocks*(sizeW + SIZEOF_STRICT_ALIGNMENT) > SIZEOF_OM_BIN_PAGE);
+
+    sizeW = sizeW >> LOG_SIZEOF_LONG;
+    if (size > OM_MAX_BLOCK_SIZE)
+    {
+      om_new_specBin = om_LargeBin;
+    }
+#ifdef OM_ALIGNMENT_NEEDS_WORK
+    else if (align)
+    {
+      om_new_specBin = omSmallSize2AlignedBin( size );
+    }
+#endif
+#ifdef OM_HAVE_TRACK
+    else if (track)
+    {
+      om_new_specBin = omSmallSize2TrackBin( size );
+    }
+#endif
+    else
+    {
+      om_new_specBin = omSmallSize2Bin( size );
+    }
+  }
+
+  if (om_new_specBin == om_LargeBin ||
+      om_new_specBin->max_blocks < max_blocks)
+  {
+    omSpecBin s_bin;
+#ifdef OM_HAVE_TRACK
+    if (track)
+      s_bin = omFindInSortedGList(om_SpecTrackBin, next, max_blocks, max_blocks);
+    else
+#endif
+      s_bin = omFindInSortedGList(om_SpecBin, next, max_blocks, max_blocks);
+
+    if (s_bin != NULL)
+    {
+      (s_bin->ref)++;
+      omAssume(s_bin->bin != NULL &&
+             s_bin->bin->max_blocks == s_bin->max_blocks &&
+             s_bin->bin->sizeW == sizeW);
+      return s_bin->bin;
+    }
+    s_bin = (omSpecBin) omAlloc(sizeof(omSpecBin_t));
+    s_bin->ref = 1;
+    s_bin->next = NULL;
+    s_bin->max_blocks = max_blocks;
+    s_bin->bin = (omBin) omAlloc(sizeof(omBin_t));
+    s_bin->bin->current_page = om_ZeroPage;
+    s_bin->bin->last_page = NULL;
+    s_bin->bin->next = NULL;
+    s_bin->bin->sizeW = sizeW;
+    s_bin->bin->max_blocks = max_blocks;
+    s_bin->bin->sticky = 0;
+#ifdef OM_HAVE_TRACK
+    if (track)
+    {
+      om_SpecTrackBin = omInsertInSortedGList(om_SpecTrackBin, next, max_blocks, s_bin);
+    }
+    else
+#endif
+      om_SpecBin = omInsertInSortedGList(om_SpecBin, next, max_blocks, s_bin);
+    return s_bin->bin;
+  }
+  else
+  {
+    return om_new_specBin;
+  }
+}
+
+void _omUnGetSpecBin(omBin *bin_p, int force)
+{
+  omBin bin = *bin_p;
+  if (! omIsStaticBin(bin))
+  {
+#ifdef OM_HAVE_TRACK
+    int track_bin = 0;
+#endif
+    omSpecBin s_bin;
+
+#ifdef OM_HAVE_TRACK
+    s_bin = omFindInGList(om_SpecTrackBin, next, bin, bin);
+    if (s_bin != NULL)
+      track_bin = 1;
+    else
+#endif
+        s_bin = omFindInSortedGList(om_SpecBin, next, max_blocks, bin->max_blocks);
+
+    omAssume(s_bin != NULL && bin == s_bin->bin);
+    if (s_bin != NULL)
+    {
+      (s_bin->ref)--;
+      if (s_bin->ref == 0 || force)
+      {
+#ifdef OM_HAVE_TRACK
+        if (! track_bin)
+#endif
+          omFreeKeptAddrFromBin(s_bin->bin);
+        if(s_bin->bin->last_page == NULL || force)
+        {
+#ifdef OM_HAVE_TRACK
+          if (track_bin)
+            om_SpecTrackBin = omRemoveFromSortedGList(om_SpecTrackBin, next, max_blocks, s_bin);
+          else
+#endif
+            om_SpecBin = omRemoveFromSortedGList(om_SpecBin, next, max_blocks, s_bin);
+          omFreeSize(s_bin->bin, sizeof(omBin_t));
+          omFreeSize(s_bin, sizeof(omSpecBin_t));
+        }
+      }
+    }
+  }
+  *bin_p = NULL;
+}
+
+
+/*****************************************************************
+ *
+ * Sticky business
+ *
+ *****************************************************************/
+#define omGetStickyBin(bin, sticky_tag) \
+   omFindInGList(bin, next, sticky, sticky_tag)
+
+static omBin omCreateStickyBin(omBin bin, unsigned long sticky)
+{
+  omBin s_bin = (omBin) omAlloc(sizeof(omBin_t));
+  s_bin->sticky = sticky;
+  s_bin->current_page = om_ZeroPage;
+  s_bin->last_page = NULL;
+  s_bin->max_blocks = bin->max_blocks;
+  s_bin->sizeW = bin->sizeW;
+  s_bin->next = bin->next;
+  bin->next = s_bin;
+  return s_bin;
+}
+
+unsigned long omGetMaxStickyBinTag(omBin bin)
+{
+  unsigned long sticky = 0;
+  do
+  {
+    if (bin->sticky > sticky) sticky = bin->sticky;
+    bin = bin->next;
+  }
+  while (bin != NULL);
+  return sticky;
+}
+
+unsigned long omGetNewStickyBinTag(omBin bin)
+{
+  unsigned long sticky = omGetMaxStickyBinTag(bin);
+  if (sticky < BIT_SIZEOF_LONG - 2)
+  {
+    sticky++;
+    omCreateStickyBin(bin, sticky);
+    return sticky;
+  }
+  else
+  {
+    omAssume(sticky == BIT_SIZEOF_LONG - 1);
+  }
+  return sticky;
+}
+
+void omSetStickyBinTag(omBin bin, unsigned long sticky_tag)
+{
+  omBin s_bin;
+  s_bin = omGetStickyBin(bin, sticky_tag);
+
+  if (s_bin != bin)
+  {
+    omBinPage tc, tl;
+    unsigned long ts;
+
+    if (s_bin == NULL) s_bin = omCreateStickyBin(bin, sticky_tag);
+    ts = bin->sticky;
+    tl = bin->last_page;
+    tc = bin->current_page;
+    bin->sticky = s_bin->sticky;
+    bin->current_page = s_bin->current_page;
+    bin->last_page = s_bin->last_page;
+    s_bin->sticky = ts;
+    s_bin->last_page = tl;
+    s_bin->current_page = tc;
+  }
+}
+
+void omUnSetStickyBinTag(omBin bin, unsigned long sticky)
+{
+  omAssume(omGetStickyBin(bin, 0) != NULL);
+  if (bin->sticky == sticky)
+    omSetStickyBinTag(bin, 0);
+}
+
+static void omMergeStickyPages(omBin to_bin, omBin from_bin)
+{
+#ifdef HAVE_OM_ASSUME
+  int length = omGListLength(to_bin->last_page, prev) +
+    omGListLength(from_bin->last_page, prev);
+#endif
+
+  omBinPage page = from_bin->last_page;
+  omAssume(to_bin->sizeW == from_bin->sizeW);
+  omAssume(to_bin != from_bin);
+
+  if (page == NULL) return;
+  do
+  {
+    omSetTopBinAndStickyOfPage(page, to_bin, to_bin->sticky);
+    if (page->prev == NULL) break;
+    page = page->prev;
+  }
+  while(1);
+
+  if (to_bin->last_page == NULL)
+  {
+    omAssume(to_bin->current_page == om_ZeroPage);
+    to_bin->last_page = from_bin->last_page;
+    to_bin->current_page = from_bin->current_page;
+    return;
+  }
+
+  omAssume(to_bin->current_page != om_ZeroPage &&
+           to_bin->current_page != NULL);
+
+  if (to_bin->current_page->current != NULL)
+  {
+    if (to_bin->current_page->prev == NULL)
+    {
+      from_bin->last_page->next = to_bin->current_page;
+      to_bin->current_page->prev = from_bin->last_page;
+      to_bin->current_page = from_bin->current_page;
+      return;
+    }
+    to_bin->current_page = to_bin->current_page->prev;
+  }
+  else
+  {
+    /* need to reset this here, since new current_page is going to be
+       from_bin->current_page, and only for current_page may we have
+       used_blocks != 0 && current == NULL */
+    to_bin->current_page->used_blocks = 0;
+  }
+
+
+  omAssume(to_bin->current_page != NULL &&
+           to_bin->current_page->current == NULL &&
+           to_bin->current_page->used_blocks == 0);
+
+  from_bin->last_page->next = to_bin->current_page->next;
+  if (to_bin->current_page->next != NULL)
+    to_bin->current_page->next->prev =  from_bin->last_page;
+  else
+  {
+    omAssume(to_bin->current_page == to_bin->last_page);
+    to_bin->last_page = from_bin->last_page;
+  }
+  to_bin->current_page->next = page;
+  page->prev = to_bin->current_page;
+  to_bin->current_page = from_bin->current_page;
+
+#ifdef HAVE_OM_ASSUME
+  omAssume(omGListLength(to_bin->last_page, prev) == length);
+#endif
+}
+
+void omDeleteStickyBinTag(omBin bin, unsigned long sticky)
+{
+  omBin no_sticky_bin = NULL;
+  omBin sticky_bin = NULL;
+
+  if (sticky == 0)
+  {
+    omAssume(0);
+    return;
+  }
+
+  sticky_bin = omGetStickyBin(bin, sticky);
+  if (sticky_bin != NULL)
+  {
+    no_sticky_bin = omGetStickyBin(bin, 0);
+    omAssume(no_sticky_bin != NULL && sticky_bin != no_sticky_bin);
+
+    omMergeStickyPages(no_sticky_bin, sticky_bin);
+
+    if (bin == sticky_bin)
+    {
+      sticky_bin = no_sticky_bin;
+      omSetStickyBinTag(bin, 0);
+    }
+    bin->next = omRemoveFromGList(bin->next, next, sticky_bin);
+    omFreeSize(sticky_bin, sizeof(omBin_t));
+  }
+}
+
+
+/*****************************************************************
+ *
+ * Sticky bins
+ *
+ *****************************************************************/
+omBin om_StickyBins = NULL;
+omBin omGetStickyBinOfBin(omBin bin)
+{
+  omBin new_bin = omAlloc(sizeof(omBin_t));
+  omAssume(omIsKnownTopBin(bin, 1) && ! omIsStickyBin(bin));
+  new_bin->sticky = SIZEOF_VOIDP;
+  new_bin->max_blocks = bin->max_blocks;
+  new_bin->sizeW = bin->sizeW;
+  new_bin->next = om_StickyBins;
+  om_StickyBins = new_bin;
+  new_bin->last_page = NULL;
+  new_bin->current_page = om_ZeroPage;
+#if 0
+  if (omIsSpecBin(bin))
+  {
+    omSpecBin s_bin = omFindInSortedGList(om_SpecBin, next, max_blocks, bin->max_blocks);
+    omAssume(s_bin != NULL);
+    if (s_bin != NULL)
+      s_bin->ref++;
+  }
+#endif
+  return new_bin;
+}
+
+void omMergeStickyBinIntoBin(omBin sticky_bin, omBin into_bin)
+{
+  if (! omIsOnGList(om_StickyBins, next, sticky_bin) ||
+      !sticky_bin->sticky ||
+      sticky_bin->max_blocks != into_bin->max_blocks ||
+      sticky_bin == into_bin ||
+      !omIsKnownTopBin(into_bin, 1) ||
+      omIsStickyBin(into_bin))
+  {
+#ifndef OM_NDEBUG
+    omReportError(omError_StickyBin, omError_NoError, OM_FLR,
+                  (! omIsOnGList(om_StickyBins, next, sticky_bin)  ? "unknown sticky_bin" :
+                   (!sticky_bin->sticky ? "sticky_bin is not sticky" :
+                    (sticky_bin->max_blocks != into_bin->max_blocks ? "sticky_bin and into_bin have different block sizes" :
+                     (sticky_bin == into_bin ? "sticky_bin == into_bin" :
+                      (!omIsKnownTopBin(into_bin, 1) ? "unknown into_bin" :
+                       (omIsStickyBin(into_bin) ? "into_bin is sticky" :
+                        "unknown sticky_bin error")))))));
+#endif
+    return;
+  }
+  omFreeKeptAddrFromBin(sticky_bin);
+  om_StickyBins = omRemoveFromGList(om_StickyBins, next, sticky_bin);
+  omMergeStickyPages(into_bin, sticky_bin);
+
+#if 0
+  if (! omIsStaticBin(into_bin))
+  {
+    omBin _ibin = into_bin;
+    omUnGetSpecBin(&_ibin);
+  }
+#endif
+  omFreeSize(sticky_bin, sizeof(omBin_t));
+#if defined(OM_INTERNAL_DEBUG) && !defined(OM_NDEBUG)
+  omTestBin(into_bin, 2);
+#endif
+}
+
+/*****************************************************************
+*
+* AllBin business
+*
+*****************************************************************/
+#ifndef OM_NDEBUG
+int omIsKnownTopBin(omBin bin, int normal_bin)
+{
+  omBin to_check;
+  omSpecBin s_bin;
+  int i;
+
+  omAssume(normal_bin == 1 || normal_bin == 0);
+
+#ifdef OM_HAVE_TRACK
+  if (! normal_bin)
+  {
+    to_check = om_StaticTrackBin;
+    s_bin = om_SpecTrackBin;
+  }
+  else
+#endif
+  {
+    omAssume(normal_bin);
+    to_check = om_StaticBin;
+    s_bin = om_SpecBin;
+  }
+
+  for (i=0; i<= OM_MAX_BIN_INDEX; i++)
+  {
+    if (bin == &(to_check[i]))
+      return 1;
+  }
+
+  while (s_bin != NULL)
+  {
+    if (bin == s_bin->bin) return 1;
+    s_bin = s_bin->next;
+  }
+  to_check = om_StickyBins;
+
+  while (to_check != NULL)
+  {
+    if (bin == to_check) return 1;
+    to_check = to_check->next;
+  }
+  return 0;
+}
+#endif
+
+unsigned long omGetNewStickyAllBinTag()
+{
+  unsigned long sticky = 0, new_sticky;
+  int i;
+  omSpecBin s_bin;
+  // first, find new sticky tag
+  for (i=0; i<=OM_MAX_BIN_INDEX; i++)
+  {
+    new_sticky = omGetMaxStickyBinTag(&(om_StaticBin[i]));
+    if (new_sticky > sticky) sticky = new_sticky;
+  }
+  s_bin = om_SpecBin;
+  while (s_bin != NULL)
+  {
+    new_sticky = omGetMaxStickyBinTag(s_bin->bin);
+    if (new_sticky > sticky) sticky = new_sticky;
+    s_bin = s_bin->next;
+  }
+  if (sticky < BIT_SIZEOF_LONG - 2)
+  {
+    sticky++;
+    for (i=0; i<=OM_MAX_BIN_INDEX; i++)
+    {
+      omCreateStickyBin(&(om_StaticBin[i]), sticky);
+    }
+    s_bin = om_SpecBin;
+    while (s_bin != NULL)
+    {
+      omCreateStickyBin(s_bin->bin, sticky);
+      s_bin = s_bin->next;
+    }
+    return sticky;
+  }
+  else
+  {
+    omBin bin;
+    omAssume(sticky == BIT_SIZEOF_LONG - 1);
+    for (i=0; i<=OM_MAX_BIN_INDEX; i++)
+    {
+      bin = &om_StaticBin[i];
+      if (omGetStickyBin(bin, BIT_SIZEOF_LONG -1) == NULL)
+        omCreateStickyBin(bin, BIT_SIZEOF_LONG -1);
+    }
+    s_bin = om_SpecBin;
+    while (s_bin != NULL)
+    {
+      if (omGetStickyBin(s_bin->bin, BIT_SIZEOF_LONG -1) == NULL)
+        omCreateStickyBin(s_bin->bin, BIT_SIZEOF_LONG -1);
+      s_bin = s_bin->next;
+    }
+    return BIT_SIZEOF_LONG - 1;
+  }
+}
+
+void omSetStickyAllBinTag(unsigned long sticky)
+{
+  omSpecBin s_bin = om_SpecBin;
+  int i;
+  for (i=0; i<=OM_MAX_BIN_INDEX; i++)
+  {
+    omSetStickyBinTag(&(om_StaticBin[i]), sticky);
+  }
+  while (s_bin != NULL)
+  {
+    omSetStickyBinTag(s_bin->bin, sticky);
+    s_bin = s_bin->next;
+  }
+}
+
+void omUnSetStickyAllBinTag(unsigned long sticky)
+{
+  omSpecBin s_bin = om_SpecBin;
+  int i;
+  for (i=0; i<=OM_MAX_BIN_INDEX; i++)
+  {
+    omUnSetStickyBinTag(&(om_StaticBin[i]), sticky);
+  }
+  while (s_bin != NULL)
+  {
+    omUnSetStickyBinTag(s_bin->bin, sticky);
+    s_bin = s_bin->next;
+  }
+}
+
+void omDeleteStickyAllBinTag(unsigned long sticky)
+{
+  omSpecBin s_bin = om_SpecBin;
+  int i;
+  for (i=0; i<=OM_MAX_BIN_INDEX; i++)
+  {
+    omDeleteStickyBinTag(&(om_StaticBin[i]), sticky);
+  }
+  while (s_bin != NULL)
+  {
+    omDeleteStickyBinTag(s_bin->bin, sticky);
+    s_bin = s_bin->next;
+  }
+}
+
+#if 0
+void omPrintMissing(omBin bin)
+{
+  omBinPage page = bin->last_page;
+
+  while (page != NULL)
+  {
+    void* addr = (void*) page + SIZEOF_OM_BIN_PAGE_HEADER;
+    int i;
+
+    for (i=0; i<bin->max_blocks; i++)
+    {
+      if (! omIsOnList(page->current, addr))
+        printf("%d:%p\n", i, addr);
+      addr += bin->sizeW*SIZEOF_LONG;
+    }
+    page = page->prev;
+  }
+}
+#endif
+
+/*****************************************************************
+ *
+ * Statistics
+ *
+ *****************************************************************/
+static void omGetBinStat(omBin bin, int *pages_p, int *used_blocks_p,
+                          int *free_blocks_p)
+{
+  int pages = 0, used_blocks = 0, free_blocks = 0;
+  int where = 1;
+
+  omBinPage page = bin->last_page;
+  while (page != NULL)
+  {
+    pages++; if (where == 1)
+    {
+      used_blocks += omGetUsedBlocksOfPage(page) + 1;
+      if (bin->max_blocks > 0)
+        free_blocks += bin->max_blocks - omGetUsedBlocksOfPage(page) -1;
+    }
+    else
+    {
+      if (bin->max_blocks > 1)
+        used_blocks += bin->max_blocks;
+      else
+        used_blocks++;
+    }
+    if (page == bin->current_page) where = -1;
+    page = page->prev;
+  }
+  *pages_p = pages;
+  *used_blocks_p = used_blocks;
+  *free_blocks_p = free_blocks;
+}
+
+static void omGetTotalBinStat(omBin bin, int *pages_p, int *used_blocks_p,
+                               int *free_blocks_p)
+{
+  int t_pages = 0, t_used_blocks = 0, t_free_blocks = 0;
+  int pages = 0, used_blocks = 0, free_blocks = 0;
+
+  while (bin != NULL)
+  {
+    omGetBinStat(bin, &pages, &used_blocks, &free_blocks);
+    t_pages += pages;
+    t_used_blocks += used_blocks;
+    t_free_blocks += free_blocks;
+    if (!omIsStickyBin(bin))
+      bin = bin->next;
+    else
+      bin = NULL;
+  }
+  *pages_p = t_pages;
+  *used_blocks_p = t_used_blocks;
+  *free_blocks_p = t_free_blocks;
+}
+
+static void omPrintBinStat(FILE * fd, omBin bin, int track, int* pages, int* used_blocks, int* free_blocks)
+{
+  if (track)
+  {
+    fprintf(fd, "T \t \t");
+  }
+  else
+  {
+    fprintf(fd, "%s%ld\t%ld\t", (omIsStaticNormalBin(bin) ? " " :
+                                (omIsStickyBin(bin) ? "S" :
+                                 (omIsTrackBin(bin) ? "T" : "*"))),
+            (long)bin->sizeW, bin->max_blocks);
+  }
+  omGetTotalBinStat(bin, pages, used_blocks, free_blocks);
+  fprintf(fd, "%d\t%d\t%d\n", *pages, *free_blocks, *used_blocks);
+  if (bin->next != NULL && !omIsStickyBin(bin))
+  {
+    int s_pages, s_free_blocks, s_used_blocks;
+    while (bin != NULL)
+    {
+      omGetBinStat(bin, &s_pages, &s_used_blocks, &s_free_blocks);
+      fprintf(fd, " \t \t%d\t%d\t%d\t%d\n", s_pages, s_free_blocks, s_used_blocks,
+              (int) bin->sticky);
+      bin = bin->next;
+      *pages += s_pages;
+      *used_blocks += s_used_blocks;
+      *free_blocks += s_free_blocks;
+    }
+  }
+}
+
+void omPrintBinStats(FILE* fd)
+{
+  int i = OM_MAX_BIN_INDEX, pages=0, used_blocks=0, free_blocks=0;
+  int pages_p, used_blocks_p, free_blocks_p;
+  omSpecBin s_bin = om_SpecBin;
+  omBin sticky;
+
+  fprintf(fd, " SizeW\tBlocks\tUPages\tFBlocks\tUBlocks\tSticky\n");
+  fflush(fd);
+  while (s_bin != NULL || i >= 0)
+  {
+    if (s_bin == NULL || (i >= 0 && (unsigned long) om_StaticBin[i].max_blocks < (unsigned long) s_bin->bin->max_blocks))
+    {
+       omPrintBinStat(fd, &om_StaticBin[i], 0, &pages_p, &used_blocks_p, &free_blocks_p);
+       pages += pages_p;
+       used_blocks += used_blocks_p;
+       free_blocks += free_blocks_p;
+#ifdef OM_HAVE_TRACK
+       if (om_StaticTrackBin[i].current_page != om_ZeroPage)
+       {
+         omPrintBinStat(fd, &om_StaticTrackBin[i], 1, &pages_p, &used_blocks_p, &free_blocks_p);
+         pages += pages_p;
+         used_blocks += used_blocks_p;
+         free_blocks += free_blocks_p;
+       }
+#endif
+       i--;
+    }
+    else
+    {
+      omPrintBinStat(fd, s_bin->bin,0, &pages_p, &used_blocks_p, &free_blocks_p);
+      pages += pages_p;
+      used_blocks += used_blocks_p;
+      free_blocks += free_blocks_p;
+      s_bin = s_bin->next;
+    }
+  }
+#ifdef OM_HAVE_TRACK
+  s_bin = om_SpecTrackBin;
+  while (s_bin != NULL)
+  {
+    omPrintBinStat(fd, s_bin->bin, 0,  &pages_p, &used_blocks_p, &free_blocks_p);
+    s_bin = s_bin->next;
+    pages += pages_p;
+    used_blocks += used_blocks_p;
+    free_blocks += free_blocks_p;
+  }
+#endif
+  sticky = om_StickyBins;
+  while (sticky != NULL)
+  {
+    omPrintBinStat(fd, sticky, 0,  &pages_p, &used_blocks_p, &free_blocks_p);
+    sticky = sticky->next;
+    pages += pages_p;
+    used_blocks += used_blocks_p;
+    free_blocks += free_blocks_p;
+  }
+  fprintf(fd, "----------------------------------------\n");
+  fprintf(fd, "      \t      \t%d\t%d\t%d\n", pages, free_blocks, used_blocks);
+}
+
+static long omGetUsedBytesOfBin(omBin bin)
+{
+  int pages = 0, used_blocks = 0, free_blocks = 0;
+  omGetTotalBinStat(bin, &pages, &used_blocks, &free_blocks);
+  return ((long)used_blocks)*((long)bin->sizeW)*SIZEOF_LONG;
+}
+
+long omGetUsedBinBytes()
+{
+  int i = OM_MAX_BIN_INDEX;
+  omSpecBin s_bin = om_SpecBin;
+  long used = 0;
+  omBin sticky;
+
+  for (; i>=0; i--)
+  {
+    used += omGetUsedBytesOfBin(&om_StaticBin[i]);
+  }
+  while (s_bin != NULL)
+  {
+    used += omGetUsedBytesOfBin(s_bin->bin);
+    s_bin = s_bin->next;
+  }
+#ifdef OM_HAVE_TRACK
+  for (i=OM_MAX_BIN_INDEX; i>=0; i--)
+  {
+    used += omGetUsedBytesOfBin(&om_StaticTrackBin[i]);
+  }
+  s_bin = om_SpecTrackBin;
+  while (s_bin != NULL)
+  {
+    used += omGetUsedBytesOfBin(s_bin->bin);
+    s_bin = s_bin->next;
+  }
+#endif
+
+  sticky = om_StickyBins;
+  while (sticky != NULL)
+  {
+    used += omGetUsedBytesOfBin(sticky);
+    sticky = sticky->next;
+  }
+  return used;
+}
diff --git a/omalloc/omBin.h b/omalloc/omBin.h
new file mode 100644
index 0000000..fc32b47
--- /dev/null
+++ b/omalloc/omBin.h
@@ -0,0 +1,62 @@
+/*******************************************************************
+ *  File:    omBin.h
+ *  Purpose: declaration of routines related to Bins
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 11/99
+ *******************************************************************/
+#ifndef OM_BIN_H
+#define OM_BIN_H
+
+#define omGetAlignedSpecBin(size) _omGetSpecBin(size, 1, 0)
+#define omGetSpecBin(size) _omGetSpecBin(size, 0, 0)
+omBin _omGetSpecBin(size_t size, int align, int track);
+
+#define omUnGetSpecBin(bin_ptr) _omUnGetSpecBin(bin_ptr, 0)
+#define omDeleteSpecBin(bin_ptr) _omUnGetSpecBin(bin_ptr, 1)
+void _omUnGetSpecBin(omBin *bin, int force);
+long omGetUsedBinBytes();
+
+omBin omGetStickyBinOfBin(omBin bin);
+void omMergeStickyBinIntoBin(omBin sticky_bin, omBin into_bin);
+
+unsigned long omGetNewStickyBinTag(omBin bin);
+void omSetStickyBinTag(omBin bin, unsigned long sticky);
+void omUnSetStickyBinTag(omBin bin, unsigned long sticky);
+void omDeleteStickyBinTag(omBin bin, unsigned long sticky);
+
+unsigned long omGetNewStickyAllBinTag();
+void omSetStickyAllBinTag(unsigned long sticky);
+void omUnSetStickyAllBinTag(unsigned long sticky);
+void omDeleteStickyAllBinTag(unsigned long sticky);
+
+void omPrintBinStats(FILE* fd);
+#define omIsStickyBin(bin) (bin->sticky >= SIZEOF_VOIDP)
+
+/*BEGINPRIVATE*/
+#ifndef OM_NDEBUG
+int omIsKnownTopBin(omBin bin, int normal_bin);
+#endif
+#ifdef OM_HAVE_TRACK
+#define omGetSpecTrackBin(size) _omGetSpecBin(size, 0, 1)
+#endif
+
+#define omIsStaticNormalBin(bin)                                            \
+ ((unsigned long) bin >= ((unsigned long) &om_StaticBin[0]) &&              \
+  (unsigned long) bin <= ((unsigned long) &om_StaticBin[OM_MAX_BIN_INDEX]))
+#define omIsNormalBin(bin) omIsStaticNormalBin(bin) || omFindInGList(om_SpecBin, next, bin, bin) || omIsStickyBin(bin)
+#define omIsSpecBin(bin) (!omIsStaticNormalBin(bin) && !omIsStickyBin(bin))
+
+#ifdef OM_HAVE_TRACK
+#define omIsStaticTrackBin(bin)                                                  \
+ ((unsigned long) bin >= ((unsigned long) &om_StaticTrackBin[0]) &&              \
+  (unsigned long) bin <= ((unsigned long) &om_StaticTrackBin[OM_MAX_BIN_INDEX]))
+#define omIsTrackBin(bin) omIsStaticTrackBin(bin) || omFindInGList(om_SpecTrackBin, next, bin, bin)
+#else
+#define omIsKnownTopBin(bin, normal_bin)  1
+#define omIsStaticTrackBin(bin) 0
+#define omIsTrackBin(bin)       0
+#endif
+#define omIsStaticBin(bin) omIsStaticNormalBin(bin) || omIsStaticTrackBin(bin)
+/*ENDPRIVATE*/
+
+#endif /* OM_BIN_H */
diff --git a/omalloc/omBinPage.c b/omalloc/omBinPage.c
new file mode 100644
index 0000000..fb7b1ab
--- /dev/null
+++ b/omalloc/omBinPage.c
@@ -0,0 +1,606 @@
+/*******************************************************************
+ *  File:    omBinPage.c
+ *  Purpose: implementation of routines for primitve BinPage managment
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 11/99
+ *******************************************************************/
+#include <mylimits.h>
+#include "omalloc.h"
+#include "omDefaultConfig.h"
+
+/*******************************************************************
+ *
+ * Local declarations
+ *
+ *******************************************************************/
+
+/* define if you want to keep regions approximately in order */
+#define OM_KEEP_REGIONS_ORDER
+
+struct omBinPageRegion_s
+{
+  void* current;        /* linked list of free pages */
+  omBinPageRegion next; /* nex/prev pointer in ring of regions */
+  omBinPageRegion prev;
+  char* init_addr;      /* pointer portion of inital chunk which is still free */
+  char* addr;         /* addr returned by alloc */
+  int   init_pages;   /* number of pages still available in init_chunk */
+  int   used_pages;     /* number of used pages */
+  int pages;          /* total size of region */
+};
+
+/* globale variable holding pointing int regions ring */
+static omBinPageRegion om_CurrentBinPageRegion = NULL;
+unsigned long om_MaxBinPageIndex = 0;
+unsigned long om_MinBinPageIndex = ULONG_MAX;
+unsigned long *om_BinPageIndicies = NULL;
+
+/* declaration of local procs */
+static void* omTakeOutConsecutivePages(omBinPageRegion region, int how_many);
+static omBinPageRegion omAllocNewBinPagesRegion(int min_pages);
+static void omFreeBinPagesRegion(omBinPageRegion region);
+
+static void omBinPageIndexFault(unsigned long low_index, unsigned long high_index);
+static void omRegisterBinPages(void* low_addr, int pages);
+static void omUnregisterBinPages(void* low_addr, int pages);
+
+OM_INLINE_LOCAL void omTakeOutRegion(omBinPageRegion region)
+{
+  omAssume(region != NULL);
+
+  if (region->prev != NULL)
+  {
+    omAssume(region->prev != region && region->prev != region->next);
+    region->prev->next = region->next;
+  }
+
+  if (region->next != NULL)
+  {
+    omAssume(region->next != region && region->prev != region->next);
+    region->next->prev = region->prev;
+  }
+}
+
+OM_INLINE_LOCAL void omInsertRegionAfter(omBinPageRegion insert, omBinPageRegion after)
+{
+  omAssume(insert != NULL && after != NULL && insert != after);
+  insert->next = after->next;
+  insert->prev = after;
+  after->next = insert;
+  if (insert->next != NULL)
+  {
+    omAssume(insert->next != insert && insert->next != after);
+    insert->next->prev = insert;
+  }
+}
+
+OM_INLINE_LOCAL void omInsertRegionBefore(omBinPageRegion insert, omBinPageRegion before)
+{
+  omAssume(insert != NULL && before != NULL && insert != before);
+  insert->prev = before->prev;
+  insert->next = before;
+  before->prev = insert;
+  if (insert->prev != NULL)
+    insert->prev->next = insert;
+}
+
+
+/*******************************************************************
+ *
+ * Alloc/Free of BinPages
+ *
+ *******************************************************************/
+#define NEXT_PAGE(page) *((void**) page)
+#define OM_IS_EMPTY_REGION(region) ((region)->current == NULL && (region->init_addr == NULL))
+
+omBinPage omAllocBinPage()
+{
+  omBinPage bin_page;
+
+  if (om_CurrentBinPageRegion == NULL)
+    om_CurrentBinPageRegion = omAllocNewBinPagesRegion(1);
+
+  while (1)
+  {
+    if (om_CurrentBinPageRegion->current != NULL)
+    {
+      bin_page = om_CurrentBinPageRegion->current;
+      om_CurrentBinPageRegion->current = NEXT_PAGE(bin_page);
+      goto Found;
+    }
+    if (om_CurrentBinPageRegion->init_pages > 0)
+    {
+      bin_page = (omBinPage)om_CurrentBinPageRegion->init_addr;
+      om_CurrentBinPageRegion->init_pages--;
+      if (om_CurrentBinPageRegion->init_pages > 0)
+        om_CurrentBinPageRegion->init_addr += SIZEOF_SYSTEM_PAGE;
+      else
+        om_CurrentBinPageRegion->init_addr = NULL;
+      goto Found;
+    }
+    if (om_CurrentBinPageRegion->next != NULL)
+    {
+      om_CurrentBinPageRegion = om_CurrentBinPageRegion->next;
+    }
+    else
+    {
+      omBinPageRegion new_region = omAllocNewBinPagesRegion(1);
+      new_region->prev = om_CurrentBinPageRegion;
+      om_CurrentBinPageRegion->next = new_region;
+      om_CurrentBinPageRegion = new_region;
+    }
+  }
+
+  Found:
+  bin_page->region = om_CurrentBinPageRegion;
+  om_CurrentBinPageRegion->used_pages++;
+
+  om_Info.UsedPages++;
+  om_Info.AvailPages--;
+  if (om_Info.UsedPages > om_Info.MaxPages)
+    om_Info.MaxPages = om_Info.UsedPages;
+
+  OM_ALLOC_BINPAGE_HOOK;
+  return bin_page;
+}
+
+omBinPage omAllocBinPages(int how_many)
+{
+  omBinPage bin_page;
+  omBinPageRegion region;
+
+  if (om_CurrentBinPageRegion == NULL)
+    om_CurrentBinPageRegion = omAllocNewBinPagesRegion(how_many);
+
+  region = om_CurrentBinPageRegion;
+  while (1)
+  {
+    if (region->init_pages >= how_many)
+    {
+      bin_page = (omBinPage)region->init_addr;
+      region->init_pages -= how_many;
+      if (region->init_pages)
+        region->init_addr += how_many*SIZEOF_SYSTEM_PAGE;
+      else
+        region->init_addr = NULL;
+      goto Found;
+    }
+    if ((bin_page = omTakeOutConsecutivePages(region, how_many)) != NULL)
+    {
+      goto Found;
+    }
+    if (region->next != NULL)
+    {
+      region = region->next;
+    }
+    else
+    {
+      omBinPageRegion new_region = omAllocNewBinPagesRegion(how_many);
+      region->next = new_region;
+      new_region->prev = region;
+      region = new_region;
+    }
+  }
+  /*while (1) */
+
+  Found:
+  bin_page->region = region;
+  region->used_pages += how_many;
+
+  if (region != om_CurrentBinPageRegion && OM_IS_EMPTY_REGION(region))
+  {
+    omTakeOutRegion(region);
+    omInsertRegionBefore(region, om_CurrentBinPageRegion);
+  }
+  om_Info.UsedPages += how_many;
+  om_Info.AvailPages -= how_many;
+  if (om_Info.UsedPages > om_Info.MaxPages)
+    om_Info.MaxPages = om_Info.UsedPages;
+
+  OM_ALLOC_BINPAGE_HOOK;
+  return bin_page;
+}
+
+void omFreeBinPages(omBinPage bin_page, int how_many)
+{
+  omBinPageRegion region = bin_page->region;
+
+  region->used_pages -= how_many;
+  if (region->used_pages == 0)
+  {
+    if (region == om_CurrentBinPageRegion)
+    {
+      if (region->next != NULL)
+        om_CurrentBinPageRegion = region->next;
+      else
+        om_CurrentBinPageRegion = region->prev;
+    }
+    omTakeOutRegion(region);
+    omFreeBinPagesRegion(region);
+  }
+  else
+  {
+    if (region != om_CurrentBinPageRegion && OM_IS_EMPTY_REGION(region))
+    {
+      omTakeOutRegion(region);
+      omInsertRegionAfter(region, om_CurrentBinPageRegion);
+    }
+    if (how_many > 1)
+    {
+      int i = how_many;
+      char* page = (char *)bin_page;
+
+      while (i > 1)
+      {
+        NEXT_PAGE(page) = page + SIZEOF_SYSTEM_PAGE;
+        page = NEXT_PAGE(page);
+        i--;
+      }
+      NEXT_PAGE(page) = region->current;
+    }
+    else
+    {
+      NEXT_PAGE(bin_page) = region->current;
+    }
+    region->current = (void*) bin_page;
+  }
+  om_Info.AvailPages += how_many;
+  om_Info.UsedPages -= how_many;
+  OM_FREE_BINPAGE_HOOK;
+}
+
+static void* omTakeOutConsecutivePages(omBinPageRegion region, int pages)
+{
+  void* current;
+  char* iter;
+  void* prev = NULL;
+  void* bin_page;
+  int found;
+  current = region->current;
+  while (current != NULL)
+  {
+    found = 1;
+    iter = current;
+    while (NEXT_PAGE(iter) == (iter + SIZEOF_SYSTEM_PAGE))
+    {
+      iter = NEXT_PAGE(iter);
+      /* handle pathological case that iter + SIZEOF_SYSTEM_PAGE == 0 */
+      if (iter == NULL) return NULL;
+      found++;
+      if (found == pages)
+      {
+        bin_page = current;
+        if (current == region->current)
+        {
+          region->current = NEXT_PAGE(iter);
+        }
+        else
+        {
+          omAssume(prev != NULL);
+          NEXT_PAGE(prev) = NEXT_PAGE(iter);
+        }
+        return bin_page;
+      }
+    }
+    prev = iter;
+    current = NEXT_PAGE(iter);
+  }
+  return NULL;
+}
+
+/* Alloc a new region and insert into regions ring, set current to new region */
+static omBinPageRegion omAllocNewBinPagesRegion(int min_pages)
+{
+  omBinPageRegion region = omAllocFromSystem(sizeof(omBinPageRegion_t));
+  void* addr;
+  int pages = (min_pages>om_Opts.PagesPerRegion ? min_pages : om_Opts.PagesPerRegion);
+  size_t size = pages*SIZEOF_SYSTEM_PAGE;
+
+  addr = _omVallocFromSystem(size, 1);
+  if (addr == NULL)
+  {
+    pages = min_pages;
+    size = min_pages*SIZEOF_SYSTEM_PAGE;
+    addr = omVallocFromSystem(size);
+  }
+
+  omRegisterBinPages(addr, pages);
+  region->addr = addr;
+  region->pages = pages;
+  region->used_pages = 0;
+  region->init_addr = addr;
+  region->init_pages = pages;
+  region->current = NULL;
+  region->next = NULL;
+  region->prev = NULL;
+
+  om_Info.AvailPages += pages;
+
+  om_Info.CurrentRegionsAlloc++;
+  if (om_Info.CurrentRegionsAlloc > om_Info.MaxRegionsAlloc)
+    om_Info.MaxRegionsAlloc = om_Info.CurrentRegionsAlloc;
+
+  return region;
+}
+
+/* Free region */
+static void omFreeBinPagesRegion(omBinPageRegion region)
+{
+  omAssume(region != NULL && region->used_pages == 0);
+
+  om_Info.AvailPages -= region->pages;
+  om_Info.CurrentRegionsAlloc--;
+
+  omUnregisterBinPages(region->addr, region->pages);
+  omVfreeToSystem(region->addr, region->pages*SIZEOF_SYSTEM_PAGE);
+  omFreeSizeToSystem(region, sizeof(omBinPageRegion_t));
+}
+
+/*******************************************************************
+ *
+ * BinPage registration
+ *
+ *******************************************************************/
+
+static void omBinPageIndexFault(unsigned long low_index, unsigned long high_index)
+{
+  unsigned long index_diff = high_index - low_index;
+  long i;
+  omAssume(low_index <= high_index &&
+           (high_index > om_MaxBinPageIndex || low_index < om_MinBinPageIndex));
+
+  if (om_BinPageIndicies == NULL)
+  {
+    om_BinPageIndicies = (unsigned long*) omAllocFromSystem((index_diff + 1)*SIZEOF_LONG);
+    om_MaxBinPageIndex = high_index;
+    om_MinBinPageIndex = low_index;
+    for (i=0; i<=index_diff; i++) om_BinPageIndicies[i] = 0;
+  }
+  else
+  {
+    unsigned long old_length = om_MaxBinPageIndex - om_MinBinPageIndex + 1;
+    unsigned long new_length = (low_index < om_MinBinPageIndex ?
+                                om_MaxBinPageIndex - low_index :
+                                high_index - om_MinBinPageIndex) + 1;
+    om_BinPageIndicies  = (unsigned long*) omReallocSizeFromSystem(om_BinPageIndicies, old_length*SIZEOF_LONG,
+                                                                   new_length*SIZEOF_LONG);
+    if (low_index < om_MinBinPageIndex)
+    {
+      unsigned long offset = new_length - old_length;
+      for (i=old_length - 1; i >= 0; i--) om_BinPageIndicies[i+offset] = om_BinPageIndicies[i];
+      for (i=0; i<offset; i++)  om_BinPageIndicies[i] = 0;
+      om_MinBinPageIndex = low_index;
+    }
+    else
+    {
+      for (i=old_length; i<new_length; i++) om_BinPageIndicies[i] = 0;
+      om_MaxBinPageIndex = high_index;
+    }
+  }
+}
+
+static void omRegisterBinPages(void* low_addr, int pages)
+{
+  unsigned long low_index = omGetPageIndexOfAddr(low_addr);
+  char* high_addr = (char *)low_addr + (pages-1)*SIZEOF_SYSTEM_PAGE;
+  unsigned long high_index = omGetPageIndexOfAddr(high_addr);
+  unsigned long shift;
+
+  if (low_index < om_MinBinPageIndex || high_index > om_MaxBinPageIndex)
+    omBinPageIndexFault(low_index, high_index);
+
+  shift = omGetPageShiftOfAddr(low_addr);
+  if (low_index < high_index)
+  {
+    if (shift == 0)
+    {
+      om_BinPageIndicies[low_index-om_MinBinPageIndex] = ULONG_MAX;
+    }
+    else
+    {
+      om_BinPageIndicies[low_index-om_MinBinPageIndex] |= ~ ((((unsigned long) 1) << shift) - 1);
+    }
+    for (shift = low_index+1; shift < high_index; shift++)
+    {
+      om_BinPageIndicies[shift-om_MinBinPageIndex] = ULONG_MAX;
+    }
+    shift = omGetPageShiftOfAddr(high_addr);
+    if (shift == BIT_SIZEOF_LONG - 1)
+    {
+      om_BinPageIndicies[high_index - om_MinBinPageIndex] = ULONG_MAX;
+    }
+    else
+    {
+      om_BinPageIndicies[high_index-om_MinBinPageIndex] |= ((((unsigned long) 1) << (shift + 1)) - 1);
+    }
+  }
+  else
+  {
+    high_index = omGetPageShiftOfAddr(high_addr);
+    while (high_index > shift)
+    {
+      om_BinPageIndicies[low_index-om_MinBinPageIndex] |= (((unsigned long) 1) << high_index);
+      high_index--;
+    }
+    om_BinPageIndicies[low_index-om_MinBinPageIndex] |= (((unsigned long) 1) << shift);
+  }
+}
+
+static void omUnregisterBinPages(void* low_addr, int pages)
+{
+  unsigned long low_index = omGetPageIndexOfAddr(low_addr);
+  char* high_addr = (char *)low_addr + (pages-1)*SIZEOF_SYSTEM_PAGE;
+  unsigned long high_index = omGetPageIndexOfAddr(high_addr);
+  unsigned long shift;
+
+  shift = omGetPageShiftOfAddr(low_addr);
+  if (low_index < high_index)
+  {
+    if (shift == 0)
+    {
+      om_BinPageIndicies[low_index-om_MinBinPageIndex] = 0;
+    }
+    else
+    {
+      om_BinPageIndicies[low_index-om_MinBinPageIndex] &= ((((unsigned long) 1) << shift) - 1);
+    }
+    for (shift = low_index+1; shift < high_index; shift++)
+    {
+      om_BinPageIndicies[shift-om_MinBinPageIndex] = 0;
+    }
+    shift = omGetPageShiftOfAddr(high_addr);
+    if (shift == BIT_SIZEOF_LONG - 1)
+    {
+      om_BinPageIndicies[high_index - om_MinBinPageIndex] = 0;
+    }
+    else
+    {
+      om_BinPageIndicies[high_index-om_MinBinPageIndex] &= ~ ((((unsigned long) 1) << (shift + 1)) - 1);
+    }
+  }
+  else
+  {
+     high_index = omGetPageShiftOfAddr(high_addr);
+     while (high_index > shift)
+     {
+       om_BinPageIndicies[low_index-om_MinBinPageIndex] &= ~(((unsigned long) 1) << high_index);
+       high_index--;
+     }
+     om_BinPageIndicies[low_index-om_MinBinPageIndex] &= ~(((unsigned long) 1) << shift);
+  }
+}
+
+/***********************************************************************
+ *
+ * checking routines
+ *
+ *******************************************************************/
+#ifndef OM_NDEBUG
+#include "omDebug.h"
+
+int omIsKnownMemoryRegion(omBinPageRegion region)
+{
+  omBinPageRegion iter = om_CurrentBinPageRegion;
+
+  if (region == NULL || iter == NULL) return 0;
+  iter = omGListLast(om_CurrentBinPageRegion, prev);
+  do
+  {
+    if (region == iter) return 1;
+    iter = iter->next;
+  }
+  while (iter != NULL);
+  return 0;
+}
+
+
+omError_t omCheckBinPageRegion(omBinPageRegion region, int level, omError_t report, OM_FLR_DECL)
+{
+  if (level <= 0) return omError_NoError;
+
+  omCheckReturn(omCheckPtr(region, report, OM_FLR_VAL));
+  omCheckReturnCorrupted(! omIsKnownMemoryRegion(region));
+  omCheckReturnCorrupted(! omIsAddrPageAligned(region->addr) || ! omIsAddrPageAligned(region->current));
+  omCheckReturnCorrupted(region->used_pages < 0);
+  omCheckReturnCorrupted(region->init_pages < 0 || region->init_pages > region->pages);
+
+  if (region->init_pages)
+  {
+    omCheckReturnCorrupted(! omIsAddrPageAligned(region->init_addr));
+    omCheckReturnCorrupted(! (region->init_addr >= region->addr
+                              && region->init_addr <= region->addr + (region->pages -1)*SIZEOF_SYSTEM_PAGE));
+    omCheckReturnCorrupted(region->init_addr !=
+                           region->addr + (region->pages - region->init_pages)*SIZEOF_SYSTEM_PAGE);
+  }
+
+  omCheckReturn(omCheckList(region->current, level, report, OM_FLR_VAL));
+  omCheckReturnCorrupted(region->current == NULL && region->used_pages + region->init_pages != region->pages);
+  omCheckReturnCorrupted(level > 1 &&
+                         omListLength(region->current)+region->used_pages+region->init_pages != region->pages);
+  return omError_NoError;
+}
+
+omError_t omCheckBinPageRegions(int level, omError_t report, OM_FLR_DECL)
+{
+  omBinPageRegion iter = om_CurrentBinPageRegion;
+
+  if (level <= 0) return omError_NoError;
+  if (iter == NULL) return omError_NoError;
+
+  omCheckReturnError(om_CurrentBinPageRegion->next != NULL && OM_IS_EMPTY_REGION(om_CurrentBinPageRegion->next),
+                     omError_InternalBug);
+  omCheckReturnError(om_CurrentBinPageRegion->prev != NULL && ! OM_IS_EMPTY_REGION(om_CurrentBinPageRegion->prev),
+                     omError_InternalBug);
+
+
+  if (level > 1)
+  {
+    omBinPageRegion prev_last = (omBinPageRegion) omGListLast(om_CurrentBinPageRegion, prev);
+    omBinPageRegion next_last = (omBinPageRegion) omGListLast(om_CurrentBinPageRegion, next);
+
+    omCheckReturn(omCheckGList(iter, next, level, report, OM_FLR_VAL));
+    omCheckReturn(omCheckGList(iter, prev, level, report, OM_FLR_VAL));
+
+    omCheckReturnCorrupted(omGListLength(prev_last, next)
+                          !=
+                          omGListLength(next_last, prev));
+
+    omCheckReturn(omCheckBinPageRegion(om_CurrentBinPageRegion, level - 1, report, OM_FLR_VAL));
+
+    iter = om_CurrentBinPageRegion->next;
+    while (iter)
+    {
+      omCheckReturnError(OM_IS_EMPTY_REGION(iter), omError_InternalBug);
+
+      omCheckReturn(omCheckBinPageRegion(iter, level - 1, report, OM_FLR_VAL));
+      iter = iter->next;
+    }
+
+    iter = om_CurrentBinPageRegion->prev;
+    while (iter)
+    {
+      omCheckReturnError( !OM_IS_EMPTY_REGION(iter), omError_InternalBug);
+      omCheckReturn(omCheckBinPageRegion(iter, level - 1, report, OM_FLR_VAL));
+      iter = iter->prev;
+    }
+  }
+  return omError_NoError;
+}
+
+omBinPageRegion omFindRegionOfAddr(void* addr)
+{
+  omBinPageRegion region = om_CurrentBinPageRegion;
+
+  if (region == NULL) return 0;
+  region = omGListLast(region, prev);
+  do
+  {
+    if ((char *)addr >= region->addr
+    && (char *)addr < region->addr + (region->pages)*SIZEOF_SYSTEM_PAGE)
+      return region;
+    region = region->next;
+  }
+  while (region != NULL);
+  return NULL;
+}
+
+int omIsAddrOnFreeBinPage(void* addr)
+{
+  char *c_addr=(char *)addr;
+  omBinPageRegion region = om_CurrentBinPageRegion;
+
+  if (region == NULL) return 0;
+  do
+  {
+    if (c_addr > region->addr && c_addr < region->addr + (region->pages)*SIZEOF_SYSTEM_PAGE)
+    {
+      if (omIsOnList(region->current, omGetPageOfAddr(addr))) return 1;
+      return 0;
+    }
+    region = region->next;
+  }
+  while (region != NULL);
+  return 0;
+}
+
+#endif /* ! OM_NDEBUG */
diff --git a/omalloc/omBinPage.h b/omalloc/omBinPage.h
new file mode 100644
index 0000000..98cb54d
--- /dev/null
+++ b/omalloc/omBinPage.h
@@ -0,0 +1,91 @@
+/*******************************************************************
+ *  File:    omBinPage.h
+ *  Purpose: declaration of routines for primitve BinPage managment
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 11/99
+ *******************************************************************/
+#ifndef OM_BIN_PAGE_H
+#define OM_BIN_PAGE_H
+
+/***********************************************************************
+ *
+ * Macros for page manipulations
+ *
+ **********************************************************************/
+
+#define omIsAddrPageAligned(addr) \
+  (((long) (addr) & (SIZEOF_SYSTEM_PAGE -1)) == 0)
+
+#define omGetPageOfAddr(addr) \
+  ((void*) (((long)addr) & ~(SIZEOF_SYSTEM_PAGE -1)))
+
+#define omGetBinPageOfAddr(addr) \
+  ((omBinPage) ((long) (addr) & ~(SIZEOF_SYSTEM_PAGE -1)))
+
+#define omIsAddrOnPage(addr, page) (omGetPageOfAddr(addr) == (void*) (page))
+
+#define omAreAddrOnSamePage(a1, a2) \
+  (omGetPageOfAddr(a1) == omGetPageOfAddr(a2))
+
+/***********************************************************************
+ *
+ * Identifying whether an address is a BinPageAddr:
+ *
+ *******************************************************************/
+
+/* Here is how it works (assume SIZEOF_LONG == 4, SIZEOF_SYSTEM_PAGE = 2^12):
+   Let
+   Addr: |    15               |  5       |    12        |
+          PAGE_INDEX            PAGE_SHIFT PAGE_OFFSET
+
+                                      PAGE_BASE
+
+   om_PageIndicies is an array of bit-fields which is indexed by
+                  PAGE_INDEX - om_MinBinPageIndex. Its maximal length
+                  is 2^15. PAGE_SHIFT is used as index into the bit-field.
+                  If it's value is 1, then addr is from omBinPage, else
+                  not.
+
+   om_MinPageIndex is minimal page index of registered BinPageAddr
+
+   In other words: omIsBinPageAddr iff PAGE_INDEX >= om_MinBinPageIndex && PAGE_INDEX <=  om_MaxBinPageIndex
+   && om_PageIndicies[PAGE_INDEX - om_MinPageIndex] & (1 << PAGE_SHIFT) */
+
+extern unsigned long om_MaxBinPageIndex;
+extern unsigned long om_MinBinPageIndex;
+extern unsigned long *om_BinPageIndicies;
+
+#define OM_SIZEOF_INDEX_PAGE (((unsigned long) SIZEOF_SYSTEM_PAGE) << LOG_BIT_SIZEOF_LONG)
+
+#define omGetPageShiftOfAddr(addr) \
+  ((((unsigned long) addr) & (OM_SIZEOF_INDEX_PAGE -1)) >> LOG_BIT_SIZEOF_SYSTEM_PAGE)
+
+#define omGetPageIndexOfAddr(addr) \
+  (((unsigned long) addr) >> (LOG_BIT_SIZEOF_LONG + LOG_BIT_SIZEOF_SYSTEM_PAGE))
+
+
+#if defined(OM_INLINE) || defined(OM_INTERNAL_DEBUG)
+#define omIsBinPageAddr(addr) _omIsBinPageAddr(addr)
+#else
+/* let's hope the compiler can eliminate common subexpressions well */      \
+#define omIsBinPageAddr(addr)                                               \
+  ((omGetPageIndexOfAddr(addr) >= om_MinBinPageIndex) &&                    \
+   (omGetPageIndexOfAddr(addr) <= om_MaxBinPageIndex) &&                    \
+   ((om_BinPageIndicies[omGetPageIndexOfAddr(addr) - om_MinBinPageIndex] &   \
+     (((unsigned long) 1) << omGetPageShiftOfAddr(addr))) != 0))
+#endif
+
+/*BEGINPRIVATE*/
+/*******************************************************************
+ *
+ * Alloc/Free of BinPages
+ *
+ *******************************************************************/
+extern omBinPage omAllocBinPages(int how_many);
+extern omBinPage omAllocBinPage();
+
+extern void omFreeBinPages(omBinPage page, int how_many);
+#define omFreeBinPage(addr) omFreeBinPages(addr, 1)
+/*ENDPRIVATE*/
+
+#endif /* OM_BIN_PAGE_H */
diff --git a/omalloc/omDebug.c b/omalloc/omDebug.c
new file mode 100644
index 0000000..399761c
--- /dev/null
+++ b/omalloc/omDebug.c
@@ -0,0 +1,644 @@
+/*******************************************************************
+ *  File:    omTest.c
+ *  Purpose: implementation of main omTest functions
+ *  Author:  obachman at mathematik.uni-kl.de (Olaf Bachmann)
+ *  Created: 7/00
+ *******************************************************************/
+#include <mylimits.h>
+#include <string.h>
+#include "omConfig.h"
+#include "omalloc.h"
+#include "omDebug.h"
+#include "omReturn.h"
+
+#ifndef OM_NDEBUG
+/*******************************************************************
+ *
+ * Declarations
+ *
+ *******************************************************************/
+
+static void* __omDebugAlloc(void* size_bin, omTrackFlags_t  flags, char track, OM_FLR_DECL);
+static void* __omDebugRealloc(void* old_addr, void* old_size_bin, void* new_size_bin,
+                              omError_t old_status, omTrackFlags_t  old_flags,
+                              omTrackFlags_t  new_flags,
+                              char track, OM_FLR_DECL);
+static void __omDebugFree(void* addr, void* size_bin, omTrackFlags_t  flags, OM_FLR_DECL);
+
+void* om_KeptAddr = NULL;
+static unsigned long om_NumberOfKeptAddrs = 0;
+void* om_LastKeptAddr = NULL;
+void* om_AlwaysKeptAddrs = NULL;
+
+
+/*******************************************************************
+ *
+ * Test routines
+ *
+ *******************************************************************/
+#define OM_CLFL check_level OM_FL_KOMMA OM_FL
+omError_t omTestAddrBin(void* addr, omBin bin, int check_level)
+{
+  return _omDebugAddr(addr,bin,OM_FBIN,OM_CLFL);
+}
+omError_t omTestBinAddrSize(void* addr, size_t size, int check_level)
+{
+  return _omDebugAddr(addr,(void*)(size),OM_FSIZE|OM_FBINADDR,OM_CLFL);
+}
+omError_t omTestAddrSize(void* addr, size_t size, int check_level)
+{
+  return _omDebugAddr(addr,(void*)(size),OM_FSIZE,OM_CLFL);
+}
+omError_t omTestBinAddr(void* addr, int check_level)
+{
+  return _omDebugAddr(addr,NULL, OM_FBINADDR, OM_CLFL);
+}
+omError_t omTestAddr(void* addr, int check_level)
+{
+  return _omDebugAddr(addr,NULL, 0, OM_CLFL);
+}
+omError_t omtestAddrSize(void* addr, size_t size, int check_level)
+{
+  return _omDebugAddr(addr,(void*)(size),OM_FSIZE|OM_FSLOPPY,OM_CLFL);
+}
+omError_t omtestAddr(void* addr, int check_level)
+{
+  return _omDebugAddr(addr,NULL, OM_FSLOPPY, OM_CLFL);
+}
+
+omError_t omTestAddrAlignedBin(void* addr, omBin bin, int check_level)
+{
+  return _omDebugAddr(addr,bin,OM_FBIN|OM_FALIGN,OM_CLFL);
+}
+omError_t omTestAddrAlignedSize(void* addr, size_t size, int check_level)
+{
+  return _omDebugAddr(addr,(void*)(size),OM_FSIZE|OM_FALIGN,OM_CLFL);
+}
+omError_t omTestAddrAligned(void* addr, int check_level)
+{
+  return _omDebugAddr(addr,NULL, OM_FALIGN, OM_CLFL);
+}
+omError_t omtestAddrAlignedSize(void* addr, size_t size, int check_level)
+{
+  return _omDebugAddr(addr,(void*)(size),OM_FSIZE|OM_FSLOPPY|OM_FALIGN,OM_CLFL);
+}
+omError_t omtestAddrAligned(void* addr, int check_level)
+{
+  return _omDebugAddr(addr,NULL, OM_FSLOPPY|OM_FALIGN, OM_CLFL);
+}
+
+omError_t omTestBin(omBin bin, int check_level)
+{
+  return _omDebugBin(bin, OM_CLFL);
+}
+omError_t omTestMemory(int check_level)
+{
+  return _omDebugMemory(OM_CLFL);
+}
+
+#undef MAX
+#define MAX(a,b) (a > b ? a : b)
+#undef MIN
+#define MIN(a,b) (a < b ? a : b)
+
+/*******************************************************************
+ *
+ * First level _omDebug alloc/free routines: call respective checks and dispatch
+ * to routines which do the actual work
+ *
+ *******************************************************************/
+void* _omDebugAlloc(void* size_bin, omTrackFlags_t flags, OM_CTFL_DECL)
+{
+  void* addr;
+  OM_R_DEF;
+  check = MAX(check, om_Opts.MinCheck);
+  track = MAX(track, om_Opts.MinTrack);
+  check = MIN(check, om_Opts.MaxCheck);
+  track = MIN(track, om_Opts.MaxTrack);
+
+  if (check)
+  {
+    if (check > 1)
+    {
+      if (flags & OM_FBIN)
+        (void) _omCheckBin((omBin)size_bin, 1, check-1, omError_MemoryCorrupted, OM_FLR_VAL);
+      else if (check > 2)
+      {
+        omAssume(flags & OM_FSIZE);
+        (void) _omCheckMemory(check-2, omError_MemoryCorrupted, OM_FLR_VAL);
+      }
+    }
+    if (size_bin == NULL && ! (flags & OM_FSLOPPY))
+    {
+      omReportError(omError_NullSizeAlloc, omError_NoError, OM_FLR_VAL, "");
+    }
+  }
+
+  addr = __omDebugAlloc(size_bin, flags, track, OM_FLR_VAL);
+
+#ifdef OM_INTERNAL_DEBUG
+  (void) _omCheckAddr(addr, size_bin,flags|OM_FUSED,check, omError_InternalBug, OM_FLR);
+#endif
+
+  return addr;
+}
+
+
+void* _omDebugRealloc(void* old_addr, void* old_size_bin, void* new_size_bin,
+                      omTrackFlags_t old_flags, omTrackFlags_t new_flags, OM_CTFL_DECL)
+{
+  void* new_addr = NULL;
+  omError_t status = omError_NoError;
+  OM_R_DEF;
+  check = MAX(check, om_Opts.MinCheck);
+  track = MAX(track, om_Opts.MinTrack);
+  check = MIN(check, om_Opts.MaxCheck);
+  track = MIN(track, om_Opts.MaxTrack);
+
+  if (check)
+  {
+    status = _omCheckAddr(old_addr, old_size_bin, old_flags|OM_FUSED, check, omError_NoError, OM_FLR_VAL);
+
+    if (status == omError_NoError && check > 1 && new_flags & OM_FBIN)
+      status = omDoCheckBin((omBin)new_size_bin, 1, check-1, omError_MemoryCorrupted, OM_FLR_VAL);
+
+    if (new_size_bin == NULL && !(new_flags & OM_FSLOPPY))
+    {
+      omReportError(omError_NullSizeAlloc, omError_NoError, OM_FLR_VAL, "");
+      new_size_bin = (void*) 1;
+    }
+  }
+
+  new_addr = __omDebugRealloc(old_addr, old_size_bin, new_size_bin,
+                              status, old_flags, new_flags, track, OM_FLR_VAL);
+#ifdef OM_INTERNAL_DEBUG
+  if (status == omError_NoError)
+    (void) _omCheckAddr(new_addr, new_size_bin,new_flags|OM_FUSED,check, omError_InternalBug, OM_FLR);
+#endif
+
+  return new_addr;
+}
+
+void _omDebugFree(void* addr, void* size_bin,
+                  omTrackFlags_t flags, OM_CFL_DECL)
+{
+  OM_R_DEF;
+  check = MAX(check, om_Opts.MinCheck);
+  check = MIN(check, om_Opts.MaxCheck);
+
+  if (check && _omCheckAddr(addr, size_bin, flags|OM_FUSED, check, omError_NoError, OM_FLR_VAL)) return;
+
+  __omDebugFree(addr,size_bin,flags, OM_FLR_VAL);
+
+#ifdef OM_INTERNAL_DEBUG
+  if (flags & OM_FBIN)
+    (void) _omCheckBin((omBin)size_bin, 1, check-1,omError_InternalBug, OM_FLR);
+  else
+    (void) _omCheckMemory(check-2,omError_InternalBug,OM_FLR);
+#endif
+}
+
+void* _omDebugMemDup(void* addr, omTrackFlags_t flags, OM_CTFL_DECL)
+{
+  void* ret;
+  size_t sizeW;
+  OM_R_DEF;
+
+  check = MAX(check, om_Opts.MinCheck);
+  track = MAX(track, om_Opts.MinTrack);
+  check = MIN(check, om_Opts.MaxCheck);
+  track = MIN(track, om_Opts.MaxTrack);
+
+  if (check & _omCheckAddr(addr, 0, OM_FUSED, check, omError_NoError, OM_FLR_VAL))
+  {
+    return NULL;
+  }
+  else
+  {
+    sizeW = omSizeWOfAddr(addr);
+  }
+
+  ret = __omDebugAlloc((void*) (sizeW << LOG_SIZEOF_LONG), OM_FSIZE | flags, track, OM_FLR_VAL);
+  omMemcpyW(ret, addr, sizeW);
+
+#ifdef OM_INTERNAL_DEBUG
+  (void) _omCheckAddr(ret, (void*) (sizeW << LOG_SIZEOF_LONG),OM_FUSED|OM_FSIZE,
+                     check, omError_InternalBug, OM_FLR);
+#endif
+  return ret;
+}
+
+char* _omDebugStrDup(const char* addr, OM_TFL_DECL)
+{
+#if 0
+  unsigned long size;
+#endif
+  unsigned long i=0;
+  char* ret;
+  OM_R_DEF;
+
+  if (addr == NULL)
+  {
+    omReportAddrError(omError_NotString, omError_NoError, (char *)addr, 0, 0, OM_FLR_VAL, "NULL String");
+    return NULL;
+  }
+  track = MAX(track, om_Opts.MinTrack);
+  track = MIN(track, om_Opts.MaxTrack);
+
+#if 0
+  // this breaks if SizeOfAddr(addr) > PAGESIZE
+  if (omIsBinPageAddr(addr))
+  {
+    size = omSizeOfAddr(addr);
+  }
+  else
+  {
+    size = ULONG_MAX;
+  }
+#endif
+  while ((addr[i] != '\0') /* && (i < size)*/) i++;
+// there seems to be no way to check if it is really a string
+#if 0
+  if (i == size)
+  {
+    omReportAddrError(omError_NotString, omError_NoError, addr, 0, 0, OM_FLR_VAL, "Not 0 terminated");
+    i = size-1;
+  }
+#endif
+  ret = __omDebugAlloc((char*)i+1, OM_FSIZE, track, OM_FLR_VAL);
+  memcpy(ret, addr, i);
+  ret[i] = '\0';
+
+#ifdef OM_INTERNAL_DEBUG
+  (void) _omCheckAddr(ret, (void*)i+1,OM_FUSED|OM_FSIZE,om_Opts.MinCheck, omError_InternalBug, OM_FLR);
+#endif
+  return ret;
+}
+
+omError_t _omDebugAddr(void* addr, void* bin_size, omTrackFlags_t flags, OM_CFL_DECL)
+{
+  OM_R_DEF;
+  check = MAX(check,om_Opts.MinCheck);
+  check = MIN(check,om_Opts.MaxCheck);
+  return _omCheckAddr(addr, bin_size,
+                      OM_FUSED|flags,check,omError_NoError,OM_FLR_VAL);
+}
+omError_t _omDebugMemory(OM_CFL_DECL)
+{
+  OM_R_DEF;
+  check = MAX(check,om_Opts.MinCheck);
+  check = MIN(check,om_Opts.MaxCheck);
+  return _omCheckMemory(check, omError_NoError,OM_FLR_VAL);
+}
+omError_t _omDebugBin(omBin bin, OM_CFL_DECL)
+{
+  OM_R_DEF;
+  return _omCheckBin(bin, 1, MAX(check, om_Opts.MinCheck), omError_NoError,OM_FLR_VAL);
+}
+
+/*******************************************************************
+ *
+ * Second level _omDebug alloc/free routines: do the actual work
+ *
+ *******************************************************************/
+static void* __omDebugAlloc(void* size_bin, omTrackFlags_t flags, char track, OM_FLR_DECL)
+{
+  void* o_addr;
+  size_t o_size = (flags & OM_FBIN ? ((omBin)size_bin)->sizeW << LOG_SIZEOF_LONG : (size_bin != NULL ? (size_t) size_bin: 1));
+
+#ifdef OM_HAVE_TRACK
+  if (track > 0)
+  {
+    o_addr = omAllocTrackAddr(size_bin, flags, track, OM_FLR_VAL);
+  }
+  else
+#endif
+  {
+    if (flags & OM_FBIN)
+    {
+      omBin bin = (omBin) size_bin;
+
+      if (flags & OM_FZERO)
+        __omTypeAlloc0Bin(void*, o_addr, bin);
+      else
+        __omTypeAllocBin(void*, o_addr, bin);
+    }
+    else
+    {
+      if (flags & OM_FZERO)
+      {
+#ifdef OM_ALIGNMENT_NEEDS_WORK
+        if (flags & OM_FALIGN)
+          __omTypeAlloc0Aligned(void*, o_addr, o_size);
+        else
+#endif
+          __omTypeAlloc0(void*, o_addr, o_size);
+      }
+      else
+      {
+#ifdef OM_ALIGNMENT_NEEDS_WORK
+        if (flags & OM_FALIGN)
+          __omTypeAllocAligned(void*, o_addr, o_size);
+        else
+#endif
+          __omTypeAlloc(void*, o_addr, o_size);
+      }
+    }
+  }
+
+  return o_addr;
+}
+
+static void* __omDebugRealloc(void* old_addr, void* old_size_bin, void* new_size_bin,
+                              omError_t old_status, omTrackFlags_t  old_flags, omTrackFlags_t  new_flags,
+                              char track, OM_FLR_DECL)
+{
+  void* new_addr;
+  size_t old_size = (old_flags & OM_FSIZE ? (size_t) old_size_bin :
+                     (omSizeOfAddr(old_addr)));
+  size_t new_size;
+
+  omAssume(new_flags & OM_FSIZE || new_flags & OM_FBIN);
+
+  if (old_addr == NULL || ((old_flags & OM_FSIZE) && old_size_bin == NULL))
+  {
+    new_addr = __omDebugAlloc(new_size_bin, new_flags, track, OM_FLR_VAL);
+  }
+  else if (om_Opts.Keep > 0 || track > 0 || omIsTrackAddr(old_addr) || old_status != omError_NoError ||
+           old_flags & OM_FKEEP || new_flags & OM_FKEEP)
+  {
+    new_addr = __omDebugAlloc(new_size_bin, new_flags, track, OM_FLR_VAL);
+    new_size =  omSizeOfAddr(new_addr);
+    old_size = omSizeOfAddr(old_addr);
+
+    memcpy(new_addr, old_addr, (old_size < new_size ? old_size : new_size));
+
+    if ((new_flags & OM_FZERO) && new_size > old_size)
+      memset((char *)new_addr + old_size, 0, new_size - old_size);
+    if (old_status == omError_NoError)
+      __omDebugFree(old_addr, old_size_bin, old_flags, OM_FLR_VAL);
+  }
+  else
+  {
+    if (new_flags & OM_FBIN)
+    {
+      omBin new_bin = (omBin) new_size_bin;
+      omBin old_bin = (omBin) old_size_bin;
+
+      omAssume(old_flags & OM_FBIN);
+      if (new_flags & OM_FZERO)
+        __omTypeRealloc0Bin(old_addr, old_bin, void*, new_addr, new_bin);
+      else
+        __omTypeReallocBin(old_addr, old_bin, void*, new_addr, new_bin);
+    }
+    else
+    {
+      new_size = (size_t) new_size_bin;
+      if (new_size == 0) new_size = 1;
+      omAssume(!(new_flags & OM_FBIN) && !(old_flags & OM_FBIN));
+
+      if (old_flags & OM_FSIZE)
+      {
+        size_t old_size = (size_t) old_size_bin;
+
+        if (new_flags & OM_FZERO)
+        {
+#ifdef OM_ALIGNMENT_NEEDS_WORK
+          if (new_flags & OM_FALIGN)
+            __omTypeRealloc0AlignedSize(old_addr, old_size, void*, new_addr, new_size);
+          else
+#endif
+            __omTypeRealloc0Size(old_addr, old_size, void*, new_addr, new_size);
+        }
+        else
+        {
+#ifdef OM_ALIGNMENT_NEEDS_WORK
+          if (new_flags & OM_FALIGN)
+            __omTypeReallocAlignedSize(old_addr, old_size, void*, new_addr, new_size);
+          else
+#endif
+            __omTypeReallocSize(old_addr, old_size, void*, new_addr, new_size);
+        }
+      }
+      else
+      {
+        if (new_flags & OM_FZERO)
+        {
+#ifdef OM_ALIGNMENT_NEEDS_WORK
+          if (new_flags & OM_FALIGN)
+            __omTypeRealloc0Aligned(old_addr, void*, new_addr, new_size);
+          else
+#endif
+            __omTypeRealloc0(old_addr, void*, new_addr, new_size);
+        }
+        else
+        {
+#ifdef OM_ALIGNMENT_NEEDS_WORK
+          if (new_flags & OM_FALIGN)
+            __omTypeReallocAligned(old_addr, void*, new_addr, new_size);
+          else
+#endif
+            __omTypeRealloc(old_addr, void*, new_addr, new_size);
+        }
+      }
+    }
+  }
+  return new_addr;
+}
+
+static omBin omGetOrigSpecBinOfAddr(void* addr)
+{
+  if (omIsBinPageAddr(addr))
+  {
+#ifdef OM_HAVE_TRACK
+    if (omIsBinAddrTrackAddr(addr)) return omGetOrigSpecBinOfTrackAddr(addr);
+    else
+#endif
+    {
+      omBin bin = omGetTopBinOfAddr(addr);
+      if (omIsSpecBin(bin)) return bin;
+    }
+  }
+  return NULL;
+}
+
+static void __omDebugFree(void* addr, void* size_bin, omTrackFlags_t flags, OM_FLR_DECL)
+{
+  omBin bin = NULL;
+
+  if (addr == NULL || ((flags & OM_FSIZE) && size_bin == NULL)) return;
+  if (om_Opts.Keep > 0)
+  {
+#ifdef OM_HAVE_TRACK
+    if (omIsTrackAddr(addr))
+      addr = omMarkAsFreeTrackAddr(addr, 1, &flags, OM_FLR_VAL);
+#endif
+    bin = omGetOrigSpecBinOfAddr(addr);
+    if (bin != NULL)
+    {
+      omSpecBin s_bin = omFindInGList(om_SpecBin, next, bin, (unsigned long) bin);
+      omAssume(s_bin != NULL);
+      (s_bin->ref)++;
+    }
+
+    if (flags & OM_FKEEP)
+    {
+      *((void**) addr) = om_AlwaysKeptAddrs;
+      om_AlwaysKeptAddrs = addr;
+      return;
+    }
+
+    if (om_NumberOfKeptAddrs)
+    {
+      omAssume(om_KeptAddr != NULL && om_LastKeptAddr != NULL &&
+               ((om_NumberOfKeptAddrs == 1 && om_LastKeptAddr == om_KeptAddr) ||
+                (om_NumberOfKeptAddrs != 1 && om_LastKeptAddr != om_KeptAddr)));
+      om_NumberOfKeptAddrs++;
+      *((void**) om_LastKeptAddr) = addr;
+      om_LastKeptAddr = addr;
+      *((void**) addr) = NULL;
+    }
+    else
+    {
+      om_NumberOfKeptAddrs = 1;
+      om_LastKeptAddr = addr;
+      om_KeptAddr = addr;
+      *((void**) om_LastKeptAddr) = NULL;
+    }
+
+    if (om_NumberOfKeptAddrs > om_Opts.Keep)
+    {
+      omError_t status = omDoCheckAddr(om_KeptAddr, NULL, OM_FKEPT, om_Opts.MinCheck,
+                                       omError_MemoryCorrupted, OM_FLR_VAL);
+      addr = om_KeptAddr;
+      if (addr!=NULL) om_KeptAddr = *((void**) addr);
+      om_NumberOfKeptAddrs--;
+      if (status != omError_NoError) return;
+    }
+    else
+      return;
+
+    bin = omGetOrigSpecBinOfAddr(addr);
+  }
+
+#ifdef OM_HAVE_TRACK
+  if (omIsTrackAddr(addr))
+  {
+    omMarkAsFreeTrackAddr(addr, 0, &flags, OM_FLR_VAL);
+    omFreeTrackAddr(addr);
+  }
+  else
+#endif
+    if (om_Opts.Keep <= 0 && ((flags & OM_FBIN) || (flags & OM_FBINADDR)))
+      __omFreeBinAddr(addr);
+    else if (om_Opts.Keep <= 0 && (flags & OM_FSIZE))
+      __omFreeSize(addr, (size_t) size_bin);
+    else
+      __omFree(addr);
+
+  if (bin != NULL) omUnGetSpecBin(&bin);
+}
+
+void omFreeKeptAddrFromBin(omBin bin)
+{
+  void* addr = om_KeptAddr;
+  void* prev_addr = NULL;
+  void* next_addr;
+  omTrackFlags_t flags;
+
+  while (addr != NULL)
+  {
+    next_addr = *((void**) addr);
+    if (omIsBinPageAddr(addr) && omGetTopBinOfAddr(addr) == bin)
+    {
+      if (prev_addr != NULL)
+        *((void**) prev_addr) = next_addr;
+      else
+        om_KeptAddr =  next_addr;
+      if (addr == om_LastKeptAddr)
+        om_LastKeptAddr = prev_addr;
+      om_NumberOfKeptAddrs--;
+#ifdef OM_HAVE_TRACK
+      if (omIsTrackAddr(addr))
+      {
+        omMarkAsFreeTrackAddr(addr, 0, &flags, OM_FLR);
+        omFreeTrackAddr(addr);
+      }
+    else
+#endif
+      __omFree(addr);
+      addr = next_addr;
+    }
+    else
+    {
+      prev_addr = addr;
+      addr = next_addr;
+    }
+  }
+
+  addr = om_AlwaysKeptAddrs;
+  prev_addr = NULL;
+  while (addr != NULL)
+  {
+    next_addr = *((void**) addr);
+    if (omIsBinPageAddr(addr) && omGetTopBinOfAddr(addr) == bin)
+    {
+      if (prev_addr != NULL)
+        *((void**) prev_addr) = next_addr;
+      else
+        om_AlwaysKeptAddrs = next_addr;
+#ifdef OM_HAVE_TRACK
+      if (omIsTrackAddr(addr))
+      {
+        omMarkAsFreeTrackAddr(addr, 0, &flags, OM_FLR);
+        omFreeTrackAddr(addr);
+      }
+    else
+#endif
+      __omFree(addr);
+      addr = next_addr;
+    }
+    else
+    {
+      prev_addr = addr;
+      addr = next_addr;
+    }
+  }
+}
+
+void omFreeKeptAddr()
+{
+  void* next;
+  omBin bin;
+  omTrackFlags_t flags;
+  void* addr = om_KeptAddr;
+
+  if (om_LastKeptAddr != NULL)
+    *((void**) om_LastKeptAddr) = om_AlwaysKeptAddrs;
+
+  om_NumberOfKeptAddrs = 0;
+  om_LastKeptAddr = NULL;
+  om_AlwaysKeptAddrs = NULL;
+  om_KeptAddr = NULL;
+
+  while (addr != NULL)
+  {
+    next = *((void**)addr);
+    bin = omGetOrigSpecBinOfAddr(addr);
+
+#ifdef OM_HAVE_TRACK
+    if (omIsTrackAddr(addr))
+    {
+      omMarkAsFreeTrackAddr(addr, 0, &flags, OM_FLR);
+      omFreeTrackAddr(addr);
+    }
+    else
+#endif
+      __omFree(addr);
+
+    addr = next;
+    if (bin != NULL) omUnGetSpecBin(&bin);
+  }
+}
+
+#endif /* ! OM_NDEBUG */
diff --git a/omalloc/omDebug.h b/omalloc/omDebug.h
new file mode 100644
index 0000000..3d05c4a
--- /dev/null
+++ b/omalloc/omDebug.h
@@ -0,0 +1,196 @@
+/*******************************************************************
+ *  File:    omDebug.h
+ *  Purpose: declaration of common Debug/Check/Track stuff
+ *  Author:  obachman at mathematik.uni-kl.de (Olaf Bachmann)
+ *  Created: 7/00
+ *******************************************************************/
+#ifndef OM_DEBUG_H
+#define OM_DEBUG_H
+
+
+#if defined(OM_NDEBUG) || ! defined(OM_HAVE_TRACK)
+#define omIsTrackAddr(addr)             0
+#define omIsTrackAddrPage(page)         0
+#define omIsNormalBinPageAddr(addr)     omIsBinPageAddr(addr)
+#define omIsBinAddrTrackAddr(addr)      0
+#else
+#define omIsTrackAddrBinPage(bin_page)  ((bin_page)->used_blocks < 0)
+#define omIsBinAddrTrackAddr(addr)      omIsTrackAddrBinPage(omGetBinPageOfAddr(addr))
+#define omIsTrackAddr(addr)             (omIsBinPageAddr(addr) && omIsBinAddrTrackAddr(addr))
+#define omIsNormalBinPageAddr(addr)     (omIsBinPageAddr(addr) && !omIsBinAddrTrackAddr(addr))
+#endif
+
+#if defined(OM_NDEBUG)
+#define omMarkAsStaticAddr(addr)    do {} while (0)
+#define omMarkMemoryAsStatic()      do {} while (0)
+#define omUnMarkAsStaticAddr()      do {} while (0)
+#define omUnMarkMemoryAsStatic()    do {} while (0)
+#define omFreeKeptAddr()            do {} while (0)
+#define omPrintUsedAddrs(fd,m)      do {} while (0)
+#define omPrintUsedTrackAddrs(fd,m) do {} while (0)
+#else
+#define OM_FBIN     1           /* size_bin is bin */
+#define OM_FSIZE    2           /* size_bin is size */
+#define OM_FUSED    4           /* is in use, if set */
+#define OM_FKEPT    8           /* had been freed, if set */
+#define OM_FSTATIC  16          /* if set, considered to be static, i.e. never be freed */
+#define OM_FZERO    32          /* for Alloc0 */
+#define OM_FALIGN   64          /* for AllocAligned */
+#define OM_FSLOPPY  128         /* be sloppy about arguments */
+#define OM_FBINADDR 256         /* addr is bin addr */
+#define OM_FKEEP    512         /* addr is never really freed */
+/* maximal flag: OM_FBIN and OM_FSIZE can not be at the same time,
+   and so can't OM_USED and OM_KEPT. Hence 1024 - BIN - USED*/
+#define OM_FMAX     1024 - OM_FBIN - OM_FUSED
+typedef unsigned short omTrackFlags_t;
+
+void* _omDebugAlloc(void* size_bin, omTrackFlags_t flags, OM_CTFL_DECL);
+void* _omDebugRealloc(void* old_addr, void* old_size_bin, void* new_size_bin,
+                      omTrackFlags_t old_flags, omTrackFlags_t new_flags, OM_CTFL_DECL);
+void  _omDebugFree(void* addr, void* size_bin, omTrackFlags_t flags, OM_CFL_DECL);
+void* _omDebugMemDup(void* addr, omTrackFlags_t flags, OM_CTFL_DECL);
+char* _omDebugStrDup(const char* addr, OM_TFL_DECL);
+
+omError_t _omDebugBin(omBin bin, OM_CFL_DECL);
+omError_t _omDebugMemory(OM_CFL_DECL);
+omError_t _omDebugAddr(void* addr, void* bin_size, omTrackFlags_t flags, OM_CFL_DECL);
+
+void omFreeKeptAddr();
+void omPrintUsedAddrs(FILE* fd, int max_frames);
+void omPrintUsedTrackAddrs(FILE* fd, int max_frames);
+
+void omMarkAsStaticAddr(void* addr);
+void omMarkMemoryAsStatic();
+void omUnMarkAsStaticAddr(void* addr);
+void omUnMarkMemoryAsStatic();
+#endif /* ! OM_NDEBUG */
+
+
+#ifdef OM_TRACK_CUSTOM
+#ifdef OM_NDEBUG
+#define omSetCustomOfAddr(addr,value) do {} while (0)
+#define omGetCustomOfAddr(addr) ((void*)0)
+#define omSetCustomOfTrackAddr(addr,value) do {} while (0)
+#define omGetCustomOfTrackAddr(addr) ((void*)0)
+#else
+void omSetCustomOfTrackAddr(void* addr, void* value);
+void* omGetCustomOfTrackAddr(void* addr);
+#define omSetCustomOfAddr(addr,value) \
+  do{if (omIsTrackAddr(addr)) omSetCustomOfTrackAddr(addr,value);}while(0)
+#define omGetCustomOfAddr(addr) \
+  (omIsTrackAddr(addr) ? omGetCustomOfTrackAddr(addr) : NULL)
+#endif /* OM_NDEBUG */
+#endif /* OM_TRACK_CUSTOM */
+
+/*BEGINPRIVATE*/
+
+#if defined(OM_NDEBUG) || ! defined(OM_HAVE_TRACK)
+#define omGetUsedBlocksOfPage(page)     (page->used_blocks)
+#else
+#define omGetUsedBlocksOfPage(page)     ((long)(page->used_blocks & ~(((unsigned long) 1) << (BIT_SIZEOF_LONG -1))))
+#endif
+
+#ifndef OM_NDEBUG
+extern void* om_KeptAddr;
+extern void* om_LastKeptAddr;
+extern unsigned long om_MaxAddr;
+extern unsigned long om_MinAddr;
+extern void* om_AlwaysKeptAddrs;
+
+void omFreeKeptAddrFromBin(omBin bin);
+/***********************************************************************
+ *
+ * omDebugCheck.c
+ *
+ **********************************************************************/
+omError_t omCheckPtr(const void* ptr, omError_t report, OM_FLR_DECL);
+omError_t _omCheckAddr(void* addr, void* size_bin, omTrackFlags_t flags, char check,
+                       omError_t report, OM_FLR_DECL);
+omError_t omDoCheckBinAddr(void* addr, void* bin_size, omTrackFlags_t flags, char level,
+                           omError_t report, OM_FLR_DECL);
+omError_t _omCheckBin(omBin bin, int normal_bin, char check,  omError_t report, OM_FLR_DECL);
+omError_t _omCheckMemory(char check,  omError_t report, OM_FLR_DECL);
+omError_t omReportAddrError(omError_t error, omError_t report, void* addr,
+                            void* bin_size, omTrackFlags_t flags,
+                            OM_FLR_DECL, const char* fmt, ...);
+omError_t omDoCheckBin(omBin bin, int normal_bin, char level,
+                       omError_t report, OM_FLR_DECL);
+void omIterateTroughAddrs(int normal, int track, void (*CallBackUsed)(void*), void (*CallBackFree)(void*));
+void omIterateTroughBinAddrs(omBin bin, void (*CallBackUsed)(void*), void (*CallBackFree)(void*));
+omError_t omDoCheckAddr(void* addr, void* bin_size, omTrackFlags_t flags, char level,
+                        omError_t report, OM_FLR_DECL);
+int omIsInKeptAddrList(void* addr);
+
+/***********************************************************************
+ *
+ * omDebugTrack.c
+ *
+ **********************************************************************/
+#ifdef OM_HAVE_TRACK
+extern omBin_t om_StaticTrackBin[];
+extern omBin om_Size2TrackBin[];
+#define omSmallSize2TrackBin(size)      om_Size2TrackBin[((size) -1)>>LOG_SIZEOF_OM_ALIGNMENT]
+extern omBinPage om_JustFreedPage;
+extern void omFreeTrackAddr(void* addr);
+extern size_t omOutSizeOfTrackAddr(void* addr);
+extern omSpecBin om_SpecTrackBin;
+
+void* omAllocTrackAddr(void* bin_size, omTrackFlags_t flags, char track, OM_FLR_DECL);
+void* omMarkAsFreeTrackAddr(void* addr, int keep, omTrackFlags_t *flags, OM_FLR_DECL);
+omError_t omCheckTrackAddr(void* addr, void* bin_size, omTrackFlags_t flags, char level,
+                           omError_t report_error, OM_FLR_DECL);
+void omPrintTrackAddrInfo(FILE* fd, void* addr, int max_frames);
+omBin omGetOrigSpecBinOfTrackAddr(void* addr);
+size_t omOutSizeOfTrackAddr(void* addr);
+extern int omIsStaticTrackAddr(void* addr);
+#define omSetTrackOfUsedBlocks(ub)      (ub |= (((unsigned long) 1) << (BIT_SIZEOF_LONG -1)))
+#define omUnsetTrackOfUsedBlocks(ub)    (ub &= ~(((unsigned long) 1) << (BIT_SIZEOF_LONG -1)))
+#define omIsSetTrackOfUsedBlocks(ub)    (ub & (((unsigned long) 1) << (BIT_SIZEOF_LONG -1)))
+#else
+#define omIsStaticTrackAddr(addr)   0
+#endif
+void* omAddr_2_OutAddr(void* addr);
+
+/***********************************************************************
+ *
+ * omBinPage.c
+ *
+ **********************************************************************/
+int omIsKnownMemoryRegion(omBinPageRegion region);
+omError_t omCheckBinPageRegion(omBinPageRegion region, int level, omError_t report, OM_FLR_DECL);
+omError_t omCheckBinPageRegions(int level, omError_t report, OM_FLR_DECL);
+omBinPageRegion omFindRegionOfAddr(void* addr);
+int omIsAddrOnFreeBinPage(void* addr);
+
+/***********************************************************************
+ *
+ * Some Handy Macros
+ *
+ **********************************************************************/
+#define omCheckReturn(cond) \
+  do {omError_t _status = cond; if (_status) return _status;} while (0)
+#define omCheckReturnError(cond, error) \
+  do {if (cond) return omReportError(error, report, OM_FLR_VAL, "");} while (0)
+#define omCheckReturnCorrupted(cond) \
+  omCheckReturnError(cond, omError_MemoryCorrupted)
+#define omAddrCheckReturn(cond)                                               \
+do                                                                            \
+{                                                                             \
+  omError_t _status = cond;                                                   \
+  if (_status && (_status != omError_MaxError))                               \
+  {                                                                           \
+    _omPrintAddrInfo(stderr, _status, addr, bin_size, flags, 10, "  occured for"); \
+    return _status;                                                           \
+  }                                                                           \
+} while (0)
+#define omAddrCheckReturnError(cond, error) \
+  do {if (cond) return omReportAddrError(error, report, addr, bin_size, flags, OM_FLR_VAL, "");} while (0)
+#define omAddrCheckReturnCorrupted(cond) \
+  omAddrCheckReturnError(cond, omError_MemoryCorrupted)
+
+#else
+#define omFreeKeptAddrFromBin(bin) do {} while (0)
+#endif /* ! OM_NDEBUG */
+/*ENDPRIVATE*/
+
+#endif /* OM_DEBUG_H */
diff --git a/omalloc/omDebugCheck.c b/omalloc/omDebugCheck.c
new file mode 100644
index 0000000..ac4dabd
--- /dev/null
+++ b/omalloc/omDebugCheck.c
@@ -0,0 +1,578 @@
+/*******************************************************************
+ *  File:    omDebugCheck.c
+ *  Purpose: implementation of omCheck functions
+ *  Author:  obachman at mathematik.uni-kl.de (Olaf Bachmann)
+ *  Created: 11/99
+ *******************************************************************/
+#include <mylimits.h>
+#include <stdarg.h>
+
+#include "omalloc.h"
+#include "omDebug.h"
+
+#ifndef OM_NDEBUG
+/*******************************************************************
+ *
+ *   Declarations: Static function
+ *
+ *******************************************************************/
+unsigned long om_MaxAddr = 0;
+unsigned long om_MinAddr = ULONG_MAX;
+static omError_t omDoCheckLargeAddr(void* addr, void* bin_size, omTrackFlags_t flags, char level,
+                                    omError_t report, OM_FLR_DECL);
+omError_t omDoCheckBin(omBin bin, int normal_bin, char level,
+                       omError_t report, OM_FLR_DECL);
+static omError_t omDoCheckBinPage(omBinPage page, int normal_page, int level,
+                                  omError_t report, OM_FLR_DECL);
+static void _omPrintAddrInfo(FILE* fd, omError_t error, void* addr, void* bin_size, omTrackFlags_t flags, int max_frames, const char* s);
+
+
+/*******************************************************************
+ *
+ * First level omCheck routines: dispatch to lower-level omDoCheck
+ * routines which do the actual tests
+ *
+ *******************************************************************/
+omError_t _omCheckAddr(void* addr, void* size_bin,
+                       omTrackFlags_t flags, char check, omError_t report, OM_FLR_DECL)
+{
+  if (check <= 0) return omError_NoError;
+  if (check > 1)
+  {
+    omCheckReturn(check > 2 && _omCheckMemory(check - 2, (report ? report : omError_MemoryCorrupted), OM_FLR_VAL));
+    omCheckReturn(omIsBinPageAddr(addr) && omDoCheckBin(omGetBinOfAddr(addr), !omIsBinAddrTrackAddr(addr), check-1,
+                                                        (report ? report : omError_MemoryCorrupted), OM_FLR_VAL));
+  }
+  return omDoCheckAddr(addr, size_bin, flags, check, report, OM_FLR_VAL);
+}
+
+omError_t _omCheckBin(omBin bin, int what_bin, char check, omError_t report, OM_FLR_DECL)
+{
+  if (check <= 0) return omError_NoError;
+
+  omCheckReturn(check > 1 && _omCheckMemory(check - 1, (report ? report : omError_MemoryCorrupted), OM_FLR_VAL));
+
+  return omDoCheckBin(bin, what_bin, check, report, OM_FLR_VAL);
+}
+
+omError_t _omCheckMemory(char check, omError_t report, OM_FLR_DECL)
+{
+  int i = 0;
+  omSpecBin s_bin;
+  omBin sticky;
+
+  if (check <= 0) return omError_NoError;
+
+  omCheckReturn(omCheckBinPageRegions(check, report, OM_FLR_VAL));
+
+  for (i=0; i<= OM_MAX_BIN_INDEX; i++)
+  {
+    omCheckReturn(omDoCheckBin(&om_StaticBin[i], 1, check, report, OM_FLR_VAL));
+  }
+
+  s_bin = om_SpecBin;
+  omCheckReturn(omCheckGList(s_bin, next, check, omError_MemoryCorrupted, OM_FLR_VAL));
+  while (s_bin != NULL)
+  {
+    omCheckReturn(omDoCheckBin(s_bin->bin, 1, check, report, OM_FLR_VAL));
+    s_bin = s_bin->next;
+  }
+
+  sticky = om_StickyBins;
+  omCheckReturn(omCheckGList(sticky, next, check, omError_MemoryCorrupted, OM_FLR_VAL));
+  while (sticky != NULL)
+  {
+    omCheckReturn(omDoCheckBin(sticky, 1, check, report, OM_FLR_VAL));
+    sticky = sticky->next;
+  }
+
+#ifdef OM_HAVE_TRACK
+  for (i=0; i<= OM_MAX_BIN_INDEX; i++)
+  {
+    omCheckReturn(omDoCheckBin(&om_StaticTrackBin[i], 0, check, report, OM_FLR_VAL));
+  }
+  s_bin = om_SpecTrackBin;
+  omCheckReturn(omCheckGList(s_bin, next, check, omError_MemoryCorrupted, OM_FLR_VAL));
+  while (s_bin != NULL)
+  {
+    omCheckReturn(omDoCheckBin(s_bin->bin, 0, check, report, OM_FLR_VAL));
+    s_bin = s_bin->next;
+  }
+#endif
+
+  if (check > 1)
+  {
+    if (om_KeptAddr != NULL)
+    {
+      void* addr = om_KeptAddr;
+      omCheckReturn(omCheckList(om_KeptAddr, check - 1, (report ? report :  omError_KeptAddrListCorrupted), OM_FLR_VAL));
+      while (addr != NULL)
+      {
+        omCheckReturn(omDoCheckAddr(addr, NULL, OM_FKEPT, check, report, OM_FLR_VAL));
+        addr = *((void**) addr);
+      }
+    }
+    if (om_AlwaysKeptAddrs != NULL)
+    {
+      void* addr = om_AlwaysKeptAddrs;
+      omCheckReturn(omCheckList(om_AlwaysKeptAddrs, check - 1, (report ? report :  omError_KeptAddrListCorrupted), OM_FLR_VAL));
+      while (addr != NULL)
+      {
+        omCheckReturn(omDoCheckAddr(addr, NULL, OM_FKEPT, check, report, OM_FLR_VAL));
+        addr = *((void**) addr);
+      }
+    }
+  }
+
+  return omError_NoError;
+}
+
+/*******************************************************************
+ *
+ * Second level omCheck routines: do the actual checks
+ *
+ *******************************************************************/
+
+omError_t omCheckPtr(const void* ptr, omError_t report, OM_FLR_DECL)
+{
+  omCheckReturnError(ptr == NULL, omError_NullAddr);
+  omCheckReturnError(!OM_IS_ALIGNED(ptr), omError_UnalignedAddr);
+  omCheckReturnError(((unsigned long) ptr) < om_MinAddr ||
+                     ((unsigned long) ptr) >= om_MaxAddr, omError_InvalidRangeAddr);
+  return omError_NoError;
+}
+
+
+omError_t omDoCheckAddr(void* addr, void* bin_size, omTrackFlags_t flags, char level,
+                        omError_t report, OM_FLR_DECL)
+{
+  if (level <= 0) return omError_NoError;
+  omAssume(! ((flags & OM_FSIZE) && (flags & OM_FBIN)));
+
+  if (addr == NULL)
+  {
+    omCheckReturnError(!(flags & OM_FSLOPPY), omError_NullAddr);
+    return omError_NoError;
+  }
+  if ((flags & OM_FSIZE) && bin_size == NULL) return omError_NoError;
+  omAddrCheckReturn(omCheckPtr(addr, report, OM_FLR_VAL));
+  omAddrCheckReturnError((flags & OM_FALIGN) &&  !OM_IS_STRICT_ALIGNED(addr), omError_UnalignedAddr);
+  omAddrCheckReturnError((flags & OM_FBIN) && !omIsKnownTopBin((omBin) bin_size, 1), omError_UnknownBin);
+
+  if (omIsBinPageAddr(addr))
+  {
+#ifdef OM_HAVE_TRACK
+    if (omIsBinAddrTrackAddr(addr))
+      return omCheckTrackAddr(addr, bin_size, flags, level, report, OM_FLR_VAL);
+    else
+#endif
+      return omDoCheckBinAddr(addr, bin_size, flags, level, report, OM_FLR_VAL);
+  }
+  else
+  {
+    return omDoCheckLargeAddr(addr, bin_size, flags, level, report, OM_FLR_VAL);
+  }
+}
+
+
+
+static omError_t omDoCheckLargeAddr(void* addr, void* bin_size, omTrackFlags_t flags, char level,
+                                    omError_t report, OM_FLR_DECL)
+{
+  size_t r_size;
+
+  omAssume(! omIsBinPageAddr(addr));
+  omAssume(! omCheckPtr(addr, omError_NoError, OM_FLR));
+
+  omAddrCheckReturnError((flags & OM_FBIN) || (flags & OM_FBINADDR), omError_NotBinAddr);
+  omAddrCheckReturnError(level > 1 && omFindRegionOfAddr(addr) != NULL, omError_FreedAddrOrMemoryCorrupted);
+  r_size = omSizeOfLargeAddr(addr);
+  omAddrCheckReturnError(! OM_IS_ALIGNED(r_size), omError_FalseAddrOrMemoryCorrupted);
+  omAddrCheckReturnError(r_size <= OM_MAX_BLOCK_SIZE, omError_FalseAddrOrMemoryCorrupted);
+  omAddrCheckReturnError((flags & OM_FSIZE) && r_size < OM_ALIGN_SIZE((size_t) bin_size),
+                         omError_WrongSize);
+  omAddrCheckReturnError((level > 1) && (flags & OM_FUSED) && omIsInKeptAddrList(addr), omError_FreedAddr);
+  return omError_NoError;
+}
+
+omError_t omDoCheckBinAddr(void* addr, void* bin_size, omTrackFlags_t flags, char level,
+                           omError_t report, OM_FLR_DECL)
+{
+  omBinPage page = omGetBinPageOfAddr(addr);
+  omBinPageRegion region = page->region;
+  omBin bin = omGetBinOfPage(page);
+
+  omAssume(omIsBinPageAddr(addr));
+  omAssume(! omCheckPtr(addr, 0, OM_FLR));
+
+  omAddrCheckReturnCorrupted(! omIsKnownTopBin(bin, ! omIsBinAddrTrackAddr(addr)));
+
+  if (flags & OM_FBINADDR && flags & OM_FSIZE)
+    omAddrCheckReturnError(bin->sizeW*SIZEOF_LONG != (size_t) bin_size, omError_WrongSize);
+
+  if (level > 1)
+  {
+    omAddrCheckReturnError(omIsAddrOnFreeBinPage(addr), omError_FreedAddr);
+    omAddrCheckReturnError(omFindRegionOfAddr(addr) != region, omError_FreedAddrOrMemoryCorrupted);
+    omAddrCheckReturnError(!omIsOnGList(bin->last_page, prev, page), omError_FreedAddrOrMemoryCorrupted);
+
+    if (flags & OM_FUSED)
+    {
+      omAddrCheckReturnError(omIsOnList(page->current, addr), omError_FreedAddr);
+      omAddrCheckReturnError((level > 1) && omIsInKeptAddrList(addr), omError_FreedAddr);
+    }
+  }
+  else
+  {
+    omAddrCheckReturnError(omCheckPtr(region, omError_MaxError, OM_FLR_VAL), omError_FreedAddrOrMemoryCorrupted);
+  }
+
+
+  /* Check that addr is aligned within page of bin */
+  omAddrCheckReturnError((bin->max_blocks >= 1) &&
+                         ( ( ( (unsigned long) addr)
+                             - ((unsigned long) page)
+                             - SIZEOF_OM_BIN_PAGE_HEADER)
+                           % (bin->sizeW * SIZEOF_VOIDP)
+                           != 0), omError_FalseAddr);
+
+  /* Check that specified bin or size is correct */
+  omAddrCheckReturnError((flags & OM_FBIN) &&  bin_size != NULL
+                         && ((omBin) bin_size) != omGetTopBinOfAddr(addr), omError_WrongBin);
+
+  if ((flags & OM_FSIZE) && (!(flags & OM_FSLOPPY)  || (size_t) bin_size > 0))
+  {
+    size_t size = (size_t) bin_size;
+    omAssume(!omIsBinAddrTrackAddr(addr));
+    omAddrCheckReturnError((bin->sizeW << LOG_SIZEOF_LONG) < OM_ALIGN_SIZE(size), omError_WrongSize);
+  }
+
+  return omError_NoError;
+}
+
+omError_t omDoCheckBin(omBin bin, int normal_bin, char level,
+                       omError_t report, OM_FLR_DECL)
+{
+  omBin top_bin = bin;
+
+  omCheckReturnError(!omIsKnownTopBin(bin, normal_bin), omError_UnknownBin);
+  if (! omIsStickyBin(bin))
+    omCheckReturn(omCheckGList(bin->next, next, level, report, OM_FLR_VAL));
+
+  do
+  {
+    int where;
+    omBinPage page;
+
+    if (bin->last_page == NULL || bin->current_page == om_ZeroPage)
+    {
+      omCheckReturnCorrupted(! (bin->current_page == om_ZeroPage && bin->last_page == NULL));
+      continue;
+    }
+    omCheckReturn(omDoCheckBinPage(bin->current_page, normal_bin, level, report, OM_FLR_VAL));
+    omCheckReturn(bin->current_page != bin->last_page  &&
+                  omDoCheckBinPage(bin->last_page, normal_bin, level, report, OM_FLR_VAL));
+    omCheckReturnCorrupted(bin->last_page->next != NULL);
+
+    if (bin != top_bin)
+    {
+      omCheckReturnCorrupted(bin->sizeW != top_bin->sizeW ||
+                             bin->max_blocks != top_bin->max_blocks);
+    }
+    if (level <= 1) continue;
+
+    if (! omIsStickyBin(bin))
+      omCheckReturnCorrupted(omFindInGList(bin->next, next, sticky, bin->sticky));
+    omCheckReturn(omCheckGList(bin->last_page, prev, level-1, report, OM_FLR_VAL));
+    page = omGListLast(bin->last_page, prev);
+    omCheckReturn(omCheckGList(page, next, level-1, report, OM_FLR_VAL));
+    omCheckReturnCorrupted(omGListLength(bin->last_page, prev) != omGListLength(page, next));
+
+    omCheckReturnCorrupted(! omIsOnGList(bin->last_page, prev, bin->current_page));
+
+    page = bin->last_page;
+    where = 1;
+    while (page != NULL)
+    {
+      omCheckReturnCorrupted(omGetTopBinOfPage(page) != top_bin);
+      omCheckReturn(page != bin->last_page && page != bin->current_page &&
+                    omDoCheckBinPage(page, normal_bin, level - 1, report, OM_FLR_VAL));
+
+      omCheckReturnCorrupted(page != bin->last_page &&
+                             (page->next == NULL || page->next->prev != page));
+      omCheckReturnCorrupted(page->prev != NULL && page->prev->next != page);
+
+      omCheckReturnCorrupted(omGetStickyOfPage(page) != bin->sticky && bin->sticky < SIZEOF_VOIDP);
+      omCheckReturnCorrupted(omGetBinOfPage(page) != bin);
+
+      if (where == -1)
+      {
+        /* we are at the left of current_page,
+           i.e., page is empty */
+        omCheckReturnCorrupted(omGetUsedBlocksOfPage(page) != 0 || page->current != NULL);
+      }
+      else
+      {
+        if (page == bin->current_page)
+        {
+          where = -1;
+        }
+        else
+        {
+          /* we are at the right of current_page,
+             i.e., page is neither full nor empty */
+          omCheckReturnCorrupted(page->current == NULL ||
+                                 omGetUsedBlocksOfPage(page) == bin->max_blocks - 1);
+        }
+      }
+      page = page->prev;
+    }   /* while (page != NULL) */
+  } while (!omIsStickyBin(bin) && ((bin = bin->next) != NULL));
+
+  return omError_NoError;
+}
+
+
+static omError_t omDoCheckBinPage(omBinPage page, int normal_page, int level,
+                                  omError_t report, OM_FLR_DECL)
+{
+  omBin bin;
+
+  omCheckReturn(omCheckPtr(page, report, OM_FLR_VAL));
+  omCheckReturnCorrupted(! omIsAddrPageAligned(page));
+
+  omCheckReturn(omCheckPtr(page->region, report, OM_FLR_VAL));
+  omCheckReturnCorrupted(level > 1 && omFindRegionOfAddr(page) != page->region);
+
+
+#ifdef OM_HAVE_TRACK
+  if (! normal_page)
+  {
+    omCheckReturnCorrupted(! omIsSetTrackOfUsedBlocks(page->used_blocks));
+  }
+  else
+#endif
+    omAssume(normal_page);
+
+  bin = omGetTopBinOfPage(page);
+  if (bin->max_blocks > 1)
+  {
+    omCheckReturnCorrupted(omGetUsedBlocksOfPage(page) > bin->max_blocks - 1);
+    omCheckReturnCorrupted(omGetUsedBlocksOfPage(page) == bin->max_blocks - 1 &&
+                           page->current != NULL);
+    omCheckReturnCorrupted(omGetUsedBlocksOfPage(page) < 0);
+  }
+  else
+  {
+    omCheckReturnCorrupted(omGetUsedBlocksOfPage(page) != 0);
+  }
+
+  omCheckReturn(omCheckList(page->current, level, report, OM_FLR_VAL));
+
+  if (level > 1)
+  {
+    void* current = page->current;
+
+    omCheckReturnCorrupted(current != NULL &&
+                           omListLength(current) != bin->max_blocks - omGetUsedBlocksOfPage(page) - 1);
+
+    while (current != NULL)
+    {
+      omCheckReturnCorrupted(omGetPageOfAddr(current) != page);
+
+      omCheckReturnCorrupted( ( ( (unsigned long) current)
+                                - ((unsigned long) page)
+                                - SIZEOF_OM_BIN_PAGE_HEADER)
+                              % (bin->sizeW * SIZEOF_LONG)
+                              != 0);
+      current = *((void**) current);
+    }
+  }
+  return omError_NoError;
+}
+
+omError_t omReportAddrError(omError_t error, omError_t report_error, void* addr, void* bin_size, omTrackFlags_t flags,
+                            OM_FLR_DECL, const char* fmt, ...)
+{
+  int max_check, max_track;
+  va_list ap;
+  va_start(ap, fmt);
+
+  /* reset MaxTrack and MaxCheck to prevent infinite loop, in case
+     printf allocates memory */
+  max_check = om_Opts.MaxCheck;
+  max_track = om_Opts.MaxTrack;
+  om_Opts.MaxCheck = 0;
+  om_Opts.MaxTrack = 0;
+
+  om_CallErrorHook = 0;
+  omReportError(error, report_error, OM_FLR_VAL, fmt, ap);
+  om_CallErrorHook = 1;
+
+  _omPrintAddrInfo(stderr, error, addr, bin_size, flags, 10, " occured for");
+  om_Opts.ErrorHook();
+
+  om_Opts.MaxCheck = max_check;
+  om_Opts.MaxTrack = max_track;
+  return om_ErrorStatus;
+}
+
+void _omPrintAddrInfo(FILE* fd, omError_t error, void* addr, void* bin_size, omTrackFlags_t flags, int frames, const char* s)
+{
+  int x;
+  if (! (x=omCheckPtr(addr, omError_MaxError, OM_FLR)))
+  {
+    fprintf(fd, "%s addr:%p size:%ld", s, addr, (long)omSizeOfAddr(addr));
+
+  if (error == omError_WrongSize && (flags & OM_FSIZE))
+    fprintf(fd, " specified size:%ld", (long) bin_size);
+
+  if (error == omError_WrongBin && (flags & OM_FBIN))
+    fprintf(fd, " specified bin is of size:%ld",
+                 (long)((omBin) bin_size)->sizeW << LOG_SIZEOF_LONG);
+
+  if (omIsTrackAddr(addr))
+    omPrintTrackAddrInfo(fd, addr, frames);
+  else
+    fprintf(fd, "\n");
+  }
+  else
+  {
+    fprintf(fd, "%s (invalid) addr: %p (error=%d)\n", s, addr,x);
+  }
+}
+
+void omPrintAddrInfo(FILE* fd, void *addr, const char* s)
+{
+  _omPrintAddrInfo(fd, omError_NoError, addr, NULL, 0, 10, s);
+}
+
+/*******************************************************************
+ *
+ * Misc for iterating, etc.
+ *
+ *******************************************************************/
+
+void omIterateTroughBinAddrs(omBin bin, void (*CallBackUsed)(void*), void (*CallBackFree)(void*))
+{
+  omBinPage page;
+  char* addr;
+  int is_free;
+  int i;
+
+  do
+  {
+    page = bin->last_page;
+    while (page != NULL)
+    {
+      addr = (char*) page + SIZEOF_OM_BIN_PAGE_HEADER;
+      i = 0;
+      do
+      {
+        is_free = omIsOnList(page->current, addr) != NULL
+                  || omIsInKeptAddrList(addr);
+        if (is_free)
+        {
+          if (CallBackFree != NULL) CallBackFree(addr);
+        }
+        else
+        {
+          if (CallBackUsed != NULL) CallBackUsed(addr);
+        }
+        addr = (char *)((char**) addr) + bin->sizeW;
+        i++;
+      } while (i < bin->max_blocks);
+      page = page->prev;
+    }
+    if (omIsStickyBin(bin))
+      bin = NULL;
+    else
+      bin = bin->next;
+  } while (bin != NULL);
+
+}
+
+void omIterateTroughAddrs(int normal, int track, void (*CallBackUsed)(void*), void (*CallBackFree)(void*))
+{
+  int i;
+  omSpecBin s_bin;
+  omBin sticky;
+
+  if (normal)
+  {
+    for (i=0; i<=OM_MAX_BIN_INDEX; i++)
+    {
+      omIterateTroughBinAddrs(&om_StaticBin[i], CallBackUsed, CallBackFree);
+    }
+    s_bin = om_SpecBin;
+    while (s_bin != NULL)
+    {
+      omIterateTroughBinAddrs(s_bin->bin, CallBackUsed, CallBackFree);
+      s_bin = s_bin->next;
+    }
+  }
+
+#ifdef OM_HAVE_TRACK
+  if (track)
+  {
+    for (i=0; i<=OM_MAX_BIN_INDEX; i++)
+    {
+      omIterateTroughBinAddrs(&om_StaticTrackBin[i], CallBackUsed, CallBackFree);
+    }
+    s_bin = om_SpecTrackBin;
+    while (s_bin != NULL)
+    {
+      omIterateTroughBinAddrs(s_bin->bin, CallBackUsed, CallBackFree);
+      s_bin = s_bin->next;
+    }
+  }
+#endif
+  sticky = om_StickyBins;
+  while (sticky != NULL)
+  {
+    omIterateTroughBinAddrs(sticky, CallBackUsed, CallBackFree);
+    sticky = sticky->next;
+  }
+}
+
+static FILE* om_print_used_addr_fd;
+static size_t om_total_used_size;
+static unsigned long om_total_used_blocks;
+static int om_print_frames;
+
+static void _omPrintUsedAddr(void* addr)
+{
+  if (!omIsTrackAddr(addr) || !omIsStaticTrackAddr(addr))
+  {
+    om_total_used_blocks++;
+    om_total_used_size += omSizeOfAddr(addr);
+    if (om_print_frames > 0)
+    {
+      _omPrintAddrInfo(om_print_used_addr_fd, omError_NoError, addr, NULL, 0, om_print_frames, "");
+      fprintf(om_print_used_addr_fd, "\n");
+    }
+  }
+}
+
+void omPrintUsedAddrs(FILE* fd, int max)
+{
+  om_total_used_size = 0;
+  om_total_used_blocks = 0;
+  om_print_used_addr_fd = (fd == NULL ? stdout : fd);
+  om_print_frames = max;
+  omIterateTroughAddrs(1, 1, _omPrintUsedAddr, NULL);
+  fprintf(fd, "UsedAddrs Summary: UsedBlocks:%ld  TotalSize:%ld\n",
+          om_total_used_blocks, (long)om_total_used_size);
+}
+
+void omPrintUsedTrackAddrs(FILE* fd, int max)
+{
+  om_total_used_size = 0;
+  om_total_used_blocks = 0;
+  om_print_used_addr_fd = (fd == NULL ? stdout : fd);
+  om_print_frames = max;
+  omIterateTroughAddrs(0, 1 ,  _omPrintUsedAddr, NULL);
+  fprintf(fd, "UsedTrackAddrs Summary: UsedBlocks:%ld  TotalSize:%ld\n",
+          om_total_used_blocks, (long)om_total_used_size);
+}
+#endif /* ! OM_NDEBUG */
diff --git a/omalloc/omDebugTrack.c b/omalloc/omDebugTrack.c
new file mode 100644
index 0000000..0dd7b22
--- /dev/null
+++ b/omalloc/omDebugTrack.c
@@ -0,0 +1,764 @@
+/*******************************************************************
+ *  File:    omDebug.c
+ *  Purpose: implementation of main omDebug functions
+ *  Author:  obachman at mathematik.uni-kl.de (Olaf Bachmann)
+ *  Created: 11/99
+ *******************************************************************/
+#include <mylimits.h>
+#include <string.h>
+#include "omConfig.h"
+#include "omDerivedConfig.h"
+
+#ifdef OM_HAVE_TRACK
+#include "omDefaultConfig.h"
+#include "omalloc.h"
+
+/*******************************************************************
+ *
+ * Declarations
+ *
+ *******************************************************************/
+omBinPage om_JustFreedPage = NULL;
+omSpecBin om_SpecTrackBin = NULL;
+
+/* number of bytes for padding before addr: needs to > 0 and a multiple of OM_SIZEOF_STRICT_ALIGNMENT */
+#ifndef OM_MIN_SIZEOF_FRONT_PATTERN
+#define OM_MIN_SIZEOF_FRONT_PATTERN (OM_MIN_SIZEWOF_FRONT_PATTERN*SIZEOF_STRICT_ALIGNMENT)
+#endif
+/* number of bytes for padding after addr: needs to be a multiple of OM_SIZEOF_STRICT_ALIGNMENT */
+#ifndef OM_MIN_SIZEOF_BACK_PATTERN
+#define OM_MIN_SIZEOF_BACK_PATTERN (OM_MIN_SIZEWOF_BACK_PATTERN*SIZEOF_STRICT_ALIGNMENT)
+#endif
+
+struct omTrackAddr_s;
+typedef struct omTrackAddr_s omTrackAddr_t;
+typedef omTrackAddr_t * omTrackAddr;
+struct omTrackAddr_s
+{
+  void*             next;   /* reserved for page->current queue */
+  char              track;  /* > 0; determines size of header */
+  omTrackFlags_t    flags;
+    #ifdef OM_TRACK_FILE_LINE
+  short             alloc_line;
+  const char*       alloc_file;
+    #endif
+    #ifdef OM_TRACK_RETURN
+  const char*       alloc_r;
+    #endif
+    #ifdef OM_TRACK_BACKTRACE
+      #define OM_TRACK_ADDR_MEM_1 alloc_frames
+
+  /* track > 1 */
+  char*             alloc_frames[OM_MAX_KEPT_FRAMES];
+    #else
+      #define OM_TRACK_ADDR_MEM_1 bin_size
+    #endif
+    #define OM_TRACK_ADDR_MEM_2 bin_size
+
+  /* track > 2 */
+  void*             bin_size;
+    #ifdef OM_TRACK_CUSTOM
+  void*             custom;
+    #endif
+    #ifdef OM_TRACK_FILE_LINE
+      #define OM_TRACK_ADDR_MEM_3 free_line
+
+  /* track > 3 */
+  short             free_line;
+  const char*       free_file;
+    #endif
+    #ifdef OM_TRACK_RETURN
+       #ifndef OM_TRACK_ADDR_MEM_3
+       #define OM_TRACK_ADDR_MEM_3 free_r
+       #endif
+  const void*       free_r;
+    #endif
+    #ifdef OM_TRACK_BACKTRACE
+      #define OM_TRACK_ADDR_MEM_4 free_frames
+
+  /* track > 4 */
+  void*             free_frames[OM_MAX_KEPT_FRAMES];
+    #endif
+};
+
+static omError_t omDoCheckTrackAddr(omTrackAddr d_addr, void* addr, void* bin_size, omTrackFlags_t flags, char level,
+                                    omError_t report_error, OM_FLR_DECL);
+static int omCheckFlags(omTrackFlags_t flag);
+static int omCheckPattern(char* s, char p, size_t size);
+
+#define OM_TRACK_MAX 5
+static struct omTrackAddr_s track_addr; /* this is only needed to determine OM_SIZEOF_TRACK_ADDR(i) */
+#if 0
+#define OM_SIZEOF_TRACK_ADDR_1  OM_STRICT_ALIGN_SIZE(((char*)&track_addr.alloc_frames-(char*)&track_addr))
+#define OM_SIZEOF_TRACK_ADDR_2  OM_STRICT_ALIGN_SIZE(((char*)&track_addr.bin_size-(char*)&track_addr))
+#define OM_SIZEOF_TRACK_ADDR_3  OM_STRICT_ALIGN_SIZE(((char*)&track_addr.free_line-(char*)&track_addr)+OM_MIN_SIZEOF_FRONT_PATTERN)
+#define OM_SIZEOF_TRACK_ADDR_4  OM_STRICT_ALIGN_SIZE(((char*)&track_addr.free_frames-(char*)&track_addr)+OM_MIN_SIZEOF_FRONT_PATTERN)
+#define OM_SIZEOF_TRACK_ADDR_5  OM_STRICT_ALIGN_SIZE(sizeof(struct omTrackAddr_s)+OM_MIN_SIZEOF_FRONT_PATTERN)
+#endif
+
+#define OM_SIZEOF_TRACK_ADDR_1  OM_STRICT_ALIGN_SIZE(((char*)&track_addr.OM_TRACK_ADDR_MEM_1-(char*)&track_addr))
+#define OM_SIZEOF_TRACK_ADDR_2  OM_STRICT_ALIGN_SIZE(((char*)&track_addr.OM_TRACK_ADDR_MEM_2-(char*)&track_addr))
+#define OM_SIZEOF_TRACK_ADDR_3  OM_STRICT_ALIGN_SIZE(((char*)&track_addr.OM_TRACK_ADDR_MEM_3-(char*)&track_addr)+OM_MIN_SIZEOF_FRONT_PATTERN)
+#ifdef OM_TRACK_ADDR_MEM_4
+#define OM_SIZEOF_TRACK_ADDR_4  OM_STRICT_ALIGN_SIZE(((char*)&track_addr.OM_TRACK_ADDR_MEM_4-(char*)&track_addr)+OM_MIN_SIZEOF_FRONT_PATTERN)
+#else
+#define OM_SIZEOF_TRACK_ADDR_4 OM_SIZEOF_TRACK_ADDR_5
+#endif
+#define OM_SIZEOF_TRACK_ADDR_5  OM_STRICT_ALIGN_SIZE(sizeof(struct omTrackAddr_s)+OM_MIN_SIZEOF_FRONT_PATTERN)
+
+#define OM_SIZEOF_TRACK_ADDR(i)                                                                     \
+(i > 3 ?                                                                                            \
+ (i == 4 ? OM_SIZEOF_TRACK_ADDR_4 : OM_SIZEOF_TRACK_ADDR_5) :                                       \
+  (i == 3 ? OM_SIZEOF_TRACK_ADDR_3 :  (i == 2 ? OM_SIZEOF_TRACK_ADDR_2 : OM_SIZEOF_TRACK_ADDR_1)))
+
+OM_INLINE_LOCAL omTrackAddr omOutAddr_2_TrackAddr(void* addr);
+
+#define _omOutSize_2_TrackAddrSize(size, track)                                                     \
+  (size + OM_SIZEOF_TRACK_ADDR(track) + (track > 2 ? OM_MIN_SIZEOF_BACK_PATTERN : 0))
+
+#define _omTrackAddr_2_SizeOfTrackAddrHeader(d_addr) ((size_t) OM_SIZEOF_TRACK_ADDR(((omTrackAddr) (d_addr))->track))
+#define _omTrackAddr_2_OutSize(d_addr)                                                                      \
+  (((omTrackAddr) (d_addr))->track > 2 ?                                                                    \
+   omTrack3Addr_2_OutSize(d_addr) : omSizeOfBinAddr(d_addr) - omTrackAddr_2_SizeOfTrackAddrHeader(d_addr))
+#define _omTrack3Addr_2_OutSize(d_addr)                                         \
+  ((((omTrackAddr) (d_addr))->flags & OM_FBIN) ?                            \
+   (((omBin)((omTrackAddr) (d_addr))->bin_size)->sizeW) << LOG_SIZEOF_LONG :    \
+   ((size_t)((omTrackAddr) (d_addr))->bin_size))
+
+/* assume track > 2 */
+#define _omTrackAddr_2_FrontPattern(d_addr) \
+          ((void*)((unsigned long)d_addr + omTrackAddr_2_SizeOfTrackAddrHeader(d_addr) - OM_MIN_SIZEOF_FRONT_PATTERN))
+#define _omTrackAddr_2_SizeOfFrontPattern(d_addr) \
+  ((char*) omTrackAddr_2_OutAddr(d_addr) - (char*) omTrackAddr_2_FrontPattern(d_addr))
+#define _omTrackAddr_2_BackPattern(d_addr) \
+  ((char*) ((unsigned long)d_addr + omTrackAddr_2_SizeOfTrackAddrHeader(d_addr) + _omTrack3Addr_2_OutSize(d_addr)))
+#define _omTrackAddr_2_SizeOfBackPattern(d_addr) \
+  ((char*) d_addr + omSizeOfBinAddr(d_addr) - omTrackAddr_2_BackPattern(d_addr))
+#define omTrackAddr_2_OutAddr(d_addr) ((void*)((unsigned long)d_addr + omTrackAddr_2_SizeOfTrackAddrHeader(d_addr)))
+
+
+#ifdef OM_INTERNAL_DEBUG
+static size_t omTrackAddr_2_SizeOfTrackAddrHeader(omTrackAddr d_addr)
+{
+  size_t size;
+  omAssume(omIsTrackAddr(d_addr) && omOutAddr_2_TrackAddr(d_addr) == d_addr &&
+           d_addr->track > 0 && d_addr->track <= 5);
+  size = _omTrackAddr_2_SizeOfTrackAddrHeader(d_addr);
+  return size;
+}
+static void* omTrackAddr_2_FrontPattern(omTrackAddr d_addr)
+{
+  void* addr;
+  omAssume(omIsTrackAddr(d_addr) && omOutAddr_2_TrackAddr(d_addr) == d_addr &&
+           d_addr->track > 2 && d_addr->track <= 5);
+  addr = _omTrackAddr_2_FrontPattern(d_addr);
+  return addr;
+}
+static size_t omTrackAddr_2_SizeOfFrontPattern(omTrackAddr d_addr)
+{
+  size_t size;
+  omAssume(omIsTrackAddr(d_addr) && omOutAddr_2_TrackAddr(d_addr) == d_addr &&
+           d_addr->track > 2 && d_addr->track <= 5);
+  omAssume((unsigned long) omTrackAddr_2_OutAddr(d_addr) > (unsigned long) omTrackAddr_2_FrontPattern(d_addr));
+  size = _omTrackAddr_2_SizeOfFrontPattern(d_addr);
+  omAssume(size > 0);
+  return size;
+}
+static char* omTrackAddr_2_BackPattern(omTrackAddr d_addr)
+{
+  char* addr;
+  omAssume(omIsTrackAddr(d_addr) && omOutAddr_2_TrackAddr(d_addr) == d_addr &&
+           d_addr->track > 2 && d_addr->track <= 5);
+  addr = _omTrackAddr_2_BackPattern(d_addr);
+  omAssume(OM_ALIGN_SIZE((unsigned long) addr) == (unsigned long) addr);
+  return addr;
+}
+static size_t omTrackAddr_2_SizeOfBackPattern(omTrackAddr d_addr)
+{
+  size_t size;
+  omAssume(omIsTrackAddr(d_addr) && omOutAddr_2_TrackAddr(d_addr) == d_addr &&
+           d_addr->track > 2 && d_addr->track <= 5);
+  size = _omTrackAddr_2_SizeOfBackPattern(d_addr);
+  omAssume(size > 0 && OM_ALIGN_SIZE(size) == size);
+  return size;
+}
+static size_t omTrack3Addr_2_OutSize(omTrackAddr d_addr)
+{
+  size_t size;
+  omAssume(omIsTrackAddr(d_addr) && omOutAddr_2_TrackAddr(d_addr) == d_addr &&
+           d_addr->track > 2 && d_addr->track <= 5);
+  omAssume(d_addr->flags > 0 && d_addr->flags < OM_FMAX &&
+           ! ((d_addr->flags & OM_FBIN) && (d_addr->flags & OM_FSIZE)));
+
+  size = _omTrack3Addr_2_OutSize(d_addr);
+  return size;
+}
+static size_t omTrackAddr_2_OutSize(omTrackAddr d_addr)
+{
+  size_t size;
+  omAssume(omIsTrackAddr(d_addr) && omOutAddr_2_TrackAddr(d_addr) == d_addr &&
+           d_addr->track > 0 && d_addr->track <= 5);
+
+  size = _omTrackAddr_2_OutSize(d_addr);
+  return size;
+}
+static size_t omOutSize_2_TrackAddrSize(size_t size, char track)
+{
+  size_t da_size;
+  omAssume(track > 0 && track <= 5);
+  da_size = _omOutSize_2_TrackAddrSize(size, track);
+  return da_size;
+}
+#else
+#define omTrackAddr_2_SizeOfTrackAddrHeader _omTrackAddr_2_SizeOfTrackAddrHeader
+#define omTrackAddr_2_FrontPattern          _omTrackAddr_2_FrontPattern
+#define omTrackAddr_2_BackPattern           _omTrackAddr_2_BackPattern
+#define omTrack3Addr_2_OutSize              _omTrack3Addr_2_OutSize
+#define omTrackAddr_2_OutSize               _omTrackAddr_2_OutSize
+#define omOutSize_2_TrackAddrSize           _omOutSize_2_TrackAddrSize
+#define omTrackAddr_2_SizeOfFrontPattern     _omTrackAddr_2_SizeOfFrontPattern
+#define omTrackAddr_2_SizeOfBackPattern     _omTrackAddr_2_SizeOfBackPattern
+#endif
+
+OM_INLINE_LOCAL omTrackAddr omOutAddr_2_TrackAddr(void* addr)
+{
+  omTrackAddr d_addr;
+  char* page = omGetPageOfAddr(addr);
+  size_t size = omGetTopBinOfPage((omBinPage) page)->sizeW << LOG_SIZEOF_LONG;
+
+  omAssume(omIsBinPageAddr(addr));
+
+  page += SIZEOF_OM_BIN_PAGE_HEADER;
+  d_addr = (omTrackAddr) ((unsigned long) page + (unsigned long) ((((unsigned long)addr - (unsigned long)page) / size)*size));
+  return d_addr;
+}
+
+size_t omOutSizeOfTrackAddr(void* addr)
+{
+  omTrackAddr d_addr = omOutAddr_2_TrackAddr(addr);
+  omAssume(omIsTrackAddr(addr));
+  return omTrackAddr_2_OutSize(d_addr);
+}
+
+void* omAddr_2_OutAddr(void* addr)
+{
+  if (omIsTrackAddr(addr))
+  {
+    return omTrackAddr_2_OutAddr(omOutAddr_2_TrackAddr(addr));
+  }
+  else
+  {
+    return addr;
+  }
+}
+
+/*******************************************************************
+ *
+ * Low level allocation/free routines: do the actual work,
+ * no checks/tests, assume that everything in
+ * environment is ok
+ *
+ *******************************************************************/
+
+static omTrackAddr _omAllocTrackAddr(size_t d_size)
+{
+  omTrackAddr d_addr;
+  omBin bin;
+
+  if (d_size <= OM_MAX_BLOCK_SIZE)
+    bin = omSmallSize2TrackBin(d_size);
+  else
+    bin = omGetSpecTrackBin(d_size);
+
+  __omTypeAllocBin(omTrackAddr, d_addr, bin);
+
+  omAssume(bin->current_page == omGetPageOfAddr(d_addr));
+
+  omSetTrackOfUsedBlocks(bin->current_page->used_blocks);
+
+  return d_addr;
+}
+void* omAllocTrackAddr(void* bin_size,
+                       omTrackFlags_t flags, char track, OM_FLR_DECL)
+{
+  void* o_addr;
+  size_t o_size = (flags & OM_FBIN ? ((omBin)bin_size)->sizeW << LOG_SIZEOF_LONG :
+                   (bin_size != NULL ? OM_ALIGN_SIZE((size_t) bin_size) : OM_ALIGN_SIZE(1)));
+  omTrackAddr d_addr;
+  size_t d_size;
+  if (track <= 0) track = 1;
+  if (track >  5) track = 5;
+
+  if ((flags & OM_FBIN) && !omIsStaticNormalBin((omBin)bin_size))
+    /* Need to set track >= 3 such that bin_size is kept: Needed
+       for om_KeptAddr */
+    track = (track > 3 ? track : 3);
+  d_size = omOutSize_2_TrackAddrSize(o_size, track);
+
+  d_addr = _omAllocTrackAddr(d_size);
+  d_addr->next = (void*)-1;
+  d_addr->track = track;
+  d_addr->flags = flags | OM_FUSED;
+  if (om_Opts.MarkAsStatic)
+    d_addr->flags |= OM_FSTATIC;
+
+#ifdef OM_TRACK_FILE_LINE
+  d_addr->alloc_file = f;
+  d_addr->alloc_line = (l > SHRT_MAX || l < 0 ? 0 : l);
+#endif
+#ifdef OM_TRACK_RETURN
+  d_addr->alloc_r = r;
+#endif
+
+  o_addr = omTrackAddr_2_OutAddr(d_addr);
+  if (track > 1)
+  {
+#ifdef OM_INTERNAL_DEBUG
+#define FROM_FRAMES 0
+#else
+#define FROM_FRAMES 2
+#endif
+
+#ifdef OM_TRACK_BACKTRACE
+    omGetBackTrace((void **)d_addr->alloc_frames,  FROM_FRAMES, OM_MAX_KEPT_FRAMES);
+#endif
+
+    if (track > 2)
+    {
+      if (flags & OM_FBIN && ((omBin) bin_size)->sticky)
+      {
+        d_addr->bin_size = (void*)(((omBin) bin_size)->sizeW<<LOG_SIZEOF_LONG);
+        d_addr->flags &= ~OM_FBIN;
+        d_addr->flags |= OM_FSIZE;
+      }
+      else
+        d_addr->bin_size = (flags & OM_FBIN ? bin_size : (void*) o_size);
+      omAssume(OM_ALIGN_SIZE((size_t)d_addr->bin_size) == (size_t) d_addr->bin_size);
+
+      memset(omTrackAddr_2_FrontPattern(d_addr), OM_FRONT_PATTERN, omTrackAddr_2_SizeOfFrontPattern(d_addr));
+      if (! (flags & OM_FZERO)) memset(o_addr, OM_INIT_PATTERN, o_size);
+      memset(omTrackAddr_2_BackPattern(d_addr), OM_BACK_PATTERN, omTrackAddr_2_SizeOfBackPattern(d_addr));
+
+#ifdef OM_TRACK_CUSTOM
+      d_addr->custom = NULL;
+#endif
+      if (track > 3)
+      {
+#ifdef OM_TRACK_FILE_LINE
+        d_addr->free_line = -1;
+        d_addr->free_file = (char*) -1;
+#endif
+#ifdef OM_TRACK_RETURN
+        d_addr->free_r = (void*) -1;
+#endif
+
+#ifdef OM_TRACK_BACKTRACE
+        if (track > 4)
+          memset(&d_addr->free_frames, 0, OM_MAX_KEPT_FRAMES*SIZEOF_VOIDP);
+#endif
+      }
+    }
+  }
+  if (flags & OM_FZERO) omMemsetW(o_addr, 0, o_size >> LOG_SIZEOF_LONG);
+  return o_addr;
+}
+
+
+void* omMarkAsFreeTrackAddr(void* addr, int keep, omTrackFlags_t *flags, OM_FLR_DECL)
+{
+  omTrackAddr d_addr = omOutAddr_2_TrackAddr(addr);
+  omAssume(omIsTrackAddr(addr));
+
+  d_addr->next = (void*) -1;
+  if (d_addr->track > 2)
+  {
+    if (d_addr->flags & OM_FUSED)
+    {
+      memset(omTrackAddr_2_OutAddr(d_addr), OM_FREE_PATTERN, omTrackAddr_2_OutSize(d_addr));
+      if (d_addr->track > 3)
+      {
+#ifdef OM_TRACK_FILE_LINE
+        d_addr->free_line = l;
+        d_addr->free_file = f;
+#endif
+#ifdef OM_TRACK_RETURN
+        d_addr->free_r = r;
+#endif
+
+#ifdef OM_TRACK_BACKTRACE
+        if (d_addr->track > 4)
+          omGetBackTrace(d_addr->free_frames,  FROM_FRAMES, OM_MAX_KEPT_FRAMES);
+#endif
+      }
+    }
+    else
+    {
+      omAssume(d_addr->flags & OM_FKEPT);
+    }
+  }
+  if (d_addr->flags & OM_FKEEP) *flags |= OM_FKEEP;
+  d_addr->flags &= ~OM_FUSED;
+  if (keep) d_addr->flags |= OM_FKEPT;
+  else d_addr->flags &= ~OM_FKEPT;
+
+  return(void*) d_addr;
+}
+
+void omFreeTrackAddr(void* d_addr)
+{
+  omBinPage page;
+  omBin bin;
+
+  omAssume(omIsBinPageAddr(d_addr));
+  omAssume(d_addr != NULL && omIsTrackAddr(d_addr));
+  d_addr = omOutAddr_2_TrackAddr(d_addr);
+
+  page = omGetBinPageOfAddr((void*) d_addr);
+  bin = omGetTopBinOfPage(page);
+  /* Ok, here is how it works:
+    1. we unset the first bit of used_blocks
+       ==> used_blocks >= 0
+    2. we do a normal free
+    3. if page of addr was freed, then om_JustFreedPage
+          is != NULL ==> nothing to be done by us
+       else
+          page is still active ==> reset first bit of used_blocks
+  */
+
+  omUnsetTrackOfUsedBlocks(page->used_blocks);
+
+  om_JustFreedPage = NULL;
+
+  __omFreeBinAddr(d_addr);
+
+  if (page != om_JustFreedPage)
+    omSetTrackOfUsedBlocks(page->used_blocks);
+  else
+  {
+    /* Still need to check wheter we need to get rid of SpecBin */
+    if (bin->last_page == NULL && ! omIsStaticTrackBin(bin))
+      omDeleteSpecBin(&bin);
+  }
+}
+
+/*******************************************************************
+ *
+ * Checking a Track Addr
+ *
+ *
+ *******************************************************************/
+
+omError_t omCheckTrackAddr(void* addr, void* bin_size, omTrackFlags_t flags, char level,
+                           omError_t report, OM_FLR_DECL)
+{
+  omTrackAddr d_addr = omOutAddr_2_TrackAddr(addr);
+  omAssume(omIsTrackAddr(addr));
+  omAssume(! omCheckPtr(addr, 0, OM_FLR));
+
+  omAddrCheckReturnCorrupted(d_addr->track < 1 || d_addr->track > OM_TRACK_MAX);
+  omAddrCheckReturnError((flags & OM_FUSED) && omTrackAddr_2_OutAddr(d_addr) != addr, omError_FalseAddrOrMemoryCorrupted);
+
+  omCheckReturn(omDoCheckBinAddr(d_addr, 0, (flags & OM_FUSED ? OM_FUSED : (flags & OM_FKEPT ? OM_FKEPT: 0)),
+                                 level, report, OM_FLR_VAL));
+  return omDoCheckTrackAddr(d_addr, addr, bin_size, flags, level, report, OM_FLR_VAL);
+}
+
+
+static omError_t omDoCheckTrackAddr(omTrackAddr d_addr, void* addr, void* bin_size, omTrackFlags_t flags, char level,
+                                    omError_t report, OM_FLR_DECL)
+{
+  if (flags & OM_FUSED)
+    omAddrCheckReturnError(d_addr->next != ((void*) -1), omError_FreedAddrOrMemoryCorrupted);
+  else
+    omAddrCheckReturnError(d_addr->next != NULL && omCheckPtr(d_addr->next, omError_MaxError, OM_FLR_VAL),
+                           omError_FreedAddrOrMemoryCorrupted);
+  omAddrCheckReturnCorrupted(omCheckFlags(d_addr->flags));
+
+  omAddrCheckReturnError(level > 1 && (flags & OM_FUSED) && omIsInKeptAddrList(d_addr), omError_FreedAddr);
+  omAddrCheckReturnError((d_addr->flags & OM_FUSED) ^ (flags & OM_FUSED), omError_FreedAddrOrMemoryCorrupted);
+
+  if (flags & OM_FBINADDR && flags & OM_FSIZE)
+    omAddrCheckReturnError(omTrackAddr_2_OutSize(d_addr) != (size_t) bin_size, omError_WrongSize);
+
+  if (d_addr->track > 2)
+  {
+    if (d_addr->flags & OM_FBIN)
+    {
+      omAddrCheckReturnCorrupted(!omIsKnownTopBin((omBin) d_addr->bin_size, 1));
+    }
+    else
+    {
+      omAssume(d_addr->flags & OM_FSIZE);
+
+      omAddrCheckReturnCorrupted(!OM_IS_ALIGNED(d_addr->bin_size));
+      omAddrCheckReturnCorrupted((size_t) d_addr->bin_size >
+                                 omSizeOfBinAddr(d_addr)
+                                 - omTrackAddr_2_SizeOfTrackAddrHeader(d_addr)
+                                 - OM_MIN_SIZEOF_BACK_PATTERN);
+      /* Hmm .. here I'd love to have a stricter bound */
+      omAddrCheckReturnCorrupted((size_t) d_addr->bin_size < SIZEOF_OM_ALIGNMENT);
+    }
+
+    omAddrCheckReturnError((flags & OM_FBINADDR) && !((d_addr->flags & OM_FBIN) || ((size_t) d_addr->bin_size <= OM_MAX_BLOCK_SIZE)), omError_NotBinAddr);
+
+    if (flags & OM_FBIN)
+    {
+      if (d_addr->flags & OM_FBIN)
+        omAddrCheckReturnError(((omBin) d_addr->bin_size)->sizeW != ((omBin) bin_size)->sizeW, omError_WrongBin);
+      else
+        omAddrCheckReturnError((((omBin) bin_size)->sizeW << LOG_SIZEOF_LONG) != OM_ALIGN_SIZE((size_t) d_addr->bin_size), omError_WrongBin);
+    }
+    else if (flags & OM_FSIZE)
+    {
+      if (d_addr->flags & OM_FBIN)
+      {
+        omAddrCheckReturnError((((omBin) d_addr->bin_size)->sizeW << LOG_SIZEOF_LONG) < ((size_t) bin_size), omError_WrongSize);
+      }
+      else
+      {
+        omAddrCheckReturnError((size_t) d_addr->bin_size < (size_t) bin_size, omError_WrongSize);
+      }
+    }
+
+    omAddrCheckReturnError(omCheckPattern(omTrackAddr_2_FrontPattern(d_addr), OM_FRONT_PATTERN,omTrackAddr_2_SizeOfFrontPattern(d_addr)),omError_FrontPattern);
+    omAddrCheckReturnError(omCheckPattern(omTrackAddr_2_BackPattern(d_addr), OM_BACK_PATTERN,omTrackAddr_2_SizeOfBackPattern(d_addr)),omError_BackPattern);
+    if (! (d_addr->flags & OM_FUSED))
+      omAddrCheckReturnError(omCheckPattern(omTrackAddr_2_OutAddr(addr), OM_FREE_PATTERN, omTrackAddr_2_OutSize(d_addr)),omError_FreePattern);
+
+    if (d_addr->track > 3)
+    {
+#ifdef OM_TRACK_FILE_LINE
+      if (d_addr->flags & OM_FUSED)
+      {
+        omAddrCheckReturnCorrupted(d_addr->free_line != -1);
+        omAddrCheckReturnCorrupted(d_addr->free_file != (void*) -1);
+      }
+      else
+      {
+        omAddrCheckReturnCorrupted(d_addr->free_line < 0);
+        omAddrCheckReturnCorrupted(d_addr->free_file == (void*) -1);
+      }
+#endif
+#ifdef OM_TRACK_RETURN
+      omAddrCheckReturnCorrupted((d_addr->flags & OM_FUSED)
+                                 && (d_addr->free_r != (void*) -1));
+#endif
+    }
+  }
+  else
+  {
+    /* track < 2 */
+    if (flags & OM_FBIN)
+    {
+      size_t size = omTrackAddr_2_OutSize(d_addr);
+      omAddrCheckReturnError(!omIsKnownTopBin((omBin) bin_size, 1), omError_UnknownBin);
+      omAddrCheckReturnError(size < (((omBin)bin_size)->sizeW<<LOG_SIZEOF_LONG), omError_WrongBin);
+    }
+    else if (flags & OM_FSIZE
+    && (!(flags & OM_FSLOPPY)
+    || (size_t)bin_size > 0))
+    {
+      omAddrCheckReturnError(omTrackAddr_2_OutSize(d_addr) < (size_t) bin_size, omError_WrongSize);
+    }
+    else if (flags & OM_FBINADDR)
+    {
+      size_t size = omTrackAddr_2_OutSize(d_addr);
+      omAddrCheckReturnError(size > OM_MAX_BLOCK_SIZE, omError_NotBinAddr);
+    }
+  }
+  return omError_NoError;
+}
+
+static int omCheckFlags(omTrackFlags_t flag)
+{
+  if (flag > OM_FMAX) return 1;
+  if (! ((flag & OM_FBIN) ^ (flag & OM_FSIZE))) return 1;
+  if (flag & OM_FUSED && flag & OM_FKEPT) return 1;
+  return 0;
+}
+
+static int omCheckPattern(char* s, char p, size_t size)
+{
+  int i;
+  for (i=0; i<size; i++)
+  {
+    if (s[i] != p)
+      return 1;
+  }
+  return 0;
+}
+
+#ifdef OM_TRACK_BACKTRACE
+#define OM_ALLOC_FRAMES(d_addr) d_addr->alloc_frames
+#define OM_FREE_FRAMES(d_addr)  d_addr->free_frames
+#else
+#define OM_ALLOC_FRAMES(d) NULL
+#define OM_FREE_FRAMES(d)  NULL
+#endif
+
+void omPrintTrackAddrInfo(FILE* fd, void* addr, int max_frames)
+{
+  omTrackAddr d_addr = omOutAddr_2_TrackAddr(addr);
+  omAssume(d_addr->track > 0);
+  if (max_frames <= 0) return;
+  if (! (d_addr->flags & OM_FUSED)) return;
+
+  if (max_frames > OM_MAX_KEPT_FRAMES) max_frames = OM_MAX_KEPT_FRAMES;
+
+  fprintf(fd, " allocated at ");
+  if (! _omPrintBackTrace((void **)OM_ALLOC_FRAMES(d_addr),
+                          (d_addr->track > 1 ? max_frames : 0),
+                          fd,
+                          OM_FLR_ARG(d_addr->alloc_file, d_addr->alloc_line, d_addr->alloc_r)))
+    fprintf(fd," ??");
+  if (d_addr->track > 1)
+  {
+    if (d_addr->track > 3 && ! (d_addr->flags & OM_FUSED))
+    {
+      fprintf(fd, "\n freed at ");
+      if (! _omPrintBackTrace(OM_FREE_FRAMES(d_addr),
+                          (d_addr->track > 4 ? max_frames : 0),
+                          fd,
+                          OM_FLR_ARG(d_addr->free_file, d_addr->free_line, d_addr->free_r)))
+        fprintf(fd," ??");
+    }
+  }
+  fprintf(fd, "\n");
+  fflush(fd);
+}
+
+/*******************************************************************
+ *
+ * Misc routines for marking, etc.
+ *
+ *******************************************************************/
+int omIsStaticTrackAddr(void* addr)
+{
+  omTrackAddr d_addr = omOutAddr_2_TrackAddr(addr);
+  omAssume(omIsTrackAddr(addr));
+
+  return (d_addr->flags & OM_FSTATIC);
+}
+
+omBin omGetOrigSpecBinOfTrackAddr(void* addr)
+{
+  omTrackAddr d_addr = omOutAddr_2_TrackAddr(addr);
+  omAssume(omIsTrackAddr(addr));
+
+  if (d_addr->track > 2 && (d_addr->flags & OM_FBIN))
+  {
+    omBin bin = (omBin) d_addr->bin_size;
+    if (omIsSpecBin(bin)) return bin;
+  }
+  return NULL;
+}
+
+void omMarkAsStaticAddr(void* addr)
+{
+  if (omIsTrackAddr(addr))
+  {
+    omTrackAddr d_addr = omOutAddr_2_TrackAddr(addr);
+    d_addr->flags |= OM_FSTATIC;
+  }
+}
+
+void omUnMarkAsStaticAddr(void* addr)
+{
+  if (omIsTrackAddr(addr))
+  {
+    omTrackAddr d_addr = omOutAddr_2_TrackAddr(addr);
+    d_addr->flags &= ~OM_FSTATIC;
+  }
+}
+
+static void _omMarkAsStatic(void* addr)
+{
+  omTrackAddr d_addr = (omTrackAddr) addr;
+  if (!omCheckPtr(addr, omError_MaxError, OM_FLR))
+  {
+    omAssume(omIsTrackAddr(addr) && omOutAddr_2_TrackAddr(addr) == d_addr);
+    d_addr->flags |= OM_FSTATIC;
+  }
+}
+
+static void _omUnMarkAsStatic(void* addr)
+{
+  omTrackAddr d_addr = (omTrackAddr) addr;
+  omAssume(omIsTrackAddr(addr) && omOutAddr_2_TrackAddr(addr) == d_addr);
+  d_addr->flags &= ~OM_FSTATIC;
+}
+
+void omUnMarkMemoryAsStatic()
+{
+  omIterateTroughAddrs(0, 1, _omUnMarkAsStatic, NULL);
+}
+
+void omMarkMemoryAsStatic()
+{
+  omIterateTroughAddrs(0, 1, _omMarkAsStatic, NULL);
+}
+
+#ifdef OM_TRACK_CUSTOM
+void omSetCustomOfTrackAddr(void* addr, void* value)
+{
+  omTrackAddr d_addr = omOutAddr_2_TrackAddr(addr);
+  omAssume(omIsTrackAddr(addr));
+
+  if (d_addr->track > 2)
+  {
+    d_addr->custom = value;
+  }
+}
+
+void* omGetCustomOfTrackAddr(void* addr)
+{
+  omTrackAddr d_addr = omOutAddr_2_TrackAddr(addr);
+  omAssume(omIsTrackAddr(addr));
+
+  if (d_addr->track > 2)
+  {
+    return d_addr->custom;
+  }
+  else
+  {
+    return NULL;
+  }
+}
+#endif
+
+#endif /* OM_HAVE_TRACK */
+
+#ifndef OM_NDEBUG
+
+#ifndef OM_HAVE_TRACK
+#include "omalloc.h"
+#endif
+
+int omIsInKeptAddrList(void* addr)
+{
+  void* ptr = om_KeptAddr;
+  int ret = 0;
+
+#ifdef OM_HAVE_TRACK
+  if (omIsTrackAddr(addr))
+    addr = omOutAddr_2_TrackAddr(addr);
+#endif
+
+  if (om_LastKeptAddr != NULL)
+    *((void**) om_LastKeptAddr) = om_AlwaysKeptAddrs;
+
+  while (ptr != NULL)
+  {
+    if (ptr == addr)
+    {
+      ret = 1; break;
+    }
+    ptr = *((void**) ptr);
+  }
+
+  if (om_LastKeptAddr != NULL)
+    *((void**) om_LastKeptAddr) = NULL;
+
+  return ret;
+}
+#endif /*!OM_NDEBUG*/
diff --git a/omalloc/omDefaultConfig.h b/omalloc/omDefaultConfig.h
new file mode 100644
index 0000000..d13e753
--- /dev/null
+++ b/omalloc/omDefaultConfig.h
@@ -0,0 +1,201 @@
+/*******************************************************************
+ *  File:    omDefaultConfig.h
+ *  Purpose: default declaration of of configurable stuff
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 11/99
+ *******************************************************************/
+
+/********************************************************************
+  If you want to make changes to any of these defines, create a file,
+  say, MyOmConfig.h, define your particular stuff there, and run configure with
+  --external-config-h=MyOmConfig.h.
+
+  If you also need to implement something, then implement it in, say,
+  MyOmConfig.c, and run configure with
+  --external-config-h=MyOmConfig.h --external-config-c=MyOmConfig.c
+
+  For omTest to link, you need to make sure that your implementation can also be
+  used when not linked with your application. I.e. you should also provide a
+  stand-alone implementation if OM_STANDALONE is defined.
+
+  Notice that some of these parameters can also be set at run-time, using
+  the global om_Opts struct.
+********************************************************************/
+#include <mylimits.h>
+#include "omConfig.h"
+/* if external config was provided, 'make' makes links from it to omExternalConfig.h */
+#ifdef OM_HAVE_EXTERNAL_CONFIG_H
+#include "omExternalConfig.h"
+#endif
+
+/* If this is larger than the track parameter given to the omDebug routines,
+   then this is used as TrackLevel: om_Opts.MinTrack is initalized with this */
+#ifndef OM_DEFAULT_MIN_TRACK
+#define OM_DEFAULT_MIN_TRACK 0
+#endif
+
+/* If this is larger than the check parameter given to the omDebug routines,
+   then this is used as CheckLevel: om_Opts.MinCheck is initalized with this */
+#ifndef OM_DEFAULT_MIN_CHECK
+#define OM_DEFAULT_MIN_CHECK 0
+#endif
+
+/* MAX options. If Max < Min, then Max value is used. */
+/* If this is smaller than the track parameter given to the omDebug routines,
+   then this is used as TrackLevel: om_Opts.MaxTrack is initalized with this */
+#ifndef OM_DEFAULT_MAX_TRACK
+#define OM_DEFAULT_MAX_TRACK 5
+#endif
+
+/* If this is smaller than the check parameter given to the omDebug routines,
+   then this is used as CheckLevel: om_Opts.MaxCheck is initalized with this */
+#ifndef OM_DEFAULT_MAX_CHECK
+#define OM_DEFAULT_MAX_CHECK 10
+#endif
+
+/* If this is greater than 0, then the omDebugFree omDebugRealloc delay freeing memory
+   by that many blocks: Initalizes omOpts.Keep
+   Setting this to LONG_MAX never frees memory */
+#ifndef OM_DEFAULT_KEEP
+#define OM_DEFAULT_KEEP 100
+#endif
+
+/* If this is set to
+   0: errors are not reported, only the global variable om_ErrorStatus is set
+   1: short error description, i.e. omError2String(om_ErrorStatus), is reported to stderr
+   2: backtrace of current stack is printed to stderr
+   3: more detailed error description is printed -- this might not make too much sense if
+      you are not familiar with omalloc
+   Initializes om_Opts.HowToReprotErrors
+*/
+#ifndef OM_DEFAULT_HOW_TO_REPORT_ERRORS
+#if defined(OM_INTERNAL_DEBUG)
+#define OM_DEFAULT_HOW_TO_REPORT_ERRORS 3
+#else
+#define OM_DEFAULT_HOW_TO_REPORT_ERRORS 2
+#endif
+#endif
+
+/* if this is set, then all memory allocated with track >= 1 is marked as
+   static, i.e. it is not mention in omPrintUsedAddrs */
+#ifndef OM_DEFAULT_MARK_AS_STATIC
+#define OM_DEFAULT_MARK_AS_STATIC 0
+#endif
+
+/* Number of pages per region, i.e., how many pages are allocated at once, after we
+   run out of pages: Initalizes om_Opts.PagesPerRegion
+   The higher this value is, the fewer calls to valloc (resp. mmap) need to be make,
+   but the more unused memory the application might have allocated from the operating system
+*/
+#ifndef OM_DEFAULT_PAGES_PER_REGION
+#define OM_DEFAULT_PAGES_PER_REGION 512
+#endif
+
+/* This is called if nothing goes any more, i.e., if
+   memory request can not be serviced. If set, this function should never return.*/
+#ifndef OM_DEFAULT_OUT_OF_MEMORY_FUNC
+/* This initalizes om_Opts.OutOfMemoryFunc which is declared as
+   void (*OutOfMemoryFunc)(); */
+#define OM_DEFAULT_OUT_OF_MEMORY_FUNC NULL
+#endif
+#ifndef OM_OUT_OF_MEMORY_HOOK
+#define OM_OUT_OF_MEMORY_HOOK()                             \
+do                                                          \
+{                                                           \
+  if (om_Opts.OutOfMemoryFunc != NULL)                      \
+    om_Opts.OutOfMemoryFunc();                              \
+   fprintf(stderr, "***Emergency Exit: Out of Memory\n");   \
+   exit(1);                                                 \
+}                                                           \
+while (0)
+#endif
+
+/* This is called whenever no more memory could be obtained from the system.
+   It should trigger the release of as much memory by the application as possible */
+#ifndef OM_DEFAULT_MEMORY_LOW_FUNC
+/* This initalizes om_Opts.MemoryLowFunc which is declared as
+   void (*MemoryLowFunc)(); */
+#define OM_DEFAULT_MEMORY_LOW_FUNC NULL
+#endif
+#ifndef OM_DEFAULT_MEMORY_LOW_HOOK
+#define OM_MEMORY_LOW_HOOK()                    \
+do                                              \
+{                                               \
+  if (om_Opts.MemoryLowFunc != NULL)            \
+    om_Opts.MemoryLowFunc();                    \
+}                                               \
+while(0)
+#endif
+
+/* This is called after an omError was reported.
+   It is especially useful to set a debugger breakpoint
+   to this func */
+#ifndef OM_DEFAULT_ERROR_HOOK
+#define OM_DEFAULT_ERROR_HOOK omErrorBreak
+#endif
+
+/********************************************************************
+ *
+ * The following can NOT be set at run time
+ *
+ ********************************************************************/
+/* The following hooks are called after the respective
+   system routine was called, and the Stats struct was updated
+   Not settable at run-time (makes no sense for thise to be functions, for they would
+   be called each time the underlying malloc/valloc is called !) */
+#ifndef OM_MALLOC_HOOK
+#define OM_MALLOC_HOOK(size) do {} while (0)
+#endif
+#ifndef OM_REALLOC_HOOK
+#define OM_REALLOC_HOOK(oldsize, newsize) do {} while (0)
+#endif
+#ifndef OM_VALLOC_HOOK
+#define OM_VALLOC_HOOK(size) do {} while (0)
+#endif
+#ifndef OM_FREE_HOOK
+#define OM_FREE_HOOK(size) do {} while (0)
+#endif
+#ifndef OM_VFREE_HOOK
+#define OM_VFREE_HOOK(size) do {} while (0)
+#endif
+#ifndef OM_ALLOC_BINPAGE_HOOK
+#define OM_ALLOC_BINPAGE_HOOK do {} while (0)
+#endif
+#ifndef OM_FREE_BINPAGE_HOOK
+#define OM_FREE_BINPAGE_HOOK do {} while (0)
+#endif
+
+/*
+ * Some stuff related to tracking of addresses
+ */
+
+/* minimal number of WORDS for padding before addr: needs to > 0: only relevant for track >= 3 */
+#ifndef OM_MIN_SIZEWOF_FRONT_PATTERN
+#define OM_MIN_SIZEWOF_FRONT_PATTERN 1
+#endif
+
+/* minimal number of WORDS for padding before addr: needs to > 0: only relevant for track >= 3 */
+#ifndef OM_MIN_SIZEWOF_BACK_PATTERN
+#define OM_MIN_SIZEWOF_BACK_PATTERN 1
+#endif
+
+/* maximal number of stack frames kept for stack at the allocation time of addr (track >= 2)
+   and free time of addr (track >= 5) */
+#ifndef OM_MAX_KEPT_FRAMES
+#define OM_MAX_KEPT_FRAMES 10
+#endif
+
+/* pattern with which memory is initalized, for front and back padding,
+   and for free memory: only relevant if track >= 3*/
+#ifndef OM_INIT_PATTERN
+#define OM_INIT_PATTERN    0xfe
+#endif
+#ifndef OM_FRONT_PATTERN
+#define OM_FRONT_PATTERN   0xfd
+#endif
+#ifndef OM_BACK_PATTERN
+#define OM_BACK_PATTERN    0xfc
+#endif
+#ifndef OM_FREE_PATTERN
+#define OM_FREE_PATTERN    0xfb
+#endif
diff --git a/omalloc/omDerivedConfig.h b/omalloc/omDerivedConfig.h
new file mode 100644
index 0000000..2408ffa
--- /dev/null
+++ b/omalloc/omDerivedConfig.h
@@ -0,0 +1,142 @@
+/*******************************************************************
+ *  File:    omDerivedConfig.h.in
+ *  Purpose: configuration which are derived from omConfig.h
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 11/99
+ *******************************************************************/
+#ifndef OM_DERIVED_CONFIG_H
+#define OM_DERIVED_CONFIG_H
+
+#ifndef SIZEOF_VOIDP
+/* configure makes sure that SIZEOF_VOIDP == SIZEOF_LONG */
+#define SIZEOF_VOIDP SIZEOF_LONG
+#endif
+
+/* SIZEOF_VOIDP == 8 || SIZEOF_VOIDP == 4 checked by configure */
+#if SIZEOF_VOIDP == 8
+#define LOG_SIZEOF_LONG  3
+#define LOG_SIZEOF_VOIDP 3
+#define LOG_BIT_SIZEOF_LONG 6
+#else
+#define LOG_SIZEOF_LONG  2
+#define LOG_SIZEOF_VOIDP 2
+#define LOG_BIT_SIZEOF_LONG 5
+#endif
+
+/* SIZEOF_SYSTEM_PAGE == 4096 || SIZEOF_SYSTEM_PAGE == 8192 checked by configure */
+#if SIZEOF_SYSTEM_PAGE == 8192
+#define LOG_BIT_SIZEOF_SYSTEM_PAGE 13
+#else
+#define LOG_BIT_SIZEOF_SYSTEM_PAGE 12
+#endif
+
+#ifndef CHAR_BIT
+#define CHAR_BIT 8
+#endif
+
+#ifndef BIT_SIZEOF_LONG
+#define BIT_SIZEOF_LONG (CHAR_BIT << LOG_SIZEOF_LONG)
+#endif
+
+#ifdef OM_ALIGN_8
+#define SIZEOF_OM_ALIGNMENT 8
+#define SIZEOF_OM_ALIGNMENT_1 7
+#define LOG_SIZEOF_OM_ALIGNMENT 3
+#define SIZEOF_STRICT_ALIGNMENT 8
+#else
+#define SIZEOF_OM_ALIGNMENT 4
+#define SIZEOF_OM_ALIGNMENT_1 3
+#define LOG_SIZEOF_OM_ALIGNMENT 2
+#ifdef OM_ALIGNMENT_NEEDS_WORK
+#define SIZEOF_STRICT_ALIGNMENT 8
+#else
+#define SIZEOF_STRICT_ALIGNMENT 4
+#endif
+#endif
+
+#define OM_ALIGN_SIZE(size) \
+   ((((unsigned long) size) + SIZEOF_OM_ALIGNMENT_1) & (~SIZEOF_OM_ALIGNMENT_1))
+
+#define OM_IS_ALIGNED(what) \
+   ((((unsigned long) what) & SIZEOF_OM_ALIGNMENT_1) == 0)
+
+#define OM_STRICT_ALIGN_SIZE(size)                                          \
+   ((((size_t) (size)) + SIZEOF_STRICT_ALIGNMENT - 1) & (~ (SIZEOF_STRICT_ALIGNMENT - 1)))
+
+#define OM_IS_STRICT_ALIGNED(what) \
+   ((((unsigned long) what) & (SIZEOF_STRICT_ALIGNMENT -1)) == 0)
+
+#if defined(OM_NDEBUG) && defined(OM_HAVE_TRACK)
+#undef OM_HAVE_TRACK
+#endif
+
+/* define to enable assume */
+#ifndef HAVE_OM_ASSUME
+#if defined(OM_INTERNAL_DEBUG)
+#define HAVE_OM_ASSUME
+#endif
+#endif
+
+/* set to 0 to disable aso memory mamagent */
+#ifndef HAVE_ASO
+#define HAVE_ASO 1
+#endif
+#if defined(HAVE_ASO) && HAVE_ASO == 1
+/* define to enable ASO debugging */
+#undef ASO_DEBUG
+#endif
+
+#ifndef NULL
+#define NULL ((void*)0)
+#endif
+
+#if !defined(OM_TRACK_FILE_LINE) && ! defined(OM_TRACK_RETURN)
+#define OM_TRACK_FILE_LINE
+#endif
+
+/* The following macros save a lot of typing */
+#ifdef OM_TRACK_FILE_LINE
+#define OM_FL_DECL      const char* f, const int l
+#define OM_FL_VAL       f, l
+#define OM_FL           __FILE__,__LINE__
+#define OM_FL_KOMMA     ,
+#else
+#define OM_FL_DECL
+#define OM_FL_VAL
+#define OM_FL
+#define OM_FL_KOMMA
+#endif
+
+#define OM_CFL_DECL     char check OM_FL_KOMMA OM_FL_DECL
+#define OM_CFL_VAL      check OM_FL_KOMMA OM_FL_VAL
+#define OM_CFL          OM_CHECK OM_FL_KOMMA OM_FL
+
+#define OM_TFL_DECL     char track OM_FL_KOMMA OM_FL_DECL
+#define OM_TFL_VAL      track OM_FL_KOMMA OM_FL_VAL
+#define OM_TFL          OM_TRACK OM_FL_KOMMA OM_FL
+
+#define OM_CTFL_DECL    char check, char track OM_FL_KOMMA OM_FL_DECL
+#define OM_CTFL_VAL     check,track OM_FL_KOMMA OM_FL_VAL
+#define OM_CTFL         OM_CHECK,OM_TRACK OM_FL_KOMMA OM_FL
+
+#ifdef OM_TRACK_RETURN
+#define OM_FLR_DECL         OM_FL_DECL OM_FL_KOMMA const void* r
+#define OM_FLR_VAL          OM_FL_VAL OM_FL_KOMMA r
+#define OM_FLR              OM_FL OM_FL_KOMMA 0
+#define OM_R_DEF            void* r; GET_RET_ADDR(r)
+#ifdef OM_TRACK_FILE_LINE
+#define OM_FLR_ARG(f,l,r)   f,l,r
+#else
+#define OM_FLR_ARG(f,l,r)   r
+#endif
+
+#else
+
+#define OM_FLR_DECL OM_FL_DECL
+#define OM_FLR_VAL  OM_FL_VAL
+#define OM_FLR      OM_FL
+#define OM_R_DEF    do {} while (0)
+#define OM_FLR_ARG(f,l,r)   f,l
+#endif
+
+#endif /* OM_DERIVED_CONFIG_H  */
diff --git a/omalloc/omError.c b/omalloc/omError.c
new file mode 100644
index 0000000..c697acb
--- /dev/null
+++ b/omalloc/omError.c
@@ -0,0 +1,136 @@
+/*******************************************************************
+ *  File:    omError.c
+ *  Purpose: implementation of Error handling routines
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 11/99
+ *******************************************************************/
+
+#include <stdarg.h>
+#include "omalloc.h"
+
+omError_t om_ErrorStatus = omError_NoError;
+omError_t om_InternalErrorStatus = omError_NoError;
+
+struct omErrorString_s
+{
+  omError_t error;
+  char* s_error;
+  char* string;
+};
+
+/* strings describing omErrors */
+static struct omErrorString_s om_ErrorStrings[] =
+{
+  {omError_NoError,                     "omError_NoError",                     "no error"},
+  {omError_Unknown,                     "omError_Unknown",                     "unknown error" },
+  {omError_MemoryCorrupted,             "omError_MemoryCorrupted",             "memory corrupted"},
+  {omError_InternalBug,                 "omError_InternalBug",                 "internal omalloc bug"},
+  {omError_NullAddr,                    "omError_NullAddr",                    "addr is NULL"},
+  {omError_InvalidRangeAddr,            "omError_InvalidRangeAddr",            "addr not in valid range"},
+  {omError_FalseAddr,                   "omError_FalseAddr",                   "addr not as returned by omalloc"},
+  {omError_FalseAddrOrMemoryCorrupted,  "omError_FalseAddrOrMemoryCorrupted",  "addr not as returned by omalloc or memory corrupted", },
+  {omError_WrongSize,                   "omError_WrongSize",                   "wrong size specification of addr"},
+  {omError_FreedAddr,                   "omError_FreedAddr",                   "addr had previosuly been freed"},
+  {omError_FreedAddrOrMemoryCorrupted,  "omError_FreedAddrOrMemoryCorrupted",  "addr had previosuly been freed  or memory corrupted"},
+  {omError_WrongBin,                    "omError_WrongBin",                    "addr is not from given Bin"},
+  {omError_UnknownBin,                  "omError_UnknownBin",                  "given Bin is unknown"},
+  {omError_NotBinAddr,                  "omError_NotBinAddr",                  "addr is not a BinAddr"},
+  {omError_UnalignedAddr,               "omError_UnalignedAddr",               "addr is unaligned"},
+  {omError_NullSizeAlloc,               "omError_NullSizeAlloc",               "alloc of size 0"},
+  {omError_ListCycleError,              "omError_ListCycleError",              "list has cycles"},
+  {omError_SortedListError,             "omError_SortedListError",             "sorted list is unsorted"},
+  {omError_KeptAddrListCorrupted,       "omError_KeptAddrListCorrupted",       "list of kept addresses are corrupted"},
+  {omError_FrontPattern,                "omError_FrontPattern",                "written to front of addr"},
+  {omError_BackPattern,                 "omError_BackPattern",                 "written after end of addr"},
+  {omError_FreePattern,                 "omError_FreePattern",                 "written into freed memory"},
+  {omError_NotString,                   "omError_NotString",                   "string not null terminated"},
+  {omError_StickyBin,                   "omError_StickyBin",                   "wrong handling of sticky bins"},
+
+  {omError_MaxError, NULL} /* this needs to be the last entry */
+};
+
+const char* omError2String(omError_t error)
+{
+  int i = 0;
+  while (! (om_ErrorStrings[i].string == NULL && om_ErrorStrings[i].error == omError_MaxError))
+  {
+    if (om_ErrorStrings[i].error == error) return om_ErrorStrings[i].string;
+    i++;
+  }
+  return "undocumented error";
+}
+
+const char* omError2Serror(omError_t error)
+{
+  int i = 0;
+  while (! (om_ErrorStrings[i].string == NULL && om_ErrorStrings[i].error == omError_MaxError))
+  {
+    if (om_ErrorStrings[i].error == error) return om_ErrorStrings[i].s_error;
+    i++;
+  }
+  return "omError_UnKnown";
+}
+
+#ifndef OM_NDEBUG
+int om_CallErrorHook = 1;
+#endif
+
+omError_t omReportError(omError_t error, omError_t report_error, OM_FLR_DECL,
+                        const char* fmt, ...)
+{
+  int max_check, max_track;
+
+  if (report_error == omError_MaxError) return error;
+  /* reset MaxTrack and MaxCheck to prevent infinite loop, in case
+     printf allocates memory */
+  max_check = om_Opts.MaxCheck;
+  max_track = om_Opts.MaxTrack;
+  om_Opts.MaxCheck = 0;
+  om_Opts.MaxTrack = 0;
+
+  om_InternalErrorStatus = error;
+  om_ErrorStatus = (report_error == omError_NoError ? error : report_error);
+
+  if (om_Opts.HowToReportErrors && om_ErrorStatus != omError_NoError)
+  {
+    /* to avoid spurious error msg in 64 bit mode*/
+    if (om_ErrorStatus == omError_StickyBin) return error;
+    fprintf(stderr, "***%s: %s", omError2Serror(om_ErrorStatus), omError2String(om_ErrorStatus));
+
+#ifdef OM_INTERNAL_DEBUG
+    if (om_ErrorStatus != error)
+      fprintf(stderr, "\n___%s: %s", omError2Serror(error), omError2String(error));
+#endif
+
+    if (om_Opts.HowToReportErrors > 2 && fmt != NULL && *fmt != '\0')
+    {
+      va_list ap;
+      va_start(ap, fmt);
+      fprintf(stderr, ": ");
+      vfprintf(stderr, fmt, ap);
+      va_end(ap);
+    }
+
+    if (om_Opts.HowToReportErrors > 1)
+    {
+#ifndef OM_NDEBUG
+      fprintf(stderr, "\n occured at: ");
+      if (! _omPrintCurrentBackTrace(stderr, OM_FLR_VAL))
+        fprintf(stderr, " ??");
+#endif
+    }
+    fprintf(stderr, "\n");
+    fflush(stderr);
+  }
+  if (om_CallErrorHook)
+    om_Opts.ErrorHook();
+
+  om_Opts.MaxCheck = max_check;
+  om_Opts.MaxTrack = max_track;
+  return error;
+}
+
+
+/* this is a dummy function and used as default for om_Opts.ErrorHook */
+extern void omErrorBreak()
+{}
diff --git a/omalloc/omError.h b/omalloc/omError.h
new file mode 100644
index 0000000..95ea54b
--- /dev/null
+++ b/omalloc/omError.h
@@ -0,0 +1,98 @@
+/*******************************************************************
+ *  File:    omError.h
+ *  Purpose: Error handling of omalloc
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 11/99
+ *******************************************************************/
+#ifndef OM_ERROR_H
+#define OM_ERROR_H
+
+#include <stdio.h>
+/*******************************************************************
+ *
+ *  error codes
+ *
+ *******************************************************************/
+enum omError_e
+{
+  omError_NoError = 0,
+  omError_Unknown,
+  omError_InternalBug,
+  omError_MemoryCorrupted,
+  omError_NullAddr,
+  omError_InvalidRangeAddr,
+  omError_FalseAddr,
+  omError_FalseAddrOrMemoryCorrupted,
+  omError_WrongSize,
+  omError_FreedAddr,
+  omError_FreedAddrOrMemoryCorrupted,
+  omError_WrongBin,
+  omError_UnknownBin,
+  omError_NotBinAddr,
+  omError_UnalignedAddr,
+  omError_NullSizeAlloc,
+  omError_ListCycleError,
+  omError_SortedListError,
+  omError_KeptAddrListCorrupted,
+  omError_FreePattern,
+  omError_BackPattern,
+  omError_FrontPattern,
+  omError_NotString,
+  omError_StickyBin,
+  omError_MaxError
+};
+typedef enum omError_e omError_t;
+
+/* global variable holding last omError */
+extern omError_t om_ErrorStatus;
+/* globale variable holding last low-level omError */
+extern omError_t om_InternalErrorStatus;
+/* returns description of error */
+const char* omError2String(omError_t error);
+/* returns error as string */
+const char* omError2Serror(omError_t error);
+extern omError_t omReportError(omError_t error, omError_t report_error, OM_FLR_DECL,
+                               const char* fmt, ...);
+
+/* this is a dummy function and used as default for om_Opts.ErrorHook */
+extern void omErrorBreak();
+
+#ifndef OM_NDEBUG
+extern void omPrintAddrInfo(FILE* fd, void* addr, const char* s);
+#else
+#define omPrintAddrInfo(fd, addr, s) fprintf(fd, "OM_NDEBUG: no addr info available\n")
+#endif
+
+/*BEGINPRIVATE*/
+
+#ifndef OM_NDEBUG
+extern int om_CallErrorHook;
+#else
+#define om_CallErrorHook 1
+#endif
+
+/*******************************************************************
+ *
+ * om_assume(x) -- a handy macro for assumptions
+ *
+ ******************************************************************/
+#ifndef HAVE_OM_ASSUME
+
+#define omAssume(x) do {} while (0)
+
+#else /* ! HAVE_OM_ASSUME */
+
+#define omAssume(x)                                             \
+do                                                              \
+{                                                               \
+  if (! (x))                                                    \
+  {                                                             \
+    omReportError(omError_InternalBug, omError_InternalBug, OM_FLR, "omAssume violation");   \
+  }                                                             \
+}                                                               \
+while (0)
+
+#endif /* HAVE_OM_ASSUME */
+/*ENDPRIVATE*/
+
+#endif /* OM_LOCAL_H */
diff --git a/omalloc/omGetBackTrace.c b/omalloc/omGetBackTrace.c
new file mode 100644
index 0000000..3dd5b07
--- /dev/null
+++ b/omalloc/omGetBackTrace.c
@@ -0,0 +1,80 @@
+/*******************************************************************
+ *  File:    omGetBackTrace.c
+ *  Purpose: routines for getting Backtraces of stack
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 11/99
+ *******************************************************************/
+#ifndef OM_NDEBUG
+
+#if __GNUC__ > 1
+
+static void* om_this_main_frame_addr = 0;
+
+void omInitGetBackTrace()
+{
+  if (__builtin_frame_address(0) != 0 &&
+      __builtin_frame_address(1) > __builtin_frame_address(0))
+    om_this_main_frame_addr = __builtin_frame_address(1);
+}
+
+#define OM_GET_BACK_TRACE(j)                                    \
+case j:                                                         \
+{                                                               \
+  f_addr = __builtin_frame_address(j);                          \
+  if (f_addr  > this_frame && f_addr < om_this_main_frame_addr) \
+  {                                                             \
+    r_addr = __builtin_return_address(j);                       \
+    if (r_addr)                                                 \
+    {                                                           \
+      bt[i] = r_addr;                                           \
+      i++;                                                      \
+      if (i >= max) break;                                      \
+    }                                                           \
+    else break;                                                 \
+  }                                                             \
+  else break;                                                   \
+}
+
+int omGetBackTrace(void** bt, int start, int max)
+{
+  int i = 0;
+  void* this_frame = __builtin_frame_address(0);
+  void* f_addr;
+  void* r_addr;
+
+  start++;
+
+  switch(start)
+  {
+    OM_GET_BACK_TRACE(1)
+    OM_GET_BACK_TRACE(2)
+/* the following fails on Mac OsX, but the debugging
+ * support it provides is too useful to disable it
+ */
+#ifdef __linux
+#if defined(__x86_64) || defined(__i386)
+    OM_GET_BACK_TRACE(3)
+    OM_GET_BACK_TRACE(4)
+    OM_GET_BACK_TRACE(5)
+    OM_GET_BACK_TRACE(6)
+    OM_GET_BACK_TRACE(7)
+    OM_GET_BACK_TRACE(8)
+    OM_GET_BACK_TRACE(9)
+    OM_GET_BACK_TRACE(10)
+    OM_GET_BACK_TRACE(11)
+    OM_GET_BACK_TRACE(12)
+    OM_GET_BACK_TRACE(13)
+    OM_GET_BACK_TRACE(14)
+    OM_GET_BACK_TRACE(15)
+    OM_GET_BACK_TRACE(16)
+    OM_GET_BACK_TRACE(17)
+#endif
+#endif
+  }
+  if (i < max) bt[i] = 0;
+  return i;
+}
+
+#endif /* __GNUC__ > 1 */
+
+#endif /* ! OM_NDEBUG */
diff --git a/omalloc/omGetBackTrace.h b/omalloc/omGetBackTrace.h
new file mode 100644
index 0000000..cbe933d
--- /dev/null
+++ b/omalloc/omGetBackTrace.h
@@ -0,0 +1,18 @@
+/*******************************************************************
+ *  File:    omGetBackTrace.h
+ *  Purpose: routines for getting Backtraces of stack
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 11/99
+ *******************************************************************/
+#ifndef OM_GET_BACKTRACE_H
+#define OM_GET_BACKTRACE_H
+
+#if defined(OM_GET_BACKTRACE_WORKS) && !defined(OM_NDEBUG) && !defined(__OPTIMIZE__)
+void omInitGetBackTrace();
+int omGetBackTrace(void** bt, int start, int max);
+#else
+#define omInitGetBackTrace() do {} while (0)
+#define omGetBackTrace(bt, s, max) (0)
+#endif
+
+#endif
diff --git a/omalloc/omGetPageSize.h b/omalloc/omGetPageSize.h
new file mode 100644
index 0000000..7f8fc19
--- /dev/null
+++ b/omalloc/omGetPageSize.h
@@ -0,0 +1,46 @@
+/*******************************************************************
+ *  File:    omGetPageSize.h
+ *  Purpose: figure out how to get the pagesize
+ *  This is adapted from dlmalloc's mechanisms which in fact derived it from
+ *  bsd/gnu getpagesize.h
+ *******************************************************************/
+#include <unistd.h>
+
+#ifndef omalloc_getpagesize
+#  ifdef _SC_PAGESIZE         /* some SVR4 systems omit an underscore */
+#    ifndef _SC_PAGE_SIZE
+#      define _SC_PAGE_SIZE _SC_PAGESIZE
+#    endif
+#  endif
+#  ifdef _SC_PAGE_SIZE
+#    define omalloc_getpagesize sysconf(_SC_PAGE_SIZE)
+#  else
+#    if defined(BSD) || defined(DGUX) || defined(HAVE_GETPAGESIZE)
+       extern size_t getpagesize();
+#      define omalloc_getpagesize getpagesize()
+#    else
+#      include <sys/param.h>
+#      ifdef EXEC_PAGESIZE
+#        define omalloc_getpagesize EXEC_PAGESIZE
+#      else
+#        ifdef NBPG
+#          ifndef CLSIZE
+#            define omalloc_getpagesize NBPG
+#          else
+#            define omalloc_getpagesize (NBPG * CLSIZE)
+#          endif
+#        else
+#          ifdef NBPC
+#            define omalloc_getpagesize NBPC
+#          else
+#            ifdef PAGESIZE
+#              define omalloc_getpagesize PAGESIZE
+#            else
+#              define omalloc_getpagesize (4096) /* just guess */
+#            endif
+#          endif
+#        endif
+#      endif
+#    endif
+#  endif
+#endif
diff --git a/omalloc/omInline.h b/omalloc/omInline.h
new file mode 100644
index 0000000..cb4c1c6
--- /dev/null
+++ b/omalloc/omInline.h
@@ -0,0 +1,262 @@
+/*******************************************************************
+ *  File:    omInline.c
+ *  Purpose: implementation of omalloc functions which could
+ *           be inlined
+ *  Author:  obachman at mathematik.uni-kl.de (Olaf Bachmann)
+ *  Created: 11/99
+ *******************************************************************/
+#if defined(OM_INLINE) || defined(OM_ALLOC_C)
+
+#ifndef OM_INLINE_H
+#define OM_INLINE_H
+
+OM_INLINE_IMPL omBin omGetBinOfPage(omBinPage page)
+{
+  unsigned long sticky = omGetStickyOfPage(page);
+  omBin bin = omGetTopBinOfPage(page);
+
+  if (! omIsStickyBin(bin))
+  {
+    while (bin->sticky != sticky && bin->next != NULL)
+    {
+      bin = bin->next;
+    }
+  }
+  return bin;
+}
+
+OM_INLINE_IMPL int _omIsBinPageAddr(const void* addr)
+{
+  unsigned long index = omGetPageIndexOfAddr(addr);
+  if (index >= om_MinBinPageIndex && index <= om_MaxBinPageIndex)
+  {
+    unsigned long shift = omGetPageShiftOfAddr(addr);
+    return ((om_BinPageIndicies[index - om_MinBinPageIndex] & (((unsigned long) 1) << shift)) != 0L);
+  }
+  return 0;
+}
+
+OM_INLINE_IMPL void* _omAllocBin(omBin bin)
+{
+  void* addr;
+  __omTypeAllocBin(void*, addr, bin);
+  return addr;
+}
+OM_INLINE_IMPL void* _omAlloc0Bin(omBin bin)
+{
+  void* addr;
+  __omTypeAlloc0Bin(void*, addr, bin);
+  return addr;
+}
+OM_INLINE_IMPL void* _omReallocBin(void* addr, omBin old_bin, omBin new_bin)
+{
+  void* new_addr;
+  __omTypeReallocBin(addr, old_bin, void*, new_addr, new_bin);
+  return new_addr;
+}
+OM_INLINE_IMPL void* _omRealloc0Bin(void* addr, omBin old_bin, omBin new_bin)
+{
+  void* new_addr;
+  __omTypeRealloc0Bin(addr, old_bin, void*, new_addr, new_bin);
+  return new_addr;
+}
+
+
+OM_INLINE_IMPL void* _omAlloc(size_t size)
+{
+  void* addr;
+  __omTypeAlloc(void*, addr, size);
+  return addr;
+}
+OM_INLINE_IMPL void* _omAlloc0(size_t size)
+{
+  void* addr;
+  __omTypeAlloc0(void*, addr, size);
+  return addr;
+}
+OM_INLINE_IMPL void* _omReallocSize(void* addr, size_t old_size, size_t new_size)
+{
+  void* new_addr;
+  __omTypeReallocSize(addr, old_size, void*, new_addr, new_size);
+  return new_addr;
+}
+OM_INLINE_IMPL void* _omRealloc0Size(void* addr, size_t old_size, size_t new_size)
+{
+  void* new_addr;
+  __omTypeRealloc0Size(addr, old_size, void*, new_addr, new_size);
+  return new_addr;
+}
+OM_INLINE_IMPL void* _omRealloc(void* addr, size_t size)
+{
+  void* new_addr;
+  __omTypeRealloc(addr, void*, new_addr, size);
+  return new_addr;
+}
+OM_INLINE_IMPL void* _omRealloc0(void* addr, size_t size)
+{
+  void* new_addr;
+  __omTypeRealloc0(addr, void*, new_addr, size);
+  return new_addr;
+}
+
+#ifdef OM_ALIGNMENT_NEEDS_WORK
+OM_INLINE_IMPL void* _omAllocAligned(size_t size)
+{
+  void* addr;
+  __omTypeAllocAligned(void*, addr, size);
+  return addr;
+}
+OM_INLINE_IMPL void* _omAlloc0Aligned(size_t size)
+{
+  void* addr;
+  __omTypeAlloc0Aligned(void*, addr, size);
+  return addr;
+}
+OM_INLINE_IMPL void* _omReallocAlignedSize(void* addr, size_t old_size, size_t new_size)
+{
+  void* new_addr;
+  __omTypeReallocAlignedSize(addr, old_size, void*, new_addr, new_size);
+  return new_addr;
+}
+OM_INLINE_IMPL void* _omRealloc0AlignedSize(void* addr, size_t old_size, size_t new_size)
+{
+  void* new_addr;
+  __omTypeRealloc0AlignedSize(addr, old_size, void*, new_addr, new_size);
+  return new_addr;
+}
+OM_INLINE_IMPL void* _omReallocAligned(void* addr, size_t size)
+{
+  void* new_addr;
+  __omTypeReallocAligned(addr, void*, new_addr, size);
+  return new_addr;
+}
+OM_INLINE_IMPL void* _omRealloc0Aligned(void* addr, size_t size)
+{
+  void* new_addr;
+  __omTypeRealloc0Aligned(addr, void*, new_addr, size);
+  return new_addr;
+}
+
+OM_INLINE_IMPL void* _omMemDupAligned(void* addr)
+{
+  void* r;
+  size_t sizeW = omSizeWOfAddr(addr);
+  __omTypeAllocAligned(void*, r, sizeW << LOG_SIZEOF_LONG);
+  omMemcpyW(r, addr, sizeW);
+  return r;
+}
+
+#endif /* OM_ALIGNMENT_NEEDS_WORK */
+
+OM_INLINE_IMPL char* _omStrDup(const char* s)
+{
+  void* r;
+  size_t i=(size_t)0;
+
+  while (s[i]) i++;
+  i++;
+  __omTypeAlloc(void*, r, i);
+  memcpy(r, (void*) s, i);
+  return (char*) r;
+}
+
+OM_INLINE_IMPL void* _omMemDup(void* addr)
+{
+  void* r;
+  if (omIsNormalBinPageAddr(addr))
+  {
+    omBin bin = omGetTopBinOfAddr(addr);
+    __omTypeAllocBin(void*, r, bin);
+    omMemcpyW(r, addr, bin->sizeW);
+  }
+  else
+  {
+    size_t size = omSizeWOfAddr(addr);
+    __omTypeAlloc(void*, r, size << LOG_SIZEOF_LONG);
+    omMemcpyW(r, addr, size);
+  }
+  return r;
+}
+
+OM_INLINE_IMPL void* _omalloc(size_t size)
+{
+  void* addr;
+  if (! size) size = (size_t)1;
+  __omTypeAllocAligned(void*, addr,size);
+  return addr;
+}
+
+OM_INLINE_IMPL void* _omalloc0(size_t size)
+{
+  void* addr;
+  if (! size) size = (size_t)1;
+  __omTypeAlloc0Aligned(void*,addr, size);
+  return addr;
+}
+
+OM_INLINE_IMPL void* _omreallocSize(void* addr, size_t old_size, size_t new_size)
+{
+  void* new_addr;
+
+  if (!new_size) new_size = (size_t)1;
+  if (addr != NULL)
+  {
+    __omTypeReallocAlignedSize(addr, old_size, void* , new_addr, new_size);
+  }
+  else
+  {
+    __omTypeAllocAligned(void* , new_addr, new_size);
+  }
+  return new_addr;
+}
+
+OM_INLINE_IMPL void* _omrealloc0Size(void* addr, size_t old_size, size_t new_size)
+{
+  void* new_addr;
+
+  if (!new_size) new_size = (size_t)1;
+  if (addr != NULL && old_size > ((size_t)0))
+  {
+    __omTypeRealloc0AlignedSize(addr, old_size, void* , new_addr, new_size);
+  }
+  else
+  {
+    __omTypeAlloc0(void* , new_addr, new_size);
+  }
+  return new_addr;
+}
+
+OM_INLINE_IMPL void* _omrealloc(void* addr, size_t size)
+{
+  void* new_addr;
+
+  if (!size) size = (size_t)1;
+  if (addr != NULL)
+  {
+    __omTypeReallocAligned(addr, void* , new_addr, size);
+  }
+  else
+  {
+    __omTypeAlloc(void* , new_addr, size);
+  }
+  return new_addr;
+}
+
+OM_INLINE_IMPL void* _omrealloc0(void* addr, size_t size)
+{
+  void* new_addr;
+
+  if (!size) size = (size_t)1;
+  if (addr != NULL)
+  {
+    __omTypeRealloc0Aligned(addr, void* , new_addr, size);
+  }
+  else
+  {
+    __omTypeAlloc0(void* , new_addr, size);
+  }
+  return new_addr;
+}
+#endif /* OM_INLINE_H */
+
+#endif /* defined(OM_INLINE) || defined(OM_ALLOC_C) */
diff --git a/omalloc/omInlineDecl.h b/omalloc/omInlineDecl.h
new file mode 100644
index 0000000..e2c8c9b
--- /dev/null
+++ b/omalloc/omInlineDecl.h
@@ -0,0 +1,46 @@
+/*******************************************************************
+ *  File:    omInlineDecl.h
+ *  Purpose: declarations of omalloc functions which could
+ *           be inlined
+ *  Author:  obachman at mathematik.uni-kl.de (Olaf Bachmann)
+ *  Created: 11/99
+ *******************************************************************/
+#ifndef OM_INLINE_DECL_H
+#define OM_INLINE_DECL_H
+
+OM_INLINE_DECL omBin omGetBinOfPage(omBinPage page);
+OM_INLINE_DECL int _omIsBinPageAddr(const void* addr);
+
+OM_INLINE_DECL void* _omAllocBin(omBin bin);
+OM_INLINE_DECL void* _omAlloc0Bin(omBin bin);
+OM_INLINE_DECL void* _omReallocBin(void* addr, omBin old_bin, omBin new_bin);
+OM_INLINE_DECL void* _omRealloc0Bin(void* addr, omBin old_bin, omBin new_bin);
+
+OM_INLINE_DECL void* _omAlloc(size_t size);
+OM_INLINE_DECL void* _omAlloc0(size_t size);
+OM_INLINE_DECL void* _omReallocSize(void* addr, size_t old_size, size_t new_size);
+OM_INLINE_DECL void* _omRealloc0Size(void* addr, size_t old_size, size_t new_size);
+OM_INLINE_DECL void* _omRealloc(void* addr, size_t size);
+OM_INLINE_DECL void* _omRealloc0(void* addr, size_t size);
+
+OM_INLINE_DECL void* _omalloc(size_t size);
+OM_INLINE_DECL void* _omalloc0(size_t size);
+OM_INLINE_DECL void* _omreallocSize(void* addr, size_t old_size, size_t new_size);
+OM_INLINE_DECL void* _omrealloc0Size(void* addr, size_t old_size, size_t new_size);
+OM_INLINE_DECL void* _omrealloc(void* addr, size_t size);
+OM_INLINE_DECL void* _omrealloc0(void* addr, size_t size);
+
+OM_INLINE_DECL char* _omStrDup(const char* s);
+OM_INLINE_DECL void* _omMemDup(void* addr);
+
+#ifdef OM_ALIGNMENT_NEEDS_WORK
+OM_INLINE_DECL void* _omAllocAligned(size_t size);
+OM_INLINE_DECL void* _omAlloc0Aligned(size_t size);
+OM_INLINE_DECL void* _omReallocAlignedSize(void* addr, size_t old_size, size_t new_size);
+OM_INLINE_DECL void* _omRealloc0AlignedSize(void* addr, size_t old_size, size_t new_size);
+OM_INLINE_DECL void* _omReallocAligned(void* addr, size_t size);
+OM_INLINE_DECL void* _omRealloc0Aligned(void* addr, size_t size);
+OM_INLINE_DECL void* _omMemDupAligned(void* addr);
+#endif
+
+#endif /* OM_INLINE_DECL_H */
diff --git a/omalloc/omList.c b/omalloc/omList.c
new file mode 100644
index 0000000..b6e83ce
--- /dev/null
+++ b/omalloc/omList.c
@@ -0,0 +1,259 @@
+/*******************************************************************
+ *  File:    omList.c
+ *  Purpose: implementation of routines for operations on linked lists
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 11/99
+ *******************************************************************/
+#include "omConfig.h"
+
+#ifndef NULL
+#define NULL ((void*) 0)
+#endif
+
+#define _VALUE(list, offset) *((void**) ((char *)list + offset))
+#define VALUE(list, offset) (unsigned long) _VALUE(list, offset)
+#define NEXT(list) _VALUE(list, next)
+#define ITER(list) list = NEXT(list)
+
+int _omListLength(void* list, int next)
+{
+  int l = 0;
+  while (list != NULL)
+  {
+    l++;
+    ITER(list);
+  }
+  return l;
+}
+
+
+void* _omListLast(void* list, int next)
+{
+  if (list == NULL) return NULL;
+
+  while (NEXT(list) != NULL) ITER(list);
+
+  return list;
+}
+
+
+void* _omListHasCycle(void* list, int next)
+{
+  void* l1 = list;
+  void* l2;
+
+  int l = 0, i;
+
+  while (l1 != NULL)
+  {
+    i = 0;
+    l2 = list;
+    while (l1 != l2)
+    {
+      i++;
+      ITER(l2);
+    }
+    if (i != l) return l1;
+    ITER(l1);
+    l++;
+  }
+  return NULL;
+}
+
+
+void* _omIsOnList(void* list, int next, void* addr)
+{
+  if (addr == NULL)
+    return (NULL);
+
+  while (list != NULL)
+  {
+    if (addr == list) return addr;
+    ITER(list);
+  }
+  return 0;
+}
+
+void* _omRemoveFromList(void* list, int next, void* addr)
+{
+  void* nlist;
+  void* olist;
+
+  if (list == NULL) return NULL;
+
+  nlist = NEXT(list);
+  if (list == addr) return nlist;
+
+  olist = list;
+  while (nlist != NULL && nlist != addr)
+  {
+    list = nlist;
+    ITER(nlist);
+  }
+
+  if (nlist != NULL) NEXT(list) = NEXT(nlist);
+  return olist;
+}
+
+void* _omFindInList(void* list, int next, int long_field, unsigned long what)
+{
+  while (list != NULL)
+  {
+    if (VALUE(list, long_field) == what) return list;
+    ITER(list);
+  }
+  return NULL;
+}
+
+void* _omFindInSortedList(void* list, int next, int long_field,
+                          unsigned long what)
+{
+  while (list != NULL)
+  {
+    if (VALUE(list, long_field) >= what)
+    {
+      if (VALUE(list, long_field) == what) return list;
+      return NULL;
+    }
+    ITER(list);
+  }
+  return NULL;
+}
+
+void* _omRemoveFromSortedList(void* list, int next, int long_field, void* addr)
+{
+  void* nlist;
+  void* olist;
+  unsigned long what = VALUE(addr, long_field);
+
+  if (list == NULL) return NULL;
+  nlist = NEXT(list);
+  if (list == addr) return nlist;
+  if (VALUE(list, long_field) > what) return list;
+
+  olist = list;
+  while (nlist != NULL && nlist != addr)
+  {
+    if (VALUE(list, long_field) > what) return olist;
+    list = nlist;
+    ITER(nlist);
+  }
+
+  if (nlist != NULL) NEXT(list) = NEXT(nlist);
+  return olist;
+}
+
+void* _omInsertInSortedList(void* list, int next, int long_field, void* addr)
+{
+  unsigned long what = VALUE(addr, long_field);
+
+  if (list == NULL || what <= VALUE(list, long_field))
+  {
+    NEXT(addr) = list;
+    return addr;
+  }
+  else
+  {
+    void* prev = list;
+    void* curr = NEXT(list);
+
+    while (curr != NULL && VALUE(curr, long_field) < what)
+    {
+      prev = curr;
+      ITER(curr);
+    }
+    NEXT(prev) = addr;
+    NEXT(addr) = curr;
+    return list;
+  }
+}
+
+
+#ifndef OM_NDEBUG
+#include "omalloc.h"
+#include "omDebug.h"
+
+omError_t _omCheckList(void* list, int next, int level, omError_t report, OM_FLR_DECL)
+{
+  if (level < 1) return omError_NoError;
+
+  if (level == 1)
+  {
+    while (list != NULL)
+    {
+      omCheckReturn(omCheckPtr(list, report, OM_FLR_VAL));
+      ITER(list);
+    }
+  }
+  else
+  {
+    void* l1 = list;
+    void* l2;
+    int l = 0, i;
+
+    l1 = list;
+    while (l1 != NULL)
+    {
+      omCheckReturn(omCheckPtr(l1, report, OM_FLR_VAL));
+      i = 0;
+      l2 = list;
+      while (l1 != l2)
+      {
+        i++;
+        ITER(l2);
+      }
+      if (i != l)
+        return omReportError(omError_ListCycleError, report, OM_FLR_VAL, "");
+      ITER(l1);
+      l++;
+    }
+  }
+  return omError_NoError;
+}
+
+omError_t _omCheckSortedList(void* list, int next, int long_field, int level, omError_t report, OM_FLR_DECL)
+{
+  void* prev = NULL;
+
+  if (level <= 1) return omError_NoError;
+
+  if (level == 1)
+  {
+    while (list != NULL)
+    {
+      omCheckReturn(omCheckPtr(list, report, OM_FLR_VAL));
+      if (prev != NULL && VALUE(prev, long_field) > VALUE(list, long_field))
+        return omReportError(omError_SortedListError, report, OM_FLR_VAL,
+                             "%d > %d", VALUE(prev, long_field), VALUE(list, long_field));
+      prev = list;
+      ITER(list);
+    }
+  }
+  else
+  {
+    void* l1 = list;
+    void* l2;
+    int l = 0, i;
+
+    while (l1 != NULL)
+    {
+      omCheckReturn(omCheckPtr(l1, report, OM_FLR_VAL));
+      if (prev != NULL && VALUE(prev, long_field) > VALUE(l1, long_field))
+        return omReportError(omError_SortedListError, report, OM_FLR_VAL,
+                             "%d > %d", VALUE(prev, long_field), VALUE(l1, long_field));
+      i = 0;
+      l2 = list;
+      while (l1 != l2)
+      {
+        i++;
+        ITER(l2);
+      }
+      omCheckReturnError(i != l, omError_ListCycleError);
+      prev = l1;
+      ITER(l1);
+      l++;
+    }
+  }
+  return omError_NoError;
+}
+#endif
diff --git a/omalloc/omList.h b/omalloc/omList.h
new file mode 100644
index 0000000..7805348
--- /dev/null
+++ b/omalloc/omList.h
@@ -0,0 +1,123 @@
+/*******************************************************************
+ *  File:    omList.h
+ *  Purpose: declaration of routines for operations on linked lists
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 11/99
+ *******************************************************************/
+
+#ifndef OM_LIST_H
+#define OM_LIST_H
+
+#define OM_LIST_OFFSET(ptr, name_of_offset_field) \
+  (ptr != NULL ? ((char*) &(ptr->name_of_offset_field)) - ((char*) ptr) : 0)
+
+/********************************************************************
+ *
+ * Primitve routines -- don't use directly, use om macros, instead
+ *
+ ********************************************************************/
+/* Returns the length of a memory list; assumes list has no cycles */
+int _omListLength(void* list, int next);
+/* Returns last non-NULL element of list; assumes list has no cycles */
+void* _omListLast(void* list, int next);
+/* Checks whether memory list has cycles: If yes, returns address of
+ * first element of list which is contained at least twice in memory
+ * list. If no, NULL is returned */
+void* _omListHasCycle(void* list, int next);
+/* returns addr, if addr is contained in memory list
+ * 0, otherwise */
+void* _omIsOnList(void* list, int next, void* addr);
+/* Removes addr from list, if contained in it and returns new list */
+void* _omRemoveFromList(void* list, int next, void* addr);
+/*
+ * The following cast list->long_field to a pointer to  unsigned long
+ */
+/* Find element with that value in list and return it, if found (else NULL) */
+void* _omFindInList(void* list, int next, int long_field,
+                    unsigned long what);
+/*
+ * The following assume that list is ordered increasingly w.r.t. long_field
+ */
+/* Finds element in sorted list */
+void* _omFindInSortedList(void* list, int next, int long_field,
+                          unsigned long what);
+/* Remove element with that value from list and return new list */
+void* _omRemoveFromSortedList(void* list,int next,int long_field,
+                                  void* addr);
+/* Inserts addr at the right place, returns list assumes addr != NULL */
+void* _omInsertInSortedList(void* list, int next, int long_field,
+                            void* addr);
+#ifndef OM_NDEBUG
+/* Check whether list is ok, i.e. whether addr of lists are aligned and in valid range */
+omError_t _omCheckList(void* list, int next, int level, omError_t report, OM_FLR_DECL);
+/* like above, but also check that sorting is ok */
+omError_t _omCheckSortedList(void* list, int next, int long_field, int level, omError_t report, OM_FLR_DECL);
+#endif
+
+/********************************************************************
+ *
+ * The following routines assume that Next(list) == *((void**) list)
+ *
+ ********************************************************************/
+#define omListLength(ptr) \
+  _omListLength(ptr, 0)
+#define omListLast(ptr) \
+  _omListLast(ptr, 0)
+#define omListHasCycle(ptr) \
+  _omListHasCycle(ptr, 0)
+#define omIsOnList(ptr, addr) \
+  _omIsOnList(ptr, 0, addr)
+#define omRemoveFromList(ptr, addr) \
+  _omRemoveFromList(ptr, 0, addr)
+#define omFindInList(ptr, what, value) \
+  _omFindInList(ptr, 0, OM_LIST_OFFSET(ptr, what), (unsigned long) value)
+#define omInsertInSortedList(ptr, what, addr) \
+  _omInsertInSortedList(ptr, 0, OM_LIST_OFFSET(ptr, what), addr)
+#define omFindInSortedList(ptr, what, value) \
+  _omFindInSortedList(ptr, 0, OM_LIST_OFFSET(ptr, what), value)
+#define omRemoveFromSortedList(ptr, what, addr) \
+  _omRemoveFromSortedList(ptr, 0, OM_LIST_OFFSET(ptr, what), addr)
+#ifndef OM_NDEBUG
+#define omTestList(ptr, level) \
+  _omCheckList(ptr, 0, level, omError_NoError, OM_FLR)
+#define omCheckList(ptr, level, report, OM_FLR_VAL) \
+  _omCheckList(ptr, 0, level, report, OM_FLR_VAL)
+#define omCheckSortedList(ptr, what, level, report, OM_FLR_VAL) \
+  _omCheckSortedList(ptr, 0, OM_LIST_OFFSET(ptr, what), level, report, OM_FLR_VAL)
+#endif
+
+/********************************************************************
+ *
+ * The following routines have name of next field as argument
+ *
+ ********************************************************************/
+#define omGListLength(ptr, next) \
+  _omListLength(ptr, OM_LIST_OFFSET(ptr, next))
+#define omGListLast(ptr, next) \
+  _omListLast(ptr, OM_LIST_OFFSET(ptr, next))
+#define omGListHasCycle(ptr, next) \
+  _omListHasCycle(ptr, OM_LIST_OFFSET(ptr, next))
+#define omIsOnGList(ptr, next, addr) \
+  _omIsOnList(ptr, OM_LIST_OFFSET(ptr, next), addr)
+#define omRemoveFromGList(ptr, next, addr) \
+  _omRemoveFromList(ptr, OM_LIST_OFFSET(ptr, next), addr)
+#define omFindInGList(ptr, next, what, value) \
+  _omFindInList(ptr, OM_LIST_OFFSET(ptr, next), OM_LIST_OFFSET(ptr, what), (unsigned long) value)
+#define omInsertInSortedGList(ptr, next, what, addr) \
+  _omInsertInSortedList(ptr, OM_LIST_OFFSET(ptr, next), OM_LIST_OFFSET(ptr, what), addr)
+#define omFindInSortedGList(ptr, next, what, value) \
+  _omFindInSortedList(ptr, OM_LIST_OFFSET(ptr, next),OM_LIST_OFFSET(ptr,what),value)
+#define omRemoveFromSortedGList(ptr, next, what, addr) \
+  _omRemoveFromSortedList(ptr, OM_LIST_OFFSET(addr,next),OM_LIST_OFFSET(addr,what),addr)
+#ifndef OM_NDEBUG
+#define omTestGList(ptr, next, level) \
+ omCheckGList(ptr, next, level, omError_NoError, OM_FLR)
+#define omCheckGList(ptr, next, level, report, OM_FLR_VAL) \
+ _omCheckList(ptr, OM_LIST_OFFSET(ptr,next), level, report, OM_FLR_VAL)
+#define omCheckSortedGList(ptr, next, what, level, report, OM_FLR_VAL) \
+ _omCheckSortedList(ptr, OM_LIST_OFFSET(ptr,next), OM_LIST_OFFSET(ptr,what), level, report, OM_FLR_VAL)
+#else
+#define omTestGList(ptr, next, val) (omError_NoError)
+#endif
+
+#endif /* OM_LIST_H */
diff --git a/omalloc/omMalloc.h b/omalloc/omMalloc.h
new file mode 100644
index 0000000..0b6fb2a
--- /dev/null
+++ b/omalloc/omMalloc.h
@@ -0,0 +1,33 @@
+/*******************************************************************
+ *  File:    omMallocSystem.h
+ *  Purpose: declaration of macros for malloc to be used from the system
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 11/99
+ *******************************************************************/
+#ifndef OM_MALLOC_H
+#define OM_MALLOC_H
+
+#include "omConfig.h"
+
+#ifdef OMALLOC_USES_SYSTEM_MALLOC
+#include "omalloc/omMallocSystem.h"
+#endif
+
+#ifdef OMALLOC_USES_EXTERNAL_MALLOC
+#include EXTERNAL_MALLOC_HEADER
+#endif
+
+#ifdef OMALLOC_USES_PMALLOC
+#include "omalloc/pmalloc.h"
+#endif
+
+#ifdef OMALLOC_USES_GMALLOC
+#include "omalloc/gmalloc.h"
+#endif
+
+#ifdef OMALLOC_USES_DLMALLOC
+#include "omalloc/dlmalloc.h"
+#endif
+
+#endif /* OM_MALLOC_H */
+
diff --git a/omalloc/omMallocSystem.h b/omalloc/omMallocSystem.h
new file mode 100644
index 0000000..1d68e3c
--- /dev/null
+++ b/omalloc/omMallocSystem.h
@@ -0,0 +1,19 @@
+/*******************************************************************
+ *  File:    omMallocSystem.h
+ *  Purpose: declaration of macros for malloc to be used from the system
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 11/99
+ *******************************************************************/
+#ifndef OM_MALLOC_SYSTEM_H
+#define OM_MALLOC_SYSTEM_H
+
+/* this is the minimal set of OM_MALLOC_* macros which must be defined */
+#define OM_MALLOC_MALLOC   malloc
+#define OM_MALLOC_REALLOC  realloc
+#define OM_MALLOC_FREE     free
+#define OM_MALLOC_VALLOC   valloc
+#define OM_MALLOC_VFREE(addr, size) OM_MALLOC_FREE(addr)
+/* the following will work under Mac OS X */
+#define OM_MALLOC_SIZEOF_ADDR(addr)  (malloc_size(addr))
+
+#endif /* OM_MALLOC_SYSTEM_H */
diff --git a/omalloc/omMemOps.h b/omalloc/omMemOps.h
new file mode 100644
index 0000000..d73f6f5
--- /dev/null
+++ b/omalloc/omMemOps.h
@@ -0,0 +1,177 @@
+/*******************************************************************
+ *  File:    omMemOps.h
+ *  Purpose: low-level Macros for memory operations
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 11/99
+ *******************************************************************/
+
+#ifndef OM_MEM_OPS_H
+#define OM_MEM_OPS_H
+
+#ifdef DO_DEEP_PROFILE
+extern void _omMemcpyW(long* p1, long* p2, long l);
+#define omMemcpy_nwEVEN(p1, p2, l)    _omMemcpyW((long*) p1, (long*) p2, (long) l)
+#define omMemcpy_nwODD(p1, p2, l)     _omMemcpyW((long*) p1, (long*) p2, (long) l)
+#define omMemcpyW(p1, p2, l)          _omMemcpyW((long*) p1, (long*) p2, (long) l)
+
+extern void _omMemaddW(long* p1, long* p2, long* p3, long l);
+#define omMemaddW(p1, p2, p3, l)          _omMemaddW(p1, p2, p3, l)
+#define omMemadd_nwODD(p1, p2, p3, l)     _omMemaddW(p1, p2, p3, l)
+#define omMemadd_nwEVEN(p1, p2, p3, l)    _omMemaddW(p1, p2, p3, l)
+#define omMemadd_nwONE(p1, p2, p3)        _omMemaddW(p1, p2, p3, 1)
+#define omMemadd_nwTWO(p1, p2, p3)        _omMemaddW(p1, p2, p3, 2)
+
+extern void _omMemsetW(long* p1, long w, long l);
+#define omMemsetW(p1, w, l) _omMemsetW(p1, w, l)
+
+#else /* ! DO_DEEP_PROFILE */
+
+#define omMemcpyW(p1, p2, l)                    \
+do                                              \
+{                                               \
+  long _i = l;                                  \
+  long* _s1 = (long*) (p1);                       \
+  const long* _s2 = (long*) (p2);                 \
+                                                \
+  for (;;)                                      \
+  {                                             \
+    *_s1 = *_s2;                                \
+    _i--;                                       \
+    if (_i == 0) break;                         \
+    _s1++;                                      \
+    _s2++;                                      \
+  }                                             \
+}                                               \
+while(0)
+
+#define omMemcpy_nwODD(p1, p2, l)               \
+do                                              \
+{                                               \
+  long _i = (l) - 1;                              \
+  long* _s1 = (long*) (p1);                       \
+  const long* _s2 = (long*) (p2);                 \
+                                                \
+  *_s1++ = *_s2++;                              \
+  for (;;)                                      \
+  {                                             \
+    *_s1++ = *_s2++;                            \
+    *_s1++ = *_s2++;                            \
+    _i -= 2;                                    \
+    if (_i == 0) break;                         \
+  }                                             \
+}                                               \
+while(0)
+
+#define omMemcpy_nwEVEN(p1, p2, l)              \
+do                                              \
+{                                               \
+  long _i = l;                                  \
+  long* _s1 = (long*) (p1);                       \
+  const long* _s2 = (long*) (p2);                 \
+                                                \
+  for (;;)                                      \
+  {                                             \
+    *_s1++ = *_s2++;                            \
+    *_s1++ = *_s2++;                            \
+    _i -= 2;                                    \
+    if (_i == 0) break;                         \
+  }                                             \
+}                                               \
+while(0)
+
+#define omMemaddW(P1, P2, P3, L)                \
+do                                              \
+{                                               \
+  unsigned long* _p1 = P1;                      \
+  const unsigned long* _p2 = P2;                \
+  const unsigned long* _p3 = P3;                \
+  unsigned long l = L;                          \
+                                                \
+  do                                            \
+  {                                             \
+    *_p1++ = *_p2++ + *_p3++;                   \
+    l--;                                        \
+  }                                             \
+  while(l);                                     \
+}                                               \
+while(0)
+
+#define omMemadd_nwODD(P1, P2, P3, L)           \
+do                                              \
+{                                               \
+  unsigned long* _p1 = P1;                      \
+  const unsigned long* _p2 = P2;                \
+  const unsigned long* _p3 = P3;                \
+  unsigned long l = L;                          \
+                                                \
+ *_p1++ = *_p2++ + *_p3++;                      \
+  l--;                                          \
+                                                \
+  do                                            \
+  {                                             \
+     *_p1++ = *_p2++ + *_p3++;                  \
+     *_p1++ = *_p2++ + *_p3++;                  \
+     l -=2;                                     \
+  }                                             \
+  while(l);                                     \
+}                                               \
+while(0)
+
+#define omMemadd_nwEVEN(P1, P2, P3, L)          \
+do                                              \
+{                                               \
+  unsigned long* _p1 = P1;                      \
+  const unsigned long* _p2 = P2;                \
+  const unsigned long* _p3 = P3;                \
+  unsigned long l = L;                          \
+                                                \
+  do                                            \
+  {                                             \
+     *_p1++ = *_p2++ + *_p3++;                  \
+     *_p1++ = *_p2++ + *_p3++;                  \
+     l -=2;                                     \
+  }                                             \
+  while(l);                                     \
+}                                               \
+while(0)
+
+#define omMemadd_nwONE(P1, P2, P3)              \
+do                                              \
+{                                               \
+  unsigned long* _p1 = P1;                      \
+  const unsigned long* _p2 = P2;                \
+  const unsigned long* _p3 = P3;                \
+                                                \
+ *_p1 = *_p2 + *_p3;                            \
+}                                               \
+while(0)
+
+#define omMemadd_nwTWO(P1, P2, P3)              \
+do                                              \
+{                                               \
+  unsigned long* _p1 = P1;                      \
+  const unsigned long* _p2 = P2;                \
+  const unsigned long* _p3 = P3;                \
+                                                \
+ *_p1++ = *_p2++ + *_p3++;                      \
+ *_p1 = *_p2 + *_p3;                            \
+}                                               \
+while(0)
+
+#define omMemsetW(P1, W, L)                     \
+do                                              \
+{                                               \
+  long* _p1 = (long*) (P1);                     \
+  unsigned long _l = L;                         \
+  unsigned long _w = W;                         \
+  while(_l)                                     \
+  {                                             \
+    *_p1++ = _w;                                \
+    _l--;                                       \
+  }                                             \
+}                                               \
+while(0)
+
+#endif /* DO_DEEP_PROFILE */
+
+#endif /* OM_LIST_H */
diff --git a/omalloc/omMmap.c b/omalloc/omMmap.c
new file mode 100644
index 0000000..7d18bc6
--- /dev/null
+++ b/omalloc/omMmap.c
@@ -0,0 +1,46 @@
+/*******************************************************************
+ *  File:    omMmap.c
+ *  Purpose: implementing valloc via mmap
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 11/99
+ *******************************************************************/
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+
+#if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
+#define MAP_ANONYMOUS MAP_ANON
+#endif
+
+static void* omVallocMmap(size_t size)
+{
+  void* addr;
+#ifndef MAP_ANONYMOUS
+  static int fd = -1;
+#endif
+
+#ifdef MAP_ANONYMOUS
+#ifndef __CYGWIN__
+  /* under cygwin, MAP_PRIVATE|MAP_ANONYMOUS fails */
+  addr = mmap(0, size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
+#else
+  /* however, the following works */
+  addr = mmap(0, size, PROT_READ|PROT_WRITE, MAP_PRIVATE, -1, 0);
+#endif
+#else /* !MAP_ANONYMOUS */
+  if (fd < 0)
+  {
+    fd = open("/dev/zero", O_RDWR);
+    if (fd < 0) return NULL;
+  }
+  addr = mmap(0, size, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
+#endif
+
+  if (addr == (void*) -1) return NULL;
+  return addr;
+}
+
+static int omVfreeMmap(void* addr, size_t size)
+{
+  return munmap(addr, size);
+}
diff --git a/omalloc/omOpts.c b/omalloc/omOpts.c
new file mode 100644
index 0000000..40eff65
--- /dev/null
+++ b/omalloc/omOpts.c
@@ -0,0 +1,24 @@
+/*******************************************************************
+ *  File:    omStats.c
+ *  Purpose: definitions of stats related stuff
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 11/99
+ *******************************************************************/
+
+#include "omalloc.h"
+#include "omDefaultConfig.h"
+
+omOpts_t om_Opts =
+{
+  OM_DEFAULT_MIN_TRACK,
+  OM_DEFAULT_MIN_CHECK,
+  OM_DEFAULT_MAX_TRACK,
+  OM_DEFAULT_MAX_CHECK,
+  OM_DEFAULT_KEEP,
+  OM_DEFAULT_HOW_TO_REPORT_ERRORS,
+  OM_DEFAULT_MARK_AS_STATIC,
+  OM_DEFAULT_PAGES_PER_REGION,
+  OM_DEFAULT_OUT_OF_MEMORY_FUNC,
+  OM_DEFAULT_MEMORY_LOW_FUNC,
+  OM_DEFAULT_ERROR_HOOK
+};
diff --git a/omalloc/omOpts.h b/omalloc/omOpts.h
new file mode 100644
index 0000000..488249a
--- /dev/null
+++ b/omalloc/omOpts.h
@@ -0,0 +1,27 @@
+/*******************************************************************
+ *  File:    omOpts.h
+ *  Purpose: declaration of options for omalloc
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 11/99
+ *******************************************************************/
+#ifndef OM_OPTS_H
+#define OM_OPTS_H
+
+/* Default values for these options are defined in omDefaultConfig.h */
+struct omOpts_s
+{
+  int MinTrack;
+  int MinCheck;
+  int MaxTrack;
+  int MaxCheck;
+  int Keep;
+  int HowToReportErrors;
+  int MarkAsStatic;
+  unsigned int PagesPerRegion;
+  void (*OutOfMemoryFunc)();
+  void (*MemoryLowFunc)();
+  void (*ErrorHook)();
+};
+extern omOpts_t om_Opts;
+
+#endif /* OM_OPTS_H */
diff --git a/omalloc/omPage.h b/omalloc/omPage.h
new file mode 100644
index 0000000..54f6f6b
--- /dev/null
+++ b/omalloc/omPage.h
@@ -0,0 +1,122 @@
+/*******************************************************************
+ *  File:    omPage.h
+ *  Purpose: declaration of routines for primitve page managment
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 11/99
+ *******************************************************************/
+#ifndef OM_PAGE_H
+#define OM_PAGE_H
+
+/***********************************************************************
+ *
+ * Identifying whether an address is a BinAddr or LargeAddr:
+ * For this to work, omRegisterBinAddr or omRegisterLargeAddr must be called
+ * with every address gotten from an external malloc  routine
+ */
+
+/* Here is how it works (assume SIZEOF_LONG == 4, SIZEOF_SYSTEM_PAGE = 2^12):
+   Let
+   Addr: |    15               |  5       |    12        |
+          PAGE_INDEX            PAGE_SHIFT PAGE_OFFSET
+
+                                      PAGE_BASE
+
+   omPageIndicies is an array of bit-fields which is indexed by
+                  PAGE_INDEX - omMinPageIndex. Its maximal length
+                  is 2^15. PAGE_SHIFT is used as index into the bit-field.
+                  If it's value is 1, then addr is from omPage, else
+                  not.
+
+   omMinPageIndex is minimal page index of registered addr
+
+   In other words: omIsPageAddr iff
+   omPageIndicies[PAGE_INDEX - omMinPageIndex] & (1 << PAGE_SHIFT) */
+
+
+#define OM_SIZEOF_INDEX_PAGE (SIZEOF_SYSTEM_PAGE << LOG_BIT_SIZEOF_LONG)
+
+#define omGetPageShiftOfAddr(addr) \
+  ((((unsigned long) addr) & (OM_SIZEOF_INDEX_PAGE -1)) >> LOG_BIT_SIZEOF_SYSTEM_PAGE)
+
+#define omGetPageIndexOfAddr(addr) \
+  (((unsigned long) addr) >> (LOG_BIT_SIZEOF_LONG + LOG_BIT_SIZEOF_SYSTEM_PAGE))
+
+#define omIsPageAddr(addr) \
+   ((omPageIndicies[omGetPageIndexOfAddr(addr) - omMinPageIndex] & \
+    (((unsigned long)1) << omGetPageShiftOfAddr(addr))) != 0)
+
+extern void omPageIndexFault(unsigned long page_index);
+extern unsigned long omMaxPageIndex;
+extern unsigned long omMinPageIndex;
+extern unsigned long *omPageIndicies;
+
+#define omRegisterPageIndex(index)                      \
+do                                                      \
+{                                                       \
+  if (index < omMinPageIndex || index > omMaxPageIndex) \
+  {                                                     \
+    omPageIndexFault(index);                            \
+  }                                                     \
+}                                                       \
+while (0)
+
+#define omRegisterExternalAddr(addr)                        \
+do                                                          \
+{                                                           \
+  unsigned long _omPageIndex = omGetPageIndexOfAddr(addr);  \
+  omRegisterPageIndex(_omPageIndex);                        \
+  omPageIndicies[_omPageIndex - omMinPageIndex] &=          \
+    ~ (((unsigned long) 1) << omGetPageShiftOfAddr(addr));  \
+}                                                           \
+while (0)
+
+#define omRegisterPageAddr(addr)                            \
+do                                                          \
+{                                                           \
+  unsigned long _omPageIndex = omGetPageIndexOfAddr(addr);  \
+  omRegisterPageIndex(_omPageIndex);                        \
+  omPageIndicies[_omPageIndex - omMinPageIndex] |=          \
+      (((unsigned long) 1) << omGetPageShiftOfAddr(addr));  \
+}                                                           \
+while (0)
+
+/***********************************************************************
+ *
+ * declarations of procedures
+ */
+
+void* omGetPage();
+
+void omFreePage(void* page);
+
+void omReleaseFreePages();
+
+int omGetNumberOfFreePages();
+int omGetNumberOfUsedPages();
+int omGetNumberOfAllocatedPages();
+
+/***********************************************************************
+ *
+ * Macros for page manipulations
+ */
+
+#define omIsAddrPageAligned(addr) \
+  (((long) (addr) & (SIZEOF_SYSTEM_PAGE -1)) == 0)
+
+#define omGetPageOfAddr(addr) \
+  ((void*) ((long) (addr) & ~(SIZEOF_SYSTEM_PAGE -1)))
+
+#define omGetBinPageOfAddr(addr) \
+  ((omBinPage) ((long) (addr) & ~(SIZEOF_SYSTEM_PAGE -1)))
+
+#define omIsAddrOnPage(addr, page) (omGetPageOfAddr(addr) == (void*) (page))
+
+#define omAreAddrOnSamePage(a1, a2) \
+  (omGetPageOfAddr(a1) == omGetPageOfAddr(a2))
+
+int omIsAddrOnFreePage(void* addr);
+int omIsAddrOnRegisteredPage(void* addr);
+
+#define omIsNotAddrOnFreePage(addr) (!omIsAddrOnFreePage(addr))
+
+#endif /* OM_PAGE_H */
diff --git a/omalloc/omRet2Info.c b/omalloc/omRet2Info.c
new file mode 100644
index 0000000..39d01a7
--- /dev/null
+++ b/omalloc/omRet2Info.c
@@ -0,0 +1,283 @@
+/*******************************************************************
+ *  File:    omRetur2Info.c
+ *  Purpose: translation of return addr to RetInfo
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 11/99
+ *******************************************************************/
+#include <stdio.h>
+#include <string.h>
+
+#ifndef PACKAGE
+#include "omConfig.h"
+#endif
+
+#ifndef OM_NDEBUG
+
+#include "omDerivedConfig.h"
+#include "omStructs.h"
+#include "omRet2Info.h"
+#include "omGetBackTrace.h"
+
+#ifndef MAXPATHLEN
+#define MAXPATHLEN 1024
+#endif
+
+/* define to also print return addresses in (default)
+   output of omPrintInfo */
+/* #define OM_PRINT_RETURN_ADDRESS */
+static char om_this_prog[MAXPATHLEN] = "";
+
+#ifndef OM_MAX_BACKTRACE_DEPTH
+#define OM_MAX_BACKTRACE_DEPTH 16
+#endif
+
+void omInitRet_2_Info(const char* argv0)
+{
+//  char buf[MAXPATHLEN];
+
+  if (argv0 != NULL) // // && omFindExec(argv0, buf))
+  {
+    strncpy(om_this_prog, argv0, MAXPATHLEN); // // buf);
+    om_this_prog[MAXPATHLEN - 1]= '\0';
+  }
+}
+
+
+int omBackTrace_2_RetInfo(void** bt, omRetInfo info, int max)
+{
+  int i=0, j=0, filled = 0;
+  if (max <= 0 || bt == NULL || info == NULL) return 0;
+  if (max > OM_MAX_BACKTRACE_DEPTH) max = OM_MAX_BACKTRACE_DEPTH;
+  memset(info, 0, max*sizeof(omRetInfo_t));
+  while (i<max)
+  {
+    if (bt[i])
+    {
+      info[j].addr = bt[i];
+      j++;
+    }
+    i++;
+  }
+  if (j == 0) return 0;
+
+#if defined(HAVE_POPEN) && defined(OM_PROG_ADDR2LINE)
+  if (*om_this_prog != '\0')
+  {
+    char command[2*MAXPATHLEN + 15 + OM_MAX_BACKTRACE_DEPTH*(2*SIZEOF_VOIDP + 4)];
+    FILE *pipe;
+    int l;
+    l = sprintf(command, "%s -s -C -f -e %s",
+                OM_PROG_ADDR2LINE, om_this_prog);
+    i=0;
+    while (i<j)
+    {
+      l+=sprintf(&command[l], " %p", info[i].addr);
+      i++;
+    }
+    fflush(NULL);
+    pipe = popen(command, "r");
+    if (pipe != NULL)
+    {
+        /* An output entry of addr2line looks as follows:
+FunctionName
+File:Line
+        */
+      while ((filled < j) &&
+             (fscanf(pipe, "%200[^\n]\n%200[^:]:%d\n", info[filled].func, info[filled].file, &(info[filled].line)) == 3))
+      {
+        if (*info[filled].func != '?' && *info[filled].file != '?' && info[filled].line > 0)
+          filled++;
+      }
+      pclose(pipe);
+    }
+    return filled;
+  }
+#endif
+  return j;
+}
+
+int omPrintRetInfo(omRetInfo info, int max, FILE* fd, const char* fmt)
+{
+  int i = 0;
+  if (max <= 0 || info == NULL || fmt == NULL || fd == NULL) return 0;
+  while (i < max && info[i].addr != NULL)
+  {
+    int l = 0;
+    while (fmt[l] != 0)
+    {
+      if (fmt[l] == '%')
+      {
+        l++;
+        if (fmt[l] == 'p') fprintf(fd, "%p", info[i].addr);
+        else if (fmt[l] == 'f') fprintf(fd, "%-20s", (*info[i].file != '\0' ? info[i].file : "??"));
+        else if (fmt[l] == 'F') fprintf(fd, "%-20s", (*info[i].func != '\0' ? info[i].func : "??"));
+        else if (fmt[l] == 'l') fprintf(fd, "%d", info[i].line);
+        else if (fmt[l] == 'N')
+        {
+          if (*info[i].func != '\0')
+          {
+            char* found = (char*) strchr(info[i].func, '(');
+            if (found) *found = '\0';
+            fprintf(fd, "%-20s", info[i].func);
+            if (found) *found = '(';
+          }
+          else
+            fprintf(fd, "%-20s", "??");
+        }
+        else if (fmt[l] == 'L')
+        {
+          int n = fprintf(fd, "%s:%d", (*info[i].func != '\0' ? info[i].file : "??"), info[i].line);
+          if (n < 20) fprintf(fd, "%*s", 20-n, " ");
+        }
+        else if (fmt[l] == 'i') fprintf(fd, "%d", i);
+        else
+        {
+          fputc('%', fd);
+          l--;
+        }
+      }
+      else
+      {
+        fputc(fmt[l], fd);
+      }
+      l++;
+    }
+    i++;
+  }
+  return i;
+}
+
+int omPrintBackTrace(void** bt, int max, FILE* fd)
+{
+  int i;
+
+  omRetInfo_t info[OM_MAX_BACKTRACE_DEPTH];
+  if (max > OM_MAX_BACKTRACE_DEPTH) max = OM_MAX_BACKTRACE_DEPTH;
+
+  i = omBackTrace_2_RetInfo(bt, info, max);
+#ifdef OM_PRINT_RETURN_ADDRESS
+  return omPrintRetInfo(info, i, fd, "  #%i at %L in %N ra=%p\n");
+#else
+  return omPrintRetInfo(info, i, fd, "  #%i at %L in %N\n");
+#endif
+}
+
+int omPrintCurrentBackTraceMax(FILE* fd, int max)
+{
+  int i;
+  void* bt[OM_MAX_BACKTRACE_DEPTH];
+  if (max > OM_MAX_BACKTRACE_DEPTH)
+    max = OM_MAX_BACKTRACE_DEPTH;
+  if (max <= 0) return 0;
+  i = omGetBackTrace(bt, 1, max);
+  return omPrintBackTrace(bt, i, fd);
+}
+
+/*************************************************************
+ *
+ * Various Filters
+ *
+ *************************************************************/
+int omFilterRetInfo_i(omRetInfo info, int max, int i)
+{
+  int j=0, k=i;
+
+  while (k < max)
+  {
+    info[j] = info[k];
+    j++;
+    k++;
+  }
+  return j;
+}
+
+/*************************************************************
+ *
+ * Low level routines
+ *
+ *************************************************************/
+
+int _omPrintBackTrace(void** bt, int max, FILE* fd , OM_FLR_DECL)
+{
+#ifndef __OPTIMIZE__
+  int i = 0;
+
+  omRetInfo_t info[OM_MAX_BACKTRACE_DEPTH];
+  if (max > OM_MAX_BACKTRACE_DEPTH) max = OM_MAX_BACKTRACE_DEPTH;
+  if (bt != NULL)
+  {
+  for (; i<max; i++)
+  {
+    if (bt[i] == NULL)
+    {
+      max = i+1;
+      break;
+    }
+  }
+  i = omBackTrace_2_RetInfo(bt, info, max);
+  }
+#ifdef OM_TRACK_RETURN
+  if (i == 0)
+    i = omBackTrace_2_RetInfo(((void*)&r),info, 1);
+#endif
+#ifndef OM_INTERNAL_DEBUG
+  if (i > 1)
+  {
+#ifdef OM_TRACK_RETURN
+    if (r != NULL)
+      omFilterRetInfo(info, i, addr_i == r);
+#endif
+#ifdef OM_TRACK_FILE_LINE
+    if (f != NULL && l > 0)
+      omFilterRetInfo(info, i, strcmp(f, file_i) == 0 && l + 2 >= line_i && l - 2 <= line_i);
+#endif
+    /* if we have both, use overwrite what we got from return addressse --
+       they sometimes are wrong */
+#if defined(OM_TRACK_RETURN) && defined(OM_TRACK_FILE_LINE)
+    if (r != NULL && info[0].addr == r && l > 0 && f != 0)
+    {
+      strcpy(info[0].file, f);
+      info[0].line = l;
+    }
+#endif
+  }
+  if (i == 0)
+  {
+#endif /* ! OM_INTERNAL_DEBUG */
+
+#ifdef OM_TRACK_FILE_LINE
+    fprintf(fd, " %s:%d", f, l);
+#endif
+#ifdef OM_TRACK_RETURN
+    fprintf(fd," ra=%p", r);
+#endif
+
+#ifndef OM_INTERNAL_DEBUG
+    return 1;
+  }
+  else
+#endif /* ! OM_INTERNAL_DEBUG */
+#ifdef OM_PRINT_RETURN_ADDRESS
+    return omPrintRetInfo(info, i, fd, "\n  #%i at %L in %N ra=%p");
+#else
+    return omPrintRetInfo(info, i, fd, "\n  #%i at %L in %N");
+#endif
+#else
+  return 0;
+#endif
+}
+
+int _omPrintCurrentBackTrace(FILE* fd , OM_FLR_DECL)
+{
+#ifdef __OPTIMIZE__
+  /* does not work without -g */
+  return 0;
+#else
+  int i;
+  void* bt[OM_MAX_BACKTRACE_DEPTH];
+
+  i = omGetBackTrace(bt, 1, OM_MAX_BACKTRACE_DEPTH);
+  return _omPrintBackTrace(bt, i, fd , OM_FLR_VAL);
+#endif
+}
+#endif /* ! OM_NDEBUG */
diff --git a/omalloc/omRet2Info.h b/omalloc/omRet2Info.h
new file mode 100644
index 0000000..f76dc70
--- /dev/null
+++ b/omalloc/omRet2Info.h
@@ -0,0 +1,80 @@
+/*******************************************************************
+ *  File:    omAddr2Info.h
+ *  Purpose: translation of return addr to RetInfo
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 11/99
+ *******************************************************************/
+#ifndef OM_RET_2_INFO_H
+#define OM_RET_2_INFO_H
+
+
+struct omRetInfo_s
+{
+  void* addr;
+  char  func[200]; /* if you change these numbers, alos change */
+  char  file[200]; /* the fscanf statement in BackTrace_2_RetInfo */
+  int   line;
+};
+
+/* print to fd array of max RetInfo's and use fmt as format string for one RetInfo.
+   The following conversions are recognized:
+    %i -- number of return addr
+    %p -- address (in hex)
+    %F -- function name with arguments (for C++, only)
+    %N -- funtion name without arguments
+    %f -- file
+    %l -- line
+    %L -- file:line
+   return how many lines were printed */
+#ifndef OM_NDEBUG
+int omPrintRetInfo(omRetInfo info, int max, FILE *fd, const char* fmt);
+/* translate array of max BackTrace addresses into array of max RetInfos
+   return how many were translated */
+int omBackTrace_2_RetInfo(void** bt, omRetInfo info, int max);
+
+/* call with argv[0] to enable RetInfo translations */
+void omInitRet_2_Info(const char* argv0);
+
+int omPrintBackTrace(void** bt, int max, FILE* fd);
+#define omPrintCurrentBackTrace(fd) omPrintCurrentBackTraceMax(fd, 1000)
+int omPrintCurrentBackTraceMax(FILE* fd, int max);
+
+int omFilterRetInfo_i(omRetInfo info, int max, int i);
+
+#define omFilterRetInfo(info, max, cond)        \
+do                                              \
+{                                               \
+  int _max = max;                               \
+  int _i = max -1;                              \
+  while (_i > 0)                                \
+  {                                             \
+    void* addr_i = info[_i].addr;               \
+    char* file_i = info[_i].file;               \
+    char* func_i = info[_i].func;               \
+    int   line_i = info[_i].line;               \
+                                                \
+    if (cond)                                   \
+      max = omFilterRetInfo_i(info, max, _i);   \
+    _i--;                                       \
+  }                                             \
+}                                               \
+while (0)
+
+
+/*BEGINPRIVATE*/
+int _omPrintBackTrace(void** bt, int max, FILE* fd , OM_FLR_DECL);
+int _omPrintCurrentBackTrace(FILE* fd , OM_FLR_DECL);
+/*ENDPRIVATE*/
+
+#else /* OM_NDEBUG */
+#define omPrintRetInfo(i, max, fd, fmt) do {} while (0)
+#define omBackTrace_2_RetInfo(bt, i, m) do {} while (0)
+#define omInitRet_2_Info(a)             do {} while (0)
+#define omPrintBackTrace(bt,max,fd)     do {} while (0)
+#define omPrintCurrentBackTrace(fd)     do {} while (0)
+#define omPrintCurrentBackTraceMax(fd,max) do {} while (0)
+#define omFilterRetInfo_i(info,max,i)   do {} while (0)
+#define omFilterRetInfo(info, max, cond)do {} while (0)
+#endif /* ! OM_NDEBUG */
+
+#endif /* OM_RET_2_INFO_H */
diff --git a/omalloc/omReturn.h b/omalloc/omReturn.h
new file mode 100644
index 0000000..54501d3
--- /dev/null
+++ b/omalloc/omReturn.h
@@ -0,0 +1,60 @@
+/* slightly changed for use by omalloc.h */
+/*
+ * defines to get the return-address for non-dmalloc_lp malloc calls.
+ *
+ * Copyright 2000 by Gray Watson
+ *
+ * This file is part of the dmalloc package.
+ *
+ * Permission to use, copy, modify, and distribute this software for
+ * any purpose and without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies, and that the name of Gray Watson not be used in advertising
+ * or publicity pertaining to distribution of the document or software
+ * without specific, written prior permission.
+ *
+ * Gray Watson makes no representations about the suitability of the
+ * software described herein for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * The author may be contacted via http://dmalloc.com/
+ *
+ */
+
+/*
+ * This file contains the definition of the GET_RET_ADDR macro which
+ * is designed to contain the archecture/compiler specific hacks to
+ * determine the return-address from inside the malloc library.  With
+ * this information, the library can display caller information from
+ * calls that do not use the malloc_lp functions.
+ *
+ * Most of the archectures here have been contributed by other
+ * individuals and may need to be toggled a bit to remove local
+ * configuration differences.
+ *
+ * PLEASE send all submissions, comments, problems to the author.
+ *
+ * NOTE: examining the assembly code for x =
+ * __builtin_return_address(0); with gcc version 2+ should give you a
+ * good start on building a hack for your box.
+ *
+ * NOTE: the hacks mentioned above were removed in favor of the GCC macro
+ * __builtin_return_address(). Assumptions made in these hacks break for
+ * recent GCC versions.
+ */
+
+#ifndef __OM_RETURN_H__
+#define __OM_RETURN_H__
+
+
+/********************************** default **********************************/
+#ifndef GET_RET_ADDR
+
+#if __GNUC__ > 1
+#define GET_RET_ADDR(file) (file = __builtin_return_address(0))
+#else
+#define GET_RET_ADDR(file)	(file = 0)
+#endif
+#endif /* __GNUC__ > 1 */
+
+#endif /* ! __OM_RETURN_H__ */
diff --git a/omalloc/omStats.c b/omalloc/omStats.c
new file mode 100644
index 0000000..969f0f6
--- /dev/null
+++ b/omalloc/omStats.c
@@ -0,0 +1,143 @@
+/*******************************************************************
+ *  File:    omStats.c
+ *  Purpose: definitions of stats related stuff
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 11/99
+ *******************************************************************/
+#include <unistd.h>
+#include "omConfig.h"
+#include "omDefaultConfig.h"
+#include "omMalloc.h"
+#include "omalloc.h"
+
+omInfo_t om_Info = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+
+unsigned long om_SbrkInit = 0;
+
+void omInitInfo()
+{
+#ifdef HAVE_SBRK
+  om_SbrkInit = (unsigned long) sbrk(0);
+#endif
+}
+
+void omUpdateInfo()
+{
+#ifdef OM_MALLOC_UPDATE_INFO
+  OM_MALLOC_UPDATE_INFO;
+#endif
+
+  /* this can happen, since sizes are added as requested, and
+     subtracted as the real size of the memory */
+  if (om_Info.CurrentBytesFromMalloc < 0)
+    om_Info.CurrentBytesFromMalloc = 0;
+
+  om_Info.UsedBytesFromValloc = omGetUsedBinBytes();
+  om_Info.AvailBytesFromValloc = om_Info.CurrentBytesFromValloc - om_Info.UsedBytesFromValloc;
+
+#ifdef OM_MALLOC_USED_BYTES
+  om_Info.UsedBytesMalloc = OM_MALLOC_USED_BYTES;
+#else
+  om_Info.UsedBytesMalloc = om_Info.CurrentBytesFromMalloc;
+#endif
+#ifdef OM_MALLOC_AVAIL_BYTES
+  om_Info.AvailBytesMalloc = OM_MALLOC_AVAIL_BYTES;
+#endif
+
+  om_Info.UsedBytes = om_Info.UsedBytesMalloc + om_Info.UsedBytesFromValloc;
+  om_Info.AvailBytes = om_Info.AvailBytesMalloc + om_Info.AvailBytesFromValloc;
+
+#ifdef OM_HAVE_VALLOC_MMAP
+  om_Info.CurrentBytesMmap = om_Info.CurrentBytesFromValloc;
+  om_Info.MaxBytesMmap = om_Info.MaxBytesFromValloc;
+#endif
+#ifdef OM_MALLOC_CURRENT_BYTES_MMAP
+  om_Info.CurrentBytesMmap += OM_MALLOC_CURRENT_BYTES_MMAP;
+#endif
+#ifdef OM_MALLOC_MAX_BYTES_MMAP
+  om_Info.MaxBytesMmap += OM_MALLOC_MAX_BYTES_MMAP;
+#endif
+
+#ifndef OM_MALLOC_CURRENT_BYTES_SBRK
+#ifdef HAVE_SBRK
+  if (om_SbrkInit)
+  {
+    om_Info.CurrentBytesSbrk = (unsigned long) sbrk(0) - om_SbrkInit;
+    if (om_Info.CurrentBytesSbrk > om_Info.MaxBytesSbrk)
+      om_Info.MaxBytesSbrk = om_Info.CurrentBytesSbrk;
+  }
+  else
+  {
+    om_SbrkInit = (unsigned long) sbrk(0);
+  }
+#endif
+#else
+  om_Info.CurrentBytesSbrk = OM_MALLOC_CURRENT_BYTES_SBRK;
+#ifdef OM_MALLOC_MAX_BYTES_SBRK
+  om_Info.MaxBytesSbrk = OM_MALLOC_MAX_BYTES_SBRK;
+#else
+    if (om_Info.CurrentBytesSbrk > om_Info.MaxBytesSbrk)
+      om_Info.MaxBytesSbrk = om_Info.CurrentBytesSbrk;
+#endif
+#endif
+
+#ifdef OM_MALLOC_CURRENT_BYTES_SYSTEM
+  om_Info.CurrentBytesSystem = OM_MALLOC_CURRENT_BYTES_SYSTEM;
+#else
+  om_Info.CurrentBytesSystem =
+    (om_Info.CurrentBytesSbrk > om_Info.UsedBytesMalloc ?
+     om_Info.CurrentBytesSbrk : om_Info.UsedBytesMalloc);
+#endif
+#ifdef OM_HAVE_VALLOC_MMAP
+  om_Info.CurrentBytesSystem += om_Info.CurrentBytesFromValloc;
+#endif
+
+#if ! (defined(OM_HAVE_VALLOC_MMAP) && defined(OM_MALLOC_MAX_BYTES_SYSTEM))
+#ifdef OM_MALLOC_MAX_BYTES_SYSTEM
+  om_Info.MaxBytesSystem = OM_MALLOC_MAX_BYTES_SYSTEM;
+#else
+  om_Info.MaxBytesSystem =
+    (om_Info.MaxBytesSbrk + om_Info.MaxBytesMmap >
+     om_Info.MaxBytesFromMalloc + om_Info.MaxBytesFromValloc ?
+     om_Info.MaxBytesSbrk + om_Info.MaxBytesMmap :
+     om_Info.MaxBytesFromMalloc + om_Info.MaxBytesFromValloc);
+#endif
+#endif
+}
+
+omInfo_t omGetInfo()
+{
+  omUpdateInfo();
+  return om_Info;
+}
+
+void omPrintStats(FILE* fd)
+{
+  omUpdateInfo();
+  fprintf(fd, "System %ldk:%ldk Appl %ldk/%ldk Malloc %ldk/%ldk Valloc %ldk/%ldk Pages %ld/%ld Regions %ld:%ld\n",
+          om_Info.CurrentBytesSystem/1024, om_Info.MaxBytesSystem/1024,
+          om_Info.UsedBytes/1024, om_Info.AvailBytes/1024,
+          om_Info.UsedBytesMalloc/1024, om_Info.AvailBytesMalloc/1024,
+          om_Info.CurrentBytesFromValloc/1024, om_Info.AvailBytesFromValloc/1024,
+          om_Info.UsedPages, om_Info.AvailPages,
+          om_Info.CurrentRegionsAlloc, om_Info.MaxRegionsAlloc);
+}
+
+
+void omPrintInfo(FILE* fd)
+{
+  omUpdateInfo();
+  fprintf(fd, "                  Current:       Max:\n");
+  fprintf(fd, "BytesSystem:     %8ldk  %8ldk\n", om_Info.CurrentBytesSystem/1024, om_Info.MaxBytesSystem/1024);
+  fprintf(fd, "BytesSbrk:       %8ldk  %8ldk\n", om_Info.CurrentBytesSbrk/1024, om_Info.MaxBytesSbrk/1024);
+  fprintf(fd, "BytesMmap:       %8ldk  %8ldk\n", om_Info.CurrentBytesMmap/1024, om_Info.MaxBytesMmap/1024);
+  fprintf(fd, "BytesFromMalloc: %8ldk  %8ldk\n", om_Info.CurrentBytesFromMalloc/1024, om_Info.MaxBytesFromMalloc/1024);
+  fprintf(fd, "BytesFromValloc: %8ldk  %8ldk\n", om_Info.CurrentBytesFromValloc/1024, om_Info.MaxBytesFromValloc/1024);
+  fprintf(fd, "PagesAlloc:      %8ld   %8ld \n", om_Info.UsedPages, om_Info.MaxPages);
+  fprintf(fd, "RegionsAlloc:    %8ld   %8ld \n", om_Info.CurrentRegionsAlloc, om_Info.MaxRegionsAlloc);
+  fprintf(fd, "                     Used:     Avail:\n");
+  fprintf(fd, "BytesAppl:       %8ldk  %8ldk\n", om_Info.UsedBytes/1024, om_Info.AvailBytes/1024);
+  fprintf(fd, "BytesMalloc:     %8ldk  %8ldk\n", om_Info.UsedBytesMalloc/1024, om_Info.AvailBytesMalloc/1024);
+  fprintf(fd, "BytesValloc:     %8ldk  %8ldk\n", om_Info.UsedBytesFromValloc/1024, om_Info.AvailBytesFromValloc/1024);
+  fprintf(fd, "Pages:           %8ld   %8ld\n", om_Info.UsedPages, om_Info.AvailPages);
+}
diff --git a/omalloc/omStats.h b/omalloc/omStats.h
new file mode 100644
index 0000000..41ac339
--- /dev/null
+++ b/omalloc/omStats.h
@@ -0,0 +1,51 @@
+/*******************************************************************
+ *  File:    omStats.h
+ *  Purpose: declaration of statistics related stuff
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 11/99
+ *******************************************************************/
+#ifndef OM_STATS_H
+#define OM_STATS_H
+
+struct omInfo_s
+{
+  long MaxBytesSystem;      /* set in omUpdateInfo(), is more accurate with malloc support   */
+  long CurrentBytesSystem;  /* set in omUpdateInfo(), is more accurate with malloc support */
+  long MaxBytesSbrk;        /* always up-to-date, not very accurate, needs omInintInfo() */
+  long CurrentBytesSbrk;    /* set in omUpdateInfo(), needs omInintInfo() */
+  long MaxBytesMmap;        /* set in omUpdateInfo(), not very accurate */
+  long CurrentBytesMmap;    /* set in omUpdateInfo(), not very accurate */
+  long UsedBytes;           /* set in omUpdateInfo() */
+  long AvailBytes;          /* set in omUpdateInfo() */
+  long UsedBytesMalloc;     /* set in omUpdateInfo(), needs malloc support */
+  long AvailBytesMalloc;    /* set in omUpdateInfo(), needs malloc support */
+  long MaxBytesFromMalloc;      /* always kept up-to-date */
+  long CurrentBytesFromMalloc;  /* always kept up-to-date */
+  long MaxBytesFromValloc;      /* always kept up-to-date */
+  long CurrentBytesFromValloc;  /* always kept up-to-date */
+  long UsedBytesFromValloc; /* set in omUpdateInfo()  */
+  long AvailBytesFromValloc;/* set in omUpdateInfo()  */
+  long MaxPages;            /* always kept up-to-date */
+  long UsedPages;           /* always kept up-to-date */
+  long AvailPages;          /* always kept up-to-date */
+  long MaxRegionsAlloc;     /* always kept up-to-date */
+  long CurrentRegionsAlloc; /* always kept up-to-date */
+};
+
+/* returns a copy of omallinfo struct */
+extern struct omInfo_s omGetInfo();
+/* the struct itself which is always up-to-date */
+/* use read-only */
+extern struct omInfo_s om_Info;
+/* update the global info struct */
+extern void omUpdateInfo();
+/* initialize such that sbrk can be measured */
+extern void omInitInfo();
+extern void omPrintStats(FILE* fd);
+extern void omPrintInfo(FILE* fd);
+
+/*BEGINPRIVATE*/
+/* used internally to keep track of sbrk */
+extern unsigned long om_SbrkInit;
+/*ENDPRIVATE*/
+#endif /* OM_STATS_H */
diff --git a/omalloc/omStructs.h b/omalloc/omStructs.h
new file mode 100644
index 0000000..545f21c
--- /dev/null
+++ b/omalloc/omStructs.h
@@ -0,0 +1,36 @@
+/*******************************************************************
+ *  File:    omStructs.h
+ *  Purpose: declaration of structs and typedefs of omalloc
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 11/99
+ *******************************************************************/
+#ifndef OM_STRUCTS_H
+#define OM_STRUCTS_H
+
+struct omBin_s;
+typedef struct omBin_s      omBin_t;
+typedef omBin_t*            omBin;
+
+struct omBinPage_s;
+typedef struct omBinPage_s  omBinPage_t;
+typedef omBinPage_t*        omBinPage;
+
+struct omBinPageRegion_s;
+typedef struct omBinPageRegion_s omBinPageRegion_t;
+typedef omBinPageRegion_t* omBinPageRegion;
+
+struct omOpts_s;
+typedef struct omOpts_s omOpts_t;
+
+struct omInfo_s;
+typedef struct omInfo_s omInfo_t;
+
+struct omSpecBin_s;
+typedef struct omSpecBin_s omSpecBin_t;
+typedef omSpecBin_t*        omSpecBin;
+
+struct omRetInfo_s;
+typedef struct omRetInfo_s omRetInfo_t;
+typedef omRetInfo_t*        omRetInfo;
+
+#endif /* OM_STRUCTS_H */
diff --git a/omalloc/omTables.c b/omalloc/omTables.c
new file mode 100644
index 0000000..390baeb
--- /dev/null
+++ b/omalloc/omTables.c
@@ -0,0 +1,219 @@
+/*******************************************************************
+ *  File:    omTables.c
+ *  Purpose: program which generates omTables.inc
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 11/99
+ *******************************************************************/
+
+#ifndef MH_TABLES_C
+#define MH_TABLES_C
+
+#define _POSIX_SOURCE 1
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include "omConfig.h"
+#include "omDerivedConfig.h"
+#include "omStructs.h"
+#include "omAllocPrivate.h"
+
+/* Specify the minimal number of blocks which should go into a bin */
+#if SIZEOF_SYSTEM_PAGE > 4096
+#define MIN_BIN_BLOCKS 8
+#define INCR_FACTOR     2
+#else
+#define MIN_BIN_BLOCKS 4
+#define INCR_FACTOR 1
+#endif
+
+
+#define OM_MAX_BLOCK_SIZE ((SIZEOF_OM_BIN_PAGE / MIN_BIN_BLOCKS) & ~(SIZEOF_STRICT_ALIGNMENT - 1))
+
+/* Specify sizes of static bins */
+#ifdef OM_ALIGN_8
+
+size_t om_BinSize [SIZEOF_OM_BIN_PAGE / MIN_BIN_BLOCKS] =
+{   8,  16,  24,  32,
+    40,  48,  56,  64, 72,
+    80,  96, 112, 128, 144,
+    160, 192, 224,
+    ((SIZEOF_OM_BIN_PAGE / (MIN_BIN_BLOCKS + INCR_FACTOR*9)) / 8)*8,
+    ((SIZEOF_OM_BIN_PAGE / (MIN_BIN_BLOCKS + INCR_FACTOR*6)) / 8)*8,
+    ((SIZEOF_OM_BIN_PAGE / (MIN_BIN_BLOCKS + INCR_FACTOR*4)) / 8)*8,
+    ((SIZEOF_OM_BIN_PAGE / (MIN_BIN_BLOCKS + INCR_FACTOR*2)) / 8)*8,
+    ((SIZEOF_OM_BIN_PAGE / (MIN_BIN_BLOCKS + INCR_FACTOR))   / 8)*8,
+    OM_MAX_BLOCK_SIZE};
+
+#else /* ! OM_ALIGN_8 */
+
+size_t om_BinSize [SIZEOF_OM_BIN_PAGE / MIN_BIN_BLOCKS] =
+{   8,  12,  16,  20,
+    24,  28,  32,
+    40,  48,  56,  64,
+    80,  96, 112, 128,
+    160, 192, 224,
+    ((SIZEOF_OM_BIN_PAGE / (MIN_BIN_BLOCKS + INCR_FACTOR*9)) / SIZEOF_STRICT_ALIGNMENT)*SIZEOF_STRICT_ALIGNMENT,
+    ((SIZEOF_OM_BIN_PAGE / (MIN_BIN_BLOCKS + INCR_FACTOR*6)) / SIZEOF_STRICT_ALIGNMENT)*SIZEOF_STRICT_ALIGNMENT,
+    ((SIZEOF_OM_BIN_PAGE / (MIN_BIN_BLOCKS + INCR_FACTOR*4)) / SIZEOF_STRICT_ALIGNMENT)*SIZEOF_STRICT_ALIGNMENT,
+    ((SIZEOF_OM_BIN_PAGE / (MIN_BIN_BLOCKS + INCR_FACTOR*2)) / SIZEOF_STRICT_ALIGNMENT)*SIZEOF_STRICT_ALIGNMENT,
+    ((SIZEOF_OM_BIN_PAGE / (MIN_BIN_BLOCKS + INCR_FACTOR))   / SIZEOF_STRICT_ALIGNMENT)*SIZEOF_STRICT_ALIGNMENT,
+    OM_MAX_BLOCK_SIZE};
+
+#endif /* OM_ALIGN_8 */
+
+void OutputSize2Bin(size_t *binSize, size_t max_block_size, int track)
+{
+  long i, j;
+  printf("omBin om_Size2%sBin[/*%ld*/] = {\n",
+         (track? "Track" : ""), (long)(max_block_size / SIZEOF_OM_ALIGNMENT));
+  i=0;
+  j=SIZEOF_OM_ALIGNMENT;
+  while (j < max_block_size)
+  {
+    printf("&om_Static%sBin[%ld], /* %ld */ \n", (track? "Track" : ""), i, j);
+    if (binSize[i] == j) i++;
+    j += SIZEOF_OM_ALIGNMENT;
+  }
+  printf("&om_Static%sBin[%ld] /* %ld */};\n\n", (track? "Track" : ""), i, j);
+}
+
+void OutputSize2AlignedBin(size_t *binSize, size_t max_block_size, int track)
+{
+  long i, j;
+  if (OM_MAX_BLOCK_SIZE % 8 != 0)
+  {
+    fprintf(stderr, "OM_MAX_BLOCK_SIZE == %d not divisible by 8\n", OM_MAX_BLOCK_SIZE);fflush(stdout);
+    _exit(1);
+  }
+  printf("omBin om_Size2%sBin[/*%ld*/] = {\n",
+         (track ? "Track" : "Aligned"), (long)(max_block_size / SIZEOF_OM_ALIGNMENT));
+  i=0;
+  while (binSize[i] % SIZEOF_STRICT_ALIGNMENT != 0) i++;
+  j=SIZEOF_OM_ALIGNMENT;
+  while (j < max_block_size)
+  {
+    printf("&om_Static%sBin[%ld], /* %ld */ \n", (track ? "Track" : ""), i, j);
+    if (binSize[i] == j)
+    {
+      i++;
+      while (binSize[i] % SIZEOF_STRICT_ALIGNMENT != 0) i++;
+    }
+    j += SIZEOF_OM_ALIGNMENT;
+  }
+  printf("&om_Static%sBin[%ld] /* %ld */};\n\n", (track ? "Track" : ""), i, j);
+}
+
+void OutputStaticBin(size_t *binSize, int max_bin_index, int track)
+{
+  long i;
+  printf("omBin_t om_Static%sBin[/*%d*/] = {\n", (track ? "Track" : ""), max_bin_index+1);
+
+  for (i=0;  i< max_bin_index; i++)
+  {
+    printf("{om_ZeroPage, NULL, NULL, %ld, %ld, 0},\n",
+           (long)(binSize[i] / SIZEOF_LONG),
+           (long)(SIZEOF_OM_BIN_PAGE/binSize[i]));
+  }
+  printf("{om_ZeroPage, NULL, NULL, %ld, %ld, 0}\n};\n\n",
+         (long)(binSize[i] / SIZEOF_LONG),
+         (long)(SIZEOF_OM_BIN_PAGE/binSize[i]));
+}
+
+int GetMaxBlockThreshold()
+{
+  int i;
+  for (i=SIZEOF_OM_ALIGNMENT; i < OM_MAX_BLOCK_SIZE; i += SIZEOF_OM_ALIGNMENT)
+  {
+    if ((SIZEOF_OM_BIN_PAGE/i) == SIZEOF_OM_BIN_PAGE/(i + SIZEOF_OM_ALIGNMENT))
+      return i;
+  }
+  /* should never get here */
+  printf("error");fflush(stdout);
+  _exit(1);
+}
+
+void CreateDenseBins()
+{
+  size_t size, align_size = SIZEOF_OM_ALIGNMENT;
+  int i = 1;
+#ifdef OM_ALIGNMENT_NEEDS_WORK
+  int n = GetMaxBlockThreshold();
+#endif
+
+  size = align_size;
+  om_BinSize[0] = align_size;
+  i = 1;
+  while (size < OM_MAX_BLOCK_SIZE)
+  {
+    size += align_size;
+#ifdef OM_ALIGNMENT_NEEDS_WORK
+    if (size >= n && align_size != SIZEOF_STRICT_ALIGNMENT)
+    {
+      align_size = SIZEOF_STRICT_ALIGNMENT;
+      size= OM_STRICT_ALIGN_SIZE(size);
+    }
+#endif
+    om_BinSize[i] = size;
+    if ((SIZEOF_OM_BIN_PAGE / (size + align_size)) < (SIZEOF_OM_BIN_PAGE /size))
+    {
+      i++;
+    }
+  }
+}
+
+int main(int argc, char* argv[])
+{
+  int max_bin_index = 0;
+  /* determine max_bin_index */
+#ifdef OM_HAVE_DENSE_BIN_DISTRIBUTION
+  CreateDenseBins();
+#endif
+  for(;;)
+  {
+    max_bin_index++;
+    if (om_BinSize[max_bin_index] == OM_MAX_BLOCK_SIZE) break;
+  }
+  if (argc > 1)
+  {
+    /* output what goes into omTables.h */
+  printf(
+"#ifndef OM_TABLES_H\n"
+"#define OM_TABLES_H\n"
+"#define OM_MAX_BLOCK_SIZE %d\n"
+"#define OM_MAX_BIN_INDEX %d\n"
+"#define OM_SIZEOF_UNIQUE_MAX_BLOCK_THRESHOLD %d\n"
+"#endif /* OM_TABLES_H */\n"
+,  OM_MAX_BLOCK_SIZE, max_bin_index, GetMaxBlockThreshold());
+  return 0;
+  }
+
+  printf(
+"#ifndef OM_TABLES_INC\n"
+"#define OM_TABLES_INC\n"
+);
+
+  /* Output om_StaticBin */
+  OutputStaticBin(om_BinSize, max_bin_index, 0);
+  /* Output om_Size2Bin */
+  OutputSize2Bin(om_BinSize, OM_MAX_BLOCK_SIZE, 0);
+
+#ifdef OM_ALIGNMENT_NEEDS_WORK
+  OutputSize2AlignedBin(om_BinSize, OM_MAX_BLOCK_SIZE, 0);
+#endif
+
+  printf("\n#ifdef OM_HAVE_TRACK\n");
+  /* Output om_StaticBin */
+  OutputStaticBin(om_BinSize, max_bin_index, 1);
+  /* Output om_Size2Bin */
+#ifdef OM_ALIGNMENT_NEEDS_WORK
+  OutputSize2AlignedBin(om_BinSize, OM_MAX_BLOCK_SIZE, 1);
+#else
+  OutputSize2Bin(om_BinSize, OM_MAX_BLOCK_SIZE, 1);
+#endif
+  printf("\n#endif /* OM_HAVE_TRACK */\n");
+
+  printf("\n#endif /* OM_TABLES_INC */\n");
+  return 0;
+}
+#endif /* MH_TABLES_C */
diff --git a/omalloc/om_Alloc.c b/omalloc/om_Alloc.c
new file mode 100644
index 0000000..f901982
--- /dev/null
+++ b/omalloc/om_Alloc.c
@@ -0,0 +1,264 @@
+/*******************************************************************
+ *  File:    omAlloc.c
+ *  Purpose: implementation of main omalloc functions
+ *  Author:  obachman at mathematik.uni-kl.de (Olaf Bachmann)
+ *  Created: 11/99
+ *******************************************************************/
+#ifndef OM_ALLOC_C
+#define OM_ALLOC_C
+
+#include "omalloc.h"
+/*******************************************************************
+ *
+ *  global variables
+ *
+ *******************************************************************/
+
+omBinPage_t om_ZeroPage[] = {{0, NULL, NULL, NULL, NULL}};
+omSpecBin om_SpecBin = NULL;
+
+#include <omalloc/omTables.inc>
+
+
+/*******************************************************************
+ *
+ *  Local stuff
+ *
+ *******************************************************************/
+
+/* Get new page and initialize */
+static omBinPage omAllocNewBinPage(omBin bin)
+{
+  omBinPage newpage;
+  void* tmp;
+  int i = 1;
+
+  if (bin->max_blocks > 0) newpage = omAllocBinPage();
+  else newpage = omAllocBinPages(-bin->max_blocks);
+
+  omAssume(omIsAddrPageAligned((void*) newpage));
+
+  omSetTopBinAndStickyOfPage(newpage, bin, bin->sticky);
+  newpage->used_blocks = -1;
+  newpage->current = (void*) (((char*)newpage) + SIZEOF_OM_BIN_PAGE_HEADER);
+  tmp = newpage->current;
+  while (i < bin->max_blocks)
+  {
+    tmp = *((void**)tmp) = ((void**) tmp) + bin->sizeW;
+    i++;
+  }
+  *((void**)tmp) = NULL;
+  omAssume(omListLength(newpage->current) ==
+           (bin->max_blocks > 1 ? bin->max_blocks : 1));
+  return newpage;
+}
+
+/* primitives for handling of list of pages */
+OM_INLINE_LOCAL void omTakeOutBinPage(omBinPage page, omBin bin)
+{
+  if (bin->current_page == page)
+  {
+    if (page->next == NULL)
+    {
+      if (page->prev == NULL)
+      {
+        omAssume(bin->last_page == page);
+        bin->last_page = NULL;
+        bin->current_page = om_ZeroPage;
+        return;
+      }
+      bin->current_page = page->prev;
+    }
+    else
+      bin->current_page = page->next;
+  }
+  if (bin->last_page == page)
+  {
+    omAssume(page->prev != NULL && page->next == NULL);
+    bin->last_page = page->prev;
+  }
+  else
+  {
+    omAssume(page->next != NULL);
+    page->next->prev = page->prev;
+  }
+  if (page->prev != NULL) page->prev->next = page->next;
+}
+
+OM_INLINE_LOCAL void omInsertBinPage(omBinPage after, omBinPage page, omBin bin)
+{
+  if (bin->current_page == om_ZeroPage)
+  {
+    omAssume(bin->last_page == NULL);
+    page->next = NULL;
+    page->prev = NULL;
+    bin->current_page = page;
+    bin->last_page = page;
+  }
+  else
+  {
+    omAssume(after != NULL && bin->last_page != NULL);
+    if (after == bin->last_page)
+    {
+      bin->last_page = page;
+    }
+    else
+    {
+      omAssume(after->next != NULL);
+      after->next->prev = page;
+    }
+    page->next = after->next;
+    after->next = page;
+    page->prev = after;
+  }
+}
+
+/* bin->current_page is empty, get new bin->current_page, return addr*/
+void* omAllocBinFromFullPage(omBin bin)
+{
+  void* addr;
+  omBinPage newpage;
+  omAssume(bin->current_page->current == NULL);
+
+  if (bin->current_page != om_ZeroPage)
+  {
+    omAssume(bin->last_page != NULL);
+    /* Set this to zero, but preserve the first bit,
+       so that tracking works */
+#ifdef OM_HAVE_TRACK
+    bin->current_page->used_blocks &= (((unsigned long) 1) << (BIT_SIZEOF_LONG -1));
+#else
+    bin->current_page->used_blocks = 0;
+#endif
+  }
+
+  if (!bin->sticky && bin->current_page->next != NULL)
+  {
+    omAssume(bin->current_page->next->current != NULL);
+    newpage = bin->current_page->next;
+  }
+  else
+  {
+    // need to Allocate new page
+    newpage = omAllocNewBinPage(bin);
+    omInsertBinPage(bin->current_page, newpage, bin);
+  }
+
+  bin->current_page = newpage;
+  omAssume(newpage != NULL && newpage != om_ZeroPage &&
+           newpage->current != NULL);
+  __omTypeAllocFromNonEmptyPage(void*, addr, newpage);
+  return addr;
+}
+
+
+/* page->used_blocks <= 0, so, either free page or reallocate to
+   the right of current_page */
+/*
+ * Now: there are three different strategies here, on what to do with
+ * pages which were full and now have a free block:
+ * 1.) Insert at the end (default)
+ * 2.) Insert after current_page  => #define PAGE_AFTER_CURRENT
+ * 3.) Let it be new current_page => #define PAGE_BEFORE_CURRENT
+ * Still need to try out which is best
+ */
+void  omFreeToPageFault(omBinPage page, void* addr)
+{
+  omBin bin;
+  omAssume(page->used_blocks <= 0L);
+
+#ifdef OM_HAVE_TRACK
+  if (page->used_blocks < 0L)
+  {
+    omFreeTrackAddr(addr);
+    return;
+  }
+#endif
+
+  bin = omGetBinOfPage(page);
+  if ((page->current != NULL) || (bin->max_blocks <= 1))
+  {
+    // all blocks of page are now collected
+    omTakeOutBinPage(page, bin);
+    // page can be freed
+    if (bin->max_blocks > 0)
+      omFreeBinPage(page);
+    else
+      omFreeBinPages(page, - bin->max_blocks);
+#ifdef OM_HAVE_TRACK
+    om_JustFreedPage = page;
+#endif
+  }
+  else
+  {
+    // page was full
+    page->current = addr;
+    page->used_blocks = bin->max_blocks - 2;
+    *((void**)addr) = NULL;
+
+    omTakeOutBinPage(page, bin);
+#if defined(PAGE_BEFORE_CURRENT)
+    if (bin->current_page->prev != NULL)
+      omInsertBinPage(bin->current_page->prev, page);
+    else
+      omInsertBinPage(bin->current_page, page, bin);
+    bin->current_page = page;
+#else
+#  if defined(PAGE_AFTER_CURRENT)
+      omInsertBinPage(bin->current_page, page, bin);
+#  else
+      omInsertBinPage(bin->last_page, page, bin);
+#  endif
+#endif
+  }
+}
+
+/*******************************************************************
+ *
+ *  DoRealloc
+ *
+ *******************************************************************/
+#ifdef OM_ALIGNMNET_NEEDS_WORK
+#define DO_ZERO(flag) (flag & 1)
+#else
+#define DO_ZERO(flag)    flag
+#endif
+
+void* omDoRealloc(void* old_addr, size_t new_size, int flag)
+{
+  void* new_addr;
+
+  if (!omIsBinPageAddr(old_addr) && new_size > OM_MAX_BLOCK_SIZE)
+  {
+    if (DO_ZERO(flag))
+      return omRealloc0Large(old_addr, new_size);
+    else
+      return omReallocLarge(old_addr, new_size);
+  }
+  else
+  {
+    size_t old_size = omSizeOfAddr(old_addr);
+    size_t min_size;
+
+    omAssume(OM_IS_ALIGNED(old_addr));
+
+#ifdef OM_ALIGNMENT_NEEDS_WORK
+    if (flag & 2)
+      __omTypeAllocAligned(void*, new_addr, new_size);
+    else
+#endif
+      __omTypeAlloc(void*, new_addr, new_size);
+
+    new_size = omSizeOfAddr(new_addr);
+    min_size = (old_size < new_size ? old_size : new_size);
+    omMemcpyW(new_addr, old_addr, min_size >> LOG_SIZEOF_LONG);
+
+    if (DO_ZERO(flag) && (new_size > old_size))
+      omMemsetW((char*) new_addr + min_size, 0, (new_size - old_size) >> LOG_SIZEOF_LONG);
+
+    __omFreeSize(old_addr, old_size);
+
+    return new_addr;
+  }
+}
+#endif /* OM_ALLOC_C */
diff --git a/omalloc/omalloc.c b/omalloc/omalloc.c
new file mode 100644
index 0000000..3b10242
--- /dev/null
+++ b/omalloc/omalloc.c
@@ -0,0 +1,128 @@
+/*******************************************************************
+ *  File:    omalloc.c
+ *  Purpose: implementation of ANSI-C conforming malloc functions
+ *           -- the real version
+ *  Author:  obachman at mathematik.uni-kl.de (Olaf Bachmann)
+ *  Created: 11/99
+ *******************************************************************/
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#ifndef OMALLOC_C
+#define OMALLOC_C
+
+#include "omalloc.h"
+
+#ifdef OM_MALLOC_MARK_AS_STATIC
+#define OM_MARK_AS_STATIC(addr) omMarkAsStaticAddr(addr)
+#else
+#define OM_MARK_AS_STATIC(addr) do {} while (0)
+#endif
+
+#if OM_PROVIDE_MALLOC > 0
+
+void* calloc(size_t nmemb, size_t size)
+{
+  void* addr;
+  if (size == 0) size = 1;
+  if (nmemb == 0) nmemb = 1;
+
+  size = size*nmemb;
+  omTypeAlloc0Aligned(void*, addr, size);
+  OM_MARK_AS_STATIC(addr);
+  return addr;
+}
+
+void free(void* addr)
+{
+  omfree(addr);
+}
+
+void* valloc(size_t size)
+{
+  fprintf(stderr, "omalloc Warning: valloc not yet implemented\n");
+  fflush(NULL);
+  return NULL;
+}
+
+#if defined(sgi)
+void* memalign(size_t size_1, size_t size_2)
+#elif (defined(__sun) && (defined(__sparc) || defined(__i386) || defined(__x86_64)) || defined(__CYGWIN__))
+void* memalign(size_t size_1, size_t size_2)
+#else
+void* memalign(void* alignment, size_t size)
+#endif
+{
+  fprintf(stderr, "omalloc Warning: memalign not yet implemented\n");
+  fflush(NULL);
+  return NULL;
+}
+
+void* realloc(void* old_addr, size_t new_size)
+{
+  if (old_addr && new_size)
+  {
+    void* new_addr;
+    omTypeReallocAligned(old_addr, void*, new_addr, new_size);
+    OM_MARK_AS_STATIC(new_addr);
+    return new_addr;
+  }
+  else
+  {
+    free(old_addr);
+    return malloc(new_size);
+  }
+}
+
+/* on some systems strdup is a macro -- replace it unless OMALLOC_FUNC
+   is defined */
+#ifndef OMALLOC_USES_MALLOC
+#if !defined(OMALLOC_FUNC)
+#undef strdup
+#endif
+char* strdup_(const char* addr)
+{
+  char* n_s;
+  if (addr)
+  {
+    n_s = omStrDup(addr);
+    OM_MARK_AS_STATIC(n_s);
+    return n_s;
+  }
+  return NULL;
+}
+#endif
+#endif
+
+void* malloc(size_t size)
+{
+  void* addr;
+  if (size == 0) size = 1;
+
+  omTypeAllocAligned(void*, addr, size);
+  OM_MARK_AS_STATIC(addr);
+  return addr;
+}
+
+void freeSize(void* addr, size_t size)
+{
+  if (addr) omFreeSize(addr, size);
+}
+
+void* reallocSize(void* old_addr, size_t old_size, size_t new_size)
+{
+  if (old_addr && new_size)
+  {
+   void* new_addr;
+    omTypeReallocAlignedSize(old_addr, old_size, void*, new_addr, new_size);
+    OM_MARK_AS_STATIC(new_addr);
+    return new_addr;
+  }
+  else
+  {
+    freeSize(old_addr, old_size);
+    return malloc(new_size);
+  }
+}
+#endif
diff --git a/omalloc/omalloc.h b/omalloc/omalloc.h
new file mode 100644
index 0000000..8f05f95
--- /dev/null
+++ b/omalloc/omalloc.h
@@ -0,0 +1,54 @@
+/*******************************************************************
+ *  File:    omalloc.h
+ *  Purpose: declaration of public routines for omalloc
+ *  Author:  obachman at mathematik.uni-kl.de (Olaf Bachmann)
+ *  Created: 11/99
+ *******************************************************************/
+#ifndef OM_ALLOC_H
+#define OM_ALLOC_H
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <omalloc/omConfig.h>
+
+#if defined(OM_NDEBUG) && !defined(OM_ALLOC_INTERNAL)
+#if (SIZEOF_LONG == 8)
+#define OM_T_FREE1
+#define OM_T_FREE3
+#define OM_T_STR
+#define OM_T_ALLOC
+#define OM_T_REALLOC
+#endif
+#endif
+
+#include "omDerivedConfig.h"
+#include "omError.h"
+#include "omStructs.h"
+#include "omAllocDecl.h"
+#include "omInlineDecl.h"
+#include "omBin.h"
+#include "omMemOps.h"
+#include "omList.h"
+#include "omGetBackTrace.h"
+#include "omRet2Info.h"
+#include "omStats.h"
+#include "omOpts.h"
+#include "omBinPage.h"
+#include "omAllocSystem.h"
+#include <omalloc/omTables.h>
+#include "omAllocPrivate.h"
+#include "omDebug.h"
+#include "omInline.h"
+#include "omAllocFunc.h"
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* OM_ALLOC_H */
diff --git a/omalloc/omalloc.pc.in b/omalloc/omalloc.pc.in
new file mode 100644
index 0000000..ada6a11
--- /dev/null
+++ b/omalloc/omalloc.pc.in
@@ -0,0 +1,17 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: @PACKAGE@
+Description: The Singular memory manager
+Version: @PACKAGE_VERSION@
+URL: https://github.com/Singular/Sources/tree/spielwiese/@PACKAGE@
+
+# Requires:
+# Conflicts:
+
+Cflags: -I${includedir} -DOM_NDEBUG
+Libs: -L${libdir} -l at PACKAGE@
+# Libs.private:
+
diff --git a/omalloc/omalloc_provide.c b/omalloc/omalloc_provide.c
new file mode 100644
index 0000000..fde8fa1
--- /dev/null
+++ b/omalloc/omalloc_provide.c
@@ -0,0 +1,16 @@
+/*******************************************************************
+ *  File:    omalloc_provide.c
+ *  Purpose: implementation of ANSI-C conforming malloc functions
+ *            which are to be provided by omalloc library
+ *  Author:  obachman at mathematik.uni-kl.de (Olaf Bachmann)
+ *  Created: 11/99
+ *******************************************************************/
+#include "omConfig.h"
+
+#if OM_PROVIDE_MALLOC > 0
+#if OM_PROVIDE_MALLOC > 1
+#include <omalloc/omalloc_debug.c>
+#else
+#include <omalloc/omalloc.c>
+#endif
+#endif
diff --git a/omalloc/omtTest.c b/omalloc/omtTest.c
new file mode 100644
index 0000000..68309bb
--- /dev/null
+++ b/omalloc/omtTest.c
@@ -0,0 +1,495 @@
+#include "omtTest.h"
+
+#if CHECK_LEVEL > 0
+#define OM_CHECK CHECK_LEVEL
+#endif
+
+#include "omalloc.h"
+
+omMemCell_t cells[MAX_CELLS];
+int errors = 0;
+int missed_errors = 0;
+int used_regions = 0;
+int seed;
+
+#if defined (__hpux) || defined (__alpha)  || defined (__svr4__) || defined (__SVR4)
+/* SF1 cosimo.medicis.polytechnique.fr V4.0 1229 alpha works */
+#if defined (__hpux) || defined (__svr4__) || defined (__SVR4)
+/* HPUX lacks random().  DEC OSF/1 1.2 random() returns a double.  */
+long mrand48 ();
+void srand48();
+static long
+random ()
+{
+  return mrand48 ();
+}
+static void srandom(long seed)
+{
+  srand48(seed);
+}
+#endif
+#endif
+
+#if CHECK_LEVEL > 0
+void omtTestDebug(omMemCell cell)
+{
+  size_t size = GET_SIZE(cell->spec);
+  size_t is_size;
+
+  if (om_ErrorStatus != omError_NoError) return;
+  if (cell->bin != NULL)
+  {
+    if (IS_ALIGNED(cell->spec))
+      omDebugAddrAlignedBin(cell->addr, cell->bin);
+    else
+      omDebugAddrBin(cell->addr, cell->bin);
+  }
+  else
+  {
+    if (IS_ALIGNED(cell->spec))
+      omDebugAddrAlignedSize(cell->addr, size);
+    else
+      omDebugAddrSize(cell->addr, size);
+  }
+  if (om_ErrorStatus != omError_NoError) return;
+
+  if (!OM_IS_ALIGNED(cell->addr))
+  {
+    omReportError(omError_Unknown, omError_NoError, OM_FLR,
+                  "addr:%p is unaligned", cell->addr);
+    return;
+  }
+
+  if (IS_ALIGNED(cell->spec) && !OM_IS_STRICT_ALIGNED(cell->addr))
+  {
+    omReportError(omError_Unknown, omError_NoError, OM_FLR,
+                  "addr:%p is not strict unaligned", cell->addr);
+    return;
+  }
+
+  is_size = omSizeOfAddr(cell->addr);
+  if (!OM_IS_ALIGNED(is_size))
+  {
+    omReportError(omError_Unknown, omError_NoError, OM_FLR,
+                  "is_size == %u is unaligned", is_size);
+    return;
+  }
+  if (is_size < size)
+  {
+    omReportError(omError_Unknown, omError_NoError, OM_FLR,
+                  "is_size==%u < size==%u", is_size, size);
+    return;
+  }
+
+  if (is_size >> LOG_SIZEOF_LONG != omSizeWOfAddr(cell->addr))
+  {
+    omReportError(omError_Unknown, omError_NoError, OM_FLR,
+                  "is_sizeW==%u < sizeW==%u", is_size >> LOG_SIZEOF_LONG, omSizeWOfAddr(cell->addr));
+    return;
+  }
+
+  TestAddrContent(cell->addr, (IS_ZERO(cell->spec) ? 0 : cell->spec), is_size);
+}
+
+void TestAddrContentEqual(void* s1, void* s2, size_t size)
+{
+  int i;
+  size_t sizeW = OM_ALIGN_SIZE(size) >> LOG_SIZEOF_LONG;
+
+  for (i=0; i<sizeW; i++)
+  {
+    if (((unsigned long*)s1)[i] != ((unsigned long*)s2)[i])
+    {
+       omReportError(omError_Unknown, omError_NoError, OM_FLR,
+                     "s1[%u]==%d  !=  s2[%u]==%d", i, ((unsigned long*)s1)[i], i, ((unsigned long*)s2)[i]);
+       return;
+    }
+  }
+}
+
+void TestAddrContent(void* addr, unsigned long value, size_t size)
+{
+  size_t sizeW = OM_ALIGN_SIZE(size) >> LOG_SIZEOF_LONG;
+  int i;
+
+  if (!OM_IS_ALIGNED(addr))
+  {
+    omReportError(omError_Unknown, omError_NoError, OM_FLR,
+                  "addr %p unaligned", addr);
+    return;
+  }
+
+  for (i=0; i<sizeW; i++)
+  {
+    if (((unsigned long*)addr)[i] != value)
+    {
+      omReportError(omError_Unknown, omError_NoError, OM_FLR,
+                    "word %d modified: is %u should be %u", i, ((unsigned long*)addr)[i], value);
+      return;
+    }
+  }
+}
+#endif
+
+void InitCellAddrContent(omMemCell cell)
+{
+  size_t sizeW = omSizeWOfAddr(cell->addr);
+  omMemsetW(cell->addr, (IS_ZERO(cell->spec) ? 0 : cell->spec), sizeW);
+}
+
+void omCheckCells(int n, int level, omMemCell_t* cells)
+{
+#if END_CHECK_LEVEL > 0
+  int l = om_Opts.MinCheck;
+  int i;
+
+  omTestMemory(level);
+  om_Opts.MinCheck = 1;
+  for (i=0; i<n; i++)
+  {
+    omtTestDebug(&cells[i]);
+    if (om_ErrorStatus != omError_NoError)
+    {
+      errors++;
+      om_ErrorStatus = omError_NoError;
+    }
+    if ((i % 10000) == 0)
+    {
+      printf(".");
+      fflush(stdout);
+    }
+  }
+  om_Opts.MinCheck = l;
+#endif
+}
+
+
+int size_range = RANGE_MIN;
+int size_range_number = RANGE_MAX / RANGE_MIN;
+
+int MyRandSpec()
+{
+  unsigned long spec = random() + 1;
+  if (! size_range_number)
+  {
+    size_range = size_range << 1;
+    if (size_range > RANGE_MAX) size_range = RANGE_MIN;
+    size_range_number = RANGE_MAX / size_range;
+  }
+  SET_SIZE(spec, GET_SIZE(spec) & (size_range -1));
+  size_range_number--;
+  if (GET_SIZE(spec) == 0) spec++;
+  return spec;
+}
+
+
+void TestAlloc(omMemCell cell, unsigned long spec)
+{
+  if (DO_CHECK(spec))
+  {
+    if (DO_TRACK(spec))
+      om_Opts.MinTrack = GET_TRACK(spec);
+    else
+      om_Opts.MinTrack = 0;
+
+    if (DO_KEEP(spec))
+      omtTestAllocKeep(cell, spec);
+    else
+      omtTestAllocDebug(cell, spec);
+  }
+  else
+    omtTestAlloc(cell, spec);
+  if (om_ErrorStatus != omError_NoError)
+  {
+    errors++;
+    om_ErrorStatus = omError_NoError;
+  }
+}
+
+void TestRealloc(omMemCell cell, unsigned long spec)
+{
+  if (DO_CHECK(spec))
+  {
+    if (DO_TRACK(spec))
+      om_Opts.MinTrack = GET_TRACK(spec);
+    else
+      om_Opts.MinTrack = 0;
+
+    if (DO_KEEP(spec))
+      omtTestReallocKeep(cell, spec);
+    else
+      omtTestReallocDebug(cell, spec);
+  }
+  else
+    omtTestRealloc(cell, spec);
+  if (om_ErrorStatus != omError_NoError)
+  {
+    errors++;
+    om_ErrorStatus = omError_NoError;
+  }
+}
+
+void TestDup(omMemCell cell, unsigned long spec)
+{
+  if (DO_CHECK(spec))
+  {
+    if (DO_TRACK(spec))
+      om_Opts.MinTrack = GET_TRACK(spec);
+    else
+      om_Opts.MinTrack = 0;
+
+    if (DO_KEEP(spec))
+      omtTestDupKeep(cell, spec);
+    else
+      omtTestDupDebug(cell, spec);
+  }
+  else
+    omtTestDup(cell, spec);
+
+  if (om_ErrorStatus != omError_NoError)
+  {
+    errors++;
+    om_ErrorStatus = omError_NoError;
+  }
+}
+
+void TestFree(omMemCell cell)
+{
+  if (cell->addr != NULL)
+  {
+    if (DO_FREE_CHECK(cell->spec))
+    {
+      if (DO_KEEP(cell->spec))
+        omtTestFreeKeep(cell);
+      else
+        omtTestFreeDebug(cell);
+    }
+    else
+    {
+      omtTestFree(cell);
+    }
+    if (om_ErrorStatus != omError_NoError)
+    {
+      errors++;
+      om_ErrorStatus = omError_NoError;
+    }
+  }
+}
+
+omBin omtGetStickyBin(omBin bin)
+{
+  omBin sticky_bin = omFindInGList(om_StickyBins, next, max_blocks, bin->max_blocks);
+  if (sticky_bin == NULL)
+    sticky_bin = omGetStickyBinOfBin(bin);
+  return sticky_bin;
+}
+
+void omtMergeStickyBins(omMemCell cell, int n)
+{
+  int i;
+  omBin bin;
+
+  for (i=0; i<n; i++)
+  {
+    if (cell[i].orig_bin != NULL)
+    {
+      if (omIsOnGList(om_StickyBins, next, cell[i].bin))
+        omMergeStickyBinIntoBin(cell[i].bin, cell[i].orig_bin);
+
+      cell[i].bin = cell[i].orig_bin;
+      cell[i].orig_bin = NULL;
+    }
+  }
+
+  bin = om_StickyBins;
+  while (bin != NULL)
+  {
+    if (bin->current_page == om_ZeroPage)
+    {
+      omBin next_bin = bin->next;
+      om_StickyBins = omRemoveFromGList(om_StickyBins, next, bin);
+      __omFreeBinAddr(bin);
+      bin = next_bin;
+    }
+    else
+    {
+      bin = bin->next;
+    }
+  }
+}
+
+
+void my_exit()
+{
+  printf("\nomtTest Summary: ");
+  if (errors || missed_errors || used_regions)
+  {
+    printf("***FAILED***errors:%d, missed_errors:%d, used_regions:%d, seed=%d\n", errors, missed_errors, used_regions, seed);
+    if (errors) exit(errors);
+    if (missed_errors) exit(missed_errors);
+    if (used_regions) exit(used_regions);
+  }
+  else
+  {
+    printf("OK\n");
+    exit(0);
+  }
+}
+
+
+int main(int argc, char* argv[])
+{
+  int i=0, error_test = 1;
+  unsigned long spec, j;
+  int n = 1;
+  int n_cells = MAX_CELLS;
+  int decr = 2;
+  int last_kept_freed = 0;
+  om_Opts.MinCheck = CHECK_LEVEL;
+  om_Opts.Keep = KEEP_ADDR;
+
+  seed = time(NULL);
+
+  omInitRet_2_Info(argv[0]);
+  omInitGetBackTrace();
+  omInitInfo();
+  om_Opts.PagesPerRegion = PAGES_PER_REGION;
+
+  if (argc > 1) sscanf(argv[1], "%d", &error_test);
+  if (argc > 2) sscanf(argv[2], "%d", &seed);
+  srandom(seed);
+
+  if (argc > 3) sscanf(argv[3], "%d", &n);
+  if (argc > 4) sscanf(argv[4], "%d", &decr);
+
+  if (decr < 2) decr = 2;
+  printf("seed == %d\n", seed);
+  fflush(stdout);
+  while (1)
+  {
+    if (i == n_cells)
+    {
+      i = 0;
+      printf("\nCells: %d KeptAddr:%d AlwaysKeptAddr:%d\n", n_cells,
+#ifndef OM_NDEBUG
+             omListLength(om_KeptAddr), omListLength(om_AlwaysKeptAddrs)
+#else
+             0, 0
+#endif
+             );
+
+      printf("Checking Memory and all cells ");
+      fflush(stdout);
+      omCheckCells(n_cells, END_CHECK_LEVEL, cells);
+      printf("\n");
+      omPrintStats(stdout);
+      omPrintInfo(stdout);
+      if (om_Info.CurrentRegionsAlloc > 0) omPrintBinStats(stdout);
+      fflush(stdout);
+#if CHECK_LEVEL > 0 && TRACK_LEVEL > 0
+      if (error_test && errors == 0)
+      {
+        missed_errors = omtTestErrors();
+        if (missed_errors < 0)
+        {
+          my_exit();
+        }
+      }
+#endif
+      omtMergeStickyBins(cells, n_cells);
+      while (i< n_cells)
+      {
+        TestFree(&cells[i]);
+        i++;
+      }
+      omFreeKeptAddr();
+      omtMergeStickyBins(cells, -1);
+      omPrintStats(stdout);
+      omPrintInfo(stdout);
+      if (om_Info.CurrentRegionsAlloc > 0)
+      {
+        omPrintBinStats(stdout);
+        used_regions += om_Info.CurrentRegionsAlloc;
+      }
+      omPrintUsedAddrs(stdout, 5);
+      i=0;
+      n--;
+      if (n <= 0 || n_cells <= 100)
+      {
+        my_exit();
+      }
+      else
+      {
+        n_cells = n_cells / decr;
+      }
+    }
+    spec = MyRandSpec();
+    myprintf("%d:%lu:%ld:%ld", i, spec, GET_SIZE(spec), GET_TRACK(spec));
+    myfflush(stdout);
+    if (DO_FREE(spec))
+    {
+      if (i != 0)
+      {
+        myprintf(" FREE");
+        j = spec % i;
+        myprintf(" %ld ", j);
+        myfflush(stdout);
+        TestFree(&cells[j]);
+        TestAlloc(&cells[j], spec);
+      }
+    }
+    else if (DO_REALLOC(spec))
+    {
+      if (i != 0)
+      {
+        myprintf(" REALLOC");
+        j = spec % i;
+        myprintf(" %ld ", j);
+        myfflush(stdout);
+        TestRealloc(&cells[j], spec);
+      }
+    }
+    else if (DO_DUP(spec))
+    {
+      if (i != 0)
+      {
+        myprintf(" DUP");
+        j = spec % i;
+        myprintf(" %ld ", j);
+        myfflush(stdout);
+        TestDup(&cells[j], spec);
+      }
+    }
+    else
+    {
+      myprintf(" ALLOC");
+      myfflush(stdout);
+      TestAlloc(&cells[i], spec);
+      i++;
+      if (i % 1000 == 0)
+      {
+        printf("%d:", i / 1000);
+        fflush(stdout);
+      }
+    }
+    myprintf("\n");
+    myfflush(stdout);
+    // free kept addresses from time to time
+    if ((i % 10000) == 0 && i != n_cells && i!=last_kept_freed)
+    {
+      printf("F:");
+      omFreeKeptAddr();
+      last_kept_freed = i;
+    }
+#if 0
+    if (CHECK_LEVEL > 2)
+    {
+      for (j=0; j<i; j++)
+      {
+        omtTestDebug(&cells[j]);
+      }
+    }
+#endif
+  }
+  return 0;
+}
diff --git a/omalloc/omtTest.h b/omalloc/omtTest.h
new file mode 100644
index 0000000..4d9ba16
--- /dev/null
+++ b/omalloc/omtTest.h
@@ -0,0 +1,127 @@
+#include <time.h>
+#include <string.h>
+#include <mylimits.h>
+
+#define TRACK_LEVEL   1
+#define CHECK_LEVEL   1
+// keep every ith address: define to 0 if no keeping
+#define KEEP_LEVEL    20
+// #define KEEP_LEVEL    0
+
+// #define MAX_CELLS  500000
+// #define MAX_CELLS     100000
+#define MAX_CELLS     100000
+#define KEEP_ADDR     100
+// #define KEEP_ADDR     0
+#define END_CHECK_LEVEL 5
+
+#ifdef OM_TEST_MALLOC
+#define OM_EMULATE_OMALLOC
+#endif
+
+
+#include "omStructs.h"
+
+struct omMemCell_s
+{
+  void* addr;
+  omBin bin;
+  unsigned long spec;
+  omBin orig_bin;
+};
+
+typedef struct omMemCell_s omMemCell_t;
+typedef omMemCell_t* omMemCell;
+
+extern omMemCell_t cells[];
+void TestAlloc(omMemCell cell, unsigned long spec);
+void TestRealloc(omMemCell cell, unsigned long spec);
+void TestFree(omMemCell cell);
+
+#if CHECK_LEVEL > 2
+#define myprintf(format, args...) \
+  printf(format, ## args)
+#define myfflush(what) fflush(what)
+#else
+#define myprintf(format, args...) do {} while (0)
+#define myfflush(what)            do {} while (0)
+#endif
+
+#define IS_STICKY_BIN(spec) (spec & 1)
+// #define IS_STICKY_BIN(spec) (0)
+#define GET_SIZE(spec)      (spec & ((((unsigned long) 1) << 14) -1))
+#define SET_SIZE(spec, size) spec = ((spec & ~((((unsigned long) 1) << 14) -1)) | (size))
+#define IS_ALIGNED(spec)    (spec & (((unsigned long) 1) << 15))
+#define IS_ZERO(spec)       (spec & (((unsigned long) 1) << 16))
+#define IS_BIN(spec)        (spec & (((unsigned long) 1) << 17))
+#define IS_SPEC_BIN(spec)   (spec & (((unsigned long) 1) << 18))
+#define IS_INLINE(spec)     (spec & (((unsigned long) 1) << 19))
+#define DO_FREE(spec)       (!(spec & (((unsigned long) 1) << 20))  && !(spec & (((unsigned long) 1) << 21)))
+#define DO_REALLOC(spec)    ((spec & (((unsigned long) 1) << 20))  && (spec & (((unsigned long) 1) << 21)))
+#define DO_DUP(spec)        ((spec & (((unsigned long) 1) << 20)) && ! (spec & (((unsigned long) 1) << 21)))
+#if CHECK_LEVEL > 0
+//#define DO_CHECK(spec)      1
+#define DO_CHECK(spec)      (spec & (((unsigned long) 1) << 22))
+#define DO_FREE_CHECK(spec) (spec & (((unsigned long) 1) << 23))
+#else
+#define DO_CHECK(spec)      0
+#define DO_FREE_CHECK(spec) 0
+#endif
+#if CHECK_LEVEL > 0 && TRACK_LEVEL > 0
+#define DO_TRACK(spec)      (spec & (((unsigned long) 1) << 24))
+#define GET_TRACK(spec)     (((spec & ((((unsigned long) 1) << 27) | (((unsigned long) 1) << 26) | (((unsigned long) 1) << 25))) >> 25) % 5) + TRACK_LEVEL
+// #define DO_TRACK(spec)      TRACK_LEVEL
+// #define GET_TRACK(spec)     TRACK_LEVEL
+#else
+#define DO_TRACK(spec)      0
+#define GET_TRACK(spec)     0
+#endif
+#if KEEP_LEVEL > 0
+#define DO_KEEP(spec)           (DO_CHECK(spec) && (spec % KEEP_LEVEL == 0))
+#define DO_FREE_KEEP(spec)      (DO_FREE_CHECK(spec) && (spec % KEEP_LEVEL == 0))
+#else
+#define DO_KEEP(spec)       0
+#define DO_FREE_KEEP(spec)  0
+#endif
+
+#define IS_FREE_SIZE(spec)      (spec & (((unsigned long) 1) << 28))
+#define IS_FREE_BIN(spec)       (spec & (((unsigned long) 1) << 29))
+#define IS_SLOPPY(spec)         (spec & (((unsigned long) 1) << 30))
+#define IS_FREE_BINADDR(spec)   (spec & (((unsigned long) 1) << 31))
+
+
+#define SPEC_MAX   ULONG_MAX
+#define SIZE_MAX  ((((unsigned long) 1) << 14) -1)
+#define RANGE_MIN (((unsigned long) 1) << 6)
+#define RANGE_MAX (((unsigned long) 1) << 14)
+
+#define PAGES_PER_REGION 128
+
+void omtTestAlloc(omMemCell cell, unsigned long spec);
+void omtTestRealloc(omMemCell cell, unsigned long spec);
+void omtTestDup(omMemCell cell, unsigned long spec);
+void omtTestFree(omMemCell cell);
+
+void omtTestAllocDebug(omMemCell cell, unsigned long spec);
+void omtTestReallocDebug(omMemCell cell, unsigned long spec);
+void omtTestDupDebug(omMemCell cell, unsigned long spec);
+void omtTestFreeDebug(omMemCell cell);
+
+void omtTestAllocKeep(omMemCell cell, unsigned long spec);
+void omtTestReallocKeep(omMemCell cell, unsigned long spec);
+void omtTestDupKeep(omMemCell cell, unsigned long spec);
+void omtTestFreeKeep(omMemCell cell);
+
+void InitCellAddrContent(omMemCell cell);
+int omtTestErrors();
+omBin omtGetStickyBin(omBin bin);
+
+#if CHECK_LEVEL > 0
+void omtTestDebug(omMemCell cell);
+void TestAddrContent(void* addr, unsigned long value, size_t size);
+void TestAddrContentEqual(void* s1, void* s2, size_t size);
+#else
+#define omtTestDebug(cell)               do {} while (0)
+#define TestAddrContent(a,v,s)          do {} while (0)
+#define TestAddrContentEqual(s1, s2, s) do {} while (0)
+#endif
diff --git a/omalloc/omtTestAlloc.c b/omalloc/omtTestAlloc.c
new file mode 100644
index 0000000..6713f67
--- /dev/null
+++ b/omalloc/omtTestAlloc.c
@@ -0,0 +1,372 @@
+/*******************************************************************
+ *  File:    omtTestAlloc.c
+ *  Purpose: alloc function to be included in omMain.c
+ *  Author:  obachman at mathematik.uni-kl.de (Olaf Bachmann)
+ *  Created: 11/99
+ *******************************************************************/
+#include "omtTest.h"
+
+#ifdef TEST_CHECK
+#define OM_CHECK CHECK_LEVEL
+#define omtTestAlloc   omtTestAllocDebug
+#define omtTestRealloc omtTestReallocDebug
+#define omtTestFree    omtTestFreeDebug
+#define omtTestDup     omtTestDupDebug
+#endif
+
+#ifdef TEST_KEEP
+#define OM_CHECK CHECK_LEVEL
+#define OM_KEEP  1
+#define omtTestAlloc   omtTestAllocKeep
+#define omtTestRealloc omtTestReallocKeep
+#define omtTestFree    omtTestFreeKeep
+#define omtTestDup     omtTestDupKeep
+#endif
+
+#include "omalloc.h"
+
+#ifndef OM_ALIGNMENT_NEEDS_WORK
+#define omSmallSize2AlignedBin omSmallSize2Bin
+#endif
+
+void omtTestAlloc(omMemCell cell, unsigned long spec)
+{
+  size_t size = GET_SIZE(spec);
+  void* addr;
+  omBin bin = NULL;
+  omBin orig_bin = NULL;
+
+  if (IS_BIN(spec) && (size <= OM_MAX_BLOCK_SIZE || IS_SPEC_BIN(spec)))
+  {
+    if (IS_SPEC_BIN(spec))
+    {
+      if (IS_ALIGNED(spec))
+        bin = omGetAlignedSpecBin(size);
+      else
+        bin = omGetSpecBin(size);
+    }
+    else
+    {
+      if (IS_ALIGNED(spec))
+        bin = omSmallSize2AlignedBin(size);
+      else
+        bin = omSmallSize2Bin(size);
+    }
+
+    if (IS_STICKY_BIN(spec))
+    {
+      orig_bin = bin;
+      bin = omtGetStickyBin(bin);
+    }
+
+    if (IS_INLINE(spec))
+    {
+      if (IS_ZERO(spec))
+        addr = omAlloc0Bin(bin);
+      else
+        addr = omAllocBin(bin);
+    }
+    else
+    {
+      if (IS_ZERO(spec))
+        omTypeAlloc0Bin(void*, addr, bin);
+      else
+        omTypeAllocBin(void*, addr, bin);
+    }
+  }
+  else
+  {
+    if (IS_INLINE(spec))
+    {
+      if (IS_ZERO(spec))
+      {
+        if (IS_ALIGNED(spec))
+        {
+          if (IS_SLOPPY(spec))
+            addr = omalloc0(size);
+          else
+            addr = omAlloc0Aligned(size);
+        }
+        else
+          addr = omAlloc0(size);
+      }
+      else
+      {
+        if (IS_ALIGNED(spec))
+        {
+          if (IS_SLOPPY(spec))
+            addr = omalloc(size);
+          else
+            addr = omAllocAligned(size);
+        }
+        else
+          addr = omAlloc(size);
+      }
+    }
+    else
+    {
+      if (IS_ZERO(spec))
+      {
+        if (IS_ALIGNED(spec))
+          omTypeAlloc0Aligned(void*, addr, size);
+        else
+          omTypeAlloc0(void*, addr, size);
+      }
+      else
+      {
+        if (IS_ALIGNED(spec))
+          omTypeAllocAligned(void*, addr, size);
+        else
+          omTypeAlloc(void*, addr, size);
+      }
+    }
+  }
+  cell->addr = addr;
+  cell->bin = bin;
+  cell->orig_bin = orig_bin;
+  cell->spec = spec;
+
+  InitCellAddrContent(cell);
+
+  omtTestDebug(cell);
+}
+
+void omtTestFree(omMemCell cell)
+{
+  void* addr = cell->addr;
+  unsigned long spec = cell->spec;
+  omBin bin = cell->bin;
+  omBin orig_bin = cell->orig_bin;
+  size_t size = GET_SIZE(spec);
+
+  omtTestDebug(cell);
+
+  if (IS_FREE_SIZE(spec))
+  {
+    if (IS_SLOPPY(spec))
+      omfreeSize(addr, size);
+    else
+      omFreeSize(addr, size);
+  }
+  else if (bin != NULL && IS_FREE_BIN(spec))
+    omFreeBin(addr, bin);
+  else if (IS_FREE_BINADDR(spec) && (bin != NULL) && (size <= OM_MAX_BLOCK_SIZE))
+  {
+    omFreeBinAddr(addr);
+  }
+  else
+  {
+    if (IS_SLOPPY(spec))
+      omfree(addr);
+    else
+      omFree(addr);
+  }
+
+  if (bin != NULL && IS_SPEC_BIN(spec))
+  {
+    if (orig_bin != NULL)
+      omUnGetSpecBin(&orig_bin);
+    else
+      omUnGetSpecBin(&bin);
+  }
+
+  cell->addr = NULL;
+  cell->spec = 0;
+  cell->bin = NULL;
+  cell->orig_bin = NULL;
+}
+
+void omtTestRealloc(omMemCell cell, unsigned long new_spec)
+{
+  void* old_addr = cell->addr;
+  unsigned long old_spec = cell->spec;
+  omBin old_bin = cell->bin;
+  omBin old_orig_bin = cell->orig_bin;
+  size_t old_size = GET_SIZE(old_spec);
+  void* new_addr;
+  omBin new_bin = NULL;
+  omBin new_orig_bin = NULL;
+  size_t new_size = GET_SIZE(new_spec);
+  size_t real_old_size = omSizeOfAddr(old_addr);
+  size_t min_size;
+
+  omtTestDebug(cell);
+
+  if (old_bin != NULL && IS_FREE_BIN(old_spec) &&
+      IS_BIN(new_spec) && ((new_size <= OM_MAX_BLOCK_SIZE) || IS_SPEC_BIN(new_spec)))
+  {
+    if (IS_SPEC_BIN(new_spec))
+    {
+      if (IS_ALIGNED(new_spec))
+        new_bin = omGetAlignedSpecBin(new_size);
+      else
+        new_bin = omGetSpecBin(new_size);
+    }
+    else
+    {
+      if (IS_ALIGNED(new_spec))
+        new_bin = omSmallSize2AlignedBin(new_size);
+      else
+        new_bin = omSmallSize2Bin(new_size);
+    }
+
+    if (IS_STICKY_BIN(new_spec))
+    {
+      new_orig_bin = new_bin;
+      new_bin = omtGetStickyBin(new_bin);
+    }
+
+    if (IS_INLINE(new_spec))
+    {
+      if (IS_ZERO(new_spec)) new_addr = omRealloc0Bin(old_addr, old_bin, new_bin);
+      else new_addr = omReallocBin(old_addr, old_bin, new_bin);
+    }
+    else
+    {
+      if (IS_ZERO(new_spec)) omTypeRealloc0Bin(old_addr, old_bin, void*, new_addr, new_bin);
+      else omTypeReallocBin(old_addr, old_bin, void*, new_addr, new_bin);
+    }
+  }
+  else
+  {
+    if (IS_FREE_SIZE(old_spec))
+    {
+      if (IS_INLINE(new_spec))
+      {
+        if (IS_ZERO(new_spec))
+        {
+          if (IS_ALIGNED(new_spec))
+          {
+            if (IS_SLOPPY(new_spec))
+              new_addr = omrealloc0Size(old_addr, old_size, new_size);
+            else
+              new_addr = omRealloc0AlignedSize(old_addr, old_size, new_size);
+          }
+          else
+            new_addr = omRealloc0Size(old_addr, old_size, new_size);
+        }
+        else
+        {
+          if (IS_ALIGNED(new_spec))
+          {
+            if (IS_SLOPPY(new_spec))
+              new_addr = omreallocSize(old_addr, old_size, new_size);
+            else
+              new_addr = omReallocAlignedSize(old_addr, old_size, new_size);
+          }
+          else  new_addr = omReallocSize(old_addr, old_size, new_size);
+        }
+      }
+      else
+      {
+        if (IS_ZERO(new_spec))
+        {
+          if (IS_ALIGNED(new_spec)) omTypeRealloc0AlignedSize(old_addr, old_size, void*, new_addr, new_size);
+          else  omTypeRealloc0Size(old_addr, old_size, void*, new_addr, new_size);
+        }
+        else
+        {
+          if (IS_ALIGNED(new_spec))  omTypeReallocAlignedSize(old_addr, old_size, void*, new_addr, new_size);
+          else  omTypeReallocSize(old_addr, old_size, void*, new_addr, new_size);
+        }
+      }
+    }
+    else
+    {
+      if (IS_INLINE(new_spec))
+      {
+        if (IS_ZERO(new_spec))
+        {
+          if (IS_ALIGNED(new_spec))
+          {
+            if (IS_SLOPPY(new_spec))
+              new_addr = omrealloc0(old_addr, new_size);
+            else
+              new_addr = omRealloc0Aligned(old_addr, new_size);
+          }
+          else  new_addr = omRealloc0(old_addr, new_size);
+        }
+        else
+        {
+          if (IS_ALIGNED(new_spec))
+          {
+            if (IS_SLOPPY(new_spec))
+              new_addr = omrealloc(old_addr, new_size);
+            else
+              new_addr = omReallocAligned(old_addr, new_size);
+          }
+          else  new_addr = omRealloc(old_addr, new_size);
+        }
+      }
+      else
+      {
+        if (IS_ZERO(new_spec))
+        {
+          if (IS_ALIGNED(new_spec)) omTypeRealloc0Aligned(old_addr, void*, new_addr, new_size);
+          else  omTypeRealloc0(old_addr, void*, new_addr, new_size);
+        }
+        else
+        {
+          if (IS_ALIGNED(new_spec))  omTypeReallocAligned(old_addr, void*, new_addr, new_size);
+          else  omTypeRealloc(old_addr, void*, new_addr, new_size);
+        }
+      }
+    }
+  }
+
+  if (old_bin != NULL && IS_SPEC_BIN(old_spec))
+  {
+    if (old_orig_bin != NULL)
+      omUnGetSpecBin(&old_orig_bin);
+    else
+      omUnGetSpecBin(&old_bin);
+  }
+
+  new_size = omSizeOfAddr(new_addr);
+  old_size = real_old_size;
+  min_size = (new_size < old_size ? new_size : old_size);
+
+  if (IS_ZERO(old_spec) && IS_ZERO(new_spec))
+    TestAddrContent(new_addr, 0, new_size);
+  else
+  {
+    TestAddrContent(new_addr, (IS_ZERO(old_spec) ? 0 : old_spec), min_size);
+    if (IS_ZERO(new_spec) &&  old_size < new_size)
+      TestAddrContent((char *)new_addr + old_size, 0, new_size - old_size);
+  }
+
+  cell->addr = new_addr;
+  cell->spec = new_spec;
+  cell->bin = new_bin;
+  cell->orig_bin = new_orig_bin;
+  InitCellAddrContent(cell);
+  omtTestDebug(cell);
+}
+
+#define DO_STRDUP(l) (l & 1)
+void omtTestDup(omMemCell cell, unsigned long spec)
+{
+  omtTestDebug(cell);
+
+  if (DO_STRDUP(spec))
+  {
+    size_t size = omSizeOfAddr(cell->addr);
+    void* new_addr;
+    memset(cell->addr, 'a', size - 1);
+    ((char*) cell->addr)[size-1] = '\0';
+    new_addr = omStrDup(cell->addr);
+    TestAddrContentEqual(new_addr, cell->addr, size);
+    omFree(new_addr);
+    InitCellAddrContent(cell);
+  }
+  else
+  {
+    void* new_addr = omMemDup(cell->addr);
+    TestAddrContentEqual(new_addr, cell->addr, omSizeOfAddr(cell->addr));
+    omFree(new_addr);
+    new_addr = omMemDupAligned(cell->addr);
+    TestAddrContentEqual(new_addr, cell->addr, omSizeOfAddr(cell->addr));
+    omDebugAddrAlignedSize(new_addr,  omSizeOfAddr(cell->addr));
+    omFree(new_addr);
+  }
+}
diff --git a/omalloc/omtTestDebug.c b/omalloc/omtTestDebug.c
new file mode 100644
index 0000000..5ea423e
--- /dev/null
+++ b/omalloc/omtTestDebug.c
@@ -0,0 +1,2 @@
+#define TEST_CHECK
+#include <omalloc/omtTestAlloc.c>
diff --git a/omalloc/omtTestError.c b/omalloc/omtTestError.c
new file mode 100644
index 0000000..a57916a
--- /dev/null
+++ b/omalloc/omtTestError.c
@@ -0,0 +1,436 @@
+#include "omtTest.h"
+#define OM_CHECK 1
+#include "omalloc.h"
+
+struct LongSpec
+{
+  int MaxSize;
+  int MinSize;
+  int MinTrack;
+  int NotIsBin;
+  int NoTrack;
+  int NotZero;
+};
+
+omMemCell omFindCell(struct LongSpec spec)
+{
+  int i;
+  for (i=0; i<MAX_CELLS; i++)
+  {
+    if ((cells[i].addr != NULL) &&
+        (spec.MinTrack == 0 || (DO_CHECK(cells[i].spec) &&
+                                DO_TRACK(cells[i].spec) &&
+                                GET_TRACK(cells[i].spec) >= spec.MinTrack)) &&
+        (spec.MinSize == 0  || GET_SIZE(cells[i].spec) >= spec.MinSize) &&
+        (spec.MaxSize == 0  || GET_SIZE(cells[i].spec) <= spec.MaxSize) &&
+        (spec.NotIsBin == 0 || cells[i].bin == NULL) &&
+        (spec.NotZero == 0  || !IS_ZERO(cells[i].spec)) &&
+        (spec.NoTrack == 0  || !DO_CHECK(cells[i].spec) || !DO_TRACK(cells[i].spec)))
+    {
+      return &cells[i];
+    }
+  }
+  return NULL;
+}
+
+int omtTestErrors()
+{
+#ifndef OM_NDEBUG
+  int level = om_Opts.MinCheck;
+  omError_t error;
+  struct LongSpec spec;
+  int missed = 0, alloc;
+  omMemCell cell = NULL;
+
+  printf("omtTestErrors: Start\n");
+  om_Opts.MinCheck = 2;
+  for (error = omError_MemoryCorrupted; error < omError_MaxError; error++)
+  {
+    om_InternalErrorStatus = omError_NoError;
+    om_ErrorStatus = omError_NoError;
+    printf("!!!expect %s\n", omError2Serror(error));
+    memset(&spec, 0, sizeof(struct LongSpec));
+    cell = NULL;
+    alloc = 0;
+    switch (error)
+    {
+        case omError_MemoryCorrupted:
+        {
+          spec.MaxSize = OM_MAX_BLOCK_SIZE;
+          cell = omFindCell(spec);
+          if (cell != NULL)
+          {
+            omBin bin = omGetTopBinOfAddr(cell->addr);
+            omBinPage last_page = bin->last_page;
+            omAssume(last_page != NULL);
+            bin->last_page = NULL;
+            omDebugBin(cell->bin);
+            bin->last_page = last_page;
+          }
+          else printf("cell not found\n");
+          break;
+        }
+
+        case omError_NullAddr:
+        {
+          omDebugAddr(NULL);
+          break;
+        }
+
+        case omError_InvalidRangeAddr:
+        {
+          omDebugAddr((void*) om_MaxAddr);
+          break;
+        }
+
+        case omError_FalseAddr:
+        {
+          spec.MinSize = 8;
+          spec.MaxSize = OM_MAX_BLOCK_SIZE;
+          spec.NoTrack = 1;
+          cell = omFindCell(spec);
+          if (cell != NULL)
+          {
+            omDebugAddr(cell->addr + SIZEOF_VOIDP);
+          }
+          else printf("cell not found\n");
+          break;
+        }
+
+        case omError_FalseAddrOrMemoryCorrupted:
+        {
+          spec.MinSize = 8;
+          spec.MinTrack = 3;
+          cell = omFindCell(spec);
+          if (cell != NULL)
+          {
+            omDebugAddr(cell->addr + SIZEOF_VOIDP);
+          }
+          else printf("cell not found\n");
+          break;
+        }
+
+        case omError_WrongSize:
+        {
+          spec.MaxSize = OM_MAX_BLOCK_SIZE;
+          cell = omFindCell(spec);
+          if (cell != NULL)
+          {
+            omDebugAddrSize(cell->addr, OM_MAX_BLOCK_SIZE + 1);
+            if (om_ErrorStatus != omError_NoError)
+            {
+              om_ErrorStatus = omError_NoError;
+              spec.MaxSize = 0;
+              spec.MinTrack = 3;
+              spec.NotIsBin = 1;
+              spec.MinSize = 2;
+              cell = omFindCell(spec);
+              if (cell != NULL)
+              {
+                omDebugAddrSize(cell->addr, GET_SIZE(cell->spec) + SIZEOF_OM_ALIGNMENT);
+                if (om_ErrorStatus != omError_NoError)
+                {
+                  om_ErrorStatus = omError_NoError;
+                  spec.MaxSize = OM_MAX_BLOCK_SIZE;
+                  spec.MinTrack = 0;
+                  spec.NotIsBin = 0;
+                  cell = omFindCell(spec);
+                  if (cell != NULL)
+                    omDebugBinAddrSize(cell->addr, GET_SIZE(cell->spec) - 1);
+                  else printf("cell not found");
+                }
+              }
+              else printf("cell not found\n");
+            }
+          }
+          else printf("cell not found\n");
+          break;
+        }
+
+        case omError_FreedAddr:
+        {
+#if KEEP_LEVEL > 0
+          void* addr = om_AlwaysKeptAddrs;
+          while (addr != NULL && omIsTrackAddr(addr))
+          {
+            addr = *((void**) addr);
+          }
+          if (addr != NULL)
+          {
+            omFree(addr);
+            if (om_ErrorStatus == omError_FreedAddr)
+            {
+              om_ErrorStatus = omError_NoError;
+              addr = om_AlwaysKeptAddrs;
+               while (addr != NULL && ! omIsTrackAddr(addr))
+               {
+                 addr = *((void**) addr);
+               }
+               if (addr != NULL)
+               {
+                 addr = omAddr_2_OutAddr(addr);
+                 omFree(addr);
+               }
+            }
+          }
+          if (addr == NULL)
+          {
+            printf("addr not found\n");
+            break;
+          }
+          if (om_ErrorStatus != omError_FreedAddr)
+            break;
+#endif
+          spec.MinTrack = 5;
+          spec.NotIsBin = 1;
+          cell = omFindCell(spec);
+          if (cell != NULL)
+          {
+            omFree(cell->addr);
+            omFree(cell->addr);
+            alloc = 1;
+            cell->addr=NULL;
+          }
+          else printf("cell not found\n");
+          break;
+        }
+
+        case omError_FreedAddrOrMemoryCorrupted:
+        {
+          spec.MaxSize = OM_MAX_BLOCK_SIZE;
+          spec.NoTrack = 1;
+          cell = omFindCell(spec);
+          if (cell != NULL)
+          {
+            omBinPage page = omGetBinPageOfAddr(cell->addr);
+            omBinPageRegion region = page->region;
+            page->region = NULL;
+            om_Opts.MinCheck = 1;
+            omDebugAddr(cell->addr);
+            om_Opts.MinCheck = 2;
+            page->region = region;
+          }
+          else printf("cell not found\n");
+          break;
+        }
+
+        case omError_WrongBin:
+        {
+          spec.MaxSize = 32;
+          spec.NoTrack = 1;
+          cell = omFindCell(spec);
+          if (cell != NULL)
+          {
+            omDebugAddrBin(cell->addr, &om_StaticBin[OM_MAX_BIN_INDEX]);
+          }
+          else printf("cell not found\n");
+          break;
+        }
+
+        case omError_UnknownBin:
+        {
+          spec.MaxSize = OM_MAX_BLOCK_SIZE;
+          cell = omFindCell(spec);
+          if (cell != NULL)
+          {
+            omDebugAddrBin(cell->addr, (void*) omGetTopBinOfAddr(cell->addr) + SIZEOF_VOIDP);
+          }
+          else printf("cell not found\n");
+          break;
+        }
+
+        case omError_NotBinAddr:
+        {
+          spec.NotIsBin = 1;
+          spec.MinSize = OM_MAX_BLOCK_SIZE + 1;
+          cell = omFindCell(spec);
+          if (cell != NULL)
+          {
+            omDebugBinAddr(cell->addr);
+          }
+          else printf("cell not found");
+          break;
+        }
+
+        case omError_UnalignedAddr:
+        {
+          cell = omFindCell(spec);
+          if (cell != NULL)
+          {
+            omDebugAddr(cell->addr + 1);
+          }
+          else printf("cell not found\n");
+          break;
+        }
+
+        case omError_NullSizeAlloc:
+        {
+          void* addr = omAlloc(0);
+          addr = omRealloc(addr, 0);
+          omFree(addr);
+          break;
+        }
+
+        case omError_ListCycleError:
+        {
+          void* last = omListLast(om_SpecBin);
+          if (last != NULL)
+          {
+            *((void**)last) = om_SpecBin;
+            omCheckList(om_SpecBin, 5, omError_NoError, OM_FLR);
+            *((void**)last) = NULL;
+          } else printf("last == NULL\n");
+          break;
+        }
+
+        case omError_SortedListError:
+        {
+          if (om_SpecBin != NULL && om_SpecBin->next != NULL)
+          {
+            int max_blocks = om_SpecBin->max_blocks;
+            om_SpecBin->max_blocks = om_SpecBin->next->max_blocks + 1;
+            omCheckSortedList(om_SpecBin, max_blocks, 5, omError_NoError, OM_FLR);
+            om_SpecBin->max_blocks = max_blocks;
+          } else printf("om_SpecBin->next == NULL\n");
+          break;
+        }
+
+        case omError_KeptAddrListCorrupted:
+        {
+          if (om_KeptAddr != NULL)
+          {
+            void* last = omListLast(om_KeptAddr);
+            *((void**)last) = om_KeptAddr;
+            om_Opts.MinCheck = 5;
+            omDebugMemory();
+            om_Opts.MinCheck = 2;
+            *((void**)last) = NULL;
+          }
+          else printf("om_KeptAddr == NULL\n");
+          break;
+        }
+
+        case omError_FreePattern:
+        {
+          if (om_Opts.Keep > 0)
+          {
+            spec.MinTrack=3;
+            spec.NotIsBin = 1;
+            cell = omFindCell(spec);
+            if (cell != NULL)
+            {
+              void* value;
+              omFree(cell->addr);
+              value = *((void**) cell->addr);
+              *((void**) cell->addr) = value -1;
+              omDebugMemory();
+              *((void**) cell->addr) = value;
+              alloc = 1;
+              cell->addr = NULL;
+            }
+            else printf("cell not found\n");
+          }
+          else printf("om_Opts.Keep == 0");
+          break;
+        }
+
+        case omError_BackPattern:
+        {
+          spec.MinTrack = 3;
+          spec.NotIsBin = 1;
+          cell = omFindCell(spec);
+          if (cell != NULL)
+          {
+            void* addr = cell->addr + omSizeOfAddr(cell->addr);
+            void* value = *((void**) addr);
+            *((void**) addr) = value -1;
+            omDebugAddr(cell->addr);
+            *((void**) addr) = value;
+          }
+          else printf("cell not found\n");
+          break;
+        }
+
+        case omError_FrontPattern:
+        {
+          spec.MinTrack=3;
+          cell = omFindCell(spec);
+          if (cell != NULL)
+          {
+            void* addr = cell->addr - SIZEOF_VOIDP;
+            void* value = *((void**) addr);
+            *((void**) addr) = value -1;
+            omDebugAddr(cell->addr);
+            *((void**) addr) = value;
+          }
+          else printf("cell not found\n");
+          break;
+        }
+
+        case omError_NotString:
+        {
+/* can only test for NULL string */
+#if 0
+          spec.MaxSize = OM_MAX_BLOCK_SIZE;
+          cell = omFindCell(spec);
+          if (cell != NULL)
+          {
+            char* addr = (char*) cell->addr;
+            char* s;
+            memset(cell->addr, 1, omSizeOfAddr(cell->addr));
+            omDebugAddr(cell->addr);
+            s = omStrDup(addr);
+            omFree(s);
+            InitCellAddrContent(cell);
+          }
+          else printf("cell not found\n");
+          break;
+#endif
+          omStrDup(NULL);
+          break;
+        }
+
+        case omError_StickyBin:
+        {
+          omMergeStickyBinIntoBin(NULL, NULL);
+          break;
+        }
+
+        default:
+          printf("No Error test implemented\n");
+    }
+
+    if (om_ErrorStatus != error)
+    {
+      printf("---missed %s\n", omError2Serror(error));
+      missed++;
+    }
+    else
+    {
+      printf("+++ok  %s\n", omError2Serror(error));
+    }
+
+    om_ErrorStatus = omError_NoError;
+    if (cell != NULL)
+    {
+      if (alloc) TestAlloc(cell, cell->spec);
+      omtTestDebug(cell);
+    }
+    else
+    {
+      omDebugMemory();
+    }
+    if (om_ErrorStatus != omError_NoError)
+    {
+      printf("omtTest panik: memory corrupted\n\n");
+      return -1;
+    }
+    printf("\n");
+  }
+  printf("omtTestErrors: Summary: missed = %d\n\n", missed);
+  om_Opts.MinCheck = level;
+  return missed;
+#else
+  return 0;
+#endif
+}
diff --git a/omalloc/omtTestKeep.c b/omalloc/omtTestKeep.c
new file mode 100644
index 0000000..aa358d2
--- /dev/null
+++ b/omalloc/omtTestKeep.c
@@ -0,0 +1,2 @@
+#define TEST_KEEP
+#include <omalloc/omtTestAlloc.c>
diff --git a/omalloc/omtTestReal.c b/omalloc/omtTestReal.c
new file mode 100644
index 0000000..38baf1a
--- /dev/null
+++ b/omalloc/omtTestReal.c
@@ -0,0 +1 @@
+#include <omalloc/omtTestAlloc.c>
diff --git a/resources/Makefile.am b/resources/Makefile.am
new file mode 100644
index 0000000..fa69ccc
--- /dev/null
+++ b/resources/Makefile.am
@@ -0,0 +1,24 @@
+ACLOCAL_AMFLAGS = -I ../m4
+
+libresources_LTLIBRARIES = libresources.la
+
+libresourcesdir = $(libdir)
+
+
+AM_CPPFLAGS = -I${top_srcdir} -I${top_builddir}
+
+
+SOURCES  = omFindExec.c feResource.cc feFopen.cc
+libresources_la_SOURCES   = $(SOURCES)
+
+libresources_la_LDFLAGS   = -release ${PACKAGE_VERSION}
+
+libresources_includedir  =$(includedir)/resources
+
+libresources_include_HEADERS = omFindExec.h feResource.h feFopen.h
+
+nodist_libresources_include_HEADERS = resourcesconfig.h
+DISTCLEANFILES = $(nodist_libresources_include_HEADERS)
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = resources.pc
diff --git a/resources/Makefile.in b/resources/Makefile.in
new file mode 100644
index 0000000..1fdd698
--- /dev/null
+++ b/resources/Makefile.in
@@ -0,0 +1,987 @@
+# Makefile.in generated by automake 1.13.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 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@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+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 = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/configure $(am__configure_deps) \
+	$(srcdir)/_config.h.in $(srcdir)/resources.pc.in \
+	$(top_srcdir)/../build-aux/depcomp \
+	$(libresources_include_HEADERS) ../build-aux/ar-lib \
+	../build-aux/compile ../build-aux/config.guess \
+	../build-aux/config.sub ../build-aux/depcomp \
+	../build-aux/install-sh ../build-aux/missing \
+	../build-aux/ylwrap ../build-aux/ltmain.sh \
+	$(top_srcdir)/../build-aux/ar-lib \
+	$(top_srcdir)/../build-aux/compile \
+	$(top_srcdir)/../build-aux/config.guess \
+	$(top_srcdir)/../build-aux/config.sub \
+	$(top_srcdir)/../build-aux/install-sh \
+	$(top_srcdir)/../build-aux/ltmain.sh \
+	$(top_srcdir)/../build-aux/missing
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/../m4/ax_append_compile_flags.m4 \
+	$(top_srcdir)/../m4/ax_append_flag.m4 \
+	$(top_srcdir)/../m4/ax_append_link_flags.m4 \
+	$(top_srcdir)/../m4/ax_check_compile_flag.m4 \
+	$(top_srcdir)/../m4/ax_check_link_flag.m4 \
+	$(top_srcdir)/../m4/ax_compute_relative_paths.m4 \
+	$(top_srcdir)/../m4/ax_normalize_path.m4 \
+	$(top_srcdir)/../m4/ax_prefix_config_h.m4 \
+	$(top_srcdir)/../m4/flags.m4 $(top_srcdir)/../m4/libtool.m4 \
+	$(top_srcdir)/../m4/ltoptions.m4 \
+	$(top_srcdir)/../m4/ltsugar.m4 \
+	$(top_srcdir)/../m4/ltversion.m4 \
+	$(top_srcdir)/../m4/lt~obsolete.m4 $(top_srcdir)/configure.ac
+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 = resources.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__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
+am__installdirs = "$(DESTDIR)$(libresourcesdir)" \
+	"$(DESTDIR)$(pkgconfigdir)" \
+	"$(DESTDIR)$(libresources_includedir)" \
+	"$(DESTDIR)$(libresources_includedir)"
+LTLIBRARIES = $(libresources_LTLIBRARIES)
+libresources_la_LIBADD =
+am__objects_1 = omFindExec.lo feResource.lo feFopen.lo
+am_libresources_la_OBJECTS = $(am__objects_1)
+libresources_la_OBJECTS = $(am_libresources_la_OBJECTS)
+AM_V_lt = $(am__v_lt_ at AM_V@)
+am__v_lt_ = $(am__v_lt_ at AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 = 
+libresources_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
+	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
+	$(AM_CXXFLAGS) $(CXXFLAGS) $(libresources_la_LDFLAGS) \
+	$(LDFLAGS) -o $@
+AM_V_P = $(am__v_P_ at AM_V@)
+am__v_P_ = $(am__v_P_ at AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_ at AM_V@)
+am__v_GEN_ = $(am__v_GEN_ at AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_ at AM_V@)
+am__v_at_ = $(am__v_at_ at AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+DEFAULT_INCLUDES = -I. at am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/../build-aux/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+	$(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_ at AM_V@)
+am__v_CC_ = $(am__v_CC_ at AM_DEFAULT_V@)
+am__v_CC_0 = @echo "  CC      " $@;
+am__v_CC_1 = 
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+	$(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_ at AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_ at AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo "  CCLD    " $@;
+am__v_CCLD_1 = 
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \
+	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+	$(AM_CXXFLAGS) $(CXXFLAGS)
+AM_V_CXX = $(am__v_CXX_ at AM_V@)
+am__v_CXX_ = $(am__v_CXX_ at AM_DEFAULT_V@)
+am__v_CXX_0 = @echo "  CXX     " $@;
+am__v_CXX_1 = 
+CXXLD = $(CXX)
+CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+	$(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CXXLD = $(am__v_CXXLD_ at AM_V@)
+am__v_CXXLD_ = $(am__v_CXXLD_ at AM_DEFAULT_V@)
+am__v_CXXLD_0 = @echo "  CXXLD   " $@;
+am__v_CXXLD_1 = 
+DIST_SOURCES = $(libresources_la_SOURCES)
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+DATA = $(pkgconfig_DATA)
+HEADERS = $(libresources_include_HEADERS) \
+	$(nodist_libresources_include_HEADERS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \
+	$(LISP)_config.h.in
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+CSCOPE = cscope
+AM_RECURSIVE_TARGETS = cscope
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+distdir = $(PACKAGE)-$(VERSION)
+top_distdir = $(distdir)
+am__remove_distdir = \
+  if test -d "$(distdir)"; then \
+    find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \
+      && rm -rf "$(distdir)" \
+      || { sleep 5 && rm -rf "$(distdir)"; }; \
+  else :; fi
+am__post_remove_distdir = $(am__remove_distdir)
+DIST_ARCHIVES = $(distdir).tar.gz
+GZIP_ENV = --best
+DIST_TARGETS = dist-gzip
+distuninstallcheck_listfiles = find . -type f -print
+am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \
+  | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$'
+distcleancheck_listfiles = find . -type f -print
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+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@
+FGREP = @FGREP@
+GREP = @GREP@
+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@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+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@
+POLYMAKE_CXXFLAGS = @POLYMAKE_CXXFLAGS@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SINGULAR_CFLAGS = @SINGULAR_CFLAGS@
+STRIP = @STRIP@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+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@
+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@
+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@
+ACLOCAL_AMFLAGS = -I ../m4
+libresources_LTLIBRARIES = libresources.la
+libresourcesdir = $(libdir)
+AM_CPPFLAGS = -I${top_srcdir} -I${top_builddir}
+SOURCES = omFindExec.c feResource.cc feFopen.cc
+libresources_la_SOURCES = $(SOURCES)
+libresources_la_LDFLAGS = -release ${PACKAGE_VERSION}
+libresources_includedir = $(includedir)/resources
+libresources_include_HEADERS = omFindExec.h feResource.h feFopen.h
+nodist_libresources_include_HEADERS = resourcesconfig.h
+DISTCLEANFILES = $(nodist_libresources_include_HEADERS)
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = resources.pc
+all: _config.h
+	$(MAKE) $(AM_MAKEFLAGS) all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .cc .lo .o .obj
+am--refresh: Makefile
+	@:
+$(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) --foreign'; \
+	      $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \
+		&& exit 0; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign 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; else :; fi
+	@if test ! -f $@; then $(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
+resources.pc: $(top_builddir)/config.status $(srcdir)/resources.pc.in
+	cd $(top_builddir) && $(SHELL) ./config.status $@
+
+install-libresourcesLTLIBRARIES: $(libresources_LTLIBRARIES)
+	@$(NORMAL_INSTALL)
+	@list='$(libresources_LTLIBRARIES)'; test -n "$(libresourcesdir)" || list=; \
+	list2=; for p in $$list; do \
+	  if test -f $$p; then \
+	    list2="$$list2 $$p"; \
+	  else :; fi; \
+	done; \
+	test -z "$$list2" || { \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(libresourcesdir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(libresourcesdir)" || exit 1; \
+	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libresourcesdir)'"; \
+	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libresourcesdir)"; \
+	}
+
+uninstall-libresourcesLTLIBRARIES:
+	@$(NORMAL_UNINSTALL)
+	@list='$(libresources_LTLIBRARIES)'; test -n "$(libresourcesdir)" || list=; \
+	for p in $$list; do \
+	  $(am__strip_dir) \
+	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libresourcesdir)/$$f'"; \
+	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libresourcesdir)/$$f"; \
+	done
+
+clean-libresourcesLTLIBRARIES:
+	-test -z "$(libresources_LTLIBRARIES)" || rm -f $(libresources_LTLIBRARIES)
+	@list='$(libresources_LTLIBRARIES)'; \
+	locs=`for p in $$list; do echo $$p; done | \
+	      sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+	      sort -u`; \
+	test -z "$$locs" || { \
+	  echo rm -f $${locs}; \
+	  rm -f $${locs}; \
+	}
+
+libresources.la: $(libresources_la_OBJECTS) $(libresources_la_DEPENDENCIES) $(EXTRA_libresources_la_DEPENDENCIES) 
+	$(AM_V_CXXLD)$(libresources_la_LINK) -rpath $(libresourcesdir) $(libresources_la_OBJECTS) $(libresources_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/feFopen.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/feResource.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/omFindExec.Plo at am__quote@
+
+.c.o:
+ at am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+ at am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+ at am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+ at am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+ at am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+ at am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+ at am__fastdepCC_TRUE@	$(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+.cc.o:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+ at am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXXCOMPILE) -c -o $@ $<
+
+.cc.obj:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+ at am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.cc.lo:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+ at am__fastdepCXX_TRUE@	$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LTCXXCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+
+distclean-libtool:
+	-rm -f libtool config.lt
+install-pkgconfigDATA: $(pkgconfig_DATA)
+	@$(NORMAL_INSTALL)
+	@list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(pkgconfigdir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" || exit 1; \
+	fi; \
+	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|^.*/||'`; \
+	dir='$(DESTDIR)$(pkgconfigdir)'; $(am__uninstall_files_from_dir)
+install-libresources_includeHEADERS: $(libresources_include_HEADERS)
+	@$(NORMAL_INSTALL)
+	@list='$(libresources_include_HEADERS)'; test -n "$(libresources_includedir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(libresources_includedir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(libresources_includedir)" || exit 1; \
+	fi; \
+	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)$(libresources_includedir)'"; \
+	  $(INSTALL_HEADER) $$files "$(DESTDIR)$(libresources_includedir)" || exit $$?; \
+	done
+
+uninstall-libresources_includeHEADERS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(libresources_include_HEADERS)'; test -n "$(libresources_includedir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	dir='$(DESTDIR)$(libresources_includedir)'; $(am__uninstall_files_from_dir)
+install-nodist_libresources_includeHEADERS: $(nodist_libresources_include_HEADERS)
+	@$(NORMAL_INSTALL)
+	@list='$(nodist_libresources_include_HEADERS)'; test -n "$(libresources_includedir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(libresources_includedir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(libresources_includedir)" || exit 1; \
+	fi; \
+	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)$(libresources_includedir)'"; \
+	  $(INSTALL_HEADER) $$files "$(DESTDIR)$(libresources_includedir)" || exit $$?; \
+	done
+
+uninstall-nodist_libresources_includeHEADERS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(nodist_libresources_include_HEADERS)'; test -n "$(libresources_includedir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	dir='$(DESTDIR)$(libresources_includedir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	$(am__define_uniq_tagged_files); \
+	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-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	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"
+cscope: cscope.files
+	test ! -s cscope.files \
+	  || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS)
+clean-cscope:
+	-rm -f cscope.files
+cscope.files: clean-cscope cscopelist
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+	-rm -f cscope.out cscope.in.out cscope.po.out cscope.files
+
+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
+	-test -n "$(am__skip_mode_fix)" \
+	|| find "$(distdir)" -type d ! -perm -755 \
+		-exec chmod u+rwx,go+rx {} \; -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__post_remove_distdir)
+
+dist-bzip2: distdir
+	tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2
+	$(am__post_remove_distdir)
+
+dist-lzip: distdir
+	tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz
+	$(am__post_remove_distdir)
+
+dist-xz: distdir
+	tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz
+	$(am__post_remove_distdir)
+
+dist-tarZ: distdir
+	tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
+	$(am__post_remove_distdir)
+
+dist-shar: distdir
+	shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
+	$(am__post_remove_distdir)
+
+dist-zip: distdir
+	-rm -f $(distdir).zip
+	zip -rq $(distdir).zip $(distdir)
+	$(am__post_remove_distdir)
+
+dist dist-all:
+	$(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:'
+	$(am__post_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) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\
+	*.tar.bz2*) \
+	  bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
+	*.tar.lz*) \
+	  lzip -dc $(distdir).tar.lz | $(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) gzip -dc $(distdir).shar.gz | unshar ;;\
+	*.zip*) \
+	  unzip $(distdir).zip ;;\
+	esac
+	chmod -R a-w $(distdir)
+	chmod u+w $(distdir)
+	mkdir $(distdir)/_build $(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" \
+	    $(AM_DISTCHECK_CONFIGURE_FLAGS) \
+	    $(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__post_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:
+	@test -n '$(distuninstallcheck_dir)' || { \
+	  echo 'ERROR: trying to run $@ with an empty' \
+	       '$$(distuninstallcheck_dir)' >&2; \
+	  exit 1; \
+	}; \
+	$(am__cd) '$(distuninstallcheck_dir)' || { \
+	  echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \
+	  exit 1; \
+	}; \
+	test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \
+	   || { 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-am
+all-am: Makefile $(LTLIBRARIES) $(DATA) $(HEADERS) _config.h
+installdirs:
+	for dir in "$(DESTDIR)$(libresourcesdir)" "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(libresources_includedir)" "$(DESTDIR)$(libresources_includedir)"; 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:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+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)
+	-test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
+
+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-libresourcesLTLIBRARIES clean-libtool \
+	mostlyclean-am
+
+distclean: distclean-am
+	-rm -f $(am__CONFIG_DISTCLEAN_FILES)
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+	distclean-hdr distclean-libtool distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-libresourcesLTLIBRARIES \
+	install-libresources_includeHEADERS \
+	install-nodist_libresources_includeHEADERS \
+	install-pkgconfigDATA
+
+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 $(am__CONFIG_DISTCLEAN_FILES)
+	-rm -rf $(top_srcdir)/autom4te.cache
+	-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-libresourcesLTLIBRARIES \
+	uninstall-libresources_includeHEADERS \
+	uninstall-nodist_libresources_includeHEADERS \
+	uninstall-pkgconfigDATA
+
+.MAKE: all install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am am--refresh check check-am clean \
+	clean-cscope clean-generic clean-libresourcesLTLIBRARIES \
+	clean-libtool cscope cscopelist-am ctags ctags-am dist \
+	dist-all dist-bzip2 dist-gzip dist-lzip dist-shar dist-tarZ \
+	dist-xz dist-zip distcheck distclean distclean-compile \
+	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-libresourcesLTLIBRARIES \
+	install-libresources_includeHEADERS install-man \
+	install-nodist_libresources_includeHEADERS install-pdf \
+	install-pdf-am install-pkgconfigDATA 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 tags-am uninstall uninstall-am \
+	uninstall-libresourcesLTLIBRARIES \
+	uninstall-libresources_includeHEADERS \
+	uninstall-nodist_libresources_includeHEADERS \
+	uninstall-pkgconfigDATA
+
+
+# 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/resources/_config.h.in b/resources/_config.h.in
new file mode 100644
index 0000000..27c0db0
--- /dev/null
+++ b/resources/_config.h.in
@@ -0,0 +1,141 @@
+/* _config.h.in.  Generated from configure.ac by autoheader.  */
+
+/* bindir */
+#undef BIN_DIR
+
+/* datadir */
+#undef DATA_DIR
+
+/* exec_prefix */
+#undef EXEC_PREFIX
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
+
+/* Define to 1 if you have the `getcwd' function. */
+#undef HAVE_GETCWD
+
+/* Define to 1 if you have the `getpwnam' function. */
+#undef HAVE_GETPWNAM
+
+/* Define to 1 if you have the `getwd' function. */
+#undef HAVE_GETWD
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if your system has a GNU libc compatible `malloc' function, and
+   to 0 otherwise. */
+#undef HAVE_MALLOC
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the `putenv' function. */
+#undef HAVE_PUTENV
+
+/* Define to 1 if you have the <pwd.h> header file. */
+#undef HAVE_PWD_H
+
+/* Define to 1 if you have the `readlink' function. */
+#undef HAVE_READLINK
+
+/* Define to 1 if you have the `setenv' function. */
+#undef HAVE_SETENV
+
+/* Define to 1 if stdbool.h conforms to C99. */
+#undef HAVE_STDBOOL_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/param.h> header file. */
+#undef HAVE_SYS_PARAM_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 1 if the system has the type `_Bool'. */
+#undef HAVE__BOOL
+
+/* libexecdir */
+#undef LIBEXEC_DIR
+
+/* libdir */
+#undef LIB_DIR
+
+/* Define to the sub-directory in which libtool stores uninstalled libraries.
+   */
+#undef LT_OBJDIR
+
+/* Define to 1 if your C compiler doesn't accept -c and -o together. */
+#undef NO_MINUS_C_MINUS_O
+
+/* "Disable OM Debug" */
+#undef OM_NDEBUG
+
+/* Name of package */
+#undef PACKAGE
+
+/* 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
+
+/* prefix */
+#undef PREFIX
+
+/* SINGULAR_CFLAGS */
+#undef SINGULAR_CFLAGS
+
+/* "Disable Singular Debug" */
+#undef SING_NDEBUG
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Version number of package */
+#undef VERSION
+
+/* Define to empty if `const' does not conform to ANSI C. */
+#undef const
+
+/* Define to `__inline__' or `__inline' if that's what the C compiler
+   calls it, or to nothing if 'inline' is not supported under any name.  */
+#ifndef __cplusplus
+#undef inline
+#endif
+
+/* Define to rpl_malloc if the replacement function should be used. */
+#undef malloc
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+#undef size_t
diff --git a/resources/aclocal.m4 b/resources/aclocal.m4
new file mode 100644
index 0000000..10596b8
--- /dev/null
+++ b/resources/aclocal.m4
@@ -0,0 +1,1180 @@
+# generated automatically by aclocal 1.13.4 -*- Autoconf -*-
+
+# Copyright (C) 1996-2013 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_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])
+m4_ifndef([AC_AUTOCONF_VERSION],
+  [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],,
+[m4_warning([this file was generated for autoconf 2.69.
+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'.])])
+
+# Copyright (C) 2002-2013 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.13'
+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.13.4], [],
+      [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.13.4])dnl
+m4_ifndef([AC_AUTOCONF_VERSION],
+  [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
+
+# Copyright (C) 2011-2013 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_AR([ACT-IF-FAIL])
+# -------------------------
+# Try to determine the archiver interface, and trigger the ar-lib wrapper
+# if it is needed.  If the detection of archiver interface fails, run
+# ACT-IF-FAIL (default is to abort configure with a proper error message).
+AC_DEFUN([AM_PROG_AR],
+[AC_BEFORE([$0], [LT_INIT])dnl
+AC_BEFORE([$0], [AC_PROG_LIBTOOL])dnl
+AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([ar-lib])dnl
+AC_CHECK_TOOLS([AR], [ar lib "link -lib"], [false])
+: ${AR=ar}
+
+AC_CACHE_CHECK([the archiver ($AR) interface], [am_cv_ar_interface],
+  [am_cv_ar_interface=ar
+   AC_COMPILE_IFELSE([AC_LANG_SOURCE([[int some_variable = 0;]])],
+     [am_ar_try='$AR cru libconftest.a conftest.$ac_objext >&AS_MESSAGE_LOG_FD'
+      AC_TRY_EVAL([am_ar_try])
+      if test "$ac_status" -eq 0; then
+        am_cv_ar_interface=ar
+      else
+        am_ar_try='$AR -NOLOGO -OUT:conftest.lib conftest.$ac_objext >&AS_MESSAGE_LOG_FD'
+        AC_TRY_EVAL([am_ar_try])
+        if test "$ac_status" -eq 0; then
+          am_cv_ar_interface=lib
+        else
+          am_cv_ar_interface=unknown
+        fi
+      fi
+      rm -f conftest.lib libconftest.a
+     ])
+   ])
+
+case $am_cv_ar_interface in
+ar)
+  ;;
+lib)
+  # Microsoft lib, so override with the ar-lib wrapper script.
+  # FIXME: It is wrong to rewrite AR.
+  # But if we don't then we get into trouble of one sort or another.
+  # A longer-term fix would be to have automake use am__AR in this case,
+  # and then we could set am__AR="$am_aux_dir/ar-lib \$(AR)" or something
+  # similar.
+  AR="$am_aux_dir/ar-lib $AR"
+  ;;
+unknown)
+  m4_default([$1],
+             [AC_MSG_ERROR([could not determine $AR interface])])
+  ;;
+esac
+AC_SUBST([AR])dnl
+])
+
+# AM_AUX_DIR_EXPAND                                         -*- Autoconf -*-
+
+# Copyright (C) 2001-2013 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-2013 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_CONDITIONAL(NAME, SHELL-CONDITION)
+# -------------------------------------
+# Define a conditional.
+AC_DEFUN([AM_CONDITIONAL],
+[AC_PREREQ([2.52])dnl
+ m4_if([$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-2013 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.
+
+
+# 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", "OBJC", "OBJCXX", "UPC", or "GJC".
+# 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
+
+m4_if([$1], [CC],   [depcc="$CC"   am_compiler_list=],
+      [$1], [CXX],  [depcc="$CXX"  am_compiler_list=],
+      [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
+      [$1], [OBJCXX], [depcc="$OBJCXX" 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".
+  rm -rf conftest.dir
+  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 10 /bin/sh.
+      echo '/* dummy */' > 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
+      ;;
+    msvc7 | msvc7msys | 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], [dnl
+AS_HELP_STRING(
+  [--enable-dependency-tracking],
+  [do not reject slow dependency extractors])
+AS_HELP_STRING(
+  [--disable-dependency-tracking],
+  [speeds up one-time build])])
+if test "x$enable_dependency_tracking" != xno; then
+  am_depcomp="$ac_aux_dir/depcomp"
+  AMDEPBACKSLASH='\'
+  am__nodep='_no'
+fi
+AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
+AC_SUBST([AMDEPBACKSLASH])dnl
+_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl
+AC_SUBST([am__nodep])dnl
+_AM_SUBST_NOTMAKE([am__nodep])dnl
+])
+
+# Generate code to set up dependency tracking.              -*- Autoconf -*-
+
+# Copyright (C) 1999-2013 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_OUTPUT_DEPENDENCY_COMMANDS
+# ------------------------------
+AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
+[{
+  # Older Autoconf 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"`
+    # 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'`; 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"])
+])
+
+# Do all the work for Automake.                             -*- Autoconf -*-
+
+# Copyright (C) 1996-2013 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 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.65])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],
+[AC_DIAGNOSE([obsolete],
+             [$0: two- and three-arguments forms are deprecated.])
+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], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]),
+  [ok:ok],,
+  [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([AC_PROG_MKDIR_P])dnl
+# For better backward compatibility.  To be removed once Automake 1.9.x
+# dies out for good.  For more background, see:
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
+AC_SUBST([mkdir_p], ['$(MKDIR_P)'])
+# 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])],
+		  [m4_define([AC_PROG_CC],
+			     m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_CXX],
+		  [_AM_DEPENDENCIES([CXX])],
+		  [m4_define([AC_PROG_CXX],
+			     m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_OBJC],
+		  [_AM_DEPENDENCIES([OBJC])],
+		  [m4_define([AC_PROG_OBJC],
+			     m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_OBJCXX],
+		  [_AM_DEPENDENCIES([OBJCXX])],
+		  [m4_define([AC_PROG_OBJCXX],
+			     m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl
+])
+AC_REQUIRE([AM_SILENT_RULES])dnl
+dnl The testsuite driver may need to know about EXEEXT, so add the
+dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen.  This
+dnl macro 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-2013 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-2013 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.
+
+# 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-2013 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_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 enable maintainer-specific portions of Makefiles])
+  dnl maintainer-mode's default is 'disable' unless 'enable' is passed
+  AC_ARG_ENABLE([maintainer-mode],
+    [AS_HELP_STRING([--]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
+]
+)
+
+# Check to see how 'make' treats includes.	            -*- Autoconf -*-
+
+# Copyright (C) 2001-2013 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_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
+])
+
+# Copyright (C) 1999-2013 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_CC_C_O
+# --------------
+# Like AC_PROG_CC_C_O, but changed for automake.
+AC_DEFUN([AM_PROG_CC_C_O],
+[AC_REQUIRE([AC_PROG_CC_C_O])dnl
+AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([compile])dnl
+# FIXME: we rely on the cache variable name because
+# there is no other way.
+set dummy $CC
+am_cc=`echo $[2] | sed ['s/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/']`
+eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o
+if test "$am_t" != yes; then
+   # Losing compiler, so override with the script.
+   # FIXME: It is wrong to rewrite CC.
+   # But if we don't then we get into trouble of one sort or another.
+   # A longer-term fix would be to have automake use am__CC in this case,
+   # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
+   CC="$am_aux_dir/compile $CC"
+fi
+dnl Make sure AC_PROG_CC is never called again, or it will override our
+dnl setting of CC.
+m4_define([AC_PROG_CC],
+          [m4_fatal([AC_PROG_CC cannot be called after AM_PROG_CC_C_O])])
+])
+
+# Fake the existence of programs that GNU maintainers use.  -*- Autoconf -*-
+
+# Copyright (C) 1997-2013 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_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 is modern enough.
+# If it is, 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 --is-lightweight"; then
+  am_missing_run="$MISSING "
+else
+  am_missing_run=
+  AC_MSG_WARN(['missing' script is too old or missing])
+fi
+])
+
+# Helper functions for option handling.                     -*- Autoconf -*-
+
+# Copyright (C) 2001-2013 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_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-2013 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_SANITY_CHECK
+# ---------------
+AC_DEFUN([AM_SANITY_CHECK],
+[AC_MSG_CHECKING([whether build environment is sane])
+# 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 (
+   am_has_slept=no
+   for am_try in 1 2; do
+     echo "timestamp, slept: $am_has_slept" > conftest.file
+     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
+     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
+     if test "$[2]" = conftest.file || test $am_try -eq 2; then
+       break
+     fi
+     # Just in case.
+     sleep 1
+     am_has_slept=yes
+   done
+   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])
+# If we didn't sleep, we still need to ensure time stamps of config.status and
+# generated files are strictly newer.
+am_sleep_pid=
+if grep 'slept: no' conftest.file >/dev/null 2>&1; then
+  ( sleep 1 ) &
+  am_sleep_pid=$!
+fi
+AC_CONFIG_COMMANDS_PRE(
+  [AC_MSG_CHECKING([that generated files are newer than configure])
+   if test -n "$am_sleep_pid"; then
+     # Hide warnings about reused PIDs.
+     wait $am_sleep_pid 2>/dev/null
+   fi
+   AC_MSG_RESULT([done])])
+rm -f conftest.file
+])
+
+# Copyright (C) 2009-2013 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_SILENT_RULES([DEFAULT])
+# --------------------------
+# Enable less verbose build rules; with the default set to DEFAULT
+# ("yes" being less verbose, "no" or empty being verbose).
+AC_DEFUN([AM_SILENT_RULES],
+[AC_ARG_ENABLE([silent-rules], [dnl
+AS_HELP_STRING(
+  [--enable-silent-rules],
+  [less verbose build output (undo: "make V=1")])
+AS_HELP_STRING(
+  [--disable-silent-rules],
+  [verbose build output (undo: "make V=0")])dnl
+])
+case $enable_silent_rules in @%:@ (((
+  yes) AM_DEFAULT_VERBOSITY=0;;
+   no) AM_DEFAULT_VERBOSITY=1;;
+    *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);;
+esac
+dnl
+dnl A few 'make' implementations (e.g., NonStop OS and NextStep)
+dnl do not support nested variable expansions.
+dnl See automake bug#9928 and bug#10237.
+am_make=${MAKE-make}
+AC_CACHE_CHECK([whether $am_make supports nested variables],
+   [am_cv_make_support_nested_variables],
+   [if AS_ECHO([['TRUE=$(BAR$(V))
+BAR0=false
+BAR1=true
+V=1
+am__doit:
+	@$(TRUE)
+.PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then
+  am_cv_make_support_nested_variables=yes
+else
+  am_cv_make_support_nested_variables=no
+fi])
+if test $am_cv_make_support_nested_variables = yes; then
+  dnl Using '$V' instead of '$(V)' breaks IRIX make.
+  AM_V='$(V)'
+  AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
+else
+  AM_V=$AM_DEFAULT_VERBOSITY
+  AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY
+fi
+AC_SUBST([AM_V])dnl
+AM_SUBST_NOTMAKE([AM_V])dnl
+AC_SUBST([AM_DEFAULT_V])dnl
+AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl
+AC_SUBST([AM_DEFAULT_VERBOSITY])dnl
+AM_BACKSLASH='\'
+AC_SUBST([AM_BACKSLASH])dnl
+_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl
+])
+
+# Copyright (C) 2001-2013 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-2013 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_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-2013 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_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.  Yes, it's still used
+# in the wild :-(  We should find a proper way to deprecate it ...
+AC_SUBST([AMTAR], ['$${TAR-tar}'])
+
+# We'll loop over all known methods to create a tar archive until one works.
+_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
+
+m4_if([$1], [v7],
+  [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'],
+
+  [m4_case([$1],
+    [ustar],
+     [# The POSIX 1988 'ustar' format is defined with fixed-size fields.
+      # There is notably a 21 bits limit for the UID and the GID.  In fact,
+      # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343
+      # and bug#13588).
+      am_max_uid=2097151 # 2^21 - 1
+      am_max_gid=$am_max_uid
+      # The $UID and $GID variables are not portable, so we need to resort
+      # to the POSIX-mandated id(1) utility.  Errors in the 'id' calls
+      # below are definitely unexpected, so allow the users to see them
+      # (that is, avoid stderr redirection).
+      am_uid=`id -u || echo unknown`
+      am_gid=`id -g || echo unknown`
+      AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format])
+      if test $am_uid -le $am_max_uid; then
+         AC_MSG_RESULT([yes])
+      else
+         AC_MSG_RESULT([no])
+         _am_tools=none
+      fi
+      AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format])
+      if test $am_gid -le $am_max_gid; then
+         AC_MSG_RESULT([yes])
+      else
+        AC_MSG_RESULT([no])
+        _am_tools=none
+      fi],
+
+  [pax],
+    [],
+
+  [m4_fatal([Unknown tar format])])
+
+  AC_MSG_CHECKING([how to create a $1 tar archive])
+
+  # Go ahead even if we have the value already cached.  We do so because we
+  # need to set the values for the 'am__tar' and 'am__untar' variables.
+  _am_tools=${am_cv_prog_tar_$1-$_am_tools}
+
+  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])
+      AM_RUN_LOG([cat conftest.dir/file])
+      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([../m4/ax_append_compile_flags.m4])
+m4_include([../m4/ax_append_flag.m4])
+m4_include([../m4/ax_append_link_flags.m4])
+m4_include([../m4/ax_check_compile_flag.m4])
+m4_include([../m4/ax_check_link_flag.m4])
+m4_include([../m4/ax_compute_relative_paths.m4])
+m4_include([../m4/ax_normalize_path.m4])
+m4_include([../m4/ax_prefix_config_h.m4])
+m4_include([../m4/flags.m4])
+m4_include([../m4/libtool.m4])
+m4_include([../m4/ltoptions.m4])
+m4_include([../m4/ltsugar.m4])
+m4_include([../m4/ltversion.m4])
+m4_include([../m4/lt~obsolete.m4])
diff --git a/resources/configure b/resources/configure
new file mode 100755
index 0000000..871974e
--- /dev/null
+++ b/resources/configure
@@ -0,0 +1,21164 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.69 for resources 4.0.1.
+#
+#
+# Copyright (C) 1992-1996, 1998-2012 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.
+as_myself=
+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
+
+# Use a proper internal environment variable to ensure we don't fall
+  # into an infinite loop, continuously re-executing ourselves.
+  if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then
+    _as_can_reexec=no; export _as_can_reexec;
+    # 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.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+  *v*x* | *x*v* ) as_opts=-vx ;;
+  *v* ) as_opts=-v ;;
+  *x* ) as_opts=-x ;;
+  * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+as_fn_exit 255
+  fi
+  # We don't want this to propagate to other subprocesses.
+          { _as_can_reexec=; unset _as_can_reexec;}
+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
+test -x / || 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
+
+  test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || (
+    ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+    ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO
+    ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO
+    PATH=/empty FPATH=/empty; export PATH FPATH
+    test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\
+      || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || 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 :
+  export CONFIG_SHELL
+             # 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.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+  *v*x* | *x*v* ) as_opts=-vx ;;
+  *v* ) as_opts=-v ;;
+  *x* ) as_opts=-x ;;
+  * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+exit 255
+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_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+  test -f "$1" && test -x "$1"
+} # as_fn_executable_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 STATUS 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=$1; test $as_status -eq 0 && as_status=1
+  if test "$4"; then
+    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+  fi
+  $as_echo "$as_me: error: $2" >&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; }
+
+  # If we had to re-execute with $CONFIG_SHELL, we're ensured to have
+  # already done that, so ensure we don't try to do so again and fall
+  # in an infinite loop.  This has already happened in practice.
+  _as_can_reexec=no; export _as_can_reexec
+  # 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 -pR'.
+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+      as_ln_s='cp -pR'
+  elif ln conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s=ln
+  else
+    as_ln_s='cp -pR'
+  fi
+else
+  as_ln_s='cp -pR'
+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
+
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
+
+# 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'"
+
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+
+test -n "$DJDIR" || exec 7<&0 </dev/null
+exec 6>&1
+
+# Name of the host.
+# hostname on some systems (SVR3.2, old GNU/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='resources'
+PACKAGE_TARNAME='resources'
+PACKAGE_VERSION='4.0.1'
+PACKAGE_STRING='resources 4.0.1'
+PACKAGE_BUGREPORT=''
+PACKAGE_URL=''
+
+ac_unique_file="omFindExec.h"
+# 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
+CXXCPP
+OTOOL64
+OTOOL
+LIPO
+NMEDIT
+DSYMUTIL
+MANIFEST_TOOL
+RANLIB
+DLLTOOL
+OBJDUMP
+NM
+ac_ct_DUMPBIN
+DUMPBIN
+LD
+FGREP
+SED
+host_os
+host_vendor
+host_cpu
+host
+build_os
+build_vendor
+build_cpu
+build
+LIBTOOL
+LIBOBJS
+EGREP
+GREP
+CPP
+LN_S
+POLYMAKE_CXXFLAGS
+am__fastdepCXX_FALSE
+am__fastdepCXX_TRUE
+CXXDEPMODE
+ac_ct_CXX
+CXXFLAGS
+CXX
+SINGULAR_CFLAGS
+WANT_OPTIMIZATIONFLAGS_FALSE
+WANT_OPTIMIZATIONFLAGS_TRUE
+WANT_DEBUG_FALSE
+WANT_DEBUG_TRUE
+am__fastdepCC_FALSE
+am__fastdepCC_TRUE
+CCDEPMODE
+am__nodep
+AMDEPBACKSLASH
+AMDEP_FALSE
+AMDEP_TRUE
+am__quote
+am__include
+DEPDIR
+OBJEXT
+EXEEXT
+ac_ct_CC
+CPPFLAGS
+LDFLAGS
+CFLAGS
+CC
+ac_ct_AR
+AR
+AM_BACKSLASH
+AM_DEFAULT_VERBOSITY
+AM_DEFAULT_V
+AM_V
+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
+MAINT
+MAINTAINER_MODE_FALSE
+MAINTAINER_MODE_TRUE
+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
+enable_silent_rules
+enable_dependency_tracking
+enable_debug
+enable_optimizationflags
+enable_shared
+enable_static
+with_pic
+enable_fast_install
+with_gnu_ld
+with_sysroot
+enable_libtool_lock
+'
+      ac_precious_vars='build_alias
+host_alias
+target_alias
+CC
+CFLAGS
+LDFLAGS
+LIBS
+CPPFLAGS
+CXX
+CXXFLAGS
+CCC
+CPP
+CXXCPP'
+
+
+# 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_TARNAME}'
+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= ;;
+  *)    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
+  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 resources 4.0.1 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/resources]
+  --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
+  case $ac_init_help in
+     short | recursive ) echo "Configuration of resources 4.0.1:";;
+   esac
+  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]
+  --disable-maintainer-mode
+                          disable make rules and dependencies not useful (and
+                          sometimes confusing) to the casual installer
+  --enable-silent-rules   less verbose build output (undo: "make V=1")
+  --disable-silent-rules  verbose build output (undo: "make V=0")
+  --enable-dependency-tracking
+                          do not reject slow dependency extractors
+  --disable-dependency-tracking
+                          speeds up one-time build
+  --enable-debug          build the debugging version of the libraries
+  --disable-optimizationflags
+                          build the without default optimization flags
+  --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)
+
+Optional Packages:
+  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
+  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
+  --with-pic[=PKGS]       try to use only PIC/non-PIC objects [default=use
+                          both]
+  --with-gnu-ld           assume the C compiler uses GNU ld [default=no]
+  --with-sysroot=DIR Search for dependent libraries within DIR
+                        (or the compiler's sysroot if not specified).
+
+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    (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
+              you have headers in a nonstandard directory <include dir>
+  CXX         C++ compiler command
+  CXXFLAGS    C++ compiler flags
+  CPP         C preprocessor
+  CXXCPP      C++ preprocessor
+
+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
+resources configure 4.0.1
+generated by GNU Autoconf 2.69
+
+Copyright (C) 2012 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; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_compile
+
+# ac_fn_cxx_try_compile LINENO
+# ----------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_cxx_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_cxx_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; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_cxx_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 ||
+	 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; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_link
+
+# 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; } > conftest.i && {
+	 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; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $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; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_run
+
+# 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 eval \${$3+:} false; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; 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.i 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 eval \${$3+:} false; 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; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_header_mongrel
+
+# 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 eval \${$3+:} false; 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; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_header_compile
+
+# 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 eval \${$3+:} false; 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; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_func
+
+# ac_fn_c_check_type LINENO TYPE VAR INCLUDES
+# -------------------------------------------
+# Tests whether TYPE exists after having included INCLUDES, setting cache
+# variable VAR accordingly.
+ac_fn_c_check_type ()
+{
+  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 eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  eval "$3=no"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+if (sizeof ($2))
+	 return 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+if (sizeof (($2)))
+	    return 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+  eval "$3=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
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_type
+
+# ac_fn_cxx_try_cpp LINENO
+# ------------------------
+# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
+ac_fn_cxx_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; } > conftest.i && {
+	 test -z "$ac_cxx_preproc_warn_flag$ac_cxx_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; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_cxx_try_cpp
+
+# ac_fn_cxx_try_link LINENO
+# -------------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded.
+ac_fn_cxx_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_cxx_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext && {
+	 test "$cross_compiling" = yes ||
+	 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; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_cxx_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 resources $as_me 4.0.1, which was
+generated by GNU Autoconf 2.69.  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
+
+    $as_echo "## ---------------- ##
+## Cache variables. ##
+## ---------------- ##"
+    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
+
+    $as_echo "## ----------------- ##
+## Output variables. ##
+## ----------------- ##"
+    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
+      $as_echo "## ------------------- ##
+## File substitutions. ##
+## ------------------- ##"
+      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
+      $as_echo "## ----------- ##
+## confdefs.h. ##
+## ----------- ##"
+      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
+  # We do not want a PATH search for config.site.
+  case $CONFIG_SITE in #((
+    -*)  ac_site_file1=./$CONFIG_SITE;;
+    */*) ac_site_file1=$CONFIG_SITE;;
+    *)   ac_site_file1=./$CONFIG_SITE;;
+  esac
+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 /dev/null != "$ac_site_file" && 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" \
+      || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "failed to load site script $ac_site_file
+See \`config.log' for more details" "$LINENO" 5; }
+  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.  DJGPP emulates it as a regular file.
+  if test /dev/null != "$cache_file" && 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_aux_dir=
+for ac_dir in ../build-aux "$srcdir"/../build-aux; do
+  if test -f "$ac_dir/install-sh"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install-sh -c"
+    break
+  elif test -f "$ac_dir/install.sh"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install.sh -c"
+    break
+  elif test -f "$ac_dir/shtool"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/shtool install -c"
+    break
+  fi
+done
+if test -z "$ac_aux_dir"; then
+  as_fn_error $? "cannot find install-sh, install.sh, or shtool in ../build-aux \"$srcdir\"/../build-aux" "$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.
+
+
+
+ac_config_headers="$ac_config_headers _config.h"
+
+
+
+{ $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=yes
+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
+
+
+am__api_version='1.13'
+
+# 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 ${ac_cv_path_install+:} false; 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 as_fn_executable_p "$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; }
+# 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 (
+   am_has_slept=no
+   for am_try in 1 2; do
+     echo "timestamp, slept: $am_has_slept" > conftest.file
+     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
+     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
+     if test "$2" = conftest.file || test $am_try -eq 2; then
+       break
+     fi
+     # Just in case.
+     sleep 1
+     am_has_slept=yes
+   done
+   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; }
+# If we didn't sleep, we still need to ensure time stamps of config.status and
+# generated files are strictly newer.
+am_sleep_pid=
+if grep 'slept: no' conftest.file >/dev/null 2>&1; then
+  ( sleep 1 ) &
+  am_sleep_pid=$!
+fi
+
+rm -f conftest.file
+
+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 --is-lightweight"; then
+  am_missing_run="$MISSING "
+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 ${ac_cv_prog_STRIP+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_STRIP+:} false; 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 as_fn_executable_p "$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 ${ac_cv_path_mkdir+:} false; 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
+	   as_fn_executable_p "$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
+
+  test -d ./--version && rmdir ./--version
+  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.
+    MKDIR_P="$ac_install_sh -d"
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5
+$as_echo "$MKDIR_P" >&6; }
+
+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 ${ac_cv_prog_AWK+:} false; 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 as_fn_executable_p "$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 eval \${ac_cv_prog_make_${ac_make}_set+:} false; 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
+
+# Check whether --enable-silent-rules was given.
+if test "${enable_silent_rules+set}" = set; then :
+  enableval=$enable_silent_rules;
+fi
+
+case $enable_silent_rules in # (((
+  yes) AM_DEFAULT_VERBOSITY=0;;
+   no) AM_DEFAULT_VERBOSITY=1;;
+    *) AM_DEFAULT_VERBOSITY=1;;
+esac
+am_make=${MAKE-make}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5
+$as_echo_n "checking whether $am_make supports nested variables... " >&6; }
+if ${am_cv_make_support_nested_variables+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if $as_echo 'TRUE=$(BAR$(V))
+BAR0=false
+BAR1=true
+V=1
+am__doit:
+	@$(TRUE)
+.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then
+  am_cv_make_support_nested_variables=yes
+else
+  am_cv_make_support_nested_variables=no
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5
+$as_echo "$am_cv_make_support_nested_variables" >&6; }
+if test $am_cv_make_support_nested_variables = yes; then
+    AM_V='$(V)'
+  AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
+else
+  AM_V=$AM_DEFAULT_VERBOSITY
+  AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY
+fi
+AM_BACKSLASH='\'
+
+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='resources'
+ VERSION='4.0.1'
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE "$PACKAGE"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define VERSION "$VERSION"
+_ACEOF
+
+# 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"}
+
+# For better backward compatibility.  To be removed once Automake 1.9.x
+# dies out for good.  For more background, see:
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
+mkdir_p='$(MKDIR_P)'
+
+# We need awk for the "check" target.  The system "awk" is bad on
+# some platforms.
+# Always define AMTAR for backward compatibility.  Yes, it's still used
+# in the wild :-(  We should find a proper way to deprecate it ...
+AMTAR='$${TAR-tar}'
+
+
+# We'll loop over all known methods to create a tar archive until one works.
+_am_tools='gnutar  pax cpio none'
+
+am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'
+
+
+
+
+
+ # -Wno-extra-portability -Werror silent-rules
+# Check whether --enable-silent-rules was given.
+if test "${enable_silent_rules+set}" = set; then :
+  enableval=$enable_silent_rules;
+fi
+
+case $enable_silent_rules in # (((
+  yes) AM_DEFAULT_VERBOSITY=0;;
+   no) AM_DEFAULT_VERBOSITY=1;;
+    *) AM_DEFAULT_VERBOSITY=0;;
+esac
+am_make=${MAKE-make}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5
+$as_echo_n "checking whether $am_make supports nested variables... " >&6; }
+if ${am_cv_make_support_nested_variables+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if $as_echo 'TRUE=$(BAR$(V))
+BAR0=false
+BAR1=true
+V=1
+am__doit:
+	@$(TRUE)
+.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then
+  am_cv_make_support_nested_variables=yes
+else
+  am_cv_make_support_nested_variables=no
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5
+$as_echo "$am_cv_make_support_nested_variables" >&6; }
+if test $am_cv_make_support_nested_variables = yes; then
+    AM_V='$(V)'
+  AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
+else
+  AM_V=$AM_DEFAULT_VERBOSITY
+  AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY
+fi
+AM_BACKSLASH='\'
+
+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='\'
+  am__nodep='_no'
+fi
+ if test "x$enable_dependency_tracking" != xno; then
+  AMDEP_TRUE=
+  AMDEP_FALSE='#'
+else
+  AMDEP_TRUE='#'
+  AMDEP_FALSE=
+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 ${ac_cv_prog_CC+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_CC+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_CC+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_CC+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_CC+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_CC+:} false; 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 as_fn_executable_p "$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
+  fi
+  rm -f conftest.er1 conftest.err
+  $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.  */
+
+int
+main ()
+{
+
+  ;
+  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"
+# 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 whether the C compiler works" >&5
+$as_echo_n "checking whether the C compiler works... " >&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
+if test -z "$ac_file"; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+$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 77 "C compiler cannot create executables
+See \`config.log' for more details" "$LINENO" 5; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+fi
+{ $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; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
+$as_echo "$ac_file" >&6; }
+ac_exeext=$ac_cv_exeext
+
+rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+{ $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 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
+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="$ac_clean_files conftest.out"
+# 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; }
+if test "$cross_compiling" != yes; then
+  { { 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; }
+  if { ac_try='./conftest$ac_cv_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
+    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: $cross_compiling" >&5
+$as_echo "$cross_compiling" >&6; }
+
+rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out
+ac_clean_files=$ac_clean_files_save
+{ $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 ${ac_cv_objext+:} false; 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 ${ac_cv_c_compiler_gnu+:} false; 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 ${ac_cv_prog_cc_g+:} false; 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 ${ac_cv_prog_cc_c89+:} false; 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>
+struct stat;
+/* 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
+
+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 ${am_cv_CC_dependencies_compiler_type+:} false; 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".
+  rm -rf conftest.dir
+  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 10 /bin/sh.
+      echo '/* dummy */' > 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
+      ;;
+    msvc7 | msvc7msys | 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 -n "$ac_tool_prefix"; then
+  for ac_prog in ar lib "link -lib"
+  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 ${ac_cv_prog_AR+:} false; 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_AR="$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
+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
+
+
+    test -n "$AR" && break
+  done
+fi
+if test -z "$AR"; then
+  ac_ct_AR=$AR
+  for ac_prog in ar lib "link -lib"
+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 ${ac_cv_prog_ac_ct_AR+:} false; 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_AR="$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_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
+
+
+  test -n "$ac_ct_AR" && break
+done
+
+  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
+fi
+
+: ${AR=ar}
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the archiver ($AR) interface" >&5
+$as_echo_n "checking the archiver ($AR) interface... " >&6; }
+if ${am_cv_ar_interface+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  am_cv_ar_interface=ar
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+int some_variable = 0;
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  am_ar_try='$AR cru libconftest.a conftest.$ac_objext >&5'
+      { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$am_ar_try\""; } >&5
+  (eval $am_ar_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      if test "$ac_status" -eq 0; then
+        am_cv_ar_interface=ar
+      else
+        am_ar_try='$AR -NOLOGO -OUT:conftest.lib conftest.$ac_objext >&5'
+        { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$am_ar_try\""; } >&5
+  (eval $am_ar_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+        if test "$ac_status" -eq 0; then
+          am_cv_ar_interface=lib
+        else
+          am_cv_ar_interface=unknown
+        fi
+      fi
+      rm -f conftest.lib libconftest.a
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_ar_interface" >&5
+$as_echo "$am_cv_ar_interface" >&6; }
+
+case $am_cv_ar_interface in
+ar)
+  ;;
+lib)
+  # Microsoft lib, so override with the ar-lib wrapper script.
+  # FIXME: It is wrong to rewrite AR.
+  # But if we don't then we get into trouble of one sort or another.
+  # A longer-term fix would be to have automake use am__AR in this case,
+  # and then we could set am__AR="$am_aux_dir/ar-lib \$(AR)" or something
+  # similar.
+  AR="$am_aux_dir/ar-lib $AR"
+  ;;
+unknown)
+  as_fn_error $? "could not determine $AR interface" "$LINENO" 5
+  ;;
+esac
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5
+$as_echo_n "checking whether build environment is sane... " >&6; }
+# 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 (
+   am_has_slept=no
+   for am_try in 1 2; do
+     echo "timestamp, slept: $am_has_slept" > conftest.file
+     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
+     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
+     if test "$2" = conftest.file || test $am_try -eq 2; then
+       break
+     fi
+     # Just in case.
+     sleep 1
+     am_has_slept=yes
+   done
+   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; }
+# If we didn't sleep, we still need to ensure time stamps of config.status and
+# generated files are strictly newer.
+am_sleep_pid=
+if grep 'slept: no' conftest.file >/dev/null 2>&1; then
+  ( sleep 1 ) &
+  am_sleep_pid=$!
+fi
+
+rm -f conftest.file
+
+
+# Add pre'prefixed config
+
+ac_config_commands="$ac_config_commands resourcesconfig.h"
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Please note that we set empty defaults for \`CFLAGS' and \`CXXFLAGS' (instead of \`-g -O')" >&5
+$as_echo "$as_me: WARNING: Please note that we set empty defaults for \`CFLAGS' and \`CXXFLAGS' (instead of \`-g -O')" >&2;}
+ : ${CFLAGS:=""}
+ : ${CXXFLAGS:=""}
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts " >&5
+$as_echo_n "checking whether C compiler accepts ... " >&6; }
+if ${ax_cv_check_cflags__+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$CFLAGS
+  CFLAGS="$CFLAGS   -Werror"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ax_cv_check_cflags__=yes
+else
+  ax_cv_check_cflags__=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  CFLAGS=$ax_check_save_flags
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags__" >&5
+$as_echo "$ax_cv_check_cflags__" >&6; }
+if test x"$ax_cv_check_cflags__" = xyes; then :
+  :
+else
+  :
+fi
+
+if ${CFLAGS+:} false; then :
+  case " $CFLAGS " in
+    *"  "*)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS already contains "; } >&5
+  (: CFLAGS already contains ) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      ;;
+    *)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS=\"\$CFLAGS \""; } >&5
+  (: CFLAGS="$CFLAGS ") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      CFLAGS="$CFLAGS "
+      ;;
+   esac
+else
+  CFLAGS=""
+fi
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+if test -z "$CXX"; then
+  if test -n "$CCC"; then
+    CXX=$CCC
+  else
+    if test -n "$ac_tool_prefix"; then
+  for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+  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 ${ac_cv_prog_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CXX"; then
+  ac_cv_prog_CXX="$CXX" # 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CXX="$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
+CXX=$ac_cv_prog_CXX
+if test -n "$CXX"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5
+$as_echo "$CXX" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+    test -n "$CXX" && break
+  done
+fi
+if test -z "$CXX"; then
+  ac_ct_CXX=$CXX
+  for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+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 ${ac_cv_prog_ac_ct_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_CXX"; then
+  ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CXX="$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_CXX=$ac_cv_prog_ac_ct_CXX
+if test -n "$ac_ct_CXX"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5
+$as_echo "$ac_ct_CXX" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$ac_ct_CXX" && break
+done
+
+  if test "x$ac_ct_CXX" = x; then
+    CXX="g++"
+  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
+    CXX=$ac_ct_CXX
+  fi
+fi
+
+  fi
+fi
+# 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
+  fi
+  rm -f conftest.er1 conftest.err
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+done
+
+{ $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 ${ac_cv_cxx_compiler_gnu+:} false; 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_cxx_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_cxx_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5
+$as_echo "$ac_cv_cxx_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+  GXX=yes
+else
+  GXX=
+fi
+ac_test_CXXFLAGS=${CXXFLAGS+set}
+ac_save_CXXFLAGS=$CXXFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5
+$as_echo_n "checking whether $CXX accepts -g... " >&6; }
+if ${ac_cv_prog_cxx_g+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_save_cxx_werror_flag=$ac_cxx_werror_flag
+   ac_cxx_werror_flag=yes
+   ac_cv_prog_cxx_g=no
+   CXXFLAGS="-g"
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ac_cv_prog_cxx_g=yes
+else
+  CXXFLAGS=""
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+
+else
+  ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+	 CXXFLAGS="-g"
+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ac_cv_prog_cxx_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_cxx_werror_flag=$ac_save_cxx_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5
+$as_echo "$ac_cv_prog_cxx_g" >&6; }
+if test "$ac_test_CXXFLAGS" = set; then
+  CXXFLAGS=$ac_save_CXXFLAGS
+elif test $ac_cv_prog_cxx_g = yes; then
+  if test "$GXX" = yes; then
+    CXXFLAGS="-g -O2"
+  else
+    CXXFLAGS="-g"
+  fi
+else
+  if test "$GXX" = yes; then
+    CXXFLAGS="-O2"
+  else
+    CXXFLAGS=
+  fi
+fi
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+depcc="$CXX"  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 ${am_cv_CXX_dependencies_compiler_type+:} false; 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".
+  rm -rf conftest.dir
+  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_CXX_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 10 /bin/sh.
+      echo '/* dummy */' > 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
+      ;;
+    msvc7 | msvc7msys | 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_CXX_dependencies_compiler_type=$depmode
+        break
+      fi
+    fi
+  done
+
+  cd ..
+  rm -rf conftest.dir
+else
+  am_cv_CXX_dependencies_compiler_type=none
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5
+$as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; }
+CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type
+
+ if
+  test "x$enable_dependency_tracking" != xno \
+  && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then
+  am__fastdepCXX_TRUE=
+  am__fastdepCXX_FALSE='#'
+else
+  am__fastdepCXX_TRUE='#'
+  am__fastdepCXX_FALSE=
+fi
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the linker accepts " >&5
+$as_echo_n "checking whether the linker accepts ... " >&6; }
+if ${ax_cv_check_ldflags__+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$LDFLAGS
+  LDFLAGS="$LDFLAGS  "
+  _save_cflags="$CFLAGS"
+  CFLAGS="$CFLAGS -Werror"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ax_cv_check_ldflags__=yes
+else
+  ax_cv_check_ldflags__=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+  CFLAGS="$_save_cflags"
+  LDFLAGS=$ax_check_save_flags
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_ldflags__" >&5
+$as_echo "$ax_cv_check_ldflags__" >&6; }
+if test x"$ax_cv_check_ldflags__" = xyes; then :
+  :
+else
+  :
+fi
+
+
+#  SING_SHOW_FLAGS([Initial state?...])dnl
+
+ # Check whether --enable-debug was given.
+if test "${enable_debug+set}" = set; then :
+  enableval=$enable_debug; ENABLE_DEBUG="$enableval"
+else
+  ENABLE_DEBUG=""
+fi
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking debugging checks should be embedded" >&5
+$as_echo_n "checking debugging checks should be embedded... " >&6; }
+ if test "x${ENABLE_DEBUG}" != xyes; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ fi
+
+ # Check whether --enable-optimizationflags was given.
+if test "${enable_optimizationflags+set}" = set; then :
+  enableval=$enable_optimizationflags; ENABLE_OPTIMIZATION="$enableval"
+else
+  ENABLE_OPTIMIZATION="yeah"
+fi
+
+
+ if test "x${ENABLE_DEBUG}" = xyes; then
+  SINGULAR_CFLAGS=""
+  if test "x${ENABLE_OPTIMIZATION}" = xyeah; then
+   ENABLE_OPTIMIZATION="no"
+   { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Please note that we disable implicit (default) optimization flags since you have enabled the debug flags... " >&5
+$as_echo "$as_me: WARNING: Please note that we disable implicit (default) optimization flags since you have enabled the debug flags... " >&2;}
+  fi
+ else
+  SINGULAR_CFLAGS="-DSING_NDEBUG -DOM_NDEBUG"
+  # for now let '-DSING_NDEBUG -DOM_NDEBUG' be here...
+
+$as_echo "#define OM_NDEBUG 1" >>confdefs.h
+
+
+$as_echo "#define SING_NDEBUG 1" >>confdefs.h
+
+ fi
+
+ if test "x${ENABLE_OPTIMIZATION}" = xyeah; then
+   ENABLE_OPTIMIZATION="yes"
+ fi
+
+ if test "x${ENABLE_OPTIMIZATION}" = xyes; then
+  if test "x${ENABLE_DEBUG}" = xyes; then
+   { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Please note that you will be using our optimization flags together with debug flags... " >&5
+$as_echo "$as_me: WARNING: Please note that you will be using our optimization flags together with debug flags... " >&2;}
+  fi
+ fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether optimization flags should be used" >&5
+$as_echo_n "checking whether optimization flags should be used... " >&6; }
+ if test "x${ENABLE_OPTIMIZATION}" = xyes; 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; }
+ fi
+
+
+  if test x"${ENABLE_DEBUG}" = xyes; then
+  WANT_DEBUG_TRUE=
+  WANT_DEBUG_FALSE='#'
+else
+  WANT_DEBUG_TRUE='#'
+  WANT_DEBUG_FALSE=
+fi
+
+  if test x"${ENABLE_OPTIMIZATION}" = xyes; then
+  WANT_OPTIMIZATIONFLAGS_TRUE=
+  WANT_OPTIMIZATIONFLAGS_FALSE='#'
+else
+  WANT_OPTIMIZATIONFLAGS_TRUE='#'
+  WANT_OPTIMIZATIONFLAGS_FALSE=
+fi
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SINGULAR_CFLAGS "$SINGULAR_CFLAGS"
+_ACEOF
+
+
+
+# SING_SHOW_FLAGS([checking flags....])
+
+ FLAGS="-pipe -fno-common"
+ 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
+
+
+
+for flag in ${FLAGS}; do
+  as_CACHEVAR=`$as_echo "ax_cv_check_cflags__$flag" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts $flag" >&5
+$as_echo_n "checking whether C compiler accepts $flag... " >&6; }
+if eval \${$as_CACHEVAR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$CFLAGS
+  CFLAGS="$CFLAGS  $flag -Werror"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  eval "$as_CACHEVAR=yes"
+else
+  eval "$as_CACHEVAR=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  CFLAGS=$ax_check_save_flags
+fi
+eval ac_res=\$$as_CACHEVAR
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if test x"`eval 'as_val=${'$as_CACHEVAR'};$as_echo "$as_val"'`" = xyes; then :
+  if ${CFLAGS+:} false; then :
+  case " $CFLAGS " in
+    *" $flag "*)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS already contains \$flag"; } >&5
+  (: CFLAGS already contains $flag) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      ;;
+    *)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS=\"\$CFLAGS \$flag\""; } >&5
+  (: CFLAGS="$CFLAGS $flag") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      CFLAGS="$CFLAGS $flag"
+      ;;
+   esac
+else
+  CFLAGS="$flag"
+fi
+
+else
+  :
+fi
+
+done
+
+ 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=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+
+for flag in ${FLAGS}; do
+  as_CACHEVAR=`$as_echo "ax_cv_check_cxxflags__$flag" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C++ compiler accepts $flag" >&5
+$as_echo_n "checking whether C++ compiler accepts $flag... " >&6; }
+if eval \${$as_CACHEVAR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$CXXFLAGS
+  CXXFLAGS="$CXXFLAGS  $flag -Werror"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  eval "$as_CACHEVAR=yes"
+else
+  eval "$as_CACHEVAR=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  CXXFLAGS=$ax_check_save_flags
+fi
+eval ac_res=\$$as_CACHEVAR
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if test x"`eval 'as_val=${'$as_CACHEVAR'};$as_echo "$as_val"'`" = xyes; then :
+  if ${CXXFLAGS+:} false; then :
+  case " $CXXFLAGS " in
+    *" $flag "*)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CXXFLAGS already contains \$flag"; } >&5
+  (: CXXFLAGS already contains $flag) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      ;;
+    *)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CXXFLAGS=\"\$CXXFLAGS \$flag\""; } >&5
+  (: CXXFLAGS="$CXXFLAGS $flag") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      CXXFLAGS="$CXXFLAGS $flag"
+      ;;
+   esac
+else
+  CXXFLAGS="$flag"
+fi
+
+else
+  :
+fi
+
+done
+
+
+
+for flag in -fexceptions -frtti; do
+  as_CACHEVAR=`$as_echo "ax_cv_check_cxxflags__$flag" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C++ compiler accepts $flag" >&5
+$as_echo_n "checking whether C++ compiler accepts $flag... " >&6; }
+if eval \${$as_CACHEVAR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$CXXFLAGS
+  CXXFLAGS="$CXXFLAGS  $flag -Werror"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  eval "$as_CACHEVAR=yes"
+else
+  eval "$as_CACHEVAR=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  CXXFLAGS=$ax_check_save_flags
+fi
+eval ac_res=\$$as_CACHEVAR
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if test x"`eval 'as_val=${'$as_CACHEVAR'};$as_echo "$as_val"'`" = xyes; then :
+  if ${POLYMAKE_CXXFLAGS+:} false; then :
+  case " $POLYMAKE_CXXFLAGS " in
+    *" $flag "*)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : POLYMAKE_CXXFLAGS already contains \$flag"; } >&5
+  (: POLYMAKE_CXXFLAGS already contains $flag) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      ;;
+    *)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : POLYMAKE_CXXFLAGS=\"\$POLYMAKE_CXXFLAGS \$flag\""; } >&5
+  (: POLYMAKE_CXXFLAGS="$POLYMAKE_CXXFLAGS $flag") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      POLYMAKE_CXXFLAGS="$POLYMAKE_CXXFLAGS $flag"
+      ;;
+   esac
+else
+  POLYMAKE_CXXFLAGS="$flag"
+fi
+
+else
+  :
+fi
+
+done
+
+ 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
+
+
+
+
+for flag in ${FLAGS}; do
+  as_CACHEVAR=`$as_echo "ax_cv_check_ldflags__$flag" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the linker accepts $flag" >&5
+$as_echo_n "checking whether the linker accepts $flag... " >&6; }
+if eval \${$as_CACHEVAR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$LDFLAGS
+  LDFLAGS="$LDFLAGS  $flag"
+  _save_cflags="$CFLAGS"
+  CFLAGS="$CFLAGS -Werror"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "$as_CACHEVAR=yes"
+else
+  eval "$as_CACHEVAR=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+  CFLAGS="$_save_cflags"
+  LDFLAGS=$ax_check_save_flags
+fi
+eval ac_res=\$$as_CACHEVAR
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if test x"`eval 'as_val=${'$as_CACHEVAR'};$as_echo "$as_val"'`" = xyes; then :
+  if ${LDFLAGS+:} false; then :
+  case " $LDFLAGS " in
+    *" $flag "*)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : LDFLAGS already contains \$flag"; } >&5
+  (: LDFLAGS already contains $flag) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      ;;
+    *)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : LDFLAGS=\"\$LDFLAGS \$flag\""; } >&5
+  (: LDFLAGS="$LDFLAGS $flag") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      LDFLAGS="$LDFLAGS $flag"
+      ;;
+   esac
+else
+  LDFLAGS="$flag"
+fi
+
+else
+  :
+fi
+
+done
+
+
+
+
+ if test "x${ENABLE_DEBUG}" = xyes; then
+  DBGFLAGS="-g -ftrapv -fdiagnostics-show-option -Wall -Wextra"
+  #  -pedantic too strict ??? -Wvla -Wno-long-long ???
+  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
+
+
+
+for flag in ${DBGFLAGS}; do
+  as_CACHEVAR=`$as_echo "ax_cv_check_cflags__$flag" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts $flag" >&5
+$as_echo_n "checking whether C compiler accepts $flag... " >&6; }
+if eval \${$as_CACHEVAR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$CFLAGS
+  CFLAGS="$CFLAGS  $flag -Werror"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  eval "$as_CACHEVAR=yes"
+else
+  eval "$as_CACHEVAR=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  CFLAGS=$ax_check_save_flags
+fi
+eval ac_res=\$$as_CACHEVAR
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if test x"`eval 'as_val=${'$as_CACHEVAR'};$as_echo "$as_val"'`" = xyes; then :
+  if ${CFLAGS+:} false; then :
+  case " $CFLAGS " in
+    *" $flag "*)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS already contains \$flag"; } >&5
+  (: CFLAGS already contains $flag) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      ;;
+    *)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS=\"\$CFLAGS \$flag\""; } >&5
+  (: CFLAGS="$CFLAGS $flag") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      CFLAGS="$CFLAGS $flag"
+      ;;
+   esac
+else
+  CFLAGS="$flag"
+fi
+
+else
+  :
+fi
+
+done
+
+  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=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+
+for flag in ${DBGFLAGS}; do
+  as_CACHEVAR=`$as_echo "ax_cv_check_cxxflags__$flag" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C++ compiler accepts $flag" >&5
+$as_echo_n "checking whether C++ compiler accepts $flag... " >&6; }
+if eval \${$as_CACHEVAR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$CXXFLAGS
+  CXXFLAGS="$CXXFLAGS  $flag -Werror"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  eval "$as_CACHEVAR=yes"
+else
+  eval "$as_CACHEVAR=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  CXXFLAGS=$ax_check_save_flags
+fi
+eval ac_res=\$$as_CACHEVAR
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if test x"`eval 'as_val=${'$as_CACHEVAR'};$as_echo "$as_val"'`" = xyes; then :
+  if ${CXXFLAGS+:} false; then :
+  case " $CXXFLAGS " in
+    *" $flag "*)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CXXFLAGS already contains \$flag"; } >&5
+  (: CXXFLAGS already contains $flag) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      ;;
+    *)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CXXFLAGS=\"\$CXXFLAGS \$flag\""; } >&5
+  (: CXXFLAGS="$CXXFLAGS $flag") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      CXXFLAGS="$CXXFLAGS $flag"
+      ;;
+   esac
+else
+  CXXFLAGS="$flag"
+fi
+
+else
+  :
+fi
+
+done
+
+  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
+
+
+
+for flag in ${DBGFLAGS}; do
+  as_CACHEVAR=`$as_echo "ax_cv_check_ldflags__$flag" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the linker accepts $flag" >&5
+$as_echo_n "checking whether the linker accepts $flag... " >&6; }
+if eval \${$as_CACHEVAR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$LDFLAGS
+  LDFLAGS="$LDFLAGS  $flag"
+  _save_cflags="$CFLAGS"
+  CFLAGS="$CFLAGS -Werror"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "$as_CACHEVAR=yes"
+else
+  eval "$as_CACHEVAR=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+  CFLAGS="$_save_cflags"
+  LDFLAGS=$ax_check_save_flags
+fi
+eval ac_res=\$$as_CACHEVAR
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if test x"`eval 'as_val=${'$as_CACHEVAR'};$as_echo "$as_val"'`" = xyes; then :
+  if ${LDFLAGS+:} false; then :
+  case " $LDFLAGS " in
+    *" $flag "*)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : LDFLAGS already contains \$flag"; } >&5
+  (: LDFLAGS already contains $flag) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      ;;
+    *)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : LDFLAGS=\"\$LDFLAGS \$flag\""; } >&5
+  (: LDFLAGS="$LDFLAGS $flag") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      LDFLAGS="$LDFLAGS $flag"
+      ;;
+   esac
+else
+  LDFLAGS="$flag"
+fi
+
+else
+  :
+fi
+
+done
+
+ fi
+
+ ## for clang: -Wunneeded-internal-declaration
+
+ if test "x${ENABLE_OPTIMIZATION}" != xno; then
+  OPTFLAGS="-O3 -Wno-unused-function -Wno-trigraphs -Wno-unused-parameter -Wunknown-pragmas -Wno-unused-variable -fomit-frame-pointer -fwrapv -fvisibility=default -finline-functions -fno-exceptions -fno-rtti -fno-threadsafe-statics -fno-enforce-eh-specs -fconserve-space -funroll-loops"
+  #  -O3 - crashes gcc???!!!
+  # -fpermissive
+  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
+
+
+
+for flag in ${OPTFLAGS}; do
+  as_CACHEVAR=`$as_echo "ax_cv_check_cflags__$flag" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts $flag" >&5
+$as_echo_n "checking whether C compiler accepts $flag... " >&6; }
+if eval \${$as_CACHEVAR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$CFLAGS
+  CFLAGS="$CFLAGS  $flag -Werror"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  eval "$as_CACHEVAR=yes"
+else
+  eval "$as_CACHEVAR=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  CFLAGS=$ax_check_save_flags
+fi
+eval ac_res=\$$as_CACHEVAR
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if test x"`eval 'as_val=${'$as_CACHEVAR'};$as_echo "$as_val"'`" = xyes; then :
+  if ${CFLAGS+:} false; then :
+  case " $CFLAGS " in
+    *" $flag "*)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS already contains \$flag"; } >&5
+  (: CFLAGS already contains $flag) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      ;;
+    *)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS=\"\$CFLAGS \$flag\""; } >&5
+  (: CFLAGS="$CFLAGS $flag") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      CFLAGS="$CFLAGS $flag"
+      ;;
+   esac
+else
+  CFLAGS="$flag"
+fi
+
+else
+  :
+fi
+
+done
+
+  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=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+
+for flag in ${OPTFLAGS}; do
+  as_CACHEVAR=`$as_echo "ax_cv_check_cxxflags__$flag" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C++ compiler accepts $flag" >&5
+$as_echo_n "checking whether C++ compiler accepts $flag... " >&6; }
+if eval \${$as_CACHEVAR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$CXXFLAGS
+  CXXFLAGS="$CXXFLAGS  $flag -Werror"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  eval "$as_CACHEVAR=yes"
+else
+  eval "$as_CACHEVAR=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  CXXFLAGS=$ax_check_save_flags
+fi
+eval ac_res=\$$as_CACHEVAR
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if test x"`eval 'as_val=${'$as_CACHEVAR'};$as_echo "$as_val"'`" = xyes; then :
+  if ${CXXFLAGS+:} false; then :
+  case " $CXXFLAGS " in
+    *" $flag "*)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CXXFLAGS already contains \$flag"; } >&5
+  (: CXXFLAGS already contains $flag) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      ;;
+    *)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CXXFLAGS=\"\$CXXFLAGS \$flag\""; } >&5
+  (: CXXFLAGS="$CXXFLAGS $flag") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      CXXFLAGS="$CXXFLAGS $flag"
+      ;;
+   esac
+else
+  CXXFLAGS="$flag"
+fi
+
+else
+  :
+fi
+
+done
+
+#   AX_APPEND_COMPILE_FLAGS([-fno-threadsafe-statics -fno-enforce-eh-specs -fconserve-space], [CXXFLAGS])
+###  AX_APPEND_COMPILE_FLAGS([-fno-implicit-templates], [CXXFLAGS]) # problems due to STL
+  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
+
+
+
+for flag in ${OPTFLAGS}; do
+  as_CACHEVAR=`$as_echo "ax_cv_check_ldflags__$flag" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the linker accepts $flag" >&5
+$as_echo_n "checking whether the linker accepts $flag... " >&6; }
+if eval \${$as_CACHEVAR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$LDFLAGS
+  LDFLAGS="$LDFLAGS  $flag"
+  _save_cflags="$CFLAGS"
+  CFLAGS="$CFLAGS -Werror"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "$as_CACHEVAR=yes"
+else
+  eval "$as_CACHEVAR=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+  CFLAGS="$_save_cflags"
+  LDFLAGS=$ax_check_save_flags
+fi
+eval ac_res=\$$as_CACHEVAR
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if test x"`eval 'as_val=${'$as_CACHEVAR'};$as_echo "$as_val"'`" = xyes; then :
+  if ${LDFLAGS+:} false; then :
+  case " $LDFLAGS " in
+    *" $flag "*)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : LDFLAGS already contains \$flag"; } >&5
+  (: LDFLAGS already contains $flag) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      ;;
+    *)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : LDFLAGS=\"\$LDFLAGS \$flag\""; } >&5
+  (: LDFLAGS="$LDFLAGS $flag") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      LDFLAGS="$LDFLAGS $flag"
+      ;;
+   esac
+else
+  LDFLAGS="$flag"
+fi
+
+else
+  :
+fi
+
+done
+
+#  AX_APPEND_LINK_FLAGS([-fno-threadsafe-statics -fno-enforce-eh-specs -fconserve-space])
+###  AX_APPEND_LINK_FLAGS([-fno-implicit-templates]) # see above :(
+#  AX_APPEND_LINK_FLAGS([ ])
+ fi
+
+ FLAGS2="-Qunused-arguments"
+ 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
+
+
+
+for flag in ${FLAGS2}; do
+  as_CACHEVAR=`$as_echo "ax_cv_check_cflags__$flag" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts $flag" >&5
+$as_echo_n "checking whether C compiler accepts $flag... " >&6; }
+if eval \${$as_CACHEVAR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$CFLAGS
+  CFLAGS="$CFLAGS  $flag -Werror"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  eval "$as_CACHEVAR=yes"
+else
+  eval "$as_CACHEVAR=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  CFLAGS=$ax_check_save_flags
+fi
+eval ac_res=\$$as_CACHEVAR
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if test x"`eval 'as_val=${'$as_CACHEVAR'};$as_echo "$as_val"'`" = xyes; then :
+  if ${CFLAGS+:} false; then :
+  case " $CFLAGS " in
+    *" $flag "*)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS already contains \$flag"; } >&5
+  (: CFLAGS already contains $flag) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      ;;
+    *)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS=\"\$CFLAGS \$flag\""; } >&5
+  (: CFLAGS="$CFLAGS $flag") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      CFLAGS="$CFLAGS $flag"
+      ;;
+   esac
+else
+  CFLAGS="$flag"
+fi
+
+else
+  :
+fi
+
+done
+
+ 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=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+
+for flag in ${FLAGS2}; do
+  as_CACHEVAR=`$as_echo "ax_cv_check_cxxflags__$flag" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C++ compiler accepts $flag" >&5
+$as_echo_n "checking whether C++ compiler accepts $flag... " >&6; }
+if eval \${$as_CACHEVAR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$CXXFLAGS
+  CXXFLAGS="$CXXFLAGS  $flag -Werror"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  eval "$as_CACHEVAR=yes"
+else
+  eval "$as_CACHEVAR=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  CXXFLAGS=$ax_check_save_flags
+fi
+eval ac_res=\$$as_CACHEVAR
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if test x"`eval 'as_val=${'$as_CACHEVAR'};$as_echo "$as_val"'`" = xyes; then :
+  if ${CXXFLAGS+:} false; then :
+  case " $CXXFLAGS " in
+    *" $flag "*)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CXXFLAGS already contains \$flag"; } >&5
+  (: CXXFLAGS already contains $flag) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      ;;
+    *)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CXXFLAGS=\"\$CXXFLAGS \$flag\""; } >&5
+  (: CXXFLAGS="$CXXFLAGS $flag") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      CXXFLAGS="$CXXFLAGS $flag"
+      ;;
+   esac
+else
+  CXXFLAGS="$flag"
+fi
+
+else
+  :
+fi
+
+done
+
+ 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
+
+
+
+
+for flag in ${FLAGS2}; do
+  as_CACHEVAR=`$as_echo "ax_cv_check_ldflags__$flag" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the linker accepts $flag" >&5
+$as_echo_n "checking whether the linker accepts $flag... " >&6; }
+if eval \${$as_CACHEVAR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$LDFLAGS
+  LDFLAGS="$LDFLAGS  $flag"
+  _save_cflags="$CFLAGS"
+  CFLAGS="$CFLAGS -Werror"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "$as_CACHEVAR=yes"
+else
+  eval "$as_CACHEVAR=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+  CFLAGS="$_save_cflags"
+  LDFLAGS=$ax_check_save_flags
+fi
+eval ac_res=\$$as_CACHEVAR
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if test x"`eval 'as_val=${'$as_CACHEVAR'};$as_echo "$as_val"'`" = xyes; then :
+  if ${LDFLAGS+:} false; then :
+  case " $LDFLAGS " in
+    *" $flag "*)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : LDFLAGS already contains \$flag"; } >&5
+  (: LDFLAGS already contains $flag) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      ;;
+    *)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : LDFLAGS=\"\$LDFLAGS \$flag\""; } >&5
+  (: LDFLAGS="$LDFLAGS $flag") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      LDFLAGS="$LDFLAGS $flag"
+      ;;
+   esac
+else
+  LDFLAGS="$flag"
+fi
+
+else
+  :
+fi
+
+done
+
+
+# SING_SHOW_FLAGS([before PROG_C_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
+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 ${ac_cv_prog_CC+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_CC+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_CC+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_CC+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_CC+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_CC+:} false; 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 as_fn_executable_p "$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
+  fi
+  rm -f conftest.er1 conftest.err
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+done
+
+{ $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 ${ac_cv_c_compiler_gnu+:} false; 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 ${ac_cv_prog_cc_g+:} false; 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 ${ac_cv_prog_cc_c89+:} false; 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>
+struct stat;
+/* 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
+
+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 ${am_cv_CC_dependencies_compiler_type+:} false; 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".
+  rm -rf conftest.dir
+  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 10 /bin/sh.
+      echo '/* dummy */' > 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
+      ;;
+    msvc7 | msvc7msys | 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
+
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+if test -z "$CXX"; then
+  if test -n "$CCC"; then
+    CXX=$CCC
+  else
+    if test -n "$ac_tool_prefix"; then
+  for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+  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 ${ac_cv_prog_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CXX"; then
+  ac_cv_prog_CXX="$CXX" # 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CXX="$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
+CXX=$ac_cv_prog_CXX
+if test -n "$CXX"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5
+$as_echo "$CXX" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+    test -n "$CXX" && break
+  done
+fi
+if test -z "$CXX"; then
+  ac_ct_CXX=$CXX
+  for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+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 ${ac_cv_prog_ac_ct_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_CXX"; then
+  ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CXX="$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_CXX=$ac_cv_prog_ac_ct_CXX
+if test -n "$ac_ct_CXX"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5
+$as_echo "$ac_ct_CXX" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$ac_ct_CXX" && break
+done
+
+  if test "x$ac_ct_CXX" = x; then
+    CXX="g++"
+  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
+    CXX=$ac_ct_CXX
+  fi
+fi
+
+  fi
+fi
+# 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
+  fi
+  rm -f conftest.er1 conftest.err
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+done
+
+{ $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 ${ac_cv_cxx_compiler_gnu+:} false; 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_cxx_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_cxx_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5
+$as_echo "$ac_cv_cxx_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+  GXX=yes
+else
+  GXX=
+fi
+ac_test_CXXFLAGS=${CXXFLAGS+set}
+ac_save_CXXFLAGS=$CXXFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5
+$as_echo_n "checking whether $CXX accepts -g... " >&6; }
+if ${ac_cv_prog_cxx_g+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_save_cxx_werror_flag=$ac_cxx_werror_flag
+   ac_cxx_werror_flag=yes
+   ac_cv_prog_cxx_g=no
+   CXXFLAGS="-g"
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ac_cv_prog_cxx_g=yes
+else
+  CXXFLAGS=""
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+
+else
+  ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+	 CXXFLAGS="-g"
+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ac_cv_prog_cxx_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_cxx_werror_flag=$ac_save_cxx_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5
+$as_echo "$ac_cv_prog_cxx_g" >&6; }
+if test "$ac_test_CXXFLAGS" = set; then
+  CXXFLAGS=$ac_save_CXXFLAGS
+elif test $ac_cv_prog_cxx_g = yes; then
+  if test "$GXX" = yes; then
+    CXXFLAGS="-g -O2"
+  else
+    CXXFLAGS="-g"
+  fi
+else
+  if test "$GXX" = yes; then
+    CXXFLAGS="-O2"
+  else
+    CXXFLAGS=
+  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
+
+depcc="$CXX"  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 ${am_cv_CXX_dependencies_compiler_type+:} false; 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".
+  rm -rf conftest.dir
+  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_CXX_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 10 /bin/sh.
+      echo '/* dummy */' > 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
+      ;;
+    msvc7 | msvc7msys | 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_CXX_dependencies_compiler_type=$depmode
+        break
+      fi
+    fi
+  done
+
+  cd ..
+  rm -rf conftest.dir
+else
+  am_cv_CXX_dependencies_compiler_type=none
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5
+$as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; }
+CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type
+
+ if
+  test "x$enable_dependency_tracking" != xno \
+  && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then
+  am__fastdepCXX_TRUE=
+  am__fastdepCXX_FALSE='#'
+else
+  am__fastdepCXX_TRUE='#'
+  am__fastdepCXX_FALSE=
+fi
+
+
+
+
+if test "x$CC" != xcc; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC and cc understand -c and -o together" >&5
+$as_echo_n "checking whether $CC and cc understand -c and -o together... " >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether cc understands -c and -o together" >&5
+$as_echo_n "checking whether cc understands -c and -o together... " >&6; }
+fi
+set dummy $CC; ac_cc=`$as_echo "$2" |
+		      sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'`
+if eval \${ac_cv_prog_cc_${ac_cc}_c_o+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+# Make sure it works both with $CC and with simple cc.
+# We do the test twice because some compilers refuse to overwrite an
+# existing .o file with -o, though they will create one.
+ac_try='$CC -c conftest.$ac_ext -o conftest2.$ac_objext >&5'
+rm -f conftest2.*
+if { { 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; } &&
+   test -f conftest2.$ac_objext && { { 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
+  eval ac_cv_prog_cc_${ac_cc}_c_o=yes
+  if test "x$CC" != xcc; then
+    # Test first that cc exists at all.
+    if { ac_try='cc -c conftest.$ac_ext >&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_try") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then
+      ac_try='cc -c conftest.$ac_ext -o conftest2.$ac_objext >&5'
+      rm -f conftest2.*
+      if { { 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; } &&
+	 test -f conftest2.$ac_objext && { { 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
+	# cc works too.
+	:
+      else
+	# cc exists but doesn't like -o.
+	eval ac_cv_prog_cc_${ac_cc}_c_o=no
+      fi
+    fi
+  fi
+else
+  eval ac_cv_prog_cc_${ac_cc}_c_o=no
+fi
+rm -f core conftest*
+
+fi
+if eval test \$ac_cv_prog_cc_${ac_cc}_c_o = yes; 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; }
+
+$as_echo "#define NO_MINUS_C_MINUS_O 1" >>confdefs.h
+
+fi
+
+# FIXME: we rely on the cache variable name because
+# there is no other way.
+set dummy $CC
+am_cc=`echo $2 | sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'`
+eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o
+if test "$am_t" != yes; then
+   # Losing compiler, so override with the script.
+   # FIXME: It is wrong to rewrite CC.
+   # But if we don't then we get into trouble of one sort or another.
+   # A longer-term fix would be to have automake use am__CC in this case,
+   # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
+   CC="$am_aux_dir/compile $CC"
+fi
+
+
+# AM_PROG_AR
+
+{ $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
+
+
+
+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 ${ac_cv_prog_CPP+:} false; 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.i 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.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i 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.i 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.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i 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 grep that handles long lines and -e" >&5
+$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
+if ${ac_cv_path_GREP+:} false; 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"
+      as_fn_executable_p "$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 ${ac_cv_path_EGREP+:} false; 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"
+      as_fn_executable_p "$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 ANSI C header files" >&5
+$as_echo_n "checking for ANSI C header files... " >&6; }
+if ${ac_cv_header_stdc+:} false; 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
+"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+for ac_header in stdlib.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "stdlib.h" "ac_cv_header_stdlib_h" "$ac_includes_default"
+if test "x$ac_cv_header_stdlib_h" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_STDLIB_H 1
+_ACEOF
+
+fi
+
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU libc compatible malloc" >&5
+$as_echo_n "checking for GNU libc compatible malloc... " >&6; }
+if ${ac_cv_func_malloc_0_nonnull+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test "$cross_compiling" = yes; then :
+  ac_cv_func_malloc_0_nonnull=no
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#if defined STDC_HEADERS || defined HAVE_STDLIB_H
+# include <stdlib.h>
+#else
+char *malloc ();
+#endif
+
+int
+main ()
+{
+return ! malloc (0);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  ac_cv_func_malloc_0_nonnull=yes
+else
+  ac_cv_func_malloc_0_nonnull=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
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_malloc_0_nonnull" >&5
+$as_echo "$ac_cv_func_malloc_0_nonnull" >&6; }
+if test $ac_cv_func_malloc_0_nonnull = yes; then :
+
+$as_echo "#define HAVE_MALLOC 1" >>confdefs.h
+
+else
+  $as_echo "#define HAVE_MALLOC 0" >>confdefs.h
+
+   case " $LIBOBJS " in
+  *" malloc.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS malloc.$ac_objext"
+ ;;
+esac
+
+
+$as_echo "#define malloc rpl_malloc" >>confdefs.h
+
+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 ${ac_cv_header_stdc+:} false; 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
+
+for ac_header in stdlib.h string.h unistd.h pwd.h sys/param.h sys/stat.h sys/types.h
+do :
+  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+for ac_func in readlink getcwd getwd getpwnam setenv putenv
+do :
+  as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+# Checks for typedefs, structures, and compiler characteristics.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5
+$as_echo_n "checking for an ANSI C-conforming const... " >&6; }
+if ${ac_cv_c_const+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+#ifndef __cplusplus
+  /* Ultrix mips cc rejects this sort of thing.  */
+  typedef int charset[2];
+  const charset cs = { 0, 0 };
+  /* SunOS 4.1.1 cc rejects this.  */
+  char const *const *pcpcc;
+  char **ppc;
+  /* NEC SVR4.0.2 mips cc rejects this.  */
+  struct point {int x, y;};
+  static struct point const zero = {0,0};
+  /* AIX XL C 1.02.0.0 rejects this.
+     It does not let you subtract one const X* pointer from another in
+     an arm of an if-expression whose if-part is not a constant
+     expression */
+  const char *g = "string";
+  pcpcc = &g + (g ? g-g : 0);
+  /* HPUX 7.0 cc rejects these. */
+  ++pcpcc;
+  ppc = (char**) pcpcc;
+  pcpcc = (char const *const *) ppc;
+  { /* SCO 3.2v4 cc rejects this sort of thing.  */
+    char tx;
+    char *t = &tx;
+    char const *s = 0 ? (char *) 0 : (char const *) 0;
+
+    *t++ = 0;
+    if (s) return 0;
+  }
+  { /* Someone thinks the Sun supposedly-ANSI compiler will reject this.  */
+    int x[] = {25, 17};
+    const int *foo = &x[0];
+    ++foo;
+  }
+  { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
+    typedef const int *iptr;
+    iptr p = 0;
+    ++p;
+  }
+  { /* AIX XL C 1.02.0.0 rejects this sort of thing, saying
+       "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
+    struct s { int j; const int *ap[3]; } bx;
+    struct s *b = &bx; b->j = 5;
+  }
+  { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
+    const int foo = 10;
+    if (!foo) return 0;
+  }
+  return !cs[0] && !zero.x;
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_c_const=yes
+else
+  ac_cv_c_const=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5
+$as_echo "$ac_cv_c_const" >&6; }
+if test $ac_cv_c_const = no; then
+
+$as_echo "#define const /**/" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5
+$as_echo_n "checking for inline... " >&6; }
+if ${ac_cv_c_inline+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_cv_c_inline=no
+for ac_kw in inline __inline__ __inline; do
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifndef __cplusplus
+typedef int foo_t;
+static $ac_kw foo_t static_foo () {return 0; }
+$ac_kw foo_t foo () {return 0; }
+#endif
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_c_inline=$ac_kw
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  test "$ac_cv_c_inline" != no && break
+done
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5
+$as_echo "$ac_cv_c_inline" >&6; }
+
+case $ac_cv_c_inline in
+  inline | yes) ;;
+  *)
+    case $ac_cv_c_inline in
+      no) ac_val=;;
+      *) ac_val=$ac_cv_c_inline;;
+    esac
+    cat >>confdefs.h <<_ACEOF
+#ifndef __cplusplus
+#define inline $ac_val
+#endif
+_ACEOF
+    ;;
+esac
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdbool.h that conforms to C99" >&5
+$as_echo_n "checking for stdbool.h that conforms to C99... " >&6; }
+if ${ac_cv_header_stdbool_h+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+             #include <stdbool.h>
+             #ifndef bool
+              "error: bool is not defined"
+             #endif
+             #ifndef false
+              "error: false is not defined"
+             #endif
+             #if false
+              "error: false is not 0"
+             #endif
+             #ifndef true
+              "error: true is not defined"
+             #endif
+             #if true != 1
+              "error: true is not 1"
+             #endif
+             #ifndef __bool_true_false_are_defined
+              "error: __bool_true_false_are_defined is not defined"
+             #endif
+
+             struct s { _Bool s: 1; _Bool t; } s;
+
+             char a[true == 1 ? 1 : -1];
+             char b[false == 0 ? 1 : -1];
+             char c[__bool_true_false_are_defined == 1 ? 1 : -1];
+             char d[(bool) 0.5 == true ? 1 : -1];
+             /* See body of main program for 'e'.  */
+             char f[(_Bool) 0.0 == false ? 1 : -1];
+             char g[true];
+             char h[sizeof (_Bool)];
+             char i[sizeof s.t];
+             enum { j = false, k = true, l = false * true, m = true * 256 };
+             /* The following fails for
+                HP aC++/ANSI C B3910B A.05.55 [Dec 04 2003]. */
+             _Bool n[m];
+             char o[sizeof n == m * sizeof n[0] ? 1 : -1];
+             char p[-1 - (_Bool) 0 < 0 && -1 - (bool) 0 < 0 ? 1 : -1];
+             /* Catch a bug in an HP-UX C compiler.  See
+                http://gcc.gnu.org/ml/gcc-patches/2003-12/msg02303.html
+                http://lists.gnu.org/archive/html/bug-coreutils/2005-11/msg00161.html
+              */
+             _Bool q = true;
+             _Bool *pq = &q;
+
+int
+main ()
+{
+
+             bool e = &s;
+             *pq |= q;
+             *pq |= ! q;
+             /* Refer to every declared value, to avoid compiler optimizations.  */
+             return (!a + !b + !c + !d + !e + !f + !g + !h + !i + !!j + !k + !!l
+                     + !m + !n + !o + !p + !q + !pq);
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_header_stdbool_h=yes
+else
+  ac_cv_header_stdbool_h=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdbool_h" >&5
+$as_echo "$ac_cv_header_stdbool_h" >&6; }
+   ac_fn_c_check_type "$LINENO" "_Bool" "ac_cv_type__Bool" "$ac_includes_default"
+if test "x$ac_cv_type__Bool" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE__BOOL 1
+_ACEOF
+
+
+fi
+
+
+if test $ac_cv_header_stdbool_h = yes; then
+
+$as_echo "#define HAVE_STDBOOL_H 1" >>confdefs.h
+
+fi
+
+ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default"
+if test "x$ac_cv_type_size_t" = xyes; then :
+
+else
+
+cat >>confdefs.h <<_ACEOF
+#define size_t unsigned int
+_ACEOF
+
+fi
+
+
+# Turn off shared libraries during beta-testing, since they
+# make the build process take too long.
+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.4.2'
+macro_revision='1.3337'
+
+
+
+
+
+
+
+
+
+
+
+
+
+ltmain="$ac_aux_dir/ltmain.sh"
+
+# 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 ${ac_cv_build+:} false; 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 ${ac_cv_host+:} false; 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
+
+
+# Backslashify 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'
+
+ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5
+$as_echo_n "checking how to print strings... " >&6; }
+# Test print first, because it will be a builtin if present.
+if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \
+   test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then
+  ECHO='print -r --'
+elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then
+  ECHO='printf %s\n'
+else
+  # Use this function as a fallback that always works.
+  func_fallback_echo ()
+  {
+    eval 'cat <<_LTECHO_EOF
+$1
+_LTECHO_EOF'
+  }
+  ECHO='func_fallback_echo'
+fi
+
+# func_echo_all arg...
+# Invoke $ECHO with all args, space-separated.
+func_echo_all ()
+{
+    $ECHO ""
+}
+
+case "$ECHO" in
+  printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5
+$as_echo "printf" >&6; } ;;
+  print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5
+$as_echo "print -r" >&6; } ;;
+  *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5
+$as_echo "cat" >&6; } ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+{ $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 ${ac_cv_path_SED+:} false; 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"
+      as_fn_executable_p "$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 fgrep" >&5
+$as_echo_n "checking for fgrep... " >&6; }
+if ${ac_cv_path_FGREP+:} false; 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"
+      as_fn_executable_p "$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 ${lt_cv_path_LD+:} false; 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 ${lt_cv_prog_gnu_ld+:} false; 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 ${lt_cv_path_NM+:} false; 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 "$DUMPBIN"; then :
+    # Let the user override the test.
+  else
+    if test -n "$ac_tool_prefix"; then
+  for ac_prog in dumpbin "link -dump"
+  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 ${ac_cv_prog_DUMPBIN+:} false; 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 as_fn_executable_p "$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 "link -dump"
+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 ${ac_cv_prog_ac_ct_DUMPBIN+:} false; 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 as_fn_executable_p "$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
+
+    case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in
+    *COFF*)
+      DUMPBIN="$DUMPBIN -symbols"
+      ;;
+    *)
+      DUMPBIN=:
+      ;;
+    esac
+  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 ${lt_cv_nm_interface+:} false; 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:$LINENO: $ac_compile\"" >&5)
+  (eval "$ac_compile" 2>conftest.err)
+  cat conftest.err >&5
+  (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
+  (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
+  cat conftest.err >&5
+  (eval echo "\"\$as_me:$LINENO: 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; }
+
+# 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 ${lt_cv_sys_max_cmd_len+:} false; 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;
+    ;;
+
+  mint*)
+    # On MiNT this can take a long time and run out of memory.
+    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
+    ;;
+
+  os2*)
+    # The test takes a long time on OS/2.
+    lt_cv_sys_max_cmd_len=8192
+    ;;
+
+  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"`env echo "$teststring$teststring" 2>/dev/null` \
+	         = "X$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%"$_lt_dummy"}, \
+      = c,a/b,b/c, \
+    && 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 how to convert $build file names to $host format" >&5
+$as_echo_n "checking how to convert $build file names to $host format... " >&6; }
+if ${lt_cv_to_host_file_cmd+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $host in
+  *-*-mingw* )
+    case $build in
+      *-*-mingw* ) # actually msys
+        lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32
+        ;;
+      *-*-cygwin* )
+        lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32
+        ;;
+      * ) # otherwise, assume *nix
+        lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32
+        ;;
+    esac
+    ;;
+  *-*-cygwin* )
+    case $build in
+      *-*-mingw* ) # actually msys
+        lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin
+        ;;
+      *-*-cygwin* )
+        lt_cv_to_host_file_cmd=func_convert_file_noop
+        ;;
+      * ) # otherwise, assume *nix
+        lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin
+        ;;
+    esac
+    ;;
+  * ) # unhandled hosts (and "normal" native builds)
+    lt_cv_to_host_file_cmd=func_convert_file_noop
+    ;;
+esac
+
+fi
+
+to_host_file_cmd=$lt_cv_to_host_file_cmd
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5
+$as_echo "$lt_cv_to_host_file_cmd" >&6; }
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5
+$as_echo_n "checking how to convert $build file names to toolchain format... " >&6; }
+if ${lt_cv_to_tool_file_cmd+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  #assume ordinary cross tools, or native build.
+lt_cv_to_tool_file_cmd=func_convert_file_noop
+case $host in
+  *-*-mingw* )
+    case $build in
+      *-*-mingw* ) # actually msys
+        lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32
+        ;;
+    esac
+    ;;
+esac
+
+fi
+
+to_tool_file_cmd=$lt_cv_to_tool_file_cmd
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5
+$as_echo "$lt_cv_to_tool_file_cmd" >&6; }
+
+
+
+
+
+{ $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 ${lt_cv_ld_reload_flag+:} false; 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
+  cygwin* | mingw* | pw32* | cegcc*)
+    if test "$GCC" != yes; then
+      reload_cmds=false
+    fi
+    ;;
+  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 ${ac_cv_prog_OBJDUMP+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_OBJDUMP+:} false; 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 as_fn_executable_p "$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 ${lt_cv_deplibs_check_method+:} false; 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.
+  # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin.
+  if ( test "$lt_cv_nm_interface" = "BSD nm" && 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
+    # Keep this pattern in sync with the one in func_win32_libid.
+    lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)'
+    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
+  ;;
+
+haiku*)
+  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])(-bit)?( [LM]SB)? 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 glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+netbsd*)
+  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_glob=
+want_nocaseglob=no
+if test "$build" = "$host"; then
+  case $host_os in
+  mingw* | pw32*)
+    if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then
+      want_nocaseglob=yes
+    else
+      file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"`
+    fi
+    ;;
+  esac
+fi
+
+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}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 ${ac_cv_prog_DLLTOOL+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_DLLTOOL+:} false; 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 as_fn_executable_p "$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
+
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5
+$as_echo_n "checking how to associate runtime and link libraries... " >&6; }
+if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_sharedlib_from_linklib_cmd='unknown'
+
+case $host_os in
+cygwin* | mingw* | pw32* | cegcc*)
+  # two different shell functions defined in ltmain.sh
+  # decide which to use based on capabilities of $DLLTOOL
+  case `$DLLTOOL --help 2>&1` in
+  *--identify-strict*)
+    lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib
+    ;;
+  *)
+    lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback
+    ;;
+  esac
+  ;;
+*)
+  # fallback: assume linklib IS sharedlib
+  lt_cv_sharedlib_from_linklib_cmd="$ECHO"
+  ;;
+esac
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5
+$as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; }
+sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd
+test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+  for ac_prog in ar
+  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 ${ac_cv_prog_AR+:} false; 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_AR="$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
+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
+
+
+    test -n "$AR" && break
+  done
+fi
+if test -z "$AR"; then
+  ac_ct_AR=$AR
+  for ac_prog in ar
+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 ${ac_cv_prog_ac_ct_AR+:} false; 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_AR="$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_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
+
+
+  test -n "$ac_ct_AR" && break
+done
+
+  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
+fi
+
+: ${AR=ar}
+: ${AR_FLAGS=cru}
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5
+$as_echo_n "checking for archiver @FILE support... " >&6; }
+if ${lt_cv_ar_at_file+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_ar_at_file=no
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  echo conftest.$ac_objext > conftest.lst
+      lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5'
+      { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5
+  (eval $lt_ar_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      if test "$ac_status" -eq 0; then
+	# Ensure the archiver fails upon bogus file names.
+	rm -f conftest.$ac_objext libconftest.a
+	{ { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5
+  (eval $lt_ar_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+	if test "$ac_status" -ne 0; then
+          lt_cv_ar_at_file=@
+        fi
+      fi
+      rm -f conftest.* libconftest.a
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5
+$as_echo "$lt_cv_ar_at_file" >&6; }
+
+if test "x$lt_cv_ar_at_file" = xno; then
+  archiver_list_spec=
+else
+  archiver_list_spec=$lt_cv_ar_at_file
+fi
+
+
+
+
+
+
+
+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 ${ac_cv_prog_STRIP+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_STRIP+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_RANLIB+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_RANLIB+:} false; 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 as_fn_executable_p "$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 \$tool_oldlib"
+    ;;
+  *)
+    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib"
+    ;;
+  esac
+  old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib"
+fi
+
+case $host_os in
+  darwin*)
+    lock_old_archive_extraction=yes ;;
+  *)
+    lock_old_archive_extraction=no ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 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 ${lt_cv_sys_global_symbol_pipe+:} false; 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};"\
+"     /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\
+"     /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
+  lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'"
+
+  # 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
+/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests.  */
+#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE)
+/* DATA imports from DLLs on WIN32 con't be const, because runtime
+   relocations are performed -- see ld's documentation on pseudo-relocs.  */
+# define LT_DLSYM_CONST
+#elif defined(__osf__)
+/* This system does not cope well with relocations in const data.  */
+# define LT_DLSYM_CONST
+#else
+# define LT_DLSYM_CONST const
+#endif
+
+#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.  */
+LT_DLSYM_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_globsym_save_LIBS=$LIBS
+	  lt_globsym_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_globsym_save_LIBS
+	  CFLAGS=$lt_globsym_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
+
+# Response file support.
+if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+  nm_file_list_spec='@'
+elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then
+  nm_file_list_spec='@'
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5
+$as_echo_n "checking for sysroot... " >&6; }
+
+# Check whether --with-sysroot was given.
+if test "${with_sysroot+set}" = set; then :
+  withval=$with_sysroot;
+else
+  with_sysroot=no
+fi
+
+
+lt_sysroot=
+case ${with_sysroot} in #(
+ yes)
+   if test "$GCC" = yes; then
+     lt_sysroot=`$CC --print-sysroot 2>/dev/null`
+   fi
+   ;; #(
+ /*)
+   lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"`
+   ;; #(
+ no|'')
+   ;; #(
+ *)
+   { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${with_sysroot}" >&5
+$as_echo "${with_sysroot}" >&6; }
+   as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5
+   ;;
+esac
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5
+$as_echo "${lt_sysroot:-no}" >&6; }
+
+
+
+
+
+# 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 '$LINENO' "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 ${lt_cv_cc_needs_belf+:} false; 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
+  ;;
+*-*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*)
+        case $host in
+        i?86-*-solaris*)
+          LD="${LD-ld} -m elf_x86_64"
+          ;;
+        sparc*-*-solaris*)
+          LD="${LD-ld} -m elf64_sparc"
+          ;;
+        esac
+        # GNU ld 2.21 introduced _sol2 emulations.  Use them if available.
+        if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then
+          LD="${LD-ld}_sol2"
+        fi
+        ;;
+      *)
+	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"
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args.
+set dummy ${ac_tool_prefix}mt; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_MANIFEST_TOOL+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$MANIFEST_TOOL"; then
+  ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt"
+    $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
+MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL
+if test -n "$MANIFEST_TOOL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5
+$as_echo "$MANIFEST_TOOL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_MANIFEST_TOOL"; then
+  ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL
+  # Extract the first word of "mt", so it can be a program name with args.
+set dummy mt; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_MANIFEST_TOOL"; then
+  ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_MANIFEST_TOOL="mt"
+    $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_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL
+if test -n "$ac_ct_MANIFEST_TOOL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5
+$as_echo "$ac_ct_MANIFEST_TOOL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_MANIFEST_TOOL" = x; then
+    MANIFEST_TOOL=":"
+  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
+    MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL
+  fi
+else
+  MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL"
+fi
+
+test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5
+$as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; }
+if ${lt_cv_path_mainfest_tool+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_path_mainfest_tool=no
+  echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5
+  $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out
+  cat conftest.err >&5
+  if $GREP 'Manifest Tool' conftest.out > /dev/null; then
+    lt_cv_path_mainfest_tool=yes
+  fi
+  rm -f conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5
+$as_echo "$lt_cv_path_mainfest_tool" >&6; }
+if test "x$lt_cv_path_mainfest_tool" != xyes; then
+  MANIFEST_TOOL=:
+fi
+
+
+
+
+
+
+  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 ${ac_cv_prog_DSYMUTIL+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_NMEDIT+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_NMEDIT+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_LIPO+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_LIPO+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_OTOOL+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_OTOOL+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_OTOOL64+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_OTOOL64+:} false; 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 as_fn_executable_p "$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 ${lt_cv_apple_cc_single_mod+:} false; 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 there is a non-empty error log, and "single_module"
+	# appears in it, assume the flag caused a linker warning
+        if test -s conftest.err && $GREP single_module conftest.err; then
+	  cat conftest.err >&5
+	# Otherwise, if the output was created with a 0 exit code from
+	# the compiler, it worked.
+	elif test -f libconftest.dylib && test $_lt_result -eq 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 ${lt_cv_ld_exported_symbols_list+:} false; 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; }
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5
+$as_echo_n "checking for -force_load linker flag... " >&6; }
+if ${lt_cv_ld_force_load+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_ld_force_load=no
+      cat > conftest.c << _LT_EOF
+int forced_loaded() { return 2;}
+_LT_EOF
+      echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5
+      $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5
+      echo "$AR cru libconftest.a conftest.o" >&5
+      $AR cru libconftest.a conftest.o 2>&5
+      echo "$RANLIB libconftest.a" >&5
+      $RANLIB libconftest.a 2>&5
+      cat > conftest.c << _LT_EOF
+int main() { return 0;}
+_LT_EOF
+      echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5
+      $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err
+      _lt_result=$?
+      if test -s conftest.err && $GREP force_load conftest.err; then
+	cat conftest.err >&5
+      elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then
+	lt_cv_ld_force_load=yes
+      else
+	cat conftest.err >&5
+      fi
+        rm -f conftest.err libconftest.a conftest conftest.c
+        rm -rf conftest.dSYM
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5
+$as_echo "$lt_cv_ld_force_load" >&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" != ":" && test "$lt_cv_ld_force_load" = "no"; then
+      _lt_dsymutil='~$DSYMUTIL $lib || :'
+    else
+      _lt_dsymutil=
+    fi
+    ;;
+  esac
+
+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" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_DLFCN_H 1
+_ACEOF
+
+fi
+
+done
+
+
+
+func_stripname_cnf ()
+{
+  case ${2} in
+  .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;;
+  *)  func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;;
+  esac
+} # func_stripname_cnf
+
+
+
+
+
+# Set options
+
+
+
+        enable_dlopen=no
+
+
+  enable_win32_dll=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; lt_p=${PACKAGE-default}
+    case $withval in
+    yes|no) pic_mode=$withval ;;
+    *)
+      pic_mode=default
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for lt_pkg in $withval; do
+	IFS="$lt_save_ifs"
+	if test "X$lt_pkg" = "X$lt_p"; then
+	  pic_mode=yes
+	fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac
+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 ${lt_cv_objdir+:} false; 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
+
+# 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 "$cc_temp" | $SED "s%.*/%%; 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 ${lt_cv_path_MAGIC_CMD+:} false; 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 ${lt_cv_path_MAGIC_CMD+:} false; 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*
+
+
+## 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...
+if test -n "$compiler"; then
+
+lt_prog_compiler_no_builtin_flag=
+
+if test "$GCC" = yes; then
+  case $cc_basename in
+  nvcc*)
+    lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;;
+  *)
+    lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;;
+  esac
+
+  { $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 ${lt_cv_prog_compiler_rtti_exceptions+:} false; 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:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $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 "$_lt_compiler_boilerplate" | $SED '/^$/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=
+
+
+  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'
+      ;;
+
+    haiku*)
+      # PIC is the default for Haiku.
+      # The "-static" flag exists, but is broken.
+      lt_prog_compiler_static=
+      ;;
+
+    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
+
+    case $cc_basename in
+    nvcc*) # Cuda Compiler Driver 2.2
+      lt_prog_compiler_wl='-Xlinker '
+      if test -n "$lt_prog_compiler_pic"; then
+        lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic"
+      fi
+      ;;
+    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 | kopensolaris*-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'
+	;;
+      nagfor*)
+	# NAG Fortran compiler
+	lt_prog_compiler_wl='-Wl,-Wl,,'
+	lt_prog_compiler_pic='-PIC'
+	lt_prog_compiler_static='-Bstatic'
+	;;
+      pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
+        # 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* | bgxl* | bgf* | mpixl*)
+	# IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene
+	lt_prog_compiler_wl='-Wl,'
+	lt_prog_compiler_pic='-qpic'
+	lt_prog_compiler_static='-qstaticlink'
+	;;
+      *)
+	case `$CC -V 2>&1 | sed 5q` in
+	*Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*)
+	  # 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=''
+	  ;;
+	*Sun\ F* | *Sun*Fortran*)
+	  lt_prog_compiler_pic='-KPIC'
+	  lt_prog_compiler_static='-Bstatic'
+	  lt_prog_compiler_wl='-Qoption ld '
+	  ;;
+	*Sun\ C*)
+	  # Sun C 5.9
+	  lt_prog_compiler_pic='-KPIC'
+	  lt_prog_compiler_static='-Bstatic'
+	  lt_prog_compiler_wl='-Wl,'
+	  ;;
+        *Intel*\ [CF]*Compiler*)
+	  lt_prog_compiler_wl='-Wl,'
+	  lt_prog_compiler_pic='-fPIC'
+	  lt_prog_compiler_static='-static'
+	  ;;
+	*Portland\ Group*)
+	  lt_prog_compiler_wl='-Wl,'
+	  lt_prog_compiler_pic='-fpic'
+	  lt_prog_compiler_static='-Bstatic'
+	  ;;
+	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* | sunf77* | sunf90* | sunf95*)
+	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}: checking for $compiler option to produce PIC" >&5
+$as_echo_n "checking for $compiler option to produce PIC... " >&6; }
+if ${lt_cv_prog_compiler_pic+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_pic=$lt_prog_compiler_pic
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5
+$as_echo "$lt_cv_prog_compiler_pic" >&6; }
+lt_prog_compiler_pic=$lt_cv_prog_compiler_pic
+
+#
+# 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 ${lt_cv_prog_compiler_pic_works+:} false; 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:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $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 "$_lt_compiler_boilerplate" | $SED '/^$/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 ${lt_cv_prog_compiler_static_works+:} false; 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 "$_lt_linker_boilerplate" | $SED '/^$/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 ${lt_cv_prog_compiler_c_o+:} false; 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:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $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 "$_lt_compiler_boilerplate" | $SED '/^$/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 ${lt_cv_prog_compiler_c_o+:} false; 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:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $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 "$_lt_compiler_boilerplate" | $SED '/^$/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_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
+    ;;
+  esac
+
+  ld_shlibs=yes
+
+  # On some targets, GNU ld is compatible enough with the native linker
+  # that we're better off using the native interface for both.
+  lt_use_gnu_ld_interface=no
+  if test "$with_gnu_ld" = yes; then
+    case $host_os in
+      aix*)
+	# The AIX port of GNU ld has always aspired to compatibility
+	# with the native linker.  However, as the warning in the GNU ld
+	# block says, versions before 2.19.5* couldn't really create working
+	# shared libraries, regardless of the interface used.
+	case `$LD -v 2>&1` in
+	  *\ \(GNU\ Binutils\)\ 2.19.5*) ;;
+	  *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;;
+	  *\ \(GNU\ Binutils\)\ [3-9]*) ;;
+	  *)
+	    lt_use_gnu_ld_interface=yes
+	    ;;
+	esac
+	;;
+      *)
+	lt_use_gnu_ld_interface=yes
+	;;
+    esac
+  fi
+
+  if test "$lt_use_gnu_ld_interface" = 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
+      *GNU\ gold*) supports_anon_versioning=yes ;;
+      *\ [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.19, 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 install binutils
+*** 2.20 or above, or modify your PATH so that a non-GNU linker is found.
+*** You will then need to restart the configuration process.
+
+_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'
+      export_dynamic_flag_spec='${wl}--export-all-symbols'
+      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/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols'
+      exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'
+
+      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
+      ;;
+
+    haiku*)
+      archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+      link_all_deplibs=yes
+      ;;
+
+    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 | kopensolaris*-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=' $pic_flag'
+	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; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+	  tmp_addflag=' $pic_flag'
+	  ;;
+	pgf77* | pgf90* | pgf95* | pgfortran*)
+					# 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; func_echo_all \"$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]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below)
+	  tmp_sharedflag='-qmkshrobj'
+	  tmp_addflag= ;;
+	nvcc*)	# Cuda Compiler Driver 2.2
+	  whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+	  compiler_needs_object=yes
+	  ;;
+	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; func_echo_all \"$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* | bgf* | bgxlf* | mpixlf*)
+	  # 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='${wl}-rpath ${wl}$libdir'
+	  archive_cmds='$LD -shared $libobjs $deplibs $linker_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 $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+	  fi
+	  ;;
+	esac
+      else
+        ld_shlibs=no
+      fi
+      ;;
+
+    netbsd*)
+      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 $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	archive_expsym_cmds='$CC -shared $pic_flag $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 $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	archive_expsym_cmds='$CC -shared $pic_flag $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 $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	archive_expsym_cmds='$CC -shared $pic_flag $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
+	# Also, AIX nm treats weak defined symbols like other global
+	# defined symbols, whereas GNU nm marks them as "W".
+	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") || (\$ 2 == "W")) && (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
+      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.
+        if test "${lt_cv_aix_libpath+set}" = set; then
+  aix_libpath=$lt_cv_aix_libpath
+else
+  if ${lt_cv_aix_libpath_+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  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
+	  }
+      }'
+  lt_cv_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 "$lt_cv_aix_libpath_"; then
+    lt_cv_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 "$lt_cv_aix_libpath_"; then
+    lt_cv_aix_libpath_="/usr/lib:/lib"
+  fi
+
+fi
+
+  aix_libpath=$lt_cv_aix_libpath_
+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 func_echo_all "${wl}${allow_undefined_flag}"; 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.
+	 if test "${lt_cv_aix_libpath+set}" = set; then
+  aix_libpath=$lt_cv_aix_libpath
+else
+  if ${lt_cv_aix_libpath_+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  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
+	  }
+      }'
+  lt_cv_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 "$lt_cv_aix_libpath_"; then
+    lt_cv_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 "$lt_cv_aix_libpath_"; then
+    lt_cv_aix_libpath_="/usr/lib:/lib"
+  fi
+
+fi
+
+  aix_libpath=$lt_cv_aix_libpath_
+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'
+	  if test "$with_gnu_ld" = yes; then
+	    # We only use this code for GNU lds that support --whole-archive.
+	    whole_archive_flag_spec='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+	  else
+	    # Exported symbols can be pulled into shared objects from archives
+	    whole_archive_flag_spec='$convenience'
+	  fi
+	  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.
+      case $cc_basename in
+      cl*)
+	# Native MSVC
+	hardcode_libdir_flag_spec=' '
+	allow_undefined_flag=unsupported
+	always_export_symbols=yes
+	file_list_spec='@'
+	# 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 $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
+	archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	    sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
+	  else
+	    sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
+	  fi~
+	  $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+	  linknames='
+	# The linker will not automatically build a static lib if we build a DLL.
+	# _LT_TAGVAR(old_archive_from_new_cmds, )='true'
+	enable_shared_with_static_runtimes=yes
+	exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
+	export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols'
+	# Don't use ranlib
+	old_postinstall_cmds='chmod 644 $oldlib'
+	postlink_cmds='lt_outputfile="@OUTPUT@"~
+	  lt_tool_outputfile="@TOOL_OUTPUT@"~
+	  case $lt_outputfile in
+	    *.exe|*.EXE) ;;
+	    *)
+	      lt_outputfile="$lt_outputfile.exe"
+	      lt_tool_outputfile="$lt_tool_outputfile.exe"
+	      ;;
+	  esac~
+	  if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
+	    $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+	    $RM "$lt_outputfile.manifest";
+	  fi'
+	;;
+      *)
+	# Assume MSVC wrapper
+	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 `func_echo_all "$deplibs" | $SED '\''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'
+	enable_shared_with_static_runtimes=yes
+	;;
+      esac
+      ;;
+
+    darwin* | rhapsody*)
+
+
+  archive_cmds_need_lc=no
+  hardcode_direct=no
+  hardcode_automatic=yes
+  hardcode_shlibpath_var=unsupported
+  if test "$lt_cv_ld_force_load" = "yes"; then
+    whole_archive_flag_spec='`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+
+  else
+    whole_archive_flag_spec=''
+  fi
+  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=func_echo_all
+    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
+      ;;
+
+    # 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 $pic_flag -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 $pic_flag ${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 && test "$with_gnu_ld" = no; then
+	archive_cmds='$CC -shared $pic_flag ${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_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 && test "$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 $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	*)
+	  archive_cmds='$CC -shared $pic_flag ${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'
+	  ;;
+	*)
+
+	  # Older versions of the 11.00 compiler do not understand -b yet
+	  # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does)
+	  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5
+$as_echo_n "checking if $CC understands -b... " >&6; }
+if ${lt_cv_prog_compiler__b+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler__b=no
+   save_LDFLAGS="$LDFLAGS"
+   LDFLAGS="$LDFLAGS -b"
+   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 "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
+       $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+       if diff conftest.exp conftest.er2 >/dev/null; then
+         lt_cv_prog_compiler__b=yes
+       fi
+     else
+       lt_cv_prog_compiler__b=yes
+     fi
+   fi
+   $RM -r conftest*
+   LDFLAGS="$save_LDFLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5
+$as_echo "$lt_cv_prog_compiler__b" >&6; }
+
+if test x"$lt_cv_prog_compiler__b" = xyes; then
+    archive_cmds='$CC -b ${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
+
+	  ;;
+	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 $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${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.
+	# This should be the same for all languages, so no per-tag cache variable.
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5
+$as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; }
+if ${lt_cv_irix_exported_symbol+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  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) { return 0; }
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  lt_cv_irix_exported_symbol=yes
+else
+  lt_cv_irix_exported_symbol=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_irix_exported_symbol" >&5
+$as_echo "$lt_cv_irix_exported_symbol" >&6; }
+	if test "$lt_cv_irix_exported_symbol" = yes; then
+          archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
+	fi
+      else
+	archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+	archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -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*)
+      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" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${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" && func_echo_all "-set_version $verstring"` -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} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${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" && func_echo_all "-set_version $verstring"` -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 "-set_version $verstring"` -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 $pic_flag ${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 $pic_flag ${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; }
+if ${lt_cv_archive_cmds_need_lc+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  $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
+	    lt_cv_archive_cmds_need_lc=no
+	  else
+	    lt_cv_archive_cmds_need_lc=yes
+	  fi
+	  allow_undefined_flag=$lt_save_allow_undefined_flag
+	else
+	  cat conftest.err 1>&5
+	fi
+	$RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5
+$as_echo "$lt_cv_archive_cmds_need_lc" >&6; }
+      archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc
+      ;;
+    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
+  case $host_os in
+    mingw* | cegcc*) lt_sed_strip_eq="s,=\([A-Za-z]:\),\1,g" ;;
+    *) lt_sed_strip_eq="s,=/,/,g" ;;
+  esac
+  lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq`
+  case $lt_search_path_spec in
+  *\;*)
+    # 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 's/;/ /g'`
+    ;;
+  *)
+    lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"`
+    ;;
+  esac
+  # 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; }
+}'`
+  # AWK program above erroneously prepends '/' to C:/dos/paths
+  # for these hosts.
+  case $host_os in
+    mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\
+      $SED 's,/\([A-Za-z]:\),\1,g'` ;;
+  esac
+  sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP`
+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 # correct to gnu/linux during the next big refactor
+  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 # correct to gnu/linux during the next big refactor
+  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=`func_echo_all "$lib" | $SED '\''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 # correct to gnu/linux during the next big refactor
+  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,$cc_basename in
+  yes,*)
+    # gcc
+    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="$sys_lib_search_path_spec /usr/lib/w32api"
+      ;;
+    mingw* | cegcc*)
+      # MinGW DLLs use traditional 'lib' prefix
+      soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      ;;
+    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
+    dynamic_linker='Win32 ld.exe'
+    ;;
+
+  *,cl*)
+    # Native MSVC
+    libname_spec='$name'
+    soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+    library_names_spec='${libname}.dll.lib'
+
+    case $build_os in
+    mingw*)
+      sys_lib_search_path_spec=
+      lt_save_ifs=$IFS
+      IFS=';'
+      for lt_path in $LIB
+      do
+        IFS=$lt_save_ifs
+        # Let DOS variable expansion print the short 8.3 style file name.
+        lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"`
+        sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path"
+      done
+      IFS=$lt_save_ifs
+      # Convert to MSYS style.
+      sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'`
+      ;;
+    cygwin*)
+      # Convert to unix form, then to dos form, then back to unix form
+      # but this time dos style (no spaces!) so that the unix form looks
+      # like /cygdrive/c/PROGRA~1:/cygdr...
+      sys_lib_search_path_spec=`cygpath --path --unix "$LIB"`
+      sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null`
+      sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+      ;;
+    *)
+      sys_lib_search_path_spec="$LIB"
+      if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then
+        # It is most probably a Windows format PATH.
+        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
+      # FIXME: find the short name or the path components, as spaces are
+      # common. (e.g. "Program Files" -> "PROGRA~1")
+      ;;
+    esac
+
+    # 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'
+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+      dlpath=$dir/\$dldll~
+       $RM \$dlpath'
+    shlibpath_overrides_runpath=yes
+    dynamic_linker='Win32 link.exe'
+    ;;
+
+  *)
+    # Assume MSVC wrapper
+    library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
+    dynamic_linker='Win32 ld.exe'
+    ;;
+  esac
+  # 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 # correct to gnu/linux during the next big refactor
+  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
+  ;;
+
+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[23].*) objformat=aout ;;
+    *) objformat=elf ;;
+    esac
+  fi
+  # Handle Gentoo/FreeBSD as it was Linux
+  case $host_vendor in
+    gentoo)
+      version_type=linux ;;
+    *)
+      version_type=freebsd-$objformat ;;
+  esac
+
+  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
+      ;;
+    linux)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+      soname_spec='${libname}${release}${shared_ext}$major'
+      need_lib_prefix=no
+      need_version=no
+      ;;
+  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 # correct to gnu/linux during the next big refactor
+  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
+  ;;
+
+haiku*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  dynamic_linker="$host_os runtime_loader"
+  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=LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
+  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'
+  # or fails outright, so override atomically:
+  install_override_mode=555
+  ;;
+
+interix[3-9]*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  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 # correct to gnu/linux during the next big refactor
+	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 glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  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
+  if ${lt_cv_shlibpath_overrides_runpath+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_shlibpath_overrides_runpath=no
+    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 :
+  lt_cv_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
+
+fi
+
+  shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath
+
+  # 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;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'
+  ;;
+
+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 # correct to gnu/linux during the next big refactor
+  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 # correct to gnu/linux during the next big refactor
+  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 # correct to gnu/linux during the next big refactor
+  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 # correct to gnu/linux during the next big refactor
+    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 # correct to gnu/linux during the next big refactor
+  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 # correct to gnu/linux during the next big refactor
+  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 ${ac_cv_lib_dl_dlopen+:} false; 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" = xyes; 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" = xyes; 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 ${ac_cv_lib_dld_shl_load+:} false; 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" = xyes; 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" = xyes; 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 ${ac_cv_lib_dl_dlopen+:} false; 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" = xyes; 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 ${ac_cv_lib_svld_dlopen+:} false; 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" = xyes; 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 ${ac_cv_lib_dld_dld_link+:} false; 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" = xyes; 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 ${lt_cv_dlopen_self+:} false; 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 $LINENO "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
+
+/* When -fvisbility=hidden is used, assume the code has been annotated
+   correspondingly for the symbols needed.  */
+#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+int fnord () __attribute__((visibility("default")));
+#endif
+
+int fnord () { return 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;
+          else puts (dlerror ());
+	}
+      /* 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 ${lt_cv_dlopen_self_static+:} false; 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 $LINENO "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
+
+/* When -fvisbility=hidden is used, assume the code has been annotated
+   correspondingly for the symbols needed.  */
+#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+int fnord () __attribute__((visibility("default")));
+#endif
+
+int fnord () { return 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;
+          else puts (dlerror ());
+	}
+      /* 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"
+
+      if test -n "$CXX" && ( test "X$CXX" != "Xno" &&
+    ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) ||
+    (test "X$CXX" != "Xg++"))) ; then
+  ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_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; }
+if test -z "$CXXCPP"; then
+  if ${ac_cv_prog_CXXCPP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+      # Double quotes because CXXCPP needs to be expanded
+    for CXXCPP in "$CXX -E" "/lib/cpp"
+    do
+      ac_preproc_ok=false
+for ac_cxx_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_cxx_try_cpp "$LINENO"; then :
+
+else
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i 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_cxx_try_cpp "$LINENO"; then :
+  # Broken: success on invalid input.
+continue
+else
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+  break
+fi
+
+    done
+    ac_cv_prog_CXXCPP=$CXXCPP
+
+fi
+  CXXCPP=$ac_cv_prog_CXXCPP
+else
+  ac_cv_prog_CXXCPP=$CXXCPP
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5
+$as_echo "$CXXCPP" >&6; }
+ac_preproc_ok=false
+for ac_cxx_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_cxx_try_cpp "$LINENO"; then :
+
+else
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i 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_cxx_try_cpp "$LINENO"; then :
+  # Broken: success on invalid input.
+continue
+else
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i 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 \"$CXXCPP\" 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
+
+else
+  _lt_caught_CXX_error=yes
+fi
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+archive_cmds_need_lc_CXX=no
+allow_undefined_flag_CXX=
+always_export_symbols_CXX=no
+archive_expsym_cmds_CXX=
+compiler_needs_object_CXX=no
+export_dynamic_flag_spec_CXX=
+hardcode_direct_CXX=no
+hardcode_direct_absolute_CXX=no
+hardcode_libdir_flag_spec_CXX=
+hardcode_libdir_separator_CXX=
+hardcode_minus_L_CXX=no
+hardcode_shlibpath_var_CXX=unsupported
+hardcode_automatic_CXX=no
+inherit_rpath_CXX=no
+module_cmds_CXX=
+module_expsym_cmds_CXX=
+link_all_deplibs_CXX=unknown
+old_archive_cmds_CXX=$old_archive_cmds
+reload_flag_CXX=$reload_flag
+reload_cmds_CXX=$reload_cmds
+no_undefined_flag_CXX=
+whole_archive_flag_spec_CXX=
+enable_shared_with_static_runtimes_CXX=no
+
+# Source file extension for C++ test sources.
+ac_ext=cpp
+
+# Object file extension for compiled C++ test sources.
+objext=o
+objext_CXX=$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.
+
+
+
+
+
+
+# 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_CFLAGS=$CFLAGS
+  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++"}
+  CFLAGS=$CXXFLAGS
+  compiler=$CC
+  compiler_CXX=$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 "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
+
+
+  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_prog_compiler_no_builtin_flag_CXX=' -fno-builtin'
+    else
+      lt_prog_compiler_no_builtin_flag_CXX=
+    fi
+
+    if test "$GXX" = yes; then
+      # Set up default GNU C++ configuration
+
+
+
+# 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 ${lt_cv_path_LD+:} false; 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 ${lt_cv_prog_gnu_ld+:} false; 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
+
+
+
+
+
+
+
+      # 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
+        archive_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+        archive_expsym_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+
+        hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+        export_dynamic_flag_spec_CXX='${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
+          whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+        else
+          whole_archive_flag_spec_CXX=
+        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.
+        archive_cmds_CXX='$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 -v "^Configured with:" | $GREP "\-L"'
+
+    else
+      GXX=no
+      with_gnu_ld=no
+      wlarc=
+    fi
+
+    # PORTME: fill in a description of your system's C++ link characteristics
+    { $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; }
+    ld_shlibs_CXX=yes
+    case $host_os in
+      aix3*)
+        # FIXME: insert proper C++ library support
+        ld_shlibs_CXX=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.
+
+        archive_cmds_CXX=''
+        hardcode_direct_CXX=yes
+        hardcode_direct_absolute_CXX=yes
+        hardcode_libdir_separator_CXX=':'
+        link_all_deplibs_CXX=yes
+        file_list_spec_CXX='${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
+	    hardcode_direct_CXX=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_CXX=yes
+	    hardcode_libdir_flag_spec_CXX='-L$libdir'
+	    hardcode_libdir_separator_CXX=
+	  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
+
+        export_dynamic_flag_spec_CXX='${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_CXX=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_CXX='-berok'
+          # Determine the default libpath from the value encoded in an empty
+          # executable.
+          if test "${lt_cv_aix_libpath+set}" = set; then
+  aix_libpath=$lt_cv_aix_libpath
+else
+  if ${lt_cv_aix_libpath__CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+
+  lt_aix_libpath_sed='
+      /Import File Strings/,/^$/ {
+	  /^0/ {
+	      s/^0  *\([^ ]*\) *$/\1/
+	      p
+	  }
+      }'
+  lt_cv_aix_libpath__CXX=`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 "$lt_cv_aix_libpath__CXX"; then
+    lt_cv_aix_libpath__CXX=`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 "$lt_cv_aix_libpath__CXX"; then
+    lt_cv_aix_libpath__CXX="/usr/lib:/lib"
+  fi
+
+fi
+
+  aix_libpath=$lt_cv_aix_libpath__CXX
+fi
+
+          hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath"
+
+          archive_expsym_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+        else
+          if test "$host_cpu" = ia64; then
+	    hardcode_libdir_flag_spec_CXX='${wl}-R $libdir:/usr/lib:/lib'
+	    allow_undefined_flag_CXX="-z nodefs"
+	    archive_expsym_cmds_CXX="\$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.
+	    if test "${lt_cv_aix_libpath+set}" = set; then
+  aix_libpath=$lt_cv_aix_libpath
+else
+  if ${lt_cv_aix_libpath__CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+
+  lt_aix_libpath_sed='
+      /Import File Strings/,/^$/ {
+	  /^0/ {
+	      s/^0  *\([^ ]*\) *$/\1/
+	      p
+	  }
+      }'
+  lt_cv_aix_libpath__CXX=`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 "$lt_cv_aix_libpath__CXX"; then
+    lt_cv_aix_libpath__CXX=`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 "$lt_cv_aix_libpath__CXX"; then
+    lt_cv_aix_libpath__CXX="/usr/lib:/lib"
+  fi
+
+fi
+
+  aix_libpath=$lt_cv_aix_libpath__CXX
+fi
+
+	    hardcode_libdir_flag_spec_CXX='${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_CXX=' ${wl}-bernotok'
+	    allow_undefined_flag_CXX=' ${wl}-berok'
+	    if test "$with_gnu_ld" = yes; then
+	      # We only use this code for GNU lds that support --whole-archive.
+	      whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+	    else
+	      # Exported symbols can be pulled into shared objects from archives
+	      whole_archive_flag_spec_CXX='$convenience'
+	    fi
+	    archive_cmds_need_lc_CXX=yes
+	    # This is similar to how AIX traditionally builds its shared
+	    # libraries.
+	    archive_expsym_cmds_CXX="\$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
+	  allow_undefined_flag_CXX=unsupported
+	  # Joseph Beckenbach <jrb3 at best.com> says some releases of gcc
+	  # support --undefined.  This deserves some investigation.  FIXME
+	  archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	else
+	  ld_shlibs_CXX=no
+	fi
+	;;
+
+      chorus*)
+        case $cc_basename in
+          *)
+	  # FIXME: insert proper C++ library support
+	  ld_shlibs_CXX=no
+	  ;;
+        esac
+        ;;
+
+      cygwin* | mingw* | pw32* | cegcc*)
+	case $GXX,$cc_basename in
+	,cl* | no,cl*)
+	  # Native MSVC
+	  # hardcode_libdir_flag_spec is actually meaningless, as there is
+	  # no search path for DLLs.
+	  hardcode_libdir_flag_spec_CXX=' '
+	  allow_undefined_flag_CXX=unsupported
+	  always_export_symbols_CXX=yes
+	  file_list_spec_CXX='@'
+	  # 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_CXX='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
+	  archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	      $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
+	    else
+	      $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
+	    fi~
+	    $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+	    linknames='
+	  # The linker will not automatically build a static lib if we build a DLL.
+	  # _LT_TAGVAR(old_archive_from_new_cmds, CXX)='true'
+	  enable_shared_with_static_runtimes_CXX=yes
+	  # Don't use ranlib
+	  old_postinstall_cmds_CXX='chmod 644 $oldlib'
+	  postlink_cmds_CXX='lt_outputfile="@OUTPUT@"~
+	    lt_tool_outputfile="@TOOL_OUTPUT@"~
+	    case $lt_outputfile in
+	      *.exe|*.EXE) ;;
+	      *)
+		lt_outputfile="$lt_outputfile.exe"
+		lt_tool_outputfile="$lt_tool_outputfile.exe"
+		;;
+	    esac~
+	    func_to_tool_file "$lt_outputfile"~
+	    if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
+	      $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+	      $RM "$lt_outputfile.manifest";
+	    fi'
+	  ;;
+	*)
+	  # g++
+	  # _LT_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless,
+	  # as there is no search path for DLLs.
+	  hardcode_libdir_flag_spec_CXX='-L$libdir'
+	  export_dynamic_flag_spec_CXX='${wl}--export-all-symbols'
+	  allow_undefined_flag_CXX=unsupported
+	  always_export_symbols_CXX=no
+	  enable_shared_with_static_runtimes_CXX=yes
+
+	  if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+	    archive_cmds_CXX='$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...
+	    archive_expsym_cmds_CXX='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
+	    ld_shlibs_CXX=no
+	  fi
+	  ;;
+	esac
+	;;
+      darwin* | rhapsody*)
+
+
+  archive_cmds_need_lc_CXX=no
+  hardcode_direct_CXX=no
+  hardcode_automatic_CXX=yes
+  hardcode_shlibpath_var_CXX=unsupported
+  if test "$lt_cv_ld_force_load" = "yes"; then
+    whole_archive_flag_spec_CXX='`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+
+  else
+    whole_archive_flag_spec_CXX=''
+  fi
+  link_all_deplibs_CXX=yes
+  allow_undefined_flag_CXX="$_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=func_echo_all
+    archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
+    module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
+    archive_expsym_cmds_CXX="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_CXX="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}"
+       if test "$lt_cv_apple_cc_single_mod" != "yes"; then
+      archive_cmds_CXX="\$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}"
+      archive_expsym_cmds_CXX="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
+  ld_shlibs_CXX=no
+  fi
+
+	;;
+
+      dgux*)
+        case $cc_basename in
+          ec++*)
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+          ghcx*)
+	    # Green Hills C++ Compiler
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+          *)
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+        esac
+        ;;
+
+      freebsd2.*)
+        # C++ shared libraries reported to be fairly broken before
+	# switch to ELF
+        ld_shlibs_CXX=no
+        ;;
+
+      freebsd-elf*)
+        archive_cmds_need_lc_CXX=no
+        ;;
+
+      freebsd* | dragonfly*)
+        # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF
+        # conventions
+        ld_shlibs_CXX=yes
+        ;;
+
+      gnu*)
+        ;;
+
+      haiku*)
+        archive_cmds_CXX='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+        link_all_deplibs_CXX=yes
+        ;;
+
+      hpux9*)
+        hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir'
+        hardcode_libdir_separator_CXX=:
+        export_dynamic_flag_spec_CXX='${wl}-E'
+        hardcode_direct_CXX=yes
+        hardcode_minus_L_CXX=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
+            ld_shlibs_CXX=no
+            ;;
+          aCC*)
+            archive_cmds_CXX='$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; func_echo_all "$list"'
+            ;;
+          *)
+            if test "$GXX" = yes; then
+              archive_cmds_CXX='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${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
+              ld_shlibs_CXX=no
+            fi
+            ;;
+        esac
+        ;;
+
+      hpux10*|hpux11*)
+        if test $with_gnu_ld = no; then
+	  hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir'
+	  hardcode_libdir_separator_CXX=:
+
+          case $host_cpu in
+            hppa*64*|ia64*)
+              ;;
+            *)
+	      export_dynamic_flag_spec_CXX='${wl}-E'
+              ;;
+          esac
+        fi
+        case $host_cpu in
+          hppa*64*|ia64*)
+            hardcode_direct_CXX=no
+            hardcode_shlibpath_var_CXX=no
+            ;;
+          *)
+            hardcode_direct_CXX=yes
+            hardcode_direct_absolute_CXX=yes
+            hardcode_minus_L_CXX=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
+	    ld_shlibs_CXX=no
+	    ;;
+          aCC*)
+	    case $host_cpu in
+	      hppa*64*)
+	        archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	        ;;
+	      ia64*)
+	        archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	        ;;
+	      *)
+	        archive_cmds_CXX='$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; func_echo_all "$list"'
+	    ;;
+          *)
+	    if test "$GXX" = yes; then
+	      if test $with_gnu_ld = no; then
+	        case $host_cpu in
+	          hppa*64*)
+	            archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	            ;;
+	          ia64*)
+	            archive_cmds_CXX='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	            ;;
+	          *)
+	            archive_cmds_CXX='$CC -shared -nostdlib $pic_flag ${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
+	      ld_shlibs_CXX=no
+	    fi
+	    ;;
+        esac
+        ;;
+
+      interix[3-9]*)
+	hardcode_direct_CXX=no
+	hardcode_shlibpath_var_CXX=no
+	hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+	export_dynamic_flag_spec_CXX='${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_CXX='$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_CXX='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++
+	    archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -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.
+	    old_archive_cmds_CXX='$CC -ar -WR,-u -o $oldlib $oldobjs'
+	    ;;
+          *)
+	    if test "$GXX" = yes; then
+	      if test "$with_gnu_ld" = no; then
+	        archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+	      else
+	        archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib'
+	      fi
+	    fi
+	    link_all_deplibs_CXX=yes
+	    ;;
+        esac
+        hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+        hardcode_libdir_separator_CXX=:
+        inherit_rpath_CXX=yes
+        ;;
+
+      linux* | k*bsd*-gnu | kopensolaris*-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.
+	    archive_cmds_CXX='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'
+	    archive_expsym_cmds_CXX='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; func_echo_all "$list"'
+
+	    hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+	    export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+
+	    # Archives containing C++ object files must be created using
+	    # "CC -Bstatic", where "CC" is the KAI C++ compiler.
+	    old_archive_cmds_CXX='$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."*)
+	        archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+		archive_expsym_cmds_CXX='$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
+	        archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+		archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+		;;
+	    esac
+	    archive_cmds_need_lc_CXX=no
+	    hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+	    export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+	    whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+	    ;;
+          pgCC* | pgcpp*)
+            # Portland Group C++ compiler
+	    case `$CC -V` in
+	    *pgCC\ [1-5].* | *pgcpp\ [1-5].*)
+	      prelink_cmds_CXX='tpldir=Template.dir~
+		rm -rf $tpldir~
+		$CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~
+		compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"'
+	      old_archive_cmds_CXX='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 | sort | $NL2SP`~
+		$RANLIB $oldlib'
+	      archive_cmds_CXX='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 | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+	      archive_expsym_cmds_CXX='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 | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
+	      ;;
+	    *) # Version 6 and above use weak symbols
+	      archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+	      archive_expsym_cmds_CXX='$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
+
+	    hardcode_libdir_flag_spec_CXX='${wl}--rpath ${wl}$libdir'
+	    export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+	    whole_archive_flag_spec_CXX='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+            ;;
+	  cxx*)
+	    # Compaq C++
+	    archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	    archive_expsym_cmds_CXX='$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
+	    hardcode_libdir_flag_spec_CXX='-rpath $libdir'
+	    hardcode_libdir_separator_CXX=:
+
+	    # 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=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed'
+	    ;;
+	  xl* | mpixl* | bgxl*)
+	    # IBM XL 8.0 on PPC, with GNU ld
+	    hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+	    export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+	    archive_cmds_CXX='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	    if test "x$supports_anon_versioning" = xyes; then
+	      archive_expsym_cmds_CXX='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
+	      no_undefined_flag_CXX=' -zdefs'
+	      archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	      archive_expsym_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols'
+	      hardcode_libdir_flag_spec_CXX='-R$libdir'
+	      whole_archive_flag_spec_CXX='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+	      compiler_needs_object_CXX=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='func_echo_all'
+
+	      # 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.
+	      old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs'
+	      ;;
+	    esac
+	    ;;
+	esac
+	;;
+
+      lynxos*)
+        # FIXME: insert proper C++ library support
+	ld_shlibs_CXX=no
+	;;
+
+      m88k*)
+        # FIXME: insert proper C++ library support
+        ld_shlibs_CXX=no
+	;;
+
+      mvs*)
+        case $cc_basename in
+          cxx*)
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+	  *)
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+	esac
+	;;
+
+      netbsd*)
+        if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+	  archive_cmds_CXX='$LD -Bshareable  -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags'
+	  wlarc=
+	  hardcode_libdir_flag_spec_CXX='-R$libdir'
+	  hardcode_direct_CXX=yes
+	  hardcode_shlibpath_var_CXX=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*)
+        ld_shlibs_CXX=yes
+	;;
+
+      openbsd2*)
+        # C++ shared libraries are fairly broken
+	ld_shlibs_CXX=no
+	;;
+
+      openbsd*)
+	if test -f /usr/libexec/ld.so; then
+	  hardcode_direct_CXX=yes
+	  hardcode_shlibpath_var_CXX=no
+	  hardcode_direct_absolute_CXX=yes
+	  archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+	  hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+	  if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+	    archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib'
+	    export_dynamic_flag_spec_CXX='${wl}-E'
+	    whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+	  fi
+	  output_verbose_link_cmd=func_echo_all
+	else
+	  ld_shlibs_CXX=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.
+	    archive_cmds_CXX='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'
+
+	    hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+	    hardcode_libdir_separator_CXX=:
+
+	    # Archives containing C++ object files must be created using
+	    # the KAI C++ compiler.
+	    case $host in
+	      osf3*) old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ;;
+	      *) old_archive_cmds_CXX='$CC -o $oldlib $oldobjs' ;;
+	    esac
+	    ;;
+          RCC*)
+	    # Rational C++ 2.4.1
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+          cxx*)
+	    case $host in
+	      osf3*)
+	        allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*'
+	        archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+	        hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+		;;
+	      *)
+	        allow_undefined_flag_CXX=' -expect_unresolved \*'
+	        archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+	        archive_expsym_cmds_CXX='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 "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~
+	          $RM $lib.exp'
+	        hardcode_libdir_flag_spec_CXX='-rpath $libdir'
+		;;
+	    esac
+
+	    hardcode_libdir_separator_CXX=:
+
+	    # 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=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+	    ;;
+	  *)
+	    if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+	      allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*'
+	      case $host in
+	        osf3*)
+	          archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+		  ;;
+	        *)
+	          archive_cmds_CXX='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+		  ;;
+	      esac
+
+	      hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+	      hardcode_libdir_separator_CXX=:
+
+	      # 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 -v "^Configured with:" | $GREP "\-L"'
+
+	    else
+	      # FIXME: insert proper C++ library support
+	      ld_shlibs_CXX=no
+	    fi
+	    ;;
+        esac
+        ;;
+
+      psos*)
+        # FIXME: insert proper C++ library support
+        ld_shlibs_CXX=no
+        ;;
+
+      sunos4*)
+        case $cc_basename in
+          CC*)
+	    # Sun C++ 4.x
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+          lcc*)
+	    # Lucid
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+          *)
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+        esac
+        ;;
+
+      solaris*)
+        case $cc_basename in
+          CC* | sunCC*)
+	    # Sun C++ 4.2, 5.x and Centerline C++
+            archive_cmds_need_lc_CXX=yes
+	    no_undefined_flag_CXX=' -zdefs'
+	    archive_cmds_CXX='$CC -G${allow_undefined_flag}  -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	    archive_expsym_cmds_CXX='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'
+
+	    hardcode_libdir_flag_spec_CXX='-R$libdir'
+	    hardcode_shlibpath_var_CXX=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?)
+		whole_archive_flag_spec_CXX='-z allextract$convenience -z defaultextract'
+	        ;;
+	    esac
+	    link_all_deplibs_CXX=yes
+
+	    output_verbose_link_cmd='func_echo_all'
+
+	    # 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.
+	    old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs'
+	    ;;
+          gcx*)
+	    # Green Hills C++ Compiler
+	    archive_cmds_CXX='$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.
+	    old_archive_cmds_CXX='$CC $LDFLAGS -archive -o $oldlib $oldobjs'
+	    ;;
+          *)
+	    # GNU C++ compiler with Solaris linker
+	    if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+	      no_undefined_flag_CXX=' ${wl}-z ${wl}defs'
+	      if $CC --version | $GREP -v '^2\.7' > /dev/null; then
+	        archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+	        archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+		  $CC -shared $pic_flag -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 -v "^Configured with:" | $GREP "\-L"'
+	      else
+	        # g++ 2.7 appears to require `-G' NOT `-shared' on this
+	        # platform.
+	        archive_cmds_CXX='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+	        archive_expsym_cmds_CXX='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 -v "^Configured with:" | $GREP "\-L"'
+	      fi
+
+	      hardcode_libdir_flag_spec_CXX='${wl}-R $wl$libdir'
+	      case $host_os in
+		solaris2.[0-5] | solaris2.[0-5].*) ;;
+		*)
+		  whole_archive_flag_spec_CXX='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+		  ;;
+	      esac
+	    fi
+	    ;;
+        esac
+        ;;
+
+    sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
+      no_undefined_flag_CXX='${wl}-z,text'
+      archive_cmds_need_lc_CXX=no
+      hardcode_shlibpath_var_CXX=no
+      runpath_var='LD_RUN_PATH'
+
+      case $cc_basename in
+        CC*)
+	  archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	*)
+	  archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  archive_expsym_cmds_CXX='$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.
+	no_undefined_flag_CXX='${wl}-z,text'
+	allow_undefined_flag_CXX='${wl}-z,nodefs'
+	archive_cmds_need_lc_CXX=no
+	hardcode_shlibpath_var_CXX=no
+	hardcode_libdir_flag_spec_CXX='${wl}-R,$libdir'
+	hardcode_libdir_separator_CXX=':'
+	link_all_deplibs_CXX=yes
+	export_dynamic_flag_spec_CXX='${wl}-Bexport'
+	runpath_var='LD_RUN_PATH'
+
+	case $cc_basename in
+          CC*)
+	    archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    old_archive_cmds_CXX='$CC -Tprelink_objects $oldobjs~
+	      '"$old_archive_cmds_CXX"
+	    reload_cmds_CXX='$CC -Tprelink_objects $reload_objs~
+	      '"$reload_cmds_CXX"
+	    ;;
+	  *)
+	    archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    archive_expsym_cmds_CXX='$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
+	    ld_shlibs_CXX=no
+	    ;;
+          *)
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+        esac
+        ;;
+
+      vxworks*)
+        # FIXME: insert proper C++ library support
+        ld_shlibs_CXX=no
+        ;;
+
+      *)
+        # FIXME: insert proper C++ library support
+        ld_shlibs_CXX=no
+        ;;
+    esac
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5
+$as_echo "$ld_shlibs_CXX" >&6; }
+    test "$ld_shlibs_CXX" = no && can_build_shared=no
+
+    GCC_CXX="$GXX"
+    LD_CXX="$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...
+    # Dependencies to place before and after the object being linked:
+predep_objects_CXX=
+postdep_objects_CXX=
+predeps_CXX=
+postdeps_CXX=
+compiler_lib_search_path_CXX=
+
+cat > conftest.$ac_ext <<_LT_EOF
+class Foo
+{
+public:
+  Foo (void) { a = 0; }
+private:
+  int a;
+};
+_LT_EOF
+
+
+_lt_libdeps_save_CFLAGS=$CFLAGS
+case "$CC $CFLAGS " in #(
+*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;;
+*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;;
+*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;;
+esac
+
+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
+  # 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 ${prev}${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
+       fi
+
+       # Expand the sysroot to ease extracting the directories later.
+       if test -z "$prev"; then
+         case $p in
+         -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;;
+         -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;;
+         -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;;
+         esac
+       fi
+       case $p in
+       =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;;
+       esac
+       if test "$pre_test_object_deps_done" = no; then
+	 case ${prev} 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 "$compiler_lib_search_path_CXX"; then
+	     compiler_lib_search_path_CXX="${prev}${p}"
+	   else
+	     compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} ${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 "$postdeps_CXX"; then
+	   postdeps_CXX="${prev}${p}"
+	 else
+	   postdeps_CXX="${postdeps_CXX} ${prev}${p}"
+	 fi
+       fi
+       prev=
+       ;;
+
+    *.lto.$objext) ;; # Ignore GCC LTO objects
+    *.$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 "$predep_objects_CXX"; then
+	   predep_objects_CXX="$p"
+	 else
+	   predep_objects_CXX="$predep_objects_CXX $p"
+	 fi
+       else
+	 if test -z "$postdep_objects_CXX"; then
+	   postdep_objects_CXX="$p"
+	 else
+	   postdep_objects_CXX="$postdep_objects_CXX $p"
+	 fi
+       fi
+       ;;
+
+    *) ;; # Ignore the rest.
+
+    esac
+  done
+
+  # Clean up.
+  rm -f a.out a.exe
+else
+  echo "libtool.m4: error: problem compiling CXX test program"
+fi
+
+$RM -f confest.$objext
+CFLAGS=$_lt_libdeps_save_CFLAGS
+
+# PORTME: override above test on systems where it is broken
+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.
+  predep_objects_CXX=
+  postdep_objects_CXX=
+  postdeps_CXX=
+  ;;
+
+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
+      postdeps_CXX='-library=Cstd -library=Crun'
+    fi
+    ;;
+  esac
+  ;;
+
+solaris*)
+  case $cc_basename in
+  CC* | sunCC*)
+    # 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
+      postdeps_CXX='-library=Cstd -library=Crun'
+    fi
+    ;;
+  esac
+  ;;
+esac
+
+
+case " $postdeps_CXX " in
+*" -lc "*) archive_cmds_need_lc_CXX=no ;;
+esac
+ compiler_lib_search_dirs_CXX=
+if test -n "${compiler_lib_search_path_CXX}"; then
+ compiler_lib_search_dirs_CXX=`echo " ${compiler_lib_search_path_CXX}" | ${SED} -e 's! -L! !g' -e 's!^ !!'`
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    lt_prog_compiler_wl_CXX=
+lt_prog_compiler_pic_CXX=
+lt_prog_compiler_static_CXX=
+
+
+  # C++ specific cases for pic, static, wl, etc.
+  if test "$GXX" = yes; then
+    lt_prog_compiler_wl_CXX='-Wl,'
+    lt_prog_compiler_static_CXX='-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_CXX='-Bstatic'
+      fi
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            lt_prog_compiler_pic_CXX='-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_CXX='-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
+      lt_prog_compiler_pic_CXX='-DDLL_EXPORT'
+      ;;
+    darwin* | rhapsody*)
+      # PIC is the default on this platform
+      # Common symbols not allowed in MH_DYLIB files
+      lt_prog_compiler_pic_CXX='-fno-common'
+      ;;
+    *djgpp*)
+      # DJGPP does not support shared libraries at all
+      lt_prog_compiler_pic_CXX=
+      ;;
+    haiku*)
+      # PIC is the default for Haiku.
+      # The "-static" flag exists, but is broken.
+      lt_prog_compiler_static_CXX=
+      ;;
+    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_prog_compiler_pic_CXX=-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_prog_compiler_pic_CXX='-fPIC'
+	;;
+      esac
+      ;;
+    *qnx* | *nto*)
+      # QNX uses GNU C++, but need to define -shared option too, otherwise
+      # it will coredump.
+      lt_prog_compiler_pic_CXX='-fPIC -shared'
+      ;;
+    *)
+      lt_prog_compiler_pic_CXX='-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_prog_compiler_static_CXX='-Bstatic'
+	else
+	  lt_prog_compiler_static_CXX='-bnso -bI:/lib/syscalls.exp'
+	fi
+	;;
+      chorus*)
+	case $cc_basename in
+	cxch68*)
+	  # Green Hills C++ Compiler
+	  # _LT_TAGVAR(lt_prog_compiler_static, CXX)="--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
+	;;
+      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).
+	lt_prog_compiler_pic_CXX='-DDLL_EXPORT'
+	;;
+      dgux*)
+	case $cc_basename in
+	  ec++*)
+	    lt_prog_compiler_pic_CXX='-KPIC'
+	    ;;
+	  ghcx*)
+	    # Green Hills C++ Compiler
+	    lt_prog_compiler_pic_CXX='-pic'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      freebsd* | dragonfly*)
+	# FreeBSD uses GNU C++
+	;;
+      hpux9* | hpux10* | hpux11*)
+	case $cc_basename in
+	  CC*)
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_static_CXX='${wl}-a ${wl}archive'
+	    if test "$host_cpu" != ia64; then
+	      lt_prog_compiler_pic_CXX='+Z'
+	    fi
+	    ;;
+	  aCC*)
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_static_CXX='${wl}-a ${wl}archive'
+	    case $host_cpu in
+	    hppa*64*|ia64*)
+	      # +Z the default
+	      ;;
+	    *)
+	      lt_prog_compiler_pic_CXX='+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_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_static_CXX='-non_shared'
+	    # CC pic flag -KPIC is the default.
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      linux* | k*bsd*-gnu | kopensolaris*-gnu)
+	case $cc_basename in
+	  KCC*)
+	    # KAI C++ Compiler
+	    lt_prog_compiler_wl_CXX='--backend -Wl,'
+	    lt_prog_compiler_pic_CXX='-fPIC'
+	    ;;
+	  ecpc* )
+	    # old Intel C++ for x86_64 which still supported -KPIC.
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_pic_CXX='-KPIC'
+	    lt_prog_compiler_static_CXX='-static'
+	    ;;
+	  icpc* )
+	    # Intel C++, used to be incompatible with GCC.
+	    # ICC 10 doesn't accept -KPIC any more.
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_pic_CXX='-fPIC'
+	    lt_prog_compiler_static_CXX='-static'
+	    ;;
+	  pgCC* | pgcpp*)
+	    # Portland Group C++ compiler
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_pic_CXX='-fpic'
+	    lt_prog_compiler_static_CXX='-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_prog_compiler_pic_CXX=
+	    lt_prog_compiler_static_CXX='-non_shared'
+	    ;;
+	  xlc* | xlC* | bgxl[cC]* | mpixl[cC]*)
+	    # IBM XL 8.0, 9.0 on PPC and BlueGene
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_pic_CXX='-qpic'
+	    lt_prog_compiler_static_CXX='-qstaticlink'
+	    ;;
+	  *)
+	    case `$CC -V 2>&1 | sed 5q` in
+	    *Sun\ C*)
+	      # Sun C++ 5.9
+	      lt_prog_compiler_pic_CXX='-KPIC'
+	      lt_prog_compiler_static_CXX='-Bstatic'
+	      lt_prog_compiler_wl_CXX='-Qoption ld '
+	      ;;
+	    esac
+	    ;;
+	esac
+	;;
+      lynxos*)
+	;;
+      m88k*)
+	;;
+      mvs*)
+	case $cc_basename in
+	  cxx*)
+	    lt_prog_compiler_pic_CXX='-W c,exportall'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      netbsd*)
+	;;
+      *qnx* | *nto*)
+        # QNX uses GNU C++, but need to define -shared option too, otherwise
+        # it will coredump.
+        lt_prog_compiler_pic_CXX='-fPIC -shared'
+        ;;
+      osf3* | osf4* | osf5*)
+	case $cc_basename in
+	  KCC*)
+	    lt_prog_compiler_wl_CXX='--backend -Wl,'
+	    ;;
+	  RCC*)
+	    # Rational C++ 2.4.1
+	    lt_prog_compiler_pic_CXX='-pic'
+	    ;;
+	  cxx*)
+	    # Digital/Compaq C++
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    # Make sure the PIC flag is empty.  It appears that all Alpha
+	    # Linux and Compaq Tru64 Unix objects are PIC.
+	    lt_prog_compiler_pic_CXX=
+	    lt_prog_compiler_static_CXX='-non_shared'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      psos*)
+	;;
+      solaris*)
+	case $cc_basename in
+	  CC* | sunCC*)
+	    # Sun C++ 4.2, 5.x and Centerline C++
+	    lt_prog_compiler_pic_CXX='-KPIC'
+	    lt_prog_compiler_static_CXX='-Bstatic'
+	    lt_prog_compiler_wl_CXX='-Qoption ld '
+	    ;;
+	  gcx*)
+	    # Green Hills C++ Compiler
+	    lt_prog_compiler_pic_CXX='-PIC'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      sunos4*)
+	case $cc_basename in
+	  CC*)
+	    # Sun C++ 4.x
+	    lt_prog_compiler_pic_CXX='-pic'
+	    lt_prog_compiler_static_CXX='-Bstatic'
+	    ;;
+	  lcc*)
+	    # Lucid
+	    lt_prog_compiler_pic_CXX='-pic'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+	case $cc_basename in
+	  CC*)
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_pic_CXX='-KPIC'
+	    lt_prog_compiler_static_CXX='-Bstatic'
+	    ;;
+	esac
+	;;
+      tandem*)
+	case $cc_basename in
+	  NCC*)
+	    # NonStop-UX NCC 3.20
+	    lt_prog_compiler_pic_CXX='-KPIC'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      vxworks*)
+	;;
+      *)
+	lt_prog_compiler_can_build_shared_CXX=no
+	;;
+    esac
+  fi
+
+case $host_os in
+  # For platforms which do not support PIC, -DPIC is meaningless:
+  *djgpp*)
+    lt_prog_compiler_pic_CXX=
+    ;;
+  *)
+    lt_prog_compiler_pic_CXX="$lt_prog_compiler_pic_CXX -DPIC"
+    ;;
+esac
+
+{ $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 ${lt_cv_prog_compiler_pic_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_pic_CXX=$lt_prog_compiler_pic_CXX
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_CXX" >&5
+$as_echo "$lt_cv_prog_compiler_pic_CXX" >&6; }
+lt_prog_compiler_pic_CXX=$lt_cv_prog_compiler_pic_CXX
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$lt_prog_compiler_pic_CXX"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5
+$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... " >&6; }
+if ${lt_cv_prog_compiler_pic_works_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_pic_works_CXX=no
+   ac_outfile=conftest.$ac_objext
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+   lt_compiler_flag="$lt_prog_compiler_pic_CXX -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:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $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 "$_lt_compiler_boilerplate" | $SED '/^$/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_CXX=yes
+     fi
+   fi
+   $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works_CXX" >&5
+$as_echo "$lt_cv_prog_compiler_pic_works_CXX" >&6; }
+
+if test x"$lt_cv_prog_compiler_pic_works_CXX" = xyes; then
+    case $lt_prog_compiler_pic_CXX in
+     "" | " "*) ;;
+     *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;;
+     esac
+else
+    lt_prog_compiler_pic_CXX=
+     lt_prog_compiler_can_build_shared_CXX=no
+fi
+
+fi
+
+
+
+
+
+#
+# Check to make sure the static flag actually works.
+#
+wl=$lt_prog_compiler_wl_CXX eval lt_tmp_static_flag=\"$lt_prog_compiler_static_CXX\"
+{ $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 ${lt_cv_prog_compiler_static_works_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_static_works_CXX=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 "$_lt_linker_boilerplate" | $SED '/^$/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_CXX=yes
+       fi
+     else
+       lt_cv_prog_compiler_static_works_CXX=yes
+     fi
+   fi
+   $RM -r conftest*
+   LDFLAGS="$save_LDFLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works_CXX" >&5
+$as_echo "$lt_cv_prog_compiler_static_works_CXX" >&6; }
+
+if test x"$lt_cv_prog_compiler_static_works_CXX" = xyes; then
+    :
+else
+    lt_prog_compiler_static_CXX=
+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 ${lt_cv_prog_compiler_c_o_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_c_o_CXX=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:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $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 "$_lt_compiler_boilerplate" | $SED '/^$/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_CXX=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_CXX" >&5
+$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&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 ${lt_cv_prog_compiler_c_o_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_c_o_CXX=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:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $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 "$_lt_compiler_boilerplate" | $SED '/^$/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_CXX=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_CXX" >&5
+$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; }
+
+
+
+
+hard_links="nottested"
+if test "$lt_cv_prog_compiler_c_o_CXX" = 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; }
+
+  export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  exclude_expsyms_CXX='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'
+  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
+    # Also, AIX nm treats weak defined symbols like other global defined
+    # symbols, whereas GNU nm marks them as "W".
+    if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+      export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+    else
+      export_symbols_cmds_CXX='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+    fi
+    ;;
+  pw32*)
+    export_symbols_cmds_CXX="$ltdll_cmds"
+    ;;
+  cygwin* | mingw* | cegcc*)
+    case $cc_basename in
+    cl*)
+      exclude_expsyms_CXX='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
+      ;;
+    *)
+      export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols'
+      exclude_expsyms_CXX='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'
+      ;;
+    esac
+    ;;
+  *)
+    export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+    ;;
+  esac
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5
+$as_echo "$ld_shlibs_CXX" >&6; }
+test "$ld_shlibs_CXX" = no && can_build_shared=no
+
+with_gnu_ld_CXX=$with_gnu_ld
+
+
+
+
+
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$archive_cmds_need_lc_CXX" in
+x|xyes)
+  # Assume -lc should be added
+  archive_cmds_need_lc_CXX=yes
+
+  if test "$enable_shared" = yes && test "$GCC" = yes; then
+    case $archive_cmds_CXX 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; }
+if ${lt_cv_archive_cmds_need_lc_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  $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_CXX
+	  pic_flag=$lt_prog_compiler_pic_CXX
+	  compiler_flags=-v
+	  linker_flags=-v
+	  verstring=
+	  output_objdir=.
+	  libname=conftest
+	  lt_save_allow_undefined_flag=$allow_undefined_flag_CXX
+	  allow_undefined_flag_CXX=
+	  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5
+  (eval $archive_cmds_CXX 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
+	    lt_cv_archive_cmds_need_lc_CXX=no
+	  else
+	    lt_cv_archive_cmds_need_lc_CXX=yes
+	  fi
+	  allow_undefined_flag_CXX=$lt_save_allow_undefined_flag
+	else
+	  cat conftest.err 1>&5
+	fi
+	$RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc_CXX" >&5
+$as_echo "$lt_cv_archive_cmds_need_lc_CXX" >&6; }
+      archive_cmds_need_lc_CXX=$lt_cv_archive_cmds_need_lc_CXX
+      ;;
+    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 # correct to gnu/linux during the next big refactor
+  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 # correct to gnu/linux during the next big refactor
+  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=`func_echo_all "$lib" | $SED '\''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 # correct to gnu/linux during the next big refactor
+  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,$cc_basename in
+  yes,*)
+    # gcc
+    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}'
+
+      ;;
+    mingw* | cegcc*)
+      # MinGW DLLs use traditional 'lib' prefix
+      soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      ;;
+    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
+    dynamic_linker='Win32 ld.exe'
+    ;;
+
+  *,cl*)
+    # Native MSVC
+    libname_spec='$name'
+    soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+    library_names_spec='${libname}.dll.lib'
+
+    case $build_os in
+    mingw*)
+      sys_lib_search_path_spec=
+      lt_save_ifs=$IFS
+      IFS=';'
+      for lt_path in $LIB
+      do
+        IFS=$lt_save_ifs
+        # Let DOS variable expansion print the short 8.3 style file name.
+        lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"`
+        sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path"
+      done
+      IFS=$lt_save_ifs
+      # Convert to MSYS style.
+      sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'`
+      ;;
+    cygwin*)
+      # Convert to unix form, then to dos form, then back to unix form
+      # but this time dos style (no spaces!) so that the unix form looks
+      # like /cygdrive/c/PROGRA~1:/cygdr...
+      sys_lib_search_path_spec=`cygpath --path --unix "$LIB"`
+      sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null`
+      sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+      ;;
+    *)
+      sys_lib_search_path_spec="$LIB"
+      if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then
+        # It is most probably a Windows format PATH.
+        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
+      # FIXME: find the short name or the path components, as spaces are
+      # common. (e.g. "Program Files" -> "PROGRA~1")
+      ;;
+    esac
+
+    # 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'
+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+      dlpath=$dir/\$dldll~
+       $RM \$dlpath'
+    shlibpath_overrides_runpath=yes
+    dynamic_linker='Win32 link.exe'
+    ;;
+
+  *)
+    # Assume MSVC wrapper
+    library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
+    dynamic_linker='Win32 ld.exe'
+    ;;
+  esac
+  # 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 # correct to gnu/linux during the next big refactor
+  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
+  ;;
+
+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[23].*) objformat=aout ;;
+    *) objformat=elf ;;
+    esac
+  fi
+  # Handle Gentoo/FreeBSD as it was Linux
+  case $host_vendor in
+    gentoo)
+      version_type=linux ;;
+    *)
+      version_type=freebsd-$objformat ;;
+  esac
+
+  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
+      ;;
+    linux)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+      soname_spec='${libname}${release}${shared_ext}$major'
+      need_lib_prefix=no
+      need_version=no
+      ;;
+  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 # correct to gnu/linux during the next big refactor
+  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
+  ;;
+
+haiku*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  dynamic_linker="$host_os runtime_loader"
+  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=LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
+  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'
+  # or fails outright, so override atomically:
+  install_override_mode=555
+  ;;
+
+interix[3-9]*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  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 # correct to gnu/linux during the next big refactor
+	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 glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  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
+  if ${lt_cv_shlibpath_overrides_runpath+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_shlibpath_overrides_runpath=no
+    save_LDFLAGS=$LDFLAGS
+    save_libdir=$libdir
+    eval "libdir=/foo; wl=\"$lt_prog_compiler_wl_CXX\"; \
+	 LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec_CXX\""
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+  if  ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then :
+  lt_cv_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
+
+fi
+
+  shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath
+
+  # 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;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'
+  ;;
+
+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 # correct to gnu/linux during the next big refactor
+  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 # correct to gnu/linux during the next big refactor
+  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 # correct to gnu/linux during the next big refactor
+  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 # correct to gnu/linux during the next big refactor
+    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 # correct to gnu/linux during the next big refactor
+  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 # correct to gnu/linux during the next big refactor
+  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_CXX=
+if test -n "$hardcode_libdir_flag_spec_CXX" ||
+   test -n "$runpath_var_CXX" ||
+   test "X$hardcode_automatic_CXX" = "Xyes" ; then
+
+  # We can hardcode non-existent directories.
+  if test "$hardcode_direct_CXX" != 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, CXX)" != no &&
+     test "$hardcode_minus_L_CXX" != no; then
+    # Linking always hardcodes the temporary library directory.
+    hardcode_action_CXX=relink
+  else
+    # We can link without hardcoding, and we can hardcode nonexisting dirs.
+    hardcode_action_CXX=immediate
+  fi
+else
+  # We cannot hardcode anything, or else we can only hardcode existing
+  # directories.
+  hardcode_action_CXX=unsupported
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action_CXX" >&5
+$as_echo "$hardcode_action_CXX" >&6; }
+
+if test "$hardcode_action_CXX" = relink ||
+   test "$inherit_rpath_CXX" = 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"
+
+  CC=$lt_save_CC
+  CFLAGS=$lt_save_CFLAGS
+  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_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_config_commands="$ac_config_commands libtool"
+
+
+
+
+# Only expand once:
+
+
+# ([shared])
+# LT_INIT(dlopen disable-static) # doesn't work on PowerPC!
+
+# SING_CHECK_PIPE
+
+##### SEE http://www.gnu.org/prep/standards/html_node/Directory-Variables.html
+
+_lcl_receval="$prefix"
+config_prefix=`(test "x$prefix" = xNONE && prefix="$ac_default_prefix"
+     test "x$exec_prefix" = xNONE && exec_prefix="${prefix}"
+     _lcl_receval_old=''
+     while test "$_lcl_receval_old" != "$_lcl_receval"; do
+       _lcl_receval_old="$_lcl_receval"
+       eval _lcl_receval="\"$_lcl_receval\""
+     done
+     echo "$_lcl_receval")`
+case ":$config_prefix:" in
+# change empty paths to '.'
+  ::) config_prefix='.' ;;
+# strip trailing slashes
+  :*[\\/]:) config_prefix=`echo "$config_prefix" | sed 's,[\\/]*$,,'` ;;
+  :*:) ;;
+esac
+# squeze repeated slashes
+case '/' in
+# if the path contains any backslashes, turn slashes into backslashes
+ *\\*) config_prefix=`echo "$config_prefix" | sed 's,\(.\)[\\/][\\/]*,\1\\\\,g'` ;;
+# if the path contains slashes, also turn backslashes into slashes
+ *) config_prefix=`echo "$config_prefix" | sed 's,\(.\)[\\/][\\/]*,\1/,g'` ;;
+esac
+
+cat >>confdefs.h <<_ACEOF
+#define PREFIX "$config_prefix"
+_ACEOF
+
+
+_lcl_receval="$exec_prefix"
+config_exec_prefix=`(test "x$prefix" = xNONE && prefix="$ac_default_prefix"
+     test "x$exec_prefix" = xNONE && exec_prefix="${prefix}"
+     _lcl_receval_old=''
+     while test "$_lcl_receval_old" != "$_lcl_receval"; do
+       _lcl_receval_old="$_lcl_receval"
+       eval _lcl_receval="\"$_lcl_receval\""
+     done
+     echo "$_lcl_receval")`
+case ":$config_exec_prefix:" in
+# change empty paths to '.'
+  ::) config_exec_prefix='.' ;;
+# strip trailing slashes
+  :*[\\/]:) config_exec_prefix=`echo "$config_exec_prefix" | sed 's,[\\/]*$,,'` ;;
+  :*:) ;;
+esac
+# squeze repeated slashes
+case '/' in
+# if the path contains any backslashes, turn slashes into backslashes
+ *\\*) config_exec_prefix=`echo "$config_exec_prefix" | sed 's,\(.\)[\\/][\\/]*,\1\\\\,g'` ;;
+# if the path contains slashes, also turn backslashes into slashes
+ *) config_exec_prefix=`echo "$config_exec_prefix" | sed 's,\(.\)[\\/][\\/]*,\1/,g'` ;;
+esac
+
+cat >>confdefs.h <<_ACEOF
+#define EXEC_PREFIX "$config_exec_prefix"
+_ACEOF
+
+
+_lcl_receval="$libexecdir"
+config_libexecdir=`(test "x$prefix" = xNONE && prefix="$ac_default_prefix"
+     test "x$exec_prefix" = xNONE && exec_prefix="${prefix}"
+     _lcl_receval_old=''
+     while test "$_lcl_receval_old" != "$_lcl_receval"; do
+       _lcl_receval_old="$_lcl_receval"
+       eval _lcl_receval="\"$_lcl_receval\""
+     done
+     echo "$_lcl_receval")`
+case ":$config_libexecdir:" in
+# change empty paths to '.'
+  ::) config_libexecdir='.' ;;
+# strip trailing slashes
+  :*[\\/]:) config_libexecdir=`echo "$config_libexecdir" | sed 's,[\\/]*$,,'` ;;
+  :*:) ;;
+esac
+# squeze repeated slashes
+case '/' in
+# if the path contains any backslashes, turn slashes into backslashes
+ *\\*) config_libexecdir=`echo "$config_libexecdir" | sed 's,\(.\)[\\/][\\/]*,\1\\\\,g'` ;;
+# if the path contains slashes, also turn backslashes into slashes
+ *) config_libexecdir=`echo "$config_libexecdir" | sed 's,\(.\)[\\/][\\/]*,\1/,g'` ;;
+esac
+
+cat >>confdefs.h <<_ACEOF
+#define LIBEXEC_DIR "$config_libexecdir"
+_ACEOF
+
+
+_lcl_receval="$libdir"
+config_libdir=`(test "x$prefix" = xNONE && prefix="$ac_default_prefix"
+     test "x$exec_prefix" = xNONE && exec_prefix="${prefix}"
+     _lcl_receval_old=''
+     while test "$_lcl_receval_old" != "$_lcl_receval"; do
+       _lcl_receval_old="$_lcl_receval"
+       eval _lcl_receval="\"$_lcl_receval\""
+     done
+     echo "$_lcl_receval")`
+case ":$config_libdir:" in
+# change empty paths to '.'
+  ::) config_libdir='.' ;;
+# strip trailing slashes
+  :*[\\/]:) config_libdir=`echo "$config_libdir" | sed 's,[\\/]*$,,'` ;;
+  :*:) ;;
+esac
+# squeze repeated slashes
+case '/' in
+# if the path contains any backslashes, turn slashes into backslashes
+ *\\*) config_libdir=`echo "$config_libdir" | sed 's,\(.\)[\\/][\\/]*,\1\\\\,g'` ;;
+# if the path contains slashes, also turn backslashes into slashes
+ *) config_libdir=`echo "$config_libdir" | sed 's,\(.\)[\\/][\\/]*,\1/,g'` ;;
+esac
+
+cat >>confdefs.h <<_ACEOF
+#define LIB_DIR "$config_libdir"
+_ACEOF
+
+
+_lcl_receval="$bindir"
+config_bindir=`(test "x$prefix" = xNONE && prefix="$ac_default_prefix"
+     test "x$exec_prefix" = xNONE && exec_prefix="${prefix}"
+     _lcl_receval_old=''
+     while test "$_lcl_receval_old" != "$_lcl_receval"; do
+       _lcl_receval_old="$_lcl_receval"
+       eval _lcl_receval="\"$_lcl_receval\""
+     done
+     echo "$_lcl_receval")`
+case ":$config_bindir:" in
+# change empty paths to '.'
+  ::) config_bindir='.' ;;
+# strip trailing slashes
+  :*[\\/]:) config_bindir=`echo "$config_bindir" | sed 's,[\\/]*$,,'` ;;
+  :*:) ;;
+esac
+# squeze repeated slashes
+case '/' in
+# if the path contains any backslashes, turn slashes into backslashes
+ *\\*) config_bindir=`echo "$config_bindir" | sed 's,\(.\)[\\/][\\/]*,\1\\\\,g'` ;;
+# if the path contains slashes, also turn backslashes into slashes
+ *) config_bindir=`echo "$config_bindir" | sed 's,\(.\)[\\/][\\/]*,\1/,g'` ;;
+esac
+
+cat >>confdefs.h <<_ACEOF
+#define BIN_DIR "$config_bindir"
+_ACEOF
+
+
+_lcl_receval="$datadir"
+config_datadir=`(test "x$prefix" = xNONE && prefix="$ac_default_prefix"
+     test "x$exec_prefix" = xNONE && exec_prefix="${prefix}"
+     _lcl_receval_old=''
+     while test "$_lcl_receval_old" != "$_lcl_receval"; do
+       _lcl_receval_old="$_lcl_receval"
+       eval _lcl_receval="\"$_lcl_receval\""
+     done
+     echo "$_lcl_receval")`
+case ":$config_datadir:" in
+# change empty paths to '.'
+  ::) config_datadir='.' ;;
+# strip trailing slashes
+  :*[\\/]:) config_datadir=`echo "$config_datadir" | sed 's,[\\/]*$,,'` ;;
+  :*:) ;;
+esac
+# squeze repeated slashes
+case '/' in
+# if the path contains any backslashes, turn slashes into backslashes
+ *\\*) config_datadir=`echo "$config_datadir" | sed 's,\(.\)[\\/][\\/]*,\1\\\\,g'` ;;
+# if the path contains slashes, also turn backslashes into slashes
+ *) config_datadir=`echo "$config_datadir" | sed 's,\(.\)[\\/][\\/]*,\1/,g'` ;;
+esac
+
+cat >>confdefs.h <<_ACEOF
+#define DATA_DIR "$config_datadir"
+_ACEOF
+
+
+ac_config_files="$ac_config_files resources.pc 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
+    if test "x$cache_file" != "x/dev/null"; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
+$as_echo "$as_me: updating cache $cache_file" >&6;}
+      if test ! -f "$cache_file" || test -h "$cache_file"; then
+	cat confcache >"$cache_file"
+      else
+        case $cache_file in #(
+        */* | ?:*)
+	  mv -f confcache "$cache_file"$$ &&
+	  mv -f "$cache_file"$$ "$cache_file" ;; #(
+        *)
+	  mv -f confcache "$cache_file" ;;
+	esac
+      fi
+    fi
+  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=
+U=
+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 -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
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5
+$as_echo_n "checking that generated files are newer than configure... " >&6; }
+   if test -n "$am_sleep_pid"; then
+     # Hide warnings about reused PIDs.
+     wait $am_sleep_pid 2>/dev/null
+   fi
+   { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5
+$as_echo "done" >&6; }
+ if test -n "$EXEEXT"; then
+  am__EXEEXT_TRUE=
+  am__EXEEXT_FALSE='#'
+else
+  am__EXEEXT_TRUE='#'
+  am__EXEEXT_FALSE=
+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
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5
+$as_echo_n "checking that generated files are newer than configure... " >&6; }
+   if test -n "$am_sleep_pid"; then
+     # Hide warnings about reused PIDs.
+     wait $am_sleep_pid 2>/dev/null
+   fi
+   { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5
+$as_echo "done" >&6; }
+if test -z "${WANT_DEBUG_TRUE}" && test -z "${WANT_DEBUG_FALSE}"; then
+  as_fn_error $? "conditional \"WANT_DEBUG\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${WANT_OPTIMIZATIONFLAGS_TRUE}" && test -z "${WANT_OPTIMIZATIONFLAGS_FALSE}"; then
+  as_fn_error $? "conditional \"WANT_OPTIMIZATIONFLAGS\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then
+  as_fn_error $? "conditional \"am__fastdepCXX\" 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 "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then
+  as_fn_error $? "conditional \"am__fastdepCXX\" 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.
+as_myself=
+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 STATUS 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=$1; test $as_status -eq 0 && as_status=1
+  if test "$4"; then
+    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+  fi
+  $as_echo "$as_me: error: $2" >&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 -pR'.
+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+      as_ln_s='cp -pR'
+  elif ln conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s=ln
+  else
+    as_ln_s='cp -pR'
+  fi
+else
+  as_ln_s='cp -pR'
+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
+
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+  test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
+
+# 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 resources $as_me 4.0.1, which was
+generated by GNU Autoconf 2.69.  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
+      --config     print configuration, 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_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
+ac_cs_version="\\
+resources config.status 4.0.1
+configured by $0, generated by GNU Autoconf 2.69,
+  with options \\"\$ac_cs_config\\"
+
+Copyright (C) 2012 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=`expr "X$1" : 'X\([^=]*\)='`
+    ac_optarg=
+    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 ;;
+  --config | --confi | --conf | --con | --co | --c )
+    $as_echo "$ac_cs_config"; 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"` ;;
+    '') as_fn_error $? "missing file argument" ;;
+    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"
+PACKAGE="$PACKAGE"
+
+
+# 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'
+macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`'
+macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`'
+enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`'
+enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`'
+pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`'
+enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`'
+SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`'
+ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`'
+PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`'
+host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`'
+host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`'
+host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`'
+build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`'
+build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`'
+build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`'
+SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`'
+Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`'
+GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`'
+EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`'
+FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`'
+LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`'
+NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`'
+LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`'
+max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`'
+ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`'
+exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`'
+lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`'
+lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`'
+lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`'
+lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`'
+lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`'
+reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`'
+reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`'
+OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`'
+deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`'
+file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`'
+file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`'
+want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`'
+DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`'
+sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`'
+AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`'
+AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`'
+archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`'
+STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`'
+RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`'
+old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`'
+old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`'
+old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`'
+lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`'
+CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`'
+CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`'
+compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`'
+GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`'
+nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`'
+lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`'
+objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`'
+MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`'
+lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`'
+need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`'
+MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`'
+DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`'
+NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`'
+LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`'
+OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`'
+OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`'
+libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`'
+shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`'
+extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`'
+archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`'
+enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`'
+export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`'
+whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`'
+compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`'
+old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`'
+old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`'
+archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`'
+archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`'
+module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`'
+module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`'
+with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`'
+allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`'
+no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`'
+hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`'
+hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`'
+hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`'
+hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`'
+hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`'
+inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`'
+link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`'
+always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`'
+export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`'
+exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`'
+include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`'
+prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`'
+postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`'
+file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`'
+variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`'
+need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`'
+need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`'
+version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`'
+runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`'
+shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`'
+shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`'
+libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`'
+library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`'
+soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`'
+install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`'
+postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`'
+postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`'
+finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`'
+finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`'
+hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`'
+sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`'
+sys_lib_dlsearch_path_spec='`$ECHO "$sys_lib_dlsearch_path_spec" | $SED "$delay_single_quote_subst"`'
+hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`'
+enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`'
+enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`'
+enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`'
+old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`'
+striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`'
+compiler_lib_search_dirs='`$ECHO "$compiler_lib_search_dirs" | $SED "$delay_single_quote_subst"`'
+predep_objects='`$ECHO "$predep_objects" | $SED "$delay_single_quote_subst"`'
+postdep_objects='`$ECHO "$postdep_objects" | $SED "$delay_single_quote_subst"`'
+predeps='`$ECHO "$predeps" | $SED "$delay_single_quote_subst"`'
+postdeps='`$ECHO "$postdeps" | $SED "$delay_single_quote_subst"`'
+compiler_lib_search_path='`$ECHO "$compiler_lib_search_path" | $SED "$delay_single_quote_subst"`'
+LD_CXX='`$ECHO "$LD_CXX" | $SED "$delay_single_quote_subst"`'
+reload_flag_CXX='`$ECHO "$reload_flag_CXX" | $SED "$delay_single_quote_subst"`'
+reload_cmds_CXX='`$ECHO "$reload_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+old_archive_cmds_CXX='`$ECHO "$old_archive_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+compiler_CXX='`$ECHO "$compiler_CXX" | $SED "$delay_single_quote_subst"`'
+GCC_CXX='`$ECHO "$GCC_CXX" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_no_builtin_flag_CXX='`$ECHO "$lt_prog_compiler_no_builtin_flag_CXX" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_pic_CXX='`$ECHO "$lt_prog_compiler_pic_CXX" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_wl_CXX='`$ECHO "$lt_prog_compiler_wl_CXX" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_static_CXX='`$ECHO "$lt_prog_compiler_static_CXX" | $SED "$delay_single_quote_subst"`'
+lt_cv_prog_compiler_c_o_CXX='`$ECHO "$lt_cv_prog_compiler_c_o_CXX" | $SED "$delay_single_quote_subst"`'
+archive_cmds_need_lc_CXX='`$ECHO "$archive_cmds_need_lc_CXX" | $SED "$delay_single_quote_subst"`'
+enable_shared_with_static_runtimes_CXX='`$ECHO "$enable_shared_with_static_runtimes_CXX" | $SED "$delay_single_quote_subst"`'
+export_dynamic_flag_spec_CXX='`$ECHO "$export_dynamic_flag_spec_CXX" | $SED "$delay_single_quote_subst"`'
+whole_archive_flag_spec_CXX='`$ECHO "$whole_archive_flag_spec_CXX" | $SED "$delay_single_quote_subst"`'
+compiler_needs_object_CXX='`$ECHO "$compiler_needs_object_CXX" | $SED "$delay_single_quote_subst"`'
+old_archive_from_new_cmds_CXX='`$ECHO "$old_archive_from_new_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+old_archive_from_expsyms_cmds_CXX='`$ECHO "$old_archive_from_expsyms_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+archive_cmds_CXX='`$ECHO "$archive_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+archive_expsym_cmds_CXX='`$ECHO "$archive_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+module_cmds_CXX='`$ECHO "$module_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+module_expsym_cmds_CXX='`$ECHO "$module_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+with_gnu_ld_CXX='`$ECHO "$with_gnu_ld_CXX" | $SED "$delay_single_quote_subst"`'
+allow_undefined_flag_CXX='`$ECHO "$allow_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`'
+no_undefined_flag_CXX='`$ECHO "$no_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_flag_spec_CXX='`$ECHO "$hardcode_libdir_flag_spec_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_separator_CXX='`$ECHO "$hardcode_libdir_separator_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_direct_CXX='`$ECHO "$hardcode_direct_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_direct_absolute_CXX='`$ECHO "$hardcode_direct_absolute_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_minus_L_CXX='`$ECHO "$hardcode_minus_L_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_shlibpath_var_CXX='`$ECHO "$hardcode_shlibpath_var_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_automatic_CXX='`$ECHO "$hardcode_automatic_CXX" | $SED "$delay_single_quote_subst"`'
+inherit_rpath_CXX='`$ECHO "$inherit_rpath_CXX" | $SED "$delay_single_quote_subst"`'
+link_all_deplibs_CXX='`$ECHO "$link_all_deplibs_CXX" | $SED "$delay_single_quote_subst"`'
+always_export_symbols_CXX='`$ECHO "$always_export_symbols_CXX" | $SED "$delay_single_quote_subst"`'
+export_symbols_cmds_CXX='`$ECHO "$export_symbols_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+exclude_expsyms_CXX='`$ECHO "$exclude_expsyms_CXX" | $SED "$delay_single_quote_subst"`'
+include_expsyms_CXX='`$ECHO "$include_expsyms_CXX" | $SED "$delay_single_quote_subst"`'
+prelink_cmds_CXX='`$ECHO "$prelink_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+postlink_cmds_CXX='`$ECHO "$postlink_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+file_list_spec_CXX='`$ECHO "$file_list_spec_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_action_CXX='`$ECHO "$hardcode_action_CXX" | $SED "$delay_single_quote_subst"`'
+compiler_lib_search_dirs_CXX='`$ECHO "$compiler_lib_search_dirs_CXX" | $SED "$delay_single_quote_subst"`'
+predep_objects_CXX='`$ECHO "$predep_objects_CXX" | $SED "$delay_single_quote_subst"`'
+postdep_objects_CXX='`$ECHO "$postdep_objects_CXX" | $SED "$delay_single_quote_subst"`'
+predeps_CXX='`$ECHO "$predeps_CXX" | $SED "$delay_single_quote_subst"`'
+postdeps_CXX='`$ECHO "$postdeps_CXX" | $SED "$delay_single_quote_subst"`'
+compiler_lib_search_path_CXX='`$ECHO "$compiler_lib_search_path_CXX" | $SED "$delay_single_quote_subst"`'
+
+LTCC='$LTCC'
+LTCFLAGS='$LTCFLAGS'
+compiler='$compiler_DEFAULT'
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+  eval 'cat <<_LTECHO_EOF
+\$1
+_LTECHO_EOF'
+}
+
+# Quote evaled strings.
+for var in SHELL \
+ECHO \
+PATH_SEPARATOR \
+SED \
+GREP \
+EGREP \
+FGREP \
+LD \
+NM \
+LN_S \
+lt_SP2NL \
+lt_NL2SP \
+reload_flag \
+OBJDUMP \
+deplibs_check_method \
+file_magic_cmd \
+file_magic_glob \
+want_nocaseglob \
+DLLTOOL \
+sharedlib_from_linklib_cmd \
+AR \
+AR_FLAGS \
+archiver_list_spec \
+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 \
+nm_file_list_spec \
+lt_prog_compiler_no_builtin_flag \
+lt_prog_compiler_pic \
+lt_prog_compiler_wl \
+lt_prog_compiler_static \
+lt_cv_prog_compiler_c_o \
+need_locks \
+MANIFEST_TOOL \
+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_separator \
+exclude_expsyms \
+include_expsyms \
+file_list_spec \
+variables_saved_for_relink \
+libname_spec \
+library_names_spec \
+soname_spec \
+install_override_mode \
+finish_eval \
+old_striplib \
+striplib \
+compiler_lib_search_dirs \
+predep_objects \
+postdep_objects \
+predeps \
+postdeps \
+compiler_lib_search_path \
+LD_CXX \
+reload_flag_CXX \
+compiler_CXX \
+lt_prog_compiler_no_builtin_flag_CXX \
+lt_prog_compiler_pic_CXX \
+lt_prog_compiler_wl_CXX \
+lt_prog_compiler_static_CXX \
+lt_cv_prog_compiler_c_o_CXX \
+export_dynamic_flag_spec_CXX \
+whole_archive_flag_spec_CXX \
+compiler_needs_object_CXX \
+with_gnu_ld_CXX \
+allow_undefined_flag_CXX \
+no_undefined_flag_CXX \
+hardcode_libdir_flag_spec_CXX \
+hardcode_libdir_separator_CXX \
+exclude_expsyms_CXX \
+include_expsyms_CXX \
+file_list_spec_CXX \
+compiler_lib_search_dirs_CXX \
+predep_objects_CXX \
+postdep_objects_CXX \
+predeps_CXX \
+postdeps_CXX \
+compiler_lib_search_path_CXX; do
+    case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+    *[\\\\\\\`\\"\\\$]*)
+      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$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 \
+postlink_cmds \
+postinstall_cmds \
+postuninstall_cmds \
+finish_cmds \
+sys_lib_search_path_spec \
+sys_lib_dlsearch_path_spec \
+reload_cmds_CXX \
+old_archive_cmds_CXX \
+old_archive_from_new_cmds_CXX \
+old_archive_from_expsyms_cmds_CXX \
+archive_cmds_CXX \
+archive_expsym_cmds_CXX \
+module_cmds_CXX \
+module_expsym_cmds_CXX \
+export_symbols_cmds_CXX \
+prelink_cmds_CXX \
+postlink_cmds_CXX; do
+    case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+    *[\\\\\\\`\\"\\\$]*)
+      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\""
+      ;;
+    *)
+      eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+      ;;
+    esac
+done
+
+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'
+
+
+
+
+
+
+_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" ;;
+    "resourcesconfig.h") CONFIG_COMMANDS="$CONFIG_COMMANDS resourcesconfig.h" ;;
+    "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;;
+    "resources.pc") CONFIG_FILES="$CONFIG_FILES resources.pc" ;;
+    "Makefile") CONFIG_FILES="$CONFIG_FILES 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= ac_tmp=
+  trap 'exit_status=$?
+  : "${ac_tmp:=$tmp}"
+  { test ! -d "$ac_tmp" || rm -fr "$ac_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 -d "$tmp"
+}  ||
+{
+  tmp=./conf$$-$RANDOM
+  (umask 077 && mkdir "$tmp")
+} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
+ac_tmp=$tmp
+
+# 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 {' >"$ac_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 >>"\$ac_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 >>"\$ac_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 < "$ac_tmp/subs1.awk" > "$ac_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 sole $(srcdir),
+# ${srcdir} and @srcdir@ entries 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[	 ]*=[	 ]*/{
+h
+s///
+s/^/:/
+s/[	 ]*$/:/
+s/:\$(srcdir):/:/g
+s/:\${srcdir}:/:/g
+s/:@srcdir@:/:/g
+s/^:*//
+s/:*$//
+x
+s/\(=[	 ]*\).*/\1/
+G
+s/\n//
+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 >"$ac_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_tt=`sed -n "/$ac_delim/p" confdefs.h`
+  if test -z "$ac_tt"; 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="$ac_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 1 "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 >"$ac_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 "$ac_tmp/subs.awk" \
+  >$ac_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' "$ac_tmp/out"`; test -n "$ac_out"; } &&
+  { ac_out=`sed -n '/^[	 ]*datarootdir[	 ]*:*=/p' \
+      "$ac_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 "$ac_tmp/stdin"
+  case $ac_file in
+  -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";;
+  *) rm -f "$ac_file" && mv "$ac_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 "$ac_tmp/defines.awk"' "$ac_file_inputs"
+    } >"$ac_tmp/config.h" \
+      || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+    if diff "$ac_file" "$ac_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 "$ac_tmp/config.h" "$ac_file" \
+	|| as_fn_error $? "could not create $ac_file" "$LINENO" 5
+    fi
+  else
+    $as_echo "/* $configure_input  */" \
+      && eval '$AWK -f "$ac_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"" || {
+  # Older Autoconf 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"`
+    # 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'`; 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
+}
+ ;;
+    "resourcesconfig.h":C)
+ac_prefix_conf_OUT=`echo resourcesconfig.h`
+ac_prefix_conf_PKG=`echo `
+ac_prefix_conf_LOW=`echo $ac_prefix_conf_PKG | sed -e "y:ABCDEFGHIJKLMNOPQRSTUVWXYZ-:abcdefghijklmnopqrstuvwxyz_:"`
+ac_prefix_conf_UPP=`echo $ac_prefix_conf_PKG | sed -e "y:abcdefghijklmnopqrstuvwxyz-:ABCDEFGHIJKLMNOPQRSTUVWXYZ_:"  -e "/^[0123456789]/s/^/_/"`
+ac_prefix_conf_INP=`echo "_config.h" | sed -e 's/ *//'`
+ac_prefix_conf_DEF=`echo "$ac_prefix_conf_UPP $PACKAGE $ac_prefix_conf_OUT" | sed -e "y:abcdefghijklmnopqrstuvwxyz:ABCDEFGHIJKLMNOPQRSTUVWXYZ:" -e "s/[^abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ]/_/g"`
+
+if test ".$ac_prefix_conf_INP" = "."; then
+   for ac_file in : $CONFIG_HEADERS; do test "_$ac_file" = _: && continue
+     case "$ac_file" in
+        *.h) ac_prefix_conf_INP=$ac_file ;;
+        *)
+     esac
+     test ".$ac_prefix_conf_INP" != "." && break
+   done
+fi
+if test ".$ac_prefix_conf_INP" = "."; then
+   case "$ac_prefix_conf_OUT" in
+      */*) ac_prefix_conf_INP=`basename "$ac_prefix_conf_OUT"`
+      ;;
+      *-*) ac_prefix_conf_INP=`echo "$ac_prefix_conf_OUT" | sed -e "s/[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_]*-//"`
+      ;;
+      *) ac_prefix_conf_INP=config.h
+      ;;
+   esac
+fi
+#if test -z "$_PKG" ; then
+#   AC_MSG_ERROR([no prefix for AX_PREFIX_PKG_CONFIG_H])
+#else
+  if test ! -f "$ac_prefix_conf_INP" ; then if test -f "$srcdir/$ac_prefix_conf_INP" ; then
+     ac_prefix_conf_INP="$srcdir/$ac_prefix_conf_INP"
+  fi fi
+  { $as_echo "$as_me:${as_lineno-$LINENO}: creating '$ac_prefix_conf_OUT' - prefix '$ac_prefix_conf_UPP' for '$ac_prefix_conf_INP' defines" >&5
+$as_echo "$as_me: creating '$ac_prefix_conf_OUT' - prefix '$ac_prefix_conf_UPP' for '$ac_prefix_conf_INP' defines" >&6;}
+  if test -f $ac_prefix_conf_INP ; then
+    $as_echo "s/^#undef  *\\([ABCDEFGHIJKLMNOPQRSTUVWXYZ_]\\)/#undef $ac_prefix_conf_UPP""\\1/" > conftest.prefix
+    $as_echo "s/^#undef  *\\([abcdefghijklmnopqrstuvwxyz]\\)/#undef $ac_prefix_conf_LOW""\\1/" >> conftest.prefix
+    $as_echo "s/^#define  *\\([ABCDEFGHIJKLMNOPQRSTUVWXYZ_][abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_]*\\)\\(.*\\)/#ifndef $ac_prefix_conf_UPP""\\1\\" >> conftest.prefix
+    $as_echo "#define $ac_prefix_conf_UPP""\\1\\2\\" >> conftest.prefix
+    $as_echo "#endif/" >> conftest.prefix
+    $as_echo "s/^#define  *\\([abcdefghijklmnopqrstuvwxyz][abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_]*\\)\\(.*\\)/#ifndef $ac_prefix_conf_LOW""\\1\\" >> conftest.prefix
+    $as_echo "#define $ac_prefix_conf_LOW""\\1\\2\\" >> conftest.prefix
+    $as_echo "#endif/" >> conftest.prefix
+
+    # now executing _script on _DEF input to create _OUT output file
+    echo "#ifndef $ac_prefix_conf_DEF"      >$tmp/pconfig.h
+    echo "#define $ac_prefix_conf_DEF 1" >>$tmp/pconfig.h
+    echo ' ' >>$tmp/pconfig.h
+
+    echo /'*' $ac_prefix_conf_OUT. Generated automatically at end of configure. '*'/ >>$tmp/pconfig.h
+    echo ' ' >>$tmp/pconfig.h
+
+    sed -f conftest.prefix $ac_prefix_conf_INP >>$tmp/pconfig.h
+    echo ' ' >>$tmp/pconfig.h
+    echo '/* once:' $ac_prefix_conf_DEF '*/' >>$tmp/pconfig.h
+    echo "#endif" >>$tmp/pconfig.h
+    if cmp -s $ac_prefix_conf_OUT $tmp/pconfig.h 2>/dev/null; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_prefix_conf_OUT is unchanged" >&5
+$as_echo "$as_me: $ac_prefix_conf_OUT is unchanged" >&6;}
+    else
+      ac_dir=`$as_dirname -- "$ac_prefix_conf_OUT" ||
+$as_expr X"$ac_prefix_conf_OUT" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$ac_prefix_conf_OUT" : 'X\(//\)[^/]' \| \
+	 X"$ac_prefix_conf_OUT" : 'X\(//\)$' \| \
+	 X"$ac_prefix_conf_OUT" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$ac_prefix_conf_OUT" |
+    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
+      rm -f "$ac_prefix_conf_OUT"
+      mv $tmp/pconfig.h "$ac_prefix_conf_OUT"
+    fi
+    cp conftest.prefix _configs.sed
+    rm _configs.sed
+  else
+    as_fn_error $? "input file $ac_prefix_conf_INP does not exist - skip generating $ac_prefix_conf_OUT" "$LINENO" 5
+  fi
+  rm -f conftest.*
+#fi
+ ;;
+    "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, 2009, 2010, 2011 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="CXX "
+
+# ### BEGIN LIBTOOL CONFIG
+
+# 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
+
+# Shell to use when invoking shell scripts.
+SHELL=$lt_SHELL
+
+# An echo program that protects backslashes.
+ECHO=$lt_ECHO
+
+# The PATH separator for the build system.
+PATH_SEPARATOR=$lt_PATH_SEPARATOR
+
+# 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
+
+# convert \$build file names to \$host format.
+to_host_file_cmd=$lt_cv_to_host_file_cmd
+
+# convert \$build files to toolchain format.
+to_tool_file_cmd=$lt_cv_to_tool_file_cmd
+
+# An object symbol dumper.
+OBJDUMP=$lt_OBJDUMP
+
+# 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
+
+# How to find potential files when deplibs_check_method = "file_magic".
+file_magic_glob=$lt_file_magic_glob
+
+# Find potential files using nocaseglob when deplibs_check_method = "file_magic".
+want_nocaseglob=$lt_want_nocaseglob
+
+# DLL creation program.
+DLLTOOL=$lt_DLLTOOL
+
+# Command to associate shared and link libraries.
+sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd
+
+# The archiver.
+AR=$lt_AR
+
+# Flags to create an archive.
+AR_FLAGS=$lt_AR_FLAGS
+
+# How to feed a file listing to the archiver.
+archiver_list_spec=$lt_archiver_list_spec
+
+# 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
+
+# Whether to use a lock for old archive extraction.
+lock_old_archive_extraction=$lock_old_archive_extraction
+
+# 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
+
+# Specify filename containing input files for \$NM.
+nm_file_list_spec=$lt_nm_file_list_spec
+
+# The root where to search for dependent libraries,and in which our libraries should be installed.
+lt_sysroot=$lt_sysroot
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# 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
+
+# Manifest tool.
+MANIFEST_TOOL=$lt_MANIFEST_TOOL
+
+# 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
+
+# Permission mode override for installation of shared libraries.
+install_override_mode=$lt_install_override_mode
+
+# 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
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag
+reload_cmds=$lt_reload_cmds
+
+# 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
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_lt_prog_compiler_pic
+
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl
+
+# 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
+
+# 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
+
+# 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
+
+# Commands necessary for finishing linking programs.
+postlink_cmds=$lt_postlink_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
+
+# The directories searched by this compiler when creating a shared library.
+compiler_lib_search_dirs=$lt_compiler_lib_search_dirs
+
+# Dependencies to place before and after the objects being linked to
+# create a shared library.
+predep_objects=$lt_predep_objects
+postdep_objects=$lt_postdep_objects
+predeps=$lt_predeps
+postdeps=$lt_postdeps
+
+# The library search path used internally by the compiler when linking
+# a shared library.
+compiler_lib_search_path=$lt_compiler_lib_search_path
+
+# ### 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 '$q' "$ltmain" >> "$cfgfile" \
+     || (rm -f "$cfgfile"; exit 1)
+
+  if test x"$xsi_shell" = xyes; then
+  sed -e '/^func_dirname ()$/,/^} # func_dirname /c\
+func_dirname ()\
+{\
+\    case ${1} in\
+\      */*) func_dirname_result="${1%/*}${2}" ;;\
+\      *  ) func_dirname_result="${3}" ;;\
+\    esac\
+} # Extended-shell func_dirname implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_basename ()$/,/^} # func_basename /c\
+func_basename ()\
+{\
+\    func_basename_result="${1##*/}"\
+} # Extended-shell func_basename implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_dirname_and_basename ()$/,/^} # func_dirname_and_basename /c\
+func_dirname_and_basename ()\
+{\
+\    case ${1} in\
+\      */*) func_dirname_result="${1%/*}${2}" ;;\
+\      *  ) func_dirname_result="${3}" ;;\
+\    esac\
+\    func_basename_result="${1##*/}"\
+} # Extended-shell func_dirname_and_basename implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_stripname ()$/,/^} # func_stripname /c\
+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}"}\
+} # Extended-shell func_stripname implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_split_long_opt ()$/,/^} # func_split_long_opt /c\
+func_split_long_opt ()\
+{\
+\    func_split_long_opt_name=${1%%=*}\
+\    func_split_long_opt_arg=${1#*=}\
+} # Extended-shell func_split_long_opt implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_split_short_opt ()$/,/^} # func_split_short_opt /c\
+func_split_short_opt ()\
+{\
+\    func_split_short_opt_arg=${1#??}\
+\    func_split_short_opt_name=${1%"$func_split_short_opt_arg"}\
+} # Extended-shell func_split_short_opt implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_lo2o ()$/,/^} # func_lo2o /c\
+func_lo2o ()\
+{\
+\    case ${1} in\
+\      *.lo) func_lo2o_result=${1%.lo}.${objext} ;;\
+\      *)    func_lo2o_result=${1} ;;\
+\    esac\
+} # Extended-shell func_lo2o implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_xform ()$/,/^} # func_xform /c\
+func_xform ()\
+{\
+    func_xform_result=${1%.*}.lo\
+} # Extended-shell func_xform implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_arith ()$/,/^} # func_arith /c\
+func_arith ()\
+{\
+    func_arith_result=$(( $* ))\
+} # Extended-shell func_arith implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_len ()$/,/^} # func_len /c\
+func_len ()\
+{\
+    func_len_result=${#1}\
+} # Extended-shell func_len implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+fi
+
+if test x"$lt_shell_append" = xyes; then
+  sed -e '/^func_append ()$/,/^} # func_append /c\
+func_append ()\
+{\
+    eval "${1}+=\\${2}"\
+} # Extended-shell func_append implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_append_quoted ()$/,/^} # func_append_quoted /c\
+func_append_quoted ()\
+{\
+\    func_quote_for_eval "${2}"\
+\    eval "${1}+=\\\\ \\$func_quote_for_eval_result"\
+} # Extended-shell func_append_quoted implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  # Save a `func_append' function call where possible by direct use of '+='
+  sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \
+    && mv -f "$cfgfile.tmp" "$cfgfile" \
+      || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+  test 0 -eq $? || _lt_function_replace_fail=:
+else
+  # Save a `func_append' function call even when '+=' is not available
+  sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \
+    && mv -f "$cfgfile.tmp" "$cfgfile" \
+      || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+  test 0 -eq $? || _lt_function_replace_fail=:
+fi
+
+if test x"$_lt_function_replace_fail" = x":"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to substitute extended shell functions in $ofile" >&5
+$as_echo "$as_me: WARNING: Unable to substitute extended shell functions in $ofile" >&2;}
+fi
+
+
+   mv -f "$cfgfile" "$ofile" ||
+    (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
+  chmod +x "$ofile"
+
+
+    cat <<_LT_EOF >> "$ofile"
+
+# ### BEGIN LIBTOOL TAG CONFIG: CXX
+
+# The linker used to build libraries.
+LD=$lt_LD_CXX
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag_CXX
+reload_cmds=$lt_reload_cmds_CXX
+
+# Commands used to build an old-style archive.
+old_archive_cmds=$lt_old_archive_cmds_CXX
+
+# A language specific compiler.
+CC=$lt_compiler_CXX
+
+# Is the compiler the GNU compiler?
+with_gcc=$GCC_CXX
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_CXX
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_lt_prog_compiler_pic_CXX
+
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl_CXX
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_lt_prog_compiler_static_CXX
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_lt_cv_prog_compiler_c_o_CXX
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$archive_cmds_need_lc_CXX
+
+# Whether or not to disallow shared libs when runtime libs are static.
+allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_CXX
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_CXX
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_whole_archive_flag_spec_CXX
+
+# Whether the compiler copes with passing no objects directly.
+compiler_needs_object=$lt_compiler_needs_object_CXX
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_CXX
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_CXX
+
+# Commands used to build a shared archive.
+archive_cmds=$lt_archive_cmds_CXX
+archive_expsym_cmds=$lt_archive_expsym_cmds_CXX
+
+# Commands used to build a loadable module if different from building
+# a shared archive.
+module_cmds=$lt_module_cmds_CXX
+module_expsym_cmds=$lt_module_expsym_cmds_CXX
+
+# Whether we are building with GNU ld or not.
+with_gnu_ld=$lt_with_gnu_ld_CXX
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_allow_undefined_flag_CXX
+
+# Flag that enforces no undefined symbols.
+no_undefined_flag=$lt_no_undefined_flag_CXX
+
+# 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_CXX
+
+# Whether we need a single "-rpath" flag with a separated argument.
+hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX
+
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
+# DIR into the resulting binary.
+hardcode_direct=$hardcode_direct_CXX
+
+# 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_CXX
+
+# Set to "yes" if using the -LDIR flag during linking hardcodes DIR
+# into the resulting binary.
+hardcode_minus_L=$hardcode_minus_L_CXX
+
+# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
+# into the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var_CXX
+
+# 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_CXX
+
+# Set to yes if linker adds runtime paths of dependent libraries
+# to runtime path list.
+inherit_rpath=$inherit_rpath_CXX
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$link_all_deplibs_CXX
+
+# Set to "yes" if exported symbols are required.
+always_export_symbols=$always_export_symbols_CXX
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_export_symbols_cmds_CXX
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_exclude_expsyms_CXX
+
+# Symbols that must always be exported.
+include_expsyms=$lt_include_expsyms_CXX
+
+# Commands necessary for linking programs (against libraries) with templates.
+prelink_cmds=$lt_prelink_cmds_CXX
+
+# Commands necessary for finishing linking programs.
+postlink_cmds=$lt_postlink_cmds_CXX
+
+# Specify filename containing input files.
+file_list_spec=$lt_file_list_spec_CXX
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action_CXX
+
+# The directories searched by this compiler when creating a shared library.
+compiler_lib_search_dirs=$lt_compiler_lib_search_dirs_CXX
+
+# Dependencies to place before and after the objects being linked to
+# create a shared library.
+predep_objects=$lt_predep_objects_CXX
+postdep_objects=$lt_postdep_objects_CXX
+predeps=$lt_predeps_CXX
+postdeps=$lt_postdeps_CXX
+
+# The library search path used internally by the compiler when linking
+# a shared library.
+compiler_lib_search_path=$lt_compiler_lib_search_path_CXX
+
+# ### END LIBTOOL TAG CONFIG: CXX
+_LT_EOF
+
+ ;;
+
+  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 1
+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/resources/configure.ac b/resources/configure.ac
new file mode 100644
index 0000000..ab3f5a7
--- /dev/null
+++ b/resources/configure.ac
@@ -0,0 +1,74 @@
+AC_INIT([resources], [4.0.1])
+
+AC_CONFIG_MACRO_DIR([../m4])
+AC_CONFIG_AUX_DIR([../build-aux])
+AC_CONFIG_SRCDIR([omFindExec.h])
+AC_CONFIG_HEADER([_config.h])
+
+AM_MAINTAINER_MODE([enable])
+AM_INIT_AUTOMAKE([-Wall foreign subdir-objects]) # -Wno-extra-portability -Werror silent-rules
+m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
+m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
+
+dnl Check if build env is sane
+AM_SANITY_CHECK
+
+# Add pre'prefixed config
+AX_PREFIX_CONFIG_H([resourcesconfig.h],[],[_config.h])
+
+SING_RESET_FLAGS()
+SING_CHECK_SET_ARGS()
+
+AM_PROG_CC_C_O
+# AM_PROG_AR
+
+AC_PROG_LN_S
+AC_PROG_INSTALL
+
+AC_FUNC_MALLOC
+AC_HEADER_STDC
+AC_CHECK_HEADERS([stdlib.h string.h unistd.h pwd.h sys/param.h sys/stat.h sys/types.h])
+AC_CHECK_FUNCS(readlink getcwd getwd getpwnam setenv putenv)
+
+# Checks for typedefs, structures, and compiler characteristics.
+AC_C_CONST
+AC_C_INLINE
+AC_HEADER_STDBOOL
+AC_TYPE_SIZE_T
+
+# Turn off shared libraries during beta-testing, since they
+# make the build process take too long.
+LT_INIT
+# ([shared])
+# LT_INIT(dlopen disable-static) # doesn't work on PowerPC!
+
+# SING_CHECK_PIPE
+
+##### SEE http://www.gnu.org/prep/standards/html_node/Directory-Variables.html
+
+AX_RECURSIVE_EVAL([[$]prefix], [config_prefix])
+AX_NORMALIZE_PATH([config_prefix],['/'])
+AC_DEFINE_UNQUOTED([PREFIX],"$config_prefix",[prefix])
+
+AX_RECURSIVE_EVAL([[$]exec_prefix], [config_exec_prefix])
+AX_NORMALIZE_PATH([config_exec_prefix],['/'])
+AC_DEFINE_UNQUOTED([EXEC_PREFIX],"$config_exec_prefix",[exec_prefix])
+
+AX_RECURSIVE_EVAL([[$]libexecdir], [config_libexecdir])
+AX_NORMALIZE_PATH([config_libexecdir],['/'])
+AC_DEFINE_UNQUOTED([LIBEXEC_DIR],"$config_libexecdir",[libexecdir])
+
+AX_RECURSIVE_EVAL([[$]libdir], [config_libdir])
+AX_NORMALIZE_PATH([config_libdir],['/'])
+AC_DEFINE_UNQUOTED([LIB_DIR],"$config_libdir",[libdir])
+
+AX_RECURSIVE_EVAL([[$]bindir], [config_bindir])
+AX_NORMALIZE_PATH([config_bindir],['/'])
+AC_DEFINE_UNQUOTED([BIN_DIR],"$config_bindir",[bindir])
+
+AX_RECURSIVE_EVAL([[$]datadir], [config_datadir])
+AX_NORMALIZE_PATH([config_datadir],['/'])
+AC_DEFINE_UNQUOTED([DATA_DIR],"$config_datadir",[datadir])
+
+AC_CONFIG_FILES([resources.pc Makefile])
+AC_OUTPUT
diff --git a/resources/feFopen.cc b/resources/feFopen.cc
new file mode 100644
index 0000000..9dcf42d
--- /dev/null
+++ b/resources/feFopen.cc
@@ -0,0 +1,210 @@
+#include "resourcesconfig.h"
+#include "feResource.h"
+#include "feFopen.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <errno.h>
+
+#if defined(HAVE_PWD_H) && defined(HAVE_GETPWNAM)
+#include <pwd.h>
+#endif
+
+
+
+
+extern "C" {
+void (*WerrorS_callback)(const char *s) = NULL;
+short errorreported=0;
+void WerrorS(const char *s)
+{
+  if (WerrorS_callback == NULL)
+  {
+     fwrite("   ? ",1,5,stderr);
+     fwrite((char *)s,1,strlen((char *)s),stderr);
+     fwrite("\n",1,1,stderr);
+     fflush(stderr);
+  }
+  else
+  {
+    WerrorS_callback(s);
+  }
+  errorreported = 1;
+}
+}
+
+/*****************************************************************
+ *
+ * File handling
+ *
+ *****************************************************************/
+
+FILE * feFopen(const char *path, const char *mode, char *where,
+               short useWerror, short path_only)
+{
+  char longpath[MAXPATHLEN];
+  if (path[0]=='~')
+  {
+    if (path[1] == DIR_SEP)
+    {
+      const char* home = getenv("HOME");
+#ifdef __CUGWIN__
+      if ((home==NULL)||(!access(home,X_OK)))
+        home = getenv("SINGHOME");
+#endif
+      if (home != NULL)
+      {
+        strcpy(longpath, home);
+        strcat(longpath, &(path[1]));
+        path = longpath;
+      }
+    }
+#if defined(HAVE_PWD_H) && defined(HAVE_GETPWNAM)
+    else
+    {
+      char* dir_sep;
+      struct passwd *pw_entry;
+      strcpy (longpath, path);
+      dir_sep = strchr(longpath, DIR_SEP);
+      if (dir_sep==NULL)
+      {
+        char buf[256];
+        strcpy(buf,"illegal ~ in filename >>");
+        strncat(buf,longpath,235);
+        strcat(buf,"<<");
+        WerrorS(buf);
+        return NULL;
+      }
+      *dir_sep = '\0';
+      pw_entry = getpwnam(&longpath[1]);
+      if (pw_entry != NULL)
+      {
+        strcpy(longpath, pw_entry->pw_dir);
+        dir_sep = strchr((char *)path, DIR_SEP);
+        strcat(longpath, dir_sep);
+        path = longpath;
+      }
+    }
+#endif
+  }
+  FILE * f=NULL;
+  if (! path_only)
+  {
+    struct stat statbuf;
+    int res = -1;
+    do
+    {
+      res = stat(path,&statbuf);
+    } while((res < 0) and (errno == EINTR));
+    if ((res == 0)
+    && (S_ISREG(statbuf.st_mode)))
+      f = myfopen(path,mode);
+  }
+  if (where!=NULL) strcpy(where,path);
+  if ((*mode=='r') &&
+      (path[0]!=DIR_SEP) &&
+      ! (path[0] == '.' && path[1] == DIR_SEP) &&
+      (f==NULL))
+  {
+    char found = 0;
+    char* spath = feResource('s');
+    char *s;
+
+    if (where==NULL) s=(char *)malloc(1024);
+    else             s=where;
+
+    if (spath!=NULL)
+    {
+      char *p,*q;
+      p = spath;
+      while( (q=strchr(p, fePathSep)) != NULL)
+      {
+        *q = '\0';
+        strcpy(s,p);
+        *q = fePathSep;
+        strcat(s, DIR_SEPP);
+        strcat(s, path);
+        if(!access(s, R_OK)) { found++; break; }
+        p = q+1;
+      }
+      if(!found)
+      {
+        strcpy(s,p);
+        strcat(s, DIR_SEPP);
+        strcat(s, path);
+      }
+      f=myfopen(s,mode);
+      if (f!=NULL)
+      {
+        if (where==NULL) free(s);
+        return f;
+      }
+    }
+    else
+    {
+      if (where!=NULL) strcpy(s/*where*/,path);
+      f=myfopen(path,mode);
+    }
+    if (where==NULL) free(s);
+  }
+  if ((f==NULL)&&(useWerror))
+  {
+    char buf[256];
+    strcpy(buf,"cannot open `");
+    strncat(buf,path,240);
+    strcat(buf,"`");
+    WerrorS(buf);
+  }
+  return f;
+}
+
+// Make sure that mode contains binary option
+FILE* myfopen(const char *path, const char *mode)
+{
+#if (defined(__CUGWIN__))
+  char mmode[4];
+  int i;
+  int done = 0;
+
+  for (i=0;;i++)
+  {
+    mmode[i] = mode[i];
+    if (mode[i] == '\0') break;
+    if (mode[i] == 'w') done = 1;
+    if (mode[i] == 'a') done = 1;
+    if (mode[i] == 'b') done = 1;
+  }
+
+  if (! done)
+  {
+    mmode[i] = 'b';
+    mmode[i+1] = '\0';
+  }
+  return fopen(path, mmode);
+#else
+  return fopen(path, mode);
+#endif
+}
+// replace "\r\n" by " \n" and "\r" by "\n"
+
+size_t myfread(void *ptr, size_t size, size_t nmemb, FILE *stream)
+{
+  size_t got = fread(ptr, size, nmemb, stream) * size;
+  size_t i;
+
+  for (i=0; i<got; i++)
+  {
+    if ( ((char*) ptr)[i] == '\r')
+    {
+      if (i+1 < got && ((char*) ptr)[i+1] == '\n')
+        ((char*) ptr)[i] = ' ';
+      else
+        ((char*) ptr)[i] = '\n';
+    }
+  }
+  return got;
+}
diff --git a/resources/feFopen.h b/resources/feFopen.h
new file mode 100644
index 0000000..c593abb
--- /dev/null
+++ b/resources/feFopen.h
@@ -0,0 +1,37 @@
+#ifndef FEFOPEN_H
+#define FEFOPEN_H
+
+/*****************************************************************
+ *
+ * File Stuff
+ *
+ *****************************************************************/
+#ifdef __cplusplus
+
+#include <stdio.h>
+
+FILE*feFopen(const char *path, const char *mode, char *where=0, short useWerror=0, short path_only=0);
+
+/*
+// These are our versions of fopen and fread They are very similar to
+// the usual fopen and fread, except that on reading, they always
+// convert "\r\n" into " \n" and "\r" into "\n".
+//
+// IMPORTANT: do only use myfopen and myfread when reading text,
+// do never use fopen and fread
+*/
+FILE *myfopen(const char *path, const char *mode);
+size_t myfread(void *ptr, size_t size, size_t nmemb, FILE *stream);
+
+extern "C"
+{
+#endif
+
+extern short errorreported;
+void    WerrorS(const char *s);
+extern void (*WerrorS_callback)(const char *s);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/resources/feResource.cc b/resources/feResource.cc
new file mode 100644
index 0000000..c55c027
--- /dev/null
+++ b/resources/feResource.cc
@@ -0,0 +1,717 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: management of resources
+*/
+
+#include "resourcesconfig.h"
+#include "feResource.h"
+#include "omFindExec.h"
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdio.h>
+#include <sys/param.h>
+
+
+char* feArgv0 = NULL;
+
+#ifdef AIX_4
+#ifndef HAVE_PUTENV
+#define HAVE_PUTENV 1
+#endif
+#endif
+
+#if defined(HPUX_10) || defined(HPUX_9)
+#ifndef HAVE_SETENV
+extern "C" int setenv(const char *name, const char *value, int overwrite);
+#endif
+#endif
+
+
+//char* feResource(const char id, int warn = -1);
+//char* feResource(const char* key, int warn = -1);
+
+// define RESOURCE_DEBUG for chattering about resource management
+// #define RESOURCE_DEBUG
+
+#define SINGULAR_DEFAULT_DIR PREFIX
+
+/*****************************************************************
+ *
+ * Declarations: Data  structures
+ *
+ *****************************************************************/
+// feSprintf transforms format strings as follows:
+// 1.) substrings of the form %c (c being a letter) are replaced by respective resource value
+// 2.) substrings of the form $string are replaced by value of resp. env variable
+
+// feCleanResource makes furthermore  the following transformations (except for URL resources)
+// 1.) '/' characters are replaced by respective directory - separators
+// 2.) ';' characters are replaced by respective path separators
+feResourceConfig_s feResourceConfigs[] =
+{
+  {"SearchPath",    's', feResPath,  NULL,
+   "$SINGULARPATH;"
+   "%D/singular/LIB;"
+   "%r/share/singular/LIB;"
+   "%b/../share/singular/LIB;"
+   // gftables:
+   "%D/factory;"
+   "%r/share/factory;"
+   "%b/LIB;"
+   "%b/../factory;"
+   // path for dynamic modules, should match ProcDir:
+   "%b/MOD;"
+   "%r/lib/singular/MOD;"
+   "%r/libexec/singular/MOD;"
+   LIB_DIR "/singular/MOD;"
+   LIBEXEC_DIR "/singular/MOD;"
+   "%b",
+   (char *)""},
+  {"Singular",  'S',    feResBinary,"SINGULAR_EXECUTABLE",  "%d/Singular",          (char *)""},
+  {"BinDir",    'b',    feResDir,   "SINGULAR_BIN_DIR",     "",                  (char *)""},
+  // should be changed to %b/../lib/singular/pProcs/:
+  {"ProcDir",   'P',    feResPath,  "SINGULAR_PROCS_DIR",
+     "%b/MOD;"
+     "%r/lib/singular/MOD;"
+     "%r/libexec/singular/MOD;"
+     LIB_DIR "/singular/MOD;"   /*debian: -> /usr/lib/singular/MOD */
+     LIBEXEC_DIR "/singular/MOD" ,                  (char *)""},
+  {"RootDir",   'r',    feResDir,   "SINGULAR_ROOT_DIR",    "%b/..",                (char *)""},
+  {"DataDir",   'D',    feResDir,   "SINGULAR_DATA_DIR",    "%b/../share/",          (char *)""},
+  {"DefaultDir",'d',    feResDir,   "SINGULAR_DEFAULT_DIR",  SINGULAR_DEFAULT_DIR,  (char *)""},
+  {"InfoFile",  'i',    feResFile,  "SINGULAR_INFO_FILE",   "%D/info/singular.hlp", (char *)""},
+  {"IdxFile",   'x',    feResFile,  "SINGULAR_IDX_FILE",    "%D/doc/singular.idx",  (char *)""},
+  {"HtmlDir",   'h',    feResDir,   "SINGULAR_HTML_DIR",    "%D/singular/html",              (char *)""},
+  {"ManualUrl", 'u',    feResUrl,   "SINGULAR_URL",         "http://www.singular.uni-kl.de/Manual/",    (char *)""},
+  {"ExDir",     'm',    feResDir,   "SINGULAR_EXAMPLES_DIR","%r/examples",          (char *)""},
+  {"Path",      'p',    feResPath,  NULL,                   "%b;%P;$PATH",             (char *)""},
+
+  {"emacs",     'E',    feResBinary,"ESINGULAR_EMACS",      "%b/emacs",             (char *)""},
+  {"xemacs",    'A',    feResBinary,"ESINGULAR_EMACS",      "%b/xemacs",            (char *)""},
+  {"SingularEmacs",'M', feResBinary,"ESINGULAR_SINGULAR",   "%b/Singular",          (char *)""},
+  {"EmacsLoad", 'l',    feResFile,  "ESINGULAR_EMACS_LOAD", "%e/.emacs-singular",   (char *)""},
+  {"EmacsDir",  'e',    feResDir,   "ESINGULAR_EMACS_DIR",  "%D/singular/emacs",             (char *)""},
+  {"SingularXterm",'M', feResBinary,"TSINGULAR_SINGULAR",   "%b/Singular",          (char *)""},
+#ifdef __CYGWIN__
+  {"rxvt",      'X',    feResBinary,"RXVT",                 "%b/rxvt",              (char *)""},
+#else
+  {"xterm",     'X',    feResBinary,"XTERM",                "%b/xterm",             (char *)""},
+#endif
+  {"EmacsDir",  'e',    feResDir,   "SINGULAR_EMACS_DIR",   "%r/emacs",             (char *)""},
+  {NULL, 0, feResUndef, NULL, NULL, NULL}, // must be the last record
+};
+
+
+/*****************************************************************
+ *
+ * Declarations: Local variables / functions
+ *
+ *****************************************************************/
+
+#define MAXRESOURCELEN 5*MAXPATHLEN
+
+static feResourceConfig feGetResourceConfig(const char id);
+static feResourceConfig feGetResourceConfig(const char* key);
+static char* feResource(feResourceConfig config, int warn);
+static char* feResourceDefault(feResourceConfig config);
+static char* feInitResource(feResourceConfig config, int warn);
+static char* feGetExpandedExecutable();
+static int feVerifyResourceValue(feResourceType type, char* value);
+static char* feCleanResourceValue(feResourceType type, char* value);
+static char* feCleanUpFile(char* fname);
+static char* feCleanUpPath(char* path);
+static void mystrcpy(char* d, char* s);
+static char* feSprintf(char* s, const char* fmt, int warn = -1);
+#if defined(__CYGWIN__) && defined(__GNUC__)
+// utility function of Cygwin32:
+extern "C" int cygwin32_posix_path_list_p (const char *path);
+#endif
+
+/*****************************************************************
+ *
+ * Public functions
+ *
+ *****************************************************************/
+char* feResource(const char* key, int warn)
+{
+  return feResource(feGetResourceConfig(key), warn);
+}
+
+char* feResource(const char id, int warn)
+{
+  return feResource(feGetResourceConfig(id), warn);
+}
+
+char* feGetResource(const char id, int warn)
+{
+  return feResource(feGetResourceConfig(id), warn);
+}
+
+char* feResourceDefault(const char id)
+{
+  return feResourceDefault(feGetResourceConfig(id));
+}
+
+char* feResourceDefault(const char* key)
+{
+  return feResourceDefault(feGetResourceConfig(key));
+}
+
+void feInitResources(const char* argv0)
+{
+  if (argv0==NULL)
+  {
+    //WarnS("illegal argv[0]==NULL");
+    feArgv0 = (char*)malloc(MAXPATHLEN+strlen("/Singular"));
+    getcwd(feArgv0, MAXPATHLEN);
+    strcpy(feArgv0+strlen(feArgv0),"/Singular");
+  }
+  else
+    feArgv0 = strdup(argv0);
+#ifdef RESOURCE_DEBUG
+  printf("feInitResources(argv0: '%s'): entering...\n", feArgv0);
+#endif
+  // init some Resources
+  feResource('b');
+  feResource('r');
+  // don't complain about stuff when initializing SingularPath
+  feResource('s',0);
+  feResource('P');
+
+#if defined(HAVE_SETENV) || defined(HAVE_PUTENV)
+  char* path = feResource('p');
+#ifdef RESOURCE_DEBUG
+  printf("feInitResources(argv0): setting path with '%s'\n", path);
+#endif
+#ifdef HAVE_PUTENV
+  if (path != NULL) { char *s=(char *)malloc(strlen(path)+6);
+                      sprintf(s,"PATH=%s",path);
+                      putenv(s);
+                    }
+#else
+  if (path != NULL) setenv("PATH", path, 1);
+#endif
+#endif
+}
+
+void feReInitResources()
+{
+  int i = 0;
+  while (feResourceConfigs[i].key != NULL)
+  {
+    if ((feResourceConfigs[i].value != NULL)
+    && (feResourceConfigs[i].value[0] != '\0'))
+    {
+      free(feResourceConfigs[i].value);
+      feResourceConfigs[i].value = (char *)"";
+    }
+    i++;
+  }
+#ifdef RESOURCE_DEBUG
+  printf("feInitResources(): entering...\n");
+#endif
+  // init some Resources
+  feResource('b');
+  feResource('r');
+  // don't complain about stuff when initializing SingularPath
+  feResource('s',0);
+}
+
+/*****************************************************************
+ *
+ * Local functions
+ *
+ *****************************************************************/
+static feResourceConfig feGetResourceConfig(const char id)
+{
+  int i = 0;
+  while (feResourceConfigs[i].key != NULL)
+  {
+    if (feResourceConfigs[i].id == id) return &(feResourceConfigs[i]);
+    i++;
+  }
+  return NULL;
+}
+
+static feResourceConfig feGetResourceConfig(const char* key)
+{
+  int i = 0;
+  while (feResourceConfigs[i].key != NULL)
+  {
+    if (strcmp(feResourceConfigs[i].key, key) == 0)
+      return &(feResourceConfigs[i]);
+    i++;
+  }
+  return NULL;
+}
+
+static char* feResource(feResourceConfig config, int warn)
+{
+  if (config == NULL) return NULL;
+  if (config->value != NULL && *(config->value) != '\0') return config->value;
+  return feInitResource(config, warn);
+}
+
+static char* feResourceDefault(feResourceConfig config)
+{
+  if (config == NULL) return NULL;
+  char* value = (char*) malloc(MAXRESOURCELEN);
+  feSprintf(value, config->fmt, -1);
+  return value;
+}
+
+static char* feInitResource(feResourceConfig config, int warn)
+{
+  /*assume(config != NULL);*/
+#ifdef RESOURCE_DEBUG
+  printf("feInitResource(config->key: '%s', warn: '%d') : entering ...\n", config->key, warn);
+#endif
+
+  char value[MAXRESOURCELEN];
+  // now we have to work
+  // First, check Environment variable
+  if (config->env != NULL)
+  {
+    char* evalue = getenv(config->env);
+    if (evalue != NULL)
+    {
+#ifdef RESOURCE_DEBUG
+      printf("feInitResource(config,warn): Found value from env:%s\n", evalue);
+#endif
+      strcpy(value, evalue);
+      if (config->type == feResBinary  // do not verify binaries
+          ||
+          feVerifyResourceValue(config->type,
+                                feCleanResourceValue(config->type, value)))
+      {
+#ifdef RESOURCE_DEBUG
+        printf("feInitResource(config,warn): Set value of config (with key: '%s') to '%s'\n", config->key, value);
+#endif
+        config->value = strdup(value);
+        return config->value;
+      }
+    }
+  }
+
+  *value = '\0';
+  // Special treatment of executable
+  if (config->id == 'S')
+  {
+    char* executable = feGetExpandedExecutable();
+    if (executable != NULL)
+    {
+#ifdef RESOURCE_DEBUG
+      printf("exec:%s\n", executable);
+#endif
+      strcpy(value, executable);
+#ifdef RESOURCE_DEBUG
+      printf("value:%s\n", value);
+#endif
+      free(executable);
+    }
+  }
+  // and bindir
+  else if (config->id == 'b')
+  {
+    char* executable = feResource('S');
+#ifdef RESOURCE_DEBUG
+      printf("feInitResource(config,warn): Get '%s' from \"%s\"\n", config->key, executable);
+#endif
+    if (executable != NULL)
+    {
+      strcpy(value, executable);
+      executable = strrchr(value, DIR_SEP);
+      if (executable != NULL) *executable = '\0';
+    }
+  }
+
+#ifdef RESOURCE_DEBUG
+  printf("value:%s\n", value);
+#endif
+
+  if (*value == '\0' && config->fmt != NULL )
+  {
+    feSprintf(value, config->fmt, warn);
+  }
+  else if (config->fmt == NULL)
+  {
+    printf("Bug >>Wrong Resource Specification of '%s'<< at \"%s:%d\"\n",config->key,__FILE__,__LINE__);
+    // TODO: printf -> WarnS???
+    return NULL;
+  }
+
+  // Clean and verify
+  if (feVerifyResourceValue(config->type,
+                            feCleanResourceValue(config->type, value)))
+  {
+#ifdef RESOURCE_DEBUG
+    printf("feInitResource(config,warn): Set value of '%s' to \"%s\"\n", config->key, value);
+#endif
+    config->value = strdup(value);
+    return config->value;
+  }
+  else if (config->type == feResBinary)
+  {
+    // for binaries, search through PATH once more
+    char* executable = omFindExec(config->key, value);
+    if (executable != NULL)
+    {
+      if (feVerifyResourceValue(config->type,
+                                feCleanResourceValue(config->type, value)))
+      {
+        config->value = strdup(value);
+#ifdef RESOURCE_DEBUG
+        printf("feInitResource(config,warn): Set value of '%s' to \"%s\"\n", config->key, config->value);
+#endif
+        return config->value;
+      }
+    }
+  }
+
+  // issue warning if explicitely requested, or if
+  // this value is gotten for the first time
+  if (warn > 0 || (warn < 0 && config->value != NULL))
+  {
+    printf("// ** Could not get '%s'.\n", config->key);
+    printf("// ** Either set environment variable '%s' to '%s',\n",
+         config->env, config->key);
+    feSprintf(value, config->fmt, warn);
+    printf("// ** or make sure that '%s' is at \"%s\"\n", config->key, value);
+  }
+#ifdef RESOURCE_DEBUG
+  printf("feInitResource(config,warn): Set value of '%s' to NULL", config->key);
+#endif
+  config->value = NULL;
+  return NULL;
+}
+
+static char* feGetExpandedExecutable()
+{
+  if (feArgv0 == NULL || *feArgv0 == '\0')
+  {
+    if (feArgv0 == NULL)
+      printf("Bug >>feArgv0 == NULL<< at %s:%d\n",__FILE__,__LINE__);
+    else
+      printf("Bug >>feArgv0 == ''<< at %s:%d\n",__FILE__,__LINE__);
+    return NULL;
+  }
+#ifdef __CYGWIN__ // stupid WINNT sometimes gives you argv[0] within ""
+  if (*feArgv0 == '"')
+  {
+    int l = strlen(feArgv0);
+    if (feArgv0[l-1] == '"')
+    {
+      feArgv0[l-1] = '\0';
+      feArgv0++;
+    }
+  }
+#endif
+#ifdef RESOURCE_DEBUG
+  printf("feGetExpandedExecutable: calling find_exec with \"%s\"\n", feArgv0);
+#endif
+  char executable[MAXRESOURCELEN];
+  char* value = omFindExec(feArgv0, executable);
+#ifdef RESOURCE_DEBUG
+  printf("feGetExpandedExecutable: find_exec exited with \"%s\": %d\n", executable, access(executable, X_OK));
+#endif
+  if (value == NULL)
+  {
+    printf("Bug >>Could not get expanded executable from \"%s\"<< at %s:%d\n",feArgv0,__FILE__,__LINE__);
+    return NULL;
+  }
+  return strdup(value);
+}
+
+
+static int feVerifyResourceValue(feResourceType type, char* value)
+{
+#ifdef RESOURCE_DEBUG
+  printf("feVerifyResourceValue(type: %d, value: \"%s\"): entering\n", (int)type, value);
+  printf("Access: ROK: %d, XOK: %d\n", access(value, R_OK), access(value, X_OK));
+#endif
+  switch(type)
+  {
+      case feResUrl:
+      case feResPath:
+        return 1;
+
+      case feResFile:
+        return ! access(value, R_OK);
+
+      case feResBinary:
+      case feResDir:
+        return ! access(value, X_OK);
+
+      default:
+        return 0;
+  }
+}
+
+/*****************************************************************
+ *
+ * Cleaning/Transformations of resource values
+ *
+ *****************************************************************/
+
+static char* feCleanResourceValue(feResourceType type, char* value)
+{
+  if (value == NULL || *value == '\0') return value;
+#ifdef RESOURCE_DEBUG
+      printf("Clean value:%s\n", value);
+#endif
+#ifdef __CYGWIN__
+#ifdef RESOURCE_DEBUG
+      printf("Clean WINNT value:%s\n", value);
+#endif
+  if (type == feResBinary)
+  {
+    int l = strlen(value);
+    if (l < 4 || (strcmp(&value[l-4], ".exe") != 0 &&
+                  strcmp(&value[l-4], ".EXE") != 0))
+      strcat(value, ".exe");
+  }
+#endif
+  if (type == feResFile || type == feResBinary || type == feResDir)
+    return feCleanUpFile(value);
+  if (type == feResPath)
+    return feCleanUpPath(value);
+  return value;
+}
+
+static char* feCleanUpFile(char* fname)
+{
+  char* fn;
+
+#ifdef RESOURCE_DEBUG
+  printf("feCleanUpFile: entering with =%s=\n", fname);
+#endif
+  // Remove unnecessary .. and //
+  for (fn = fname; *fn != '\0'; fn++)
+  {
+    if (*fn == '/')
+    {
+      if (*(fn+1) == '\0')
+      {
+        if (fname != fn) *fn = '\0';
+        break;
+      }
+      if (*(fn + 1) == '/' && (fname != fn))
+      {
+        mystrcpy(fn, fn+1);
+        fn--;
+      }
+      else if (*(fn+1) == '.')
+      {
+        if (*(fn+2) == '.' && (*(fn + 3) == '/' || *(fn + 3) == '\0'))
+        {
+        #if 0
+        // this does not work: ./../../mmm will be changed to ./../mmm
+        // but we only want to change ././mmm to ./mmm
+          *fn = '\0';
+          s = strrchr(fname, '/');
+          if (s != NULL)
+          {
+            mystrcpy(s+1, fn + (*(fn + 3) != '\0' ? 4 : 3));
+            fn = s-1;
+          }
+          else
+          {
+            *fn = '/';
+          }
+        #endif
+        }
+        else if (*(fn+2) == '/' || *(fn+2) == '\0')
+        {
+          mystrcpy(fn+1, fn+3);
+          fn--;
+        }
+      }
+    }
+  }
+
+#ifdef RESOURCE_DEBUG
+  printf("feCleanUpFile: leaving with =%s=\n", fname);
+#endif
+  return fname;
+}
+
+// remove duplicates dir resp. those which do not exist
+static char* feCleanUpPath(char* path)
+{
+#ifdef RESOURCE_DEBUG
+  printf("feCleanUpPath: entering with: =%s=\n", path);
+#endif
+  if (path == NULL) return path;
+
+  int n_comps = 1, i, j;
+  char* opath = path;
+  char** path_comps;
+
+  for (; *path != '\0'; path++)
+  {
+    if (*path == fePathSep) n_comps++;
+    else if (*path == ';')
+    {
+      *path = fePathSep;
+      n_comps++;
+    }
+  }
+
+  path_comps = (char**) malloc(n_comps*sizeof(char*));
+  path_comps[0]=opath;
+  path=opath;
+  i = 1;
+
+  if (i < n_comps)
+  {
+    while (1)
+    {
+      if (*path == fePathSep)
+      {
+        *path = '\0';
+        path_comps[i] = path+1;
+        i++;
+        if (i == n_comps) break;
+      }
+      path++;
+    }
+  }
+
+  for (i=0; i<n_comps; i++)
+    path_comps[i] = feCleanUpFile(path_comps[i]);
+#ifdef RESOURCE_DEBUG
+  printf("feCleanUpPath: after CleanUpName: ");
+  for (i=0; i<n_comps; i++)
+    printf("%s:", path_comps[i]);
+  printf("\n");
+#endif
+
+  for (i=0; i<n_comps;)
+  {
+#ifdef RESOURCE_DEBUG
+    if (access(path_comps[i], X_OK | R_OK))
+      printf("feCleanUpPath: remove %d:%s -- can not access\n", i, path_comps[i]);
+#endif
+    if ( ! access(path_comps[i], X_OK | R_OK))
+    {
+      // x- permission is granted -- we assume that it is a dir
+      for (j=0; j<i; j++)
+      {
+        if (strcmp(path_comps[j], path_comps[i]) == 0)
+        {
+          // found a duplicate
+#ifdef RESOURCE_DEBUG
+          printf("feCleanUpPath: remove %d:%s -- equal to %d:%s\n", j, path_comps[j], i, path_comps[i]);
+#endif
+          j = i+1;
+          break;
+        }
+      }
+      if (j == i)
+      {
+        i++;
+        continue;
+      }
+    }
+    // now we can either not access or found a duplicate
+    path_comps[i] = NULL;
+    for (j=i+1; j<n_comps; j++)
+        path_comps[j-1] = path_comps[j];
+    n_comps--;
+  }
+
+
+  // assemble everything again
+  for (path=opath, i=0;i<n_comps-1;i++)
+  {
+    mystrcpy(path, path_comps[i]);
+    path += strlen(path);
+    *path = fePathSep;
+    path++;
+  }
+  if (n_comps)
+  {
+    mystrcpy(path, path_comps[i]);
+  }
+  else
+  {
+    *opath = '\0';
+  }
+  free(path_comps);
+#ifdef RESOURCE_DEBUG
+  printf("feCleanUpPath: leaving with path=%s=\n", opath);
+#endif
+  return opath;
+}
+
+// strcpy where source and destination may overlap
+static void mystrcpy(char* d, char* s)
+{
+  /*assume(d != NULL && s != NULL);*/
+  while (*s != '\0')
+  {
+    *d = *s;
+    d++;
+    s++;
+  }
+  *d = '\0';
+}
+
+/*****************************************************************
+ *
+ * feSprintf
+ *
+ *****************************************************************/
+static char* feSprintf(char* s, const char* fmt, int warn)
+{
+  char* s_in = s;
+  if (fmt == NULL) return NULL;
+
+  while (*fmt != '\0')
+  {
+    *s = *fmt;
+
+    if (*fmt == '%' && *(fmt + 1) != '\0')
+    {
+      fmt++;
+      char* r = feResource(*fmt, warn);
+      if (r != NULL)
+      {
+        strcpy(s, r);
+        s += strlen(r) - 1;
+      }
+      else
+      {
+        s++;
+        *s = *fmt;
+      }
+    }
+    else if (*fmt == '$' && *(fmt + 1) != '\0')
+    {
+      fmt++;
+      char* v = s + 1;
+      while (*fmt == '_' ||
+             (*fmt >= 'A' && *fmt <= 'Z') ||
+             (*fmt >= 'a' && *fmt <= 'z'))
+      {
+        *v = *fmt;
+        v++;
+        fmt++;
+      }
+      fmt--;
+      *v = '\0';
+      v = getenv(s + 1);
+      if (v != NULL) strcpy(s, v);
+      s += strlen(s) - 1;
+    }
+    s++;
+    fmt++;
+  }
+  *s = '\0';
+  return s_in;
+}
+
diff --git a/resources/feResource.h b/resources/feResource.h
new file mode 100644
index 0000000..b082efd
--- /dev/null
+++ b/resources/feResource.h
@@ -0,0 +1,59 @@
+#ifndef FERESOURCE_H
+#define FERESOURCE_H
+
+#include <sys/param.h>
+
+#define DIR_SEP '/'
+#define DIR_SEPP "/"
+
+#ifndef MAXPATHLEN
+#define MAXPATHLEN 1024
+#endif
+
+#ifdef __cplusplus
+/*****************************************************************
+ *
+ * Resource management (feResources.cc)
+ *
+ *****************************************************************/
+typedef enum {feResUndef = 0, feResBinary, feResDir, feResFile, feResUrl, feResPath} feResourceType;
+
+typedef struct feResourceConfig_s
+{
+  const char*           key;   // key to identify resource
+  const char            id;    // char id to identify resource
+  feResourceType  type;  // type of Resource
+  const char*           env;   // env variable to look for
+  const char*           fmt;   // format string -- see below for epxlaination
+  char*                 value; // what it was set to: may be changed
+} feResourceConfig_s;
+typedef feResourceConfig_s * feResourceConfig;
+
+extern feResourceConfig_s feResourceConfigs[];
+
+// returns value of Resource as read-only string, or NULL
+// if Resource not found
+// issues warning, if explicitely requested (warn > 0), or
+// if warn < 0 and Resource is gotten for the first time
+// Always quiet if warn == 0
+char* feResource(const char id, int warn = -1);
+char* feResource(const char* key, int warn = -1);
+
+char* feGetResource(const char id, int warn = -1);
+
+// char* feResourceDefault(const char id);
+// char* feResourceDefault(const char* key);
+
+
+// This needs to be called before the first call to feResource
+// Initializes Resources, SearchPath, and extends PATH
+void feInitResources(const char* argv0);
+// Re-inits resources, should be called after changing env. variables
+void feReInitResources();
+#endif /* end ifdef __cplusplus */
+
+extern char* feArgv0;
+
+const char fePathSep = ':' ;
+
+#endif
diff --git a/resources/omFindExec.c b/resources/omFindExec.c
new file mode 100644
index 0000000..c4d729c
--- /dev/null
+++ b/resources/omFindExec.c
@@ -0,0 +1,284 @@
+/*******************************************************************
+ *  File:    omFindExec.c
+ *  Purpose: routine which determines absolute pathname of executable
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 11/99
+ *******************************************************************/
+
+
+#include "resourcesconfig.h"
+
+
+#if defined(HAVE_UNISTD_H) && defined(STDC_HEADERS)
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h> /* always defiend */
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "omFindExec.h"
+
+#ifndef MAXPATHLEN
+#define MAXPATHLEN 1024
+#endif
+
+/* ABSOLUTE_FILENAME_P (fname): True if fname is an absolute filename */
+#define ABSOLUTE_FILENAME_P(fname)        (fname[0] == '/')
+
+/* Return the absolute name of the program named NAME.  This function
+   searches the directories in the PATH environment variable if PROG
+   has no directory components. */
+#ifndef HAVE_READLINK
+char * omFindExec (const char *name, char* executable)
+#else
+static char * omFindExec_link (const char *name, char* executable)
+#endif
+{
+  char *search;
+  char *p;
+#ifdef WINNT
+  char *extra = NULL;
+#endif
+  char tbuf[MAXPATHLEN];
+
+  if (ABSOLUTE_FILENAME_P(name))
+  {
+      /* If we can execute the named file then return it. */
+      if (! access (name, X_OK))
+      {
+        strcpy(executable, name);
+#ifdef __CYGWIN__
+        strcat(executable, ".exe");
+#endif
+        return executable;
+      }
+  }
+  else
+  {
+    if (((name[0] == '.') && (name[1] == '/')) ||
+        ((name[0] == '.') && (name[1] == '.') && (name[2] == '/')) ||
+        strchr(name, '/') != NULL)
+    {
+
+#ifdef HAVE_GETCWD
+      getcwd (tbuf, MAXPATHLEN);
+#else
+# ifdef HAVE_GETWD
+      getwd (tbuf);
+# endif
+#endif
+      strcat (tbuf, "/");
+      strcat (tbuf, name);
+      if (! access(tbuf, X_OK))
+      {
+        strcpy(executable, tbuf);
+#ifdef __CYGWIN__
+        strcat(executable, ".exe");
+#endif
+        return executable;
+      }
+    }
+
+
+    search = getenv("PATH");
+/* for winnt under msdos, cwd is implictly in the path */
+#ifdef WINNT
+    p = getenv("SHELL");
+    if (p == NULL || strlen(p) < 2)
+    {
+      char *extra = NULL;
+      /* we are under msdos display */
+      extra = (char*) malloc((search != NULL ? strlen(search) : 0) + 3);
+      strcpy(extra, ".:");
+      if (search != NULL) strcat(extra, search);
+      search = extra;
+    }
+#endif
+    p = search;
+
+    if (p != NULL)
+    {
+      while (1)
+      {
+        char *next;
+        next = tbuf;
+
+        /* Copy directory name into [tbuf]. */
+        /* This is somewhat tricky: empty names mean cwd, w.r.t. some
+           shell spec */
+        while (*p && *p != ':')
+          *next ++ = *p ++;
+        *next = '\0';
+
+        if ((tbuf[0] == '.' && tbuf[1] == '\0') || tbuf[0] == '\0') {
+#ifdef HAVE_GETCWD
+          getcwd (tbuf, MAXPATHLEN);
+#else
+# ifdef HAVE_GETWD
+          getwd (tbuf);
+# endif
+#endif
+        }
+
+        if (tbuf[strlen(tbuf)-1] != '/') strcat(tbuf, "/");
+        strcat (tbuf, name);
+
+        /* If we can execute the named file, then return it. */
+        if (! access (tbuf, X_OK))
+        {
+#ifdef WINNT
+          if (extra != NULL)
+            free(extra);
+#endif
+          strcpy(executable, tbuf);
+#ifdef __CYGWIN__
+          strcat(executable, ".exe");
+#endif
+          return executable;
+        }
+
+        if (*p != '\0')
+        {
+          p ++;
+        }
+        else
+        {
+          break;
+        }
+      }
+    }
+  }
+  return NULL;
+}
+
+#ifdef HAVE_READLINK
+/* similar to readlink, but dont' mess up absolute pathnames */
+static int my_readlink(const char* name, char* buf, size_t bufsize)
+{
+  char buf2[MAXPATHLEN];
+  int ret;
+
+  if ((ret = readlink(name, buf2, bufsize)) > 0)
+  {
+    buf2[ret] = 0;
+    if (*name == '/' && *buf2 != '/')
+    {
+      char* last = strrchr(name, '/');
+      int i = 0;
+      while (&(name[i]) != last)
+      {
+        buf[i] = name[i];
+        i++;
+      }
+      buf[i] = '/';
+      i++;
+      strcpy(&(buf[i]), buf2);
+      return i + ret;
+    }
+    else
+    {
+      strcpy(buf, buf2);
+    }
+  }
+  return ret;
+}
+
+#define MAX_LINK_LEVEL 10
+/* similar to readlink (cf. man readlink), except that symbolic links are
+   followed up to MAX_LINK_LEVEL
+*/
+static int full_readlink(const char* name, char* buf, size_t bufsize)
+{
+  int ret;
+
+  if ((ret=my_readlink(name, buf, bufsize)) > 0)
+  {
+    char buf2[MAXPATHLEN];
+    int ret2, i = 0;
+
+    do
+    {
+      buf[ret] = '\0';
+      if ((ret2 = my_readlink(buf, buf2, MAXPATHLEN)) > 0)
+      {
+        i++;
+        buf2[ret2] = '\0';
+        strcpy(buf, buf2);
+        ret = ret2;
+      }
+      else
+      {
+        return ret;
+      }
+    }
+    while (i<MAX_LINK_LEVEL);
+  }
+  return -1;
+}
+
+#ifdef WINNT
+char * _omFindExec (const char *name, char* exec);
+/* for windows, serch first for .exe */
+char* omFindExec(const char *name, char* exec)
+{
+
+  if (strstr(name, ".exe") == NULL)
+  {
+    char buf[MAXPATHLEN];
+    char* ret;
+    strcpy(buf, name);
+    strcat(buf, ".exe");
+    ret = _omFindExec(buf, exec);
+    if (ret != NULL) return ret;
+  }
+  return _omFindExec(name, exec);
+}
+#else
+#define _omFindExec omFindExec
+#endif
+
+char * _omFindExec (const char *name, char* exec)
+{
+  char * link = omFindExec_link(name, exec);
+  char buf[MAXPATHLEN];
+  int ret;
+
+  if (link == NULL && (ret=full_readlink(name, buf, MAXPATHLEN)) > 0)
+  {
+    buf[ret] ='\0';
+    link = omFindExec_link(buf, exec);
+  }
+  if (link != NULL && (ret=full_readlink(link, buf, MAXPATHLEN)) > 0)
+  {
+    char *p = strrchr(link, '/');
+
+
+    if(p!=NULL) *(p+1)='\0';
+    buf[ret]='\0';
+
+    if (buf[0] != '/')
+    {
+      strcpy(exec, link);
+      strcat(exec, buf);
+    }
+    else
+    {
+      strcpy(exec, buf);
+    }
+
+    return exec;
+  }
+  return link;
+}
+#endif /* HAVE_READLINK */
+
+#else
+
+char* omFindExec (const char *name, char* exec)
+{
+  return name;
+}
+
+#endif /* defined(HAVE_UNISTD_H) && defined(STDC_HEADERS) */
diff --git a/resources/omFindExec.h b/resources/omFindExec.h
new file mode 100644
index 0000000..b2b9b5b
--- /dev/null
+++ b/resources/omFindExec.h
@@ -0,0 +1,22 @@
+/*******************************************************************
+ *  File:    omFindExec.h
+ *  Purpose: declaration routines for getting Backtraces of stack
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 11/99
+ *******************************************************************/
+#ifndef OM_FIND_EXEC_H
+#define OM_FIND_EXEC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* determines absolute pathname of program prog, writes it into exec */
+/* returns exec on succes, NULL on failure */
+char* omFindExec(const char* prog, char* exec);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* OM_FINDEXEC_H */
diff --git a/resources/resources.pc.in b/resources/resources.pc.in
new file mode 100644
index 0000000..d040056
--- /dev/null
+++ b/resources/resources.pc.in
@@ -0,0 +1,17 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: @PACKAGE@
+Description: The Singular resources manager
+Version: @PACKAGE_VERSION@
+URL: https://github.com/Singular/Sources/tree/spielwiese/@PACKAGE@
+
+# Requires:
+# Conflicts:
+
+Cflags: -I${includedir} @SINGULAR_CFLAGS@
+Libs: -L${libdir} -l at PACKAGE@
+# Libs.private:
+
diff --git a/singular.spec.in b/singular.spec.in
new file mode 100644
index 0000000..a2b9dee
--- /dev/null
+++ b/singular.spec.in
@@ -0,0 +1,81 @@
+Name: singular
+Summary: computer algebra system for polynomial computations (binary files)
+Version: @PACKAGE_VERSION@
+Release: 1%{?dist}
+License: GPLv2+
+Group: Applications/Math
+Vendor: Singular Team
+URL: http://www.singular.uni-kl.de
+Packager: Mathias Schulze <mschulze at mathematik.uni-kl.de>
+Source0: http://www.mathematik.uni-kl.de/ftp/pub/Math/Singular/UNIX/%{name}-%{version}.tar.gz
+BuildArch: %{_arch}
+BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
+BuildRequires: cddlib-devel, gmp-devel, ntl-devel
+Requires: singular-common
+
+%description
+Singular is a computer algebra system for polynomial computations with
+emphasis on the special needs of commutative algebra, algebraic geometry,
+and singularity theory.
+
+This package contains binary files.
+
+%package common
+Summary: computer algebra system for polynomial computations (common files).
+BuildArch: noarch
+%description common
+Singular is a computer algebra system for polynomial computations with
+emphasis on the special needs of commutative algebra, algebraic geometry,
+and singularity theory.
+
+This package contains architecture-independent files.
+
+%package devel
+Summary: computer algebra system for polynomial computations (development)
+BuildArch: noarch
+%description devel
+Singular is a computer algebra system for polynomial computations with
+emphasis on the special needs of commutative algebra, algebraic geometry,
+and singularity theory.
+
+This package contains development files.
+
+%prep
+%setup -q
+
+%check
+make check
+
+%build
+%configure --enable-gfanlib
+make %{?_smp_mflags}
+
+%install
+rm -rf %{buildroot}
+make install DESTDIR=%{buildroot}
+install -D desktop/Singular.desktop %{buildroot}/%{_datadir}/applications/Singular.desktop
+install -D desktop/Singular-manual.desktop %{buildroot}/%{_datadir}/applications/Singular-manual.desktop
+install -D desktop/Singular.png %{buildroot}/%{_datadir}/icons/Singular.png
+
+%clean
+rm -rf %{buildroot}
+
+%files
+%defattr(-,root,root,-)
+%{_bindir}/*
+%{_libdir}/*
+%{_libexecdir}/*
+
+%files common
+%doc README COPYING ChangeLog
+%{_datadir}/*
+#%{_mandir}/*
+#%{_infodir}/*
+
+%files devel
+%{_includedir}/*
+
+%changelog
+* Tue Apr 30 2013 Mathias Schulze <mschulze at mathematik.uni-kl.de> 3.1.3.rc-1
+- Initial release
+
diff --git a/xalloc/AUTHORS b/xalloc/AUTHORS
new file mode 100644
index 0000000..e69de29
diff --git a/xalloc/ChangeLog b/xalloc/ChangeLog
new file mode 100644
index 0000000..e69de29
diff --git a/xalloc/Makefile.am b/xalloc/Makefile.am
new file mode 100644
index 0000000..de9cb47
--- /dev/null
+++ b/xalloc/Makefile.am
@@ -0,0 +1,19 @@
+ACLOCAL_AMFLAGS = -I ../m4
+
+noinst_LTLIBRARIES=libomalloc.la
+
+# lib_LTLIBRARIES=libomalloc.la
+# lib_LIBRARIES=libomalloc.a
+
+# libomallocdir = $(libdir)/
+
+# libomalloc_includedir=$(includedir)/omalloc
+# libomalloc_include_HEADERS = omalloc.h
+
+SOURCES = dummy.c omalloc.h
+
+libomalloc_la_SOURCES  =$(SOURCES)
+
+libomalloc_la_LDFLAGS  = -release ${PACKAGE_VERSION}
+
+
diff --git a/xalloc/Makefile.in b/xalloc/Makefile.in
new file mode 100644
index 0000000..a4aef68
--- /dev/null
+++ b/xalloc/Makefile.in
@@ -0,0 +1,660 @@
+# Makefile.in generated by automake 1.13.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 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@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+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 = xalloc
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/build-aux/depcomp AUTHORS ChangeLog NEWS README
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_append_compile_flags.m4 \
+	$(top_srcdir)/m4/ax_append_flag.m4 \
+	$(top_srcdir)/m4/ax_append_link_flags.m4 \
+	$(top_srcdir)/m4/ax_check_compile_flag.m4 \
+	$(top_srcdir)/m4/ax_check_link_flag.m4 \
+	$(top_srcdir)/m4/ax_compute_relative_paths.m4 \
+	$(top_srcdir)/m4/ax_normalize_path.m4 \
+	$(top_srcdir)/m4/ax_prefix_config_h.m4 \
+	$(top_srcdir)/m4/ax_pthread.m4 \
+	$(top_srcdir)/m4/ax_python_embed.m4 \
+	$(top_srcdir)/m4/ax_python_with_version.m4 \
+	$(top_srcdir)/m4/cpu-check.m4 $(top_srcdir)/m4/dbm-check.m4 \
+	$(top_srcdir)/m4/flags.m4 $(top_srcdir)/m4/flint-check.m4 \
+	$(top_srcdir)/m4/gfanlib-check.m4 \
+	$(top_srcdir)/m4/gmp-check.m4 \
+	$(top_srcdir)/m4/google-perftools.m4 \
+	$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+	$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+	$(top_srcdir)/m4/lt~obsolete.m4 \
+	$(top_srcdir)/m4/mathic-check.m4 $(top_srcdir)/m4/ntl-check.m4 \
+	$(top_srcdir)/m4/options.m4 $(top_srcdir)/m4/p-procs.m4 \
+	$(top_srcdir)/m4/polymake-check.m4 \
+	$(top_srcdir)/m4/readline-check.m4 $(top_srcdir)/configure.ac
+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 =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+libomalloc_la_LIBADD =
+am__objects_1 = dummy.lo
+am_libomalloc_la_OBJECTS = $(am__objects_1)
+libomalloc_la_OBJECTS = $(am_libomalloc_la_OBJECTS)
+AM_V_lt = $(am__v_lt_ at AM_V@)
+am__v_lt_ = $(am__v_lt_ at AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 = 
+libomalloc_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+	$(libomalloc_la_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_P = $(am__v_P_ at AM_V@)
+am__v_P_ = $(am__v_P_ at AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_ at AM_V@)
+am__v_GEN_ = $(am__v_GEN_ at AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_ at AM_V@)
+am__v_at_ = $(am__v_at_ at AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+DEFAULT_INCLUDES = -I. at am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+	$(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_ at AM_V@)
+am__v_CC_ = $(am__v_CC_ at AM_DEFAULT_V@)
+am__v_CC_0 = @echo "  CC      " $@;
+am__v_CC_1 = 
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+	$(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_ at AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_ at AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo "  CCLD    " $@;
+am__v_CCLD_1 = 
+DIST_SOURCES = $(libomalloc_la_SOURCES)
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BUILTIN_LIBS = @BUILTIN_LIBS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CDDGMPCPPFLAGS = @CDDGMPCPPFLAGS@
+CDDGMPLDFLAGS = @CDDGMPLDFLAGS@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATA_DIR = @DATA_DIR@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DOC_DIR = @DOC_DIR@
+DOXYGEN = @DOXYGEN@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FACTORY_INCLUDES = @FACTORY_INCLUDES@
+FACTORY_LIBS = @FACTORY_LIBS@
+FGREP = @FGREP@
+FLINT_CFLAGS = @FLINT_CFLAGS@
+FLINT_HOME = @FLINT_HOME@
+FLINT_LIBS = @FLINT_LIBS@
+GMP_CFLAGS = @GMP_CFLAGS@
+GMP_HOME = @GMP_HOME@
+GMP_LIBS = @GMP_LIBS@
+GMP_VERSION = @GMP_VERSION@
+GREP = @GREP@
+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@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NTL_CFLAGS = @NTL_CFLAGS@
+NTL_LIBS = @NTL_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OMALLOC_INCLUDES = @OMALLOC_INCLUDES@
+OMALLOC_LIBS = @OMALLOC_LIBS@
+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@
+PKG_REQUIRE = @PKG_REQUIRE@
+PMCONFIG = @PMCONFIG@
+PM_CFLAGS = @PM_CFLAGS@
+PM_INC = @PM_INC@
+PM_LDFLAGS = @PM_LDFLAGS@
+PM_LIBS = @PM_LIBS@
+POLYMAKE_CXXFLAGS = @POLYMAKE_CXXFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LDFLAGS = @PTHREAD_LDFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
+PYTHON = @PYTHON@
+PYTHON_CSPEC = @PYTHON_CSPEC@
+PYTHON_EXECPREFIX = @PYTHON_EXECPREFIX@
+PYTHON_LSPEC = @PYTHON_LSPEC@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+RANLIB = @RANLIB@
+RESOURCES_INCLUDES = @RESOURCES_INCLUDES@
+RESOURCES_LIBS = @RESOURCES_LIBS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SINGULAR_CFLAGS = @SINGULAR_CFLAGS@
+SI_COUNTEDREF_AUTOLOAD = @SI_COUNTEDREF_AUTOLOAD@
+SI_CPU_I386 = @SI_CPU_I386@
+SI_CPU_IA64 = @SI_CPU_IA64@
+SI_CPU_PPC = @SI_CPU_PPC@
+SI_CPU_SPARC = @SI_CPU_SPARC@
+SI_CPU_X86_64 = @SI_CPU_X86_64@
+STRIP = @STRIP@
+USEPPROCSDYNAMICLD = @USEPPROCSDYNAMICLD@
+USEPPROCSDYNAMICLDFLAGS = @USEPPROCSDYNAMICLDFLAGS@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
+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@
+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@
+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@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+ACLOCAL_AMFLAGS = -I ../m4
+noinst_LTLIBRARIES = libomalloc.la
+
+# lib_LTLIBRARIES=libomalloc.la
+# lib_LIBRARIES=libomalloc.a
+
+# libomallocdir = $(libdir)/
+
+# libomalloc_includedir=$(includedir)/omalloc
+# libomalloc_include_HEADERS = omalloc.h
+SOURCES = dummy.c omalloc.h
+libomalloc_la_SOURCES = $(SOURCES)
+libomalloc_la_LDFLAGS = -release ${PACKAGE_VERSION}
+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) --foreign xalloc/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign xalloc/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-noinstLTLIBRARIES:
+	-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+	@list='$(noinst_LTLIBRARIES)'; \
+	locs=`for p in $$list; do echo $$p; done | \
+	      sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+	      sort -u`; \
+	test -z "$$locs" || { \
+	  echo rm -f $${locs}; \
+	  rm -f $${locs}; \
+	}
+
+libomalloc.la: $(libomalloc_la_OBJECTS) $(libomalloc_la_DEPENDENCIES) $(EXTRA_libomalloc_la_DEPENDENCIES) 
+	$(AM_V_CCLD)$(libomalloc_la_LINK)  $(libomalloc_la_OBJECTS) $(libomalloc_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/dummy.Plo at am__quote@
+
+.c.o:
+ at am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+ at am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+ at am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+ at am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+ at am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+ at am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+ at am__fastdepCC_TRUE@	$(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	$(am__define_uniq_tagged_files); \
+	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-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	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"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+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 $(LTLIBRARIES)
+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:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+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 clean-noinstLTLIBRARIES \
+	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 TAGS all all-am check check-am clean clean-generic \
+	clean-libtool clean-noinstLTLIBRARIES cscopelist-am ctags \
+	ctags-am 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 tags-am uninstall uninstall-am
+
+
+# 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/xalloc/NEWS b/xalloc/NEWS
new file mode 100644
index 0000000..e69de29
diff --git a/xalloc/README b/xalloc/README
new file mode 100644
index 0000000..e69de29
diff --git a/xalloc/dummy.c b/xalloc/dummy.c
new file mode 100644
index 0000000..1ab806e
--- /dev/null
+++ b/xalloc/dummy.c
@@ -0,0 +1,6 @@
+#include "omalloc.h"
+
+int om_sing_opt_show_mem; /* dummy */
+struct omInfo_s om_Info; /* dummy */
+struct omOpts_s om_Opts; /* dummy */
+
diff --git a/xalloc/omalloc.h b/xalloc/omalloc.h
new file mode 100644
index 0000000..a8688ed
--- /dev/null
+++ b/xalloc/omalloc.h
@@ -0,0 +1,242 @@
+#ifndef XMEMORY_H
+#define XMEMORY_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT
+*/
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef size_t            omBin;
+
+struct omInfo_s;
+typedef struct omInfo_s omInfo_t;
+struct omInfo_s
+{
+  long MaxBytesSystem;      /* set in omUpdateInfo(), is more accurate with malloc support   */
+  long CurrentBytesSystem;  /* set in omUpdateInfo(), is more accurate with malloc support */
+  long MaxBytesSbrk;        /* always up-to-date, not very accurate, needs omInintInfo() */
+  long CurrentBytesSbrk;    /* set in omUpdateInfo(), needs omInintInfo() */
+  long MaxBytesMmap;        /* set in omUpdateInfo(), not very accurate */
+  long CurrentBytesMmap;    /* set in omUpdateInfo(), not very accurate */
+  long UsedBytes;           /* set in omUpdateInfo() */
+  long AvailBytes;          /* set in omUpdateInfo() */
+  long UsedBytesMalloc;     /* set in omUpdateInfo(), needs malloc support */
+  long AvailBytesMalloc;    /* set in omUpdateInfo(), needs malloc support */
+  long MaxBytesFromMalloc;      /* always kept up-to-date */
+  long CurrentBytesFromMalloc;  /* always kept up-to-date */
+  long MaxBytesFromValloc;      /* always kept up-to-date */
+  long CurrentBytesFromValloc;  /* always kept up-to-date */
+  long UsedBytesFromValloc; /* set in omUpdateInfo()  */
+  long AvailBytesFromValloc;/* set in omUpdateInfo()  */
+  long MaxPages;            /* always kept up-to-date */
+  long UsedPages;           /* always kept up-to-date */
+  long AvailPages;          /* always kept up-to-date */
+  long MaxRegionsAlloc;     /* always kept up-to-date */
+  long CurrentRegionsAlloc; /* always kept up-to-date */
+};
+
+extern struct omInfo_s om_Info;
+
+struct omOpts_s;
+extern struct omOpts_s
+{
+  int MinTrack;
+  int MinCheck;
+  int MaxTrack;
+  int MaxCheck;
+  int Keep;
+  int HowToReportErrors;
+  int MarkAsStatic;
+  unsigned int PagesPerRegion;
+  void (*OutOfMemoryFunc)();
+  void (*MemoryLowFunc)();
+  void (*ErrorHook)();
+} om_Opts;
+
+typedef struct omOpts_s omOpts_t;
+
+extern int om_sing_opt_show_mem;
+
+static inline void * omAlloc(size_t s)
+{ if (s!=0) {long *d=(long*)malloc(s+sizeof(long)); *d=s;d++;return d; }
+  else return NULL;
+}
+static inline void * omAlloc0(size_t s)
+{ void *d=omAlloc(s);memset(d,0,s); return d; }
+static inline void * omalloc0(size_t s)
+{ if (s!=0) { void *d=omAlloc(s);memset(d,0,s); return d;} else return NULL; }
+
+static inline void *omRealloc(void *d, size_t ns)
+{ if (d==NULL) return omAlloc(ns);
+  else
+  {
+    long *dd=(long*)d; dd--; dd=(long*)realloc(dd,ns+sizeof(long));
+    *dd=ns+sizeof(long);dd++; return dd;
+  }
+}
+static inline void *omReallocSize(void *d, size_t os, size_t ns)
+{ if (d==NULL) return omAlloc(ns);
+  else
+  {
+    long *dd=(long*)d; dd--; dd=(long*)realloc(dd,ns+sizeof(long));
+    *dd=ns+sizeof(long);dd++; return dd;
+  }
+}
+static inline long omSizeOfAddr(void *d)
+{ long *dd=(long*)d; dd--; return *dd;}
+
+static inline void omFree(void *d)
+{ if (d!=NULL) { long *dd=(long*)d; dd--; free(dd);}}
+
+static inline void *omRealloc0(void *d, size_t ns)
+{
+  void *n=omAlloc0(ns);
+  if (d!=NULL)
+  {
+    size_t c;
+    size_t os=omSizeOfAddr(d);
+    if (ns>os) c=os; else c=ns;
+    memcpy(n,d,c);
+    omFree(d);
+  }
+  return n;
+}
+static inline void omFreeSize(void *d, size_t s)
+{ if (d!=NULL) { long *dd=(long*)d; dd--; free(dd);}}
+
+static inline char * omStrDup(const char *s)
+{ size_t l=strlen(s);char *ns=(char *)omAlloc(l+1);
+  return strcpy(ns,s);
+}
+static inline void * omMemDup(void * s)
+{ long *n;long *d=(long*)s; d--;
+  n=(long*)malloc(*d+sizeof(long));
+  memcpy(n,d,(*d)+sizeof(long));
+  n++;
+  return n;
+}
+
+/* #define omSizeWOfBin(bin_ptr) ((bin_ptr)->sizeW) */
+#define omSizeWOfBin(bin_ptr) (((bin_ptr)+sizeof(long)-1)/sizeof(long))
+
+/*******************************************************************
+ *
+ *  error codes
+ *
+ *******************************************************************/
+enum omError_e
+{
+  omError_NoError = 0,
+  omError_Unknown,
+  omError_InternalBug,
+  omError_MemoryCorrupted,
+  omError_NullAddr,
+  omError_InvalidRangeAddr,
+  omError_FalseAddr,
+  omError_FalseAddrOrMemoryCorrupted,
+  omError_WrongSize,
+  omError_FreedAddr,
+  omError_FreedAddrOrMemoryCorrupted,
+  omError_WrongBin,
+  omError_UnknownBin,
+  omError_NotBinAddr,
+  omError_UnalignedAddr,
+  omError_NullSizeAlloc,
+  omError_ListCycleError,
+  omError_SortedListError,
+  omError_KeptAddrListCorrupted,
+  omError_FreePattern,
+  omError_BackPattern,
+  omError_FrontPattern,
+  omError_NotString,
+  omError_StickyBin,
+  omError_MaxError
+};
+// typedef enum omError_e omError_t;
+
+#define omSizeWOfAddr(P)         (omSizeOfAddr(P)/sizeof(long))
+
+#define omTypeAllocBin(T,P,B)    P=(T)omAlloc(B)
+#define omTypeAlloc(T,P,S)       P=(T)omAlloc(S)
+#define omTypeAlloc0Bin(T,P,B)   P=(T)omAlloc0(B)
+#define omalloc(S)               omAlloc(S)
+#define omAlloc0Aligned(S)       omAlloc0(S)
+#define omAllocAligned(S)        omAlloc(S)
+#define omAllocBin(B)            omAlloc(B)
+#define omAllocBin0(B)           omAlloc0(B)
+#define omAlloc0Bin(B)           omAlloc0(B)
+#define omInitInfo()
+#define omInitGetBackTrace()
+#define omUpdateInfo()
+#define omPrintStats(F)
+#define omPrintInfo(F)
+#define omPrintBinStats(F)
+#define omMarkMemoryAsStatic()
+#define omfree(P)                omFree(P)
+#define omFree(P)                omFree(P)
+#define omFreeBin(P,B)           omFree(P)
+#define omfreeSize(P,S)          omFreeSize(P,S)
+#define omFreeFunc               omFree
+#define omFreeBinAddr(P)         omFree(P)
+#define omrealloc(A,NS)          omRealloc(A,NS)
+#define omreallocSize(A,OS,NS)   omRealloc(A,NS)
+#define omRealloc0Size(A,OS,NS)  omRealloc0(A,NS)
+#define omrealloc0Size(A,OS,NS)  omRealloc(A,NS)
+#define omMarkAsStaticAddr(A)
+#define omMemCpyW(A,B,S)         memcpy(A,B,(S)<<2)
+#define omMemcpyW(A,B,S)         memcpy(A,B,(S)<<2)
+#define omGetSpecBin(A)          (A)
+#define omUnGetSpecBin(A)        do {} while (0)
+#define memcpyW(A,B,C)         memcpy(A,B,(C)*sizeof(long))
+#define omGetStickyBinOfBin(B) omGetSpecBin(B)
+
+
+/* debug dummies: */
+#define omTypeReallocAlignedSize     omTypeReallocSize
+#define omTypeRealloc0AlignedSize    omTypeRealloc0Size
+#define omReallocAlignedSize         omReallocSize
+#define omRealloc0AlignedSize        omRealloc0Size
+#define omMemDupAligned     omMemDup
+#define omCheckIf(cond, test)                    do {} while (0)
+#define omCheckBinAddr(addr)                     do {} while (0)
+#define omCheckAddrBin(addr,bin)                 do {} while (0)
+#define omCheckBinAddrSize(addr,size)            do {} while (0)
+#define omCheckAddrSize(addr,size)               do {} while (0)
+#define omCheckAddr(addr)                        do {} while (0)
+#define omcheckAddrSize(addr,size)               do {} while (0)
+#define omcheckAddr(addr)                        do {} while (0)
+#define omCheckBin(bin)                          do {} while (0)
+#define omCheckMemory()                          do {} while (0)
+#define omPrintCurrentBackTraceMax(A,B)          do {} while (0)
+#define omPrintUsedTrackAddrs(F,max)             do {} while (0)
+#define omPrintCurrentBackTrace(F)               do {} while (0)
+#define omPrintUsedAddrs(F,max)                  do {} while (0)
+#define omdebugAddrSize(A,B)                     do {} while (0)
+#define omPrintAddrInfo(A,B,C)                   do {} while (0)
+#define omIsBinPageAddr(A)                       (1)
+#define omTestBinAddrSize(A,B,C)                 (omError_NoError)
+#define omTestList(ptr, level)                   (omError_NoError)
+#define omInitRet_2_Info(argv0)                  do {} while (0)
+#define omMergeStickyBinIntoBin(A,B)             do {} while (0)
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#undef OMALLOC_USES_MALLOC
+#define X_OMALLOC
+#define omMallocFunc omAlloc
+#define omReallocSizeFunc omReallocSize
+#define omFreeSizeFunc omFreeSize
+/* #define OM_NDEBUG */
+#undef OM_SING_KEEP
+
+#endif

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/singular.git



More information about the debian-science-commits mailing list